./0000700000175000017500000000000012133201303007653 5ustar olesoles./saods9/0000755000175000017500000000000012133201305011071 5ustar olesoles./saods9/make.macosxleopard0000644000175000017500000000017711260736452014616 0ustar olesolesOS = macosx ARCH = macosxleopard ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-leopard.tar.gz ./saods9/make.pkgs0000644000175000017500000000155512126355726012725 0ustar olesoles#--------------------------basic DS9VERSION= 7.2 XPAVERSION= 2.1.14 #--------------------------version BLTVER = blt3.0 TCLVER = tcl8.5 TCLLIBVER = tcllib1.14 TCLXMLVER = Tclxml3.2 TKVER = tk8.5 TKCONVER = tkcon2.5 TKIMGVER= Img1.4 TKTABLEVER= Tktable2.10 XMLRPCVER = xmlrpc0.3 #--------------------------dir ASTDIR= ast-7.1.1 BLTDIR= blt3.0.1 CHECKDNSDIR= checkdns FUNTOOLSDIR= funtools-1.4.5 HCOMPRESSDIR = hcompress HTMLDIR= html IISDIR= iis PLIODIR= plio RICEDIR= rice SAOTKDIR= saotk SIGNALDIR= signal_ext1.4 SLADIR= sla TCLDIR= tcl8.5.9 TCLLIBDIR= tcllib-1.14 TCLXMLDIR= tclxml-3.2 TKCONDIR= tkcon-2.5 TKDIR= tk8.5.9 TKIMGDIR= tkimg1.4 TKMPEGDIR= tkmpeg TKTABLEDIR= tktable2.10 WCSSUBSDIR= wcssubs-3.8.4 XMLRPCDIR= xmlrpc-0.3 XPADIR= xpa-2.1.14 ZIPDIR= zip-2.31 ZLIBDIR= zlib-1.2.5 ZVFSDIR= zvfs #--------------------------compilers TCC= tcc-0.9.25-win32-bin.zip ./saods9/make.darwin64x86snowleopard0000644000175000017500000000114112127331353016221 0ustar olesolesOS = unix ARCH = darwin64x86snowleopard X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -m64 -arch x86_64 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz ASTFLAGS = star_cv_cnf_trail_type=long JOBS = 4 ./saods9/make.solaris0000644000175000017500000000105011773331763013425 0ustar olesolesOS = unix ARCH = solaris X11INCLUDE=/usr/X/include X11LIB = /usr/X/lib X11LIBS = -lX11 -lXext XX = -O2 YY = -g -fno-inline ZZ = #ZZ = -m64 -mcpu=v9 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = /opt/local/bin/zcat JOBS = 4 ./saods9/Makefile0000644000175000017500000004070512061451606012552 0ustar olesolesinclude make.include include make.pkgs .NOTPARALLEL : #--------------------------defines export root := $(shell pwd) USER = joye #DEST = bokhara.cfa.harvard.edu DEST = bokhara DIRS = bin lib include man html share dist #--------------------------dirs SRCDIR = src DOCDIR = doc DS9DIR = ds9 #--------------------------cache CACHE = $(root)/myconfig.cache LOCALCACHE = myconfig.cache #--------------------------dist DS9APP=SAOImage\ DS9\ $(DS9VERSION) XPAAPP=XPA\ $(XPAVERSION) #--------------------------blt stuff BLTINCL = blt.h bltVector.h BLTWITHOUT = \ --without-jpegincdir --without-jpeglibdir \ --without-pngincdir --without-pnglibdir \ --without-tiffincdir --without-tifflibdir \ --without-xpmincdir --without-xpmlibdir \ --without-xrandrincdir --without-xrandrlibdir \ --without-expatincdir --without-expatlibdir \ --without-mysqlincdir --without-mysqllibdir #--------------------------flags ifeq ($(OS),unix) TCLDIRDIR= $(TCLDIR)/unix TKDIRDIR= $(TKDIR)/unix XFLAGS = --x-includes=$(X11INCLUDE) --x-libraries=$(X11LIB) TCLFLAGS = $(XFLAGS) $(EXTTCLFLAGS) TKTABLEFLAGS = $(XFLAGS) BLTFLAGS = $(XFLAGS) $(BLTWITHOUT) TKIMGFLAGS = $(XFLAGS) XPAFLAGS = $(XFLAGS) SIGNAL= signal SIGNALCLEAN= signalclean OPTDIR= unix OPTDIRCLEAN= unixclean endif ifeq ($(OS),windows) TCLDIRDIR= $(TCLDIR)/win TKDIRDIR= $(TKDIR)/win TCLFLAGS = --enable-symbols TKTABLEFLAGS = --enable-symbols BLTFLAGS = --without-x $(BLTWITHOUT) \ --without-xftincdir --without-xftlibdir TKIMGFLAGS = --enable-symbols XPAFLAGS = --without-x PREHTMLFLAGS = config_BUILD_TCLSH=tclsh85sg \ config_TARGET_TCL_SCRIPT_DIR=$(root)/lib/tcl8.5 SIGNAL= SIGNALCLEAN= OPTDIR= win OPTDIRCLEAN= winclean endif ifeq ($(OS),macosx) TCLDIRDIR= $(TCLDIR)/unix TKDIRDIR= $(TKDIR)/unix TCLFLAGS = --enable-aqua BLTFLAGS = --x-includes=/usr/X11/include --x-libraries=/usr/X11/lib \ $(BLTWITHOUT) # xpa configure will not accept --without-x XPAFLAGS = --with-x=disabled --enable-posix_spawn PREHTMLFLAGS = config_TARGET_LIBS="-framework CoreFoundation -framework Carbon" \ config_TARGET_X_INC="-I$(root)/$(TKDIR)/xlib" \ config_TARGET_X_LIBS=" " FUNTOOLSFLAGS = --enable-posix_spawn SIGNAL= signal SIGNALCLEAN= signalclean OPTDIR= macosx OPTDIRCLEAN= macosxclean endif CVSFILES = admin \ checkdns \ tkmpeg \ COPYING \ copyright \ iis \ make.darwin64x86mountainlion \ make.darwinx86mountainlion \ make.darwinmountainlion \ make.darwin64x86lion \ make.darwinx86lion \ make.darwinlion \ make.darwin64x86snowleopard \ make.darwinx86snowleopard \ make.darwinsnowleopard \ make.darwin64x86leopard \ make.darwinx86leopard \ make.darwinppcleopard \ make.darwinleopard \ make.darwinx86tiger \ make.darwinppctiger \ make.darwintiger \ make.linux \ make.linux64 \ make.macosxsnowleopard \ make.macosxx86leopard \ make.macosxppcleopard \ make.macosxleopard \ make.macosxx86tiger \ make.macosxppctiger \ make.macosxtiger \ make.solaris \ make.source \ make.windows \ make.pkgs \ Makefile \ notes.txt \ mods \ README \ saotk \ unix \ win \ macosx \ tests \ doc \ cmaps \ template \ src \ msgs \ ds9 \ util \ compilers \ $(ZVFSDIR)/Makefile \ $(WCSSUBSDIR)/Makefile \ $(RICEDIR)/Makefile \ $(HCOMPRESSDIR)/Makefile \ $(PLIODIR)/Makefile # $(BLTDIR)/src/Makefile-macosx.in \ # $(BLTDIR)/src/bltMacOSX.h \ # $(BLTDIR)/src/bltMacOSX.c \ # $(BLTDIR)/src/macosx.c ZIPOBJS = zipfile.o \ zipup.o \ fileio.o \ util.o \ globals.o \ crypt.o \ ttyio.o \ unix.o \ crc32.o \ deflate.o \ trees.o #--------------------------build all : build build : dirs \ tcl tk \ tktable tkcon xmlrpc blt \ zlib tclxml tkimg tkmpeg html \ xpa iis checkdns $(SIGNAL) funtools \ ast wcssubs \ rice hcompress plio \ $(OPTDIR) \ saotk zip zvfs ds9 doc : FORCE @echo "Making Documentation..." cd $(DOCDIR); $(MAKE) #--------------------------language language: FORCE grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl da iso8859-1 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl de iso8859-1 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl es iso8859-1 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl fr iso8859-1 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl pt iso8859-1 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl cs iso8859-2 grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl ja euc-jp grep 'msgcat::mc' src/*.tcl | tclsh8.5 util/mergedict.tcl zh big5 #--------------------------items ds9 : scrub @echo "Making DS9..." cd $(DS9DIR); $(MAKE) ifeq ($(OS),macosx) ds9app : ds9 cd $(DS9DIR); $(MAKE) ds9app ds9dmg : FORCE rm -rf dist/$(DS9APP) rm -rf dist/$(DS9APP).dmg mkdir dist/$(DS9APP) ln -s /Applications dist/$(DS9APP)/. cp -r ds9/macosx/README dist/$(DS9APP)/. cp -rp bin/SAOImage\ DS9.app dist/$(DS9APP)/. hdiutil create -srcfolder dist/$(DS9APP) dist/$(DS9APP) endif ifeq ($(OS),windows) ds9app : ds9 cd $(DS9DIR); $(MAKE) ds9app ds9winzip : FORCE $(RM) -f dist/$(DS9APP)\ Install.* /cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip -p -r dist/$(DS9APP)\ Install.zip bin/ds9app # /cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE dist/$(DS9APP)\ Install.zip -setup -i ds9/win/ds9.ico -le -runasuser -t ds9/win/message.txt -a ds9/win/about.txt -c cscript install.vbs /cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE dist/$(DS9APP)\ Install.zip -d C:\\ds9 -i ds9/win/ds9.ico -le -overwrite -runasuser -c cscript install.vbs xpawinzip : FORCE $(RM) -f dist/$(XPAAPP)\ Install.* /cygdrive/c/Program\ Files\ \(x86\)/WinZip/wzzip dist/$(XPAAPP)\ Install.zip bin/xpa* bin/cygwin1.dll /cygdrive/c/Program\ Files\ \(x86\)/WinZip\ Self-Extractor/WINZIPSE.EXE dist/$(XPAAPP)\ Install.zip -d C:\\ds9 -le -overwrite -runasuser endif debug : FORCE @echo "Making DS9..." cd $(DS9DIR); $(MAKE) debug dirs : FORCE @echo "Installing Directories..." @for d in $(DIRS); do if [ ! -d $$d ]; then mkdir $$d; fi done tcl : FORCE @echo "Installing Tcl..." cd $(TCLDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) $(TCLFLAGS) --disable-shared --cache-file=$(CACHE) cd $(TCLDIRDIR); $(MAKE) -j $(JOBS); $(MAKE) install tk : FORCE @echo "Installing Tk..." cd $(TKDIRDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) $(TCLFLAGS) --disable-shared --cache-file=$(CACHE) cd $(TKDIRDIR); $(MAKE) -j $(JOBS); $(MAKE) install $(RM) -r lib/$(TKVER)/demos tktable : FORCE @echo "Installing TkTable..." cd $(TKTABLEDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) $(TKTABLEFLAGS) --disable-shared --cache-file=$(CACHE) cd $(TKTABLEDIR); $(MAKE) -j $(JOBS) ; $(MAKE) install tkcon : FORCE @echo "Installing TkCon..." $(RM) -r lib/$(TKCONVER) mkdir lib/$(TKCONVER) cp $(TKCONDIR)/*.tcl lib/$(TKCONVER) xmlrpc : FORCE @echo "Installing XMLRPC..." $(RM) -r lib/$(XMLRPCVER) mkdir lib/$(XMLRPCVER) cp $(XMLRPCDIR)/xmlrpc.tcl lib/$(XMLRPCVER) blt : FORCE @echo "Installing BLT..." cd $(BLTDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIR) --with-tk=$(root)/$(TKDIR) $(BLTFLAGS) --disable-shared --cache-file=$(CACHE) cd $(BLTDIR)/src; $(MAKE) -j $(JOBS) build_static cp $(BLTDIR)/src/*.a lib/. cd $(BLTDIR)/src; cp $(BLTINCL) ../../include/. zlib : FORCE @echo "Installing zlib..." cd $(ZLIBDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --static cd $(ZLIBDIR); $(MAKE) -j $(JOBS) install tclxml : FORCE @echo "Installing TCLXML..." cd $(TCLXMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --disable-shared --disable-threads --with-xml-static=1 $(TCLXMLFLAGS) --cache-file=$(CACHE) cd $(TCLXMLDIR); $(MAKE) -j $(JOBS) ; $(MAKE) install tkimg : libtiff @echo "Installing TKIMG..." cd $(TKIMGDIR); CC='$(CC)' CFLAGS='$(OPTS) -DPNG_NO_WRITE_gAMA' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) --with-tk=$(root)/$(TKDIRDIR) $(TKIMGFLAGS) --disable-shared --disable-threads --cache-file=$(LOCALCACHE) cd $(TKIMGDIR); $(MAKE) -j $(JOBS) all; $(MAKE) install libtiff : FORCE @echo "Installing LIBTIFF..." cd $(TKIMGDIR)/compat/libtiff; CC='$(CC)' CFLAGS='$(OPTS)' CXX='$(CC)' CXXFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --disable-shared --cache-file=$(LOCALCACHE) cd $(TKIMGDIR)/compat/libtiff; $(MAKE) -j $(JOBS) ; $(MAKE) install tkmpeg : FORCE @echo "Installing TKMPEG..." cd $(TKMPEGDIR); $(MAKE) -j $(JOBS) cd $(TKMPEGDIR); $(MAKE) install html : FORCE @echo "Installing HTMLWIDGET..." cd $(HTMLDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' $(PREHTMLFLAGS) $(root)/htmlwidget/configure --prefix $(root) --with-tcl=$(root)/$(TCLDIR) --with-tk=$(root)/$(TKDIR) $(XFLAGS) --enable-shared=no --cache-file=$(CACHE) cd $(HTMLDIR); $(MAKE) headers libtkhtml.a cp $(HTMLDIR)/libtkhtml.a lib/. xpa : FORCE @echo "Installing XPA..." cd $(XPADIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-tcl=$(root)/$(TCLDIRDIR) $(XPAFLAGS) --disable-shared --cache-file=$(CACHE) cd $(XPADIR); $(MAKE) -j $(JOBS); $(MAKE) install cd bin; strip xpa* iis : FORCE @echo "Installing IIS..." cd $(IISDIR); $(MAKE) -j $(JOBS) install checkdns: FORCE @echo "Installing CheckDNS..." cd $(CHECKDNSDIR); $(MAKE) -j $(JOBS) install signal: FORCE @echo "Installing Signal..." cd $(SIGNALDIR); $(MAKE) -j $(JOBS) install funtools: FORCE @echo "Installing Funtools..." cd $(FUNTOOLSDIR); CC='$(CC)' CFLAGS='$(OPTS)' LDFLAGS='$(LIBS)' ./configure --prefix $(root) --with-zlib=../../lib/libz.a --with-wcslib=../lib/libwcs.a --enable-mainlib $(FUNTOOLSFLAGS) cd $(FUNTOOLSDIR); $(MAKE) lib cp $(FUNTOOLSDIR)/libfuntools.a lib/. ast : FORCE @echo "Installing AST..." cd $(ASTDIR); \ touch aclocal.m4; sleep 1; \ touch Makefile.in; sleep 1; \ touch configure; \ ./configure --enable-shared=no --prefix=$(root) $(ASTFLAGS) CC='$(CC)' CFLAGS='$(OPTS) -I.'; \ $(MAKE) -j $(JOBS) ast.h install-libLTLIBRARIES install-nodist_includeHEADERS install-includeHEADERS wcssubs : FORCE @echo "Installing WCSSUBS..." cd $(WCSSUBSDIR); $(MAKE) -j $(JOBS) install rice : FORCE @echo "Installing RICE..." cd $(RICEDIR); $(MAKE) -j $(JOBS) install hcompress: FORCE @echo "Installing HCOMPRESS..." cd $(HCOMPRESSDIR); $(MAKE) -j $(JOBS) install plio: FORCE @echo "Installing PLIO..." cd $(PLIODIR); $(MAKE) -j $(JOBS) install ifdef OPTDIR $(OPTDIR) : FORCE @echo "Installing $(OPTDIR)..." cd $(OPTDIR); $(MAKE) -j $(JOBS) install endif saotk : FORCE @echo "Installing SAOTK..." cd $(SAOTKDIR); $(MAKE) -j $(JOBS) install zip : FORCE @echo "Installing ZIP..." cd $(ZIPDIR); PREFIX=$(root) $(MAKE) -j $(JOBS) CC='$(CC)' CFLAGS='$(OPTS) -I. -DUNIX' LFLAGS1='$(OPTS)' -f unix/Makefile generic cd $(ZIPDIR); PREFIX=$(root) $(MAKE) -j $(JOBS) CC='$(CC)' CFLAGS='$(OPTS) -I. -DUNIX' LFLAGS1='$(OPTS)' -f unix/Makefile install cd $(ZIPDIR); $(RM) libzip.a cd $(ZIPDIR); $(AR) -cr libzip.a $(ZIPOBJS) cp $(ZIPDIR)/libzip.a lib/. zvfs : FORCE @echo "Installing ZVFS..." cd $(ZVFSDIR); $(MAKE) cd $(ZVFSDIR); $(MAKE) install #--------------------------clean scrub : FORCE find . -name "*[~#]" -exec rm {} \; ifeq ($(OS),windows) find . -name "*stackdump*" -exec rm {} \; endif distclean : filesclean \ tclclean tkclean \ tktableclean bltclean \ zlibclean tclxmlclean tkimgclean tkmpegclean htmlclean \ xpaclean iisclean checkdnsclean $(SIGNALCLEAN) funtoolsclean \ astclean wcssubsclean \ riceclean hcompressclean plioclean \ $(OPTDIRCLEAN) \ saotkclean zipclean zvfsclean ds9clean srcclean \ dirsclean filesclean: FORCE find . -name "myconfig.cache" -exec rm {} \; $(RM) core *~ *# dirsclean: FORCE @for d in $(DIRS); do rm -rf $$d; done tclclean : FORCE cd $(TCLDIRDIR); $(MAKE) distclean tkclean : FORCE cd $(TKDIRDIR); $(MAKE) distclean tktableclean: FORCE cd $(TKTABLEDIR); $(MAKE) distclean bltclean: FORCE cd $(BLTDIR); $(MAKE) distclean zlibclean: FORCE cd $(ZLIBDIR); $(MAKE) distclean tclxmlclean: FORCE cd $(TCLXMLDIR); $(MAKE) distclean tkimgclean: libtiffclean rm -fr $(TKIMGDIR)/Img/* rm -fr $(LIB)/Img1.* cd $(TKIMGDIR); $(MAKE) distclean libtiffclean: FORCE cd $(TKIMGDIR)/compat/libtiff; $(MAKE) distclean tkmpegclean: FORCE cd $(TKMPEGDIR); $(MAKE) distclean htmlclean: FORCE cd $(HTMLDIR); $(MAKE) distclean xpaclean : FORCE cd $(XPADIR); $(MAKE) distclean iisclean : FORCE cd $(IISDIR); $(MAKE) distclean checkdnsclean : FORCE cd $(CHECKDNSDIR); $(MAKE) distclean signalclean : FORCE cd $(SIGNALDIR); $(MAKE) distclean funtoolsclean: FORCE cd $(FUNTOOLSDIR); $(MAKE) distclean astclean: FORCE cd $(ASTDIR); $(MAKE) distclean wcssubsclean: FORCE cd $(WCSSUBSDIR); $(MAKE) distclean riceclean: FORCE cd $(RICEDIR); $(MAKE) distclean hcompressclean: FORCE cd $(HCOMPRESSDIR); $(MAKE) distclean plioclean: FORCE cd $(PLIODIR); $(MAKE) distclean saotkclean : FORCE cd $(SAOTKDIR); $(MAKE) distclean zipclean: FORCE cd $(ZIPDIR); PREFIX=$(root) $(MAKE) -f unix/Makefile clean zvfsclean: FORCE cd $(ZVFSDIR); $(MAKE) distclean ds9clean : FORCE cd $(DS9DIR); $(MAKE) distclean srcclean : FORCE cd $(SRCDIR); $(MAKE) distclean unixclean : FORCE cd unix; $(MAKE) distclean winclean : FORCE cd win; $(MAKE) distclean macosxclean : FORCE cd macosx; $(MAKE) distclean #--------------------------cvs commit : FORCE cvs commit -m "" $(CVSFILES) update : FORCE cvs update $(CVSFILES) #--------------------------distribution dist : distds9 distxpa distall : distds9 distxpa distdoc distsource ifeq ($(OS),windows) distapp : distds9app distxpaapp endif ifeq ($(OS),macosx) distapp : distds9app endif ifdef CVS_SERVER #--------------------------remote distds9 : FORCE @echo "Creating SAODS9 Distribution" cd bin; tar cvf - ds9$(EXE) $(ZIPFILE) | gzip > ../dist/ds9.$(ARCH).$(DS9VERSION).tar.gz scp dist/ds9.$(ARCH).$(DS9VERSION).tar.gz $(USER)@$(DEST):build/$(ARCH)/. ssh $(USER)@$(DEST) 'cd build/$(ARCH); zcat ds9.$(ARCH).$(DS9VERSION).tar.gz | tar -xvf -' ifeq ($(OS),windows) distds9app : ds9winzip scp dist/$(DS9APP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/. endif ifeq ($(OS),macosx) distds9app : ds9dmg scp -r dist/$(DS9APP)/SAOImage\ DS9.app $(USER)@$(DEST):build/$(ARCH)/. scp dist/$(DS9APP).dmg $(USER)@$(DEST):build/$(ARCH)/. endif distxpa : FORCE @echo "Creating XPA Distribution" cd bin; tar cvf - xpa*$(EXE) |gzip > ../dist/xpa.$(ARCH).$(XPAVERSION).tar.gz scp dist/xpa.$(ARCH).$(XPAVERSION).tar.gz $(USER)@$(DEST):build/$(ARCH)/. ssh $(USER)@$(DEST) 'cd build/$(ARCH); zcat xpa.$(ARCH).$(XPAVERSION).tar.gz | tar -xvf -' ifeq ($(OS),windows) distxpaapp : xpawinzip @echo "Creating XPA Distribution" scp dist/$(XPAAPP)\ Install.exe $(USER)@$(DEST):build/$(ARCH)/. endif distdoc : doc @echo "Creating Documentation Distribution" scp -r doc $(USER)@$(DEST):build/. distsource : FORCE @echo "Creating Source Distribution" rm -rf dist/saods9 cd dist; cvs export -Dtoday saods9 cd dist/saods9; rm -rf notes mods admin cd dist; tar cvf - saods9 | gzip > ds9.$(DS9VERSION).tar.gz rm -rf dist/saods9 scp dist/ds9.$(DS9VERSION).tar.gz $(USER)@$(DEST):build/source/. #--------------------------remote else #--------------------------local distds9 : FORCE @echo "Creating SAODS9 Distribution" cd bin; tar cvf - ds9$(EXE) $(ZIPFILE) | gzip > ../dist/ds9.$(ARCH).$(DS9VERSION).tar.gz cp dist/ds9.$(ARCH).$(DS9VERSION).tar.gz $(HOME)/build/$(ARCH)/. cd $(HOME)/build/$(ARCH); $(ZCAT) ds9.$(ARCH).$(DS9VERSION).tar.gz | tar -xvf - ifeq ($(OS),windows) distds9app : ds9winzip cp dist/ds9.$(ARCH).$(DS9VERSION).exe $(HOME)/build/$(ARCH)/. endif ifeq ($(OS),macosx) distds9app : ds9dmg cp -r dist/$(DS9APP)/SAOImage\ DS9.app $(HOME)/build/$(ARCH)/. cp dist/$(DS9APP).dmg $(HOME)/build/$(ARCH)/. endif distxpa : FORCE @echo "Creating XPA Distribution" cd bin; tar cvf - xpa*$(EXE) |gzip > ../dist/xpa.$(ARCH).$(XPAVERSION).tar.gz cp dist/xpa.$(ARCH).$(XPAVERSION).tar.gz $(HOME)/build/$(ARCH)/. cd $(HOME)/build/$(ARCH); $(ZCAT) xpa.$(ARCH).$(XPAVERSION).tar.gz | tar -xvf - ifeq ($(OS),windows) distxpaapp : xpawinzip cp dist/xpa.$(ARCH).$(XPAVERSION).exe $(HOME)/build/$(ARCH)/. endif distdoc : doc @echo "Creating Documentation Distribution" cp -r doc $(HOME)/build/. distsource : FORCE @echo "Creating Source Distribution" rm -rf dist/saods9 cd dist; cvs export -Dtoday saods9 cd dist/saods9; rm -rf notes mods admin cd dist; tar cvf - saods9 | gzip > ds9.$(DS9VERSION).tar.gz rm -rf dist/saods9 cp dist/ds9.$(DS9VERSION).tar.gz $(HOME)/build/source/. #--------------------------local endif FORCE : ./saods9/make.darwin64x86leopard0000644000175000017500000000126111773331763015330 0ustar olesolesOS = unix ARCH = darwin64x86leopard X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation export MACOSX_DEPLOYMENT_TARGET := 10.5 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -m64 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-leopard.tar.gz ASTFLAGS = star_cv_cnf_trail_type=long JOBS = 4 ./saods9/make.darwin64x86mountainlion0000644000175000017500000000126312077031450016404 0ustar olesoles# make sure installed: PKG_CONFIG for Xft, see notes OS = unix ARCH = darwin64x86mountainlion X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -m64 -arch x86_64 -mmacosx-version-min=10.8 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz ASTFLAGS = star_cv_cnf_trail_type=long JOBS = 4 ./saods9/make.windows0000644000175000017500000000070511775370172013450 0ustar olesolesOS = windows ARCH = windows X11INCLUDE=../include/X11 XX = -O2 YY = -g ZZ = -DSTATIC_BUILD -mnop-fun-dllimport -DWIN32 -D_GNU_SOURCE AA = -D__WIN32__ -D_WIN32 -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = zcat EXE = .exe ZIPFILE = ds9.zip JOBS = 4 ./saods9/README0000644000175000017500000000434211775400302011765 0ustar olesoles************** Welcome to DS9 ************** Quick Instructions for those who hate to read instructions. After installation, ds9 can be located in saods9/bin/ds9. To build DS9, just cut and paste the following commands: *********** For Solaris *********** # WARNING: saods9 uses gnu make cd saods9 ln -s make.solaris make.include make ********* For Linux ********* cd saods9 ln -s make.linux make.include make ********* For Linux64 ********* cd saods9 ln -s make.linux64 make.include make ******************* For X11 MacOSX (Universal) ******************* cd saods9 ln -s make.darwintiger make.include or ln -s make.darwinleopard make.include or ln -s make.darwinsnowleopard make.include or ln -s make.darwinlion make.include make ******************* For Aqua MacOSX (Universal) ******************* cd saods9 ln -s make.macosxtiger make.include or ln -s make.macosxleopard make.include or ln -s make.macosxsnowleopard make.include or ln -s make.macosxlion make.include make make ds9app **************************** For Windows 7 **************************** # Obtain/install Cygwin from http://www.cygwin.com # Make sure you install the following programs (aside from gcc, make, etc.): # perl, cpio unzip # Make sure you install the following libraries: # tcl/tk, libxml2, libxml2-devel, libxslt libxslt-devel # Probably you also need to add saods9/bin and . to your path cd saods9 ln -s make.windows make.include make ******************* Building philosophy ******************* DS9 is a Tcl/Tk standalone application. It requires no support files, libraries, etc. To build DS9, you must also build Tcl, Tk, BLT, TkImg, TkHTML, TkTable, zlib, zip, zvfs, AST,and XPA, along with SAOtk. The makefiles handle all this for you, however, it takes some time and appears very messy. The current makefiles are targeted for: MAKE = gnu make 3.8 CC = gcc 4.x (minimum 3.4) CXX = g++ 4.x (minimum 3.4) YACC = bison 2.4 LEX = flex 2.5 X11 = R6 There are a number of issues to lead to the current set up. 1. DS9 comes with Tcl/Tk8.5.9. There are several modifications to the Tcl/Tk source code to provide support for certain features within DS9. Please use this version when building DS9. 2. The windows version is built with gcc under cygwin. ./saods9/tkmpeg/0000755000175000017500000000000012133201303012356 5ustar olesoles./saods9/tkmpeg/tkmpeg.h0000644000175000017500000000105511700667477014052 0ustar olesoles// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __tkmpeg_h__ #define __tkmpeg_h__ extern "C" { #include "ezmpeg.h" } class TkMPEG { private: Tcl_Interp* interp; ezMPEGStream ms; int width; int height; int fps; int gop; int quality; public: TkMPEG(Tcl_Interp*); ~TkMPEG(); int create(int, const char*[]); int add(int, const char*[]); int close(int, const char*[]); }; extern TkMPEG* tkmpeg; #endif ./saods9/tkmpeg/readme.txt0000644000175000017500000000233610036567765014413 0ustar olesolesezMPEG Copyright (C)2002 Ingo Oppermann (ingo_opp@users.sourceforge.net) 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., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- Welcome to ezMPEG http://sourceforge.net/projects/ezmpeg ezMPEG is an easy-to-use and easy-to-understand MPEG1 video encoder API The documentation of the API is still in development and incomplete. It can be found in 'doc/ezmpeg.txt' To use the API just include 'ezmpeg.h' in your files and compile with gcc yourfile.c ezmpeg.c -o yourfile -lm You are free to use any other C compiler than gcc./saods9/tkmpeg/Makefile0000644000175000017500000000067211517376116014047 0ustar olesolesinclude ../make.include # we must compile non-optimized (MacOSX) CXXFLAGS = $(CXXNOPT) -I../include -I$(X11INCLUDE) CFLAGS = $(CCNOPT) -I. SRC = tkmpeg.C CSRC = ezmpeg.c OBJS = $(SRC:%.C=%.o) COBJS = $(CSRC:%.c=%.o) LIB = libtkmpeg.a all : $(LIB) install : all cp -f $(LIB) ../lib/. $(LIB) : $(OBJS) $(COBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) $(COBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.a *.so *.o FORCE : ./saods9/tkmpeg/license-GER.txt0000644000175000017500000004374110036567764015217 0ustar olesolesGNU General Public License Deutsche Übersetzung der Version 2, Juni 1991 Copyright © 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA Diese Übersetzung ist kein rechtskräftiger Ersatz für die englischsprachige Originalversion! Vorwort Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die Freiheit zu nehmen, die Software weiterzugeben und zu verändern. Im Gegensatz dazu soll Ihnen die GNU General Public License , die Allgemeine Öffentliche GNU-Lizenz, ebendiese Freiheit garantieren. Sie soll sicherstellen, daß die Software für alle Benutzer frei ist. Diese Lizenz gilt für den Großteil der von der Free Software Foundation herausgegebenen Software und für alle anderen Programme, deren Autoren ihr Datenwerk dieser Lizenz unterstellt haben. Auch Sie können diese Möglichkeit der Lizenzierung für Ihre Programme anwenden. (Ein anderer Teil der Software der Free Software Foundation unterliegt stattdessen der GNU Library General Public License , der Allgemeinen Öffentlichen GNU-Lizenz für Bibliotheken.) [Mittlerweile wurde die GNU Library Public License von der GNU Lesser Public License abgelöst - Anmerkung des Übersetzers.] Die Bezeichnung ,,freie`` Software bezieht sich auf Freiheit, nicht auf den Preis. Unsere Lizenzen sollen Ihnen die Freiheit garantieren, Kopien freier Software zu verbreiten (und etwas für diesen Service zu berechnen, wenn Sie möchten), die Möglichkeit, die Software im Quelltext zu erhalten oder den Quelltext auf Wunsch zu bekommen. Die Lizenzen sollen garantieren, daß Sie die Software ändern oder Teile davon in neuen freien Programmen verwenden dürfen - und daß Sie wissen, daß Sie dies alles tun dürfen. Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie aufzufordern, auf diese Rechte zu verzichten. Aus diesen Einschränkungen folgen bestimmte Verantwortlichkeiten für Sie, wenn Sie Kopien der Software verbreiten oder sie verändern. Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die Sie selbst haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien eines solchen Programms verbreiten. Sie müssen sicherstellen, daß auch die Empfänger den Quelltext erhalten bzw. erhalten können. Und Sie müssen ihnen diese Bedingungen zeigen, damit sie ihre Rechte kennen. Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Software unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz an, die Ihnen das Recht gibt, die Software zu vervielfältigen, zu verbreiten und/oder zu verändern. Um die Autoren und uns zu schützen, wollen wir darüberhinaus sicherstellen, daß jeder erfährt, daß für diese freie Software keinerlei Garantie besteht. Wenn die Software von jemand anderem modifiziert und weitergegeben wird, möchten wir, daß die Empfänger wissen, daß sie nicht das Original erhalten haben, damit irgendwelche von anderen verursachte Probleme nicht den Ruf des ursprünglichen Autors schädigen. Schließlich und endlich ist jedes freie Programm permanent durch Software-Patente bedroht. Wir möchten die Gefahr ausschließen, daß Distributoren eines freien Programms individuell Patente lizensieren - mit dem Ergebnis, daß das Programm proprietär würde. Um dies zu verhindern, haben wir klargestellt, daß jedes Patent entweder für freie Benutzung durch jedermann lizenziert werden muß oder überhaupt nicht lizenziert werden darf. Es folgen die genauen Bedingungen für die Vervielfältigung, Verbreitung und Bearbeitung: Allgemeine Öffentliche GNU-Lizenz Bedingungen für die Vervielfältigung, Verbreitung und Bearbeitung §0. Diese Lizenz gilt für jedes Programm und jedes andere Datenwerk, in dem ein entsprechender Vermerk des Copyright-Inhabers darauf hinweist, daß das Datenwerk unter den Bestimmungen dieser General Public License verbreitet werden darf. Im folgenden wird jedes derartige Programm oder Datenwerk als ,,das Programm`` bezeichnet; die Formulierung ,,auf dem Programm basierendes Datenwerk`` bezeichnet das Programm sowie jegliche Bearbeitung des Programms im urheberrechtlichen Sinne, also ein Datenwerk, welches das Programm, auch auszugsweise, sei es unverändert oder verändert und/oder in eine andere Sprache übersetzt, enthält. (Im folgenden wird die Übersetzung ohne Einschränkung als ,,Bearbeitung`` eingestuft.) Jeder Lizenznehmer wird im folgenden als ,,Sie`` angesprochen. Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung werden von dieser Lizenz nicht berührt; sie fallen nicht in ihren Anwendungsbereich. Der Vorgang der Ausführung des Programms wird nicht eingeschränkt, und die Ausgaben des Programms unterliegen dieser Lizenz nur, wenn der Inhalt ein auf dem Programm basierendes Datenwerk darstellt (unabhängig davon, daß die Ausgabe durch die Ausführung des Programmes erfolgte). Ob dies zutrifft, hängt von den Funktionen des Programms ab. §1. Sie dürfen auf beliebigen Medien unveränderte Kopien des Quelltextes des Programms, wie sie ihn erhalten haben, anfertigen und verbreiten. Voraussetzung hierfür ist, daß Sie mit jeder Kopie einen entsprechenden Copyright-Vermerk sowie einen Haftungsausschluß veröffentlichen, alle Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie beziehen, unverändert lassen und desweiteren allen anderen Empfängern des Programms zusammen mit dem Programm eine Kopie dieser Lizenz zukommen lassen. Sie dürfen für den eigentlichen Kopiervorgang eine Gebühr verlangen. Wenn Sie es wünschen, dürfen Sie auch gegen Entgeld eine Garantie für das Programm anbieten. §2. Sie dürfen Ihre Kopie(n) des Programms oder eines Teils davon verändern, wodurch ein auf dem Programm basierendes Datenwerk entsteht; Sie dürfen derartige Bearbeitungen unter den Bestimmungen von Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, daß zusätzlich alle im folgenden genannten Bedingungen erfüllt werden: 1. Sie müssen die veränderten Dateien mit einem auffälligen Vermerk versehen, der auf die von Ihnen vorgenommene Modifizierung und das Datum jeder Änderung hinweist. 2. Sie müssen dafür sorgen, daß jede von Ihnen verbreitete oder veröffentlichte Arbeit, die ganz oder teilweise von dem Programm oder Teilen davon abgeleitet ist, Dritten gegenüber als Ganzes unter den Bedingungen dieser Lizenz ohne Lizenzgebühren zur Verfügung gestellt wird. 3. Wenn das veränderte Programm normalerweise bei der Ausführung interaktiv Kommandos einliest, müssen Sie dafür sorgen, daß es, wenn es auf dem üblichsten Wege für solche interaktive Nutzung gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen geeigneten Copyright-Vermerk enthält sowie einen Hinweis, daß es keine Gewährleistung gibt (oder anderenfalls, daß Sie Garantie leisten), und daß die Benutzer das Programm unter diesen Bedingungen weiter verbreiten dürfen. Auch muß der Benutzer darauf hingewiesen werden, wie er eine Kopie dieser Lizenz ansehen kann. (Ausnahme: Wenn das Programm selbst interaktiv arbeitet, aber normalerweise keine derartige Meldung ausgibt, muß Ihr auf dem Programm basierendes Datenwerk auch keine solche Meldung ausgeben). Diese Anforderungen gelten für das bearbeitete Datenwerk als Ganzes. Wenn identifizierbare Teile des Datenwerkes nicht von dem Programm abgeleitet sind und vernünftigerweise als unabhängige und eigenständige Datenwerke für sich selbst zu betrachten sind, dann gelten diese Lizenz und ihre Bedingungen nicht für die betroffenen Teile, wenn Sie diese als eigenständige Datenwerke weitergeben. Wenn Sie jedoch dieselben Abschnitte als Teil eines Ganzen weitergeben, das ein auf dem Programm basierendes Datenwerk darstellt, dann muß die Weitergabe des Ganzen nach den Bedingungen dieser Lizenz erfolgen, deren Bedingungen für weitere Lizenznehmer somit auf das gesamte Ganze ausgedehnt werden - und somit auf jeden einzelnen Teil, unabhängig vom jeweiligen Autor. Somit ist es nicht die Absicht dieses Abschnittes, Rechte für Datenwerke in Anspruch zu nehmen oder Ihnen die Rechte für Datenwerke streitig zu machen, die komplett von Ihnen geschrieben wurden; vielmehr ist es die Absicht, die Rechte zur Kontrolle der Verbreitung von Datenwerken, die auf dem Programm basieren oder unter seiner auszugsweisen Verwendung zusammengestellt worden sind, auszuüben. Ferner bringt auch das einfache Zusammenlegen eines anderen Datenwerkes, das nicht auf dem Programm basiert, mit dem Programm oder einem auf dem Programm basierenden Datenwerk auf ein- und demselben Speicher- oder Vertriebsmedium dieses andere Datenwerk nicht in den Anwendungsbereich dieser Lizenz. §3. Sie dürfen das Programm (oder ein darauf basierendes Datenwerk gemäß Paragraph 2) als Objectcode oder in ausführbarer Form unter den Bedingungen der Paragraphen 1 und 2 kopieren und weitergeben - vorausgesetzt, daß Sie außerdem eine der folgenden Leistungen erbringen: 1. Liefern Sie das Programm zusammen mit dem vollständigen zugehörigen maschinenlesbaren Quelltext auf einem für den Datenaustausch üblichen Medium aus, wobei die Verteilung unter den Bedingungen der Paragraphen 1 und 2 erfolgen muß. Oder: 2. Liefern Sie das Programm zusammen mit einem mindestens drei Jahre lang gültigen schriftlichen Angebot aus, jedem Dritten eine vollständige maschinenlesbare Kopie des Quelltextes zur Verfügung zu stellen - zu nicht höheren Kosten als denen, die durch den physikalischen Kopiervorgang anfallen -, wobei der Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf einem für den Datenaustausch üblichen Medium weitergegeben wird. Oder: 3. Liefern Sie das Programm zusammen mit dem schriftlichen Angebot der Zurverfügungstellung des Quelltextes aus, das Sie selbst erhalten haben. (Diese Alternative ist nur für nicht-kommerzielle Verbreitung zulässig und nur, wenn Sie das Programm als Objectcode oder in ausführbarer Form mit einem entsprechenden Angebot gemäß Absatz b erhalten haben.) Unter dem Quelltext eines Datenwerkes wird diejenige Form des Datenwerkes verstanden, die für Bearbeitungen vorzugsweise verwendet wird. Für ein ausführbares Programm bedeutet ,,der komplette Quelltext``: Der Quelltext aller im Programm enthaltenen Module einschließlich aller zugehörigen Modulschnittstellen-Definitionsdateien sowie der zur Compilation und Installation verwendeten Skripte. Als besondere Ausnahme jedoch braucht der verteilte Quelltext nichts von dem zu enthalten, was üblicherweise (entweder als Quelltext oder in binärer Form) zusammen mit den Hauptkomponenten des Betriebssystems (Kernel, Compiler usw.) geliefert wird, unter dem das Programm läuft - es sei denn, diese Komponente selbst gehört zum ausführbaren Programm. Wenn die Verbreitung eines ausführbaren Programms oder von Objectcode dadurch erfolgt, daß der Kopierzugriff auf eine dafür vorgesehene Stelle gewährt wird, so gilt die Gewährung eines gleichwertigen Zugriffs auf den Quelltext als Verbreitung des Quelltextes, auch wenn Dritte nicht dazu gezwungen sind, den Quelltext zusammen mit dem Objectcode zu kopieren. §4. Sie dürfen das Programm nicht vervielfältigen, verändern, weiter lizenzieren oder verbreiten, sofern es nicht durch diese Lizenz ausdrücklich gestattet ist. Jeder anderweitige Versuch der Vervielfältigung, Modifizierung, Weiterlizenzierung und Verbreitung ist nichtig und beendet automatisch Ihre Rechte unter dieser Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen Kopien oder Rechte unter dieser Lizenz erhalten haben, nicht beendet, solange diese die Lizenz voll anerkennen und befolgen. §5. Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie sie nicht unterzeichnet haben. Jedoch gibt Ihnen nichts anderes die Erlaubnis, das Programm oder von ihm abgeleitete Datenwerke zu verändern oder zu verbreiten. Diese Handlungen sind gesetzlich verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das Programm (oder ein darauf basierendes Datenwerk) verändern oder verbreiten, erklären Sie Ihr Einverständnis mit dieser Lizenz und mit allen ihren Bedingungen bezüglich der Vervielfältigung, Verbreitung und Veränderung des Programms oder eines darauf basierenden Datenwerks. §6. Jedesmal, wenn Sie das Programm (oder ein auf dem Programm basierendes Datenwerk) weitergeben, erhält der Empfänger automatisch vom ursprünglichen Lizenzgeber die Lizenz, das Programm entsprechend den hier festgelegten Bestimmungen zu vervielfältigen, zu verbreiten und zu verändern. Sie dürfen keine weiteren Einschränkungen der Durchsetzung der hierin zugestandenen Rechte des Empfängers vornehmen. Sie sind nicht dafür verantwortlich, die Einhaltung dieser Lizenz durch Dritte durchzusetzen. §7. Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer Patentverletzung oder aus einem anderen Grunde (nicht auf Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschluß, Vergleich oder anderweitig) auferlegt werden, die den Bedingungen dieser Lizenz widersprechen, so befreien Sie diese Umstände nicht von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist, das Programm unter gleichzeitiger Beachtung der Bedingungen in dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu verbreiten, dann dürfen Sie als Folge das Programm überhaupt nicht verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie Weiterverbreitung des Programms durch diejenigen erlaubt, die das Programm direkt oder indirekt von Ihnen erhalten haben, dann besteht der einzige Weg, sowohl das Patentrecht als auch diese Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms zu verzichten. Sollte sich ein Teil dieses Paragraphen als ungültig oder unter bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser Paragraph seinem Sinne nach angewandt werden; im übrigen soll dieser Paragraph als Ganzes gelten. Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, irgendwelche Patente oder andere Eigentumsansprüche zu verletzen oder die Gültigkeit solcher Ansprüche zu bestreiten; dieser Paragraph hat einzig den Zweck, die Integrität des Verbreitungssystems der freien Software zu schützen, das durch die Praxis öffentlicher Lizenzen verwirklicht wird. Viele Leute haben großzügige Beiträge zu dem großen Angebot der mit diesem System verbreiteten Software im Vertrauen auf die konsistente Anwendung dieses Systems geleistet; es liegt am Autor/Geber, zu entscheiden, ob er die Software mittels irgendeines anderen Systems verbreiten will; ein Lizenznehmer hat auf diese Entscheidung keinen Einfluß. Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als Konsequenz aus dem Rest dieser Lizenz betrachtet wird. §8. Wenn die Verbreitung und/oder die Benutzung des Programms in bestimmten Staaten entweder durch Patente oder durch urheberrechtlich geschützte Schnittstellen eingeschränkt ist, kann der Urheberrechtsinhaber, der das Programm unter diese Lizenz gestellt hat, eine explizite geographische Begrenzung der Verbreitung angeben, in der diese Staaten ausgeschlossen werden, so daß die Verbreitung nur innerhalb und zwischen den Staaten erlaubt ist, die nicht ausgeschlossen sind. In einem solchen Fall beinhaltet diese Lizenz die Beschränkung, als wäre sie in diesem Text niedergeschrieben. §9. Die Free Software Foundation kann von Zeit zu Zeit überarbeitete und/oder neue Versionen der General Public License veröffentlichen. Solche neuen Versionen werden vom Grundprinzip her der gegenwärtigen entsprechen, können aber im Detail abweichen, um neuen Problemen und Anforderungen gerecht zu werden. Jede Version dieser Lizenz hat eine eindeutige Versionsnummer. Wenn in einem Programm angegeben wird, daß es dieser Lizenz in einer bestimmten Versionsnummer oder ,,jeder späteren Version`` (``any later version'') unterliegt, so haben Sie die Wahl, entweder den Bestimmungen der genannten Version zu folgen oder denen jeder beliebigen späteren Version, die von der Free Software Foundation veröffentlicht wurde. Wenn das Programm keine Versionsnummer angibt, können Sie eine beliebige Version wählen, die je von der Free Software Foundation veröffentlicht wurde. §10. Wenn Sie den Wunsch haben, Teile des Programms in anderen freien Programmen zu verwenden, deren Bedingungen für die Verbreitung anders sind, schreiben Sie an den Autor, um ihn um die Erlaubnis zu bitten. Für Software, die unter dem Copyright der Free Software Foundation steht, schreiben Sie an die Free Software Foundation ; wir machen zu diesem Zweck gelegentlich Ausnahmen. Unsere Entscheidung wird von den beiden Zielen geleitet werden, zum einen den freien Status aller von unserer freien Software abgeleiteten Datenwerke zu erhalten und zum anderen das gemeinschaftliche Nutzen und Wiederverwenden von Software im allgemeinen zu fördern. Keine Gewährleistung §11. Da das Programm ohne jegliche Kosten lizenziert wird, besteht keinerlei Gewährleistung für das Programm, soweit dies gesetzlich zulässig ist. Sofern nicht anderweitig schriftlich bestätigt, stellen die Copyright-Inhaber und/oder Dritte das Programm so zur Verfügung, ,,wie es ist``, ohne irgendeine Gewährleistung, weder ausdrücklich noch implizit, einschließlich - aber nicht begrenzt auf - Marktreife oder Verwendbarkeit für einen bestimmten Zweck. Das volle Risiko bezüglich Qualität und Leistungsfähigkeit des Programms liegt bei Ihnen. Sollte sich das Programm als fehlerhaft herausstellen, liegen die Kosten für notwendigen Service, Reparatur oder Korrektur bei Ihnen. §12. In keinem Fall, außer wenn durch geltendes Recht gefordert oder schriftlich zugesichert, ist irgendein Copyright-Inhaber oder irgendein Dritter, der das Programm wie oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber für irgendwelche Schäden haftbar, einschließlich jeglicher allgemeiner oder spezieller Schäden, Schäden durch Seiteneffekte (Nebenwirkungen) oder Folgeschäden, die aus der Benutzung des Programms oder der Unbenutzbarkeit des Programms folgen (einschließlich - aber nicht beschränkt auf - Datenverluste, fehlerhafte Verarbeitung von Daten, Verluste, die von Ihnen oder anderen getragen werden müssen, oder dem Unvermögen des Programms, mit irgendeinem anderen Programm zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber oder Dritter über die Möglichkeit solcher Schäden unterrichtet worden war. Ende der Bedingungen ./saods9/tkmpeg/ezmpeg.h0000644000175000017500000000466310035565556014055 0ustar olesoles//This file is part of ezMPEG //Copyright (C)2002 Ingo Oppermann ( ingo_opp@users.sourceforge.net / http://sourceforge.net/projects/ezmpeg/ ) // //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. // Version 0.1 typedef struct ezMPEGStream { char *outfile; FILE *out; int hsize; int vsize; int picture_rate; int gop_size; int dc_prev[3]; double q_scale; int picture_count; int buffersize; int buffercount; char *buffer; int buf; int pos; short error_code; char error_msg[256]; } ezMPEGStream; typedef struct Block { float a[64]; } Block; typedef struct Macroblock { Block lum[4]; Block chrom[2]; } Macroblock; // Prototypes // 'sichtbare' Funktionen. Nur diese 5 Funktionen werden direkt benutzt int ezMPEG_Init(ezMPEGStream *ms, const char *outfile, int hsize, int vsize, int picture_rate, int gop_size, int q_scale); int ezMPEG_Start(ezMPEGStream *ms); int ezMPEG_Add(ezMPEGStream *ms, unsigned char *picture); int ezMPEG_Finalize(ezMPEGStream *ms); void ezMPEG_Resize(ezMPEGStream *ms, unsigned char *outbild, unsigned char *inbild, int x, int y, int u, int v); char *ezMPEG_GetLastError(ezMPEGStream *ms); // 'unsichtbare' Funktionen void ezMPEG_InitBitBuffer(ezMPEGStream *ms); void ezMPEG_ByteAlign(ezMPEGStream *ms); int ezMPEG_WriteBits(ezMPEGStream *ms, unsigned int value, int length); void ezMPEG_WriteSequenceHeader(ezMPEGStream *ms); void ezMPEG_WriteGOPHeader(ezMPEGStream *ms); void ezMPEG_WritePictureHeader(ezMPEGStream *ms); Macroblock ezMPEG_GetMacroblock(ezMPEGStream *ms, unsigned char *picture, int number); Macroblock ezMPEG_QuantizeMacroblock(ezMPEGStream *ms, Macroblock mb); void ezMPEG_WriteMacroblock(ezMPEGStream *ms, Macroblock mb); float ezMPEG_1DFDCT(float *v, int i); void ezMPEG_EncodeDC(ezMPEGStream *ms, int dc_diff, int type); void ezMPEG_EncodeAC(ezMPEGStream *ms, int runlength, int level); void ezMPEG_FlushBuffer(ezMPEGStream *ms); void ezMPEG_SetError(ezMPEGStream *ms, const char *error_msg); ./saods9/tkmpeg/tkmpeg.C0000644000175000017500000001022711750571573014002 0ustar olesoles// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include #include using namespace std; #include #include #include "tkmpeg.h" extern "C" { int Tkmpeg_Init(Tcl_Interp* interp); int TkmpegCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]); } TkMPEG* tkmpeg=NULL; int Tkmpeg_Init(Tcl_Interp* interp) { // Define Package Name if (Tcl_PkgProvide(interp, "tkmpeg", "1.0") == TCL_ERROR) return TCL_ERROR; // Commands Tcl_CreateCommand(interp, "mpeg", TkmpegCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); tkmpeg = new TkMPEG(interp); if (tkmpeg) return TCL_OK; else return TCL_ERROR; } int TkmpegCmd(ClientData data,Tcl_Interp *interp,int argc,const char* argv[]) { if (argc>=2) { if (!strncmp(argv[1], "create", 3)) return tkmpeg->create(argc, argv); else if (!strncmp(argv[1], "add", 3)) return tkmpeg->add(argc, argv); else if (!strncmp(argv[1], "close", 3)) return tkmpeg->close(argc, argv); else { Tcl_AppendResult(interp, "tkmpeg: unknown command: ", argv[1], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkmpeg ?create?close?add?", NULL); return TCL_ERROR; } } TkMPEG::TkMPEG(Tcl_Interp* intp) { interp = intp; width = 512; height = 512; quality = 2; } int TkMPEG::create(int argc, const char* argv[]) { if (argc == 8) { if (argv[2] == '\0') { Tcl_AppendResult(interp, "bad filename", NULL); return TCL_ERROR; } { string s(argv[3]); istringstream str(s); str >> width; } { string s(argv[4]); istringstream str(s); str >> height; } { string s(argv[5]); istringstream str(s); str >> fps; } { string s(argv[6]); istringstream str(s); str >> gop; } { string s(argv[7]); istringstream str(s); str >> quality; } // width and height must be a multiple of 16 int ww = int(width/16.+1)*16; int hh = int(height/16.+1)*16; if(!ezMPEG_Init(&ms, argv[2], ww, hh, fps, gop, quality)) { Tcl_AppendResult(interp, "ezMPEG_Init ", ezMPEG_GetLastError(&ms), NULL); return TCL_ERROR; } if(!ezMPEG_Start(&ms)) { Tcl_AppendResult(interp, "ezMPEG_Start ", ezMPEG_GetLastError(&ms),NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkmpeg create ", NULL); return TCL_ERROR; } return TCL_OK; } int TkMPEG::add(int argc, const char* argv[]) { if (argv[2] == '\0') { Tcl_AppendResult(interp, "bad image name", NULL); return TCL_ERROR; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, argv[2]); if (!photo) { Tcl_AppendResult(interp, "bad image handle", NULL); return TCL_ERROR; } Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block", NULL); return TCL_ERROR; } int ww = ms.hsize*16; int hh = ms.vsize*16; unsigned char* pict = new unsigned char[ww*hh*3]; if (!pict) { Tcl_AppendResult(interp, "unable to alloc memory", NULL); return TCL_ERROR; } memset(pict,0,ww*hh*3); unsigned char* src = block.pixelPtr; unsigned char* dst = pict; for (int jj=0; jj #include #include #include #include "ezmpeg.h" #define c(i) (((i) == 0) ? 0.3535534 : 0.5) // 1 / (0.5 * sqrt(2)) #define LUMINANCE 1 #define CHROMINANCE 2 int zigzag[64] = {0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63}; // Quantisierungsmatrix float intraquant[64] = {8.0, 16.0, 19.0, 22.0, 26.0, 27.0, 29.0, 34.0, 16.0, 16.0, 22.0, 24.0, 27.0, 29.0, 34.0, 37.0, 19.0, 22.0, 26.0, 27.0, 29.0, 34.0, 34.0, 38.0, 22.0, 22.0, 26.0, 27.0, 29.0, 34.0, 37.0, 40.0, 22.0, 26.0, 27.0, 29.0, 32.0, 35.0, 40.0, 48.0, 26.0, 27.0, 29.0, 32.0, 35.0, 40.0, 48.0, 58.0, 26.0, 27.0, 29.0, 34.0, 38.0, 46.0, 56.0, 69.0, 27.0, 29.0, 35.0, 38.0, 46.0, 56.0, 69.0, 83.0}; // Cosinustabelle float fcostable[32]; // Macroblock Address Increment VLC (Tabelle B.1) int macroblock_address_increment_code[36] = {0x0, 0x1, 0x3, 0x2, 0x3, 0x2, 0x3, 0x2, 0x7, 0x6, 0xB, 0xA, 0x9, 0x8, 0x7, 0x6, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xF, 0x8}; int macroblock_address_increment_length[36] = {0, 1, 3, 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}; #define MACROBLOCK_STUFFING 34 #define MACROBLOCK_ESCAPE 35 // Index des Arrays ist size, von 0 bis 8 (Tabelle D.12) int diff_dc_size_codes_lum[9] = {0x4, 0x0, 0x1, 0x5, 0x6, 0xE, 0x1E, 0x3E, 0x7E}; int diff_dc_size_length_lum[9] = {3, 2, 2, 3, 3, 4, 5, 6, 7}; int diff_dc_size_codes_chrom[9] = {0x0, 0x1, 0x2, 0x6, 0xE, 0x1E, 0x3E, 0x7E, 0xFE}; int diff_dc_size_length_chrom[9] = {2, 2, 2, 3, 4, 5, 6, 7, 8}; // Index des Arrays ist size, von 0 bis 8 (Tabelle D.13) int diff_dc_add_codes_pos[9] = {0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; int diff_dc_add_codes_neg[9] = {0x0, 0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F}; int diff_dc_add_length[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; // Tabelle D.15, der Index ist level ohne Vorzeichen, das muss noch extra hinzugefügt werden! // Bei Index==0 steht drin, wieviele Levels da sind int ac_codes_intra0[41] = {40, 3, 4, 5, 6, 38, 33, 10, 29, 24, 19, 16, 26, 25, 24, 23, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 24, 23, 22, 21, 20, 19, 18, 17, 16}; int ac_length_intra0[41] = {0, 2, 4, 5, 7, 8, 8, 10, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}; int ac_codes_intra1[19] = {18, 3, 6, 37, 12, 27, 22, 21, 31, 30, 29, 28, 27, 26, 25, 19, 18, 17, 16}; int ac_length_intra1[19] = {0, 3, 6, 8, 10, 12, 13, 13, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16}; int ac_codes_intra2[6] = {5, 5, 4, 11, 20, 20}; int ac_length_intra2[6] = {0, 4, 7, 10, 12, 13}; int ac_codes_intra3[5] = {4, 7, 36, 28, 19}; int ac_length_intra3[5] = {0, 5, 8, 12, 13}; int ac_codes_intra4[4] = {3, 6, 15, 18}; int ac_length_intra4[4] = {0, 5, 10, 12}; int ac_codes_intra5[4] = {3, 7, 9, 18}; int ac_length_intra5[4] = {0, 6, 10, 13}; int ac_codes_intra6[4] = {3, 5, 30, 20}; int ac_length_intra6[4] = {0, 6, 12, 16}; int ac_codes_intra7[3] = {2, 4, 21}; int ac_length_intra7[3] = {0, 6, 12}; int ac_codes_intra8[3] = {2, 7, 17}; int ac_length_intra8[3] = {0, 7, 12}; int ac_codes_intra9[3] = {2, 5, 17}; int ac_length_intra9[3] = {0, 7, 13}; int ac_codes_intra10[3] = {2, 39, 16}; int ac_length_intra10[3] = {0, 8, 13}; int ac_codes_intra11[3] = {2, 35, 26}; int ac_length_intra11[3] = {0, 8, 16}; int ac_codes_intra12[3] = {2, 34, 25}; int ac_length_intra12[3] = {0, 8, 16}; int ac_codes_intra13[3] = {2, 32, 24}; int ac_length_intra13[3] = {0, 8, 16}; int ac_codes_intra14[3] = {2, 14, 23}; int ac_length_intra14[3] = {0, 10, 16}; int ac_codes_intra15[3] = {2, 13, 22}; int ac_length_intra15[3] = {0, 10, 16}; int ac_codes_intra16[3] = {2, 8, 21}; int ac_length_intra16[3] = {0, 10, 16}; int ac_codes_intra17[2] = {1, 31}; int ac_length_intra17[2] = {0, 12}; int ac_codes_intra18[2] = {1, 26}; int ac_length_intra18[2] = {0, 12}; int ac_codes_intra19[2] = {1, 25}; int ac_length_intra19[2] = {0, 12}; int ac_codes_intra20[2] = {1, 23}; int ac_length_intra20[2] = {0, 12}; int ac_codes_intra21[2] = {1, 22}; int ac_length_intra21[2] = {0, 12}; int ac_codes_intra22[2] = {1, 31}; int ac_length_intra22[2] = {0, 13}; int ac_codes_intra23[2] = {1, 30}; int ac_length_intra23[2] = {0, 13}; int ac_codes_intra24[2] = {1, 29}; int ac_length_intra24[2] = {0, 13}; int ac_codes_intra25[2] = {1, 28}; int ac_length_intra25[2] = {0, 13}; int ac_codes_intra26[2] = {1, 27}; int ac_length_intra26[2] = {0, 13}; int ac_codes_intra27[2] = {1, 31}; int ac_length_intra27[2] = {0, 16}; int ac_codes_intra28[2] = {1, 30}; int ac_length_intra28[2] = {0, 16}; int ac_codes_intra29[2] = {1, 29}; int ac_length_intra29[2] = {0, 16}; int ac_codes_intra30[2] = {1, 28}; int ac_length_intra30[2] = {0, 16}; int ac_codes_intra31[2] = {1, 27}; int ac_length_intra31[2] = {0, 16}; int *ac_codes_intra[] = { ac_codes_intra0, ac_codes_intra1, ac_codes_intra2, ac_codes_intra3, ac_codes_intra4, ac_codes_intra5, ac_codes_intra6, ac_codes_intra7, ac_codes_intra8, ac_codes_intra9, ac_codes_intra10, ac_codes_intra11, ac_codes_intra12, ac_codes_intra13, ac_codes_intra14, ac_codes_intra15, ac_codes_intra16, ac_codes_intra17, ac_codes_intra18, ac_codes_intra19, ac_codes_intra20, ac_codes_intra21, ac_codes_intra22, ac_codes_intra23, ac_codes_intra24, ac_codes_intra25, ac_codes_intra26, ac_codes_intra27, ac_codes_intra28, ac_codes_intra29, ac_codes_intra30, ac_codes_intra31}; int *ac_length_intra[] = { ac_length_intra0, ac_length_intra1, ac_length_intra2, ac_length_intra3, ac_length_intra4, ac_length_intra5, ac_length_intra6, ac_length_intra7, ac_length_intra8, ac_length_intra9, ac_length_intra10, ac_length_intra11, ac_length_intra12, ac_length_intra13, ac_length_intra14, ac_length_intra15, ac_length_intra16, ac_length_intra17, ac_length_intra18, ac_length_intra19, ac_length_intra20, ac_length_intra21, ac_length_intra22, ac_length_intra23, ac_length_intra24, ac_length_intra25, ac_length_intra26, ac_length_intra27, ac_length_intra28, ac_length_intra29, ac_length_intra30, ac_length_intra31}; // Spezielle Codes int ac_codes_special[2] = {2, 1}; int ac_length_special[2] = {2, 6}; #define BLOCK_EOB 0 #define BLOCK_ESCAPE 1 int ezMPEG_Init(ezMPEGStream *ms, const char *outfile, int hsize, int vsize, int picture_rate, int gop_size, int q_scale) { int i, j; if(ms == NULL) return 0; if(outfile == NULL) { ezMPEG_SetError(ms, "ezMPEG_Init: Please specify an output filename"); return 0; } if(hsize < 16 || hsize > 768) { ezMPEG_SetError(ms, "ezMPEG_Init: Horizontal size should be between 16 and 768"); return 0; } if(vsize < 16 || vsize > 576) { ezMPEG_SetError(ms, "ezMPEG_Init: Vertical size should be between 16 and 576"); return 0; } if(picture_rate != 25) { ezMPEG_SetError(ms, "ezMPEG_Init: Picture rate should be 25 (for now)"); return 0; } if(gop_size == 0) { ezMPEG_SetError(ms, "ezMPEG_Init: GOP size should be 1 or greater"); return 0; } if(q_scale < 1 || q_scale > 31) { ezMPEG_SetError(ms, "ezMPEG_Init: Quantizer scale should be between 1 and 31"); return 0; } ms->outfile = (char *)malloc((strlen(outfile) + 1) * sizeof(char)); if(!ms->outfile) { ezMPEG_SetError(ms, "ezMPEG_Init: Couldn't allocate enough memory"); return 0; } strcpy(ms->outfile, outfile); ms->hsize = hsize / 16; ms->vsize = vsize / 16; ms->picture_rate = picture_rate; // picture_rate; ms->gop_size = gop_size; ms->dc_prev[0] = 128; ms->dc_prev[1] = 128; ms->dc_prev[2] = 128; ms->q_scale = (float)q_scale; // Versteckte Felder ms->picture_count = 0; ms->buffersize = 8192; ms->buffercount = 0; ms->buffer = (char *)malloc(ms->buffersize * sizeof(char)); if(!ms->buffer) { ezMPEG_SetError(ms, "ezMPEG_Init: Couldn't allocate enough memory"); return 0; } ms->error_code = 0; strcpy(ms->error_msg, ""); // Cosinustabelle füllen for(i = 0; i < 8; i++) { for(j = 0; j < 4; j++) { if((i % 2)) // ungerade fcostable[i * 4 + j] = cos((M_PI * (2.0 * (float)j + 1.0) / 16.0) + (M_PI * (float)((i - 1) / 2) * (2.0 * (float)j + 1.0) / 8.0)); else fcostable[i * 4 + j] = cos(M_PI * (float)(i / 2) * (2.0 * (float)j + 1.0) / 8.0); } } return 1; } int ezMPEG_Start(ezMPEGStream *ms) { if(ms == NULL) return 0; // Datei zum Reinschreiben aufmachen ms->out = fopen(ms->outfile, "wb"); if(ms->out == NULL) { ezMPEG_SetError(ms, "ezMPEG_Start: Couldn't open output file"); return 0; } // BitBuffer initialisieren ezMPEG_InitBitBuffer(ms); // MPEG Video Sequence Header schreiben ezMPEG_WriteSequenceHeader(ms); if(ms->error_code) return 0; return 1; } void ezMPEG_WriteSequenceHeader(ezMPEGStream *ms) { ezMPEG_ByteAlign(ms); ezMPEG_WriteBits(ms, 0x1B3, 32); // sequence_header_code ezMPEG_WriteBits(ms, ms->hsize & 0xFF, 8); // horizontal_size (in Macroblocks) ezMPEG_WriteBits(ms, (ms->hsize >> 8) & 0xF, 4); // ezMPEG_WriteBits(ms, ms->vsize & 0xFF, 8); // vertical_size (in Macroblocks) ezMPEG_WriteBits(ms, (ms->vsize >> 8) & 0xF, 4); // ezMPEG_WriteBits(ms, 1, 4); // pel_aspect_ratio (1:1) ezMPEG_WriteBits(ms, 3, 4); // picture_rate (25Hz) ezMPEG_WriteBits(ms, 0xFFFF, 16); // variable_length_bitrate (18x 1) ezMPEG_WriteBits(ms, 0x3, 2); // ezMPEG_WriteBits(ms, 1, 1); // marker_bit (1) ezMPEG_WriteBits(ms, 20, 10); // vbv_buffer_size (20) ezMPEG_WriteBits(ms, 1, 1); // constrained_parameter_flags (1) ezMPEG_WriteBits(ms, 0, 1); // load_intra_quantizer_matrix (0) ezMPEG_WriteBits(ms, 0, 1); // load_non_intra_quantizer_maxtrix (0) if(ms->error_code) strcpy(ms->error_msg, "ezMPEG_WriteSequenceHeader: Couldn't write sequence header"); return; } void ezMPEG_InitBitBuffer(ezMPEGStream *ms) { ezMPEG_WriteBits(ms, 0, -1); return; } void ezMPEG_ByteAlign(ezMPEGStream *ms) { ezMPEG_WriteBits(ms, 0, -2); return; } int ezMPEG_WriteBits(ezMPEGStream *ms, unsigned int value, int length) { int temp; if(length == -1) { ms->buf = 0; ms->pos = 0; return 1; } if(length == -2) { if(ms->pos == 0) return 1; length = 8 - ms->pos; value = 0; } do { if(length >= 8) { temp = value >> ((length - 8) + ms->pos); ms->buf += temp; ms->buffer[ms->buffercount++] = ms->buf; length -= (8 - ms->pos); ms->pos = 0; ms->buf = 0; } else { if(length + ms->pos < 8) { temp = value << (8 - length); temp = temp & 0xFF; temp = temp >> ms->pos; ms->buf += temp; ms->pos += length; length = 0; } else { temp = value << (8 - length); temp = temp & 0xFF; temp = temp >> ms->pos; ms->buf += temp; ms->buffer[ms->buffercount++] = ms->buf; length -= (8 - ms->pos); ms->buf = 0; ms->pos = 0; } } if(ms->buffercount >= ms->buffersize) { if(fwrite(ms->buffer, ms->buffercount, 1, ms->out) < 1) { ezMPEG_SetError(ms, "ezMPEG_WriteBits: Couldn't write buffer to file"); return 0; } ms->buffercount = 0; } }while(length != 0); return 1; } int ezMPEG_Add(ezMPEGStream *ms, unsigned char *picture) { int m; Macroblock mb; // Schauen, ob eine neue GOP angefangen werden muss if(ms->picture_count % ms->gop_size == 0) ezMPEG_WriteGOPHeader(ms); ezMPEG_WritePictureHeader(ms); for(m = 0; m < ms->hsize * ms->vsize; m++) { // Das Bild in Macroblocks und YCbCr umwandeln mb = ezMPEG_GetMacroblock(ms, picture, m /* Nummer */); // Das Bild transformieren und scalieren mb = ezMPEG_QuantizeMacroblock(ms, mb); // Macroblock codieren und schreiben ezMPEG_WriteMacroblock(ms, mb); } ms->picture_count++; if(ms->error_code) return 0; return 1; } void ezMPEG_WriteMacroblock(ezMPEGStream *ms, Macroblock mb) { int j, k, run, level, dc_diff; // Macroblock Header, macroblock_address_increment ezMPEG_WriteBits(ms, macroblock_address_increment_code[1], macroblock_address_increment_length[1]); if(ms->q_scale != 1.0) { ezMPEG_WriteBits(ms, 1, 2); // macroblock_type (I-Block, intra-q) ezMPEG_WriteBits(ms, (int)ms->q_scale, 5); // nochmals quantizer_scale wie im Slice } else ezMPEG_WriteBits(ms, 1, 1); // macroblock_type (I-Block, intra-d) // Ueber jeden Block in diesem Macroblock gehen (zuerst Luminance) for(j = 0; j < 4; j++) { // DC-Koeffizienten codieren mb.lum[j].a[0] += (mb.lum[j].a[0] > 0.0) ? 0.5 : -0.5; dc_diff = (int)mb.lum[j].a[0] - ms->dc_prev[0]; ezMPEG_EncodeDC(ms, dc_diff, LUMINANCE); ms->dc_prev[0] += dc_diff; // AC-Koeffizienten Runlength codieren run = 0; level = 0; for(k = 1; k < 64; k++) { mb.lum[j].a[zigzag[k]] += (mb.lum[j].a[zigzag[k]] > 0.0) ? 0.5 : -0.5; level = (int)mb.lum[j].a[zigzag[k]]; if(level != 0) { ezMPEG_EncodeAC(ms, run, level); run = 0; } else run++; } ezMPEG_WriteBits(ms, ac_codes_special[BLOCK_EOB], ac_length_special[BLOCK_EOB]); } // Ueber den Cb-Block gehen mb.chrom[0].a[0] += (mb.chrom[0].a[0] > 0.0) ? 0.5 : -0.5; dc_diff = (int)mb.chrom[0].a[0] - ms->dc_prev[1]; ezMPEG_EncodeDC(ms, dc_diff, CHROMINANCE); ms->dc_prev[1] += dc_diff; run = 0; level = 0; for(k = 1; k < 64; k++) { mb.chrom[0].a[zigzag[k]] += (mb.chrom[0].a[zigzag[k]] > 0.0) ? 0.5 : -0.5; level = (int)mb.chrom[0].a[zigzag[k]]; if(level != 0) { ezMPEG_EncodeAC(ms, run, level); run = 0; } else run++; } ezMPEG_WriteBits(ms, ac_codes_special[BLOCK_EOB], ac_length_special[BLOCK_EOB]); // Ueber den Cr-Block gehen mb.chrom[1].a[0] += (mb.chrom[1].a[0] > 0.0) ? 0.5 : -0.5; dc_diff = (int)mb.chrom[1].a[0] - ms->dc_prev[2]; ezMPEG_EncodeDC(ms, dc_diff, CHROMINANCE); ms->dc_prev[2] += dc_diff; run = 0; level = 0; for(k = 1; k < 64; k++) { mb.chrom[1].a[zigzag[k]] += (mb.chrom[1].a[zigzag[k]] > 0.0) ? 0.5 : -0.5; level = (int)mb.chrom[1].a[zigzag[k]]; if(level != 0) { ezMPEG_EncodeAC(ms, run, level); run = 0; } else run++; } ezMPEG_WriteBits(ms, ac_codes_special[BLOCK_EOB], ac_length_special[BLOCK_EOB]); return; } void ezMPEG_WriteGOPHeader(ezMPEGStream *ms) { ezMPEG_ByteAlign(ms); ezMPEG_WriteBits(ms, 0x1B8, 32); // group_start_code ezMPEG_WriteBits(ms, 0, 1); // time_code ezMPEG_WriteBits(ms, ((ms->picture_count / ms->picture_rate) / 60) / 24, 5); // Stunden ezMPEG_WriteBits(ms, ((ms->picture_count / ms->picture_rate) / 60) % 24, 6); // Minuten ezMPEG_WriteBits(ms, 1, 1); // ezMPEG_WriteBits(ms, (ms->picture_count / ms->picture_rate) % 60, 6); // Sekunden ezMPEG_WriteBits(ms, ms->picture_count % ms->picture_rate, 6); // picture_time_code ezMPEG_WriteBits(ms, 1, 1); // closed_gop (1) ezMPEG_WriteBits(ms, 0, 1); // broken_link (0) if(ms->error_code) ezMPEG_SetError(ms, "ezMPEG_WriteGOPHeader: Couldn't write GOP header"); return; } void ezMPEG_WritePictureHeader(ezMPEGStream *ms) { ezMPEG_ByteAlign(ms); ezMPEG_WriteBits(ms, 0x100, 32); // picture_start_code (0x100) // temporal_reference (0) wird bei jedem Bild in dieser GOP um 1 erhöht // und fängt bei einer neuen GOP wieder bei 0 an ezMPEG_WriteBits(ms, ms->picture_count % ms->gop_size, 10); ezMPEG_WriteBits(ms, 1, 3); // picture_coding_type (1, I-Picture) ezMPEG_WriteBits(ms, 0, 16); // vbv_delay (0, kann irgendwas sein wenn variable Bitrate) ezMPEG_WriteBits(ms, 0, 1); // extra_bit_picture // Ein Slice pro Picture sollte reichen ezMPEG_ByteAlign(ms); ezMPEG_WriteBits(ms, 0x101, 32); // slice_start_code (vertikale Position diese Slices in Macroblockeinheiten) // horizontale Position gegeben durch macroblock_address(_increment) des ersten // Macroblocks in diesem Slice. Jeder Slice ist 16 Pels hoch // Reset der DC-Keoff. für differential-Codierung // dc_lum_prev = 128, dc_cb_prev = 128, dc_cr_prev = 128 // slice_vertical_position = macroblock_row + 1; // quantize_scale, in jedem Macroblockheader muss macroblock_type=intra_q (01), oder intra_d (1) sein. // Wenn intra_q => macroblock_quant wird == 1 sein ezMPEG_WriteBits(ms, (int)ms->q_scale, 5); ezMPEG_WriteBits(ms, 0, 1); // extra_bit_slice ms->dc_prev[0] = 128; ms->dc_prev[1] = 128; ms->dc_prev[2] = 128; if(ms->error_code) ezMPEG_SetError(ms, "ezMPEG_WritePictureHeader: Couldn't write picture header"); return; } Macroblock ezMPEG_GetMacroblock(ezMPEGStream *ms, unsigned char *picture, int number) { int i, j, k, l, m; int mb_r[64], mb_g[64], mb_b[64]; int offset; Macroblock mb; i = number / ms->hsize; j = number % ms->hsize; offset = 3 * ms->hsize * 16; // 1. Block m = 0; for(k = i * 16; k < i * 16 + 8; k++) { for(l = j * 16 * 3; l < j * 16 * 3 + 24; l += 3) { mb.lum[0].a[m] = 0.299 * (float)picture[k * offset + l] + 0.587 * (float)picture[k * offset + l + 1] + 0.114 * (float)picture[k * offset + l + 2]; mb_r[m] = picture[k * offset + l]; mb_g[m] = picture[k * offset + l + 1]; mb_b[m] = picture[k * offset + l + 2]; m++; } } // 2. Block m = 0; for(k = i * 16; k < i * 16 + 8; k++) { for(l = j * 16 * 3 + 24; l < j * 16 * 3 + 48; l += 3) { mb.lum[1].a[m] = 0.299 * (float)picture[k * offset + l] + 0.587 * (float)picture[k * offset + l + 1] + 0.114 * (float)picture[k * offset + l + 2]; mb_r[m] += picture[k * offset + l]; mb_g[m] += picture[k * offset + l + 1]; mb_b[m] += picture[k * offset + l + 2]; m++; } } // 3. Block m = 0; for(k = i * 16 + 8; k < (i + 1) * 16; k++) { for(l = j * 16 * 3; l < j * 16 * 3 + 24; l += 3) { mb.lum[2].a[m] = 0.299 * (float)picture[k * offset + l] + 0.587 * (float)picture[k * offset + l + 1] + 0.114 * (float)picture[k * offset + l + 2]; mb_r[m] += picture[k * offset + l]; mb_g[m] += picture[k * offset + l + 1]; mb_b[m] += picture[k * offset + l + 2]; m++; } } // 4. Block m = 0; for(k = i * 16 + 8; k < (i + 1) * 16; k++) { for(l = j * 16 * 3 + 24; l < j * 16 * 3 + 48; l += 3) { mb.lum[3].a[m] = 0.299 * (float)picture[k * offset + l] + 0.587 * (float)picture[k * offset + l + 1] + 0.114 * (float)picture[k * offset + l + 2]; mb_r[m] += picture[k * offset + l]; mb_g[m] += picture[k * offset + l + 1]; mb_b[m] += picture[k * offset + l + 2]; m++; } } for(m = 0; m < 64; m++) { mb.chrom[0].a[m] = -0.1687 * (float)mb_r[m] * 0.25 - 0.3313 * (float)mb_g[m] * 0.25 + 0.5 * (float)mb_b[m] * 0.25 + 128.0; mb.chrom[1].a[m] = 0.5 * (float)mb_r[m] * 0.25 - 0.4187 * (float)mb_g[m] * 0.25 - 0.0813 * (float)mb_b[m] * 0.25 + 128.0; } return mb; } Macroblock ezMPEG_QuantizeMacroblock(ezMPEGStream *ms, Macroblock mb) { int i, j, l, p; float w[8]; Macroblock tempmb; // Ueber alle Luminanceblocks gehen for(l = 0; l < 4; l++) { // Ueber alle Einträge im Block gehen for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { for(p = 0; p < 8; p++) { // Koeffizienten mit FDCT berechnen w[p] = ezMPEG_1DFDCT(&mb.lum[l].a[p * 8], j); } tempmb.lum[l].a[i * 8 + j] = ezMPEG_1DFDCT(w, i) * c(i) * c(j); // Quantifizierung if(i == 0 && j == 0) tempmb.lum[l].a[i * 8 + j] /= 8.0; else // mit quantizer_scale (slice_header und macroblock_header beachten) tempmb.lum[l].a[i * 8 + j] *= 8.0 / (ms->q_scale * intraquant[i * 8 + j]); } } } // Ueber alle Chrominanceblocks gehen for(l = 0; l < 2; l++) { // Ueber alle Einträge im Block gehen for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { for(p = 0; p < 8; p++) { // Koeffizienten mit FDCT berechnen w[p] = ezMPEG_1DFDCT(&mb.chrom[l].a[p * 8], j); } tempmb.chrom[l].a[i * 8 + j] = ezMPEG_1DFDCT(w, i) * c(i) * c(j); // Quantifizierung if(i == 0 && j == 0) tempmb.chrom[l].a[i * 8 + j] /= 8.0; else // mit quantizer_scale tempmb.chrom[l].a[i * 8 + j] *= 8.0 / (ms->q_scale * intraquant[i * 8 + j]); } } } return tempmb; } float ezMPEG_1DFDCT(float *v, int i) { int n; float temp; temp = 0.0; if((i % 2)) { // i ungerade for(n = 0; n < 4; n++) temp += (v[n] - v[7 - n]) * fcostable[i * 4 + n]; } else { // i gerade for(n = 0; n < 4; n++) temp += (v[n] + v[7 - n]) * fcostable[i * 4 + n]; } return temp; } void ezMPEG_EncodeAC(ezMPEGStream *ms, int runlength, int level) { int level_abs; level_abs = level < 0 ? -level : level; // ac_codes_intra[runlength][0]: Dieser Wert dort gibt an, ob der entsprechende Level // direkt codiert werden kann: if((level_abs > ac_codes_intra[runlength][0]) || runlength > 31) { // Benutze ac_codes_special[BLOCK_ESCAPE] ezMPEG_WriteBits(ms, ac_codes_special[BLOCK_ESCAPE], ac_length_special[BLOCK_ESCAPE]); // Table D.16, Codierung der Runlenght, wenn runlength/level-Kombination in Tabel D.15 nicht vorkommt: ezMPEG_WriteBits(ms, runlength, 6); // Der Escape-Code wurde oben schon ausgegeben und es ist kein Array nötig, da die runlength direkt codiert wird // Hier kommet noch Tabelle D.17 zur Anwendung // Hier muss noch der Level codiert werden: if(level > 0) { if(level >= 1 && level < 128) ezMPEG_WriteBits(ms, level, 8); else ezMPEG_WriteBits(ms, level, 16); } else { if(level <= -1 && level > -128) { ezMPEG_WriteBits(ms, 256 + level, 8); } else { ezMPEG_WriteBits(ms, 32896 + (level + 128), 16); } } } else { // Table D.15 // code = ac_codes_intra[runlength][abs(level)]; // length = ac_length_intra[runlength][abs(level)]; ezMPEG_WriteBits(ms, ac_codes_intra[runlength][level_abs], ac_length_intra[runlength][level_abs]); // Und noch das Vorzeichen if(level < 0.0) { ezMPEG_WriteBits(ms, 1, 1); } else { ezMPEG_WriteBits(ms, 0, 1); } } if(ms->error_code) ezMPEG_SetError(ms, "ezMPEG_EncodeAC: Couldn't write ac codes"); return; } void ezMPEG_EncodeDC(ezMPEGStream *ms, int dc_diff, int type) { int dc_diff_abs; int code = 0, length = 0; dc_diff_abs = dc_diff < 0 ? -dc_diff : dc_diff; if(type == LUMINANCE) { if(dc_diff_abs == 0) { code = diff_dc_size_codes_lum[0]; length = diff_dc_size_length_lum[0]; } else if(dc_diff_abs == 1) { code = diff_dc_size_codes_lum[1]; length = diff_dc_size_length_lum[1]; } else if(dc_diff_abs >= 2 && dc_diff_abs <= 3) { code = diff_dc_size_codes_lum[2]; length = diff_dc_size_length_lum[2]; } else if(dc_diff_abs >= 4 && dc_diff_abs <= 7) { code = diff_dc_size_codes_lum[3]; length = diff_dc_size_length_lum[3]; } else if(dc_diff_abs >= 8 && dc_diff_abs <= 15) { code = diff_dc_size_codes_lum[4]; length = diff_dc_size_length_lum[4]; } else if(dc_diff_abs >= 16 && dc_diff_abs <= 31) { code = diff_dc_size_codes_lum[5]; length = diff_dc_size_length_lum[5]; } else if(dc_diff_abs >= 32 && dc_diff_abs <= 63) { code = diff_dc_size_codes_lum[6]; length = diff_dc_size_length_lum[6]; } else if(dc_diff_abs >= 64 && dc_diff_abs <= 127) { code = diff_dc_size_codes_lum[7]; length = diff_dc_size_length_lum[7]; } else if(dc_diff_abs >= 128 && dc_diff_abs <= 255) { code = diff_dc_size_codes_lum[8]; length = diff_dc_size_length_lum[8]; } else { ezMPEG_SetError(ms, "ezMPEG_EncodeDC: FATAL! absolute dc difference > 255 (Luminance)"); } } else if(type == CHROMINANCE) { if(dc_diff_abs == 0) { code = diff_dc_size_codes_chrom[0]; length = diff_dc_size_length_chrom[0]; } else if(dc_diff_abs == 1) { code = diff_dc_size_codes_chrom[1]; length = diff_dc_size_length_chrom[1]; } else if(dc_diff_abs >= 2 && dc_diff_abs <= 3) { code = diff_dc_size_codes_chrom[2]; length = diff_dc_size_length_chrom[2]; } else if(dc_diff_abs >= 4 && dc_diff_abs <= 7) { code = diff_dc_size_codes_chrom[3]; length = diff_dc_size_length_chrom[3]; } else if(dc_diff_abs >= 8 && dc_diff_abs <= 15) { code = diff_dc_size_codes_chrom[4]; length = diff_dc_size_length_chrom[4]; } else if(dc_diff_abs >= 16 && dc_diff_abs <= 31) { code = diff_dc_size_codes_chrom[5]; length = diff_dc_size_length_chrom[5]; } else if(dc_diff_abs >= 32 && dc_diff_abs <= 63) { code = diff_dc_size_codes_chrom[6]; length = diff_dc_size_length_chrom[6]; } else if(dc_diff_abs >= 64 && dc_diff_abs <= 127) { code = diff_dc_size_codes_chrom[7]; length = diff_dc_size_length_chrom[7]; } else if(dc_diff_abs >= 128 && dc_diff_abs <= 255) { code = diff_dc_size_codes_chrom[8]; length = diff_dc_size_length_chrom[8]; } else { ezMPEG_SetError(ms, "ezMPEG_EncodeDC: FATAL! absolute dc difference > 255 (Chrominance)"); } } else { ezMPEG_SetError(ms, "ezMPEG_EncodeDC: FATAL! Unknown coefficient type"); } ezMPEG_WriteBits(ms, code, length); if(dc_diff == 0) { return; } if(dc_diff < 0) { if(dc_diff == -1) { code = diff_dc_add_codes_neg[1]; length = diff_dc_add_length[1]; } else if(dc_diff <= -2 && dc_diff >= -3) { code = diff_dc_add_codes_neg[2] - (-2 - dc_diff); length = diff_dc_add_length[2]; } else if(dc_diff <= -4 && dc_diff >= -7) { code = diff_dc_add_codes_neg[3] - (-4 - dc_diff); length = diff_dc_add_length[3]; } else if(dc_diff <= -8 && dc_diff >= -15) { code = diff_dc_add_codes_neg[4] - (-8 - dc_diff); length = diff_dc_add_length[4]; } else if(dc_diff <= -16 && dc_diff >= -31) { code = diff_dc_add_codes_neg[5] - (-16 - dc_diff); length = diff_dc_add_length[5]; } else if(dc_diff <= -32 && dc_diff >= -63) { code = diff_dc_add_codes_neg[6] - (-32 - dc_diff); length = diff_dc_add_length[6]; } else if(dc_diff <= -64 && dc_diff >= -127) { code = diff_dc_add_codes_neg[7] - (-64 - dc_diff); length = diff_dc_add_length[7]; } else if(dc_diff <= -128 && dc_diff >= -255) { code = diff_dc_add_codes_neg[8] - (-128 - dc_diff); length = diff_dc_add_length[8]; } else { ezMPEG_SetError(ms, "ezMPEG_EncodeDC: FATAL! dc difference < -255"); } } else { if(dc_diff == 1) { code = diff_dc_add_codes_pos[1]; length = diff_dc_add_length[1]; } else if(dc_diff >= 2 && dc_diff <= 3) { code = diff_dc_add_codes_pos[2] + (dc_diff - 2); length = diff_dc_add_length[2]; } else if(dc_diff >= 4 && dc_diff <= 7) { code = diff_dc_add_codes_pos[3] + (dc_diff - 4); length = diff_dc_add_length[3]; } else if(dc_diff >= 8 && dc_diff <= 15) { code = diff_dc_add_codes_pos[4] + (dc_diff - 8); length = diff_dc_add_length[4]; } else if(dc_diff >= 16 && dc_diff <= 31) { code = diff_dc_add_codes_pos[5] + (dc_diff - 16); length = diff_dc_add_length[5]; } else if(dc_diff >= 32 && dc_diff <= 63) { code = diff_dc_add_codes_pos[6] + (dc_diff - 32); length = diff_dc_add_length[6]; } else if(dc_diff >= 64 && dc_diff <= 127) { code = diff_dc_add_codes_pos[7] + (dc_diff - 64); length = diff_dc_add_length[7]; } else if(dc_diff >= 128 && dc_diff <= 255) { code = diff_dc_add_codes_pos[8] + (dc_diff - 128); length = diff_dc_add_length[8]; } else { ezMPEG_SetError(ms, "ezMPEG_EncodeDC: FATAL! dc difference > 255"); } } ezMPEG_WriteBits(ms, code, length); return; } int ezMPEG_Finalize(ezMPEGStream *ms) { // Den Stream mit dem entsprechenden Code beenden // und den Buffer flushen ezMPEG_ByteAlign(ms); ezMPEG_WriteBits(ms, 0x01B7, 32); // sequence_end_code ezMPEG_FlushBuffer(ms); // ms->out schliessen fclose(ms->out); // Speicher freigeben free(ms->outfile); free(ms->buffer); if(ms->error_code) return 0; return 1; } void ezMPEG_FlushBuffer(ezMPEGStream *ms) { if(fwrite(ms->buffer, ms->buffercount, 1, ms->out) < 1) ezMPEG_SetError(ms, "ezMPEG_FlushBuffer: Couldn't write buffer to file"); ms->buffercount = 0; return; } void ezMPEG_SetError(ezMPEGStream *ms, const char *error_msg) { if(ms != NULL && error_msg != NULL) { ms->error_code = 1; strcpy(ms->error_msg, error_msg); } return; } char *ezMPEG_GetLastError(ezMPEGStream *ms) { ms->error_code = 0; return ms->error_msg; } void ezMPEG_Resize(ezMPEGStream *ms, unsigned char *outbild, unsigned char *inbild, int x, int y, int u, int v) { float hor, ver; int a, b, c, d, e, f, g, h; if(outbild == NULL || inbild == NULL) ezMPEG_SetError(ms, "ezMPEG_Resize: Nullpointer"); if(x <= 0 || y <= 0 || u <= 0 || v <= 0) ezMPEG_SetError(ms, "ezMPEG_Resize: Dimensions must be greater than 0"); if(ms->error_code) return; hor = (float)u / (float)x; ver = (float)v / (float)y; c = y; d = x; if(ver > 1.0) { c = v; } if(hor > 1.0) { d = u; } for(a = 0; a < c; a++) { for(b = 0; b < d; b++) { if(ver > 1.0) { e = a * u; g = (int)((float)a / ver) * x; } else { e = (int)((float)a * ver) * u; g = a * x; } if(hor > 1.0) { f = b; h = (int)((float)b / hor); } else { f = (int)((float)b * hor); h = b; } outbild[e * 3 + f * 3] = inbild[g * 3 + h * 3]; outbild[e * 3 + f * 3 + 1] = inbild[g * 3 + h * 3 + 1]; outbild[e * 3 + f * 3 + 2] = inbild[g * 3 + h * 3 + 2]; } } return; } ./saods9/tkmpeg/license.txt0000644000175000017500000003517310036567765014605 0ustar olesolesGNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ./saods9/template/0000755000175000017500000000000012133201304012703 5ustar olesoles./saods9/template/chandra/0000755000175000017500000000000012133201304014303 5ustar olesoles./saods9/template/chandra/hrc/0000755000175000017500000000000012132057676015103 5ustar olesoles./saods9/template/chandra/hrc/hrc-s.tpl0000644000175000017500000000376711446443665016661 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(0.014345364,-0.0013056111) || # point=boxcircle color=blue point(0.016219966,0.0012246581) || # point=boxcircle box(0.016219966,0.0012246581,40",40",0.0074458106) || # color=red line(0.016216487,-0.023775231,0.016222854,0.02622438) || # line=0 0 color=red line(359.99122,0.0012283276,0.041219741,0.0012216413) || # line=0 0 color=red # text(359.38538,0.0030653744) || textangle=359.45857 color=blue text={S1} polygon(359.14343,0.056577828,359.14354,-0.050535114,359.68674,-0.049942976,359.68662,0.057169491) || # color=blue line(359.14351,-0.019991269,359.6867,-0.019398968) || # line=0 0 color=blue polygon(359.08396,0.077760121,359.08412,-0.072286681,359.6868,-0.071629351,359.68663,0.078416884) || # color=blue background # text(359.98814,0.0037220871) || textangle=359.45857 color=blue text={S2} polygon(359.70851,0.057193071,359.70863,-0.049919757,0.27053203,-0.049307389,0.27041232,0.057805635) || # color=blue line(359.7086,-0.019374933,359.92699,-0.019136806) || # line=0 0 color=blue line(359.92699,-0.019136806,359.9269,0.057431375) || # line=0 0 color=blue line(0.10661832,0.057626818,0.1067037,-0.01894101) || # line=0 0 color=blue line(0.1067037,-0.01894101,0.27049777,-0.018762924) || # line=0 0 color=blue polygon(359.68663,0.078416884,359.6868,-0.071629351,0.28965388,-0.070972867,0.28948516,0.079073122) || # color=blue background # text(0.59092858,0.0043780574) || textangle=359.45857 color=blue text={S3} polygon(0.29539512,0.057832417,0.29551495,-0.049280661,0.8367598,-0.048690494,0.83664301,0.058421797) || # color=blue line(0.29548067,-0.018735466,0.83672616,-0.018146798) || # line=0 0 color=blue polygon(0.28948516,0.079073122,0.28965388,-0.070972867,0.89236821,-0.070316746,0.89220504,0.079728383) # color=blue background ./saods9/template/chandra/hrc/hrc-i.tpl0000644000175000017500000000167311446443665016641 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(359.99932,0.0042101979) || # point=boxcircle color=blue point(0.00069740655,0.0082266505) || # point=boxcircle box(0.00069740655,0.0082266505,40",40",0.0074458119) || # color=red line(0.00069392696,-0.01677324,0.00070029419,0.033226372) || # line=0 0 color=red line(359.9757,0.0082303192,0.025697186,0.0082236331) || # line=0 0 color=red # text(0.0060229964,-0.071730321) || textangle=359.45857 color=blue text={I0} polygon(359.99635,-0.35905082,359.63404,0.0033523352,359.99665,0.36586903,0.35895968,0.0034650549) || # color=blue polygon(359.99531,-0.3931907,359.57097,0.031258645,359.99542,0.45559694,0.4197573,0.031147222) # color=blue dashlist=12 4 background ./saods9/template/chandra/acis/0000755000175000017500000000000012133201304015222 5ustar olesoles./saods9/template/chandra/acis/acis-i.tpl0000644000175000017500000000257111446443664017144 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(359.99565,0.0059387181) || # point=boxcircle color=blue point(359.99369,0.0057314379) || # point=boxcircle box(359.99369,0.0057314379,16",16",0.0074458093) || # color=red line(359.99369,-0.019268453,359.9937,0.03073116) || # line=0 0 color=red line(359.96869,0.0057351065,0.018691898,0.0057284211) || # line=0 0 color=red # text(0.074983471,-0.07503056) || textangle=359.45857 color=blue text={I0} polygon(0.14468917,-0.14493171,0.14506091,-0.0051482778,0.0052770566,-0.0051292868,0.0049055019,-0.14491342) || # color=blue # text(359.93236,-0.075069338) || textangle=359.45857 color=blue text={I1} polygon(359.86231,-0.0051675813,359.86264,-0.14495208,0.0024209693,-0.14496979,0.0020857765,-0.0051863415) || # color=blue # text(0.075029991,0.0678101) || textangle=359.45857 color=blue text={I2} polygon(0.14508996,-0.0020934155,0.14475484,0.13769617,0.0049709953,0.13771371,0.0053064433,-0.0020753216) || # color=blue # text(359.93241,0.067857426) || textangle=359.45857 color=blue text={I3} polygon(359.86271,0.13776073,359.86234,-0.0020285164,0.0021152286,-0.0020463747,0.0024869566,0.13774255) # color=blue ./saods9/template/chandra/acis/acis-si.tpl0000644000175000017500000000503511446443664017325 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(359.98115,0.082070413) || # point=boxcircle color=blue point(359.98265,0.082004845) || # point=boxcircle box(359.98265,0.082004845,16",16",0.0074458153) || # color=red line(359.98265,0.057004991,359.98265,0.1070045) || # line=0 0 color=red line(359.95765,0.082008495,0.0076502475,0.082001831) || # line=0 0 color=red # text(0.060103564,-0.24632926) || textangle=359.45857 color=blue text={I0} polygon(0.12980967,-0.3162311,0.13018093,-0.17644548,359.9904,-0.17642695,359.99003,-0.31621219) || # color=blue # text(359.91749,-0.24636747) || textangle=359.45857 color=blue text={I1} polygon(359.84743,-0.17646563,359.84776,-0.31625111,359.98754,-0.31626967,359.98721,-0.17648316) || # color=blue # text(0.060150801,-0.1034866) || textangle=359.45857 color=blue text={I2} polygon(0.13021067,-0.17339142,0.12987474,-0.033600335,359.99009,-0.033582341,359.99043,-0.17337279) || # color=blue # text(359.91753,-0.10343879) || textangle=359.45857 color=blue text={I3} polygon(359.84783,-0.033535754,359.84746,-0.17332537,359.98724,-0.17334399,359.98761,-0.033553613) || # color=blue # text(0.37121376,0.08257996) || textangle=359.45857 color=blue text={S0} polygon(0.44115766,0.15258465,0.30121961,0.1525348,0.30127095,0.012574598,0.44120866,0.012624389) || # color=blue dashlist=12 4 background # text(0.22864787,0.082511499) || textangle=359.45857 color=blue text={S1} polygon(0.29856987,0.15253562,0.15862653,0.15244371,0.15872558,0.012483867,0.29866856,0.012581379) || # color=blue dashlist=12 4 background # text(0.086114019,0.082457918) || textangle=359.45857 color=blue text={S2} polygon(0.15604234,0.15248238,0.016087265,0.15239031,0.016185851,0.012430134,0.15614059,0.01252742) || # color=blue # text(359.94336,0.082398238) || textangle=359.45857 color=blue text={S3} polygon(0.013306535,0.15240374,359.87336,0.15234768,359.87341,0.01239362,0.013362384,0.012449456) || # color=blue # text(359.80097,0.082345111) || textangle=359.45857 color=blue text={S4} polygon(359.87092,0.15234664,359.73097,0.15229619,359.73102,0.012342662,359.87097,0.012392486) || # color=blue dashlist=12 4 background # text(359.65854,0.082284459) || textangle=359.45857 color=blue text={S5} polygon(359.7285,0.15228281,359.58855,0.15224296,359.58859,0.012288386,359.72853,0.012323208) # color=blue dashlist=12 4 background ./saods9/template/chandra/acis/acis-is.tpl0000644000175000017500000000502511446443664017324 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(359.9814,-0.1158516) || # point=boxcircle color=blue point(359.97944,-0.11605888) || # point=boxcircle box(359.97944,-0.11605888,16",16",0.0074458169) || # color=red line(359.97944,-0.14105864,359.97944,-0.091059238) || # line=0 0 color=red line(359.95444,-0.11605518,0.0044416507,-0.1160619) || # line=0 0 color=red # text(0.060733243,-0.19682027) || textangle=359.45857 color=blue text={I0} polygon(0.13043901,-0.26672034,0.13081075,-0.12693824,359.99103,-0.12691956,359.99066,-0.26670229) || # color=blue # text(359.91811,-0.19685894) || textangle=359.45857 color=blue text={I1} polygon(359.84806,-0.12695743,359.84839,-0.26674043,359.98817,-0.26675865,359.98784,-0.12697661) || # color=blue # text(0.060779763,-0.053980247) || textangle=359.45857 color=blue text={I2} polygon(0.13083979,-0.12388339,0.13050467,0.015906345,359.99072,0.015923489,359.99106,-0.12386561) || # color=blue # text(359.91816,-0.053932908) || textangle=359.45857 color=blue text={I3} polygon(359.84846,0.015970851,359.84809,-0.12381838,359.98786,-0.12383666,359.98824,0.015952329) || # color=blue # text(0.37184311,0.1320915) || textangle=359.45857 color=blue text={S0} polygon(0.44178599,0.20209913,0.30184873,0.20204633,0.30189968,0.062083348,0.4418371,0.062137092) || # color=blue dashlist=12 4 background # text(0.22927653,0.13201944) || textangle=359.45857 color=blue text={S1} polygon(0.2991992,0.20204725,0.15925574,0.2019529,0.15935471,0.061990276,0.29929739,0.062090227) || # color=blue dashlist=12 4 background # text(0.086742871,0.13196478) || textangle=359.45857 color=blue text={S2} polygon(0.15667073,0.20199168,0.016716491,0.20189768,0.016814458,0.061935721,0.15676886,0.062034932) || # color=blue # text(359.94399,0.13190556) || textangle=359.45857 color=blue text={S3} polygon(0.013935284,0.20191224,359.87399,0.20185577,359.87404,0.061899917,0.013991488,0.061955169) || # color=blue # text(359.8016,0.13185239) || textangle=359.45857 color=blue text={S4} polygon(359.87155,0.20185484,359.7316,0.2018065,359.73165,0.061850174,359.8716,0.061898904) || # color=blue dashlist=12 4 background # text(359.65917,0.13179423) || textangle=359.45857 color=blue text={S5} polygon(359.72912,0.20179225,359.58918,0.20175502,359.58922,0.061799638,359.72916,0.061830852) # color=blue dashlist=12 4 background ./saods9/template/chandra/acis/acis-s.tpl0000644000175000017500000000337311446443664017157 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: /tmp/ds9sao26241407288736.fits.gz global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,359.45114) || composite=0 point(359.97589,-0.00023858801) || # point=boxcircle color=blue point(359.97739,-0.00030415722) || # point=boxcircle box(359.97739,-0.00030415722,16",16",0.0074458058) || # color=red line(359.97738,-0.025304045,359.97739,0.024695564) || # line=0 0 color=red line(359.95239,-0.00030048775,0.0023881862,-0.00030717384) || # line=0 0 color=red # text(0.36595192,0.00027268306) || textangle=359.45857 color=blue text={S0} polygon(0.4358959,0.070278402,0.29595769,0.070227238,0.29600903,-0.069733324,0.4359469,-0.069682246) || # color=blue # text(0.22338589,0.00020314963) || textangle=359.45857 color=blue text={S1} polygon(0.29330794,0.070228032,0.1533645,0.070135307,0.15346356,-0.069824861,0.29340664,-0.069726563) || # color=blue # text(0.080851968,0.00014900597) || textangle=359.45857 color=blue text={S2} polygon(0.15078032,0.070173966,0.010825204,0.070081577,0.01092379,-0.06987889,0.15087857,-0.069781319) || # color=blue # text(359.9381,8.9273906e-05) || textangle=359.45857 color=blue text={S3} polygon(0.0080444743,0.070095011,359.8681,0.070039132,359.86815,-0.069915191,0.0081003229,-0.069859569) || # color=blue # text(359.79571,3.6603168e-05) || textangle=359.45857 color=blue text={S4} polygon(359.86566,0.070038097,359.72571,0.069988331,359.72576,-0.069965427,359.86571,-0.069916317) || # color=blue # text(359.65328,-2.3084464e-05) || textangle=359.45857 color=blue text={S5} polygon(359.72323,0.069974963,359.58329,0.069936296,359.58333,-0.070018472,359.72327,-0.069984864) # color=blue ./saods9/template/heasarc/0000755000175000017500000000000012133201304014311 5ustar olesoles./saods9/template/heasarc/suzaku/0000755000175000017500000000000012132057676015657 5ustar olesoles./saods9/template/heasarc/suzaku/xis.tpl0000644000175000017500000000055311476230566017207 0ustar olesoles# Created with aemkreg version 6.1 with Euler angles (0, 90, 0) global color=blue dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,0) || composite=1 polygon( 0.150000, -0.150000,359.850000, -0.150000,359.850000, 0.150000, 0.150000, 0.150000) #text=XIS ./saods9/template/heasarc/suzaku/xrs.tpl0000644000175000017500000000674211476230566017226 0ustar olesoles# Created with aemkreg version 6.1 with Euler angles (0, 90, 0) global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,0) || composite=1 polygon( 0.008047, 0.016399, 0.008047, 0.024344, 0.000102, 0.024344, 0.000102, 0.016399) || #text=XRS polygon( 0.008047, 0.008251, 0.008047, 0.016196, 0.000102, 0.016196, 0.000102, 0.008251) || #text=XRS polygon( 0.024344, 0.008251, 0.024344, 0.016196, 0.016399, 0.016196, 0.016399, 0.008251) || #text=XRS polygon( 0.016196, 0.000102, 0.016196, 0.008047, 0.008251, 0.008047, 0.008251, 0.000102) || #text=XRS polygon( 0.024344, 0.000102, 0.024344, 0.008047, 0.016399, 0.008047, 0.016399, 0.000102) || #text=XRS polygon( 0.008047, 0.000102, 0.008047, 0.008047, 0.000102, 0.008047, 0.000102, 0.000102) || #text=XRS polygon( 0.008047, -0.008047, 0.008047, -0.000102, 0.000102, -0.000102, 0.000102, -0.008047) || #text=XRS polygon( 0.008047, -0.024344, 0.008047, -0.016399, 0.000102, -0.016399, 0.000102, -0.024344) || #text=XRS polygon( 0.008047, -0.016196, 0.008047, -0.008251, 0.000102, -0.008251, 0.000102, -0.016196) || #text=XRS polygon( 0.016196, -0.024344, 0.016196, -0.016399, 0.008251, -0.016399, 0.008251, -0.024344) || #text=XRS polygon( 0.016196, -0.016196, 0.016196, -0.008251, 0.008251, -0.008251, 0.008251, -0.016196) || #text=XRS polygon( 0.024344, -0.016196, 0.024344, -0.008251, 0.016399, -0.008251, 0.016399, -0.016196) || #text=XRS polygon( 0.016196, -0.008047, 0.016196, -0.000102, 0.008251, -0.000102, 0.008251, -0.008047) || #text=XRS polygon( 0.024344, -0.008047, 0.024344, -0.000102, 0.016399, -0.000102, 0.016399, -0.008047) || #text=XRS polygon(359.999898, -0.024344,359.999898, -0.016399,359.991953, -0.016399,359.991953, -0.024344) || #text=XRS polygon(359.999898, -0.016196,359.999898, -0.008251,359.991953, -0.008251,359.991953, -0.016196) || #text=XRS polygon(359.991749, -0.024344,359.991749, -0.016399,359.983804, -0.016399,359.983804, -0.024344) || #text=XRS polygon(359.991749, -0.016196,359.991749, -0.008251,359.983804, -0.008251,359.983804, -0.016196) || #text=XRS polygon(359.983601, -0.016196,359.983601, -0.008251,359.975656, -0.008251,359.975656, -0.016196) || #text=XRS polygon(359.991749, -0.008047,359.991749, -0.000102,359.983804, -0.000102,359.983804, -0.008047) || #text=XRS polygon(359.983601, -0.008047,359.983601, -0.000102,359.975656, -0.000102,359.975656, -0.008047) || #text=XRS polygon(359.999898, -0.008047,359.999898, -0.000102,359.991953, -0.000102,359.991953, -0.008047) || #text=XRS polygon(359.999898, 0.000102,359.999898, 0.008047,359.991953, 0.008047,359.991953, 0.000102) || #text=XRS polygon(359.999898, 0.016399,359.999898, 0.024344,359.991953, 0.024344,359.991953, 0.016399) || #text=XRS polygon(359.999898, 0.008251,359.999898, 0.016196,359.991953, 0.016196,359.991953, 0.008251) || #text=XRS polygon(359.991749, 0.016399,359.991749, 0.024344,359.983804, 0.024344,359.983804, 0.016399) || #text=XRS polygon(359.991749, 0.008251,359.991749, 0.016196,359.983804, 0.016196,359.983804, 0.008251) || #text=XRS polygon(359.983601, 0.008251,359.983601, 0.016196,359.975656, 0.016196,359.975656, 0.008251) || #text=XRS polygon(359.991749, 0.000102,359.991749, 0.008047,359.983804, 0.008047,359.983804, 0.000102) || #text=XRS polygon(359.983601, 0.000102,359.983601, 0.008047,359.975656, 0.008047,359.975656, 0.000102) #text=XRS ./saods9/template/heasarc/suzaku/hxd.tpl0000644000175000017500000000152211476230566017164 0ustar olesoles# Created with aemkreg version 6.1 with Euler angles (0, 90, 0) global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,0) || composite=1 polygon( 0.563355, -0.621657,359.436645, -0.621657,359.436652, 0.504992, 0.563348, 0.504992) || #text={PIN (FULL)} polygon(360.000000, -0.340000,359.718333, -0.058333, 0.000000, 0.223333, 0.281667, -0.058333) || #text={PIN (FWHM)} polygon( 4.574921, -4.618431,355.425079, -4.618431,355.425574, 4.501888, 4.574426, 4.501888) || #text={GSO (FULL)} polygon(360.000000, -2.340833,357.717499, -0.058318, 0.000000, 2.224167, 2.282501, -0.058318) || #text={GSO (FWHM)} polygon( 0.008333, -0.066667,359.991667, -0.066667,359.991667, -0.050000, 0.008333, -0.050000) #text={HXD-nominal} ./saods9/template/mmt/0000755000175000017500000000000012133201304013500 5ustar olesoles./saods9/template/mmt/binospec.tpl0000644000175000017500000000043311073704415016040 0ustar olesoles# Region file format: DS9 version 4.0 global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || composite=1 box(359.9225,0,480",900",0) || # tag={Bino} box(0.077500142,0,480",900",0) # tag={Bino} ./saods9/template/mmt/megacam/0000755000175000017500000000000012133201304015072 5ustar olesoles./saods9/template/mmt/megacam/megacam-chip.tpl0000644000175000017500000001027010271504030020131 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/sao/megacam.fits[IM1] global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || point(0,0) || # point=boxcircle # text(359.8369,-0.1883876) || textangle=90 text={C1} box(359.83692,-0.18840971,163.33361",367.7002",90) || # text(359.8369,-0.141288) || textangle=90 text={C2} box(359.83692,-0.14131021,163.33361",367.7002",90) || # text(359.83689,-0.094188304) || textangle=90 text={C3} box(359.83692,-0.094210505,163.33361",367.7002",90) || # text(359.83689,-0.047088504) || textangle=90 text={C4} box(359.83691,-0.047110605,163.33361",367.7002",90) || # text(359.8369,1.1396249e-05) || textangle=90 text={C5} box(359.83692,-1.0704976e-05,163.33361",367.7002",90) || # text(359.8369,0.047111296) || textangle=90 text={C6} box(359.83692,0.047089195,163.33361",367.7002",90) || # text(359.83689,0.094211197) || textangle=90 text={C7} box(359.83691,0.094188996,163.33361",367.7002",90) || # text(359.8369,0.1413109) || textangle=90 text={C8} box(359.83692,0.1412887,163.33361",367.7002",90) || # text(359.8369,0.1884104) || textangle=90 text={C9} box(359.83692,0.1883883,163.33361",367.7002",90) || # text(359.94828,-0.1883883) || textangle=90 text={C10} box(359.94831,-0.1884104,163.33361",367.7002",90) || # text(359.94828,-0.1412886) || textangle=90 text={C11} box(359.9483,-0.1413107,163.33361",367.7002",90) || # text(359.94828,-0.0941887) || textangle=90 text={C12} box(359.9483,-0.094210801,163.33361",367.7002",90) || # text(359.94828,-0.047088601) || textangle=90 text={C13} box(359.9483,-0.047110801,163.33361",367.7002",90) || # text(359.94828,1.1399465e-05) || textangle=90 text={C14} box(359.9483,-1.0700924e-05,163.33361",367.7002",90) || # text(359.94828,0.047111499) || textangle=90 text={C15} box(359.9483,0.047089299,163.33361",367.7002",90) || # text(359.94828,0.0942115) || textangle=90 text={C16} box(359.9483,0.094189399,163.33361",367.7002",90) || # text(359.94828,0.1413114) || textangle=90 text={C17} box(359.9483,0.1412893,163.33361",367.7002",90) || # text(359.94829,0.1884111) || textangle=90 text={C18} box(359.94831,0.188389,163.33361",367.7002",90) || # text(0.051681678,-0.1883883) || textangle=90 text={C19} box(0.051711674,-0.1884104,163.33361",367.7002",90) || # text(0.051680764,-0.1412886) || textangle=90 text={C20} box(0.051710759,-0.1413107,163.33361",367.7002",90) || # text(0.051679849,-0.094188702) || textangle=90 text={C21} box(0.051709844,-0.094210801,163.33361",367.7002",90) || # text(0.051688932,-0.047088601) || textangle=90 text={C22} box(0.051708928,-0.047110801,163.33361",367.7002",90) || # text(0.051688017,1.1398494e-05) || textangle=90 text={C23} box(0.051708013,-1.0701118e-05,163.33361",367.7002",90) || # text(0.051687103,0.047111498) || textangle=90 text={C24} box(0.051707098,0.047089299,163.33361",367.7002",90) || # text(0.051686188,0.094211499) || textangle=90 text={C25} box(0.051706183,0.094189399,163.33361",367.7002",90) || # text(0.051685273,0.1413114) || textangle=90 text={C26} box(0.051705268,0.1412893,163.33361",367.7002",90) || # text(0.051684358,0.1884111) || textangle=90 text={C27} box(0.051704353,0.188389,163.33361",367.7002",90) || # text(0.16309374,-0.18838761) || textangle=90 text={C28} box(0.16311374,-0.1884097,163.33361",367.7002",90) || # text(0.16309085,-0.14128801) || textangle=90 text={C29} box(0.16311085,-0.1413102,163.33361",367.7002",90) || # text(0.16308797,-0.094188306) || textangle=90 text={C30} box(0.16311796,-0.094210504,163.33361",367.7002",90) || # text(0.16309508,-0.047088505) || textangle=90 text={C31} box(0.16311508,-0.047110604,163.33361",367.7002",90) || # text(0.16309219,1.1394411e-05) || textangle=90 text={C32} box(0.16311219,-1.0704364e-05,163.33361",367.7002",90) || # text(0.1630893,0.047111394) || textangle=90 text={C33} box(0.1631193,0.047089196,163.33361",367.7002",90) || # text(0.16309642,0.094211195) || textangle=90 text={C34} box(0.16311641,0.094188996,163.33361",367.7002",90) || # text(0.16309353,0.14131089) || textangle=90 text={C35} box(0.16311352,0.1412887,163.33361",367.7002",90) || # text(0.16309064,0.18841039) || textangle=90 text={C36} box(0.16311064,0.1883883,163.33361",367.7002",90) ./saods9/template/mmt/megacam/megacam-amp.tpl0000644000175000017500000002017610271504030017771 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/sao/megacam.fits[IM1] global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || point(0,0) || # point=boxcircle # text(359.83689,-0.19976359) || textangle=90 text={A1} box(359.83692,-0.19974141,81.586975",367.7002",90) || # text(359.83689,-0.17705651) || textangle=90 text={A2} box(359.83692,-0.17703433,81.586975",367.7002",90) || # text(359.83689,-0.15266411) || textangle=90 text={A3} box(359.83691,-0.15264196,81.586975",367.7002",90) || # text(359.83689,-0.12995693) || textangle=90 text={A4} box(359.83691,-0.12993478,81.586975",367.7002",90) || # text(359.8369,-0.10556443) || textangle=90 text={A5} box(359.83692,-0.10554228,81.586975",367.7002",90) || # text(359.83689,-0.082857155) || textangle=90 text={A6} box(359.83691,-0.082835001,81.586975",367.7002",90) || # text(359.8369,-0.058464655) || textangle=90 text={A7} box(359.83692,-0.058442401,81.586975",367.7002",90) || # text(359.8369,-0.035757276) || textangle=90 text={A8} box(359.83692,-0.035735122,81.586975",367.7002",90) || # text(359.83689,-0.011364703) || textangle=90 text={A9} box(359.83692,-0.011342522,81.586975",367.7002",90) || # text(359.83689,0.011342576) || textangle=90 text={A10} box(359.83692,0.011364757,81.586975",367.7002",90) || # text(359.83689,0.035735176) || textangle=90 text={A11} box(359.83691,0.03575733,81.586975",367.7002",90) || # text(359.83689,0.058442456) || textangle=90 text={A12} box(359.83691,0.05846461,81.586975",367.7002",90) || # text(359.8369,0.082835056) || textangle=90 text={A13} box(359.83692,0.08285721,81.586975",367.7002",90) || # text(359.83689,0.10554233) || textangle=90 text={A14} box(359.83691,0.10556449,81.586975",367.7002",90) || # text(359.8369,0.12993483) || textangle=90 text={A15} box(359.83692,0.12995699,81.586975",367.7002",90) || # text(359.8369,0.15264201) || textangle=90 text={A16} box(359.83692,0.15266417,81.586975",367.7002",90) || # text(359.83689,0.17703439) || textangle=90 text={A17} box(359.83691,0.17705654,81.586975",367.7002",90) || # text(359.83689,0.19974147) || textangle=90 text={A18} box(359.83692,0.19976365,81.586975",367.7002",90) || # text(359.94828,-0.19976436) || textangle=90 text={A19} box(359.94832,-0.19974215,81.586975",367.7002",90) || # text(359.94828,-0.17705718) || textangle=90 text={A20} box(359.94832,-0.17703497,81.586975",367.7002",90) || # text(359.94828,-0.15266468) || textangle=90 text={A21} box(359.94832,-0.15264247,81.586975",367.7002",90) || # text(359.94828,-0.1299574) || textangle=90 text={A22} box(359.94832,-0.12993529,81.586975",367.7002",90) || # text(359.94827,-0.10556483) || textangle=90 text={A23} box(359.94832,-0.10554269,81.586975",367.7002",90) || # text(359.94828,-0.082857522) || textangle=90 text={A24} box(359.94832,-0.082835313,81.586975",367.7002",90) || # text(359.94827,-0.05846485) || textangle=90 text={A25} box(359.94832,-0.058442613,81.586975",367.7002",90) || # text(359.94828,-0.035757443) || textangle=90 text={A26} box(359.94832,-0.035735333,81.586975",367.7002",90) || # text(359.94828,-0.01136477) || textangle=90 text={A27} box(359.94833,-0.011342533,81.586975",367.7002",90) || # text(359.94828,0.011342636) || textangle=90 text={A28} box(359.94832,0.011364846,81.586975",367.7002",90) || # text(359.94828,0.035735309) || textangle=90 text={A29} box(359.94833,0.035757546,81.586975",367.7002",90) || # text(359.94828,0.058442715) || textangle=90 text={A30} box(359.94832,0.058464925,81.586975",367.7002",90) || # text(359.94828,0.082835388) || textangle=90 text={A31} box(359.94833,0.082857525,81.586975",367.7002",90) || # text(359.94827,0.10554267) || textangle=90 text={A32} box(359.94832,0.1055649,81.586975",367.7002",90) || # text(359.94828,0.12993527) || textangle=90 text={A33} box(359.94833,0.1299575,81.586975",367.7002",90) || # text(359.94828,0.15264255) || textangle=90 text={A34} box(359.94833,0.15266468,81.586975",367.7002",90) || # text(359.94828,0.17703505) || textangle=90 text={A35} box(359.94833,0.17705728,81.586975",367.7002",90) || # text(359.94828,0.19974223) || textangle=90 text={A36} box(359.94833,0.19976436,81.586975",367.7002",90) || # text(0.051677255,-0.19976435) || textangle=90 text={A37} box(0.051707189,-0.19974217,81.586975",367.7002",90) || # text(0.051684011,-0.17705714) || textangle=90 text={A38} box(0.051703946,-0.17703499,81.586975",367.7002",90) || # text(0.051686072,-0.15266464) || textangle=90 text={A39} box(0.051706007,-0.15264249,81.586975",367.7002",90) || # text(0.051682828,-0.12995746) || textangle=90 text={A40} box(0.051702762,-0.12993531,81.586975",367.7002",90) || # text(0.051684887,-0.10556486) || textangle=90 text={A41} box(0.051704821,-0.10554261,81.586975",367.7002",90) || # text(0.05168164,-0.082857485) || textangle=90 text={A42} box(0.051701574,-0.082835329,81.586975",367.7002",90) || # text(0.051683696,-0.058464784) || textangle=90 text={A43} box(0.05170363,-0.058442629,81.586975",367.7002",90) || # text(0.051680447,-0.035757505) || textangle=90 text={A44} box(0.051700381,-0.03573525,81.586975",367.7002",90) || # text(0.051682501,-0.011364805) || textangle=90 text={A45} box(0.051702435,-0.011342549,81.586975",367.7002",90) || # text(0.05167925,0.011342574) || textangle=90 text={A46} box(0.051699184,0.01136483,81.586975",367.7002",90) || # text(0.051681302,0.035735274) || textangle=90 text={A47} box(0.051701235,0.03575753,81.586975",367.7002",90) || # text(0.051678048,0.058442653) || textangle=90 text={A48} box(0.051707979,0.058464837,81.586975",367.7002",90) || # text(0.051680098,0.082835354) || textangle=90 text={A49} box(0.051700031,0.082857509,81.586975",367.7002",90) || # text(0.051686839,0.10554266) || textangle=90 text={A50} box(0.051706772,0.10556492,81.586975",367.7002",90) || # text(0.051678889,0.12993533) || textangle=90 text={A51} box(0.051708819,0.12995752,81.586975",367.7002",90) || # text(0.051685628,0.15264254) || textangle=90 text={A52} box(0.051705561,0.1526647,81.586975",367.7002",90) || # text(0.051677676,0.17703501) || textangle=90 text={A53} box(0.051707605,0.1770572,81.586975",367.7002",90) || # text(0.051684413,0.19974222) || textangle=90 text={A54} box(0.051704345,0.19976437,81.586975",367.7002",90) || # text(0.16309024,-0.19976357) || textangle=90 text={A55} box(0.16311018,-0.19974141,81.586975",367.7002",90) || # text(0.16308605,-0.17705659) || textangle=90 text={A56} box(0.16311598,-0.17703431,81.586975",367.7002",90) || # text(0.16308709,-0.15266409) || textangle=90 text={A57} box(0.16310702,-0.15264193,81.586975",367.7002",90) || # text(0.16309289,-0.12995698) || textangle=90 text={A58} box(0.16311283,-0.12993483,81.586975",367.7002",90) || # text(0.16309393,-0.10556448) || textangle=90 text={A59} box(0.16311386,-0.10554223,81.586975",367.7002",90) || # text(0.16308973,-0.082857204) || textangle=90 text={A60} box(0.16310967,-0.082835048,81.586975",367.7002",90) || # text(0.16309077,-0.058464604) || textangle=90 text={A61} box(0.1631107,-0.058442447,81.586975",367.7002",90) || # text(0.16308657,-0.035757325) || textangle=90 text={A62} box(0.1631165,-0.03573514,81.586975",367.7002",90) || # text(0.1630876,-0.011364725) || textangle=90 text={A63} box(0.16310754,-0.011342568,81.586975",367.7002",90) || # text(0.1630934,0.011342583) || textangle=90 text={A64} box(0.16311333,0.011364739,81.586975",367.7002",90) || # text(0.16309443,0.035735183) || textangle=90 text={A65} box(0.16311436,0.035757339,81.586975",367.7002",90) || # text(0.16309023,0.058442462) || textangle=90 text={A66} box(0.16311016,0.058464618,81.586975",367.7002",90) || # text(0.16309125,0.082835062) || textangle=90 text={A67} box(0.16311119,0.082857219,81.586975",367.7002",90) || # text(0.16308705,0.10554234) || textangle=90 text={A68} box(0.16310698,0.1055645,81.586975",367.7002",90) || # text(0.16308807,0.12993484) || textangle=90 text={A69} box(0.16310801,0.129957,81.586975",367.7002",90) || # text(0.16309386,0.15264205) || textangle=90 text={A70} box(0.1631138,0.1526642,81.586975",367.7002",90) || # text(0.16308489,0.17703442) || textangle=90 text={A71} box(0.16311482,0.17705661,81.586975",367.7002",90) || # text(0.16309068,0.19974143) || textangle=90 text={A72} box(0.16311061,0.19976368,81.586975",367.7002",90) ./saods9/template/mmt/megacam/megacam-chip-guide.tpl0000644000175000017500000001165511075735605021255 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /tmp/dss1224085352034269.fits.gz global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || composite=1 point(0,0) || # point=boxcircle # text(359.83879,-0.19000008) || textangle=89.429076 text={C1} box(359.83881,-0.19002199,163.33361",367.7002",89.429076) || # text(359.83831,-0.14290288) || textangle=89.429076 text={C2} box(359.83833,-0.14292488,163.33361",367.7002",89.429076) || # text(359.83784,-0.095805501) || textangle=89.429076 text={C3} box(359.83787,-0.095827401,163.33361",367.7002",89.429076) || # text(359.83737,-0.048708098) || textangle=89.429076 text={C4} box(359.83739,-0.048729996,163.33361",367.7002",89.429076) || # text(359.8369,-0.0016104951) || textangle=89.429076 text={C5} box(359.83692,-0.0016323935,163.33361",367.7002",89.429076) || # text(359.83644,0.045487183) || textangle=89.429076 text={C6} box(359.83646,0.045465284,163.33361",367.7002",89.429076) || # text(359.83596,0.092584587) || textangle=89.429076 text={C7} box(359.83598,0.09256259,163.33361",367.7002",89.429076) || # text(359.8355,0.13968217) || textangle=89.429076 text={C8} box(359.83551,0.13966,163.33361",367.7002",89.429076) || # text(359.83503,0.18677928) || textangle=89.429076 text={C9} box(359.83505,0.18675738,163.33361",367.7002",89.429076) || # text(359.95017,-0.1888932) || textangle=89.429076 text={C10} box(359.9502,-0.188915,163.33361",367.7002",89.429076) || # text(359.94969,-0.1417959) || textangle=89.429076 text={C11} box(359.94971,-0.1418178,163.33361",367.7002",89.429076) || # text(359.94922,-0.094698394) || textangle=89.429076 text={C12} box(359.94924,-0.094720293,163.33361",367.7002",89.429076) || # text(359.94875,-0.047600518) || textangle=89.429076 text={C13} box(359.94878,-0.047622515,163.33361",367.7002",89.429076) || # text(359.94828,-0.00050291415) || textangle=89.429076 text={C14} box(359.9483,-0.00052481167,163.33361",367.7002",89.429076) || # text(359.94781,0.046594788) || textangle=89.429076 text={C15} box(359.94783,0.046572792,163.33361",367.7002",89.429076) || # text(359.94734,0.093692567) || textangle=89.429076 text={C16} box(359.94736,0.09367067,163.33361",367.7002",89.429076) || # text(359.94687,0.14079007) || textangle=89.429076 text={C17} box(359.94689,0.14076818,163.33361",367.7002",89.429076) || # text(359.94642,0.18788765) || textangle=89.429076 text={C18} box(359.94644,0.18786575,163.33361",367.7002",89.429076) || # text(0.053560184,-0.18786505) || textangle=89.429076 text={C19} box(0.053590399,-0.18788685,163.33361",367.7002",89.429076) || # text(0.053088973,-0.14076769) || textangle=89.429076 text={C20} box(0.053119188,-0.1407895,163.33361",367.7002",89.429076) || # text(0.052617761,-0.093670143) || textangle=89.429076 text={C21} box(0.052647975,-0.093691943,163.33361",367.7002",89.429076) || # text(0.052156546,-0.046572288) || textangle=89.429076 text={C22} box(0.052176763,-0.046594288,163.33361",367.7002",89.429076) || # text(0.051685335,0.00052536623) || textangle=89.429076 text={C23} box(0.051705551,0.00050346653,163.33361",367.7002",89.429076) || # text(0.051214124,0.047623121) || textangle=89.429076 text={C24} box(0.05123434,0.047601121,163.33361",367.7002",89.429076) || # text(0.050742913,0.094720775) || textangle=89.429076 text={C25} box(0.050763127,0.094698876,163.33361",367.7002",89.429076) || # text(0.0502717,0.14181833) || textangle=89.429076 text={C26} box(0.050291915,0.14179643,163.33361",367.7002",89.429076) || # text(0.049800489,0.18891568) || textangle=89.429076 text={C27} box(0.049820703,0.18889379,163.33361",367.7002",89.429076) || # text(0.1649667,-0.18675652) || textangle=89.429076 text={C28} box(0.16498692,-0.18677841,163.33361",367.7002",89.429076) || # text(0.16449352,-0.13965928) || textangle=89.429076 text={C29} box(0.16451373,-0.13968127,163.33361",367.7002",89.429076) || # text(0.16402034,-0.092561943) || textangle=89.429076 text={C30} box(0.16405055,-0.092583842,163.33361",367.7002",89.429076) || # text(0.16355716,-0.045464409) || textangle=89.429076 text={C31} box(0.16357738,-0.045486307,163.33361",367.7002",89.429076) || # text(0.16308398,0.001633126) || textangle=89.429076 text={C32} box(0.16310419,0.0016112271,163.33361",367.7002",89.429076) || # text(0.16261079,0.04873076) || textangle=89.429076 text={C33} box(0.16264101,0.048708862,163.33361",367.7002",89.429076) || # text(0.16214762,0.095828296) || textangle=89.429076 text={C34} box(0.16216783,0.095806296,163.33361",367.7002",89.429076) || # text(0.16167444,0.14292563) || textangle=89.429076 text={C35} box(0.16169464,0.14290364,163.33361",367.7002",89.429076) || # text(0.16120125,0.19002276) || textangle=89.429076 text={C36} box(0.16122147,0.19000087,163.33361",367.7002",89.429076) || # text(359.9993,0.32469933) || textangle=89.429076 text={G1} box(359.9993,0.32469933,163.33361",364",89.429076) || # text(0.0007,-0.32469933) || textangle=89.429076 text={G2} box(0.0007,-0.32469933,163.33361",364",89.429076) ./saods9/template/mmt/megacam/megacam-amp-guide.tpl0000644000175000017500000002116411075735605021103 0ustar olesoles# Region file format: DS9 version 4.0 global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0|| composite=1 point(0,0) || # point=boxcircle # text(359.83864,-0.20117642) || textangle=89.5 text={A1} box(359.83867,-0.20115398,81.586975",367.7002",89.5) || # text(359.83844,-0.1784702) || textangle=89.5 text={A2} box(359.83847,-0.17844776,81.586975",367.7002",89.5) || # text(359.83823,-0.15407873) || textangle=89.5 text={A3} box(359.83825,-0.15405641,81.586975",367.7002",89.5) || # text(359.83803,-0.13137242) || textangle=89.5 text={A4} box(359.83805,-0.13135009,81.586975",367.7002",89.5) || # text(359.83783,-0.10698076) || textangle=89.5 text={A5} box(359.83785,-0.10695843,81.586975",367.7002",89.5) || # text(359.83762,-0.084274433) || textangle=89.5 text={A6} box(359.83764,-0.084252106,81.586975",367.7002",89.5) || # text(359.83742,-0.059882774) || textangle=89.5 text={A7} box(359.83744,-0.059860347,81.586975",367.7002",89.5) || # text(359.83722,-0.037176259) || textangle=89.5 text={A8} box(359.83724,-0.037153931,81.586975",367.7002",89.5) || # text(359.837,-0.012784701) || textangle=89.5 text={A9} box(359.83703,-0.012762259,81.586975",367.7002",89.5) || # text(359.8368,0.0099217144) || textangle=89.5 text={A10} box(359.83683,0.0099441558,81.586975",367.7002",89.5) || # text(359.83658,0.034313386) || textangle=89.5 text={A11} box(359.8366,0.034335714,81.586975",367.7002",89.5) || # text(359.83639,0.057019803) || textangle=89.5 text={A12} box(359.8364,0.05704213,81.586975",367.7002",89.5) || # text(359.83618,0.081411562) || textangle=89.5 text={A13} box(359.8362,0.081433889,81.586975",367.7002",89.5) || # text(359.83597,0.10411788) || textangle=89.5 text={A14} box(359.83599,0.10414022,81.586975",367.7002",89.5) || # text(359.83577,0.12850954) || textangle=89.5 text={A15} box(359.83579,0.12853188,81.586975",367.7002",89.5) || # text(359.83557,0.15121586) || textangle=89.5 text={A16} box(359.83559,0.15123819,81.586975",367.7002",89.5) || # text(359.83535,0.17560722) || textangle=89.5 text={A17} box(359.83537,0.17562955,81.586975",367.7002",89.5) || # text(359.83515,0.19831344) || textangle=89.5 text={A18} box(359.83518,0.19833588,81.586975",367.7002",89.5) || # text(359.95003,-0.20020716) || textangle=89.5 text={A19} box(359.95007,-0.2001846,81.586975",367.7002",89.5) || # text(359.94983,-0.17750084) || textangle=89.5 text={A20} box(359.94987,-0.17747829,81.586975",367.7002",89.5) || # text(359.94962,-0.15310927) || textangle=89.5 text={A21} box(359.94966,-0.15308671,81.586975",367.7002",89.5) || # text(359.94942,-0.13040286) || textangle=89.5 text={A22} box(359.94946,-0.1303804,81.586975",367.7002",89.5) || # text(359.9492,-0.1060113) || textangle=89.5 text={A23} box(359.94924,-0.10598873,81.586975",367.7002",89.5) || # text(359.94901,-0.08330477) || textangle=89.5 text={A24} box(359.94905,-0.083282213,81.586975",367.7002",89.5) || # text(359.94878,-0.058913113) || textangle=89.5 text={A25} box(359.94883,-0.058890441,81.586975",367.7002",89.5) || # text(359.94859,-0.036206483) || textangle=89.5 text={A26} box(359.94863,-0.036184025,81.586975",367.7002",89.5) || # text(359.94838,-0.011814738) || textangle=89.5 text={A27} box(359.94843,-0.011792066,81.586975",367.7002",89.5) || # text(359.94818,0.010891805) || textangle=89.5 text={A28} box(359.94822,0.010914362,81.586975",367.7002",89.5) || # text(359.94797,0.03528355) || textangle=89.5 text={A29} box(359.94802,0.035306221,81.586975",367.7002",89.5) || # text(359.94777,0.057990092) || textangle=89.5 text={A30} box(359.94781,0.058012649,81.586975",367.7002",89.5) || # text(359.94756,0.082381837) || textangle=89.5 text={A31} box(359.94761,0.082404408,81.586975",367.7002",89.5) || # text(359.94735,0.10508817) || textangle=89.5 text={A32} box(359.9474,0.10511083,81.586975",367.7002",89.5) || # text(359.94715,0.12947993) || textangle=89.5 text={A33} box(359.9472,0.12950259,81.586975",367.7002",89.5) || # text(359.94695,0.15218634) || textangle=89.5 text={A34} box(359.947,0.15220891,81.586975",367.7002",89.5) || # text(359.94673,0.17657792) || textangle=89.5 text={A35} box(359.94678,0.17660058,81.586975",367.7002",89.5) || # text(359.94654,0.19928423) || textangle=89.5 text={A36} box(359.94659,0.1993068,81.586975",367.7002",89.5) || # text(0.053422167,-0.19930672) || textangle=89.5 text={A37} box(0.053451906,-0.19928428,81.586975",367.7002",89.5) || # text(0.053230353,-0.17660032) || textangle=89.5 text={A38} box(0.053250094,-0.17657799,81.586975",367.7002",89.5) || # text(0.053019108,-0.15220873) || textangle=89.5 text={A39} box(0.053038849,-0.1521864,81.586975",367.7002",89.5) || # text(0.052817296,-0.12950244) || textangle=89.5 text={A40} box(0.052837036,-0.12948012,81.586975",367.7002",89.5) || # text(0.052606049,-0.10511075) || textangle=89.5 text={A41} box(0.052625787,-0.10508833,81.586975",367.7002",89.5) || # text(0.052404233,-0.082404267) || textangle=89.5 text={A42} box(0.052423972,-0.082381938,81.586975",367.7002",89.5) || # text(0.052192982,-0.058012476) || textangle=89.5 text={A43} box(0.052212722,-0.057990148,81.586975",367.7002",89.5) || # text(0.051991165,-0.035306089) || textangle=89.5 text={A44} box(0.052010904,-0.035283661,81.586975",367.7002",89.5) || # text(0.051779913,-0.010914299) || textangle=89.5 text={A45} box(0.051799651,-0.010891871,81.586975",367.7002",89.5) || # text(0.051578093,0.011792188) || textangle=89.5 text={A46} box(0.051597832,0.011814616,81.586975",367.7002",89.5) || # text(0.051366839,0.036183977) || textangle=89.5 text={A47} box(0.051386577,0.036206406,81.586975",367.7002",89.5) || # text(0.051165016,0.058890464) || textangle=89.5 text={A48} box(0.051194752,0.058912908,81.586975",367.7002",89.5) || # text(0.05095376,0.083282255) || textangle=89.5 text={A49} box(0.050973498,0.083304583,81.586975",367.7002",89.5) || # text(0.050761932,0.10598876) || textangle=89.5 text={A50} box(0.050781669,0.10601119,81.586975",367.7002",89.5) || # text(0.050540675,0.13038043) || textangle=89.5 text={A51} box(0.05057041,0.13040288,81.586975",367.7002",89.5) || # text(0.050348846,0.15308683) || textangle=89.5 text={A52} box(0.050368584,0.15310917,81.586975",367.7002",89.5) || # text(0.050127588,0.17747831) || textangle=89.5 text={A53} box(0.050157322,0.17750076,81.586975",367.7002",89.5) || # text(0.049935755,0.20018471) || textangle=89.5 text={A54} box(0.049955493,0.20020703,81.586975",367.7002",89.5) || # text(0.16483089,-0.19833571) || textangle=89.5 text={A55} box(0.16485064,-0.19831338,81.586975",367.7002",89.5) || # text(0.16462814,-0.17562963) || textangle=89.5 text={A56} box(0.16465787,-0.17560709,81.586975",367.7002",89.5) || # text(0.16441587,-0.15123805) || textangle=89.5 text={A57} box(0.16443561,-0.15121572,81.586975",367.7002",89.5) || # text(0.1642231,-0.12853175) || textangle=89.5 text={A58} box(0.16424285,-0.12850943,81.586975",367.7002",89.5) || # text(0.16401084,-0.10414017) || textangle=89.5 text={A59} box(0.16403057,-0.10411775,81.586975",367.7002",89.5) || # text(0.16380807,-0.081433798) || textangle=89.5 text={A60} box(0.16382782,-0.081411469,81.586975",367.7002",89.5) || # text(0.16359581,-0.057042117) || textangle=89.5 text={A61} box(0.16361554,-0.057019787,81.586975",367.7002",89.5) || # text(0.16339304,-0.034335739) || textangle=89.5 text={A62} box(0.16342277,-0.034313294,81.586975",367.7002",89.5) || # text(0.16318077,-0.0099440576) || textangle=89.5 text={A63} box(0.16320051,-0.0099217278,81.586975",367.7002",89.5) || # text(0.162988,0.012762437) || textangle=89.5 text={A64} box(0.16300773,0.012784766,81.586975",367.7002",89.5) || # text(0.16277572,0.037154118) || textangle=89.5 text={A65} box(0.16279546,0.037176447,81.586975",367.7002",89.5) || # text(0.16257296,0.059860497) || textangle=89.5 text={A66} box(0.16259269,0.059882825,81.586975",367.7002",89.5) || # text(0.16236067,0.084252178) || textangle=89.5 text={A67} box(0.16238042,0.084274507,81.586975",367.7002",89.5) || # text(0.1621579,0.10695856) || textangle=89.5 text={A68} box(0.16217764,0.10698089,81.586975",367.7002",89.5) || # text(0.16194562,0.13135014) || textangle=89.5 text={A69} box(0.16196536,0.13137247,81.586975",367.7002",89.5) || # text(0.16175284,0.15405653) || textangle=89.5 text={A70} box(0.16177259,0.15407886,81.586975",367.7002",89.5) || # text(0.16153057,0.1784479) || textangle=89.5 text={A71} box(0.1615603,0.17847035,81.586975",367.7002",89.5) || # text(0.16133779,0.20115409) || textangle=89.5 text={A72} box(0.16135752,0.20117652,81.586975",367.7002",89.5)|| # text(359.99712,0.32469933) || textangle=89.429076 text={G1} box(359.99712,0.32469933,163.33361",367.7002",89.429076) || # text(0.0028790655,-0.32469933) || textangle=89.429076 text={G2} box(0.0028790655,-0.32469933,163.33361",367.7002",89.429076) ./saods9/template/mmt/mmirs/0000755000175000017500000000000012133201304014627 5ustar olesoles./saods9/template/mmt/mmirs/longslit.tpl0000644000175000017500000000504611444434371017230 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: test.fits global color=green dashlist=8 3 width=1 font="helvetica 10 normal" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,5.2213707e-05) || composite=1 box(0,0,1",408",5.2213707e-05) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016979321,359.89215,0.057385486,359.90996,0.092233383,359.94322,0.11811841,359.98286,0.13249802,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,359.98288,0.073283367,359.94221,0.069587115,359.92874,0.054886822,359.92887,-0.055011809,359.94234,-0.069675137,359.98292,-0.073297943,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,359.98294,-0.13251162,359.94344,-0.11820308,359.91024,-0.092419349,359.89236,-0.057641649,359.89229,-0.017235729) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016944321,359.89215,0.056508482,359.91364,0.088477822,359.94746,0.1093244,359.98286,0.1175641,359.98287,0.091928249,359.93711,0.086467601,359.92194,0.079989511,359.91524,0.062597422,359.91542,-0.062765368,359.92215,-0.080135045,359.93729,-0.08656855,359.98293,-0.091941579,359.98293,-0.117578,359.94765,-0.10939812,359.9139,-0.088649851,359.89236,-0.056764653,359.89229,-0.017200729) || # tag={Mask} # text(359.90741,-9.7747524e-05) || textangle=270.00005 text={Camera 1} tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283029,0.017027184,0.11290769,0.057431829,0.090040766,0.092277881,0.056787713,0.11814596,0.017143943,0.13250625,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,0.017125131,0.073291941,0.057793497,0.069616127,0.071262324,0.054922962,0.071130502,-0.054973028,0.057658219,-0.069643411,0.017083571,-0.073288523,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,0.017068804,-0.13250186,0.056562363,-0.11817101,0.089760798,-0.092369245,0.11268869,-0.057590992,0.11276514,-0.017186583) || # tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283022,0.016992185,0.11192484,0.056556496,0.086360832,0.088520613,0.052547573,0.10935005,0.017139089,0.11757242,0.017130929,0.091936714,0.062891853,0.086498803,0.078062803,0.080028419,0.084756883,0.062640181,0.084577917,-0.062719024,0.077852405,-0.080091921,0.0627089,-0.086533678,0.017078796,-0.091932052,0.017072419,-0.11756833,0.052354648,-0.1093686,0.086103276,-0.088601901,0.11171106,-0.056712414,0.11276521,-0.017151584) || # tag={Mask} # text(0.092595036,-4.9017175e-05) || textangle=90.000052 text={Camera 2} tag={Mask} # vector(359.96798,0.055537453,180",180.00005) || vector=1 tag={Mask} # text(359.98315,0.062281588) textangle=180.00005 text={Wavelength} tag={Mask} ./saods9/template/mmt/mmirs/mask.tpl0000644000175000017500000000505011444434371016323 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: test.fits global color=green dashlist=8 3 width=1 font="helvetica 10 normal" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,5.2213707e-05) || composite=1 box(0,0,240",408",5.2213707e-05) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016979321,359.89215,0.057385486,359.90996,0.092233383,359.94322,0.11811841,359.98286,0.13249802,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,359.98288,0.073283367,359.94221,0.069587115,359.92874,0.054886822,359.92887,-0.055011809,359.94234,-0.069675137,359.98292,-0.073297943,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,359.98294,-0.13251162,359.94344,-0.11820308,359.91024,-0.092419349,359.89236,-0.057641649,359.89229,-0.017235729) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016944321,359.89215,0.056508482,359.91364,0.088477822,359.94746,0.1093244,359.98286,0.1175641,359.98287,0.091928249,359.93711,0.086467601,359.92194,0.079989511,359.91524,0.062597422,359.91542,-0.062765368,359.92215,-0.080135045,359.93729,-0.08656855,359.98293,-0.091941579,359.98293,-0.117578,359.94765,-0.10939812,359.9139,-0.088649851,359.89236,-0.056764653,359.89229,-0.017200729) || # tag={Mask} # text(359.90741,-9.7747524e-05) || textangle=270.00005 text={Camera 1} tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283029,0.017027184,0.11290769,0.057431829,0.090040766,0.092277881,0.056787713,0.11814596,0.017143943,0.13250625,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,0.017125131,0.073291941,0.057793497,0.069616127,0.071262324,0.054922962,0.071130502,-0.054973028,0.057658219,-0.069643411,0.017083571,-0.073288523,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,0.017068804,-0.13250186,0.056562363,-0.11817101,0.089760798,-0.092369245,0.11268869,-0.057590992,0.11276514,-0.017186583) || # tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283022,0.016992185,0.11192484,0.056556496,0.086360832,0.088520613,0.052547573,0.10935005,0.017139089,0.11757242,0.017130929,0.091936714,0.062891853,0.086498803,0.078062803,0.080028419,0.084756883,0.062640181,0.084577917,-0.062719024,0.077852405,-0.080091921,0.0627089,-0.086533678,0.017078796,-0.091932052,0.017072419,-0.11756833,0.052354648,-0.1093686,0.086103276,-0.088601901,0.11171106,-0.056712414,0.11276521,-0.017151584) || # tag={Mask} # text(0.092595036,-4.9017175e-05) || textangle=90.000052 text={Camera 2} tag={Mask} # vector(359.96798,0.055537453,180",180.00005) || vector=1 tag={Mask} # text(359.98315,0.062281588) textangle=180.00005 text={Wavelength} tag={Mask} ./saods9/template/mmt/mmirs/image.tpl0000644000175000017500000000505011444434371016452 0ustar olesoles# Region file format: DS9 version 4.1 # Filename: test.fits global color=green dashlist=8 3 width=1 font="helvetica 10 normal" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 wcs0;fk5 # composite(0,0,5.2213707e-05) || composite=1 box(0,0,408",408",5.2213707e-05) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016979321,359.89215,0.057385486,359.90996,0.092233383,359.94322,0.11811841,359.98286,0.13249802,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,359.98288,0.073283367,359.94221,0.069587115,359.92874,0.054886822,359.92887,-0.055011809,359.94234,-0.069675137,359.98292,-0.073297943,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,359.98294,-0.13251162,359.94344,-0.11820308,359.91024,-0.092419349,359.89236,-0.057641649,359.89229,-0.017235729) || # tag={Mask} polygon(359.89225,-0.00012771548,359.89222,0.016944321,359.89215,0.056508482,359.91364,0.088477822,359.94746,0.1093244,359.98286,0.1175641,359.98287,0.091928249,359.93711,0.086467601,359.92194,0.079989511,359.91524,0.062597422,359.91542,-0.062765368,359.92215,-0.080135045,359.93729,-0.08656855,359.98293,-0.091941579,359.98293,-0.117578,359.94765,-0.10939812,359.9139,-0.088649851,359.89236,-0.056764653,359.89229,-0.017200729) || # tag={Mask} # text(359.90741,-9.7747524e-05) || textangle=270.00005 text={Camera 1} tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283029,0.017027184,0.11290769,0.057431829,0.090040766,0.092277881,0.056787713,0.11814596,0.017143943,0.13250625,1.6000224e-06,0.11759077,8.5553752e-07,0.091934992,0.017125131,0.073291941,0.057793497,0.069616127,0.071262324,0.054922962,0.071130502,-0.054973028,0.057658219,-0.069643411,0.017083571,-0.073288523,1.9770939e-06,-0.091934318,3.0342173e-06,-0.11759067,0.017068804,-0.13250186,0.056562363,-0.11817101,0.089760798,-0.092369245,0.11268869,-0.057590992,0.11276514,-0.017186583) || # tag={Mask} polygon(0.11279767,-7.9210806e-05,0.11283022,0.016992185,0.11192484,0.056556496,0.086360832,0.088520613,0.052547573,0.10935005,0.017139089,0.11757242,0.017130929,0.091936714,0.062891853,0.086498803,0.078062803,0.080028419,0.084756883,0.062640181,0.084577917,-0.062719024,0.077852405,-0.080091921,0.0627089,-0.086533678,0.017078796,-0.091932052,0.017072419,-0.11756833,0.052354648,-0.1093686,0.086103276,-0.088601901,0.11171106,-0.056712414,0.11276521,-0.017151584) || # tag={Mask} # text(0.092595036,-4.9017175e-05) || textangle=90.000052 text={Camera 2} tag={Mask} # vector(359.96798,0.055537453,180",180.00005) || vector=1 tag={Mask} # text(359.98315,0.062281588) textangle=180.00005 text={Wavelength} tag={Mask} ./saods9/template/mmt/hecto/0000755000175000017500000000000012133201304014602 5ustar olesoles./saods9/template/mmt/hecto/hectochelle.tpl0000644000175000017500000000035110270004706017610 0ustar olesoles# Region file format: DS9 version 4.0 global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || point(0,0) || # point=boxcircle circle(0,0,1800") ./saods9/template/mmt/hecto/hectospec.tpl0000644000175000017500000000035110270004706017306 0ustar olesoles# Region file format: DS9 version 4.0 global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || point(0,0) || # point=boxcircle circle(0,0,1800") ./saods9/template/mmt/swirc.tpl0000644000175000017500000000373610270004707015371 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/sao/swirc.fits global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(0,0,0) || point(0,0) || # point=boxcircle # text(359.97636,0.021004921) || font="times 12 normal" text={I} # text(359.97633,-0.021495059) || font="times 12 normal" text={II} # text(0.023662353,-0.021532975) || font="times 12 normal" text={III} # text(0.023196531,0.021134073) || font="times 12 normal" text={IV} box(0.021365501,0.02401054,153.6",19.2",0) || box(0.021361229,0.01867721,153.6",19.2",0) || box(359.97603,0.021380188,19.2",153.6",0) || box(359.97866,-0.01862193,153.6",19.2",0) || box(359.97866,-0.023955261,153.6",19.2",0) || box(0.023995853,-0.021324909,19.2",153.6",0) || box(0.021348413,0.0026772167,153.6",19.2",0) || box(0.021352685,0.0080105479,153.6",19.2",0) || box(0.021356957,0.013343879,153.6",19.2",0) || box(0.021369773,0.02934387,153.6",19.2",0) || box(0.021374046,0.0346772,153.6",19.2",0) || box(0.021378318,0.040010529,153.6",19.2",0) || box(359.97865,-0.039955249,153.6",19.2",0) || box(359.97865,-0.03462192,153.6",19.2",0) || box(359.97866,-0.029288591,153.6",19.2",0) || box(359.97867,-0.013288599,153.6",19.2",0) || box(359.97867,-0.0079552683,153.6",19.2",0) || box(359.97868,-0.0026219371,153.6",19.2",0) || box(359.96003,0.021393001,19.2",153.6",0) || box(359.96536,0.021388731,19.2",153.6",0) || box(359.9707,0.021384459,19.2",153.6",0) || box(359.98136,0.021375917,19.2",153.6",0) || box(359.9867,0.021371645,19.2",153.6",0) || box(359.99203,0.021367373,19.2",153.6",0) || box(359.99736,0.021363101,19.2",153.6",0) || box(0.0026625281,-0.021307822,19.2",153.6",0) || box(0.0079958596,-0.021312094,19.2",153.6",0) || box(0.013329191,-0.021316366,19.2",153.6",0) || box(0.018662522,-0.021320637,19.2",153.6",0) || box(0.029329184,-0.02132918,19.2",153.6",0) || box(0.034662514,-0.021333451,19.2",153.6",0) || box(0.039995843,-0.021337722,19.2",153.6",0) ./saods9/template/xmm/0000755000175000017500000000000012132057676013530 5ustar olesoles./saods9/template/xmm/epicpn.tpl0000644000175000017500000000424610370226423015523 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/xmm/epicpn/image_epicpn.ds global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(-0.032,0.0166,0) || point(359.9684,0.017688302) || # point=boxcircle polygon(0.0024077734,-0.00014830005,359.78785,-0.00041752552,359.78786,-0.072646412,0.0018211508,-0.072695941) || # text(359.90368,-0.036006347) || text={1} polygon(0.0024077734,-0.00014830005,359.78785,-0.00041752552,359.78786,-0.072646412,0.0018211508,-0.072695941) || # text(359.90247,-0.11213125) || text={2} polygon(0.0021963947,-0.075102588,359.78764,-0.075372326,359.78765,-0.14760027,0.0016077991,-0.14765228) || # text(359.90368,-0.18704668) || text={3} polygon(0.0019729992,-0.14975594,359.78741,-0.15002511,359.78742,-0.2222521,0.0013929609,-0.22230368) || # text(359.90247,0.041326975) || text={4} polygon(0.0026231785,0.074806934,359.78805,0.074537239,359.78807,0.0023093611,0.0020385428,0.0022583476) || # text(359.90126,0.11382726) || text={5} polygon(0.0028373576,0.14976211,359.78827,0.14949189,359.78828,0.077263098,0.0022494778,0.077213572) || # text(359.90247,0.18632595) || text={6} polygon(0.0030451022,0.22471722,359.78848,0.2244455,359.78849,0.15221877,0.0024592092,0.15216874) || # text(0.11272235,0.040118972) || text={7} polygon(0.21961801,0.074544059,0.0050560461,0.074274386,0.0050631475,0.0020453621,0.21903517,0.0019959256) || # text(0.11272285,0.11141062) || text={8} polygon(0.21982932,0.14949757,0.0052702679,0.14922958,0.0052781157,0.077000618,0.21924514,0.076949464) || # text(0.11513727,0.18753426) || text={9} polygon(0.22003744,0.22445102,0.0054832423,0.22418372,0.0054866164,0.15195581,0.21945715,0.15190497) || # text(0.1115122,-0.037214702) || text={10} polygon(0.21940876,-0.00041148409,0.0048458181,-0.00068086539,0.0048521831,-0.072908947,0.21882206,-0.07295968) || # text(0.1127201,-0.11333958) || text={11} polygon(0.21919634,-0.075366094,0.0046291113,-0.075636181,0.0046399943,-0.14786432,0.21860577,-0.14791435) || # text(0.11272043,-0.1870464) || text={12} polygon(0.21897336,-0.15001881,0.0044055854,-0.15028956,0.0044157238,-0.22251775,0.21838946,-0.22256606) ./saods9/template/xmm/epicmos2.tpl0000644000175000017500000000250110370226423015756 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/xmm/epicmos/image_epicmos2.ds global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(-.02,-.015099,0) || point(359.98032,-0.015255945) || # point=boxcircle # text(0.002598154,-7.5391061e-05) || text={1} # text(0.19351408,-0.090699798) || text={2} # text(0.0013898207,-0.18132479) || text={3} # text(359.80806,-0.090699806) || text={4} # text(0.19351408,0.09175734) || text={7} # text(0.00018148737,0.18600729) || text={6} # text(359.80927,0.092965679) || text={5} polygon(0.092381631,0.092656826,359.91167,0.092172121,359.91162,-0.090971255,0.092913154,-0.089866031) || polygon(0.091779215,-0.092315194,359.90928,-0.093457297,359.91102,-0.2759413,0.092316593,-0.27483652) || polygon(359.90894,-8.3494418e-05,359.72643,-0.00062029737,359.72749,-0.18040463,359.90763,-0.18114781) || polygon(359.90805,0.18424156,359.72735,0.1837549,359.7273,0.00061430326,359.90859,0.0017195055) || polygon(0.091791652,0.27698791,359.91108,0.27650239,359.91103,0.09336198,0.092327659,0.094467032) || polygon(0.27583152,0.18479008,0.095118571,0.18430591,0.095069778,0.001163703,0.27636646,0.0022696912) || polygon(0.27552481,0.00013033963,0.094815474,-0.00035441732,0.094691734,-0.18108137,0.27625199,-0.17875761) ./saods9/template/xmm/epicmos1.tpl0000644000175000017500000000250110370226422015754 0ustar olesoles# Region file format: DS9 version 4.0 # Filename: /home/joye/templates/xmm/epicmos/image_epicmos1.ds global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source wcs0;fk5 # composite(-0.017,-0.014495,0) || point(359.98122,-0.014772826) || # point=boxcircle # text(0.095331979,0.18528183) || text={5} # text(0.18353977,0.0004077268) || text={6} # text(359.99987,0.00040772889) || text={1} # text(359.90683,0.18649016) || text={4} # text(359.81379,0.0016160537) || text={3} # text(0.092915319,-0.18325807) || text={7} # text(359.90925,-0.18204976) || text={2} polygon(0.18524639,0.27414948,0.0045201849,0.27427278,0.0056046815,0.09358257,0.1845215,0.093406209) || polygon(0.18400899,-0.094584329,0.0032641713,-0.093859609,0.0043500151,-0.27454963,0.18385383,-0.2741015) || polygon(0.27711421,0.089482136,0.094538624,0.090759,0.093867077,-0.091797152,0.27761497,-0.091828859) || polygon(0.092712157,0.091309595,359.91014,0.092586111,359.91122,-0.088106013,0.092552581,-0.088209985) || polygon(0.0033282835,0.27363238,359.82076,0.27490768,359.82001,0.094768685,0.0031744198,0.094115539) || polygon(359.90953,0.092568474,359.72696,0.093844064,359.72812,-0.089262169,359.90881,-0.088176995) || polygon(0.0019846216,-0.091478854,359.81886,-0.092032372,359.8205,-0.27089198,0.0018258799,-0.27099729) ./saods9/make.darwinppcleopard0000644000175000017500000000116611773331763015317 0ustar olesolesOS = unix ARCH = darwinppcleopard X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation export MACOSX_DEPLOYMENT_TARGET := 10.5 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch ppc -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip ASTFLAGS = star_cv_cnf_trail_type=long JOBS = 4 ./saods9/ds9/0000755000175000017500000000000012133201304011567 5ustar olesoles./saods9/ds9/Makefile0000644000175000017500000002340112036045553013245 0ustar olesolesinclude ../make.include include ../make.pkgs #--------------------------defines ZDIR = zipdir/zvfsmntpt FFILES = $(ZDIR)/$(TCLVER) \ $(ZDIR)/tcl8 \ $(ZDIR)/$(TKVER) \ $(ZDIR)/$(BLTVER) \ $(ZDIR)/$(TCLLIBVER) \ $(ZDIR)/$(TKCONVER) \ $(ZDIR)/$(XMLRPCVER) \ $(ZDIR)/src \ $(ZDIR)/msgs \ $(ZDIR)/doc \ $(ZDIR)/cmaps \ $(ZDIR)/template ifdef FILTERCOMPILER FILES = $(FFILES) \ $(ZDIR)/$(FILTERCOMPILER) else FILES = $(FFILES) endif # for unix, macosx MAINDIR = ../$(TKDIR)/unix MAIN = tkAppInit LIBS = \ ../lib/libsaotk.a \ ../lib/libtkhtml.a \ ../lib/libtkmpeg.a \ ../lib/$(TCLXMLVER)/libTclxml3.2.a \ ../lib/$(TKTABLEVER)/libTktable2.10.a \ ../lib/$(TKIMGVER)/libtkimgpng1.4.a \ ../lib/$(TKIMGVER)/libpngtcl1.4.3.a \ ../lib/$(TKIMGVER)/libtkimgtiff1.4.a \ ../lib/$(TKIMGVER)/libtifftcl3.9.4.a \ ../lib/$(TKIMGVER)/libtkimgjpeg1.4.a \ ../lib/$(TKIMGVER)/libjpegtcl8.2.a \ ../lib/$(TKIMGVER)/libtkimggif1.4.a \ ../lib/$(TKIMGVER)/libtkimgppm1.4.a \ ../lib/$(TKIMGVER)/libtkimgwindow1.4.a \ ../lib/$(TKIMGVER)/libzlibtcl1.2.5.a \ ../lib/$(TKIMGVER)/libtkimg1.4.a \ ../lib/libtiff.a \ ../lib/libfuntools.a \ ../lib/librice.a \ ../lib/libhcomp.a \ ../lib/libplio.a \ ../lib/libast.a \ ../lib/libast_err.a \ ../lib/libast_pal.a \ ../lib/libsaotk.a \ ../lib/libwcs.a \ ../lib/libzvfs.a \ ../lib/libzip.a \ ../lib/libz.a \ ../lib/libxpa.a \ ../lib/libiis.a \ ../lib/libcheckdns.a \ ../lib/libsignal_ext.a \ ../lib/libxxlib.a \ ../lib/libBLTX30.a \ ../lib/libBLTCore30.a \ ../lib/libtk8.5.a \ ../lib/libtcl8.5.a # if windows, redefine ifeq ($(OS),windows) MAINDIR = ../$(TKDIR)/win MAIN = winMain RES = ds9.res.o LIBS = \ ../lib/libsaotk.a \ ../lib/libtkhtml.a \ ../lib/libtkmpeg.a \ ../lib/$(TCLXMLVER)/Tclxml32.a \ ../lib/$(TKTABLEVER)/Tktable210.a \ ../lib/$(TKIMGVER)/tkimgpng14.a \ ../lib/$(TKIMGVER)/pngtcl143.a \ ../lib/$(TKIMGVER)/tkimgtiff14.a \ ../lib/$(TKIMGVER)/tifftcl394.a \ ../lib/$(TKIMGVER)/tkimgjpeg14.a \ ../lib/$(TKIMGVER)/jpegtcl82.a \ ../lib/$(TKIMGVER)/tkimggif14.a \ ../lib/$(TKIMGVER)/tkimgppm14.a \ ../lib/$(TKIMGVER)/tkimgwindow14.a \ ../lib/$(TKIMGVER)/zlibtcl125.a \ ../lib/$(TKIMGVER)/tkimg14.a \ ../lib/libtiff.a \ ../lib/libfuntools.a \ ../lib/librice.a \ ../lib/libhcomp.a \ ../lib/libplio.a \ ../lib/libast.a \ ../lib/libast_err.a \ ../lib/libast_pal.a \ ../lib/libsaotk.a \ ../lib/libwcs.a \ ../lib/libzvfs.a \ ../lib/libzip.a \ ../lib/libz.a \ ../lib/libxpa.a \ ../lib/libiis.a \ ../lib/libcheckdns.a \ ../lib/libxxlib.a \ ../lib/libBLTX30.a \ ../lib/libBLTCore30.a \ ../lib/libtk85sg.a \ ../lib/libtcl85sg.a endif OBJS = ds9.o $(MAIN).o $(RES) #--------------------------targets ifeq ($(OS),unix) CFLAGS= $(CCOPT) -I. -I../include \ -I../$(TKDIR)/generic -I../$(TKDIR)/unix \ -I$(X11INCLUDE) ifneq (,$(findstring darwin,$(ARCH))) CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE all: ds9 ds9 : ds9Base ds9.zip $(RM) $@ cp ds9Base ds9 strip ds9 cp ds9 ../bin/. cp ds9.zip ../bin/. cd ../bin; $(CODESIGN) -s "SAOImage DS9" ds9 debug : ds9Base ds9.zip $(RM) $@ cp ds9Base ds9 ds9.zip : $(FILES) cd zipdir; ../../bin/zip -r9 ../ds9.zip * else CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) all: ds9 ds9 : null.zip ds9Base $(FILES) $(RM) $@ cp ds9Base ds9.zip strip ds9.zip cat null.zip >> ds9.zip cd zipdir; ../../bin/zip -rA9 ../ds9.zip * mv ds9.zip ds9 cp ds9 ../bin/. debug : null.zip ds9Base $(FILES) $(RM) $@ cp ds9Base ds9.zip cat null.zip >> ds9.zip cd zipdir; ../../bin/zip -rA9 ../ds9.zip * mv ds9.zip ds9 endif endif ifeq ($(OS),windows) CFLAGS= $(CCOPT) -I. -I../include \ -I../$(TKDIR)/generic -I../$(TKDIR)/win \ -I$(X11INCLUDE) CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE all: ds9.exe ds9.exe : ds9Base.exe ds9.zip ../bin/tcc $(RM) $@ cp ds9Base.exe ds9.exe strip ds9.exe cp ds9.exe ../bin/. cp ds9.zip ../bin/. cp /bin/cygwin1.dll ../bin/. cp /bin/cygxml2-2.dll ../bin/. cp /bin/cygstdc++-6.dll ../bin/. cp /bin/cygiconv-2.dll ../bin/. cp /bin/cygz.dll ../bin/. cp /bin/cyggcc_s-1.dll ../bin/. cp /bin/cygjbig-2.dll ../bin/. cp /bin/cyglzma-5.dll ../bin/. debug : ds9Base.exe ds9.zip ../bin/tcc $(RM) $@ cp ds9Base.exe ds9.exe ds9app : ds9.exe $(RM) -r ../bin/ds9app mkdir ../bin/ds9app cp ds9.exe ../bin/ds9app/. cp ds9.zip ../bin/ds9app/. cp /bin/cygwin1.dll ../bin/ds9app/. cp /bin/cygxml2-2.dll ../bin/ds9app/. cp /bin/cygstdc++-6.dll ../bin/ds9app/. cp /bin/cygiconv-2.dll ../bin/ds9app/. cp /bin/cygz.dll ../bin/ds9app/. cp /bin/cyggcc_s-1.dll ../bin/ds9app/. cp /bin/cygjbig-2.dll ../bin/ds9app/. cp /bin/cyglzma-5.dll ../bin/ds9app/. cp -rp ../bin/tcc ../bin/ds9app/. cp ../ds9/win/install.vbs ../bin/ds9app/. ds9.zip : $(FILES) cd zipdir; ../../bin/zip -r9 ../ds9.zip * endif ifeq ($(OS),macosx) CFLAGS= $(CCOPT) -I. -I../include \ -I../$(TKDIR)/generic -I../$(TKDIR)/macosx \ -I$(X11INCLUDE) CXXFLAGS = $(CXXOPT) -I. -I../include -I$(X11INCLUDE) -DZIPFILE all: ds9 ds9 : ds9Base ds9.zip $(RM) $@ cp ds9Base ds9 strip ds9 cp ds9 ../bin/. cp ds9.zip ../bin/. debug : ds9Base ds9.zip $(RM) $@ cp ds9Base ds9 ds9app : ds9 rm -rf ../bin/SAOImage\ DS9.app cp -rp macosx/SAOImage\ DS9.app ../bin/. cd ../bin/SAOImage\ DS9.app; find -d . -name CVS -exec rm -rf {} \; cp -p ../bin/ds9 ../bin/SAOImage\ DS9.app/Contents/MacOS/. cp -p ../bin/ds9.zip ../bin/SAOImage\ DS9.app/Contents/MacOS/. cd ../bin; $(CODESIGN) -s "SAOImage DS9" SAOImage\ DS9.app ds9.zip : $(FILES) cd zipdir; ../../bin/zip -r9 ../ds9.zip * endif $(MAIN).o : $(MAIN).c $(CC) $(CFLAGS) -DTK_LOCAL_APPINIT=SAOAppInit \ -DTK_LOCAL_MAIN_HOOK=SAOLocalMainHook -c $(MAIN).c -o $@ $(MAIN).c : $(MAINDIR)/$(MAIN).c cp $(MAINDIR)/$(MAIN).c . null.zip: echo . | zip null.zip - zip null.zip -d - zipdir : mkdir zipdir mkdir $(ZDIR) $(ZDIR)/$(TCLVER) : zipdir ../lib/$(TCLVER) $(RM) -r $@ cp -r ../lib/$(TCLVER) $(ZDIR)/. $(ZDIR)/tcl8 : zipdir ../lib/tcl8 $(RM) -r $@ cp -r ../lib/tcl8 $(ZDIR)/. $(ZDIR)/$(TKVER) : zipdir ../lib/$(TKVER) $(RM) -r $@ cp -r ../lib/$(TKVER) $(ZDIR)/. rm -rf $(ZDIR)/$(TKVER)/images rm -rf $(ZDIR)/$(TKVER)/demos $(ZDIR)/$(BLTVER) : zipdir $(RM) -r $@ mkdir $(ZDIR)/$(BLTVER) mkdir $(ZDIR)/$(BLTVER)/afm cp ../$(BLTDIR)/library/graph.tcl $(ZDIR)/$(BLTVER)/. cp ../$(BLTDIR)/library/bltGraph.pro $(ZDIR)/$(BLTVER)/. cp ../$(BLTDIR)/library/tclIndex $(ZDIR)/$(BLTVER)/. cp ../$(BLTDIR)/library/afm/*.afm $(ZDIR)/$(BLTVER)/afm/. $(ZDIR)/$(TCLLIBVER) : zipdir $(RM) -r $@ mkdir $(ZDIR)/$(TCLLIBVER) cp -r ../$(TCLLIBDIR)/modules/base64 $(ZDIR)/$(TCLLIBVER)/. cp -r ../$(TCLLIBDIR)/modules/ftp $(ZDIR)/$(TCLLIBVER)/. cp -r ../$(TCLLIBDIR)/modules/log $(ZDIR)/$(TCLLIBVER)/. cp -r ../$(TCLLIBDIR)/modules/textutil $(ZDIR)/$(TCLLIBVER)/. cp -r ../$(TCLLIBDIR)/modules/math $(ZDIR)/$(TCLLIBVER)/. $(ZDIR)/$(TKCONVER) : zipdir ../lib/$(TKCONVER) $(RM) -r $@ cp -r ../lib/$(TKCONVER) $@ $(ZDIR)/$(XMLRPCVER) : zipdir ../lib/$(XMLRPCVER) $(RM) -r $@ cp -r ../lib/$(XMLRPCVER) $@ $(ZDIR)/src : zipdir ../src/*.tcl $(RM) -r $@ cp -r ../src $(ZDIR)/. $(ZDIR)/msgs : zipdir ../msgs/* $(RM) -r $@ cp -r ../msgs $(ZDIR)/. $(ZDIR)/doc : zipdir ../doc/* ../doc/ref/* ../doc/user/* ../doc/release/* $(RM) -r $@ cd ..; find doc -name "*.html" | cpio -pdmuv ds9/$(ZDIR) cd ..; find doc -name "*.gif" | cpio -pdmuv ds9/$(ZDIR) cd ..; find doc -name "*.png" | cpio -pdmuv ds9/$(ZDIR) $(ZDIR)/cmaps : zipdir ../cmaps/* $(RM) -r $@ cp -r ../cmaps $(ZDIR)/. $(ZDIR)/template : zipdir ../template/* $(RM) -r $@ cd ..; find template -name "*.tpl" | cpio -pdmuv ds9/$(ZDIR) ifdef FILTERCOMPILER $(ZDIR)/$(FILTERCOMPILER) : zipdir ../compilers/$(FILTERCOMPILER) $(RM) -r $@ cp ../compilers/$(FILTERCOMPILER) $(ZDIR)/$(FILTERCOMPILER) endif #--------------------------solaris ifeq ($(ARCH),solaris) ds9Base : $(OBJS) $(LIBS) $(RM) $@ rm -f libstdc++.a ln -s `$(CXX) ${OPTS} -print-file-name=libstdc++.a` . $(CXX) -static-libgcc ${OPTS} \ -o $@ $(OBJS) $(LIBS) \ -Wl,-Bstatic -L. -lstdc++ \ -Wl,-Bdynamic \ -L$(X11LIB) -lX11 -lXext -lXft -lXrender -lfontconfig -lfreetype \ -lxml2 \ -lsocket -lnsl -ldl rm -f libstdc++.a endif #--------------------------linux ifneq (,$(findstring linux,$(ARCH))) ds9Base : $(OBJS) $(LIBS) $(RM) $@ rm -f libstdc++.a ln -s `$(CXX) ${OPTS} -print-file-name=libstdc++.a` . $(CXX) ${OPTS} -static-libgcc -Wl,--export-dynamic \ -o $@ $(OBJS) $(LIBS) \ -Wl,-Bstatic -L. -lstdc++ \ -Wl,-Bdynamic \ -L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss \ -lxml2 \ -ldl -lpthread rm -f libstdc++.a endif #--------------------------darwin ifneq (,$(findstring darwin,$(ARCH))) ds9Base : $(OBJS) $(LIBS) $(RM) $@ $(CXX) ${OPTS} \ -o $@ $(OBJS) $(LIBS) \ -L$(X11LIB) -lX11 -lXext -lXft -lXrender -lXss -lfontconfig -lfreetype \ -lxml2 \ -lstdc++ -liconv endif #--------------------------macosx ifeq ($(OS),macosx) ds9Base : $(OBJS) $(LIBS) $(RM) $@ $(CXX) ${OPTS} \ -o $@ $(OBJS) $(LIBS) \ -lxml2 \ -lstdc++ -liconv \ -sectcreate __TEXT __tk_rsrc ../$(TKDIR)/unix/tk8.5.rsrc \ -framework CoreFoundation -framework Carbon endif #--------------------------windows ifeq ($(OS),windows) ds9Base.exe: $(OBJS) $(LIBS) $(RM) $@ $(CXX) ${OPTS} \ -o $@ $(OBJS) $(LIBS) \ -lxml2 -ljbig \ -lws2_32 -limm32 -lcomctl32 -mwindows $(RES) : win/ds9.rc win/ds9.ico windres -o $@ --define STATIC_BUILD --include ../$(TKDIR)/generic \ --include ../$(TCLDIR)/generic --include ../$(TKDIR)/win/rc \ --include win win/ds9.rc ../bin/tcc: ../compilers/$(TCC) $(RM) -r $@ cd ../bin; unzip ../compilers/$(TCC) chmod +x ../bin/tcc/tcc.exe touch $@ endif #--------------------------cleanup clean : FORCE $(RM) core *~ *# ifeq ($(OS),windows) distclean: FORCE $(RM) core *~ *# ds9Base.exe ds9.exe *.zip *.o $(RM) -r zipdir bin/tcc else distclean: FORCE $(RM) core *~ *# ds9Base ds9 *.zip *.o $(RM) -r zipdir endif FORCE : ./saods9/ds9/win/0000755000175000017500000000000012132057632012400 5ustar olesoles./saods9/ds9/win/message.txt0000644000175000017500000000010311370071032014550 0ustar olesolesTo install SAOImage DS9 in C:\ds9, please select the Setup button. ./saods9/ds9/win/ds9.ico0000644000175000017500000056511611367615300013612 0ustar olesoles(öh h† èî ¨ Ö  ¨~00h&*00¨Ž000 ¨%6M@@h Þr@@(2F}@@ (Bn¯€€h(–ñ€€(Èþ€€ (&â( À˜À°HàøP¸€øøøp°`èèØèàÀ0ÐÈ 0¨À€¸°X°ˆØÈˆHÀ˜àà@Û½@¥Éë`@@lSìF“žˆè饒JÆšñÿV¿‡²Œ “§—ðïÜýýüýüùÿþýȶSž¦”¤“¨5Ò¿ñÿâèw¬Vc·píþæúéÿçþèÿãòçýéþàçc¸q#ÝÝñÿ.Öˤ“«°«†È­=þÿÿýüúßïߢ4¯¦’§‘²‹–›äð ëÿ éÿ'ÚØèþçþçþèÿçÿèÿçþèÿäõèÿ ëÿçøˆ£3¶ˆ‰¢0TÀ‰MÆ—v§BíḵȅÕÌ…§>£“”œ§@ 3Z¼€ éúæú êÿçÿèÿçþçþèÿçþçþçÿèÿæû ëüd·p¶ˆo±\äïòÿâì'оšÎôõê´œ3ηðÿ#Ýßâð êÿ êÿ$ÜÝä÷èþæýèþçþèÿèÿèÿèÿçþèÿçýèþáéc·o7Ñ» éÿíÿGÈž¨’¥¡)ûûöÓÌ‹¬’–š;ϲãîçÿíÿ ìÿ êÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçý íÿ ëÿíÿ(ÙÔ¤’©¥“¤Œåß¶¿±J£”¨‘©š˜”›r¯Z5Ò»çøçýçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿæûæö0ÕÅ–š«Ž¢”£” ɾhµ¢%®Ž±Œ¯©˜š‡£5W¾…åôèþçýèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþçýèþ)ÙÓt­S—™¤“¯²‹­‹¸§1¢£-{ªIX¾…<ζ#Ýßæú ìÿ ìÿèÿçÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçü éÿæú#Ýß:Ï·V¿ˆx«M¡££+}©F[¼~>Ͱ'ÚØäôéÿæûçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿ ìÿ ìÿäö%ÛÜ?̱Y¾ƒzªJ£œ¶£(®Ž²‹°Œ§‘›˜x«L.ÖÊèþçýçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþæùV¿‡‰¢2›˜«°±Œ­‹¸¦2¿±J£“£”¡”ª–š/ÖÆæ÷æûèÿçÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþçýçú1ÔÃl²cž$•›¦‘©‘ŸËÀlÖÍ‹«“¥‘©¦’*ØÐíÿ ëÿ ìÿæüèþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿ êÿ ìÿíÿéÿå÷2Ô¿‘ž&§‹åâ½øõ硨;Ÿ¦’IÇœíÿ éÿ6Ò¼gµj!Ýâéþæüèþçþèÿèÿèÿèÿçþèþçýèþåø'ÚØèÿ êÿâî&ÛÛîÿ)ÕÊ­™úüù¦Ñ¡)θåðñÿäïl²a¶ˆk´e ëýæûèÿçÿçþçþèÿçþçþèÿçÿ êÿæü êüU¿‰‘,€§?•›¢“Ž¢2!ÓȯÅþÿÿóæÄ§=SÁ‹Y¾Š¢/µ‰Œ ,æö ëÿèÿãñèþçþéÿçÿèÿçþçþèþ(Ú×èÿ ëÿçö‹¡-³Š§‘¥’°‚¡.ÛîÝüüùþÿÿζQ«…±Žª¦‘2ÓÄñÿ!Ýßhµh!Þâéþçÿãñèþçþéÿæûìþ[¼}§Gßàñÿ+×Ð¥’¤’¦”žÅ²Kÿþüüüúýýûôó媛Ÿ’²Œ]»zñÿHÇž¡”…¤7 êÿ ëþ;϶a¹uìþèþ5ÓÁå÷éû#ÜÝ«ŽŸ•NÄ”ïÿSÀ‹³‹¢’©—ñðÜýýüýýüáݰ§‰¦<&ÜÜx¬R­°‹zªIèÿìÿw¬OŒ , éÿ êÿ{ªHCʦïÿ ëÿQÁ±‹®}©H%ÜÝ{«J§ˆÝØ£ýýûýýûÿÿÿÙÏŽl©I–š²£”©•›äõåø’!– äõæú—š ”Dʤ êÿ ëÿu­Qª¯Ž›™l¥@ÒÉ€ÿÿÿýýûþþþþþþÿÿÿÝ΋¦ ¦•©‘Ÿ• àëäöš˜ª,×Ð%Ûܤ“§®f¶kïÿ>γ°Ÿ‘¥ÙÈ}ÿÿÿþþþþþþÿÿÿå⺰ &‹¬Œr²^ôÿHÇ ¨‘°ŒCʧ:Ï·¯Œ¢”£“°Ž+ÛÙ<̯©„« âݱÿÿÿþþþøøîÒÂr~°X$ѵJ¾ƒŸ’¤’¯Œ`¹u[¼±‹¢“£ 2Ȩ®OÔ¾m÷öëýýûñöìÒДç2®›¥–¬Ž…¤7€§?¬Ž¥– ®š±°G½Ù°øïØýýûþþýüüùÿÿÿëèÌÑÈÅ·YºµU»´SÅ·YÑÈëèËÿÿÿýüùþþýÿþÿÿðÿÿŽqÿþ|>ýпû@ßõ€¯þê_Ü;ðø€Ð €€Ð €øðÜ;ê_þõ€¯û@ßýÐ ¿þz^ÿ€ÿÿú_ÿÿþÿ( @ þþþýüúÿÿÿ÷÷íLçã½KÙÏ‘ÞÒˇÿÒˇÿÖÍÞçáºKööëLÿÿÿþþþýýûùïÙ>¼Ú²±¬®Fì«• ÿ ÿ¨‰ÿ¡0ÿ{£5ÿ¨‰ÿŸÿª• ÿ¿£'ìÏÍŒ°íôç>ÿÿÿ ýýû÷÷ë;Ô¾n³…«Hÿ/Ê­ÿžŽÿ¤ü£”ü±þaºxÿZ¾„ÿ±þ¥“ü ’üL½ƒÿ Ó»ÿx±YÿͼeÑöôæ;þþþÿÿÿãßµ‡¬ž"ÿ©„ÿFÇžý&Ýàû®Žý¥“þ¡”þ±‹ÿCʨÿ;϶ÿ®ÿ©þMĘþõÿýj¶kû¬ŒýŒÿ¬›ÿàÚª‡ÿÿÿþþþþþþÿÿÿÜÍŠ·¦ÿž‘û°ûIÇŸþïÿÿ^ºxþ«ÿ¨‘ÿ¦’ÿ,×Ïÿ#ÜÞÿ¦‘ÿ¢”ÿáéÿâðþŸ– þ©‘þ¦•ü¡‘û¤‹ÿׯx·ÿÿÿþþþýýûÿÿÿ ÙÎŒºo¨Fÿ–›ø°Žþªÿ{ªGþ êýÿ ëÿÿ9жÿ›˜ÿ– ÿãôÿæüÿ—šÿ˜™ÿãóÿæúÿž$ÿ©þ¢”ÿ±þššøj¨GÿÑÇ}ºÿÿÿ ýýüþþþýýûàÛ«‡¦‰ÿ…¤8ù#Ýàÿs®Xþ¬Žþ³Šÿ[¼~ÿ êÿÿîÿÿ7Ñ»ÿ¨Bÿèÿÿ ìÿÿ‚¦=ÿ}¨Cÿ ëþÿ éÿÿu­Qÿ±‹ÿ­þx«Qþ%ÜÝÿ©Cù¦ˆÿÛÖŸ¯ýýûýýûóòâ:ª˜ü¢’ø²Œþ^ºxþñÿÿGÈ ÿš˜ÿ¯Œÿ*ÙÓÿ éüÿåùÿ3ÓÃÿçþÿíþÿ[¼~ÿ=Ͳÿ ëþÿ êÿÿ€§>ÿ¥’ÿJÆšÿñÿÿV¿‡þ²Œþ “ø§—þðïÜ_ýýüýüùÿþýȶSÞžÿ¦”û¤“ÿ¨þ5Ò¿ÿñÿÿâèÿw¬Vÿc·pÿíþÿæúÿéÿÿçþÿèÿÿãòÿçýÿéþÿàçÿc¸qÿ#ÝÝÿñÿÿ.ÖËÿ¤“þ«ÿ°û«†þÈ­=éþÿÿ ýüúßïßj¢4ÿ¯ú¦’þ§‘þ²‹ÿ–›ÿäðÿ ëÿÿ éÿÿ'ÚØÿèþÿçþÿçþÿèÿÿçÿÿèÿÿçþÿèÿÿäõÿèÿÿ ëÿÿçøÿˆ£3ÿ¶ˆÿ‰¢0þTÀ‰þMÆ—úv§Bÿíá¸vµÈ…½ÕÌý…§>û£“ÿ”œÿ§@ÿ 3ÿZ¼€ÿ éúÿæúÿ êÿÿçÿÿèÿÿçþÿçþÿèÿÿçþÿçþÿçÿÿèÿÿæûÿ ëüÿd·pÿ¶ˆÿo±\ÿäïÿòÿÿâìü'оýšÎàôõê|´œþ3ηþðÿþ#Ýßþâðÿ êÿÿ êÿÿ$ÜÝÿä÷ÿèþÿæýÿèþÿçþÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçýÿèþÿáéÿc·oÿ7Ñ»ÿ éÿÿíÿÿGÈžþ¨’þ¥ü¡)úûûö4ÓÌ‹›¬’ÿ–šÿ;ϲÿãîÿçÿÿíÿÿ ìÿÿ êÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçýÿ íÿÿ ëÿÿíÿÿ(ÙÔÿ¤’ÿ©ÿ¥“ü¤Œÿåß¶w¿±J꣔þ¨‘ÿ©þš˜ÿ”›ÿr¯Zÿ5Ò»ÿçøÿçýÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿæûÿæöÿ0ÕÅÿ–šÿ«Žÿ¢”þ£”ÿ þɾhÿµ¢%ÿ®Žÿ±Œÿ¯ÿ©ÿ˜šÿ‡£5ÿW¾…ÿåôÿèþÿçýÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿçýÿèþÿ)ÙÓÿt­Sÿ—™ÿ¤“ÿ¯ÿ²‹þ­‹ÿ¸§1ý¢£-þ{ªIÿX¾…ÿ<ζÿ#Ýßÿæúÿ ìÿÿ ìÿÿèÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçüÿ éÿÿæúÿ#Ýßÿ:Ï·ÿV¿ˆÿx«Mÿ¡ÿ££+þ}©Fÿ[¼~ÿ>Ͱÿ'ÚØÿäôÿéÿÿæûÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçÿÿèÿÿ ìÿÿ ìÿÿäöÿ%ÛÜÿ?̱ÿY¾ƒÿzªJÿ£œÿ¶£(ÿ®Žÿ²‹ÿ°Œÿ§‘ÿ›˜ÿx«Lÿ.ÖÊÿèþÿçýÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿæùÿV¿‡ÿ‰¢2ÿ›˜ÿ«ÿ°ÿ±Œþ­‹ÿ¸¦2ý¿±J裓þ£”ÿ¡”þªÿ–šÿ/ÖÆÿæ÷ÿæûÿèÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿçýÿçúÿ1ÔÃÿl²cÿž$ÿ•›ÿ¦‘þ©‘ÿŸþËÀlÿÖÍ‹ «“ÿ¥‘ÿ©ÿ¦’ÿ*ØÐÿíÿÿ ëÿÿ ìÿÿæüÿèþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçÿÿèÿÿ êÿÿ ìÿÿíÿÿéÿÿå÷ÿ2Ô¿ÿ‘ž&ü§‹ÿåâ½wøõç@¡¨;ðŸþ¦’þIÇœþíÿÿ éÿÿ6Ò¼ÿgµjÿ!Ýâÿéþÿæüÿèþÿçþÿèÿÿèÿÿèÿÿèÿÿçþÿèþÿçýÿèþÿåøÿ'ÚØÿèÿÿ êÿÿâîÿ&ÛÛþîÿþ)ÕÊü­™úúüù4¦Ñ¡»)θýåðûñÿÿäïÿl²aÿ¶ˆÿk´eÿ ëýÿæûÿèÿÿçÿÿçþÿçþÿèÿÿçþÿçþÿèÿÿçÿÿ êÿÿæüÿ êüÿU¿‰ÿ‘,ÿ€§?ÿ•›ÿ¢“ÿŽ¢2ü!ÓÈý¯ÅàþÿÿóæÄj§=ÿSÁ‹úY¾þŠ¢/þµ‰ÿŒ ,ÿæöÿ ëÿÿèÿÿãñÿèþÿçþÿéÿÿçÿÿèÿÿçþÿçþÿèþÿ(Ú×ÿèÿÿ ëÿÿçöÿ‹¡-ÿ³Šÿ§‘þ¥’þ°ú‚¡.ÿÛîÝvüüùþÿÿζQÞ«…ÿ±Žûªÿ¦‘þ2ÓÄÿñÿÿ!Ýßÿhµhÿ!Þâÿéþÿçÿÿãñÿèþÿçþÿéÿÿæûÿìþÿ[¼}ÿ§Gÿßàÿñÿÿ+×Ðÿ¥’þ¤’ÿ¦”ûžþŲKéÿþü üüúýýûôóå:ª›üŸ’ø²Œþ]»zþñÿÿHÇžÿ¡”ÿ…¤7ÿ êÿÿ ëþÿ;϶ÿa¹uÿìþÿèþÿ5ÓÁÿå÷ÿéûÿ#ÜÝÿ«ŽÿŸ•ÿNÄ”ÿïÿÿSÀ‹þ³‹þ¢’ø©—þñðÜ_ýýüýýüáݰ‡§‰ÿ¦<ù&ÜÜÿx¬Rþ­þ°‹ÿzªIÿèÿÿìÿÿw¬OÿŒ ,ÿ éÿÿ êÿÿ{ªHÿCʦÿïÿÿ ëÿÿQÁÿ±‹ÿ®þ}©Hþ%ÜÝÿ{«Jù§ˆÿÝØ£¯ýýûýýûÿÿÿ ÙÏŽºl©Iÿ–šø²þ£”ÿ©þ•›ÿäõÿåøÿ’!ÿ– ÿäõÿæúÿ—šÿ ”ÿDʤÿ êÿÿ ëÿÿu­Qþªÿ¯Žþ›™øl¥@ÿÒÉ€ºÿÿÿ ýýûþþþþþþÿÿÿÝ΋·¦ÿ û¦•û©‘þŸ• ÿàëþäöÿš˜ÿªÿ,×Ðÿ%ÛÜÿ¤“ÿ§ÿ®ÿf¶kþïÿÿ>γþ°ûŸ‘û¥ÿÙÈ}·ÿÿÿþþþþþþÿÿÿå⺇° &ÿ‹ÿ¬Œýr²^ûôÿýHÇ þ¨‘ÿ°ŒþCʧÿ:Ï·ÿ¯Œþ¢”ÿ£“þ°Žý+ÛÙû<̯ý©„ÿ« ÿâݱ‡ÿÿÿþþþøøî;ÒÂr³~°Xÿ$ѵÿJ¾ƒÿŸ’ÿ¤’ÿ¯Œÿ`¹uÿ[¼ÿ±‹ÿ¢“ÿ£ÿ ÿ2Ȩÿ®OÿÔ¾m³÷öë;ýýûñöì@ÒД°Ã§2Û®›ø¥–ÿ¬Žþ…¤7ÿ€§?ÿ¬Žþ¥– ÿ®šø±°GÛ½Ù°°øïØ@ýýûþþýüüùÿÿÿëèÌ€ÑȘŷY뺵Uÿ»´SÿÅ·YëÑȘëèË€ÿÿÿýüùþþýÿþÿÿðÿÿŽqÿþ|>ýпû@ßõ€¯þê_Ü;ðø€Ð €€Ð €øðÜ;ê_þõ€¯û@ßýÐ ¿þz^ÿ€ÿÿú_ÿÿþÿ(0` àèøøøHÀÈÈ€€ 0@ȨÀ°H˜ èàÈèøh°h0ÐÈx¨PàØ `¸x ")îîâ"" ”pPN ïÐðÔ" HÚP`¼„ èÁ ª0Ž $Ш¬rpÚ­Ú£ +Ê¡°ú£º£Ò"xeѪ¦:¦:¬†ˆ ºð ªª0Ê¡¡€¯r"à¬Pjª­ªª¡€ÊÀ"£Zª¬ªªÜª¡ñ¡P "'Úª ªªªªª¦\ª¯r""ªª6ªªªªªª¬ªªÀ€kªªªªªªªªªª¡Pa·" ÑPÚªªªªªªªªªª¯\ªª£.ŠÿÁüªªªªªªªªªªÀƒ¡ø‹B'ªªªª¡ªªªªªªªªªªfª­r˜jªªªªªªªªªªªªªªªªª0à óaªªªªªªªªªªªªªª¬pܪªªªªªªªªªªª¡Èpªªªªªªªªªªª€Óaªªªªªªªªªªªª=€Ý<ªªªªªªªªªªªªªªªªªª¡ÃØÝöÁªªªªªªªªªªªªªªªªªªcЀßaªªªªªªªªªªªª¡ý€pñªªªªªªªªªªªªøpŒªªªªªªªªªªªªª€àʪªªªªªªªªªªªªª3Иªªªªªªªªªªªªªªªªª¬€'Úª¡fªªªªªªªªªªªªªªÀrøƒª8ªªªªªªªªªªÁÿ1¥r"úªªÅºªªªªªªªªªª¯}ÌÀªªªªªªªªªªªPÖ"" ªªjªªªªªªoªªÀ "'ºªÅ:ª¡ªªªªÀ\ª¯r"€ªÍªªÊª­ñ¡P "à¬PªÐ¡Ñª¬jÀ"úð¡Ê¡ªªð r"xeʦ:¦:ª­†‡ /:¯ú¯ ¬Òp:¯Z­Œª€ $Ê¥¨ ª€B•ªð Ž å1Ï`„ M ð þ  ”xP‡I  )äDDN’ ÿùÀÿÿæwÿÿø ÿÿ`ÿþÀý¿ú_ô/àø À À€€À Àø àô/ú_ý¿þÀÿ`ÿÿøÿÿægÿÿûÀßÿ(0`€þþýýýûÿÿÿúúôöõèéäÀàÙ©âÛ¬âÛ¬àÙ¨åß·öôæúùóÿÿÿýþýþþýÿÿÿþþþýýûÿøíæäÁÍÄt»­A­›¢ž©ˆ{¡2{¡3©ˆŸ¡«šº¬@ÊÂrçâ½ÿøðþþýõóäÛÊ€|ÅŽo¯Z¥‰ ¤‘¦“¤”±e¸qZ¾„°¤”¦“¤‘ ¨†¡” œ¯MÂÕ¤ñïÚÿÿÿýýûþþþúùñÐÊ…¶˜j©J äú†¤6­¥”¦“¦“¤’ªŽHÇŸ;䪤’¥“¥“ª‘jµm(ÚÒàê<Äš›¢*ÑÃuø÷íþþýþþþåà·³¤.¡‹¡‘-ÙÓãñ˜™¨‘¤’¥’¥“¥’¨-×Î Þã§‘¥’£“¬Ž[¼~ìÿ ìÿPÃ’¥” £ Œ°Ÿ%âÜ®þþýýýüüüùÐÆz¤‘¡«‘‘ž#àë ìþq¯W°Œ¢”¥“¥’§‘›—áïåùž%¨©Œ ,äô ìý/Õʨ§‘¥“§”¢Ž¢É½eüü÷ýýûýýüÿúòijQžŒ¥“¥”©‘!àë êþ"Ýጠ/°¥’£“¬~¨Cæûèþt®T«¯q°Yíÿ éþMÄ–®¢”¦’¥’¦“¦“Œ¼¬?úòàýýüýýýþøð¬¾o—ޝޤ”¤“¦‘¥’4Ò ìÿèÿâígµh¦‘¥’°Œa¹u êÿ ìÿW¾…¯Œ«Žd·nìþ êÿHÇŸ®¢”¥“¦’¥“£”®™¡³VøòáýýüþýýþþüýüúįE‰˜BÍ®„¤;­¦’¢”«~©Cæöæúçþ ëÿ?Ì­–°ŒIÇ ìþ ëþ?Ì®§‘©MÄ— ëþ êÿ/ÕÊ¥’¥’¥’£”¦’®Œ -?ϵž+¾¦.øùóþýýɽdœ‹²Žc¸o êýX½‚ • ¬Ž¡•®l²a êÿæûåùîÿIÇž£“0ÕÈ êÿéÿ%ÜÝš˜¦’&ÚÛéÿèÿ Þä’ ¨¢”«Ž¢“`¹t éøY½€±ŽžŒÃ¶TþþþþþýýýüÿÿÿÜÕ¡¦“¥“©;ϲñÿ/ÕÇ€§?­Ž¦’¨=ͱ ëÿæûçüçýq¯Wàëèÿæýèü–šx¬L êÿæûèþß玟(¬¬Žˆ£64ÓÁðÿ3ÓÁ§¥’¦”¡Œ×Ïÿÿÿýýûýýüôò⫚¤‘¦“¤“©‘#ßè ìÿçøSÀˆš˜³Š…¤6çûçþæýçþ-×Íçÿçÿçý êþi´f5ÒÀ ëþæù éÿ Þä—¤“Y½€æô ëÿäõ‡£4«Ž£“¥“£’©— ñíÖýýûþþþýýûÿÿþȺ]ŸŒ§”¥’¦’£”®k³b êÿçüíÿ#ÝÚx¬Pª7ѽ ëÿæüçþéÿçþèÿèÿçþáìèÿçþçü ìþEɤ„¤:'ÚÒìÿçý ëÿ]»z®¢”¤“¨‘ª’ ‹¾³MþÿÿýýüþþþüüùþþþåèÌŸ• ¥’¥’¦“¥“¥“¥’©=Ͳ ìÿåø êÿ ëÿQÁEɤìþæûèÿçýçþèÿçþèÿéÿçþèÿçþçý4ÒÁæù ëÿåù ëÿ2ÔŤ’¥’§‘®Žœ—•›¥’ª‹åßµýüû¡ÏžZ³i°Ž£“¤“¤“¥“¤’ªž%äòéÿåûèþ ëÿæûèÿçþèÿèÿèÿèÿèÿçþçýçþèÿèÿçÿ êÿèÿæûèýäó‡£2©«—šEÉ¡$ÜÙ#ÛÝ-ØÑ_²jÁ°GÿýûüýüùëËy³` èö€§?­¬¬¨‘¤“¢”­n±^ éýçýçýçüèÿçÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèþçýçýæüîÿ[¼€²Š¬Ž‰¢5&Û×ìÿ êÿíÿ êÿìÿOŘïèËÿÿÿÚÈ|…#çûå÷FȤb¹sY½‚8л ßåáè)ÙÖZ½*ØÓ éÿçýçþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿæü êþ8Ñ»©’*V¾‡å÷éÿçúæ÷X¾ƒ–›• ]²jÅˉÿÿÿýýû¼±J¥ˆHÊ¥ïÿ êÿ ìÿ ìÿ êÿéÿéÿ êÿ ìÿå÷çþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçýéÿ;ζ@Ì­âîìÿèÿæú éÿk³c±‹¨ª‘ªˆ»«7þþþëçÈ®Ÿ¦Ž›˜<Í´éÿéÿ êÿ ìÿéÿæùçüçüèÿèþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþ êÿíÿéÿæûåøîÿJÅš®£“¤“¥“¤“£ø÷îÚÒ—¦“¤“¨‘¦’|©Ea¹uQÁ<δàæíÿ ëÿçÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçýæûçýçÿíÿ,×Íš˜§‘£“¥’¦“¦“ Œåà·É¾f¥’¦’¤“¥“««­Ž«Ž•›l²`+ØÐçúçýçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþèÿåó9е—š¨‘¢”¤“¥“¥“¥’£ÎÄu¾±H¤“£”¤”§’ª«ªª¦‘’œ#`¹uãñçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿæýçþàè[¼~¡“®ª­Ž«§‘¤“£”¢‘¼®Cµ¢&«²‹¯Œž– ž'y«JW¾„;Ï·#ÝÝäö êÿèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿäõàé#ÝÝ:иW¾…u­PŽŸ)ž– ®²‹ª¸¨2¦ªÌ±&ÜÙ#Ýßâðèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿèÿäó$ÜÜ?Ì®]»zzªI‘%¡•¯Œ²‹ª¸¨3¿²M¤“£”£”§’«­Žª¯Œ¦‘`¹u#ÜÞèþæýèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþçü\¼}•› ©«ª«©‘¦’¤”£”¢‘¼®BȽe¥’¦“¥“¥“¤“¢”¨‘—š8жçøèÿçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçýçý%ÜÜd·pž*§‘®Ž¬Ž¬¦’¤“¦’¢ŽÐÆ{ÚÒ–¦“¥’¦“¥’¤“§‘–.ÖÊíÿçýçüæûçýèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçþ êÿíÿâï5ÓÁJÆ›SÁŒq°W¢” ©¤” Œçâ¼íḛ́Ÿ¢¥“¤“£“¯ŒMÄ•îÿåøæûéÿíÿ êÿçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèþèÿçüçüæùèÿ ëÿ êÿ êÿ êÿ/ÖÆ“"©¥• ùøðþþý¿²J¦‡¬‘©°‹n±]éÿæúçÿìÿâî?Ì®DÉ¥èûçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçÿäô ëÿ ëÿéÿéÿ êÿ ìÿ íÿ êÿïÿ9Ѿ¡¹¬<þþþÑÎZ¶rŒ¢.‘ž$V¿‡æ÷çú éÿæúW¾†‘ž*¬?̰ ëÿæüèþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçþæýéþ%ÛÛ_ºx7Ñ¿ßæ"Ýâ<ϵ[¼c¸qP“áì ìÿ{¡1ÙÂoÿÿÿþÿÿöðÛdÀ„ êÿ ìÿîÿ ëÿìÿ%Ûׄ¤=¬Ž²Še¶nìÿæýçýçýèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿçüçýçü ëÿb¸s¯Œ¢”¥“¨‘¬Ž¬Ž®ž+æîr²aøåÀθWkªR2ÖÉ)ÙÔ)ÙÒIÇ›—š­Ž§‘Œ *ãðèýåúèÿ êÿæüèÿçþèÿçýçþèÿèÿèÿèÿèÿçþèÿæù ëÿèÿæûèþèþ‚¦:­Ž¤“¥“¤“¤“¢“³Œ`±d‘Ï ÿûóûþþüüùþþþîìÓ¯’¨ž—¡”­Ž§‘¤“¨8к ëÿåù ëÿæù9ϸåøçþçþçýéÿèÿçþèÿçþçýèÿæûìþ?̯Z½çû ëÿåù êþ.ÖÌ¢” ¦‘¤“¥“¥“¥’¦’‘ÞåÇüýüþþþýüúÿÿÿǽdŸŒ¨“¦’¤“¢”¯c·n ëÿæüìÿ&ÚÓ‡£;OÓ ìÿçüçþéÿáëçýèÿèÿèÿéÿçþæü êÿ)ØÔ¨†£<-×Ëìÿçÿ ëÿ]»{®£”¦’¥’§”ŸŒÃµSÿþýýýûþþþýýüõòã­œ¢¦“¤“©‘#áí ìÿçöTÁ‰ •§‘'ÚØ êþæù êþ/ÖÊp°Z éÿçýèÿçý-×Îèÿæþæý êÿy«J²‹¡“ [¼€åð ëÿäõ†¤5«Ž£“¦“¤‘©– ñîÙýýûýüûÿÿÿߨ¥¢Ž¥“¥“©;ϳðÿ4ÒÁ…¤9«¬ŽŸ(ßçèþæû ëÿt®Sž– æóèþçÿäöv­Qáìèûæú êþ5ÒÀ¥’¦’­Œ .:ϸîÿ.Öʤ’¦‘¥”¢ŽÙÒ•ÿÿÿýýüËÁl‹°Ž_ºw éù_ºt¢“¬Ž¢”¦‘™˜%ÛÛ éÿèÿà韕 ¢“3ÓÅ êÿéÿ$ÜÝ¡”[¼~ïÿæüåú ëÿ]»{®¡”ª¥‘g¶kèõP¯‹Å¸ZÿÿÿþþýþýýþýüýýûűEƒš!>϶†£7°Œ¦’£”¥’£“«Ž9к ëÿ ëþDɧ§‘­ŽIÆ ëþ ëþ>̰©£“NÕ éÿéÿæú êþu­Q­Ž¢”¥’®ŽŸ)DÌ®&Áª7úúôþýýýýýýùñ«¿q™®£”¥“¦’¦“¢”®PÃ’ êÿ ëþY¾ƒ¨¯Œ`¹v ëÿ ìÿZ½€°‹¤“©w¬N ÞÞ êÿ êþ)ØÕž–§‘¤“£”­‹¥±O÷óãýýüýýüÿúòĵUžŒ¥’¦”¥’¦’¢”­OÃ’ éþíþ_»x¬Ž©€§@æúèþu­R®£“¤“¯”› 'Û× éÿçüŠ¢/¬Ž¤”¥’žŒ¿±KúôåýýüýýüýþüÒȦ“¡Ž§”¥“¦‘­8м ëýèû…¤6¬Ž¥’– áíåùŸ%©¤’¥“¢”¯Œ|©GèüçýŠ¢/­ £ÍÂrüü÷ýýüþþþéäÁ¶§5 Œ¢‘§“ ]½ ìÿìÿZ½ª¤“¤“¨-×Î!Þã§‘¥’¦“¥’¥’§‘›—!ßæ$Þ䜔¢Š²£.äÞ³þþýþþþûúôÙ̉¢¥1@“Þå*ØÎg·q©’¦“¥“¤’«ŽGÇ ?Ì®ª¤’¦“¦“¥”¬‘Œ +ãõd¬T¶˜Ðʆúùñþþþ÷óãÍש µ[£“©ˆ Œ£¥’£“°‹g¶jX¾„¯Œ£“¥’£ŸŒ¥‰{ªH{Ç‘ÜÊ€õóãþþþýýûÿûôêæÆÏȾ°I²¢$©— £’­Žƒ¥:‚¦<­Ž£’©— ²¢$½°HÎÅwèäÃÿùïýýûþþþþýûÿÿÿîêÏáÛ¬×ÎÏÃtÌÅyÍÅxÏÃt×ÎáÛ¬îêÏÿÿÿþýûÿÿý¿ÿÿÿÿÀÿÿÿÿ=¼ÿÿÿøÐ ÿÿçÀçÿÿÝ[ÿÿ¨ÿþÈÿ ¿ÿ@ÿÿ€ô¯þèü?øÐ¨Ð€€€Ð€øÐøü?èþô¯ÿ€ÿ@ÿÿ ¿þÈÿ¨ÿÿÝ»ÿÿçÀçÿÿùèŸÿÿÿÿÿÿÿèÿÿÿÿý¿ÿÿ(0` þþýýýûÿÿÿúúôöõèéäÀÍàÙ©ÿâÛ¬üâÛ¬üàÙ¨ÿåß·Íöôæúùóÿÿÿýþýþþýÿÿÿþþþýýûÿøí<æäÁ—ÍÄtÏ»­Aÿ­›ÿ¢ÿžÿ©ˆÿ{¡2ÿ{¡3ÿ©ˆÿŸÿ¡ÿ«šÿº¬@ÿÊÂrÏçâ½—ÿøð<þþýõóäHÛÊ€²|ÅŽùo¯Zÿ¥‰ÿ ü¤‘ü¦“ü¤”þ±ÿe¸qþZ¾„þ°ÿ¤”þ¦“ü¤‘ü ü¨†ÿ¡” ÿœ¯MúÂÕ¤°ñïÚ[ÿÿÿ!ýýûþþþúùñ4ÐÊ…½¶˜ÿj©Jÿ äúÿ†¤6ú­ü¥”ÿ¦“þ¦“ÿ¤’ÿªŽÿHÇŸÿ;δÿªÿ¤’ÿ¥“ÿ¥“þª‘ÿjµmü(ÚÒúàêÿ<Äšÿ›¢*ÿÑÃuáø÷í3þþýþþþåà·³¤.ÿ¡‹ÿ¡‘ý-ÙÓüãñþ˜™þ¨‘þ¤’ÿ¥’ÿ¥“ÿ¥’ÿ¨ÿ-×Îÿ Þãÿ§‘ÿ¥’ÿ£“ÿ¬Žÿ[¼~ÿìÿþ ìÿþPÃ’þ¥” ü£ú Œÿ°Ÿ%ÿâÜ®þþýýýüüüùOÐÆz椑ÿ¡ý«‘ü‘ž#þàëÿ ìþþq¯Wÿ°Œÿ¢”ÿ¥“ÿ¥’ÿ§‘ÿ›—ÿáïÿåùÿž%ÿ¨ÿ©ÿŒ ,ÿäôÿ ìýÿ/ÕÊÿ¨ÿ§‘þ¥“ÿ§”ý¢Žý¢ÿɽeæüü÷OýýûýýüÿúòTijQüžŒÿ¥“û¥”ÿ©þ‘!ÿàëÿ êþÿ"ÝáÿŒ /ÿ°ÿ¥’ÿ£“ÿ¬ÿ~¨Cÿæûÿèþÿt®Tÿ«ÿ¯ÿq°Yÿíÿÿ éþÿMÄ–ÿ®ÿ¢”ÿ¦’ÿ¥’þ¦“ÿ¦“ûŒÿ¼¬?üúòàTýýüýýýþøðQ¬¾oÿ—Žý¯Žü¤”ÿ¤“ÿ¦‘þ¥’ÿ4ÒÂÿ ìÿÿèÿÿâíÿgµhÿ¦‘ÿ¥’ÿ°Œÿa¹uÿ êÿÿ ìÿÿW¾…ÿ¯Œÿ«Žÿd·nÿìþÿ êÿÿHÇŸÿ®ÿ¢”ÿ¥“ÿ¦’þ¥“ÿ£”ÿ®ü™ý¡³VÿøòáQýýüþýýþþüýüúZįEþ‰˜ûBÍ®ü„¤;ÿ­þ¦’ÿ¢”ÿ«ÿ~©Cÿæöÿæúÿçþÿ ëÿÿ?Ì­ÿ–ÿ°ŒÿIÇÿ ìþÿ ëþÿ?Ì®ÿ§‘ÿ©ÿMÄ—ÿ ëþÿ êÿÿ/ÕÊÿ¥’ÿ¥’ÿ¥’ÿ£”ÿ¦’ÿ®þŒ -ÿ?ϵüž+û¾¦.ÿøùóWþýýɽd蜋þ²Žüc¸oÿ êýþX½‚ÿ • ÿ¬Žÿ¡•ÿ®ÿl²aÿ êÿÿæûÿåùÿîÿÿIÇžÿ£“ÿ0ÕÈÿ êÿÿéÿÿ%ÜÝÿš˜ÿ¦’ÿ&ÚÛÿéÿÿèÿÿ Þäÿ’ ÿ¨ÿ¢”ÿ«Žÿ¢“ÿ`¹tÿ éøþY½€ÿ±ŽþžŒûöTþþþþEþþýýýüÿÿÿÜÕ¯¡ú¦“û¥“þ©þ;ϲÿñÿÿ/ÕÇÿ€§?ÿ­Žÿ¦’ÿ¨ÿ=ͱÿ ëÿÿæûÿçüÿçýÿq¯Wÿàëÿèÿÿæýÿèüÿ–šÿx¬Lÿ êÿÿæûÿèþÿßçÿŽŸ(ÿ¬ÿ¬Žÿˆ£6ÿ4ÓÁÿðÿÿ3ÓÁÿ§þ¥’ÿ¦”û¡Œþ×Ϻÿÿÿýýûýýüôòâ8«šÿ¤‘ý¦“ÿ¤“ÿ©ÿ‘#ÿßèÿ ìÿÿçøÿSÀˆÿš˜ÿ³Šÿ…¤6ÿçûÿçþÿæýÿçþÿ-×Íÿçÿÿçÿÿçýÿ êþÿi´fÿ5ÒÀÿ ëþÿæùÿ éÿÿ Þäÿ—ÿ¤“ÿY½€ÿæôÿ ëÿÿäõÿ‡£4ÿ«Žÿ£“þ¥“ÿ£’ú©— ÿñíÖ—ýýûþþþýýûÿÿþ&Ⱥ]럌ù§”ý¥’þ¦’ÿ£”ÿ®ÿk³bÿ êÿÿçüÿíÿÿ#ÝÚÿx¬Pÿªÿ7ѽÿ ëÿÿæüÿçþÿéÿÿçþÿèÿÿèÿÿçþÿáìÿèÿÿçþÿçüÿ ìþÿEɤÿ„¤:ÿ'ÚÒÿìÿÿçýÿ ëÿÿ]»zÿ®ÿ¢”ÿ¤“ÿ¨‘þª’ý ‹ù¾³Méþÿÿ&ýýüþþþüüùþþþåèÌ’Ÿ• ÿ¥’û¥’ÿ¦“ÿ¥“ÿ¥“ÿ¥’ÿ©ÿ=Ͳÿ ìÿÿåøÿ êÿÿ ëÿÿQÁÿEɤÿìþÿæûÿèÿÿçýÿçþÿèÿÿçþÿèÿÿéÿÿçþÿèÿÿçþÿçýÿ4ÒÁÿæùÿ ëÿÿåùÿ ëÿÿ2ÔÅÿ¤’ÿ¥’ÿ§‘ÿ®Žÿœ—ÿ•›ÿ¥’ûª‹ÿåßµ‘ýüû¡ÏžôZ³iþ°Žþ£“þ¤“ÿ¤“ÿ¥“ÿ¤’ÿªÿž%ÿäòÿéÿÿåûÿèþÿ ëÿÿæûÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçýÿçþÿèÿÿèÿÿçÿÿ êÿÿèÿÿæûÿèýÿäóÿ‡£2ÿ©ÿ«ÿ—šÿEÉ¡ÿ$ÜÙÿ#ÛÝþ-ØÑþ_²jüÁ°GùÿýûüýüùëËNy³`ó èöû€§?þ­ÿ¬ÿ¬ÿ¨‘ÿ¤“ÿ¢”ÿ­ÿn±^ÿ éýÿçýÿçýÿçüÿèÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèþÿçýÿçýÿæüÿîÿÿ[¼€ÿ²Šÿ¬Žÿ‰¢5ÿ&Û×ÿìÿÿ êÿÿíÿÿ êÿþìÿùOŘüïèËÿÿÿÚÈ|Ä…#ÿçûûå÷ÿFȤÿb¹sÿY½‚ÿ8лÿ ßåÿáèÿ)ÙÖÿZ½ÿ*ØÓÿ éÿÿçýÿçþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿæüÿ êþÿ8Ñ»ÿ©ÿ’*ÿV¾‡ÿå÷ÿéÿÿçúÿæ÷ÿX¾ƒÿ–›þ• û]²jýÅˉ´ÿÿÿýýûi¼±Jÿ¥ˆþHÊ¥ÿïÿþ êÿÿ ìÿÿ ìÿÿ êÿÿéÿÿéÿÿ êÿÿ ìÿÿå÷ÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçýÿéÿÿ;ζÿ@Ì­ÿâîÿìÿÿèÿÿæúÿ éÿÿk³cÿ±‹ÿ¨ÿª‘ÿªˆû»«7ÿþþþëçÈU®Ÿý¦Žÿ›˜þ<Í´ÿéÿÿéÿÿ êÿÿ ìÿÿéÿÿæùÿçüÿçüÿèÿÿèþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿ êÿÿíÿÿéÿÿæûÿåøÿîÿÿJÅšÿ®ÿ£“ÿ¤“ÿ¥“þ¤“ü£ýø÷îÚÒ—Š¦“ÿ¤“ÿ¨‘ÿ¦’ÿ|©Eÿa¹uÿQÁÿ<δÿàæÿíÿÿ ëÿÿçÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçýÿæûÿçýÿçÿÿíÿÿ,×Íÿš˜ÿ§‘ÿ£“ÿ¥’ÿ¦“ÿ¦“þ Œÿåà·àɾfÿ¥’ÿ¦’ÿ¤“ÿ¥“ÿ«ÿ«ÿ­Žÿ«Žÿ•›ÿl²`ÿ+ØÐÿçúÿçýÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿèÿÿåóÿ9еÿ—šÿ¨‘ÿ¢”ÿ¤“ÿ¥“ÿ¥“ÿ¥’ÿ£ÿÎÄuÿ¾±Hü¤“ÿ£”ÿ¤”ÿ§’ÿªÿ«ÿªÿªÿ¦‘ÿ’œ#ÿ`¹uÿãñÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿæýÿçþÿàèÿ[¼~ÿ¡“ÿ®ÿªÿ­Žÿ«ÿ§‘ÿ¤“ÿ£”þ¢‘ÿ¼®Cýµ¢&ÿ«ÿ²‹ÿ¯Œÿž– ÿž'ÿy«JÿW¾„ÿ;Ï·ÿ#ÝÝÿäöÿ êÿÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿäõÿàéÿ#ÝÝÿ:иÿW¾…ÿu­PÿŽŸ)ÿž– ÿ®ÿ²‹ÿªÿ¸¨2ÿ¦ª<ÿz«JÿTÀ‹ÿ8кÿ&ÚÚÿä÷ÿ ìÿÿ êÿÿ ëÿÿ êÿÿèÿÿçüÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿéÿÿêÿÿ ëÿÿ êÿÿ ìÿÿæûÿ&ÛÙÿ5Ò¾ÿQ‘ÿv¬Nÿœ›ÿ¨¨7ÿ|ªFÿX¾„ÿ=ͱÿ+ØÒÿãóÿ ëÿÿ ëÿÿ êÿÿ êÿÿêÿÿéÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿèÿÿ êÿÿ êÿÿ ëÿÿ ëÿÿãóÿ+ØÑÿ9ϸÿU¿‰ÿ{ªGÿ ™ÿ¶£)ÿ«ÿ±Œÿ±‹ÿ¡”ÿž%ÿ~¨Bÿa¹sÿ>̱ÿ&ÜÙÿ#Ýßÿâðÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿèÿÿäóÿ$ÜÜÿ?Ì®ÿ]»zÿzªIÿ‘%ÿ¡•ÿ¯Œÿ²‹ÿªÿ¸¨3ÿ¿²Mü¤“ÿ£”ÿ£”ÿ§’ÿ«ÿ­Žÿªÿ¯Œÿ¦‘ÿ`¹uÿ#ÜÞÿèþÿæýÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿçüÿ\¼}ÿ•› ÿ©ÿ«ÿªÿ«ÿ©‘ÿ¦’ÿ¤”ÿ£”þ¢‘ÿ¼®BýȽeÿ¥’ÿ¦“ÿ¥“ÿ¥“ÿ¤“ÿ¢”ÿ¨‘ÿ—šÿ8жÿçøÿèÿÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçýÿçýÿ%ÜÜÿd·pÿž*ÿ§‘ÿ®Žÿ¬Žÿ¬ÿ¦’ÿ¤“ÿ¦’ÿ¢ŽÿÐÆ{ÿÚÒ–ˆ¦“ý¥’ÿ¦“þ¥’ÿ¤“ÿ§‘ÿ–ÿ.ÖÊÿíÿÿçýÿçüÿæûÿçýÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿ êÿÿíÿÿâïÿ5ÓÁÿJÆ›ÿSÁŒÿq°Wÿ¢” ÿ©ÿ¤”þ Œÿçâ¼àíéÌ]°Ÿÿ¢ÿ¥“ÿ¤“ÿ£“ÿ¯ŒÿMÄ•ÿîÿÿåøÿæûÿéÿÿíÿÿ êÿÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèþÿèÿÿçüÿçüÿæùÿèÿÿ ëÿÿ êÿÿ êÿÿ êÿÿ/ÖÆÿ“"þ©ü¥• ýùøðþþýG¿²Jߦ‡þ¬‘ý©þ°‹ÿn±]ÿéÿÿæúÿçÿÿìÿÿâîÿ?Ì®ÿDÉ¥ÿèûÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçÿÿäôÿ ëÿÿ ëÿÿéÿÿéÿÿ êÿÿ ìÿÿ íÿÿ êÿÿïÿÿ9Ѿÿ¡û¹¬<ÿþþþÑΜZ¶rÿŒ¢.ù‘ž$ÿV¿‡ÿæ÷ÿçúÿ éÿÿæúÿW¾†ÿ‘ž*ÿ¬ÿ?̰ÿ ëÿÿæüÿèþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿæýÿéþÿ%ÛÛÿ_ºxÿ7Ñ¿ÿßæÿ"Ýâÿ<ϵÿ[¼ÿc¸qÿP“ÿáìþ ìÿû{¡1ýÙÂo´ÿÿÿþÿÿöðÛWdÀ„ó êÿü ìÿþîÿÿ ëÿÿìÿÿ%Û×ÿ„¤=ÿ¬Žÿ²Šÿe¶nÿìÿÿæýÿçýÿçýÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçÿÿèÿÿçüÿçýÿçüÿ ëÿÿb¸sÿ¯Œÿ¢”ÿ¥“ÿ¨‘ÿ¬Žÿ¬Žÿ®ÿž+þæîùr²aüøåÀθWôkªRþ2ÖÉþ)ÙÔþ)ÙÒÿIÇ›ÿ—šÿ­Žÿ§‘ÿŒ *ÿãðÿèýÿåúÿèÿÿ êÿÿæüÿèÿÿçþÿèÿÿçýÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿæùÿ ëÿÿèÿÿæûÿèþÿèþÿ‚¦:ÿ­Žÿ¤“ÿ¥“ÿ¤“ÿ¤“ÿ¢“þ³Œþ`±dü‘Ï ùÿûóûþþüüùþþþîìÓ’¯’ÿ¨ûž—ÿ¡”ÿ­Žÿ§‘ÿ¤“ÿ¨ÿ8кÿ ëÿÿåùÿ ëÿÿæùÿ9ϸÿåøÿçþÿçþÿçýÿéÿÿèÿÿçþÿèÿÿçþÿçýÿèÿÿæûÿìþÿ?̯ÿZ½ÿçûÿ ëÿÿåùÿ êþÿ.ÖÌÿ¢” ÿ¦‘ÿ¤“ÿ¥“ÿ¥“ÿ¥’ÿ¦’û‘ÿÞåÇ‘üýüþþþýüúÿÿÿ&ǽd럌ù¨“ý¦’þ¤“ÿ¢”ÿ¯ÿc·nÿ ëÿÿæüÿìÿÿ&ÚÓÿ‡£;ÿOÓÿ ìÿÿçüÿçþÿéÿÿáëÿçýÿèÿÿèÿÿèÿÿéÿÿçþÿæüÿ êÿÿ)ØÔÿ¨ÿ†£<ÿ-×Ëÿìÿÿçÿÿ ëÿÿ]»{ÿ®ÿ£”ÿ¦’ÿ¥’þ§”ýŸŒùõSéÿþý&ýýûþþþýýüõòã8­œÿ¢ý¦“ÿ¤“ÿ©ÿ‘#ÿáíÿ ìÿÿçöÿTÁ‰ÿ •ÿ§‘ÿ'ÚØÿ êþÿæùÿ êþÿ/ÖÊÿp°Zÿ éÿÿçýÿèÿÿçýÿ-×Îÿèÿÿæþÿæýÿ êÿÿy«Jÿ²‹ÿ¡“ ÿ[¼€ÿåðÿ ëÿÿäõÿ†¤5ÿ«Žÿ£“þ¦“ÿ¤‘ú©– ÿñîÙ—ýýûýüûÿÿÿߨ¥¯¢Žú¥“û¥“þ©þ;ϳÿðÿÿ4ÒÁÿ…¤9ÿ«ÿ¬ŽÿŸ(ÿßçÿèþÿæûÿ ëÿÿt®Sÿž– ÿæóÿèþÿçÿÿäöÿv­Qÿáìÿèûÿæúÿ êþÿ5ÒÀÿ¥’ÿ¦’ÿ­ÿŒ .ÿ:ϸÿîÿÿ.ÖÊÿ¤’þ¦‘ÿ¥”û¢ŽþÙÒ•ºÿÿÿýýüËÁlè‹þ°Žü_ºwÿ éùþ_ºtÿ¢“ÿ¬Žÿ¢”ÿ¦‘ÿ™˜ÿ%ÛÛÿ éÿÿèÿÿàéÿŸ• ÿ¢“ÿ3ÓÅÿ êÿÿéÿÿ$ÜÝÿ¡”ÿ[¼~ÿïÿÿæüÿåúÿ ëÿÿ]»{ÿ®ÿ¡”ÿªÿ¥‘ÿg¶kÿèõþPÂÿ¯þ‹ûŸZþÿÿÿEþþýþýýþýüýýûZűEþƒš!û>϶ü†£7ÿ°Œþ¦’ÿ£”ÿ¥’ÿ£“ÿ«Žÿ9кÿ ëÿÿ ëþÿDɧÿ§‘ÿ­ŽÿIÆÿ ëþÿ ëþÿ>̰ÿ©ÿ£“ÿNÕÿ éÿÿéÿÿæúÿ êþÿu­Qÿ­Žÿ¢”ÿ¥’ÿ®þŽŸ)ÿDÌ®ü&ûÁª7ÿúúôWþýýýýýýùñQ«¿qÿ™ý®ü£”ÿ¥“ÿ¦’þ¦“ÿ¢”ÿ®ÿPÃ’ÿ êÿÿ ëþÿY¾ƒÿ¨ÿ¯Œÿ`¹vÿ ëÿÿ ìÿÿZ½€ÿ°‹ÿ¤“ÿ©ÿw¬Nÿ ÞÞÿ êÿÿ êþÿ)ØÕÿž–ÿ§‘þ¤“ÿ£”ÿ­ü‹ý¥±Oÿ÷óãQýýüýýüÿúòTĵUüžŒÿ¥’û¦”ÿ¥’þ¦’ÿ¢”ÿ­ÿOÃ’ÿ éþÿíþÿ_»xÿ¬Žÿ©ÿ€§@ÿæúÿèþÿu­Rÿ®ÿ£“ÿ¤“ÿ¯ÿ”› ÿ'Û×ÿ éÿÿçüÿŠ¢/ÿ¬Žþ¤”ÿ¥’ûžŒÿ¿±KüúôåTýýüýýüýþüOÒÈ榓ÿ¡Žý§”ü¥“þ¦‘ÿ­þ8мÿ ëýÿèûÿ…¤6ÿ¬Žÿ¥’ÿ– ÿáíÿåùÿŸ%ÿ©ÿ¤’ÿ¥“ÿ¢”ÿ¯Œÿ|©GÿèüþçýÿŠ¢/þ­ü ý£ÿÍÂræüü÷OýýüþþþéäÁ¶§5ÿ Œÿ¢‘ý§“ ü]½þ ìÿþìÿþZ½ÿªÿ¤“ÿ¤“ÿ¨ÿ-×Îÿ!Þãÿ§‘ÿ¥’ÿ¦“ÿ¥’ÿ¥’ÿ§‘þ›—þ!ßæþ$Þäüœ”ý¢Šÿ²£.ÿäÞ³þþýþþþûúô4Ù̉½¢¥1ÿ@“ÿÞåþ*ØÎúg·qú©’þ¦“ÿ¥“þ¤’ÿ«ŽÿGÇ ÿ?Ì®ÿªÿ¤’ÿ¦“þ¦“ÿ¥”þ¬‘úŒ +úãõþd¬Tÿ¶˜ÿÐʆ½úùñ4þþþ÷óãHÍש² µ[ú£“ÿ©ˆÿ Œÿ£ÿ¥’ÿ£“ÿ°‹ÿg¶jÿX¾„ÿ¯Œÿ£“ÿ¥’ÿ£ÿŸŒÿ¥‰ÿ{ªHÿ{Ç‘úÜÊ€²õóãHþþþýýûÿûô;êæÆ›ÏȘ¾°Iñ²¢$ÿ©— þ£’ÿ­Žÿƒ¥:ÿ‚¦<ÿ­Žÿ£’ÿ©— þ²¢$ÿ½°HñÎÅw˜èäÛÿùï;ýýûþþþþýûÿÿÿOîêÏdáÛ¬a×ÎÝÏÃtÿÌÅyýÍÅxýÏÃtÿ×ÎÝáÛ¬aîêÏdÿÿÿOþýûÿÿý¿ÿÿÿÿÀÿÿÿÿ=¼ÿÿÿøÐ ÿÿçÀçÿÿÝ[ÿÿ¨ÿþÈÿ ¿ÿ@ÿÿ€ô¯þèü?øÐ¨Ð€€€Ð€øÐøü?èþô¯ÿ€ÿ@ÿÿ ¿þÈÿ¨ÿÿÝ»ÿÿçÀçÿÿùèŸÿÿÿÿÿÿÿèÿÿÿÿý¿ÿÿ(@€  èøøøøHÀØÐ€ 8@ȨÀ°H˜˜ààèàÀh°X0ÐÀ`¸xˆ¨@èø ""ªªªJ""   *G€Pt¢ " Fà Ðt G3`ŽÔ" "H ˜\Ÿ›„"®‰þ‰ø ñ€„ $ßQÈB pÑ€±1ñ°  ¨Ññ01ÁÿP„ *€¿ÿ€ÁùÁÿPB¨8 ñÿñ€‘ñ°ƒ„" *€¹°‘ÿñ0ñ°‘ñ0 ¢" (€ïÿÿ ñ0 ñ`aÀ‚""p‘ÿÿ†ñÀŒñ`¹€ ¿È‘ÿñÙñ±ÿñ`†B (ØÑÿñŸÿñ›Áÿñ0 ‘ñÈ "p‘ÿàYÿÿÿùÿñ¸ÁP"  ±ÿñóŒÿÿÿÿñÿÿ9ÿ@ "-€ÿñÉÿÿÿÿÿÿÿÿñÿñÀ‹Û€r ­0‘ÿÿÿÿÿÿÿÿÿÿÿÿÿù€ñó„""s±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿaÿñd 5ˆífmSÿÿÿÿÿÿÿÿÿÿÿÿñÀ¼ñó»Í *‘™‘œñÿÿÿÿÿÿÿÿÿÿÿÿP¼ñÿP€B$1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿñ•r'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ°€ ¶É‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@ˆ‹9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñh@Ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó€p‹ŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöPp[6Ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœcµ€p³l‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÌ;Pî<™ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™Ã¸îÖ™ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ™ÍèP³l‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÆ;€p[ÓÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœmµ€@iÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ@oñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“€@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöµˆ€ aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ™Í' ÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ€$‰ÿüÁÿÿÿÿÿÿÿÿÿÿÿÿÿñÿÿñr*ˆÁÿË‘ÿÿÿÿÿÿÿÿÿÿÿÿÿÉñ™‘°B ÜÛoñ›ÿÿÿÿÿÿÿÿÿÿÿÿñhÓcÞˆ‘0 "Cÿ€±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿQ7 ¨Ù0‘ÿÿÿÿÿÿÿÿÿÿÿñÿÿÿPd""'îèÿŸÿÿÿÿÿÿÿñœÿñÀb €±ÿñÁÿÿÿÿÿÿñÈÙÿ@ "p‘ÿUÿñŸÿÿñÿÿûaP" (Ð ÿ¹ÿùÿ ‘ñÈ¿hÿ ñÿùPƒñB "p‘›ñÈñÈÁÿñ`¼P '€ñ0 ñ0±ÿÿ1À‚""€Ù° ÿ°ñ° ñÿÿàâ"¥Øÿ€ÿñ€ìñ˜‹„" *€Ÿ€Áù1ÿýB¨ÿ€1 Š p±a  $ õQ¿B §a°‰øéõê "H¼ùÎ ÈÑ0„"Mè`3t Dà 0d  *GàPt¢   "*¤DDJ¢" ÿÿægÿÿÿÿ˜ÿÿÿÿ`ÿÿÿû€Ÿÿÿô/ÿÿøÿÿ ÿÿ ÿþÀý¿úøôðèÐ € @€€@ €Ð èðôøúý¿þÀÿ ÿÿ ÿÿøÿÿô/ÿÿû€ßÿÿÿ`ÿÿÿÿ˜ÿÿÿÿççÿÿ(@€2þþýýýûÿÿÿÿÿÿþþþüû÷üûöðìÔåà·æá¹æá¹æáºæá¹äßµëæÇûûöûû÷þþýÿÿÿÿÿÿýýúþþýþþþýüúÿýû÷ðÜæã½ÓË„Á´O¯Ÿ¥’¢Ž¡«Š~£7¢5«Š¡¢Ž£®œ¾°HÒʃæâ»óðÞþÿÿüüúþþýÿÿÿþþýüùòêס°Ë¥¬B¤‹Ÿ‹¢¤‘¥’¥“¢”´Š_ºxY¾„±‹£”¥“¦“¤‘£ ‹Ÿ‹±¡%μcæÕ›ýóâþþþúùóÕË…¹©6QÄ•6Ã™š“ ¨“¥”¦“¦“¦“¤’¤“¬MÄ–=Ͳ§‘¦’¤’¦“¦“¦“¦”«’¥Ž€™xªI”½rÉÌŒõðÜÿÿÿýýýþþþþþýÿÿÿýýúØÑ’°£&ªŒS¹wíÿZÀ‰²Œ¡”¥’¦“¦“¥“¥“§‘ž– 6Ò¾(ÚØ˜š©¤“¦“¥“¤“«€§@1ÕÉãîæûÚÚf²`«ÓʃüûøÿÿÿþþýÿÿÿêæÅ¶¨4¢¤”›ãóæù{ªI«£“¦“¦“¦“¦“¤“«‘"!ÝâæùŸ)¬Ž£’¥“¤“«q¯Yçü êÿ ìÿ3ÓÂ’ž&£“¡¢³£)åßµÿÿÿþþþÿÿÿúùñÐÇ|¦“¢£”®Žd·oæü éþ^ºz±‹¡”¥’¥“¦“¥“£’­‡£4èüíÿ{ªH¬Ž¤“¤’¨‘ž#äøèþéý.ÖËš—¬¥’¦“¦“££ÌÁnöôæÿÿÿþþþýýýòïÚ¿±I Œ¥‘¦“¢“¯ŒX½„èÿ ëÿ0ÕÉœ—§£”¥“¦’¤“¤“ªl²aìÿ êþY½ƒ§‘¥’£“®NÄ–éÿåøíÿm²a®£”¥’¥“¥’¦“¦“Ÿ‹µ¥3ðìÒýýüþþþðëϰ¡#¡¦”¦“¥’¢”¯ŒX½„èþæû êýLÅ–¦‘©¤“¥“¥’¥’¥’MÄ— éþ éÿ?Ì®¢“¦‘¢”±‹/ÖÊ ëþæûäõ€¦?­£“¦“¦“¦“¥’¦“§• Œ«›äÝ®þþþþþþÿÿÿìëѬ "§‹¤•¥“¦’¥“£“«v­Qåøèüçüèý:Ð¶ŽŸ&ª¦’£“§‘ • ,×Ðéÿçþßè–§‘£“¨+ØÐ êþæýãó¦>¬Ž¤“¦“¦“¦“¥“¦’¥“¤– ¦Œ¨– ÞÝ®ÿÿÿþþþþþþÿÿÿïê̦¡+W¹x”#®¦’¤“¦’¥’¥’¤“,×Î ëÿæýçÿ êÿáìf¶k£’¨¦‘™™åúçþæý éÿŸ%§‘¦‘”œ$ÜÞ êþä÷íÿs®V¯‹¢“¥“¦“¥“¦’¤“¤“®ššW»}™›!ãÛ©ÿÿÿýüûþþþýýúÿÿÿñî×®œ §Œp²_ Ýãm²b¤’ª¤“¥“¥“¨…¤6áèéÿçýçýèÿ ëÿNÕ¡” ©¦< éÿæýçþèþn±^¦‘©€§?áîéÿå÷íþW¾„¨¥’¤“¥“¦’£“ª¨v¬R"ÜÝ[¾‚§Œ©—éåÃÿÿÿýýüþþþýýüöôæ´¥+ ¨“«Aˬïÿ>̯Œ ,¬Ž¥’¥“¤“®x«Lçûçýçþçýæøìÿ`ºt®^ºyéþçþçþéÿMÄ—¤“²Š[¼ êþæüæú êÿ>̰ž– §‘¤“¥“¥“«Ž“œ GÈ¡ìÿ5Ò½¦‘¨“¢°žòïÛþþþýýýþýüþýûŹ\ §•£’©‘"#ÜÚíÿßçe¶m¤’ª¤“£“«ŽSÁíÿåùèÿæüçûäôž$FÈ¢ êÿçþçþ êÿ0ÕÈ«š—2ÔÆ ëÿåúåû êÿ;ε— ¦‘£“©ªm±`ßäìÿâê‹¡-«£“¦” ½¯Düû÷ýýýýýýÜÕ ¦“¥’¥’£“­l²`çùéÿ éÿ7й‹¡,«¦’§‘‘"%ÜÚ êþæûèÿåùîÿgµj#Ýß éÿæýçþèÿâð£’k³b ëÿåúçþæû êþ;δ›˜©¬Žž%@˪éÿèÿ êûc·o¯Œ£“¥’¥’¦“ ×ÏŽÿÿÿþþýþþýõô嬛£¦“¥’¦“¥’¥“¨FȤ êþæú ëÿáì_¹wœ—«¬ŽZ½ ëþæúçþçýèþ%ÜÜåøèÿçþæýéÿâîj²b/ÕÉ êþæûèÿåùíýHÇŸ©¢” j´eàè ìÿåú êÿ5ÒÁž•¦‘¤“¦“¦“¦“£¨– ðíÖýýüþþþýýüÿÿÿÆ»a¢Ž¥’¥“¦“¥“¦“¤“©•š!Ýã éÿæûèÿíÿ2ÔÃzªIµˆ¦=àíéÿæýèÿçÿéÿèÿçÿèÿçþèÿåø ßå êÿæþçþçýæûìÿv¬OŽž-6Ѻíÿéÿæûèþá2­£“¥“¥“¥“¥“¥“¡Ž¿±Jÿÿÿýýüþþþýýúé⺫— £‘¦“¦“¦“¦“¥“¥’£“¬Žr¯Wéÿçýçþåù ëÿåóT¿Œ—™0ÕÉ ëþæüçþèÿçýçþèÿçþèÿçÿèÿéÿçýèÿèÿæû êÿ1ÕÉRÁàäíÿæúçýçý êÿ]ºz¬Ž£“¥“¦’©ªªª¨§“ßÚ«ýüùþþýüýüÿýû¥Çˆ„𦔥’¥“¥“¦“¦“¦“¦’¥’§‘Cʧ ëÿæüçÿæúèÿ ìÿ5ÒÀ#Üà êÿçýèÿèÿèÿèÿèÿèÿçþèÿçþçýçþçþçþçþèþäôçÿêÿæúçþæý êÿ6Ѿ£“¥’£”§‘¦’”œq¯Xh´it®S‘ 'Ÿ¿­>úûùþþýüû÷ùâ·cÄGÄž«¤“£“¥“¥“¤“£”¢”¡•¥’ž"áëèýæüèÿçýçþêÿèÿçÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿèÿçýèÿæüèüâï‹ )ª¡•« ” RÂçþ êÿéÿèÿäöMÜ›éÜ­þÿÿüüúüüùüÿÿß¿cF»ïÿo°Z²Šª¨‘¨‘¬±Œ´Š´Š³Š·ˆr¯W ëÿæûçþèÿçþçþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçþçþçþåûìÿa¹s©¢”¯Œ™™;϶ ëÿçþæüèÿìÿïÿøÿ)˰ÀÃxÿûõñöêÁŸY¸w ìýå÷RÀŒ¦<“œ”›zªJ]»{FȤEÊ¥Dʧ[¼„‰¢2HÇ¡ìÿæûçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿåúìÿ4Óá• ®¨‘o°`'ÚÔ ëÿæûæû êÿäõQÂs®Wq°Y2ÓÂlÀƒ÷êÍÿÿÿäâ»¤Š‡¤9àìéþ êÿâî!Þã!Þããóéÿîÿîÿîÿ êÿàå.ÖÌãîèþæýèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçýéýáè¦>¡”h´g5ÒÀæû êÿæûåû ëÿ'ÚÕ…¤8§°‹°Œž˜’ãÛ¬ÿÿÿþþýÐÇ{Œ¯QÁìÿæúçÿéÿêÿèÿçþæûæûæûçý êÿéÿçýèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþéÿàë0ÕÇäõèÿ êÿèÿçüæýèýßæ‰¢3®¥“£”£”©’¤‹Ç¼cþþý÷õ麫<¢¦’ž•Cɧ êÿìÿ êÿéÿèÿæùçüçþèÿçþçýçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿéÿèÿèÿçýçþçþæüèÿk³b®£“¥“¦’¥“¥“¤‘¬šòïܪ˜¥’¥“§‘¥‘n±_@˪3ÓÃ"Ýáãòîÿ ëÿèÿçþçþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçþçþèÿçþçþæüíÿAʬ§‘¤“¥’¥“¦“¦“¦“¦“ ôòááÛ¬¥‘¦“¦’¤“¥’¯Œ¢”™™ž&Œ -w¬NKÅ™ãò ëÿ éÿèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþèÿèÿîÿ<β›˜¦‘¤“¦“¦“¦“¦“¦“¥’¤ߨ¤ÓÊ‚¦“¥’¥“¦’¥“£”¦’¨‘©‘ª©¢”™˜_¹uÞäæûèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿæúäïGÇžš˜¦’£”¥“¦’¥“¦“¦“¦“¦“¤ÐÆyɼe¦“¥“¦’¥“¤“£”¢•£”¨‘«±Œ¯¢”—šj²cáíçþçýèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþäõ:϶€§@±‹²‹¬©¥“¢•¤”¤“¥“¦’¥“¥‘¾±G¼®B¥“¥“¤“¥“ª­Ž´Š¬Ž“œ€§?n±`W¾‚>Ͱ$ÜÝçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿáí-×Î>̯TÁˆk³b§>‘!©µŠ­Žª¦’¤”¤“¤’»­A¸§2©‘«¯¦’‡£4o±]SÁŽ<α*ØÒâî ëÿðÿ ìÿéÿçþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþéÿ ëÿ ìÿïÿ ëÿâî)ÙÔ:жOÕl²`†£4 ”°Œ«¨µ¥+¬¯Ix«KV¾†3ÓÃ!Þâãòæû ëÿ ìÿêÿèÿæûæùæûçüçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçýæûæùæûèÿéÿ ìÿ ìÿçýâñàç/ÕËSÁŒu¬Q–›®®F}©DY¾‚;ε$ÜÝáíåù êÿ ìÿ ëÿéÿçüåùæûçüçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçüæûåùçüéÿ êÿ ìÿ êÿåøáì Ýã5ѾY½|©E—·§1©‘«®ªŽŸ's¯VU¿‰AË«1ÔÆÞå êÿðÿíÿ ìÿéÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþèÿêÿ ìÿðÿ êÿÞå-×Î?̯V¿‰s¯VŸ(¥’¯«¨µ¥,¿±J¥“¥“¤“¥“©‘­Ž³‹®–†¤5r¯ZY½IÆ:и ßäèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿãò(ÚÕ@ˬZ½}q°Z…¤5˜š¬Ž³Š­Ž©‘¥“¤“¥“¤’»­Aʾi¦“¥“¦’¥“¤“¤”¢”£”§’ª²‹µˆ§@?Ì­ãðçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþæýçþ^ºxš˜¤“²‹°Œª§’£”¡•£”¤“¥“¦’¥“¥‘¾±GÓɦ“¥’¦“¦“¦“¥“¦’¥“£“¦’š˜GÈ åòçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþæþáêQÁ“œŸ• ¦‘«ªª¨‘£”¤“¦’¥“¥’¤‘ÑÇ|áÛ¬¥’¦“¦“¦“¦“¦“¦“¤“¦’— <βîÿçÿèÿçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿéÿ ëÿæü@ˬk³b…¤7Œ *Ÿ%›˜®Ž¨‘¤“¦’¦“¢ãݰòïÛ©— ¥’¦“¦“¦“¥“¥’¤“ªFÈ£íÿæüçþçþèÿçþçþçþèÿçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþçþçþçþçþèÿ êÿîÿèÿáì"Ýá5Ò¾_ºw–©¥“¥’£ôñà÷÷콯D¢¥“¥“¦“¥“£“­n±] éÿæüçþçþçýèÿèÿêÿéÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçýçþçþçþçüæúçüèÿèÿ êÿíÿ4Ó”›¨‘£²¡"þþþÐÉ€¢‰ª‘¤“£”¥’­Žž* Þäèýæýçüèÿ êÿèÿå÷8к(ÚÖéÿçþçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçýéÿ ëÿèÿçüæûæûèÿéÿêÿêÿèÿæùíÿ?̯ªŸŽÈ½eþþýÿÿÿìâ»”–®®Œ¤’…¤7'ÙÔ êÿæûæú éÿæû5ÒÀi´f • ‡£3 Þáéþæüçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèýäð0ÔÇ#Üàèþ ëÿîÿíÿèÿãð!Þã"Þâàçèÿéÿä÷u¯X§†ßݲþþþÿîӃŋ+ÒÄf¸lp°ZGÈ ãó êÿæüæû ëÿ"ÝÜn±`¨­Ž¥’AË­ìÿåûçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿæúìÿ9Ϻž'k³iNÄ•C˦JÆ`¹w¨B”›•› )^»{ ÞåïþPÁ½– îòäûüùþþýÒÊ„A¾‰öÿðÿ ëÿèÿæüçÿ ëÿ9Ï·“œ(®¢“ªn±] êýæûçþèÿçþçþèÿçþèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçþèÿçþçþçþçþçþåüìÿ`ºw³Š²‹´Š´Š°Œ«¨‘¨‘¨‘´‰„¥7ìý@¾‰Û¸Rûþþüû÷ïæÄ«›\¹vàëéÿéÿ êÿäôRÁŽ¡” ¬Ž¡•©’œàéèýæüèÿçýèÿèÿçÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿçÿèÿêÿèÿçýèÿçþçúçõ§<§‘¡•¢”£”¤“¥“¥“£“£“¯RÁ‘MÉ¢öØŸÿÿÿüüúþþþýüúüÿÿ̽d¢Œ™›}¨Bx«L|©E–›¦’§‘£”¤’¥’=Ͳ ëÿæýçþæúéÿçþáìæùçþçþçþèÿçüçþèÿçþèÿèÿèÿèÿèÿèÿçý éþ"Ýá5Ò¿ êýéÿæúçþæý êÿ.ÖË¡”¥’¦’¦“¦“¦“¦“¥“¥’ª’—’Ê•ÿùîþþýýýûíëÑ®œ¦Žªªª©¦’¥“£“­i³d éÿçýçýæúìÿáåX¾„9м ìÿæûçþèÿçýéÿèÿçÿèÿçþèÿçþçýèÿçþæü êÿ(Ùבœ h´lßäìÿæûçýçý êÿX¾…­Ž£“¦’¥“¦“¦“¦“¦“¤‘§“äÚ©ýüúþþþýüûÿÿÿǼb¡Ž¥“¥“¥“¥“¥“£“ªŸ)áî éÿæûèÿ ìÿ6Ñ»Žž1§=éùæûçþèÿçý ëÿ!Þãå÷èÿçþèÿçÿèÿéÿçÿèÿæýçýåöq¯X»†‰¢0=Ͱ êÿéÿæûèþá솣2­£“¦“¥“¦“¥“¥’¡ŽÂµSÿÿÿýýûþþþþþþõó寞£¦“¥’¦“¥’¤“©?Ì® ëÿæú ëÿáíb¸r • ±‹[¼~îÿå÷èÿæü éý#ÝÛr®Uàçéÿæýçþèÿå÷%ÜÜèþçýçþåùíÿLب‘©¥‘l²`àéìÿæú êÿ5ÒÁŸ•§‘¤“¦’¥“¦“£¨– òïÚýýýýýýáÚ«¡¦“¦“¥’£“­l²`ç÷ êÿèÿ=Í¯Š¡.ª¨œ— ?̯ êþæúçþåú ëÿgµk±‹àë êÿçþæý éÿ"Ýàgµiîÿåùèÿæüèþàꈢ0©¤“«“œIÆ›èþèÿ êü^ºx­Ž¤’¥“¥’¦“ ×ÏŽÿÿÿþþþþþüþþþɾg¡Œ§”£“©’œ!#ÜÚíÿ Þãm±`ª©¤“¦‘ž– <ͳ ëÿåúæû êþ-×Ï–š­Ž@Ì­ éÿçþçþ êÿ5ÒÀœ—+ØÐ éÿæúèÿåúìÿDÉ¥§¤’£“ªªt®U)ÙÕ ëÿåô…¥8ª£’¦”¢Á´Oýüùýýýýýü÷õ깩6¡Ž¨“§=αïÿHÇŸ“œ «Ž¥“¥“¤“¦’¤“LĘëþæùæûìÿOÓ°‹¥’e¶mèþçþçþéÿKÆš¯Œr®Wéüèûåûçþæü ëÿf¶k¯Œ¤“¥“¥“ªš˜MÄ— êû+ØÏ ”©’¡Ž² #óñÞþþþýýýýýûÿÿÿòïÛ¯ž §‹e¸pàép°]ªª£“¦’¥“¥“¤“­e¶mïÿå÷èþä÷r®W¬Ž¦‘¦< éÿæýçþèþm±_¨‘¥’a¸tçúéÿçýçþèýçûzªH«¤“¦’¤“¨‘©x«N(ØÓWÀЦ‹­›íéÍÿÿÿýýüþþþþþþÿÿÿïéË¡¤4Z·r–œ"­¤“¤“¦’¥“¦“¦“£“®€§@æöæüéÿ ÞäŸ)¨‘§‘™™åúçþæý éÿŸ%§‘¥’§xªN'ÙÖ êÿçÿæý êÿ%ÜÜ™˜¦‘¥’¦’¤“¤“­›™c³e™›åÝ®ÿÿÿýüúþþþþþþÿÿÿëìÓ®Ÿ¦Š¤•¥“¦’¥“¦“¦“¥“¤’¬Ž¥=âñçþ éþ%ÛÜ•›§‘¥’ • +×Ñèÿçþ#ÜÝž– ¨¤“¥“ª›˜LÅ— éûçüçüèÿc¸q®£“¥“¦’¥“¤•¦ª–ÞÝ®ÿÿÿþþþþþþðëб£' Œ¦“¦“¥’¦“¦“¦“¤“¬¦=ãõæý êþ$ÜÝ—¥’¥“¥’PÂ’ êþ éÿ?Ì®¢“¦‘¥’¥“¤“§‘ªX¾€ êúåù ëþFɤ±‹¡”¥’¦“§” Œ¯ !çã¼ÿÿÿýýüôòâÀ³M¡¤‘¦“¥’¦“¥’£”®Œx«L ëþåù êÿ>᲋¢”¤’«Žq°Yíÿ êþY½ƒ§‘¥’¤“¦’¦“¤“¥’¤’ :Ϲ êÿ ìþAÌ«²‹¡”¦“¥’ ‹»­>ñíÖýýüþþþÿÿÿüûõ×Ϩ– ¢Ž¦“¦“¦’ª£“8л ëýçýåú†¤4¨¤“£“­†¤5èüíÿ{ªH¬Ž¤“¥“¦“¥“¦“¡”°Œk³cçøéÿX¾„°¢”¢£ÏÅyùøîÿÿÿþþþÿÿÿïëÒ»­@¢£¡”˜›CË©ìÿ êÿçýp°Zª¤’¥’¤“«‘""ÝâæùŽŸ(¬Ž£’¦“¦“¦“¦“£“ª}©Eäöæú…£6¦Œ¢¶¨4éäÁÿÿÿþþýÿÿÿýþýÝ×£¶¢%h²cØÕä÷ãí4ÔÆzªJ©¦“¥“¦“¤“§‘– 5ÒÁ-ÖÏš˜¨¥“¥“¦“¦“¥’¢”±fºt ëÿL¼„ª°£&ØÑ’ýýúÿÿÿþþýþþþúùòØÎŒ ½q{°W‚–§‹ª¦•¦”¦“¦“¥’¤“®PÑ<γ§‘¦’¤’¦“¦“¦“¦”¥“¡A»…LǺª6ÕË„úùóþþþþþýÿúôíÜ«ÑÀm¶©7¤‘Ÿ‹¢Ž£¥’¦“¢”¶‰b¸sW¾…²‹£“¥“¥’£¢ŽžŠ£­«=¶ÌêØ£üùðþþýþþþýüúÿÿÿõóäëæÆØÏÄ·V·¨3ª˜¤‘¤“¬„¥8†£4­Ž¤“¤‘ª˜·¨3Ä·VØÏéåÃöðÞÿÿÿýüúþþþþþüüûöÿÿÿúùòôòãðìÕêæÇÝÕžÛÓšÛÕœÚÕžÛÔšÝÕžêæÇðìÕôòãúùòÿÿÿûûöþýûÿÿÿú_ÿÿÿÿÿÿÿÿÿÿÿøú_ÿÿÿÿç@çÿÿÿÿÚYÿÿÿÿ4.ÿÿÿýпÿÿò€Oÿÿí·ÿÿÔ+ÿÿ¨ÿÿ@ÿþ ÿÀ¿ýÿÿ€_þÿõ/þèü+Ðø€Ð€€€€€€€ÐøÐü+èþõ/þÿÿ€_ýÿÿÀ¿þ ÿ@ÿÿ¨ÿÿÔ+ÿÿí·ÿÿò€OÿÿýÐ ¿ÿÿÿ4,ÿÿÿÿÚ[ÿÿÿÿç çÿÿÿÿøÿÿÿÿÿ ÿÿÿÿÿÿú_ÿÿÿ(@€ þþýýýûÿÿÿÿÿÿþþþüû÷ üûöðìÔÁåà·ÿæá¹üæá¹ÿæáºÿæá¹üäßµÿëæÇÁûûöûû÷ þþýÿÿÿÿÿÿýýúþþýþþþýüúÿýûE÷ðÜ>æã½ÐÓË„ÿÁ´Oÿ¯Ÿÿ¥’ÿ¢Žÿ¡ÿ«Šÿ~£7ÿ¢5ÿ«Šÿ¡ÿ¢Žÿ£ÿ®œÿ¾°HÿÒʃÿæâ»ÐóðÞ>þÿÿEüüúþþýÿÿÿþþýüùò^êסްËÿ¥¬Bÿ¤‹ÿŸ‹þ¢þ¤‘þ¥’þ¥“þ¢”ÿ´Šþ_ºxÿY¾„ÿ±‹þ£”ÿ¥“þ¦“þ¤‘þ£þ ‹þŸ‹ÿ±¡%ÿμcÿæÕ›Žýóâ^þþþúùóMÕË…¥¹©6ÿQÄ•ÿ6Ùùš“ ú¨“ý¥”ÿ¦“þ¦“ÿ¦“ÿ¤’ÿ¤“ÿ¬ÿMÄ–ÿ=Ͳÿ§‘ÿ¦’ÿ¤’ÿ¦“ÿ¦“ÿ¦“þ¦”ÿ«’ý¥Žú€™ùxªIÿ”½rÿÉÌŒ¡õðܧÿÿÿ)ýýýþþþþþýÿÿÿýýú&ØÑ’Ó°£&ñªŒÿS¹wûíÿúZÀ‰ÿ²Œþ¡”ÿ¥’ÿ¦“ÿ¦“ÿ¥“ÿ¥“ÿ§‘ÿž– ÿ6Ò¾ÿ(ÚØÿ˜šÿ©ÿ¤“ÿ¦“ÿ¥“ÿ¤“ÿ«ÿ€§@ÿ1ÕÉþãîÿæûúÚÚüf²`ÿ«ÿÓʃçüûø$ÿÿÿþþýÿÿÿêæÅ×¶¨4ú¢ÿ¤ÿ”›ûãóþæùÿ{ªIþ«ÿ£“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¤“ÿ«ÿ‘"ÿ!ÝâÿæùÿŸ)ÿ¬Žÿ£’ÿ¥“ÿ¤“ÿ«ÿq¯Yÿçüÿ êÿÿ ìÿþ3ÓÂÿ’ž&þ£“û¡ú¢ÿ³£)úåßµ×ÿÿÿþþþÿÿÿ úùñYÐÇ|Ϧ“ÿ¢ý£”ý®Žþd·oÿæüþ éþÿ^ºzÿ±‹ÿ¡”ÿ¥’ÿ¥“ÿ¦“ÿ¥“ÿ£’ÿ­ÿ‡£4ÿèüÿíÿÿ{ªHÿ¬Žÿ¤“ÿ¤’ÿ¨‘ÿž#ÿäøÿèþÿéýÿ.ÖËÿš—ÿ¬ÿ¥’þ¦“ÿ¦“ý£ý£ÿÌÁnÏöôæYÿÿÿ þþþýýýòïÚ´¿±Iÿ Œÿ¥‘þ¦“ÿ¢“þ¯ŒÿX½„ÿèÿÿ ëÿÿ0ÕÉÿœ—ÿ§ÿ£”ÿ¥“ÿ¦’ÿ¤“ÿ¤“ÿªÿl²aÿìÿÿ êþÿY½ƒÿ§‘ÿ¥’ÿ£“ÿ®ÿNÄ–ÿéÿÿåøÿíÿÿm²aÿ®ÿ£”ÿ¥’ÿ¥“ÿ¥’þ¦“ÿ¦“þŸ‹ÿµ¥3ÿðìÒ´ýýüþþþðëÏÀ°¡#ÿ¡÷¦”ý¦“ÿ¥’þ¢”ÿ¯ŒÿX½„ÿèþÿæûÿ êýÿLÅ–ÿ¦‘ÿ©ÿ¤“ÿ¥“ÿ¥’ÿ¥’ÿ¥’ÿMÄ—ÿ éþÿ éÿÿ?Ì®ÿ¢“ÿ¦‘ÿ¢”ÿ±‹ÿ/ÖÊÿ ëþÿæûÿäõÿ€¦?ÿ­ÿ£“ÿ¦“ÿ¦“ÿ¦“ÿ¥’þ¦“ÿ§•ý Œ÷«›ÿäÝ®Àþþþþþþÿÿÿ ìëÑÁ¬ "ÿ§‹ø¤•ÿ¥“þ¦’ÿ¥“ÿ£“ÿ«ÿv­Qÿåøÿèüÿçüÿèýÿ:жÿŽŸ&ÿªÿ¦’ÿ£“ÿ§‘ÿ • ÿ,×Ðÿéÿÿçþÿßèÿ–ÿ§‘ÿ£“ÿ¨ÿ+ØÐÿ êþÿæýÿãóÿ¦>ÿ¬Žÿ¤“ÿ¦“ÿ¦“ÿ¦“ÿ¥“ÿ¦’ÿ¥“þ¤– ÿ¦Œø¨– ÿÞÝ®Áÿÿÿ þþþþþþÿÿÿïê̾¦¡+ÿW¹xø”#ÿ®þ¦’ÿ¤“ÿ¦’ÿ¥’ÿ¥’ÿ¤“ÿ,×Îÿ ëÿÿæýÿçÿÿ êÿÿáìÿf¶kÿ£’ÿ¨ÿ¦‘ÿ™™ÿåúÿçþÿæýÿ éÿÿŸ%ÿ§‘ÿ¦‘ÿ”œÿ$ÜÞÿ êþÿä÷ÿíÿÿs®Vÿ¯‹ÿ¢“ÿ¥“ÿ¦“ÿ¥“ÿ¦’ÿ¤“ÿ¤“ÿ®þššÿW»}ø™›!ÿãÛ©¾ÿÿÿýüûþþþýýúÿÿÿñî׺®œ ÿ§Œúp²_ÿ Ýãÿm²bÿ¤’ÿªÿ¤“ÿ¥“ÿ¥“ÿ¨ÿ…¤6ÿáèÿéÿÿçýÿçýÿèÿÿ ëÿÿNÕÿ¡” ÿ©ÿ¦<ÿ éÿÿæýÿçþÿèþÿn±^ÿ¦‘ÿ©ÿ€§?ÿáîÿéÿÿå÷ÿíþÿW¾„ÿ¨ÿ¥’ÿ¤“ÿ¥“ÿ¦’ÿ£“ÿªÿ¨ÿv¬Rÿ"ÜÝÿ[¾‚ÿ§Œú©—ÿéåûÿÿÿ ýýüþþþýýüöôæ?´¥+ÿ ö¨“ÿ«þAˬÿïÿÿ>̯ÿŒ ,ÿ¬Žÿ¥’ÿ¥“ÿ¤“ÿ®ÿx«Lÿçûÿçýÿçþÿçýÿæøÿìÿÿ`ºtÿ®ÿ^ºyÿéþÿçþÿçþÿéÿÿMÄ—ÿ¤“ÿ²Šÿ[¼ÿ êþÿæüÿæúÿ êÿÿ>̰ÿž– ÿ§‘ÿ¤“ÿ¥“ÿ¥“ÿ«Žÿ“œ ÿGÈ¡ÿìÿÿ5Ò½ÿ¦‘þ¨“ÿ¢ú°žÿòïÛÄþþþýýýþýüþýûŹ\Ý ú§•þ£’þ©ÿ‘"ÿ#ÜÚÿíÿÿßçÿe¶mÿ¤’ÿªÿ¤“ÿ£“ÿ«ŽÿSÁÿíÿÿåùÿèÿÿæüÿçûÿäôÿž$ÿFÈ¢ÿ êÿÿçþÿçþÿ êÿÿ0ÕÈÿ«ÿš—ÿ2ÔÆÿ ëÿÿåúÿåûÿ êÿÿ;εÿ— ÿ¦‘ÿ£“ÿ©ÿªÿm±`ÿßäÿìÿÿâêÿ‹¡-ÿ«ÿ£“þ¦”ÿ ù½¯Dÿüû÷!ýýýýýýÜÕé ÿ¦“ý¥’ÿ¥’ÿ£“ÿ­ÿl²`ÿçùÿéÿÿ éÿÿ7йÿ‹¡,ÿ«ÿ¦’ÿ§‘ÿ‘"ÿ%ÜÚÿ êþÿæûÿèÿÿåùÿîÿÿgµjÿ#Ýßÿ éÿÿæýÿçþÿèÿÿâðÿ£’ÿk³bÿ ëÿÿåúÿçþÿæûÿ êþÿ;δÿ›˜ÿ©ÿ¬Žÿž%ÿ@˪ÿéÿÿèÿÿ êûÿc·oÿ¯Œÿ£“ÿ¥’ÿ¥’þ¦“þ û×ÏŽìÿÿÿ#þþýþþýõôå@¬›ö£ü¦“þ¥’þ¦“ÿ¥’ÿ¥“ÿ¨ÿFȤÿ êþÿæúÿ ëÿÿáìÿ_¹wÿœ—ÿ«ÿ¬ŽÿZ½ÿ ëþÿæúÿçþÿçýÿèþÿ%ÜÜÿåøÿèÿÿçþÿæýÿéÿÿâîÿj²bÿ/ÕÉÿ êþÿæûÿèÿÿåùÿíýÿHÇŸÿ©ÿ¢” ÿj´eÿàèÿ ìÿÿåúÿ êÿÿ5ÒÁÿž•ÿ¦‘ÿ¤“ÿ¦“ÿ¦“ÿ¦“ÿ£ü¨– ÿðíÖÎýýüþþþýýüÿÿÿVÆ»aú¢Žý¥’ý¥“ÿ¦“ÿ¥“ÿ¦“ÿ¤“ÿ©ÿ•šÿ!Ýãÿ éÿÿæûÿèÿÿíÿÿ2ÔÃÿzªIÿµˆÿ¦=ÿàíÿéÿÿæýÿèÿÿçÿÿéÿÿèÿÿçÿÿèÿÿçþÿèÿÿåøÿ ßåÿ êÿÿæþÿçþÿçýÿæûÿìÿÿv¬OÿŽž-ÿ6Ѻÿíÿÿéÿÿæûÿèþÿáîÿ†£2ÿ­ÿ£“ÿ¥“ÿ¥“ÿ¥“ÿ¥“þ¥“þ¡Žü¿±JäÿÿÿVýýüþþþýýúé⺨«— ÿ£‘ù¦“ÿ¦“þ¦“ÿ¦“ÿ¥“ÿ¥’ÿ£“ÿ¬Žÿr¯Wÿéÿÿçýÿçþÿåùÿ ëÿÿåóÿT¿Œÿ—™ÿ0ÕÉÿ ëþÿæüÿçþÿèÿÿçýÿçþÿèÿÿçþÿèÿÿçÿÿèÿÿéÿÿçýÿèÿÿèÿÿæûÿ êÿÿ1ÕÉÿRÁÿàäÿíÿÿæúÿçýÿçýÿ êÿÿ]ºzÿ¬Žÿ£“ÿ¥“ÿ¦’ÿ©ÿªÿªÿªÿ¨ù§“ÿßÚ«§ýüùþþýüýüÿýûd¥Çˆñ„š÷¦”þ¥’þ¥“ÿ¥“ÿ¦“ÿ¦“ÿ¦“ÿ¦’ÿ¥’ÿ§‘ÿCʧÿ ëÿÿæüÿçÿÿæúÿèÿÿ ìÿÿ5ÒÀÿ#Üàÿ êÿÿçýÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçýÿçþÿçþÿçþÿçþÿèþÿäôÿçÿÿêÿÿæúÿçþÿæýÿ êÿÿ6Ѿÿ£“ÿ¥’ÿ£”ÿ§‘ÿ¦’ÿ”œÿq¯Xÿh´iÿt®Sþ‘ 'þŸö¿­>òúûùXþþýüû÷ ùâ·_cÄÿGÄž÷«ÿ¤“ÿ£“ÿ¥“ÿ¥“ÿ¤“ÿ£”ÿ¢”ÿ¡•ÿ¥’ÿž"ÿáëÿèýÿæüÿèÿÿçýÿçþÿêÿÿèÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿèÿÿçýÿèÿÿæüÿèüÿâïÿ‹ )ÿªÿ¡•ÿ«ÿ ” ÿRÂÿçþÿ êÿÿéÿÿèÿÿäöÿMÃùœ›ÿéÜ­“þÿÿüüúüüùüÿÿß¿c¬F»üïÿûo°Zþ²Šÿªÿ¨‘ÿ¨‘ÿ¬ÿ±Œÿ´Šÿ´Šÿ³Šÿ·ˆÿr¯Wÿ ëÿÿæûÿçþÿèÿÿçþÿçþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿçþÿçþÿåûÿìÿÿa¹sÿ©ÿ¢”ÿ¯Œÿ™™ÿ;϶ÿ ëÿÿçþÿæüÿèÿÿìÿÿïÿþøÿÿ)˰ùÀÃxÿÿûõCñöê9ÁŸÿY¸wù ìýÿå÷ÿRÀŒÿ¦<ÿ“œÿ”›ÿzªJÿ]»{ÿFȤÿEÊ¥ÿDʧÿ[¼„ÿ‰¢2ÿHÇ¡ÿìÿÿæûÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿåúÿìÿÿ4ÓÃÿ¡• ÿ®ÿ¨‘ÿo°`ÿ'ÚÔÿ ëÿÿæûÿæûÿ êÿÿäõÿQÂÿs®Wÿq°Yþ2ÓÂùlÀƒü÷êÍ.ÿÿÿ#äâ»Ý¤Šû‡¤9þàìþéþÿ êÿÿâîÿ!Þãÿ!Þãÿãóÿéÿÿîÿÿîÿÿîÿÿ êÿÿàåÿ.ÖÌÿãîÿèþÿæýÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçýÿéýÿáèÿ¦>ÿ¡”ÿh´gÿ5ÒÀÿæûÿ êÿÿæûÿåûÿ ëÿÿ'ÚÕÿ…¤8ÿ§ÿ°‹ÿ°Œÿž˜þ’þãÛ¬Þÿÿÿþþý-ÐÇ{ÿŒÿ¯ÿQÁÿìÿÿæúÿçÿÿéÿÿêÿÿèÿÿçþÿæûÿæûÿæûÿçýÿ êÿÿéÿÿçýÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿéÿÿàëÿ0ÕÇÿäõÿèÿÿ êÿÿèÿÿçüÿæýÿèýÿßæÿ‰¢3ÿ®ÿ¥“ÿ£”ÿ£”ÿ©’ÿ¤‹ýǼcÿþþý ÷õé.º«<ý¢ÿ¦’þž•ÿCɧÿ êÿÿìÿÿ êÿÿéÿÿèÿÿæùÿçüÿçþÿèÿÿçþÿçýÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿéÿÿèÿÿèÿÿçýÿçþÿçþÿæüÿèÿÿk³bÿ®ÿ£“ÿ¥“ÿ¦’ÿ¥“ÿ¥“þ¤‘ý¬šýòïܪ˜ÿ¥’ÿ¥“ÿ§‘ÿ¥‘ÿn±_ÿ@˪ÿ3ÓÃÿ"Ýáÿãòÿîÿÿ ëÿÿèÿÿçþÿçþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿçþÿèÿÿçþÿçþÿæüÿíÿÿAʬÿ§‘ÿ¤“ÿ¥’ÿ¥“ÿ¦“ÿ¦“ÿ¦“ÿ¦“þ ÿôòáá۬ɥ‘ÿ¦“ÿ¦’ÿ¤“ÿ¥’ÿ¯Œÿ¢”ÿ™™ÿž&ÿŒ -ÿw¬NÿKÅ™ÿãòÿ ëÿÿ éÿÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿèÿÿèÿÿîÿÿ<βÿ›˜ÿ¦‘ÿ¤“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¥’ÿ¤ÿߨ¤ÿÓÊ‚ÿ¦“ÿ¥’ÿ¥“ÿ¦’ÿ¥“ÿ£”ÿ¦’ÿ¨‘ÿ©‘ÿªÿ©ÿ¢”ÿ™˜ÿ_¹uÿÞäÿæûÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿæúÿäïÿGÇžÿš˜ÿ¦’ÿ£”ÿ¥“ÿ¦’ÿ¥“ÿ¦“ÿ¦“ÿ¦“ÿ¦“þ¤ÿÐÆyùɼeü¦“ÿ¥“ÿ¦’ÿ¥“ÿ¤“ÿ£”ÿ¢•ÿ£”ÿ¨‘ÿ«ÿ±Œÿ¯ÿ¢”ÿ—šÿj²cÿáíÿçþÿçýÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿäõÿ:϶ÿ€§@ÿ±‹ÿ²‹ÿ¬ÿ©ÿ¥“ÿ¢•ÿ¤”ÿ¤“ÿ¥“ÿ¦’ÿ¥“ÿ¥‘ÿ¾±Gÿ¼®Bÿ¥“ÿ¥“ÿ¤“ÿ¥“ÿªÿ­Žÿ´Šÿ¬Žÿ“œÿ€§?ÿn±`ÿW¾‚ÿ>Ͱÿ$ÜÝÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿáíÿ-×Îÿ>̯ÿTÁˆÿk³bÿ§>ÿ‘!ÿ©ÿµŠÿ­Žÿªÿ¦’ÿ¤”ÿ¤“ÿ¤’ÿ»­Aÿ¸§2ÿ©‘ÿ«ÿ¯ÿ¦’ÿ‡£4ÿo±]ÿSÁŽÿ<αÿ*ØÒÿâîÿ ëÿÿðÿÿ ìÿÿéÿÿçþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿéÿÿ ëÿÿ ìÿÿïÿÿ ëÿÿâîÿ)ÙÔÿ:жÿOÕÿl²`ÿ†£4ÿ ”ÿ°Œÿ«ÿ¨ÿµ¥+ÿ¬¯Iÿx«KÿV¾†ÿ3ÓÃÿ!Þâÿãòÿæûÿ ëÿÿ ìÿÿêÿÿèÿÿæûÿæùÿæûÿçüÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçýÿæûÿæùÿæûÿèÿÿéÿÿ ìÿÿ ìÿÿçýÿâñÿàçÿ/ÕËÿSÁŒÿu¬Qÿ–›ÿ®®Fÿ}©DÿY¾‚ÿ;εÿ$ÜÝÿáíÿåùÿ êÿÿ ìÿÿ ëÿÿéÿÿçüÿåùÿæûÿçüÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçüÿæûÿåùÿçüÿéÿÿ êÿÿ ìÿÿ êÿÿåøÿáìÿ Ýãÿ5ѾÿY½ÿ|©Eÿ—ÿ·§1ÿ©‘ÿ«ÿ®ÿªÿŽŸ'ÿs¯VÿU¿‰ÿAË«ÿ1ÔÆÿÞåÿ êÿÿðÿÿíÿÿ ìÿÿéÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿèÿÿêÿÿ ìÿÿðÿÿ êÿÿÞåÿ-×Îÿ?̯ÿV¿‰ÿs¯VÿŸ(ÿ¥’ÿ¯ÿ«ÿ¨ÿµ¥,ÿ¿±Jÿ¥“ÿ¥“ÿ¤“ÿ¥“ÿ©‘ÿ­Žÿ³‹ÿ®ÿ–ÿ†¤5ÿr¯ZÿY½ÿIÆÿ:иÿ ßäÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿãòÿ(ÚÕÿ@ˬÿZ½}ÿq°Zÿ…¤5ÿ˜šÿ¬Žÿ³Šÿ­Žÿ©‘ÿ¥“ÿ¤“ÿ¥“ÿ¤’ÿ»­Aÿʾiü¦“ÿ¥“ÿ¦’ÿ¥“ÿ¤“ÿ¤”ÿ¢”ÿ£”ÿ§’ÿªÿ²‹ÿµˆÿ§@ÿ?Ì­ÿãðÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿæýÿçþÿ^ºxÿš˜ÿ¤“ÿ²‹ÿ°Œÿªÿ§’ÿ£”ÿ¡•ÿ£”ÿ¤“ÿ¥“ÿ¦’ÿ¥“ÿ¥‘ÿ¾±GÿÓÉÿ¦“ÿ¥’ÿ¦“ÿ¦“ÿ¦“ÿ¥“ÿ¦’ÿ¥“ÿ£“ÿ¦’ÿš˜ÿGÈ ÿåòÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿæþÿáêÿQÁÿ“œÿŸ• ÿ¦‘ÿ«ÿªÿªÿ¨‘ÿ£”ÿ¤“ÿ¦’ÿ¥“ÿ¥’þ¤‘ÿÑÇ|ùá۬ɥ’ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¤“ÿ¦’ÿ— ÿ<βÿîÿÿçÿÿèÿÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿéÿÿ ëÿÿæüÿ@ˬÿk³bÿ…¤7ÿŒ *ÿŸ%ÿ›˜ÿ®Žÿ¨‘ÿ¤“ÿ¦’ÿ¦“ÿ¢ÿãݰÿòïÛ©— ÿ¥’ÿ¦“ÿ¦“ÿ¦“ÿ¥“ÿ¥’ÿ¤“ÿªÿFÈ£ÿíÿÿæüÿçþÿçþÿèÿÿçþÿçþÿçþÿèÿÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿçþÿçþÿçþÿçþÿèÿÿ êÿÿîÿÿèÿÿáìÿ"Ýáÿ5Ò¾ÿ_ºwÿ–ÿ©ÿ¥“ÿ¥’þ£ÿôñà÷÷ì/½¯Dÿ¢ÿ¥“ÿ¥“ÿ¦“ÿ¥“ÿ£“ÿ­ÿn±]ÿ éÿÿæüÿçþÿçþÿçýÿèÿÿèÿÿêÿÿéÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçýÿçþÿçþÿçþÿçüÿæúÿçüÿèÿÿèÿÿ êÿÿíÿÿ4ÓÂÿ”›ÿ¨‘þ£ý²¡"ýþþþ)ÐÉ€ú¢‰ÿª‘þ¤“ÿ£”ÿ¥’ÿ­ÿŽž*ÿ Þäÿèýÿæýÿçüÿèÿÿ êÿÿèÿÿå÷ÿ8кÿ(ÚÖÿéÿÿçþÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçýÿéÿÿ ëÿÿèÿÿçüÿæûÿæûÿèÿÿéÿÿêÿÿêÿÿèÿÿæùÿíÿÿ?̯ÿªÿŸŽýȽeÿþþý ÿÿÿìâ»B”û–ú®þ®Œÿ¤’ÿ…¤7ÿ'ÙÔÿ êÿÿæûÿæúÿ éÿÿæûÿ5ÒÀÿi´fÿ • ÿ‡£3ÿ Þáÿéþÿæüÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèýÿäðÿ0ÔÇÿ#Üàÿèþÿ ëÿÿîÿÿíÿÿèÿÿãðÿ!Þãÿ"Þâÿàçÿèÿÿéÿÿä÷ÿu¯Xþ§†þßݲÞþþþÿîÓCƒÅ‹ÿ+ÒÄùf¸lÿp°ZÿGÈ ÿãóÿ êÿÿæüÿæûÿ ëÿÿ"ÝÜÿn±`ÿ¨ÿ­Žÿ¥’ÿAË­ÿìÿÿåûÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿæúÿìÿÿ9Ϻÿž'ÿk³iÿNÄ•ÿC˦ÿJÆÿ`¹wÿ¨Bÿ”›ÿ•›ÿ )ÿ^»{ÿ ÞåÿïþþPÁù½– üîòä.ûüùþþýÒÊ„¬A¾‰üöÿûðÿþ ëÿÿèÿÿæüÿçÿÿ ëÿÿ9Ï·ÿ“œ(ÿ®ÿ¢“ÿªÿn±]ÿ êýÿæûÿçþÿèÿÿçþÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçþÿèÿÿçþÿçþÿçþÿçþÿçþÿåüÿìÿÿ`ºwÿ³Šÿ²‹ÿ´Šÿ´Šÿ°Œÿ«ÿ¨‘ÿ¨‘ÿ¨‘ÿ´‰ÿ„¥7þìýÿ@¾‰ùÛ¸RÿûþþCüû÷ ïæÄ_«›ÿ\¹v÷àëÿéÿÿéÿÿ êÿÿäôÿRÁŽÿ¡” ÿ¬Žÿ¡•ÿ©ÿ’œÿàéÿèýÿæüÿèÿÿçýÿèÿÿèÿÿçÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçÿÿèÿÿêÿÿèÿÿçýÿèÿÿçþÿçúÿçõÿ§<ÿ§‘ÿ¡•ÿ¢”ÿ£”ÿ¤“ÿ¥“ÿ¥“ÿ£“ÿ£“ÿ¯ÿRÁ‘ùMÉ¢ÿöØŸ“ÿÿÿüüúþþþýüúüÿÿd̽dñ¢Œ÷™›þ}¨Bþx«Lÿ|©Eÿ–›ÿ¦’ÿ§‘ÿ£”ÿ¤’ÿ¥’ÿ=Ͳÿ ëÿÿæýÿçþÿæúÿéÿÿçþÿáìÿæùÿçþÿçþÿçþÿèÿÿçüÿçþÿèÿÿçþÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿçýÿ éþÿ"Ýáÿ5Ò¿ÿ êýÿéÿÿæúÿçþÿæýÿ êÿÿ.ÖËÿ¡”ÿ¥’ÿ¦’ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¥“ÿ¥’þª’þ—ö’Ê•òÿùîXþþýýýûíëѨ®œÿ¦Žùªÿªþªÿ©ÿ¦’ÿ¥“ÿ£“ÿ­ÿi³dÿ éÿÿçýÿçýÿæúÿìÿÿáåÿX¾„ÿ9мÿ ìÿÿæûÿçþÿèÿÿçýÿéÿÿèÿÿçÿÿèÿÿçþÿèÿÿçþÿçýÿèÿÿçþÿæüÿ êÿÿ(Ù×ÿ‘œ ÿh´lÿßäÿìÿÿæûÿçýÿçýÿ êÿÿX¾…ÿ­Žÿ£“ÿ¦’ÿ¥“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¤‘ù§“ÿäÚ©§ýüúþþþýüûÿÿÿVǼbú¡Žý¥“ý¥“ÿ¥“ÿ¥“ÿ¥“ÿ£“ÿªÿŸ)ÿáîÿ éÿÿæûÿèÿÿ ìÿÿ6Ñ»ÿŽž1ÿ§=ÿéùÿæûÿçþÿèÿÿçýÿ ëÿÿ!Þãÿå÷ÿèÿÿçþÿèÿÿçÿÿèÿÿéÿÿçÿÿèÿÿæýÿçýÿåöÿq¯Xÿ»†ÿ‰¢0ÿ=Ͱÿ êÿÿéÿÿæûÿèþÿáìÿ†£2ÿ­ÿ£“ÿ¦“ÿ¥“ÿ¦“ÿ¥“þ¥’þ¡ŽüµSäÿÿÿVýýûþþþþþþõóå@¯žö£ü¦“þ¥’þ¦“ÿ¥’ÿ¤“ÿ©ÿ?Ì®ÿ ëÿÿæúÿ ëÿÿáíÿb¸rÿ • ÿ±‹ÿ[¼~ÿîÿÿå÷ÿèÿÿæüÿ éýÿ#ÝÛÿr®Uÿàçÿéÿÿæýÿçþÿèÿÿå÷ÿ%ÜÜÿèþÿçýÿçþÿåùÿíÿÿLŘÿ¨‘ÿ©ÿ¥‘ÿl²`ÿàéÿìÿÿæúÿ êÿÿ5ÒÁÿŸ•ÿ§‘ÿ¤“ÿ¦’ÿ¥“ÿ¦“ÿ£ü¨– ÿòïÚÎýýýýýýáÚ«é¡ÿ¦“ý¦“ÿ¥’ÿ£“ÿ­ÿl²`ÿç÷ÿ êÿÿèÿÿ=ͯÿŠ¡.ÿªÿ¨ÿœ— ÿ?̯ÿ êþÿæúÿçþÿåúÿ ëÿÿgµkÿ±‹ÿàëÿ êÿÿçþÿæýÿ éÿÿ"Ýàÿgµiÿîÿÿåùÿèÿÿæüÿèþÿàêÿˆ¢0ÿ©ÿ¤“ÿ«ÿ“œÿIÆ›ÿèþÿèÿÿ êüÿ^ºxÿ­Žÿ¤’ÿ¥“ÿ¥’þ¦“þ û×ÏŽìÿÿÿ#þþþþþüþþþɾgÝ¡Œú§”þ£“þ©ÿ’œ!ÿ#ÜÚÿíÿÿ Þãÿm±`ÿªÿ©ÿ¤“ÿ¦‘ÿž– ÿ<ͳÿ ëÿÿåúÿæûÿ êþÿ-×Ïÿ–šÿ­Žÿ@Ì­ÿ éÿÿçþÿçþÿ êÿÿ5ÒÀÿœ—ÿ+ØÐÿ éÿÿæúÿèÿÿåúÿìÿÿDÉ¥ÿ§ÿ¤’ÿ£“ÿªÿªÿt®Uÿ)ÙÕÿ ëÿÿåôÿ…¥8ÿªÿ£’þ¦”ÿ¢ùÁ´Oÿýüù!ýýýýýü÷õê?¹©6ÿ¡Žö¨“ÿ§þ=αÿïÿÿHÇŸÿ“œ ÿ«Žÿ¥“ÿ¥“ÿ¤“ÿ¦’ÿ¤“ÿLĘÿëþÿæùÿæûÿìÿÿOÓÿ°‹ÿ¥’ÿe¶mÿèþÿçþÿçþÿéÿÿKÆšÿ¯Œÿr®Wÿéüÿèûÿåûÿçþÿæüÿ ëÿÿf¶kÿ¯Œÿ¤“ÿ¥“ÿ¥“ÿªÿš˜ÿMÄ—ÿ êûÿ+ØÏÿ ”þ©’ÿ¡Žú² #ÿóñÞÄþþþýýýýýûÿÿÿòïÛº¯ž ÿ§‹úe¸pÿàéÿp°]ÿªÿªÿ£“ÿ¦’ÿ¥“ÿ¥“ÿ¤“ÿ­ÿe¶mÿïÿÿå÷ÿèþÿä÷ÿr®Wÿ¬Žÿ¦‘ÿ¦<ÿ éÿÿæýÿçþÿèþÿm±_ÿ¨‘ÿ¥’ÿa¸tÿçúÿéÿÿçýÿçþÿèýÿçûÿzªHÿ«ÿ¤“ÿ¦’ÿ¤“ÿ¨‘ÿ©ÿx«Nÿ(ØÓÿWÀŠÿ¦‹ú­›ÿíéÍ»ÿÿÿ ýýüþþþþþþÿÿÿïé˾¡¤4ÿZ·rø–œ"ÿ­þ¤“ÿ¤“ÿ¦’ÿ¥“ÿ¦“ÿ¦“ÿ£“ÿ®ÿ€§@ÿæöÿæüÿéÿÿ ÞäÿŸ)ÿ¨‘ÿ§‘ÿ™™ÿåúÿçþÿæýÿ éÿÿŸ%ÿ§‘ÿ¥’ÿ§ÿxªNÿ'ÙÖÿ êÿÿçÿÿæýÿ êÿÿ%ÜÜÿ™˜ÿ¦‘ÿ¥’ÿ¦’ÿ¤“ÿ¤“ÿ­þ›™ÿc³eø™›ÿåÝ®¾ÿÿÿýüúþþþþþþÿÿÿ ëìÓÁ®Ÿÿ¦Šø¤•ÿ¥“þ¦’ÿ¥“ÿ¦“ÿ¦“ÿ¥“ÿ¤’ÿ¬Žÿ¥=ÿâñÿçþÿ éþÿ%ÛÜÿ•›ÿ§‘ÿ¥’ÿ • ÿ+×Ñÿèÿÿçþÿ#ÜÝÿž– ÿ¨ÿ¤“ÿ¥“ÿªÿ›˜ÿLÅ—ÿ éûÿçüÿçüÿèÿÿc¸qÿ®ÿ£“ÿ¥“ÿ¦’ÿ¥“þ¤•ÿ¦øª–ÿÞÝ®Áÿÿÿ þþþþþþðëÐÀ±£'ÿ Œ÷¦“ý¦“ÿ¥’þ¦“ÿ¦“ÿ¦“ÿ¤“ÿ¬ÿ¦=ÿãõÿæýÿ êþÿ$ÜÝÿ—ÿ¥’ÿ¥“ÿ¥’ÿPÂ’ÿ êþÿ éÿÿ?Ì®ÿ¢“ÿ¦‘ÿ¥’ÿ¥“ÿ¤“ÿ§‘ÿªÿX¾€ÿ êúÿåùÿ ëþÿFɤÿ±‹ÿ¡”ÿ¥’þ¦“ÿ§”ý Œ÷¯ !ÿçã¼Àÿÿÿýýüôòâ´À³Mÿ¡ÿ¤‘þ¦“ÿ¥’þ¦“ÿ¥’ÿ£”ÿ®Œÿx«Lÿ ëþÿåùÿ êÿÿ>αÿ²‹ÿ¢”ÿ¤’ÿ«Žÿq°Yÿíÿÿ êþÿY½ƒÿ§‘ÿ¥’ÿ¤“ÿ¦’ÿ¦“ÿ¤“ÿ¥’ÿ¤’ ÿ:Ϲÿ êÿÿ ìþÿAÌ«ÿ²‹ÿ¡”þ¦“ÿ¥’þ ‹ÿ»­>ÿñíÖ´ýýüþþþÿÿÿ üûõY×ÏϨ– ÿ¢Žý¦“ý¦“þ¦’ÿªþ£“ÿ8лÿ ëýÿçýÿåúÿ†¤4ÿ¨ÿ¤“ÿ£“ÿ­ÿ†¤5ÿèüÿíÿÿ{ªHÿ¬Žÿ¤“ÿ¥“ÿ¦“ÿ¥“ÿ¦“ÿ¡”ÿ°Œÿk³cÿçøÿéÿþX¾„ÿ°þ¢”ý¢ý£ÿÏÅyÏùøîYÿÿÿ þþþÿÿÿïëÒ×»­@ú¢ÿ£ÿ¡”û˜›þCË©ÿìÿþ êÿÿçýÿp°Zÿªÿ¤’ÿ¥’ÿ¤“ÿ«ÿ‘"ÿ"ÝâÿæùÿŽŸ(ÿ¬Žÿ£’ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ£“ÿªÿ}©Eþäöÿæúþ…£6û¦Œÿ¢ÿ¶¨4úéäÁ×ÿÿÿþþýÿÿÿýþý&Ý×£Ó¶¢%ñh²cÿØÕûä÷úãíÿ4ÔÆþzªJÿ©ÿ¦“ÿ¥“ÿ¦“ÿ¤“ÿ§‘ÿ– ÿ5ÒÁÿ-ÖÏÿš˜ÿ¨ÿ¥“ÿ¥“ÿ¦“ÿ¦“ÿ¥’ÿ¢”ÿ±þfºtÿ ëÿúL¼„ûªÿ°£&ñØÑ’Óýýú&ÿÿÿþþýþþþúùòMØÎŒ¥ ½qÿ{°Wÿ‚–ù§‹úªú¦•þ¦”ÿ¦“þ¦“ÿ¥’ÿ¤“ÿ®ÿPÑÿ<γÿ§‘ÿ¦’ÿ¤’ÿ¦“ÿ¦“þ¦“ÿ¦”þ¥“ú¡úA»…ùLÇÿºª6ÿÕË„¥úùóMþþþþþýÿúô^íÜ«ŽÑÀmÿ¶©7ÿ¤‘ÿŸ‹ÿ¢Žÿ£ÿ¥’ÿ¦“ÿ¢”ÿ¶‰ÿb¸sÿW¾…ÿ²‹ÿ£“ÿ¥“ÿ¥’ÿ£ÿ¢ŽÿžŠÿ£ÿ­«=ÿ¶ÌÿêØ£Žüùð^þþýþþþýüúÿÿÿCõóäBëæÆCØÏèÄ·Vÿ·¨3þª˜ÿ¤‘ÿ¤“ÿ¬ÿ„¥8ÿ†£4ÿ­Žÿ¤“ÿ¤‘ÿª˜ÿ·¨3þÄ·VÿØÏèéåÃCöðÞBÿÿÿCýüúþþþþþü üûöÿÿÿ&úùò/ôòã3ðìÕ/êæÇÊÝÕžÿÛÓšüÛÕœÿÚÕžÿÛÔšüÝÕžÿêæÇÊðìÕ/ôòã3úùò/ÿÿÿ&ûûöþýû ÿÿÿú_ÿÿÿÿÿÿÿÿÿÿÿøú_ÿÿÿÿç@çÿÿÿÿÚYÿÿÿÿ4.ÿÿÿýпÿÿò€Oÿÿí·ÿÿÔ+ÿÿ¨ÿÿ@ÿþ ÿÀ¿ýÿÿ€_þÿõ/þèü+Ðø€Ð€€€€€€€ÐøÐü+èþõ/þÿÿ€_ýÿÿÀ¿þ ÿ@ÿÿ¨ÿÿÔ+ÿÿí·ÿÿò€OÿÿýÐ ¿ÿÿÿ4,ÿÿÿÿÚ[ÿÿÿÿç çÿÿÿÿøÿÿÿÿÿ ÿÿÿÿÿÿú_ÿÿÿ(€( øøøààh°`ÐÀpèèЀ¨@0ÐÀ@È ¸¨@èàÀ˜˜èøàذX¸€ØÐ˜Zªªª I°0¹Mùp ñ “0 ÆŸ»|°Ãnîd °ÇÈ·ÌÌ‹¿lÎÇ,Ì{•ûìÈ̲Ìǰ@|°¼Ì`ìÌÆ |ÌàlÌà,Ì µ[|ÌÃìÌ€ÌÌpð°ìÌÌ‹|Ì ÌÌp[à¼ÌÌÂ`,ÌËÌÌ ëð°ç`ÌÌÌÎ ÌÌÆÌÌË·€ ΰŒÌÌÌàÌÌÎÌÌÃ"° PÌ&ÌÌÌÆÌÌÈÌÌÎ|ƱìÌëÌÌÌÂÌÌÂ<ÌÌÎìÌ€  ²ÌÂ`ŒÌÌÌlÌḬ̀,ÌÌÎg̰аÌÌΰ¼ÌÌÌŒÌÌÌcÌÌÌÎÌÌαìÌÌ&ÌÌÌÌÌÌÌ‚ÌÌÌÆ,ÌÌp²ÌÌÌ‹ÌÌÌÌÌÌÌÌÌÌÌ{ìḬ̀P@ÌÌÌÂfÌÌÌÌÌÌÌÌÌÌÌâÌÌÌÎkŒÌÌÌÈÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌpc6° ƒ²ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌḬ̀âÌÌ.´ "°ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÎÌÌÌÌ{ð,{ŒÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌp |ÌÌÌÌÈð|Âæfè,Ì~bÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ`âÌÌ̆g`<ÌÌÌÌÌÌÌÇÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÎ âÌÌÌà ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇ,ÌÌÌÌà,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ ·ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ+nç|ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ0P hÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÃðð¾ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÂ`@@gÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇë@è,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ(æ°n‡ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇŽ` >|ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ~6°–ç,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇæ°–è,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ(æ° nrÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÂ~k°¶çÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇã`@>|ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌxæ@ çÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÂ`ðbÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌȰ@ ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇ;ÐlÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ'~0P ,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÂ` ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÆ <ÌÌÌÌ(,ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌḬ̀ ÌÌÌÂëÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÇ,ÌÌÌÌÌÌÌà—;ŒÌÌÂà²ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌc‚Ì(æfâÌ ÞÌÌÌÌÌ{ŒÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌpŒÀð ŒÌÌÌÈÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÎÀ,ÌÂà²ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ`$°f`ŒÌÌÌÂÌÌÌÌÌÌÌÌÌÌÈÌÌÌÌpå@ÌÌÌÂìÌÌÌÌÌÌÌÌÌÌÆgÌÌÌβÌÌÌëŒÌÌÌÌÌÌÌÌÌÌÎìḬ̀ŒÌÌ& ÌÌÌÌìÌÌÌÌÌÌÂ|ÌÌpÌÌΰÌÌÌÎlÌÌÌŒÌÌÌ`ÌÌαP²ÌÇ`ÌÌÌ ÌÌÌlÌÌÌp·Ì°ÐìÌàÌÌÌàÌÌÂÌÌÌÆâÌpÌvÌḬ̀ÌÌÈ ,Ḭ̀ |Α²ÎÌÌÇÌÌÎ<ÌÌÌp"° P°ç`ÌÌÎ ÌÌÆ,ÌÌȸ€Và|ÌÆ,ÌËgÌÌÌ`kð°|ÌÆ|ÌpìÌÌ€[|ÌÆìÌ€ÌÌ Ð|ÌÀlÌàìÌÀµ ÌÌ€¼Ì`Ì Ṵ̂ÌÌ€ð ŒÌ&ÇÌ`‘ ›ŒÌÇ`Îǽcî°ò{¿ @Æcù°p ñ I`™Jªªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿþ?ÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€ÈïëÐéäÀéäÀéäÀéäÀéäÀéäÀéäÀéäÀúùðãÞ°ÓÉ€¼®A±¡!¦“¦“¦“¦“¦“n²`¦“¦“¦“¦“¦“¬š¼®AÍÂqãÞ°úùðôòàØÐ¼®A¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“·§1ØÐôòàãްµQn²`n²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜èÿŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®AÞ× Þ× ±¡!œ˜7Ò¿èÿ“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Š¢0e¸p\½€e¸p•°PÓÉ€úùðãÞ°±¡!¦“¦“@ͯèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿIÈŸ¦“¦“¦“¦“¦“¦“¦“¦““ 7Ò¿èÿèÿèÿèÿIÈŸ“ ¬šÞ× ôò༮A¦“¦“¦“Š¢0èÿèÿ\½€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“@ͯèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“Š¢0âïèÿèÿèÿ-ØÏ“ ¦“¦“¦“¦“·§1ïëÐØÐ¬š¦“¦“¦“¦“RÂèÿèÿ@ͯ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“$Ýßèÿèÿ¦“¦“¦“¦“¦“¦“œ˜âïèÿèÿèÿ-ØÏœ˜¦“¦“¦“¦“¦“¦“¦“ÓÉ€úùðµQ¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿâ¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜èÿèÿèÿ¨@¦“¦“¦“¦“¦“\½€èÿèÿèÿèÿ¨@¦“¦“¦“¦“¦“¦“¦“¦“¦“·§1ôòàïëз§1¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿR¦“¦“¦“¦“¦“¦“¦“¦“¦“w­Pèÿèÿèÿe¸p¦“¦“¦“¦“¦“$Ýßèÿèÿèÿâ煉¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¬šïëÐïëЬš¦“¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿèÿn²`¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿèÿèÿIÈŸ¦“¦“¦“¦“¦“èÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Þ× ïëЬš¦“¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿèÿèÿèÿèÿIÈŸœ˜¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿ$Ýߦ“¦“¦“¦“œ˜èÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Þ× ïëТž \½€¦“¦“¦“¦“¦“¦“¦“¦“¦““ èÿèÿèÿèÿèÿèÿ$Ýßw­P¦“¦“¦“¦“¦“âïèÿèÿèÿèÿœ˜¦“¦“¦“¨@èÿèÿèÿèÿâ煉¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“e¸p“ Þ× ïëЬš¦“\½€-ØÏŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿèÿèÿèÿèÿèÿèÿR¦“¦“¦““ èÿèÿèÿèÿèÿ¨@¦“¦“¦“n²`èÿèÿèÿèÿèÿ“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦““ 7Ò¿@ͯ¦“¦“ãÞ°úù𬚦“¦“¦“-ØÏèÿRœ˜¦“¦“¦“¦“¦“¦“¦“IÈŸèÿèÿèÿèÿèÿèÿèÿR¦“¦“w­Pèÿèÿèÿèÿèÿ\½€¦“¦“¦“IÈŸèÿèÿèÿèÿèÿn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“\½€âïâ¦“¦“¬šïëз§1¦“¦“¦“¦“¨@èÿèÿ$Ýߨ@¦“¦“¦“¦“¦“¦“¦“-ØÏèÿèÿèÿèÿèÿèÿèÿ¨@¦“RÂèÿèÿèÿèÿèÿ@ͯ¦“¦“¦“âïèÿèÿèÿèÿèÿ\½€¦“¦“¦“¦“¦“¦“¦“Š¢0-ØÏèÿèÿw­P¦“¦“¦“¦“±¡!úùðÍÂq¦“¦“¦“¦“¦“¦“RÂèÿèÿèÿRœ˜¦“¦“¦“¦“¦“Š¢0èÿèÿèÿèÿèÿèÿèÿ$Ýߦ“7Ò¿èÿèÿèÿèÿèÿ$Ýߦ“¦“n²`èÿèÿèÿèÿèÿèÿ\½€¦“¦“¦“¦“¦“¦“\½€èÿèÿèÿ@ͯ¦“¦“¦“¦“¦“¦“µQéäÀ¦“¦“¦“¦“¦“¦“¦“œ˜$Ýßèÿèÿèÿ$Ýߨ@¦“¦“¦“¦“¦“IÈŸèÿèÿèÿèÿèÿèÿèÿŠ¢0èÿèÿèÿèÿèÿèÿèÿ“ ¦“$Ýßèÿèÿèÿèÿèÿèÿ\½€¦“¦“¦“¦“Š¢0-ØÏèÿèÿèÿâ¦“¦“¦“¦“¦“¦“¦“ãÞ°±¡!¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿèÿèÿèÿèÿRœ˜¦“¦“¦““ èÿèÿèÿèÿèÿèÿèÿ@ͯèÿèÿèÿèÿèÿèÿèÿw­Pn²`èÿèÿèÿèÿèÿèÿèÿe¸p¦“¦“¦“\½€èÿèÿèÿèÿèÿe¸p¦“¦“¦“¦“¦“¦“¦“¦“¬šúùðÓÉ€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“RÂèÿèÿèÿèÿèÿâïw­P¦“¦“¦“@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿIÈŸâïèÿèÿèÿèÿèÿèÿèÿŠ¢0¦“¨@$Ýßèÿèÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ȼaôòଚ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜$Ýßèÿèÿèÿèÿèÿèÿ@ͯœ˜¦“e¸pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏœ˜RÂèÿèÿèÿèÿèÿèÿâï“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ïëÐȼa¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿèÿèÿèÿèÿèÿèÿâïw­PŠ¢0èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ\½€$Ýßèÿèÿèÿèÿèÿèÿèÿe¸p¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®Aôòàw­P“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“IÈŸèÿèÿèÿèÿèÿèÿèÿèÿ@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¨@n²`n²`¨@œ˜¦“¦“éäÀÓÉ€@ͯn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâï“ ¦“¦“¦“¦“¦“e¸pâïèÿèÿèÿèÿâïRœ˜ȼa¬šâï$Ýßœ˜¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“w­Pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿe¸p¦“¦“¦“¦“¦“IÈŸèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏœ˜ôòàÞ× ¦“âïèÿ-ØÏœ˜¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏ¦“¦“¦“¦“œ˜7Ò¿èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ@ͯØÐµQ¦“7Ò¿èÿèÿâïRÂw­P¨@¨@\½€@ͯâïèÿèÿèÿ-ØÏ\½€Š¢0âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿŠ¢0¦“¦“¦“e¸pâïèÿèÿèÿèÿèÿèÿ@Í¯Š¢0¦“¦“w­P7Ò¿ž«@úù𦓦“n²`èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ\½€¦““ \½€$Ýßèÿèÿèÿèÿèÿèÿèÿn²`¦“¦“¦“¦“¦“¦“¦“ôòàãÞ°¦“¦“¦“-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ7Ò¿$Ýßèÿèÿèÿèÿèÿèÿèÿèÿèÿe¸p¦“¦“¦“¦“¦“¦“¦“¦“ØÐȼa¦“¦“¦“Š¢0âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ@ͯ¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®A·§1¦“¦“¦“¦““ 7Ò¿èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâï“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Š¢0\½€\½€7Ò¿7Ò¿èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ïëÐéäÀ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“w­PIÈŸèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Þ× Þ× ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜RÂèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâïw­P¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ÓÉ€ÓÉ€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Š¢0-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏe¸pœ˜¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“µQȼa¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@e¸p@ͯ$Ýßèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ$Ýß@ͯ\½€¨@œ˜¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®A¼®A¦“¦“¦“¦“¦“¦“¦“¦“¦“Š¢0e¸pIÈŸ-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏIÈŸe¸p¨@¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®A¼®A¦“¦“¦“¦““ n²`RÂ7Ò¿èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏRÂn²`Š¢0¦“¦“¦“¦“±¡!³³Pw­P\½€7Ò¿âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ7Ò¿RÂw­P“ ³³P¨@\½€@ͯ$Ýßèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâï@ͯ\½€¨@œ˜¼®A¦“¦“¦“¦“œ˜w­P\½€7Ò¿âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâï7Ò¿\½€w­P“ ¦“¦“¦“¦“±¡!¼®A¦“¦“¦“¦“¦“¦“¦“¦“¦““ w­PRÂ7Ò¿èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ7Ò¿RÂn²`Š¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®AÍÂq¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Š¢0n²`RÂ-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏIÈŸe¸pŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®AÓÉ€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜\½€-ØÏèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâïw­P¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“µQÞ× ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“w­Pâïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ@ͯ“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ÓÉ€éäÀ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“n²`èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ7Ò¿n²`“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ãÞ°¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“w­Pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ$Ýß7Ò¿7Ò¿RÂn²`¦“¦“¦“¦“¦“¦“¦“ïëз§1¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ$Ýߨ@¦“¦“¦“¦“¬šÍÂq¦“¦“¦“¦“¦“¦“¦“¦“¦“@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿw­P¦“¦“¦“µQãÞ°¦“¦“¦“¦“¦“¦“¦“¦“n²`èÿèÿèÿèÿèÿèÿèÿèÿèÿ$ÝßIÈŸâïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿâ¦“¦“ØÐ¦“œ˜¦“¦“¦“¦“¦“n²`èÿèÿèÿèÿèÿèÿèÿ$Ýß\½€“ ¦“e¸pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏâïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿR¦“¦“ôòàµQ-ØÏn²`“ ¦“w­P@ͯèÿèÿèÿèÿèÿèÿâïe¸p¦“¦“¦““ âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ¨@n²`@ͯ$Ýßèÿèÿ$Ýß@ͯe¸p¨@¨@¨@e¸p$Ýßèÿèÿ$Ýߦ“·§1ãÞ°\½€èÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏ“ ¦“¦“¦“¦“@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“IÈŸèÿèÿ¦“ØÐ¬šIÈŸèÿèÿèÿèÿèÿèÿèÿèÿIÈŸ¦“¦“¦“¦“¦“w­Pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ\½€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿ¦“úùðÓÉ€¦“e¸p$Ýßèÿèÿèÿèÿ$Ýße¸p¦“¦“¦“¦“¦“œ˜âïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@$Ýßȼaúù𬚦“¦“Š¢0¨@¨@Š¢0¦“¦“¦“¦“¦“¦“¦“@ͯèÿèÿèÿèÿèÿèÿèÿèÿâïèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ@ͯèÿèÿèÿèÿèÿèÿèÿèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“e¸pïëÐÓÉ€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“w­Pèÿèÿèÿèÿèÿèÿèÿ$Ýße¸pèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿw­PŠ¢0-ØÏèÿèÿèÿèÿèÿèÿèÿ\½€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¼®Aúù𬚦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜âïèÿèÿèÿèÿèÿèÿRœ˜@ͯèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿR¦“¦“\½€èÿèÿèÿèÿèÿèÿâï“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ôòàÓÉ€¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“@ͯèÿèÿèÿèÿèÿ$Ýߨ@¦“œ˜èÿèÿèÿèÿèÿèÿèÿèÿRÂèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿèÿ$Ýߦ“¦“¦“Š¢0-ØÏèÿèÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“ÍÂq·§1¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿèÿèÿèÿèÿRœ˜¦“¦“¨@èÿèÿèÿèÿèÿèÿèÿ\½€Š¢0èÿèÿèÿèÿèÿèÿèÿ@ͯèÿèÿèÿèÿèÿèÿèÿ¨@¦“¦“¦“¦“\½€èÿèÿèÿèÿèÿe¸p¦“¦“¦“¦“¦“¦“¦“¦“¬šúùðïëЦ“¦“¦“¦“¦“¦“¦“œ˜$Ýßèÿèÿèÿ-ØÏ¨@¦“¦“¦“¦“\½€èÿèÿèÿèÿèÿèÿ$Ýߦ“¦“èÿèÿèÿèÿèÿèÿèÿŠ¢0èÿèÿèÿèÿèÿèÿèÿ7Ò¿¦“¦“¦“¦“¦““ 7Ò¿èÿèÿèÿâï“ ¦“¦“¦“¦“¦“¦“¦“ãÞ°ÓÉ€¦“¦“¦“¦“¦“¦“RÂèÿèÿèÿ\½€¦“¦“¦“¦“¦“¦“\½€èÿèÿèÿèÿèÿèÿe¸p¦“¦“7Ò¿èÿèÿèÿèÿèÿ$Ýߦ“IÈŸèÿèÿèÿèÿèÿèÿèÿw­P¦“¦“¦“¦“¦“¦“e¸pâïèÿèÿ7Ò¿¦“¦“¦“¦“¦“¦“ȼa¼®A¦“¦“¦“¦“¨@èÿèÿ-ØÏŠ¢0¦“¦“¦“¦“¦“¦“¦“n²`èÿèÿèÿèÿèÿèÿœ˜¦“¦“\½€èÿèÿèÿèÿèÿ@ͯ¦““ âïèÿèÿèÿèÿèÿèÿâ¦“¦“¦“¦“¦“¦““ 7Ò¿èÿèÿe¸p¦“¦“¦“¦“·§1úùðúùð±¡!¦“¦“œ˜$Ýßèÿ\½€¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿèÿèÿèÿèÿ7Ò¿¦“¦“¦“w­Pèÿèÿèÿèÿèÿ\½€¦“¦“n²`èÿèÿèÿèÿèÿèÿèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“e¸pâïâï“ ¦“¦“¬šïëÐïëЬš¦“RÂ-ØÏŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“èÿèÿèÿèÿèÿ\½€¦“¦“¦““ èÿèÿèÿèÿèÿ¨@¦“¦“¦“n²`âïèÿèÿèÿèÿèÿèÿIÈŸ¦“¦“¦“¦“¦“¦“¦“¦““ @ͯ@ͯ¦“¦“ïëÐïëЙ¤0e¸p¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿèÿw­P¦“¦“¦“¦“âïèÿèÿèÿèÿœ˜¦“¦“¦“¦“Š¢07Ò¿èÿèÿèÿèÿèÿèÿ¨@¦“¦“¦“¦“¦“¦“¦“¦“¦“w­P“ Þ× ïëЬš¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿèÿ¨@¦“¦“¦“¦“7Ò¿èÿèÿèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“e¸pèÿèÿèÿèÿèÿ@ͯ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“Þ× ïëЬš¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿèÿ¨@¦“¦“¦“¦“\½€èÿèÿèÿIÈŸ¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿèÿèÿèÿ$Ýߦ“¦“¦“¦“¦“¦“¦“¦“¬šãÞ°ôòà·§1¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“-ØÏèÿèÿèÿèÿ¦“¦“¦“¦“¦“¨@èÿèÿèÿe¸p¦“¦“¦“¦“¦“¦“¦“¦“¦“e¸pèÿèÿèÿèÿ¦“¦“¦“¦“¦“¦“¦“±¡!ïëÐúùðȼa¦“¦“¦“¦“¦“¦“¦“¦“¦““ èÿèÿèÿèÿIÈŸ¦“¦“¦“¦“¦“œ˜èÿèÿèÿ¨@¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“$Ýßèÿèÿ$Ýߦ“¦“¦“¦“¦“¦“¼®AúùðãÞ°¬š¦“¦“¦“¦“¦“¦“¦“7Ò¿èÿèÿèÿâï“ ¦“¦“¦“¦“¦“¦“$Ýßèÿèÿ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“RÂèÿèÿ@ͯ¦“¦“¦“¦“¦“ØÐúùðµQ¦“¦“¦“¦“œ˜@ͯèÿèÿèÿâ0¦“¦“¦“¦“¦“¦“¦“@ͯèÿ-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿèÿw­P¦“¦“¦“¼®AôòàéäÀ·§1œ˜@ͯèÿèÿèÿèÿ7Ò¿Š¢0¦“¦“¦“¦“¦“¦“¦“¦“\½€èÿR¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“IÈŸèÿ7Ò¿¦“¦“±¡!ãÞ°Þ× ­¬@n²`\½€e¸p“ ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@èÿn²`¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“œ˜âï-ØÏœ˜±¡!Þ× éäÀȼa¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“èÿŠ¢0¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“¨@n²`µQãÞ°úùðÞנµQ¬š¦“¦“¦“¦“¦“¦“¦“¦“¦“-ØÏ¦“¦“¦“¦“¦“¦“¦“¦“¦“¦“µQØÐúùðéäÀÓɀµQ·§1¦“¦“¦“¦“¦“w­P¦“¦“¦“¦“¦“·§1µQÓÉ€éäÀúùðéäÀéäÀéäÀéäÀéäÀéäÀéäÀúùðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿþ?ÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€ ïëÐÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿúùðÿãÞ°ÿÓÉ€ÿ¼®Aÿ±¡!ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿ¼®AÿÍÂqÿãÞ°ÿúùðÿôòàÿØÐÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ·§1ÿØÐÿôòàÿãÞ°ÿµQÿn²`ÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿèÿÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®AÿÞ× ÿÞ× ÿ±¡!ÿœ˜ÿ7Ò¿ÿèÿÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿe¸pÿ\½€ÿe¸pÿ•°PÿÓÉ€ÿúùðÿãÞ°ÿ±¡!ÿ¦“ÿ¦“ÿ@ͯÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿIÈŸÿ“ ÿ¬šÿÞ× ÿôòàÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿâïÿèÿÿèÿÿèÿÿ-ØÏÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ·§1ÿïëÐÿØÐÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿRÂÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ$Ýßÿèÿÿèÿÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿèÿÿèÿÿèÿÿ-ØÏÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÓÉ€ÿúùðÿµQÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿâïÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ·§1ÿôòàÿïëÐÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿRÂÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ$Ýßÿèÿÿèÿÿèÿÿâïÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿïëÐÿïëÐÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÞ× ÿïëÐÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿIÈŸÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÞ× ÿïëÐÿ¢ž ÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿâïÿèÿÿèÿÿèÿÿèÿÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿâïÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿ“ ÿÞ× ÿïëÐÿ¬šÿ¦“ÿ\½€ÿ-ØÏÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿ¦“ÿ¦“ÿ¦“ÿ“ ÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ7Ò¿ÿ@ͯÿ¦“ÿ¦“ÿãÞ°ÿúùðÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿèÿÿRÂÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿâïÿâïÿœ˜ÿ¦“ÿ¦“ÿ¬šÿïëÐÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿ$Ýßÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿRÂÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ-ØÏÿèÿÿèÿÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ±¡!ÿúùðÿÍÂqÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿRÂÿèÿÿèÿÿèÿÿRÂÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿµQÿéäÀÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ$Ýßÿèÿÿèÿÿèÿÿ$Ýßÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿŠ¢0ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ“ ÿ¦“ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ-ØÏÿèÿÿèÿÿèÿÿâïÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿãÞ°ÿ±¡!ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿw­Pÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿúùðÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿRÂÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿIÈŸÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿŠ¢0ÿ¦“ÿ¨@ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿȼaÿôòàÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿœ˜ÿ¦“ÿe¸pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿœ˜ÿRÂÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿïëÐÿȼaÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿw­PÿŠ¢0ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®Aÿôòàÿw­Pÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿn²`ÿn²`ÿ¨@ÿœ˜ÿ¦“ÿ¦“ÿéäÀÿÓÉ€ÿ@ͯÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿâïÿèÿÿèÿÿèÿÿèÿÿâïÿRÂÿœ˜ÿȼaÿ¬šÿâïÿ$Ýßÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿœ˜ÿôòàÿÞ× ÿ¦“ÿâïÿèÿÿ-ØÏÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿØÐÿµQÿ¦“ÿ7Ò¿ÿèÿÿèÿÿâïÿRÂÿw­Pÿ¨@ÿ¨@ÿ\½€ÿ@ͯÿâïÿèÿÿèÿÿèÿÿ-ØÏÿ\½€ÿŠ¢0ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿŠ¢0ÿ¦“ÿ¦“ÿw­Pÿ7Ò¿ÿž«@ÿúùðÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ“ ÿ\½€ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿôòàÿãÞ°ÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿØÐÿȼaÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®Aÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ\½€ÿ\½€ÿ7Ò¿ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿïëÐÿéäÀÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­PÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÞ× ÿÞ× ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿRÂÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÓÉ€ÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿe¸pÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿµQÿȼaÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿe¸pÿ@ͯÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ@ͯÿ\½€ÿ¨@ÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®Aÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿe¸pÿIÈŸÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿIÈŸÿe¸pÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®Aÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿn²`ÿRÂÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿRÂÿn²`ÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ±¡!ÿ³³Pÿw­Pÿ\½€ÿ7Ò¿ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿRÂÿw­Pÿ“ ÿ³³Pÿ¨@ÿ\½€ÿ@ͯÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ@ͯÿ\½€ÿ¨@ÿœ˜ÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿw­Pÿ\½€ÿ7Ò¿ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ7Ò¿ÿ\½€ÿw­Pÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ±¡!ÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿw­PÿRÂÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿRÂÿn²`ÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®AÿÍÂqÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿn²`ÿRÂÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿIÈŸÿe¸pÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®AÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ\½€ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿµQÿÞ× ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÓÉ€ÿéäÀÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿn²`ÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿãÞ°ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ7Ò¿ÿ7Ò¿ÿRÂÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿïëÐÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿÍÂqÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿw­Pÿ¦“ÿ¦“ÿ¦“ÿµQÿãÞ°ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$ÝßÿIÈŸÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿœ˜ÿ¦“ÿ¦“ÿØÐÿ¦“ÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ\½€ÿ“ ÿ¦“ÿe¸pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿ¦“ÿ¦“ÿôòàÿµQÿ-ØÏÿn²`ÿ“ ÿ¦“ÿw­Pÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ“ ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿn²`ÿ@ͯÿ$Ýßÿèÿÿèÿÿ$Ýßÿ@ͯÿe¸pÿ¨@ÿ¨@ÿ¨@ÿe¸pÿ$Ýßÿèÿÿèÿÿ$Ýßÿ¦“ÿ·§1ÿãÞ°ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿèÿÿ¦“ÿØÐÿ¬šÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿ¦“ÿúùðÿÓÉ€ÿ¦“ÿe¸pÿ$Ýßÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿ$Ýßÿȼaÿúùðÿ¬šÿ¦“ÿ¦“ÿŠ¢0ÿ¨@ÿ¨@ÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿïëÐÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿe¸pÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿw­PÿŠ¢0ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®Aÿúùðÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿœ˜ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿôòàÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¨@ÿ¦“ÿœ˜ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÍÂqÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿèÿÿRÂÿœ˜ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿŠ¢0ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿúùðÿïëÐÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ$Ýßÿèÿÿèÿÿèÿÿ-ØÏÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿŠ¢0ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ7Ò¿ÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿãÞ°ÿÓÉ€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿRÂÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿIÈŸÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿâïÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿȼaÿ¼®Aÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿ-ØÏÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿœ˜ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿ¦“ÿ“ ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿâïÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ7Ò¿ÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ·§1ÿúùðÿúùðÿ±¡!ÿ¦“ÿ¦“ÿœ˜ÿ$Ýßÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿn²`ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿâïÿâïÿ“ ÿ¦“ÿ¦“ÿ¬šÿïëÐÿïëÐÿ¬šÿ¦“ÿRÂÿ-ØÏÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿèÿÿèÿÿèÿÿèÿÿèÿÿ\½€ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿn²`ÿâïÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿ@ͯÿ@ͯÿ¦“ÿ¦“ÿïëÐÿïëÐÿ™¤0ÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿâïÿèÿÿèÿÿèÿÿèÿÿœ˜ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿŠ¢0ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿ“ ÿÞ× ÿïëÐÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿèÿÿèÿÿèÿÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿÞ× ÿïëÐÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¬šÿãÞ°ÿôòàÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿèÿÿèÿÿèÿÿèÿÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿèÿÿèÿÿe¸pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿe¸pÿèÿÿèÿÿèÿÿèÿÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ±¡!ÿïëÐÿúùðÿȼaÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ“ ÿèÿÿèÿÿèÿÿèÿÿIÈŸÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿèÿÿèÿÿèÿÿ¨@ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ$Ýßÿèÿÿèÿÿ$Ýßÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¼®AÿúùðÿãÞ°ÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ7Ò¿ÿèÿÿèÿÿèÿÿâïÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ$Ýßÿèÿÿèÿÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿRÂÿèÿÿèÿÿ@ͯÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿØÐÿúùðÿµQÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿ@ͯÿèÿÿèÿÿèÿÿâïÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ@ͯÿèÿÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿèÿÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¼®AÿôòàÿéäÀÿ·§1ÿœ˜ÿ@ͯÿèÿÿèÿÿèÿÿèÿÿ7Ò¿ÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ\½€ÿèÿÿRÂÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿIÈŸÿèÿÿ7Ò¿ÿ¦“ÿ¦“ÿ±¡!ÿãÞ°ÿÞ× ÿ­¬@ÿn²`ÿ\½€ÿe¸pÿ“ ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿèÿÿn²`ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿœ˜ÿâïÿ-ØÏÿœ˜ÿ±¡!ÿÞ× ÿéäÀÿȼaÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿèÿÿŠ¢0ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¨@ÿn²`ÿµQÿãÞ°ÿúùðÿÞ× ÿµQÿ¬šÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ-ØÏÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿµQÿØÐÿúùðÿéäÀÿÓÉ€ÿµQÿ·§1ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿw­Pÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ¦“ÿ·§1ÿµQÿÓÉ€ÿéäÀÿúùðÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿéäÀÿúùðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿþ?ÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿàÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿøÿÿÿÿÿÿüÿÿÿÿÿÿüÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿþ?ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ./saods9/ds9/win/ds9.rc0000644000175000017500000001370412040054224013422 0ustar olesoles#include #define VV "7.2" VS_VERSION_INFO VERSIONINFO FILEVERSION 7,2,0,0 PRODUCTVERSION 7,2,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "SAOImage DS9 " VV VALUE "OriginalFilename", "ds9.exe" VALUE "CompanyName", "Smithsonian Astrophysical Observatory" VALUE "FileVersion", VV VALUE "LegalCopyright", "Copyright 1999-2012 by Smithsonian Astrophysical Observatory" VALUE "ProductName", "SAOImage DS9" VALUE "ProductVersion", VV END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END tk ICON DISCARDABLE "ds9.ico" // // Bitmaps // buttons BITMAP DISCARDABLE "buttons.bmp" // // Cursors // X_cursor CURSOR DISCARDABLE "cursor00.cur" arrow CURSOR DISCARDABLE "cursor02.cur" based_arrow_down CURSOR DISCARDABLE "cursor04.cur" based_arrow_up CURSOR DISCARDABLE "cursor06.cur" boat CURSOR DISCARDABLE "cursor08.cur" bogosity CURSOR DISCARDABLE "cursor0a.cur" bottom_left_corner CURSOR DISCARDABLE "cursor0c.cur" bottom_right_corner CURSOR DISCARDABLE "cursor0e.cur" bottom_side CURSOR DISCARDABLE "cursor10.cur" bottom_tee CURSOR DISCARDABLE "cursor12.cur" box_spiral CURSOR DISCARDABLE "cursor14.cur" center_ptr CURSOR DISCARDABLE "cursor16.cur" circle CURSOR DISCARDABLE "cursor18.cur" clock CURSOR DISCARDABLE "cursor1a.cur" coffee_mug CURSOR DISCARDABLE "cursor1c.cur" cross CURSOR DISCARDABLE "cursor1e.cur" cross_reverse CURSOR DISCARDABLE "cursor20.cur" crosshair CURSOR DISCARDABLE "cursor22.cur" diamond_cross CURSOR DISCARDABLE "cursor24.cur" dot CURSOR DISCARDABLE "cursor26.cur" dotbox CURSOR DISCARDABLE "cursor28.cur" double_arrow CURSOR DISCARDABLE "cursor2a.cur" draft_large CURSOR DISCARDABLE "cursor2c.cur" draft_small CURSOR DISCARDABLE "cursor2e.cur" draped_box CURSOR DISCARDABLE "cursor30.cur" exchange CURSOR DISCARDABLE "cursor32.cur" fleur CURSOR DISCARDABLE "cursor34.cur" gobbler CURSOR DISCARDABLE "cursor36.cur" gumby CURSOR DISCARDABLE "cursor38.cur" hand1 CURSOR DISCARDABLE "cursor3a.cur" hand2 CURSOR DISCARDABLE "cursor3c.cur" heart CURSOR DISCARDABLE "cursor3e.cur" icon CURSOR DISCARDABLE "cursor40.cur" iron_cross CURSOR DISCARDABLE "cursor42.cur" left_ptr CURSOR DISCARDABLE "cursor44.cur" left_side CURSOR DISCARDABLE "cursor46.cur" left_tee CURSOR DISCARDABLE "cursor48.cur" leftbutton CURSOR DISCARDABLE "cursor4a.cur" ll_angle CURSOR DISCARDABLE "cursor4c.cur" lr_angle CURSOR DISCARDABLE "cursor4e.cur" man CURSOR DISCARDABLE "cursor50.cur" middlebutton CURSOR DISCARDABLE "cursor52.cur" mouse CURSOR DISCARDABLE "cursor54.cur" pencil CURSOR DISCARDABLE "cursor56.cur" pirate CURSOR DISCARDABLE "cursor58.cur" plus CURSOR DISCARDABLE "cursor5a.cur" question_arrow CURSOR DISCARDABLE "cursor5c.cur" right_ptr CURSOR DISCARDABLE "cursor5e.cur" right_side CURSOR DISCARDABLE "cursor60.cur" right_tee CURSOR DISCARDABLE "cursor62.cur" rightbutton CURSOR DISCARDABLE "cursor64.cur" rtl_logo CURSOR DISCARDABLE "cursor66.cur" sailboat CURSOR DISCARDABLE "cursor68.cur" sb_down_arrow CURSOR DISCARDABLE "cursor6a.cur" sb_h_double_arrow CURSOR DISCARDABLE "cursor6c.cur" sb_left_arrow CURSOR DISCARDABLE "cursor6e.cur" sb_right_arrow CURSOR DISCARDABLE "cursor70.cur" sb_up_arrow CURSOR DISCARDABLE "cursor72.cur" sb_v_double_arrow CURSOR DISCARDABLE "cursor74.cur" shuttle CURSOR DISCARDABLE "cursor76.cur" sizing CURSOR DISCARDABLE "cursor78.cur" spider CURSOR DISCARDABLE "cursor7a.cur" spraycan CURSOR DISCARDABLE "cursor7c.cur" star CURSOR DISCARDABLE "cursor7e.cur" target CURSOR DISCARDABLE "cursor80.cur" tcross CURSOR DISCARDABLE "cursor82.cur" top_left_arrow CURSOR DISCARDABLE "cursor84.cur" top_left_corner CURSOR DISCARDABLE "cursor86.cur" top_right_corner CURSOR DISCARDABLE "cursor88.cur" top_side CURSOR DISCARDABLE "cursor8a.cur" top_tee CURSOR DISCARDABLE "cursor8c.cur" trek CURSOR DISCARDABLE "cursor8e.cur" ul_angle CURSOR DISCARDABLE "cursor90.cur" umbrella CURSOR DISCARDABLE "cursor92.cur" ur_angle CURSOR DISCARDABLE "cursor94.cur" watch CURSOR DISCARDABLE "cursor96.cur" xterm CURSOR DISCARDABLE "cursor98.cur" none CURSOR DISCARDABLE "cursor9a.cur" // // This enables themed scrollbars in XP by trying to use comctl32 v6. // #ifndef RT_MANIFEST #define RT_MANIFEST 24 #endif #ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 #endif ./saods9/ds9/win/install.vbs0000644000175000017500000000065711374524132014573 0ustar olesoles' ' Copy to destination ' 'dim fso 'set fso = CreateObject("Scripting.FileSystemObject") 'fso.CopyFolder "..\WZSE0.TMP","c:\ds9",True ' ' Create a ds9 shortcut on the Desktop ' set WshShell = CreateObject("WScript.Shell") strDesktop = WshShell.SpecialFolders("Desktop") set oMyShortCut= WshShell.CreateShortcut(strDesktop+"\SAOImage DS9.lnk") oMyShortCut.WindowStyle = 7 oMyShortCut.TargetPath = "c:\ds9\ds9.exe" oMyShortCut.Save ./saods9/ds9/win/buttons.bmp0000644000175000017500000000151611607122125014575 0ustar olesolesBMNv(4Ø€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿffffffffffffffffffffffffffÕff""ffffb"&ffff""ffffb"&fff"33"ffb#32&ff"33"ffb#32&fža3DD3&f4DC2fa3ff3&f6fc2faTDDC&fDDD2faVffc&ffff2fGDDDD2aTDDC&ffff2aVffc&KDDDD2aT@C&ffff2aV`c&žDDDD2aT@C&ffff2aV`c&¡DDDD2aTDDC&ffff2aVffc&½aTDDC&fDDD2faVffc&ffff2f aUDDU&fTDERfaUffU&fVfeRf fUUffaUQffUUffaUQfffffffaffffffffaff¬""""""""""""""""""""""""""33333!33333233333!333332‚DDDDC!TDDDD2ffffc!Vffff2 DDDDC!TDDD2ffffc!Vfff2»»DDDDC!T@DD2ffffc!V`ff2DDDDC!TD2ffffc!Vf2 DDDDC!T@D2ffffc!V`f2DDDDC!TD2ffffc!Vf2¬DDDDC!TDD@2ffffc!Vff`2 DDDDC!TDDD2ffffc!Vfff2LoDDDDC!TDDDD2ffffc!Vffff2UUUUS!UUUUU2UUUUS!UUUUU2¡!!6./saods9/ds9/win/about.txt0000644000175000017500000000023011370071032014237 0ustar olesolesSAOImage DS9 installation program. For futher information, please visit us at http://hea-www.harvard.edu/RD/ds9 or contact us at saord@cfa.harvard.edu. ./saods9/ds9/macosx/0000755000175000017500000000000012133201304013061 5ustar olesoles./saods9/ds9/macosx/README0000644000175000017500000000040311214011637013745 0ustar olesoles To install SAOimage DS9, drag and drop the DS9 icon onto the Applications Folder. You also can drag the DS9 icon from Applications to your Dock in order to make DS9 more easily accessible. Email us with questions and comments: saord@cfa.havard.edu ./saods9/ds9/macosx/SAOImage DS9.app/0000755000175000017500000000000012132057632015621 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/0000755000175000017500000000000012132057632017416 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/MacOS/0000755000175000017500000000000012133201304020344 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/MacOS/ds90000644000175000017500000000000010663370611020772 0ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/0000755000175000017500000000000012132057632021370 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/App.icns0000644000175000017500000013556710662656612023020 0ustar olesolesicns»wics#Hàø?ü?üþþþþþþ?ü?üøðàø?ü?üþþþþþþ?ü?üøðis32Õÿÿ»ÿ„ÿ –%%,]k‚ÿD< Wz7Q“";ÿÿÿA=0ºq‘“œCBÿ£¬…æÐëëe¯ e“‡`÷÷üúó÷•2R{ÿ!¤âðùø éÁ„$ÿÿ#5tèû€ø ÷ûØr7xÌ-N‹Öûø ùðŸ](UÿQ›ã‚ø3õñ˜ÿky`ûöùúøüu¡˜R„ «‡Þõåí¨·+xÿ+A2hÆ“’²R#G(€ÿ ÿ1 ¤EVvb2ÿ€ÿ ÿ_f!&t\ÿƒÿ™?>yÿÿUîÏ„ÿ ÐȰ®±­¿Ä‚ÿ ·ªÂÅ´º§Í®»€ÿ4¹³¯±Î¿ÅÆÈ­¸¹ÿÚ®®ËÃØÓÙټ̰©ÏÂÎûÜÛÝÜÛÜÆ±Àİ«Ê×Ú‚Ü ÙÐǰªª¯µ¿ØÜ ÛÜÕ¾´¬Ò̱ºÄÔƒÜ Úɼ®ª­¼È×‚Ü ÛÚǦªªÁÈ»ÅÜÛ€Ü4Ý¿Éϼ̩¨ËÃÖÛ×ÙÊά°Íÿ³¸³¼ÑÆÅ͸¯¼³ÿÿµªÐ¬¶¹Â«µ€ÿ ÈÀ«­­¬ÁÀƒÿظ´ÇÿÿUÿÿ_„ÿ çŸÊÀ»Ñ²×‚ÿ áÕ”m ŒÙ`¿á€ÿD㥾¤5rWUMÁ¥ÚÿÿÌÂAa" {?´Õç´c^€T¤—™ÐÒG/dŪÿ¤o q¢¿ðÿ½\ Lƒ´âÓO€ QÚѪ¤u}Y3nJ\¬·ÑÏB` E8»¶ÒÿÛ¤¥x+VV<аžÞÿÿÒÍN¾•‡m„ÛÒ€ÿ ܡϷ²ÃÖƒÿåØÙÿÿÿs8mk~ÇåæÏ…Dâÿÿÿÿÿÿí^B÷ÿÿÿÿÿÿÿÿÿ\Ýÿÿÿÿÿÿÿÿÿÿî jÿÿÿÿÿÿÿÿÿÿÿÿˆ¶ÿÿÿÿÿÿÿÿÿÿÿÿÏÓÿÿÿÿÿÿÿÿÿÿÿÿè Ùÿÿÿÿÿÿÿÿÿÿÿÿé¼ÿÿÿÿÿÿÿÿÿÿÿÿÖ yÿÿÿÿÿÿÿÿÿÿÿÿ•ëÿÿÿÿÿÿÿÿÿÿý3^ÿÿÿÿÿÿÿÿÿÿ}hüÿÿÿÿÿÿÿ„3«êúûì²E()ICN#à?üÿÿÿ€ÿÿÀÿÿàÿÿðÿÿøÿÿøÿÿü?ÿÿü?ÿÿü?ÿÿþ?ÿÿþ?ÿÿþÿÿþ?ÿÿþ?ÿÿþ?ÿÿü?ÿÿü?ÿÿüÿÿøÿÿøÿÿðÿÿðÿÿàÿÿÀÿÿ?þðà?üÿÿÿ€ÿÿÀÿÿàÿÿðÿÿøÿÿøÿÿü?ÿÿü?ÿÿü?ÿÿþ?ÿÿþ?ÿÿþÿÿþ?ÿÿþ?ÿÿþ?ÿÿü?ÿÿü?ÿÿüÿÿøÿÿøÿÿðÿÿðÿÿàÿÿÀÿÿ?þðil32 ‰ÿ†‘ÿ ÿÿ™’mhˆœêÿŽÿÿ¥P1%6 -d†ÿŠÿ  Q~©,@m€+”*vÿˆÿ ÿe¯èp«€*é!Xÿ†ÿÿK €^ÿTž× ­ú(Aç„ÿÿFD&€xÿlÆñ+Ïÿ¥JEÿƒÿ€½c¢ÿ­åýSÊÿÔ<Ã=Vÿÿ¿&Nÿ©‰ÿï}ôúÅ÷ÿ^„ÿ‡{‚ÿ+D ™ÿÜ•óúõ÷øúùë[ÄÿÍ ?ÿÿÿœuÎÜ|Ùÿùôøùøóóÿó7 q™ÿÿy[\Îÿ¯(Yˆøü±}¥[›½@ÿÿ>ÝÿôËïù†ø÷ðÿ÷Dßì(Mòÿýùˆø ù÷Ä~_*”wDÃùˆø÷üœ q}0Z‡µÕê‹øñáÀ”e:6ª;r´âûÿÿ‹øûÿþêÃ…=/d )M”ô‰øúÙr.XÃ"M¹ù‰øùõÊ0€ Šÿ-ˆçòÿÿü÷‡ø÷õÿÿÙ™ÿÿEiùÂÍê߸ò†ø÷ü…lÚÿ­<ÿÿq>©ÿþú„øûþÔ «ÿìª~ÿÿÿL\ÿÿ°Óûùø÷üù÷Êóÿ˜CK4¡€ÿpëïiáýæôüÂëÿªEÔÿI€cÿÿH©¿'pÿÿƒæÿR–ÿÖ—Ð;ÿ‚ÿæ#Bm5íÿ¡ Óù%BÿÄR`„ÿº8€ ºÿu­ã&þž'v†ÿt;߈€‚¾廀5ˆÿÿb QUŠMÝtTÏŠÿÿ›t`)E3‡˜ÿÿ ÿµ‡SF**;Zf™€ÿƒÿˆÿ‰ÿ†‘ÿ€ÔÝÕÊÈÔÛÿ€ŽÿjßÁµ¬³¶º³®³ÅÑmŠÿÜÀÊѱ¥¥´¾¤§¥´Í³ÍˆÿÇ­ª¦ÌÙ¬£¾Ë¤§¥¯Ù±±Ââ†ÿ¿³§§¤ºà¸¢ÈÕ§¤¨ÌÜ®¥°ºç„ÿ½¼®¤§¤ÀཤÑÚ«¯Óàʦ¤©¼»èƒÿÒ´«Ï»¥£ÉßÌ©ØÝ¸ÒßÔ©£³Ð³°Áÿⱦ¥·Þ˪ÄÞÚÀÛÜÑÜÞº¥ÂÞ䦯Íÿ ¼®¨¥¤ÇàÖÆÛƒÜÙ¹ÐßÓ¨¦§¨ºÎÿÿÖÃÔÖÁ¥¨ÕÞÜÛƒÜÛÛÝÛ±£¥¤¤ÈÖÿÿÌùÓà̯¹‡Ü ÛÝÍÁʹÈÔ¹º¨¤«ÖßÛÒÚˆÜÚÞßááܶ¯éÿ³¦§¤¶ÛÝÝ‹ÜѺ¯¥¯ÕÏ«¦¥¤£´Ñ‰ÜÛÝÇ«£¢¤¥±Ìͬ±ºÃÍÔÙ‹ÜÛ×ÐÆ¼²³·à¼¿Î×ÜÞÞŒÜÞÝÙÐú´Âª¥¥¨¯¶ÆÛŠÜÕ¾°ª¦¤¯Áá°¦¥©¬¶Î‹ÜÛÒ°¤§¦±Õ‹´©ÄØÛÞÞ݉ÜÛÞßÖª¥¦­Óÿ¾ÃÜÐÓÙÖÎÛ†ÜÛݽÕßÌ«­¹ÿÍϳ¥¨¬©ËÝ݆ÜÝÔ§©ËßÙÔÌÿÿU»ª¦§£ºÞÞÌÔÜ ÝÜÛÒÛßÇ£¦µ·´Ù€ÿ˱¦¦«ÙÚ¼«×ÝØÛÝÐÙÝË´Ôß¶¤¥­Çÿ¼°¥ËЮ¡¾ÞÞÂØÞ·ÇßÔ¦©ÇÓª©¸ÿ‚ÿæ±»¾¦¤²ÙßɨÔÜ®´Þѧ¥¤¸½­Ù„ÿæ´ª¦¦ÎÞÀ¦¤Ìר®ÞȤ§§¦¯Ì†ÿɸ¯¨×㦤ÂÏ¥©ØÏ¤¥«¶ÐˆÿÒÆ®Ð¸¤§¥¸Ä¤¥¶×IJÂíŠÿØÇ¾²­«´ºª­¯±ËÖUÿ ÝÒÁ½°°¸ÃÆÚ€ÿ‡ˆÿ‰ÿ†‘ÿ€Éâåßßåçÿ€ŽÿUåäØÍÙĶÛÐÑÍÙ‘ŠÿëÛ‰L¨ÐÏ™uÒÊϯiÕãˆÿÝÎÐË?·ÖsCÒÊѬµÙÛÙ†ÿÜÜËÊÔŠÚMÈÑÅA¯ÎØÚç„ÿݦ­ÔËÓlvÕ,º«$GÌÒ¿™ÔèƒÿáÚ¹5~ÐÖJ@ÁŒ) ÁÖž0›ÛÚÿçÒÍÒD¾_ j,‚ÐcaÔÊÓáÿ,àÓÆÑÓQU †.&ÆÌËÎ×ÂÿÿÿŒ%iÐÀ£ÙÓÓÒ‹ÑÿÿÒ•„%?®†… >iIg„P9Ø ÕÖÕ¹( … –ÖÿÿÒËÊÒ€ˆ.g€¬ÐÑæßÎÏÒÓÕ˜.‡P¼×Ü×Î×ßäÁ¦…`: Š1V|ŸÅÒï½p<€‹€/bªÒÖÎÓÑÅ­V‡r©¿ÎÒÚÚðÐÌѸ7‰)§ÒÊÊÔæsÓÎ`€ˆ½ÐÌÏáÿæ/&8…cxA¼ÂÄÿôfšÑȸÁD€„* ÇÀB T¾ÿÿ¼ÒËËÖ„?!)RÕʘÂÿ€ÿåÔÊθ y½0 C˜ “ÓÐÛßÿÖÖÎE2®ÞtfTÍÂT%¾ÑÓÿ‚ÿæÖ uËÕ¢ JÅ!±˜.ËÎÓŒ€Ñè„ÿìÄÖÌÍ6oÌÔ@Ç®MÓÊËÓÅ׆ÿéÔÖÆ_×ËÓe3ÒÀ5ÔËÐÓäˆÿÒÜÕUˆÒÊщ_ÓÐvÒÛóŠÿóÀ©ÙÓÔ³×ÑÛ¾¥ÖUÿÿãØ×ÊÇÔÜÜÿÿÿ‡ˆÿl8mk-cbbeA P¥éûÿÿÿÿÿóÀY3ÉÿÿÿÿÿÿÿÿÿÿÿÿÊR{úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬”ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©,õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâ,øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿd„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJ øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿj9þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿg&ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿh"øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\ Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö)Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷D)ÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøGÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷L”üÿÿÿÿÿÿÿÿÿÿÿÿÿÁ+.¦÷ÿÿÿÿÿÿÿÿõ»R &\Œ¶³³µ£_#ich#HüÿÿÿÿÀÿÿðÿÿü?ÿÿþÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÀÿÿÿÿàÿÿÿÿðÿÿÿÿðÿÿÿÿøÿÿÿÿøÿÿÿÿøÿÿÿÿüÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿüÿÿÿÿüÿÿÿÿøÿÿÿÿøÿÿÿÿøÿÿÿÿðÿÿÿÿðÿÿÿÿàÿÿÿÿàÿÿÿÿÀÿÿÿÿ€ÿÿÿÿÿÿþ?ÿÿüÿÿøÿÿðÿÿÀþðüÿÿÿÿÀÿÿðÿÿü?ÿÿþÿÿÿÿÿÿÿ€ÿÿÿÿÀÿÿÿÿÀÿÿÿÿàÿÿÿÿðÿÿÿÿðÿÿÿÿøÿÿÿÿøÿÿÿÿøÿÿÿÿüÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿü?ÿÿÿÿüÿÿÿÿüÿÿÿÿøÿÿÿÿøÿÿÿÿøÿÿÿÿðÿÿÿÿðÿÿÿÿàÿÿÿÿàÿÿÿÿÀÿÿÿÿ€ÿÿÿÿÿÿþ?ÿÿüÿÿøÿÿðÿÿÀþðih32A¿ÿ…ÿ€ÿÿÿ¢sˆi_`_xlßÿ™ÿЈl=& =9[œ³•ÿÿŸt)€?„ƒ‹\R·’ÿÿ›OIÖ÷‚f¼‚Ê )wÿÿÿe$€)êÿn€”ë‹ÿ:PÐÿÿÛ] «ÿÎ Ãý8àÿR€Fµ‹ÿÑC€ œÿàçÿ`€ 1Ìÿø3'š‰ÿ#é?G5¹ÿî$>øÿ‘pîÿÿ«W5ˆÿÿhÁsßûÿWeÿÿ¿lÿûÿÌ€;ÅVA؇ÿ ˆOÿ¶+îùÿª˜ÿûÝ5çûøö? ~ü£€Eÿ…ÿ'Ì/˜ÿénáüùô@¿þùí£û÷ÿ°<Äÿàr„ÿÿ[€#Úÿÿ³( ÿ÷üÖèùø÷ðù÷ÿU}óÿýX3Úƒÿš € SüøÿáŸòø÷üù€ø ù÷ùî^¾ÿùÿª€ÿÿÿ_eÍàÎn€ ÿ÷ûúõ‡øõóÿ÷üæ €*°ÿ³ŠÐ×ýÿÿ–ãü÷Šøùøøý^% »Š\ƒÿ …3SåýÿÐ]\ûŒø÷üljÖéå ŸÙÿEGÿÿÿÿa K÷ùþÿâ¹îù÷Šø÷øíÿýûûÿ°(Õÿÿð-”ÿ÷øüÿùŽøùø÷þÿøëß’nÿÿ·&€¶ÿþ‘ø÷ùÿÐx8 „ÿÿ€oÆóøùóu‚ fÿÿ2 %Mp¯ðù÷ø÷ùòº‹_6=ÿÿÿu&Is¢Ðïýÿÿù‘øùþÿÿöß¶…V/,ÿÿ1ˆÉö€ÿýú•øùû€ÿþÞ¤U0ÿÿÿyExªÕðÿü÷’øó⺆X/3ÿÿMƒ %MÈý÷ø½U„PÿÿŠ‚%Žïù‘ø÷âr€vÿÿÓ(Gq„·ïÿù÷‘ø ÷ûÿ€j€ÿÿ;°ÿù÷øüŽø÷ùÿÿùúøF‘ÿÿÿsžÿÿûÿýÎòøþtÄúýþÑ€'Þ€ÿ…5ñ¹S;UЦ”N þ÷‹ø ÷üØNÑÿÿÖb>ln‚ÿºt³ ƒHúù÷üû÷‡øûø÷ÿŸ²€ÿùŒ‚ÿ‡6 Ôþ÷ÿÙØû÷ƒø€÷ßüûøüS [’†7Cÿ‚ÿÅ)€‘ÿüþ¤%Áÿ÷ùù÷øøúù÷ý¾sêÿýÙ‚ ˆ„ÿ(~A÷ÿä`%ñùúåäùøù“ëùøø4'¹ÿÿ–Uÿ„ÿ'ÿ< Îÿ¦!…ÿ÷ÿ¨«ÿùð&“ÿ÷ÿloîÿC¦†ÿ´/ˆî`€-éûúø<ÿü×1óùÿo€-¾Ô Œÿ‡ÿt ;ž!€ÅÿýûsUÿÿ­ÈþýM{wTÿˆÿ„<ŽÿÿÜT.òÿ{¤ÿí"€*TÅŠÿ ÿO ÔÿÄ€ ØÿN“ÿâ€DÐŒÿ~4Þõ1¯ø'aÿö4têŽÿÿ¾P ºÕƒÞ ±ÿ¶:ÿ‘ÿÿ‚3MÈ€Yª„ب?fÛÿ“ÿêt€A‚2i‚ /¶ÿ–ÿÒ¢Œ<1(1$60cxÓÿšÿÿÿí«wJD_™Úÿÿ¡ÿ†ÿ¿ÿŠÿ€ÿÛÌÔÈ€ÄÎÖÌò¹™ÿÞ×ʹº¯©¨®·§ª¬´ÀÃÝÞ•ÿëÚÏʱ¤¥§§¥³Ã¤§§¦¤§Í¾Àä’ÿÝ¿´µÕݦ§§¤¼Ï¦¦€§¤ÂÓ®±Ìáÿáȹ¦¦¤®Ùྤ§¤ÆÚ©¦€§ £Äß±¤³¿ïÿ íŲ¥§§¦¤ËßÓ§¦¦ÐÞ±¥§§¤¬×Þ·¤¦§Ää‹ÿ㻪¦€§¦¤Èß׫¥«ÙÞ»¤§¤°ÓÝܰ¥§§£·Ü‰ÿÿºº°£€§¦¦ÎÝÚ­¤³ÜÞŤ¥¾ÚÝÞ̦¦§¥©¹ºÜˆÿ%ÒÈ«ªÐ¿¥¥§¦ª×ÜÞ¹¢¼ÞÝФ¾ÞÜÝÓª¦¦¤²Ò¸£Àñ‡ÿÕ¶¦¤·ßή¤¦­ÚÜÞË¢ÇÞÜ×±Ù€Ü ³¤¥§ÁÞÊ¥§©»á…ÿ'î·¥§§¥ÇàÙ¾¥¨×ÜÜÛ³ÐÝÜÚÊÝÛÞÌ¥£²Òà׫¦§¦³Ì„ÿfÄ©¦§§¦ªÖÝÞÍ­ÉÞÛÝÕÙ€Ü ÚÜÛÞ·¥ÁÛÞݹ¤€§¥¸ñƒÿÙ³¦ª§¥§¤¸ÝÜÞØÈÚÜÛÝ‚Ü ÛÜÚºÏÞÜÞË¥‚§«Ð$ÿ?ÆÀÓ×Ó¾¥¦¥ÉÞÛÜÜÛ‡ÜÛÛÝÛÝØ¬¤¦€§¤®ÑÞÿáÏÔÕÝÞÞǨ£«×ÝÛŒÜ Ûݺ¦­¬§¤¤©ÎÍÇÿÓº¨§·ØÝÞÔ»©ºÜÛ‹ÜÛÜÒÃÕÙØÑÈÈÕà¶¼qÿÿ?Æ€¦ £¶ÜÛÝÞ×ÏÚÜÛŒÜÚÞÝÜÜÞßÞàÌ¥µñÿÿ𳦧§¦¤ÆßÛÜÝÞ’ÜÝÞÜÚׯ©¥´Ìÿÿä¼¥€§¦©ÎßÝ“ÜÞÔÀ²¬ª¥¦¦ªÓÿÏ´¦§¤¥½ÑÚÜÛÛ¾¥¢¤¥¦€§¨Èÿ´°¥¨­¶¾ÌÚÜÛÜÛÎÄ»±©¦¤¥¦¨»3ÿή®µ¿ÉÓÚÞßÝ“ÜÝÞÞÜÖÍø°­³UUܳÄÒÜßßÞÝ—ÜÝÞßßÞ×ʼ³ÿЬ¤§¬´ÀËÔÛÞÝÛ’ÜÛØÎù¯©¦§¶ÿ½²¦§¦¥¤¥¨­¶ÑÝÛÜи¨¦¤¥¦§§¨¿UÿÓ¶¦§§¥¤¤¥­ÅÚ‘ÜÛÜØ¿¦¦§¨Îÿ¦§µ¾ÃÎÚÞ•ÜÞ¤¦§§¦­Éÿÿ‘·§ªÍÞÞßÞ€ÜÝÜÛÜÜÞÝÜÛܵ¤§§¦¸Ôÿÿf̧ÉáÝÝÞÝÓÛŒÜÛÝÈ¿ÑÝÜÝÔ¬¤¥¥±î€ÿÔ¼Ûϸ³¸ÄÊÆ·ÉÝÛ‹ÜÛÝÕ©¥¶ÔÝÝÕ»´ÁÆÿÕÆÎ§£¥¥¤¥¡µÝÜÛÝ݈ÜÝÜÛÞɤ¤ªÍßßáÝÑÙ‚ÿѺ¥§ ¦©ÕÝÛÞÖÕÜÛ„ÜÛÜÖÝÜÜݸ¤¥§ºÆÃ²»ï‚ÿ沦§ ¤ÅßÜÞÊ­ÑÝÛÜÛÜÜÛÝÏ¿ÚÞÝÖª¦§¥¤£¯Ó„ÿÒ´¦§§¤³ÜÞ׺¤­ÛÜÜØØ€ÜÅـܰ­ÏÞ߯¥€§¦Âß„ÿ'ṩ§¦¨Óßʬ¤£ÂÞÛÞËËÝÜÚ¬ÆÞÛÞ½£¦¾ÚÞ´¤§¥³Ý†ÿ㺦¤ÄÚº€¥¯ÙÜÜݲÁÞÜÕ§°ÛÜÞ½¤§¤¯ÐÕ©¥¯Öf‡ÿ ̪³É­¤§¦©Ñ€Ý¿£¸ÞÝÌ¥§ÒÝݶ¤§§¥¦Á¿¬ÁÔˆÿÑ»§¥§§¥ÅßÝ׸¥¥¯ÛßÁ¤¤ÊÞÚ­¦§¤µ¿ÜŠÿj¿±¥§¦¨ÕÞÑ«¤§¦©Õß¶¥¤Æßت¦€§¥¬½ÜŒÿп§¥©×ܰ¤§§¦¥ÌÜ®¥¥ºÞܱ¥§§¤¶ÌÿŽÿ 濳¥ÏÕ¦¦€§¤ÃÖ¨¦¦§ÍáΨ¥©¿×Ò‘ÿéÒ¶¾Ò©¦€§¤¹Ì¥¦§¦©ÂÖоÇó“ÿÿÎÉ¿©ª¦¥¤°½£¦¥¨©±´Ïâs—ÿÜÝÔ¸µº´´¸²·À´ÇÍ通ÿöà̾»ÅÖñÜ€¡ÿ†ÿ¿ÿŠÿ€öèßæÞÙÙÜâæÛõ­™ÿÿÿæÕÛÔÎѺžÕÏÑ×Þ×çÿ•ÿå礑®ÑËÊÊÐbÓÊËÊÉÌr¬ãë’ÿèÙØeÌËÊÓ{6Í€ËÊÕb&ÑÑàáÿáÝÚÌÊÖ®uÒÊÔVÀÍÊËÊÖ] ÑØÙõÿÿÜ×Ê€ËÔB&ÇÌË/£ÐÊÊÓ·ŽÓÉÍáï‹ÿãØÕÊËÔN»Ð»ÓËÔ¨)§ÐÊËÌÜä‰ÿÿÛ›¢ÕÌ€ËÎ6 °ÕžYÔÐs CÌËÊÒ‚ÑìˆÿÃÞÔº0rÍÐÊͽˆÜ{2Ôv€ '¾ÎÌÕ .‰ÑÝö‡ÿ&åÙÉÓ9­Õϳ DÛS¥›ÒÑÈhJÑËÏÖ×…ÿóÖÊËËÒRvÏÃ3 H€ >ÒÖŸ.ºÏÊÊÙà„ÿfÛÐÍÌÊμ;³L€ŒÑi‡ÓÊËËÊ×øƒÿ èÞɼÈÓËÓ‹€K€ ƒ3€DÏËÊÐßÿ?à€&&vÐÎÐL…¶ÔÎÌËÊÒ©—ÿÿÿ’€TÃÙº‹ƒÌ²·ËÓÔÁ6nðÿã¹ÃÊ‹%ƒÃ„Œ+_/NM•áUÿÿ?ÜÑÍÌ×’€7 ‹ … @ÌÕôÿÿÿÑËÓVWÁÍØÞÿÿïÝÊ€ËÍÂ:€‘#n µ¿ÑÍÊÏåÿãØÊËÒÏu,qÏÝÖÐÍ€ËÎßÿÒÖÍÒÔÒDZ‘r? 8^€¥ÁÎÔÓÏÏÕÿãɰ•pK$ ’€:aŠ©ÀÏ€ë§^*ƒ”ƒHŠÌÿàÖÑÈ·˜kD ’8a†ªÃÎÔÔÿØ×ÊÌÎÒÓÐų‘)Ž3‹ÄÏÔÓÐÍËÎÙÿãÙÊËÌÒÔÔѲ[ ‘rÎÌËÎãÿõÕÊÎÊ•tc9 “fÓÊËËÊÓÞÿÿ‘ÓÏ¿@‚—ÕÊËÉÛåÿÿ3àÔN‚$‹Nr.€#¸ÕÑÓÏî€ÿ ðÄ7‹ˆ_GW‘K ÂÑ#~›zÂÿÿª9ÈÔÑÓÓÒÜ–ˆLÑÕ¼=€~ò‚ÿ ưÏÊËËÊÍÀ!€„ ‹ÓÎȆWcžÜï‚ÿÿÔËÊÓY€Iµ0€2r¼ÎÌÓÔÔÜæ„ÿ(æÙÊËÊÓ›‚Õ±X¦°7TÒÊÊËËÙß„ÿ ×ÔÏËÍÅ&GµÔ×b€GC µW€ xÚÌu ™ÒÊÊÕë†ÿ&îÙËÓ` ÏÏѬ¢gɧvÓÌÔ¬4"ÂÌÔæ3‡ÿ ßÔN´ÔËÍÁ.€pÚ‰BÒÊ*’ÒÊÊÑËkkÔÛɈÿ#ç¸ÈÏËÊÒZ‹ÒЫjÔÒG ³ÎÊËËÌÒ´ÌÿŠÿUàÖÊËÌÆ!.¹ÔÊÌÄÒÓW½Í€ËÊÒÝÿŒÿãÞÍ˧ÓÊËËÐ@±ÎÓ€¥ÓÊËÉÚàÿŽÿïØØÏ6 ËËÊËÊÔcÅÌÌÈ><ÄÌÏÞæÒ‘ÿáãÚ %½ÍÊËÊÒ‡EÐËÊÎÃcJÃâù“ÿÿê©¿ÒÏËÉÏ¥vÓÉÉÍÑàÌÐè\—ÿÿìæÕÒÛØË½ØØßÒÞàÿ€šÿÿîÝÖÝÝçõЀ¡ÿ†ÿh8mk :PyÐÌÌÌÌϲPR7nÏúÿÿÿÿÿÿÿÿÿÿÿâ¥/(›ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû›'Zæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø˜#"šÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞSÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿsÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿuØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿp"Ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\ŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLQÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿNNÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJ#íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ\ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ†àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[ Ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾%òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿe‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ Øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿk\ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ pÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿФÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ tÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓyÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØSáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”"#–÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏU%žúÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÊ[ 4lÌÊýÿÿÿÿÿÿÿÜÊl/:LKKKKKMit32K—ÿÿÿÿÿ©ÚöäØÂŸ…š¾ÂÉàôìâÿøÞ¤„f:„zpbbQNOQaS€N _bgwŒWZršØöÿØ ÿî½{¾ÞÅu[,  2 ‚  ‘¥A½ÿ¶ÝïžH=k¾ÝÜÓ¸u.‰ Šø}) Y²õž A¸™ˆªÀÁ°?DäöýûöÓ¤5‰,´û? 7œúñk A…½¿ßn:, "Rœâÿùöê¿<†>Øý¼S'õüÆ9 $?våé¹™œ¬U„ c³úøüüñx… JèþÏaŒ'õýéR€Z¶¾¿¶ÿ™‹† >ãùøùÿòY!…_úÿéyŒ8œúúÿ}>‚’±wÿÿ³î›8 ‡ †øù÷÷ÿ¶V…2Šÿúù"Œl½þ÷ÿ^ƒ ;üî±´Á`4Š Lðø÷÷ûë‹(„E¦ÿøý«M‹ °äþ÷ÿ³t… &wÛé¯̯—* ‹0è€÷ùû¡?„P·ÿ÷ý¹dŠ4Ñóü÷ÿ·x†8¬ÊÙ­”ª™Œ Óôù÷÷þ´]ƒgØÿ÷ý̆‰ ®õû÷÷ÿªkˆÆ»ÿ«švŽ Óôù÷÷þ¿pƒîú÷ý㯈 '™ÿøø÷÷ÿN‰?ÂÌ©›1 Óôù÷÷þÇ~ƒ 1šüø÷ùëÄ…!ŒÀòøùúo1‰ )¸¶§™“P2Ž Þöù÷÷þ͈ƒ H©ý÷÷øôÖ*‚ ?ˆÎéû€÷øúÙL‰ 2c¬¿¥Ž @F -éøø÷÷þÓ“ƒb·ý€÷ùãA-ìûü÷ø÷¨(‰%7I𮶤™‰N´(Œ Põù€÷þ㯂Ñý€÷ûíh pÎÿúø÷ûüÕ4 ‰4­­8k£ Ãh 7¼àl/Š‹øù€÷ùòÏ€«áý€÷ ûóœ¨Ûø€÷ýøÝK † Û¡iHßÈŸ¿ßw9€yò¼Rˆ£úù€÷ øøá< ¾êú€÷ ûöµ `Ùòûø÷øÿφL|Éàj2€!•îïÿî»( *Êùê¶V#†¼ûù÷ ûït!Öôù€÷ ûùÐ )»öúƒ÷ûç5†"f­âý¯,8ËÒîçFƒ bèýüëŽ. „Ôýù÷ û÷­ ?çû÷ùøë5x÷ø„÷þ™E…  %‘æÿýîN„clœuq…¡Üþú÷Êz1„Ôýù÷ øùå3 {ïû÷øøþQ<Ûýø‚÷øùâ9…&mÕ÷úüð‡…t››Â‡ BòúùóÝ»`‚Ëüù‚÷øöŒ!šóû÷øøÿpFmøùø‚÷ùø˜‚ n§Ýøùýé¿%†,Zß™ò¥x‡ tÖûøüûìŸI ¾ûù‚÷øú½9 °öû‚÷øÿ‡e‡ÿ„÷øñf ‚  K¬Üþýøýч=»™î_$‰ 1ˆûøøùúÿÛk8 €Ÿùù‚÷øúúq3Õúû‚÷øÿ±›±ÿƒ÷ùõÙ€  %âüüù÷úò”1‰EÌÿ—w!‰3¼ûù€÷ üòÕ‚ löù„÷ÿΘ?îøù‚÷øúÖÐÛÿƒ÷ý逅¼÷þø€÷ÿ¥E‰»•Ôß0 ‹Vè÷ø÷÷øúõà¦I-æ÷øƒ÷ùðܲó÷ø‚÷øøïíðùƒ÷ýÙ^€ U¯ßðùùø÷ùû×S‹XÝô”¤¨‹£èú÷ øúê°xB­êú„÷øôéö÷ ùøÇ17e·îùú€÷øúöˆ$‹´È“ÌŠcVÏ„÷þÿÐ!xÛúø„÷øø÷ úîµ 9Åÿùø÷ø÷â? Ž|•ì’­‡Ùþƒ÷ùüúÔo¹Ýú™÷ÿÕ˜hß÷ÿøƒ÷ûäŠ ‰í’xk"I€ph1 …+•òùø‚÷øøúâ×Ýø™÷úÜŤíö€ø‚÷ý쩎By¦‘ßr7Fs‹©€¿»›xD'„_µýøƒ÷øûöëìø™÷ùìäÜûùø‚÷øøüÂgŽ%„}oö¿Ðo(˜Ùðÿ‚þå•`„-nö÷ø„÷ùùø›÷øúþ…÷øúï'JÇ„GêînD0Ôýÿþø€÷øøÿÿ䃴öù°÷øÿ I ´öŒ)›™ÚöMv»€úûÿþù‚øöçž' ‚9Ü÷ø®÷ùúÙ7xööˆ RU »°eÀmko€Æóüü€÷ø÷í·u- Šæü­÷øúìb&?]lon`A‚ d”áÿé|#ÏÙŒ™Ž\uŽN/-1A‡Æäøù€÷øýê²h+€UÍóù¬÷ úöÎ7.Cb}ª®¬ŸYG1.(()1Y¢ËþÿÖn Ã΋ÿªj"ƒBÚþ‚÷ þÿî±N Íþ¬÷üäˆ5§Õõ„ÿóæÉ¹ª¨¬Êóýþøÿ¨N Ž‘‹òè3„Jãþù÷ øúûóÉšp8&bðúø©÷úèÒ«éùúù„÷ùúüû€ú üúøøúÿY!KH‹ÎÆnðùø÷ øùùóèÝÊ­—¦åùø©÷øñìçùùø…÷øøƒù øøùù®"®íŠª¤ ˆ8Îóú„÷ ûýýúêÏÎèøøª÷ôõúùøŽ÷øùöæq€¯ãŠig‰qÜû†÷øúÿÿþú­÷ø‘÷úøäŸ¼ŠHH‰¦àþÈ÷ùûƒÿö£jƒXs‰îµŠ;yøùøÂ÷øùþþùóâÐÎÅ·E ƒ;M‰ا ŒC¹üûù¿÷ûû÷îѸ™Šwed_W@…%K숽mêûúøø»÷ øøüóàÇa1‹L숚u PÜ÷þúº÷øûþâ˜L‘;߈šu  9Ìúþþûøµ÷øøÝ‰0 ’2ƈ„e‘7h“±Ïäï³÷øøóÆ‚< ”,®ˆjQ’ .d Éäøø±÷ øúì›> ’%•ˆI8‘ !>e•Âäúø±÷ øúñÛ¾ŸlG*‘nˆ2'‹ 0H|™ÂÕçóöùùøµ÷øúûúöôèÙ»pX5‹nˆ2'…-Je~˜¸ÉÒáèôöøù·÷‚ùøöñéÞ×Í´š‚kN/ …Q‡õ=$ #.8Ol‰£½×ðûþ€ýûøÀ÷øù‚ýïØÂªmM>-$ H‡ ùY 2Mq—¾Òì‚ÿúøË÷øúúÿ úèØ¶™bH2 H‡õX-Q£Öçóöùûüþúø×÷ úýýûùöóîÏPH‡ú]*>T{”±¿ÏÚæïöø‚ùøøÁ÷€ø‚ù÷óðèÛÎı–t^J,H‡ÿb'ƒ ;b’°Ëæô÷øûýúùÁ÷øøùýûùöóàÌ·™eB-„Kˆ2'‰ +Mt¸Ôñúÿýù¶÷øûÿ ýï×°•e> ‰nˆF6‹ #=So’ºÚëóöµ÷ñä̰—z_3  ŠnˆZE .AYk¶õøø°÷€øçÊŸjI4$ !…ˆnT– C‡öøø³÷⾋F" ’(ŸˆnT•O©ìúø´÷ü€ÿÕŒF’1ˆ”q’L©Ýó€ø´÷€øúøñÞŽ2ˆ­„Ž ;V{¬ßõúø¹÷ùûûöÑx$  @؈Ș† +Sˆ´âÿþù¾÷øþÔT!ŒJîˆîµƒRqŠš§´ÂåúÿÿþøÂ÷þÉŒ)5‰ÿN.‚ iÓñöøùúûüþúøÆ÷úÛq‹QjŠ]Z^“Üø…ùøø¸÷øùøˆ÷úóÍ8ŠlŽŠ},—Ëþýø÷ø­÷øõô÷ùøƒ÷øùîh ˆ‚«Š» €žêþø’÷öõ«÷úæßàó÷ùûú„÷ùüÍ( ˆ §ßŠ êà Kïø÷÷øúý€ÿûú…÷øøÿúÈÄìùø©÷ ÿÖ *G¨Öøÿûøƒ÷ü˜E‡-JÔŠÿÌ=ªúùùýþðæÞßçôùþ„ýþúÞ†“³úøø©÷ ùóÊK(:²ùø‚÷øøýl,8^¸úýúøøÿ×n‰ 3äÞ—ßZ,ˆ 2ˆûùøø÷íÅxH‚>Ëùù‚÷øþÛx¾óù‚÷øÿ±)}ðùøƒ÷ÿƒ9€ ${Êð÷ùøýó•4ˆ^ù阛t‡ tàÿ÷øøí©7 ƒæýƒ÷øüÌE ôû‚÷øÿ$Îûûƒ÷ÿ¡J‚ 8¶àùú÷ýÔ“‡ 8šNB‡ yÄüøÿó°d ƒ&Þöùƒ÷ÿà¡‚ðû÷ øøÿg ~ðûƒ÷ÿ­Qƒ X±øÿùùäK †OiÌ›¶±ƒ -ÉðÿûÉt:……ôø„÷ÿ¢c [ëû÷ ùùõJ /Øôø‚÷ÿ®Q„ 5rÎôþ÷½(„5²Øœ×Ót íùå®`% …HÑúù‚÷ øùÜ]'<áùø€÷ úùã0 ¯áû‚÷ÿ§M†#cªÝúðq‚Óÿ£Â) 1Îïâ²V†@ˆÿ„÷ øõ¦(#Õôù€÷ûù΀†Ìþ‚÷ÿœGˆU§ãø¸37ÓÚ šN$ ÿ®^ˆ4•ñúƒ÷ ûúÈ%ºêý€÷ûô£F§þ‚÷ÿz4ŠLÇø{<€ÄÌ¡ ‘eV5jÉe †!·äýø÷ùþæ»-”Ôý€÷ûð„ (ôù÷÷øùúX Š  ¿¤!Eнÿ¢kb5Efy(ˆqáõú€÷øûúÏš_ ‚Èý€÷ûë] ~æý÷÷ùüî>Œ8z}DEfš¥{yHM‰Âùû÷÷€øùâG ƒ i»þø÷÷úä7 n×ÿ÷÷ùýÝ(Ž'=W‡š¦ÿõx‹Zõø€÷øþõÊ;… 4þø÷ùôÕ‚cÎÿ÷÷ùüÇ‘ “”§ÿîjaJŠ"’øø€÷ÿ‹!†‡óú÷ý泃[¿ÿ÷÷ùû¶"ˆªªj^J‰ .¾ûø÷øþ¾L‡lÜþ÷ýÖ—„T²ÿ÷÷ùû´ŽYv™ª¬jb'†1Êü€øõ…‰_Îÿ÷ýʃ„ M¦ÿ÷÷ùû¼‹2{𝙛# „ 4ÊüøûùÌŠP·ÿ÷ý²Y„ =Šÿ÷÷ùýÖ$Š /®¿°ÿ™¶m…1ÊüøûëX‹6ÿøþŸ7„ FòúøøúøPŠ#XÕÌÿ²¿»¢Oƒ(¥úúôÖ'‹$uÿúòˆ„ œøùøøþ¢JˆY£ÐÞÿ´ìÍi2 ŠøûðË‹eúûçz… aåöùøýÍs…4{Ëÿ¸»ÂQ€Vñÿ꺌 LéþÒb‡ Ÿåùú÷þÃx G»¿» Ìâ¦] ¾ùê» Œ3Ìü°Kˆw²€ÿ ûî¢?V«ðÝÿ¼ 餗Æn8Öóß$Œ&Ÿù‘7ˆ"Y½æóùóÏxIbÇͬÿÿ¿ Ïß{qd5{ºØ]Œ†÷u$Š "Zx‡‘“‹sowmÝëÅßÂi).x¹‹ŒkóZ *7JdŠßÊîß~Q7P ‹FÖDŽ@¢êîÌ ÿÝsÔܶg:#‰&¢+‰ 3‰¾²9”îÿÏ öòÂrŽpN:) „i„  8Mlk6šÔÞ×!ÿõÚštP1- : 13:n˜ÎßáîíǦœ–oo\‚JNoo¦ÄÄêíæÿÿ̪™ˆffUƒDffˆªÌÌÿÿÿÿÿ«ÿÿÿÿÿ©ÚüõñééÜ…Ûèéëóûìâ ÿÿòÞÒÈ»ÓÑÎÇÇÀ¿ÀÁÆÁ¿ÀÀÇÈÊÐÖÂÄÌÚðúÿØ(ÿÿæÍçôëÙÏÅ´®©§¤¢¡¡¢§°¥¡¡¢¢¥§¨¯ºÂÉÖëôóÅæÿÿÔÿúìÔÆ°§€¡¢¤ƒ¦§­Ä­„¦ ¤¢¡¡¢¨´½ÏëûúÐÿÿìÚʸ¬§‹¦§±Ï²¦¥‡¦ §¤¤§³ÅÈÐôÚË ÿóÝØÊ¿µ§££¤¥ˆ¦¥§µ×·¨¥ˆ¦ ¤££ªÅÈÈ˾ßéÆ ÿÿÕðí×½­©§¥¦§§‰¦¥©»Ü»ª¥Š¦ ¥¨ÊÉÁ¬»ÙÞ´æÿÂÿóúÞ¿¸¾Î×ÖÓο°ª¤ˆ¦¥«ÂÞÁ­£‹¦ £¹ÎÝȤ£¨¼çÝÝÔÀçä»§¥¨´Æ×ÜßÝÝÔɱ£ˆ¦¯ÎÞDZ£‹¦ £±ÇÜܽ©££¦»Ôé½Ôó˸²§¥¦¦§ª·È×ÞÜÜÙϲ¦¥„¦¥¦³ÕßÏ·¤‹¦¤®ÅÛÞѲ§¤¥¨°»Íõô¹ÝÝà­££€¦ ¤¢ª»ÌÝÜÝÝÛÀ«¦¥ƒ¦¤§¶ÙßÓ»Œ¦¤®ÅÛÞÙ·ª¤¦¢¤­Äæèß¶ÿÝÒ×®£¤„¦£©´Ø€ÜÞÚ¹¬£ƒ¦£©»ÜÞÙÀ¨¥Š¦£²ÈÜÜÞÁ²£€¦¥¢¯ÚäÌÿÿ³øÚ·¤¤‡¦ ¤§ÂÝÜÛÛÞ饃¦£¯ÄÞÜÜÅ­£Š¦£¼ÏÞÛßǸ£‚¦£§¹Òÿÿ±ßéŶ¨¥ˆ¦ ¤¥·ÚÜÛÛÜØÄ®¤‚¦£³ÊÞÜÞ˵£‰¦ ¥§ÌØÞÛÞ;£‚¦¥¦©°Ïòô¯îáÛ³§£‰¦¥¦±ØÛÜÉ´£‚¦¤·ÎÞÛÝ룉¦ ¥±ÔÛÝÛÞ;£„¦¤¥¸âìï­ÔÞÛª£¤Š¦¥¦©ÔÚ€Ûßꣃ¦¼ÕÞÛÝÓ㇦ ¥¥©ËÜÝÛÛÞ˼£†¦¡®Üêîÿ«ÛϦ¤Œ¦¥¦©ÔÚ€ÛÞн£¦ ¥ªÂÚÜÛÝ×Ë¥†¦£¥®ÇÞÛßĵ£‡¦¢©»éî©Èݱ§¤¦¥¦©ÔÚ€ÛÞÒ£¦£°ÈÝ€ÛÙÒª…¦£­ÄÐÜÛÜܾ¯£ˆ¦£¦±çÚ§ÝÙÀ±ª¥¤Œ¦¥¦¬ÖÛÞÓ㦣µËÝÛÔ¯¥¦¤¥¨²ÃÓÙÝÛÝÔ¶ª¥‡¦¤¦©±Éâç¥ÏÓÓ¨³µ¬¤Œ¦¥¦¯ØÛÞÔÅ£¦£»ÎÝ€ÛÜ×´¥¥€¦¤¨°ÄÙÝÝ‚ÛÝÊ®¥ˆ¦¥­±¶©Üâ㤠ÛÖ¤£µÁÌ®¤¤Š¦¤¥·ÜÜ€ÛÞØË‚¦£ÄÓÝ€Û ÝÚ¼¦¥¦¦£ª¾ÒßÜÜÛÜÝÔ±§¥…¦ ¥¥£±Ë˲¡ªËé£ êÈ­¤¦¦°ÏÖ¼¯¥£ˆ¦¤§ÄÝÜ€ÛÜÛÓª¥¦Ê×Ý€Û ÝÛǧ¥¦¥ªË×ÞƒÛÞÜÕ¶¥†¦ ¤¦«Â×ɼ¥¦£®¼óÚŸ¿ó͹¥¥¦¤ªÀÛÐÅ·¨¥‡¦¥©ÊÝÜ€Û ÜÜײ¥¦¦§©ÐÙÜ€ÛÝÜÍ©€¦»ÖÛ݃ÛÞÔÅ«¤…¦¥«¶ÁÓ×½°¤¦¤¦¯Úùïÿøè³§£¦¦¥¦®ÒÞÙ͸¬§¥¥„¦¥ªÏÝÜÛÜÛ¾¥¥¦¥­Ô‚Û ÝÝÓ­¤¦¯ÎÝ܃Ûܨۤ„¦¥¦¬¼Ì×ßË®¥¥¦¦¤¥¸íîö÷¾¤£¦ ¥¦»ÙÝÝÙ理…¦­ÔÞÜÛÜÜÌ¥´ÙÝÛÜÜÙ²¤¨ÀÝ…ÛßÇ´£„¦ ¥¦®ÅØÞÞÛ·§¤‚¦¡ÉÌ¿œÎÍ£†¦ ÉÖÞÜÞÒÀ°£¥ƒ¦­ÔÞÜ‚ÛÜ×±¦£§ÀÛ݃ÛÞ·ª³ÕÞƒÛÜÜײ©¥‚¦ ¥£¬¾ÔÞÜÝܨ…¦¤ÍÝ›éׯ¥…¦¤´ÈÛ€ÜÖ骤¤¦¬ÒÞÜ‚ÛÜÜ룧ÇÛ݃Ûß½µ¾Ý܃ÛÜÞÆ©¥‚¦ ¥ª½ÉÖÜÜÞÙÏ®¥…¦£´Äó™ÿÞФ†¦¤ª¾ÕÜÛÜÝÚȶª§¥¦¦¥ªÏÝ܃ÛÝϱ¦¨ÌÜ݃ÛßüÄß„ÛÜÜ»§¥¦¦¥¥¦«¶ËÖÞÝÜÞÓĦ¥…¦¤ª»æ™øÇ±¢‡¦£¯ÄÞÛÛÜÜßÕ½±¥¥¦¤¨ÈÝ܃ÛÜÜ¿°©ÔÝ݃ÛÞÌÈÍÞ…ÛÕ«¦¥¦¦£¤«Á×ÞÝÛÛÜÜǰ£‡¦¢¨½îÿ—ή£Š¦°ÏÝÜ€Û ÞÛÕ«¤£¦½ÝÜ„ÛÞÓÇ´ÚÜ܃ÛÜÔÓÖÞƒÛÝÙÈ£€¦£«ÃÐÜÞÛßɳ¤Š¦§éÝ•é󵨤‰¦¥¨¸ÙÛ ÜÜÛØÊµ©£°Ù…ÛÜÚÕÌÛÜ܃ÛÜÚÚÛ܃ÛÝÖ»£¤¥§¶Ì×ÛÜÜÛÛÜÝÔ¸©¤‰¦¥¤Äóù”Þ᪥¥‹¦ªÉØÜÛ ÜÝÙÍÀ³©ËÙÜ†ÛØÛ ÜÜѰ¢¨±»ÎÚƒÛÜÜ쌦¤¬åê“îØÉ£¥‹¦¥¤¸Ô܃ÛÞÞÓÅ­¾×Ý…ÛÜÜÛ ÜÚͪ¤²ÂÑÞÜ܃Û׳§¥Œ¦¡ÑÛÿ’è㨦¥¤ƒ£†¦¥ÃÖÞƒÛÜÝÞÔ¾ÎÖÜ™ÛÞÔÆ¨¼ÖÜÞ„ÛÝÙÄ¥¥¦£¯Õø’ÎË¢£¨­µ€½¼°¨¤¤ƒ¦£®ÆÚÜ…ÛÝÖÔÕšÛÜÖÑÉÛÜÜ„ÛÞÚÊ«¥Ž¦¨¶Ìß‘ó͸¥³¿ÄË€ÐÏÈÀ´­ƒ¦¤¨ºÍÞ…ÛÝÛØØšÛÜÙ×ÕÝÜÜ„ÛÝм¦¥¦¥®ÂÇÌÿ¿íÌ©®ÇÕÚÞßÞØÆº¨¥‚¦¤®½Ý†ÛÜÜÛÜÞ†ÛÜÙÅ­£¦¥¤¶ÑÅ¿÷ÿ˼°ÔßÞ݃ÛÞßÙ¦£¤‚¦«ÍÜܱÛßɵ¤¦¥¤¥ÍÜűÝÝÚü¿ÃÎÞ€ÜÞÞÜÜÛÜÚÈ®§¤€¦¤¥²Õ°ÛÜÝÕ±¨…£¤¥ƒ¦ ££ª¿ÜÛîÁÌ îã¿ÅÏÄ¿¾¿ÂÑÛÝÝ€ÛÜÜÚο¯¤¤¦¥¥¦ÃÙÞ®ÛÜÚ¼¦§­²¹¼½½¹³¬©¦¤ ¦«ºÅ×ÞØÁ©±îïŒÝ×¼¿Äµ°¯°³ÂÐ×ÜÜÛ ÝÙͼ®§¦¥¥£·ÓÜÜ®ÛÓ²­³»ÁÈËÌÌȺ¶°¯­­®±¹ÉÒÝÞÕ¾§«ëê‹ÿÝ̯©¦ƒ£´ÅÕÞ‚Û ÞÞÚͶ¬§¥¤¦ÄÒÞ¬ÛÝØÄ±ËÔÛÞ߀ÞßÞÛØÐÏÊÊËÑÛÝÝÛÞʶ£¤ÙÚ‹öøµ§…¦¤«µ×ÞÜ‚Û ÜÝÜÒÆ¾²¨®»ÚܪÛÜÙÔËÙÝ܆ÛÜÞÝÞÜÞ¹¬£¤¿¾‹î묆¦¥¥©¾ÚÜ‚ÛÜÚ×ÑÌÆÊØÜªÛÜÚØØ€Ü†Û‡ÜÞ̬¦¥¤°â÷Šâে¦¥¥²ÒÚ…ÛÜÞÞÜÙÓÓÙ¬ÛÚÚ‘Û ÜÜÛÙ¾§¥¦¤©ãôŠÊË£‰¦¤¾×Þ‡ÛÜ€ÞÜÂÛ ÜÞÙɧ¥¥¦¦¢×犾¾¤‰¦¥«ÉÖÞÉÛÜ‚ÞßÛȼ©¥¦¡Ä͉øå°¥Š¦¤³ÁÜÜÃÛÜÜÞÞÜÛØÒÒÐÎĵ«§ƒ¦¢¹¿‰ðàª¥Š¦¥ª´ÎÝÝÜ¿ÛÝÝÜÙÓÎÇÄ¿½»º·²ª¦¥ƒ¦£²Àøˆçئ¤©½ÙÞÝ¿ÛÝÜ×Ñĺ°¬¨¦¥¤££¥…¦¤«À÷ˆÛ΢¦¥¥·ÕÝßÜ»Û Üßׯ¶ª££¤¥¥Œ¦§»óˆÛΡ¦¥²ÂÓÜßÞÝܵÛÜÜÖ°©§’¦£µêˆÓÈ¡¦¤¨°»ÅÍÔØÚ¶ÛѰ¦¤¤¥‘¦£³âˆÉÁ¡¦££¦°»ÉÒØ´ÛÜÙȳ¦¤¥“¦¢¯Ùˆ½¸¢‹¦¥¤€£§©­³¼ÆÐØÜ³Û ÜÚÖÏȽ¶¯ª¦£¥‹¦¢¬Ëˆµ²¢…¦¥£ ¦«°µÀÇÏÔÙÜÜÝÝܵÛÜÝÞÝÜÜÙÕÎȾ¹±ª¦¤€£¤¥„¦¢¬Ëˆµ²¢¦¥¥€¤ ¦§ª¯´ºÀÆÎÒÔØÙ…ÜµÛƒÜ€ÛÙ×ÕÒÎÇÁ¼µ°©§¥¤¤¥¥¦¦¢©Á‡ÿº±¢€¦ ¨ª¬°²·¾ÃÉÏÔÛÜÝÜÃÛÝÞÚÕÐËÄ¿¶²¯¬¨¨§§¦¢©¾‡üÄ­¢¨¬°¶¾ÆÎÓÙÞ߀ÞÜÜËÛ€ÜÞ ÜÙÕÎǺµ°«§£ª¾‡ûIJ·ÊÕÙÝÝÞÜØÛÜÞÝÜÚÓÈ·¶¾‡ üįª³¼ÁÅÎÓÚÜÞÞ€ÝÒÛÜÝÝÞÜÛÚÔÍÈü³¨¬¾‡üů¤ª¯²¶¿ÅÌÏÓÖØÚÜÛ„ÜÃÛƒÜ€Û ÙÖÒÐÍÆ¾¹´¯ª£©¾‡ÿDz£¥£ ¦ª­²»ÆÌÑ×Ü€ÝÞÜÜÃÛÜÞ€Ý Ü×ÒÍǼ´°©¥£¥¢©¾ˆµ²¢ƒ¦¥¤€£¥¨¯¶¾ÄÎÔÚÜÞßÞÞÝÜ·ÛÜÞÞßßÞÚÕÌÆ¼³¬©¦€£¤¥ƒ¦¢¬Ëˆ¼·¢‹¦ ¥§¨¨­³¸¾ÄÏÕÙÚ¶Û Ú×ÑÌÅÀ»±®©§¦¥‹¦¢¬ËˆĽ¡‹¦¥ §¨«®²¸½ÄÍÛÜܳÛØÒȽµ¯¬¨¨¥‹¦¢®ÓˆË¡¦¥¤€£¦´ÃÛÜܳÛÖÏõ¬¦£¥¦¢°ÝˆË¡’¦¥£¦¶ÊÙܵÛÜ€ÞÔĵ¥¥¦£´éˆÙÍ¡¦££¤ª¶Ê×ÜܹÛÜÝÜ×Ä«¥¤Ž¦·éˆáÓ¢‡¦‚¥ ¦¦¨«±¸ÀËÖÛÝܹÛÜÝÝÜÔÀ­§Œ¦¥©¼ðˆëÛ¥‡¦¥¦§§¨ª«¯¸ÃÍ×ÞÞÜ¿ÛßÓ¸­¥‹¦¤­¾øˆù嬤„¦ ¤¬·½ÂÇÊÍÐØÜÞÞÝÃÛßÒÅ©¥Š¦¢²µ‰ÿ¾µ£¦¥¦«½ÔÛÝÞÝÞÜÇÛÝÖ¾¤Š¦¡ÁÉŠÂÅ£€¦¥§¹ÅׇÜÈÛÚÒ²¥¥ˆ¦¢Ë׊ÒѤ€¦¥¯ÇÒÞÝÁÛÜÛÚÛ‚Ü„ÛÜÚ½§¥ˆ¦¤ÔáŠê肦ÈÚÞÃÛÜÙ××ÜÝÝÞÜ„ÛÜÞÑ®§¥†¦¤©àóŠöô°¥£¥¶ÜÜ€ÛÜÝ€Þ܈ÛÞÜÒÑÙÜªÛ ÞÔȯµÀÊÔÜßÜ„Ûßdz£¥…¦¤µ¾ÿŠÿî¹¥£ªÊÝÜÜÝÝÚØÖÖÙÛÜÝÞ‚ÝÞÝÜÖÃÆÍÝÜªÛ ÜÜÒµ¥ª­²»ËØÜÝ‚ÛÜØË¼§¤¥¥¦¥¤¥¥¦ÅÂŒÌÅ¥¥­ÔÞÜÛÚÔÎËÉÈÌÏÑÕÙÚ€ÛÚØÕÑǹÆÐÞ¬Û Ý׿¤£¤¦¬¼ËÔـ܀ÛÝÖ˳«§¦§¦§ª®¬ÑÒŒîß©¨µ€Ü×ǵ«©§§¨¬¯·ÂÇÊËËÈÀ·¯¤¸ÕÞÜ®Û Õ²¥¤¥££ª¹ÇÚÜÜÛ ÝÝÕÁµ°­®¶ÁȹçãŒÿø³°¼ÞÞȺ¥£¥¥¦¦¥¥¤££¥¥¦¦€£¤«ÒÜÝ®ÛÜÜͪ¥€¦¤£¦¼ÖÝÝ‚Û ÞÞÛÙÔ×ÞØÏ¾Ì ÿÿÇÀ¼ß̰§¥¦¤§ÅÛܱÛݽ®¤ƒ¦µÐÙß„ÛÜÝÞØÄµØÝÚȺݾª¤¦¤¨²ÔÜÜ…ÛÜÜœÛÜ܆ÛÞͺ¨¤¦¥ª½É؆ÝÖ÷µêîê̹װ§¥¦¤¯¿Þ‡ÛÜÜœÛÜ܆ÛÜÚÆ®£‚¦£ª´ÌØ€Ü ÝÜÜÚÖÈ®®¸øÚ¾ÀÁ§Ž¦¥¨¿ÕÞ…ÛÜßÖÕÙÜ™ÛÚÚÙÞÜÜ„ÛÞÖÃ¥ƒ¦¤¤§²ÄÉÎÑÎĽ²¥ ·Ë’äß©¦£»ÑÞ„ÛÝÞÜŸ½ÙÜšÛ×ËËÜÞÞ„ÛÜÔ¸¤¥„¦ ¥§©ª«¨¨§¥¤©Íí’æÝ²¥¦¥­É×݃ÛÝÛÖȲ±»ÛÜšÛÙоÉÓÛ݃ÛÜØÉª…¦€¤¥¥¤£¹Íñ“ÅÊ¥¥¦¾ÖÜÛ ÜÜÛØÏÁÞ’ÛÜÜ„ÛÜÚº³¿ÎÚÜ܃Ûظ¨¥Œ¦¤ÑÔ”Ý骦®ÑÜÜÛ ÜÞÙó§££ºÉßÛÚØÙÜ„Û ÜÝΦ¦®ÈÛÞÝÛÜÝϰŒ¦¥±ëò”ÿîÉ«¢‰¦¥¬ÅÞÜ€Û ÜßÜÏ·§¥¥¦¥ÅÓÞ„ÛÚÕÙÜ܃ÛÞÕÀÂÜÜƒÛ ÜÜÚ´©£¦¸ÐÙßÜÛÝᣉ¦¥¤Úâÿ–黪¤‡¦¤ª¹ÖÜÜÛÛÝṴ̂¨¥¦¦¤¬ÎÚ܃ÛÝØÈÓÛ܃ÛÞѰ°ÍÞƒÛÜÜݼ®£¥¨±ºÎÜÝÜÛÛÞÕ½¨¥‡¦¤§¶öî—óÄ´£‡¦ ¥°ÄÜÛÛÜÜÚѾ´¦¤€¦£³Ò…ÛÝÖ¿ÏÚ܃ÛÞÌ«¨ÁÛÜ„Û Þ±£¦¤§­ÀÑÛ€ÜÝÛÆ±¤‡¦¤¬Äüé˜ÝÌ£†¦ ¥©¿ÖÞÛÛÜÛ˲¦¤‚¦£ÅØÝ„ÛÝÓµÉÜ݃Ûß飮ÓÝ܃ÛÞɵ£¦¦¥¤¥²Í×ÞÜÛÞÕŤ†¦¤¨·êš¿¾½¡…¦ £ÀÒÞÛÞÛÌ»§£¥¦¤¤®Ö…ÛÞÖȨÁÛ݃ÛÞ¼©£¥ÀÜ݃ÛÞ˶£‚¦ ¤ª¹ÍÜÞÜÜØ¶¥¥„¦¡ÁÌî›æä­¤¤‚¦ ¥¯ÑÚÞÝÑ¿²©¦¥‚¦¤§ÂÜÜ„Ûßɺ¤ºÚ݄۵§¤¥°ÕÚƒÛÞ˶£‚¦ ¥¦©°ÀÒÜÞÜÏ­¦¥‚¦¢·åñœçïΩ¥¥¦¦¥¥ªÂÚÜØÌº¬¦¥ƒ¦¤ª´ÔÜ܃ÛÝÖ¹¬¤³×ÜÛ ÜÜׯ§¦¦§Ë×Ý‚ÛÞʶ£†¦¬»ËÖÜÛ¾©¤€¦¥¥©×îÿÈ鲨¤¦¦¥¦°ÒÜØÍ¸¦¤¥„¦¥³ÃÞ…ÛÝÊ®¤¤­ÓÚÛÝÝÓ¬€¦£ÂÒÞ‚ÛÞÈ´£…¦ ¥£§·Ê×ÞÍ®¥€¦¤¦¸ðì  Û¿¢¦¦¤¬Éß˺©£†¦£±ÇÚÜƒÛ ÜÝÑ®¦¥¦¦ÎÙÝ€Û ÝÜɨ¥¦¦£µËÞ‚ÛÞÀ°£‡¦¥¤«·ÑÞÁ²£¦¤¦°ëî¡ ÑÇᣰ½Ò¼ª§†¦¥£­ÎÙÞ‚ÛÜßØÎ¯¥€¦£ÅÔÝ€Û ÝÛ§¥¦¦¥®ÅÚÜÛۀܹ¬£‰¦ ¥¦¬ÁÐÊ­¥¤½Öæÿ¢ÇŶ£³»¿­€¥‡¦¾×ÛÝ€Û€ÜÓȺ§¤€¦£ÁÒÞ€ÛÝÚº¦¥¦¦¥ªÁØÝÛÛÜÝÚ´©¤‰¦ ¥¤¦°ÀÁ´¥½ÉÚ¥ÍЩ´¶¬£ˆ¦§«ÏÝÜÛÜÝ×ĵ§£¦£¼ÏÞ€ÛÝÙ²¥¥¦¦¥§¾ÕÞÛÛÜÞ×­§¥Œ¦£­³¸«ÕÚ¦ÿüЬ¢¥ˆ¦¤¨¹Ü‚ÛÞÝÒ³¥¤¥‚¦£±ÈÝÛÔ«‚¦ ¥»ÒÞÛÛÜÞÑ«¥Ž¦¤£¥ÚÕ§ÿÿÅÆ¾¡ˆ¦¤¬ÅÝÛßÐÄ­¥…¦ ¥«ÃÛÜÛÝØÌ§‚¦ ¥ºÐÞÛÛÜÝΨ¤¦¤¤°ÔÝÿªÉž£¤¥…¦¤®ÏÝ€ÛÝ϶¬¦¥†¦§½ÖÞÛÝÔÆ¤‚¦ ¤·ÌÞÛÛÜÝÍ©¥Œ¦£§ÅÎÝÿ¬ÄDZ§¥¥„¦¥°ÑÞۀܬ¥¥‡¦¥ºÓÞÛÝÒ£‚¦ £µÊÞÛÛÜÝϪ¥Š¦¥¥¦µÑÛ¯Ýݰ¨¤„¦ §²ÑÞÛÝÝÒ«¦¥ˆ¦£µÍÞÛÝ͹£‚¦ £±ÃßÛÛÜÞÔ­§Š¦¤¥µãå°ÿÝæË¬¡ƒ¦ ¥°ÑÞÛÝÚ¹¤¥‰¦£°ÅÞÛÝȱ£‚¦¥«µÚ‚Ü·«£‡¦¤¢°Åñîÿ²ãæÞÀ¥£¥€¦¤­ÊÝÛÛÔ®¤Š¦£¬ÀÞÛÚ줄¦ªÇÞ€ÜÞɵ£¥„¦¥£§Äßîòÿ´÷ì̳ª¥¥¦¦¤«ÃÝÜÚÒª¥Š¦¤«¼ÝÜÙÁ©¥ƒ¦ ¥§ºÙÛÜÜÝÒ¾ª¤¥ƒ¦¥¨·Ñìÿ¸ ÝêÀ¬£¦¦¤¨¸ÜÞÙÎŒ¦¥¨·ÙÞÓº¥„¦ ¥¥¦ÉÙÞÜÛÞо¥¤¦¤¤©½çå» îôàÇ©¢¥¦ªÎÞÚϨ¦°Ñß͵£†¦¥©ÀÍÞ Ûʳª§¤¡­Äâùîÿ¼ÿÞØḭ̀¦¡²ÔÛ×®£¥Š¦¥­ÉÞŰ£‡¦¥§¬¹Ï×ÚÜÜÓÀ¶®ÈëíÞÿÿ¿ ßóÑËȵ¬ÁÎÕº¤¥Š¦¥«ÂÞ¿¬£ˆ¦¥¦¬¸ÀÃÅÆÇÄÇÍËñóÅ ôê̱²ÁÎÄ¥¥Š¦¥©½Üº¨£‰¦ ¥££§¬°µ¿ÈÔôÊÿóÒ··¦¤¤‰¦¥§µÕ´§¥‰¦¥¢¡¥®¼ßøöÌ ÿîÅîóäʺ±¦€¡¢¤„¦§®È°§„¦¤£¢¡¢¦«·Öèâ´ÕÿÿÏ ÿúèÌØØÍ¿¸²­¨¦ƒ¤¥©½ª„¤ ¦¨«®·¿ÌʶÚîò× ÿúòÛÎÁµ´°ª©§¦ª´©¥¥¦¦§¨«¯¶µ¸ËÚíôáÿùìàÝÛÍÍÆ‚ÀÁÍÍÙàëëø÷æÿÿî€ÝˆÌÝÝîîÿÿÿÿÿ«ÿÿÿÿÿ©Úÿøõòòë…êñòó÷üìâ ÿÿöìæÞÓåãáÞÞÙÙØÖÌ×ÚÙÚÞßáäçÙÚàêöÿÿØÿÿîÞðùóéâÝÑÐÌËÉ€Èƽ¢ÀÊ€ÈÊËÐÏ×ÛàèòøøÞîÿÿÔ ÿýôçÞÐÊÈÇÈÈÉ‚ÊËÆ±Y°ÍƒÊ ÉÈÇÈÈËÑ×ãôýÿÐ ÿÿôéßÕÎÌËÊʀɄÊÍÆ£,žÊÏ„Ê ÉÉÊÊÉÉÊ¿ÙÝã÷ÚË ÿ÷êçÝØÕÐÐÊÉɈÊÎÄ‘ÃÏˆÊ ÉÉÊ»‡’«ßÝëñÆ ÿÿæ÷òÛÀ®¯³½È€ËˆÊÐÁ|}»Ï‰Ê ËÏÂCDd½ÕéíÍîÿÂÿÿüìØ¼s05l§ÀÐˇÊÏ·Zf®ÔŠÊ ËÕƒ<J¿ÊÍÖñîîÿÀðïÕÊʾ–TF£ÔˆÊͪ8LÔŠÊ ËÕ¡M t½ÑÉËÖåò½Ô÷ßÔÒÊÉÊÉÆ¼‰L1œË΄ÊÎÉš2‰ÐŠÊËÑ­U*ŸÇÎÊÌÐÔáùô¹îîíÚÎÈÈÊÊÌÒÙº{8€ h¼Ê̓ÊÐÅ#}ÌˉÊËÑ­U‰ºÐÊÈÉÍÝðñï¶ÿîãèÏÉÉ„ÊÓÀš€„µÓƒÊ Ô¾~hÁÐˈÊËÕ L€f›Ô€ÊÉÈÏéïîÿÿ³üéÓÉɆÊËÏÃ]7‡ÏƒÊ Ô§[W±ÔˈÊËÕt3€LÔ‚ÊÉÌÕäÿÿ±ßñÜÔËɈÊÏÌ [­ÑËÊÔ˜E€AÕˇÊËÎÅ;€:oÔ„ÊÌÑâøô¯ÿðêÓËȉÊÎÍ¥IšÔËÊÒŽ7€6zÕˆÊËÍΡ"€7lÔ„ÊÉÉÔîóô­ßêëÍÈÉŠÊÌÎÀ:€ÔËÊÌx€'_ÔË…ÊËÎͼ>BwÔ†ÊÈÏëòîÿ«éãÉÉŒÊÌÎÀ2qÔË€ÊϺa €<φÊÔÏ®NƒYŽÔ‡ÊÈÌ×òÿ©ÈëÖÑÉÊÌÎÀ +eÔËÊÊËÔ¦P€ +ºÍËÊËÍÔ²X/ ƒr§ÔˆÊËÎÓñã§îèÖ¶³ÉÏŒÊÌ̵ '^ÔËÊÊËÕ’DªÍÌ€ÊÏÍÄœ[$‚¼Ï‡ÊÏļ°Ýîï¥ß鿯–’¹ÐÌ‹ÊÍʦ ‚ "UÓËÊÊËÕ|8‚ —ÍÍÊÊËÐéW ƒB­Î‡ÊËήËëîì¤ éèÊÔŽc8ªÐÐˉÊÏ̉‚ <ËÌËÊËÕX#‚ vÉÍÊËÔ»p#…¡ÆÎ…Ê ÌÐÕ£==ŸÌÍáò£ óßÏÉËɤ2t¨ÏÓˇÊÏÆZ‚ "»ÎËËÌÌ?‚ LÄÍËμA„ËÌ…Ê ÑʵcHwÎÊÈÎ×÷ÚŸ¿÷áÖÉÉÊмi4Z‹ÁÎÍË…ÊÎÀE‚ šÎÌËÍÁ/ ‚7¼ÍÍÇ|…%WºÎË‚ÊËÎϸg)v¥ÑËÉËÐéûïÿÿñÒÊÈÊÊÍʬ&7„µÇÌ̓ÊËÍ»1ƒ nÎÍÌͱ‚!±ÐÌ«3…X£ÑË‚ÊÌÍ˵{?=ªÌÎÊÊÉÉÔõòÿûØÊÈÊ ÍÉ{ X§ÈÐË‚ÊÌË´ƒ?ÈÍÎΙƒ  ÓÂi…N–ÓƒÊ ËÍÉ®U ÇÑÊÉÇÞàÔœÞáÈƒÊ ËÍÊH'i¦ÔÐË€ÊÌʲ„£ÊÔÇf …‹¿ž„ÀÏ‚Ê ÏÓ±r ]ÂÍË„Êâë›òèÏÉ„ÊÌÓ—L5€¿ÏÐÊÊÌ˶%„Z·ÕÄM …p“t…O½ÌË€Ê ÌϽtF0¯ÌÌ…ÊÔÝ÷™ÿëã†ÊËÒ¹m€  K‘¼ÉÍËËͺ/„2£ËÂ<…]w]† xÈÎÊÊÍÍÉ·Ž@"VÌÎË…ÊÌÖï™ûÝÐȇÊÓ¨]‚ v¢ÍÏËÐÄI†p¤»…;L<… ¹ÍÌÊÌÒÍ´dU¦ÔˆÊÈÌÖÿÿ—áÎȈÊÍË¥2 b¹ÒÔÉs†$O™ …!… KÓËËÍÒ»`3‚F—ÐˉÊËòî•é÷ÑÊȈÊËφ‚C‘¼Õ§…8† … ~ÕÒÑlj; ‚ˆ¾ÐŠÊÉÜøù”æîÌ‹ÊÍË·G„>oÀ> ††€„ +£Úâ{8 ƒ\²ÍÍŠÊÉÍðò“ÿåßÉÊʃ˄ÊÍφ&…$V³j› 7¼Ñžd+…™ÇÏŒÊÈåéÿ’òïËÊÎÑ‚ÕÔÍË‚ÊËÌÏ]†p3›PÄv†[ÍÍŽÊÐçû’âáÌÓÁ°€qw¥ÄÐÒÌÊËÓªQ†›*F† A¹ÎÌ‹ÊËÌÁ˜Àì‘øâÖÆ—nZC€14Pj—¯ÎÍÊÏÃ8‡ › ˆ.xÍÌË‹ÊÌή^™ßÿ¿ôáÈ«O ‚R~ÁÏËÊѪq´ W°ÓËŒÊÍÑ)uÕúÿà̤‡bÍÔÏ€ÊËÌ»8³I”ÒÊÎÑË8\¾êîÚÿׇ2ˆJ­ÇÑ€ÊÏÍœ°ŸÄÕ„ÔÑÏÌÊ ÌÓÔ»j]¼ÙÝ ÿîš[.Ysuqc*ƒ 6l©ÒÒÍÌÍÊ\°|ÌÆ¯›wtv€™µÀÌÑÒÒÑ̶}VfÀÑõïŒ îç“kXލª§˜_)ƒ ;y°ÅÊÌÎÕ‰'®%Ÿ²›zeMB?AKd‚‘¢®°±¯£ƒH(sÆÐóò‹ÿîß½Â΃Ô—U„ ;µÈÏÑÎW$­\ C„ '4@B>&€BÓÉéæ‹öûÓÏÍ̃ËϹ„  (Nq Æ¬|¬@‡€‚…¶ÔÉÙÖ‹òó΀˃ÊÍËÀr †'=OC« ’?¶ÊÍÊÏîûŠêíˆÊÎÍ¡$‰##¬“ qÇÎÊÉÌðùŠÞßÉɇÊËÍpÒ IÉÏÌÊÊÈéñŠÖÙɈÊËμCÑGvÀÏÊÇÜá‰ûðЊÊËÒiÈ "#*5W‘»ÉÌ‚ÊÇÕØ‰÷îÍŠÊËϾ™6Ä #8P\kx{‰œºËÎË‚ÊÈÒÙúˆñéÊÑ¿tÀ (X}£³ÁÊÏÒÔÔÐË„ÊÉÎÛûˆéãÈÊÍ̉¾ O»ÕÕÑÏÏÌŒÊÖ÷ˆéãÈŽÊËÌd%»\¥ÀÊÌËËÊÈÓóˆåßÇÊÏÁ¤{S=# µ+d¢ÍÓÒÏËÊÈÒíˆßÛÈŒÊËÓÓÇ¥yH&µ MÌÐÏÍÌÌËŒÊÈÐéˆ×ÕÈŠÊÌÏÓ€ÕÉÀ±šxR,µ/Is’©ºËÔÕÕÔÐÌˉÊÈÎàˆÑÑÈ„ÊËЀÔÓʹ¦’fO, ¶2Lp…¢¾ÎÒ€ÔÑ΄ÊÈÎàˆÑÑÈÊÎЀÒÍȼª’|gN5*$ À (8Ncwލ½ÆÏÒÒÐÎËÊÈÌÙ‡ÿÕÑÉËÌÉÆ½´¨žŒu\G2Í .CYsŒ™«´ÀÄÇÊËÉÍׇ üÜÏÈö£ŽoP0 Ú 6Nz£»ÆÈÍׇ üÜÀ‰EÛ  !K‹®×‡ üÜʲš|hT5 Ü  ;L]{™´ÄׇüÜÎþ¬œŠjQ;0& Ð %,;Qp’«¼ÅÌׇÿÜÑÊÏÓ€Ô Ì¼²|U;$Æ %5Oy—¨ÀÏÓÔÔÓÐÉÌØˆÑÑÈ‚ÊÌÏÑ€Õ ÎĨ‹mY4 ×Ý ÿÿÞ´x;¥ÉÏË„Ê ËËÊËÌÌËËÐÅT ²qªÑÊÊ€ËÉ‘/ „[¯èîé¿q¼Ñ͈ʀËÊοž#³8ÃÏ€ÊËлvM„\”ÊòÿóÈ’¥ÇÎÊѧlˆœ‡QªÓËÊÓ¹“:  J¬ÆÔüÚÖÊcÉËÊÏÃnˆ š ˆ]ÏÌËÊÒÓÊŸ\F6(7YrŸÏÏØà’îé¶ÉÊËÓ~2†R‡u ›?>†&†ÏÍÊËÌÌÎÆÁ½»ÁÆÉÎÉÍáô’òéÎÉŒÊÌͲJ… Oš£|› *qK' …H¸ËÍ‚ÊËÏÏÎÌÌÏÈÖàõ“ÞàŒÊËÍÉu„4[ªÙ¡j‘† ƒ›m7ƒ†ÂÏËŒÊäæ”îòÎËŠÊÍʯ&ƒ ^™ÊÔÔ}H†‡ †5ÆÊ«K ‚2¥ËÍ‹ÊÑóö”ÿÿÞÎȉÊϵUƒ -ŒÇÎÏËÏU!… …ha†˜ÀÒÈ….ƒ]¨Ó‰ÊÉÉëîÿ–ñÖÌɇÊѾ…:b¦Å€ÌÒµ4…L!…+£¦<†s¬ÔÍŸ~8ƒrÁ·ÊÈÊÒúÿ—÷ÝÔȆÊËЦ] *k“ÎÑËÊËÕ˜%†i/…:·Âf † `¡ÔËÑǰj' €R¢ÑˆÊÈÍÛüé˜ëâÈ…ÊËÐÁm€A ÊÒÌ€ÊÌÒW…)•H …YÀÕ¯"… H”ÔÊÊÎÑΠ7€!TÐÌ…ÊÉËÓòšÔÝ×ÇÉƒÊ ËÔi.;zÆÐÍË€ÊÏÏ­…IÃa …wÁÔËf …?ŽÔÊ Ìѽ„;ŽËÍ„ÊÇÙÞÿ›îîÎÈÉÊ Ìͪ' (lŸ¿ÌÍËÊÏÆ_†HЄŽÅÑÎ¥„>ŽÔ‚Ê ÍÍÀ¤o$1®ÊÍ‚ÊÈÓïõœï÷ãËÉÉÊÊËÌÀb @~°ÈÏË‚ÊÏ»–#„°Ñš‚¤ÉÎÍÆ<„C‘ÔƒÊ ÍÎÊ´|C q½Ð€ÊÉÉÌçõÿÚòÏËÉÊÊÎÉ¥# 9†ËÒσÊËΛ\†C­ÑÏ®‚"µ€ËÔ`(„M–Ô…ÊÍÓʇD7¨ËËÊÊÉÉÕõñ êÚÈÊÊÒ´I>¿ÔÍ˃ÊËÔ£R…'­ÉÏÌÉ3‚FÃÍÊËÔ’E„h¦Ô‡ÊÏÓ¹Ž(gœÔËÉÊÐôÿ¡ ãÞÝÉÓ£t'xºÇËË„ÊÍѲ5„ 3§ÎÌÊËÔS ‚ _ÆÍÊËϬUƒ…¶ÔˆÊ ËÍ̹d/E±ÍÉÙæîÿ¢ ßÝÓÏ“wh¯ËÍË„ÊËÍÉp„ %O~ÆÏËÊËÕe*‚ ÊÍÊÊϺd‚ šÀÑ‰Ê ÌÏÌ¢if“ÉØÞê¥ÞãÍ’‹³ÔˆÊÌʹ-ƒ Y’ÃÓËÊÊËÕw5‚ ŸÍÍÊÊÏÇr«ÈÏ‹ÊÌÓ°›…Êçê¦ÿþãÎÉψÊÒƒ%œÎÒÏÊËÕ£N·ÌË€ÊÏ|#(»ÌŽÊÒÒÊêæ§ÿÿÞÝÙȈÊÒ¶U‚/[±Î˃ÊËи^€9ÈÌË€Êσ06ÀÏÊÉÊÒæîÿªÙÚÙÈÉÉ…ÊÏ©/2µÍÍ…ÊÌÇs€RÒÌÊÒ‹;8¾ÍŒÊÈËÝâîÿ¬ÙÞÑÊÉ„ÊËÍ¥&€`µÏΆÊËÎ$€)bÕËÊÔ‘D1»ÍˉÊÉÉÊÕãé¯ÝêÏÌÉƒÊ ÌË¢&$¼ÍΈÊÔ7€<ƒÕËÊÓ[±Ê͉ÊÉÉÓïî°ÿîïàÍÇƒÊ Î¦&‚Ï͉ÊÔ¤W€M¡ÕËÊÏ»’Œ¹Ó‡ÊÉÈÐÛ÷óÿ²ñðìÚÉÈÉ€Ê Ñ±E¬ÎÌ‰Ê Ô³n]µÑËÊË˺LG“ÔÎ…ÊÈËÜìõöÿ´ùôàÑÌÉÉÊÊÒ¸[%¼ÎˉÊÒºzh¿ÎƒÊÎÈ}€%q»ÐÎÌËÊÉËÕãôÿ¸îòÙÎÉÊÊÑÂ… 3ÉÌˉÊÏÃ!~Ï„ÊÌÏÉI€/kÌÐÍËÊÌÖñî»ÿùîÝÏÈÊʽ02ÅÌËŠÊ̤$<’Ó†ÊÏÀk;€ Hš¼ÆÈÇÎÜïûÿÿ¼ÿîéóáÐÌÌ­ÑÍŠÊϲJV£Ô‡ÊÏǶ„1 "i“ÏÞôöæÿÿ¿ ß÷áàà×¾g5~ÏÍŠÊй_l²Ô‡ÊÍÏʵ†j^UWq¹áßù÷Å ÷ñàÓµs9ZËÌŠÊоt ‚ÁÓ‰Ê ÍÔÓø°´ÖÞå÷Êÿ÷åÚʉ¾ÈŠÊÐÇ””ÇÏŠÊÈÇÎÑÖíüÿÌ ÿÿÞôöçßÕÐÉÈɃÊÍÉ­G©Ë„ÊÉÉ€È ÎÐÓçñíÍæÿÿÏ ÿÿòàæçàÙÕÑÎËÊ‚ÉÊȸuµÊƒÉ ÊÌÍÏÔÚáàÒêôö×ÿûõêáÙÒÒЀÌËËÊÉæÄÌÊ€Ë ÌÍÏÔÒÒàêó÷áÿýôîìëââÞ‚ÙÚââéîôôüûæ€ÿƒîƒÝîÿÿÿÿ«t8mk@Òàààààààààààààààààà‡÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`WÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒààãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïàÒ`€‡øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø‡€`ÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ- xñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñð´ ´ÀßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÀÀ0Kóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿo Kÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡ÒðóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøððÀøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ0Wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿo0WÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÒøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþá‡÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÄðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüà€ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡ Kÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó´Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð´<ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÀüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàp¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðxàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÒüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÃ0ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?<ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¨çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßpÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà8ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿààÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿààÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿààÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿààÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÒüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÄ´óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó´?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK Kóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþá8ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÄïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿pÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñxðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÀ´óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüá KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ ‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ`àüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá8àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿pÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ-0oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ<0ÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏðþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ<áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-8Ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç?`ÀÃüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÀ¨áüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð<Ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð€€@¨àáþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçàÄðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß?¨àààààãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðàààà¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/fits.icns0000644000175000017500000013662110662656612023235 0ustar olesolesicns½‘ics#H€?à?ð?ø?ø?ü?ü?ü?ü?ü?ü?ü?ü?üü€?à?ð?ø?ø?ü?ü?ü?ü?ü?ü?ü?ü?üüis32y й¿··±•…ʾ©²Í¢„ ®‡ŒzrgΰÁ¿ƒ ÃË»Á±Ý»®°ƒ‚ –èçîÈ„‡ÄžŠ‘y šêñ @.-¬ØÎ† óÌ(–ïäZ@áà™ ÿ….òûÿÅ$Æí£ ¡ÿ™Cåþÿ» Òô¨ ¡üç nÕÁ7e÷ö­ ûÿºB0Hãøû¯ ðîóæ·Äõïëô­‚-/$ ˆ "Z^?:SK\l  й¿··±•…ʾ©²Í¢„ ®‡ŒzrgΰÁ¿ƒ ÃË»¾ª×º®°ƒ‚ –èçêßÎÊÍš‹‘y šêëË­µ²²ÎÔΆ ð䲯ØÕº¸àà™ ÷Ó±ØÚÚбÞê£ ¡úÚµÕÚÛήæñ¨ ¡ùó¯¾ÒϳÆòö­ úü滫³Àïôû¯ øöøóåèöôñú¯ k·»»¹³²­­®±v ^ÃÔÔÊÈÐÍÓÙÇg JxwyxxzƒŽ‡vV й¿··±•…ʾ©²Í¢„ ®‡ŒzrgΰÁ¿ƒ ÃË»¾«Ö»®°ƒ‚ –èçëÝÖÕËš‹‘y šêìÙˆVb—ÙÔΆ ðå}@ªàà™÷à`‚æê£¡úÝT“îñ¨ ¡ùñ£2U´ôö­ úüwÃôôû¯€ùøðñöõòû¯‚ÔÖÖÔÑЀÍÓ’ |áêêäãèåéíç‹f—”€•™¤ªŸ•qs8mk`````c>LÿÿÿÿÿÿþeLÿÿÿÿÿÿÿÿeLÿÿÿÿÿÿÿÿÿeLÿÿÿÿÿÿÿÿÿý=LÿÿÿÿÿÿÿÿÿÿhLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgLÿÿÿÿÿÿÿÿÿÿgNÿÿÿÿÿÿÿÿÿÿj7ÀÀ¿¿¿ÂËÆÀÄJ ICN#ÿðÿøÿüÿþÿÿÿÿ€ÿÿÀÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿðÿøÿüÿþÿÿÿÿ€ÿÿÀÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàÿÿàil32:‚‹Ž€Š€}}ytlmÈßÙØÕÔÒÑÍËÇ¿²¢”,ÂåÍÉÙÓÉÃÇÅÃ˰¡˜ ŒÂÊ5°[“(}<Ïɼ™§² ‹ÅÅ&¼¯HÜ<È0–ÕÎÄ¡—ë¬ ŠÇÃ3Ù¬EÙ6Ót3ÚÑÊ«•ûï¬ ‰ÅבçȔ݋Óz—ÛÕβ•êíä°ˆÅìêáåêáêâëèÜÙÓºŒmepŒ‡Çì‚äéèÛÊÑàÝÆ¡†}}~‘‰‡Çïææåæí³r€ (›Ðǵ´´®¨š-†Èñççéí[[J=ÈÙÐÏÊé'†Íôêêó\`nž[ÀÔÝÖÔѹ+†Íöìò¿££åèúœ“,eëÛ××Â*†ÎùïöcjvÿúøøýÕ\I\ÑáÜÜÉ/†Òûòí„ó÷ ø÷¢?¦ìááÎ/†ÓþöÚL£óø÷ ö±fñååÒ/†ÕÿøåFÞû÷ ÿ¡šôèèÕ3†Õÿöö:€½×ý€÷ þÈÆIÆóëìÙ3†Õÿöÿ£¤ÏöúýéËQlððíïÛ3†Õÿ÷úêMVÙÒ‘¶&R©ùððñÞ3†Óÿù÷ÿË©~ Žüòññôâ3†Óÿ€ùÿÌU&€ F%šýôôòòõã8†ÕÿúúùùÿþÅzel£öÿõõôôòöä8†â‘ÿó8† ^a_a[b[_`bddce€c€bd[§‡#eŸ_taUrrkf)FvŒŠ%|e‰jqcU*{e†P¤|u}o±)Ž„7¡šÆ‚‹Ž€Š€}}ytlmÇßÙØÕÔÒÑÍËÇ¿²¢”,ÂäÍÉÙÓÉÃÇÅÃ˰¡˜ ŒÂÊ5°[“(}<Ïɼ™§² ‹ÅÅ&¼¯HÜ<È0–ÕÎÄ¡—ë¬ ŠÇÃ3Ù¬EÙ6Ót3ÚÑÊ«•ûï¬ ‰ÅבçȔ݋Óz—ÛÕβ•êíä°ˆÅìêáåêáêâêåÛÙÓºŒmepŒ‡Çì‚äåäáÝÜÝØÄ£†}}~‘‰‡ÇïææååçÚÆ£©¡²ÎÒö´´®¨š-†Èñ€çèÀ“º©·™­µ©ÕÕÑÏÊé'†Íôêêìéš¼¿É»Ð£©°ÜÚ×Ôѹ+†Íöìí࣠ÊÊÕ×ÚÈDZŒÃáÛ××Â*†ÎùïñƾÃÀÛ€Ù ÚÓ»·¾ßàÜÜÉ/†Òûóð¥Å„Ùɴ׿ááÎ/†Óþõì«·Ê׃Ùͽ¦ÑëååÒ/†Õÿõ𤢶ÔÚÙ Úʤ™ÖïèèÕ3†Õÿöö¹ÂÏÓÚ€Ù ÚÑзžäïëìÙ3†ÕÿöøÛœ›ÉÒÙÙÚ×ѧ¹ÆðïíïÛ3†Õÿ÷÷ô§«¸ºÓÒÇίº•ÝôððñÞ3†Óÿù÷ú骘ʤ«ÉÔöòññôâ3†Óÿ€ùûëðŒª—·´Ú÷ôôòòõã8†ÕÿúúùùúúéÑÊÍÝõùõõôôòöä8†Ú‚ÿþþ‚ÿýûû€úùûé8† ²ÒÊÊÈÊÈÊÉÊÌ̂ʀÉ˼*† }®§¡²š±¡¢š€‘ “‘“’’ˆ!†€à¹ÎáÌÓÍȶÑÑϮκÃÔ·Ûµˆ!†€ÁÕÎÚÏÓÍȺÔÎÙÇãÕÓÕÒ缊!†ƒ¸´°³®À®¯ª´°´¬»°Æê³¿«Ž!†kql€mlm ps~Žqloq“¨‚‹Ž€Š€}}ytlmÇÝÙØÕÔÒÑÍËÇ¿²¢”,ÂäÍÉÙÓÉÃÇÅÃ˰¡˜ ŒÂÊ5°[“(}<Ïɼ™§² ‹ÅÅ&¼¯HÜ<È0–ÕÎÄ¡—ë¬ ŠÇÃ3Ù¬EÙ6Ót3ÚÑÊ«•ûï¬ ‰ÅבçȔ݋Óz—ÛÕβ•êíä°ˆÅìêáåêáêáêåÛÙÓºŒmepŒ‡Çì‚äåêâáßßÚÄ£†}}~‘‰‡ÇïææååçØ£È£Ã¾½Öö´´®¨š-†Èñ€çæØËB|U³nZÚÖÔÑÏÊé'†ÍôêêìÜz­I@M–v¼àÚ×Ôѹ+†ÍöìíÞ¢›€ %mÐÐßÛ××Â*†Îùïô·63:ƒKRpèàÜÜÉ/†ÒûñðÐÈ.„`°ãåááÎ/†Óþôó¤S„ F‡ÛêååÒ/†Õÿõò¿—\„•°áìèèÕ3†Õÿöú³)†V¸êïëìÙ3†ÕÿöûŸ°ƒŠIôïíïÛ3†Õÿ÷÷øÔtWP$qNÈîòððñÞ3†Óÿù÷úì°§“4}Ç®Óöòññôâ3†Óÿ€ù úø´xÏt¯Xªí÷ô€òõã8†ÕÿúúùùúûíãÕßíñ÷õõôôòöä8†Öÿƒüþþÿüüú€ù÷÷öúè8†ÁæÞÞÝÞÝÞ݂ނÝÛßÏ/† £ÑÊÆÐÂÑÆÆÂ€½ ¼¾¼½¾¼½¾³*†¥ðÔàìßäàÞÓääâÍàÖÚäÓéÓ³*†¥ÝåâèâãàÞÖåàèÝîåäåãðر*†ªÝ×ÕÖÒÝÔÓÑÖÕÖÐØÒßöÖÜÒµ/†Š“ŽŽŽ€ Ž–¤©£¨¥‘Ž‘“¨l8mk*;;;;;;;;;;;;1 Äÿüüüüüüüüüüýû®ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí'Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò4Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò5Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø6¤ØÓÓÓÓÓÓÓÓÓÕÙæëäÜÖÓÓÔ¿* 455555555567<=;86555& ich#Hÿÿüÿÿþÿÿÿÿÿÿ€ÿÿÿÀÿÿÿàÿÿÿðÿÿÿøÿÿÿüÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿüÿÿþÿÿÿÿÿÿ€ÿÿÿÀÿÿÿàÿÿÿðÿÿÿøÿÿÿüÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿih32\„D4ƒ1‡)+/˜™ÔÑÐÏÏÌËÉÆÅÅ¿¹¯©¢™x–†çßÝßßÜÜÛÙ×ÕÔÓÐÎÍɺ­¦šs•wäÛäçæÛÜâÙááÝÕÙÙÐÉž³¤—Ÿs”xåâoAOʰXÉMBAŸh@–ÑÊż¬”–´l“xåç)R¼Ý‘Õ¡ {œ|‘ÓËÊó™„Í»l’xæç22«ì“ÝÙ¦ÍCÛÐÎËȺŸÊç¸l‘xçè15­ì”ßÕ ê­ kÜÑÏÊ¿§€Éúâ¹kxçè'lòç‘ß֣ń1?áÔÑΫƒÅÿõá¸lxêær›çå´bàÛ^¾ÙbO´ÜÖÔÐů†Èÿÿûè¼lŽxêáëçááåìááìäàèêàÚÙÖÓɳ‰ŒŒ’¡µ®wxì‡âááààÝÜÛÙÕ͸šxbYX\e€lŒxì‚ä€âäâäéíìéêçàÙп§€{}~‰“U‹xíƒå€äíâ­uMLLt´ÚÝʺ¬¡€Ÿš—¡‹‹|ðçæç€æåçë—f<€jÝÎþ€½º´­®Ž‹|ñƒçêáDÀ,’”EÔØÑÐÎÎËž½‹ |ôêèêèèëâH€©váßpJÚÝ×ÕÓÑÏÉÊ—‹~õ‚ëóLwǪ$ÿSæÂtMçÜÚ×ÖÓÐÔ¡‹~öìõ¡ìV¦ö¾ûäÿJM퀣çÜÚÙÖÔÚ¦‹€÷íîh†Xjÿåøý÷úöÕÿj€hâßÝÛÙÖß­‹ €úðïðôÆ$êª>àý‚÷ý铳ЮI¸æàÝÜÚᮋ€û€ñüˆûÿó…÷ ÿË‘F…ðäáàÝæ²‹€ü€òýY€Wéú„÷þ¾€Zóåäáà賋‚þ€ôýN™âýú†÷ øÿá˜Söçæäâë·‹‚ÿ€õÿR€EËý„÷úæd€Wùëèæåí¸‹‚ÿ€õÿ{8‚ïû„÷øÿÄ€zùìëèç𻋂ÿ€öý²×ÙôÊéû‚÷ûÛvì¼¹öíìêèò»‹‚ÿ€öøëj€Uÿðöø÷û÷öÿ1©«eéðïíìêõ¼‹€ÿ€÷öÿ‹€ ì“\ÿôøÝþ§œì€‹ùððïíìö¿‹€ÿ÷ùõIý†ÿ@Ê»M}òóñ€ðïùÀ‹~ÿù÷ù÷÷þÓHúDï‚«€"Ôøò€ñððû‹~ÿ‚ù ÷ÿТ7§R±€ÐüòññðüÄ‹~ÿ„ùÿìZ^€Dg4\íú€ô€òññþÆ‹~ÿúùûÿ܆.,yâÿøõõô€òþÆ‹~ÿ„ú€ùûÿÿöî÷ÿÿú€öõ€ôòÿÆ‹€ÿ„þýýþþÿýý€üú€ù€øÿÊ‹xãØÙم؃׀ÕÖÔÓÒܪ¾ ;6@ ¡µyc‰²¥d½±`H>@]1i#PH[½o–º1Ÿ½©WŸ˜xÅ>j¾¿p‰P¼Ò)´Nmg 4¨ŰVic:µ0€—¿ ´C‚d»o7A,]N‘_s,?<uPx}o ˆ‡q§Vˆl«ÿ™„D4ƒ1‡)+/˜™ÔÓ€ÑÐÏÏÌËÈÆÅÅ¿¹¯©¢šx–†çÝÝßÝÝÜÛÙ×ÕÔÓÐÎÍɺ­¦šs•wäÛäçæÛÜâÙááÝÕÙÙÐÉž³¤—Ÿs”xåâoAOʰXÉMBAŸh@–ÑÊż¬”–´l“xåç)R¼Ý‘Õ¡ {œ|‘ÓËÊó™„Í»l’xæç22«ì“ÝÙ¦ÍCÛÐÎËȺŸÊç¸l‘xçè15­ì”ßÕ ê­ kÜÑÏÊ¿§€Éúâ¹kxçè'lòç‘ß֣ń1?áÔÑΫƒÅÿõá¸lxèær›çå´bàÛ^¾ÙbO´ÜÖÔÐů†Èÿÿûè¼lŽxêáëçááåìàáìäàèêàÚÙÖÓɳ‰ŒŒ’¡µ®wxì‡âááààÝÜÛÙÕ͸šxbYX\e€lŒxì‚ä‚â äãåãâáàÜ×п§€{}~‰“U‹xíƒå€äæåÙÉ¿½½Ç×Ü×ʺ¬¡€Ÿš—¡‹‹|ðçæç‚æçÒõ““­’’¥ÃË×Ëľ€½º´­®Ž‹|ñ„çå¼”–б—Èš‘«Æ”ºÚÔÑÐÎÎËž½‹!|ôêèêèèê绕’’ÊÀž× ¨ÖÀ–»ÜÚ×ÕÓÑÏÉÊ—‹~õëê쾘Á§’Ñʮܺ×Ж§Á—½áÜÚ×ÖÓÐÔ¡‹~öìíØ”«ØºÊÙÏÚÕÛ¶·Ø«‘˜ÔàÜÚÙÖÔÚ¦‹€÷‚íÅû’¿ÝÕÙÚ€ÙÒÜ¿’’•ÄâßÝÛÙÖß­‹ €úðïðð䧯ØË´ÔÚ‚ÙÚ×ÇÍÆÍ¹ÚäàÝÜÚ⮋€û€ñõÔ’®ÚÛ×…Ù ÚÑÇ·•ÏèäáàÝæ²‹€ü€òöÄ•›»Ø…Ù ÚϪš’Áëåäáà賋‚þ€ôöÁ­ÈÕÚÚ‡Ù ÛÕÈ­¿íçæäâë·‹‚ÿ€õ÷Öž§´ÑÚ…Ù ×½§¡—Áðëèæåí¸‹‚ÿ€õùЧ³ÂØØ…Ù ÛÑ ‘’Îðìëèç𻋂ÿ€ö÷á®ÕÔÙÑ×Ú‚ÙÚÔÀØÐáðíìëèò»‹‚ÿöóÅž˜›ºÜØ€ÙÚÙÙܱÌÌÄïðïíìêõ¼‹€ÿ÷úÖ’’ ØÇ»ÛÙÙÔÚÊÈØ ”˜Óôððïíìö¿‹€ÿ÷ùö³’Å·”ÈÚÅÛ´ÑÏ–¸Ã‘´òññ€ðïùÀ‹~ÿù÷ù÷÷øì±ž·Ú¶£Ø¡ÃË”’Ÿ²ëôò€ñððû‹~ÿƒùúë«Ë³‘›Ì—ºÍ‘‘¬êöô€òññðüÄ‹~ÿ„ùúõÆ¿ž“¶’—¾¶Èóö€ô€òññþÆ‹~ÿúùúûñÕ¸­±­·Ðñùöõõô€òþÆ‹~ÿ„ú€ùúüû÷õ÷úú÷€öõ€ôòÿÆ‹~ÿü…û„úù÷€ö€õÿÇ‹|ù‚ð€ïð„ïî‚í€ëêê÷¾‹Z¢˜—™™——š˜—˜š˜™Žš¢}‹Q™§Á£ž¾¶”ªÁ¬”´ ’‘ ”’‘’”’‘’”‘‘”œz‹!QšèÕ©ÍÚè´ãÍëœç²­ËÄÁÁ˜µÊ´—¼Ï¹œÇÄ›œz‹!Q™Êë™Ðßé½á­ë¡å®ÉáÝÔí¶ÁÏë²ìÒÚÇéðº™z‹!Q›¢çÆÐÏá½å·í ç¯ÉÏÍÀç¼×ßì·èÃ×Îëаšz‹!Qš½Ü¯Â¼Ì°ÆÜÌ—Ó¨¼ÂÀ¶Ó²ÇÔÕ¢ÒâÚ«ÚÓ¨›z‹U¡›œšœœ››šš››œ›š˜•˜–¤ÎàÖ–œ›¤}‹F~wuŠt vx}†ŽŽ‰‡•“|€tu|iž #í„D4ƒ1‡)+/˜™ÔÑÐÏÏÌËÈÆÅÅ¿¹¯¥¢™x–†çÝÝßÝÝÜÛÙ×ÕÔÓÐÎÍɺ­¦šs•wäÛäçæÛÜâÙááÝÕÙÙÐÉž³¤—Ÿs”xåâoAOʰXÉMBAŸh@–ÑÊż¬”–´l“xåç)R¼Ý‘Õ¡ {œ|‘ÓËÊó™„Í»l’xæç22«ì“ÝÙ¦ÍCÛÐÎËȺŸÊç¸l‘xçè15­ì”ßÕ ê­ kÜÑÏÊ¿§€Éúâ¹kxçè'lòç‘ß֣ń1?áÔÑΫƒÅÿõá¸lxêær›çå´bàÛ^¾ÙbO´ÜÖÔÐů†Èÿÿûè¼lŽxêáëçááåìááìäàèêàÚÙÖÓɳ‰ŒŒ’¡µ®wxì‡âááààÝÜÛÙÕ͸šxbYX\e€lŒxì‚ä€âäââääâäàÝÛ×п§€{}~‰“U‹|ïƒå€äåêêÙÓÈÓÖÞàÕʺ¬¡€Ÿš—¡‹‹|ðçæçƒæãmÀ¼l½Â ŒÝÖËľ€½º´­®Ž‹|ñƒçæéÖ±l¼%´Ð}ÆÓÜÔÑÐÎÎËž½‹|ôêèê€èê¹²ÇÈ<¥¢‡>б¸àÚ×ÕÓÑÏÉÊ—‹~õëêìØ¬8ŒÈvS¾‹9¯ÔàÜÚ×ÕÓÐÔ¡‹~ö‚ìéÇÒ|S‚[X€ÈÂáßÜÚÙÖÔÚ¦‹€÷íó—%NÇB† CÉɶ–æßÝÛÙÖÝ­‹ €úðïððé›ob† $+ lìâàÝÜÚ᱋€û€ñôáÂÐvŠ &Z¼ÞçäáàÝæ²‹€ü€òôÚ¿°Oˆ „³ÉÃ×èåäáà賋‚þ€ôöÎjŒ lËìçæäâë·‹‚ÿ€õöر¥Œ^ˆ E‰ž°Õïëèæåí¸‹‚ÿ€õ÷àÂe2‰  ÍÁÞïìëèç𻋂ÿöô}Š ;¦´çðíìêèò»‹‚ÿöû}š·®S† l¨ôðïíìëõ¼‹€ÿ‚÷åÁÈŸ%M‚¤Æ±äñððïíìö¿‹€ÿƒ÷Ѹ4YÆ.a¾V5¼Óòññ€ðïùÀ‹~ÿù÷ù÷÷ùõª–ÓZ^•ž0ÆË”«óòò€ñððû‹~ÿ„ùñÑÁgЮ¹S žÒðõô€òññðüÄ‹~ÿ…ù öãešÂ¹W½°<ƒáôõ€ô€òññþÆ‹~ÿú‚ù ûñÛÔÍ´Í×èì÷€õô€òþÆ‹~ÿ„ú€ùúûúùù÷ùù÷€öõ€ôòÿÆ‹~ÿ…û„ú€ù÷ö€õôÿÆ‹|þõ„ô‚òóóñðïúÀ‹ iËÁ¿Â¿ÁÂÁ¿ÁÂÁÂËž‹iÅÊÙÈÄØÓÀÌÙ̾ÒÅ‚½¾€½¾€½¾½½¾É‹!iÇðåËàéñÑîàóÄðÐÍàÜÙÙÁÒßÑ¿×âÔÄÝÜÃÈ‹!iÅßóÂãëó×ìÍóÆïÍÞìëåôÓÙãóÐóãèÝóöÖÇ‹!iÇÈñÝãâî×ïÓôÆðÍÞâàÙñ×èëóÔðÚæàóãÐÇ‹!iÇØêÏÚÕßÐÝêß¿äÊÕÙØÓäÐÝ忯ãìèËçäÊÈ‹hÎÇÈÇÈÇÈÇ‚ÈÇÇÅÃÁÂÂËäðêÄÈÈÇÑŸ‹Y¢™‹– ˜š ¬¶¶¯ª¯¬›–†ž*(ìh8mk   Sîèèèèèèèèèèèèèèèèèèç¹DlÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôT uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñQwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòRwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñQwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñPwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè3wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’ wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ aÜÞÝÝÝÝÝÝÝÝÝÝÝÝÝÝÞàåñûùôîæâÞÝÝÝÜÞ #ASTTTTTTTTTTTTTTUWZagfc_[WUTTTSH- it32PŠÿä–ÿä–ÿ„à†ß‚ÞÝ€Ü ÛÚÚÙÙØØ×ÖÖ€ÕÔÓÓÒÑÑÐÎÍÊÈÅÁ¿¾¹¶´ºÌΤ–ÿ„àá…àßàßàß‚ÞÝÝÜÜÛÚÚ€ÙØ×ÖÖÕÕÔÔÓÓÒÑÐÏÎÊÇÅ¿½¹µ²¯¬´î®¢–ÿ„ˆáàáá€à€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÆÃ¿¼¹¶²®©«Æ_¡–ÿ„ââ…áâá€à€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÇ¿¼¸µ°¬§¨À+ –ÿ„âáâ€áâáàà€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÏÏÊÉÆÂ¾»·²®ª¤©Â0Ÿ–ÿ„„âáá‚âáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÏÍËÈÆÁ½¹´¯ª§¢³Â-ž–ÿ„Œâáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÎÍÊÈÄÀ»·±¬¦¢¢½Á*–ÿ„âáà‚߀ÞÝÜÜÛ€ÚÙØ××ÖÖ€ÕÔÓÓÒÎÎÊǾ¹²­¦¢¬ÈÀ*œ–ÿ„Žãâáà߀ÞÝÜÜÛÚÙØØ××ÖÕÕÔÓÓÑÏÍÉÅ»¶¯©¡œ™ÃÊ¿'›–ÿ„„ã„y€ãâ€áàà†ÛÚ €HÉ×ÖÕÕÔÓÒÑÎËÇÿ¸°ª£›•ªÓÊ¿'š–ÿ„„ã„yã€âáà†ܾ‚V××ÖÕÕÔÓÒÑÌÊÅÀ»³ª£œ”“ÝÓÊ¿$™–ÿ„„〆ã€ââá€à€ßÞÞÝvIÚÙ+Ø×ÖÖ€ÕÓÒÑÍÉüµ¬£›”×ÝÓʾ!˜–ÿ„„〆 âáàà€&ßßÞÝvfÛÚÙÙØØ×ÖÖÕÕÔÓÒÏËÆ¿·®¥›”‹ÉåÝÓʾ!—–ÿ„„䀆ä€ãâá€àßßÞv€¡Û€ÚÙØØ××ÖÕÔÓÐÍǹ°¦“Œ¾íåÝÓʾ––ÿ„„䀆ä€äãâ€ààßßÀ€¯Û€ÚÙØØ××ÕÔÔÑÏÉü²¨ž”гôíåÝÓʾ•–ÿ„„䃃ä€ääã€áà•€ ÍÜÛÚÚÙØØ×ÖÕÔÒÏÌÆ¿¶ª •ЍúôíåÝÓʾ”–ÿ„„䃃䀀ä€ã€ááàw€ ,ÜÜÛÚÚÙØØ×ÖÔÒÐÍÇÁ·®¡–‹šÿúôíåÝÓʾ“–ÿ„„倆å€åä䀀âá€àY€gÜÜÛ€ÚÙÙ×ÕÔÑÏɺ¯¤—‹–ÿÿúôíåÝÓʾ’–ÿ„„倆倂åä€ã€âá€à-ÝÜÜÛ€Ú ÙØÖÕÓÏÊû±¦™€ÿúôíåÝÓʾ‘–ÿ„„倆倂åä€ãã€âáàà€ÞÝÜÜÛ€Ú ØØÖÓÐÊü³§›ŽŽÿúôíåÝÓʾ–ÿ„„å€†å€ƒå€ äããây´à³ßßÞÝÝÜÛÛÙØ×ÔÐÌż´¨†‚ÿúôíåÝÓʾ!–ÿ„ææ‚å€æ…倃å€ääã㦃w€ßÞÝÝÜÛÚÙØÕÒÌǾµªž‘…ƒÿúôíåÝÓʾ!Ž–ÿ„€çæ€ç…怃怀åääˆxáà€ßÞÝÝÜÚÚÙÕÓÏÈÁ¶«Ÿ“†„ÿúôíåÝÓʾ!–ÿ„ƒç€æ‚çŽæåää€ãâ€áà€ßÞÝÝÛÚÙÖÓÎÉÀ¸¬ ”‰…ÿúôíåÝÓʾ!Œ–ÿ„…çæ…çææç‰æåää€ãâ€á€àßßÞÝÜÚØÕÐËø®¡•‰†ÿúôíåÝÓʾ'‹–ÿ„•ç†æåää€ãâ€á€à!ßÞÝÝÛÙÖÑÊù®£—‹€vnn‚€€Š¢¯¿ÑãÝÓÊ¿'Š–ÿ„’èççè‡çæåå€äã€â$áààßÝÝÜÚÖÑÌÄ»±¤™Ž„{slifddegimpt’¬ÉÊ¿'‰–ÿ„–è‡çæåå€äã€â$áààÞÝÜÛØÒÎÆ¼³§œ’ˆxsnljjklnqsvzƒŸ¾À-ˆ–ÿ„éšèƒçæåå€äã€âáàßßÝÜÙÕÏÉÀ¶¬¡—ކzwt€s ttvy|~„‰¤¾0‡–ÿ„ƒéšè€ç€æåå€äããââáàßÞÜÚ×ÑÊú°§œ”‡ƒ~|€} €‚„‡‰Œ‘¼]†–ÿ„…éèé”è€çæå€äããââáàÞÝÛ×ÓÍžµ«¤œ•‘Љ‰ˆ‚‰ ŠŒŽ‘”——¢É†–ÿ„Šê•éèèçæåä€ãáàÞÜØÔÐɺ²ª¥Ÿ›—•€–€• –˜——››­ê…–ÿ„ê’éèè€çææ€åäããâáßÝÚÕÑÍÆ¿¹³­©¦¢¢¡€¢ ¡¡  ¡  ¡¡¢£Ã „–ÿ„‘êŒé5íØÄ³›„vzw|®½ÉíâäââàÞÝÙÕÐÌÆÁ¼¸³±°­®­®¯®¯¯¬¬«ª¨©§§¨¦¦¹„–ÿ„€ë‘ê†éçâ®rA€> 4c•×áãâàÞÛØÔÐÌÇÄÀ½»º‚¹ºº¹¸¶µ³²°¯®¬¬«®Ø„–ÿ„ƒë€êëë‹ê‚éåËj„Ž#ƒdy´ÔáàÞÜØÕÑÎËÈÆÄÃÂÃÂà ÂÀÀ¾½»¸¶µ²±¯±¾„–ÿ„…ìëììŒë êêçÎdt¯£]‚Â@„`¼4H¶×ßÞÜØÖÔÓÏÍÌËËÊËÊÊÉÇÆÄÁÀ¾»º·´³¶„–ÿ„‹ìŠë Ömƒüÿ´5ðe„1ø™FËÞßÜÛØÖÔÔÓÓÒÑуРÎÌËÈÅÿ½º¶¶„–ÿ„ì‡ë»9€†ÿÿˆ€ZÿŒ„GøØ%+šáßßÝÛÚÚØØ×Ö×ÖÖ€Õ ÔÔÒÏÎÌÉÇÄÁ¾º¸„–ÿ„ííŽì‚ëè’ƒ.ñÿç3€‡ÿ¸ ƒœÿëF€uààßÞÝÝÜ€ÛÚ€ÙØ××ÖÖÔÑÐÍËÈÅ¿»„–ÿ„îŽíììߌ „ áÿöZ²ÿÝ$`óÿà5\ØâááàßßÞÞÜÜÛÛÚÙÙØ×ÖÖÓÒÎÌÉÆÂÀ„–ÿ„„îííîîˆíæx … äþùk Õÿ÷D€™÷üÿ¸ ƒTÕããâááàßÞÞÝÝÜÛÚÙÙØ×ÖÓÒÏÍÉÆÃ„–ÿ„Šî…íæˆm3„9õûþƒBìüÿn;ÂÿúüóK‚y'YØããâááàßßÞÝÝÜÛÛÚÚÙØÖÔÒÏÍÊÇ„–ÿ„Œîƒí£ L×h‚dÿøÿ¶eýùÿš(ßÿøùúz‚FÆyræääãââáààßÞÞÝÜÜÛÚÚÙ×ÕÒÏÍÊ„–ÿ„ðï€îÏ€˜þ¨,{ÿ÷üé$“ÿ÷ÿ½ ¡ÿ÷÷ÿœ € ˆõÁ œáååäãââáààßÞÞÝÜÛÚÚÙ×ÕÒÐ΄–ÿ„ðŒïæAÍÿåixÿ÷÷ÿx¾ÿ÷þÖTéü÷ûì-€JÌÿð9É€åäãââáààßßÞÝÜÛÛÚÙ×ÕÒЄ–ÿ„ƒð€ïðð…!Põÿö .Uÿø÷ýÖL×þ÷úé¶ôø÷ÿ°‚íÿþ€‚Yç€åäããâááàßÞÞÝÜÜÛÚÙ×ÕÒ„–ÿ„Šð‚ïׄ–ÿûÿáf$Øý÷÷ûßðø÷÷öõø÷øþaHÎÿýÿ½ƒ·æ€åäããâááàßßÞÝÝÜÛÚÙ×Õ„–ÿ„ðïì{ "Öÿ÷ÿú ¨÷ø÷÷ûø÷ ø÷÷üêLƒëÿøûóH…HäæååääããâááàßßÞÝÝÜÛÚÚׄ–ÿ„òòŒñÕA® X €^øú÷úÿçñøˆ÷ùëÖÿý÷øÿ’†Uºççææå€ä ãââààßßÞÝÝÛÛÚ„–ÿ„‚òˆñðˆvù€ÿø¤ ÿ€÷ù‹÷øüø÷÷ÿÍ…0Áeáèçææå€ä ãââáààßÞÝÜÜÛ„–ÿ„„òññòò‚ñß|©‚‘çÿûÿÈE"äþ’÷ûðCOeT!FÏÝ&Çèèçææå€ä ãââáààßÞÝÝÜ„–ÿ„òóˆò€ñÇ#=»ÿ÷ÿê‹: lóú‘÷û¾ŠÖîõðÙ»ª¸êÿž•€èçææå€ä ãââáààßÞÝÝ„–ÿ„‹ôóñ‚ Ûÿ÷ýÿóÈ›ãû‘÷õêÿÿûúúþÿï4Wí€êéèèçææåäããâááàßÞ„–ÿ„ŒôìNƒdøú÷÷ûÿþ”÷ùø€÷ü€ÿýÛb2Îë€êéèèçææåääãâááàß„–ÿ„õõŠôä$ƒŠÿü€÷ø–÷øÿÿé¾›m€·ìë€ê éèèçææååäãâááà„–ÿ„ƒõ†ô¼„¥ûÿû—÷øÿÛƒ8…’ììë€êéèèç€æåäããâá„–ÿ„‰õ€ô¨†W¯âö•÷ùø¡ˆt€ìë€ê éèèçææåääããâ„–ÿ„‹õôƒ „'=yÌ÷ø”÷ùöµvQ/„W€ìëëêêééèèçææåääãâ„–ÿ„Œöˆ€ Iw¨Ììýÿû˜÷€ÿñÕ´„X% €Cî€íììëëêêééèççæååã„–ÿ„÷‹ö q$f‘¾ßòüÿÿûøœ÷øûþÿþõäÆ˜q5Eïïîííììëëê€éèççæåå„–ÿ„‚÷‡öpg›Îëû€ÿþúøš÷øúüÿðØ©|0Bððïîííììëëê€éèççæå„–ÿ„„÷öö÷÷ö !HmœÀâóýÿø—÷ ùúöçÈŸuS-H€ðïîîíììëëê€éèççæ„–ÿ„Š÷öö „AlŸëú•÷ùÛ†G …[ðï€îììëëê€éèçç„–ÿ„ö‹÷ž‡€ðú•÷øê½p†wñðï€îíìëëê€éèç„–ÿ„Œ÷¾…%fÈÿú—÷úÿÿ½…ññðï€îíìëëê€éè„–ÿ„÷øø‰÷é%€jž´Þûÿøš÷øÿºƒ ¸òññðï€îíììëê€é„–ÿ„öƒø÷÷ø‚÷õO<Éÿþø€÷úø’÷öþÿýø÷øÿ”ƒ0Ê€òñ€ðïï€îí€ìêéé„–ÿ„öˆø€÷õ˜Ðÿþûùúýÿãðø÷ ùô°°äýýøûíB‚Tìòññððïï€îí€ìëê„–ÿ„õ‹ø÷ÅkÿûѸÄÞöþüꨖóú÷øþ—#}âÿùþàQƒòññððïï€îí€ìë„–ÿ„öŒøê1¦á[ AQL)3àü’÷úôK)žþüý﬌®ƒÌóó‚ò€ñðïï€îí€ì„–ÿ„õø’§X†§ÿ€÷þû‹÷ úø÷÷ÿÏ ƒõÿ¢aì€ó‚òñïï€îíìì„–ÿ„ôù‰øÓf…^öú÷úÿÖàúˆ÷ø÷çüü÷øÿ’H˜°_©‚ó‚òñðï€îíì„–ÿ„ôƒùøøùùƒøô}… $Ùÿ÷ÿû«4¾ÿ÷÷øø÷ ýù÷÷ýÀ’ìÿøûóH…<ç„óòñðð€îí„–ÿ„ó‰ù‚øàƒ ™ÿúÿÞ`9æü÷øôõ÷÷ø÷Ðóù÷úóC?Êÿûÿă¼ôô…ó€òñððïîî„–ÿ„òŒù€øŠ‚ Løÿý¦(‚ÿø÷þÈÖü÷úïH²ÿ÷÷ÿˆ}÷ÿÿ€ƒS‚ô…óòòñððïî„–ÿ„ñŽùøßF"ÇÿÜh Òþ÷øÿ‚®ÿ÷þÞLúù÷ÿ«LÅÿë9Ê„ô…óòñððï„–ÿ„ñúùÒ€›ÿ¢(tÿø÷ÿÍÿ÷ÿÁÈþ÷ÿ° € ÷Æ °ôõ…ô„óòñðð„–ÿ„ðúŒùöŸ KÍk Mçü÷ÿñLfýùÿ™þøÿ–‚LÆttó€õ…ô…óò€ñð„–ÿ„ïƒúùùúú‡ùô…r-‚'âÿøÿà\AíüÿnIôûÿg„‚+Rçƒõ…ô„óòòññ„–ÿ„ï‰ú†ùò€ƒ…ÿúû³-€ Óÿ÷A1èÿúB…_á†õ…ôƒóòòñ„–ÿ„î‹ú…ùòƒ Áÿÿ ¬ÿÛ!(Ýÿõ7…Wá€ö†õ…ô‚óòò„–ÿ„îŽúƒùô™€ ÉÿÄ ƒ †ÿ· ½ÿýWƒ xì‚ö‡õ„ô‚óò„–ÿ„î‘úùöÊ3´ÿr„\ÿ[ÿÿµ ©õ†ö…õ…ôó„–ÿ„íû’úùãzeÿb„7ñh ‡íÿ¬. YÕ€÷‡ö†õƒô€ó„–ÿ„íû“úùöÔc©„ÅAƒ7”¸‡R»ñ‚÷‡ö†õ„ôó„–ÿ„íƒûúúûúùùïÖzw ƒ ‘!ƒ]Äå‡÷†ö†õƒô„–ÿ„í‰ûúùðã¢q5? €$\‘Þðø†÷‡ö…õ‚ô„–ÿ„íŒûŽúùööáß¹™ƒron{˜·ÕÞîö„ø‡÷‡ö…õ€ô„–ÿ„íûŽúŠù‰ø†÷‡ö…õó„–ÿ„í’ûú‹ùˆø‡÷…ö„õô„–ÿ„í”ûŽúˆùŠø†÷†ö‚õó„–ÿ„íüü”ûŽú‰ùˆø‡÷…öõó„–ÿ„í‚ü€ûüûú‰ùˆø†÷†öõõò„–ÿ„íˆüûŽú‡ù‰ø†÷†öò„–ÿ„îŠüûúûŒúˆùˆø…÷…öñ„–ÿ„îü‘û‹úˆùˆø‡÷‚öð„–ÿ„[Û–ÿ„Ü–ÿä–ÿä–ÿ‰@€€0`€€`‚`€€` €€@¸–ÿˆÿðЂÿЀЂÿЀ@ÿÿ€¸–ÿˆ ðÿà ÿ@0ÿÿ°°ÿÿ@0ÿÿ°°ÿÿ@@ÿÿ€€ @@0@ @ ƒ @@ ƒ @0 @@ Œ–ÿˆÿÿà‚@ÿÿ€@ÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€ÿÿàðÿÿ  €ÿ  0àÿ   ‚ÿÀ  ÿ  Š–ÿˆÐÿÿ @ÿÿ€@ÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€€ÿ°°€ÿ"°°ÿÿ€°ÿÀ€°ÿÿ€€ÿÿ°€ÿÿÀ€ÿÿ°°ÿÿ€Š–ÿˆP€ÿ €@ÿÿÀ€ ÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€*ÿÿààÿðÿÿð°°àÿÀðÿàÿÿÀðÿàÿÿÀŠ–ÿ‰€€ÿ`@ÿÿàÀÐÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€ ÿÿÀÀÿÀ€ÿ`€€àÿÀÿÿÀÿÿÀÿÿà€€ÿÿÀŠ–ÿŠ ÿÿð@ÿÿ€@ÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€ ÿÿÀÀÿÀ€ÿ0à‚ÿ ÀÿÿÀÿÿÀ„ÿÀŠ–ÿ‹Àÿÿ@@ÿÿ€@ÿÿ€@ÿÿ@@ÿÿ€@ÿÿ€€ ÿÿÀÀÿÀ€ÿ ÿÿp@ÐÿÀÿÿÀÿÿÀÿÿÐ@0Š–ÿˆ Àp€ÿÿ@@ÿÿ€@ÿÿ€@ÿÿ€€ÿÿ`@ÿÿ€€ ÿÿÀÀÿÀ€ÿàÿÿðÿÀàÿðÿÿÀàÿð0ÀŠ–ÿˆ°ðÀÿÿà@ÿÿ€@ÿÿ€àÿÿÀÿÿà€@ÿÿ€€ ÿÿÀÀÿÀ€ÿ`ÿÿààðÿÀ`ÿÿààÿÿÀ`ÿÿàÀðÿ Š–ÿˆ ÀÀ 00ÀÀ`0ÀÀ`0 €À 0€0ÀÀ`€ ÀÀÀ€À`ÀÀ`À`ÀÀ`ÿÿÀ`À Š–ÿÊÿÿÀ”–ÿÅÐð00ÿÿ°”–ÿÅ€ƒÿP”–ÿÆ`€ •–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä‰ÿŠÿä–ÿä–ÿ„‚à…ß‚ÞÝ€Ü ÛÚÚÙÙØØ×ÖÖ€ÕÔÓÓÒÑÑÐÎÍÊÈÅÁ¿¾¹¶´ºÌΤ–ÿ„ƒàßàßàßààß‚ÞÝÜÝÝÜ€ÚØÙÙ××ÖÖÕÕ€ÔÓÒÑÐÏÍÊÈÅ¿½¹¶³¯­´î®¢–ÿ„ˆáàáà€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÆÃ¿¼¹¶²®©«Æ_¡–ÿ„ââ„áââ‚áàà€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÇ¿¼¸µ°¬§¨À+ –ÿ„€âáâáâáàà€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÏÏÊÉÆÂ¾»·²®ª¤©Â0Ÿ–ÿ„„âáá‚âáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÏÍËÈÆÁ½¹´¯ª§¢³Â-ž–ÿ„Œâáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÎÍÊÈÄÀ»·±¬¦¢¢½Á*–ÿ„âáà‚߀ÞÝÜÜÛ€ÚÙØ××ÖÖ€ÕÔÓÓÒÎÎÊǾ¹²­¦¢¬ÈÀ*œ–ÿ„Žãâáà߀ÞÝÜÜÛÚÙØØ××ÖÕÕÔÓÓÑÏÍÉÅ»¶¯©¡œ™ÃÊ¿'›–ÿ„„ã„y€ãâ€áàà†ÛÚ €HÉ×ÖÕÕÔÓÒÑÎËÇÿ¸°ª£›•ªÓÊ¿'š–ÿ„„ã„yã€âáà†ܾ‚V××ÖÕÕÔÓÒÑÌÊÅÀ»³ª£œ”“ÝÓÊ¿$™–ÿ„„〆ã€ââá€à€ßÞÞÝvIÚÙ+Ø×ÖÖ€ÕÓÒÑÍÉüµ¬£›”×ÝÓʾ!˜–ÿ„„〆 âáàà€&ßßÞÝvfÛÚÙÙØØ×ÖÖÕÕÔÓÒÏËÆ¿·®¥›”‹ÉåÝÓʾ!—–ÿ„„䀆ä€ãâá€àßßÞv€¡Û€ÚÙØØ××ÖÕÔÓÐÍǹ°¦“Œ¾íåÝÓʾ––ÿ„„䀆ä€äãâ€ààßßÀ€¯Û€ÚÙØØ××ÕÔÔÑÏÉü²¨ž”гôíåÝÓʾ•–ÿ„„䃃ä€ääã€áà•€ ÍÜÛÚÚÙØØ×ÖÕÔÒÏÌÆ¿¶ª •ЍúôíåÝÓʾ”–ÿ„„䃃䀀ä€ã€ááàw€ ,ÜÜÛÚÚÙØØ×ÖÔÒÐÍÇÁ·®¡–‹šÿúôíåÝÓʾ“–ÿ„„倆å€åä䀀âá€àY€gÜÜÛ€ÚÙÙ×ÕÔÑÏɺ¯¤—‹–ÿÿúôíåÝÓʾ’–ÿ„„倆倂åä€ã€âá€à-ÝÜÜÛ€Ú ÙØÖÕÓÏÊû±¦™€ÿúôíåÝÓʾ‘–ÿ„„倆倂åä€ãã€âáàà€ÞÝÜÜÛ€Ú ØØÖÓÐÊü³§›ŽŽÿúôíåÝÓʾ–ÿ„„å€†å€ƒå€ äããây´à³ßßÞÝÝÜÛÛÙØ×ÔÐÌż´¨†‚ÿúôíåÝÓʾ!–ÿ„ææ‚å€æ…倃å€ääã㦃w€ßÞÝÝÜÛÚÙØÕÒÌǾµªž‘…ƒÿúôíåÝÓʾ!Ž–ÿ„çƒæ€ç…怃怀åääˆxáà€ßÞÝÝÜÚÚÙÕÓÏÈÁ¶«Ÿ“†„ÿúôíåÝÓʾ!–ÿ„ƒç€æçæåää€ãâ€áà€ßÞÝÝÛÚÙÖÓÎÉÀ¸¬ ”‰…ÿúôíåÝÓʾ!Œ–ÿ„…çæ‚çæçç€æçˆæåää€ãâ€á€àßßÞÝÜÚØÕÐËø®¡•‰†ÿúôíåÝÓʾ'‹–ÿ„“çæç†æåää€ãâ€á€à!ßÞÝÝÛÙÖÑÊù®£—‹€vnn‚€€Š¢¯¿ÑãÝÓÊ¿'Š–ÿ„”èˆçæåå€äã€â$áààßÝÝÜÚÖÑÌÄ»±¤™Ž„{slifddegimpt’¬ÉÊ¿'‰–ÿ„—èçè„çæåå€äã€â$áààÞÝÜÛØÒÎÆ¼³§œ’ˆxsnljjklnqsvzƒŸ¾À-ˆ–ÿ„éšèƒçæåå€äã€âáàßßÝÜÙÕÏÉÀ¶¬¡—ކzwt€s ttvy|~„‰¤¾0‡–ÿ„ƒé—èçèç€æåå€äããââáàßÞÜÚ×ÑÊú°§œ”‡ƒ~|€} €‚„‡‰Œ‘¼]†–ÿ„…éèé”èçèçæå€äããââáßÞÝÛ×ÓÍžµ«¤œ•‘Љ‰ˆ‚‰ ŠŒŽ‘”——¢É†–ÿ„Œê’é€èçæåä€ãáàÞÜØÔÐɺ²ª¥Ÿ›—•€–€• –˜——››­ê…–ÿ„ê’éèè€ç€æååäããâáßÝÚÖÑÍÆ¿º³­©¦£¢¡€¢ ¡¡  ¡  ¡¡¢£Ã „–ÿ„‘êŒé5îèßßÛÑÌÎÌÎ×àÝàíääââàÞÝÙÕÐÌÆÁ¼¸³±°­®­®¯®¯¯¬¬«ª¨©§§¨¦¦¹„–ÿ„€ë‘ê†é#êîÝ̺®¦¤£¤²¦£¤¦«¶ÈÔëæãâàÞÛØÔÐÌÇÄÀ½»º‚¹ºº¹¸¶µ³²°¯®¬¬«®Ø„–ÿ„ƒë€êëë‹ê‚é(ëéÉ®¢¡¢¤¥¦¥§Å­¥¦¥¤£ ¤ÀÊÜàáàÞÜØÕÑÎÌÈÆÄÃÂÃÂà ÂÀÀ¾½»¸¶µ²±¯±¾„–ÿ„…ìëììŒë êêëèÆÃÊȹ¨¥€¦¥ªÐ²¤‚¦£¹Ï²ºÝáßßÜØÖÔÓÏÍÌËËÊËÊÊÉÇÆÄÁÀ¾»º·´³¶„–ÿ„‹ìŠëçÈ©¡¨ÂÞßͨ¥¦¦¤±Û»£‚¦¤¯ÜÇ¡¤¼åßßÜÛØÖÔÔÓÓÒÑÑÐ ÏÐÎÌËÈÅÿ½º¶¶„–ÿ„Žì…ëíá·£¤¦¤¤ÂßßÃ¥¦¦£¸àĤ‚¦£µÜÕ¬££³ÕæßÞÝÛÚÚØØ×Ö×ÖÖ€Õ ÔÔÒÏÎÌÉÇÄÁ¾º¸„–ÿ„ííŽìƒëÖª¡¦ £¯ÚÝØ°¤¦¤ÃáΧ¥€¦¥£ÈßÙ³£¦£¤ÎçàßÞÝÝÜ€ÛÚ€ÙØ××ÖÖÔÑÐÍËÈÅ¿»„–ÿ„îíìéÓ§£‚¦8¤«ÖÜܸ£¦§ÍßÖ­¤¦¦¤¤»ÛÞ×°¤¦¦¤¤ÄæâááàßßÞÞÜÜÛÛÚÙÙØ×ÖÖÓÒÎÌÉÆÂÀ„–ÿ„„îííîîˆíëÌ¥¡ƒ¦¤«×Üݼ£¤«ÔÝÜ´¤¦£©ÇÜÜÞͧ¥€¦£ ¿€ãâááàßÞÞÝÝÜÛÚÙÙØ×ÖÓÒÏÍÉÆÃ„–ÿ„Šî…íëÒª½¯£¥¦£±ÛÜÞ££³ÙÜÞ½£¤²ÐÞÜÝÛµ¤€¦¤ªÀ¬ÄäããâáààßßÞÝÝÜÛÛÚÚÙØÖÔÒÏÍÊÇ„–ÿ„ŒîƒíÛ¨¢µÖ¼¦¤€¦,£»ÞÛÞÍ¥£¼ÝÛßÇ¡®×ßÛÛÝÀ£¦¦¥¤µÒÀ¤¡ÌçääãââáààßÞÞÝ€ÜÚÚÙ×ÕÒÏÍÊ„–ÿ„ðï€îDꬣ¦¤ÇßÊ®¤¥¦£ÁßÛÜØ¬¡ÆßÛÞϦÉÞÛÛÞȦ¥¦¤©ÃÝЧ¥¤¨ÕäååäããâáààßÞÞÝÜÛÚÚÙ×ÕÒÐ΄–ÿ„ðŒï.𺢦¦¤ªÒàØ¼¤££ÀßÛÛÞ¿¢ÏÞÛÜÕ¸ÙÜÛÜÚ®¤¤£µÒáÛ±£¦¦£­æ€åäãââááàßßÞÝÜÛÛÚÙ×ÕÒЄ–ÿ„ƒð€ïðð…ïÔ¥¥€¦£·ÛÞÜɯ ·ÞÛÛÝÔµÕÝÛÜØÎ€Û Ý̤£©ÂÚÞÞÁ¤¦¢Âè€åäããâááàßÞÞÝÜÜÛÚÙ×ÕÒ„–ÿ„Šð‚ïꬣ¦¥¤ÆÞÜߨ»¬ÕÝÛÛÜÖÚ‚Û ÜÛÛÞº¡´ÓÞÝÞϨ¥¦¥¥áç€åäããâááàßßÞÝÝÜÛÚÙ×Õ„–ÿ„ðïïР¤¦¥£¥¦¤¬ÕÝÛÝÝÉÊÜ€ÛÜ…Û ÜÙµÂÙÞÛÜÛµ£ƒ¦¢½íæååääããâááàßßÞÝÜÜÛÚÚׄ–ÿ„òòŒñ뮲ÅÌɸ§¤¦£¹ÜÜÛÜÞØÚŠÛÙÕÞÜÛÛÞŤ„¦¥¹âççææå€ä ãââáàßßÞÝÝÛÛÚ„–ÿ„‚òˆñðÕ¿ÝáßÞÝÊ©£¥¦ÉÞ€ÛÜŒÛÜ€ÛÞÓ«¢£¤¤¥¦¥¢¯ÏÅèèçææå€ä ãâááààßÞÝÜÜÛ„–ÿ„„òññòò‚ñíÆÉÂÅØÞÛßÒ´£¡«ØÝ’ÛÜÛ³©¶»·­§¥¦³ÒÖ®äèèçææå€ä ãââáààßÞÝÝÜ„–ÿ„Šò€ñ箨¤¤±ÏÞÛÞÙIJ§½“ÛÜÐÄÔÛÜÛÕÎÊÎÙàÈ¥Ö€èçææå€ä ãââááàßßÝÝ„–ÿ„‹ôóóÖ¡¥¦¦£«ÕÝÛÝÞÜÑÈØÜ’ÛØÝÝÜÛÜÜ€ÞàÛ° Âï€êéèèçææåääãâááàßÞ„–ÿ„Œôò¿£¦£»ÜÜÛÛÜÝÝ™Û ÜÝÞÞÝÖ»¤£µæë€êéèèçææåääãâááàß„–ÿ„õõôõˆôò²¤¦¥¥ÄàÜ›ÛÝÞÙÏÈĽ«¤¦¥§àìë€ê éèèçææååäãââáà„–ÿ„ƒõ€ôõ‚ô嬥‚¦¥¨ÊÞÞܘÛÝÖ°¨¥¤¤¥€¦£×ììë€êéèèç€æåäãââá„–ÿ„‰õ€ôÝ©¥ƒ¦¤¤¸ÌØ—ÛÜȨ ¢¤¥ƒ¦¢Ì€ìë€ê éèèçææåääããá„–ÿ„‹õôЧ¥¦¥¥¤£¥¨­²ÀÓ˜Ûξ·¯ª¥€¤¥¦¦£À€ìëëêêééèèçææåääãã„–ÿ„Œö Ó¢£¤§«´¾ÊÓÚÝÞÜ—ÛÜÞßÝÛÔ͸­§¤¤¡ºî€íììëëêêééèççæååã„–ÿ„÷‹öÍ«½ÆÏ×Û€ÝÜžÛÜÝÞÝÛØÑÇ¿°»ïïîííììëëê€éèççæåå„–ÿ„‚÷‡ö̪¼ÆÓÚÝ€ÞÝÜÛÜÝ€ÞÚÕÊÀ¯ºððïîîíììëëê€éèççæå„–ÿ„„÷öö÷÷ö Ñ£¤¥¨¬µ½ÈÐ×ÛÞÞ˜Û€Ü ØÑÉ¿·¯©¥¤¢»€ðïîîíììëëê€éèççæ„–ÿ„Š÷ööÔ§¥¦¥¤££¤¦«³¼ÈÙÜ–ÛÕô¬§€£¤¥¦¦¢Âðï€îììëëê€éèçç„–ÿ„ö‹÷Û¨¥ƒ¦¥£¡§ÁÚÜ–ÛØÏ½¨£„¦¢Ìñðï€îíìëëê€éèç„–ÿ„Œ÷欤¦¦¥££¤¥¬»ÒÞÜ—ÛÜÞàЫ¤ƒ¦£×ññðï€îíìëëê€éè„–ÿ„÷øø‰÷ ô±¤¦¤ª¼ÅÈÍÖÝÝœÛÞϬ¤¦¥§áòññðï€îíììëê€é„–ÿ„öƒø÷÷ø‚÷ ö¿¤¤²ÒßßÞÞÝÛÜ”ÛÝÞÝ€Û߯£¦£µç€òñ€ðïï€îí€ìêéé„–ÿ„öˆø÷Ù ªÔ߀݂ÜÝ×ÚÜ’ÛÌÌØÝÜÛÜÚ´£¥¦¥¢Âóòññððïï€îíììëëê„–ÿ„ö‹ø÷顼áÝÓÎÑÖÜÝÝÙÊÆÛÜ‘ÛÞÆ£«Á×ÞÜÝ×·¤£¤ªÔƒòññððïï€îí€ìë„–ÿ„öŒøöµÉع©§§«³·¶¬°×Ý’ÛÜÛµ¡¤­ÈÞÜÝÚËÄËÅéóƒòñïï€îí€ì„–ÿ„õø×ʸ¢¥££¢£Ê߀ÛÝÜ‹ÛÜ€ÛÞÓ¬¤¤¥ÂÜßßáâÈÅñ€ó‚òñïï€îíìì„–ÿ„ô€ùŠøíÀ¨¥ƒ¦ ¤ºÜÛÛÜÞÕÖ܉ÛÚØÝÜÛÛÞÆ¤¦¥¥µÇÍȹ¨Þòó‚òñðï€îíì„–ÿ„ô‚ù€øùùƒø÷Тƒ¦ ¤­ÕÝÛÝÝ˰ÏÝ…ÛÜÜÛÛÜÏÆÚÞÛÜÛµ£¦¦££¥£Ÿ¹ñ„óòñðð€îí„–ÿ„ó‰ù‚ø流¦ ¥ÈÞÛÞÖº¤±ÙÜÛÛÚ‚ÛÓ€Û ÜÛ³±ÒÞÜÝѪ¥¦¥§åôô…ó€òñððïîî„–ÿ„òŒù€øÖ¤¥€¦"£µÜÞÝÊ®£¢ÂÝÛÛÝÒÔÜÛÜÚ³ÌÞÛÛßá¨ÁÛÞÞÁ¤¦¡Á‚ô…óòòñððïî„–ÿ„ñŽù/øî¼¢¦¦¤«ÒàÖ¼¦¤¤¨ÓÝÛÛÝÂÌÞÛÜÖ§µÝÛÛÞ˦¤¤¶ÑàÚ±¤¦¦£¬ê„ô…óòñððï„–ÿ„ñúù.ì­£¦¤ÇáÉ­£¥¦£¾ÞÛÛÞÓªÄÞÛÞЦ§ÑÝÛÞ˦¥¦£©ÂÝÑ¥¥¤¥âõõ…ô„óòñðð„–ÿ„ð€úù ÷Û¨£¶Ó½§£¦¦£¶ØÜÛÝÛ¶ »ÝÛßǤ£ÁÝÛÞÆ¥€¦¤¤µÒ¿¥¢Íõ…ô…óò€ñð„–ÿ„ïƒúùùúú‡ù÷Ñ©¾¯¢¥¦¦¤­×ÞÛÞ×¹££²ÚÜÞ½£¤µÛÜÞ¼£‚¦¢ªÂ®Àñƒõ…ô„óòòññ„–ÿ„ï‰ú†ù÷Ϩ£¦¤ÃÞÜÝͯ¤¦¤«ÔÝÜ´¤¤°ØÝÝ´¤ƒ¦¤£Äñ†õ…ôƒóòòñ„–ÿ„î‹ú…ù÷Ц£¦¦¥§ÏÞݦ£¦¦¥¦ËßÕ¬¥¤­ÖÝÛ±¤‚¦¤£Áó€ö†õ…ô‚óòò„–ÿ„îú‚ù ÷Ú«£¦¥©ÒàЧ¤¦ ¤Âàͨ¥¥¨Ïßݸ£¦¤§Ïóƒö†õ„ô‚óò„–ÿ„î‘úù øêµ¡£¥Íá¾¢‚¦£¹ßŤ¦¦¤¹ßàͦ£¦¥ ¬à÷†ö…õ…ôó„–ÿ„íû’úùòЭ »á»£‚¦¤±Û¼£¦¦¥¦ÃÚßË®¤©Ãí÷÷ˆö…õ„ô€ó„–ÿ„íû’úùùøìÇ­ÊÄ¢‚¦¥«Ò²¤¦¤°ÅÍžäö‚÷ˆö…õ„ôó„–ÿ„íƒûúúûúùù÷ïÌŨ¢£¤¦¦¥§Æ¬¥¦¦¥£¢¤¯Åéò‡÷†ö†õƒô„–ÿ„í‰ûúùöôÝ͵¨¥¤¤£²¦££¤§¯ÅÖñõø†÷‡ö…õ‚ô„–ÿ„íŒûŽúùøùñòåÛÓÏÎÍÐÙäîïõ÷…ø†÷‡ö…õ€ô„–ÿ„íûŽú‰ù‰ø‡÷‡ö…õó„–ÿ„í’ûŽú‰ùˆøˆ÷…ö„õô„–ÿ„í”ûŽúˆù‰øˆ÷…ö‚õó„–ÿ„íüü”ûŽú‰ùˆø‡÷…öõó„–ÿ„í‚ü”ûú‰ùˆø†÷†öõõò„–ÿ„íˆüûúˆù‰ø†÷†öò„–ÿ„îŠüûú‰ùˆø…÷…öñ„–ÿ„îü‘û‹úˆùˆø‡÷‚öð„–ÿ„Á®Ô¦„–ÿ„Ö¦„–ÿ„Ö¦„–ÿ„Ö¦„–ÿ„‚¦¼€Ó·¦È€ÓÈ‚¦È€ÓȦ±ÓÓ¼±¦„–ÿ„¦Øÿú¬¦¦ï‚ÿï‚ÿ¼ÿÿÓ±¦„–ÿ„¦ úÿô¬Þÿ¼¦·ÿÿã¦ãÿÿ¼¦·ÿÿã¦ãÿÿ¼¦¦¼ÿÿÓ€¦ ¼¼·¬¼±¦¦¬¼±ƒ¦±¼¼±ƒ¦±¼·¦±¼¼±…¦„–ÿ„¦ÿÿô‚¦¼ÿÿÓ¦¼ÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦ÿÿôúÿÿÞÞ€ÿÞ±¦¦·ôÿÞ±¦¦±Þ‚ÿ馦±ÞÿÞ±ƒ¦„–ÿ„¦ïÿÿÞ¦¼ÿÿÓ¦¼ÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦€ÿãã€ÿ"ããÿÿÓ¦¦ãÿéÓãÿÿÓ¦¦ÓÿÿãÓÿÿ馦ÓÿÿããÿÿÓƒ¦„–ÿ„¦Â€ÿÞ€¦¼ÿÿéÓÞÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦*ÿÿô¦¦ôÿú¦¦ÿÿú¦¦ã㬦¦ôÿ馦úÿô¦¦ÿÿ馦úÿô¦¦ÿÿ郦„–ÿ„‚¦Ó€ÿȦ¦¼ÿÿôéïÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦ ÿÿ馦éÿ馦€ÿ¦ÈÓÓôÿ馦ÿÿ馦ÿÿ馦ÿÿôÓÓÿÿ郦„–ÿ„ƒ¦Þÿÿú¦¦¼ÿÿÓ¦¼ÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦ ÿÿ馦éÿ馦€ÿ¦¦·ô‚ÿ 馦ÿÿ馦ÿÿ馦„ÿ郦„–ÿ„„¦éÿÿ¼¦¼ÿÿÓ¦¼ÿÿÓ¦¼ÿÿ¼¦¼ÿÿÓ¦¦¼ÿÿÓ€¦ ÿÿ馦éÿ馦€ÿ¦¦Þÿÿͼïÿ馦ÿÿ馦ÿÿ馦ÿÿï¼·ƒ¦„–ÿ„¦ éͦÓÿÿ¼¦¼ÿÿÓ¦¼ÿÿÓ¦¼ÿÿÓ¦ÓÿÿȦ¦¼ÿÿÓ€¦ ÿÿ馦éÿ馦€ÿ¦¦ôÿÿ¬¬úÿ馦ôÿú¬¬ÿÿ馦ôÿú¬¦·é؃¦„–ÿ„¦ãúéÿÿô¦¦¼ÿÿÓ¦¼ÿÿÓ¦¦ôÿÿéÿÿô€¦¼ÿÿÓ€¦ ÿÿ馦éÿ馦€ÿ¦¦Èÿÿôôúÿ馦Èÿÿôôÿÿ馦ÈÿÿôéúÿÞƒ¦„–ÿ„¦±ØééÞ·¦¦·ééȦ·ééȦ¦·Þ€éÞ·€¦·ééÈ€¦ é騦¦Øéئ¦€é¦¦¬ÈééÈØéØ¦¦¬ÈééÈÿÿ馦¬ÈéÞ¬ƒ¦„–ÿ„æÿÿ馄–ÿ„¾¦ïú·¦·ÿÿ㦄–ÿ„¾¦Óƒÿ¦„–ÿ„¿¦Èӱަ„–ÿ„Ö¦„–ÿ„xE1,,% %4DWgx›¢£¤¥¤£¢Ÿš”ˆ{naP9(’–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä‰ÿŠÿä–ÿä–ÿ„à†ß‚ÞÝ€Ü ÛÚÚÙÙØØ×ÖÖ€ÕÔÓÓÒÑÑÐÎÍÊÈÅÁ¿¾¹¶´ºÌΤ–ÿ„†àáßàà€ßÞ ÜÜÝÜÛÛÚØÙÙ×€ÖÕÕÔ€ÓÒÑÑÏÎÊÇÅÁ¿½¹µ²¯¬´î®¢–ÿ„ˆáààá€à€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÆÃ¿¼¹¶²®©«Æ_¡–ÿ„â…áââá€à€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÐÏÌÈÇ¿¼¸µ°¬§¨À+ –ÿ„€âƒáâáàà€ßÞ€ÝÜÛÛÚÙØØ×ÖÖÕÔÔÓÒÒÑÏÏÊÉÆÂ¾»·²®ª¤©Â0Ÿ–ÿ„„âáá‚âáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÏÍËÈÆÁ½¹´¯ª§¢³Â-ž–ÿ„Œâáàà߀ÞÝÜÜÛ€ÚÙØØ×ÖÖ€ÕÔÓÓÒÎÍÊÈÄÀ»·±¬¦¢¢½Á*–ÿ„âáà‚߀ÞÝÜÜÛ€ÚÙØ××ÖÖ€ÕÔÓÓÒÎÎÊǾ¹²­¦¢¬ÈÀ*œ–ÿ„Žãâáà߀ÞÝÜÜÛÚÙØØ××ÖÕÕÔÓÓÑÏÍÉÅ»¶¯©¡œ™ÃÊ¿'›–ÿ„„ã„y€ãâ€áàà†ÛÚ €HÉ×ÖÕÕÔÓÒÑÎËÇÿ¸°ª£›•ªÓÊ¿'š–ÿ„„ã„yã€âáà†ܾ‚V××ÖÕÕÔÓÒÑÌÊÅÀ»³ª£œ”“ÝÓÊ¿$™–ÿ„„〆ã€ââá€à€ßÞÞÝvIÚÙ+Ø×ÖÖ€ÕÓÒÑÍÉüµ¬£›”×ÝÓʾ!˜–ÿ„„〆 âáàà€&ßßÞÝvfÛÚÙÙØØ×ÖÖÕÕÔÓÒÏËÆ¿·®¥›”‹ÉåÝÓʾ!—–ÿ„„䀆ä€ãâá€àßßÞv€¡Û€ÚÙØØ××ÖÕÔÓÐÍǹ°¦“Œ¾íåÝÓʾ––ÿ„„䀆ä€äãâ€ààßßÀ€¯Û€ÚÙØØ××ÕÔÔÑÏÉü²¨ž”гôíåÝÓʾ•–ÿ„„䃃ä€ääã€áà•€ ÍÜÛÚÚÙØØ×ÖÕÔÒÏÌÆ¿¶ª •ЍúôíåÝÓʾ”–ÿ„„䃃䀀ä€ã€ááàw€ ,ÜÜÛÚÚÙØØ×ÖÔÒÐÍÇÁ·®¡–‹šÿúôíåÝÓʾ“–ÿ„„倆å€åä䀀âá€àY€gÜÜÛ€ÚÙÙ×ÕÔÑÏɺ¯¤—‹–ÿÿúôíåÝÓʾ’–ÿ„„倆倂åä€ã€âá€à-ÝÜÜÛ€Ú ÙØÖÕÓÏÊû±¦™€ÿúôíåÝÓʾ‘–ÿ„„倆倂åä€ãã€âáàà€ÞÝÜÜÛ€Ú ØØÖÓÐÊü³§›ŽŽÿúôíåÝÓʾ–ÿ„„å€†å€ƒå€ äããây´à³ßßÞÝÝÜÛÛÙØ×ÔÐÌż´¨†‚ÿúôíåÝÓʾ!–ÿ„ææ‚å€æ…倃å€ääã㦃w€ßÞÝÝÜÛÚÙØÕÒÌǾµªž‘…ƒÿúôíåÝÓʾ!Ž–ÿ„çç‚æ€†æ€ƒæ€€åääˆxáà€ßÞÝÝÜÚÚÙÕÓÏÈÁ¶«Ÿ“†„ÿúôíåÝÓʾ!–ÿ„ƒç€æ‚çŽæåää€ãâ€áà€ßÞÝÝÛÚÙÖÓÎÉÀ¸¬ ”‰…ÿúôíåÝÓʾ!Œ–ÿ„…çæ…çŒæåää€ãâ€á€àßßÞÝÜÚØÕÐËø®¡•‰†ÿúôíåÝÓʾ'‹–ÿ„•ç†æåää€ãâ€á€à!ßÞÝÝÛÙÖÑÊù®£—‹€vnn‚€€Š¢¯¿ÑãÝÓÊ¿'Š–ÿ„”èˆçæåå€äã€â$áààßÝÝÜÚÖÑÌÄ»±¤™Ž„{slifddegimpt’¬ÉÊ¿'‰–ÿ„—è†çæåå€äã€â$áààÞÝÜÛØÒÎÆ¼³§œ’ˆxsnljjklnqsvzƒŸ¾À-ˆ–ÿ„éèé™è‚çæåå€äã€âáàßßÝÜÙÕÏÉÀ¶¬¡—ކzwt€s ttvy|~„‰¤¾0‡–ÿ„ƒé—èƒç€æ€åääã€âáàßÞÜÚ×ÑÊú°§œ”‡ƒ~|€} €‚„‡‰Œ‘¼]†–ÿ„…éèé“èçèççæå€äããââáßÞÝÛ×ÓÍžµ«¤œ•‘Љ‰ˆ‚‰ ŠŒŽ‘”——¢É†–ÿ„Šê”é€èçæåä€ãáàÞÜØÔÐɺ²ª¥Ÿ›—•€–€• –˜——››­ê…–ÿ„êéê’éèè€ç€æååääãâáßÝÚÖÑÍÆ¿¹³­©¦¢¢¡€¢ ¡¡  ¡  ¡¡¢£Ã „–ÿ„ëêŒé5îëæèèãàÞàâæëäåíääââàÞÝÙÕÐÌÆÁ¼¸³±°­®­®¯®¯¯¬¬«ª¨©§§¨¦¦¹„–ÿ„€ëê‡é#ëðçàÖÏÊÉÉÈ•ÀÊÉËÎÔÞâòèãáàÞÛØÔÐÌÇÄÀ½»º‚¹ºº¹¸¶µ³²°¯®¬¬«®Ø„–ÿ„ƒë€êëë‹ê‚é(íïàØÕÊÇÈÉÊÌÇW°ÏÊÉÉÈÇÉ›½èãáàÞÜØÕÑÎÌÈÆÄÃÂÃÂà ÂÀÀ¾½»¸¶µ²±¯±¾„–ÿ„…ìëììë êìð݆2C€ÁÏ€ÊϹ/›Ò‚ÊÓ|+´ÚåæßÞÜØÖÔÒÏÍÌËËÊËÊÊÉÇÆÄÁÀ¾»º·´³¶„–ÿ„‹ìŠëêÞÌȺc;ÃÏÊÊÒ¢ |Ó‚ÊÒ§LÍÌÖêàßÜÛØ×ÔÔÓÓÒÑуРÎÌËÈÅÿ½º¶¶„–ÿ„ì†ëíêÕÉÉÊÑÓ`_ÍÌÊÔ†ZÒËÊÕ•±ÐÈÒãçßßÝÛÚÚØØ×Ö×ÖÖ€Õ ÔÔÒÏÎÌÉÇÄÁ¾º¸„–ÿ„ííŽì‚ëìäÌÈ€ÊÉÕª¤ÒÊÒa7ÅÍ€ÊÎ×M—ÔÊÈÉáçàßÞÝÝÜ€ÛÚ€ÙØ××ÖÖÔÑÐÍËÈÅ¿»„–ÿ„îíìêçËÈ‚Ê8м†ÔÌÈ;±ÐÊÊÐÒ€¥ÒÊÊÉÉÝêâááàßßÞÞÝÜÛÛÚÙÙØ×ÖÖÓÒÎÌÉÆÂÀ„–ÿ„ƒî€íîîˆíìÕÂуÊиxÕз–ÔÊÕ¾P7Å΀ÊÏÆËçããâááàßÞÞÝÝÜÛÚÙÙØØÖÓÒÏÍÉÆÃ„–ÿ„Šî†íæ½p¦ÔÎÊÓ¡bÕÔš vÕÒž/€$ÒÊÊËÔºh¨âæããâáààßßÞÝÝÜÛÛÚÚÙØÖÔÒÏÍÊÇ„–ÿ„ŒîƒíçËÑ‘zÌÒ€ÊÕ}€8ÎÙz€OÚ¬€%jÓËÊÐÑ•+jÍÉàçääãââáààßÞÞÝÜÜÛÚÚÙ×ÕÒÏÍÊ„–ÿ„ðï€î ñÎÈËÑRC«ÒÍÊÕg€²ÛV€2ÍK%NÉÍËÓ½_0ÇÏÉÌãååääããâáààßÞÞÝÜÛÛÚÙ×ÕÒÐ΄–ÿ„ðŒïòÕÇÊÊÑ»%yÑÓÖimÖ3€‡€ ©ÓÐÔ’(  ÔÊÊÈÏí€åäãââááàßßÞÝÜÛÛÚÙ×ÕÒЄ–ÿ„ƒð€ïðð…ïåÊÉ€ÊÓL©á‹€7€ =ÒÖ½e eÑÌ€ÊÇÛé€åäããâááàßßÞÝÜÜÛÚÙ×ÕÒ„–ÿ„Šð‚ï îÍÉÌÌÊÊÍÒR€´€Þ”%€3ÄÏÊÉÊìç€åäããâááàßßÞÝÝÜÛÚÙ×Õ„–ÿ„ð ïðãÑÐÊÎÔÍÉÒ³€JCŠ ‘c€“ÕƒÊÈØïæååääããâááàßßÞÝÜÜÛÚÚׄ–ÿ„òòñ Ö’Z@L‡ÆÒÊÕŠ ‚VÒË‚ÊËË‹âççææå€ä ãââáàßßÞÝÜÛÛÚ„–ÿ„ò‰ñðåh€GÁÔÍËJ–&¸ÙÓÓÏÌËÍØ©(¾êèçææå€ä ãâááààßÞÝÜÜÛ„–ÿ„„òññòò‚ñó ˜ÕÍËÌÌÙôòññððïï€îí€ìëê„–ÿ„õŒøðÔr"5,EQ’SÓ³h€ÓÖηáƒòññððïï€îí€ìë„–ÿ„öø Ò>…ÁÈÄ¶šŠ´¥”‘ÜѲL€ @ZÈô€ó‚òñðï€îíìì„–ÿ„ôù‰øó•»ÍƒÊÔŠ‚ VÐËÎÍ”S=O}Åîòó‚òñðï€îíì„–ÿ„ô‚ù€øùù„øäɃÊÒ²B¥1‹/W € “ÕÊÌÔÓÎÓÓÙ…óòñðð€îí„–ÿ„ó‰ù‚øöÐÉÊÌÏO€€Ñ¢€€"€šŸ)€-½Ï€ÊËÊËïôô…ó€òñððïîî„–ÿ„òŒù€øçÉÊ Ö‘F®×Ûb*€ ™> ^ÚÁgeÓË€ÊÆÙõô…óòòñððïî„–ÿ„ñŽùøòØÇÊÊѹ+yÉÑÐÁ"d?€Å‘€CÉÒÑ‘, ÓÊÊÈÍò„ô…óòñððï„–ÿ„ñúù òÎÈÌÓOI¯ÕÎËÖp&º[€.ÍÈ)€@ÈÌËÖÁe,ÉÏÈÉìöõ…ô„óòñðð„–ÿ„ð€úù øéÌБ%vÉÓËÊÓ€ àxQÒÓg€ TÎËÊÊÐÑ’,pÌÉáö€õ…ô…óò€ñð„–ÿ„ïƒúùùúú‡ù øå¼jªÖÍÊÊѯ€‚ÕÕ› uÕÓzÔÊË×¼a¢ßóƒõ…ô„óòòññ„–ÿ„ï‰ú‡ùÜÀÏ€ÊËÒa;«ÐËи!˜ÓÒ¤˜ÓƒÊÎÇЇõ„ô„óòòñ„–ÿ„î‹ú…ùøãÉÈÊÊÌÆ0dËÔËÊÌË@³ÐЯ¡Ó‚ÊÉÈÜö†õ…ô‚óòò„–ÿ„îú‚ù øèÎÈÊÍÃ(.ÇÑÊ Òb9ÆÍÎÁ2‡ÖÊÉÊâõƒö†õ„ô‚óò„–ÿ„î‘ú‚ùòÒÇËÌ<oÙ‚ÊÔ…XÑËÊÔ„:ÈÖËÉÇÎìø†ö…õ…ôó„–ÿ„íû’úù÷ãÐÒu|ׂÊÒ  zÓÊÊÍË_ C¨ÅÍÛô÷÷‡ö†õ„ô€ó„–ÿ„íû’ú€ùñáÉ8QÒËÊϹ,œÓ€ÊÍÔ¢N2gÃñö‚÷‡ö†õ„ôó„–ÿ„íƒûúúûúùùø÷Ñ—ÄÉÈÉÊÊÍÇU²ÏÊÊ€ÉÒÕÖòõ‡÷†ö†õƒô„–ÿ„í‰ûúùùúéàÓËÉ —ÀÉÈÉÊÐÝåõöø†÷‡ö…õ‚ô„–ÿ„íŒûŽú€ù õöðêèãÞàåêñôó÷…ø‡÷‡ö…õ€ô„–ÿ„íûŽúŠùˆø‡÷‡ö„õôó„–ÿ„í’ûŽúŠù‡øˆ÷…ö„õô„–ÿ„í”ûŽúˆù‰ø‡÷†ö‚õó„–ÿ„í€ü“ûŽú‰ùˆø‡÷…öõó„–ÿ„í‚ü”ûú‰ùˆø†÷†öõõò„–ÿ„íˆüûúˆù‰ø†÷†öò„–ÿ„îŠüûŽúˆù‡ø‡÷„öñ„–ÿ„îüûúû‹úˆùˆø‡÷‚öð„–ÿ„ØÏÔÊ„–ÿ„ÖÊ„–ÿ„ÖÊ„–ÿ„ÖÊ„–ÿ„‚Ê×€åÔÊÞ€åÞ‚ÊÞ€åÞÊÑååױʄ–ÿ„ÊèÿüÍÊÊõ‚ÿõ€Êõ‚ÿõ€Ê×ÿÿå±Ê„–ÿ„Ê üÿùÍëÿ×ÊÔÿÿïÊïÿÿ×ÊÔÿÿïÊïÿÿ×ÊÊ×ÿÿå€Ê ××ÔÍ×ÑÊÊÍ×уÊÑ××уÊÑ×ÔÊÑ××Ñ…Ê„–ÿ„Êÿÿù‚Ê×ÿÿåÊ×ÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Êÿÿùüÿÿëë€ÿëÑÊÊÔùÿëÑÊÊÑë‚ÿòÊÊÑëÿëуʄ–ÿ„ÊõÿÿëÊ×ÿÿåÊ×ÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Ê€ÿïï€ÿ"ïïÿÿåÊÊïÿòåïÿÿåÊÊåÿÿïåÿÿòÊÊåÿÿïïÿÿåƒÊ„–ÿ„ÊÛ€ÿë€Ê×ÿÿòåëÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Ê*ÿÿùÊÊùÿüÊÊÿÿüÊÊïïÍÊÊùÿòÊÊüÿùÊÊÿÿòÊÊüÿùÊÊÿÿòƒÊ„–ÿ„‚Êå€ÿÞÊÊ×ÿÿùòõÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Ê ÿÿòÊÊòÿòÊÊ€ÿÊÞååùÿòÊÊÿÿòÊÊÿÿòÊÊÿÿùååÿÿòƒÊ„–ÿ„ƒÊëÿÿüÊÊ×ÿÿåÊ×ÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Ê ÿÿòÊÊòÿòÊÊ€ÿÊÊÔù‚ÿ òÊÊÿÿòÊÊÿÿòÊÊ„ÿòƒÊ„–ÿ„„Êòÿÿ×Ê×ÿÿåÊ×ÿÿåÊ×ÿÿ×Ê×ÿÿåÊÊ×ÿÿå€Ê ÿÿòÊÊòÿòÊÊ€ÿÊÊëÿÿá×õÿòÊÊÿÿòÊÊÿÿòÊÊÿÿõ×ԃʄ–ÿ„Ê òáÊåÿÿ×Ê×ÿÿåÊ×ÿÿåÊ×ÿÿåÊåÿÿÞÊÊ×ÿÿå€Ê ÿÿòÊÊòÿòÊÊ€ÿÊÊùÿÿÍÍüÿòÊÊùÿüÍÍÿÿòÊÊùÿüÍÊÔòèƒÊ„–ÿ„ÊïüòÿÿùÊÊ×ÿÿåÊ×ÿÿåÊÊùÿÿòÿÿù€Ê×ÿÿå€Ê ÿÿòÊÊòÿòÊÊ€ÿÊÊÞÿÿùùüÿòÊÊÞÿÿùùÿÿòÊÊÞÿÿùòüÿëƒÊ„–ÿ„ÊÑèòòëÔÊÊÔòòÞÊÔòòÞÊÊÔë€òëÔ€ÊÔòòÞ€Ê òòèÊÊèòèÊÊ€òÊÊÍÞòòÞèòèÊÊÍÞòòÞÿÿòÊÊÍÞòë̓ʄ–ÿ„ÃÊÿÿòÊ„–ÿ„¾ÊõüÔÊÔÿÿïÊ„–ÿ„¾ÊåƒÿÛÊ„–ÿ„¿ÊÞåÑŽÊ„–ÿ„ÖÊ„–ÿ„’V>86-  -?Ti’¬¾ÆÇÈÉÇÆÅÂÀ»µ§–…vcF2’–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä–ÿä‰ÿt8mk@    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûì´E   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÇ9  ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿún  %6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû|  *>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùY .EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùZ 1Iÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü[ 3KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý\ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý[ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýZ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûZ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùY 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùG 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ'3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅ$ 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùD 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ' 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ03Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿù7# 3Mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ>( 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC, 3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿG/3MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿI13MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJ23MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿM33LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿL33KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK31IÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿI1.EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE. *>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>*  %6Ygr~„‡„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ƒ†ˆŒ‘˜ ©¹Ðåò÷÷ôìãÛÔ͵ª¢•މ…ƒ€€€€€€€~zti[I6%  ,;IU]befffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeb]UI;,   ,6>EIKLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLKIE>6,  %*.133333333333333333333333333333333333333333333333333333333333333333333333333333331.*%    ./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/0000755000175000017500000000000012133201304024072 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/InfoPlist.strings0000644000175000017500000000123412040054224027420 0ustar olesolesÿþ/* Localized versions of Info.plist keys */ NSHumanReadableCopyright = "© Smithsonian Astrophysical Observatory, 1999-2012"; CFBundleDisplayName = "SAOImage DS9"; CFBundleName = "SAOImage DS9"; CFBundleShortVersionString = "7.2"; CFBundleGetInfoString = "SAOImage DS9 7.2 Copyright 1999-2012 Smithsonian Astrophysical Observatory"; ./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/0000755000175000017500000000000012132057632025601 5ustar olesoles./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/classes.nib0000644000175000017500000000004310662656612027736 0ustar olesoles{ IBClasses = (); IBVersion = 1; } ./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/objects.xib0000644000175000017500000002545310662656612027760 0ustar olesoles IBCarbonFramework NSApplication main Foo Foo About Foo 0 abou _NSAppleMenu File File New n new Open… o open TRUE Close w clos Save s save Save As… S svas Revert r rvrt TRUE Page Setup… P page Print… p prnt Edit Edit Undo z undo Redo Z redo TRUE Cut x cut Copy c copy Paste v past Delete clea Select All a sall TRUE Special Characters… chrp Window Window TRUE Minimize m mini TRUE Minimize All m 1572864 mina Zoom zoom TRUE TRUE Bring All to Front bfrt TRUE Arrange in Front 1572864 frnt _NSWindowsMenu _NSMainMenu 204 300 564 780 Window 0 0 360 480 0 0 480 360 FALSE TRUE TRUE FALSE Files Owner MainWindow MenuBar 200 ./saods9/ds9/macosx/SAOImage DS9.app/Contents/Resources/English.lproj/main.nib/info.nib0000644000175000017500000000127410662656612027243 0ustar olesoles IBDocumentLocation 117 12 356 240 0 0 1920 1178 IBEditorPositions 29 110 302 204 44 0 0 1920 1178 IBFramework Version 431.0 IBOldestOS 3 IBOpenObjects 29 166 IBSystem Version 8A383 targetFramework IBCarbonFramework ./saods9/ds9/macosx/SAOImage DS9.app/Contents/Info.plist0000644000175000017500000000341112040054224021355 0ustar olesoles CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeExtensions fits fit fts fitz ftz fz CFBundleTypeIconFile fits.icns CFBundleTypeMIMETypes image/fits CFBundleTypeName Flexible Image Transport System CFBundleTypeOSTypes FITS CFBundleTypeRole Viewer LSTypeIsPackage NSDocumentClass FITSData NSPersistentStoreTypeKey Binary CFBundleExecutable ds9 CFBundleIconFile App CFBundleIdentifier com.sao.SAOImageDS9 CFBundleInfoDictionaryVersion 7.1 CFBundleName SAOImage DS9 CFBundlePackageType APPL CFBundleSignature DS9 CFBundleVersion 7.2 CSResourcesFileMapped LSMinimumSystemVersion 10.4.0 LSEnvironment PATH /sw/bin:/usr/local/bin:/opt/local/bin:/usr/bin:/bin/:/usr/sbin:/sbin ./saods9/ds9/macosx/SAOImage DS9.app/Contents/PkgInfo0000644000175000017500000000001010662656612020676 0ustar olesolesAPPLDS9 ./saods9/ds9/ds9.C0000644000175000017500000002101611700667500012407 0ustar olesoles// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include #include #include using namespace std; #include #include extern "C" { int SAOAppInit(Tcl_Interp *interp); int SAOLocalMainHook(int* argc, char*** argv); void TclSetStartupScriptFileName(const char*); int Zvfs_Init(Tcl_Interp*); int Zvfs_Mount(Tcl_Interp*, char*, char *); int Blt_core_Init(Tcl_Interp*); int Blt_x_Init(Tcl_Interp*); int Tktable_Init(Tcl_Interp*); int Checkdns_Init(Tcl_Interp*); int Saotk_Init(Tcl_Interp*); int Tkhtml_Init(Tcl_Interp*); int Tkmpeg_Init(Tcl_Interp*); int Tkimg_Init(Tcl_Interp*); int Zlibtcl_Init(Tcl_Interp*); int Jpegtcl_Init(Tcl_Interp*); int Tkimgjpeg_Init(Tcl_Interp*); int Tifftcl_Init(Tcl_Interp*); int Tkimgtiff_Init(Tcl_Interp*); int Pngtcl_Init(Tcl_Interp*); int Tkimgpng_Init(Tcl_Interp*); int Tkimggif_Init(Tcl_Interp*); int Tkimgppm_Init(Tcl_Interp*); int Tkimgwindow_Init(Tcl_Interp*); int Tclxpa_Init(Tcl_Interp*); int Iis_Init(Tcl_Interp*); int Tclxml_Init(Tcl_Interp*); int Tclxml_libxml2_Init(Tcl_Interp*); #ifndef _WIN32 int Signal_ext_Init(Tcl_Interp*); #endif #ifdef _MACOSX int Tkmacosx_Init(Tcl_Interp*); #endif #ifdef _WIN32 int Tkwin32_Init(Tcl_Interp*); #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN #endif } static char* appname = NULL; char* dupstr(const char* str); Tcl_Interp *global_interp; void internalError(const char* msg) { Tcl_SetVar2(global_interp, "ds9", "msg", msg, TCL_GLOBAL_ONLY); Tcl_SetVar2(global_interp, "ds9", "msg,level", "error", TCL_GLOBAL_ONLY); } // currently use relative path // using full path with spaces causes problems // with htmwidget and tcl/tk int SAOLocalMainHook(int* argcPtr, char*** argvPtr) { // sync C++ io calls with C io calls ios::sync_with_stdio(); // save real application name int argc = *argcPtr; char** argv = *argvPtr; appname = dupstr(argv[0]); // so that tcl and tk know where to find their libs // we do it here before InitLibraryPath is called putenv((char*)"TCL_LIBRARY=./zvfsmntpt/tcl8.5"); putenv((char*)"TK_LIBRARY=./zvfsmntpt/tk8.5"); // invoke startup script TclSetStartupScriptFileName("./zvfsmntpt/src/ds9.tcl"); } int SAOAppInit(Tcl_Interp *interp) { // reset argv0 if (appname) { Tcl_SetVar(interp, "argv0", appname, TCL_GLOBAL_ONLY); delete [] appname; } // save interp for cputs function global_interp = interp; // We have to initialize the virtual filesystem before calling // Tcl_Init(). Otherwise, Tcl_Init() will not be able to find // its startup script files. if (Zvfs_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "zvfs", Zvfs_Init, (Tcl_PackageInitProc*)NULL); // find current working directory, and set as mount point { Tcl_DString pwd; Tcl_DStringInit(&pwd); Tcl_GetCwd(interp, &pwd); #ifdef ZIPFILE ostringstream str; #ifndef _WIN32 str << (char *)Tcl_GetNameOfExecutable() << ".zip" << ends; #else str << (char *)Tcl_GetNameOfExecutable() << "/../ds9.zip" << ends; #endif if( Zvfs_Mount(interp, (char*)str.str().c_str(), Tcl_DStringValue(&pwd)) != TCL_OK ){ char str[] = "ERROR: Unable to open the auxiliary ds9 file 'ds9.zip'. If you moved the ds9 program from its original location, please also move the zip file to the same place."; #ifndef _WIN32 cerr << str << endl; #else MessageBox(NULL, str, "SAOImage DS9", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND); #endif exit(1); } #else Zvfs_Mount(interp, (char *)Tcl_GetNameOfExecutable(), Tcl_DStringValue(&pwd)); #endif Tcl_DStringFree(&pwd); } // Initialize Tcl and Tk if (Tcl_Init(interp)) return TCL_ERROR; // Tk if (Tk_Init(interp)) return TCL_ERROR; Tcl_StaticPackage(interp,"Tk", Tk_Init, Tk_SafeInit); { Tcl_DString pwd; Tcl_DStringInit(&pwd); Tcl_GetCwd(interp, &pwd); Tcl_DStringFree(&pwd); } // Blt if (Blt_core_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, (Tcl_PackageInitProc*)NULL); if (Blt_x_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init, (Tcl_PackageInitProc*)NULL); // Tktable if (Tktable_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "Tktable", Tktable_Init, (Tcl_PackageInitProc*)NULL); // Checkdns if (Checkdns_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "checkdns", Checkdns_Init, (Tcl_PackageInitProc*)NULL); // Saotk if (Saotk_Init(interp) == TCL_ERROR) return TCL_ERROR; //Tcl_StaticPackage (interp, "saotk", Saotk_Init, // (Tcl_PackageInitProc*)NULL); // Tkhtml if (Tkhtml_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "tkhtml", Tkhtml_Init, (Tcl_PackageInitProc*)NULL); // Tclxpa if (Tclxpa_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "Tclxpa", Tclxpa_Init, (Tcl_PackageInitProc*)NULL); // IIS if (Iis_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "iis", Iis_Init, (Tcl_PackageInitProc*)NULL); // Tkmpeg if (Tkmpeg_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "tkmpeg", Tkmpeg_Init, (Tcl_PackageInitProc*)NULL); // Tclxml if (Tclxml_Init(interp) == TCL_ERROR) return TCL_ERROR; // Tkimg if (Tkimg_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "img", Tkimg_Init, (Tcl_PackageInitProc*)NULL); // zlibtcl if (Zlibtcl_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "zlibtcl", Zlibtcl_Init, (Tcl_PackageInitProc*)NULL); // jpegtcl if (Jpegtcl_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "jpegtcl", Jpegtcl_Init, (Tcl_PackageInitProc*)NULL); // Tkimgjpeg if (Tkimgjpeg_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "jpeg", Tkimgjpeg_Init, (Tcl_PackageInitProc*)NULL); // Tifftcl if (Tifftcl_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "tifftcl", Tifftcl_Init, (Tcl_PackageInitProc*)NULL); // Tkimgtiff if (Tkimgtiff_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "tiff", Tkimgtiff_Init, (Tcl_PackageInitProc*)NULL); // Pngtcl if (Pngtcl_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "pngtcl", Pngtcl_Init, (Tcl_PackageInitProc*)NULL); // Tkimgpng if (Tkimgpng_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "png", Tkimgpng_Init, (Tcl_PackageInitProc*)NULL); // Tkimggif if (Tkimggif_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "gif", Tkimggif_Init, (Tcl_PackageInitProc*)NULL); // Tkimgppm if (Tkimgppm_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "ppm", Tkimgppm_Init, (Tcl_PackageInitProc*)NULL); // Tkimgwindow if (Tkimgwindow_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "window", Tkimgwindow_Init, (Tcl_PackageInitProc*)NULL); // Signal_Ext #ifndef _WIN32 if (Signal_ext_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "signal", Signal_ext_Init, (Tcl_PackageInitProc*)NULL); #endif #ifdef _MACOSX if (Tkmacosx_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "macosx", Tkmacosx_Init, (Tcl_PackageInitProc*)NULL); #endif #ifdef _WIN32 if (Tkwin32_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage (interp, "win32", Tkwin32_Init, (Tcl_PackageInitProc*)NULL); #endif // Variables Tcl_SetVar(interp, "auto_path", "./zvfsmntpt/tcl8.5 ./zvfsmntpt/tcl8/8.3 ./zvfsmntpt/tcl8/8.4 ./zvfsmntpt/tcl8/8.5 ./zvfsmntpt/tk8.5 ./zvfsmntpt/blt3.0 ./zvfsmntpt/tcllib1.10 ./zvfsmntpt/src", TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tcl_libPath", "./zvfsmntpt/tcl8.5", TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "blt_library", "./zvfsmntpt/blt3.0", TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "blt_libPath", "./zvfsmntpt/blt3.0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "env", "TK_TABLE_LIBRARY", "", TCL_GLOBAL_ONLY); //Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); return TCL_OK; } ./saods9/make.darwintiger0000644000175000017500000000016411614303700014255 0ustar olesolesOS = unix ARCH = darwintiger ZCAT = gzcat CODESIGN = echo ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-tiger.tar.gz./saods9/htmlwidget/0000755000175000017500000000000012133201304013240 5ustar olesoles./saods9/htmlwidget/listvers.sh0000755000175000017500000000043307504443344015474 0ustar olesoles#! /bin/sh # # This script extracts version information from all the source files. # Run this script in the top-level directory of the source tree. # grep Revision: `find . -type f -print` | sed -e 's,^./,,' -e 's,:[^ ]*, ,' | awk '/[1-9]\.[1-9]/ { printf "%-20s %s\n",$1,$3 }' ./saods9/htmlwidget/README0000644000175000017500000000101507504443343014136 0ustar olesolesThis directory contains all source code files for the TkHtml widget. TkHtml renders HTML for Tcl/Tk 8.0 and later. COPYRIGHT Text of the GNU Public License, under which this software is distributed. COMPILE.txt Instructions on how to compile TkHtml. doc Other documentation about TkHtml. src All of the source code. tools Source code to tools that are used to build the widget but which do not become part of the widget. ./saods9/htmlwidget/COPYING0000644000175000017500000004307007504443343014320 0ustar olesoles GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ./saods9/htmlwidget/tests/0000755000175000017500000000000012133201304014402 5ustar olesoles./saods9/htmlwidget/tests/html3.test0000644000175000017500000001606707504443346016370 0ustar olesoles# # Test script for the Tk HTML widget # wm withdraw . if {[lsearch [namespace children] ::tcltest] == -1} { source [file dirname $argv0]/engine.tcl namespace import ::tcltest::* } ::tcltest::test html-3.1 {Check the HTML parser for sanity} { set h [tkhtml_test_widget] $h clear $h parse "

Test1 \nEnd\n" $h token list 1.0 end } {0 {{Markup p align center} {Text Test1} {Space 1 1} {Text End} {Space 1 1}}} ::tcltest::test html-3.2 {Check that markup arguments are parsed correctly} { set h [tkhtml_test_widget] $h clear $h parse {

} $h token list 1.0 end } {0 {{Markup p align center id {"5"} id2 '4'}}} ::tcltest::test html-3.3 {Check that comments are ignored} { set h [tkhtml_test_widget] $h clear $h parse {

} $h token list 1.0 end } {0 {{Markup p} {Markup /p}}} ::tcltest::test html-3.4 {Check that entities are resolved} { set h [tkhtml_test_widget] $h clear $h parse {& <>H

} $h token list 1.0 end } {0 {{Text {& <>H}} {Markup p}}} ::tcltest::test html-3.5 {Check that spacing is recorded properly} { set h [tkhtml_test_widget] $h clear $h parse "

\n\tHi\tThere\n
" $h token list 1.0 end } {0 {{Markup pre} {Space 1 1} {Space 8 0} {Text Hi} {Space 6 0} {Text There} {Space 1 1} {Markup /pre}}} ::tcltest::test html-3.6 {Script markup should become a single token} { set h [tkhtml_test_widget] $h clear $h parse "\n" $h token list 1.0 end } {0 {{Markup script} {Space 1 1}}} ::tcltest::test html-3.6b {Style markup should become a single token} { set h [tkhtml_test_widget] $h clear $h parse "\n" $h token list 1.0 end } {0 {{Markup style} {Space 1 1}}} ::tcltest::test html-3.7 {All markup within listing is normal text} { set h [tkhtml_test_widget] $h clear $h parse "

Hello

\n" $h token list 1.0 end } {0 {{Markup listing} {Text

Hello} {Text

} {Markup /listing} {Space 1 1}}} ::tcltest::test html-3.8 {All markup within xmp is normal text} { set h [tkhtml_test_widget] $h clear $h parse "<p>Hello</p>\n" $h token list 1.0 end } {0 {{Markup xmp} {Text

Hello} {Text

} {Markup /xmp} {Space 1 1}}} ::tcltest::test html-3.9 {All markup within textarea is treated as normal text. This is not valid HTML, but it is what Netscape does.} { set h [tkhtml_test_widget] $h clear $h parse "\n" $h token list 1.0 end } {0 {{Markup textarea} {Text

Hello} {Text

} {Markup /textarea} {Space 1 1}}} ::tcltest::test html-3.10 {All markup after plaintext become normal text} { set h [tkhtml_test_widget] $h clear $h parse "<p>Hello</p></plaintext>\n" $h token list 1.0 end } {0 {{Markup plaintext} {Text <p>Hello} {Text </p>} {Text </plaintext>} {Space 1 1}}} ::tcltest::test html-3.11 {Unrecognized markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse "<unknown>Text\n" $h token list 1.0 end } {0 {{Text Text} {Space 1 1}}} ::tcltest::test html-3.12 {Entities are resolved within markup arguments} { set h [tkhtml_test_widget] $h clear $h parse {<p id="&lt;hi&gt;">} $h token list 1.0 end } {0 {{Markup p id <hi>}}} ::tcltest::test html-3.13 {Entites are resolved within markup arguments} { set h [tkhtml_test_widget] $h clear $h parse {<p id=&lt;hi&gt;>} $h token list 1.0 end } {0 {{Markup p id <hi>}}} ::tcltest::test html-3.14 {White space within markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse {<br >} $h token list 1.0 end } {0 {{Markup br}}} ::tcltest::test html-3.15 {Whitespace within markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse {<br id = 5>} $h token list 1.0 end } {0 {{Markup br id 5}}} ::tcltest::test html-3.16 {Whitespace in markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse {<br id = 5 >} $h token list 1.0 end } {0 {{Markup br id 5}}} ::tcltest::test html-3.17 {Whitespace in markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse {<br id =5>} $h token list 1.0 end } {0 {{Markup br id 5}}} ::tcltest::test html-3.18 {Whitespace in markup is ignored} { set h [tkhtml_test_widget] $h clear $h parse {<br id= 5 >} $h token list 1.0 end } {0 {{Markup br id 5}}} ::tcltest::test html-3.19 {Whitespace in markup is ignored, except when quoted} { set h [tkhtml_test_widget] $h clear $h parse {<br id= " 5 " >} $h token list 1.0 end } {0 {{Markup br id { 5 }}}} ::tcltest::test html-3.20 {Tabs in markup are treated like whitespace} { set h [tkhtml_test_widget] $h clear $h parse "<br id\t=\t' 5 '\t>" $h token list 1.0 end } {0 {{Markup br id { 5 }}}} ::tcltest::test html-3.21 {Newlines in markup are treated like whitespace} { set h [tkhtml_test_widget] $h clear $h parse "<br id\n=\n\" 5 \"\n>" $h token list 1.0 end } {0 {{Markup br id { 5 }}}} ::tcltest::test html-3.22 {Markup arguments without values} { set h [tkhtml_test_widget] $h clear $h parse "<br clear >" $h token list 1.0 end } {0 {{Markup br clear {}}}} ::tcltest::test html-3.23 {Markup arguments without values} { set h [tkhtml_test_widget] $h clear $h parse "<br clear id=9>" $h token list 1.0 end } {0 {{Markup br clear {} id 9}}} ::tcltest::test html-3.24 {XHTML style / at the end of markup} { set h [tkhtml_test_widget] $h clear $h parse {<br clear="both"/>} $h token list 1.0 end } {0 {{Markup br clear both}}} ::tcltest::test html-3.25 {XHTML style / at the end of markup} { set h [tkhtml_test_widget] $h clear $h parse {<br />} $h token list 1.0 end } {0 {{Markup br}}} ::tcltest::test html-3.26 {XHTML style / at the end of markup} { set h [tkhtml_test_widget] $h clear $h parse {<br/>} $h token list 1.0 end } {0 {{Markup br}}} ::tcltest::test html-3.27 {/ At the end of markup adds a second token} { set h [tkhtml_test_widget] $h clear $h parse {<p />} $h token list 1.0 end } {0 {{Markup p} {Markup /p}}} ::tcltest::test html-3.28 {/ at the end of markup adds a second token} { set h [tkhtml_test_widget] $h clear $h parse {<p/>} $h token list 1.0 end } {0 {{Markup p} {Markup /p}}} ::tcltest::test html-3.29 {/ not at the end of markup still work} { set h [tkhtml_test_widget] $h clear $h parse "<A href=\"\" /privacy.html=\"/privacy.html\">\n" $h token list 1.0 end } {0 {{Markup a href {} /privacy.html /privacy.html} {Space 1 1}}} ::tcltest::test html-3.30 {Incremental parsing} { set h [tkhtml_test_widget] $h clear set txt {<a href="" /privacy.html="none"/>Hello&amp;<p>} set len [string length $txt] for {set i 0} {$i<$len} {incr i} { $h parse [string index $txt $i] } $h token list 1.0 end } {0 {{Markup a href {} /privacy.html none} {Markup /a} {Text Hello&} {Markup p}}} ::tcltest::test html-3.31 {Searching for anchors} { set h [tkhtml_test_widget] $h clear $h parse { <a name="one">One</a> <a id="two">Two</a> <a href="three">Three</a> <a name="four" id="vier">Four</a> } update $h names } {0 {one two four}} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�015377� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image13�������������������������������������������������������������0000644�0001750�0001750�00000007751�07504443347�016607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aP�8�÷��t†„¼Â„´‚ŒÜåá,BDŒ¦|ÜÒŒ„JT”Žl´¬¬Æ´Ü°¸Pbd´©±üóÙÄÔÍœ¢œ´³´”‘œ|šl<2TLEOÄÃÄÜÆÌ$$'œ´œ„‚zľ°tmtLRTôæÌTrDœnt÷òç´´ÄÄËÎÜÖÌ„…Œ”ž¤äå씞\”jt¤®´tvyÌÆ„\Y^447ôÒÜœ´xddhÄ¢´üþë|v”ÜÛܸ¶t¬¤ ¼º°„З𖀄~„¼Ê¼´¦Ì¤ž£ÌÞÜÔÃÌÔÍÔäîìt~|ÔÒÄ„’„LKP4&L¤´¸ÐÒdX„lko¬¦d¼Ã¹¼µºÄÂÜ,+/lup¼½ÄìíÜ4T4ÜÒ¬´®¶œ¢¬¤’œ„‹ôôõìÞ䤒¤¤Œ¼Î¬Ü¾ÄüýÂl:DÌÅÌÌÌÐ|y}^^bÜÜä´¶˜¤šÌ„œ‘|ƒ—”ˆ<<AøÂÔT\\üâ켵̌†‘ÌÆœlb„üþüŒŒ˜ž„TNl¼ÄÇäää¼²Œ––¬³¤ÄºÜ¬~Œ¹–Ÿlvd¤–l„X`´Æ¬¬º| <Z<DDGľŒÜÞ¤l~|ä¶Ä\ddŒ’|ìÌØ¬v„|Œ|¤º¼ÜÚ¼ôìôìÕÜÌ®´”‘“\vd¤´ÔΔ¬ªtì¾ÌÄÆ¬¬¦µÔÕÜüþÜTjT¬ª”ÄÖ¬¼¾œÔΤľÄÜÖÜœšt”–”ÌÖ¤¤¢|<>TÔ¶¼ÜÎÔ0:<üÚä¼¾|¶®É\^|¤žt´²¤´®¡¼ÎФœ®lv€¼¨´ÌÖØ¤¶¬ìæð¬¬°ÔÊŒlfmäÞÌììŒŒŒx¬£ÄÒœ¼º¤äÜœäܰtrv´Æ¿„š|„v¤|~ƒ¼®´|‚|¤£¤TFTäÊÔ,&,TTYüêÔœœ dV\TMT¬²´ÌÆÔ4.4¤¤­¬” üöû$$äºÈäÜ䬞ÄD>D´z„¬štŒZd¼Ä¤D^D¬¾Ä̽ÁäÒÜÔÒœÜÖœ´ª¼´µ¼ÄÅÌ„„„TvTty„œ²„̦´¬¦¬¼»¼ÔÎÜÔÓÔ„–”,����P�8��þ�ïH° Áâîˆ#–fˆ3ï¼õKc)áKwhˆÃqŒ¨ØÐI²$ƒ(S*gÑ båÒ„2ã/Ôzr^@5g•(¡ÒTºl™2e¥ëså6Q$žTIõ`Ë\~¥ñç-'?*öä¬g&¬2üFŒ ²‡Ê“uëX1Z‚à Ž`òNq:5LDË«U¡Õ¦™2dÍxóV±™!ý†@îçme> …)…ìP -8µè¤ê‡å*®,Ø*Kb| ›I\ó¡í‡C^½R1‰\$|±¡` †ñEœâ-²•€Ç±h¨úu©È²uJ.-aÛ°ÊŸCÛþþöóGÞÌ¥jxWÞÓŒÍ(+V@PÈ×ꘂc<x|ù’Øo©£šuTÁ†CipžxäÕÄ*b0€É+B8Dí ’H"šL‚5Pc‡X@‘Ã4_LÅ|ˆ@ J¿„WS ¡¤Jw2Š7=¸¢N‚ˆQ ,@, †ÔÀDIè‡%æ�‰1y˜RIÖqA8¿ 0Ç6–wAmT˜B¨ÐôPxX¸¡d"H$—Àò DA�Oì1ÇNÚA‡.ó�ÃÃƨҊŸT]k ¥â üÌT?¨„²æAÙ™?iÐ^õð‚:’ £ þrtQN ß=ñU=ÑBË LàFd’ ¤àâO9^ öK?õìÊfPŽà¤Ù¨øó õÔ“ÆxoÞ89pÀá9²°$Ž%å P ÕM6ÅL‰ M0Ã@8�Š.~HPرV%¥šÑOÀd1 xLà‡x°€G=¿„RÆCÝ݆A$ž00ƒ áð‹¬îîó…e\ð$ƒL4g0Óƒ.´�29�cÁT‰ƒÂLŠEA…Ð1xôPŠÈ� åÔ6^?‡‘uÉ ZhA‡ Üt€G&I7F@ü± Æl±…4̘àÇ<sèúC¯~øÌ‡þÁ Mc�L‡ ‡.mM€3„LA½iã›ð€’·.ÄË»° ƒoX ÃÅ@R ,L!º`1G4ó´þ…yøL ßw¤Ò {Ì;£G;LPƒÙàØ]w©pœüx¹¬p‚JüÓ@ÿ0Å#(r»´±C°pÆÌÙè Á-èã ™¬¢w² ­p(GŸ!ƒ+RXÀ >.t> ɳA©¶‚3À ½È…;Ü P"�lhDâx@®¨…÷L� |è«|H†I¡ƒ¬blÝðFb#*È$ ý�ÇäŽ 4¡ gàØvº3„™\ þ$ KMH@…z€þè† Î°‹îB.Pð&0làÐÀCn¡(œ9ÈÁ*ì±`Ø€.ˆ8¼ŠrÔU©HM¶Ò&Ð$(áᇦñ°ˆMc ›Mf³;Š1£ 2\Ðd#ºÈ: :P ô €ŒLö(ßcbTÝaLxÈ2´<JŽƒÌ€¢ :`‚iðà i(‡Æø1­3 ò×@à ³ ,p~8Ãì‡U€ ôàÇ1§aEf’àŒð»ÃˆpÇ1éNJµ ìÎÌF")̳ ¡àCl¢%¤1MXÀþà¨0~Ðã“Êì²1 hš¤˜Æ*à62avá=BÁTÈ„;fÈ *v×DB ‰l‚:…ÁŒæõ¨‰ Ráh)æœ" Nøñ•fÐèÁü0žÒãÓX0¾pÅ3‚¢ðÛ º9Ï `x€F\@UÊ@¤W•Á#®z† � . JÂp²Ošú„Pø æ�Œ{ÙÃÂzä1¿àÉ1ÊÀü°&ŇiP—©¨‡./@sNÃÆ!×Ù‘Þx°%´¼a†Pf,³!,=æ@ÓLJ †&°š¹ ‚£§=ÍÄ#šPŒzƒÉšþ€?¸P†qþ°˜â¬1÷xE£ø488¾ H�,û,©ü[~èD“þôçn% :,3b«XÅ4NÛÓläaªÌ `{@\@ÁƒLe’“P�ÐpEô @‚Øqƒ ?„¸…™Ìa³4M°? +Ï^�”µh3Á°Ýîf . ÅÀBŒœÈ¶©*4Ùàcbb2¸Æ¼pƒ#8 ü€  Â¹› ¦úÉOÏ6ØœXȾq:a­"Åh_v3!X !ô°Á°GÚÑ!pïA³ŽL á7ð�á)¸ H¸†þ ÐÀp4&“%K¨PX(0ؘÇ8 q)|£ ö8ri™ < aŠ00ŒÀ/uø\°D/“eœÄà ��€ XCЏI‡;ÚN£ˆdÍ1L%Ð ,ô˜û�?öñD�à×(éƆ‡AÈ ^P„=|?oð\`)cÐJc‚c 2"nà ¬ö Å‚s/� <8²M`ÁìFgN‚ãÜÏôï¥ð‚7 YÍ.@ Æá…q a XèÅ ïPqó!¸-¬¹ý ?0#ÌHÁdí ðáDˆ ?2уl€5Ë`A ?ð|i=Çš˜Ù˜@»þŽ4\Co°¥ ÅLd*wøEFËA €£Õœû˜Æ?­8Ž£XPÓR_‹Kp~pdMÃñbš;çà (=Àa)¸€´x×üˆ3@bÑäh(F .�œŸæ<7©%…7(Ü…ØÉæK:Ì´|"—¦ÐÊsVk ÔÒàŠ`Á€a>Emaö0Æ445Þ:Ø Êq4 ìÕ5¾ñ?”itzÍ0 —°üÀ 0FëgSs@˜V&Þà:tà ÛÉèž�-Œw}|–ÇÉ\Ò àÐÀ¦u «ûA°Žw‰ ¨0L�#MTÀ-©þ°ÉgÇž ~ØÇÄÒ,[˜¡ | Àv¶3Þl*D þ¸eyPAîKŸ»Š~°Ã 0*ØÀýÁ6`t ª§ô£GzöH±‡meCÀ²Ã{ÕhÀgÁ4µ05Ý gàÐ+UÄm‡ ^Â7 Áõ@MÀÀ{ÑESOõH\6lÍ´n— C \PpXÍ‚ç†4~Ð/ðg ;ï‡sg``}ª—`ŸEƒ¥×esq ô0 �HF�MÝr çITdøÓÙp•kfðH?È}k‘vä™01¢H°Ý_ˆ æÄ)þ{ MfXC5´x` ~@{S{Å‚ u O I mzhEÙ ^xÓ 0‡á"İGý„ ü”|5$9t@` ×° ”˜‚Tñ,è‚–'ôpZ =�UýÓ«PJ´€Ñ##ÀVçI´&p à=`FƒèrøIüp`¥ — ލ‡2ðWwã%øY?Hnfx�cEtP À KhŠîø%@}ÓÐ k µ¼†ókq`:@�û4•“}À@ 5DEZ<2ði, þð†ùx¡p«�˜dNyhEæ^€=e )þ«ˆi äHEI32à®À†ç·ŒM8U`),_a#Up×Ð’,p ’Ái°;þuºpTäˆ,ùMàf@Ý脦„L“ Uˆt 97thŠpPYË,ÁTÀe#0-Y  TÔ=p ý% Éø @é UŽd'¤X×ð-) 0ù" ‘spnfhO;0<Špoð•ç7–×a ˆéÃE6=pH.�™tÀíø"° |„in°=`?µðˆð™`I…zY ü° S¥bR ra¦ëØx/"D`àpB~ÀM`Šà^Úðg0 %v/ÒhDe°™ÀQô±ðQƒ¤–~A™S6}Õ¤9Àô}v öÐ ÿ'Ÿµnt Ù°7”HÌ xþ×hAɃ6 Ù`gÐ?/ð™mH0Á4D�bÿ4 `@P:€{1i-ÁÄ9 [ Š„n‡·Ð §èŸj$êF`6ðP2zw ¡PÀ`ìÔŠ÷3J)¯õZã…F2ŠÄ�bj «[dDÙ¤Vñ~GÚD<UY퇥bêŸ(OT[W:¦X�;�����������������������./saods9/htmlwidget/tests/page1/image9��������������������������������������������������������������0000644�0001750�0001750�00000000213�07504443347�016516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a ��ã��FRTªª¼z†„2fdþþüÎÎÌŠ¦¤Zroÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þMade with GIMP�!ù ��,���� � �@&È)‹9`”Á»çÓñ¤GIl%'¶àY¼ERÚ7Àœ 0�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image6��������������������������������������������������������������0000644�0001750�0001750�00000004210�07504443347�016514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aP�=�¥��öê香¤””šÕÕÖÊ·¸:8YP:+Q~m„zx~‰‰ÌÇÉ_We@JEWhgnãäåîÙÙ(&L';ª©­¶¶¸R7HÚxxꙘð¸¸ñÉÇÉ™™, ÎÑ))Ñ88×XW?°ËØihȇ‡Ì©¨€:PÕHH³)(¹YXºgh¾zzí¨§ç‰ˆž¢''´IJþýû›¬£99d±‰a ¶:;–~|*)U$%Hÿÿÿ!þMade with GIMP�!ù �?�,����P�=�@þÀŸpH‚à·,:ŸÐ¨tJýE, äÁmH$\ƒ!;nLÀYNÇó…6„Å‚@' fuï¤0Ð]e[b]\4$Œ$!uqst''./! $#402++,-&˜8C/�� '%:5##!/.r'-+2 ¡Žl)-prÖ ./%)Ï¢51:,&&88 ²F/:ŽÂÕÉ-àò!«•t-!!) 1j³‚Z%9w´yûÔhD ¨Z<ÀÎ&¹((``áF`¢hÄXqÂZ¶ :C†A“"lJ.$ŒØ-¸Èó þ„<pУ£Hc°€£d€.RB•ƒƒÎžX³�T(Q£4ªP°@Ö"ÆüAD±L &@¡ž³x�@& "aÐ� SÀ€��NŸn*ñaÔQ5j€šü!E$ è‡)Ó�%¦(AoA…®CÝf™€Â`Ó°¢Q)_ÚD*Qâ �l`!Æ f:>Ô¨ê ÉV¨ŒCýªáò<ˆµ™áÁ1:òeB ûiµ‘‚UYð[¹†Ë˜oã‡Οp :´GŽÁ„àBˆA@€ 2À  ÂüFžS ¨ RÁŒv{·Dp‚ Ëþô W;yË$ÀÀ7ÜàÅü4‡22¨àÈ#nÔBà žÀÀ‡…xÖˆ%r”"H•€™r$À£Lö„Ë�w4Y„� „!†<À?™%å— €Æ‡x!!VvaÀe ‘ _òÁZ‡”ÑÖ!_”i� àôD©”¦„—LÚ“�¨Vg¨éW7¬ Išø8$C 09c0ælPÒ5ØJDL?U ÀPƒ¹uf tfo�1ÄDúÐͱ92Ä`ÛQDvS~C@%#¤¨ï9”‚ä@ì#lD2à-8nÖq*€òi#¤pÁ¨þ¤V€À±=jð¹)˜pÊ„P‚­ ºñ’IdÐ ¾¤È`Ž LqÛ+�˜ Ã°G1GÖVÜ¥ð[.s(ì H ›ªÐ©<£yÌý—\M3VF º(Y‘O-õË(Ôµp ÐÙ: 6,Ç-úBc¶µdNI¼úŠ’ÇH1‡,@šØÑ"ðê#½ö¼K®0µ su?%Ôê'#úÂÑrN †¸ŸWþu[e/D‹° %¨ÞQ5cBY:E‹ :¬Dœ[e´QG�’[@ӌٶ€ÃºcõHøk÷÷ßµ4^`KyÚÉàáXm^þãO=€¸§#À0úæ_5þ0„©xPØ$@Vé±`b¼úVaøNÁ]ÁÿXe2Š&šx®é€–7?ź…�FÆ÷ß«VÀLŠä×à{œRFô]€Å!�"‘€PB®q|Æs•È„ê 0€'¾ŽÖmÊ©¸Ðˆa  AIXŸ`1ØI5H�üp�f�–Š Â^°LˆskÃ4¬C/]A)JTx^_U'A,J‹Æ?J™T,&`Á ÀQ™>ÍHÇáBbrŒ<è'0Þ!°T¦-pÁÍÇØÊe3RqéAA{A ¼ƒ_ä&=¸ þèf5Ó¤Ž (Œ£¬ä� h2‰ŠJhS¬`yË6 ¡$ð�»låøRKªq‡y¥ @„AK&•´Kµ Xò¶@ÏÕá­¨Ãp|@É êRŒñÎÊÅ¢hÍ`«r¡Š¢Ñžßxd Û'Pƈü…Ê:Ö€ji�„€A%¸™5”±­‘K/U.A¯YáëVÕév€¦ `à^w¥ TÀƒ3TÒK�ÀÀТ±Aµó:OA Ù”[6¶Œ ,ä ¾ ` "ÅQ:0ÉJ‰›°”†àI,ðd“WOiä#‰% % ,Ž‚Tþ)šI]­3ÊÓ=‹à®`dsÃÑŸôW ¯m†8ÌdP. ÎW¶–÷Û#Ò¹�iRó ØGM–†�úôæ#‡.9lc;Z}ˆÀ¬–‡Ä(ÄÝA x@K‹BüùŠzògRvš *– –¢1f@a Ë[>Šò 씜¢èÜ 5T � p�Іɠój&X§<õl‹+ºHb/T)®rÕâj€Lmé$à ‰ª(Ç*P»Æ@Gë½6pO@N“,`(I V!s(ʰJ!¯”‡û ÉQ”R ¨Pï|×D9PË‹2)sDùnhš7à ³#]O+‹Ñ·„É€"X¬%e—© )ù ÇfÌ9FsC¨ßLµ÷¤ÔM $މ¼¦¨¬ÎÈ!<èq½«½­ &¼n;г6 7…€£Š}Àò*Œ¹úžè¾ß|Á@‹11€µ$þŒ‰ XÓdÀˆcŒ•T­J®ŒAˆwÌãuÅD=ðKä"«Íp�O‚��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/index.html����������������������������������������������������������0000644�0001750�0001750�00000102706�07504443346�017426� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML><HEAD><TITLE>Slashdot:News for Nerds. Stuff that Matters.</TITLE> </HEAD> <BODY bgcolor="#000000" text="#000000" link="#006666" vlink="#000000"> <center><a href="http://209.207.224.220/redir.pl?1463" target="_top"><img src="image1" alt="Click Here to enter the Sweepstakes" border="2" width="468" height="60"></a></center> <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TR><TD WIDTH="1"><SCRIPT LANGUAGE="JAVASCRIPT"> <!-- now="now" ="" new="new" Date();="Date();" tail="tail" ="" now.getTime();="now.getTime();" document.write("<IMG="document.write("<IMG" SRC="http://209.207.224.245/Slashdot/pc.gif?/slashhead.inc,"+" tail="tail" +="+" "=""" WIDTH="1" HEIGHT="1><BR>");" --> </SCRIPT> <NOSCRIPT> <IMG SRC="image2" WIDTH="1" HEIGHT="1"> </NOSCRIPT></TD></TR></TABLE><P> <TABLE bgcolor="#FFFFFF" cellpadding="0" cellspacing="0" border="0" width="99%" align="center"> <TR> <TD valign="top" align="left" valign="top"><A href="http://slashdot.org/"><IMG src="image3" width="275" height="72" border="0" alt="Welcome to Slashdot"></A></TD> <TD><A href="http://slashdot.org/search.pl?topic=linux"><IMG SRC="image4" width="60" height="70" border="0" alt="Linux"></A></TD> <TD><A href="http://slashdot.org/search.pl?topic=news"><IMG SRC="image5" width="34" height="44" border="0" alt="News"></A></TD> <TD><A href="http://slashdot.org/search.pl?topic=usa"><IMG SRC="image6" width="80" height="61" border="0" alt="United States"></A></TD> <TD><A href="http://slashdot.org/search.pl?topic=ed"><IMG SRC="image7" width="87" height="64" border="0" alt="Education"></A></TD> <TD><A href="http://slashdot.org/search.pl?topic=space"><IMG SRC="image8" width="73" height="59" border="0" alt="Space"></A></TD> </TR></TABLE> <TABLE width="99%" align="center" cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF"><TR> <TD valign="top" rowspan="5"><NOBR><FONT size="2"><B> &nbsp;<A href="/faq.shtml">faq</A> <BR> &nbsp;<A href="/code.shtml">code</A> <BR> &nbsp;<A href="/awards.shtml">awards</A> <BR> &nbsp;<A href="http://Andover.Net/privacy.html">privacy</A> <BR> &nbsp;<A href="http://slashnet.org">slashNET</A> <BR> &nbsp;<A href="/search.pl">older stuff</A> <BR> &nbsp;<A href="http://cmdrtaco.net">rob's page</A> <BR> &nbsp;<A href="/users.pl?op=preferences">preferences</A> <BR> &nbsp;<A href="http://Andover.Net">andover.net</A> <BR> &nbsp;<A href="/submit.pl">submit story</A> <BR> &nbsp;<A href="/advertising.shtml">advertising</A> <BR> &nbsp;<A href="/supporters.shtml">supporters</A> <BR> &nbsp;<A href="/pollBooth.pl">past polls</A> <BR> &nbsp;<A href="/topics.shtml">topics</A> <BR> &nbsp;<A href="/about.shtml">about</A> <BR> &nbsp;<A href="/jobs.shtml">jobs</A> <BR> &nbsp;<A href="/hof.shtml">hof</A> </B></FONT></NOBR> <P><TABLE border="0" cellpadding="1" cellspacing="0" align="center" bgcolor="#CCCCCC"><TR> <TD><FONT size="2" color="#000000"><B> Sections</B></FONT></TD></TR> <TR><TD><TABLE border="0" cellspacing="1" cellpadding="1" bgcolor="#FFFFFF" width="100%"><TR><TD><FONT color="#000000" size="2"><NOBR> 1/23<BR> <B><A href="http://slashdot.org/index.pl?section=apache">apache</A></B><BR> 1/29 (3)<BR> <B><A href="http://slashdot.org/index.pl?section=askslashdot">askslashdot</A></B><BR> 1/27<BR> <B><A href="http://slashdot.org/index.pl?section=awards">awards</A></B><BR> 1/29 (2)<BR> <B><A href="http://slashdot.org/index.pl?section=books">books</A></B><BR> 1/27<BR> <B><A href="http://slashdot.org/index.pl?section=bsd">bsd</A></B><BR> 1/28 (2)<BR> <B><A href="http://slashdot.org/index.pl?section=features">features</A></B><BR> 1/28 (2)<BR> <B><A href="http://slashdot.org/index.pl?section=interviews">interviews</A></B><BR> 1/19<BR> <B><A href="http://slashdot.org/index.pl?section=radio">radio</A></B><BR> 1/27 (2)<BR> <B><A href="http://slashdot.org/index.pl?section=science">science</A></B><BR> 1/28 (3)<BR> <B><A href="http://slashdot.org/index.pl?section=yro">yro</A></B><BR> </NOBR></FONT></TD></TR></TABLE><TR> <TD><A href="http://andover.net"><FONT size="2" color="#000000"><B>Andover.Net</B></FONT></A></TD></TR> <TR><TD><TABLE border="0" cellspacing="1" cellpadding="1" bgcolor="#FFFFFF"><TR><TD> <FONT color="#000000" size="2"><NOBR><A href="http://www.andovernews.com">AndoverNews</A><BR><A href="http://www.askreggie.com">Ask Reggie</A><BR><A href="http://www.davecentral.com">DaveCentral</A><BR><A href="http://www.freecode.com">FreeCode</A><BR><A href="http://www.mediabuilder.com">MediaBuilder</A><BR> </NOBR></FONT></TD></TR></TABLE></TD></TR></TABLE></P> <P></P> </TD><TD valign="top" align="left"><FONT color="#000000"> <TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Who Bought Linux.Net?</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=linux"><IMG src="image4" width="60" height="70" border="0" align="right" hspace="20" vspace="10" alt="Linux"></A> <B>Posted by <A href="http://CmdrTaco.net">CmdrTaco</A> on Saturday January 29, @10:52AM</B><BR> <FONT size="2"><B>from the this-game-again dept.</B></FONT><BR> So Fred VanKampen (who has to hold the record for most money made by reselling two domain names) e-mailed us to say that the Domain Name for 'Linux.Net' has been sold. He won't say to whom, but it supposedly will be announced at LinuxWorld next week. Of course we have no idea what he got for the entry, but the rumors were that he made several million when he sold <A href="http://www.linux.com">Linux.com</A> to <A href="http://www.valinux.com">VA Linux</A>. Hopefully he'll take me for a ride in his yacht. ;) <P><B>( </B><A href="http://slashdot.org/articles/00/01/29/0837235.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/29/0837235&mode=thread&threshold=0">58</A> of <A href="http://slashdot.org/article.pl?sid=00/01/29/0837235&mode=thread&threshold=-1">62</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Book Reviews: E-Mails from (Over?) The Edge</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=news"><IMG src="image5" width="34" height="44" border="0" align="right" hspace="20" vspace="10" alt="News"></A> <B>Posted by <A href="http://hemos.net">Hemos</A> on Saturday January 29, @10:43AM</B><BR> <FONT size="2"><B>from the touching-story dept.</B></FONT><BR> I'd like to thank the author of this book for sending it to me. Nick's written a book that's touching and endearing, and one that's well worth reading for everyone who's ever had social struggles to deal with. As well, his involvement with the fine folks of <a href="http://www.thevenue.org">TheVenue</a>. I'll warn you - it's not a tech text. But it's still worth reading. Click below to read more. <P><B>( </B><A href="http://slashdot.org/books/00/01/24/1146250.shtml"><B>Read More...</B></A> | <A href="http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=nocomment">6197 bytes in body</A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=thread&threshold=0">6</A> of <A href="http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=thread&threshold=-1">22</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Linux Kernel 2.3.41</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=linux"><IMG src="image4" width="60" height="70" border="0" align="right" hspace="20" vspace="10" alt="Linux"></A> <B>Posted by <A href="http://CmdrTaco.net">CmdrTaco</A> on Saturday January 29, @10:21AM</B><BR> <FONT size="2"><B>from the download-compile-reboot-repeat dept.</B></FONT><BR> <A href="mailto:bwhitehead@nospam.acm.org">sdriver</A> writes <I>"For those of us who enjoy *panic*, *oops*, and suddenly seeing their video BIOS... the newest version is out! Be the first on your block to submit a new patch! ;) "</I> If you don't know where to get it, you probably should stick to your warm and cuddly 2.2.x kernel *grin*. Now outta my way, I wanna crash my laptop! <P><B>( </B><A href="http://slashdot.org/articles/00/01/29/0834223.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/29/0834223&mode=thread&threshold=0">52</A> of <A href="http://slashdot.org/article.pl?sid=00/01/29/0834223&mode=thread&threshold=-1">57</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Congress Still Figuring Out E-Mail</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=usa"><IMG src="image6" width="80" height="61" border="0" align="right" hspace="20" vspace="10" alt="United States"></A> <B>Posted by <A href="mailto:roblimo@slashdot.org">Roblimo</A> on Saturday January 29, @07:28AM</B><BR> <FONT size="2"><B>from the voice-of-the-people-can-get-awfully-loud dept.</B></FONT><BR> Jett writes <I>" <A href="http://www.vote.com/">Vote.com</A> has <A href="http://www.vote.com/magazine/editorials/editorial1843752.phtml">an interesting article</A> in their Webmag Fifth Estate about how congressmen have responded to the popularity of e-mail in their daily operations. Quote: 'Of the 440 voting and non-voting House of Representatives members, 22 have no e-mail at all. Even House Speaker Dennis Hastert is wired only halfway -- his office receives e-mail, but does not respond to it. And while all U.S. senators have e-mail, they, like their House counterparts, routinely shun non-constituent mail -- even though they chair committees whose decisions affect the entire country.'"</I> <P><B>( </B><A href="http://slashdot.org/articles/00/01/28/2311232.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/28/2311232&mode=thread&threshold=0">66</A> of <A href="http://slashdot.org/article.pl?sid=00/01/28/2311232&mode=thread&threshold=-1">66</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Ask Slashdot: Sci Fi Literature 101?</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=ed"><IMG src="image7" width="87" height="64" border="0" align="right" hspace="20" vspace="10" alt="Education"></A> <B>Posted by <A href="http://exit118.com/">Cliff</A> on Saturday January 29, @06:56AM</B><BR> <FONT size="2"><B>from the recommendations-wanted dept.</B></FONT><BR> ohlaadee asks: <I>"My niece (she's 13) wants to start reading science fiction. I do too. I gave us both Asimov's </I>_The Foundation_<I>&nbsp; for Christmas. We'll read it together. I suppose we could spend the rest of our lives just reading Asimov, but I'm wondering what books and movies you folks would come up with? What does the /. recommended Science Fiction 101 list include?"</I> <P><B>( </B><A href="http://slashdot.org/askslashdot/00/01/22/1946244.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/22/1946244&mode=thread&threshold=0">345</A> of <A href="http://slashdot.org/article.pl?sid=00/01/22/1946244&mode=thread&threshold=-1">345</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Could Distributed.Net Help the Mars Polar Lander?</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=space"><IMG src="image8" width="73" height="59" border="0" align="right" hspace="20" vspace="10" alt="Space"></A> <B>Posted by <A href="mailto:roblimo@slashdot.org">Roblimo</A> on Saturday January 29, @03:35AM</B><BR> <FONT size="2"><B>from the food-for-thought dept.</B></FONT><BR> Anonymous Coward writes <I>"This official JPL <A href="http://mpfwww.jpl.nasa.gov/msp98/news/mpl000127.html">press release</A> describes the current attempt to listen for faint signals from the Mars Lander. They get three windows a day, and it takes 18 hours to process data because the signal is so weak (if it's really there). Too bad they don't have a deal with <A href="http://www.distributed.net"> distributed.net</A>."</I> Interesting thought. Is anyone at distributed.net or JPL interested in pursuing it? <P><B>( </B><A href="http://slashdot.org/articles/00/01/28/2318246.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/28/2318246&mode=thread&threshold=0">99</A> of <A href="http://slashdot.org/article.pl?sid=00/01/28/2318246&mode=thread&threshold=-1">102</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>iCrave TV Loses Battle against U.S. Broadcasters</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=tv"><IMG src="image10" width="50" height="50" border="0" align="right" hspace="20" vspace="10" alt="Television"></A> <B>Posted by <A href="mailto:roblimo@slashdot.org">Roblimo</A> on Saturday January 29, @12:21AM</B><BR> <FONT size="2"><B>from the shut-down-just-before-the-super-bowl dept.</B></FONT><BR> <A href="mailto:doran@brandx.net">Doran</A> writes <I>"C|Net has <a href="http://news.cnet.com/news/0-1004-200-1535528.html">this story</a> about how the Canadian company <a href="http://www.icravetv.com">iCraveTV.com</a> has lost its latest battle in U.S. courts over whether it can rebroadcast TV signals over the Web. The broadcasters say it's theft, while iCraveTV sez it's just doing what's legal for other cable TV companies in Canada (ie. rebroadcasting TV). Of course, by framing the streaming video iCraveTV is doing more than just rebroadcasting, they're also adding more commercial content, which the broadcasters feel dilutes their TV commercials. "</I> <P><B>( </B><A href="http://slashdot.org/articles/00/01/29/0010203.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/29/0010203&mode=thread&threshold=0">152</A> of <A href="http://slashdot.org/article.pl?sid=00/01/29/0010203&mode=thread&threshold=-1">170</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Win2k Security holes found</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=microsoft"><IMG src="image11" width="75" height="55" border="0" align="right" hspace="20" vspace="10" alt="Microsoft"></A> <B>Posted by <A href="mailto:heunique@slashdot.org">HeUnique</A> on Friday January 28, @04:58PM</B><BR> <FONT size="2"><B>from the and-it's-not-even-out-yet dept.</B></FONT><BR> According to a story posted by <a href="http://www.zdnn.com">ZDNN</a>, <a href="http://www.zdnet.com/zdnn/stories/news/0,4586,2429334,00.html?chkpt=zdnntop">two security holes</a> have been found on Windows 2000, and that's even before the official release of Windows 2000! Administrators who rush to incorporate the patch from MS beware - according to one of the talkback posts on ZDNN, the patch creates a new problem with Windows 2000 news server service. <P><B>( </B><A href="http://slashdot.org/articles/00/01/28/1653228.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/28/1653228&mode=thread&threshold=0">510</A> of <A href="http://slashdot.org/article.pl?sid=00/01/28/1653228&mode=thread&threshold=-1">534</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Encryption Debate at Mitnick Trial</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=encryption"><IMG src="image12" width="80" height="70" border="0" align="right" hspace="20" vspace="10" alt="Encryption"></A> <B>Posted by <A href="http://hemos.net">Hemos</A> on Friday January 28, @03:33PM</B><BR> <FONT size="2"><B>from the gimmie-the-data dept.</B></FONT><BR> A number of people have written about <A HREF="http://nytimes.com/library/tech/00/01/cyber/cyberlaw/28law.html">the latest twist</a> in the Mitnick case. Kevin wants to get his data back, but the government is refusing to do so until he gives them the key. Apparently, the government is unable to crack the encryption that he's got on it - you'd think after having the data for five years, they'd be able to brute-force the darn thing. It's a NYT article - free login required. <P><B>( </B><A href="http://slashdot.org/articles/00/01/28/1320253.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/28/1320253&mode=thread&threshold=0">504</A> of <A href="http://slashdot.org/article.pl?sid=00/01/28/1320253&mode=thread&threshold=-1">521</A> </B>comments <B>)</B> <P><TABLE width="99%" cellpadding="0" cellspacing="0" border="0"><TR><TD valign="top" bgcolor="#006666"><IMG src="image9" width="13" height="16" alt="" align="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Forum: Future Ports of Games to Linux</B></FONT></TD> </TR></TABLE><A href="http://slashdot.org/search.pl?topic=games"><IMG src="image13" width="80" height="56" border="0" align="right" hspace="20" vspace="10" alt="Games"></A> <B>Posted by <A href="http://CmdrTaco.net">CmdrTaco</A> on Friday January 28, @02:26PM</B><BR> <FONT size="2"><B>from the it's-been-awhile dept.</B></FONT><BR> It's been a long time since I posted an open forum like this, but I'm curious what people think on this one. What games do you most want to see ported to Linux in the next few months? Of course, for me personally it's StarCraft and Diablo 2, but I'm curious what games have come out or are due soon that people would most like to see a port of (and note that WINE doesn't count. ;) <P><B>( </B><A href="http://slashdot.org/articles/00/01/28/1257211.shtml"><B>Read More...</B></A> | <B><A href="http://slashdot.org/article.pl?sid=00/01/28/1257211&mode=thread&threshold=0">648</A> of <A href="http://slashdot.org/article.pl?sid=00/01/28/1257211&mode=thread&threshold=-1">652</A> </B>comments <B>)</B> <P></TD><TD width="210" align="center" valign="top"><TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B><A HREF="/index.pl?section=features"><FONT COLOR="#FFFFFF">Features</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><A href="/vote.pl">Voting has begun</A> for the $100k <A href="/index.pl?section=awards">Slashdot Beanie Awards</A>. Talk amongst yourselves and choose who deserves the cash. <P>The latest installment of <A href="http://www.thesync.com/geeks">Geeks in Space</A> is up at <A href="http://www.thesync.com">The Sync</A>. Listen to CmdrTaco, Hemos, and Nate talk about the latest events to happen - or not happen in the computer world. <P>Perhaps you are seeking Jon Katz's series of articles related to recent events in Colorado. These articles include <A href="/article.pl?sid=99/04/25/1438249">Voices from the Hellmouth</A>, <A href="/article.pl?sid=99/04/27/0310247">More Stories from the Hellmouth</A> or <A href="/article.pl?sid=99/04/29/0124247">The Price of Being Different</A>, <P>For something different, try reading a little essay <A href="/article.pl?sid=99/03/31/0137221">Thoughts from the Furnace</A> about the internet, and flame. <p> And for a bit of an amusing take on the Open Source world, check out <a href="/article.pl?sid=99/08/24/1327256&mode=thread">Open Source as an Ant Farm</a> <P><B>Update: 01/03 03:10</B> by <B><A href="http://cowboyneal.org">CowboyNeal</a></B>: <P align="right"><B><A href="/features/">Past Features</A></B> <!-- end="end" features="features" block="block" --></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B><A HREF="http://slashdot.org/index.pl?section=askslashdot"><FONT COLOR="#FFFFFF">Ask Slashdot</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1946244">Sci Fi Literature 101?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/192226">Linux and Satellite Internet Services</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1843258">Open Defensive Patents?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1825252">Technologies That Shaped the Last Century?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1958212">Disk Repair Tools for Linux?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1955215">Why Can't the Command-Line be More Standardized?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1928235">Packet Radio Networking with PalmOS?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1817211">Cheap Rackmount Enclosures/Systems?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1950249">Open Source Software and Tax Breaks?</A> <li><A HREF="http://slashdot.org/article.pl?sid=00/01/22/1917207">Building an Upgradable Dual Processor System</A> <P> if you have a question for Ask Slashdot, send it to <A href="mailto:askslashdot@slashdot.org">askslashdot@slashdot.org</A></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B><A HREF="/users.pl"><FONT COLOR="#FFFFFF">Slashdot Login</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><FORM action="/users.pl" METHOD="POST"> <B>Nickname:</B><BR> <INPUT type="text" name="unickname" size="20" value=""><BR> <B>Password:</B><BR> <INPUT type="hidden" name="returnto" value="index.pl"> <INPUT type="password" name="upasswd" size="20"><BR> <INPUT type="submit" name="op" value="userlogin"> </FORM> Don't have an account yet? <A href="/users.pl">Go Create One</A>. A user account will allow you to customize all these <A href="/cheesyportal.shtml">nutty little boxes</A>, tailor the stories you see, as well as remember your comment viewing preferences.</FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Slashdot Poll</B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><FORM action="http://slashdot.org/pollBooth.pl"> <INPUT type="hidden" name="qid" value="techadvance"> <B>The Tech Advance I Most Want Is:</B><BR><INPUT type="radio" name="aid" value="1">Nanotechnology<BR><INPUT type="radio" name="aid" value="2">Cold Fusion<BR><INPUT type="radio" name="aid" value="3">Powerful Fuel Cells<BR><INPUT type="radio" name="aid" value="4">Hard Wiring my Body<BR><INPUT type="radio" name="aid" value="5">Universal Strong Crypto<BR><INPUT type="radio" name="aid" value="6">Interstellar Travel<BR><INPUT type="radio" name="aid" value="7">Cybernetic Body Armor<BR><INPUT type="radio" name="aid" value="8">ColecoVision<BR><INPUT type="submit" value="Vote"> [ <A href="http://slashdot.org/pollBooth.pl?qid=techadvance&aid=-1"><B>Results</B></A> | <A href="http://slashdot.org/pollBooth.pl?"><B>Polls</B></A> ] <BR>Comments:<B>656</B> | Votes:<B>29121</B></FORM> </FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Older Stuff</B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><P><B><A href="http://slashdot.org/index.pl?section=&issue=730512&mode=thread"><FONT size="4">Friday</FONT></A> January 28</B> <LI><A href="http://slashdot.org/articles/00/01/28/1110258.shtml">Abstract Programming and GPL Enforcement</A> (235) <LI><A href="http://slashdot.org/interviews/00/01/28/1225206.shtml">Interview: FreeDOS Leader Jim Hall Answers</A> (86) <LI><A href="http://slashdot.org/articles/00/01/28/116240.shtml">Open Source's Achilles Heel</A> (466) <LI><A href="http://slashdot.org/features/00/01/26/1915230.shtml">The Virtue of Communal Instincts</A> (237) <LI><A href="http://slashdot.org/articles/00/01/28/0723223.shtml">Gartner Group Debunking Open Source Myths</A> (165) <LI><A href="http://slashdot.org/yro/00/01/28/0917229.shtml">DoubleClick Taken to Court</A> (310) <LI><A href="http://slashdot.org/articles/00/01/28/0718209.shtml">Updated Slash & Server 51</A> (81) <LI><A href="http://slashdot.org/articles/00/01/28/089230.shtml">XMMS 1.0.0 Released</A> (128) <LI><A href="http://slashdot.org/askslashdot/00/01/22/192226.shtml">Linux and Satellite Internet Services</A> (138) <LI><A href="http://slashdot.org/articles/00/01/27/1811221.shtml">UN Wants to Combat Online Racism</A> (531) <P><B><A href="http://slashdot.org/index.pl?section=&issue=730511&mode=thread"><FONT size="4">Thursday</FONT></A> January 27</B> <LI><A href="http://slashdot.org/yro/00/01/27/2330205.shtml">Crackdowns, Fools and the MPAA</A> (351) <LI><A href="http://slashdot.org/articles/00/01/27/0832215.shtml">Heroes of Might and Magic III Demo Released</A> (157) <LI><A href="http://slashdot.org/science/00/01/27/1345241.shtml">Sandia Labs Venture Into Nanotechnology</A> (117) <LI><A href="http://slashdot.org/articles/00/01/27/0931237.shtml">CA Announces Program Ports to Linux</A> (195) <LI><A href="http://slashdot.org/interviews/00/01/27/1118251.shtml">Interview: Larry Augustin Finally Answers</A> (210) <LI><A href="http://slashdot.org/awards/00/01/27/0855252.shtml">Final Call for Voting in Slashdot's Beanie Awards</A> (178) <LI><A href="http://slashdot.org/features/00/01/26/197211.shtml">Transmeta Code Morphing != Just In Time</A> (449) <LI><A href="http://slashdot.org/books/00/01/24/1150256.shtml">Intrusion Detection</A> (65) <LI><A href="http://slashdot.org/science/00/01/27/0824239.shtml">Using Enzymes to Help Fight CO2 Build-Up</A> (165) <LI><A href="http://slashdot.org/articles/00/01/27/0712217.shtml">Jon Johansen on ABC World News Tonight</A> (415) <P align="right"><BR><A href="http://slashdot.org/search.pl?section=&min=30"><B>Older Articles</B></A><BR><A href="http://slashdot.org/index.pl?section=&mode=thread&issue=730512"><B>Yesterday's Edition</B></A> </FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B><A HREF="/index.pl?section=books"><FONT COLOR="#FFFFFF">Book Reviews</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><p>Jon Katz, Resident Gasbag, has a new, very appropriate book coming out soon, <a href="http://www.thinkgeek.com">Geeks</a>. Preorder now and receive the book early. <p>For probably the best fiction read around, check out Neal Stephenson's <cite><a href="/article.pl?sid=99/06/23/139229&mode=thread">Cryptonomicon</a></cite>, an engaging read about WWII, cryptography and buried treasure. And data vaults. <p>If you've been doing a lot of work in Perl, you've probably figured out you really need <cite><a href="/article.pl?sid=99/05/10/2238254&mode=thread">Perl in a Nutshell</a></cite> or <cite><a href="/article.pl?sid=99/01/29/1035246&mode=thread">The Perl Cookbook</a></cite>. If you're still learning, grab <cite><a href="/books/older/980526096229.shtml">Programming Perl</a></cite>. <p>And if you want to learn more about how to become a better coder, grab <cite><a href="/article.pl?sid=99/06/28/1417229&mode=thread">The Unified Software Development Process</a></cite> or <cite><a href="/article.pl?sid=99/04/08/1512209&mode=thread">The Practice of Programming</cite></a> Additionally, check out <cite><a href="http://slashdot.org/article.pl?sid=99/09/16/1333202&mode=thread">Refactoring: Improving the Design of Existing Code</a></cite> . <p>Developing a large application? Grab Eric Greenberg's excellent <cite><a href="/article.pl?sid=99/07/13/1943258&mode=thread">Network Application Frameworks</cite></a>. <P>Visit <A href="/index.pl?section=books">Our Book Reviews Section</A> for more. <br> <B>Update: 11/12 05:19</B> by <B><A href="mailto:hemos@slashdot.org">H</A></B>:</FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B>Quick Links</B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><B>Cool Sites:</B> <LI><A href="http://www.linux.com">Linux.com</A> (What <B>is</B> Linux?) <LI><A href="http://everything.blockstackers.com">Everything</A> (Blow your Mind) <LI><A href="http://www.geekculture.com/geekycomics/Aftery2k/aftery2kmain.html">After Y2k</A> (<I>This</I> is Post-Apocalyptic?) <LI><A href="http://www.userfriendly.org">User Friendly</A> (Laugh) <LI><A href="http://themes.org">Themes.org</A> (Make X Perty) <P><B>Support Slashdot:</B> <LI><A href="http://www.thinkgeek.com">ThinkGeek</A> (Clothe Yourself in Slashdot) <LI><A href="http://cdnow.com/from=sr-302791">CDnow</A> (Support <A href="http://www.cdnow.com/gift/malda@slashdot.org">Rob's Who Habit</A>) <LI><A href="http://adfu.slashdot.org">Slashdot Advertiser Index</A></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding="1" cellspacing="0" border="0" width="200" align="center"> <TR bgcolor="#006666"> <TD valign="top"><FONT size="4" color="#FFFFFF" face="arial,helvetica"><B><A HREF="http://freshmeat.net"><FONT COLOR="#FFFFFF">Freshmeat</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor="#CCCCCC"><FONT color="#000000" size="2"><P><FONT size="4" color="#006666"><B>January</B></FONT><BR> <LI><A href="http://freshmeat.net/news/2000/01/29/949208399.html">We should get this out of the door now</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949159642.html">Is Linux for Crazies?</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949156343.html">SQN Linux 1.6</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949156277.html">Limo 0.3.2</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949156237.html">Fusion GS 1.3</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949145887.html">MMR 1.5.4</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949142835.html">KUPS 0.3.4</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949142815.html">3DSE patch for XMMS 4</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949139763.html">Linux 2.3.41</A> <LI><A href="http://freshmeat.net/news/2000/01/29/949139751.html">Free Code for Linux S/390</A> <FORM METHOD="post" ACTION="http://core.freshmeat.net/search.php3"> <FONT size="3" color="#006666"><B>Search Freshmeat:</B></FONT><BR> <INPUT TYPE="hidden" NAME="link" VALUE="freshmeat.net"> <INPUT TYPE="text" NAME="query"> </FORM> <P align="right"><A href="http://freshmeat.net"><B>More Meat...</B></A></FONT></TD> </TR> </TABLE><P> </FONT></TD> </TR> </TABLE><TABLE cellpadding="0" cellspacing="0" border="0" width="99%" align="center" bgcolor="ffffff"> <TR> <TD colspan="4" align="center"><IMG src="image14" alt="" width="80%" height="1" hspace="10" vspace="30"></TD> </TR><TR> <TD align="center"><FONT size="2" face="arial,helvetica"> <FORM method="GET" action="http://slashdot.org/search.pl"> <INPUT type="name" name="query" value="" width="20" size="20" length="20"> <INPUT type="submit" value="Search"> </FORM> </FONT> </TD> <TD bgcolor="#ffffff" width="25"> &nbsp; </TD> <TD align="center"> <FONT size="2" face="arial,helvetica"><I>Wasn't there something about a PASCAL programmer knowing the value of everything and the Wirth of nothing? <TD>&nbsp;</TD></I></FONT> </FONT> </TD></TR> <TR><TD colspan="4" align="center"> <FONT size="1" color="#006666" face="arial,helvetica"> All trademarks and copyrights on this page are owned by their respective owners. Comments are owned by the Poster. The Rest © 1997-2000 <A href="http://Andover.Net">Andover.Net</A>. </FONT></CENTER> </TD> </TR> </TABLE> <CENTER> <FONT size="2" color="#006666"> [ <A href="http://slashdot.org/"><Font color="#ffffff">home</FONT></A> | <A href="http://slashdot.org/awards.shtml"><Font color="#ffffff">awards</FONT></A> | <A href="http://slashdot.org/supporters.shtml"><FONT color="#ffffff">supporters</FONT></A> | <A href="http://CmdrTaco.net"><FONT color="#ffffff">rob's homepage</FONT></A> | <A href="http://slashdot.org/submit.pl"><FONT color="#ffffff">contribute story</FONT></A> | <A href="http://slashdot.org/search.pl"><FONT color="#ffffff">older articles</FONT></A> | <A href="http://Andover.Net"><FONT color="#ffffff">Andover.Net</FONT></A> | <A href="http://slashdot.org/advertising.shtml"><FONT color="#ffffff">advertising</FONT></A> | <A href="http://slashdot.org/pollBooth.pl"><FONT color="#ffffff">past polls</FONT></A> | <A href="http://slashdot.org/about.shtml"><FONT color="#ffffff">about</FONT></A> | <A href="http://slashdot.org/faq.shtml"><FONT color="#ffffff">faq</FONT></A> ] </FONT> </CENTER> </BODY> </HTML> ����������������������������������������������������������./saods9/htmlwidget/tests/page1/image10�������������������������������������������������������������0000644�0001750�0001750�00000006027�07504443347�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a2�2�÷��Œ’Œ¼ÊÄLZTœ²¬lvtÔæä4><Œ¢œ„~|ÜÖÔlfdLBD¼¶´ìæìTjdÄÚÔ¤¢œt‚|,.,<NLœ’”ìöô\Z\¤º´ÌÊĄЄ4.4|vt4FD¼Â¼ÜÞÜLNL¤ª¤üöôÜò쌚”¬®¬lnlÌÒÌl~tœ¢œ¬¢¤œšœ\b\”ŠŒ464\VTTb\djlìþüDFDÌÆÄìâ䬶´tvtäæäìîìÔÚÔ|ЄļäÞÜLVT|rt<64TZTD>D„†„¼¾¼$64DVTôöô´º´ŒŠŒ´®¬tnl¤šœdbd$&$”’”ÄÖÔ”ª¤äÚÜ\jd¤¦¬|‚|DNLÔÎÌ|~|TRT”š”ÔÒÌÄÊÄ<><”¢œÜÚÔLJL¼º´Ìâܤ¦œÌÎÄ<FDLRL¬ª¤üþüäúôœª¤¬¦¤4:4DJDtztäîìôòôÄÆ¼äâÜ,64´²¬,*,\ndŒ–”L^\lztÜæä„‚„ljlLFDìêäÌÚÜœ–”ÔâÜdrl¬º´äò줮¬t~|Œ†„ôþü´¶´TVTľ¼t†„,24ìúô\^\„ŽŒ|z|¼ÆÄÜâÜüúüŒžœ¬²´lrlœ¦¤œžœ\fd”ŽŒäêäìòìÔÞÜ<:<T^\ôúô´¾¼ŒŽŒtrt¤žœdfd$*+|†„DRO”žœÔÖÔÄÎÌ<B?”¦¤<JH¬¾¼äöôÔêäÄÞÔ<RL424dnlDBD$:4”–”,:4Œ’”LZ\„~„ÜÖÜlfl¼¶¼¤¢¤ÌÊÌ„ŠŒ|v|¼ÂÄLNT¤ª¬üöüÌÒÔœ¢¤¬¢¬\bd46<\V\TbdDFLtv||ŠŒÄÂÄäÞä<6<TZ\´º¼´®´tnt\jl|‚„|~„”šœÔÒÔÄÊÌ”¢¤ÜÚܼº¼¤¦¤ÌÎÌLRT¬ª¬¬¦¬4:<DJLtz|ÄÆÄäâä´²´\nllz|LFLìê윖œŒ†Œìúü\^dÜâälrtœž¤”Ž”äêììòôôúüŒŽ”¤ž¤dfl,����2�2��þ� ´wíÆ¨c6ˆA(– 4! H/âDD!òs4GJ"<¢‘Aš >Y.ü³%HÛƒ¶ ¡W¨˜˜7!J”a‘ßEˆø‰¤„†hš¨ŒaJÓ3< ð<c¦É–-mš˜i+`HÕ1QžôYèèQ #B:ù-êQ…Fs>A»%”¦(¶ºqOÑ3[&¬ÚâjÈP®¨†Cò-ПhyTK”ÑEæ¨Õš¢[eÒ½‚–D–{܆©Þ6dˆnÑ Ü›íÆÓ1bB*¤c²edeázU¯¼[·˜=*W†M3!·>µºUºêaO”‡ï ¤!Xîþ]²ÅÂZr˜ö‰d‹B‡ÝJåªÐ‚Ï¿zYà ²¡Z—V3€†i¦ðqI${ì’%XRBÇ`bˆ§Ü¡žeCÍB&ªS?+P >™tÓB/?\Å-.ÔòÉ <Ò7ì1 ™¬0N0+XBD�mt‘‚GG�'´ÐÍ +#O0PF¹Œ %”€9™$ )¼…"Mp„<¹“Ë8)¬ sÝ ¡ÀE*JÊ#ˆþDé?*œ£‚9íˆ3Í:4L³Š7ÂLÓN–‘„I Á3Ê 3@²ž‘h Š!ÝÈóá þ(£L0£ª°Œ9%ЃҰ9þ °ãG<ìôàÀ v³Î0 ”qÃdC¡Q /¨<ñDL¬@¢¨øìÌg”ÐN‹¬³Ž«dûAlë O¬ L�åÌÀ‚Pk‰D¨ôó„<L*›‚2)àå8æ(‘„ ³N[„#8ÔÀN k4)Œ`´QŽPìÅ(C$ñ.¼$‚£Š™ŒzF´í4 ‹s…7_ôÀŽ=„#Å <±Î¦¤SÎzëiãÃ0ýäS<ø¬à…ƒÓq&㜡jd³9MŸðÅ$×àO¥HzA:Џù‘H©X1Ê.ùäóˆªà£ÊÚ)3ÎÛgX²/ßd ÌS¯,þ5$ î(€` G|í‘f 3J.ùŒ²B.Zt£Šä™ÌAæÐ‘Hµ4|C9Þ¬;ìà°Ç +d0Ê#Y˜óZŠSñ(´ƒ› SÞö9¨6PÌ4\# è¢w;I/7à³Î(Md‘…á°'^q£˜mì¹ä²ö½æÈͪð߬ÃÔ|€Å ™“)f€,[Ö€ÐZÅ›$Aý(Oìr‡ªTŽo ‰Ô:†÷¹Ð‰n‘à@úFaŠ,€ 2†ÓD:*6„Qôãö»_�r±‚Qsâø ˜­UD#yèÇŒ²Ç VÀÂ(†‘„M´&ƒIØEä* *dndþƒòÜðBç o"y4``Z1ÜÁ†˜!õæ1„Ch ‚‹ËD&ò„/ïMc4 `½ARp M*1Ä–A£¸á<¨HÅrP‹n‹0Ff-áŒGôGÿ‚6¸p-j`†L0Š$h ‡˜žµ˜‰{I+ _\Ç7†HFrðÁ™ ÂXÂá j€*0Œ=TlT<þîXÉÿµ Óø] HaðøX1°‡=¬ÐDI»=@rzOà`“܆ª�²*ˆìe ø°‚kDâB0æ)Ñð†»@{¹¨-vǶÙrd<Ô�Á' S, ‰þ¸"ºÐ…µ` ˜‚!´°‹Ååƒz-°“¶8Ž5�*‰øb«æ™uüÃOÀ)²ð‰[À8G¨ % 0…<@B wX±¬w»”`´8¨ Ò x›\€)6Q€àEè„eDê c»Ñ�—â£n³Ò-ù(ÏÎ ÃUõüÇ(Ìa‚,tADF8>€ƒ #ˆØA ` S`!òh*“ JM�ZSž}à&¿ÁSl• è‚ ˜4q¬#9Ȇ`E,ñÎÄžòŒ°ëÀ,¿’‘ ­#xäÐéVcЇO|‚nØÃžP"°ã¶�þ)bÀ‚Va Æ&˜P ‡¢ªF1ŠAÎ~C“äXņg>lu ŸaÃ'IqÄQ”€hPGÐ1ÖÖ´`0ÅVqì ³Ö:02ÜUãD8ˆ�sÜã`ø„) dŠ_DbÂ@„-&à6¸  ˜N+6P 8㹸Æ4pI÷sÉ]8ÂQÜlã æÐg`ûúËKÌ#«8B bÀ'ÌÁ§hE+ø)ØZœ¢`XÀÆÖ^‚ŽŒœ$V[,4·hî'#‘‰uàÀ#:PÇÐÁ�¸`§p;ƒ%Þ xa`c¾ðÆþ’ÁoìA¬Jf`‚&Ä hG8à€GX`HÐ:\à„F°¡§`Ã#ª \`}€‡"²Ñ„"‡È6%ŽHX¬Ip4p‰=D*@ÁHJ�ŠVÌá@‡ŒÑ‚ll4 MhÂ~i‚lÜ€7¸A$†À‚Õš# ÷hš›€LL#… F¦½â9hfl(Ã-$ ”hºˆF$ðf*Ž¢O¸À@ u aì€Ã8§ Hâ­8�²ü"ç)âh‚)– Ž`ÁÃ{ä‚17ü¢ 1G8â‘.œa BE'4�+Á¶Ólþ/` €I‡påýÌQ¿G€!%ðF'¢]ñõD›êyC" ` E´ V�fГ?a6…¯‡}Œ'`AX9(^q~„“öJ€ ˜‚*PDÇË¡ˆ (‡1XÀ Ö0S4áÝìP[†*RœñÃY¿ø$‘‹¨CMa(Ž.ð&Ô”rN‚8âC颹Hèz h=(T‰*H�0×Þ$äÂÉ!=&ä×buÂåÝ"©·$‰;dbÃÐ@$roÀò.JÕ wÌqg€,\ŽA|�#ébýûŠüêCDØ—= 3}‘�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image4��������������������������������������������������������������0000644�0001750�0001750�00000003704�07504443347�016521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a<�F�Æ��ª¨ÜUMy8JIi{{±ØØÙ»·Ïéé霜¡''&''MÈÈËUToiit:.<§§¨¹¸¸667^\u6( GD=ŒŒŽxxz”””„„†'µ¨’ yפĤ¼–°zÙ¸ñ¼èËèÄ®šh»ƒ 㪠çÍT\F ;;s…eÑ• Õœ sO …Y ºŽD•gwkn¦‹eûûùnYW¬—§Z=Æ‹ ¸•hJ0¡k€hLŽv„I9I������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!þMade with GIMP�!ù �@�,����<�F�@þ€@‚ƒ„…†�†‘’“”‡‹ ‹‹› •¬•,-(#$$)$%$",›+¤ ©­Æƒ+ 5Í5ªÎÌÒš½ ¥ÄªÇ’¡ÌÑÎÍÒã㘘›+ÂÚ«Æ‹áõÏåâøÍüýŒÀ2$–êÝ #*,¡°!¯E ÆÙ«Ç C,16!bÆ… ¨2ˆ€Á<B„8‘#ÇEŒ.N„€±¡—Í^;d°tÂ…‹!Øpà`0 "pY°ÐHU¨ „ iªª©©Ä¤FÕ:ÕjÕ¬M r#Dàf¯„*u䨷þ@ ¸0ÀB6¨–€C/H³5…ÛJ tÊ aâ l¨Öàc„n r° ƒhäÌAÁ_(QÙܽ-*UhröD¿>}z‘€À·Qº«C†ò.” 'î5#P¨°Ùá Ú tÃCB† 7rlÁ!tì §7„°®}v† HÏ<Rª„dÈpAƒ`øÚ×p¡¿ÿÿõÙ—Ÿ}T Aaq³ÊS@,( I 2(–f‘$`Ö"™ °€H™Qx †èÀLéæ!%� à™H—ˆTô‚AR¦ b≅ȥ€! —‹o˜°W/@'Œâþ(ˆ�Àà.%€ÐA¸ƒuQ I3‚Äa’ ˆ5ð•HϤ‰e/+4 ‡J‚èÉVŽfÚtoв¥™&qÏ0Pši¢¬f%+„B ÓLdN4r]ò—¢ðø£Vl÷¼– 5TSÛ"X6L‡’€v,L@§wú *h "ˆ°\/T€QÕÈ'�<iTÞ8,B€ ‚*T àA‹KB4@G£jƒT×vÚE9ëžÊ. «Ý‚™è“°æ&硤â'”{ÝF.Ø@Qüa¡TDpÃð <È� 8¬@ÔÃ3Ìà�FþáÀ§Äà U1t ”ÛPIÅ€)ðÁ—€|óÍ·rʈyõžÊ+·üòUH.êÔ=ímÕcO´Ï9+IÈŠ\øƒF·"ç… 8ð€†9ëÜ4!Z* ‰E_]HŠZß4ê‚Ùè5!)*PJY‹X ]½˜ŠíÙ ZHdü à� �÷"€]ËgÓrQ€%•€ðÁšïýU*)%ž-H^'È‚K-´”`+›¥ ~cÓ¨`/-·ˆ�‚O/Ød-Hƒíp2„� ´ÐB Êg<^ŠÙ^s6ƒ™Ð@ƒ K¹Vž½Üæ¹Õo ‰Aš'“ìò79�ùÜZ8@DþøÄêÌ 7-à¯f$í¶ò@ŠÊTÔ˜U@ºÐW¢?ŸÉª4%!ã?‹ @Ù>g ˜Yáó”þTñ�L`T`ý a!M +\ÉNš˜çQÈ­u“ðÓ÷+ Öc£ZA¯FÖŠ `úР¬•&ÚØ)¬++6A€ $°SÞ™”4°4*Rá†{’°uZEœ&~Jˆ5`@cÔ»~ýN‡“ˆ½òä¯8?LÓªJp+~ ‹N6h€Ü ÓºW”HE¨FƒÖqApŠ È€<Ï9"Ÿt ‹aý§Q�•%Ä�&¶k½°3AÞè…ÜÈoîþµƒED ŒƒÒ�â¨É†Ð�%2È ¶˜óläû³d$3ÊLvK!€O[Þ¡EsqË]0pÀŸa& TcOJ‰ËXk€Ôa‰K$™í  0¨@Ö6±ƒZ6#-èAÔ&öÌË`k4p€ 2‚–È„ ƒÀ Ð� xâaD¡@�€°H32 €ÇÈÉÁ ¦d(K@ @à�?è˜ÄŠ‚Ÿûìg? }(D÷%±Š Dd»$DɨB3úè¢öqÙËR&°ÜÀ¤'-PRöT -h4&« RF ˜]+X© Káó•Ÿ9hOIÅûLT°Ôh%cêTŒJÀJ¼ChOÝÆQE*4¡5Hr`-D ��;������������������������������������������������������������./saods9/htmlwidget/tests/page1/image14�������������������������������������������������������������0000644�0001750�0001750�00000000065�07504443347�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��€��fdÿ�ÿ!þMade with GIMP�,�������D�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image2��������������������������������������������������������������0000644�0001750�0001750�00000000052�07504443347�016510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ð��������!ù����,��������;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image1��������������������������������������������������������������0000644�0001750�0001750�00000021443�07504443347�016516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aÔ<�æ!�ÿÿÿÿÿÌÿÌÿÌÿÿÌÌÿÌÌÌÌ̙̙fÌ™3™Ì̙̙™Ìf™™Ì™™™™™f™™3™ff™f3fÌÌfÌ3f™Ìf™ff™3fff3™Ì3™™3™f3f™33333��™Ì�™™���ÿÿÿÿÿ™ÿÿfÿÿ3ÿÿ�ÿÌÌÿÌ™ÿÌfÿÌ3ÿÌ�ÿ™ÿÿ™Ìÿ™™ÿ™fÿ™3ÿ™�ÿfÿÿfÌÿf™ÿffÿf3ÿf�ÿ3ÿÿ3Ìÿ3™ÿ3fÿ33ÿ3�ÿ�ÿÿ�Ìÿ�™ÿ�fÿ�3ÿ��ÌÿÌÌÿ™ÌÿfÌÿ3Ìÿ�ÌÌfÌÌ3ÌÌ�Ì™ÿÌ™ÌÌ™™Ì™�ÌfÿÌfÌÌf™ÌffÌf3Ìf�Ì3ÿÌ3ÌÌ3™Ì3fÌ33Ì3�Ì�ÿÌ�ÌÌ�™Ì�fÌ�3Ì��™ÿÿ™ÿÌ™ÿ™™ÿf™ÿ3™ÿ�™Ìÿ™Ì3™Ì�™™ÿ™™�™fÿ™fÌ™f™™f�™3ÿ™3Ì™3™™3f™33™3�™�ÿ™�Ì™�™™�f™�3™��fÿÿfÿÌfÿ™fÿf!ÿ NETSCAPE2.0���!ùd�!�,����Ô<��ÿ€�‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´¢·¸ˆ » µ¿ÀŒ¼ ¬Ä¾ÁÊ˯Ãĺ¼ÉÌÔ’× žÎ»Æ«ÈÕáâ¡Ä݇àãê‰éœÜÅÇÒëóô’æ»Ó„íõóûšïÞTùãG°`ƒ{  ˆ ×-w¹R9„±CBåèÈaÀH/fÔø° ÉVx¥äõQ¸Øº€MÛ ˜×’ÑD˜mP˜-q^óY· -}%$4ßOlÆ`òÌ@(4©¼lØ©[>¬*µ}Vôœ"®æ>*‹ÏØ]Gÿ`{téÉ»¡Þ¥ �ÇAûVö$á4‚Dˆ/‘à|l •UÈöžÌ­ÈÚ,ltç}ï'µÈx—XÇ¥Ï,ÍáãâÔ£ñʾôf^ åx|Óœ¾¬„á^»gs2FbÚBcÓ}È8`äžuOÞ®2ÏàŒ¦;ìE]?Ç^z° ÊÜú,ov¶{L¼õ’Víüv÷w3¸N'ÿ¼Jÿp_ëá&HmæõÅÒjh } 釠1· 3Ñk­E „VEÌxçÆÖi…¼Ó�ï$“boÒYxà‡ïÅXI¼ý¦~.¥`‚ˆ$¦a‚5&–ˆ0B¨ŠÄ,Ùÿ޶‘×bݽh ÂcsÍ™#}IJöŸ‚ ò—Œd®Õ¥‡ >§Ún ¾V–w§ÍEg2Õ&f‘è]Р’ºI³`YTÐÀœ÷8Ùäi‚É£¢1¥W!–c*2hzkB¥šæÕÈb7ý!Ú^™ *ÒN§ŠNèmH-x&ŠŸ=c#Úœê©f‹`ˆ¦mò&V«g.9k@ ±Ç©–H&Š‚÷ˆ)UéøP¤‘†*-SÂ^ÖŽ­À­”j˜ÊÕõåŽÐ‹,t¢âV”/E…û ›dfèq‰^£×<úi´¥çE[.Ú,–Åk,¾ÓJkh˾ú€GE9Y@— ë·>½Eqÿ–¦÷š››Âú.“ð> )¹ˆJ0¦Ö<Ÿ¿}\›½W bÁ1†–ÚaXN¦†ñb1»æˆÕ’ îJªÒƒG›öãe¾ú*1°�‹Ô¯SÄ–H,¿@_V*¸…,éjÇ3Óì^múyTôÖ+Ýo˜h{§õ¸…ÔÛõªr%kè.„DÜôªc~mhœåxg%„ãuºb"#vœ ÙUêDÖ¾U‹]æÏRªíO¡wçS˜žèY­cÞpqΖ² “Œ Ósöñ¯?&ĹĮë)XåÂÝC$2«²pœM³yîfÙŒPØ’ßuxnªùCµâ²§µ‘-ñÊv"îó¬ÏôÊ·–ã*$¼o‚'ý©ÿ!oΧe£J=«ÉF^ü{lÅæµË$÷ûüé?]|ë‘LñJºç•Úà°×š½­+RÖAÝT¼d!÷1PXcÒ`”Ç“ÑLê(0#Þû6ø A]@?`œ\äôA jbP{Ú„õ¡°„ra!%<H¢GÐPƒ$la#œÆÁãl>ì! ½1¿ñˆ±8ß§¾õ-ñ‰ªˆ™˜šNñŠy1"§u°^˜p‹` £G8’1šñŒhL£×ÈÆ6ºñpŒ£çHÇ:ÚñŽxÌ£÷ÈÇ>úñ€ ¤ IÈBòˆL¤"ÉÈF:ò‘Œ¤$'IÉJZò’˜Ì¤&7ÉÉNzò6“  ¥(GIÊRšò”¨L¥*WÉÊVºò•°Œ¥,gIËZÚò–¸Ì¥.wÉË^úò—À ¦0‡)‹@��!ù´�!�,°��ã�'��ÿ€ ‚ !†‡ˆ‰Š‹ŒŽ‘’‹ƒ “˜™š›œ•—œ ¡¢£!ž¤§¨¨¦©!®Ÿ¬š¯° ·Š«±»¼Žº§•½“Áƒ’‰¿Ã̼ˣłÍÑ ÇɈÏÓÛ£Ú¡ÕÜà‘ÈÆÊƒ´áêè¬ãëˆï•Öç‚éðù‘Þ òùþâ°⧯ =KîþSÐ\¶v#6Òå ÃLøUd#Ã_m2d¢‘PrL·Šá,Z/ ¹òôÊQÌV5>›‰®æJš[:Ô™3å,™E£™¬¶”žÊVÕ–jG¯ÞÀ¤í¢Ò³IÕ)¥ªRq‚•Ft¬!SU™¥&,ê'·_ÿÓŠ s¬5O`iÌj×jYž[Ê»v®Ý³èòæ¢Ë6±W­~‘–<¹/äÁSïÅã{¸aß“–)ƒõعïPйš¾\×®ÞÏ¢«^öŠXó!¥¨1}öìÈ·a›¶]›±êá©‹þ]9sâ{5ÿ>î:øêÜwÎÌõ«ì¤‘Ë~Ø3»ìÀn™ÊÖÚ;,á·L}†wœ“il™ñŸÞÎÿ 9,Šmæ]´¡fmà#š€Q‘Gw­…ÕQYR5¨œ€N¨ÝbÙWÜA&åÖÞƒæeЇÁ‡%Ñ!ˆq‚6T‰Äy·`$�ý²Š?Éîá†âm*ªõ¢‹5âvcÿcA&3$„K¦ô‘‰õuúõŽBàX׃ fÙß‘°Äˆa„Í-³c€†ÙÞ[@æ^›QŽÃŸœØe´ž›oy`™lÊØ¤9�)iæÀµçp!Ê㨓â)×bjB¤(¢’(yc¡UžæY¢dÆfÜ|Y–ŠÝZÝÍ6fP¶J ž†‡f”¯Òú)‡ƒVè–˜öúY¿-ÊX¥Hæ +˜ÇÍj  ÂG*ŸWž:Þ­½n©¤º˜æªŸ—Ú*«©œÚv¨­ÝþÚ¨@z­´`ZF¬TÝ.ˤ²áê+…¸F(lˆ¼Ö é½Ú¨ê¤«[­”Iþ‹l«ãÊÛçŸÞâˆîÄêL¡ÿ• éa¼ kºì“kZlªƒúF̤–KÐÅ%áu¤U Öè™#l²  &,®7ç•.‰V©ß‰_ ¤U(vüòˆ#+íi¼Ú̉óÈò‚·N+R…R�æ´žÀ+×Z-ŠÙ=9K¡*×ZÏ`þŒ´ÕÒ鬫.÷—¨Óæ6S²M;u·ÞÁPgIàÛjªÕw¬N}ð;‡vI~5àpYŽzß3Šh —.óuÔú;ãuÏa»•æ›'ÇçK§÷vm/»‰Sívåã9gzW°9XžÜ¬/Xx#yÚ#æïâ ‘®íîdŽ{´É; ñÁÒê©Û—æÌN»ñ(û<¥Cq½³ ß,<;yÔô⬟|©·lõÅ͹üñScÿMïëw8Ή˘Mø…¿êIWr@Y,pö;Éû—ˆ@��!ù´�!�,��’9��ÿ€�‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûô þ qøÇaÑ@ø¢@;†ùƒ( A‹ :dGQ⯎�‚H˜H$É^ ÿm\Ò#/&/" V æJ–ÿ"ºŒeóæ ˜Kµ¹¨'&£›†"*K© 5‹2u45‘SCW“5àÀõ$€ ]ÚÊU'€Ž4 �èLE1ÿÓô)¬Ú 7 tåà-³v!Òź7¯\†­.D–ëX‘Ù6>©·ëʽbýz=Ôàp΂={ݪ62ã½�Hÿ‹Õ³¿ ¬¡U›xYJ7[ŠÔé1!·#eŽ„¬’ÐíÒ bïŒñxéØˆŽ¯ì­1QËA©#œÎÐxõ§9= /1ò“ÚßÖ…ˆúWäÿ¥ßll÷ j¯^O+HàôBr:9çßwÎùf qƒ "ý‰Ôà{êÅk®¨žx~×| ÀbpŽ˜œ|Þ…¢‰è™áp±eÌa$¹ÆÚq²yèh9UTá!160[v=æXd‚Vàÿu…<ˆÝkÆ¥5ár+’xœNøÉ¡‘¸ýb"Y"tcZå 6$”‚t–W~/r d˜]Zx¡l¤É'…wƒ#x) ¡YT–$ U!d\6D‰ºi“â`¢<¢ ‰}‚`º%„ mꤠ=jh¡²Ö’oŠl¹éŽ/Ò%–Ÿî§Œ„©åß“'⺗†ƒ ªSL"VÈ!œ»"j§¢c!¶kwV}GÜ_B6'¥™y_užzÈ$"Ûzi©®MvÆ«?U†kœÀaWÝã§\xǬ #F p-Þš›Ÿ¾8¢"NÎ7¡·'Âêk“ØÎ{ìJízWœuÖ‚K(|å:gÿ»&F|L˜íwP¼ê)[,W¦Z›."'s(ÚÈŽ-\ÈÊ,¬ãˆK*(Ã?˜íÃ3Ò¯!ºõl`ä¾h1²¯[¬{Ç\¨od²ö¬È½Á’:¬ÂÑEZë­’ôëE9]áup:´ó Ÿ›+· glª*ìdÒßJC#šóÌè!8[z²ºÂ2(VÔÍ´l2?ìSÄ22àÚ6/Ê,«…K½ªMòÙkµo¥<ïÙÈnê`ä„3§?±‘—¬ÆµVºù߆xÎ5d‹·ü3®È:ØrÖ䦊œ^ôµQ_™fGgæžv¹€¶tçAái®ôGoDìJ³m]wëÍ”&ùuÄ] þÿa®ÿ=àVÏ{ú_â”Ðíëï~âGÖþœa«XHŒâ«µ’¥éÛæAž•é[ÀÍý>'7=KCœ Oÿò” ѬŽgCNù5©ækxÚƒÏû´v¼upnõr„k袗Açq´#˜Œš¢X�4õÔv“ÇÍÎD5ÆÛ ¹—ù/š3ßb=Ñ%17"¡l´ã&ú…N„‡CDãA¾0Q0ÚbÀ´S2…6É«6ù1ˆÛ`Üø¢Õ”ñáŽÑ±cT*!GñÑñC£§äÇQôñ”è ?ÑÇEbE‘°ÁãNΡÃIZò’j›!&7ÉÊqò;“ü8NAIÊRšò”¨L¥*WÉÊVºò•°Œ¥,gIËZÚò–¸Ì¥.wÉË^úò—À ¦0‡IÌbó˜×�!ùP�!�, ��½:��ÿ€�‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œ�M ¤¥¦§¨©ª«¬­®˜¢¡ ¯·¸¹º»¼½¾¤±¢Ÿµ ¿ÉÊËÌÍÎÏ„µ Å×ÐÝÞßàáâƒ×ÚŵÅãïðñòó˜åØ çííÈôþÿ�~+ÐŽC- @ì+7J Ã‡#ª*wŽ`BçÎÙëîS5 8JI²$%‚Å:ˆB¢C±|ölRÀÀ‚›rŠ4ɳ§OA ^¸XÐ`vv6£©�gN ,,øIµêÈ¢ùê3Ç¡ÂÂnŸšæUj�«hÓÒC™¯mÂ}æÿÚes÷ìÓ²d-HUË·o¸ ù:(„«iÒºw£â-ËͯãÇË^vp»µ(Ü†Ì ˆ µ¬C‹ÖÅv2B—p¹V8ê�g6{ž:º¶í‰æLçKýò\¶l¯IøD ñã X`óS½zA+^�¹òÛØ³'BšŽ÷>ßè¼v`\‚ èÓ«— ”½žõVhŒ¨zóêÑKH ½ö`¢$ Šw\¡sW˜eRÜy4èàƒbÀr‡hß´'yøA!ø'¢h�Šbo»±ã•†“pèá6øÁ(’@TÀ¢ Õ1#„ð7â}™ Š6¢x•ÿº…wÁYš „3þ(ã,j¦t‰,heŒIä˜VY£Î€ µÕÖKÅì Ì(§œVÎHÁ!h–Á–ÓÝ÷%˜„Hæ ?Õb"š €š¡#‹›Ž$çúùøãŒC’g d°§bââ‹t‚y'¡¨šT⑉Àèš Xƒ}–Ф…`Pg˜ƒ|"§žÎXc…’R)gU‚jªÌ>Ä‘‰�\ó*:ÃÀ%Ó&pÆ”—òêÉ}èU9㲃øI¥„Ê™ûâ°Í¶+Ñ0öìF-�CŒ:˜W¸_z+¥®Έ"ä0;Yð©î6ìAGZ{ AsÉeLÿ%C,xzzÀ+æ«á¿T’ €ÂìðÊÿ d¢aÚdˆÍM`�x >¡ÁÃx)êÌ®! óì±ÉA{œËLϱ¡0Çz6äé�“®cB$ü>HizV&�2·SX!Ê Mv„M·ýÎÓ;zè1yBÒ>@:HqFS:!�LjAÈJ0ÀáÙ0Ù¢LãÙªìöäÉ ÓD!«šèh̘`€aàÝ£wÒ”îÔu„GnÞê¬ï‡vÚfÀ7•CSn{.'Çc¬“ïtÇÒZk3_–á"¤3¼w±£žÀ©Ç¸Ÿâå½hòíØ«ÀBÔªƒ”WÜSµÿ𿯓š6ìC0óî4{óð9x‡T.ýý¯S±oÓXŒN65a’Ìw™æ0‡`߃$ĸô(~/‚àŸÆ…¿ ºÂDJÂkÒç»ò.±Kù24 �$ÀJó£Ÿ=öµ^ªvŒ¡)Ò;¤ÄdnI’›ïRs ¼QŸ�œÑ>4ÄøùÍW`2â( (:q†…yÙoVó›#¡ï7„1ˆ�å’¨ú‘J[a¨Ø /zÍoM|¢;ÑÎ̓¿©Øw8`V9�J‡�ƒ`4§*e�l—ŠQ¨¤ä5 ‡2b! )Åž5:mtãˤˆÅ9V¦v›FÎ Ñ# P�ÿžÜOr>‘4©°A0Û¶¼&$‚Ë“ 4ŽÞIËIèïP³¢2ÈyacxìÐÛp 8C”’RE‹œØNçÉ‚:Hc-§É‰©Íe@9Œ#/—dŒ8^c“‘\ÉN6Dô|²o†£¦:WcðFŽrD‘£tÈL¬BP}&¿ë­óŸõЈw*vÀó P‡×¢Äû¶dˆSF ÔÃ(H€Zt(16ú?)Êå¸g7°S=´A%ýÄ'é¡|Îò¢0MÄ7OtšÃn:ÞK»Ä ’úD*K*ªOR‰¨1Mª$Õ›ïH7à;Ôoðh Iùô$ÿeâ éŸn€\ø¤WI T¥š•±°E0R¹½ó´²DHŠÕ’Š\õ*¹øVW¯J󬀯Ä(ÒÉDÒ­êTwºˆê8ö¯‡«òA�``¬%ýk`kš¤—gÂ!hßÈXKDv¬ àHq(@V¯Nv³›%a¼>+I †öP­8­d`°³`�l›'ˆ/&k²WmՊü±b�¾nI=ù[àÆn¸I…—L³o2·¶Òˆ¡¥RT0@ºèÕ+va«¹¸¨ã»à•Kè(ÉÒBb®é•.ì»^Z~ó€ñ­-“˜ÔôÍ¿+uL]×RÀŸý…)LA*£\6A¥ @¬Ä›!ªªâº[%€ˆ5a³Nø°n¬Z… ȦŠu±Ä0öʼn•{áHœèŠàŒ±Ž] òN‚MØ8ÞŽ‡ì´šLÌ��!ùP�!�,b���$��ÿ€!‚ƒ„ƒ Š …Ž‘’“”•–—˜‰ Š ™¤¥¦§¨”ž … š©´µ¶§° ®¼ƒ À·ÄÅÆ«¢”Š…¾ ²ÆÐѨ«»¦Í£ÒÙÚ“«Ï§ºÛáâ„°ãçèÖàéì퓵 ؇ÜÞÌ Œ•ˆ‹Ø!›ÃhmêG¨@À^‚`Ù;ÕŒW'I¾þ£¦h&dº@9¤ÐÑÆGqÊÊœ _“r…€‡éP"(W‚´Ê_ˆrÀÊ=Bva(B5ƒÔíU,«x•ªUÐH.5†2yr¦ UPŸ†$T³ (‰!°z"f¡¤\ôÅ«aÖ™[ÿ5Iz!Õ²Vo&Û b˜NG[©¼šW¦Ñ…~&lÚ«ï ¥ 7v}«‹0Äx aÖ¼Ðì!©ÞFKØg¾» OÖäxlkGŒYBÌhaʼn_‡U‹(ÔÑ‚ƒF›Z^aA²ÿAÔMµÕä˜MØfÜfsóÙìÅÏwAÄË|ù‹ r¤ÙªÛCB¿´×õ÷…¸S/êy©@IË› Gú1¡õBñÔJ~ý•–RíE‡Zfÿ‹MÄÕW„Ç­Cštüµ[‚ÿ膇‘W‰x·YÔ!DN'Ûí–ÛIÞÔf˜#öm–ÚA*q„™Ê€•¢^ϬÆß‚iaƒ“s/Â2Lÿ2û1s^ƒƒ}%Ü0¤Y²Ì#?2H–/DÓšNþ˜Ô•ÉßÁiDuO5IIÁeYS„šu©W[<ê•Ïq q¨¤d2ó•‡^Ê"⃔äƒ+6‡åq:zƒ¡ ’× ¤eA§$‚ÉHã/têØ¢P%-ʨm„~¸deÙTc5.NÇcI"-”£x*’3déˆ+0Å’Ò“»ÙyPø€˜+'¸¦Uâ`¬"÷Ìg•}·è¥£>6W(ô ëwÙþ³m·iùF®—eY`¾9³*‡g« "u™j ½­DB¯©ke«á&ú@å­;,\¸'lK”©*ì0-¡rùðÄÄlZ$Åׂ˜wLJ7.õêñÈ•`”'É(Ob%��!ù´�!�,��:���ý€!‚ƒ!† „‰Š‹ŒŽ„†‚”•–’ “—›œŠ ¡¡¢¦– ˆ§¬  ­±žµ ‘!¥”šƒ¾¡ †µ«ª!Ä¥ «’µ! ăŸ¼Ò¡™Š¤·¤¾¶Ÿˆ©“ÝØÍ¯©‹Ü‹ÎÊÈ·å´ãØœ¹‰ÄÀ‚Ý„¤‚Tñ2díÞ&ð08W"m©x)ÓVHâ%Š„R% 1Ú½W¾BÈIÚ»Žº`I2˜¤BM¶VíÒÔ@Ó……b‚iQeÎ_°jrLV-X´Úá<w ^3HÎ4 ˆ¨è+l»ñ˸µ?p¿Êu•u*+Ù³þÎ’«VT �!ùú�!�, ��½:��ÿ€�‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­ª ° �°³ ®½¾¿ÀÁÂú ÇʲÍËǼÄÓÔÕÖר–ÊÐɵ´ ¼¹ÈÉÊÙçèéêë§Û´¼º�ÊîÈáãÎÒìþÿ�þ»p �‚‚€¨%k–1eÌ œH±¢EVÊlíbx ÄAÈäÁ ·±Á­zSª\ÉÒÁ’éò˜ÑHƒöqpçŒ[¿–@ƒ ø’IýLê‹Yë–G] 7Þü9´ªÕ«Á¢Ö<À]³†´º*”õ±ëFf=b]˶í©e°ÿ@"5F0cÁ\ÉîÙª,¼“8Ý LXƒ|¹Ü)äҦ؆(ŤåL2I§e kÞ\xæSg²âmzpgWÅ]AÇËgò›,ªœc˪0<Ž<M“=H‹à<§ÛôBh{ÒÙÈ“¯ô¶4î=Ÿ1qÆ¥‰Ó¸¬„°D;MöZ¹÷ïDqœ¬ 5=ñH—“†O9î~>O¿>¶Ï3yÞeΓý˜Ó•e»'VDö%¨ 0·xuÐB’9eÚKÚÉN>ô<·Œd·Qµ l †(b(­Ý†Ï1½U¶TW¦±XOLm³ŒZQ)V`X#æ¨c'ÇÝŸ7ÆI£PXðÜãchz‰SPÿ-xqÇ ˆ;F)å#³sa<ƒLxË_Õ9£O<Ä©u‹j!ƒã”h¦iÏš^y$ãd^ÁK9`Åi£|;ÕxRv¸ø¸›€*è „j(›i&ú‹|Œ6êè£F*餔Vj饒*ªi+nêé§ ~ŠL¤–jꩨ¦ªêª¬žú@n*ë)b „ ¸æªë®¼öêë¯Àò ë¬Ä–Rk@·«ì²Ì;l±Ð‚r,Q 4kíµË>í¶›L;PµØ†+n®Úrk®%Þú“ì¸ìZ[î¹ðF"¦=‡Ð+ ”¡à;Ⱥ»"aÀ¿HàzÀíòJðÀÁ¾ïŒЈ'7xšää#ú*R[ÿƒ‹ð‹«‡ÀqÁºr<Á¿*Ìðɇ”éLZ+;KZ™-²¤$÷X™1¸¹ V©ôó�ȸ>à€‚ì«É('-ˆÊ8n¹ïq©Å¬Èn•˜y³®&tÁ?¿8?ÀÖM�`t¯H+²ÊýXÔ0:’Ë%C^-° ¤îш²ÙÎÆªöàl?cÝQ›UÙ…3Hãî-~HÝP½,ÕºY7A¯�¯Hè,ˆ goLé»rLpÖ&´@�§=øÂ…Ëuø,’yä€9m—™ï»lHÝ,¯'W®‚8àkç�„m:�M4P6�`-–ã€çª:ÿJf@± >{ÿÒ4¶ø ŽÛÜ;šYÞääcÌMâþ¶ùo‡õf!Éü¯Cëª?�[{Ã" 3’q¬�|Ñ�ð7‚½Z ®d7¾s¥Ëm†ˆ‰ü²µœLKƒg¢Gëç"Øä�pžÀ €„9Àcã…6‡«7ТzÀ ÇÆ £mOÜáØÄWA†]pƒ…ˆŽ!0˜;©iqHd-0¶Dpéϼ]s�åéŠhX¢ ¹G=íuˆ#‹¸­#†ÐƒR;_?Ø>B îq4©#þ¬X´] aið€CˆÎø_!D‡C2ŠìsÂ""áåFDÄ­wlâcÇ(ŽeÿFq|PÐú¨«�~ €,$õþÅÊèͰlh+ÿåJ3RŒ‘œäÚBÉDB\²“!üeî8‰ÇÖF?QåØÑÈ,6o”&PÕÏôg€žÊ‹¦3ÀÖxÑÌ!êòd•¬—·z)ÌÔ“„ÀÌÝ•ù�Z@Ò`‚óz�,²o»¢¦½HÀìMP’ßlc(g–Aoe2q¾Ô#:‹‰Çs®ë”ÝÄUÖž‰€p¬›å¡?q%C3’,|§7¯c))/“ç´j³ÉáM 1ƒépp¶·Ñ-t2Z²ÖHŽEW X6wÈ‹&äÊ¢eü'IKš™÷4J_1^Tí²ª2J?UÖ]ÆT/Üñ ¤ š?÷& Ñ!\ D¡d6'2B@‘#[ãR5U«šäÑ� Šðʘ½F¯–£ ]ú À–?~= Î&¸7}`†$d)÷ö½Çæ\ÐGfص?’Bs�>û*€ÎuVéb‡Æ{ª òÊk¥B[k1kªŸ¡j¤§(EVë7±É5·hJí:xÛ[ý¸R®:ˆ[Üv¹;êT¨¦KÝ鎪UØÍ®vWUZèB Sà ¯xÇKÞòšÖ»èM¯z×ËÞöº÷½ð/!�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image11�������������������������������������������������������������0000644�0001750�0001750�00000002621�07504443347�016574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aK�7�„�� š‡’?6WHBÌÊÈL*'vha̤ pH8†k`¶§œ1)&ýýûn8)nYO«™çdoȯ£¼@Dót“QE%êØØÂRQü•˜‹xnû°´º¸¶_TOÙ×ÕH94���!þMade with GIMP�!ù ��,����K�7�@þà'Ždiž¦Õ)ÏdÏFXhm߸h=…PŽ cà‰žäb¹¨8ŸÎA'G­Y"Ac»E8HDAÉ®W&ãð,¡σV=u8¡Ó±h4>  CD -n–npSu" 7ML 0hN«BMµztU3ž"nÀ`d,/Œ–H¹O2½Ã: 3t L¨ªoqIJªpä èLÀ 2}Õ7³˜Pëýrö� àÒ—‚‰ÕÊA3#nÊÁq0 `‰YHØH¡£A`®ÉÐ Q«EGþðp ’iAaÕÈyÑ‚…ZÄéd·$‰«W,2©äà´ Ò*æ°°’æbïzÂháÍa3tð°ÔÄ+ N=mpÕ¡H’ŒpeªõõÁ<{¨áP�€Ý»xóêÝ»7ÓÝ |÷2‰`'‹(:ð@r®ñ9V ä"¶È#‚#Iˆ ^ îÉ“«àÀ²A§‹R:kÌûàx Ç‚\À0#†ªBfC”¬Ý$9´…Œhi€À¬Â‘k’Q]ÓpÖQ'r”Ú³ A€ @˜p¡d±%°Ô*�ÂXÆŠ¶»®iÀ;èõòˆ|ò-:‰ó2¯ÄBQA¬þ”J‡UcÀ&õØ@@ŽÃÄ�k¼×Â2,±šj´x–Ô0Tð@„6(�M.=9§€Ë(¢OV+…Xz èËW´Õ¡‚IpàÊB0¶†kH@”Š4=ÚJX>N"$z/²à‚"t˜‰ßA)Ú`7 o ÃhM|µHZçHÄ8•¨G qQA@š5Òw *pöf- ¸ãÄ]© ÏÐYÑ�˜ŸžýYKgM<Ê8•Úƒvµ)ö c™´Am¤ê �(ê&¥Ä]#Ϭ¸ ?o,@«žDHQDê 7*®(pA�†œÖÊJGxÁA3›É­Äþ–ÐseëEDGRÍäÉ™KÕ’pn5·Ð† 0ÉC¹É`¹#Ü–[¶`ð‹‘i Õ†¼¡ˆ9Ù t´\ ñ›/o,£±=áA�œ"Ær+Ç2!½°¦CQgÉÈš©3bm @lTžG¥…„¥xÃ$AjFßLûb�ÙÀõG ƒâÇ/$äšC$1‰-YÊ „ˆÀŠ~: ]´�µà9!”##ë3« VcÁƒ9^ô‡äå 8=q[ÒüŸNp¶'x@5L¨…†zø“Øh@œU‚[Õr2à¶zYÂ:aO"®¸õœþ¹|8ÄQ.ým'=‹°)aºDiS™¡�Ö¡’ äa9) lºê!JÄ CG»1q_˜Ž;r°ûEÞ<hKS½x%$ª„œºÿžÕÜ(† Uy¥"ò¹#8LºjÄófÀŽT6Üï"Áe‚#ü6P(!€I²®ó¡„3ذƒBQ±š˜`da">¦ ?yè@È‘÷>€ÊIæGŠƒ>Œ� `4¤d’òŒ8¤6±·ð¡gkã’Ìô4rìÄuKÈK?6CŽõõ03¬ “˜~a—'ÑQ�ÀÔ ,•—7¹¡‰‘Š˜µ± ‘‰X„"Ef*2�;���������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image12�������������������������������������������������������������0000644�0001750�0001750�00000004644�07504443347�016604� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aP�F�¥��ççæ°°®Ž‡ˆ…vusddb||y—˜•ÉÈÈÏÏÎmmkFDB$"" 1,)MLK··µŸ žUTS><;840þþü]\Z¿À½"¨¨¦ÙÙÙààà‚~~‚|ððñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þMade with GIMP�!ù � �,����P�F�@þ@pH,ȤrÉ$2–¨%ˆ€ªÔˆÔ¢`€¨ îÖò +„Šóðp1,2j¢¡P6W¨4{µÓhg [BU zQ_^�UR C G MD € �—B§�h‡¥B  ÎiÓttCiµ_²Ü©Þ²B�i~CêÆÇ³óâÎëþÿÿˆ�Ø€ ž<z5H€çÎ]< "΂؞ŋáEÜh/aG„ ëa0Â!A :((p¡Ú;0Èà fƒ›8˜È±çþÇ�8�J”A|èq< `@H&À@BJ&¼¬ 3ÍšrBXÖÌ_‡í*jÀ‡áäÂhv˜;W³çp)P[¦/íhZ@ØÚ„Ç—u°ËïY^½©Vµz%a‚ŸX³¸)¸"”, °�ŠëÁ¢aq:`P©!ªX¹Rùq·oB(xÎèTæ`ù~¥M€âàTXPÁé!°.x}›VîÝEP’@a‹‚ ˆ¬L°…h0’ìa�nN ¬�À `ß„úH³’eK \€Á+ä±]h!E‘À>ÎpVZï¬å mù—1þLãá‡"_”hb‰C1A\,¶ˆVx aC4ÖèÐE4Âó9&-tŒ@! d†)}Ç\L21 $<4Ñ“PN€`@eXf™ÀnA4ËxQ’,ºiÅÕL_Ù”Óš7@×YñD’8Þ @•Tbž 1åcý@Æ×SVÕPp&„FGbd•åZî¼øf]:Ù¦¥l AV/5êèýØÆé©¨î@SXp€ˆ¨RÈ-‰,²…# J¢ •\¢Ýs @sB[@!RÜy^Š'…y¹Z²^-¿qÁ›9 l,PþtÖÝ‚Ó&2Äh À™l”YÚgšqæÙ,E´'Q@}£lÚí&‚Å$ z†åÅ¡Ü&d�Uv¼,°N¬u±È!'„8Ö oÇùFNpñWÄ (ÖM¡e�0,Íëa5.PÀ‚0…³¶J+JlL\ 0AW°¶ÀNOò"á>û|ëõ×# ±ÝºQ|WmyçyQÄ)ýHHé;ù’Bºñg÷Ýv‡™jÈh@ŒsÅèDõt¤Œs¹˜¸‹,žE¡U¶E'=ø ÀœhbÙØÔ7Z%D >Qع$PÕàkQY¥¡ìçŸþ׈—‘è¦[¸§žlaè;ï0u�꩚£ŸÐ€zfš`9€5”>õÀå˜Wo=¡TTú—z“³(P@‹zÕ|jl6 @Ü…�|ð_SåÙH>þéÌc†¯Àä£ÚùÒ×€è´mBP#ð¹ÝuÉOrYÌ:À›%ÐÏ/Á‹Ýÿ�´<æQàQßšFYþ–8‡�©O5»¦ø!€î¥jPUZ]òª1Á˜Ë†™@ÓðŒ7M…Û›^†bÌEà\‚Õ !˜Æ@�A¢§HÅ*êå `€j˜ªØ.¡«xQ��QHÀ-qfñfB€ãþ >Ntb,Yl͇F¥‘Ñ]qdÄ,Ñ]yç`UyÑ­!`€Žˆ™DÁœ€)BT¸ AŸ„Õ¢ •ØÀ†- Øj¤°B€7<0—¢FÒÉmQëh´��ΘŠD”C P¿ )Øë’$a&МWr`,uxq¢°ËZ”ÑŠœšXs†f„b´’:¸£û؈?ZA¹Tã²Úx´ ‚À_œà  �—‚A¦[I‹B& ɰ²!Ò Š¼V'Æ µe'Ø.ºUK}²§¡”VƒL9l á=k€±�€ d¬�ûø×.#ˆS ÓÔ%/ËþøË(sÄ4f^"ùž°4éE Àp³~ðÇCÿ Õ° L 2k�jVŸ °F&¦‰ÆJZò:€ãã%ЙÆ5t N«™SЉ` ƒ…å¨ÂSa5ã;µ;ŒB‘ÏAfá Zæ4S·Q¨âcƽô¤”8%v³ûš×ˆˆ†ÚµŸ£Ì«)ôÓI¥å"ò(O¬Ò”þàMÌP€±ä˜Òj˜Âü*,ø1¡Š8É?ñÆ„åÄÚÖ–¨C@�@nt„àCÿˆ@„+¡ Í·BXQ\è²\¿1†Œ‹®(NØEK®³õ„Ž"ÐÇsbuÜn‡þ»·`v!ˆ_ÜW¸íÉiOÙÒªBw»9éIÑ#]ô4�+*N÷ГAಘ×ä-ïDt4'q4˜N“ ^^J²ºc´.K1 ¢#E£Yӑ釧ßa(¾C¢ÊB&Ò½¨Xx„CˆUTb&ª™¯&MqOxÒ¾+iéÇ[: G¾t€(ªWM)°ÏZò6'Ï‹’œ´ç1ͨP÷HŠA<€(‚€~Ñ0�·4=9}Ï“›R:²'¢È/‘ó–•b›]µ�èQ™Ždæ3° 5Ff’å ±~öspðü(#¸8|Ês2Xþ\Àâ²èGö€ð‰ͧ·/%ùÏ8ýT\Ÿ ©+\Ó"ø¡ŽÖVH~KÁÅÐP 5ö`‡¨�öyÒ Ða¤üaÙÐI�C« Ÿ«î6†¤ž!™Í¬‰.C„»t<j½ìLÍFŠ„Ý~Ƭ(Q቉aY,õ&¿±ºdDÔTê—}l&‰KD7bFzëL9c�ýE®£¯«'t؆ŽÒ·ýíŒf üT�ÐÀ:¬Ä%ðø ÅÙªN�Þ{ �;��������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image7��������������������������������������������������������������0000644�0001750�0001750�00000003746�07504443347�016532� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aW�@�¥��"."+<*???4J2>X;KKJRUQ__^LkHYwUfkapxnj„h|“zƒzjÿ�ÿ™€Vk„„‚Ž‘˜—’¢Ž¤¨£©±ª®¼­¹¸´ÂžËÏÊÚÝÛêìëúúûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù���,����W�@��þÀpH,Ȥr¹„8ŸP!G"‰X­ìãÊíz¿Zíw<G¨íTÉ𸼜w%^ÏvÛÿ€ry|O^ ‘’“”–Ž–‘˜›žŸ‘ ]†‡NoW�ޱ –³•’”¹œ›±š\§{«­• ÎνÑÒŽÏÐ ÏÓÚÍÕÝš W…z\ÔÝÐÓ ÑðõÛ±õ úÕ •[W&PfÌ—`åËFÏÚÂ} çq{q_ƒ‹üžAueÁƒÅòpA `bÄX2D¬†qe·‹Yö+î Ñq `À¤þÅz NuÀà’ėúZ.|”€‹›*„ÜY€¢Å£Ð6pp€hQØàae«=XNx¬€¡—’õÌ*pp1ƒ±ðpÈ`Ñ‚t5¸àL¹Þqð”AÎoM†Õì`,4°€ªÃ†2x°«T&VÅWC5ù Ü¢‚·mЖ†Í2XÀÐáB†ÜtK †é­Àbj£»ò`@UØ |Ãæš³ÎK•ú,¼l÷GÇ x •óWó½kàá.<És»nØpݳV‚šÅFÜ45òñl™wEBï¬Tˆ\:³[m¦GoÕ¹gqg-6€xä•bE�þ¸“`=èaŠÔ|èÌ|Zqpa˜åVJ~1]•Ñ{Æ¥¦Z†žÑ¡‰bað] Uã@˜‚ÁøÜ|Áíç]…6bàN—F½Ôcän{!iÁošYpÊH¸‚5Z1ÀSX¥Lb]0"ÎxF—ó!y _úXPˆ!î™Oš¬ùŽbàáJÍðöe&RCš>]…èÁmûV‘“êY(¥†X¼BgzÑí“|øäÓY‚Å%h§þ:%@¢FXz lÀjb°Å´§ j(€ ZAàCL>£"t.l¤Â^HlŽ×o²ÍeØ<Ü…ê¯ÝuÛÊZlþ¢rƒÑº>>“$CÞ&˜åpÐùãé´TM$hLHÞ5ï{%Yâ¿ÌB­¹Ôî8ÜaÝ0 GeZY§{ìA, ] aÁšD�а8æk…Ï ¹Áù©7Ô`Dþ敟ytP0CãëšBÞUÚ¨ Œš]~Z Àv´‡ÔI€ð[8—õ’¯C3Úa¾í³"o*=„˜D5‡|³O%ûÕàŠh ØÙe³²3¡]0ËMœ' pÜÒ®-Úh{¨Ñ÷! bÍÔ”Ò׌^nL÷RäÚˆ·”ôa)¦T^9*•ÏgMnûøé6ÛóöÁÌÙ4®¦Ò6Cž®~01Ѐë¯{–þ3p—ÁgF!N:4v{Ü›ç°úÈ-5Cò{ Y¶mf™¼õJ“Üz;&Hr3˜%‹|ò™¥±ÄfV·»3Ñ;>}õ³'ÅPüµIY’‰¤zd†ruB?Qù§?Ný›VY$Ò l4Äx~9hNѾãÕ‹…^Âô6·~8Œ4ÛXŠ#63¾l@1þ«^ÔbQC4@KU fºâC̈À¾ ` qV5Ñ»þM¯°H@úâ! |FÙ¸¡=HçJ”ë‡éº‡ñ)iôC‰�“Œ YØBNo1”"gnwD+ñŒ9ÌiD€ÜËkT`À+þ‚È m„(Ðo(E$ÚÃ�F¬¦õ L rèã;Ù )ÂBkŒÇ%j"C}j g8ƒ„w‹O0r¶ÈÁzA� à °äZŠ¡§/rŠÊE)#'ËY–ą-o)€�¼’–”ˆ¥.gyÊ+P@•0Ç)’ —¿„¥/#çKá��×€6£9ËiN“𨬦8Ç)Î^Ї 8À°Ìb|À uæIÏzÚ“ º§>÷‰Otž!T˜ÀšT㘠âµ»À*â)ßu ‚s º¡ ,` ÈYK):€ÐÀm ¡ é0Pƈ‡í<ý<þƒ L`8€Ò PÒšÚÔP7Í©NwªÓ™ŠG£èX)4p <�¦1•éL—ÊÔ¦:õ©P*TðÓ(3*Q)00` «XÇJÖ²šõ¬h5+#P c<¡†*9¸šØõ®¸+òª×¾úõ¯€ l`³ rœ#Nèh\5p¤ T€¬d'KÙÊZö²˜­¬c¯¬FáAD*1º"Œ®öj+*íi”ÚÖºöµ°­0fkZbl _àâj9ÍǿՊo‡›½á÷¸È=n‘L ÜæV· íŒt§KÝêZ÷ºØ•î1Øð\èöí»à ¯xÇK Þò†÷Ü…@��;��������������������������./saods9/htmlwidget/tests/page1/image8��������������������������������������������������������������0000644�0001750�0001750�00000002242�07504443347�016521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aI�;�Äÿ���óÕ¦¡žœid`g:ÎÌË0 ‰['Ú·}¤z@õΉèçæùäÃÀ›_853ì¸UÞŸ1ÀÀÀõíß ������������������������������!ù���,����I�;�@ÿ`$Ždi.E±˜lë¾p\ô:¢Â@„3üƒÄc¨0ŽÅI…˜4¨Z«Å�b‹H$x`L Ëx@Y%¤ñD§’«UÁßÒ»=be…†�IKLha;‘a-G X} _`a‡¢£�44)6739‘‚P" šI tN”¤½‡¦ª"˜š4,¦b¦&3:¡¾Ðc>v-8@¦wS0(¬4צ§vÂÚäå%*³9»<;ëÔæðxµW~^”>a‚ššJp™IÚ0ú‚®\=Vð¹…‹;B½ l”€Ï¢\ÊÆµ@²‡aC/_vñŠvè@ƒ-!ÃÿDò(u< AkžGO Hú–ÜŒT4Shéô¢ÎQ> ŽÀTDï‚­ÖÌÁQ2¦)ÇõE”OPu+ãÇ;kíT:h÷¤@ž…þæ$ˆJV›„»w­Å`KÑFúÅm’`€ÆxL÷lbèpd™ºÔjóÉD:PÇ@رÈÇ”F @)­Eoäf—³-.(] =j"“4ÚxJPF&ŒÄl`+Ì𶝠k°¸Iˆ¸‚€i¼a®¢W ©}®Ûæ^Ò¬¾CÌ&—딌g/5s ŽV@¬ •P\é׋’ÙsÊŒ�®´'B áY êé‡Mÿ Ä4Å3ð €ð Ÿ(ˆab�C—{3Xu!VZiFÓ(ÖA ­DBJV>`ÓŸŠ4¢˜"8Æ @ Ýåè# À$ì„5ãðüdC3ëˆää6hE H–`MThÁ]s „LÔab]Üh”eX4t ‡—_‚éÄGª(¥¸ Žì…_’1eÑr^ÈG#pX„‹=F©ñ¦U Q™&”1ALJæÌ£õ¤ô‹$Ð@ d—C‚šsk†ªé(<™_L¬9„C²”cé·Ü2”C`@Ó€ì�6Ø/É4¦ ¨ÚÂG'¥—àcË¡±K£zAHÿ­1ܺØyÄåDRE˹Á©In86†„,hëÑp Ð\~GUÐ@@K,Ê7œÆ¡ë2 vÙQ aÞY 3ì�†¾$pTÝnŸìòÌ…PÐ!w×4Þ.ØF@]ª8Í6""× ‚7Þè R§Z=Ö!:ñˆØÜHUÊ+Mƒ¢ÃŒçìÈc<HÊ&OÈ3JJüìQI™$+ªÐ×Ô¡î"¸ôQ Z™W 4�@©(Ôb~M†Î$Ü5Ù2&p8ÍB1¦ËÕLg½Ô<@5N§ôôß¡½š- kçÄTqVCêfCBø998Õã ¹àŽkxsßǺ€ƒˆf¾U•Aµ¨Óä5“.‹ðåœs|vŒ®º{ܤ`»í6Ï>B�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image3��������������������������������������������������������������0000644�0001750�0001750�00000006621�07504443347�016521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aH�Ä��  NŒŒ JEUYXÁÐÏfdŠŒ13üüú²´ÀÀÀj¦¤ZU.ww157ÿÿÿ������������������������������������������������!ù�� �,����H�@ÿ $Ždiž%�‡Àp,Ïtmßx®ï|ïÿÀ p( Ž¯ZcX8eƒH­Z¯Ø¬v[0¢r „xL.# €¤,`n�žt>çÖî¼á�“> NK?tKyn|;…AKa‡�:^q?e k›dprRŸch¤¥g˜3x©gЍ›pšy *�®‰0±n½µn1®’*j5ËT ¿Ÿl©p ÄnÊÈ©hIØ»S­Ý°¥pÜh” »‰å‡ÁŠÙmÁiõy’”9«@Ñ¥(P &ùv™ñ.�ñ>íñe_*$#,†€T¥BŒ„möÿUÊŲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ*J´¨‚� ø°QÐ飸‹¾Ä!dZ #¤ã^`#zõ¢€Œ Œ £�†VC0pM…« ë”Œ  Âˆ+U+£FíB{#rÊÚaÔEj`š×Ö*ÚU2‚‹ƒÜ-{Òí †>'öÅÒ·ãÚFþºà3Bq™ÿ¾Õj ,ÓëÞ½Û�2¢¾Ñ 50 ãÐ3„ ­¼ø€ßD  +4ÁóÜ žNÐ8ú�æ ¬§ì›+ñŒãÃ;gn]¸n‘뱟IŸÙtÙé‘o/î6}ûºç!‡Ö|à¹5PÚ!÷Wÿ$ÏI—\Ýe—ßyiGžs¹ù†ÝnGtH‚Iv„(âˆ$–h" –b …cR‹²øs¢m2‰î¸ÒÑŒ,¤R?&0sŒŸ„5‘‡„2ÃFÀ9˜BÞÀP#“‡ÙÇHTîX@� �Hy-Éä7xaÑ `ÙF˜HÚ‚ 8Tê‘FŽ©8&ԇܨ¦p´Y;b½s�žeÌsÒ'·¼€’?â0‰~êC'¢�À É�|,úg3hZFƒî¢gE‘Š褟ôòd†³‰2Š&óh?Dp€M,¬WN5ä T./ÜŠ Ì{“"àtæ ¹²à“®2ت‚ÔVëÿ 80Ó²Íðf”—î¹E·ä¾·À¸å*÷%Wë¦[íºû. NÄ[׆æ2ç%ïæ†Àáz;†¼ˇ/ÁŒ”�¤`U€ˆ àÂm_°À 8Ð�Æqg€V^õS8ÀgÌ6QjÑBÕgµ%uÛmÏ!5À_-‡ñ_¾m,VÛqÉ Êð®%W‹,ÎW‹a´¡È7_v@ryHR_Áuó[VG×ÀÔ—9Tš0@°hMJÕ_Â5±d\³€>/•ðÝxç­÷Þ|÷í÷߀÷íáà%pËãáˆ'®x)>‚‹G.ùä”ÛиŠ44 ô.¤•Zhå;êFÿ˜8r>y4Hípù‡7xJ†½èŠ’ ß zdŠˆê&Zžèg£ež�m§»œMƒç È¸%À{š1 iGð¥Höxô·Çôk|©=GÃ7�0¢QØÐ<"ãh = ¤•0 ÿ†òÖ¾d•5»Cr Küd_(.CÇX¾—‡ŽDJ ¹P‡=HC¥(OÛë@Á¢ÙÉHsÞ# ò—$î‘CTç 7ÕA@M­òÔ�ø1ÁHÌj}ÊóAš’ùñ)òƒmÄ©U¡ãN ¤¥vè†S ÊS)”.Ü— àY.†@°á0Â5UJ…™r…¦)øïu!Œ$ò¨ÿ*¶!>†0T¸Œ:±CÐÜæŠW) ŠeO;Ÿ*„ÔB~ÑaÔ_%ĘPJòXc’ÂBYnPÜô¨Ç*/'Š˜cŒdp�|gzßóF!QÈ<d øcH0u(2.KZžœŽHô8†VÍ€ž%0¬Ã]M,Bí†IÌbšEbÈtÁâ�¸f:ó™ÐŒ¦4§©7Û<ˆ*i¦Èâr0o±)7;»¦¼Â™°®°Àt»Mhò2•Ý,í;WÁ¥8ã©©‰“7\ Þl†–¼0Œš ;Ì,ö°ˆ€KûNUÐ�|')Q�4ˆ²�Œl �@F'nvt’ÿ"-FCJÛâ³MƒÐ@ŠG;a¶hM- ^qô Pñ6,7ÃÂL¨miô|šE£†²›UmmМÖ\Ú5Ñ|£¸<é#A’¦í6kCÙH!ö–4¦¨_ÚBˆsÏ¿-L8arÊšp‘Œœ4e;sëZ;‘1÷ø”d[*)TWR—¹e/GkBBã´ºtB©p™ŽX¨²€0$C©øZÓXx]Dg ]@X”ÖÐzÚL¨·ʨ¦Õ¼ ¥.õ«r¾†Œ¶Æ“l(5RÊŽ‚UËrÓ´Œ­˜V…2ÊfT³4¨p‡KÜâ÷¸ÈM®r—Ëܼ9î¹—h2IÝêZ·ÿÐE*¯ËÝî^wuŽžwÇKÞÉ·Cˆ`y×Ë^Ä×1Ä –¬=hÌò¾ø%é®Ë¥üúw–ê#ÑìAÄõw–ð[ßà ¥ÊZZDŠ æ0l� cÁŒŒ²0‰j„)õb½6ècHˆ#;kDrÂA,ŽÄK"MNñ…<Á‰[¸¿’TÐÄÝ¥0‹/|ÈY*%0¶ <ÜÊ€8�r†¢š�J{" ÎÜ’©A:ЀÂÑ¥óʇÍ1O{½“—§‡_ÍârÔ²>Ž\ ø†n =žg@K{P6Ø ¥ZbÐ`rO|u†Dï�ŽÀJû2ëvÀÄ:ÉÇt¶ÿäyœÓW8¦úQŸ¹3Áý:U ŠÔþ>Â*è5S1†ÀŽoIË®ÞØ 4Ðÿfv"æIŠ.Ä$ŸE• ×% æ2å!Óø?T.Št @§¬œãUgn#›³”™Œ_^÷ÑwHqófAÆ’˜0{IÔN]ÕÄ 7C'ÆAÔ,=Ž$ãÙÅ¡L-ŒH-2Iuäa W oç)ÒFé%w)ÞH#¤;ë®ÓZçÜçRD©qÞµ½…#[/¤ŒGT"=”«rkØF¸BÄánÿÁ!£ZDuŸ­¤cŠ Òâ$ ÔŠ‘øoR.Ñæ.8ª‰�ó<PÂ?ÖG»±s\ÃË‹Ú6°ÿÈo9Omtd%œ­b_ Øó º6†îðo‰–È©9\Žo†é[æ©è¸kÎ*\pý‡$‘å gÙÑäoç¡ ‡–Ÿ°"^%¥ñ°>aô»–l·âvqþñ!|Ú…³ˆ»®­Û"I§?Ðó,…ú¬,@"müôWå’ŽG)án³Tš€¦÷Èa— ¿oÆÉúÎãË ¥¤¼ÞÊXñ<^‰!$Ë“Åñò}SœS®À$ pŽô§?}9‹ZÔϾö¥¿ÄdSzùËo~Kýíg_å7¿ø ç¬i!_ýÚ~ le6ß�âþ€ Žó±u¼�Àß9¸ÐxTLÿH€V€˜L7° Ø€ ˜ˆ€5À€H€1PÉ4wÇ„ ¨Èd,ü#1H¨×^(˜‚æÕ\,Ø‚.ø‚0ƒ28ƒ4è-aÁ%CqXÁ¥7ñ42cZà@“.Bx7v"1[BÓ€.±1ÜDW|õ/86CøÒÓM \Êq…/h$íÔÂa1Ìñ/aÈ/!ñõ0W±1máç‚o(,³ú’XÊáÇð² 0v؇ @„ E-¨�…—å† ¢‡ŽZ ZÇÑ(Uphìâa¸Y!ó%@ ˜ˆ}H’˜&Ž”щ¢Á<h…‰Ñ´0ÿ MI¡1?³�´ð¯ñ5Á¢1S KUãI½XkîÑ2Ãá$·2G#1ÓP�@EZs1-à„Xc#ã#HaR<•4F\µ1žä5ÓZsS àfcaÀRâ¹wsSEóŽñeÓòHXúè;#‘^ UV~sV¸UPc£9 E lˆ2a‹±�)4\1Txe2–•2me9#þ3±å„1s3áq©Õ [;xŸR>ÈÐ2GÓSùNMƒ’Ç¡‘öZõ< µTqã5`ãZjk2W5Cl3r¤5CéÅøXÎtVžÿs1Ÿä–5Z¶A Å%8>ÅN!aQ� 2 y›‘Xþô%Q�—…5a°YßÁy^âZ:ˆ '¥ 4ù/HÃPœTŸ•‘#Ó“l£Rµ!”»åTE)6ê¤5t£”´Å”Z%2b9PQéŽa5b8j1ƒØOk!Qc‘õÄZÕÁ¹'ÐRn!‚±ÉW«1ia+ÉA�§™{ãƒIƒ5`s1(•,,ÙTÁ€Ç �ºI2 ‘’‘Qs›†%œ}u3¬)dQI!] ”›rÑR¶5Ř+½yšhÑ’aPa(u+É9†-ù51š/Yƒú¹ŸüÙŸþùŸ� : Z z j!��;���������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page1/image5��������������������������������������������������������������0000644�0001750�0001750�00000001715�07504443347�016522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a"�,�¥��5  –ÑÐÎt`Vǵ®‰{ròîí¼™†êÒÈÓ¹°¥rŒhZZ@7àÛܯ¤Ÿ˜Š€À§œ’:M/)~nfdOFîÜÓŠR0R ÆÂ½rgÙ¹¥Š~úúü•v­–ŽßÎÃ������������������������������������������������������������������������������������������������!þMade with GIMP�!ù � �,����"�,�@þ@pH, •¢Ò¨ATžÐ#€BNëRH B€!4‰RB�#>VÄdèL2Rùhþ y`aOBH wm€bb‚‚P[  •fvT‘¤ŒKHqW GsVO•| MœZ¢zgp ƒˆ  œo´K]Ñ gN~ƒ � ¶IDG¨•‚›œü”@�sÕ{’0á‘aÃ256®ˆ€41b¦,*10l@ùÁÓ�T Щ“˜'"èà€&þH16$·OO4Øâ€ß8Î8gMN ª &AN &˜3Ó&Y4VY0À%Α¶JñÓÓ¤š³ @§ßgt Ä"À`B=f«|ÒÄÏ&(Jð‘9õàð4Nìúxpà@–„¾íÛ@�©‰ ލܰàÖ BA"èkìŽV> è�'¤CÜV¤ô†øµe‚+}0H‰È•+H{EtVʹ8 °y²IŽWóPðz… �$è)¨»o%(H€€¿ ù2€QPa¨M¨Ð–›œ!@D0 ÁÄñ•$jN'S€ Ú,pfNÌx©lðÀ� 0€P½±„$x|0•¾áGTæb5b|Š] à@V¡u× øq�.ÇUN0—fý“×çxøA�l½˜t<à�:—)ùÁ, À ðŒdtQ�%˜TãX'h|ôÁDoÑ‘$P KOücSဓÅR *€‡õt†5˜=Q@YÈqÏ(t@™4›„³Î< Ýgµ" ?À£$:©>@@,¤€Öª� ”™J�ðÓ™i§‘’m°%�;���������������������������������������������������./saods9/htmlwidget/tests/html2.test����������������������������������������������������������������0000644�0001750�0001750�00000003702�07504443346�016357� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Test script for the Tk HTML widget # wm withdraw . if {[lsearch [namespace children] ::tcltest] == -1} { source [file dirname $argv0]/engine.tcl namespace import ::tcltest::* cd [file dirname $argv0] } # in image to use for all GIFs. # image create photo nogifsm -data { R0lGODdhEAAQAPEAAACQkADQ0PgAAAAAACwAAAAAEAAQAAACNISPacHtD4IQz80QJ60as25d 3idKZdR0IIOm2ta0Lhw/Lz2S1JqvK8ozbTKlEIVYceWSjwIAO/// } # A callback to handle image requests # proc ImageCmd {args} { set fn [lindex $args 0] if {[catch {image create photo -file $fn} img]} { set img nogifsm } return $img } # Free all images # proc FreeImages {} { foreach img [image names] { image delete $img } } # Create the HTML widget to use for all testing. # set h [tkhtml_test_widget] $h config -imagecommand ImageCmd ::tcltest::test html-2.1 { A snapshot of Slashdot on Jan 29, 2000. } { set file page1/index.html $h clear set f [open $file r] $h config -base $file $h parse [read $f [file size $file]] close $f set r [::tcltest::user-result] $h clear FreeImages return $r } {2 pass} ::tcltest::test html-2.2 { A snapshot of a page from the Scriptics website on Jan 29, 2000. } { set file page2/index.html $h clear set f [open $file r] $h config -base $file $h parse [read $f [file size $file]] close $f set r [::tcltest::user-result] $h clear FreeImages return $r } {2 pass} ::tcltest::test html-2.3 { A snapshot of freshmeat on Jan 29, 2000 } { set file page4/index.html $h clear set f [open $file r] $h config -base $file $h parse [read $f [file size $file]] close $f set r [::tcltest::user-result] $h clear FreeImages return $r } {2 pass} ::tcltest::test html-2.4 { A slide show about mktclapp } { set file page3/index.html $h clear set f [open $file r] $h config -base $file $h parse [read $f [file size $file]] close $f set r [::tcltest::user-result] $h clear FreeImages return $r } {2 pass} ��������������������������������������������������������������./saods9/htmlwidget/tests/engine.tcl����������������������������������������������������������������0000644�0001750�0001750�00000007375�07504443346�016413� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file contains the test driver for the html widget. It defines # a special version of the test procedure to use for testing the # html widget. # # Initialize variables # namespace eval tcltest { set mode run set current {} set passed 0 set failed 0 set total 0 set status {} } # Arguments: # # tag A symbolic tag for this test. Ex: html-1.0 # # desc A human-readable description of what this test does. # # script Tcl code to implement the test # # result The expected result from this test. If the actual result # is different the test fails. # proc ::tcltest::test {tag desc script result} { ::tcltest::change-desc $tag $desc if {[info exists ::tcltest::idle]} { catch {after cancel $::tcltest::idle} catch {unset ::tcltest::idle} } set rc [catch {uplevel #0 $script} msg] set r [list $rc $msg] if {$r==$result} { incr ::tcltest::passed puts "---- Test $tag passed" } else { incr ::tcltest::failed puts "**** Test $tag failed" puts "Expected: [list $result]" puts "Got: [list $r]" } incr ::tcltest::total ::tcltest::update-status set ::tcltest::idle [after 100 ::tcltest::testing-complete] } # Create the test control window # proc ::tcltest::mainwin {} { set w .testinfo toplevel $w wm title $w {Html Widget Test Information} wm iconname $w {Html-Test} set f $w.f1 frame $f pack $f -side top -fill x label $f.l -text {Status: } label $f.v -textvariable ::tcltest::status pack $f.l $f.v -side left set f $w.f2 frame $f pack $f -side top -fill x label $f.l -text {Current Test: } label $f.v -textvariable ::tcltest::current pack $f.l $f.v -side left set f $w.b frame $f pack $f -side bottom -fill x button $f.pause -text Pause -command ::tcltest::pause button $f.pass -text {Pass} -command {::tcltest::set-result pass} button $f.fail -text {Fail} -command {::tcltest::set-result fail} button $f.exit -text Exit -command exit pack $f.pause $f.pass $f.fail $f.exit -side right -pady 10 -expand 1 scrollbar $w.sb -orient vertical -command "$w.t yview" pack $w.sb -side right -fill y html $w.t -yscrollcommand "$w.sb set" -width 400 -height 150 \ -bd 2 -relief sunken -padx 5 -pady 5 pack $w.t -side right -fill both -expand 1 ::tcltest::update-status } # Change the test description in the control window # proc ::tcltest::change-desc {tag desc} { if {![winfo exists .testinfo]} ::tcltest::mainwin .testinfo.t clear .testinfo.t parse $desc\n set ::tcltest::current $tag } # Update the status line # proc ::tcltest::update-status {} { set v "$::tcltest::passed passed $::tcltest::failed failed " append v "$::tcltest::total total" set ::tcltest::status $v } # Wait for the user to press either the pass or failed buttons. # proc ::tcltest::user-result {} { .testinfo.b.pass config -state normal .testinfo.b.fail config -state normal update raise .testinfo focus .testinfo.b.pass set ::tcltest::result {} vwait ::tcltest::result .testinfo.b.pass config -state disabled .testinfo.b.fail config -state disabled return $::tcltest::result } # Called when the user presses either the failed or passed buttons. # proc ::tcltest::set-result v { set ::tcltest::result $v } # Call this routine at the end of all tests # proc ::tcltest::testing-complete {} { ::tcltest::change-desc {} {Testing is now complete} } # Construct an HTML widget to use for testing. # proc tkhtml_test_widget {} { set w .tkhtml_test if {[winfo exists $w]} { return $w.h } toplevel $w wm title $w {TkHtml Test Widget} wm iconname $w {TkHtml Test} scrollbar $w.sb -orient vertical -command "$w.h yview" pack $w.sb -side right -fill y html $w.h -yscrollcommand "$w.sb set" pack $w.h -side right -fill both -expand 1 return $w.h } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/all.test������������������������������������������������������������������0000644�0001750�0001750�00000000242�07504443346�016075� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Run all tests # cd [file dirname $argv0] set me [file tail $argv0] foreach file [lsort -dictionary [glob *.test]] { if {$file==$me} continue source $file } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/html1.test����������������������������������������������������������������0000644�0001750�0001750�00000012444�07504443346�016361� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Test script for the Tk HTML widget # wm withdraw . if {[lsearch [namespace children] ::tcltest] == -1} { source [file dirname $argv0]/engine.tcl namespace import ::tcltest::* } ::tcltest::test html-1.0 { Verify that all of the entites are displayed correctly. } { set h [tkhtml_test_widget] $h clear $h parse { <html> <h1>Entity and special character test</h1> <p>The following list shows each entity of HTML 3.2 in four formats: (1) the name, (2) as &amp;entity;, (3) as &amp;#123;, and (4) as a raw UTF-8 or Ascii character.</p> <ul> <li> quot &quot; &#34; " </li> <li> amp &amp; &#38; & </li> <li> lt &lt; &#60; < </li> <li> gt &gt; &#62; > </li> <li> nbsp &nbsp; &#32; </li> <li> iexcl &iexcl; &#161; ¡ </li> <li> cent &cent; &#162; ¢ </li> <li> pound &pound; &#163; £ </li> <li> curren &curren; &#164; ¤ </li> <li> yen &yen; &#165; ¥ </li> <li> brvbar &brvbar; &#166; ¦ </li> <li> sect &sect; &#167; § </li> <li> uml &uml; &#168; ¨ </li> <li> copy &copy; &#169; © </li> <li> ordf &ordf; &#170; ª </li> <li> laquo &laquo; &#171; « </li> <li> not &not; &#172; ¬ </li> <li> shy &shy; &#173; ­ </li> <li> reg &reg; &#174; ® </li> <li> macr &macr; &#175; ¯ </li> <li> deg &deg; &#176; ° </li> <li> plusmn &plusmn; &#177; ± </li> <li> sup2 &sup2; &#178; ² </li> <li> sup3 &sup3; &#179; ³ </li> <li> acute &acute; &#180; ´ </li> <li> micro &micro; &#181; µ </li> <li> para &para; &#182; ¶ </li> <li> middot &middot; &#183; · </li> <li> cedil &cedil; &#184; ¸ </li> <li> sup1 &sup1; &#185; ¹ </li> <li> ordm &ordm; &#186; º </li> <li> raquo &raquo; &#187; » </li> <li> frac14 &frac14; &#188; ¼ </li> <li> frac12 &frac12; &#189; ½ </li> <li> frac34 &frac34; &#190; ¾ </li> <li> iquest &iquest; &#191; ¿ </li> <li> Agrave &Agrave; &#192; À </li> <li> Aacute &Aacute; &#193; Á </li> <li> Acirc &Acirc; &#194;  </li> <li> Atilde &Atilde; &#195; à </li> <li> Auml &Auml; &#196; Ä </li> <li> Aring &Aring; &#197; Å </li> <li> AElig &AElig; &#198; Æ </li> <li> Ccedil &Ccedil; &#199; Ç </li> <li> Egrave &Egrave; &#200; È </li> <li> Eacute &Eacute; &#201; É </li> <li> Ecirc &Ecirc; &#202; Ê </li> <li> Euml &Euml; &#203; Ë </li> <li> Igrave &Igrave; &#204; Ì </li> <li> Iacute &Iacute; &#205; Í </li> <li> Icirc &Icirc; &#206; Î </li> <li> Iuml &Iuml; &#207; Ï </li> <li> ETH &ETH; &#208; Ð </li> <li> Ntilde &Ntilde; &#209; Ñ </li> <li> Ograve &Ograve; &#210; Ò </li> <li> Oacute &Oacute; &#211; Ó </li> <li> Ocirc &Ocirc; &#212; Ô </li> <li> Otilde &Otilde; &#213; Õ </li> <li> Ouml &Ouml; &#214; Ö </li> <li> times &times; &#215; × </li> <li> Oslash &Oslash; &#216; Ø </li> <li> Ugrave &Ugrave; &#217; Ù </li> <li> Uacute &Uacute; &#218; Ú </li> <li> Ucirc &Ucirc; &#219; Û </li> <li> Uuml &Uuml; &#220; Ü </li> <li> Yacute &Yacute; &#221; Ý </li> <li> THORN &THORN; &#222; Þ </li> <li> szlig &szlig; &#223; ß </li> <li> agrave &agrave; &#224; à </li> <li> aacute &aacute; &#225; á </li> <li> acirc &acirc; &#226; â </li> <li> atilde &atilde; &#227; ã </li> <li> auml &auml; &#228; ä </li> <li> aring &aring; &#229; å </li> <li> aelig &aelig; &#230; æ </li> <li> ccedil &ccedil; &#231; ç </li> <li> egrave &egrave; &#232; è </li> <li> eacute &eacute; &#233; é </li> <li> ecirc &ecirc; &#234; ê </li> <li> euml &euml; &#235; ë </li> <li> igrave &igrave; &#236; ì </li> <li> iacute &iacute; &#237; í </li> <li> icirc &icirc; &#238; î </li> <li> iuml &iuml; &#239; ï </li> <li> eth &eth; &#240; ð </li> <li> ntilde &ntilde; &#241; ñ </li> <li> ograve &ograve; &#242; ò </li> <li> oacute &oacute; &#243; ó </li> <li> ocirc &ocirc; &#244; ô </li> <li> otilde &otilde; &#245; õ </li> <li> ouml &ouml; &#246; ö </li> <li> divide &divide; &#247; ÷ </li> <li> oslash &oslash; &#248; ø </li> <li> ugrave &ugrave; &#249; ù </li> <li> uacute &uacute; &#250; ú </li> <li> ucirc &ucirc; &#251; û </li> <li> uuml &uuml; &#252; ü </li> <li> yacute &yacute; &#253; ý </li> <li> thorn &thorn; &#254; þ </li> <li> yuml &yuml; &#255; ÿ </li> </ul> </html> } ::tcltest::user-result } {0 pass} ::tcltest::test html-1.1 { Verify that all subscripting and superscripting works. } { set h [tkhtml_test_widget] $h clear $h parse { <html> <body> <h1>A test of subscripting and superscripting</h1> <p>Here is sub<sub>script</sub>. And now super<sup>script</sup>.</p> <p>Here is sub<sub>sub<sub>script</sub></sub>. And now super<sup>super<sup>script</sup></sup>.</p> <p>Here is sub<sub>super<sup>script</sup></sub></p> </body> </html> } ::tcltest::user-result } {0 pass} ::tcltest::test html-1.2 { Verify stylistic markup. } { set h [tkhtml_test_widget] $h clear $h parse { <html> <body> <h1>A test of font changing markup</h1> <p>This is normal text</p> <p>&lt;b&gt;: <b>bold text</b></p> <p>&lt;big&gt;: <big>big text</big></p> <p>&lt;cite&gt;: <cite>cite text</cite></p> <p>&lt;code&gt;: <code>code text</code></p> <p>&lt;em&gt;: <em>emphasized text</em></p> <p>&lt;i&gt;: <i>italic text</i></p> <p>&lt;kbd&gt;: <kbd>keyboard text</kbd></p> <p>&lt;s&gt;: <s>strike-thru text</s></p> <p>&lt;samp&gt;: <samp>sample text</samp></p> <p>&lt;small&gt;: <small>small text</small></p> <p>&lt;strike&gt;: <strike>strike-thru text</strike></p> <p>&lt;strong&gt;: <strong>strong text</strong></p> <p>&lt;tt&gt;: <tt>teletype text</tt></p> <p>&lt;u&gt;: <u>underlined text</u></p> <p>&lt;var&gt;: <var>variable text</var></p> <p>This is normal text</p> </body> </html> } ::tcltest::user-result } {0 pass} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057636�015422� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image9��������������������������������������������������������������0000644�0001750�0001750�00000002740�07504443353�016525� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a–�+�Äÿ����ÿÿÿ�333ffÿ��Ì��™��f��3��ÿ33ÿffÿ™™ÿÌÌÌÌÌ™™™fff333ÿÿÿ������������������������������������������,����–�+��ÿ` Ždižhª®lë¾p,Ïtmßx®ï|Ÿ?À‡ã䦢Ù0:…ÈXcê˜FSMçp¤:ºÏ§(†Ê€tú:‚¨Ó[’ûý8Þxu½Õp@æofIyq€yyHw‹tRxlrj(n–”p_@•+M•Š€‚“ s¥h�{§i™QSsWˆ›œž/Žj¥"м˜%µ™#®�†%ºnÌLJjDpm¯'³#Âl«Æ/µjÓ½&ÀšÃ\Ù&®ÊòóòÑi{ëk„�WsúˆmÑ-»¨ò] ¤ €:jÛí*á€xô2Ö»'Àá]Ó¥Âñ?‚Iÿˆãuâ•°…o¦¡#ùÐTÊ1s`ÔÈ“€3¿…,YŽU»G’�É'Ÿ.˜zL>|Iq%ðzj%P�(QTRÓ5ôÇíÕ$¦,V}¹IéÏAlÁVUˆέ[ 8@. ºEk£eÖ `ަX•ªkÒL”D‰EµÙq'^ž .(™oÑ€$ ŸÜg”E-Y×L>øúqß·cpÕ2p¹g ¸ÖxiêÀ'¬¨,ìûp t�ZTÂ5Uß,­BP»ç‚�¹»FZœMrb,9“&G9ìr–Тo~>:DÚÕ5^Ï­ûÚdÈ쉺"'²g,tõ·km&˜'Ê`¤€ÿ (À�ƒô$°� Ðw[� (À•Bß­'Vlÿ•5š,A—Zoìeâ×kqµW‰+ÌÃ@�3Ö8"̈׉°€<ÑXòÜk­¦Ö 2Ç‚#[p—¢ê9ç¢YÅ(Ïu¸]¨!4ævá•@¨Û}¤´_~ÃiBâgX,‹hJ‡®­¢CŽÀGÀŒ†É£Ÿòà¨á|óhæÏ7p†ˆŠ¿ ÷Š n‘éÂc÷Á%"�–:zà+Žìħ< `¸'v ”*èŸôù´†“‰å·4ºÂ[v²8ž‡4IÄi;J@¨êXÂ8¦jèßÝ¡MV0‰ä.Í¢Rbg‰Öÿ“IÙt*#n Š:ã‚äB諪dÉ%’I¥Ù"dË·‚³¤9™µ¶~hâ®ɸã¯~^—}çàT¹ÚkúÉ ï$ø"6"Š™Þ‰ì¶Cr‹Vî .ÀÄúç ÿÖGVo ³›¦Ã‘å¨Ë)ˆóÇÌqâ:g6uNQÔÉó)Àj)!†I_w"áp‡¦„G\½+(²H‘SU£í¦F  F?‡úã¯Â~*цê3Î*¥ÔŠ‚€‡‰VØéšP9oë®QŽXYj„©@îÀ š@­¢é‚€+©°ÊÂÒÊ©ÉWëj”+wÅד^÷æSËX ÷uð¥g±ÕÏÿP#ºÖ2lµQÇ–gä•!˜ΰ`H±-:2#BÉ–éßÀ–ñÝ­¸¥gëòúPïí>>–hñ¶<­HªÔ,»(†ÏÕ®#•¯ÙçûÖœky£Ùžû“-&»8ë û^ÃW·ý» ³¬ví¢·mÂyòÚÜê:C̾廉Fçâ3åfˆ»]gÈ3$Ùůjvû5”Ñ>žü`Ëš—?M0/tãÛ‡ÓFãÀd¸ <mZÏ�€€‹X¦�öÀ Ýd\°«sôóîÒ‚"äc}Çj¾€‰*H.M~¨„C¡Á›í……v‰â+~ø‰JA)_È¢ùÑ@¬æeB(Ÿ u‡e·Äd,Ã@ß"ºÕ @‰j�>¾˜+0V\̃:ta7ST¡ ¥øcà&H ò T¤ § …"˜ñƒpÁ!Û!ÈJÒˆM³$t9-xò“  ¥(GIÊRšò”¨L¥*WiÊ��;��������������������������������./saods9/htmlwidget/tests/page4/image6��������������������������������������������������������������0000644�0001750�0001750�00000000326�07504443353�016520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ó����� ,,)889PPRyy{‹¾¾½ÎÎÍÞÞÞÿÿÿ������������,������@‹È) RK!#æDK¸�ËPg1Œb&%m,/Áϳ""I=VË31`DA(!Üp‹A K)ÔŠ$²^qÜnL"d…æº0P‰@ÜaXØ-Å´_˜"sW(ˆ[-FW*&e!k,‚gmW>Ag�}!€�‚“”lnL¡1:�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/index.html����������������������������������������������������������0000644�0001750�0001750�00000226756�07504443353�017443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML="HTML" PUBLIC="PUBLIC" "-//W3C//DTD=""-//W3C//DTD" HTML="HTML" 4.0="4.0" Transitional//EN"="Transitional//EN""> <HTML> <HEAD> <TITLE>[fm] welcome to freshmeat.net</TITLE> <STYLE TYPE="text/css"><!-- A:link {text-decoration: none}A:visited{text-decoration:none}A:active{text-decoration:none}--></STYLE> </HEAD> <BODY MARGINWIDTH="0" MARGINHEIGHT="0" LEFTMARGIN="0" RIGHTMARGIN="0" TOPMARGIN="0" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#336699" VLINK="#336699" ALINK="#336699"> <BR><CENTER><TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TR><TD WIDTH="1"><SCRIPT LANGUAGE="JAVASCRIPT"> <!-- now = new Date(); tail = now.getTime(); document.write("<IMG SRC='http://209.207.224.246/FreshMeat/Core/pc.gif?/index.php3," + tail + "' WIDTH=1 HEIGHT=1><BR>"); //--> </SCRIPT> <NOSCRIPT> <IMG SRC="image1" WIDTH="1" HEIGHT="1"><BR> </NOSCRIPT></TD></TR></TABLE> <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TR><TD WIDTH="468"><SCRIPT LANGUAGE="JAVASCRIPT"> <!-- now = new Date(); tail = now.getTime(); AltText = "\"Please click here.\""; document.write("<A HREF='http://ads.freshmeat.net/cgi-bin/ad_click.pl?index,tsof0001en'>") document.write("<IMG SRC='http://ads.freshmeat.net/tsof0001en.gif?" + tail + "' WIDTH=468 HEIGHT=60 ALT=" + AltText + "></A><BR>"); //--> </SCRIPT> <NOSCRIPT> <A HREF="http://ads.freshmeat.net/cgi-bin/ad_click.pl?index,tsof0001en"><IMG SRC="image2" WIDTH="468" HEIGHT="60" ALT="Please click here."></A><BR> </NOSCRIPT></TD></TR></TABLE> <TABLE CELLSPACING="0" CELLPADDING="2" BORDER="0" WIDTH="97%"><TR> <TD ALIGN="left" VALIGN="bottom"><A HREF="/"><IMG SRC="image3" BORDER="0" ALT="freshmeat.net" WIDTH="300" HEIGHT="65"></A></TD> <TD VALIGN="bottom" ALIGN="left" ROWSPAN="2"><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <FORM METHOD="get" ACTION="/search.php3"> <SMALL>find: <INPUT TYPE="text" SIZE="15" NAME="query"></SMALL></FORM></FONT></TD> <TD ALIGN="right" VALIGN="bottom"><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <A HREF="http://www.linux.com"><FONT COLOR="#000000"><B><SMALL>linux.com partner</SMALL></B></FONT></A><BR> <TABLE CELLSPACING="0" CELLPADDING="1" BORDER="0" WIDTH="100%"><TR> <TD ALIGN="right"><SMALL><NOBR><FONT FACE="Lucida,Verdana,Helvetica,Arial"><B><A HREF="/">news</A> |<BR> <A HREF="/appindex/">appindex</A> |<BR> <A HREF="/editorials/">editorials</A> |</B></FONT></NOBR></SMALL></TD> <TD ALIGN="right"><SMALL><NOBR><FONT FACE="Lucida,Verdana,Helvetica,Arial"><B><A HREF="/lounge/">lounge</A> |<BR> <A HREF="/contrib.php3">contribute</A> |<BR> <A HREF="/feedback.php3">feedback</A> |</B></FONT></NOBR></SMALL></TD> <TD ALIGN="right"><SMALL><NOBR><FONT FACE="Lucida,Verdana,Helvetica,Arial"><B><A HREF="/about.php3">about</A> |<BR> <A HREF="/awards.php3">awards</A> |<BR> <A HREF="/faq.php3">FAQ</A> |</B></FONT></NOBR></SMALL></TD> </TR></TABLE></TD> </TR></TABLE> <TABLE WIDTH="100%" CELLPADDING="0" CELLSPACING="0" BORDER="0"> <TR BGCOLOR="#000000"><TD><IMG SRC="image4" WIDTH="1" HEIGHT="2" ALT=""></TD></TR></TABLE> <TABLE CELLSPACING="0" CELLPADDING="3" BORDER="0" WIDTH="100%" BGCOLOR="#BBDDFF"> <TR><TD ALIGN="center" VALIGN="top"> <BR> <FONT FACE="Lucida,Verdana,Helvetica,Arial"> <SMALL><B>sort by: [ <A HREF="/news/2000/01/29/">date</A> | <A HREF="/news/list.php3?day=/2000/01/29/&orderby=name">name</A> | <A HREF="/news/list.php3?day=/2000/01/29/&orderby=urgency">urgency</A> ]</B></SMALL><BR></TD><TD>&nbsp;</TD></TR><TR><TD VALIGN="top" ALIGN="center"><FONT FACE="Lucida,Verdana,Helvetica,Arial"><TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">We should get this out of the door now</FONT></B><BR> <SMALL><B><A HREF="mailto:scoop@freshmeat.net">scoop</A> - January 29th 2000, 23:59 EST</B></SMALL> <P>Everyone else is talking about it, so we should announce it ourselves before you start to think it's a government hoax. <A HREF="http://server51.freshmeat.net/">Server 51</A> is our new hosting service for Open Source projects, based on Super Cool Space Alien Technology(TM). We hadn't planned to announce it quite so soon, and it's still in the alpha stage as we work day and night at integrating SCSAT with our terrestrial systems, but feel free to take a look around and see what's going on. When we're out of the testing stage and ready to make room for your project, we'll send word via your implants. Be listening. <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949208399.html">comments (8)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>Category: freshmeat </SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://server51.freshmeat.net"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">Is Linux for Crazies?</FONT></B><BR> <SMALL><B><A HREF="mailto:jeff.covey@pobox.com">jeff covey</A> - January 29th 2000, 23:59 EST</B></SMALL> <P>Ray Woodcock writes: "In terms relevant to Linux, this freshmeat editorial glances at the tendency of mainstream viewpoints to dismiss other viewpoints as 'fringe,' the propensity of dissident movements to splinter into factions before they can effectively counter their primary adversaries, and the difficulty of creating stability without squelching curiosity." <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949208340.html">comments (2), 2065 words in body</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>Category: Editorial </SMALL></B></FONT></FONT></TD><TD ALIGN="right"> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">RabbIT 2.0.2</FONT></B><BR> <SMALL><B><A HREF="mailto:d94-rol@nada.kth.se">Ernimril</A> - January 29th 2000, 18:29 EST</B></SMALL> <DIV ALIGN="justify"><P>RabbIt is the mutating, caching webproxy which is used to speed up surfing over slow links like modems. It does this by removing advertising and background images and scaling down images to low quality JPEGs. RabbIT is written in Java and should be able to run on any platform. It does depend upon an image converter if imagescaleing is on. The recommended image converter is "convert" from the ImageMagick package.</DIV> <P><B>Changes:</B> Fixes have been made for a few bugs concerning keep alive and the HTTP response header, a bug with NT and cache directories, a bug concerning requests without a response body, a bug in GZIPHandler that caused it to not gzip already compressed (gzip or compress) streams, a bug in HTTPHeader regarding response phrases that are multiline, and a few bugs in ImageHandler and NCache. GZIPHandler has been built as an intermediate(*) to FilterHandler (this means that it is possible to gzip text/plain, etc., without filtering those streams) uuencoding has been added to the Coder, RabbIT now uses HTTP/1.1, HTMLParser now compiles cleanly with Jikes, and GeneralHeader has been created to allow for HTTPFooter (which is useful when sending chunked data). <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949188564.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: freely distributable</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/daemons/proxy.html"><FONT COLOR="#FFFFFF">Daemons/Proxy</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/902659138/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/902659138/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/1998/08/09/902659138.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">nmpg 1.1.3</FONT></B><BR> <SMALL><B><A HREF="mailto:narkos@linuxmail.org">Joel Lindau</A> - January 29th 2000, 18:18 EST</B></SMALL> <DIV ALIGN="justify"><P>nmpg is a small command-driven frontend and network-jukebox for mpg123.</DIV> <P><B>Changes:</B> Bugfixes, better memory managment, a new .nmpgrc parser, and new options. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949187896.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: OpenSource</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/sound.html"><FONT COLOR="#FFFFFF">Console/Sound</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/935430877/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/935430877/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/935430877/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/08/23/935430877.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">mod_dtcl 0.7.3</FONT></B><BR> <SMALL><B><A HREF="mailto:davidw@prosa.it">David Welton</A> - January 29th 2000, 18:11 EST</B></SMALL> <DIV ALIGN="justify"><P>Mod_dtcl is a free/open source implementation of server-parsed Tcl under Apache. It allows you to tightly integrate HTML with Tcl, a widely-used scripting language with many years of development invested in it. There are also many external Tcl modules that you can load into mod_dtcl, to create images, access databases, etc.</DIV> <P><B>Changes:</B> A major overhaul of header handling and internal buffering, and the addition of the ability to handle binary data. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949187471.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/web/development.html"><FONT COLOR="#FFFFFF">Web/Development</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/917925309/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/917925309/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/917925309/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/02/01/917925309.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">CoreLinux++ 0.4.6</FONT></B><BR> <SMALL><B><A HREF="mailto:frankc@users.sourceforge.net">Frank V. Castellucci</A> - January 29th 2000, 18:07 EST</B></SMALL> <DIV ALIGN="justify"><P>CoreLinux++ is an initiative to normalize methods and conventions for OOA/OOD/C++ development for Linux, materialized in a set of Open Source C++ class libraries (libcorelinux++ and libcoreframework++) to support common patterns and exploit the C++ standards.</DIV> <P><B>Changes:</B> This release adds AbstractFactory and AssociativeIterator analysis, design, implementations, test code, a CVS daily tarball, a Patch Submission facility and updated FAQ, Web Pages, and defect reporting guidelines. <P><B>Urgency:</B> medium <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949187233.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: LGPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/development/libraries.html"><FONT COLOR="#FFFFFF">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/944077775/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/944077775/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/944077775/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/12/01/944077775.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">scribe 0.2</FONT></B><BR> <SMALL><B><A HREF="mailto:kahlage@logoncafe.net">ChromeBob</A> - January 29th 2000, 12:12 EST</B></SMALL> <DIV ALIGN="justify"><P>scribe writes functions prototypes for your C code, so you don't have to. It also compares unique functions between source code files and will 'extern' when appropriate. C++ methods support is also planned.</DIV> <P><B>Changes:</B> A fix for an fflush() bug and better documentation. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949165962.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/development/tools.html"><FONT COLOR="#FFFFFF">Development/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/946661656/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/946661656/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/1999/12/31/946661656.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">E theme updater 0.1</FONT></B><BR> <SMALL><B><A HREF="mailto:hallvar@ii.uib.no">Hallvar Helleseth</A> - January 29th 2000, 12:04 EST</B></SMALL> <DIV ALIGN="justify"><P>E theme Updater is a bash script to automatically update all of your Enlightenment themes from e.themes.org.</DIV> <P><B>Changes:</B> Initial release. <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949165472.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/misc.html"><FONT COLOR="#FFFFFF">Console/Misc</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/949164501/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/949164501/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/2000/01/29/949164501.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">Powertweak-Linux 0.1.7</FONT></B><BR> <SMALL><B><A HREF="mailto:dave@denial.force9.co.uk">Dave Jones</A> - January 29th 2000, 12:03 EST</B></SMALL> <DIV ALIGN="justify"><P>Powertweak-Linux is a port of the Microsoft Windows tool of the same name rewritten from the ground up. Its main function is to tune your system to its optimal performance settings. Currently, it tunes PCI chipsets and can set /proc/sys entries.</DIV> <P><B>Changes:</B> A major GUI overhaul, the ability to generate configuration files, extended PCI information tabs, extra information support for the Matrox G200, and numerous other bugfixes & improvements. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949165416.html">comments (2)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/system.html"><FONT COLOR="#FFFFFF">Console/System</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/930836224/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/930836224/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/930836224/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/07/01/930836224.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">Pexeso Beta</FONT></B><BR> <SMALL><B><A HREF="mailto:pavolkrigler@pobox.sk">Pavol Krigler</A> - January 29th 2000, 11:55 EST</B></SMALL> <DIV ALIGN="justify"><P>pexeso is a simple graphic card game for one or two players.</DIV> <P><B>Changes:</B> Initial public release. <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164956.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: Freeware</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/games.html"><FONT COLOR="#FFFFFF">Console/Games</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/949141436/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/949141436/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/2000/01/29/949141436.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">XZX 2.9.2</FONT></B><BR> <SMALL><B><A HREF="mailto:Erik.Kunze@fantasy.muc.de">E. Kunze</A> - January 29th 2000, 11:54 EST</B></SMALL> <DIV ALIGN="justify"><P>XZX is a portable emulator of ZX Spectrum 48K/128K/+3 (8-bit home computers made by Sir Clive Sinclair) and Pentagon/Scorpion (Spectrum clones made in Russia) for machines running UNIX and the X Window system. XZX is completely written in C and emulates Spectrum 48K, 128K, +2 and +3, Pentagon and Scorpion, Interface I with up to 8 microdrives, Multiface 128 and Multiface 3, BetaDisk 128 interface by Technology Research Ltd with 4 disk drives, +D interface by Miles Gordon Technology with 2 disk drives, Kempston mouse, Kempston joystick and built-in machine code monitor.</DIV> <P><B>Changes:</B> Lots of feature improvement and bug fixes. Most parts of the audio support has been rewritten for different UNICES. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164896.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: Shareware</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/x11/emulators.html"><FONT COLOR="#FFFFFF">X11/Emulators</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/936956384/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/936956384/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/936956384/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/09/10/936956384.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">DistroLib 0.4</FONT></B><BR> <SMALL><B><A HREF="mailto:phir@gcu-squad.org">PhiR</A> - January 29th 2000, 11:54 EST</B></SMALL> <DIV ALIGN="justify"><P>DistroLib is an abstraction library designed to make the development of distributed application easier. Its main target is currently compute-bound tasks based on a one server, many clients model (much like distributed.net), but it is quite generic and could be used for any client/server app. It is lightweight, easy-to-use, and relies heavily on threads.</DIV> <P><B>Changes:</B> Important bug fixes and command history support. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164869.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/development/libraries.html"><FONT COLOR="#FFFFFF">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/942588431/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/942588431/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/942588431/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/11/14/942588431.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">ToutDoux 1.1.7</FONT></B><BR> <SMALL><B><A HREF="mailto:yeupou@altern.org">yeupou</A> - January 29th 2000, 11:54 EST</B></SMALL> <DIV ALIGN="justify"><P>ToutDoux is a project manager which lets you design a plan of action using a tree structure, with translations in French and English.</DIV> <P><B>Changes:</B> A new menu and XML standard for save files. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164843.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/gnome/tools.html"><FONT COLOR="#FFFFFF">GNOME/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/944433411/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/944433411/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/1999/12/05/944433411.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">goMP 1.0.3</FONT></B><BR> <SMALL><B><A HREF="mailto:dioxine@poulet.org">Gautier</A> - January 29th 2000, 11:52 EST</B></SMALL> <DIV ALIGN="justify"><P>goMP is a set of CGI scripts that allows you to remotely control, via a Web browser, a computer acting as an MP3 jukebox. This program is very useful for someone who's got a dedicated computer with a lot of MP3 files but that doesn't have any output and input devices except network and sound card. It's main advantages are built-in cataloging, fast access to music, and no special software needed on the client side.</DIV> <P><B>Changes:</B> Bugfixes, a password-protected config page, basic search function, easier installation thanks to an install script, and relocation of HTML docs and CGIs to a subdirectory. <P><B>Urgency:</B> medium <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164772.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: Artistic</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/web/tools.html"><FONT COLOR="#FFFFFF">Web/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/948492962/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/948492962/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/948492962/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/2000/01/21/948492962.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">APSEND 1.40</FONT></B><BR> <SMALL><B><A HREF="mailto:sventek@gmx.net">M.K.</A> - January 29th 2000, 11:50 EST</B></SMALL> <DIV ALIGN="justify"><P>APSEND is a TCP/IP packet sender to test firewalls and other network applications. It also includes a syn flood option, the land DoS attack, and a DoS attack against tcpdump running on a UNIX-based system. Future updates will include support for a scripting language to construct TCP packets and a few more options and protocols like UDP and ICMP. A port of APSEND from Perl to C is planned as well.</DIV> <P><B>Changes:</B> The stream attack, bugfixes, and rewrites for parts of the code. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164633.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/networking.html"><FONT COLOR="#FFFFFF">Console/Networking</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/941654429/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/941654429/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/941654429/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/11/03/941654429.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">ecasound 1.6.12r10</FONT></B><BR> <SMALL><B><A HREF="mailto:kaiv@wakkanet.fi">Kai Vehmanen</A> - January 29th 2000, 11:48 EST</B></SMALL> <DIV ALIGN="justify"><P>Ecasound is a software package designed for multitrack audio processing. It can be used for simple tasks like audio playback, recording and format conversions, as well as for multitrack effect processing, mixing, recording and signal recycling. Ecasound supports a wide range of audio inputs, outputs and effect algorithms. Ecasound has a chain-based design that allows effects to be easily combined both in series and in parallel. Oscillators and MIDI-CCs can be used for controlling effect parameters. Includes a versatile console mode interface, a Qt-based X-interface and various command-line utils suitable for batch processing.</DIV> <P><B>Changes:</B> Support for 24- and 32-bit audio formats and for ALSA 0.5, multichannel noisegate, a new 2nd order lowpass filter, some ia-mode commands, and various bugfixes and low-level improvements. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164529.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/sound.html"><FONT COLOR="#FFFFFF">Console/Sound</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/931819147/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/931819147/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/931819147/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/07/12/931819147.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">SCEZ 20000129</FONT></B><BR> <SMALL><B><A HREF="mailto:m032@mbsks.franken.de">endergone Zwiebeltuete</A> - January 29th 2000, 11:46 EST</B></SMALL> <DIV ALIGN="justify"><P>SCEZ is a library that should make the handling of smart cards (not memory cards) and card readers as simple as possible and be at the same time small and easily portable. Currently supported are Dumb Mouse, CT-API and Towitoko readers and Schlumberger Cryptoflex, Gemplus GPK4000, GSM SIM and Telesec SigG cards. A PKCS#15 implementation is in the design phase. There are ports to PalmOS and MS-Windows available.</DIV> <P><B>Changes:</B> More card and reader drivers, and an application to read out GSM SIM card (phone book and SMS) and write it to the card. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164394.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: BSD type</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/development/libraries.html"><FONT COLOR="#FFFFFF">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/939677525/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/939677525/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/1999/10/11/939677525.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">Comicq 0.2.0</FONT></B><BR> <SMALL><B><A HREF="mailto:terminal6@submail.net">Terminal6</A> - January 29th 2000, 11:45 EST</B></SMALL> <DIV ALIGN="justify"><P>COMICQ is a command line ICQ messaging tool that allows a user to connect to ICQ using your UIN and password, then sends a message to the destination UIN.</DIV> <P><B>Changes:</B> Several bugfixes, icq99a compliance, and a new option --ip that allows you to get any user's IP by their UIN. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164350.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/communication.html"><FONT COLOR="#FFFFFF">Console/Communication</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/948389309/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/948389309/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="/appindex/2000/01/20/948389309.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">senv 0.2</FONT></B><BR> <SMALL><B><A HREF="mailto:kojak@ids.pl">Zbyszek Sobiecki</A> - January 29th 2000, 11:44 EST</B></SMALL> <DIV ALIGN="justify"><P>Senv allows you to run programs with a specified environment. It can set uid, gid, root directory, working directory, limits, and environment variables. It is useful in init scripts and as a shell for users for setting resource limits and environment variables. You can create sets of configurations and specify the one to use from command line.</DIV> <P><B>Changes:</B> Login shell limits and environment setting for users, permanent resource limits for specified groups of users and environment variables, and other minor bugfixes. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949164259.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: GPL</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/console/administration.html"><FONT COLOR="#FFFFFF">Console/Administration</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/944953892/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/changelog/944953892/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/12/11/944953892.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="97%" BORDER="0" BGCOLOR="#000000"><TR><TD COLSPAN="2"> <TABLE CELLSPACING="0" CELLPADDING="3" WIDTH="100%" BORDER="0" BGCOLOR="#FFFFFF"> <TR><TD><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B><FONT SIZE="+2">XZX 2.9.2</FONT></B><BR> <SMALL><B><A HREF="mailto:Erik.Kunze@fantasy.muc.de">E. Kunze</A> - January 29th 2000, 10:55 EST</B></SMALL> <DIV ALIGN="justify"><P>XZX is a portable emulator of ZX Spectrum 48K/128K/+3 (8-bit home computers made by Sir Clive Sinclair) and Pentagon/Scorpion (Spectrum clones made in Russia) for machines running UNIX and the X Window system. XZX is completely written in C and emulates Spectrum 48K, 128K, +2 and +3, Pentagon and Scorpion, Interface I with up to 8 microdrives, Multiface 128 and Multiface 3, BetaDisk 128 interface by Technology Research Ltd with 4 disk drives, +D interface by Miles Gordon Technology with 2 disk drives, Kempston mouse, Kempston joystick and built-in machine code monitor.</DIV> <P><B>Changes:</B> Lots of feature improvement and bug fixes. Most parts of the audio support has been rewritten for different UNICES. <P><B>Urgency:</B> low <P ALIGN="right"><B>[ <A HREF="/news/2000/01/29/949161354.html">comments (0)</A> ]</B> </FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN="middle"> &nbsp;<FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#FFFFFF"><B><SMALL>License: Shareware</SMALL></B><BR> <B><SMALL>&nbsp;Category: <A HREF="/appindex/x11/emulators.html"><FONT COLOR="#FFFFFF">X11/Emulators</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN="right"> <A HREF="http://apps.freshmeat.net/download/936956384/"><IMG SRC="image6" WIDTH="21" HEIGHT="21" BORDER="0" ALT="download"></A> <A HREF="http://apps.freshmeat.net/homepage/936956384/"><IMG SRC="image5" WIDTH="21" HEIGHT="21" BORDER="0" ALT="homepage"></A> <A HREF="http://apps.freshmeat.net/changelog/936956384/"><IMG SRC="image8" WIDTH="21" HEIGHT="21" BORDER="0" ALT="changelog"></A> <A HREF="/appindex/1999/09/10/936956384.html"><IMG SRC="image7" WIDTH="21" HEIGHT="21" BORDER="0" ALT="appindex record"></A> &nbsp; </TD></TR></TABLE> <HR WIDTH="0" SIZE="0"> <P><SMALL><CENTER><B>[ <A HREF="/news/2000/01/29/">full page for today</A> | <A HREF="/news/2000/01/28/">yesterday's edition</A> ]</SMALL></B></CENTER></FONT></TD><TD WIDTH="27%" VALIGN="top" ALIGN="center"><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">navigator</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/29/"><FONT COLOR="#000000">full page for today</FONT></A><BR> - <A HREF="/news/2000/01/28/"><FONT COLOR="#000000">yesterday's edition</FONT></A><BR> - <A HREF="news://news.freshmeat.net/"><FONT COLOR="#000000"><B>new:</B> fm news via NNTP</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">eye catcher</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <B>Free Shirts</B><BR>We give away a free freshmeat t-shirt every week for the best comment added to an application announcement or story posted on freshmeat. <P><B>#freshmeat</B><BR>If you want to chat about what's new on freshmeat and hang out with other fm lounge lizards and the fm staff, head over to #freshmeat on irc.freshmeat.net, part of <A HREF="http://openprojects.nu/">The Open Projects Network</A>. &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">site notes</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/29/949208399.html"><FONT COLOR="#000000">We should get this out of the door now (Jan 29th)</FONT></A><BR> - <A HREF="/news/2000/01/01/946704535.html"><FONT COLOR="#000000">freshmeat Y2K report (Jan 01st)</FONT></A><BR> - <A HREF="/news/1999/08/16/934862340.html"><FONT COLOR="#000000">Assorted freshmeat notes (Aug 16th)</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">recent editorials</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/29/949208340.html"><FONT COLOR="#000000">Is Linux for Crazies? (Jan 29th)</FONT></A><BR> - <A HREF="/news/2000/01/22/948603540.html"><FONT COLOR="#000000">A New Business Plan for Free Software (Jan 22nd)</FONT></A><BR> - <A HREF="/news/2000/01/15/947998740.html"><FONT COLOR="#000000">Is Linux Going to Reunite the UNIX Market? (Jan 15th)</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">andover.net</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> <BR><CENTER><A HREF="http://andover.net"><IMG SRC="image9" BORDER="0" WIDTH="150" HEIGHT="43" ALT="Mirror Logo"></A></CENTER><P> - <A HREF="http://www.animfactory.com/"><FONT COLOR="#000000">Animation Factory</FONT></A><BR> - <A HREF="http://www.davecentral.com/"><FONT COLOR="#000000">DaveCentral</FONT></A><BR> - <A HREF="http://www.freecode.com/"><FONT COLOR="#000000">FreeCode</FONT></A><BR> - <A HREF="http://www.InternetTrafficReport.com/"><FONT COLOR="#000000">Internet Traffic Report</FONT></A><BR> - <A HREF="http://www.ITManagersJournal.com/"><FONT COLOR="#000000">IT Manager's Journal</FONT></A><BR> - <A HREF="http://www.mediabuilder.com/"><FONT COLOR="#000000">MediaBuilder</FONT></A><BR> - <A HREF="http://slashdot.org/"><FONT COLOR="#000000">Slashdot</FONT></A><BR> - <A HREF="http://www.slaughterhouse.com/"><FONT COLOR="#000000">Slaughterhouse</FONT></A><BR> - <A HREF="http://www.techmailings.com/"><FONT COLOR="#000000">TechMailings</FONT></A><BR> - <A HREF="http://www.techsightings.com/"><FONT COLOR="#000000">TechSightings</FONT></A><BR> <BR><CENTER><B>E-Commerce</B></CENTER><P> - <A HREF="http://www.thinkgeek.com"><FONT COLOR="#000000">ThinkGeek (Stuff for smart masses)</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000">supported sites</FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://www.userfriendly.org"><FONT COLOR="#000000">Userfriendly.org</FONT></A><BR> - <A HREF="http://www.securityfocus.com"><FONT COLOR="#000000">SecurityFocus</FONT></A><BR> - <A HREF="http://copyleft.net"><FONT COLOR="#000000">copyleft</FONT></A><BR> - <A HREF="http://filewatcher.org"><FONT COLOR="#000000">Filewatcher</FONT></A><BR> - <A HREF="http://www.linux.com"><FONT COLOR="#000000">Linux.com</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org"><FONT COLOR="#000000">LinuxTelephony</FONT></A><BR> - <A HREF="http://www.linuxtoday.com"><FONT COLOR="#000000">LinuxToday</FONT></A><BR> - <A HREF="http://openprojects.nu/services/irc.html"><FONT COLOR="#000000">Openprojects</FONT></A><BR> - <A HREF="http://www.32bitsonline.com"><FONT COLOR="#000000">32bitsonline</FONT></A><BR> - <A HREF="http://www.gnu.org"><FONT COLOR="#000000">The GNU Project</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="/news/2000/01/29/"><font color="#000000">saturday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/29/949208399.html"><FONT COLOR="#000000">We should get this out of the door now</FONT></A><BR> - <A HREF="/news/2000/01/29/949208340.html"><FONT COLOR="#000000">Is Linux for Crazies?</FONT></A><BR> - <A HREF="/news/2000/01/29/949188564.html"><FONT COLOR="#000000">RabbIT 2.0.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949187896.html"><FONT COLOR="#000000">nmpg 1.1.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949187471.html"><FONT COLOR="#000000">mod_dtcl 0.7.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949187233.html"><FONT COLOR="#000000">CoreLinux++ 0.4.6</FONT></A><BR> - <A HREF="/news/2000/01/29/949165962.html"><FONT COLOR="#000000">scribe 0.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949165472.html"><FONT COLOR="#000000">E theme updater 0.1</FONT></A><BR> - <A HREF="/news/2000/01/29/949165416.html"><FONT COLOR="#000000">Powertweak-Linux 0.1.7</FONT></A><BR> - <A HREF="/news/2000/01/29/949164956.html"><FONT COLOR="#000000">Pexeso Beta</FONT></A><BR> - <A HREF="/news/2000/01/29/949164896.html"><FONT COLOR="#000000">XZX 2.9.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949164869.html"><FONT COLOR="#000000">DistroLib 0.4</FONT></A><BR> - <A HREF="/news/2000/01/29/949164843.html"><FONT COLOR="#000000">ToutDoux 1.1.7</FONT></A><BR> - <A HREF="/news/2000/01/29/949164772.html"><FONT COLOR="#000000">goMP 1.0.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949164633.html"><FONT COLOR="#000000">APSEND 1.40</FONT></A><BR> - <A HREF="/news/2000/01/29/949164529.html"><FONT COLOR="#000000">ecasound 1.6.12r10</FONT></A><BR> - <A HREF="/news/2000/01/29/949164394.html"><FONT COLOR="#000000">SCEZ 20000129</FONT></A><BR> - <A HREF="/news/2000/01/29/949164350.html"><FONT COLOR="#000000">Comicq 0.2.0</FONT></A><BR> - <A HREF="/news/2000/01/29/949164259.html"><FONT COLOR="#000000">senv 0.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949161354.html"><FONT COLOR="#000000">XZX 2.9.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949161036.html"><FONT COLOR="#000000">log4j 0.7.5</FONT></A><BR> - <A HREF="/news/2000/01/29/949156343.html"><FONT COLOR="#000000">SQN Linux 1.6</FONT></A><BR> - <A HREF="/news/2000/01/29/949156277.html"><FONT COLOR="#000000">Limo 0.3.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949156237.html"><FONT COLOR="#000000">Fusion GS 1.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949145887.html"><FONT COLOR="#000000">MMR 1.5.4</FONT></A><BR> - <A HREF="/news/2000/01/29/949142835.html"><FONT COLOR="#000000">KUPS 0.3.4</FONT></A><BR> - <A HREF="/news/2000/01/29/949142815.html"><FONT COLOR="#000000">3DSE patch for XMMS 4</FONT></A><BR> - <A HREF="/news/2000/01/29/949139763.html"><FONT COLOR="#000000">Linux 2.3.41</FONT></A><BR> - <A HREF="/news/2000/01/29/949139751.html"><FONT COLOR="#000000">Free Code for Linux S/390</FONT></A><BR> - <A HREF="/news/2000/01/29/949135979.html"><FONT COLOR="#000000">CircleMUD 3.0 beta patchlevel 17</FONT></A><BR> - <A HREF="/news/2000/01/29/949135938.html"><FONT COLOR="#000000">NiL Isn't Liero 000128</FONT></A><BR> - <A HREF="/news/2000/01/29/949135913.html"><FONT COLOR="#000000">OpenSSH Unix Port 1.2.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949135889.html"><FONT COLOR="#000000">KBoxes! 1.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949135867.html"><FONT COLOR="#000000">phpLanParty 0.23</FONT></A><BR> - <A HREF="/news/2000/01/29/949135509.html"><FONT COLOR="#000000">DGen/SDL 1.20</FONT></A><BR> - <A HREF="/news/2000/01/29/949135482.html"><FONT COLOR="#000000">EdcomLib 1.0 alpha 5</FONT></A><BR> - <A HREF="/news/2000/01/29/949135309.html"><FONT COLOR="#000000">Etherboot 4.4.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949135205.html"><FONT COLOR="#000000">BLADE 0.18.0</FONT></A><BR> - <A HREF="/news/2000/01/29/949135115.html"><FONT COLOR="#000000">Sapphire 0.13.7</FONT></A><BR> - <A HREF="/news/2000/01/29/949135070.html"><FONT COLOR="#000000">ippl 1.99.3</FONT></A><BR> - <A HREF="/news/2000/01/29/949134977.html"><FONT COLOR="#000000">Saint 1.5patch1</FONT></A><BR> - <A HREF="/news/2000/01/29/949134943.html"><FONT COLOR="#000000">Zircon 1.18.232</FONT></A><BR> - <A HREF="/news/2000/01/29/949134927.html"><FONT COLOR="#000000">nmap 2.3BETA14</FONT></A><BR> - <A HREF="/news/2000/01/29/949134901.html"><FONT COLOR="#000000">xterm patch #124</FONT></A><BR> - <A HREF="/news/2000/01/29/949134817.html"><FONT COLOR="#000000">MyThreads-Links v0.5.2</FONT></A><BR> - <A HREF="/news/2000/01/29/949134633.html"><FONT COLOR="#000000">sudo 1.6.2p1</FONT></A><BR> - <A HREF="/news/2000/01/29/949134552.html"><FONT COLOR="#000000">MIT Photonic-Bands 0.10</FONT></A><BR> - <A HREF="/news/2000/01/29/949134246.html"><FONT COLOR="#000000">Launcher 0.86</FONT></A><BR> - <A HREF="/news/2000/01/29/949134179.html"><FONT COLOR="#000000">nano 0.8.1</FONT></A><BR> - <A HREF="/news/2000/01/29/949134103.html"><FONT COLOR="#000000">Gtk-- 1.1.8</FONT></A><BR> - <A HREF="/news/2000/01/29/949134049.html"><FONT COLOR="#000000">tkchooser 0.65</FONT></A><BR> - <A HREF="/news/2000/01/29/949133420.html"><FONT COLOR="#000000">XShipWars 1.33a</FONT></A><BR> - <A HREF="/news/2000/01/29/949133280.html"><FONT COLOR="#000000">Lamerpad 0.1</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="/news/2000/01/28/"><font color="#000000">friday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/28/949117833.html"><FONT COLOR="#000000">fsv 0.9</FONT></A><BR> - <A HREF="/news/2000/01/28/949117711.html"><FONT COLOR="#000000">popsneaker 0.1.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949114716.html"><FONT COLOR="#000000">eyep-updater.sh 1.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949113240.html"><FONT COLOR="#000000">W3Mail 0.5.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949113214.html"><FONT COLOR="#000000">The Urgent Decision 0.9.9</FONT></A><BR> - <A HREF="/news/2000/01/28/949112269.html"><FONT COLOR="#000000">LTSP 1.02</FONT></A><BR> - <A HREF="/news/2000/01/28/949112198.html"><FONT COLOR="#000000">Production BASIC 0.2.12</FONT></A><BR> - <A HREF="/news/2000/01/28/949112123.html"><FONT COLOR="#000000">Postfix 19991231-pl03</FONT></A><BR> - <A HREF="/news/2000/01/28/949109732.html"><FONT COLOR="#000000">Mp3 Commander 0.7</FONT></A><BR> - <A HREF="/news/2000/01/28/949109324.html"><FONT COLOR="#000000">iManager 1.0.1b</FONT></A><BR> - <A HREF="/news/2000/01/28/949108399.html"><FONT COLOR="#000000">Eterm 0.9</FONT></A><BR> - <A HREF="/news/2000/01/28/949108308.html"><FONT COLOR="#000000">dqd_dirindex 1.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949108087.html"><FONT COLOR="#000000">Tidings 1.0.4</FONT></A><BR> - <A HREF="/news/2000/01/28/949108026.html"><FONT COLOR="#000000">localscan 2.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949107922.html"><FONT COLOR="#000000">WMKeyboard 0.3</FONT></A><BR> - <A HREF="/news/2000/01/28/949107834.html"><FONT COLOR="#000000">fcmp 1.0.2</FONT></A><BR> - <A HREF="/news/2000/01/28/949107767.html"><FONT COLOR="#000000">Akkord 0.3.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949107649.html"><FONT COLOR="#000000">HiM 0.1.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949106305.html"><FONT COLOR="#000000">cdrecord 1.8</FONT></A><BR> - <A HREF="/news/2000/01/28/949103400.html"><FONT COLOR="#000000">eMixer 0.05.5</FONT></A><BR> - <A HREF="/news/2000/01/28/949103187.html"><FONT COLOR="#000000">FreeVSD 1.4.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949103096.html"><FONT COLOR="#000000">Common C++ Libraries 0.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949095155.html"><FONT COLOR="#000000">Moonshine 1.0beta2</FONT></A><BR> - <A HREF="/news/2000/01/28/949095112.html"><FONT COLOR="#000000">swim 0.3.5</FONT></A><BR> - <A HREF="/news/2000/01/28/949095009.html"><FONT COLOR="#000000">Xmame/xmess 0.36b15.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949094448.html"><FONT COLOR="#000000">pcmcia-cs 3.1.9</FONT></A><BR> - <A HREF="/news/2000/01/28/949091509.html"><FONT COLOR="#000000">gPS 0.5.2</FONT></A><BR> - <A HREF="/news/2000/01/28/949091415.html"><FONT COLOR="#000000">Snort 1.5.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949090436.html"><FONT COLOR="#000000">Pygmy Linux 0.7 beta</FONT></A><BR> - <A HREF="/news/2000/01/28/949090237.html"><FONT COLOR="#000000">Intro to Bash Programming HOWTO 0.3</FONT></A><BR> - <A HREF="/news/2000/01/28/949084379.html"><FONT COLOR="#000000">GNU Pth 1.3b2</FONT></A><BR> - <A HREF="/news/2000/01/28/949084356.html"><FONT COLOR="#000000">Laonux 0.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949084304.html"><FONT COLOR="#000000">x-wvdial 0.12</FONT></A><BR> - <A HREF="/news/2000/01/28/949084188.html"><FONT COLOR="#000000">Intro to Bash Programming HOWTO 0.3</FONT></A><BR> - <A HREF="/news/2000/01/28/949084106.html"><FONT COLOR="#000000">Catalog 1.02</FONT></A><BR> - <A HREF="/news/2000/01/28/949084062.html"><FONT COLOR="#000000">harvest 1.5.20-kj-0.9</FONT></A><BR> - <A HREF="/news/2000/01/28/949068306.html"><FONT COLOR="#000000">wmseti 0.3.0a</FONT></A><BR> - <A HREF="/news/2000/01/28/949057272.html"><FONT COLOR="#000000">RIG 1.02</FONT></A><BR> - <A HREF="/news/2000/01/28/949057019.html"><FONT COLOR="#000000">FreeAddr 0.2</FONT></A><BR> - <A HREF="/news/2000/01/28/949056939.html"><FONT COLOR="#000000">GtkAda 1.2.5</FONT></A><BR> - <A HREF="/news/2000/01/28/949056664.html"><FONT COLOR="#000000">dot.conf 0.6.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949055099.html"><FONT COLOR="#000000">dep.pl 1.28.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949054980.html"><FONT COLOR="#000000">Prae's Scripts 1.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949044301.html"><FONT COLOR="#000000">Project Clock 0.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949044285.html"><FONT COLOR="#000000">Xtheater 0.2.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949040013.html"><FONT COLOR="#000000">i-no Chart 0.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949039945.html"><FONT COLOR="#000000">spliff 0.8.1</FONT></A><BR> - <A HREF="/news/2000/01/28/949038953.html"><FONT COLOR="#000000">Regexx 0.95</FONT></A><BR> - <A HREF="/news/2000/01/28/949038316.html"><FONT COLOR="#000000">RBook 0.5.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949036742.html"><FONT COLOR="#000000">RIG 1.01</FONT></A><BR> - <A HREF="/news/2000/01/28/949036714.html"><FONT COLOR="#000000">wchat 1.2.0</FONT></A><BR> - <A HREF="/news/2000/01/28/949036428.html"><FONT COLOR="#000000">PCCS MySQLDatabase Admin Tool 1.2.2</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="/news/2000/01/27/"><font color="#000000">thursday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="/news/2000/01/27/949033332.html"><FONT COLOR="#000000">CADUBI 1.1b1</FONT></A><BR> - <A HREF="/news/2000/01/27/949032987.html"><FONT COLOR="#000000">Angus' Chess Clock 0.8.1</FONT></A><BR> - <A HREF="/news/2000/01/27/949032555.html"><FONT COLOR="#000000">MP3 Report Generator 1.0.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949032518.html"><FONT COLOR="#000000">4DOM 0.9.2</FONT></A><BR> - <A HREF="/news/2000/01/27/949032386.html"><FONT COLOR="#000000">4XSLT 0.8.2</FONT></A><BR> - <A HREF="/news/2000/01/27/949031346.html"><FONT COLOR="#000000">OpenNaken 1.10</FONT></A><BR> - <A HREF="/news/2000/01/27/949025747.html"><FONT COLOR="#000000">iManager 1.0b</FONT></A><BR> - <A HREF="/news/2000/01/27/949025168.html"><FONT COLOR="#000000">QuakeForge 0.1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949023271.html"><FONT COLOR="#000000">pylice 0.7.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949023250.html"><FONT COLOR="#000000">Solfege 0.6.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949023151.html"><FONT COLOR="#000000">xinetd 2.1.8.7p1</FONT></A><BR> - <A HREF="/news/2000/01/27/949022849.html"><FONT COLOR="#000000">jac 0.13</FONT></A><BR> - <A HREF="/news/2000/01/27/949022803.html"><FONT COLOR="#000000">Xmms 1.0.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949022319.html"><FONT COLOR="#000000">KSrnd 0.97</FONT></A><BR> - <A HREF="/news/2000/01/27/949021877.html"><FONT COLOR="#000000">getpg / UW-IMAP 0.54</FONT></A><BR> - <A HREF="/news/2000/01/27/949021849.html"><FONT COLOR="#000000">getpg 0.53</FONT></A><BR> - <A HREF="/news/2000/01/27/949021824.html"><FONT COLOR="#000000">setserial 2.17</FONT></A><BR> - <A HREF="/news/2000/01/27/949021250.html"><FONT COLOR="#000000">Pan 0.7.3</FONT></A><BR> - <A HREF="/news/2000/01/27/949021216.html"><FONT COLOR="#000000">jwhois 2.4.1</FONT></A><BR> - <A HREF="/news/2000/01/27/949021126.html"><FONT COLOR="#000000">Kmp3 1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949020964.html"><FONT COLOR="#000000">xPine 0.0.12</FONT></A><BR> - <A HREF="/news/2000/01/27/949019905.html"><FONT COLOR="#000000">Avenger's News System 2.1 Alpha</FONT></A><BR> - <A HREF="/news/2000/01/27/949019709.html"><FONT COLOR="#000000">RIG 1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949019321.html"><FONT COLOR="#000000">scroller 1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/949018347.html"><FONT COLOR="#000000">Perl EyeP Client 0.1</FONT></A><BR> - <A HREF="/news/2000/01/27/949017796.html"><FONT COLOR="#000000">sfront 0.54</FONT></A><BR> - <A HREF="/news/2000/01/27/949017631.html"><FONT COLOR="#000000">XFrisk 1.2</FONT></A><BR> - <A HREF="/news/2000/01/27/949016202.html"><FONT COLOR="#000000">Moffy 0.0.1</FONT></A><BR> - <A HREF="/news/2000/01/27/949015348.html"><FONT COLOR="#000000">Solid POP3 0.14</FONT></A><BR> - <A HREF="/news/2000/01/27/949014200.html"><FONT COLOR="#000000">php3guest 1.5</FONT></A><BR> - <A HREF="/news/2000/01/27/949013630.html"><FONT COLOR="#000000">crUD 01.27.2000</FONT></A><BR> - <A HREF="/news/2000/01/27/949013380.html"><FONT COLOR="#000000">crUD 01.27.2000</FONT></A><BR> - <A HREF="/news/2000/01/27/949012979.html"><FONT COLOR="#000000">Free Pascal Compiler 0.99.14</FONT></A><BR> - <A HREF="/news/2000/01/27/949012771.html"><FONT COLOR="#000000">gtk-font-hack 0.2-gtk-1.2.6</FONT></A><BR> - <A HREF="/news/2000/01/27/949009233.html"><FONT COLOR="#000000">Linux 2.2.15pre5</FONT></A><BR> - <A HREF="/news/2000/01/27/949005620.html"><FONT COLOR="#000000">krunseti 0.2.1</FONT></A><BR> - <A HREF="/news/2000/01/27/948996446.html"><FONT COLOR="#000000">CompuPic 5.0.1036</FONT></A><BR> - <A HREF="/news/2000/01/27/948995905.html"><FONT COLOR="#000000">gfontview 0.3.3</FONT></A><BR> - <A HREF="/news/2000/01/27/948995819.html"><FONT COLOR="#000000">authlocal 1.0.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948995600.html"><FONT COLOR="#000000">bigwig 1.1</FONT></A><BR> - <A HREF="/news/2000/01/27/948995501.html"><FONT COLOR="#000000">CAFire 0.0.11</FONT></A><BR> - <A HREF="/news/2000/01/27/948995429.html"><FONT COLOR="#000000">ANVLOGIN 2.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948994944.html"><FONT COLOR="#000000">sawmill.el 1.9</FONT></A><BR> - <A HREF="/news/2000/01/27/948994810.html"><FONT COLOR="#000000">Perlsh 20000127</FONT></A><BR> - <A HREF="/news/2000/01/27/948994776.html"><FONT COLOR="#000000">sitescooper 2.1.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948994691.html"><FONT COLOR="#000000">MHDns 1.4</FONT></A><BR> - <A HREF="/news/2000/01/27/948994419.html"><FONT COLOR="#000000">JChemPaint 0.5</FONT></A><BR> - <A HREF="/news/2000/01/27/948994364.html"><FONT COLOR="#000000">Filesystems HOWTO 0.7.3</FONT></A><BR> - <A HREF="/news/2000/01/27/948994343.html"><FONT COLOR="#000000">KSnes9x 1.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948993513.html"><FONT COLOR="#000000">Mozilla M13</FONT></A><BR> - <A HREF="/news/2000/01/27/948993439.html"><FONT COLOR="#000000">edna 0.3</FONT></A><BR> - <A HREF="/news/2000/01/27/948993409.html"><FONT COLOR="#000000">GMasqdialer 0.99.8</FONT></A><BR> - <A HREF="/news/2000/01/27/948993341.html"><FONT COLOR="#000000">spliff 0.8</FONT></A><BR> - <A HREF="/news/2000/01/27/948992808.html"><FONT COLOR="#000000">MultiSeti 0.3</FONT></A><BR> - <A HREF="/news/2000/01/27/948970667.html"><FONT COLOR="#000000">rude 0.50</FONT></A><BR> - <A HREF="/news/2000/01/27/948970605.html"><FONT COLOR="#000000">cgi-util++ 0.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948970479.html"><FONT COLOR="#000000">Cricket 0.72</FONT></A><BR> - <A HREF="/news/2000/01/27/948970458.html"><FONT COLOR="#000000">nuni 0.04</FONT></A><BR> - <A HREF="/news/2000/01/27/948970379.html"><FONT COLOR="#000000">Ksetiwatch 0.3.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948970358.html"><FONT COLOR="#000000">SiteMgrYAP 0.1.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948970322.html"><FONT COLOR="#000000">phpLanParty 0.21</FONT></A><BR> - <A HREF="/news/2000/01/27/948970285.html"><FONT COLOR="#000000">Glitter Newsreader 0.1</FONT></A><BR> - <A HREF="/news/2000/01/27/948970263.html"><FONT COLOR="#000000">Fastresolve 2.4</FONT></A><BR> - <A HREF="/news/2000/01/27/948970164.html"><FONT COLOR="#000000">ColdSync 1.1.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948970080.html"><FONT COLOR="#000000">DDD 3.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948970032.html"><FONT COLOR="#000000">X Northern Captain 4.2.1</FONT></A><BR> - <A HREF="/news/2000/01/27/948969919.html"><FONT COLOR="#000000">abcde 1.0.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948969659.html"><FONT COLOR="#000000">Gnapster 1.3.2</FONT></A><BR> - <A HREF="/news/2000/01/27/948969551.html"><FONT COLOR="#000000">xmix 1.0 Alpha</FONT></A><BR> - <A HREF="/news/2000/01/27/948969488.html"><FONT COLOR="#000000">gtktetcolor 0.3</FONT></A><BR> - <A HREF="/news/2000/01/27/948969412.html"><FONT COLOR="#000000">muttzilla 0.40</FONT></A><BR> - <A HREF="/news/2000/01/27/948969395.html"><FONT COLOR="#000000">muttzilla 0.40</FONT></A><BR> - <A HREF="/news/2000/01/27/948969337.html"><FONT COLOR="#000000">asp2php 0.73.6</FONT></A><BR> - <A HREF="/news/2000/01/27/948969217.html"><FONT COLOR="#000000">mod_ticket 1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948969078.html"><FONT COLOR="#000000">MegaHAL for Eggdrop .01</FONT></A><BR> - <A HREF="/news/2000/01/27/948968456.html"><FONT COLOR="#000000">Jetty 2.3.5</FONT></A><BR> - <A HREF="/news/2000/01/27/948968386.html"><FONT COLOR="#000000">xlpotdb 1.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948968341.html"><FONT COLOR="#000000">Koala Complete MUD Server 0.1.1a</FONT></A><BR> - <A HREF="/news/2000/01/27/948968255.html"><FONT COLOR="#000000">mcountd 0.4</FONT></A><BR> - <A HREF="/news/2000/01/27/948967933.html"><FONT COLOR="#000000">cdbackup 0.5.0</FONT></A><BR> - <A HREF="/news/2000/01/27/948967908.html"><FONT COLOR="#000000">The Java SSH/Telnet Application/Applet 2.0 RC1</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://slashdot.org"><font color="#000000">slashdot</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://slashdot.org/article.pl?sid=00/01/29/1534255"><FONT COLOR="#000000">Petition Apple for Linux QuickTime</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/29/1223249"><FONT COLOR="#000000">GNUstep 0.6.5 freeze</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/28/2324203"><FONT COLOR="#000000">YETI@Home</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/29/1024215"><FONT COLOR="#000000">Documents Unsealed in Microsoft/Caldera Case</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/29/0837235"><FONT COLOR="#000000">Who Bought Linux.Net?</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/24/1146250"><FONT COLOR="#000000">E-Mails from (Over?) The Edge</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/29/0834223"><FONT COLOR="#000000">Linux Kernel 2.3.41</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/28/2311232"><FONT COLOR="#000000">Congress Still Figuring Out E-Mail</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/22/1946244"><FONT COLOR="#000000">Sci Fi Literature 101?</FONT></A><BR> - <A HREF="http://slashdot.org/article.pl?sid=00/01/28/2318246"><FONT COLOR="#000000">Could Distributed.Net Help the Mars Polar Lander?</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://www.securityfocus.com"><font color="#000000">securityfocus</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/zdnn/stories/news/0,4586,2429334,00.html?chkpt=zdnntop"><FONT COLOR="#000000">Win2000 security hole a 'major threat'</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.computerworld.com/home/print.nsf/all/000128e45a"><FONT COLOR="#000000">Visa acknowledges cracker break-ins</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/sr/stories/column/0,4712,2429536,00.html"><FONT COLOR="#000000">What's Wrong With Microsoft Security?</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/pcweek/stories/news/0,4153,2429334,00.html"><FONT COLOR="#000000">Microsoft posts first Win2K security patch</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=tools&id=1018"><FONT COLOR="#000000">Libnids 1.12</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.theregister.co.uk/000127-000005.html"><FONT COLOR="#000000">New hack attack is greater threat than imagined</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=news&id=http://www.mercurycenter.com/svtech/news/indepth/docs/hacker012700.htm"><FONT COLOR="#000000">Student charged with hacking</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=library&id=63"><FONT COLOR="#000000">Building and Managing Virtual Private Networks (book)</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=library&id=111"><FONT COLOR="#000000">Threats, Vulnerabilities and Real-Worl Responses: The Foundations of the TruSecure Process</FONT></A><BR> - <A HREF="http://www.securityfocus.com/level2/?go=library&id=1701"><FONT COLOR="#000000">The Hundredth Window : Protecting Your Privacy and Security in the Age of the Internet (boo</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://www.bebits.com"><font color="#000000">bebits</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://www.bebits.com/app/706/"><FONT COLOR="#000000">Pe 3.0a3</FONT></A><BR> - <A HREF="http://www.bebits.com/app/757/"><FONT COLOR="#000000">Rarscript 1.5</FONT></A><BR> - <A HREF="http://www.bebits.com/app/736/"><FONT COLOR="#000000">CD Manager 0.66a beta</FONT></A><BR> - <A HREF="http://www.bebits.com/app/174/"><FONT COLOR="#000000">TraX 1.1</FONT></A><BR> - <A HREF="http://www.bebits.com/app/785/"><FONT COLOR="#000000">BeMath 1.2.2</FONT></A><BR> - <A HREF="http://www.bebits.com/app/784/"><FONT COLOR="#000000">simple blackjack 1</FONT></A><BR> - <A HREF="http://www.bebits.com/app/758/"><FONT COLOR="#000000">HtmlTree 0.5.3</FONT></A><BR> - <A HREF="http://www.bebits.com/app/783/"><FONT COLOR="#000000">Yacp 0.1</FONT></A><BR> - <A HREF="http://www.bebits.com/app/222/"><FONT COLOR="#000000">TicTacToe 1.5</FONT></A><BR> - <A HREF="http://www.bebits.com/app/706/"><FONT COLOR="#000000">Pe 3.0a2</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://linuxtoday.com"><font color="#000000">linuxtoday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://linuxtoday.com/story.php3?sn=15878"><FONT COLOR="#000000">Linux Journal: KDE--The Next Generation</FONT></A><BR> - <A HREF="http://linuxtoday.com/story.php3?sn=15876"><FONT COLOR="#000000">Kernel Cousin gimp-devel #11 Is Out</FONT></A><BR> - <A HREF="http://linuxtoday.com/story.php3?sn=15875"><FONT COLOR="#000000">Infoworld: Corel Linux OS ideal for the desktop</FONT></A><BR> - <A HREF="http://linuxtoday.com/story.php3?sn=15874"><FONT COLOR="#000000">Technology Evaluation: IBM Jumps on the Linux Bandwagon with Both Feet, Sort Of</FONT></A><BR> - <A HREF="http://linuxtoday.com/story.php3?sn=15873"><FONT COLOR="#000000">Tobias Hövekamp: European Union acknowledges</FONT></A><BR> - <A HREF=""><FONT COLOR="#000000">&</FONT></A><BR> - <A HREF=""><FONT COLOR="#000000">#34;Open Source Software</FONT></A><BR> - <A HREF=""><FONT COLOR="#000000">&</FONT></A><BR> - <A HREF=""><FONT COLOR="#000000">#34;</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://www.linuxtelephony.org"><font color="#000000">linuxtelephony</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=208&r=0"><FONT COLOR="#000000">Traverse Technologies releases NETspider-U in US</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=207&r=0"><FONT COLOR="#000000">Quicknet releases new GPL'd Linux Drivers!</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=206&r=0"><FONT COLOR="#000000">Natural Microsystems Delivers Carrier-Class Linux</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=205&r=0"><FONT COLOR="#000000">Quicknet is hiring programmers of all kinds!</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=204&r=0"><FONT COLOR="#000000">Babylon MLPPP Software Released under GPL</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=202&r=0"><FONT COLOR="#000000">Linux Telephony Server Project?</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=203&r=0"><FONT COLOR="#000000">Vovida Networks to Hire Telephony Software Engineers</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=200&r=0"><FONT COLOR="#000000">SPIRO-Linux Introduces Web-Enabled Phone Administration</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=199&r=0"><FONT COLOR="#000000">LinuxTelephony sponsors area at LinuxFest 2000</FONT></A><BR> - <A HREF="http://www.linuxtelephony.org/article.cgi?i=198&r=0"><FONT COLOR="#000000">GSM-Mobile Switching Center (MSC) with Linux-PC</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <TABLE BORDER="0" CELLPADDING="1" CELLSPACING="0" BGCOLOR="#000000" WIDTH="97%"><TR><TD> <TABLE WIDTH="100%" BORDER="0" CELLSPACING="1" CELLPADDING="3"> <TR><TD ALIGN="center" BGCOLOR="#EEEEEE"><B><FONT FACE="Lucida,Verdana,Helvetica,Arial"><FONT COLOR="#000000"><a href="http://www.32bitsonline.com"><font color="#000000">32bitsonline</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR="#FFFFFF"><SMALL><FONT FACE="Lucida,Verdana,Helvetica,Arial"> - <A HREF="http://www.32bitsonline.com/article.php3?file=issues/200001/homeworld&page=1 "><FONT COLOR="#000000">Game: Homeworld</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001271a&page=1 "><FONT COLOR="#000000">DVD Lawsuit Spreads Its Own 'Trade Secrets'</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001272&page=1 "><FONT COLOR="#000000">Register.com Adds 'One-step' Domain Registration</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/article.php3?file=issues/200001/webevent&page=1 "><FONT COLOR="#000000">WebEvent: Keeping you organized</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001273a&page=1 "><FONT COLOR="#000000">Y2K Officers Defend $100 Bil Investment</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/article.php3?file=issues/200001/jan2000_john_berger&page=1 "><FONT COLOR="#000000">DON'T BE FOOLED</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001274&page=1 "><FONT COLOR="#000000">Microsoft Scorns Think-Tank's Breakup Idea</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001275a&page=1 "><FONT COLOR="#000000">Yahoo Accused Of Stalking Internet Users</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/news.php3?news=news/200001/nb200001276a&page=1 "><FONT COLOR="#000000">eToys.com Settles Spat With Swiss Artist Group</FONT></A><BR> - <A HREF="http://www.32bitsonline.com/ "><FONT COLOR="#000000">[more articles/news]</FONT></A><BR> &nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P> <BR><BR></FONT> </TD></TR></TABLE> <TABLE WIDTH="100%" CELLPADDING="0" CELLSPACING="0" BORDER="0"> <TR BGCOLOR="#000000"><TD><IMG SRC="image4" WIDTH="1" HEIGHT="2" ALT=""></TD></TR></TABLE> </CENTER> <TABLE CELLSPACING="0" CELLPADDING="2" WIDTH="100%" BORDER="0"><TR> <TD VALIGN="top" ALIGN="center"><FONT FACE="Lucida,Verdana,Helvetica,Arial"><SMALL>copyright © 1997-2000 <A HREF="http://andover.net">Andover.Net</A> - icons courtesy of <A HREF="mailto:tigert@gimp.org">tigert@gimp.org</A> - code revision <A HREF="http://freshmeat.net/ChangeLog">20000101</A> - our <A HREF="http://www.andover.net/privacy.html">privacy policy</A></SMALL></FONT></TD> </TR></TABLE> </BODY> </HTML> ������������������./saods9/htmlwidget/tests/page4/image4��������������������������������������������������������������0000644�0001750�0001750�00000000075�07504443353�016517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��€ÿ�ÀÀÀ���!ù����,�������D�;�,�������L�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image2��������������������������������������������������������������0000644�0001750�0001750�00000034007�07504443353�016517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aÔ<�Õ*������!!!!)))))1Z11111R999BBBR9RRRcZ”cccsssss„„„„”””œœœ¥{­­­µµµ½­­½½½Æ”ÆÆÆÎ�)ÎÎÎÖÖÖÞ­!ÞÞÖÞÞÞçççïïï÷µ�÷Ö)÷÷÷ÿÿÿtsu������������������������������������������������������������tsu!ÿ NETSCAPE2.0���!ùP�?�,����Ô<��þ�H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµ*Ê (0`+Ö¬ŠK¶lCY(àʶkµjU<0K·®Ý¦hÕ¶õÊ·­Ú*î L8çV­\½ðÊuqâ¶æžL¹²Ék3v˹­cÌ–C‹móÞÓ›ÿE¼•´ë×° šîKû1g*$Èí»·ï³m7¦Ý·… r,îú»¹s²z9×ÖìW… ²¶}ν;ÔÌÔ7þ§°0öìÑ„õξ=Qµãm¦ 8{ZÖÜëßÏóüÎ�ÇU^™yÆßÒÄÚxâ œt‰­—à„ž”Ù|.‡ZxmqUᇠz„ƒ¶§a€†¨âŠE—!‰0n¶‹4ÖÈPVÓ}& €‡-¸c~6)$�ÚÑ]ƒÒÁ…£ƒoíYd‚ô¤dM9ä•-IžW9È%`‘¡••Ž|íT™%P š%$Ä&–pNTä[õ=@€–¡uÜ|Z`§¶¦›j~ô&B‡Æ©hCZªÀç~ÂW¢>Z‚Z‘h&š…z”¨AVŽd]˜^”Û©º)ðÒ¨¥*tj”þ�ছ@¼*P}ª&$k§¡Je}r1´«@¶VyÜu`Édr¹BTäTŠ\‰@ké™|J€ä€ƒrªVÖe«@˪Ь@‡~&‘Oô¤ªÆi+[¸s…j lž;›lZ0®Iø¢©¯Ahª@ÁD¢�œÉë@[Л D1C£{æ¿ð[Âÿ¦0¡-éhÃh~ÀÚb tìñÇø¨ØÀ4‘ŒÐ æ�(÷+á¡.V¢hbÇo® ô\‚£Ø"„²Ÿ!?”²Ò «ôt² !,›À�]zh"àê™3tt¬/-r—0.ÎVôKLÝ´³kµŒmþÏ`17𤦬‚Œ\vëðÍ/®žÒiðfÐ ·Ý¦ä—Íxã%íp³»JW­X¤ðâdÔ9¹j™ž:êÍ‚›Ý@˜i…›Z(gëê±çª5A(¦4VhÂ^'Äd 4k\;�ø¢\1­u¶_Ûãºü5óJyn¡ÇŽ™¹¹«®ôÜÃßìp ÀÁCt~à `¶ J€¦Ô÷4µ‡žæA<óÖßž72PqlYä$g1Á) mœz@ÏžW~Iì€ÞrÜÇ\6°Ñ1¬t<Áv&UÕícÄâWä"v¦ XPƒnKØ¥¨gë±Scž Ã0¥iï þ{›aÇ\ˆB¾ÐˆeÛñ°5Ù0na,,AÌvÂŽ [<$[ Õ“ºFä-w‚ÔVŽW»Ø`dàŠn\¦2%O&6+ÈßÊÖ5®õ isƒ!¿ÔD´°‘ðLFœ!‹XÁ~}pƒ\S!™Ø3í9/hh9“öþ¸U[rCáÓôB„Á-‰í“#¶f¿Kñ’qóâï¸È4ï„éû£Ÿ–—C%ÒêrþÈÕh¹Ç:þï“2Ô™*{9 =L!Z‘àà°F‡a&+¥´�[ž„2m…ç1‰#AFöC_þ/QU|^â(¨Ç’ܤUÊ�XÆ¿…Åz0¼à"s¼öÁ³aþƒœ/ò¼Cf²Ë“åÉÒÁp\7DY�ùTBêÒa=À‘‡ª¡} g ûž÷ÌXõ‰44È�‚¸`Þªih\0GØÏÚ¥t›Ø›D֢̭@ n`!À_$YœS§I9ÑæKÐMcêq= ¥\Í9¹r2’äZçAP&¶Æ’kˆb"©’eÕ¦q°…%l(_–ƒ> 4æA§z1’Æ0qK‹¦@¬wE‹‚ [(¼[¬ãC®UWL+á&ß”Ã(Ô p-« yw&™Î3b´éÁt´4Ìšqfeä¿ó J-R=d *CAöë†1tªjß”Ð4ê“­%PþUWóÊyVm‰e‹%û\@—I¦h¤:Öäj؆®U­¶œ+›&™6à^g«Äu™ÑæÕ’6­Š~:¥_“-¢ž´±=<Ö±üŠ[’-¸Ð5«»rÓ"®D‹5Iã�N ßú~@[ÃÑQÃ#(œÀõp=Ën¨Xã²é%]mð(Úœ9­±ƒT<“kÎÛFµ¡ð­ÄHºÍÞ >…=¤L‹¦9)†´ W[éa"X`7äJ½5ã"z¸–µ-&ý‰,ÆJ;äUgh[œ–Z©w®¤ŠÚ·ƒ/½E¾'ˆ²”£,_ø–2M(ê¯Mþû¿¦LBƒ•$S…ÜÐ>žÓ©!|­þAP–+Èù˜Âm³°rñ*´î†tijóŒ§^6ÏùˆFmq§g,^™bÿjÚ íZÚù‰Ç©Í\âÆF".-Èîf¡…F\ÑåØ}\‘`š0ß)›ZÊiñÚO;êßÿJf¤üª�¬D2>.Ø›3sSÁ -ä…óÁhµsLOL°Œ"d•Ž­âzüì.¥å2ÄT%—ó0jÚO“™Žhl¶ÏŒH©a·RyàÆµ\!ý/Zv$u¥éh:%šûRY\¬9•ŒL¯tŒ¾§Î·©é¨Ã(áKˆ÷LÒ2ô\˜ xGN‘ÏI$v$qøAV‡‘éa$àÁ¸E$>@aÊú¹”þ9À£ü&µY Z7õ!ÖÔWä0§ïgÈ$]ÎÇ,Qf^s˜gªCn™¬cMïœëGv<﹩¡ÌåÊCªlÑ~ô'—ZéS~yÓM¤eª{ý7H¿:ÖANå‰çëh{tJv‘×·íòåL‘“öº¿&Shi{¾ß.vùÚÉÞ(2ÔíNxËèZIÏ:ß—Î>ý\Ç’�[ OyÊ€oˆ|ϼØé;_|º’K£2×à+Oz»ˆÞ~JüÞå«´T�2ÏÜèKOû±€õ©W=çå[k}ìó‡<Ôf_ûâO,{ý}î5o_ß­C’*“ñ§ÑóÙó`>zxï|B==èÔSoä½õ ½ÑªÔÍÉt M]üð× ù �9õÛŸ¡\îÿ¼ÿþeN%f~÷·~•tÔâØGâV0c èjœ1st—€hà‘|9S)éÇe3¸‚116E€•Â/ÓFû7y ��!ù´�?�, ��½5��þ�H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜÈQ  ˆ Ò@Ç“(Sª\ɲ¥Ë—0cB,‰@A‘# 0 `„2ƒ J´¨Ñ£H'x À�ÎDF)€€ $$Ýʵ«×¯`‘°ú´¬Ù <�¶­Û·pã¾5À`ªÔ»PGÚ-pSä‚�r L¸ðEgËÚ@—b¨ KžL¹²Û žNÝl³ 8 زéÓ¨S£0:ob»Q1K¨PA‚cªªsëÞÍÛàmœœ]—•M»Âƒßz+_μ0k¼‰¡PKôqQDnν»÷¤ Zþ»¾xªìÐŽwâþξ½û• G.óõôµ¿ßÏ¿¿Ä¦éÝDžY± 6Içß‚ 6È@|P„H ž^Р–ðd6ÞBG›IC•X[ ©H‹ Æ(£@pØáJ pàˆ#}‘¦P72@‘V°’%(9ã“ P>VÐWpLIåVФ_BL–`äPL: &—P¦ÙŸnÉe#eéæèXß8Ž)T™$F¡VjÊmÎÙ¡›…9ç"¢ˆP˜zŧ ”Ρ¡tŠg@¡˜~PTxÙÐ�%‚X[¤iX©`Фþ�<�Ú¬@eEë@¶‚檆¦¢ �¯@³ÚVé±I€§†Öy›˜vø¡ PÚA2¤è„Œ¦jc•Û 4)8~à*¬Lfå# âúâì"+¯P ,Ë쇴}ëa—Œ]Úa°«Þûaf„ûjž ié&Œ„ΉA¸|6,­«� {£¾7¢øÀ–œÆ[½^T쬾Êr°%4«Á�ä*± i ZÊÙ #˜· $«u Ù,.h,Tj°$‡Ôƒ Zس½\‡•¬m,R½Q£÷´ÂJMÀgŠÚµ´Ëâˆâ�̆f»ZÉ)YŒ©V0»¥Çm{]Ñ–“i7þB:Zs‡‘mœ£@mÞüq’ ÑI£âK"@ßaì¡ÑE)jxATZÁk÷�‡MÀçbàùZŽ p„¦‹ä÷á{7¼  ¯“L𫳨hS¸¶Ánÿ«Àk·Œ£Õb]ÝÙhåIÛñPνä С‘ c0,ö:~}ÆÆKËÐç ¾ÐÜÊš¶QHÏ-‰ Fèaf < Âgž/Û:©þóÜgTpœ4Œuÿ{ʆr™WŒÓŒ$Ø;*¡*x* “¼'¸ù dz¾)œ£lF9¬8%4ÐSßàfWïÕÌ:Fà ¶#C\ae K™Ùv0Ã�Ù`E„þ-ÃJdxˆ¢QŒ 6Ò §àÀàpg3DÛæ>£ÀpkB@éQÔžh=Q…%8â@´ä“™©eÖq}øE`Åh9´Í±âCÁ}€5ëKÕªÂf%º¬¥‹ HHW§ñï:rúP°Fƒ€¯Mˆf°€�pä*ÞÕí}sìÄ«¶0“˜Ö˜÷£aaŒ-ܲ‘¯E8 ™G@Qå÷ù+†é&!K 9Á¹0�ÐR!aI¤2–+—WdåARÙ$�pHKNåŤF"ÉS­"ȦŽ'E ÅoBCìPrn‰Ì&¹²1Rò`B°Ç?±&;ŽNÆ”¥$Íñþ¼ ›ɯ*VPLŽ<ããnTIò]ÒqÛºŒ0h&Oz/’£\æ4mä©í ôùתXIQ…åopT’à´bÇqK�aòä'{éÊ‹ŠqwÒe’’«öA¥ò›P¹¥ÅI–À޳lñ°J'Ñ dW+…Z8iÕF@œHmzÒ”$� »ÜÇÚ©#vA¼*äÕ*Ä9Ôõp�l2•ãH€"Ä¡ÚÄ`8©ˆ:5™Ü¢CÙ÷¯šb� ,È6Š™“qï{)ËÅDà 3�¥s¦ù´ä*¨.U]:MÎ`³yT_V3UÒšPRíPËö‘DºcR——+ä ”Q9Òþ© @ÖÐT—ŸEª¿úÚD˜>´oF“ªdK`Ó¶ ³Ä…^ji¦Í|-’124!±‚5ž¬J´îmTgªÍ夭�3щ`I§ºkfZí„ðÏ °“gsjC§Y€ã%›9.(]Ô±—o©$ZdŠ S'jé›ZjØ/çFàÒò¢&ñ¬Kó;Må%ÇM qœ0™d’“^щ³ÝÐôp;a„0Z:U›öKÈz¨¾Ÿ¼èºLý:d6«zcj‚˜ÕÆ@v�Ž3Þ *¥ªpÚê&#éëDZjùÒ–¿'4ÆaBÑ^aÚRåÍ !úm°giÅÁÁŽ¿ç¤þhKGÔ‹†÷E$¾,]%a2다ŒÓ¨‰Ü×ÌÃ6‰Iuâ·”4¿Ášî¶Ž¦½�å@1¥V¼JŠs7 Æ7GÒ: Dˆ•/ ÕG@ªªÀB@ê\ :£á‹ë6T8ùó®Mþ•ÜJ9FLéiRïÅr|;9ÍaÍ:°Ñï7‰;\BOH±e^huZì¥~ruÛ¡i¬ô)¾Óº•ÊmZp±u#öÂØqÒ¾Z¹…•]n~H º[Šè>µ 5�V×ÄÈ4¦œý¶‡nj÷‰ BvB8]Çð….* ÍNÀðúÔ§2ÀÁðVãÅ)á‹Ö˜$F¥¼ÄËÒZh|þUšÅ]¼×¿z²I•i¯Ž[%6€•m—¿¸wµ e£7ê!œþÛÚczrKÉÜèhZ›ÒSæù·uG‰:±ÑÞwAÆJ³ÑøíhÕ«-J–>(„#‚Vצs —ÀÂîðRÏ&4k©xm°KŸdÜÖAkÙ´Z¯r}j“?çÔÒMJ¸Äf‘±kËìgoÎ9!,/Ö0 ÆwÛXgkÃw,1ØÆøÝÑ|™ù‹•“ê÷°}ÍùÕè_¸µú±Âñ˜æku¢&æ�G¡þKó%}DrX›¹«íÈoøfUüÐ\('\ëƒf�4FàAa'züþ¦ø†¼ûù¾E“ÂQ9¦%äGˆN¨/º¼zÓ&<ˆÏ‘ô·$<ÈŸÚCüþ;ü˧v€Â1v· úæVö^óÒ€Hp�£ÆþWlwH R6ctøBXjX‚ç�Á ¢R>‚K ø‚A0h‚ÈGj'¨q#¾ç.ïƒ@Ø @�Pj5hƒm‡ƒ!€ò?èq„à„T¸Ø1ƒ8ˆ„IH¤ö|;X…`†€…HøpYøpt´dbø†p˜*N8ƒ£V€JXjEã:/ò‡€‡áA*¢†‡Éw‡þ4h„! 5Óq2²‰TN1%�€xˆˆ‰¨ˆ~â,|h*£�ì'‰¤ˆ,Sò!˜˜‡Šh„¤!ür�C³V£Xж(§8n¬“‰­h„öR(Òa%"hq-·xŒ‚º¸‹›hj؉î$ðFOŒÖ¨&”(Zä'—ˆ‰Þ¿8k„'‚×xŽ3²�}qMÜX ŽâØ$PbŽèxý#±:ØÐh({XŽ‚ÉÀ}Q{þØÑÒBÏ·SX™¬¡rR. Tò¡ù‘½£Át ÙióÕ’*‰¬a=ˆ‘~b ’t2CÒ±��!ùx�?�,��Á7��þ�8°A‚*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç '6H1²BÈ“(Sª\ɲ¥Ë—0cR, …I™8sêÜɳ§ÏŸ- 8x¨Ñ£H“*]ÊTaŠM£JJµªU‡ „Ú,𵂂¿Z¸yµ¬Ù³hÓF̺U P6 û´¨Ú»xóêMZ×íP¸$ýŽ»·°áÈQŽD!p$T¸kÆML¹²åË  nÜ×±]Ì C‹¾;ðÍÒ�´Ž^ͺµT¡ESD†½ÙµíÛ¸söMxäWÀŸs N|#ÍÆc³Ú]\¼¹óçQ ½ºuèS3þØu°W²)½þ‹WØlyê »œÙ;zŽê¯Ëç¹5pPOñ˶¯8¿ÙÔi _ù½GVDå·Ð~ ‚ç‚óEˆS| È`dý1È`€úMf¡ry• l ˜•~ ^4Xж8•€éegÁgêQG!y>$ ~€á‡aXdטŽm‡P~¿­Vr`ÉH”C>Ü)éâ•.ôŒGâWAgNÀbþ¡W¤–Z–ˆ‚Ž}iŸVú¡$~#y`œ3"Dæ~±yY×—rh„c†IÖŽbb©hHÝ¡‡(’ÅÙãŒ9FJ×€z>e¨š)håÕš:f—‰ã¦“ºù׌™)þuvŠ¢vžØé¢¸zTÞoY8+’)XèS´Îyk¦qjjRy´²åÕ¨˜¦yf³ÃÚ¹¤†jeìWÀT`›°ÒúX|ÂÖÄc®èf´+§$¡©]ˆîǘòjh¦�º+î¼�îh+W—ÎZj¹ ÙJ"½>ÚË-¦œ )µž¦Çj¥éV,Ò`y&Ä%A ø„y<¾üÉÕa³E’„p”B:0‰È¾©Ÿ¸{õî‘6• ¡¶5,çÇ[,4D5²›¦Ë ›f±Qâè¥xæÄköxÐËÖNª5Ïc ‰t¯ÂëòÌ´šTéÒC§ÑÆÞ>L`βý¶ß§»eïQ_]õ²ÎúÚÖì&Û§Ã}ñ‰ï¹ášû_`w«öã±m5Øþñ*ê¬'k8åz3j倊õ9Ìkž4Þ“SÎ+µc"*våÇž%”z²¨˜íDÓ^ûífê.ûïÀ/üðÄoüñÈ'¯üòÌ7ïüóÐG/ýôÔWoýõØg¯ýöÜwïý÷à‡/þøä—oþù觯þúì·ïþûðÇ/ÿüô×oÿýøç¯ÿþü÷ïÿÿ�  �HÀr/ ��!ùx�?�,��Ä��þ�ØÀB*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI±AŠ �R$$ɲ¥Ë—0cÊœI³¦ÍŒR4�°ó¦ÏŸ@ƒ J´(K“)Œ*]Ê´©Ó§P%D¡²gÁ +y6h€Òʨ`ÊKlÁ“=s T)ð,Ö:ËÊK·®ÝpÓÆM¹7§W¯w L¸,Ò¶pæ]˶°ãÇ#ß< çW¤;1KÞ̹³gŒ–¯ ]ùäçÓ¨SwÎÙsqi½YUËžM»¬kÖ<M3îY»·ïßDM~åéµ oÊÀ“+_þÒï­̣KŸr§Z‘Wÿþ©+ÖØÿþÏ^÷ëi±žo{qŸä-ˆoˆ>æñ÷.·¯÷Þžf}Žæý7’A(ô×QNp%˜B/!¥ \ .„àm (áb:ô \É„ …0M¸aCvH’p•øR‚:˜ U æÇ!G¸ ô!Køy¸à†1z„Uö—£í¸De!‰ T‹$%éÓ ɤnGÁ•Uv+º¶Ð‹#ÚÄ¥FPÚˆUKMÈÐVÖX\®Y&’`26çVg]n‰1”àhg*'›•e¶g[Ð*hŽáz`‚ûMÅ–¢ZÈ•AÏ]Š©Mêéfy‚&Ê(qŽÚ)äŽzÁˆ(q÷ªçwþž’j©«lЧAVA¸'¥m1J¨qÏIÙ¯ Qé'‡VÙŸ)¨®µ8䇩´ ^Í66¤’ 2Id{.ªÊ×Iy=©Û´¥Eî²RžCÄr c­mˆPºÜ¢"˜}ñÛ˜ ¡k§®všëÚºI™ÊŠŠÍ8íŒã"´diÙ~õp™èò{/ÅF&ô ¾øÊ›àeR™ðºïZ”´üÆõqÁæ+ÁÏ) ñ…äªdî?ÎL§qe('¿+õŒ ƒ/ %ÏÍm]§ï·i±-oÜ2[L÷iôŽ0³h°Ã¿8áNk ³Às6¼,Ç«J¥É]/Öî‹@ÿ›mB[ÿÌ/þÐÜæ<©½qm³FÙ¶°‘\¯Ö`Ÿ{óâ@*NÅ\©dB—ïõëÒ×ò òš™‹M±Å3*®öVîÊû´Öò‘Ýç¸nbº¢¤4Ø þhçh†kE\êÓbk;¤ézÜøx™1œvÁTÿL%oP í»¤7ÉlÝTc¹y^Õê”êÓ÷þ¸Uâ¥ky(áò}w¥÷„Îir¶m+ønÌôrœÔ¶"V®¹W`®ÞwD’JÌÜþ4®�•ŒB³^͇ªõhçpÜS”ÀT”µ„-/E_3 R²BAf(zfëUäsAîË4 S˜îÌô »å {òŠÍUúWÀºn/,êö~¡”•D;þ,ûÙ—¼4¡ï¨ïmFœÍš'@îEN}+çr7±guŽv´ëŽñœÅc©ntALÉ€(µ©íKˆ8# ;·Â2íjdgÑàÍ:¨ÝP7 z ½tƄ팧»žƒÊÓA*ö‰ajZZ ä¾Î•)‡\dABÇE•½i}Ç:’ÐèŰx1+‰ ºÒ–t#´É-Y¯Sˆ ØÉ=-Ïd¼)%ñ2v°óÑç’8;Iw˜…:³•(Ž 3¥Nv¶Ã‚qp*º#Þ&¦<>б\/Z]‡Þ¹âa/k +$ûÀ·Fñ”á[’ÐT„§ÊìãÛvg08ÙÌ™”ã¶8f0Ís…¢þTVk´ÔÎZ1•óŒX…²¸#Rä}½šÝøLÄyN>DòÖ †P ¢rxü\%<i×Bª­Nƒ,bÈÆÉ!‰žÑäè¶ÌnQ~@BÓF©Jg͘ëjQ¶šu*{ž2hy¤ãÿ®ôDE6П͈͋“­XÞíQ;ecCX!+5tcö#&=I1wí¨Ú2’I„xÁgÆô„³{Ó,ÅæKTf³¤Wc–.gä"¾]µhk•#âf[į2lF<‰(™bÄ“„=Š…[Ø5 6±«ºc¥Y b Ÿ•ˆ&[©Ãr–:  ­GŽ&RÑšö´¨WSËÚÖJ'Z³ ��!ùx�?�,�(�­���þ�H°` Zh@PaÁ‡�V`±¢@‰ *T˜Ð‚Ň?ŠI#É“(#¦XÉE *WŽ´°2äIš)lÆdÙR'Dš>S¦ÄYA¨ÑŠ-yÖŒ‰bf A?Ò„ r¥K¥Q²Ìzô£D˜]½6ð9õåÅ•w–D8v α A* ù¶êRmM2m;ðkƱ λ°$à´ùFœk°AB›~û2ÖˆÖb«n“Â,Ë3£R—§ê¼ü0`,+tð9³U³�¦eöõÙªeÊÞùvì¤9âìó+‡,7wŒK:…ðÞ8Qx~õésÐÑŸ7ȳzQÚÀ=þ¿¾p7uçà»{lþtzeÑÍ[=ˆ™ôDÙ7"¯ü;5SÔK5÷›t;Qtš€ŽöOßù7[|±¤•n½ä „¤¨]QÉ)Ö_„55pÕBn¤SrÂåf–€ÞU]à•¨¢KÚ)âi�GL[¹Ø]N³M¨ã|nÈ”U<.ˆ$xÕÆ–Ne•TY‹ (ZŽ 7‘„ ÚEÕ~Câ†åm¸Y`bn!õáU ñ—_“àqdf‰ ŽÄÞ}#ªã€Î çXjbö¡]erÄP °õ8fbY–f!Z±YdEÁEÞ€0ˆ#—"q¦Þ|®æ)©qvJ‡èw¦òY–{pÛåøi‹®q˜ÜUòÕ&á«*žÔ܈rúëvoU׃=Â(%q¯àJ™òäZž] ©b´2Õz$¼Išz\áîE6†WXa•ËèHjŽ+.D86æ.ºôÖkoJŠÞ«ï¾üö«o¾þ,ðÀ¯[ðH�!ùú�?�,Û�(�Ç� ��þ�HP … lpP¡A„#´±â‰ZÜÈ‘àÄŽ %"Ĩ1¤I†+~4É€…)*„ s!ÍŽ4Kn|I3Š-Y6¸”ãО4eåÈSiÁœK;6pô§Â—((r„Ú±*äQ® [°*Ò:ÉRKkÑp+ÊÓ'Å©3jÌÙ ¥E¼µæM8®B††ã.Tl˜ JÅŽnœ{fVª†ýæu˜¸0cȈ¸…‹°dâ”( GÌY©h˜•iþÔ*»ç_Ùª=ÖÖŠµ©…ŸJ«RµlswážVåZvH3álâ.}‚í]EôË×k;¬ûíð˜9þ;m [:Ö¹3af„Š´»à§ÈSîýõ2w ¯ñóŒ7تð„BZs!dZfÉ÷x0QDÔ~ÑÅ´ t°}7 €fÅP`*Q(_k¸-XœLÿÕawꥇ_~Ùé6 ‹ЏVJ€¥XV| .èu^ãT<.!s°5àÞ`¹év \*ˆŽùÅöâd¿ñ…¢‡}åxœ|F*("uÕÖ\D�NÄ™‰QªÈdLG)¤ì5iYBh>–V†*VX×H#¥‰^˜ØyU`€#eé‹<mi^T ô¤xïw¨cЩiiS5”"^q~\ÝÕ“›ò·X\I1j˜zÅUc‘>R –¤ JapÉ:¥¬+^G‘p•­ן,=*銚—r‘Vg\vÊB_…Õizå¡Í8é–ßf .…‚õ¤ÑT Y mÀ&ë֬𒫢·ÑŽkc¼G^—˜´â‹m†áVG š¾Çï­’xè\v™ªVW¹–u'™{6±ZÉUñØ]ÒÆ§v��!ù�?�,���Å<��þ�H°`A2 HÁ°¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤I"0Ȳ¥Kƒ"d0I³¦Í›8sêÜɳ§ÏŠ (0xI”hÌ?“*]Ê´©Ó§P?’Z´*A™Q³jÝʵ«×¯)FPXiõe %Àª]˶­Û·1 -Ë’Á¸xóêÝË×äˆt F�Ñ·°áÈù¢ 0 0€$KžL¹òSÆt![Þ̹³g‘˜«jþLº´éÓª2 |ºµë׈Q�6;¶íÛ¸ÙŽ˜Û’BîßÀƒ?Å@Ö`„´Â“+_n35ÌÚÌ£KŸžq·qêØ³koè|`¤ÛÃþ‹ON‚÷ãñèÓãî�ºú÷ð=ƒ Ë ¾ýû–gûÆÏ¿_ ¹ç߀ª‚�,Tà‚ rÅ@ F(¡SìgÒB¦€Â†vèᇖ âˆ$–hâ‰% âŠ,¶èâ‹0®8ÂŒ ÌH£#Ôh£Ž7îˆ#9þ(¤DöhdE"y$L¹¤“JFÙd’Sã•Xf‰â–\–�â—j(æ[`PS†‚Øåšlf馌ORI#Ð ‚xÖygzö¹çvú™' |þ9蟂 ¨¡Šz¨ž‹>J¨¤xFšè¤—ÖX¥”C¾ù&›k‚ù¡˜ ¶•x4e¨¡š ¢ ¢«þ^¾*k¬´zêæp&y䌙6:)£¿Vê«¡‡ û+¤Èl²Æ;l³ÌB»,»æhëµ.’ë¶³r‹¢¨’:&[5Ú„&«Þ¦K" )bÛ¢œðÞhl¯ÀæÙÁ½øæ«ï¾üöëï¿�,ðÀLp½—úYgœ ㊭‰Þ‚ª­¨«Š‹¦¸:±kykÃSRЬÁ$wÁÉ(§¬rÊ´ìòË0Ç,óÌ4×lóÍ8ç¬sÎ+÷¬rÉýª0¢8]´»0†:êÅgÞ¤`šÒ ë¬YMm”¼:{,ÐþúŒò'ƒ2Ø4[вÙ ­öÙl§ÝöÚnÇ ÷Üo×-·Ýtß­wþÞ|ãݶÌcíõ©\ã«5°œÆä§#N-ë—¿u®‡':Þî›ïÊ$½õÞuÏbžÁ;—nú騧^ºè£ûìyÍë§ÑÔÖˆtå%N &Çæ"×4ºk+"æÕj©È¯wºØË¯l3ÚC÷ôÓK½õ.cÿwõ/_ß}ößoï=øâ“}Ì^3öÉ…×+ûXc´Š\n .Ó4‘0‚Ó«²ºåÇXã‘´ˆ•¼|j}¬CÙÌòF½ñÏ|Úk ù¸ÁðI°|¼ #¸½–%í žâ¤ù±Hj»ß¸jòT¥ªP ‘-£IihZ«S Ø:Ñ©¯‡þ@bè„8qˆÍœ‰¨Ä &ñˆEtb™¸Ä ¢l‡÷ŠÝ¥lX»ÝNb®º_˜TE“ ˜icó߬N4?«q1SÂ"¾>HÇ:ÚñŽxÌ£?¸× Y‰r£oÇ.ˆåÎK ŠÜÓnB ýŽT`¢U·.ç)Å!I‹{’£{8DŸ©î“  ¥(Ǻ'öq‡‡;ÞÕ˜t;Ëé.‘ªÂ_M"�!þ-\kd£ U$È¢=ë}„J'«¸Çbó˜È\óüH„Õ«Z7Úe!·ôJXbŒŒ6a@‚ps±n*ò› )Õ-à N¦Åò›ÞL':שÎv²óîŒgäæ9NÞysåãħ<÷¹B·€ 1š@Z�À‘M¨BA2›ú,ô¡ÍÈ|ЈZô¢ì©åE7jÑòä; éCÙ#Šô¤²NA PQ”º´?$Èq^JSÿÇ%­©NÓ£Ò–°t§@Elвš U;1mÉhŽÊÔå„F4‘iªTóT«,uªXmÍbã˜Ádõ«¥ù‹c€–‚õ¬‡‘ËXWŠ´ºõ0b)ÎZ¯bÖ·Ú,S1Ï\WÞõ¯] Š^÷Ê’˜Ô°ˆõÉR"WÂ5!¥J¬dÍEd€`�W×��!ùú�?�,���Ê<��þ�H°`Á4¤XȰ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç C^¡a‚Á“(Sª\ɲ¥Ë—0_&I³¦Í›8sêÜÉS$ˆ b J´¨Q—@ô\Ê´©Ó§P£füô¨Õ«X³H Pª×¯`Êëð§Ö³hÓžœ@¶­Û·pãjÔPU­Ý»D¹ÊÝË·¯_¯fñ ¬2éßÈ+þh’°cdžKžLyrãǘÕF®Ì¹³ç·—Y&Ä ¡dæÓk•~^ͺõÓÐ)E8Dr §ÈvͰ¿oN|·ßâÄ¥Ö.¨DUÝuW"<9 Âè'j8ݵwç àÃþ‡ïÞ°¤xñ¨_¯;Åyðª–dÏ~æØ÷IEÐW/U¿ÊæÙ¥°�²™”ÀBÆ t` dœ{±õ“€ñAh›w9·Ÿzl•µ!‡éí·Ð†å}H_‡ áWaN@Ñ÷Û~(B5 J(š6R€„-dš$]] Dx>.gׂrFׇ1.ôä†Qf¤ß‰#Šè£‰0:Ô"{K‘8åzäA¥d„µ š 9ha¾éž„ ¶ €-˜Y™MJ6¦– qÉ'Föxe}[r¹y$òtèzl}IæWÎI×ávtî( @:Þ™BPލ])leg„›>VeŸ‹I ¨”þ\>8×{Ú-z›¢T2ô(ˆ<é{²š¹Vt a�À¨qh§žzšZ*²£fêæ™j˪bŠ:”-N®êÕ-B#ŒP(°Ò7¨MÝžV¥ ž(|z¬ðÊ $œ÷B¤ŽÈr* z„­zmbŠŽ ß¶ºšw¢} !'œ{ûœ+Cß 8߉¥9 \YÁ%×ÐOâáñm?ü±yâ©Rme²Û!Iv–Ù˜ÌÇ.Žu‡]*Ü—†&œ¥‰(Šð-–  æ§"îÊ¡q"ŒµÔR+ýáÅì=Øh¢'ŠÙ¥®G«×sG¸QðA;MÚhïlÐz„1éóbã²×Uݓފ+þ¯¾2Ø¥Õõi°âÁŠ:-·ÓÎå¿æR¼·À QÛR³ÖŠšPÏÝWØbs}õÐ{·Wh­X*ޱ—¸Ž°5ãvƒþ8Ä.z®èØ͘—Öá~yL´k熦Î:¤ˆ»a¶ŽîúìòaM|i};Þ8ð]nh0ÞÛTöîÜWîûb¸FŠëòrwk°ù°³'4ö_—ÛºûyËžÀ€sx´B$~÷ê5¹Ý}nßSŒá$5]u+s ù(½Ðu}òc”ˆ¨+ë!.}ñcZìn"¹ÿ,€‰©ßŸ\EÁ†ˆ�eDóÒøg´Ð1iuÖkXõFƯa‰D—»G;ºÄþ@ ¢‡HÄ"ñˆHL¢‰8¸±ø {ÎëÜm¨©á肉âñÈE+"$z5ÄRºÀH>¡ÙÄv A^t—Ñø%¹LW’4¤‰^úá÷ÈÇ>ú1‰øÝ¢Tg" ªÏ‹ÌS!"®£ pEkŸKc« Š1bÊ Ô«j²½tè "ðOµHf9æÜf �úIbC‘ýñ•°Œ%é–tÕOl†S!”ÐÇËE¡,d¨ÓR&½#óåp’†\2 ‡(œˆÀ ýRÉu®òÉ5¡OÁ™u:¸6Š D–à g,ßÃBæò€ÔR£Ì7®(M,] ¬"üÖ3x†Ñ\¹þ&¥ˆƒ`•›ZÐý•#¦éˆG R4½W—ƒ&­†ÎrVPxD‘Ëä1°GŽŠS‰´K.“YE_ÎŒõc ‰n™-J‚ûV¶OõȆ*ƒ$"™¹´œ¤SÁS.%шjÊh·:Én¨Rƒ|U¥šÈ„zÊ£"”"U1b¼Ä@¢À[éB<zDÕÀùèÛ½Fú›ç»4R6“¤Y£"¢ØgÃÖÕ <êGZÊf! _UeËŒ–ê¶›Š*Æ2åöR‰'kö‹±þ’È7‰¸U‡�Q5ÀÀ Å* $îFAdˆZ…ÈÖ¯•0]¦3þé¥Óš |ÊÔkõ3øö·&€p}+EH ×$\ÈqM€GŒtRª„-›6ù•*8 ¨9ÛTW”²3¥ÌÈ»Fm–6ç%/7iVBT >;V즫CÄhFHK%š5ˆñZoWç;DU¾dbgÃbO–Ó®ÞJ^%m4M抯ÁoCà[ ÿ¶>Àµ0…#£Ÿ {8¸ ÒÀ‡-Ü\‹<óŽèv¬)^ uª;vôÔ€N{lZ3SŠ-*yS€o–µ ²< ZZ¢ˆ²{ƒìU%¯UWc{Â^ÈÆ£r2ÇC+&®QxKˆ­zÙ¸x¦Ð!•þ‡ %µåVØ·-Êðröæ:ÃY/>î€çâ½j�&ÁŽS… È\×9Ø5/|’¦Ô$)åćÕWU›cÍCäÇ© r“DNƒõ6‚k¯j–jD‰¬×È�mH¥|Sl—ˆmÁÏiϳTüȇ„ 1Ú{,½ÒH©×sH ©T¼ˆœX<ýb‚:kx¸%1…ólZº¹ÎR:î³™ë‘ÐÄ(^&¡îŒ-´]�¥2•Ö1NI ÊòÜÈÅòÕ¹;LwZÓ°–2‘¥Œê!>H¿›ŽjB³v'Ó' )gûdF¦PMj5i¸À‡« ×à A¼ìŒqiÿ$¡x³þ=.m+ë¹#Ü|ÉÙ†²ré´Ü*r{ˆ½÷‚ý9^G.²”òMe­â[5o˜Ÿ]½ó{“Œ$GÞ2?Sçø,÷Ùt~óÈ+ìt ‹x¸[½º…=â¿:&晹zCKð®`9ȯÞ÷zåÓÞ€×|ʨ-}sÙLüÏ _ºg,þÛÎ’|Úúo1€m† —ðŽß}»ç‹œØë»S×ÌinB²¿ÝòS6G9­Z"Òà»áh¹=íiˇ²èJ×»“Hƒ§Süâº"ùqWmçá–çï‰1äU%‘¬1Ë@ìJWõê†8¨ý|E›ôÎ[¾ô⪓.ÄÆ«ž2µxâ¯þÞwùŒ8ð†Ï³…;Ë}Æs$å»W Ø)6ù¹¯öý²\µeŒj­¤™Ì"­jýݲ\¥p<üOgÙggÓF{°§—~¨!yèøQž¡,QÕ\?’ùwb%&|—xÊ5aäñwvö1×Vm !{è§€i9®ô€.eQFJ3ÂQƒK,CjI=eæe1!¥&Âa25(8ùGJÍ#el?èƒög1?x‚%hgRg!µxËåw Hr[(rÁ.kñg¥‘‚*øûgQ/؆}ä„hæ/×e !2 öBh'&+ ‚J�Už$%rØc<f*¡q þÓâ,°‘)7•nCB/Ó‡[qû'‚·gжU†x&x¾Å…!õaÖWQ¬Ô´•–†N5o䆰˜DVè es A?šT¨,UqB™ÅiäI¤’!ˆžâ&h²n• ‘MvÈ âClö"13tÑxhÒÕ@·ál½Fð"{È Ç…ªÁqÿW~Ü6†þCi "J)1MPu@AùX‰‘‡ñò)�9Yy ™ ¹1Q—UpÂ5s‹„æIvq’xl½HhUÊFUv2‘ ™eJn‚‡I+VYÐxþŒ©)Á…׆Z§mÝW{çÔ&{¥8g‚n*†*¸Q&z!4‰ ¤ò@£v9ëw}׸µ#ÎR6&)ÎUYI•–f'Ü¥)Êrbg^2‰(i`ùŒxÙtbì&s„È~ ¢,e³–K(ß÷…èlƉr&{õ2uÔ¦qµS·ˆw 1~³/) @Á#í‘‘H2EEr9àx}Û“i ˆˆH*åÕc ™—)iˆ¦²‡ éŒÈ÷‘U ¡,,‰’´¸’e×¥”žRp)‘yhj#ˆuáxÀ•…æXaƒ YÇéqA)ôH#iQѲ%ÝTR²hÛ,þˆ ¨Ô§VPh!lQ5R'Þ¸Îxš23a–%Y*IQPØè™uR‹1n¢&òTÖ%f¿ÑÜ(“a™9"¶mÚˆœ{ÖqXøÚ÷fV)×#å#§¢ l"’RöŒ°Yˆ¹q‰¬ByQPÖ©›±9„XIo¿¹Ÿb™šæi›Êäµ=w˜'Ѝ ´Iˆôˆ"[f U‹ £à¸UHºIZ §A‰VMÚœM:¡(HGÄY¿xˆ†)©B9yâPÒ•b˜I¥¼a¢‡1ƒá1ó0h eiz§mz}ä. /YUºÑ"pBiAqSï‚ú9/—(ú?›¡9f*•Š*,,Ñ2uÑÏ‘GKI‡)2/³iT†J¦¬‘¨‹Ú©=‘‚pSÿģت¤ÊŠÐé;œê©¬ª=hˆD‰ªZ‘”>‹¶z«¸J_òFGÁŒ]'«V‘™­:¬ÃÀ ¬´J¬Êª¬Tq¬ÎŠ&Ë­žÚ¬ÏZ­;"XÒš­¼A¯j­7’Ú®Ûzlûè­;��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image1��������������������������������������������������������������0000644�0001750�0001750�00000000052�07504443353�016507� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ð��������!ù����,��������;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image7��������������������������������������������������������������0000644�0001750�0001750�00000000225�07504443353�016517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò����� 889yy{‹¾¾½ÞÞÞÿÿÿ,������@bº1eÇ”Ö*'ë¼ö6 æ›%–Ê'érÐ@ZQŋВ…À¸RàEÌ ‹Â8À)/‚S€Ì|ORÐ#h-¤Ár Ž©rzäE©ßž�ª¯5+€àüjâè$y �;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image8��������������������������������������������������������������0000644�0001750�0001750�00000000313�07504443353�016516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ó�����$$ DDA]]Z}}{‹®®¬¾¾½ÞÞÞÿÿÿ������������������,������@€ÈÈA æ<I˜� a†BHŠˆŽ^¼Â®ÛjØo.ü¹NVÁˆ™DÐÛGD†ÃÄ`{µvE¤Ip–HF§ Ô¡‚2%Uf ’7*2XåU`N^iB8Xˆ,RN+d%ua6n‚p3;g‡p!l2zj›�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image3��������������������������������������������������������������0000644�0001750�0001750�00000042526�07504443353�016525� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a,A�÷�����  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ,����,A��þ�ÿéÛ÷"ÿÎ5K'°Ý?~ñýëg‹/"Üȱ£Ç Cn̘±`>}ùùËÑß>}ýDÊœI³¦Í›8sêÜIóÞ=}üîÔÄ„BŠ>âþ…ƒØK~úHbäIU¤Ô‹üêåHjLüöŬJ¶¬Ù³hÑúÃÇ6Ÿ¿ÈT4´„qþ潓ø°_¿«oÓ’üïÞÛ{'îÇo¬àÇ#K¦ú•`>L�üük†D€•nöâÅ늒ð䜄F|ø¢ßÀ§cËž="½A‘³e‹J‚#Åâå;÷îµiÚ3¿ûGOÙ´˜éüùýë¹õëØiþJPߣˆÆþ]"&l‹!°ê½csßñì #““£‡cõåkÑ1üÿ�Ò&V=Œ¡TÊSÓŠ(ÂÐb†GˆRN<íØCTv>M”À‡ 4ÁN>÷؃ÏWþe¨âŠg¹GOAõüËG„ƒ "¤0ã ¼`Ë9×cÑU,X0"@qÏ/p�Ê=õÐsDiå•:Åø>Åc |³L„¸2Œ-u@À(èpŽ{û VPÓÁf`ïÑ$Ý_™R€ ÷4ÒÄ�pŒ3N9îÔƒ•%”'–jHd|“†„Ò––™C�±`S‡j ÂÊ/~d0Â#ݬƒN;oí÷{þÞ„g¥5혟yàs‰HÁŒ4×”#aÅJ鬯Fjå£FÒÒJTâã�¸£HL±J-º�‚ps;î¸u_T!KN¶„ÊlèsŠ´K0Èh£N<TÖzÕtÚ©l‘̉áLŒ9ÊR¼SJ„‰.ÂlbCG “Î:àTÄVUê&›Ük¹Ò€üТFtrK/Ï„sŽV+°Í7[óÀË:‹óºVùeÑ>b-³Ô�ã���"¶,ó ¤pÉ:íŒ#K ‡¼s­$ÿ£KNøã H ˆ+²“7ðèŸÐÇÍÑÍÏú̳þY¼?M¤_>ìä�,ÝðáB �°‚¥4CÌ „ Ç6í°Ñ>€SÇ®×xÍç?Fóà1jœ£˜‚ 4×À³hka}äwM�¼÷c}ëÍQcŒÞyرÎ#@0ÁLðE&·lóÉ  AL¢ë85Ðèw‚ÎnØÜt€B?Í ÁÂhp² +Æ4³=ÛÔÏK¶_u¡‡”ût» Ö{ÎŽ‹«Œt ÜÀª�C< � V¸Ä,´Á‹%� À`G:ìa" ä/€^ûÞèÎÑ ìcg`Á�È  K”ÂÅ G¹`âýÔO*ô¨‡=ö“"„í¯‡þýë�Gâ;™øƒ#P�3 á†P` Vð��€= "» VpŠq#B©’†Œã—°¼$,\2‰Pò‘„Y„Kœó‡ ÆT žò�²ðFx"ÇÇ:瞉à£"¡Ç9ºq‰œc"aäÇ7ÞÁ¹W ä-`¡Ž>ðq‘¨f¬Ú‡DÒ–ÀYä†vÈ_òá1‰È‘n:9Ž*cRî„'1<üQÑÄãUÙŠ%ÿ±Ã*ÍòkDDæFè1�‚}àA *¤�xZ! e "@D8àvHD?ÆiÖÊ8¾°ÒH¼PþФÀƒ/þz?\é;yÔà×øFô8…E$B­†7ÐaŸÌ—ªH:±„)DÑG=$ò“rœ«+é‡>¶W;}êcĈ„Q p„a *c5Ëh *Ëi l”™·œÍò‡A‰DòñŒRâŸXFAì18É-ô =ìq)ƒñÔªÙÊ#àƒtŒ" �@Áðð0 �&%Œ1 Bt�h�†<Ô±–d’§ëZΫúq‹+PàR8 v` 6Êc ©ˆiµ!@ë�„ÀE âª7ÐÑ”{ÄD¤ûÇ?JÌÁÀ%ö!šyȑԨþÇJì!ʇ°¤Xñ¨È?rá„Ø -ðÀ 6Qspn,Òé×Ý*UÓý„QǽLýåS×ĤDÄ$È0ì ƒa`A!´!ý„t"óàKUmD¬z„û8(P fÈ! Ø‚ê+��‚^1T8Ö »8;*4¤ž8eðp p€ŠIbƒ4 Ðv¸c"Š%’ukf�舘¬¡Kdv‹HÙøQ¸à¥ø‡:ì�€'(8½90 sL¤%t žPÀ±‡ Ì ÉøÇ3&±‚œ÷ä,ëFSë„ ýhÇAtZSê¦Òº±‡þlû1 ´€Ã@Ç8XÁ�„Áÿ‡–ÞY˜Æè™{ýA%HX»©N c88@úJP 1x  Ћhì `Â0à1Žt(·?í­D¼‡ D!ïF*|ÑIÐ ”p<Ρ{´OÁóÜ´NñGø �<HD"$qŠ^`#ê@‰>æ!LjD`߀G0DqAßÐÆ:ü0ì`c¨†?fø–¦(j+ïX¸¡n€"à˜>àˆx¬CvÇíé™÷ô"Ž‘ãEžVI2AÇ܋ųœ�Š¡qØb݈Eà†l´#N‘-=Ú‘p)~Fj¯ÈþB8ع’À‚�nЇ=Pb¥ˆÄ�€$¬P(€ l\‰i,I“wÜsÀG<@a&ä!½@ƒV° w”#îÀ$`C4þã�Ä?$‘¼….ªq( « âøE \À ~äB_ˆ€¶àŒd,ƒäÀÃüøa%Ä|Ë>Ü241` óP%º…?£l € bŽtÀpù“%šW…ÌÀêØaóÃÖ¬Ë{úÇ< b‰ 8¡ï°Å®°†Rã¸À"Ì1C¤/�nq®©Â$ä‚öÈOþñŠÀ ÂhÃ0þÀGdbº°E+¼pœ`‹(C4[ò`ãq§b]áÑ"¸ƒ>Ú)d �'`΀ զŠ Ú€é…kf¤SýÐ àû0 C0�3ÀŽ §ð ÷|ÿ`¤ð`À°²pXÐ ‹  µ� Þ àíÐ ðÕÐ2„üÀxü€tà�y ÈWP@Ž€ ª°PÁð ã[õi?{~Á !~ "pï0R‚?ázû#z{"øð (`å°’@+p� Ȱ jð�<` Ö@ íÀ{eÀ0ð­ðþï0,…tJuó—r!Ð�°° |P°‘` ¡À ¹Ð ¯� Pô 7 �€«@ ÆÀ bxv%t\G?ºàPðt@P��€�G�  x* É0 æP»´u/±=`¡  ö0 EP�8@ — ¯p á`ë ŸpPZ€ :V ypPs\p ` Áà 0�¿ ŒÐ�p àð è ôÐTý ¼��|àÏO ��@sH Î@ 0 Î@ï0†35:ã‹�œÀŽà(@ ïóðÀc†gXp{‚Ï€8@ êp WpþV˜à ˜°@¿à ÓÀH@»À*G×Àé¡“!pñ6-@‘°P”À« ¼° Û`�Àë }u�€© Ò`üâtRkÁñ "0ë1CÐ�@LÀ4màް°²€ ú’¹IŸ¥%¼p�fðˆðÀ�6°G`C°8@@PÔÐã0 ¸à VP�ÐiЖÀ ˜@ ²pF€ìà$`�ð Áà ÞÀIåðÖ@DpÜàM��€M�@âP EÀ�AP Ã` ïОT†åþF%ó3¯¢Qòó� ú@ ?Ð�Z ìð†l±›#[ÁFý�%º‹|²x‰¡ö@° ù h`au-��CР° Pžà ̰ .À�Í@i� ÛÐ â�÷C6Lî%1{©�2@¼�|˜�‘Ó¡P�P Øà ¼ €[P Æ` äÐþÁIý°mù°à ó� Y€�Àx0 W��$€ Ê � ²  î þ�¢õîPHþ0%[Òo°�p´e M@80SàjÐ ¼11¡�·@ þ~€PnPŒŒ° ´€ ð÷ ‰p�0´@ ǰ yñé� ð ß� K Ѓ [°‚¶p ™‡ ²� âÐ#Å9aq)¹V¦4@§��D€ · ! ´ Ó` ìPA—Fóc!ÿ¢xòsH‰aÄ0 p %��@’pÀ“@ ÀÀìè Uªê° Ep�[` Ù  âàùTŸù!#º3ý( Ÿ0 p�±à }�𚀠·Ð Ú ä@� ò ©°  À�P¢° Þp®Uï@[³gÿP Ôòþ¶p,��&À™ˆ–zæP@°G¥à Æç` ˆ0o°Ìð*ø ñ jÈ7íÀ îÃIÚ*?Ѻ×@ а[  èp ›Âw }`ƒ@  Sª�Ýp5`�g` ²P´‰„�€ð³À#P�7@p s`@âp áêÀ“ð7LY,']€³%œ$?þÐ `Êp‹0ðáã�gD ðC8µ?<˜ºDã*q.i Àêp gà±ð—p аpØð W0�0@ °€ Ÿ�M0É PšÐ Ïþ0 2³IÀC,%’»ŠÕ�@çÀ6`~OP]Ÿ` Õ `Èp u ݰ fpм@¦æÐc!L( ”¥Ì@?0�`“ uP`p�;0 §�Ù´²0 ÐPÐÐup Ñ–aÛP.P ¶@ †€ ˜ ¤p ©  ŽP {À[`=à> îp�MP~ €‹  ¨Ð.€ ØP ŒÐ 0˜ð ²@ ×ð» ZPÎÀ;0�P˜À„ ;;Îð X@C P ¤ °³ ß ~,þã kRrHô zÁìpà0!ôP�  óð A�@0 Äp Ý€ôÐÂdkA¾ ¦Àõ^Ÿu«bakm¤c?@Å�‰° �^0 –`‹ 0fbÐ�wÀ©  ÐÆ�Ðмp ÒP0E.ÑPoä½ gu° ôÐ Ò� µ`›0YJ�ÿ„N& ‰À mL Ť°@˜0¡CµOü@h�Ç@Šà��d Œ`„° Ð�’( spP›P�¦ð"ì€ _��½ø¢¶ß �ðÄÀþ mÐ8�@0GÐ7  d� €�°ÿ  <@�!�}P€ÀwŒ •0W Âp i]…ð · è@À öðHp�à‘P ƒ0Š P£` zÀœp �p0w6ÐD NPfph€i°×] R 5@ipñ0 ÛÐ YP) «ð¥ÕÈæ�Q!†1f°ðÁ0'Lûìp Ïp ³züP–à�„àµ@›† Ž ?��l  P�€’0 ·ðë A�I ¥0 Éà‡ç êþp]ñ0DËÆ2« ä é€ ¹° éxëÔð màÛ Àæ l`s Þ  j@¤ƒýð"Å„ €£U– ‘`€ŒÀ ‘`ÒvІ�À2€xðP ‚pÒ€ Œ°+ âpë#ýÀ ��Ò€aS4�€��� �.n�£ðqÐ `e0lð„� @ w€�‰ ª` ð_gð‰ £œ àúp a* ‘À‚P_m�Üð. �Up Ó� Äà ±° ¡ ‚0i@KGPEpþJÀ^@w@ƒ`C�aP€µ  w0� ?�T€apn@Žàqõ ò ÐÝ0 “ðÉP _Ð.€#зðÔ`;ÀÝ`0V€P „�0 À€Ë ¼À€€0cÛI`ÀP PFPH@ZðmÀz B®Ø(‘ï°³,PaÀZ€Ÿ0€©° ¬  ¼@ ÑPÈÀ4à Êð3a ¿ Ép% E°´`ý#ðP ç09à�'P•`à…`”à yÀ�-P­@ 0� ÿþ „€@ÐzP Ò` 0ð�vСšðp&¦Ù†jp� � %Ð:``å €Ù�J sЉ ¡à É@0º¡€ ŽP�tà™€ Øà# â09p�!P– Ä‰` ™° k��8� ¶Ð`Ò è�à€ÈbæÉ#‘;ó@[ü–P 8°© ˜pE J UÐQ0S`дæÐR@Ò �0p�màRð(pj` ²à ìðŽà¢�bð—‡ ”à …P õe000™þ¹Û@ v°GPù}^QSÀ+˜^qã½/!cùàÌC�°0prà¥@;°ç\�RðƒP�Ðëð -€�P�aÇ’-lÎ 9#•<žèS ´Lj”¤K¢’¥Â€Ö±;($ú—lŽ �ÀX4¬Ø$qӦݿ) 6½{c‚‚)Mš@‘‚åM@Wú7H†]ê¼a³HS­`Èv˜€·KÕ¸J)�èˆQ↘4Äü›¥EA-ö‚$È“©Z­JX°UlV¶¨Ñ³ÈÐ @‚ 1‚$‰Ò%NŸ<ešäh‘ ?nâ|þ’ô#ÙN|Ø„Í 7Ÿ;|ÿàÕÓw†ŸZ7"@Ê^§O—ÈlirdI™IÇÜý[ç‹€†j¬°—MÌ„8 %:´‡%MÀl-à§[%TÉïŸ:pʦ•«'ž½|öêÙsÀ‘k÷ÎÁó'@þ!°@ɹä ��@tÀg/0XÀƒ$¨ ƒ< �pØæ-2�à€ ª˜C“_ºÙ&•7˜°"Š!zX¢xþ`�qDE Ñc”R|±æ �֘ǎ ':zp�€ ø`fñ‚)œQçvöy�Jäqã¬P 1Ê€ƒŽ;âȃƒÚÙþf PC 5ìPd”^Äñ¥ƒ$Î¥r:á�žø‚¡—tÉñ@&A$BqÅb²áb�>ƹ¤€…^¸lð!ˆd€ÕZ˜aXð … ÚèæŽÐagjQF\b¹å—Y`©å”Þè@a‚FÒ©ç‹x‘ç•oæùÇœwÌñ‡Ÿ|ʉ¥Z1ä .@ :ù� ôød‘@Á$RŽ¡’’&*@z–É%™‘†¦–[LYåU:™d”.hau®‘'Ÿ~ìéÇ@“Ïf“:¼øá€¬)† �@��\`�tÀÀ[Àþá…�X ‚”pSZQ¥š|à™†õTy‚„�2pB <É$”^–¹¦N�à`TàDŸI†X`ø ƒ‚`Ä‘. À B<ÉæŸL؃ž>…" 0Â8ÃŽ>AdލÈÇ•(€Š9ÌX#Nr¡†N�ˆcE’ç�H™}‰æn…‘Â�>P9ü¨„eªù&@�øáV®8à�egÁ�€€ž@€ `p�êÉ&а"‰*Ò †˜>¢ $~p‚‰`ð€€i&%�€G i„PTiÅT&ICv¡ T\ÃÛ8F)þÖñ 9Ä  ›ô€NÜbÜH.<@Z$ã 8Kœ0…(¼á®¸Â”0-@áH°{pŠd£ñØ>d2½cü(‡1nˆ ê@Ä € ¼`.0Á ¦ð�`å0…L"� #àÐà‡[0ü`†3ÀÁ d´BF`Á*€h¡¸¨?ÎñøâvpF9¨Ðl€ qЀ€Ô  *ðÀ 2°ˆ °?A�4h8ƒÁV€a�ðG8™ƒ7´á ‘ØÄ#*Á |¤�Ÿø‡ p1K˜eª°.’þ±Œi¬C«€…ªÀ (€:Ã$z1ŽlÃ…1öP�Ì�+È™j€è zˆ$5É0��®pF  �€�20F3®Ð>À�P@ò,ÐNÈâO�(ðA-Ø D0BpP„t�þ8!R± eHòø†*HQ‰2ð    ˆYô j(À ¶a3€˜�¦à[¸à(�0€�€A%Hƒ'`Ñ‹h”ã"ã!ÚAzCÒp |xBpÁ¦0†.ha wèC`j$ã øÀnÀ@�¸€ ’àþ„,Ô!¤ F>ÂŽquÃ’xL0£˜BêPŽÜÉ" O°€@€¼à qh„)¢Ñ q€C¹Ã´}4"�€Bì@‡B€b½pÆ,À tháÀ Ð�ˆKlø€öÀ€\lC œ˜&XP³@a p0Ä+†±Š\„ãá†/.h �#P‚$q�ðÁŸÐÁŽ L  ¨E,>-¨@ˆkȇ:¤Á &8@2x‚(-€JÆ8Þ`8€›5{� lÀ½tâh0ÀE7Á,�x��TUøÃI2g þYô¢Õ`‡7 q‹S¬ "¸@p@I€áLØè*��ºÓ ÿ8†S€ç!`7@B± RÜ"Ù>ö! 2ûãò`‡9® \ô;‡.´  á _ØBÔ€V1„�¬<�$„ BpºhND sà†9t D<âÁˆF8Ê¡g¬BWB  �4ƒœE0ªq jP#ß0G<ô‘Žkd£ÇH1¦¡ŽJèÀ"ø˜DðBü”˜…2¾  a»ˆìð€ˆ<h *h0‚|@Í_@Ä7.ƒŸ2°4¾‘8þ(¢ž˜1¬qŽtˆc‰Ø‚ P€�Ü ¸¨Ã ü¡ñH6®‘Žy¸#v`° È ‡6Ô¡"Ð�5H(Á O(Afq@”øQ¸ª�†5ÈŽp„$ZQ‡�L¸HC à€ À3K8¬! 0€ž@(…8‡DdâkÌH‡:¦ KpÁ&>±Fô��*˜ÂÀoØb &éª0†-˜a„X„""á‰WôÂï¸Ç>ú±w¾ïÝóˆÇ<ÌQ eÈðE7øp0a dCôpˆIPB�PÃ7XáƒÈ€ jÀ œ€ƒ0þ žÒ†4Ú@‚ ä j -%L1‹r¼CéÐ…-Ü0…_4£y *hQ i<£»x)(ч:Á Ÿ'„+h1‡ á¨`ïá‡=hBÒ ‡+°ˆ}4" �Â#‘ M€ݰÆP�%üC>ÐÃ2F„p€6� �‡sPx‚2ˆƒB…Xxs‡w@ \ „0(†k°,� ‡c6 >�JX…c¸†e(„�„Cðƒ phx�/X3`Xyx��$`ƒ+Hƒ>ˆB(„E@„Eà[8„€xˆ†8è)`þ-€x06X2£SÐDÈ#0ƒ;„>©…iðl‡mIÈJ(<:è8 �8hh ¸€/`­„AøƒE8A˜„Ùû…m€‡{è»I½³‡rømH‚p„u`„ €#P8E„Rp…Y¸Hcaƒ�-P@¦{„Dè7(-�ˆ†i€ƒ�€8 h!h- ?Wè…jø‡qh}(I€s>3�(Ø^Ù€`€H€X…l˜x�€ �>ÐOhÆ|ƒ0u€@�)X„BH1þ��:؇_h X�<ø‡R / †\˜‚�p-H‚@�Hh¨‚%+‘à€80pƒ9�Nx…\ÀyX‡jˆ‡]ˆ„)¸ƒu…5€ ` È‚2€_˜[(ƒˆ�9à Pj „x€=@ÄP€T°H  ðà�xFp7HЄU(†T Іpøƒ"ˆ�%0.(ƒa€KP‚ �ø€ à~ø)@€ê£0èE˜Wx…¦Úv˜nø„9°�pЇd0`�¨ `¢?BPJ…W�f‡x ‡Iì;yØy°þ¨‡v@‡mv'XÁ8ðƒAè„V ¦j¨…8�Q¸†CÈ€5H˜K¸„K „E¨ƒ X€ià#�  žP�Ã�Ð#‚¬-P`^˜…CÐH€p�@�ç!'�öL�VCÐ�¨‡S¨wäƒ=`è²4‡m( x€8ÐP 0sP7à� { „�˜ñ‚(.3 �ˆo°‚ 0€0'è¢�x�¸&Pƒ6p®1ghQèf …¸�¢š2æ¹€ðEXe¨ƒð�(H�1B’9¸=�‚…y˜þXÏ ‚H�ˆYê„Q`…\{�àqX„)`Ž4à‚-`€#hiˆ(�è‚(�Eˆ>ø�œF�ˆ€p2à/ˆ¼E¸UHfÀU`‚° sH† €(&˜ˆ‚G(KXT`…aˆ†sˆyè‡sø‡p †^t€‡|(ú z`…Àl0†9K>ðƒD€…aht8sðƒ4ZH�B L@¦ H „BHp„kÈ ¸�"°‚( €� zÏ€(8ÐÉL. ‚ šù€("`‚-À�w€4þ €ø‡^¸¼9�Rð…o�è|(+@C „ÌT€'ø‡ZØD‚Œc7À� @†nP÷Y‚& É„kÀƒ�$˜‚¨ଜé"� FH‚,H5Àƒ\P6�¡8€˜�qJ€H/0ÔL(šAmàƒ�8DØ·l€PÀ‡E˜Yw †�7Ø…JH¾_qH�€{ˆ„2¨� P.˜ŸH€T8€$Àƒ�(PPØZø‚&€"0ž� `�P#@œ5�„HF2€"Ð168�¨PÒ NPª`P5hœ‡þ} mƒh�Ð5ˆ…i ‡rá}ˆŽÈ€`<à€`ƒ>H„U jp‡vÈTp€(dXP9(„Là._Ø…^ÈVÀ‚ƒk0$��øƒ2è6ð‚%è� &;Ü�è€1¸†‡{¨‡gh#€€ x9x8F_JT(J‡W�‚—ȃ:ðJ…rø…~¸„#€`:h.(€D¨Nè†H@‚àl8É„…k8 0ð‚<ð�è‚i(…@€5 (ƒ,(&K€šé"T‰$ØTN"&x;À_0XÀ�Pþ€À‚PØ…FÀðqÈ”JƒH€¸m؆BØZÈwX!�*¸„MX…Vø\ ‡Hh�3Ї˜Ü€ ø‚,€¨w¸$(�Ø7 °dX†,h�¨‚5 *È3PʉY4pÐP\�h|†1¸€œ ÿãP8[@g‡tx ~p_:0F8\88€0ƒS°wЇ.`€LHC8 ‚=H„Q°¡z¨‡¸†h�Mè†G` ˆJ°T†h¸m˜j „à�WxH``0ˆ5Xƒ,ð�2øCØ*þ‘� €¸‚=†Qlà†_pX€&¸ƒ3-0€2X‡cP €xcu�ƒ;0LØ~È„X|�!H7¸x€fÐApP°8€] �GA`à�-`� hnЃ�€83xƒ?È‚°E#(*x×`€;`¯»2<˜ƒAH?¨,xÙ©¹UØ…;8�3¨†,x‰L „�” …3 rªƒyØ+€ hI€‚P ƒ<ˆ€‡f˜ƒX€/ °qà†;ð#@ÃÙ€ („oÈ!ˆ€ þ6è>ˆèM$H�`€ �!šA€›�ð…à)˜ �†{°ƒp�6 …ÛŠ†o€‡ù€ª0‚ 0…xøvx‡a(m  6€søP€­qp…#0€¸DØa�‡{È»xxƒxr8'H€ „G�a°r�‡oˆ‡g¸<-@^H8€8ƒ�…hXЈ#°z‚"Ø0‚.pb:ð€ ‚:ÙÀt°„ ��}Ð…%(�`ƒ9I€v„[²@(Ø‚í#à{¸6à†]8ƒLàL¸¼pƒw¯£þ%€�à‚m(@@¨.°3 P~`‡\ˆ (*ø�ƒhp p� €ƒ<€7ƒ9؃<Pƒ+xr(‚VÀ…Pƒj°ô„€€6@tP%P€�€*ÐSHX8H$Ð;°€0€ÝÂ< ‚�¨‚2 €0ø‡`�p:p?¨"Ð…Mîˆ$ЃðZ<N%ˆ‚]¤\+Væ7`¯(!…yðt¨P¸…fL‡|¨½‹Õ)¨€.hƒ2Ø`à†qðY ƒH$ؾ‚t@†+€€À®Jèn˜‡z(ÝU`�þè6x� XÃMð…¦j‡ãÈO¸€„e8,©=à �<…V@†I Ê×C� �`� x4À…_�ˆ�2ÐGU?0ðHV0� 38>àbø?8�XèAà€È FP‚h„¸„%xkøƒVa+€(8W‚ HÈ€&×€H„j8Mˆ7H„˜�CLcH„P€! 6È‚�h\p…?Ø�š|;@„HÐYZBØ#ˆ� 8ƒ^ÐJ˜†- � °� Ð{¸R�€@€˜^€ƒ € Àcø‡|`‡Dp�çþu�&X+(��Eø‡Ø|€ ƒ=hv»k1è…n€¬ Ø€* „,0€&`C•(¸� h@؃ €ðWæGh8€æƒ{ „+`ÝI€h@‡|¸(¹�´‚?¸\¸†q8†A(à¤Ô¡4à� ƒ@[˜ç¾~kHÐlH`€08LàYr�|õüý 'À M½–:‚`Ä<¼�ãk•�0ú„±Ã��Ø@§×.8D¾Ùg¬Œˆ�XÂÇ)ŠbÐ*µ‹\–ªðá‘P€¦=ddKÇG„™g¡~•ƒÓÂ��Ò|QqþÓŽXN �(!)Y5QV.¨Ðâã@…UnáÃ@Dœ=z<�ÈÂʯ6"ˆ"§Ó,^º|{Ô¢€†PŸ`)s�„šOøÒ…’€„* 4P{F‡„ôთl”�4ý{ÄdÁ `Éû#c@’A†Üªd÷A`Ì`©1aK— l( µ+\=‘ ãP²wÒ1 ‘UâÅòb@„ Q©Œy“wïþýÆýù ’@)!†¡CM4¢°áœ&ï\rÂTäÉ+ɘÃÎ?úÄS�|SÊØà‡$²#Ž<ôÜcÏ=¸ø @ Žü¢M4v˜þÿA!,b(0Â…¸Gk„Ä �ÀB#ר‚ÆPp3Ž#9� �¨¢$Z(P‚vòÆl �@'ñЂ|PℇäK € /Ë$SÆ @-ÚÀqJ>”@€°�� ÔbN4{¼°�`@Ö8% iàáÇ�P#Ã3K#X¸ðÁW´‘È&Œ‘aÀ¢Ë1¿0Ñ&ùü£Ž'†0B�(ÁA¦€S �D Ì?ìXãHfP�@ÿœr”ðÁ2ßÈqfuÒ‡šD¢Ä.¸Á 4ÊPbE"�€/´rÍ! °Å,Kþ?ü,ƒI"i´p�>L€6ŠрsTâI/Ó¨ƒO~ÿØó9·ü¡Û�( E¤Q -Ü£ÌsŠ�$A$« 3Ž:ÿÈãÏ'�1Ž.d@pЍ¢ 8êÜÓ=üäÃIÜ�Ç&¶\ "Vð B”àcËH‡!bFâˆ!x”Ñ„5xR ,ˆTƒ¡×ñ�®àcH ˜àÆjàPÂ5ˆ� ?{À…œ�B3øðA/�y S̶TÐ�“œH0fl�Rdr†�ÜÇ(·PL!aÄð–𳋠x°Ç ˆ@B�¬ $ÅdcM0’Œ1þà / P \SÏ0½@£IlÔSŒ,…`RM7Å ¨…¼ƒ d0Ê;ß<²Æ!P0 @õèr80Â5²ÑT@=8ƒ"!Š^Œ"è€,‹i4ãh€ h s¨£ )`À@�UЃ¡HD(¾‘ E\A�€�~Q=`jh&p±Œrø*?ú¸G=àá Zða È‘� X!«PÆ2®±Ž[dA(ÐÃ!<‘ m”cùðÇ2H�XXã%�Á ]Hƒ÷±Ç;üá Il �$@ƒ!6ñ k€Ãå G;º‰�`jðÃ" Q|þb„ D4€¨Í‰Ã«�ÙX â hC�@ ì°‡h)æØÆ?àaˆ$À f�€ ðAŒ7dà^#°„7F1ƒ”€°7`q _d¡è%8A%­à N<Æ5ºÑs”ã×pD Ђ9Ø!pøÒ€!Æ7Öñ gèb°È†;ÐQŒ;à´ ‚ʰ,Œ¡› 3º Eá�5PF/Ä€�8Aª˜DÛR ��àäC Šgƒ]Ü#Êp…2ð�-Db¶H†%|�� A”€4¸QŽ>æc¬àB:p„ \  j°ÀÐŒm#þ´D €np‚`A"DQŠfˆcEüÈÏ>èvl#­X|ð™ *ˆ0Ñ‹p£øÀ‘‰]8ÃðèÇ?ÊÑ�´A›A�–HÌÂÜpG†èñ{@£}@ ÆI”Ùƒ…$¬Ð t $4áŠ_À£¸*°�0Tb˜8ƒ$%Id�aÈ#N`€àA-P@%l¡ [4£’U¢€�A€#|ã�_ˆ@ I¬��!(BT dÀÕeÁúðJ”/ pô� P°b¥-D  ��⃨D*@шþ2 � YcÚ�6f¡ˆ0¨�´È…ð€ €'ðÁŠ^D#¡p3Œá‡P”Q ‚j�� X@�¬ Grp¯ˆ¿G9¢Á‡l¤¹°(( *�\‰ÐÄ+h W,¢ )� ¸ ‚( � p€là4$‚ÏÀ3"A‰fÀ" ÐÀLÑŠ`X#ôÐ~ú‘y¸ÃØ0F.bá‰DÔ +€�€‚"À Èƒ&À@P‚ÄÀÆ7ê‘~\‚@>@€%С¯pF6ÚQ°|ðcòðF"n€€‘¬�ü\ƒªƒ �€[þ˜ƒþÀ X�#Ãø…pO�4À G:�`…>  õÚƒ$À�&¢ͪAÎІ;ôA 5«p>8¡¨B°�)ha àA$`�C@ãUPÀŽ€9ìÁ´kXF¢‚"d! q f Œ` qÐC!*ÁkW8b gI`P„/¤¡èzƒn b?V�V0�‘DÀX˜*‚ cpƒ¦€) 0¼°�R��ð�J$�@À†°…A0¢Œ�ÂP X ÃÞX…r„�  gˆC¸� ÀL°ƒVpLT$�¸þÀÂ@M4£Ãç°"z` ‚³h8àq‚Úü‡8f^‹UŒ"–ðô°ö™h@ lhƒº­ðHÖX‡†þ¡$ÀP& àB a´yö臆Új°B ˜‰�ðÝ OxÃâ Pè"Ú¸Æ5’Q f`"@î19ô!pA²€ÌÁ{8C0€P@¸€L˜à¥‘ÀðDD%’@a /�À<‡àaX,B&˜B,hBØ‹HÀäžHÀtÈ"ˆB,ìB18ƒ/Tˆ�V¸Ý�H�h€�þÀ�� Â0� è€ ´ŽHh�˜#`B,hC1€ByÁP �ø€ h�Ѐ-Â^Á�LT  ÁL�˜A(¤‚2Ã6€ƒ.Ø ´ÎÊ�À�@�lÀAÐÁ°ÁøA<Á 4� -€$A0)P•,T4€ä 2hÃ:Ð^í^õÃ=¼C:˜Ã4ƒ,¤)|‚&`B` ¬�(@�À`Á(‚'øB4¬>¸ƒ?ø+0H€ü€#pÂ.0C8¨<àGµƒ9d.$Bð€¬\9ÀÜÀ°AÄÁ ÂuÃþ"²Ã9`ƒ7Xƒ*PÁ@Œ@ÄA°Á,”�� ¨Á$�‚(‚¼ÀÈŸH0@ ¼Ü@ �À@"´A `Å$AAœ`œ $˜Á$B%°B/$-4BÈ�@îÀpÀ ¸RÈ,B+C3T8<C2Ä#¨AÄ¡E � „ô�h�ˆÀB Á˜ÁŒôÀfE@<@ <d&p‚œ Á¬A ¼�A œ[ÀÀ ÀÀÈA&ˆ0`Ã5l7&¬p�ÀD¹ @ÁÌÁÎ#ø„,|þB!A`¢€ÀxTÂ%¸Â� *ð‚3”<ìÃ?ìÃ>èƒ=ă;´C;¬Ã8\C3 .°)˜#ÜÁ(VL€ „AäQ.(ƒ7´=|L>0_#B!P‚#hB)�4œCŠà•>è= Ã6@1Ä‚#¨ÁTÁXtA€ÙÁ¼ÁDÂ'ô‚8¤C:ÈÃ>´C9¬ƒ7äB%ØêA°Áà$|&�ˆ$G&B)<‚pÁ(HÁ! ‚´Aœ!”‚%‚"´tøÁÜ!XL8‹´SÎ!|Â/ÜÂ08ÃG9B$§pþˆAÔ´‚$ÀÂ3„ƒ8tƒ40C1øÂ,x‚ ¸A( ´@ øÀtÁ0Â4ÀDm�s‚AØA üPAÀˆÄÌ�¤T@XA´ÁÌA´Á'¹`A¬ÁØÀJ@@F6$&È‚6dÃ6xÃ6(ƒ,€‚¤lD¼ètät’B*¤‚)ˆ‚&Â0È¡P@ÒiØ@­õA'è 8°œñ^å‡ááÃd¢Ã7TŒâÂ)ˆ'ü@,pÓ"x.Ã9Üâ>ÌÃbÉé/œ‚º˜+�C6¨ƒ=äƒ}?ÐC:xƒþ4Ã-¨ÂžéÁüÐÁ  $„‚,,Ã8ÈC><Í=œƒÕqƒ5+ (è �B$¨‚/ƒ-̯n‚&8‚(18Ã-€‚&TB#,¬A ‚$X‚'°D=!8‚$BB ÔA!,Bp@A>Fç¢2 ƒ3 H0È‚)PB $‚ÐÁÔ"ð D‚)ð‚4”ƒ:˜ƒ;lÃ1ðB-¨(p#$B!B"4‚" B 8, Ð�¨A¤xœ! ¬AÌ€4ÀKº]hØð Â8A p@ püAüAàÁ°A¤c"(Â'ÔþÂ1lƒ:¨ƒ8`C2è+lÂ$,Bº&©ô B-�Ã…2ž'H!´xÀ¬\€ì@:vB/pƒ:øŠ?ô螢ÔÔ>ÜC<¨ÃLqC4èÂ,Èk'X#\+ÔRB)èB2¬:àÇ;¼Ã:ƒ7,„‚¬n5t)–ÚUù>ÌC;Œƒ4 ƒ.‚&H$8#0Â#L‚&x‚(À‚1h9ÄÃ?àÃåC>˜Ò50ƒ/¤‚(t#lÂ'¬,ÜB2Ã,Ä‚,Ø‚,Â*ø‚4C1Ô,°&<ÂÐŽ%|Â+´BgŽÂ)p‚+äB)€‚(xB&*<nRÂ!þ‚ ‚hÃ7œƒ:Ã4pæ*|B%,¶2"`Â$TÂ(äB]e'>àƒ<$«4ƒ-°‚(ˆÂDì#4‚%P&\Â!ü!‚%X‚%l(|‚ãIB\Á €À@ À0ÐÁ§°é'”Âà°@BÏF‚`zÂ%@ÂÚ …xÞ8¸Ã;´Ã9hÃ2à*|‚% "0B!<B"Ü {ùIC4 C-¼*„B%8B"¬ÁŒ€0À$€ pAì%à‚6 ÇtLÇtê?ðC=´Ã"zÃ4,Ã0Ü*t&0‚"\Â(´0TÃ:hç§ÞÃ=tC5(C0�ƒ1<ƒþ5�Òàédþƒ?ì8¸ŒŒ®B*¨B*œB+¼‚,àÊ5”ƒ;€.8ƒsÌz5(0äB-ìB/Ã2P6XÃ4@Cˆ 10C5lÃ6\4/ÈÂ*œ+¬+$î1CöìÂ.32/T`2HqÒ* ê%dÂ0]ƒÌ¾ƒ;¨8,2뺂iI•*´Bb0çÒ>è?à°;¤C8XC3 ×+@b(š'„B)œ‚)€B&T$`B)ÄÂbøB/ÐB+'H À4Ah`ƒJ‚*¨31û‚+Œ¿V‚‡*¨)t‚&|B{ƒ4|<„.š03Àk+\þ³Nc³-äB/0ƒ7”C9ˆƒ7\Ã3ƒ0u)tÂ$‚`DÁœ V*HÃ98&)c?ˆîòÂ=Ô8dÃ3¸µðžÂüC¨ÑÃUÉÙ ¯C9l5L¤Á,<|‘~ðÃd®dÂÃ:œ7”ó¯ùÂ.äÂ/2D7Ôêë…38ÛÃ<°9l%ƒ3<5È:˜Ã8€C7`C5\CÍ¡9„ƒ6H2œ³-ô/üÂ1DÃ5Xƒ4TÃ4¨¶7|ƒ6”34Œ¥5,CQ ð*øUÁƒ=Üp=¸9dÃ4(ß/è.ìBo3Ã4xƒ:ÌCJo*¨2¯ïb54ƒ1�ƒbäB+þÀ-ÜB-ÄÂ?«Y.ó4¤¶3ä .À)TÉÖ¬™A B'˜‚ÿ^w68CC¿‚*”) ,ØÂ.ØÂ+¬‚+XV‘Ã<x=ÀC<Ã6HÃ2Ã0C.èB0(CÝ}ƒk4; ƒ8p€+°µ‚'0Ú¶¨<Z‚,P:@vdgÈ>pjÁDæ) D<¤C7´20$41 Ã4„C<< 3Gæ>à=´:ð;̃<DÍ)†n?„lƒª< ·7dC5Dƒ3¨68¤C< «>78ëÇœáñ8°è8œƒ;®q+ù:Ü­;ÄC’#º8 ö3Ô]4TƒL-â8”Ã8¤:;¨2þ9ƒ9$º8tw302C1·&>pê)êC.êu6Pƒ4PC�‰ƒªÛƒ! ~<º´Çƒ*×:5@C²Ã1,ƒ34ƒ2ƒ0Ã1HC7pÐ:¬;”ƒ6<C1àB*|Â&@!ðA%œÂ©ƒ·Ã782ƒ050C3”†òÃ2Hƒ5„Ã: žáA¦<ðîL_5<ƒ4dC8¤z<ðÃ=o>„<ÀGx0ÜÂ*ˆÂ&̦�Â"‚/«›G6lÃv¤{ªèÚýƒ6и6h¼=ÀYœqª÷<¼æ=¨´¤„~`½§²=¼C̆Ã7:¸Jÿ¦>œ"Ú£=~HþM«ßq¬s{?xÑŠÔÝ׋´|’×69ˆ8„C9°C<̃¸·;°Ã;ÈÃ<ÀC;ÀC< >eª:xƒ—kÃ7d'©…s©iÈF›Ã°› ·Ã<œ½§’2?H»<à±^s>w8üz8H>vÒ<Ø=éÊG[B5r*è¸(K9ЃùÞ;|C7pƒ6XÃuwƒ¶“uwÃ7ˆ9°Ã‘“r=hÕæß“¿C Ë™JƒnæÓ;„€3Ã0ðÂ+œê(”ÂÒ(8¸ÃÏGöç†.~Ä9^ùp¾mŸÃ9 @¨sGO¿ý%Ü·O_>‡"ô'1bÄ…ûòÕ“÷þÎ]¼yôîåÓ·°bEýø1̇_½z÷ôõ;©f͆øPêk9/<wïäÙ£‰ÏÞÃ}ýú1¤W”?}÷ê¹c·n];y÷ö5ÕÊ©NðàÅ‹'>ƒe"Di°ßSzòIJk÷Nl<ŽUƒŠ\yÏ^½yðÔóv š²dÈ’I㮾‘ûîÅ£º.Ý9tíÂÂãØî'¼¢ýFôÇ/ÔzôÜík_¾¬2O¢ô§¯^¼vç¾eCFl1cÉ aK'ïlÉ’ ‘sE«³ï<yóê9Nû9uä ‘O(1¶ìƒNG¦¼8Ýxù„MA#ä:Q¢L¤)Š<Ê;ìëYٷŧ²õþ>öÖ¯£.)†Fú¯¢ôþIJ9µ´²çžÖbÉ5~°ƒï¨¤îù+žtÄçoÆQdz¬(¤Žžz𛧍{XdQÂõ*,n-®ô™ˆ¡¦òÑî?ö±ÊÈñfm¼!« , 6Ѱ«…h²Ï:¤’,O´³ºsɃ¤´ÒK+Q²ò:¤²=ÅˊɦöQ‹<“NúÒÌ2ÿI ´­ÈÌSOíœÍçêÑÌ.uÐQ' c;hBø(ÜŠ«7¹|4Í…ÎlóKáD¥|ì¡g|äi‡x>:ôË‚vÜÑÎ8­;¥´¨¼.¶ÿ’âî̉xŒé×vlÎê\M)ŸX5£C“}4P¼>×JKÓ÷^KR«…$E«89·°»õ(ª“%®ˆÂ Q)íÖ¤/—tÓ Xúî½g %üøÁIÎ{Ô3VY«Ä÷8~ÎÖ߀63K`ý5XÖ/gMXáûœ²Km¯+1AåtW€/NO^Y=éQ‚ž—¦‹PÆôŸ€��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page4/image5��������������������������������������������������������������0000644�0001750�0001750�00000000311�07504443353�016511� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ó����� 889YYZyy{‹¾¾½ÎÎÍÞÞÞÿÿÿ������������������,������@~ȈA æ4ICRž€"Ò¡¾pâ¹p ³�(¦ƒ-—¾‘PÁˆ áD@‹…JŒd Š*‰i{’±»ê¨JFgˆ ”Ô…¶@ýBDÝÓ^,N¨uõ/i?\\VƒTCb*}c2a€!�oBZ–>8gƒtlJ•1š�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�015401� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image13�������������������������������������������������������������0000644�0001750�0001750�00000011777�07504443352�016610� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aä�÷�õ�����0@0666>>>>R>H`HLdLVrVZvZ`€`d„dfvfhˆhllln’nr–r||||¤|€€€€ˆ€‚š‚†²†À”œ”–––˜˜˜œ¬œžžž   ¢¢¢¬¬¬®®®°°°²²²¶¾¶¸¸¸ººº¼¼¼ÀÀÀÂÂÂÈÈÈÊÊÊÐÐÐÒÒÒØØØÚÚÚÜÜÜàààèèèðððøøø������������������������������������,����ä�÷��þÀ‹pH¼$ŠÈ¤rÉl:ŸÐ¨tJ­Z‰ÇeáÂèz¿‰¯xL.›Ïè´zÍn»ßðxØà" ø<¾ ïûÿ€‚ƒ„…†‡ˆ‰Š‹Œ| u –— ˜›œžŸ ¡¢£¤¥¦§¨©¡•œšœ‘\²csq¹º¹]½_jÀ^»ÇÈbµ˜ ¸_µ³“¶bÐÉØq½ÛÝÝ## à +åÂá½Æ ãéçÙò¹µÕ“ÏdÒ’Ò˜øó�ÙˆAÁ ïÀ뵂݆†+šK·°`À‹jêEûÇ ‚?jÓ¤ÐãÉ1ï žCHN¡±†ã®TØÅet'sF³´×þÈ.úhÙórM'F—*#v#8‚eAq#6çm©SœFsjôb $WYû†v)šµìœͪA^Ù†tð'£»xóš€gÁ½€"@×]?À&HP�ƒãÇ#KžL¹²å˘3kÞ̹³çÏ 1/Þ2iFŒÓ¨S«^ͺµë×°cËžM»¶íÛ¸s¿æ�–ÖŒÀƒ N¼¸ñãÈ“+_μ¹óçУKG.¡wé騳kßν»wíÕCþþN¾¼ùóèɇß7^¸‡ðß;÷à¡Eá÷ÓëßÏ_ÿzßÄÁ×}�Ø—_r˜ }öçàƒ6÷ßuÃ5 �| �€aƒÆþY˜á†^Èa„$–á„´œ€ð…Ø@}Þç¢bhâ8ò‡¢ŠÀ±˜¡�#r I£…Bæ¨ä’ßí¸Ÿ€LF)åtNêGß”Xf¹\•Zvéåƒ\~)æ˜åíøÁ™h¦©æšl¶éæ›pÆ)çœtÖiçxæù&Š*èé矀*è „jd&ªhw‡.êè£Ð5 餔'i¥˜Vz)2Ìàé§ †*ꨠŠ0d¦ŽnÚ ¤¶êj¨¦Ê ƒy4¶Ð髸暫©¶êê««¼Þúë°3ðjiH± Cy4òø�²*Ic´üM;kzµ»p§€³Þ}ˤ¸’«_þÚÒÂm Þ‚Û¹9»Ÿ¼Þ·i·æÑ®»$ꋞ¿ä¡[ܽìæËc~/žJܕȡÃåAü®½È‡ïŠ/ºWß}#'/ºÚÇ Çï1¸1‡ô x%”Çpp/¿l¼ïÅ·"Ì,ã§ñÌg¬s€Ê\œÀÄŒŸŒ¶`$�%ËÇ`ÒÂ} œ‹^X3�AfØBˆ2Ë+¤É_+u}VgrÐf£ì,ÈHOm`Ó5?$ÔÁIýuÂL—\wñ¥=Ñß&¸µ‡?r}ªÔ‡cX *øá}4.ΣÀ %ÑX™9|‘7þù×Q¯ýv¶^¸µR!éu_n þÒ ®>õ‹5ŽÞ5ÅÛZ\°ËzXóê5¶¸zå¥ÿÝ"’µi¡ä idòQߌ.äïiX7âŸ;.ºÊLS_ýæ7‡žtñ6"û߆^ ù¶çþ⼫ë»{Ñc¤óèG޽øãäT§?5Hr’^ô&—¿é­}ØXw8#9ÏS»œ…”f¡ vÐmk`’ö–®I¬ ;m#ŽÄ°³Âþ´p99ã�'ÁIGoCã×v^8/>Gh9œaýLx?ƒýˇâá‘Èdžcât ÅV±‰Wdáe1aKWèñâÇHÆ2šñŒ£âнf°,T¹qJª{bÅþ€s±7ÚQI9ƒâ÷X¢<αuä£ äÇÞÑñwDÊÆ\½…ÑoBÝ +UHû’9Z`~ö÷¢¥  u _Ò–=¬%�’›¤—*IÄKiB$Ù&œ¬å‡iÆËÜ"s¹ÁìmÐx-€e¡†IÌbÊI–j[ð˜à™*˜åìfŸZµ¨V¢ôÓjD¼ÍåGÏ §8ÇIÎršóœèL§:×ÉÎvºÓˆ„¤ Èx2Ó28M¯7ŒÌ>‘Ì[$]†6úðóE>ó tÃІ:ô¡¸a<VÃ?òžöœŽ(�U2éMfEéyQfÔ£(EŽI)þ:OKÖ“8+M©L•Ó£Ô¥% ipHÀÓžúô§@ ªP‡JÔ¢õ¨HMªR—ÊÔ¢§¦‹li+_úTG)ȪV·ÊÕ®zõ«` «XÇJÖ²šõ¬hM+XÛ¨Ê8Ët«ÐH׺Úõ®xýUUíÉJ.ºR8rõ]EÅxª3¬`g€XP¶Plb›×ÊZö² Ú+KájQ{v²Œl F»ØÁR1²…@ €XÕ&öµŠ=-fgK[»jV¤Rõ+UkÕÌU¶ª .iM[ZØ·µŒì§d[Ûæ:—X·µinOÝ«w¬Mì`IûZãª6µ -pC;þZÉ>÷¼èUußÚ‚¸öV”uíw»ÜÖ–—»Œµ/h]›]ʦ÷¿ÿ]/ÝÚÛY˜¾ÀN°sÜWêò6ž!P°„'œW+³Àž©†ÛÚÛ»÷¤ž©[=Œá‡øÄæë…IêÙo¢°©'Œa,ãw‹Æ&Æ-gYl`cÇ46V Z�ä 3tÈEž1’:äKwÇ8m±§“EèH€ÈRºr•·„eðXø¦SÍ锥³eçh9Ë]nRš±se'GÊa–ryÊ,¡5+éÌê±³tÚœâ͘ÇÖŽ³¸<W¨‘$ä£öA¾ÅP8†®e£­¬gÃ%º8|Έ\Dþ7wgÐ2zž&7$B±Ez‘L[öl ½ º I d¦+} Ì­ºƒ ΩÏAY'Óõó‡ç vT—¹³áùk=+[DYSˆ ÷9̱hÚ!#ήãã>$Ž>qlö #çmôiûËÓítŸÉêÆƒ¿<RÂÎ ®U}  õêjíè×ÙˆÞ ëè5kd²¼…[×´n\ðDtnO“Ðߎ³âvÐúÔâ~¸#Ê"‘‘ÌâÒ*2ƒÎ\p“Ê2.îsìån°7½â(÷˜ØèÙ5Žtîå*Æ\æè†³nÅŒóóðÜDGg³³)ípNÿuÝß¡3s’N"ªþïyéÏ™y‡¾[¨{gÆ<“–Þ§±ÓìÒºŠÁ<t9“§OdoÜÉ~'¹Óî úŸmh£”ælw0‡9 ÂþðˆO¼âÏøÆ;þñ¼ä'OùÊ[Þð[¯yœaê {þó³]{ºŸî÷ÒÇ(ðê6½ê‹Ãõ‹®þõç;ìgûÍÓ~ö­óí5œûÝþ÷¾_=ðƒoúá)Û8ëXƒ^†°EŸDÆ?þ¾÷Ö7ƒVó>sáÙFæñ=_?Ñ?N‚F˜:¤-Ïuü®`‹ÊV5\?=áÿÀá?0Kòc_kç+\úÑ÷¸hÇ—€8€X€†M:¶w¶Ç[ŸRþ0†3BÄp!ò5#$?KS~Ÿä2zHW. zB'xšæbÐñsóÑ1ï€7z]7‚º§Îç(˜‚б‚!˜zÁFƒ¨bƒ Øv7§ƒ™ÂƒÃ&P„Fx„H˜„J¸„LØ„Nø„P…R8…TX…Mz7„Á1WØ…^¨^M§y>¸^\è_£‚\Ÿâ_”_jø…nøEYXb^ç[‹EXÝ…†ÅE\ŠU^o؇`†¨Gz9¸…ùuZYÊu]Ø¥]T4Z«Yލ\Å凔Ø*qqsø[Þ^u¨‡Æ[ã5‰•8Š™ˆ,HtD¸]ÀZˆX‡Ø…X¬ØŠ‚¥\ÁUXúþEЏÈ#B(‡.8\ˆYf˜‹¤x‰²—‰ÂxŒµEŒ 8‡+`dÎøŒÐµ¡Œcq@è(»ˆ‰½x•’ŸÜ8)Þ¸Œàøu˜åDöyèXYëˆFèhŠ7(ˆ#&qéau'‚uJ'u=(‚ƒøuõˆU'W§À¡vÂÆ‹ÿøiiyæ—™€ZÃ7…æly30crâ—3w:7<ér?cùdýˆƒó(h•7uqÇræl†s“Øw7‘„Cûf#¶„‚»$‘Ä1I£71·mæ'#OÓpsX{ÕØ”ôxhÒ:[ã<¡T3ÿV“õ6j?‚•¯³?þºt;ìçoƒ”%Ó=×ôm¦Viäæ8ÔlüX‘ )RÜ„lÀ”5V‘GãA•ó“Üvl,s=~™•ZIQ¼”—s£>…I—ÂcnpÙ”ñG‚Ù1nÔH!Sjz‰jtAƒ}dãj¶Ã™?yrÅ1mþc$˜ÙrtÙk¹vÔè-9™ ‰f©š0”¯É’’ùc³%öHiUä|)ùf+)»Ie½É$¿™uÉeq©±É›9ל`BÌéÃÉ^rÉ.`€×ÝéÞ žâyxäY€¹iœ/ŽZ2ŽO9‚,@wò9ŸôYŸg’™ˆ-xOïÔŸþùŸ� : :N˜ÚþLÒ¸  Ú ºlEœËÄž‚~ÊGz¡w”¡úFÚ¡¨ò¡ Š)":¢”R¢& )(š¢Ž²¢–I˜šY=D ¢ÒwŠºç#x)=§ÄH%ãI $$Ùôr.òIƆJ·ÖQ8ê”þ(Lg"K>¢C:¶45Wónt˜ò!€iK#dŸbjŸÈ¤’qåLД:JS3Ó†@¨vo¬ƒMd¤òÖM¡–0¸º§|Ú§ì‚ŹŸ •O1°O %“ s*6ÓqÂO0‚•)×¥FY”>ó –Ú ¨Ûù,Mªî ›ÇÙ©8ò©º¹ž¢!¤ªžÃÑT¬Úª®úª°«Kþ•Pº&é)¨ï¥Vºº«¼Ú«¾ú«g`P¬ÄZ¬ï™bªñô‹Èø¬c$¬p'ð@­' ‹ù©£?HˆÐú­Ä"­Ô:ãz«¨è­àº®¹"®/(p­ÙŠ®n§®ìz¯¤"®ãQ®óúœ úYø°¡"­ï ñگʪŸézUÛ° ø "媭š æ° +¬&@x‡g‹ ß¸Îб÷*¬ ð(›²/ð±i±ÍJ²«±„ŠÀ²fê²¾³«±ñ$6+¡8K„:‹¯<ûk?«Ak¯Cû­E iG뤥š³K»®M«kO™/;µàZµþyµËµB«µLëV>K¯Ýʰb ­\+s^«°õжi‹Œk[¶þ²�·Â8·mË­dˆ·rK¶{¸šµ~›‹zk¶}[¸† ¸ˆëi#«¸”x¸uKŽ" ¹¸(¹ Ë·Žk¹¤ˆ¹åˆ´ÿz±œ¹Œ;¹ïY¹£Kº½E·™+¸ K‡©ë‡ž»P«ªa»o8»©:¸R‹»n¨»Ûêºo »¾û…À[±¡K¸ÅÛ…Ç ²”{·ËËÍÛ²ÉÛ»Ñ+½¥Ûºúº{½6½7[½·ë½Ÿ¾@+¾JK¾f¾ k·¢«¾ß›½Ÿ[»¼;¾ð+aìK¿Ü{¿ž—¿Xk½ü›`þûµ¶›þ¾ü_ì¶gK¼Œ` ¬¹ÆØÀ R{x»½ÃÛ½ü\&«²){Ár©ÁÜ\Òšd,� œ´p;ÂèE°¿3±Á,ÜÂÛ¯›Âè»Â3ì\îÊ.üŠÃ;LÂ5œ­‹°óû¿ö;Ä´%®Õ*æŠÄ´«ÄÌÄ—åÄ' ¯R¼»¯aVLÄ7*1<¿§º$\<¼elÆÁ‹Á œÆJrÆmL d5fcu|©­qǺ1Æ´K10³µdA&ÈxÜ„|d|ÜázùX&ÖÙËI‰ªÚÁÈTòÈuV›ÝÉ"9ɦ*–\’I›iºÌªµQ*DšÃa þ� Ï$ÉîâÊ®,³ M�N&`àʱ,N¶ü’4Š’žŒÊö4¢I¤A"J‹IË¿Ü˯¬Ô ËÕ\Í™µ|ÍÖÜ �ÎàìÊØœË²ÜäŒÍ @αl›š¹4¾V“¦ ¶è‘Ê…³lþc;ÓLÎ&̯,N½ÍzÐþ<ËáÌÁ,б¼Ðè¼Îä„Ì”9“óhÙ©¿hìÇË\8òf£U¹ÍÐÑ*`ÍÐäËë<ÒÎýl#ÝËá„Î�Ñ,=Ëç¬ÒýÒ¬lSw$ ÷˜ILÀõ[Ï|…¨ÿ´Iké,¾ÌÏè¬ÒzÊÔ)Ò¿\Ë,=ÒÑNà$wþ,ÍÍÜ|ÕSÒ9=£/7;e™ÌéÊÑÁÉS‡Éû±œ?wÑT|f œŽ¬ÉÜÖ³6Ï ן¬vÍ×jíÍ”?­À}×1Ÿ„‚v‰Mdc 'Š­'n Ô¯[0@Lx7L—ÝØm’Ù~BÖnüQkì^\ž¤]Ú¦}Ú¨-¡ aüŹ뼧ûÙ‰²¢²%´]ÛRRH£á¸-&93!ÛÛ_rÛÂG@Ý8ú—ÜʽÜÌÝÜÎýÜÐÝÒ=ÝÔ]ÝÖýܧ*^yÝÜÝÝÞýÝàÞâÝÜóGÅ­)æ}Þ“¢*ê )ìÝÞ©2 à ¯  ö}ßøßú½ßüM õ½ 7 f@kQà~àl@à]��þàÞà>á^á~ážá¾áÞáþá â!.á�;�./saods9/htmlwidget/tests/page3/image9��������������������������������������������������������������0000644�0001750�0001750�00000004513�07504443353�016524� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aÇ�ò�����???¿¿¿ÿÿÿ���������!ù���,����Ç��ÿHºÜþ0ÊI«½8ëÍ»ÿ`(Ždižhª®lë¾p,Ïtmߘ€ï|½ Pö©"rÉü(›Ðh% “Z¯ AËj‘­xL.o…æty�û¢µlŽ8n »7ösêÎÓt3€$~&|;Tb6Œ a@+‡8:ype …/U™–l›„£4… i¥,›jcŠš¬«2³µ{%·“7º®sº'º¨©’Á-£ž °’̘dÂǬ¼aÍ(§¡!׋ÔÎ Ý#‘Èæ!a¤h¡ŽxcœÖsàïìA~g¿®tárÖãÇçŸ*ƒÛÜåš§¾úº(„0àˆo¦>#8†ÿ F'pìx ÄGZÇ•ÜPO˜Åy:Ä×nÜKuÚ>„„™“%Í|)$òvÒgPð<@ú ñ(RÐ(xª¨êf,¤Ò>‘Å´Snüª²ú”Þ¯f‹¶ù*±m§»ºîˆw‘Ë£TmÊÉëP¯_wÿ^½(—Û¾nÐ%¼·æÛº�ÇâMœ#YÏ„‚–œ™¯âŸŸa~œYg`Ò¡³L†u@¢�Þy.‹:õfÊ´m{KÇ—ß•ÈÝÖ­y7çÚ¹¯Ž�»9;y.Û: •\6 ³‰'ÚrRï˜xCF¬} H:ÒYÈ^¼}p¨Ÿß¯?NzõÛËêq-ê]s;ÿX!ç ,tuâ›TTÇŸ°…r]Zì™tÇNƒÄÁÀq‡à>(@G\'WURo$ê× „HÈ£‘° ¦'\„ @Gl­Å[6vìè`‚(2_~qµ°NiE.ÇÄNªUƒ¤]-I–i‡}^Áå"C>y\{ ¸ÆÇ‘¹“5²¡¦š@€ge“`–ÅÕ‹eb¹€îSâo‚$‘[”¨bŸôHáÈ&罘|Sªàa+€døœXJZ‘TÝT™„–°ÔA!Š¢™WdGã|äÙrª8pÆ`ªG¼Zƒ¬•–ŠC­^ Ö´ÎЫª]¬´Ë®'àù‡°•uæ ÿX’OKëA¥²YT†GöÝ@ŒGÊE­§d«,ßÖÙ¨ä–Û¨›¶£î¹«²ºG¼³>#®cIЛ‘¹XÄËç»Ú toSItùî*ú~I¿�,p¿(0ÜpœÕŽdq1&6±—¾*·ñ9A°kÔÇ E%ÉNâ;2Ê*$ŒÝÀŠ�À �À ñ®ÕÌ� 3Ë.Û€ÁðÜáÏ$Ï6¯Ê4ÊJcƒÇ OuÜ^¬uXÀZÝË\Ø]]ò¾_w½±Ø¯eöÄhS¬v²^7öÚ ·M¤«a']öÞºÚ‹Ü†Ñ °Ý~ß]fá§u8Ügó]¯à;Nvßz®•ÿœBÉ8Û’c:È›j˜ayÇýxU_à蛨ŒüF:äꮢÜõG{0ÔkiçŠñ¸éïëÈàë›×Íû8âH<å¦O~:ó[.}´•?o}4Õ;¯½Tˆ+Œ÷âÐs>ýö"u+®ãsŸ½âǾ>JàSÿ±Èo§_>Ôö_¼ñ³nMFÖþƒ™îÚ,_™Ï{†2 Ëè‡.ZP¸Ú� x3W=ÐS6››Yæ¶3)ƒ 9ØÁq„!”€Ì¢6A,00E3;! Kà ’Ðp&´á S ꄇç«Á@2¯–Ȫ̟¼eDVi/¬Õ q0 ͦ…]ˆb•ÿ¢R>]ˆDŸ@ˆx.)Öç2™c¯â—±‹X&)ñá¯w2&¾$¯HpÄôe‰ŽI²cC‚'(Aaèv¤æ “DŠ?¯ …#áÀ l4Çdä[¤„4¹;EFÆO€c´Ø² –®‰i“—hÂÄ¥N©,’cŠž·)9(RßQ¾X'þ„NSÕ fÙ‡”Ýî@J%ì°²¨ß\è<’¥þ¦)©Bê'7¼¤” .×@…h8“æÊ6•¼HÉæw÷PæþzL`OTã7ç97¢Ò•ÃñØ&ï™&øå V@óg>ÈOŽ%® ,¨€Jù ˆä! u¢[jùÿÈZæ2»„¨BII³š× D6#zÄ&TR±©F´33š6ºåœÔ>’ºÌÞôf=JҒꡌŒèMM¹L~&ìWí)MúÓa)õa²祒úT‰ŠÀYÀj.ÀX¿6x” âW»JÖVÕªaôêY}JÔ‰Œµ¬ªlÄ[åIµ°U©ý§)æJWÍ…¯s¬ëֺжê°ôº 9˜WNþ•°…mêc!ËÖ¥Ùu«” Óe#Û À¾@L¹�gg3«�£‘@f›]éZPCo íLž…AkA Ø’–•PlÂb±�@ÿù–#”ˆí'sØ?TÑo»çGÛÄãÿ׸Rb®+ÝFW®Ðõ`u§8Ëí‚ðºÅm.x÷šÝîbW¼àã†À‰Ëá’½"\|€'( ‰’Rá®®PsRIK*Ï…¯TÚ›¨þ¶æ¾ø}¯~¡wŠÆ¤u×Ù¯wzåÕQÁÖÕîylÞüf¸Ãæ.qCü] {XÄF@®pW–â�sxÄfý0Œe(ãO&&1Ð~k†Þò8µ¨ímg×0‰ &Eí‘WŒ5%È30ò‘ñ9ã)—ÑÊÑÃrµŒc.—ØËs—¿ÅdL~KÊ\.³Pœ|Û ÍSfíÄà<d9ÏYÍž ži�å gvˆ\ëמ·ºD%öyÿ”Mc]¼Ö*þð­ÉõÅêEC :W€žjeý|V¤¦èÒ½°m!ëéXZ²Ž5u¢ ;YIJšÑ~õ{ZꟚ©¸þôªS5jWóZפ–5§«úup Ò£p…Åû¹ßuó‘;Šf2‘m.[ò‘¢Ë.WzÚ´íïÐÉ£ŠrXáÔxmZ·mgÍIQ[¸tݹÌ[VbMÀãÑêÐ k•hö¥Ï^´n…}âf±¹€¿Vu°në]ë•W·µÄîë‡vá–ÃCMñÕ\ÇJ­5Ä]èÕ¼›²Zm³Æme‹:]b¶ZÄÅé˜ã i6WÕr®sœóü[;ÿy¹|.ô¢ýèHOºB��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image6��������������������������������������������������������������0000644�0001750�0001750�00000000117�07504443352�016514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ñ��ÿÿÿ8°p������!ù���,����� �� ”i¡½ÁÜTÎjÌ:fê!Û5& J'fœ¾pè�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/index.html����������������������������������������������������������0000644�0001750�0001750�00000322747�07504443352�017436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html><body bgcolor="white"> <hr> <h1 align="center">Embedding Tcl in C/C++ Applications</h1> <table width="100%"> <tr><td valign="top" align="left" width="46%"> <b>Presented At:</b> <blockquote> The&nbsp;Tcl2K&nbsp;Conference<br> Austin, Texas<br> <nobr>9:00am, February 15, 2000</nobr><br> </blockquote> </td> <td width="5%">&nbsp;</td> <td valign="top" align="left" width="46%"> <b>Instructor:</b> <blockquote> D. Richard Hipp<br> drh@hwaci.com<br> http://www.hwaci.com/drh/<br> 704.948.4565 </blockquote> </td></tr> </table><p> <center><table border="2"> <tr><td> <p align="center"> Copies of these notes, example source code,<br>and other resources related to this tutorial<br>are available online at <a href="http://www.hwaci.com/tcl2k/"> http://www.hwaci.com/tcl2k/</a></p> <p align="center"><small>$Id: index.html,v 1.1.1.1 2002/06/20 21:19:38 joye Exp $</small></p></td></tr> </table> </center> </p> <br clear="both"><p><hr></p> <h2 align="center">Tutorial Outline</h2> <p><ul><li>Introduction</li> <li>Building It Yourself</li> <ul><li>"Hello, World!" using Tcl</li> <li>Tcl scripts as C strings</li> <li>Adding new Tcl commands</li> <li>A tour of the Tcl API</li> <li>Tcl initialization scripts</li> <li>Adding Tk</li> </ul><li>Tools Survey</li> <li>Mktclapp</li> <ul><li>"Hello World" using mktclapp</li> <li>Adding C code</li> <li>Other Features</li> <li>Invoking Tcl from C</li> <li>Running mktclapp directly</li> <li>Real-world examples</li> </ul><li>Summary</li> </ul></p> <br clear="both"><p><hr></p> <h2 align="center">Embedding Tcl in C/C++ Applications</h2> <p><ul><li>You know how to program in Tcl/Tk</li></ul><ul><li>You know how to program in C/C++</li></ul><ul><li>This tutorial is about how to do both at the same time.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Why Mix C With Tcl/Tk?</h2> <p><ul><li>Use C for the things C is good at and Tcl for the things Tcl is good at.</li></ul><ul><li>Generate standalone executables. <ul><li>Eliminate the need to install Tcl/Tk.</li> <li>Prevent problems when the wrong version of Tcl/Tk is installed.</li> </ul></li></ul><ul><li>Prevent end users from changing the source code. <ul><li>Keeps users from creating new bugs.</li> <li>Protects proprietary code.</li> </ul></li></ul><ul><li>Office politics</li></ul><ul><li>Use Tcl/Tk as a portability layer for a large C program</li></ul><ul><li>Use Tcl as a testing interface</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Why Mix C With Tcl/Tk?</h2> <p><blockquote><big><b> "Use C for the things C is good at and use Tcl/Tk for the things Tcl/Tk is good at." </b></blockquote></p><p> <table width="100%"> <tr><td valign="top" align="left" width="46%"> <b>C is good at:</b> <ul> <li>Speed</li> <li>Complex data structures</li> <li>Computation</li> <li>Interacting with hardware</li> <li>Byte-by-byte data analysis</li> </ul> </td> <td width="5%">&nbsp;</td> <td valign="top" align="left" width="46%"> <b>Tcl/Tk is good at:</b> <ul> <li>Building a user interface</li> <li>Manipulation of strings</li> <li>Portability</li> <li>Opening sockets</li> <li>Handling events</li> </ul> </td></tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Programming Models</h2> <table width="100%"> <tr><td valign="top" width="49%"> <p><b>Mainstream Tcl Programming Model:</b></p> </td> <td width="2%">&nbsp;</td> <td valign="top" width="49%"> <p><b>Embedded Tcl Programming Model:&nbsp;&nbsp;</b></p> </td></tr> <tr><td valign="top" width="49%"> <ul><li>Add bits of C code to a large Tcl program</li></ul> </td> <td width="2%">&nbsp;</td> <td valign="top" width="49%"> <ul><li>Add bits of Tcl code to a large C program</li></ul> </td></tr> <tr><td valign="top" width="49%"> <ul><li>Main Tcl script loads extensions written in C</li></ul> </td> <td width="2%">&nbsp;</td> <td valign="top" width="49%"> <ul><li>Main C procedure invokes the Tcl interpreter</li></ul> </td></tr> <tr><td valign="top" width="49%"> <ul><li>Tcl/Tk is a programming language</li></ul> </td> <td width="2%">&nbsp;</td> <td valign="top" width="49%"> <ul><li>Tcl/Tk is a C library</li></ul> </td></tr> <tr><td valign="top" width="49%"> <center><img src="image1"><br> Most of the Tcl2K conference is about</center> </td> <td width="2%">&nbsp;</td> <td valign="top" width="49%"> <center><img src="image1"><br> This tutorial is about</center> </td></tr> </table> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using The Tcl Library</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h></tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Always include &lt;tcl.h></td> </tr> <tr><td valign="center"> <small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Create a new Tcl interpreter</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;"puts&nbsp;{Hello,&nbsp;World!}");</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Execute a Tcl command.</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Compiling "Hello, World!"</h2> <p><p><b>Unix:</b></p> <blockquote><tt> $ gcc hello.c -ltcl -lm -ldl<br> $ ./a.out<br> Hello, World!</tt></blockquote> <p><b>Windows using Cygwin:</b></p> <blockquote><tt> C:> gcc hello.c -ltcl80 -lm<br> C:> a.exe<br> Hello, World!</tt></blockquote> <p><b>Windows using Mingw32:</b></p> <blockquote><tt> C:> gcc -mno-cygwin hello.c -ltcl82 -lm<br> </tt></blockquote> <table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>Also works with VC++</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">Where Does <tt>-ltcl</tt> Come From On Unix?</h2> <p><p>Build it yourself using these steps:</p></p><p> <p><ul><li>Get tcl8.2.2.tar.gz from Scriptics</li></ul><ul><li><tt>zcat tcl8.2.2.tar.gz | tar vx </tt></li></ul><ul><li><tt>cd tcl8.2.2/unix</tt></li></ul><ul><li><tt>./configure --disable-shared</tt></li></ul><ul><li><tt>make</tt></li></ul><ul><li>Move <b>libtcl8.2.a</b> to your lib directory.</li></ul><ul><li>Copy <b>../generic/tcl.h</b> into /usr/include.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">What Other Libraries Are Required For Unix?</h2> <p><ul><li>The sequence of <b>-l</b> options after <b>-ltcl</b> varies from system to system</li></ul><ul><li>Observe what libraries the TCL makefile inserts when it is building <b>tclsh</b></li></ul><ul><li>Examples in this talk are for RedHat Linux 6.0 for Intel</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">How To Compile Under Unix Without Installing Tcl</h2> <p><p>Specify the *.a file directly:</p> <blockquote><pre> $ gcc -I../tcl8.2.2/generic hello.c \ ../tcl8.2.2/unix/libtcl8.2.a -lm -ldl $ strip a.out $ ./a.out Hello, World!</pre></blockquote> <p>Or, tell the C compiler where to look for *.a files:</p> <blockquote><pre> $ gcc -I../tcl8.2.2/generic hello.c \ -L../tcl8.2.2/unix -ltcl -lm -ldl $ strip a.out $ ./a.out Hello, World!</pre></blockquote> <table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>The <tt>-I../tcl8.2.2</tt> argument tells the compiler where to find <tt>&lt;tcl.h&gt;</tt>.</p></b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">What's "Cygwin"?</h2> <p><ul><li>An implementation of GCC/G++ and all development tools for Windows95/98/NT/2000</li></ul><ul><li>Available for free download at <blockquote> <tt>http://sourceware.cygnus.com/cygwin/</tt> </blockquote></li></ul><ul><li>Also available shrink-wrapped at your local software retailer or online at <blockquote> <tt>http://www.cygnus.com/cygwin/index.html</tt> </blockquote></li></ul><ul><li>Programs compiled using Cygwin require a special DLL (<b>cygwin1.dll</b>) that provides a POSIX system API</li></ul><ul><li>Cygwin1.dll cannot be shipped with proprietary programs without purchasing a license from Cygnus.</li></ul><ul><li>Mingw32 is the same compiler as Cygwin, but generates binaries that do not use cygwin1.dll</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Where Does <tt>-ltcl82</tt> Come From On Windows?</h2> <p><p>Build it like this:</p></p><p> <p><ul><li>Get <b>tcl82.lib</b> and <b>tcl82.dll</b> from Scriptics.</li></ul><ul><li><tt>echo EXPORTS >tcl82.def</tt></li></ul><ul><li><tt>nm tcl82.lib | grep 'T _' | sed 's/.* T _//' >>tcl82.def</tt></li></ul><ul><li><tt>dlltool --def tcl82.def --dllname tcl82.dll --output-lib libtcl82.a</tt></li></ul><ul><li>Move <b>libtcl82.a</b> to the lib directory and <b>tcl82.dll</b> to the bin directory.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Where Does Your Code Go?</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Your&nbsp;application&nbsp;code&nbsp;goes&nbsp;here&nbsp;*/</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Insert C code here to do whatever it is your program is suppose to do</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Building A Simple TCLSH</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;char&nbsp;*z;<br> &nbsp;&nbsp;char&nbsp;zLine[2000];<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;while(&nbsp;fgets(zLine,sizeof(zLine),stdin)&nbsp;){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Get one line of input</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zLine);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Execute the input as Tcl.</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;z&nbsp;=&nbsp;Tcl_GetStringResult(interp);<br> &nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;z[0]&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("¸üÿ¿PX¶\n",&nbsp;z);<br> &nbsp;&nbsp;&nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Print result if not empty</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;}<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>What if user types more than 2000 characters?</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Building A Simple TCLSH</h2> <p>Use TCL to handle input. Allows input lines of unlimited length.</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> /*&nbsp;Tcl&nbsp;code&nbsp;to&nbsp;implement&nbsp;the<br> **&nbsp;input&nbsp;loop&nbsp;*/<br> static&nbsp;char&nbsp;zLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\n"</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"&nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]\n"</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Get one line of input</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"&nbsp;&nbsp;set&nbsp;result&nbsp;[eval&nbsp;$line]\n"</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Execute input as Tcl</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"&nbsp;&nbsp;if&nbsp;{$result!=\"\"}&nbsp;{puts&nbsp;$result}\n"</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Print result</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"}\n"<br> ;<br> &nbsp;<br> <br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zLoop);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Run the Tcl input loop</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>But what about commands that span multiple lines of input?</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Better Handling Of Command-Line Input</h2> <p>The file "input.tcl"</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>set&nbsp;line&nbsp;{}<br> while&nbsp;{![eof&nbsp;stdin]}&nbsp;{</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if&nbsp;{$line!=""}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;">&nbsp;"<br> &nbsp;&nbsp;}&nbsp;else&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;"%&nbsp;"<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;flush&nbsp;stdout</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Prompt for user input. The prompt is normally &quot;%&quot; but changes to &quot;&gt;&quot; if the current line is a continuation.</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]<br> &nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">If the command is complete, execute it.</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;"Error:&nbsp;$result"<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=""}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;}&nbsp;else&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\n<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">If the command is incomplete, append a newline and get another line of text.</td> </tr> <tr><td valign="center"> <small><tt>}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Better Handling Of Command-Line Input</h2> <p>The file "input.c"</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;"source&nbsp;input.tcl");</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Read and execute the input loop</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>But now the program is not standalone!</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Converting Scripts Into C Strings</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;"set&nbsp;line&nbsp;{}\n"<br> &nbsp;&nbsp;"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;if&nbsp;{$line!=\"\"}&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\">&nbsp;\"\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;}&nbsp;else&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\"%&nbsp;\"\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;}\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;flush&nbsp;stdout\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;\"Error:&nbsp;$result\"\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=\"\"}&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;}\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;}&nbsp;else&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\\n\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;}\n"<br> &nbsp;&nbsp;"}\n"<br> ;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Compile Tcl Scripts Into C Programs</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt><br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Actual&nbsp;code&nbsp;omitted&nbsp;*/<br> ;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Copy and paste the converted Tcl script here</td> </tr> <tr><td valign="center"> <small><tt><br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Execute the Tcl code</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Converting Scripts To Strings<br>Using SED Or TCLSH</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>sed&nbsp;-e&nbsp;'s/\\/\\\\/g'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Convert <b>\</b> into <b>\\</b></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'s/"/\\"/g'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Convert <b>"</b> into <b>\"</b></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'s/^/&nbsp;&nbsp;"/'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Add <b>"</b> to start of each line</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'s/$/\\n"/'&nbsp;input.tcl</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Add <b>\n"</b> to end of each line</td> </tr> <tr><td valign="center"> <small><tt><br> &nbsp;<br> <br> &nbsp;<br> <br> while&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br> &nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\}&nbsp;$line&nbsp;{&amp;&amp;}&nbsp;line</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Convert <b>\</b> into <b>\\</b></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{"}&nbsp;$line&nbsp;{\"}&nbsp;line</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Convert <b>"</b> into <b>\"</b></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;puts&nbsp;"\"$line\\n\""</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Add <b>"</b> in front and <b>\n"</b> at the end</td> </tr> <tr><td valign="center"> <small><tt>}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Converting Scripts Into C Strings</h2> <p>You may want to save space by removing comments and extra whitespace from scripts.</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;"set&nbsp;line&nbsp;{}\n"<br> &nbsp;&nbsp;"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\n"<br> &nbsp;&nbsp;"if&nbsp;{$line!=\"\"}&nbsp;{\n"<br> &nbsp;&nbsp;"puts&nbsp;-nonewline&nbsp;\">&nbsp;\"\n"<br> &nbsp;&nbsp;"}&nbsp;else&nbsp;{\n"<br> &nbsp;&nbsp;"puts&nbsp;-nonewline&nbsp;\"%&nbsp;\"\n"<br> &nbsp;&nbsp;"}\n"<br> &nbsp;&nbsp;"flush&nbsp;stdout\n"<br> &nbsp;&nbsp;"append&nbsp;line&nbsp;[gets&nbsp;stdin]\n"<br> &nbsp;&nbsp;"if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{\n"<br> &nbsp;&nbsp;"if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{\n"<br> &nbsp;&nbsp;"puts&nbsp;stderr&nbsp;\"Error:&nbsp;$result\"\n"<br> &nbsp;&nbsp;"}&nbsp;elseif&nbsp;{$result!=\"\"}&nbsp;{\n"<br> &nbsp;&nbsp;"puts&nbsp;$result\n"<br> &nbsp;&nbsp;"}\n"<br> &nbsp;&nbsp;"set&nbsp;line&nbsp;{}\n"<br> &nbsp;&nbsp;"}&nbsp;else&nbsp;{\n"<br> &nbsp;&nbsp;"append&nbsp;line&nbsp;\\n\n"<br> &nbsp;&nbsp;"}\n"<br> &nbsp;&nbsp;"}\n"<br> ;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Converting Scripts To Strings</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>sed&nbsp;-e&nbsp;'s/\\/\\\\/g'&nbsp;\&nbsp;<br> &nbsp;&nbsp;-e&nbsp;'s/"/\\"/g'&nbsp;\&nbsp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'/^&nbsp;*#/d'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Delete lines that begin with #</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'/^&nbsp;*$/d'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Delete blank lines</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'s/^&nbsp;*/&nbsp;&nbsp;"/'&nbsp;\&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Delete leading spaces</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;-e&nbsp;'s/$/\\n"/'&nbsp;input.tcl<br> &nbsp;<br> <br> &nbsp;<br> <br> &nbsp;<br> while&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br> &nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;set&nbsp;line&nbsp;[string&nbsp;trimleft&nbsp;$line]</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Remove leading space</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if&nbsp;{$line==""}&nbsp;continue</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Delete blank lines</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if&nbsp;{[string&nbsp;index&nbsp;$line&nbsp;0]=="#"}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;continue<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Delete lines starting with #</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\}&nbsp;$line&nbsp;{&amp;&amp;}&nbsp;line<br> &nbsp;&nbsp;regsub&nbsp;-all&nbsp;{"}&nbsp;$line&nbsp;{\"}&nbsp;line<br> &nbsp;&nbsp;puts&nbsp;"\"$line\\n\""<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Removing Comments Or Leading Space<br>Will Break Some Tcl Scripts!</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>image&nbsp;create&nbsp;bitmap&nbsp;smiley&nbsp;-data&nbsp;{</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>#define&nbsp;smile_width&nbsp;15<br> #define&nbsp;smile_height&nbsp;15</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">These lines begin with # but are not comment</td> </tr> <tr><td valign="center"> <small><tt>static&nbsp;unsigned&nbsp;char&nbsp;smile_bits[]&nbsp;=&nbsp;{<br> &nbsp;&nbsp;&nbsp;0xc0,&nbsp;0x01,&nbsp;0x30,&nbsp;0x06,&nbsp;0x0c,&nbsp;0x18,<br> &nbsp;&nbsp;&nbsp;0x04,&nbsp;0x10,&nbsp;0x22,&nbsp;0x22,&nbsp;0x52,&nbsp;0x25,<br> &nbsp;&nbsp;&nbsp;0x01,&nbsp;0x40,&nbsp;0x01,&nbsp;0x40,&nbsp;0x01,&nbsp;0x40,<br> &nbsp;&nbsp;&nbsp;0x12,&nbsp;0x24,&nbsp;0xe2,&nbsp;0x23,&nbsp;0x04,&nbsp;0x10,<br> &nbsp;&nbsp;&nbsp;0x0c,&nbsp;0x18,&nbsp;0x30,&nbsp;0x06,&nbsp;0xc0,&nbsp;0x01};<br> }<br> &nbsp;<br> <br> &nbsp;<br> text&nbsp;.t<br> pack&nbsp;.t<br> .t&nbsp;insert&nbsp;end&nbsp;[string&nbsp;trim&nbsp;{</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>She&nbsp;walks&nbsp;in&nbsp;beauty,&nbsp;like&nbsp;the&nbsp;night<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Of&nbsp;cloudless&nbsp;climes&nbsp;and&nbsp;starry&nbsp;skies;<br> And&nbsp;all&nbsp;that's&nbsp;best&nbsp;of&nbsp;dark&nbsp;and&nbsp;bright<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Meet&nbsp;in&nbsp;her&nbsp;aspect&nbsp;and&nbsp;her&nbsp;eyes;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Indentation is deleted on lines 2 and 4</td> </tr> <tr><td valign="center"> <small><tt>}]&nbsp;<br> &nbsp;<br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>Problems like these are rare</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Adding A "continue" Command</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>set&nbsp;line&nbsp;{}<br> while&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br> &nbsp;&nbsp;if&nbsp;{$line!=""}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;">&nbsp;"<br> &nbsp;&nbsp;}&nbsp;else&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;"%&nbsp;"<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;flush&nbsp;stdout<br> &nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]<br> &nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[lindex&nbsp;$line&nbsp;0]=="continue"}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Break out of the loop if the command is "continue"</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;"Error:&nbsp;$result"<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=""}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}<br> &nbsp;&nbsp;}&nbsp;else&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\n<br> &nbsp;&nbsp;}<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Stop For Tcl Input At Various Points<br>In A C Program</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;Input&nbsp;loop&nbsp;as&nbsp;a&nbsp;C&nbsp;string&nbsp;*/<br> ;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Do some computation</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Stop for some Tcl input</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;More&nbsp;application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Do more computation</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Stop for more Tcl input</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Finish&nbsp;up&nbsp;the&nbsp;application&nbsp;*/</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Finish the computation</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Using Tcl For Testing</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;Input&nbsp;loop&nbsp;as&nbsp;a&nbsp;C&nbsp;string&nbsp;*/<br> ;<br> &nbsp;<br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> #ifdef&nbsp;TESTING<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Create interpreter only if TESTING is defined</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br> #endif<br> &nbsp;&nbsp;/*&nbsp;Application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>#ifdef&nbsp;TESTING<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> #endif</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Accept command-line input only if TESTING is defined</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;More&nbsp;application&nbsp;C&nbsp;code&nbsp;*/<br> #ifdef&nbsp;TESTING<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> #endif<br> &nbsp;&nbsp;/*&nbsp;Finish&nbsp;up&nbsp;the&nbsp;application&nbsp;*/<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Creating A New Tcl Command In C</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> int&nbsp;NewCmd(</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;void&nbsp;*clientData,<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp,<br> &nbsp;&nbsp;int&nbsp;argc,<br> &nbsp;&nbsp;char&nbsp;**argv</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">The Tcl command is implemented as a C function with four arguments.</td> </tr> <tr><td valign="center"> <small><tt>){<br> &nbsp;&nbsp;printf("Hello,&nbsp;World!\n");</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Returns TCL_OK or TCL_ERROR</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br> ;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_CreateCommand(interp,&nbsp;"helloworld",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewCmd,&nbsp;0,&nbsp;0);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Tell the interpreter which C function to call when the "helloworld" Tcl command is executed</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Linkage From Tcl To C</h2> <p><p align="center"><img src="image4"></p></p><p><ul><li>3rd parameter of Tcl_CreateCommand() is a pointer to the C subroutine that implements the command.</li></ul><ul><li>4th parameter to Tcl_CreateCommand() becomes the 1st parameter to the C routine whenever the Tcl command is executed.</li></ul><ul><li>1st parameter to Tcl_CreateCommand() must be a valid Tcl interpreter. The same pointer appears as the second parameter to the C routine whenever the Tcl command is executed.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Linkage From Tcl To C</h2> <p><p align="center"><img src="image5"></p></p><p><ul><li>5th parameter of Tcl_CreateCommand() is a pointer to the C subroutine that is called when the Tcl command is deleted.</li></ul><ul><li>4th parameter to Tcl_CreateCommand() becomes the 1st parameter to the C routine.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">When To Use A Delete Proc</h2> <p>Examples of where the delete proc is used in standard Tcl/Tk:</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>button&nbsp;.b&nbsp;-text&nbsp;Hello<br> pack&nbsp;.b</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>rename&nbsp;.b&nbsp;{}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Deleting the <b>.b</b> command causes the button to be destroyed</td> </tr> <tr><td valign="center"> <small><tt><br> &nbsp;<br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>image&nbsp;create&nbsp;photo&nbsp;smiley&nbsp;\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;-file&nbsp;smiley.gif</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>rename&nbsp;smiley&nbsp;{}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Deleting the <b>smiley</b> command destroys the image and reclaims the memory used to hold the image</td> </tr> </table> <p><ul><li>Always use a delete proc if the clientData is a pointer to malloced memory or some other resource that needs freeing</li></ul><ul><li>Delete procs are never used in the Tcl core but are used extensively in Tk</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Linkage From Tcl To C</h2> <p>The <tt>argc</tt> and <tt>argv</tt> parameters work just like in <tt>main()</tt></p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>helloworld&nbsp;one&nbsp;{two&nbsp;three}&nbsp;four</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center"><tt>argc = 4<br> argv[0] = "helloworld"<br> argv[1] = "one"<br> argv[2] = "two three"<br> argv[3] = "four"<br> argv[4] = NULL</tt></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">A Short-Cut</h2> <p>In a program with many new Tcl commands implemented in C, it becomes tedious to type the same four parameters over and over again. So we define a short-cut.</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#define&nbsp;TCLARGS&nbsp;\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;*clientData,&nbsp;\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;Tcl_Interp&nbsp;*interp,&nbsp;\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;argc,&nbsp;\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*argv</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Define TCLARGS once in a header file</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;<br> &nbsp;<br> &nbsp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Use the TCLARGS macro to define new C functions that implement Tcl commands.</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;/*&nbsp;implementation...&nbsp;*/<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>For brevity, we will use the TCLARGS macro during the rest of this talk.</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Returning A Value From C Back To Tcl</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Note that the C function returns an "int"</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Return value is TCL_OK or TCL_ERROR</td> </tr> <tr><td valign="center"> <small><tt>}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><ul><li>TCL_OK and TCL_ERROR are defined in &lt;tcl.h&gt;</li></ul><ul><li>Other valid return values TCL_RETURN, TCL_BREAK and TCL_CONTINUE are rarely used</li></ul><ul><li>Common mistake: forgetting to return TCL_OK</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Returning A Value From C Back To Tcl</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_SetResult(interp,"Hello!",TCL_STATIC);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Set the result to "Hello!"</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><ul><li>Result should be the text of an error message if you return TCL_ERROR.</li></ul><ul><li>3rd argument to Tcl_SetResult() can be TCL_STATIC, TCL_DYNAMIC, TCL_VOLATILE, or a function pointer.</li></ul><ul><li>Also consider using Tcl_AppendResult().</li></ul><ul><li>Direct access to <tt>interp->result</tt> is deprecated.</li></ul><ul><li>See the man pages for details.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">The Tcl_Obj Interface</h2> <p><ul><li>A new way to write Tcl commands in C code</li></ul><ul><li>First introduced in Tcl8.0</li></ul><ul><li>Can be much faster, especially for lists or numeric values.</li></ul><ul><li>Able to handle arbitrary binary data.</li></ul><ul><li>More difficult to program.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">The Tcl_Obj Interface</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>int&nbsp;NewObjCmd(<br> &nbsp;&nbsp;void&nbsp;*clientData,<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp,<br> &nbsp;&nbsp;int&nbsp;objc,</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Obj&nbsp;*const*&nbsp;objv</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">4th parameter is an array Tcl_Objs, not an array of strings</td> </tr> <tr><td valign="center"> <small><tt>){<br> &nbsp;&nbsp;/*&nbsp;Implementation...&nbsp;*/<br> &nbsp;&nbsp;return&nbsp;TCL_OK;<br> }<br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br> ;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_CreateObjCommand(interp,&nbsp;"newcmd",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewObjCmd,&nbsp;0,&nbsp;0);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Use a different function to register the command</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">The Tcl_Obj Interface</h2> <p><ul><li>There are countless access methods for reading information from and placing information in Tcl_Objs. Always use the access methods.</li></ul><ul><li>Details provided at Lee Bernhard's talk this afternoon.</li></ul><ul><li>Definitely use Tcl_Objs if you are writing a new Tcl extension.</li></ul><ul><li>Tcl_Objs address some of the weaknesses of Tcl relative to C/C++. <ul> <li> Tcl_Objs are faster </li> <li> Tcl_Objs work with binary data </li> </ul> But C/C++ is faster still and better for working with binary data.</li></ul><ul><li>When mixing C/C++ with Tcl/Tk the benefits of Tcl_Objs are less important. Using Tcl_Objs in this context may not be worth the extra trouble.</li></ul><ul><li>This talk will focus on the string interface.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Nickel Tour Of The Tcl API</h2> <p><p><b>Memory allocation functions</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_Alloc<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_Free<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_Realloc<br> </tt></small></td> </table></center><p><b>Functions useful in the implementation of new Tcl commands</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_AppendElement<br> Tcl_AppendResult<br> Tcl_GetBoolean<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_GetDouble<br> Tcl_GetInt<br> Tcl_GetStringResult<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_ResetResult<br> Tcl_SetResult<br> </tt></small></td> </table></center><p><b>Functions for controlling the Tcl interpreter</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_CreateCommand<br> Tcl_CreateInterp<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_CreateObjCommand<br> Tcl_DeleteCommand<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_DeleteInterp<br> Tcl_Exit<br> </tt></small></td> </table></center></p> <br clear="both"><p><hr></p> <h2 align="center">Nickel Tour Of The Tcl API</h2> <p><p><b>I/O functions</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_Close<br> Tcl_Eof<br> Tcl_Flush<br> Tcl_GetChannel<br> Tcl_GetChannelMode<br> Tcl_GetChannelName<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_Gets<br> Tcl_OpenCommandChannel<br> Tcl_OpenFileChannel<br> Tcl_OpenTcpClient<br> Tcl_OpenTcpServer<br> Tcl_Read<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_Seek<br> Tcl_Tell<br> Tcl_Ungets<br> Tcl_Write<br> Tcl_WriteChars<br> </tt></small></td> </table></center><p><b>Names and meanings of system error codes</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_ErrnoId<br> Tcl_ErrnoMsg<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_GetErrno<br> Tcl_SetErrno<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_SignalId<br> Tcl_SignalMsg<br> </tt></small></td> </table></center></p> <br clear="both"><p><hr></p> <h2 align="center">Nickel Tour Of The Tcl API</h2> <p><p><b>General Operating System Calls</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_Access<br> Tcl_Chdir<br> Tcl_GetCwd<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_GetHostName<br> Tcl_GetNameOfExecutable<br> Tcl_Sleep<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_Stat<br> </tt></small></td> </table></center><p><b>String Manipulation And Comparison</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_Concat<br> Tcl_Merge<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_SplitList<br> Tcl_StringCaseMatch<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_StringMatch<br> </tt></small></td> </table></center><p><b>Dynamically Resizable Strings</b></p> <center><table width="90%"><tr> <td width="49%" valign="top"><small><tt> Tcl_DStringAppend<br> Tcl_DStringAppendElement<br> Tcl_DStringEndSublist<br> Tcl_DStringInit<br> Tcl_DStringLength<br> </tt></small></td> <td width="49%" valign="top"><small><tt> Tcl_DStringResult<br> Tcl_DStringSetLength<br> Tcl_DStringStartSublist<br> Tcl_DStringValue<br> </tt></small></td> </table></center></p> <br clear="both"><p><hr></p> <h2 align="center">Nickel Tour Of The Tcl API</h2> <p><p><b>Event Handlers</b></p> <center><table width="90%"><tr> <td width="49%" valign="top"><small><tt> Tcl_CancelIdleCall<br> Tcl_CreateChannelHandler<br> Tcl_CreateTimerHandler<br> Tcl_DeleteChannelHandler<br> </tt></small></td> <td width="49%" valign="top"><small><tt> Tcl_DeleteTimerHandler<br> Tcl_DoOneEvent<br> Tcl_DoWhenIdle<br> </tt></small></td> </table></center><p><b>Functions For Reading And Writing Tcl Variables</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_GetVar<br> Tcl_GetVar2<br> Tcl_LinkVar<br> Tcl_SetVar<br> Tcl_SetVar2<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_TraceVar<br> Tcl_TraceVar2<br> Tcl_UnlinkVar<br> Tcl_UnsetVar<br> Tcl_UnsetVar2<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_UntraceVar<br> Tcl_UntraceVar2<br> Tcl_UpdateLinkedVar<br> </tt></small></td> </table></center><p><b>Functions For Executing Tcl Code</b></p> <center><table width="90%"><tr> <td width="32%" valign="top"><small><tt> Tcl_Eval<br> Tcl_EvalFile<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_EvalObj<br> Tcl_GlobalEval<br> </tt></small></td> <td width="32%" valign="top"><small><tt> Tcl_GlobalEvalObj<br> Tcl_VarEval<br> </tt></small></td> </table></center></p> <br clear="both"><p><hr></p> <h2 align="center">Nickel Tour Of The Tcl API</h2> <p><p><b>Functions For Dealing With Unicode</b></p> <center><table width="90%"><tr> <td width="49%" valign="top"><small><tt> Tcl_NumUtfChars<br> Tcl_UniCharAtIndex<br> Tcl_UniCharIsAlnum<br> Tcl_UniCharIsAlpha<br> Tcl_UniCharIsControl<br> Tcl_UniCharIsDigit<br> Tcl_UniCharIsGraph<br> Tcl_UniCharIsLower<br> Tcl_UniCharIsPrint<br> Tcl_UniCharIsPunct<br> Tcl_UniCharIsSpace<br> Tcl_UniCharIsUpper<br> Tcl_UniCharIsWordChar<br> Tcl_UniCharLen<br> Tcl_UniCharNcmp<br> Tcl_UniCharToLower<br> Tcl_UniCharToTitle<br> </tt></small></td> <td width="49%" valign="top"><small><tt> Tcl_UniCharToUpper<br> Tcl_UniCharToUtf<br> Tcl_UniCharToUtfDString<br> Tcl_UtfAtIndex<br> Tcl_UtfBackslash<br> Tcl_UtfCharComplete<br> Tcl_UtfFindFirst<br> Tcl_UtfFindLast<br> Tcl_UtfNcasecmp<br> Tcl_UtfNcmp<br> Tcl_UtfNext<br> Tcl_UtfPrev<br> Tcl_UtfToLower<br> Tcl_UtfToTitle<br> Tcl_UtfToUniChar<br> Tcl_UtfToUniCharDString<br> Tcl_UtfToUpper<br> </tt></small></td> </table></center> <p><b>Functions For Dealing With Tcl_Objs</b></p> <blockquote><i>Too numerous to list...</i></blockquote></p> <br clear="both"><p><hr></p> <h2 align="center">Documentation Of The Tcl API</h2> <p><ul><li>Tcl comes with excellent man pages</li></ul><ul><li>"Use the source, Luke"</li></ul><ul><li>See <tt>tclDecl.h</tt> for a list of API functions</li></ul><ul><li>The header comments on the implementation of API functions usually gives a good description of what the function does and how it should be used.</li></ul><ul><li>Most API functions are used within Tcl and Tk. Use grep to locate examples.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Initialization Scripts</h2> <p><ul><li>Run the mini TCLSH implemented above and execute the <tt>parray</tt> command</li></ul><ul><li>It doesn't work! What's wrong? </p></li></li></ul><ul><li><tt>parray</tt> is really a Tcl proc that is read in when the interpreter is initialized. </p></li></li></ul><ul><li><tt>parray</tt> (and several other commands) are stored in a handful of &quot;Initialization Scripts&quot; </p></li></li></ul><ul><li>All the initialization scripts are stored in the &quot;Tcl Library&quot; - a directory on the host computer. </p></li></li></ul><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>Invoke the Tcl_Init() function to locate and read the Tcl initialization scripts.</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">The <tt>Tcl_Init()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br> ;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Init(interp);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Locate and read the initialization scripts</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Call&nbsp;Tcl_CreateCommand()?&nbsp;*/<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>But Tcl_Init() can fail. We need to check its return value...</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">The <tt>Tcl_Init()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br> &nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br> ;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_Init(interp)!=TCL_OK&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"Tcl_Init()&nbsp;failed:&nbsp;¸üÿ¿PX¶",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tcl_GetStringResult(interp));<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Print error message if Tcl_Init() fails</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Call&nbsp;Tcl_CreateCommand()?&nbsp;*/<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>But now the program is not standalone.</b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">How <tt>Tcl_Init()</tt> Works</h2> <p><ul><li>Computes the value of variable <tt>tcl_libPath</tt>.</li></ul><ul><li>Invokes the procedure named &quot;<tt>tclInit</tt>&quot;</li></ul><ul><li>A default <tt>tclInit</tt> procedure is built into Tcl. You can define an alternative <tt>tclInit</tt> procedure prior to calling <tt>Tcl_Init()</tt>.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">The Default <tt>initTcl</tt> Procedure</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>set&nbsp;errors&nbsp;{}<br> set&nbsp;dirs&nbsp;{}<br> if&nbsp;{[info&nbsp;exists&nbsp;tcl_library]}&nbsp;{<br> &nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$tcl_library<br> }&nbsp;else&nbsp;{<br> &nbsp;&nbsp;if&nbsp;{[info&nbsp;exists&nbsp;env(TCL_LIBRARY)]}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$env(TCL_LIBRARY)<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$tclDefaultLibrary<br> &nbsp;&nbsp;unset&nbsp;tclDefaultLibrary<br> &nbsp;&nbsp;set&nbsp;dirs&nbsp;[concat&nbsp;$dirs&nbsp;$tcl_libPath]<br> }<br> foreach&nbsp;i&nbsp;$dirs&nbsp;{<br> &nbsp;&nbsp;set&nbsp;tcl_library&nbsp;$i<br> &nbsp;&nbsp;set&nbsp;tclfile&nbsp;[file&nbsp;join&nbsp;$i&nbsp;init.tcl]<br> &nbsp;&nbsp;if&nbsp;{[file&nbsp;exists&nbsp;$tclfile]}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{![catch&nbsp;{uplevel&nbsp;#0&nbsp;[list&nbsp;source&nbsp;$tclfile]}&nbsp;msg]}&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;errors&nbsp;"$tclfile:&nbsp;$msg\n$errorInfo\n"<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> error&nbsp;"Can't&nbsp;find&nbsp;a&nbsp;usable&nbsp;init.tcl&nbsp;..."</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">The Default Initialization Sequence</h2> <p><ul><li>The <tt>tclInit</tt> procedure locates and sources the <tt>init.tcl</tt> script. The directory that contains <tt>init.tcl</tt> is stored in the <tt>tcl_library</tt> variable.</li></ul><ul><li>The <tt>init.tcl</tt> script creates an <tt>unknown</tt> procedure. The <tt>unknown</tt> procedure will run whenever Tcl encounters an unknown command.</li></ul><ul><li>The <tt>unknown</tt> procedure consults the file <tt>tclIndex</tt> in the <tt>tcl_library</tt> directory to see if the command is defined by one of the initialization scripts.</li></ul><ul><li>The <tt>unknown</tt> procedure sources any needed initialization scripts and retries the command.</li></ul><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>Commands defined in the initialization scripts are loaded on demand.</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">Standalone Initialization Techniques</h2> <p><p><b>Manually execute all initialization scripts</b></p> <ul><li>Convert all initialization scripts into C strings and put them in the executable.</li></ul><ul><li>Call <tt>Tcl_Eval()</tt> on each initialization script and omit the call to <tt>Tcl_Init()</tt></li></ul><ul><li>Or, redefine <tt>tclInit</tt> so that it does not attempt to source <tt>init.tcl</tt> then call <tt>Tcl_Eval()</tt> on each initialization script after <tt>Tcl_Init()</tt> returns.</li></ul><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>This approach is not recommended</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">Standalone Initialization Techniques</h2> <p><p><b>Redefining the builtin <tt>source</tt> command</b></p> <ul><li>Convert all initialization scripts into C strings and put them in the executable.</li></ul><ul><li>Create a new <tt>source</tt> command that calls <tt>Tcl_Eval()</tt> on the appropriate built-in string instead of reading from the disk.</li></ul><ul><li>Read from disk if the named file is not one that is built in.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Redefining <tt>source</tt></h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>static&nbsp;char&nbsp;zInitTcl[]&nbsp;=&nbsp;"...";<br> static&nbsp;char&nbsp;zParrayTcl[]&nbsp;=&nbsp;"...";</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Scripts <tt>init.tcl</tt> and <tt>parray.tcl</tt></td> </tr> <tr><td valign="center"> <small><tt><br> int&nbsp;NewSourceCmd(TCLARGS){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;!strcmp(argv[1],"/builtin/init.tcl")&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Tcl_Eval(interp,&nbsp;zInitTcl);<br> &nbsp;&nbsp;if(&nbsp;!strcmp(argv[1],"/builtin/parray.tcl")&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Tcl_Eval(interp,&nbsp;zParrayTcl);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Call <tt>Tcl_Eval()</tt> on builtin strings if the names match</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;Tcl_EvalFile(interp,&nbsp;argv[1]);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Call <tt>Tcl_EvalFile()</tt> if no match</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;setenv("TCL_LIBRARY","/builtin");</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Causes <tt>tclInit</tt> to look for <tt>init.tcl</tt> in <tt>/builtin</tt></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_CreateCommand(interp,&nbsp;"source",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewSourceCmd,&nbsp;0,&nbsp;0);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Redefine <tt>source</tt></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Init(interp);<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Redefining <tt>source</tt></h2> <p><ul><li>This approach works for all versions of Tcl and Tk.</li></ul><ul><li>Also need to redefine the "<tt>file exists</tt>" Tcl command since it too is used by <tt>tclInit</tt>.</li></ul><ul><li>To verify that the program is really standalone, remove the call to <tt>Tcl_EvalFile()</tt>.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Standalone Initialization Techniques</h2> <p><p><b>Use the <tt>Tcl</tt>*<tt>InsertProc()</tt> functions</b></p> <ul><li>Three routines that overload basic file I/O operations: <ul> <li> <tt>TclStatInsertProc()</tt> </li> <li> <tt>TclAccessInsertProc()</tt> </li> <li> <tt>TclOpenFileChannelInsertProc()</tt> </li> </ul></li></ul><ul><li>Allows us to implement a virtual filesystem that overlays the real filesystem.</li></ul><ul><li>The virtual filesystem contains all the initialization scripts as compiled-in strings. The initialization scripts look like they are resident on disk even though they are built in.</li></ul><ul><li>These functions first appeared in Tcl8.0.3. Presumably to support TclPro Wrapper.</li></ul><ul><li>The only documentation is comments on the code. See the Tcl source file <tt>generic/tclIOUtil.c</tt></li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">The <tt>TclStatInsertProc()</tt> Function</h2> <p><ul><li>Sole argument is a pointer to a function whose interface is the same as <tt>stat()</tt></li></ul><ul><li>Functions are stacked. Tcl tries each <tt>stat</tt> function on the list, beginning with the most recently inserted, until one succeeds.</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">The <tt>TclStatInsertProc()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tclInt.h></tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Rather than <tt>&lt;tcl.h&gt;</tt>!</td> </tr> <tr><td valign="center"> <small><tt><br> static&nbsp;int<br> BltinFileStat(char&nbsp;*path,struct&nbsp;stat&nbsp;*buf){<br> &nbsp;&nbsp;char&nbsp;*zData;<br> &nbsp;&nbsp;int&nbsp;nData;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(path,&nbsp;0,&nbsp;&amp;nData);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Check if <tt>path</tt> is a builtin</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;zData==0&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Fail if <tt>path</tt> is not a builtin</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;memset(buf,&nbsp;0,&nbsp;sizeof(*buf));<br> &nbsp;&nbsp;buf->st_mode&nbsp;=&nbsp;0400;<br> &nbsp;&nbsp;buf->st_size&nbsp;=&nbsp;nData;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Success if it is builtin</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;TclStatInsertProc(BltinFileStat);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Register new <tt>stat</tt> function</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br> &nbsp;&nbsp;Tcl_Init(interp);<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">The <tt>TclAccessInsertProc()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tclInt.h></tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Rather than <tt>&lt;tcl.h&gt;</tt>!</td> </tr> <tr><td valign="center"> <small><tt><br> /*&nbsp;BltinFileStat()&nbsp;not&nbsp;shown...&nbsp;*/<br> &nbsp;<br> static&nbsp;int<br> BltinFileAccess(char&nbsp;*path,&nbsp;int&nbsp;mode){<br> &nbsp;&nbsp;char&nbsp;*zData;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;mode&nbsp;&amp;&nbsp;3&nbsp;)&nbsp;return&nbsp;-1;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">All builtins are read-only</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(path,&nbsp;0,&nbsp;&amp;nData);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Check if <tt>path</tt> is a builtin</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;zData==0&nbsp;)&nbsp;return&nbsp;-1;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Fail if <tt>path</tt> is not a builtin</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;0;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Success if it is builtin</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;TclStatInsertProc(BltinFileStat);<br> &nbsp;&nbsp;TclAccessInsertProc(BltinFileAccess);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Register new <tt>stat</tt> and <tt>access</tt> functions</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br> &nbsp;&nbsp;Tcl_Init(interp);<br> &nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">The <tt>TclOpenFileChannelInsertProc()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>static&nbsp;Tcl_Channel&nbsp;BuiltinFileOpen(<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp,&nbsp;&nbsp;&nbsp;/*&nbsp;The&nbsp;TCL&nbsp;interpreter&nbsp;doing&nbsp;the&nbsp;open&nbsp;*/<br> &nbsp;&nbsp;char&nbsp;*zFilename,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Name&nbsp;of&nbsp;the&nbsp;file&nbsp;to&nbsp;open&nbsp;*/<br> &nbsp;&nbsp;char&nbsp;*modeString,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Mode&nbsp;string&nbsp;for&nbsp;the&nbsp;open&nbsp;(ignored)&nbsp;*/<br> &nbsp;&nbsp;int&nbsp;permissions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Permissions&nbsp;for&nbsp;a&nbsp;newly&nbsp;created&nbsp;file&nbsp;(ignored)&nbsp;*/<br> ){<br> &nbsp;&nbsp;char&nbsp;*zData;<br> &nbsp;&nbsp;BuiltinFileStruct&nbsp;*p;<br> &nbsp;&nbsp;int&nbsp;nData;<br> &nbsp;&nbsp;char&nbsp;zName[50];<br> &nbsp;&nbsp;Tcl_Channel&nbsp;chan;<br> &nbsp;&nbsp;static&nbsp;int&nbsp;count&nbsp;=&nbsp;1;<br> &nbsp;<br> &nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(zFilename,&nbsp;1,&nbsp;&amp;nData);<br> &nbsp;&nbsp;if(&nbsp;zData==0&nbsp;)&nbsp;return&nbsp;NULL;<br> &nbsp;&nbsp;p&nbsp;=&nbsp;(BuiltinFileStruct*)Tcl_Alloc(&nbsp;sizeof(BuiltinFileStruct)&nbsp;);<br> &nbsp;&nbsp;if(&nbsp;p==0&nbsp;)&nbsp;return&nbsp;NULL;<br> &nbsp;&nbsp;p->zData&nbsp;=&nbsp;zData;<br> &nbsp;&nbsp;p->nData&nbsp;=&nbsp;nData;<br> &nbsp;&nbsp;p->cursor&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;sprintf(zName,"etbi_bffffc7c_8049b04",((int)BuiltinFileOpen)>>12,count++);<br> &nbsp;&nbsp;chan&nbsp;=&nbsp;Tcl_CreateChannel(&amp;builtinChannelType,&nbsp;zName,&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ClientData)p,&nbsp;TCL_READABLE);<br> &nbsp;&nbsp;return&nbsp;chan;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">The <tt>TclOpenFileChannelInsertProc()</tt> Function</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>static&nbsp;Tcl_ChannelType&nbsp;builtinChannelType&nbsp;=&nbsp;{<br> &nbsp;&nbsp;"builtin",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Type&nbsp;name.&nbsp;*/<br> &nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Always&nbsp;non-blocking.*/<br> &nbsp;&nbsp;BuiltinFileClose,&nbsp;&nbsp;&nbsp;/*&nbsp;Close&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;BuiltinFileInput,&nbsp;&nbsp;&nbsp;/*&nbsp;Input&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;BuiltinFileOutput,&nbsp;&nbsp;/*&nbsp;Output&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;BuiltinFileSeek,&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Seek&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Set&nbsp;option&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Get&nbsp;option&nbsp;proc.&nbsp;*/<br> &nbsp;&nbsp;BuiltinFileWatch,&nbsp;&nbsp;&nbsp;/*&nbsp;Watch&nbsp;for&nbsp;events&nbsp;on&nbsp;console.&nbsp;*/<br> &nbsp;&nbsp;BuiltinFileHandle,&nbsp;&nbsp;/*&nbsp;Get&nbsp;a&nbsp;handle&nbsp;from&nbsp;the&nbsp;device.&nbsp;*/<br> };</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p> <p>For additional information see:</p> <ul> <li>The man page for <tt>Tcl_CreateChannel()</tt></li> <li>Tk source code file <tt>generic/tkConsole.c</tt></li> </ul> </p> <br clear="both"><p><hr></p> <h2 align="center">Initializing Tk</h2> <p><ul><li>All the same initialization script issues as Tcl</li></ul><ul><li>Tk initialization scripts are in a different directory than the Tcl initialization scripts - the "Tk Library"</li></ul><ul><li>Call <tt>Tk_Init()</tt> after <tt>Tcl_Init()</tt></li></ul><ul><li>Must have an event loop or Tk will not work!</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Implementing An Event Loop</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>button&nbsp;.b&nbsp;-text&nbsp;Hello&nbsp;-command&nbsp;exit<br> pack&nbsp;.b</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Create a Tk interface</td> </tr> <tr><td valign="center"> <small><tt><br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>bind&nbsp;.&nbsp;&lt;Destroy>&nbsp;{<br> &nbsp;&nbsp;if&nbsp;{![winfo&nbsp;exists&nbsp;.]}&nbsp;exit<br> }</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Close the application when the main window is destroyed</td> </tr> <tr><td valign="center"> <small><tt><br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>while&nbsp;1&nbsp;{vwait&nbsp;forever}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">The event loop</td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using Tk</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tk.h><br> &nbsp;<br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>static&nbsp;char&nbsp;zHello[]&nbsp;=&nbsp;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">The application code</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"button&nbsp;.b&nbsp;"<br> &nbsp;&nbsp;&nbsp;&nbsp;"-text&nbsp;{Hello,&nbsp;World}&nbsp;"<br> &nbsp;&nbsp;&nbsp;&nbsp;"-command&nbsp;exit\n"<br> &nbsp;&nbsp;"pack&nbsp;.b\n";<br> &nbsp;<br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>static&nbsp;char&nbsp;zEventLoop[]&nbsp;=</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">The event loop</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;"bind&nbsp;.&nbsp;&lt;Destroy>&nbsp;{\n"<br> &nbsp;&nbsp;"&nbsp;&nbsp;if&nbsp;{![winfo&nbsp;exists&nbsp;.]}&nbsp;exit\n"<br> &nbsp;&nbsp;"}\n"<br> &nbsp;&nbsp;"while&nbsp;1&nbsp;{vwait&nbsp;forever}\n";<br> &nbsp;<br> <br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br> &nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Init(interp);<br> &nbsp;&nbsp;Tk_Init(interp);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">We really should check the return values of the init functions...</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zHello);</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zEventLoop);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">The event loop never returns</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Compiling "Hello, World!" For Tk</h2> <p><p><b>Unix:</b></p> <blockquote><pre> $ gcc hello.c -ltk -L/usr/X11R6/lib \ -lX11 -ltcl -lm -ldl $ ./a.out</pre></blockquote> <p><b>Windows using Cygwin:</b></p> <blockquote><pre> C:> gcc hello.c -mwindows -ltk80 -ltcl80 -lm C:> a.exe</pre></blockquote> <p><b>Windows using Mingw32:</b></p> <blockquote><pre> C:> gcc -mno-cygwin hello.c -mwindows \ -ltk82 -ltcl82 -lm C:> a.exe</pre></blockquote></p> <br clear="both"><p><hr></p> <h2 align="center">Making The Program Standalone</h2> <p><p>To make a Tcl application standalone you have to convert the following initialization scripts to C strings and compile them into the executable:</p> <table><tr> <td valign="top"><tt> &nbsp;&nbsp;auto.tcl<br> &nbsp;&nbsp;history.tcl<br> &nbsp;&nbsp;init.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;ldAout.tcl<br> &nbsp;&nbsp;package.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;parray.tcl<br> &nbsp;&nbsp;safe.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;tclIndex<br> &nbsp;&nbsp;word.tcl </tt></td> </tr></table> <p>To make a Tk application standalone requires these additional initialization scripts from the Tk Library:</p> <table><tr> <td valign="top"><tt> &nbsp;&nbsp;bgerror.tcl<br> &nbsp;&nbsp;button.tcl<br> &nbsp;&nbsp;clrpick.tcl<br> &nbsp;&nbsp;comdlg.tcl<br> &nbsp;&nbsp;console.tcl<br> &nbsp;&nbsp;dialog.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;entry.tcl<br> &nbsp;&nbsp;focus.tcl<br> &nbsp;&nbsp;listbox.tcl<br> &nbsp;&nbsp;menu.tcl<br> &nbsp;&nbsp;msgbox.tcl<br> &nbsp;&nbsp;optMenu.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;palette.tcl<br> &nbsp;&nbsp;safetk.tcl<br> &nbsp;&nbsp;scale.tcl<br> &nbsp;&nbsp;scrlbar.tcl<br> &nbsp;&nbsp;tclIndex<br> &nbsp;&nbsp;tearoff.tcl </tt></td> <td valign="top"><tt> &nbsp;&nbsp;text.tcl<br> &nbsp;&nbsp;tk.tcl<br> &nbsp;&nbsp;tkfbox.tcl<br> &nbsp;&nbsp;xmfbox.tcl </tt></td> </tr></table> <p>Total of about 13K lines and 400K bytes of text or 9K lines and 250K bytes if you strip comments and leading spaces</p></p> <br clear="both"><p><hr></p> <h2 align="center">A Review Of The Features We Want</h2> <p><ol type="A"> <li value="1"> Combine C/C++ with Tcl/Tk into a single executable.</dd> </li></ol> <ol type="A"> <li value="2"> The executable should be standalone. It must not depend on files not normally found on the system. </li></ol> <ol type="A"> <li value="3"> It should be difficult for end users to alter the program (and introduce bugs). </li></ol></p> <br clear="both"><p><hr></p> <h2 align="center">Available Programming Aids</h2> <p><p>Several tools are available. The chart below shows which tools help achieve which objectives.</p> <center><table border="2"> <tr> <td></td> <td colspan="3" align="center"> <b>Features The Tool Helps To Achieve</b></td> </tr> <tr> <td align="center"><b>Tool Name</b></td> <td align="center">Mix C and Tcl</td> <td align="center">Standalone</td> <td align="center">Hide Source</td> </tr> <tr> <td>SWIG</td> <td align="center"><img src="image6"></td> <td>&nbsp;</td> <td>&nbsp;</td> </tr> <tr> <td>TclPro Wrapper</td> <td>&nbsp;</td> <td align="center"><img src="image6"></td> <td align="center"><img src="image6"></td> </tr> <tr> <td>FreeWrap</td> <td>&nbsp;</td> <td align="center"><img src="image6"></td> <td align="center"><img src="image6"></td> </tr> <tr> <td>Wrap</td> <td>&nbsp;</td> <td align="center"><img src="image6"></td> <td>&nbsp;</td> </tr> <tr> <td>mktclapp</td> <td align="center"><img src="image6"></td> <td align="center"><img src="image6"></td> <td align="center"><img src="image6"></td> </tr> </table></center></p> <br clear="both"><p><hr></p> <h2 align="center">SWIG</h2> <table><tr><td valign="top"><img src="image7"></td> <td valign="top"><p><ul><li>Creates an interface between an existing C/C++ library and a high-level programming language. Support for: <ul> <li> Tcl/Tk </li> <li> Perl </li> <li> Python </li> <li> Java </li> <li> Eiffel </li> <li> Guile </li> </ul></li></ul><ul><li>No changes required to C/C++ code. Can be used with legacy libraries.</li></ul><ul><li>Generates an extension, not a standalone binary</li></ul><ul><li>The tutorial on SWIG was yesterday afternoon.</li></ul><ul><li>http://www.swig.org/</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">Wrapper Programs</h2> <table><tr><td valign="top"><img src="image8"></td> <td valign="top"><p><ul><li>Convert a pure Tcl/Tk program into a standalone binary</li></ul><ul><li>Several wrapper programs are available: <ul> <li> TclPro Wrapper - http://www.scriptics.com/ </li> <li> FreeWrap - http://www.albany.net/~dlabelle/freewrap/freewrap.html </li> <li> Wrap - http://members1.chello.nl/~j.nijtmans/wrap.html </li> </ul></li></ul><ul><li>No C compiler required!</li></ul><ul><li>TclPro will convert Tcl script into bytecode so that it cannot be easily read by the end user. FreeWrap encrypts the scripts.</li></ul><ul><li>FreeWrap uses compression on its executable. Wrap uses compression on both the executable and on the bundled script files.</li></ul><ul><li>Usually include extensions like winico and/or BLT</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">mktclapp</h2> <table><tr><td valign="top"><img src="image9"></td> <td valign="top"><p><ul><li>Mix C/C++ with Tcl/Tk into a standalone binary</li></ul> <ul><li><tt>mktclapp</tt> generates an application initialization file that contains Tcl scripts as strings and makes all necessary calls to <tt>Tcl_Init</tt>, <tt>Tcl_CreateCommand</tt>, <tt>Tcl</tt>*<tt>InsertProc</tt>, etc.</li></ul><ul><li>Features to make it easier to write new Tcl command in C</li></ul><ul><li><tt>xmktclapp.tcl</tt> provides a GUI interface to <tt>mktclapp</tt></li></ul><ul><li>http://www.hwaci.com/sw/mktclapp/</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using Mktclapp</h2> <p><ul><li>Download <tt>mktclapp.c</tt> and <tt>xmktclapp.tcl</tt> from http://www.hwaci.com/sw/mktclapp/</li></ul><ul><li>Compile <tt>mktclapp</tt>: <blockquote><pre> cc -o mktclapp mktclapp.c </pre></blockquote></li></ul><ul><li>Create "Hello, World!" as a Tcl script in file <tt>hw.tcl</tt>: <blockquote><pre> button .b -text {Hello, World!} -command exit pack .b </pre></blockquote></li></ul><ul><li>Launch xmktclapp: <blockquote><pre> wish xmktclapp.tcl </pre></blockquote></li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using Mktclapp</h2> <table width="100%"><tr><td valign="top"><p><ul><li>Set "Command Line Input?" to "None"</li></ul><ul><li>Set "Standalone?" to "Yes"</li></ul><ul><li>Enter "<tt>hw.mta</tt>" for the Configuration File</li></ul><ul><li>Enter "<tt>hw.c</tt>" for the Output C File</li></ul></p></td> <td valign="top" align="right"><img src="image10"></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using Mktclapp</h2> <table width="100%"><tr><td valign="top"><p><ul><li>Go to the "Tcl Scripts" page</li></ul><ul><li>Press "Insert" and add <tt>hw.tcl</tt> to the list of Tcl scripts</li></ul><ul><li>Change the "Startup Script" to be <tt>hw.tcl</tt>.</li></ul><ul><li>Select File/Build and File/Exit</li></ul></p></td> <td valign="top" align="right"><img src="image11"></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">"Hello, World!" Using Mktclapp</h2> <p><ul><li>Mktclapp generates <tt>hw.c</tt>. Compile it something like this: <pre> cc hw.c -ltk -L/usr/X11R6/lib -lX11 -ltcl -lm -ldl </pre></li></ul><ul><li>Or, if using Cygwin: <pre> gcc hw.c -mwindows -ltk80 -ltcl80 -lm </pre></li></ul><ul><li>Or, if using Mingw32: <pre> gcc -mno-cygwin hw.c -mwindows -ltk82 -ltcl82 -lm </pre></li></ul><ul><li>And you're done!</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Adding C Code To Your Program</h2> <p>Put the new C code in a new source file named "<tt>add.c</tt>"</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"hw.h"</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Generated by mktclapp</td> </tr> <tr><td valign="center"> <small><tt></tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>int&nbsp;ET_COMMAND_add(ET_TCLARGS){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center"><tt>ET_TCLARGS</tt> is a macro defined in <tt>hw.h</tt></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;int&nbsp;a,&nbsp;b;<br> &nbsp;&nbsp;char&nbsp;zResult[30];<br> &nbsp;&nbsp;a&nbsp;=&nbsp;atoi(argv[1]);<br> &nbsp;&nbsp;b&nbsp;=&nbsp;atoi(argv[2]);<br> &nbsp;&nbsp;sprintf(zResult,&nbsp;"-1073742724",&nbsp;a+b);<br> &nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br> &nbsp;&nbsp;return&nbsp;TCL_OK;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Adding C Code To Your Program</h2> <table width="100%"><tr><td valign="top"><p><ul><li>Go to the "C/C++ Modules" page of xmktclapp.tcl</li></ul> <ul><li>Press "Insert" and add <tt>add.c</tt> to the list of C/C++ modules</p></li></ul></li></ul><ul><li>Select File/Build and File/Exit</li></ul></p></td> <td valign="top" align="right"><img src="image12"></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">Adding C Code To Your Program</h2> <p><ul><li>Compile as follows: <pre> cc add.c hw.c -ltk -L/usr/X11R6/lib -ltcl -lm -ldl </pre></li></ul><ul><li>Or construct a Makefile that compiles <tt>add.c</tt> into <tt>add.o</tt> and <tt>hw.c</tt> into <tt>hw.o</tt> and then links them.</li></ul><ul><li>Compile the same way for Windows except use the usual Windows libraries and options...</li></ul><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>Don't have to worry with <tt>Tcl_CreateCommand()</tt> - Mktclapp takes care of that automatically.</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">Checking Parameters In The <tt>add</tt> Command</h2> <p>Modify <tt>add.c</tt> to insure the <tt>add</tt> command is called with exactly two integer arguments</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"hw.h"<br> &nbsp;<br> int&nbsp;ET_COMMAND_add(ET_TCLARGS){<br> &nbsp;&nbsp;int&nbsp;a,&nbsp;b;<br> &nbsp;&nbsp;char&nbsp;zResult[30];</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;argc!=3&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;Tcl_AppendResult(interp,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"wrong&nbsp;#&nbsp;args:&nbsp;should&nbsp;be:&nbsp;\"",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[0],&nbsp;"&nbsp;VALUE&nbsp;VALUE\"",&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Report an error if there are not exactly 2 arguments</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;a)!=TCL_OK&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Report an error if the first argument is not an integer</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[2],&nbsp;&amp;b)!=TCL_OK&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Do the same for the second argument</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;sprintf(zResult,&nbsp;"-1073742724",&nbsp;a+b);<br> &nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br> &nbsp;&nbsp;return&nbsp;TCL_OK;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Using The Tcl_Obj Interface</h2> <p>In the file <tt>objadd.c</tt> put this code:</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"hw.h"</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt><br> int&nbsp;ET_OBJCOMMAND_add2(ET_OBJARGS){<br> &nbsp;&nbsp;int&nbsp;a,&nbsp;b;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Use "<tt>ET_OBJCOMMAND</tt>" instead of "<tt>ET_COMMAND</tt>" and "<tt>ET_OBJARGS</tt>" instead of "<tt>ET_TCLARGS</tt>"</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;objc!=3&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;Tcl_WrongNumArgs(interp,&nbsp;1,&nbsp;objv,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"number&nbsp;number");<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">A special routine for "wrong # args" error</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetIntFromObj(interp,&nbsp;objv[1],&nbsp;&amp;a)&nbsp;){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Instead of <tt>Tcl_GetInt</tt></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;if(&nbsp;Tcl_GetIntFromObj(interp,&nbsp;objv[2],&nbsp;&amp;b)&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_SetIntObj(Tcl_GetObjResult(interp),&nbsp;a+b);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Result stored as integer, not a string</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Speed Of Tcl_Obj Versus "char*" Interfaces</h2> <p><ul><li>Compile both <tt>add</tt> and <tt>add2</tt> into the same executable.</li></ul><ul><li>Compare their speeds: <pre> time {add 123456 654321} 10000 <font color="blue">26 microseconds per iteration</font> time {add2 123456 654321} 10000 <font color="blue">4 microseconds per iteration</font> </pre></li></ul><ul><li>The Tcl_Obj version is 650 faster!</li></ul><ul><li>Replace the addition with a "real" computation that takes 10 milliseconds.</li></ul><ul><li>Now the Tcl_Obj version is only 0.2 faster!</li></ul><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>In many real-world problems, the Tcl_Obj interface has no noticeable speed advantage over the string interface.</b></td></tr></table></p> <br clear="both"><p><hr></p> <h2 align="center">More About Built-in Tcl Scripts</h2> <table><tr><td valign="top"><img src="image11"></td> <td valign="top"><p><ul><li>Comments and leading white-space are removed from the script by default. Use the "Don't Strip Comments" button to change this.</li></ul><ul><li>The file name must exactly match the name that is used by the <tt>source</tt> command.</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">Locations Of Libraries</h2> <table><tr><td valign="top"><img src="image13"></td> <td valign="top"><p><ul><li>Tells mktclapp where to look for script libraries.</li></ul><ul><li>All Tcl scripts in the indicated directories are compiled into the <tt>appinit.c</tt> file.</li></ul><ul><li>Comments and extra white-space are removed. There is no way to turn this off.</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">Built-in Binary Data Files</h2> <table><tr><td valign="top"><img src="image14"></td> <td valign="top"><p><ul><li>Arbitrary files become part of the virtual filesystem</li></ul><ul><li>No comment or white-space removal is attempted</li></ul><ul><li>Useful for images or other binary data</li></ul></p></td></tr></table> <br clear="both"><p><hr></p> <h2 align="center">New Commands In Namespaces</h2> <p>Two underscores (__) are replaced by two colons (::) in command names, thus giving the ability to define new commands in a namespace</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;hw.h></tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt><br> int&nbsp;ET_COMMAND_adder__add(ET_TCLARGS){<br> &nbsp;&nbsp;int&nbsp;a,&nbsp;b;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Creates the Tcl command called "<tt>adder::add</tt>"</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;char&nbsp;*zResult[30];<br> &nbsp;&nbsp;if(&nbsp;argc!=3&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;Tcl_AppendResult(interp,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"wrong&nbsp;#&nbsp;args:&nbsp;should&nbsp;be:&nbsp;\"",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[0],&nbsp;"&nbsp;VALUE&nbsp;VALUE\"",&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;a)!=TCL_OK&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;b)!=TCL_OK&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;sprintf(zResult,&nbsp;"-1073742724",&nbsp;a+b);<br> &nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br> &nbsp;&nbsp;return&nbsp;TCL_OK;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Adding Your Own <tt>main()</tt></h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;/*&nbsp;Application&nbsp;specific&nbsp;initialization&nbsp;*/</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Never returns!</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><table><tr><td valign="top"><img src="image3"></td> <td valign="top"><b>The "Autofork" feature is disabled if you supply your own <tt>main()</tt></b></td></tr></table> </p> <br clear="both"><p><hr></p> <h2 align="center">Initializing The Tcl Interpreter</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> int&nbsp;counter&nbsp;=&nbsp;0;<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br> &nbsp;&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);<br> &nbsp;&nbsp;&nbsp;/*NOTREACHED*/<br> &nbsp;&nbsp;&nbsp;return&nbsp;0;<br> }<br> &nbsp;<br> int&nbsp;Et_AppInit(Tcl_Interp&nbsp;*interp){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;if(&nbsp;Blt_Init(Interp)&nbsp;){<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Example: Initialize an extension</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Tcl_LinkVar(interp,&nbsp;"counter",&nbsp;&amp;counter,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TCL_LINK_INT);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Or link a C variable to a Tcl variable</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Return TCL_OK if successful</td> </tr> <tr><td valign="center"> <small><tt>}</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Writing Your Own Event Loop</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> </tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>void&nbsp;Et_CustomMainLoop(Tcl_Interp&nbsp;*interp){</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Replaces the default event loop</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;return;</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Ex: Return without handling any events.</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">This now returns after initializing Tcl</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*&nbsp;Application&nbsp;code&nbsp;here&nbsp;*/<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Writing Your Own Event Loop</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;&lt;tcl.h><br> &nbsp;<br> void&nbsp;Et_CustomMainLoop(Tcl_Interp&nbsp;*interp){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;for(;;){<br> &nbsp;&nbsp;&nbsp;&nbsp;Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT);<br> &nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Other&nbsp;processing...&nbsp;*/<br> &nbsp;&nbsp;}</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Intermix processing and event handling</td> </tr> <tr><td valign="center"> <small><tt>}<br> &nbsp;<br> int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){</tt></small></td> <td></td><td></td><td></td><td></td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Never returns</td> </tr> <tr><td valign="center"> <small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br> &nbsp;&nbsp;return&nbsp;0;<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Mktclapp Initialization Sequence</h2> <p><ul><li>Initialization starts when the <tt>Et_Init()</tt> function is called either by client code or by the <tt>main()</tt> that mktclapp generates</li></ul><ul><li>Create the main Tcl interpreter</li></ul><ul><li>Construct the virtual filesystem overlay by redefining the <tt>source</tt> command and by using the <tt>Tcl</tt>*<tt>InsertProc()</tt> functions</li></ul><ul><li>Call <tt>Et_PreInit()</tt> if the client defines it</li></ul><ul><li>Call <tt>Tcl_Init()</tt> and <tt>Tk_Init()</tt></li></ul><ul><li>Call <tt>Tcl_CreateCommand()</tt> and <tt>Tcl_CreateObjCommand()</tt> for every <tt>ET_COMMAND_</tt>* and <tt>ET_OBJCOMMAND_</tt>* function in the client code</li></ul><ul><li>Call <tt>Et_AppInit()</tt> if the client defines it</li></ul><ul><li>Run the main Tcl script if there is one</li></ul><ul><li>Call <tt>Et_CustomMainLoop()</tt> if defined by client code or else run the built-in event loop</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Invoking Tcl From C</h2> <p><ul><li>Use one of the built-in evaluation functions: <center><table width="80%"> <tr><td valign="top" width="50%"><ul> <li> Tcl_Eval() </li> <li> Tcl_VarEval() </li> <li> Tcl_EvalFile() </li> <li> Tcl_GlobalEval() </li> </ul></td> <td valign="top" width="50%"><ul> <li> Tcl_EvalObj() </li> <li> Tcl_GlobalEvalObj() </li> </ul></td></tr> </table></center></li></ul><ul><li>Mktclapp provides evaluation functions with variable argument lists as in <tt>printf()</tt>: <ul> <li> Et_EvalF() </li> <li> Et_GlobalEvalF() </li> </ul></li></ul><ul><li>Mktclapp provides a global variable <tt>Et_Interp</tt> which is a pointer to the main interpreter</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Invoking Tcl From C</h2> <p>Example: A C function that pops up an error message dialog box</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"appinit.h"<br> &nbsp;<br> void&nbsp;ErrMsg(char&nbsp;*zMsg){<br> &nbsp;&nbsp;Tcl_SetVar(Et_Interp,&nbsp;"zMsg",&nbsp;zMsg,&nbsp;TCL_GLOBAL_ONLY);<br> &nbsp;&nbsp;Tcl_GlobalEval(Et_Interp,&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;$zMsg&nbsp;-type&nbsp;ok");<br> &nbsp;&nbsp;Tcl_UnsetVar(Et_Interp,&nbsp;"zMsg",&nbsp;TCL_GLOBAL_ONLY);<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Invoking Tcl From C</h2> <p>The same C function implemented using <tt>Et_EvalF()</tt> instead of <tt>Tcl_GlobalEval()</tt></p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"appinit.h"<br> &nbsp;<br> void&nbsp;ErrMsg(char&nbsp;*zMsg){<br> &nbsp;&nbsp;Et_EvalF(Et_Interp,&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;{¸üÿ¿PX¶}&nbsp;-type&nbsp;ok",<br> &nbsp;&nbsp;&nbsp;&nbsp;zMsg);<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p> <ul><li> Suppose the function is called as follows: <blockquote> <tt>ErrMsg("Syntax error near \"}\"");</tt> </blockquote> </li></ul> <ul><li> The command that gets executed is: <pre> tk_messageBox -icon error -msg \ {Syntax error near "}"} -type ok </pre> </li></ul> <ul><li> But this is an ill-formed Tcl command! </li></ul> </p> <br clear="both"><p><hr></p> <h2 align="center">Invoking Tcl From C</h2> <p>Use the "<tt></tt>" format to generate a quoted string</p><p> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#include&nbsp;"appinit.h"<br> &nbsp;<br> void&nbsp;ErrMsg(char&nbsp;*zMsg){<br> &nbsp;&nbsp;Et_EvalF(Et_Interp,&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;\"%\"&nbsp;-type&nbsp;ok",<br> &nbsp;&nbsp;&nbsp;&nbsp;zMsg);<br> }</tt></small></td> <td></td><td></td><td></td><td></td> </tr> </table> <p><ul><li>The <tt></tt> puts a backslash before all characters that are special to Tcl</li></ul><ul><li>The Tcl command becomes: <pre> tk_messageBox -icon error -msg \ "Syntax error near \"\}\"" -type ok </pre></li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Other Functions Provided By Mktclapp</h2> <p><ul><li><tt>void Et_ResultF(Tcl_Interp*, ...);</tt></li></ul><ul><li><tt>char *Et_DStringAppendF(Tcl_DString*, ...);</tt></li></ul><ul><li><tt>int Et_AppendObjF(Tcl_Obj*, ...);</tt></li></ul><ul><li><tt>char *mprintf(const char *format, ...);<br> char *vmprintf(const char *format, va_list);</tt></li></ul><ul><li><tt>void Et_NewBuiltinFile(char *filename, char *data, int amt);</tt></li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Operating Mktclapp From The Command Line</h2> <p><ul><li>Generate the <tt>appinit.h</tt> header file like this: <blockquote> <tt>mktclapp -header &gt;appinit.h</tt> </blockquote></li></ul><ul><li>Generate the <tt>appinit.c</tt> file like this: <blockquote> <tt>mktclapp -f appinit.mta >appinit.c</tt> </blockquote></li></ul><ul><li>The <tt>*.mta</tt> file is just a list of command-line options</li></ul><ul><li>Enter <blockquote> <tt>mktclapp -help</tt> </blockquote> to get a list of available options</li></ul><ul><li>Look at MTA files generated by xmktclapp.tcl for examples</li></ul></p> <br clear="both"><p><hr></p> <h2 align="center">Format Of An MTA File</h2> <table cellspacing="0" cellpadding="0" border="0"> <tr><td valign="center"> <small><tt>#&nbsp;Configuration&nbsp;file&nbsp;generated&nbsp;by&nbsp;xmktclapp<br> #&nbsp;Hand&nbsp;editing&nbsp;is&nbsp;not&nbsp;recommended<br> #</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Comments begin with one #</td> </tr> <tr><td valign="center"> <small><tt>##&nbsp;Autofork&nbsp;No<br> ##&nbsp;CFile:add.c&nbsp;1<br> ##&nbsp;CFile:objadd.c&nbsp;1<br> ##&nbsp;CmdLine&nbsp;Console<br> ##&nbsp;ConfigFile&nbsp;hw.mta<br> ##&nbsp;Data:check.gif&nbsp;1<br> ##&nbsp;MainScript&nbsp;hw.tcl<br> ##&nbsp;Mode&nbsp;Tcl/Tk<br> ##&nbsp;NoSource&nbsp;No<br> ##&nbsp;OutputFile&nbsp;hw.c<br> ##&nbsp;Shroud&nbsp;No<br> ##&nbsp;Standalone&nbsp;Yes<br> ##&nbsp;TclFile:hw.tcl&nbsp;1<br> ##&nbsp;TclLib&nbsp;/usr/lib/tcl8.0<br> ##&nbsp;TkLib&nbsp;/usr/lib/tk8.0</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">Lines beginning with two #s are used by xmktclapp.tcl and ignored by mktclapp</td> </tr> <tr><td valign="center"> <small><tt>-console<br> -main-script&nbsp;"hw.tcl"<br> -tcl-library&nbsp;"/usr/lib/tcl8.0"<br> -tk-library&nbsp;"/usr/lib/tk8.0"<br> "add.c"<br> "objadd.c"<br> -i&nbsp;"check.gif"<br> -strip-tcl&nbsp;"hw.tcl"</tt></small></td> <td>&nbsp;&nbsp;</td> <td valign="center"><img src="image2"></td> <td>&nbsp;&nbsp;</td> <td valign="center">All other lines are read by mktclapp and ignored by xmktclapp.tcl</td> </tr> </table> <br clear="both"><p><hr></p> <h2 align="center">Summary</h2> <p><ul><li>Use Tcl for the things Tcl is good at and use C/C++ for the things that C/C++ is good at</li></ul><ul><li>Use wrapper programs to make pure Tcl programs standalone</li></ul><ul><li>Use mktclapp to combine Tcl/Tk with C/C++ into a standalone</li></ul></p> <br clear="both"><p><hr></p> �������������������������./saods9/htmlwidget/tests/page3/image10�������������������������������������������������������������0000644�0001750�0001750�00000011740�07504443352�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aä�÷�õ�����0@0666>>>>R>H`HLdLVrVZvZ`€`d„dfvfhˆhllln’nr–r||||¤|€€€€ˆ€‚š‚†²†À”œ”–––˜˜˜œ¬œžžž¢¢¢¬¬¬°°°²²²¶¾¶¸¸¸ººº¼¼¼ÂÂÂÈÈÈÊÊÊÐÐÐÒÒÒØØØÚÚÚàààèèèðððøøø���������������������������������������������������,����ä�÷��þ@‹pH´$ŠÈ¤rÉl:ŸÐ¨tJ­Z‰ÇeÁÂèz¿‰¯xL.›Ïè´zÍn»ßðxØà" ø<¾ ïûÿ€‚ƒ„…†‡ˆ‰Š‹Œ| u –— ˜›œžŸ ¡¢£¤¥¦§¨©¡•œšœ‘\²csq¹º¹]½_jÀ^»ÇÈbµ˜ ¸_µ³“¶bÐÉØq½ÛÝÝ à 'åÂá½Æ ãéçÙò¹µÕ“ÏdÒ’Ò˜øó�ÙˆAA ïÀëu‚††'šK·°`À‹jêEûÇ ‚?jÓ¤ÐãÉ1ï žCHN¡±†ã®TØÅet'sF³´×þÈ.úhÙórM'F—*#v#‚eAq#6çm©SœFsjôb $WYû†v)šµìœͪA^Ù†tð'£»xóš€gÁ½€"@×]?À&HPà‚ãÇ#KžL¹²å˘3kÞ̹³çÏ 1/Þ2ɋӨS«^ͺµë×°cËžM»¶íÛ¸s¿Þ�––‹Àƒ N¼¸ñãÈ“+_μ¹óçУKG.¡wé騳kßν»wíÕCþþN¾¼ùóèɇß7^8‡ðß;çÀ!Eá÷ÓëßÏ_ÿzßÄÁ—}�Ø—_r˜ }öçàƒ6÷ßuÃ5 �| �€aƒÆþY˜á†^Èa„$–á„´œ€ð…Ø@}Þç"bhâ8ò‡¢ŠÀ±˜!�#r I£…Bæ¨ä’ßí¸Ÿ€LF)åtNêGß”Xf¹\•Zvéåƒ\~)æ˜åíØÁ™h¦©æšl¶éæ›pÆ)çœtÖiçxæù&Š&èé矀*è „jd&ªhw‡.êè£Ð5 餔'i¥˜Vz)p+¸àé§ †*ꨠ~0d¦¨z·i§+”Gc -*묡š +­¸æª«­±êꫬ¼þ*ì§¶Z’p§@ -˜G#³J>Û,ÒZY ±û Ë‚²<~@·&~û ¸û][ܦþÉšG®ºà–¸.ï¢g.qènË®¼í’¯~ûª{\½¾è^}÷x\¿Ý!¬o¾÷–ûï±Á¥Û£Œ¦`$�ï18 |Po~/žJÜ•Èí+à•—ÉÁ±Ì²qï¾ߊ-§LsË"{ÌãÌø©ŒáËÅÍ;Àø ¹a‚)¸øcˆ/Ç{í†ö1XpÆW,\¼B2$}9{\ß…UCý³À6ïû4ÅÀ)øbÈ2k¤Õ:W`Ö!c\uÚ¯M0‡B G4p\ψt-&= ÆWóx­Ò�€Ýb&maÓŠ{løÄx{,¤†Öxaç…3}ªÙØò…†·ø¡ˆf¸ÜR¬àþå’¹èW?œmÄö~¡Fnýù†Ÿ™dܹKŽaÆG®ú}4Ž^y—ÿž†{x;ˆÊ×x¸ôÄ©¹}G^1á6Fÿzîð}n¸û™×è½ú–cK‹¶Ø¡¾âª_<àïjûõÖw:Èý/k0jÚ<¼ß}ˆD^î¬g.:PFH¢Ï6þ  |Àƒ`üÚ79#%ï\ŽÄ¢s·ýá‹I ƒŽÍ‚Æ0ïô-8#O µ³ÃqÕp>]“Û¹sCàäÐ[CœN´D&‘‡º»ïÎ'F§‰ð²âv°˜"¦àˆÞéÕ°ÆHÆ2šñŒhL£§8ÆT¹1G¨Ãa þS°Â7ÚñF)kã÷è <αŽ| $ü¸;öNˆÔ!¥hÈD6G7TM«Ô¨‚ò,røsärLIH¢ )Тq$`ÉéQ“Ã¥wÎÊí’<—DÔQ™Uv‡•¶Î+¿ËLæÈ`fÁˆ8‘­•²Q1c§ÌéàrdëÙqvé^ÎG?ã˜Ô ½ºqljCBœãö¦·à´ëdk»Ï‘LÞI8Ï Xêd¤1âP³;ÖldŽ@'"ŒÉ/>òéœòZôª´mn{(pÎI±£ƒÆá$j> OPv+¡ Òž=Ké·?²D@BÒòº%÷n¤æbÜ@þhΡM™ ‚hq\ & €2ñÄÁ†¾ÂÒ”ýeÁwÐ~ZÏ‚?ò_JcgA~p¡.aáÎg± §Oj"AE‘©Ó¤Q0ƒ>å%P IÇb3?^LO.·“SåÌ8÷äN>Ë%’µS­&jkrŽ WŽÊ‘¬€¤e*ójQWúÕˆAìqhZ¨:Ù”«Ø‰ëvæXÅ^µ±vÒª $ÀÙÎzö³ ýìa¿˜XËš6:”5ëiW£ŽVµ¬m2]ËHºÊö¶Qýkm+kÙNvr’i¬äOi‹ÉkÆV¢¾½ E×Éj'µ¸envô*çfº·•.v¨ëæo¬»…­vÚ6þœ—½Ì`ͬÐtº9¤!BϪҡ.ʤ9ÊÑžòº ›ØÐèµPmakhԨƢ¿W æ"áZ¸Ö´ §…•§øìf0﮼ÅÕ',Y÷¸ =Õ@þ4œB%g4åÈh …\è´⪶T9„ñ&UCQC¶GÃ[žFuißÒŠ•™ zÛÄ,bË‘Ð{ICqḇ>…6HÁ’“±r‹¦ÇÚø¢;}QOy<\Ýfضå`éž:©~˜iNÝÝwÔy|7†™~符I«Wž-Æ.V.ÿØË²Ô0¥¤–í:3ÂËyk ,,ìbJÑÎ1t|­¾.ºÇ¯.aãÜ]þL‡7º˜¥ÓcµËhÔb8Ð`Ž­C'͆öհ欧¿Ì[ÜÆÖѶÎ5®sÛ]óZ¶¾>mr! \4 ÷ψÍtv‡›å¶ËÉþtv7MêY£ºÖ‚•tt¸ RËðÔ¾D¤›s 9Wja¾ækùFófõ…6i•¢“jc¯ÆL—¹±×kÚäš?8â|Ý®b!ƒr¼U,ÏÓ«ò k5Ám\YÄGK‹ z9•¦tãè+i{£ãåÙnÜ ¥ñM©‹Q‹Hâø¤¸ -Î䕹æ#,yöPšqê½ØgnÞئ\Ó•Ss3Ú²p¼ýœ`§yJµ9Y?’þ¶ÎB;ï_ó¶F;N#]Ì{–iqV}&<³œž|6¡Ÿ'NÜk‹7Uil‰¸í³x#{ÞÒä]åN"ºCÓîlt¸Y«mèø]BÖüj©Ìê7úÙw¿¯`ÉÞø6¹:Ö˜÷lâ+þë[Ë<Õ÷|ÛúÓ:½ôŠ=½b™›bŸñØ6­ßžmÖÛÆÙàÙüÌOmÈÇï³×ôÜ^]݃^K2ÛØq\ß ªnUþ*‰ÏnŸ>æ£ç|–¸NpÆ.ßzÛ·À ¾œ?Ÿ9 ϳ„ÏWϵc_ðÚÇRHK'3’ƒB/³‹¡Ÿœw}Ê*×p’cý3CLçª%êô3sþR7‡PÏc}^;œóµTt(arr#r€äöyØÆ$R�äU³A D<X×uPFB¶”gvÄW$E%vÈ HK…÷‡×UÅqƒ‰‚´§ƒ½Ç–„n%„Â×wÄ×iò&y:Xypòx¹÷„>ÆZ”'…Y•›•y^h|!ˆzŽ”ƒb˜HdX†‚t†hÈGj˜H¶w®gF°÷~²çvÑõ†´{Ù„­»wZ;è=¸%`8„¨ˆÍ1ˆÊÁ‡D¢„}Ä6ËaWÍÄ2<30ô8çç^ÒwKÔ÷nsr刃„àT`ÜTnì%ì45áç_ãG; 66Í7éwvþGa?Xˆ29,¦bGTÕL¼X7 ø*q‹úÇÈÅ5Ær¸:¨‹ý8ÜÃdPƒt˜³1¶ƒ7ev-BödåeˆŒ×Vf‹I—KGÔrA…Ófa‡ŠRµ2Mõ*ýcfpÖ‚ Tgk"ƒqFƒG¢víh…ôÆGq'ˆÈЍpyWxG{§E‰AĈ$'ŠÇU‘‘åŽÇ¥…nB…{è‘X’nry^ˆy$¹†´Ô†,ùF.ù’©rzt62C—„–f"Âq2™NWRS×<-×aF¢biÆ_ A=©‹$pgVã€G•ˆ£=<S¬"¨Ó”&¹•\)(Z]þ°#0–&ð?ö• b;î“q&•>R#Wbc9—tY—vy—x™—z¹—|Ù—~ù—€É—Û–#Чñ`&pŠi:þÖ#‡o$“nßÄ)xX™–y™°#0˜JØ›5¹”]♜™}Dš¢¹G¨I˜†˜šŽ²šù™Â´Y›¶y›¸™›º¹›¼Ù›¾ù›ÀœÂ9œÄYœ´9°išt…šÂ‘%ðœÐÒ9ÔYÖyؙڹÜÙÞùàù`Á‘œ~¸œ² F깞ìÙžîIFÈù™¬9PE´"ú¹Ÿü9*ñYšå™,̉ž êøéþ)j €ŸÚŸ¡:Fÿ©p�3 ÀQŸ"�jŸ.À¡UdŸ0�Z¢&z¢ŸR¡óÙœ! ¢ú¡ú¡ú¡(Z£6ºŸ*›•øÙ£øÙ =Š ê¡7Z¤FzF9ªœzžz¤Nú¤8*äY‡øƒ¡)àPš¥ZªFI Ûb¥®™)S |v¦aZ)cz¡Lz¦˜’¦Ae¦bÂz+°¬WV˜¹-ÃÖ¥T:Epú%ÍèIÀ†™\JwZ¨Š…*¥ò©£"ig†ÌAJ ÙŽÕÆ¨�º§§¹¦d©Úš„X©Í5ÎqOnši}ê%ž*©¡º”ê{8Õ¨Jþú¥œ:&àš ù©Ä!@Ïñªå…«è†8ÓúSޣЩú¦µ*&§uiG‘jVûuA&hƒq¶5/â?.Ô@9ã«]vi­Èº¢‹Ò¬BgRЪ«#Cah@<Ö.oC• óq{Va9< ÈŽÇ:ž²ê¥± ªRÒ-@RUöW7­áb©`ßJ¬+%9©ƒ9%Ô —9åꨎ.Uc7G>ÈÉ®îqoõ”.3³6‚‰0"™o®8C>>³zJ¦Uº¬~Ú‰H²¹'ª}õDŠfªÿª©æ)°Q²ªHK¤Ú2K%7«¦K»$Jë´MËO[|;«þû¨ƒbSÎ8(”ª…c (D›©8˧:ë%Y¨'$°…’mÛXr+(Q«¬S˦ZrªŸ–ªz«(||~û·d¸eº¶„[¸E›¶›š·‰%†›³Žû¸K¹j»)™¹š»¹œÛ¹žû¹ ºœ»¸ª[zº¨ëžh …”»(1Ùº^òº°«%²;»Xrz &²·"¨P¶kNW°%¦e9pÜÊ5ýç÷»“¥‘]õ^r"4b;RƼßŵàY ô–E†–Ó ;VW¢[¾æ{¾è›¾eI˜Ÿb/tæ>úºuÇA‹³­¡”ºøÛŸ*°ºxÛ ‰½úa¹Kn�|þ#|´,&¼¤“›Àý±À´º£0Á\Á|ÁœÁ¼ÁÜÁüÁ Â"<Â$ìw‹ªkšžù»Â,Ì#͙ܵ -<Ã[zÂ}›ÂDJÃ:|¤6,¸8좺¡9¼ÃD¥þÊ¿(¼£-£ž2ÄEüÄïÙÇ«Ä2£@ÊÄPœÅí)Å’KŸ£"ÃZÆìÉÅj»£b|ÆüIÆ,'p§nüÆp|§jŒÀ<š¤Û¿u¼·wœÄy¬ÇH|à œ,ÀŸ&0ÈOZÈêYI”4Ç l"¬ºm>‹# kX—zÄÉÊÇ%òȆÉÌÉÅWÉð´Ç€ìÈŒ“¬$§<’ Üµæ!€þ”^‡XïEr–X^•H³Æ‘Êy30+ó°뉺›‹[ °ƒ‹€´@„6LÜä|9£ËÌtoìÇ5óJãM ;²Ç;¶@)«gÑŒ¯Ãl´œÉfÅ4DÕ:Ñ3‚×ëÌüDPQ™qné@ßË“uÌ“sRžc±Js/\Ìç‘ÍKöÎÐs°ëZG$È:ÃaÒ»Û¨®ëÌÉjƒÏü´z¶Jׯ¡üÇ>\ÊÓaÏj6@Õf/XÏÅ"DE‚$¿}”!Ñ RòÓ<Ý,a_EÍÊK"šÌƒž<|=]_B Lg{É£LÎèá̄ԹøDGÈÈLÊIýÓLÈÔ5=’þá̸tÌÓËT!JÝi«üψ›,€¹éûYŠÖiý¹k}¾\h¾P Ã}<%dÝÕuýw×v-ÊÍ×R²×€Í$‚=بìׇûI]¹ØŒÝØ_‹Ø9˜’=Ù”]Ù–}٘ٹ¿F|$Ç Ú¢™­BH£Az†Í$)3y—ÚSR»®­HŸ'uð\Û¶}Û¸Ûº½Û¼ÝÛ¾ýÛÀܼ ŒZí|Â}ÜÈÜʽÜÌÝÜ»=4sÛd²)Ò=&Ô]Ý_rÝØÝ%Ö�žð ªÞâ=Þä]Þæ}Þ¤�Þ›� ’`d±ðßòÍïÝP�ßú½ßø½ßþýß�à>à^à~àžà ¾à Îàý-àA��;��������������������������������./saods9/htmlwidget/tests/page3/image4��������������������������������������������������������������0000644�0001750�0001750�00000005760�07504443352�016523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a‡¿�ò�����???¿¿¿ÿÿÿ���������!ù���,����‡¿��ÿHºÜþ0ÊI«½8ëÍ»ÿ`(Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßðq�@¯Ûïø¼~Ïïûÿ€}wq‡0�ˆ&‹Œ)#”˜"†™ › �“¡Ž¥¨Ÿ©–¬¯ а«³¯®¶§¹¥²¼¸¿ ’µÅtœÈ»Ì‡Št—ÏÁÔp„t¤×ÇÜmuÛßÎãjÚæÖég„âì ÞðdËó å÷aöú ëý^Þ$ o Á0ù*äòo¡C,r0- ÅwæJ(Qÿ! *F t)[†l�2°n3•M„læh¦±e0ØT°³XĘLò°)åÐ:"-y‰¥²IÒÒ!àRAƔʌ:M)’Ø3Ž@-ìrG�WÏ‹ͬ§€íLµ—òú´ˆ­"‘`må ;aì4›g!À}2¤£QˆÈ%—ªN¼×~òíï¯åfŠßZ*¬ØÒœ¶3:~K•”µ¼¶POn`x&KI¯'Ýý á®Ô’KiÂu×0Ź’–㵬Æ_{WWæLQ@ƤšKN0:g«²Å]‡~Ñ5tç#óSþ¥êWòcDSK޾=ÉîãßP-?ÄG$U%%G”5}üÿ¬¶_,ÇuÁ^}PÔÍ€Øq§_, Rà I¾!ð!ø�g×5· u 4XˆõÔ³Maê1¶ÒYòÄ”NKUtÊ*×ðt]8Å…ÛùÙxŸsèÈÖ\^ˆCÞ–!žqB¡Œ ¨¥UõàHЕ[Øc[²qR•/ŠUiÚ…›I‰SEí2æa¤œRŽ›V¶äŠMJ’’Hdø%‰Æ•‰d•„º¨'O†n¸Ÿ›w꘣ƒšågM VQ‚dª©4›v*Èx�yæ'GBjW(bÝ‘¶Å‰‚Æêx±ºâ™ŸÀzë„ï`U^Šâª$>¥˜Xf¥£ÿHIÕ,UÈÚ8GTu@»kJPÙAjV§L;Í´Ó†h^€¨ö * #þ)FqUð¸™ê–Q ÁnÀn¼=úéKøÆëîÿâ)ÖII½-Ë J¿>ð›„Ñ.ØÂYy*š†¾¦ DZº­Rö  ›ì©peç°€°07.˜i”³¿nå§sa…ít&Â8ãp/3<Ìq¥ ”Æ>q2ü´Ë‘´A*ÁX.™•ÓËh5 Y¥:œs¡CM"uT#iˆhXŸk. ãêÃ2¢?M²Šp#) œ¶ÏUø¼ XR19!•P|ÒÈ׸y}~%zW5NøjÀ‰Ã½øf;9n•àÿ=æ¹üFë”ýµv¡èÒ–ól5嶈çŸsUnP–žÑé<ûX”K‘e™-qšÛ"â‡(ºX£¢Ìq§åÀ"ÖY<cZb `SÊÓÊ|‡êþ<OfÁ¹I£'¢€.pœÃˆÝ¼÷N6þñ) „üTüÎùý¢÷½Xù¹~ø£FÅP0y•Á~ïÚ+`¥'ÂiÁVP Ú÷ ]ä"XÚ̼ZT§çœÈ96ñ_À,ü$écÆÃ2h —܈V‚©´\×™l�i*? 0µÅCJ—`ÈtbUøâMó{B&6Âè-ˆÓÉ ›DR9§%Q‚K8áÿà•ŽÈfl²I0zB,Ú” †0¼A4R6‚€‚Ôh” mØ–†°JjÔQh³•›Ù(m6°ˆ³þ¡¥ó’éÑD (ÍÉšÃ2'I0ð0a†dR ðÈ$tR0™”‚³ØÈ Œ²iA Ò„KFÁ•Hs#2XRJ )Å Ÿ<B.•’HÖ?išb¸x„Së—°J\)œ(FõxYm¶æ#q¡ãXÙ“²ªU-Àò ß¼À.ß@,Û`í/ ÑÕpÆ.QaçU›×Ɔ*º¹`œÞs1±²%SlÞ¸W–ŸMkmŽÚ[ÜL†Ì&ìSk BiÿPT¡¥Ig™ðÉYZ!œìëå,7‡ØÄ&dPºÚ¤B :êåÎelR"ÚÌÀÑDE&yÎiŠÀ3½ˆzÛ_<dðP#õ–¡ôÀQƒâÑ*€TˆIuä3qPÓ T•˜QEÂR‡°Uˆ4«9ljýÄz?²®!"]]bª«P´o“˜H+ä ×7¦®xªï̪¬b¢xMM_�GÁ®·h(ä>P”C®aЫ$ë±P�V±n`+'IˆÙÈî'°€¬ «Y*¼µ³l ìÙô‰Ú. µµ%[ë  ÖbÂÖ¨·%ÇWk»ÕÁ·ã-JÛÍW¸JÍ­ú” 6æÿ"wÀ-Bt È×çÆà¸;Ðla­»Ñfι¬ânXX]GŠwØÕfA‹ˆŠ)Q‡nð. ëWT0P'ï+Ëë„é:`»çÏ`IÈß�£@¾ÝÕ¯ |¾3Á¿ucpqì‚ú®%»EŽ‚G»a�Ç–Bˆňô~x ¥5±.ï`ˆ–½`¨ä7F<^¨¸ˆýƃ¯˜Åþn"œ…·ƒÈ“E²@aä34y¥…ñ0ÜãÀ»O–0}°å‚J˜Y¾n hûeXùÞõp™'¦äÕrvÍ9³ ç+y¾A–r=Ñæßö9Š{æ±l{œá@“àÿÌfÎóŸ ­ŠE¡Ëmeô ä<ièYÒ@t ¼kaLËÄÑC€´š=mQ ÏÔ¤öÇLçT{Õ"†u„]­JßÊ´^¦i ß]kYÖ5r®kmêIzØð5Qï|idoØ\†¶ÝœÍÒb³–Ú%PvïLfl{�Ò½•6˜¼=[·à¸Í&·—‰kuó™¼3H7¹Í=StÚÝÐ6 <j|wãØSHeù�îï‚w``m¸ëŠæA. \zlê�ÃdÊ$ÔÈl%¼¸¥-#8W8ñKKC‡CcàQG´-´5¯! + éV#SVY´Dã Cb«§íq´Ù ÿ¡8’jâÀZ$¯ì a^z¢óš Žæç9‡ %âUѨŠÏ’u³c¨ÌX6#Ѧ嵩’Äê{ÜEc…r´o}†~¤ÙoÀ5/CÐJ×ÌzœV66ºóÄk}™‰kü“˜ç*|‡»JˆÖu;ü%%h·X:ú¶-U+dwVÓÕ¥m‹kÁõÏ:ËéBÙÌhj¤²û~ÂVºX~.%Ñè9ÿXöÊwlö -KêÅf£«E­{²‰'<{?üÖ¢.»·‘U(Ý»JEÍ— EŽï|Ûtã÷6U'+Cšg'w=¾‡¢9aÝô’Ÿõ– ãŠ>†·oÍÏ[¤¢}Q^r/‚Tÿ›ž˜}ªÌ­mU´9‘â~eBð§ ÐÿW‰iاgK‚rWË~"#2wB£Ñ8¶g^Hr8[4Ù7%àqQïG9M!‚:G)CQŠSÓm¥P¹Ç88uÅÇ?‚b‚è6A‡¡äCžáÁ ôW0aDD‡X’@‚$.T×ìw92>$¡;1:±£ibw+UCùÑR—s;NbFaè$$7}³q|{b)¦3‡PÑBå²v±cR´ƒ†ò¬Ã…-„£Cr X¸á†Â±'Kw æDˆ|h¼Ñ…¿ˆ­AÛP.»ƒuµ³%›µ†DØB’%¦µ†¯á› v…7<šô9CÔS9b dt<$$°èAäóÓSÕ£=ã8õÖ“‹!”=Æ“FðÁ!Þq‹Œá‹@µ,‡¶Ù±.B¼Øp^·=¼˜#=Q ï³ÙC-"À878[Ó#oR°eèÓ[wü eâ¦Ü«j$ÔM@?àdpy™ ¹ Ùù‘9‘Y‘y‘™‘É] ��;����������������./saods9/htmlwidget/tests/page3/image14�������������������������������������������������������������0000644�0001750�0001750�00000007023�07504443352�016576� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aä�÷�õ�����0@0666>>>>R>H`HLdLVrVZvZ`€`d„dfvfhˆhllln’nr–r||||¤|€€€€ˆ€‚š‚†²†À”œ”–––˜˜˜œ¬œžžž   ¢¢¢¬¬¬®®®°°°²²²´´´¶¾¶¸¸¸ººº¼¼¼¾¾¾ÀÀÀÈÈÈÊÊÊÌÌÌÎÎÎÐÐÐÒÒÒØØØÚÚÚÜÜÜàààèèèêêêðððøøø���������������������������,����ä�÷��þ@‹pH´$ŠÈ¤rÉl:ŸÐ¨tJ­Z‰ÇeÁÂèz¿‰¯xL.›Ïè´zÍn»ßðxØà" ø<¾ ïûÿ€‚ƒ„…†‡ˆ‰Š‹Œ| u –— ˜›œžŸ ¡¢£¤¥¦§¨©¡•œšœ‘\²csq¹º¹]½_jÀ^»ÇÈbµ˜ ¸_µ³“¶bÐÉØq½ÛÝÝ## à -åÂá½Æ ãéçÙò¹µÕ“ÏdÒ’Ò˜øó�ÙˆAA ïÀëÕ‚††-šK·°`À‹jêEûÇ ‚?jÓ¤ÐãÉ1ï žCHN¡±†ã®TØÅet'sF³´×þÈ.úhÙórM'F—*#v#8‚eAq#6çm©SœFsjôb $WYû†v)šµìœͪA^Ù†tð'£»xóš€gÁ½€"@×]?À&HPà‚ãÇ#KžL¹²å˘3kÞ̹³çÏ 1/Þ2ÉÆŒÓ¨S«^ͺµë×°cËžM»¶íÛ¸s¿Þ�––Àƒ N¼¸ñãÈ“+_μ¹óçУKG.¡wé騳kßν»wíÕCþþN¾¼ùóèɇß7^x‡ðß;ïÐáEá÷ÓëßÏ_ÿzßÄÁ÷}�Ø—_r˜ }öçàƒ6÷ßuÃ5 �| �€aƒÆþY˜á†^Èa„$–á„´œ€ð…Ø@}Þçbbhâ8ò‡¢ŠÀ±˜a�#r I£…Bæ¨ä’ßí¸Ÿ€LF)åtNêGß”Xf¹\•Zvéåƒ\~)æ˜åíèÁ™h¦©æšl¶éæ›pÆ)çœtÖiçxæù&Š*èé矀*è „jd&ªhw‡.êè£Ð5 餔'i¥˜Vzi¦œJWƒ  †*ꨤ–jjC·é 2˜êê«£¢ú§°Özj}´Úªë®¤Êš+¯À†Šj 5XY ¥! ת åÑH¬yΛc´ýÑÈãyÇ·éiØ^ë�Þ–îƒãî—­ªþÉÇ­yå².‰íò/zç·í ÝÒûn„óê×/»ÇÝ›ïÀJþ«o…/VX܆W"W¯pã—ppWÞ7âqóæ÷bªÄ5ŒñµV|ñŠÀy\ò&ï{ñ‘\2” SÌqpó(ä{28ä±âlàpq2þl$�8ËÇàÏÂÕL4‹ ZœtÂ07ïÍ8cq}ú¼¡/RÍa¿<mµI³¼tLÓÌ£‚ ¾  Ü4¿Xc!š4pC÷(ä†q»øcÞ©:-·‡vÝb~sÓoÓL7ÑgÓ,¤†xÃwaæ9qpHñ…t·ø¡ˆ>î6ÐnN·ë•ß2þÒMœ.pëž|¤âEר"Ý4ùá¤ë¦ßüçµ÷8ùñïiX·ˆœÿ.»ò´¯Î:”ÙÞ{‚€c/<оp¡ç[ã±5ž}óÚÞþBîºo$@~˜úF2_÷é—«Ÿ…àf¿$iotŒ«ŸÖìS»ý¡/}íS_ÿ(9èeË~ˆsÜÍÎg@«íë[¶Û‡pè³îƒÙ1¼PØœªG…ßÙÛ úŸ©Œ…Ó!„t8Ÿ™P^!¤Åñ它-‰‡1Ä¡vdHÃo)1:HìO»3Åì@ ˆ“ᯂÅÅ.zñ‹` #°ø“+mËÌꔣD:¡É„kŒ£‰þªÖD9ÚñAt|#ïÈG<6¨Ž} ¤yò(BuíQˆäõ8dà‘Œ¤$'IÉJZò’˜Ì¤&7ÉÉNzò“Á $@ÊR–Rƒ#…C‚ˆñ•°Œ¥,gùÅQ¢à–¸% bpȶÍp•Áie¨J`*b ´L¦2—IK[¢€&àÀ-y™J7w½&¨Y*n–Š˜È4&3ÇIÎrÖÊ™4¦ÙKB ÑL P‚Ðsž%Àç<E…Ï|ÚÀžæ ¨@jKËÒ¤¦ÄTyÍùeSžÛ´ìéÏŠS¢E¦7ÊÑŽÎÒ–éÎ:º¢E6”„­Ô§Dõþyϸt�6È'=aºQÚô¦]¥AƒƒP’RΚïÄf<yNzâô¨Håâ(i ‚4IÀ§¾¤¡6“JÕªÊr”'à€V·º‚vš4¨ªUÇJV/޲T0ð*CÁŠRW–õ­p=§x䨨Y„'+Ý×¾úTgN]ïÊ7`gªMlY+œÁV³°'}¨b'KVÆòÔ®ýedÅJÙÎ"Õ²ÀqìBñŠ(½“¯žM­GAûÑ–t­yê^UKÛŽ²Öµ?…,[%[Ûޚ󶘭ncÖÙúö¸Ì.a5»[Î"÷¹W«`ƒûZÒѹÐÍn•›Y©¢V»àÍ©tKþÝÜ2—¸m ¯zÅK×òFÕ°/@ìzç+×ö.×»ôÍo}§{_øÊW¿�w…{ÞÒÊö´N°¨\ÝḸV°‚l^üJ8Á~ïf{a�gØèåm‡õûᯆ»#^o‰aûàô¦8¿+¶®iû݇7ƾ.‡m¬^XÇæqÇ{Ùþn8ÈB¯-œd%9´îq‹EÜäì.Ù¿5®òq¯|dkY»\n¼å'·6Ê&ž2ŠÉ\Û0ŸxÌln³™q«a1#9Îr¶ow±Œç2ë™ÀLî3mݬf8 º³„²—=è9£™ÅŠŽo–­ØDÏXÒ”V­¥¼èþL#ÚÑF¶s§==ÙMCxÔ¤N¬©]œêJƒzÏ]Æt«]ýçÿøÒÿ5\WMe]Ç•×köue_ h> »¯À6ô±­šì;/{¬ÍFõ³™Ml[zÚÔ®u…mhW{Û±Îu·mY»ªå÷¹mšîI¯{µß®ó›ýnvÇ[Ê‘Vw½Úî}öÞiη»ýÐ~ü¦?8¼µ-ïBÓ[á¿8¤q=pˆ'Wâ2æ´¹-NPŒç˜âçhÂCq†ãä$/¸Ço­q}§ü£+¿öË—9ò™Ó<æÜ¶ùÍMp”ë|çü…µ¨7þófâ<Ü/:k®ôX2½é¯|:Ô·{ô¡þ»|êJ­ú¼¥õ¥kÝá\ïºY¿.p±ÃRêfÚÓΫµ³]Wnû~Éê­]îc$»Ïñ®v½·<é|7UÜ_ªÁ~T†?¼€ý~ê»+þU‰|ä?ùÃWžð—|æù¾y¼w^îŸ{èÙ>ú´—Þì§{껾z¬·~ꯇzì›>{¥×¾è·ÿyîu¾{›÷~æ¿yðS>|’?äÇçxò-¾|ˆ7_áÏ?xô >}Wßׯwöß}V5aàÑoüÕ¿ø¬nU«]ºÝÇOþßH€¤J«úÁîøö“J§Ò)TOþwûË!ÕZ°=×þyë´S¶D€gþ€(xë€2€P»TwôÇ~äçL,àÈ€áÇjxˆ M8e‚…÷T1+Ђ1@i) 6xƒ8˜ƒ:¸ƒ¹ñ*Ðidmð•HDÈü×xE˜„Øq„p¤„NøLØKO8…Ì…Tx…-T€Hˆ…\ˆ‚—Ö…`nC†`h…dx†fx†a˜†Ü!<ˆõ†Ü"‡:‡8Hl¸3Po¸/`r臀H‡º!ˆ9è‡ß‘‡ÚÑ„Ø!X&%ŽøDÇሉ¨…Œ8™(“‰”¸xˆ‰R˜›¡Ø$‘È$©Øˆ£Ø€[ˆp$C¬C­þ&ð€JÁÁÂa&@«8¹˜‹Âá‹À¨ Àh‹¼øÀØŒ•8Œ”s.´h‰Þ¡ˆ¦(…!‚>t9A’=Âq‹ÒŒË¨‹Ê¨êØŽ»h‹ÖÍ˜Ž»è‹ð÷ø¹¸‹úxÀŒºÈýøŽÅaŽEr9H23ÚØÜ(‹Þ8Ã8´4æ8ûM9ºŒÃaޏ¸‘i/ðŒÏ8ÐØ‹ÍXŒ&Ið2›ƒ$úãB£ôŠXŠ :€s$Ã> ɨ& ʘŒÌXŒBÙ’Æa‘A¹ŽÓ(�”Aé‹ÿˆ‹+ •Æa2»#“ i„¤øþp´1ôá5s2H9EI•ÒxŽ¸È–gIGŒ))”GÉŒÌèƒA)òx—Ky”ó3_—‹§‡ù)ŠŸèñx2)R4ùq·ˆ6I%ɘR²˜Š9™,‹šx™œ˜™ÙÁ™%bš♀¤‰.P(“X(gòš°ù'²I›ª9„Ù1°éƒ³é¼Ù›~ò›€r›±¦†XØÆù„„4‘–œTX5£1†Î©œ_9Ç©…Ä>Ú¹ÜÙÞùàžâ9žäYžæyžàÙF”ù2èÙžîùžðŸò9Ÿái/òcƹ*øy†ú¹ŸaØŸþÙ…Ö�žð ªp šE  º  Ú ¤` ›� ’`d±z¡ÊÚP�ð¡ ¢¢$Z¢&z¢(š¢*º¢,Ú¢.ú¢0£2*£#Š¢A��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image2��������������������������������������������������������������0000644�0001750�0001750�00000000112�07504443352�016503� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ð�����ÿÿÿ!ù���,����� ��!Œ©»� s‘ÍYÓ½ÙìbáH–£gžRú)`çrpüD�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image1��������������������������������������������������������������0000644�0001750�0001750�00000000161�07504443352�016506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ð�����ÿÿÿ!ù���,�������HŒ©Ë�œ\ÎûªÅMkNyˆˆ™™'¨šXÛN0,Í4cÏa'|~øSBã†"Š’$ÊI‚²zI)Çú¢>µQîTÅT®�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image11�������������������������������������������������������������0000644�0001750�0001750�00000010605�07504443352�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aä�÷�õ�����0@0666>>>>R>H`HLdLVrVZvZ`€`d„dfvfhˆhllln’nr–r||||¤|€€€€ˆ€‚š‚†²†À”œ”–––˜˜˜œ¬œžžž   ¢¢¢¬¬¬®®®°°°²²²¶¾¶¸¸¸ººº¼¼¼¾¾¾ÀÀÀÂÂÂÈÈÈÊÊÊÌÌÌÎÎÎÐÐÐÒÒÒØØØÚÚÚÜÜÜàààèèèêêêðððøøø������������������������,����ä�÷��þÀ‹pH¼$ŠÈ¤rÉl:ŸÐ¨tJ­Z‰ÇeáÂèz¿‰¯xL.›Ïè´zÍn»ßðxØà" ø<¾ ïûÿ€‚ƒ„…†‡ˆ‰Š‹Œ| u –— ˜›œžŸ ¡¢£¤¥¦§¨©¡•œšœ‘\²csq¹º¹]½_jÀ^»ÇÈbµ˜ ¸_µ³“¶bÐÉØq½ÛÝÝ## à .åÂá½Æ ãéçÙò¹µÕ“ÏdÒ’Ò˜øó�ÙˆAÁ ïÀëå‚݆†.šK·°`À‹jêEûÇ ‚?jÓ¤ÐãÉ1ï žCHN¡±†ã®TØÅet'sF³´×þÈ.úhÙórM'F—*#v#8‚eAq#6çm©SœFsjôb $WYû†v)šµìœͪA^Ù†tð'£»xóš€gÁ½€"@×]?À&HP�ƒãÇ#KžL¹²å˘3kÞ̹³çÏ 1/Þ2éÓ¨S«^ͺµë×°cËžM»¶íÛ¸s¿æ�–Ö Àƒ N¼¸ñãÈ“+_μ¹óçУKG.¡wé騳kßν»wíÕCþþN¾¼ùóèɇß7^¸‡ðß;÷àFá÷ÓëßÏ_ÿzßÄÁ}�Ø—_r˜ }öçàƒ6÷ßuÃ5 �| �€aƒÆþY˜á†^Èa„$–á„´œ€ð…Ø@}Þç¢bhâ8ò‡¢ŠÀ±˜¡�#r I£…Bæ¨ä’ßí¸Ÿ€LF)åtNêGß”Xf¹\•Zvéåƒ\~)æ˜åíøÁ™h¦©æšl¶éæ›pÆ)çœtÖiçxæù&Š+èé矀*è „jd&ªhw‡.êè£Ð5 餔'i¥˜Vzi¦QÚpç †*ꨤ– ªCš¸) 3˜ê꫟¢ ƒ§°Ö:ª¬´Úªë®§z`ƒ ýÑ8+¯ÄÞ «¥! ×ê åÑø«yΛ#<êÀ³é ‹ì>Âv�Õz.“ã:X®µþÇmê­yç–×.ŽïZ®»é&ܺîÎË]¼&ò‹ž¿ä¸--ÝÒð­¾Ûa»ïÅ·bp ×à•Å),n½ÜÞk0~/ºWß}#÷n~/¦JÅ"W+à•PvÊ/ sÅÕ œ`p ¾Xrà ¤ÃÜ1~c83q§îÆ=Ê´‘�¼×sÏ-÷®Í6–Ì¢ÔR-Ü»B2$}&]ß…]oh ÎsoÎB|! 9kèâ†aÍca—u×V7Ͷ×8cL°Æ ¹áÍwG"ÌW[ía†h·d†t[ùÞ…' eÒt iwæX£éš§ú¶×žûŒ9Ð5ªM£þêœÛhº}tãüâé™ç]øÀ“ìñ‘•;;æήwÐ’c˜üåu¯õò_?,0Šk¨»ˆ¨;OzNsÍBÜ…B¢Ÿ ’ô¡ŸäøÌÃwáíóÿ~ºôª<ârknäØóÃÛŒD=Ý}È|@²PÎЇ=Ú {sk Å”3¥O}5b áǪçjr]ú,#eÐï ðÅ?é8fÿB„,6Ÿ²!M†ÝÝp–†ÀÝ0†äÂáwh¸/ý±8ø ˜§CÄþ41‡KÔŽ…ÃCvE1:OÜO·+bgŠÁQW®ŠEÆ2šñŒ¼zÐѨ+©ëÌâ”þ§4·0Ú ‰L›£•Tµ*îñ7êãaD@òA‚ÌÉHD6ÈŒ$zy¸E G$Ȥ&7ÉÉNzò“  ¥(GIÊRšò”¨L%*aà¦T葃,$ B ‚ZÚò–¸Ì¥.wÉË^úò—À ¦0‡IÌb “Yè€2- Ì€ „ƒ$a@°ñšØÌ¦6·iFH�à4AÀ)hRr– N5oP‚Pu‘Tí U ÞÉÍzÚóžõô&9_`rš–Š$$4«9€Ð]lg<o`Pv¾“žøŒ¨D'ª+}¢à7g9_IÅXT�ÀBp„ÎTegI)þÊÒ–ºôSúÜh ú¹QŽu4 ²TÁ<ÚE„"T¥ MèJ_JÔ¢rSŸíÉhMWÐJ t8ë•BK P’®ô¤'5ªV·ÚM ,u¦KmÚMšS®šõ¬õf $ÀÖ¶²àŸcEçS…U´Úõ®×ô¦ öÊWÔ�®vÄéGñJØÂË›¦IÍ L�XàL³®†¬dI…Øá|€± ,Y;ÙÎz¶²Â¹lc¥éQ¨ZÓ³¨,hƒ#ÚÌ:¶´t=mjg{×Õ§µ6Õ¬\ËJÛÞžÕ¶¬Äln_+XÓúö¸[.n™×#ÎU²E®t[ª\á2W·Îåít·;ÑêŽö±Ñå®xó)þ-W¬Ø^lÇË^òš×ºè%îfÛÞúbÓ»®%mq×kßþž¿ÃÕï|ùëß Àוïn9kàÛ Áñð‚éëà » Âѯ…7\* Ÿ3» æ°ˆS^ËÂ7ð…îˆWìá¦N˜À+Þp‹›«^ǘÃ3No Ù;8Ç 1…}üã‡öÄ®1ÃKäYÂB†q“ldÖ"ÙÅQ¶ñ” üd o™ËU¾í•i¼cj2ùËíírŠ—Œf*¿÷»k6s›ý«æýjyÎispálg6ã¹¾uðÿ,Þ@¿xЄޮ¡³ìçDZÏçEqŸåìèG¿9¿^®´¢!=fþ§³Ñš–LéP‹šÓ|4¨MíÛQ—¹Ç¬¦­«?]êX÷vÖÏ]µ­S‹kíîz¶½ñ¯Qì!û³¨Ætœa}lÉ[ÊÍvv²œéhOöÙˆ¶va±­km–Ûµöö¶§`(“šÙâ¶+¸Ñîß’;ÂÕnwmß-iU‡[Þh]÷™ñÍU}ó¯þþ·ºéäWï[àE 8Âͪð…'—àX>÷ÁNÝòª)²Ä)Þo œ ™Í|«²'ÍnŽSÔ›5U R}èn›œ¥Þl´€ãU–3úÞ/‡ù7kÇt ¬õn9ÎsÞÝoÊœæ(�zÁi]r¢ßÓ¢<÷yÒm¾q§þ»Ô¢-xÁ7§>r{7ÝêGÝ: @Ðv]è_»6õºWðõ¯g¿¹ tC÷ºÛýîxÏ{n`°‚ÖıÜÓ”¤à½³ô\ogzG@ï-Æ;¾îä)|!µC$ž0Hìå3ÿøÎÛóß‘<4)?úìH óeBýOúˆ—™ôMR}콘(ÖÞõ´†½wNOû-É^¶ïŽè¿3y0V¬8¼'Ž @�‚§Â1 ¨ó{ã,¿ùÄY–ègÎŽö±/é;'øĽáuÿ5öiPtAŸp’?ów`ü+¸?óñ¿âÐ9ö‡ß×|&ùGv&ÐÜÞÇþË÷€Ø|Û7XáG}­Gf¹—Å·8Š=õFÿöw} h‚Òg‚þW}ÅQ‚)(Ì×}Ý·Ò}Þ'ƒ0‚ (ƒ ¨ƒ'؃:¨}Ó§è·Ãç¸!Gâ7VS6#Ò'„˜QHƒ~+ˆCQ¸}/˜ƒÓgƒùç…÷wƒÍ'…;hƒ>¸ƒi¸…Cˆ·§ëÇ£·3b4ùq4OÈwæç…9ȇ}¸‡Ã‘‡Ù·‡€è…Î~Ó~÷w|h~Ó÷ˆà‰ˆ(‰Î÷ˆmè†Â§~“'‡³—z½Ç7X"E¨GØ›ˆ‚,È)£˜¥È§H%«¨ŠŸ(&­þˆ¯¸4ð…Â{…r&¾ø‹Â˜'·8¹¨3 Œ|7ŒË8ŒÎh'‘§‰¥7xÔˆ‹Ò8&žGw‹gwcrŒY¢yÙX˜Žºz_âXR‹ç‘ŠÏQŒQ‚ŽS¢ŽæÁŽç××(&òè‰ÛáŽLR2/ø|†x…ø|Ëw:H}*óB*dü¸$þ%�ù…ø} �IBx‘ ˜ƒÌW×LjóÇ‚E":쳂b‘LÌ'}-i‘Ýw‚:H~1ùˆ\èƒI’=jˆö‡±øÖ÷…UHŽèL)†é…3Ù…Y 2ÄãAÞô“ž‡éhXh‰9(‰zHƒþ_I‚$–Sˆ…ÈÇ‚,c‡6‚’çx_’ê1‹E““)é–^—¨Šu ”ÓRBb•÷zßøŒÄ˜yò|d—]Ò'†‰'Í(‚in„Y– *y™šy™¹™žImÕV¢9š¤Yš¦yš¨™šª¹š¬Ùš®ùš°›²ÉV z vÕ™Ÿù™º¹››Ù›¾y™ÀœÕ8œÄ9xÆyœ’”œÊÙHÌÙœ‡ôœÐ HÒ9{TÖ9G™™@;P‰  –²Š3;ê#��p9ÎBÀ6Ü©@!rAäY"ǘiâJïÙÉs@kã= 3;6ß‹“y jþ˜ú š“ÆJ”°C7Â>òS:Ú’;-²6½£„L¹†ú¡ ¢":¢$Z¢&z¢!:‡Œ\–Gqä0d38¸ã7(1\Ó6P’ḣ<Úy‹¥¢|I‘Æ×!!SŸæ1¤Ç8¤HŠ)Jº¢LÚ¤”ò¤Ajb})¥B¥W9yQŠ¥YzbAws{6P¦fz¦hš¦jº¦lÚ¦nú¦p§r:§tZ§mVú[:z‘¦¸iOyw¤6¦Â¡ +õ§¯¨ jo„¨î$*’ª¨vd@º§Bzb‘êSCÅN@U?U©–:*Œ xqö¨À©%å©(õ©¤Zª¡þrªð–ª}ÚSóÔE¡Úª¹ÊP‡*«¦Š©z:˜¹×§ð¬‡%¬‚úzÆŠ¬lD«a:¨‘æ=Z­Öz­¸­K ¦]²£Ûˆ­®ñ­Ú¨¬*tªú–Ù8Žàºœgwæ(f™J¬ë×¥Y‰€!÷ê{䊪 J¯~i¯r)Š˜ûZ«ýÊ­Z‚—Ç‘¯`2°Ì~Z*¯\аß 賫8;Tù;Ö#Û9 K’ étieñJ™ÅJ±õjS!²ž“#@ä„«Øîà t<F²A Â@Žãž>¹ 5'铭̪²ÿŠé™;Ý£ XG#.vã Ó"Š$$ŸÈôþg©2;@k9’E»­Wš´Ì>ô#?ö±„x(²öá²ñq<'T¡”·ã8$µßY#29l ¯ÃвóŠ´Bù@RY]C6ˆÛ1›‡W"5÷‘6 ³¶C8s£ò2Ž[¹>Ò¸Ú ¥„+‘éÁ°Bº[•c ºe[¸ëè°'âºDø¹UZ´]¢°9i»ÜAº˜x®F›²«+‘†Œ *'Âë' ¦d›(ŽùŒ‘9¼qÒ¼~"»š ­^ )+¸û»Õ+&×xþº½cÒ½¶ºàë%â{°Ú[¾Zr¾ŽzY0›ð¿ò;¿ô[¿ó‹¼PÎJQ'xêkHØù¿“é¿|º+ZÀ<»L¼ÀrÀœ%ÁS’H£1¨œ)U3ŽšÁ˜2Á ‘êG:W[Â&|Â(œÂ*¼Â,ÜÂ.üÂ0Ã0 µ‚; 2|Ã8œÃ:¼Ã<ÜÃ,¼Cƒ´*B|HD\Ä€tÄH¼GÖ�žð ªÅR<ÅT\ÅV|Ť�Å›� ’`d±`ÆbÌ_ÜP�Æj¼Æh¼ÆnüÆpÇr<Çt\Çv|ÇxœÇz¼Ç|ÌÇm,ÇA��;���������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image12�������������������������������������������������������������0000644�0001750�0001750�00000006773�07504443352�016607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aä�÷�õ�����0@0666>>>>R>H`HLdLVrVZvZ`€`d„dfvfhˆhllln’nr–r||||¤|€€€€ˆ€‚š‚†²†À”œ”–––˜˜˜œ¬œžžž   ¢¢¢¬¬¬®®®°°°²²²´´´¶¾¶¸¸¸ººº¼¼¼¾¾¾ÀÀÀÈÈÈÊÊÊÌÌÌÎÎÎÐÐÐÒÒÒØØØÚÚÚÜÜÜàààèèèêêêðððøøø���������������������������,����ä�÷��þ@‹pH´$ŠÈ¤rÉl:ŸÐ¨tJ­Z‰ÇeÁÂèz¿‰¯xL.›Ïè´zÍn»ßðxØà" ø<¾ ïûÿ€‚ƒ„…†‡ˆ‰Š‹Œ| u –— ˜›œžŸ ¡¢£¤¥¦§¨©¡•œšœ‘\²csq¹º¹]½_jÀ^»ÇÈbµ˜ ¸_µ³“¶bÐÉØq½ÛÝÝ## à -åÂá½Æ ãéçÙò¹µÕ“ÏdÒ’Ò˜øó�ÙˆAA ïÀëÕ‚††-šK·°`À‹jêEûÇ ‚?jÓ¤ÐãÉ1ï žCHN¡±†ã®TØÅet'sF³´×þÈ.úhÙórM'F—*#v#8‚eAq#6çm©SœFsjôb $WYû†v)šµìœͪA^Ù†tð'£»xóš€gÁ½€"@×]?À&HPà‚ãÇ#KžL¹²å˘3kÞ̹³çÏ 1/Þ2ÉÆŒÓ¨S«^ͺµë×°cËžM»¶íÛ¸s¿Þ�––Àƒ N¼¸ñãÈ“+_μ¹óçУKG.¡wé騳kßν»wíÕCþþN¾¼ùóèɇß7^x‡ðß;ïÐáEá÷ÓëßÏ_ÿzßÄÁ÷}�Ø—_r˜ }öçàƒ6÷ßuÃ5 �| �€aƒÆþY˜á†^Èa„$–á„´œ€ð…Ø@}Þçbbhâ8ò‡¢ŠÀ±˜a�#r I£…Bæ¨ä’ßí¸Ÿ€LF)åtNêGß”Xf¹\•Zvéåƒ\~)æ˜åíèÁ™h¦©æšl¶éæ›pÆ)çœtÖiçxæù&Š*èé矀*è „jd&ªhw‡.êè£Ð5 餔'i¥˜Vz)¦5Øàé§ †*ꨤ–jCfÊܦ/È`ꫯ¢úB§°Ö**ª5Ô $³Úê«©²Òúë°6ÈjiH¹*Cy4æj<Þ€³ü5«kz¼»p§@´Þ}ˤ¸’«_þÚÒÂí Þ‚Û¹9»Ÿ¼Þ·i·æÑ®»$ꋞ¿ä¡[ܽìæËïvô x%”w¥{C>|Àó'0qWø"ÄöuÌœ¼ù½˜*q'¯ IßÈÂPß…ïÕ·¡/nÌ0pð¾ߊÁé\\ƒ%·ÌãÎøýŒaÐÄ]<\Æ+Êhà Fº,ò} >-ôpèÎ<õ}5§lupò \ ÀP^ €Ž ß…jgøBˆ%Ó›µÓ83ƒSC-À×8óX Ê"»3Ø=Æg3‡J ÇôŠBn˜àÛþwªaãùÙ5g¤Û“_Ý2ÏèÙ¸†`_9†m×8 Ëž_¶^ø¶þiGŽ!Ê­×mãØ‹ýbjãNxº“¬ ñ‘0?^c‹³ÓH¹ß–£;Û´+Ì:Ø<Š.»è+÷èúÚŠîa idîºçG6Ôn?½¼Î£¯àø³S_÷éªÇ?üÀȇ¯ÃåãžÊض!¶qO~-B¯€d¡ùð|ØW´ Ä==0r3!Ø7¬Yˆ}æóP’fwºŽð~üÛ–ÿ &º%í`Ú¡„d蜛™ †ï²Wÿ€ó¿è ®84ÄNû3Äå í…Ó¡ yÈ€áPˆO$bß5Åì$.8‹s⿪¨p1†_”Îs/aëŒh|“̘Æ6ºñWº— þ–¥ª:NIvXÜá zhÇ>æèfYô£ KH=òqˆtP!—¸Ç&&ò‘OjP !IIó,R]+ 2ÀÉNzò“  ¥(GIÊRšò”¨L¥*WÉJU‚àˆ¥,e©)ÎŽ$A ÞÈË^úò—Àü%,Q@Ì1pä%‹—Iáè2T%ðT4ƒIÍjZóšÃ& X`3™¶Ì##ùøLPyÑçĦ:×ÉÎ`j“2À7•)I\j2%€@>!ÀO~~ŠŸÓl§@JPR “ºò€7Á‰ŸzŽ3—)è§ý™Îtô¢mç0á y2´i·|è=%JÒ �ų́JWþJMX"48 ýháBŠI&ÞÓTe©NwêFXÒ@i’€LùÈròô¨Hí%,OÀ¦:uô¤)3mêÌ]&õªX%,Gƒ¨Š³¦¼iVÇJÖRmu80WÉhϪ–õ­pýx”Öµ¾ ¨V«^¯zVáÔ5œl©[÷JØ£ö¦jì]Û£ö±*=,pþÚP©"ª™Í+d7[Pɾ€² ýêTÃ:XΚV žíLE{Yªfö´°egj[YÖ¯´±ÍmKçŠVÚ†6°`%§fuK\¥òÖ¯¾]-pG+Üâ:׸tM.Q Ç>÷ºZ=.bíŠWìz7»Ñå.u_`þÝïš×¬Ú¬t—ÙZÒ¾ö¼ðEoxÛÝøÚ7T³¯`ß{ßþæ—¾ã-oÏûßÚ.·½Íð} üÛÅî·ºÃU°y¬\¢¶/…§û`òF8ÃØÝ0{oË_WĽ°XM|âô~v½)f.†YÜâùØÂ2^1¯‹bË’Â;önm‹Y ™Ç.V-‡UŒÛ#wÈþ±‡ü\(ãÁ3¦ò““ cyÊZÞ²\ß0çÖÊe63lÑ૲lî°€ßüØ83¹ÄtÞ¬sÜä<×™Ëú½³‘ý¬g@XÎn&t\÷Œe+š°Œ–òœýÖHyÒ”&«¥];èþLëuÓîí´§á êzц¾qšO]ÖRg™Õ­N5™Û kR˺«®5V]íh]óõÖKæ3ž}T^÷™Ø†öˆ/hd³ÔØÃvöN¡-jiO[Ù1nô±­½Rjƒ™Û<õ6¦ÁÝYl{™Óß&÷³ÍMdt[ݨew”™ oŠ»ÙõÖ¨¼¯,i|ç{÷þwd÷kÇ{̸¦µÁ/ð…—áÁÖv´®Î†Süའ´°«}qlZ¼ã�'¸ÂArˆ/ÛÝþ&9t3~hA§[åÖü8Ì«)ó™»S䈶ù5k®s_ò¼ç¼ü9Ð{Šs—¿{èàe¹ªGŽô•#WãçxÓÓ(ô©þ'ýé-ßøË­Nõ¢kýè\‡UÕÃn«±“]ì^úÖÏþ+³³]¾JŸuÎß~F·Ó]Tv¿;¨ò®wOñ½ï×{àï>xºþí‡g{âϾx²7>ìçzä­>ù©W¾é—Gz懾y w¾çŸ×yèm>ú™—æ§WyêI¾z·¾ã¯¿xì)>{‡×~á·7xî¾û÷>ß¿¯wðá=|uŸÜÇwò¹½U5a ËíõÚûŽ^¦:µ©PͺÚÁN}¹Ò@T]Õ~¿»_v ¼48B…úøÉvpô³êÉ¥Ï}êôZU?½Ù¯Fyº_ …Lú‡rü×ÄÄ.àò—mëWþ€å(ðÞ$€â·8*°¸40€Ò—º1‚$X‚&x‚(˜/ ­AGrçr•ƒÞ1‡$ƒ6˜4èH7¸ƒ-Ä€_ƃ@XC>ˆnAX„Ê‘ƒF˜„Ë„JØ„2„Òç„RÈ„RX…'eV¨„TÈ2‚¨ÑH^Ø-ax‚`X‚ä±…Û15à…ð¦†mø†c¨qh‚møh¨5ˆà†eâ‡QÒ‡aD}ˆ‡P¸‡ÓˆÒ!ˆ8ˆèÁˆàq†‡¨ƒÙ¡ˆÑ‰MˆL‚‰|(‰ç…•¨ƒc”4ÅÁ‰Àaðµ &`Ô¡‰ÃЍ(­þøŠ*À*ðŠÆÁ¨¸Š/ðмx¦è>ŸCŒž}–‡"!d>h$×#ÅÈ‹º˜Š¹¨ظªHˆ²èаxªØŠðåø¨¨ŠèXŽÀq‹©¨ŽëØ¥øîSA 䆸‰ËøÍè8³9¬sEÕŽéØM)Œ©‹ÃQŒ§˜IŽ/à‹¾(Œ¿ÈмH‹9ŒÞ-ãƒ$b# ™ŒóF„¡˜4Žs$ƒ3,3Úˆ‹¹è’¯ˆŽ*�ŒèG§H&0“º(ŒÁÈ舋­ØŽ7I‘?© 2ò:.2"…8ƒ“ø‡$2+s8ƒ4Ÿ‹ y‘Á˜•[9î2“þÁØ•99“µ´‹»¸‚9F™“°8–`é•$#3O33øè”úH‰Ø±ÎÁ‘èˆçÁ—FcMÙyX’Þ˜è—æ˜"’üöƒ†ÙŒ¹ˆ6y#“¹%Ž9I•è…"ˆ…r&žù™𣙙ã¥�ø™+(š°š¬é'® (¦ÙaY˜„…Y›A¸H£…¸™› 20Ø›@x›Âyƒów:Ž“œÊ¹œÌÙœÎùœÐÒ9ÔYÖyˉG#é0ØÙÞùàžâ9žÒ¹4zTœµÉ*èi…깞RØžîÙ„Ö�žð ªpŸø™Ÿú¹ŸüÙŸ¤`Ÿ›� ’`d±z Ê-ÚP�ð ¡¡Z¡z¡š¡º¡Ú¡ú¡ ¢"*¢Š¡A��;�����./saods9/htmlwidget/tests/page3/image7��������������������������������������������������������������0000644�0001750�0001750�00000003115�07504443353�016517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a‘�ò�ò�����???¿¿¿ÿÿÿ���������,����‘�ò��þHºÜþ0ÊI«½8ëÍ»ÿ`(ŽdižhzBë¾p,«tí°î@Âvo:›ÀG åT­@qÙp± ”Gp2¯+DÆm·ØpEK#‹Ï 3eÚ}-Ôè3\ÁýZêq´§âç±jJ6,WjQ#S„…K‡ m2vUŒs&˜•'Ž=š›%l‘]Ÿ#¥ª“¢ Š;n².$±M—7­(¨w=@¸fG)I#§½PÁ ¤-R\t©t’x”¯Ô«^ÞÕÐmÉÎèi>çæëÌêÍžâBïoé5ìáòÛ¹ñô"ùêaà¦íŸwüîu3"` Bœ‡O`A{ûfÔþ¡F†ØúÁéêÁ¢q-óØÌ‚Vù$vÜø+/p 8¥$šÏ92Eb„ÀsÍŠê|8Eiˆ€ž ˜ºœ¨ðb`A†,Ò X‰UŸä<Åb§1§7‡ªÁëÈ¡èrºAˆ•¾;ÄZAIO h7Ý·&Ë~ÞÞ°[¥¬SÇ@/lI“²b$H·<5¼#,¯Ì—"ÛÅ*Ù@Ïu,ŠL¯·žjÿúêl:à‹ÁÖ&º´ŠÚ'Œ)è®j3ž_Vr‘Ûmq±ŽœÀŸ”¾Œ8ZaŒY©)ÝìTê”v6oèÂûÕ�ÐÍ>5+¾|c¶œIf õôç2¶$¿^,¯þü‡þõWÙxóá7 €ö1}­ÑàV/,8Ð,©PÂ-Eó…el؆„z€r—ˆYŸ‰Â¡ÈœŠ'š¸ß/c3Èâw›Ô(Ç��€Ža�‰�<¦x£�D9 ˆy$L²èdVi唳%È–GX—FjùåŽ^ÂH¦˜fŠ&˜Rf“!¢ ç™VÂf;r®ÁŠc¾q¥P€¼™¢_½9Õ›y šç;é€\]N—¨›‹ŽÒÛR¦fxj :AQM‰µÔf%ñ ' Ü‰g[ÒXi§q²:f¬÷Ùé*f9Þ*kštrr寫èꢒœš*±]þ‹ìª$ªZ„³.»i®ÒÖ‡"´‡[m‹¶n ¨¶Þâ(l¸üµJîŠøˆ­M&yn¹0ºûî´æÎKo!ò¸îÀFH¬±Ö’ˆ¿RÊøK¾Šö€ „Ö]kpŸtasͽõþ÷̆Ì6û°Å{Z ÃÙî .ÇôÌ®¦ÀMÒ˾“ŠüÆm„R÷­ˆwb¢ÅÍÝù–±Æì:¡šj:G#•µ*Ö< zAõ{#*K2mE‡\+ÈO3X À¨bjÒ9ú黟€9JIY?GÆÞVV°ÜrÖ†þ1ZKÁÖÜi{ýOÛtï ·|Ð-¼ÔæuÙ9ÕYØ{BáXÝGø·^ «Íé«PþG-ßIä+yHÿiÓä(b]²0:%g–ÜnsKsçA*wQUäš&582Py!´¤2¯îñè&Snuà¸V=«ð§Ù¼kTï ½òÂauË)¿N¿Õ#»ùUÛŸ¼„èövÿž½DGO>ºD`~þÌÏBï-ø¿¯8„òg™¾ûïBË{ýMÇÏï?|$ü€)0Ëÿ 2¥��À€ëS (À«¡@‚ äö6ˆùUp~áúàdÎ'BŠ‘«„%ÞñÖ‡Bþµ°~¨PO쥋 À°K?{‚tDÓ:Ca°|$Lnò4‚Ù/ˆÂY¡ˆ¸´‘|+³BYv¨·Ÿ<fþý Ÿ  cŽ ‰Ýòà¡8F-Œ#ãÕFrðË`|ä8':ÖÑŽ´Â#¬ôh>>ZÂ{$¥9HBþчD¤Ô¥HÉ«‘øx$$—7I@°’o¼¤ §ç )’MðÃãÂGDFjbY˜X Ÿ4ŒeFkd,?)5?ÎÒ”µäã- ¹KBb 4äÞÎùK®D*:§&,%—Æä`.Ê´¥7�ÃDÁhb• 3‰á®è¨nFS—¹Ôc/‰9͋͑—#Ò 6 ‰Å­ç&è¹ÔÉI4·-¯”f_ÖƒŒFá�:ÁDŸ8/´ u2a?¨0h")¹Àq.Ó{ vt¨>'G‰‚¢t´è@¡ÉyQAž¬äÛ€ÕQ$��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image8��������������������������������������������������������������0000644�0001750�0001750�00000001540�07504443353�016520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ag�»�ò�����???¿¿¿ÿÿÿ���������,����g�»��þHºÜþ0ÊI«½8ëÍ»ÿ`(Ždižhª®lë¾p,Ïœ`ßxn4:è¶ÌØëìTÇâEÀk”ËaR¤ƒZ )pËÅ2¼Ö ˜5CÊH³¸ÒmçLõùŒ#i›r4AàÍzp|"Rr{^[l@Mƒ=zZn‡yˆ/•3‘”8xš2œ“7B[a£ S'¬›˜«‹)OEª LŸ$Uµ°_Yžž«J¶ ¡Tý·™ÈhÆ!Ï(Ä–-Ñ­ÉÅ˼ÍÜ.Ö&ÓßFÌÂåÕ便dèÊê+âºØÔëÛîóïìÙö7M~ÅþàçàP‡ Ìw¯¡¥ ^àd`HE&?d þ§]ºr‰NÄ‘d±Ž•LêÖ âŠ/+f´è£D{Vœi»„Sš¡†3õÙ3‹  ¯üÔIÁ D&Ù,e) É«Ašþ|i*Æ’/®Ùú…VÓ{žÊ’·uè²EÁÁM‰o®¾svÍëªDß¹¥²^ìVÍA:Öæ…¶FáÆR!ã•\—rË—1ïÕ,—ó5ÏAÇ=šô1Ó§QƒxLzÀMÕ�0 ›�Ö¢]Ö——0°ßÀ¹Læ;Ü.î9³%«œªñâs›Ç5$ntèp«{$No±ö»Ü+wšù]¯_#͗μ¡¢D]Süúƒ¶PìKºŽ¼Ê5éþÂî5"Ó';ȧÛâÆZyÍÅÒjøµáT�>Wáuf7!uò” †j˜!sÕgâ‰@Ø'Yy+îæ‹Á˜œ‹¼Ñ؉âø–ŽÈè=¹£ZY¤‘U!9–’�p“ˆ��e”S.¥b»¡Øˆf9Ø‘Ë-ˆ5×Q)Â"Bm©žaø†J’áÈ¡7`v˜ÊN Ê類lÒgˆÚ™ž" Œ>Öx*N`Ó"ŒZ~ðPiF2ñàRT‘ÞÉÀQð„ƒ&Á÷WLY¨Œ¥X<‘D§–$&x…î—VMYzi¥_¥å‰~ªÊ§¤Áæ 蜆20´Y­ÇîÙlŸÉÖ3¬§ÑBB(°,Ìš]#ÜÁ¥–9`Yå¸ä–kî¹è¦«îºì¶+C�;����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image3��������������������������������������������������������������0000644�0001750�0001750�00000001251�07504443352�016511� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a��ö����� &&&(((,,,...222666888:::<<<>>>@@@BBBDDDHHHJJJLLLNNNTTTVTTVVVXXXZZZ\\\^^^```bbbdddhhhjjjlllnnnppprrrtttvvvxvvxxxzzz|||~~~€€€‚‚‚„„„†††ˆˆˆŠŠŠŽŽŽ’’’”””–––˜˜˜šššžžž   ¢¢¢¤¤¤¦¦¦²²²´´´¶¶¶¸¸¸º¸¸ººº¼¼¼ÀÀÀÄÄÄÆÆÆÈÈÈÊÊÊÌÌÌÒÒÒÔÔÔÖÖÖØÖÖØØØÜÜÜÞÞÞàààâââäääæææêêêìììîîîðððôôôøøø���������������������������������������������������������������������������������������������������!ù��^�,�������ÿ€^‚ƒ„…ƒ]†‰†?DC0>*$*ŠŠ'<^FDƒ.4^ˆ”‚].P‚NY)2..<$.MŠ5R^Z:$R!‚C‚-[X.†F,T^QD? ,-)%.Õ‚.3+9^\U^L#-6^-„.&8=\TSOH*-´@^XH:´+ V¸ ùñ`“ 8�øø€ã„#íbT @áF‘ "l¢"†/J¼4©Q¢P¸BƒŠŽ%9Ž4`’€… (`,4@Á�.4ì`’¥ŠF¸ð1%É‹D0@ @K�4¨æÃK .n$2â"D@É;7�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page3/image5��������������������������������������������������������������0000644�0001750�0001750�00000004371�07504443352�016521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aw¥�ò�����???¿¿¿ÿÿÿ���������!ù���,����w¥��ÿHºÜþ0ÊI«½8ëÍ»ÿ`(Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL˜Ïè´zÍn»ßð¸|N—ÈxW Pïûÿ€‚m�wy‡'ˆ>ŠŒ!…<{”—“˜:†›Ÿ| :𣦖¦8’©£Ž¬8‹¯—’ž³5¨·Œ¥º¸¶½c¢À6µÃÁ²Æ5®É^ËÌ4¹ÏYÅÒ¸ÕY¼Ø2ÚÛPÂÞ3ÔáOÑä1ÎçJéê0æíCãð1õE��×ø2ôþ|ìÛ÷+ ‹U}Ø/á‹Xy ,q¸Š5"ÃøâÿGü>¢ë&rÅ�Š%U°KÉrÊ»–0Ë5ŒIÓ Éš8‹ ¬'ï<”Ì�­`ÆÁÌœV†[èó"ƒ…=Bˆ5SÑ>}˜>݈tÂË€E§öÛ)–&²�4PÛõ‚ÔY ĵ À#Tt>m( jÈa @¬±.AÁWÙ*PÚÖçÍQŠÙ¢Š¦˜€%IG÷.6.p`À‹ „•pã hY [¹µYÓeœácœçÌEÕ¢YPùóé ƒo©lˆlkCza[–ÇÀd¯å\{qïÌ¿#$µ°a÷î²¿Ëæ§ïíE´QÕ5RÞžy ÞÇêd©y§õû2Îîàñ§£ÿòÀÞç %`H˜€ àR÷“„ŸUÆŸ�]8BpF°_‡`"_hâ Û¨âþ£UàIàÛùÁháG¥‘ÔPþ¤Æ“ˆ3ž÷ ¾õ´…ß-Tq8 >X €»A€ÞÏ •%^E u€5×bƒ)H�z^˜P‰¯€çfs1÷yi·ÑzúxWÕ‹ˆ±'ž²$ÉÛkT¡‚¦€…rUy½ÜãÊY®ñ†œˆñU'2¶evœu hY¯ÉžrSÞˆ!{¦²’á-Žxi§¡‚A?´©©Yíë®r:¨|d,Ìåjì±Æú…ì²ÿÌ6ëì³uÁða*|`* e$.‚Ô)k¬–Ébä§Þ! b¢°µDãrZA±q¹Dé Nê2N^†»˜>†ÍkT®2Ôi®û W¼’Ôu‡±×&†n–9Ìm,©6Ñb )®HÓª)\¬1KÓ’ÀñÇ1±iBÈ$—”± &q’•þ¦Ì‚Ç#0:†(Ëœ‚*мŌLêüBΑT ;A ­‡¢*Ô;Æ++Í‚Í)´Ì……#KÝBÖ,óxµQ1k­’Ñ'ûlÒa‹‚Ó;3íÐi«‚Õ5»½ÎvËÝÕsÇ=ÅË>ù­·ÈfƒPøàçðŒ׈ãÃöây7îÝ"P.ù9ÿ|£èõåê0>‚眓£x"d‡®ÎãôFn:æ‚õêádÞ5ì^ôæ´WC4»GQçxýµž»–ƒP<.†îÃ[ðzÍÂ7ßËáP/=«Öo0úõÒôî÷ÜÏr¼ã¡óá[=²+Qzú.d¯íE¼ÿAòg°}ößo’êe� Êç?pÏ#Bþ ‚†`9è{†¾Ðœàâ2hA ƒ<™8œ/„88 ˆÂM´l!.ø=Êðû à ŸTB×õp‡ŒPa^ÄKñvEÄ^¿÷Ã$â!‡j¢Ç€:–­oŠa"ÿbˆÅ-‘w\ì"hØð‰Ñe6dŸÏØ…*bl‰lü ?Æ8Rá‹L£µ@F¸qb0#×È+hÑ-p,dæXÆ:*Ò&‰Ô!ù7GÚ‰’Œä ¯ˆI)Ò–ì$É>ŠR ¡lÊ)Ÿ˜J|r•IÐä# K'¼2)­¬%H©==ê’ ¹ÜÊ/æË!rr˜H%ðˆÌ&ÜCÁlf˜YÆIJ“¦\!-¯©“br“üæ+ž)N2P³œ´°&:×ÉÎvºóÀÑQZ~7+- nÎÙ¦b´€‹ÐóÇ$–tô9«“Ì+,iB( « ø±J³jè^æAÿ¤¿8‰<| [ÒÎ$¦fâ] hPªÂ•äAÀ›ÀŽHi4*íLBIËLÏû8hÃ$µ¨2˜ñSVøb Ý\#X%Õ2&è$TJã1uø¢'5‰ê'«y¢nó-Q)õ3 ]wÄ4ÑÔ\óØ(D&ñ“ )AaSË…ºùð*J¥èqÒzÅh«fÒªÈ$®„òÊ2z kZÏJUÀµSÕªÓFMªô)Fp2„ K±¿ò&±gÊS]h³Y~è¦ZTRó®Km´I žÔU¦4¶4S‘;Þã)ö@H³ï‘ feë¯Ú,Œ²XÁŒAE ܦ+£{-[&‹òÿPÊ5ßùݫ´Ïö‰´ƒ‚‘w0ÕÔ½ž´§Å 8ÄÝ^Á¨¼ÓIïOÏJœ]iŸ`3K¾² š~ÒŠ+ïõ[™ô$ õÇB ͥ컜�WõK>ÌèòkÙr1ô5—©|Ú+ÓW9LZ,E,t,ŽÖfL6˜\~AUõöj:Ãâ[‚UÚª’˼añYŒ£Zyر`Jp²0P”û4W`¨Z¢ü â´ÀfÂpM‡/Ü ‡T7‚ÎYº;«òÂ8>}•ÕxÍ!MÀç¿ó ëK×kâ's”¾’Ñ–tã‹fI ¦Ë’•ìQ¢u¯ÞÚ8,ý%s˜ã œ-Y…£|Ω§Â›c ‘¾§3¡ó ß|áÅJ†J´0+uâõ^f͸’¨²±©�YÆtiOTâtÉFÅÔóKÀäâÙütÇaübõpt•ÅnÕ`ºBX©Ç³k}!¶Óá’‘«ó“°~Ý%?pÚµ‡JQ£ÒøÅU¼Â×±=‹ªXcÙ,üÒÏ®7-ÞäJ\üú‹¯üS8A¥Ö6Ƈ2·¨JN4øeâÎÙŸc­Ô“÷N©Iß-~óÎF&EÍÂy!ç<ɯðL¸ÂÎð†;Ü ��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�015400� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image13�������������������������������������������������������������0000644�0001750�0001750�00000000755�07504443350�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a9�$�ô��ÿÿÿõöùëîóâæíØÝçÏÕáÆÍܼÅÖ³½Ñ©´Ë ¬Å—¤Àœºƒ“´z‹®qƒ©h{£aŒç^sTj—Kb’BZŒ8Q†0_À/^½/J,X±?€:v 5>���,����9�$�@þà'ŽdižhªŠæ¾p,Ïtmk\Î5À¤s Àa(p&�À#“db"Gæ‚ÀY�X ‚ÌoL.›Ïè4çÂn»ßð¸|Ng¯îøüIÍïûÍ� ‚DF ��YHN9B ^A]”“d¡¢£¤¥¦§¨©¡z¬­®¯°)³´i ˆµºjA>:PW=<‹¹HU DJ@‚[9·»ØÙÚÛcuÞßàáâãâ±æçèéêëìí#Üð:ñôd bõµ� cÈ·o  PàPa Á%@4 ÑÀƒ†N(`V¦×Y8,ª€$@‚Žsœ|öìÀ£hJ¨ùëâà̳):”åXd!�Px’O"‡2å òŒÚJh ÔÇA>ª †*@À!+C‹:¤ŠÑA r4L˯­ÛlâÊK·®Ý»xóÆ%Ç·¯ß¿€ö@¸°áÈ+^̘p�;�������������������./saods9/htmlwidget/tests/page2/image23�������������������������������������������������������������0000644�0001750�0001750�00000001033�07504443350�016566� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÌ3÷Æ3îÀ4ê½4æº4â·4ß´4Ö®5ͧ5Å¢6Àž6¸˜6¯’6«7§Œ7œ„7˜8—€8“}8‹w8‡t8zk9vh9tg9h^:d[:]V:TO;HG;GF;?@;>?;6:<27<.4<%-='=!== >>���������������������������������������������������������������������,����x� �@þ@€pH,ȤrÉl:ŸP!jŠª@PB‰¨ „Þ©€rPiú!�8#@`s*Ü `·LMQ‚ƒK(#B'#!� ( ’ d( �'� ˜p�e 'o(q’ „´µR‡¶rº„»ÁQhD'(‰]_�•cd'$"(oq¤�"o!$q¥t'˜ÂéêëìíL îõöPÄB" #|ø\ðÀP,�ˆpìÄ  �H!B� "H�5�t÷ÒÊ,ÀµYÌ–y!)EDˆ<�®}HFŠ !¾qq"CAœ(Hh@rŠì0í„®JB*0€©L$=¢Î¨"U©@€:d0瀮 ']+¨�°#Ü$ Ћ-’ �;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image29�������������������������������������������������������������0000644�0001750�0001750�00000000171�07504443351�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87at��ò��aŒçHwÙ3\Ê0_À+O¬$D™������,����t���FXºÜþ0ÊI«$ëÍ»ÿ`(Žd) hª®lë¾p,ÏtÜx®ï|ïÿÀ pȤrÉl:ŸÐ¨ô9¨Z¯Ø¬vËíz¿à°7�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image20�������������������������������������������������������������0000644�0001750�0001750�00000001025�07504443350�016564� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞâï×ÝìÐ×éÏÖéÌÔçÅÍä½Çà¹ÄßµÀݳ¾Û¯»Ú«·Ø§´Ö¡®Óœ«Ñ•¥ÎŽžÊ‚•Å’Ã{ŽÁu‰¿q†½m‚»j¹f|¸e|·^v´Wo±Tm¯Lf«E`¨D_¨A]§=Y¥9V£6S¡.Mž'G›������������������������������������������������������������,����x� �@þÀ•pH,G’Él:ŸÐ¨´)¬T �`±Ò$+ȇXŠ�¡sc˜Ê(€¸Ò·«-Lÿ€PV�#&]DCƒf� C#xD$)Š�v_ ‰§¨+�O)«­¯L_‹©¼½O ~C�ŽB*D+!®’C'{BÌË�]�w (¾àà&`á忀êêO«ëMÝç÷¨Ê˜D#<²²B„ \2€Ë3Œb ¢+* ‡ï¤ˆ#"q 4�|‹´kÅ% +@Xë"a� ]@(Ññ;¤ �@¨ø`‰O䙬âÀ�ŒB˜BE€+,�8¡HÁ€OEM¬ìÙ1ÅX"O©à:ÄT²¨‚��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image31�������������������������������������������������������������0000644�0001750�0001750�00000000116�07504443351�016567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax��ñ��PwÐ0_À/P¯���,����x���'Œ©Ëí£œ¢Ú‹³Þ¼û†"@–扦êʶî ÇÓL×öçúÎß�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image9��������������������������������������������������������������0000644�0001750�0001750�00000000754�07504443352�016525� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a8�$�ô��ÿÿÿëîóâæíØÝçÏÕáÆÍܼÅÖ³½Ñ©´Ë ¬Å—¤Àœºƒ“´z‹®qƒ©h{£aŒç^sTj—Kb’BZŒ8Q†0_À/^½/J-Y³%A{:v 5>������,����8�$�@þ 'ŽdižhªzY{½p,Ïtm×[¾€Bé À àØ À$`l�‡°ØP‚‚aS� ?B`8èÎè´zÍn³-ð¸|N¯ÛïxËjÏï›Ü€‚m ?F� ?A9B9SU‹N] h©ª«¬­®¯°±~´µ¶·¸'ƒ»¼€X]½Ã‚ •§A��ŠH�? Ì=˜^g]Ë”ËmÄãäå½yèéêëìíê¹ðñòóôõööæùúûƒÆ “øã1 C( A˜p† ByPaA³ þ:HhqZЬ™° €�GÌr€�¨Fe¢ bXV IG—3&°2£IAx4ÈQ@��[Z²ÉìâMØ$YvRÑ2aA60Ùò$Ê¥–—РJž�üȶ­>pãÊK·®Ý»x9¸ÛË·¯ß¿€ûvL¸°áÈ+^Ü!�;��������������������./saods9/htmlwidget/tests/page2/image6��������������������������������������������������������������0000644�0001750�0001750�00000000366�07504443351�016520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ô��aŒç0_À/^½,X±+V­'Ož"EŠ=z:v7o2g-]+W&L"E?< 5>���������������������������������������,�����$�@{à$Ž$) â8Œ’FA Hm#PÃ,Éíç W-@,¥äÈW˵z̦Nˆ�X¯X¬rË%ÝbŒ‡Ž•î Q'5=E3Ô£|N'vïø|+mQ Nde‡n?ƒ‰S e8c‹7j”6–‘pPžŸŸu¢£¤¦§¨¨!�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/index.html����������������������������������������������������������0000644�0001750�0001750�00000100263�07504443347�017424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title>Tcl Resource Center</title> </head> <body bgcolor="white" text="black"> <!-- MenuTopLevel Resource Software Extensions --> <table border="0" cellpadding="0" cellspacing="0"> <tr> <td width="120" valign="TOP"><a href="/"><img src="image1" width="120" height="79" alt="Scriptics" border="0"></a></td> <td valign="top" width="548"> <!-- Table to hold tabs --> <table cellpadding="0" cellspacing="0" border="0" width="548"> <tr> <td valign="top" align="right" colspan="15" width="548"><a name="TOP"><img src="image2" width="548" height="9" alt="Tcl/Tk" border="0"></a></td> </tr> <tr> <td valign="top" align="right" colspan="15" width="548"><img src="image3" width="482" height="34" alt="Scripting Solutions for eBusiness Integration" border="0"></td> </tr> <tr> <td width="18" valign="TOP"><img src="image4" width="18" height="36" alt="" border="0"></td> <td width="58"><a href="/products/" onMouseOver="msover(4, 'http://images.scriptics.com/images/ProductsMouseOff.gif') ; return true ;" onMouseOut="msover(4, 'http://images.scriptics.com/images/ProductsOff.gif') ; return true ;"><img src="image5" width="58" height="36" alt="Products" border="0"></a></td> <td width="14" valign="TOP"><img src="image6" width="14" height="36" alt="" border="0"></td> <td width="69"><a href="/customers/" onMouseOver="msover(6, 'http://images.scriptics.com/images/CustomersMouseOff.gif') ; return true ;" onMouseOut="msover(6, 'http://images.scriptics.com/images/CustomersOff.gif') ; return true ;"><img src="image7" width="69" height="36" alt="Customers" border="0"></a></td> <td width="14" valign="TOP"><img src="image6" width="14" height="36" alt="" border="0"></td> <td width="60"><a href="/partners/" onMouseOver="msover(8, 'http://images.scriptics.com/images/PartnersMouseOff.gif') ; return true ;" onMouseOut="msover(8, 'http://images.scriptics.com/images/PartnersOff.gif') ; return true ;"><img src="image8" width="60" height="36" alt="Partners" border="0"></a></td> <td width="14" valign="TOP"><img src="image6" width="14" height="36" alt="" border="0"></td> <td width="56"><a href="/services/" onMouseOver="msover(10, 'http://images.scriptics.com/images/ServicesMouseOff.gif') ; return true ;" onMouseOut="msover(10, 'http://images.scriptics.com/images/ServicesOff.gif') ; return true ;"><img src="image9" width="56" height="36" alt="Services" border="0"></a></td> <td width="14" valign="TOP"><img src="image10" width="14" height="36" alt="" border="0"></td> <td width="88"><a href="/resource/" onMouseOver="msover(12, 'http://images.scriptics.com/images/ResourceMouseOn.gif') ; return true ;" onMouseOut="msover(12, 'http://images.scriptics.com/images/ResourceOn.gif') ; return true ;"><img src="image11" width="88" height="36" alt="Tcl Resources" border="0"></a></td> <td width="14" valign="TOP"><img src="image12" width="14" height="36" alt="" border="0"></td> <td width="57"><a href="/company/" onMouseOver="msover(14, 'http://images.scriptics.com/images/CompanyMouseOff.gif') ; return true ;" onMouseOut="msover(14, 'http://images.scriptics.com/images/CompanyOff.gif') ; return true ;"><img src="image13" width="57" height="36" alt="Company" border="0"></a></td> <td width="8" valign="TOP"><img src="image14" width="8" height="36" alt="" border="0"></td> <td width="50" valign="TOP"><img src="image15" width="50" height="36" alt="" border="0"></td> <td width="14" valign="TOP"><img src="image16" width="14" height="36" alt="" border="0"></td> </tr> </table> </td> </tr> </table> <script language="Javascript"> <!-- function msover(num, file ) { old = (((navigator.appName=='Netscape') && (parseInt(navigator.appVersion)<=3.0 ))) if ( !old ) { document.images[num].src=file } } //--> </SCRIPT> <!-- MenuSubLevel Resource Software Extensions Tk --> <table cellpadding="0" cellspacing="0" border="0"> <!-- Left Hand Column--> <tr><td valign="top" width="120"><table cellpadding="0" cellspacing="0" border="0" width="120"> <tr> <td width="120" valign="TOP"><img src="image17" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/"><img src="image18" width="120" height="11" alt="Software" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image19" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/tcltk/"><img src="image20" width="120" height="11" alt="Tcl/Tk Core" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image19" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/applications/"><img src="image21" width="120" height="11" alt="Applications" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image22" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/extensions/"><img src="image23" width="120" height="11" alt="Extensions" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image24" width="120" height="6" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/patches/"><img src="image25" width="120" height="11" alt="Patches" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image19" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/java/"><img src="image26" width="120" height="11" alt="Tcl &amp; Java" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image19" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/ports/"><img src="image27" width="120" height="11" alt="Tcl/Tk Ports" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image19" width="120" height="4" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/software/tools/"><img src="image28" width="120" height="11" alt="Tools" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image29" width="120" height="6" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/doc/"><img src="image30" width="120" height="11" alt="Documentation" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image31" width="120" height="5" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/resource/community/"><img src="image32" width="120" height="11" alt="Community" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image31" width="120" height="5" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/live/bydate"><img src="image33" width="120" height="11" alt="What's New" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image31" width="120" height="5" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/forms/urlnote.html"><img src="image34" width="120" height="11" alt="Add URL" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image31" width="120" height="5" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/live/keyword"><img src="image35" width="120" height="11" alt="Keyword Search" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image31" width="120" height="5" alt="" border="0"></td> </tr> <tr> <td width="120" valign="TOP"><a href="/live/sitemap"><img src="image36" width="120" height="11" alt="Index" border="0"></a></td> </tr> <tr> <td width="120" valign="TOP"><img src="image37" width="120" height="6" alt="" border="0"></td> </tr> </table><!-- End Left Column --></td><!-- Right Hand Column --><td valign="top" width="548" align="left"><table cellpadding="0" cellspacing="0" border="0" width="548"> <tr> <td width="295" valign="TOP"><img src="image38" width="295" height="42" alt="Resource" border="0"></td> <td width="187" valign="bottom" align="right"><FORM action="/live/keyword"><img src="image39" width="46" height="24" alt="" border="0"><INPUT TYPE="TEXT" SIZE="10" MAXLENGTH="35" NAME="keywords"><INPUT type="IMAGE" border="0" img="img" src="http://images.scriptics.com/images/Go.gif" value="submit" width="33" height="24"></FORM> </tr> </table> <!-- 2 Columns for spacer --> <table cellpadding="0" cellspacing="0" border="0" width="548"> <tr> <!-- Spacer Column --> <td valign="top" width="10"> &nbsp; </td> <td valign="top" width="548"><font face="Geneva, Helvetica, Arial" size="2"><h1>Tcl Resource Center</h1> <font size="+1"><a href="/resource/">Top</a>&gt;<a href="/resource/software/" ="">Software Central</a>&gt;<a href="/resource/software/extensions/" ="">Extensions</a>&gt;Tk Widgets</font><font size="-1"><br>Viewed by name (<a href="/resource/software/extensions/tk/?sortby=date">By date</a>)</font><br> <p>Tk is a toolkit for building graphical user interfaces with Tcl. Your Tcl/Tk scripts run on UNIX, Windows, and Macintosh.<p> <font face="Geneva, Helvetica, Arial"><ul></ul></font><dl> <dt><b><a href="http://marge.phys.washington.edu/%7Ezager/blt80-unoff-exe.zip" ="">BLT 8.0 Unofficial zip and DLL</a></b> <dd>This is a compiled version of BLT 8.0 "unofficial" for the Windows platform. <a href="/live/annotate?url=http%3a%2f%2fmarge%2ephys%2ewashington%2eedu%2f%257Ezager%2fblt80%2dunoff%2dexe%2ezip">Edit</a> <i><font size="-1">(September 24, 1999 06:31)</font></i><dt><b><a href="ftp://ftp.neosoft.com/languages/tcl/sorted/unknown/blt8.0p2-unoff.tgz" ="">BLT 8.0p2 Unofficial tar file</a><a name="bltunoff"></a></b> <dd>This is a contributed patch to make BLT compatible with Tcl/Tk 8.0p2. While still "unofficial", it is widely used. Make sure you get the 8.0p2 version because the 8.0 version does not compile under windows. There is also a <a href="ftp://ftp.neosoft.com/languages/sorted/devel/blt2.3-8.1.tar.gz">2.3-8.1 version</a> that has been patched to work with 8.1. <a href="ftp://ftp.neosoft.com/languages/tcl/sorted/unknown/blt8.0p2-unoff.README">README file</a>. <a href="/live/annotate?url=ftp%3a%2f%2fftp%2eneosoft%2ecom%2flanguages%2ftcl%2fsorted%2funknown%2fblt8%2e0p2%2dunoff%2etgz">Edit</a> <i><font size="-1">(August 30, 1999 06:38)</font></i><dt><b><a href="http://www.tcltk.com/blt/" ="">BLT Home Page</a></b> <dd> Author <b>George Howlett</b>, Version <b>2.3</b>, Works with <b>Tk 4.1 through Tk 8.1</b> <br><a href="ftp://ftp.tcltk.com/pub/blt/">Download</a>, <a href="ftp://ftp.tcltk.com/pub/blt/BLT2.3.tar.gz">BLT2.3.tar.gz</a>, <a href="ftp://ftp.tcltk.com/pub/blt/BLT2.4h.tar.gz">BLT2.4h.tar.gz</a>, <a href="ftp://ftp.tcltk.com/pub/blt/BLT2.4i.tar.gz">BLT2.4i.tar.gz</a>, <a href="ftp://ftp.tcltk.com/pub/blt/blt2.4i-for-8.0.exe">blt2.4i-for-8.0.exe</a>, <a href="ftp://ftp.tcltk.com/pub/blt/blt2.4i-for-8.1.exe">blt2.4i-for-8.1.exe</a><br>BLT is a set of widgets for Tk, including a graph widget, bar chart, drag&drop, a simple command tracer, and much more. The 2.4 release, which is still under development, works with 8.0 or higher. There are also an "<a href="#bltunoff">unofficial</a>" release for 8.0p2 and 8.1a2 that were not done by the author. <a href="/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fblt%2f">Edit</a> <i><font size="-1">(October 26, 1999 09:43)</font></i><dt><b><a href="http://www.unifix-online.com/BWidget/index.html" ="">BWidget</a></b> <dd>A set of native Tk 8.x Widgets using Tcl8.x namespaces. The ToolKit is available under Unix/X11 and Windows. The BWidget(s) have a professional look&feel as in other well known Toolkits (Tix or Incr Widget) but the concept is radically different because everything is native so no platform compilation, no compiled extension library are needed. The code is 100 Pure Tcl/Tk. More 30 components : Notebook, PageManager, Tree, PanedWindow, ButtonBox, ScrollView, ComboBox, SpinBox, ListBox, SelectFont, SelectColor, ProgressBare ... <a href="/live/annotate?url=http%3a%2f%2fwww%2eunifix%2donline%2ecom%2fBWidget%2findex%2ehtml">Edit</a> <i><font size="-1">(September 06, 1999 09:58)</font></i><dt><b><a href="http://purl.oclc.org/net/nijtmans/dash.html" ="">Dash Patch for Tk</a></b> <dd>This patch has many enhancements to the Tk and its canvas widget, including dashed lines, smoothed polygons, and performance enhancements. <a href="/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2fnijtmans%2fdash%2ehtml">Edit</a> <i><font size="-1">(November 21, 1999 06:33)</font></i><dt><b><a href="http://www.hwaci.com/sw/et" ="">Embedded Tk (et)</a></b> <dd> Author <b><a href="mailto:drh@acm.org" ="">Richard Hipp</a></b>, Version <b>8.0b5</b>, Works with <b>Tk 4.0, 4.1, 4.2, 8.0</b> <br>Download: <a href="http://www.hwaci.com/sw/et/et80b5.tar.gz">et80b5.tar.gz</a><br>Embedded Tk or ``ET'' is tool for making stand-alone executables out of a mixture of C or C++ and Tcl/Tk. Using ET you can invoke a short Tcl/Tk script in the middle of a C routine, or you can invoke a C routine in the middle of a Tcl/Tk script. ET also bundles external Tcl/Tk scripts (including the standard Tcl/Tk startup scripts) into the executable so that the executable can be run on another binary-compatible computer that doesn't have Tcl/Tk installed. <a href="/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2fet">Edit</a> <i><font size="-1">(August 19, 1999 15:35)</font></i><dt><b><a href="http://www.purl.org/net/hobbs/tcl/script/tkcon/" ="">Enhanced Tk Console (TkCon)</a></b> <dd> Author <b><a href="mailto:jeffrey.hobbs@oen.siemens.de" ="">Jeff Hobbs</a></b>, Version <b>1.3</b>, Works with <b>Tk 4.1 through Tk 8.1</b> <br>Download: <a href="http://www.purl.org/net/hobbs/tcl/script/tkcon/tkcon.tar.gz">tkcon.tar.gz</a><br>TkCon is a replacement for the standard console that comes with Tk (on Windows/Mac, but also works on Unix). The console itself provides many more features than the standard console. <a href="/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fscript%2ftkcon%2f">Edit</a> <i><font size="-1">(August 23, 1999 12:06)</font></i><dt><b><a href="http://www.scriptmeridian.org/projects/tk/" ="">Frontier-Tk ScriptMeridian project</a></b> <dd>This project seeks to integrate the Tk toolkit with the Frontier scripting language. <a href="/live/annotate?url=http%3a%2f%2fwww%2escriptmeridian%2eorg%2fprojects%2ftk%2f">Edit</a> <i><font size="-1">(August 19, 1999 15:36)</font></i><dt><b><a href="http://purl.oclc.org/net/nijtmans/img.html" ="">Img image format extension</a></b> <dd>This package enhances Tk, adding support for many other Image formats: BMP, XBM, XPM, GIF (with transparency), PNG, JPEG, TIFF and postscript. This is implemented as a shared library that can be dynamically loaded into Tcl/Tk. <a href="/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2fnijtmans%2fimg%2ehtml">Edit</a> <i><font size="-1">(November 21, 1999 06:35)</font></i><dt><b><a href="http://purl.oclc.org/net/oakley/tcl/mclistbox/index.html" ="">mclistbox - a multi-column listbox widget</a></b> <dd>mclistbox is a multi-column listbox that is written in pure tcl and runs on all platforms that support tcl/tk 8.0 or higher. This widget requires no other extensions; it is completely standalone. <a href="/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2foakley%2ftcl%2fmclistbox%2findex%2ehtml">Edit</a> <i><font size="-1">(August 19, 1999 15:37)</font></i><dt><b><a href="http://home.t-online.de/home/dshepherd/tkview.htm" ="">MFC views C++ class for embedding Tk</a></b> <dd>The idea of embedding Tk in MFC windows always seemed very enticing but information was sparse and contradictory - on a scale between "very easy" and "not yet possible". The only thing for it was to have a go and lo, it wasn't that hard after all. CTkView is a C++ class which can be used in MFC SDI or MDI applications. An instance of CTkView hosts an embedded Tk toplevel widget and performs some management chores for the widget so that it can size, update and react correctly to Windows events. <a href="/live/annotate?url=http%3a%2f%2fhome%2et%2donline%2ede%2fhome%2fdshepherd%2ftkview%2ehtm">Edit</a> <i><font size="-1">(August 19, 1999 15:38)</font></i><dt><b><a href="http://www.cs.umd.edu/hcil/pad++" ="">Pad++</a></b> <dd> Author <b><a href="mailto:pad-info@cs.umd.edu" ="">Ben Bederson et al</a></b>, Version <b>0.9p1</b>, Works with <b>8.0</b> <br>Download: <a href="http://www.cs.umd.edu/hcil/pad++/download.html">download.html</a><br>Pad++ is a Tk widget that provides a Zoomable User Interface (ZUI) that supports real-time interactive zoomable graphics in a fashion similar to the Tk Canvas widget. Pad++ supports tens of thousands of objects which include text, images, graphics, portals, lenses, simple html (and more), including transparency and rotation. <a href="/live/annotate?url=http%3a%2f%2fwww%2ecs%2eumd%2eedu%2fhcil%2fpad%2b%2b">Edit</a> <i><font size="-1">(August 19, 1999 15:39)</font></i><dt><b><a href="http://home.t-online.de/home/sesam.com/freeware.htm" ="">Progressbar</a></b> <dd>Progressbar is a megawidget written in pure tcl (ie: no compiling required - runs on all platforms Macintosh, Unix, Windows). Its primary purpose is to show the progress of any action in percent. <a href="/live/annotate?url=http%3a%2f%2fhome%2et%2donline%2ede%2fhome%2fsesam%2ecom%2ffreeware%2ehtm">Edit</a> <i><font size="-1">(January 24, 2000 09:19)</font></i><dt><b><a href="http://jfontain.free.fr/" ="">scwoop (Simple Composite Widget Object Oriented Package)</a></b> <dd>Scwoop is a composite widget (also known as mega widget) extension to the great Tk widget library. Scwoop is entirely written in Tcl using the stooop (Simple Tcl Only Object Oriented Programming) extension. <a href="/live/annotate?url=http%3a%2f%2fjfontain%2efree%2efr%2f">Edit</a> <i><font size="-1">(January 09, 2000 02:10)</font></i><dt><b><a href="http://www2.clearlight.com/~oakley/tcl/supertext.html" ="">Supertext - tk text widget with unlimited undo</a></b> <dd> Author <b><a href="mailto:oakley@channelpoint.com" ="">Bryan Oakley</a></b>, Version <b>1.0b1</b>, Works with <b>Tcl 8.0</b> <br>Download: <a href="http://www2.clearlight.com/~oakley/tcl/supertext.tcl">supertext.tcl</a><br>Supertext is a package that provides a tk text widget with full undo and the ability to execute procedures both before and after a text widget command has been processed. Supertext may be used as-is, or for the brave it may be used in place of the standard text widget. <a href="/live/annotate?url=http%3a%2f%2fwww2%2eclearlight%2ecom%2f%7eoakley%2ftcl%2fsupertext%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:06)</font></i><dt><b><a href="http://www.hwaci.com/sw/tk/nbpi.html" ="">Tabbed Notebook Widget</a></b> <dd> Author <b><a href="mailto:drh@acm.org" ="">Richard Hipp</a></b>, Version <b>1.0</b>, Works with <b>Tk 4.1 or later.</b> <br>Download: <a href="http://www.hwaci.com/sw/tk/notebook.tcl">notebook.tcl</a><br>This implements a tabbed notebook using a canvas widget and embedded frames. This is pure Tcl code - not a C extension. <a href="/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2ftk%2fnbpi%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:08)</font></i><dt><b><a href="http://www.tcltk.com/ellson/ftp/Gdtclft2.0.README" ="">Tcl GD - graphics</a></b> <dd> Author <b>John Ellson and Spencer Thomas</b>, Version <b>2.0</b>, Works with <b>8.0 and higher</b> <br>Download: <a href="http://www.tcltk.com/ellson/ftp/Gdtclft2.0.tar.gz">Gdtclft2.0.tar.gz</a><br> Thomas Boutell's Gd package provides a convenient way to generate PNG images with a C program. If you prefer Tcl for CGI applications, you'll want the TCL GD extension. <a href="/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fellson%2fftp%2fGdtclft2%2e0%2eREADME">Edit</a> <i><font size="-1">(August 19, 1999 14:52)</font></i><dt><b><a href="http://www.stratasys.com/software/metagui" ="">The Meta-GUI Tools</a></b> <dd>The Meta-GUI tools provide a framework for quickly building full GUI applications. The GUI is rendered by a run-time engine based on a hierarchical set of definitions you provide. At the bottom of the hierarchy are abstract data types such as length, angle, string, etc., and these are used to progressively build up frames, dialogs, toolbars, menus, and operations. <a href="/live/annotate?url=http%3a%2f%2fwww%2estratasys%2ecom%2fsoftware%2fmetagui">Edit</a> <i><font size="-1">(August 23, 1999 12:10)</font></i><dt><b><a href="http://jfontain.free.fr/" ="">Tkpiechart Home Page</a></b> <dd>Tkpiechart is a Tcl-only extension that allows the programmer to create and dynamically update 2D or 3D pie charts in a Tcl/Tk application. This uses the stooop package and builds pie charts on a Tk canvas. <a href="/live/annotate?url=http%3a%2f%2fjfontain%2efree%2efr%2f">Edit</a> <i><font size="-1">(January 09, 2000 02:12)</font></i><dt><b><a href="http://www.cygnus.com/~irox/tkprint/" ="">TkPrint</a></b> <dd>TkPrint is an extension that allows you to print from a Tk widget. <a href="/live/annotate?url=http%3a%2f%2fwww%2ecygnus%2ecom%2f%7eirox%2ftkprint%2f">Edit</a> <i><font size="-1">(October 11, 1999 09:58)</font></i><dt><b><a href="http://www.purl.org/net/hobbs/tcl/capp/" ="">TkTable Home Page</a></b> <dd>The TkTable widget. The <code>table</code> command creates a 2-dimensional grid of cells. The table can use a Tcl array variable or Tcl command for data storage and retrieval. <a href="/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fcapp%2f">Edit</a> <i><font size="-1">(November 18, 1999 09:25)</font></i><dt><b><a href="http://ftp.austintx.net/users/jatucker/TkTextmatrix/default.htm" ="">TkTextMatrix (spreadsheet)</a></b> <dd> Author <b><a href="mailto:jatucker@austin.dsccc.com" ="">John Arthur Tucker</a></b>, Version <b>4.1</b>, Works with <b>Tk 4.1</b> <br>Download: <a href="http://ftp.austintx.net/users/jatucker/TkTextmatrix/download.htm">download.htm</a>, <a href="http://ftp.austintx.net/users/jatucker/TkTextmatrix/textmatrix4.1.tar.gz">textmatrix4.1.tar.gz</a><br>A Tcl/Tk spreadsheet widget, TkTextmatrix, which is implemented in C++ and is basically a Tk Canvas widget plus extra behavior for manipulating rows and columns of cell items many times faster than with a plain Tk Canvas. It actually inserts text nearly as fast as the Tk Text widget. If you work with or are interested in creating your own Tcl/Tk widgets in C++, you might want to take a look at the C++ widget library included with this distribution. <a href="/live/annotate?url=http%3a%2f%2fftp%2eaustintx%2enet%2fusers%2fjatucker%2fTkTextmatrix%2fdefault%2ehtm">Edit</a> <i><font size="-1">(August 23, 1999 12:14)</font></i><dt><b><a href="http://www.cs.umd.edu/~bederson/Togl.html" ="">ToGL - a Tk Open GL widget</a></b> <dd>Togl is a Tk widget for OpenGL rendering. Togl is based on OGLTK, originally written by Benjamin Bederson at the University of New Mexico (who has since moved to the University of Maryland). Togl adds the new features: <ul> <li> color-index mode support including color allocation functions <li> support for requesting stencil, accumulation, alpha buffers, etc <li> multiple OpenGL drawing widgets <li> OpenGL extension testing from Tcl <li> simple, portable font support <li> overlay plane support </ul> Togl allows one to create and manage a special Tk/OpenGL widget with Tcl and render into it with a C program. That is, a typical Togl program will have Tcl code for managing the user interface and a C program for computations and OpenGL rendering. <a href="/live/annotate?url=http%3a%2f%2fwww%2ecs%2eumd%2eedu%2f%7ebederson%2fTogl%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:14)</font></i><dt><b><a href="http://www.hwaci.com/sw/tk/treepi.html" ="">Tree Widget</a></b> <dd>This implements a tree display in a canvas widget. It is similar in layout to that of the Windows explorer file viewer. This is pure Tcl code - not a C extension. <a href="/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2ftk%2ftreepi%2ehtml">Edit</a> <i><font size="-1">(September 29, 1999 14:37)</font></i><dt><b><a href="http://www.du.edu/~mschwart/tcl-tk.htm" ="">Windows Extensions for Tcl/Tk (Michael Schwartz)</a></b> <dd>This site has pointers to several extensions specific to the Windows platform. The extensions provide printing, a MAPI interface to send email, and an interface to manipulate .INI files, among other things. <a href="/live/annotate?url=http%3a%2f%2fwww%2edu%2eedu%2f%7emschwart%2ftcl%2dtk%2ehtm">Edit</a> <i><font size="-1">(October 07, 1999 10:50)</font></i><dt><b><a href="http://www.tcltk.com/iwidgets/" ="">[incr Widgets] Home Page</a></b> <dd>[incr Widgets] is a set of megawidgets (combo boxes, etc.) that are upon the [incr Tcl] object system and the [incr Tk] megawidget framework. This comes bundled with the <a href="http://www.tcltk.com/itcl/">[incr Tcl]</a> distributions. <a href="/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fiwidgets%2f">Edit</a> <i><font size="-1">(September 05, 1999 16:08)</font></i><dt><b><a href="http://www1.clearlight.com/~oakley/tcl/combobox/index.html" ="">combobox</a></b> <dd> Author <b><a href="mailto:oakley@channelpoint.com" ="">Bryan Oakley</a></b>, Version <b>1.03</b>, Works with <b>8.x</b> <br>Download: <a href="http://www1.clearlight.com/~oakley/tcl/combobox/combobox.tcl">combobox.tcl</a><br>combobox is a pure-tcl implementation of a combobox widget. It is entirely self contained and does not require any other OO or megawidget extension. It supports both editable and non-editable entries, and provides the ability to call a procedure anytime the value of the combobox changes. <a href="/live/annotate?url=http%3a%2f%2fwww1%2eclearlight%2ecom%2f%7eoakley%2ftcl%2fcombobox%2findex%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:15)</font></i><dt><b><a href="http://www.multimania.com/droche/rnotebook/index.html" ="">Rnotebook</a></b> <dd> Author <b><a href="mailto:dan@lectra.com" ="">Daniel Roche</a></b>, Version <b>1.0</b>, Works with <b>8.0 or higher</b> <br>Download: <a href="http://www.multimania.com/droche/rnotebook/index.html">index.html</a><br>This implements a resizeable notebook widget in pure tcl/tk <a href="/live/annotate?url=http%3a%2f%2fwww%2emultimania%2ecom%2fdroche%2frnotebook%2findex%2ehtml">Edit</a> <i><font size="-1">(August 19, 1999 15:39)</font></i><dt><b><a href="http://www.tregar.com/samdi.html" ="">saMDI v1.0a1 Multi-Document Interface Extension</a></b> <dd>A multi-document interface (MDI) extension for TCL/Tk 8.0. This is a common interface format in Microsoft Windows that lets a parent window contain multiple child windows. In effect you get a window manager inside a window! Uses and includes the STOOOP object-oriented extension by Jean-Luc Fontaine. saMDI v1.0a1 GPL Copyright 1998 Sam Tregar. <a href="/live/annotate?url=http%3a%2f%2fwww%2etregar%2ecom%2fsamdi%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:07)</font></i><dt><b><a href="http://tix.mne.com/htdocs/tix/index.html" ="">Tix Support Site</a></b> <dd> Author <b><a href="mailto:tix@mne.com" ="">Ioi Lam, (adopted by Gregg Squires)</a></b>, Version <b>4.1</b>, Works with <b>Tcl 7.4 through Tcl 8.0</b> <br><a href="ftp://ftp.tix.mne.com/pub/tix/">Download</a>, <a href="ftp://ftp.tix.mne.com/pub/tix/Tix4.1.0.006.tar.gz">Tix4.1.0.006.tar.gz</a>, <a href="ftp://ftp.tix.mne.com/pub/tix/Tix41p6.zip">Tix41p6.zip</a>, <a href="ftp://ftp.tix.mne.com/pub/tix/win41p6bin.zip">win41p6bin.zip</a><br><b>Tix has found a new home!</b> <br> Tix provides over 40 new Tk including the combo box, file selection dialogs, paned widget, notebook, hierarchical list, directory tree, and more. <a href="/live/annotate?url=http%3a%2f%2ftix%2emne%2ecom%2fhtdocs%2ftix%2findex%2ehtml">Edit</a> <i><font size="-1">(August 23, 1999 12:11)</font></i><dt><b><a href="ftp://ftp.archive.eso.org/pub/tree" ="">Tk Tree Widget (C++)</a></b> <dd>Tk Tree widget for Tcl8.0.3. This version contains (optional) support for \[incr Tcl\] and \[incr Tk\] version 3.0. <br> With the tree widget, you can display a tree in a Tk canvas. The nodes can be made up of any number of canvas items or even other Tk widgets. You create the objects that make up a node and the line that connects it to its parent and pass them to the tree widget. After this the tree widget manages the positions of the nodes and end points of the tree lines. Operations are available for inserting, moving and removing nodes and subtrees and for querrying the position of a node in the tree. The tree can be displayed horizontally or vertically. <a href="/live/annotate?url=ftp%3a%2f%2fftp%2earchive%2eeso%2eorg%2fpub%2ftree">Edit</a> <i><font size="-1">(August 25, 1999 03:14)</font></i><dt><b><a href="http://www.purl.org/net/hobbs/tcl/script/widget/" ="">widget, simple megawidget package</a></b> <dd> Author <b><a href="mailto:jeffrey.hobbs@oen.siemens.de" ="">Jeffrey Hobbs</a></b>, Version <b>0.9</b>, Works with <b>Tcl/Tk 8.0 or higher</b> <br>Download: <a href="http://www.purl.org/net/hobbs/tcl/script/widget/widget-0.9.tar.gz">widget-0.9.tar.gz</a><br>This is a package of megawidgets (i.e., compound widgets) that work almost exactly like Tk widgets. You can also build your own new megawidgets. Includes: combobox, hierarchy, console, progressbar, tabnotebook, validating entry, pane geometry manager, baloon help. <a href="/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fscript%2fwidget%2f">Edit</a> <i><font size="-1">(August 23, 1999 12:16)</font></i></dl> <hr><p><center><font size="-1" face="Geneva, Helvetica, Arial"><br><a href="#TOP"><b>Top</b></a><br><!-- key ResourceSoftwareExtensions --><a href="/">Home</a> | <a href="/products/">Products</a> | <a href="/customers/">Customers</a> | <a href="/partners/">Partners</a> | <a href="/services/">Services</a> | <a href="/resource/">Tcl Resources</a> | <a href="/company/">Company</a> <br><a href="/live/keyword">Search</a> | <a href="/live/map">Site Map</a> | <a href="/company/feedback.html?url=%2fresource%2fsoftware%2fextensions%2ftk%2f">Feedback</a> | <a href="/company/contact.html">Contact Us</a> | <a href="mailto:info@scriptics.com">info@scriptics.com</a> <SCRIPT LANGUAGE="Javascript"> <!-- browser = (((navigator.appName == "Netscape") &&(parseInt(navigator.appVersion) >= 3 )) || ((navigator.appName =="Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4 ))) if ( browser ) { over = new MakeImageArray(10) over[0].src = "http://images.scriptics.com/images/ProductsMouseOff.gif" over[1].src = "http://images.scriptics.com/images/CustomersMouseOff.gif" over[2].src = "http://images.scriptics.com/images/PartnersMouseOff.gif" over[3].src = "http://images.scriptics.com/images/ServicesMouseOff.gif" over[4].src = "http://images.scriptics.com/images/ResourceMouseOff.gif" over[5].src = "http://images.scriptics.com/images/CompanyMouseOff.gif" over[6].src = "http://images.scriptics.com/images/homeMainRollover1.gif" over[7].src = "http://images.scriptics.com/images/homeMainRollover2.gif" over[8].src = "http://images.scriptics.com/images/homeMainRollover3.gif" over[9].src = "http://images.scriptics.com/images/homeMainRollover3.gif" } function MakeImageArray(n) { this.length = n for (var i = 0; i<=n; i++)="i++)" {="{" this[i]="this[i]" ="" new="new" Image()="Image()" }="}" return="return" this="this" }="}" //="//" --="--"> </SCRIPT><br> <font size="2"> &copy; 1998-2000 Scriptics Corporation. All rights reserved. <a href="/legal_notice.html">Legal Notice</a> | <A href="" /privacy.html="/privacy.html"> Privacy Statement</a> </td></tr></table></td></tr></table> </Body> </Html>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image32�������������������������������������������������������������0000644�0001750�0001750�00000001054�07504443351�016572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùçíøãê÷àçößçõÕÞòË×ïÇÔîÁÏì½Ìë´Åè¯Âç¬¿æ¦ºä¢·ãŸµâ˜¯à—¯ß‰¤ÛƒŸÙœØ|š×y—Öu”ÕhŠÑgŠÑd‡Ða…ÏYÍU|ËNvÉHqÇDoÆ>jÄ:gÃ6dÂ0_À������������������������������������������������������������������������,����x� �@þÀ“p(1��†‰Èl:ŸÐ¨tJ­ZMšÇC#Ì>8Â΄$>‰ÉãòÙdq<>áÉI4é˜'¢®|ˆÙ[ÿ€R �!C �B'#�� ‘“• '�'�r�'& �C¥³´C�«B!ƒ%BŸ'G{ Å'›Ã¨'¦¡©žH�G&$µÞV�B&Ž «�'’� ë�íïñÊfÍ�ŽÑ¨ª'Zô­ Áƒ&,a`€† –(œHÑÛD �a€!H”¸;-‰‰‘Ê8y…*� ©H|ä!„£�\¨ˆðR!žöpuH�È*z4©¬e+¥IXt*•ä�øÉÓ ‰# aB�\:‚ôá�6�ÖnukÂ(ƒq¥p� V!» L˜b�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image15�������������������������������������������������������������0000644�0001750�0001750�00000000104�07504443350�016565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a �$�ñ��aŒç0_À>,���� �$��œ©Ëí£œ´Ú‹³ÞøâH–扦j)´î[��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image30�������������������������������������������������������������0000644�0001750�0001750�00000001227�07504443351�016572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùçíøãê÷àçößçõÕÞòÎÙðË×ïÇÔî½Ìë¶Çé¯Âç¬¿æ¦ºä¡¶âŸµâ˜¯à”¬Þ§ÜƒŸÙ|š×x—Öu”ÕnÓgŠÑd‡Ða…Ï]‚ÎYÍV|ÌOwÉHqÇAlÅ>jÄ:gÃ6dÂ0_À������������������������������������������������������������������������,����x� �@þÀ“pxòŽŒqÉl:ŸÐ¨tJ­Š&ØŒiè‰8.ÛSHÒ¨˜LÇ$äLHî“›tÁNØ—‹|"f&E!'&'BWB]_[W"&zU–K�€'�'B � £%C ž™z#� ' •©��B �B%��¾À'™€ ¢¤ ³—ÔÉš'�'%� ƒ'ß#©Ö•�z£€ �ñ´�™™ñ�¡Ù Öú”qónP&´¦U³$°€ 'x:‘�À¤PÃî¬ ß(4@k¢iâõ:ñKˆ}Y"(QHÅ™<� p¡½ÏŸ@ƒ ­–‰…Ä91"ÌЧP/);àÀ‰�2xpÀDJ !¡[%$ßЀo <÷Hx€×aPƒo#äÒ !«V®&òqÕ‰@�pšöËÃK"c;‚� ç¡j-ˆpóº•-O\� a�ã™×xÃG9VÏÂC2 xK?ŒÛ@ààÀ� v²±@Š.Vð¤iHhb'h`"�<‘bh·µYë€A5ìÂNa‡ÿn)�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image34�������������������������������������������������������������0000644�0001750�0001750�00000000760�07504443351�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùçìøãê÷ÜäôÕÞòÎÙðË×ïÇÔî¾Íë¶Çé¯Âç¬¿æ¦ºä¢·ã›²á˜¯à”¬Þ§Ü†¢ÚƒŸÙ{™×y—Öu”ÕnÓgŠÑd‡Ð`„Ï]‚ÎRyÊNvÉHqÇAlÅ>jÄ:gÃ6dÂ0_À���������������������������������������������������������������������������,����x� �@þ@“p8t,Ĥ’È()©@5P„Í¥vËíz¿Z‘D3œTB $ä¤-#%çÁ¨ÄM’Œi¤6]Ò`ƒ„…`% #� &�‚x� ‹C �B�&�¡�Bš†§¨©B� �q� $”�I¦”Ÿ� &�&»ªÆÇZ � �%” �Dš&ÎR¾"�%Ä›ÈèéêëìíC%­§»½�æîýƒ 2�ÀàhY� (ep�iÛ¹z tp¦§˜¿‹KX( «D4~Ø�Pà“'P 4IᇱeÕL|@øÈ@>2 âÀ[� ”óe�$š¨ pÉ´©ÓvA��;����������������./saods9/htmlwidget/tests/page2/image19�������������������������������������������������������������0000644�0001750�0001750�00000000065�07504443350�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax��ð��$D™���,����x���„©Ëí£œ´Ú‹³Þ¼û†âT��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image17�������������������������������������������������������������0000644�0001750�0001750�00000000121�07504443350�016566� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax��ñ��$D™!8–/{&d,����x���*œ©Ëí£œ¢Ú‹³Þ¼û†b@–扦êʶî ÇÀL×öçúÎ÷þ,��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image10�������������������������������������������������������������0000644�0001750�0001750�00000000377�07504443350�016574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ô��aŒçM{ÒJwÒDnÅ0_À/^½+V­'Ož&QŸ"EŠ=z:v7o2f-[+W&L"E 5>������������������������������������,�����$�@„ %Ž$YœÆ‘(Ì1È,4Ó<@ì<½ØŽoH,îJÈ‘áÀ!�…áò&$®X1Éí’–MÈ  Ýqñ\•ÖAÝúÝ”ïø»wÏï{§8cd€ dn?Te=5av T’fo8—†›SqEŸm<¥¥Žy«¬¬¯°±±!�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image25�������������������������������������������������������������0000644�0001750�0001750�00000000705�07504443350�016575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞâïÚßîÐ×éÏÖéÈÐåÅÍä¹Äß¶Áݯ»Ú«·Ø¡®Ó˜§Ï•¥ÎŽžÊ’Ã|Âp…½m‚»j¹f|¸by¶^v´Wo±Sl¯Lf«A]§=Y¥9V£6S¡.Mž'G›���������������������������������������������������������������������������������,����x� �@ê@’pH,ȤrÉl:ŸP!À!&$@Cº /@`³X…,`íø ÖˆPtN¯#Œð$!�$ $egi�rf#v™šP�›E# ¢¦§Fx ˜WRXZC jB ¸^¨ÂÃÄÅÆsÉrÇÍÎIS$�·$Ú  zTfÛ´aÏìGkkX�‹]½µiZ TH��K»ƒC¢ i `A�˜�ôQiÄFfШ¹ð“‹�" e•"Hj �;�����������������������������������������������������������./saods9/htmlwidget/tests/page2/image36�������������������������������������������������������������0000644�0001750�0001750�00000000624�07504443351�016600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùçíøãê÷ÜäôÒÜñÎÙðÇÔî½Ìë¯Âç¬¿æ¦ºä¢·ãž´â˜¯à—¯ß§Ü…¡ÚƒŸÙœØ{™×u”ÕkÒd‡Ð`„Ï]‚ÎOwÉHqÇDoÆ>jÄ:gÃ3bÁ0_À���������������������������������������������������������������������������������������,����x� �@¹@‘p(Ú$ĤrÉl:ŸÐ¨t:ì@2¢ DdÅj!”ð Á€"‘P(" Qßðx\ØB‚H]p>� |� [B�~r‹ŒItv�"{}�“ƒ‰"�zŽ£¤Sƒ‰‘„ƒC n¥¸¹º»¼¼§½ÀÁR§}€‘ Ÿƒ"²·ÂÖ¦•�«” ƒàc‰×çÃÙ" Ùá “ �’èú»ÕûþBA�;������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image4��������������������������������������������������������������0000644�0001750�0001750�00000000414�07504443351�016510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ô��ÿÿÿááᣣ£yyyaŒçLLL8880_À/^½,X±&K™"""?€:v*U @ 5>������������������������������������������,�����$�@‘ Žc …±H,0°p ?’È8Òì<.ë¼ÝaH,‰%Ÿ¯ d5Œ`“ ®Ø¬K«¦è5 ÂJBm } E°Q®ö¦ö]}Þ8úÿ€G]"_*>$e„Š‹Œoe‰ejqdJkm ŽJ6suzx|{¢¦©MytªRS ³´¶·¸»¼½¾¼!�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image14�������������������������������������������������������������0000644�0001750�0001750�00000000303�07504443350�016565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ô��aŒç0_À/^½,X±&K™%I•!C‰?€:v4j"C?<6 > ������������������������������������������,�����$��H`$Ždižhª¦Â@ Œ#"‡A !<b GwH4†=’§\6‘Ïa4¹„U§Ì«Ö¹…^à0@.“è´zÍn»ßé‡|.�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image22�������������������������������������������������������������0000644�0001750�0001750�00000000121�07504443350�016562� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax��ñ��ÿÌ3PwÐ0_À$D™,����x���*œ©Ëí£œ¢Ú‹³Þ¼û†b@–扦êʶî ÇÀL×öçúÎ÷þ,��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image33�������������������������������������������������������������0000644�0001750�0001750�00000001126�07504443351�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùãê÷ßçõÖßòÏÚðË×ïÇÔîÀÏì½Ìë¶Çé¯Âç¦ºä¢·ãž´â˜¯à—¯ß‰¤Û…¡ÚƒŸÙœØ|š×y—Öu”ÕnÓgŠÑd‡Ða…Ï]‚ÎV|ÌOwÉHqÇDoÆ>jÄ:gÃ6dÂ0_À���������������������������������������������������������������������������,����x� �@þ@“phrB¦acz@ĨtˆL‡BHx\¿à°x®D™4ù˜&QD#¼HLŸsTaHDDlnl&ˆt&$lLd‘’c ���  B  &%�Q �nCž ¨�V&�¼“ÇÈC¼Ë� $Ξ&£&#�%&�ÝÝÐV Ý€Bž°ÜºÞ�ÐE�HÉö‘ÝØÎ&žÔFeòVè«(ÛLlxîˆ��ÖAi@‚o÷2jÜȱ£G!Å A¼c`�²*CB˜£Õ­PÄ0É8á“��&H b|!›(x0qÁÍŦ±|…s]†" 1p�„1;f*€`€ü}M�`ˆ* l3ØŠˆ�˜(ö¦�ëXË„`��eÕX¢ÀqwvV3QÀ�ˆe ˆ$²À�Vîlðr—Þ;% r˜�`ËàÓ¨Sg �;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image26�������������������������������������������������������������0000644�0001750�0001750�00000001010�07504443350�016564� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞãðÞâïÚßî×ÝìÏÖéËÓçÅÍä½Çà¹Äß¶Áݯ»Ú§´Ö¡®Ó«Ñ˜§Ï•¥ÎŽžÊ‡˜Ç‚•Å|Âu‰¿q†½l‚»j¹f|¸e|·^v´Wo±Lf«A]§=Y¥9V£6S¡.Mž'G›���������������������������������������������������������������������,����x� �@þ@”pH,ȤrÉl:ŸÐa€:5�� ˆ)ŠØnF�Ê‚5|ˆd�´˜P€È° B�Qƒ„IT�"#[E'�BX j�! wB B U�( (…±²i²K¡¹¼½†T D�~D ‡%[y™T€C»}�Ñ � 'r^¾á⃔ãç…ëëèBîòP‡B�Fb(hð(Ã"àˆB¡áÀ›q8PBÄbóÆÕs0`F!š±Úr ¦:(>�ð M”�`ÄD ðRŠædÔHE.ˆÊP‘ø„F�¶h˜âŒÄe „ @KÀ.(`§<PÃa{ä•W�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image2��������������������������������������������������������������0000644�0001750�0001750�00000000061�07504443350�016503� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a � �ð��ÿÿÿ���!ù����,���� � ��„©Ëía�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image1��������������������������������������������������������������0000644�0001750�0001750�00000003656�07504443350�016517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ay�O�ö������9!!!))))9µ11119µ1Bµ1ZÆ1cÆ9999Bµ9B½9cÆBBBBB½BJ½JJJJJ½JR½RRRRR½RZÆZZZZZÆZcÆcccccÆckÆckÎcŒçkkkkkÎksÎsssssÎs{Î{sÎ{{{{{Î{„Ö„{Ö„„„„„Ö„ŒÖŒ„ÖŒŒŒŒŒÖŒ”Ö”ŒÖ”””””œ””Ö”œÞœ”ÞœœœœœÞœ¥Þ¥œÞ¥¥¥¥¥Þ­¥Þ­­­­­ç­µµ­µçµ­çµµµµµçµ½ç½µç½½½½½Æ½½ç½ÆïÆÆÆÆÆÎÆÆïÆÎïÎÆïÎÎÎÎÎïÎÖïÖÎïÖÖÖÖÖÞÖÖïÞÞÞÞÞçÞÞ÷Þç÷çççççïçç÷ïç÷ïïïïï÷÷÷ÿÿÿÿ������������������������������������������������������������������������������,����y�O��þ€e‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿À¡]P@7'Ê&2;GY¯d´TD.#*.20.*'&&#7L\ÁœGç&7;?94*.ÐLP¬@¡ÂäÈXPÞ%*,Ѐ% |8ò®&'pèè0Ò*²Œ¡RìÃ$#¹áàGIHBŒà2Š60Áô„Í›Œ¸8˜pC ”#70L¦É•QÔXý8°A†#@H80ñÁ‚‡;ÜY"ÔÐÇþ2¸P€ÁE7<8 ÁÁ‚(Kä‹$m19ˆCm–¥#žÑøà@&2(ž0ÁEº8##qÑ QPÁ„7& ô…ŠŠ,lØ;FGEe e‡¢ &4Cá¡‚ムNà71 ÝÈÊìEL,8ºok&cqéA‹ „1ô¥‰ÕÄ?À4³CìR ~%` îPq?ؘ·zY0ÁƒW‰•ÁÅ ¬´ &˜ì ÛP™àœ;¨ÐÏ EX¥MF?¨Ñ_*`0‹© ÞsW©Xˆ UdD<÷T"&þçã!`xâ%Yl`ÂGü€±$“œ`%3e0‚== ôt® 'Ê ˜ð¤#YÌ ›k4¸ðA XÐã–Š¼Ð iqñÅCŽA(ĸЙYä|°g�Áç#GÈÐ```AHá`„€¾9é#\P!Ä &ÆæÀ«œ‘ªÂBPÁÝ©¸æªë®¼ê2…��0€™@&-� /� ÁSˆ�€—8!ì—�À±©¨ÉH²)RB È. ‰:lAˆ%`« ¨ K8Ï�h �¸û‹�ÐÂ"Z!B”`¯ AÄpE1<+H >þ rE ;Qƒ 1È:[B A¢D â…Á§`!S´ -xQJÂÆˆЂAt�€ ‚àœ‚à.�è[FÈAFHË­B pA:—l „€�- 4�]Q@ F”�€¥h!@°€]ˆ`ó -<\Lë …Óe�€ÀÞ>L«|o;¿~ "t¸‚L/áeø�wP^¹§¬ãƒ @ň�®!†;íÃÜ‘—¡E�øÍ¯¿eL>�¼ŒÚ®è í´ P€"€ƒNˆáˆ €!¼›{;!B,¿Šðë{+%Ì]q þÆ#¯,ë¸@†àl÷ôƒè^†�D H³ñ§°D+�ÐAÉŸàæZÞá‘8ùB}×ëõ�@¹ Äo5à¿<—Š8+s €ø”÷¸òÐpÐ@É §Àö1PZæ!ºRÈ‹)èìL‡ºC$|®›[!´@��ì}’;¡ 6BF�î £pú Q�ÿ•ÁmÔ*ÄÂnXˆÖP�  W' e¹â瘶B¿áîÏE² (ˆü‘i¾sBPGEš¯"°Þë4¸;-‚B+À•€�Ð �uJð#)DW€üq«> ÝŠ˜?^σ™{ èHþg±€!À€_»›$™†:-ð®� ÀöJ1„0±ƒDâ–(»D`a…°|!!®°·%…Œ½êDÈhLN ³˜ž¨‘iL�“™ÐŒ¦4§¹«XóšØÌ¦6·ÉÍnzó›à §8ÇiM,Àœè<'Ö @àð|§;ç)ÏxÆsçÌg:÷©Ï~òóŸîl§= Oz®Ÿÿô§>C P„ªsžm'D#ÊΊ&ô¢ Í(:*ÑŽZT Õ'Fÿ‚‘îó õçFQ:RºÔ¤ê|(K7*Ò—*”¡0uèIczÑ–úÔ¦:ý©NºP¡Õ¨H=ªR“ÊÏ’.õ©L…ªT£jÎ�XõªXͪV·ÊÕ®zõ«` «XÇ€@��;����������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image16�������������������������������������������������������������0000644�0001750�0001750�00000000235�07504443350�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ó��ÿÿÿáááÂÎ筽ߣ££”¨Ì|‘³yyyaŒçLLL8880_À""">���,�����$��RP¥cÊèí:ST±q]ÉÁ”¬£¤d[«\¾šÍ¹î¥¾/Øy ÂÑqX&–Š%cI­Z¯Ø¬v˵!¾àpxA.›Ïè´zÍn»Ñ¸|>��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image24�������������������������������������������������������������0000644�0001750�0001750�00000000227�07504443350�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ak��ó��ÿÎ=ÿÌ3àµ4Ö®5)=Ž&6y%>›3ˆ,r$[������������������,����k���L„I«½8ëÍ»ÿÀ Œdižhª®lë¾C"Ïtmßx®ï|ïË„pH,ȤrÉl: „ƒtJ­Z¯Ø¬vËíz †°xL.›Ïè´zÍn‡#�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image11�������������������������������������������������������������0000644�0001750�0001750�00000001116�07504443350�016565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aX�$�ô��ÿÿÿöøüíñùåê÷ÜäôÓÝñËÖïÂÏìºÉê±Â稻䠵◮ߎ§Ü†¡Ú}š×u”ÕlÒg‡ÍaŒç`~¿[€ÍTq«RyÊM{ÒIrÇDnÅ9jÎ0_À>������,����X�$�@þ 'Ždižhª®¬ŠMp,Ïtmßx®ÓeqÀ „�`™œ€Á NAÀH 8`H�B�Iu,ÖpÌÁEœ àÀ(d€‚ƒ„…†‡ˆ‰Š‹ŒŠ-‘’“-Ž–—˜‡CAŸKnfM�Uiª Q� ©CYW�`Gt £Q h™ÑÒ—”ÕÖרÙÚÛ$ÓÞ߆C�ã�¥‡äGæàë«@tTOM€u@âDZãíï–4A£Æ�›¡3ŽŠ�¨cG±¢Å‹3jܨ‘›Ç CŠI²¤É“+Ô&rܸAƒÊ•0ƒÌ5ê¥ šjb^Ú$“U  Í ‡>¨ÑÀÀ¡ 2Õ™*¤>U‰À † IáE¸²@+!ž„92M.žfY�àÞ3^É›F <€S¨P‚ˆ'kå%ÖoÈ2 @äp@Ÿ£gÒT€Ë.�î�(Ó v@Ñpú8\@�1ºÄyö¬j˜—°?L�Á4|M ŽâûÃqy@ü«³¹óçУKŸN½ºóسkßν»÷ïàË�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image35�������������������������������������������������������������0000644�0001750�0001750�00000001324�07504443351�016575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõ÷üîòúëïùçíøãê÷àçößçõÕÞòÎÙðË×ïÇÔîÀÏì½Ìë·Çé°Âç¯Âç¬¿æ¦ºä¢·ãž´â˜¯à—¯ß§Ü†¢ÚƒŸÙœØ|š×x—Öu”ÕnÓgŠÑd‡Ða…Ï]‚ÎV|ÌOwÉHqÇDoÆ>jÄ:gÃ6dÂ0_À���������������������������������������������������������������,����x� �@þ@•p¨.*NaBl:ŸÐèÓs�%©vËíªJêT© 6åÊHXÙ5fSå3ìD$t¨r"cTe!M$ &){e"$*)`kf*“*^¤!��C m’ �B ��#»B€�!¹*�*ÅkCU�`»£*(»�*¦ºÉD��¤^¦� * �ð'$� �ÖÊ�%$Þ€€B<áPi‡TD*(œ @!¦àˆ„Â<Ç’y<×%½hroHF à¡0L€Â:�` ¤¦úGCPœr�&� U(PÀ͆bˆOs$³jÝʵ«W—�ø�ôkV{2X@0Të‰,fµ˜z÷`Õ€!Rè´�©5ù"Ày`À]„… �àÏ=TÒ € Y$vQÖA, Û^\×aÄš«q‰¤{'Æ]€LTôPP……… ,uVH9ƒ«Ö”8¨I‰wG,²€‡ 3ÞŒÔÒꀰ¦ÖÖ{‚¯w‡<ô\.$E,EA “°”ƒ0ëÜ� ÷ 40€ �å” :a`ÊÍ©¢ÁM (jÛE(¡“uQ!WA��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image12�������������������������������������������������������������0000644�0001750�0001750�00000000376�07504443350�016575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�$�ô��aŒçTq«JwÒF_‘DnÅ9jÎ5Iw0_À,X±+V­'Ož"EŠ=z:v7o2g-]+W#B&L< 5>���������������������������,�����$�@ƒà%Ž$ FDEÃ,J‚ Gm7ÔANÓØ·¤å¥äX8àtÄŸñÉêI€v«ìzIµ‚€€“èxE&} B­Gj4.œïøãwÏï c fUib kpj9;@r‘n,ˆ•lto˜5“Nu”5 §¨yª«¬®¯°°!�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image27�������������������������������������������������������������0000644�0001750�0001750�00000001065�07504443351�016600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞâïÚßî×ÝìÐ×éÏÖéÌÔçÅÍä½Çà¹Ä߯»Ú§´Ö¡®Ó«Ñ˜§Ï•¥ÎŽžÊ‚•Å’Ã{ŽÁu‰¿q†½m‚»j¹e|·^v´Wo±Sl¯Lf«E`¨A]§=Y¥9V£6S¡.Mž'G›���������������������������������������������������������������������,����x� �@þ@”pH,GÉl:ŸÐ¨´  N �€Ò ¨G‡X‚�Ÿ³cØ(OŽ@ QB1'ƒá„jpIZtS„…GV�!#]DCˆf� D $�Šv ¤' &[(|†µS�O&¸º¼L �"†'$¶Î„• nC�“B'D•(»—›#&B äæ {ä B$ÈÖÏóÎ#`ôøùóýýO4àò÷€‰…~Bè[Ho[� À@$„JVP€0�‚ƒ C¤¡Q ÅL…ÑÃ`ÄF=8`� �†ú*9@¤d[H…B¶uC NH/k²à€Ÿ ž‚�€y8Z¡�`V�HŒÓ 5hÆn  egš �Jœ�æW丠èpb�•Yš0Zd-=㢔HØH�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image39�������������������������������������������������������������0000644�0001750�0001750�00000000561�07504443351�016603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a.��ô��ÿÿÿêîöàæòÕÝîÊÔéÀÌåµÃá ³Ù•ªÔ‹¢Ð€™ÌuÇkˆÃ`¿Uw»Ko·@f²6^®+Uª L¥D¡�3™ÀÀÀ���������������������������!ù���,����.��@î %Ždižhjlë¾p,»&  TPI…B ñƒP"�dPA ~„ PQø �•vË­1%‡«BQ¶(•Ëh¤äÈd@µÆ³Ý¼~Ïïûÿ#kq3‡ˆ,5, hj‘X�;9l;†,T‘w‹�Ab‰§1€ª«¬­®¯°±"- ¨¹4%�L ,¸: Ã, bÇÄ´¶ † j‹¡ c“Æ?kXU-uWx$/àv@¸M iI:<â TX5DÖc¡$L`áN€�0@ˆÂq¢xéšC–Å‹"B��;�����������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image38�������������������������������������������������������������0000644�0001750�0001750�00000020212�07504443351�016575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a'*�÷��ÿÿÿÿ÷÷ïÞÎ÷ïçÿ÷ï÷çÖïÞÆçÖ½÷çÎÞεçÎ¥Ö½”ÞÆœ½¥{!ÿ÷ç÷çÆïÞ½çÖµÞÎ­ÖÆ¥Î½œÆµ”ïÖ¥çÎœÞÆ”Ö½ŒÎµ„Æ­{­”cçÆ„Þ½{¥ŒZÖµsœ„Rέk”{JÆ¥c½œZœ{9”s1kR!„c!B1cJZB9)�÷ïÞïçÖçΔֽ„ε{Æ­sµœc­”ZÞ½sÖµk¥ŒRέcÆ¥Z½œRŒs9µ”J­ŒB„k1Î¥J¥„9ÆœBœ{1½”9sZ!Æœ9”s)µŒ1Œk!­„)kRïÞµçÖ­ÞÎ¥ÖÆœÎ½”ƵŒ½­„µ¥{ÞÆŒçΌֽ{½¥kεsÆ­kµœZÞ½kœ„J­”R¥ŒJέZcR)Æ¥R½œJ”{9ZJ!µ”BŒs1Ö­J{c)­Œ9Ö­B¥„1RBÎ¥9œ{)½”1Æœ1”s!µŒ)J9½”)sZçÞÆïÞ­ç֥νŒÆµ„­œk¥”cÞÆ„ç΄½¥cεkÆ­cµœRÞ½c­”JÖµZ¥ŒBέRkZ)ÖµRÆ¥JέJ½œBcR!Æ¥B”{1µ”9½œ9­Œ1µ”1{c!„k!¥„)­Œ)Î¥1œ{!÷ïÖïçÎÞÖ½ÞÎœÖÆ”ç֜ν„µ¥sƵ{œŒZÞÆ{¥”ZÖ½k½¥Z{k9Æ­Z„s9µœJ­”Bœ„9¥Œ9ÖµJkZ!”{)ZJ½œ1cRŒs!µ”))!RB{cçÞ½ÞÎ”ÖÆŒ½­sν{µ¥kƵsœŒR¥”RÖ½c½¥RÆ­RŒ{9{k1½¥JµœB­”9œ„1¥Œ1έ9œ„)Æ¥1kZ”{!ZJïçÆÞÖµÖÎ­ÎÆ¥ç޵ƽ”ÞÎŒÖÆ„½­kνsƵk”„B{k)91B91)ïç½ÖÎ¥ÎÆœ½µŒ½­cJBçÞ­ÞÖ¥ÖΜ÷÷ïÿÿ÷÷÷çïïÞïïÖççÎ��������������������������,����'*�@þ� <H°`A]*ÔŰ¡Ã†åt•›H±b¹qã^`dÁ‘9vÈÙ9r—](ߤtQ«Z­Z-nż儦“iNðèDÂëRÏK+0 ÅÄ—Q\tèP£Å)NÓLP¡jšª©N®\–îȹ3§ë¦¯pà@kC¶¬5²©EÄÖ˜!·†¼Èõ’£nŽSxñú°P ,€Ï<CTá¢+Îp˜1áÇ3¸ùâv…ò•˘3kÞ|Ðe@¿�u=úW·_¿®¤N­áŠ_¾@ÅÎ�jm(¸¡h{"¡·µ1â½#��€z T˜°yræË>œ±â¸‹×¯c·ó¦ZÎK˜pþÅi¢É–´Md1jkÌK*/nµ?5cÏ=PöˆÂ’C>"µëµõ–1l!â_²‡ ˆ’`|†¼'!]véå×ܦoæXcMo¼Y‡#zB¢9æ<¡ú1†Å^y"ãŒ4fac߈°Å <’@‚)d&¨c!H&©¤’\4Ù$8[lQC05ŒBÃ/„"(QDÅ×ôÒËÖx≠2t"Ï�Âð<WœqtJ7]CÑ%W9·ˆ£É&ŒÐ$¦Ÿ(.’C*Æ0rVzލ©Š ÅH¤ê)`¥Žt*ip€ Ç&çu5Çya…5Vzm8Òª¤þ’^z€6è…vÕ5j=ÚF$‘ÀÑ©#aÖWÈ&Vh5è^b˜m{è±á(¢8¢‡Ü’øaoàF/ƒÈ¡„8FñȺLÒŒ»lLÂÆ¼ó¯àû @ôëJ!>¢Š*A6iÃ0UŽÂ‡–]R0½ä!À™2ÈC °ùÎÆï�œsÎIçÈ#×S å´@G&–̱l$­þÚª«ÆÜ)³‘¶±‰%™ÐB‡x™LµVrÈaËÑE'­ÕÒXå"GÓYíÕ&pÜÑò&™ÔrË)zÌ�ß\©8¨†£®†šj«´ÎºÖjŒ:XÈJsž4¦Ú2‡sزtþÒEC-G–ümIàE>¸“LR ϸáL iü†D°Fd>DæŠá¹çË4âÃ2Ç”qŒǨr‚À ©…7\xcƒ ¥” ó1…–RDAÁïaæ‘=ËcqÆoL@�7ÿ1�"ÇYœÈ$W?ò@õÀP÷,gG Hˆ×D.¶P-Mª¡K—Äñ³QL\r HÐ?ýøÿ$ÿþA URJP.H‹88%ÑÊTê°„ÀÙíTT Ì<E«õ¬Í@l €Ø+õ H :«-âÇ œÜ‚&4™Æ,è÷¡0!€J„$Œ� "$"a8D!º@°×Í®þ5ÀîBÁ» œÃw¿®q%*€‰×�&1 Oxô˜Å*f<Œ à_ä˜ó>Vœ8ANÓ³ž×ÈF’!§ &ÞræHG;I„!ÙHITò†Z¼¡;~ dÿøÇ]¼á$$‰H:‚qp#Œ¤F&™‘HZÒ‘‘ldG>B‘$r&Q‰!ÿè—¼¤0‘É Uà„YÌ kXƒ2ZÑŠd”`¦ð)ªŽmd#OüÄðè&ã­ yKæòÐ1f2ÓMÎN4™÷¦æ5�f4#õÚÈÍnzsÒ1Ès¹;=$"w´ˆE²É4Ò‘ñÈ:<ùÉ]€’µþ0ä.jÁ’—8 —`-‚¶¼¯ ë‰Ë]�Á Í€1ˆ ¢D¡ja€øÁ€m4Ñ`¡¡2 Ä)r ‚\å%/ ÈÕ]ôˆ èA) ܃«ºÄè}ñ `2Ä iIk¾�ªP-S™Îˆ¦4HjF #7¢¤z£ªB5 P}ªV±êT K¿Ð@(|Ñ�Pp©{À6´Ñ ©LfÎÆ˜—FãÔ‘ wrCò$G<Žã ¸„ê�5´Ç¦|y7 ˆ¼Ô…QÖY&[)M9Ji¦ÆVÁH­Eƒly‹!â‚«“ZˆF3ÂéHGª+š2J> *þP­;(ŠBá ØâV<‘€Ì£Àn :q±‹7¸óØ­‰<Ñ‹µBá ŒâtY¡ŠcX×e(ƒ+ÐðŠCt7Þ=Ä!€ð ¸â¼è-ÀvU˜@?âÂ0€¨°,õÎw×`«ðÌTÌs8##6ÙøFåèbHh‚4Ú [5@ƒTÈzÙ§†u³ô€0R²ÀÔ¥@5‡ÁYe T±V§oÅEC1ŠófªËmw˜ŠÓÞ78¨E>ŒˆgÕ€ˆ`¨¡WØ©¢ÔÁWm8XsÈU¨R‡JÔAhU±GeÀ5-Å-îʨÎGªQ%I†Ü $@â gX„þœÁJ°k̘D»Ð¸}½b_ü2¯z÷<°ÖŒv¥È–Üßk@l¿ýE¦òšÉÌçIïŒß4™.ìp‰L�Šf2Ë4Ì`VN·t(Šâ À:<ðmèÕ&º‚â\<*< †²‚þ¹°(t`—bÀRTjç Ú2øñJ³ á¯Ä’jªEpTÐŽ 4Tu¬UçÍK€J4hQ@g8£rp~DvC÷9Vô€„àH0ˆ(¹;J5ˆ·¼k�Dz× ¸øÀo>0€ˆRpG¸”Äk|¢‡ÎbñŽFáHóMóXËH2‘mó›ÆÈâÇåà1ðô=þ÷hJ“Œ¤ß O•–»\U¹2ßP¼6yhSi¬9Áí8ÈzÖµæEýT “|ª$‘‰Ô'WÂÏ—À¤3©‰MœÐÊР—‡8Ò†d„#_ *<@ `8 T˜‚*Pl,ÑÐWT8šŠi̺[¬‹vǘ½˜1á8\ŒtuÞÈ.ŽñÂcÜ9âlŽ^ÍyN<~\Ú©äF4ùŽ„é‡\z]ð†~šê'¤:ÕU0 «×…@ V®‰%ÜÁnçIÏÚn•œ4¤ÜàK_t ÛçJ.’‹Mg´ØÆšÔ¦+Õ‹î?P™†b!¨A…ŒaDýÁÀ A¾ŒeVþ3€Æ«£ ¼T¤Žß«èO*RÑÿU¤n@5­«Y¹´€(¤ ì˜ÀÚêV¸blc cWÑqˆW€åÄx¡NqQIôNŒO–ǵ0 µ2¦†j’b 9P[¶‘5#|ÑP‡1Q…2õQ¡(9@!‰…‚/"#|0¢ZÇ—X`½S<(b{0Rña ©P„²Zz¡|{})ØSNd3Ò p#" ï6 [€…ƒ…Xøn^ø…^oPe%%cµ%QÐð% &p�fâ p<Âá1F2w5G㔊·WH±-€+ M þ›� Í¢ [C8Zðá ÿA6žU+´’ ÅÖÄ–‰š(ÂW¶'#Í—‚0HƒpR¿GSnñ§ÐS…±ì"e²[½\ÅE\Å•‹ºØ Ée&O°Üp 6"7Â#é†$¬`nÕÕ{ÖŒê0>p¨sÇÐ^}Ögðõ#[8%õEDç0‡–ü•&Ç`x‡Õ“‡gGŠ·qa·€ ™0<F§=%-‰q‚‘!„“8aš6mdq4ã*°ò)Ìò*˜BÁ²iFv‰ì^�‰ïЦåX-¸+ñ‘A�2YŽ"+²2Ãf wÑS`SÛb Ê•�ir\Ãõþ[Ð[fâ!Ð\á YБ€ ŸÓ®À h0”D™/óÒ ±Àöw†‡à æõ/Ó^BÂh £%G´D·_Åã_#Fo‚MÆFvôǵÀu� =v ‚‚#•A Ôž3“56ž")êÁY–•3‘ðy£Xf*¥B7Éâl©2mpÀiÙi©b,:¶Ÿ6‡Õ{o![ Õ(Œ¸¸ 1#3ÇB7z#Yá…åAí‘ Ã§ST0›¢� }—Ñ "à• àJJà“àf‰ólð.Ç)/LÙ ¯À”ÞÕ/z¦^S0V9_B4woþ1@L\ô_a`tqÆQ–&Ga2µ ˆàˆ *ta6ƒ303a{¹a›p=“kär:×:§ ™ðŸKV &e8"f š08îƒ –¶®âÒ§à,™™ é*À⚢š2a£²4"Æ7N5V‘  tW!e•0b ¤ •Ðz†38‰s‰ó ’ ‹� °Êð±0 ‘PÀÂ.ë‚0”p^þÒŒ«ÓT$>4;÷–;Ø)Úùv€E çE×L #qŽFxÜd2õP—@K°*Âæ˜ ÉJ¡Ò™ŒÀ3A“"V|:.'43¦˜¿2þ©bmX¡s´p¸?ò“kûLPÔ0Uád£e ù)œ6§ÐV¨ªa©FmèC7tÃbyƒb :8•°ªn ´ f€°`9ÌPd0 РЀ bÀ ½*<À < Ǹ$Gò#°;VùCµÃøÖo»#Zº•Lô ]:<[d<aùwÐTM'gD=fêMg2å`HN`i3Sq *2Ó)†` q`7RÃjO³u sÚæ>J�tú¯¶fkD¡zI@<×kPA4úz4&A3óY"‰ 8*‘À˜Œi6Ñv¤" t€ òS?©§kqà nàôrgzæþ؈$V oA4 VÂeø ÿFD:»³ZÂ;gD[ù;RdhVDÝ™­ žsxކŽN[q†g=G1`�`ø°µ\‹ö` =1ä°O-p71 ¥G?;áòƒ ©H@tP@œ€@-§°ø:4ECª¨ö®2[Æ[“Ø+ 9*Û#$²H€RwJ N@z¥·¶$«?Bq.J° áa�8p ÀÐ}ÀoS€çpn÷v†v­W4<ÃDôP»C<Ä#�SLß™´á McôhfµÆk–¦t„€ èNŠTy˜„AXÖþI‘t(¡tú´ˆä½%¾ŠdñÔIå[¾$à ¾)¡yMwJ©uŽ»BH€uk Bð?�v;0v¤`U@€Ø€ 'LÃ4wx‡<_ÔwlâÀïìwaªLÍ`v'Å iÇÛÁgš‡~ˆxÌ;U«€aI ¸I"AOÞ›y£ÄG}Ô{BS§BÓ€?¨'?Kÿ3@«w@Z€{ÏVV+ [(Zò!’‘tQZ·‡ZNøSŽAÐT“1؇¨ƨ¡dÜ ªWÐ  Ñ}å—TnüÆI%Æ¿ PÇó í°�íì°bâƒþenÒ1ÆAµÁˆÌ¼ h½&| Ø€ðÄI4à›y'¡Oú¿O§J4œBõ ¸0Pš`4TÃ,ë!®#{áPˆR(ú¡QÕ"üuŠv!|_㈮y?EQúŒs¡R¦¥{ƒòQù(T[}Ðç|Í×Ñ}pœ~o¼~ëçÆY@UQuÍpŒVcUV P÷7  ÐV‡1�€Ì32±Wx%‰<ÂŒlÂØ!yáHœÄ+LÉHwÉt¶H@œ0Ê›06í©RÃÇÊ5QûøÐµƒ‘{=e(ì�˲,ÑÁ¨Ê3r2(yÑ{ QÅ&¢üáþ‰5eSBƒ Å„=å Ï÷|@õ|Ÿ!#j,…6B%T2o=ÍÓ<=%S†5ð bXY€ÔVÇ© ó °†äÜV½à!Z4‡ë`uUÈБxˆLNgy'ñx'<,½™4ÉZ3ÐJ uà2¦\ ¨lX ·uzÀ3À‚ðÑžÏr ÑÒS2‚ÀçZïA¸èˆ™I â Lü5‰SBQ¸%‚XÐ(ˆ|Â÷ŸÈÒ¨Å|L¸¢ÍY "ð ƒ�NÒÚ®ýÚN_\ÀÚ¬=]hÔUB£€t\V]¢VVD&ü¥&S‡àj=WG_ÂxÏõþaµà+ ­g7¥<~‘ ”Ê3²(¼Â‘›ˆ‰è-×…m{(Õ{ÕX‰|8¥iUÙž`‹ºüß Á`\ð!¿¸×‚SuÚß%<2Ir<ÄCª@á×80=€áîE&p$Gâ$6 %¹ÍsŒ†øÅVã ½;`Ù&tužêèÕ·`½±Å™ ÂrÊGˆw‘Šs1 Ù+½bY4±I^AéË ‚ƒR̦˜ZxáÞP¬Š¯u ´•!Õ’’æ ß»Å‹�“ý‹À•&¼e"ox�Pà §€Úƒ Næ–áÖU>�•â5^þãe^zv^Ð訃:ÓI‚`0"ÞÒŠDmÈÃâkòw/ÞFg`z(Їå –‚£lcoYÌå§ ǦlƸŒ )˜²—Ž c›Å—j±Y’‘^ ŒR„FÈÒiZ*•åbÞŸÅä‚B(u->X"4Ù c.\Ä…‹ÏŽæ¼e dòäÜ¿0¾šŒ=@Øå ÚE”ÜÅ”örgæÎ/yö/®0Õ8±c•ñ¦0%¾•mè¥ý¦K;–ÝTézȇ‡\ëะ…e¨†r(†ÑX"À+²€žÒ—d“l˜6¡Æ—t™+lÌÒA„ÞŽH„5Õ{«ÕþZJÜ‘“µ7³i¡Ú˜ê1m±È0Å-`W´x&Êe"rÎÚ.Q@`Ï`«Ë¤Cù.Ͱôl”± ÷’/æþ Py^ë5‡n•ô5 ÑZQEE{&]„<m"¦íìMÉ}éËðN –�=6(¾�‚†ñ"¥Î™qJa޲®—cã÷;ët* ­V¯§Ò°ÏV,kÄ13|©6HœÄ­[¼B,Ÿº,jq\17ô°ziñd G8(ƒA›(‰×RÙ¸¥"}ŒP� W0s ³°âà–À.hÐ ôr”¼Ÿ/¿Ï”å5^VÏ:#;ͪ0 °èK4þì Ätw}—LÖ´ÕûÏâÄö´@äð±am ŸlùùŠ3F‰¢²jVSC܈ ÿ‰ 7ΖøœÖlÖö@¡2+c[péQ�qêTŽS^©q„PM¤6 22¨Mœ8rl-Ñ”«Ž¥:š–ÔÙ˜±R9çl‚Ó†¡#FŒƒéE„—T9rˆ‘JÄÍT:Œ‰q4'’3ˆs3iÒ‘G“˜MBÓì›Wh‚ ©šõ …¼êrBÐXo\lt(ÅŸ)R¤D¡pí‚<yèy’!C^Œ}ã½ü.À`x @ ñbÆ<€ùA½åZä2vj@ÆmþB g¥B„mªa¤ÆtCG§1rgÓM9eʤI·î޽ukÔd‰7oŽÃ?îÖ”).Zuæ¤\íÒA@²D”={Kî©W›N( ‘c‘à̹“ £%õê7æ²´¾c%ø%åÀ¯³ä#Gý–*ý_@ÿ&±dJl©DqÆxc3Öç“(âJy„™GÐà+ <t¥¿òAU9Q .¼±Á†´FáƒP¤¨�.¹èÅ.¼ô’§¯þŒ€ÁÞ§°��P ±#cr1Éê²²].ÉdŽ“à€£µÕÒ²!/ÕXˆ50c“£6:” #ÜšÐMÝ* ÎKäþÓ"“¬´Å+çÈÏ;ä˜C&.1D@ZB$ƒX2†&/ AÄ%ØÚPÍ¥Hb5í¶S?íã³$[îÈÓ>Kî`/¾ür¾:åŒVX TJ©gÜp& !”YC™4Ì€G‰¤c#)ÃØeÊ`–YW|xÖ+Â:ñD¼Ñ¢,†A+­µ¦˜ñœs(ˆ ǺèÉKu} L0Á # ÞÄ[²IÇ$Ó¥–8à{ÎKð¾S <ÕX;ÍhlInMKô,uÔûäð ¹7ëôJ,/†ËMlÉ„ZpÁZðˆã9Ùb͑ؠKhÓíZ»X6iöm“9¤ íb”vÍÊ™óþüóOû„¶ÎWdà \Q0à `Iä•dQDGªF†EÈК•¬{�»ÇFq,A²]±Ek¨µ¾Ñãš+Ç<vÔ+¾újw0x‹,€# KÒ^Ã4à}3±ÅË$LCeÈ)U-¥HÉ!•Mâ ƒ5?O3Üx«4,¡aHã›Ñë(¹8h¡&0¡½vL˜`Bv\Ò¤ÆsNDÏÍ£\LB š†u9REJK=ã˜e“gèápþyk•ÎJ”6B’ 4˜)c™FÈP™¯Y!„Þ'a.œùïç"pÔn±Û>8ÅÛÖжHÁ爂þnT—Ü…G{À;"˜�¼«0<R’S¸zÎp”y@¾v¡„60"um€NäPØ%8è�wÀE&N…3Eg¡BU.tƒ›hpd³£Ý%Vp ÛÕnv¸@â™”è95/8têJVƒä%;*SÙjÌS=Ó嬆=³ÒŸ:’‰ÂN g¤…œ¾f@ ÎòA‰TÑA´\�ǶÀ¶`ôqä×£µ’-2b€[Ü".r‘K.½0×¹v¤®½M‚ñº`à ³˜ ΃Ÿd  ¸q¼¡NÀ…&ä $H®5]‚.Á¦L47¸ñ5”�2L ‘HÀ.þÁ‹a^˜B,¢s·»3Ñ‚qøÝ-w³‘’XÉtßIˆ¥")KcSÝIÊJ&î(¯ 6‹Om8‡ $Là -¸Å-œ€"bJpfÕH„X\å#ꉴµ¶¶Áè|ÅŒÜ"7¹Uà…èC8®F^ƒn×€¤Ýì"�¦+=â[ÞE8ÀÍ«1…eJC9™QRFº¨‡ìqzèbv¨Å-„ÈœÜ,aas E<�ÌYL#˜ÀD*=‹y $™¶ËÝ2ÑDg2ñ–µÜO‡wŸ…›¨‘Taˆ±¾d¬Æà9e3ªT¢ ËÁÄ%Üy xÊÓ *˜ôêþTcâø+-Ò `A- `�n -�-}øVZQ¹Ô 8Â,$1K—ºt–Ÿ€'ð2IJVHA"L‘ê…ÒªÔµL’ d ¤‹rÔvµÅíKu«‹ØFƦäØÅ)…yÌcÖί+P&ψOjPäªnJ•Eôt’Ьä4 §C&ô¸Ž³c*0ãÙ‚ZT£Á­†)k±^öÞ"§ñ*^ñ:‹`“¸—‡Ä!„d˜!_C1+ Çö l¡E0—OØí³žèh^$<a KX]îHùvZX0“&åäkE|8ö_»¥-mË1³xÅ, ÇÈûþ;ܶ/µí8X`‡]×ïu‚]`TwâÕ G2|á[ ò’wêÝiü†¿ÁÊOÆò•©l.Û0î2—×Ñe*—ù .Po-~Ì^x¶Y¨G.ª^‡ ¡ýþàá(1Bà?Âé ÂÐQlÄåœÕ‘…)9€JúÈGv´âñ£v½CH˜ \'G¼i×Ö42”)±‰EÝ[ã–Å,`Á:ªÌ^6¯·ÍMvu¬[0k÷²z½V¾ò.Æüe/Õ,Ðq°… ì`û×ãðõ—Éæ1«:ËoHïÉkºÂγÐ+„„ „;—`¦øƒ¬P…@g# PÀ'ìòÙtŒ]ØÑ§­t¼åÝ·‘f²¤(åt¾U ÞÆÔŸžÌ“�nbÞ¢XŦn1±~ê7Üá+¶-nM-qŠKü¶Á82žñ`s\á`³Æ,ò(çúÊë5/“sZ×[Ì kèÕ*~àmp‹» °@6°ñ‰O|]<ª$`,YA¿éo~#zÒ1ø7Mã[ßOe@��;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image37�������������������������������������������������������������0000644�0001750�0001750�00000000174�07504443351�016601� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax��ó��ÿÿÿíñùÜäô ¶â—¯ßc‡ÏIsÇAlÅ0_À���������������������,����x���1ÉI«½8ëÍ»ÿÆ'Ždivq®lëNDp¼tm[G�áíÿ&ƒ�@ À¤Sè��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image7��������������������������������������������������������������0000644�0001750�0001750�00000001047�07504443351�016516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aE�$�ô��ÿÿÿëîóâæíØÝçÏÕáÆÍܼÅÖ³½Ñ©´Ë ¬Å—¤Àœºƒ“´z‹®qƒ©h{£aŒç^sTj—Kb’BZŒ8Q†0_À/^½/J,X±:v 5>���������,����E�$�@þ`'Ždižhª®cv¹W,Ïtmßxžk¼& =  Y�$B`8h € @I�@DÃ��0/Ò8(8ŠÃì$¹lßð¸|N¯Ûy–¼~Ïïûÿ€‚z,…†‡‡wŠ‹Œ‹�� <a <X �ea¡� h ›Fœž o¾¿ÀÁÂÃÄÅÆÇ¿ˆÊËÌÍÎÏ%ÒÓÓQ ÔÛÜCoÞFH^[£ç�¤O�C�gFbhY›ãWæÜÿ� Ü6¨ Áƒ*\hšÃ‡#JœH±¢Å3jܸ1¹8r4²)ä‚3­TЀAõÈ\°f‚Ì•*|ä!SÔL”3×°t sŽ· àŽhR”:–�°´„F‹‚{ázIGŠi¸ɪÁÁ»�NIQxº m¦YP‘2"+—‘yÚx˜€v΃,K4D�LªB”¨›¸ò¨0/U.o©–Žõ’T0$Ã^$ɹ³ç8B‹Mº´éÓ¨S«Ͱµë×°cËž½ƒíÛ¸sëÞÍ»·ïß·C��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image28�������������������������������������������������������������0000644�0001750�0001750�00000000640�07504443351�016577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷æêóâæñÞâïÚßî×ÝìÐ×éËÓçÄÌã½Çà¹ÄßµÀݲ½Û¯»Ú«·Ø§´Ö¡®Ó«Ñ’¢ÌÊ‚•Å’Ãu‰¿p…½m‚»^v´Wo±Tm¯IdªE`¨D_¨A]§=Y¥9V£6S¡.Mž'G›���������������������������������������������������������������������������,����x� �@Å@“pH,ȤrÉl:ŸÐa`*1ÄÈ´ �!`™Œ–¨zÍf?¨�†˜˜ ˆ#°P„�$m†‡ˆB�vj$%‰”•Qo& Bš�&t&�C�“–­®¯°±•¶²¹ºK˜&&"  Ba&$c »Ñk˜ B `\�£~Š�ÈÒåN˜�#%ì&é"¤"$ &�¬æþM$H ѯH‰ÿd�;������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image21�������������������������������������������������������������0000644�0001750�0001750�00000001064�07504443350�016570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞâïÚßî×ÝìÐ×éÏÖéÌÔçÅÍä½Çà¹Äß²½Û¯»Ú¤±Õ«Ñ˜§Ï•¤ÍŽžÊ‚•Å’Ã|Âtˆ¾q†½nƒ»j¹f|¸e|·^v´Wo±Tm¯Oi­Lf¬Gb©A]§=Y¥9V£6S¡.Mž'G›���������������������������������������������������������������,����x� �@þ@•pH,ȤrÉl:ŸPb!,�±Á†�àM¶¤Ê ÀGU @� žQu„€EД�&` 'Q‡ˆC�dm �) prlŽ&�$"B*#�#t* $(*` *])‰¿Q�ÀÅJ)&ÆÊI`�eg*’ !p!BcmdBm*qs}pÔpä�m¹&îËö÷øùúG#û�F±’À€  , !¡! üS–�º¨È`ÀƒŠ† ±uTaâO~$†!�€�;À�N…h Ìb àCZš¸9²�€Ä�&LRñE/Êhg�.ôÜ”™¨Íˆ�œhC„FtJ¤ðfŽØ¿'w1=G'E€œ’õ‰�H…‡&pœð!µJNÐ"¬"�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image8��������������������������������������������������������������0000644�0001750�0001750�00000000761�07504443351�016521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a<�$�ô��ÿÿÿõöùëîóâæíØÝçÏÕáÆÍܼÅÖ³½Ñ©´Ë ¬Å—¤Àœºƒ“´z‹®qƒ©aŒç^sTj—Kb’BZŒ8Q†0_À/^½/J.[·%A{:v 5>������,����<�$�@þ 'Ždižhª–YëfW,Ïtmßø½íH½ß¦ì$�À IÃ�˜øv�A:�…Íp`(¼´zÍn»ßðeN¯Ûïø¼~o_ùÿ€*qƒ„…o>@<ZKHU;ˆX TXS L >j©ª«¬­®¯°±¬´µ¶·¸†»¼ƒ>T� ½Ã…> �� HJ�“BS‘‘XT\E_bT Äæçèén|ìíîïðñòu¹õö÷øùúûüºêÿ�ª°‰“Àt”")«À † ,m€‘ ¢1˜TQYÅå"lY ¬ wÙ0 ��4¦p¡4Ì™iB} R Í ‚ 0‚�<h2Y “42àÁJF“×D8U@‚GTvRºÊ6*@B-¡2ËÆƒpãä@·®Ý»xóêÝË÷€ L¸p‡Ãˆ+^̸±ãÇŠC��;���������������./saods9/htmlwidget/tests/page2/image18�������������������������������������������������������������0000644�0001750�0001750�00000001041�07504443350�016571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87ax� �õ��ÿÿÿõöúíð÷êíõæêóâæñÞãðÛàîÚßî×ÝìÐ×éÏÖéÌÔçÅÍä¾Çá¹Äß¶Áݳ¾Û¯»Ú«·Ø¨µ×§´Ö¡®Ó«Ñ•¥ÎŽžÊ‡˜Ç‚•Å’Ã|Âu‰¿q†½l‚»j¹f|¸e|·^v´Wo±Tm¯Lf«Gb©D_¨A]§=Y¥9V£6S¡.Mž'G›������������������������������������������������,����x� �@þÀ—p8$e4$¢rÉl:ŸÐ¨tJ% �Xˆë`+ÂÆø”†�j˜¼.€Ô«üÁ�T"�ä…Ū¨€‚B} -l/l/bdfB X$/-� [�‹�|ƒ§¨O.� B#[‹°¶.¶¹&/F-/&À'B¹¤©ÏÐB'� �IÓ{ %,B�&ß� W(/ �/v �Š| ÝÑøùúûüÐv^~õHЦ�Œ9 AÀ�oò4p”&�Šaq!€�(0£vE€ 2\IÕ  Î¨ æ‹³2g^L aG€B¿6�`<’�–õq¶²Ÿ‹ $VØÁ°¢ÍÑŽÆ —“–�x1ž@¡( À�%r6xâ‘°æê…�;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image3��������������������������������������������������������������0000644�0001750�0001750�00000025123�07504443351�016513� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89aâ"�÷��ÿÿÿccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞççç÷÷÷çïïï÷÷÷ÿÿÆÎÎÎÖÖÖÞÞÞççµ½½¥­­­µµ½ÆÆŒ”””œœœ¥¥„ŒŒs{{{„„ÖçƔµÎÞçï½ÆÎœ¥­Öç÷½ÎÞœ­½”¥µ{Œœ­ÆÞŒ¥½çï÷ï÷ÿÎÖÞÆÎÖ­µ½¥­µŒ”œ„Œ”ÎÞïÆÖ筽Όœ­„”¥µÎ祽֜µÎ”­Æ„œµ{”­œ½Þ”µÖŒ­Î„¥Æ{œ½„­ÖÖÞ絽Ɣœ¥œ½ç”µÞŒ­Ö„¥ÎµÆÞ”¥½­Æç¥½ÞœµÖ”­ÎŒ¥Æ„œ½{”µ½Î眭Æ{Œ¥„¥ÖÆÖï­½Ö¥µÎŒœµ„”­œµÞ”­ÖŒ¥Î{”½Þç÷½ÆÖœ¥µ¥½ç„œÆÆÎÞ¥­½µÆç­½Þ¥µÖœ­Î”¥ÆŒœ½„”µ{Œ­Œ¥Ö„œÎÖÞïÎÖ絽έµÆŒ”¥­½ç¥µÞœ­Ö”¥ÎŒœÆ„”½{Œµ½ÆÞÖÞ÷ÎÖïÆÎ筵Υ­Æ”œµŒ”­„Œ¥½ÆçÆÎïµ½Þ”œ½Œ”µ„Œ­µ½çççïïï÷÷÷ÿÆÆÎÎÎÖÖÖÞÞÞçµµ½¥¥­­­µ½½ÆŒŒ”””œœœ¥„„Œss{çç÷ïïÿ{{„ÎÎÞÖÖçÞÞïÆÆÖ­­½µµÆ½½Î¥¥µœœ­ÞÞ÷””¥ÀÀÀ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!ù��²�,����â"�@þ�Hp`�ZªPa¡Ã† -IœH±âD–dHÀHA†ŒŽ KQ)²ÒÈ‘&+©\¹2†J—0cƘI³æLR7càÜIŠÔ™ž?ƒ =C´¨ÑE‘žQŠiª3OŸâI¥ÕBx°ZÝʵ«×¯xrX›£lYC9ÐZ˶­Û·p½’K׋/vñÞu´Wß¿‡ <˜páÃ…µÒ¢¥Ï˜>Œ7rCÙ–F—kÆÌ9s£Ï ?»™LùÍ›(o¹yóÅÏ+Räĉ$Îkt¸ˆáÂEÒ:bróæR§ÎpÞÆëЙ3ËœäÅ%_èÊ9€�Y¹ŽéïàÃþ‹/~µ›GŒ ‘:X°½û÷ð Z(¡B(ØP @KPTA€@‰D ˜ Q%$` *É`ÒI•X(…ZHáK•¸ô)˜hâL'êdN:u"@¢˜@>QÃ1 ¥“'‚% ˜B QMKQOJS*,¹T“©¢d*S‘°ŠŒ¢Ô�6  UWbÖ˜bY%晆(fk Ð Zª°ÇZl²I§yÈuWž{Ú雇Øõ'_~épס¦WÀÐ]a„aÅV�Dsˆ¡©‹¡é"›‚*FtQjptlªêª¬J²©«þC¸ œt=ôf+qŒ ÇÈn¹öÊE®Ç{\rÈ‹±ÆWqbÔë³®fÜ´tTk­µ¤ÒAj$XD:G$s.säŽ É¸±Éä™ÖñÅ«A�X’@$ÁLà@��ˆ@•D` h A  0a)8˜À(XBI2 ‚&)‚ hb!%`òR)1ŒâIˆÛH‰)T²É()ªHŠèD &€'ÜxÉBw’ÉRx@Ã&œ‘I�¨ uI�g4ÝÉ 'ÀRà 6Ì�• À‰T¢ €U]ãqÆ)Ì`Õ  hU�x ·þU) ‡UlhiŠyäц�àÑÆ�xˆù iÑ ÊÚ† mH9 І!àÀ¦lîÁ ké0Â+†èº\y8Bc§­¶|,)‹ðÀC¤B€º¨aðªïšöÐŒô<#Ë+o|òb¸Êꦩjj­©Xd¿ÆG\E Û7—=X\[­õCˆ!-pC¤?DµÊe!mÀ9k³C "F¬öÿf?ýYIJ@‡:€txŸùx-S‘¯|¤Â·šC.ç+0Du¬S9\,¯c…’á„($C !‡Jr`xÎ/„Ôˆó™�$ /ˆL„‡þ¢D‚¨�MHA ª„%”˜¡R¨C%ÉÐJDâ’–À$D)ªN´˜“œì„&¤°‘O&0FŸü¤GJ!Ê|ĵ¥ åH]+R× ¢¤¬@JVi,ð� *�$�ä–i¦± %Lk\ZÖ‚;ÅNv¢“$uÆD_€ÃX …àánw<˜ `àA#lÇ 0hÔí‰ÜíŽ<Bd9*YÎ2Ra˜ƒµË^6‡T³B$„iªb–*UÈ4¦ŠéÀj)ó˜¦ÊB3h-išAYÀB3˜Ê›f C8³€„b fèf8ÍvÒá€æDBö°€Íw6›ÙþÃgùòéœ50Ç‚dÎ(È Îa ¼B <(‡…2´…Ú‘ƒä@tÇí|Ø#ÞP ¹! #Z¤¤FLP‚>¢‘R,1‰1ɆRB!–u¨Š•pbM°x¢}QE@íÉNp䓬'Cš@PŠt†!5…kM‰ — 9. ¼£’ðФ@2+„äJé†/€!%Ø‚Zƒ°+\ @¨BÞ €“_ˆ‚eå;©.Ou“êðÄ:Õ°ÒÁb¦@'¡ Sð¨PT 4•ֱŠp…2áo¨‚ Ki…îu¶ dCŠð„2á Nðþƒ¦ð7L±SpC>sÞú`2ZM#vëBŒ†¸ÆÕ«ruË\ÝF! “pî$ôÚ‡(<º/˜Ä ¢PÝÔLáߥmÀû†ôá çͨz×ËÞöºW½‡€ÏBèC¯ù±^<I( H#Zi)’Ä}¤$²̲ž^D(²‰u2™TGC:ê”JF£.•>yêRŒªÖ±Ä$ ÁHP©¦Â«° Á½ò¥°&ò+ib¤šÂ¢–°ÉÇ’d $/§§µ6’sù“ê–ì»ÊP|)L”³0ÆŠaÌo÷JåÉ„V—µª@?x° ohþkâ …HLkZŒ¨ÞôÒ' Ýl*}u`ûöÇçäôª~ÉN ­,dº8uN‹Ó,F+ÏÓšÕû¬‡ªk-B[ÚÊ0a`?øA†ïýjHjú6ÄÔ™À�$��&b�X+P%ä0Tìˆ Ê@�0à!N€d£Ð P‰�\âCâ©�^¦„�dâD E%:1€œÝ¤¬w(tò èäŸÚŒˆR#Œ"4 Q6µP€Âz;C�–P$½¡­ª/î# ¨Â†¸aÅ� ¸Ê�R€‡U0l�¶"Š€îoVA,ðÀ‰QŒéLyÐC(þ(§¹Æ"tîVÝZC„€tk�êò`¨Â­…/†à‹øzˆ(Ä!RÌ]§@ÕàÍòw<îÄÐ;M%SPŸžz=㉒PÞÕ¹ ¼_åªë_O׳žç!ìJ7Œ ³¦tó¬ZkžkXÊ�….@¡îv·;Þï…;@a w�üŽ0ø¸Ë}{ƒ?Â߯ø¹ßîw<ÝËP†'ØÁ•§¼Z»ùÖRÞ:­ÎAË•ËsÍá\R˜ƒ q¦K[@sxF]ê‚$¤^9”€H²ß’qˆÚˆ‹˜!ÿ¶ÔBÈïHI¢ø!™‚ˆeUDQŠH"MŒFÅÉoþDFJõ'>jjQ†4â6ž¡ªql#RTLªàáŽ2þ#TY«Pi+5þJôð‰ —[!&iH˜ÓHØ‹t9 È&5:à@ ;r𬡶)¿³|p<Øh<XtTwi¹£‡*Ø-¾ä‚³ ЄLçãL¥òL¦‚*•–*é“@Ô2iós>ÒÒ2ó£> D@ñãvïc@Y?OOòóNòÔ´MÛ„t Ä…[˜OBÀ…ÜÄMPÿÄ*8P…A e õA×ñA••RBbö@x8 ö†@j9R74 7T%µ_þ?t&5D"qDÅ·k3…!2àD(Ñ| aXtE,ÂE>¥39#8âaJeFHá#5¢FâçFæ×FUUU%GK,&cQ’ TR_V66cÒ‹bò7h’: „pI‰°RŒ- º£ŠŒ¥BŽEE QR�?�/@Z°s~¡Qð‰ -t<P;ºK¹Ó;B°;‘Ò-a�»”K²ä‚ãò‚`¶KαÙS†ÎaL5ØL×3OIÖÂ…T>ô> Ôƒ¿!$Zˆk€G°e0QVPy8éi}j"9’êõi$ù5ˆQ ¡{F4 0 þ|D„R*…Rñ 2aÈ·`4eS˜Ø–‰T6'pn;Ñ#ÙwŠ!fŠL1bçGUåw$K¢' bXÙŠN1px„_’`Q&bgjŒ?6dHÖ€©3‘Ô–Žp'€•†âd„RÞ(‰±‡Ae~©(~©opBT0ŒEj@c0S€–ÁÃeIºe°‘0Kb�WG¾‚+·ÂÀR?À"hÎRg„&,…FÇâg…&‰æšÍÒ,®ò+Ñ# ˆ %W�.,$`’'ù޵Wjì15ˆ„8 úD½×’)5D!.5D±Dþ²DýEm9µa8EÓa?U_Ô#@‘#>C~§ˆFIAOa$Q媈•…0pJòG€´$Sº¸‹géÁ¸c d ˆ9BÖ ƒIxsuy­cXNæd‰¢XQæU`^«Ef°C¹U˜*A 0`*¹Ô-r–uš"=¬b>«£³™v0Ê>¾‘£|–>¶’vz棿âgÄ¢š¬Y,‰Fhõ£,Ðâ>Ô2„4øL1h*ô™IÃ.™Y.²QÕ^`œÇi{ôõQÊÙ ±°jp�ÀC b/ž`D °�`�08 !@ p ý!� P!þ° «6�×V 0  � @!1àDÐ!P�Jp 2"�ã6¢à “º ž(�› T� ¤0`Š@“ C3�zo¤P�—p¡À   �¢Jxp«yJKÑ7zÄ«`]3p_•nV!9€%¨€Ÿ �P�8€{© '‹Ó¨` VQ�{Ð@�¬V¬Ö*##�®6àhÁ®Z¬s#Ð"§l:”ä'8—Kf‰ŠåTP°˜¶*­$K°4u¡¢)ätŸu¢"u›Buf=šâ£µÂ<¼âu¿Âuh÷µ²ÈñgzV+y²Éþh°‰hÅa„FØN‚N‰¹=qGx€w‘:kx…‡³BëOý˜=ñ¨-Ä„iÄ™ââ-¹$JÌ! µ¼ ©gµêB9¦ó¢œdZ§v�`¦/¹ ` ¿v� |C”� Â! �»–!Ÿ�20�ž0�˜P `¨¸:¢ €3• ÐSyÛ2€},"£Ú1 œ0À”¨0l>Ò Ñê4¤0�£ZªJA�œ'—€«{ lðG ‹«4 3À ¢�¶(%{  Hy°7…°€ %x   ÌÛ ­¼zHh�3�«þð‹pl…0�œ‹£á»o’$�5°€k± oé'ª#‚‘:Z�çØI't‹€¿¼óIJ£Ò°Ou ÒSç<ËÃ<Í£À\Ç<TGu«’>l=d‘ÛÃwP xÜÃ=†W‘ødOö…ô3@ösš¿±?´?¿ñ„t @TO \-ø4†ü¤=s° Õ=ÕQ”×Ãe€€yqX§%f'”-äA�K X›Ä²÷}@jµœ94”ð�P ;$Å�|Îyk˜à{ B  B ˜¢!˜ 27%8ÕS™€ 6¢‰ØGžþæ#4€ا  >ÓTñY~E±ºï‡y€(@•4€¾Ú~1æ$Uµ÷7 J ­°lÐ hðz0�erc—£G€h¬üÌ›Ê^ ¹EeZ�+q€Œ¹ƒK¸C‚úË)$x<Æ#‚ÍÓûËœb¥ÄD¼tKËDA`†X°LÈDiÔc=Ò’* TioÎ|v@ÁñhnW?¿Áú£?Œ6„?ÎâÂÃWx- d>¥R>ÍÁ-ûx†ÿ¤‚£s°Ãä†Ú¡&„BÀ‘xh!I{ïÁ]‹C;´{¸6é{— Ò¢$-Sr!'Áþ!òD}™H”.A}+r}7rLI £¨Mu#NE•營M~™ÜU/æ6T"ôU¼‹¼X&‹TH®ìc“–h1d Ú€~•:ƒAo- t¸S;µÃ)XÀ¸)˜zj'µóxK¥¥²T×K[׳4ƒ�é)É”*9ÓB@¨"- Yƒä@ $…Õ ,?ŽýÂQøNìtMÛÄØäMø†bX-™Ù‚dHPeHÐ$J¢ •Ð×sXQv˜mµ‘! `ÚÉI_è’…ØÅ^D¿`ÀwDET`|²“ßéDRÄ!.áD:Ó1!ÓÔþÇ"é9}Fçv#â·FMálÄÈSùFCH]G/¶Ÿ×GïÇUö' 6V RHgY€?¶H@f(=ŽÙ˜Œ¹C;Á*u8Ö|€;˜¿ŸdK¼ƒKu­KïÞ¢ï8Ë¡ù(AÌtLÞLÌÔÙÙ†ÌÄ…B°OÒtL÷œØø„ùâÝ†Ž Ãf€NÝ$OX¨_ˆ³ wÞƒÃ8 Bµ©ÝAj˜ÚÞ‡u(ZÛ!ä-¤†ä"õP«ÝBq0]ê^ñå·=^^ˆú‚ó Ή¦Ã'“Â]“.u·ÈgRâDâÒWTçÑ-éùEDÅ}þAá#7âÝâÇ5fD~L1G†Ž~KâqHíÇG\uÔû) b©…”‡°QPV;pV‰ÀIÉøé'j&PNИc@A@JR`�ºuXxAd…so©dy’:X6YD@än)bàÌ»ƒ×¶T.¢­áÒüÏ`Æú¸LÚœÍþ|âäã@ºÄìtpz(f-Wd¦ZT°.¦1Öå\ªîªqØ]à>]Õ5 Õµîo ]�é…^'YïöjmÛ8äC]ë¸G¾Ç_�â_GôÆï_âæRdâiÒáÉ‘*;U”žÈBuñ: èIb^~rUPpæ êÝþɹÈ6(ïŸN &aalar/ÏHj± Ø u¢Õúúd†BI;¯XŠe|eQöóƒñóA?˜‹¡JŸô¸Ì‡Vv¶U·U¡Ñ[½%\ Z§Áoq ‚Á¡‚»Äg¢É.,uæH,ƒF¤f¤Î¢g.{š‰¶$4BVðÐÞÞ¥ yïµeð¦µWÅcNRúrÅ 1ÆðÒÿES»¦`²Ò>yÒy©ož0AÝTÿE8Ñ#Bñ#NŠD⊉®~\©$PÒG¶xòŽÎɰïÔd™ 2Ïc’d3¯ûni'îXu¹ó e~Ay0G_(B_ô‚˜‹þeLŸeYv“U³ÔiE ¢•EêTà+0 q þqPYrh‡£W+¼QgÒãz&+³R¤íšÇ",CjhFz¬Ù,ºá�QGŒ@Iň)x° 1 > FŽ•?~Þ\ĘQãÆ7}ð��RäH’%T�ié¤%”*]º¬ðÒ’K,gÖ¼)AM –vR P©§P AeT:T(ÒJKc¥Pªi©Mc\­T+©¬1H]½ú•ÔX±b¯žðz†Ô™jÛR:£–-©pÙ²=‘·mª»©H¤R‘ V*Â' á!Ö Xx'nìXòdÊ’sP6”#³!Cx.ãþáOžÐšóhæLš´¡Õª9ëÈ£Ã/:tÊ“ÇË!/yÉ>tÛÑ¡CŽ~×qü7Z´L3fJq7QÜ4×2éEŸ7S¨È!Ë,W®#Œ˜ER¤„™Ãðàüƒtä9ˆ_Ì‚uzÄO.ö3H :$ñ ë¨cˆ:¸hðA!„ÁİB.dArPüÙOûèÈâDûR±!1"Q1 ûˆDˆHà»9䈣 ?¨xHŽ6êà RLBÒ$”@ZÒ% @ªÄNh ‚˜*  Ëšh ášxš‰¦Ÿ(!“LÒ (©¢‚ª©J¤²*«¬àŒþ¡D%“ª¾Ò ,³¼¢ëA-Pb¬«Î „¬¶â¢k­32Aa®¶ôb+Jù:ÃRÀR)„0ÃC…BNPl=ZAT*cµUÉ:Ûì²Îd-T4Ë´–`ƒ5_Y[ÍWÒzcÍ‹Ú`«ÍÜj˹âˆsv7´ ÂŠ à¨â 9àhÎ;*¨�bŽ0‚Ž0ʽ‘!èc—]ù\œO?± F†`„@øÃ·Ž{´0C&¸à .øÁ'D°Ázæ/‹‚† ¿‡T¬1,è¨Ñ\ã  øæˆDÜ9L>Y܉âøŽ!5Ò"I™Pé$&aŠ �Ml¶ÄjþÒ’¦š àKKzÒ‰&<ª¦¡Ž– ”˜ZJª£ªšëªfÐY+«¼Þ,¯®úä°B%­¯Îˆá.·ÞŽëºîÒ+/¾N¸{0K# 0R ùôS<N°a�ÃV=Œ²Onp3Ç8ó 4ÐdÍcrè5´`Sö×`µM7ÚrÛm·ã†{Ú窰""ð"ŠèFÙ£ý EÚcÝùþÃý |qè^FDÞ?¹`yå…Wá ¶Bè¦ðà;dDBüê ƒA)F( ç“ï!Õå˜c!â3yä”ç€äd þ9¤„Ç?„ä–™•LIKhf à�xÐþ €T 8@M–V\âh–XZ%0Š`"›€%<!�LX ,S�>  À¥�Á(!ƒK| +A‰A&LáL`¢€4¨D&Љ`›ÀD¡ÆÆ5%\Ehb'À6Rp`1(RO|à ˜À H!�Q €¡À”@�N( E*Bq�<œa 8l Æ¤�Á_PƒUÙ@�)ȃ`<Ô �KЃ*VA�=àX>A�4à ›Ä@€Uè ®ØÃe˜ �C°¡�8Ѓt`€b“lÈA C¤@�¡N�Òþ ΀6¿iÖlˆSBüàn Â{Á,‚´[ĹÖs;öð@ ëƒ7q§»ÝÍ'_ÿ‘DÒ™N1ô`yŒ`„;“—=wŠAy’H¾’7 o Ðóײ P¥h X@ÂA×�……BÁ¡}h  щJ´ hEí0Ñ'Ø! v�éÊP;tô %éHUZóbWHÙxà3Ó“¹ïdRx)$À#)ìȧq°ˆF>ò¿’°&!¡D81‚�8à°‰žZOÀ›(ÀM`U ŒÂIóª p´(@•@€ £B�È€�H� (!§:±‰fÅJ 8þ‚J|�a3 (�`1XÚZb0€MäQ� ðàâ×3lbwAÛ F‰'Q`�Ž +”Š<`�)@A³ª¿Ô`�ÄÃ�jàT µ `|)Šˆb˜4�s°"7ðÀä>)�@�8h%æXÃÌà¿A( 1€6膺zÐ!@‡eÉÆ¼Ä‰BÂPM>,âvîC{y°MnŽKï §íØuÍôW ñŒgàà yÉð½ÔY z)D^.Bº††:ô¢O€(îp„ +TÂXÀ‚°›! &>±Ì $°ØÅ-f1!þK˜ÂG¸qޝ�…@¬á #…ÂJ…\+¨e8r‘a@�bGW˜_ýp?)@â :ÕOåð‡Ä€¨5[RLh€ ´Ä%œ@€Xmb ( è�7q“xB„Ø’'F!ƒ6Ë *À4¡³£\"�KJ)F �ºöu°•'´B Ð`К‹ØjÛijTº Å*;�G‰eœÈC�2qÙ®eÐ(0t\è–©»˜"g¨#©l‹ë¿ N¶r­cRÁQàáè$ ‚Ê ’q…)<‰¹Ë¤€�£n'?Ôxà9Øehô €C´a�¾ÅX#›Øþk6ZxA~Óˆ-„=Èæ6à »û."á¼7ñ{þöWÀ 0€Ovþçw ¡C"¯áG€ÆyŒccA‚PÅ2’7Dû9¿¼w=uèŸuÅÔ½™‹!EEQÎUdA”‹óxÇÉC—¶ô 0’•n@hë M&2¤Îd&ûT:…DOƒTŒ4âË!Ú˜·:JˆÀ�;³`�`w®I`�Š &`$@2ÀX Ä€�£\¥‚�”"*¢`´) ŠÀ{BNM´ž*A‰¿‹â±Y…ÙÆ–iPÀóF”4)”`ZS€þ°gP<oO Tö²tá„(ز ˜Â¹¦Èc�zkX €Œž¥_Wˆ|°­dl ÓŠ¢y°|LÉP �§-n¼­ÜæÀ!èL(?‚l sÛÀ™ØÀWØCq¼0cEa -xs¾ˆÜ."Õ„¯÷º¦€{/|38>H¸…3¸ø'‘‘Ü‚s: »‚#˜ƒ5:u)—r—û¨˜ý¨ûdñ™9~‰¹AA˜3!1a¹zIA›9‰I‘Ô¹S±ž: ñ” „ú™ƒ"D:ó§{²$[2+:2ø2¨2°þªÛ‘8Ј(ø•0ª1s š‰ – É¡)߀š€Ã+  �  š¥8ŠªI´Çk4¬èŠ>‹¬à“²0”µ¡@ ¹¸ ¸x‹¸°‹EaļˆXÈÆ`ŒÁá ¾ D@’ N!•Æi4ø€=ÐCb…ႜRÌÔ _É•ÎÑœ_a7CЂ7¨0�ƒ7�j’/jš/àƒ{ëÅöê¯{ë_0D@t/©)#º9XñºñpFò‚jìÀúÀÆë@‰Ÿ¬A›Çˆˆ¨sì(˜sá˜ÃÁˆ‘L‘̹û8빟³ ÂhþÂ#<¢{)ÈŸ£[„ÔŸj2ª#ƒ8 ©+*”BþÁˆ™ C0\ 1”€1ìÈ™C-Ù’‘œ‰0I¤yCËš¤y“ 0¼–\7Á<­›±ùCœ ÄPK ¸X‹¶µ¶pJhDºqD¼XŒÅ¨ÄJÉ”Ààµ?r ¾>ÇHNd•ϘÉÐØŒÍЕÓ`ÅÍ™ _97�‚÷)Ø)¨¦¶œ¦{[|»öb÷º‘™ƒúó€²—‘—™ªFsaôÉÜñ˜Ü@Ÿó9Ã4L Á9ñ±£˜z¼ApD1PAºÌœ#±Ð̹AÀ9˜SAMþÍ1:ØGãÇ œÀh$B"4ÈÜ<H&|º§“'ûM&kH(|H*´HŒp¢â™13› ™š ‘’ɤiÞ ?[C2‰ŠªqIzº’ °ÉÃL«>™€¯˜�¯H”´¹µFQDD‰›EqJ™”¤Ì ý¬DPÊÄ •Ä8ŒÈ¨Êª´ÊW™ŒÎ¨[é ψ•Õ@UlTì -ˆ‚ %¸P0P„iòÐ\\/øØKm1§ƒ#„ˆøËˆPLm2Ñ&mRÌjì˜rQ´ DÆ<ÍÑ©G µÏÄÁr1ƒÆ¤3XÍ3@‚$µ%UþÍMAÈ‚'m±,°RK‘ëA}ÄGA°M ™!”Æ“q©¼ $œ9hS„äMô@%N&ƒ®ãˆ˜‘™0C– ˜8Ã1Ä ’ü’éDšJ¸ JH²ЍI4£X ¥Àªx<òìŠ=>É4²pOÅZ R€‹¶ñIDt›ŸÄ GÜOIÄ›¦´DId-á3 ØŠŒU9ÐÊÀJÉ‘•È1%(ETÈ ]ќՠ(x/€0Ehjr¯lÊK§»B&3ÀôP¹Ì¯j¢ƒù¢‘5™õ ™™ÆÄ‚9g´‘j¬Æs1—ÌÆÜÀ¬ÆñQwA$ ÒìÇ,�1þƒM,RÔ4±k1³R)E‘)ÝÒ±z9“M ±”ƈ=Ó÷9BüqSœâÍ'KHàœˆ;}™8$itN2´‰ �Ô”í‰ *T8Lš§‘Y7ìN6¹C¥Ϧ�O­)OLÍɰ( ö¤"*jÏO•›·aĸ€D½XŒüÜ‹¼ÀÙ¼ÐPY•«5ÐZMЬÌÕ% Í•á¸Ð7Ø0XË÷ØEj Eƒ ˆV'¸B2pÛ8¸–³LÖ¸„Ë8j2—lʦÑ™‚oW‘Ìñ×oE\ÃFumWĤ׎“\ɹØËQ†5ÇzTR$�1:h±,ÝRÑÌþ˜‹0 ³B2ðƒ* *ðƒù*€ƒ1p]Ø=Î;µ×Y?ÀÝ×}< ’Ø…ƒ?è‘?ð‘*¨‚á­?ø&C*8Î͈ä4‰šI æÃŒÎ2ü’ yY5¤ DÞð³ì|ԛɧx“ª “<¤«Mõ@ÁÉô¤¢¯@‹±@‹35úüÉI©Ï3hZ¤Ü‹ÀpÊÁQŒ�¾¿¸Ú^ÓZÊøŒYáÊÛ°Ð/@„D`)h neÍ:)¸B·%ƒ"(k±E‚8�‚7øçpcY·ÙÐÚÐBˆ8 Û×™¦ñ·Ø‰@eQqQÌš:\ø˜Ø“1Óf¤X!ÂÁ„—vYþˆ†¹rùÜ,‚AŸ»,@:"‹ƒ"h^Ѝ‚8°á8ˆèý]ŒèƒGèƒx{ƒGxƒ@ã7pƒŽ¸îÞ;Æã<Öã=Æ/ 0C @] 4C”5š/ÁÎ jÃ4ÁÎ7„Ôš•Š—ÄÙõÅ!8yßK›®à“öŒô”AT‹A<Úµ€ ŸDÚ¥àûजMù”M1`曬åD¬Ì „/ `0H„-ðå¶µ‚8ˆøƒ"¨c& øà ¸`]ÖâÈb–dqácj·ãØ ÝЂFP'a"«‚ˆ9Ø&û\…©Íâ"„òúyçxº@À(ƒ%þ¼ç£;‚+ Ú½*˜8ž„:îŽë°ƒ®ŽëpƒF8hëp脞„ê°ŽIˆ‚)x„Š~„9Ž‚Gè(ã7ðèG€c‘®c‘vc>Fé”Vi<6$ñÂ1ûÈšÉAÔ•ý’—mY8„š j¡¨ÃŸOIž ¬é;<|ß>9OL…ßLË´P¥‹¶1Z¹(å¸1DU^”½Á›J´ZRÁµ«U-aÃZvÖ8„@ƒ]îåðå-@a �‚ä…ƒ€]þ^gžÐÎVVì ݈ æà(¯Úà áXè7`è"°Â20*ƒ*˜ì"çh7èŽø–è "PƒW)Ðì> ‚>˜ÑvØæFXímö†fŽFÈlBí(m7 ܾŽÜ®†Öí‡Îh7 è( èâ¶ŽŒiãè96é6é6Æ5Î;^éê¶n<ÖS‘�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tests/page2/image5��������������������������������������������������������������0000644�0001750�0001750�00000000754�07504443351�016520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a:�$�ô��ÿÿÿõöùëîóâæíØÝçÏÕáÆÍܼÅÖ³½Ñ©´Ë ¬Å—¤Àœºƒ“´z‹®qƒ©aŒç^sTj—Kb’BZŒ8Q†0_À/^½/J?€:v 5>���������,����:�$�@þ`'ŽdižhªŽWë¾p,Ïtíj`àz>€‚¦"� < ÐH� ‡Ð (†åR0œxL.›Ïè4ÚÂn»ßð¸|No¯îø<JÍïûÓ=cPPLK9�C�‹OQ Žc¥¦§¨©ª«¬­¦z°±²³´+·¸|�»�W¹¿�F<?“R�89; �ÌSÏcÌ»ÀÝÞßàjuãäåæçèéµëìíîïðñò'áö÷øjÑùá=’h`@°0(†ƒ ƒ 8*0¨öÀ“!œ€! Éôbp�@±BSr�€øì䎒¤);dÑI!Ï£C@�%qjÐl � 2rsMÃÂÌìäeI?z-åU ß@Z…fPŒY…%A¼ú[ËÖÞ†·pãÊK·®Ý»pÓéÝË·¯ß¿€ÙpL¸°áÈ+^L8�;��������������������./saods9/htmlwidget/COMPILE.txt���������������������������������������������������������������������0000644�0001750�0001750�00000006201�07504443343�015111� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� HOW TO COMPILE THE TKHTML WIDGET The TkHtml widget is written in C code. But many of the C source code files are automatically generated. This makes the compilation more complex that many people are used to. The source code is contained in the directory where this file was found and its subdirectories. You should not compile in the source code directory. Instead, compile in a parallel directory. Like this: mkdir ../bld cd ../bld All the build products will be placed in the "bld" directory which is a sibling directory of the source code directory. You will need a working installation of Tcl/Tk in order to compile. If you installation is not complex, and you are not trying to do anything clever like cross-compile, then you should be able to compile as follows: ../htmlwidget/configure make This above assumes that the name of the top-level directory containing source code is "htmlwidget" and that you are building in a sibling directory named "bld". The configure script makes a valiant attempt to figure out how to compile on your system. It is successful many times. But a lot of times you have to give it some hints. The most common problem that configure has is in locating appropriate Tcl/Tk header files and libraries. If you have compiled Tcl/Tk yourself, you can point the configure script to the directories where you compiled Tcl/Tk and the makefile will use libraries and header files found in those directories. Note that you do NOT have to install Tcl/Tk in order for this to work. You merely have to compile it. Suppose I have compiled Tcl in a directory named /home/drh/tcltk/tcl8.2 and I compiled Tk in /home/drh/tcltk/tk8.2. Then I might type: ../htmlwidget/configure --with-tcl=/home/drh/tcltk/tcl8.2 \ --with-tk=/home/drh/tcltk/tk8.2 make If you are trying to do something really strange, like cross-compile, you will probably need to give configure some specific hints about the locations of compiles, linkers, libraries and so forth. You can do this with environment variables. See the comment at the beginning of the "configure.in" file for additional information. Even if configure is not able to locate all the necessary libraries, it will probably find enough information for you to type: make srcdir The "srcdir" make target generates all of the C code and header files and makes copies of them into the subdirectory named "srcdir". Given those source files, you should probably be able to concoct your own build procedure that will do what you need. The Makefile does not know how to build DLLs. There is a script for that purpose in the source directory. (mkdll.sh). The script works as a cross-compiler using the Cygwin/Mingw32 compiler suite on a Linux host. It is setup for my particular machine. You will probably need to adjust some paths to get it to work at your site. Note that that Makefile for TkHtml is generated by a tcl script. The configure script first collects information that will be needed and uses this information to construct "makemake.tcl" from "makemake.tcl.in". Once "makemake.tcl" has been constructed, it is executed to generate the Makefile. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/COPYRIGHT�����������������������������������������������������������������������0000644�0001750�0001750�00000001523�07504443343�014555� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1997,1998 D. Richard Hipp # # 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 Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Author contact information: # drh@acm.org # http://www.hwaci.com/drh/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014027� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlimage.c�����������������������������������������������������������������0000644�0001750�0001750�00000015417�07504443345�016175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlimage.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines used for processing <IMG> markup ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <string.h> #include <stdlib.h> #include "htmlimage.h" /* ** Find the alignment for an image */ int HtmlGetImageAlignment(HtmlElement *p){ char *z; int i; int result; static struct { char *zName; int iValue; } aligns[] = { { "bottom", IMAGE_ALIGN_Bottom }, { "baseline", IMAGE_ALIGN_Bottom }, { "middle", IMAGE_ALIGN_Middle }, { "top", IMAGE_ALIGN_Top }, { "absbottom", IMAGE_ALIGN_AbsBottom }, { "absmiddle", IMAGE_ALIGN_AbsMiddle }, { "texttop", IMAGE_ALIGN_TextTop }, { "left", IMAGE_ALIGN_Left }, { "right", IMAGE_ALIGN_Right }, }; z = HtmlMarkupArg(p, "align", 0); result = IMAGE_ALIGN_Bottom; if( z ){ for(i=0; i<sizeof(aligns)/sizeof(aligns[0]); i++){ if( stricmp(aligns[i].zName,z)==0 ){ result = aligns[i].iValue; TestPoint(0); break; }else{ TestPoint(0); } } }else{ TestPoint(0); } return result; } /* ** This routine is called when an image changes. If the size of the ** images changes, then we need to completely redo the layout. If ** only the appearance changes, then this works like an expose event. */ static void ImageChangeProc( ClientData clientData, /* Pointer to an HtmlImage structure */ int x, /* Left edge of region that changed */ int y, /* Top edge of region that changed */ int w, /* Width of region that changes. Maybe 0 */ int h, /* Height of region that changed. Maybe 0 */ int newWidth, /* New width of the image */ int newHeight /* New height of the image */ ){ HtmlImage *pImage; HtmlWidget *htmlPtr; HtmlElement *pElem; pImage = (HtmlImage*)clientData; htmlPtr = pImage->htmlPtr; if( pImage->w!=newWidth || pImage->h!=newHeight ){ /* We have to completely redo the layout after adjusting the size ** of the images */ for(pElem = pImage->pList; pElem; pElem = pElem->image.pNext){ pElem->image.w = newWidth; pElem->image.h = newHeight; TestPoint(0); } htmlPtr->flags |= RELAYOUT; pImage->w = newWidth; pImage->h = newHeight; HtmlRedrawEverything(htmlPtr); }else{ for(pElem = pImage->pList; pElem; pElem = pElem->image.pNext){ pElem->image.redrawNeeded = 1; } htmlPtr->flags |= REDRAW_IMAGES; HtmlScheduleRedraw(htmlPtr); } } /* ** Append all the arguments of the given markup to the given ** DString. ** ** Example: If the markup is <IMG SRC=image.gif ALT="hello!"> ** then the following text is appended to the DString: ** ** "src image.gif alt hello!" ** ** Notice how all attribute names are converted to lower case. ** This conversion happens in the parser. */ void HtmlAppendArglist(Tcl_DString *str, HtmlElement *pElem){ int i; for(i=0; i+1<pElem->base.count; i+=2){ char *z = pElem->markup.argv[i+1]; Tcl_DStringAppendElement(str, pElem->markup.argv[i]); Tcl_DStringAppendElement(str, z); } } /* ** Given an <IMG> markup, find or create an appropriate HtmlImage ** structure and return a pointer to that structure. NULL might ** be returned. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. Use HtmlLock() if necessary to preserve the ** widget structure. */ HtmlImage *HtmlGetImage(HtmlWidget *htmlPtr, HtmlElement *p){ char *zWidth; char *zHeight; char *zSrc; char *zImageName; HtmlImage *pImage; int result; Tcl_DString cmd; int lenSrc, lenW, lenH; /* Lengths of various strings */ if( p->base.type!=Html_IMG ){ CANT_HAPPEN; return 0; } if( htmlPtr->zGetImage==0 || htmlPtr->zGetImage[0]==0 ){ TestPoint(0); return 0; } zSrc = HtmlMarkupArg(p, "src", 0); if( zSrc==0 ){ return 0; } HtmlLock(htmlPtr); zSrc = HtmlResolveUri(htmlPtr, zSrc); if( HtmlUnlock(htmlPtr) || zSrc==0 ) return 0; zWidth = HtmlMarkupArg(p, "width", ""); zHeight = HtmlMarkupArg(p, "height", ""); for(pImage=htmlPtr->imageList; pImage; pImage=pImage->pNext){ if( strcmp(pImage->zUrl,zSrc)==0 && strcmp(pImage->zWidth, zWidth)==0 && strcmp(pImage->zHeight, zHeight)==0 ){ HtmlFree(zSrc); return pImage; } } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zGetImage, -1); Tcl_DStringAppendElement(&cmd,zSrc); Tcl_DStringAppendElement(&cmd,zWidth); Tcl_DStringAppendElement(&cmd,zHeight); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, p); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( HtmlUnlock(htmlPtr) ){ HtmlFree(zSrc); } zImageName = htmlPtr->interp->result; lenSrc = strlen(zSrc); lenW = strlen(zWidth); lenH = strlen(zHeight); pImage = HtmlAlloc( sizeof(HtmlImage) + lenSrc + lenW + lenH + 3 ); memset(pImage,0,sizeof(HtmlImage)); pImage->htmlPtr = htmlPtr; pImage->zUrl = (char*)&pImage[1]; strcpy(pImage->zUrl,zSrc); HtmlFree(zSrc); pImage->zWidth = &pImage->zUrl[lenSrc+1]; strcpy(pImage->zWidth, zWidth); pImage->zHeight = &pImage->zWidth[lenW+1]; strcpy(pImage->zHeight, zHeight); pImage->w = 0; pImage->h = 0; if( result==TCL_OK ){ pImage->image = Tk_GetImage(htmlPtr->interp, htmlPtr->clipwin, zImageName, ImageChangeProc, pImage); TestPoint(0); }else{ Tcl_AddErrorInfo(htmlPtr->interp, "\n (\"-imagecommand\" command executed by html widget)"); Tcl_BackgroundError(htmlPtr->interp); pImage->image = 0; TestPoint(0); } if( pImage->image==0 ){ HtmlFree((char*)pImage); TestPoint(0); return 0; } pImage->pNext = htmlPtr->imageList; htmlPtr->imageList = pImage; TestPoint(0); Tcl_ResetResult(htmlPtr->interp); return pImage; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlcmd.c�������������������������������������������������������������������0000644�0001750�0001750�00000045362�11344041345�015647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlcmd.c,v 1.2 2010/03/04 23:31:49 joye Exp $"; /* ** Routines to implement the HTML widget commands ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <stdlib.h> #include "htmlcmd.h" /* ** WIDGET resolve ?URI ...? ** ** Call the TCL command specified by the -resolvercommand option ** to resolve the URL. */ int HtmlResolveCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ return HtmlCallResolver(htmlPtr, argv+2); } /* ** WIDGET cget CONFIG-OPTION ** ** Retrieve the value of a configuration option */ int HtmlCgetCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ TestPoint(0); return Tk_ConfigureValue(interp, htmlPtr->tkwin, HtmlConfigSpec(), (char *) htmlPtr, argv[2], 0); } /* ** WIDGET clear ** ** Erase all HTML from this widget and clear the screen. This is ** typically done before loading a new document. */ int HtmlClearCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlClear(htmlPtr); htmlPtr->flags |= REDRAW_TEXT | VSCROLL | HSCROLL; HtmlScheduleRedraw(htmlPtr); TestPoint(0); return TCL_OK; } /* ** WIDGET configure ?OPTIONS? ** ** The standard Tk configure command. */ int HtmlConfigCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ if (argc == 2) { TestPoint(0); return Tk_ConfigureInfo(interp, htmlPtr->tkwin, HtmlConfigSpec(), (char *) htmlPtr, (char *) NULL, 0); } else if (argc == 3) { TestPoint(0); return Tk_ConfigureInfo(interp, htmlPtr->tkwin, HtmlConfigSpec(), (char *) htmlPtr, argv[2], 0); } else { TestPoint(0); return ConfigureHtmlWidget(interp, htmlPtr, argc-2, argv+2, TK_CONFIG_ARGV_ONLY, 0); } } /* ** WIDGET href X Y ** ** Returns the URL on the hyperlink that is beneath the position X,Y. ** Returns {} if there is no hyperlink beneath X,Y. */ int HtmlHrefCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ int x, y; char *z; if( Tcl_GetInt(interp, argv[2], &x) != TCL_OK || Tcl_GetInt(interp, argv[3], &y) != TCL_OK ){ TestPoint(0); return TCL_ERROR; } z = HtmlGetHref(htmlPtr, x + htmlPtr->xOffset, y + htmlPtr->yOffset); if( z ){ HtmlLock(htmlPtr); z = HtmlResolveUri(htmlPtr, z); if( !HtmlUnlock(htmlPtr) ){ Tcl_SetResult(interp, z, TCL_DYNAMIC); } } return TCL_OK; } /* ** WIDGET names ** ** Returns a list of names associated with <a name=...> tags. */ int HtmlNamesCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlElement *p; char *z; TestPoint(0); for(p=htmlPtr->pFirst; p; p=p->pNext){ if( p->base.type!=Html_A ) continue; z = HtmlMarkupArg(p,"name",0); if( z ){ Tcl_AppendElement(interp,z); }else{ z = HtmlMarkupArg(p,"id",0); if( z ){ Tcl_AppendElement(interp,z); } } } return TCL_OK; } /* ** WIDGET parse HTML ** ** Appends the given HTML text to the end of any HTML text that may have ** been inserted by prior calls to this command. Then it runs the ** tokenizer, parser and layout engine as far as possible with the ** text that is available. The display is updated appropriately. */ int HtmlParseCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlElement *endPtr; endPtr = htmlPtr->pLast; HtmlLock(htmlPtr); HtmlTokenizerAppend(htmlPtr, argv[2]); if( HtmlIsDead(htmlPtr) ){ return TCL_OK; } if( endPtr ){ if( endPtr->pNext ){ HtmlAddStyle(htmlPtr, endPtr->pNext); } }else if( htmlPtr->pFirst ){ htmlPtr->paraAlignment = ALIGN_None; htmlPtr->rowAlignment = ALIGN_None; htmlPtr->anchorFlags = 0; htmlPtr->inDt = 0; htmlPtr->anchorStart = 0; htmlPtr->formStart = 0; htmlPtr->innerList = 0; HtmlAddStyle(htmlPtr, htmlPtr->pFirst); TestPoint(0); } if( !HtmlUnlock(htmlPtr) ){ htmlPtr->flags |= EXTEND_LAYOUT; HtmlScheduleRedraw(htmlPtr); TestPoint(0); } return TCL_OK; } /* ** WIDGET xview ?SCROLL-OPTIONS...? ** ** Implements horizontal scrolling in the usual Tk way. */ int HtmlXviewCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ if( argc==2 ){ HtmlComputeHorizontalPosition(htmlPtr,interp->result); TestPoint(0); }else{ int count; double fraction; int maxX = htmlPtr->maxX; int w = HtmlUsableWidth(htmlPtr); int offset = htmlPtr->xOffset; int type = Tk_GetScrollInfo(interp,argc,argv,&fraction,&count); switch( type ){ case TK_SCROLL_ERROR: TestPoint(0); return TCL_ERROR; case TK_SCROLL_MOVETO: offset = fraction * maxX; TestPoint(0); break; case TK_SCROLL_PAGES: offset += (count * w * 9)/10; TestPoint(0); break; case TK_SCROLL_UNITS: offset += (count * w)/10; TestPoint(0); break; } if( offset + w > maxX ){ offset = maxX - w; TestPoint(0); }else{ TestPoint(0); } if( offset < 0 ){ offset = 0; TestPoint(0); }else{ TestPoint(0); } HtmlHorizontalScroll(htmlPtr, offset); } return TCL_OK; } /* ** WIDGET yview ?SCROLL-OPTIONS...? ** ** Implements vertical scrolling in the usual Tk way, but with one ** enhancement. If the argument is a single word, the widget looks ** for a <a name=...> tag with that word as the "name" and scrolls ** to the position of that tag. */ int HtmlYviewCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ if( argc==2 ){ HtmlComputeVerticalPosition(htmlPtr,interp->result); TestPoint(0); }else if( argc==3 ){ char *z; HtmlElement *p; for(p=htmlPtr->pFirst; p; p=p->pNext){ if( p->base.type!=Html_A ) continue; z = HtmlMarkupArg(p,"name",0); if( z==0 ){ TestPoint(0); continue; } if( strcmp(z,argv[2])!=0 ){ TestPoint(0); continue; } HtmlVerticalScroll(htmlPtr, p->anchor.y); TestPoint(0); break; } } else if( argc==4 && !strncmp(argv[2],"text",4)) { HtmlElement *p; int i; HtmlLock(htmlPtr); if( HtmlGetIndex(htmlPtr, argv[3], &p, &i)!=0 ){ if( !HtmlUnlock(htmlPtr) ){ Tcl_AppendResult(interp,"malformed index: \"", argv[3], "\"", 0); } TestPoint(0); return TCL_ERROR; } if( !HtmlUnlock(htmlPtr) && p ){ if( p->base.type==Html_Text ) { int offset = p->text.y-20; if (offset<0) offset = 0; HtmlVerticalScroll(htmlPtr, offset); } TestPoint(0); } } else{ int count; double fraction; int maxY = htmlPtr->maxY; int h = HtmlUsableHeight(htmlPtr); int offset = htmlPtr->yOffset; int type = Tk_GetScrollInfo(interp,argc,argv,&fraction,&count); switch( type ){ case TK_SCROLL_ERROR: TestPoint(0); return TCL_ERROR; case TK_SCROLL_MOVETO: offset = fraction * maxY; TestPoint(0); break; case TK_SCROLL_PAGES: offset += (count * h * 9)/10; TestPoint(0); break; case TK_SCROLL_UNITS: offset += (count * h)/10; TestPoint(0); break; } if( offset + h > maxY ){ offset = maxY - h; TestPoint(0); }else{ TestPoint(0); } if( offset < 0 ){ offset = 0; TestPoint(0); }else{ TestPoint(0); } HtmlVerticalScroll(htmlPtr, offset); } return TCL_OK; } /* ** WIDGET token handler TAG ?SCRIPT? */ int HtmlTokenHandlerCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ int type = HtmlNameToType(argv[3]); if( type==Html_Unknown ){ Tcl_AppendResult(interp,"unknown tag: \"", argv[3], "\"", 0); return TCL_ERROR; } if( argc==4 ){ if( htmlPtr->zHandler[type]!=0 ){ interp->result = htmlPtr->zHandler[type]; } }else{ if( htmlPtr->zHandler[type]!=0 ){ HtmlFree(htmlPtr->zHandler[type]); } htmlPtr->zHandler[type] = HtmlAlloc( strlen(argv[4]) + 1 ); if( htmlPtr->zHandler[type] ){ strcpy(htmlPtr->zHandler[type],argv[4]); } } return TCL_OK; } /* ** WIDGET index INDEX */ int HtmlIndexCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlElement *p; int i; HtmlLock(htmlPtr); if( HtmlGetIndex(htmlPtr, argv[2], &p, &i)!=0 ){ if( !HtmlUnlock(htmlPtr) ){ Tcl_AppendResult(interp,"malformed index: \"", argv[2], "\"", 0); } TestPoint(0); return TCL_ERROR; } if( !HtmlUnlock(htmlPtr) && p ){ sprintf(interp->result, "%d.%d", HtmlTokenNumber(p), i); TestPoint(0); }else{ TestPoint(0); } return TCL_OK; } /* The pSelStartBlock and pSelEndBlock values have been changed. ** This routine's job is to loop over all HtmlBlocks and either ** set or clear the HTML_Selected bits in the .base.flags field ** as appropriate. For every HtmlBlock where the bit changes, ** mark that block for redrawing. */ static void UpdateSelection(HtmlWidget *htmlPtr){ int selected = 0; HtmlIndex tempIndex; HtmlBlock *pTempBlock; int temp; HtmlBlock *p; for(p=htmlPtr->firstBlock; p; p=p->pNext){ if( p==htmlPtr->pSelStartBlock ){ selected = 1; HtmlRedrawBlock(htmlPtr, p); TestPoint(0); }else if( !selected && p==htmlPtr->pSelEndBlock ){ selected = 1; tempIndex = htmlPtr->selBegin; htmlPtr->selBegin = htmlPtr->selEnd; htmlPtr->selEnd = tempIndex; pTempBlock = htmlPtr->pSelStartBlock; htmlPtr->pSelStartBlock = htmlPtr->pSelEndBlock; htmlPtr->pSelEndBlock = pTempBlock; temp = htmlPtr->selStartIndex; htmlPtr->selStartIndex = htmlPtr->selEndIndex; htmlPtr->selEndIndex = temp; HtmlRedrawBlock(htmlPtr, p); TestPoint(0); }else{ TestPoint(0); } if( p->base.flags & HTML_Selected ){ if( !selected ){ p->base.flags &= ~HTML_Selected; HtmlRedrawBlock(htmlPtr,p); TestPoint(0); }else{ TestPoint(0); } }else{ if( selected ){ p->base.flags |= HTML_Selected; HtmlRedrawBlock(htmlPtr,p); TestPoint(0); }else{ TestPoint(0); } } if( p==htmlPtr->pSelEndBlock ){ selected = 0; HtmlRedrawBlock(htmlPtr, p); TestPoint(0); }else{ TestPoint(0); } } } /* Given the selection end-points in htmlPtr->selBegin ** and htmlPtr->selEnd, recompute pSelBeginBlock and ** pSelEndBlock, then call UpdateSelection to update the ** display. ** ** This routine should be called whenever the selection ** changes or whenever the set of HtmlBlock structures ** change. */ void HtmlUpdateSelection(HtmlWidget *htmlPtr, int forceUpdate){ HtmlBlock *pBlock; int index; int needUpdate = forceUpdate; int temp; if( htmlPtr->selEnd.p==0 ){ htmlPtr->selBegin.p = 0; TestPoint(0); }else{ TestPoint(0); } HtmlIndexToBlockIndex(htmlPtr, htmlPtr->selBegin, &pBlock, &index); if( needUpdate || pBlock != htmlPtr->pSelStartBlock ){ needUpdate = 1; HtmlRedrawBlock(htmlPtr, htmlPtr->pSelStartBlock); htmlPtr->pSelStartBlock = pBlock; htmlPtr->selStartIndex = index; TestPoint(0); }else if( index != htmlPtr->selStartIndex ){ HtmlRedrawBlock(htmlPtr, pBlock); htmlPtr->selStartIndex = index; TestPoint(0); }else{ TestPoint(0); } if( htmlPtr->selBegin.p==0 ){ htmlPtr->selEnd.p = 0; TestPoint(0); }else{ TestPoint(0); } HtmlIndexToBlockIndex(htmlPtr, htmlPtr->selEnd, &pBlock, &index); if( needUpdate || pBlock != htmlPtr->pSelEndBlock ){ needUpdate = 1; HtmlRedrawBlock(htmlPtr, htmlPtr->pSelEndBlock); htmlPtr->pSelEndBlock = pBlock; htmlPtr->selEndIndex = index; TestPoint(0); }else if( index != htmlPtr->selEndIndex ){ HtmlRedrawBlock(htmlPtr, pBlock); htmlPtr->selEndIndex = index; TestPoint(0); }else{ TestPoint(0); } if( htmlPtr->pSelStartBlock && htmlPtr->pSelStartBlock==htmlPtr->pSelEndBlock && htmlPtr->selStartIndex > htmlPtr->selEndIndex ){ temp = htmlPtr->selStartIndex; htmlPtr->selStartIndex = htmlPtr->selEndIndex; htmlPtr->selEndIndex = temp; TestPoint(0); }else{ TestPoint(0); } if( needUpdate ){ UpdateSelection(htmlPtr); TestPoint(0); }else{ TestPoint(0); } } /* ** WIDGET selection set INDEX INDEX */ int HtmlSelectionSetCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlIndex selBegin, selEnd; HtmlLock(htmlPtr); if( HtmlGetIndex(htmlPtr, argv[3], &selBegin.p, &selBegin.i) ){ if( !HtmlUnlock(htmlPtr) ){ Tcl_AppendResult(interp,"malformed index: \"", argv[3], "\"", 0); } TestPoint(0); return TCL_ERROR; } if( HtmlIsDead(htmlPtr) ) return TCL_OK; if( HtmlGetIndex(htmlPtr, argv[4], &selEnd.p, &selEnd.i) ){ if( !HtmlUnlock(htmlPtr) ){ Tcl_AppendResult(interp,"malformed index: \"", argv[4], "\"", 0); } TestPoint(0); return TCL_ERROR; } if( HtmlUnlock(htmlPtr) ) return TCL_OK; htmlPtr->selBegin = selBegin; htmlPtr->selEnd = selEnd; HtmlUpdateSelection(htmlPtr,0); TestPoint(0); return TCL_OK; } /* ** WIDGET selection clear */ int HtmlSelectionClearCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ htmlPtr->pSelStartBlock = 0; htmlPtr->pSelEndBlock = 0; htmlPtr->selBegin.p = 0; htmlPtr->selEnd.p = 0; UpdateSelection(htmlPtr); TestPoint(0); return TCL_OK; } /* ** Recompute the position of the insertion cursor based on the ** position in htmlPtr->ins. */ void HtmlUpdateInsert(HtmlWidget *htmlPtr){ HtmlIndexToBlockIndex(htmlPtr, htmlPtr->ins, &htmlPtr->pInsBlock, &htmlPtr->insIndex); HtmlRedrawBlock(htmlPtr, htmlPtr->pInsBlock); if( htmlPtr->insTimer==0 ){ htmlPtr->insStatus = 0; HtmlFlashCursor(htmlPtr); TestPoint(0); }else{ TestPoint(0); } } /* ** WIDGET insert INDEX */ int HtmlInsertCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlIndex ins; if( argv[2][0]==0 ){ HtmlRedrawBlock(htmlPtr, htmlPtr->pInsBlock); htmlPtr->insStatus = 0; htmlPtr->pInsBlock = 0; htmlPtr->ins.p = 0; TestPoint(0); }else{ HtmlLock(htmlPtr); if( HtmlGetIndex(htmlPtr, argv[2], &ins.p, &ins.i) ){ if( !HtmlUnlock(htmlPtr) ){ Tcl_AppendResult(interp,"malformed index: \"", argv[2], "\"", 0); } TestPoint(0); return TCL_ERROR; } if( HtmlUnlock(htmlPtr) ) return TCL_OK; HtmlRedrawBlock(htmlPtr, htmlPtr->pInsBlock); htmlPtr->ins = ins; HtmlUpdateInsert(htmlPtr); TestPoint(0); } return TCL_OK; } /* ** WIDGET token list START END */ int HtmlTokenListCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlElement *pStart, *pEnd; int i; if( HtmlGetIndex(htmlPtr, argv[3], &pStart, &i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", argv[3], "\"", 0); return TCL_ERROR; } if( HtmlGetIndex(htmlPtr, argv[4], &pEnd, &i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", argv[4], "\"", 0); return TCL_ERROR; } if( pStart ){ HtmlTclizeList(interp,pStart,pEnd ? pEnd->base.pNext : 0); } return TCL_OK; } #ifdef DEBUG /* ** WIDGET debug dump START END */ int HtmlDebugDumpCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlElement *pStart, *pEnd; int i; if( HtmlGetIndex(htmlPtr, argv[3], &pStart, &i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", argv[3], "\"", 0); return TCL_ERROR; } if( HtmlGetIndex(htmlPtr, argv[4], &pEnd, &i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", argv[4], "\"", 0); return TCL_ERROR; } if( pStart ){ HtmlPrintList(pStart,pEnd ? pEnd->base.pNext : 0); } return TCL_OK; } /* ** WIDGET debug testpt FILENAME */ int HtmlDebugTestPtCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlTestPointDump(argv[3]); return TCL_OK; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlindex.c�����������������������������������������������������������������0000644�0001750�0001750�00000031373�07504443345�016221� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlindex.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines that deal with indexes ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <ctype.h> #include <tk.h> #include "htmlindex.h" /* ** Return a pointer to the Nth HtmlElement in the list. If there ** is no Nth element, return 0 if flag==0 and return either the first ** or last element (whichever is closest) if flag!=0 */ HtmlElement *HtmlTokenByIndex(HtmlWidget *htmlPtr, int N, int flag){ HtmlElement *p; int n; if( N > htmlPtr->nToken/2 ){ /* Start at the end and work back toward the beginning */ for(p=htmlPtr->pLast, n=htmlPtr->nToken; p; p=p->base.pPrev){ if( p->base.type!=Html_Block ){ if( n==N ){ TestPoint(0); break; } n--; TestPoint(0); }else{ TestPoint(0); } } }else{ /* Start at the beginning and work forward */ for(p=htmlPtr->pFirst; p; p = p->base.pNext){ if( p->base.type!=Html_Block ){ N--; if( N<=0 ){ TestPoint(0); break; } }else{ TestPoint(0); } } } return p; } /* ** Return the token number for the given HtmlElement */ int HtmlTokenNumber(HtmlElement *p){ int n = 0; while( p ){ if( p->base.type!=Html_Block ){ TestPoint(0); n++; }else{ TestPoint(0); } p = p->base.pPrev; } return n; } /* ** Find the maximum index for the given token */ static void maxIndex(HtmlElement *p, int *pIndex){ if( p==0 ){ *pIndex = 0; TestPoint(0); }else{ switch( p->base.type ){ case Html_Text: *pIndex = p->base.count-1; TestPoint(0); break; case Html_Space: if( p->base.style.flags & STY_Preformatted ){ *pIndex = p->base.count-1; TestPoint(0); }else{ *pIndex = 0; TestPoint(0); } break; default: *pIndex = 0; TestPoint(0); break; } } } /* ** Given a Block and an x coordinate, find the Index of the character ** that is closest to the given x coordinate. ** ** The x-coordinate might specify a point to the left of the block, ** in which case the procedure returns the first token and a character ** index of 0. Or the x-coordinate might specify a point to the right ** of the block, in which case the last token is returned with an index ** equal to its last character. */ static void FindIndexInBlock( HtmlWidget *htmlPtr, /* The widget */ HtmlBlock *pBlock, /* The block */ int x, /* The x coordinate */ HtmlElement **ppToken, /* Write the closest token here */ int *pIndex /* Write the charater index in ppToken here */ ){ HtmlElement *p; Tk_Font font; int len; int n; p = pBlock->base.pNext; HtmlLock(htmlPtr); font = HtmlGetFont(htmlPtr, p->base.style.font); if( HtmlUnlock(htmlPtr) ){ *ppToken = p; *pIndex = 0; return; } if( x <= pBlock->left ){ *ppToken = p; *pIndex = 0; TestPoint(0); return; }else if( x>= pBlock->right ){ *ppToken = p; *pIndex = 0; while( p && p->base.type!=Html_Block ){ *ppToken = p; p = p->base.pNext; TestPoint(0); } p = *ppToken; if( p && p->base.type==Html_Text ){ *pIndex = p->base.count - 1; TestPoint(0); }else{ TestPoint(0); } return; } if( pBlock->n==0 ){ *ppToken = p; *pIndex = 0; TestPoint(0); }else{ TestPoint(0); } n = Tk_MeasureChars(font, pBlock->z, pBlock->n, x - pBlock->left, 0, &len); *pIndex = 0; *ppToken = 0; while( p && n>=0 ){ switch( p->base.type ){ case Html_Text: if( n<p->base.count ){ *pIndex = n; TestPoint(0); }else{ *pIndex = p->base.count - 1; TestPoint(0); } *ppToken = p; n -= p->base.count; break; case Html_Space: if( p->base.style.flags & STY_Preformatted ){ if( n<p->base.count ){ *pIndex = n; TestPoint(0); }else{ *pIndex = p->base.count - 1; TestPoint(0); } *ppToken = p; n -= p->base.count; }else{ *pIndex = 0; *ppToken = p; n--; TestPoint(0); } break; default: TestPoint(0); break; } if( p ){ p = p->base.pNext; TestPoint(0); }else{ TestPoint(0); } } } /* ** Convert an Element-based index into a Block-based index. ** ** In other words, given a pointer to an element and an index ** of a particular character within that element, compute a ** pointer to the HtmlBlock used to display that character and ** the index in the HtmlBlock of the character. */ void HtmlIndexToBlockIndex( HtmlWidget *htmlPtr, /* The widget */ HtmlIndex sIndex, /* The index to be translated */ HtmlBlock **ppBlock, /* Write the corresponding block here */ int *piIndex /* Write the block index here */ ){ int n = sIndex.i; HtmlElement *p; if( sIndex.p==0 ){ *ppBlock = 0; *piIndex = 0; TestPoint(0); return; } p = sIndex.p->base.pPrev; while( p && p->base.type!=Html_Block ){ switch( p->base.type ){ case Html_Text: n += p->base.count; TestPoint(0); break; case Html_Space: if( p->base.style.flags & STY_Preformatted ){ n += p->base.count; TestPoint(0); }else{ n++; TestPoint(0); } break; default: TestPoint(0); break; } p = p->base.pPrev; } if( p ){ *ppBlock = &p->block; *piIndex = n; TestPoint(0); return; } for(p=sIndex.p; p && p->base.type!=Html_Block; p=p->base.pNext){ TestPoint(0); } *ppBlock = &p->block; *piIndex = 0; } /* ** Given a base index name (without any modifiers) return a pointer ** to the token described, and the character within that token. ** ** Valid input forms include: ** ** N.M Token number N (with numbering starting at 1) and ** character number M (with numbering starting at 0). ** ** end The end of all text ** ** N.last Last character of token number N. ** ** sel.first First character of the selection. ** ** sel.last Last character of the selection. ** ** ins The character holding the insertion cursor. ** ** @X,Y The character a location X,Y of the clipping window. ** ** Zero is returned if we are successful and non-zero if there is ** any kind of error. ** ** If the given token doesn't exist (for example if there are only 10 ** tokens and 11.5 is requested) then *ppToken is left pointing to NULL. ** But the function still returns 0 for success. */ static int DecodeBaseIndex( HtmlWidget *htmlPtr, /* The HTML widget we are dealing with */ const char *zBase, /* The base index string */ HtmlElement **ppToken, /* Write the pointer to the token here */ int *pIndex /* Write the character offset here */ ){ int x, y; int n; int i; HtmlElement *p; HtmlBlock *pBlock; HtmlBlock *pNearby; int dist = 1000000; int rc = 0; while( isspace(*zBase) ){ TestPoint(0); zBase++; } switch( *zBase ){ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = sscanf(zBase,"%d.%d",&x,&y); if( n>0 ){ p = *ppToken = HtmlTokenByIndex(htmlPtr, x, 0); TestPoint(0); }else{ TestPoint(0); } if( n==2 ){ *pIndex = y; TestPoint(0); }else{ for(i=1; isdigit(zBase[i]); i++){ TestPoint(0); } if( zBase[i]==0 ){ *pIndex = 0; TestPoint(0); }else if( strcmp(&zBase[i],".last")==0 ){ maxIndex(p,pIndex); TestPoint(0); }else{ rc = 1; TestPoint(0); } } break; case 'e': if( strcmp(zBase,"end")==0 ){ p = *ppToken = htmlPtr->pLast; maxIndex(p,pIndex); TestPoint(0); }else{ rc = 1; TestPoint(0); } break; case 's': if( strcmp(zBase,"sel.first")==0 ){ *ppToken = htmlPtr->selBegin.p; *pIndex = htmlPtr->selBegin.i; TestPoint(0); }else if( strcmp(zBase,"sel.last")==0 ){ *ppToken = htmlPtr->selEnd.p; *pIndex = htmlPtr->selEnd.i; TestPoint(0); }else{ rc = 1; TestPoint(0); } break; case 'i': if( strcmp(zBase,"insert")==0 ){ *ppToken = htmlPtr->ins.p; *pIndex = htmlPtr->ins.i; TestPoint(0); }else{ rc = 1; TestPoint(0); } break; case '@': n = sscanf(zBase,"@%d,%d",&x,&y); if( n!=2 ){ rc = 1; TestPoint(0); break; } x += htmlPtr->xOffset; y += htmlPtr->yOffset; pNearby = 0; *ppToken = htmlPtr->pLast; *pIndex = 0; for(pBlock=htmlPtr->firstBlock; pBlock; pBlock=pBlock->pNext){ int dotest; if( pBlock->n==0 ){ switch( pBlock->base.pNext->base.type ){ case Html_LI: case Html_IMG: case Html_INPUT: case Html_TEXTAREA: case Html_SELECT: dotest = 1; TestPoint(0); break; default: dotest = 0; TestPoint(0); break; } }else{ dotest = 1; TestPoint(0); } if (dotest){ if( pBlock->top <= y && pBlock->bottom >= y ){ if( pBlock->left > x ){ if( pBlock->left - x < dist ){ dist = pBlock->left - x; pNearby = pBlock; TestPoint(0); }else{ TestPoint(0); } }else if( pBlock->right < x ){ if( x - pBlock->right < dist ){ dist = x - pBlock->right; pNearby = pBlock; TestPoint(0); }else{ TestPoint(0); } }else{ HtmlLock(htmlPtr); FindIndexInBlock(htmlPtr, pBlock, x, ppToken, pIndex); if( HtmlUnlock(htmlPtr) ) return 1; TestPoint(0); break; } }else{ int distY; int distX; if( pBlock->bottom < y ){ distY = y - pBlock->bottom; TestPoint(0); }else{ distY = pBlock->top - y; TestPoint(0); } if( pBlock->left > x ){ distX = pBlock->left - x; TestPoint(0); }else if( pBlock->right < x ){ distX = x - pBlock->right; TestPoint(0); }else{ distX = 0; TestPoint(0); } if( distX + 4*distY < dist ){ dist = distX + 4*distY; pNearby = pBlock; TestPoint(0); }else{ TestPoint(0); } } } } if( pBlock==0 ){ if( pNearby ){ HtmlLock(htmlPtr); FindIndexInBlock(htmlPtr, pNearby, x, ppToken, pIndex); if( HtmlUnlock(htmlPtr) ) return 1; TestPoint(0); }else{ TestPoint(0); } }else{ TestPoint(0); } break; default: rc = 1; TestPoint(0); break; } return rc; } /* ** This routine decodes a complete index specification. A complete ** index consists of the base specification followed by modifiers. */ int HtmlGetIndex( HtmlWidget *htmlPtr, /* The widget */ char *zIndex, /* Complete text of the index spec */ HtmlElement **ppToken, /* Write the pointer to the token here */ int *pIndex /* Write the character offset here */ ){ TestPoint(0); return DecodeBaseIndex(htmlPtr, zIndex, ppToken, pIndex); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/html.h����������������������������������������������������������������������0000644�0001750�0001750�00000123343�07504443345�015175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** Structures and typedefs used by the HTML widget ** $Revision: 1.1.1.1 $ ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ /* ** Debug must be turned on for testing to work. */ #define DEBUG 1 /* ** Version information for the package mechanism. */ #define HTML_PKGNAME "Tkhtml" #define HTML_PKGVERSION "0.0" /* ** Sanity checking macros. */ #ifdef DEBUG #define HtmlAssert(X) \ if(!(X)){ \ fprintf(stderr,"Assertion failed on line %d of %s\n",__LINE__,__FILE__); \ } #define HtmlCantHappen \ fprintf(stderr,"Can't happen on line %d of %s\n",__LINE__,__FILE__); #else #define HtmlAssert(X) #define HtmlCantHappen #endif /* ** The TRACE macro is used to print internal information about the ** HTML layout engine during testing and debugging. The amount of ** information printed is governed by a global variable named ** HtmlTraceMask. If bits in the first argument to the TRACE macro ** match any bits in HtmlTraceMask variable, then the trace message ** is printed. ** ** All of this is completely disabled, of course, if the DEBUG macro ** is not defined. */ #ifdef DEBUG # define TRACE_INDENT printf("%*s",HtmlDepth-3,"") # define TRACE(Flag, Args) \ if( (Flag)&HtmlTraceMask ){ \ TRACE_INDENT; printf Args; fflush(stdout); \ } # define TRACE_PUSH(Flag) if( (Flag)&HtmlTraceMask ){ HtmlDepth+=3; } # define TRACE_POP(Flag) if( (Flag)&HtmlTraceMask ){ HtmlDepth-=3; } #else # define TRACE_INDENT # define TRACE(Flag, Args) # define TRACE_PUSH(Flag) # define TRACE_POP(Flag) #endif /* ** Bitmasks for the HtmlTraceMask global variable */ #define HtmlTrace_Table1 0x00000001 #define HtmlTrace_Table2 0x00000002 #define HtmlTrace_Table3 0x00000004 #define HtmlTrace_Table4 0x00000008 #define HtmlTrace_Table5 0x00000010 #define HtmlTrace_Table6 0x00000020 #define HtmlTrace_GetLine 0x00000100 #define HtmlTrace_GetLine2 0x00000200 #define HtmlTrace_FixLine 0x00000400 #define HtmlTrace_BreakMarkup 0x00001000 #define HtmlTrace_Style 0x00002000 #define HtmlTrace_Input1 0x00004000 /* ** Macros to allocate and free memory. */ #define HtmlAlloc(A) ((void*)Tcl_Alloc(A)) #define HtmlFree(A) Tcl_Free((char*)(A)) #define HtmlRealloc(A,B) ((void*)Tcl_Realloc((A),(B))) /* ** Various data types. This code is designed to run on a modern ** cached architecture where the CPU runs a lot faster than the ** memory bus. Hence we try to pack as much data into as small a space ** as possible so that it is more likely to fit in cache. The ** extra CPU instruction or two needed to unpack the data is not ** normally an issue since we expect the speed of the memory bus ** to be the limiting factor. */ typedef unsigned char Html_u8; /* 8-bit unsigned integer */ typedef short Html_16; /* 16-bit signed integer */ typedef unsigned short Html_u16; /* 16-bit unsigned integer */ typedef int Html_32; /* 32-bit signed integer */ /* ** An instance of the following structure is used to record style ** information on each Html element. */ struct HtmlStyle { unsigned int font : 6; /* Font to use for display */ unsigned int color : 4; /* Foreground color */ signed int subscript : 4; /* Positive for <sup>, negative for <sub> */ unsigned int align : 2; /* Horizontal alignment */ unsigned int bgcolor : 4; /* Background color */ unsigned int flags : 12; /* the STY_ flags below */ } /* ** We allow 8 different font families: Normal, Bold, Italic and ** Bold-Italic in either variable or constant width. ** Within each family there can be up to 7 font sizes from 1 ** (the smallest) up to 7 (the largest). Hence, the widget can use ** a maximum of 56 fonts. The ".font" field of the style is an integer ** between 0 and 55 which indicates which font to use. */ #define N_FONT_FAMILY 8 #define N_FONT_SIZE 7 #define N_FONT (N_FONT_FAMILY*N_FONT_SIZE) #define NormalFont(X) (X) #define BoldFont(X) ((X)+N_FONT_SIZE) #define ItalicFont(X) ((X)+2*N_FONT_SIZE) #define CWFont(X) ((X)+4*N_FONT_SIZE) #define FontSize(X) ((X)%N_FONT_SIZE) #define FontFamily(X) (((X)/N_FONT_SIZE)*N_FONT_SIZE) #define FONT_Any -1 #define FONT_Default 3 #define FontSwitch(Size, Bold, Italic, Cw) \ ((Size)+(Bold+(Italic)*2+(Cw)*4)*N_FONT_SIZE) /* ** Macros for manipulating the fontValid bitmap of an HtmlWidget structure. */ #define FontIsValid(H,I) (((H)->fontValid[(I)>>3] & (1<<((I)&3)))!=0) #define FontSetValid(H,I) ((H)->fontValid[(I)>>3] |= (1<<((I)&3))) #define FontClearValid(H,I) ((H)->fontValid[(I)>>3] &= ~(1<<((I)&3))) /* ** Information about available colors. ** ** The widget will use at most N_COLOR colors. 4 of these colors ** are predefined. The rest are user selectable by options to ** various markups. (Ex: <font color=red>) ** ** All colors are stored in the apColor[] array of the main widget ** structure. The ".color" field of the HtmlStyle is an integer ** between 0 and N_COLOR-1 which indicates which of these colors ** to use. */ #define N_COLOR 16 /* Total number of colors */ #define COLOR_Normal 0 /* Index for normal color (black) */ #define COLOR_Unvisited 1 /* Index for unvisited hyperlinks */ #define COLOR_Visited 2 /* Color for visited hyperlinks */ #define COLOR_Selection 3 /* Background color for the selection */ #define COLOR_Background 4 /* Default background color */ #define N_PREDEFINED_COLOR 5 /* Number of predefined colors */ /* ** The "align" field of the style determines how text is justified ** horizontally. ALIGN_None means that the alignment is not specified. ** (It should probably default to ALIGN_Left in this case.) */ #define ALIGN_Left 1 #define ALIGN_Right 2 #define ALIGN_Center 3 #define ALIGN_None 0 /* ** Possible value of the "flags" field of HtmlStyle are shown below. ** ** STY_Preformatted If set, the current text occurred within ** <pre>..</pre> ** ** STY_StrikeThru Draw a solid line thru the middle of this text. ** ** STY_Underline This text should drawn with an underline. ** ** STY_NoBreak This text occurs within <nobr>..</nobr> ** ** STY_Anchor This text occurs within <a href=X>..</a>. ** ** STY_DT This text occurs within <dt>..</dt>. ** ** STY_Invisible This text should not appear in the main HTML ** window. (For example, it might be within ** <title>..</title> or <marquee>..</marquee>.) */ #define STY_Preformatted 0x001 #define STY_StrikeThru 0x002 #define STY_Underline 0x004 #define STY_NoBreak 0x008 #define STY_Anchor 0x010 #define STY_DT 0x020 #define STY_Invisible 0x040 #define STY_FontMask (STY_StrikeThru|STY_Underline) /* ** The first thing done with input HTML text is to parse it into ** HtmlElements. All sizing and layout is done using these elements, ** so this is a very important structure. ** ** Elements are designed so that the common ones (Text and Space) ** require as little storage as possible, in order to increase ** the chance of memory cache hits. (Turns out I didn't do a ** very good job of this. This widget is a pig for memory. But ** the speed is good, so I'm not going to change it right now...) ** ** Some elements require more memory than Text and Space (ex: <IMG>). ** An HtmlElement is therefore represented as a union of many other ** structures all of different sizes. That way we can have a pointer ** to a generic element without having to worry about how big that ** element is. The ".base.type" field (which is found in all elements) ** will tell us what type of element we are dealing with. ** ** NOTE: This trick will only work on compilers that align all elements ** of a union to the lowest memory address in that union. This is true ** for every C compiler I've ever seen, but isn't guarenteed for ANSI-C. */ union HtmlElement { HtmlElement *pNext; HtmlBaseElement base; HtmlTextElement text; HtmlSpaceElement space; HtmlMarkupElement markup; HtmlCell cell; HtmlTable table; HtmlRef ref; HtmlLi li; HtmlListStart list; HtmlImageMarkup image; HtmlInput input; HtmlForm form; HtmlHr hr; HtmlAnchor anchor; HtmlScript script; HtmlBlock block; }; /* ** Every element contains at least this much information: */ struct HtmlBaseElement { HtmlElement *pNext; /* Next input token in a list of them all */ HtmlElement *pPrev; /* Previous token in a list of them all */ HtmlStyle style; /* The rendering style for this token */ Html_u8 type; /* The token type. */ Html_u8 flags; /* The HTML_ flags below */ Html_16 count; /* Various uses, depending on "type" */ }; /* ** Bitmasks for the "flags" field of the HtmlBaseElement */ #define HTML_Visible 0x01 /* This element produces "ink" */ #define HTML_NewLine 0x02 /* type==Html_Space and ends with newline */ #define HTML_Selected 0x04 /* Some or all of this Html_Block is selected */ /* Used by Html_Block elements only. */ /* ** Each text element holds additional information as show here. Notice ** that extra space is allocated so that zText[] will be large enough ** to hold the complete text of the element. X and y coordinates are ** relative to the virtual canvas. The y coordinate refers to the ** baseline. */ struct HtmlTextElement { HtmlBaseElement base; /* All the base information */ Html_32 y; /* y coordinate where text should be rendered */ Html_16 x; /* x coordinate where text should be rendered */ Html_16 w; /* width of this token in pixels */ Html_u8 ascent; /* height above the baseline */ Html_u8 descent; /* depth below the baseline */ Html_u8 spaceWidth; /* Width of one space in the current font */ char zText[1]; /* Text for this element. Null terminated */ }; /* ** Each space element is represented like this: */ struct HtmlSpaceElement { HtmlBaseElement base; /* All the base information */ Html_16 w; /* Width of a single space in current font */ Html_u8 ascent; /* height above the baseline */ Html_u8 descent; /* depth below the baseline */ }; /* ** Most markup uses this structure. Some markup extends this structure ** with additional information, but most use it as a base, at the very ** least. ** ** If the markup doesn't have arguments (the "count" field of ** HtmlBaseElement is 0) then the extra "argv" field of this structure ** is not allocated and should not be used. */ struct HtmlMarkupElement { HtmlBaseElement base; char **argv; }; /* Each <td> or <th> markup is represented by an instance of the ** following structure. ** ** Drawing for a cell is a sunken 3D border with the border width given ** by the borderWidth field in the associated <table> structure. */ struct HtmlCell { HtmlMarkupElement markup; Html_16 rowspan; /* Number of rows spanned by this cell */ Html_16 colspan; /* Number of columns spanned by this cell */ Html_16 x; /* X coordinate of left edge of border */ Html_16 w; /* Width of the border */ Html_32 y; /* Y coordinate of top of border indentation */ Html_32 h; /* Height of the border */ HtmlElement *pTable; /* Pointer back to the <table> */ HtmlElement *pEnd; /* Element that ends this cell */ }; /* ** The maximum number of columns allowed in a table. Any columns beyond ** this number are ignored. */ #define HTML_MAX_COLUMNS 40 /* ** This structure is used for each <table> element. ** ** In the minW[] and maxW[] arrays, the [0] element is the overall ** minimum and maximum width, including cell padding, spacing and ** the "hspace". All other elements are the minimum and maximum ** width for the contents of individual cells without any spacing or ** padding. */ struct HtmlTable { HtmlMarkupElement markup; Html_u8 borderWidth; /* Width of the border */ Html_u8 nCol; /* Number of columns */ Html_u16 nRow; /* Number of rows */ Html_32 y; /* top edge of table border */ Html_32 h; /* height of the table border */ Html_16 x; /* left edge of table border */ Html_16 w; /* width of the table border */ int minW[HTML_MAX_COLUMNS+1]; /* minimum width of each column */ int maxW[HTML_MAX_COLUMNS+1]; /* maximum width of each column */ }; /* This structure is used for </table>, </td>, <tr>, </tr> ** and </th> elements. It points back to the <table> element ** that began the table. It is also used by </a> to point back ** to the original <a>. I'll probably think of other uses before ** all is said and done... */ struct HtmlRef { HtmlMarkupElement markup; HtmlElement *pOther; /* Pointer to some other Html element */ }; /* ** An instance of the following structure is used to represent ** each <LI> markup. */ struct HtmlLi { HtmlMarkupElement markup; Html_u8 type; /* What type of list is this? */ Html_u8 ascent; /* height above the baseline */ Html_u8 descent; /* depth below the baseline */ Html_16 cnt; /* Value for this element (if inside <OL>) */ Html_16 x; /* X coordinate of the bullet */ Html_32 y; /* Y coordinate of the bullet */ }; /* ** The .type field of an HtmlLi or HtmlListStart structure can take on ** any of the following values to indicate what type of bullet to draw. ** The value in HtmlLi will take precedence over the value in HtmlListStart ** if the two values differ. */ #define LI_TYPE_Undefined 0 /* If in HtmlLi, use the HtmlListStart value */ #define LI_TYPE_Bullet1 1 /* A solid circle */ #define LI_TYPE_Bullet2 2 /* A hollow circle */ #define LI_TYPE_Bullet3 3 /* A hollow square */ #define LI_TYPE_Enum_1 4 /* Arabic numbers */ #define LI_TYPE_Enum_A 5 /* A, B, C, ... */ #define LI_TYPE_Enum_a 6 /* a, b, c, ... */ #define LI_TYPE_Enum_I 7 /* Capitalized roman numerals */ #define LI_TYPE_Enum_i 8 /* Lower-case roman numerals */ /* ** An instance of this structure is used for <UL> or <OL> ** markup. */ struct HtmlListStart { HtmlMarkupElement markup; Html_u8 type; /* One of the LI_TYPE_ defines above */ Html_u8 compact; /* True if the COMPACT flag is present */ Html_u16 cnt; /* Next value for <OL> */ Html_u16 width; /* How much space to allow for indentation */ HtmlElement *pPrev; /* Next higher level list, or NULL */ }; /* ** Information about each image on the HTML widget is held in an ** instance of the following structure. A pointer to this structure ** is the clientData for the image change callback. All image structures ** are held on a list attached to the main widget structure. ** ** This structure is NOT an element. The <IMG> element is represented ** by an HtmlImageMarkup structure below. There is one HtmlImageMarkup ** for each <IMG> in the source HTML. There is one of these structures ** for each unique image loaded. (If two <IMG> specify the same image, ** there are still two HtmlImageMarkup structures but only one ** HtmlImage structure that is shared between them.) */ struct HtmlImage { HtmlWidget *htmlPtr; /* The owner of this image */ Tk_Image image; /* The Tk image token */ Html_32 w; /* Requested width of this image (0 if none) */ Html_32 h; /* Requested height of this image (0 if none) */ char *zUrl; /* The URL for this image. */ char *zWidth, *zHeight; /* Width and height in the <img> markup. */ HtmlImage *pNext; /* Next image on the list */ HtmlElement *pList; /* List of all <IMG> markups that use this ** same image */ }; /* Each <img> markup is represented by an instance of the ** following structure. ** ** If pImage==0, then we use the alternative text in zAlt. */ struct HtmlImageMarkup { HtmlMarkupElement markup; Html_u8 align; /* Alignment. See IMAGE_ALIGN_ defines below */ Html_u8 textAscent; /* Ascent of text font in force at the <IMG> */ Html_u8 textDescent; /* Descent of text font in force at the <IMG> */ Html_u8 redrawNeeded; /* Need to redraw this image because the image ** content changed. */ Html_16 h; /* Actual height of the image */ Html_16 w; /* Actual width of the image */ Html_16 ascent; /* How far image extends above "y" */ Html_16 descent; /* How far image extends below "y" */ Html_16 x; /* X coordinate of left edge of the image */ Html_32 y; /* Y coordinate of image baseline */ char *zAlt; /* Alternative text */ HtmlImage *pImage; /* Corresponding HtmlImage structure */ HtmlElement *pNext; /* Next markup using the same HtmlImage structure */ }; /* ** Allowed alignments for images. These represent the allowed arguments ** to the "align=" field of the <IMG> markup. */ #define IMAGE_ALIGN_Bottom 0 #define IMAGE_ALIGN_Middle 1 #define IMAGE_ALIGN_Top 2 #define IMAGE_ALIGN_TextTop 3 #define IMAGE_ALIGN_AbsMiddle 4 #define IMAGE_ALIGN_AbsBottom 5 #define IMAGE_ALIGN_Left 6 #define IMAGE_ALIGN_Right 7 /* ** All kinds of form markup, including <INPUT>, <TEXTAREA> and <SELECT> ** are represented by instances of the following structure. ** ** (later...) We also use this for the <APPLET> markup. That way, ** the window we create for an <APPLET> responds to the HtmlMapControls() ** and HtmlUnmapControls() function calls. For an <APPLET>, the ** pForm field is NULL. (Later still...) <EMBED> works just like ** <APPLET> so it uses this structure too. */ struct HtmlInput { HtmlMarkupElement markup; HtmlElement *pForm; /* The <FORM> to which this belongs */ HtmlElement *pNext; /* Next element in a list of all input elements */ Tk_Window tkwin; /* The window that implements this control */ HtmlWidget *htmlPtr; /* The whole widget. Needed by geometry callbacks */ HtmlElement *pEnd; /* End tag for <TEXTAREA>, etc. */ Html_32 y; /* Baseline for this input element */ Html_u16 x; /* Left edge */ Html_u16 w, h; /* Width and height of this control */ Html_u8 padLeft; /* Extra padding on left side of the control */ Html_u8 align; /* One of the IMAGE_ALIGN_xxx types */ Html_u8 textAscent; /* Ascent for the current font */ Html_u8 textDescent; /* descent for the current font */ Html_u8 type; /* What type of input is this? */ Html_u8 sized; /* True if this input has been sized already */ Html_u16 cnt; /* Used to derive widget name. 0 if no widget */ }; /* ** An input control can be one of the following types. See the ** comment about <APPLET> on the HtmlInput structure insight into ** INPUT_TYPE_Applet. */ #define INPUT_TYPE_Unknown 0 #define INPUT_TYPE_Checkbox 1 #define INPUT_TYPE_File 2 #define INPUT_TYPE_Hidden 3 #define INPUT_TYPE_Image 4 #define INPUT_TYPE_Password 5 #define INPUT_TYPE_Radio 6 #define INPUT_TYPE_Reset 7 #define INPUT_TYPE_Select 8 #define INPUT_TYPE_Submit 9 #define INPUT_TYPE_Text 10 #define INPUT_TYPE_TextArea 11 #define INPUT_TYPE_Applet 12 /* ** There can be multiple <FORM> entries on a single HTML page. ** Each one must be given a unique number for identification purposes, ** and so we can generate unique state variable names for radiobuttons, ** checkbuttons, and entry boxes. */ struct HtmlForm { HtmlMarkupElement markup; Html_u16 id; /* Unique number assigned to this form */ }; /* ** Information used by a <HR> markup */ struct HtmlHr { HtmlMarkupElement markup; Html_32 y; /* Baseline for this input element */ Html_u16 x; /* Left edge */ Html_u16 w, h; /* Width and height of this control */ Html_u8 is3D; /* Is it drawn 3D? */ }; /* ** Information used by a <A> markup */ struct HtmlAnchor { HtmlMarkupElement markup; Html_32 y; /* Top edge for this element */ }; /* ** Information about the <SCRIPT> markup. The parser treats <SCRIPT> ** specially. All text between <SCRIPT> and </SCRIPT> is captured and ** is pointed to by the zScript field of this structure. ** ** Note that zScript is not null-terminated. Instead, zScript just ** points to a spot in the zText field of the HtmlWidget structure. ** The nScript field determines how long the script is. */ struct HtmlScript { HtmlMarkupElement markup; char *zScript; /* Complete text of this script */ int nScript; /* Number of characters of text */ } /* ** A block is a single unit of display information. This can be ** one or more text elements, or the border of table, or an ** image, etc. ** ** Blocks are used to improve display speed and to improve the ** speed of linear searchs through the token list. A single ** block will typically contain enough information to display ** a dozen or more Text and Space elements all with a single ** call to Tk_DrawChars(). The blocks are linked together on ** their own list, so we can search them much faster then elements ** (since there are fewer of them.) ** ** Of course, you can construct pathological HTML that has as ** many Blocks as it has normal tokens. But you haven't lost ** anything. Using blocks just speeds things up in the common ** case. ** ** Much of the information needed for display is held in the ** original HtmlElement structures. "base.pNext" points to the first ** structure in the list which can be used to find the "style" ** "x" and "y". ** ** If n==0, then "base.pNext" might point to a special HtmlElement that ** defines some other kind of drawing, like <LI> or <IMG> or <INPUT>. */ struct HtmlBlock { HtmlBaseElement base; /* Superclass. Must be first */ char *z; /* Space to hold text when n>0 */ int top, bottom; /* Extremes of y coordinates */ Html_u16 left, right; /* Left and right boundry of this object */ Html_u16 n; /* Number of characters in z[] */ HtmlBlock *pPrev, *pNext; /* Linked list of all Blocks */ }; /* ** Linux doesn't have a stricmp() function. */ #ifndef HAVE_STRICMP # define stricmp strcasecmp # define strnicmp strncasecmp #endif /* ** A stack of these structures is used to keep track of nested font and ** style changes. This allows us to easily revert to the previous style ** when we encounter and end-tag like </em> or </h3>. ** ** This stack is used to keep track of the current style while walking ** the list of elements. After all elements have been assigned a style, ** the information in this stack is no longer used. */ struct HtmlStyleStack { HtmlStyleStack *pNext; /* Next style on the stack */ int type; /* A markup that ends this style. Ex: Html_EndEM */ HtmlStyle style; /* The currently active style. */ } /* ** A stack of the following structures is used to remember the ** left and right margins within a layout context. */ struct HtmlMargin { int indent; /* Size of the current margin */ int bottom; /* Y value at which this margin expires */ int tag; /* Markup that will cancel this margin */ HtmlMargin *pNext; /* Previous margin */ }; /* ** How much space (in pixels) used for a single level of indentation due ** to a <UL> or <DL> or <BLOCKQUOTE>, etc. */ #define HTML_INDENT 36 /* ** A layout context holds all state information used by the layout ** engine. */ struct HtmlLayoutContext { HtmlWidget *htmlPtr; /* The html widget undergoing layout */ HtmlElement *pStart; /* Start of elements to layout */ HtmlElement *pEnd; /* Stop when reaching this element */ int headRoom; /* Extra space wanted above this line */ int top; /* Absolute top of drawing area */ int bottom; /* Bottom of previous line */ int left, right; /* Left and right extremes of drawing area */ int pageWidth; /* Width of the layout field, including ** the margins */ int maxX, maxY; /* Maximum X and Y values of paint */ HtmlMargin *leftMargin; /* Stack of left margins */ HtmlMargin *rightMargin; /* Stack of right margins */ }; /* ** With 28 different fonts and 16 colors, we could in principle have ** as many as 448 different GCs. But in practice, a single page of ** HTML will typically have much less than this. So we won't try to ** keep all GCs on hand. Instead, We'll keep around the most recently ** used GCs and allocate new ones as necessary. ** ** The following structure is used to build a cache of GCs in the ** main widget structure. */ #define N_CACHE_GC 16 struct GcCache { GC gc; /* The graphics context */ Html_u8 font; /* Font used for this context */ Html_u8 color; /* Color used for this context */ Html_u8 index; /* Index used for LRU replacement */ }; /* ** An HtmlIndex is a reference to a particular character within a ** particular Text or Space token. */ struct HtmlIndex { HtmlElement *p; /* The token containing the character */ int i; /* Index of the character */ }; /* ** A single instance of the following structure (together with various ** other structures to which this structure points) contains complete ** state information for a single HTML widget. The clientData for ** the widget command is a pointer to this structure. ** ** The HTML widget is really a mega-widget. It consists of two nested ** windows. The outer window (tkwin) contains the focus highlight border, ** the 3D border and the padding between the border and the text. All ** text that results from the HTML is drawn into the clipping window ** (clipwin). The clipping window is a child of the main ** window and has the name "x". We have to use a clipping window so ** that subwindows required by <FORM> will be clipped properly and won't ** overlap with the borders. ** ** Two primary coordinate systems are used in this widget. ** ** Window coordinates In this system, (0,0) is the upper left-hand ** corner of the clipping window. This coordinates ** apply only to objects which is visible on screen. ** ** Virtual canvas The virtual canvas is an imaginary canvas holding ** the entire document. Typically, part of the ** virtual canvas will show thru the clipping ** window to become visible. The mapping from ** window to virtual canvas coordinates is ** governed by the "xOffset" and "yOffset" fields ** of the widget structure. ** ** */ struct HtmlWidget { Tk_Window tkwin; /* The main window for this widget */ Tk_Window clipwin; /* The clipping window in which all text is ** rendered. */ char *zClipwin; /* Name of the clipping window. */ Display *display; /* The X11 Server that contains tkwin */ Tcl_Interp *interp; /* The interpreter in which the widget lives */ char *zCmdName; /* Name of the command */ HtmlElement *pFirst; /* First HTML token on a list of them all */ HtmlElement *pLast; /* Last HTML token on the list */ int nToken; /* Number of HTML tokens on the list. * Html_Block tokens don't count. */ HtmlElement *lastSized; /* Last HTML element that has been sized */ HtmlElement *nextPlaced; /* Next HTML element that needs to be * positioned on canvas. */ HtmlBlock *firstBlock; /* List of all HtmlBlock tokens */ HtmlBlock *lastBlock; /* Last HtmlBlock in the list */ HtmlElement *firstInput; /* First <INPUT> element */ HtmlElement *lastInput; /* Last <INPUT> element */ int nInput; /* The number of <INPUT> elements */ int nForm; /* The number of <FORM> elements */ int varId; /* Used to construct a unique name for a ** global array used by <INPUT> elements */ /* * Information about the selected region of text */ HtmlIndex selBegin; /* Start of the selection */ HtmlIndex selEnd; /* End of the selection */ HtmlBlock *pSelStartBlock; /* Block in which selection starts */ Html_16 selStartIndex; /* Index in pSelStartBlock of first selected * character */ Html_16 selEndIndex; /* Index of last selecte char in pSelEndBlock */ HtmlBlock *pSelEndBlock; /* Block in which selection ends */ /* * Information about the insertion cursor */ int insOnTime; /* How long the cursor states one (millisec) */ int insOffTime; /* How long it is off (milliseconds) */ int insStatus; /* Is it visible? */ Tcl_TimerToken insTimer; /* Timer used to flash the insertion cursor */ HtmlIndex ins; /* The insertion cursor position */ HtmlBlock *pInsBlock; /* The HtmlBlock containing the cursor */ int insIndex; /* Index in pInsBlock of the cursor */ /* * The following fields hold state information used by * the tokenizer. */ char *zText; /* Complete text of the unparsed HTML */ int nText; /* Number of characters in zText */ int nAlloc; /* Space allocated for zText */ int nComplete; /* How much of zText has actually been * converted into tokens */ int iCol; /* The column in which zText[nComplete] * occurs. Used to resolve tabs in input */ int iPlaintext; /* If not zero, this is the token type that * caused us to go into plaintext mode. One * of Html_PLAINTEXT, Html_LISTING or * Html_XMP */ HtmlScript *pScript; /* <SCRIPT> currently being parsed */ char *zHandler[Html_TypeCount]; /* If not NULL, this is a TCL routine that * is used to process tokens of the given * type */ /* * These fields hold state information used by the HtmlAddStyle routine. * We have to store this state information here since HtmlAddStyle * operates incrementally. This information must be carried from * one incremental execution to the next. */ HtmlStyleStack *styleStack; /* The style stack */ int paraAlignment; /* Justification associated with <p> */ int rowAlignment; /* Justification associated with <tr> */ int anchorFlags; /* Style flags associated with <A>...</A> */ int inDt; /* Style flags associated with <DT>...</DT> */ int inTr; /* True if within <tr>..</tr> */ int inTd; /* True if within <td>..</td> or <th>..</th> */ HtmlElement *anchorStart; /* Most recent <a href=...> */ HtmlElement *formStart; /* Most recent <form> */ HtmlElement *formElemStart; /* Most recent <textarea> or <select> */ HtmlElement *innerList; /* The inner most <OL> or <UL> */ /* * These fields are used to hold the state of the layout engine. * Because the layout is incremental, this state must be held for * the life of the widget. */ HtmlLayoutContext layoutContext; /* * Information used when displaying the widget: */ Tk_3DBorder border; /* Background color */ int borderWidth; /* Width of the border. */ int relief; /* 3-D effect: TK_RELIEF_RAISED, etc. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int inset; /* Total width of highlight and 3-D border */ Tk_Font aFont[N_FONT]; /* Information about all screen fonts */ char fontValid[(N_FONT+7)/8]; /* If bit N%8 of work N/8 of this field is 0 * if aFont[N] needs to be reallocated before * being used. */ XColor *apColor[N_COLOR]; /* Information about all colors */ int colorUsed; /* bit N is 1 if color N is in use. Only ** applies to colors that aren't predefined */ int iDark[N_COLOR]; /* Dark 3D shadow of color K is iDark[K] */ int iLight[N_COLOR]; /* Light 3D shadow of color K is iLight[K] */ XColor *fgColor; /* Color of normal text. apColor[0] */ XColor *newLinkColor; /* Color of unvisitied links. apColor[1] */ XColor *oldLinkColor; /* Color of visitied links. apColor[2] */ XColor *selectionColor; /* Background color for selections */ GcCache aGcCache[N_CACHE_GC]; /* A cache of GCs for general use */ int lastGC; /* Index of recently used GC */ HtmlImage *imageList; /* A list of all images */ int width, height; /* User-requested size of the usable drawing * area, in pixels. Borders and padding * make the actual window a little larger */ int realWidth, realHeight; /* The actual physical size of tkwin as * reported in the most recent ConfigureNotify * event. */ int padx, pady; /* Separation between the edge of the window * and rendered HTML. */ int underlineLinks; /* TRUE if we should underline hyperlinks */ /* Information about the selection */ int exportSelection; /* True if the selection is automatically * exported to the clipboard */ /* Callback commands. The HTML parser will invoke callbacks from time ** to time to find out information it needs to complete formatting of ** the document. The following fields define the callback commands. */ char *zIsVisited; /* Command to tell if a hyperlink has already ** been visited */ char *zGetImage; /* Command to get an image from a URL */ char *zFrameCommand; /* Command for handling <frameset> markup */ char *zAppletCommand; /* Command to process applets */ char *zResolverCommand; /* Command to resolve URIs */ char *zFormCommand; /* When user presses Submit */ char *zHyperlinkCommand; /* Invoked when a hyperlink is clicked */ char *zFontCommand; /* Invoked to find font names */ char *zScriptCommand; /* Invoked for each <SCRIPT> markup */ /* * Miscellaneous information: */ int tableRelief; /* 3d effects on <TABLE> */ int ruleRelief; /* 3d effects on <HR> */ char *zBase; /* The base URI */ char *zBaseHref; /* zBase as modified by <BASE HREF=..> markup */ Tk_Cursor cursor; /* Current cursor for window, or None. */ char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ char *yScrollCmd; /* Command prefix for communicating with * vertical scrollbar. NULL means no command * to issue. Malloc'ed. */ char *xScrollCmd; /* Command prefix for communicating with * horizontal scrollbar. NULL means no command * to issue. Malloc'ed. */ int xOffset, yOffset; /* Current scroll position. These form the * coordinate in the virtual canvas that * corresponds to (0,0) on the physical screen * in window tkwin */ int maxX, maxY; /* Maximum extent of any "paint" that appears * on the virtual canvas. Used to compute * scrollbar positions. */ int dirtyLeft, dirtyTop; /* Top left corner of region to redraw. These * are physical screen coordinates relative to * clipwin, not tkwin. */ int dirtyRight, dirtyBottom; /* Bottom right corner of region to redraw */ int locked; /* Number of locks on this structure. Don't ** delete until it reaches zero. */ int flags; /* Various flags; see below for * definitions. */ } /* * Flag bits "flags" field of the Html widget: * * REDRAW_PENDING A DoWhenIdle handler has already been queued to * call HtmlRedrawCallback() function. * * GOT_FOCUS This widget currently has input focus. * * HSCROLL Horizontal scrollbar position needs to be * recomputed. * * VSCROLL Vertical scrollbar position needs to be * recomputed. * * RELAYOUT We need to reposition every element on the * virtual canvas. (This happens, for example, * when the size of the widget changes and we * need to recompute the line breaks.) * * RESIZE_ELEMENTS We need to recompute the size of every element. * This happens, for example, when the fonts * change. * * REDRAW_FOCUS We need to repaint the focus highlight border. * * REDRAW_TEXT Everything in the clipping window needs to be redrawn. * * REDRAW_BORDER Everything outside the clipping window needs * to be redrawn. * * RESIZE_CLIPWIN The size and position of the clipping window * needs to be adjusted using Tk_MoveResizeWindow(). * * STYLER_RUNNING There is a call to HtmlAddStyle() in process. * Used to prevent a recursive call to HtmlAddStyle(). * * INSERT_FLASHING True if there is a timer callback pending that will * toggle the state of the insertion cursor. * * REDRAW_IMAGES One or more HtmlImageMarkup structures have * their redrawNeeded flag set. */ #define REDRAW_PENDING 0x000001 #define GOT_FOCUS 0x000002 #define HSCROLL 0x000004 #define VSCROLL 0x000008 #define RELAYOUT 0x000010 #define RESIZE_ELEMENTS 0x000020 #define REDRAW_FOCUS 0x000040 #define REDRAW_TEXT 0x000080 #define REDRAW_BORDER 0x000100 #define EXTEND_LAYOUT 0x000200 #define RESIZE_CLIPWIN 0x000400 #define STYLER_RUNNING 0x000800 #define INSERT_FLASHING 0x001000 #define REDRAW_IMAGES 0x002000 /* ** Macros to set, clear or test bits of the "flags" field. */ #define HtmlHasFlag(A,F) (((A)->flags&(F))==(F)) #define HtmlHasAnyFlag(A,F) (((A)->flags&(F))!=0) #define HtmlSetFlag(A,F) ((A)->flags|=(F)) #define HtmlClearFlag(A,F) ((A)->flags&=~(F)) /* ** No coordinate is every as big as this number */ #define LARGE_NUMBER 100000000 /* ** Default values for configuration options */ #define DEF_HTML_BG_COLOR DEF_FRAME_BG_COLOR #define DEF_HTML_BG_MONO DEF_FRAME_BG_MONO #define DEF_HTML_BORDER_WIDTH "2" #define DEF_HTML_CALLBACK "" #define DEF_HTML_CURSOR DEF_FRAME_CURSOR #define DEF_HTML_EXPORT_SEL "yes" #define DEF_HTML_FG DEF_BUTTON_FG #define DEF_HTML_HEIGHT "400" #define DEF_HTML_HIGHLIGHT_BG DEF_BUTTON_HIGHLIGHT_BG #define DEF_HTML_HIGHLIGHT DEF_BUTTON_HIGHLIGHT #define DEF_HTML_HIGHLIGHT_WIDTH "0" #define DEF_HTML_INSERT_OFF_TIME "300" #define DEF_HTML_INSERT_ON_TIME "600" #define DEF_HTML_PADX "5" #define DEF_HTML_PADY "5" #define DEF_HTML_RELIEF "raised" #define DEF_HTML_SCROLL_COMMAND "" #define DEF_HTML_SELECTION_COLOR "skyblue" #define DEF_HTML_TAKE_FOCUS "0" #define DEF_HTML_UNVISITED "blue1" #define DEF_HTML_VISITED "blue3" #define DEF_HTML_WIDTH "600" #ifdef NAVIGATOR_TABLES #define DEF_HTML_TABLE_BORDER "0" #define DEF_HTML_TABLE_CELLPADDING "2" #define DEF_HTML_TABLE_CELLSPACING "5" #define DEF_HTML_TABLE_BORDER_LIGHT_COLOR "gray80" #define DEF_HTML_TABLE_BORDER_DARK_COLOR "gray40" #endif /* NAVIGATOR_TABLES */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlform.c������������������������������������������������������������������0000644�0001750�0001750�00000045152�07504443345�016055� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlform.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines used for processing HTML makeup for forms. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include "htmlform.h" /* ** Unmap any input control that is currently mapped. */ void HtmlUnmapControls(HtmlWidget *htmlPtr){ HtmlElement *p; for(p=htmlPtr->firstInput; p; p=p->input.pNext){ if( p->input.tkwin!=0 && Tk_IsMapped(p->input.tkwin) ){ Tk_UnmapWindow(p->input.tkwin); } } } /* ** Map any control that should be visible according to the ** current scroll position. At the same time, if any controls that ** should not be visible are mapped, unmap them. After this routine ** finishes, all <INPUT> controls should be in their proper places ** regardless of where they might have been before. ** ** Return the number of controls that are currently visible. */ int HtmlMapControls(HtmlWidget *htmlPtr){ HtmlElement *p; /* For looping over all controls */ int x, y, w, h; /* Part of the virtual canvas that is visible */ int cnt = 0; /* Number of visible controls */ x = htmlPtr->xOffset; y = htmlPtr->yOffset; w = Tk_Width(htmlPtr->clipwin); h = Tk_Height(htmlPtr->clipwin); for(p=htmlPtr->firstInput; p; p=p->input.pNext){ if( p->input.tkwin==0 ) continue; if( p->input.y < y+h && p->input.y + p->input.h > y && p->input.x < x+w && p->input.x + p->input.w > x ){ /* The control should be visible. Make is so if it isn't already */ Tk_MoveResizeWindow(p->input.tkwin, p->input.x - x, p->input.y - y, p->input.w, p->input.h); if( !Tk_IsMapped(p->input.tkwin) ){ Tk_MapWindow(p->input.tkwin); } cnt++; }else{ /* This control should not be visible. Unmap it. */ if( Tk_IsMapped(p->input.tkwin) ){ Tk_UnmapWindow(p->input.tkwin); } } } return cnt; } /* ** Delete all input controls. This happens when the HTML widget ** is cleared. ** ** When the TCL "exit" command is invoked, the order of operations ** here is very touchy. */ void HtmlDeleteControls(HtmlWidget *htmlPtr){ HtmlElement *p; /* For looping over all controls */ Tcl_Interp *interp; /* The interpreter */ interp = htmlPtr->interp; p = htmlPtr->firstInput; htmlPtr->firstInput = 0; htmlPtr->lastInput = 0; htmlPtr->nInput = 0; if( p==0 || htmlPtr->tkwin==0 ) return; HtmlLock(htmlPtr); for(; p; p=p->input.pNext){ if( p->input.pForm && p->input.pForm->form.id>0 && htmlPtr->zFormCommand && htmlPtr->zFormCommand[0] && !Tcl_InterpDeleted(interp) && htmlPtr->clipwin ){ Tcl_DString cmd; int result; char zBuf[60]; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); sprintf(zBuf," %d flush", p->input.pForm->form.id); Tcl_DStringAppend(&cmd, zBuf, -1); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( !Tcl_InterpDeleted(interp) ){ if( result != TCL_OK ){ Tcl_AddErrorInfo(htmlPtr->interp, "\n (-formcommand flush callback executed by html widget)"); Tcl_BackgroundError(htmlPtr->interp); TestPoint(0); } Tcl_ResetResult(htmlPtr->interp); } p->input.pForm->form.id = 0; } if( p->input.tkwin ){ if( htmlPtr->clipwin!=0 ) Tk_DestroyWindow(p->input.tkwin); p->input.tkwin = 0; } p->input.sized = 0; } HtmlUnlock(htmlPtr); } /* ** Return an appropriate type value for the given <INPUT> markup. */ static int InputType(HtmlElement *p){ int type = INPUT_TYPE_Unknown; char *z; int i; static struct { char *zName; int type; } types[] = { { "checkbox", INPUT_TYPE_Checkbox }, { "file", INPUT_TYPE_File }, { "hidden", INPUT_TYPE_Hidden }, { "image", INPUT_TYPE_Image }, { "password", INPUT_TYPE_Password }, { "radio", INPUT_TYPE_Radio }, { "reset", INPUT_TYPE_Reset }, { "submit", INPUT_TYPE_Submit }, { "text", INPUT_TYPE_Text }, }; switch( p->base.type ){ case Html_INPUT: z = HtmlMarkupArg(p, "type", "text"); if( z==0 ){ TestPoint(0); break; } for(i=0; i<sizeof(types)/sizeof(types[0]); i++){ if( stricmp(types[i].zName,z)==0 ){ type = types[i].type; TestPoint(0); break; } TestPoint(0); } break; case Html_SELECT: type = INPUT_TYPE_Select; TestPoint(0); break; case Html_TEXTAREA: type = INPUT_TYPE_TextArea; TestPoint(0); break; case Html_APPLET: case Html_IFRAME: case Html_EMBED: type = INPUT_TYPE_Applet; TestPoint(0); break; default: CANT_HAPPEN; break; } return type; } /* ** Create the window name for a child widget. Space to hold the name ** is obtained from HtmlAlloc() and must be freed by the calling function. */ static char *MakeWindowName( HtmlWidget *htmlPtr, /* The HTML widget */ HtmlElement *pElem /* The input that needs a child widget */ ){ int n; char *zBuf; n = strlen(Tk_PathName(htmlPtr->clipwin)); zBuf = HtmlAlloc( n + 20 ); sprintf(zBuf,"%s.x%d",Tk_PathName(htmlPtr->clipwin), pElem->input.cnt); return zBuf; } /* ** A Input element is the input. Mark this element as being ** empty. It has no widget and doesn't appear on the screen. ** ** This is called for HIDDEN inputs or when the -formcommand ** callback doesn't create the widget. */ static void EmptyInput(HtmlElement *pElem){ pElem->input.tkwin = 0; pElem->input.w = 0; pElem->input.h = 0; pElem->base.flags &= !HTML_Visible; pElem->base.style.flags |= STY_Invisible; pElem->input.sized = 1; } /* ** This routine is called when one of the child windows for a form ** wants to change its size. */ static void HtmlInputRequestProc(ClientData clientData, Tk_Window tkwin){ HtmlElement *pElem = (HtmlElement*)clientData; if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } if( pElem->input.tkwin!=tkwin ){ CANT_HAPPEN; return; } pElem->input.w = Tk_ReqWidth(tkwin); pElem->input.h = Tk_ReqHeight(tkwin); if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ pElem->input.htmlPtr->flags |= RELAYOUT; HtmlScheduleRedraw(pElem->input.htmlPtr); } } /* ** This routine is called when another entity takes over geometry ** management for a widget corresponding to an input element. */ static void HtmlInputLostSlaveProc(ClientData clientData, Tk_Window tkwin){ HtmlElement *pElem = (HtmlElement*)clientData; if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } if( pElem->input.tkwin!=tkwin ){ CANT_HAPPEN; return; } EmptyInput(pElem); if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ pElem->input.htmlPtr->flags |= RELAYOUT; HtmlScheduleRedraw(pElem->input.htmlPtr); } } /* ** This routine catches DestroyNotify events on a INPUT window so ** that we will know the window is been deleted. */ static void HtmlInputEventProc(ClientData clientData, XEvent *eventPtr){ HtmlElement *pElem = (HtmlElement*)clientData; /* if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } */ if( eventPtr->type==DestroyNotify ){ EmptyInput(pElem); if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ pElem->input.htmlPtr->flags |= RELAYOUT; HtmlScheduleRedraw(pElem->input.htmlPtr); } } } /* ** The geometry manager for the HTML widget */ static Tk_GeomMgr htmlGeomType = { "html", /* Name */ HtmlInputRequestProc, /* Called when widget changes size */ HtmlInputLostSlaveProc, /* Called when someone else takes over management */ }; /* ** zWin is the name of a child widget that is used to implement an ** input element. Query Tk for information about this widget (such ** as its size) and put that information in the pElem structure ** that represents the input. */ static void SizeAndLink(HtmlWidget *htmlPtr, char *zWin, HtmlElement *pElem){ pElem->input.tkwin = Tk_NameToWindow(htmlPtr->interp, zWin, htmlPtr->clipwin); if( pElem->input.tkwin==0 ){ Tcl_ResetResult(htmlPtr->interp); EmptyInput(pElem); }else if( pElem->input.type==INPUT_TYPE_Hidden ){ pElem->input.w = 0; pElem->input.h = 0; pElem->base.flags &= !HTML_Visible; pElem->base.style.flags |= STY_Invisible; }else{ pElem->input.w = Tk_ReqWidth(pElem->input.tkwin); pElem->input.h = Tk_ReqHeight(pElem->input.tkwin); pElem->base.flags |= HTML_Visible; pElem->input.htmlPtr = htmlPtr; Tk_ManageGeometry(pElem->input.tkwin, &htmlGeomType, pElem); Tk_CreateEventHandler(pElem->input.tkwin, StructureNotifyMask, HtmlInputEventProc, pElem); } pElem->input.pNext = 0; if( htmlPtr->firstInput==0 ){ htmlPtr->firstInput = pElem; }else{ htmlPtr->lastInput->input.pNext = pElem; } htmlPtr->lastInput = pElem; pElem->input.sized = 1; } /* Append all text and space tokens between pStart and pEnd to ** the given Tcl_DString. */ static void HtmlAppendText( Tcl_DString *str, /* Append the text here */ HtmlElement *pFirst, /* The first token */ HtmlElement *pEnd /* The last token */ ){ while( pFirst && pFirst!=pEnd ){ switch( pFirst->base.type ){ case Html_Text: { Tcl_DStringAppend(str, pFirst->text.zText, -1); break; } case Html_Space: { if( pFirst->base.flags & HTML_NewLine ){ Tcl_DStringAppend(str, "\n", 1); }else{ int cnt; static char zSpaces[] = " "; cnt = pFirst->base.count; while( cnt>sizeof(zSpaces)-1 ){ Tcl_DStringAppend(str, zSpaces, sizeof(zSpaces)-1); cnt -= sizeof(zSpaces)-1; } if( cnt>0 ){ Tcl_DStringAppend(str, zSpaces, cnt); } } break; } default: /* Do nothing */ break; } pFirst = pFirst->pNext; } } /* ** The "p" argument points to a <select>. This routine scans all ** subsequent elements (up to the next </select>) looking for ** <option> tags. For each option tag, it appends three elements ** to the "str" DString: ** ** * 1 or 0 to indicated whether or not the element is ** selected. ** ** * The value returned if this element is selected. ** ** * The text displayed for this element. */ static void AddSelectOptions( Tcl_DString *str, /* Add text here */ HtmlElement *p, /* The <SELECT> markup */ HtmlElement *pEnd /* The </SELECT> markup */ ){ while( p && p!=pEnd && p->base.type!=Html_EndSELECT ){ if( p->base.type==Html_OPTION ){ char *zValue; Tcl_DStringStartSublist(str); if( HtmlMarkupArg(p, "selected", 0)==0 ){ Tcl_DStringAppend(str, "0 ", 2); }else{ Tcl_DStringAppend(str, "1 ", 2); } zValue = HtmlMarkupArg(p, "value", ""); Tcl_DStringAppendElement(str, zValue); Tcl_DStringStartSublist(str); p = p->pNext; while( p && p!=pEnd && p->base.type!=Html_EndOPTION && p->base.type!=Html_OPTION && p->base.type!=Html_EndSELECT ){ if( p->base.type==Html_Text ){ Tcl_DStringAppend(str, p->text.zText, -1); }else if( p->base.type==Html_Space ){ Tcl_DStringAppend(str, " ", 1); } p = p->pNext; } Tcl_DStringEndSublist(str); Tcl_DStringEndSublist(str); }else{ p = p->pNext; } } } /* ** This routine implements the Sizer() function for <INPUT>, ** <SELECT> and <TEXTAREA> markup. ** ** A side effect of sizing these markups is that widgets are ** created to represent the corresponding input controls. ** ** The function normally returns 0. But if it is dealing with ** a <SELECT> or <TEXTAREA> that is incomplete, 1 is returned. ** In that case, the sizer will be called again at some point in ** the future when more information is available. */ int HtmlControlSize(HtmlWidget *htmlPtr, HtmlElement *pElem){ char *zWin; /* Name of child widget that implements this input */ int incomplete = 0; /* True if data is incomplete */ Tcl_DString cmd; /* The complete -formcommand callback */ if( pElem->input.sized ) return 0; pElem->input.type = InputType(pElem); switch( pElem->input.type ){ case INPUT_TYPE_Checkbox: case INPUT_TYPE_Hidden: case INPUT_TYPE_Image: case INPUT_TYPE_Radio: case INPUT_TYPE_Reset: case INPUT_TYPE_Submit: case INPUT_TYPE_Text: case INPUT_TYPE_Password: case INPUT_TYPE_File: { int result; char zToken[50]; if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 || htmlPtr->zFormCommand[0]==0 ){ EmptyInput(pElem); break; } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); sprintf(zToken," %d input ",pElem->input.pForm->form.id); Tcl_DStringAppend(&cmd, zToken, -1); pElem->input.cnt = ++htmlPtr->nInput; zWin = MakeWindowName(htmlPtr, pElem); Tcl_DStringAppend(&cmd, zWin, -1); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, pElem); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( !HtmlUnlock(htmlPtr) ){ SizeAndLink(htmlPtr, zWin, pElem); } HtmlFree(zWin); break; } case INPUT_TYPE_Select: { int result; char zToken[50]; if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 || htmlPtr->zFormCommand[0]==0 ){ EmptyInput(pElem); break; } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); sprintf(zToken," %d select ",pElem->input.pForm->form.id); Tcl_DStringAppend(&cmd, zToken, -1); pElem->input.cnt = ++htmlPtr->nInput; zWin = MakeWindowName(htmlPtr, pElem); Tcl_DStringAppend(&cmd, zWin, -1); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, pElem); Tcl_DStringEndSublist(&cmd); Tcl_DStringStartSublist(&cmd); AddSelectOptions(&cmd, pElem, pElem->input.pEnd); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( !HtmlUnlock(htmlPtr) ){ SizeAndLink(htmlPtr, zWin, pElem); } HtmlFree(zWin); break; } case INPUT_TYPE_TextArea: { int result; char zToken[50]; if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 || htmlPtr->zFormCommand[0]==0 ){ EmptyInput(pElem); break; } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); sprintf(zToken," %d textarea ",pElem->input.pForm->form.id); Tcl_DStringAppend(&cmd, zToken, -1); pElem->input.cnt = ++htmlPtr->nInput; zWin = MakeWindowName(htmlPtr, pElem); Tcl_DStringAppend(&cmd, zWin, -1); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, pElem); Tcl_DStringEndSublist(&cmd); Tcl_DStringStartSublist(&cmd); HtmlAppendText(&cmd, pElem, pElem->input.pEnd); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( !HtmlUnlock(htmlPtr) ){ SizeAndLink(htmlPtr, zWin, pElem); } HtmlFree(zWin); break; } case INPUT_TYPE_Applet: { int result; if( htmlPtr->zAppletCommand==0 || htmlPtr->zAppletCommand[0]==0 ){ EmptyInput(pElem); break; } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zAppletCommand, -1); Tcl_DStringAppend(&cmd, " ", 1); pElem->input.cnt = ++htmlPtr->nInput; zWin = MakeWindowName(htmlPtr, pElem); Tcl_DStringAppend(&cmd, zWin, -1); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, pElem); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( !HtmlUnlock(htmlPtr) ){ SizeAndLink(htmlPtr, zWin, pElem); } HtmlFree(zWin); break; } default: { CANT_HAPPEN; pElem->base.flags &= ~HTML_Visible; pElem->base.style.flags |= STY_Invisible; pElem->input.tkwin = 0; break; } } return incomplete; } #if 0 /* ** The following array determines which characters can be put directly ** in a query string and which must be escaped. */ static char needEscape[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, }; #define NeedToEscape(C) ((C)>0 && (C)<127 && needEscape[(int)(C)]) /* ** Append to the given DString, an encoded version of the given ** text. */ static void EncodeText(Tcl_DString *str, char *z){ int i; while( *z ){ for(i=0; z[i] && !NeedToEscape(z[i]); i++){ TestPoint(0); } if( i>0 ){ TestPoint(0); Tcl_DStringAppend(str, z, i); } z += i; while( *z && NeedToEscape(*z) ){ if( *z==' ' ){ Tcl_DStringAppend(str,"+",1); TestPoint(0); }else if( *z=='\n' ){ Tcl_DStringAppend(str, "%0D%0A", 6); TestPoint(0); }else if( *z=='\r' ){ /* Ignore it... */ TestPoint(0); }else{ char zBuf[5]; sprintf(zBuf,"%%%02X",0xff & *z); Tcl_DStringAppend(str, zBuf, 3); TestPoint(0); } z++; } } } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmltable.c�����������������������������������������������������������������0000644�0001750�0001750�00000115053�07504443345�016177� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmltable.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines for doing layout of HTML tables ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include "htmltable.h" /* ** Default values for various table style parameters */ #define DFLT_BORDER 0 #define DFLT_CELLSPACING_3D 5 #define DFLT_CELLSPACING_FLAT 0 #define DFLT_CELLPADDING 2 #define DFLT_HSPACE 0 #define DFLT_VSPACE 0 #if INTERFACE /* ** Set parameter A to the maximum of A and B. */ #define SETMAX(A,B) if( (A)<(B) ){ (A) = (B); } #define MAX(A,B) ((A)<(B)?(B):(A)) #endif /* ** Return the appropriate cell spacing for the given table. */ static int CellSpacing(HtmlWidget *htmlPtr, HtmlElement *pTable){ char *z; int relief; int cellSpacing; z = HtmlMarkupArg(pTable, "cellspacing", 0); if( z==0 ){ relief = htmlPtr->tableRelief; if( relief==TK_RELIEF_RAISED || relief==TK_RELIEF_SUNKEN ){ cellSpacing = DFLT_CELLSPACING_3D; }else{ cellSpacing = DFLT_CELLSPACING_FLAT; } }else{ cellSpacing = atoi(z); } return cellSpacing; } /* Forward declaration */ static HtmlElement *MinMax(HtmlWidget*, HtmlElement *, int *, int *, int); /* pStart points to a <table>. Compute the number of columns, the ** minimum and maximum size for each column and the overall minimum ** and maximum size for this table and store these value in the ** pStart structure. Return a pointer to the </table> element, ** or to NULL if there is no </table>. ** ** The min and max size for column N (where the leftmost column has ** N==1) is pStart->minW[1] and pStart->maxW[1]. The pStart->minW[0] ** and pStart->maxW[0] entries contain the minimum and maximum widths ** of the whole table, including any cell padding, cell spacing, ** border width and "hspace". The values of pStart->minW[I] for I>=1 ** do not contain any cell padding, cell spacing or border width. ** Only pStart->minW[0] contains these extra spaces. ** ** The back references from </table>, </tr>, </td> and </th> back to ** the <table> markup are also filled in. And for each <td> and <th> ** markup, the pTable and pEnd fields are set to their proper values. */ static HtmlElement *TableDimensions( HtmlWidget *htmlPtr, /* The HTML widget */ HtmlElement *pStart, /* The <table> markup */ int lineWidth /* Total widget available to the table */ ){ HtmlElement *p; /* Element being processed */ HtmlElement *pNext; /* Next element to process */ int iCol = 0; /* Current column number. 1..N */ int iRow = 0; /* Current row number */ int inRow = 0; /* True if in between <TR> and </TR> */ int i, j; /* Loop counters */ int n; /* Number of columns */ int minW, maxW, requestedW; /* min, max, requested width for a cell */ int noWrap; /* true for NOWRAP cells */ int colspan; /* Column span for the current cell */ int rowspan; /* Row span for the current cell */ char *z; /* Value of a <table> parameter */ int cellSpacing; /* Value of CELLSPACING parameter */ int cellPadding; /* Value of CELLPADDING parameter */ int tbw; /* Width of border around whole table */ int cbw; /* Width of border around one cell */ int hspace; /* Value of HSPACE parameter */ int separation; /* Space between columns */ int margin; /* Space between left margin and 1st col */ int availWidth; /* Part of lineWidth still available */ int maxTableWidth; /* Amount of lineWidth available to table*/ int fromAbove[HTML_MAX_COLUMNS+1]; /* Cell above extends thru this row */ int min0span[HTML_MAX_COLUMNS+1]; /* Min for colspan=0 cells */ int max0span[HTML_MAX_COLUMNS+1]; /* Max for colspan=0 cells */ int reqW[HTML_MAX_COLUMNS+1]; /* Requested width for each column */ /* colMin[A][B] is the absolute minimum width of all columns between ** A+1 and B+1. colMin[B][A] is the requested width of columns between ** A+1 and B+1. This information is used to add in the constraints imposed ** by <TD COLSPAN=N> markup where N>=2. */ int colMin[HTML_MAX_COLUMNS+1][HTML_MAX_COLUMNS+1]; # define ColMin(A,B) colMin[(A)-1][(B)-1] # define ColReq(A,B) colMin[(B)-1][(A)-1] if( pStart==0 || pStart->base.type!=Html_TABLE ){ TestPoint(0); return pStart; } TRACE_PUSH(HtmlTrace_Table1); TRACE(HtmlTrace_Table1, ("Starting TableDimensions..\n")); pStart->table.nCol = 0; pStart->table.nRow = 0; z = HtmlMarkupArg(pStart, "border", 0); if( z && *z==0 ) z = "2"; tbw = pStart->table.borderWidth = z ? atoi(z) : DFLT_BORDER; cbw = tbw>0; z = HtmlMarkupArg(pStart, "cellpadding", 0); cellPadding = z ? atoi(z) : DFLT_CELLPADDING; cellSpacing = CellSpacing(htmlPtr, pStart); #ifdef DEBUG /* The HtmlTrace_Table4 flag causes tables to be draw with borders ** of 2, cellPadding of 5 and cell spacing of 2. This makes the ** table clearly visible. Useful for debugging. */ if( HtmlTraceMask & HtmlTrace_Table4 ){ tbw = pStart->table.borderWidth = 2; cbw = 1; cellPadding = 5; cellSpacing = 2; pStart->base.style.bgcolor = COLOR_Background; } #endif separation = cellSpacing + 2*(cellPadding + cbw); margin = tbw + cellSpacing + cbw + cellPadding; z = HtmlMarkupArg(pStart, "hspace", 0); hspace = z ? atoi(z) : DFLT_HSPACE; for(p=pStart->pNext; p && p->base.type!=Html_EndTABLE; p=pNext){ pNext = p->pNext; switch( p->base.type ){ case Html_EndTD: case Html_EndTH: case Html_EndTABLE: p->ref.pOther = pStart; TestPoint(0); break; case Html_EndTR: p->ref.pOther = pStart; inRow = 0; TestPoint(0); break; case Html_TR: p->ref.pOther = pStart; iRow++; pStart->table.nRow++; iCol = 0; inRow = 1; maxTableWidth = availWidth = lineWidth - 2*margin; TestPoint(0); break; case Html_CAPTION: while( p && p->base.type!=Html_EndTABLE && p->base.type!=Html_EndCAPTION ){ p = p->pNext; TestPoint(0); } break; case Html_TD: case Html_TH: if( !inRow ){ /* If the <TR> markup is omitted, insert it. */ HtmlElement *pNew = HtmlAlloc( sizeof(HtmlRef) ); if( pNew==0 ) break; memset(pNew, 0, sizeof(HtmlRef)); pNew->base = p->base; pNew->base.pNext = p; pNew->base.type = Html_TR; pNew->base.count = 0; p->base.pPrev->base.pNext = pNew; p->base.pPrev = pNew; pNext = pNew; break; } do{ iCol++; }while( iCol <= pStart->table.nCol && fromAbove[iCol] > iRow ); p->cell.pTable = pStart; colspan = p->cell.colspan; if( colspan==0 ){ colspan = 1; } if( iCol + colspan - 1 > pStart->table.nCol ){ int nCol = iCol + colspan - 1; if( nCol > HTML_MAX_COLUMNS ){ nCol = HTML_MAX_COLUMNS; } for(i=pStart->table.nCol+1; i<=nCol; i++){ fromAbove[i] = 0; pStart->table.minW[i] = 0; pStart->table.maxW[i] = 0; min0span[i] = 0; max0span[i] = 0; reqW[i] = 0; for(j=1; j<i; j++){ ColMin(j,i) = 0; ColReq(j,i) = 0; } } pStart->table.nCol = nCol; } noWrap = HtmlMarkupArg(p, "nowrap", 0)!=0; pNext = MinMax(htmlPtr, p, &minW, &maxW, availWidth); p->cell.pEnd = pNext; if( (z = HtmlMarkupArg(p, "width", 0))!=0 ){ for(i=0; isdigit(z[i]); i++){} if( strcmp(z,"*")==0 ){ requestedW = availWidth; }else if( z[i]==0 ){ requestedW = atoi(z); }else if( z[i]=='%' ){ /* requestedW = (atoi(z)*availWidth + 99)/100; */ requestedW = (atoi(z)*maxTableWidth + 99)/100; } }else{ requestedW = 0; } TRACE(HtmlTrace_Table1, ("Row %d Column %d: min=%d max=%d req=%d stop at %s\n", iRow,iCol,minW,maxW,requestedW, HtmlTokenName(p->cell.pEnd))); if( noWrap ){ minW = maxW; } if( iCol + p->cell.colspan <= HTML_MAX_COLUMNS ){ int min = 0; if( p->cell.colspan==0 ){ SETMAX( min0span[iCol], minW ); SETMAX( max0span[iCol], maxW ); min = min0span[iCol] + separation; }else if( colspan==1 ){ SETMAX( pStart->table.minW[iCol], minW ); SETMAX( pStart->table.maxW[iCol], maxW ); SETMAX( reqW[iCol], requestedW ); min = pStart->table.minW[iCol] + separation; }else{ int n = p->cell.colspan; SETMAX( ColMin(iCol,iCol+n-1), minW); SETMAX( ColReq(iCol,iCol+n-1), requestedW); min = minW + separation; #if 0 maxW = (maxW + (n - 1)*(1-separation))/n; for(i=iCol; i<iCol + n && i<HTML_MAX_COLUMNS; i++){ SETMAX( pStart->table.maxW[i], maxW ); } #endif } availWidth -= min; } rowspan = p->cell.rowspan; if( rowspan==0 ){ rowspan = LARGE_NUMBER; } if( rowspan>1 ){ for(i=iCol; i<iCol + p->cell.colspan && i<HTML_MAX_COLUMNS; i++){ fromAbove[i] = iRow + rowspan; } } if( p->cell.colspan > 1 ){ iCol += p->cell.colspan - 1; }else if( p->cell.colspan==0 ){ iCol = HTML_MAX_COLUMNS + 1; } break; } } #ifdef DEBUG if( HtmlTraceMask & HtmlTrace_Table6 ){ char *zSpace = ""; TRACE_INDENT; for(i=1; i<=pStart->table.nCol; i++){ printf("%s%d:%d..%d",zSpace,i, pStart->table.minW[i],pStart->table.maxW[i]); if( reqW[i]>0 ){ printf("(w=%d)",reqW[i]); } zSpace = " "; } printf("\n"); for(i=1; i<pStart->table.nCol; i++){ for(j=i+1; j<=pStart->table.nCol; j++){ if( ColMin(i,j)>0 ){ TRACE_INDENT; printf("ColMin(%d,%d) = %d\n", i, j, ColMin(i,j)); } if( ColReq(i,j)>0 ){ TRACE_INDENT; printf("ColReq(%d,%d) = %d\n", i, j, ColReq(i,j)); } } } } #endif /* Compute the min and max width of each column */ for(i=1; i<=pStart->table.nCol; i++){ int sumMin, sumReq, sumMax; /* Reduce the max[] field to N for columns that have "width=N" */ if( reqW[i]>0 ){ pStart->table.maxW[i] = MAX(pStart->table.minW[i],reqW[i]); } /* Expand the width of columns marked with "colspan=0". */ if( min0span[i]>0 || max0span[i]>0 ){ int n = pStart->table.nCol - i + 1; minW = (min0span[i] + (n - 1)*(1-separation))/n; maxW = (max0span[i] + (n - 1)*(1-separation))/n; for(j=i; j<=pStart->table.nCol; j++){ SETMAX( pStart->table.minW[j], minW ); SETMAX( pStart->table.maxW[j], maxW ); } } /* Expand the minW[] of columns to accomodate "colspan=N" constraints. ** The minW[] is expanded up to the maxW[] first. Then all the maxW[]s ** are expanded in proportion to their sizes. The same thing occurs ** for reqW[]s. */ sumReq = reqW[i]; sumMin = pStart->table.minW[i]; sumMax = pStart->table.maxW[i]; for(j=i-1; j>=1; j--){ int cmin, creq; sumMin += pStart->table.minW[j]; sumMax += pStart->table.maxW[j]; sumReq += reqW[i]; cmin = ColMin(j,i); if( cmin>sumMin ){ int k; double scale; int *tminW = pStart->table.minW; int *tmaxW = pStart->table.maxW; if( sumMin<sumMax ){ scale = (double)(cmin - sumMin)/(double)(sumMax - sumMin); for(k=j; k<=i; k++){ sumMin -= tminW[k]; tminW[k] = (tmaxW[k] - tminW[k])*scale + tminW[k]; sumMin += tminW[k]; } }else if( sumMin>0 ){ scale = (double)cmin/(double)sumMin; for(k=j; k<=i; k++){ sumMin -= tminW[k]; tminW[k] = tmaxW[k] = tminW[k]*scale; sumMin += tminW[k]; } }else{ int unit = cmin/(i-j+1); for(k=j; k<=i; k++){ tminW[k] = tmaxW[k] = unit; sumMin += tminW[k]; } } } creq = ColReq(j,i); if( creq>sumReq ){ int k; double scale; int *tmaxW = pStart->table.maxW; if( sumReq<sumMax ){ scale = (double)(creq - sumReq)/(double)(sumMax - sumReq); for(k=j; k<=i; k++){ sumReq -= reqW[k]; reqW[k] = (tmaxW[k] - reqW[k])*scale + reqW[k]; sumReq += reqW[k]; } }else if( sumReq>0 ){ scale = (double)creq/(double)sumReq; for(k=j; k<=i; k++){ sumReq -= reqW[k]; reqW[k] = reqW[k]*scale; sumReq += reqW[k]; } }else{ int unit = creq/(i-j+1); for(k=j; k<=i; k++){ reqW[k] = unit; sumReq += reqW[k]; } } } } } #ifdef DEBUG if( HtmlTraceMask & HtmlTrace_Table6 ){ char *zSpace = ""; TRACE_INDENT; for(i=1; i<=pStart->table.nCol; i++){ printf("%s%d:%d..%d",zSpace,i, pStart->table.minW[i],pStart->table.maxW[i]); if( reqW[i]>0 ){ printf("(w=%d)",reqW[i]); } zSpace = " "; } printf("\n"); } #endif /* Compute the min and max width of the whole table */ n = pStart->table.nCol; requestedW = tbw*2 + (n+1)*cellSpacing + n*2*(cellPadding + cbw); pStart->table.minW[0] = requestedW; pStart->table.maxW[0] = requestedW; for(i=1; i<=pStart->table.nCol; i++){ pStart->table.minW[0] += pStart->table.minW[i]; pStart->table.maxW[0] += pStart->table.maxW[i]; requestedW += MAX(reqW[i], pStart->table.minW[i]); } /* Figure out how wide to draw the table */ z = HtmlMarkupArg(pStart, "width", 0); if( z ){ int len = strlen(z); int totalWidth; if( len>0 && z[len-1]=='%' ){ totalWidth = (atoi(z) * lineWidth)/100; }else{ totalWidth = atoi(z); } SETMAX( requestedW, totalWidth ); } if( lineWidth && (requestedW > lineWidth) ){ TRACE(HtmlTrace_Table5,("RequestedW reduced to lineWidth: %d -> %d\n", requestedW, lineWidth)); requestedW = lineWidth; } if( requestedW > pStart->table.minW[0] ){ float scale; int *tminW = pStart->table.minW; int *tmaxW = pStart->table.maxW; TRACE(HtmlTrace_Table5, ("Expanding table minW from %d to %d. (reqW=%d width=%s)\n", tminW[0], requestedW, requestedW, z)); if( tmaxW[0] > tminW[0] ){ scale = (double)(requestedW - tminW[0]) / (double)(tmaxW[0] - tminW[0]); for(i=1; i<=pStart->table.nCol; i++){ tminW[i] += (tmaxW[i] - tminW[i]) * scale; SETMAX(tmaxW[i], tminW[i]); } }else if( tminW[0]>0 ){ scale = requestedW/(double)tminW[0]; for(i=1; i<=pStart->table.nCol; i++){ tminW[i] *= scale; tmaxW[i] *= scale; } }else if( pStart->table.nCol>0 ){ int unit = (requestedW - margin)/pStart->table.nCol - separation; if( unit<0 ) unit = 0; for(i=1; i<=pStart->table.nCol; i++){ tminW[i] = tmaxW[i] = unit; } }else{ tminW[0] = tmaxW[0] = requestedW; } pStart->table.minW[0] = requestedW; SETMAX( pStart->table.maxW[0], requestedW ); } #ifdef DEBUG if( HtmlTraceMask & HtmlTrace_Table5 ){ TRACE_INDENT; printf("Start with %s and ", HtmlTokenName(pStart)); printf("end with %s\n", HtmlTokenName(p)); TRACE_INDENT; printf("nCol=%d minWidth=%d maxWidth=%d\n", pStart->table.nCol, pStart->table.minW[0], pStart->table.maxW[0]); for(i=1; i<=pStart->table.nCol; i++){ TRACE_INDENT; printf("Column %d minWidth=%d maxWidth=%d\n", i, pStart->table.minW[i], pStart->table.maxW[i]); } } #endif TRACE(HtmlTrace_Table1, ("Result of TableDimensions: min=%d max=%d nCol=%d\n", pStart->table.minW[0], pStart->table.maxW[0], pStart->table.nCol)); TRACE_POP(HtmlTrace_Table1); return p; } /* ** Given a list of elements, compute the minimum and maximum width needed ** to render the list. Stop the search at the first element seen that is ** in the following set: ** ** <tr> <td> <th> </tr> </td> </th> </table> ** ** Return a pointer to the element that stopped the search, or to NULL ** if we ran out of data. ** ** Sometimes the value returned for both min and max will be larger than ** the true minimum and maximum. This is rare, and only occurs if the ** element string contains figures with flow-around text. */ static HtmlElement *MinMax( HtmlWidget *htmlPtr, /* The Html widget */ HtmlElement *p, /* Start the search here */ int *pMin, /* Return the minimum width here */ int *pMax, /* Return the maximum width here */ int lineWidth /* Total width available */ ){ int min = 0; /* Minimum width so far */ int max = 0; /* Maximum width so far */ int indent = 0; /* Amount of indentation (minimum) */ int obstacle = 0; /* Possible obstacles in the margin */ int x1 = 0; /* Length of current line assuming maximum length */ int x2 = 0; /* Length of current line assuming minimum length */ int go = 1; /* Change to 0 to stop the loop */ HtmlElement *pNext; /* Next element in the list */ for(p=p->pNext; go && p; p = pNext){ pNext = p->pNext; switch( p->base.type ){ case Html_Text: x1 += p->text.w; x2 += p->text.w; if( p->base.style.flags & STY_Preformatted ){ SETMAX( min, x1 ); SETMAX( max, x1 ); }else{ SETMAX( min, x2 ); SETMAX( max, x1 ); } break; case Html_Space: if( p->base.style.flags & STY_Preformatted ){ if( p->base.flags & HTML_NewLine ){ x1 = x2 = indent; }else{ x1 += p->space.w * p->base.count; x2 += p->space.w * p->base.count; } }else if( p->base.style.flags & STY_NoBreak ){ if( x1>indent ){ x1 += p->space.w; TestPoint(0);} if( x2>indent ){ x2 += p->space.w; TestPoint(0);} }else{ if( x1>indent ){ x1 += p->space.w; TestPoint(0);} x2 = indent; } break; case Html_IMG: switch( p->image.align ){ case IMAGE_ALIGN_Left: case IMAGE_ALIGN_Right: obstacle += p->image.w; x1 = obstacle + indent; x2 = indent; SETMAX( min, x2 ); SETMAX( min, p->image.w ); SETMAX( max, x1 ); break; default: x1 += p->image.w; x2 += p->image.w; if( p->base.style.flags & STY_Preformatted ){ SETMAX( min, x1 ); SETMAX( max, x1 ); }else{ SETMAX( min, x2 ); SETMAX( max, x1 ); } break; } break; case Html_TABLE: /* pNext = TableDimensions(htmlPtr, p, lineWidth-indent); */ pNext = TableDimensions(htmlPtr, p, 0); x1 = p->table.maxW[0] + indent + obstacle; x2 = p->table.minW[0] + indent; SETMAX( max, x1 ); SETMAX( min, x2 ); x1 = indent + obstacle; x2 = indent; if( pNext && pNext->base.type==Html_EndTABLE ){ pNext = pNext->pNext; } break; case Html_UL: case Html_OL: indent += HTML_INDENT; x1 = indent + obstacle; x2 = indent; break; case Html_EndUL: case Html_EndOL: indent -= HTML_INDENT; if( indent < 0 ){ indent = 0; } x1 = indent + obstacle; x2 = indent; break; case Html_BLOCKQUOTE: indent += 2*HTML_INDENT; x1 = indent + obstacle; x2 = indent; break; case Html_EndBLOCKQUOTE: indent -= 2*HTML_INDENT; if( indent < 0 ){ indent = 0; } x1 = indent + obstacle; x2 = indent; break; case Html_APPLET: case Html_INPUT: case Html_SELECT: case Html_EMBED: case Html_TEXTAREA: x1 += p->input.w + p->input.padLeft; if( p->base.style.flags & STY_Preformatted ){ SETMAX( min, x1 ); SETMAX( max, x1 ); x2 += p->input.w + p->input.padLeft; }else{ SETMAX( min, indent + p->input.w ); SETMAX( max, x1 ); x2 = indent; } break; case Html_BR: case Html_P: case Html_EndP: case Html_DIV: case Html_EndDIV: case Html_H1: case Html_EndH1: case Html_H2: case Html_EndH2: case Html_H3: case Html_EndH3: case Html_H4: case Html_EndH4: case Html_H5: case Html_H6: x1 = indent + obstacle; x2 = indent; break; case Html_EndTD: case Html_EndTH: case Html_CAPTION: case Html_EndTABLE: case Html_TD: case Html_TR: case Html_TH: case Html_EndTR: go = 0; break; default: break; } if( !go ){ break; } } *pMin = min; *pMax = max; return p; } /* Vertical alignments: */ #define VAlign_Unknown 0 #define VAlign_Top 1 #define VAlign_Bottom 2 #define VAlign_Center 3 #define VAlign_Baseline 4 /* ** Return the vertical alignment specified by the given element. */ static int GetVerticalAlignment(HtmlElement *p, int dflt){ char *z; int rc; if( p==0 ) return dflt; z = HtmlMarkupArg(p, "valign", 0); if( z==0 ){ rc = dflt; TestPoint(0); }else if( stricmp(z,"top")==0 ){ rc = VAlign_Top; TestPoint(0); }else if( stricmp(z,"bottom")==0 ){ rc = VAlign_Bottom; TestPoint(0); }else if( stricmp(z,"center")==0 ){ rc = VAlign_Center; TestPoint(0); }else if( stricmp(z,"baseline")==0 ){ rc = VAlign_Baseline; TestPoint(0); }else{ rc = dflt; TestPoint(0); } return rc; } /* Do all layout for a single table. Return the </table> element or ** NULL if the table is unterminated. */ HtmlElement *HtmlTableLayout( HtmlLayoutContext *pLC, /* The layout context */ HtmlElement *pTable /* The <table> element */ ){ HtmlElement *pEnd; /* The </table> element */ HtmlElement *p; /* For looping thru elements of the table */ HtmlElement *pNext; /* Next element in the loop */ HtmlElement *pCaption; /* Start of the caption text. The <caption> */ HtmlElement *pEndCaption; /* End of the caption. The </caption> */ int width; /* Width of the table as drawn */ int cellSpacing; /* Value of cellspacing= parameter to <table> */ int cellPadding; /* Value of cellpadding= parameter to <table> */ int tbw; /* Width of the 3D border around the whole table */ int cbw; /* Width of the 3D border around a cell */ int pad; /* cellPadding + borderwidth */ char *z; /* A string */ int leftMargin; /* The left edge of space available for drawing */ int lineWidth; /* Total horizontal space available for drawing */ int separation; /* Distance between content of columns (or rows) */ int i; /* Loop counter */ int n; /* Number of columns */ int btm; /* Bottom edge of previous row */ int iRow; /* Current row number */ int iCol; /* Current column number */ int colspan; /* Number of columns spanned by current cell */ int vspace; /* Value of the vspace= parameter to <table> */ int hspace; /* Value of the hspace= parameter to <table> */ int rowBottom; /* Bottom edge of content in the current row */ int defaultVAlign; /* Default vertical alignment for the current row */ char *zAlign; /* Value of the ALIGN= attribute of the <TABLE> */ #define N HTML_MAX_COLUMNS+1 int y[N]; /* Top edge of each cell's content */ int x[N]; /* Left edge of each cell's content */ int w[N]; /* Width of each cell's content */ int ymax[N]; /* Bottom edge of cell's content if valign=top */ HtmlElement *apElem[N]; /* The <td> or <th> for each cell in a row */ int firstRow[N]; /* First row on which a cell appears */ int lastRow[N]; /* Row to which each cell span's */ int valign[N]; /* Vertical alignment for each cell */ HtmlLayoutContext savedContext; /* Saved copy of the original pLC */ HtmlLayoutContext cellContext; /* Used to render a single cell */ #ifdef TABLE_TRIM_BLANK extern int HtmlLineWasBlank; #endif /* TABLE_TRIM_BLANK */ if( pTable==0 || pTable->base.type!=Html_TABLE ){ TestPoint(0); return pTable; } TRACE_PUSH(HtmlTrace_Table2); TRACE(HtmlTrace_Table2, ("Starting TableLayout() at %s\n", HtmlTokenName(pTable))); /* Figure how much horizontal space is available for rendering ** this table. Store the answer in lineWidth. leftMargin is ** the left-most X coordinate of the table. btm stores the top-most ** Y coordinate. */ HtmlComputeMargins(pLC, &leftMargin, &btm, &lineWidth); TRACE(HtmlTrace_Table2, ("...btm=%d left=%d width=%d\n", btm, leftMargin, lineWidth)); /* figure out how much space the table wants for each column, ** and in total.. */ pEnd = TableDimensions(pLC->htmlPtr, pTable, lineWidth); /* If we don't have enough horizontal space to accomodate the minimum table ** width, then try to move down past some obstruction (such as an ** <IMG ALIGN=LEFT>) to give us more room. */ if( lineWidth < pTable->table.minW[0] ){ HtmlWidenLine(pLC, pTable->table.minW[0], &leftMargin, &btm, &lineWidth); TRACE(HtmlTrace_Table2, ("Widen to btm=%d left=%d width=%d\n", btm, leftMargin, lineWidth)); } savedContext = *pLC; /* Figure out how wide to draw the table */ if( lineWidth < pTable->table.minW[0] ){ width = pTable->table.minW[0]; }else if( lineWidth <= pTable->table.maxW[0] ){ width = lineWidth; }else{ width = pTable->table.maxW[0]; } /* Compute the width and left edge position of every column in ** the table */ z = HtmlMarkupArg(pTable, "cellpadding", 0); cellPadding = z ? atoi(z) : DFLT_CELLPADDING; cellSpacing = CellSpacing(pLC->htmlPtr, pTable); z = HtmlMarkupArg(pTable, "vspace", 0); vspace = z ? atoi(z) : DFLT_VSPACE; z = HtmlMarkupArg(pTable, "hspace", 0); hspace = z ? atoi(z) : DFLT_HSPACE; #ifdef DEBUG if( HtmlTraceMask & HtmlTrace_Table4 ){ cellPadding = 5; cellSpacing = 2; if( vspace<2 ) vspace = 2; if( hspace<2 ) hspace = 2; } #endif tbw = pTable->table.borderWidth; cbw = (tbw>0); pad = cellPadding + cbw; separation = cellSpacing + 2*pad; x[1] = leftMargin + tbw + cellSpacing + pad; n = pTable->table.nCol; if( n<=0 || pTable->table.maxW[0]<=0 ){ /* Abort if the table has no columns at all or if the total width ** of the table is zero or less. */ return pEnd; } zAlign = HtmlMarkupArg(pTable, "align", ""); if( width < lineWidth ){ int align = pTable->base.style.align; if( align==ALIGN_Right || stricmp(zAlign,"right")==0 ){ x[1] += lineWidth - width; }else if( align==ALIGN_Center && stricmp(zAlign,"left")!=0 ){ x[1] += (lineWidth - width)/2; } } if( width==pTable->table.maxW[0] ){ w[1] = pTable->table.maxW[1]; for(i=2; i<=n; i++){ w[i] = pTable->table.maxW[i]; x[i] = x[i-1] + w[i-1] + separation; TestPoint(0); } }else if( width > pTable->table.maxW[0] ){ int *tmaxW = pTable->table.maxW; double scale = ((double)width)/ (double)tmaxW[0]; w[1] = tmaxW[1] * scale; for(i=2; i<=n; i++){ w[i] = tmaxW[i] * scale; x[i] = x[i-1] + w[i-1] + separation; TestPoint(0); } }else if( width > pTable->table.minW[0] ){ float scale; int *tminW = pTable->table.minW; int *tmaxW = pTable->table.maxW; scale = (double)(width - tminW[0]) / (double)(tmaxW[0] - tminW[0]); w[1] = tminW[1] + (tmaxW[1] - tminW[1]) * scale; for(i=2; i<=n; i++){ w[i] = tminW[i] + (tmaxW[i] - tminW[i]) * scale; x[i] = x[i-1] + w[i-1] + separation; TestPoint(0); } }else{ w[1] = pTable->table.minW[1]; for(i=2; i<=n; i++){ w[i] = pTable->table.minW[i]; x[i] = x[i-1] + w[i-1] + separation; TestPoint(0); } } w[n] = width - ((x[n] - x[1]) + 2*(tbw + pad + cellSpacing)); /* Add notation to the pTable structure so that we will know where ** to draw the outer box around the outside of the table. */ btm += vspace; pTable->table.y = btm; pTable->table.x = x[1] - (tbw + cellSpacing + pad); pTable->table.w = width; SETMAX(pLC->maxX, pTable->table.x + pTable->table.w); btm += tbw + cellSpacing; /* Begin rendering rows of the table */ for(i=1; i<=n; i++){ firstRow[i] = 0; lastRow[i] = 0; apElem[i] = 0; } p = pTable->pNext; rowBottom = btm; for(iRow=1; iRow<=pTable->table.nRow; iRow++){ TRACE(HtmlTrace_Table2, ("Row %d: btm=%d\n",iRow,btm)); /* Find the start of the next row. Keep an eye out for the caption ** while we search */ while( p && p->base.type!=Html_TR ){ if( p->base.type==Html_CAPTION ){ pCaption = p; while( p && p!=pEnd && p->base.type!=Html_EndCAPTION ){ p = p->pNext; } pEndCaption = p; } TRACE(HtmlTrace_Table3, ("Skipping token %s\n", HtmlTokenName(p))); p = p->pNext; } if( p==0 ){ TestPoint(0); break; } /* Record default vertical alignment flag for this row */ defaultVAlign = GetVerticalAlignment(p, VAlign_Center); /* Find every new cell on this row */ for(iCol=1; iCol<=pTable->table.nCol && iCol<HTML_MAX_COLUMNS; iCol++){ if( lastRow[iCol]<iRow ) ymax[iCol] = 0; } iCol = 0; for(p=p->pNext; p && p->base.type!=Html_TR && p!=pEnd; p=pNext){ pNext = p->pNext; TRACE(HtmlTrace_Table3, ("Processing token %s\n", HtmlTokenName(p))); switch( p->base.type ){ case Html_TD: case Html_TH: /* Find the column number for this cell. Be careful to skip ** columns which extend down to this row from prior rows */ do{ iCol++; }while( iCol <= HTML_MAX_COLUMNS && lastRow[iCol] >= iRow ); TRACE(HtmlTrace_Table2, ("Column %d: x=%d w=%d\n",iCol,x[iCol],w[iCol])); /* Process the new cell. (Cells beyond the maximum number of ** cells are simply ignored.) */ if( iCol <= HTML_MAX_COLUMNS ){ apElem[iCol] = p; pNext = p->cell.pEnd; if( p->cell.rowspan==0 ){ lastRow[iCol] = pTable->table.nRow; }else{ lastRow[iCol] = iRow + p->cell.rowspan - 1; } firstRow[iCol] = iRow; /* Set vertical alignment flag for this cell */ valign[iCol] = GetVerticalAlignment(p, defaultVAlign); /* Render cell contents and record the height */ y[iCol] = btm + pad; cellContext.htmlPtr = pLC->htmlPtr; cellContext.pStart = p->pNext; cellContext.pEnd = pNext; cellContext.headRoom = 0; cellContext.top = y[iCol]; cellContext.bottom = y[iCol]; cellContext.left = x[iCol]; cellContext.right = 0; cellContext.pageWidth = x[iCol]+w[iCol]; colspan = p->cell.colspan; if( colspan==0 ){ for(i=iCol+1; i<=pTable->table.nCol; i++){ cellContext.pageWidth += w[i] + separation; lastRow[i] = lastRow[iCol]; } }else if( colspan>1 ){ for(i=iCol+1; i<iCol+colspan; i++){ cellContext.pageWidth += w[i] + separation; lastRow[i] = lastRow[iCol]; } } cellContext.maxX = 0; cellContext.maxY = 0; cellContext.leftMargin = 0; cellContext.rightMargin = 0; HtmlLock(cellContext.htmlPtr); HtmlLayoutBlock(&cellContext); if( HtmlUnlock(cellContext.htmlPtr) ) return 0; #ifdef TABLE_TRIM_BLANK /* * Cancel any trailing vertical whitespace caused * by break markup */ if (HtmlLineWasBlank) cellContext.maxY -= cellContext.headRoom; #endif /* TABLE_TRIM_BLANK */ ymax[iCol] = cellContext.maxY; SETMAX(ymax[iCol], y[iCol]); HtmlClearMarginStack(&cellContext.leftMargin); HtmlClearMarginStack(&cellContext.rightMargin); /* Set coordinates of the cell border */ p->cell.x = x[iCol] - pad; p->cell.y = btm; p->cell.w = cellContext.pageWidth + 2*pad - x[iCol]; TRACE(HtmlTrace_Table2, ("Column %d top=%d bottom=%d h=%d left=%d w=%d\n", iCol, y[iCol], ymax[iCol], ymax[iCol]-y[iCol], p->cell.x, p->cell.w)); /* Advance the column counter for cells spaning multiple columns */ if( colspan > 1 ){ iCol += colspan - 1; }else if( colspan==0 ){ iCol = HTML_MAX_COLUMNS + 1; } } break; case Html_CAPTION: /* Gotta remember where the caption is so we can render it ** at the end */ pCaption = p; while( pNext && pNext!=pEnd && pNext->base.type!=Html_EndCAPTION ){ pNext = pNext->pNext; } pEndCaption = pNext; break; } } /* Figure out how high to make this row. */ for(iCol=1; iCol<=pTable->table.nCol; iCol++){ if( lastRow[iCol] == iRow || iRow==pTable->table.nRow ){ SETMAX( rowBottom, ymax[iCol] ); } } TRACE(HtmlTrace_Table2, ("Total row height: %d..%d -> %d\n", btm,rowBottom,rowBottom-btm)); /* Position every cell whose bottom edge ends on this row */ for(iCol=1; iCol<=pTable->table.nCol; iCol++){ int dy; /* Extra space at top of cell used for vertical alignment */ /* Skip any unused cells or cells that extend down thru ** subsequent rows */ if( apElem[iCol]==0 || (iRow!=pTable->table.nRow && lastRow[iCol]>iRow) ){ continue; } /* Align the contents of the cell vertically. */ switch( valign[iCol] ){ case VAlign_Unknown: case VAlign_Center: dy = (rowBottom - ymax[iCol])/2; break; case VAlign_Top: case VAlign_Baseline: dy = 0; break; case VAlign_Bottom: dy = rowBottom - ymax[iCol]; break; } if( dy ){ HtmlElement *pLast = apElem[iCol]->cell.pEnd; TRACE(HtmlTrace_Table3, ("Delta column %d by %d\n",iCol,dy)); HtmlMoveVertically(apElem[iCol]->pNext, pLast, dy); } /* Record the height of the cell so that the border can be drawn */ apElem[iCol]->cell.h = rowBottom + pad - apElem[iCol]->cell.y; apElem[iCol] = 0; } /* Update btm to the height of the row we just finished setting */ btm = rowBottom + pad + cellSpacing; } btm += tbw; pTable->table.h = btm - pTable->table.y; SETMAX( pLC->maxY, btm ); pLC->bottom = btm + vspace; /* Render the caption, if there is one */ if( pCaption ){ } /* Whenever we do any table layout, we need to recompute all the ** HtmlBlocks. The following statement forces this. */ pLC->htmlPtr->firstBlock = pLC->htmlPtr->lastBlock = 0; /* Adjust the context for text that wraps around the table, if ** requested by an ALIGN=RIGHT or ALIGN=LEFT attribute. */ if( stricmp(zAlign,"left")==0 ){ savedContext.maxX = pLC->maxX; savedContext.maxY = pLC->maxY; *pLC = savedContext; HtmlPushMargin(&pLC->leftMargin, pTable->table.w + 2, pTable->table.y + pTable->table.h + 2, 0); }else if( stricmp(zAlign,"right")==0 ){ savedContext.maxX = pLC->maxX; savedContext.maxY = pLC->maxY; *pLC = savedContext; HtmlPushMargin(&pLC->rightMargin, pTable->table.w + 2, pTable->table.y + pTable->table.h + 2, 0); } /* All done */ TRACE(HtmlTrace_Table2, ( "Done with TableLayout(). x=%d y=%d w=%d h=%d Return %s\n", pTable->table.x, pTable->table.y, pTable->table.w, pTable->table.h, HtmlTokenName(pEnd))); TRACE_POP(HtmlTrace_Table2); return pEnd; } /* ** Move all elements in the given list vertically by the amount dy */ void HtmlMoveVertically( HtmlElement *p, /* First element to move */ HtmlElement *pLast, /* Last element. Do move this one */ int dy /* Amount by which to move */ ){ if( dy==0 ){ TestPoint(0); return; } while( p && p!=pLast ){ switch( p->base.type ){ case Html_A: p->anchor.y += dy; break; case Html_Text: p->text.y += dy; break; case Html_LI: p->li.y += dy; break; case Html_TD: case Html_TH: p->cell.y += dy; break; case Html_TABLE: p->table.y += dy; break; case Html_IMG: p->image.y += dy; break; case Html_INPUT: case Html_SELECT: case Html_APPLET: case Html_EMBED: case Html_TEXTAREA: p->input.y += dy; break; default: break; } p = p->pNext; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlparse.c�����������������������������������������������������������������0000644�0001750�0001750�00000100276�07504443345�016223� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlparse.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** A tokenizer that converts raw HTML into a linked list of HTML elements. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <tk.h> #include "htmlparse.h" /****************** Begin Escape Sequence Translator *************/ /* ** The next section of code implements routines used to translate ** the '&' escape sequences of SGML to individual characters. ** Examples: ** ** &amp; & ** &lt; < ** &gt; > ** &nbsp; nonbreakable space */ /* Each escape sequence is recorded as an instance of the following ** structure */ struct sgEsc { char *zName; /* The name of this escape sequence. ex: "amp" */ char value[8]; /* The value for this sequence. ex: "&" */ struct sgEsc *pNext; /* Next sequence with the same hash on zName */ }; /* The following is a table of all escape sequences. Add new sequences ** by adding entries to this table. */ static struct sgEsc esc_sequences[] = { { "quot", "\"", 0 }, { "amp", "&", 0 }, { "lt", "<", 0 }, { "gt", ">", 0 }, { "nbsp", " ", 0 }, { "iexcl", "\241", 0 }, { "cent", "\242", 0 }, { "pound", "\243", 0 }, { "curren", "\244", 0 }, { "yen", "\245", 0 }, { "brvbar", "\246", 0 }, { "sect", "\247", 0 }, { "uml", "\250", 0 }, { "copy", "\251", 0 }, { "ordf", "\252", 0 }, { "laquo", "\253", 0 }, { "not", "\254", 0 }, { "shy", "\255", 0 }, { "reg", "\256", 0 }, { "macr", "\257", 0 }, { "deg", "\260", 0 }, { "plusmn", "\261", 0 }, { "sup2", "\262", 0 }, { "sup3", "\263", 0 }, { "acute", "\264", 0 }, { "micro", "\265", 0 }, { "para", "\266", 0 }, { "middot", "\267", 0 }, { "cedil", "\270", 0 }, { "sup1", "\271", 0 }, { "ordm", "\272", 0 }, { "raquo", "\273", 0 }, { "frac14", "\274", 0 }, { "frac12", "\275", 0 }, { "frac34", "\276", 0 }, { "iquest", "\277", 0 }, { "Agrave", "\300", 0 }, { "Aacute", "\301", 0 }, { "Acirc", "\302", 0 }, { "Atilde", "\303", 0 }, { "Auml", "\304", 0 }, { "Aring", "\305", 0 }, { "AElig", "\306", 0 }, { "Ccedil", "\307", 0 }, { "Egrave", "\310", 0 }, { "Eacute", "\311", 0 }, { "Ecirc", "\312", 0 }, { "Euml", "\313", 0 }, { "Igrave", "\314", 0 }, { "Iacute", "\315", 0 }, { "Icirc", "\316", 0 }, { "Iuml", "\317", 0 }, { "ETH", "\320", 0 }, { "Ntilde", "\321", 0 }, { "Ograve", "\322", 0 }, { "Oacute", "\323", 0 }, { "Ocirc", "\324", 0 }, { "Otilde", "\325", 0 }, { "Ouml", "\326", 0 }, { "times", "\327", 0 }, { "Oslash", "\330", 0 }, { "Ugrave", "\331", 0 }, { "Uacute", "\332", 0 }, { "Ucirc", "\333", 0 }, { "Uuml", "\334", 0 }, { "Yacute", "\335", 0 }, { "THORN", "\336", 0 }, { "szlig", "\337", 0 }, { "agrave", "\340", 0 }, { "aacute", "\341", 0 }, { "acirc", "\342", 0 }, { "atilde", "\343", 0 }, { "auml", "\344", 0 }, { "aring", "\345", 0 }, { "aelig", "\346", 0 }, { "ccedil", "\347", 0 }, { "egrave", "\350", 0 }, { "eacute", "\351", 0 }, { "ecirc", "\352", 0 }, { "euml", "\353", 0 }, { "igrave", "\354", 0 }, { "iacute", "\355", 0 }, { "icirc", "\356", 0 }, { "iuml", "\357", 0 }, { "eth", "\360", 0 }, { "ntilde", "\361", 0 }, { "ograve", "\362", 0 }, { "oacute", "\363", 0 }, { "ocirc", "\364", 0 }, { "otilde", "\365", 0 }, { "ouml", "\366", 0 }, { "divide", "\367", 0 }, { "oslash", "\370", 0 }, { "ugrave", "\371", 0 }, { "uacute", "\372", 0 }, { "ucirc", "\373", 0 }, { "uuml", "\374", 0 }, { "yacute", "\375", 0 }, { "thorn", "\376", 0 }, { "yuml", "\377", 0 }, }; /* The size of the handler hash table. For best results this should ** be a prime number which is about the same size as the number of ** escape sequences known to the system. */ #define ESC_HASH_SIZE (sizeof(esc_sequences)/sizeof(esc_sequences[0])+7) /* The hash table ** ** If the name of an escape sequences hashes to the value H, then ** apEscHash[H] will point to a linked list of Esc structures, one of ** which will be the Esc structure for that escape sequence. */ static struct sgEsc *apEscHash[ESC_HASH_SIZE]; /* Hash a escape sequence name. The value returned is an integer ** between 0 and ESC_HASH_SIZE-1, inclusive. */ static int EscHash(const char *zName){ int h = 0; /* The hash value to be returned */ char c; /* The next character in the name being hashed */ while( (c=*zName)!=0 ){ h = h<<5 ^ h ^ c; zName++; TestPoint(0); } if( h<0 ){ h = -h; TestPoint(0); }else{ TestPoint(0); } return h % ESC_HASH_SIZE; } #ifdef TEST /* ** Compute the longest and average collision chain length for the ** escape sequence hash table */ static void EscHashStats(void){ int i; int sum = 0; int max = 0; int cnt; int notempty = 0; struct sgEsc *p; for(i=0; i<sizeof(esc_sequences)/sizeof(esc_sequences[0]); i++){ cnt = 0; p = apEscHash[i]; if( p ) notempty++; while( p ){ cnt++; p = p->pNext; } sum += cnt; if( cnt>max ) max = cnt; } printf("Longest chain=%d avg=%g slots=%d empty=%d (%g%%)\n", max,(double)sum/(double)notempty, i, i-notempty, 100.0*(i-notempty)/(double)i); } #endif /* Initialize the escape sequence hash table */ static void EscInit(void){ int i; /* For looping thru the list of escape sequences */ int h; /* The hash on a sequence */ for(i=0; i<sizeof(esc_sequences)/sizeof(esc_sequences[i]); i++){ /* #ifdef TCL_UTF_MAX */ #if 0 { int c = esc_sequences[i].value[0]; Tcl_UniCharToUtf(c, esc_sequences[i].value); } #endif h = EscHash(esc_sequences[i].zName); esc_sequences[i].pNext = apEscHash[h]; apEscHash[h] = &esc_sequences[i]; TestPoint(0); } #ifdef TEST EscHashStats(); #endif } /* ** This table translates the non-standard microsoft characters between ** 0x80 and 0x9f into plain ASCII so that the characters will be visible ** on Unix systems. Care is taken to translate the characters ** into values less than 0x80, to avoid UTF-8 problems. */ #ifndef __WIN32__ static char acMsChar[] = { /* 0x80 */ 'C', /* 0x81 */ ' ', /* 0x82 */ ',', /* 0x83 */ 'f', /* 0x84 */ '"', /* 0x85 */ '.', /* 0x86 */ '*', /* 0x87 */ '*', /* 0x88 */ '^', /* 0x89 */ '%', /* 0x8a */ 'S', /* 0x8b */ '<', /* 0x8c */ 'O', /* 0x8d */ ' ', /* 0x8e */ 'Z', /* 0x8f */ ' ', /* 0x90 */ ' ', /* 0x91 */ '\'', /* 0x92 */ '\'', /* 0x93 */ '"', /* 0x94 */ '"', /* 0x95 */ '*', /* 0x96 */ '-', /* 0x97 */ '-', /* 0x98 */ '~', /* 0x99 */ '@', /* 0x9a */ 's', /* 0x9b */ '>', /* 0x9c */ 'o', /* 0x9d */ ' ', /* 0x9e */ 'z', /* 0x9f */ 'Y', }; #endif /* Translate escape sequences in the string "z". "z" is overwritten ** with the translated sequence. ** ** Unrecognized escape sequences are unaltered. ** ** Example: ** ** input = "AT&amp;T &gt MCI" ** output = "AT&T > MCI" */ LOCAL void HtmlTranslateEscapes(char *z){ int from; /* Read characters from this position in z[] */ int to; /* Write characters into this position in z[] */ int h; /* A hash on the escape sequence */ struct sgEsc *p; /* For looping down the escape sequence collision chain */ static int isInit = 0; /* True after initialization */ from = to = 0; if( !isInit ){ EscInit(); isInit = 1; } while( z[from] ){ if( z[from]=='&' ){ if( z[from+1]=='#' ){ int i = from + 2; int v = 0; while( isdigit(z[i]) ){ v = v*10 + z[i] - '0'; i++; } if( z[i]==';' ){ i++; } /* On Unix systems, translate the non-standard microsoft ** characters in the range of 0x80 to 0x9f into something ** we can see. */ #ifndef __WIN32__ if( v>=0x80 && v<0xa0 ){ v = acMsChar[v&0x1f]; } #endif /* Put the character in the output stream in place of ** the "&#000;". How we do this depends on whether or ** not we are using UTF-8. */ #ifdef TCL_UTF_MAX { int j, n; char value[8]; n = Tcl_UniCharToUtf(v,value); for(j=0; j<n; j++){ z[to++] = value[j]; } } #else z[to++] = v; #endif from = i; }else{ int i = from+1; int c; while( z[i] && isalnum(z[i]) ){ TestPoint(0); i++; } c = z[i]; z[i] = 0; h = EscHash(&z[from+1]); p = apEscHash[h]; while( p && strcmp(p->zName,&z[from+1])!=0 ){ p = p->pNext; } z[i] = c; if( p ){ int j; for(j=0; p->value[j]; j++){ z[to++] = p->value[j]; } from = i; if( c==';' ){ from++; } }else{ z[to++] = z[from++]; } } /* On UNIX systems, look for the non-standard microsoft characters ** between 0x80 and 0x9f and translate them into printable ASCII ** codes. Separate algorithms are required to do this for plain ** ascii and for utf-8. */ #ifndef __WIN32__ #ifdef TCL_UTF_MAX }else if( (z[from]&0x80)!=0 ){ Tcl_UniChar c; int n; n = Tcl_UtfToUniChar(&z[from], &c); if( c>=0x80 && c<0xa0 ){ z[to++] = acMsChar[c & 0x1f]; from += n; }else{ while( n-- ) z[to++] = z[from++]; } #else /* if !defined(TCL_UTF_MAX) */ }else if( ((unsigned char)z[from])>=0x80 && ((unsigned char)z[from])<0xa0 ){ z[to++] = acMsChar[z[from++]&0x1f]; #endif /* TCL_UTF_MAX */ #endif /* __WIN32__ */ }else{ z[to++] = z[from++]; TestPoint(0); } } z[to] = 0; } /******************* End Escape Sequence Translator ***************/ /******************* Begin HTML tokenizer code *******************/ /* ** The following variable becomes TRUE when the markup hash table ** (stored in HtmlMarkupMap[]) is initialized. */ static int isInit = 0; /* The hash table for HTML markup names. ** ** If an HTML markup name hashes to H, then apMap[H] will point to ** a linked list of sgMap structure, one of which will describe the ** the particular markup (if it exists.) */ static HtmlTokenMap *apMap[HTML_MARKUP_HASH_SIZE]; /* Hash a markup name ** ** HTML markup is case insensitive, so this function will give the ** same hash regardless of the case of the markup name. ** ** The value returned is an integer between 0 and HTML_MARKUP_HASH_SIZE-1, ** inclusive. */ static int HtmlHash(const char *zName){ int h = 0; char c; while( (c=*zName)!=0 ){ if( isupper(c) ){ c = tolower(c); } h = h<<5 ^ h ^ c; zName++; } if( h<0 ){ h = -h; } return h % HTML_MARKUP_HASH_SIZE; } #ifdef TEST /* ** Compute the longest and average collision chain length for the ** markup hash table */ static void HtmlHashStats(void){ int i; int sum = 0; int max = 0; int cnt; int notempty = 0; struct sgMap *p; for(i=0; i<HTML_MARKUP_COUNT; i++){ cnt = 0; p = apMap[i]; if( p ) notempty++; while( p ){ cnt++; p = p->pCollide; } sum += cnt; if( cnt>max ) max = cnt; } printf("longest chain=%d avg=%g slots=%d empty=%d (%g%%)\n", max, (double)sum/(double)notempty, i, i-notempty, 100.0*(i-notempty)/(double)i); } #endif /* Initialize the escape sequence hash table */ static void HtmlHashInit(void){ int i; /* For looping thru the list of markup names */ int h; /* The hash on a markup name */ for(i=0; i<HTML_MARKUP_COUNT; i++){ h = HtmlHash(HtmlMarkupMap[i].zName); HtmlMarkupMap[i].pCollide = apMap[h]; apMap[h] = &HtmlMarkupMap[i]; } #ifdef TEST HtmlHashStats(); #endif } /* ** Append the given HtmlElement to the tokenizers list of elements */ static void AppendElement(HtmlWidget *p, HtmlElement *pElem){ pElem->base.pNext = 0; pElem->base.pPrev = p->pLast; if( p->pFirst==0 ){ p->pFirst = pElem; }else{ p->pLast->base.pNext = pElem; } p->pLast = pElem; p->nToken++; } /* ** Compute the new column index following the given character. */ static int NextColumn(int iCol, char c){ switch( c ){ case '\n': return 0; case '\t': return (iCol | 7) + 1; default: return iCol+1; } /* NOT REACHED */ } /* ** Convert a string to all lower-case letters. */ static void ToLower(char *z){ while( *z ){ if( isupper(*z) ) *z = tolower(*z); z++; } } /* Process as much of the input HTML as possible. Construct new ** HtmlElement structures and appended them to the list. Return ** the number of characters actually processed. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. ** ** This routine is not reentrant for the same HTML widget. To ** prevent reentrancy (during a callback), the p->iCol field is ** set to a negative number. This is a flag to future invocations ** not to reentry this routine. The p->iCol field is restored ** before exiting, of course. */ static int Tokenize( HtmlWidget *p /* The HTML widget doing the parsing */ ){ char *z; /* The input HTML text */ int c; /* The next character of input */ int n; /* Number of characters processed so far */ int iCol; /* Column of input */ int i, j; /* Loop counters */ int h; /* Result from HtmlHash() */ int nByte; /* Space allocated for a single HtmlElement */ HtmlElement *pElem; /* A new HTML element */ int selfClose; /* True for content free elements. Ex: <br/> */ int argc; /* The number of arguments on a markup */ HtmlTokenMap *pMap; /* For searching the markup name hash table */ char *zBuf; /* For handing out buffer space */ # define mxARG 200 /* Maximum number of parameters in a single markup */ char *argv[mxARG]; /* Pointers to each markup argument. */ int arglen[mxARG]; /* Length of each markup argument */ iCol = p->iCol; n = p->nComplete; z = p->zText; if( iCol<0 ){ TestPoint(0); return n; } /* Prevents recursion */ p->iCol = -1; while( (c=z[n])!=0 ){ if( p->pScript ){ /* We are in the middle of <SCRIPT>...</SCRIPT>. Just look for ** the </SCRIPT> markup. (later:) Treat <STYLE>...</STYLE> the ** same way. */ HtmlScript *pScript = p->pScript; char *zEnd; int nEnd; if( pScript->markup.base.type==Html_SCRIPT ){ zEnd = "</script>"; nEnd = 9; }else{ zEnd = "</style>"; nEnd = 8; } if( pScript->zScript==0 ){ pScript->zScript = &z[n]; pScript->nScript = 0; } for(i=n+pScript->nScript; z[i]; i++){ if( z[i]=='<' && z[i+1]=='/' && strnicmp(&z[i],zEnd,nEnd)==0 ){ pScript->nScript = i - n; p->pScript = 0; n = i+nEnd; break; } } if( p->pScript ){ pScript->nScript = i - n; } continue; }else if( isspace(c) ){ /* White space */ for(i=0; (c=z[n+i])!=0 && isspace(c) && c!='\n' && c!='\r'; i++){} if( c=='\r' && z[n+i+1]=='\n' ){ i++; } pElem = HtmlAlloc( sizeof(HtmlSpaceElement) ); if( pElem==0 ){ goto incomplete; } pElem->base.type = Html_Space; if( c=='\n' || c=='\r' ){ pElem->base.flags = HTML_NewLine; pElem->base.count = 1; i++; iCol = 0; TestPoint(0); }else{ int iColStart = iCol; pElem->base.flags = 0; for(j=0; j<i; j++){ iCol = NextColumn(iCol, z[n+j]); TestPoint(0); } pElem->base.count = iCol - iColStart; } AppendElement(p,pElem); n += i; }else if( c!='<' || p->iPlaintext!=0 || (!isalpha(z[n+1]) && z[n+1]!='/' && z[n+1]!='!' && z[n+1]!='?') ){ /* Ordinary text */ for(i=1; (c=z[n+i])!=0 && !isspace(c) && c!='<'; i++){} if( c==0 ){ TestPoint(0); goto incomplete; } if( p->iPlaintext!=0 && z[n]=='<' ){ switch( p->iPlaintext ){ case Html_LISTING: if( i>=10 && strnicmp(&z[n],"</listing>",10)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; case Html_XMP: if( i>=6 && strnicmp(&z[n],"</xmp>",6)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; case Html_TEXTAREA: if( i>=11 && strnicmp(&z[n],"</textarea>",11)==0 ){ p->iPlaintext = 0; goto doMarkup; } break; default: break; } } nByte = sizeof(HtmlTextElement) + i; pElem = HtmlAlloc( nByte ); if( pElem==0 ){ goto incomplete; } memset(pElem,0,nByte); pElem->base.type = Html_Text; sprintf(pElem->text.zText,"%.*s",i,&z[n]); AppendElement(p,pElem); if( p->iPlaintext==0 || p->iPlaintext==Html_TEXTAREA ){ HtmlTranslateEscapes(pElem->text.zText); } pElem->base.count = strlen(pElem->text.zText); n += i; iCol += i; }else if( strncmp(&z[n],"<!--",4)==0 ){ /* An HTML comment. Just skip it. */ for(i=4; z[n+i]; i++){ if( z[n+i]=='-' && strncmp(&z[n+i],"-->",3)==0 ){ break; } } if( z[n+i]==0 ){ TestPoint(0); goto incomplete; } for(j=0; j<i+3; j++){ iCol = NextColumn(iCol, z[n+j]); } n += i + 3; }else{ /* Markup. ** ** First get the name of the markup */ doMarkup: argc = 1; argv[0] = &z[n+1]; for(i=1; (c=z[n+i])!=0 && !isspace(c) && c!='>' && (i<2 || c!='/'); i++){} arglen[0] = i - 1; if( c==0 ){ goto incomplete; } /* ** Now parse up the arguments */ while( isspace(z[n+i]) ){ i++; } while( (c=z[n+i])!=0 && c!='>' && (c!='/' || z[n+i+1]!='>') ){ if( argc>mxARG-3 ){ argc = mxARG-3; } argv[argc] = &z[n+i]; j = 0; while( (c=z[n+i+j])!=0 && !isspace(c) && c!='>' && c!='=' && (c!='/' || z[n+i+j+1]!='>') ){ j++; } arglen[argc] = j; if( c==0 ){ goto incomplete; } i += j; while( isspace(c) ){ i++; c = z[n+i]; } if( c==0 ){ goto incomplete; } argc++; if( c!='=' ){ argv[argc] = ""; arglen[argc] = 0; argc++; continue; } i++; c = z[n+i]; while( isspace(c) ){ i++; c = z[n+i]; } if( c==0 ){ goto incomplete; } if( c=='\'' || c=='"' ){ int cQuote = c; i++; argv[argc] = &z[n+i]; for(j=0; (c=z[n+i+j])!=0 && c!=cQuote; j++){} if( c==0 ){ goto incomplete; } arglen[argc] = j; i += j+1; TestPoint(0); }else{ argv[argc] = &z[n+i]; for(j=0; (c=z[n+i+j])!=0 && !isspace(c) && c!='>'; j++){} if( c==0 ){ goto incomplete; } arglen[argc] = j; i += j; } argc++; while( isspace(z[n+i]) ){ i++; } } if( c=='/' ){ i++; c = z[n+i]; selfClose = 1; }else{ selfClose = 0; } if( c==0 ){ goto incomplete; } for(j=0; j<i+1; j++){ iCol = NextColumn(iCol, z[n+j]); } n += i + 1; /* Lookup the markup name in the hash table */ if( !isInit ){ HtmlHashInit(); isInit = 1; } c = argv[0][arglen[0]]; argv[0][arglen[0]] = 0; h = HtmlHash(argv[0]); for(pMap = apMap[h]; pMap; pMap=pMap->pCollide){ if( stricmp(pMap->zName,argv[0])==0 ){ break; } TestPoint(0); } argv[0][arglen[0]] = c; if( pMap==0 ){ continue; } /* Ignore unknown markup */ makeMarkupEntry: /* Construct a HtmlMarkup entry for this markup. */ if( pMap->extra ){ nByte = pMap->extra; }else if( argc==1 ){ nByte = sizeof(HtmlBaseElement); }else{ nByte = sizeof(HtmlMarkupElement); } if( argc>1 ){ nByte += sizeof(char*) * argc; for(j=1; j<argc; j++){ nByte += arglen[j] + 1; } } pElem = HtmlAlloc( nByte ); if( pElem==0 ){ goto incomplete; } memset(pElem,0,nByte); pElem->base.type = pMap->type; pElem->base.count = argc - 1; if( argc>1 ){ if( pMap->extra ){ pElem->markup.argv = (char**)&((char*)pElem)[pMap->extra]; }else{ pElem->markup.argv = (char**)&((HtmlMarkupElement*)pElem)[1]; } zBuf = (char*)&pElem->markup.argv[argc]; for(j=1; j<argc; j++){ pElem->markup.argv[j-1] = zBuf; zBuf += arglen[j] + 1; sprintf(pElem->markup.argv[j-1],"%.*s",arglen[j],argv[j]); HtmlTranslateEscapes(pElem->markup.argv[j-1]); if( (j&1)==1 ){ ToLower(pElem->markup.argv[j-1]); } } pElem->markup.argv[argc-1] = 0; } /* The new markup has now be constructed in pElem. But before ** appending to the list, check to see if there is a special ** handler for this markup type. */ if( p->zHandler[pMap->type] ){ Tcl_DString str; Tcl_DStringInit(&str); Tcl_DStringAppend(&str, p->zHandler[pMap->type], -1); Tcl_DStringAppendElement(&str, pMap->zName); Tcl_DStringStartSublist(&str); for(j=0; j<argc-1; j++){ Tcl_DStringAppendElement(&str, pElem->markup.argv[j]); } Tcl_DStringEndSublist(&str); HtmlFree(pElem); HtmlLock(p); Tcl_GlobalEval(p->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); if( HtmlUnlock(p) ){ return 0; } /* Tricky, tricky. The callback might have caused the p->zText ** pointer to change, so renew our copy of that pointer. The ** callback might also have cleared or destroyed the widget. ** If so, abort this routine. */ z = p->zText; if( z==0 || p->tkwin==0 ){ n = 0; iCol = 0; goto incomplete; } continue; } /* No special handler for this markup. Just append it to the ** list of all tokens. */ AppendElement(p,pElem); switch( pMap->type ){ case Html_PLAINTEXT: case Html_LISTING: case Html_XMP: case Html_TEXTAREA: p->iPlaintext = pMap->type; break; case Html_STYLE: case Html_SCRIPT: p->pScript = (HtmlScript*)pElem; break; default: break; } /* If this is self-closing markup (ex: <br/> or <img/>) then ** synthesize a closing token. */ if( selfClose && argv[0][0]!='/' && strcmp(&pMap[1].zName[1],pMap->zName)==0 ){ selfClose = 0; pMap++; argc = 1; goto makeMarkupEntry; } } } incomplete: p->iCol = iCol; return n; } /************************** End HTML Tokenizer Code ***************************/ /* ** Append text to the tokenizer engine. ** ** This routine (actually the Tokenize() subroutine that is called ** by this routine) may invoke a callback procedure which could delete ** the HTML widget. */ void HtmlTokenizerAppend(HtmlWidget *htmlPtr, const char *zText){ int len = strlen(zText); if( htmlPtr->nText==0 ){ htmlPtr->nAlloc = len + 100; htmlPtr->zText = HtmlAlloc( htmlPtr->nAlloc ); TestPoint(0); }else if( htmlPtr->nText + len >= htmlPtr->nAlloc ){ htmlPtr->nAlloc += len + 100; htmlPtr->zText = HtmlRealloc( htmlPtr->zText, htmlPtr->nAlloc ); TestPoint(0); } if( htmlPtr->zText==0 ){ htmlPtr->nText = 0; UNTESTED; return; } strcpy(&htmlPtr->zText[htmlPtr->nText], zText); htmlPtr->nText += len; htmlPtr->nComplete = Tokenize(htmlPtr); } /* ** This routine takes a text representation of a token, converts ** it into an HtmlElement structure and inserts it immediately ** prior to pToken. If pToken==0, then the newly created HtmlElement ** is appended. ** ** This routine does nothing to resize, restyle, relayout or redisplay ** the HTML. That is the calling routines responsibility. ** ** Return 0 if successful. Return non-zero if zType is not a known ** markup name. */ int HtmlInsertToken( HtmlWidget *htmlPtr, /* The widget into which the token is inserted */ HtmlElement *pToken, /* Insert before this. Append if pToken==0 */ char *zType, /* Type of markup. Ex: "/a" or "table" */ char *zArgs /* List of arguments */ ){ HtmlTokenMap *pMap; /* For searching the markup name hash table */ int h; /* The hash on zType */ HtmlElement *pElem; /* The new element */ int nByte; /* How many bytes to allocate */ int i; /* Loop counter */ if( !isInit ){ HtmlHashInit(); isInit = 1; TestPoint(0); }else{ TestPoint(0); } h = HtmlHash(zType); for(pMap = apMap[h]; pMap; pMap=pMap->pCollide){ if( stricmp(pMap->zName,zType)==0 ){ TestPoint(0); break; } TestPoint(0); } if( pMap==0 ){ TestPoint(0); return 1; } if( zArgs==0 || *zArgs==0 ){ /* Special case of no arguments. This is a lot easier... */ nByte = pMap->extra ? pMap->extra : sizeof(HtmlBaseElement); nByte += strlen(zType); pElem = HtmlAlloc( nByte ); if( pElem==0 ){ TestPoint(0); return 1; } memset(pElem,0,nByte); pElem->base.type = pMap->type; TestPoint(0); }else{ /* The general case. There are arguments that need to be parsed ** up. This is slower, but we gotta do it. */ int argc; char **argv; char *zBuf; if( Tcl_SplitList(htmlPtr->interp, zArgs, &argc, &argv)!=TCL_OK ){ TestPoint(0); return 1; } if( pMap->extra ){ nByte = pMap->extra; TestPoint(0); }else{ nByte = sizeof(HtmlMarkupElement); TestPoint(0); } nByte += sizeof(char*)*(argc+1) + strlen(zArgs) + argc + 2; pElem = HtmlAlloc( nByte ); if( pElem==0 ){ HtmlFree(argv); TestPoint(0); return 1; } memset(pElem,0,nByte); pElem->base.type = pMap->type; pElem->base.count = argc; if( pMap->extra ){ pElem->markup.argv = (char**)&((char*)pElem)[pMap->extra]; TestPoint(0); }else{ pElem->markup.argv = (char**)&((HtmlMarkupElement*)pElem)[1]; TestPoint(0); } zBuf = (char*)&pElem->markup.argv[argc]; for(i=1; i<argc; i++){ pElem->markup.argv[i-1] = zBuf; zBuf += strlen(argv[i]) + 1; strcpy(pElem->markup.argv[i-1],argv[i]); TestPoint(0); } pElem->markup.argv[argc-1] = 0; HtmlFree(argv); TestPoint(0); } if( pToken ){ pElem->base.pNext = pToken; pElem->base.pPrev = pToken->base.pPrev; if( pToken->base.pPrev ){ pToken->base.pPrev->pNext = pElem; TestPoint(0); }else{ htmlPtr->pFirst = pElem; TestPoint(0); } pToken->base.pPrev = pElem; htmlPtr->nToken++; }else{ AppendElement(htmlPtr,pElem); TestPoint(0); } return 0; } /* ** Convert a markup name into a type integer */ int HtmlNameToType(char *zType){ HtmlTokenMap *pMap; /* For searching the markup name hash table */ int h; /* The hash on zType */ if( !isInit ){ HtmlHashInit(); isInit = 1; TestPoint(0); }else{ TestPoint(0); } h = HtmlHash(zType); for(pMap = apMap[h]; pMap; pMap=pMap->pCollide){ if( stricmp(pMap->zName,zType)==0 ){ TestPoint(0); break; } TestPoint(0); } return pMap ? pMap->type : Html_Unknown; } /* ** Convert a type into a symbolic name */ const char *HtmlTypeToName(int type){ if( type>=Html_A && type<=Html_EndXMP ){ HtmlTokenMap *pMap = apMap[type - Html_A]; TestPoint(0); return pMap->zName; }else{ TestPoint(0); return "???"; } } /* ** For debugging purposes, print information about a token */ char *HtmlTokenName(HtmlElement *p){ #ifdef DEBUG static char zBuf[200]; int j; char *zName; if( p==0 ) return "NULL"; switch( p->base.type ){ case Html_Text: sprintf(zBuf,"\"%.*s\"",p->base.count,p->text.zText); break; case Html_Space: if( p->base.flags & HTML_NewLine ){ sprintf(zBuf,"\"\\n\""); }else{ sprintf(zBuf,"\" \""); } break; case Html_Block: if( p->block.n>0 ){ int n = p->block.n; if( n>150 ) n = 150; sprintf(zBuf,"<Block z=\"%.*s\">", n, p->block.z); }else{ sprintf(zBuf,"<Block>"); } break; default: if( p->base.type >= HtmlMarkupMap[0].type && p->base.type <= HtmlMarkupMap[HTML_MARKUP_COUNT-1].type ){ zName = HtmlMarkupMap[p->base.type - HtmlMarkupMap[0].type].zName; }else{ zName = "Unknown"; } sprintf(zBuf,"<%s",zName); for(j=1; j<p->base.count; j += 2){ sprintf(&zBuf[strlen(zBuf)]," %s=%s", p->markup.argv[j-1],p->markup.argv[j]); } strcat(zBuf,">"); break; } return zBuf; #else return 0; #endif } /* ** Return all tokens between the two elements as a Tcl list. */ void HtmlTclizeList(Tcl_Interp *interp, HtmlElement *p, HtmlElement *pEnd){ Tcl_DString str; int i; char *zName; char zLine[100]; Tcl_DStringInit(&str); while( p && p!=pEnd ){ switch( p->base.type ){ case Html_Block: break; case Html_Text: Tcl_DStringStartSublist(&str); Tcl_DStringAppendElement(&str,"Text"); Tcl_DStringAppendElement(&str, p->text.zText); Tcl_DStringEndSublist(&str); break; case Html_Space: sprintf(zLine,"Space %d %d", p->base.count, (p->base.flags & HTML_NewLine)!=0); Tcl_DStringAppendElement(&str,zLine); break; case Html_Unknown: Tcl_DStringAppendElement(&str,"Unknown"); break; default: Tcl_DStringStartSublist(&str); Tcl_DStringAppendElement(&str,"Markup"); if( p->base.type >= HtmlMarkupMap[0].type && p->base.type <= HtmlMarkupMap[HTML_MARKUP_COUNT-1].type ){ zName = HtmlMarkupMap[p->base.type - HtmlMarkupMap[0].type].zName; }else{ zName = "Unknown"; } Tcl_DStringAppendElement(&str, zName); for(i=0; i<p->base.count; i++){ Tcl_DStringAppendElement(&str, p->markup.argv[i]); } Tcl_DStringEndSublist(&str); break; } p = p->pNext; } Tcl_DStringResult(interp, &str); } /* ** Print a list of tokens */ #ifdef DEBUG void HtmlPrintList(HtmlElement *p, HtmlElement *pEnd){ while( p && p!=pEnd ){ if( p->base.type==Html_Block ){ char *z = p->block.z; int n = p->block.n; if( n==0 || z==0 ){ n = 1; z = ""; } printf("Block 0x%08x flags=%02x cnt=%d x=%d..%d y=%d..%d z=\"%.*s\"\n", (int)p, p->base.flags, p->base.count, p->block.left, p->block.right, p->block.top, p->block.bottom, n, z); }else{ printf("Token 0x%08x font=%2d color=%2d align=%d flags=0x%04x name=%s\n", (int)p, p->base.style.font, p->base.style.color, p->base.style.align, p->base.style.flags, HtmlTokenName(p)); } p = p->pNext; } } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/tokenlist.txt���������������������������������������������������������������0000644�0001750�0001750�00000012366�07504443346�016640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # This file contains raw data used to build the "htmltokens.c" file. # Each line contains 2 or 3 elements. The first word on each line is # the name of some HTML markup. The second word is the amount of # space to allocate for the corresponding element. "0" appears if # no extra space (beyond HtmlMarkup) is required. If there is a # corresponding end-tag, then the third column specifies the size of # the end markup. # $Revision: 1.1.1.1 $ # # Copyright (C) 1997-2000 D. Richard Hipp # # 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 Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Author contact information: # drh@acm.org # http://www.hwaci.com/drh/ # Order is not important. Comments begin with #. Spacing is ignored. a HtmlAnchor HtmlRef address 0 0 applet HtmlInput 0 area 0 b 0 0 base 0 basefont 0 0 bgsound 0 big 0 0 blockquote 0 0 body 0 0 br 0 caption 0 0 center 0 0 cite 0 0 code 0 0 comment 0 0 dd HtmlRef 0 dfn 0 0 dir HtmlListStart HtmlRef div 0 0 dl HtmlListStart HtmlRef dt HtmlRef 0 em 0 0 embed HtmlInput font 0 0 form HtmlForm HtmlRef frame 0 0 frameset 0 0 h1 0 0 h2 0 0 h3 0 0 h4 0 0 h5 0 0 h6 0 0 hr HtmlHr html 0 0 i 0 0 iframe 0 img HtmlImageMarkup input HtmlInput isindex 0 kbd 0 0 li HtmlLi 0 link 0 listing 0 0 map 0 0 marquee 0 0 menu HtmlListStart HtmlRef meta 0 nextid 0 nobr 0 0 noframe 0 0 noscript 0 0 ol HtmlListStart HtmlRef option 0 0 p 0 0 param 0 0 plaintext 0 pre 0 0 s 0 0 samp 0 0 script HtmlScript select HtmlInput HtmlRef small 0 0 strike 0 0 strong 0 0 style HtmlScript sub 0 0 sup 0 0 table HtmlTable HtmlRef td HtmlCell HtmlRef textarea HtmlInput HtmlRef th HtmlCell HtmlRef title 0 0 tr HtmlRef HtmlRef tt 0 0 u 0 0 ul HtmlListStart HtmlRef var 0 0 wbr 0 xmp 0 0 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmltest.c������������������������������������������������������������������0000644�0001750�0001750�00000006737�07504443346�016100� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmltest.c,v 1.1.1.1 2002/06/20 21:19:34 joye Exp $"; /* ** This file contains the TestPoint routines used for profiling ** and coverage analysis of the code. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ /* ** A macro named "TestPoint" is defined which increments a counter ** whenever it is encountered. This is very efficient, and should ** not impact performance of the system. For delivery, the macro ** can be nulled out by recompiling without the COVERAGE_TEST macro ** defined. ** ** See also the "renumber.c" program which can be used ** to assign unique numbers to all of the TestPoint(0) macros. */ #include "tcl.h" #include "htmltest.h" #if INTERFACE #if defined(COVERAGE_TEST) # define TestPoint(X) {extern int HtmlTPArray[]; HtmlTPArray[X]++;} # define UNTESTED HtmlTPUntested(__FILE__,__LINE__) # define CANT_HAPPEN HtmlTPCantHappen(__FILE__,__LINE__) # define HtmlVerifyLock(H) if((H)->locked==0)HtmlTPCantHappen(__FILE__,__LINE__) #else # define TestPoint(X) # define UNTESTED # define CANT_HAPPEN # define HtmlVerifyLock(H) #endif #endif /* INTERFACE */ /* ** The following global array keeps track of the number of visits to ** each testpoint. The size of the array must be set manually to the ** be at least one greater than the largest TestPoint number. */ #if defined(COVERAGE_TEST) int HtmlTPArray[2000]; #endif /* Needed by the EslTestPointDump routine */ #include <stdio.h> /* ** Recursion depth */ #if defined(DEBUG) int HtmlDepth = 0; #endif #if INTERFACE #if defined(DEBUG) #define HtmlPush HtmlDepth+=2 #define HtmlPop HtmlDepth-=2 #else #define HtmlPush #define HtmlPop #endif #endif /* This function is called to print the values of all elements of the ** TP_Array to the given file. Values are printed in decimal, one per line. */ void HtmlTestPointDump(char *filename){ #if defined(COVERAGE_TEST) FILE *fp; fp = fopen(filename,"a"); if( fp ){ int i; for(i=0; i<sizeof(HtmlTPArray)/sizeof(HtmlTPArray[0]); i++){ if( HtmlTPArray[i]>0 ){ fprintf(fp,"%d %d\n",i,HtmlTPArray[i]); } } } fclose(fp); #endif } /* This function reports an error to stderr when code that is marked ** UNTESTED gets executed. */ void HtmlTPUntested(const char *zFile, int line){ #ifndef USE_TCL_STUBS fprintf(stderr,"Untested HTML Widget code executed in file %s line %d\n", zFile,line); #endif } /* This function reports an error to stderr when safety code that should ** never execute is called. */ void HtmlTPCantHappen(const char *zFile, int line){ #ifndef USE_TCL_STUBS fprintf(stderr,"Unplanned behavior in the HTML Widget in file %s line %d\n", zFile,line); #endif } ���������������������������������./saods9/htmlwidget/src/htmlwidget.c����������������������������������������������������������������0000644�0001750�0001750�00000177764�10334236561�016407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlwidget.c,v 1.4 2005/11/09 00:06:09 joye Exp $"; /* ** The main routine for the HTML widget for Tcl/Tk ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <ctype.h> #include <stdlib.h> #include <string.h> #include "htmlwidget.h" #ifdef USE_TK_STUBS # include <tkIntXlibDecls.h> #endif /* ** This global variable is used for tracing the operation of ** the Html formatter. */ int HtmlTraceMask = 0; #ifdef __WIN32__ # define DEF_FRAME_BG_COLOR "SystemButtonFace" # define DEF_FRAME_BG_MONO "White" # define DEF_FRAME_CURSOR "" # define DEF_BUTTON_FG "SystemButtonText" # define DEF_BUTTON_HIGHLIGHT_BG "SystemButtonFace" # define DEF_BUTTON_HIGHLIGHT "SystemWindowFrame" #else # define DEF_FRAME_BG_COLOR "#d9d9d9" # define DEF_FRAME_BG_MONO "White" # define DEF_FRAME_CURSOR "" # define DEF_BUTTON_FG "Black" # define DEF_BUTTON_HIGHLIGHT_BG "#d9d9d9" # define DEF_BUTTON_HIGHLIGHT "Black" #endif /* ** Information used for argv parsing. */ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_STRING, "-appletcommand", "appletCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zAppletCommand), 0}, {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_HTML_BG_COLOR, Tk_Offset(HtmlWidget, border), TK_CONFIG_COLOR_ONLY}, {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_HTML_BG_MONO, Tk_Offset(HtmlWidget, border), TK_CONFIG_MONO_ONLY}, {TK_CONFIG_STRING, "-base", "base", "Base", "", Tk_Offset(HtmlWidget, zBase), 0}, {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, (char *) NULL, 0, 0}, {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, (char *) NULL, 0, 0}, {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_HTML_BORDER_WIDTH, Tk_Offset(HtmlWidget, borderWidth), 0}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_HTML_CURSOR, Tk_Offset(HtmlWidget, cursor), TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection","ExportSelection", DEF_HTML_EXPORT_SEL, Tk_Offset(HtmlWidget, exportSelection), 0}, {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, (char *) NULL, 0, 0}, {TK_CONFIG_STRING, "-fontcommand", "fontCommand", "FontCommand", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zFontCommand), 0}, {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_HTML_FG, Tk_Offset(HtmlWidget, fgColor), 0}, {TK_CONFIG_STRING, "-formcommand", "formlCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zFormCommand), 0}, {TK_CONFIG_STRING, "-framecommand", "frameCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zFrameCommand), 0}, {TK_CONFIG_PIXELS, "-height", "height", "Hidth", DEF_HTML_HEIGHT, Tk_Offset(HtmlWidget, height), 0}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HTML_HIGHLIGHT_BG, Tk_Offset(HtmlWidget, highlightBgColorPtr), 0}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HTML_HIGHLIGHT, Tk_Offset(HtmlWidget, highlightColorPtr), 0}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HTML_HIGHLIGHT_WIDTH, Tk_Offset(HtmlWidget, highlightWidth), 0}, {TK_CONFIG_STRING, "-hyperlinkcommand", "hyperlinkCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zHyperlinkCommand), 0}, {TK_CONFIG_STRING, "-imagecommand", "imageCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zGetImage), 0}, {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", DEF_HTML_INSERT_OFF_TIME, Tk_Offset(HtmlWidget, insOffTime), 0}, {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", DEF_HTML_INSERT_ON_TIME, Tk_Offset(HtmlWidget, insOnTime), 0}, {TK_CONFIG_STRING, "-isvisitedcommand", "isVisitedCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zIsVisited), 0}, {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", DEF_HTML_PADX, Tk_Offset(HtmlWidget, padx), 0}, {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", DEF_HTML_PADY, Tk_Offset(HtmlWidget, pady), 0}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_HTML_RELIEF, Tk_Offset(HtmlWidget, relief), 0}, {TK_CONFIG_STRING, "-resolvercommand", "resolverCommand", "HtmlCallback", DEF_HTML_CALLBACK, Tk_Offset(HtmlWidget, zResolverCommand), 0}, {TK_CONFIG_RELIEF, "-rulerelief", "ruleRelief","RuleRelief", "sunken", Tk_Offset(HtmlWidget, ruleRelief), 0}, {TK_CONFIG_STRING, "-scriptcommand", "scriptCommand", "HtmlCallback", "", Tk_Offset(HtmlWidget, zScriptCommand), 0}, {TK_CONFIG_COLOR, "-selectioncolor", "background", "Background", DEF_HTML_SELECTION_COLOR, Tk_Offset(HtmlWidget, selectionColor), 0}, {TK_CONFIG_RELIEF, "-tablerelief", "tableRelief","TableRelief", "raised", Tk_Offset(HtmlWidget, tableRelief), 0}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_HTML_TAKE_FOCUS, Tk_Offset(HtmlWidget, takeFocus), TK_CONFIG_NULL_OK}, {TK_CONFIG_COLOR, "-unvisitedcolor", "foreground", "Foreground", DEF_HTML_UNVISITED, Tk_Offset(HtmlWidget, newLinkColor), 0}, {TK_CONFIG_BOOLEAN, "-underlinehyperlinks", "underlineHyperlinks", "UnderlineHyperlinks", "1", Tk_Offset(HtmlWidget, underlineLinks), 0}, {TK_CONFIG_COLOR, "-visitedcolor", "foreground", "Foreground", DEF_HTML_VISITED, Tk_Offset(HtmlWidget, oldLinkColor), 0}, {TK_CONFIG_PIXELS, "-width", "width", "Width", DEF_HTML_WIDTH, Tk_Offset(HtmlWidget, width), 0}, {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_HTML_SCROLL_COMMAND, Tk_Offset(HtmlWidget, xScrollCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", DEF_HTML_SCROLL_COMMAND, Tk_Offset(HtmlWidget, yScrollCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /* ** Get a copy of the config specs. */ Tk_ConfigSpec *HtmlConfigSpec(void){ return configSpecs; } /* ** Find the width of the usable drawing area in pixels. If the window isn't ** mapped, use the size requested by the user. ** ** The usable drawing area is the area available for displaying rendered ** HTML. The usable drawing area does not include the 3D border or the ** padx and pady boundry within the 3D border. The usable drawing area ** is the size of the clipping window. */ int HtmlUsableWidth(HtmlWidget *htmlPtr){ int w; Tk_Window tkwin = htmlPtr->tkwin; if( tkwin && Tk_IsMapped(tkwin) ){ w = Tk_Width(tkwin) - 2*(htmlPtr->padx + htmlPtr->inset); TestPoint(0); }else{ w = htmlPtr->width; TestPoint(0); } return w; } /* ** Find the height of the usable drawing area in pixels. If the window isn't ** mapped, use the size requested by the user. ** ** The usable drawing area is the area available for displaying rendered ** HTML. The usable drawing area does not include the 3D border or the ** padx and pady boundry within the 3D border. The usable drawing area ** is the size of the clipping window. */ int HtmlUsableHeight(HtmlWidget *htmlPtr){ int h; Tk_Window tkwin = htmlPtr->tkwin; if( tkwin && Tk_IsMapped(tkwin) ){ h = Tk_Height(tkwin) - 2*(htmlPtr->pady + htmlPtr->inset); TestPoint(0); }else{ h = htmlPtr->height; TestPoint(0); } return h; } /* ** Compute a pair of floating point numbers that describe the current ** vertical scroll position. The first number is the fraction of ** the document that is off the top of the visible region and the second ** number is the fraction that is beyond the end of the visible region. */ void HtmlComputeVerticalPosition( HtmlWidget *htmlPtr, char *buf /* Write the two floating point values here */ ){ int actual; /* Size of the viewing area */ double frac1, frac2; actual = HtmlUsableHeight(htmlPtr); if( htmlPtr->maxY <= 0 ){ frac1 = 0.0; frac2 = 1.0; TestPoint(0); }else{ frac1 = (double)htmlPtr->yOffset/(double)htmlPtr->maxY; if( frac1 > 1.0 ){ frac1 = 1.0; TestPoint(0); }else if( frac1 < 0.0 ){ frac1 = 0.0; TestPoint(0); } frac2 = (double)(htmlPtr->yOffset+actual)/(double)htmlPtr->maxY; if( frac2 > 1.0 ){ frac2 = 1.0; TestPoint(0); }else if( frac2 < 0.0 ){ frac2 = 0.0; TestPoint(0); } } sprintf(buf,"%g %g",frac1, frac2); } /* ** Do the same thing for the horizontal direction */ void HtmlComputeHorizontalPosition( HtmlWidget *htmlPtr, char *buf /* Write the two floating point values here */ ){ int actual; /* Size of the viewing area */ double frac1, frac2; actual = HtmlUsableWidth(htmlPtr); if( htmlPtr->maxX <= 0 ){ frac1 = 0.0; frac2 = 1.0; TestPoint(0); }else{ frac1 = (double)htmlPtr->xOffset/(double)htmlPtr->maxX; if( frac1 > 1.0 ){ frac1 = 1.0; TestPoint(0); }else if( frac1 < 0.0 ){ frac1 = 0.0; TestPoint(0); } frac2 = (double)(htmlPtr->xOffset+actual)/(double)htmlPtr->maxX; if( frac2 > 1.0 ){ frac2 = 1.0; TestPoint(0); }else if( frac2 < 0.0 ){ frac2 = 0.0; TestPoint(0); } } sprintf(buf,"%g %g",frac1, frac2); } /* ** Clear the cache of GCs */ static void ClearGcCache(HtmlWidget *htmlPtr){ int i; for(i=0; i<N_CACHE_GC; i++){ if( htmlPtr->aGcCache[i].index ){ Tk_FreeGC(htmlPtr->display, htmlPtr->aGcCache[i].gc); htmlPtr->aGcCache[i].index = 0; TestPoint(0); }else{ TestPoint(0); } } } /* ** This routine is called when the widget command is deleted. If the ** widget isn't already in the process of being destroyed, this command ** starts that process rolling. ** ** This routine can be called in two ways. ** ** (1) The window is destroyed, which causes the command to be deleted. ** In this case, we don't have to do anything. ** ** (2) The command only is deleted (ex: "rename .html {}"). In that ** case we need to destroy the window. */ static void HtmlCmdDeletedProc(ClientData clientData){ HtmlWidget *htmlPtr = (HtmlWidget*) clientData; if (htmlPtr != NULL && htmlPtr->tkwin!=NULL ) { Tk_Window tkwin = htmlPtr->tkwin; htmlPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* ** Reset the main layout context in the main widget. This happens ** before we redo the layout, or just before deleting the widget. */ static void ResetLayoutContext(HtmlWidget *htmlPtr){ htmlPtr->layoutContext.headRoom = 0; htmlPtr->layoutContext.top = 0; htmlPtr->layoutContext.bottom = 0; HtmlClearMarginStack(&htmlPtr->layoutContext.leftMargin); HtmlClearMarginStack(&htmlPtr->layoutContext.rightMargin); } /* ** This routine is invoked in order to redraw all or part of the HTML ** widget. This might happen because the display has changed, or in ** response to an expose event. In all cases, though, this routine ** is called by an idle callback. */ static void HtmlRedrawCallback(ClientData clientData){ HtmlWidget *htmlPtr = (HtmlWidget*)clientData; Tk_Window tkwin = htmlPtr->tkwin; Tk_Window clipwin = htmlPtr->clipwin; Pixmap pixmap; /* The buffer on which to render HTML */ int x, y, w, h; /* Virtual canvas coordinates of area to draw */ int hw; /* highlight thickness */ int insetX, insetY; /* Total highlight thickness, border width and ** padx/y */ int clipwinH, clipwinW; /* Width and height of the clipping window */ HtmlBlock *pBlock; /* For looping over blocks to be drawn */ int redoSelection = 0; /* True to recompute the selection */ /* ** Don't bother doing anything if the widget is in the process of ** being destroyed. */ if( tkwin==0 ){ goto redrawExit; } /* ** Recompute the layout, if necessary or requested. ** ** Calling HtmlLayout() is tricky because HtmlLayout() may invoke one ** or more callbacks (thru the "-imagecommand" callback, for instance) ** and these callbacks could, in theory, do nasty things like delete ** or unmap this widget. So we have to take precautions: ** ** * Don't remove the REDRAW_PENDING flag until after HtmlLayout() ** has been called, to prevent a recursive call to HtmlRedrawCallback(). ** ** * Call HtmlLock() on the htmlPtr structure to prevent it from ** being deleted out from under us. ** */ if( (htmlPtr->flags & RESIZE_ELEMENTS)!=0 && (htmlPtr->flags & STYLER_RUNNING)==0 ){ HtmlImage *pImage; for(pImage=htmlPtr->imageList; pImage; pImage=pImage->pNext){ pImage->pList = 0; } htmlPtr->lastSized = 0; htmlPtr->flags &= ~RESIZE_ELEMENTS; htmlPtr->flags |= RELAYOUT; } /* We used to make a distinction between RELAYOUT and EXTEND_LAYOUT. ** RELAYOUT would be used when the widget was resized, but the ** less compute-intensive EXTEND_LAYOUT would be used when new ** text was appended. ** ** Unfortunately, EXTEND_LAYOUT has some problem that arise when ** tables are used. The quick fix is to make an EXTEND_LAYOUT do ** a complete RELAYOUT. Someday, we need to fix EXTEND_LAYOUT so ** that it works right... */ if( (htmlPtr->flags & (RELAYOUT|EXTEND_LAYOUT))!=0 && (htmlPtr->flags & STYLER_RUNNING)==0 ){ htmlPtr->nextPlaced = 0; htmlPtr->nInput = 0; htmlPtr->varId = 0; htmlPtr->maxX = 0; htmlPtr->maxY = 0; ResetLayoutContext(htmlPtr); htmlPtr->firstBlock = 0; htmlPtr->lastBlock = 0; redoSelection = 1; htmlPtr->flags &= ~RELAYOUT; htmlPtr->flags |= HSCROLL | VSCROLL | REDRAW_TEXT | EXTEND_LAYOUT; } if( (htmlPtr->flags & EXTEND_LAYOUT) && htmlPtr->pFirst!=0 ){ HtmlLock(htmlPtr); HtmlLayout(htmlPtr); if( HtmlUnlock(htmlPtr) ) goto redrawExit; tkwin = htmlPtr->tkwin; htmlPtr->flags &= ~EXTEND_LAYOUT; HtmlFormBlocks(htmlPtr); HtmlMapControls(htmlPtr); if( redoSelection && htmlPtr->selBegin.p && htmlPtr->selEnd.p ){ HtmlUpdateSelection(htmlPtr,1); HtmlUpdateInsert(htmlPtr); } } htmlPtr->flags &= ~REDRAW_PENDING; /* No need to do any actual drawing if we aren't mapped */ if( !Tk_IsMapped(tkwin) ){ goto redrawExit; } /* Redraw the scrollbars. Take care here, since the scrollbar ** update command could (in theory) delete the html widget, or ** even the whole interpreter. Preserve critical data structures, ** and check to see if we are still alive before continuing. */ if( (htmlPtr->flags & (HSCROLL|VSCROLL)) != 0 ){ Tcl_Interp *interp = htmlPtr->interp; int result; char buf[200]; if( (htmlPtr->flags & HSCROLL)!=0 ){ if( htmlPtr->xScrollCmd && htmlPtr->xScrollCmd[0] ){ HtmlComputeHorizontalPosition(htmlPtr,buf); HtmlLock(htmlPtr); result = Tcl_VarEval(interp, htmlPtr->xScrollCmd, " ", buf, 0); if( HtmlUnlock(htmlPtr) ) goto redrawExit; if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (horizontal scrolling command executed by html widget)"); Tcl_BackgroundError(interp); TestPoint(0); } } htmlPtr->flags &= ~HSCROLL; } if( (htmlPtr->flags & VSCROLL)!=0 && tkwin && Tk_IsMapped(tkwin) ){ if( htmlPtr->yScrollCmd && htmlPtr->yScrollCmd[0] ){ Tcl_Interp *interp = htmlPtr->interp; int result; char buf[200]; HtmlComputeVerticalPosition(htmlPtr,buf); HtmlLock(htmlPtr); result = Tcl_VarEval(interp, htmlPtr->yScrollCmd, " ", buf, 0); if( HtmlUnlock(htmlPtr) ) goto redrawExit; if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (horizontal scrolling command executed by html widget)"); Tcl_BackgroundError(interp); TestPoint(0); } } htmlPtr->flags &= ~VSCROLL; } tkwin = htmlPtr->tkwin; if( tkwin==0 || !Tk_IsMapped(tkwin) ){ goto redrawExit; } if( htmlPtr->flags & REDRAW_PENDING ){ return; } clipwin = htmlPtr->clipwin; if( clipwin==0 ){ TestPoint(0); goto redrawExit; } } /* Redraw the focus highlight, if requested */ hw = htmlPtr->highlightWidth; if( htmlPtr->flags & REDRAW_FOCUS ){ if( hw>0 ){ GC gc; Tk_Window tkwin = htmlPtr->tkwin; if( htmlPtr->flags & GOT_FOCUS ){ gc = Tk_GCForColor(htmlPtr->highlightColorPtr, Tk_WindowId(tkwin)); TestPoint(0); }else{ gc = Tk_GCForColor(htmlPtr->highlightBgColorPtr, Tk_WindowId(tkwin)); TestPoint(0); } Tk_DrawFocusHighlight(tkwin, gc, hw, Tk_WindowId(tkwin)); } htmlPtr->flags &= ~REDRAW_FOCUS; } /* Draw the borders around the parameter of the window. This is ** drawn directly -- it is not double buffered. */ if( htmlPtr->flags & REDRAW_BORDER ){ htmlPtr->flags &= ~REDRAW_BORDER; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), htmlPtr->border, hw, /* x */ hw, /* y */ Tk_Width(tkwin) - 2*hw, /* width */ Tk_Height(tkwin) - 2*hw, /* height */ htmlPtr->borderWidth, htmlPtr->relief); } /* ** If the styler is in a callback, unmap the clipping window and ** abort further processing. */ if( htmlPtr->flags & STYLER_RUNNING ){ if( Tk_IsMapped(clipwin) ){ Tk_UnmapWindow(clipwin); } goto earlyOut; } /* ** If we don't have a clipping window, then something is seriously ** wrong. We might as well give up. */ if( clipwin==NULL ){ TestPoint(0); goto earlyOut; } /* Resize, reposition and map the clipping window, if necessary */ insetX = htmlPtr->padx + htmlPtr->inset; insetY = htmlPtr->pady + htmlPtr->inset; if( htmlPtr->flags & RESIZE_CLIPWIN ){ int h, w; Tk_MoveResizeWindow(clipwin, insetX, insetY, htmlPtr->realWidth - 2*insetX, htmlPtr->realHeight - 2*insetY); if( !Tk_IsMapped(clipwin) ){ Tk_MapWindow(clipwin); } h = htmlPtr->realHeight - 2*insetY; if( htmlPtr->yOffset + h > htmlPtr->maxY ){ htmlPtr->yOffset = htmlPtr->maxY - h; } if( htmlPtr->yOffset < 0 ){ htmlPtr->yOffset = 0; } w = htmlPtr->realWidth - 2*insetX; if( htmlPtr->xOffset + h > htmlPtr->maxX ){ htmlPtr->xOffset = htmlPtr->maxX - w; } if( htmlPtr->xOffset < 0 ){ htmlPtr->xOffset = 0; } htmlPtr->flags &= ~RESIZE_CLIPWIN; } HtmlMapControls(htmlPtr); /* ** Compute the virtual canvas coordinates corresponding to the ** dirty region of the clipping window. */ clipwinW = Tk_Width(clipwin); clipwinH = Tk_Height(clipwin); if( htmlPtr->flags & REDRAW_TEXT ){ w = clipwinW; h = clipwinH; x = htmlPtr->xOffset; y = htmlPtr->yOffset; htmlPtr->dirtyLeft = 0; htmlPtr->dirtyTop = 0; htmlPtr->flags &= ~REDRAW_TEXT; }else{ if( htmlPtr->dirtyLeft < 0 ){ htmlPtr->dirtyLeft = 0; TestPoint(0); } if( htmlPtr->dirtyRight > clipwinW ){ htmlPtr->dirtyRight = clipwinW; TestPoint(0); } if( htmlPtr->dirtyTop < 0 ){ htmlPtr->dirtyTop = 0; TestPoint(0); } if( htmlPtr->dirtyBottom > clipwinH ){ htmlPtr->dirtyBottom = clipwinH; TestPoint(0); } w = htmlPtr->dirtyRight - htmlPtr->dirtyLeft; h = htmlPtr->dirtyBottom - htmlPtr->dirtyTop; x = htmlPtr->xOffset + htmlPtr->dirtyLeft; y = htmlPtr->yOffset + htmlPtr->dirtyTop; } /* Skip the rest of the drawing process if the area to be refreshed is ** less than zero */ if( w>0 && h>0 ){ Display *display = htmlPtr->display; int dead; GC gcBg; XRectangle xrec; /* printf("Redraw %dx%d at %d,%d\n", w, h, x, y); */ /* Allocate and clear a pixmap upon which to draw */ gcBg = HtmlGetGC(htmlPtr, COLOR_Background, FONT_Any); pixmap = Tk_GetPixmap(display, Tk_WindowId(clipwin),w,h,Tk_Depth(clipwin)); xrec.x = 0; xrec.y = 0; xrec.width = w; xrec.height = h; XFillRectangles(display, pixmap, gcBg, &xrec, 1); /* Render all visible HTML onto the pixmap */ HtmlLock(htmlPtr); for(pBlock=htmlPtr->firstBlock; pBlock; pBlock=pBlock->pNext){ if( pBlock->top <= y+h && pBlock->bottom >= y && pBlock->left <= x+w && pBlock->right >= x ){ HtmlBlockDraw(htmlPtr,pBlock,pixmap,x,y,w,h); if( htmlPtr->tkwin==0 ) break; } } dead = HtmlUnlock(htmlPtr); /* Finally, copy the pixmap onto the window and delete the pixmap */ if( !dead ){ XCopyArea(display, pixmap, Tk_WindowId(clipwin), gcBg, 0, 0, w, h, htmlPtr->dirtyLeft, htmlPtr->dirtyTop); } Tk_FreePixmap(display, pixmap); if( dead ) goto redrawExit; /* XFlush(display); */ } /* Redraw images, if requested */ if( htmlPtr->flags & REDRAW_IMAGES ){ HtmlImage *pImage; HtmlElement *pElem; int top, bottom, left, right; /* Coordinates of the clipping window */ int imageTop; /* Top edge of image */ top = htmlPtr->yOffset; bottom = top + HtmlUsableHeight(htmlPtr); left = htmlPtr->xOffset; right = left + HtmlUsableWidth(htmlPtr); for(pImage = htmlPtr->imageList; pImage; pImage=pImage->pNext){ for(pElem = pImage->pList; pElem; pElem=pElem->image.pNext){ if( pElem->image.redrawNeeded==0 ) continue; imageTop = pElem->image.y - pElem->image.ascent; if( imageTop > bottom || imageTop + pElem->image.h < top || pElem->image.x > right || pElem->image.x + pElem->image.w < left ){ TestPoint(0); continue; } HtmlDrawImage(pElem, Tk_WindowId(htmlPtr->clipwin), left, top, right, bottom); } } htmlPtr->flags &= ~REDRAW_IMAGES; } /* Set the dirty region to the empty set. */ earlyOut: htmlPtr->dirtyTop = LARGE_NUMBER; htmlPtr->dirtyLeft = LARGE_NUMBER; htmlPtr->dirtyBottom = 0; htmlPtr->dirtyRight = 0; redrawExit: return; } /* ** Make sure that a call to the HtmlRedrawCallback() routine has been ** queued. */ void HtmlScheduleRedraw(HtmlWidget *htmlPtr){ if( (htmlPtr->flags & REDRAW_PENDING)==0 && htmlPtr->tkwin!=0 && Tk_IsMapped(htmlPtr->tkwin) ){ Tcl_DoWhenIdle(HtmlRedrawCallback, (ClientData)htmlPtr); htmlPtr->flags |= REDRAW_PENDING; } } /* ** If any part of the screen needs to be redrawn, Then call this routine ** with the values of a box (in window coordinates) that needs to be ** redrawn. This routine will make sure an idle callback is scheduled ** to do the redraw. ** ** The box coordinates are relative to the clipping window (clipwin), ** not the main window (tkwin). */ void HtmlRedrawArea( HtmlWidget *htmlPtr, /* The widget to be redrawn */ int left, int top, /* Top left corner of area to redraw */ int right, int bottom /* bottom right corner of area to redraw */ ){ if( bottom < 0 ){ TestPoint(0); return; } if( top > htmlPtr->realHeight ){ TestPoint(0); return; } if( right < 0 ){ TestPoint(0); return; } if( left > htmlPtr->realWidth ){ TestPoint(0); return; } if( htmlPtr->dirtyTop > top ){ htmlPtr->dirtyTop = top; TestPoint(0);} if( htmlPtr->dirtyLeft > left ){ htmlPtr->dirtyLeft = left; TestPoint(0);} if( htmlPtr->dirtyBottom < bottom ){ htmlPtr->dirtyBottom = bottom; TestPoint(0); } if( htmlPtr->dirtyRight < right ){ htmlPtr->dirtyRight = right; TestPoint(0);} HtmlScheduleRedraw(htmlPtr); TestPoint(0); } /* Redraw the HtmlBlock given. */ void HtmlRedrawBlock(HtmlWidget *htmlPtr, HtmlBlock *p){ if( p ){ HtmlRedrawArea(htmlPtr, p->left - htmlPtr->xOffset, p->top - htmlPtr->yOffset, p->right - htmlPtr->xOffset + 1, p->bottom - htmlPtr->yOffset ); TestPoint(0); }else{ TestPoint(0); } } /* ** Call this routine to force the entire widget to be redrawn. */ void HtmlRedrawEverything(HtmlWidget *htmlPtr){ htmlPtr->flags |= REDRAW_FOCUS | REDRAW_TEXT | REDRAW_BORDER; HtmlScheduleRedraw(htmlPtr); TestPoint(0); } /* ** Do the redrawing right now. Don't wait. */ #if 0 /* NOT_USED */ static void HtmlRedrawPush(HtmlWidget *htmlPtr){ if( htmlPtr->flags & REDRAW_PENDING ){ Tcl_CancelIdleCall(HtmlRedrawCallback, (ClientData)htmlPtr); TestPoint(0); }else{ TestPoint(0); } HtmlRedrawCallback( (ClientData)htmlPtr ); } #endif /* ** Call this routine to cause all of the rendered HTML at the ** virtual canvas coordinate of Y and beyond to be redrawn. */ void HtmlRedrawText(HtmlWidget *htmlPtr, int y){ int yOffset; /* Top-most visible canvas coordinate */ int clipHeight; /* Height of the clipping window */ yOffset = htmlPtr->yOffset; clipHeight = HtmlUsableHeight(htmlPtr); y -= yOffset; if( y < clipHeight ){ HtmlRedrawArea(htmlPtr, 0, y, LARGE_NUMBER, clipHeight); TestPoint(0); }else{ TestPoint(0); } } /* ** Recalculate the preferred size of the html widget and pass this ** along to the geometry manager. */ static void HtmlRecomputeGeometry(HtmlWidget *htmlPtr){ int w, h; /* Total width and height of the widget */ htmlPtr->inset = htmlPtr->highlightWidth + htmlPtr->borderWidth; w = htmlPtr->width + 2*(htmlPtr->padx + htmlPtr->inset); h = htmlPtr->height + 2*(htmlPtr->pady + htmlPtr->inset); Tk_GeometryRequest(htmlPtr->tkwin, w, h); Tk_SetInternalBorder(htmlPtr->tkwin, htmlPtr->inset); TestPoint(0); } /* ** This routine is called in order to process a "configure" subcommand ** on the given html widget. */ int ConfigureHtmlWidget( Tcl_Interp *interp, /* Write error message to this interpreter */ HtmlWidget *htmlPtr, /* The Html widget to be configured */ int argc, /* Number of configuration arguments */ char **argv, /* Text of configuration arguments */ int flags, /* Configuration flags */ int realign /* Always do a redraw if set */ ){ int rc; int i; int redraw = realign; /* True if a redraw is required. */ /* Scan thru the configuration options to see if we need to redraw ** the widget. */ for(i=0; redraw==0 && i<argc; i+=2){ int c; int n; if( argv[i][0]!='-' ){ redraw = 1; break; } c = argv[i][1]; n = strlen(argv[i]); if( c=='c' && n>4 && strncmp(argv[i],"-cursor",n)==0 ){ /* do nothing */ }else /* The default case */ { redraw = 1; } } rc = Tk_ConfigureWidget(interp, htmlPtr->tkwin, configSpecs, argc, argv, (char *) htmlPtr, flags); if( rc!=TCL_OK || redraw==0 ){ TestPoint(0); return rc; } memset(htmlPtr->fontValid, 0, sizeof(htmlPtr->fontValid)); htmlPtr->apColor[COLOR_Normal] = htmlPtr->fgColor; htmlPtr->apColor[COLOR_Visited] = htmlPtr->oldLinkColor; htmlPtr->apColor[COLOR_Unvisited] = htmlPtr->newLinkColor; htmlPtr->apColor[COLOR_Selection] = htmlPtr->selectionColor; htmlPtr->apColor[COLOR_Background] = Tk_3DBorderColor(htmlPtr->border); Tk_SetBackgroundFromBorder(htmlPtr->tkwin, htmlPtr->border); if( htmlPtr->highlightWidth < 0 ){ htmlPtr->highlightWidth = 0; TestPoint(0);} if (htmlPtr->padx < 0) { htmlPtr->padx = 0; TestPoint(0);} if (htmlPtr->pady < 0) { htmlPtr->pady = 0; TestPoint(0);} if (htmlPtr->width < 100) { htmlPtr->width = 100; TestPoint(0);} if (htmlPtr->height < 100) { htmlPtr->height = 100; TestPoint(0);} if (htmlPtr->borderWidth < 0) {htmlPtr->borderWidth = 0; TestPoint(0);} htmlPtr->flags |= RESIZE_ELEMENTS | RELAYOUT | REDRAW_BORDER | RESIZE_CLIPWIN; HtmlRecomputeGeometry(htmlPtr); HtmlRedrawEverything(htmlPtr); ClearGcCache(htmlPtr); return rc; } /* ** Delete a single HtmlElement */ void HtmlDeleteElement(HtmlElement *p){ switch( p->base.type ){ case Html_Block: if( p->block.z ){ HtmlFree(p->block.z); } break; default: break; } HtmlFree(p); } /* ** Erase all data from the HTML widget. Bring it back to an ** empty screen. ** ** This happens (for example) when the "clear" method is invoked ** on the widget, or just before the widget is deleted. */ void HtmlClear(HtmlWidget *htmlPtr){ int i; HtmlElement *p, *pNext; HtmlDeleteControls(htmlPtr); for(p=htmlPtr->pFirst; p; p=pNext){ pNext = p->pNext; HtmlDeleteElement(p); } htmlPtr->pFirst = 0; htmlPtr->pLast = 0; htmlPtr->nToken = 0; if( htmlPtr->zText ){ HtmlFree(htmlPtr->zText); } htmlPtr->zText = 0; htmlPtr->nText = 0; htmlPtr->nAlloc = 0; htmlPtr->nComplete = 0; htmlPtr->iPlaintext = 0; for(i=N_PREDEFINED_COLOR; i<N_COLOR; i++){ if( htmlPtr->apColor[i] != 0 ){ Tk_FreeColor(htmlPtr->apColor[i]); htmlPtr->apColor[i] = 0; } } for(i=0; i<N_COLOR; i++){ htmlPtr->iDark[i] = 0; htmlPtr->iLight[i] = 0; } htmlPtr->colorUsed = 0; while( htmlPtr->imageList ){ HtmlImage *p = htmlPtr->imageList; htmlPtr->imageList = p->pNext; Tk_FreeImage(p->image); HtmlFree(p); TestPoint(0); } while( htmlPtr->styleStack ){ HtmlStyleStack *p = htmlPtr->styleStack; htmlPtr->styleStack = p->pNext; HtmlFree(p); } ClearGcCache(htmlPtr); ResetLayoutContext(htmlPtr); if( htmlPtr->zBaseHref ){ HtmlFree(htmlPtr->zBaseHref); htmlPtr->zBaseHref = 0; } htmlPtr->lastSized = 0; htmlPtr->nextPlaced = 0; htmlPtr->firstBlock = 0; htmlPtr->lastBlock = 0; htmlPtr->nInput = 0; htmlPtr->nForm = 0; htmlPtr->varId = 0; htmlPtr->paraAlignment = ALIGN_None; htmlPtr->rowAlignment = ALIGN_None; htmlPtr->anchorFlags = 0; htmlPtr->inDt = 0; htmlPtr->anchorStart = 0; htmlPtr->formStart = 0; htmlPtr->innerList = 0; htmlPtr->maxX = 0; htmlPtr->maxY = 0; htmlPtr->xOffset = 0; htmlPtr->yOffset = 0; htmlPtr->pInsBlock = 0; htmlPtr->ins.p = 0; htmlPtr->selBegin.p = 0; htmlPtr->selEnd.p = 0; htmlPtr->pSelStartBlock = 0; htmlPtr->pSelEndBlock = 0; } /* ** This routine attempts to delete the widget structure. But it won't ** do it if the widget structure is locked. If the widget structure is ** locked, then when HtmlUnlock() is called and the lock count reaches ** zero, this routine will be called to finish the job. */ static void DestroyHtmlWidget(HtmlWidget *htmlPtr){ int i; if( htmlPtr->locked>0 ) return; Tcl_DeleteCommand(htmlPtr->interp, htmlPtr->zCmdName); Tcl_DeleteCommand(htmlPtr->interp, htmlPtr->zClipwin); HtmlClear(htmlPtr); Tk_FreeOptions(configSpecs, (char*) htmlPtr, htmlPtr->display, 0); for(i=0; i<N_FONT; i++){ if( htmlPtr->aFont[i] != 0 ){ Tk_FreeFont(htmlPtr->aFont[i]); htmlPtr->aFont[i] = 0; } } for(i=0; i<Html_TypeCount; i++){ if( htmlPtr->zHandler[i] ){ HtmlFree(htmlPtr->zHandler[i]); htmlPtr->zHandler[i] = 0; } } if( htmlPtr->insTimer ){ Tcl_DeleteTimerHandler(htmlPtr->insTimer); htmlPtr->insTimer = 0; } HtmlFree(htmlPtr->zClipwin); HtmlFree(htmlPtr); } /* ** Remove a lock from the HTML widget. If the widget has been ** deleted, then delete the widget structure. Return 1 if the ** widget has been deleted. Return 0 if it still exists. ** ** Normal Tk code (that is to say, code in the Tk core) uses ** Tcl_Preserve() and Tcl_Release() to accomplish what this ** function does. But preserving and releasing are much more ** common in this code than in regular widgets, so this routine ** was invented to do the same thing easier and faster. */ int HtmlUnlock(HtmlWidget *htmlPtr){ htmlPtr->locked--; if( htmlPtr->tkwin==0 && htmlPtr->locked<=0 ){ Tcl_Interp *interp = htmlPtr->interp; Tcl_Preserve(interp); DestroyHtmlWidget(htmlPtr); Tcl_Release(interp); return 1; } return htmlPtr->tkwin==0; } /* ** Lock the HTML widget. This prevents the widget structure from ** being deleted even if the widget itself is destroyed. There must ** be a call to HtmlUnlock() to release the structure. */ void HtmlLock(HtmlWidget *htmlPtr){ htmlPtr->locked++; } /* ** This routine checks to see if an HTML widget has been ** destroyed. It is always called after calling HtmlLock(). ** ** If the widget has been destroyed, then the structure ** is unlocked and the function returns 1. If the widget ** has not been destroyed, then the structure is not unlocked ** and the routine returns 0. ** ** This routine is intended for use in code like the following: ** ** HtmlLock(htmlPtr); ** // Do something that might destroy the widget ** if( HtmlIsDead(htmlPtr) ) return; ** // Do something that might destroy the widget ** if( HtmlIsDead(htmlPtr) ) return; ** // Do something that might destroy the widget ** if( HtmlUnlock(htmlPtr) ) return; */ int HtmlIsDead(HtmlWidget *htmlPtr){ if( htmlPtr->tkwin==0 ){ HtmlUnlock(htmlPtr); return 1; } return 0; } /* ** Flash the insertion cursor. */ void HtmlFlashCursor(ClientData clientData){ HtmlWidget *htmlPtr = (HtmlWidget*)clientData; if( htmlPtr->pInsBlock==0 || htmlPtr->insOnTime<=0 || htmlPtr->insOffTime<=0 ){ htmlPtr->insTimer = 0; TestPoint(0); return; } HtmlRedrawBlock(htmlPtr, htmlPtr->pInsBlock); if( (htmlPtr->flags & GOT_FOCUS)==0 ){ htmlPtr->insStatus = 0; htmlPtr->insTimer = 0; TestPoint(0); }else if( htmlPtr->insStatus ){ htmlPtr->insTimer = Tcl_CreateTimerHandler(htmlPtr->insOffTime, HtmlFlashCursor, clientData); htmlPtr->insStatus = 0; TestPoint(0); }else{ htmlPtr->insTimer = Tcl_CreateTimerHandler(htmlPtr->insOnTime, HtmlFlashCursor, clientData); htmlPtr->insStatus = 1; TestPoint(0); } } /* ** Return a GC from the cache. As many as N_CACHE_GCs are kept valid ** at any one time. They are replaced using an LRU algorithm. ** ** A value of FONT_Any (-1) for the font means "don't care". */ GC HtmlGetGC(HtmlWidget *htmlPtr, int color, int font){ int i, j; GcCache *p = htmlPtr->aGcCache; XGCValues gcValues; int mask; Tk_Font tkfont; /* ** Check for an existing GC. */ if( color < 0 || color >= N_COLOR ){ color = 0; TestPoint(0); } if( font < FONT_Any || font >= N_FONT ){ font = FONT_Default; TestPoint(0); } for(i=0; i<N_CACHE_GC; i++, p++){ if( p->index==0 ){ TestPoint(0); continue; } if( (font<0 || p->font==font) && p->color==color ){ if( p->index>1 ){ for(j=0; j<N_CACHE_GC; j++){ if( htmlPtr->aGcCache[j].index && htmlPtr->aGcCache[j].index < p->index ){ htmlPtr->aGcCache[j].index++; } } p->index = 1; } return htmlPtr->aGcCache[i].gc; } } /* ** No GC matches. Find a place to allocate a new GC. */ p = htmlPtr->aGcCache; for(i=0; i<N_CACHE_GC; i++, p++){ if( p->index==0 || p->index==N_CACHE_GC ){ TestPoint(0); break; } } if( p->index ){ Tk_FreeGC(htmlPtr->display, p->gc); } gcValues.foreground = htmlPtr->apColor[color]->pixel; gcValues.graphics_exposures = True; mask = GCForeground | GCGraphicsExposures; if( font<0 ){ font = FONT_Default; TestPoint(0); } tkfont = HtmlGetFont(htmlPtr, font); if( tkfont ){ gcValues.font = Tk_FontId(tkfont); mask |= GCFont; } p->gc = Tk_GetGC(htmlPtr->tkwin, mask, &gcValues); if( p->index==0 ){ p->index = N_CACHE_GC + 1; TestPoint(0); } for(j=0; j<N_CACHE_GC; j++){ if( htmlPtr->aGcCache[j].index && htmlPtr->aGcCache[j].index < p->index ){ htmlPtr->aGcCache[j].index++; } } p->index = 1; p->font = font; p->color = color; return p->gc; } /* ** Retrieve any valid GC. The font and color don't matter since the ** GC will only be used for copying. */ GC HtmlGetAnyGC(HtmlWidget *htmlPtr){ int i; GcCache *p = htmlPtr->aGcCache; for(i=0; i<N_CACHE_GC; i++, p++){ if( p->index ){ TestPoint(0); return p->gc; } } TestPoint(0); return HtmlGetGC(htmlPtr, COLOR_Normal, FONT_Default); } /* ** All window events (for both tkwin and clipwin) are ** sent to this routine. */ static void HtmlEventProc(ClientData clientData, XEvent *eventPtr){ HtmlWidget *htmlPtr = (HtmlWidget*) clientData; int redraw_needed = 0; XConfigureRequestEvent *p; switch( eventPtr->type ){ case GraphicsExpose: case Expose: if( htmlPtr->tkwin==0 ){ /* The widget is being deleted. Do nothing */ TestPoint(0); }else if( eventPtr->xexpose.window!=Tk_WindowId(htmlPtr->tkwin) ){ /* Exposure in the clipping window */ HtmlRedrawArea(htmlPtr, eventPtr->xexpose.x - 1, eventPtr->xexpose.y - 1, eventPtr->xexpose.x + eventPtr->xexpose.width + 1, eventPtr->xexpose.y + eventPtr->xexpose.height + 1); TestPoint(0); }else{ /* Exposure in the main window */ htmlPtr->flags |= REDRAW_BORDER; HtmlScheduleRedraw(htmlPtr); TestPoint(0); } break; case DestroyNotify: if( (htmlPtr->flags & REDRAW_PENDING) ){ Tcl_CancelIdleCall(HtmlRedrawCallback, (ClientData)htmlPtr); htmlPtr->flags &= ~REDRAW_PENDING; } if( htmlPtr->tkwin != 0 ){ if( eventPtr->xany.window!=Tk_WindowId(htmlPtr->tkwin) ){ Tk_DestroyWindow(htmlPtr->tkwin); htmlPtr->clipwin = 0; break; } htmlPtr->tkwin = 0; Tcl_DeleteCommand(htmlPtr->interp, htmlPtr->zCmdName); Tcl_DeleteCommand(htmlPtr->interp, htmlPtr->zClipwin); } HtmlUnlock(htmlPtr); break; case ConfigureNotify: if( htmlPtr->tkwin!=0 && eventPtr->xconfigure.window==Tk_WindowId(htmlPtr->tkwin) ){ p = (XConfigureRequestEvent*)eventPtr; if( p->width != htmlPtr->realWidth ){ redraw_needed = 1; htmlPtr->realWidth = p->width; TestPoint(0); }else{ TestPoint(0); } if( p->height != htmlPtr->realHeight ){ redraw_needed = 1; htmlPtr->realHeight = p->height; TestPoint(0); }else{ TestPoint(0); } if( redraw_needed ){ htmlPtr->flags |= RELAYOUT | VSCROLL | HSCROLL | RESIZE_CLIPWIN; HtmlRedrawEverything(htmlPtr); TestPoint(0); }else{ TestPoint(0); } } break; case FocusIn: if( htmlPtr->tkwin!=0 && eventPtr->xfocus.window==Tk_WindowId(htmlPtr->tkwin) && eventPtr->xfocus.detail != NotifyInferior ){ htmlPtr->flags |= GOT_FOCUS | REDRAW_FOCUS; HtmlScheduleRedraw(htmlPtr); HtmlUpdateInsert(htmlPtr); TestPoint(0); }else{ TestPoint(0); } break; case FocusOut: if( htmlPtr->tkwin!=0 && eventPtr->xfocus.window==Tk_WindowId(htmlPtr->tkwin) && eventPtr->xfocus.detail != NotifyInferior ){ htmlPtr->flags &= ~GOT_FOCUS; htmlPtr->flags |= REDRAW_FOCUS; HtmlScheduleRedraw(htmlPtr); TestPoint(0); }else{ TestPoint(0); } break; } } /* ** The rendering and layout routines should call this routine in order to get ** a font structure. The iFont parameter specifies which of the N_FONT ** fonts should be obtained. The font is allocated if necessary. ** ** Because the -fontcommand callback can be invoked, this function can ** (in theory) cause the HTML widget to be changed arbitrarily or even ** deleted. Callers of this function much be prepared to be called ** recursively and/or to have the HTML widget deleted out from under ** them. This routine will return NULL if the HTML widget is deleted. */ Tk_Font HtmlGetFont( HtmlWidget *htmlPtr, /* The HTML widget to which the font applies */ int iFont /* Which font to obtain */ ){ Tk_Font toFree = 0; if( iFont<0 ){ iFont = 0; TestPoint(0); } if( iFont>=N_FONT ){ iFont = N_FONT - 1; CANT_HAPPEN; } /* ** If the font has previously been allocated, but the "fontValid" bitmap ** shows it is no longer valid, then mark it for freeing later. We use ** a policy of allocate-before-free because Tk's font cache operates ** much more efficiently that way. */ if( !FontIsValid(htmlPtr, iFont) && htmlPtr->aFont[iFont]!=0 ){ toFree = htmlPtr->aFont[iFont]; htmlPtr->aFont[iFont] = 0; TestPoint(0); } /* ** If we need to allocate a font, first construct the font name then ** allocate it. */ if( htmlPtr->aFont[iFont]==0 ){ char name[200]; /* Name of the font */ name[0] = 0; /* Run the -fontcommand if it is specified */ if( htmlPtr->zFontCommand && htmlPtr->zFontCommand[0] ){ int iFam; /* The font family index. Value between 0 and 7 */ Tcl_DString str; /* The command we'll execute to get the font name */ char *zSep = ""; /* Separator between font attributes */ int rc; /* Return code from the font command */ char zBuf[100]; /* Temporary buffer */ Tcl_DStringInit(&str); Tcl_DStringAppend(&str, htmlPtr->zFontCommand, -1); sprintf(zBuf, " %d {", FontSize(iFont)+1); Tcl_DStringAppend(&str,zBuf, -1); iFam = iFont / N_FONT_SIZE ; if( iFam & 1 ){ Tcl_DStringAppend(&str,"bold",-1); zSep = " "; } if( iFam & 2 ){ Tcl_DStringAppend(&str,zSep,-1); Tcl_DStringAppend(&str,"italic",-1); zSep = " "; } if( iFam & 4 ){ Tcl_DStringAppend(&str,zSep,-1); Tcl_DStringAppend(&str,"fixed",-1); } Tcl_DStringAppend(&str,"}",-1); HtmlLock(htmlPtr); rc = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); if( HtmlUnlock(htmlPtr) ){ return NULL; } if( rc!=TCL_OK ){ Tcl_AddErrorInfo(htmlPtr->interp, "\n (-fontcommand callback of HTML widget)"); Tcl_BackgroundError(htmlPtr->interp); }else{ sprintf(name,"%.100s", htmlPtr->interp->result); } Tcl_ResetResult(htmlPtr->interp); } /* ** If the -fontcommand failed or returned an empty string, or if ** there is no -fontcommand, then get the default font name. */ if( name[0]==0 ){ char *familyStr = ""; int iFamily; int iSize; int size; iFamily = iFont / N_FONT_SIZE; iSize = iFont % N_FONT_SIZE + 1; switch( iFamily ){ case 0: familyStr = "helvetica -%d"; break; case 1: familyStr = "helvetica -%d bold"; break; case 2: familyStr = "helvetica -%d italic"; break; case 3: familyStr = "helvetica -%d bold italic"; break; case 4: familyStr = "courier -%d"; break; case 5: familyStr = "courier -%d bold"; break; case 6: familyStr = "courier -%d italic"; break; case 7: familyStr = "courier -%d bold italic"; break; default: familyStr = "helvetica -14"; CANT_HAPPEN; } switch( iSize ){ case 1: size = 8; break; case 2: size = 10; break; case 3: size = 12; break; case 4: size = 14; break; case 5: size = 16; break; case 6: size = 18; break; case 7: size = 24; break; default: size = 14; CANT_HAPPEN; } sprintf(name, familyStr, size); } /* Get the named font */ htmlPtr->aFont[iFont] = Tk_GetFont(htmlPtr->interp, htmlPtr->tkwin, name); if( htmlPtr->aFont[iFont]==0 ){ Tcl_AddErrorInfo(htmlPtr->interp, "\n (trying to create a font named \""); Tcl_AddErrorInfo(htmlPtr->interp, name); Tcl_AddErrorInfo(htmlPtr->interp, "\" in the HTML widget)"); Tcl_BackgroundError(htmlPtr->interp); htmlPtr->aFont[iFont] = Tk_GetFont(htmlPtr->interp, htmlPtr->tkwin, "fixed"); } if( htmlPtr->aFont[iFont]==0 ){ Tcl_AddErrorInfo(htmlPtr->interp, "\n (trying to create font \"fixed\" in the HTML widget)"); Tcl_BackgroundError(htmlPtr->interp); htmlPtr->aFont[iFont] = Tk_GetFont(htmlPtr->interp, htmlPtr->tkwin, "helvetica -12"); } FontSetValid(htmlPtr, iFont); TestPoint(0); } /* ** Free the expired font, if any. */ if( toFree!=0 ){ Tk_FreeFont(toFree); } return htmlPtr->aFont[iFont]; } /* ** Compute the squared distance between two colors */ static float colorDistance(XColor *pA, XColor *pB){ float x, y, z; x = 0.30 * (pA->red - pB->red); y = 0.61 * (pA->green - pB->green); z = 0.11 * (pA->blue - pB->blue); TestPoint(0); return x*x + y*y + z*z; } /* ** This routine returns an index between 0 and N_COLOR-1 which indicates ** which XColor structure in the apColor[] array of htmlPtr should be ** used to describe the color specified by the given name. */ int HtmlGetColorByName(HtmlWidget *htmlPtr, char *zColor){ XColor *pNew; int iColor; Tk_Uid name; int i, n; char zAltColor[16]; /* Netscape accepts color names that are just HEX values, without ** the # up front. This isn't valid HTML, but we support it for ** compatibility. */ n = strlen(zColor); /* trucate any spaces on the end */ while (n>0 && zColor[n-1]==' ') { zColor[n-1] = '\0'; n--; } if( n==6 || n==3 || n==9 || n==12 ){ for(i=0; i<n; i++){ if( !isxdigit(zColor[i]) ) break; } if( i==n ){ sprintf(zAltColor,"#%s",zColor); }else{ strcpy(zAltColor, zColor); } name = Tk_GetUid(zAltColor); }else{ name = Tk_GetUid(zColor); } pNew = Tk_GetColor(htmlPtr->interp, htmlPtr->clipwin, name); if( pNew==0 ){ return 0; /* Color 0 is always the default */ } iColor = GetColorByValue(htmlPtr, pNew); Tk_FreeColor(pNew); return iColor; } /* ** Macros used in the computation of appropriate shadow colors. */ #define MAX_COLOR 65535 #define MAX(A,B) ((A)<(B)?(B):(A)) #define MIN(A,B) ((A)<(B)?(A):(B)) /* ** Check to see if the given color is too dark to be easily distinguished ** from black. */ static int isDarkColor(XColor *p){ float x, y, z; x = 0.50 * p->red; y = 1.00 * p->green; z = 0.28 * p->blue; return (x*x + y*y + z*z)<0.05*MAX_COLOR*MAX_COLOR; } /* ** Given that the background color is iBgColor, figure out an ** appropriate color for the dark part of a 3D shadow. */ int HtmlGetDarkShadowColor(HtmlWidget *htmlPtr, int iBgColor){ if( htmlPtr->iDark[iBgColor]==0 ){ XColor *pRef, val; pRef = htmlPtr->apColor[iBgColor]; if( isDarkColor(pRef) ){ int t1, t2; t1 = MIN(MAX_COLOR,pRef->red*1.2); t2 = (pRef->red*3 + MAX_COLOR)/4; val.red = MAX(t1,t2); t1 = MIN(MAX_COLOR,pRef->green*1.2); t2 = (pRef->green*3 + MAX_COLOR)/4; val.green = MAX(t1,t2); t1 = MIN(MAX_COLOR,pRef->blue*1.2); t2 = (pRef->blue*3 + MAX_COLOR)/4; val.blue = MAX(t1,t2); }else{ val.red = pRef->red*0.6; val.green = pRef->green*0.6; val.blue = pRef->blue*0.6; } htmlPtr->iDark[iBgColor] = GetColorByValue(htmlPtr, &val) + 1; } return htmlPtr->iDark[iBgColor] - 1; } /* ** Check to see if the given color is too light to be easily distinguished ** from white. */ static int isLightColor(XColor *p){ return p->green>=0.85*MAX_COLOR; } /* ** Given that the background color is iBgColor, figure out an ** appropriate color for the bright part of the 3D shadow. */ int HtmlGetLightShadowColor(HtmlWidget *htmlPtr, int iBgColor){ if( htmlPtr->iLight[iBgColor]==0 ){ XColor *pRef, val; pRef = htmlPtr->apColor[iBgColor]; if( isLightColor(pRef) ){ val.red = pRef->red*0.9; val.green = pRef->green*0.9; val.blue = pRef->blue*0.9; }else{ int t1, t2; t1 = MIN(MAX_COLOR,pRef->green*1.4); t2 = (pRef->green + MAX_COLOR)/2; val.green = MAX(t1,t2); t1 = MIN(MAX_COLOR,pRef->red*1.4); t2 = (pRef->red + MAX_COLOR)/2; val.red = MAX(t1,t2); t1 = MIN(MAX_COLOR,pRef->blue*1.4); t2 = (pRef->blue + MAX_COLOR)/2; val.blue = MAX(t1,t2); } htmlPtr->iLight[iBgColor] = GetColorByValue(htmlPtr, &val) + 1; } return htmlPtr->iLight[iBgColor] - 1; } /* ** Find a color integer for the color whose color components ** are given by pRef. */ LOCAL int GetColorByValue(HtmlWidget *htmlPtr, XColor *pRef){ int i; float dist; float closestDist; int closest; /* int r, g, b; # define COLOR_MASK 0xf800 */ XColor* q; q = Tk_GetColorByValue(htmlPtr->clipwin, pRef); /* Search for an exact match */ /* r = pRef->red &= COLOR_MASK; g = pRef->green &= COLOR_MASK; b = pRef->blue &= COLOR_MASK; */ for(i=0; i<N_COLOR; i++){ XColor *p = htmlPtr->apColor[i]; /* if( p && (p->red & COLOR_MASK)==r && (p->green & COLOR_MASK)==g && (p->blue & COLOR_MASK)==b ){ */ if (p && (q->red == p->red) && (q->green == p->green) && (q->blue == p->blue)) { htmlPtr->colorUsed |= (1<<i); Tk_FreeColor(q); return i; } } Tk_FreeColor(q); /* No exact matches. Look for a completely unused slot */ for(i=N_PREDEFINED_COLOR; i<N_COLOR; i++){ if( htmlPtr->apColor[i]==0 ){ htmlPtr->apColor[i] = Tk_GetColorByValue(htmlPtr->clipwin, pRef); htmlPtr->colorUsed |= (1<<i); return i; } } /* No empty slots. Look for a slot that contains a color that ** isn't currently in use. */ for(i=N_PREDEFINED_COLOR; i<N_COLOR; i++){ if( ((htmlPtr->colorUsed >> i) & 1) == 0 ){ Tk_FreeColor(htmlPtr->apColor[i]); htmlPtr->apColor[i] = Tk_GetColorByValue(htmlPtr->clipwin, pRef); htmlPtr->colorUsed |= (1<<i); return i; } } /* Ok, find the existing color that is closest to the color requested ** and use it. */ closest = 0; closestDist = colorDistance(pRef, htmlPtr->apColor[0]); for(i=1; i<N_COLOR; i++){ dist = colorDistance(pRef, htmlPtr->apColor[i]); if( dist < closestDist ){ closestDist = dist; closest = i; } } return i; } /* ** This routine searchs for a hyperlink beneath the coordinates x,y ** and returns a pointer to the HREF for that hyperlink. The text ** is held one of the markup.argv[] fields of the <a> markup. */ char *HtmlGetHref(HtmlWidget *htmlPtr, int x, int y){ HtmlBlock *pBlock; HtmlElement *pElem; for(pBlock=htmlPtr->firstBlock; pBlock; pBlock=pBlock->pNext){ if( pBlock->top > y || pBlock->bottom < y || pBlock->left > x || pBlock->right < x ){ TestPoint(0); continue; } pElem = pBlock->base.pNext; if( (pElem->base.style.flags & STY_Anchor)==0 ){ TestPoint(0); continue; } switch( pElem->base.type ){ case Html_Text: case Html_Space: case Html_IMG: while( pElem && pElem->base.type!=Html_A ){ pElem = pElem->base.pPrev; } if( pElem==0 || pElem->base.type!=Html_A ){ break; } return HtmlMarkupArg(pElem,"href", 0); default: break; } } TestPoint(0); return 0; } /* ** Change the "yOffset" field from its current value to the value given. ** This has the effect of scrolling the widget vertically. */ void HtmlVerticalScroll(HtmlWidget *htmlPtr, int yOffset){ int inset; /* The 3D border plus the pady */ int h; /* Height of the clipping window */ int diff; /* Difference between old and new offset */ GC gc; /* Graphics context used for copying */ int w; /* Width of text area */ if( yOffset==htmlPtr->yOffset ){ TestPoint(0); return; } inset = htmlPtr->pady + htmlPtr->inset; h = htmlPtr->realHeight - 2*inset; if( (htmlPtr->flags & REDRAW_TEXT)!=0 || (htmlPtr->dirtyTop < h && htmlPtr->dirtyBottom > 0) || htmlPtr->yOffset > yOffset + (h - 30) || htmlPtr->yOffset < yOffset - (h - 30) ){ htmlPtr->yOffset = yOffset; htmlPtr->flags |= VSCROLL | REDRAW_TEXT; HtmlScheduleRedraw(htmlPtr); TestPoint(0); return; } diff = htmlPtr->yOffset - yOffset; gc = HtmlGetAnyGC(htmlPtr); w = htmlPtr->realWidth - 2*(htmlPtr->inset + htmlPtr->padx); htmlPtr->flags |= VSCROLL; htmlPtr->yOffset = yOffset; if( diff < 0 ){ XCopyArea(htmlPtr->display, Tk_WindowId(htmlPtr->clipwin), /* source */ Tk_WindowId(htmlPtr->clipwin), /* destination */ gc, 0, -diff, /* source X, Y */ w, h + diff, /* Width and height */ 0, 0); /* Destination X, Y */ HtmlRedrawArea(htmlPtr, 0, h + diff, w, h); TestPoint(0); }else{ XCopyArea(htmlPtr->display, Tk_WindowId(htmlPtr->clipwin), /* source */ Tk_WindowId(htmlPtr->clipwin), /* destination */ gc, 0, 0, /* source X, Y */ w, h - diff, /* Width and height */ 0, diff); /* Destination X, Y */ HtmlRedrawArea(htmlPtr, 0, 0, w, diff); TestPoint(0); } /* HtmlMapControls(htmlPtr);*/ } /* ** Change the "xOffset" field from its current value to the value given. ** This has the effect of scrolling the widget horizontally. */ void HtmlHorizontalScroll(HtmlWidget *htmlPtr, int xOffset){ if( xOffset==htmlPtr->xOffset ){ TestPoint(0); return; } htmlPtr->xOffset = xOffset; HtmlMapControls(htmlPtr); htmlPtr->flags |= HSCROLL | REDRAW_TEXT; HtmlScheduleRedraw(htmlPtr); TestPoint(0); } /* ** The following array defines all possible widget command. The main ** widget command function just parses up the command line, then vectors ** control to one of the command service routines defined in the ** following array: */ static struct HtmlSubcommand { char *zCmd1; /* First-level subcommand. Required */ char *zCmd2; /* Second-level subcommand. May be NULL */ int minArgc; /* Minimum number of arguments */ int maxArgc; /* Maximum number of arguments */ char *zHelp; /* Help string if wrong number of arguments */ int (*xFunc)(HtmlWidget*,Tcl_Interp*,int,char**); /* Cmd service routine */ } aSubcommand[] = { { "cget", 0, 3, 3, "CONFIG-OPTION", HtmlCgetCmd }, { "clear", 0, 2, 2, 0, HtmlClearCmd }, { "configure", 0, 2, 0, "?ARGS...?", HtmlConfigCmd }, { "href", 0, 4, 4, "X Y", HtmlHrefCmd }, { "index", 0, 3, 3, "INDEX", HtmlIndexCmd }, { "insert", 0, 3, 3, "INDEX", HtmlInsertCmd }, { "names", 0, 2, 2, 0, HtmlNamesCmd }, { "parse", 0, 3, 3, "HTML-TEXT", HtmlParseCmd }, { "resolve", 0, 2, 0, "?URI ...?", HtmlResolveCmd }, { "selection", "clear", 3, 3, 0, HtmlSelectionClearCmd}, { 0, "set", 5, 5, "START END", HtmlSelectionSetCmd }, { "text", "ascii", 5, 5, "START END", HtmlTextAsciiCmd}, { 0, "delete", 5, 5, "START END", 0 }, { 0, "html", 5, 5, "START END", 0 }, { 0, "insert", 5, 5, "INDEX TEXT", 0 }, { "token", "append", 5, 5, "TAG ARGUMENTS", 0 }, { 0, "delete", 4, 5, "INDEX ?INDEX?", 0 }, { 0, "find", 4, 6, "TAG ?before|after INDEX?", 0 }, { 0, "get", 4, 5, "INDEX ?INDEX?", 0 }, { 0, "handler", 4, 5, "TAG ?SCRIPT?", HtmlTokenHandlerCmd }, { 0, "insert", 6, 6, "INDEX TAG ARGUMENTS", 0 }, { 0, "list", 5, 5, "START END", HtmlTokenListCmd }, { "xview", 0, 2, 5, "OPTIONS...", HtmlXviewCmd }, { "yview", 0, 2, 5, "OPTIONS...", HtmlYviewCmd }, #ifdef DEBUG { "debug", "dump", 5, 5, "START END", HtmlDebugDumpCmd }, { 0, "testpt", 4, 4, "FILENAME", HtmlDebugTestPtCmd }, #endif }; #define nSubcommand (sizeof(aSubcommand)/sizeof(aSubcommand[0])) /* ** This routine implements the command used by individual HTML widgets. */ static int HtmlWidgetCommand( ClientData clientData, /* The HTML widget data structure */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ){ HtmlWidget *htmlPtr = (HtmlWidget*) clientData; size_t length; int c; int i; struct HtmlSubcommand *pCmd; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", 0); TestPoint(0); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); for(i=0, pCmd=aSubcommand; i<nSubcommand; i++, pCmd++){ if( pCmd->zCmd1==0 || c!=pCmd->zCmd1[0] || strncmp(pCmd->zCmd1,argv[1],length)!=0 ){ TestPoint(0); continue; } if( pCmd->zCmd2 ){ int length2; int j; if( argc<3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ", pCmd->zCmd1, " SUBCOMMAND ?OPTIONS...?", 0); TestPoint(0); return TCL_ERROR; } length2 = strlen(argv[2]); for(j=i; j<nSubcommand && (j==i || pCmd->zCmd1==0); j++, pCmd++){ if( strncmp(pCmd->zCmd2,argv[2],length2)==0 ){ TestPoint(0); break; } } if( j>=nSubcommand || (j!=i && aSubcommand[j].zCmd1!=0) ){ Tcl_AppendResult(interp,"unknown subcommand \"", argv[2], "\" -- should be one of:", 0); for(j=i; j<nSubcommand && (j==i || aSubcommand[j].zCmd1==0); j++){ Tcl_AppendResult(interp, " ", aSubcommand[j].zCmd2, 0); TestPoint(0); } return TCL_ERROR; } } if( argc<pCmd->minArgc || (argc>pCmd->maxArgc && pCmd->maxArgc>0) ){ Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], " ", pCmd->zCmd1, 0); if( pCmd->zCmd2 ){ Tcl_AppendResult(interp, " ", pCmd->zCmd2, 0); TestPoint(0); } if( pCmd->zHelp ){ Tcl_AppendResult(interp, " ", pCmd->zHelp, 0); TestPoint(0); } Tcl_AppendResult(interp, "\"", 0); TestPoint(0); return TCL_ERROR; } if( pCmd->xFunc==0 ){ Tcl_AppendResult(interp,"command not yet implemented", 0); TestPoint(0); return TCL_ERROR; } TestPoint(0); return (*pCmd->xFunc)(htmlPtr, interp, argc, argv); } Tcl_AppendResult(interp,"unknown command \"", argv[1], "\" -- should be " "one of:", 0); for(i=0; i<nSubcommand; i++){ if( aSubcommand[i].zCmd1==0 || aSubcommand[i].zCmd1[0]=='_' ){ TestPoint(0); continue; } Tcl_AppendResult(interp, " ", aSubcommand[i].zCmd1, 0); TestPoint(0); } TestPoint(0); return TCL_ERROR; } /* ** The following routine implements the Tcl "html" command. This command ** is used to create new HTML widgets only. After the widget has been ** created, it is manipulated using the widget command defined above. */ static int HtmlCommand( ClientData clientData, /* Main window */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv /* Argument strings. */ ){ int n, c; char *z; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " pathName ?options?\"", (char *) NULL); return TCL_ERROR; } z = argv[1]; n = strlen(z); c = z[0]; /* If the first argument begins with ".", then it must be the ** name of a new window the user wants to create. */ if( argv[1][0]=='.' ){ HtmlWidget *htmlPtr; Tk_Window new; Tk_Window clipwin; char *zClipwin; Tk_Window tkwin = (Tk_Window)clientData; static int varId = 1; /* Used to construct unique names */ new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); if (new == NULL) { return TCL_ERROR; } zClipwin = HtmlAlloc( strlen(argv[1]) + 3 ); if( zClipwin==0 ){ Tk_DestroyWindow(new); return TCL_ERROR; } sprintf(zClipwin,"%s.x",argv[1]); clipwin = Tk_CreateWindowFromPath(interp, new, zClipwin, 0); if( clipwin==0 ){ Tk_DestroyWindow(new); HtmlFree(zClipwin); return TCL_ERROR; } htmlPtr = HtmlAlloc(sizeof(HtmlWidget) + strlen(argv[1]) + 1); memset(htmlPtr, 0, sizeof(HtmlWidget)); htmlPtr->tkwin = new; htmlPtr->clipwin = clipwin; htmlPtr->zClipwin = zClipwin; htmlPtr->display = Tk_Display(new); htmlPtr->interp = interp; htmlPtr->zCmdName = (char*)&htmlPtr[1]; strcpy(htmlPtr->zCmdName, argv[1]); htmlPtr->relief = TK_RELIEF_FLAT; htmlPtr->dirtyLeft = LARGE_NUMBER; htmlPtr->dirtyTop = LARGE_NUMBER; htmlPtr->flags = RESIZE_CLIPWIN; htmlPtr->varId = varId++; Tcl_CreateCommand(interp, htmlPtr->zCmdName, HtmlWidgetCommand, (ClientData)htmlPtr, HtmlCmdDeletedProc); Tcl_CreateCommand(interp, htmlPtr->zClipwin, HtmlWidgetCommand, (ClientData)htmlPtr, HtmlCmdDeletedProc); Tk_SetClass(new,"Html"); Tk_SetClass(clipwin,"HtmlClip"); Tk_CreateEventHandler(htmlPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, HtmlEventProc, (ClientData) htmlPtr); Tk_CreateEventHandler(htmlPtr->clipwin, ExposureMask|StructureNotifyMask, HtmlEventProc, (ClientData) htmlPtr); if (ConfigureHtmlWidget(interp, htmlPtr, argc-2, argv+2, 0, 1) != TCL_OK) { goto error; } interp->result = Tk_PathName(htmlPtr->tkwin); return TCL_OK; error: Tk_DestroyWindow(htmlPtr->tkwin); return TCL_ERROR; } /* html reformat $from $to $text ** ** Convert the format of text. */ if( c=='r' && strncmp(z,"reformat",n)==0 ){ if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " reformat FROM TO TEXT", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, "not yet implemented", 0); return TCL_ERROR; }else /* html urljoin $scheme $authority $path $query $fragment ** ** Merge together the parts of a URL into a single value URL. */ if( c=='u' && strncmp(z,"urljoin",n)==0 ){ if( argc!=7 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " url join SCHEME AUTHORITY PATH QUERY FRAGMENT\"", 0); return TCL_ERROR; } Tcl_AppendResult(interp, "not yet implemented", 0); return TCL_ERROR; }else /* html urlsplit $url ** ** Split a URL into a list of its parts. */ if( c=='u' && strncmp(z,"urlsplit",n)==0 ){ if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " url split URL\"", 0); return TCL_ERROR; } Tcl_AppendResult(interp, "not yet implemented", 0); return TCL_ERROR; }else /* No match. Report an error. */ { Tcl_AppendResult(interp, "unknown command \"", z, "\": should be " "a window name or one of: " "reformat urljoin urlsplit", 0); return TCL_ERROR; } return TCL_OK; } /* ** The following mess is used to define DLL_EXPORT. DLL_EXPORT is ** blank except when we are building a Windows95/NT DLL from this ** library. Some special trickery is necessary to make this wall ** work together with makeheaders. */ #if INTERFACE #define DLL_EXPORT #endif #if defined(USE_TCL_STUBS) && defined(__WIN32__) # undef DLL_EXPORT # define DLL_EXPORT __declspec(dllexport) #endif /* ** This routine is used to register the "html" command with the ** Tcl interpreter. This is the only routine in this file with ** external linkage. */ DLL_EXPORT int Tkhtml_Init(Tcl_Interp *interp){ #ifdef USE_TCL_STUBS if( Tcl_InitStubs(interp,"8.0",0)==0 ){ return TCL_ERROR; } if( Tk_InitStubs(interp,"8.0",0)==0 ){ return TCL_ERROR; } #endif Tcl_CreateCommand(interp,"html", HtmlCommand, Tk_MainWindow(interp), 0); /* Tcl_GlobalEval(interp,HtmlLib); */ #ifdef DEBUG Tcl_LinkVar(interp, "HtmlTraceMask", (char*)&HtmlTraceMask, TCL_LINK_INT); #endif Tcl_PkgProvide(interp, HTML_PKGNAME, HTML_PKGVERSION); return TCL_OK; } ������������./saods9/htmlwidget/src/htmlsizer.c�����������������������������������������������������������������0000644�0001750�0001750�00000106465�07504443345�016253� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlsizer.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines used to compute the style and size of individual elements. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <string.h> #include <stdlib.h> #include "htmlsizer.h" /* ** Get the current rendering style. In other words, get the style ** that is currently on the top of the style stack. */ static HtmlStyle GetCurrentStyle(HtmlWidget *htmlPtr){ HtmlStyle style; if( htmlPtr->styleStack ){ style = htmlPtr->styleStack->style; }else{ style.font = NormalFont(2); style.color = COLOR_Normal; style.bgcolor = COLOR_Background; style.subscript = 0; style.align = ALIGN_Left; style.flags = 0; } return style; } /* ** Push a new rendering style onto the stack. */ static void PushStyleStack( HtmlWidget *htmlPtr, /* Widget on which to push the style */ int tag, /* Tag for this style. Normally the end-tag such ** as </h3> or </em>. */ HtmlStyle style /* The style to push */ ){ HtmlStyleStack *p; p = HtmlAlloc(sizeof(*p)); p->pNext = htmlPtr->styleStack; p->type = tag; p->style = style; htmlPtr->styleStack = p; } /* ** Pop a rendering style off of the stack. ** ** The top-most style on the stack should have a tag equal to "tag". ** If not, then we have an HTML coding error. Perhaps something ** like this: "Some text <em>Enphasized</i> more text". It is an ** interesting problem to figure out how to respond sanely to this ** kind of error. Our solution it to keep popping the stack until ** we find the correct tag, or until the stack is empty. */ HtmlStyle HtmlPopStyleStack(HtmlWidget *htmlPtr, int tag){ int type; HtmlStyleStack *p; static Html_u8 priority[Html_TypeCount+1]; if( priority[Html_TABLE]==0 ){ int i; for(i=0; i<=Html_TypeCount; i++) priority[i] = 1; priority[Html_TD] = 2; priority[Html_EndTD] = 2; priority[Html_TH] = 2; priority[Html_EndTH] = 2; priority[Html_TR] = 3; priority[Html_EndTR] = 3; priority[Html_TABLE] = 4; priority[Html_EndTABLE] = 4; } if( tag<=0 || tag>Html_TypeCount ){ CANT_HAPPEN; return GetCurrentStyle(htmlPtr); } while( (p=htmlPtr->styleStack)!=0 ){ type = p->type; if( type<=0 || type>Html_TypeCount ){ CANT_HAPPEN; return GetCurrentStyle(htmlPtr); } if( type!=tag && priority[type]>priority[tag] ){ return GetCurrentStyle(htmlPtr); } htmlPtr->styleStack = p->pNext; HtmlFree(p); if( type==tag ){ break; } } return GetCurrentStyle(htmlPtr); } /* ** Change the font size on the given style by the delta-amount given */ static void ScaleFont(HtmlStyle *pStyle, int delta){ int size = FontSize(pStyle->font) + delta; if( size<0 ){ delta -= size; }else if( size>6 ){ delta -= size-6; } pStyle->font += delta; } /* ** Lookup an argument in the given markup with the name given. ** Return a pointer to its value, or the given default ** value if it doesn't appear. */ char *HtmlMarkupArg(HtmlElement *p, const char *tag, char *zDefault){ int i; if( !HtmlIsMarkup(p) ){ TestPoint(0); return 0; } for(i=0; i<p->base.count; i+=2){ if( strcmp(p->markup.argv[i],tag)==0 ){ return p->markup.argv[i+1]; } } return zDefault; } /* ** Return an alignment or justification flag associated with the ** given markup. The given default value is returned if no alignment is ** specified. */ static int GetAlignment(HtmlElement *p, int dflt){ char *z = HtmlMarkupArg(p,"align",0); int rc = dflt; if( z ){ if( stricmp(z,"left")==0 ){ rc = ALIGN_Left; }else if( stricmp(z,"right")==0 ){ rc = ALIGN_Right; }else if( stricmp(z,"center")==0 ){ rc = ALIGN_Center; } } return rc; } /* ** The "type" argument to the given element might describe the type ** for an ordered list. Return the corresponding LI_TYPE_* entry ** if this is the case, or the default value if it isn't. */ static int GetOrderedListType(HtmlElement *p, int dflt){ char *z; z = HtmlMarkupArg(p,"type",0); if( z ){ switch( *z ){ case 'A': TestPoint(0); dflt = LI_TYPE_Enum_A; break; case 'a': TestPoint(0); dflt = LI_TYPE_Enum_a; break; case '1': TestPoint(0); dflt = LI_TYPE_Enum_1; break; case 'I': TestPoint(0); dflt = LI_TYPE_Enum_I; break; case 'i': TestPoint(0); dflt = LI_TYPE_Enum_i; break; default: TestPoint(0); break; } }else{ TestPoint(0); } return dflt; } /* ** The "type" argument to the given element might describe a type ** for an unordered list. Return the corresponding LI_TYPE entry ** if this is the case, or the default value if it isn't. */ static int GetUnorderedListType(HtmlElement *p, int dflt){ char *z; z = HtmlMarkupArg(p,"type",0); if( z ){ if( stricmp(z,"disc")==0 ){ dflt = LI_TYPE_Bullet1; }else if( stricmp(z,"circle")==0 ){ dflt = LI_TYPE_Bullet2; }else if( stricmp(z,"square")==0 ){ dflt = LI_TYPE_Bullet3; } } return dflt; } /* ** Add the STY_Invisible style to every token between pFirst and pLast. */ static void MakeInvisible(HtmlElement *pFirst, HtmlElement *pLast){ if( pFirst==0 ) return; pFirst = pFirst->pNext; while( pFirst && pFirst!=pLast ){ pFirst->base.style.flags |= STY_Invisible; pFirst=pFirst->pNext; } } /* ** For the markup <a href=XXX>, find out if the URL has been visited ** before or not. Return COLOR_Visited or COLOR_Unvisited, as ** appropriate. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. The calling function should call HtmlLock() ** if it needs the widget structure to be preserved. */ static int GetLinkColor(HtmlWidget *htmlPtr, char *zURL){ char *zCmd; int result; int isVisited; if( htmlPtr->tkwin==0 ){ TestPoint(0); return COLOR_Normal; } if( htmlPtr->zIsVisited==0 || htmlPtr->zIsVisited[0]==0 ){ TestPoint(0); return COLOR_Unvisited; } zCmd = HtmlAlloc( strlen(htmlPtr->zIsVisited) + strlen(zURL) + 10 ); if( zCmd==0 ){ TestPoint(0); return COLOR_Unvisited; } sprintf(zCmd,"%s {%s}",htmlPtr->zIsVisited, zURL); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp,zCmd); HtmlFree(zCmd); if( HtmlUnlock(htmlPtr) ){ return COLOR_Unvisited; } if( result!=TCL_OK ){ TestPoint(0); goto errorOut; } result = Tcl_GetBoolean(htmlPtr->interp, htmlPtr->interp->result, &isVisited); if( result!=TCL_OK ){ TestPoint(0); goto errorOut; } TestPoint(0); return isVisited ? COLOR_Visited : COLOR_Unvisited; errorOut: Tcl_AddErrorInfo(htmlPtr->interp, "\n (\"-isvisitedcommand\" command executed by html widget)"); Tcl_BackgroundError(htmlPtr->interp); TestPoint(0); return COLOR_Unvisited; } /* ** This routine adds information to the input texts that doesn't change ** when the display is resized or when new fonts are selected, etc. ** Mostly this means adding style attributes. But other constant ** information (such as numbering on <li> and images used for <IMG>) ** is also obtained. The key is that this routine is only called ** once, where the sizer and layout routines can be called many times. ** ** This routine is called whenever the list of elements grows. The ** style stack is stored as part of the HTML widget so that we can ** always continue where we left off the last time. ** ** In addition to adding style, this routine will invoke callbacks ** needed to acquire information about a markup. The htmlPtr->zIsVisitied ** callback is called for each <a> and the htmlPtr->zGetImage is called ** for each <IMG> or for each <LI> that has a SRC= field. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. ** ** When a markup is inserted or deleted from the token list, the ** style routine must be completely rerun from the beginning. So ** what we said above, that this routine is only run once, is not ** strictly true. */ void HtmlAddStyle(HtmlWidget *htmlPtr, HtmlElement *p){ HtmlStyle style; /* Current style */ int size; /* A new font size */ int i; /* Loop counter */ int paraAlign; /* Current paragraph alignment */ int rowAlign; /* Current table row alignment */ int anchorFlags; /* Flags associated with <a> tag */ int inDt; /* True if within <dt>..</dt> */ HtmlStyle nextStyle; /* Style for next token if useNextStyle==1 */ int useNextStyle = 0; /* True if nextStyle is valid */ char *z; /* A tag parameter's value */ /* The size of header fonts relative to the current font size */ static int header_sizes[] = {+2, +1, 1, 1, -1, -1}; /* Don't allow recursion */ if( htmlPtr->flags & STYLER_RUNNING ){ TestPoint(0); return; } htmlPtr->flags |= STYLER_RUNNING; /* Load the style state out of the htmlPtr structure and into local ** variables. This is purely a matter of convenience... */ style = GetCurrentStyle(htmlPtr); paraAlign = htmlPtr->paraAlignment; rowAlign = htmlPtr->rowAlignment; anchorFlags = htmlPtr->anchorFlags; inDt = htmlPtr->inDt; /* Loop over tokens */ while( p ){ switch( p->base.type ){ case Html_A: if( htmlPtr->anchorStart ){ style = HtmlPopStyleStack(htmlPtr, Html_EndA); htmlPtr->anchorStart = 0; anchorFlags = 0; } z = HtmlMarkupArg(p,"href",0); if( z ){ HtmlLock(htmlPtr); style.color = GetLinkColor(htmlPtr, z); if( htmlPtr->underlineLinks ){ style.flags |= STY_Underline; } if( HtmlUnlock(htmlPtr) ) return; anchorFlags |= STY_Anchor; PushStyleStack(htmlPtr, Html_EndA, style); htmlPtr->anchorStart = p; } break; case Html_EndA: if( htmlPtr->anchorStart ){ p->ref.pOther = htmlPtr->anchorStart; style = HtmlPopStyleStack(htmlPtr, Html_EndA); htmlPtr->anchorStart = 0; anchorFlags = 0; } break; case Html_ADDRESS: case Html_EndADDRESS: case Html_BLOCKQUOTE: case Html_EndBLOCKQUOTE: paraAlign = ALIGN_None; TestPoint(0); break; case Html_APPLET: if( htmlPtr->zAppletCommand && *htmlPtr->zAppletCommand ){ nextStyle = style; nextStyle.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndAPPLET, nextStyle); useNextStyle = 1; }else{ PushStyleStack(htmlPtr, Html_EndAPPLET, style); } TestPoint(0); break; case Html_B: style.font = BoldFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndB, style); TestPoint(0); break; case Html_EndAPPLET: case Html_EndB: case Html_EndBIG: case Html_EndCENTER: case Html_EndCITE: case Html_EndCODE: case Html_EndCOMMENT: case Html_EndEM: case Html_EndFONT: case Html_EndI: case Html_EndKBD: case Html_EndMARQUEE: case Html_EndNOBR: case Html_EndNOFRAME: case Html_EndNOSCRIPT: case Html_EndS: case Html_EndSAMP: case Html_EndSMALL: case Html_EndSTRIKE: case Html_EndSTRONG: case Html_EndSUB: case Html_EndSUP: case Html_EndTITLE: case Html_EndTT: case Html_EndU: case Html_EndVAR: style = HtmlPopStyleStack(htmlPtr, p->base.type); TestPoint(0); break; case Html_BASE: z = HtmlMarkupArg(p,"href",0); if( z ){ HtmlLock(htmlPtr); z = HtmlResolveUri(htmlPtr, z); if( HtmlUnlock(htmlPtr) ) return; if( z!=0 ){ if( htmlPtr->zBaseHref ){ HtmlFree(htmlPtr->zBaseHref); } htmlPtr->zBaseHref = z; } } break; case Html_EndDIV: paraAlign = ALIGN_None; style = HtmlPopStyleStack(htmlPtr, p->base.type); TestPoint(0); break; case Html_EndBASEFONT: style = HtmlPopStyleStack(htmlPtr, Html_EndBASEFONT); style.font = FontFamily(style.font) + 2; TestPoint(0); break; case Html_BIG: ScaleFont(&style,1); PushStyleStack(htmlPtr, Html_EndBIG, style); TestPoint(0); break; case Html_CAPTION: paraAlign = GetAlignment(p, paraAlign); TestPoint(0); break; case Html_EndCAPTION: paraAlign = ALIGN_None; TestPoint(0); break; case Html_CENTER: paraAlign = ALIGN_None; style.align = ALIGN_Center; PushStyleStack(htmlPtr, Html_EndCENTER, style); TestPoint(0); break; case Html_CITE: PushStyleStack(htmlPtr, Html_EndCITE, style); TestPoint(0); break; case Html_CODE: style.font = CWFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndCODE, style); TestPoint(0); break; case Html_COMMENT: style.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndCOMMENT, style); TestPoint(0); break; case Html_DD: if( htmlPtr->innerList && htmlPtr->innerList->base.type==Html_DL ){ p->ref.pOther = htmlPtr->innerList; TestPoint(0); }else{ p->ref.pOther = 0; TestPoint(0); } inDt = 0; break; case Html_DIR: case Html_MENU: case Html_UL: p->list.pPrev = htmlPtr->innerList; p->list.cnt = 0; htmlPtr->innerList = p; if( p->list.pPrev==0 ){ p->list.type = LI_TYPE_Bullet1; p->list.compact = HtmlMarkupArg(p,"compact",0)!=0; TestPoint(0); }else if( p->list.pPrev->list.pPrev==0 ){ p->list.type = LI_TYPE_Bullet2; p->list.compact = 1; TestPoint(0); }else{ p->list.type = LI_TYPE_Bullet3; p->list.compact = 1; TestPoint(0); } p->list.type = GetUnorderedListType(p,p->list.type); break; case Html_EndDL: inDt = 0; TestPoint(0); /* Fall thru into the next case */ case Html_EndDIR: case Html_EndMENU: case Html_EndOL: case Html_EndUL: p->ref.pOther = htmlPtr->innerList; if( htmlPtr->innerList ){ htmlPtr->innerList = htmlPtr->innerList->list.pPrev; TestPoint(0); }else{ TestPoint(0); } break; case Html_DIV: paraAlign = ALIGN_None; style.align = GetAlignment(p, style.align); PushStyleStack(htmlPtr, Html_EndDIV, style); TestPoint(0); break; case Html_DT: if( htmlPtr->innerList && htmlPtr->innerList->base.type==Html_DL ){ p->ref.pOther = htmlPtr->innerList; TestPoint(0); }else{ p->ref.pOther = 0; TestPoint(0); } inDt = STY_DT; break; case Html_EndDD: case Html_EndDT: inDt = 0; TestPoint(0); break; case Html_DL: p->list.pPrev = htmlPtr->innerList; p->list.cnt = 0; htmlPtr->innerList = p; p->list.compact = HtmlMarkupArg(p,"compact",0)!=0; inDt = 0; TestPoint(0); break; case Html_EM: style.font = ItalicFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndEM, style); TestPoint(0); break; case Html_EMBED: break; case Html_BASEFONT: case Html_FONT: z = HtmlMarkupArg(p,"size",0); if( z ){ if( *z=='-' ){ size = FontSize(style.font) - atoi(&z[1]); }else if( *z=='+' ){ size = FontSize(style.font) + atoi(&z[1]); }else{ size = atoi(z); } if( size <= 0 ){ size = 1; } if( size >= N_FONT_SIZE ){ size = N_FONT_SIZE - 1; } style.font = FontFamily(style.font) + size - 1; } z = HtmlMarkupArg(p,"color",0); if( z ){ style.color = HtmlGetColorByName(htmlPtr, z); } PushStyleStack(htmlPtr, p->base.type==Html_FONT ? Html_EndFONT : Html_EndBASEFONT, style); break; case Html_FORM: { char *zUrl; char *zMethod; Tcl_DString cmd; /* -formcommand callback */ int result; char zToken[50]; htmlPtr->formStart = 0; p->form.id = 0; if( htmlPtr->zFormCommand==0 || htmlPtr->zFormCommand[0]==0 ){ TestPoint(0); break; } zUrl = HtmlMarkupArg(p,"action",0); if( zUrl==0 ){ TestPoint(0); break; } HtmlLock(htmlPtr); zUrl = HtmlResolveUri(htmlPtr, zUrl); if( HtmlUnlock(htmlPtr) ) return; if( zUrl==0 ) break; zMethod = HtmlMarkupArg(p,"method","GET"); sprintf(zToken," %d form ", ++htmlPtr->nForm); Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); Tcl_DStringAppend(&cmd, zToken, -1); Tcl_DStringAppendElement(&cmd, zUrl); HtmlFree(zUrl); Tcl_DStringAppendElement(&cmd, zMethod); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, p); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( HtmlUnlock(htmlPtr) ) return; if( result==TCL_OK ){ htmlPtr->formStart = p; p->form.id = htmlPtr->nForm; } Tcl_ResetResult(htmlPtr->interp); break; } case Html_EndFORM: p->ref.pOther = htmlPtr->formStart; htmlPtr->formStart = 0; TestPoint(0); break; case Html_H1: case Html_H2: case Html_H3: case Html_H4: case Html_H5: case Html_H6: paraAlign = ALIGN_None; i = (p->base.type - Html_H1)/2 + 1; if( i>=1 && i<=6 ){ ScaleFont(&style,header_sizes[i-1]); } style.font = BoldFont( FontSize(style.font) ); style.align = GetAlignment(p, style.align); PushStyleStack(htmlPtr, Html_EndH1, style); break; case Html_EndH1: case Html_EndH2: case Html_EndH3: case Html_EndH4: case Html_EndH5: case Html_EndH6: paraAlign = ALIGN_None; style = HtmlPopStyleStack(htmlPtr, Html_EndH1); TestPoint(0); break; case Html_HR: nextStyle = style; style.align = GetAlignment(p, ALIGN_None); useNextStyle = 1; break; case Html_I: style.font = ItalicFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndI, style); TestPoint(0); break; case Html_IMG: HtmlLock(htmlPtr); p->image.pImage = HtmlGetImage(htmlPtr, p); if( HtmlUnlock(htmlPtr) ) return; TestPoint(0); break; case Html_INPUT: p->input.pForm = htmlPtr->formStart; TestPoint(0); break; case Html_KBD: style.font = CWFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndKBD, style); TestPoint(0); break; case Html_LI: if( htmlPtr->innerList ){ p->li.type = htmlPtr->innerList->list.type; if( htmlPtr->innerList->base.type==Html_OL ){ z = HtmlMarkupArg(p, "value", 0); if( z ){ int n = atoi(z); if( n>0 ){ p->li.cnt = n; htmlPtr->innerList->list.cnt = n+1; TestPoint(0); }else{ TestPoint(0); } }else{ p->li.cnt = htmlPtr->innerList->list.cnt++; TestPoint(0); } p->li.type = GetOrderedListType(p,p->li.type); }else{ p->li.type = GetUnorderedListType(p,p->li.type); TestPoint(0); } }else{ p->base.flags &= ~HTML_Visible; TestPoint(0); } break; case Html_MARQUEE: style.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndMARQUEE, style); TestPoint(0); break; case Html_NOBR: style.flags |= STY_NoBreak; PushStyleStack(htmlPtr, Html_EndNOBR, style); TestPoint(0); break; case Html_NOFRAME: if( htmlPtr->zFrameCommand && *htmlPtr->zFrameCommand ){ nextStyle = style; nextStyle.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndNOFRAME, nextStyle); useNextStyle = 1; }else{ PushStyleStack(htmlPtr, Html_EndNOFRAME, style); } TestPoint(0); break; case Html_NOSCRIPT: if( htmlPtr->zScriptCommand && *htmlPtr->zScriptCommand ){ nextStyle = style; nextStyle.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndNOSCRIPT, nextStyle); useNextStyle = 1; }else{ PushStyleStack(htmlPtr, Html_EndNOSCRIPT, style); } TestPoint(0); break; case Html_OL: p->list.pPrev = htmlPtr->innerList; p->list.type = GetOrderedListType(p,LI_TYPE_Enum_1); p->list.cnt = 1; z = HtmlMarkupArg(p,"start",0); if( z ){ int n = atoi(z); if( n>0 ){ p->list.cnt = n; TestPoint(0); }else{ TestPoint(0); } }else{ TestPoint(0); } p->list.compact = htmlPtr->innerList!=0 || HtmlMarkupArg(p,"compact",0)!=0; htmlPtr->innerList = p; break; case Html_P: paraAlign = GetAlignment(p, ALIGN_None); TestPoint(0); break; case Html_EndP: paraAlign = ALIGN_None; TestPoint(0); break; case Html_PRE: case Html_LISTING: case Html_XMP: case Html_PLAINTEXT: paraAlign = ALIGN_None; style.font = CWFont( FontSize(style.font) ); style.flags |= STY_Preformatted; PushStyleStack(htmlPtr, Html_EndPRE, style); TestPoint(0); break; case Html_EndPRE: case Html_EndLISTING: case Html_EndXMP: style = HtmlPopStyleStack(htmlPtr, Html_EndPRE); TestPoint(0); break; case Html_S: style.flags |= STY_StrikeThru; PushStyleStack(htmlPtr, Html_EndS, style); TestPoint(0); break; case Html_SCRIPT: if( htmlPtr->zScriptCommand && *htmlPtr->zScriptCommand ){ Tcl_DString cmd; int result; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zScriptCommand, -1); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, p); Tcl_DStringEndSublist(&cmd); Tcl_DStringStartSublist(&cmd); Tcl_DStringAppend(&cmd, p->script.zScript, p->script.nScript); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( HtmlUnlock(htmlPtr) ) return; Tcl_ResetResult(htmlPtr->interp); } nextStyle = style; style.flags |= STY_Invisible; useNextStyle = 1; break; case Html_SELECT: p->input.pForm = htmlPtr->formStart; nextStyle.flags |= STY_Invisible; useNextStyle = 1; PushStyleStack(htmlPtr, Html_EndSELECT, style); htmlPtr->formElemStart = p; break; case Html_EndSELECT: style = HtmlPopStyleStack(htmlPtr, Html_EndSELECT); if( htmlPtr->formElemStart && htmlPtr->formElemStart->base.type==Html_SELECT ){ p->ref.pOther = htmlPtr->formElemStart; MakeInvisible(p->ref.pOther, p); }else{ p->ref.pOther = 0; } htmlPtr->formElemStart = 0; break; case Html_STRIKE: style.flags |= STY_StrikeThru; PushStyleStack(htmlPtr, Html_EndSTRIKE, style); TestPoint(0); break; case Html_STYLE: /* Ignore style sheets */ break; case Html_SAMP: style.font = CWFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndSAMP, style); TestPoint(0); break; case Html_SMALL: ScaleFont(&style,-1); PushStyleStack(htmlPtr, Html_EndSMALL, style); TestPoint(0); break; case Html_STRONG: style.font = BoldFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndSTRONG, style); TestPoint(0); break; case Html_SUB: ScaleFont(&style,-1); if( style.subscript > -6 ){ style.subscript--; TestPoint(0); }else{ TestPoint(0); } PushStyleStack(htmlPtr, Html_EndSUB, style); break; case Html_SUP: ScaleFont(&style,-1); if( style.subscript < 6 ){ style.subscript++; TestPoint(0); }else{ TestPoint(0); } PushStyleStack(htmlPtr, Html_EndSUP, style); break; case Html_TABLE: paraAlign = ALIGN_None; nextStyle = style; nextStyle.align = ALIGN_Left; z = HtmlMarkupArg(p, "bgcolor", 0); if( z ){ nextStyle.bgcolor = HtmlGetColorByName(htmlPtr, z); style.bgcolor = nextStyle.bgcolor; /* }else{ nextStyle.bgcolor = COLOR_Background; */ } PushStyleStack(htmlPtr, Html_EndTABLE, nextStyle); useNextStyle = 1; htmlPtr->inTd = 0; htmlPtr->inTr = 0; TestPoint(0); break; case Html_EndTABLE: paraAlign = ALIGN_None; if( htmlPtr->inTd ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTD); htmlPtr->inTd = 0; } if( htmlPtr->inTr ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTR); htmlPtr->inTr = 0; } style = HtmlPopStyleStack(htmlPtr, p->base.type); TestPoint(0); break; case Html_TD: if( htmlPtr->inTd ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTD); } htmlPtr->inTd = 1; paraAlign = GetAlignment(p, rowAlign); if( (z = HtmlMarkupArg(p, "bgcolor", 0))!=0 ){ style.bgcolor = HtmlGetColorByName(htmlPtr, z); } PushStyleStack(htmlPtr, Html_EndTD, style); TestPoint(0); break; case Html_TEXTAREA: p->input.pForm = htmlPtr->formStart; nextStyle = style; nextStyle.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndTEXTAREA, nextStyle); htmlPtr->formElemStart = p; useNextStyle = 1; TestPoint(0); break; case Html_EndTEXTAREA: style = HtmlPopStyleStack(htmlPtr, Html_EndTEXTAREA); if( htmlPtr->formElemStart && htmlPtr->formElemStart->base.type==Html_TEXTAREA ){ p->ref.pOther = htmlPtr->formElemStart; }else{ p->ref.pOther = 0; } htmlPtr->formElemStart = 0; break; case Html_TH: /* paraAlign = GetAlignment(p, rowAlign); */ if( htmlPtr->inTd ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTD); } paraAlign = GetAlignment(p, ALIGN_Center); style.font = BoldFont( FontSize(style.font) ); if( (z = HtmlMarkupArg(p, "bgcolor", 0))!=0 ){ style.bgcolor = HtmlGetColorByName(htmlPtr, z); } PushStyleStack(htmlPtr, Html_EndTD, style); htmlPtr->inTd = 1; TestPoint(0); break; case Html_TR: if( htmlPtr->inTd ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTD); htmlPtr->inTd = 0; } if( htmlPtr->inTr ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTR); } rowAlign = GetAlignment(p, ALIGN_None); if( (z = HtmlMarkupArg(p, "bgcolor", 0))!=0 ){ style.bgcolor = HtmlGetColorByName(htmlPtr, z); } PushStyleStack(htmlPtr, Html_EndTR, style); htmlPtr->inTr = 1; TestPoint(0); break; case Html_EndTR: if( htmlPtr->inTd ){ style = HtmlPopStyleStack(htmlPtr, Html_EndTD); htmlPtr->inTd = 0; } style = HtmlPopStyleStack(htmlPtr, Html_EndTR); htmlPtr->inTr = 0; paraAlign = ALIGN_None; rowAlign = ALIGN_None; TestPoint(0); break; case Html_EndTD: case Html_EndTH: style = HtmlPopStyleStack(htmlPtr, Html_EndTD); htmlPtr->inTd = 0; paraAlign = ALIGN_None; rowAlign = ALIGN_None; TestPoint(0); break; case Html_TITLE: style.flags |= STY_Invisible; PushStyleStack(htmlPtr, Html_EndTITLE, style); TestPoint(0); break; case Html_TT: style.font = CWFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndTT, style); TestPoint(0); break; case Html_U: style.flags |= STY_Underline; PushStyleStack(htmlPtr, Html_EndU, style); break; case Html_VAR: style.font = ItalicFont( FontSize(style.font) ); PushStyleStack(htmlPtr, Html_EndVAR, style); TestPoint(0); break; default: TestPoint(0); break; } p->base.style = style; p->base.style.flags |= anchorFlags | inDt; if( paraAlign!=ALIGN_None ){ p->base.style.align = paraAlign; } if( useNextStyle ){ style = nextStyle; useNextStyle = 0; } TRACE(HtmlTrace_Style, ("Style of 0x%08x font=%02d color=%02d bg=%02d " "align=%d flags=0x%04x token=%s\n", (int)p, p->base.style.font, p->base.style.color, p->base.style.bgcolor, p->base.style.align, p->base.style.flags, HtmlTokenName(p))); p = p->pNext; } /* Copy state information back into the htmlPtr structure for ** safe keeping. */ htmlPtr->paraAlignment = paraAlign; htmlPtr->rowAlignment = rowAlign; htmlPtr->anchorFlags = anchorFlags; htmlPtr->inDt = inDt; htmlPtr->flags &= ~STYLER_RUNNING; } /* ** Compute the size of all elements in the widget. Assume that a ** style has already been assigned to all elements. ** ** Some of the elements might have already been sized. Refer to the ** htmlPtr->lastSized and only compute sizes for elements that follow ** this one. If htmlPtr->lastSized==0, then size everything. ** ** This routine only computes the sizes of individual elements. The ** size of aggregate elements (like tables) are computed separately. ** ** The HTML_Visible flag is also set on every element that results ** in ink on the page. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. */ void HtmlSizer(HtmlWidget *htmlPtr){ HtmlElement *p; int iFont = -1; Tk_Font font; int spaceWidth = 0; Tk_FontMetrics fontMetrics; char *z; int stop = 0; if( htmlPtr->pFirst==0 ){ TestPoint(0); return; } if( htmlPtr->lastSized==0 ){ p = htmlPtr->pFirst; TestPoint(0); }else{ p = htmlPtr->lastSized->pNext; TestPoint(0); } for(; !stop && p; p=p->pNext){ if( p->base.style.flags & STY_Invisible ){ p->base.flags &= ~HTML_Visible; TestPoint(0); continue; } if( iFont != p->base.style.font ){ iFont = p->base.style.font; HtmlLock(htmlPtr); font = HtmlGetFont(htmlPtr, iFont); if( HtmlUnlock(htmlPtr) ) break; Tk_GetFontMetrics(font, &fontMetrics); spaceWidth = 0; } switch( p->base.type ){ case Html_Text: p->text.w = Tk_TextWidth(font, p->text.zText, p->base.count); p->base.flags |= HTML_Visible; p->text.descent = fontMetrics.descent; p->text.ascent = fontMetrics.ascent; if( spaceWidth==0 ){ spaceWidth = Tk_TextWidth(font, " ", 1); TestPoint(0); }else{ TestPoint(0); } p->text.spaceWidth = spaceWidth; break; case Html_Space: if( spaceWidth==0 ){ spaceWidth = Tk_TextWidth(font, " ", 1); } p->space.w = spaceWidth; p->space.descent = fontMetrics.descent; p->space.ascent = fontMetrics.ascent; p->base.flags &= ~HTML_Visible; break; case Html_TD: case Html_TH: z = HtmlMarkupArg(p, "rowspan","1"); p->cell.rowspan = atoi(z); z = HtmlMarkupArg(p, "colspan","1"); p->cell.colspan = atoi(z); p->base.flags |= HTML_Visible; TestPoint(0); break; case Html_LI: p->li.descent = fontMetrics.descent; p->li.ascent = fontMetrics.ascent; p->base.flags |= HTML_Visible; TestPoint(0); break; case Html_IMG: p->base.flags |= HTML_Visible; p->image.redrawNeeded = 0; p->image.textAscent = fontMetrics.ascent; p->image.textDescent = fontMetrics.descent; p->image.align = HtmlGetImageAlignment(p); if( p->image.pImage==0 ){ p->image.ascent = fontMetrics.ascent; p->image.descent = fontMetrics.descent; p->image.zAlt = HtmlMarkupArg(p, "alt", "<image>"); p->image.w = Tk_TextWidth(font, p->image.zAlt, strlen(p->image.zAlt)); }else{ int w, h; p->image.pNext = p->image.pImage->pList; p->image.pImage->pList = p; Tk_SizeOfImage(p->image.pImage->image, &w, &h); p->image.h = h; p->image.w = w; p->image.ascent = h/2; p->image.descent = h - p->image.ascent; } if( (z = HtmlMarkupArg(p, "width", 0))!=0 ){ int w = atoi(z); if( w>0 ) p->image.w = w; } if( (z = HtmlMarkupArg(p, "height", 0))!=0 ){ int h = atoi(z); if( h>0 ) p->image.h = h; } break; case Html_HR: case Html_TABLE: p->base.flags |= HTML_Visible; TestPoint(0); break; case Html_APPLET: case Html_EMBED: case Html_INPUT: p->input.textAscent = fontMetrics.ascent; p->input.textDescent = fontMetrics.descent; stop = HtmlControlSize(htmlPtr, p); break; case Html_SELECT: case Html_TEXTAREA: p->input.textAscent = fontMetrics.ascent; p->input.textDescent = fontMetrics.descent; break; case Html_EndSELECT: case Html_EndTEXTAREA: if( p->ref.pOther ){ p->ref.pOther->input.pEnd = p; stop = HtmlControlSize(htmlPtr, p->ref.pOther); } break; default: p->base.flags &= ~HTML_Visible; break; } } if( p ){ htmlPtr->lastSized = p; }else{ htmlPtr->lastSized = htmlPtr->pLast; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmllayout.c����������������������������������������������������������������0000644�0001750�0001750�00000103115�07504443345�016421� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmllayout.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** This file contains the code used to position elements of the ** HTML file on the screen. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <stdlib.h> #include <string.h> #include "htmllayout.h" /* ** Push a new margin onto the given margin stack. ** ** If the "bottom" parameter is non-negative, then this margin will ** automatically expire for all text that is placed below the y-coordinate ** given by "bottom". This feature is used for <IMG ALIGN=left> ** and <IMG ALIGN=right> kinds of markup. It allows text to flow around ** an image. ** ** If "bottom" is negative, then the margin stays in force until ** it is explicitly canceled by a call to HtmlPopMargin(). */ void HtmlPushMargin( HtmlMargin **ppMargin, /* The margin stack onto which to push */ int indent, /* The indentation for the new margin */ int bottom, /* The margin expires at this Y coordinate */ int tag /* Markup that will cancel this margin */ ){ HtmlMargin *pNew = HtmlAlloc( sizeof(HtmlMargin) ); pNew->pNext = *ppMargin; if( pNew->pNext ){ pNew->indent = indent + pNew->pNext->indent; TestPoint(0); }else{ pNew->indent = indent; TestPoint(0); } pNew->bottom = bottom; pNew->tag = tag; *ppMargin = pNew; } /* ** Pop one margin off of the given margin stack. */ static void HtmlPopOneMargin(HtmlMargin **ppMargin){ if( *ppMargin ){ HtmlMargin *pOld = *ppMargin; *ppMargin = pOld->pNext; HtmlFree(pOld); } } /* ** Pop as many margins as necessary until the margin that was ** created with "tag" is popped off. Update the layout context ** to move past obsticles, if necessary. ** ** If there are some margins on the stack that contain non-negative ** bottom fields, that means there are some obsticles that we have ** not yet cleared. If these margins get popped off the stack, ** then we have to be careful to advance the pLC->bottom value so ** that the next line of text will clear the obsticle. */ static void HtmlPopMargin( HtmlMargin **ppMargin, /* The margin stack to be popped */ int tag, /* The tag we want to pop */ HtmlLayoutContext *pLC /* Update this layout context */ ){ int bottom = -1; int oldTag; HtmlMargin *pM; for(pM=*ppMargin; pM && pM->tag!=tag; pM=pM->pNext){} if( pM==0 ){ /* No matching margin is found. Do nothing. */ return; } while( (pM=*ppMargin)!=0 ){ if( pM->bottom>bottom ){ bottom = pM->bottom; } oldTag = pM->tag; HtmlPopOneMargin(ppMargin); if( oldTag==tag ) break; } if( pLC && pLC->bottom<bottom ){ pLC->headRoom += bottom - pLC->bottom; pLC->bottom = bottom; } } /* ** Pop all expired margins from the stack. ** ** An expired margin is one with a non-negative bottom parameter ** that is less than the value "y". "y" is the Y-coordinate of ** the top edge the next line of text to by positioned. What this ** function does is check to see if we have cleared any obsticles ** (an obsticle is an <IMG ALIGN=left> or <IMG ALIGN=right>) and ** expands the margins if we have. */ static void PopExpiredMargins(HtmlMargin **ppMarginStack, int y){ while( *ppMarginStack && (**ppMarginStack).bottom>=0 && (**ppMarginStack).bottom <= y ){ HtmlPopOneMargin(ppMarginStack); } } /* ** Clear a margin stack to reclaim memory. This routine just blindly ** pops everything off the stack. Typically used when the screen is ** cleared or the widget is deleted, etc. */ void HtmlClearMarginStack(HtmlMargin **ppMargin){ while( *ppMargin ){ HtmlPopOneMargin(ppMargin); } } /* ** This routine gathers as many tokens as will fit on one line. ** ** The candidate tokens begin with pStart and go thru the end of ** the list or to pEnd, whichever comes first. The first token ** at the start of the next line is returned. NULL is returned if ** we exhaust data. ** ** "width" is the maximum allowed width of the line. The actual ** width is returned in *actualWidth. The actual width does not ** include any trailing spaces. Sometimes the actual width will ** be greater than the maximum width. This will happen, for example, ** for text enclosed in <pre>..</pre> that has lines longer than ** the width of the page. ** ** If the list begins with text, at least one token is returned, ** even if that one token is longer than the allowed line length. ** But if the list begins with some kind of break markup (possibly ** preceded by white space) then the returned list may be empty. ** ** The "x" coordinates of all elements are set assuming that the line ** begins at 0. The calling routine should adjust these coordinates ** to position the line horizontally. (The FixLine() procedure does ** this.) Note that the "x" coordinate of <li> elements will be negative. ** Text within <dt>..</dt> might also have a negative "x" coordinate. ** But in no case will the x coordinate every be less than "minX". */ static HtmlElement *GetLine( HtmlLayoutContext *pLC, /* The complete layout context. */ HtmlElement *pStart, /* First token on new line */ HtmlElement *pEnd, /* End of line. Might be NULL */ int width, /* How much space is on this line */ int minX, /* The minimum value of the X coordinate */ int *actualWidth /* Return space actually required */ ){ int x; /* Current X coordinate */ int spaceWanted = 0; /* Add this much space before next token */ HtmlElement *p; /* For looping over tokens */ HtmlElement *lastBreak = 0; /* Last line-break opportunity */ int isEmpty = 1; /* True if link contains nothing */ int origin; /* Initial value of "x" */ *actualWidth = 0; p = pStart; while( p && p!=pEnd && (p->base.style.flags & STY_Invisible)!=0 ){ p = p->pNext; } if( p && p->base.style.flags & STY_DT ){ origin = -HTML_INDENT; }else{ origin = 0; } x = origin; if( x<minX ){ x = minX; } if( p && p!=pEnd && p->base.type==Html_LI ){ p->li.x = x - HTML_INDENT/3; if( p->li.x - (HTML_INDENT*2)/3<minX ){ x += minX - p->li.x + (HTML_INDENT*2)/3; p->li.x = minX + (HTML_INDENT*2)/3; } isEmpty = 0; *actualWidth = 1; p = p->pNext; while( p && (p->base.type==Html_Space || p->base.type==Html_P) ){ p = p->pNext; } } for(; p && p!=pEnd; p=p->pNext){ if( p->base.style.flags & STY_Invisible ){ continue; } switch( p->base.type ){ case Html_Text: p->text.x = x + spaceWanted; if( (p->base.style.flags & STY_Preformatted) == 0 ){ if( lastBreak && x + spaceWanted + p->text.w > width ){ TestPoint(0); return lastBreak; } } TRACE(HtmlTrace_GetLine2, ("Place token %s at x=%d w=%d\n", HtmlTokenName(p), p->text.x, p->text.w)); x += p->text.w + spaceWanted; isEmpty = 0; spaceWanted = 0; break; case Html_Space: if( p->base.style.flags & STY_Preformatted ){ if( p->base.flags & HTML_NewLine ){ *actualWidth = x<=0 ? 1 : x; TestPoint(0); return p->pNext; } x += p->space.w * p->base.count; TestPoint(0); }else{ int w; if( (p->base.style.flags & STY_NoBreak)==0 ){ lastBreak = p->pNext; *actualWidth = x<=0 && !isEmpty ? 1 : x; } w = p->space.w; if( spaceWanted < w && x>origin ){ spaceWanted = w; } } break; case Html_IMG: switch( p->image.align ){ case IMAGE_ALIGN_Left: case IMAGE_ALIGN_Right: *actualWidth = x<=0 && !isEmpty ? 1 : x; return p; default: break; } p->image.x = x + spaceWanted; if( (p->base.style.flags & STY_Preformatted) == 0 ){ if( lastBreak && x + spaceWanted + p->image.w > width ){ TestPoint(0); return lastBreak; } } TRACE(HtmlTrace_GetLine2, ("Place in-line image %s at x=%d w=%d\n", HtmlTokenName(p), p->image.x, p->image.w)); x += p->image.w + spaceWanted; if( (p->base.style.flags & STY_NoBreak)==0 ){ lastBreak = p->pNext; *actualWidth = x<=0 && !isEmpty ? 1 : x; } spaceWanted = 0; isEmpty = 0; break; case Html_APPLET: case Html_EMBED: case Html_INPUT: case Html_SELECT: case Html_TEXTAREA: p->input.x = x + spaceWanted + p->input.padLeft; if( (p->base.style.flags & STY_Preformatted) == 0 ){ if( lastBreak && x + spaceWanted + p->input.w > width ){ TestPoint(0); return lastBreak; } } TRACE(HtmlTrace_GetLine2, ("Place token %s at x=%d w=%d\n", HtmlTokenName(p), p->input.x, p->input.w)); x = p->input.x + p->input.w; if( (p->base.style.flags & STY_NoBreak)==0 ){ lastBreak = p->pNext; *actualWidth = x<=0 && !isEmpty ? 1 : x; } spaceWanted = 0; isEmpty = 0; break; case Html_EndTEXTAREA: if( p->ref.pOther ){ /* HtmlResetTextarea(pLC->htmlPtr, p->ref.pOther); */ } break; case Html_DD: if( p->ref.pOther==0 ) break; if( p->ref.pOther->list.compact==0 || x + spaceWanted >= 0 ){ *actualWidth = x<=0 && !isEmpty ? 1 : x; return p; } x = 0; spaceWanted = 0; break; case Html_WBR: *actualWidth = x<=0 && !isEmpty ? 1 : x; if( x + spaceWanted >= width ){ return p->pNext; }else{ lastBreak = p->pNext; } break; case Html_ADDRESS: case Html_EndADDRESS: case Html_BLOCKQUOTE: case Html_EndBLOCKQUOTE: case Html_BODY: case Html_EndBODY: case Html_BR: case Html_CAPTION: case Html_EndCAPTION: case Html_CENTER: case Html_EndCENTER: case Html_EndDD: case Html_DIV: case Html_EndDIV: case Html_DL: case Html_EndDL: case Html_DT: case Html_H1: case Html_EndH1: case Html_H2: case Html_EndH2: case Html_H3: case Html_EndH3: case Html_H4: case Html_EndH4: case Html_H5: case Html_EndH5: case Html_H6: case Html_EndH6: case Html_EndHTML: case Html_HR: case Html_LI: case Html_LISTING: case Html_EndLISTING: case Html_MENU: case Html_EndMENU: case Html_OL: case Html_EndOL: case Html_P: case Html_EndP: case Html_PRE: case Html_EndPRE: case Html_TABLE: case Html_EndTABLE: case Html_TD: case Html_EndTD: case Html_TH: case Html_EndTH: case Html_TR: case Html_EndTR: case Html_UL: case Html_EndUL: *actualWidth = x<=0 && !isEmpty ? 1 : x; return p; default: break; } } *actualWidth = x<=0 && !isEmpty ? 1 : x; return p; } /* ** Set the y coordinate for every anchor in the given list */ static void FixAnchors(HtmlElement *p, HtmlElement *pEnd, int y){ while( p && p!=pEnd ){ if( p->base.type==Html_A ){ p->anchor.y = y; } p = p->pNext; } } /* ** This routine computes the X and Y coordinates for all elements of ** a line that has been gathered using GetLine() above. It also figures ** the ascent and descent for in-line images. ** ** The value returned is the Y coordinate of the bottom edge of the ** new line. The X coordinates are computed by adding the left margin ** plus any extra space needed for centering or right-justification. */ static int FixLine( HtmlElement *pStart, /* Start of tokens for this line */ HtmlElement *pEnd, /* First token past end of this line. Maybe NULL */ int bottom, /* Put the top of this line here */ int width, /* This is the space available to the line */ int actualWidth, /* This is the actual width needed by the line */ int leftMargin, /* The current left margin */ int *maxX /* Write maximum X coordinate of ink here */ ){ int dx; /* Amount by which to increase all X coordinates */ int maxAscent; /* Maximum height above baseline */ int maxTextAscent; /* Maximum height above baseline for text */ int maxDescent; /* Maximum depth below baseline */ int ascent, descent; /* Computed ascent and descent for one element */ HtmlElement *p; /* For looping */ int y; /* Y coordinate of the baseline */ int dy2center; /* Distance from baseline to text font center */ int max = 0; if( actualWidth>0 ){ for(p=pStart; p && p!=pEnd && p->base.type!=Html_Text; p=p->pNext){} if( p==pEnd || p==0 ) p = pStart; if( p->base.style.align == ALIGN_Center ){ dx = leftMargin + (width - actualWidth)/2; }else if( p->base.style.align == ALIGN_Right ){ dx = leftMargin + (width - actualWidth); }else{ dx = leftMargin; } if( dx<0 ) dx = 0; maxAscent = maxTextAscent = 0; for(p=pStart; p && p!=pEnd; p=p->pNext){ int ss; if( p->base.style.flags & STY_Invisible ){ continue; } switch( p->base.type ){ case Html_Text: p->text.x += dx; max = p->text.x + p->text.w; ss = p->base.style.subscript; if( ss > 0 ){ int ascent = p->text.ascent; int delta = (ascent + p->text.descent)*ss/2; ascent += delta; p->text.y = -delta; if( ascent > maxAscent ){ TestPoint(0); maxAscent = ascent; } if( ascent > maxTextAscent ){ TestPoint(0); maxTextAscent = ascent;} }else if( ss < 0 ){ int descent = p->text.descent; int delta = (descent + p->text.ascent)*(-ss)/2; descent += delta; p->text.y = delta; }else{ p->text.y = 0; if( p->text.ascent > maxAscent ){ maxAscent = p->text.ascent; } if( p->text.ascent > maxTextAscent ){ maxTextAscent = p->text.ascent; } } break; case Html_Space: if( p->space.ascent > maxAscent ){ maxAscent = p->space.ascent; } break; case Html_LI: p->li.x += dx; if( p->li.x > max ){ max = p->li.x; } break; case Html_IMG: p->image.x += dx; max = p->image.x + p->image.w; switch( p->image.align ){ case IMAGE_ALIGN_Middle: p->image.descent = p->image.h/2; p->image.ascent = p->image.h - p->image.descent; if( p->image.ascent > maxAscent ){ maxAscent = p->image.ascent; } break; case IMAGE_ALIGN_AbsMiddle: dy2center = (p->image.textDescent - p->image.textAscent)/2; p->image.descent = p->image.h/2 + dy2center; p->image.ascent = p->image.h - p->image.descent; if( p->image.ascent > maxAscent ){ maxAscent = p->image.ascent; } break; case IMAGE_ALIGN_Bottom: p->image.descent = 0; p->image.ascent = p->image.h; if( p->image.ascent > maxAscent ){ maxAscent = p->image.ascent; } break; case IMAGE_ALIGN_AbsBottom: p->image.descent = p->image.textDescent; p->image.ascent = p->image.h - p->image.descent; if( p->image.ascent > maxAscent ){ maxAscent = p->image.ascent; } break; default: TestPoint(0); break; } break; case Html_TEXTAREA: case Html_INPUT: case Html_SELECT: case Html_EMBED: case Html_APPLET: p->input.x += dx; max = p->input.x + p->input.w; dy2center = (p->input.textDescent - p->input.textAscent)/2; p->input.y = dy2center - p->input.h/2; ascent = -p->input.y; if( ascent > maxAscent ){ maxAscent = ascent; } break; default: /* Shouldn't happen */ break; } } *maxX = max; y = maxAscent + bottom; maxDescent = 0; for(p=pStart; p && p!=pEnd; p=p->pNext){ if( p->base.style.flags & STY_Invisible ){ TestPoint(0); continue; } switch( p->base.type ){ case Html_Text: p->text.y += y; if( p->text.descent > maxDescent ){ maxDescent = p->text.descent; } break; case Html_LI: p->li.y = y; if( p->li.descent > maxDescent ){ maxDescent = p->li.descent; } break; case Html_IMG: p->image.y = y; switch( p->image.align ){ case IMAGE_ALIGN_Top: p->image.ascent = maxAscent; p->image.descent = p->image.h - maxAscent; TestPoint(0); break; case IMAGE_ALIGN_TextTop: p->image.ascent = maxTextAscent; p->image.descent = p->image.h - maxTextAscent; TestPoint(0); break; default: TestPoint(0); break; } if( p->image.descent > maxDescent ){ maxDescent = p->image.descent; } break; case Html_INPUT: case Html_SELECT: case Html_TEXTAREA: case Html_APPLET: case Html_EMBED: descent = p->input.y + p->input.h; p->input.y += y; if( descent > maxDescent ){ maxDescent = descent; } break; default: /* Shouldn't happen */ break; } } TRACE(HtmlTrace_FixLine, ("Setting baseline to %d. bottom=%d ascent=%d descent=%d dx=%d\n", y, bottom, maxAscent, maxDescent, dx)); }else{ maxDescent = 0; y = bottom; } return y + maxDescent; } /* ** Increase the headroom to create a paragraph break at the current token */ static void Paragraph( HtmlLayoutContext *pLC, HtmlElement *p ){ int headroom; if( p==0 ){ TestPoint(0); return; } if( p->base.type==Html_Text ){ headroom = p->text.ascent + p->text.descent; TestPoint(0); }else if( p->pNext && p->pNext->base.type==Html_Text ){ headroom = p->pNext->text.ascent + p->pNext->text.descent; TestPoint(0); }else{ Tk_FontMetrics fontMetrics; Tk_Font font; font = HtmlGetFont(pLC->htmlPtr, p->base.style.font); if( font==0 ) return; Tk_GetFontMetrics(font, &fontMetrics); headroom = fontMetrics.descent + fontMetrics.ascent; TestPoint(0); } if( pLC->headRoom < headroom && pLC->bottom > pLC->top ){ pLC->headRoom = headroom; } } /* ** Compute the current margins for layout. Three values are returned: ** ** *pY The top edge of the area in which we can put ink. This ** takes into account any requested headroom. ** ** *pX The left edge of the inkable area. The takes into account ** any margin requests active at vertical position specified ** in pLC->bottom. ** ** *pW The width of the inkable area. This takes into account ** an margin requests that are active at the vertical position ** pLC->bottom. ** */ void HtmlComputeMargins( HtmlLayoutContext *pLC, /* The current layout context */ int *pX, /* Put the left edge here */ int *pY, /* Put the top edge here */ int *pW /* Put the width here */ ){ int x, y, w; y = pLC->bottom + pLC->headRoom; PopExpiredMargins(&pLC->leftMargin, pLC->bottom); PopExpiredMargins(&pLC->rightMargin, pLC->bottom); w = pLC->pageWidth - pLC->right; if( pLC->leftMargin ){ x = pLC->leftMargin->indent + pLC->left; TestPoint(0); }else{ x = pLC->left; TestPoint(0); } w -= x; if( pLC->rightMargin ){ w -= pLC->rightMargin->indent; TestPoint(0); }else{ TestPoint(0); } *pX = x; *pY = y; *pW = w; } /* ** Clear a wrap-around obstacle. The second option determines the ** precise behavior. ** ** CLEAR_Left Clear all obstacles on the left. ** ** CLEAR_Right Clear all obstacles on the right. ** ** CLEAR_Both Clear all obstacles on both sides. ** ** CLEAR_First Clear only the first obsticle on either side. */ #define CLEAR_Left 0 #define CLEAR_Right 1 #define CLEAR_Both 2 #define CLEAR_First 3 static void ClearObstacle(HtmlLayoutContext *pLC, int mode){ int newBottom = pLC->bottom; PopExpiredMargins(&pLC->leftMargin, pLC->bottom); PopExpiredMargins(&pLC->rightMargin, pLC->bottom); switch( mode ){ case CLEAR_Both: ClearObstacle(pLC,CLEAR_Left); ClearObstacle(pLC,CLEAR_Right); TestPoint(0); break; case CLEAR_Left: while( pLC->leftMargin && pLC->leftMargin->bottom>=0 ){ newBottom = pLC->leftMargin->bottom; HtmlPopOneMargin(&pLC->leftMargin); TestPoint(0); } if( newBottom > pLC->bottom + pLC->headRoom ){ pLC->headRoom = 0; TestPoint(0); }else{ pLC->headRoom = newBottom - pLC->bottom; TestPoint(0); } pLC->bottom = newBottom; PopExpiredMargins(&pLC->rightMargin, pLC->bottom); break; case CLEAR_Right: while( pLC->rightMargin && pLC->rightMargin->bottom>=0 ){ newBottom = pLC->rightMargin->bottom; HtmlPopOneMargin(&pLC->rightMargin); TestPoint(0); } if( newBottom > pLC->bottom + pLC->headRoom ){ pLC->headRoom = 0; TestPoint(0); }else{ pLC->headRoom = newBottom - pLC->bottom; TestPoint(0); } pLC->bottom = newBottom; PopExpiredMargins(&pLC->leftMargin, pLC->bottom); break; case CLEAR_First: if( pLC->leftMargin && pLC->leftMargin->bottom>=0 ){ if( pLC->rightMargin && pLC->rightMargin->bottom < pLC->leftMargin->bottom ){ newBottom = pLC->rightMargin->bottom; HtmlPopOneMargin(&pLC->rightMargin); TestPoint(0); }else{ newBottom = pLC->leftMargin->bottom; HtmlPopOneMargin(&pLC->leftMargin); TestPoint(0); } }else if( pLC->rightMargin && pLC->rightMargin->bottom>=0 ){ newBottom = pLC->rightMargin->bottom; HtmlPopOneMargin(&pLC->rightMargin); TestPoint(0); }else{ TestPoint(0); } if( newBottom > pLC->bottom + pLC->headRoom ){ pLC->headRoom = 0; TestPoint(0); }else{ pLC->headRoom = newBottom - pLC->bottom; TestPoint(0); } pLC->bottom = newBottom; break; } } /* ** Break markup is any kind of markup that might force a line-break. This ** routine handles a single element of break markup and returns a pointer ** to the first element past that markup. If p doesn't point to break ** markup, then p is returned. If p is an incomplete table (a <TABLE> ** that lacks a </TABLE>), then NULL is returned. */ static HtmlElement *DoBreakMarkup( HtmlLayoutContext *pLC, HtmlElement *p ){ HtmlElement *pNext = p->pNext; char *z; int x, y, w; switch( p->base.type ){ case Html_A: p->anchor.y = pLC->bottom; TestPoint(0); break; case Html_BLOCKQUOTE: HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, Html_EndBLOCKQUOTE); HtmlPushMargin(&pLC->rightMargin, HTML_INDENT, -1, Html_EndBLOCKQUOTE); Paragraph(pLC, p); TestPoint(0); break; case Html_EndBLOCKQUOTE: HtmlPopMargin(&pLC->leftMargin, Html_EndBLOCKQUOTE, pLC); HtmlPopMargin(&pLC->rightMargin, Html_EndBLOCKQUOTE, pLC); Paragraph(pLC, p); TestPoint(0); break; case Html_IMG: switch( p->image.align ){ case IMAGE_ALIGN_Left: HtmlComputeMargins(pLC, &x, &y, &w); p->image.x = x; p->image.y = y; p->image.ascent = 0; p->image.descent = p->image.h; HtmlPushMargin(&pLC->leftMargin, p->image.w + 2, y + p->image.h, 0); SETMAX( pLC->maxY, y + p->image.h ); SETMAX( pLC->maxX, x + p->image.w ); break; case IMAGE_ALIGN_Right: HtmlComputeMargins(pLC, &x, &y, &w); p->image.x = x + w - p->image.w; p->image.y = y; p->image.ascent = 0; p->image.descent = p->image.h; HtmlPushMargin(&pLC->rightMargin, p->image.w + 2, y + p->image.h, 0); SETMAX( pLC->maxY, y + p->image.h ); SETMAX( pLC->maxX, x + p->image.w ); break; default: TestPoint(0); pNext = p; break; } break; case Html_PRE: /* Skip space tokens thru the next newline. */ while( pNext->base.type==Html_Space ){ HtmlElement *pThis = pNext; pNext = pNext->pNext; if( pThis->base.flags & HTML_NewLine ){ TestPoint(0); break; } } Paragraph(pLC,p); break; case Html_UL: case Html_MENU: case Html_DIR: case Html_OL: if( p->list.compact==0 ){ Paragraph(pLC,p); } HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, p->base.type+1); break; case Html_EndOL: case Html_EndUL: case Html_EndMENU: case Html_EndDIR: if( p->ref.pOther ){ HtmlPopMargin(&pLC->leftMargin, p->base.type, pLC); if( !p->ref.pOther->list.compact ){ Paragraph(pLC,p); } } break; case Html_DL: Paragraph(pLC,p); HtmlPushMargin(&pLC->leftMargin, HTML_INDENT, -1, Html_EndDL); TestPoint(0); break; case Html_EndDL: HtmlPopMargin(&pLC->leftMargin, Html_EndDL, pLC); Paragraph(pLC,p); TestPoint(0); break; case Html_HR: { int zl, wd; p->hr.is3D = HtmlMarkupArg(p, "noshade", 0)==0; z = HtmlMarkupArg(p, "size", 0); if( z ){ p->hr.h = atoi(z); }else{ p->hr.h = 0; } if( p->hr.h<1 ){ int relief = pLC->htmlPtr->ruleRelief; if( p->hr.is3D && (relief==TK_RELIEF_SUNKEN || relief==TK_RELIEF_RAISED) ){ p->hr.h = 3; }else{ p->hr.h = 2; } } HtmlComputeMargins(pLC, &x, &y, &w); p->hr.y = y; y += p->hr.h + 1; p->hr.x = x; z = HtmlMarkupArg(p, "width", "100%"); zl = strlen(z); if( zl>0 && z[zl-1]=='%' ){ wd = (atoi(z)*w)/100; }else{ wd = atoi(z); } if( wd>w ) wd = w; p->hr.w = wd; switch( p->base.style.align ){ case ALIGN_Center: case ALIGN_None: p->hr.x += (w - wd)/2; TestPoint(0); break; case ALIGN_Right: p->hr.x += (w - wd); TestPoint(0); break; default: TestPoint(0); break; } SETMAX( pLC->maxY, y); SETMAX( pLC->maxX, wd + p->hr.x ); pLC->bottom = y; pLC->headRoom = 0; break; } case Html_ADDRESS: case Html_EndADDRESS: case Html_CENTER: case Html_EndCENTER: case Html_DIV: case Html_EndDIV: case Html_H1: case Html_EndH1: case Html_H2: case Html_EndH2: case Html_H3: case Html_EndH3: case Html_H4: case Html_EndH4: case Html_H5: case Html_EndH5: case Html_H6: case Html_EndH6: case Html_P: case Html_EndP: case Html_EndPRE: Paragraph(pLC, p); TestPoint(0); break; case Html_TABLE: pNext = HtmlTableLayout(pLC, p); TestPoint(0); break; case Html_BR: z = HtmlMarkupArg(p, "clear",0); if( z ){ if( stricmp(z,"left")==0 ){ ClearObstacle(pLC, CLEAR_Left); TestPoint(0); }else if( stricmp(z,"right")==0 ){ ClearObstacle(pLC, CLEAR_Right); TestPoint(0); }else{ ClearObstacle(pLC, CLEAR_Both); TestPoint(0); } }else{ TestPoint(0); } break; /* All of the following tags need to be handed to the GetLine() routine */ case Html_Text: case Html_Space: case Html_LI: case Html_INPUT: case Html_SELECT: case Html_TEXTAREA: case Html_APPLET: case Html_EMBED: pNext = p; TestPoint(0); break; default: TestPoint(0); break; } return pNext; } /* ** Return TRUE (non-zero) if we are currently wrapping text around ** one or more images. */ static int InWrapAround(HtmlLayoutContext *pLC){ if( pLC->leftMargin && pLC->leftMargin->bottom >= 0 ){ TestPoint(0); return 1; } if( pLC->rightMargin && pLC->rightMargin->bottom >= 0 ){ TestPoint(0); return 1; } TestPoint(0); return 0; } /* ** Move past obsticles until a linewidth of reqWidth is obtained, ** or until all obsticles are cleared. */ void HtmlWidenLine( HtmlLayoutContext *pLC, /* The layout context */ int reqWidth, /* Requested line width */ int *pX, int *pY, int *pW /* The margins. See HtmllComputeMargins() */ ){ HtmlComputeMargins(pLC, pX, pY, pW); if( *pW<reqWidth && InWrapAround(pLC) ){ ClearObstacle(pLC, CLEAR_First); HtmlComputeMargins(pLC, pX, pY, pW); } } #ifdef TABLE_TRIM_BLANK int HtmlLineWasBlank = 0; #endif /* TABLE_TRIM_BLANK */ /* ** Do as much layout as possible on the block of text defined by ** the HtmlLayoutContext. */ void HtmlLayoutBlock(HtmlLayoutContext *pLC){ HtmlElement *p, *pNext; for(p=pLC->pStart; p && p!=pLC->pEnd; p=pNext){ int lineWidth; int actualWidth; int y = 0; int leftMargin; int maxX = 0; /* Do as much break markup as we can. */ while( p && p!=pLC->pEnd ){ HtmlLock(pLC->htmlPtr); pNext = DoBreakMarkup(pLC, p); if( HtmlUnlock(pLC->htmlPtr) ) return; if( pNext==p ){ TestPoint(0); break; } if( pNext ){ TRACE(HtmlTrace_BreakMarkup, ("Processed token %s as break markup\n", HtmlTokenName(p))); pLC->pStart = p; } p = pNext; TestPoint(0); } if( p==0 || p==pLC->pEnd ){ TestPoint(0); break; } #ifdef TABLE_TRIM_BLANK HtmlLineWasBlank = 0; #endif /* TABLE_TRIM_BLANK */ /* We might try several times to layout a single line... */ while( 1 ){ /* Compute margins */ HtmlComputeMargins(pLC, &leftMargin, &y, &lineWidth); /* Layout a single line of text */ pNext = GetLine(pLC, p, pLC->pEnd, lineWidth, pLC->left-leftMargin, &actualWidth); TRACE(HtmlTrace_GetLine, ("GetLine page=%d left=%d right=%d available=%d used=%d\n", pLC->pageWidth, pLC->left, pLC->right, lineWidth, actualWidth)); FixAnchors(p,pNext,pLC->bottom); /* Move down and repeat the layout if we exceeded the available ** line length and it is possible to increase the line length by ** moving past some obsticle. */ if( actualWidth > lineWidth && InWrapAround(pLC) ){ ClearObstacle(pLC, CLEAR_First); TestPoint(0); continue; } /* Lock the line into place and exit the loop */ y = FixLine(p, pNext, y, lineWidth, actualWidth, leftMargin, &maxX); TestPoint(0); break; } #ifdef TABLE_TRIM_BLANK /* * I noticed that a newline following break markup would result * in a blank line being drawn. So if an "empty" line was found * I subtract any whitespace caused by break markup. */ if (actualWidth <= 0) { HtmlLineWasBlank = 1; } #endif /* TABLE_TRIM_BLANK */ /* If a line was completed, advance to the next line */ if( pNext && actualWidth>0 && y > pLC->bottom ){ pLC->bottom = y; pLC->headRoom = 0; pLC->pStart = pNext; } if( y > pLC->maxY ){ pLC->maxY = y; } if( maxX > pLC->maxX ){ pLC->maxX = maxX; } } } /* ** Advance the layout as far as possible */ void HtmlLayout(HtmlWidget *htmlPtr){ HtmlLayoutContext *pLC; int btm; if( htmlPtr->pFirst==0 ) return; HtmlLock(htmlPtr); HtmlSizer(htmlPtr); if( HtmlUnlock(htmlPtr) ) return; pLC = &htmlPtr->layoutContext; pLC->htmlPtr = htmlPtr; pLC->pageWidth = htmlPtr->realWidth - 2*(htmlPtr->inset + htmlPtr->padx); pLC->left = 0; pLC->right = 0; pLC->pStart = htmlPtr->nextPlaced; if( pLC->pStart==0 ){ pLC->pStart = htmlPtr->pFirst; } if( pLC->pStart ){ pLC->maxX = htmlPtr->maxX; pLC->maxY = htmlPtr->maxY; btm = pLC->bottom; HtmlLock(htmlPtr); HtmlLayoutBlock(pLC); if( HtmlUnlock(htmlPtr) ) return; htmlPtr->maxX = pLC->maxX; htmlPtr->maxY = pLC->maxY; htmlPtr->nextPlaced = pLC->pStart; htmlPtr->flags |= HSCROLL | VSCROLL; HtmlRedrawText(htmlPtr, btm); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlwish.c������������������������������������������������������������������0000644�0001750�0001750�00000000441�07504443346�016055� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlwish.c,v 1.1.1.1 2002/06/20 21:19:34 joye Exp $"; /* ** Make a "wish" that includes the html widget. ** */ #include "appinit.h" int Et_AppInit(Tcl_Interp *interp){ extern int Tkhtml_Init(Tcl_Interp*); Tkhtml_Init(interp); return TCL_OK; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmldraw.c������������������������������������������������������������������0000644�0001750�0001750�00000062054�07504443345�016047� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmldraw.c,v 1.1.1.1 2002/06/20 21:19:33 joye Exp $"; /* ** Routines used to render HTML onto the screen for the Tk HTML widget. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <string.h> #include <stdlib.h> #include "htmldraw.h" #ifdef USE_TK_STUBS # include <tkIntXlibDecls.h> #endif #define USE_TK_DRAWCHARS 1 /* ** Allocate a new HtmlBlock structure. */ static HtmlBlock *AllocBlock(void){ HtmlBlock *pNew; pNew = HtmlAlloc( sizeof(HtmlBlock) ); if( pNew ){ memset(pNew, 0, sizeof(*pNew)); pNew->base.type = Html_Block; } return pNew; } /* ** Free an HtmlBlock structure. Assume that it is already unlinked ** from the element list and the block list. */ static void FreeBlock(HtmlBlock *pBlock){ if( pBlock ){ if( pBlock->z ){ HtmlFree(pBlock->z); } HtmlFree(pBlock); } } /* ** Destroy the given Block after first unlinking it from the ** element list. Note that this unlinks the block from the ** element list only -- not from the block list. */ static void UnlinkAndFreeBlock(HtmlWidget *htmlPtr, HtmlBlock *pBlock){ if( pBlock->base.pNext ){ pBlock->base.pNext->base.pPrev = pBlock->base.pPrev; TestPoint(0); }else{ htmlPtr->pLast = pBlock->base.pPrev; TestPoint(0); } if( pBlock->base.pPrev ){ pBlock->base.pPrev->base.pNext = pBlock->base.pNext; TestPoint(0); }else{ htmlPtr->pFirst = pBlock->base.pNext; TestPoint(0); } pBlock->base.pPrev = pBlock->base.pNext = 0; FreeBlock(pBlock); } /* ** Append a block to the block list and insert the block into the ** element list immediately prior to the element given. */ static void AppendBlock( HtmlWidget *htmlPtr, /* The HTML widget */ HtmlElement *pToken, /* The token that comes after pBlock */ HtmlBlock *pBlock /* The block to be appended */ ){ pBlock->base.pPrev = pToken->base.pPrev; pBlock->base.pNext = pToken; pBlock->pPrev = htmlPtr->lastBlock; pBlock->pNext = 0; if( htmlPtr->lastBlock ){ htmlPtr->lastBlock->pNext = pBlock; TestPoint(0); }else{ htmlPtr->firstBlock = pBlock; TestPoint(0); } htmlPtr->lastBlock = pBlock; if( pToken->base.pPrev ){ pToken->base.pPrev->base.pNext = (HtmlElement*)pBlock; TestPoint(0); }else{ htmlPtr->pFirst = (HtmlElement*)pBlock; TestPoint(0); } pToken->base.pPrev = (HtmlElement*)pBlock; } /* ** Print an ordered list index into the given buffer. Use numbering ** like this: ** ** A B C ... Y Z AA BB CC ... ZZ ** ** Revert to decimal for indices greater than 52. */ static void GetLetterIndex(char *zBuf, int index, int isUpper){ int seed; if( index<1 || index>52 ){ sprintf(zBuf,"%d",index); TestPoint(0); return; } if( isUpper ){ seed = 'A'; TestPoint(0); }else{ seed = 'a'; TestPoint(0); } index--; if( index<26 ){ zBuf[0] = seed + index; zBuf[1] = 0; TestPoint(0); }else{ index -= 26; zBuf[0] = seed + index; zBuf[1] = seed + index; zBuf[2] = 0; TestPoint(0); } strcat(zBuf,"."); } /* ** Print an ordered list index into the given buffer. Use roman ** numerals. For indices greater than a few thousand, revert to ** decimal. */ static void GetRomanIndex(char *zBuf, int index, int isUpper){ int i = 0; int j; static struct { int value; char *name; } values[] = { { 1000, "m" }, { 999, "im" }, { 990, "xm" }, { 900, "cm" }, { 500, "d" }, { 499, "id" }, { 490, "xd" }, { 400, "cd" }, { 100, "c" }, { 99, "ic" }, { 90, "xc" }, { 50, "l" }, { 49, "il" }, { 40, "xl" }, { 10, "x" }, { 9, "ix" }, { 5, "v" }, { 4, "iv" }, { 1, "i" }, }; if( index<1 || index>=5000 ){ sprintf(zBuf,"%d",index); TestPoint(0); return; } for(j=0; index>0 && j<sizeof(values)/sizeof(values[0]); j++){ int k; while( index >= values[j].value ){ for(k=0; values[j].name[k]; k++){ zBuf[i++] = values[j].name[k]; TestPoint(0); } index -= values[j].value; TestPoint(0); } } zBuf[i] = 0; if( isUpper ){ for(i=0; zBuf[i]; i++){ zBuf[i] += 'A' - 'a'; TestPoint(0); } }else{ TestPoint(0); } strcat(zBuf,"."); } /* Draw the selection background for the given block */ static void DrawSelectionBackground( HtmlWidget *htmlPtr, /* The HTML widget */ HtmlBlock *pBlock, /* The block whose background is drawn */ Drawable drawable, /* Draw the background on this drawable */ int x, int y /* Virtual coords of top-left of drawable */ ){ int xLeft, xRight; /* Left and right bounds of box to draw */ int yTop, yBottom; /* Top and bottom of box */ HtmlElement *p = 0; /* First element of the block */ Tk_Font font; /* Font */ GC gc; /* GC for drawing */ XRectangle xrec; /* Size of a filled rectangle to be drawn */ if( pBlock==0 || (pBlock->base.flags & HTML_Selected)==0 ){ TestPoint(0); return; } xLeft = pBlock->left - x; if( pBlock==htmlPtr->pSelStartBlock && htmlPtr->selStartIndex>0 ){ if( htmlPtr->selStartIndex >= pBlock->n ){ TestPoint(0); return; } p = pBlock->base.pNext; font = HtmlGetFont(htmlPtr, p->base.style.font); if( font==0 ) return; if( p->base.type==Html_Text ){ xLeft = p->text.x - x + Tk_TextWidth(font, pBlock->z, htmlPtr->selStartIndex); } } xRight = pBlock->right - x; if( pBlock==htmlPtr->pSelEndBlock && htmlPtr->selEndIndex<pBlock->n ){ if( p==0 ){ p = pBlock->base.pNext; font = HtmlGetFont(htmlPtr, p->base.style.font); if( font==0 ) return; } if( p->base.type==Html_Text ){ xRight = p->text.x - x + Tk_TextWidth(font, pBlock->z, htmlPtr->selEndIndex); } } yTop = pBlock->top - y; yBottom = pBlock->bottom - y; gc = HtmlGetGC(htmlPtr, COLOR_Selection, FONT_Any); xrec.x = xLeft; xrec.y = yTop; xrec.width = xRight - xLeft; xrec.height = yBottom - yTop; XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); } /* ** Draw a rectangle. The rectangle will have a 3-D appearance if ** flat==0 and a flat appearance if flat==1. ** ** We don't use Tk_Draw3DRectangle() because it doesn't work well ** when the background color is close to pure white or pure black. */ static void HtmlDrawRect( HtmlWidget *htmlPtr, /* The HTML widget */ Drawable drawable, /* Draw it here */ HtmlElement *src, /* Element associated with drawing */ int x, int y, int w, int h, /* Coordinates of the rectangle */ int depth, /* Width of the relief, or the flat line */ int relief /* The relief. TK_RELIEF_FLAT omits 3d */ ){ if( depth>0 ){ int i; GC gcLight, gcDark; XRectangle xrec[1]; if( relief!=TK_RELIEF_FLAT ){ int iLight, iDark; iLight = HtmlGetLightShadowColor(htmlPtr, src->base.style.bgcolor); gcLight = HtmlGetGC(htmlPtr, iLight, FONT_Any); iDark = HtmlGetDarkShadowColor(htmlPtr, src->base.style.bgcolor); gcDark = HtmlGetGC(htmlPtr, iDark, FONT_Any); if( relief==TK_RELIEF_SUNKEN ){ GC gcTemp = gcLight; gcLight = gcDark; gcDark = gcTemp; } }else{ gcLight = HtmlGetGC(htmlPtr, src->base.style.color, FONT_Any); gcDark = gcLight; } xrec[0].x = x; xrec[0].y = y; xrec[0].width = depth; xrec[0].height = h; XFillRectangles(htmlPtr->display, drawable, gcLight, xrec, 1); xrec[0].x = x+w-depth; XFillRectangles(htmlPtr->display, drawable, gcDark, xrec, 1); for(i=0; i<depth && i<h/2; i++){ XDrawLine(htmlPtr->display, drawable, gcLight, x+i, y+i, x+w-i-1, y+i); XDrawLine(htmlPtr->display, drawable, gcDark, x+i, y+h-i-1, x+w-i-1, y+h-i-1); } } if( h>depth*2 && w>depth*2 ){ GC gcBg; XRectangle xrec[1]; gcBg = HtmlGetGC(htmlPtr, src->base.style.bgcolor, FONT_Any); xrec[0].x = x + depth; xrec[0].y = y + depth; xrec[0].width = w - depth*2; xrec[0].height = h - depth*2; XFillRectangles(htmlPtr->display, drawable, gcBg, xrec, 1); } } /* ** Display a single HtmlBlock. This is where all the drawing ** happens. */ void HtmlBlockDraw( HtmlWidget *htmlPtr, /* The main HTML widget */ HtmlBlock *pBlock, /* Block which needs to be drawn */ Drawable drawable, /* Draw the line on this */ int drawableLeft, /* Virtual coordinate of left edge of drawable */ int drawableTop, /* Virtual coordinate of top edge of drawable */ int drawableWidth, /* Width of the drawable */ int drawableHeight /* Height of the drawable */ ){ Tk_Font font; /* Font to use to render text */ GC gc; /* A graphics context */ HtmlElement *src; /* HtmlElement holding style information */ HtmlElement *pTable; /* The table (when drawing part of a table) */ int x, y; /* Where to draw */ if( pBlock==0 ){ TestPoint(0); return; } src = pBlock->base.pNext; while( src && (src->base.flags & HTML_Visible)==0 ){ src = src->base.pNext; TestPoint(0); } if( src==0 ){ TestPoint(0); return; } if( pBlock->n>0 ){ /* We must be dealing with plain old text */ if( src->base.type==Html_Text ){ x = src->text.x; y = src->text.y; TestPoint(0); }else{ CANT_HAPPEN; return; } if( pBlock->base.flags & HTML_Selected ){ HtmlLock(htmlPtr); DrawSelectionBackground(htmlPtr, pBlock, drawable, drawableLeft, drawableTop); if( HtmlUnlock(htmlPtr) ) return; } gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); font = HtmlGetFont(htmlPtr, src->base.style.font); if( font==0 ) return; Tk_DrawChars(htmlPtr->display, drawable, gc, font, pBlock->z, pBlock->n, x - drawableLeft, y - drawableTop); if( src->base.style.flags & STY_Underline ){ Tk_UnderlineChars(htmlPtr->display, drawable, gc, font, pBlock->z, x - drawableLeft, y-drawableTop, 0, pBlock->n); } if( src->base.style.flags & STY_StrikeThru ){ XRectangle xrec; xrec.x = pBlock->left - drawableLeft; xrec.y = (pBlock->top + pBlock->bottom)/2 - drawableTop; xrec.width = pBlock->right - pBlock->left; xrec.height = 1 + (pBlock->bottom - pBlock->top > 15); XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); } if( pBlock==htmlPtr->pInsBlock && htmlPtr->insStatus>0 ){ int x; XRectangle xrec; if( htmlPtr->insIndex < pBlock->n ){ x = src->text.x - drawableLeft; x += Tk_TextWidth(font, pBlock->z, htmlPtr->insIndex); }else{ x = pBlock->right - drawableLeft; } if( x>0 ){ TestPoint(0); x--; } xrec.x = x; xrec.y = pBlock->top - drawableTop; xrec.width = 2; xrec.height = pBlock->bottom - pBlock->top; XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); } }else{ /* We are dealing with a single HtmlElement which contains something ** other than plain text. */ int top, btm, cntr; int cnt, w; char zBuf[30]; switch( src->base.type ){ case Html_LI: x = src->li.x; y = src->li.y; cntr = (top+btm)/2; switch( src->li.type ){ case LI_TYPE_Enum_1: sprintf(zBuf,"%d.",src->li.cnt); TestPoint(0); break; case LI_TYPE_Enum_A: GetLetterIndex(zBuf,src->li.cnt,1); TestPoint(0); break; case LI_TYPE_Enum_a: GetLetterIndex(zBuf,src->li.cnt,0); TestPoint(0); break; case LI_TYPE_Enum_I: GetRomanIndex(zBuf,src->li.cnt,1); TestPoint(0); break; case LI_TYPE_Enum_i: GetRomanIndex(zBuf,src->li.cnt,0); TestPoint(0); break; default: zBuf[0] = 0; TestPoint(0); break; } gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); switch( src->li.type ){ case LI_TYPE_Undefined: case LI_TYPE_Bullet1: XFillArc(htmlPtr->display, drawable, gc, x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7, 0, 360*64); TestPoint(0); break; case LI_TYPE_Bullet2: XDrawArc(htmlPtr->display, drawable, gc, x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7, 0, 360*64); TestPoint(0); break; case LI_TYPE_Bullet3: XDrawRectangle(htmlPtr->display, drawable, gc, x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7); TestPoint(0); break; case LI_TYPE_Enum_1: case LI_TYPE_Enum_A: case LI_TYPE_Enum_a: case LI_TYPE_Enum_I: case LI_TYPE_Enum_i: cnt = strlen(zBuf); font = HtmlGetFont(htmlPtr, src->base.style.font); if( font==0 ) return; w = Tk_TextWidth(font, zBuf, cnt); Tk_DrawChars(htmlPtr->display, drawable, gc, font, zBuf, cnt, x - w - drawableLeft, y - drawableTop); TestPoint(0); break; } break; case Html_HR: { int relief = htmlPtr->ruleRelief; switch( relief ){ case TK_RELIEF_RAISED: case TK_RELIEF_SUNKEN: break; default: relief = TK_RELIEF_FLAT; break; } HtmlDrawRect(htmlPtr, drawable, src, src->hr.x - drawableLeft, src->hr.y - drawableTop, src->hr.w, src->hr.h, 1, relief); break; } case Html_TABLE: { int relief = htmlPtr->tableRelief; switch( relief ){ case TK_RELIEF_RAISED: case TK_RELIEF_SUNKEN: break; default: relief = TK_RELIEF_FLAT; break; } HtmlDrawRect(htmlPtr, drawable, src, src->table.x - drawableLeft, src->table.y - drawableTop, src->table.w, src->table.h, src->table.borderWidth, relief); break; } case Html_TH: case Html_TD: { int depth, relief; pTable = src->cell.pTable; depth = pTable && pTable->table.borderWidth>0; switch( htmlPtr->tableRelief ){ case TK_RELIEF_RAISED: relief = TK_RELIEF_SUNKEN; break; case TK_RELIEF_SUNKEN: relief = TK_RELIEF_RAISED; break; default: relief = TK_RELIEF_FLAT; break; } HtmlDrawRect(htmlPtr, drawable, src, src->cell.x - drawableLeft, src->cell.y - drawableTop, src->cell.w, src->cell.h, depth, relief); break; } case Html_IMG: if( src->image.pImage ){ HtmlDrawImage(src, drawable, drawableLeft, drawableTop, drawableLeft + drawableWidth, drawableTop + drawableHeight); }else if( src->image.zAlt ){ gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); font = HtmlGetFont(htmlPtr, src->base.style.font); if( font==0 ) return; Tk_DrawChars(htmlPtr->display, drawable, gc, font, src->image.zAlt, strlen(src->image.zAlt), src->image.x - drawableLeft, src->image.y - drawableTop); TestPoint(0); } break; default: TestPoint(0); break; } } } /* ** Draw all or part of an image. */ void HtmlDrawImage( HtmlElement *pElem, /* The <IMG> to be drawn */ Drawable drawable, /* Draw it here */ int drawableLeft, /* left edge of the drawable */ int drawableTop, /* Virtual canvas coordinate for top of drawable */ int drawableRight, /* right edge of the drawable */ int drawableBottom /* bottom edge of the drawable */ ){ int imageTop; /* virtual canvas coordinate for top of image */ int x, y; /* where to place image on the drawable */ int imageX, imageY; /* \__ Subset of image that fits */ int imageW, imageH; /* / on the drawable */ imageTop = pElem->image.y - pElem->image.ascent; y = imageTop - drawableTop; if( imageTop + pElem->image.h > drawableBottom ){ imageH = drawableBottom - imageTop; TestPoint(0); }else{ imageH = pElem->image.h; TestPoint(0); } if( y<0 ){ imageY = -y; imageH += y; y = 0; TestPoint(0); }else{ imageY = 0; TestPoint(0); } x = pElem->image.x - drawableLeft; if( pElem->image.x + pElem->image.w > drawableRight ){ imageW = drawableRight - pElem->image.x; TestPoint(0); }else{ imageW = pElem->image.w; TestPoint(0); } if( x<0 ){ imageX = -x; imageW += x; x = 0; TestPoint(0); }else{ imageX = 0; TestPoint(0); } Tk_RedrawImage(pElem->image.pImage->image, imageX, imageY, imageW, imageH, drawable, x, y); pElem->image.redrawNeeded = 0; } /* ** Recompute the following fields of the given block structure: ** ** base.count The number of elements described by this ** block structure. ** ** n The number of characters of text output ** associated with this block. If the block ** renders something other than text (ex: <IMG>) ** then set n to 0. ** ** z Pointer to malloced memory containing the ** text associated with this block. NULL if ** n is 0. ** ** Return a pointer to the first HtmlElement not covered by the ** block. */ static HtmlElement *FillOutBlock(HtmlWidget *htmlPtr, HtmlBlock *p){ HtmlElement *pElem; int go; int n; int x, y; int i; HtmlStyle style; int firstSelected; /* First selected character in this block */ int lastSelected; /* Last selected character in this block */ char zBuf[400]; /* ** Reset n and z */ if( p->n ){ p->n = 0; } if( p->z ){ HtmlFree(p->z); } firstSelected = 1000000; lastSelected = -1; /* ** Skip over HtmlElements that aren't directly displayed. */ pElem = p->base.pNext; p->base.count = 0; while( pElem && (pElem->base.flags & HTML_Visible)==0 ){ HtmlElement *pNext = pElem->pNext; if( pElem->base.type==Html_Block ){ UnlinkAndFreeBlock(htmlPtr, &pElem->block); TestPoint(0); }else{ p->base.count++; TestPoint(0); } pElem = pNext; } if( pElem==0 ){ TestPoint(0); return 0; } /* ** Handle "special" elements. */ if( pElem->base.type!=Html_Text ){ switch( pElem->base.type ){ case Html_HR: p->top = pElem->hr.y - pElem->hr.h; p->bottom = pElem->hr.y; p->left = pElem->hr.x; p->right = pElem->hr.x + pElem->hr.w; TestPoint(0); break; case Html_LI: p->top = pElem->li.y - pElem->li.ascent; p->bottom = pElem->li.y + pElem->li.descent; p->left = pElem->li.x - 10; p->right = pElem->li.x + 10; TestPoint(0); break; case Html_TD: case Html_TH: p->top = pElem->cell.y; p->bottom = pElem->cell.y + pElem->cell.h; p->left = pElem->cell.x; p->right = pElem->cell.x + pElem->cell.w; TestPoint(0); break; case Html_TABLE: p->top = pElem->table.y; p->bottom = pElem->table.y + pElem->table.h; p->left = pElem->table.x; p->right = pElem->table.x + pElem->table.w; TestPoint(0); break; case Html_IMG: p->top = pElem->image.y - pElem->image.ascent; p->bottom = pElem->image.y + pElem->image.descent; p->left = pElem->image.x; p->right = pElem->image.x + pElem->image.w; TestPoint(0); break; } p->base.count++; TestPoint(0); return pElem->pNext; } /* ** If we get this far, we must be dealing with text. */ n = 0; x = pElem->text.x; y = pElem->text.y; p->top = y - pElem->text.ascent; p->bottom = y + pElem->text.descent; p->left = x; style = pElem->base.style; go = 1; while( pElem ){ HtmlElement *pNext = pElem->pNext; switch( pElem->base.type ){ case Html_Text: if( pElem->base.style.flags & STY_Invisible ){ TestPoint(0); break; } if( pElem->text.spaceWidth <=0 ){ CANT_HAPPEN; break; } if( y != pElem->text.y || style.font != pElem->base.style.font || style.color != pElem->base.style.color || (style.flags & STY_FontMask) != (pElem->base.style.flags & STY_FontMask) ){ go = 0; TestPoint(0); }else{ int sw = pElem->text.spaceWidth; int nSpace = (pElem->text.x - x) / sw; if( nSpace * sw + x != pElem->text.x ){ go = 0; TestPoint(0); }else if( n + nSpace + pElem->base.count >= sizeof(zBuf) ){ go = 0; TestPoint(0); }else{ for(i=0; i<nSpace; i++){ zBuf[n++] = ' '; TestPoint(0); } strcpy(&zBuf[n], pElem->text.zText); n += pElem->base.count; x = pElem->text.x + pElem->text.w; } } break; case Html_Space: if( pElem->base.style.font != style.font ){ pElem = pElem->pNext; go = 0; }else if( (style.flags & STY_Preformatted)!=0 && (pElem->base.flags & HTML_NewLine)!=0 ){ pElem = pElem->pNext; go = 0; } break; case Html_Block: UnlinkAndFreeBlock(htmlPtr,&pElem->block); break; case Html_A: case Html_EndA: go = 0; break; default: if( pElem->base.flags & HTML_Visible ) go = 0; TestPoint(0); break; } if( go==0 ) break; p->base.count++; pElem = pNext; } p->right = x; while( n>0 && zBuf[n-1]==' ' ){ TestPoint(0); n--; } p->z = HtmlAlloc( n ); strncpy(p->z, zBuf, n); p->n = n; return pElem; } /* ** Scan ahead looking for a place to put a block. Return a pointer ** to the element which should come immediately after the block. ** ** if pCnt!=0, then put the number of elements skipped in *pCnt. */ static HtmlElement *FindStartOfNextBlock( HtmlWidget *htmlPtr, /* The HTML widget */ HtmlElement *p, /* First candid for the start of a block */ int *pCnt /* Write number of elements skipped here */ ){ int cnt = 0; while( p && (p->base.flags & HTML_Visible)==0 ){ HtmlElement *pNext = p->pNext; if( p->base.type==Html_Block ){ UnlinkAndFreeBlock(htmlPtr, &p->block); }else{ cnt++; } p = pNext; } if( pCnt ){ *pCnt = cnt; } return p; } /* ** Add additional blocks to the block list in order to cover ** all elements on the element list. ** ** If any old blocks are found on the element list, they must ** be left over from a prior rendering. Unlink and delete them. */ void HtmlFormBlocks(HtmlWidget *htmlPtr){ HtmlElement *pElem; if( htmlPtr->lastBlock ){ pElem = FillOutBlock(htmlPtr, htmlPtr->lastBlock); }else{ pElem = htmlPtr->pFirst; } while( pElem ){ int cnt; pElem = FindStartOfNextBlock(htmlPtr, pElem, &cnt); if( pElem ){ HtmlBlock *pNew = AllocBlock(); if( htmlPtr->lastBlock ){ htmlPtr->lastBlock->base.count += cnt; } AppendBlock(htmlPtr, pElem, pNew); pElem = FillOutBlock(htmlPtr, pNew); } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/src/htmlexts.c������������������������������������������������������������������0000644�0001750�0001750�00000005745�10334236561�016074� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** The extra routines for the HTML widget for Tcl/Tk ** ** Copyright (C) 1997-2000 Peter MacDonald and BrowseX Systems Inc. ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** peter@browsex.com ** http://browsex.com */ #include <tk.h> #include <string.h> #include <stdlib.h> #include "htmlexts.h" void HtmlTclizeAscii(Tcl_Interp *interp, HtmlIndex *s, HtmlIndex *e); /* ** WIDGET text ascii START END */ int HtmlTextAsciiCmd( HtmlWidget *htmlPtr, /* The HTML widget */ Tcl_Interp *interp, /* The interpreter */ int argc, /* Number of arguments */ char **argv /* List of all arguments */ ){ HtmlIndex iStart, iEnd; int i; char *cb, *ce; if (argc<=3) cb="begin"; else cb=argv[3]; if (argc<=4) ce=cb; else ce=argv[4]; if( HtmlGetIndex(htmlPtr, cb, &iStart.p, &iStart.i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", cb, "\"", 0); return TCL_ERROR; } if( HtmlGetIndex(htmlPtr, ce, &iEnd.p, &iEnd.i)!=0 ){ Tcl_AppendResult(interp,"malformed index: \"", ce, "\"", 0); return TCL_ERROR; } if (iEnd.p && iStart.p) { if ((!iEnd.i) && (!strchr(ce,'.'))) { iEnd.p=iEnd.p->pNext; } HtmlTclizeAscii(interp,&iStart,&iEnd); } return TCL_OK; } /* ** Return all tokens between the two elements as a Text. */ void HtmlTclizeAscii(Tcl_Interp *interp, HtmlIndex *s, HtmlIndex *e){ int i,j, nsub=0; HtmlElement* p=s->p; Tcl_DString str; if (p && p->base.type==Html_Text) { nsub=s->i; } Tcl_DStringInit(&str); while( p) { switch( p->base.type ){ case Html_Block: break; case Html_Text: j=strlen(p->text.zText); if (j<nsub) nsub=j; if (p==e->p) { j= (e->i-nsub+1); } Tcl_DStringAppend(&str, p->text.zText+nsub,j-nsub); nsub=0; break; case Html_Space: for (j=0; j< p->base.count; j++) { if (nsub-->0) continue; Tcl_DStringAppend(&str, " ", 1); } if ((p->base.flags & HTML_NewLine)!=0) Tcl_DStringAppend(&str, "\n",1); nsub=0; break; case Html_P: case Html_BR: Tcl_DStringAppend(&str, "\n",1); break; case Html_Unknown: break; default: break; } if (p==e->p) break; p = p->pNext; } Tcl_DStringResult(interp, &str); } ���������������������������./saods9/htmlwidget/src/htmlurl.c�������������������������������������������������������������������0000644�0001750�0001750�00000025176�07627767076�015740� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static char const rcsid[] = "@(#) $Id: htmlurl.c,v 1.2 2003/02/28 23:18:22 joye Exp $"; /* ** Routines for processing URLs. ** ** Copyright (C) 1997-2000 D. Richard Hipp ** ** 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 Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <tk.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include "htmlurl.h" #if LOCAL_INTERFACE /* ** A parsed URI is held in an instance of the following structure. ** Each component is recorded in memory obtained from HtmlAlloc(). ** ** The examples are from the URI ** ** http://192.168.1.1:8080/cgi-bin/printenv?name=xyzzy&addr=none#frag */ struct HtmlUri { char *zScheme; /* Ex: "http" */ char *zAuthority; /* Ex: "192.168.1.1:8080" */ char *zPath; /* Ex: "cgi-bin/printenv" */ char *zQuery; /* Ex: "name=xyzzy&addr=none" */ char *zFragment; /* Ex: "frag" */ }; #endif /* ** Return the length of the next component of the URL in z[] given ** that the component starts at z[0]. The initial sequence of the ** component must be zInit[]. The component is terminated by any ** character in zTerm[]. The length returned is 0 if the component ** doesn't exist. The length includes the zInit[] string, but not ** the termination character. ** ** Component zInit zTerm ** ---------- ------- ------- ** scheme "" ":/?#" ** authority "//" "/?#" ** path "/" "?#" ** query "?" "#" ** fragment "#" "" */ static int ComponentLength(const char *z, const char *zInit, const char *zTerm){ int i, n; for(n=0; zInit[n]; n++){ if( zInit[n]!=z[n] ) return 0; } while( z[n] ){ for(i=0; zTerm[i]; i++){ if( z[n]==zTerm[i] ) return n; } n++; } return n; } /* ** Duplicate a string of length n. */ static char *StrNDup(const char *z, int n){ char *zResult; if(!n) return NULL; if( n<=0 ){ n = strlen(z); } zResult = HtmlAlloc( n + 1 ); if( zResult ){ memcpy(zResult, z, n); zResult[n] = 0; TestPoint(0); } return zResult; } /* ** Parse a text URI into an HtmlUri structure. */ static HtmlUri *ParseUri(const char *zUri){ HtmlUri *p; int n; p = HtmlAlloc( sizeof(*p) ); if( p==0 ) return 0; memset(p, 0, sizeof(*p)); if( zUri==0 || zUri[0]==0 ) return p; while( isspace(zUri[0]) ){ zUri++; } n = ComponentLength(zUri, "", ":/?# "); if( n>0 && zUri[n]==':' ){ p->zScheme = StrNDup(zUri, n); zUri += n+1; } n = ComponentLength(zUri, "//", "/?# "); if( n>0 ){ p->zAuthority = StrNDup(&zUri[2], n-2); zUri += n; } n = ComponentLength(zUri, "", "?# "); if( n>0 ){ p->zPath = StrNDup(zUri, n); zUri += n; } n = ComponentLength(zUri, "?", "# "); if( n>0 ){ p->zQuery = StrNDup(&zUri[1], n-1); zUri += n; } n = ComponentLength(zUri, "#", " "); if( n>0 ){ p->zFragment = StrNDup(&zUri[1], n-1); } return p; } /* ** Delete an HtmlUri structure. */ static void FreeUri(HtmlUri *p){ if( p==0 ) return; if( p->zScheme ) HtmlFree(p->zScheme); if( p->zAuthority ) HtmlFree(p->zAuthority); if( p->zPath ) HtmlFree(p->zPath); if( p->zQuery ) HtmlFree(p->zQuery); if( p->zFragment ) HtmlFree(p->zFragment); HtmlFree(p); } /* ** Create a string to hold the given URI. Memory to hold the string ** is obtained from HtmlAlloc() and must be freed by the calling ** function. */ static char *BuildUri(HtmlUri *p){ int n = 1; char *z; if( p->zScheme ) n += strlen(p->zScheme)+1; if( p->zAuthority ) n += strlen(p->zAuthority)+2; if( p->zPath ) n += strlen(p->zPath)+1; if( p->zQuery ) n += strlen(p->zQuery)+1; if( p->zFragment ) n += strlen(p->zFragment)+1; z = HtmlAlloc( n ); if( z==0 ) return 0; n = 0; if( p->zScheme ){ sprintf(z, "%s:", p->zScheme); n = strlen(z); } if( p->zAuthority ){ sprintf(&z[n], "//%s", p->zAuthority); n += strlen(&z[n]); } if( p->zPath ){ sprintf(&z[n], "%s", p->zPath); n += strlen(&z[n]); } if( p->zQuery ){ sprintf(&z[n], "?%s", p->zQuery); n += strlen(&z[n]); } if( p->zFragment ){ sprintf(&z[n], "#%s", p->zFragment); }else{ z[n] = 0; } return z; } /* ** Replace the string in *pzDest with the string in zSrc */ static void ReplaceStr(char **pzDest, const char *zSrc){ if( *pzDest!=0 ) HtmlFree(*pzDest); if( zSrc==0 ){ *pzDest = 0; }else{ *pzDest = StrNDup(zSrc, -1); } } /* ** Remove leading and trailing spaces from the given string. Return ** a new string obtained from HtmlAlloc(). */ static char *Trim(char *z){ int i; char *zNew; while( isspace(*z) ) z++; i = strlen(z); zNew = HtmlAlloc( i+1 ); if( zNew==0 ) return 0; strcpy(zNew, z); if( i>0 && isspace(zNew[i-1]) ){ i--; zNew[i] = 0; } return zNew; } /* ** The input azSeries[] is a sequence of URIs. This command must ** resolve them all and put the result in the interp->result field ** of the interpreter associated with the HTML widget. Return ** TCL_OK on success and TCL_ERROR if there is a failure. ** ** This function can cause the HTML widget to be deleted or changed ** arbitrarily. */ int HtmlCallResolver( HtmlWidget *htmlPtr, /* The widget that is doing the resolving. */ char **azSeries /* A list of URIs. NULL terminated */ ){ int rc = TCL_OK; /* Return value of this function. */ char *z; HtmlVerifyLock(htmlPtr); if( htmlPtr->zResolverCommand && htmlPtr->zResolverCommand[0] ){ /* ** Append the current base URI then the azSeries arguments to the ** TCL command specified by the -resolvercommand optoin, then execute ** the result. ** ** The -resolvercommand could do nasty things, such as delete ** the HTML widget out from under us. Be prepared for the worst. */ Tcl_DString cmd; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zResolverCommand, -1); if( htmlPtr->zBaseHref && htmlPtr->zBaseHref[0] ){ z = Trim(htmlPtr->zBaseHref); }else if( htmlPtr->zBase && htmlPtr->zBase[0] ){ z = Trim(htmlPtr->zBase); } if( z ){ Tcl_DStringAppendElement(&cmd, z); HtmlFree(z); } while( azSeries[0] ){ z = Trim(azSeries[0]); if( z ){ Tcl_DStringAppendElement(&cmd, z); HtmlFree(z); } azSeries++; } HtmlLock(htmlPtr); rc = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( HtmlUnlock(htmlPtr) ) return TCL_ERROR; if( rc!=TCL_OK ){ Tcl_AddErrorInfo(htmlPtr->interp, "\n (-resolvercommand executed by HTML widget)"); } }else{ /* ** No -resolvercommand has been specified. Do the default ** resolver algorithm specified in section 5.2 of RFC 2396. */ HtmlUri *base, *term; if( htmlPtr->zBaseHref && htmlPtr->zBaseHref[0] ){ base = ParseUri(htmlPtr->zBaseHref); }else{ base = ParseUri(htmlPtr->zBase); } while( azSeries[0] ){ term = ParseUri(azSeries[0]); azSeries++; if( term->zScheme==0 && term->zAuthority==0 && term->zPath==0 && term->zQuery==0 && term->zFragment ){ ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zScheme ){ HtmlUri temp; temp = *term; *term = *base; *base = temp; }else if( term->zAuthority ){ ReplaceStr(&base->zAuthority, term->zAuthority); ReplaceStr(&base->zPath, term->zPath); ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zPath && (term->zPath[0]=='/' || base->zPath==0) ){ ReplaceStr(&base->zPath, term->zPath); ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zPath && base->zPath ){ char *zBuf; int i, j; zBuf = HtmlAlloc( strlen(base->zPath) + strlen(term->zPath) + 2 ); if( zBuf ){ sprintf(zBuf,"%s", base->zPath); for(i=strlen(zBuf)-1; i>=0 && zBuf[i]!='/'; i--){ zBuf[i] = 0; } strcat(zBuf, term->zPath); for(i=0; zBuf[i]; i++){ if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='/' ){ strcpy(&zBuf[i+1], &zBuf[i+3]); i--; continue; } if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]==0 ){ zBuf[i+1] = 0; continue; } if( i>0 && zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='.' && (zBuf[i+3]=='/' || zBuf[i+3]==0) ){ for(j=i-1; j>=0 && zBuf[j]!='/'; j--){} if( zBuf[i+3] ){ strcpy(&zBuf[j+1], &zBuf[i+4]); }else{ zBuf[j+1] = 0; } i = j-1; if( i<-1 ) i = -1; continue; } } /* look for /../ at begining */ if (!strncmp(zBuf,"/../",4)) strcpy(zBuf,zBuf+3); HtmlFree(base->zPath); base->zPath = zBuf; } ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); } FreeUri(term); } Tcl_SetResult(htmlPtr->interp, BuildUri(base), TCL_DYNAMIC); FreeUri(base); } return rc; } /* ** This is a convenient wrapper routine for HtmlCallResolver. ** It makes a copy of the result into memory obtained from HtmlAlloc() ** and invokes Tcl_ResetResult(). */ char *HtmlResolveUri(HtmlWidget *htmlPtr, char *zUri){ char *azSeq[2]; char *zSrc; int result; if( zUri==0 || *zUri==0 ) return 0; azSeq[0] = zUri; azSeq[1] = 0; HtmlLock(htmlPtr); result = HtmlCallResolver(htmlPtr, azSeq); if( HtmlUnlock(htmlPtr) ) return 0; if( result==TCL_OK ){ zSrc = HtmlAlloc( strlen(htmlPtr->interp->result) + 1 ); if( zSrc ) strcpy(zSrc, htmlPtr->interp->result); }else{ zSrc = 0; } Tcl_ResetResult(htmlPtr->interp); return zSrc; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/�����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013655� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/hv.tcl�����������������������������������������������������������������������0000644�0001750�0001750�00000020616�07504443344�015025� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # This script implements the "hv" application. Type "hv FILE" to # view FILE as HTML. # # This application is used for testing the HTML widget. It can # also server as an example of how to use the HTML widget. # # @(#) $Id: hv.tcl,v 1.1.1.1 2002/06/20 21:19:32 joye Exp $ # wm title . {HTML File Viewer} wm iconname . {HV} # Make sure the html widget is loaded into # our interpreter # if {[info command html]==""} { if {![package require tkhtml]} return foreach f { ./tkhtml.so /usr/lib/tkhtml.so /usr/local/lib/tkhtml.so ./tkhtml.dll } { if {[file exists $f]} { if {[catch {load $f Tkhtml}]==0} break } } } # The HtmlTraceMask only works if the widget was compiled with # the -DDEBUG=1 command-line option. "file" is the name of the # first HTML file to be loaded. # set HtmlTraceMask 0 set file {} foreach a $argv { if {[regexp {^debug=} $a]} { scan $a "debug=0x%x" HtmlTraceMask } else { set file $a } } # These images are used in place of GIFs or of form elements # image create photo biggray -data { R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm 6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO/// } image create photo smgray -data { R0lGODdhOAAYAPAAALi4uAAAACwAAAAAOAAYAAACI4SPqcvtD6OctNqLs968+w+G4kiW5omm 6sq27gvH8kzX9m0VADv/ } image create photo nogifbig -data { R0lGODdhJAAkAPEAAACQkADQ0PgAAAAAACwAAAAAJAAkAAACmISPqcsQD6OcdJqKM71PeK15 AsSJH0iZY1CqqKSurfsGsex08XuTuU7L9HywHWZILAaVJssvgoREk5PolFo1XrHZ29IZ8oo0 HKEYVDYbyc/jFhz2otvdcyZdF68qeKh2DZd3AtS0QWcDSDgWKJXY+MXS9qY4+JA2+Vho+YPp FzSjiTIEWslDQ1rDhPOY2sXVOgeb2kBbu1AAADv/ } image create photo nogifsm -data { R0lGODdhEAAQAPEAAACQkADQ0PgAAAAAACwAAAAAEAAQAAACNISPacHtD4IQz80QJ60as25d 3idKZdR0IIOm2ta0Lhw/Lz2S1JqvK8ozbTKlEIVYceWSjwIAO/// } # Construct the main window # frame .mbar -bd 2 -relief raised pack .mbar -side top -fill x menubutton .mbar.file -text File -underline 0 -menu .mbar.file.m pack .mbar.file -side left -padx 5 set m [menu .mbar.file.m] $m add command -label Open -underline 0 -command Load $m add command -label Refresh -underline 0 -command Refresh $m add separator $m add command -label Exit -underline 1 -command exit menubutton .mbar.view -text View -underline 0 -menu .mbar.view.m pack .mbar.view -side left -padx 5 set m [menu .mbar.view.m] set underlineHyper 0 $m add checkbutton -label {Underline Hyperlinks} -variable underlineHyper trace variable underlineHyper w ChangeUnderline proc ChangeUnderline args { global underlineHyper .h.h config -underlinehyperlinks $underlineHyper } set showTableStruct 0 $m add checkbutton -label {Show Table Structure} -variable showTableStruct trace variable showTableStruct w ShowTableStruct proc ShowTableStruct args { global showTableStruct HtmlTraceMask if {$showTableStruct} { set HtmlTraceMask [expr {$HtmlTraceMask|0x8}] .h.h config -tablerelief flat } else { set HtmlTraceMask [expr {$HtmlTraceMask&~0x8}] .h.h config -tablerelief raised } Refresh } set showImages 1 $m add checkbutton -label {Show Images} -variable showImages trace variable showImages w Refresh # Construct the main HTML viewer # frame .h pack .h -side top -fill both -expand 1 html .h.h \ -yscrollcommand {.h.vsb set} \ -xscrollcommand {.f2.hsb set} \ -padx 5 \ -pady 9 \ -formcommand FormCmd \ -imagecommand ImageCmd \ -scriptcommand ScriptCmd \ -appletcommand AppletCmd \ -underlinehyperlinks 0 \ -bg white -tablerelief raised # If the tracemask is not 0, then draw the outline of all # tables as a blank line, not a 3D relief. # if {$HtmlTraceMask} { .h.h config -tablerelief flat } # A font chooser routine. # # .h.h config -fontcommand pickFont proc pickFont {size attrs} { puts "FontCmd: $size $attrs" set a [expr {-1<[lsearch $attrs fixed]?{courier}:{charter}}] set b [expr {-1<[lsearch $attrs italic]?{italic}:{roman}}] set c [expr {-1<[lsearch $attrs bold]?{bold}:{normal}}] set d [expr {int(12*pow(1.2,$size-4))}] list $a $d $b $c } # This routine is called for each form element # proc FormCmd {n cmd args} { # puts "FormCmd: $n $cmd $args" switch $cmd { select - textarea - input { set w [lindex $args 0] label $w -image nogifsm } } } # This routine is called for every <IMG> markup # # proc ImageCmd {args} { # puts "image: $args" # set fn [lindex $args 0] # if {[catch {image create photo -file $fn} img]} { # return nogifsm # } else { # global Images # set Images($img) 1 # return $img # } #} proc ImageCmd {args} { global OldImages Images showImages if {!$showImages} { return smgray } set fn [lindex $args 0] if {[info exists OldImages($fn)]} { set Images($fn) $OldImages($fn) unset OldImages($fn) return $Images($fn) } if {[catch {image create photo -file $fn} img]} { return smgray } if {[image width $img]*[image height $img]>20000} { global BigImages set b [image create photo -width [image width $img] \ -height [image height $img]] set BigImages($b) $img set img $b after idle "MoveBigImage $b" } set Images($fn) $img return $img } proc MoveBigImage b { global BigImages if {![info exists BigImages($b)]} return $b copy $BigImages($b) image delete $BigImages($b) unset BigImages($b) update } # This routine is called for every <SCRIPT> markup # proc ScriptCmd {args} { # puts "ScriptCmd: $args" } # This routine is called for every <APPLET> markup # proc AppletCmd {w arglist} { # puts "AppletCmd: w=$w arglist=$arglist" label $w -text "The Applet $w" -bd 2 -relief raised } # This procedure is called when the user clicks on a hyperlink. # See the "bind .h.h.x" below for the binding that invokes this # procedure # proc HrefBinding {x y} { set new [.h.h href $x $y] # puts "link to [list $new]"; return if {$new!=""} { global LastFile set pattern $LastFile# set len [string length $pattern] incr len -1 if {[string range $new 0 $len]==$pattern} { incr len .h.h yview [string range $new $len end] } else { LoadFile $new } } } bind .h.h.x <1> {HrefBinding %x %y} # Pack the HTML widget into the main screen. # pack .h.h -side left -fill both -expand 1 scrollbar .h.vsb -orient vertical -command {.h.h yview} pack .h.vsb -side left -fill y frame .f2 pack .f2 -side top -fill x frame .f2.sp -width [winfo reqwidth .h.vsb] -bd 2 -relief raised pack .f2.sp -side right -fill y scrollbar .f2.hsb -orient horizontal -command {.h.h xview} pack .f2.hsb -side top -fill x # This procedure is called when the user selects the File/Open # menu option. # set lastDir [pwd] proc Load {} { set filetypes { {{Html Files} {.html .htm}} {{All Files} *} } global lastDir htmltext set f [tk_getOpenFile -initialdir $lastDir -filetypes $filetypes] if {$f!=""} { LoadFile $f set lastDir [file dirname $f] } } # Clear the screen. # # Clear the screen. # proc Clear {} { global Images OldImages hotkey if {[winfo exists .fs.h]} {set w .fs.h} {set w .h.h} $w clear catch {unset hotkey} ClearBigImages ClearOldImages foreach fn [array names Images] { set OldImages($fn) $Images($fn) } catch {unset Images} } proc ClearOldImages {} { global OldImages foreach fn [array names OldImages] { image delete $OldImages($fn) } catch {unset OldImages} } proc ClearBigImages {} { global BigImages foreach b [array names BigImages] { image delete $BigImages($b) } catch {unset BigImages} } # Read a file # proc ReadFile {name} { if {[catch {open $name r} fp]} { tk_messageBox -icon error -message $fp -type ok return {} } else { fconfigure $fp -translation binary set r [read $fp [file size $name]] close $fp return $r } } # Load a file into the HTML widget # proc LoadFile {name} { set html [ReadFile $name] if {$html==""} return Clear global LastFile set LastFile $name .h.h config -base $name .h.h parse $html ClearOldImages } # Refresh the current file. # proc Refresh {args} { global LastFile if {![info exists LastFile]} return LoadFile $LastFile } # If an arguent was specified, read it into the HTML widget. # update if {$file!=""} { LoadFile $file } # This binding changes the cursor when the mouse move over # top of a hyperlink. # bind HtmlClip <Motion> { set parent [winfo parent %W] set url [$parent href %x %y] if {[string length $url] > 0} { $parent configure -cursor hand2 } else { $parent configure -cursor {} } } ������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/ssinit.c���������������������������������������������������������������������0000644�0001750�0001750�00000000215�07504443345�015353� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <tcl.h> #include "ss.h" int Et_AppInit(Tcl_Interp *interp){ extern int Tkhtml_Init(Tcl_Interp*); return Tkhtml_Init(interp); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/nogifsm.gif������������������������������������������������������������������0000644�0001750�0001750�00000000133�07504443344�016025� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ñ����ÐÐø�����,�������4„iÁí‚ÏÍ'­³n]Þ'JeÔt ƒ¦ÚÖ´.?/=’Ôš¯+Ê3m2¥…Xqå’�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/nogif.fig��������������������������������������������������������������������0000644�0001750�0001750�00000000766�07504443344�015501� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#FIG 3.2 Landscape Center Inches Letter 100.00 Single -2 1200 2 2 2 0 1 15 17 100 0 20 0.000 0 0 -1 0 0 5 2400 1800 2925 1800 2925 2325 2400 2325 2400 1800 2 1 0 5 4 7 100 0 -1 0.000 0 1 -1 0 0 2 2475 1875 2850 2250 2 1 0 5 4 7 100 0 -1 0.000 0 1 -1 0 0 2 2475 2250 2850 1875 2 2 0 1 15 17 100 0 20 0.000 0 1 -1 0 0 5 3675 2100 3900 2100 3900 2325 3675 2325 3675 2100 2 1 0 3 4 7 100 0 -1 0.000 0 1 -1 0 0 2 3717 2141 3856 2284 2 1 0 3 4 7 100 0 -1 0.000 0 1 -1 0 0 2 3714 2287 3856 2137 ����������./saods9/htmlwidget/hv/ss.tcl�����������������������������������������������������������������������0000644�0001750�0001750�00000022540�07504443344�015033� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# @(#) $Id: ss.tcl,v 1.1.1.1 2002/06/20 21:19:32 joye Exp $ # # This script implements the "ss" application. "ss" implements # a presentation slide-show based on HTML slides. # wm title . {Tk Slide Show} wm iconname . {SlideShow} # Attempt to load the HTML widget if it isn't already part # of the interpreter # if {[info command html]==""} { foreach f { ./tkhtml.so /usr/lib/tkhtml.so /usr/local/lib/tkhtml.so ./tkhtml.dll } { if {[file exists $f]} { if {[catch {load $f Tkhtml}]==0} break } } } # Pick the initial filename from the command line # set HtmlTraceMask 0 set file {} foreach a $argv { if {[regexp {^debug=} $a]} { scan $a "debug=0x%x" HtmlTraceMask } else { set file $a } } # These are images to use with the actual image specified in a # "<img>" markup can't be found. # image create photo biggray -data { R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm 6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO/// } image create photo smgray -data { R0lGODdhOAAYAPAAALi4uAAAACwAAAAAOAAYAAACI4SPqcvtD6OctNqLs968+w+G4kiW5omm 6sq27gvH8kzX9m0VADv/ } # Build the half-size view of the page # frame .mbar -bd 2 -relief raised pack .mbar -side top -fill x menubutton .mbar.help -text File -underline 0 -menu .mbar.help.m pack .mbar.help -side left -padx 5 set m [menu .mbar.help.m] $m add command -label Open -underline 0 -command Load $m add command -label {Full Screen} -underline 0 -command FullScreen $m add command -label Refresh -underline 0 -command Refresh $m add separator $m add command -label Exit -underline 1 -command exit frame .h pack .h -side top -fill both -expand 1 html .h.h \ -width 512 -height 384 \ -yscrollcommand {.h.vsb set} \ -xscrollcommand {.f2.hsb set} \ -padx 5 \ -pady 9 \ -formcommand FormCmd \ -imagecommand "ImageCmd 1" \ -scriptcommand ScriptCmd \ -appletcommand AppletCmd \ -hyperlinkcommand HyperCmd \ -fontcommand pickFont \ -appletcommand {runApplet small} \ -bg white -tablerelief raised .h.h token handler meta "Meta .h.h" if {$HtmlTraceMask} { .h.h config -tablerelief flat } # This routine is called to pick fonts for the half-size window. # proc pickFont {size attrs} { # puts "FontCmd: $size $attrs" set a [expr {-1<[lsearch $attrs fixed]?{courier}:{charter}}] set b [expr {-1<[lsearch $attrs italic]?{italic}:{roman}}] set c [expr {-1<[lsearch $attrs bold]?{bold}:{normal}}] set d [expr {int(12*pow(1.2,$size-4))}] list $a $d $b $c } # This routine is called to pick fonts for the fullscreen view. # set baseFontSize 24 proc pickFontFS {size attrs} { # puts "FontCmd: $size $attrs" set a [expr {-1<[lsearch $attrs fixed]?{courier}:{charter}}] set b [expr {-1<[lsearch $attrs italic]?{italic}:{roman}}] set c [expr {-1<[lsearch $attrs bold]?{bold}:{normal}}] global baseFontSize set d [expr {int($baseFontSize*pow(1.2,$size-4))}] list $a $d $b $c } proc HyperCmd {args} { # puts "HyperlinkCommand: $args" } # This routine is called to run an applet # proc runApplet {size w arglist} { global AppletArg catch {unset AppletArg} foreach {name value} $arglist { set AppletArg([string tolower $name]) $value } if {![info exists AppletArg(src)]} return set src [.h.h resolve $AppletArg(src)] set AppletArg(window) $w set AppletArg(fontsize) $size if {[catch {uplevel #0 "source $src"} msg]} { puts "Applet error: $msg" } } proc FormCmd {n cmd args} { # puts "FormCmd: $n $cmd $args" # switch $cmd { # select - # textarea - # input { # set w [lindex $args 0] # label $w -image smgray # } # } } proc ImageCmd {hs args} { global OldImages Images set fn [lindex $args 0] if {[info exists OldImages($fn)]} { set Images($fn) $OldImages($fn) unset OldImages($fn) return $Images($fn) } if {[catch {image create photo -file $fn} img]} { if {$hs} { return smallgray } else { return biggray } } if {$hs} { set img2 [image create photo] $img2 copy $img -subsample 2 2 image delete $img set img $img2 } if {[image width $img]*[image height $img]>20000} { global BigImages set b [image create photo -width [image width $img] \ -height [image height $img]] set BigImages($b) $img set img $b after idle "MoveBigImage $b" } set Images($fn) $img return $img } proc MoveBigImage b { global BigImages if {![info exists BigImages($b)]} return $b copy $BigImages($b) image delete $BigImages($b) unset BigImages($b) } proc ScriptCmd {args} { # puts "ScriptCmd: $args" } proc AppletCmd {w arglist} { # puts "AppletCmd: w=$w arglist=$arglist" # label $w -text "The Applet $w" -bd 2 -relief raised } # This binding fires when there is a click on a hyperlink # proc HrefBinding {w x y} { set new [$w href $x $y] # puts "link to [list $new]"; if {$new!=""} { ProcessUrl $new } } bind HtmlClip <1> {KeyPress %W Down} bind HtmlClip <3> {KeyPress %W Up} bind HtmlClip <2> {KeyPress %w Down} # Clicking button three on the small screen causes the full-screen view # to appear. # # bind .h.h.x <3> FullScreen # Handle all keypress events on the screen # bind HtmlClip <KeyPress> {KeyPress %W %K} proc KeyPress {w keysym} { global hotkey key_block if {[info exists key_block]} return set key_block 1 after 250 {catch {unset key_block}} if {[info exists hotkey($keysym)]} { ProcessUrl $hotkey($keysym) } switch -- $keysym { Escape { if {[winfo exists .fs]} {FullScreenOff} {FullScreen} } } } # Finish building the half-size screen # pack .h.h -side left -fill both -expand 1 scrollbar .h.vsb -orient vertical -command {.h.h yview} pack .h.vsb -side left -fill y frame .f2 pack .f2 -side top -fill x frame .f2.sp -width [winfo reqwidth .h.vsb] -bd 2 -relief raised pack .f2.sp -side right -fill y scrollbar .f2.hsb -orient horizontal -command {.h.h xview} pack .f2.hsb -side top -fill x #proc FontCmd {args} { # puts "FontCmd: $args" # return {Times 12} #} #proc ResolverCmd {args} { # puts "Resolver: $args" # return [lindex $args 0] #} set lastDir [pwd] proc Load {} { set filetypes { {{Html Files} {.html .htm}} {{All Files} *} } global lastDir htmltext set f [tk_getOpenFile -initialdir $lastDir -filetypes $filetypes] if {$f!=""} { LoadFile $f set lastDir [file dirname $f] } } # Clear the screen. # proc Clear {} { global Images OldImages hotkey if {[winfo exists .fs.h]} {set w .fs.h} {set w .h.h} $w clear catch {unset hotkey} ClearBigImages ClearOldImages foreach fn [array names Images] { set OldImages($fn) $Images($fn) } catch {unset Images} } proc ClearOldImages {} { global OldImages foreach fn [array names OldImages] { image delete $OldImages($fn) } catch {unset OldImages} } proc ClearBigImages {} { global BigImages foreach b [array names BigImages] { image delete $BigImages($b) } catch {unset BigImages} } # Read a file # proc ReadFile {name} { if {[catch {open $name r} fp]} { tk_messageBox -icon error -message $fp -type ok return {} } else { set r [read $fp [file size $name]] close $fp return $r } } # Process the given URL # proc ProcessUrl {url} { switch -glob -- $url { file:* { LoadFile [string range $url 5 end] } exec:* { regsub -all \\+ [string range $url 5 end] { } url eval exec $url & } default { LoadFile $url } } } # Load a file into the HTML widget # proc LoadFile {name} { set html [ReadFile $name] if {$html==""} return Clear global LastFile set LastFile $name if {[winfo exists .fs.h]} {set w .fs.h} {set w .h.h} $w config -base $name -cursor watch $w parse $html $w config -cursor top_left_arrow ClearOldImages } # Refresh the current file. # proc Refresh {} { global LastFile if {![info exists LastFile]} return LoadFile $LastFile } # This routine is called whenever a "<meta>" markup is seen. # proc Meta {w tag alist} { foreach {name value} $alist { set v($name) $value } if {[info exists v(key)] && [info exists v(href)]} { global hotkey set hotkey($v(key)) [$w resolve $v(href)] } if {[info exists v(next)]} { global hotkey set hotkey(Down) $v(next) } if {[info exists v(prev)]} { global hotkey set hotkey(Up) $v(next) } if {[info exists v(other)]} { global hotkey set hotkey(o) $v(other) } } # Go from full-screen mode back to window mode. # proc FullScreenOff {} { destroy .fs wm deiconify . update raise . focus .h.h.x Clear ClearOldImages Refresh } # Go from window mode to full-screen mode. # proc FullScreen {} { if {[winfo exists .fs]} { wm deiconify .fs update raise .fs return } toplevel .fs wm overrideredirect .fs 1 set w [winfo screenwidth .] set h [winfo screenheight .] wm geometry .fs ${w}x$h+0+0 # bind .fs <3> FullScreenOff html .fs.h \ -padx 5 \ -pady 9 \ -formcommand FormCmd \ -imagecommand "ImageCmd 0" \ -scriptcommand ScriptCmd \ -appletcommand AppletCmd \ -hyperlinkcommand HyperCmd \ -bg white -tablerelief raised \ -appletcommand {runApplet big} \ -fontcommand pickFontFS \ -cursor tcross pack .fs.h -fill both -expand 1 .fs.h token handler meta "Meta .fs.h" Clear ClearOldImages Refresh update focus .fs.h.x } focus .h.h.x # Load the file named on the command-line, if there is # one. # update if {$file!=""} { LoadFile $file } ����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/nogif.gif��������������������������������������������������������������������0000644�0001750�0001750�00000000277�07504443344�015476� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a$�$�ñ����ÐÐø�����,����$�$��˜„©Ë£œtšŠ3½Ox­yĉH™cPª¨¤®­û±ìtñ{“¹NËô|°fH,•&Ë/‚„D““è”Z5^±ÙÛÒòŠ4¡T6ÉÏãö¢ÛÝs&]¯*x¨v —wÔ´AgH8(•ØøÅÒö¦8ø6ùXhùƒé4£‰2ZÉCCZÄó˜ÚÅÕ:›Ú@[»P��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/hv/hvinit.c���������������������������������������������������������������������0000644�0001750�0001750�00000000215�07504443344�015342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <tcl.h> #include "hv.h" int Et_AppInit(Tcl_Interp *interp){ extern int Tkhtml_Init(Tcl_Interp*); return Tkhtml_Init(interp); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/mkdll.sh������������������������������������������������������������������������0000755�0001750�0001750�00000002244�07504443344�014726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # This script builds "tkhtml.dll" for Win95/NT and Tcl/Tk8.1.1-stubs. # First do "make srcdir; cd srcdir". Then run this script. # # Notes: # # The tclstub.o and tkstub.o files were obtained by compiling the # tclStubLib.c and tkStubLib.c files from the Tk8.1.1 distribution # using cygwin/mingw. Do not use the tclstub81.lib and tkstub81.lib # files that come with Tcl/Tk from scripts. They won't work. # # $Revision: 1.1.1.1 $ # LIBHOME=/home/drh/tcltk/win32/lib TCLBASE=/home/drh/tcltk/tcl8.2.3 TKBASE=/home/drh/tcltk/tk8.2.3 TKLIB="$LIBHOME/tkstub82.a" TCLLIB="$LIBHOME/tclstub82.a" PATH=$PATH:/opt/cygwin20/bin CC='i586-cygwin32-gcc -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS -mno-cygwin -O2' INC="-I. -I$TCLBASE/generic -I$TKBASE/generic" CMD="rm *.o" echo $CMD $CMD for i in *.c; do CMD="$CC $INC -c $i" echo $CMD $CMD done echo 'EXPORTS' >tkhtml.def echo 'Tkhtml_Init' >>tkhtml.def CMD="i586-cygwin32-dllwrap \ --def tkhtml.def -v --export-all \ --driver-name i586-cygwin32-gcc \ --dlltool-name i586-cygwin32-dlltool \ --as i586-cygwin32-as \ --target i386-mingw32 -mno-cygwin \ -dllname tkhtml.dll *.o $TKLIB $TCLLIB" echo $CMD $CMD ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/makemake.tcl.in�����������������������������������������������������������������0000644�0001750�0001750�00000034074�10334236560�016151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This tcl script generates a makefile suitable for programs that # use the Tcl/Tk library. # # This script begins life as "makemake.tcl.in". A "configure" # shell script will read "makemake.tcl.in" and generate # "makemake.tcl". The makemake.tcl script then runs to # produce the makefile. # # Both this script and the "configure.in" script are general purpose # and can be easily adapted to many different projects. The # "configure.in" script will require little or not customization. # (Prehaps comment out the BLT part if you are not using BLT.) # This script requires some customization down toward the bottom. # # $Revision: 1.8 $ # # Some useful variables. # set SHLIB [list @ENABLE_SHLIB@] set TOP [list @srcdir@] set BTCLSH [list @BUILD_TCLSH@] set BEXE [list @BUILD_EXEEXT@] set TEXE [list @TARGET_EXEEXT@] set PFX [list @program_prefix@] set prefix [list @prefix@] set exec_prefix [list @exec_prefix@] set BINDIR [list @bindir@] set LIBDIR [file join @libdir@ Tkhtml] # Remove surplus ".." and "." elements from a pathname. # proc CleanPath path { regsub -all {/\./} $path / path while {[regsub -all {[^/]*[^/.]/\.\./} $path {} path]} {} return $path } # This procedure returns a pathname relative to the directory # we are compiling in, for a file whose name is relative to the # top of the source directory. # # Example: If the source tree is at /home/src/progZ and we # are compiling in /home/tmp/progZ, then # # Src src/file1.c # # returns # # ../../src/progZ/src/file1.c # proc Src rel { if {[file pathtype $rel]=="relative"} { set result [CleanPath @srcdir@/$rel] } else { set result $rel } return $result } # Convert a pathname to an absolute pathname. # proc AbsPath path { switch [file pathtype $path] { absolute { set path [CleanPath $path] } relative { set path [CleanPath [pwd]/$path] } default { } } return $path } # Remove surplus white-space from the named # variable. # proc Strip varname { upvar 1 $varname v regsub -all "\[ \t\n\r\]\[ \t\n\r\]*" [string trim $v] { } v } # Generate a C program that runs on the host machine. The input # is C source code. This routine is used to build utilities that # are used in the build process. Examples: makeheaders, mktclapp, # help2tk, lemon, etc. # proc MakeTool {name src {libs {}}} { global BEXE set n "${name}$BEXE" puts "$n: $src" puts " @BUILD_CC@ @BUILD_CFLAGS@ -o $n $src $libs" puts "" global cleanable; lappend cleanable $n } # Generate an executable that will run on the target machine. # The inputs are *.o files, *.c files and locally built libraries. # # The optional 3rd argument specifies what Tcl/Tk libraries the # executable should be linked against. The 3rd argument should be # one of the following keywords: "blt", "tk", "tcl". Or it can # be blank. # proc MakeProg {name obj {libs {tk}}} { global TEXE PFX set n "${PFX}${name}$TEXE" switch $libs { tcl { set link "@TARGET_CC@ @TARGET_CFLAGS@ -I. @TARGET_TCL_INC@" append link " @TARGET_X_INC@" set lib "@TARGET_TCL_LIBS@ @TARGET_LIBS@" } tk { set link "@TARGET_CC@ @TARGET_CFLAGS@ -I. @TARGET_TCL_INC@" append link " @TARGET_X_INC@" append link " @TARGET_TK_INC@" set lib "@TARGET_TK_LIBS@ @TARGET_X_LIBS@ @TARGET_TCL_LIBS@ @TARGET_LIBS@" } blt { set link "@TARGET_CC@ @TARGET_CFLAGS@ -I. @TARGET_TCL_INC@" append link " @TARGET_X_INC@" append link " @TARGET_TK_INC@ @TARGET_BLT_INC@" set lib "@TARGET_BLT_LIBS@ @TARGET_TK_LIBS@ @TARGET_TCL_LIBS@" append lib " @TARGET_X_LIBS@ @TARGET_LIBS@" } default { set link "@TARGET_CC@ @TARGET_CFLAGS@ -I." append link " @TARGET_X_INC@" set lib $libs } } puts "$n: $obj" puts " $link -o $n $obj $lib" puts "" global cleanable; lappend cleanable $n global exelist; lappend exelist $n } # Convert C source code into a *.o file that can be used in a # shared library. The optional 3rd argument is a list of extra # dependencies for this target. # # An "sh" prefix is added to the generated *.o file. # proc MakeShObj {name src {dep {}}} { if {"@ENABLE_SHLIB@"!=1} return set n sh$name set cc "@TARGET_CC@ @TARGET_SHLIB_CFLAGS@ -I. @TARGET_TCL_INC@" append cc " @TARGET_X_INC@" append cc " @TARGET_TK_INC@ @TARGET_BLT_INC@" puts "$n: $src $dep" puts " $cc -o $n -c $src" puts "" global cleanable; lappend cleanable $n } # Generate a shared library from *.o files that were prepared using # the MakeShObj function above. # # The optional 3rd argument specifies what Tcl/Tk libraries the # shared library should be linked against. The 3rd argument should # be one of the following keywords: "blt", "tk", "tcl". Or it can # be blank. # proc MakeShLib {name obj {libs tk}} { if {"@ENABLE_SHLIB@"!=1} return set n "$name@TARGET_SHLIB_EXT@" set link {@TARGET_SHLIB_LINK@} switch $libs { tcl { set lib "@TARGET_TCL_LIBS@ @TARGET_LIBS@" } tk { set lib "@TARGET_TK_LIBS@ @TARGET_X_LIBS@ @TARGET_TCL_LIBS@ @TARGET_LIBS@" } blt { set lib "@TARGET_BLT_LIBS@ @TARGET_TK_LIBS@ @TARGET_TCL_LIBS@" append lib " @TARGET_X_LIBS@ @TARGET_LIBS@" } } set shobj {} foreach f $obj { lappend shobj sh$f } puts "$n: $shobj" puts " $link -o $n $shobj $lib" puts "" global cleanable; lappend cleanable $n } # Convert C source code into a *.o file that can be used in a # static library. # proc MakeObj {name src {dep {}}} { set n $name set cc "@TARGET_CC@ @TARGET_CFLAGS@ -I. @TARGET_TCL_INC@" append cc " @TARGET_X_INC@" append cc " @TARGET_TK_INC@ @TARGET_BLT_INC@" puts "$n: $src $dep" puts " $cc -o $n -c $src" puts "" global cleanable; lappend cleanable $n } # Generate a static library from *.o files that were prepared using # the MakeObj function above. # proc MakeLib {name obj} { set n $name.a puts "$n: $obj" puts " @TARGET_AR@ $n $obj" set ranlib [list @TARGET_RANLIB@] if {[string length $ranlib]>0} { puts " $ranlib $n" } puts "" global cleanable; lappend cleanable $n } # Generate rules for a *.mta file, a *.h file and a *.c file for the # given application initialization file. Here are the parameters: # # name The base name of the generated files. The following # files will be generated: # ${name}.mta # ${name}.c # ${name}.h # ${name}.o # ${name}dev.mta # ${name}dev.c # ${name}dev.h # ${name}dev.o # # main The name of the main TCL script. May be {} # # alltcl The names of all TCL scripts. # # allc The names of all C source files that mktclapp needs to # read to discover ET_COMMAND_ and Et_AppInit functions. # # mode Either of two keywords: "tcl" or "tk". # # options Any additional options to pass to mktclapp. Example: -console # proc MakeMta {name main alltcl allc mode options} { global cleanable BEXE set n ${name}dev.mta puts "$n: " puts " echo ' -tcl-library @TARGET_TCL_SCRIPT_DIR@' >$n" if {$mode=="tk"} { puts " echo ' -tk-library @TARGET_TK_SCRIPT_DIR@' >>$n" } if {$main!=""} { puts " echo ' -main-script $main' >>$n" } if {$options!=""} { puts " echo ' $options' >>$n" } puts " echo ' $allc' >>$n" puts "" lappend cleanable $n puts "${name}dev.c: $n mktclapp$BEXE" puts " ./mktclapp$BEXE -f $n >${name}dev.c" puts "" lappend cleanable ${name}dev.c puts "${name}dev.h: mktclapp$BEXE" puts " ./mktclapp$BEXE -header >${name}dev.h" puts "" lappend cleanable ${name}dev.h MakeObj ${name}dev.o ${name}dev.c set n ${name}.mta puts "$n: ${name}dev.mta" puts " cat ${name}dev.mta >$n" puts " echo ' $alltcl' >>$n" puts " echo @TARGET_TCL_SCRIPT_DIR@/*.tcl >>$n" puts " echo '@TARGET_TCL_SCRIPT_DIR@/tclIndex' >>$n" if {$mode=="tk"} { puts " echo @TARGET_TK_SCRIPT_DIR@/*.tcl >>$n" puts " echo '@TARGET_TK_SCRIPT_DIR@/tclIndex' >>$n" } puts "" lappend cleanable $n puts "$name.c: $n $allc $alltcl mktclapp$BEXE" puts " ./mktclapp$BEXE -f $n >$name.c" puts "" lappend cleanable $name.c puts "$name.h: ${name}dev.h" puts " cp ${name}dev.h $name.h" puts "" lappend cleanable $name.h MakeObj $name.o $name.c } # Write an introduction to the generated makefile. # puts "# Automatically generated by makemake.tcl" puts "# Do Not Edit!" puts "" puts ".NOTPARALLEL :" ############################################################################# # CUSTOMIZE BELOW THIS LINE # # The stuff the follows is specific to each individual project and # should be customized. Edit below this line. Do not edit above # this line. # # Put the basename of each C source code modules # here. Omit the ".c" suffix. # set srcc { src/htmlcmd src/htmldraw src/htmlform src/htmlimage src/htmlindex src/htmllayout src/htmlparse src/htmlsizer src/htmltable src/htmltest src/htmlurl src/htmlwidget src/htmlexts } # Put the names of all TCL source files here. Include the ".tcl" # suffix. # set srctcl { } # Put here the basenames of all C code modules that are # generated by helper programs or/and automated scripts. These # files are C code but they are not source code. # Omit the ".c" suffix. # set autoc { htmltokens } # Put here the names of all TCL code modules that are # generated by helper programs and/or scripts. Include the # ".tcl" suffix. # set autotcl { } # Remove surplus whitespace from the lists of files defined above. # Strip srcc Strip srctcl Strip autoc Strip autotcl # A target to build everything. # set all ${PFX}hwish${TEXE} lappend all ${PFX}hv${TEXE} lappend all ${PFX}ss${TEXE} if {"@ENABLE_SHLIB@"=="1"} { lappend all tkhtml@TARGET_SHLIB_EXT@ # lappend all tkhtml.so lappend all pkgIndex.tcl } puts "all: headers $all" puts "" # Compile host-side utilities # MakeTool makeheaders [Src tools/makeheaders.c] MakeTool mktclapp [Src tools/mktclapp.c] # Generate the htmltokens.c file # puts "htmltokens.c: [Src src/tokenlist.txt] [Src tools/maketokens.tcl]" if {$BEXE == ".exe"} { puts "\t$BTCLSH \'[exec cygpath -w [Src tools/maketokens.tcl]]\' \'[exec cygpath -w [Src src/tokenlist.txt]]\' >htmltokens.c" } else { puts "\t$BTCLSH [Src tools/maketokens.tcl] [Src src/tokenlist.txt] >htmltokens.c" } puts "" lappend cleanable htmltokens.c # Generate the pkgIndex.tcl file # puts "pkgIndex.tcl: tkhtml@TARGET_SHLIB_EXT@" #puts "pkgIndex.tcl: tkhtml.so" puts "\techo 'pkg_mkIndex . tkhtml.@TARGET_SHLIB_EXT@' | $BTCLSH" #puts "\techo 'pkg_mkIndex . tkhtml.so' | $BTCLSH" puts "" lappend cleanable pkgIndex.tcl # The main library # set obj {} set shobj {} foreach f $srcc { set m [file tail $f] lappend obj $m.o MakeObj $m.o [Src $f.c] $m.h MakeShObj $m.o [Src $f.c] $m.h } foreach f $autoc { lappend obj $f.o MakeObj $f.o $f.c $f.h MakeShObj $f.o $f.c $f.h } MakeLib libtkhtml $obj MakeShLib tkhtml $obj # Header files for the library objects and for the library itself. # set mharg {} foreach f $srcc { set m [file tail $f] lappend mharg [Src $f.c]:$m.h lappend cleanable $m.h } foreach f $autoc { lappend mharg $f.c lappend cleanable $f.h } puts "headers: makeheaders$BEXE htmltokens.c" puts " ./makeheaders$BEXE $mharg [Src src/html.h]" puts "" puts "[lindex $srcc 0].h: headers" puts "" # The install routine for the shared library # puts "install-lib: pkgIndex.tcl" puts " if test ! -d $LIBDIR; then mkdir $LIBDIR; fi" puts " cp tkhtml@TARGET_SHLIB_EXT@ $LIBDIR" #puts " cp tkhtml.so $LIBDIR" puts " cp pkgIndex.tcl $LIBDIR" puts "" # Create two MTA files for appinit.c and appinitdev.c. The first # has all scripts compiled in and the second does not. The first # is suitable for shipping as a standalone executable and the # second is designed for testing. # set alltcl {} foreach f [concat $srctcl $autotcl] { lappend alltcl $f } if {$TEXE==".exe"} { set options {-console} } else { set options {-read-stdin} } MakeMta appinit [lindex $srctcl 0] $alltcl [Src src/htmlwish.c] tk $options # Now generate hwish and hwishdev # MakeObj htmlwish.o [Src src/htmlwish.c] appinit.h MakeProg hwish "htmlwish.o appinit.o libtkhtml.a" tk MakeProg hwishdev "htmlwish.o appinitdev.o libtkhtml.a" tk # Generate the "hv" application. # MakeMta hv [Src hv/hv.tcl] [Src hv/hv.tcl] [Src hv/hvinit.c] tk {} MakeObj hvinit.o [Src hv/hvinit.c] hv.h MakeProg hv "hv.o hvinit.o libtkhtml.a" tk MakeProg hvdev "hvdev.o hvinit.o libtkhtml.a" tk # Generate the "ss" application. # MakeMta ss [Src hv/ss.tcl] [Src hv/ss.tcl] [Src hv/ssinit.c] tk {} MakeObj ssinit.o [Src hv/ssinit.c] ss.h MakeProg ss "ss.o ssinit.o libtkhtml.a" tk MakeProg ssdev "ssdev.o ssinit.o libtkhtml.a" tk # This target makes a directory named "srcdir" and puts all the # source files there. It also generates the headers and # automatically generated source files. # set srclist {} foreach f $srcc { lappend srclist [Src $f.c] } foreach f $autoc { lappend srclist $f.c } puts "srcdir: makeheaders$BEXE $srclist" puts " mkdir srcdir || true" lappend srclist [Src src/html.h] puts " cp $srclist srcdir" puts " cd srcdir; ../makeheaders$BEXE *.\[ch\]" puts "" # Build the "getpage" utility # set srclist {getpage url sgmlparse httpget} set mharg {} set obj {} foreach f $srclist { lappend mharg "[Src tools/$f.c]:$f.h" lappend obj $f.o MakeObj $f.o [Src tools/$f.c] $f.h puts "$f.h: getpage_headers" puts "" } puts "getpage_headers: makeheaders" puts " ./makeheaders $mharg" puts "" MakeProg getpage $obj {} puts "publish: " puts " tclsh [Src webpage/mkwebpage.tcl]" puts " #" puts " # Run \"sh publish.sh\" to send web materials to the website" puts " #" puts "" ############################################################################# # It is not usually necessary to change anything below this line. # # The usual makefile targets... # puts "clean: " puts " rm -f $cleanable" puts " rm -rf srcdir" puts "" puts "distclean: clean" puts " rm -f Makefile makemake.tcl config.cache config.log config.status" puts "" set BINDIR ../install puts "install: all" puts " if test ! -d $BINDIR; then mkdir $BINDIR; fi" puts " for i in $exelist; do cp \$\$i $BINDIR; strip $BINDIR/\$\$i; done" puts "" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/configure�����������������������������������������������������������������������0000755�0001750�0001750�00000265502�11401260671�015172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-hints=FILE Read configuration options from FILE" ac_help="$ac_help --with-tcl=DIR Directory holding Tcl source tree for target" ac_help="$ac_help --with-tk=DIR Directory holding Tk source tree for target" ac_help="$ac_help --enable-shared Build the widget as a shared library" ac_help="$ac_help --with-x use the X Window System" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=src/html.h # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # The following RCS revision string applies to configure.in # $Revision: 1.3 $ ######### # Make sure we are not building in a subdirectory of the source tree. # temp=`echo $srcdir | grep '[^./]'` if test "$temp" = ""; then { echo "configure: error: ************************************************************************** ** This program may not be compiled in the same directory that contains ** ** the configure script or any subdirectory of that directory. Rerun ** ** the configure script from a directory that is separate from the ** ** source tree. ** **************************************************************************" 1>&2; exit 1; } fi ######### # Set up an appropriate program prefix # if test "$program_prefix" = "NONE"; then program_prefix="" fi ######### # Check to see if the --with-hints=FILE option is used. If there is none, # then check for a files named "$host.hints" and ../$hosts.hints where # $host is the hostname of the build system. If still no hints are # found, try looking in $system.hints and ../$system.hints where # $system is the result of uname -s. # # Check whether --with-hints or --without-hints was given. if test "${with_hints+set}" = set; then withval="$with_hints" hints=$withval fi if test "$hints" = ""; then host=`hostname | sed 's/\..*//'` if test -r $host.hints; then hints=$host.hints else if test -r ../$host.hints; then hints=../$host.hints fi fi fi if test "$hints" = ""; then sys=`uname -s` if test -r $sys.hints; then hints=$sys.hints else if test -r ../$sys.hints; then hints=../$sys.hints fi fi fi if test "$hints" != ""; then echo "$ac_t""reading hints from $hints" 1>&6 . $hints fi ######### # Locate a compiler for the build machine. This compiler should # generate command-line programs that run on the build machine. # default_build_cflags="-g" if test "$config_BUILD_CC" = ""; then # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:610: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:640: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:691: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:723: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 734 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:739: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:765: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:770: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:779: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:798: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi if test "$cross_compiling" = "yes"; then { echo "configure: error: unable to find a compiler for building build tools" 1>&2; exit 1; } fi BUILD_CC=$CC default_build_cflags=$CFLAGS else BUILD_CC=$config_BUILD_CC echo $ac_n "checking host compiler""... $ac_c" 1>&6 echo "configure:837: checking host compiler" >&5 CC=$BUILD_CC echo "$ac_t""$BUILD_CC" 1>&6 fi echo $ac_n "checking switches for the host compiler""... $ac_c" 1>&6 echo "configure:842: checking switches for the host compiler" >&5 if test "$config_BUILD_CFLAGS" != ""; then CFLAGS=$config_BUILD_CFLAGS BUILD_CFLAGS=$config_BUILD_CFLAGS else BUILD_CFLAGS=$default_build_cflags fi echo "$ac_t""$BUILD_CFLAGS" 1>&6 if test "$config_BUILD_LIBS" != ""; then BUILD_LIBS=$config_BUILD_LIBS fi ########## # Locate a compiler that converts C code into *.o files that run on # the target machine. # echo $ac_n "checking target compiler""... $ac_c" 1>&6 echo "configure:862: checking target compiler" >&5 if test "$config_TARGET_CC" != ""; then TARGET_CC=$config_TARGET_CC else TARGET_CC=$BUILD_CC fi echo "$ac_t""$TARGET_CC" 1>&6 echo $ac_n "checking switches on the target compiler""... $ac_c" 1>&6 echo "configure:870: checking switches on the target compiler" >&5 if test "$config_TARGET_CFLAGS" != ""; then TARGET_CFLAGS=$config_TARGET_CFLAGS else TARGET_CFLAGS=$BUILD_CFLAGS fi echo "$ac_t""$TARGET_CFLAGS" 1>&6 echo $ac_n "checking target linker""... $ac_c" 1>&6 echo "configure:878: checking target linker" >&5 if test "$config_TARGET_LINK" = ""; then TARGET_LINK=$TARGET_CC else TARGET_LINK=$config_TARGET_LINK fi echo "$ac_t""$TARGET_LINK" 1>&6 echo $ac_n "checking switches on the target compiler""... $ac_c" 1>&6 echo "configure:886: checking switches on the target compiler" >&5 if test "$config_TARGET_TFLAGS" != ""; then TARGET_TFLAGS=$config_TARGET_TFLAGS else TARGET_TFLAGS=$BUILD_CFLAGS fi if test "$config_TARGET_RANLIB" != ""; then TARGET_RANLIB=$config_TARGET_RANLIB else # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:898: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi TARGET_RANLIB=$RANLIB fi if test "$config_TARGET_AR" != ""; then TARGET_RANLIB=$config_TARGET_AR else TARGET_AR='ar cr' fi echo "$ac_t""$TARGET_TFLAGS" 1>&6 # Set the $cross variable if we are cross-compiling. Make # it 0 if we are not. # echo $ac_n "checking if host and target compilers are the same""... $ac_c" 1>&6 echo "configure:944: checking if host and target compilers are the same" >&5 if test "$BUILD_CC" = "$TARGET_CC"; then cross=0 echo "$ac_t""yes" 1>&6 else cross=1 echo "$ac_t""no" 1>&6 fi ########### # Lots of things are different if we are compiling for Windows using # the CYGWIN environment. So check for that special case and handle # things accordingly. # echo $ac_n "checking if executables have the .exe suffix""... $ac_c" 1>&6 echo "configure:959: checking if executables have the .exe suffix" >&5 if test "$config_BUILD_EXEEXT" = ".exe"; then CYGWIN=yes echo "$ac_t""yes" 1>&6 else echo "$ac_t""unknown" 1>&6 fi if test "$CYGWIN" != "yes"; then echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 echo "configure:968: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 973 "configure" #include "confdefs.h" int main() { #ifndef __CYGWIN__ #define __CYGWIN__ __CYGWIN32__ #endif return __CYGWIN__; ; return 0; } EOF if { (eval echo configure:984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_cygwin=no fi rm -f conftest* rm -f conftest* fi echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes fi if test "$CYGWIN" = "yes"; then BUILD_EXEEXT=.exe else BUILD_EXEEXT="" fi if test "$cross" = "0"; then TARGET_EXEEXT=$BUILD_EXEEXT else TARGET_EXEEXT=$config_TARGET_EXEEXT fi if test "$TARGET_EXEEXT" = ".exe"; then OS_UNIX=0 OS_WIN=1 tclsubdir=win else OS_UNIX=1 OS_WIN=0 tclsubdir=unix fi TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=$OS_UNIX -DOS_WIN=$OS_WIN" ######### # Locate a working copy of tclsh. We have to have this program # running on the build platform since the makefiles use it. # # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" : fi if test "$config_WITH_TCL" != ""; then with_tcl=$config_WITH_TCL fi # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" : fi if test "$config_WITH_TK" != ""; then with_tk=$config_WITH_TK fi if test "$config_BUILD_TCLSH" != ""; then echo $ac_n "checking for a working "tclsh"""... $ac_c" 1>&6 echo "configure:1051: checking for a working "tclsh"" >&5 BUILD_TCLSH=$config_BUILD_TCLSH echo "$ac_t""$BUILD_TCLSH" 1>&6 else if test "$with_tcl" != ""; then if test -x "$with_tcl/$tclsubdir/tclsh"; then BUILD_TCLSH=$with_tcl/$tclsubdir/tclsh else if test -x "$with_tcl/$tclsubdir/tclsh8.0"; then BUILD_TCLSH=$with_tcl/$tclsubdir/tclsh8.0 fi fi fi if test "$BUILD_TCLSH" = ""; then for ac_prog in tclsh8.2 tclsh8.1 tclsh81 tclsh8.0 tclsh80 cygtclsh80 tclsh do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1070: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_TCLSH'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$BUILD_TCLSH"; then ac_cv_prog_BUILD_TCLSH="$BUILD_TCLSH" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_BUILD_TCLSH="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi BUILD_TCLSH="$ac_cv_prog_BUILD_TCLSH" if test -n "$BUILD_TCLSH"; then echo "$ac_t""$BUILD_TCLSH" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$BUILD_TCLSH" && break done test -n "$BUILD_TCLSH" || BUILD_TCLSH="""" fi if test "$BUILD_TCLSH" = ""; then { echo "configure: error: no working "tclsh" could be found" 1>&2; exit 1; } fi fi ############### # Check to see if the user wants to build shared libraries. If so, # then locate tclConfig.sh and tkConfig.sh to figure out how. Then # set up variables to short-circuit most of the subsequent tests # since the tclConfig.sh and tkConfig.sh files tell us most of what # we need to know. # # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" : else enable_shared=yes fi if test "$config_ENABLE_SHARED" = "yes"; then enable_shared=yes fi echo $ac_n "checking if shared libraries are requested""... $ac_c" 1>&6 echo "configure:1126: checking if shared libraries are requested" >&5 if test "$enable_shared" = "yes"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$CYGWIN" = "yes"; then if test "$enable_shared" = "yes"; then echo "configure: warning: don't know how to build shared libraries with Cygwin, yet..." 1>&2 enable_shared=no fi fi #if test "$enable_shared" = "yes"; then ok=0 if test "$with_tcl" != ""; then tclconf=$with_tcl/unix/tclConfig.sh ac_safe=`echo "$tclconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tclconf""... $ac_c" 1>&6 echo "configure:1145: checking for $tclconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tclconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi #fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1; else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [file dirname [info library]] {//\1/} out puts -nonewline $out exit EOF dir=`$BUILD_TCLSH <conftest.tcl` tclconf=$dir/tclConfig.sh ac_safe=`echo "$tclconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tclconf""... $ac_c" 1>&6 echo "configure:1179: checking for $tclconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tclconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then tclconf=$dir/unix/tclConfig.sh ac_safe=`echo "$tclconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tclconf""... $ac_c" 1>&6 echo "configure:1207: checking for $tclconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tclconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then tclconf=/usr/local/lib/tclConfig.sh ac_safe=`echo "$tclconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tclconf""... $ac_c" 1>&6 echo "configure:1235: checking for $tclconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tclconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then tclconf=/usr/lib/tclConfig.sh ac_safe=`echo "$tclconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tclconf""... $ac_c" 1>&6 echo "configure:1263: checking for $tclconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tclconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then echo "configure: warning: unable to locate tclConfig.sh. Shared libraries will not be built" 1>&2; enabled_shared=no fi fi #if test "$enable_shared" = "yes"; then ok=0 tkconf=`echo $tclconf | sed 's/tclConfig.sh/tkConfig.sh/'` ac_safe=`echo "$tkconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tkconf""... $ac_c" 1>&6 echo "configure:1297: checking for $tkconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tkconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi #fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi if test "$ok" = "0"; then if test "$with_tk" != ""; then tkconf=$with_tk/unix/tkConfig.sh ac_safe=`echo "$tkconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tkconf""... $ac_c" 1>&6 echo "configure:1325: checking for $tkconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tkconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1; else echo "$ac_t""no" 1>&6 fi fi fi if test "$ok" = "0"; then tkconf=/usr/local/lib/tkConfig.sh ac_safe=`echo "$tkconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tkconf""... $ac_c" 1>&6 echo "configure:1354: checking for $tkconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tkconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then tkconf=/usr/lib/tclConfig.sh ac_safe=`echo "$tkconf" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $tkconf""... $ac_c" 1>&6 echo "configure:1382: checking for $tkconf" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $tkconf; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ok=1 else echo "$ac_t""no" 1>&6 fi fi if test "$ok" = "0"; then echo "configure: warning: unable to locate tkConfig.sh. Shared libraries will not be built" 1>&2; enabled_shared=no fi fi if test "$enable_shared" = "yes"; then ENABLE_SHLIB=1 . $tclconf . $tkconf TARGET_SHLIB_EXT=$TCL_SHLIB_SUFFIX TARGET_SHLIB_CFLAGS="$TCL_SHLIB_CFLAGS $TARGET_CFLAGS" TARGET_SHLIB_LINK="$TCL_SHLIB_LD" TARGET_SHLIB_LIBS="$TCL_SHLIB_LD_LIBS" else ENABLE_SHLIB=0 fi ######### # Locate the directory that contains all of the Tcl initialization # scripts for the target machine. # echo $ac_n "checking Tcl script library""... $ac_c" 1>&6 echo "configure:1432: checking Tcl script library" >&5 if test "$config_TARGET_TCL_SCRIPT_DIR" != ""; then TARGET_TCL_SCRIPT_DIR=$config_TARGET_TCL_SCRIPT_DIR else cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [info library] {//\1/} out puts -nonewline $out exit EOF tcllibdir=`$BUILD_TCLSH <conftest.tcl` rm -f conftest.tcl if test ! -r $tcllibdir/init.tcl; then { echo "configure: error: not found" 1>&2; exit 1; } fi TARGET_TCL_SCRIPT_DIR=$tcllibdir fi echo "$ac_t""$TARGET_TCL_SCRIPT_DIR" 1>&6 ######### # Locate the directory that contains all of the Tk initialization # scripts for the target machine. # echo $ac_n "checking Tk script library""... $ac_c" 1>&6 echo "configure:1456: checking Tk script library" >&5 if test "$config_TARGET_TK_SCRIPT_DIR" != ""; then TARGET_TK_SCRIPT_DIR=$config_TARGET_TK_SCRIPT_DIR else if test "$with_tk" != ""; then tklibdir=$with_tk/library else cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [info library] {//\1/} out regsub {/tcl7.6} $out {tk4.2} out regsub {/tcl([^/]*)} $out {/tk\1} out puts -nonewline $out exit EOF tklibdir=`$BUILD_TCLSH <conftest.tcl` rm -f conftest.tcl fi if test ! -r $tklibdir/tk.tcl; then { echo "configure: error: not found" 1>&2; exit 1; } fi TARGET_TK_SCRIPT_DIR=$tklibdir fi echo "$ac_t""$TARGET_TK_SCRIPT_DIR" 1>&6 ########## # Extract generic linker options from the environment. # if test "$config_TARGET_LIBS" != ""; then TARGET_LIBS=$config_TARGET_LIBS else TARGET_LIBS="" fi ########## # Figure out what C libraries are required to compile Tcl programs. # if test "$config_TARGET_TCL_LIBS" != ""; then TARGET_TCL_LIBS="$config_TARGET_TCL_LIBS" else if test "$with_tcl" != ""; then extra=`echo $with_tcl/$tclsubdir/libtcl8*.a` fi CC=$TARGET_CC echo $ac_n "checking for sin""... $ac_c" 1>&6 echo "configure:1502: checking for sin" >&5 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1507 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else sin(); #endif ; return 0; } EOF if { (eval echo configure:1530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sin=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="" else echo "$ac_t""no" 1>&6 LIBS="-lm" fi echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 echo "configure:1551: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <<EOF #line 1559 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen(); int main() { dlopen() ; return 0; } EOF if { (eval echo configure:1570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-ldl $LIBS" else echo "$ac_t""no" 1>&6 fi otherlibs=$LIBS if test "$extra" != ""; then LIBS=$extra else LIBS="" echo $ac_n "checking for library containing Tcl_Init""... $ac_c" 1>&6 echo "configure:1604: checking for library containing Tcl_Init" >&5 if eval "test \"`echo '$''{'ac_cv_search_Tcl_Init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_func_search_save_LIBS="$LIBS" ac_cv_search_Tcl_Init="no" cat > conftest.$ac_ext <<EOF #line 1611 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tcl_Init(); int main() { Tcl_Init() ; return 0; } EOF if { (eval echo configure:1622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_Tcl_Init="none required" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* test "$ac_cv_search_Tcl_Init" = "no" && for i in tcl8.2 tcl8.1 tcl8.0 tcl80 tcl; do LIBS="-l$i $otherlibs $ac_func_search_save_LIBS" cat > conftest.$ac_ext <<EOF #line 1633 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tcl_Init(); int main() { Tcl_Init() ; return 0; } EOF if { (eval echo configure:1644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_Tcl_Init="-l$i" break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done LIBS="$ac_func_search_save_LIBS" fi echo "$ac_t""$ac_cv_search_Tcl_Init" 1>&6 if test "$ac_cv_search_Tcl_Init" != "no"; then test "$ac_cv_search_Tcl_Init" = "none required" || LIBS="$ac_cv_search_Tcl_Init $LIBS" else : fi fi TARGET_TCL_LIBS="$LIBS $otherlibs" fi ########## # Figure out where to get the TCL header files. # echo $ac_n "checking TCL header files""... $ac_c" 1>&6 echo "configure:1673: checking TCL header files" >&5 found=no if test "$config_TARGET_TCL_INC" != ""; then TARGET_TCL_INC=$config_TARGET_TCL_INC found=yes else if test "$with_tcl" != ""; then TARGET_TCL_INC="-I$with_tcl/generic -I$with_tcl/$tclsubdir" found=yes else TARGET_TCL_INC="" found=no fi fi if test "$found" = "yes"; then echo "$ac_t""$TARGET_TCL_INC" 1>&6 else echo "$ac_t""not specified: still searching..." 1>&6 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1692: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF #line 1707 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1713: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF #line 1724 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext <<EOF #line 1741 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 ac_safe=`echo "tcl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tcl.h""... $ac_c" 1>&6 echo "configure:1773: checking for tcl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1778 "configure" #include "confdefs.h" #include <tcl.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1783: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 fi fi if test "$found" = "no"; then for dir in /usr/local /usr/X11* /usr/pkg /usr/contrib /usr; do n=$dir/include/tcl.h ac_safe=`echo "$dir/include/tcl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $dir/include/tcl.h""... $ac_c" 1>&6 echo "configure:1811: checking for $dir/include/tcl.h" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r $dir/include/tcl.h; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 fi if test "$found" = "yes"; then TARGET_TCL_INC="-I$dir/include" break fi done fi ########### # Figure out what C libraries are required to compile X11 programs. # If the target is windows, we assume the compiler is Cygwin20 and # insert arguments that generate a windows GUI application. # if test "$config_TARGET_X_LIBS" != ""; then TARGET_X_LIBS=$config_TARGET_X_LIBS TARGET_X_INC=$config_TARGET_X_INC else if test $OS_UNIX = 1; then # If we find X, set shell vars x_includes and x_libraries to the # paths, otherwise set no_x=yes. # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 echo "configure:1856: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" : fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=NO ac_x_libraries=NO rm -fr conftestdir if mkdir conftestdir; then cd conftestdir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat > Imakefile <<'EOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' EOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case "$ac_im_incroot" in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; esac case "$ac_im_usrlibdir" in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; esac fi cd .. rm -fr conftestdir fi if test "$ac_x_includes" = NO; then # Guess where to find include files, by looking for this one X11 .h file. test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h # First, try using that file with no special directory specified. cat > conftest.$ac_ext <<EOF #line 1918 "configure" #include "confdefs.h" #include <$x_direct_test_include> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1923: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* # We can compile using X headers with no special include directory. ac_x_includes= else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* # Look for the header file in a standard set of common directories. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in \ /usr/X11/include \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11 \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11/include \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11 \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ \ /usr/include \ /usr/local/include \ /usr/unsupported/include \ /usr/athena/include \ /usr/local/x11r5/include \ /usr/lpp/Xamples/include \ \ /usr/openwin/include \ /usr/openwin/share/include \ ; \ do if test -r "$ac_dir/$x_direct_test_include"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest* fi # $ac_x_includes = NO if test "$ac_x_libraries" = NO; then # Check for the libraries. test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <<EOF #line 1992 "configure" #include "confdefs.h" int main() { ${x_direct_test_function}() ; return 0; } EOF if { (eval echo configure:1999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ /usr/X11/lib \ /usr/X11R6/lib \ /usr/X11R5/lib \ /usr/X11R4/lib \ \ /usr/lib/X11 \ /usr/lib/X11R6 \ /usr/lib/X11R5 \ /usr/lib/X11R4 \ \ /usr/local/X11/lib \ /usr/local/X11R6/lib \ /usr/local/X11R5/lib \ /usr/local/X11R4/lib \ \ /usr/local/lib/X11 \ /usr/local/lib/X11R6 \ /usr/local/lib/X11R5 \ /usr/local/lib/X11R4 \ \ /usr/X386/lib \ /usr/x386/lib \ /usr/XFree86/lib/X11 \ \ /usr/lib \ /usr/local/lib \ /usr/unsupported/lib \ /usr/athena/lib \ /usr/local/x11r5/lib \ /usr/lpp/Xamples/lib \ /lib/usr/lib/X11 \ \ /usr/openwin/lib \ /usr/openwin/share/lib \ ; \ do for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest* fi # $ac_x_libraries = NO if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$ac_t""$have_x" 1>&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. cat >> confdefs.h <<\EOF #define X_DISPLAY_MISSING 1 EOF X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 echo "configure:2105: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <<EOF #line 2108 "configure" #include "confdefs.h" int main() { ; return 0; } EOF if { (eval echo configure:2115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_nospace=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_R_nospace=no fi rm -f conftest* if test $ac_R_nospace = yes; then echo "$ac_t""no" 1>&6 X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <<EOF #line 2131 "configure" #include "confdefs.h" int main() { ; return 0; } EOF if { (eval echo configure:2138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_space=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_R_space=no fi rm -f conftest* if test $ac_R_space = yes; then echo "$ac_t""yes" 1>&6 X_LIBS="$X_LIBS -R $x_libraries" else echo "$ac_t""neither works" 1>&6 fi fi LIBS="$ac_xsave_LIBS" esac fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 echo "configure:2170: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <<EOF #line 2178 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dnet_ntoa(); int main() { dnet_ntoa() ; return 0; } EOF if { (eval echo configure:2189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" else echo "$ac_t""no" 1>&6 fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 echo "configure:2211: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <<EOF #line 2219 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dnet_ntoa(); int main() { dnet_ntoa() ; return 0; } EOF if { (eval echo configure:2230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" else echo "$ac_t""no" 1>&6 fi fi # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 echo "configure:2259: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2264 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else gethostbyname(); #endif ; return 0; } EOF if { (eval echo configure:2287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 echo "configure:2308: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <<EOF #line 2316 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname(); int main() { gethostbyname() ; return 0; } EOF if { (eval echo configure:2327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" else echo "$ac_t""no" 1>&6 fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says simon@lia.di.epfl.ch: it contains # gethostby* variants that don't use the nameserver (or something). # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 echo "configure:2357: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2362 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else connect(); #endif ; return 0; } EOF if { (eval echo configure:2385: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_connect=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_connect = no; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 echo "configure:2406: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <<EOF #line 2414 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect(); int main() { connect() ; return 0; } EOF if { (eval echo configure:2425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" else echo "$ac_t""no" 1>&6 fi fi # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 echo "configure:2449: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2454 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char remove(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char remove(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_remove) || defined (__stub___remove) choke me #else remove(); #endif ; return 0; } EOF if { (eval echo configure:2477: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_remove=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_remove=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 echo "configure:2498: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <<EOF #line 2506 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char remove(); int main() { remove() ; return 0; } EOF if { (eval echo configure:2517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" else echo "$ac_t""no" 1>&6 fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 echo "configure:2541: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2546 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shmat(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shmat(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_shmat) || defined (__stub___shmat) choke me #else shmat(); #endif ; return 0; } EOF if { (eval echo configure:2569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_shmat=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 echo "configure:2590: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <<EOF #line 2598 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shmat(); int main() { shmat() ; return 0; } EOF if { (eval echo configure:2609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" else echo "$ac_t""no" 1>&6 fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS="$LDFLAGS" test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 echo "configure:2642: checking for IceConnectionNumber in -lICE" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <<EOF #line 2650 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char IceConnectionNumber(); int main() { IceConnectionNumber() ; return 0; } EOF if { (eval echo configure:2661: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" else echo "$ac_t""no" 1>&6 fi LDFLAGS="$ac_save_LDFLAGS" fi if test "$X_CFLAGS" = "-DX_DISPLAY_MISSING"; then TARGET_X_LIBS="" TARGET_X_INC="" else xlibs="$X_LIBS $X_PRE_LIB -lX11 $X_EXTRA_LIBS" TARGET_X_LIBS=`echo $xlibs | sed -e 's/^ *//' -e 's/ //'g -e 's/ *$//'` if test "$x_includes" != ""; then TARGET_X_INC=`echo $x_includes | sed -e 's/^/-I/' -e 's/ */ -I/'` fi fi else TARGET_X_LIBS="-mwindows -e _mainCRTStartup -limm32 -lcomctl32" TARGET_X_INC="" fi fi . $tkconf TARGET_X_LIBS="${TK_LIBS}" ########## # Figure out what libraries are required to compile Tk programs. # if test "$config_TARGET_TK_LIBS" != ""; then TARGET_TK_LIBS="$config_TARGET_TK_LIBS" else if test "$with_tk" != ""; then TARGET_TK_LIBS=`echo $with_tk/$tclsubdir/libtk*.a` else CC=$TARGET_CC otherlibs="$TARGET_X_LIBS $TARGET_TCL_LIBS" LIBS="" echo $ac_n "checking for library containing Tk_Init""... $ac_c" 1>&6 echo "configure:2718: checking for library containing Tk_Init" >&5 if eval "test \"`echo '$''{'ac_cv_search_Tk_Init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_func_search_save_LIBS="$LIBS" ac_cv_search_Tk_Init="no" cat > conftest.$ac_ext <<EOF #line 2725 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tk_Init(); int main() { Tk_Init() ; return 0; } EOF if { (eval echo configure:2736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_Tk_Init="none required" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* test "$ac_cv_search_Tk_Init" = "no" && for i in tk8.2 tk8.1 tk8.0 tk80 tk; do LIBS="-l$i $otherlibs $ac_func_search_save_LIBS" cat > conftest.$ac_ext <<EOF #line 2747 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tk_Init(); int main() { Tk_Init() ; return 0; } EOF if { (eval echo configure:2758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_Tk_Init="-l$i" break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done LIBS="$ac_func_search_save_LIBS" fi echo "$ac_t""$ac_cv_search_Tk_Init" 1>&6 if test "$ac_cv_search_Tk_Init" != "no"; then test "$ac_cv_search_Tk_Init" = "none required" || LIBS="$ac_cv_search_Tk_Init $LIBS" else : fi TARGET_TK_LIBS=$LIBS fi fi ########### # Figure out where to get the TK header files. # echo $ac_n "checking TK header files""... $ac_c" 1>&6 echo "configure:2787: checking TK header files" >&5 if test "$config_TARGET_TK_INC" != ""; then TARGET_TK_INC=$config_TARGET_TK_INC else if test "$with_tk" != ""; then TARGET_TK_INC="-I$with_tk/generic -I$with_tk/$tclsubdir" if test "$tclsubdir" = "win"; then TARGET_TK_INC="$TARGET_TK_INC -I$with_tk/xlib" fi else TARGET_TK_INC="" fi fi echo "$ac_t""$TARGET_TK_INC" 1>&6 ######### # Generate the output files. # trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS <<EOF #! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "makemake.tcl" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@program_prefix@%$program_prefix%g s%@CC@%$CC%g s%@BUILD_CC@%$BUILD_CC%g s%@BUILD_CFLAGS@%$BUILD_CFLAGS%g s%@BUILD_LIBS@%$BUILD_LIBS%g s%@RANLIB@%$RANLIB%g s%@TARGET_CC@%$TARGET_CC%g s%@TARGET_CFLAGS@%$TARGET_CFLAGS%g s%@TARGET_LINK@%$TARGET_LINK%g s%@TARGET_LFLAGS@%$TARGET_LFLAGS%g s%@TARGET_RANLIB@%$TARGET_RANLIB%g s%@TARGET_AR@%$TARGET_AR%g s%@BUILD_EXEEXT@%$BUILD_EXEEXT%g s%@OS_UNIX@%$OS_UNIX%g s%@OS_WIN@%$OS_WIN%g s%@TARGET_EXEEXT@%$TARGET_EXEEXT%g s%@BUILD_TCLSH@%$BUILD_TCLSH%g s%@TARGET_SHLIB_EXT@%$TARGET_SHLIB_EXT%g s%@TARGET_SHLIB_CFLAGS@%$TARGET_SHLIB_CFLAGS%g s%@TARGET_SHLIB_LINK@%$TARGET_SHLIB_LINK%g s%@TARGET_SHLIB_LIBS@%$TARGET_SHLIB_LIBS%g s%@ENABLE_SHLIB@%$ENABLE_SHLIB%g s%@TARGET_TCL_SCRIPT_DIR@%$TARGET_TCL_SCRIPT_DIR%g s%@TARGET_TK_SCRIPT_DIR@%$TARGET_TK_SCRIPT_DIR%g s%@TARGET_LIBS@%$TARGET_LIBS%g s%@TARGET_TCL_LIBS@%$TARGET_TCL_LIBS%g s%@CPP@%$CPP%g s%@TARGET_TCL_INC@%$TARGET_TCL_INC%g s%@X_CFLAGS@%$X_CFLAGS%g s%@X_PRE_LIBS@%$X_PRE_LIBS%g s%@X_LIBS@%$X_LIBS%g s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g s%@TARGET_X_LIBS@%$TARGET_X_LIBS%g s%@TARGET_X_INC@%$TARGET_X_INC%g s%@TARGET_TK_LIBS@%$TARGET_TK_LIBS%g s%@TARGET_TK_INC@%$TARGET_TK_INC%g s%@TARGET_BLT_INC@%$TARGET_BLT_INC%g s%@TARGET_BLT_LIBS@%$TARGET_BLT_LIBS%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"makemake.tcl"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <<EOF tclsh=$BUILD_TCLSH EOF cat >> $CONFIG_STATUS <<\EOF $tclsh makemake.tcl >Makefile exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/configure.in��������������������������������������������������������������������0000644�0001750�0001750�00000050341�10425444635�015576� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # This file describes a "configure" script that is used to build # makefiles for a particular platform. Process this file using # Autoconf version 1.13 in order to generate that script. All # lines of this file up to the AC_INIT macro are ignored. # # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The # configure script needs to discover the following properties of the # build and target systems: # # srcdir # # The is the name of the directory that contains the # "configure" shell script. All source files are # located relative to this directory. # # bindir # # The name of the directory where executables should be # written by the "install" target of the makefile. # # program_prefix # # Add this prefix to the names of all executables that run # on the target machine. Default: "" # # ENABLE_SHARED # # True if shared libraries should be generated. # # BUILD_CC # # The name of a command that is used to convert C # source files into executables that run on the build # platform. # # BUILD_CFLAGS # # Switches that the build compiler needs in order to construct # command-line programs. # # BUILD_LIBS # # Libraries that the build compiler needs in order to construct # command-line programs. # # BUILD_EXEEXT # # The filename extension for executables on the build # platform. "" for Unix and ".exe" for Windows. # # BUILD_TCLSH # # The name of a tclsh executable on the build platform. # # TARGET_CC # # The name of a command that runs on the build platform # and converts C source files into *.o files for the # target platform. In other words, the cross-compiler. # # TARGET_CFLAGS # # Switches that the target compiler needs to turn C source files # into *.o files. Do not include TARGET_TCL_INC, TARGET_X_INC # or TARGET_TK_INC in this list. Makefiles might add # additional switches such as "-I.". # # TARGET_SHLIB_CFLAGS # # Switches that the target compiler needs to turn C source files # into *.o files that can later be linked into a shared library. # Does not include TARGET_*_INC. # # TARGET_TCL_INC # TARGET_X_INC # TARGET_TK_INC # TARGET_BLT_INC # # These variables define the directories that contain header # files for Tcl, X11, Tk, and BLT respectively. If the compiler # is able to find <tcl.h>, <X11/Xlib.h>, <tk.h> and <blt.h> # on its own, then these can be blank. # # TARGET_LINK # # The name of the linker that combines *.o files generated # by TARGET_CC into executables for the target platform. # # TARGET_SHLIB_LINK # # The name of the linker an maybe some options that combines # *.o files into a shared library. # # TARGET_SHLIB_EXT # # The extension used for shared libraries on the target system. # # TARGET_TCL_LIBS # TARGET_X_LIBS # TARGET_TK_LIBS # TARGET_BLT_LIBS # # These are the library directives passed to the target linker # that cause the executable to link against Tcl, X11, Tk, and # BLT respectively. They might be switches like "-ltcl8.0" or # pathnames of library files like "../../src/libtcl8.0.a". # # TARGET_LIBS # # Additional libraries or other switch that the target linker needs # to build an executable on the target. Do not include # on this list any libraries in TARGET_TCL_LIBS, TARGET_X_LIBS, # TARGET_TK_LIBS, or TARGET_BLT_LIBS. # # TARGET_EXEEXT # # The filename extension for executables on the # target platform. "" for Unix and ".exe" for windows. # # TARGET_TCL_SCRIPT_DIR # # A directory on the build platform that contains the # Tcl script libraries that are compatible with the # Tcl C libraries of the target platform. # # TARGET_TK_SCRIPT_DIR # # A directory on the build platform that contains the # Tk script libraries that are compatible with the # Tk C libraries of the target platform. # # The generated configure script will make an attempt to guess # at all of the above parameters. You can override any of # the guesses by setting the environment variable named # "config_AAAA" where "AAAA" is the name of the parameter # described above. (Exception: srcdir cannot be set this way.) # If you have a file that sets one or more of these environment # variables, you can invoke configure as follows: # # configure --with-hints=FILE # # where FILE is the name of the file that sets the environment # variables. FILE should be an absolute pathname. # # If you have a Tcl/Tk/BLT source distribution available, then the # files in that distribution will be used instead of any other # Tcl/Tk/BLT files the script might discover if you tell the configure # script about the source tree. Use commandline options: # # --with-tcl=PATH --with-tk=PATH --with-blt=PATH # # Or set environment variables config_WITH_TCL, config_WITH_TK, or # config_WITH_BLT. # # This configure.in file is easy to reuse on other projects. Just # change the argument to AC_INIT(). And disable any features that # you don't need (for example BLT) by erasing or commenting out # the corresponding code. # AC_INIT(src/html.h) dnl Put the RCS revision string after AC_INIT so that it will also dnl show in in configure. # The following RCS revision string applies to configure.in # $Revision: 1.2 $ ######### # Make sure we are not building in a subdirectory of the source tree. # changequote(<<<,>>>) temp=`echo $srcdir | grep '[^./]'` changequote([,]) if test "$temp" = ""; then AC_MSG_ERROR([ ************************************************************************** ** This program may not be compiled in the same directory that contains ** ** the configure script or any subdirectory of that directory. Rerun ** ** the configure script from a directory that is separate from the ** ** source tree. ** **************************************************************************]) fi ######### # Set up an appropriate program prefix # if test "$program_prefix" = "NONE"; then program_prefix="" fi AC_SUBST(program_prefix) ######### # Check to see if the --with-hints=FILE option is used. If there is none, # then check for a files named "$host.hints" and ../$hosts.hints where # $host is the hostname of the build system. If still no hints are # found, try looking in $system.hints and ../$system.hints where # $system is the result of uname -s. # AC_ARG_WITH(hints, [ --with-hints=FILE Read configuration options from FILE], hints=$withval) if test "$hints" = ""; then host=`hostname | sed 's/\..*//'` if test -r $host.hints; then hints=$host.hints else if test -r ../$host.hints; then hints=../$host.hints fi fi fi if test "$hints" = ""; then sys=`uname -s` if test -r $sys.hints; then hints=$sys.hints else if test -r ../$sys.hints; then hints=../$sys.hints fi fi fi if test "$hints" != ""; then AC_MSG_RESULT(reading hints from $hints) . $hints fi ######### # Locate a compiler for the build machine. This compiler should # generate command-line programs that run on the build machine. # default_build_cflags="-g" if test "$config_BUILD_CC" = ""; then AC_PROG_CC if test "$cross_compiling" = "yes"; then AC_MSG_ERROR([unable to find a compiler for building build tools]) fi BUILD_CC=$CC default_build_cflags=$CFLAGS else BUILD_CC=$config_BUILD_CC AC_MSG_CHECKING([host compiler]) CC=$BUILD_CC AC_MSG_RESULT($BUILD_CC) fi AC_MSG_CHECKING([switches for the host compiler]) if test "$config_BUILD_CFLAGS" != ""; then CFLAGS=$config_BUILD_CFLAGS BUILD_CFLAGS=$config_BUILD_CFLAGS else BUILD_CFLAGS=$default_build_cflags fi AC_MSG_RESULT($BUILD_CFLAGS) if test "$config_BUILD_LIBS" != ""; then BUILD_LIBS=$config_BUILD_LIBS fi AC_SUBST(BUILD_CC) AC_SUBST(BUILD_CFLAGS) AC_SUBST(BUILD_LIBS) ########## # Locate a compiler that converts C code into *.o files that run on # the target machine. # AC_MSG_CHECKING([target compiler]) if test "$config_TARGET_CC" != ""; then TARGET_CC=$config_TARGET_CC else TARGET_CC=$BUILD_CC fi AC_MSG_RESULT($TARGET_CC) AC_MSG_CHECKING([switches on the target compiler]) if test "$config_TARGET_CFLAGS" != ""; then TARGET_CFLAGS=$config_TARGET_CFLAGS else TARGET_CFLAGS=$BUILD_CFLAGS fi AC_MSG_RESULT($TARGET_CFLAGS) AC_MSG_CHECKING([target linker]) if test "$config_TARGET_LINK" = ""; then TARGET_LINK=$TARGET_CC else TARGET_LINK=$config_TARGET_LINK fi AC_MSG_RESULT($TARGET_LINK) AC_MSG_CHECKING([switches on the target compiler]) if test "$config_TARGET_TFLAGS" != ""; then TARGET_TFLAGS=$config_TARGET_TFLAGS else TARGET_TFLAGS=$BUILD_CFLAGS fi if test "$config_TARGET_RANLIB" != ""; then TARGET_RANLIB=$config_TARGET_RANLIB else AC_PROG_RANLIB TARGET_RANLIB=$RANLIB fi if test "$config_TARGET_AR" != ""; then TARGET_RANLIB=$config_TARGET_AR else TARGET_AR='ar cr' fi AC_MSG_RESULT($TARGET_TFLAGS) AC_SUBST(TARGET_CC) AC_SUBST(TARGET_CFLAGS) AC_SUBST(TARGET_LINK) AC_SUBST(TARGET_LFLAGS) AC_SUBST(TARGET_RANLIB) AC_SUBST(TARGET_AR) # Set the $cross variable if we are cross-compiling. Make # it 0 if we are not. # AC_MSG_CHECKING([if host and target compilers are the same]) if test "$BUILD_CC" = "$TARGET_CC"; then cross=0 AC_MSG_RESULT(yes) else cross=1 AC_MSG_RESULT(no) fi ########### # Lots of things are different if we are compiling for Windows using # the CYGWIN environment. So check for that special case and handle # things accordingly. # AC_MSG_CHECKING([if executables have the .exe suffix]) if test "$config_BUILD_EXEEXT" = ".exe"; then CYGWIN=yes AC_MSG_RESULT(yes) else AC_MSG_RESULT(unknown) fi if test "$CYGWIN" != "yes"; then AC_CYGWIN fi if test "$CYGWIN" = "yes"; then BUILD_EXEEXT=.exe else BUILD_EXEEXT="" fi if test "$cross" = "0"; then TARGET_EXEEXT=$BUILD_EXEEXT else TARGET_EXEEXT=$config_TARGET_EXEEXT fi if test "$TARGET_EXEEXT" = ".exe"; then OS_UNIX=0 OS_WIN=1 tclsubdir=win else OS_UNIX=1 OS_WIN=0 tclsubdir=unix fi TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=$OS_UNIX -DOS_WIN=$OS_WIN" AC_SUBST(BUILD_EXEEXT) AC_SUBST(OS_UNIX) AC_SUBST(OS_WIN) AC_SUBST(TARGET_EXEEXT) ######### # Locate a working copy of tclsh. We have to have this program # running on the build platform since the makefiles use it. # AC_ARG_WITH(tcl, [ --with-tcl=DIR Directory holding Tcl source tree for target]) if test "$config_WITH_TCL" != ""; then with_tcl=$config_WITH_TCL fi AC_ARG_WITH(tk, [ --with-tk=DIR Directory holding Tk source tree for target]) if test "$config_WITH_TK" != ""; then with_tk=$config_WITH_TK fi if test "$config_BUILD_TCLSH" != ""; then AC_MSG_CHECKING([for a working "tclsh"]) BUILD_TCLSH=$config_BUILD_TCLSH AC_MSG_RESULT($BUILD_TCLSH) else if test "$with_tcl" != ""; then if test -x "$with_tcl/$tclsubdir/tclsh"; then BUILD_TCLSH=$with_tcl/$tclsubdir/tclsh else if test -x "$with_tcl/$tclsubdir/tclsh8.0"; then BUILD_TCLSH=$with_tcl/$tclsubdir/tclsh8.0 fi fi fi if test "$BUILD_TCLSH" = ""; then AC_CHECK_PROGS(BUILD_TCLSH, tclsh8.2 tclsh8.1 tclsh81 tclsh8.0 tclsh80 cygtclsh80 tclsh, "") fi if test "$BUILD_TCLSH" = ""; then AC_MSG_ERROR([no working "tclsh" could be found]) fi fi AC_SUBST(BUILD_TCLSH) ############### # Check to see if the user wants to build shared libraries. If so, # then locate tclConfig.sh and tkConfig.sh to figure out how. Then # set up variables to short-circuit most of the subsequent tests # since the tclConfig.sh and tkConfig.sh files tell us most of what # we need to know. # AC_ARG_ENABLE(shared, [ --enable-shared Build the widget as a shared library],, enable_shared=yes) if test "$config_ENABLE_SHARED" = "yes"; then enable_shared=yes fi AC_MSG_CHECKING([if shared libraries are requested]) if test "$enable_shared" = "yes"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi if test "$CYGWIN" = "yes"; then if test "$enable_shared" = "yes"; then AC_MSG_WARN([don't know how to build shared libraries with Cygwin, yet...]) enable_shared=no fi fi if test "$enable_shared" = "yes"; then ok=0 if test "$with_tcl" != ""; then tclconf=$with_tcl/unix/tclConfig.sh AC_CHECK_FILE($tclconf, ok=1; ) fi if test "$ok" = "0"; then changequote(<<<,>>>)dnl cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [file dirname [info library]] {//\1/} out puts -nonewline $out exit EOF changequote([,])dnl dir=`$BUILD_TCLSH <conftest.tcl` tclconf=$dir/tclConfig.sh AC_CHECK_FILE($tclconf, ok=1) fi if test "$ok" = "0"; then tclconf=$dir/unix/tclConfig.sh AC_CHECK_FILE($tclconf, ok=1) fi if test "$ok" = "0"; then tclconf=/usr/local/lib/tclConfig.sh AC_CHECK_FILE($tclconf, ok=1) fi if test "$ok" = "0"; then tclconf=/usr/lib/tclConfig.sh AC_CHECK_FILE($tclconf, ok=1) fi if test "$ok" = "0"; then AC_MSG_WARN( [unable to locate tclConfig.sh. Shared libraries will not be built]); enabled_shared=no fi fi if test "$enable_shared" = "yes"; then ok=0 tkconf=`echo $tclconf | sed 's/tclConfig.sh/tkConfig.sh/'` AC_CHECK_FILE($tkconf, ok=1) if test "$ok" = "0"; then if test "$with_tk" != ""; then tkconf=$with_tk/unix/tkConfig.sh AC_CHECK_FILE($tkconf, ok=1; ) fi fi if test "$ok" = "0"; then tkconf=/usr/local/lib/tkConfig.sh AC_CHECK_FILE($tkconf, ok=1) fi if test "$ok" = "0"; then tkconf=/usr/lib/tclConfig.sh AC_CHECK_FILE($tkconf, ok=1) fi if test "$ok" = "0"; then AC_MSG_WARN( [unable to locate tkConfig.sh. Shared libraries will not be built]); enabled_shared=no fi fi if test "$enable_shared" = "yes"; then ENABLE_SHLIB=1 . $tclconf . $tkconf TARGET_SHLIB_EXT=$TCL_SHLIB_SUFFIX TARGET_SHLIB_CFLAGS="$TCL_SHLIB_CFLAGS $TARGET_CFLAGS" TARGET_SHLIB_LINK="$TCL_SHLIB_LD" TARGET_SHLIB_LIBS="$TCL_SHLIB_LD_LIBS" else ENABLE_SHLIB=0 fi AC_SUBST(TARGET_SHLIB_EXT) AC_SUBST(TARGET_SHLIB_CFLAGS) AC_SUBST(TARGET_SHLIB_LINK) AC_SUBST(TARGET_SHLIB_LIBS) AC_SUBST(ENABLE_SHLIB) ######### # Locate the directory that contains all of the Tcl initialization # scripts for the target machine. # AC_MSG_CHECKING([Tcl script library]) if test "$config_TARGET_TCL_SCRIPT_DIR" != ""; then TARGET_TCL_SCRIPT_DIR=$config_TARGET_TCL_SCRIPT_DIR else changequote(<<<,>>>)dnl cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [info library] {//\1/} out puts -nonewline $out exit EOF changequote([,])dnl tcllibdir=`$BUILD_TCLSH <conftest.tcl` rm -f conftest.tcl if test ! -r $tcllibdir/init.tcl; then AC_MSG_ERROR(not found) fi TARGET_TCL_SCRIPT_DIR=$tcllibdir fi AC_MSG_RESULT($TARGET_TCL_SCRIPT_DIR) AC_SUBST(TARGET_TCL_SCRIPT_DIR) ######### # Locate the directory that contains all of the Tk initialization # scripts for the target machine. # AC_MSG_CHECKING([Tk script library]) if test "$config_TARGET_TK_SCRIPT_DIR" != ""; then TARGET_TK_SCRIPT_DIR=$config_TARGET_TK_SCRIPT_DIR else if test "$with_tk" != ""; then tklibdir=$with_tk/library else changequote(<<<,>>>)dnl cat > conftest.tcl <<\EOF regsub {^([A-Za-z]):/} [info library] {//\1/} out regsub {/tcl7.6} $out {tk4.2} out regsub {/tcl([^/]*)} $out {/tk\1} out puts -nonewline $out exit EOF changequote([,])dnl tklibdir=`$BUILD_TCLSH <conftest.tcl` rm -f conftest.tcl fi if test ! -r $tklibdir/tk.tcl; then AC_MSG_ERROR(not found) fi TARGET_TK_SCRIPT_DIR=$tklibdir fi AC_MSG_RESULT($TARGET_TK_SCRIPT_DIR) AC_SUBST(TARGET_TK_SCRIPT_DIR) ########## # Extract generic linker options from the environment. # if test "$config_TARGET_LIBS" != ""; then TARGET_LIBS=$config_TARGET_LIBS else TARGET_LIBS="" fi AC_SUBST(TARGET_LIBS) ########## # Figure out what C libraries are required to compile Tcl programs. # if test "$config_TARGET_TCL_LIBS" != ""; then TARGET_TCL_LIBS="$config_TARGET_TCL_LIBS" else if test "$with_tcl" != ""; then extra=`echo $with_tcl/$tclsubdir/libtcl8*.a` fi CC=$TARGET_CC AC_CHECK_FUNC(sin, LIBS="", LIBS="-lm") AC_CHECK_LIB(dl, dlopen) otherlibs=$LIBS if test "$extra" != ""; then LIBS=$extra else LIBS="" AC_SEARCH_LIBS(Tcl_Init, tcl8.2 tcl8.1 tcl8.0 tcl80 tcl,,,$otherlibs) fi TARGET_TCL_LIBS="$LIBS $otherlibs" fi AC_SUBST(TARGET_TCL_LIBS) ########## # Figure out where to get the TCL header files. # AC_MSG_CHECKING([TCL header files]) found=no if test "$config_TARGET_TCL_INC" != ""; then TARGET_TCL_INC=$config_TARGET_TCL_INC found=yes else if test "$with_tcl" != ""; then TARGET_TCL_INC="-I$with_tcl/generic -I$with_tcl/$tclsubdir" found=yes else TARGET_TCL_INC="" found=no fi fi if test "$found" = "yes"; then AC_MSG_RESULT($TARGET_TCL_INC) else AC_MSG_RESULT(not specified: still searching...) AC_CHECK_HEADER(tcl.h, [found=yes]) fi if test "$found" = "no"; then for dir in /usr/local /usr/X11* /usr/pkg /usr/contrib /usr; do n=$dir/include/tcl.h AC_CHECK_FILE($dir/include/tcl.h, found=yes) if test "$found" = "yes"; then TARGET_TCL_INC="-I$dir/include" break fi done fi AC_SUBST(TARGET_TCL_INC) ########### # Figure out what C libraries are required to compile X11 programs. # If the target is windows, we assume the compiler is Cygwin20 and # insert arguments that generate a windows GUI application. # if test "$config_TARGET_X_LIBS" != ""; then TARGET_X_LIBS=$config_TARGET_X_LIBS TARGET_X_INC=$config_TARGET_X_INC else if test $OS_UNIX = 1; then AC_PATH_XTRA if test "$X_CFLAGS" = "-DX_DISPLAY_MISSING"; then TARGET_X_LIBS="" TARGET_X_INC="" else xlibs="$X_LIBS $X_PRE_LIB -lX11 $X_EXTRA_LIBS" TARGET_X_LIBS=`echo $xlibs | sed -e 's/^ *//' -e 's/ //'g -e 's/ *$//'` if test "$x_includes" != ""; then TARGET_X_INC=`echo $x_includes | sed -e 's/^/-I/' -e 's/ */ -I/'` fi fi else TARGET_X_LIBS="-mwindows -e _mainCRTStartup -limm32 -lcomctl32" TARGET_X_INC="" fi fi AC_SUBST(TARGET_X_LIBS) AC_SUBST(TARGET_X_INC) ########## # Figure out what libraries are required to compile Tk programs. # if test "$config_TARGET_TK_LIBS" != ""; then TARGET_TK_LIBS="$config_TARGET_TK_LIBS" else if test "$with_tk" != ""; then TARGET_TK_LIBS=`echo $with_tk/$tclsubdir/libtk*.a` else CC=$TARGET_CC otherlibs="$TARGET_X_LIBS $TARGET_TCL_LIBS" LIBS="" AC_SEARCH_LIBS(Tk_Init, tk8.2 tk8.1 tk8.0 tk80 tk,,,$otherlibs) TARGET_TK_LIBS=$LIBS fi fi AC_SUBST(TARGET_TK_LIBS) ########### # Figure out where to get the TK header files. # AC_MSG_CHECKING([TK header files]) if test "$config_TARGET_TK_INC" != ""; then TARGET_TK_INC=$config_TARGET_TK_INC else if test "$with_tk" != ""; then TARGET_TK_INC="-I$with_tk/generic -I$with_tk/$tclsubdir" if test "$tclsubdir" = "win"; then TARGET_TK_INC="$TARGET_TK_INC -I$with_tk/xlib" fi else TARGET_TK_INC="" fi fi AC_MSG_RESULT($TARGET_TK_INC) AC_SUBST(TARGET_TK_INC) dnl ############ dnl # Figure out where to look for BLT header files <blt.h>. dnl # dnl AC_ARG_WITH(blt, dnl [ --with-blt=DIR Directory holding BLT source tree for target]) dnl if test "$config_WITH_BLT" != ""; then dnl with_tk=$config_WITH_BLT dnl fi dnl AC_MSG_CHECKING([BLT header files]) dnl if test "$config_TARGET_BLT_INC" != ""; then dnl TARGET_BLT_INC=$config_TARGET_BLT_INC dnl else dnl if test "$with_blt" != ""; then dnl TARGET_BLT_INC="-I$with_blt/src" dnl else dnl TARGET_BLT_INC="" dnl fi dnl fi dnl AC_MSG_RESULT($TARGET_BLT_INC) AC_SUBST(TARGET_BLT_INC) dnl dnl ########## dnl # Figure out what libraries are required to compile BLT programs. dnl # dnl if test "$config_TARGET_BLT_LIBS" != ""; then dnl TARGET_BLT_LIBS="$config_TARGET_BLT_LIBS" dnl else dnl if test "$with_blt" != ""; then dnl TARGET_BLT_LIBS=`echo $with_blt/src/libBLT*.a` dnl else dnl CC=$TARGET_CC dnl otherlibs="$TARGET_TK_LIBS $TARGET_X_LIBS $TARGET_TCL_LIBS" dnl LIBS="" dnl AC_SEARCH_LIBS(Blt_Init, BLT BLT2.4 BLT24,,,$otherlibs) dnl TARGET_BLT_LIBS=$LIBS dnl fi dnl fi AC_SUBST(TARGET_BLT_LIBS) ######### # Generate the output files. # AC_OUTPUT_COMMANDS([$tclsh makemake.tcl >Makefile], tclsh=$BUILD_TCLSH) AC_OUTPUT(makemake.tcl) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/doc/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014005� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/doc/spec.html�������������������������������������������������������������������0000644�0001750�0001750�00000063506�07504443344�015661� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <!-- Specifications for the Tk HTML Widget $Revision: 1.1.1.1 $ Copyright (C) 1997, 1998, 1999 D. Richard Hipp 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., 675 Mass Ave, Cambridge, MA 02139, USA. Author Contact Information: drh@acm.org http://www.hwaci.com/drh/ @(#) $Id: spec.html,v 1.1.1.1 2002/06/20 21:19:32 joye Exp $ --> <head> <title>Interface Specification For The HTML Widget</title> </head> <body bgcolor=white> <h1>Interface Specification For The HTML Widget</h1> <p>This is a draft interface specification for the Tk HTML widget currently under development. Since it is still a draft, it is subject to change. Eventually, the interface will stabilize and this interface specification will morph into a manual page.</p> <h2>Configuration Options</h2> <table cellspacing=10> <tr><td valign=top><tt>-appletcommand</tt></td> <td> <p>This option specifies the name of the Tcl procedure to invoke when the <tt>&lt;applet&gt;...&lt;/applet&gt;</tt> tag sequence is seen. The html widget will append two arguments to the procedure before calling it. The first argument is the name of a widget that the callback should create to hold the applet. The second argument is a list of name/value pairs which are the arguments to the <tt>&lt;applet&gt;</tt> tag.</p> <p>The text between <tt>&lt;applet&gt</tt> and <tt>&lt;/applet&gt;</tt> is normally suppressed. However, if the <tt>-appletcommand</tt> option is set to the empty string, the <tt>&lt;applet&gt</tt> tag is ignored and all text between <tt>&lt;applet&gt;</tt> and <tt>&lt;/applet&gt;</tt> is displayed normally.</p> <p>"&lt;embed&gt;" is treated as an alias for "&lt;applet&gt;&lt;/applet&gt".</p> </td></tr> <tr><td valign=top><tt>-background</tt></td> <td> <p>The background color for the widget.</p> <p>Note that the <tt>&lt;body bgcolor=...&gt;</tt> HTML tag does not automatically cause the widget to change its background color. If you want the background color to change in response to this HTML tag, then your Tcl script should intercept the <tt>&lt;body&gt;</tt> tag using the ``<tt>token handler</tt>'' widget command (described below) and change the background color manually.</p> </td></tr> <tr><td valign=top><tt>-base</tt></td> <td> <p>The base URI for the current document. This should be set to the URI that was used to retrieve the document before parsing begins.</p> </td></tr> <tr><td valign=top><tt>-bd</tt><td>An alias for <tt>-borderwidth</tt> <tr><td valign=top><tt>-bg</tt><td>An alias for <tt>-background</tt> <tr><td valign=top><tt>-borderwidth</tt></td> <td> <p>The width of the 3-D border drawn around the parameter of the widget, in pixels.</p> </td></tr> <tr><td valign=top><tt>-cursor</tt></td> <td> <p>The cursor displayed when the pointer is positioned over the HTML widget. If {}, the cursor reverts to its default shape.</p> </td></tr> <tr><td valign=top><tt>-exportselection</tt></td> </tr> <tr><td valign=top><tt>-fontcommand</tt></td> <td> <p>The name of a TCL procedure that is used to convert HTML font names into TCL font names. A default built-in procedure is used if the value of this option is {}.</p> <p>When the HTML widget needs a new font, it calls this procedure with two arguments. This first argument is the font size expressed as an integer between 1 and 7. The standard size is 4. The second argument is a set of between 0 and 3 keywords drawn from the following set: "bold", "italic", and "fixed". If the "bold" keyword is present in the second argument, the font returned should be bold. If the "italic" keyword is present, the font should be italic. If the "fixed" keyword is present, the font should be fixed-width. The TCL procedure should return the name of the TCL font that the HTML widget will use to render the given HTML font. If the TCL procedure returns an empty string, then the built-in default procedure is used to determine the font.</p> <p>Examples: This is {4 {}}. <tt>This is {4 fixed}</tt>. <small>This is {3 {}}</small>. <large><tt><bold>This is {5 {fixed bold}} </bold></tt></large></p> </td></tr> <tr><td valign=top><tt>-fg</tt></td> <td>An alias for <tt>-foreground</tt>.</td> </tr> <tr><td valign=top><tt>-foreground</tt></td> <td> The default foreground color in which HTML text is rendered. The HTML can override this using the <tt>color=...</tt> attribute on various HTML tags. </td></tr> <tr><td valign=top> <code>-formcommand <var>string</var></code> </td><td> Declares a handler for everything to do with forms within a document. Arguments will be appended to <var>string</var> and the result evaluated during parsing (for form creation) and when the widget is cleared (for form cleanup). The first argument is a token for identifying a form. The second argument selects the action to perform. The remaining arguments depend on the action, as follows. <dl><dt><code><var>string token</var> form <var>URL method attrs</var></code> <dd>The handler should begin taking notes for form <var>token</var>, especially the (resolved) <var>URL</var> of the action and the <var>method</var> to be applied. The raw attributes of the FORM element are in the pairlist <var>attrs</var>. <dt><code><var>string token</var> flush</code> <dd>When the document is cleared, the widget will destroy all the windows it requested. This handler should clean up anything else it created for that form. <dt><code><var>string token</var> input <var>path attrs</var></code> <dd>The handler should create a window named <var>path</var> appropriate for the element described by the <var>attrs</var>. The widget will map the window into its rendering appropriately. <p>It is not an error for the handler to return without creating such a window (it's natural in the case of type=hidden); the widget simply ignores the element in that case. The attributes are the raw values in the HTML, with one exception; a <code>src</code> will be resolved before the handler is called. <dt><code><var>string token</var> textarea <var>path attrs initial</var></code> <dd>The handler should create a window (a single Text, or a Frame with Text and Scrollbars, or whatever) appropriate for a &lt;textarea&gt; and initialise it to the <var>initial</var> string. <dt><code><var>string token</var> select <var>path attrs choices initial</var></code> <dd><em>&lt;select&gt is quite a complicated case...</em> The handler should create a window appropriate for a &lt;select&gt; of the given attributes and present the list of <var>choices</var>. Each choice is a pair, the value and its label. <var>initial</var> is a list of values initially selected. <em>This approach is somewhat questionable but should do most of the time.</em> </dl> Caution: Be very careful to avoid confusing HTML variables with TCL variables. It may be tempting to use the <code>name</code> attribute fairly directly to link together related widgets, but it will likely cause incorrect behaviours. Also be careful to observe the order in which the elements are created; this determines the order in which they must be submitted. A default form handler with the correct bahaviour written in TCL will be bundled with the widget. <p>The attribute names will be downcased within <var>attrs</var>. </td></tr> <tr><td valign=top><tt>-framecommand</tt><td> The script specified by this option is invoked when the HTML parser encounters a <tt>&lt;frameset&gt;...&lt;/frameset&gt;</tt> tag sequence. The arguments to the script are TBD. If the value of the option is the empty string, then the text within the <tt>&lt;noframe&gt...&lt;/noframe&gt;</tt> tag sequence is displayed. <tr><td valign=top><tt>-height</tt><td> Specifies the height of the area into which HTML is rendered. This value plus twice the <tt>-padx</tt>, <tt>-borderwidth</tt> and <tt>-highlightthickness</tt> values is the total height of the widget. <tr><td valign=top><tt>-highlightbackground</tt><td> <tr><td valign=top><tt>-highlightcolor</tt><td> <tr><td valign=top><tt>-highlightthickness</tt><td> <tr><td valign=top><tt>-hyperlinkcommand</tt></td> <td> The script specified by this option is invoked whenever the user clicks on a hyperlink on the HTML page. Before invoking this script, the URI for the hyperlink is appended. </td></tr> <tr><td valign=top><tt>-imagecommand</tt></td> <td> When a ``<tt>&lt;img src=...&gt;</tt>'' tag is encountered, the HTML widget invokes the script specified by this option in order to get the name of a Tk image object to display the HTML image. Before invoking the script, the following arguments are appended: <ol> <li>The value of the <tt>src=...</tt> parameter after have been processed by the resolver. <li>The value of the <tt>width=...</tt> parameter. <li>The value of the <tt>height=...</tt> parameter. <li>A list containing the names and values of all parameters. </ol> If the name returned by this script is the empty string, or if the script is an empty string, then the HTML widget displays the <tt>alt=...</tt> text of the <tt>&lt;img&gt</tt> tag instead of an image. </td></tr> <tr><td valign=top><tt>-isvisitedcommand</tt><td> When the HTML widget encounters a hyperlink (``<tt>&lt;a href=...&gt;</tt>'') it invokes the script specified by this option in order to determine whether or not the hyperlink has been visited. This information is needed to determine what color to use to display the hyperlink. <tr><td valign=top><tt>-padx</tt><td> The amount of extra space to insert between the 3-D border and the left and right sides of the document text. <tr><td valign=top><tt>-pady</tt><td> The amount of extra space to insert between the 3-D border and the top and bottom of the document text. <tr><td valign=top><tt>-relief</tt><td> The relief used to draw the 3-D border. <tr><td valign=top><tt>-resolvercommand</tt></td> <td> <p>The name of a TCL command used to resolve URIs. If blank, a built-in resolver is used. If a TCL command is specified but it returns an empty string, the built-in resolver is used then too. The build-in resolver is based on the algorithm in section 5.2 of RFC 2396. </p> <p>Multiple URIs are appended to the TCL command before it is executed. The first URI is the BASE URI of the document (the URL that specified by the -base configuration option and updated according to any prior &lt;BASE&gt; markup). Zero or more additional URIs are appended to this base. The result of the script should be the resolution of the whole series or URIs.</p> </td></tr> <tr><td valign=top><tt>-rulerelief</tt></td> <td> <p>Determines the appearance of the Horizontal Rule (&lt;HR&gt) markup. The default is "sunken". This can also be "raised" or "flat". If "flat", then the &lt;HR&gt; is drawn using a solid line in the current foreground color. "groove" and "ridge" are the same as "flat".</p> </td></tr> <tr><td valign=top><tt>-scriptcommand</tt></td> <td> <p>Whenever &lt;SCRIPT&gt;...&lt;/SCRIPT&gt; markup is encountered in the input HTML, the attributes of the &lt;SCRIPT&gt; markup and the body of the script are appended to this string and the result is executed as a TCL command. If this options is the empty string, then the script is ignored. </td></tr> <tr><td valign=top><tt>-selectioncolor</tt><td> The background color used when drawing the selection. The foreground color for the selection is the same as the regular foreground color. <tr><td valign=top><tt>-tablerelief</tt></td> <td> <p>Determines the appearance of the borders around tables. The default is "raised". This can also be "sunken" or "flat". If "flat", then the borders is drawn using solid lines in the current foreground color. "groove" and "ridge" are the same as "flat".</p> </td></tr> <tr><td valign=top><tt>-takefocus</tt><td> <tr><td valign=top><tt>-unvisitedcolor</tt><td> The foreground color used to draw hyperlinks that have not been visited. <tr><td valign=top><tt>-underlinehyperlinks</tt><td> Set to TRUE to cause hyperlinks to be drawn using an underlined font. <tr><td valign=top><tt>-visitedcolor</tt><td> The foreground color used to draw hyperlinks that have been visited. <tr><td valign=top><tt>-width</tt><td> The width of the document text. This value does not include space allocated for <tt>-highlightthickness</tt>, <tt>-borderwiddth</tt> or <tt>-padx</tt>. <tr><td valign=top><tt>-xscrollcommand</tt><td> <tr><td valign=top><tt>-yscrollcommand</tt><td> </table> <h2>Indices</h2> Internally, the HTML widget stores the HTML document as a list of tokens. Each token is either <ul> <li>a contiguous sequence of non-space characters (Text), <li>a contiguous sequence of spaces, tabs or newlines (Space), <li>or an HTML markup tag (such as ``<tt>&lt;em&gt;</tt>''.) </ul> Tokens are identified by number. The first token is ``1'', the second is ``2'' and so forth. So in its simplest form, an index is just an integer greater than 0. <p> Within a single Text or Space token, individual characters are also identified by number, though the counting starts with 0 instead of 1. The character number is connected to the token number by a period. So, for example, the 4th character in the 9th token would be ``9.3''. <p> Two integers separated by a dot is called the <em>connonical</em> form of an index. Other index forms are available, including: <table cellspacing=10> <tr><td valign=top>end<td> The keyword ``end'' means one character past the last character of the last token. <tr><td valign=top>@X,Y<td> The character located at screen coordinates X,Y. <tr><td valign=top>*.last<td> The second integer can be replaced by the keyword ``last'' to mean the last character in the token. <tr><td valign=top>sel.first<td> This is the first character that is part of the selection. <tr><td valign=top>sel.last<td> This is the last character that is part of the selection. <tr><td valign=top>ins<td> The character immediately following the insertion cursor. </table> <h2>Commands</h2> <dl> <dt><b>html</b> <i>window</i> ?<i>options ...</i>?</dt><p> <dd> Create a new HTML widget instance named <i>windows</i> </dd> <p> <dt><b>html</b> <b>reformat</b> <i>from to text</i><p> <dd> Convert text from one encoding to another. The text is given in the <i>text</i> argument. The current encoding of the text is specified by the <i>from</i> argument. This command returns the same text in the <i>to</i> encoding. <p> <i>From</i> and <i>to</i> may be any of the following values: <p> <table cellspacing=10> <tr><td valign=top>plain</td> <td> Ordinary text with no characters escaped. </td></tr> <tr><td valign=top>http</td> <td> The text is encoded in a form suitable for use with the HTTP protocol. Spaces are converted to "+". Special characters and escaped as "%aa" where "a" is a hexadecimal digit. A special character is anything other than an alphanumeric or one of these: ".", "$", "-", or "_". </td></tr> <tr><td valign=top>url</td> <td> The text is encoded in a form suitable for use as a URI. Spaces are converted to "+". Special characters and escaped as "%aa" where "a" is a hexadecimal digit. A special character is anything other than an alphanumeric or one of these: ".", "$", "-", "_", or "/". </td></tr> <tr><td valign=top>html</td> <td> The text is encoded in a form suitable for use within HTML. "&amp;" is encoded as "&amp;amp;", "&lt;" is encoded as "&amp;lt;" and so forth. </td></tr> </table> <p> This command is intended to be useful to the TCL procedures that implement callbacks for the HTML widget. </dd> <p> <dt><b>html</b> <b>uri join</b> <i>scheme authority path query fragment</i><p> <dd> This command takes the five main components of a URI and joins them together into a complete URI. Special characters in any component are escaped. </dd> <p> <dt><b>html</b> <b>uri split</b> <i>uri</i><p> <dd> This command takes a single URI and splits it into its five major components: scheme, authorithy, path, query and fragement. The command returns a list where each component is an element of the list. Components missing from the URI are represented as empty elements in the list. </dd> </dl> <h2>Widget Commands</h2> <dl> <dt><i>WIDGET</i>&nbsp <tt>cget</tt> <i>config-option</i><p> <dd> Return the value of a configuration option. Works just like any other Tk widget. <p> <dt><i>WIDGET</i>&nbsp <tt>clear</tt><p> <dd> Remove all tokens and text from the HTML widget. The parser is reset to its initial state. This routine should be called to changes pages. <p> <dt><i>WIDGET</i>&nbsp <tt>configure</tt> ?<i>args...</i>?<p> <dd> The standard Tk configuration command. <p> <dt><i>WIDGET</i>&nbsp <tt>href</tt>&nbsp <i>X&nbsp Y</i><p> <dd>If the coordinates <i>X Y</i> define a point above a hyperlink, then this command will return the target URL for that hyperlink. The URL will be resolved using the -resolvercommand before it is returned. <p> <dt><i>WIDGET</i>&nbsp <tt>index</tt>&nbsp <i>INDEX&nbsp ?COUNT&nbsp UNITS?</i></p> <dd> Translates <i>INDEX</i> into its connonical form. The connonical form of an index is two integers separated by a period. <p> The optional 3rd and 4th arguments specify a displacement from <i>INDEX</i> to the value of the index returned. <i>COUNT</i> can be any integer value, including a negative number. <i>UNITS</i> must be either ``<tt>char</tt>'' or ``<tt>line</tt>''. <p> <dt><i>WIDGET</i>&nbsp <tt>insert</tt>&nbsp <i>INDEX</i><p> <dd> Causes the insertion cursor (a flashing vertical bar) to be positioned immediately before the character specified by <i>INDEX</i>. <p> <dt><i>WIDGET</i>&nbsp <tt>names</tt><p> <dd> This command causes the widget to scan the entire text of the document looking for tags of the form ``<tt>&lt;a name=...&gt;</tt>''. It returns a list of values of the <tt>name=...</tt> fields. <p> The vertical position of the document can be moved to any of these names using the ``<i>WIDGET</i> <tt>yview</tt> <i>NAME</i>'' command described below. <p> <dt><i>WIDGET</i>&nbsp <tt>parse</tt>&nbsp <i>HTML-TEXT</i><p> <dd>Adds the given HTML text to the end of any text previously received through the <tt>parse</tt> command and parses as much of the text as possible into tokens. Afterwards, the display is updated to show the new tokens, if they are visible.<p> <dt><i>WIDGET</i>&nbsp; <tt>resolver</tt>&nbsp; ?<i>uri ...</i>?<p> <dd>The resolver specified by the -resolvercommand option is called with the base URI of the document followed by the remaining arguments to this commant. The result of this command is the result of the -resolvercommand script.<p> <dt><i>WIDGET</i>&nbsp <tt>selection</tt>&nbsp <i>subcommand args...</i><p> <dd>The selection widget command is used to control the selection.<p> <dl> <dt><i>WIDGET</i>&nbsp <tt>selection clear</tt><p> <dd>Clear the current selection. No text will be selected after this command executes.<p> <dt><i>WIDGET</i>&nbsp <tt>selection set</tt>&nbsp <i>START&nbsp END</i><p> <dd>Change the selection to be all text contained within the given indices.<p> </dl> <p> <dt><i>WIDGET</i>&nbsp <tt>text</tt>&nbsp <i>subcommand args...</i><p> <dd>There are several token commands. They all have the common property that they directly manipulate the text that is displayed. These commands (none of which are currently implemented) can be used to build an WYSIWYG editor for HTML.<p> <dl> <dt><i>WIDGET</i>&nbsp; <tt>text ascii</tt>&nbsp <i>INDEX-1&nbsp INDEX-2</i><p> <dd><p> Returns plain ASCII text that represents all characters between <i>INDEX-1</i> and <i>INDEX-2</i>. Formatting tags are omitted. The <i>INDEX-1</i> character is included by <i>INDEX-2</i> is omitted. <p> <dt><i>WIDGET</i>&nbsp; <tt>text delete</tt>&nbsp <i>INDEX-1&nbsp INDEX-2</i><p> <dd><p> All text from <i>INDEX-1</i> up to, but not including <i>INDEX-2</i> is removed and the display is updated accordingly. <p> <dt><i>WIDGET</i>&nbsp; <tt>text html</tt>&nbsp <i>INDEX-1&nbsp INDEX-2</i><p> <dd><p> Returns HTML text that represents all characters and formatting tags between <i>INDEX-1</i> and <i>INDEX-2</i>. The <i>INDEX-1</i> character is included by <i>INDEX-2</i> is omitted. <p> <dt><i>WIDGET</i>&nbsp; <tt>text insert</tt>&nbsp <i>INDEX&nbsp TEXT</i><p> <dd><p> Inserts one or more characters immediately before the character whose index is given. <p> </dl> <dt><i>WIDGET</i>&nbsp <tt>token</tt>&nbsp <i>subcommand args...</i><p> <dd>There are several token commands. They all have the common property that they involve the list of tokens into which the HTML is parsed.<p> Some of the following subcommands make use of indices. The character number of these indices is ignored since these commands deal only with whole tokens. <p> <dl> <dt><i>WIDGET</i>&nbsp; <tt>token append</tt>&nbsp; <i>TAG&nbsp; ARGUMENTS</i><p> <dd> The command causes a token to be appended to the current list of tokens in the HTML widget. This command is typically used within a token handler. <p> <dt><i>WIDGET</i>&nbsp; <tt>token delete</tt>&nbsp; <i>INDEX&nbsp ?INDEX-2?</i><p> <dd> Deletes the single token indentified by the index. If a second index is given, the range of tokens from the first to the second index inclusive is deleted. <p> <dt><i>WIDGET</i>&nbsp; <tt>token find</tt>&nbsp; <i>TAG</i><p> <dd> Locates all tokens with the given <i>TAG</i> and returns them all as a list. Each element of the returned list is a sublist containing the index for the token and the arguments for the token. <p> <dt><i>WIDGET</i>&nbsp; <tt>token get</tt>&nbsp; <i>INDEX&nbsp ?INDEX-2?</i><p> <dd> Returns a list of tokens in the range of <i>INDEX</i> through <i>INDEX-2</i>. Each element of the list consists of the token tag followed by the token arguments. <p> <dt><i>WIDGET</i>&nbsp; <tt>token handler</tt>&nbsp; <i>TAG&nbsp; ?SCRIPT?</i><p> <dd> This command allows special processing to occur for selected tokens in the HTML input stream. The <i>TAG</i> argument is either ``Text'' or ``Space'' or the name of an HTML tag (ex: ``H3'' or ``/A''). If a non-empty script is specified for a particular tag, then when instances of that tag are encountered by the parser, the parser calls the corresponding script instead of appending the token to the end of the token list. Before calling the script, three arguments are appended: <ol> <li>The token number. <li>The tag. (ex: <tt>H3</tt>) <li>A list of name/value pairs describing all arguments to the tag. </ol> An empty handler script causes the default processing to occur for the tag. If the script argument is omitted all together, then the current value of the token handler for the given tag is returned. <p> Only one handler may be defined for each token type. If a new handler is specified for a token type that previously had a different handler defined, then the old handler is overwritten by the new. <p> <dt><i>WIDGET</i>&nbsp; <tt>token insert</tt>&nbsp; <i>INDEX&nbsp TAG&nbsp ARGUMENTS</i><p> <dd> Inserts a single token given by <i>TAG</i> and <i>ARGUMENTS</i> into the token list immediately before <i>INDEX</i>. <p> </dl> <p> <dt><i>WIDGET</i>&nbsp; <tt>xview</tt>&nbsp; <i>args...</i><p> <dd>Used to control horizontal scrolling.<p> <dl> <dt><i>WIDGET</i>&nbsp <tt>xview</tt><p> <dd>Returns a list containing two elements. The elements are a fractions between 0.0 and 1.0 that define the position of the left and right edges of the visible part of the document as a fraction of the whole.<p> <dt><i>WIDGET</i>&nbsp <tt>xview moveto</tt>&nbsp <i>FRACTION</i><p> <dd>Adjusts the horizontal position of the document so that <i>FRACTION</i> of the horizontal span of the document is off-screen to the left.<p> <dt><i>WIDGET</i>&nbsp <tt>xview scroll</i>&nbsp <i>NUMBER&nbsp WHAT</i><p> <dd> Shifts the view in the window left or right according to <i>NUMBER</i> and <i>WHAT</i>.&nbsp&nbsp <i>NUMBER</i> is an integer and <i>WHAT</i> is either <tt>units</tt> or <tt>pages</tt>.<p> </dl> <dt><i>WIDGET</i>&nbsp <tt>yview</tt>&nbsp; <i>args...</i><p> <dd>Used to control the vertical position of the document.<p> <dl> <dt><i>WIDGET</i>&nbsp <tt>yview</tt><p> <dd>Returns a list containing two elements. The elements are a fractions between 0.0 and 1.0 that define the position of the top and bottom edges of the visible part of the document as a fraction of the whole.<p> <dt><i>WIDGET</i>&nbsp <tt>yview</tt>&nbsp <i>NAME</i><p> <dd>Adjusts the vertical position of the document so that the tag ``<tt>&lt;a name=</tt><i>NAME</i><tt>&gt;</tt>'' is on screen, and preferably near the top of the screen.<p> <dt><i>WIDGET</i>&nbsp <tt>yview moveto</tt>&nbsp <i>FRACTION</i><p> <dd>Adjusts the horizontal position of the document so that <i>FRACTION</i> of the vertical span of the document is off-screen above the visible region.<p> <dt><i>WIDGET</i>&nbsp <tt>xview scroll</i>&nbsp; <i>NUMBER&nbsp; WHAT</i><p> <dd> Shifts the view in the window up or down according to <i>NUMBER</i> and <i>WHAT</i>.&nbsp&nbsp <i>NUMBER</i> is an integer and <i>WHAT</i> is either <tt>units</tt> or <tt>pages</tt>.<p> </dl> </dl> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/doc/simple.make�����������������������������������������������������������������0000644�0001750�0001750�00000003455�07504443344�016166� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # Trying to generate a loadable module for Tcl/Tk8.1.1 on # WindowsNT using Cygwin20 cross-compiler running under # RedHat6.0. # Step -1: # Make a copy of winsock.h into winsock2.h. "Winsock2.h" is needed by # tclWinPort.h. tclWinPort.h is included by tclStubLib.c in step 3. # # Step 0: # Make sure the cross-compiler tools are on PATH and remove # old files. # PATH=$PATH:/opt/cygwin20/bin rm -f simple.o stublib.o simple.dll # Step 1: # Generate the C source code into "simple.c" # cat >simple.c <<\END #include <tcl.h> int Simple_Init(Tcl_Interp *interp){ Tcl_InitStubs(interp,"8.1",0); Tk_InitStubs(interp,"8.1",0); return TCL_OK; } END # Step 2: # Compile the C source code yielding simple.o # i586-cygwin32-gcc \ -I/home/drh/tcltk/tcl8.1.1/generic \ -mno-cygwin \ -DUSE_TCL_STUBS=1 \ -c simple.c # Step 3: # Compile the Stub libraries yielding tclstub.o and tkstub.o # i586-cygwin32-gcc \ -I/home/drh/tcltk/tcl8.1.1/generic \ -I/home/drh/tcltk/tcl8.1.1/win \ -mno-cygwin \ -o tclstub.o \ -c /home/drh/tcltk/tcl8.1.1/generic/tclStubLib.c i586-cygwin32-gcc \ -I/home/drh/tcltk/tcl8.1.1/generic \ -I/home/drh/tcltk/tcl8.1.1/win \ -I/home/drh/tcltk/tk8.1.1/generic \ -I/home/drh/tcltk/tk8.1.1/win \ -I/home/drh/tcltk/tk8.1.1/xlib \ -mno-cygwin \ -o tkstub.o \ -c /home/drh/tcltk/tk8.1.1/generic/tkStubLib.c # Step 4: # Generate the DEF file # cat >simple.def <<\END EXPORTS Simple_Init END # Step 5: # Use dllwrap to build the DLL. Note: tclstub81.lib is copied out # of the binary tk8.1 distribution from Scriptics. # i586-cygwin32-dllwrap \ --def simple.def \ -v \ --driver-name i586-cygwin32-gcc \ --dlltool-name i586-cygwin32-dlltool \ --as i586-cygwin32-as \ --dllname simple.dll \ --target i386-mingw32 -mno-cygwin \ simple.o tclstub.o tkstub.o �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/doc/notes1.txt������������������������������������������������������������������0000644�0001750�0001750�00000002767�07504443344�016015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������The HTML widget uses lots of TCL callback routines. But a TCL callback can do nasty things. For example, a TCL callback could delete the HTML widget that invoked the callback. Or it could delete the TCL interpreter in which the HTML widget is running. So we have to call HtmlLock() before invoking a TCL callback and check to make sure the widget was not deleted before using any fields in the widget structure after the callback runs. The following routines can call TCL callbacks, either directly or indirectly: HtmlTokenizerAppend() HtmlParseCmd() HtmlWidgetCommand() HtmlGetImage() HtmlAddStyle() HtmlParseCmd()... HtmlSizer() HtmlLayout() HtmlRedrawCallback() GetLinkColor() HtmlAddStyle()... HtmlCallResolver() HtmlGetImage()... HtmlResolveCmd() HtmlWidgetCommand() HtmlRedrawCallback()... HtmlGetFont() DrawSelectionBackground() HtmlBlockDraw()... HtmlBlockDraw() HtmlRedrawCallback() FindIndexInBlock() DecodeBaseIndex() HtmlGetIndex() HtmlIndexCmd() HtmlWidgetCommand()... HtmlSelectionSetCmd() HtmlWidgetCommand()... HtmlInsertCmd() HtmlWidgetCommand()... Paragraph() DoBreakMarkup() HtmlLayoutBlock() HtmlLayout()... HtmlTableLayout() DoBreakMarkup()... HtmlDeleteControls() HtmlClear() HtmlWidgetCommand()... HtmlDestroyWidget() ���������./saods9/htmlwidget/webpage/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057636�014672� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/webpage/mkwebpage.tcl�����������������������������������������������������������0000644�0001750�0001750�00000013471�07504443354�017351� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/tclsh # # Construct the web page for tkhtml # # @(#) $Id: mkwebpage.tcl,v 1.1.1.1 2002/06/20 21:19:40 joye Exp $ # set p [open publish.sh w] puts $p "#!/bin/sh" puts $p "#" set SendList {} set f [open index.html w] puts $f { <html> <head> <title>An HTML Widget for Tcl/Tk</title> </head> <body bgcolor=white> <h1 align=center>An HTML Widget For Tcl/Tk</h1> } puts $f "<p align=center><i>Last update: [clock format [clock seconds]]</i></p>" puts $f { <p>"Tkhtml" is a Tcl/Tk widget that displays HTML. Tkhtml is implemented in C. It is a true widget, not a metawidget implemented using the Text or Canvas widgets of the Tcl/Tk core. Implementing Tkhtml in C gives it a number of advantages:</p> <p> <ul> <li> It runs fast and uses little memory.</li> <li> It supports smooth scrolling.</li> <li> It supports text wrap-around on images and tables.</li> <li> It has a full implementation of tables. Complex pages (such as <a href="http://www.scriptics.com/">http://www.scriptics.com/</a>) are displayed correctly.</li> <li> Supports forms. </li> <li> It supports the &lt;APPLET&gt;, &lt;SCRIPT&gt; and &lt;EMBED&gt;. (Partially. Full support is pending.) </li> <li> Support for frames is planned. </li> </ul> </p> <p>Tkhtml can be used with Tcl/Tk8.0 or later. The shared libraries use the new stubs mechanism, so you should be able to load Tkhtml with any version of "wish" beginning with 8.0.6.</p> <p>At the moment, there is not a lot of software that uses this widget. Tkhtml is not an application in and of itself. It is only a tool. But applications are being built around tkhtml. Check back later for new developments.</p> <h2>Mailing List!</h2> <p><font color=red><b><i>New!</i></b></font> A mailing list has been started for users of tkhtml. Sign up if you want to recieve notifications of updates or ask questions about using tkhtml.</p> <form method=GET action="http://www.egroups.com/subscribe"> <input type=hidden name="listname" value="tkhtml"> <input type=hidden name="SubmitAction" value="Subscribe"> <p>Enter your e-mail address below and click the button to sign up for the tkhtml mailing list:</p> <p> <table cellspacing=10> <tr><td valign=center> <input type=text name="emailaddr" value="your e-mail" size=21> </td><td valign=center> <input type=image border=0 alt="Click here to join tkhtml" name="Click here to join tkhtml" SRC="http://www.egroups.com/oems/default/languages/english/images/subscriptionBoxButton.gif"> </td></tr> </table> </p> <p>You can also view the <a href="http://www.egroups.com/group/tkhtml/">archives</a> for the mailing list. To post to this mailing list, send a message to <a href="mailto:tkhtml@eGroups.com">tkhtml@eGroups.com</a>. The mailing list is hosted by <a href="http://www.egroups.com/">eGroups.com</A> </p> </form> <h2>You Can Help!</h2> <p>If you would like to help, please consider contributing in the following ways:</p> <p> <ul> <li> Try out tkhtml on your computer and report bugs to <a href="mailto:drh@acm.org">drh@acm.org</a>. </li> <li> Fix bugs and send in patches. (Write access to the CVS repository may be granted to anyone who is serious about this.)</li> <li> Make suggestions for new features. </li> <li> Write applications that use tkhtml. </li> <li> Improve the documentation. </li> </ul> </p> <p>Any help you can provide is appreciated.</p> <h2>Getting The Widget</h2> <p>Visit the <a href="download.html">download</a> page for a list of files available for immediate download.</p> <p>You can now also obtain the latest tkhtml sources via anonymous CVS. To access the anonymous CVS server, first install CVS on your system. (See <a href="http://www.cyclic.com/">http://www.cyclic.com/</a> for additional information.) Then login as follows:</p> <blockquote><pre> cvs -d :pserver:cvs@xoli.dyn.dhs.org:/home/cvs/cvsroot login </pre></blockquote> <p>You will be prompted for a password. Use "<tt>cvs</tt>". After you get logged in successfully, you can check out the source tree like this:</p> <blockquote><pre> cvs -d :pserver:cvs@xoli.dyn.dhs.org:/home/cvs/cvsroot checkout htmlwidget </pre></blockquote> <p>This command creates a directory named "<tt>htmlwidget</tt>" and fills it with the latest version of the sources.</p> </body> </html> } close $f lappend SendList index.html set f [open download.html w] puts $f { <html> <head> <title>TkHtml Download Page</title> </head> <body bgcolor=white> <h1 align=center>TkHtml Download Page</h1> } puts $f "<p align=center><i>Last update: [clock format [clock seconds]]</i></p>" puts $f { <p>The files shown below are available for download. For the very latest sources, visit the anonymous CVS server. Instructions for reaching the anonymous CVS server are on the tkhtml <a href="index.html">homepage</a>.</p> <ul> } foreach {file desc} { tkhtml.tar.gz {A tarball containing all the latest source code} hv.tcl.gz {The "Html Viewer" example application} spec.html {A raw specification of how the tkhtml widget works} tkhtml.so.gz {Shared library suitable for use on Linux} tkhtml.dll.zip {A DLL suitable for use on Windows95/98/NT/2K} } { if {![file readable $file]} continue lappend SendList $file puts $f "<li><p><a href=\"$file\">$file</a><br>" puts $f "Description: $desc<br>" puts $f "Size: [file size $file] bytes<br>" puts $f "Last modified: [clock format [file mtime $file]]" switch -glob -- $file { *.zip - *.gz {set access zcat} default {set access cat} } if {![catch {exec $access $file | ident | grep {$Id: }} ident]} { puts $f "<br>Version information:" puts $f "<pre>\n$ident</pre>" } puts $f "</p></li>\n" } puts $f { </ul> <p><a href="index.html">Back</a> to the tkhtml home page</p> </body> </html> } close $f lappend SendList download.html puts $p "scp [lsort $SendList] hwaci@oak.he.net:public_html/sw/tkhtml" close $p �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014400� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/url.c���������������������������������������������������������������������0000644�0001750�0001750�00000015401�07504443354�015372� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** This file contains code use for resolving relative URLs */ #include <stdlib.h> #include "url.h" #if INTERFACE /* ** A parsed URI is held in an instance of the following structure. ** Each component is recorded in memory obtained from malloc(). ** ** The examples are from the URI ** ** http://192.168.1.1:8080/cgi-bin/printenv?name=xyzzy&addr=none#frag */ typedef struct Url Url; struct Url { char *zScheme; /* Ex: "http" */ char *zAuthority; /* Ex: "192.168.1.1:8080" */ char *zPath; /* Ex: "cgi-bin/printenv" */ char *zQuery; /* Ex: "name=xyzzy&addr=none" */ char *zFragment; /* Ex: "frag" */ }; #endif /* ** Return the length of the next component of the URL in z[] given ** that the component starts at z[0]. The initial sequence of the ** component must be zInit[]. The component is terminated by any ** character in zTerm[]. The length returned is 0 if the component ** doesn't exist. The length includes the zInit[] string, but not ** the termination character. ** ** Component zInit zTerm ** ---------- ------- ------- ** scheme "" ":/?#" ** authority "//" "/?#" ** path "/" "?#" ** query "?" "#" ** fragment "#" "" */ static int ComponentLength(const char *z, const char *zInit, const char *zTerm){ int i, n; for(n=0; zInit[n]; n++){ if( zInit[n]!=z[n] ) return 0; } while( z[n] ){ for(i=0; zTerm[i]; i++){ if( z[n]==zTerm[i] ) return n; } n++; } return n; } /* ** Duplicate a string of length n. */ static char *StrNDup(const char *z, int n){ char *zResult; if( n<=0 ){ n = strlen(z); } zResult = malloc( n + 1 ); if( zResult ){ memcpy(zResult, z, n); zResult[n] = 0; } return zResult; } /* ** Parse a text URI into an Url structure. */ Url *ParseUrl(const char *zUri){ Url *p; int n; p = malloc( sizeof(*p) ); if( p==0 ) return 0; memset(p, 0, sizeof(*p)); if( zUri==0 || zUri[0]==0 ) return p; while( isspace(zUri[0]) ){ zUri++; } n = ComponentLength(zUri, "", ":/?# "); if( n>0 && zUri[n]==':' ){ p->zScheme = StrNDup(zUri, n); zUri += n+1; } n = ComponentLength(zUri, "//", "/?# "); if( n>0 ){ p->zAuthority = StrNDup(&zUri[2], n-2); zUri += n; } n = ComponentLength(zUri, "", "?# "); if( n>0 ){ p->zPath = StrNDup(zUri, n); zUri += n; } n = ComponentLength(zUri, "?", "# "); if( n>0 ){ p->zQuery = StrNDup(&zUri[1], n-1); zUri += n; } n = ComponentLength(zUri, "#", " "); if( n>0 ){ p->zFragment = StrNDup(&zUri[1], n-1); } return p; } /* ** Delete an Url structure. */ void FreeUrl(Url *p){ if( p==0 ) return; if( p->zScheme ) free(p->zScheme); if( p->zAuthority ) free(p->zAuthority); if( p->zPath ) free(p->zPath); if( p->zQuery ) free(p->zQuery); if( p->zFragment ) free(p->zFragment); free(p); } /* ** Create a string to hold the given URI. Memory to hold the string ** is obtained from malloc() and must be freed by the calling ** function. */ char *BuildUrl(Url *p){ int n = 1; char *z; if( p->zScheme ) n += strlen(p->zScheme)+1; if( p->zAuthority ) n += strlen(p->zAuthority)+2; if( p->zPath ) n += strlen(p->zPath)+1; if( p->zQuery ) n += strlen(p->zQuery)+1; if( p->zFragment ) n += strlen(p->zFragment)+1; z = malloc( n ); if( z==0 ) return 0; n = 0; if( p->zScheme ){ sprintf(z, "%s:", p->zScheme); n = strlen(z); } if( p->zAuthority ){ sprintf(&z[n], "//%s", p->zAuthority); n += strlen(&z[n]); } if( p->zPath ){ sprintf(&z[n], "%s", p->zPath); n += strlen(&z[n]); } if( p->zQuery ){ sprintf(&z[n], "?%s", p->zQuery); n += strlen(&z[n]); } if( p->zFragment ){ sprintf(&z[n], "#%s", p->zFragment); } return z; } /* ** Replace the string in *pzDest with the string in zSrc */ static void ReplaceStr(char **pzDest, const char *zSrc){ if( *pzDest!=0 ) free(*pzDest); if( zSrc==0 ){ *pzDest = 0; }else{ *pzDest = StrNDup(zSrc, -1); } } /* ** Remove leading and trailing spaces from the given string. Return ** a new string obtained from malloc(). */ static char *Trim(char *z){ int i; char *zNew; while( isspace(*z) ) z++; i = strlen(z); zNew = malloc( i+1 ); if( zNew==0 ) return 0; strcpy(zNew, z); if( i>0 && isspace(zNew[i-1]) ){ i--; zNew[i] = 0; } return zNew; } /* ** Resolve a sequence of URLs. Return the result in space obtained ** from malloc(). */ char *ResolveUrl( char *zBase, /* The base URL */ const char **azSeries /* A list of relatives. NULL terminated */ ){ Url *base; Url *term; char *z; base = ParseUrl(zBase); while( azSeries[0] ){ term = ParseUrl(azSeries[0]); azSeries++; if( term->zScheme==0 && term->zAuthority==0 && term->zPath==0 && term->zQuery==0 && term->zFragment ){ ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zScheme ){ Url temp; temp = *term; *term = *base; *base = temp; }else if( term->zAuthority ){ ReplaceStr(&base->zAuthority, term->zAuthority); ReplaceStr(&base->zPath, term->zPath); ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zPath && term->zPath[0]=='/' ){ ReplaceStr(&base->zPath, term->zPath); ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); }else if( term->zPath && base->zPath ){ char *zBuf; int i, j; zBuf = malloc( strlen(base->zPath) + strlen(term->zPath) + 2 ); if( zBuf ){ sprintf(zBuf,"%s", base->zPath); for(i=strlen(zBuf)-1; i>=0 && zBuf[i]!='/'; i--){ zBuf[i] = 0; } strcat(zBuf, term->zPath); for(i=0; zBuf[i]; i++){ if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='/' ){ strcpy(&zBuf[i+1], &zBuf[i+3]); i--; continue; } if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]==0 ){ zBuf[i+1] = 0; continue; } if( i>0 && zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='.' && (zBuf[i+3]=='/' || zBuf[i+3]==0) ){ for(j=i-1; j>=0 && zBuf[j]!='/'; j--){} if( zBuf[i+3] ){ strcpy(&zBuf[j+1], &zBuf[i+4]); }else{ zBuf[j+1] = 0; } i = j-1; if( i<-1 ) i = -1; continue; } } free(base->zPath); base->zPath = zBuf; } ReplaceStr(&base->zQuery, term->zQuery); ReplaceStr(&base->zFragment, term->zFragment); } FreeUrl(term); } z = BuildUrl(base); FreeUrl(base); return z; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/mktclapp.c����������������������������������������������������������������0000644�0001750�0001750�00000313017�07504443354�016407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** Copyright (c) 1998, 1999 D. Richard Hipp ** ** 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 library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** Author contact information: ** drh@acm.org ** http://www.hwaci.com/drh/ */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #if defined(_WIN32) || defined(WIN32) # include <windows.h> # if !defined(R_OK) # define R_OK 4 # endif #else # include <unistd.h> #endif #include <time.h> #include <assert.h> /* ** Version information for this program */ static char zVersion[] = "mktclapp version 3.5. July 5, 1999"; /* ** Each new TCL commands discovered while scanning C/C++ source code is ** stored in an instance of the following structure. */ typedef struct EtCmd EtCmd; struct EtCmd { char *zIf; /* Surrounding #if statement */ char *zName; /* Name of the command */ int isObj; /* True if this is a Tcl_Obj command */ EtCmd *pNext; /* Next command on a list of them all */ }; /* ** This is a list of all TCL commands in the scanned source */ static EtCmd *cmdList = 0; /* ** Number of commands and object commands. */ static int nCmd = 0; static int nObjCmd = 0; /* ** Each nested "#if" statement is stored as an instance of the ** following structure. */ typedef struct IfStmt IfStmt; struct IfStmt { char *zArg; /* Argument to the #if. Ex: "defined(DEBUG)" */ int invert; /* True to put a "!" in front */ int line; /* Line number of the original #if */ IfStmt *pNext; /* Next #if statement down on the stack */ }; /* ** The nested #if statements */ static IfStmt *ifStack = 0; /* ** Name of this program. */ static char *Argv0 = "mktclapp"; /* ** Number of errors */ static int nError = 0; /* ** Surround the call to Et_AppInit() with this #if */ static char *seenEtAppInit = "0"; /* ** Surround the call to Et_PreInit() with this #if */ static char *seenEtPreInit = "0"; /* ** Surround the implmentation of main() with the inverse of this #if */ static char *seenMain = "0"; /* ** Allocate memory. Never fail. If not enough memory is available, ** print an error message and abort. */ void *SafeMalloc(int nByte){ void *p = malloc(nByte); if( p==0 ){ fprintf(stderr,"Out of memory. Can't allocate %d bytes\n", nByte); exit(1); } memset(p, 0, nByte); return p; } void *SafeRealloc(void *old, int nByte){ void *p; if( old==0 ) return SafeMalloc(nByte); p = realloc(old, nByte); if( p==0 ){ fprintf(stderr,"Out of memory. Can't allocate %d bytes\n", nByte); exit(1); } return p; } /* ** The opposite of SafeMalloc(). Free memory previously obtained. */ void SafeFree(void *pMem){ if( pMem ) free(pMem); } /* ** Return TRUE if the given character can be part of a C identifier. */ static int IsIdent(int c){ return isalnum(c) || c=='_'; } /* ** Create an "#if" argument that captures the state of all nested ** "#if" statements, ORed with "zExtra". Space to hold ** the returned string is obtained from SafeMalloc and must be ** freed by the calling function. ** ** If the conditional is always TRUE, then NULL is returned. */ static char *IfString(char *zExtra){ int len = 0; IfStmt *p; char *z; int i; int isStackTrue = 1; int isStackFalse = 0; int isExtraFalse = 0; char *zSep; IfStmt *altStack; if( zExtra && *zExtra ){ if( zExtra[1]==0 && zExtra[0]=='0' ){ isExtraFalse = 1; }else if( zExtra[1]==0 && zExtra[0]=='1' ){ return 0; } len = strlen(zExtra) + 10; }else{ len = 1; isExtraFalse = 1; } for(p=ifStack; p; p=p->pNext){ len += strlen(p->zArg) + 6; if( p->zArg[0]=='0' && p->zArg[1]==0 ){ if( !p->invert ){ isStackFalse = 1; isStackTrue = 0; break; } }else if( p->zArg[0]=='1' && p->zArg[1]==0 ){ if( p->invert ){ isStackFalse = 1; isStackTrue = 0; break; } }else{ isStackTrue = 0; } } if( isStackTrue ){ return 0; }else if( isStackFalse && isExtraFalse ){ z = SafeMalloc( 2 ); strcpy(z,"0"); return z; } z = SafeMalloc( len ); if( !isExtraFalse ){ sprintf(z,"(%s) || (",zExtra); i = strlen(z); }else{ i = 0; } zSep = ""; altStack = 0; while( ifStack ){ p = ifStack; ifStack = p->pNext; p->pNext = altStack; altStack = p; } for(p=altStack; p; p=p->pNext){ if( p->zArg[0]=='0' && p->zArg[1]==0 && p->invert ) continue; if( p->zArg[0]=='1' && p->zArg[1]==0 && !p->invert ) continue; if( p->invert ){ sprintf(&z[i],"%s!%s",zSep,p->zArg); }else{ sprintf(&z[i],"%s%s",zSep,p->zArg); } i += strlen(&z[i]); zSep = " && "; } while( altStack ){ p = altStack; altStack = p->pNext; p->pNext = ifStack; ifStack = p; } if( !isExtraFalse ){ sprintf(&z[i],")"); } return z; } /* ** Push a new "#if" onto the if stack. */ static void PushIf(char *zArg, int line, int isNegated, int isDefined){ char *z; IfStmt *p; if( !isDefined ){ int i; z = SafeMalloc( strlen(zArg) + 3 ); for(i=0; zArg[i] && IsIdent(zArg[i]); i++){} if( zArg[i]==0 ){ sprintf(z,"%s",zArg); }else{ sprintf(z,"(%s)",zArg); } }else{ z = SafeMalloc( strlen(zArg) + 10 ); sprintf(z,"defined(%s)",zArg); } p = SafeMalloc( sizeof(IfStmt) ); p->zArg = z; p->line = line; p->invert = isNegated; p->pNext = ifStack; ifStack = p; } /* ** Extract the argument to an #if. Remove all leading and trailing ** space. */ static char *GetArg(const char *fileName, char *z, int *pI, int *pLine){ int i = *pI; int line = *pLine; int start; char *zResult; int j, k; while( isspace(z[i]) && z[i]!='\n' ){ i++; } start = i; if( z[i]=='\n' || z[i]==0 ){ fprintf(stderr,"%s: Missing argument to \"#if\" on line %d\n", fileName, *pLine); nError++; line++; }else{ while( z[i] && z[i]!='\n' ){ if( z[i]=='\\' && z[i+1]!=0 ){ i++; } if( z[i]=='\n' ){ line++; } i++; } } zResult = SafeMalloc( i + 1 - start ); for(j=0, k=start; k<i; k++){ if( isspace(z[k]) && j>0 && isspace(zResult[j-1]) ){ /* Do nothing */ }else if( z[k]=='\\' && z[k+1]=='\n' ){ if( j>0 && !isspace(zResult[j-1]) ){ zResult[j++] = ' '; } k++; }else if( z[k]=='\\' ){ zResult[j++] = z[k++]; } zResult[j++] = z[k]; } zResult[j] = 0; while( j>0 && isspace(zResult[j-1]) ){ j--; zResult[j] = 0; } *pI = i; *pLine = line; return zResult; } /* ** Read the complete text of a file into memory. Return 0 if there ** is any kind of error. */ char *ReadFileIntoMemory(const char *fileName){ FILE *in; /* Input file stream */ char *textBuf; /* A buffer in which to put entire text of input */ int toRead; /* Amount of input file read to read */ int got; /* Amount read so far */ struct stat statBuf; /* Status buffer for the file */ if( stat(fileName,&statBuf)!=0 ){ fprintf(stderr,"%s: no such file: %s\n", Argv0, fileName); return 0; } textBuf = SafeMalloc( statBuf.st_size + 1 ); in = fopen(fileName,"rb"); if( in==0 ){ fprintf(stderr,"%s: can't open for reading: %s\n", Argv0, fileName); SafeFree(textBuf); return 0; } textBuf[statBuf.st_size] = 0; toRead = statBuf.st_size; got = 0; while( toRead ){ int n = fread(&textBuf[got],1,toRead,in); if( n<=0 ) break; toRead -= n; got += n; } fclose(in); textBuf[got] = 0; return textBuf; } /* ** Given the "aaaa" part of the name of an ET_COMMAND_aaaa function, ** compute the name of the corresponding Tcl command. ** ** The name is usually the same, except if there are two underscores ** in the middle of the command, they are changed to colons. This ** feature allows namespaces to be used. Example: The function ** named ** ** ET_COMMAND_space1__proc1(ET_TCLARGS){...} ** ** will generate a TCL command called ** ** space1::proc1 ** ** Space to hold the TCL command name is obtained from malloc(). */ static char *FuncToProc(char *zFunc){ char *zProc; int i; zProc = SafeMalloc( strlen(zFunc) + 1 ); strcpy(zProc, zFunc); for(i=0; zProc[i]; i++){ if( i>0 && zProc[i]=='_' && zProc[i+1]=='_' && isalnum(zProc[i-1]) && isalnum(zProc[i+2]) ){ zProc[i] = ':'; zProc[i+1] = ':'; } } return zProc; } /* ** Scan a source file looking for new TCL commands and/or the Et_AppInit() ** or Et_PreInit() functions. ** ** Skip all comments, and any text contained within "#if 0".."#endif" */ void ScanFile(const char *fileName){ char *z; /* Complete text of the file, NULL terminated. */ int i, j; int inBrace = 0; int line = 1; z = ReadFileIntoMemory(fileName); if( z==0 ){ nError++; return; } for(i=0; z[i]; i++){ switch( z[i] ){ case '\n': line++; break; case '/': /* This might be a comment. If it is, skip it. */ if( z[i+1]=='*' ){ int start = line; i += 2; while( z[i] && (z[i]!='*' || z[i+1]!='/') ){ if( z[i]=='\n' ) line++; i++; } if( z[i]==0 ){ fprintf(stderr,"%s: Unterminated comment beginning on line %d\n", fileName, start); nError++; }else{ i++; } }else if( z[i+1]=='/' ){ while( z[i] && z[i]!='\n' ){ i++; } if( z[i] ){ line++; }; } break; case '\'': { /* Skip character literals */ int start = line; for(i++; z[i] && z[i]!='\''; i++){ if( z[i]=='\n' ){ fprintf(stderr,"%s: Newline in character literal on line %d\n", fileName, start); line++; } if( z[i]=='\\' ) i++; } if( z[i]==0 ){ fprintf(stderr,"%s: unterminate character literal on line %d\n", fileName, start); nError++; } break; } case '"': { /* Skip over a string */ int start = line; for(i++; z[i] && z[i]!='"'; i++){ if( z[i]=='\n' ){ fprintf(stderr,"%s: Newline in string literal on line %d\n", fileName, start); line++; } if( z[i]=='\\' ) i++; } if( z[i]==0 ){ fprintf(stderr,"%s: unterminate string literal on line %d\n", fileName, start); nError++; } break; } case '#': /* This might be a preprocessor macro such as #if 0 or #endif */ if( i>0 && z[i-1]!='\n' ) break; for(j=i+1; isspace(z[j]); j++){} if( strncmp(&z[j],"endif",5)==0 ){ if( ifStack==0 ){ fprintf(stderr,"%s: Unmatched \"#endif\" on line %d\n", fileName, line); nError++; }else{ IfStmt *p = ifStack; ifStack = p->pNext; SafeFree(p->zArg); SafeFree(p); } break; } if( strncmp(&z[j],"else",4)==0 ){ if( ifStack==0 ){ fprintf(stderr,"%s: No \"#if\" to pair with \"#else\" on line %d\n", fileName, line); nError++; }else{ ifStack->invert = !ifStack->invert; } break; } if( z[j]!='i' || z[j+1]!='f' ) break; if( strncmp(&z[j+2],"ndef",4)==0 ){ char *zArg; int start = line; i = j+6; zArg = GetArg(fileName, z,&i,&line); PushIf(zArg,start,1,1); SafeFree(zArg); }else if( strncmp(&z[j+2],"def",3)==0 ){ char *zArg; int start = line; i = j+5; zArg = GetArg(fileName,z,&i,&line); PushIf(zArg,start,0,1); SafeFree(zArg); }else{ char *zArg; int start = line; i = j+2; zArg = GetArg(fileName,z,&i,&line); PushIf(zArg,start,0,0); SafeFree(zArg); } break; case '{': inBrace++; break; case '}': inBrace--; break; case 'm': /* Check main() */ if( inBrace>0 ) break; if( i>0 && IsIdent(z[i-1]) ) break; if( strncmp(&z[i],"main",4)==0 && !IsIdent(z[i+4]) ){ seenMain = IfString(seenMain); } case 'E': /* Check ET_COMMAND_... or Et_AppInit or Et_PreInit */ if( inBrace>0 ) break; if( i>0 && IsIdent(z[i-1]) ) break; if( z[i+1]=='T' && strncmp(&z[i],"ET_COMMAND_",11)==0 ){ EtCmd *p; for(j=i+11; IsIdent(z[j]); j++){} p = SafeMalloc( sizeof(EtCmd) ); p->zIf = IfString(0); p->zName = SafeMalloc( j-(i+9) ); sprintf(p->zName,"%.*s",j-(i+11),&z[i+11]); p->pNext = cmdList; cmdList = p; nCmd++; }else if( z[i+1]=='T' && strncmp(&z[i],"ET_OBJCOMMAND_",14)==0 ){ EtCmd *p; for(j=i+14; IsIdent(z[j]); j++){} p = SafeMalloc( sizeof(EtCmd) ); p->zIf = IfString(0); p->zName = SafeMalloc( j-(i+9) ); p->isObj = 1; sprintf(p->zName,"%.*s",j-(i+14),&z[i+14]); p->pNext = cmdList; cmdList = p; nObjCmd++; }else if( z[i+1]=='t' ){ if( strncmp(&z[i],"Et_AppInit",10)==0 && !IsIdent(z[i+10]) ){ seenEtAppInit = IfString(seenEtAppInit); } if( strncmp(&z[i],"Et_PreInit",10)==0 && !IsIdent(z[i+10]) ){ seenEtPreInit = IfString(seenEtPreInit); } } break; default: /* Do nothing. Continue to the next character */ break; } } SafeFree(z); while( ifStack ){ IfStmt *p = ifStack; fprintf(stderr,"%s: unterminated \"#if\" on line %d\n", fileName, p->line); nError++; ifStack = p->pNext; SafeFree(p->zArg); SafeFree(p); } } /* ** Set a macro according to the value of an #if argument. */ static void SetMacro(char *zMacroName, char *zIf){ if( zIf==0 || *zIf==0 ){ printf("#define %s 1\n",zMacroName); }else if( zIf[0]=='0' && zIf[1]==0 ){ printf("#define %s 0\n",zMacroName); }else{ printf( "#if %s\n" "# define %s 1\n" "#else\n" "# define %s 0\n" "#endif\n", zIf, zMacroName, zMacroName ); } } /* ** Look at the name of the file given and see if it is a Tcl file ** or a C or C++ source file. Return TRUE for TCL and FALSE for ** C or C++. */ static int IsTclFile(char *zFile){ static char *azCSuffix[] = { ".c", ".cc", ".C", ".cpp", ".CPP", ".cxx", ".CXX" }; int len = strlen(zFile); int i; for(i=0; i<sizeof(azCSuffix)/sizeof(azCSuffix[0]); i++){ int len2 = strlen(azCSuffix[i]); if( len>len2 && strcmp(&zFile[len-len2],azCSuffix[i])==0 ){ return 0; } } return 1; } /* ** Compress a TCL script by removing comments and excess white-space */ static void CompressTcl(char *z){ int i, j, c; int atLineStart = 1; for(i=j=0; (c=z[i])!=0; i++){ switch( c ){ case ' ': case '\t': if( atLineStart ){ c = 0; } break; case '#': if( atLineStart && !isalpha(z[i+1]) ){ while( z[i] && z[i]!='\n' ){ i++; } c = 0; if( z[i]==0 ){ i--; } }else{ atLineStart = 0; } break; case '\n': if( atLineStart ){ c = 0; }else{ atLineStart = 1; } break; default: atLineStart = 0; break; } if( c!=0 ){ z[j++] = c; } } z[j] = 0; } /* ** Write the text of the given file as a string. Tcl-style comments ** are removed if the doCompress flag is true. */ static void WriteAsString(char *z, int shroud){ int c; int xor; int atLineStart = 1; if( shroud>0 ){ xor = shroud; } putchar('"'); atLineStart = 0; while( (c=*z)!=0 ){ z++; if( c=='\r' && *z=='\n' ) continue; if( shroud>0 && c>=0x20 ){ c ^= xor; xor = (xor+1)&0x1f; } if( atLineStart ){ putchar('"'); atLineStart = 0; } switch( c ){ case '"': case '\\': putchar('\\'); putchar(c); break; case '\n': putchar('\\'); putchar('n'); putchar('"'); putchar('\n'); atLineStart = 1; break; default: if( c<' ' || c>'~' ){ putchar('\\'); putchar( ((c>>6)&3) + '0' ); putchar( ((c>>3)&7) + '0' ); putchar( (c&7) + '0' ); }else{ putchar(c); } break; } } if( !atLineStart ){ putchar('"'); putchar('\n'); } } /* ** The header string. */ static char zHeader[] = "/* Automatically generated code */\n" "/* DO NOT EDIT */\n" "#ifndef ET_TCLARGS\n" "#include <tcl.h>\n" "#ifdef __cplusplus\n" "# define ET_EXTERN extern \"C\"\n" "#else\n" "# define ET_EXTERN extern\n" "#endif\n" "ET_EXTERN char *mprintf(const char*,...);\n" "ET_EXTERN char *vmprintf(const char*,...);\n" "ET_EXTERN int Et_EvalF(Tcl_Interp*,const char *,...);\n" "ET_EXTERN int Et_GlobalEvalF(Tcl_Interp*,const char *,...);\n" "ET_EXTERN int Et_DStringAppendF(Tcl_DString*,const char*,...);\n" "ET_EXTERN int Et_ResultF(Tcl_Interp*,const char*,...);\n" "ET_EXTERN Tcl_Interp *Et_Interp;\n" "#if TCL_RELEASE_VERSION>=8\n" "ET_EXTERN int Et_AppendObjF(Tcl_Obj*,const char*,...);\n" "#endif\n" "#define ET_TCLARGS " "ClientData clientData,Tcl_Interp*interp,int argc,char**argv\n" "#define ET_OBJARGS " "ClientData clientData,Tcl_Interp*interp,int objc,Tcl_Obj *CONST objv[]\n" "#endif\n" ; /* ** Print a usage comment and die */ static void Usage(char *argv0){ fprintf(stderr,"Usage: %s arguments...\n", argv0); fprintf(stderr, " -header print a header file and exit\n" " -srcdir DIR Prepend DIR to all relative pathnames\n" " -version print the version number of mktclapp and exit\n" " -notk built a Tcl-only program. No GUI\n" " -autofork automatically fork the program into the background\n" " -strip-tcl remove comments and extra white-space from\n" " subsequent TCL files\n" " -dont-strip-tcl stop stripping TCL files\n" " -tcl-library directory holding the TCL script library\n" " -tk-library directory holding the TK script library\n" " -main-script FILE run the script FILE after initialization\n" " -read-stdin read standard input\n" " -console create a console window\n" " -shroud hide compile-in TCL from view\n" " -enable-obj use TCL Obj commands where possible\n" " -standalone make the \"source\" TCL command only work\n" " for builtin scripts\n" " -f FILE read more command-line parameters from FILE\n" " *.c scan this file for new TCL commands\n" " *.tcl compile this file into the generated C code\n" ); exit(1); } /* ** Read one or more characters form "in" that follow a \ and ** interpret them appropriately. Return the character that ** results from this interpretation. */ static int EscapeChar(FILE *in){ int c, d; c = getc(in); switch( c ){ case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 'f': c = '\f'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; case 'a': c = '\a'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; d = getc(in); if( d<'0' || d>'7' ){ ungetc(d,in); break; } c = (c<<3) + (d - '0'); if( d<'0' || d>'7' ){ ungetc(d,in); break; } c = (c<<3) + (d - '0'); break; default: break; } return c; } /* MS-Windows and MS-DOS both have the following serious OS bug: the ** length of a command line is severely restricted. But this program ** occasionally requires long command lines. Hence the following ** work around. ** ** If the parameters "-f FILENAME" appear anywhere on the command line, ** then the named file is scanned for additional command line arguments. ** These arguments are substituted in place of the "FILENAME" argument ** in the original argument list. ** ** This first parameter to this routine is the index of the "-f" ** parameter in the argv[] array. The argc and argv are passed by ** pointer so that they can be changed. ** ** Parsing of the parameters in the file is very simple. Parameters ** can be separated by any amount of white-space (including newlines ** and carriage returns.) " and ' can be used for quoting strings ** with embedded spaces. The \ character escapes the following character. ** The length of a token is limited to about 1000 characters. */ static void AddParameters(int index, int *pArgc, char ***pArgv){ int argc = *pArgc; /* The original argc value */ char **argv = *pArgv; /* The original argv value */ int newArgc; /* Value for argc after inserting new arguments */ char **zNew; /* The new argv after this routine is done */ char *zFile; /* Name of the input file */ int nNew = 0; /* Number of new entries in the argv[] file */ int nAlloc = 0; /* Space allocated for zNew[] */ int i; /* Loop counter */ int n; /* Number of characters in a new argument */ int c; /* Next character of input */ int startOfLine = 1; /* True if we are where '#' can start a comment */ FILE *in; /* The input file */ char zBuf[1000]; /* A single argument is accumulated here */ if( index+1==argc ) return; zFile = argv[index+1]; in = fopen(zFile,"r"); if( in==0 ){ fprintf(stderr,"Can't open input file \"%s\"\n",zFile); exit(1); } c = ' '; while( c!=EOF ){ while( c!=EOF && isspace(c) ){ if( c=='\n' ){ startOfLine = 1; } c = getc(in); if( startOfLine && c=='#' ){ while( c!=EOF && c!='\n' ){ c = getc(in); } } } n = 0; if( c=='\'' || c=='"' ){ int quote = c; c = getc(in); startOfLine = 0; while( c!=EOF && c!=quote ){ if( c=='\\' ) c = EscapeChar(in); if( n<sizeof(zBuf)-1 ){ zBuf[n++] = c; } c = getc(in); } if( c!=EOF ) c = getc(in); }else{ while( c!=EOF && !isspace(c) ){ if( c=='\\' ) c = EscapeChar(in); if( n<sizeof(zBuf)-1 ){ zBuf[n++] = c; } startOfLine = 0; c = getc(in); } } zBuf[n] = 0; if( n>0 ){ nNew++; if( nNew + argc >= nAlloc ){ if( nAlloc==0 ){ nAlloc = 100 + argc; zNew = malloc( sizeof(char*) * nAlloc ); }else{ nAlloc *= 2; zNew = realloc( zNew, sizeof(char*) * nAlloc ); } } if( zNew ){ int j = nNew + index; zNew[j] = malloc( n + 1 ); if( zNew[j] ){ strcpy( zNew[j], zBuf ); } } } } if( nNew>0 ){ newArgc = argc + nNew - 1; for(i=0; i<=index; i++){ zNew[i] = argv[i]; } }else{ zNew = argv; } for(i=nNew + index + 1; i<newArgc; i++){ zNew[i] = argv[i + 1 - nNew]; } zNew[newArgc] = 0; *pArgc = newArgc; *pArgv = zNew; } int main(int argc, char **argv){ int i; /* Loop counter */ EtCmd *pCmd; /* A new TCL command found in C code */ int useTk = 1; /* False if the -notk flag is used */ int autoFork = 0; /* True if the -autofork flag is used */ int nTcl = 0; /* Number of TCL scripts */ char **azTcl; /* Name of all TCL scripts */ int *aDoCompress; /* Whether or not to compress each TCL script */ int doCompress = 1; /* Current state of the compression flag */ char *zTclLib = 0; /* Name of the TCL library */ char *zTkLib = 0; /* Name of the TK library */ char *zMainScript = 0; /* Name of a script to run first */ int shroud = 0; /* True to encrypt the compiled-in TCL */ int readStdin = 0; /* True to read TCL commands from STDIN */ int enableObj = 0; /* Enable the use of object commands */ int standalone = 0; /* True to disable the "source" command */ int stringify = 0; /* True to output only strings of the scripts */ int console = 0; /* True to put up a debugging console */ int nHash; /* Number of entries in hash table */ extern char zTail[]; if( argc>=2 && strcmp(argv[1],"-header")==0 ){ printf("%s",zHeader); return 0; } if( argc>=2 && strcmp(argv[1],"-version")==0 ){ printf("%s\n",zVersion); return 0; } azTcl = SafeMalloc( sizeof(char*)*(argc + 100) ); aDoCompress = SafeMalloc( sizeof(int)*(argc + 100) ); for(i=1; i<argc; i++){ if( argv[i][0]=='-' ){ if( strcmp(argv[i],"-header")==0 ){ printf("%s",zHeader); return 0; }else if( strcmp(argv[i],"-notk")==0 ){ useTk = 0; }else if( strcmp(argv[i],"-autofork")==0 ){ autoFork = 1; }else if( strcmp(argv[i],"-read-stdin")==0 ){ readStdin = 1; }else if( strcmp(argv[i],"-console")==0 ){ console = 1; }else if( strcmp(argv[i],"-shroud")==0 ){ shroud = 1; }else if( strcmp(argv[i],"-strip-tcl")==0 ){ doCompress = 1; }else if( strcmp(argv[i],"-dont-strip-tcl")==0 ){ doCompress = 0; }else if( strcmp(argv[i],"-enable-obj")==0 ){ enableObj = 1; }else if( strcmp(argv[i],"-standalone")==0 ){ standalone = 1; }else if( strcmp(argv[i],"-stringify")==0 ){ stringify = 1; }else if( i<argc-1 && strcmp(argv[i],"-srcdir")==0 ){ chdir(argv[++i]); }else if( i<argc-1 && strcmp(argv[i],"-main-script")==0 ){ zMainScript = argv[++i]; }else if( i<argc-1 && strcmp(argv[i],"-tcl-library")==0 ){ zTclLib = argv[++i]; }else if( i<argc-1 && strcmp(argv[i],"-tk-library")==0 ){ zTkLib = argv[++i]; }else if( strcmp(argv[i],"-f")==0 ){ AddParameters(i, &argc, &argv); azTcl = SafeRealloc(azTcl, sizeof(char*)*(argc + 100) ); aDoCompress = SafeRealloc(aDoCompress, sizeof(int)*(argc + 100) ); }else{ Usage(argv[0]); } }else if( IsTclFile(argv[i]) ){ if( access(argv[i],R_OK) ){ fprintf(stderr,"%s: can't open \"%s\" for reading\n", Argv0, argv[i]); nError++; }else{ int len = strlen(argv[i]); azTcl[nTcl] = argv[i]; if( len>=9 && strcmp(&argv[i][len-9],"/tclIndex")==0 ){ aDoCompress[nTcl] = 0; }else{ aDoCompress[nTcl] = doCompress; } nTcl++; } }else{ ScanFile(argv[i]); } } if( nError>0 ) return nError; if( stringify ){ for(i=0; i<nTcl; i++){ char *z; z = ReadFileIntoMemory(azTcl[i]); if( z==0 ) continue; if( aDoCompress[i] ) CompressTcl(z); WriteAsString(z,shroud); printf(";\n"); SafeFree(z); } return 0; } if( nObjCmd>0 ) enableObj = 1; printf( "/* This code is automatically generated by \"mktclapp\" */\n" "/* DO NOT EDIT */\n" "#include <tcl.h>\n" "#define INTERFACE 1\n" "#if INTERFACE\n" "#define ET_TCLARGS " "ClientData clientData,Tcl_Interp*interp,int argc,char**argv\n" "#define ET_OBJARGS " "ClientData clientData,Tcl_Interp*interp,int objc,Tcl_Obj*CONST objv[]\n" "#endif\n" ); printf("#define ET_ENABLE_OBJ %d\n", enableObj); printf("#define ET_ENABLE_TK %d\n", useTk!=0); printf("#define ET_AUTO_FORK %d\n", autoFork!=0); printf("#define ET_STANDALONE %d\n", standalone!=0); SetMacro("ET_HAVE_APPINIT",seenEtAppInit); SetMacro("ET_HAVE_PREINIT",seenEtPreInit); SetMacro("ET_HAVE_MAIN",seenMain); if( zTclLib ){ printf("#define ET_TCL_LIBRARY "); WriteAsString(zTclLib,0); } if( zTkLib ){ printf("#define ET_TK_LIBRARY "); WriteAsString(zTkLib,0); } if( zMainScript ){ printf("#define ET_MAIN_SCRIPT "); WriteAsString(zMainScript,0); } if( shroud>0 ){ shroud = time(0) % 31 + 1; } printf("#define ET_SHROUD_KEY %d\n",shroud); printf("#define ET_READ_STDIN %d\n",readStdin); printf("#define ET_CONSOLE %d\n",console); for(pCmd=cmdList; pCmd; pCmd=pCmd->pNext){ if( pCmd->zIf && pCmd->zIf[0]=='0' && pCmd->zIf[1]==0 ) continue; if( pCmd->isObj ){ printf("extern int ET_OBJCOMMAND_%s(ET_OBJARGS);\n", pCmd->zName); }else{ printf("extern int ET_COMMAND_%s(ET_TCLARGS);\n", pCmd->zName); } } printf( "static struct {\n" " char *zName;\n" " int (*xProc)(ET_TCLARGS);\n" "} Et_CmdSet[] = {\n" ); for(pCmd=cmdList; pCmd; pCmd=pCmd->pNext){ char *zProc; if( pCmd->isObj ) continue; if( pCmd->zIf ){ if( pCmd->zIf[0]=='0' && pCmd->zIf[1]==0 ) continue; printf("#if %s\n",pCmd->zIf); } zProc = FuncToProc(pCmd->zName); printf(" { \"%s\", ET_COMMAND_%s },\n", zProc, pCmd->zName); SafeFree(zProc); if( pCmd->zIf ){ printf("#endif\n"); } } printf("{0, 0}};\n"); if( enableObj ){ char *zProc; printf( "static struct {\n" " char *zName;\n" " int (*xProc)(ET_OBJARGS);\n" "} Et_ObjSet[] = {\n" ); for(pCmd=cmdList; pCmd; pCmd=pCmd->pNext){ if( !pCmd->isObj ) continue; if( pCmd->zIf ){ if( pCmd->zIf[0]=='0' && pCmd->zIf[1]==0 ) continue; printf("#if %s\n",pCmd->zIf); } zProc = FuncToProc(pCmd->zName); printf(" { \"%s\", ET_OBJCOMMAND_%s },\n", zProc, pCmd->zName); SafeFree(zProc); if( pCmd->zIf ){ printf("#endif\n"); } } printf("{0, 0}};\n"); } for(i=0; i<nTcl; i++){ char *z; printf("static char Et_zFile%d[] = \n",i); z = ReadFileIntoMemory(azTcl[i]); if( z==0 ) continue; if( aDoCompress[i] ) CompressTcl(z); WriteAsString(z,shroud); printf(";\n"); SafeFree(z); } printf( "struct EtFile {\n" " char *zName;\n" " char *zData;\n" " int nData;\n" " int shrouded;\n" " struct EtFile *pNext;\n" "};\n" "static struct EtFile Et_FileSet[] = {\n" ); for(i=0; i<nTcl; i++){ printf(" { \"%s\", Et_zFile%d, sizeof(Et_zFile%d)-1, %d, 0 },\n", azTcl[i], i, i, shroud); } fflush(stdout); nHash = nTcl*2 + 1; if( nHash<71 ){ nHash = 71; } printf( "{0, 0}};\n" "static struct EtFile *Et_FileHashTable[%d];\n" "%s", nHash, zTail ); return nError; } char zTail[] = "/* The following copyright notice applies to code generated by\n" "** \"mktclapp\". The \"mktclapp\" program itself is covered by the\n" "** GNU Public License.\n" "**\n" "** Copyright (c) 1998 D. Richard Hipp\n" "**\n" "** The author hereby grants permission to use, copy, modify, distribute,\n" "** and license this software and its documentation for any purpose, provided\n" "** that existing copyright notices are retained in all copies and that this\n" "** notice is included verbatim in any distributions. No written agreement,\n" "** license, or royalty fee is required for any of the authorized uses.\n" "** Modifications to this software may be copyrighted by their authors\n" "** and need not follow the licensing terms described here, provided that\n" "** the new terms are clearly indicated on the first page of each file where\n" "** they apply.\n" "**\n" "** In no event shall the author or the distributors be liable to any party\n" "** for direct, indirect, special, incidental, or consequential damages\n" "** arising out of the use of this software, its documentation, or any\n" "** derivatives thereof, even if the author has been advised of the \n" "** possibility of such damage. The author and distributors specifically\n" "** disclaim any warranties, including but not limited to the implied\n" "** warranties of merchantability, fitness for a particular purpose, and\n" "** non-infringment. This software is provided at no fee on an\n" "** \"as is\" basis. The author and/or distritutors have no obligation\n" "** to provide maintenance, support, updates, enhancements and/or\n" "** modifications.\n" "**\n" "** GOVERNMENT USE: If you are acquiring this software on behalf of the\n" "** U.S. government, the Government shall have only \"Restricted Rights\"\n" "** in the software and related documentation as defined in the Federal \n" "** Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you\n" "** are acquiring the software on behalf of the Department of Defense, the\n" "** software shall be classified as \"Commercial Computer Software\" and the\n" "** Government shall have only \"Restricted Rights\" as defined in Clause\n" "** 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the\n" "** author grants the U.S. Government and others acting in its behalf\n" "** permission to use and distribute the software in accordance with the\n" "** terms specified in this license. \n" "*/\n" "#include <ctype.h>\n" "#include <string.h>\n" "#include <stdarg.h>\n" "#include <stdio.h>\n" "#if ET_ENABLE_TK\n" "# include <tk.h>\n" "#else\n" "# include <tcl.h>\n" "#endif\n" "#include <stdlib.h>\n" "#include <sys/types.h>\n" "#include <sys/stat.h>\n" "#include <fcntl.h>\n" "\n" "/*\n" "** ET_WIN32 is true if we are running Tk under windows. The\n" "** <tcl.h> module will define __WIN32__ for us if we are compiling\n" "** for windows.\n" "*/\n" "#if defined(__WIN32__) && ET_ENABLE_TK\n" "# define ET_WIN32 1\n" "# include <windows.h>\n" "#else\n" "# define ET_WIN32 0\n" "#endif\n" "\n" "/*\n" "** Always disable ET_AUTO_FORK under windows. Windows doesn't\n" "** fork well.\n" "*/\n" "#if defined(__WIN32__)\n" "# undef ET_AUTO_FORK\n" "# define ET_AUTO_FORK 0\n" "#endif\n" "\n" "/*\n" "** Omit <unistd.h> under windows.\n" "*/\n" "#if !defined(__WIN32__)\n" "# include <unistd.h>\n" "#endif\n" "\n" "/*\n" "** The Tcl*InsertProc functions allow the system calls \"stat\",\n" "** \"access\" and \"open\" to be overloaded. This in turns allows us\n" "** to substituted compiled-in strings for files in the filesystem.\n" "** But the Tcl*InsertProc functions are only available in Tcl8.0.3\n" "** and later.\n" "**\n" "** Define the ET_HAVE_INSERTPROC macro if and only if we are dealing\n" "** with Tcl8.0.3 or later.\n" "*/\n" "#if TCL_MAJOR_VERSION==8 && (TCL_MINOR_VERSION>0 || TCL_RELEASE_SERIAL>=3)\n" "# define ET_HAVE_INSERTPROC\n" "#endif\n" "\n" "/*\n" "** Don't allow Win32 applications to read from stdin. Nor do\n" "** programs that automatically go into the background. Force\n" "** the use of a console in these cases.\n" "*/\n" "#if (ET_WIN32 || ET_AUTO_FORK) && ET_READ_STDIN\n" "# undef ET_READ_STDIN\n" "# undef ET_CONSOLE\n" "# define ET_READ_STDIN 0\n" "# define ET_CONSOLE 1\n" "#endif\n" "\n" "/*\n" "** The console won't work without Tk.\n" "*/\n" "#if ET_ENABLE_TK==0 && ET_CONSOLE\n" "# undef ET_CONSOLE\n" "# define ET_CONSOLE 0\n" "# undef ET_READ_STDIN\n" "# define ET_READ_STDIN 1\n" "#endif\n" "\n" "/*\n" "** Set ET_HAVE_OBJ to true if we are able to link against the\n" "** new Tcl_Obj interface.\n" "*/\n" "#if ET_ENABLE_OBJ || TCL_MAJOR_VERSION>=8\n" "# define ET_HAVE_OBJ 1\n" "#else\n" "# define ET_HAVE_OBJ 0\n" "#endif\n" "\n" "/*\n" "** The Tcl_GetByteArrayFromObj() only appears in Tcl version 8.1\n" "** and later. Substitute Tcl_GetStringFromObj() in Tcl version 8.0.X\n" "*/\n" "#if ET_HAVE_OBJ && TCL_MINOR_VERSION==0\n" "# define Tcl_GetByteArrayFromObj Tcl_GetStringFromObj\n" "#endif\n" "\n" "/*\n" "** Tcl code to implement the console.\n" "**\n" "** This code is written and tested separately, then run through\n" "** \"mktclapp -stringify\" and then pasted in here.\n" "*/\n" "#if ET_CONSOLE\n" "static char zEtConsole[] = \n" "\"proc console:create {w prompt title} {\\n\"\n" "\"upvar #0 $w.t v\\n\"\n" "\"if {[winfo exists $w]} {destroy $w}\\n\"\n" "\"catch {unset v}\\n\"\n" "\"toplevel $w\\n\"\n" "\"wm title $w $title\\n\"\n" "\"wm iconname $w $title\\n\"\n" "\"frame $w.mb -bd 2 -relief raised\\n\"\n" "\"pack $w.mb -side top -fill x\\n\"\n" "\"menubutton $w.mb.file -text File -menu $w.mb.file.m\\n\"\n" "\"menubutton $w.mb.edit -text Edit -menu $w.mb.edit.m\\n\"\n" "\"pack $w.mb.file $w.mb.edit -side left -padx 8 -pady 1\\n\"\n" "\"set m [menu $w.mb.file.m]\\n\"\n" "\"$m add command -label {Source...} -command \\\"console:SourceFile $w.t\\\"\\n\"\n" "\"$m add command -label {Save As...} -command \\\"console:SaveFile $w.t\\\"\\n\"\n" "\"$m add separator\\n\"\n" "\"$m add command -label {Close} -command \\\"destroy $w\\\"\\n\"\n" "\"$m add command -label {Exit} -command exit\\n\"\n" "\"set m [menu $w.mb.edit.m]\\n\"\n" "\"$m add command -label Cut -command \\\"console:Cut $w.t\\\"\\n\"\n" "\"$m add command -label Copy -command \\\"console:Copy $w.t\\\"\\n\"\n" "\"$m add command -label Paste -command \\\"console:Paste $w.t\\\"\\n\"\n" "\"$m add command -label {Clear Screen} -command \\\"console:Clear $w.t\\\"\\n\"\n" "\"catch {$m config -postcommand \\\"console:EnableEditMenu $w\\\"}\\n\"\n" "\"scrollbar $w.sb -orient vertical -command \\\"$w.t yview\\\"\\n\"\n" "\"pack $w.sb -side right -fill y\\n\"\n" "\"text $w.t -font fixed -yscrollcommand \\\"$w.sb set\\\"\\n\"\n" "\"pack $w.t -side right -fill both -expand 1\\n\"\n" "\"bindtags $w.t Console\\n\"\n" "\"set v(text) $w.t\\n\"\n" "\"set v(history) 0\\n\"\n" "\"set v(historycnt) 0\\n\"\n" "\"set v(current) -1\\n\"\n" "\"set v(prompt) $prompt\\n\"\n" "\"set v(prior) {}\\n\"\n" "\"set v(plength) [string length $v(prompt)]\\n\"\n" "\"set v(x) 0\\n\"\n" "\"set v(y) 0\\n\"\n" "\"$w.t mark set insert end\\n\"\n" "\"$w.t tag config ok -foreground blue\\n\"\n" "\"$w.t tag config err -foreground red\\n\"\n" "\"$w.t insert end $v(prompt)\\n\"\n" "\"$w.t mark set out 1.0\\n\"\n" "\"catch {rename puts console:oldputs$w}\\n\"\n" "\"proc puts args [format {\\n\"\n" "\"if {![winfo exists %s]} {\\n\"\n" "\"rename puts {}\\n\"\n" "\"rename console:oldputs%s puts\\n\"\n" "\"return [uplevel #0 puts $args]\\n\"\n" "\"}\\n\"\n" "\"switch -glob -- \\\"[llength $args] $args\\\" {\\n\"\n" "\"{1 *} {\\n\"\n" "\"set msg [lindex $args 0]\\\\n\\n\"\n" "\"set tag ok\\n\"\n" "\"}\\n\"\n" "\"{2 stdout *} {\\n\"\n" "\"set msg [lindex $args 1]\\\\n\\n\"\n" "\"set tag ok\\n\"\n" "\"}\\n\"\n" "\"{2 stderr *} {\\n\"\n" "\"set msg [lindex $args 1]\\\\n\\n\"\n" "\"set tag err\\n\"\n" "\"}\\n\"\n" "\"{2 -nonewline *} {\\n\"\n" "\"set msg [lindex $args 1]\\n\"\n" "\"set tag ok\\n\"\n" "\"}\\n\"\n" "\"{3 -nonewline stdout *} {\\n\"\n" "\"set msg [lindex $args 2]\\n\"\n" "\"set tag ok\\n\"\n" "\"}\\n\"\n" "\"{3 -nonewline stderr *} {\\n\"\n" "\"set msg [lindex $args 2]\\n\"\n" "\"set tag err\\n\"\n" "\"}\\n\"\n" "\"default {\\n\"\n" "\"uplevel #0 console:oldputs%s $args\\n\"\n" "\"return\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"console:Puts %s $msg $tag\\n\"\n" "\"} $w $w $w $w.t]\\n\"\n" "\"after idle \\\"focus $w.t\\\"\\n\"\n" "\"}\\n\"\n" "\"bind Console <1> {console:Button1 %W %x %y}\\n\"\n" "\"bind Console <B1-Motion> {console:B1Motion %W %x %y}\\n\"\n" "\"bind Console <B1-Leave> {console:B1Leave %W %x %y}\\n\"\n" "\"bind Console <B1-Enter> {console:cancelMotor %W}\\n\"\n" "\"bind Console <ButtonRelease-1> {console:cancelMotor %W}\\n\"\n" "\"bind Console <KeyPress> {console:Insert %W %A}\\n\"\n" "\"bind Console <Left> {console:Left %W}\\n\"\n" "\"bind Console <Control-b> {console:Left %W}\\n\"\n" "\"bind Console <Right> {console:Right %W}\\n\"\n" "\"bind Console <Control-f> {console:Right %W}\\n\"\n" "\"bind Console <BackSpace> {console:Backspace %W}\\n\"\n" "\"bind Console <Control-h> {console:Backspace %W}\\n\"\n" "\"bind Console <Delete> {console:Delete %W}\\n\"\n" "\"bind Console <Control-d> {console:Delete %W}\\n\"\n" "\"bind Console <Home> {console:Home %W}\\n\"\n" "\"bind Console <Control-a> {console:Home %W}\\n\"\n" "\"bind Console <End> {console:End %W}\\n\"\n" "\"bind Console <Control-e> {console:End %W}\\n\"\n" "\"bind Console <Return> {console:Enter %W}\\n\"\n" "\"bind Console <KP_Enter> {console:Enter %W}\\n\"\n" "\"bind Console <Up> {console:Prior %W}\\n\"\n" "\"bind Console <Control-p> {console:Prior %W}\\n\"\n" "\"bind Console <Down> {console:Next %W}\\n\"\n" "\"bind Console <Control-n> {console:Next %W}\\n\"\n" "\"bind Console <Control-k> {console:EraseEOL %W}\\n\"\n" "\"bind Console <<Cut>> {console:Cut %W}\\n\"\n" "\"bind Console <<Copy>> {console:Copy %W}\\n\"\n" "\"bind Console <<Paste>> {console:Paste %W}\\n\"\n" "\"bind Console <<Clear>> {console:Clear %W}\\n\"\n" "\"proc console:Puts {w t tag} {\\n\"\n" "\"set nc [string length $t]\\n\"\n" "\"set endc [string index $t [expr $nc-1]]\\n\"\n" "\"if {$endc==\\\"\\\\n\\\"} {\\n\"\n" "\"if {[$w index out]<[$w index {insert linestart}]} {\\n\"\n" "\"$w insert out [string range $t 0 [expr $nc-2]] $tag\\n\"\n" "\"$w mark set out {out linestart +1 lines}\\n\"\n" "\"} else {\\n\"\n" "\"$w insert out $t $tag\\n\"\n" "\"}\\n\"\n" "\"} else {\\n\"\n" "\"if {[$w index out]<[$w index {insert linestart}]} {\\n\"\n" "\"$w insert out $t $tag\\n\"\n" "\"} else {\\n\"\n" "\"$w insert out $t\\\\n $tag\\n\"\n" "\"$w mark set out {out -1 char}\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"$w yview insert\\n\"\n" "\"}\\n\"\n" "\"proc console:Insert {w a} {\\n\"\n" "\"$w insert insert $a\\n\"\n" "\"$w yview insert\\n\"\n" "\"}\\n\"\n" "\"proc console:Left {w} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"if {$col>$v(plength)} {\\n\"\n" "\"$w mark set insert \\\"insert -1c\\\"\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:Backspace {w} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"if {$col>$v(plength)} {\\n\"\n" "\"$w delete {insert -1c}\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:EraseEOL {w} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"if {$col>=$v(plength)} {\\n\"\n" "\"$w delete insert {insert lineend}\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:Right {w} {\\n\"\n" "\"$w mark set insert \\\"insert +1c\\\"\\n\"\n" "\"}\\n\"\n" "\"proc console:Delete w {\\n\"\n" "\"$w delete insert\\n\"\n" "\"}\\n\"\n" "\"proc console:Home w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"$w mark set insert $row.$v(plength)\\n\"\n" "\"}\\n\"\n" "\"proc console:End w {\\n\"\n" "\"$w mark set insert {insert lineend}\\n\"\n" "\"}\\n\"\n" "\"proc console:Enter w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"set start $row.$v(plength)\\n\"\n" "\"set line [$w get $start \\\"$start lineend\\\"]\\n\"\n" "\"if {$v(historycnt)>0} {\\n\"\n" "\"set last [lindex $v(history) [expr $v(historycnt)-1]]\\n\"\n" "\"if {[string compare $last $line]} {\\n\"\n" "\"lappend v(history) $line\\n\"\n" "\"incr v(historycnt)\\n\"\n" "\"}\\n\"\n" "\"} else {\\n\"\n" "\"set v(history) [list $line]\\n\"\n" "\"set v(historycnt) 1\\n\"\n" "\"}\\n\"\n" "\"set v(current) $v(historycnt)\\n\"\n" "\"$w insert end \\\\n\\n\"\n" "\"$w mark set out end\\n\"\n" "\"if {$v(prior)==\\\"\\\"} {\\n\"\n" "\"set cmd $line\\n\"\n" "\"} else {\\n\"\n" "\"set cmd $v(prior)\\\\n$line\\n\"\n" "\"}\\n\"\n" "\"if {[info complete $cmd]} {\\n\"\n" "\"set rc [catch {uplevel #0 $cmd} res]\\n\"\n" "\"if {![winfo exists $w]} return\\n\"\n" "\"if {$rc} {\\n\"\n" "\"$w insert end $res\\\\n err\\n\"\n" "\"} elseif {[string length $res]>0} {\\n\"\n" "\"$w insert end $res\\\\n ok\\n\"\n" "\"}\\n\"\n" "\"set v(prior) {}\\n\"\n" "\"$w insert end $v(prompt)\\n\"\n" "\"} else {\\n\"\n" "\"set v(prior) $cmd\\n\"\n" "\"regsub -all {[^ ]} $v(prompt) . x\\n\"\n" "\"$w insert end $x\\n\"\n" "\"}\\n\"\n" "\"$w mark set insert end\\n\"\n" "\"$w mark set out {insert linestart}\\n\"\n" "\"$w yview insert\\n\"\n" "\"}\\n\"\n" "\"proc console:Prior w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"if {$v(current)<=0} return\\n\"\n" "\"incr v(current) -1\\n\"\n" "\"set line [lindex $v(history) $v(current)]\\n\"\n" "\"console:SetLine $w $line\\n\"\n" "\"}\\n\"\n" "\"proc console:Next w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"if {$v(current)>=$v(historycnt)} return\\n\"\n" "\"incr v(current) 1\\n\"\n" "\"set line [lindex $v(history) $v(current)]\\n\"\n" "\"console:SetLine $w $line\\n\"\n" "\"}\\n\"\n" "\"proc console:SetLine {w line} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"scan [$w index insert] %d.%d row col\\n\"\n" "\"set start $row.$v(plength)\\n\"\n" "\"$w delete $start end\\n\"\n" "\"$w insert end $line\\n\"\n" "\"$w mark set insert end\\n\"\n" "\"$w yview insert\\n\"\n" "\"}\\n\"\n" "\"proc console:Button1 {w x y} {\\n\"\n" "\"global tkPriv\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"set v(mouseMoved) 0\\n\"\n" "\"set v(pressX) $x\\n\"\n" "\"set p [console:nearestBoundry $w $x $y]\\n\"\n" "\"scan [$w index insert] %d.%d ix iy\\n\"\n" "\"scan $p %d.%d px py\\n\"\n" "\"if {$px==$ix} {\\n\"\n" "\"$w mark set insert $p\\n\"\n" "\"}\\n\"\n" "\"$w mark set anchor $p\\n\"\n" "\"focus $w\\n\"\n" "\"}\\n\"\n" "\"proc console:nearestBoundry {w x y} {\\n\"\n" "\"set p [$w index @$x,$y]\\n\"\n" "\"set bb [$w bbox $p]\\n\"\n" "\"if {![string compare $bb \\\"\\\"]} {return $p}\\n\"\n" "\"if {($x-[lindex $bb 0])<([lindex $bb 2]/2)} {return $p}\\n\"\n" "\"$w index \\\"$p + 1 char\\\"\\n\"\n" "\"}\\n\"\n" "\"proc console:SelectTo {w x y} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"set cur [console:nearestBoundry $w $x $y]\\n\"\n" "\"if {[catch {$w index anchor}]} {\\n\"\n" "\"$w mark set anchor $cur\\n\"\n" "\"}\\n\"\n" "\"set anchor [$w index anchor]\\n\"\n" "\"if {[$w compare $cur != $anchor] || (abs($v(pressX) - $x) >= 3)} {\\n\"\n" "\"if {$v(mouseMoved)==0} {\\n\"\n" "\"$w tag remove sel 0.0 end\\n\"\n" "\"}\\n\"\n" "\"set v(mouseMoved) 1\\n\"\n" "\"}\\n\"\n" "\"if {[$w compare $cur < anchor]} {\\n\"\n" "\"set first $cur\\n\"\n" "\"set last anchor\\n\"\n" "\"} else {\\n\"\n" "\"set first anchor\\n\"\n" "\"set last $cur\\n\"\n" "\"}\\n\"\n" "\"if {$v(mouseMoved)} {\\n\"\n" "\"$w tag remove sel 0.0 $first\\n\"\n" "\"$w tag add sel $first $last\\n\"\n" "\"$w tag remove sel $last end\\n\"\n" "\"update idletasks\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:B1Motion {w x y} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"set v(y) $y\\n\"\n" "\"set v(x) $x\\n\"\n" "\"console:SelectTo $w $x $y\\n\"\n" "\"}\\n\"\n" "\"proc console:B1Leave {w x y} {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"set v(y) $y\\n\"\n" "\"set v(x) $x\\n\"\n" "\"console:motor $w\\n\"\n" "\"}\\n\"\n" "\"proc console:motor w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"if {![winfo exists $w]} return\\n\"\n" "\"if {$v(y)>=[winfo height $w]} {\\n\"\n" "\"$w yview scroll 1 units\\n\"\n" "\"} elseif {$v(y)<0} {\\n\"\n" "\"$w yview scroll -1 units\\n\"\n" "\"} else {\\n\"\n" "\"return\\n\"\n" "\"}\\n\"\n" "\"console:SelectTo $w $v(x) $v(y)\\n\"\n" "\"set v(timer) [after 50 console:motor $w]\\n\"\n" "\"}\\n\"\n" "\"proc console:cancelMotor w {\\n\"\n" "\"upvar #0 $w v\\n\"\n" "\"catch {after cancel $v(timer)}\\n\"\n" "\"catch {unset v(timer)}\\n\"\n" "\"}\\n\"\n" "\"proc console:Copy w {\\n\"\n" "\"if {![catch {set text [$w get sel.first sel.last]}]} {\\n\"\n" "\"clipboard clear -displayof $w\\n\"\n" "\"clipboard append -displayof $w $text\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:canCut w {\\n\"\n" "\"set r [catch {\\n\"\n" "\"scan [$w index sel.first] %d.%d s1x s1y\\n\"\n" "\"scan [$w index sel.last] %d.%d s2x s2y\\n\"\n" "\"scan [$w index insert] %d.%d ix iy\\n\"\n" "\"}]\\n\"\n" "\"if {$r==1} {return 0}\\n\"\n" "\"if {$s1x==$ix && $s2x==$ix} {return 1}\\n\"\n" "\"return 2\\n\"\n" "\"}\\n\"\n" "\"proc console:Cut w {\\n\"\n" "\"if {[console:canCut $w]==1} {\\n\"\n" "\"console:Copy $w\\n\"\n" "\"$w delete sel.first sel.last\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:Paste w {\\n\"\n" "\"if {[console:canCut $w]==1} {\\n\"\n" "\"$w delete sel.first sel.last\\n\"\n" "\"}\\n\"\n" "\"if {[catch {selection get -displayof $w -selection CLIPBOARD} topaste]} {\\n\"\n" "\"return\\n\"\n" "\"}\\n\"\n" "\"set prior 0\\n\"\n" "\"foreach line [split $topaste \\\\n] {\\n\"\n" "\"if {$prior} {\\n\"\n" "\"console:Enter $w\\n\"\n" "\"update\\n\"\n" "\"}\\n\"\n" "\"set prior 1\\n\"\n" "\"$w insert insert $line\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:EnableEditMenu w {\\n\"\n" "\"set m $w.mb.edit.m\\n\"\n" "\"switch [console:canCut $w.t] {\\n\"\n" "\"0 {\\n\"\n" "\"$m entryconf Copy -state disabled\\n\"\n" "\"$m entryconf Cut -state disabled\\n\"\n" "\"}\\n\"\n" "\"1 {\\n\"\n" "\"$m entryconf Copy -state normal\\n\"\n" "\"$m entryconf Cut -state normal\\n\"\n" "\"}\\n\"\n" "\"2 {\\n\"\n" "\"$m entryconf Copy -state normal\\n\"\n" "\"$m entryconf Cut -state disabled\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:SourceFile w {\\n\"\n" "\"set types {\\n\"\n" "\"{{TCL Scripts} {.tcl}}\\n\"\n" "\"{{All Files} *}\\n\"\n" "\"}\\n\"\n" "\"set f [tk_getOpenFile -filetypes $types -title \\\"TCL Script To Source...\\\"]\\n\"\n" "\"if {$f!=\\\"\\\"} {\\n\"\n" "\"uplevel #0 source $f\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:SaveFile w {\\n\"\n" "\"set types {\\n\"\n" "\"{{Text Files} {.txt}}\\n\"\n" "\"{{All Files} *}\\n\"\n" "\"}\\n\"\n" "\"set f [tk_getSaveFile -filetypes $types -title \\\"Write Screen To...\\\"]\\n\"\n" "\"if {$f!=\\\"\\\"} {\\n\"\n" "\"if {[catch {open $f w} fd]} {\\n\"\n" "\"tk_messageBox -type ok -icon error -message $fd\\n\"\n" "\"} else {\\n\"\n" "\"puts $fd [string trimright [$w get 1.0 end] \\\\n]\\n\"\n" "\"close $fd\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"}\\n\"\n" "\"proc console:Clear w {\\n\"\n" "\"$w delete 1.0 {insert linestart}\\n\"\n" "\"}\\n\"\n" "\"console:create {.@console} {% } {Tcl/Tk Console}\\n\"\n" ";\n" "#endif\n" "\n" "/*\n" "** The \"printf\" code that follows dates from the 1980's. It is in\n" "** the public domain. The original comments are included here for\n" "** completeness...\n" "**\n" "** The following modules is an enhanced replacement for the \"printf\" programs\n" "** found in the standard library. The following enhancements are\n" "** supported:\n" "**\n" "** + Additional functions. The standard set of \"printf\" functions\n" "** includes printf, fprintf, sprintf, vprintf, vfprintf, and\n" "** vsprintf. This module adds the following:\n" "**\n" "** * snprintf -- Works like sprintf, but has an extra argument\n" "** which is the size of the buffer written to.\n" "**\n" "** * mprintf -- Similar to sprintf. Writes output to memory\n" "** obtained from malloc.\n" "**\n" "** * xprintf -- Calls a function to dispose of output.\n" "**\n" "** * nprintf -- No output, but returns the number of characters\n" "** that would have been output by printf.\n" "**\n" "** * A v- version (ex: vsnprintf) of every function is also\n" "** supplied.\n" "**\n" "** + A few extensions to the formatting notation are supported:\n" "**\n" "** * The \"=\" flag (similar to \"-\") causes the output to be\n" "** be centered in the appropriately sized field.\n" "**\n" "** * The %b field outputs an integer in binary notation.\n" "**\n" "** * The %c field now accepts a precision. The character output\n" "** is repeated by the number of times the precision specifies.\n" "**\n" "** * The %' field works like %c, but takes as its character the\n" "** next character of the format string, instead of the next\n" "** argument. For example, printf(\"%.78'-\") prints 78 minus\n" "** signs, the same as printf(\"%.78c\",'-').\n" "**\n" "** + When compiled using GCC on a SPARC, this version of printf is\n" "** faster than the library printf for SUN OS 4.1.\n" "**\n" "** + All functions are fully reentrant.\n" "**\n" "*/\n" "/*\n" "** Undefine COMPATIBILITY to make some slight changes in the way things\n" "** work. I think the changes are an improvement, but they are not\n" "** backwards compatible.\n" "*/\n" "/* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */\n" "\n" "/*\n" "** Characters that need to be escaped inside a TCL string.\n" "*/\n" "static char NeedEsc[] = {\n" " 1, 1, 1, 1, 1, 1, 1, 1, 'b', 't', 'n', 1, 'f', 'r', 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 0, 0, '\"', 0, '$', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n" " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n" " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n" " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '[','\\\\', ']', 0, 0,\n" " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n" " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n" "};\n" "\n" "/*\n" "** Conversion types fall into various categories as defined by the\n" "** following enumeration.\n" "*/\n" "enum et_type { /* The type of the format field */\n" " etRADIX, /* Integer types. %d, %x, %o, and so forth */\n" " etFLOAT, /* Floating point. %f */\n" " etEXP, /* Exponentional notation. %e and %E */\n" " etGENERIC, /* Floating or exponential, depending on exponent. %g */\n" " etSIZE, /* Return number of characters processed so far. %n */\n" " etSTRING, /* Strings. %s */\n" " etPERCENT, /* Percent symbol. %% */\n" " etCHARX, /* Characters. %c */\n" " etERROR, /* Used to indicate no such conversion type */\n" "/* The rest are extensions, not normally found in printf() */\n" " etCHARLIT, /* Literal characters. %' */\n" " etTCLESCAPE, /* Strings with special characters escaped. %q */\n" " etMEMSTRING, /* A string which should be deleted after use. %z */\n" " etORDINAL /* 1st, 2nd, 3rd and so forth */\n" "};\n" "\n" "/*\n" "** Each builtin conversion character (ex: the 'd' in \"%d\") is described\n" "** by an instance of the following structure\n" "*/\n" "typedef struct et_info { /* Information about each format field */\n" " int fmttype; /* The format field code letter */\n" " int base; /* The base for radix conversion */\n" " char *charset; /* The character set for conversion */\n" " int flag_signed; /* Is the quantity signed? */\n" " char *prefix; /* Prefix on non-zero values in alt format */\n" " enum et_type type; /* Conversion paradigm */\n" "} et_info;\n" "\n" "/*\n" "** The following table is searched linearly, so it is good to put the\n" "** most frequently used conversion types first.\n" "*/\n" "static et_info fmtinfo[] = {\n" " { 'd', 10, \"0123456789\", 1, 0, etRADIX, },\n" " { 's', 0, 0, 0, 0, etSTRING, }, \n" " { 'q', 0, 0, 0, 0, etTCLESCAPE, },\n" " { 'z', 0, 0, 0, 0, etMEMSTRING, },\n" " { 'c', 0, 0, 0, 0, etCHARX, },\n" " { 'o', 8, \"01234567\", 0, \"0\", etRADIX, },\n" " { 'u', 10, \"0123456789\", 0, 0, etRADIX, },\n" " { 'x', 16, \"0123456789abcdef\", 0, \"x0\", etRADIX, },\n" " { 'X', 16, \"0123456789ABCDEF\", 0, \"X0\", etRADIX, },\n" " { 'r', 10, \"0123456789\", 0, 0, etORDINAL, },\n" " { 'f', 0, 0, 1, 0, etFLOAT, },\n" " { 'e', 0, \"e\", 1, 0, etEXP, },\n" " { 'E', 0, \"E\", 1, 0, etEXP, },\n" " { 'g', 0, \"e\", 1, 0, etGENERIC, },\n" " { 'G', 0, \"E\", 1, 0, etGENERIC, },\n" " { 'i', 10, \"0123456789\", 1, 0, etRADIX, },\n" " { 'n', 0, 0, 0, 0, etSIZE, },\n" " { '%', 0, 0, 0, 0, etPERCENT, },\n" " { 'b', 2, \"01\", 0, \"b0\", etRADIX, }, /* Binary */\n" " { 'p', 10, \"0123456789\", 0, 0, etRADIX, }, /* Pointers */\n" " { '\\'', 0, 0, 0, 0, etCHARLIT, }, /* Literal char */\n" "};\n" "#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))\n" "\n" "/*\n" "** If NOFLOATINGPOINT is defined, then none of the floating point\n" "** conversions will work.\n" "*/\n" "#ifndef etNOFLOATINGPOINT\n" "/*\n" "** \"*val\" is a double such that 0.1 <= *val < 10.0\n" "** Return the ascii code for the leading digit of *val, then\n" "** multiply \"*val\" by 10.0 to renormalize.\n" "**\n" "** Example:\n" "** input: *val = 3.14159\n" "** output: *val = 1.4159 function return = '3'\n" "**\n" "** The counter *cnt is incremented each time. After counter exceeds\n" "** 16 (the number of significant digits in a 64-bit float) '0' is\n" "** always returned.\n" "*/\n" "static int et_getdigit(double *val, int *cnt){\n" " int digit;\n" " double d;\n" " if( (*cnt)++ >= 16 ) return '0';\n" " digit = (int)*val;\n" " d = digit;\n" " digit += '0';\n" " *val = (*val - d)*10.0;\n" " return digit;\n" "}\n" "#endif\n" "\n" "#define etBUFSIZE 1000 /* Size of the output buffer */\n" "\n" "/*\n" "** The root program. All variations call this core.\n" "**\n" "** INPUTS:\n" "** func This is a pointer to a function taking three arguments\n" "** 1. A pointer to anything. Same as the \"arg\" parameter.\n" "** 2. A pointer to the list of characters to be output\n" "** (Note, this list is NOT null terminated.)\n" "** 3. An integer number of characters to be output.\n" "** (Note: This number might be zero.)\n" "**\n" "** arg This is the pointer to anything which will be passed as the\n" "** first argument to \"func\". Use it for whatever you like.\n" "**\n" "** fmt This is the format string, as in the usual print.\n" "**\n" "** ap This is a pointer to a list of arguments. Same as in\n" "** vfprint.\n" "**\n" "** OUTPUTS:\n" "** The return value is the total number of characters sent to\n" "** the function \"func\". Returns -1 on a error.\n" "**\n" "** Note that the order in which automatic variables are declared below\n" "** seems to make a big difference in determining how fast this beast\n" "** will run.\n" "*/\n" "int vxprintf(\n" " void (*func)(void*,char*,int),\n" " void *arg,\n" " const char *format,\n" " va_list ap\n" "){\n" " register const char *fmt; /* The format string. */\n" " register int c; /* Next character in the format string */\n" " register char *bufpt; /* Pointer to the conversion buffer */\n" " register int precision; /* Precision of the current field */\n" " register int length; /* Length of the field */\n" " register int idx; /* A general purpose loop counter */\n" " int count; /* Total number of characters output */\n" " int width; /* Width of the current field */\n" " int flag_leftjustify; /* True if \"-\" flag is present */\n" " int flag_plussign; /* True if \"+\" flag is present */\n" " int flag_blanksign; /* True if \" \" flag is present */\n" " int flag_alternateform; /* True if \"#\" flag is present */\n" " int flag_zeropad; /* True if field width constant starts with zero */\n" " int flag_long; /* True if \"l\" flag is present */\n" " int flag_center; /* True if \"=\" flag is present */\n" " unsigned long longvalue; /* Value for integer types */\n" " double realvalue; /* Value for real types */\n" " et_info *infop; /* Pointer to the appropriate info structure */\n" " char buf[etBUFSIZE]; /* Conversion buffer */\n" " char prefix; /* Prefix character. \"+\" or \"-\" or \" \" or '\\0'. */\n" " int errorflag = 0; /* True if an error is encountered */\n" " enum et_type xtype; /* Conversion paradigm */\n" " char *zMem; /* String to be freed */\n" " char *zExtra; /* Extra memory used for etTCLESCAPE conversions */\n" " static char spaces[] = \" \"\n" " \" \";\n" "#define etSPACESIZE (sizeof(spaces)-1)\n" "#ifndef etNOFLOATINGPOINT\n" " int exp; /* exponent of real numbers */\n" " double rounder; /* Used for rounding floating point values */\n" " int flag_dp; /* True if decimal point should be shown */\n" " int flag_rtz; /* True if trailing zeros should be removed */\n" " int flag_exp; /* True to force display of the exponent */\n" " int nsd; /* Number of significant digits returned */\n" "#endif\n" "\n" " fmt = format; /* Put in a register for speed */\n" " count = length = 0;\n" " bufpt = 0;\n" " for(; (c=(*fmt))!=0; ++fmt){\n" " if( c!='%' ){\n" " register int amt;\n" " bufpt = (char *)fmt;\n" " amt = 1;\n" " while( (c=(*++fmt))!='%' && c!=0 ) amt++;\n" " (*func)(arg,bufpt,amt);\n" " count += amt;\n" " if( c==0 ) break;\n" " }\n" " if( (c=(*++fmt))==0 ){\n" " errorflag = 1;\n" " (*func)(arg,\"%\",1);\n" " count++;\n" " break;\n" " }\n" " /* Find out what flags are present */\n" " flag_leftjustify = flag_plussign = flag_blanksign = \n" " flag_alternateform = flag_zeropad = flag_center = 0;\n" " do{\n" " switch( c ){\n" " case '-': flag_leftjustify = 1; c = 0; break;\n" " case '+': flag_plussign = 1; c = 0; break;\n" " case ' ': flag_blanksign = 1; c = 0; break;\n" " case '#': flag_alternateform = 1; c = 0; break;\n" " case '0': flag_zeropad = 1; c = 0; break;\n" " case '=': flag_center = 1; c = 0; break;\n" " default: break;\n" " }\n" " }while( c==0 && (c=(*++fmt))!=0 );\n" " if( flag_center ) flag_leftjustify = 0;\n" " /* Get the field width */\n" " width = 0;\n" " if( c=='*' ){\n" " width = va_arg(ap,int);\n" " if( width<0 ){\n" " flag_leftjustify = 1;\n" " width = -width;\n" " }\n" " c = *++fmt;\n" " }else{\n" " while( isdigit(c) ){\n" " width = width*10 + c - '0';\n" " c = *++fmt;\n" " }\n" " }\n" " if( width > etBUFSIZE-10 ){\n" " width = etBUFSIZE-10;\n" " }\n" " /* Get the precision */\n" " if( c=='.' ){\n" " precision = 0;\n" " c = *++fmt;\n" " if( c=='*' ){\n" " precision = va_arg(ap,int);\n" "#ifndef etCOMPATIBILITY\n" " /* This is sensible, but SUN OS 4.1 doesn't do it. */\n" " if( precision<0 ) precision = -precision;\n" "#endif\n" " c = *++fmt;\n" " }else{\n" " while( isdigit(c) ){\n" " precision = precision*10 + c - '0';\n" " c = *++fmt;\n" " }\n" " }\n" " /* Limit the precision to prevent overflowing buf[] during conversion */\n" " if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;\n" " }else{\n" " precision = -1;\n" " }\n" " /* Get the conversion type modifier */\n" " if( c=='l' ){\n" " flag_long = 1;\n" " c = *++fmt;\n" " }else{\n" " flag_long = 0;\n" " }\n" " /* Fetch the info entry for the field */\n" " infop = 0;\n" " for(idx=0; idx<etNINFO; idx++){\n" " if( c==fmtinfo[idx].fmttype ){\n" " infop = &fmtinfo[idx];\n" " break;\n" " }\n" " }\n" " /* No info entry found. It must be an error. */\n" " if( infop==0 ){\n" " xtype = etERROR;\n" " }else{\n" " xtype = infop->type;\n" " }\n" " zExtra = 0;\n" "\n" " /*\n" " ** At this point, variables are initialized as follows:\n" " **\n" " ** flag_alternateform TRUE if a '#' is present.\n" " ** flag_plussign TRUE if a '+' is present.\n" " ** flag_leftjustify TRUE if a '-' is present or if the\n" " ** field width was negative.\n" " ** flag_zeropad TRUE if the width began with 0.\n" " ** flag_long TRUE if the letter 'l' (ell) prefixed\n" " ** the conversion character.\n" " ** flag_blanksign TRUE if a ' ' is present.\n" " ** width The specified field width. This is\n" " ** always non-negative. Zero is the default.\n" " ** precision The specified precision. The default\n" " ** is -1.\n" " ** xtype The class of the conversion.\n" " ** infop Pointer to the appropriate info struct.\n" " */\n" " switch( xtype ){\n" " case etORDINAL:\n" " case etRADIX:\n" " if( flag_long ) longvalue = va_arg(ap,long);\n" " else longvalue = va_arg(ap,int);\n" "#ifdef etCOMPATIBILITY\n" " /* For the format %#x, the value zero is printed \"0\" not \"0x0\".\n" " ** I think this is stupid. */\n" " if( longvalue==0 ) flag_alternateform = 0;\n" "#else\n" " /* More sensible: turn off the prefix for octal (to prevent \"00\"),\n" " ** but leave the prefix for hex. */\n" " if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;\n" "#endif\n" " if( infop->flag_signed ){\n" " if( *(long*)&longvalue<0 ){\n" " longvalue = -*(long*)&longvalue;\n" " prefix = '-';\n" " }else if( flag_plussign ) prefix = '+';\n" " else if( flag_blanksign ) prefix = ' ';\n" " else prefix = 0;\n" " }else prefix = 0;\n" " if( flag_zeropad && precision<width-(prefix!=0) ){\n" " precision = width-(prefix!=0);\n" " }\n" " bufpt = &buf[etBUFSIZE];\n" " if( xtype==etORDINAL ){\n" " long a,b;\n" " a = longvalue%10;\n" " b = longvalue%100;\n" " bufpt -= 2;\n" " if( a==0 || a>3 || (b>10 && b<14) ){\n" " bufpt[0] = 't';\n" " bufpt[1] = 'h';\n" " }else if( a==1 ){\n" " bufpt[0] = 's';\n" " bufpt[1] = 't';\n" " }else if( a==2 ){\n" " bufpt[0] = 'n';\n" " bufpt[1] = 'd';\n" " }else if( a==3 ){\n" " bufpt[0] = 'r';\n" " bufpt[1] = 'd';\n" " }\n" " }\n" " {\n" " register char *cset; /* Use registers for speed */\n" " register int base;\n" " cset = infop->charset;\n" " base = infop->base;\n" " do{ /* Convert to ascii */\n" " *(--bufpt) = cset[longvalue%base];\n" " longvalue = longvalue/base;\n" " }while( longvalue>0 );\n" " }\n" " length = (long)&buf[etBUFSIZE]-(long)bufpt;\n" " for(idx=precision-length; idx>0; idx--){\n" " *(--bufpt) = '0'; /* Zero pad */\n" " }\n" " if( prefix ) *(--bufpt) = prefix; /* Add sign */\n" " if( flag_alternateform && infop->prefix ){ /* Add \"0\" or \"0x\" */\n" " char *pre, x;\n" " pre = infop->prefix;\n" " if( *bufpt!=pre[0] ){\n" " for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;\n" " }\n" " }\n" " length = (long)&buf[etBUFSIZE]-(long)bufpt;\n" " break;\n" " case etFLOAT:\n" " case etEXP:\n" " case etGENERIC:\n" " realvalue = va_arg(ap,double);\n" "#ifndef etNOFLOATINGPOINT\n" " if( precision<0 ) precision = 6; /* Set default precision */\n" " if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;\n" " if( realvalue<0.0 ){\n" " realvalue = -realvalue;\n" " prefix = '-';\n" " }else{\n" " if( flag_plussign ) prefix = '+';\n" " else if( flag_blanksign ) prefix = ' ';\n" " else prefix = 0;\n" " }\n" " if( infop->type==etGENERIC && precision>0 ) precision--;\n" " rounder = 0.0;\n" "#ifdef COMPATIBILITY\n" " /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */\n" " for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);\n" "#else\n" " /* It makes more sense to use 0.5 */\n" " for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);\n" "#endif\n" " if( infop->type==etFLOAT ) realvalue += rounder;\n" " /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */\n" " exp = 0;\n" " if( realvalue>0.0 ){\n" " int k = 0;\n" " while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; }\n" " while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; }\n" " while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; }\n" " while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; }\n" " if( k>=100 ){\n" " bufpt = \"NaN\";\n" " length = 3;\n" " break;\n" " }\n" " }\n" " bufpt = buf;\n" " /*\n" " ** If the field type is etGENERIC, then convert to either etEXP\n" " ** or etFLOAT, as appropriate.\n" " */\n" " flag_exp = xtype==etEXP;\n" " if( xtype!=etFLOAT ){\n" " realvalue += rounder;\n" " if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }\n" " }\n" " if( xtype==etGENERIC ){\n" " flag_rtz = !flag_alternateform;\n" " if( exp<-4 || exp>precision ){\n" " xtype = etEXP;\n" " }else{\n" " precision = precision - exp;\n" " xtype = etFLOAT;\n" " }\n" " }else{\n" " flag_rtz = 0;\n" " }\n" " /*\n" " ** The \"exp+precision\" test causes output to be of type etEXP if\n" " ** the precision is too large to fit in buf[].\n" " */\n" " nsd = 0;\n" " if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){\n" " flag_dp = (precision>0 || flag_alternateform);\n" " if( prefix ) *(bufpt++) = prefix; /* Sign */\n" " if( exp<0 ) *(bufpt++) = '0'; /* Digits before \".\" */\n" " else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);\n" " if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */\n" " for(exp++; exp<0 && precision>0; precision--, exp++){\n" " *(bufpt++) = '0';\n" " }\n" " while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);\n" " *(bufpt--) = 0; /* Null terminate */\n" " if( flag_rtz && flag_dp ){ /* Remove trailing zeros and \".\" */\n" " while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;\n" " if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;\n" " }\n" " bufpt++; /* point to next free slot */\n" " }else{ /* etEXP or etGENERIC */\n" " flag_dp = (precision>0 || flag_alternateform);\n" " if( prefix ) *(bufpt++) = prefix; /* Sign */\n" " *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */\n" " if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */\n" " while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);\n" " bufpt--; /* point to last digit */\n" " if( flag_rtz && flag_dp ){ /* Remove tail zeros */\n" " while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;\n" " if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;\n" " }\n" " bufpt++; /* point to next free slot */\n" " if( exp || flag_exp ){\n" " *(bufpt++) = infop->charset[0];\n" " if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */\n" " else { *(bufpt++) = '+'; }\n" " if( exp>=100 ){\n" " *(bufpt++) = (exp/100)+'0'; /* 100's digit */\n" " exp %= 100;\n" " }\n" " *(bufpt++) = exp/10+'0'; /* 10's digit */\n" " *(bufpt++) = exp%10+'0'; /* 1's digit */\n" " }\n" " }\n" " /* The converted number is in buf[] and zero terminated. Output it.\n" " ** Note that the number is in the usual order, not reversed as with\n" " ** integer conversions. */\n" " length = (long)bufpt-(long)buf;\n" " bufpt = buf;\n" "\n" " /* Special case: Add leading zeros if the flag_zeropad flag is\n" " ** set and we are not left justified */\n" " if( flag_zeropad && !flag_leftjustify && length < width){\n" " int i;\n" " int nPad = width - length;\n" " for(i=width; i>=nPad; i--){\n" " bufpt[i] = bufpt[i-nPad];\n" " }\n" " i = prefix!=0;\n" " while( nPad-- ) bufpt[i++] = '0';\n" " length = width;\n" " }\n" "#endif\n" " break;\n" " case etSIZE:\n" " *(va_arg(ap,int*)) = count;\n" " length = width = 0;\n" " break;\n" " case etPERCENT:\n" " buf[0] = '%';\n" " bufpt = buf;\n" " length = 1;\n" " break;\n" " case etCHARLIT:\n" " case etCHARX:\n" " c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);\n" " if( precision>=0 ){\n" " for(idx=1; idx<precision; idx++) buf[idx] = c;\n" " length = precision;\n" " }else{\n" " length =1;\n" " }\n" " bufpt = buf;\n" " break;\n" " case etSTRING:\n" " case etMEMSTRING:\n" " zMem = bufpt = va_arg(ap,char*);\n" " if( bufpt==0 ) bufpt = \"(null)\";\n" " length = strlen(bufpt);\n" " if( precision>=0 && precision<length ) length = precision;\n" " break;\n" " case etTCLESCAPE:\n" " {\n" " int i, j, n, c, k;\n" " char *arg = va_arg(ap,char*);\n" " if( arg==0 ) arg = \"(NULL)\";\n" " for(i=n=0; (c=arg[i])!=0; i++){\n" " k = NeedEsc[c&0xff];\n" " if( k==0 ){\n" " n++;\n" " }else if( k==1 ){\n" " n+=4;\n" " }else{\n" " n+=2;\n" " }\n" " }\n" " n++;\n" " if( n>etBUFSIZE ){\n" " bufpt = zExtra = Tcl_Alloc( n );\n" " }else{\n" " bufpt = buf;\n" " }\n" " for(i=j=0; (c=arg[i])!=0; i++){\n" " k = NeedEsc[c&0xff];\n" " if( k==0 ){\n" " bufpt[j++] = c;\n" " }else if( k==1 ){\n" " bufpt[j++] = '\\\\';\n" " bufpt[j++] = ((c>>6) & 3) + '0';\n" " bufpt[j++] = ((c>>3) & 7) + '0';\n" " bufpt[j++] = (c & 7) + '0';\n" " }else{\n" " bufpt[j++] = '\\\\';\n" " bufpt[j++] = k;\n" " }\n" " }\n" " bufpt[j] = 0;\n" " length = j;\n" " if( precision>=0 && precision<length ) length = precision;\n" " }\n" " break;\n" " case etERROR:\n" " buf[0] = '%';\n" " buf[1] = c;\n" " errorflag = 0;\n" " idx = 1+(c!=0);\n" " (*func)(arg,\"%\",idx);\n" " count += idx;\n" " if( c==0 ) fmt--;\n" " break;\n" " }/* End switch over the format type */\n" " /*\n" " ** The text of the conversion is pointed to by \"bufpt\" and is\n" " ** \"length\" characters long. The field width is \"width\". Do\n" " ** the output.\n" " */\n" " if( !flag_leftjustify ){\n" " register int nspace;\n" " nspace = width-length;\n" " if( nspace>0 ){\n" " if( flag_center ){\n" " nspace = nspace/2;\n" " width -= nspace;\n" " flag_leftjustify = 1;\n" " }\n" " count += nspace;\n" " while( nspace>=etSPACESIZE ){\n" " (*func)(arg,spaces,etSPACESIZE);\n" " nspace -= etSPACESIZE;\n" " }\n" " if( nspace>0 ) (*func)(arg,spaces,nspace);\n" " }\n" " }\n" " if( length>0 ){\n" " (*func)(arg,bufpt,length);\n" " count += length;\n" " }\n" " if( xtype==etMEMSTRING && zMem ){\n" " Tcl_Free(zMem);\n" " }\n" " if( flag_leftjustify ){\n" " register int nspace;\n" " nspace = width-length;\n" " if( nspace>0 ){\n" " count += nspace;\n" " while( nspace>=etSPACESIZE ){\n" " (*func)(arg,spaces,etSPACESIZE);\n" " nspace -= etSPACESIZE;\n" " }\n" " if( nspace>0 ) (*func)(arg,spaces,nspace);\n" " }\n" " }\n" " if( zExtra ){\n" " Tcl_Free(zExtra);\n" " }\n" " }/* End for loop over the format string */\n" " return errorflag ? -1 : count;\n" "} /* End of function */\n" "\n" "/*\n" "** The following section of code handles the mprintf routine, that\n" "** writes to memory obtained from malloc().\n" "*/\n" "\n" "/* This structure is used to store state information about the\n" "** write to memory that is currently in progress.\n" "*/\n" "struct sgMprintf {\n" " char *zBase; /* A base allocation */\n" " char *zText; /* The string collected so far */\n" " int nChar; /* Length of the string so far */\n" " int nAlloc; /* Amount of space allocated in zText */\n" "};\n" "\n" "/* \n" "** The xprintf callback function. \n" "**\n" "** This routine add nNewChar characters of text in zNewText to\n" "** the sgMprintf structure pointed to by \"arg\".\n" "*/\n" "static void mout(void *arg, char *zNewText, int nNewChar){\n" " struct sgMprintf *pM = (struct sgMprintf*)arg;\n" " if( pM->nChar + nNewChar + 1 > pM->nAlloc ){\n" " pM->nAlloc = pM->nChar + nNewChar*2 + 1;\n" " if( pM->zText==pM->zBase ){\n" " pM->zText = Tcl_Alloc(pM->nAlloc);\n" " if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);\n" " }else{\n" " pM->zText = Tcl_Realloc(pM->zText, pM->nAlloc);\n" " }\n" " }\n" " if( pM->zText ){\n" " memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);\n" " pM->nChar += nNewChar;\n" " pM->zText[pM->nChar] = 0;\n" " }\n" "}\n" "\n" "/*\n" "** mprintf() works like printf(), but allocations memory to hold the\n" "** resulting string and returns a pointer to the allocated memory.\n" "*/\n" "char *mprintf(const char *zFormat, ...){\n" " va_list ap;\n" " struct sgMprintf sMprintf;\n" " char *zNew;\n" " char zBuf[200];\n" "\n" " sMprintf.nChar = 0;\n" " sMprintf.nAlloc = sizeof(zBuf);\n" " sMprintf.zText = zBuf;\n" " sMprintf.zBase = zBuf;\n" " va_start(ap,zFormat);\n" " vxprintf(mout,&sMprintf,zFormat,ap);\n" " va_end(ap);\n" " sMprintf.zText[sMprintf.nChar] = 0;\n" " if( sMprintf.zText==sMprintf.zBase ){\n" " zNew = Tcl_Alloc( sMprintf.nChar+1 );\n" " if( zNew ) strcpy(zNew,zBuf);\n" " }else{\n" " zNew = Tcl_Realloc(sMprintf.zText,sMprintf.nChar+1);\n" " }\n" " return zNew;\n" "}\n" "\n" "/* This is the varargs version of mprintf. \n" "*/\n" "char *vmprintf(const char *zFormat, va_list ap){\n" " struct sgMprintf sMprintf;\n" " char zBuf[200];\n" " sMprintf.nChar = 0;\n" " sMprintf.zText = zBuf;\n" " sMprintf.nAlloc = sizeof(zBuf);\n" " sMprintf.zBase = zBuf;\n" " vxprintf(mout,&sMprintf,zFormat,ap);\n" " sMprintf.zText[sMprintf.nChar] = 0;\n" " if( sMprintf.zText==sMprintf.zBase ){\n" " sMprintf.zText = Tcl_Alloc( strlen(zBuf)+1 );\n" " if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf);\n" " }else{\n" " sMprintf.zText = Tcl_Realloc(sMprintf.zText,sMprintf.nChar+1);\n" " }\n" " return sMprintf.zText;\n" "}\n" "\n" "/*\n" "** Add text output to a Tcl_DString.\n" "**\n" "** This routine is called by vxprintf(). It's job is to add\n" "** nNewChar characters of text from zNewText to the Tcl_DString\n" "** that \"arg\" is pointing to.\n" "*/\n" "static void dstringout(void *arg, char *zNewText, int nNewChar){\n" " Tcl_DString *str = (Tcl_DString*)arg;\n" " Tcl_DStringAppend(str,zNewText,nNewChar);\n" "}\n" "\n" "/*\n" "** Append formatted output to a DString.\n" "*/\n" "char *Et_DStringAppendF(Tcl_DString *str, const char *zFormat, ...){\n" " va_list ap;\n" " va_start(ap,zFormat);\n" " vxprintf(dstringout,str,zFormat,ap);\n" " va_end(ap);\n" " return Tcl_DStringValue(str);\n" "}\n" "\n" "/*\n" "** Make this variable true to trace all calls to EvalF\n" "*/\n" "int Et_EvalTrace = 0;\n" "\n" "/*\n" "** Eval the results of a string.\n" "*/\n" "int Et_EvalF(Tcl_Interp *interp, const char *zFormat, ...){\n" " char *zCmd;\n" " va_list ap;\n" " int result;\n" " va_start(ap,zFormat);\n" " zCmd = vmprintf(zFormat,ap);\n" " if( Et_EvalTrace ) printf(\"%s\\n\",zCmd);\n" " result = Tcl_Eval(interp,zCmd);\n" " if( Et_EvalTrace ) printf(\"%d %s\\n\",result,interp->result);\n" " Tcl_Free(zCmd);\n" " return result;\n" "}\n" "int Et_GlobalEvalF(Tcl_Interp *interp, const char *zFormat, ...){\n" " char *zCmd;\n" " va_list ap;\n" " int result;\n" " va_start(ap,zFormat);\n" " zCmd = vmprintf(zFormat,ap);\n" " if( Et_EvalTrace ) printf(\"%s\\n\",zCmd);\n" " result = Tcl_GlobalEval(interp,zCmd);\n" " if( Et_EvalTrace ) printf(\"%d %s\\n\",result,interp->result);\n" " Tcl_Free(zCmd);\n" " return result;\n" "}\n" "\n" "/*\n" "** Set the result of an interpreter using printf-like arguments.\n" "*/\n" "void Et_ResultF(Tcl_Interp *interp, const char *zFormat, ...){\n" " Tcl_DString str;\n" " va_list ap;\n" "\n" " Tcl_DStringInit(&str);\n" " va_start(ap,zFormat);\n" " vxprintf(dstringout,&str,zFormat,ap);\n" " va_end(ap);\n" " Tcl_DStringResult(interp,&str); \n" "}\n" "\n" "#if ET_HAVE_OBJ\n" "/*\n" "** Append text to a string object.\n" "*/\n" "int Et_AppendObjF(Tcl_Obj *pObj, const char *zFormat, ...){\n" " va_list ap;\n" " int rc;\n" "\n" " va_start(ap,zFormat);\n" " rc = vxprintf((void(*)(void*,char*,int))Tcl_AppendToObj, pObj, zFormat, ap);\n" " va_end(ap);\n" " return rc;\n" "}\n" "#endif\n" "\n" "\n" "#if ET_WIN32\n" "/*\n" "** This array translates all characters into themselves. Except\n" "** for the \\ which gets translated into /. And all upper-case\n" "** characters are translated into lower case. This is used for\n" "** hashing and comparing filenames, to work around the Windows\n" "** but of ignoring filename case and using the wrong separator\n" "** character for directories.\n" "**\n" "** The array is initialized by FilenameHashInit().\n" "**\n" "** We also define a macro ET_TRANS() that actually does\n" "** the character translation. ET_TRANS() is a no-op under\n" "** unix.\n" "*/\n" "static char charTrans[256];\n" "#define ET_TRANS(X) (charTrans[0xff&(int)(X)])\n" "#else\n" "#define ET_TRANS(X) (X)\n" "#endif\n" "\n" "/*\n" "** Hash a filename. The value returned is appropriate for\n" "** indexing into the Et_FileHashTable[] array.\n" "*/\n" "static int FilenameHash(char *zName){\n" " int h = 0;\n" " while( *zName ){\n" " h = h ^ (h<<5) ^ ET_TRANS(*(zName++));\n" " }\n" " if( h<0 ) h = -h;\n" " return h % (sizeof(Et_FileHashTable)/sizeof(Et_FileHashTable[0]));\n" "}\n" "\n" "/*\n" "** Compare two filenames. Return 0 if they are the same and\n" "** non-zero if they are different.\n" "*/\n" "static int FilenameCmp(char *z1, char *z2){\n" " int diff;\n" " while( (diff = ET_TRANS(*z1)-ET_TRANS(*z2))==0 && *z1!=0){\n" " z1++;\n" " z2++;\n" " }\n" " return diff;\n" "}\n" "\n" "/*\n" "** Initialize the file hash table\n" "*/\n" "static void FilenameHashInit(void){\n" " int i;\n" "#if ET_WIN32\n" " for(i=0; i<sizeof(charTrans); i++){\n" " charTrans[i] = i;\n" " }\n" " for(i='A'; i<='Z'; i++){\n" " charTrans[i] = i + 'a' - 'A';\n" " }\n" " charTrans['\\\\'] = '/';\n" "#endif\n" " for(i=0; i<sizeof(Et_FileSet)/sizeof(Et_FileSet[0]) - 1; i++){\n" " struct EtFile *p;\n" " int h;\n" " p = &Et_FileSet[i];\n" " h = FilenameHash(p->zName);\n" " p->pNext = Et_FileHashTable[h];\n" " Et_FileHashTable[h] = p;\n" " }\n" "}\n" "\n" "/*\n" "** Locate the text of a built-in file given its name. \n" "** Return 0 if not found. Return this size of the file (not\n" "** counting the null-terminator in *pSize if pSize!=NULL.\n" "**\n" "** If deshroud==1 and the file is shrouded, then descramble\n" "** the text.\n" "*/\n" "static char *FindBuiltinFile(char *zName, int deshroud, int *pSize){\n" " int h;\n" " struct EtFile *p;\n" "\n" " h = FilenameHash(zName);\n" " p = Et_FileHashTable[h];\n" " while( p && FilenameCmp(p->zName,zName)!=0 ){ p = p->pNext; }\n" "#if ET_SHROUD_KEY>0\n" " if( p && p->shrouded && deshroud ){\n" " char *z;\n" " int xor = ET_SHROUD_KEY;\n" " for(z=p->zData; *z; z++){\n" " if( *z>=0x20 ){ *z ^= xor; xor = (xor+1)&0x1f; }\n" " }\n" " p->shrouded = 0;\n" " }\n" "#endif\n" " if( p && pSize ){\n" " *pSize = p->nData;\n" " }\n" " return p ? p->zData : 0;\n" "}\n" "\n" "/*\n" "** Add a new file to the list of built-in files.\n" "**\n" "** This routine makes a copy of zFilename. But it does NOT make\n" "** a copy of zData. It just holds a pointer to zData and uses\n" "** that for all file access. So after calling this routine,\n" "** you should never change zData!\n" "*/\n" "void Et_NewBuiltinFile(\n" " char *zFilename, /* Name of the new file */\n" " char *zData, /* Data for the new file */\n" " int nData /* Number of bytes in the new file */\n" "){\n" " int h;\n" " struct EtFile *p;\n" "\n" " p = (struct EtFile*)Tcl_Alloc( sizeof(struct EtFile) + strlen(zFilename) + 1);\n" " if( p==0 ) return;\n" " p->zName = (char*)&p[1];\n" " strcpy(p->zName, zFilename);\n" " p->zData = zData;\n" " p->nData = nData;\n" " p->shrouded = 0;\n" " h = FilenameHash(zFilename);\n" " p->pNext = Et_FileHashTable[h];\n" " Et_FileHashTable[h] = p;\n" "}\n" "\n" "/*\n" "** A TCL interface to the Et_NewBuiltinFile function. For Tcl8.0\n" "** and later, we make this an Obj command so that it can deal with\n" "** binary data.\n" "*/\n" "#if ET_HAVE_OBJ\n" "static int Et_NewBuiltinFileCmd(ET_OBJARGS){\n" " char *zData, *zNew;\n" " int nData;\n" " if( objc!=3 ){\n" " Tcl_WrongNumArgs(interp, 1, objv, \"filename data\");\n" " return TCL_ERROR;\n" " }\n" " zData = Tcl_GetByteArrayFromObj(objv[2], &nData);\n" " zNew = Tcl_Alloc( nData );\n" " if( zNew ){\n" " memcpy(zNew, zData, nData);\n" " Et_NewBuiltinFile(Tcl_GetByteArrayFromObj(objv[1], 0), zNew, nData);\n" " }\n" " return TCL_OK;\n" "}\n" "#else\n" "static int Et_NewBuiltinFileCmd(ET_TCLARGS){\n" " char *zData;\n" " int nData;\n" " if( argc!=3 ){\n" " Et_ResultF(interp,\"wrong # args: should be \\\"%s FILENAME DATA\\\"\", argv[0]);\n" " return TCL_ERROR;\n" " }\n" " nData = strlen(argv[2]) + 1;\n" " zData = Tcl_Alloc( nData );\n" " if( zData ){\n" " strcpy(zData, argv[2]);\n" " Et_NewBuiltinFile(argv[1], zData, nData);\n" " }\n" " return TCL_OK;\n" "}\n" "#endif\n" "\n" "/*\n" "** The following section implements the InsertProc functionality. The\n" "** new InsertProc feature of Tcl8.0.3 and later allows us to overload\n" "** the usual system call commands for file I/O and replace them with\n" "** commands that operate on the built-in files.\n" "*/\n" "#ifdef ET_HAVE_INSERTPROC\n" "\n" "/* \n" "** Each open channel to a built-in file is an instance of the\n" "** following structure.\n" "*/\n" "typedef struct Et_FileStruct {\n" " char *zData; /* All of the data */\n" " int nData; /* Bytes of data, not counting the null terminator */\n" " int cursor; /* How much of the data has been read so far */\n" "} Et_FileStruct;\n" "\n" "/*\n" "** Close a previously opened built-in file.\n" "*/\n" "static int Et_FileClose(ClientData instanceData, Tcl_Interp *interp){\n" " Et_FileStruct *p = (Et_FileStruct*)instanceData;\n" " Tcl_Free((char*)p);\n" " return 0;\n" "}\n" "\n" "/*\n" "** Read from a built-in file.\n" "*/\n" "static int Et_FileInput(\n" " ClientData instanceData, /* The file structure */\n" " char *buf, /* Write the data read here */\n" " int bufSize, /* Read this much data */\n" " int *pErrorCode /* Write the error code here */\n" "){\n" " Et_FileStruct *p = (Et_FileStruct*)instanceData;\n" " *pErrorCode = 0;\n" " if( p->cursor+bufSize>p->nData ){\n" " bufSize = p->nData - p->cursor;\n" " }\n" " memcpy(buf, &p->zData[p->cursor], bufSize);\n" " p->cursor += bufSize;\n" " return bufSize;\n" "}\n" "\n" "/*\n" "** Writes to a built-in file always return EOF.\n" "*/\n" "static int Et_FileOutput(\n" " ClientData instanceData, /* The file structure */\n" " char *buf, /* Read the data from here */\n" " int toWrite, /* Write this much data */\n" " int *pErrorCode /* Write the error code here */\n" "){\n" " *pErrorCode = 0;\n" " return 0;\n" "}\n" "\n" "/*\n" "** Move the cursor around within the built-in file.\n" "*/\n" "static int Et_FileSeek(\n" " ClientData instanceData, /* The file structure */\n" " long offset, /* Offset to seek to */\n" " int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */\n" " int *pErrorCode /* Write the error code here */\n" "){\n" " Et_FileStruct *p = (Et_FileStruct*)instanceData;\n" " switch( mode ){\n" " case SEEK_CUR: offset += p->cursor; break;\n" " case SEEK_END: offset += p->nData; break;\n" " default: break;\n" " }\n" " if( offset<0 ) offset = 0;\n" " if( offset>p->nData ) offset = p->nData;\n" " p->cursor = offset;\n" " return offset;\n" "}\n" "\n" "/*\n" "** The Watch method is a no-op\n" "*/\n" "static void Et_FileWatch(ClientData instanceData, int mask){\n" "}\n" "\n" "/*\n" "** The Handle method always returns an error.\n" "*/\n" "static int Et_FileHandle(ClientData notUsed, int dir, ClientData *handlePtr){\n" " return TCL_ERROR;\n" "}\n" "\n" "/*\n" "** This is the channel type that will access the built-in files.\n" "*/\n" "static Tcl_ChannelType builtinChannelType = {\n" " \"builtin\", /* Type name. */\n" " NULL, /* Always non-blocking.*/\n" " Et_FileClose, /* Close proc. */\n" " Et_FileInput, /* Input proc. */\n" " Et_FileOutput, /* Output proc. */\n" " Et_FileSeek, /* Seek proc. */\n" " NULL, /* Set option proc. */\n" " NULL, /* Get option proc. */\n" " Et_FileWatch, /* Watch for events on console. */\n" " Et_FileHandle, /* Get a handle from the device. */\n" "};\n" "\n" "/*\n" "** This routine attempts to do an open of a built-in file.\n" "*/\n" "static Tcl_Channel Et_FileOpen(\n" " Tcl_Interp *interp, /* The TCL interpreter doing the open */\n" " char *zFilename, /* Name of the file to open */\n" " char *modeString, /* Mode string for the open (ignored) */\n" " int permissions /* Permissions for a newly created file (ignored) */\n" "){\n" " char *zData;\n" " Et_FileStruct *p;\n" " int nData;\n" " char zName[50];\n" " Tcl_Channel chan;\n" "\n" " zData = FindBuiltinFile(zFilename, 1, &nData);\n" " if( zData==0 ) return NULL;\n" " p = (Et_FileStruct*)Tcl_Alloc( sizeof(Et_FileStruct) );\n" " if( p==0 ) return NULL;\n" " p->zData = zData;\n" " p->nData = nData;\n" " p->cursor = 0;\n" " sprintf(zName,\"builtin%08x\",(unsigned int)zData);\n" " chan = Tcl_CreateChannel(&builtinChannelType, zName, \n" " (ClientData)p, TCL_READABLE);\n" " return chan;\n" "}\n" "\n" "/*\n" "** This routine does a stat() system call for a built-in file.\n" "*/\n" "static int Et_FileStat(char *path, struct stat *buf){\n" " char *zData;\n" " int nData;\n" "\n" " zData = FindBuiltinFile(path, 0, &nData);\n" " if( zData==0 ){\n" " return -1;\n" " }\n" " memset(buf, 0, sizeof(*buf));\n" " buf->st_mode = 0400;\n" " buf->st_size = nData;\n" " return 0;\n" "}\n" "\n" "/*\n" "** This routien does an access() system call for a built-in file.\n" "*/\n" "static int Et_FileAccess(char *path, int mode){\n" " char *zData;\n" "\n" " if( mode & 3 ){\n" " return -1;\n" " }\n" " zData = FindBuiltinFile(path, 0, 0);\n" " if( zData==0 ){\n" " return -1;\n" " }\n" " return 0; \n" "}\n" "#endif /* ET_HAVE_INSERTPROC */\n" "\n" "/*\n" "** An overloaded version of \"source\". First check for the file\n" "** is one of the built-ins. If it isn't a built-in, then check the\n" "** disk. But if ET_STANDALONE is set (which corresponds to the\n" "** \"Strict\" option in the user interface) then never check the disk.\n" "** This gives us a quick way to check for the common error of\n" "** sourcing a file that exists on the development by mistake, \n" "** and only discovering the mistake when you move the program\n" "** to your customer's machine.\n" "*/\n" "static int Et_Source(ET_TCLARGS){\n" " char *z;\n" "\n" " if( argc!=2 ){\n" " Et_ResultF(interp,\"wrong # args: should be \\\"%s FILENAME\\\"\", argv[0]);\n" " return TCL_ERROR;\n" " }\n" " z = FindBuiltinFile(argv[1], 1, 0);\n" " if( z ){\n" " int rc;\n" " rc = Tcl_Eval(interp,z);\n" " if (rc == TCL_ERROR) {\n" " char msg[200];\n" " sprintf(msg, \"\\n (file \\\"%.150s\\\" line %d)\", argv[1],\n" " interp->errorLine);\n" " Tcl_AddErrorInfo(interp, msg);\n" " } else {\n" " rc = TCL_OK;\n" " }\n" " return rc;\n" " }\n" "#if ET_STANDALONE\n" " Et_ResultF(interp,\"no such file: \\\"%s\\\"\", argv[1]);\n" " return TCL_ERROR;\n" "#else\n" " return Tcl_EvalFile(interp,argv[1]);\n" "#endif\n" "}\n" "\n" "#ifndef ET_HAVE_INSERTPROC\n" "/*\n" "** An overloaded version of \"file exists\". First check for the file\n" "** in the file table, then go to disk.\n" "**\n" "** We only overload \"file exists\" if we don't have InsertProc() \n" "** procedures. If we do have InsertProc() procedures, they will\n" "** handle this more efficiently.\n" "*/\n" "static int Et_FileExists(ET_TCLARGS){\n" " int i, rc;\n" " Tcl_DString str;\n" " if( argc==3 && strncmp(argv[1],\"exis\",4)==0 ){\n" " if( FindBuiltinFile(argv[2], 0, 0)!=0 ){\n" " interp->result = \"1\";\n" " return TCL_OK;\n" " }\n" " }\n" " Tcl_DStringInit(&str);\n" " Tcl_DStringAppendElement(&str,\"Et_FileCmd\");\n" " for(i=1; i<argc; i++){\n" " Tcl_DStringAppendElement(&str, argv[i]);\n" " }\n" " rc = Tcl_Eval(interp, Tcl_DStringValue(&str));\n" " Tcl_DStringFree(&str);\n" " return rc;\n" "}\n" "#endif\n" "\n" "/*\n" "** This is the main Tcl interpreter. It's a global variable so it\n" "** can be accessed easily from C code.\n" "*/\n" "Tcl_Interp *Et_Interp = 0;\n" "\n" "\n" "#if ET_WIN32\n" "/*\n" "** Implement the Et_MessageBox command on Windows platforms. We\n" "** use the MessageBox() function from the Win32 API so that the\n" "** error message will be displayed as a dialog box. Writing to\n" "** standard error doesn't do anything on windows.\n" "*/\n" "int Et_MessageBox(ET_TCLARGS){\n" " char *zMsg = \"(Empty Message)\";\n" " char *zTitle = \"Message...\";\n" "\n" " if( argc>1 ){\n" " zTitle = argv[1];\n" " }\n" " if( argc>2 ){\n" " zMsg = argv[2];\n" " }\n" " MessageBox(0, zMsg, zTitle, MB_ICONSTOP | MB_OK);\n" " return TCL_OK;\n" "}\n" "#endif\n" "\n" "/*\n" "** A default implementation for \"bgerror\"\n" "*/\n" "static char zBgerror[] = \n" " \"proc Et_Bgerror err {\\n\"\n" " \" global errorInfo tk_library\\n\"\n" " \" if {[info exists errorInfo]} {\\n\"\n" " \" set ei $errorInfo\\n\"\n" " \" } else {\\n\"\n" " \" set ei {}\\n\"\n" " \" }\\n\"\n" " \" if {[catch {bgerror $err}]==0} return\\n\"\n" " \" if {[string length $ei]>0} {\\n\"\n" " \" set err $ei\\n\"\n" " \" }\\n\"\n" " \" if {[catch {Et_MessageBox {Error} $err}]} {\\n\"\n" " \" puts stderr $err\\n\"\n" " \" }\\n\"\n" " \" exit\\n\"\n" " \"}\\n\"\n" ";\n" "\n" "/*\n" "** Do the initialization.\n" "**\n" "** This routine is called after the interpreter is created, but\n" "** before Et_PreInit() or Et_AppInit() have been run.\n" "*/\n" "static int Et_DoInit(Tcl_Interp *interp){\n" " int i;\n" " extern int Et_PreInit(Tcl_Interp*);\n" " extern int Et_AppInit(Tcl_Interp*);\n" "\n" " /* Insert our alternative stat(), access() and open() procedures\n" " ** so that any attempt to work with a file will check our built-in\n" " ** scripts first.\n" " */\n" "#ifdef ET_HAVE_INSERTPROC\n" " extern int TclStatInsertProc(int (*)(char*, struct stat *));\n" " extern int TclAccessInsertProc(int (*)(char*, int));\n" " extern int TclOpenFileChannelInsertProc(Tcl_Channel (*)(Tcl_Interp*,char*,\n" " char*,int));\n" " TclStatInsertProc(Et_FileStat);\n" " TclAccessInsertProc(Et_FileAccess);\n" " TclOpenFileChannelInsertProc(Et_FileOpen);\n" "#endif\n" "\n" " /* Initialize the hash-table for built-in scripts\n" " */\n" " FilenameHashInit();\n" "\n" " /* The Et_NewBuiltFile command is inserted for use by FreeWrap\n" " ** and similar tools.\n" " */\n" "#if ET_HAVE_OBJ\n" " Tcl_CreateObjCommand(interp,\"Et_NewBuiltinFile\",Et_NewBuiltinFileCmd,0,0);\n" "#else\n" " Tcl_CreateCommand(interp,\"Et_NewBuiltinFile\",Et_NewBuiltinFileCmd,0,0);\n" "#endif\n" "\n" " /* Overload the \"file\" and \"source\" commands\n" " */\n" "#ifndef ET_HAVE_INSERTPROC\n" " {\n" " static char zRename[] = \"rename file Et_FileCmd\";\n" " Tcl_Eval(interp,zRename);\n" " Tcl_CreateCommand(interp,\"file\",Et_FileExists,0,0);\n" " }\n" "#endif\n" " Tcl_CreateCommand(interp,\"source\",Et_Source,0,0);\n" "\n" " Et_Interp = interp;\n" "#ifdef ET_TCL_LIBRARY\n" " Tcl_SetVar(interp,\"tcl_library\",ET_TCL_LIBRARY,TCL_GLOBAL_ONLY);\n" " Tcl_SetVar(interp,\"tcl_libPath\",ET_TCL_LIBRARY,TCL_GLOBAL_ONLY);\n" " Tcl_SetVar2(interp,\"env\",\"TCL_LIBRARY\",ET_TCL_LIBRARY,TCL_GLOBAL_ONLY);\n" "#endif\n" "#ifdef ET_TK_LIBRARY\n" " Tcl_SetVar(interp,\"tk_library\",ET_TK_LIBRARY,TCL_GLOBAL_ONLY);\n" " Tcl_SetVar2(interp,\"env\",\"TK_LIBRARY\",ET_TK_LIBRARY,TCL_GLOBAL_ONLY);\n" "#endif\n" "#if ET_WIN32\n" " Tcl_CreateCommand(interp,\"Et_MessageBox\",Et_MessageBox, 0, 0);\n" "#endif \n" " Tcl_Eval(interp,zBgerror);\n" "#if ET_HAVE_PREINIT\n" " if( Et_PreInit(interp) == TCL_ERROR ){\n" " goto initerr;\n" " }\n" "#endif\n" " if( Tcl_Init(interp) == TCL_ERROR ){\n" " goto initerr;\n" " }\n" " Et_GlobalEvalF(interp,\"set dir $tcl_library;source $dir/tclIndex;unset dir\");\n" "#if ET_ENABLE_TK\n" " if( Tk_Init(interp) == TCL_ERROR ){\n" " goto initerr;\n" " }\n" " Tcl_StaticPackage(interp,\"Tk\", Tk_Init, 0);\n" " Et_GlobalEvalF(interp,\"set dir $tk_library;source $dir/tclIndex;unset dir\");\n" "#endif\n" " /* Tcl_SetVar(interp, \"tcl_rcFileName\", \"~/.wishrc\", TCL_GLOBAL_ONLY); */\n" " for(i=0; i<sizeof(Et_CmdSet)/sizeof(Et_CmdSet[0]) - 1; i++){\n" " Tcl_CreateCommand(interp, Et_CmdSet[i].zName, Et_CmdSet[i].xProc, 0, 0);\n" " }\n" "#if ET_ENABLE_OBJ\n" " for(i=0; i<sizeof(Et_ObjSet)/sizeof(Et_ObjSet[0]) - 1; i++){\n" " Tcl_CreateObjCommand(interp, Et_ObjSet[i].zName, Et_ObjSet[i].xProc, 0, 0);\n" " }\n" "#endif\n" " Tcl_LinkVar(interp,\"Et_EvalTrace\",(char*)&Et_EvalTrace,TCL_LINK_BOOLEAN);\n" "#if ET_HAVE_APPINIT\n" " if( Et_AppInit(interp) == TCL_ERROR ){\n" " goto initerr;\n" " }\n" "#endif\n" "#if ET_CONSOLE\n" " Tcl_Eval(interp,zEtConsole);\n" "#endif\n" "#ifdef ET_MAIN_SCRIPT\n" " if( Et_EvalF(interp,\"source \\\"%q\\\"\", ET_MAIN_SCRIPT)!=TCL_OK ){\n" " goto initerr;\n" " }\n" "#endif\n" " return TCL_OK;\n" "\n" "initerr:\n" " Et_EvalF(interp,\"Et_Bgerror \\\"%q\\\"\", interp->result);\n" " return TCL_ERROR;\n" "}\n" "\n" "\n" "#if ET_READ_STDIN==0 || ET_AUTO_FORK!=0\n" "/*\n" "** Initialize everything.\n" "*/\n" "static int Et_Local_Init(int argc, char **argv){\n" " Tcl_Interp *interp;\n" " char *args;\n" " char buf[100];\n" " static char zWaitForever[] = \"while 1 {vwait forever}\";\n" "\n" " Tcl_FindExecutable(argv[0]);\n" " interp = Tcl_CreateInterp();\n" " args = Tcl_Merge(argc-1, argv+1);\n" " Tcl_SetVar(interp, \"argv\", args, TCL_GLOBAL_ONLY);\n" " ckfree(args);\n" " sprintf(buf, \"%d\", argc-1);\n" " Tcl_SetVar(interp, \"argc\", buf, TCL_GLOBAL_ONLY);\n" " Tcl_SetVar(interp, \"argv0\", argv[0], TCL_GLOBAL_ONLY);\n" " Tcl_SetVar(interp, \"tcl_interactive\", \"0\", TCL_GLOBAL_ONLY);\n" " Et_DoInit(interp);\n" " Tcl_Eval(interp,zWaitForever);\n" " /* Tcl_DeleteInterp(interp); */\n" " /* Tcl_Exit(0); */\n" " return 0;\n" "}\n" "#endif\n" "\n" "/*\n" "** This routine is called to do the complete initialization.\n" "*/\n" "int Et_Init(int argc, char **argv){\n" "#ifdef ET_TCL_LIBRARY\n" " putenv(\"TCL_LIBRARY=\" ET_TCL_LIBRARY);\n" "#endif\n" "#ifdef ET_TK_LIBRARY\n" " putenv(\"TK_LIBRARY=\" ET_TK_LIBRARY);\n" "#endif\n" "#if ET_CONSOLE || !ET_READ_STDIN\n" " Et_Local_Init(argc, argv);\n" "#else\n" "# if ET_ENABLE_TK\n" " Tk_Main(argc,argv,Et_DoInit);\n" "# else\n" " Tcl_Main(argc, argv, Et_DoInit);\n" "# endif\n" "#endif\n" " return 0;\n" "}\n" "\n" "#if !ET_HAVE_MAIN\n" "/*\n" "** Main routine for UNIX programs. If the user has supplied\n" "** their own main() routine in a C module, then the ET_HAVE_MAIN\n" "** macro will be set to 1 and this code will be skipped.\n" "*/\n" "int main(int argc, char **argv){\n" "#if ET_AUTO_FORK\n" " int rc = fork();\n" " if( rc<0 ){\n" " perror(\"can't fork\");\n" " exit(1);\n" " }\n" " if( rc>0 ) return 0;\n" " close(0);\n" " open(\"/dev/null\",O_RDONLY);\n" " close(1);\n" " open(\"/dev/null\",O_WRONLY);\n" "#endif\n" " return Et_Init(argc,argv)!=TCL_OK;\n" "}\n" "#endif\n" ; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/maketokens.tcl������������������������������������������������������������0000644�0001750�0001750�00000004426�10423760215�017266� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # This script is a replacement for the maketokens.sh shell script. # The shell script required GNU awk. This script should work with # any old version of tclsh. # \ exec tclsh "$0" ${1+"$@"} if {$argc!=1} { puts stderr "Usage: $argv0 tokenlist.txt >htmltokens.c" exit 1 } if {[catch {open [lindex $argv 0] r} f]} { puts stderr "$argv0: can not open \"[lindex $argv 0]\": $f" exit 1 } set tokenlist {} while {![eof $f]} { set line [string trim [gets $f]] if {$line==""} continue if {[string index $line 0]=="#"} continue if {[llength $line]!=2 && [llength $line]!=3} continue lappend tokenlist [lindex $line 0] lappend tokenlist [lindex $line 1] lappend tokenlist [lindex $line 2] } close $f global tcl_platform if {$tcl_platform(platform) == "windows"} { fconfigure stdout -translation lf } puts {/* DO NOT EDIT ** The code in this file was automatically generated. */ #include <tk.h> #include "htmltokens.h" #if INTERFACE struct HtmlTokenMap { char *zName; /* Name of a markup */ Html_16 type; /* Markup type code */ Html_16 extra; /* Extra space needed above HtmlBaseElement */ HtmlTokenMap *pCollide; /* Hash table collision chain */ }; #define Html_Text 1 #define Html_Space 2 #define Html_Unknown 3 #define Html_Block 4 #define HtmlIsMarkup(X) ((X)->base.type>Html_Block) } set count 5 set fmt {#define %-20s %d} foreach {name start end} $tokenlist { set upr [string toupper $name] puts [format $fmt Html_$upr $count] incr count if {$end!=""} { puts [format $fmt Html_End$upr $count] incr count } } puts [format $fmt Html_TypeCount [expr $count-1]] puts "#define HTML_MARKUP_HASH_SIZE [expr $count+11]" puts "#define HTML_MARKUP_COUNT [expr $count-5]" puts "#endif /* INTERFACE */" puts "HtmlTokenMap HtmlMarkupMap\[\] = {" set fmt " { %-15s %-25s %-30s }," foreach {name start end} $tokenlist { set upr [string toupper $name] set nm "\"$name\"," set val Html_$upr, if {$start=="0"} { set size "0," } else { set size "sizeof($start)," } puts [format $fmt $nm $val $size] if {$end==""} continue set nm "\"/$name\"," set val Html_End$upr, if {$end=="0"} { set size "0," } else { set size "sizeof($end)," } puts [format $fmt $nm $val $size] } puts "};" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/getpage.c�����������������������������������������������������������������0000644�0001750�0001750�00000010045�07504443354�016203� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** This is a simple program used to retrieve an HTML document using ** HTTP. The program also fetches all images that the document ** references. */ #include <stdio.h> #include <stdlib.h> #include "getpage.h" #define stricmp strcasecmp /* ** Each image to be loaded is an instance of the following structure. */ typedef struct Image Image; struct Image { char *zUrl; /* The URL for this image */ char *zLocal; /* The local filename */ Image *pNext; /* Next in a list of them all */ }; static FILE *html; /* Html output to this file. */ static int nImage = 0; /* Number of images loaded so far */ static Image *pImage; /* List of all images */ static global_nErr = 0; /* System wide errors */ static char baseUrl[1000];/* The base URL */ static int quiet = 0; /* The quiet flag */ /* ** Make sure the given URL is loaded as a local file. Return the ** name of the local file. */ static char *GetImage(char *zUrl){ Image *p; for(p=pImage; p; p=p->pNext){ if( strcmp(p->zUrl,zUrl)==0 ){ return p->zLocal; } } p = malloc( sizeof(*p) + strlen(zUrl) + 100 ); p->zUrl = (char*)&p[1]; strcpy(p->zUrl, zUrl); p->zLocal = &p->zUrl[strlen(zUrl)+1]; sprintf(p->zLocal,"image%d", ++nImage); p->pNext = pImage; pImage = p; HttpFetch(zUrl, p->zLocal, quiet, 0, 0); return p->zLocal; } /* ** Print a usage comment and exit */ void usage(char *argv0){ fprintf(stderr,"Usage: %s URL\n",argv0); exit(1); } /* ** Handle anything that isn't markup */ static void WordHandler(const char *zText, void *notUsed){ fprintf(html, zText); } /* ** Handle all markup that we don't care about. */ static void DefaultMarkup(int argc, const char **argv, void *notUsed){ int i; fprintf(html,"<%s",argv[0]); for(i=1; i<argc-1; i+=2){ fprintf(html," %s=\"%s\"", argv[i], argv[i+1]); } fprintf(html,">"); } /* ** Handler for <IMG> markup */ static void ImageMarkup(int argc, const char **argv, void *notUsed){ int i; for(i=1; i<argc-1; i+=2){ if( stricmp(argv[i],"src")==0 ){ const char *azUrl[2]; char *zResolved; azUrl[0] = argv[i+1]; azUrl[1] = 0; zResolved = ResolveUrl(baseUrl, azUrl); if( !quiet ){ printf("Resolved: (%s) (%s) -> (%s)\n",baseUrl, azUrl[0], zResolved); } argv[i+1] = GetImage(zResolved); /* printf("%s -> %s -> argv[i+1]\n",argv[i+1], zResolved); */ free(zResolved); } } DefaultMarkup(argc, argv, 0); } /* ** Handler for <BASE> markup */ static void BaseMarkup(int argc, const char **argv, void *notUsed){ int i; for(i=1; i<argc-1; i+=2){ if( stricmp(argv[i],"href")==0 ){ if( !quiet ){ printf("Base Href=%s\n",argv[i+1]); } sprintf(baseUrl,"%.*s", sizeof(baseUrl), argv[i+1]); } } } /* ** Name of a temporary file */ static char zTemp[] = "index.html.orig"; /* ** The main routine */ int main(int argc, char **argv){ int i; /* Loop counter */ int nErr; /* Number of errors */ int rc; /* Result code */ char *zUrl = 0; /* The URL */ FILE *in; /* For reading the raw html */ if( argc<2 ) usage(argv[0]); zUrl = 0; for(i=1; i<argc; i++){ if( strcmp(argv[i],"-quiet")==0 ){ quiet = 1; }else if( argv[i][0]=='-' ){ usage(argv[0]); }else{ zUrl = argv[i]; } } if( zUrl==0 ) usage(argv[0]); rc = HttpFetch(zUrl, zTemp, quiet, sizeof(baseUrl), baseUrl); if( rc!=200 ){ unlink(zTemp); fprintf(stderr,"Unable to fetch base page %s\n", zUrl); exit(1); } in = fopen(zTemp,"r"); /* unlink(zTemp); */ if( in==0 ){ perror("can't reopen temporary file!"); exit(1); } html = fopen("index.html","w"); if( html==0 ){ perror("can't open output file \"index.html\""); exit(1); } SgmlWordHandler(WordHandler); SgmlSpaceHandler(WordHandler); SgmlCommentHandler(WordHandler); SgmlDefaultMarkupHandler(DefaultMarkup); SgmlHandler("img", ImageMarkup); SgmlHandler("base", BaseMarkup); SgmlParse(in, 0); fclose(in); fclose(html); return global_nErr; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/sgmlparse.c���������������������������������������������������������������0000644�0001750�0001750�00000012705�07504443354�016571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** This file contains code used to tokenize SGML. */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <assert.h> #include "sgmlparse.h" #define stricmp strcasecmp /* These three pointers define certain special handlers. All whitespace ** is sent to xSpaceHandler. Non-whitespace is given to xWordHandler. ** Any markup that isn't specifically directed elsewhere is given ** to xDefaultMarkupHandlers. */ static void (*xSpaceHandler)(const char*,void*); static void (*xWordHandler)(const char*,void*); static void (*xCommentHandler)(const char*,void*); static void (*xDefaultMarkupHandler)(int, const char**, void*); /* Each handler is stored in a hash table as an instance of the ** following structure. */ typedef struct sgHandler Handler; struct sgHandler { char *zName; /* Name of markup to handle */ void (*xHandler)(int, const char**, void*); /* Routine to do the work */ Handler *pCollide; /* Next handler with same hash */ }; /* The size of the handler hash table. ** For best results, this should be a prime number which is larger than ** the number of markups in the hash table. */ #define SGML_HASH_SIZE 203 /* The handler hash table */ static Handler *apHandler[SGML_HASH_SIZE]; /* Hash a handler name */ static int SgmlHash(const char *zName){ int h = 0; char c; while( (c=*zName)!=0 ){ if( isupper(c) ) c = tolower(c); h = h<<5 ^ h ^ c; zName++; } if( h<0 ) h = -h; return h % SGML_HASH_SIZE; } /* Given a pointer to an input file, read and parse that file ** as if it were SGML. ** ** This is not a true SGML parser because it handles some unusual ** cases differently, and ignores the & operator completely. */ void SgmlParse(FILE *in, void *pArg){ int c; int i, j; int argc; Handler *pHandler; char *argv[100]; char zBuf[10000]; c = getc(in); while( c!=EOF ){ if( isspace(c) ){ /* Case 1: spaces */ zBuf[0] = c; i = 1; while( i<sizeof(zBuf)-2 && (c=getc(in))!=EOF && isspace(c) ){ zBuf[i++] = c; } zBuf[i] = 0; /* Dispose of space */ if( xSpaceHandler ){ (*xSpaceHandler)(zBuf,pArg); } }else if( c=='<' ){ int cQuote = 0; i = 0; zBuf[i++] = c; while( (c=getc(in))!=EOF && (cQuote || c!='>') ){ if( i<sizeof(zBuf)-3 ) zBuf[i++] = c; if( cQuote ){ if( cQuote==c ) cQuote = 0; }else if( c=='"' || c=='\'' ){ cQuote = c; } } if( c=='>' ) c = getc(in); zBuf[i] = 0; if( strncmp(zBuf,"<!--",4)==0 ){ zBuf[i++] = '>'; zBuf[i] = 0; if( xCommentHandler ){ (*xCommentHandler)(zBuf,pArg); } continue; } argc = 0; argv[0] = &zBuf[1]; for(j=1; zBuf[j] && !isspace(zBuf[j]); j++){} if( zBuf[j] ){ zBuf[j++] = 0; while( argc<(sizeof(argv)/sizeof(argv[0])) - 4 && zBuf[j] ){ while( isspace(zBuf[j]) ) j++; argv[++argc] = &zBuf[j]; while( zBuf[j] && !isspace(zBuf[j]) && zBuf[j]!='=' ) j++; if( zBuf[j]!='=' ){ argv[argc+1] = argv[argc]; argc++; if( zBuf[j] ) zBuf[j++] = 0; continue; } zBuf[j++] = 0; if( zBuf[j]=='"' || zBuf[j]=='\'' ){ cQuote = zBuf[j++]; }else{ cQuote = 0; } argv[++argc] = &zBuf[j]; if( cQuote ){ while( zBuf[j] && zBuf[j]!=cQuote ) j++; }else{ while( zBuf[j] && !isspace(zBuf[j]) ) j++; } if( zBuf[j] ) zBuf[j++] = 0; } } argv[++argc] = 0; /* Despose of a markup */ pHandler = apHandler[SgmlHash(argv[0])]; while( pHandler && stricmp(pHandler->zName,argv[0])!=0 ){ pHandler = pHandler->pCollide; } if( pHandler ){ if( pHandler->xHandler ){ (*pHandler->xHandler)(argc,(const char**)argv,pArg); } }else if( xDefaultMarkupHandler ){ (*xDefaultMarkupHandler)(argc,(const char**)argv,pArg); } }else{ zBuf[0] = c; i = 1; while( i<sizeof(zBuf)-2 && (c=getc(in))!=EOF && c!='<' && !isspace(c) ){ zBuf[i++] = c; } zBuf[i] = 0; /* Dispose of a word */ if( xWordHandler ){ (*xWordHandler)(zBuf,pArg); } } } } /* ** Clear out the handler hash table */ void SgmlHandlerReset(void){ Handler *pHandler; int i; for(i=0; i<SGML_HASH_SIZE; i++){ Handler *pNext; for(pHandler=apHandler[i]; pHandler; pHandler=pNext){ pNext = pHandler->pCollide; free(pHandler); } apHandler[i] = 0; } } /* Install a new handler */ void SgmlHandler(const char *zName, void (*xFunc)(int,const char**,void*)){ int h = SgmlHash(zName); extern void *malloc(); Handler *pNew = malloc( sizeof(Handler) + strlen(zName) + 1 ); if( pNew==0 ) return; pNew->zName = (char*)&pNew[1]; strcpy(pNew->zName,zName); pNew->pCollide = apHandler[h]; pNew->xHandler = xFunc; apHandler[h] = pNew; } /* Install the default handlers */ void SgmlWordHandler(void (*xWord)(const char*,void*)){ xWordHandler = xWord; } void SgmlSpaceHandler(void (*xSpace)(const char*,void*)){ xSpaceHandler = xSpace; } void SgmlCommentHandler(void (*xComment)(const char*,void*)){ xCommentHandler = xComment; } void SgmlDefaultMarkupHandler(void (*xMarkup)(int,const char**,void*)){ xDefaultMarkupHandler = xMarkup; } �����������������������������������������������������������./saods9/htmlwidget/tools/makeheaders.c�������������������������������������������������������������0000644�0001750�0001750�00000261116�07504443354�017047� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** This program scans C and C++ source files and automatically generates ** appropriate header files. ** %Z% %P% %I% %G% %Z% */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <memory.h> #include <sys/stat.h> #include <assert.h> #ifndef WIN32 # include <unistd.h> #else # include <string.h> #endif /* ** Macros for debugging. */ #ifdef DEBUG static int debugMask = 0; # define debug0(F,M) if( (F)&debugMask ){ fprintf(stderr,M); } # define debug1(F,M,A) if( (F)&debugMask ){ fprintf(stderr,M,A); } # define debug2(F,M,A,B) if( (F)&debugMask ){ fprintf(stderr,M,A,B); } # define debug3(F,M,A,B,C) if( (F)&debugMask ){ fprintf(stderr,M,A,B,C); } # define PARSER 0x00000001 # define DECL_DUMP 0x00000002 # define TOKENIZER 0x00000004 #else # define debug0(Flags, Format) # define debug1(Flags, Format, A) # define debug2(Flags, Format, A, B) # define debug3(Flags, Format, A, B, C) #endif /* ** The following macros are purely for the purpose of testing this ** program on itself. They don't really contribute to the code. */ #define INTERFACE 1 #define EXPORT_INTERFACE 1 #define EXPORT /* ** Each token in a source file is represented by an instance of ** the following structure. Tokens are collected onto a list. */ typedef struct Token Token; struct Token { const char *zText; /* The text of the token */ int nText; /* Number of characters in the token's text */ int eType; /* The type of this token */ int nLine; /* The line number on which the token starts */ Token *pComment; /* Most recent block comment before this token */ Token *pNext; /* Next token on the list */ Token *pPrev; /* Previous token on the list */ }; /* ** During tokenization, information about the state of the input ** stream is held in an instance of the following structure */ typedef struct InStream InStream; struct InStream { const char *z; /* Complete text of the input */ int i; /* Next character to read from the input */ int nLine; /* The line number for character z[i] */ }; /* ** Each declaration in the C or C++ source files is parsed out and stored as ** an instance of the following structure. ** ** A "forward declaration" is a declaration that an object exists that ** doesn't tell about the objects structure. A typical forward declaration ** is: ** ** struct Xyzzy; ** ** Not every object has a forward declaration. If it does, thought, the ** forward declaration will be contained in the zFwd field for C and ** the zFwdCpp for C++. The zDecl field contains the complete ** declaration text. */ typedef struct Decl Decl; struct Decl { char *zName; /* Name of the object being declared. The appearance ** of this name is a source file triggers the declaration ** to be added to the header for that file. */ char *zFile; /* File from which extracted. */ char *zIf; /* Surround the declaration with this #if */ char *zFwd; /* A forward declaration. NULL if there is none. */ char *zFwdCpp; /* Use this forward declaration for C++. */ char *zDecl; /* A full declaration of this object */ struct Include *pInclude; /* #includes that come before this declaration */ int flags; /* See the "Properties" below */ Token *pComment; /* A block comment associated with this declaration */ Token tokenCode; /* Implementation of functions and procedures */ Decl *pSameName; /* Next declaration with the same "zName" */ Decl *pSameHash; /* Next declaration with same hash but different zName */ Decl *pNext; /* Next declaration with a different name */ }; /* ** Properties associated with declarations. ** ** DP_Forward and DP_Declared are used during the generation of a single ** header file in order to prevent duplicate declarations and definitions. ** DP_Forward is set after the object has been given a forward declaration ** and DP_Declared is set after the object gets a full declarations. ** (Example: A forward declaration is "typedef struct Abc Abc;" and the ** full declaration is "struct Abc { int a; float b; };".) ** ** The DP_Export and DP_Local flags are more permanent. They mark objects ** that have EXPORT scope and LOCAL scope respectively. If both of these ** marks are missing, then the object has library scope. The meanings of ** the scopes are as follows: ** ** LOCAL scope The object is only usable within the file in ** which it is declared. ** ** library scope The object is visible and usable within other ** files in the same project. By if the project is ** a library, then the object is not visible to users ** of the library. (i.e. the object does not appear ** in the output when using the -H option.) ** ** EXPORT scope The object is visible and usable everywhere. ** ** The DP_Flag is a temporary use flag that is used during processing to ** prevent an infinite loop. It's use is localized. ** ** The DP_Cplusplus, DP_ExternCReqd and DP_ExternReqd flags are permanent ** and are used to specify what type of declaration the object requires. */ #define DP_Forward 0x001 /* Has a forward declaration in this file */ #define DP_Declared 0x002 /* Has a full declaration in this file */ #define DP_Export 0x004 /* Export this declaration */ #define DP_Local 0x008 /* Declare in its home file only */ #define DP_Flag 0x010 /* Use to mark a subset of a Decl list ** for special processing */ #define DP_Cplusplus 0x020 /* Has C++ linkage and cannot appear in a ** C header file */ #define DP_ExternCReqd 0x040 /* Prepend 'extern "C"' in a C++ header. ** Prepend nothing in a C header */ #define DP_ExternReqd 0x080 /* Prepend 'extern "C"' in a C++ header if ** DP_Cplusplus is not also set. If DP_Cplusplus ** is set or this is a C header then ** prepend 'extern' */ /* ** Convenience macros for dealing with declaration properties */ #define DeclHasProperty(D,P) (((D)->flags&(P))==(P)) #define DeclHasAnyProperty(D,P) (((D)->flags&(P))!=0) #define DeclSetProperty(D,P) (D)->flags |= (P) #define DeclClearProperty(D,P) (D)->flags &= ~(P) /* ** These are state properties of the parser. Each of the values is ** distinct from the DP_ values above so that both can be used in ** the same "flags" field. ** ** Be careful not to confuse PS_Export with DP_Export or ** PS_Local with DP_Local. Their names are similar, but the meanings ** of these flags are very different. */ #define PS_Extern 0x000800 /* "extern" has been seen */ #define PS_Export 0x001000 /* If between "#if EXPORT_INTERFACE" ** and "#endif" */ #define PS_Export2 0x002000 /* If "EXPORT" seen */ #define PS_Typedef 0x004000 /* If "typedef" has been seen */ #define PS_Static 0x008000 /* If "static" has been seen */ #define PS_Interface 0x010000 /* If within #if INTERFACE..#endif */ #define PS_Method 0x020000 /* If "::" token has been seen */ #define PS_Local 0x040000 /* If within #if LOCAL_INTERFACE..#endif */ #define PS_Local2 0x080000 /* If "LOCAL" seen. */ /* ** The following set of flags are ORed into the "flags" field of ** a Decl in order to identify what type of object is being ** declared. */ #define TY_Class 0x00100000 #define TY_Subroutine 0x00200000 #define TY_Macro 0x00400000 #define TY_Typedef 0x00800000 #define TY_Variable 0x01000000 #define TY_Structure 0x02000000 #define TY_Union 0x04000000 #define TY_Enumeration 0x08000000 #define TY_Defunct 0x10000000 /* Used to erase a declaration */ /* ** Each nested #if (or #ifdef or #ifndef) is stored in a stack of ** instances of the following structure. */ typedef struct Ifmacro Ifmacro; struct Ifmacro { int nLine; /* Line number where this macro occurs */ char *zCondition; /* Text of the condition for this macro */ Ifmacro *pNext; /* Next down in the stack */ int flags; /* Can hold PS_Export, PS_Interface or PS_Local flags */ }; /* ** When parsing a file, we need to keep track of what other files have ** be #include-ed. For each #include found, we create an instance of ** the following structure. */ typedef struct Include Include; struct Include { char *zFile; /* The name of file include. Includes "" or <> */ char *zIf; /* If not NULL, #include should be enclosed in #if */ char *zLabel; /* A unique label used to test if this #include has * appeared already in a file or not */ Include *pNext; /* Previous include file, or NULL if this is the first */ }; /* ** Identifiers found in a source file that might be used later to provoke ** the copying of a declaration into the corresponding header file are ** stored in a hash table as instances of the following structure. */ typedef struct Ident Ident; struct Ident { char *zName; /* The text of this identifier */ Ident *pCollide; /* Next identifier with the same hash */ Ident *pNext; /* Next identifier in a list of them all */ }; /* ** A complete table of identifiers is stored in an instance of ** the next structure. */ #define IDENT_HASH_SIZE 2237 typedef struct IdentTable IdentTable; struct IdentTable { Ident *pList; /* List of all identifiers in this table */ Ident *apTable[IDENT_HASH_SIZE]; /* The hash table */ }; /* ** The following structure holds all information for a single ** source file named on the command line of this program. */ typedef struct InFile InFile; struct InFile { char *zSrc; /* Name of input file */ char *zHdr; /* Name of the generated .h file for this input. ** Will be NULL if input is to be scanned only */ int flags; /* One or more DP_, PS_ and/or TY_ flags */ InFile *pNext; /* Next input file in the list of them all */ IdentTable idTable; /* All identifiers in this input file */ }; /* ** An unbounded string is able to grow without limit. We use these ** to construct large in-memory strings from lots of smaller components. */ typedef struct String String; struct String { int nAlloc; /* Number of bytes allocated */ int nUsed; /* Number of bytes used (not counting null terminator) */ char *zText; /* Text of the string */ }; /* ** The following structure contains a lot of state information used ** while generating a .h file. We put the information in this structure ** and pass around a pointer to this structure, rather than pass around ** all of the information separately. This helps reduce the number of ** arguments to generator functions. */ typedef struct GenState GenState; struct GenState { String *pStr; /* Write output to this string */ IdentTable *pTable; /* A table holding the zLabel of every #include that * has already been generated. Used to avoid * generating duplicate #includes. */ const char *zIf; /* If not NULL, then we are within a #if with * this argument. */ int nErr; /* Number of errors */ const char *zFilename; /* Name of the source file being scanned */ int flags; /* Various flags (DP_ and PS_ flags above) */ }; /* ** The following text line appears at the top of every file generated ** by this program. By recognizing this line, the program can be sure ** never to read a file that it generated itself. */ const char zTopLine[] = "/* \aThis file was automatically generated. Do not edit! */\n"; #define nTopLine (sizeof(zTopLine)-1) /* ** The name of the file currently being parsed. */ static char *zFilename; /* ** The stack of #if macros for the file currently being parsed. */ static Ifmacro *ifStack = 0; /* ** A list of all files that have been #included so far in a file being ** parsed. */ static Include *includeList = 0; /* ** The last block comment seen. */ static Token *blockComment = 0; /* ** The following flag is set if the -doc flag appears on the ** command line. */ static int doc_flag = 0; /* ** If the following flag is set, then makeheaders will attempt to ** generate prototypes for static functions and procedures. */ static int proto_static = 0; /* ** A list of all declarations. The list is held together using the ** pNext field of the Decl structure. */ static Decl *pDeclFirst; /* First on the list */ static Decl *pDeclLast; /* Last on the list */ /* ** A hash table of all declarations */ #define DECL_HASH_SIZE 3371 static Decl *apTable[DECL_HASH_SIZE]; /* ** The TEST macro must be defined to something. Make sure this is the ** case. */ #ifndef TEST # define TEST 0 #endif #ifdef NOT_USED /* ** We do our own assertion macro so that we can have more control ** over debugging. */ #define Assert(X) if(!(X)){ CantHappen(__LINE__); } #define CANT_HAPPEN CantHappen(__LINE__) static void CantHappen(int iLine){ fprintf(stderr,"Assertion failed on line %d\n",iLine); *(char*)1 = 0; /* Force a core-dump */ } #endif /* ** Memory allocation functions that are guaranteed never to return NULL. */ static void *SafeMalloc(int nByte){ void *p = malloc( nByte ); if( p==0 ){ fprintf(stderr,"Out of memory. Can't allocate %d bytes.\n",nByte); exit(1); } return p; } static void SafeFree(void *pOld){ if( pOld ){ free(pOld); } } static void *SafeRealloc(void *pOld, int nByte){ void *p; if( pOld==0 ){ p = SafeMalloc(nByte); }else{ p = realloc(pOld, nByte); if( p==0 ){ fprintf(stderr, "Out of memory. Can't enlarge an allocation to %d bytes\n",nByte); exit(1); } } return p; } static char *StrDup(const char *zSrc, int nByte){ char *zDest; if( nByte<=0 ){ nByte = strlen(zSrc); } zDest = SafeMalloc( nByte + 1 ); strncpy(zDest,zSrc,nByte); zDest[nByte] = 0; return zDest; } /* ** Return TRUE if the character X can be part of an identifier */ #define ISALNUM(X) ((X)=='_' || isalnum(X)) /* ** Routines for dealing with unbounded strings. */ static void StringInit(String *pStr){ pStr->nAlloc = 0; pStr->nUsed = 0; pStr->zText = 0; } static void StringReset(String *pStr){ SafeFree(pStr->zText); StringInit(pStr); } static void StringAppend(String *pStr, const char *zText, int nByte){ if( nByte<=0 ){ nByte = strlen(zText); } if( pStr->nUsed + nByte >= pStr->nAlloc ){ if( pStr->nAlloc==0 ){ pStr->nAlloc = nByte + 100; pStr->zText = SafeMalloc( pStr->nAlloc ); }else{ pStr->nAlloc = pStr->nAlloc*2 + nByte; pStr->zText = SafeRealloc(pStr->zText, pStr->nAlloc); } } strncpy(&pStr->zText[pStr->nUsed],zText,nByte); pStr->nUsed += nByte; pStr->zText[pStr->nUsed] = 0; } #define StringGet(S) ((S)->zText?(S)->zText:"") /* ** Compute a hash on a string. The number returned is a non-negative ** value between 0 and 2**31 - 1 */ static int Hash(const char *z, int n){ int h = 0; if( n<=0 ){ n = strlen(z); } while( n-- ){ h = h ^ (h<<5) ^ *z++; } if( h<0 ) h = -h; return h; } /* ** Given an identifier name, try to find a declaration for that ** identifier in the hash table. If found, return a pointer to ** the Decl structure. If not found, return 0. */ static Decl *FindDecl(const char *zName, int len){ int h; Decl *p; if( len<=0 ){ len = strlen(zName); } h = Hash(zName,len) % DECL_HASH_SIZE; p = apTable[h]; while( p && (strncmp(p->zName,zName,len)!=0 || p->zName[len]!=0) ){ p = p->pSameHash; } return p; } /* ** Install the given declaration both in the hash table and on ** the list of all declarations. */ static void InstallDecl(Decl *pDecl){ int h; Decl *pOther; h = Hash(pDecl->zName,0) % DECL_HASH_SIZE; pOther = apTable[h]; while( pOther && strcmp(pDecl->zName,pOther->zName)!=0 ){ pOther = pOther->pSameHash; } if( pOther ){ pDecl->pSameName = pOther->pSameName; pOther->pSameName = pDecl; }else{ pDecl->pSameName = 0; pDecl->pSameHash = apTable[h]; apTable[h] = pDecl; } pDecl->pNext = 0; if( pDeclFirst==0 ){ pDeclFirst = pDeclLast = pDecl; }else{ pDeclLast->pNext = pDecl; pDeclLast = pDecl; } } /* ** Look at the current ifStack. If anything declared at the current ** position must be surrounded with ** ** #if STUFF ** #endif ** ** Then this routine computes STUFF and returns a pointer to it. Memory ** to hold the value returned is obtained from malloc(). */ static char *GetIfString(void){ Ifmacro *pIf; char *zResult = 0; int hasIf = 0; String str; for(pIf = ifStack; pIf; pIf=pIf->pNext){ if( pIf->zCondition==0 || *pIf->zCondition==0 ) continue; if( !hasIf ){ hasIf = 1; StringInit(&str); }else{ StringAppend(&str," && ",4); } StringAppend(&str,pIf->zCondition,0); } if( hasIf ){ zResult = StrDup(StringGet(&str),0); StringReset(&str); }else{ zResult = 0; } return zResult; } /* ** Create a new declaration and put it in the hash table. Also ** return a pointer to it so that we can fill in the zFwd and zDecl ** fields, and so forth. */ static Decl *CreateDecl( const char *zName, /* Name of the object being declared. */ int nName /* Length of the name */ ){ Decl *pDecl; pDecl = SafeMalloc( sizeof(Decl) + nName + 1); memset(pDecl,0,sizeof(Decl)); pDecl->zName = (char*)&pDecl[1]; sprintf(pDecl->zName,"%.*s",nName,zName); pDecl->zFile = zFilename; pDecl->pInclude = includeList; pDecl->zIf = GetIfString(); InstallDecl(pDecl); return pDecl; } /* ** Insert a new identifier into an table of identifiers. Return TRUE if ** a new identifier was inserted and return FALSE if the identifier was ** already in the table. */ static int IdentTableInsert( IdentTable *pTable, /* The table into which we will insert */ const char *zId, /* Name of the identifiers */ int nId /* Length of the identifier name */ ){ int h; Ident *pId; if( nId<=0 ){ nId = strlen(zId); } h = Hash(zId,nId) % IDENT_HASH_SIZE; for(pId = pTable->apTable[h]; pId; pId=pId->pCollide){ if( strncmp(zId,pId->zName,nId)==0 && pId->zName[nId]==0 ){ /* printf("Already in table: %.*s\n",nId,zId); */ return 0; } } pId = SafeMalloc( sizeof(Ident) + nId + 1 ); pId->zName = (char*)&pId[1]; sprintf(pId->zName,"%.*s",nId,zId); pId->pNext = pTable->pList; pTable->pList = pId; pId->pCollide = pTable->apTable[h]; pTable->apTable[h] = pId; /* printf("Add to table: %.*s\n",nId,zId); */ return 1; } /* ** Check to see if the given value is in the given IdentTable. Return ** true if it is and false if it is not. */ static int IdentTableTest( IdentTable *pTable, /* The table in which to search */ const char *zId, /* Name of the identifiers */ int nId /* Length of the identifier name */ ){ int h; Ident *pId; if( nId<=0 ){ nId = strlen(zId); } h = Hash(zId,nId) % IDENT_HASH_SIZE; for(pId = pTable->apTable[h]; pId; pId=pId->pCollide){ if( strncmp(zId,pId->zName,nId)==0 && pId->zName[nId]==0 ){ return 1; } } return 0; } /* ** Remove every identifier from the given table. Reset the table to ** its initial state. */ static void IdentTableReset(IdentTable *pTable){ Ident *pId, *pNext; for(pId = pTable->pList; pId; pId = pNext){ pNext = pId->pNext; SafeFree(pId); } memset(pTable,0,sizeof(IdentTable)); } #ifdef DEBUG /* ** Print the name of every identifier in the given table, one per line */ static void IdentTablePrint(IdentTable *pTable, FILE *pOut){ Ident *pId; for(pId = pTable->pList; pId; pId = pId->pNext){ fprintf(pOut,"%s\n",pId->zName); } } #endif /* ** Read an entire file into memory. Return a pointer to the memory. ** ** The memory is obtained from SafeMalloc and must be freed by the ** calling function. ** ** If the read fails for any reason, 0 is returned. */ static char *ReadFile(const char *zFilename){ struct stat sStat; FILE *pIn; char *zBuf; int n; if( stat(zFilename,&sStat)!=0 #ifndef WIN32 || !S_ISREG(sStat.st_mode) #endif ){ return 0; } pIn = fopen(zFilename,"r"); if( pIn==0 ){ return 0; } zBuf = SafeMalloc( sStat.st_size + 1 ); n = fread(zBuf,1,sStat.st_size,pIn); zBuf[n] = 0; fclose(pIn); return zBuf; } /* ** Write the contents of a string into a file. Return the number of ** errors */ static int WriteFile(const char *zFilename, const char *zOutput){ FILE *pOut; pOut = fopen(zFilename,"w"); if( pOut==0 ){ return 1; } fwrite(zOutput,1,strlen(zOutput),pOut); fclose(pOut); return 0; } /* ** Major token types */ #define TT_Space 1 /* Contiguous white space */ #define TT_Id 2 /* An identifier */ #define TT_Preprocessor 3 /* Any C preprocessor directive */ #define TT_Comment 4 /* Either C or C++ style comment */ #define TT_Number 5 /* Any numeric constant */ #define TT_String 6 /* String or character constants. ".." or '.' */ #define TT_Braces 7 /* All text between { and a matching } */ #define TT_EOF 8 /* End of file */ #define TT_Error 9 /* An error condition */ #define TT_BlockComment 10 /* A C-Style comment at the left margin that * spans multple lines */ #define TT_Other 0 /* None of the above */ /* ** Get a single low-level token from the input file. Update the ** file pointer so that it points to the first character beyond the ** token. ** ** A "low-level token" is any token except TT_Braces. A TT_Braces token ** consists of many smaller tokens and is assembled by a routine that ** calls this one. ** ** The function returns the number of errors. An error is an ** unterminated string or character literal or an unterminated ** comment. ** ** Profiling shows that this routine consumes about half the ** CPU time on a typical run of makeheaders. */ static int GetToken(InStream *pIn, Token *pToken){ int i; const char *z; int cStart; int c; int startLine; /* Line on which a structure begins */ int nlisc = 0; /* True if there is a new-line in a ".." or '..' */ int nErr = 0; /* Number of errors seen */ z = pIn->z; i = pIn->i; pToken->nLine = pIn->nLine; pToken->zText = &z[i]; switch( z[i] ){ case 0: pToken->eType = TT_EOF; pToken->nText = 0; break; case '#': if( i==0 || z[i-1]=='\n' || (i>1 && z[i-1]=='\r' && z[i-2]=='\n')){ /* We found a preprocessor statement */ pToken->eType = TT_Preprocessor; i++; while( z[i]!=0 && z[i]!='\n' ){ if( z[i]=='\\' ){ i++; if( z[i]=='\n' ) pIn->nLine++; } i++; } pToken->nText = i - pIn->i; }else{ /* Just an operator */ pToken->eType = TT_Other; pToken->nText = 1; } break; case ' ': case '\t': case '\r': case '\f': case '\n': while( isspace(z[i]) ){ if( z[i]=='\n' ) pIn->nLine++; i++; } pToken->eType = TT_Space; pToken->nText = i - pIn->i; break; case '\\': pToken->nText = 2; pToken->eType = TT_Other; if( z[i+1]=='\n' ){ pIn->nLine++; pToken->eType = TT_Space; }else if( z[i+1]==0 ){ pToken->nText = 1; } break; case '\'': case '\"': cStart = z[i]; startLine = pIn->nLine; do{ i++; c = z[i]; if( c=='\n' ){ if( !nlisc ){ fprintf(stderr, "%s:%d: (warning) Newline in string or character literal.\n", zFilename, pIn->nLine); nlisc = 1; } pIn->nLine++; } if( c=='\\' ){ i++; c = z[i]; if( c=='\n' ){ pIn->nLine++; } }else if( c==cStart ){ i++; c = 0; }else if( c==0 ){ fprintf(stderr, "%s:%d: Unterminated string or character literal.\n", zFilename, startLine); nErr++; } }while( c ); pToken->eType = TT_String; pToken->nText = i - pIn->i; break; case '/': if( z[i+1]=='/' ){ /* C++ style comment */ while( z[i] && z[i]!='\n' ){ i++; } pToken->eType = TT_Comment; pToken->nText = i - pIn->i; }else if( z[i+1]=='*' ){ /* C style comment */ int isBlockComment = i==0 || z[i-1]=='\n'; i += 2; startLine = pIn->nLine; while( z[i] && (z[i]!='*' || z[i+1]!='/') ){ if( z[i]=='\n' ){ pIn->nLine++; if( isBlockComment ){ if( z[i+1]=='*' || z[i+2]=='*' ){ isBlockComment = 2; }else{ isBlockComment = 0; } } } i++; } if( z[i] ){ i += 2; }else{ isBlockComment = 0; fprintf(stderr,"%s:%d: Unterminated comment\n", zFilename, startLine); nErr++; } pToken->eType = isBlockComment==2 ? TT_BlockComment : TT_Comment; pToken->nText = i - pIn->i; }else{ /* A divide operator */ pToken->eType = TT_Other; pToken->nText = 1; } break; case '0': if( z[i+1]=='x' || z[i+1]=='X' ){ /* A hex constant */ i += 2; while( isxdigit(z[i]) ){ i++; } }else{ /* An octal constant */ while( isdigit(z[i]) ){ i++; } } pToken->eType = TT_Number; pToken->nText = i - pIn->i; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': while( isdigit(z[i]) ){ i++; } if( (c=z[i])=='.' ){ i++; while( isdigit(z[i]) ){ i++; } c = z[i]; if( c=='e' || c=='E' ){ i++; if( ((c=z[i])=='+' || c=='-') && isdigit(z[i+1]) ){ i++; } while( isdigit(z[i]) ){ i++; } c = z[i]; } if( c=='f' || c=='F' || c=='l' || c=='L' ){ i++; } }else if( c=='e' || c=='E' ){ i++; if( ((c=z[i])=='+' || c=='-') && isdigit(z[i+1]) ){ i++; } while( isdigit(z[i]) ){ i++; } }else if( c=='L' || c=='l' ){ i++; c = z[i]; if( c=='u' || c=='U' ){ i++; } }else if( c=='u' || c=='U' ){ i++; c = z[i]; if( c=='l' || c=='L' ){ i++; } } pToken->eType = TT_Number; pToken->nText = i - pIn->i; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': while( isalnum(z[i]) || z[i]=='_' ){ i++; }; pToken->eType = TT_Id; pToken->nText = i - pIn->i; break; default: pToken->eType = TT_Other; pToken->nText = 1; break; } pIn->i += pToken->nText; return nErr; } /* ** This routine recovers the next token from the input file which is ** not a space or a comment or any text between an "#if 0" and "#endif". ** ** This routine returns the number of errors encountered. An error ** is an unterminated token or unmatched "#if 0". ** ** Profiling shows that this routine uses about a quarter of the ** CPU time in a typical run. */ static int GetNonspaceToken(InStream *pIn, Token *pToken){ int nIf = 0; int inZero = 0; const char *z; int value; int startLine; int nErr = 0; startLine = pIn->nLine; while( 1 ){ nErr += GetToken(pIn,pToken); /* printf("%04d: Type=%d nIf=%d [%.*s]\n", pToken->nLine,pToken->eType,nIf,pToken->nText, pToken->eType!=TT_Space ? pToken->zText : "<space>"); */ pToken->pComment = blockComment; switch( pToken->eType ){ case TT_Comment: case TT_Space: break; case TT_BlockComment: if( doc_flag ){ blockComment = SafeMalloc( sizeof(Token) ); *blockComment = *pToken; } break; case TT_EOF: if( nIf ){ fprintf(stderr,"%s:%d: Unterminated \"#if\"\n", zFilename, startLine); nErr++; } return nErr; case TT_Preprocessor: z = &pToken->zText[1]; while( *z==' ' || *z=='\t' ) z++; if( sscanf(z,"if %d",&value)==1 && value==0 ){ nIf++; inZero = 1; }else if( inZero ){ if( strncmp(z,"if",2)==0 ){ nIf++; }else if( strncmp(z,"endif",5)==0 ){ nIf--; if( nIf==0 ) inZero = 0; } }else{ return nErr; } break; default: if( !inZero ){ return nErr; } break; } } /* NOT REACHED */ } /* ** This routine looks for identifiers (strings of contiguous alphanumeric ** characters) within a preprocessor directive and adds every such string ** found to the given identifier table */ static void FindIdentifiersInMacro(Token *pToken, IdentTable *pTable){ Token sToken; InStream sIn; int go = 1; sIn.z = pToken->zText; sIn.i = 1; sIn.nLine = 1; while( go && sIn.i < pToken->nText ){ GetToken(&sIn,&sToken); switch( sToken.eType ){ case TT_Id: IdentTableInsert(pTable,sToken.zText,sToken.nText); break; case TT_EOF: go = 0; break; default: break; } } } /* ** This routine gets the next token. Everything contained within ** {...} is collapsed into a single TT_Braces token. Whitespace is ** omitted. ** ** If pTable is not NULL, then insert every identifier seen into the ** IdentTable. This includes any identifiers seen inside of {...}. ** ** The number of errors encountered is returned. An error is an ** unterminated token. */ static int GetBigToken(InStream *pIn, Token *pToken, IdentTable *pTable){ const char *z, *zStart; int iStart; int nBrace; int c; int nLine; int nErr; nErr = GetNonspaceToken(pIn,pToken); switch( pToken->eType ){ case TT_Id: if( pTable!=0 ){ IdentTableInsert(pTable,pToken->zText,pToken->nText); } return nErr; case TT_Preprocessor: if( pTable!=0 ){ FindIdentifiersInMacro(pToken,pTable); } return nErr; case TT_Other: if( pToken->zText[0]=='{' ) break; return nErr; default: return nErr; } z = pIn->z; iStart = pIn->i; zStart = pToken->zText; nLine = pToken->nLine; nBrace = 1; while( nBrace ){ nErr += GetNonspaceToken(pIn,pToken); /* printf("%04d: nBrace=%d [%.*s]\n",pToken->nLine,nBrace, pToken->nText,pToken->zText); */ switch( pToken->eType ){ case TT_EOF: fprintf(stderr,"%s:%d: Unterminated \"{\"\n", zFilename, nLine); nErr++; pToken->eType = TT_Error; return nErr; case TT_Id: if( pTable ){ IdentTableInsert(pTable,pToken->zText,pToken->nText); } break; case TT_Preprocessor: if( pTable!=0 ){ FindIdentifiersInMacro(pToken,pTable); } break; case TT_Other: if( (c = pToken->zText[0])=='{' ){ nBrace++; }else if( c=='}' ){ nBrace--; } break; default: break; } } pToken->eType = TT_Braces; pToken->nText = 1 + pIn->i - iStart; pToken->zText = zStart; pToken->nLine = nLine; return nErr; } /* ** This routine frees up a list of Tokens. The pComment tokens are ** not cleared by this. So we leak a little memory when using the -doc ** option. So what. */ static void FreeTokenList(Token *pList){ Token *pNext; while( pList ){ pNext = pList->pNext; SafeFree(pList); pList = pNext; } } /* ** Tokenize an entire file. Return a pointer to the list of tokens. ** ** Space for each token is obtained from a separate malloc() call. The ** calling function is responsible for freeing this space. ** ** If pTable is not NULL, then fill the table with all identifiers seen in ** the input file. */ static Token *TokenizeFile(const char *zFile, IdentTable *pTable){ InStream sIn; Token *pFirst = 0, *pLast = 0, *pNew; int nErr = 0; sIn.z = zFile; sIn.i = 0; sIn.nLine = 1; blockComment = 0; while( sIn.z[sIn.i]!=0 ){ pNew = SafeMalloc( sizeof(Token) ); nErr += GetBigToken(&sIn,pNew,pTable); debug3(TOKENIZER, "Token on line %d: [%.*s]\n", pNew->nLine, pNew->nText<50 ? pNew->nText : 50, pNew->zText); if( pFirst==0 ){ pFirst = pLast = pNew; pNew->pPrev = 0; }else{ pLast->pNext = pNew; pNew->pPrev = pLast; pLast = pNew; } if( pNew->eType==TT_EOF ) break; } if( pLast ) pLast->pNext = 0; blockComment = 0; if( nErr ){ FreeTokenList(pFirst); pFirst = 0; } return pFirst; } #if TEST==1 /* ** Use the following routine to test or debug the tokenizer. */ void main(int argc, char **argv){ char *zFile; Token *pList, *p; IdentTable sTable; if( argc!=2 ){ fprintf(stderr,"Usage: %s filename\n",*argv); exit(1); } memset(&sTable,0,sizeof(sTable)); zFile = ReadFile(argv[1]); if( zFile==0 ){ fprintf(stderr,"Can't read file \"%s\"\n",argv[1]); exit(1); } pList = TokenizeFile(zFile,&sTable); for(p=pList; p; p=p->pNext){ int j; switch( p->eType ){ case TT_Space: printf("%4d: Space\n",p->nLine); break; case TT_Id: printf("%4d: Id %.*s\n",p->nLine,p->nText,p->zText); break; case TT_Preprocessor: printf("%4d: Preprocessor %.*s\n",p->nLine,p->nText,p->zText); break; case TT_Comment: printf("%4d: Comment\n",p->nLine); break; case TT_BlockComment: printf("%4d: Block Comment\n",p->nLine); break; case TT_Number: printf("%4d: Number %.*s\n",p->nLine,p->nText,p->zText); break; case TT_String: printf("%4d: String %.*s\n",p->nLine,p->nText,p->zText); break; case TT_Other: printf("%4d: Other %.*s\n",p->nLine,p->nText,p->zText); break; case TT_Braces: for(j=0; j<p->nText && j<30 && p->zText[j]!='\n'; j++){} printf("%4d: Braces %.*s...}\n",p->nLine,j,p->zText); break; case TT_EOF: printf("%4d: End of file\n",p->nLine); break; default: printf("%4d: type %d\n",p->nLine,p->eType); break; } } FreeTokenList(pList); SafeFree(zFile); IdentTablePrint(&sTable,stdout); } #endif #ifdef DEBUG /* ** For debugging purposes, write out a list of tokens. */ static void PrintTokens(Token *pFirst, Token *pLast){ int needSpace = 0; int c; pLast = pLast->pNext; while( pFirst!=pLast ){ switch( pFirst->eType ){ case TT_Preprocessor: printf("\n%.*s\n",pFirst->nText,pFirst->zText); needSpace = 0; break; case TT_Id: case TT_Number: printf("%s%.*s", needSpace ? " " : "", pFirst->nText, pFirst->zText); needSpace = 1; break; default: c = pFirst->zText[0]; printf("%s%.*s", (needSpace && (c=='*' || c=='{')) ? " " : "", pFirst->nText, pFirst->zText); needSpace = pFirst->zText[0]==','; break; } pFirst = pFirst->pNext; } } #endif /* ** Convert a sequence of tokens into a string and return a pointer ** to that string. Space to hold the string is obtained from malloc() ** and must be freed by the calling function. ** ** The characters ";\n" are always appended. */ static char *TokensToString(Token *pFirst, Token *pLast){ char *zReturn; String str; int needSpace = 0; int c; StringInit(&str); pLast = pLast->pNext; while( pFirst!=pLast ){ switch( pFirst->eType ){ case TT_Preprocessor: StringAppend(&str,"\n",1); StringAppend(&str,pFirst->zText,pFirst->nText); StringAppend(&str,"\n",1); needSpace = 0; break; case TT_Id: if( pFirst->nText==6 && pFirst->zText[0]=='E' && strncmp(pFirst->zText,"EXPORT",6)==0 ){ break; } /* Fall thru to the next case */ case TT_Number: if( needSpace ){ StringAppend(&str," ",1); } StringAppend(&str,pFirst->zText,pFirst->nText); needSpace = 1; break; default: c = pFirst->zText[0]; if( needSpace && (c=='*' || c=='{') ){ StringAppend(&str," ",1); } StringAppend(&str,pFirst->zText,pFirst->nText); /* needSpace = pFirst->zText[0]==','; */ needSpace = 0; break; } pFirst = pFirst->pNext; } StringAppend(&str,";\n",2); zReturn = StrDup(StringGet(&str),0); StringReset(&str); return zReturn; } /* ** This routine is called when we see one of the keywords "struct", ** "enum", "union" or "class". This might be the beginning of a ** type declaration. This routine will process the declaration and ** remove the declaration tokens from the input stream. ** ** If this is a type declaration that is immediately followed by a ** semicolon (in other words it isn't also a variable definition) ** then set *pReset to ';'. Otherwise leave *pReset at 0. The ** *pReset flag causes the parser to skip ahead to the next token ** that begins with the value placed in the *pReset flag, if that ** value is different from 0. */ static int ProcessTypeDecl(Token *pList, int flags, int *pReset){ Token *pName, *pEnd; Decl *pDecl; String str; int need_to_collapse = 1; *pReset = 0; if( pList==0 || pList->pNext==0 || pList->pNext->eType!=TT_Id ){ return 0; } pName = pList->pNext; /* Catch the case of "struct Foo;" and skip it. */ if( pName->pNext && pName->pNext->zText[0]==';' ){ *pReset = ';'; return 0; } for(pEnd=pName->pNext; pEnd && pEnd->eType!=TT_Braces; pEnd=pEnd->pNext){ switch( pEnd->zText[0] ){ case '(': case '*': case '[': case '=': case ';': return 0; } } if( pEnd==0 ){ return 0; } /* ** At this point, we know we have a type declaration that is bounded ** by pList and pEnd and has the name pName. */ /* ** If the braces are followed immedately by a semicolon, then we are ** dealing a type declaration only. There is not variable definition ** following the type declaration. So reset... */ if( pEnd->pNext==0 || pEnd->pNext->zText[0]==';' ){ *pReset = ';'; need_to_collapse = 0; }else{ need_to_collapse = 1; } if( proto_static==0 && (flags & (PS_Local|PS_Export|PS_Interface))==0 ){ /* Ignore these objects unless they are explicitly declared as interface, ** or unless the "-local" command line option was specified. */ *pReset = ';'; return 0; } #ifdef DEBUG if( debugMask & PARSER ){ printf("**** Found type: %.*s %.*s...\n", pList->nText, pList->zText, pName->nText, pName->zText); PrintTokens(pList,pEnd); printf(";\n"); } #endif pDecl = CreateDecl(pName->zText,pName->nText); if( (flags & PS_Static) || !(flags & (PS_Interface|PS_Export)) ){ DeclSetProperty(pDecl,DP_Local); } switch( *pList->zText ){ case 'c': DeclSetProperty(pDecl,TY_Class); break; case 's': DeclSetProperty(pDecl,TY_Structure); break; case 'e': DeclSetProperty(pDecl,TY_Enumeration); break; case 'u': DeclSetProperty(pDecl,TY_Union); break; default: /* Can't Happen */ break; } /* The object has a full declaration only if it is contained within ** "#if INTERFACE...#endif" or "#if EXPORT_INTERFACE...#endif" or ** "#if LOCAL_INTERFACE...#endif". Otherwise, we only give it a ** forward declaration. */ if( flags & (PS_Local | PS_Export | PS_Interface) ){ pDecl->zDecl = TokensToString(pList,pEnd); }else{ pDecl->zDecl = 0; } pDecl->pComment = pList->pComment; StringInit(&str); StringAppend(&str,"typedef ",0); StringAppend(&str,pList->zText,pList->nText); StringAppend(&str," ",0); StringAppend(&str,pName->zText,pName->nText); StringAppend(&str," ",0); StringAppend(&str,pName->zText,pName->nText); StringAppend(&str,";\n",2); pDecl->zFwd = StrDup(StringGet(&str),0); StringReset(&str); StringInit(&str); StringAppend(&str,pList->zText,pList->nText); StringAppend(&str," ",0); StringAppend(&str,pName->zText,pName->nText); StringAppend(&str,";\n",2); pDecl->zFwdCpp = StrDup(StringGet(&str),0); StringReset(&str); if( flags & PS_Export ){ DeclSetProperty(pDecl,DP_Export); }else if( flags & PS_Local ){ DeclSetProperty(pDecl,DP_Local); } /* Here's something weird. ANSI-C doesn't allow a forward declaration ** of an enumeration. So we have to build the typedef into the ** definition. */ if( pDecl->zDecl && DeclHasProperty(pDecl, TY_Enumeration) ){ StringInit(&str); StringAppend(&str,pDecl->zDecl,0); StringAppend(&str,pDecl->zFwd,0); SafeFree(pDecl->zDecl); SafeFree(pDecl->zFwd); pDecl->zFwd = 0; pDecl->zDecl = StrDup(StringGet(&str),0); StringReset(&str); } if( pName->pNext->zText[0]==':' ){ DeclSetProperty(pDecl,DP_Cplusplus); } if( pName->nText==5 && strncmp(pName->zText,"class",5)==0 ){ DeclSetProperty(pDecl,DP_Cplusplus); } /* ** Remove all but pList and pName from the input stream. */ if( need_to_collapse ){ while( pEnd!=pName ){ Token *pPrev = pEnd->pPrev; pPrev->pNext = pEnd->pNext; pEnd->pNext->pPrev = pPrev; SafeFree(pEnd); pEnd = pPrev; } } return 0; } /* ** Given a list of tokens that declare something (a function, procedure, ** variable or typedef) find the token which contains the name of the ** thing being declared. ** ** Algorithm: ** ** The name is: ** ** 1. The first identifier that is followed by a "[", or ** ** 2. The first identifier that is followed by a "(" where the ** "(" is followed by another identifier, or ** ** 3. The first identifier followed by "::", or ** ** 4. If none of the above, then the last identifier. ** ** In all of the above, certain reserved words (like "char") are ** not considered identifiers. */ static Token *FindDeclName(Token *pFirst, Token *pLast){ Token *pName = 0; Token *p; int c; if( pFirst==0 || pLast==0 ){ return 0; } pLast = pLast->pNext; for(p=pFirst; p && p!=pLast; p=p->pNext){ if( p->eType==TT_Id ){ static IdentTable sReserved; static int isInit = 0; static char *aWords[] = { "char", "class", "const", "double", "enum", "extern", "EXPORT", "ET_PROC", "float", "int", "long", "register", "static", "struct", "sizeof", "signed", "typedef", "union", "volatile", "virtual", "void", }; if( !isInit ){ int i; for(i=0; i<sizeof(aWords)/sizeof(aWords[0]); i++){ IdentTableInsert(&sReserved,aWords[i],0); } isInit = 1; } if( !IdentTableTest(&sReserved,p->zText,p->nText) ){ pName = p; } }else if( p==pFirst ){ continue; }else if( (c=p->zText[0])=='[' && pName ){ break; }else if( c=='(' && p->pNext && p->pNext->eType==TT_Id && pName ){ break; }else if( c==':' && p->zText[1]==':' && pName ){ break; } } return pName; } /* ** This routine is called when we see a function or procedure definition. ** We make an entry in the declaration table that is a prototype for this ** function or procedure. */ static int ProcessProcedureDef(Token *pFirst, Token *pLast, int flags){ Token *pName; Decl *pDecl; Token *pCode; if( pFirst==0 || pLast==0 ){ return 0; } if( flags & PS_Method ){ return 0; } if( (flags & PS_Static)!=0 && !proto_static ){ return 0; } pCode = pLast; while( pLast && pLast!=pFirst && pLast->zText[0]!=')' ){ pLast = pLast->pPrev; } if( pLast==0 || pLast==pFirst || pFirst->pNext==pLast ){ fprintf(stderr,"%s:%d: Unrecognized syntax.\n", zFilename, pFirst->nLine); return 1; } if( flags & (PS_Interface|PS_Export|PS_Local) ){ fprintf(stderr,"%s:%d: Missing \"inline\" on function or procedure.\n", zFilename, pFirst->nLine); return 1; } pName = FindDeclName(pFirst,pLast); if( pName==0 ){ fprintf(stderr,"%s:%d: Malformed function or procedure definition.\n", zFilename, pFirst->nLine); return 1; } /* ** At this point we've isolated a procedure declaration between pFirst ** and pLast with the name pName. */ #ifdef DEBUG if( debugMask & PARSER ){ printf("**** Found routine: %.*s on line %d...\n", pName->nText, pName->zText, pFirst->nLine); PrintTokens(pFirst,pLast); printf(";\n"); } #endif pDecl = CreateDecl(pName->zText,pName->nText); pDecl->pComment = pFirst->pComment; if( pCode && pCode->eType==TT_Braces ){ pDecl->tokenCode = *pCode; } DeclSetProperty(pDecl,TY_Subroutine); pDecl->zDecl = TokensToString(pFirst,pLast); if( (flags & (PS_Static|PS_Local2))!=0 ){ DeclSetProperty(pDecl,DP_Local); }else if( (flags & (PS_Export2))!=0 ){ DeclSetProperty(pDecl,DP_Export); } if( flags & DP_Cplusplus ){ DeclSetProperty(pDecl,DP_Cplusplus); }else{ DeclSetProperty(pDecl,DP_ExternCReqd); } return 0; } /* ** This routine is called whenever we see the "inline" keyword. We ** need to seek-out the inline function or procedure and make a ** declaration out of the entire definition. */ static int ProcessInlineProc(Token *pFirst, int flags, int *pReset){ Token *pName; Token *pEnd; Decl *pDecl; for(pEnd=pFirst; pEnd; pEnd = pEnd->pNext){ if( pEnd->zText[0]=='{' || pEnd->zText[0]==';' ){ *pReset = pEnd->zText[0]; break; } } if( pEnd==0 ){ *pReset = ';'; fprintf(stderr,"%s:%d: incomplete inline procedure definition\n", zFilename, pFirst->nLine); return 1; } pName = FindDeclName(pFirst,pEnd); if( pName==0 ){ fprintf(stderr,"%s:%d: malformed inline procedure definition\n", zFilename, pFirst->nLine); return 1; } #ifdef DEBUG if( debugMask & PARSER ){ printf("**** Found inline routine: %.*s on line %d...\n", pName->nText, pName->zText, pFirst->nLine); PrintTokens(pFirst,pEnd); printf("\n"); } #endif pDecl = CreateDecl(pName->zText,pName->nText); pDecl->pComment = pFirst->pComment; DeclSetProperty(pDecl,TY_Subroutine); pDecl->zDecl = TokensToString(pFirst,pEnd); if( (flags & (PS_Static|PS_Local|PS_Local2)) ){ DeclSetProperty(pDecl,DP_Local); }else if( flags & (PS_Export|PS_Export2) ){ DeclSetProperty(pDecl,DP_Export); } if( flags & DP_Cplusplus ){ DeclSetProperty(pDecl,DP_Cplusplus); }else{ DeclSetProperty(pDecl,DP_ExternCReqd); } return 0; } /* ** Determine if the tokens between pFirst and pEnd form a variable ** definition or a function prototype. Return TRUE if we are dealing ** with a variable defintion and FALSE for a prototype. ** ** pEnd is the token that ends the object. It can be either a ';' or ** a '='. If it is '=', then assume we have a variable definition. ** ** If pEnd is ';', then the determination is more difficult. We have ** to search for an occurance of an ID followed immediately by '('. ** If found, we have a prototype. Otherwise we are dealing with a ** variable definition. */ static int isVariableDef(Token *pFirst, Token *pEnd){ if( pEnd && pEnd->zText[0]=='=' ){ return 1; } while( pFirst && pFirst!=pEnd && pFirst->pNext && pFirst->pNext!=pEnd ){ if( pFirst->eType==TT_Id && pFirst->pNext->zText[0]=='(' ){ return 0; } pFirst = pFirst->pNext; } return 1; } /* ** This routine is called whenever we encounter a ";" or "=". The stuff ** between pFirst and pLast constitutes either a typedef or a global ** variable definition. Do the right thing. */ static int ProcessDecl(Token *pFirst, Token *pEnd, int flags){ Token *pName; Decl *pDecl; int isLocal = 0; int isVar; int nErr = 0; if( pFirst==0 || pEnd==0 ){ return 0; } if( flags & PS_Typedef ){ if( (flags & (PS_Export2|PS_Local2))!=0 ){ fprintf(stderr,"%s:%d: \"EXPORT\" or \"LOCAL\" ignored before typedef.\n", zFilename, pFirst->nLine); nErr++; } if( (flags & (PS_Interface|PS_Export|PS_Local|DP_Cplusplus))==0 ){ /* It is illegal to duplicate a typedef in C (but OK in C++). ** So don't record typedefs that aren't within a C++ file or ** within #if INTERFACE..#endif */ return nErr; } if( (flags & (PS_Interface|PS_Export|PS_Local))==0 && proto_static==0 ){ /* Ignore typedefs that are not with "#if INTERFACE..#endif" unless ** the "-local" command line option is used. */ return nErr; } if( (flags & (PS_Interface|PS_Export))==0 ){ /* typedefs are always local, unless within #if INTERFACE..#endif */ isLocal = 1; } }else if( flags & (PS_Static|PS_Local2) ){ if( proto_static==0 && (flags & PS_Local2)==0 ){ /* Don't record static variables unless the "-local" command line ** option was specified or the "LOCAL" keyword is used. */ return nErr; } while( pFirst!=0 && pFirst->pNext!=pEnd && ((pFirst->nText==6 && strncmp(pFirst->zText,"static",6)==0) || (pFirst->nText==5 && strncmp(pFirst->zText,"LOCAL",6)==0)) ){ /* Lose the initial "static" or local from local variables. ** We'll prepend "extern" later. */ pFirst = pFirst->pNext; isLocal = 1; } if( pFirst==0 || !isLocal ){ return nErr; } }else if( flags & PS_Method ){ /* Methods are declared by their class. Don't declare separately. */ return nErr; } isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd); if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0 && (flags & PS_Extern)==0 ){ fprintf(stderr,"%s:%d: Can't define a variable in this context\n", zFilename, pFirst->nLine); nErr++; } pName = FindDeclName(pFirst,pEnd->pPrev); if( pName==0 ){ fprintf(stderr,"%s:%d: Can't find a name for the object declared here.\n", zFilename, pFirst->nLine); return nErr+1; } #ifdef DEBUG if( debugMask & PARSER ){ if( flags & PS_Typedef ){ printf("**** Found typedef %.*s at line %d...\n", pName->nText, pName->zText, pName->nLine); }else if( isVar ){ printf("**** Found variable %.*s at line %d...\n", pName->nText, pName->zText, pName->nLine); }else{ printf("**** Found prototype %.*s at line %d...\n", pName->nText, pName->zText, pName->nLine); } PrintTokens(pFirst,pEnd->pPrev); printf(";\n"); } #endif pDecl = CreateDecl(pName->zText,pName->nText); if( (flags & PS_Typedef) ){ DeclSetProperty(pDecl, TY_Typedef); }else if( isVar ){ DeclSetProperty(pDecl,DP_ExternReqd | TY_Variable); if( !(flags & DP_Cplusplus) ){ DeclSetProperty(pDecl,DP_ExternCReqd); } }else{ DeclSetProperty(pDecl, TY_Subroutine); if( !(flags & DP_Cplusplus) ){ DeclSetProperty(pDecl,DP_ExternCReqd); } } pDecl->pComment = pFirst->pComment; pDecl->zDecl = TokensToString(pFirst,pEnd->pPrev); if( isLocal || (flags & (PS_Local||PS_Local2))!=0 ){ DeclSetProperty(pDecl,DP_Local); }else if( flags & (PS_Export|PS_Export2) ){ DeclSetProperty(pDecl,DP_Export); } if( flags & DP_Cplusplus ){ DeclSetProperty(pDecl,DP_Cplusplus); } return nErr; } /* ** Push an if condition onto the if stack */ static void PushIfMacro( const char *zPrefix, /* A prefix, like "define" or "!" */ const char *zText, /* The condition */ int nText, /* Number of characters in zText */ int nLine, /* Line number where this macro occurs */ int flags /* Either 0, PS_Interface, PS_Export or PS_Local */ ){ Ifmacro *pIf; int nByte; nByte = sizeof(Ifmacro); if( zText ){ if( zPrefix ){ nByte += strlen(zPrefix) + 2; } nByte += nText + 1; } pIf = SafeMalloc( nByte ); if( zText ){ pIf->zCondition = (char*)&pIf[1]; if( zPrefix ){ sprintf(pIf->zCondition,"%s(%.*s)",zPrefix,nText,zText); }else{ sprintf(pIf->zCondition,"%.*s",nText,zText); } }else{ pIf->zCondition = 0; } pIf->nLine = nLine; pIf->flags = flags; pIf->pNext = ifStack; ifStack = pIf; } /* ** This routine is called to handle all preprocessor directives. ** ** This routine will recompute the value of *pPresetFlags to be the ** logical or of all flags on all nested #ifs. The #ifs that set flags ** are as follows: ** ** conditional flag set ** ------------------------ -------------------- ** #if INTERFACE PS_Interface ** #if EXPORT_INTERFACE PS_Export ** #if LOCAL_INTERFACE PS_Local ** ** For example, if after processing the preprocessor token given ** by pToken there is an "#if INTERFACE" on the preprocessor ** stack, then *pPresetFlags will be set to PS_Interface. */ static int ParsePreprocessor(Token *pToken, int flags, int *pPresetFlags){ const char *zCmd; int nCmd; const char *zArg; int nArg; int nErr = 0; Ifmacro *pIf; zCmd = &pToken->zText[1]; while( isspace(*zCmd) && *zCmd!='\n' ){ zCmd++; } if( !isalpha(*zCmd) ){ return 0; } nCmd = 1; while( isalpha(zCmd[nCmd]) ){ nCmd++; } if( nCmd==5 && strncmp(zCmd,"endif",5)==0 ){ /* ** Pop the if stack */ pIf = ifStack; if( pIf==0 ){ fprintf(stderr,"%s:%d: extra '#endif'.\n",zFilename,pToken->nLine); return 1; } ifStack = pIf->pNext; SafeFree(pIf); }else if( nCmd==6 && strncmp(zCmd,"define",6)==0 ){ /* ** Record a #define if we are in PS_Interface or PS_Export */ Decl *pDecl; if( !(flags & (PS_Local|PS_Interface|PS_Export)) ){ return 0; } zArg = &zCmd[6]; while( *zArg && isspace(*zArg) && *zArg!='\n' ){ zArg++; } if( *zArg==0 || *zArg=='\n' ){ return 0; } for(nArg=0; ISALNUM(zArg[nArg]); nArg++){} if( nArg==0 ){ return 0; } pDecl = CreateDecl(zArg,nArg); pDecl->pComment = pToken->pComment; DeclSetProperty(pDecl,TY_Macro); pDecl->zDecl = SafeMalloc( pToken->nText + 2 ); sprintf(pDecl->zDecl,"%.*s\n",pToken->nText,pToken->zText); if( flags & PS_Export ){ DeclSetProperty(pDecl,DP_Export); }else if( flags & PS_Local ){ DeclSetProperty(pDecl,DP_Local); } }else if( nCmd==7 && strncmp(zCmd,"include",7)==0 ){ /* ** Record an #include if we are in PS_Interface or PS_Export */ Include *pInclude; char *zIf; if( !(flags & (PS_Interface|PS_Export)) ){ return 0; } zArg = &zCmd[7]; while( *zArg && isspace(*zArg) ){ zArg++; } for(nArg=0; !isspace(zArg[nArg]); nArg++){} if( (zArg[0]=='"' && zArg[nArg-1]!='"') ||(zArg[0]=='<' && zArg[nArg-1]!='>') ){ fprintf(stderr,"%s:%d: malformed #include statement.\n", zFilename,pToken->nLine); return 1; } zIf = GetIfString(); if( zIf ){ pInclude = SafeMalloc( sizeof(Include) + nArg*2 + strlen(zIf) + 10 ); pInclude->zFile = (char*)&pInclude[1]; pInclude->zLabel = &pInclude->zFile[nArg+1]; sprintf(pInclude->zFile,"%.*s",nArg,zArg); sprintf(pInclude->zLabel,"%.*s:%s",nArg,zArg,zIf); pInclude->zIf = &pInclude->zLabel[nArg+1]; SafeFree(zIf); }else{ pInclude = SafeMalloc( sizeof(Include) + nArg + 1 ); pInclude->zFile = (char*)&pInclude[1]; sprintf(pInclude->zFile,"%.*s",nArg,zArg); pInclude->zIf = 0; pInclude->zLabel = pInclude->zFile; } pInclude->pNext = includeList; includeList = pInclude; }else if( nCmd==2 && strncmp(zCmd,"if",2)==0 ){ /* ** Push an #if. Watch for the special cases of INTERFACE ** and EXPORT_INTERFACE and LOCAL_INTERFACE */ zArg = &zCmd[2]; while( *zArg && isspace(*zArg) && *zArg!='\n' ){ zArg++; } if( *zArg==0 || *zArg=='\n' ){ return 0; } nArg = pToken->nText + (int)pToken->zText - (int)zArg; if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){ PushIfMacro(0,0,0,pToken->nLine,PS_Interface); }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){ PushIfMacro(0,0,0,pToken->nLine,PS_Export); }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){ PushIfMacro(0,0,0,pToken->nLine,PS_Local); }else{ PushIfMacro(0,zArg,nArg,pToken->nLine,0); } }else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){ /* ** Push an #ifdef. */ zArg = &zCmd[5]; while( *zArg && isspace(*zArg) && *zArg!='\n' ){ zArg++; } if( *zArg==0 || *zArg=='\n' ){ return 0; } nArg = pToken->nText + (int)pToken->zText - (int)zArg; PushIfMacro("defined",zArg,nArg,pToken->nLine,0); }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){ /* ** Push an #ifndef. */ zArg = &zCmd[6]; while( *zArg && isspace(*zArg) && *zArg!='\n' ){ zArg++; } if( *zArg==0 || *zArg=='\n' ){ return 0; } nArg = pToken->nText + (int)pToken->zText - (int)zArg; PushIfMacro("!defined",zArg,nArg,pToken->nLine,0); }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){ /* ** Invert the #if on the top of the stack */ if( ifStack==0 ){ fprintf(stderr,"%s:%d: '#else' without an '#if'\n",zFilename, pToken->nLine); return 1; } pIf = ifStack; if( pIf->zCondition ){ ifStack = ifStack->pNext; PushIfMacro("!",pIf->zCondition,strlen(pIf->zCondition),pIf->nLine,0); SafeFree(pIf); }else{ pIf->flags = 0; } }else{ /* ** This directive can be safely ignored */ return 0; } /* ** Recompute the preset flags */ *pPresetFlags = 0; for(pIf = ifStack; pIf; pIf=pIf->pNext){ *pPresetFlags |= pIf->flags; } return nErr; } /* ** Parse an entire file. Return the number of errors. ** ** pList is a list of tokens in the file. Whitespace tokens have been ** eliminated, and text with {...} has been collapsed into a ** single TT_Brace token. ** ** initFlags are a set of parse flags that should always be set for this ** file. For .c files this is normally 0. For .h files it is PS_Interface. */ static int ParseFile(Token *pList, int initFlags){ int nErr = 0; Token *pStart = 0; int flags = initFlags; int presetFlags = initFlags; int resetFlag = 0; includeList = 0; while( pList ){ switch( pList->eType ){ case TT_EOF: goto end_of_loop; case TT_Preprocessor: nErr += ParsePreprocessor(pList,flags,&presetFlags); pStart = 0; presetFlags |= initFlags; flags = presetFlags; break; case TT_Other: switch( pList->zText[0] ){ case ';': nErr += ProcessDecl(pStart,pList,flags); pStart = 0; flags = presetFlags; break; case '=': nErr += ProcessDecl(pStart,pList,flags); pStart = 0; while( pList && pList->zText[0]!=';' ){ pList = pList->pNext; } if( pList==0 ) goto end_of_loop; flags = presetFlags; break; case ':': if( pList->zText[1]==':' ){ flags |= PS_Method; } break; default: break; } break; case TT_Braces: nErr += ProcessProcedureDef(pStart,pList,flags); pStart = 0; flags = presetFlags; break; case TT_Id: if( pStart==0 ){ pStart = pList; flags = presetFlags; } resetFlag = 0; switch( pList->zText[0] ){ case 'c': if( pList->nText==5 && strncmp(pList->zText,"class",5)==0 ){ nErr += ProcessTypeDecl(pList,flags,&resetFlag); } break; case 'E': if( pList->nText==6 && strncmp(pList->zText,"EXPORT",6)==0 ){ flags |= PS_Export2; /* pStart = 0; */ } break; case 'e': if( pList->nText==4 && strncmp(pList->zText,"enum",4)==0 ){ if( pList->pNext && pList->pNext->eType==TT_Braces ){ pList = pList->pNext; }else{ nErr += ProcessTypeDecl(pList,flags,&resetFlag); } }else if( pList->nText==6 && strncmp(pList->zText,"extern",6)==0 ){ pList = pList->pNext; if( pList && pList->nText==3 && strncmp(pList->zText,"\"C\"",3)==0 ){ pList = pList->pNext; flags &= ~DP_Cplusplus; }else{ flags |= PS_Extern; } pStart = pList; } break; case 'i': if( pList->nText==6 && strncmp(pList->zText,"inline",6)==0 ){ nErr += ProcessInlineProc(pList,flags,&resetFlag); } break; case 'L': if( pList->nText==5 && strncmp(pList->zText,"LOCAL",5)==0 ){ flags |= PS_Local2; pStart = pList; } break; case 's': if( pList->nText==6 && strncmp(pList->zText,"struct",6)==0 ){ if( pList->pNext && pList->pNext->eType==TT_Braces ){ pList = pList->pNext; }else{ nErr += ProcessTypeDecl(pList,flags,&resetFlag); } }else if( pList->nText==6 && strncmp(pList->zText,"static",6)==0 ){ flags |= PS_Static; } break; case 't': if( pList->nText==7 && strncmp(pList->zText,"typedef",7)==0 ){ flags |= PS_Typedef; } break; case 'u': if( pList->nText==5 && strncmp(pList->zText,"union",5)==0 ){ if( pList->pNext && pList->pNext->eType==TT_Braces ){ pList = pList->pNext; }else{ nErr += ProcessTypeDecl(pList,flags,&resetFlag); } } break; default: break; } if( resetFlag!=0 ){ while( pList && pList->zText[0]!=resetFlag ){ pList = pList->pNext; } if( pList==0 ) goto end_of_loop; pStart = 0; flags = presetFlags; } break; case TT_Number: break; default: pStart = pList; flags = presetFlags; break; } pList = pList->pNext; } end_of_loop: /* Verify that all #ifs have a matching "#endif" */ while( ifStack ){ Ifmacro *pIf = ifStack; ifStack = pIf->pNext; fprintf(stderr,"%s:%d: This '#if' has no '#endif'\n",zFilename, pIf->nLine); SafeFree(pIf); } return nErr; } /* ** Reset the DP_Forward and DP_Declared flags on all Decl structures. ** Set both flags for anything that is tagged as local and isn't ** in the file zFilename so that it won't be printing in other files. */ static void ResetDeclFlags(char *zFilename){ Decl *pDecl; for(pDecl = pDeclFirst; pDecl; pDecl = pDecl->pNext){ DeclClearProperty(pDecl,DP_Forward|DP_Declared); if( DeclHasProperty(pDecl,DP_Local) && pDecl->zFile!=zFilename ){ DeclSetProperty(pDecl,DP_Forward|DP_Declared); } } } /* ** Forward declaration of the ScanText() function. */ static void ScanText(const char*, GenState *pState); /* ** The output in pStr is currently within an #if CONTEXT where context ** is equal to *pzIf. (*pzIf might be NULL to indicate that we are ** not within any #if at the moment.) We are getting ready to output ** some text that needs to be within the context of "#if NEW" where ** NEW is zIf. Make an appropriate change to the context. */ static void ChangeIfContext( const char *zIf, /* The desired #if context */ GenState *pState /* Current state of the code generator */ ){ if( zIf==0 ){ if( pState->zIf==0 ) return; StringAppend(pState->pStr,"#endif\n",0); pState->zIf = 0; }else{ if( pState->zIf ){ if( strcmp(zIf,pState->zIf)==0 ) return; StringAppend(pState->pStr,"#endif\n",0); pState->zIf = 0; } ScanText(zIf, pState); if( pState->zIf!=0 ){ StringAppend(pState->pStr,"#endif\n",0); } StringAppend(pState->pStr,"#if ",0); StringAppend(pState->pStr,zIf,0); StringAppend(pState->pStr,"\n",0); pState->zIf = zIf; } } /* ** Add to the string pStr a #include of every file on the list of ** include files pInclude. The table pTable contains all files that ** have already been #included at least once. Don't add any ** duplicates. Update pTable with every new #include that is added. */ static void AddIncludes( Include *pInclude, /* Write every #include on this list */ GenState *pState /* Current state of the code generator */ ){ if( pInclude ){ if( pInclude->pNext ){ AddIncludes(pInclude->pNext,pState); } if( IdentTableInsert(pState->pTable,pInclude->zLabel,0) ){ ChangeIfContext(pInclude->zIf,pState); StringAppend(pState->pStr,"#include ",0); StringAppend(pState->pStr,pInclude->zFile,0); StringAppend(pState->pStr,"\n",1); } } } /* ** Add to the string pStr a declaration for the object described ** in pDecl. ** ** If pDecl has already been declared in this file, detect that ** fact and abort early. Do not duplicate a declaration. ** ** If the needFullDecl flag is false and this object has a forward ** declaration, then supply the forward declaration only. A later ** call to CompleteForwardDeclarations() will finish the declaration ** for us. But if needFullDecl is true, we must supply the full ** declaration now. Some objects do not have a forward declaration. ** For those objects, we must print the full declaration now. ** ** Because it is illegal to duplicate a typedef in C, care is taken ** to insure that typedefs for the same identifier are only issued once. */ static void DeclareObject( Decl *pDecl, /* The thing to be declared */ GenState *pState, /* Current state of the code generator */ int needFullDecl /* Must have the full declaration. A forward * declaration isn't enough */ ){ Decl *p; /* The object to be declared */ int flag; int isCpp; /* True if generating C++ */ int doneTypedef = 0; /* True if a typedef has been done for this object */ /* ** For any object that has a forward declaration, go ahead and do the ** forward declaration first. */ isCpp = (pState->flags & DP_Cplusplus) != 0; for(p=pDecl; p; p=p->pSameName){ if( p->zFwd ){ if( !DeclHasProperty(p,DP_Forward) ){ DeclSetProperty(p,DP_Forward); if( strncmp(p->zFwd,"typedef",7)==0 ){ if( doneTypedef ) continue; doneTypedef = 1; } ChangeIfContext(p->zIf,pState); StringAppend(pState->pStr,isCpp ? p->zFwdCpp : p->zFwd,0); } } } /* ** Early out if everything is already suitably declared. ** ** This is a very important step because it prevents us from ** executing the code the follows in a recursive call to this ** function with the same value for pDecl. */ flag = needFullDecl ? DP_Declared|DP_Forward : DP_Forward; for(p=pDecl; p; p=p->pSameName){ if( !DeclHasProperty(p,flag) ) break; } if( p==0 ){ return; } /* ** Make sure we have all necessary #includes */ for(p=pDecl; p; p=p->pSameName){ AddIncludes(p->pInclude,pState); } /* ** Go ahead an mark everything as being declared, to prevent an ** infinite loop thru the ScanText() function. At the same time, ** we decide which objects need a full declaration and mark them ** with the DP_Flag bit. We are only able to use DP_Flag in this ** way because we know we'll never execute this far into this ** function on a recursive call with the same pDecl. Hence, recursive ** calls to this function (through ScanText()) can never change the ** value of DP_Flag out from under us. */ for(p=pDecl; p; p=p->pSameName){ if( !DeclHasProperty(p,DP_Declared) && (p->zFwd==0 || needFullDecl) && p->zDecl!=0 ){ DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag); }else{ DeclClearProperty(p,DP_Flag); } } /* ** Call ScanText() recusively (this routine is called from ScanText()) ** to include declarations required to come before these declarations. */ for(p=pDecl; p; p=p->pSameName){ if( DeclHasProperty(p,DP_Flag) ){ if( p->zDecl[0]=='#' ){ ScanText(&p->zDecl[1],pState); }else{ ScanText(p->zDecl,pState); } } } /* ** Output the declarations. Do this in two passes. First ** output everything that isn't a typedef. Then go back and ** get the typedefs by the same name. */ for(p=pDecl; p; p=p->pSameName){ if( DeclHasProperty(p,DP_Flag) && !DeclHasProperty(p,TY_Typedef) ){ if( DeclHasAnyProperty(p,TY_Enumeration) ){ if( doneTypedef ) continue; doneTypedef = 1; } ChangeIfContext(p->zIf,pState); if( !isCpp && DeclHasAnyProperty(p,DP_ExternReqd) ){ StringAppend(pState->pStr,"extern ",0); }else if( isCpp && DeclHasProperty(p,DP_Cplusplus|DP_ExternReqd) ){ StringAppend(pState->pStr,"extern ",0); }else if( isCpp && DeclHasAnyProperty(p,DP_ExternCReqd|DP_ExternReqd) ){ StringAppend(pState->pStr,"extern \"C\" ",0); } StringAppend(pState->pStr,p->zDecl,0); if( !isCpp && DeclHasProperty(p,DP_Cplusplus) ){ fprintf(stderr, "%s: C code ought not reference the C++ object \"%s\"\n", pState->zFilename, p->zName); pState->nErr++; } DeclClearProperty(p,DP_Flag); } } for(p=pDecl; p && !doneTypedef; p=p->pSameName){ if( DeclHasProperty(p,DP_Flag) ){ /* This has to be a typedef */ doneTypedef = 1; ChangeIfContext(p->zIf,pState); StringAppend(pState->pStr,p->zDecl,0); } } } /* ** This routine scans the input text given, and appends to the ** string in pState->pStr the text of any declarations that must ** occur before the text in zText. ** ** If an identifier in zText is immediately followed by '*', then ** only forward declarations are needed for that identifier. If the ** identifier name is not followed immediately by '*', we must supply ** a full declaration. */ static void ScanText( const char *zText, /* The input text to be scanned */ GenState *pState /* Current state of the code generator */ ){ int nextValid = 0; /* True is sNext contains valid data */ InStream sIn; /* The input text */ Token sToken; /* The current token being examined */ Token sNext; /* The next non-space token */ sIn.z = zText; sIn.i = 0; sIn.nLine = 1; while( sIn.z[sIn.i]!=0 ){ if( nextValid ){ sToken = sNext; nextValid = 0; }else{ GetNonspaceToken(&sIn,&sToken); } if( sToken.eType==TT_Id ){ int needFullDecl; /* True if we need to provide the full declaration, ** not just the forward declaration */ Decl *pDecl; /* The declaration having the name in sToken */ /* ** See if there is a declaration in the database with the name given ** by sToken. */ pDecl = FindDecl(sToken.zText,sToken.nText); if( pDecl==0 ) continue; /* ** If we get this far, we've found an identifier that has a ** declaration in the database. Now see if we the full declaration ** or just a forward declaration. */ GetNonspaceToken(&sIn,&sNext); if( sNext.zText[0]=='*' ){ needFullDecl = 0; }else{ needFullDecl = 1; nextValid = sNext.eType==TT_Id; } /* ** Generate the needed declaration. */ DeclareObject(pDecl,pState,needFullDecl); }else if( sToken.eType==TT_Preprocessor ){ sIn.i -= sToken.nText - 1; } } } /* ** Provide a full declaration to any object which so far has had only ** a foward declaration. */ static void CompleteForwardDeclarations(GenState *pState){ Decl *pDecl; int progress; do{ progress = 0; for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){ if( DeclHasProperty(pDecl,DP_Forward) && !DeclHasProperty(pDecl,DP_Declared) ){ DeclareObject(pDecl,pState,1); progress = 1; assert( DeclHasProperty(pDecl,DP_Declared) ); } } }while( progress ); } /* ** Generate an include file for the given source file. Return the number ** of errors encountered. ** ** if nolocal_flag is true, then we do not generate declarations for ** objected marked DP_Local. */ static int MakeHeader(InFile *pFile, FILE *report, int nolocal_flag){ int nErr = 0; GenState sState; String outStr; IdentTable includeTable; Ident *pId; char *zNewVersion; char *zOldVersion; if( pFile->zHdr==0 || *pFile->zHdr==0 ) return 0; sState.pStr = &outStr; StringInit(&outStr); StringAppend(&outStr,zTopLine,nTopLine); sState.pTable = &includeTable; memset(&includeTable,0,sizeof(includeTable)); sState.zIf = 0; sState.nErr = 0; sState.zFilename = pFile->zSrc; sState.flags = pFile->flags & DP_Cplusplus; ResetDeclFlags(nolocal_flag ? "no" : pFile->zSrc); for(pId = pFile->idTable.pList; pId; pId=pId->pNext){ Decl *pDecl = FindDecl(pId->zName,0); if( pDecl ){ DeclareObject(pDecl,&sState,1); } } CompleteForwardDeclarations(&sState); ChangeIfContext(0,&sState); nErr += sState.nErr; zOldVersion = ReadFile(pFile->zHdr); zNewVersion = StringGet(&outStr); if( report ) fprintf(report,"%s: ",pFile->zHdr); if( zOldVersion==0 ){ if( report ) fprintf(report,"updated\n"); if( WriteFile(pFile->zHdr,zNewVersion) ){ fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr); nErr++; } }else if( strncmp(zOldVersion,zTopLine,nTopLine)!=0 ){ if( report ) fprintf(report,"error!\n"); fprintf(stderr, "%s: Can't overwrite this file because it wasn't previously\n" "%*s generated by 'makeheaders'.\n", pFile->zHdr, strlen(pFile->zHdr), ""); nErr++; }else if( strcmp(zOldVersion,zNewVersion)!=0 ){ if( report ) fprintf(report,"updated\n"); if( WriteFile(pFile->zHdr,zNewVersion) ){ fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr); nErr++; } }else if( report ){ fprintf(report,"unchanged\n"); } SafeFree(zOldVersion); IdentTableReset(&includeTable); StringReset(&outStr); return nErr; } /* ** Generate a global header file -- a header file that contains all ** declarations. If the forExport flag is true, then only those ** objects that are exported are included in the header file. */ static int MakeGlobalHeader(int forExport){ GenState sState; String outStr; IdentTable includeTable; Decl *pDecl; sState.pStr = &outStr; StringInit(&outStr); /* StringAppend(&outStr,zTopLine,nTopLine); */ sState.pTable = &includeTable; memset(&includeTable,0,sizeof(includeTable)); sState.zIf = 0; sState.nErr = 0; sState.zFilename = "(all)"; sState.flags = 0; ResetDeclFlags(0); for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){ if( forExport==0 || DeclHasProperty(pDecl,DP_Export) ){ DeclareObject(pDecl,&sState,1); } } ChangeIfContext(0,&sState); printf("%s",StringGet(&outStr)); IdentTableReset(&includeTable); StringReset(&outStr); return 0; } #ifdef DEBUG /* ** Return the number of characters in the given string prior to the ** first newline. */ static int ClipTrailingNewline(char *z){ int n = strlen(z); while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ){ n--; } return n; } /* ** Dump the entire declaration list for debugging purposes */ static void DumpDeclList(void){ Decl *pDecl; for(pDecl = pDeclFirst; pDecl; pDecl=pDecl->pNext){ printf("**** %s from file %s ****\n",pDecl->zName,pDecl->zFile); if( pDecl->zIf ){ printf("If: [%.*s]\n",ClipTrailingNewline(pDecl->zIf),pDecl->zIf); } if( pDecl->zFwd ){ printf("Decl: [%.*s]\n",ClipTrailingNewline(pDecl->zFwd),pDecl->zFwd); } if( pDecl->zDecl ){ printf("Def: [%.*s]\n",ClipTrailingNewline(pDecl->zDecl),pDecl->zDecl); } if( pDecl->flags ){ static struct { int mask; char *desc; } flagSet[] = { { TY_Class, "class" }, { TY_Enumeration, "enum" }, { TY_Structure, "struct" }, { TY_Union, "union" }, { TY_Variable, "variable" }, { TY_Subroutine, "function" }, { TY_Typedef, "typedef" }, { TY_Macro, "macro" }, { DP_Export, "export" }, { DP_Local, "local" }, { DP_Cplusplus, "C++" }, }; int i; printf("flags:"); for(i=0; i<sizeof(flagSet)/sizeof(flagSet[0]); i++){ if( flagSet[i].mask & pDecl->flags ){ printf(" %s", flagSet[i].desc); } } printf("\n"); } if( pDecl->pInclude ){ Include *p; printf("includes:"); for(p=pDecl->pInclude; p; p=p->pNext){ printf(" %s",p->zFile); } printf("\n"); } } } #endif /* ** When the "-doc" command-line option is used, this routine is called ** to print all of the database information to standard output. */ static void DocumentationDump(void){ Decl *pDecl; static struct { int mask; char flag; } flagSet[] = { { TY_Class, 'c' }, { TY_Enumeration, 'e' }, { TY_Structure, 's' }, { TY_Union, 'u' }, { TY_Variable, 'v' }, { TY_Subroutine, 'f' }, { TY_Typedef, 't' }, { TY_Macro, 'm' }, { DP_Export, 'x' }, { DP_Local, 'l' }, { DP_Cplusplus, '+' }, }; for(pDecl = pDeclFirst; pDecl; pDecl=pDecl->pNext){ int i; int nLabel = 0; char *zDecl; char zLabel[50]; for(i=0; i<sizeof(flagSet)/sizeof(flagSet[0]); i++){ if( DeclHasProperty(pDecl,flagSet[i].mask) ){ zLabel[nLabel++] = flagSet[i].flag; } } if( nLabel==0 ) continue; zLabel[nLabel] = 0; zDecl = pDecl->zDecl; if( zDecl==0 ) zDecl = pDecl->zFwd; printf("%s %s %s %d %d %d %d %d %d\n", pDecl->zName, zLabel, pDecl->zFile, pDecl->pComment ? (int)pDecl->pComment/sizeof(Token) : 0, pDecl->pComment ? pDecl->pComment->nText+1 : 0, pDecl->zIf ? strlen(pDecl->zIf)+1 : 0, zDecl ? strlen(zDecl) : 0, pDecl->pComment ? pDecl->pComment->nLine : 0, pDecl->tokenCode.nText ? pDecl->tokenCode.nText+1 : 0 ); if( pDecl->pComment ){ printf("%.*s\n",pDecl->pComment->nText, pDecl->pComment->zText); } if( pDecl->zIf ){ printf("%s\n",pDecl->zIf); } if( zDecl ){ printf("%s",zDecl); } if( pDecl->tokenCode.nText ){ printf("%.*s\n",pDecl->tokenCode.nText, pDecl->tokenCode.zText); } } } /* ** Given the complete text of an input file, this routine prints a ** documentation record for the header comment at the beginning of the ** file (if the file has a header comment.) */ void PrintModuleRecord(const char *zFile, const char *zFilename){ int i; static int addr = 5; while( isspace(*zFile) ){ zFile++; } if( *zFile!='/' || zFile[1]!='*' ) return; for(i=2; zFile[i] && (zFile[i-1]!='/' || zFile[i-2]!='*'); i++){} if( zFile[i]==0 ) return; printf("%s M %s %d %d 0 0 0\n%.*s\n", zFilename, zFilename, addr, i+1, i, zFile); addr += 4; } /* ** Given an input argument to the program, construct a new InFile ** object. */ static InFile *CreateInFile(char *zArg, int *pnErr){ int nSrc; char *zSrc; InFile *pFile; int i; /* ** Get the name of the input file to be scanned */ zSrc = zArg; for(nSrc=0; zSrc[nSrc] && zArg[nSrc]!=':'; nSrc++){} pFile = SafeMalloc( sizeof(InFile) ); memset(pFile,0,sizeof(InFile)); pFile->zSrc = StrDup(zSrc,nSrc); /* Figure out if we are dealing with C or C++ code. Assume any ** file with ".c" or ".h" is C code and all else is C++. */ if( nSrc>2 && zSrc[nSrc-2]=='.' && (zSrc[nSrc-1]=='c' || zSrc[nSrc-1]=='h')){ pFile->flags &= ~DP_Cplusplus; }else{ pFile->flags |= DP_Cplusplus; } /* ** If a separate header file is specified, use it */ if( zSrc[nSrc]==':' ){ int nHdr; char *zHdr; zHdr = &zSrc[nSrc+1]; for(nHdr=0; zHdr[nHdr] && zHdr[nHdr]!=':'; nHdr++){} pFile->zHdr = StrDup(zHdr,nHdr); } /* Look for any 'c' or 'C' in the suffix of the file name and change ** that character to 'h' or 'H' respectively. If no 'c' or 'C' is found, ** then assume we are dealing with a header. */ else{ int foundC = 0; pFile->zHdr = StrDup(zSrc,nSrc); for(i = nSrc-1; i>0 && pFile->zHdr[i]!='.'; i--){ if( pFile->zHdr[i]=='c' ){ foundC = 1; pFile->zHdr[i] = 'h'; }else if( pFile->zHdr[i]=='C' ){ foundC = 1; pFile->zHdr[i] = 'H'; } } if( !foundC ){ SafeFree(pFile->zHdr); pFile->zHdr = 0; } } /* ** If pFile->zSrc contains no 'c' or 'C' in its extension, it ** must be a header file. In that case, we need to set the ** PS_Interface flag. */ pFile->flags |= PS_Interface; for(i=nSrc-1; i>0 && zSrc[i]!='.'; i--){ if( zSrc[i]=='c' || zSrc[i]=='C' ){ pFile->flags &= ~PS_Interface; break; } } /* Done! */ return pFile; } /* MS-Windows and MS-DOS both have the following serious OS bug: the ** length of a command line is severely restricted. But this program ** occasionally requires long command lines. Hence the following ** work around. ** ** If the parameters "-f FILENAME" appear anywhere on the command line, ** then the named file is scanned for additional command line arguments. ** These arguments are substituted in place of the "FILENAME" argument ** in the original argument list. ** ** This first parameter to this routine is the index of the "-f" ** parameter in the argv[] array. The argc and argv are passed by ** pointer so that they can be changed. ** ** Parsing of the parameters in the file is very simple. Parameters ** can be separated by any amount of white-space (including newlines ** and carriage returns.) There are now quoting characters of any ** kind. The length of a token is limited to about 1000 characters. */ static void AddParameters(int index, int *pArgc, char ***pArgv){ int argc = *pArgc; /* The original argc value */ char **argv = *pArgv; /* The original argv value */ int newArgc; /* Value for argc after inserting new arguments */ char **zNew; /* The new argv after this routine is done */ char *zFile; /* Name of the input file */ int nNew = 0; /* Number of new entries in the argv[] file */ int nAlloc = 0; /* Space allocated for zNew[] */ int i; /* Loop counter */ int n; /* Number of characters in a new argument */ int c; /* Next character of input */ int startOfLine = 1; /* True if we are where '#' can start a comment */ FILE *in; /* The input file */ char zBuf[1000]; /* A single argument is accumulated here */ if( index+1==argc ) return; zFile = argv[index+1]; in = fopen(zFile,"r"); if( in==0 ){ fprintf(stderr,"Can't open input file \"%s\"\n",zFile); exit(1); } c = ' '; while( c!=EOF ){ while( c!=EOF && isspace(c) ){ if( c=='\n' ){ startOfLine = 1; } c = getc(in); if( startOfLine && c=='#' ){ while( c!=EOF && c!='\n' ){ c = getc(in); } } } n = 0; while( c!=EOF && !isspace(c) ){ if( n<sizeof(zBuf)-1 ){ zBuf[n++] = c; } startOfLine = 0; c = getc(in); } zBuf[n] = 0; if( n>0 ){ nNew++; if( nNew + argc > nAlloc ){ if( nAlloc==0 ){ nAlloc = 100 + argc; zNew = malloc( sizeof(char*) * nAlloc ); }else{ nAlloc *= 2; zNew = realloc( zNew, sizeof(char*) * nAlloc ); } } if( zNew ){ int j = nNew + index; zNew[j] = malloc( n + 1 ); if( zNew[j] ){ strcpy( zNew[j], zBuf ); } } } } newArgc = argc + nNew - 1; for(i=0; i<=index; i++){ zNew[i] = argv[i]; } for(i=nNew + index + 1; i<newArgc; i++){ zNew[i] = argv[i + 1 - nNew]; } zNew[newArgc] = 0; *pArgc = newArgc; *pArgv = zNew; } #ifdef NOT_USED /* ** Return the time that the given file was last modified. If we can't ** locate the file (because, for example, it doesn't exist), then ** return 0. */ static unsigned int ModTime(const char *zFilename){ unsigned int mTime = 0; struct stat sStat; if( stat(zFilename,&sStat)==0 ){ mTime = sStat.st_mtime; } return mTime; } #endif /* ** Print a usage comment for this program. */ static void Usage(const char *argv0, const char *argvN){ fprintf(stderr,"%s: Illegal argument \"%s\"\n",argv0,argvN); fprintf(stderr,"Usage: %s [options] filename...\n" "Options:\n" " -h Generate a single .h to standard output.\n" " -H Like -h, but only output EXPORT declarations.\n" " -v (verbose) Write status information to the screen.\n" " -doc Generate no header files. Instead, output information\n" " that can be used by an automatic program documentation\n" " and cross-reference generator.\n" " -local Generate prototypes for \"static\" functions and\n" " procedures.\n" " -f FILE Read additional command-line arguments from the file named\n" " \"FILE\".\n" #ifdef DEBUG " -! MASK Set the debugging mask to the number \"MASK\".\n" #endif " -- Treat all subsequent comment-line parameters as filenames,\n" " even if they begin with \"-\".\n", argv0 ); } /* ** The following text contains a few simple #defines that we want ** to be available to every file. */ static char zInit[] = "#define INTERFACE 0\n" "#define EXPORT_INTERFACE 0\n" "#define LOCAL_INTERFACE 0\n" "#define EXPORT\n" "#define LOCAL static\n" ; #if TEST==0 int main(int argc, char **argv){ int i; /* Loop counter */ int nErr = 0; /* Number of errors encountered */ Token *pList; /* List of input tokens for one file */ InFile *pFileList = 0;/* List of all input files */ InFile *pTail; /* Last file on the list */ InFile *pFile; /* for looping over the file list */ int h_flag = 0; /* True if -h is present. Output unified header */ int H_flag = 0; /* True if -H is present. Output EXPORT header */ int v_flag = 0; /* Verbose */ int noMoreFlags; /* True if -- has been seen. */ FILE *report; /* Send progress reports to this, if not NULL */ noMoreFlags = 0; for(i=1; i<argc; i++){ if( argv[i][0]=='-' && !noMoreFlags ){ switch( argv[i][1] ){ case 'h': h_flag = 1; break; case 'H': H_flag = 1; break; case 'v': v_flag = 1; break; case 'd': doc_flag = 1; proto_static = 1; break; case 'l': proto_static = 1; break; case 'f': AddParameters(i, &argc, &argv); break; case '-': noMoreFlags = 1; break; #ifdef DEBUG case '!': i++; debugMask = strtol(argv[i],0,0); break; #endif default: Usage(argv[0],argv[i]); return 1; } }else{ pFile = CreateInFile(argv[i],&nErr); if( pFile ){ if( pFileList ){ pTail->pNext = pFile; pTail = pFile; }else{ pFileList = pTail = pFile; } } } } if( h_flag && H_flag ){ h_flag = 0; } if( v_flag ){ report = (h_flag || H_flag) ? stderr : stdout; }else{ report = 0; } if( nErr>0 ){ return nErr; } for(pFile=pFileList; pFile; pFile=pFile->pNext){ char *zFile; zFilename = pFile->zSrc; if( zFilename==0 ) continue; zFile = ReadFile(zFilename); if( zFile==0 ){ fprintf(stderr,"Can't read input file \"%s\"\n",zFilename); nErr++; continue; } if( strncmp(zFile,zTopLine,nTopLine)==0 ){ pFile->zSrc = 0; }else{ if( report ) fprintf(report,"Reading %s...\n",zFilename); pList = TokenizeFile(zFile,&pFile->idTable); if( pList ){ nErr += ParseFile(pList,pFile->flags); FreeTokenList(pList); }else if( zFile[0]==0 ){ fprintf(stderr,"Input file \"%s\" is empty.\n", zFilename); nErr++; }else{ fprintf(stderr,"Errors while processing \"%s\"\n", zFilename); nErr++; } } if( !doc_flag ) SafeFree(zFile); if( doc_flag ) PrintModuleRecord(zFile,zFilename); } if( nErr>0 ){ return nErr; } #ifdef DEBUG if( debugMask & DECL_DUMP ){ DumpDeclList(); return nErr; } #endif if( doc_flag ){ DocumentationDump(); return nErr; } zFilename = "--internal--"; pList = TokenizeFile(zInit,0); if( pList==0 ){ return nErr+1; } ParseFile(pList,PS_Interface); FreeTokenList(pList); if( h_flag || H_flag ){ nErr += MakeGlobalHeader(H_flag); }else{ for(pFile=pFileList; pFile; pFile=pFile->pNext){ if( pFile->zSrc==0 ) continue; nErr += MakeHeader(pFile,report,0); } } return nErr; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/tools/httpget.c�����������������������������������������������������������������0000644�0001750�0001750�00000012375�07504443354�016256� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ** This file contains code to fetch a single URL into a local file. */ #include <stdio.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <linux/in.h> #include "httpget.h" #define strnicmp strncasecmp /* ** Get a URL using HTTP. Return the result code. If a Location: field ** appears in the header, write it into zLocation[]. Location[] should ** be at least 200 characters in size. */ static int HttpTryOnce(char *zUrl, char *zLocalFile, int quiet, char *zLocation){ int i, j; int nErr = 0; /* Number of errors */ char *zPath; /* Pathname to send as second argument to GET */ int iPort; /* TCP port for the server */ struct hostent *pHost; /* Name information */ int s; /* The main communications socket */ int c; /* A character read from the remote side */ int n; /* Number of characters in header */ int rc = 200; /* The result code */ FILE *sock; /* FILE corresponding to file descriptor s */ FILE *out; /* Write output here */ int last_was_nl; /* TRUE if last character received was '\n' */ struct sockaddr_in addr; /* The address structure */ int nByte = 0; char zIpAddr[400]; /* The IP address of the server to print */ char zMsg[1000]; /* Space to hold error messages */ char zLine[1000]; /* A single line of the header */ out = fopen(zLocalFile, "w"); if( out==0 ){ sprintf(zMsg, "can't open output fule \"%.100s\"", zLocalFile); perror(zMsg); return 1; } i = 0; if( strnicmp(zUrl,"http:",5)==0 ){ i = 5; } while( zUrl[i]=='/' ){ i++; } j = 0; while( zUrl[i] && zUrl[i]!=':' && zUrl[i]!='/' ){ if( j<sizeof(zIpAddr)-1 ){ zIpAddr[j++] = zUrl[i]; } i++; } zIpAddr[j] = 0; if( zUrl[i]==':' ){ iPort = 0; i++; while( isdigit(zUrl[i]) ){ iPort = iPort*10 + zUrl[i] - '0'; i++; } }else{ iPort = 80; } zPath = &zUrl[i]; addr.sin_family = AF_INET; addr.sin_port = htons(iPort); *(int*)&addr.sin_addr = inet_addr(zIpAddr); if( -1 == *(int*)&addr.sin_addr ){ pHost = gethostbyname(zIpAddr); if( pHost==0 ){ fprintf(stderr,"can't resolve host name: %s\n",zIpAddr); return 1; } memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); if( !quiet ){ fprintf(stderr,"Address resolution: %s -> %d.%d.%d.%d\n",zIpAddr, pHost->h_addr_list[0][0]&0xff, pHost->h_addr_list[0][1]&0xff, pHost->h_addr_list[0][2]&0xff, pHost->h_addr_list[0][3]&0xff); } } s = socket(AF_INET,SOCK_STREAM,0); if( s<0 ){ sprintf(zMsg,"can't open socket to %.100s", zIpAddr); perror(zMsg); fclose(out); return 1; } if( connect(s,(struct sockaddr*)&addr,sizeof(addr))<0 ){ sprintf(zMsg,"can't connect to host %.100s", zIpAddr); perror(zMsg); fclose(out); return 1; } sock = fdopen(s,"r+"); if( *zPath==0 ) zPath = "/"; fprintf(sock,"GET %s HTTP/1.0\r\n",zPath); fprintf(sock,"User-Agent: Mozilla/2.0 (X11; U; Linux 0.99p17 i486)\r\n"); if( iPort!=80 ){ fprintf(sock,"Host: %s:%d\r\n", zIpAddr, iPort); }else{ fprintf(sock,"Host: %s\r\n", zIpAddr); } fprintf(sock,"Accept: image/gif, image/x-xbitmap, image/jpeg, */*\r\n"); fprintf(sock,"\r\n"); fflush(sock); n = 0; rc = 0; while( (c=getc(sock))!=EOF && (c!='\n' || !last_was_nl) ){ if( c=='\r' ) continue; last_was_nl = (c=='\n'); if( last_was_nl ){ zLine[n] = 0; if( strncmp(zLine,"Location:",9)==0 && zLocation ){ int j, k; for(j=9; isspace(zLine[j]); j++){} k = 0; while( zLine[j] && !isspace(zLine[j]) && k<199 ){ zLocation[k++] = zLine[j++]; } zLocation[k] = 0; if( !quiet ) fprintf(stderr,"Location: %s\n", zLocation); }else if( rc==0 ){ sscanf(zLine,"HTTP/%*d.%*d %d ",&rc); if( !quiet ) fprintf(stderr,"Status: %d\n", rc); } } if( n<sizeof(zLine)-1 ){ zLine[n++] = c; } if( last_was_nl ){ n = 0; } } if( rc==0 ) rc = 200; if( !quiet ){ fprintf(stderr, "Reading %s...", zUrl); } while( (c=getc(sock))!=EOF ){ nByte++; putc(c,out); } if( !quiet ){ fprintf(stderr, " %d bytes\n", nByte); } fclose(sock); fclose(out); return rc; } /* ** Get the file. Take up to 7 redirects. */ int HttpFetch( char *zUrl, /* Fetch this URL */ char *zLocalFile, /* Write to this file */ int quiet, /* Be quiet if true */ int nActual, /* Size of zActual[] */ char *zActual /* Write actual URL retrieved here */ ){ int i; int rc; char *zOriginalUrl = zUrl; char zLocation[300]; for(i=0; i<7; i++){ if( !quiet ) fprintf(stderr,"HTTP: %s -> %s\n", zUrl, zLocalFile); rc = HttpTryOnce(zUrl, zLocalFile, quiet, zLocation); if( rc==301 || rc==302 ){ char *z; const char *az[2]; az[0] = zLocation; az[1] = 0; z = ResolveUrl(zUrl, az); if( zUrl!=zOriginalUrl ){ free(zUrl); } zUrl = z; }else{ break; } } if( nActual>0 && zActual!=0 ){ sprintf(zActual, "%.*s", nActual, zUrl); } if( zUrl!=zOriginalUrl ){ free(zUrl); } return rc; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/htmlwidget/mkso.sh�������������������������������������������������������������������������0000755�0001750�0001750�00000001040�07504443344�014565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # # This script builds "libtkhtml.so" for Linux and Tcl/Tk8.3-stubs. # First do "make srcdir; cd srcdir". Then run this script. # # $Revision: 1.1.1.1 $ # BASE=/home/drh/tcltk/8.3linux VERS=8.3 TKLIB="$BASE/libtkstub${VERS}g.a -L/usr/X11R6/lib -lX11" TCLLIB="$BASE/libtclstub${VERS}g.a -lm -ldl" CC='gcc -fPIC -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 -O2' INC="-I. -I$BASE" CMD="rm *.o" echo $CMD $CMD for i in *.c; do CMD="$CC $INC -c $i" echo $CMD $CMD done CMD="gcc -o libtkhtml.so -shared *.o $TKLIB $TCLLIB" echo $CMD $CMD ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/���������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�011654� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/Makefile�������������������������������������������������������������������������������0000644�0001750�0001750�00000001306�11115554507�013333� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include CXXFLAGS = $(CXXOPT) -I../include CFLAGS = $(CCOPT) -I../include SRC = iistcl.C xim.C CSRC = iis.c util.c OBJS = $(SRC:%.C=%.o) COBJS = $(CSRC:%.c=%.o) LIB = libiis.a SHARED = libiis.so all : $(LIB) install : all cp -f $(LIB) ../lib/. $(LIB) : $(OBJS) $(COBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) $(COBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.a *.so *.o FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) %.d: %.c set -e; $(CC) -MM $(CFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(CSRC:.c=.d) endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/ximtool.h������������������������������������������������������������������������������0000644�0001750�0001750�00000027360�10041014647�013540� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __ximtool_h__ #define __ximtool_h__ #define XtPointer void * #define Boolean int #define String char * #define Widget void * #define PSImagePtr void * /* Default values, size limiting values. */ #define MAX_FBCONFIG 128 /* max possible frame buf sizes */ #define MAX_FRAMES 16 /* max number of frames */ #define MAX_MAPPINGS 100 /* max number of mappings/frame */ #define MAX_CLIENTS 8 /* max display server clients */ #define MAX_ISM 8 /* max ISM module clients */ #define MAX_COLORMAPS 256 /* max number of colormaps */ #define MAX_COLORS 256 /* max size colormap */ #define MAX_PRINTERS 128 /* max number of printers */ #define FIRST_COLOR 10 /* first allocatable color */ #define DEF_NCOLORS 201 /* default number of colors */ #define DEF_COLORMAP 1 /* default colormap */ #define DEF_NFRAMES 1 /* save memory; only one frame */ #define DEF_FRAME_WIDTH 512 /* 512 square frame */ #define DEF_FRAME_HEIGHT 512 /* 512 square frame */ #define DEF_FRAME_DEPTH 8 /* 8 bits deep */ #define DEF_WIN_WIDTH 512 /* default size window */ #define DEF_WIN_HEIGHT 512 /* default size window */ #define DEF_TILE_BORDER 3 /* border width for tileFrames */ #define DEF_BORDER_COLOR "9" /* border highlight color */ #define SZ_CMAPNAME 32 /* colormap name buffer */ #define SZ_NAME 80 /* object name buffer */ #define SZ_LABEL 256 /* main frame label string */ #define SZ_IMTITLE 128 /* image title string */ #define SZ_WCTEXT 80 /* WCS box text */ #define SZ_OLD_WCSBUF 320 /* old WCS text buffer size */ #define SZ_WCSBUF 1024 /* WCS text buffer size */ #define SZ_MSGBUF 8192 /* message buffer size */ #define SZ_COLORBAR 11 /* height of colorbar in pixels */ #define SZ_FIFOBUF 4000 /* transfer size for FIFO i/o */ #define SZ_FNAME 256 #define SZ_LINE 256 #define ERR (-1) #define OK 0 #define EOS '\0' #define M_UNITARY 0 /* xim_setmapping */ #define M_ASPECT 1 #define M_FILL 2 /* Magic numbers. */ #define DEF_PORT 5137 /* default tcp/ip socket */ #define I_DEVNAME "/dev/imt1o" /* pseudo device names */ #define O_DEVNAME "/dev/imt1i" /* our IN is client's OUT */ #define DEF_UNIXADDR "/tmp/.IMT%d" /* default unix socket */ #define DEF_ANTIALIASTYPE "boxcar" /* default antialiasing */ #define FBCONFIG_1 ".imtoolrc" #define FBCONFIG_2 "/usr/local/lib/imtoolrc" #define CMAPCONFIG "/usr/local/lib/imtoolcmap" #define FBCONFIG_ENV1 "imtoolrc" #define FBCONFIG_ENV2 "IMTOOLRC" #define PRINTCONFIG "/usr/local/lib/ximprint.cfg" #define DEF_ISM_ADDR "/tmp/.ISM%d" /* default ISM unix socket */ #define DEF_ISM_TEMPLATE "/tmp/.ISM%d_%d" /* ISM client socket template */ #define DEF_ISM_TASK "wcspix" #define DEF_ISM_CMD "ism_wcspix.e wcspix &" #define SZ_ISMBUF 4096 /* WCS definitions. */ #define W_UNITARY 0 #define W_LINEAR 1 #define W_LOG 2 #define W_USER 3 #define W_DEFFORMAT " %7.2f %7.2f %7.1f%c" /* Rotation matrix defining world coordinate system (WCS) of a frame. */ typedef struct { int valid; /* has WCS been set? */ float a, b; /* x, y scale factors */ float c, d; /* x, y cross factors */ float tx, ty; /* x, y translation */ float z1, z2; /* greyscale range */ int zt; /* greyscale mapping */ char format[32]; /* wcs output format */ char imtitle[SZ_IMTITLE+1]; /* image title from WCS */ } Ctran, *CtranPtr; /* Coordinate mappings on each frame buffer. */ typedef struct { int id; /* object id */ Ctran ctran; /* world coordinate system */ char ref[SZ_FNAME+1]; /* image reference from WCS */ int regid; /* region id */ char region[SZ_FNAME+1]; /* region name from WCS */ float sx, sy; /* source rect */ int snx, sny; int dx, dy; /* destination rect */ int dnx, dny; } Mapping, *MappingPtr; /* The frame buffers. */ typedef struct { int frameno; /* frame number */ int raster; /* frame buffer raster */ int zoomras; /* zoom/pan raster */ int zoommap; /* zoom/pan mapping */ int dispmap; /* mapping used for display */ int colormap; /* greyscale transformation */ float offset, scale; /* transfer function */ float xscale, yscale; /* scaling at [xy]mag==1.0 */ float xmag, ymag; /* zoom/dezoom factors */ float xcen, ycen; /* center of zoomed region */ float xoff, yoff; /* offset of zoomed region */ int xflip, yflip; /* flip in X or Y? */ char label[SZ_LABEL+1]; /* frame label string */ Ctran ctran; /* world coordinate system */ char wcsbuf[SZ_WCSBUF]; /* wcs info string */ Mapping mapping[MAX_MAPPINGS]; /* coordinate mappings */ int nmaps; /* number of defined mappings */ } FrameBuf, *FrameBufPtr; /* Possible frame buffer sizes. */ typedef struct { int nframes; /* number of frames */ int width; /* frame buffer width */ int height; /* frame buffer height */ } FbConfig, *FbConfigPtr; /* Predefined colormaps. */ typedef struct { int mapno; /* widget colormap number */ char name[SZ_CMAPNAME+1]; /* colormap name */ } ColorMap, *ColorMapPtr; /* Predefined lookup tables. */ typedef struct { float red, green, blue; } Triplet, *TripletPtr; typedef struct { int lutlen; Triplet hue[MAX_COLORS]; } Lut, *LutPtr; /* Client IIS I/O channel. */ typedef struct { XtPointer xim; /* backpointer to xim descriptor */ XtPointer id; /* input callback id */ int type; /* channel type */ int datain; /* input channel */ int dataout; /* output channel */ int keepalive; /* used to keep input fifo ready */ char path[SZ_FNAME+1]; /* for unix sockets */ int reference_frame; /* reference (cmd i/o) frame */ int version; /* flags capability of client */ FrameBufPtr rf_p; /* reference frame descriptor */ } IoChan, *IoChanPtr; #define IO_FIFO 1 #define IO_INET 2 #define IO_UNIX 3 /* Client ISM I/O channel. */ typedef struct { XtPointer xim; /* backpointer to xim descriptor */ XtPointer id; /* input callback id */ int datain; /* input channel */ int dataout; /* output channel */ int connected; /* client connected? */ char name[SZ_FNAME+1]; /* client name */ char path[SZ_FNAME+1]; /* for unix sockets */ char msgbuf[SZ_ISMBUF+1]; /* incomplete message buffer */ } IsmIoChan, *IsmIoChanPtr; /* Definitions for the supported ISM Modules. */ typedef void (*IsmFunc)(); typedef struct { char name[SZ_FNAME]; /* name of the module */ char command[SZ_LINE]; /* cmd to execute for module */ IsmFunc startupCB; /* connection callback func */ IsmFunc shutdownCB; /* shutdown callback func */ IsmFunc commandCB; /* client command callback func */ int connected; /* client is connected */ int ref_count; /* reference count */ IsmIoChanPtr chan; /* i/o channel */ } ismModule, *IsmModule; /* Printer list. */ typedef struct { char printerName[SZ_FNAME+1]; /* printer name */ char printCmd[SZ_FNAME+1]; /* printer dispose command */ } Printer, *PrinterPtr; /* Printer configuration struct. */ typedef struct { int printno; /* printer number */ int seqno; /* sequence number */ int diskfile; /* print to diskfile? */ char printFile[SZ_FNAME+1]; /* disk filename template */ char printCmd[SZ_FNAME+1]; /* dispose command */ } PrintCfg, *PrintCfgPtr; /* File save definitions and structure. */ typedef struct { int seqno; /* sequence number */ int format; /* save format */ int colorType; /* save color type */ int w, h, d; /* dimensions of last file saved */ char fname[SZ_FNAME+1]; /* save filename */ } fileSave, *fileSavePtr; #define XIM_GRAYSCALE 0 /* save color options */ #define XIM_PSEUDOCOLOR 1 #define XIM_RGB 2 #define XIM_RAS 0 /* save format options */ #define XIM_GIF 1 #define XIM_TIFF 2 #define XIM_JPEG 3 #define XIM_X11 4 #define XIM_FITS 5 #define XIM_RAW 6 #define XIM_EPS 7 #define XIM_OIF 8 /* File load struct. */ typedef struct { int nfiles; /* number of files in directory */ char **FileList; /* list of directory contents */ char curdir[SZ_FNAME+1]; /* current directory */ char homedir[SZ_FNAME+1]; /* home directory */ char pattern[SZ_NAME+1]; /* file pattern to match */ int gray; /* load as a grayscale image? */ int zscale; /* zscale the image */ int zrange; /* use full data range */ float z1, z2; /* user-supplied zrange limits */ int nsample; /* number of zscale sample pts */ } fileLoad, *fileLoadPtr; /* * Application resources and runtime descriptor. * ---------------------------------------------- */ typedef struct { /* Resources. */ Boolean autoscale; /* is XY autoscaling enabled */ Boolean antialias; /* apply antialiasing when dezooming */ Boolean tileFrames; /* tile rather than overlay frames */ Boolean highlightFrames; /* highlight tiled frames */ Boolean invert; /* use inverted colormap */ int def_config; /* default FB config */ int def_nframes; /* default number of frames */ int ncolors; /* number of image pixel colors */ int tileBorder; /* image border when tiling frames */ String borderColor; /* border color for tileFrames */ String gui; /* GUI file name */ String imtoolrc; /* imtoolrc file name */ String memModel; /* FB memory model */ String userCMap1; /* user colormap file */ String userCMap2; /* user colormap file */ String userCMapDir1; /* user colormap directory */ String userCMapDir2; /* user colormap directory */ String antialiasType; /* type of antialiasing */ String printConfig; /* printer configuration file */ String input_fifo; /* client's output, e.g. /dev/imt1o */ String output_fifo; /* client's input, e.g. /dev/imt1i */ String unixaddr; /* format for unix socket path */ String ism_addr; /* format for ISM unix socket path */ String ism_task; /* image support module taskname */ int port; /* port for INET socket */ /* Internal state. */ XtPointer obm; /* object manager */ IoChanPtr cursor_chan; /* cursor mode channel */ IoChan chan[MAX_CLIENTS]; /* client i/o descriptors */ IsmIoChan ism_chan; /* image support module channel */ IsmIoChan ism_client[MAX_ISM]; /* ISM client i/o descriptors */ Widget toplevel; /* dummy toplevel app shell */ Widget gt; /* imagewin gterm-image widget */ Widget cb; /* colorbar gterm-image widget */ XtPointer gm_border; /* border marker for tileFrames */ int tileFramesList; /* frames to be tiled (bitmask) */ int nTileFrames; /* number of frames to be tiled */ int tileRows; /* number of tile rows */ int tileCols; /* number of tile cols */ Boolean tileByRows; /* fill tiles by row vs cols */ Boolean tileTopDown; /* fill tiles by top to bottom */ Boolean tileLabels; /* label frame tiles */ int rop; /* rasterop for mappings */ int display_frame; /* currently displayed frame */ FrameBufPtr df_p; /* display frame descriptor */ FrameBuf frames[MAX_FRAMES]; /* array of frame descriptors */ int fb_configno; /* current config number */ int nframes; /* current number of frame bufs */ int width, height; /* current width, height */ FbConfig fb_config[MAX_FBCONFIG]; /* fb config table */ int *clientPrivate; /* used by imtool client code */ PSImagePtr psim; /* EPS image struct pointer */ PrintCfgPtr pcp; /* printer config pointer */ fileLoadPtr flp; /* load disk file pointer */ fileSavePtr fsp; /* save disk file pointer */ } XimData, *XimDataPtr; /* Functions. */ #ifndef abs #define abs(a) (((a)<0)?(-(a)):(a)) #endif #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif #ifndef max #define max(a,b) ((a)<(b)?(b):(a)) #endif void xim_iisio(); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/iis.c����������������������������������������������������������������������������������0000644�0001750�0001750�00000122100�11222465473�012621� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #ifdef HAVE_SYS_UN_H #include <sys/un.h> #endif #include <fcntl.h> #include "iis.h" #include "xim.h" /* IIS data pixel values. */ #define CMS_DATASTART 1 #define CMS_DATAEND 200 #define CMS_DATARANGE 200 /* IIS color assignments. */ #define CMS_CURSOR 201 #define CMS_BACKGROUND 202 #define CMS_FOREGROUND 203 #define CMS_RED 204 #define CMS_GREEN 205 #define CMS_BLUE 206 #define CMS_YELLOW 207 #define CMS_CYAN 208 #define CMS_MAGENTA 209 #define XtInputId void * #define XtNumber(x) MAX_CLIENTS /* * IIS.C -- IRAF/IIS "imtool" protocol module. This code is responsible for * accepting connections from remote network clients and communicating with * them via the imtool/iis image display server communications prototcol. * * fd = xim_iisopen (xim) * xim_iisclose (xim) * xim_iisio (xim, &fd, &id) * * xim_frameLabel (xim) * xim_encodewcs (xim, sx, sy, sz, obuf) * xim_retCursorVal (xim, sx, sy, frame, wcs, key, strval) * * xim_iisiomap (w, iomap, &iomap_len) * xim_iiscolormap (w, r, g, b, &first, &ngray, &rgb_len) * * xim_iisio is a callback procedure called by Xt when there is input to be * processed on the stream used to communicate with the remote client. */ #define MEMORY 01 /* frame buffer i/o */ #define LUT 02 /* lut i/o */ #define FEEDBACK 05 /* used for frame clears */ #define IMCURSOR 020 /* logical image cursor */ #define WCS 021 /* used to set WCS */ #define SZ_IOBUF 65536 /* max size data transfer */ #define IO_TIMEOUT 30 /* i/o not getting anywhere */ #define MAXCONN 5 #define IIS_VERSION 10 /* version 10 -> 1.0 */ #define SZ_IMCURVAL 160 #define PACKED 0040000 #define COMMAND 0100000 #define IIS_READ 0100000 #define IMC_SAMPLE 0040000 #define IMT_FBCONFIG 077 #define XYMASK 077777 struct iism70 { short tid; short thingct; short subunit; short checksum; short x, y, z; short t; }; /* Running id for frame mappings. We keep a separate id for each of the * currently allowed MAX_FRAMES since the object id is used in the WCS * code for the image along with the (frame_num * 100). */ int objid[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static int *wcspix_enabled = NULL; static int iis_debug = -1; /* protocol debug */ static void set_fbconfig(), add_mapping(); static void xim_connectClient(), xim_disconnectClient(); static int chan_read(), chan_write(), decode_frameno(); static CtranPtr wcs_update(); static IoChanPtr open_fifo(), open_inet(); #ifdef HAVE_SYS_UN_H static IoChanPtr open_unix(); #endif static IoChanPtr get_iochan(); static MappingPtr xim_getMapping(); extern int errno; /* XIM_IISOPEN -- Initialize the IIS protocol module and ready the module to * accept client connections and begin processing client requests. Clients * may connect to the server using a fifo connection or an internet or * UNIX domain socket connection. All three types of server ports are * simultaneously ready to receive client connections. */ xim_iisOpen (xim) register XimDataPtr xim; { int nopen = 0; if (open_fifo (xim)) nopen++; if (open_inet (xim)) nopen++; #ifdef HAVE_SYS_UN_H if (open_unix (xim)) nopen++; #endif return (nopen); } /* XIM_IISCLOSE -- Close down the IIS protocol module. */ void xim_iisClose (xim) register XimDataPtr xim; { register IoChanPtr chan; register int i; for (i=0, chan=NULL; i < XtNumber(xim->chan); i++) { chan = &xim->chan[i]; if (chan->id) { xim_removeInput (xim, chan->id); chan->id = NULL; } switch (chan->type) { case IO_FIFO: if (chan->keepalive >= 0) close (chan->keepalive); if (chan->datain >= 0) close (chan->datain); if (chan->dataout >= 0) close (chan->dataout); chan->type = 0; break; case IO_INET: close (chan->datain); chan->type = 0; break; #ifdef HAVE_SYS_UN_H case IO_UNIX: close (chan->datain); unlink (chan->path); chan->type = 0; break; #endif } } } /* OPEN_FIFO -- Ooen the (x)imtool fifo port and make ready to accept client * connections and begin processing client requests. There is no client * yet at this stage. */ static IoChanPtr open_fifo (xim) register XimDataPtr xim; { register IoChanPtr chan; int datain, dataout; int keepalive; #ifdef __DARWIN__ /* On OS X we don't use fifos. */ xim->input_fifo = "none"; return (NULL); #endif /* Setting the input fifo to "none" or the null string disables * fifo support. */ if (!xim->input_fifo[0] || strcmp(xim->input_fifo,"none")==0) return (NULL); datain = dataout = -1; /* Open the output fifo (which is the client's input fifo). We have * to open it ourselves first as a client to get around the fifo * open-no-client error. */ if ((datain = open (xim->input_fifo, O_RDONLY|O_NDELAY)) != -1) { if ((dataout = open (xim->input_fifo, O_WRONLY|O_NDELAY)) != -1) fcntl (dataout, F_SETFL, O_WRONLY); else goto done; close (datain); } else goto done; /* Open the input stream, a FIFO pseudodevice file used by * applications to send us commands and data. */ if ((datain = open (xim->output_fifo, O_RDONLY|O_NDELAY)) == -1) goto done; else { /* Clear O_NDELAY for reading. */ fcntl (datain, F_SETFL, O_RDONLY); /* Open the client's output fifo as a pseudo-client to make it * appear that a client is connected. */ keepalive = open (xim->output_fifo, O_WRONLY); } done: /* Allocate and fill in i/o channel descriptor. */ if (datain > 0 && dataout > 0 && (chan = get_iochan(xim))) { chan->xim = (XtPointer) xim; chan->type = IO_FIFO; chan->datain = datain; chan->dataout = dataout; chan->keepalive = keepalive; chan->reference_frame = 1; chan->version = 0; chan->rf_p = &xim->frames[0]; } else { /* fprintf (stderr, "Warning: cannot open %s\n", xim->output_fifo); */ strcpy (xim->input_fifo, "none"); chan = NULL; } /* Register input callback. */ if (chan) { chan->id = xim_addInput (xim, chan->datain, xim_iisio, (XtPointer)chan); } else { if (datain > 0) close (datain); if (dataout > 0) close (dataout); } return (chan); } /* OPEN_INET -- Set up a port to be used for incoming client connections * using internet domain sockets. */ static IoChanPtr open_inet (xim) register XimDataPtr xim; { register int s = 0; register IoChanPtr chan; struct sockaddr_in sockaddr; int reuse = 1; /* Setting the port to zero disables inet socket support. */ if (xim->port <= 0) return (NULL); if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) goto err; memset ((void *)&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons((short)xim->port); sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) goto err; if (bind (s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) goto err; if (listen (s, MAXCONN) < 0) goto err; /* make sure we close on exec */ fcntl(s, F_SETFD, FD_CLOEXEC); /* Allocate and fill in i/o channel descriptor. */ if (chan = get_iochan(xim)) { chan->xim = (XtPointer) xim; chan->type = IO_INET; chan->datain = s; chan->dataout = s; chan->reference_frame = 1; chan->version = 0; chan->rf_p = &xim->frames[0]; /* Register connectClient callback. */ chan->id = xim_addInput (xim,s,xim_connectClient,(XtPointer)chan); return (chan); } err: /* if (errno == EADDRINUSE) { fprintf (stderr,"ximtool: inet port %d already in use - disabled\n", xim->port); } else { fprintf (stderr, "ximtool: can't open inet socket %d, errno=%d\n", xim->port, errno); } */ xim->port = 0; if (s) close (s); return (NULL); } /* OPEN_UNIX -- Set up a port to be used for incoming client connections * using unix domain sockets. */ #ifdef HAVE_SYS_UN_H static IoChanPtr open_unix (xim) register XimDataPtr xim; { register int s = 0; register IoChanPtr chan; struct sockaddr_un sockaddr; int addrlen; char path[256]; /* Setting the addr to "none" or the null string disables unix * socket support. */ if (!xim->unixaddr[0] || strcmp(xim->unixaddr,"none")==0) return (NULL); /* Get path to be used for the unix domain socket. */ sprintf (path, xim->unixaddr, getuid()); unlink (path); if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) goto err; memset ((void *)&sockaddr, 0, sizeof(sockaddr)); sockaddr.sun_family = AF_UNIX; strcpy (sockaddr.sun_path, path); addrlen = sizeof(sockaddr) - sizeof(sockaddr.sun_path) + strlen(path); if (bind (s, (struct sockaddr *)&sockaddr, addrlen) < 0) goto err; if (listen (s, MAXCONN) < 0) goto err; /* make sure we close on exec */ fcntl(s, F_SETFD, FD_CLOEXEC); /* Allocate and fill in i/o channel descriptor. */ if (chan = get_iochan(xim)) { chan->xim = (XtPointer) xim; chan->type = IO_UNIX; chan->datain = s; chan->dataout = s; chan->reference_frame = 1; chan->version = 0; chan->rf_p = &xim->frames[0]; strncpy (chan->path, path, SZ_FNAME); /* Register connectClient callback. */ chan->id = xim_addInput (xim,s,xim_connectClient,(XtPointer)chan); return (chan); } err: /* if (errno == EADDRINUSE) { fprintf (stderr,"ximtool: unix addr %s already in use - disabled\n", path); } else { fprintf (stderr,"ximtool: cannot open unix socket '%s', errno=%d\n", path, errno); } */ strcpy (xim->unixaddr, "none"); if (s) close (s); return (NULL); } #endif /* XIM_CONNECTCLIENT -- Called when a client has attempted a connection on * a socket port. Accept the connection and set up a new i/o channel to * communicate with the new client. */ static void xim_connectClient (chan_port, source, id) IoChanPtr chan_port; int *source; XtPointer id; { register XimDataPtr xim = (XimDataPtr) chan_port->xim; register IoChanPtr chan; register int s; /* Accept connection. */ if ((s = accept ((int)*source, (struct sockaddr *)0, (int *)0)) < 0) return; /* if (fcntl (s, F_SETFL, O_RDWR|O_NDELAY) < 0) { close (s); return; } */ /* Allocate and fill in i/o channel descriptor. */ if (chan = get_iochan(xim)) { chan->xim = (XtPointer) xim; chan->type = chan_port->type; chan->datain = s; chan->dataout = s; chan->reference_frame = 1; chan->version = 0; chan->rf_p = &xim->frames[0]; chan->id = xim_addInput (xim, s, xim_iisio, (XtPointer)chan); } } /* XIM_DISCONNECTCLIENT -- Called to close a client connection when EOF is * seen on the input port. Close the connection and free the channel * descriptor. */ static void xim_disconnectClient (chan) register IoChanPtr chan; { switch (chan->type) { case IO_INET: case IO_UNIX: close (chan->datain); if (chan->id) { xim_removeInput (chan->xim, chan->id); chan->id = NULL; } chan->type = 0; break; default: break; } } /* GET_IOCHAN --- Get an i/o channel descriptor. */ static IoChanPtr get_iochan (xim) register XimDataPtr xim; { register IoChanPtr chan; register int i; for (i=0; i < XtNumber(xim->chan); i++) if (!xim->chan[i].type) return (&xim->chan[i]); return (NULL); } /* XIM_IISIO -- Xt file i/o callback procedure, called when there is input * pending on the data stream to the ximtool client. */ void xim_iisio (chan, fd_addr, id_addr) IoChanPtr chan; int *fd_addr; XtInputId *id_addr; { register XimDataPtr xim = (XimDataPtr) chan->xim; register MappingPtr mp = (MappingPtr) NULL; register FrameBufPtr fb; register int sum, i; register short *p; int datain = *fd_addr; int dataout = chan->dataout; int ndatabytes, nbytes, n, newframe, ntrys=0; struct iism70 iis; char buf[SZ_FIFOBUF]; static int errmsg=0, bswap=0; /* Initialize the debug output. */ if (iis_debug == -1) iis_debug = (getenv("DEBUG_IIS") != (char *)NULL); /* Get the IIS header. */ if ((n = chan_read (datain, (char *)&iis, sizeof(iis))) < sizeof(iis)) { if (n != 0) fprintf (stderr, "ximtool: command input read error, n=%d of %d, errno=%d\n", n, sizeof(iis), errno); if (n <= 0) xim_disconnectClient (chan); return; } else if (bswap) bswap2 ((char *)&iis, (char *)&iis, sizeof(iis)); /* Verify the checksum. If it fails swap the bytes and try again. */ for (;;) { for (i=0, sum=0, p=(short *)&iis; i < 8; i++) sum += *p++; if ((sum & 0177777) == 0177777) break; if (ntrys++) { if (!errmsg++) { fprintf (stderr, "ximtool: bad data header checksum\n"); if (bswap) bswap2 ((char *)&iis, (char *)&iis, sizeof(iis)); fprintf (stderr, "noswap:"); for (i=0, p=(short *)&iis; i < 8; i++) fprintf (stderr, " %6o", p[i]); fprintf (stderr, "\n"); bswap2 ((char *)&iis, (char *)&iis, sizeof(iis)); fprintf (stderr, " swap:"); for (i=0, p=(short *)&iis; i < 8; i++) fprintf (stderr, " %6o", p[i]); fprintf (stderr, "\n"); } break; } else { bswap2 ((char *)&iis, (char *)&iis, sizeof(iis)); bswap = !bswap; } } ndatabytes = -iis.thingct; if (!(iis.tid & PACKED)) ndatabytes *= 2; if (iis_debug) { fprintf (stderr, "subunit=%06o tid=%06o nbytes=%7d x=%06o y=%06o z=%06o t=%06o\n", iis.subunit & 077, iis.tid, ndatabytes, iis.x & 0177777, iis.y & 0177777, iis.z & 0177777, iis.t & 0177777); fflush (stderr); } switch (iis.subunit & 077) { case FEEDBACK: /* The feedback unit is used only to clear a frame. The * xim_eraseFrame() procedure takes care of uncaching the * mappings associated with this frame. */ newframe = decode_frameno (iis.z & 0177777); xim_setReferenceFrame (chan, newframe); if (newframe == chan->reference_frame) xim_eraseFrame (xim, chan->reference_frame); /* ISM: Uncache all mappings associated with this frame. */ fb = &xim->frames[newframe-1]; for (i=0; i < fb->nmaps; i++) { mp = &fb->mapping[i]; if (mp->id) { sprintf (buf, "uncache %d", mp->id); ism_message (xim, "wcspix", buf); wcspix_message (xim, buf); mp->id = 0; } } /* Reset various counters for the new frame and release the * mappings. */ fb->nmaps = 0; fb->ctran.valid = 0; objid[newframe-1] = 0; fb->nmaps = 0; if (iis_debug) fprintf (stderr, "erase frame %d - ref = %d\n", newframe, chan->reference_frame); break; case LUT: /* Data mode writes to the frame lookup tables are not implemented. * A command mode write to the LUT subunit is used to connect * image memories up to the RGB channels, i.e., to select the frame * to be displayed. We ignore any attempt to assign multiple * frames to multiple color channels, and just do a simple frame * select. */ if (iis.subunit & COMMAND) { int frame, z, n; short x[17]; if (chan_read (datain, (char *)x, ndatabytes) == ndatabytes) { if (bswap) bswap2 ((char *)x, (char *)x, ndatabytes); z = x[0]; if (!z) z = 1; for (n=0; !(z & 1); z >>= 1) n++; frame = max (1, n + 1); if (frame > xim->nframes) { if (frame <= MAX_FRAMES) { set_fbconfig (chan, xim->fb_configno, frame); if (iis_debug) fprintf (stderr, "set_fbconfig (%d, %d)\n", xim->fb_configno, frame); } else { fprintf (stderr, "ximtool warning: "); fprintf (stderr, "attempt to display nonexistent frame %d\n", frame); return; } } xim_setDisplayFrame (xim, frame); if (iis_debug) fprintf (stderr, "set_frame (%d)\n", frame); return; } } case MEMORY: /* Load data into the frame buffer. Data is assumed to be byte * packed. */ if (iis.tid & IIS_READ) { /* Read from the display. */ unsigned char *ip, iobuf[SZ_IOBUF]; int nbytes, nleft, n, x, y; long starttime; /* Get the frame to read from. */ xim_setReferenceFrame (chan, decode_frameno (iis.z & 0177777)); nbytes = ndatabytes; x = iis.x & XYMASK; y = iis.y & XYMASK; if (x < 0 || x >= xim->width || y < 0 || y >= xim->height) { fprintf (stderr, "ximtool: attempted read out of bounds on framebuf\n"); fprintf (stderr, "read %d bytes at [%d,%d]\n", nbytes, x, y); memset ((void *)iobuf, 0, nbytes); } else { GtReadPixels (xim->gt, chan->rf_p->raster, iobuf, 8, x, y, min(xim->width-x,nbytes), max(1,nbytes/xim->width)); if (iis_debug) fprintf (stderr, "read %d bytes at [%d,%d]\n", nbytes, x, y); } /* Return the data from the frame buffer. */ starttime = time(0); for (nleft=nbytes, ip=iobuf; nleft > 0; nleft -= n) { n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF; if ((n = chan_write (dataout, ip, n)) <= 0) { if (n < 0 || (time(0) - starttime > IO_TIMEOUT)) { fprintf (stderr, "XIMTOOL: timeout on write\n"); break; } } else ip += n; } return; } else { /* Write to the display. */ unsigned char *op, iobuf[SZ_IOBUF]; int nbytes, nleft, n, x, y; long starttime; /* Get the frame to be written into (encoded with a bit for * each frame, 01 is frame 1, 02 is frame 2, 04 is frame 3, * and so on). */ xim_setReferenceFrame (chan, decode_frameno (iis.z & 0177777)); nbytes = ndatabytes; x = iis.x & XYMASK; y = iis.y & XYMASK; /* Read the data into the frame buffer. */ starttime = time(0); for (nleft=nbytes, op=iobuf; nleft > 0; nleft -= n) { n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF; if ((n = chan_read (datain, op, n)) <= 0) { if (n < 0 || (time(0) - starttime > IO_TIMEOUT)) { fprintf (stderr, "XIMTOOL: timeout on read\n"); break; } } else op += n; } if (x < 0 || x >= xim->width || y < 0 || y >= xim->height) { fprintf (stderr, "ximtool: attempted write out of bounds on framebuf\n"); fprintf (stderr, "write %d bytes at [%d,%d]\n", nbytes, x, y); memset ((void *)iobuf, 0, nbytes); } else { GtWritePixels (xim->gt, chan->rf_p->raster, iobuf, 8, x, y, min(xim->width-x,nbytes), max(1,nbytes/xim->width)); if (iis_debug) fprintf (stderr, "write %d bytes at x=%d, y=%d\n", nbytes, x, y); } return; } break; case WCS: /* Read or write the WCS for a frame. The frame number to * which the WCS applies is passed in Z and the frame buffer * configuration in T. The client changes the frame buffer * configuration in a WCS set. The WCS text follows the header * as byte packed ASCII data. */ if (iis.tid & IIS_READ) { /* Return the WCS for the referenced frame. */ char emsg[SZ_WCSBUF]; char *text; int frame, wcsnum; memset ((char *)emsg, 0, SZ_WCSBUF); if ((iis.x & 017777) && (iis.y & 017777)) { /* This is a check by the client on our capabilities. * Return with a version number which can be used by the * client. However we write back using the old WCS * buffer size for compatability. */ sprintf (text=emsg, "version=%d", IIS_VERSION); chan->version = IIS_VERSION; chan_write (dataout, text, SZ_OLD_WCSBUF); if (iis_debug) fprintf (stderr, "version query wcs: %s\n",text); } else if ((iis.x & 017777) && (iis.t & 017777)) { /* Return the buffer for a specified WCS number. */ CtranPtr ct = (CtranPtr) NULL; FrameBufPtr fr = (FrameBufPtr) NULL; int wcsnum = (iis.t & 017777); register int i, j; /* Decode the requested wcs number. */ frame = decode_frameno (iis.z & 0177777); /* Search for the requested WCS number. */ mp = (MappingPtr) NULL; for (j=0; j < xim->nframes; j++) { fr = &xim->frames[j]; if (fr->frameno != frame) continue; for (i=0; i < fr->nmaps; i++) { mp = &fr->mapping[i]; if (mp->id == wcsnum) { /* found the mapping */ ct = &(mp->ctran); goto map_found; } } } /* Encode the WCS and mapping information. */ map_found: if (ct) { char wcs[SZ_WCSBUF], mapping[SZ_WCSBUF]; sprintf (wcs, "%s\n%f %f %f %f %f %f %f %f %d\n", ct->imtitle, ct->a, ct->b, ct->c, ct->d, ct->tx, ct->ty, ct->z1, ct->z2, ct->zt); sprintf (mapping, "%s %f %f %d %d %d %d %d %d\n%s\n", mp->region, mp->sx, mp->sy, mp->snx, mp->sny, mp->dx, mp->dy, mp->dnx, mp->dny, mp->ref); strcpy (text=emsg, wcs); strcat (text, mapping); } else strcpy (text=emsg, "[NOSUCHWCS]\n"); chan_write (dataout, text, SZ_WCSBUF); if (iis_debug) { fprintf (stderr, "query specified wcs=%d frame=%d\n", wcsnum, frame); write (2, text, strlen (text)); } } else { frame = decode_frameno (iis.z & 0177777); xim_setReferenceFrame (chan, frame); /*** waj ***/ /* We always want to use the wcs buffer. If frameno == 0 ds9 will fill in the buffer. if (chan->rf_p->frameno <= 0) strcpy (text=emsg, "[NOSUCHFRAME]\n"); else */ /*** waj ***/ text = chan->rf_p->wcsbuf; if ((iis.x & 0777)) chan_write (dataout, text, SZ_WCSBUF); else chan_write (dataout, text, SZ_OLD_WCSBUF); if (iis_debug) { fprintf (stderr, "query wcs: frame = %d\n", frame); write (2, text, strlen(text)); } } } else { /* Set the WCS for the referenced frame. */ register CtranPtr ct; int fb_config, frame, new_wcs = 0; frame = decode_frameno (iis.z & 0177777); fb_config = (iis.t & 0777) + 1; new_wcs = (iis.x & 0777); /* See if we need to change the frame buffer configuration, * or allocate a new frame. */ if (fb_config != xim->fb_configno) set_fbconfig (chan, fb_config, frame); else if (frame > xim->nframes && frame <= MAX_FRAMES) set_fbconfig (chan, xim->fb_configno, frame); /* Read in and set up the WCS. */ xim_setReferenceFrame (chan, frame); memset ((char *)buf, 0, SZ_WCSBUF); if (chan_read (datain, buf, ndatabytes) == ndatabytes) strncpy (chan->rf_p->wcsbuf, buf, (new_wcs ? SZ_WCSBUF : SZ_OLD_WCSBUF)); if (iis_debug) { fprintf (stderr, "set wcs:\n"); write (2, buf, ndatabytes); } strcpy (chan->rf_p->ctran.format, W_DEFFORMAT); chan->rf_p->ctran.imtitle[0] = '\0'; chan->rf_p->ctran.valid = 0; ct = wcs_update (xim, chan->rf_p); /* If we're connected to an old-style client, disable the * WCSPIX ISM, otherwise just let the GUI know it capable. */ wcspix_message (xim, (new_wcs ? "capable" : "disable")); /* Add the mapping information. */ add_mapping (xim, ct, chan->rf_p->wcsbuf, &xim->frames[chan->reference_frame-1]); xim_message (xim, "frameTitle", ct->imtitle); } return; case IMCURSOR: /* Read or write the logical image cursor. This is an extension * added to provide a high level cursor read facility; this is * not the same as a low level access to the IIS cursor subunit. * Cursor reads may be either nonblocking (immediate) or blocking, * using the keyboard or mouse to terminate the read, and * coordinates may be returned in either image (world) or frame * buffer pixel coordinates. */ if (iis.tid & IIS_READ) { /* Read the logical image cursor. In the case of a blocking * read all we do is initiate a cursor read; completion occurs * when the user hits a key or button. */ if (iis_debug) fprintf (stderr, "read cursor position\n"); if (iis.tid & IMC_SAMPLE) { /* Sample the cursor position and return the cursor value * on the output datastream encoded in a fixed size * ascii buffer. */ int wcs = iis.z; int raster, frame; float sx, sy; IoChanPtr sv_chan; /* Save the cursor channel so that sampled cursor reads * can occur on one channel without affecting any * interactive cursor reads in progress on another * channel. */ sv_chan = xim->cursor_chan; xim->cursor_chan = chan; xim_getCursorPos (xim, &sx, &sy, &raster, &frame); xim_retCursorVal (xim, sx, sy, frame, wcs, 0, ""); xim->cursor_chan = sv_chan; } else { /* Initiate a user triggered cursor read. */ if (xim->cursor_chan) { int frame = xim->cursor_chan->reference_frame; xim_retCursorVal (xim, 0., 0., frame, 0, EOF, ""); } xim->cursor_chan = chan; xim_cursorMode (xim, 1); } } else { /* Write (set) the logical image cursor position. */ register CtranPtr ct; int sx = iis.x, sy = iis.y; float wx = sx, wy = sy; int wcs = iis.z; if (iis_debug) fprintf(stderr, "write cursor position: [%d,%d]\n", sx, sy); if (wcs) { ct = wcs_update (xim, xim->df_p); if (ct->valid) { if (abs(ct->a) > .001) sx = (wx - ct->tx) / ct->a; if (abs(ct->d) > .001) sy = (wy - ct->ty) / ct->d; } } xim_setCursorPos (xim, sx, sy); } return; default: /* Ignore unsupported command input. */ break; } /* Discard any data following the header. */ if (!(iis.tid & IIS_READ)) for (nbytes = ndatabytes; nbytes > 0; nbytes -= n) { n = (nbytes < SZ_FIFOBUF) ? nbytes : SZ_FIFOBUF; if ((n = chan_read (datain, buf, n)) <= 0) { if (iis_debug) fprintf (stderr, "discarding %d bytes following header:\n", n); break; } } } /* SET_FBCONFIG -- Set the frame buffer configuration, or add additional * frames to the current configuration. */ static void set_fbconfig (chan, config, frame) IoChanPtr chan; int config; int frame; { register XimDataPtr xim = (XimDataPtr) chan->xim; register FrameBufPtr fb = &xim->frames[frame-1]; register int i; if (config != xim->fb_configno) { /* Change the frame buffer configuration. */ xim_initialize (xim, config, max (xim->fb_config[config-1].nframes, frame), 1); /* Reinitialize the tile framing if enabled. */ /* if (xim->tileFrames) xim_tileFrames (xim, xim->tileFramesList);*/ /* Initialize the ISM to uncache all images when we change * frame buffer configs. */ ism_message (xim, "wcspix", "initialize"); } else if (frame > xim->nframes) { /* Add additional frames. */ for (i=1; i <= frame; i++) { fb = &xim->frames[i-1]; if (fb->frameno != i) { xim_initFrame (xim, i, frame, &xim->fb_config[config-1], xim->memModel); /* If we're in tile mode, add the frame to the tile list * and if needed resize the tile frames. */ if (xim->tileFrames) { xim->tileFramesList |= (1 << (i-1)); xim->nTileFrames++; /* xim_tileFrames (xim, xim->tileFramesList);*/ } } } } xim_setReferenceFrame (chan, frame); if (frame != xim->display_frame) xim_setDisplayFrame (xim, frame); } /* DECODE_FRAMENO -- Decode encoded IIS register frame number. */ static decode_frameno (z) register int z; { register int n; /* Get the frame number, encoded with a bit for each frame, 01 is * frame 1, 02 is frame 2, 04 is frame 3, and so on. */ if (!z) z = 1; for (n=0; !(z & 1); z >>= 1) n++; return (max (1, n + 1)); } /* XIM_RETCURSORVAL -- Return the cursor value on the output datastream to * the client which requested the cursor read. */ /* xim_retCursorVal (xim, sx, sy, frame, wcs, key, strval) register XimDataPtr xim; float sx, sy; int frame; int wcs; int key; char *strval; */ void xim_retCursorVal(XimDataPtr xim, float sx, float sy, int frame, int wcs, int key, char* strval) { register CtranPtr ct; register MappingPtr mp = (MappingPtr) NULL; int dataout, wcscode; char curval[SZ_IMCURVAL]; char keystr[20]; float wx, wy; if (xim->cursor_chan) dataout = xim->cursor_chan->dataout; else return; /* Compute cursor coordinates. */ if (wcs) { ct = wcs_update (xim, xim->df_p); if (ct->valid) { /* The imtool WCS assumes that the center of the first display * pixel is at (0,0) but actually it is at (0.5,0.5). */ sx -= 0.5; sy -= 0.5; if (abs(ct->a) > .001) wx = ct->a * sx + ct->c * sy + ct->tx; if (abs(ct->d) > .001) wy = ct->b * sx + ct->d * sy + ct->ty; } } else { wx = sx; wy = sy; } /* Compute WCS code. */ wcscode = frame * 100 + wcs; if (wcspix_enabled != NULL && *wcspix_enabled) { if ((mp = xim_getMapping (xim, sx, sy, frame))) { wcscode = mp->id; /* Return the coordinates in terms of the mapping. */ ct = &(mp->ctran); wx = ct->a * sx + ct->c * sy + ct->tx; wy = ct->b * sx + ct->d * sy + ct->ty; } } /* Encode the cursor value. */ if (key == EOF) sprintf (curval, "EOF\n"); else { if (isprint (key) && !isspace(key)) { keystr[0] = key; keystr[1] = '\0'; } else sprintf (keystr, "\\%03o", key); sprintf (curval, "%10.3f %10.3f %d %s %s\n", wx, wy, wcscode, keystr, strval); } if (iis_debug) fprintf (stderr, "curval: %s", curval); /* Send it to the client program and terminate cursor mode. */ chan_write (dataout, curval, sizeof(curval)); xim_cursorMode (xim, 0); xim->cursor_chan = NULL; } /* XIM_ENCODEWCS -- Transform the input screen (raster) coordinates and * pixel value and return a string giving X, Y, and the pixel intensity in * world units. */ void xim_encodewcs (register XimDataPtr xim, float sx, float sy, int sz, char* obuf) //float sx, sy; /* screen (raster) pixel coordinates */ //int sz; /* screen pixel value */ //char *obuf; /* receives encoded string */ { register CtranPtr ct; MappingPtr mp = (MappingPtr) NULL; float wx, wy, wz; float y = xim->height - sy; register int j=0, i=0, ch, map_found = 0; char buf[SZ_LINE]; /* The first time we're called get the address of the wcspix * connected flag so we can check whether to get screen pixel * or real-image values. */ if (wcspix_enabled == NULL) { register IsmModule ism; extern ismModule ism_modules[]; extern int ism_nmodules; for (i=0; i < ism_nmodules; i++) { ism = &ism_modules[i]; if (strcmp ("wcspix", ism->name) == 0) wcspix_enabled = &(ism->connected); } } /* Now lookup the coordinate mapping and update the WCS and real * pixel value if the ISM is running. */ if (wcspix_enabled != NULL && *wcspix_enabled) { if ((mp = xim_getMapping (xim, sx+1.0, sy, xim->display_frame))) { ct = &(mp->ctran); sx -= 0.5; sy -= 0.5; wx = ct->a * sx + ct->c * sy + ct->tx; wy = ct->b * sx + ct->d * sy + ct->ty; /* Found the image mapping so request the WCS * and pixel information from the WPIX ISM. */ if (mp->ref != NULL) { sprintf (buf, "wcstran %d %g %g\n", mp->id, wx, wy); ism_message (xim, "wcspix", buf); } map_found++; } } ct = wcs_update (xim, xim->df_p); if (ct->valid) { /* The imtool WCS assumes that the center of the first display * pixel is at (0,0) but actually it is at (0.5,0.5). */ wx = ct->a * sx + ct->c * sy + ct->tx; wy = ct->b * sx + ct->d * sy + ct->ty; if (sz == 0) wz = 0.0; else { switch (ct->zt) { case W_LINEAR: wz = ((sz - CMS_DATASTART) * (ct->z2 - ct->z1) / (CMS_DATARANGE-1)) + ct->z1; break; default: wz = sz; break; } } } else { wx = sx; wy = sy; wz = sz; } ch = ' '; if (sz && ct->valid) { if (ct->z1 < ct->z2) { if (wz < (ct->z1 + 0.01)) ch = '-'; else if (wz > (ct->z2 - 0.01)) ch = '+'; } else if (ct->z1 > ct->z2) { if (wz < (ct->z2 + 0.01)) ch = '-'; else if (wz > (ct->z1 - 0.01)) ch = '+'; } } sprintf (obuf, ct->format, wx + 0.005, wy + 0.005, wz, ch); } /* XIM_GETMAPPING -- Return the mapping struct for the given screen coords. */ static MappingPtr xim_getMapping (xim, sx, sy, frame) register XimDataPtr xim; float sx, sy; /* screen (raster) pixel coordinates */ int frame; { FrameBufPtr fb = (FrameBufPtr) NULL; MappingPtr mp = (MappingPtr) NULL; register int j=0, i=0; float y = xim->height - sy; char buf[SZ_LINE]; register map_debug = 0; /* Loop through the frame buffers until we find the current one. * The mappings aren't stored in the display fb so we need to * search. */ for (j=0; j < xim->nframes; j++) { fb = &xim->frames[j]; if (frame == fb->frameno) { /* Got the right frame, now search for mappings on this * frame which intersect the screen coords. We assume there * are no overlapping image mappings. */ for (i=0; i < fb->nmaps; i++) { mp = &fb->mapping[i]; if (map_debug) { printf ("sx=%.2f sy=%.2f / %.2f --> ", sx, sy, y); printf ("mp->dx=%d+%d=%d mp->dy=%d+%d=%d", mp->dx, mp->dnx, mp->dx+mp->dnx, mp->dy, mp->dny, mp->dy+mp->dny); } if ((sx >= mp->dx && sx <= (mp->dx + mp->dnx)) && ( y >= mp->dy && y <= (mp->dy + mp->dny))) { if (map_debug) printf (" YES\n"); return (mp); } if (map_debug) printf (" NO\n"); } } } return ((MappingPtr) NULL); } /* XIM_FRAMELABEL -- Return a pointer to the frame label string for the current * frame. */ char * xim_frameLabel (xim) register XimDataPtr xim; { register FrameBufPtr df_p = xim->df_p; sprintf (df_p->label, "[%d] %s", df_p->frameno, df_p->ctran.imtitle); return (df_p->label); } /* WCS_UPDATE -- Load the screen WCS, if not yet validated, from the user * wcs file, if any. * * File format (two lines): * * image title (imtool header label string)\n * a b c d tx ty z1 z2 zt * * The WCS text is passed in via the data stream as a write to the subunit * WCS and left in the buffer "wcsbuf". Mapping information is parsed * elsewhere if needed, our only purpose here is to extract the frame WCS. */ static CtranPtr wcs_update (xim, fr) register XimDataPtr xim; FrameBufPtr fr; { register CtranPtr ct = &fr->ctran; char buf[1024], *format; /* Get the new WCS. */ if (!ct->valid) { fr->label[0] = '\0'; ct->zt = W_UNITARY; /* Attempt to read the WCS and set up a unitary transformation * if the information cannot be read. */ if (sscanf (fr->wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d", buf, &ct->a, &ct->b, &ct->c, &ct->d, &ct->tx, &ct->ty, &ct->z1, &ct->z2, &ct->zt) < 7) { if (fr->wcsbuf[0]) fprintf (stderr, "ximtool: error decoding WCS\n"); strncpy (ct->imtitle, "[NO WCS]\n", SZ_IMTITLE); ct->a = ct->d = 1; ct->b = ct->c = 0; ct->tx = ct->ty = 0; ct->zt = W_UNITARY; } else /*** waj ***/ xim_wcs(fr->frameno, ct->a, ct->b, ct->c, ct->d, ct->tx, ct->ty, ct->z1, ct->z2, ct->zt); /*** waj ***/ strncpy (ct->imtitle, buf, SZ_IMTITLE); ct->valid++; } /* Determine best format for wcs output. */ if (ct->valid && ct->zt == W_LINEAR) { float z1, z2, zrange; z1 = ct->z1; z2 = ct->z2; zrange = (z1 > z2) ? z1 - z2 : z2 - z1; if (zrange < 0.01 || (abs(z1) + abs(z2)) / 2.0 < 0.01) format = " %7.2f %7.2f %9.3g%c"; else if (zrange < 100.0 && (abs(z1) + abs(z2)) / 2.0 < 200.0) format = " %7.2f %7.2f %7.3f%c"; else if (zrange > 99999.0 || (abs(z1) + abs(z2)) / 2.0 > 99999.0) format = " %7.2f %7.2f %9.3g%c"; else format = W_DEFFORMAT; } else format = " %7.2f %7.2f %7.0f%c"; strcpy (ct->format, format); return (ct); } /* ADD_MAPPING -- Add a mapping for the current frame. * * File format (two lines): * * image title (imtool header label string)\n * a b c d tx ty z1 z2 zt \n * region_name sx sy snx sny dx dy dnx dny\n * object_ref * * The WCS text is passed in via the data stream as a write to the subunit * WCS and left in the buffer "wcsbuf". Mapping information is parsed * elsewhere if needed, our only purpose here is to extract the frame WCS. */ static void add_mapping (xim, ctran, wcsbuf, fr) register XimDataPtr xim; CtranPtr ctran; char *wcsbuf; FrameBufPtr fr; { register MappingPtr mp = &fr->mapping[fr->nmaps]; register CtranPtr ct = &mp->ctran; register int i, j, frame = fr->frameno; char buf[SZ_WCSBUF], *format; /* Attempt to read the WCS and set up a unitary transformation * if the information cannot be read. */ if (sscanf (wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d", buf, &ct->a, &ct->b, &ct->c, &ct->d, &ct->tx, &ct->ty, &ct->z1, &ct->z2, &ct->zt) < 7) { if (wcsbuf[0]) fprintf (stderr, "ximtool: error decoding WCS\n"); strncpy (ct->imtitle, "[NO WCS]\n", SZ_IMTITLE); ct->a = ct->d = 1; ct->b = ct->c = 0; ct->tx = ct->ty = 0; ct->zt = W_UNITARY; } else strncpy (ct->imtitle, buf, SZ_IMTITLE); ct->valid = 1; /* Skip over the first two lines of WCS data. */ strcpy (buf, wcsbuf); for (i=0, j=0; j < 2 && buf[i]; i++) if (buf[i] == '\n') j++; /* Attempt to read the mapping. */ mp->regid = (++objid[frame-1]) + (frame * 100); mp->id = mp->regid; mp->ref[0] = '\0'; mp->region[0] = '\0'; if (sscanf (&buf[i], "%s%f%f%d%d%d%d%d%d\n%s\n", mp->region, &mp->sx, &mp->sy, &mp->snx, &mp->sny, &mp->dx, &mp->dy, &mp->dnx, &mp->dny, mp->ref) < 10) { if (!wcsbuf[0]) fprintf (stderr, "ximtool: error decoding WCS mapping\n"); strncpy (mp->region, "none", SZ_IMTITLE); strncpy (mp->ref, "none", SZ_IMTITLE); mp->sx = 1.0; mp->sy = 1.0; mp->snx = xim->width; mp->sny = xim->height; mp->dx = 1; mp->dy = 1; mp->dnx = xim->width; mp->dny = xim->height; } memmove (ctran, &mp->ctran, sizeof (Ctran)); /* Tell the ISM to cache this mapping if we have an object ref. */ sprintf (buf, "cache %s %d", mp->ref, mp->id); ism_message (xim, "wcspix", buf); sprintf (buf, "wcslist %d", mp->id); ism_message (xim, "wcspix", buf); /* Send the object ref to the GUI. */ sprintf (buf, "cache %s %d %d", mp->ref, fr->frameno, mp->id); wcspix_message (xim, buf); sprintf (buf, "orient %d %d %d %d", mp->id, fr->frameno, (int)ctran->a, (int)(-1 * ctran->d)); wcspix_message (xim, buf); fr->nmaps++; /* Debug the mappings. */ if (getenv("DEBUG_MAPPINGS") != NULL) print_mappings (fr); } /* PRINT_MAPPINGS -- Debug routine to print all mappings on a frame. */ print_mappings (fr) FrameBufPtr fr; { MappingPtr mp; register int i; if (fr->nmaps == 0) printf ("No mappings for frame %d\n", fr->frameno); for (i=0; i < fr->nmaps; i++) { mp = &fr->mapping[i]; printf ("Mapping %d of %d: id=%d frame=%d:\n", i+1, fr->nmaps, mp->id, fr->frameno); printf ("\t%s %f %f %d %d %d %d %d %d\n\t%s\n", mp->region, mp->sx, mp->sy, mp->snx, mp->sny, mp->dx, mp->dy, mp->dnx, mp->dny, mp->ref); } } /* CHAN_READ -- Read exactly "n" bytes from a descriptor. */ static int chan_read (fd, vptr, nbytes) int fd; void *vptr; int nbytes; { char *ptr = vptr; int nread = 0, nleft = nbytes, nb = 0; while (nleft > 0) { if ( (nb = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) nb = 0; /* and call read() again */ else return(-1); } else if (nb == 0) break; /* EOF */ nleft -= nb; ptr += nb; nread += nb; } return (nread); /* return no. of bytes read */ } /* CHAN_WRITE -- Write exactly "n" bytes to a descriptor. */ static int chan_write (fd, vptr, nbytes) int fd; void *vptr; int nbytes; { char *ptr = vptr; int nwritten = 0, nleft = nbytes, nb = 0; while (nleft > 0) { if ( (nb = write(fd, ptr, nleft)) <= 0) { if (errno == EINTR) nb = 0; /* and call write() again */ else return(-1); /* error */ } nleft -= nb; ptr += nb; nwritten += nb; } return (nwritten); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/iistcl.C�������������������������������������������������������������������������������0000644�0001750�0001750�00000024614�11700667477�013310� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <ctype.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> using namespace std; #include <tcl.h> #include "iistcl.h" extern "C" { #include "iis.h" #include "xim.h" int Iis_Init(Tcl_Interp* interp); int IisCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]); } IIS* iis=NULL; // Debug int IISDebug= 0; static char* dupstr(const char* str) { char* copy; if (str) { copy=new char[strlen(str)+1]; strcpy(copy,str); } else copy=NULL; return copy; } static char* toLower(char* str) { char* ptr = str; while (*ptr) { *ptr = (char)(tolower(((int)(*ptr)))); ptr++; } return str; } int Iis_Init(Tcl_Interp* interp) { if (IISDebug) cerr << "Iis_Init()" << endl; // Define Package Name if (Tcl_PkgProvide(interp, "iis", "1.0") == TCL_ERROR) return TCL_ERROR; // Commands Tcl_CreateCommand(interp, "iis", IisCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); iis = new IIS(interp); if (iis) return TCL_OK; else return TCL_ERROR; } int IisCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]) { if (argc>=2) { if (!strncmp(argv[1], "open", 4)) return iis->open(argc, argv); else if (!strncmp(argv[1], "close", 4)) return iis->close(); else if (!strncmp(argv[1], "retcur", 4)) return iis->retcur(argc, argv); else if (!strncmp(argv[1], "debug", 4)) return iis->debug(argc, argv); else { Tcl_AppendResult(interp, "iis: unknown command: ", argv[1], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: iis ?open?close?retcur?", NULL); return TCL_ERROR; } } IIS::IIS(Tcl_Interp* intp) { interp = intp; { for (int i=0; i<MAXCHANNEL; i++) { chan[i] = NULL; func[i] = NULL; } } // Resources xim.def_config = 1; // default FB config xim.def_nframes = 0; // default number of frames xim.ncolors = DEF_NCOLORS; // number of image pixel colors xim.tileBorder = DEF_TILE_BORDER; // image border when tiling frames xim.borderColor = dupstr(DEF_BORDER_COLOR); // border color for tileFrames xim.autoscale = 0; // is XY autoscaling enabled xim.antialias = 0; // apply antialiasing when dezooming xim.antialiasType = (char*)DEF_ANTIALIASTYPE; // type of antialiasing xim.invert = 0; // use inverted colormap xim.tileFrames = 0; // tile rather than overlay frames xim.highlightFrames = 0; // highlight tiled frames xim.gui = dupstr("default"); // GUI file name // xim.imtoolrc = dupstr(FBCONFIG_2); // imtoolrc file name xim.memModel = dupstr("fast"); // *FB memory model xim.userCMap1 = dupstr("none"); // user colormap file xim.userCMap2 = dupstr("none"); // user colormap file xim.userCMapDir1 = dupstr("none"); // user colormap directory xim.userCMapDir2 = dupstr(CMAPCONFIG); // user colormap directory xim.printConfig = dupstr(PRINTCONFIG); // printer configuration file xim.input_fifo = dupstr(O_DEVNAME); // *client's output, e.g. /dev/imt1o xim.output_fifo = dupstr(I_DEVNAME); // *client's input, e.g. /dev/imt1i xim.unixaddr = dupstr(DEF_UNIXADDR); // *format for unix socket path xim.ism_addr = dupstr("none"); xim.port = DEF_PORT; // *port for INET socket xim.ism_task = dupstr(DEF_ISM_TASK); // items that require 'c' style memory allocation xim.imtoolrc = (char *) calloc(strlen(FBCONFIG_2)+1, sizeof(char)); strncpy (xim.imtoolrc, FBCONFIG_2, strlen(FBCONFIG_2)); /* Internal state. */ xim.obm = NULL; // object manager { for (int i=0; i<MAX_CLIENTS; i++) { xim.chan[i].xim = NULL; // backpointer to xim descriptor xim.chan[i].id = 0; // input callback id xim.chan[i].type = 0; // channel type xim.chan[i].datain = 0; // input channel xim.chan[i].dataout = 0; // output channel xim.chan[i].keepalive = 0; // used to keep input fifo ready xim.chan[i].path[0] = '\0'; // for unix sockets xim.chan[i].reference_frame;// reference (cmd i/o) frame xim.chan[i].rf_p = NULL; // reference frame descriptor } } xim.cursor_chan = NULL; // *cursor mode channel { xim.ism_chan.xim = (XtPointer)NULL; xim.ism_chan.id = 0; xim.ism_chan.datain = 0; xim.ism_chan.dataout = 0; xim.ism_chan.connected = 0; xim.ism_chan.name[0] = '\0'; xim.ism_chan.path[0] = '\0'; xim.ism_chan.msgbuf[0] = '\0'; } { for (int i=0; i<MAX_ISM; i++) { xim.ism_client[i].xim = (XtPointer)NULL; xim.ism_client[i].id = 0; xim.ism_client[i].datain = 0; xim.ism_client[i].dataout = 0; xim.ism_client[i].connected = 0; xim.ism_client[i].name[0] = '\0'; xim.ism_client[i].path[0] = '\0'; xim.ism_client[i].msgbuf[0] = '\0'; } } xim.toplevel = NULL; // dummy toplevel app shell xim.gt = NULL; // *imagewin gterm-image widget xim.cb = NULL; // colorbar gterm-image widget xim.gm_border = NULL; // border marker for tileFrames xim.tileFramesList = 0; // frames to be tiled (bitmask) xim.nTileFrames = 0; // number of frames to be tiled xim.tileRows = 1; xim.tileCols = 1; xim.tileByRows = 1; xim.tileTopDown = 1; xim.tileLabels = 0; xim.rop = 0; // rasterop for mappings xim.display_frame = 0; // currently displayed frame xim.df_p = NULL; // *display frame descriptor { for (int i=0; i<MAX_FRAMES; i++) { xim.frames[i].frameno = 0; xim.frames[i].raster = 0; xim.frames[i].zoomras = 0; xim.frames[i].zoommap = 0; xim.frames[i].dispmap = 0; xim.frames[i].colormap = DEF_COLORMAP; xim.frames[i].offset = 0.5; xim.frames[i].scale = 1.0; xim.frames[i].xscale = xim.frames[i].yscale = 1.0; xim.frames[i].xmag = xim.frames[i].ymag = 1.0; xim.frames[i].xcen = xim.frames[i].ycen = 0.0; xim.frames[i].xoff = xim.frames[i].yoff = 0.0; xim.frames[i].xflip = xim.frames[i].yflip = 0; xim.frames[i].label[0] = '\0'; xim.frames[i].ctran.valid = 0; xim.frames[i].ctran.a = xim.frames[i].ctran.b = 0; xim.frames[i].ctran.c = xim.frames[i].ctran.d = 0; xim.frames[i].ctran.tx = xim.frames[i].ctran.ty = 0; xim.frames[i].ctran.z1 = xim.frames[i].ctran.z2 = 0; xim.frames[i].ctran.zt = 0; xim.frames[i].ctran.format[0] = '\0'; xim.frames[i].ctran.imtitle[0] = '\0'; xim.frames[i].wcsbuf[0] = '\0'; xim.frames[i].nmaps = 0; } } xim.fb_configno = 0; // *current config number xim.nframes = 0; // *current number of frame bufs xim.width = 0; xim.height = 0; // *current width, height //xim.fb_config[MAX_FBCONFIG]; // *fb config table xim.clientPrivate = NULL; // used by imtool client code xim.psim = NULL; // EPS image struct pointer xim.pcp = NULL; // printer config pointer xim.flp = NULL; // load disk file pointer xim.fsp = NULL; // save disk file pointer } IIS::~IIS() { if (xim.borderColor) delete [] xim.borderColor; if (xim.gui) delete [] xim.gui; // if (xim.imtoolrc) // delete xim.imtoolrc; if (xim.memModel) delete [] xim.memModel; if (xim.userCMap1) delete [] xim.userCMap1; if (xim.userCMap2) delete [] xim.userCMap2; if (xim.userCMapDir1) delete [] xim.userCMapDir1; if (xim.userCMapDir2) delete [] xim.userCMapDir2; if (xim.antialiasType) delete xim.antialiasType; if (xim.printConfig) delete [] xim.printConfig; if (xim.input_fifo) delete [] xim.input_fifo; if (xim.output_fifo) delete [] xim.output_fifo; if (xim.unixaddr) delete [] xim.unixaddr; if (xim.ism_addr) delete [] xim.ism_addr; if (xim.ism_task) delete [] xim.ism_task; // items that require 'c' style memory allocation if (xim.imtoolrc) free(xim.imtoolrc); } void IIS::eval(char* cmd) { if (Tcl_Eval(interp, cmd) == TCL_ERROR) cerr << interp->result << endl; } char *IIS::evalstr(char* cmd) { if (Tcl_Eval(interp, cmd) == TCL_ERROR) cerr << interp->result << endl; return interp->result; } int IIS::open(int argc, const char* argv[]) { if (IISDebug) cerr << "IIS:open()" << endl; if (argc==6) { delete [] xim.input_fifo; xim.input_fifo = dupstr(argv[2]); // *client's output, e.g. /dev/imt1i delete [] xim.output_fifo; xim.output_fifo = dupstr(argv[3]); // *client's input, e.g. /dev/imt1o string x(argv[4]); istringstream str(x); str >> xim.port; // *port for INET socket delete [] xim.unixaddr; xim.unixaddr = dupstr(argv[5]); // *format for unix socket path } xim_initialize(&xim, xim.def_config, xim.def_nframes, 1); xim_iisOpen(&xim); return TCL_OK; } int IIS::close() { if (IISDebug) cerr << "IIS::close()" << endl; xim_iisClose(&xim); return TCL_OK; } int IIS::retcur(int argc, const char* argv[]) { if (argc==6) { if (xim.cursor_chan == NULL) { Tcl_AppendResult(interp, "iis retcur: no cursor channel", NULL); return TCL_ERROR; } float xx,yy; { string x(argv[2]); istringstream str(x); str >> xx; } { string x(argv[3]); istringstream str(x); str >> yy; } int key = argv[4][0]; int frame; { string x(argv[5]); istringstream str(x); str >> frame; } xim_retCursorVal(&xim, xx, yy, frame, 0, key, (char*)""); return TCL_OK; } else { Tcl_AppendResult(interp, "iis retcur: wrong number of args", NULL); return TCL_ERROR; } } int IIS::encodewcs(int argc, const char* argv[]) { if (argc==4 || argc==5) { float sx,sy; { string x(argv[2]); istringstream str(x); str >> sx; } { string x(argv[3]); istringstream str(x); str >> sy; } int sz = 0; { string x(argv[4]); istringstream str(x); str >> sz; } char buf[SZ_LINE]; xim_encodewcs(&xim, sx, sy, sz, buf); Tcl_SetResult (interp, buf, TCL_VOLATILE); return TCL_OK; } else { Tcl_AppendResult(interp, "iis encodewcs: wrong number of args", NULL); return TCL_ERROR; } } int IIS::debug(int argc, const char* argv[]) { IISDebug = !strncmp(argv[2],"1",1); return TCL_OK; } ��������������������������������������������������������������������������������������������������������������������./saods9/iis/iistcl.h�������������������������������������������������������������������������������0000644�0001750�0001750�00000001363�11700667477�013351� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __iistcl_h__ #define __iistcl_h__ extern "C" { #include "ximtool.h" } extern int IISDebug; #define MAXCHANNEL 40 class IIS { private: Tcl_Interp* interp; public: XimData xim; IoChan* chan[MAXCHANNEL]; void (*func[MAXCHANNEL])(IoChan*, int*, void*); public: IIS(Tcl_Interp*); ~IIS(); void eval(char*); char* evalstr(char*); const char* result() {return interp->result;} int open(int, const char*[]); int close(); int retcur(int, const char*[]); int encodewcs(int, const char*[]); int debug(int, const char*[]); }; extern IIS* iis; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/xim.C����������������������������������������������������������������������������������0000644�0001750�0001750�00000016061�11700667477�012613� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <string.h> #include <sys/time.h> #include <iostream> #include <sstream> using namespace std; #include <tcl.h> #include "iistcl.h" extern "C" { #include "iis.h" #include "xim.h" void iisIO(void* data, int mask) { int fd = (long)data; if (IISDebug) cerr << "iisIO() " << fd << ' ' << mask << endl; if ((fd < MAXCHANNEL) && iis->func[fd]) { (*iis->func[fd])(iis->chan[fd], &fd, NULL); } else cerr << "Error: IIS iisIO problems" << endl; } } // extern 'C' int xim_addInput(XimDataPtr xim, int fd, void (*func)(IoChan*, int*, void*), IoChan* chan) { if (IISDebug) cerr << "xim_addInput() " << fd << ' ' << func << ' ' << chan << endl; iis->func[fd] = func; iis->chan[fd] = chan; #ifndef __WIN32__ Tcl_CreateFileHandler(fd, TCL_READABLE, (void (*)(void*,int))iisIO, (void*)fd); #else Tcl_CreateEventSource(setupProc, checkProc, (void*)fd); #endif return fd; } #ifdef __WIN32__ void setupProc(void* fd, int flags) { Tcl_Time blockTime = {0,1000}; Tcl_SetMaxBlockTime(&blockTime); return; } void checkProc(void* fdd, int flags) { int fd = (int)fdd; fd_set readfds; struct timeval tv = {0,0}; FD_ZERO(&readfds); FD_SET(fd, &readfds); int got = select(fd+1, &readfds, NULL, NULL, &tv); if (got<0) Tcl_DeleteEventSource(setupProc, checkProc, fdd); else if (got>0) iisIO(fdd,0); } #endif void xim_removeInput(XimDataPtr xim, int fd) { if (IISDebug) cerr << "xim_removeInput() " << fd << endl; if (fd < MAXCHANNEL) { iis->func[fd] = NULL; iis->chan[fd] = NULL; #ifndef __WIN32__ Tcl_DeleteFileHandler(fd); #endif } else cerr << "Error: IIS xim_removeInput-- bad fd" << endl; } void xim_initialize(XimDataPtr xim, int config, int nframes, int hardreset) { // from ximtool xim_initialize get_fbconfig(xim); xim->fb_configno = config; xim->df_p = &xim->frames[0]; FbConfigPtr cf = &xim->fb_config[config-1]; xim->width = cf->width; xim->height = cf->height; ostringstream str; str << "IISInitializeCmd " << xim->width << ' ' << xim->height << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "IISInitializeCmd " << xim->width << ' ' << xim->height << endl; } void xim_initFrame(XimDataPtr xim, int frame, int nframes, FbConfig* config, char* memModel) { // from ximtool xim_initFrame FrameBufPtr fb = &xim->frames[frame-1]; fb->frameno = frame; fb->raster = frame; fb->zoomras = 0; fb->zoommap = 0; fb->dispmap = 0; fb->colormap = DEF_COLORMAP; fb->offset = 0.5; fb->scale = 1.0; fb->xscale = fb->yscale = 1.0; fb->xmag = fb->ymag = 1.0; fb->xcen = fb->ycen = 0.0; fb->xoff = fb->yoff = 0.0; fb->xflip = fb->yflip = 0; fb->label[0] = '\0'; fb->wcsbuf[0] = '\0'; fb->nmaps = 0; // my stuff ostringstream str; str << "IISInitFrameCmd " << frame << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_initFrame() " << str.str().c_str() << endl; } void xim_setDisplayFrame(XimDataPtr xim, int frame) { // from imtool xim_setDisplayFrame FbConfig* config = &xim->fb_config[xim->fb_configno-1]; xim->df_p = &xim->frames[frame-1]; xim->width = config->width; xim->height = config->height; // and my stuff ostringstream str; str << "IISSetDisplayFrameCmd " << frame << ' ' << config->width << ' ' << config->height << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) { cerr << "xim_setDisplayFrame() " << str.str().c_str() << endl; } } void xim_setReferenceFrame(IoChanPtr chan, int frame) { // from imtool xim_setDisplayFrame // Ignore request if channel not active. if (!chan->type) return; XimDataPtr xim = (XimDataPtr)chan->xim; int frameno = max(1, min(MAX_FRAMES, frame)); FrameBufPtr fb = &xim->frames[frameno-1]; // Ignore request if not a valid frame. // // All frames are valid, ds9 frames now work with iis. // // if (fb->frameno > 0) { chan->reference_frame = frameno; chan->rf_p = fb; // } ostringstream str; str << "IISSetRefFrameCmd " << frame << ends; char *wcs = iis->evalstr((char*)str.str().c_str()); if (IISDebug) if (*wcs) cerr << "xim_setReferenceFrame() " << str.str().c_str() << " " << wcs << endl; else cerr << "xim_setReferenceFrame() " << str.str().c_str() << endl; if (*wcs) strcpy(fb->wcsbuf, wcs); } void xim_eraseFrame(XimDataPtr xim, int frame) { ostringstream str; str << "IISEraseFrameCmd " << frame << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_eraseFrame() " << str.str().c_str() << endl; } void xim_message(XimDataPtr xim, char* message, char* imtitle) { ostringstream str; str << "IISMessageCmd {" << message << ' ' << imtitle << '}' << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_message() " << str.str().c_str() << endl; } void xim_wcs(int frame, float a, float b, float c, float d, float tx, float ty, float z1, float z2, int zt) { ostringstream str; str << "IISWCSCmd " << frame << ' ' << a << ' ' << b << ' ' << c << ' ' << d << ' ' << tx << ' ' << ty << ' ' << z1 << ' ' << z2 << ' ' << zt << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_wcs() " << frame << ' ' << a << ' ' << b << ' ' << c << ' ' << d << ' ' << tx << ' ' << ty << ' ' << z1 << ' ' << z2 << ' ' << zt << endl; } void GtWritePixels(void* gt, int frame, void* pixels, int bits, int xx, int yy, int dx, int dy) { ostringstream str; str << "IISWritePixelsCmd " << frame << ' ' << pixels << ' ' << xx << ' ' << yy << ' ' << dx << ' ' << dy << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "GtWritePixels() " << str.str().c_str() << endl; } void GtReadPixels(void* gt, int frame, void* pixels, int nbits, int xx, int yy, int dx, int dy) { ostringstream str; str << "IISReadPixelsCmd " << frame << ' ' << pixels << ' ' << xx << ' ' << yy << ' ' << dx << ' ' << dy << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "GtReadPixels() " << str.str().c_str() << endl; } void xim_cursorMode(XimDataPtr xim, int state) { ostringstream str; str << "IISCursorModeCmd " << state << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_cursorMode() " << state << endl; } void xim_getCursorPos(XimDataPtr xim, float* xx, float* yy, int* raster, int* frame) { { ostringstream str; str << "IISGetCursorPosCmd " << ends; iis->eval((char*)str.str().c_str()); } if (IISDebug) cerr << "xim_getCursorPos()" << endl; { string x(iis->result()); istringstream str(x); str >> *xx >> *yy >> *frame; *raster = *frame; } } void xim_setCursorPos(XimDataPtr xim, int xx, int yy) { ostringstream str; str << "IISSetCursorPosCmd " << xx << ' ' << yy << ends; iis->eval((char*)str.str().c_str()); if (IISDebug) cerr << "xim_setCursorPos()" << endl; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/iis/xim.h����������������������������������������������������������������������������������0000644�0001750�0001750�00000001737�07307475503�012657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __xim_h__ #define __xim_h__ #include "ximtool.h" void xim_initialize(XimDataPtr, int, int, int); void GtQueryColormap(void*, int, int*, int*, int*); void GtReadPixels(void*, int, void*, int, int, int, int, int); void GtWritePixels(void*, int, void*, int, int, int, int, int); void xim_cursorMode(XimDataPtr, int); void xim_getCursorPos(XimDataPtr, float*, float*, int*, int*); void xim_setReferenceFrame(IoChanPtr, int); void xim_setDisplayFrame(XimDataPtr, int); void xim_removeInput(XimDataPtr, int); void xim_message(XimDataPtr, char*, char*); void xim_initFrame(XimDataPtr, int, int, FbConfig*, char*); void xim_setCursorPos(XimDataPtr, int, int); void xim_eraseFrame(XimDataPtr, int); int xim_addInput(XimDataPtr, int, void (*func)(IoChan*, int*, void*), IoChan*); void xim_wcs(int, float, float, float, float, float, float, float, float, int); #ifdef __WIN32__ void setupProc(void*, int); void checkProc(void*, int); #endif void default_imtoolrc (XimDataPtr xim); #endif ���������������������������������./saods9/iis/iis.h����������������������������������������������������������������������������������0000644�0001750�0001750�00000000700�11107101056�012611� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __iis_h__ #define __iis_h__ #include "ximtool.h" int xim_iisOpen(XimDataPtr); void xim_iisClose(XimDataPtr); void xim_retCursorVal(XimDataPtr, float, float, int, int, int, char*); void xim_encodewcs(XimDataPtr, float, float, int, char*); void get_fbconfig(XimDataPtr); void bswap2 (char* a, char* b, int nbytes); void wcspix_message (XimDataPtr xim, char* message); void ism_message (XimDataPtr xim, char* object, char* command); #endif ����������������������������������������������������������������./saods9/iis/util.c���������������������������������������������������������������������������������0000644�0001750�0001750�00000016510�10423300740�013004� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdio.h> #include <stdlib.h> #include <string.h> #include "iis.h" #include "xim.h" /* Definitions for the supported ISM Modules. */ int ism_nmodules = 0; ismModule ism_modules[] = { {"wcspix", "", NULL, NULL, NULL, 0}, }; /* BSWAP2 - Move bytes from array "a" to array "b", swapping successive * pairs of bytes. The two arrays may be the same but may not be offset * and overlapping. */ void bswap2 (char* a, char* b, int nbytes) { register char *ip=a, *op=b, *otop; register unsigned temp; /* Swap successive pairs of bytes. */ for (otop = op + (nbytes & ~1); op < otop; ) { temp = *ip++; *op++ = *ip++; *op++ = temp; } /* If there is an odd byte left, move it to the output array. */ if (nbytes & 1) *op = *ip; } /* GET_FBCONFIG -- Read the XIMTOOL startup file to get the set of possible * frame buffer sizes. * * File format: configno nframes width height [extra fields] * e.g., 1 2 512 512 * 2 2 800 800 * 3 1 1024 1024 # comment */ void get_fbconfig (register XimDataPtr xim) { register char *ip; register FILE *fp = NULL; int config, nframes, width, height, i; char lbuf[SZ_LINE+1], *fname; static char *fb_paths[] = { "/usr/local/lib/imtoolrc", "/opt/local/lib/imtoolrc", "/iraf/iraf/dev/imtoolrc", "/local/lib/imtoolrc", "/usr/iraf/dev/imtoolrc", "/usr/local/iraf/dev/imtoolrc", NULL}; /* Initialize the config table. */ xim->fb_configno = 1; for (i=0; i < MAX_FBCONFIG; i++) { xim->fb_config[i].nframes = 1; xim->fb_config[i].width = DEF_FRAME_WIDTH; xim->fb_config[i].height = DEF_FRAME_HEIGHT; } /* Now add in some defaults for commonly used sizes based on the * standard IRAF imtoolrc file, we'll avoid any instrument specific * configurations. */ xim->fb_config[0].width = xim->fb_config[0].height = 512; xim->fb_config[1].width = xim->fb_config[1].height = 800; xim->fb_config[2].width = xim->fb_config[2].height = 1024; xim->fb_config[3].width = xim->fb_config[3].height = 1600; xim->fb_config[4].width = xim->fb_config[4].height = 2048; xim->fb_config[5].width = xim->fb_config[5].height = 4096; /* Attempt to open the config file. */ if ((fname=getenv(FBCONFIG_ENV1)) || (fname=getenv(FBCONFIG_ENV2))) fp = fopen (fname, "r"); if (!fp && (fname = getenv ("HOME"))) { sprintf (lbuf, "%s/%s", fname, FBCONFIG_1); fp = fopen (fname = lbuf, "r"); if (fp) { if (xim->imtoolrc) free(xim->imtoolrc); xim->imtoolrc = (char *) calloc (SZ_LINE, sizeof(char)); strncpy (xim->imtoolrc, fname, strlen(fname)); } } if (!fp) fp = fopen (fname = xim->imtoolrc, "r"); for (i=0; !fp && fb_paths[i]; i++) { if ((fp = fopen (fname = fb_paths[i], "r"))) { if (xim->imtoolrc) free(xim->imtoolrc); xim->imtoolrc = calloc(strlen(fb_paths[i])+1,sizeof(char)); strncpy (xim->imtoolrc, fb_paths[i],strlen(fb_paths[i])); break; } } if (!fp) { default_imtoolrc(xim); return; } /* Scan the frame buffer configuration file. */ while (fgets (lbuf, SZ_LINE, fp) != NULL) { /* Skip comment lines and blank lines. */ for (ip=lbuf; *ip == ' ' || *ip == '\t'; ip++) ; if (*ip == '\n' || *ip == '#') continue; if (!isdigit (*ip)) continue; switch (sscanf (ip, "%d%d%d%d", &config,&nframes,&width,&height)) { case 4: break; /* normal case */ case 3: height = width; /* default to square format */ break; default: fprintf (stderr, "ximtool: bad config `%s'\n", ip); continue; } nframes = max (1, nframes); width = max (1, width); height = max (1, height); /* Since the frame buffer is stored in a memory pixrect * (effectively), the line length should be an integral number * of 16 bit words. */ if (width & 1) { fprintf (stderr, "imtool warning: fb config %d [%d-%dx%d] - ", config, nframes, width, height); fprintf (stderr, "frame width should be even, reset to %d\n", --width); } config = max(1, min(MAX_FBCONFIG, config)) - 1; xim->fb_config[config].nframes = nframes; xim->fb_config[config].width = width; xim->fb_config[config].height = height; } if (fp) fclose (fp); } /* * Default imtoolrc file-- if a valid imtoolrc file can not be found, * then fill out a default fb_config */ void default_imtoolrc(XimDataPtr xim) { /* 1 2 512 512 # imt1|imt512 */ xim->fb_config[0].nframes = 2; xim->fb_config[0].width = 512; xim->fb_config[0].height = 512; /* 2 2 800 800 # imt2|imt800 */ xim->fb_config[1].nframes = 2; xim->fb_config[1].width = 800; xim->fb_config[1].height = 800; /* 3 2 1024 1024 # imt3|imt1024 */ xim->fb_config[2].nframes = 2; xim->fb_config[2].width = 1024; xim->fb_config[2].height = 1024; /* 4 1 1600 1600 # imt4|imt1600 */ xim->fb_config[3].nframes = 1; xim->fb_config[3].width = 1600; xim->fb_config[3].height = 1600; /* 5 1 2048 2048 # imt5|imt2048 */ xim->fb_config[4].nframes = 1; xim->fb_config[4].width = 2048; xim->fb_config[4].height = 2048; /* 6 1 4096 4096 # imt6|imt4096 */ xim->fb_config[5].nframes = 1; xim->fb_config[5].width = 4096; xim->fb_config[5].height = 4096; /* 7 1 8192 8192 # imt7|imt8192 */ xim->fb_config[6].nframes = 1; xim->fb_config[6].width = 8192; xim->fb_config[6].height = 8192; /* 8 1 1024 4096 # imt8|imt1x4 */ xim->fb_config[7].nframes = 1; xim->fb_config[7].width = 1024; xim->fb_config[7].height = 4096; /* 9 2 1144 880 # imt9|imtfs full screen (1152x900 minus frame) */ xim->fb_config[8].nframes = 2; xim->fb_config[8].width = 1144; xim->fb_config[8].height = 880; /* 10 2 1144 764 # imt10|imtfs35 full screen at 35mm film aspect */ xim->fb_config[9].nframes = 2; xim->fb_config[9].width = 1144; xim->fb_config[9].height = 764; /* 11 2 128 128 # imt11|imt128 */ xim->fb_config[10].nframes = 2; xim->fb_config[10].width = 128; xim->fb_config[10].height = 128; /* 12 2 256 256 # imt12|imt256 */ xim->fb_config[11].nframes = 2; xim->fb_config[11].width = 256; xim->fb_config[11].height = 256; /* 13 2 128 1056 # imt13|imttall128 tall & narrow for spectro. */ xim->fb_config[12].nframes = 2; xim->fb_config[12].width = 128; xim->fb_config[12].height = 1056; /* 14 2 256 1056 # imt14|imttall256 tall & wider for spectro. */ xim->fb_config[13].nframes = 2; xim->fb_config[13].width = 256; xim->fb_config[13].height = 1056; /* 15 2 1056 128 # imt15|imtwide128 wide & thin for spectro. */ xim->fb_config[14].nframes = 2; xim->fb_config[14].width = 1056; xim->fb_config[14].height = 128; /* 16 2 1056 256 # imt16|imtwide256 wide & fatter for spectro. */ xim->fb_config[15].nframes = 2; xim->fb_config[15].width = 1056; xim->fb_config[15].height = 256; /* 17 2 1008 648 # imt17|imtssy Solitaire fmt w/ imtool border */ xim->fb_config[16].nframes = 2; xim->fb_config[16].width = 1008; xim->fb_config[16].height = 648; /* 18 2 1024 680 # imt18|imtssn Solitaire fmt w/out imtool border */ xim->fb_config[17].nframes = 2; xim->fb_config[17].width = 1024; xim->fb_config[17].height = 680; /* 19 1 4096 1024 # imt19|imt4x1 */ xim->fb_config[18].nframes = 1; xim->fb_config[18].width = 4096; xim->fb_config[18].height = 1024; } void wcspix_message (XimDataPtr xim, char* message) {} void ism_message (XimDataPtr xim, char* object, char* command) {} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/plio/��������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012033� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/plio/Makefile������������������������������������������������������������������������������0000644�0001750�0001750�00000000422�10735271617�013515� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include CFLAGS = $(CCOPT) -I. SRC = pliocomp.c OBJS = $(SRC:%.c=%.o) LIB = libplio.a $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) install : $(LIB) cp $(LIB) ../lib/. clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.a *.so FORCE : ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/plio/pliocomp.c����������������������������������������������������������������������������0000644�0001750�0001750�00000015654�10737246655�014066� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* stdlib is needed for the abs function */ #include <stdlib.h> /* The following prototype code was provided by Doug Tody, NRAO, for performing conversion between pixel arrays and line lists. The compression technique is used in IRAF. */ int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* * PL_P2L -- Convert a pixel array to a line list. The length of the list is * returned as the function value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif int pl_p2li (int *pxsrc, int xs, short *lldst, int npix) /* int *pxsrc; input pixel array */ /* int xs; starting index in pxsrc (?) */ /* short *lldst; encoded line list */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2, i__3; /* Local variables */ static int zero, v, x1, hi, ip, dv, xe, np, op, iz, nv, pv, nz; /* Parameter adjustments */ --lldst; --pxsrc; /* Function Body */ if (! (npix <= 0)) { goto L110; } ret_val = 0; goto L100; L110: lldst[3] = -100; lldst[2] = 7; lldst[1] = 0; lldst[6] = 0; lldst[7] = 0; xe = xs + npix - 1; op = 8; zero = 0; /* Computing MAX */ i__1 = zero, i__2 = pxsrc[xs]; pv = max(i__1,i__2); x1 = xs; iz = xs; hi = 1; i__1 = xe; for (ip = xs; ip <= i__1; ++ip) { if (! (ip < xe)) { goto L130; } /* Computing MAX */ i__2 = zero, i__3 = pxsrc[ip + 1]; nv = max(i__2,i__3); if (! (nv == pv)) { goto L140; } goto L120; L140: if (! (pv == 0)) { goto L150; } pv = nv; x1 = ip + 1; goto L120; L150: goto L131; L130: if (! (pv == 0)) { goto L160; } x1 = xe + 1; L160: L131: np = ip - x1 + 1; nz = x1 - iz; if (! (pv > 0)) { goto L170; } dv = pv - hi; if (! (dv != 0)) { goto L180; } hi = pv; if (! (abs(dv) > 4095)) { goto L190; } lldst[op] = (short) ((pv & 4095) + 4096); ++op; lldst[op] = (short) (pv / 4096); ++op; goto L191; L190: if (! (dv < 0)) { goto L200; } lldst[op] = (short) (-dv + 12288); goto L201; L200: lldst[op] = (short) (dv + 8192); L201: ++op; if (! (np == 1 && nz == 0)) { goto L210; } v = lldst[op - 1]; lldst[op - 1] = (short) (v | 16384); goto L91; L210: L191: L180: L170: if (! (nz > 0)) { goto L220; } L230: if (! (nz > 0)) { goto L232; } lldst[op] = (short) min(4095,nz); ++op; /* L231: */ nz += -4095; goto L230; L232: if (! (np == 1 && pv > 0)) { goto L240; } lldst[op - 1] = (short) (lldst[op - 1] + 20481); goto L91; L240: L220: L250: if (! (np > 0)) { goto L252; } lldst[op] = (short) (min(4095,np) + 16384); ++op; /* L251: */ np += -4095; goto L250; L252: L91: x1 = ip + 1; iz = x1; pv = nv; L120: ; } /* L121: */ lldst[4] = (short) ((op - 1) % 32768); lldst[5] = (short) ((op - 1) / 32768); ret_val = op - 1; goto L100; L100: return ret_val; } /* plp2li_ */ /* * PL_L2PI -- Translate a PLIO line list into an integer pixel array. * The number of pixels output (always npix) is returned as the function * value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix) /* short *ll_src; encoded line list */ /* int xs; starting index in ll_src */ /* int *px_dst; output pixel array */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2; /* Local variables */ static int data, sw0001, otop, i__, lllen, i1, i2, x1, x2, ip, xe, np, op, pv, opcode, llfirt; static int skipwd; /* Parameter adjustments */ --px_dst; --ll_src; /* Function Body */ if (! (ll_src[3] > 0)) { goto L110; } lllen = ll_src[3]; llfirt = 4; goto L111; L110: lllen = (ll_src[5] << 15) + ll_src[4]; llfirt = ll_src[2] + 1; L111: if (! (npix <= 0 || lllen <= 0)) { goto L120; } ret_val = 0; goto L100; L120: xe = xs + npix - 1; skipwd = 0; op = 1; x1 = 1; pv = 1; i__1 = lllen; for (ip = llfirt; ip <= i__1; ++ip) { if (! skipwd) { goto L140; } skipwd = 0; goto L130; L140: opcode = ll_src[ip] / 4096; data = ll_src[ip] & 4095; sw0001 = opcode; goto L150; L160: x2 = x1 + data - 1; i1 = max(x1,xs); i2 = min(x2,xe); np = i2 - i1 + 1; if (! (np > 0)) { goto L170; } otop = op + np - 1; if (! (opcode == 4)) { goto L180; } i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = pv; /* L190: */ } /* L191: */ goto L181; L180: i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = 0; /* L200: */ } /* L201: */ if (! (opcode == 5 && i2 == x2)) { goto L210; } px_dst[otop] = pv; L210: L181: op = otop + 1; L170: x1 = x2 + 1; goto L151; L220: pv = (ll_src[ip + 1] << 12) + data; skipwd = 1; goto L151; L230: pv += data; goto L151; L240: pv -= data; goto L151; L250: pv += data; goto L91; L260: pv -= data; L91: if (! (x1 >= xs && x1 <= xe)) { goto L270; } px_dst[op] = pv; ++op; L270: ++x1; goto L151; L150: ++sw0001; if (sw0001 < 1 || sw0001 > 8) { goto L151; } switch ((int)sw0001) { case 1: goto L160; case 2: goto L220; case 3: goto L230; case 4: goto L240; case 5: goto L160; case 6: goto L160; case 7: goto L250; case 8: goto L260; } L151: if (! (x1 > xe)) { goto L280; } goto L131; L280: L130: ; } L131: i__1 = npix; for (i__ = op; i__ <= i__1; ++i__) { px_dst[i__] = 0; /* L290: */ } /* L291: */ ret_val = npix; goto L100; L100: return ret_val; } /* pll2pi_ */ ������������������������������������������������������������������������������������./saods9/saotk/�������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012211� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013474� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/panner.C����������������������������������������������������������������������0000644�0001750�0001750�00000022125�12042560016�015074� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include "panner.h" #include "util.h" // Parser Stuff #undef yyFlexLexer #define yyFlexLexer pnFlexLexer #include <FlexLexer.h> void* pnlval; extern int pnparse(Panner*, pnFlexLexer*); int pnlex(void* vval, pnFlexLexer* ll) { pnlval = vval; return ll ? ll->yylex() : 0; } void pnerror(Panner* pn, pnFlexLexer* ll, const char* m) { pn->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { pn->error(": "); pn->error(cmd); } } // Public Member Functions Panner::Panner(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Widget(i, c, item) { thumbnail = 0; highLite = 0; panning = 0; needsUpdate = 0; bboxGC = NULL; useBBox = 1; compassGC = NULL; threed = 0; useCompass = 1; validWCSCompass = 0; tkfont_ = NULL; } Panner::~Panner() { if (bboxGC) XFreeGC(display, bboxGC); if (compassGC) XFreeGC(display, compassGC); if (tkfont_) Tk_FreeFont(tkfont_); } int Panner::parse(istringstream& istr) { result = TCL_OK; pnFlexLexer* ll = new pnFlexLexer(&istr); pnparse(this, ll); delete ll; return result; } void Panner::update() { needsUpdate = 1; redraw(); } // Required Virtual Functions // UpdatePixmap. This function is responsable for creating a valid // pixmap the size of the current Panner int Panner::updatePixmap(const BBox& bb) { // bb is in canvas coords // create a valid pixmap if needed if (!pixmap) { if (!(pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), options->width, options->height, depth))) { internalError("Panner: Unable to Create Pixmap"); return TCL_OK; } updateGCs(); } if (needsUpdate) { if (thumbnail) { XSetClipOrigin(display, gc, 0, 0); XCopyArea(display, thumbnail, pixmap, gc, 0, 0, options->width, options->height, 0, 0); if (useBBox) renderBBox(); if (useCompass) { renderImageCompass(); if (validWCSCompass) renderWCSCompass(); } } else clearPixmap(); needsUpdate = 0; } return TCL_OK; } void Panner::invalidPixmap() { Widget::invalidPixmap(); update(); } // Command Functions void Panner::getBBoxCmd() { Vector v = bbox[0]; for (int i=1; i<4; i++) v += bbox[i]; v /= 4; ostringstream str; str << v << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Panner::getSizeCmd() { ostringstream str; str << options->width << " " << options->height << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Panner::highLiteCmd(int which) { if (highLite != which) { highLite = !highLite; update(); } } void Panner::highLiteCmd(const Vector& v) { if (highLite != isInBBox(v)) { highLite = !highLite; update(); } } void Panner::panToCmd(const Vector& v) { for (int i=0; i<4; i++) bbox[i] = v; update(); } void Panner::panBeginCmd(const Vector& v) { if (useBBox && isInBBox(v)) { panStart = v; panning = 1; } } void Panner::panMotionCmd(const Vector& v) { if (panning && useBBox) { Vector diff = v - panStart; for (int i=0; i<4; i++) bbox[i] += diff; panStart = v; update(); } } void Panner::panEndCmd(const Vector& v) { if (panning && useBBox) { Vector diff = v - panStart; for (int i=0; i<4; i++) bbox[i] += diff; panning = 0; update(); } } void Panner::setCompassCmd(int w) { useCompass = w ? 1 : 0; update(); } void Panner::setBBoxCmd(int w) { useBBox = w ? 1 : 0; update(); } void Panner::updateCmd(void* p) { thumbnail = (Pixmap)p; update(); } void Panner::updateBBoxCmd(const Vector& ll, const Vector& lr, const Vector& ur, const Vector& ul) { bbox[0] = ll; bbox[1] = lr; bbox[2] = ur; bbox[3] = ul; update(); } void Panner::updateImageCompassCmd(Vector xx, Vector yy) { threed =0; imageX = xx; imageY = yy; update(); } void Panner::updateImageCompassCmd(Vector xx, Vector yy, Vector zz) { threed =1; imageX = xx; imageY = yy; imageZ = zz; update(); } void Panner::updateWCSCompassCmd() { validWCSCompass = 0; update(); } void Panner::updateWCSCompassCmd(const Vector& nn, const Vector& ee) { validWCSCompass = 1; wcsNorth = nn; wcsEast = ee; update(); } void Panner::warpCmd(const Vector& vv) { Vector v = vv; XWarpPointer(display, None, None, 0, 0, 0, 0, (int)v[0], (int)v[1]); } // Private Functions void Panner::updateGCs() { if (!bboxGC) { bboxGC = XCreateGC(display, pixmap, 0, NULL); XSetForeground(display, bboxGC, getColor("cyan")); } if (!tkfont_) { ostringstream fstr; fstr << '{' << options->helvetica << '}' << " 9 roman normal" << ends; tkfont_ = Tk_GetFont(interp, tkwin, fstr.str().c_str()); if (tkfont_) Tk_GetFontMetrics(tkfont_, &metric); } if (!compassGC) { compassGC = XCreateGC(display, pixmap, 0, NULL); XSetLineAttributes(display, compassGC, 1, LineSolid, CapButt, JoinMiter); if (tkfont_) XSetFont(display, compassGC, Tk_FontId(tkfont_)); } } void Panner::renderBBox() { XSetLineAttributes(display, bboxGC, (highLite ? 2 : 1), LineSolid, CapButt,JoinMiter); for (int i=0; i<3; i++) XDrawLine(display, pixmap, bboxGC, (int)(bbox[i])[0], (int)(bbox[i])[1], (int)(bbox[i+1])[0], (int)(bbox[i+1])[1]); XDrawLine(display, pixmap, bboxGC, (int)(bbox[3])[0], (int)(bbox[3])[1], (int)(bbox[0])[0], (int)(bbox[0])[1]); } void Panner::renderImageCompass() { float length = (options->width/2 + options->height/2)/2 * .4; Vector center(options->width/2., options->height/2.); renderArm(int(length*imageX.length()), center, Rotate(-imageX.angle()), "X", getColor("green")); renderArm(int(length*imageY.length()), center, Rotate(-imageY.angle()), "Y", getColor("green")); if (threed) { renderArm(int(length*imageZ.length()), center, Rotate(-imageZ.angle()), "Z", getColor("green")); } } void Panner::renderWCSCompass() { float length = (options->width/2 + options->height/2)/2 * .25; Vector center(options->width/2., options->height/2.); renderArm(int(length*wcsEast.length()), center, Rotate(-wcsEast.angle()), "E", getColor("yellow")); renderArm(int(length*wcsNorth.length()), center, Rotate(-wcsNorth.angle()), "N", getColor("yellow")); } void Panner::renderArm(int length, Vector center, Rotate rot, const char* str, int color) { if (length<=0) return; // set GC XSetForeground(display, compassGC, color); const int textOffset = 15; // Text offset const int tip = 6; // length from end of line to tip of arrow const int tail = 2; // length from end of line to tails of arrow const int wc = 2; // width of arrow at end of line const int wt = 3; // width of arrow at tails // Arrow-- oriented on Y axis Vector arrow[6]; arrow[0] = Vector(0, tip); arrow[1] = Vector(-wc, 0); arrow[2] = Vector(-wt, -tail); arrow[3] = Vector(0, 0); arrow[4] = Vector(wt, -tail); arrow[5] = Vector(wc, 0); // Staff-- oriented on X axis XPoint arrowArray[6]; Matrix arrowMatrix = Rotate(M_PI_2) * Translate(length,0) * rot * Translate(center); for (int i=0; i<6; i++) { Vector r = (arrow[i] * arrowMatrix).round(); arrowArray[i].x = (int)r[0]; arrowArray[i].y = (int)r[1]; } Vector c = ((Vector&)center).round(); Vector end = (Vector(length, 0) * rot * Translate(center)).round(); XDrawLine(display, pixmap, compassGC, (int)c[0], (int)c[1], (int)end[0], (int)end[1]); XFillPolygon(display, pixmap, compassGC, arrowArray, 6, Nonconvex, CoordModeOrigin); if (tkfont_) { Vector et = Vector((length + textOffset), 0) * rot * Translate(center) * Translate(-Tk_TextWidth(tkfont_, str, 1)/2., metric.ascent/2.); Tk_DrawChars(display, pixmap, compassGC, tkfont_, str, 1, (int)et[0], (int)et[1]); } } int Panner::isInBBox(const Vector& v) { /* v[0]-- x value of point being tested v[1]-- y value of point being tested This algorithm is from "An Introduction to Ray Tracing", Academic Press, 1989, edited by Andrew Glassner, pg 53 -- a point lies in a polygon if a line is extended from the point to infinite in any direction and the number of intersections with the polygon is odd. This is valid for both concave and convex polygons. Points on a vertex are considered inside. Points on a edge are considered inside. */ int crossings = 0; // number of crossings Vector v1; Vector v2 = bbox[0] - v; int sign = ((v2[1])>=0) ? 1 : -1; // init sign // for all edges for (int i=1; i<4; i++) { // look at next two vertices v1 = v2; v2 = bbox[i] - v; int nextSign = (v2[1]>=0) ? 1 : -1; // sign holder for p2 if (sign != nextSign) { if (v1[0]>0 && v2[0]>0) crossings++; else if (v1[0]>0 || v2[0]>0) { if (v1[0]-(v1[1]*(v2[0]-v1[0])/(v2[1]-v1[1])) > 0) crossings++; } sign = nextSign; } } return fmod(float(crossings),float(2)) ? 1 : 0; // if odd, point is inside } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/Makefile����������������������������������������������������������������������0000644�0001750�0001750�00000001303�11267434552�015155� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) \ -I. -I.. -I../widget -I../vector -I../util \ -I../../include -I$(X11INCLUDE) SS = \ panner.C \ pannerpseudo.C \ pannertrue.C SRC = $(SS) \ parser.C \ lex.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o $(LIB) parser.output ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif parsers : parser parser : FORCE bison -d -p pn -o parser.C parser.Y flex -Ppn -olex.C lex.L FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/lex.L�������������������������������������������������������������������������0000644�0001750�0001750�00000002743�11775376666�014452� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* pnlval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% bbox {return BBOX_;} begin {return BEGIN_;} clear {return CLEAR_;} compass {return COMPASS_;} debug {return DEBUG_;} end {return END_;} false {return FALSE_;} get {return GET_;} height {return HEIGHT_;} hide {return HIDE_;} highlite {return HIGHLITE_;} image {return IMAGE_;} invalid {return INVALID_;} motion {return MOTION_;} n {return N_;} no {return NO_;} off {return OFF_;} on {return ON_;} pan {return PAN_;} reset {return RESET_;} show {return SHOW_;} size {return SIZE_;} true {return TRUE_;} to {return TO_;} update {return UPDATE_;} version {return VERSION_;} warp {return WARP_;} wcs {return WCS_;} width {return WIDTH_;} y {return Y_;} yes {return YES_;} [+-]?{D}+ { // Integer pnlval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number pnlval->real = atof(yytext); return REAL; } 0[xX][0-9a-fA-F]+ { // Pointer pnlval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } [ \t]+ { // White Spaces } . { // Else, return the char return yytext[0]; } %% �����������������������������./saods9/saotk/panner/pannerpseudo.h����������������������������������������������������������������0000644�0001750�0001750�00000000611�11700666272�016370� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __pannerpseudo_h__ #define __pannerpseudo_h__ #include "panner.h" class PannerPseudoColor : public Panner { private: void clearPixmap(); public: PannerPseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif �����������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/parser.H����������������������������������������������������������������������0000644�0001750�0001750�00000006535�11775376666�015155� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, POINTER = 260, BBOX_ = 261, BEGIN_ = 262, CLEAR_ = 263, COMPASS_ = 264, DEBUG_ = 265, END_ = 266, FALSE_ = 267, GET_ = 268, HEIGHT_ = 269, HIDE_ = 270, HIGHLITE_ = 271, IMAGE_ = 272, INVALID_ = 273, MOTION_ = 274, N_ = 275, NO_ = 276, OFF_ = 277, ON_ = 278, PAN_ = 279, RESET_ = 280, SHOW_ = 281, SIZE_ = 282, TRUE_ = 283, TO_ = 284, UPDATE_ = 285, VERSION_ = 286, WARP_ = 287, WCS_ = 288, WIDTH_ = 289, Y_ = 290, YES_ = 291 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define POINTER 260 #define BBOX_ 261 #define BEGIN_ 262 #define CLEAR_ 263 #define COMPASS_ 264 #define DEBUG_ 265 #define END_ 266 #define FALSE_ 267 #define GET_ 268 #define HEIGHT_ 269 #define HIDE_ 270 #define HIGHLITE_ 271 #define IMAGE_ 272 #define INVALID_ 273 #define MOTION_ 274 #define N_ 275 #define NO_ 276 #define OFF_ 277 #define ON_ 278 #define PAN_ 279 #define RESET_ 280 #define SHOW_ 281 #define SIZE_ 282 #define TRUE_ 283 #define TO_ 284 #define UPDATE_ 285 #define VERSION_ 286 #define WARP_ 287 #define WCS_ 288 #define WIDTH_ 289 #define Y_ 290 #define YES_ 291 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 24 "parser.Y" { float real; int integer; void* ptr; char str[1024]; } /* Line 1529 of yacc.c. */ #line 128 "parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/parser.Y����������������������������������������������������������������������0000644�0001750�0001750�00000005755�12042571357�015157� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Panner* pn} %lex-param {pnFlexLexer* ll} %parse-param {pnFlexLexer* ll} %{ #define YYDEBUG 1 #include <stdlib.h> #include "panner.h" #undef yyFlexLexer #define yyFlexLexer pnFlexLexer #include <FlexLexer.h> extern int pnlex(void*, pnFlexLexer*); extern void pnerror(Panner*, pnFlexLexer*, const char*); %} %union { float real; int integer; void* ptr; char str[1024]; } %type <real> numeric %type <integer> yesno %token <integer> INT %token <real> REAL %token <ptr> POINTER %token BBOX_ %token BEGIN_ %token CLEAR_ %token COMPASS_ %token DEBUG_ %token END_ %token FALSE_ %token GET_ %token HEIGHT_ %token HIDE_ %token HIGHLITE_ %token IMAGE_ %token INVALID_ %token MOTION_ %token N_ %token NO_ %token OFF_ %token ON_ %token PAN_ %token RESET_ %token SHOW_ %token SIZE_ %token TRUE_ %token TO_ %token UPDATE_ %token VERSION_ %token WARP_ %token WCS_ %token WIDTH_ %token Y_ %token YES_ %% command : DEBUG_ debug | BBOX_ bbox | CLEAR_ {pn->updateCmd(0);} | COMPASS_ yesno {pn->setCompassCmd($2);} | IMAGE_ COMPASS_ yesno {pn->setCompassCmd($3);} | GET_ get | HIDE_ {pn->hideCmd();} | HIGHLITE_ highLite | PAN_ pan | RESET_ {pn->resetCmd();} | SHOW_ {pn->showCmd();} | UPDATE_ update | VERSION_ {pn->msg("Panner 1.0");} | WARP_ numeric numeric {pn->warpCmd(Vector($2, $3));} | WCS_ COMPASS_ yesno {pn->setCompassCmd($3);} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; yesno : INT {$$=($1 ? 1 : 0);} | YES_ {$$=1;} | Y_ {$$=1;} | ON_ {$$=1;} | TRUE_ {$$=1;} | NO_ {$$=0;} | N_ {$$=0;} | OFF_ {$$=0;} | FALSE_ {$$=0;} ; bbox : ON_ {pn->setBBoxCmd(1);} | OFF_ {pn->setBBoxCmd(0);} ; get : BBOX_ {pn->getBBoxCmd();} | HEIGHT_ {pn->getHeightCmd();} | SIZE_ {pn->getSizeCmd();} | WIDTH_ {pn->getWidthCmd();} ; highLite: numeric numeric {pn->highLiteCmd(Vector($1,$2));} | OFF_ {pn->highLiteCmd(0);} | ON_ {pn->highLiteCmd(1);} ; pan : BEGIN_ numeric numeric {pn->panBeginCmd(Vector($2,$3));} | MOTION_ numeric numeric {pn->panMotionCmd(Vector($2,$3));} | END_ numeric numeric {pn->panEndCmd(Vector($2,$3));} | TO_ numeric numeric {pn->panToCmd(Vector($2,$3));} ; update : POINTER {pn->updateCmd($1);} | BBOX_ numeric numeric numeric numeric numeric numeric numeric numeric {pn->updateBBoxCmd(Vector($2,$3),Vector($4,$5), Vector($6,$7),Vector($8,$9));} | IMAGE_ COMPASS_ updateImageCompass | WCS_ COMPASS_ updateWCSCompass ; updateImageCompass : numeric numeric numeric numeric {pn->updateImageCompassCmd(Vector($1,$2),Vector($3,$4));} | numeric numeric numeric numeric numeric numeric {pn->updateImageCompassCmd(Vector($1,$2), Vector($3,$4), Vector($5,$6));} ; updateWCSCompass : numeric numeric numeric numeric {pn->updateWCSCompassCmd(Vector($1,$2),Vector($3,$4));} | INVALID_ {pn->updateWCSCompassCmd();} ; %% �������������������./saods9/saotk/panner/parser.C����������������������������������������������������������������������0000644�0001750�0001750�00000147314�12042571357�015127� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse pnparse #define yylex pnlex #define yyerror pnerror #define yylval pnlval #define yychar pnchar #define yydebug pndebug #define yynerrs pnnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, POINTER = 260, BBOX_ = 261, BEGIN_ = 262, CLEAR_ = 263, COMPASS_ = 264, DEBUG_ = 265, END_ = 266, FALSE_ = 267, GET_ = 268, HEIGHT_ = 269, HIDE_ = 270, HIGHLITE_ = 271, IMAGE_ = 272, INVALID_ = 273, MOTION_ = 274, N_ = 275, NO_ = 276, OFF_ = 277, ON_ = 278, PAN_ = 279, RESET_ = 280, SHOW_ = 281, SIZE_ = 282, TRUE_ = 283, TO_ = 284, UPDATE_ = 285, VERSION_ = 286, WARP_ = 287, WCS_ = 288, WIDTH_ = 289, Y_ = 290, YES_ = 291 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define POINTER 260 #define BBOX_ 261 #define BEGIN_ 262 #define CLEAR_ 263 #define COMPASS_ 264 #define DEBUG_ 265 #define END_ 266 #define FALSE_ 267 #define GET_ 268 #define HEIGHT_ 269 #define HIDE_ 270 #define HIGHLITE_ 271 #define IMAGE_ 272 #define INVALID_ 273 #define MOTION_ 274 #define N_ 275 #define NO_ 276 #define OFF_ 277 #define ON_ 278 #define PAN_ 279 #define RESET_ 280 #define SHOW_ 281 #define SIZE_ 282 #define TRUE_ 283 #define TO_ 284 #define UPDATE_ 285 #define VERSION_ 286 #define WARP_ 287 #define WCS_ 288 #define WIDTH_ 289 #define Y_ 290 #define YES_ 291 /* Copy the first part of user declarations. */ #line 10 "parser.Y" #define YYDEBUG 1 #include <stdlib.h> #include "panner.h" #undef yyFlexLexer #define yyFlexLexer pnFlexLexer #include <FlexLexer.h> extern int pnlex(void*, pnFlexLexer*); extern void pnerror(Panner*, pnFlexLexer*, const char*); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 24 "parser.Y" { float real; int integer; void* ptr; char str[1024]; } /* Line 193 of yacc.c. */ #line 197 "parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 210 "parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 57 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 118 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 37 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 12 /* YYNRULES -- Number of rules. */ #define YYNRULES 50 /* YYNRULES -- Number of states. */ #define YYNSTATES 93 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 291 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 6, 9, 11, 14, 18, 21, 23, 26, 29, 31, 33, 36, 38, 42, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 87, 89, 91, 95, 99, 103, 107, 109, 119, 123, 127, 132, 139, 144 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 38, 0, -1, 10, 40, -1, 6, 42, -1, 8, -1, 9, 41, -1, 17, 9, 41, -1, 13, 43, -1, 15, -1, 16, 44, -1, 24, 45, -1, 25, -1, 26, -1, 30, 46, -1, 31, -1, 32, 39, 39, -1, 33, 9, 41, -1, 4, -1, 3, -1, 23, -1, 22, -1, 3, -1, 36, -1, 35, -1, 23, -1, 28, -1, 21, -1, 20, -1, 22, -1, 12, -1, 23, -1, 22, -1, 6, -1, 14, -1, 27, -1, 34, -1, 39, 39, -1, 22, -1, 23, -1, 7, 39, 39, -1, 19, 39, 39, -1, 11, 39, 39, -1, 29, 39, 39, -1, 5, -1, 6, 39, 39, 39, 39, 39, 39, 39, 39, -1, 17, 9, 47, -1, 33, 9, 48, -1, 39, 39, 39, 39, -1, 39, 39, 39, 39, 39, 39, -1, 39, 39, 39, 39, -1, 18, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 72, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 89, 90, 93, 94, 97, 99, 100, 101, 102, 104, 105, 106, 107, 110, 111, 114, 115, 116, 117, 120, 121, 122, 125, 126, 127, 128, 131, 132, 136, 137, 140, 142, 147, 149 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "POINTER", "BBOX_", "BEGIN_", "CLEAR_", "COMPASS_", "DEBUG_", "END_", "FALSE_", "GET_", "HEIGHT_", "HIDE_", "HIGHLITE_", "IMAGE_", "INVALID_", "MOTION_", "N_", "NO_", "OFF_", "ON_", "PAN_", "RESET_", "SHOW_", "SIZE_", "TRUE_", "TO_", "UPDATE_", "VERSION_", "WARP_", "WCS_", "WIDTH_", "Y_", "YES_", "$accept", "command", "numeric", "debug", "yesno", "bbox", "get", "highLite", "pan", "update", "updateImageCompass", "updateWCSCompass", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 48, 48 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 2, 1, 2, 3, 2, 1, 2, 2, 1, 1, 2, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 3, 3, 1, 9, 3, 3, 4, 6, 4, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 11, 12, 0, 14, 0, 0, 0, 31, 30, 3, 21, 29, 27, 26, 28, 24, 25, 23, 22, 5, 20, 19, 2, 32, 33, 34, 35, 7, 18, 17, 37, 38, 0, 9, 0, 0, 0, 0, 0, 10, 43, 0, 0, 0, 13, 0, 0, 1, 36, 6, 0, 0, 0, 0, 0, 0, 0, 15, 16, 39, 41, 40, 42, 0, 0, 45, 50, 0, 46, 0, 0, 0, 0, 0, 0, 0, 47, 49, 0, 0, 0, 48, 44 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 16, 42, 32, 29, 19, 37, 43, 49, 54, 75, 78 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -37 static const yytype_int8 yypact[] = { 85, -12, -37, 61, -7, -5, -37, 1, 17, 6, -37, -37, -3, -37, 15, 18, 12, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, 15, -37, 61, 15, 15, 15, 15, -37, -37, 15, 27, 29, -37, 15, 61, -37, -37, -37, 15, 15, 15, 15, 15, 15, 3, -37, -37, -37, -37, -37, -37, 15, 15, -37, -37, 15, -37, 15, 15, 15, 15, 15, 15, 15, 15, -37, 15, 15, 15, -37, -37 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -37, -37, -14, -37, -36, -37, -37, -37, -37, -37, -37, -37 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 55, 33, 50, 51, 38, 39, 38, 39, 59, 34, 17, 18, 57, 45, 52, 30, 31, 46, 38, 39, 68, 76, 35, 40, 41, 47, 44, 56, 58, 36, 53, 60, 61, 62, 63, 48, 65, 64, 66, 0, 0, 67, 0, 0, 0, 0, 69, 70, 71, 72, 73, 74, 77, 0, 0, 0, 0, 0, 0, 79, 80, 0, 0, 81, 20, 82, 83, 84, 85, 86, 87, 88, 89, 21, 90, 91, 92, 0, 0, 0, 0, 22, 23, 24, 25, 0, 0, 0, 0, 26, 0, 1, 0, 2, 3, 4, 27, 28, 5, 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 0, 0, 12, 13, 14, 15 }; static const yytype_int8 yycheck[] = { 14, 6, 5, 6, 3, 4, 3, 4, 44, 14, 22, 23, 0, 7, 17, 22, 23, 11, 3, 4, 56, 18, 27, 22, 23, 19, 9, 9, 42, 34, 33, 45, 46, 47, 48, 29, 9, 51, 9, -1, -1, 55, -1, -1, -1, -1, 60, 61, 62, 63, 64, 65, 66, -1, -1, -1, -1, -1, -1, 73, 74, -1, -1, 77, 3, 79, 80, 81, 82, 83, 84, 85, 86, 12, 88, 89, 90, -1, -1, -1, -1, 20, 21, 22, 23, -1, -1, -1, -1, 28, -1, 6, -1, 8, 9, 10, 35, 36, 13, -1, 15, 16, 17, -1, -1, -1, -1, -1, -1, 24, 25, 26, -1, -1, -1, 30, 31, 32, 33 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 6, 8, 9, 10, 13, 15, 16, 17, 24, 25, 26, 30, 31, 32, 33, 38, 22, 23, 42, 3, 12, 20, 21, 22, 23, 28, 35, 36, 41, 22, 23, 40, 6, 14, 27, 34, 43, 3, 4, 22, 23, 39, 44, 9, 7, 11, 19, 29, 45, 5, 6, 17, 33, 46, 39, 9, 0, 39, 41, 39, 39, 39, 39, 39, 9, 9, 39, 41, 39, 39, 39, 39, 39, 39, 47, 18, 39, 48, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (pn, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, pn, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Panner* pn, pnFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, pn, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Panner* pn; pnFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (pn); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Panner* pn, pnFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, pn, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Panner* pn; pnFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, pn, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Panner* pn, pnFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, pn, ll) YYSTYPE *yyvsp; int yyrule; Panner* pn; pnFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , pn, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, pn, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Panner* pn, pnFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, pn, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Panner* pn; pnFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (pn); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Panner* pn, pnFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Panner* pn, pnFlexLexer* ll) #else int yyparse (pn, ll) Panner* pn; pnFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 4: #line 74 "parser.Y" {pn->updateCmd(0);;} break; case 5: #line 75 "parser.Y" {pn->setCompassCmd((yyvsp[(2) - (2)].integer));;} break; case 6: #line 76 "parser.Y" {pn->setCompassCmd((yyvsp[(3) - (3)].integer));;} break; case 8: #line 78 "parser.Y" {pn->hideCmd();;} break; case 11: #line 81 "parser.Y" {pn->resetCmd();;} break; case 12: #line 82 "parser.Y" {pn->showCmd();;} break; case 14: #line 84 "parser.Y" {pn->msg("Panner 1.0");;} break; case 15: #line 85 "parser.Y" {pn->warpCmd(Vector((yyvsp[(2) - (3)].real), (yyvsp[(3) - (3)].real)));;} break; case 16: #line 86 "parser.Y" {pn->setCompassCmd((yyvsp[(3) - (3)].integer));;} break; case 17: #line 89 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 18: #line 90 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 19: #line 93 "parser.Y" {yydebug=1;;} break; case 20: #line 94 "parser.Y" {yydebug=0;;} break; case 21: #line 97 "parser.Y" {(yyval.integer)=((yyvsp[(1) - (1)].integer) ? 1 : 0);;} break; case 22: #line 99 "parser.Y" {(yyval.integer)=1;;} break; case 23: #line 100 "parser.Y" {(yyval.integer)=1;;} break; case 24: #line 101 "parser.Y" {(yyval.integer)=1;;} break; case 25: #line 102 "parser.Y" {(yyval.integer)=1;;} break; case 26: #line 104 "parser.Y" {(yyval.integer)=0;;} break; case 27: #line 105 "parser.Y" {(yyval.integer)=0;;} break; case 28: #line 106 "parser.Y" {(yyval.integer)=0;;} break; case 29: #line 107 "parser.Y" {(yyval.integer)=0;;} break; case 30: #line 110 "parser.Y" {pn->setBBoxCmd(1);;} break; case 31: #line 111 "parser.Y" {pn->setBBoxCmd(0);;} break; case 32: #line 114 "parser.Y" {pn->getBBoxCmd();;} break; case 33: #line 115 "parser.Y" {pn->getHeightCmd();;} break; case 34: #line 116 "parser.Y" {pn->getSizeCmd();;} break; case 35: #line 117 "parser.Y" {pn->getWidthCmd();;} break; case 36: #line 120 "parser.Y" {pn->highLiteCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 37: #line 121 "parser.Y" {pn->highLiteCmd(0);;} break; case 38: #line 122 "parser.Y" {pn->highLiteCmd(1);;} break; case 39: #line 125 "parser.Y" {pn->panBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 40: #line 126 "parser.Y" {pn->panMotionCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 41: #line 127 "parser.Y" {pn->panEndCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 42: #line 128 "parser.Y" {pn->panToCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 43: #line 131 "parser.Y" {pn->updateCmd((yyvsp[(1) - (1)].ptr));;} break; case 44: #line 134 "parser.Y" {pn->updateBBoxCmd(Vector((yyvsp[(2) - (9)].real),(yyvsp[(3) - (9)].real)),Vector((yyvsp[(4) - (9)].real),(yyvsp[(5) - (9)].real)), Vector((yyvsp[(6) - (9)].real),(yyvsp[(7) - (9)].real)),Vector((yyvsp[(8) - (9)].real),(yyvsp[(9) - (9)].real)));;} break; case 47: #line 141 "parser.Y" {pn->updateImageCompassCmd(Vector((yyvsp[(1) - (4)].real),(yyvsp[(2) - (4)].real)),Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 48: #line 143 "parser.Y" {pn->updateImageCompassCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)), Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)), Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 49: #line 148 "parser.Y" {pn->updateWCSCompassCmd(Vector((yyvsp[(1) - (4)].real),(yyvsp[(2) - (4)].real)),Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 50: #line 149 "parser.Y" {pn->updateWCSCompassCmd();;} break; /* Line 1267 of yacc.c. */ #line 1706 "parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (pn, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (pn, ll, yymsg); } else { yyerror (pn, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, pn, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, pn, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (pn, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, pn, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, pn, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 152 "parser.Y" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/pannerpseudo.C����������������������������������������������������������������0000644�0001750�0001750�00000007044�11700666272�016332� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "pannerpseudo.h" // Tk Canvas Widget Function Declarations int PannerPseudoColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // PannerPseudoColor Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec pannerPseudoColorSpecs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "panner", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType pannerPseudoColorType = { (char*)"pannerpseudocolor", // name sizeof(WidgetOptions), // size PannerPseudoColorCreateProc, // configProc pannerPseudoColorSpecs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int PannerPseudoColor_Init(Tcl_Interp* interp) { Tk_CreateItemType(&pannerPseudoColorType); return TCL_OK; } int PannerPseudoColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { PannerPseudoColor* panner = new PannerPseudoColor(interp, canvas, item); // and set default configuration if (panner->configure(argc, (const char**)argv, 0) != TCL_OK) { delete panner; Tcl_AppendResult(interp, " error occured while creating pannerPseudoColor.", NULL); return TCL_ERROR; } return TCL_OK; } PannerPseudoColor::PannerPseudoColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Panner(i, c, item) { configSpecs = pannerPseudoColorSpecs; // panner configure options } void PannerPseudoColor::clearPixmap() { XFillRectangle(display, pixmap, gc, 0, 0, options->width, options->height); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/panner.h����������������������������������������������������������������������0000644�0001750�0001750�00000004516�11775376666�015201� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __panner_h__ #define __panner_h__ #include "widget.h" class Panner : public Widget { private: Pixmap thumbnail; // current frame thumbnail pixmap int highLite; // flag to highlite bbox int panning; // flag for panning status Vector panStart; // initial location of panning operation int needsUpdate; // flag to indicate refresh needed GC bboxGC; // bbox gc int useBBox; // flag to use BBox Vector bbox[4]; // current view GC compassGC; // compass gc Vector imageX; Vector imageY; Vector imageZ; int threed; // 2d or 3d compass int useCompass; // flag to use image/wcs compass Vector wcsNorth; Vector wcsEast; int validWCSCompass; // flag to indicate wcs data is valid Tk_Font tkfont_; // Tk font Tk_FontMetrics metric; // Tk font metric private: void update(); // use existing pixmap, just update void invalidPixmap(); // new pixmap, then update protected: virtual void clearPixmap() =0; // clear pixmap private: int updatePixmap(const BBox&); // renders image/graphics into pixmap void renderBBox(); int isInBBox(const Vector&); void renderImageCompass(); void renderWCSCompass(); void renderArm(int, Vector, Rotate, const char*, int); void updateGCs(); public: Panner(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Panner(); int parse(istringstream&); // parse subcommands // SubCommandFunctions void getBBoxCmd(); void getSizeCmd(); void highLiteCmd(int); void highLiteCmd(const Vector&); void panToCmd(const Vector&); void panBeginCmd(const Vector&); void panMotionCmd(const Vector&); void panEndCmd(const Vector&); void setCompassCmd(int); void setBBoxCmd(int); void updateCmd(void*); void updateBBoxCmd(const Vector&, const Vector&, const Vector&, const Vector&); void updateImageCompassCmd(Vector, Vector); void updateImageCompassCmd(Vector, Vector, Vector); void updateWCSCompassCmd(); void updateWCSCompassCmd(const Vector&, const Vector&); void warpCmd(const Vector&); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/pannertrue.h������������������������������������������������������������������0000644�0001750�0001750�00000000601�11700666272�016047� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __pannertrue_h__ #define __pannertrue_h__ #include "panner.h" class PannerTrueColor : public Panner { private: void clearPixmap(); public: PannerTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif �������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/lex.C�������������������������������������������������������������������������0000644�0001750�0001750�00000140056�12032640000�014374� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lex.C" #line 4 "lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer pnFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *pnalloc (yy_size_t ); void *pnrealloc (void *,yy_size_t ); void pnfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 38 #define YY_END_OF_BUFFER 39 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[144] = { 0, 0, 0, 39, 37, 36, 38, 37, 37, 32, 32, 37, 37, 37, 37, 37, 37, 37, 37, 37, 15, 37, 37, 37, 37, 37, 37, 37, 37, 30, 36, 0, 32, 34, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 18, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 35, 0, 0, 0, 0, 0, 6, 0, 8, 0, 0, 0, 0, 0, 0, 17, 19, 0, 0, 0, 0, 0, 0, 0, 28, 0, 31, 0, 34, 1, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 27, 0, 2, 3, 0, 5, 7, 0, 0, 12, 0, 0, 20, 0, 0, 29, 0, 9, 0, 0, 14, 25, 0, 4, 0, 13, 26, 11, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 1, 17, 18, 19, 20, 21, 1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 1, 1, 1, 1, 1, 31, 32, 33, 34, 35, 36, 37, 38, 39, 1, 1, 40, 41, 42, 43, 44, 1, 45, 46, 47, 48, 49, 50, 51, 52, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[54] = { 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[145] = { 0, 0, 0, 300, 320, 297, 320, 49, 51, 54, 57, 56, 50, 59, 53, 65, 62, 63, 58, 58, 60, 68, 75, 72, 70, 91, 91, 102, 107, 104, 296, 112, 115, 118, 135, 122, 0, 111, 118, 121, 125, 135, 134, 131, 125, 135, 146, 144, 132, 135, 320, 148, 320, 143, 140, 144, 135, 320, 144, 162, 154, 155, 155, 168, 166, 187, 191, 197, 0, 162, 179, 197, 185, 182, 320, 185, 320, 195, 198, 196, 200, 207, 200, 320, 320, 205, 192, 208, 209, 214, 200, 203, 320, 201, 320, 220, 229, 320, 222, 227, 242, 237, 240, 238, 320, 237, 243, 239, 237, 234, 320, 320, 320, 235, 244, 320, 246, 320, 320, 239, 320, 320, 239, 249, 320, 250, 248, 320, 256, 249, 320, 247, 320, 247, 276, 320, 320, 276, 320, 284, 320, 320, 320, 320, 295 } ; static yyconst flex_int16_t yy_def[145] = { 0, 143, 1, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 0, 143 } ; static yyconst flex_int16_t yy_nxt[374] = { 0, 4, 5, 6, 7, 8, 9, 10, 4, 11, 12, 13, 14, 15, 16, 17, 18, 4, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 4, 29, 4, 4, 11, 12, 13, 14, 15, 16, 17, 18, 4, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 4, 29, 4, 31, 32, 32, 33, 33, 34, 32, 32, 34, 32, 32, 37, 35, 39, 38, 35, 40, 41, 42, 43, 44, 45, 47, 48, 49, 46, 50, 51, 36, 53, 54, 55, 56, 52, 37, 35, 39, 38, 35, 40, 41, 42, 43, 44, 45, 47, 48, 49, 46, 50, 51, 36, 53, 54, 55, 56, 52, 57, 59, 58, 60, 61, 64, 62, 33, 33, 34, 32, 32, 63, 33, 33, 66, 35, 67, 67, 65, 69, 70, 71, 57, 59, 58, 60, 61, 64, 62, 33, 33, 72, 73, 74, 63, 35, 75, 76, 35, 77, 80, 65, 69, 70, 71, 78, 81, 82, 79, 83, 84, 85, 86, 87, 72, 73, 74, 88, 35, 75, 76, 89, 77, 80, 90, 91, 92, 93, 78, 81, 82, 79, 83, 84, 85, 86, 87, 94, 97, 95, 88, 96, 96, 98, 89, 67, 67, 90, 91, 92, 93, 67, 67, 99, 100, 101, 102, 103, 104, 105, 94, 97, 106, 107, 108, 109, 98, 110, 111, 112, 113, 114, 115, 116, 96, 96, 99, 100, 101, 102, 103, 104, 105, 96, 96, 106, 107, 108, 109, 117, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 117, 133, 134, 135, 136, 137, 138, 139, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 140, 133, 134, 135, 136, 137, 138, 139, 141, 142, 68, 30, 30, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 140, 143, 143, 143, 143, 143, 143, 143, 141, 142, 3, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 } ; static yyconst flex_int16_t yy_chk[374] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 9, 12, 11, 10, 12, 13, 14, 15, 16, 17, 18, 18, 19, 17, 20, 21, 9, 22, 23, 24, 24, 21, 11, 9, 12, 11, 10, 12, 13, 14, 15, 16, 17, 18, 18, 19, 17, 20, 21, 9, 22, 23, 24, 24, 21, 25, 26, 25, 27, 28, 29, 28, 31, 31, 32, 32, 32, 28, 33, 33, 35, 32, 35, 35, 33, 37, 38, 39, 25, 26, 25, 27, 28, 29, 28, 34, 34, 40, 41, 42, 28, 34, 43, 44, 32, 45, 47, 33, 37, 38, 39, 46, 48, 49, 46, 51, 53, 54, 55, 56, 40, 41, 42, 58, 34, 43, 44, 59, 45, 47, 60, 61, 62, 63, 46, 48, 49, 46, 51, 53, 54, 55, 56, 64, 69, 65, 58, 65, 65, 70, 59, 66, 66, 60, 61, 62, 63, 67, 67, 71, 72, 73, 75, 77, 78, 79, 64, 69, 80, 81, 82, 85, 70, 86, 87, 88, 89, 90, 91, 93, 95, 95, 71, 72, 73, 75, 77, 78, 79, 96, 96, 80, 81, 82, 85, 98, 86, 87, 88, 89, 90, 91, 93, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109, 113, 114, 116, 119, 122, 98, 123, 125, 126, 128, 129, 131, 133, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109, 113, 114, 116, 119, 122, 134, 123, 125, 126, 128, 129, 131, 133, 137, 139, 144, 30, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 137, 139, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* pnlval; /* rules */ #line 550 "lex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 26 "lex.L" #line 653 "lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 144 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 143 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 28 "lex.L" {return BBOX_;} YY_BREAK case 2: YY_RULE_SETUP #line 29 "lex.L" {return BEGIN_;} YY_BREAK case 3: YY_RULE_SETUP #line 30 "lex.L" {return CLEAR_;} YY_BREAK case 4: YY_RULE_SETUP #line 31 "lex.L" {return COMPASS_;} YY_BREAK case 5: YY_RULE_SETUP #line 32 "lex.L" {return DEBUG_;} YY_BREAK case 6: YY_RULE_SETUP #line 33 "lex.L" {return END_;} YY_BREAK case 7: YY_RULE_SETUP #line 34 "lex.L" {return FALSE_;} YY_BREAK case 8: YY_RULE_SETUP #line 35 "lex.L" {return GET_;} YY_BREAK case 9: YY_RULE_SETUP #line 36 "lex.L" {return HEIGHT_;} YY_BREAK case 10: YY_RULE_SETUP #line 37 "lex.L" {return HIDE_;} YY_BREAK case 11: YY_RULE_SETUP #line 38 "lex.L" {return HIGHLITE_;} YY_BREAK case 12: YY_RULE_SETUP #line 39 "lex.L" {return IMAGE_;} YY_BREAK case 13: YY_RULE_SETUP #line 40 "lex.L" {return INVALID_;} YY_BREAK case 14: YY_RULE_SETUP #line 41 "lex.L" {return MOTION_;} YY_BREAK case 15: YY_RULE_SETUP #line 42 "lex.L" {return N_;} YY_BREAK case 16: YY_RULE_SETUP #line 43 "lex.L" {return NO_;} YY_BREAK case 17: YY_RULE_SETUP #line 44 "lex.L" {return OFF_;} YY_BREAK case 18: YY_RULE_SETUP #line 45 "lex.L" {return ON_;} YY_BREAK case 19: YY_RULE_SETUP #line 46 "lex.L" {return PAN_;} YY_BREAK case 20: YY_RULE_SETUP #line 47 "lex.L" {return RESET_;} YY_BREAK case 21: YY_RULE_SETUP #line 48 "lex.L" {return SHOW_;} YY_BREAK case 22: YY_RULE_SETUP #line 49 "lex.L" {return SIZE_;} YY_BREAK case 23: YY_RULE_SETUP #line 50 "lex.L" {return TRUE_;} YY_BREAK case 24: YY_RULE_SETUP #line 51 "lex.L" {return TO_;} YY_BREAK case 25: YY_RULE_SETUP #line 52 "lex.L" {return UPDATE_;} YY_BREAK case 26: YY_RULE_SETUP #line 53 "lex.L" {return VERSION_;} YY_BREAK case 27: YY_RULE_SETUP #line 54 "lex.L" {return WARP_;} YY_BREAK case 28: YY_RULE_SETUP #line 55 "lex.L" {return WCS_;} YY_BREAK case 29: YY_RULE_SETUP #line 56 "lex.L" {return WIDTH_;} YY_BREAK case 30: YY_RULE_SETUP #line 57 "lex.L" {return Y_;} YY_BREAK case 31: YY_RULE_SETUP #line 58 "lex.L" {return YES_;} YY_BREAK case 32: YY_RULE_SETUP #line 61 "lex.L" { // Integer pnlval->integer = atoi(yytext); return INT; } YY_BREAK case 33: #line 67 "lex.L" case 34: YY_RULE_SETUP #line 67 "lex.L" { // Real Number pnlval->real = atof(yytext); return REAL; } YY_BREAK case 35: YY_RULE_SETUP #line 72 "lex.L" { // Pointer pnlval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } YY_BREAK case 36: YY_RULE_SETUP #line 77 "lex.L" { // White Spaces } YY_BREAK case 37: YY_RULE_SETUP #line 80 "lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 38: YY_RULE_SETUP #line 84 "lex.L" ECHO; YY_BREAK #line 931 "lex.C" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; pnfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); pnfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ pnrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pnrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 144 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 144 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 143); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) pnalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) pnalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) pnfree((void *) b->yy_ch_buf ); pnfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)pnalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)pnrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) pnalloc(new_size ); else (yy_start_stack) = (int *) pnrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *pnalloc (yy_size_t size ) { return (void *) malloc( size ); } void *pnrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void pnfree (void * ptr ) { free( (char *) ptr ); /* see pnrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 84 "lex.L" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/panner/pannertrue.C������������������������������������������������������������������0000644�0001750�0001750�00000007614�11700666272�016015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "pannertrue.h" #include "util.h" // Tk Canvas Widget Function Declarations int PannerTrueColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // PannerTrueColor Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec pannerTrueColorSpecs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "panner", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType pannerTrueColorType = { (char*)"pannertruecolor", // name sizeof(WidgetOptions), // size PannerTrueColorCreateProc, // configProc pannerTrueColorSpecs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int PannerTrueColor_Init(Tcl_Interp* interp) { Tk_CreateItemType(&pannerTrueColorType); return TCL_OK; } int PannerTrueColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { PannerTrueColor* panner = new PannerTrueColor(interp, canvas, item); // and set default configuration if (panner->configure(argc, (const char**)argv, 0) != TCL_OK) { delete panner; Tcl_AppendResult(interp, " error occured while creating pannerTrueColor.", NULL); return TCL_ERROR; } return TCL_OK; } PannerTrueColor::PannerTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Panner(i, c, item) { configSpecs = pannerTrueColorSpecs; // panner configure options } void PannerTrueColor::clearPixmap() { XImage* xmap = XGetImage(display, pixmap, 0, 0, options->width, options->height, AllPlanes, ZPixmap); if (!xmap) { internalError("Panner: Unable to Create XImage"); return; } memset(XImageData(xmap), 255, xmap->bytes_per_line * xmap->height); XPutImage(display, pixmap, gc, xmap, 0, 0, 0, 0, options->width, options->height); XDestroyImage(xmap); } ��������������������������������������������������������������������������������������������������������������������./saods9/saotk/Makefile�����������������������������������������������������������������������������0000644�0001750�0001750�00000003075�10725335411�013672� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include include ../make.pkgs .NOTPARALLEL : #--------------------------defines CXXFLAGS = $(CXXOPT) -I../include -I$(X11INCLUDE) DIRS = widget frame colorbar panner magnifier vector list fitsy++ util OBJS = \ widget/*.o \ frame/*.o \ colorbar/*.o \ panner/*.o \ magnifier/*.o \ vector/*.o \ list/*.o \ fitsy++/*.o \ util/*.o LIB = libsaotk.a #--------------------------build all : $(LIB) install : all cp -f $(LIB) ../lib/. #--------------------------items $(LIB) : $(DIRS) $(RM) $@ $(AR) -cr $@ $(OBJS) frame : FORCE cd frame; $(MAKE) colorbar: FORCE cd colorbar; $(MAKE) panner : FORCE cd panner; $(MAKE) magnifier: FORCE cd magnifier; $(MAKE) widget : FORCE cd widget; $(MAKE) vector : FORCE cd vector; $(MAKE) list : FORCE cd list; $(MAKE) fitsy++ : FORCE cd fitsy++; $(MAKE) util : FORCE cd util; $(MAKE) clean : FORCE cd frame; $(MAKE) clean cd colorbar; $(MAKE) clean cd panner; $(MAKE) clean cd magnifier; $(MAKE) clean cd widget; $(MAKE) clean cd vector; $(MAKE) clean cd list; $(MAKE) clean cd fitsy++; $(MAKE) clean cd util; $(MAKE) clean distclean : FORCE rm -f *.o *.a *.so cd frame; $(MAKE) distclean cd colorbar; $(MAKE) distclean cd panner; $(MAKE) distclean cd magnifier; $(MAKE) distclean cd widget; $(MAKE) distclean cd vector; $(MAKE) distclean cd list; $(MAKE) distclean cd fitsy++; $(MAKE) distclean cd util; $(MAKE) distclean parsers : FORCE cd frame; $(MAKE) parsers cd colorbar; $(MAKE) parsers cd panner; $(MAKE) parsers cd magnifier; $(MAKE) parsers cd fitsy++; $(MAKE) parsers FORCE : �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057641�013510� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/Makefile����������������������������������������������������������������������0000644�0001750�0001750�00000001064�11435772356�015165� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) \ -I. -I.. -I../vector -I../util \ -I../../include -I$(X11INCLUDE) SRC = truecolor8.C \ truecolor16.C \ truecolor24.C \ widget.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o $(LIB) ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif FORCE: ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/widget.h����������������������������������������������������������������������0000644�0001750�0001750�00000014754�11772121574�015165� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __widget_h__ #define __widget_h__ #include <string.h> #include <stdlib.h> #include <limits.h> #include <float.h> #include <math.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <tcl.h> #include <tk.h> #include "vector.h" class Attribute; // in tkCanvasPs.c extern float psScale; // General Defines #define WIDGET(x) (*(((WidgetOptions*)(x))->widget)) // Widget ConfigSpecs Defines #define CONFIGX 1 #define CONFIGY 2 #define CONFIGWIDTH 3 #define CONFIGHEIGHT 4 #define CONFIGANCHOR 5 #define CONFIGCOMMAND 6 #define CONFIGHELVETICA 7 #define CONFIGCOURIER 8 #define CONFIGTIMES 9 // Tk Canvas Widget Function Declarations extern int WidgetConfigProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const [],int); extern int WidgetCoordProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); extern void WidgetDeleteProc(Tk_Canvas, Tk_Item*, Display*); extern void WidgetDisplayProc(Tk_Canvas, Tk_Item*, Display*, Drawable, int, int, int, int); extern double WidgetPointProc(Tk_Canvas, Tk_Item*, double*); extern int WidgetAreaProc(Tk_Canvas, Tk_Item*, double*); extern int WidgetPostscriptProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int); extern void WidgetScaleProc(Tk_Canvas, Tk_Item*, double, double, double, double); extern void WidgetTranslateProc(Tk_Canvas, Tk_Item*, double, double); extern int WidgetIndexProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, char, int*); extern void WidgetICursorProc(Tk_Canvas, Tk_Item*, int); extern int WidgetSelectionProc(Tk_Canvas, Tk_Item*, int, char*, int); extern void WidgetInsertProc(Tk_Canvas, Tk_Item*, int, char*); extern void WidgetDCharsProc(Tk_Canvas, Tk_Item*, int, int); extern int WidgetParse(ClientData, Tcl_Interp*, int, char**); class Widget; // this structure is returned by each Canvas Function Proc struct WidgetOptions { Tk_Item item; // required by tk int x, y; // Coordinates of positioning point on canvas int width; // widget width int height; // widget height Tk_Anchor anchor; // Where to anchor widget relative to x,y char* cmdName; // Suggested Tcl command name char* helvetica; // name of X11 font char* courier; // name of X11 font char* times; // name of X11 font Widget* widget; // pointer to widget class }; // Widget Class class Widget { friend class Attribute; public: enum PSColorSpace {BW, GRAY, RGB, CMYK}; Tcl_Interp* interp; // Tcl interp protected: WidgetOptions* options; // Pointer to Tk Options Tk_ConfigSpec* configSpecs; // configure specs Tk_Canvas canvas; // handle to canvas Tk_Window tkwin; // Tk window id Display* display; // display of canvas Visual* visual; // visual of canvas int depth; // depth of canvas int screenNumber; // screen number of canvas Pixmap pixmap; // size of canvas item GC gc; // gc for pixmap XCopyArea int visible; // redraw when true int originX; // widget upper left origin int originY; // widget upper left origin char* cmd; // actual command name used int result; // result of TCL command int psResolution; // postscript resolution int psLevel; // postscript level PSColorSpace psColorSpace; // postscript color space protected: virtual int updatePixmap(const BBox&) =0; // render into pixmap virtual void invalidPixmap(); // pixmap is invalid virtual void reset() {}; // reset widget void createCommand(); // create tcl command void updateBBox(); // update item bounding box int checkArgs(int, int, char**); // check args utility void psHead1(int, int); void psHead2(int, int, const char*, const char*); Vector psOrigin(); void psFix(ostringstream& ostr); public: Widget(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Widget(); Tcl_Interp* getInterp() {return interp;} void redraw(); // ping tk to redraw this widget void redraw(BBox); // ping tk to redraw this bbox void redrawNow(); // force update now this widget void redrawNow(BBox); // force update now this bbox void forceUpdate(); // only force update virtual int parse(istringstream&) =0; // parse subcommands virtual int configure(int, const char**, int); // parse config options void error(const char*); // parse error function void msg(const char*); // parse msg function Tk_Window getTkwin() {return tkwin;} Display* getDisplay() {return display;} double getDisplayRatio(); Visual* getVisual() {return visual;} int getWidth() {return options->width;} int getHeight() {return options->height;} int getDepth() {return depth;} int getScreenNumber() {return screenNumber;} Tk_Canvas getCanvas() {return canvas;} int getColor(const char* str); XColor* getXColor(const char*); // Required Canvas Functions int coordProc(int, char**); void displayProc(Drawable, int, int, int, int); double pointProc(double*); int areaProc(double*); virtual int postscriptProc(int); void scaleProc(double, double, double, double); void translateProc(double, double); virtual int indexProc(char indexString, int* indexPtr) {return TCL_OK;} virtual void icursorProc(int index) {} virtual int selectionProc(int offset, char* buffer, int maxBytes) {return maxBytes;} virtual void insertProc(int index, char* string) {} virtual void dcharsProc(int first, int last) {} // Subcommand Functions int configCmd(int, const char**); // configure command void getHeightCmd(); // return height of widget void getWidthCmd(); // return width of widget void hideCmd(); // hide item command void resetCmd(); // reset item command void showCmd(); // show item command // Postscript Commands void psLevelCmd(int l) {psLevel = l;} void psResolutionCmd(int r) {psResolution = r;} void psColorSpaceCmd(PSColorSpace c) {psColorSpace = c;} void psScaleCmd(float s) {psScale = s;} #ifdef _MACOSX virtual void macsosxPrintCmd() {} #endif }; #endif ��������������������./saods9/saotk/widget/truecolor16.h�����������������������������������������������������������������0000644�0001750�0001750�00000001441�11700666272�016054� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __truecolor16_h__ #define __truecolor16_h__ #include <string.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <tk.h> class TrueColor16 { protected: unsigned long rx_; unsigned long gx_; unsigned long bx_; unsigned short rm_; unsigned short gm_; unsigned short bm_; int rs_; int gs_; int bs_; private: unsigned short decodeMask(unsigned short, int*); protected: void decodeTrueColor(char*, XColor*, XImage*); void encodeTrueColor(XColor*, char*, XImage*); void encodeTrueColor(unsigned char*, XImage*); public: TrueColor16(Visual*); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/truecolor8.C������������������������������������������������������������������0000644�0001750�0001750�00000004021�11700666272�015725� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "truecolor8.h" #include "util.h" #ifdef _MACOSX extern void macosxGetMasks(unsigned long*, unsigned long*, unsigned long*, unsigned long*); #endif TrueColor8::TrueColor8(Visual* visual) { #if !(_WIN32 || _MACOSX) rx_ = visual->red_mask; gx_ = visual->green_mask; bx_ = visual->blue_mask; #endif #if _MACOSX // tk visual masks are bogus unsigned long red_mask, green_mask, blue_mask, alpha_mask; macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask); rx_ = red_mask; gx_ = green_mask; bx_ = blue_mask; #endif #if _WIN32 // windows masks are plain wrong rx_ = 0xE0; gx_ = 0x18; bx_ = 0x07; #endif rm_ = decodeMask((unsigned char)rx_, &rs_); gm_ = decodeMask((unsigned char)rx_, &gs_); bm_ = decodeMask((unsigned char)rx_, &bs_); } unsigned char TrueColor8::decodeMask(unsigned char mask, int* s) { *s=0; for (int i=0; i<8; i++, (*s)++) { if (mask & 0x80) break; mask <<= 1; } return mask; } void TrueColor8::encodeTrueColor(XColor* src, char* dest, XImage* ximage) { *dest = ((((unsigned char)src->blue) & bm_) >> bs_) | ((((unsigned char)src->green) & gm_) >> gs_) | ((((unsigned char)src->red) & rm_) >> rs_); } void TrueColor8::decodeTrueColor(char* src, XColor* dest, XImage* ximage) { dest->red = (unsigned short)((*src & rx_) >> rs_); dest->green = (unsigned short)((*src & gx_) >> gs_); dest->blue = (unsigned short)((*src & bx_) >> bs_); } void TrueColor8::encodeTrueColor(unsigned char* src, XImage* ximage) { int& width = ximage->width; int& height = ximage->height; char* data = XImageData(ximage); const unsigned char* ptr = src; for (int j=0; j<height; j++) { char* dest = data + j*ximage->bytes_per_line; for (int i=0; i<width; i++, dest++, ptr+=3) *dest = ((ptr[0] & rm_) >> rs_) | ((ptr[1] & gm_) >> gs_) | ((ptr[2] & bm_) >> bs_); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/truecolor24.C�����������������������������������������������������������������0000644�0001750�0001750�00000014743�11700666272�016017� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "truecolor24.h" #include "util.h" #ifdef _MACOSX extern void macosxGetMasks(unsigned long*, unsigned long*, unsigned long*, unsigned long*); #endif TrueColor24::TrueColor24(Visual* visual) { #if !(_WIN32 || _MACOSX) rx_ = visual->red_mask; gx_ = visual->green_mask; bx_ = visual->blue_mask; ax_ = 0; #endif #if _MACOSX // tk visual masks are bogus unsigned long red_mask, green_mask, blue_mask, alpha_mask; macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask); rx_ = red_mask; gx_ = green_mask; bx_ = blue_mask; ax_ = alpha_mask; #endif #if _WIN32 // windows masks are plain wrong rx_ = 0x00FF0000; gx_ = 0x0000FF00; bx_ = 0x000000FF; ax_ = 0; #endif rs_ = decodeMask((unsigned long)rx_); gs_ = decodeMask((unsigned long)gx_); bs_ = decodeMask((unsigned long)bx_); as_ = decodeMask((unsigned long)ax_); } int TrueColor24::decodeMask(unsigned long mask) { switch (mask) { case 0: return 0; case 0xff: return 0; case 0xff00: return 8; case 0xff0000: return 16; case 0xff000000: return 24; } } void TrueColor24::encodeTrueColor(XColor* src, char* dest, XImage* ximage) { if (!ximage) return; switch (ximage->bits_per_pixel) { case 24: encodeTrueColor24(src, dest, ximage); break; case 32: encodeTrueColor32(src, dest, ximage); break; } } void TrueColor24::decodeTrueColor(char* src, XColor* dest, XImage* ximage) { if (!ximage) return; switch (ximage->bits_per_pixel) { case 24: decodeTrueColor24(src, dest, ximage); break; case 32: decodeTrueColor32(src, dest, ximage); break; } } void TrueColor24::encodeTrueColor24(XColor* src, char* dest, XImage* ximage) { int msb = ximage->byte_order; unsigned int r = (unsigned char)src->red; unsigned int g = (unsigned char)src->green; unsigned int b = (unsigned char)src->blue; unsigned int v = 0; v |= r << rs_; v |= g << gs_; v |= b << bs_; if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 3); else { unsigned char* rr = (unsigned char*)(&v); *(dest+0) = *(rr+3); *(dest+1) = *(rr+2); *(dest+2) = *(rr+1); } } void TrueColor24::decodeTrueColor24(char* src, XColor* dest, XImage* ximage) { int msb = ximage->byte_order; unsigned int v = 0; if ((!msb && lsb()) || (msb && !lsb())) memcpy(&v, src, 3); else { unsigned char* rr = (unsigned char*)(&v); *(rr+3) = *(src+0); *(rr+2) = *(src+1); *(rr+1) = *(src+2); } dest->red = (unsigned short)((v & rx_) >> rs_); dest->green = (unsigned short)((v & gx_) >> gs_); dest->blue = (unsigned short)((v & bx_) >> bs_); } void TrueColor24::encodeTrueColor32(XColor* src, char* dest, XImage* ximage) { int msb = ximage->byte_order; unsigned int r = (unsigned char)src->red; unsigned int g = (unsigned char)src->green; unsigned int b = (unsigned char)src->blue; unsigned int v = 0; v |= r << rs_; v |= g << gs_; v |= b << bs_; if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 4); else { unsigned char* rr = (unsigned char*)(&v); *(dest+0) = *(rr+3); *(dest+1) = *(rr+2); *(dest+2) = *(rr+1); *(dest+3) = *(rr+0); } } void TrueColor24::decodeTrueColor32(char* src, XColor* dest, XImage* ximage) { int msb = ximage->byte_order; unsigned int v = 0; if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 4); else { unsigned char* rr = (unsigned char*)(&v); *(rr+3) = *(src); *(rr+2) = *(src+1); *(rr+1) = *(src+2); *(rr+0) = *(src+3); } dest->red = (unsigned short)((v & rx_) >> rs_); dest->green = (unsigned short)((v & gx_) >> gs_); dest->blue = (unsigned short)((v & bx_) >> bs_); } void TrueColor24::encodeTrueColor(unsigned char* src, XImage* ximage) { if (!ximage) return; switch (ximage->bits_per_pixel) { case 24: encodeTrueColor24(src, ximage); break; case 32: encodeTrueColor32(src, ximage); break; } } void TrueColor24::encodeTrueColor24(unsigned char* src, XImage* ximage) { int& width = ximage->width; int& height = ximage->height; char* data = XImageData(ximage); int bytesPerPixel = ximage->bits_per_pixel/8; int msb = ximage->byte_order; const unsigned char* ptr = src; if ((!msb && lsb()) || (msb && !lsb())) { for (int jj=0; jj<height; jj++) { char* dest = data + jj*ximage->bytes_per_line; for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { unsigned int r = ptr[0]; unsigned int g = ptr[1]; unsigned int b = ptr[2]; unsigned int v = 0; v |= r << rs_; v |= g << gs_; v |= b << bs_; memcpy(dest, &v, 3); } } } else { for (int jj=0; jj<height; jj++) { char* dest = data + jj*ximage->bytes_per_line; for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { unsigned int r = ptr[0]; unsigned int g = ptr[1]; unsigned int b = ptr[2]; unsigned int v = 0; v |= r << rs_; v |= g << gs_; v |= b << bs_; unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+3); *(dest+1) = *(rr+2); *(dest+2) = *(rr+1); } } } } void TrueColor24::encodeTrueColor32(unsigned char* src, XImage* ximage) { int& width = ximage->width; int& height = ximage->height; char* data = XImageData(ximage); int bytesPerPixel = ximage->bits_per_pixel/8; int msb = ximage->byte_order; const unsigned char* ptr = src; if ((!msb && lsb()) || (msb && !lsb())) { for (int jj=0; jj<height; jj++) { // the line may be padded at the end char* dest = data + jj*ximage->bytes_per_line; for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { unsigned int r = ptr[0]; unsigned int g = ptr[1]; unsigned int b = ptr[2]; unsigned int v = 0; #ifdef _MACOSX unsigned int a = 0xff; v |= a << as_; #endif v |= r << rs_; v |= g << gs_; v |= b << bs_; memcpy(dest, &v, 4); } } } else { for (int jj=0; jj<height; jj++) { // the line may be padded at the end char* dest = data + jj*ximage->bytes_per_line; for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { unsigned int r = ptr[0]; unsigned int g = ptr[1]; unsigned int b = ptr[2]; unsigned int v = 0; #ifdef _MACOSX unsigned int a = 0xff; v |= a << as_; #endif v |= r << rs_; v |= g << gs_; v |= b << bs_; unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+3); *(dest+1) = *(rr+2); *(dest+2) = *(rr+1); *(dest+3) = *(rr); } } } } �����������������������������./saods9/saotk/widget/truecolor24.h�����������������������������������������������������������������0000644�0001750�0001750�00000002037�11700666272�016055� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __truecolor24_h__ #define __truecolor24_h__ #include <string.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <tk.h> class TrueColor24 { protected: unsigned long rx_; unsigned long gx_; unsigned long bx_; unsigned long ax_; int rs_; int gs_; int bs_; int as_; private: int decodeMask(unsigned long); void decodeTrueColor24(char*, XColor*, XImage*); void decodeTrueColor32(char*, XColor*, XImage*); void encodeTrueColor24(XColor*, char*, XImage*); void encodeTrueColor24(unsigned char*, XImage*); void encodeTrueColor32(XColor*, char*, XImage*); void encodeTrueColor32(unsigned char*, XImage*); protected: void decodeTrueColor(char*, XColor*, XImage*); void encodeTrueColor(XColor*, char*, XImage*); void encodeTrueColor(unsigned char*, XImage*); public: TrueColor24(Visual*); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/widget.C����������������������������������������������������������������������0000644�0001750�0001750�00000043375�11712062042�015105� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "widget.h" #include "util.h" // Tk Canvas Widget Functions Declaration int WidgetConfigProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[], int flags) { return WIDGET(item).configure(argc, (const char**)argv, flags); } int WidgetCoordProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { return WIDGET(item).coordProc(argc, (char**)argv); } void WidgetDeleteProc(Tk_Canvas canvas, Tk_Item* item, Display* display) { delete ((WidgetOptions*)item)->widget; } void WidgetDisplayProc(Tk_Canvas canvas, Tk_Item* item, Display* display, Drawable draw, int x, int y, int width, int height) { WIDGET(item).displayProc(draw, x, y, width, height); } double WidgetPointProc(Tk_Canvas canvas, Tk_Item* item, double* point) { return WIDGET(item).pointProc(point); } int WidgetAreaProc(Tk_Canvas canvas, Tk_Item* item, double* bbox) { return WIDGET(item).areaProc(bbox); } int WidgetPostscriptProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int prepass) { return WIDGET(item).postscriptProc(prepass); } void WidgetScaleProc(Tk_Canvas canvas, Tk_Item* item, double Ox, double Oy , double Sx, double Sy) { WIDGET(item).scaleProc(Ox, Oy, Sx, Sy); } void WidgetTranslateProc(Tk_Canvas canvas, Tk_Item* item, double x, double y) { WIDGET(item).translateProc(x, y); } int WidgetIndexProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, char indexString, int* indexPtr) { WIDGET(item).indexProc(indexString, indexPtr); return 1; } void WidgetICursorProc(Tk_Canvas canvas, Tk_Item* item, int index) { WIDGET(item).icursorProc(index); } int WidgetSelectionProc(Tk_Canvas canvas, Tk_Item* item, int offset, char* buffer, int maxBytes) { WIDGET(item).selectionProc(offset, buffer, maxBytes); return 1; } void WidgetInsertProc(Tk_Canvas canvas, Tk_Item* item, int index, char* string) { WIDGET(item).insertProc(index, string); } void WidgetDCharsProc(Tk_Canvas canvas, Tk_Item* item, int first, int last) { WIDGET(item).dcharsProc(first, last); } int WidgetParse(ClientData widget, Tcl_Interp* interp, int argc, const char** argv) { int result; Tcl_Preserve(widget); if (argc >= 2 && !strncmp(argv[1],"config",6)) result = ((Widget*)widget)->configCmd(argc-2, argv+2); else { istringstream istr(ios::in|ios::out); ostream ostr(istr.rdbuf()); for (int i=1; i<argc; i++) ostr << argv[i] << " "; ostr << ends; result = ((Widget*)widget)->parse(istr); } Tcl_Release(widget); return result; } // Member Functions Widget::Widget(Tcl_Interp* interp_, Tk_Canvas canvas_, Tk_Item* item) : interp(interp_), canvas(canvas_) { // initialize item ptr to this. This is the method the canvas widget procs // know how to call member functions. ((WidgetOptions*)item)->widget = this; // init members options = (WidgetOptions*)item; configSpecs = NULL; tkwin = Tk_CanvasTkwin(canvas); display = Tk_Display(tkwin); screenNumber = Tk_ScreenNumber(tkwin); visual = Tk_Visual(tkwin); depth = Tk_Depth(tkwin); pixmap = 0; visible = True; originX = 0; originY = 0; // this is needed because of a problem with Tk_ConfigureWidget options->cmdName = NULL; options->helvetica = NULL; options->courier = NULL; options->times = NULL; cmd = NULL; result = TCL_OK; // create GC for pixmap XGCValues values; gc = Tk_GetGC(tkwin, 0, &values); // postscript psLevel = 2; psResolution = 300; psColorSpace = RGB; } Widget::~Widget() { // free the options Tk_FreeOptions(configSpecs, (char*)this->options, display, 0); // clean up tcl command if (cmd) { Tcl_DeleteCommand(interp, cmd); delete [] cmd; } // clean up pixmap resources if (pixmap) Tk_FreePixmap(display, pixmap); if (gc) Tk_FreeGC(display, gc); } void Widget::error(const char* m) { Tcl_AppendResult(interp, m, NULL); result = TCL_ERROR; } void Widget::msg(const char* m) { Tcl_AppendResult(interp, m, NULL); } int Widget::configure(int argc, const char** argv, int flags) { if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, (char*)this->options, flags) != TCL_OK) return TCL_ERROR; if (flags != TK_CONFIG_ARGV_ONLY) { // create command createCommand(); updateBBox(); invalidPixmap(); } else { // configure command if (configSpecs[CONFIGCOMMAND].specFlags & TK_CONFIG_OPTION_SPECIFIED) createCommand(); if ((configSpecs[CONFIGX].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGY].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGANCHOR].specFlags & TK_CONFIG_OPTION_SPECIFIED)) updateBBox(); if ((configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED)) invalidPixmap(); if ((configSpecs[CONFIGX].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGY].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGANCHOR].specFlags & TK_CONFIG_OPTION_SPECIFIED)) redraw(); } return TCL_OK; } // Required Canvas Functions int Widget::coordProc(int argc, char** argv) { char xStr[TCL_DOUBLE_SPACE], yStr[TCL_DOUBLE_SPACE]; switch (argc) { // print the current values case 0: Tcl_PrintDouble(interp, options->x, xStr); Tcl_PrintDouble(interp, options->y, yStr); Tcl_AppendResult(interp, xStr, " ", yStr, NULL); return TCL_OK; // set current x&y to new values case 2: { double x0, y0; if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &x0) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &y0) != TCL_OK)) return TCL_ERROR; options->x = (int)x0; options->y = (int)y0; updateBBox(); return TCL_OK; } // else, error message default: Tcl_AppendResult(interp, "wrong # coordinates: expected 0 or 2", NULL); return TCL_ERROR; } } // Widget Display Procedure. It takes the contents of the pixmap and // after clipping, copies it into the drawable. void Widget::displayProc(Drawable draw, int clipX, int clipY, int clipWidth, int clipHeight) { if (visible == False) return; // create bbox BBox bb(clipX, clipY, clipX+clipWidth, clipY+clipHeight); // update the pixmap from ximage/graphics if (updatePixmap(bb) != TCL_OK) return; // something is wrong, bail out // define pixmap clip region // NOTE: it appears that the canvas coord system is 1 to n, width/height = n // with the original of value 1,1 located at upper left corner int pmX, pmY, pmWidth, pmHeight; if (clipX > options->item.x1) { pmX = clipX - options->item.x1; pmWidth = options->item.x2 - clipX; } else { pmX = 0; if ((clipX + clipWidth) < options->item.x2) pmWidth = clipX + clipWidth - options->item.x1; else pmWidth = options->item.x2 - options->item.x1; } if (clipY > options->item.y1) { pmY = clipY - options->item.y1; pmHeight = options->item.y2 - clipY; } else { pmY = 0; if ((clipY + clipHeight) < options->item.y2) pmHeight = clipY + clipHeight - options->item.y1; else pmHeight = options->item.y2 - options->item.y1; } // convert to canvas coords short drawX, drawY; Tk_CanvasDrawableCoords(canvas, (double)(options->item.x1 + pmX), (double)(options->item.y1 + pmY), &drawX, &drawY); // set the clip region and copy the pixmap into the drawable XSetClipOrigin(display, gc, drawX - pmX, drawY - pmY); XCopyArea(display, pixmap, draw, gc, pmX, pmY, (unsigned int) pmWidth, (unsigned int) pmHeight, drawX, drawY); } double Widget::pointProc(double* point) { double xdiff, ydiff; if (point[0] < options->item.x1) xdiff = options->item.x1 - point[0]; else if (point[0] > options->item.x2) xdiff = point[0] - options->item.x2; else xdiff = 0; if (point[1] < options->item.y1) ydiff = options->item.y1 - point[1]; else if (point[1] > options->item.y2) ydiff = point[1] - options->item.y2; else ydiff = 0; return hypot(xdiff, ydiff); } int Widget::areaProc(double* bbox) { if ((bbox[2] <= options->item.x1) || (bbox[0] >= options->item.x2) || (bbox[3] <= options->item.y1) || (bbox[1] >= options->item.y2)) return -1; // item is outside bbox if ((bbox[0] <= options->item.x1) && (bbox[1] <= options->item.y1) && (bbox[2] >= options->item.x2) && (bbox[3] >= options->item.y2)) return 1; // item is inside bbox return 0; // item overlaps bbox } int Widget::postscriptProc(int prepass) { return TCL_OK; } void Widget::scaleProc(double Ox, double Oy, double Sx, double Sy) { // translate to (Ox,Oy), scale by (Sx,Sy), translate back from (Ox,Oy) options->x = (int)(Ox + (Sx * (options->x - Ox))); options->y = (int)(Oy + (Sy * (options->y - Oy))); options->width = (int)(options->width * Sx); options->height = (int)(options->height * Sy); updateBBox(); invalidPixmap(); // width and height have changed } void Widget::translateProc(double deltaX, double deltaY) { options->x += (int)deltaX; options->y += (int)deltaY; updateBBox(); } // Subcommand Functions int Widget::configCmd(int argc, const char** argv) { switch (argc) { case 0: return Tk_ConfigureInfo(interp, tkwin, configSpecs, (char*)this->options, NULL, 0); case 1: return Tk_ConfigureInfo(interp, tkwin, configSpecs, (char*)this->options, argv[0],0); default: return configure(argc, argv, TK_CONFIG_ARGV_ONLY); } } void Widget::getHeightCmd() { ostringstream str; str << options->height << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Widget::getWidthCmd() { ostringstream str; str << options->width << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Widget::hideCmd() { visible = False; redraw(); } void Widget::resetCmd() { reset(); invalidPixmap(); redraw(); } void Widget::showCmd() { visible = True; redraw(); } // Private Member Functions void Widget::createCommand() { if (cmd) { Tcl_DeleteCommand(interp, cmd); if (cmd) delete [] cmd; } cmd = new char[strlen(options->cmdName)+1]; strcpy(cmd, options->cmdName); Tcl_CreateCommand(interp, cmd, WidgetParse, (ClientData)this, NULL); } int Widget::checkArgs(int should, int argc, char** argv) { // if should is negative, don't check if (should >= 0) { if (should != argc) { ostringstream str; str << should << '\0'; Tcl_AppendResult(interp, "wrong # args: requires ", str.str().c_str(), " args.", NULL); return TCL_ERROR; } else return TCL_OK; } return TCL_OK; } double Widget::getDisplayRatio() { return 25.4/72 * DisplayWidth(display, screenNumber) / DisplayWidthMM(display, screenNumber); } void Widget::invalidPixmap() { if (pixmap) Tk_FreePixmap(display, pixmap); pixmap = 0; } void Widget::redraw() { Tk_CanvasEventuallyRedraw(canvas, options->item.x1, options->item.y1, options->item.x2, options->item.y2); } void Widget::redraw(BBox bb) { // bb in canvas coords // we need to expand by 1, i don't know why Tk_CanvasEventuallyRedraw(canvas, (int)bb.ll[0], (int)bb.ll[1], (int)bb.ur[0]+1, (int)bb.ur[1]+1); } void Widget::redrawNow() { Tk_CanvasEventuallyRedraw(canvas, options->item.x1, options->item.y1, options->item.x2, options->item.y2); Tcl_DoOneEvent(TCL_IDLE_EVENTS); } void Widget::redrawNow(BBox bb) { // bb in canvas coords // we need to expand by 1, i don't know why Tk_CanvasEventuallyRedraw(canvas, (int)bb.ll[0], (int)bb.ll[1], (int)bb.ur[0]+1, (int)bb.ur[1]+1); Tcl_DoOneEvent(TCL_IDLE_EVENTS); } void Widget::forceUpdate() { Tcl_DoOneEvent(TCL_IDLE_EVENTS); } // Update Bounding Box. For image at (n,n) with size (m,m), // bbox is defined from (n,n) to (n+m,n+m) void Widget::updateBBox() { originX = options->x; originY = options->y; int& ww = options->width; int& hh = options->height; // Modify position point using anchor information. switch (options->anchor) { case TK_ANCHOR_N: originX -= ww/2; break; case TK_ANCHOR_NE: originX -= ww; break; case TK_ANCHOR_E: originX -= ww; originY -= hh/2; break; case TK_ANCHOR_SE: originX -= ww; originY -= hh; break; case TK_ANCHOR_S: originX -= ww/2; originY -= hh; break; case TK_ANCHOR_SW: originY -= hh; break; case TK_ANCHOR_W: originY -= hh/2; break; case TK_ANCHOR_NW: break; case TK_ANCHOR_CENTER: originX -= ww/2; originY -= hh/2; break; } // Update item item options->item.x1 = originX; options->item.y1 = originY; options->item.x2 = originX + options->width; options->item.y2 = originY + options->height; } int Widget::getColor(const char* str) { XColor* cc = Tk_GetColor(interp, tkwin, str); return cc ? cc->pixel : 0; } XColor* Widget::getXColor(const char* str) { // note: Tk_GetColor can return an XColor without valid red,green,blue // if common colorname is used. (uses XAllocNamedColor). // force an hash string instead (uses XAllocColor). XColor* cc=NULL; if (!strncmp(str,"white",5)) cc = Tk_GetColor(interp, tkwin, "#ffffff"); else if (!strncmp(str,"black",5)) cc = Tk_GetColor(interp, tkwin, "#000000"); else if (!strncmp(str,"red",3)) cc = Tk_GetColor(interp, tkwin, "#ff0000"); else if (!strncmp(str,"green",5)) cc = Tk_GetColor(interp, tkwin, "#00ff00"); else if (!strncmp(str,"blue",4)) cc = Tk_GetColor(interp, tkwin, "#0000ff"); else if (!strncmp(str,"cyan",4)) cc = Tk_GetColor(interp, tkwin, "#00ffff"); else if (!strncmp(str,"magenta",7)) cc = Tk_GetColor(interp, tkwin, "#ff00ff"); else if (!strncmp(str,"yellow",6)) cc = Tk_GetColor(interp, tkwin, "#ffff00"); else cc = Tk_GetColor(interp, tkwin, str); return cc ? cc : Tk_GetColor(interp, tkwin, "white"); } void Widget::psHead1(int width, int height) { ostringstream str; switch (psColorSpace) { case BW: case GRAY: str << "/picstr " << dec << width << " string def" << endl << width << ' ' << height << " 8 matrix" << endl << "{currentfile picstr readhexstring pop}" << endl << "image" << endl; break; case RGB: case CMYK: str << "/picstr " << dec << width*3 << " string def" << endl << width << ' ' << height << " 8 matrix" << endl << "{currentfile picstr readhexstring pop}" << endl << "false 3 colorimage" << endl; break; } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Widget::psHead2(int width, int height, const char* compress, const char* decode) { ostringstream str; switch (psColorSpace) { case BW: case GRAY: str << "/DeviceGray setcolorspace" << endl; break; case RGB: str << "/DeviceRGB setcolorspace" << endl; break; case CMYK: str << "/DeviceCMYK setcolorspace" << endl; break; } str << "<<" << endl << "/ImageType 1" << endl << "/Width " << dec << width << endl << "/Height " << dec << height << endl << "/BitsPerComponent 8" << endl; switch (psColorSpace) { case BW: case GRAY: str << "/Decode [0 1]" << endl; break; case RGB: str << "/Decode [0 1 0 1 0 1]" << endl; break; case CMYK: str << "/Decode [0 1 0 1 0 1 0 1]" << endl; break; } // << "/ASCIIHexDecode filter" << endl // << "/ASCII85Decode filter" << endl // << "/RunLengthDecode filter" << endl // << "/FlateDecode filter" << endl str << "/ImageMatrix matrix" << endl << "/DataSource currentfile" << endl; if (decode) str << "/" << decode << "Decode filter" << endl; if (compress) str << "/" << compress << "Decode filter" << endl; str << ">>" << endl << "image" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } // compute coordinates of lower-left corner of the image // taking into account the anchor position for the image. // this mapping is different than in widget.c, due to postscript origin // (y is flipped) Vector Widget::psOrigin() { double xx = options->x; double yy = Tk_CanvasPsY(canvas, options->y); double ww = options->width; double hh = options->height; switch (options->anchor) { case TK_ANCHOR_N: xx -= ww/2; yy -= hh; break; case TK_ANCHOR_NE: xx -= ww; yy -= hh; break; case TK_ANCHOR_E: xx -= ww; yy -= hh/2; break; case TK_ANCHOR_SE: xx -= ww; break; case TK_ANCHOR_S: xx -= ww/2; break; case TK_ANCHOR_SW: break; case TK_ANCHOR_W: yy -= hh/2; break; case TK_ANCHOR_NW: yy -= hh; break; case TK_ANCHOR_CENTER: xx -= ww/2; yy -= hh/2; break; } return Vector(xx,yy); } // this routine attemps a work around for a problems with level 2 postscript // and other software such as dvips and assemble void Widget::psFix(ostringstream& ostr) { string str = ostr.str(); const char* buf = str.c_str(); int size = str.length(); char* a = (char*)buf; while (*a && a<buf+size) { // dvips version 5.55. Basically, we can't have %% at the start of a line if (*a=='\n' && *(a+1)=='%' && *(a+2)=='%') { // reverse the order so that we don't have a %% at the begining of a line *a++ = '%'; *a++ = '%'; *a++ = '\n'; } // assemble. Basically, we can't have % at the start of a line else if (*a=='\n' && *(a+1)=='%') { // reverse the order so that we don't have a % at the begining of a line *a++ = '%'; *a++ = '\n'; } a++; } ostr.str(str); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/truecolor8.h������������������������������������������������������������������0000644�0001750�0001750�00000001430�11700666272�015773� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __truecolor8_h__ #define __truecolor8_h__ #include <string.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <tk.h> class TrueColor8 { protected: unsigned long rx_; unsigned long gx_; unsigned long bx_; unsigned char rm_; unsigned char gm_; unsigned char bm_; int rs_; int gs_; int bs_; private: unsigned char decodeMask(unsigned char, int*); protected: void decodeTrueColor(char*, XColor*, XImage*); void encodeTrueColor(XColor*, char*, XImage*); void encodeTrueColor(unsigned char*, XImage*); public: TrueColor8(Visual*); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/widget/truecolor16.C�����������������������������������������������������������������0000644�0001750�0001750�00000007573�11700666272�016023� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "truecolor16.h" #include "util.h" #ifdef _MACOSX extern void macosxGetMasks(unsigned long*, unsigned long*, unsigned long*, unsigned long*); #endif TrueColor16::TrueColor16(Visual* visual) { #if !(_WIN32 || _MACOSX) rx_ = visual->red_mask; gx_ = visual->green_mask; bx_ = visual->blue_mask; #endif #if _MACOSX // tk visual masks are bogus unsigned long red_mask, green_mask, blue_mask, alpha_mask; macosxGetMasks(&red_mask, &green_mask, &blue_mask, &alpha_mask); rx_ = red_mask; gx_ = green_mask; bx_ = blue_mask; #endif #if _WIN32 // windows masks are plain wrong rx_ = 0x7C00; gx_ = 0x03E0; bx_ = 0x001F; #endif rm_ = decodeMask((unsigned short)rx_, &rs_); gm_ = decodeMask((unsigned short)gx_, &gs_); bm_ = decodeMask((unsigned short)bx_, &bs_); } unsigned short TrueColor16::decodeMask(unsigned short mask, int* s) { // first calc ffs for mask unsigned short m1 = mask; int m1s; for (m1s=0; m1s<16; m1s++) { if (m1 & 0x1) break; m1 >>= 1; } // then shift mask to mask a char for (int i=0; i<16; i++) { if (mask & 0x8000) break; mask <<= 1; } mask >>= 8; // now calc ffs for new mask unsigned short m2 = mask; int m2s; for (m2s=0; m2s<16; m2s++) { if (m2 & 0x1) break; m2 >>= 1; } *s = m1s-m2s; return mask; } void TrueColor16::encodeTrueColor(XColor* src, char* dest, XImage* ximage) { if (!ximage) return; int msb = ximage->byte_order; unsigned short r = (unsigned char)src->red; unsigned short g = (unsigned char)src->green; unsigned short b = (unsigned char)src->blue; unsigned short v = 0; v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 2); else { unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+1); *(dest+1) = *(rr); } } void TrueColor16::decodeTrueColor(char* src, XColor* dest, XImage* ximage) { if (!ximage) return; int msb = ximage->byte_order; unsigned short v = 0; if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 2); else { unsigned char* rr = (unsigned char*)(&v); *(rr+1) = *(src+0); *(rr+0) = *(src+1); } dest->red = (unsigned short)((v & rx_) >> rs_); dest->green = (unsigned short)((v & gx_) >> gs_); dest->blue = (unsigned short)((v & bx_) >> bs_); } void TrueColor16::encodeTrueColor(unsigned char* src, XImage* ximage) { int& width = ximage->width; int& height = ximage->height; char* data = XImageData(ximage); int msb = ximage->byte_order; const unsigned char* ptr = src; if ((!msb && lsb()) || (msb && !lsb())) { for (int jj=0; jj<height; jj++) { char* dest = data + jj*ximage->bytes_per_line; // may be padded at the end for (int ii=0; ii<width; ii++, dest+=2, ptr+=3) { unsigned short r = ptr[0]; unsigned short g = ptr[1]; unsigned short b = ptr[2]; unsigned short v = 0; v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); memcpy(dest, &v, 2); } } } else { for (int jj=0; jj<height; jj++) { char* dest = data + jj*ximage->bytes_per_line; for (int ii=0; ii<width; ii++, dest+=2, ptr+=3) { unsigned short r = ptr[0]; unsigned short g = ptr[1]; unsigned short b = ptr[2]; unsigned short v = 0; v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+1); *(dest+1) = *(rr); } } } } �������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013303� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitscompress.C�����������������������������������������������������������������0000644�0001750�0001750�00000006724�12106546556�016166� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" #include "rice.h" #include "gzip.h" #include "gzraw.h" #include "hcompress.h" #include "plio.h" void FitsImage::initCompress() { int bitpix = fits_->getInteger("ZBITPIX",0); char* type = fits_->getString("ZCMPTYPE"); if (!bitpix || !type) { if (type) delete [] type; return ; } if (compress_) delete compress_; compress_ = NULL; FitsHead* srcHead = fits_->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); FitsColumn* gzip = srcHDU->find("GZIP_COMPRESSED_DATA"); // if GZIP_COMPRESS_DATA found, must be floating point, force gzraw if (gzip && (bitpix==-32 || bitpix==-64)) memcpy(type,"GZRAW",5); if (!strncmp(type,"RICE",4)) switch (bitpix) { case 8: compress_ = new FitsRicem<unsigned char>(fits_); break; case 16: compress_ = new FitsRicem<short>(fits_); break; case -16: compress_ = new FitsRicem<unsigned short>(fits_); break; case 32: compress_ = new FitsRicem<int>(fits_); break; case 64: compress_ = new FitsRicem<long long>(fits_); break; case -32: compress_ = new FitsRicem<float>(fits_); break; case -64: compress_ = new FitsRicem<double>(fits_); break; } else if (!strncmp(type,"GZIP",4)) switch (bitpix) { case 8: compress_ = new FitsGzipm<unsigned char>(fits_); break; case 16: compress_ = new FitsGzipm<short>(fits_); break; case -16: compress_ = new FitsGzipm<unsigned short>(fits_); break; case 32: compress_ = new FitsGzipm<int>(fits_); break; case 64: compress_ = new FitsGzipm<long long>(fits_); break; case -32: compress_ = new FitsGzipm<float>(fits_); break; case -64: compress_ = new FitsGzipm<double>(fits_); break; } else if (!strncmp(type,"PLIO",4)) switch (bitpix) { case 8: compress_ = new FitsPliom<unsigned char>(fits_); break; case 16: compress_ = new FitsPliom<short>(fits_); break; case -16: compress_ = new FitsPliom<unsigned short>(fits_); break; case 32: compress_ = new FitsPliom<int>(fits_); break; case 64: compress_ = new FitsPliom<long long>(fits_); break; case -32: compress_ = new FitsPliom<float>(fits_); break; case -64: compress_ = new FitsPliom<double>(fits_); break; } else if (!strncmp(type,"HCOMPRESS",4)) switch (bitpix) { case 8: compress_ = new FitsHcompressm<unsigned char>(fits_); break; case 16: compress_ = new FitsHcompressm<short>(fits_); break; case -16: compress_ = new FitsHcompressm<unsigned short>(fits_); break; case 32: compress_ = new FitsHcompressm<int>(fits_); break; case 64: compress_ = new FitsHcompressm<long long>(fits_); break; case -32: compress_ = new FitsHcompressm<float>(fits_); break; case -64: compress_ = new FitsHcompressm<double>(fits_); break; } else if (!strncmp(type,"GZRAW",5)) switch (bitpix) { case -32: compress_ = new FitsGzrawm<float>(fits_); break; case -64: compress_ = new FitsGzrawm<double>(fits_); break; } if (type) delete [] type; return; } ��������������������������������������������./saods9/saotk/frame/fitsimage.C��������������������������������������������������������������������0000644�0001750�0001750�00000236525�12132022364�015402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" #include "framebase.h" #include "mmap.h" #include "smmap.h" #include "mmapincr.h" #include "alloc.h" #include "allocgz.h" #include "channel.h" #include "share.h" #include "sshare.h" #include "socket.h" #include "socketgz.h" #include "var.h" #include "iis.h" #include "hist.h" #include "compress.h" #include "analysis.h" #include "photo.h" #define MAXPV 99 #define MAXCO 13 // this is kluge to speed up doug minks wcssubs 'ksearch' routine extern "C" { FitsHead* wcshead = NULL; FitsHead* wcsprim = NULL; char* ksearchh(char*, char*); char* findit(char* cards, char* key) { char* rr = NULL; if (wcshead) { if (rr = wcshead->find(key)) return rr; if (wcsprim) if (rr = wcsprim->find(key)) return rr; return NULL; } else return ksearchh(cards, key); } }; FitsImage::FitsImage(Base* p) { parent = p; objectName = NULL; rootBaseFileName = NULL; fullBaseFileName = NULL; rootFileName = NULL; fullFileName = NULL; rootFileName3d = NULL; fullFileName3d = NULL; iisFileName = NULL; fits_ = NULL; compress_ = NULL; hist_ = NULL; hpx_ = NULL; base_ = NULL; basedata_ = NULL; smooth_ = NULL; smoothdata_ = NULL; image_ = NULL; data_ = NULL; nextMosaic_ = NULL; nextSlice_ = NULL; for (int ii=0; ii<FTY_MAXAXES ; ii++) naxis_[ii] = 0; bitpix_ = 0; doSmooth_ = 0; smoothFunction_ = GAUSSIAN; smoothRadius_ = 3; binFunction_ = FitsHist::SUM; binFactor_ = Vector(1,1); binBufferSize_ = 1024; binDepth_ = 1; binSliceFilter =NULL; keyLTMV = 0; keyATMV = 0; keyDTMV = 0; keyDATASEC = 0; imageToData = Translate(-.5, -.5); dataToImage = Translate( .5, .5); imageToData3d = Translate3d(-.5, -.5, -.5); dataToImage3d = Translate3d( .5, .5, .5); wcs =NULL; wcsHeader =NULL; ast =NULL; iisMode = 0; iiszt = 0; mparams =NULL; for (int ii=0; ii<FTY_MAXAXES; ii++) address[ii] =1; } FitsImage::~FitsImage() { if (objectName) delete [] objectName; if (rootBaseFileName) delete [] rootBaseFileName; if (fullBaseFileName) delete [] fullBaseFileName; if (rootFileName) delete [] rootFileName; if (fullFileName) delete [] fullFileName; if (rootFileName3d) delete [] rootFileName3d; if (fullFileName3d) delete [] fullFileName3d; if (iisFileName) delete [] iisFileName; if (fits_) delete fits_; if (compress_) delete compress_; if (hist_) delete hist_; if (hpx_) delete hpx_; if (basedata_) delete basedata_; if (smooth_) delete smooth_; if (smoothdata_) delete smoothdata_; if (wcs) { for (int ii=0; ii<MULTWCS; ii++) if (wcs[ii]) wcsfree(wcs[ii]); delete [] wcs; } if (ast) { // we have a problem with windows being too slow // look at it later # ifndef _WIN32 for (int ii=0; ii<MULTWCS; ii++) if (ast[ii]) astAnnul(ast[ii]); #endif delete [] ast; } if (wcsHeader) delete wcsHeader; } // Fits FitsImageFitsAlloc::FitsImageFitsAlloc(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsFitsAlloc(ch, FitsFile::RELAX, flush); process(fn,id); } FitsImageFitsAllocGZ::FitsImageFitsAllocGZ(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsFitsAllocGZ(ch, FitsFile::RELAX, flush); process(fn,id); } FitsImageFitsChannel::FitsImageFitsChannel(Base* p, Tcl_Interp* interp, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsFitsChannel(interp, ch, fn, FitsFile::RELAX, flush); process(fn,id); } FitsImageFitsMMap::FitsImageFitsMMap(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsFitsMMap(fn, FitsFile::RELAX); process(fn,id); } FitsImageFitsSMMap::FitsImageFitsSMMap(Base* p, const char* hdr, const char* fn, int id) : FitsImage(p) { fits_ = new FitsFitsSMMap(hdr, fn); process(fn,id); } FitsImageFitsMMapIncr::FitsImageFitsMMapIncr(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsFitsMMapIncr(fn, FitsFile::RELAX); process(fn,id); } FitsImageFitsShare::FitsImageFitsShare(Base* p, Base::ShmType type, int sid, const char* fn, int id) : FitsImage(p) { switch (type) { case Base::SHMID: fits_ = new FitsFitsShareID(sid, fn, FitsFile::RELAX); break; case Base::KEY: fits_ = new FitsFitsShareKey(sid, fn, FitsFile::RELAX); break; } process(fn,id); } FitsImageFitsSShare::FitsImageFitsSShare(Base* p, Base::ShmType type, int hdr, int sid, const char* fn, int id) : FitsImage(p) { switch (type) { case Base::SHMID: fits_ = new FitsFitsSShareID(hdr, sid, fn); break; case Base::KEY: fits_ = new FitsFitsSShareKey(hdr, sid, fn); break; } process(fn,id); } FitsImageFitsSocket::FitsImageFitsSocket(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsFitsSocket(s, fn, FitsFile::RELAX, flush); process(fn,id); } FitsImageFitsSocketGZ::FitsImageFitsSocketGZ(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsFitsSocketGZ(s, fn, FitsFile::RELAX, flush); process(fn,id); } FitsImageFitsVar::FitsImageFitsVar(Base* p, Tcl_Interp* interp, const char* var, const char* fn, int id) : FitsImage(p) { fits_ = new FitsFitsVar(interp, var, fn, FitsFile::RELAX); process(fn,id); } // Fits Next FitsImageFitsNextAlloc::FitsImageFitsNextAlloc(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextAlloc(prev); process(fn,id); } FitsImageFitsNextAllocGZ::FitsImageFitsNextAllocGZ(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextAllocGZ(prev); process(fn,id); } FitsImageFitsNextChannel::FitsImageFitsNextChannel(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextChannel(prev); process(fn,id); } FitsImageFitsNextMMap::FitsImageFitsNextMMap(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextMMap(prev); process(fn,id); } FitsImageFitsNextSMMap::FitsImageFitsNextSMMap(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextSMMap(prev); process(fn,id); } FitsImageFitsNextMMapIncr::FitsImageFitsNextMMapIncr(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextMMapIncr(prev); process(fn,id); } FitsImageFitsNextShare::FitsImageFitsNextShare(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextShare(prev); process(fn,id); } FitsImageFitsNextSShare::FitsImageFitsNextSShare(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextSShare(prev); process(fn,id); } FitsImageFitsNextSocket::FitsImageFitsNextSocket(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextSocket(prev); process(fn,id); } FitsImageFitsNextSocketGZ::FitsImageFitsNextSocketGZ(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextSocketGZ(prev); process(fn,id); } FitsImageFitsNextVar::FitsImageFitsNextVar(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsFitsNextVar(prev); process(fn,id); } FitsImageFitsNextHist::FitsImageFitsNextHist(Base* p, FitsImage* fi, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsHistNext(prev); process(NULL,id); fits_->setpFilter(fi->getHistFilter()); rootBaseFileName = dupstr(fi->getRootBaseFileName()); fullBaseFileName = dupstr(fi->getFullBaseFileName()); iisFileName = dupstr(fi->getFullBaseFileName()); } FitsImageFitsNextCompress::FitsImageFitsNextCompress(Base* p, FitsImage* fi, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsCompressNext(prev); process(NULL,id); rootBaseFileName = dupstr(fi->getRootBaseFileName()); fullBaseFileName = dupstr(fi->getFullBaseFileName()); iisFileName = dupstr(fi->getFullBaseFileName()); } // Array FitsImageArrAlloc::FitsImageArrAlloc(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsArrAlloc(ch, flush); process(fn,id); } FitsImageArrAllocGZ::FitsImageArrAllocGZ(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsArrAllocGZ(ch, flush); process(fn,id); } FitsImageArrChannel::FitsImageArrChannel(Base* p, Tcl_Interp* interp, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsArrChannel(interp, ch, fn, flush); process(fn,id); } FitsImageArrMMap::FitsImageArrMMap(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsArrMMap(fn); process(fn,id); } FitsImageArrMMapIncr::FitsImageArrMMapIncr(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsArrMMapIncr(fn); process(fn,id); } FitsImageArrShare::FitsImageArrShare(Base* p, Base::ShmType type, int sid, const char* fn, int id) : FitsImage(p) { switch (type) { case Base::SHMID: fits_ = new FitsArrShareID(sid, fn); break; case Base::KEY: fits_ = new FitsArrShareKey(sid, fn); break; } process(fn,id); } FitsImageArrSocket::FitsImageArrSocket(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsArrSocket(s, fn, flush); process(fn,id); } FitsImageArrSocketGZ::FitsImageArrSocketGZ(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsArrSocketGZ(s, fn, flush); process(fn,id); } FitsImageArrVar::FitsImageArrVar(Base* p, Tcl_Interp* interp, const char* var, const char* fn, int id) : FitsImage(p) { fits_ = new FitsArrVar(interp, var, fn); process(fn,id); } // NRRD FitsImageNRRDAlloc::FitsImageNRRDAlloc(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsNRRDAlloc(ch, flush); process(fn,id); } FitsImageNRRDChannel::FitsImageNRRDChannel(Base* p, Tcl_Interp* interp, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsNRRDChannel(interp, ch, fn, flush); process(fn,id); } FitsImageNRRDMMap::FitsImageNRRDMMap(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsNRRDMMap(fn); process(fn,id); } FitsImageNRRDShare::FitsImageNRRDShare(Base* p, Base::ShmType type, int sid, const char* fn, int id) : FitsImage(p) { switch (type) { case Base::SHMID: fits_ = new FitsNRRDShareID(sid, fn); break; case Base::KEY: fits_ = new FitsNRRDShareKey(sid, fn); break; } process(fn,id); } FitsImageNRRDSocket::FitsImageNRRDSocket(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsNRRDSocket(s, fn, flush); process(fn,id); } FitsImageNRRDVar::FitsImageNRRDVar(Base* p, Tcl_Interp* interp, const char* var, const char* fn, int id) : FitsImage(p) { fits_ = new FitsNRRDVar(interp, var, fn); process(fn,id); } // Photo FitsImagePhoto::FitsImagePhoto(Base* p, Tcl_Interp* interp, const char* ph, const char* fn, int id) : FitsImage(p) { fits_ = new FitsPhoto(interp, ph); process(fn,id); } FitsImagePhotoCube::FitsImagePhotoCube(Base* p, Tcl_Interp* interp, const char* ph, const char* fn, int id) : FitsImage(p) { fits_ = new FitsPhotoCube(interp, ph); process(fn,id); } FitsImagePhotoCubeNext::FitsImagePhotoCubeNext(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsPhotoCubeNext(prev); process(fn,id); } // Mosaic FitsImageMosaicAlloc::FitsImageMosaicAlloc(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicAlloc(ch, flush); process(fn,id); } FitsImageMosaicAllocGZ::FitsImageMosaicAllocGZ(Base* p, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicAllocGZ(ch, flush); process(fn,id); } FitsImageMosaicChannel::FitsImageMosaicChannel(Base* p, Tcl_Interp* interp, const char* ch, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicChannel(interp, ch, flush); process(fn,id); } FitsImageMosaicMMap::FitsImageMosaicMMap(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsMosaicMMap(fn); process(fn,id); } FitsImageMosaicMMapIncr::FitsImageMosaicMMapIncr(Base* p, const char* fn, int id) : FitsImage(p) { fits_ = new FitsMosaicMMapIncr(fn); process(fn,id); } FitsImageMosaicShare::FitsImageMosaicShare(Base* p, Base::ShmType type, int sid, const char* fn, int id) : FitsImage(p) { switch (type) { case Base::SHMID: fits_ = new FitsMosaicShareID(sid); break; case Base::KEY: fits_ = new FitsMosaicShareKey(sid); break; } process(fn,id); } FitsImageMosaicSocket::FitsImageMosaicSocket(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicSocket(s, flush); process(fn,id); } FitsImageMosaicSocketGZ::FitsImageMosaicSocketGZ(Base* p, int s, const char* fn, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicSocketGZ(s, flush); process(fn,id); } FitsImageMosaicVar::FitsImageMosaicVar(Base* p, Tcl_Interp* interp, const char* var, const char* fn, int id) : FitsImage(p) { fits_ = new FitsMosaicVar(interp, var, fn); process(fn,id); } // Mosaic Next FitsImageMosaicNextAlloc::FitsImageMosaicNextAlloc(Base* p, const char* fn, FitsFile* prev, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicNextAlloc(prev, flush); process(fn,id); } FitsImageMosaicNextAllocGZ::FitsImageMosaicNextAllocGZ(Base* p, const char* fn, FitsFile* prev, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicNextAllocGZ(prev, flush); process(fn,id); } FitsImageMosaicNextChannel::FitsImageMosaicNextChannel(Base* p, const char* fn, FitsFile* prev, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicNextChannel(prev, flush); process(fn,id); } FitsImageMosaicNextMMap::FitsImageMosaicNextMMap(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsMosaicNextMMap(prev); process(fn,id); } FitsImageMosaicNextMMapIncr::FitsImageMosaicNextMMapIncr(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsMosaicNextMMapIncr(prev); process(fn,id); } FitsImageMosaicNextShare::FitsImageMosaicNextShare(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsMosaicNextShare(prev); process(fn,id); } FitsImageMosaicNextSocket::FitsImageMosaicNextSocket(Base* p, const char* fn, FitsFile* prev, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicNextSocket(prev, flush); process(fn,id); } FitsImageMosaicNextSocketGZ::FitsImageMosaicNextSocketGZ(Base* p, const char* fn, FitsFile* prev, FitsFile::FlushMode flush, int id) : FitsImage(p) { fits_ = new FitsMosaicNextSocketGZ(prev, flush); process(fn,id); } FitsImageMosaicNextVar::FitsImageMosaicNextVar(Base* p, const char* fn, FitsFile* prev, int id) : FitsImage(p) { fits_ = new FitsMosaicNextVar(prev); process(fn,id); } // IIS FitsImageIIS::FitsImageIIS(Base* p, int w, int h) : FitsImage(p) { fits_ = new FitsIIS(w, h); process("",1); iisMode = 1; } void FitsImageIIS::iisErase() { ((FitsIIS*)fits_)->erase(); } char* FitsImageIIS::iisGet(int xx, int yy, int dx, int dy) { return ((FitsIIS*)fits_)->get(xx, yy, dx, dy); } void FitsImageIIS::iisSet(const char* src, int xx, int yy, int dx, int dy) { ((FitsIIS*)fits_)->set(src, xx, yy, dx, dy); } void FitsImageIIS::iisWCS(const Matrix& mx, const Vector& z, int zt) { iisz = z; iiszt = zt; } // FitsImage void FitsImage::analysis() { image_ = base_; data_ = basedata_; FitsHead* head = image_->head(); for (int ii=0; ii<FTY_MAXAXES; ii++) naxis_[ii] = head->naxis(ii); bitpix_ = head->bitpix(); if (smooth_) delete smooth_; smooth_ = NULL; if (smoothdata_) delete smoothdata_; smoothdata_ = NULL; if (parent->doSmooth_) { smooth_ = new FitsAnalysis(image_); if (smooth_->isValid()) { smoothdata_ = new FitsDatam<double>(smooth_, parent); if (smooth()) { image_ = smooth_; data_ = smoothdata_; FitsHead* head = image_->head(); for (int ii=0; ii<FTY_MAXAXES; ii++) naxis_[ii] = head->naxis(ii); bitpix_ = head->bitpix(); } else { delete smooth_; smooth_ = NULL; delete smoothdata_; smoothdata_ = NULL; } } else { delete smooth_; smooth_ = NULL; } } } void FitsImage::appendWCS(FitsHead* hh) { // process OBJECT keyword char* obj = hh->getString("OBJECT"); if (obj) { if (objectName) delete [] objectName; objectName = obj; } // Process WCS keywords FitsHead* head = image_->head(); // append wcs keywords to the end of the header int ll = head->headbytes()+hh->headbytes(); char* cards = new char[ll]; // copy default wcs memcpy(cards, head->cards(), head->headbytes()); // find first END and zero out for (int i=0; i<head->headbytes(); i+=80) if (!strncmp(cards+i,"END",3)) { memcpy(cards+i, " ",3); break; } // copy appended wcs memcpy(cards+head->headbytes(), hh->cards(), hh->headbytes()); if (wcsHeader) delete wcsHeader; wcsHeader = new FitsHead(cards,ll,FitsHead::ALLOC); initWCS(wcsHeader, (image_->primary() && image_->inherit() ? image_->primary() : NULL)); } char* FitsImage::display(FitsHead* head) { int size = head->ncard() * (FTY_CARDLEN+1); char* lbuf = new char[size+1]; char* lptr = lbuf; char* cptr = head->cards(); for (int i=0; i<head->ncard(); i++,cptr+=FTY_CARDLEN) { memcpy(lptr, cptr, FTY_CARDLEN); lptr+=FTY_CARDLEN; *(lptr++) = '\n'; } lbuf[size] = '\0'; return lbuf; } char* FitsImage::displayHeader() { if (DebugBin || DebugCompress) return display(image_->head()); else return display(fits_->head()); } char* FitsImage::displayPrimary() { return display(fits_->primary()); } char* FitsImage::displayWCS() { if (wcsHeader) return display(wcsHeader); else return display(image_->head()); } int FitsImage::findKeyword(const char* key) { return fits_->find(key); } FitsBound* FitsImage::getDataParams(FrScale::ScanMode which) { switch (which) { case FrScale::IMGSEC: return &iparams; case FrScale::DATASEC: return &dparams; case FrScale::CROPSEC: return &cparams; } } FitsHead* FitsImage::getHead() { if (image_) return image_->head(); else return NULL; } char* FitsImage::getKeyword(const char* key) { return fits_->getKeyword(key); } const char* FitsImage::getValue(const Vector& v) { if (!isIIS()) return data_->getValue(v); else { double value = data_->getValueDouble(v); ostringstream str; if (value <= 1) str << '<' << iisz[0] << ends; else if (value >= 200) str << '>' << iisz[1] << ends; else str << ((value-1) * (iisz[1]-iisz[0]))/199 + iisz[0] << ends; memcpy(buf,str.str().c_str(), str.str().length()); return buf; } } void FitsImage::iisSetFileName(const char* fn) { if (iisFileName) delete [] iisFileName; iisFileName = dupstr(fn); } void FitsImage::initWCS(FitsHead* head, FitsHead* primary) { // free up wcs and ast arrays if (wcs) { for (int ii=0; ii<MULTWCS; ii++) if (wcs[ii]) wcsfree(wcs[ii]); delete [] wcs; } if (ast) { for (int ii=0; ii<MULTWCS; ii++) if (ast[ii]) astAnnul(ast[ii]); delete [] ast; } // wcsinit is sloooowwww! so try to figure it out first wcs = new WorldCoor*[MULTWCS]; for (int ii=0; ii<MULTWCS; ii++) wcs[ii] = NULL; // look first for default WCS. Let wcsinit figure it out since there can // be many different non-standard wcs's present wcshead = head; wcsprim = primary; wcs[0] = wcsinit(head->cards()); wcshead = NULL; wcsprim = NULL; // now look for WCSA - WCSZ // we can take a short cut here, since only valid FITS wcs's are available for (int ii=1; ii<MULTWCS; ii++) { char str[] = "CTYPE1 "; str[6] = '@'+ii; if (head->find(str)) { wcshead = head; wcsprim = primary; wcs[ii] = wcsinitc(head->cards(),str+6); wcshead = NULL; wcsprim = NULL; } } // AST ast = new AstFrameSet*[MULTWCS]; for (int ii=0; ii<MULTWCS; ii++) { ast[ii] = NULL; if (wcs[ii]) astinit(ii, head); } // WCSDEP if (head->find("WCSDEP")) { char* str = head->getString("WCSDEP"); if (str) { for (int ii=1; ii<MULTWCS; ii++) { if (wcs[ii]) { if (wcs[ii]->wcsname) { if (!strncmp(str,wcs[ii]->wcsname,strlen(wcs[ii]->wcsname))) { if (ast[0] && ast[ii]) { AstFrameSet* dep = (AstFrameSet*)astCopy(ast[ii]); astInvert(ast[0]); astAddFrame(dep,2,astUnitMap(2,""),ast[0]); astSetI(dep,"current",4); astAnnul(ast[0]); ast[0] = dep; } } } } } delete [] str; } } // xth axis wcs char scrpix[] = "CRPIX "; char scrval[] = "CRVAL "; char scd[] = "CD _ "; char scdelt[] = "CDELT "; for (int jj=0; jj<WCSXMAX; jj++) { for (int ii=0; ii<MULTWCS; ii++) { int kk = WCSXMAX*jj+ii; wcsx[kk] = 0; crpixx[kk] = 0; crvalx[kk] = 0; cdx[kk] = 0; scrpix[5] = '3'+jj; scrpix[6] = !ii ? ' ' : '@'+jj; scrval[5] = '3'+jj; scrval[6] = !ii ? ' ' : '@'+jj; scd[2] = '3'+jj; scd[4] = '3'+jj; scd[5] = !ii ? ' ' : '@'+jj; scdelt[5] = '3'+jj; scdelt[6] = !ii ? ' ' : '@'+jj; if (head->find(scrpix) && head->find(scrval)) { wcsx[kk] = 1; crpixx[kk] = head->getReal(scrpix,0); crvalx[kk] = head->getReal(scrval,0); cdx[kk] = head->getReal(scd,0); if (!cdx[kk]) cdx[kk] = head->getReal(scdelt,0); } } } // now see if we have a 'physical' wcs, if so, set LTMV keywords for (int ii=1; ii<MULTWCS; ii++) { if (wcs[ii] && wcs[ii]->wcsname && !strncmp(wcs[ii]->wcsname, "PHYSICAL", 8)) { keyLTMV = 1; double ltm11 = wcs[ii]->cd[0] != 0 ? 1/wcs[ii]->cd[0] : 0; double ltm12 = wcs[ii]->cd[1] != 0 ? 1/wcs[ii]->cd[1] : 0; double ltm21 = wcs[ii]->cd[2] != 0 ? 1/wcs[ii]->cd[2] : 0; double ltm22 = wcs[ii]->cd[3] != 0 ? 1/wcs[ii]->cd[3] : 0; double ltv1 = wcs[ii]->crpix[0] - wcs[ii]->crval[0]*ltm11 - wcs[ii]->crval[1]*ltm21; double ltv2 = wcs[ii]->crpix[1] - wcs[ii]->crval[0]*ltm12 - wcs[ii]->crval[1]*ltm22; physicalToImage = Matrix(ltm11, ltm12, ltm21, ltm22, ltv1, ltv2); imageToPhysical = physicalToImage.invert(); } } if (DebugWCS) { for (int ii=0; ii<MULTWCS; ii++) { if (wcs[ii]) wcsShow(wcs[ii]); if (wcsx[ii]) { cerr << "wcs " << (char)(!ii ? ' ' : '@'+ii) << endl; cerr << "wcs->crpix3=" << crpixx[ii] << endl; cerr << "wcs->crval3=" << crvalx[ii] << endl; cerr << "wcs->cd3_3=" << cdx[ii] << endl; } } } } void FitsImage::initWCS0(const Vector& pix) { int ii = Coord::WCS0-Coord::WCS; if (wcs[ii]) wcsfree(wcs[ii]); wcs[ii] = NULL; if (wcs[0]) { Vector cc = mapFromRef(pix, Coord::IMAGE, Coord::FK5); WorldCoor* ww = wcs[0]; wcs[ii] = wcskinit(ww->nxpix, ww->nypix, "RA---TAN", "DEC--TAN", cc[0], cc[1], 0, 0, ww->cd, 0, 0, 0, 2000, 2000); wcs[ii]->longpole = 999; wcs[ii]->latpole = 999; if (ast[ii]) astAnnul(ast[ii]); ast[ii] = NULL; astinit(ii, NULL); if (DebugWCS) { if (wcs[ii]) wcsShow(wcs[ii]); } } } void FitsImage::load() { if (compress_) base_ = compress_; else if (hpx_) base_ = hpx_; else if (hist_) base_ = hist_; else base_ = fits_; if (basedata_) delete basedata_; switch (base_->head()->bitpix()) { case 8: basedata_ = new FitsDatam<unsigned char>(base_, parent); break; case 16: basedata_ = new FitsDatam<short>(base_, parent); break; case -16: basedata_ = new FitsDatam<unsigned short>(base_, parent); break; case 32: basedata_ = new FitsDatam<int>(base_, parent); break; case 64: basedata_ = new FitsDatam<long long>(base_, parent); break; case -32: basedata_ = new FitsDatam<float>(base_, parent); break; case -64: basedata_ = new FitsDatam<double>(base_, parent); break; } analysis(); resetWCS(); iparams.reset(); dparams.reset(); cparams.reset(); if (mparams) delete mparams; mparams = NULL; processKeywords(); } void FitsImage::match(const char* xxname1, const char* yyname1, Coord::CoordSystem sys1, Coord::SkyFrame sky1, const char* xxname2, const char* yyname2, Coord::CoordSystem sys2, Coord::SkyFrame sky2, double rad, Coord::CoordSystem sys, Coord::SkyDist dist, const char* rrname) { astClearStatus; // get lists Tcl_Obj* listxx1 = Tcl_GetVar2Ex(parent->interp, xxname1, NULL, TCL_LEAVE_ERR_MSG); Tcl_Obj* listyy1 = Tcl_GetVar2Ex(parent->interp, yyname1, NULL, TCL_LEAVE_ERR_MSG); Tcl_Obj* listxx2 = Tcl_GetVar2Ex(parent->interp, xxname2, NULL, TCL_LEAVE_ERR_MSG); Tcl_Obj* listyy2 = Tcl_GetVar2Ex(parent->interp, yyname2, NULL, TCL_LEAVE_ERR_MSG); // get objects int nxx1; Tcl_Obj **objxx1; Tcl_ListObjGetElements(parent->interp, listxx1, &nxx1, &objxx1); int nyy1; Tcl_Obj **objyy1; Tcl_ListObjGetElements(parent->interp, listyy1, &nyy1, &objyy1); int nxx2; Tcl_Obj **objxx2; Tcl_ListObjGetElements(parent->interp, listxx2, &nxx2, &objxx2); int nyy2; Tcl_Obj **objyy2; Tcl_ListObjGetElements(parent->interp, listyy2, &nyy2, &objyy2); // sanity check if (nxx1 != nyy1 || nxx2 != nyy2) return; // get doubles double* ixx1 = new double[nxx1]; for (int ii=0 ; ii<nxx1 ; ii++) Tcl_GetDoubleFromObj(parent->interp, objxx1[ii], ixx1+ii); double* iyy1 = new double[nyy1]; for (int ii=0 ; ii<nyy1 ; ii++) Tcl_GetDoubleFromObj(parent->interp, objyy1[ii], iyy1+ii); double* oxx1 = new double[nxx1]; memset(oxx1,0,sizeof(double)*nxx1); double* oyy1 = new double[nyy1]; memset(oyy1,0,sizeof(double)*nyy1); double* ixx2 = new double[nxx2]; for (int ii=0 ; ii<nxx2 ; ii++) Tcl_GetDoubleFromObj(parent->interp, objxx2[ii], ixx2+ii); double* iyy2 = new double[nyy2]; for (int ii=0 ; ii<nyy2 ; ii++) Tcl_GetDoubleFromObj(parent->interp, objyy2[ii], iyy2+ii); double* oxx2 = new double[nxx2]; memset(oxx2,0,sizeof(double)*nxx2); double* oyy2 = new double[nyy2]; memset(oyy2,0,sizeof(double)*nyy2); // map from wcs to image { int ss = sys1-Coord::WCS; if (!(ss>=0 && ast && ast[ss])) return; if (astIsASkyFrame(astGetFrame(ast[0], AST__CURRENT))) { setAstSkyFrame(ast[ss],sky1); for (int ii=0; ii<nxx1; ii++) { ixx1[ii] *= M_PI/180.; iyy1[ii] *= M_PI/180.; } astTran2(ast[ss], nxx1, ixx1, iyy1, 0, oxx1, oyy1); } } { int ss = sys2-Coord::WCS; if (!(ss>=0 && ast && ast[ss])) return; if (astIsASkyFrame(astGetFrame(ast[ss], AST__CURRENT))) { setAstSkyFrame(ast[ss],sky2); for (int ii=0; ii<nxx2; ii++) { ixx2[ii] *= M_PI/180.; iyy2[ii] *= M_PI/180.; } astTran2(ast[ss], nxx2, ixx2, iyy2, 0, oxx2, oyy2); } } // radius Vector cd = getWCScdelt(sys); switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: rad /= 60; break; case Coord::ARCSEC: rad /= 60*60; break; } double rx = rad/cd[0]; double ry = rad/cd[1]; double rr = (rx*rx + ry*ry)/2; // now compare int cnt=0; Tcl_Obj* objrr = Tcl_NewListObj(0,NULL); for(int jj=0; jj<nxx2; jj++) { for (int ii=0; ii<nxx1; ii++) { double dx = oxx2[jj]-oxx1[ii]; double dy = oyy2[jj]-oyy1[ii]; if (dx*dx + dy*dy < rr) { Tcl_Obj* obj[2]; obj[0] = Tcl_NewIntObj(ii+1); obj[1] = Tcl_NewIntObj(jj+1); Tcl_Obj* list = Tcl_NewListObj(2,obj); Tcl_ListObjAppendElement(parent->interp, objrr, list); cnt++; } } } Tcl_Obj* listrr = Tcl_SetVar2Ex(parent->interp, rrname, NULL, objrr, TCL_LEAVE_ERR_MSG); // clean up delete [] ixx1; delete [] iyy1; delete [] oxx1; delete [] oyy1; delete [] ixx2; delete [] iyy2; delete [] oxx2; delete [] oyy2; } Matrix& FitsImage::matrixFromData(Coord::InternalSystem sys) { switch (sys) { case Coord::WIDGET: return dataToWidget; case Coord::PANNER: return dataToPanner; case Coord::MAGNIFIER: return dataToMagnifier; case Coord::PS: return dataToPS; } } Matrix& FitsImage::matrixToData(Coord::InternalSystem sys) { switch (sys) { case Coord::WIDGET: return widgetToData; case Coord::PANNER: return pannerToData; case Coord::MAGNIFIER: return magnifierToData; case Coord::PS: return psToData; } } Matrix3d& FitsImage::matrixFromData3d(Coord::InternalSystem sys) { switch (sys) { case Coord::WIDGET: return dataToWidget3d; case Coord::PANNER: return dataToPanner3d; case Coord::MAGNIFIER: return dataToMagnifier3d; case Coord::PS: return dataToPS3d; } } Matrix3d& FitsImage::matrixToData3d(Coord::InternalSystem sys) { switch (sys) { case Coord::WIDGET: return widgetToData3d; case Coord::PANNER: return pannerToData3d; case Coord::MAGNIFIER: return magnifierToData3d; case Coord::PS: return psToData3d; } } int FitsImage::parseSection(char* lbuf, Vector* v1, Vector* v2) { double x1, y1, x2, y2; char d1,d2,d3,d4,d5; // dummy char string x(lbuf); istringstream str(x); str >> d1 >> x1 >> d2 >> x2 >> d3 >> y1 >> d4 >> y2 >> d5; // verify input if (!(d1=='[' && d2==':' && d3==',' && d4==':' && d5==']')) return 0; // it looks ok *v1 = Vector(x1,y1); *v2 = Vector(x2,y2); return 1; } void FitsImage::process(const char* fn, int id) { if (!fits_->isValid()) { reset(); return; } if (fits_->isImage()) { switch (fits_->pNRRDEncoding()) { case FitsFile::RAW: break; case FitsFile::GZIP: initNRRD(); if (!compress_->isValid()) { reset(); return; } break; default: reset(); return; } load(); } else if (fits_->isBinTable()) { // Compress if (fits_->find("ZIMAGE")) { initCompress(); if (!compress_->isValid()) { reset(); return; } load(); } // HEALPIX else if ((fits_->find("PIXTYPE") && (!strncmp(fits_->getString("PIXTYPE"),"HEALPIX",4))) || (fits_->find("NSIDE"))) { initHPX(); if (!hpx_->isValid()) { reset(); return; } load(); } else // Bintable initHist(); } else if (fits_->isAsciiTable()) { // HEALPIX if (fits_->find("NSIDE")) { initHPX(); if (!hpx_->isValid()) { reset(); return; } load(); } } // set slice address for (int ii=1; ii<id; ii++) { for (int jj=2; jj<FTY_MAXAXES; jj++) { if (address[jj]<naxis(jj)) { address[jj]++; break; } else address[jj]=1; } } // load() can call reset() if (fits_) setFileName(fn); } void FitsImage::processKeywords() { // Physical to Image (LTM/LTV keywords) (with no wcsname already located) if (!keyLTMV) { if (image_->find("LTM1_1") || image_->find("LTM1_2") || image_->find("LTM2_1") || image_->find("LTM2_2") || image_->find("LTV1") || image_->find("LTV2")) keyLTMV = 1; double ltm11 = image_->getReal("LTM1_1", 1); double ltm12 = image_->getReal("LTM1_2", 0); double ltm21 = image_->getReal("LTM2_1", 0); double ltm22 = image_->getReal("LTM2_2", 1); double ltv1 = image_->getReal("LTV1", 0); double ltv2 = image_->getReal("LTV2", 0); physicalToImage = Matrix(ltm11, ltm12, ltm21, ltm22, ltv1, ltv2); imageToPhysical = physicalToImage.invert(); } // CDD to Detector (DTM/DTV keywords) if (image_->find("DTM1_1") || image_->find("DTM1_2") || image_->find("DTM2_1") || image_->find("DTM2_2") || image_->find("DTV1") || image_->find("DTV2")) keyDTMV = 1; double dtm11 = image_->getReal("DTM1_1", 1); double dtm12 = image_->getReal("DTM1_2", 0); double dtm21 = image_->getReal("DTM2_1", 0); double dtm22 = image_->getReal("DTM2_2", 1); double dtv1 = image_->getReal("DTV1", 0); double dtv2 = image_->getReal("DTV2", 0); physicalToDetector = Matrix(dtm11, dtm12, dtm21, dtm22, dtv1, dtv2); detectorToPhysical = physicalToDetector.invert(); // Physical to Amplifier (ATM/ATV keywords) if (image_->find("ATM1_1") || image_->find("ATM1_2") || image_->find("ATM2_1") || image_->find("ATM2_2") || image_->find("ATV1") || image_->find("ATV2")) keyATMV = 1; double atm11 = image_->getReal("ATM1_1", 1); double atm12 = image_->getReal("ATM1_2", 0); double atm21 = image_->getReal("ATM2_1", 0); double atm22 = image_->getReal("ATM2_2", 1); double atv1 = image_->getReal("ATV1", 0); double atv2 = image_->getReal("ATV2", 0); physicalToAmplifier = Matrix(atm11, atm12, atm21, atm22, atv1, atv2); amplifierToPhysical = physicalToAmplifier.invert(); if (DebugMosaic) { cerr << endl; cerr << "ATM/V: " << physicalToAmplifier << endl; cerr << "ATM/V-1: " << amplifierToPhysical << endl; cerr << "DTM/V: " << physicalToDetector << endl; cerr << "DTM/V-1: " << detectorToPhysical << endl; cerr << "LTM/V: " << physicalToImage << endl; cerr << "LTM/V-1: " << imageToPhysical << endl; } // iparams is a BBOX in DATA coords 0-n iparams.xmin = 0; iparams.xmax = width(); iparams.ymin = 0; iparams.ymax = height(); iparams.zmin = 0; iparams.zmax = depth(); { char* datstr = image_->getString("DATASEC"); // default Vector v1(1,1); Vector v2(width(),height()); if (datstr && *datstr && parseSection(datstr,&v1,&v2)) { // additional check if (v1[0]<1 || v1[1]<1 || v1[1]>width() || v2[1]>height() || v1[0]>v2[0] || v1[1]>v2[1]) { // default v1 = Vector(1,1); v2 = Vector(width(),height()); keyDATASEC = 0; } else keyDATASEC = 1; } else keyDATASEC = 0; // dparams is a BBOX in DATA coords 0-n datasec = BBox(v1,v2); v1 -= Vector(1,1); dparams.xmin = v1[0]; dparams.xmax = v2[0]; dparams.ymin = v1[1]; dparams.ymax = v2[1]; dparams.zmin = iparams.zmin; dparams.zmax = iparams.zmax; if (datstr) delete [] datstr; } // FITS SECTION Vector ll(dparams.xmin,dparams.ymin); Vector ur(dparams.xmax,dparams.ymax); int zmin =iparams.zmin; int zmax =iparams.zmax; if (fits_->coord() && fits_->xvalid() && fits_->yvalid()) { ll[0] = fits_->xmin(); ur[0] = fits_->xmax(); ll[1] = fits_->ymin(); ur[1] = fits_->ymax(); ll = ll*physicalToImage*Translate(-1,-1); ur = ur*physicalToImage; parent->setScanMode(FrScale::CROPSEC); } if (!fits_->coord() && fits_->xvalid()) { ll[0] = fits_->xmin()-1; ur[0] = fits_->xmax(); parent->setScanMode(FrScale::CROPSEC); } if (!fits_->coord() && fits_->yvalid()) { ll[1] = fits_->ymin()-1; ur[1] = fits_->ymax(); parent->setScanMode(FrScale::CROPSEC); } if (!fits_->coord() && fits_->zvalid()) { zmin = fits_->zmin()-1; zmax = fits_->zmax(); parent->setScanMode(FrScale::CROPSEC); } // params is a BBOX in DATA coords 0-n setCropParams(ll,ur,0); setCrop3dParams(zmin,zmax); // clear the flags so that rebinning tables will not see them // fits_->setCoord(0); // fits_->setXValid(0); // fits_->setYValid(0); // fits_->setZValid(0); // DEBUG if (DebugCrop) { cerr << "iparams " << iparams << endl; cerr << "dparams " << dparams << endl; cerr << "cparams " << cparams << endl; } } int FitsImage::processKeywordsIRAF(FitsImage* fits) { // DETSEC Coord::Orientation orientation = Coord::NORMAL; Coord::Orientation mo = Coord::NORMAL; char* detstr = image_->getString("DETSEC"); Vector dv1,dv2; if (!(detstr && *detstr && parseSection(detstr,&dv1,&dv2))) { if (detstr) delete [] detstr; return 0; } delete [] detstr; BBox detsec = BBox(dv1,dv2); int xx = (dv1[0] < dv2[0]); int yy = (dv1[1] < dv2[1]); if (xx && yy) orientation = Coord::NORMAL; else if (!xx && yy) orientation = Coord::XX; else if (!xx && !yy) orientation = Coord::XY; else if (xx && !yy) orientation = Coord::YY; // DETSIZE char* sizestr = image_->getString("DETSIZE"); Vector sv1(1,1); Vector sv2(10000,10000); if (sizestr && *sizestr) { if (!(parseSection(sizestr,&sv1,&sv2))) { delete [] sizestr; return 0; } } if (sizestr) delete [] sizestr; BBox detsize = BBox(sv1,sv2); // CCDSUM Vector ccdsum(1,1); char* ccdstr = image_->getString("CCDSUM"); if (ccdstr && *ccdstr) { double Ns, Np, Ns1, Np1; string x(ccdstr); istringstream str(x); str >> Ns >> Np >> Ns1 >> Np1; ccdsum = Vector(1/Ns, 1/Np); } if (ccdstr) delete [] ccdstr; // origin Vector origin = detsec.ll * Scale(ccdsum) * Translate(-datasec.ll); // matrix // if the segment is flipped, we can have a discontinuity at // the edges, due to round off errors, so we 'nudge' it Matrix flip; switch (orientation) { case Coord::NORMAL: break; case Coord::XX: flip = FlipX(); break; case Coord::YY: flip = FlipY(); break; case Coord::XY: flip = FlipXY(); break; } // internal flip Matrix mflip; switch (parent->IRAFOrientation(orientation)) { case Coord::NORMAL: break; case Coord::XX: mflip = FlipX(); break; case Coord::YY: mflip = FlipY(); break; case Coord::XY: mflip = FlipXY(); break; } Vector center = datasec.center() * imageToData; Vector mcenter = detsize.center() * imageToData * Scale(ccdsum); wcsToRef = Translate(-center) * flip * Translate(center) * Translate(origin) * Translate(-mcenter) * mflip * Translate(mcenter); // we do this to shift the origin to the middle of the image to match // the wcs case. Needed by imageBBox() // first? reset wcsToRef if (fits == this) { irafToRef = wcsToRef.invert(); wcsToRef = Matrix(); } else wcsToRef *= fits->irafToRef; if (DebugMosaic) { cerr << "ProcessKeywordsIRAF" << endl << " datasec: " << datasec << endl << " ccdsum : " << ccdsum << endl << " detsize: " << detsize << endl << " detsec : " << detsec << endl << " matrix : " << wcsToRef << endl; } return 1; } int FitsImage::processKeywordsWCS(FitsImage* fits, Coord::CoordSystem sys) { if (!fits->hasWCS(sys)) return 0; wcsToRef = parent->calcAlignWCS(fits, this, sys, sys, Coord::FK5); if (DebugMosaic) cerr << "ProcessKeywordsWCS " << endl << " matrix : " << wcsToRef << endl; return 1; } void FitsImage::replaceWCS(FitsHead* hh) { // Process OBJECT keyword if (objectName) delete [] objectName; objectName = hh->getString("OBJECT"); // Process WCS keywords if (wcsHeader) delete wcsHeader; wcsHeader = new FitsHead(*hh); initWCS(hh, NULL); } void FitsImage::reset() { if (fits_) delete fits_; fits_ = NULL; if (compress_) delete compress_; compress_ = NULL; if (hpx_) delete hpx_; hpx_ = NULL; if (hist_) delete hist_; hist_ = NULL; if (basedata_) delete basedata_; basedata_ = NULL; if (smooth_) delete smooth_; smooth_ = NULL; if (smoothdata_) delete smoothdata_; smoothdata_ = NULL; base_ = NULL; image_ = NULL; data_ = NULL; } void FitsImage::resetWCS() { // Process OBJECT keyword if (objectName) delete [] objectName; objectName = image_->getString("OBJECT"); // Process WCS keywords if (wcsHeader) delete wcsHeader; wcsHeader = NULL; initWCS(image_->head(), (image_->primary() && image_->inherit() ? image_->primary() : NULL)); } void FitsImage::resetWCS0() { int ii = Coord::WCS0-Coord::WCS; if (wcs[ii]) wcsfree(wcs[ii]); wcs[ii] = NULL; } char* FitsImage::root(const char* fn) { if (fn) { const char* ptr = fn; // init the ptr while(*ptr++); // walk it forward to end of string ptr--; // backup one while(*ptr != '/' && ptr != fn) // walk it backward til last / or beginning ptr--; if (*ptr == '/') // step it over the last '/' ptr++; return dupstr(ptr); // got it! } else return NULL; } void FitsImage::setBinSliceFilter(const char* ff) { if (binSliceFilter) delete [] binSliceFilter; binSliceFilter = dupstr(ff); } void FitsImage::setCropParams(int datasec) { FitsBound* params; if (!datasec) params = &iparams; else params = &dparams; cparams.xmin = params->xmin; cparams.xmax = params->xmax; cparams.ymin = params->ymin; cparams.ymax = params->ymax; } void FitsImage::setCropParams(const Vector& ss, const Vector& tt, int datasec) { // Coord are in DATA Vector ll = ss; Vector ur = tt; int xmin = ll[0]; int xmax = ur[0]; int ymin = ll[1]; int ymax = ur[1]; if (xmin>xmax) { xmin = ur[0]; xmax = ll[0]; } if (ymin>ymax) { ymin = ur[1]; ymax = ll[1]; } setCropParams(xmin,ymin,xmax,ymax,datasec); } void FitsImage::setCropParams(int x0, int y0, int x1, int y1, int datasec) { FitsBound* params; if (!datasec) params = &iparams; else params = &dparams; // Coords are in DATA if (x0<params->xmin) x0=params->xmin; if (x0>params->xmax) x0=params->xmax; if (x1<params->xmin) x1=params->xmin; if (x1>params->xmax) x1=params->xmax; if (y0<params->ymin) y0=params->ymin; if (y0>params->ymax) y0=params->ymax; if (y1<params->ymin) y1=params->ymin; if (y1>params->ymax) y1=params->ymax; cparams.xmin = x0; cparams.xmax = x1; cparams.ymin = y0; cparams.ymax = y1; } void FitsImage::setCrop3dParams() { // params is a BBOX in DATA coords 0-n cparams.zmin = iparams.zmin; cparams.zmax = iparams.zmax; } void FitsImage::setCrop3dParams(double z0, double z1) { // params is a BBOX in DATA coords 0-n double zmin = z0; double zmax = z1; // always have at least 1 if (zmin+1>zmax) zmax = z0+1; // round to int setCrop3dParams(int(zmin+.5), int(zmax+.5)); } void FitsImage::setCrop3dParams(int z0, int z1) { // params is a BBOX in DATA coords 0-n if (z0<iparams.zmin) { z0=iparams.zmin; if (z0+1>z1) z1=z0+1; } if (z1>iparams.zmax) { z1=iparams.zmax; if (z0+1>z1) z0=z1-1; } cparams.zmin = z0; cparams.zmax = z1; } void FitsImage::setMinMaxParams() { if (mparams) delete mparams; mparams = NULL; } void FitsImage::setMinMaxParams(int x0, int y0, int x1, int y1) { if (mparams) delete mparams; mparams = new FitsBound(x0,y0,x1,y1); } void FitsImage::setFileName(const char* fn) { if (fullBaseFileName) delete [] fullBaseFileName; fullBaseFileName = NULL; if (rootBaseFileName) delete [] rootBaseFileName; rootBaseFileName = NULL; if (iisFileName) delete [] iisFileName; iisFileName = NULL; // no filename to set if (!fn) return; // strip any '[]' char* ffn = strip(fn); FitsFile* ptr = compress_ ? compress_ : fits_; if (!ptr) return; const char* ext = ptr->extname(); if (ext) { { ostringstream str; str << ffn << '[' << ext << ']' << ends; fullBaseFileName = dupstr(str.str().c_str()); } { char* m = root(ffn); ostringstream str; str << m << '[' << ext << ']' << ends; rootBaseFileName = dupstr(str.str().c_str()); delete [] m; } } else if (ptr->ext()) { { ostringstream str; str << ffn << '[' << ptr->ext() << ']' << ends; fullBaseFileName = dupstr(str.str().c_str()); } { char* m = root(ffn); ostringstream str; str << m << '[' << ptr->ext() << ']' << ends; rootBaseFileName = dupstr(str.str().c_str()); delete [] m; } } else { fullBaseFileName = dupstr(ffn); rootBaseFileName = root(ffn); } // by default, iisFileName is fullBaseFileName if (fullBaseFileName) iisFileName = dupstr(fullBaseFileName); delete [] ffn; updateFileName(); } void FitsImage::setObjectName(const char* obj) { if (objectName) delete [] objectName; objectName = dupstr(obj); } char* FitsImage::strip(const char* fn) { if (fn) { char* r = dupstr(fn); // dup the string char* ptr = r; // init the ptr while(*ptr != '[' && *ptr) // walk it forward til '[' or end ptr++; *ptr = '\0'; // zero out rest return r; // got it! } else return NULL; } int FitsImage::nhdu() { int dd =1; for (int ii=2; ii<FTY_MAXAXES; ii++) if (naxis_[ii]) dd *= naxis_[ii]; return dd; } void FitsImage::updateClip(FrScale* fr) { if (data_) if (mparams) data_->updateClip(fr,mparams); else data_->updateClip(fr,getDataParams(fr->scanMode())); } void FitsImage::updateFileName() { if (fullFileName) delete [] fullFileName; fullFileName = NULL; if (rootFileName) delete [] rootFileName; rootFileName = NULL; if (fullFileName3d) delete [] fullFileName3d; fullFileName3d = NULL; if (rootFileName3d) delete [] rootFileName3d; rootFileName3d = NULL; // note: 3d bin'd tables will be of type isImage() if (isImage() && !binSliceFilter) { char* sec =NULL; char* sec3d =NULL; char* add =NULL; // 2d/3d section switch (parent->scanMode()) { case FrScale::IMGSEC: case FrScale::DATASEC: break; case FrScale::CROPSEC: { FitsBound* params =getDataParams(FrScale::CROPSEC); // params is a BBOX in DATA coords 0-n // xlate to 1-n Vector3d ll= Vector3d(params->xmin,params->ymin,params->zmin)* Translate3d(1,1,1); Vector3d ur(params->xmax,params->ymax,params->zmax); { ostringstream str; str << ll[0] << ':' << ur[0] << ',' << ll[1] << ':' << ur[1] << ends; sec = dupstr(str.str().c_str()); } { ostringstream str; str << ll[0] << ':' << ur[0] << ',' << ll[1] << ':' << ur[1] << ',' << ll[2] << ':' << ur[2] << ends; sec3d = dupstr(str.str().c_str()); } } break; } // address { int doAdd =0; ostringstream str; int jj; for (jj=FTY_MAXAXES-1; jj>=2; jj--) { if (address[jj]!=1) break; } jj++; for (int ii=2; ii<jj; ii++) { doAdd =1; if (ii==2) str << "plane="; else str << ':'; str << address[ii]; } if (doAdd) { str << ends; add = dupstr(str.str().c_str()); } } if (fullBaseFileName) { ostringstream str; if (add && sec) str << fullBaseFileName << '[' << add << ']' << '[' << sec << ']'; else if (add && !sec) str << fullBaseFileName << '[' << add << ']'; else if (!add && sec) str << fullBaseFileName << '[' << sec << ']'; else str << fullBaseFileName; str << ends; fullFileName = dupstr(str.str().c_str()); } if (rootBaseFileName) { ostringstream str; if (add && sec) str << rootBaseFileName << '[' << add << ']' << '[' << sec << ']'; else if (add && !sec) str << rootBaseFileName << '[' << add << ']'; else if (!add && sec) str << rootBaseFileName << '[' << sec << ']'; else str << rootBaseFileName; str << ends; rootFileName = dupstr(str.str().c_str()); } if (fullBaseFileName) { ostringstream str; if (sec3d) str << fullBaseFileName << '[' << sec3d << ']'; else str << fullBaseFileName; str << ends; fullFileName3d = dupstr(str.str().c_str()); } if (rootBaseFileName) { ostringstream str; if (sec3d) str << rootBaseFileName << '[' << sec3d << ']'; else str << rootBaseFileName; str << ends; rootFileName3d = dupstr(str.str().c_str()); } if (sec) delete [] sec; if (sec3d) delete [] sec3d; if (add) delete [] add; } else if (isBinTable() || binSliceFilter) { char* sec = NULL; char* filter = (char*)fits_->pFilter(); int doFilter = (filter && *filter); int doSlice = (binSliceFilter && *binSliceFilter); switch (parent->scanMode()) { case FrScale::IMGSEC: case FrScale::DATASEC: break; case FrScale::CROPSEC: { ostringstream secstr; FitsBound* params =getDataParams(FrScale::CROPSEC); // dataToPhysical not set yet Vector ll = Vector(params->xmin,params->ymin) * dataToImage * imageToPhysical; Vector ur = Vector(params->xmax,params->ymax) * dataToImage * imageToPhysical; secstr << fits_->pBinX() << ">=" << ll[0] << ',' << fits_->pBinX() << "<=" << ur[0] << ',' << fits_->pBinY() << ">=" << ll[1] << ',' << fits_->pBinY() << "<=" << ur[1] << ends; sec = dupstr(secstr.str().c_str()); } break; } if (fullBaseFileName) { ostringstream str; str << fullBaseFileName; if (doFilter && sec && doSlice) str << '[' << filter << ',' << sec << ',' << binSliceFilter << ']'; else if (doFilter && sec && !doSlice) str << '[' << filter << ',' << sec << ']'; else if (doFilter && !sec && doSlice) str << '[' << filter << ',' << binSliceFilter << ']'; else if (doFilter && !sec && !doSlice) str << '[' << filter << ']'; else if (!doFilter && sec && doSlice) str << '[' << sec << ',' << binSliceFilter << ']'; else if (!doFilter && sec && !doSlice) str << '[' << sec << ']'; else if (!doFilter && !sec && doSlice) str << '[' << binSliceFilter << ']'; str << ends; fullFileName = dupstr(str.str().c_str()); fullFileName3d = dupstr(fullFileName); } if (rootBaseFileName) { ostringstream str; str << rootBaseFileName; if (doFilter && sec && doSlice) str << '[' << filter << ',' << sec << ',' << binSliceFilter << ']'; else if (doFilter && sec && !doSlice) str << '[' << filter << ',' << sec << ']'; else if (doFilter && !sec && doSlice) str << '[' << filter << ',' << binSliceFilter << ']'; else if (doFilter && !sec && !doSlice) str << '[' << filter << ']'; else if (!doFilter && sec && doSlice) str << '[' << sec << ',' << binSliceFilter << ']'; else if (!doFilter && sec && !doSlice) str << '[' << sec << ']'; else if (!doFilter && !sec && doSlice) str << '[' << binSliceFilter << ']'; str << ends; rootFileName = dupstr(str.str().c_str()); rootFileName3d = dupstr(rootFileName); } } } void FitsImage::updateMatrices(Matrix& rgbToRef, Matrix& refToWidget, Matrix& widgetToCanvas) { dataToRef = wcsToRef * rgbToRef; refToData = dataToRef.invert(); dataToWidget = dataToRef * refToWidget; widgetToData = dataToWidget.invert(); refToCanvas = refToWidget * widgetToCanvas; canvasToRef = refToCanvas.invert(); imageToRef = imageToData * dataToRef; refToImage = imageToRef.invert(); imageToWidget = imageToRef * refToWidget; widgetToImage = imageToWidget.invert(); physicalToRef = physicalToImage * imageToData * dataToRef; refToPhysical = physicalToRef.invert(); amplifierToRef = amplifierToPhysical * physicalToRef; refToAmplifier = amplifierToRef.invert(); detectorToRef = detectorToPhysical * physicalToRef; refToDetector = detectorToRef.invert(); } void FitsImage::updateMatrices(Matrix3d& refToWidget3d) { dataToWidget3d = dataToRef3d * refToWidget3d; widgetToData3d = dataToWidget3d.invert(); } void FitsImage::updatePannerMatrices(Matrix& refToPanner) { dataToPanner = dataToRef * refToPanner; pannerToData = dataToPanner.invert(); } void FitsImage::updatePannerMatrices(Matrix3d& refToPanner3d) { dataToPanner3d = dataToRef3d * refToPanner3d; pannerToData3d = dataToPanner3d.invert(); } void FitsImage::updateMagnifierMatrices(Matrix& refToMagnifier) { dataToMagnifier = dataToRef * refToMagnifier; magnifierToData = dataToMagnifier.invert(); } void FitsImage::updateMagnifierMatrices(Matrix3d& refToMagnifier3d) { dataToMagnifier3d = dataToRef3d * refToMagnifier3d; magnifierToData3d = dataToMagnifier3d.invert(); } void FitsImage::updatePS(Matrix ps) { dataToPS = dataToRef * ps; psToData = dataToPS.invert(); } void FitsImage::updatePS(Matrix3d ps) { dataToPS3d = dataToRef3d * ps; psToData3d = dataToPS3d.invert(); } // WCS Vector FitsImage::getWCScrpix(Coord::CoordSystem sys) { if (hasWCS(sys)) { int i = sys-Coord::WCS; if (!wcs[i]->coorflip) return Vector(wcs[i]->crpix[0], wcs[i]->crpix[1]); else return Vector(wcs[i]->crpix[1], wcs[i]->crpix[0]); } else return Vector(); } Vector FitsImage::getWCScrval(Coord::CoordSystem sys) { if (hasWCS(sys)) { int i = sys-Coord::WCS; if (!wcs[i]->coorflip) return Vector(wcs[i]->crval[0], wcs[i]->crval[1]); else return Vector(wcs[i]->crval[1], wcs[i]->crval[0]); } else return Vector(); } Vector FitsImage::getWCScdelt(Coord::CoordSystem sys) { if (hasWCS(sys)) { int i = sys-Coord::WCS; if (!wcs[i]->coorflip) return Vector(wcs[i]->cdelt[0], wcs[i]->cdelt[1]); else return Vector(wcs[i]->cdelt[1], wcs[i]->cdelt[0]); } else return Vector(); } Coord::Orientation FitsImage::getWCSOrientation(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (hasWCS(sys)) { Vector orpix = center(); Vector orval = pix2wcs(orpix, sys, sky); Vector delta = getWCScdelt(sys).abs(); Vector npix = wcs2pix(Vector(orval[0],orval[1]+delta[1]), sys, sky); Vector north = (npix-orpix).normalize(); Vector epix = wcs2pix(Vector(orval[0]+delta[0],orval[1]), sys, sky); Vector east = (epix-orpix).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) return Coord::NORMAL; // take the cross product and see which way the 3rd axis is pointing double w = east[0]*north[1]-east[1]*north[0]; if (!hasWCSCel(sys)) return w>0 ? Coord::NORMAL : Coord::XX; else return w<0 ? Coord::NORMAL : Coord::XX; } } double FitsImage::getWCSRotation(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (hasWCS(sys)) { Vector orpix = center(); Vector orval = pix2wcs(orpix, sys, sky); Vector delta = getWCScdelt(sys).abs(); Vector npix = wcs2pix(Vector(orval[0],orval[1]+delta[1]), sys, sky); Vector north = (npix-orpix).normalize(); Vector epix = wcs2pix(Vector(orval[0]+delta[0],orval[1]), sys, sky); Vector east = (epix-orpix).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) return 0; if (wcs[sys-Coord::WCS]->imflip) return (north.angle()-M_PI_2); else return -(north.angle()-M_PI_2); } return 0; } // AST Vector FitsImage::ASTpix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) { astClearStatus; int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) { double xx =0; double yy =0; if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { setAstSkyFrame(ast[ii],sky); astTran2(ast[ii], 1, in.v, in.v+1, 1, &xx, &yy); if (astOK) if (checkAst(xx,yy)) return Vector(radToDeg(xx),yy*180./M_PI); } else { astTran2(ast[ii], 1, in.v, in.v+1, 1, &xx, &yy); if (astOK) if (checkAst(xx,yy)) return Vector(xx,yy); } } maperr =1; return Vector(); } Vector* FitsImage::ASTpix2wcs(Vector* in, int num, Coord::CoordSystem sys, Coord::SkyFrame sky) { astClearStatus; double xin[num]; double yin[num]; double xout[num]; double yout[num]; Vector* out = new Vector[num]; for (int ii=0; ii<num; ii++) { xin[ii] = (in[ii])[0]; yin[ii] = (in[ii])[1]; } int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) { double xx =0; double yy =0; if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { setAstSkyFrame(ast[ii],sky); astTran2(ast[ii], num, xin, yin, 1, xout, yout); if (astOK) { for (int ii=0; ii<num; ii++) if (checkAst(xout[ii],yout[ii])) out[ii] = Vector(radToDeg(xout[ii]),yout[ii]*180./M_PI); return out; } } else { astTran2(ast[ii], num, xin, yin, 1, xout, yout); if (astOK) { for (int ii=0; ii<num; ii++) if (checkAst(xout[ii],yout[ii])) out[ii] = Vector(xout[ii],yout[ii]); return out; } } } maperr =1; return out; } char* FitsImage::ASTpix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, char* lbuf, int len) { astClearStatus; int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) { double xx =0; double yy =0; ostringstream str; if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { setAstSkyFrame(ast[ii],sky); astTran2(ast[ii], 1, in.v, in.v+1, 1, &xx, &yy); if (!astOK || !checkAst(xx,yy)) { maperr =1; lbuf[0] = '\0'; return lbuf; } switch (format) { case Coord::DEGREES: xx =radToDeg(xx); // 0 to 360 yy *=180./M_PI; str << setprecision(8) << xx << ' ' << yy << ' ' << coord.skyFrameStr(sky) << ends; break; case Coord::SEXAGESIMAL: switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: xx = zeroTWOPI(xx); setAstFormat(ast[ii],1,"hms.3"); setAstFormat(ast[ii],2,"+dms.2"); break; case Coord::GALACTIC: case Coord::SUPERGALACTIC: case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: xx = zeroTWOPI(xx); setAstFormat(ast[ii],1,"+dms.3"); setAstFormat(ast[ii],2,"+dms.3"); break; } str << astFormat(ast[ii], 1, xx) << ' ' << astFormat(ast[ii], 2, yy) << ' ' << coord.skyFrameStr(sky) << ends; break; } } else { astTran2(ast[ii], 1, in.v, in.v+1, 1, &xx, &yy); if (!astOK || !checkAst(xx,yy)) { maperr =1; return lbuf; } str << setprecision(8) << xx << ' ' << yy << ends; } strncpy(lbuf, str.str().c_str(), str.str().length()); } return lbuf; } Vector FitsImage::ASTwcs2pix(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) { astClearStatus; int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) { double xx =0; double yy =0; if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { setAstSkyFrame(ast[ii],sky); Vector rr = in*M_PI/180.; astTran2(ast[ii], 1, rr.v, &(rr[1]), 0, &xx, &yy); if (astOK) if (checkAst(xx,yy)) return Vector(xx,yy); } else { astTran2(ast[ii], 1, in.v, in.v+1, 0, &xx, &yy); if (astOK) if (checkAst(xx,yy)) return Vector(xx,yy); } } maperr =1; return Vector(); } Vector* FitsImage::ASTwcs2pix(Vector* in, int num, Coord::CoordSystem sys, Coord::SkyFrame sky) { astClearStatus; double xin[num]; double yin[num]; double xout[num]; double yout[num]; Vector* out = new Vector[num]; for (int ii=0; ii<num; ii++) { xin[ii] = (in[ii])[0]; yin[ii] = (in[ii])[1]; } int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) { double xx =0; double yy =0; if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { setAstSkyFrame(ast[ii],sky); for (int ii=0; ii<num; ii++) { xin[ii] *= M_PI/180.; yin[ii] *= M_PI/180.; } astTran2(ast[ii], num, xin, yin, 0, xout, yout); if (astOK) { for (int ii=0; ii<num; ii++) if (checkAst(xout[ii],yout[ii])) out[ii] = Vector(xout[ii],yout[ii]); return out; } } else { astTran2(ast[ii], num, xin, yin, 0, xout, yout); if (astOK) { for (int ii=0; ii<num; ii++) if (checkAst(xout[ii],yout[ii])) out[ii] = Vector(xout[ii],yout[ii]); return out; } } } maperr =1; return out; } double FitsImage::ASTwcsdist(Vector a, Vector b, Coord::CoordSystem sys) { astClearStatus; int ii = sys-Coord::WCS; double rr=0; if (ii>=0 && ast && ast[ii]) { if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { Vector aa = a*M_PI/180.; Vector bb = b*M_PI/180.; rr = astDistance(ast[ii], aa.v, bb.v) *180./M_PI; } else rr = astDistance(ast[ii], a.v, b.v); if (!astOK) { maperr =1; return 0; } } return rr; } // WCSSUB Vector FitsImage::WCSpix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) { int ii = sys-Coord::WCS; if (ii>=0 && wcs && wcs[ii]) { if (hasWCSCel(sys)) wcsoutinit(wcs[ii], coord.skyFrameStr(sky)); else wcsoutinit(wcs[ii], ::getradecsys(wcs[ii])); double x=0; double y=0; ::pix2wcs(wcs[ii], in[0], in[1], &x, &y); return Vector(x,y); } maperr =1; return Vector(); } char* FitsImage::WCSpix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, char* lbuf, int len) { int ii = sys-Coord::WCS; if (ii>=0 && wcs && wcs[ii]) { if (hasWCSCel(sys)) { wcsoutinit(wcs[ii], coord.skyFrameStr(sky)); switch (format) { case Coord::DEGREES: setwcsdeg(wcs[ii],1); wcs[ii]->ndec = 5; break; case Coord::SEXAGESIMAL: setwcsdeg(wcs[ii],0); wcs[ii]->ndec = 3; break; } } else { wcsoutinit(wcs[ii], ::getradecsys(wcs[ii])); setwcslin(wcs[ii],2); } ::pix2wcst(wcs[ii], in[0], in[1], lbuf, len); } return lbuf; } Vector FitsImage::WCSwcs2pix(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) { int ii = sys-Coord::WCS; if (ii>=0 && wcs && wcs[ii]) { if (hasWCSCel(sys)) wcsininit(wcs[ii], coord.skyFrameStr(sky)); else wcsininit(wcs[ii], ::getradecsys(wcs[ii])); double x=0; double y=0; int off=0; ::wcs2pix(wcs[ii], in[0], in[1], &x, &y, &off); if (off) { maperr =1; return Vector(); } else return Vector(x,y); } maperr =1; return Vector(); } double FitsImage::WCSwcsdist(Vector a, Vector b, Coord::CoordSystem sys) { int ii = sys-Coord::WCS; if (ii>=0 && wcs && wcs[ii]) return ::wcsdist(a[0],a[1],b[0],b[1]); maperr =1; return 0; } int FitsImage::hasWCS(Coord::CoordSystem sys) { int ii = sys-Coord::WCS; return (sys>=Coord::WCS && ast && ast[ii]) ? 1 : 0; } int FitsImage::hasWCSEqu(Coord::CoordSystem sys) { astClearStatus; int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) { // special case of xLON/xLAT char* bb = &(wcs[ii]->c1type[1]); if (!strncmp(bb,"LON",3) || !strncmp(bb,"LAT",3)) switch (wcs[ii]->c1type[0]) { case 'G': case 'H': case 'E': case 'S': return 1; default: return 0; } // special case of xyLN/xyLT char* cc = &(wcs[ii]->c1type[2]); if (!strncmp(cc,"LN",2) || !strncmp(cc,"LT",3)) return 0; return 1; } return 0; } int FitsImage::hasWCSCel(Coord::CoordSystem sys) { astClearStatus; int ii = sys-Coord::WCS; if (ii>=0 && ast && ast[ii]) if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) return 1; return 0; } // WCSX int FitsImage::hasWCSx(Coord::CoordSystem sys, int ss) { int rr = ss-2; int ii = sys-Coord::WCS; int kk = WCSXMAX*rr+ii; return (rr<WCSXMAX && sys>=Coord::WCS && wcsx[kk]) ? 1 : 0; } double FitsImage::pix2wcsx(double in, Coord::CoordSystem sys, int ss) { if (hasWCSx(sys,ss)) { int rr = ss-2; int ii = sys-Coord::WCS; int kk = WCSXMAX*rr+ii; return (in-crpixx[kk])*cdx[kk] + crvalx[kk]; } else return in; } double FitsImage::wcs2pixx(double in, Coord::CoordSystem sys, int ss) { if (hasWCSx(sys,ss)) { int rr = ss-2; int ii = sys-Coord::WCS; int kk = WCSXMAX*rr+ii; return (in-crvalx[kk])/cdx[kk] + crpixx[kk]; } else return in; } // WCS/AST support void FitsImage::wcsShow(WorldCoor* ww) { if (!ww) return; int n = ww->naxes; int nn = n*n; cerr << "wcs->wcsname=" << (ww->wcsname ? ww->wcsname : "") << endl; cerr << "wcs->naxes=" << ww->naxes << endl; cerr << "wcs->naxis=" << ww->naxis << endl; cerr << "wcs->radecsys=" << ww->radecsys << endl; cerr << "wcs->equinox=" << ww->equinox << endl; cerr << "wcs->epoch=" << ww->epoch << endl; cerr << "wcs->ctype[0]=" << ww->ctype[0] << endl; cerr << "wcs->ctype[1]=" << ww->ctype[1] << endl; cerr << "wcs->c1type=" << ww->c1type << endl; cerr << "wcs->c2type=" << ww->c2type << endl; cerr << "wcs->ptype=" << ww->ptype << endl; for (int jj=0; jj<n; jj++) cerr << "wcs->crpix[" << jj << "]=" << ww->crpix[jj] << endl; for (int jj=0; jj<n; jj++) cerr << "wcs->crval[" << jj << "]=" << ww->crval[jj] << endl; for (int jj=0; jj<n; jj++) cerr << "wcs->cdelt[" << jj << "]=" << ww->cdelt[jj] << endl; for (int jj=0; jj<4; jj++) cerr << "wcs->cd[" << jj << "]=" << ww->cd[jj] << endl; for (int jj=0; jj<nn; jj++) cerr << "wcs->pc[" << jj << "]=" << ww->pc[jj] << endl; cerr << "wcs->longpole=" << ww->longpole << endl; cerr << "wcs->latpole=" << ww->latpole << endl; cerr << "wcs->prjcode=" << ww->prjcode << endl; cerr << "wcs->rot=" << ww->rot << endl; cerr << "wcs->imrot=" << ww->imrot << endl; cerr << "wcs->imflip=" << ww->imflip << endl; cerr << "wcs->pa_north=" << ww->pa_north << endl; cerr << "wcs->pa_east=" << ww->pa_east << endl; cerr << "wcs->coorflip=" << ww->coorflip << endl; cerr << "wcs->syswcs=" << ww->syswcs << endl; cerr << "wcs->wcsproj=" << ww->wcsproj << endl; cerr << "wcs->distcode=" << ww->distcode << endl; } void FitsImage::astinit(int ii, FitsHead* hh) { if (!wcs[ii]) { ast[ii] = NULL; return; } // DSS,PLT,HPX,TAB goes straight to AST if (wcs[ii]->prjcode==WCS_DSS || wcs[ii]->prjcode==WCS_PLT || (wcs[ii]->prjcode==WCS_LIN && !strncmp(wcs[ii]->ptype,"HPX",3)) || (wcs[ii]->prjcode==WCS_LIN && !strncmp(wcs[ii]->ptype,"TAB",3))) ast[ii] = fits2ast(hh); else ast[ii] = wcs2ast(ii); if (!ast[ii]) return; // set default skyframe if (astIsASkyFrame(astGetFrame(ast[ii], AST__CURRENT))) setAstSkyFrame(ast[ii],Coord::FK5); if (DebugAST) astShow(ast[ii]); } int FitsImage::checkAst(double x, double y) { // check for reasonable values return (fabs(x) < FLT_MAX && fabs(y) < FLT_MAX) ? 1 : 0; } void FitsImage::setAstFormat(AstFrameSet* aa, int id, const char* format) { // is it already set? // ast is very slow when changing params { ostringstream str; str << "Format(" << id << ")" << ends; const char* out = astGetC(aa, str.str().c_str()); if (!strcmp(out,format)) return; } ostringstream str; str << "Format(" << id << ")=" << format << ends; astSet(aa, str.str().c_str()); } void FitsImage::setAstSkyFrame(AstFrameSet* aa, Coord::SkyFrame sky) { // is sky frame if (!astIsASkyFrame(astGetFrame(aa, AST__CURRENT))) return; // is it already set? // ast is very slow when changing system,equinox const char* str = astGetC(aa, "System"); // TLON/XLON and HPX will do this if (!strncmp(str,"Unknown",3)) return; switch (sky) { case Coord::FK4_NO_E: if (!strncmp(str,"FK4-NO-E",8)) return; astSet(aa, "System=FK4-NO-E, Equinox=B1950"); return; case Coord::FK4: if (!strncmp(str,"FK4",3)) return; astSet(aa, "System=FK4, Equinox=B1950"); return; case Coord::FK5: if (!strncmp(str,"FK5",3)) return; astSet(aa, "System=FK5, Equinox=J2000"); return; case Coord::ICRS: if (!strncmp(str,"ICRS",4)) return; astSet(aa, "System=ICRS"); return; case Coord::GALACTIC: if (!strncmp(str,"GALACTIC",8)) return; astSet(aa, "System=GALACTIC"); return; case Coord::SUPERGALACTIC: if (!strncmp(str,"SUPERGALACTIC",13)) return; astSet(aa, "System=SUPERGALACTIC"); return; case Coord::ECLIPTIC: if (!strncmp(str,"ECLIPTIC",8)) return; astSet(aa, "System=ECLIPTIC"); // get AST to agree with WCSSUBS astSetD(aa, "EQUINOX", astGetD(aa, "EPOCH")); return; case Coord::HELIOECLIPTIC: if (!strncmp(str,"HELIOECLIPTIC",13)) return; astSet(aa, "System=HELIOECLIPTIC"); return; } } AstFrameSet* FitsImage::fits2ast(FitsHead* hh) { FitsHead* head = hh; // we may have an error, just reset astClearStatus; // new fitschan AstFitsChan* chan = astFitsChan(NULL, NULL, ""); if (!astOK || chan == AST__NULL) return NULL; // no warning messages astClear(chan,"Warnings"); // fill up chan char* cards =NULL; int ncards =0; if (!head) if (image_) head = image_->head(); if (head) { cards = head->cards(); ncards = head->ncard(); } if (cards == NULL || ncards == 0) return NULL; for (int i=0; i<ncards; i++) { char buf[81]; strncpy(buf,cards+(i*80),80); buf[80] = '\0'; astPutFits(chan, buf, 0); // sometimes, we get a bad parse, just ignore if (!astOK) astClearStatus; } // enable -TAB //astSetI(chan,"TabOK",1); // we may have an error, just reset astClearStatus; astClear(chan, "Card"); // parse header AstFrameSet* frameSet = (AstFrameSet*)astRead(chan); // do we have anything? if (!astOK || frameSet == AST__NULL || strncmp(astGetC(frameSet,"Class"), "FrameSet", 8)) return NULL; return frameSet; } AstFrameSet* FitsImage::wcs2ast(int ww) { // read wcs struct into astChannel // we may have an error, just reset astClearStatus; // new fitschan AstFitsChan* chan; chan = astFitsChan(NULL, NULL, ""); if (!astOK || chan == AST__NULL) return NULL; // no warning messages astClear(chan,"Warnings"); // fill up chan FitsFile* fits = image_; if (DebugAST) cerr << endl << "wcs2ast()" << endl; // Alt WCS char alt = (ww==0) ? ' ' : (char)('@'+ww); // CTYPE if (wcs[ww]->prjcode == WCS_TAN && wcs[ww]->distcode) { // SIP { ostringstream str; str << wcs[ww]->ctype[0] << "-SIP" << ends; putFitsCard(chan, "CTYPE1", str.str().c_str()); } { ostringstream str; str << wcs[ww]->ctype[1] << "-SIP" << ends; putFitsCard(chan, "CTYPE2", str.str().c_str()); } } else if (wcs[ww]->prjcode == WCS_PIX || wcs[ww]->prjcode == WCS_LIN) { // this is not a mistake, WCS manges the ctype[0] and ctype[1] putFitsCard(chan, "CTYPE1", wcs[ww]->c1type); putFitsCard(chan, "CTYPE2", wcs[ww]->c2type); } else { putFitsCard(chan, "CTYPE1", wcs[ww]->ctype[0]); putFitsCard(chan, "CTYPE2", wcs[ww]->ctype[1]); } // CRPIX/CRVAL putFitsCard(chan, "CRPIX1", wcs[ww]->crpix[0]); putFitsCard(chan, "CRPIX2", wcs[ww]->crpix[1]); putFitsCard(chan, "CRVAL1", wcs[ww]->crval[0]); putFitsCard(chan, "CRVAL2", wcs[ww]->crval[1]); // CD/CDELT/PC // This is very complicated. AST is very, very, very picky as to which // keywords it use... { ostringstream cd; cd << "CD1_1" << alt << ends; ostringstream cdelt; cdelt << "CDELT1" << alt << ends; ostringstream pc; pc << "PC1_1" << alt << ends; if (fits->find(cd.str().c_str(), wcsHeader)) { if (!wcs[ww]->cd[1] && !wcs[ww]->cd[2] && !wcs[ww]->rot && wcs[ww]->latpole == 999 && wcs[ww]->longpole == 999) { // simple case putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]); putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]); } else { putFitsCard(chan, "CD1_1", wcs[ww]->cd[0]); putFitsCard(chan, "CD1_2", wcs[ww]->cd[1]); putFitsCard(chan, "CD2_1", wcs[ww]->cd[2]); putFitsCard(chan, "CD2_2", wcs[ww]->cd[3]); } } else if (fits->find(cdelt.str().c_str(), wcsHeader)) { putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]); putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]); if (fits->find(pc.str().c_str(), wcsHeader)) { putFitsCard(chan, "PC1_1", wcs[ww]->pc[0]); putFitsCard(chan, "PC1_2", wcs[ww]->pc[1]); putFitsCard(chan, "PC2_1", wcs[ww]->pc[2]); putFitsCard(chan, "PC2_2", wcs[ww]->pc[3]); } else if (!ww && fits->find("PC001001", wcsHeader)) { putFitsCard(chan, "PC001001", wcs[ww]->pc[0]); putFitsCard(chan, "PC001002", wcs[ww]->pc[1]); putFitsCard(chan, "PC002001", wcs[ww]->pc[2]); putFitsCard(chan, "PC002002", wcs[ww]->pc[3]); } else { if (!ww && fits->find("CROTA1", wcsHeader)) putFitsCard(chan, "CROTA1", wcs[ww]->rot); if (!ww && fits->find("CROTA2", wcsHeader)) putFitsCard(chan, "CROTA2", wcs[ww]->rot); } } else if (!wcs[ww]->cd[0] && !wcs[ww]->cd[1] && !wcs[ww]->cd[2] && !wcs[ww]->cd[3]) { // sanity check putFitsCard(chan, "CDELT1", wcs[ww]->cdelt[0]); putFitsCard(chan, "CDELT2", wcs[ww]->cdelt[1]); putFitsCard(chan, "PC1_1", wcs[ww]->pc[0]); putFitsCard(chan, "PC1_2", wcs[ww]->pc[1]); putFitsCard(chan, "PC2_1", wcs[ww]->pc[2]); putFitsCard(chan, "PC2_2", wcs[ww]->pc[3]); } else { putFitsCard(chan, "CD1_1", wcs[ww]->cd[0]); putFitsCard(chan, "CD1_2", wcs[ww]->cd[1]); putFitsCard(chan, "CD2_1", wcs[ww]->cd[2]); putFitsCard(chan, "CD2_2", wcs[ww]->cd[3]); } } // equatorial keywords if (wcs[ww]->prjcode>0 && wcs[ww]->prjcode<34) { // equiniox putFitsCard(chan, "EQUINOX", wcs[ww]->equinox); // from wcssub/wcsinit.c line 800 // wcs[ww]->epoch = 1900.0 + (mjd - 15019.81352) / 365.242198781; putFitsCard(chan, "MJD-OBS", (wcs[ww]->epoch-1900)*365.242198781+15019.81352); if (!strncmp("RA",wcs[ww]->ctype[0],2) || !strncmp("RA",wcs[ww]->ctype[1],2)) { if (!strncmp("FK4",wcs[ww]->radecsys,3) || !strncmp("FK4-NO-E",wcs[ww]->radecsys,8) || !strncmp("FK5",wcs[ww]->radecsys,3) || !strncmp("ICRS",wcs[ww]->radecsys,4)) putFitsCard(chan, "RADESYS", wcs[ww]->radecsys); } } // ast is picky about latpole/longpole if ((wcs[ww]->latpole == 999 && wcs[ww]->longpole == 999) || (wcs[ww]->latpole == 0 && wcs[ww]->longpole == 0)) ; else { if (wcs[ww]->latpole != 999) putFitsCard(chan, "LATPOLE", wcs[ww]->latpole); if (wcs[ww]->longpole != 999) putFitsCard(chan, "LONPOLE", wcs[ww]->longpole); } // Projection parameters- PV, QV, WAT // TAN+PV (old SCAMP-backward compatibility) // TPV+PV (new SCAMP) // xxx+PV (ZPN generic) // xxx+QV (TAN AUTOASTROM) // TNX/ZPX+WAT (IRAF) // TAN/LIN-SIP (SIP) // PVx_y (old SCAMP, SCAMP, generic) for (int ii=1; ii<=2; ii++) { for (int mm=0; mm<=MAXPV; mm++) { ostringstream str,str2; str << "PV" << ii << '_' << mm << alt << ends; str2 << "PV" << ii << '_' << mm << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str2.str().c_str(), val); } } } // QVx_y (Autoastrom) for (int ii=1; ii<=2; ii++) { for (int mm=0; mm<=MAXPV; mm++) { ostringstream str,str2; str << "QV" << ii << '_' << mm << alt << ends; str2 << "QV" << ii << '_' << mm << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str2.str().c_str(), val); } } } // WATx_ (IRAF) (primary only) if ((wcs[ww]->prjcode == WCS_TNX || wcs[ww]->prjcode == WCS_ZPX) && !ww) { for (int jj=0; jj<=2; jj++) { for (int ii=1; ii<=9; ii++) { ostringstream str; str << "WAT" << jj << "_00" << ii << ends; if (fits->find(str.str().c_str(), wcsHeader)) { char* val = fits->getString(str.str().c_str(), wcsHeader); if (val) { putFitsCard(chan, str.str().c_str(), val); delete [] val; } } } } } // SIP (TAN-SIP/LIN-SIP) (primary only) if ((wcs[ww]->prjcode == WCS_TAN || wcs[ww]->prjcode == WCS_LIN) && !ww && wcs[ww]->distcode) { if (fits->find("A_ORDER", wcsHeader)) { int val = fits->getInteger("A_ORDER",0, wcsHeader); putFitsCard(chan, "A_ORDER", val); } if (fits->find("AP_ORDER", wcsHeader)) { int val = fits->getInteger("AP_ORDER",0, wcsHeader); putFitsCard(chan, "AP_ORDER", val); } if (fits->find("A_DMAX", wcsHeader)) { double val = fits->getReal("A_DMAX",0, wcsHeader); putFitsCard(chan, "A_DMAX", val); } if (fits->find("B_ORDER", wcsHeader)) { int val = fits->getInteger("B_ORDER",0, wcsHeader); putFitsCard(chan, "B_ORDER", val); } if (fits->find("BP_ORDER", wcsHeader)) { int val = fits->getInteger("BP_ORDER",0, wcsHeader); putFitsCard(chan, "BP_ORDER", val); } if (fits->find("B_DMAX", wcsHeader)) { double val = fits->getReal("B_DMAX",0, wcsHeader); putFitsCard(chan, "B_DMAX", val); } for (int jj=0; jj<=9; jj++) { for (int ii=0; ii<=9; ii++) { { ostringstream str; str << "A_" << jj << "_" << ii << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str.str().c_str(), val); } } { ostringstream str; str << "AP_" << jj << "_" << ii << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str.str().c_str(), val); } } { ostringstream str; str << "B_" << jj << "_" << ii << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str.str().c_str(), val); } } { ostringstream str; str << "BP_" << jj << "_" << ii << ends; if (fits->find(str.str().c_str(), wcsHeader)) { double val = fits->getReal(str.str().c_str(),0, wcsHeader); putFitsCard(chan, str.str().c_str(), val); } } } } } // rewind chan astClear(chan, "Card"); // parse header AstFrameSet* frameSet = (AstFrameSet*)astRead(chan); // do we have anything? if (!astOK || frameSet == AST__NULL || strncmp(astGetC(frameSet,"Class"), "FrameSet", 8)) return NULL; if (wcs[ww]->coorflip) { int orr[] = {2,1}; astPermAxes(frameSet,orr); } // cleanup astAnnul(chan); return frameSet; } void FitsImage::putFitsCard(void* chan, const char* key, const char* value) { char buf[80]; memset(buf,'\0', 80); ostringstream str; str.setf(ios::left,ios::adjustfield); str.width(8); str << key << "= '" << value << "'"; memcpy(buf,str.str().c_str(),str.str().length()); astPutFits(chan, buf, 0); astClearStatus; if (DebugAST) cerr << str.str().c_str() << endl; } void FitsImage::putFitsCard(void* chan, const char* key, int value) { char buf[80]; memset(buf,'\0', 80); ostringstream str; str.setf(ios::left,ios::adjustfield); str.width(8); str << key << "= " << value; memcpy(buf,str.str().c_str(),str.str().length()); astPutFits(chan, buf, 0); astClearStatus; if (DebugAST) cerr << str.str().c_str() << endl; } void FitsImage::putFitsCard(void* chan, const char* key, double value) { char buf[80]; memset(buf,'\0', 80); ostringstream str; str.setf(ios::left,ios::adjustfield); str.setf(ios::scientific,ios::floatfield); str.width(8); str.precision(16); str << key << "= " << value; memcpy(buf,str.str().c_str(),str.str().length()); astPutFits(chan, buf, 0); astClearStatus; if (DebugAST) cerr << str.str().c_str() << endl; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergb.h���������������������������������������������������������������������0000644�0001750�0001750�00000011174�12103032232�015244� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framergb_h__ #define __framergb_h__ #include "context.h" #include "framebase.h" #include "colorscalergb.h" // Frame class FrameRGB : public virtual FrameBase { protected: int channel; // current channel Coord::CoordSystem rgbSystem; // alignment coordinate system Matrix rgb[3]; // rgb matrix int view[3]; // visible channels float bias[3]; // current colormap bias float contrast[3]; // current colormap contrast ColorScaleRGB* colorScale[3]; // current color scale int colorCount; // number of dynamic colors unsigned char* colorCells; // current color values private: void alignWCS(); void alignWCS(Coord::CoordSystem, Coord::SkyFrame); void alignWCS(FitsImage*, Coord::CoordSystem); int doRender(); BBox imageBBox(FrScale::ScanMode); void loadRGBCube(MemType, const char*, FitsImage*); void loadRGBImage(MemType, const char*, FitsImage*); void loadRGBFinish(); void reset(); void rgbAlignWCS(int); void setBinCursor(); void setKeyFits(); void unloadFits(); void pushMatrices(); void pushMagnifierMatrices(); void pushPannerMatrices(); void pushPSMatrices(float, int, int); void updateRGBMatrices(); protected: int isFrameRGB() {return 1;} unsigned char* fillImage(int, int, Coord::InternalSystem); void updateColorCells(unsigned char*, int); void updateColorScale(); void unloadAllFits(); int validColorScale() {return colorScale[0] && colorScale[1] && colorScale[2];} public: FrameRGB(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FrameRGB(); void getColorbarCmd(); void getInfoCmd(const Vector&, Coord::InternalSystem, char*); void getRGBChannelCmd(); void getRGBSystemCmd(); void getRGBViewCmd(); void getTypeCmd(); void iisCmd(int, int) {} void iisEraseCmd() {} void iisGetCmd(char*, int, int, int, int) {} void iisSetCmd(const char*, int, int, int, int) {} void iisWCSCmd(const Matrix&, const Vector&, int) {} void loadPhotoCmd(const char*, const char*); void loadSlicePhotoCmd(const char*, const char*) {} void loadRGBCubeAllocCmd(const char*, const char*); void loadRGBCubeAllocGZCmd(const char*, const char*); void loadRGBCubeChannelCmd(const char*, const char*); void loadRGBCubeMMapCmd(const char*, LoadMethod); void loadRGBCubeSMMapCmd(const char*, const char*, LoadMethod); void loadRGBCubeMMapIncrCmd(const char*, LoadMethod); void loadRGBCubeShareCmd(ShmType, int, const char*, LoadMethod); void loadRGBCubeSShareCmd(ShmType, int, int, const char*, LoadMethod); void loadRGBCubeSocketCmd(int, const char*); void loadRGBCubeSocketGZCmd(int, const char*); void loadRGBCubeVarCmd(const char*, const char*, LoadMethod); void loadRGBImageAllocCmd(const char*, const char*); void loadRGBImageAllocGZCmd(const char*, const char*); void loadRGBImageChannelCmd(const char*, const char*); void loadRGBImageMMapCmd(const char*, LoadMethod); void loadRGBImageMMapIncrCmd(const char*, LoadMethod); void loadRGBImageShareCmd(ShmType, int, const char*, LoadMethod); void loadRGBImageSocketCmd(int, const char*); void loadRGBImageSocketGZCmd(int, const char*); void loadRGBImageVarCmd(const char*, const char*, LoadMethod); void loadArrayRGBCubeAllocCmd(const char*, const char*); void loadArrayRGBCubeAllocGZCmd(const char*, const char*); void loadArrayRGBCubeChannelCmd(const char*, const char*); void loadArrayRGBCubeMMapCmd(const char*); void loadArrayRGBCubeMMapIncrCmd(const char*); void loadArrayRGBCubeShareCmd(ShmType, int, const char*); void loadArrayRGBCubeSocketCmd(int, const char*); void loadArrayRGBCubeSocketGZCmd(int, const char*); void loadArrayRGBCubeVarCmd(const char*, const char*); void saveFitsRGBImage(OutFitsStream&); void saveFitsRGBImageFileCmd(const char*); void saveFitsRGBImageChannelCmd(const char*); void saveFitsRGBImageSocketCmd(int); void saveFitsRGBCube(OutFitsStream&); void saveFitsRGBCubeFileCmd(const char*); void saveFitsRGBCubeChannelCmd(const char*); void saveFitsRGBCubeSocketCmd(int); void saveArrayRGBCube(OutFitsStream&, FitsFile::ArchType); void saveArrayRGBCubeFileCmd(const char*, FitsFile::ArchType); void saveArrayRGBCubeChannelCmd(const char*, FitsFile::ArchType); void saveArrayRGBCubeSocketCmd(int, FitsFile::ArchType); void savePhotoCmd(const char*); void setRGBChannelCmd(const char*); void setRGBViewCmd(int, int, int); void setRGBSystemCmd(Coord::CoordSystem); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/annulus.C����������������������������������������������������������������������0000644�0001750�0001750�00000024432�12030663652�015117� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "annulus.h" #include "fitsimage.h" Annulus::Annulus(const Annulus& a) : BaseEllipse(a) {} Annulus::Annulus(Base* p, const Vector& ctr, double r1, double r2, int rn, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn+1; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) { double r = i*(r2-r1)/rn+r1; annuli_[i] = Vector(r,r); } strcpy(type_, "annulus"); numHandle = 4 + numAnnuli_; updateBBox(); } Annulus::Annulus(Base* p, const Vector& ctr, int rn, double* r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = Vector(r[i],r[i]); sortAnnuli(); strcpy(type_, "annulus"); numHandle = 4 + numAnnuli_; updateBBox(); } void Annulus::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); if (h<5) { // calc dist between edge of circle and handle double d = annuli_[numAnnuli_-1].length() - annuli_[numAnnuli_-1][0]; for (int i=0; i<numAnnuli_; i++) { double r = ((v * mm).length() - d)/annuli_[numAnnuli_-1][0]; annuli_[i] *= r; } } else { double d = (v * mm).length(); annuli_[h-5] = Vector(d,d); } updateBBox(); doCallBack(CallBack::EDITCB); } void Annulus::editEnd() { sortAnnuli(); updateBBox(); doCallBack(CallBack::EDITENDCB); } int Annulus::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm).length(); return insertAnnuli(Vector(l,l)); } void Annulus::analysis(AnalysisTask mm, int which) { switch (mm) { case RADIAL: if (!analysisRadial_ && which) { addCallBack(CallBack::MOVECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisRadialCB_[1], parent->options->cmdName); } if (analysisRadial_ && !which) { deleteCallBack(CallBack::MOVECB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITCB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisRadialCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisRadialCB_[0]); deleteCallBack(CallBack::DELETECB, analysisRadialCB_[1]); } analysisRadial_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Annulus::analysisRadial(char* xname, char* yname, char* ename, Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) { Vector ll = -annuli_[ii] * Translate(center); Vector ur = annuli_[ii] * Translate(center); bb[ii] = BBox(ll,ur) ; } int num = parent->markerAnalysisRadial(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, bb, sys); analysisRadialResult(xname, yname, ename, xx, yy, ee, num); } void Annulus::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) { Vector ll = -annuli_[ii] * Translate(center); Vector ur = annuli_[ii] * Translate(center); bb[ii] = BBox(ll,ur) ; } parent->markerAnalysisStats(this, str, numAnnuli_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Annulus::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys); str << r; if (i!=numAnnuli_-1) str << ','; } str << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] <<','; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC); str << r << "\""; if (i!=numAnnuli_-1) str << ','; } str << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' ; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC); str << r << "\""; if (i!=numAnnuli_-1) str << ','; } str << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys); str << r; if (i!=numAnnuli_-1) str << ','; } str << ')'; } } } listPost(str, conj, strip); } void Annulus::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadiusX(ptr,sys,annuli_,numAnnuli_); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Annulus::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); for (int i=0; i<numAnnuli_-1; i++) { listCiaoPre(str); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ptr->mapLenFromRef(annuli_[i][0],Coord::PHYSICAL) << ',' << ptr->mapLenFromRef(annuli_[i+1][0],Coord::PHYSICAL) << ')'; listCiaoPost(str, strip); } } break; default: if (ptr->hasWCSCel(sys)) { char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; for (int i=0; i<numAnnuli_-1; i++) { listCiaoPre(str); str << type_ << '(' << ra << ',' << dec << ',' << ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCMIN) << '\'' << ',' << ptr->mapLenFromRef(annuli_[i+1][0],sys,Coord::ARCMIN) << '\'' << ')'; listCiaoPost(str, strip); } } } } void Annulus::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],Coord::IMAGE); str << r << ' '; } } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v[0] << "d " << v[1] <<"d"; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC); str << ' ' << r << '"'; } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << ra << ' ' << dec; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC); str << ' ' << r << '"'; } } break; } } } listProsPost(str, strip); } void Annulus::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { double r = ptr->mapLenFromRef(annuli_[i][0],Coord::IMAGE); str << r; if (i!=numAnnuli_-1) str << ','; } str << ')'; listSAOimagePost(str, strip); } // special composite funtionallity void Annulus::setComposite(const Matrix& mx, double aa) { center *= mx; updateBBox(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/inversescale.h�����������������������������������������������������������������0000644�0001750�0001750�00000002641�11700666270�016162� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __inversescale_h__ #define __inversescale_h__ #include <iostream> using namespace std; class InverseScale { protected: double* level_; int size_; public: InverseScale(int); InverseScale(int, double*); virtual ~InverseScale(); int size() {return size_;} double* level() {return level_;} double level(int i) {return level_[i];} friend ostream& operator<<(ostream&, const InverseScale&); }; class LinearInverseScale : public InverseScale { public: LinearInverseScale(int, double, double); }; class LogInverseScale : public InverseScale { public: LogInverseScale(int, double, double, double); }; class PowInverseScale : public InverseScale { public: PowInverseScale(int, double, double, double); }; class SqrtInverseScale : public InverseScale { public: SqrtInverseScale(int, double, double); }; class SquaredInverseScale : public InverseScale { public: SquaredInverseScale(int, double, double); }; class AsinhInverseScale : public InverseScale { public: AsinhInverseScale(int, double, double); }; class SinhInverseScale : public InverseScale { public: SinhInverseScale(int, double, double); }; class HistEquInverseScale : public InverseScale { public: HistEquInverseScale(int, double, double, double*, int); }; #endif �����������������������������������������������������������������������������������������������./saods9/saotk/frame/grid.C�������������������������������������������������������������������������0000644�0001750�0001750�00000001014�12001327760�014341� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid.h" #include "context.h" #include "fitsimage.h" extern "C" { #include "ast.h" } Grid::Grid(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, GridType type, const char* v) : system_(sys), sky_(sky), skyFormat_(format), type_(type) { vars_ = dupstr(v); } Grid::~Grid() { if (vars_) delete [] vars_; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame.C������������������������������������������������������������������������0000644�0001750�0001750�00000021034�12107012362�014506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame.h" #include "fitsimage.h" #include "ps.h" #include "sigbus.h" // Frame Member Functions Frame::Frame(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item) { context = new Context(); context->parent(this); currentContext = context; keyContext = context; keyContextSet =1; cmapID = 1; bias = 0.5; contrast = 1.0; colorCount = 0; colorScale = NULL; colorCells = NULL; indexCells = NULL; iisSaveRoot = 0; iisInteractive = 0; } Frame::~Frame() { if (context) delete context; if (colorScale) delete colorScale; if (colorCells) delete [] colorCells; if (indexCells) delete [] indexCells; } unsigned char* Frame::fillImage(int width, int height, Coord::InternalSystem sys) { // img unsigned char* img = new unsigned char[width*height*3]; { unsigned char* ptr = img; for (int jj=0; jj<height; jj++) for (int ii=0; ii<width; ii++) { *ptr++ = (unsigned char)bgColor->red; *ptr++ = (unsigned char)bgColor->green; *ptr++ = (unsigned char)bgColor->blue; } } if (!context->cfits) return img; // basics int length = colorScale->size() - 1; const unsigned char* table = colorScale->psColors(); FitsImage* sptr = context->cfits; int mosaic = isMosaic(); // variable double* mm = sptr->matrixToData(sys).mm(); FitsBound* params = sptr->getDataParams(context->frScale.scanMode()); int srcw = sptr->width(); double ll = sptr->getLowDouble(); double hh = sptr->getHighDouble(); double diff = hh - ll; // main loop unsigned char* dest = img; SETSIGBUS for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest+=3) { if (mosaic) { sptr = context->cfits; mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); if (isfinite(value)) { if (value <= ll) { *(dest+2) = table[0]; *(dest+1) = table[1]; *dest = table[2]; } else if (value >= hh) { *(dest+2) = table[length*3]; *(dest+1) = table[length*3+1]; *dest = table[length*3+2]; } else { int l = (int)(((value - ll)/diff * length) + .5); *(dest+2) = table[l*3]; *(dest+1) = table[l*3+1]; *dest = table[l*3+2]; } } else { *(dest+2) = nanColor->blue; *(dest+1) = nanColor->green; *dest = nanColor->red; } break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } } } } while (mosaic && sptr); } } CLEARSIGBUS return img; } int Frame::isIIS() { return context->cfits && context->cfits->isIIS(); } void Frame::reset() { cmapID = 1; bias = 0.5; contrast = 1.0; context->frScale.resetScanMode(); context->updateClip(); Base::reset(); } void Frame::updateColorCells(unsigned short* index, unsigned char* cells, int cnt) { // the colorbar widget will pass us a pointer to the indexCells colorCount = cnt; if (indexCells) delete [] indexCells; indexCells = new unsigned short[cnt]; if (!indexCells) { internalError("Unable to Alloc indexCells"); return; } memcpy(indexCells, index, cnt*sizeof(unsigned short)); // copy the rgb vales to the colorCells array (for postscript printing) if (colorCells) delete [] colorCells; colorCells = new unsigned char[cnt*3]; if (!colorCells) { internalError("Unable to Alloc colorCells"); return; } memcpy(colorCells, cells, cnt*3); } void Frame::unloadFits() { if (DebugPerf) cerr << "Frame::unloadFits" << endl; // clean up from iis if needed if (isIIS()) { context->frScale.setClipMode(FrScale::MINMAX); context->frScale.setMMMode(FrScale::SAMPLE); context->frScale.setULow(DEFAULTLOW); context->frScale.setUHigh(DEFAULTHIGH); context->frScale.setColorScaleType(FrScale::LINEARSCALE); } context->unload(); FrameBase::unloadFits(); } // Commands void Frame::getColorbarCmd() { ostringstream str; str << cmapID << ' ' << bias << ' ' << contrast << ' ' << invert << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame::getRGBChannelCmd() { Tcl_AppendResult(interp, "red", NULL); } void Frame::getRGBViewCmd() { Tcl_AppendResult(interp, "1 1 1", NULL); } void Frame::getRGBSystemCmd() { Tcl_AppendResult(interp, "image", NULL); } void Frame::getTypeCmd() { Tcl_AppendResult(interp, "base", NULL); } void Frame::iisCmd(int width, int height) { unloadAllFits(); // force clip mode to user between 1 to 200 context->frScale.setClipMode(FrScale::USERCLIP); context->frScale.setMMMode(FrScale::SCAN); context->frScale.setULow(IISMIN); context->frScale.setUHigh(IISMAX); context->frScale.setColorScaleType(FrScale::IISSCALE); FitsImage* img = new FitsImageIIS(this, width, height); loadDone(currentContext->load(this, ALLOC, "", img, IMG),IMG); } void Frame::iisEraseCmd() { if (context->cfits) ((FitsImageIIS*)context->cfits)->iisErase(); } void Frame::iisGetCmd(char* dest, int xx, int yy, int dx, int dy) { if (context->cfits) { char* buf = ((FitsImageIIS*)context->cfits)->iisGet(xx,yy,dx,dy); memcpy(dest, buf, dx*dy); delete [] buf; } } void Frame::iisSetCmd(const char* src, int xx, int yy, int dx, int dy) { if (context->cfits) ((FitsImageIIS*)context->cfits)->iisSet(src, xx, yy, dx, dy); } void Frame::iisWCSCmd(const Matrix& mx, const Vector& z, int zt) { if (context->cfits) ((FitsImageIIS*)context->cfits)->iisWCS(mx, z, zt); } void Frame::savePhotoCmd(const char* ph) { FitsImage* fits = currentContext->cfits; if (!fits) return; // basics int length = colorScale->size() - 1; const unsigned char* table = colorScale->psColors(); // variable FitsBound* params = fits->getDataParams(context->frScale.scanMode()); double ll = fits->getLowDouble(); double hh = fits->getHighDouble(); double diff = hh - ll; int width = params->xmax - params->xmin; int height = params->ymax - params->ymin; // photo if (*ph == '\0') { Tcl_AppendResult(interp, "bad image name ", NULL); return; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, ph); if (!photo) { Tcl_AppendResult(interp, "bad image handle ", NULL); return; } if (Tk_PhotoSetSize(interp, photo, width, height) != TCL_OK) { Tcl_AppendResult(interp, "bad photo set size ", NULL); return; } Tk_PhotoBlank(photo); Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block ", NULL); return; } if (block.pixelSize<4) { Tcl_AppendResult(interp, "bad pixel size ", NULL); return; } // main loop SETSIGBUS unsigned char* dest = block.pixelPtr; for (long jj=params->ymax-1; jj>=params->ymin; jj--) { for (long ii=params->xmin; ii<params->xmax; ii++, dest += block.pixelSize) { double value = fits->getValueDouble(Vector(ii,jj)); if (isfinite(value)) { if (value <= ll) { *(dest+block.offset[0]) = table[2]; *(dest+block.offset[1]) = table[1]; *(dest+block.offset[2]) = table[0]; *(dest+block.offset[3]) = 255; } else if (value >= hh) { *(dest+block.offset[0]) = table[length*3+2]; *(dest+block.offset[1]) = table[length*3+1]; *(dest+block.offset[2]) = table[length*3]; *(dest+block.offset[3]) = 255; } else { int l = (int)(((value - ll)/diff * length) + .5); *(dest+block.offset[0]) = table[l*3+2]; *(dest+block.offset[1]) = table[l*3+1]; *(dest+block.offset[2]) = table[l*3]; *(dest+block.offset[3]) = 255; } } else { *(dest+block.offset[0]) = nanColor->red; *(dest+block.offset[1]) = nanColor->green; *(dest+block.offset[2]) = nanColor->blue; *(dest+block.offset[3]) = 255; } } } CLEARSIGBUS if (Tk_PhotoPutBlock(interp, photo, &block, 0, 0, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { Tcl_AppendResult(interp, "bad put block ", NULL); return; } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ciaoparser.H�������������������������������������������������������������������0000644�0001750�0001750�00000005733�11626771517�015604� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, ANGDEGREE = 260, ARCMINUTE = 261, ARCSECOND = 262, SEXSTR = 263, HMSSTR = 264, DMSSTR = 265, EOF_ = 266, ANNULUS_ = 267, BOX_ = 268, CIRCLE_ = 269, DEBUG_ = 270, ELLIPSE_ = 271, OFF_ = 272, ON_ = 273, PIE_ = 274, POINT_ = 275, POLYGON_ = 276, ROTBOX_ = 277, VERSION_ = 278 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define ANGDEGREE 260 #define ARCMINUTE 261 #define ARCSECOND 262 #define SEXSTR 263 #define HMSSTR 264 #define DMSSTR 265 #define EOF_ 266 #define ANNULUS_ 267 #define BOX_ 268 #define CIRCLE_ 269 #define DEBUG_ 270 #define ELLIPSE_ 271 #define OFF_ 272 #define ON_ 273 #define PIE_ 274 #define POINT_ 275 #define POLYGON_ 276 #define ROTBOX_ 277 #define VERSION_ 278 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 43 "ciaoparser.Y" { #define CIAOBUFSIZE 2048 double real; int integer; char str[CIAOBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 103 "ciaoparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �������������������������������������./saods9/saotk/frame/sigbus.h�����������������������������������������������������������������������0000644�0001750�0001750�00000001745�12114224330�014762� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __sigbus_h__ #define __sigbus_h__ // Signal Support #include <setjmp.h> #include <signal.h> static sigjmp_buf crashbuf; static struct sigaction sigact, osigbus, osigsegv; static void crashHandler(int dummy) { siglongjmp(crashbuf, 1); } #define INTERP interp #define SETSIGBUS \ if (sigsetjmp(crashbuf, 1)) { \ Tcl_SetVar2(INTERP, "ds9", "msg", "A SIGBUS or SIGSEGV error has been received.", TCL_GLOBAL_ONLY); \ Tcl_SetVar2(INTERP, "ds9", "msg,level", "error", TCL_GLOBAL_ONLY); \ } \ else { \ sigact.sa_handler = crashHandler; \ sigemptyset(&sigact.sa_mask); \ sigact.sa_flags = 0; \ sigaction(SIGSEGV, &sigact, &osigsegv); \ sigaction(SIGBUS, &sigact, &osigbus); #define CLEARSIGBUS \ } \ sigaction(SIGSEGV, &osigsegv, NULL); \ sigaction(SIGBUS, &osigbus, NULL); #endif ���������������������������./saods9/saotk/frame/Makefile�����������������������������������������������������������������������0000644�0001750�0001750�00000005763�12042543346�014774� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include include ../../make.pkgs CXXFLAGS = $(CXXOPT) -w \ -I. -I.. -I../widget -I../vector -I../list -I../fitsy++ -I../util \ -I../../include -I$(X11INCLUDE) \ -I../../$(FUNTOOLSDIR)/util \ -I/usr/include/libxml2 \ -I../../$(ASTDIR) SS = \ annulus.C \ base.C \ basecommand.C \ basebox.C \ baseellipse.C \ baseline.C \ basemarker.C \ basepanda.C \ box.C \ boxannulus.C \ bpanda.C \ callback.C \ circle.C \ colorscale.C \ colorscalergb.C \ colorscaletrue8.C \ colorscaletrue16.C \ colorscaletrue24.C \ colorscaletrue32.C \ compass.C \ composite.C \ context.C \ contour.C \ coord.C \ cpanda.C \ ellipse.C \ ellipseannulus.C \ epanda.C \ fitsanalysis.C \ fitsbin.C \ fitscompress.C \ fitsdata.C \ fitshealpix.C \ fitsimage.C \ fitsmask.C \ fitsmap.C \ fitsnrrd.C \ frame.C \ frame3d.C \ framebase.C \ frame3dbase.C \ framergb.C \ framergbtruecolor.C \ framergbtruecolor8.C \ framergbtruecolor16.C \ framergbtruecolor24.C \ frametrue.C \ frame3dtrue.C \ frametruecolor.C \ frame3dtruecolor.C \ frametruecolor8.C \ frametruecolor16.C \ frametruecolor24.C \ frame3dtruecolor8.C \ frame3dtruecolor16.C \ frame3dtruecolor24.C \ frblt.C \ frcommand.C \ fr3dcommand.C \ frload.C \ frmap.C \ fr3dmap.C \ frmarker.C \ frmarkerxml.C \ frsave.C \ frscale.C \ fvcontour.C \ grid.C \ grid2d.C \ grid25d.C \ grid3d.C \ inversescale.C \ line.C \ marker.C \ point.C \ polygon.C \ projection.C \ ruler.C \ tag.C \ text.C \ vect.C ifeq ($(OS),unix) SSP = \ colorscalepseudo8.C \ framepseudo.C \ framepseudocolor.C \ framepseudocolor8.C endif SRC = $(SS) $(SSP) \ ciaoparser.C \ ciaolex.C \ ds9parser.C \ ds9lex.C \ parser.C \ lex.C \ prosparser.C \ proslex.C \ saoparser.C \ saolex.C \ tngparser.C \ tnglex.C \ xyparser.C \ xylex.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o parser.output ds9parser.output ciaoparser.output prosparser.output tngparser.output saoparser.output xyparser.output ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif parsers : ciaoparser ds9parser parser prosparser saoparser tngparser xyparser ciaoparser : FORCE bison -d -p ciao -o ciaoparser.C ciaoparser.Y flex -Pciao -ociaolex.C ciaolex.L ds9parser : FORCE bison -d -p mk -o ds9parser.C ds9parser.Y flex -Pmk -ods9lex.C ds9lex.L parser : FORCE bison -d -p fr -o parser.C parser.Y flex -Pfr -olex.C lex.L prosparser : FORCE bison -d -p pros -o prosparser.C prosparser.Y flex -Ppros -oproslex.C proslex.L saoparser : FORCE bison -d -p sao -o saoparser.C saoparser.Y flex -Psao -osaolex.C saolex.L tngparser : FORCE bison -d -p tng -o tngparser.C tngparser.Y flex -Ptng -otnglex.C tnglex.L xyparser : FORCE bison -d -p xy -o xyparser.C xyparser.Y flex -Pxy -oxylex.C xylex.L FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SS:.C=.d) endif �������������./saods9/saotk/frame/frame3dtruecolor8.h������������������������������������������������������������0000644�0001750�0001750�00000001300�11700666267�017044� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3dtruecolor8_h__ #define __frame3dtruecolor8_h__ #include "frame3dtruecolor.h" #include "truecolor8.h" class Frame3dTrueColor8 : public Frame3dTrueColor, public TrueColor8 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor8::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor8::encodeTrueColor(src, ximage);} void updateColorScale(); public: Frame3dTrueColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~Frame3dTrueColor8(); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor16.h�����������������������������������������������������������0000644�0001750�0001750�00000001310�11700666267�017124� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3dtruecolor16_h__ #define __frame3dtruecolor16_h__ #include "frame3dtruecolor.h" #include "truecolor16.h" class Frame3dTrueColor16 : public Frame3dTrueColor, public TrueColor16 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor16::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor16::encodeTrueColor(src, ximage);} void updateColorScale(); public: Frame3dTrueColor16(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~Frame3dTrueColor16(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscalepseudo8.h������������������������������������������������������������0000644�0001750�0001750�00000004200�11725514403�017123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscalepseudo8_h__ #define __colorscalepseudo8_h__ #include "colorscale.h" class Base; class ColorScalePseudoColor8 : public virtual ColorScale { public: ColorScalePseudoColor8(int); virtual ~ColorScalePseudoColor8(); }; class LinearScalePseudoColor8 : public virtual ColorScale, public LinearScale, public ColorScalePseudoColor8 { public: LinearScalePseudoColor8(int, unsigned short*, unsigned char*, int); }; class LogScalePseudoColor8 : public virtual ColorScale, public LogScale, public ColorScalePseudoColor8 { public: LogScalePseudoColor8(int, unsigned short*, unsigned char*, int, double); }; class PowScalePseudoColor8 : public virtual ColorScale, public PowScale, public ColorScalePseudoColor8 { public: PowScalePseudoColor8(int, unsigned short*, unsigned char*, int, double); }; class SqrtScalePseudoColor8 : public virtual ColorScale, public SqrtScale, public ColorScalePseudoColor8 { public: SqrtScalePseudoColor8(int, unsigned short*, unsigned char*, int); }; class SquaredScalePseudoColor8 : public virtual ColorScale, public SquaredScale, public ColorScalePseudoColor8 { public: SquaredScalePseudoColor8(int, unsigned short*, unsigned char*, int); }; class AsinhScalePseudoColor8 : public virtual ColorScale, public AsinhScale, public ColorScalePseudoColor8 { public: AsinhScalePseudoColor8(int, unsigned short*, unsigned char*, int); }; class SinhScalePseudoColor8 : public virtual ColorScale, public SinhScale, public ColorScalePseudoColor8 { public: SinhScalePseudoColor8(int, unsigned short*, unsigned char*, int); }; class IISScalePseudoColor8 : public virtual ColorScale, public IISScale, public ColorScalePseudoColor8 { public: IISScalePseudoColor8(Base*,unsigned short*, unsigned char*, int); }; class HistEquScalePseudoColor8 : public virtual ColorScale, public HistEquScale, public ColorScalePseudoColor8 { public: HistEquScalePseudoColor8(int, unsigned short*, unsigned char*, int, double*, int); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/circle.h�����������������������������������������������������������������������0000644�0001750�0001750�00000002604�12030663652�014735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __circle_h__ #define __circle_h__ #include "baseellipse.h" class Circle : public BaseEllipse { public: Circle(const Circle&); Circle(Base* p, const Vector& ctr, double r, const char* clr, int *dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Circle(*this);} void edit(const Vector&, int); void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} void analysis(AnalysisTask, int); void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); virtual void listCiao(ostream&, Coord::CoordSystem, int); virtual void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOimage(ostream&, int); // special composite funtionality void setComposite(const Matrix&, double); }; #endif ����������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid2d.C�����������������������������������������������������������������������0000644�0001750�0001750�00000007063�12001331444�014573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid2d.h" #include "context.h" #include "framebase.h" #include "fitsimage.h" extern "C" { #include "ast.h" } extern Grid2dBase* astGrid2dPtr; Grid2d::Grid2d(Widget* p, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, GridType t, const char* o, const char* v) : Grid(sys, sky, format, t, v), Grid2dBase(p,o) {} Grid2d::~Grid2d() {} int Grid2d::doit(RenderMode rm) { FrameBase* pp = (FrameBase*)parent_; matrix_ = pp->widgetToCanvas; gc_ = pp->gridGC; pixmap_ = pp->pixmap; renderMode_ = rm; Context* context = pp->keyContext; FitsImage* fits = context->fits; if (!fits) return 1; int width = fits->width(); int height = fits->height(); astClearStatus; // just to make sure astBegin; // start memory management AstFrameSet* frameSet = NULL; AstPlot* plot = NULL; if (!(frameSet = astFrameSet(astFrame(2,"Domain=WIDGET"),""))) { astEnd; return 0; } // map from Widget to Image matrixMap(frameSet,fits->widgetToImage,"Domain=IMAGE"); switch (system_) { case Coord::IMAGE: break; case Coord::PHYSICAL: matrixMap(frameSet,fits->imageToPhysical,"Domain=PHYSICAL"); break; case Coord::AMPLIFIER: matrixMap(frameSet,fits->imageToAmplifier,"Domain=AMPLIFIER"); break; case Coord::DETECTOR: matrixMap(frameSet,fits->imageToDetector,"Domain=DETECTOR"); break; default: { AstFrameSet* wcsfs = (AstFrameSet*)astCopy(fits->getAST(system_)); // set desired skyformat if (astIsASkyFrame(astGetFrame(wcsfs, AST__CURRENT))) fits->setAstSkyFrame(wcsfs, sky_); // add wcs to frameset // this will link frame 2 of frameset to frame 3 wcs with unitMap // set the current of frameset to last astInvert(wcsfs); astAddFrame(frameSet,2,astUnitMap(2,""),wcsfs); astSetI(frameSet,"current",astGetI(frameSet,"nframe")); } } astSet(frameSet,"Title=%s", " "); // create astPlot float gbox[4]; double pbox[4]; switch (type_) { case ANALYSIS: { gbox[0] = pbox[0] = 0; gbox[1] = pbox[1] = 0; gbox[2] = pbox[2] = pp->options->width-1; gbox[3] = pbox[3] = pp->options->height-1; } break; case PUBLICATION: { Matrix mm = fits->imageToWidget; BBox b = pp->imageBBox(pp->context->frScale.scanMode()); Vector ll = b.ll * mm; Vector lr = b.lr() * mm; Vector ur = b.ur * mm; Vector ul = b.ul() * mm; BBox bb(ll,ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); gbox[0] = pbox[0] = bb.ll[0]; gbox[1] = pbox[1] = bb.ll[1]; gbox[2] = pbox[2] = bb.ur[0]; gbox[3] = pbox[3] = bb.ur[1]; } break; } // and now create astGrid astGrid2dPtr = this; plot = astPlot(frameSet, gbox, pbox, option_); astGrid(plot); astEnd; // now, clean up memory astGrid2dPtr =NULL; return 1; } int Grid2d::matrixMap(void* fs, Matrix& mx, const char* str) { AstFrameSet* frameSet = (AstFrameSet*)fs; double ss[] = {mx.matrix(0,0),mx.matrix(1,0), mx.matrix(0,1),mx.matrix(1,1)}; double tt[] = {mx.matrix(2,0),mx.matrix(2,1)}; AstMatrixMap* mm; if (!(mm= astMatrixMap(2, 2, 0, ss, ""))) return 0; AstShiftMap* sm; if (!(sm = astShiftMap(2, tt, ""))) return 0; AstCmpMap* cmp; if (!(cmp = astCmpMap(mm, sm, 1, ""))) return 0; astAddFrame(frameSet, AST__CURRENT, cmp, astFrame(2, str)); return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framebase.C��������������������������������������������������������������������0000644�0001750�0001750�00000010611�11775376665�015375� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "framebase.h" #include "fitsimage.h" #include "marker.h" #include "context.h" #include "ps.h" #include "sigbus.h" // Public FrameBase::FrameBase(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Base(i, c, item) { rotateSrcXM = NULL; rotateDestXM = NULL; rotatePM = 0; } FrameBase::~FrameBase() { } double FrameBase::calcZoomPanner() { if (!(keyContext->fits && pannerPixmap)) return 1; Vector src = imageSize(keyContext->frScale.datasec() ? FrScale::DATASEC : FrScale::IMGSEC); return calcZoom(src, Vector(pannerWidth,pannerHeight)); } void FrameBase::x11MagnifierCursor(const Vector& vv) { // first, the inner color'd box Vector uu = vv * canvasToUser; Matrix mm = Translate(-uu) * Rotate(wcsRotation) * Rotate(rotation) * Scale(zoom_) * Scale(magnifierZoom_) * Translate(magnifierWidth/2., magnifierHeight/2.); Vector c[5]; c[0] = (uu + Vector(-.5,-.5)) * mm; c[1] = (uu + Vector( .5,-.5)) * mm; c[2] = (uu + Vector( .5, .5)) * mm; c[3] = (uu + Vector(-.5, .5)) * mm; c[4] = c[0]; XPoint pts[5]; for (int ii=0; ii<5; ii++) { Vector z = c[ii].round(); pts[ii].x = (short)z[0]; pts[ii].y = (short)z[1]; } XSetForeground(display, gc, getColor(magnifierColorName)); XDrawLines(display, magnifierPixmap, gc, pts, 5, CoordModeOrigin); // now, the outer black box Matrix nn = Translate(-(uu * mm)) * Rotate(-rotation) * Rotate(-wcsRotation); Matrix oo = nn.invert(); Vector dd[5]; for (int ii=0; ii<5; ii++) dd[ii] = c[ii] * nn; dd[0]+=Vector(-1,-1); dd[1]+=Vector( 1,-1); dd[2]+=Vector( 1, 1); dd[3]+=Vector(-1, 1); dd[4]=dd[0]; for (int ii=0; ii<5; ii++) { dd[ii] = dd[ii] * oo; Vector zz = dd[ii].round(); pts[ii].x = (int)zz[0]; pts[ii].y = (int)zz[1]; } XSetForeground(display, gc, getColor("black")); XDrawLines(display, magnifierPixmap, gc, pts, 5, CoordModeOrigin); } void FrameBase::setBinCursor() { if (context->cfits) context->cfits->setBinCursor(cursor); } void FrameBase::updateBin(const Matrix& mx) { // Note: cursor is in REF coords, imageCenter() in IMAGE coords cursor = imageCenter(FrScale::IMGSEC); Base::updateBin(mx); } void FrameBase::updatePanner() { Base::updatePanner(); if (usePanner) { ostringstream str; str << pannerName << " update " << (void*)pannerPixmap << ";"; // calculate bbox Vector ll = Vector(0,0) * widgetToPanner; Vector lr = Vector(options->width,0) * widgetToPanner; Vector ur = Vector(options->width,options->height) * widgetToPanner; Vector ul = Vector(0,options->height) * widgetToPanner; str << pannerName << " update bbox " << ll << lr << ur << ul << ";"; // calculate image compass vectors Matrix mm = FlipY() * wcsOrientationMatrix * Rotate(wcsRotation) * orientationMatrix * Rotate(rotation); Vector xx = (Vector(1,0)*mm).normalize(); Vector yy = (Vector(0,1)*mm).normalize(); str << pannerName << " update image compass " << xx << yy << ";"; if (keyContext->fits && keyContext->fits->hasWCS(wcsSystem_)) { Vector orpix = keyContext->fits->center(); Vector orval=keyContext->fits->pix2wcs(orpix, wcsSystem_, wcsSky_); Vector orpix2 = keyContext->fits->wcs2pix(orval, wcsSystem_,wcsSky_); Vector delta = keyContext->fits->getWCScdelt(wcsSystem_).abs(); Vector npix = keyContext->fits->wcs2pix(Vector(orval[0],orval[1]+delta[1]), wcsSystem_,wcsSky_); Vector north = ((npix-orpix2)*mm).normalize(); Vector epix = keyContext->fits->wcs2pix(Vector(orval[0]+delta[0],orval[1]), wcsSystem_,wcsSky_); Vector east = ((epix-orpix2)*mm).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) { north = (Vector(0,1)*mm).normalize(); east = (Vector(-1,0)*mm).normalize(); } str << pannerName << " update wcs compass " << north << east << ends; } else str << pannerName << " update wcs compass invalid" << ends; Tcl_Eval(interp, str.str().c_str()); } } �����������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/epanda.h�����������������������������������������������������������������������0000644�0001750�0001750�00000003715�12030663652�014730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __epanda_h__ #define __epanda_h__ #include "basepanda.h" #include "baseellipse.h" class Epanda : public BasePanda, public BaseEllipse { private: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif void updateHandles(); void listA(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listB(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); int isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa); public: Epanda(const Epanda&); Epanda(Base* p, const Vector& ctr, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Epanda(Base* p, const Vector& ctr, int an, double* a, int rn, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Epanda(*this);} void edit(const Vector&, int); void editEnd(); int addAnnuli(const Vector&); int addAngles(const Vector&); void setAnglesAnnuli(double, double, int, Vector, Vector, int); void setAnglesAnnuli(const double*, int, const Vector*, int); void deleteAnglesAnnuli(int h); void analysis(AnalysisTask, int); void analysisPanda(Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); }; #endif ���������������������������������������������������./saods9/saotk/frame/ellipseannulus.C���������������������������������������������������������������0000644�0001750�0001750�00000026660�12030663652�016502� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "ellipseannulus.h" #include "fitsimage.h" EllipseAnnulus::EllipseAnnulus(const EllipseAnnulus& a) : BaseEllipse(a) {} EllipseAnnulus::EllipseAnnulus(Base* p, const Vector& ctr, const Vector& r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = 1; annuli_ = new Vector[1]; annuli_[0] = r; strcpy(type_,"ellipseannulus"); numHandle = 4; updateBBox(); } EllipseAnnulus::EllipseAnnulus(Base* p, const Vector& ctr, const Vector& inner,const Vector& outer,int num, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = num+1; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((outer-inner)/num)*i+inner; strcpy(type_, "ellipseannulus"); numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } EllipseAnnulus::EllipseAnnulus(Base* p, const Vector& ctr, int an, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = an; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = r[i]; sortAnnuli(); strcpy(type_, "ellipseannulus"); numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } void EllipseAnnulus::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); Vector n = v * mm; if (h<5) { // don't go thru the center if (n[0]!=0 && n[1]!=0) { Vector o = annuli_[numAnnuli_-1]; for (int i=0; i<numAnnuli_; i++) { annuli_[i][0] *= fabs(n[0]/o[0]); annuli_[i][1] *= fabs(n[1]/o[1]); } } } else { // we must have some length double l = n.length(); annuli_[h-5] = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; } updateBBox(); doCallBack(CallBack::EDITCB); } void EllipseAnnulus::editEnd() { sortAnnuli(); updateBBox(); doCallBack(CallBack::EDITENDCB); } int EllipseAnnulus::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm).length(); Vector rr = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; return insertAnnuli(rr); } void EllipseAnnulus::analysis(AnalysisTask mm, int which) { switch (mm) { case RADIAL: if (!analysisRadial_ && which) { addCallBack(CallBack::MOVECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisRadialCB_[1], parent->options->cmdName); } if (analysisRadial_ && !which) { deleteCallBack(CallBack::MOVECB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITCB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisRadialCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisRadialCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisRadialCB_[0]); deleteCallBack(CallBack::DELETECB, analysisRadialCB_[1]); } analysisRadial_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void EllipseAnnulus::analysisRadial(char* xname, char* yname, char* ename, Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv = annuli_[ii]; bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } int num = parent->markerAnalysisRadial(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, bb, sys); analysisRadialResult(xname, yname, ename, xx, yy, ee, num); } void EllipseAnnulus::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv = annuli_[ii]; bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } parent->markerAnalysisStats(this, str, numAnnuli_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void EllipseAnnulus::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << "ellipse(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys); str << r[0] << ',' << r[1] << ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << "ellipse(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << r[0] << "\"" << ',' << r[1] << "\"" << ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << "ellipse(" << ra << ',' << dec << ',' ; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << r[0] << "\""<< ',' << r[1] << "\""<< ','; } str << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << "ellipse(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys); str << r[0] << ',' << r[1] << ','; } str << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void EllipseAnnulus::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_,numAnnuli_); XMLRowAng(sys,sky); XMLRowProps(ptr,sys); XMLRowEnd(str); } void EllipseAnnulus::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],Coord::IMAGE); str << "ellipse " << setprecision(8) << v << r << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],Coord::IMAGE); str << " & !ellipse " << setprecision(8) << v << r1<<radToDeg(angle); } listProsPost(str, strip); } } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << "ellipse " << setprecision(8) << v[0] << "d " << v[1]<<"d " << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); str << " & !ellipse " << setprecision(8) << v[0] << "d " << v[1] << "d " << r1[0] << "\" " << r1[1] << "\" " << radToDeg(angle); } listProsPost(str, strip); } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << "ellipse " << ra << ' ' << dec << ' ' << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); str << " & !ellipse " << ra << ' ' << dec << ' ' << r1[0] << "\" " << r1[1] << "\" " << radToDeg(angle); } listProsPost(str, strip); } } break; } } } } void EllipseAnnulus::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); for (int i=0; i<numAnnuli_; i++) { Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << "ellipse(" << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[i][0] << ',' << annuli_[i][1] << ',' << radToDeg(angle) << ')'; if (i!=0) str << " & !ellipse(" << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[i-1][0] << ',' << annuli_[i-1][1] << ',' << radToDeg(angle) << ')'; listSAOimagePost(str, strip); } } ��������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor16.C�����������������������������������������������������������0000644�0001750�0001750�00000012741�11700666267�017071� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame3dtruecolor16.h" #include "colorscaletrue16.h" #include "util.h" // Tk Canvas Widget Function Declarations int Frame3dTrueColor16CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Frame3dTrueColor16 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frame3dTrueColor16Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame3d", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frame3dTrueColor16Type = { (char*)"frame3dtruecolor16", // name sizeof(WidgetOptions), // item size Frame3dTrueColor16CreateProc, // configProc frame3dTrueColor16Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int Frame3dTrueColor16_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frame3dTrueColor16Type); return TCL_OK; } int Frame3dTrueColor16CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { Frame3dTrueColor16* frame = new Frame3dTrueColor16(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // Frame3dTrueColor16 Member Functions Frame3dTrueColor16::Frame3dTrueColor16(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i,c,item), Frame3dTrueColor(i,c,item), TrueColor16(visual) { configSpecs = frame3dTrueColor16Specs; // frame configure options } Frame3dTrueColor16::~Frame3dTrueColor16() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void Frame3dTrueColor16::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells) return; if (colorScale) delete colorScale; switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor16(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor16(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } �������������������������������./saods9/saotk/frame/annulus.h����������������������������������������������������������������������0000644�0001750�0001750�00000003074�12030663652�015163� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __annulus_h__ #define __annulus_h__ #include "baseellipse.h" class Annulus : public BaseEllipse { public: Annulus(const Annulus&); Annulus(Base* p, const Vector& ctr, double inner, double outer, int num, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Annulus(Base* p, const Vector& ctr, int rn, double* r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Annulus(*this);} void edit(const Vector&, int); void editEnd(); int addAnnuli(const Vector&); void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} void analysis(AnalysisTask, int); void analysisRadial(char*, char*, char*, Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listCiao(ostream&, Coord::CoordSystem, int); void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void listSAOimage(ostream&, int); // special composite funtionality void setComposite(const Matrix&, double); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/lex.L��������������������������������������������������������������������������0000644�0001750�0001750�00000024661�12076042210�014226� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "parser.H" extern YYSTYPE* frlval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% about {return ABOUT_;} aip {return AIP_;} alloc {return ALLOC_;} allocgz {return ALLOCGZ_;} align {return ALIGN_;} all {return ALL_;} alt {return ALT_;} amplifier {return AMPLIFIER_;} analysis {return ANALYSIS_;} angle {return ANGLE_;} annulus {return ANNULUS_;} append {return APPEND_;} arcmin {return ARCMIN_;} arcsec {return ARCSEC_;} array {return ARRAY_;} arrow {return ARROW_;} asinh {return ASINH_;} ast {return AST_;} auto {return AUTO_;} aux {return AUX_;} average {return AVERAGE_;} b1950 {return B1950_;} back {return BACK_;} base {return BASE_;} bbox {return BBOX_;} begin {return BEGIN_;} bg {return BG_;} big {return BIGENDIAN_;} bigendian {return BIGENDIAN_;} bin {return BIN_;} bitpix {return BITPIX_;} blt {return BLT_;} block {return BLOCK_;} border {return BORDER_;} box {return BOX_;} boxannulus {return BOXANNULUS_;} boxcar {return BOXCAR_;} boxcircle {return BOXCIRCLE_;} bpanda {return BPANDA_;} buffer {return BUFFER_;} bw {return BW_;} callback {return CALLBACK_;} canvas {return CANVAS_;} catalog {return CATALOG_;} celestrial {return CELESTRIAL_;} center {return CENTER_;} centroid {return CENTROID_;} channel {return CHANNEL_;} ciao {return CIAO_;} circle {return CIRCLE_;} clear {return CLEAR_;} clip {return CLIP_;} color {return COLOR_;} colorbar {return COLORBAR_;} colormap {return COLORMAP_;} colorscale {return COLORSCALE_;} colorspace {return COLORSPACE_;} cols {return COLS_;} column {return COLUMN_;} command {return COMMAND_;} compass {return COMPASS_;} composite {return COMPOSITE_;} compress {return COMPRESS_;} contour {return CONTOUR_;} contrast {return CONTRAST_;} coordinates {return COORDINATES_;} copy {return COPY_;} count {return COUNT_;} crop {return CROP_;} cross {return CROSS_;} cpanda {return CPANDA_;} create {return CREATE_;} crosshair {return CROSSHAIR_;} cube {return CUBE_;} cursor {return CURSOR_;} cut {return CUT_;} cmyk {return CMYK_;} dash {return DASH_;} dashlist {return DASHLIST_;} data {return DATA_;} datamin {return DATAMIN_;} datasec {return DATASEC_;} debug {return DEBUG_;} degrees {return DEGREES_;} default {return DEFAULT_;} delete {return DELETE_;} depth {return DEPTH_;} detector {return DETECTOR_;} diamond {return DIAMOND_;} dim {return DIM_;} ds9 {return DS9_;} ecliptic {return ECLIPTIC_;} ellipse {return ELLIPSE_;} ellipseannulus {return ELLIPSEANNULUS_;} edit {return EDIT_;} end {return END_;} epanda {return EPANDA_;} equatorial {return EQUATORIAL_;} erase {return ERASE_;} ext {return EXT_;} factor {return FACTOR_;} false {return FALSE_;} file {return FILE_;} filter {return FILTER_;} fit {return FIT_;} fits {return FITS_;} fitsy {return FITSY_;} fixed {return FIXED_;} fk4 {return FK4_;} fk4-no-e {return FK4_NO_E_;} fk5 {return FK5_;} font {return FONT_;} from {return FROM_;} front {return FRONT_;} full {return FULL_;} function {return FUNCTION_;} galactic {return GALACTIC_;} gaussian {return GAUSSIAN_;} get {return GET_;} global {return GLOBAL_;} graphics {return GRAPHICS_;} gray {return GRAY_;} grid {return GRID_;} gz {return GZ_;} handle {return HANDLE_;} has {return HAS_;} head {return HEAD_;} header {return HEADER_;} height {return HEIGHT_;} helioecliptic {return HELIOECLIPTIC_;} hide {return HIDE_;} high {return HIGH_;} highlite {return HIGHLITE_;} histequ {return HISTEQU_;} histogram {return HISTOGRAM_;} horizontal {return HORIZONTAL_;} icrs {return ICRS_;} id {return ID_;} iis {return IIS_;} image {return IMAGE_;} include {return INCLUDE_;} incr {return INCR_;} info {return INFO_;} integer {return INTEGER_;} iteration {return ITERATION_;} iraf {return IRAF_;} irafmin {return IRAFMIN_;} j2000 {return J2000_;} key {return KEY_;} keyword {return KEYWORD_;} label {return LABEL_;} length {return LENGTH_;} level {return LEVEL_;} little {return LITTLEENDIAN_;} littleendian {return LITTLEENDIAN_;} line {return LINE_;} linear {return LINEAR_;} list {return LIST_;} load {return LOAD_;} local {return LOCAL_;} log {return LOG_;} low {return LOW_;} macosx {return MACOSX_;} magnifier {return MAGNIFIER_;} match {return MATCH_;} map {return MAP_;} mark {return MARK_;} marker {return MARKER_;} mask {return MASK_;} message {return MESSAGE_;} method {return METHOD_;} minmax {return MINMAX_;} mip {return MIP_;} mmap {return MMAP_;} mmapincr {return MMAPINCR_;} mode {return MODE_;} mosaic {return MOSAIC_;} motion {return MOTION_;} move {return MOVE_;} name {return NAME_;} nan {return NAN_;} native {return NATIVE_;} naxes {return NAXES_;} new {return NEW_;} next {return NEXT_;} no {return NO_;} none {return NONE_;} now {return NOW_;} nrrd {return NRRD_;} number {return NUMBER_;} object {return OBJECT_;} off {return OFF_;} on {return ON_;} only {return ONLY_;} option {return OPTION_;} orient {return ORIENT_;} pan {return PAN_;} panda {return CPANDA_;} panner {return PANNER_;} param {return PARAM_;} parser {return PARSER_;} paste {return PASTE_;} perf {return PERF_;} photo {return PHOTO_;} physical {return PHYSICAL_;} pixel {return PIXEL_;} plot2d {return PLOT2D_;} plot3d {return PLOT3D_;} point {return POINT_;} pointer {return POINTER_;} polygon {return POLYGON_;} postscript {return POSTSCRIPT_;} pow {return POW_;} print {return PRINT_;} preserve {return PRESERVE_;} projection {return PROJECTION_;} property {return PROPERTY_;} pros {return PROS_;} publication {return PUBLICATION_;} radial {return RADIAL_;} radius {return RADIUS_;} region {return REGION_;} replace {return REPLACE_;} resample {return RESAMPLE_;} reset {return RESET_;} resolution {return RESOLUTION_;} rgb {return RGB_;} root {return ROOT_;} rotate {return ROTATE_;} ruler {return RULER_;} sample {return SAMPLE_;} saoimage {return SAOIMAGE_;} saotng {return SAOTNG_;} save {return SAVE_;} scale {return SCALE_;} scan {return SCAN_;} scientific {return SCIENTIFIC_;} scope {return SCOPE_;} segment {return SEGMENT_;} select {return SELECT_;} set {return SET_;} sexagesimal {return SEXAGESIMAL_;} shape {return SHAPE_;} shared {return SHARED_;} shift {return SHIFT_;} shmid {return SHMID_;} show {return SHOW_;} sinh {return SINH_;} size {return SIZE_;} slice {return SLICE_;} smmap {return SMMAP_;} smooth {return SMOOTH_;} socket {return SOCKET_;} socketgz {return SOCKETGZ_;} source {return SOURCE_;} sqrt {return SQRT_;} squared {return SQUARED_;} sshared {return SSHARED_;} stats {return STATS_;} status {return STATUS_;} sum {return SUM_;} supergalactic {return SUPERGALACTIC_;} system {return SYSTEM_;} table {return TABLE_;} tag {return TAG_;} template {return TEMPLATE_;} text {return TEXT_;} threads {return THREADS_;} 3d {return THREED_;} threshold {return THRESHOLD_;} thick {return THICK_;} transparency {return TRANSPARENCY_;} to {return TO_;} toggle {return TOGGLE_;} tophat {return TOPHAT_;} true {return TRUE_;} type {return TYPE_;} undo {return UNDO_;} unload {return UNLOAD_;} unhighlite {return UNHIGHLITE_;} unselect {return UNSELECT_;} update {return UPDATE_;} user {return USER_;} value {return VALUE_;} var {return VAR_;} view {return VIEW_;} vector {return VECTOR_;} version {return VERSION_;} vertex {return VERTEX_;} vertical {return VERTICAL_;} warp {return WARP_;} wcs {return WCS_;} wcsa {return WCSA_;} wcsb {return WCSB_;} wcsc {return WCSC_;} wcsd {return WCSD_;} wcse {return WCSE_;} wcsf {return WCSF_;} wcsg {return WCSG_;} wcsh {return WCSH_;} wcsi {return WCSI_;} wcsj {return WCSJ_;} wcsk {return WCSK_;} wcsl {return WCSL_;} wcsm {return WCSM_;} wcsn {return WCSN_;} wcso {return WCSO_;} wcsp {return WCSP_;} wcsq {return WCSQ_;} wcsr {return WCSR_;} wcss {return WCSS_;} wcst {return WCST_;} wcsu {return WCSU_;} wcsv {return WCSV_;} wcsw {return WCSW_;} wcsx {return WCSX_;} wcsy {return WCSY_;} wcsz {return WCSZ_;} wcs0 {return WCS0_;} wfpc2 {return WFPC2_;} width {return WIDTH_;} win32 {return WIN32_;} xml {return XML_;} xy {return XY_;} yes {return YES_;} zmax {return ZMAX_;} zscale {return ZSCALE_;} zoom {return ZOOM_;} [+-]?{D}+ { // Integer frlval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number frlval->real = atof(yytext); return REAL; } 0[xX][0-9a-fA-F]+ { // Pointer frlval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } [+-]?{D}+"."?d | [+-]?{D}*"."{D}+d { // degrees yytext[yyleng-1] = '\0'; frlval->real = atof(yytext); return ANGDEGREE; } [+-]{D}+"."?r | [+-]{D}*"."{D}+r { // radians yytext[yyleng-1] = '\0'; frlval->real = atof(yytext); return ANGRADIAN; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // sexagesimal int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return SEXSTR; } [+-]?{D}+h{D}+m{D}+"."?s | [+-]?{D}+h{D}+m{D}*"."{D}+s { // HMS int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return HMSSTR; } [+-]?{D}+d{D}+m{D}+"."?s | [+-]?{D}+d{D}+m{D}*"."{D}+s { // DMS int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return DMSSTR; } \"[^\"]*\" | \'[^\']*\' { // Quoted String int ll = (yyleng-2)<(FRBUFSIZE-1) ? (yyleng-2):(FRBUFSIZE-1); strncpy(frlval->str,yytext+1,ll); // skip the " " frlval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}]*\} { // Quoted String int ll = (yyleng-2)<(FRBUFSIZE-1) ? (yyleng-2):(FRBUFSIZE-1); strncpy(frlval->str,yytext+1,ll); // skip the '{' frlval->str[ll] = '\0'; // Remove the '}' return STRING; } [!-~][!-~]+ { // General String-- at least 2 printable chars int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } . { // Else, return the char return toupper(yytext[0]); } %% �������������������������������������������������������������������������������./saods9/saotk/frame/fr3dcommand.C������������������������������������������������������������������0000644�0001750�0001750�00000032541�12011262056�015617� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "frame3dbase.h" #include "fitsimage.h" #include "context.h" #include "marker.h" #include "sigbus.h" void Frame3dBase::binToFitCmd() { if (!keyContext->fits) return; Vector3d dim(keyContext->fits->getHistDim(), keyContext->fits->binDepth()); double bf = 1/calcZoom3d(dim, Vector(options->width,options->height)); // round up to next power of 2 if (bf < 1) { keyContext->fits->setBinToFactor(Vector(1,1)); binFactor_ = Vector(1,1); } else { int p=1; while (p<bf) p*=2; keyContext->fits->setBinToFactor(Vector(p,p)); binFactor_ = Vector(p,p); } updateBin(keyContext->fits->updateHistCursor()); } void Frame3dBase::crop3dBeginCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; cropBegin = vv * Scale(zoom_).invert(); cropEnd = vv * Scale(zoom_).invert(); // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(keyContext->frScale.scanMode()); if (!which) cropsl_ = params->zmin; else cropsl_ = params->zmax; } void Frame3dBase::crop3dMotionCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(keyContext->frScale.scanMode()); Vector ss(params->xmin,params->ymin); Vector tt(params->xmax,params->ymax); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector ll = mapFromRef3d(ss,Coord::CANVAS,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::CANVAS,cropsl_); Vector ur = mapFromRef3d(tt,Coord::CANVAS,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::CANVAS,cropsl_); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } cropEnd = vv * Scale(zoom_).invert(); Vector diff = cropEnd-cropBegin; if (!which) cropsl_ = diff[0]+params->zmin; else cropsl_ = diff[0]+params->zmax; // this will be incorrect for multiple ext/file cubes // double depth = keyContext->fits->depth(); double depth = keyContext->naxis(2); if (!which) { if (cropsl_<0) cropsl_ = 0; if (cropsl_>params->zmax-1) cropsl_ = params->zmax-1; } else { if (cropsl_<params->zmin+1) cropsl_ = params->zmin+1; if (cropsl_>depth) cropsl_ = depth; } // and draw to window { Vector ll = mapFromRef3d(ss,Coord::WINDOW,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::WINDOW,cropsl_); Vector ur = mapFromRef3d(tt,Coord::WINDOW,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::WINDOW,cropsl_); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ll[0],ll[1],lr[0],lr[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,lr[0],lr[1],ur[0],ur[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ur[0],ur[1],ul[0],ul[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ul[0],ul[1],ll[0],ll[1]); } } void Frame3dBase::crop3dEndCmd(const Vector& vv, int which) { // which =0 (zmin) which =1 (zmax) if (!keyContext->fits) return; // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(keyContext->frScale.scanMode()); Vector ss(params->xmin,params->ymin); Vector tt(params->xmax,params->ymax); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector ll = mapFromRef3d(ss,Coord::CANVAS,cropsl_); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),Coord::CANVAS,cropsl_); Vector ur = mapFromRef3d(tt,Coord::CANVAS,cropsl_); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),Coord::CANVAS,cropsl_); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } cropEnd = vv * Scale(zoom_).invert(); Vector diff = cropEnd-cropBegin; if (!which) cropsl_ = diff[0]+params->zmin; else cropsl_ = diff[0]+params->zmax; // this will be incorrect for multiple ext/file cubes // double depth = keyContext->fits->depth(); double depth = keyContext->naxis(2); if (!which) { if (cropsl_<0) cropsl_ = 0; if (cropsl_>params->zmax-1) cropsl_ = params->zmax-1; } else { if (cropsl_<params->zmin+1) cropsl_ = params->zmin+1; if (cropsl_>depth) cropsl_ = depth; } if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { keyContext->frScale.setScanMode(FrScale::CROPSEC); // params is a BBOX in DATA coords 0-n FitsImage* sptr = keyContext->fits; while (sptr) { if (!which) sptr->setCrop3dParams(int(cropsl_+.5),params->zmax); else sptr->setCrop3dParams(params->zmin,int(cropsl_+.5)); sptr->updateFileName(); sptr = sptr->nextSlice(); } // set current slice if needed // setSlice() IMAGE (ranges 1-n) // context->slice() IMAGE (ranges 1-n) // cropsl_ ranges coords 0-n double sl = keyContext->slice(2)-.5; if (!which) { if (sl<=cropsl_) setSlice(2,int(cropsl_+1.5)); } else { if (sl>cropsl_) setSlice(2,int(cropsl_)); } } else { keyContext->frScale.resetScanMode(); FitsImage* sptr = keyContext->fits; while (sptr) { sptr->setCropParams(keyContext->frScale.datasec()); sptr->setCrop3dParams(); sptr->updateFileName(); sptr = sptr->nextSlice(); } } keyContext->frScale.clearHistogram(); keyContext->updateClip(); keyContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Frame3dBase::get3dBorderCmd() { if (border_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dBorderColorCmd() { Tcl_AppendResult(interp, borderColorName_, NULL); } void Frame3dBase::get3dCompassCmd() { if (compass_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dCompassColorCmd() { Tcl_AppendResult(interp, compassColorName_, NULL); } void Frame3dBase::get3dHighliteCmd() { if (highlite_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Frame3dBase::get3dHighliteColorCmd() { Tcl_AppendResult(interp, highliteColorName_, NULL); } void Frame3dBase::get3dRenderMethodCmd() { ostringstream str; switch (renderMethod_) { case MIP: str << "mip" << ends; break; case AIP: str << "aip" << ends; break; } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dScaleCmd() { ostringstream str; str << zscale_ << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dViewCmd() { ostringstream str; str << m180To180(radToDeg(az_)) << ' ' << m180To180(radToDeg(el_)) << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::get3dViewPointCmd() { ostringstream str; str << vp_ << viewCursor_ << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::getCursorCmd(Coord::InternalSystem sys) { Vector aa = Vector(options->width,options->height)/2.; Vector bb = mapToRef(aa,Coord::WIDGET); Vector cc = mapFromRef(bb,sys); printVector(cc, DEFAULT); } void Frame3dBase::getCursorCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Precision pp) { if (keyContext->fits) { Vector aa = Vector(options->width,options->height)/2.; Vector bb = mapToRef(aa,Coord::WIDGET); printFromRef(keyContext->fits, bb, sys, sky, format, pp); } else printVector(Vector(), DEFAULT); } void Frame3dBase::gridCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Grid::GridType type, const char* ops, const char* vars) { if (grid) delete grid; switch (type) { case Grid::ANALYSIS: grid = new Grid25d(this, sys, sky, format, type, ops, vars); break; case Grid::PUBLICATION: grid = new Grid3d(this, sys, sky, format, type, ops, vars); break; } update(PIXMAP); } void Frame3dBase::panCmd(const Vector& v1, const Vector& v2) { viewCursor_ -= (v1-v2)*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panCmd(const Vector& vv) { viewCursor_ -= vv*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector cc = Vector(options->width,options->height)/2.; Vector dd = mapToRef(cc,Coord::WIDGET); Vector uu = keyContext->fits->mapFromRef(dd, sys, sky); uu += vv; Vector ee = keyContext->fits->mapToRef(uu, sys, sky); Vector ff = mapFromRef(ee,Coord::WIDGET); viewCursor_ += (cc-ff)*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panToCmd(const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panToCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panBBoxCmd(const Vector& vv) { // vv is center of panBBox in panner coordinate Vector aa = vv*pannerToWidget3d; Vector dd = Vector(options->width,options->height)/2. - aa; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::panEndCmd(const Vector& vv) { if (panPM) Tk_FreePixmap(display, panPM); panPM = 0; Vector dd = vv*canvasToWidget - panCursor*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); update(MATRIX); } void Frame3dBase::rotateBeginCmd() { // save the current rotation rotateRotation = rotation; } void Frame3dBase::rotateMotionCmd(double angle) { rotation = rotateRotation + angle; update(MATRIX); } void Frame3dBase::rotateEndCmd() { update(MATRIX); } void Frame3dBase::set3dBorderCmd(int hh) { border_ = hh; update(PIXMAP); } void Frame3dBase::set3dBorderColorCmd(const char* clr) { if (borderColorName_) delete [] borderColorName_; borderColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(borderColorName_)); update(PIXMAP); } void Frame3dBase::set3dCompassCmd(int hh) { compass_ = hh; update(PIXMAP); } void Frame3dBase::set3dCompassColorCmd(const char* clr) { if (compassColorName_) delete [] compassColorName_; compassColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(compassColorName_)); update(PIXMAP); } void Frame3dBase::set3dHighliteCmd(int hh) { highlite_ = hh; update(PIXMAP); } void Frame3dBase::set3dHighliteColorCmd(const char* clr) { if (highliteColorName_) delete [] highliteColorName_; highliteColorName_ = dupstr(clr); if (threedGC) XSetForeground(display, threedGC, getColor(highliteColorName_)); update(PIXMAP); } void Frame3dBase::set3dRenderMethodCmd(int m) { RenderMethod mm = (RenderMethod)m; if (mm!=renderMethod_) { renderMethod_ = mm; update(MATRIX); } } void Frame3dBase::set3dScaleCmd(double ss) { zscale_ = ss; update(MATRIX); } void Frame3dBase::set3dViewCmd(float az, float el) { if (az>=-180 && az<=180) az_ = degToRad(az); if (el>=-90 && el<=90) el_ = degToRad(el); update(MATRIX); } void Frame3dBase::set3dViewPointCmd(const Vector3d& vv, const Vector& cc) { vp_ = vv; viewCursor_ = cc; update(MATRIX); } void Frame3dBase::zoomAboutCmd(const Vector& zz, const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); Vector az = ((Vector&)zz).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; update(MATRIX); } void Frame3dBase::zoomAboutCmd(const Vector& zz, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); Vector az = ((Vector&)zz).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; update(MATRIX); } void Frame3dBase::zoomToAboutCmd(const Vector& zz, const Vector& vv) { Vector dd = Vector(options->width,options->height)/2. - vv*canvasToWidget; viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); zoom_ = ((Vector&)zz).abs(); update(MATRIX); } void Frame3dBase::zoomToAboutCmd(const Vector& zz, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!keyContext->fits) return; Vector aa = keyContext->fits->mapToRef(vv, sys, sky); Vector dd = Vector(options->width,options->height)/2. - mapFromRef(aa,Coord::WIDGET); viewCursor_ += dd*Scale(1/zoom_[0],1/zoom_[1]); zoom_ = ((Vector&)zz).abs(); update(MATRIX); } void Frame3dBase::zoomToFitCmd(double ss) { if (!keyContext->fits) return; centerImage(); Vector3d tt = imageSize3d(keyContext->frScale.scanMode()); double zz = calcZoom3d(tt,Vector(options->width,options->height)) * ss; zoom_ = Vector(zz,zz); update(MATRIX); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3d.C����������������������������������������������������������������������0000644�0001750�0001750�00000045215�12107012362�014744� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame3d.h" #include "fitsimage.h" #include "ps.h" #include "sigbus.h" #include <pthread.h> void render3dTimer(void* ptr) { int rr = ((Frame3d*)ptr)->updateImage(); if (rr) { Tcl_TimerToken tt = Tcl_CreateTimerHandler(250,render3dTimer,ptr); ((Frame3d*)ptr)->setTimer(tt); } else ((Frame3d*)ptr)->setTimer(0); } Frame3d::Frame3d(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i,c,item) { context = new Context(); context->parent(this); currentContext = context; keyContext = context; keyContextSet =1; cmapID = 1; bias = 0.5; contrast = 1.0; colorCount = 0; colorScale = NULL; colorCells = NULL; indexCells = NULL; thread =NULL; targ =NULL; nrays =0; xid =NULL; yid =NULL; timer =0; // scope is alway global keyContext->frScale.setClipScope(FrScale::GLOBAL); } Frame3d::~Frame3d() { if (context) delete context; if (colorScale) delete colorScale; if (colorCells) delete [] colorCells; if (indexCells) delete [] indexCells; if (thread) delete [] thread; if (targ) delete [] targ; if (xid) delete [] xid; if (yid) delete [] yid; } unsigned char* Frame3d::fillImage(int width, int height, Coord::InternalSystem sys) { unsigned char* img; switch (sys) { case Coord::WIDGET: zbuf = &zbufWidget_; mkzbuf = &mkzbufWidget_; if (syncUpdate) img = fillImageJoin(width, height, sys); else img = fillImageDetach(width, height, sys); break; case Coord::PANNER: zbuf = &zbufPanner_; mkzbuf = &mkzbufPanner_; img = fillImageJoin(width, height, sys); break; case Coord::MAGNIFIER: zbuf = &zbufMagnifier_; mkzbuf = &mkzbufMagnifier_; img = fillImageJoin(width, height, sys); break; case Coord::PS: zbuf = &zbufPS_; mkzbuf = &mkzbufPS_; img = fillImageJoin(width, height, sys); break; } if (!img) { internalError("fillImage Error"); return NULL; } // no need to carry this around switch (sys) { case Coord::WIDGET: case Coord::PANNER: break; case Coord::MAGNIFIER: if (zbufMagnifier_) delete [] zbufMagnifier_; zbufMagnifier_ = NULL; if (mkzbufMagnifier_) delete [] mkzbufMagnifier_; mkzbufMagnifier_ = NULL; break; case Coord::PS: if (zbufPS_) delete [] zbufPS_; zbufPS_ = NULL; if (mkzbufPS_) delete [] mkzbufPS_; mkzbufPS_ = NULL; break; } return img; } void* raytrace(void* arg) { t_arg* targ = (t_arg*)arg; Frame3dBase::RenderMethod renderMethod = targ->renderMethod; int width = targ->width; Coord::InternalSystem sys = targ->sys; float** zbuf = targ->zbuf; unsigned char** mkzbuf = targ->mkzbuf; Context* context = targ->context; int* xid = targ->xid; int* yid = targ->yid; int start = targ->start; int stop = targ->stop; int zstart = targ->zstart; int zstop = targ->zstop; // this will be incorrect for multiple ext/file cubes // int srcd = context->fits->depth(); int srcd = context->naxis(2); double* mm = context->fits->matrixToData3d(sys).mm(); FitsImage* ptr = context->fits; // if more than 3 axes, walk it forward int num = context->calcSlice(); for (int ii=1; ii<num; ii++) if (ptr) ptr = ptr->nextSlice(); // slice jump vector FitsImage* sjv[srcd]; FitsImage* sptr = ptr; int ii=0; while (sptr) { sjv[ii++] = sptr; if (sptr) sptr = sptr->nextSlice(); } FitsBound* params = context->fits->getDataParams(context->frScale.scanMode()); int srcw = context->fits->width(); targ->rays =0; for (int ll=start; ll<=stop; ll++, targ->rays++) { int& jj = yid[ll]; int& ii = xid[ll]; double ii0 = ii*mm[0]; double ii1 = ii*mm[1]; double ii2 = ii*mm[2]; double jj4 = jj*mm[4]; double jj5 = jj*mm[5]; double jj6 = jj*mm[6]; int cnt=0; float acc=0; float max = -FLT_MAX; int kks = zstart; int kkt = zstop; // good abort point if (targ->abort) { targ->done =1; return 0; } int inside =0; for (int kk=kks; kk<kkt; kk++) { double xx = ii0 + jj4 + kk*mm[8] + mm[12]; double yy = ii1 + jj5 + kk*mm[9] + mm[13]; double zz = ii2 + jj6 + kk*mm[10] + mm[14]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax && zz>=params->zmin && zz<params->zmax) { float value = sjv[int(zz)]->getValueDouble(long(yy)*srcw+long(xx)); inside =1; // ignore nan if (isfinite(value)) { if (value>max) max = value; cnt++; acc+=value; } } else { // early determination if (inside) break; } } if (cnt) { float* dest = *zbuf + jj*width + ii; unsigned char* mkdest = *mkzbuf + jj*width + ii; switch (renderMethod) { case Frame3dBase::MIP: *dest =max; break; case Frame3dBase::AIP: *dest =acc/cnt; break; } *mkdest=1; } } targ->done=1; return 0; } unsigned char* Frame3d::fillImageJoin(int width, int height, Coord::InternalSystem sys) { if (!*zbuf) { *zbuf = new float[width*height]; if (!(*zbuf)) { internalError("fillImageJoin Error"); return NULL; } memset(*zbuf, 0, width*height*sizeof(float)); *mkzbuf = new unsigned char[width*height]; if (!(*mkzbuf)) { internalError("fillImageJoin Error"); return NULL; } memset(*mkzbuf, 0, width*height); BBox3d bb = imageBounds(width,height,sys); int ww = bb.ur[0]-bb.ll[0]; int hh = bb.ur[1]-bb.ll[1]; // local var overide int nrays = ww*hh; float incr = nrays/threads_; int* xid = new int[nrays]; int* yid = new int[nrays]; int x=bb.ll[0]+.5; // don't know why; int y=bb.ll[1]+.5; // don't know why // init array for (int jj=0; jj<hh; jj++) { for (int ii=0; ii<ww; ii++) { xid[jj*ww+ii] = ii+x; yid[jj*ww+ii] = jj+y; } } // local var overide pthread_t thread[threads_]; t_arg targ[threads_]; for (int ii=0; ii<threads_; ii++) { targ[ii].renderMethod = renderMethod_; targ[ii].width = width; targ[ii].sys = sys; targ[ii].zbuf = zbuf; targ[ii].mkzbuf = mkzbuf; targ[ii].context = context; targ[ii].xid = xid; targ[ii].yid = yid; targ[ii].start = incr*ii; if (ii+1<threads_) targ[ii].stop = incr*(ii+1)-1; else targ[ii].stop = nrays-1; targ[ii].zstart = bb.ll[2]; targ[ii].zstop = bb.ur[2]; targ[ii].rays =0; targ[ii].abort =0; targ[ii].done =0; } for (int ii=0; ii<threads_; ii++) { int rr = pthread_create(&thread[ii], NULL, raytrace, &targ[ii]); if (rr) internalError("Unable to Create Thread"); } // clean up threads for (int ii=0; ii<threads_; ii++) { int rr = pthread_join(thread[ii], NULL); if (rr) internalError("Unable to Join Thread"); } if (xid) delete [] xid; if (yid) delete [] yid; } return fillImageColor(width, height); } unsigned char* Frame3d::fillImageDetach(int width, int height, Coord::InternalSystem sys) { if (!*zbuf) { *zbuf = new float[width*height]; if (!(*zbuf)) { internalError("fillImageDetach Error"); return NULL; } memset(*zbuf, 0, width*height*sizeof(float)); *mkzbuf = new unsigned char[width*height]; if (!(*mkzbuf)) { internalError("fillImageDetach Error"); return NULL; } memset(*mkzbuf, 0, width*height); BBox3d bb = imageBounds(width,height,sys); int ww = bb.ur[0]-bb.ll[0]; int hh = bb.ur[1]-bb.ll[1]; nrays = ww*hh; float incr = nrays/threads_; if (xid) delete [] xid; xid = new int[nrays]; if (yid) delete [] yid; yid = new int[nrays]; int x=bb.ll[0]+.5; // don't know why int y=bb.ll[1]+.5; // don't know why // init array for (int jj=0; jj<hh; jj++) { for (int ii=0; ii<ww; ii++) { xid[jj*ww+ii] = ii+x; yid[jj*ww+ii] = jj+y; } } // randomize array for (int kk=nrays-1; kk>0; kk--) { int ll = rand() % (kk+1); // 0 <= ll <= kk if (ll!=kk) { int tx = xid[kk]; int ty = yid[kk]; xid[kk]=xid[ll]; yid[kk]=yid[ll]; xid[ll]=tx; yid[ll]=ty; } } // init threads thread = new pthread_t[threads_]; targ = new t_arg[threads_]; for (int ii=0; ii<threads_; ii++) { targ[ii].renderMethod = renderMethod_; targ[ii].width = width; targ[ii].sys = sys; targ[ii].zbuf = zbuf; targ[ii].mkzbuf = mkzbuf; targ[ii].context = context; targ[ii].xid = xid; targ[ii].yid = yid; targ[ii].start = incr*ii; if (ii+1<threads_) targ[ii].stop = incr*(ii+1)-1; else targ[ii].stop = nrays-1; targ[ii].zstart = bb.ll[2]; targ[ii].zstop = bb.ur[2]; targ[ii].rays =0; targ[ii].abort =0; targ[ii].done =0; } for (int ii=0; ii<threads_; ii++) { int rr = pthread_create(&thread[ii], NULL, raytrace, &targ[ii]); if (rr) internalError("Unable to Create Thread"); } // start the timer, if needed if (!timer) render3dTimer(this); } return fillImageColor(width, height); } void Frame3d::cancelImage() { // abort any threads if (thread) { // set cancel flag for (int ii=0; ii<threads_; ii++) targ[ii].abort =1; // now wait until done for (int ii=0; ii<threads_; ii++) { int rr = pthread_join(thread[ii], NULL); if (rr) internalError("Unable to Join Thread"); } delete [] thread; thread = NULL; } if (targ) { delete [] targ; targ = NULL; } if (xid) delete [] xid; xid =NULL; if (yid) delete [] yid; yid =NULL; // delete buffers if (zbufWidget_) delete [] zbufWidget_; zbufWidget_ = NULL; if (mkzbufWidget_) delete [] mkzbufWidget_; mkzbufWidget_ = NULL; if (zbufPanner_) delete [] zbufPanner_; zbufPanner_ = NULL; if (mkzbufPanner_) delete [] mkzbufPanner_; mkzbufPanner_ = NULL; if (zbufMagnifier_) delete [] zbufMagnifier_; zbufMagnifier_ = NULL; if (mkzbufMagnifier_) delete [] mkzbufMagnifier_; mkzbufMagnifier_ = NULL; if (zbufPS_) delete [] zbufPS_; zbufPS_ = NULL; if (mkzbufPS_) delete [] mkzbufPS_; mkzbufPS_ = NULL; } int Frame3d::updateImage() { // anything running? if (!thread) return 0; // we done yet? int sum=0; for (int ii=0; ii<threads_; ii++) sum += targ[ii].done; if (sum == threads_) { for (int ii=0; ii<threads_; ii++) { int rr = pthread_join(thread[ii], NULL); if (rr) internalError("Unable to Join Thread"); } nrays =0; if (thread) delete [] thread; thread = NULL; if (targ) delete [] targ; targ = NULL; if (xid) delete [] xid; xid = NULL; if (yid) delete [] yid; yid =NULL; // clear progress bar Tcl_SetVar2(interp,"threed","status","0",TCL_GLOBAL_ONLY); // update image updateNow(BASE); updateMagnifier(); return 0; } //progressbar int rays=0; for (int ii=0; ii<threads_; ii++) rays += targ[ii].rays; ostringstream str; str << int(float(rays)/nrays*100.) << ends; Tcl_SetVar2(interp,"threed","status",str.str().c_str(), TCL_GLOBAL_ONLY); // update image update(BASE); updateMagnifier(); return 1; } unsigned char* Frame3d::fillImageColor(int width, int height) { unsigned char* img = new unsigned char[width*height*3]; memset(img, 0, width*height*3); int length = colorScale->size() - 1; const unsigned char* table = colorScale->psColors(); double ll = keyContext->fits->getLowDouble(); double hh = keyContext->fits->getHighDouble(); double diff = hh - ll; register unsigned char red = (unsigned char)bgColor->red; register unsigned char green = (unsigned char)bgColor->green; register unsigned char blue = (unsigned char)bgColor->blue; unsigned char* dest = img; float* src = *zbuf; unsigned char* mksrc = *mkzbuf; for (int jj=0; jj<height; jj++) { for (int ii=0; ii<width; ii++, dest+=3, src++, mksrc++) { *dest = red; *(dest+1) = green; *(dest+2) = blue; if (*mksrc) { float value = *src; // will not see nan if (value <= ll) { *(dest+2) = table[0]; *(dest+1) = table[1]; *dest = table[2]; } else if (value >= hh) { *(dest+2) = table[length*3]; *(dest+1) = table[length*3+1]; *dest = table[length*3+2]; } else { int l = (int)(((value - ll)/diff * length) + .5); *(dest+2) = table[l*3]; *(dest+1) = table[l*3+1]; *dest = table[l*3+2]; } } } } return img; } BBox3d Frame3d::imageBounds(int width, int height, Coord::InternalSystem sys) { Matrix3d mx = keyContext->fits->matrixToData3d(sys).invert() * Translate3d(.5,.5,.5); FitsBound* params = keyContext->fits->getDataParams(keyContext->frScale.scanMode()); int& xmin = params->xmin; int& xmax = params->xmax; int& ymin = params->ymin; int& ymax = params->ymax; int& zmin = params->zmin; int& zmax = params->zmax; Vector3d llf = Vector3d(xmin,ymin,zmin) * mx; Vector3d lrf = Vector3d(xmax,ymin,zmin) * mx; Vector3d urf = Vector3d(xmax,ymax,zmin) * mx; Vector3d ulf = Vector3d(xmin,ymax,zmin) * mx; Vector3d llb = Vector3d(xmin,ymin,zmax) * mx; Vector3d lrb = Vector3d(xmax,ymin,zmax) * mx; Vector3d urb = Vector3d(xmax,ymax,zmax) * mx; Vector3d ulb = Vector3d(xmin,ymax,zmax) * mx; BBox3d bb(llf); bb.bound(lrf); bb.bound(urf); bb.bound(ulf); bb.bound(llb); bb.bound(lrb); bb.bound(urb); bb.bound(ulb); bb.clip(Vector3d(width,height,zdepth_)); return bb; } void Frame3d::reset() { cmapID = 1; bias = 0.5; contrast = 1.0; keyContext->frScale.resetScanMode(); keyContext->updateClip(); Base::reset(); } void Frame3d::updateColorCells(unsigned short* index, unsigned char* cells, int cnt) { // the colorbar widget will pass us a pointer to the indexCells colorCount = cnt; if (indexCells) delete [] indexCells; indexCells = new unsigned short[cnt]; if (!indexCells) { internalError("Unable to Alloc indexCells"); return; } memcpy(indexCells, index, cnt*sizeof(unsigned short)); // copy the rgb vales to the colorCells array (for postscript printing) if (colorCells) delete [] colorCells; colorCells = new unsigned char[cnt*3]; if (!colorCells) { internalError("Unable to Alloc colorCells"); return; } memcpy(colorCells, cells, cnt*3); } void Frame3d::pushMatrices() { Base::pushMatrices(); FitsImage* ptr = keyContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMatrices(refToWidget3d); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Frame3d::pushPannerMatrices() { Base::pushPannerMatrices(); FitsImage* ptr = keyContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updatePannerMatrices(refToPanner3d); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Frame3d::pushMagnifierMatrices() { Base::pushMagnifierMatrices(); FitsImage* ptr = keyContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMagnifierMatrices(refToMagnifier3d); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Frame3d::pushPSMatrices(float scale, int width, int height) { Base::pushPSMatrices(scale, width, height); Matrix3d mx = psMatrix(scale, width, height); FitsImage* ptr = keyContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updatePS(mx); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Frame3d::unloadFits() { if (DebugPerf) cerr << "Frame3d::unloadFits" << endl; // kill any active threads cancelImage(); keyContext->unload(); Base::unloadFits(); } // Commands void Frame3d::getColorbarCmd() { ostringstream str; str << cmapID << ' ' << bias << ' ' << contrast << ' ' << invert << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3d::getRGBChannelCmd() { Tcl_AppendResult(interp, "red", NULL); } void Frame3d::getRGBViewCmd() { Tcl_AppendResult(interp, "1 1 1", NULL); } void Frame3d::getRGBSystemCmd() { Tcl_AppendResult(interp, "image", NULL); } void Frame3d::getTypeCmd() { Tcl_AppendResult(interp, "3d", NULL); } void Frame3d::savePhotoCmd(const char* ph) { FitsImage* fits = currentContext->cfits; if (!fits) return; // basics int length = colorScale->size() - 1; const unsigned char* table = colorScale->psColors(); // variable FitsBound* params = fits->getDataParams(context->frScale.scanMode()); double ll = fits->getLowDouble(); double hh = fits->getHighDouble(); double diff = hh - ll; int width = params->xmax - params->xmin; int height = params->ymax - params->ymin; // photo if (*ph == '\0') { Tcl_AppendResult(interp, "bad image name ", NULL); return; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, ph); if (!photo) { Tcl_AppendResult(interp, "bad image handle ", NULL); return; } if (Tk_PhotoSetSize(interp, photo, width, height) != TCL_OK) { Tcl_AppendResult(interp, "bad photo set size ", NULL); return; } Tk_PhotoBlank(photo); Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block ", NULL); return; } if (block.pixelSize<4) { Tcl_AppendResult(interp, "bad pixel size ", NULL); return; } // main loop SETSIGBUS unsigned char* dest = block.pixelPtr; for (long jj=params->ymax-1; jj>=params->ymin; jj--) { for (long ii=params->xmin; ii<params->xmax; ii++, dest += block.pixelSize) { double value = fits->getValueDouble(Vector(ii,jj)); if (isfinite(value)) { if (value <= ll) { *(dest+block.offset[0]) = table[2]; *(dest+block.offset[1]) = table[1]; *(dest+block.offset[2]) = table[0]; *(dest+block.offset[3]) = 255; } else if (value >= hh) { *(dest+block.offset[0]) = table[length*3+2]; *(dest+block.offset[1]) = table[length*3+1]; *(dest+block.offset[2]) = table[length*3]; *(dest+block.offset[3]) = 255; } else { int l = (int)(((value - ll)/diff * length) + .5); *(dest+block.offset[0]) = table[l*3+2]; *(dest+block.offset[1]) = table[l*3+1]; *(dest+block.offset[2]) = table[l*3]; *(dest+block.offset[3]) = 255; } } else { *(dest+block.offset[0]) = nanColor->red; *(dest+block.offset[1]) = nanColor->green; *(dest+block.offset[2]) = nanColor->blue; *(dest+block.offset[3]) = 255; } } } CLEARSIGBUS if (Tk_PhotoPutBlock(interp, photo, &block, 0, 0, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { Tcl_AppendResult(interp, "bad put block ", NULL); return; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametruecolor16.h�������������������������������������������������������������0000644�0001750�0001750�00000001327�11700666270�016677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametruecolor16_h__ #define __frametruecolor16_h__ #include "frametruecolor.h" #include "truecolor16.h" class FrameTrueColor16 : public virtual FrameBase, public FrameTrueColor, public TrueColor16 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor16::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor16::encodeTrueColor(src, ximage);} void updateColorScale(); public: FrameTrueColor16(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameTrueColor16(); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudocolor8.C������������������������������������������������������������0000644�0001750�0001750�00000012313�11700666267�017076� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framepseudocolor8.h" #include "colorscalepseudo8.h" // Tk Canvas Widget Function Declarations int FramePseudoColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FramePseudoColor8 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec framePseudoColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType framePseudoColor8Type = { (char*)"framepseudocolor8", // name sizeof(WidgetOptions), // item size FramePseudoColor8CreateProc, // configProc framePseudoColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FramePseudoColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&framePseudoColor8Type); return TCL_OK; } int FramePseudoColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FramePseudoColor8* frame = new FramePseudoColor8(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FramePseudoColor8 Member Functions FramePseudoColor8::FramePseudoColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FramePseudoColor(i,c,item) { configSpecs = framePseudoColor8Specs; // frame configure options } FramePseudoColor8::~FramePseudoColor8() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void FramePseudoColor8::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells) return; if (colorScale) delete colorScale; switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScalePseudoColor8(colorCount, indexCells, colorCells, colorCount); break; case FrScale::LOGSCALE: colorScale = new LogScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo()); break; case FrScale::POWSCALE: colorScale = new PowScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo()); break; case FrScale::SQRTSCALE: colorScale = new SqrtScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount); break; case FrScale::ASINHSCALE: colorScale = new AsinhScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount); break; case FrScale::SINHSCALE: colorScale = new SinhScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount); break; case FrScale::IISSCALE: colorScale = new IISScalePseudoColor8(this,indexCells, colorCells, colorCount); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScalePseudoColor8(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE); break; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/epanda.C�����������������������������������������������������������������������0000644�0001750�0001750�00000053442�12030663652�014665� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "epanda.h" #include "fitsimage.h" Epanda::Epanda(const Epanda& a) : BasePanda(a), BaseEllipse(a) {} Epanda::Epanda(Base* p, const Vector& ctr, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(a1, a2, an), BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn+1; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) annuli_[ii] = ((r2-r1)/rn)*ii+r1; strcpy(type_, "epanda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } Epanda::Epanda(Base* p, const Vector& ctr, int an, double* a, int rn, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(an, a), BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) annuli_[ii] = r[ii]; sortAnnuli(); strcpy(type_, "epanda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } void Epanda::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { BaseEllipse::renderX(drawable, sys, mode); GC lgc = renderXGC(mode); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,-angles_[ii]),sys); Vector rr1 = fwdMap(intersect(r1,-angles_[ii]),sys); if (mode == SRC) { if (selected) { if (ii == 0) XSetForeground(display, gc, parent->getColor("red")); else if (ii == numAngles_-1) XSetForeground(display, gc, parent->getColor("blue")); else XSetForeground(display, gc, color); } else XSetForeground(display, gc, color); } XDrawLine(display, drawable, lgc, rr0[0], rr0[1], rr1[0], rr1[1]); } } void Epanda::renderPS(int mode) { BaseEllipse::renderPS(mode); renderPSGC(mode); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,-angles_[ii]),Coord::CANVAS); Vector rr1 = fwdMap(intersect(r1,-angles_[ii]),Coord::CANVAS); ostringstream str; str << "newpath " << rr0.TkCanvasPs(parent->canvas) << "moveto" << rr1.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void Epanda::renderMACOSX() { BaseEllipse::renderMACOSX(); renderMACOSXGC(); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,-angles_[ii]),Coord::CANVAS); Vector rr1 = fwdMap(intersect(r1,-angles_[ii]),Coord::CANVAS); macosxDrawLine(rr0,rr1); } } #endif #ifdef _WIN32 void Epanda::renderWIN32() { BaseEllipse::renderWIN32(); renderWIN32GC(); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,-angles_[ii]),Coord::CANVAS); Vector rr1 = fwdMap(intersect(r1,-angles_[ii]),Coord::CANVAS); win32DrawLine(rr0,rr1); } } #endif // Support void Epanda::updateHandles() { BaseEllipse::updateHandles(); Vector rr = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) handle[ii+4+numAnnuli_] = fwdMap(intersect(rr,-angles_[ii]),Coord::CANVAS); } void Epanda::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); Vector n = v * mm; if (h<5) { // don't go thru the center if (n[0]!=0 && n[1]!=0) { Vector o = annuli_[numAnnuli_-1]; for (int i=0; i<numAnnuli_; i++) { annuli_[i][0] *= fabs(n[0]/o[0]); annuli_[i][1] *= fabs(n[1]/o[1]); } } } else if (h<(5+numAnnuli_)) { // we must have some length double l = n.length(); annuli_[h-5] = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; } else { angles_[h-5-numAnnuli_] = -((v * mm).angle()); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; } updateBBox(); doCallBack(CallBack::EDITCB); } void Epanda::editEnd() { sortAnnuli(); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITENDCB); } int Epanda::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm).length(); Vector rr = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; // we need to insert into the next to the last location // new size array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_+1]; // copy old values for (int i=0; i<numAnnuli_; i++) annuli_[i] = old[i]; // save last annuli_[numAnnuli_] = old[numAnnuli_-1]; // delete old if (old) delete [] old; // new size on end annuli_[numAnnuli_-1] = rr; numAnnuli_++; numHandle++; return 4+numAnnuli_-1; } int Epanda::addAngles(const Vector& v) { Matrix mm = bckMatrix(); addAngle(-((v * mm).angle())); numHandle++; return 4+numAnnuli_+numAngles_-1; } void Epanda::setAnglesAnnuli(double a1, double a2, int an, Vector r1, Vector r2, int rn) { numAnnuli_ = rn+1; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((r2-r1)/rn)*i+r1; sortAnnuli(); setAngles(a1,a2,an); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Epanda::setAnglesAnnuli(const double* a, int an, const Vector* r, int rn) { numAnnuli_ = rn; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = r[i]; sortAnnuli(); setAngles(an,a); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Epanda::deleteAnglesAnnuli(int h) { if (h>4) { int hh = h-4-1; if (numAnnuli_>2 && hh<numAnnuli_) { // new annuli_ array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_-1]; // copy up to annuli_ in question for (int i=0; i<hh; i++) annuli_[i] = old[i]; // copy remainder for (int i=hh; i<numAnnuli_-1; i++) annuli_[i] = old[i+1]; if (old) delete [] old; numAnnuli_--; } else if (numAngles_>2 && hh<(numAnnuli_+numAngles_)) { hh -= numAnnuli_; deleteAngle(hh); } numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITCB); } } int Epanda::isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa) { Vector pp = bckMap(vv,sys); return BaseEllipse::isIn(vv,sys,nn) && BasePanda::isIn(pp,aa); } void Epanda::analysis(AnalysisTask mm, int which) { switch (mm) { case PANDA: if (!analysisPanda_ && which) { addCallBack(CallBack::MOVECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPandaCB_[1], parent->options->cmdName); } if (analysisPanda_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisPandaCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisPandaCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisPandaCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPandaCB_[1]); } analysisPanda_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Epanda::analysisPanda(Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv = annuli_[ii]; bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } int num = parent->markerAnalysisPanda(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, numAngles_-1, angles_, bb, sys); analysisPandaResult(xx, yy, ee, num); } void Epanda::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv = annuli_[ii]; bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } parent->markerAnalysisStats(this, str, numAnnuli_-1, numAngles_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Epanda::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { int regular = 1; if (numAngles_>2) { double delta; if (angles_[1] > angles_[0]) delta = angles_[1]-angles_[0]; else delta = angles_[1]+M_TWOPI-angles_[0]; for (int ii=2; ii<numAngles_; ii++) { double diff; if (angles_[ii] > angles_[ii-1]) diff = angles_[ii]-angles_[ii-1]; else diff = angles_[ii]+M_TWOPI-angles_[ii-1]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (numAnnuli_>2) { double delta = annuli_[1][0]-annuli_[0][0]; for (int i=2; i<numAnnuli_; i++) { double diff = annuli_[i][0]-annuli_[i-1][0]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (regular) listA(str, sys, sky, format, conj, strip); else listB(str, sys, sky, format, conj, strip); } void Epanda::listA(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ',' << numAngles_-1 << ',' << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys,sky); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector r1 = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void Epanda::listB(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # epanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys); str << r[0] << ' ' << r[1] << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # epanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys,Coord::ARCSEC); str << r[0] << '"' << ' ' << r[1] << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << '"' << ',' << r1[1] << '"' <<',' << r2[0] << '"' << ',' << r2[1] << '"' <<',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # epanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys,Coord::ARCSEC); str << r[0] << '"' << ' ' << r[1] << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; } break; } else { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # epanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys); str << r[0] << ' ' << r[1] << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } } } } void Epanda::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_,numAnnuli_); XMLRowAng(sys,sky); XMLRowAng(sys,sky,angles_,numAngles_); XMLRowProps(ptr,sys); XMLRowEnd(str); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor.h������������������������������������������������������������0000644�0001750�0001750�00000001512�11727730000�017207� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framergbtruecolor_h__ #define __framergbtruecolor_h__ #include "framergb.h" #include "frametrue.h" class FrameRGBTrueColor : public virtual FrameBase, public FrameRGB, public FrameTrue { protected: long* colormapData[3]; // preextract data private: void buildXImage(XImage*, Coord::InternalSystem); public: FrameRGBTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FrameRGBTrueColor(); void colormapCmd(float, float, float, float, float, float, int, unsigned char*, int); void colormapBeginCmd(); void colormapEndCmd(); void colormapMotionCmd(float, float, float, float, float, float, int, unsigned char*, int); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/line.h�������������������������������������������������������������������������0000644�0001750�0001750�00000002666�12002337004�014417� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __line_h__ #define __line_h__ #include "baseline.h" class Line : public BaseLine { protected: int p1Arrow; int p2Arrow; protected: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif void updateHandles(); public: Line(const Line&); Line(Base* p, const Vector& ptr1, const Vector& ptr2, int a1, int a2, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Line(*this);} void setArrows(int,int); int getP1Arrow() {return p1Arrow;} int getP2Arrow() {return p2Arrow;} void analysis(AnalysisTask, int); void analysisPlot2d(char*, char*, char*, char*, Coord::CoordSystem, Coord::SkyFrame, Marker::AnalysisMethod); virtual void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); virtual void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); virtual void listPost(ostream&, int, int); void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); }; #endif ��������������������������������������������������������������������������./saods9/saotk/frame/cpanda.C�����������������������������������������������������������������������0000644�0001750�0001750�00000054065�12030663652�014665� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "cpanda.h" #include "fitsimage.h" Cpanda::Cpanda(const Cpanda& a) : BasePanda(a), BaseEllipse(a) {} Cpanda::Cpanda(Base* p, const Vector& ctr, double a1, double a2, int an, double r1, double r2, int rn, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(a1, a2, an), BaseEllipse(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn+1; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) { double r = ii*(r2-r1)/rn+r1; annuli_[ii] = Vector(r,r); } strcpy(type_, "panda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } Cpanda::Cpanda(Base* p, const Vector& ctr, int an, double* a, int rn, double* r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(an, a), BaseEllipse(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) annuli_[ii] = Vector(r[ii],r[ii]); sortAnnuli(); strcpy(type_, "panda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } void Cpanda::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { BaseEllipse::renderX(drawable, sys, mode); GC lgc = renderXGC(mode); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(Vector(r0[0]*cos(-angles_[ii]),r0[1]*sin(-angles_[ii])), sys); Vector rr1 = fwdMap(Vector(r1[0]*cos(-angles_[ii]),r1[1]*sin(-angles_[ii])), sys); if (mode == SRC) { if (selected) { if (ii == 0) XSetForeground(display, gc, parent->getColor("red")); else if (ii == numAngles_-1) XSetForeground(display, gc, parent->getColor("blue")); else XSetForeground(display, gc, color); } else XSetForeground(display, gc, color); } XDrawLine(display, drawable, lgc, rr0[0], rr0[1], rr1[0], rr1[1]); } } void Cpanda::renderPS(int mode) { BaseEllipse::renderPS(mode); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(Vector(r0[0]*cos(-angles_[ii]),r0[1]*sin(-angles_[ii])), Coord::CANVAS); Vector rr1 = fwdMap(Vector(r1[0]*cos(-angles_[ii]),r1[1]*sin(-angles_[ii])), Coord::CANVAS); ostringstream str; str << "newpath " << rr0.TkCanvasPs(parent->canvas) << "moveto" << rr1.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void Cpanda::renderMACOSX() { BaseEllipse::renderMACOSX(); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(Vector(r0[0]*cos(-angles_[ii]),r0[1]*sin(-angles_[ii])), Coord::CANVAS); Vector rr1 = fwdMap(Vector(r1[0]*cos(-angles_[ii]),r1[1]*sin(-angles_[ii])), Coord::CANVAS); macosxDrawLine(rr0,rr1); } } #endif #ifdef _WIN32 void Cpanda::renderWIN32() { BaseEllipse::renderWIN32(); Vector r0 = annuli_[0]; Vector r1 = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(Vector(r0[0]*cos(-angles_[ii]), r0[1]*sin(-angles_[ii])), Coord::CANVAS); Vector rr1 = fwdMap(Vector(r1[0]*cos(-angles_[ii]), r1[1]*sin(-angles_[ii])), Coord::CANVAS); win32DrawLine(rr0,rr1); } } #endif // Support void Cpanda::updateHandles() { // handles are in canvas coords // we can't garantee that the annuli_ have been sorted yet if (handle) delete [] handle; handle = new Vector[numHandle]; Vector max; for(int ii=0; ii<numAnnuli_; ii++) if (max[0]<annuli_[ii][0]) max = annuli_[ii]; Vector& r = max; handle[0] = fwdMap(Vector(-r[0],-r[1]),Coord::CANVAS); handle[1] = fwdMap(Vector( r[0],-r[1]),Coord::CANVAS); handle[2] = fwdMap(Vector( r[0], r[1]),Coord::CANVAS); handle[3] = fwdMap(Vector(-r[0], r[1]),Coord::CANVAS); for (int ii=0; ii<numAnnuli_; ii++) handle[ii+4] = fwdMap(Vector(annuli_[ii][0],0),Coord::CANVAS); Vector rr = annuli_[numAnnuli_-1]; for (int ii=0; ii<numAngles_; ii++) handle[4+numAnnuli_+ii] = fwdMap(Vector(rr[0]*cos(-angles_[ii]),rr[1]*sin(-angles_[ii])),Coord::CANVAS); } void Cpanda::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); if (h<5) { // calc dist between edge of circle and handle double d = annuli_[numAnnuli_-1].length() - annuli_[numAnnuli_-1][0]; for (int i=0; i<numAnnuli_; i++) { double r = ((v * mm).length() - d)/annuli_[numAnnuli_-1][0]; annuli_[i] *= r; } } else if (h<(5+numAnnuli_)) { double d = (v * mm).length(); annuli_[h-5] = Vector(d,d); } else { angles_[h-5-numAnnuli_] = -((v * mm).angle()); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; } updateBBox(); doCallBack(CallBack::EDITCB); } void Cpanda::editEnd() { sortAnnuli(); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITENDCB); } int Cpanda::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm).length(); // we need to insert into the next to the last location // new size array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_+1]; // copy old values for (int i=0; i<numAnnuli_; i++) annuli_[i] = old[i]; // save last annuli_[numAnnuli_] = old[numAnnuli_-1]; // delete old if (old) delete [] old; // new size on end annuli_[numAnnuli_-1] = Vector(l,l); numAnnuli_++; numHandle++; // return handle number return 4+numAnnuli_-1; } int Cpanda::addAngles(const Vector& v) { Matrix mm = bckMatrix(); addAngle(-((v * mm).angle())); numHandle++; // return handle number return 4+numAnnuli_+numAngles_-1; } void Cpanda::setAnglesAnnuli(double a1, double a2, int an, Vector r1, Vector r2, int rn) { numAnnuli_ = rn+1; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((r2-r1)/rn)*i+r1; sortAnnuli(); setAngles(a1,a2,an); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Cpanda::setAnglesAnnuli(const double* a, int an, const Vector* r, int rn) { numAnnuli_ = rn; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = r[i]; sortAnnuli(); setAngles(an,a); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Cpanda::deleteAnglesAnnuli(int h) { if (h>4) { int hh = h-4-1; if (numAnnuli_>2 && hh<numAnnuli_) { // new annuli_ array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_-1]; // copy up to annuli_ in question for (int i=0; i<hh; i++) annuli_[i] = old[i]; // copy remainder for (int i=hh; i<numAnnuli_-1; i++) annuli_[i] = old[i+1]; if (old) delete [] old; numAnnuli_--; } else if (numAngles_>2 && hh<(numAnnuli_+numAngles_)) { hh -= numAnnuli_; deleteAngle(hh); } numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITCB); } } int Cpanda::isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa) { Vector pp = bckMap(vv,sys); return BaseEllipse::isIn(vv,sys,nn) && BasePanda::isIn(pp,aa); } void Cpanda::analysis(AnalysisTask mm, int which) { switch (mm) { case PANDA: if (!analysisPanda_ && which) { addCallBack(CallBack::MOVECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPandaCB_[1], parent->options->cmdName); } if (analysisPanda_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisPandaCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisPandaCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPandaCB_[1]); } analysisPanda_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Cpanda::analysisPanda(Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) { Vector ll = -annuli_[ii] * Translate(center); Vector ur = annuli_[ii] * Translate(center); bb[ii] = BBox(ll,ur) ; } int num = parent->markerAnalysisPanda(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, numAngles_-1, angles_, bb, sys); analysisPandaResult(xx, yy, ee, num); } void Cpanda::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) { Vector ll = -annuli_[ii] * Translate(center); Vector ur = annuli_[ii] * Translate(center); bb[ii] = BBox(ll,ur) ; } parent->markerAnalysisStats(this, str, numAnnuli_-1, numAngles_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Cpanda::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { int regular = 1; if (numAngles_>2) { double delta; if (angles_[1] > angles_[0]) delta = angles_[1]-angles_[0]; else delta = angles_[1]+M_TWOPI-angles_[0]; for (int ii=2; ii<numAngles_; ii++) { double diff; if (angles_[ii] > angles_[ii-1]) diff = angles_[ii]-angles_[ii-1]; else diff = angles_[ii]+M_TWOPI-angles_[ii-1]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (numAnnuli_>2) { double delta = annuli_[1][0]-annuli_[0][0]; for (int i=2; i<numAnnuli_; i++) { double diff = annuli_[i][0]-annuli_[i-1][0]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (regular) listA(str, sys, sky, format, conj, strip); else listB(str, sys, sky, format, conj, strip); } void Cpanda::listA(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ',' << numAngles_-1 << ',' << ptr->mapLenFromRef(annuli_[0][0],sys) << ',' << ptr->mapLenFromRef(annuli_[numAnnuli_-1][0],sys) << ',' << numAnnuli_-1 << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC) << '"' << ',' << ptr->mapLenFromRef(annuli_[numAnnuli_-1][0],sys,Coord::ARCSEC)<< '"'<<',' << numAnnuli_-1 << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC) << '"' << ',' << ptr->mapLenFromRef(annuli_[numAnnuli_-1][0],sys,Coord::ARCSEC)<< '"'<<',' << numAnnuli_-1 << ')'; } break; } } else { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << ptr->mapLenFromRef(annuli_[0][0],sys) << ',' << ptr->mapLenFromRef(annuli_[numAnnuli_-1][0],sys)<< ',' << numAnnuli_-1 << ')'; } } } listPost(str, conj, strip); } void Cpanda::listB(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << ptr->mapLenFromRef(annuli_[i-1][0],sys) << ',' << ptr->mapLenFromRef(annuli_[i][0],sys) << ",1)"; if (!strip) { if (conj) str << " ||"; str << " # panda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) str << ptr->mapLenFromRef(annuli_[k][0],sys) << ((k<numAnnuli_-1) ? ' ' : ')'); listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << ptr->mapLenFromRef(annuli_[i-1][0],sys,Coord::ARCSEC) << '"' <<',' << ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC) << '"' <<",1)"; if (!strip) { if (conj) str << " ||"; str << " # panda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) str << ptr->mapLenFromRef(annuli_[k][0],sys,Coord::ARCSEC) << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 << ",1," << ptr->mapLenFromRef(annuli_[i-1][0],sys,Coord::ARCSEC) << '"' <<',' << ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCSEC) << '"' <<",1)"; if (!strip) { if (conj) str << " ||"; str << " # panda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) str << ptr->mapLenFromRef(annuli_[k][0],sys,Coord::ARCSEC) << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; } break; } else { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << ptr->mapLenFromRef(annuli_[i-1][0],sys) <<',' << ptr->mapLenFromRef(annuli_[i][0],sys) <<",1)"; if (!strip) { if (conj) str << " ||"; str << " # panda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) str << ptr->mapLenFromRef(annuli_[k][0],sys) << ((k<numAnnuli_-1) ? ' ' : ')'); listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } } } } void Cpanda::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadiusX(ptr,sys,annuli_,numAnnuli_); XMLRowAng(sys,sky,angles_,numAngles_); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Cpanda::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); for (int i=0; i<numAnnuli_-1; i++) for (int j=0; j<numAngles_-1; j++) { listCiaoPre(str); double ang1 = radToDeg(angles_[j]); double ang2 = radToDeg(angles_[j+1]); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; str << "pie(" << setprecision(8) << v[0] << ',' << v[1] << ',' << ptr->mapLenFromRef(annuli_[i][0],Coord::PHYSICAL) << ',' << ptr->mapLenFromRef(annuli_[i+1][0],Coord::PHYSICAL) << ',' << ang1 << ',' << ang2 << ')'; listCiaoPost(str, strip); } } break; default: if (ptr->hasWCSCel(sys)) { char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL, buf, 64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; for (int i=0; i<numAnnuli_-1; i++) for (int j=0; j<numAngles_-1; j++) { listCiaoPre(str); double ang1 = radToDeg(angles_[j]); double ang2 = radToDeg(angles_[j+1]); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; str << "pie(" << ra << ',' << dec << ',' << ptr->mapLenFromRef(annuli_[i][0],sys,Coord::ARCMIN) << '\'' << ',' << ptr->mapLenFromRef(annuli_[i+1][0],sys,Coord::ARCMIN) << '\'' << ',' << ang1 << ',' << ang2 << ')'; listCiaoPost(str, strip); } } } } // special composite funtionallity void Cpanda::setComposite(const Matrix& mx, double aa) { center *= mx; updateBBox(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/vect.C�������������������������������������������������������������������������0000644�0001750�0001750�00000007537�12057220627�014402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "vect.h" #include "fitsimage.h" Vect::Vect(Base* p, const Vector& ptr1, const Vector& ptr2, int arr, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Line(p, ptr1, ptr2, 0, arr, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { strcpy(type_,"vector"); } Vect::Vect(Base* p, const Vector& pt, double mag, double ang, int arr, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Line(p, pt, pt, 0, arr, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { strcpy(type_,"vector"); p2 = Vector(mag,0) * Rotate(ang) * FlipY() * Translate(p1); updateBBox(); } void Vect::setPoints(const Vector& pt, double mag, double ang) { p1 = pt; p2 = Vector(mag,0) * Rotate(ang) * FlipY() * Translate(p1); updateBBox(); doCallBack(CallBack::EDITCB); } // list void Vect::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); double mag = (p2-p1).length(); double ang = (p2-p1).angle(); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << ptr->mapLenFromRef(mag,sys) << ',' << radToDeg(parent->mapAngleFromRef(ang,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); double mag = (p2-p1).length(); double ang = (p2-p1).angle(); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << ptr->mapLenFromRef(mag,sys,Coord::ARCSEC) << "\"" << ',' << radToDeg(parent->mapAngleFromRef(ang,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra1[16], ra2[16]; char dec1[16], dec2[16]; double mag = (p2-p1).length(); double ang = (p2-p1).angle(); { ptr->mapFromRef(p1,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra1 >> dec1; } str << type_ << '(' << ra1 << ',' << dec1 << ',' << ptr->mapLenFromRef(mag,sys,Coord::ARCSEC) << "\"" << ',' << radToDeg(parent->mapAngleFromRef(ang,sys,sky)) << ')'; } break; } } else { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); double mag = (p2-p1).length(); double ang = (p2-p1).angle(); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << ptr->mapLenFromRef(mag,sys) << ',' << radToDeg(parent->mapAngleFromRef(ang,sys)) << ')'; } } } if (conj) str << " ||"; str << " vector=" << p2Arrow; listProperties(str, 0); } } void Vect::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); double rr = ptr->mapLenFromRef((p2-p1).length(),sys,Coord::ARCSEC); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowPoint(ptr,sys,sky,format,p1); XMLRow(XMLR,rr); XMLRowAng(sys,sky); XMLRow(XMLPARAM,p2Arrow); XMLRowProps(ptr,sys); XMLRowEnd(str); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ds9lex.L�����������������������������������������������������������������������0000644�0001750�0001750�00000014650�11734430017�014651� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "ds9parser.H" extern YYSTYPE* mklval; extern mkFlexLexer* mklexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(mklval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return STRING; } amplifier {return AMPLIFIER_;} ann[u][l][u][s] {return ANNULUS_;} arcmin {return ARCMIN_;} arcsec {return ARCSEC_;} arrow {return ARROW_;} b1950 {return B1950_;} background {return BACKGROUND_;} begin {return BEGIN_;} box {return BOX_;} boxcircle {return BOXCIRCLE_;} bpanda {return BPANDA_;} callback {return CALLBACK_;} cir[c][l][e] {return CIRCLE_;} circle3d {return CIRCLE3D_;} color {return COLOR_;} compass {return COMPASS_;} composite {return COMPOSITE_;} cpanda {return CPANDA_;} cross {return CROSS_;} dash {return DASH_;} dashlist {return DASHLIST_;} debug {return DEBUG_;} degrees {return DEGREES_;} delete {return DELETE_;} detector {return DETECTOR_;} diamond {return DIAMOND_;} edit {return EDIT_;} ell[i][p][s][e] {return ELLIPSE_;} ecliptic {return ECLIPTIC_;} epanda {return EPANDA_;} end {return END_;} false {return FALSE_;} fie[l][d] {return FIELD_;} fixed {return FIXED_;} fk4 {return FK4_;} fk4-no-e {return FK4_NO_E_;} fk5 {return FK5_;} font {return FONT_;} galactic {return GALACTIC_;} global {return GLOBAL_;} helioecliptic {return HELIOECLIPTIC_;} highlite {return HIGHLITE_;} icrs {return ICRS_;} ignore {return IGNORE_;} include {return INCLUDE_;} image {return IMAGE_;} key {return KEY_;} j2000 {return J2000_;} lin[e] {return LINE_;} linear {return LINEAR_;} move {return MOVE_;} n {return N_;} no {return NO_;} off {return OFF_;} on {return ON_;} panda {return CPANDA_;} physical {return PHYSICAL_;} pie {return PIE_;} pixels {return PIXELS_;} poi[n][t] {return POINT_;} pol[y][g][o][n] {return POLYGON_;} projection {return PROJECTION_;} property {return PROPERTY_;} rotate {return ROTATE_;} rotbox {return ROTBOX_;} ruler {return RULER_;} select {return SELECT_;} source {return SOURCE_;} supergalactic {return SUPERGALACTIC_;} tag {return TAG_;} text {return TEXT_;} textangle {return TEXTANGLE_;} textrotate {return TEXTROTATE_;} tile {return TILE_;} true {return TRUE_;} vector {return VECTOR_;} version {return VERSION_;} update {return UPDATE_;} unhighlite {return UNHIGHLITE_;} unselect {return UNSELECT_;} wcs {return WCS_;} wcsa {return WCSA_;} wcsb {return WCSB_;} wcsc {return WCSC_;} wcsd {return WCSD_;} wcse {return WCSE_;} wcsf {return WCSF_;} wcsg {return WCSG_;} wcsh {return WCSH_;} wcsi {return WCSI_;} wcsj {return WCSJ_;} wcsk {return WCSK_;} wcsl {return WCSL_;} wcsm {return WCSM_;} wcsn {return WCSN_;} wcso {return WCSO_;} wcsp {return WCSP_;} wcsq {return WCSQ_;} wcsr {return WCSR_;} wcss {return WCSS_;} wcst {return WCST_;} wcsu {return WCSU_;} wcsv {return WCSV_;} wcsw {return WCSW_;} wcsx {return WCSX_;} wcsy {return WCSY_;} wcsz {return WCSZ_;} wcs0 {return WCS0_;} width {return WIDTH_;} x {return X_;} y {return Y_;} yes {return YES_;} [+-]?{D}+ { // Integer mklval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number mklval->real = atof(yytext); return REAL; } [+-]?{D}+"."?d | [+-]?{D}*"."{D}+d { // degrees yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ANGDEGREE; } [+-]?{D}+"."?r | [+-]?{D}*"."{D}+r { // radians yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ANGRADIAN; } [+-]?{D}+"."?p | [+-]?{D}*"."{D}+p { // physical coords yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return PHYCOORD; } [+-]?{D}+"."?i | [+-]?{D}*"."{D}+i { // image coords yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return IMGCOORD; } {D}+"."?' | {D}*"."{D}+' | [+-]?{D}+"."?({E})?' | [+-]?{D}*"."{D}+({E})?' { // minutes of arc yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ARCMINUTE; } {D}+"."?\" | {D}*"."{D}+\" | [+-]?{D}+"."?({E})?\" | [+-]?{D}*"."{D}+({E})?\" { // seconds of arc yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ARCSECOND; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // Sexagesimal int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return SEXSTR; } [+-]?{D}+h{D}+m{D}+"."?s | [+-]?{D}+h{D}+m{D}*"."{D}+s { // HMS int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return HMSSTR; } [+-]?{D}+d{D}+m{D}+"."?s | [+-]?{D}+d{D}+m{D}*"."{D}+s { // DMS int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return DMSSTR; } \"[^\"\n]*\" | \'[^\'\n]*\' { // Quoted String int ll = (yyleng-2)<(MKBUFSIZE-1) ? (yyleng-2):(MKBUFSIZE-1); strncpy(mklval->str,yytext+1,ll); // skip the " " mklval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}\n]*\} { // Quoted String int ll = (yyleng-2)<(MKBUFSIZE-1) ? (yyleng-2):(MKBUFSIZE-1); strncpy(mklval->str,yytext+1,ll); // skip the '{' mklval->str[ll] = '\0'; // Remove the '}' return STRING; } [0-9A-Za-z]+ { // General String int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \\n { // fake line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% void mkDiscard(int doit) { if (mklexx) mklexx->begin(DISCARD, doit); } void mkFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ����������������������������������������������������������������������������������������./saods9/saotk/frame/grid25d.C����������������������������������������������������������������������0000644�0001750�0001750�00000007325�12001331443�014660� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid25d.h" #include "context.h" #include "frame3dbase.h" #include "fitsimage.h" extern "C" { #include "ast.h" } extern Grid25dBase* astGrid25dPtr; Grid25d::Grid25d(Widget* p, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, GridType t, const char* o, const char* v) : Grid(sys, sky, format, t, v), Grid25dBase(p,o) {} Grid25d::~Grid25d() {} int Grid25d::doit(RenderMode rm) { Frame3dBase* pp = (Frame3dBase*)parent_; matrix_ = pp->widgetToCanvas; gc_ = pp->gridGC; pixmap_ = pp->pixmap; renderMode_ = rm; Context* context = pp->keyContext; FitsImage* fits = context->fits; if (!fits) return 1; int width = fits->width(); int height = fits->height(); astClearStatus; // just to make sure astBegin; // start memory management AstFrameSet* frameSet = NULL; FitsBound* params = fits->getDataParams(context->frScale.scanMode()); switch (system_) { case Coord::IMAGE: frameSet = (AstFrameSet*)matrixMap(fits->refToImage,"Domain=IMAGE"); break; case Coord::PHYSICAL: frameSet = (AstFrameSet*)matrixMap(fits->refToPhysical,"Domain=PHYSICAL"); break; case Coord::AMPLIFIER: frameSet = (AstFrameSet*)matrixMap(fits->refToAmplifier,"Domain=AMPLIFIER"); break; case Coord::DETECTOR: frameSet = (AstFrameSet*)matrixMap(fits->refToDetector,"Domain=DETECTOR"); default: { // imageToData frame/map double ss[] = {-.5, -.5}; AstShiftMap *sm = astShiftMap(2, ss, " "); AstFrame *df = astFrame(2, "Domain=DATA"); // Get 2D SkyFrame AstFrameSet* wcs = (AstFrameSet*)astCopy(fits->getAST(system_)); if (astIsASkyFrame(astGetFrame(wcs, AST__CURRENT))) fits->setAstSkyFrame(wcs, sky_); // astShow(wcs); // Record the index of the current Frame int isky = astGetI(wcs, "Current"); // Add the new DATA Frame into the FrameSet, using the ShiftMap to // connect it to the existing IMAGE Frame. astAddFrame(wcs, AST__BASE, sm, df); // The above call to astAddFrame will have changed the current Frame // in the FrameSet to be the new DATA Frame. First record the index of // the DATA Frame, and then re-instate the original current Frame (i.e. // the SKY Frame). int idata = astGetI(wcs, "Current"); astSetI(wcs, "Current", isky); // make the DATA Frame the new base Frame astSetI(wcs, "Base", idata); frameSet = wcs; } } if (!frameSet) return 0; astSet(frameSet,"Title=%s", " "); // create astPlot float gbox[4]; double pbox[4]; Vector ll = Vector(params->xmin,params->ymin); Vector ur = Vector(params->xmax,params->ymax); Vector gll = ll * fits->dataToWidget; Vector gur = ur * fits->dataToWidget; pbox[0] = gbox[0] = ll[0]; pbox[1] = gbox[1] = ll[1]; pbox[2] = gbox[2] = ur[0]; pbox[3] = gbox[3] = ur[1]; // and now create astGrid astGrid25dPtr = this; AstPlot* plot = astPlot(frameSet, gbox, pbox, option_); astGrid(plot); astEnd; // now, clean up memory astGrid25dPtr =NULL; return 1; } void* Grid25d::matrixMap(Matrix& mx, const char* str) { double ss[] = {mx.matrix(0,0),mx.matrix(1,0), mx.matrix(0,1),mx.matrix(1,1)}; double tt[] = {mx.matrix(2,0),mx.matrix(2,1)}; AstMatrixMap* mm = astMatrixMap(2, 2, 0, ss, ""); AstShiftMap* sm = astShiftMap(2, tt, ""); AstCmpMap* cmap = astCmpMap(mm, sm, 1, ""); AstFrame* in = astFrame(2,"Domain=REF"); AstFrame* out = astFrame(2,str); AstFrameSet* frameSet = astFrameSet(in,""); astAddFrame(frameSet,AST__CURRENT,cmap,out); return frameSet; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/point.C������������������������������������������������������������������������0000644�0001750�0001750�00000052115�12012511326�014550� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "point.h" #include "fitsimage.h" #define NUMSEG 16 Point::Point(const Point& a) : Marker(a) { shape_ = a.shape_; shapestr_ = dupstr(a.shapestr_); size_ = a.size_; } Point::Point(Base* p, const Vector& ctr, PointShape ss, int size, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { strcpy(type_, "point"); shape_ = ss; shapeStr(ss); size_ = size; handle = new Vector[4]; numHandle = 4; updateBBox(); } Point::~Point() { if (shapestr_) delete [] shapestr_; } // X11 void Point::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector* vv = NULL; switch (shape_) { case CIRCLE: renderXCircle(drawable, sys, mode, size_); break; case BOX: renderXBox(drawable, sys, mode); break; case DIAMOND: vv = generateDiamond(sys); XDrawLine(display, drawable, lgc, vv[0][0], vv[0][1], vv[1][0], vv[1][1]); XDrawLine(display, drawable, lgc, vv[1][0], vv[1][1], vv[2][0], vv[2][1]); XDrawLine(display, drawable, lgc, vv[2][0], vv[2][1], vv[3][0], vv[3][1]); XDrawLine(display, drawable, lgc, vv[3][0], vv[3][1], vv[0][0], vv[0][1]); break; case CROSS: vv = generateCross(sys); XDrawLine(display, drawable, lgc, vv[0][0], vv[0][1], vv[1][0], vv[1][1]); XDrawLine(display, drawable, lgc, vv[2][0], vv[2][1], vv[3][0], vv[3][1]); break; case EX: vv = generateEx(sys); XDrawLine(display, drawable, lgc, vv[0][0], vv[0][1], vv[1][0], vv[1][1]); XDrawLine(display, drawable, lgc, vv[2][0], vv[2][1], vv[3][0], vv[3][1]); break; case ARROW: vv = generateArrow(sys); XDrawLine(display, drawable, lgc, vv[0][0], vv[0][1], vv[3][0], vv[3][1]); XDrawLine(display, drawable, lgc, vv[1][0], vv[1][1], vv[3][0], vv[3][1]); XDrawLine(display, drawable, lgc, vv[2][0], vv[2][1], vv[3][0], vv[3][1]); break; case BOXCIRCLE: renderXBox(drawable, sys, mode); renderXCircle(drawable, sys, mode, size_-2); break; } if (vv) delete [] vv; } void Point::renderXCircle(Drawable drawable, Coord::InternalSystem sys, RenderMode mode, int rr) { GC lgc = renderXGC(mode); if (parent->isAzElZero()) { Vector cc = parent->mapFromRef(center,sys); Vector v = cc*Translate(-Vector(rr,rr)/2); #ifndef _WIN32 XDrawArc(display, drawable, lgc, v[0], v[1], rr, rr, 0, 360*64); #else int ss = int(rr/2.+.5)*2; XDrawArc(display, drawable, lgc, v[0], v[1], ss, ss, 0, 360*64); #endif } else { Vector* vv = generateCircle(sys, rr); for (int ii=1; ii<=NUMSEG; ii++) XDrawLine(display, drawable, lgc, vv[ii-1][0], vv[ii-1][1], vv[ii][0], vv[ii][1]); delete [] vv; } } void Point::renderXBox(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector* vv = generateBox(sys); XDrawLine(display, drawable, lgc, vv[0][0], vv[0][1], vv[1][0], vv[1][1]); XDrawLine(display, drawable, lgc, vv[1][0], vv[1][1], vv[2][0], vv[2][1]); XDrawLine(display, drawable, lgc, vv[2][0], vv[2][1], vv[3][0], vv[3][1]); XDrawLine(display, drawable, lgc, vv[3][0], vv[3][1], vv[0][0], vv[0][1]); delete [] vv; } void Point::renderXLineDash(GC lgc) { char dl[2]; #ifdef _WIN32 dl[0] = dlist[0]/2; dl[1] = dlist[1]/2; #else dl[0] = ceil(dlist[0]/2.); dl[1] = ceil(dlist[1]/2.); #endif int ww = (highlited && canHighlite()) ? lineWidth*2 : lineWidth; XSetDashes(display, lgc, 0, dl, 2); XSetLineAttributes(display, lgc, ww, LineOnOffDash, CapButt, JoinMiter); } // PS void Point::renderPS(int mode) { renderPSGC(mode); Vector* vv =NULL; ostringstream str; switch (shape_) { case CIRCLE: renderPSCircle(mode, size_); break; case BOX: renderPSBox(mode); break; case DIAMOND: vv = generateDiamond(Coord::CANVAS); str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[1].TkCanvasPs(parent->canvas) << " lineto" << endl << vv[2].TkCanvasPs(parent->canvas) << " lineto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto" << endl << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); break; case CROSS: vv = generateCross(Coord::CANVAS); str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[1].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "newpath " << vv[2].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); break; case EX: vv = generateEx(Coord::CANVAS); str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[1].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "newpath " << vv[2].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); break; case ARROW: vv = generateArrow(Coord::CANVAS); str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "newpath " << vv[1].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << "newpath " << vv[2].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); break; case BOXCIRCLE: renderPSBox(mode); renderPSCircle(mode,size_-2); break; } if (vv) delete [] vv; } void Point::renderPSCircle(int mode, int ss) { if (parent->isAzElZero()) { Vector cc = parent->mapFromRef(center,Coord::CANVAS); ostringstream str; str << "newpath " << cc.TkCanvasPs(parent->canvas) << ss/2. << " 0 360 arc stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } else { Vector* vv = generateCircle(Coord::CANVAS,ss); ostringstream str; str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto " << endl; for (int ii=1; ii<NUMSEG; ii++) str << vv[ii].TkCanvasPs(parent->canvas) << " lineto" << endl; str << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); delete [] vv; } } void Point::renderPSBox(int mode) { Vector* vv = generateBox(Coord::CANVAS); ostringstream str; str << "newpath " << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl << vv[1].TkCanvasPs(parent->canvas) << " lineto" << endl << vv[2].TkCanvasPs(parent->canvas) << " lineto" << endl << vv[3].TkCanvasPs(parent->canvas) << " lineto" << endl << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); delete [] vv; } void Point::renderPSLineDash() { ostringstream str; str << lineWidth << " setlinewidth" << endl; str << '[' << dlist[0]/2. << ' ' << dlist[1]/2. << "] 0 setdash" << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); } // MacOSX #ifdef _MACOSX void Point::renderMACOSX() { renderMACOSXGC(); switch (shape_) { case CIRCLE: renderMACOSXCircle(size_); break; case BOX: renderMACOSXBox(); break; case DIAMOND: vv = generateDiamond(Coord::CANVAS); macosxDrawLines(vv,5); break; case CROSS: vv = generateCross(Coord::CANVAS); macosxDrawLine(vv[0],vv[1]); macosxDrawLine(vv[2],vv[3]); break; case EX: vv = generateEx(Coord::CANVAS); macosxDrawLine(vv[0],vv[1]); macosxDrawLine(vv[2],vv[3]); break; case ARROW: vv = generateArrow(Coord::CANVAS); macosxDrawLine(vv[0],vv[3]); macosxDrawLine(vv[1],vv[3]); macosxDrawLine(vv[2],vv[3]); break; case BOXCIRCLE: renderMACOSXBox(); renderMACOSXCircle(size_-2); break; } if (vv) delete [] vv; } void Point::renderMACOSXCircle(int ss) { renderMACOSXGC(); if (parent->isAzElZero()) { Vector cc = parent->mapFromRef(center,Coord::CANVAS); macosxDrawArc(cc, ss/2., 0, M_TWOPI); } else { Vector* vv = generateCircle(Coord::CANVAS, ss); macosxDrawLines(vv,NUMSEG+1); delete [] vv; } } void Point::renderMACOSXBox() { renderMACOSXGC(); Vector* vv = generateBox(Coord::CANVAS); macosxDrawLines(vv,5); delete [] vv; } void Point::renderMACOSXLineDash() { macosxWidth(lineWidth); float dl[2]; dl[0] = dlist[0]/2.; dl[1] = dlist[1]/2.; macosxDash(dl,2); } #endif // WIN32 #ifdef _WIN32 void Point::renderWIN32() { renderWIN32GC(); Vector* vv = NULL; switch (shape_) { case CIRCLE: renderWIN32Circle(size_); break; case BOX: renderWIN32Box(); break; case DIAMOND: vv = generateDiamond(Coord::CANVAS); win32DrawLines(vv,5); break; case CROSS: vv = generateCross(Coord::CANVAS); win32DrawLine(vv[0],vv[1]); win32DrawLine(vv[2],vv[3]); break; case EX: vv = generateEx(Coord::CANVAS); win32DrawLine(vv[0],vv[1]); win32DrawLine(vv[2],vv[3]); break; case ARROW: vv = generateArrow(Coord::CANVAS); win32DrawLine(vv[0],vv[3]); win32DrawLine(vv[1],vv[3]); win32DrawLine(vv[2],vv[3]); break; case BOXCIRCLE: renderWIN32Box(); renderWIN32Circle(size_-2); break; } if (vv) delete [] vv; } void Point::renderWIN32Circle(int ss) { if (parent->isAzElZero()) { Vector cc = parent->mapFromRef(center,Coord::CANVAS); win32DrawArc(cc, ss/2., 0, M_TWOPI); } else { Vector* vv = generateCircle(Coord::CANVAS, ss); win32DrawLines(vv,NUMSEG+1); delete [] vv; } } void Point::renderWIN32Box() { Vector* vv = generateBox(Coord::CANVAS); win32DrawLines(vv,5); delete [] vv; } void Point::renderWIN32LineDash() { win32Width(lineWidth); float dl[2]; dl[0] = dlist[0]/2.; dl[1] = dlist[1]/2.; win32Dash(dl,2); } #endif // Support Vector* Point::generateCircle(Coord::InternalSystem sys, int ss) { Vector* vv = new Vector[NUMSEG+1]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector cc = center*mm; for (int ii=0; ii<NUMSEG; ii++) { double ang = ii*M_TWOPI/NUMSEG; Vector xy = Vector(cos(ang)*ss/2, sin(ang)*ss/2); Vector aa = cc+xy; Vector bb = aa*nn; vv[ii] = parent->mapFromRef(bb,sys); } vv[NUMSEG] = vv[0]; return vv; } Vector* Point::generateBox(Coord::InternalSystem sys) { Vector* vv = new Vector[5]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); double ss = size_/2; Vector cc = center*mm; Vector v1a = cc+Vector(-ss,-ss); Vector v1b = v1a*nn; vv[0] = parent->mapFromRef(v1b,sys); Vector v2a = cc+Vector(-ss,ss); Vector v2b = v2a*nn; vv[1] = parent->mapFromRef(v2b,sys); Vector v3a = cc+Vector(ss,ss); Vector v3b = v3a*nn; vv[2] = parent->mapFromRef(v3b,sys); Vector v4a = cc+Vector(ss,-ss); Vector v4b = v4a*nn; vv[3] = parent->mapFromRef(v4b,sys); vv[4] = vv[0]; return vv; } Vector* Point::generateDiamond(Coord::InternalSystem sys) { Vector* vv = new Vector[5]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector xx = Vector(size_-1,0)/2; Vector yy = Vector(0,size_-1)/2; Vector cc = center*mm; Vector v1a = cc-xx; Vector v1b = v1a*nn; vv[0] = parent->mapFromRef(v1b,sys); Vector v2a = cc-yy; Vector v2b = v2a*nn; vv[1] = parent->mapFromRef(v2b,sys); Vector v3a = cc+xx; Vector v3b = v3a*nn; vv[2] = parent->mapFromRef(v3b,sys); Vector v4a = cc+yy; Vector v4b = v4a*nn; vv[3] = parent->mapFromRef(v4b,sys); vv[4] = vv[0]; return vv; } Vector* Point::generateCross(Coord::InternalSystem sys) { Vector* vv = new Vector[4]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector xx = Vector(size_,0)/2; Vector yy = Vector(0,size_)/2; Vector cc = center*mm; Vector v1a = cc-xx; Vector v1b = v1a*nn; vv[0] = parent->mapFromRef(v1b,sys); Vector v2a = cc+xx; Vector v2b = v2a*nn; vv[1] = parent->mapFromRef(v2b,sys); Vector v3a = cc-yy; Vector v3b = v3a*nn; vv[2] = parent->mapFromRef(v3b,sys); Vector v4a = cc+yy; Vector v4b = v4a*nn; vv[3] = parent->mapFromRef(v4b,sys); return vv; } Vector* Point::generateEx(Coord::InternalSystem sys) { Vector* vv = new Vector[4]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector xy = Vector(-size_,-size_)/2; Vector yx = Vector( size_,-size_)/2; Vector cc = center*mm; Vector v1a = cc+xy; Vector v1b = v1a*nn; vv[0] = parent->mapFromRef(v1b,sys); Vector v2a = cc-xy; Vector v2b = v2a*nn; vv[1] = parent->mapFromRef(v2b,sys); Vector v3a = cc+yx; Vector v3b = v3a*nn; vv[2] = parent->mapFromRef(v3b,sys); Vector v4a = cc-yx; Vector v4b = v4a*nn; vv[3] = parent->mapFromRef(v4b,sys); return vv; } Vector* Point::generateArrow(Coord::InternalSystem sys) { Vector* vv = new Vector[4]; Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector xx = Vector(-size_,0)/2; Vector yy = Vector(0,-size_)/2; Vector cc = center*mm; Vector v1a = cc+xx; Vector v1b = v1a*nn; vv[0] = parent->mapFromRef(v1b,sys); Vector v2a = cc+yy; Vector v2b = v2a*nn; vv[1] = parent->mapFromRef(v2b,sys); Vector v3a = cc+xx+yy; Vector v3b = v3a*nn; vv[2] = parent->mapFromRef(v3b,sys); Vector v4a = cc; Vector v4b = v4a*nn; vv[3] = parent->mapFromRef(v4b,sys); return vv; } void Point::shapeStr(PointShape ss) { switch (ss) { case CIRCLE: shapestr_ = dupstr("circle"); break; case BOX: shapestr_ = dupstr("box"); break; case DIAMOND: shapestr_ = dupstr("diamond"); break; case CROSS: shapestr_ = dupstr("cross"); break; case EX: shapestr_ = dupstr("x"); break; case ARROW: shapestr_ = dupstr("arrow"); break; case BOXCIRCLE: shapestr_ = dupstr("boxcircle"); break; } } void Point::setShape(PointShape ss) { shape_ = ss; shapeStr(ss); updateBBox(); doCallBack(CallBack::EDITCB); } void Point::setSize(int size) { size_ = size; updateBBox(); doCallBack(CallBack::EDITCB); } void Point::updateHandles() { // bound marker double ss = size_/2; Vector cc = center*parent->refToCanvas; Vector lla = cc+Vector(-ss,-ss); Vector llb = lla*parent->canvasToRef; Vector ll = parent->mapFromRef(llb,Coord::CANVAS); Vector lra = cc+Vector(-ss,ss); Vector lrb = lra*parent->canvasToRef; Vector lr = parent->mapFromRef(lrb,Coord::CANVAS); Vector ura = cc+Vector(ss,ss); Vector urb = ura*parent->canvasToRef; Vector ur = parent->mapFromRef(urb,Coord::CANVAS); Vector ula = cc+Vector(ss,-ss); Vector ulb = ula*parent->canvasToRef; Vector ul = parent->mapFromRef(ulb,Coord::CANVAS); handle[0] = ll; handle[1] = lr; handle[2] = ur; handle[3] = ul; } void Point::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT3D: if (!analysisPlot3d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot3dCB_[1], parent->options->cmdName); } if (analysisPlot3d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot3dCB_[1]); } analysisPlot3d_ = which; break; } } void Point::analysisPlot3d(char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { double* x; double* y; Vector ll = -Vector(.5,.5) * Translate(center); Vector ur = Vector(.5,.5) * Translate(center); BBox bb(ll,ur); int num = parent->markerAnalysisPlot3d(this, &x, &y, bb, sys, method); analysisPlot3dResult(xname, yname, x, y, num); } int Point::isIn(const Vector& vv, Coord::InternalSystem sys) { Vector pp = bckMap(vv,sys); if (pp[0]<-.5 || pp[0]>=.5 || pp[1]<-.5 || pp[1]>=.5) return 0; else return 1; } // list void Point::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } } } listPost(str, conj, strip); } void Point::listPost(ostream& str, int conj, int strip) { // no props for semicolons if (!strip) { if (conj) str << " ||"; str << " # point=" << shapestr_; if (size_ != POINTSIZE) str << ' ' << size_; listProperties(str,0); } else { if (conj) str << "||"; else str << ';'; } } void Point::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRow(XMLPARAM,shapestr_); XMLRow(XMLPARAM2,size_); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Point::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); listCiaoPre(str); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; default: if (ptr->hasWCSCel(sys)) { char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ')'; } break; } listCiaoPost(str, strip); } void Point::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector v = ptr->mapFromRef(center,sys); str << type_ << ' ' << setprecision(8) << v; } break; default: if (ptr->hasWCSCel(sys)) { coord.listProsCoordSystem(str,sys,sky); str << "; "; switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << ' ' << setprecision(8) << v[0] << "d " << v[1] << "d "; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') str << type_ << ' ' << ra << ' ' << dec+1; else str << type_ << ' ' << ra << ' ' << dec; } break; } } } listProsPost(str, strip); } void Point::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); listSAOtngPre(str, strip); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ')'; } break; } } } listSAOtngPost(str,strip); } void Point::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); // all coords are in image coords Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; listSAOimagePost(str, strip); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/saoparser.Y��������������������������������������������������������������������0000644�0001750�0001750�00000015351�11727715200�015456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {saoFlexLexer* ll} %parse-param {saoFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; saoDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer saoFlexLexer #include <FlexLexer.h> extern int saolex(void*, saoFlexLexer*); extern void saoerror(Base*, saoFlexLexer*, const char*); extern void saoDiscard(int); static unsigned short globalProps; static unsigned short localProps; static char *color = "green"; static int dash[] = {8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aStatus; static Vector aCenter; static double aAngle; static unsigned short aProps; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); %} %union { #define SAOBUFSIZE 2048 double real; int integer; char str[SAOBUFSIZE]; double vector[3]; } %type <real> numeric %type <real> angle %type <real> optangle %type <real> value %type <vector> vvalue %type <vector> coord %type <integer> numberof %token <integer> INT %token <real> REAL %token <str> STRING %token EOF_ %token ANNULUS_ %token BOX_ %token CIRCLE_ %token DEBUG_ %token ELLIPSE_ %token N_ %token OFF_ %token ON_ %token POINT_ %token POLYGON_ %token ROTBOX_ %token VERSION_ %% start : initGlobal commands processAnnulus ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "SAOimage" << endl;} | initLocal include shape | generalComment ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; sp : /* empty */ | ',' ; bp : /* empty */ | '(' ; ep : /* emtpy */ | ')' ; optangle: /* empty */ {$$ = 0;} | angle {$$ = $1;} ; angle : numeric {$$ = degToRad($1);} /* assume degree */ ; value : numeric {$$ = FITSPTR->mapLenToRef($1, Coord::IMAGE);} ; vvalue : numeric sp numeric { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; numberof: N_ '=' INT {$$ = $3;} ; coord : numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; initGlobal:{ globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; } ; initLocal : { // reset maperr flag maperr =0; localProps = globalProps; } ; include : /* empty */ {setProps(&localProps, Marker::INCLUDE, 1);} | '+' {setProps(&localProps, Marker::INCLUDE, 1);} | '-' {setProps(&localProps, Marker::INCLUDE, 0);} ; shape : CIRCLE_ bp coord sp value ep shapeComment {fr->createCircleCmd(Vector($3), $5, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ANNULUS_ bp coord sp value sp value ep shapeComment {fr->createAnnulusCmd(Vector($3), $5,$7,1, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ANNULUS_ bp coord sp value sp value sp {aNum=2;} aRads ep shapeComment { aAnnuli[0] = $5; aAnnuli[1] = $7; fr->createAnnulusCmd(Vector($3), aNum,aAnnuli, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ANNULUS_ bp coord sp value sp value sp numberof ep shapeComment {fr->createAnnulusCmd(Vector($3), $5,$7,$9, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ELLIPSE_ bp coord sp vvalue sp optangle ep shapeComment { // for ellipse annulus aStatus = 1; aCenter = Vector($3); aAngle = $7; aVector[0] = Vector($5); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp optangle ep '&' '!' ELLIPSE_ bp coord sp vvalue sp optangle ep { aStatus = 2; aVector[aNum++] = Vector($5); } | BOX_ bp coord sp vvalue sp optangle ep shapeComment { // for box annulus aStatus = 3; aCenter = Vector($3); aAngle = $7; aVector[0] = Vector($5); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ROTBOX_ bp coord sp vvalue sp optangle ep shapeComment {fr->createBoxCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | BOX_ bp coord sp vvalue sp optangle ep '&' '!' BOX_ bp coord sp vvalue sp optangle ep { aStatus = 4; aVector[aNum++] = Vector($5); } | POINT_ bp coord ep shapeComment {fr->createPointCmd(Vector($3), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | POLYGON_ {polylist.deleteAll();} bp polyNodes ep shapeComment {fr->createPolygonCmd(polylist, color,dash,1,font,text,localProps,localComment,taglist,cblist);} ; polyNodes : polyNodes sp polyNode | polyNode ; polyNode : coord {polylist.append(new Vertex($1));} ; aRads : aRads sp aRad | aRad ; aRad : value {aAnnuli[aNum++] = $1;} ; processAnnulus : /* empty */ { switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; } aStatus = 0; } ; generalComment : '#' {DISCARD_(1)} STRING ; shapeComment : /* empty */ processAnnulus | '#' {DISCARD_(0)} STRING processAnnulus {strncpy(localComment,$3,80);} ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basebox.C����������������������������������������������������������������������0000644�0001750�0001750�00000017057�12004304526�015053� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "basebox.h" #include "fitsimage.h" BaseBox::BaseBox(const BaseBox& a) : BaseMarker(a) { numPoints_ = a.numPoints_; vertices_ = NULL; } BaseBox::BaseBox(Base* p, const Vector& ctr, double ang, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb) : BaseMarker(p, ctr, ang, clr, dsh, w, f, t, prop, c, tag, cb) { numPoints_ = 5; vertices_ = NULL; } BaseBox::~BaseBox() { deleteVertices(); } void BaseBox::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); newVertices(); for (int ii=0; ii<numAnnuli_; ii++) { XPoint* pp = new XPoint[numPoints_]; for (int jj=0; jj<numPoints_; jj++) { Vector v = parent->mapFromRef(vertices_[ii][jj],sys); pp[jj].x = (short)v[0]; pp[jj].y = (short)v[1]; } XDrawLines(display, drawable, lgc, pp, numPoints_, CoordModeOrigin); delete [] pp; } deleteVertices(); } void BaseBox::renderPS(int mode) { renderPSGC(mode); newVertices(); for (int ii=0; ii<numAnnuli_; ii++) { for (int jj=0; jj<numPoints_; jj++) { Vector v = parent->mapFromRef(vertices_[ii][jj],Coord::CANVAS); ostringstream str; if (jj==0) str << "newpath " << endl << v.TkCanvasPs(parent->canvas) << " moveto" << endl << ends; else str << v.TkCanvasPs(parent->canvas) << " lineto" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } ostringstream str; str << "stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } deleteVertices(); } #ifdef _MACOSX void BaseBox::renderMACOSX() { renderMACOSXGC(); newVertices(); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv[numPoints_]; for (int jj=0; jj<numPoints_; jj++) vv[jj] = parent->mapFromRef(vertices_[ii][jj],CANVAS); macosxDrawLines(vv, numPoints_); } deleteVertices(); } #endif #ifdef _WIN32 void BaseBox::renderWIN32() { renderWIN32GC(); newVertices(); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv[numPoints_]; for (int jj=0; jj<numPoints_; jj++) vv[jj] = parent->mapFromRef(vertices_[ii][jj],Coord::CANVAS); win32DrawLines(vv, numPoints_); } deleteVertices(); } #endif // Support void BaseBox::updateHandles() { // handles are in canvas coords // we can't garantee that the radii have been sorted yet // also, annuli[i] could be negative if (handle) delete [] handle; handle = new Vector[numHandle]; Vector max; for(int ii=0; ii<numAnnuli_; ii++) { Vector foo = annuli_[ii].abs(); if (max[0]<foo[0]) max = foo; } Vector& s = max; handle[0] = fwdMap(Vector(-s[0],-s[1])/2,Coord::CANVAS); handle[1] = fwdMap(Vector( s[0],-s[1])/2,Coord::CANVAS); handle[2] = fwdMap(Vector( s[0], s[1])/2,Coord::CANVAS); handle[3] = fwdMap(Vector(-s[0], s[1])/2,Coord::CANVAS); // annuli if (numAnnuli_>1) for (int ii=0; ii<numAnnuli_; ii++) handle[ii+4] = fwdMap(Vector((annuli_[ii][0])/2.,0),Coord::CANVAS); } int BaseBox::isIn(const Vector& vv, Coord::InternalSystem sys, int nn) { // during resize, annuli_ can be negative Vector ss = annuli_[nn].abs(); // zero radius if (!ss[0] || !ss[1]) return 0; Vector pp = bckMap(vv,sys); if (pp[0]<-ss[0]/2 || pp[0]>=ss[0]/2 || pp[1]<=-ss[1]/2 || pp[1]>ss[1]/2) return 0; else return 1; } Vector BaseBox::intersect(Vector rr, double aa) { // special cases if (!rr[0] || !rr[1]) return Vector(); double ang = zeroTWOPI(aa); double phi = rr.angle(); if (ang >= 0 && ang < phi) return Vector(rr[0],-rr[0]*tan(ang)); else if (ang >= phi && ang < M_PI-phi) return Vector(rr[1]/tan(ang),-rr[1]); else if (ang >= M_PI-phi && ang < M_PI+phi) return Vector(-rr[0],rr[0]*tan(ang)); else if (ang >= M_PI+phi && ang < M_TWOPI-phi) return Vector(-rr[1]/tan(ang),rr[1]); else return Vector(rr[0],-rr[0]*tan(ang)); } void BaseBox::newVertices() { if (vertices_) deleteVertices(); if (teq(startAng_,stopAng_-M_TWOPI,FLT_EPSILON)) newVerticesA(); else newVerticesB(); } void BaseBox::newVerticesA() { Matrix mm = fwdMatrix(); numPoints_ = 5; vertices_ = new Vector*[numAnnuli_+1]; for (int i=0; i<numAnnuli_; i++) vertices_[i]= new Vector[numPoints_]; vertices_[numAnnuli_] = new Vector[2]; for (int i=0; i<numAnnuli_; i++) { vertices_[i][0] = Vector(-annuli_[i][0]/2.,-annuli_[i][1]/2.) * mm; vertices_[i][1] = Vector( annuli_[i][0]/2.,-annuli_[i][1]/2.) * mm; vertices_[i][2] = Vector( annuli_[i][0]/2., annuli_[i][1]/2.) * mm; vertices_[i][3] = Vector(-annuli_[i][0]/2., annuli_[i][1]/2.) * mm; vertices_[i][4] = Vector(-annuli_[i][0]/2.,-annuli_[i][1]/2.) * mm; } vertices_[numAnnuli_][0] = vertices_[numAnnuli_-1][0]; vertices_[numAnnuli_][1] = vertices_[numAnnuli_-1][2]; } void BaseBox::newVerticesB() { numPoints_ = 0; // we will increment later vertices_ = new Vector*[numAnnuli_+1]; for (int ii=0; ii<numAnnuli_; ii++) vertices_[ii]= new Vector[7]; vertices_[numAnnuli_] = new Vector[2]; double a1 = zeroTWOPI(startAng_); double a2 = zeroTWOPI(stopAng_); if (a2 <= a1) a2 += M_TWOPI; int cnt = 0; for (int ii=0; ii<numAnnuli_; ii++) { Vector rr = (annuli_[ii]).abs(); if (rr[0] && rr[1]) { double phi = rr.angle(); int s1 =0; int s2 =0; cnt = 0; vertBTest(&s1, &s2, a1, a2, 0, phi, ii, &cnt); vertBTest(&s1, &s2, a1, a2, phi, M_PI-phi, ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_PI-phi, M_PI+phi, ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_PI+phi, M_TWOPI-phi, ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_TWOPI-phi,M_TWOPI , ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_TWOPI,M_TWOPI+phi , ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_TWOPI+phi,M_THREEPI-phi , ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_THREEPI-phi,M_THREEPI+phi , ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_THREEPI+phi,M_FOURPI-phi , ii, &cnt); vertBTest(&s1, &s2, a1, a2, M_FOURPI-phi,M_FOURPI, ii, &cnt); } } // final number of segments numPoints_ = ++cnt; // include/exclude Matrix mm = fwdMatrix(); vertices_[numAnnuli_][0] = Vector(-annuli_[numAnnuli_-1][0]/2.,-annuli_[numAnnuli_-1][1]/2.) * mm; vertices_[numAnnuli_][1] = Vector( annuli_[numAnnuli_-1][0]/2., annuli_[numAnnuli_-1][1]/2.) * mm; } void BaseBox::vertBTest(int* s1, int* s2, double a1, double a2, double b1, double b2, int ii, int* cnt) { if ((!(*s1)) && (a1>=b1) && (a1<b2)) *s1 =1; if ((!(*s2)) && (a2>b1) && (a2<=b2)) *s2 =1; if (((*s1) && (!(*s2))) || ((*s1) && (*s2))) vertBPrep(a1,a2,b1,b2,ii,cnt); if (*s1&&*s2) *s1=*s2=0; } void BaseBox::vertBPrep(double a1, double a2, double ll, double ul, int ii, int* cnt) { if (!(a1 >= ll) && (a1 <= ul)) a1 = ll; if (!(a2 >= ll) && (a2 <= ul)) a2 = ul; if (a1 > a2) { vertBSeg(ll,a2,ii,cnt); vertBSeg(a1,ul,ii,cnt); } else vertBSeg(a1,a2,ii,cnt); } void BaseBox::vertBSeg(double ang1, double ang2, int ii, int* cnt) { Vector rr = (annuli_[ii]/2).abs(); Matrix mm = fwdMatrix(); vertices_[ii][(*cnt)++] = intersect(rr,ang1)*mm; vertices_[ii][(*cnt)] = intersect(rr,ang2)*mm; } void BaseBox::deleteVertices() { if (vertices_) { for (int i=0; i<numAnnuli_+1; i++) if (vertices_[i]) delete [] vertices_[i]; delete [] vertices_; } vertices_ = NULL; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/tag.C��������������������������������������������������������������������������0000644�0001750�0001750�00000001010�11700666271�014173� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tag.h" #include "util.h" Tag::Tag(const Tag& t) { tag_ = dupstr(t.tag_); } Tag::Tag(const char* t) { tag_ = dupstr(t); } Tag& Tag::operator=(const Tag& t) { tag_ = dupstr(t.tag_); return *this; } Tag::~Tag() { if (tag_) delete [] tag_; } void Tag::set(const char* t) { if (tag_) delete tag_; tag_ = dupstr(t); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/callback.C���������������������������������������������������������������������0000644�0001750�0001750�00000001752�11700666266�015175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <string.h> #include "callback.h" CallBack::CallBack(const CallBack& a) { interp_ = a.interp_; type_ = a.type_; strcpy(proc_, a.proc_); strcpy(arg_, a.arg_); previous_ = NULL; next_ = NULL; } CallBack& CallBack::operator=(const CallBack& a) { interp_ = a.interp_; type_ = a.type_; strcpy(proc_, a.proc_); strcpy(arg_, a.arg_); previous_ = NULL; next_ = NULL; return *this; } CallBack::CallBack(Tcl_Interp* interp, Type type, const char* proc, const char* arg) { interp_ = interp; type_ = type; if (proc) strncpy(proc_, proc, 32); else proc_[0] = '\0'; if (arg) strncpy(arg_, arg, 64); else arg_[0] = '\0'; previous_ = NULL; next_ = NULL; } int CallBack::eval(const char* arg2) { return Tcl_VarEval(interp_, proc_, " ", arg_, " ", arg2, NULL); } ����������������������./saods9/saotk/frame/frametruecolor8.C��������������������������������������������������������������0000644�0001750�0001750�00000012473�11700666270�016557� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frametruecolor8.h" #include "colorscaletrue8.h" // Tk Canvas Widget Function Declarations int FrameTrueColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameTrueColor8 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameTrueColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameTrueColor8Type = { (char*)"frametruecolor8", // name sizeof(WidgetOptions), // item size FrameTrueColor8CreateProc, // configProc frameTrueColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameTrueColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameTrueColor8Type); return TCL_OK; } int FrameTrueColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameTrueColor8* frame = new FrameTrueColor8(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameTrueColor8 Member Functions FrameTrueColor8::FrameTrueColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameTrueColor(i,c,item), TrueColor8(visual) { configSpecs = frameTrueColor8Specs; // frame configure options } FrameTrueColor8::~FrameTrueColor8() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void FrameTrueColor8::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells) return; if (colorScale) delete colorScale; switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor8(colorCount, indexCells, colorCells, colorCount, visual); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor8(indexCells, colorCells, colorCount, visual); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual); break; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xyparser.Y���������������������������������������������������������������������0000644�0001750�0001750�00000012415�11727715200�015332� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {xyFlexLexer* ll} %parse-param {xyFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer xyFlexLexer #include <FlexLexer.h> extern int xylex(void*, xyFlexLexer*); extern void xyerror(Base*, xyFlexLexer*, const char*); static int dash[] = {8,3}; static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static List<Tag> taglist; static List<CallBack> cblist; %} %union { #define XYBUFSIZE 2048 double real; int integer; char str[XYBUFSIZE]; double vector[3]; } %type <real> numeric %type <real> sexagesimal %type <real> hms %type <real> dms %type <vector> coord %type <integer> coordSystem %type <integer> skyFrame %token <integer> INT %token <real> REAL %token <real> ANGDEGREE %token <str> SEXSTR %token <str> HMSSTR %token <str> DMSSTR %token EOF_ %token AMPLIFIER_ %token B1950_ %token CCD_ %token DEBUG_ %token DETECTOR_ %token ECLIPTIC_ %token FK4_ %token FK4_NO_E_ %token FK5_ %token GALACTIC_ %token HELIOECLIPTIC_ %token ICRS_ %token IMAGE_ %token J2000_ %token LOGICAL_ %token OFF_ %token ON_ %token PHYSICAL_ %token SUPERGALACTIC_ %token VERSION_ %token WCS_ %token WCSA_ %token WCSB_ %token WCSC_ %token WCSD_ %token WCSE_ %token WCSF_ %token WCSG_ %token WCSH_ %token WCSI_ %token WCSJ_ %token WCSK_ %token WCSL_ %token WCSM_ %token WCSN_ %token WCSO_ %token WCSP_ %token WCSQ_ %token WCSR_ %token WCSS_ %token WCST_ %token WCSU_ %token WCSV_ %token WCSW_ %token WCSX_ %token WCSY_ %token WCSZ_ %% start : { globalSystem = fr->xySystem(); globalSky = fr->xySky(); } commands ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "X Y Format 1.0" << endl;} | coordSystem {globalSystem = (Coord::CoordSystem)$1;} | coordSystem skyFrame {globalSystem = (Coord::CoordSystem)$1; globalSky = (Coord::SkyFrame)$2;} | {localSystem = globalSystem; localSky = globalSky; maperr = 0;} shape comment ; comment : /* empty */ | junks ; junks : junks junk | junk ; junk : numeric {} ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; sp : /* empty */ | ',' ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; hms : HMSSTR {$$ = parseHMSStr($1);} ; dms : DMSSTR {$$ = parseDMSStr($1);} ; coord : sexagesimal sp sexagesimal { Vector r; if (localSky == Coord::GALACTIC || localSky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector($1,$3),localSystem,localSky); else r = FITSPTR->mapToRef(Vector($1*360./24.,$3),localSystem,localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | hms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3),localSystem,localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | dms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3),localSystem,localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3),localSystem,localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r = FITSPTR->mapToRef(Vector($1,$3),localSystem,localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; coordSystem : IMAGE_ {$$ = Coord::IMAGE;} | LOGICAL_ {$$ = Coord::IMAGE;} | PHYSICAL_ {$$ = Coord::PHYSICAL;} | CCD_ {$$ = Coord::PHYSICAL;} | AMPLIFIER_ {$$ = Coord::AMPLIFIER;} | DETECTOR_ {$$ = Coord::DETECTOR;} | WCS_ {$$ = Coord::WCS;} | WCSA_ {$$ = Coord::WCSA;} | WCSB_ {$$ = Coord::WCSB;} | WCSC_ {$$ = Coord::WCSC;} | WCSD_ {$$ = Coord::WCSD;} | WCSE_ {$$ = Coord::WCSE;} | WCSF_ {$$ = Coord::WCSF;} | WCSG_ {$$ = Coord::WCSG;} | WCSH_ {$$ = Coord::WCSH;} | WCSI_ {$$ = Coord::WCSI;} | WCSJ_ {$$ = Coord::WCSJ;} | WCSK_ {$$ = Coord::WCSK;} | WCSL_ {$$ = Coord::WCSL;} | WCSM_ {$$ = Coord::WCSM;} | WCSN_ {$$ = Coord::WCSN;} | WCSO_ {$$ = Coord::WCSO;} | WCSP_ {$$ = Coord::WCSP;} | WCSQ_ {$$ = Coord::WCSQ;} | WCSR_ {$$ = Coord::WCSR;} | WCSS_ {$$ = Coord::WCSS;} | WCST_ {$$ = Coord::WCST;} | WCSU_ {$$ = Coord::WCSU;} | WCSV_ {$$ = Coord::WCSV;} | WCSW_ {$$ = Coord::WCSW;} | WCSX_ {$$ = Coord::WCSX;} | WCSY_ {$$ = Coord::WCSY;} | WCSZ_ {$$ = Coord::WCSZ;} ; skyFrame : FK4_ {$$ = Coord::FK4;} | B1950_ {$$ = Coord::FK4;} | FK4_NO_E_ {$$ = Coord::FK4_NO_E;} | FK5_ {$$ = Coord::FK5;} | J2000_ {$$ = Coord::FK5;} | ICRS_ {$$ = Coord::ICRS;} | GALACTIC_ {$$ = Coord::GALACTIC;} | SUPERGALACTIC_ {$$ = Coord::SUPERGALACTIC;} | ECLIPTIC_ {$$ = Coord::ECLIPTIC;} | HELIOECLIPTIC_ {$$ = Coord::HELIOECLIPTIC;} ; shape : coord {fr->createPointCmd(Vector($1), Point::BOXCIRCLE, POINTSIZE, "green",dash,1,"helvetica 10 normal roman","", Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE, "",taglist,cblist); } ; %% ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor24.h�����������������������������������������������������������0000644�0001750�0001750�00000001402�11700666267�017125� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3dtruecolor24_h__ #define __frame3dtruecolor24_h__ #include "frame3dtruecolor.h" #include "truecolor24.h" class Frame3dTrueColor24 : public Frame3dTrueColor, public TrueColor24 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor24::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor24::encodeTrueColor(src, ximage);} void updateColorScale(); void updateColorScale24(); void updateColorScale32(); public: Frame3dTrueColor24(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~Frame3dTrueColor24(); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xyparser.H���������������������������������������������������������������������0000644�0001750�0001750�00000010251�11626771531�015314� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, ANGDEGREE = 260, SEXSTR = 261, HMSSTR = 262, DMSSTR = 263, EOF_ = 264, AMPLIFIER_ = 265, B1950_ = 266, CCD_ = 267, DEBUG_ = 268, DETECTOR_ = 269, ECLIPTIC_ = 270, FK4_ = 271, FK4_NO_E_ = 272, FK5_ = 273, GALACTIC_ = 274, HELIOECLIPTIC_ = 275, ICRS_ = 276, IMAGE_ = 277, J2000_ = 278, LOGICAL_ = 279, OFF_ = 280, ON_ = 281, PHYSICAL_ = 282, SUPERGALACTIC_ = 283, VERSION_ = 284, WCS_ = 285, WCSA_ = 286, WCSB_ = 287, WCSC_ = 288, WCSD_ = 289, WCSE_ = 290, WCSF_ = 291, WCSG_ = 292, WCSH_ = 293, WCSI_ = 294, WCSJ_ = 295, WCSK_ = 296, WCSL_ = 297, WCSM_ = 298, WCSN_ = 299, WCSO_ = 300, WCSP_ = 301, WCSQ_ = 302, WCSR_ = 303, WCSS_ = 304, WCST_ = 305, WCSU_ = 306, WCSV_ = 307, WCSW_ = 308, WCSX_ = 309, WCSY_ = 310, WCSZ_ = 311 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define ANGDEGREE 260 #define SEXSTR 261 #define HMSSTR 262 #define DMSSTR 263 #define EOF_ 264 #define AMPLIFIER_ 265 #define B1950_ 266 #define CCD_ 267 #define DEBUG_ 268 #define DETECTOR_ 269 #define ECLIPTIC_ 270 #define FK4_ 271 #define FK4_NO_E_ 272 #define FK5_ 273 #define GALACTIC_ 274 #define HELIOECLIPTIC_ 275 #define ICRS_ 276 #define IMAGE_ 277 #define J2000_ 278 #define LOGICAL_ 279 #define OFF_ 280 #define ON_ 281 #define PHYSICAL_ 282 #define SUPERGALACTIC_ 283 #define VERSION_ 284 #define WCS_ 285 #define WCSA_ 286 #define WCSB_ 287 #define WCSC_ 288 #define WCSD_ 289 #define WCSE_ 290 #define WCSF_ 291 #define WCSG_ 292 #define WCSH_ 293 #define WCSI_ 294 #define WCSJ_ 295 #define WCSK_ 296 #define WCSL_ 297 #define WCSM_ 298 #define WCSN_ 299 #define WCSO_ 300 #define WCSP_ 301 #define WCSQ_ 302 #define WCSR_ 303 #define WCSS_ 304 #define WCST_ 305 #define WCSU_ 306 #define WCSV_ 307 #define WCSW_ 308 #define WCSX_ 309 #define WCSY_ 310 #define WCSZ_ 311 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 41 "xyparser.Y" { #define XYBUFSIZE 2048 double real; int integer; char str[XYBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 169 "xyparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor.C������������������������������������������������������������0000644�0001750�0001750�00000016165�12107012362�017151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "framergbtruecolor.h" #include "fitsimage.h" #include "ps.h" #include "sigbus.h" FrameRGBTrueColor::FrameRGBTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameRGB(i,c,item), FrameTrue(i,c,item) { for (int kk=0; kk<3; kk++) colormapData[kk] = NULL; } FrameRGBTrueColor::~FrameRGBTrueColor() { for (int kk=0; kk<3; kk++) if (colormapData[kk]) delete [] colormapData[kk]; } void FrameRGBTrueColor::buildXImage(XImage* ximage, Coord::InternalSystem sys) { // we need a colorScale before we can render if (!validColorScale()) return; unsigned char* img = fillImage(ximage->width, ximage->height, sys); if (img) encodeTrueColor(img, ximage); delete [] img; } // Commands void FrameRGBTrueColor::colormapCmd(float rb, float gb, float bb, float rc, float gc, float bc, int i, unsigned char* cells, int cnt) { bias[0] = rb; bias[1] = gb; bias[2] = bb; contrast[0] = rc; contrast[1] = gc; contrast[2] = bc; invert = i; updateColorCells(cells, cnt); updateColorScale(); update(BASE); } void FrameRGBTrueColor::colormapBeginCmd() { // we need a colorScale before we can render if (!validColorScale()) return; // we need some fits data // we assume the colorScale length will not change during motion calls if (!context[0].fits && !context[1].fits && !context[2].fits) return; int width = options->width; int height = options->height; // Create XImage if (!(colormapXM = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap))) { internalError("Unable to Create Colormap XImage"); return; } // Create Pixmap colormapPM = Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth); if (!colormapPM) { internalError("Unable to Create Colormap Pixmap"); return; } // colormapGCXOR colormapGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); // Create table index array for (int kk=0; kk<3; kk++) { if (colormapData[kk]) delete [] colormapData[kk]; colormapData[kk] = new long[width*height]; if (!colormapData[kk]) { internalError("Unable to alloc tmp data array"); return; } } SETSIGBUS // fill data array for (int kk=0; kk<3; kk++) { if (!view[kk] || !context[kk].fits) continue; // basics int length = colorScale[kk]->size() - 1; FitsImage* sptr = context[kk].cfits; int mosaic = context[kk].isMosaic(); // variable double* mm = sptr->matrixToData(Coord::WIDGET).mm(); FitsBound* params = sptr->getDataParams(context[kk].frScale.scanMode()); int srcw = sptr->width(); double ll = sptr->getLowDouble(); double hh = sptr->getHighDouble(); double diff = hh - ll; // main loop long* dest = colormapData[kk]; for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest++) { *dest = -2; // bg if (mosaic) { sptr = context[kk].cfits; mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(context[kk].frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); if (isfinite(value)) { if (value <= ll) *dest = 0; else if (value >= hh) *dest = length; else *dest = (int)(((value - ll)/diff * length) + .5); } else *dest = -1; // nan break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(context[kk].frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } } } } while (mosaic && sptr); } } } CLEARSIGBUS } void FrameRGBTrueColor::colormapEndCmd() { if (colormapXM) { XDestroyImage(colormapXM); colormapXM = NULL; } if (colormapPM) { Tk_FreePixmap(display, colormapPM); colormapPM = 0; } if (colormapGCXOR) { XFreeGC(display, colormapGCXOR); colormapGCXOR = 0; } for (int kk=0; kk<3; kk++) if (colormapData[kk]) { delete [] colormapData[kk]; colormapData[kk] = NULL; } update(BASE); // always update } void FrameRGBTrueColor::colormapMotionCmd(float rb, float gb, float bb, float rc, float gc, float bc, int i, unsigned char* cells, int cnt) { // we need a colorScale before we can render if (!validColorScale()) return; // first check for change if (bias[0] == rb && bias[1] == gb && bias[2] == bb && contrast[0] == rc && contrast[1] == gc && contrast[2] == bc && invert == i && colorCells) return; // we got a change bias[0] = rb; bias[1] = gb; bias[2] = bb; contrast[0] = rc; contrast[1] = gc; contrast[2] = bc; invert = i; updateColorCells(cells, cnt); updateColorScale(); // special case if ((!view[0] || !context[0].fits) && (!view[1] || !context[1].fits) && (!view[2] || !context[2].fits)) return; int& width = colormapXM->width; int& height = colormapXM->height; // create img unsigned char* img = new unsigned char[width*height*3]; memset(img, 0, width*height*3); char* mk = new char[width*height]; memset(mk, 0, width*height); for (int kk=0; kk<3; kk++) { if (!view[kk] || !context[kk].fits) continue; const unsigned char* table = colorScale[kk]->psColors(); long* src = colormapData[kk]; unsigned char* dest = img; char* mptr = mk; for (long jj=0; jj<height; jj++) for (long ii=0; ii<width; ii++, src++, dest+=3, mptr++) if (*src >= 0) { memcpy(dest+kk, table+(*src), 1); *mptr = 2; } else if (*src == -1 && *mptr < 2) *mptr = 1; } // set remainder to bg { unsigned char* dest = img; char* mptr = mk; for (long jj=0; jj<height; jj++) for (long ii=0; ii<width; ii++, dest+=3, mptr++) if (*mptr == 2) // good value ; else if (*mptr == 1) { // nan *(dest ) = (unsigned char)nanColor->red; *(dest+1) = (unsigned char)nanColor->green; *(dest+2) = (unsigned char)nanColor->blue; } else { // bg *(dest ) = (unsigned char)bgColor->red; *(dest+1) = (unsigned char)bgColor->green; *(dest+2) = (unsigned char)bgColor->blue; } } // build colormapXM encodeTrueColor((unsigned char*)img, colormapXM); // clean up if (img) delete [] img; if (mk) delete [] mk; // XImage to Pixmap XPutImage(display, colormapPM, Widget::gc, colormapXM, 0, 0, 0, 0, width, height); // Display Pixmap Vector dd = Vector() * widgetToWindow; XCopyArea(display, colormapPM, Tk_WindowId(tkwin), colormapGCXOR, 0, 0, width, height, dd[0], dd[1]); // update panner updatePanner(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame.h������������������������������������������������������������������������0000644�0001750�0001750�00000002711�11761470011�014560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame_h__ #define __frame_h__ #include "context.h" #include "framebase.h" #include "colorscale.h" // Frame class Frame : public virtual FrameBase { protected: int cmapID; // current colormap id float bias; // current colormap bias float contrast; // current colormap contrast int colorCount; // number of dynamic colors ColorScale* colorScale; // current color scale unsigned char* colorCells; // current color values unsigned short* indexCells; // current color indices private: int isIIS(); void reset(); void setKeyFits() {} void unloadFits(); protected: int isFrame() {return 1;} unsigned char* fillImage(int width, int height, Coord::InternalSystem); int validColorScale() {return colorScale ? 1 : 0;} void updateColorCells(unsigned short*, unsigned char*, int); public: Frame(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Frame(); void getColorbarCmd(); void getRGBChannelCmd(); void getRGBViewCmd(); void getRGBSystemCmd(); void getTypeCmd(); void iisCmd(int, int); void iisEraseCmd(); void iisGetCmd(char*, int, int, int, int); void iisSetCmd(const char*, int, int, int, int); void iisWCSCmd(const Matrix&, const Vector&, int); void savePhotoCmd(const char*); }; #endif �������������������������������������������������������./saods9/saotk/frame/colorscaletrue24.h�������������������������������������������������������������0000644�0001750�0001750�00000004610�11700666266�016676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscaletrue24_h__ #define __colorscaletrue24_h__ #include "colorscale.h" #include "truecolor24.h" class ColorScaleTrueColor24 : public virtual ColorScale, public TrueColor24 { public: ColorScaleTrueColor24(int, Visual*, int); virtual ~ColorScaleTrueColor24(); }; class LinearScaleTrueColor24 : public virtual ColorScale, public LinearScale, public ColorScaleTrueColor24 { public: LinearScaleTrueColor24(int, unsigned short*, unsigned char*, int, Visual*, int); }; class LogScaleTrueColor24 : public virtual ColorScale, public LogScale, public ColorScaleTrueColor24 { public: LogScaleTrueColor24(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class PowScaleTrueColor24 : public virtual ColorScale, public PowScale, public ColorScaleTrueColor24 { public: PowScaleTrueColor24(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class SqrtScaleTrueColor24 : public virtual ColorScale, public SqrtScale, public ColorScaleTrueColor24 { public: SqrtScaleTrueColor24(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SquaredScaleTrueColor24 : public virtual ColorScale, public SquaredScale, public ColorScaleTrueColor24 { public: SquaredScaleTrueColor24(int, unsigned short*, unsigned char*, int, Visual*, int); }; class AsinhScaleTrueColor24 : public virtual ColorScale, public AsinhScale, public ColorScaleTrueColor24 { public: AsinhScaleTrueColor24(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SinhScaleTrueColor24 : public virtual ColorScale, public SinhScale, public ColorScaleTrueColor24 { public: SinhScaleTrueColor24(int, unsigned short*, unsigned char*, int, Visual*, int); }; class IISScaleTrueColor24 : public virtual ColorScale, public IISScale, public ColorScaleTrueColor24 { public: IISScaleTrueColor24(unsigned short*, unsigned char*, int, Visual*, int); }; class HistEquScaleTrueColor24 : public virtual ColorScale, public HistEquScale, public ColorScaleTrueColor24 { public: HistEquScaleTrueColor24(int, unsigned short*, unsigned char*, int, double*, int, Visual*, int); }; #endif ������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsmask.C���������������������������������������������������������������������0000644�0001750�0001750�00000001751�11723000130�015232� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsmask.h" #include "base.h" #include "fitsimage.h" FitsMask::FitsMask(Base* p, FitsImage* fits, char* clr, int mrk) : parent_(p), mask_(fits) { current_ = mask_; mptr_ = current_; colorName_ = dupstr(clr); color_ = parent_->getXColor(colorName_); parent_->encodeTrueColor(color_, trueColor_); mark_ = mrk; next_ = NULL; previous_ = NULL; } FitsMask::~FitsMask() { if (colorName_) delete [] colorName_; FitsImage* ptr = mask_; while (ptr) { // better not have more that one slice FitsImage* sptr = ptr->nextSlice(); while (sptr) { FitsImage* stmp = sptr->nextSlice(); delete sptr; sptr = stmp; } FitsImage* tmp = ptr->nextMosaic(); delete ptr; ptr = tmp; } } void FitsMask::nextMosaic() { if (mptr_) mptr_ = mptr_->nextMosaic(); } �����������������������./saods9/saotk/frame/frametruecolor8.h��������������������������������������������������������������0000644�0001750�0001750�00000001315�11700666270�016615� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametruecolor8_h__ #define __frametruecolor8_h__ #include "frametruecolor.h" #include "truecolor8.h" class FrameTrueColor8 : public virtual FrameBase, public FrameTrueColor, public TrueColor8 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor8::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor8::encodeTrueColor(src, ximage);} void updateColorScale(); public: FrameTrueColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameTrueColor8(); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/saolex.L�����������������������������������������������������������������������0000644�0001750�0001750�00000004707�11700666271�014744� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "saoparser.H" extern YYSTYPE* saolval; extern saoFlexLexer* saolexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(saolval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(saolval->str,yytext,ll); saolval->str[ll] = '\0'; return STRING; } annulus {return ANNULUS_;} box {return BOX_;} circle {return CIRCLE_;} debug {return DEBUG_;} ellipse {return ELLIPSE_;} n {return N_;} off {return OFF_;} on {return ON_;} point {return POINT_;} polygon {return POLYGON_;} rotbox {return ROTBOX_;} version {return VERSION_;} [+-]?{D}+ { // Integer saolval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number saolval->real = atof(yytext); return REAL; } \"[^\"\n]*\" | \'[^\'\n]*\' { // Quoted String int ll = (yyleng-2)<(SAOBUFSIZE-1)?(yyleng-2):(SAOBUFSIZE-1); strncpy(saolval->str,yytext+1,ll); // skip the " " saolval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}\n]*\} { // Quoted String int ll = (yyleng-2)<(SAOBUFSIZE-1)?(yyleng-2):(SAOBUFSIZE-1); strncpy(saolval->str,yytext+1,ll); // skip the '{' saolval->str[ll] = '\0'; // Remove the '}' return STRING; } [0-9A-Za-z]+ { // General String int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(saolval->str,yytext,ll); saolval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \\n { // fake line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% void saoDiscard(int doit) { if (saolexx) saolexx->begin(DISCARD, doit); } void saoFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ���������������������������������������������������������./saods9/saotk/frame/saolex.C�����������������������������������������������������������������������0000644�0001750�0001750�00000136352�12032640000�014712� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "saolex.C" #line 4 "saolex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer saoFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *saoalloc (yy_size_t ); void *saorealloc (void *,yy_size_t ); void saofree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 27 #define YY_END_OF_BUFFER 28 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[101] = { 0, 0, 0, 2, 2, 28, 26, 22, 25, 26, 26, 26, 26, 26, 15, 21, 21, 21, 21, 21, 21, 8, 21, 21, 21, 21, 26, 26, 2, 1, 22, 23, 0, 18, 0, 19, 0, 15, 17, 16, 15, 21, 21, 21, 21, 21, 21, 21, 21, 10, 21, 21, 21, 24, 0, 20, 2, 0, 0, 0, 16, 21, 4, 21, 21, 21, 9, 21, 21, 21, 21, 16, 0, 17, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 6, 21, 11, 21, 21, 21, 21, 5, 21, 21, 13, 21, 3, 7, 12, 14, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 1, 1, 6, 1, 1, 1, 7, 1, 7, 8, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 17, 19, 17, 20, 21, 22, 17, 23, 24, 25, 26, 27, 17, 28, 29, 17, 1, 30, 1, 1, 1, 1, 31, 32, 33, 34, 35, 36, 37, 17, 38, 17, 17, 39, 17, 40, 41, 42, 17, 43, 44, 45, 46, 47, 17, 48, 49, 17, 50, 1, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[52] = { 0, 1, 1, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1 } ; static yyconst flex_int16_t yy_base[107] = { 0, 0, 0, 252, 246, 248, 266, 245, 266, 243, 240, 236, 44, 232, 46, 48, 49, 51, 50, 53, 232, 230, 58, 54, 55, 66, 47, 186, 0, 266, 233, 266, 229, 266, 226, 266, 222, 91, 68, 77, 99, 221, 102, 96, 89, 98, 107, 106, 112, 220, 111, 115, 120, 266, 176, 266, 0, 115, 124, 217, 75, 127, 213, 134, 130, 136, 203, 139, 143, 150, 144, 199, 195, 192, 147, 156, 154, 161, 169, 173, 157, 179, 176, 185, 182, 172, 163, 192, 177, 198, 199, 149, 201, 204, 124, 210, 94, 85, 71, 63, 266, 250, 253, 256, 62, 259, 262 } ; static yyconst flex_int16_t yy_def[107] = { 0, 100, 1, 101, 101, 100, 100, 100, 100, 100, 102, 103, 100, 100, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 100, 105, 106, 100, 100, 100, 102, 100, 103, 100, 100, 100, 100, 100, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 100, 105, 100, 106, 100, 100, 100, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 100, 100, 100, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 0, 100, 100, 100, 100, 100, 100 } ; static yyconst flex_int16_t yy_nxt[318] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, 20, 21, 22, 23, 24, 20, 20, 20, 25, 20, 20, 26, 15, 16, 17, 18, 19, 20, 20, 20, 20, 21, 22, 23, 24, 20, 20, 20, 25, 20, 20, 27, 6, 36, 37, 39, 40, 100, 100, 100, 100, 42, 100, 100, 100, 46, 41, 100, 53, 43, 45, 44, 100, 47, 48, 100, 50, 51, 38, 49, 100, 52, 42, 58, 100, 60, 46, 38, 53, 43, 45, 44, 57, 47, 100, 48, 50, 51, 100, 49, 39, 37, 52, 100, 58, 100, 57, 100, 39, 40, 59, 100, 60, 57, 42, 100, 100, 61, 62, 64, 100, 100, 63, 59, 100, 71, 65, 57, 66, 100, 67, 68, 72, 100, 73, 42, 100, 61, 62, 100, 64, 69, 63, 100, 70, 100, 65, 75, 100, 66, 67, 68, 100, 100, 74, 77, 100, 76, 100, 100, 78, 69, 80, 100, 70, 100, 100, 82, 75, 81, 100, 84, 100, 79, 74, 77, 83, 76, 100, 88, 78, 100, 100, 80, 85, 100, 100, 82, 100, 81, 87, 100, 84, 79, 100, 86, 83, 92, 89, 88, 91, 100, 73, 90, 85, 73, 94, 100, 100, 71, 100, 87, 100, 100, 93, 86, 97, 92, 89, 100, 95, 91, 100, 90, 96, 98, 94, 71, 55, 100, 100, 99, 38, 35, 93, 33, 30, 97, 55, 100, 95, 100, 38, 35, 96, 98, 33, 31, 30, 100, 29, 99, 28, 28, 28, 32, 29, 32, 34, 100, 34, 54, 100, 54, 56, 100, 56, 5, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 } ; static yyconst flex_int16_t yy_chk[318] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 14, 14, 15, 16, 18, 17, 14, 19, 23, 24, 18, 104, 22, 26, 15, 17, 16, 99, 19, 22, 25, 23, 24, 38, 22, 98, 25, 14, 38, 60, 60, 18, 39, 26, 15, 17, 16, 39, 19, 97, 22, 23, 24, 44, 22, 37, 37, 25, 96, 38, 43, 37, 45, 40, 40, 42, 42, 42, 39, 40, 47, 46, 43, 44, 46, 50, 48, 45, 57, 51, 57, 47, 37, 48, 52, 50, 50, 58, 94, 58, 40, 61, 43, 44, 64, 46, 51, 45, 63, 52, 65, 47, 63, 67, 48, 50, 50, 68, 70, 61, 65, 74, 64, 91, 69, 67, 51, 69, 76, 52, 75, 80, 74, 63, 70, 77, 76, 86, 68, 61, 65, 75, 64, 78, 80, 67, 85, 79, 69, 77, 82, 88, 74, 81, 70, 79, 84, 76, 68, 83, 78, 75, 85, 81, 80, 83, 87, 73, 82, 77, 72, 88, 89, 90, 71, 92, 79, 66, 93, 87, 78, 92, 85, 81, 95, 89, 83, 62, 82, 90, 93, 88, 59, 54, 49, 41, 95, 36, 34, 87, 32, 30, 92, 27, 21, 89, 20, 13, 11, 90, 93, 10, 9, 7, 5, 4, 95, 101, 101, 101, 102, 3, 102, 103, 0, 103, 105, 0, 105, 106, 0, 106, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "saolex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "saolex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "saoparser.H" extern YYSTYPE* saolval; extern saoFlexLexer* saolexx; /* rules */ #line 528 "saolex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 30 "saolex.L" #line 632 "saolex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 101 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 100 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 32 "saolex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(saolval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 39 "saolex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(saolval->str,yytext,ll); saolval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 47 "saolex.L" {return ANNULUS_;} YY_BREAK case 4: YY_RULE_SETUP #line 48 "saolex.L" {return BOX_;} YY_BREAK case 5: YY_RULE_SETUP #line 49 "saolex.L" {return CIRCLE_;} YY_BREAK case 6: YY_RULE_SETUP #line 50 "saolex.L" {return DEBUG_;} YY_BREAK case 7: YY_RULE_SETUP #line 51 "saolex.L" {return ELLIPSE_;} YY_BREAK case 8: YY_RULE_SETUP #line 52 "saolex.L" {return N_;} YY_BREAK case 9: YY_RULE_SETUP #line 53 "saolex.L" {return OFF_;} YY_BREAK case 10: YY_RULE_SETUP #line 54 "saolex.L" {return ON_;} YY_BREAK case 11: YY_RULE_SETUP #line 55 "saolex.L" {return POINT_;} YY_BREAK case 12: YY_RULE_SETUP #line 56 "saolex.L" {return POLYGON_;} YY_BREAK case 13: YY_RULE_SETUP #line 57 "saolex.L" {return ROTBOX_;} YY_BREAK case 14: YY_RULE_SETUP #line 58 "saolex.L" {return VERSION_;} YY_BREAK case 15: YY_RULE_SETUP #line 60 "saolex.L" { // Integer saolval->integer = atoi(yytext); return INT; } YY_BREAK case 16: #line 66 "saolex.L" case 17: YY_RULE_SETUP #line 66 "saolex.L" { // Real Number saolval->real = atof(yytext); return REAL; } YY_BREAK case 18: #line 72 "saolex.L" case 19: YY_RULE_SETUP #line 72 "saolex.L" { // Quoted String int ll = (yyleng-2)<(SAOBUFSIZE-1)?(yyleng-2):(SAOBUFSIZE-1); strncpy(saolval->str,yytext+1,ll); // skip the " " saolval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 20: YY_RULE_SETUP #line 79 "saolex.L" { // Quoted String int ll = (yyleng-2)<(SAOBUFSIZE-1)?(yyleng-2):(SAOBUFSIZE-1); strncpy(saolval->str,yytext+1,ll); // skip the '{' saolval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 21: YY_RULE_SETUP #line 86 "saolex.L" { // General String int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(saolval->str,yytext,ll); saolval->str[ll] = '\0'; return STRING; } YY_BREAK case 22: YY_RULE_SETUP #line 93 "saolex.L" { // White Spaces } YY_BREAK case 23: /* rule 23 can match eol */ YY_RULE_SETUP #line 96 "saolex.L" { // windows line feed return '\n'; } YY_BREAK case 24: YY_RULE_SETUP #line 100 "saolex.L" { // fake line feed return '\n'; } YY_BREAK case 25: /* rule 25 can match eol */ YY_RULE_SETUP #line 104 "saolex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 108 "saolex.L" { // eof return EOF_; } YY_BREAK case 26: YY_RULE_SETUP #line 112 "saolex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 27: YY_RULE_SETUP #line 116 "saolex.L" ECHO; YY_BREAK #line 891 "saolex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; saofree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); saofree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ saorealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) saorealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 101 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 101 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 100); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) saoalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) saoalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) saofree((void *) b->yy_ch_buf ); saofree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)saoalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)saorealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) saoalloc(new_size ); else (yy_start_stack) = (int *) saorealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *saoalloc (yy_size_t size ) { return (void *) malloc( size ); } void *saorealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void saofree (void * ptr ) { free( (char *) ptr ); /* see saorealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 116 "saolex.L" void saoDiscard(int doit) { if (saolexx) saolexx->begin(DISCARD, doit); } void saoFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsmask.h���������������������������������������������������������������������0000644�0001750�0001750�00000002072�11723000130�015274� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsmask_h__ #define __fitsmask_h__ #include "tcl.h" #include <X11/Xlib.h> class Base; class FitsImage; class FitsMask { private: Base* parent_; FitsImage* mask_; FitsImage* current_; FitsImage* mptr_; char* colorName_; XColor* color_; char trueColor_[4]; int mark_; protected: FitsMask* previous_; FitsMask* next_; public: FitsMask(Base*, FitsImage*, char*, int); virtual ~FitsMask(); FitsImage* mask() {return mask_;} FitsImage* current() {return current_;} FitsImage* mptr() {return mptr_;} XColor* color() {return color_;} char* trueColor() {return trueColor_;} int mark() {return mark_;} void initMosaic() {mptr_ = current_;} void nextMosaic(); void nextSlice(); FitsMask* previous() {return previous_;} void setPrevious(FitsMask* m) {previous_ = m;} FitsMask* next() {return next_;} void setNext(FitsMask* m) {next_ = m;} }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/bpanda.C�����������������������������������������������������������������������0000644�0001750�0001750�00000055343�12030663652�014664� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "bpanda.h" #include "fitsimage.h" Bpanda::Bpanda(const Bpanda& a) : BasePanda(a), BaseBox(a) {} Bpanda::Bpanda(Base* p, const Vector& ctr, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(a1, a2, an), BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn+1; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((r2-r1)/rn)*i+r1; strcpy(type_, "bpanda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } Bpanda::Bpanda(Base* p, const Vector& ctr, int an, double* a, int rn, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BasePanda(an, a), BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = rn; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = r[i]; sortAnnuli(); strcpy(type_, "bpanda"); numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); } void Bpanda::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { BaseBox::renderX(drawable, sys, mode); GC lgc = renderXGC(mode); Vector r0 = (annuli_[0]/2).abs(); Vector r1 = (annuli_[numAnnuli_-1]/2).abs(); for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,angles_[ii]),sys); Vector rr1 = fwdMap(intersect(r1,angles_[ii]),sys); if (mode == SRC) { if (selected) { if (ii == 0) XSetForeground(display, gc, parent->getColor("red")); else if (ii == numAngles_-1) XSetForeground(display, gc, parent->getColor("blue")); else XSetForeground(display, gc, color); } else XSetForeground(display, gc, color); } XDrawLine(display, drawable, lgc, rr0[0], rr0[1], rr1[0], rr1[1]); } } void Bpanda::renderPS(int mode) { BaseBox::renderPS(mode); renderPSGC(mode); Vector r0 = annuli_[0]/2; Vector r1 = annuli_[numAnnuli_-1]/2; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,angles_[ii]),Coord::CANVAS); Vector rr1 = fwdMap(intersect(r1,angles_[ii]),Coord::CANVAS); ostringstream str; str << "newpath " << rr0.TkCanvasPs(parent->canvas) << "moveto" << rr1.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void Bpanda::renderMACOSX() { BaseBox::renderMACOSX(); renderMACOSXGC(); Vector r0 = annuli_[0]/2; Vector r1 = annuli_[numAnnuli_-1]/2; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,angles_[ii]),CANVAS); Vector rr1 = fwdMap(intersect(r1,angles_[ii]),CANVAS); macosxDrawLine(rr0,rr1); } } #endif #ifdef _WIN32 void Bpanda::renderWIN32() { BaseBox::renderWIN32(); renderWIN32GC(); Vector r0 = annuli_[0]/2; Vector r1 = annuli_[numAnnuli_-1]/2; for (int ii=0; ii<numAngles_; ii++) { Vector rr0 = fwdMap(intersect(r0,angles_[ii]),Coord::CANVAS); Vector rr1 = fwdMap(intersect(r1,angles_[ii]),Coord::CANVAS); win32DrawLine(rr0,rr1); } } #endif // Support void Bpanda::updateHandles() { BaseBox::updateHandles(); // at this point, annuli_[] can be neg // which will cause problems with intersect() Vector rr = (annuli_[numAnnuli_-1]/2).abs(); for (int ii=0; ii<numAngles_; ii++) handle[ii+4+numAnnuli_] = fwdMap(intersect(rr,angles_[ii]),Coord::CANVAS); } void Bpanda::editBegin(int h) { if (h<5) { switch (h) { case 1: return; case 2: annuli_[numAnnuli_-1] = Vector(-annuli_[numAnnuli_-1][0],annuli_[numAnnuli_-1][1]); return; case 3: annuli_[numAnnuli_-1] = -annuli_[numAnnuli_-1]; return; case 4: annuli_[numAnnuli_-1] = Vector(annuli_[numAnnuli_-1][0],-annuli_[numAnnuli_-1][1]); return; } } doCallBack(CallBack::EDITBEGINCB); } void Bpanda::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); Matrix nn = mm.invert(); // This sizes about the opposite node if (h<5) { Vector o = annuli_[numAnnuli_-1]; Vector n = (annuli_[numAnnuli_-1]/2) - (v*mm); // don't go thru opposite node if (n[0]!=0 && n[1]!=0) { Vector ov = annuli_[numAnnuli_-1]/2 * nn; annuli_[numAnnuli_-1] = n; Vector nv = annuli_[numAnnuli_-1]/2 * nn; center -= nv-ov; for (int i=0; i<numAnnuli_-1; i++) { annuli_[i][0] *= fabs(n[0]/o[0]); annuli_[i][1] *= fabs(n[1]/o[1]); } } } else if (h<(5+numAnnuli_)) { // we must have some length double l = (v * mm * 2).length(); annuli_[h-5] = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; } else { angles_[h-5-numAnnuli_] = -((v * mm).angle()); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; } updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); } void Bpanda::editEnd() { for (int ii=1; ii<numAnnuli_; ii++) annuli_[ii] = annuli_[ii].abs(); sortAnnuli(); sortAngles(); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITENDCB); } int Bpanda::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm * 2).length(); Vector rr = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; // we need to insert into the next to the last location // new size array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_+1]; // copy old values for (int i=0; i<numAnnuli_; i++) annuli_[i] = old[i]; // save last annuli_[numAnnuli_] = old[numAnnuli_-1]; // delete old if (old) delete [] old; // new size on end annuli_[numAnnuli_-1] = rr; numAnnuli_++; numHandle++; return 4+numAnnuli_-1; } int Bpanda::addAngles(const Vector& v) { Matrix mm = bckMatrix(); addAngle(-((v * mm).angle())); numHandle++; return 4+numAnnuli_+numAngles_-1; } void Bpanda::setAnglesAnnuli(double a1, double a2, int an, Vector r1, Vector r2, int rn) { numAnnuli_ = rn+1; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) annuli_[ii] = ((r2-r1)/rn)*ii+r1; sortAnnuli(); setAngles(a1,a2,an); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Bpanda::setAnglesAnnuli(const double* a, int an, const Vector* r, int rn) { numAnnuli_ = rn; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int ii=0; ii<numAnnuli_; ii++) annuli_[ii] = r[ii]; sortAnnuli(); setAngles(an,a); startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; numHandle = 4 + numAnnuli_ + numAngles_; updateBBox(); doCallBack(CallBack::EDITCB); } void Bpanda::deleteAnglesAnnuli(int h) { if (h>4) { int hh = h-4-1; if (numAnnuli_>2 && hh<numAnnuli_) { // new annuli_ array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_-1]; // copy up to annuli_ in question for (int ii=0; ii<hh; ii++) annuli_[ii] = old[ii]; // copy remainder for (int ii=hh; ii<numAnnuli_-1; ii++) annuli_[ii] = old[ii+1]; if (old) delete [] old; numAnnuli_--; } else if (numAngles_>2 && hh<(numAnnuli_+numAngles_)) { hh -= numAnnuli_; deleteAngle(hh); } numHandle = 4 + numAnnuli_ + numAngles_; startAng_ = angles_[0]; stopAng_ = angles_[numAngles_-1]; updateBBox(); doCallBack(CallBack::EDITCB); } } int Bpanda::isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa) { Vector pp = bckMap(vv,sys); return BaseBox::isIn(vv,sys,nn) && BasePanda::isIn(pp,aa); } void Bpanda::analysis(AnalysisTask mm, int which) { switch (mm) { case PANDA: if (!analysisPanda_ && which) { addCallBack(CallBack::MOVECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisPandaCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPandaCB_[1], parent->options->cmdName); } if (analysisPanda_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPandaCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisPandaCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisPandaCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisPandaCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPandaCB_[1]); } analysisPanda_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Bpanda::analysisPanda(Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { // during resize, annuli_ can be negative Vector vv = annuli_[ii].abs(); bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } int num = parent->markerAnalysisPanda(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, numAngles_-1, angles_, bb, sys); analysisPandaResult(xx, yy, ee, num); } void Bpanda::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { Vector vv = annuli_[ii]; bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } parent->markerAnalysisStats(this, str, numAnnuli_-1, numAngles_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Bpanda::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { int regular = 1; if (numAngles_>2) { double delta; if (angles_[1] > angles_[0]) delta = angles_[1]-angles_[0]; else delta = angles_[1]+M_TWOPI-angles_[0]; for (int ii=2; ii<numAngles_; ii++) { double diff; if (angles_[ii] > angles_[ii-1]) diff = angles_[ii]-angles_[ii-1]; else diff = angles_[ii]+M_TWOPI-angles_[ii-1]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (numAnnuli_>2) { double delta = annuli_[1][0]-annuli_[0][0]; for (int i=2; i<numAnnuli_; i++) { double diff = annuli_[i][0]-annuli_[i-1][0]; if (!teq(diff,delta,FLT_EPSILON)) { regular = 0; break; } } } if (regular) listA(str, sys, sky, format, conj, strip); else listB(str, sys, sky, format, conj, strip); } void Bpanda::listA(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ',' << numAngles_-1 << ',' << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys,sky); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector r1 = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[0],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[numAngles_-1],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; Vector v = ptr->mapFromRef(center,sys); Vector r1 = ptr->mapLenFromRef(annuli_[0],sys); Vector r2 = ptr->mapLenFromRef(annuli_[numAnnuli_-1],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 <<',' << numAngles_-1 << ',' << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << numAnnuli_-1 << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void Bpanda::listB(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # bpanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys); str << r[0] << ' ' << r[1] << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << '"' << ',' << r1[1] << '"' <<',' << r2[0] << '"' << ',' << r2[1] << '"' <<',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # bpanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys,Coord::ARCSEC); str << r[0] << '"' << ' ' << r[1] << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys,sky)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys,sky)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << '"' << ',' << r1[1] << '"' << ',' << r2[0] << '"' << ',' << r2[1] << '"' << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # bpanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys,sky)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys,Coord::ARCSEC); str << r[0] << '"' << ' ' << r[1] << '"' << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } break; } break; } else { Vector v = ptr->mapFromRef(center,sys); for (int j=1; j<numAngles_; j++) { double ang1 = radToDeg(parent->mapAngleFromRef(angles_[j-1],sys)); double ang2 = radToDeg(parent->mapAngleFromRef(angles_[j],sys)); if (ang2<=ang1+FLT_EPSILON) ang2 += 360; for (int i=1; i<numAnnuli_; i++) { listPre(str, sys, sky, ptr, strip, 0); Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys); Vector r2 = ptr->mapLenFromRef(annuli_[i],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ang1 << ',' << ang2 << ",1," << r1[0] << ',' << r1[1] << ',' << r2[0] << ',' << r2[1] << ',' << "1," << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; if (!strip) { if (conj) str << " ||"; str << " # bpanda="; if (i==1 && j==1 && !strip) { str << '('; for (int k=0; k<numAngles_; k++) str << radToDeg(parent->mapAngleFromRef(angles_[k],sys)) << ((k<numAngles_-1) ? ' ' : ')'); str << '('; for (int k=0; k<numAnnuli_; k++) { Vector r = ptr->mapLenFromRef(annuli_[k],sys); str << r[0] << ' ' << r[1] << ((k<numAnnuli_-1) ? ' ' : ')'); } str << '(' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; listProps(str); } else str << "ignore"; str << (strip ? ';' : '\n'); } else { if (conj) str << "||"; else str << ";"; } } } } } } } void Bpanda::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_,numAnnuli_); XMLRowAng(sys,sky); XMLRowAng(sys,sky,angles_,numAngles_); XMLRowProps(ptr,sys); XMLRowEnd(str); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basebox.h����������������������������������������������������������������������0000644�0001750�0001750�00000002660�12004032774�015115� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __basebox_h__ #define __basebox_h__ #include "basemarker.h" class BaseBox : public BaseMarker { protected: int numPoints_; Vector** vertices_; private: void newVertices(); void newVerticesA(); void newVerticesB(); void deleteVertices(); void vertBTest(int* s1, int* s2, double a1, double a2, double b1, double b2, int ii, int* cnt); void vertBPrep(double a1, double a2, double ll, double ul, int ii, int* cnt); void vertBSeg(double ang1, double ang2, int ii, int* cnt); protected: virtual void updateHandles(); Vector intersect(Vector, double); void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif public: BaseBox(const BaseBox&); BaseBox(Base* p, const Vector& ctr, double a, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb); virtual ~BaseBox(); virtual Marker* dup() =0; int isIn(const Vector& vv) {return isIn(vv, Coord::CANVAS);} int isIn(const Vector& vv, Coord::InternalSystem sys) {return isIn(vv,sys,numAnnuli_-1);} int isIn(const Vector&, Coord::InternalSystem, int); }; #endif ��������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor24.C�����������������������������������������������������������0000644�0001750�0001750�00000016622�11700666267�017072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame3dtruecolor24.h" #include "colorscaletrue24.h" #include "colorscaletrue32.h" // Tk Canvas Widget Function Declarations int Frame3dTrueColor24CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Frame3dTrueColor24 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frame3dTrueColor24Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame3d", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frame3dTrueColor24Type = { (char*)"frame3dtruecolor24", // name sizeof(WidgetOptions), // item size Frame3dTrueColor24CreateProc, // configProc frame3dTrueColor24Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int Frame3dTrueColor24_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frame3dTrueColor24Type); return TCL_OK; } int Frame3dTrueColor24CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { Frame3dTrueColor24* frame = new Frame3dTrueColor24(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // Frame3dTrueColor24 Member Functions Frame3dTrueColor24::Frame3dTrueColor24(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i,c,item), Frame3dTrueColor(i,c,item), TrueColor24(visual) { configSpecs = frame3dTrueColor24Specs; // frame configure options } Frame3dTrueColor24::~Frame3dTrueColor24() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void Frame3dTrueColor24::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells || !bitsperpixel_) return; if (colorScale) delete colorScale; // determine if we have 3 bytes or 4 bytes per pixel switch (bitsperpixel_) { case 24: updateColorScale24(); break; case 32: updateColorScale32(); break; } } void Frame3dTrueColor24::updateColorScale24() { switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor24(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor24(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } void Frame3dTrueColor24::updateColorScale32() { switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor32(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor32(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } ��������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framebase.h��������������������������������������������������������������������0000644�0001750�0001750�00000006334�12102520405�015411� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framebase_h__ #define __framebase_h__ #include "base.h" class FrameBase : public Base { protected: XImage* rotateSrcXM; // rotate src ximage XImage* rotateDestXM; // rotate dest ximage Pixmap rotatePM; // rotate pixmap Vector iisLastCursor; // iis cursor state info Vector iisSaveCursor; Window iisSaveRoot; int iisInteractive; protected: double calcZoomPanner(); virtual void rotateMotion() =0; void saveFitsResampleFits(OutFitsStream&); void saveFitsResampleKeyword(OutFitsStream&, FitsHead&); void setBinCursor(); virtual void updateBin(const Matrix&); void updatePanner(); void x11MagnifierCursor(const Vector&); public: FrameBase(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FrameBase(); Vector mapFromRef(const Vector&, Coord::InternalSystem); Vector3d mapFromRef3d(const Vector& vv, Coord::InternalSystem sys) {return mapFromRef(vv,sys);} Vector mapToRef(const Vector&, Coord::InternalSystem); Vector3d mapToRef3d(const Vector& vv, Coord::InternalSystem sys) {return mapToRef(vv,sys);} // Bin Commands void binToFitCmd(); // Coordinate Commands void getCursorCmd(Coord::InternalSystem); void getCursorCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision); // Grid Commands void gridCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Grid::GridType, const char*, const char*); // Fits Commands void saveFitsResample(OutFitsStream&); void saveFitsResampleFileCmd(const char*); void saveFitsResampleChannelCmd(const char*); void saveFitsResampleSocketCmd(int); // IIS Commands void iisCursorModeCmd(int); void iisGetCursorCmd(); void iisGetFileNameCmd(); void iisGetFileNameCmd(int); void iisGetFileNameCmd(const Vector&); void iisMessageCmd(const char*); void iisSetCursorCmd(const Vector&, Coord::InternalSystem); void iisSetCursorCmd(const Vector&, Coord::CoordSystem); void iisSetFileNameCmd(const char*); void iisSetFileNameCmd(const char*,int); void iisUpdateCmd() {updateNow(MATRIX);} // Pan Zoom Rotate Orient Commands void panCmd(const Vector&); void panCmd(const Vector&, const Vector&); void panCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame); void panToCmd(const Vector&); void panToCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame); void panBBoxCmd(const Vector&); void panEndCmd(const Vector&); void rotateBeginCmd(); void rotateMotionCmd(double); void rotateEndCmd(); void zoomAboutCmd(const Vector&, const Vector&); void zoomAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void zoomToAboutCmd(const Vector&, const Vector&); void zoomToAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void zoomToFitCmd(double); // 3d void get3dBorderCmd(); void get3dBorderColorCmd(); void get3dCompassCmd(); void get3dCompassColorCmd(); void get3dHighliteCmd(); void get3dHighliteColorCmd(); void get3dScaleCmd(); void get3dViewCmd(); void get3dViewPointCmd(); void get3dRenderMethodCmd(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/boxannulus.C�������������������������������������������������������������������0000644�0001750�0001750�00000030165�12030663652�015630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "boxannulus.h" #include "fitsimage.h" BoxAnnulus::BoxAnnulus(const BoxAnnulus& a) : BaseBox(a) {} BoxAnnulus::BoxAnnulus(Base* p, const Vector& ctr, const Vector& s, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = 1; annuli_ = new Vector[1]; annuli_[0] = s; strcpy(type_,"boxannulus"); numHandle = 4; updateBBox(); } BoxAnnulus::BoxAnnulus(Base* p, const Vector& ctr, const Vector& inner, const Vector& outer, int num, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = num+1; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((outer-inner)/num)*i+inner; strcpy(type_,"boxannulus"); numHandle = 4 + numAnnuli_; updateBBox(); } BoxAnnulus::BoxAnnulus(Base* p, const Vector& ctr, int an, Vector* s, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = an; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = s[i]; sortAnnuli(); strcpy(type_, "boxannulus"); numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } void BoxAnnulus::editBegin(int h) { if (h<5) { switch (h) { case 1: return; case 2: annuli_[numAnnuli_-1] = Vector(-annuli_[numAnnuli_-1][0],annuli_[numAnnuli_-1][1]); return; case 3: annuli_[numAnnuli_-1] = -annuli_[numAnnuli_-1]; return; case 4: annuli_[numAnnuli_-1] = Vector(annuli_[numAnnuli_-1][0],-annuli_[numAnnuli_-1][1]); return; } } doCallBack(CallBack::EDITBEGINCB); } void BoxAnnulus::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); Matrix nn = mm.invert(); // This sizes about the opposite node if (h<5) { Vector o = annuli_[numAnnuli_-1]; Vector n = (annuli_[numAnnuli_-1]/2) - (v*mm); // don't go thru opposite node if (n[0]!=0 && n[1]!=0) { Vector ov = annuli_[numAnnuli_-1]/2 * nn; annuli_[numAnnuli_-1] = n; Vector nv = annuli_[numAnnuli_-1]/2 * nn; center -= nv-ov; for (int i=0; i<numAnnuli_-1; i++) { annuli_[i][0] *= fabs(n[0]/o[0]); annuli_[i][1] *= fabs(n[1]/o[1]); } } } else { // we must have some length double l = (v * mm * 2).length(); annuli_[h-5] = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; } updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); } void BoxAnnulus::editEnd() { for (int i=1; i<numAnnuli_; i++) annuli_[i] = annuli_[i].abs(); sortAnnuli(); updateBBox(); doCallBack(CallBack::EDITENDCB); } int BoxAnnulus::addAnnuli(const Vector& v) { Matrix mm = bckMatrix(); double l = (v * mm * 2).length(); Vector rr = annuli_[numAnnuli_-1] * l/annuli_[numAnnuli_-1][0]; return insertAnnuli(rr); } void BoxAnnulus::analysis(AnalysisTask mm, int which) { switch (mm) { case RADIAL: if (!analysisRadial_ && which) { addCallBack(CallBack::MOVECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisRadialCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisRadialCB_[1], parent->options->cmdName); } if (analysisRadial_ && !which) { deleteCallBack(CallBack::MOVECB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITCB, analysisRadialCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisRadialCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisRadialCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisRadialCB_[0]); deleteCallBack(CallBack::DELETECB, analysisRadialCB_[1]); } analysisRadial_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITENDCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITENDCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void BoxAnnulus::analysisRadial(char* xname, char* yname, char* ename, Coord::CoordSystem sys) { double* xx; double* yy; double* ee; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { // during resize, annuli_ can be negative Vector vv = annuli_[ii].abs(); bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } int num = parent->markerAnalysisRadial(this, &xx, &yy, &ee, numAnnuli_-1, annuli_, bb, sys); analysisRadialResult(xname, yname, ename, xx, yy, ee, num); } void BoxAnnulus::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox* bb = new BBox[numAnnuli_]; Matrix mm = Rotate(angle) * Translate(center); for (int ii=0; ii<numAnnuli_; ii++) { // during resize, annuli_ can be negative Vector vv = annuli_[ii].abs(); bb[ii] = BBox(-vv * mm); bb[ii].bound( vv * mm); bb[ii].bound(Vector( vv[0],-vv[1]) * mm); bb[ii].bound(Vector(-vv[0], vv[1]) * mm); } parent->markerAnalysisStats(this, str, numAnnuli_-1, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void BoxAnnulus::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << "box(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys); str << r[0] << ',' << r[1] << ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << "box(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << r[0] << "\"" << ',' << r[1] << "\"" << ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << "box(" << ra << ',' << dec << ',' ; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << r[0] << "\""<< ',' << r[1] << "\""<< ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << "box(" << setprecision(8) << v[0] << ',' << v[1] << ','; for (int i=0; i<numAnnuli_; i++) { Vector r = ptr->mapLenFromRef(annuli_[i],sys); str << r[0] << ',' << r[1] << ',' ; } str << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void BoxAnnulus::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_,numAnnuli_); XMLRowAng(sys,sky); XMLRowProps(ptr,sys); XMLRowEnd(str); } void BoxAnnulus::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],Coord::IMAGE); str << "box " << setprecision(8) << v << r << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],Coord::IMAGE); str << " & !box " << setprecision(8) << v << r1 << radToDeg(angle); } listProsPost(str, strip); } } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << "box " << setprecision(8) << v[0] << "d " << v[1] << "d " << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); str << " & !box " << setprecision(8) << v[0] << "d " << v[1] << "d " << r1[0] << "\" " << r1[1] << "\" " << radToDeg(angle); } listProsPost(str, strip); } } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; for (int i=0; i<numAnnuli_; i++) { coord.listProsCoordSystem(str,sys,sky); str << "; "; Vector r = ptr->mapLenFromRef(annuli_[i],sys,Coord::ARCSEC); str << "box " << ra << ' ' << dec << ' ' << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); if (i!=0) { Vector r1 = ptr->mapLenFromRef(annuli_[i-1],sys,Coord::ARCSEC); str << " & !box " << ra << ' ' << dec << ' ' << r1[0] << "\" " << r1[1] << "\" " << radToDeg(angle); } listProsPost(str, strip); } } break; } } } } void BoxAnnulus::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); for (int i=0; i<numAnnuli_; i++) { Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << "box(" << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[i][0] << ',' << annuli_[i][1] << ',' << radToDeg(angle) << ')'; if (i!=0) str << " & !box(" << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[i-1][0] << ',' << annuli_[i-1][1] << ',' << radToDeg(angle) << ')'; listSAOimagePost(str, strip); } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xyparser.C���������������������������������������������������������������������0000644�0001750�0001750�00000162632�11727715200�015313� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse xyparse #define yylex xylex #define yyerror xyerror #define yylval xylval #define yychar xychar #define yydebug xydebug #define yynerrs xynerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, ANGDEGREE = 260, SEXSTR = 261, HMSSTR = 262, DMSSTR = 263, EOF_ = 264, AMPLIFIER_ = 265, B1950_ = 266, CCD_ = 267, DEBUG_ = 268, DETECTOR_ = 269, ECLIPTIC_ = 270, FK4_ = 271, FK4_NO_E_ = 272, FK5_ = 273, GALACTIC_ = 274, HELIOECLIPTIC_ = 275, ICRS_ = 276, IMAGE_ = 277, J2000_ = 278, LOGICAL_ = 279, OFF_ = 280, ON_ = 281, PHYSICAL_ = 282, SUPERGALACTIC_ = 283, VERSION_ = 284, WCS_ = 285, WCSA_ = 286, WCSB_ = 287, WCSC_ = 288, WCSD_ = 289, WCSE_ = 290, WCSF_ = 291, WCSG_ = 292, WCSH_ = 293, WCSI_ = 294, WCSJ_ = 295, WCSK_ = 296, WCSL_ = 297, WCSM_ = 298, WCSN_ = 299, WCSO_ = 300, WCSP_ = 301, WCSQ_ = 302, WCSR_ = 303, WCSS_ = 304, WCST_ = 305, WCSU_ = 306, WCSV_ = 307, WCSW_ = 308, WCSX_ = 309, WCSY_ = 310, WCSZ_ = 311 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define ANGDEGREE 260 #define SEXSTR 261 #define HMSSTR 262 #define DMSSTR 263 #define EOF_ 264 #define AMPLIFIER_ 265 #define B1950_ 266 #define CCD_ 267 #define DEBUG_ 268 #define DETECTOR_ 269 #define ECLIPTIC_ 270 #define FK4_ 271 #define FK4_NO_E_ 272 #define FK5_ 273 #define GALACTIC_ 274 #define HELIOECLIPTIC_ 275 #define ICRS_ 276 #define IMAGE_ 277 #define J2000_ 278 #define LOGICAL_ 279 #define OFF_ 280 #define ON_ 281 #define PHYSICAL_ 282 #define SUPERGALACTIC_ 283 #define VERSION_ 284 #define WCS_ 285 #define WCSA_ 286 #define WCSB_ 287 #define WCSC_ 288 #define WCSD_ 289 #define WCSE_ 290 #define WCSF_ 291 #define WCSG_ 292 #define WCSH_ 293 #define WCSI_ 294 #define WCSJ_ 295 #define WCSK_ 296 #define WCSL_ 297 #define WCSM_ 298 #define WCSN_ 299 #define WCSO_ 300 #define WCSP_ 301 #define WCSQ_ 302 #define WCSR_ 303 #define WCSS_ 304 #define WCST_ 305 #define WCSU_ 306 #define WCSV_ 307 #define WCSW_ 308 #define WCSX_ 309 #define WCSY_ 310 #define WCSZ_ 311 /* Copy the first part of user declarations. */ #line 10 "xyparser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer xyFlexLexer #include <FlexLexer.h> extern int xylex(void*, xyFlexLexer*); extern void xyerror(Base*, xyFlexLexer*, const char*); static int dash[] = {8,3}; static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static List<Tag> taglist; static List<CallBack> cblist; /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 41 "xyparser.Y" { #define XYBUFSIZE 2048 double real; int integer; char str[XYBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 255 "xyparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 268 "xyparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 126 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 60 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 20 /* YYNRULES -- Number of rules. */ #define YYNRULES 78 /* YYNRULES -- Number of states. */ #define YYNSTATES 91 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 311 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 58, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 4, 7, 11, 14, 15, 18, 20, 22, 25, 26, 30, 31, 33, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 55, 57, 59, 61, 63, 67, 71, 75, 79, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 61, 0, -1, -1, 62, 63, -1, 63, 64, 69, -1, 64, 69, -1, -1, 13, 71, -1, 29, -1, 77, -1, 77, 78, -1, -1, 65, 79, 66, -1, -1, 67, -1, 67, 68, -1, 68, -1, 70, -1, 57, -1, 58, -1, 9, -1, 4, -1, 3, -1, 26, -1, 25, -1, -1, 59, -1, 6, -1, 7, -1, 8, -1, 73, 72, 73, -1, 74, 72, 75, -1, 75, 72, 75, -1, 70, 72, 70, -1, 5, 72, 5, -1, 22, -1, 24, -1, 27, -1, 12, -1, 10, -1, 14, -1, 30, -1, 31, -1, 32, -1, 33, -1, 34, -1, 35, -1, 36, -1, 37, -1, 38, -1, 39, -1, 40, -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, -1, 51, -1, 52, -1, 53, -1, 54, -1, 55, -1, 56, -1, 16, -1, 11, -1, 17, -1, 18, -1, 23, -1, 21, -1, 19, -1, 28, -1, 15, -1, 20, -1, 76, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 119, 119, 119, 125, 126, 129, 130, 131, 132, 133, 135, 135, 138, 139, 142, 143, 146, 149, 150, 151, 154, 155, 158, 159, 162, 163, 166, 169, 172, 175, 186, 193, 200, 207, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 263 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "ANGDEGREE", "SEXSTR", "HMSSTR", "DMSSTR", "EOF_", "AMPLIFIER_", "B1950_", "CCD_", "DEBUG_", "DETECTOR_", "ECLIPTIC_", "FK4_", "FK4_NO_E_", "FK5_", "GALACTIC_", "HELIOECLIPTIC_", "ICRS_", "IMAGE_", "J2000_", "LOGICAL_", "OFF_", "ON_", "PHYSICAL_", "SUPERGALACTIC_", "VERSION_", "WCS_", "WCSA_", "WCSB_", "WCSC_", "WCSD_", "WCSE_", "WCSF_", "WCSG_", "WCSH_", "WCSI_", "WCSJ_", "WCSK_", "WCSL_", "WCSM_", "WCSN_", "WCSO_", "WCSP_", "WCSQ_", "WCSR_", "WCSS_", "WCST_", "WCSU_", "WCSV_", "WCSW_", "WCSX_", "WCSY_", "WCSZ_", "'\\n'", "';'", "','", "$accept", "start", "@1", "commands", "command", "@2", "comment", "junks", "junk", "terminator", "numeric", "debug", "sp", "sexagesimal", "hms", "dms", "coord", "coordSystem", "skyFrame", "shape", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 10, 59, 44 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 60, 62, 61, 63, 63, 64, 64, 64, 64, 64, 65, 64, 66, 66, 67, 67, 68, 69, 69, 69, 70, 70, 71, 71, 72, 72, 73, 74, 75, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 3, 2, 0, 2, 1, 1, 2, 0, 3, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 2, 0, 11, 1, 39, 38, 0, 40, 35, 36, 37, 8, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 11, 0, 0, 9, 24, 23, 7, 0, 20, 18, 19, 5, 22, 21, 25, 27, 28, 29, 25, 25, 25, 25, 78, 13, 69, 76, 68, 70, 71, 74, 77, 73, 72, 75, 10, 4, 26, 0, 0, 0, 0, 0, 12, 14, 16, 17, 34, 33, 30, 31, 32, 15 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 1, 2, 39, 40, 41, 81, 82, 83, 50, 84, 45, 76, 58, 59, 60, 61, 42, 73, 62 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -40 static const yytype_int8 yypact[] = { -40, 11, 50, -40, -40, -40, -18, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, 0, 8, -2, 98, -40, -40, -40, 8, -40, -40, -40, -40, -40, -40, -36, -40, -40, -40, -36, -36, -36, -36, -40, 12, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, 21, 12, 22, 61, 61, -40, 12, -40, -40, -40, -40, -40, -40, -40, -40 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -40, -40, -40, -40, 31, -40, -40, -40, -11, 27, -16, -40, -39, -3, -40, -12, -40, -40, -40, -40 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -7 static const yytype_int8 yytable[] = { -3, 51, 52, 53, 54, 55, 56, 43, 44, -6, 4, 3, 5, 6, 7, 51, 52, 47, 77, 78, 79, 80, 8, 75, 9, 57, 85, 10, 54, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -6, -6, -6, 4, 86, 5, 6, 7, 48, 49, 88, 89, 56, 46, 90, 8, 74, 9, 87, 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -6, -6, 63, 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, 0, 71, 0, 0, 0, 0, 72 }; static const yytype_int8 yycheck[] = { 0, 3, 4, 5, 6, 7, 8, 25, 26, 9, 10, 0, 12, 13, 14, 3, 4, 9, 57, 58, 59, 60, 22, 59, 24, 41, 5, 27, 6, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 9, 10, 77, 12, 13, 14, 57, 58, 79, 80, 8, 39, 82, 22, 46, 24, 78, -1, 27, -1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 11, -1, -1, -1, 15, 16, 17, 18, 19, 20, 21, -1, 23, -1, -1, -1, -1, 28 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 61, 62, 0, 10, 12, 13, 14, 22, 24, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 63, 64, 65, 77, 25, 26, 71, 64, 9, 57, 58, 69, 3, 4, 5, 6, 7, 8, 70, 73, 74, 75, 76, 79, 11, 15, 16, 17, 18, 19, 20, 21, 23, 28, 78, 69, 59, 72, 72, 72, 72, 72, 66, 67, 68, 70, 5, 70, 73, 75, 75, 68 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, xyFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; xyFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, xyFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; xyFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, xyFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; xyFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, xyFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; xyFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, xyFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, xyFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; xyFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 119 "xyparser.Y" { globalSystem = fr->xySystem(); globalSky = fr->xySky(); ;} break; case 8: #line 131 "xyparser.Y" {cerr << "X Y Format 1.0" << endl;;} break; case 9: #line 132 "xyparser.Y" {globalSystem = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer);;} break; case 10: #line 134 "xyparser.Y" {globalSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); globalSky = (Coord::SkyFrame)(yyvsp[(2) - (2)].integer);;} break; case 11: #line 135 "xyparser.Y" {localSystem = globalSystem; localSky = globalSky; maperr = 0;;} break; case 17: #line 146 "xyparser.Y" {;} break; case 20: #line 151 "xyparser.Y" {YYACCEPT;;} break; case 21: #line 154 "xyparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 22: #line 155 "xyparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 23: #line 158 "xyparser.Y" {yydebug=1;;} break; case 24: #line 159 "xyparser.Y" {yydebug=0;;} break; case 27: #line 166 "xyparser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 28: #line 169 "xyparser.Y" {(yyval.real) = parseHMSStr((yyvsp[(1) - (1)].str));;} break; case 29: #line 172 "xyparser.Y" {(yyval.real) = parseDMSStr((yyvsp[(1) - (1)].str));;} break; case 30: #line 176 "xyparser.Y" { Vector r; if (localSky == Coord::GALACTIC || localSky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),localSystem,localSky); else r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real)*360./24.,(yyvsp[(3) - (3)].real)),localSystem,localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 31: #line 187 "xyparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),localSystem,localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 32: #line 194 "xyparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),localSystem,localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 33: #line 201 "xyparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),localSystem,localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 34: #line 208 "xyparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),localSystem,localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 35: #line 216 "xyparser.Y" {(yyval.integer) = Coord::IMAGE;;} break; case 36: #line 217 "xyparser.Y" {(yyval.integer) = Coord::IMAGE;;} break; case 37: #line 218 "xyparser.Y" {(yyval.integer) = Coord::PHYSICAL;;} break; case 38: #line 219 "xyparser.Y" {(yyval.integer) = Coord::PHYSICAL;;} break; case 39: #line 220 "xyparser.Y" {(yyval.integer) = Coord::AMPLIFIER;;} break; case 40: #line 221 "xyparser.Y" {(yyval.integer) = Coord::DETECTOR;;} break; case 41: #line 222 "xyparser.Y" {(yyval.integer) = Coord::WCS;;} break; case 42: #line 223 "xyparser.Y" {(yyval.integer) = Coord::WCSA;;} break; case 43: #line 224 "xyparser.Y" {(yyval.integer) = Coord::WCSB;;} break; case 44: #line 225 "xyparser.Y" {(yyval.integer) = Coord::WCSC;;} break; case 45: #line 226 "xyparser.Y" {(yyval.integer) = Coord::WCSD;;} break; case 46: #line 227 "xyparser.Y" {(yyval.integer) = Coord::WCSE;;} break; case 47: #line 228 "xyparser.Y" {(yyval.integer) = Coord::WCSF;;} break; case 48: #line 229 "xyparser.Y" {(yyval.integer) = Coord::WCSG;;} break; case 49: #line 230 "xyparser.Y" {(yyval.integer) = Coord::WCSH;;} break; case 50: #line 231 "xyparser.Y" {(yyval.integer) = Coord::WCSI;;} break; case 51: #line 232 "xyparser.Y" {(yyval.integer) = Coord::WCSJ;;} break; case 52: #line 233 "xyparser.Y" {(yyval.integer) = Coord::WCSK;;} break; case 53: #line 234 "xyparser.Y" {(yyval.integer) = Coord::WCSL;;} break; case 54: #line 235 "xyparser.Y" {(yyval.integer) = Coord::WCSM;;} break; case 55: #line 236 "xyparser.Y" {(yyval.integer) = Coord::WCSN;;} break; case 56: #line 237 "xyparser.Y" {(yyval.integer) = Coord::WCSO;;} break; case 57: #line 238 "xyparser.Y" {(yyval.integer) = Coord::WCSP;;} break; case 58: #line 239 "xyparser.Y" {(yyval.integer) = Coord::WCSQ;;} break; case 59: #line 240 "xyparser.Y" {(yyval.integer) = Coord::WCSR;;} break; case 60: #line 241 "xyparser.Y" {(yyval.integer) = Coord::WCSS;;} break; case 61: #line 242 "xyparser.Y" {(yyval.integer) = Coord::WCST;;} break; case 62: #line 243 "xyparser.Y" {(yyval.integer) = Coord::WCSU;;} break; case 63: #line 244 "xyparser.Y" {(yyval.integer) = Coord::WCSV;;} break; case 64: #line 245 "xyparser.Y" {(yyval.integer) = Coord::WCSW;;} break; case 65: #line 246 "xyparser.Y" {(yyval.integer) = Coord::WCSX;;} break; case 66: #line 247 "xyparser.Y" {(yyval.integer) = Coord::WCSY;;} break; case 67: #line 248 "xyparser.Y" {(yyval.integer) = Coord::WCSZ;;} break; case 68: #line 251 "xyparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 69: #line 252 "xyparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 70: #line 253 "xyparser.Y" {(yyval.integer) = Coord::FK4_NO_E;;} break; case 71: #line 254 "xyparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 72: #line 255 "xyparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 73: #line 256 "xyparser.Y" {(yyval.integer) = Coord::ICRS;;} break; case 74: #line 257 "xyparser.Y" {(yyval.integer) = Coord::GALACTIC;;} break; case 75: #line 258 "xyparser.Y" {(yyval.integer) = Coord::SUPERGALACTIC;;} break; case 76: #line 259 "xyparser.Y" {(yyval.integer) = Coord::ECLIPTIC;;} break; case 77: #line 260 "xyparser.Y" {(yyval.integer) = Coord::HELIOECLIPTIC;;} break; case 78: #line 263 "xyparser.Y" {fr->createPointCmd(Vector((yyvsp[(1) - (1)].vector)), Point::BOXCIRCLE, POINTSIZE, "green",dash,1,"helvetica 10 normal roman","", Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE, "",taglist,cblist); ;} break; /* Line 1267 of yacc.c. */ #line 1931 "xyparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 272 "xyparser.Y" ������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid3d.h�����������������������������������������������������������������������0000644�0001750�0001750�00000001431�12001331444�014632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid3d_h__ #define __grid3d_h__ #include <tk.h> #include "grid.h" #include "grid3dbase.h" #include "coord.h" class Grid3d : public Grid, public Grid3dBase { private: void* matrixMap(Matrix&, const char*); int doit(RenderMode); public: Grid3d(Widget*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, GridType, const char*, const char*); ~Grid3d(); const char* option() {return GridBase::option();} void x11() {doit(X11);} void ps(int mode) {mode_=mode; doit(PS);} #ifdef _MACOSX void macosx() {doit(MACOSX);} #endif #ifdef _WIN32 void win32() {doit(GWIN32);} #endif }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basemarker.h�������������������������������������������������������������������0000644�0001750�0001750�00000002331�11727727777�015632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __basemarker_h__ #define __basemarker_h__ #include "marker.h" #define MAXANNULI 512 #define MAXANGLES 720 class BaseMarker : public Marker { protected: Vector* annuli_; int numAnnuli_; double startAng_; double stopAng_; protected: void sortAnnuli(); int insertAnnuli(Vector); Matrix fwdMatrix(); Matrix bckMatrix(); Vector fwdMap(const Vector&, Coord::InternalSystem); Vector bckMap(const Vector&, Coord::InternalSystem); public: BaseMarker(const BaseMarker&); BaseMarker(Base*, const Vector&, double, const char*, int* dsh, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); virtual ~BaseMarker(); virtual Marker* dup() =0; void updateCoords(const Matrix&); int numAnnuli() {return numAnnuli_;} Vector annuli(int i) {return annuli_[i];} void setAnnuli(const Vector&); void setAnnuli(const Vector&, const Vector&, int); void setAnnuli(const Vector*, int); virtual int addAnnuli() {return 0;} void deleteAnnuli(int h); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue8.h��������������������������������������������������������������0000644�0001750�0001750�00000004453�11700666266�016625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscaletrue8_h__ #define __colorscaletrue8_h__ #include "colorscale.h" #include "truecolor8.h" class ColorScaleTrueColor8 : public virtual ColorScale, public TrueColor8 { public: ColorScaleTrueColor8(int, Visual*); virtual ~ColorScaleTrueColor8(); }; class LinearScaleTrueColor8 : public virtual ColorScale, public LinearScale, public ColorScaleTrueColor8 { public: LinearScaleTrueColor8(int, unsigned short*, unsigned char*, int, Visual*); }; class LogScaleTrueColor8 : public virtual ColorScale, public LogScale, public ColorScaleTrueColor8 { public: LogScaleTrueColor8(int, unsigned short*, unsigned char*, int, double, Visual*); }; class PowScaleTrueColor8 : public virtual ColorScale, public PowScale, public ColorScaleTrueColor8 { public: PowScaleTrueColor8(int, unsigned short*, unsigned char*, int, double, Visual*); }; class SqrtScaleTrueColor8 : public virtual ColorScale, public SqrtScale, public ColorScaleTrueColor8 { public: SqrtScaleTrueColor8(int, unsigned short*, unsigned char*, int, Visual*); }; class SquaredScaleTrueColor8 : public virtual ColorScale, public SquaredScale, public ColorScaleTrueColor8 { public: SquaredScaleTrueColor8(int, unsigned short*, unsigned char*, int, Visual*); }; class AsinhScaleTrueColor8 : public virtual ColorScale, public AsinhScale, public ColorScaleTrueColor8 { public: AsinhScaleTrueColor8(int, unsigned short*, unsigned char*, int, Visual*); }; class SinhScaleTrueColor8 : public virtual ColorScale, public SinhScale, public ColorScaleTrueColor8 { public: SinhScaleTrueColor8(int, unsigned short*, unsigned char*, int, Visual*); }; class IISScaleTrueColor8 : public virtual ColorScale, public IISScale, public ColorScaleTrueColor8 { public: IISScaleTrueColor8(unsigned short*, unsigned char*, int, Visual*); }; class HistEquScaleTrueColor8 : public virtual ColorScale, public HistEquScale, public ColorScaleTrueColor8 { public: HistEquScaleTrueColor8(int, unsigned short*, unsigned char*, int, double*, int, Visual*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/base.h�������������������������������������������������������������������������0000644�0001750�0001750�00000200061�12131563542�014402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __base_h__ #define __base_h__ #include "widget.h" #include "vector3d.h" #include "callback.h" #include "fvcontour.h" #include "frscale.h" #include "grid2d.h" #include "grid25d.h" #include "grid3d.h" #include "hist.h" #include "inversescale.h" #include "list.h" #include "tag.h" #include "util.h" #include "point.h" extern int DebugAST; extern int DebugMosaic; extern int DebugPerf; extern int DebugWCS; extern int DebugBin; extern int DebugCompress; extern int DebugCrop; extern int DebugGZ; extern int DebugRGB; #define DEFAULTLOW 0 #define DEFAULTHIGH 100 #define HISTEQUSIZE 16384 #define MULTWCS 28 #define SCALESIZE 16384 class Attribute; class BaseBox; class BaseEllipse; class BaseMarker; class Composite; class Context; class Contour; class Filter; class FitsImage; class FitsMask; class FVContour; class Grid; class Grid2d; class Grid25d; class Grid3d; class Marker; class Annulus; class Box; class BoxAnnulus; class Bpanda; class Circle; class Compass; class Contour; class Cpanda; class Ellipse; class EllipseAnnulus; class Epanda; class Line; class Point; class Projection; class Polygon; class Ruler; class Text; class Vect; class Base : public Widget { friend class Attribute; friend class BaseBox; friend class BaseEllipse; friend class BaseMarker; friend class Composite; friend class Context; friend class Contour; friend class FitsImage; friend class FitsMask; friend class FVContour; friend class Grid; friend class Grid2d; friend class Grid25d; friend class Grid3d; friend class Marker; friend class Annulus; friend class Box; friend class BoxAnnulus; friend class Bpanda; friend class Circle; friend class Compass; friend class Cpanda; friend class Ellipse; friend class EllipseAnnulus; friend class Epanda; friend class Line; friend class Point; friend class Projection; friend class Polygon; friend class Ruler; friend class Text; friend class Vect; public: enum CompressType {NOCOMPRESS, GZ}; enum FileNameType {ROOTBASE, FULLBASE, ROOT, FULL, ROOT3D, FULL3D}; enum MarkerFormat {DS9, XML, CIAO, SAOTNG, SAOIMAGE, PROS, RAWXY}; enum MarkerLayer {USER, TEMPLATE, CATALOG}; enum ShmType {SHMID,KEY}; enum UndoMarkerType {NONE, MOVE, EDIT, DELETE}; enum UpdateType {MATRIX, BASE, PIXMAP, NOUPDATE}; enum MemType {ALLOC, ALLOCGZ, CHANNEL, MMAP, SMMAP, MMAPINCR, SHARE, SSHARE, SOCKET, SOCKETGZ, VAR, HIST, COMPRESS, PHOTO}; enum MosaicType {NOMOSAIC, IRAF, WCSMOSAIC, WFPC2}; enum LayerType {IMG, MASK}; enum LoadMethod {LOADALL, INCR}; enum Precision {DEFAULT, FIXED, SCIENTIFIC, INTEGER}; private: InverseScale* inverseScale; protected: Context* context; int threads_; List<Marker>* markers; // pointer to current marker stack List<Marker>* undoMarkers; // pointer to current marker stack List<Marker>* pasteMarkers;// pointer to current marker stack List<Marker> userMarkers; // foreground marker stack List<Marker> undoUserMarkers; // remember marker to undo List<Marker> pasteUserMarkers; // cut/copy/paste List<Marker> catalogMarkers; // background marker stack List<Marker> undoCatalogMarkers; // remember marker to undo List<Marker> pasteCatalogMarkers; // cut/copy/paste UndoMarkerType undoMarkerType; // type Vector markerBegin; // marker move begin in image coords Marker* editMarker; // pointer to marker currently being edited Marker* rotateMarker; // pointer to marker currently being rotated Vector regionBegin; // select region begin in canvas coords Vector regionEnd; // select region end in canvas coords Composite* compositeMarker; // pointer to current composite marker Vector cursor; // current cursor position in REF coords Vector crosshair; // crosshair location in REF coords XImage* baseXImage; // ximage of image Pixmap basePixmap; // pixmap of image UpdateType needsUpdate; // updateFlags int syncUpdate; // update 3d syncronously Context* currentContext; Context* keyContext; int keyContextSet; Coord::Orientation orientation; // current image orientation Matrix orientationMatrix; // current image orientation matrix double rotation; // current image rotation angle double rotateRotation; // tmp cursor for interactive rotation int preservePan; // flag to indicate preserve between loads Vector zoom_; // current image zoom value Pixmap panPM; // tmp pixmap for pan motion Vector panCursor; // cursor for interactive panning GC panGCXOR; // GC for interactive panning GC rotateGCXOR; // GC for interactive rotation Pixmap pannerPixmap; // pixmap for panner XImage* pannerXImage; // ximage for panner int pannerWidth; // panner width int pannerHeight; // panner height char pannerName[32]; // panner widget name int usePanner; // panner status GC pannerGC; Pixmap magnifierPixmap; // pixmap for magnifier XImage* magnifierXImage; // ximage for magnifier int magnifierWidth; // magnifier width int magnifierHeight; // magnifier height double magnifierZoom_; // magnifier zoom factor char magnifierName[32]; // magnifer widget name int useMagnifier; // magnifer status int useMagnifierGraphics; // magnifer marker status int useMagnifierCursor; // magnifier cursor status Vector magnifierCursor; // we need to save the last cursor used char* magnifierColorName; Vector cropBegin; Vector cropEnd; Coord::CoordSystem wcsSystem_; Coord::SkyFrame wcsSky_; Coord::SkyFormat wcsSkyFormat_; int wcsAlt_; // flag to indicate an alternative wcs current int wcsAlign_; // flag to indicate wcs alignment Coord::CoordSystem xySystem_; // default marker sys (RAWXY) Coord::SkyFrame xySky_; // default marker sky (RAWXY) Coord::Orientation wcsOrientation; // wcs image orientation Matrix wcsOrientationMatrix; // wcs image orientation matrix double wcsRotation; // wcs image rotation angle Coord::Orientation irafOrientation; // orientation of first iraf segment char* maskColorName; float maskAlpha; int maskMark; int invert; FitsHist::Function binFunction_; Vector binFactor_; int binBufferSize_; int binDepth_; int doSmooth_; int smoothFunction_; int smoothRadius_; GC highliteGC; int useHighlite; XRectangle rectWidget[1]; XRectangle rectWindow[1]; int useCrosshair; int showMarkers; int showMarkersText; int centroidAuto; int centroidIteration; float centroidRadius; int preserveMarkers; // flag to indicate preserve between loads GC markerGC; // marker gc GC markerGCXOR; // marker xor gc GC selectGCXOR; // select gc Grid* grid; GC gridGC; GC contourGC; char* bgColorName; XColor* bgColor; char bgTrueColor_[4]; // color encoded char* nanColorName; XColor* nanColor; char nanTrueColor_[4]; // color encoded float dlist[2]; char* colorbartag; Matrix dataToImage; Matrix imageToData; Matrix canvasToRef; Matrix canvasToUser; Matrix canvasToWidget; Matrix canvasToWindow; Matrix refToCanvas; Matrix refToUser; Matrix refToWidget; Matrix refToWindow; Matrix userToCanvas; Matrix userToRef; Matrix userToWidget; Matrix widgetToCanvas; Matrix widgetToRef; Matrix widgetToUser; Matrix widgetToWindow; Matrix windowToCanvas; Matrix windowToRef; Matrix windowToWidget; Matrix magnifierToRef; Matrix magnifierToUser; Matrix magnifierToWidget; Matrix refToMagnifier; Matrix userToMagnifier; Matrix widgetToMagnifier; Matrix pannerToRef; Matrix pannerToUser; Matrix pannerToWidget; Matrix refToPanner; Matrix userToPanner; Matrix widgetToPanner; private: void bltHist(char*, char*); // frblt.C void getInfoClearName(char*); void getInfoClearValue(char*); void getInfoClearWCS(char*); void getInfoWCS(char*, const Vector3d&, FitsImage*, FitsImage*); void invalidPixmap(); int updatePixmap(const BBox&); protected: virtual void alignWCS(); virtual void alignWCS(Coord::CoordSystem, Coord::SkyFrame); virtual void alignWCS(FitsImage*, Coord::CoordSystem); void bltCut(char*, char*, Coord::Orientation, const Vector&); void bltCutFits(double*, double*, int, Coord::Orientation, const Vector&); virtual void buildXImage(XImage*, Coord::InternalSystem) =0; virtual void centerImage(); double calcZoom(Vector,Vector); virtual double calcZoomPanner() =0; void coordToTclArray(FitsImage*, const Vector3d&, Coord::CoordSystem, Precision, const char*, const char*); void coord3ToTclArray(FitsImage*, const Vector3d&, Coord::CoordSystem, Precision, const char*, const char*); void createMarker(Marker*); void createTemplate(const Vector&, istream&); virtual int doRender(); void doubleToTclArray(double, Precision, const char*, const char*, const char*); virtual void encodeTrueColor(int, int) =0; virtual void encodeTrueColor(XColor*, char*) =0; virtual void encodeTrueColor(unsigned char*, XImage*) =0; virtual unsigned char* fillImage(int, int, Coord::InternalSystem) =0; Coord::Orientation getOrientation() {return orientation;} double getRotation() {return rotation + wcsRotation;} Coord::Orientation getWCSOrientation() {return wcsOrientation;} int hasATMV(); int hasContour(); int hasContourAux(); int hasDTMV(); int hasLTMV(); int hasWCS(Coord::CoordSystem); int hasWCSEqu(Coord::CoordSystem); int hasWCSCel(Coord::CoordSystem); int hasWCSx(Coord::CoordSystem); virtual BBox imageBBox(FrScale::ScanMode); Vector imageCenter(FrScale::ScanMode); Vector imageSize(FrScale::ScanMode); virtual int isIIS(); FitsImage* isInFits(const Vector&, Coord::InternalSystem, Vector*); FitsImage* isInCFits(const Vector&, Coord::InternalSystem, Vector*); virtual int isAzElZero() {return 1;} virtual int isFrame() {return 0;} virtual int isFrame3d() {return 0;} virtual int isFrameRGB() {return 0;} void loadDone(int, LayerType); int markerAnalysisPlot2d(Marker*, double**, double**, double**, double**, Vector&, Vector&, int, Coord::CoordSystem, Coord::SkyFrame, Marker::AnalysisMethod); int markerAnalysisPlot3d(Marker*, double**, double**, const BBox&, Coord::CoordSystem, Marker::AnalysisMethod); int markerAnalysisRadial(Marker*, double**, double**, double**, int, Vector*, BBox*, Coord::CoordSystem); int markerAnalysisPanda(Marker*, double**, double**, double**, int, Vector*, int, double*, BBox*, Coord::CoordSystem); int markerAnalysisStats1(FitsImage*, ostream&, Coord::CoordSystem); void markerAnalysisStats2(FitsImage*, ostream&, Coord::CoordSystem, int, int, double, int); void markerAnalysisStats3(ostream&); void markerAnalysisStats4(ostream&, int, int, double, double, double, double, double); void markerAnalysisStats(Marker*, ostream&, const BBox&, Coord::CoordSystem); void markerAnalysisStats(Marker*, ostream&, int, BBox*, Coord::CoordSystem); void markerAnalysisStats(Marker*, ostream&, int, int, BBox*, Coord::CoordSystem); double mapDistFromRef(const Vector&, const Vector&, Coord::InternalSystem); double mapLenFromRef(double, Coord::InternalSystem); Vector mapLenFromRef(const Vector&, Coord::InternalSystem); double mapLenToRef(double, Coord::InternalSystem); Vector mapLenToRef(const Vector&, Coord::InternalSystem); void markerListHeader(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void markerListXMLHeader(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void markerListXMLFooter(ostream&); void markerListCiaoHeader(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void markerListSAOtngHeader(ostream&,Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void markerPrintCoord(const Vector&, Coord::InternalSystem); void markerPrintCoord(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void markerPrintDouble(double, Coord::InternalSystem); void markerPrintDouble(const Vector&, double, Coord::CoordSystem, Coord::SkyDist); void markerPrintDouble(const Vector&, const Vector&, Coord::InternalSystem); void markerPrintDouble(const Vector&, const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyDist); void markerPrintVector(const Vector&,Coord::InternalSystem); void markerPrintVector(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyDist); void markerUndo(Marker*, UndoMarkerType); void parseMarker(MarkerFormat,istream&); FitsHead* parseWCS(istream&); int postscriptProc(int prepass); void printCoordSystem(Coord::CoordSystem); void printDouble(double, Precision); void printFromRef(FitsImage*, const Vector&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision); void printInteger(int); void printSkyFrame(Coord::SkyFrame); void printSkyFormat(Coord::SkyFormat); void printSkyDist(Coord::SkyDist); void printVector(const Vector&, Precision); void printVector(const Vector3d&, Precision); void ps(); void psContours(PSColorSpace); void psCrosshair(PSColorSpace); virtual void psGraphics(PSColorSpace) {} void psImage(Filter&, PSColorSpace, int, int, float); void psMarkers(List<Marker>*, int); Matrix psMatrix(float scale, int width, int height); virtual void pushMatrices(); virtual void pushMagnifierMatrices(); virtual void pushPannerMatrices(); virtual void pushPSMatrices(float, int, int); virtual void reset(); void resetScanMode(); virtual void setBinCursor() =0; void setClip(); FrScale::ScanMode scanMode(); void setScanMode(FrScale::ScanMode); void setScanModeIncr(LoadMethod); void setSlice(int,int); void unhighliteMarkers(); void unselectMarkers(List<Marker>*); void update(UpdateType); void update(UpdateType,BBox); void updateMarkers(List<Marker>*); void updateMarkerCBs(List<Marker>*); void updateMarkerCoords(List<Marker>*, const Matrix&); virtual void unloadFits(); virtual void unloadAllFits(); void updateBase(); virtual void updateBin(const Matrix&); void updateCBMarkers(); virtual void updateColorScale() =0; virtual void updateGCs(); void updateMagnifier(); void updateMagnifier(const Vector&); virtual void updateMatrices(); virtual void updateMagnifierMatrices(); virtual void updatePannerMatrices(); void updateNow(UpdateType); void updateNow(UpdateType,BBox); virtual void updatePanner(); void updatePM(const BBox&); char* varcat(char*, char*, char, char*); virtual int validColorScale() =0; void x11Contours(Pixmap, Coord::InternalSystem, int, int); void x11Crosshair(Pixmap, Coord::InternalSystem, int, int); void x11Dash(GC, int); virtual void x11Graphics(); virtual void x11MagnifierCursor(const Vector&) {} void x11MagnifierMarkers(List<Marker>*, const BBox& bb); void x11Markers(List<Marker>*, const BBox&); void x11MarkerXOR(Marker*); void xmlParse(istream&); void xmlParseFIELD(void*, int*, char**, char**, char**, char**, int); void xmlParseTR(char**, int*, char**, char**, char**, char**, int); void xmlSetProps(unsigned short*, unsigned short, char*); int xmlCount(const char*); Vector xmlPoint(FitsImage*, const char* x, const char* y, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int which=0); List<Vertex>* xmlVertex(FitsImage*, const char*, const char*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); double xmlAngle(const char*, int, double, Coord::AngleFormat, Coord::CoordSystem, Coord::SkyFrame); double* xmlAngles(const char*, int, double, int, Coord::AngleFormat, Coord::CoordSystem, Coord::SkyFrame); double* xmlDistance(FitsImage*, const char*, int, Coord::CoordSystem, Coord::SkyDist); Vector* xmlDistance(FitsImage*, const char*, const char*, int, Coord::CoordSystem, Coord::SkyDist); void ximageToPixmap(Pixmap pmap, XImage* xmap, Coord::InternalSystem); virtual void ximageToPixmapMagnifier(); Vector zoom() {return zoom_;} #ifdef _MACOSX void macosx(); void macosxContours(); void macosxCrosshair(); virtual void macosxGraphics() {} void macosxImage(float, int, int, const Vector&, const Vector&) void macosxMarkers(List<Marker>* ml); #endif #ifdef _WIN32 void win32(); void win32Contours(); void win32Crosshair(); virtual void win32Graphics() {} void win32Image(float, int, int, const Vector&, const Vector&); void win32Markers(List<Marker>* ml); #endif public: Base(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item); virtual ~Base(); void calcAlignWCS(FitsImage*, Coord::CoordSystem, Coord::SkyFrame, Coord::Orientation*, Matrix*, double*); void calcAlignWCS(FitsImage*, FitsImage*, Coord::CoordSystem, Coord::CoordSystem, Coord::SkyFrame, Coord::Orientation*, Matrix*, double*, Vector*); Matrix calcAlignWCS(FitsImage*, FitsImage*, Coord::CoordSystem, Coord::CoordSystem, Coord::SkyFrame); Vector centroid(const Vector&); FitsImage* findFits(); FitsImage* findFits(Coord::CoordSystem, const Vector&); FitsImage* findFits(const Vector&); FitsImage* findFits(int); int findFits(FitsImage*); FitsImage* findAllFits(int); int fitsCount(); Coord::Orientation IRAFOrientation(Coord::Orientation); int isMosaic(); int isCube(); int isBinTable(); virtual Vector mapFromRef(const Vector&, Coord::InternalSystem) =0; virtual Vector3d mapFromRef3d(const Vector&, Coord::InternalSystem) =0; virtual Vector mapToRef(const Vector&, Coord::InternalSystem) =0; virtual Vector3d mapToRef3d(const Vector&, Coord::InternalSystem) =0; double mapAngleFromRef(double, Coord::CoordSystem, Coord::SkyFrame =Coord::FK5); double mapAngleToRef(double, Coord::CoordSystem, Coord::SkyFrame =Coord::FK5); int parse(istringstream&); void resetCompositeMarker() {compositeMarker = NULL;} Coord::CoordSystem wcsSystem() {return wcsSystem_;} Coord::SkyFrame wcsSky() {return wcsSky_;} Coord::SkyFormat wcsSkyFormat() {return wcsSkyFormat_;} Coord::CoordSystem xySystem() {return xySystem_;} Coord::SkyFrame xySky() {return xySky_;} void matchCmd(const char* xxname1, const char* yyname1, Coord::CoordSystem sys1, Coord::SkyFrame sky1, const char* xxname2, const char* yyname2, Coord::CoordSystem sys2, Coord::SkyFrame sky2, double rad, Coord::CoordSystem sys, Coord::SkyDist dist, const char* rr); // Background Commands void bgColorCmd(const char*); void getBgColorCmd(); // Bin Commands void binCmd(const Vector&, const char*, const char*, const char*); void binCmd(const Vector&, const Vector&, const char*, const char*, const char*); void binCmd(const Vector&, int, const Vector&, const char*, const char*, const char*, const char*); void binCmd(const Vector&, int, const Vector&, const Vector&, const char*, const char*, const char*, const char*); void binAboutCmd(); void binAboutCmd(const Vector&); void binColsCmd(const char*, const char*, const char*); void binDepthCmd(int); void binFactorCmd(const Vector&); void binFactorAboutCmd(const Vector&, const Vector&); void binFactorToCmd(const Vector&); void binFactorToAboutCmd(const Vector&, const Vector&); void binFunctionCmd(FitsHist::Function); void binBufferSizeCmd(int); void binFilterCmd(const char*); virtual void binToFitCmd() =0; void getBinDepthCmd(); void getBinFactorCmd(); void getBinFunctionCmd(); void getBinBufferSizeCmd(); void getBinCursorCmd(); void getBinFilterCmd(); void getBinColsCmd(); void getBinColsMinMaxCmd(const char*); void getBinColsDimCmd(const char*); void getBinListCmd(); void hasBinColCmd(const char*); // Clip Commands void clipMinMaxModeCmd(FrScale::MinMaxMode); void clipMinMaxSampleCmd(int); void clipModeCmd(float); void clipModeCmd(FrScale::ClipMode); void clipPreserveCmd(int); virtual void clipScopeCmd(FrScale::ClipScope); void clipUserCmd(double, double); void clipUserLowCmd(double); void clipUserHighCmd(double); void clipZScaleContrastCmd(float); void clipZScaleSampleCmd(int); void clipZScaleLineCmd(int); void getClipCmd(); void getClipCmd(float); void getClipCmd(FrScale::ClipMode); void getClipMinMaxModeCmd(); void getClipMinMaxSampleCmd(); void getClipModeCmd(); void getClipPreserveCmd(); void getClipScopeCmd(); void getClipUserCmd(); void getClipZScaleContrastCmd(); void getClipZScaleSampleCmd(); void getClipZScaleLineCmd(); void getHistogramCmd(char*, char*); void getMinMaxCmd(); void hasDATAMINCmd(); void hasIRAFMINCmd(); // Colormap Commands void colorbarTagCmd(const char*); virtual void colormapCmd(int, float, float, int, unsigned short*, unsigned char*, int) {} virtual void colormapCmd(float, float, float, float, float, float, int, unsigned char*, int) {} virtual void colormapBeginCmd() {} virtual void colormapEndCmd() {} virtual void colormapMotionCmd(int, float, float, int, unsigned short*, unsigned char*, int) {} virtual void colormapMotionCmd(float, float, float, float, float, float, int, unsigned char*, int) {} virtual void getColorbarCmd() =0; void getColorbarTagCmd(); // Contour Commands void contourAuxHeadCmd(); void contourAuxNextCmd(); void contourAuxSaveCmd(const char*, Coord::CoordSystem, Coord::SkyFrame); void contourCopyCmd(Coord::CoordSystem, Coord::SkyFrame); void contourCreateCmd(const char*, int, int, FVContour::Method, int, int, FrScale::ColorScaleType, float, float, Vector, const char*); void contourDeleteCmd(); void contourDeleteAllCmd(); void contourLoadCmd(const char*, int, int, const char*, Coord::CoordSystem,Coord::SkyFrame); void contourPasteCmd(const char*, int, int, void*, Coord::CoordSystem, Coord::SkyFrame); void contourSaveCmd(const char*, Coord::CoordSystem, Coord::SkyFrame); void contourSetDashCmd(int); void contourSetColorCmd(const char*); void contourSetLineWidthCmd(int); void getContourAuxColorNameCmd(); void getContourAuxDashCmd(); void getContourAuxLineWidthCmd(); void getContourCmd(Coord::CoordSystem sys, Coord::SkyFrame sky); void getContourClipCmd(); void getContourClipModeCmd(); void getContourColorNameCmd(); void getContourDashCmd(); void getContourLevelCmd(); void getContourLineWidthCmd(); void getContourMethodCmd(); void getContourNumLevelCmd(); void getContourScaleCmd(); void getContourScaleLogCmd(); void getContourSmoothCmd(); void hasContourCmd(); void hasContourAuxCmd(); // Coordinate Commands void getWCSCmd(); void wcsCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getWCSNameCmd(Coord::CoordSystem); void getWCSAlignCmd(); void getWCSAlignPointerCmd(); void getCoordCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getCoordFromRefCmd(double, Coord::CoordSystem, int); void getCoordToRefCmd(double, Coord::CoordSystem, int); virtual void getCursorCmd(Coord::InternalSystem) =0; virtual void getCursorCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision) =0; void hasSystemCmd(Coord::CoordSystem); void hasAmplifierCmd(); void hasDetectorCmd(); void hasPhysicalCmd(); void hasWCSAltCmd(); void hasWCSCmd(Coord::CoordSystem); void hasWCSEquCmd(Coord::CoordSystem); void hasWCSCelCmd(Coord::CoordSystem); void hasWCSxCmd(Coord::CoordSystem); // Crop Commands void cropCmd(); void cropCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void cropCenterCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame, const Vector&, Coord::CoordSystem, Coord::SkyDist); void cropBeginCmd(const Vector&); void cropMotionCmd(const Vector&); void cropEndCmd(const Vector&); void crop3dCmd(); void crop3dCmd(double, double, Coord::CoordSystem); virtual void crop3dBeginCmd(const Vector&, int) {} virtual void crop3dMotionCmd(const Vector&, int) {} virtual void crop3dEndCmd(const Vector&, int) {} void getCropCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getCropCenterCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Coord::CoordSystem, Coord::SkyDist); void getCrop3dCmd(Coord::CoordSystem); void hasCropCmd(); // CrossHair Commands void crosshairCmd(int); void crosshairCmd(const Vector&, Coord::InternalSystem); void crosshairCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame =Coord::FK5); void crosshairWarpCmd(const Vector&); void getCrosshairCmd(Coord::InternalSystem); void getCrosshairCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision); void getCrosshairStatusCmd(); // DATASEC Commands void DATASECCmd(int); void getDATASECCmd(); void hasDATASECCmd(); // Data Values void getDataValuesCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyFrame, const Vector&, char*); void getDataValuesCmd(const Vector&, Coord::InternalSystem, const Vector&); // Fits Commands void getBitpixCmd(); void getFitsNAxesCmd(); void getFitsCountCmd(); void getFitsCenterCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision); void getFitsDepthCmd(int); void getFitsExtCmd(const Vector&, Coord::InternalSystem); void getFitsFileNameCmd(FileNameType); void getFitsFileNameCmd(int,FileNameType); void getFitsFileNameCmd(const Vector&, Coord::InternalSystem, FileNameType); void getFitsHeaderCmd(int); void getFitsHeaderWCSCmd(int); void getFitsHeaderKeywordCmd(int,const char*); void getFitsObjectNameCmd(); void getFitsSizeCmd(); void getFitsSizeCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyDist, Precision); void getFitsSliceCmd(int); void hasFitsCmd(); void hasFitsHPXCmd(); void hasFitsBinCmd(); void hasFitsCubeCmd(); void hasFitsMosaicCmd(); void loadFitsAllocCmd(const char*, const char*, LayerType); void loadFitsAllocGZCmd(const char*, const char*, LayerType); void loadFitsChannelCmd(const char*, const char*, LayerType); void loadFitsMMapCmd(const char*, LoadMethod, LayerType); void loadFitsSMMapCmd(const char*, const char*, LoadMethod,LayerType); void loadFitsMMapIncrCmd(const char*, LoadMethod, LayerType); void loadFitsShareCmd(ShmType, int, const char*, LoadMethod, LayerType); void loadFitsSShareCmd(ShmType, int, int, const char*, LoadMethod,LayerType); void loadFitsSocketCmd(int, const char*, LayerType); void loadFitsSocketGZCmd(int, const char*, LayerType); void loadFitsVarCmd(const char*, const char*, LoadMethod, LayerType); void loadArrAllocCmd(const char*, const char*, LayerType); void loadArrAllocGZCmd(const char*, const char*, LayerType); void loadArrChannelCmd(const char*, const char*, LayerType); void loadArrMMapCmd(const char*, LayerType); void loadArrMMapIncrCmd(const char*, LayerType); void loadArrShareCmd(ShmType, int, const char*, LayerType); void loadArrSocketCmd(int, const char*, LayerType); void loadArrSocketGZCmd(int, const char*, LayerType); void loadArrVarCmd(const char*, const char*, LayerType); void loadNRRDAllocCmd(const char*, const char*, LayerType); void loadNRRDChannelCmd(const char*, const char*, LayerType); void loadNRRDMMapCmd(const char*, LayerType); void loadNRRDShareCmd(ShmType, int, const char*, LayerType); void loadNRRDSocketCmd(int, const char*, LayerType); void loadNRRDVarCmd(const char*, const char*, LayerType); virtual void loadPhotoCmd(const char*, const char*); virtual void loadSlicePhotoCmd(const char*, const char*); void loadExtCubeAllocCmd(const char*, const char*); void loadExtCubeAllocGZCmd(const char*, const char*); void loadExtCubeChannelCmd(const char*, const char*); void loadExtCubeMMapCmd(const char*, LoadMethod); void loadExtCubeMMapIncrCmd(const char*, LoadMethod); void loadExtCubeShareCmd(ShmType, int, const char*, LoadMethod); void loadExtCubeSocketCmd(int, const char*); void loadExtCubeSocketGZCmd(int, const char*); void loadExtCubeVarCmd(const char*, const char*, LoadMethod); void loadSliceAllocCmd(const char*, const char*); void loadSliceAllocGZCmd(const char*, const char*); void loadSliceChannelCmd(const char*, const char*); void loadSliceMMapCmd(const char*, LoadMethod); void loadSliceSMMapCmd(const char*, const char*, LoadMethod); void loadSliceMMapIncrCmd(const char*, LoadMethod); void loadSliceShareCmd(ShmType, int, const char*, LoadMethod); void loadSliceSShareCmd(ShmType, int, int, const char*, LoadMethod); void loadSliceSocketCmd(int, const char*); void loadSliceSocketGZCmd(int, const char*); void loadSliceVarCmd(const char*, const char*, LoadMethod); void loadMosaicImageAllocCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicImageAllocGZCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicImageChannelCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicImageMMapCmd(MosaicType, Coord::CoordSystem, const char*, LoadMethod, LayerType); void loadMosaicImageMMapIncrCmd(MosaicType, Coord::CoordSystem, const char*, LoadMethod, LayerType); void loadMosaicImageShareCmd(MosaicType, Coord::CoordSystem, ShmType, int, const char*, LoadMethod, LayerType); void loadMosaicImageSocketCmd(MosaicType, Coord::CoordSystem, int, const char*, LayerType); void loadMosaicImageSocketGZCmd(MosaicType, Coord::CoordSystem, int, const char*, LayerType); void loadMosaicImageVarCmd(MosaicType, Coord::CoordSystem, const char*,const char*, LoadMethod, LayerType); void loadMosaicAllocCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicAllocGZCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicChannelCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LayerType); void loadMosaicMMapCmd(MosaicType, Coord::CoordSystem, const char*, LoadMethod, LayerType); void loadMosaicSMMapCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LoadMethod, LayerType); void loadMosaicMMapIncrCmd(MosaicType, Coord::CoordSystem, const char*, LoadMethod, LayerType); void loadMosaicShareCmd(MosaicType, Coord::CoordSystem, ShmType, int, const char*, LoadMethod, LayerType); void loadMosaicSShareCmd(MosaicType, Coord::CoordSystem, ShmType, int, int, const char*, LoadMethod, LayerType); void loadMosaicSocketCmd(MosaicType, Coord::CoordSystem, int, const char*, LayerType); void loadMosaicSocketGZCmd(MosaicType, Coord::CoordSystem, int, const char*, LayerType); void loadMosaicVarCmd(MosaicType, Coord::CoordSystem, const char*, const char*, LoadMethod, LayerType); void loadMosaicImageWFPC2AllocCmd(const char*, const char*); void loadMosaicImageWFPC2AllocGZCmd(const char*, const char*); void loadMosaicImageWFPC2ChannelCmd(const char*, const char*); void loadMosaicImageWFPC2MMapCmd(const char*, LoadMethod); void loadMosaicImageWFPC2MMapIncrCmd(const char*, LoadMethod); void loadMosaicImageWFPC2ShareCmd(ShmType, int, const char*,LoadMethod); void loadMosaicImageWFPC2SocketCmd(int, const char*); void loadMosaicImageWFPC2SocketGZCmd(int, const char*); void loadMosaicImageWFPC2VarCmd(const char*, const char*, LoadMethod); // Fits RGB virtual void loadRGBCubeAllocCmd(const char*, const char*) {} virtual void loadRGBCubeAllocGZCmd(const char*, const char*) {} virtual void loadRGBCubeChannelCmd(const char*, const char*) {} virtual void loadRGBCubeMMapCmd(const char*, LoadMethod) {} virtual void loadRGBCubeSMMapCmd(const char*, const char*, LoadMethod) {} virtual void loadRGBCubeMMapIncrCmd(const char*, LoadMethod) {} virtual void loadRGBCubeShareCmd(ShmType, int, const char*, LoadMethod) {} virtual void loadRGBCubeSShareCmd(ShmType,int,int,const char*,LoadMethod) {} virtual void loadRGBCubeSocketCmd(int, const char*) {} virtual void loadRGBCubeSocketGZCmd(int, const char*) {} virtual void loadRGBCubeVarCmd(const char*, const char*, LoadMethod) {} virtual void loadRGBImageAllocCmd(const char*, const char*) {} virtual void loadRGBImageAllocGZCmd(const char*, const char*) {} virtual void loadRGBImageChannelCmd(const char*, const char*) {} virtual void loadRGBImageMMapCmd(const char*, LoadMethod) {} virtual void loadRGBImageMMapIncrCmd(const char*, LoadMethod) {} virtual void loadRGBImageShareCmd(ShmType, int, const char*, LoadMethod) {} virtual void loadRGBImageSocketCmd(int, const char*) {} virtual void loadRGBImageSocketGZCmd(int, const char*) {} virtual void loadRGBImageVarCmd(const char*, const char*, LoadMethod) {} virtual void loadArrayRGBCubeAllocCmd(const char*, const char*) {} virtual void loadArrayRGBCubeAllocGZCmd(const char*, const char*) {} virtual void loadArrayRGBCubeChannelCmd(const char*, const char*) {} virtual void loadArrayRGBCubeMMapCmd(const char*) {} virtual void loadArrayRGBCubeMMapIncrCmd(const char*) {} virtual void loadArrayRGBCubeShareCmd(ShmType, int, const char*) {} virtual void loadArrayRGBCubeSocketCmd(int, const char*) {} virtual void loadArrayRGBCubeSocketGZCmd(int, const char*) {} virtual void loadArrayRGBCubeVarCmd(const char*, const char*) {} virtual void savePhotoCmd(const char*) {} void saveFits(OutFitsStream&); void saveFitsFileCmd(const char*); void saveFitsChannelCmd(const char*); void saveFitsSocketCmd(int); void saveFitsTable(OutFitsStream&); void saveFitsTableFileCmd(const char*); void saveFitsTableChannelCmd(const char*); void saveFitsTableSocketCmd(int); void saveFitsSlice(OutFitsStream&); void saveFitsSliceFileCmd(const char*); void saveFitsSliceChannelCmd(const char*); void saveFitsSliceSocketCmd(int); void saveFitsExtCube(OutFitsStream&); void saveFitsExtCubeFileCmd(const char*); void saveFitsExtCubeChannelCmd(const char*); void saveFitsExtCubeSocketCmd(int); void saveFitsMosaic(OutFitsStream&, int); void saveFitsMosaicFileCmd(const char*, int); void saveFitsMosaicChannelCmd(const char*, int); void saveFitsMosaicSocketCmd(int, int); void saveFitsMosaicImage(OutFitsStream&); void saveFitsMosaicImageFileCmd(const char*); void saveFitsMosaicImageChannelCmd(const char*); void saveFitsMosaicImageSocketCmd(int); virtual void saveFitsRGBImage(OutFitsStream&) {} virtual void saveFitsRGBImageFileCmd(const char*) {} virtual void saveFitsRGBImageChannelCmd(const char*) {} virtual void saveFitsRGBImageSocketCmd(int) {} virtual void saveFitsRGBCube(OutFitsStream&) {} virtual void saveFitsRGBCubeFileCmd(const char*) {} virtual void saveFitsRGBCubeChannelCmd(const char*) {} virtual void saveFitsRGBCubeSocketCmd(int) {} virtual void saveFitsResampleFileCmd(const char*) {} virtual void saveFitsResampleChannelCmd(const char*) {} virtual void saveFitsResampleSocketCmd(int) {} void saveArray(OutFitsStream&, FitsFile::ArchType); void saveArrayFileCmd(const char*, FitsFile::ArchType); void saveArrayChannelCmd(const char*, FitsFile::ArchType); void saveArraySocketCmd(int, FitsFile::ArchType); virtual void saveArrayRGBCube(OutFitsStream&, FitsFile::ArchType) {} virtual void saveArrayRGBCubeFileCmd(const char*, FitsFile::ArchType) {} virtual void saveArrayRGBCubeChannelCmd(const char*, FitsFile::ArchType) {} virtual void saveArrayRGBCubeSocketCmd(int, FitsFile::ArchType) {} void saveNRRD(OutFitsStream&, FitsFile::ArchType); void saveNRRDFileCmd(const char*, FitsFile::ArchType); void saveNRRDChannelCmd(const char*, FitsFile::ArchType); void saveNRRDSocketCmd(int, FitsFile::ArchType); void sliceCmd(int, int); void updateFitsCmd(int); void updateFitsCmd(int, BBox, int); void unloadFitsCmd(); // Fitsy Commands void fitsyHasExtCmd(const char*); // Frame Commands void clearCmd(); void getHeightCmd(); virtual void getTypeCmd() =0; void getWidthCmd(); void highliteCmd(int); void warpCmd(const Vector&); void warpToCmd(const Vector&); // Graph Commands void getHorzCutCmd(char*, char*, const Vector&, Coord::InternalSystem); void getVertCutCmd(char*, char*, const Vector&, Coord::InternalSystem); // Grid Commands virtual void gridCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Grid::GridType, const char*, const char*) =0; void gridDeleteCmd(); void getGridCmd(); void getGridOptionCmd(); void getGridVarsCmd(); void hasGridCmd(); // IIS Commands virtual void iisCmd(int, int) {} virtual void iisCursorModeCmd(int) {} virtual void iisEraseCmd() {} virtual void iisGetCmd(char*, int, int, int, int) {} virtual void iisGetCursorCmd() {} virtual void iisGetFileNameCmd() {} virtual void iisGetFileNameCmd(int) {} virtual void iisGetFileNameCmd(const Vector&) {} virtual void iisMessageCmd(const char*) {} virtual void iisSetCmd(const char*, int, int, int, int) {} virtual void iisSetCursorCmd(const Vector&, Coord::InternalSystem) {} virtual void iisSetCursorCmd(const Vector&, Coord::CoordSystem) {} virtual void iisSetFileNameCmd(const char*) {} virtual void iisSetFileNameCmd(const char*,int) {} virtual void iisUpdateCmd() {} virtual void iisWCSCmd(const Matrix&, const Vector&, int) {} void hasIISCmd(); // Info Commands void getInfoCmd(char*); virtual void getInfoCmd(const Vector&, Coord::InternalSystem, char*); void getInfoClipCmd(); void getValueCmd(const Vector&, Coord::InternalSystem); // loadIncr is only used by LICK OBS // maintained for backward compatibility void loadIncrDataCmd(int, int, int, int, int); void loadIncrMinMaxCmd(int, int, int, int, int); void loadIncrEndCmd(); // Magnifier Commands void magnifierCmd(char*, int, int); void magnifierCmd(int); void magnifierGraphicsCmd(int); void magnifierCursorCmd(int); void magnifierZoomCmd(double); void magnifierColorCmd(const char*); void updateMagnifierCmd(const Vector& v); // Marker Commands // Basic Regions void createCircleCmd(const Vector&, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createEllipseCmd(const Vector&, const Vector&, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createBoxCmd(const Vector&, const Vector&, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createPolygonCmd(const Vector&, const Vector&, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createPolygonCmd(const List<Vertex>&, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createContourPolygonCmd(const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createLineCmd(const Vector&, const Vector&, int, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createVectCmd(const Vector&, const Vector&, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createVectCmd(const Vector&, double mag, double ang, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createTextCmd(const Vector&, double, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createPointCmd(const Vector&, Point::PointShape, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); // Measurement Regions void createRulerCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame, Coord::CoordSystem, Coord::SkyDist, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createCompassCmd(const Vector&, double, const char*, const char*, int, int, Coord::CoordSystem, Coord::SkyFrame, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createProjectionCmd(const Vector&, const Vector&, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); // Annulus Regions void createAnnulusCmd(const Vector&, double, double, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createAnnulusCmd(const Vector&, int, double*, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createEllipseAnnulusCmd(const Vector&, const Vector&, const Vector&, int, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createEllipseAnnulusCmd(const Vector&, int, Vector*, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createBoxAnnulusCmd(const Vector&, const Vector&, const Vector&, int, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createBoxAnnulusCmd(const Vector&, int, Vector*, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); // Panda Regions void createCpandaCmd(const Vector&, double, double, int, double, double, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createCpandaCmd(const Vector&, int, double*, int, double*, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createEpandaCmd(const Vector&, double, double, int, const Vector&, const Vector&, int, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createEpandaCmd(const Vector&, int, double*, int, Vector*, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createBpandaCmd(const Vector&, double, double, int, const Vector&, const Vector&, int, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createBpandaCmd(const Vector&, int, double*, int, Vector*, double, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); // Composite Regions void createCompositeCmd(const Vector&, double, int, const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); void createCompositeCmd( const char*, int*, int, const char*, const char*, unsigned short, const char*, const List<Tag>&, const List<CallBack>& cb); // Template Regions void createTemplateCmd(const Vector&, const char*); void createTemplateCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame, const char*); void createTemplateVarCmd(const Vector&, const char* var); void getMarkerAnalysisPlot2dCmd(int, char*, char*, char*, char*, Coord::CoordSystem, Coord::SkyFrame, Marker::AnalysisMethod); void getMarkerAnalysisPlot3dCmd(int, char*, char*, Coord::CoordSystem, Marker::AnalysisMethod); void getMarkerAnalysisPandaCmd(int, Coord::CoordSystem); void getMarkerAnalysisRadialCmd(int, char*, char*, char*, Coord::CoordSystem); void getMarkerAnalysisStatsCmd(int, Coord::CoordSystem); void getMarkerAngleCmd(int); void getMarkerAngleCmd(int, Coord::CoordSystem, Coord::SkyFrame); void getMarkerAnnulusRadiusCmd(int, Coord::InternalSystem); void getMarkerAnnulusRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerBoxAnnulusRadiusCmd(int, Coord::InternalSystem); void getMarkerBoxAnnulusRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerBoxRadiusCmd(int, Coord::InternalSystem); void getMarkerBoxRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerBpandaAnglesCmd(int); void getMarkerBpandaAnglesCmd(int, Coord::CoordSystem, Coord::SkyFrame); void getMarkerBpandaRadiusCmd(int, Coord::InternalSystem); void getMarkerBpandaRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerCenterCmd(int, Coord::InternalSystem); void getMarkerCenterCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getMarkerCentroidAutoCmd(); void getMarkerCentroidRadiusCmd(); void getMarkerCentroidIterationCmd(); void getMarkerCentroidOptionCmd(); void getMarkerCircleRadiusCmd(int, Coord::InternalSystem); void getMarkerCircleRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerColorCmd(); void getMarkerColorCmd(const char*); void getMarkerColorCmd(int); void getMarkerCompassArrowCmd(int); void getMarkerCompassLabelCmd(int); void getMarkerCompassRadiusCmd(int, Coord::InternalSystem); void getMarkerCompassRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerCompassSystemCmd(int); void getMarkerCompositeCmd(int); void getMarkerCpandaAnglesCmd(int); void getMarkerCpandaAnglesCmd(int, Coord::CoordSystem, Coord::SkyFrame); void getMarkerCpandaRadiusCmd(int, Coord::InternalSystem); void getMarkerCpandaRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerEllipseRadiusCmd(int, Coord::InternalSystem); void getMarkerEllipseRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerEllipseAnnulusRadiusCmd(int, Coord::InternalSystem); void getMarkerEllipseAnnulusRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerEpandaAnglesCmd(int); void getMarkerEpandaAnglesCmd(int, Coord::CoordSystem, Coord::SkyFrame); void getMarkerEpandaRadiusCmd(int, Coord::InternalSystem); void getMarkerEpandaRadiusCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerFontCmd(); void getMarkerFontCmd(const char*); void getMarkerFontCmd(int); void getMarkerIdCmd(const char*); void getMarkerIdCmd(const Vector&); void getMarkerIdAllCmd(); void getMarkerLineCmd(int, Coord::InternalSystem); void getMarkerLineCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getMarkerLineArrowCmd(int); void getMarkerLineLengthCmd(int, Coord::InternalSystem); void getMarkerLineLengthCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerLineWidthCmd(); void getMarkerLineWidthCmd(int); void getMarkerMapLenFromRefCmd(int, double, Coord::CoordSystem, Coord::SkyDist); void getMarkerNumberCmd(); void getMarkerPointShapeCmd(int); void getMarkerPointSizeCmd(int); void getMarkerPolygonSegmentCmd(const Vector&); void getMarkerPreserveCmd(); void getMarkerProjectionPointsCmd(int, Coord::InternalSystem); void getMarkerProjectionPointsCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getMarkerProjectionLengthCmd(int, Coord::InternalSystem); void getMarkerProjectionLengthCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerProjectionMethodCmd(int); void getMarkerProjectionWidthCmd(int, Coord::InternalSystem); void getMarkerProjectionWidthCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerPropertyCmd(unsigned short); void getMarkerPropertyCmd(const char*, unsigned short); void getMarkerPropertyCmd(int, unsigned short); void getMarkerRulerLengthCmd(int, Coord::InternalSystem); void getMarkerRulerLengthCmd(int, Coord::CoordSystem, Coord::SkyDist); void getMarkerRulerPointCmd(int, Coord::InternalSystem); void getMarkerRulerPointCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getMarkerRulerSystemCmd(int); void getMarkerSelectedCmd(); void getMarkerSelectedCmd(int); void getMarkerSelectedCmd(const Vector&); void getMarkerSelectedNumberCmd(); void getMarkerShowCmd(); void getMarkerShowTextCmd(); void getMarkerHandleCmd(const Vector&); void getMarkerHighlitedCmd(); void getMarkerHighlitedCmd(int); void getMarkerHighlitedCmd(const Vector&); void getMarkerHighlitedNumberCmd(); void getMarkerTagCmd(const char*); void getMarkerTagCmd(int); void getMarkerTagCmd(int,int); void getMarkerTagDefaultNameCmd(); void getMarkerTagNumberCmd(const char*); void getMarkerTagsCmd(); void getMarkerTextCmd(int); void getMarkerTextRotateCmd(int); void getMarkerTypeCmd(int); void getMarkerVectorCmd(int, Coord::InternalSystem); void getMarkerVectorCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void getMarkerVectorArrowCmd(int); void getMarkerVectorLengthCmd(int, Coord::InternalSystem); void getMarkerVectorLengthCmd(int, Coord::CoordSystem, Coord::SkyDist); void hasMarkerHighlitedCmd(); void hasMarkerPasteCmd(); void hasMarkerSelectedCmd(); void hasMarkerUndoCmd(); void markerLayerCmd(MarkerLayer); void markerAnalysisCmd(int, Marker::AnalysisTask, int); void markerAngleCmd(int, double); void markerAngleCmd(int, double, Coord::CoordSystem, Coord::SkyFrame); void markerAnnulusCreateRadiusCmd(int, const Vector&); void markerAnnulusDeleteRadiusCmd(int, int); void markerAnnulusRadiusCmd(int, double, double, int, Coord::InternalSystem); void markerAnnulusRadiusCmd(int, double, double, int, Coord::CoordSystem, Coord::SkyDist); void markerAnnulusRadiusCmd(int, const char*, Coord::CoordSystem, Coord::SkyDist); void markerBackCmd(); void markerBackCmd(const char*); void markerBackCmd(int); void markerBoxAnnulusRadiusCmd(int, const Vector&, const Vector&, int, Coord::InternalSystem); void markerBoxAnnulusRadiusCmd(int, const Vector&, const Vector&, int, Coord::CoordSystem, Coord::SkyDist); void markerBoxAnnulusRadiusCmd(int, const char*, Coord::CoordSystem, Coord::SkyDist); void markerBoxAnnulusCreateRadiusCmd(int, const Vector&); void markerBoxAnnulusDeleteRadiusCmd(int, int); void markerBoxRadiusCmd(int, const Vector&, Coord::InternalSystem); void markerBoxRadiusCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyDist); void markerBpandaCreateAnglesCmd(int, const Vector&); void markerBpandaCreateRadiusCmd(int, const Vector&); void markerBpandaDeleteCmd(int, int); void markerBpandaEditCmd(int, double, double, int, const Vector&, const Vector&, int); void markerBpandaEditCmd(int, double, double, int, const Vector&, const Vector&, int, Coord::CoordSystem, Coord::SkyFrame); void markerBpandaEditCmd(int, const char*, const char*, Coord::CoordSystem, Coord::SkyFrame, Coord::CoordSystem, Coord::SkyDist); void markerCallBackCmd(int, CallBack::Type, const char*, const char*); void markerCentroidCmd(); void markerCentroidCmd(const char*); void markerCentroidCmd(int); void markerCentroidAutoCmd(int); void markerCentroidRadiusCmd(float); void markerCentroidIterationCmd(int); void markerCircleRadiusCmd(int, double, Coord::InternalSystem); void markerCircleRadiusCmd(int, double, Coord::CoordSystem, Coord::SkyDist); void markerColorCmd(const char*); void markerColorCmd(const char*, const char*); void markerColorCmd(int, const char*); void markerCompassArrowCmd(int, int, int); void markerCompassLabelCmd(int, const char*, const char*); void markerCompassRadiusCmd(int, double, Coord::InternalSystem); void markerCompassRadiusCmd(int, double, Coord::CoordSystem, Coord::SkyDist); void markerCompassSystemCmd(int, Coord::CoordSystem, Coord::SkyFrame); void markerCompositeCmd(int, int); void markerCompositeDeleteCmd(); void markerCommandCmd(MarkerFormat, const char*); void markerCommandVarCmd(MarkerFormat, const char*); void markerCopyCmd(); void markerCopyCmd(const char*); void markerCpandaCreateAnglesCmd(int, const Vector&); void markerCpandaCreateRadiusCmd(int, const Vector&); void markerCpandaDeleteCmd(int, int); void markerCpandaEditCmd(int, double, double, int, double, double, int); void markerCpandaEditCmd(int, double, double, int, double, double, int, Coord::CoordSystem, Coord::SkyFrame); void markerCpandaEditCmd(int, const char*, const char*, Coord::CoordSystem, Coord::SkyFrame,Coord::CoordSystem, Coord::SkyDist); void markerCutCmd(); void markerCutCmd(const char*); void markerDeleteCmd(); void markerDeleteCmd(const char*); void markerDeleteCmd(int); void markerDeleteAllCmd(); void markerDeleteLastCmd(); void markerDeleteCallBackCmd(int, CallBack::Type, const char*); void markerDeleteTagCmd(int); void markerDeleteTagCmd(int, const char*); void markerDeleteTagCmd(int, int); void markerEditBeginCmd(int, int); void markerEditBeginCmd(const Vector&, int); void markerEditMotionCmd(const Vector&, int); void markerEditEndCmd(); void markerEllipseRadiusCmd(int, const Vector&, Coord::InternalSystem); void markerEllipseRadiusCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyDist); void markerEllipseAnnulusRadiusCmd(int, const Vector&, const Vector&, int, Coord::InternalSystem); void markerEllipseAnnulusRadiusCmd(int, const Vector&, const Vector&, int, Coord::CoordSystem, Coord::SkyDist); void markerEllipseAnnulusRadiusCmd(int, const char*, Coord::CoordSystem, Coord::SkyDist); void markerEllipseAnnulusCreateRadiusCmd(int, const Vector&); void markerEllipseAnnulusDeleteRadiusCmd(int, int); void markerEpandaCreateAnglesCmd(int, const Vector&); void markerEpandaCreateRadiusCmd(int, const Vector&); void markerEpandaDeleteCmd(int, int); void markerEpandaEditCmd(int, double, double, int, const Vector&, const Vector&, int); void markerEpandaEditCmd(int, double, double, int, const Vector&, const Vector&, int, Coord::CoordSystem, Coord::SkyFrame); void markerEpandaEditCmd(int, const char*, const char*, Coord::CoordSystem, Coord::SkyFrame, Coord::CoordSystem, Coord::SkyDist); void markerFontCmd(const char*); void markerFontCmd(const char*, const char*); void markerFontCmd(int, const char*); void markerFrontCmd(); void markerFrontCmd(const char*); void markerFrontCmd(int); void markerHighliteAllCmd(); // not used void markerHighliteCmd(int); // not used void markerHighliteCmd(const char*); // not used void markerHighliteToggleCmd(const Vector&); void markerHighliteOnlyCmd(int); void markerHighliteOnlyCmd(const char*); // not used void markerHighliteOnlyCmd(const Vector&); // not used void markerKeyCmd(); void markerKeyCmd(const Vector&); void markerLineCmd(int, const Vector&, const Vector&, Coord::InternalSystem); void markerLineCmd(int, const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void markerLineArrowCmd(int, int, int); void markerLineWidthCmd(int); void markerLineWidthCmd(int, int); void markerListCmd(MarkerFormat, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int strip, int select, unsigned short, unsigned short, List<Tag>&); void markerLoadCmd(MarkerFormat,const char*); void markerLoadCmd(MarkerFormat,const char*,Coord::CoordSystem,Coord::SkyFrame); void markerLoadCmd(MarkerFormat,int); void markerLoadCmd(MarkerFormat,int,Coord::CoordSystem,Coord::SkyFrame); void markerLoadFitsCmd(const char*, const char*, int*, int, const char*); void markerMoveCmd(const Vector&); void markerMoveCmd(const char*, const Vector&); void markerMoveCmd(int id, const Vector&); void markerMoveBeginCmd(const Vector&); void markerMoveBeginCmd(int, const Vector&); void markerMoveMotionCmd(const Vector&); void markerMoveMotionCmd(int, const Vector&); void markerMoveEndCmd(); void markerMoveEndCmd(int); void markerMoveToCmd(const Vector&, Coord::InternalSystem); void markerMoveToCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame); void markerMoveToCmd(const char*, const Vector&, Coord::InternalSystem); void markerMoveToCmd(const char*, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void markerMoveToCmd(int, const Vector&, Coord::InternalSystem); void markerMoveToCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void markerPasteCmd(); void markerPasteCmd(Coord::CoordSystem, Coord::CoordSystem); void markerPointShapeCmd(int, Point::PointShape); void markerPointSizeCmd(int, int); void markerPolygonCreateVertexCmd(int, int, const Vector&); void markerPolygonDeleteVertexCmd(int, int); void markerPolygonResetCmd(int, const Vector&, Coord::InternalSystem); void markerPolygonResetCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyDist); void markerPreserveCmd(int r) {preserveMarkers = r;} void markerPropertyCmd(unsigned short, int); void markerPropertyCmd(const char*, unsigned short, int); void markerPropertyCmd(int, unsigned short, int); void markerPropertyCmd(unsigned short, int, const Vector&); void markerProjectionCmd(int, const Vector&, const Vector&, Coord::InternalSystem, double); void markerProjectionCmd(int, const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame, double, Coord::CoordSystem, Coord::SkyDist); void markerRotateBeginCmd(int); void markerRotateBeginCmd(const Vector&); void markerRotateMotionCmd(const Vector&, int h); void markerRotateEndCmd(); void markerRulerPointCmd(int, const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void markerRulerPointCmd(int, const Vector&, const Vector&, Coord::InternalSystem); void markerRulerSystemCmd(int, Coord::CoordSystem, Coord::SkyFrame, Coord::CoordSystem, Coord::SkyDist); void markerSaveCmd(const char*, MarkerFormat, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int strip); void markerSaveTemplateCmd(const char*); void markerSelectAllCmd(); void markerSelectCmd(int); // not used void markerSelectCmd(const char*); void markerSelectToggleCmd(); void markerSelectToggleCmd(const Vector&); void markerSelectOnlyCmd(int); void markerSelectOnlyCmd(const char*); void markerSelectOnlyCmd(const Vector&); void markerShowCmd(int); void markerShowTextCmd(int); void markerTagCmd(const char*); void markerTagCmd(int, const char*); void markerTagEditCmd(const char*, const char*); void markerTagDeleteCmd(const char*); void markerTagDeleteAllCmd(); void markerTagUpdateCmd(const char*); void markerTextCmd(int, const char*); void markerTextRotateCmd(int, int); void markerUndoCmd(); void markerUnhighliteAllCmd(); void markerUnhighliteCmd(int); // not used void markerUnhighliteCmd(const char*); void markerUnselectAllCmd(); void markerUnselectCmd(int); // not used void markerUnselectCmd(const char*); // not used void markerVectorCmd(int, const Vector&, Coord::InternalSystem, double, double); void markerVectorCmd(int, const Vector&, Coord::CoordSystem, Coord::SkyFrame, double, Coord::CoordSystem, Coord::SkyDist, double); void markerVectorArrowCmd(int, int); void regionHighliteBeginCmd(const Vector& v) {regionSelectBeginCmd(v);} void regionHighliteMotionCmd(const Vector& v) {regionSelectMotionCmd(v);} void regionHighliteEndCmd(); void regionHighliteShiftEndCmd(); void regionSelectBeginCmd(const Vector&); void regionSelectMotionCmd(const Vector&); void regionSelectEndCmd(); void regionSelectShiftEndCmd(); // Mask Commands void getMaskColorCmd(); void getMaskMarkCmd(); void getMaskTransparencyCmd(); void maskColorCmd(const char*); void maskClearCmd(); void maskMarkCmd(int m) {maskMark=m;} void maskTransparencyCmd(float); // NaN Commands void getNANColorCmd(); void nanColorCmd(const char*); // Pan Zoom Rotate Orient Commands void centerCmd(); void getOrientCmd(); void getRotateCmd(Precision); void getPanPreserveCmd(); void getZoomCmd(Precision); void orientCmd(Coord::Orientation); virtual void panCmd(const Vector&) =0; virtual void panCmd(const Vector&, const Vector&) =0; virtual void panCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame) =0; virtual void panToCmd(const Vector&) =0; virtual void panToCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame) =0; void panBeginCmd(const Vector&); void panMotionCmd(const Vector&); virtual void panEndCmd(const Vector&) =0; virtual void panBBoxCmd(const Vector&) =0; void panPreserveCmd(int r) {preservePan = r;} void rotateCmd(double); virtual void rotateBeginCmd() {} virtual void rotateMotionCmd(double) {} virtual void rotateEndCmd() {} void rotateToCmd(double); void wcsAlignCmd(int); // used by backup void wcsAlignCmd(int, Coord::CoordSystem, Coord::SkyFrame); void wcsAlignCmd(int, FitsImage*, Coord::CoordSystem, Coord::SkyFrame); void zoomCmd(const Vector&); void zoomToCmd(const Vector&); virtual void zoomAboutCmd(const Vector&, const Vector&) =0; virtual void zoomAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame) =0; virtual void zoomToAboutCmd(const Vector&, const Vector&) =0; virtual void zoomToAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame) =0; virtual void zoomToFitCmd(double) =0; // Panner Commands void pannerCmd(int); void pannerCmd(char*, int, int); void updatePannerCmd(); // backward compatiblity void pannerCmd(Coord::CoordSystem, Coord::SkyFrame) {} // Pixel Table Commands void getPixelTableCmd(const Vector&, Coord::InternalSystem, int, int, char*); // Print Commands #ifdef _MACOSX void macosxPrintCmd(); #endif #ifdef _WIN32 void win32PrintCmd(); #endif // Scale Commands void colorScaleCmd(FrScale::ColorScaleType); void colorScaleLogCmd(double); void getColorMapLevelCmd(int); void getColorMapLevelCmd(int, double, double, FrScale::ColorScaleType, float); void getColorMapLevelCmd(int, const Vector&, Coord::InternalSystem); void getColorScaleCmd(); void getColorScaleLevelCmd(int, double, double, FrScale::ColorScaleType, float); void getColorScaleLogCmd(); // Smooth Commands void getSmoothFunctionCmd(); void getSmoothRadiusCmd(); void hasSmoothCmd(); void smoothCmd(int,int); void smoothDeleteCmd(); // Threads Commands void getThreadsCmd(); void threadsCmd(int); // WCS void wcsAppendCmd(int, int); void wcsAppendCmd(int, const char*); void wcsAppendTxtCmd(int, const char*); void wcsReplaceCmd(int, int); void wcsReplaceCmd(int, const char*); void wcsReplaceTxtCmd(int, const char*); void wcsResetCmd(int); // RGB Commands virtual void getRGBChannelCmd() =0; virtual void getRGBViewCmd() =0; virtual void getRGBSystemCmd() =0; virtual void setRGBChannelCmd(const char*) {} virtual void setRGBViewCmd(int, int, int) {} virtual void setRGBSystemCmd(Coord::CoordSystem) {} // 3d virtual void get3dBorderCmd() =0; virtual void get3dBorderColorCmd() =0; virtual void get3dCompassCmd() =0; virtual void get3dCompassColorCmd() =0; virtual void get3dHighliteCmd() =0; virtual void get3dHighliteColorCmd() =0; virtual void get3dScaleCmd() =0; virtual void get3dViewCmd() =0; virtual void get3dViewPointCmd() =0; virtual void get3dRenderMethodCmd() =0; virtual void set3dBorderCmd(int) {} virtual void set3dBorderColorCmd(const char*) {} virtual void set3dCompassCmd(int) {} virtual void set3dCompassColorCmd(const char*) {} virtual void set3dHighliteCmd(int) {} virtual void set3dHighliteColorCmd(const char*) {} virtual void set3dScaleCmd(double) {} virtual void set3dViewCmd(float, float) {} virtual void set3dViewPointCmd(const Vector3d&, const Vector&) {} virtual void set3dRenderMethodCmd(int) {} }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frscale.h����������������������������������������������������������������������0000644�0001750�0001750�00000007433�11741350537�015123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frscale_h__ #define __frscale_h__ #include <stdlib.h> #include <string.h> class FitsImage; class FrScale { public: enum ColorScaleType {LINEARSCALE, LOGSCALE, POWSCALE, SQRTSCALE, SQUAREDSCALE, ASINHSCALE, SINHSCALE, HISTEQUSCALE, IISSCALE}; enum ClipScope {GLOBAL, LOCAL}; enum ClipMode {MINMAX, ZSCALE, ZMAX, AUTOCUT, USERCLIP}; enum MinMaxMode {AUTOSCAN, SCAN, SAMPLE, DATAMIN, IRAFMIN}; enum ScanMode {IMGSEC, DATASEC, CROPSEC}; private: ColorScaleType colorScaleType_; // color scale type ClipScope clipScope_; // color scale clip scope ClipMode clipMode_; // color scale clip mode MinMaxMode mmMode_; // method to use for determining minmax double low_; // low cut level for all data double high_; // high cut level for all data double min_; // min for all data double max_; // max for all data double uLow_; // low cut via user for all data double uHigh_; // high cut via user for all data float expo_; // log scale exponent float zContrast_; // zscale slope transfer function int zSample_; // zscale optimal sample size int zLine_; // zscale number of lines to sample int mmIncr_; // minmax sampling incr float autoCutPer_; // autoCut percentage ScanMode scanMode_; // use keyword DATASEC int preserve_; // preserve clip double* histequ_; // image histogram equalization xfer function int histequSize_; double* histogramX_; // scale histogram double* histogramY_; // scale histogram int histogramSize_; int datasec_; public: FrScale(); ~FrScale(); FrScale(const FrScale&); FrScale& operator=(const FrScale&); ColorScaleType colorScaleType() {return colorScaleType_;} ClipScope clipScope() {return clipScope_;} ClipMode clipMode() {return clipMode_;} MinMaxMode mmMode() {return mmMode_;} double low() {return low_;} double high() {return high_;} double min() {return min_;} double max() {return max_;} double uLow() {return uLow_;} double uHigh() {return uHigh_;} float expo() {return expo_;} float zContrast() {return zContrast_;} int zSample() {return zSample_;} int zLine() {return zLine_;} int mmIncr() {return mmIncr_;} float autoCutPer() {return autoCutPer_;} ScanMode scanMode() {return scanMode_;} int preserve() {return preserve_;} double* histogramX() {return histogramX_;} double* histogramY() {return histogramY_;} int datasec() {return datasec_;} void setColorScaleType(ColorScaleType v) {colorScaleType_ = v;} void setClipScope(ClipScope v) {clipScope_ = v;} void setClipMode(ClipMode v) {clipMode_ = v;} void setMMMode(MinMaxMode v) {mmMode_ = v;} void setLow(double v) {low_ = v;} void setHigh(double v) {high_ = v;} void setMin(double v) {min_ = v;} void setMax(double v) {max_ = v;} void setULow(double v) {uLow_ = v;} void setUHigh(double v) {uHigh_ = v;} void setExpo(float e) {expo_ = e>10 ? e : 10;} void setZContrast(float v) {zContrast_ = v;} void setZSample(int v) {zSample_ = v;} void setZLine(int v) {zLine_ = v;} void setMMIncr(int v) {mmIncr_ = v;} void setAutoCutPer(float v) {autoCutPer_ = v;} void setPreserve(int p) {preserve_ = p;} void setScanMode(ScanMode v) {scanMode_ = v;} void resetScanMode() {scanMode_ = datasec_ ? DATASEC : IMGSEC;} void setDataSec(int d) {datasec_ = d;} double* histequ(FitsImage*); void clearHistequ(); void histogram(FitsImage*, int); void clearHistogram(); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtrue.h������������������������������������������������������������������0000644�0001750�0001750�00000001201�11700666267�015715� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametrue_h__ #define __frametrue_h__ #include "frame3dbase.h" class Frame3dTrue : public virtual Frame3dBase { protected: int byteorder_; int bitsperpixel_; protected: void encodeTrueColor(int oo, int bb) {byteorder_ = oo; bitsperpixel_ = bb;} virtual void encodeTrueColor(XColor*, char*) =0; virtual void encodeTrueColor(unsigned char*, XImage*) =0; public: Frame3dTrue(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Frame3dTrue(); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ds9lex.C�����������������������������������������������������������������������0000644�0001750�0001750�00000347050�12032637771�014653� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "ds9lex.C" #line 4 "ds9lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer mkFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *mkalloc (yy_size_t ); void *mkrealloc (void *,yy_size_t ); void mkfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 149 #define YY_END_OF_BUFFER 150 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[522] = { 0, 0, 0, 2, 2, 150, 148, 144, 147, 148, 148, 148, 148, 148, 115, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 54, 143, 143, 143, 143, 143, 143, 143, 143, 143, 112, 113, 148, 148, 2, 1, 144, 145, 0, 140, 0, 141, 0, 115, 117, 130, 126, 116, 115, 0, 143, 118, 143, 143, 124, 122, 120, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 55, 143, 57, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 146, 0, 142, 2, 117, 132, 128, 116, 118, 0, 0, 124, 122, 120, 131, 127, 119, 0, 125, 123, 121, 118, 0, 143, 0, 116, 143, 143, 143, 143, 143, 143, 143, 143, 11, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 33, 143, 143, 143, 143, 37, 39, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 49, 143, 143, 56, 143, 143, 60, 143, 143, 143, 143, 143, 143, 143, 143, 143, 72, 143, 143, 143, 143, 143, 143, 143, 143, 83, 143, 114, 133, 129, 0, 116, 0, 0, 117, 0, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 22, 143, 143, 143, 143, 143, 143, 29, 143, 143, 143, 143, 143, 0, 40, 143, 143, 143, 143, 45, 143, 143, 143, 143, 51, 53, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 73, 76, 77, 143, 143, 143, 143, 143, 110, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 143, 0, 0, 0, 134, 0, 143, 0, 143, 143, 143, 143, 143, 7, 8, 143, 10, 143, 143, 143, 143, 17, 143, 143, 143, 21, 143, 24, 143, 143, 143, 143, 143, 143, 143, 34, 35, 36, 0, 143, 143, 143, 143, 143, 48, 143, 50, 143, 58, 143, 143, 62, 143, 143, 143, 143, 143, 68, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 111, 0, 0, 135, 134, 0, 0, 138, 0, 0, 136, 143, 143, 5, 6, 143, 143, 13, 143, 15, 143, 143, 20, 143, 143, 26, 143, 143, 143, 143, 32, 0, 143, 42, 143, 143, 46, 143, 52, 143, 61, 143, 143, 143, 66, 67, 69, 70, 143, 143, 143, 143, 143, 80, 78, 143, 138, 136, 139, 137, 143, 4, 143, 143, 143, 143, 18, 143, 143, 25, 143, 28, 143, 30, 0, 143, 143, 143, 47, 143, 63, 143, 143, 143, 143, 143, 143, 143, 79, 143, 143, 143, 14, 16, 143, 23, 27, 31, 38, 41, 143, 44, 59, 143, 65, 143, 143, 143, 143, 82, 3, 143, 12, 19, 143, 143, 143, 74, 143, 143, 9, 143, 64, 143, 75, 81, 143, 143, 143, 143, 43, 71, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 1, 1, 6, 1, 1, 1, 7, 1, 8, 9, 1, 10, 11, 12, 13, 14, 15, 16, 16, 16, 17, 18, 1, 1, 1, 1, 1, 1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 1, 45, 1, 1, 1, 1, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[74] = { 0, 1, 1, 2, 1, 3, 3, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 1, 1 } ; static yyconst flex_int16_t yy_base[530] = { 0, 0, 0, 159, 153, 152, 4270, 144, 4270, 139, 136, 125, 65, 73, 86, 101, 160, 211, 149, 270, 327, 168, 206, 383, 109, 120, 199, 183, 222, 230, 424, 139, 278, 289, 483, 352, 357, 373, 191, 411, 91, 57, 0, 4270, 126, 4270, 112, 4270, 110, 4270, 452, 542, 601, 4270, 4270, 660, 719, 483, 359, 778, 501, 510, 400, 419, 427, 565, 625, 738, 525, 579, 557, 636, 680, 697, 584, 793, 757, 752, 643, 847, 799, 801, 686, 816, 821, 823, 831, 869, 467, 875, 891, 877, 896, 911, 922, 936, 938, 946, 956, 964, 970, 972, 987, 992, 1008, 1013, 1015, 1031, 1041, 1046, 1051, 1056, 1078, 1085, 1096, 1113, 1127, 1134, 1141, 1149, 1165, 1167, 1172, 1188, 1211, 4270, 38, 4270, 0, 1228, 4270, 4270, 1241, 1211, 1252, 1266, 4270, 4270, 4270, 4270, 4270, 4270, 1277, 4270, 4270, 4270, 4270, 1285, 93, 1294, 1307, 1315, 1329, 1331, 1345, 1339, 1347, 1362, 1369, 1383, 1389, 1406, 1408, 1428, 1433, 1444, 1459, 1464, 1466, 1474, 1493, 1495, 1503, 1520, 1522, 1530, 1544, 1546, 1561, 1563, 1571, 1577, 1591, 1597, 1605, 1613, 1621, 1623, 1637, 1647, 1652, 1663, 1673, 1679, 1690, 1700, 1706, 1716, 1721, 1723, 1737, 1739, 1757, 1763, 1774, 1790, 1796, 1768, 1820, 1827, 1842, 1844, 1850, 1860, 1866, 1877, 1892, 1897, 1952, 1932, 1899, 4270, 4270, 2014, 2027, 2036, 1932, 2049, 2064, 2073, 2086, 2099, 2101, 2106, 2116, 2123, 1915, 2131, 2137, 2145, 2139, 2162, 2168, 2184, 2195, 2201, 2206, 2212, 2226, 2231, 2247, 2253, 2255, 2271, 1913, 2277, 2285, 2291, 2311, 2313, 102, 2318, 2334, 2339, 2341, 2358, 2360, 2366, 2374, 2381, 2398, 2400, 2405, 2416, 2421, 2427, 2432, 2446, 2454, 2460, 2476, 2482, 2484, 2490, 2500, 2507, 2517, 2522, 2528, 2546, 2551, 2556, 2567, 2577, 2583, 2597, 2604, 2611, 2619, 2627, 2629, 2634, 2644, 2649, 2651, 2659, 2665, 2667, 2673, 2675, 2681, 2683, 2689, 2691, 2697, 2699, 2705, 2707, 2713, 2715, 2721, 2723, 2741, 2750, 2758, 2768, 2776, 2785, 2793, 2841, 2808, 2806, 2828, 2822, 2729, 2830, 2856, 2858, 2875, 2877, 2885, 2892, 2903, 2908, 2919, 2930, 2935, 2941, 2946, 2952, 2968, 2960, 2975, 2983, 2991, 3005, 2999, 3021, 3026, 120, 3031, 3036, 3041, 3047, 3052, 3062, 3067, 3072, 3077, 3094, 3099, 3101, 3109, 3116, 3123, 3130, 3137, 3152, 3145, 3163, 3168, 3174, 3179, 3197, 3199, 3204, 3214, 3230, 3235, 3237, 154, 204, 3259, 3267, 3275, 3286, 3299, 3314, 3330, 3301, 3343, 3348, 3350, 3366, 3368, 3374, 3382, 3384, 3398, 3408, 3415, 3425, 3430, 3441, 3435, 3446, 3452, 3457, 3477, 3471, 97, 3498, 3503, 3508, 3513, 3527, 3532, 3548, 3553, 3555, 3570, 3575, 3580, 3585, 3591, 3599, 3601, 3606, 3617, 3625, 3632, 3649, 3642, 3659, 3666, 4270, 4270, 4270, 4270, 3673, 3694, 3696, 3701, 3711, 3721, 3727, 3741, 3743, 3748, 3759, 3766, 3780, 3782, 152, 3798, 3787, 3806, 3821, 3827, 3829, 3843, 3845, 3853, 3859, 3867, 3869, 3886, 3893, 3900, 3916, 3921, 3923, 3937, 3944, 3951, 3959, 3967, 4270, 3973, 3975, 3981, 3983, 3991, 3998, 4008, 4013, 4028, 4034, 4039, 4044, 4055, 4050, 4065, 4073, 4079, 4096, 4103, 4110, 4117, 4136, 4141, 4143, 4157, 4159, 4164, 4175, 4180, 4182, 4199, 4205, 4207, 4270, 4247, 4251, 4255, 4257, 4261, 4265, 90, 89 } ; static yyconst flex_int16_t yy_def[530] = { 0, 521, 1, 522, 522, 521, 521, 521, 521, 521, 523, 524, 521, 521, 525, 525, 525, 16, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 20, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 526, 527, 521, 521, 521, 523, 521, 524, 521, 521, 521, 521, 521, 521, 521, 525, 521, 525, 525, 59, 59, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 526, 521, 527, 52, 521, 521, 55, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 59, 521, 59, 59, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 521, 521, 521, 521, 521, 521, 521, 521, 59, 59, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 521, 521, 521, 521, 59, 521, 59, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 528, 529, 521, 521, 521, 521, 525, 521, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 521, 521, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 0, 521, 521, 521, 521, 521, 521, 521, 521 } ; static yyconst flex_int16_t yy_nxt[4344] = { 0, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14, 14, 6, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 31, 40, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 31, 41, 6, 50, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 54, 391, 390, 55, 56, 56, 56, 56, 56, 56, 56, 56, 57, 463, 521, 521, 59, 60, 521, 127, 61, 62, 521, 521, 49, 47, 521, 521, 63, 98, 64, 125, 229, 521, 521, 521, 44, 521, 127, 49, 65, 66, 359, 59, 60, 67, 521, 61, 62, 47, 45, 99, 521, 521, 44, 63, 521, 64, 125, 229, 521, 420, 521, 521, 43, 521, 521, 65, 66, 359, 43, 395, 67, 521, 521, 521, 78, 521, 99, 68, 79, 521, 521, 487, 80, 521, 521, 69, 420, 521, 521, 70, 521, 521, 521, 90, 521, 521, 521, 445, 521, 71, 72, 78, 521, 521, 91, 79, 521, 521, 487, 80, 521, 521, 69, 521, 521, 521, 70, 521, 521, 398, 90, 521, 101, 521, 445, 521, 71, 72, 58, 521, 521, 91, 100, 521, 521, 92, 73, 521, 521, 93, 58, 521, 521, 521, 74, 521, 521, 446, 521, 101, 75, 76, 521, 77, 521, 521, 521, 521, 521, 100, 103, 102, 92, 73, 521, 521, 93, 58, 104, 521, 521, 74, 521, 521, 446, 521, 521, 75, 76, 521, 77, 521, 521, 521, 521, 521, 521, 103, 102, 521, 521, 521, 521, 521, 521, 104, 521, 81, 82, 521, 521, 521, 521, 521, 521, 521, 83, 521, 84, 521, 85, 521, 521, 521, 521, 521, 521, 110, 112, 521, 521, 521, 521, 111, 81, 82, 521, 521, 113, 521, 521, 521, 521, 83, 114, 84, 521, 85, 521, 521, 521, 521, 521, 521, 110, 112, 521, 521, 521, 521, 111, 521, 86, 521, 521, 113, 521, 521, 521, 521, 87, 114, 88, 521, 521, 521, 89, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 86, 521, 521, 521, 521, 521, 521, 121, 87, 521, 88, 119, 521, 120, 89, 521, 521, 521, 521, 521, 521, 122, 521, 521, 521, 521, 521, 123, 521, 521, 521, 94, 521, 521, 121, 95, 521, 521, 119, 521, 120, 96, 97, 521, 521, 521, 521, 521, 122, 521, 521, 521, 521, 521, 123, 521, 521, 521, 94, 521, 521, 124, 95, 521, 521, 521, 521, 521, 96, 97, 105, 521, 521, 521, 521, 521, 521, 106, 107, 521, 58, 521, 521, 521, 108, 521, 521, 109, 124, 129, 129, 129, 129, 129, 129, 129, 129, 105, 521, 521, 521, 521, 521, 521, 106, 107, 521, 58, 181, 182, 521, 108, 521, 521, 109, 521, 521, 521, 521, 521, 147, 147, 147, 147, 147, 147, 147, 147, 521, 115, 521, 521, 521, 116, 521, 149, 149, 117, 150, 150, 150, 150, 150, 150, 150, 150, 118, 151, 151, 151, 151, 151, 151, 151, 151, 521, 115, 521, 521, 521, 116, 521, 521, 521, 117, 521, 521, 521, 521, 156, 521, 521, 521, 118, 130, 131, 521, 521, 132, 51, 51, 51, 51, 51, 51, 51, 51, 57, 521, 521, 521, 133, 134, 521, 521, 135, 136, 521, 521, 521, 521, 521, 521, 137, 521, 138, 521, 521, 521, 158, 521, 521, 521, 521, 521, 521, 521, 521, 133, 134, 521, 521, 135, 136, 521, 521, 152, 157, 521, 521, 137, 521, 138, 139, 140, 521, 158, 521, 52, 52, 52, 52, 52, 52, 52, 52, 521, 162, 521, 521, 141, 142, 521, 152, 157, 143, 521, 521, 521, 521, 521, 521, 144, 521, 145, 521, 521, 521, 521, 521, 521, 521, 521, 521, 162, 521, 521, 141, 142, 521, 521, 521, 143, 521, 153, 521, 521, 521, 521, 144, 521, 145, 53, 54, 521, 521, 521, 52, 52, 52, 52, 52, 52, 52, 52, 159, 521, 167, 521, 146, 134, 153, 521, 521, 136, 521, 521, 521, 521, 521, 521, 137, 521, 138, 521, 521, 160, 521, 521, 521, 521, 521, 159, 521, 167, 521, 146, 134, 521, 521, 174, 136, 521, 521, 521, 521, 521, 521, 137, 521, 138, 53, 54, 160, 161, 55, 56, 56, 56, 56, 56, 56, 56, 56, 57, 521, 521, 174, 59, 60, 521, 521, 61, 62, 521, 521, 521, 521, 521, 521, 63, 161, 64, 521, 521, 521, 154, 521, 521, 521, 521, 521, 521, 521, 521, 59, 60, 521, 521, 61, 62, 155, 521, 165, 521, 521, 521, 63, 521, 64, 521, 521, 166, 154, 521, 148, 148, 148, 148, 148, 148, 148, 148, 521, 521, 521, 521, 521, 155, 521, 165, 521, 521, 521, 521, 521, 521, 521, 521, 166, 521, 521, 521, 521, 521, 172, 521, 521, 521, 521, 163, 164, 521, 521, 521, 521, 521, 521, 173, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 177, 176, 521, 172, 175, 521, 521, 521, 163, 164, 521, 521, 521, 521, 521, 521, 173, 521, 521, 178, 521, 521, 521, 521, 521, 168, 521, 177, 176, 521, 169, 175, 521, 521, 521, 170, 521, 521, 521, 521, 521, 521, 521, 171, 521, 521, 178, 521, 521, 521, 179, 521, 168, 521, 521, 521, 521, 169, 521, 521, 521, 521, 170, 521, 521, 183, 521, 521, 185, 180, 171, 521, 521, 521, 521, 521, 521, 179, 521, 184, 521, 521, 521, 521, 186, 521, 521, 521, 521, 521, 521, 521, 183, 521, 187, 185, 180, 521, 521, 521, 521, 521, 521, 521, 521, 521, 184, 521, 521, 521, 521, 186, 521, 521, 521, 190, 188, 521, 521, 521, 521, 187, 521, 521, 192, 191, 189, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 190, 188, 521, 521, 521, 521, 521, 521, 521, 521, 191, 189, 521, 521, 521, 521, 521, 521, 194, 521, 521, 521, 521, 193, 521, 521, 521, 521, 195, 521, 521, 521, 196, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 194, 521, 521, 521, 521, 193, 521, 521, 521, 521, 195, 521, 521, 521, 196, 521, 197, 521, 521, 521, 521, 521, 521, 521, 521, 199, 521, 521, 521, 198, 521, 521, 521, 521, 521, 521, 521, 521, 521, 201, 521, 521, 202, 197, 200, 521, 521, 521, 521, 521, 203, 521, 199, 521, 521, 521, 198, 205, 521, 521, 204, 521, 521, 521, 521, 521, 201, 521, 521, 202, 521, 200, 521, 521, 521, 521, 521, 203, 521, 206, 521, 521, 521, 521, 205, 521, 521, 204, 521, 521, 521, 521, 521, 521, 521, 207, 521, 521, 521, 521, 521, 208, 521, 521, 521, 521, 206, 521, 521, 209, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 207, 521, 521, 521, 521, 521, 208, 521, 521, 521, 521, 521, 521, 211, 209, 521, 521, 521, 210, 521, 521, 521, 521, 521, 213, 521, 521, 521, 521, 212, 521, 521, 521, 521, 521, 214, 215, 216, 521, 521, 211, 521, 521, 521, 521, 210, 521, 521, 521, 521, 521, 213, 217, 521, 521, 521, 212, 521, 218, 219, 521, 521, 214, 215, 216, 521, 521, 521, 521, 521, 223, 223, 223, 223, 223, 223, 223, 223, 521, 217, 521, 521, 221, 222, 521, 218, 219, 129, 129, 129, 129, 129, 129, 129, 129, 130, 131, 220, 521, 521, 129, 129, 129, 129, 129, 129, 129, 129, 149, 149, 521, 224, 224, 224, 224, 224, 224, 224, 224, 521, 521, 521, 521, 521, 220, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 521, 227, 227, 227, 227, 227, 227, 227, 227, 147, 147, 147, 147, 147, 147, 147, 147, 228, 224, 224, 224, 224, 224, 224, 224, 224, 130, 131, 521, 521, 521, 150, 150, 150, 150, 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 230, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 231, 521, 521, 236, 521, 521, 521, 521, 521, 521, 521, 232, 521, 235, 230, 521, 521, 233, 521, 521, 521, 521, 521, 234, 521, 521, 521, 231, 521, 521, 521, 521, 237, 521, 521, 521, 521, 238, 232, 521, 235, 521, 521, 521, 233, 239, 521, 521, 521, 521, 234, 521, 521, 521, 521, 521, 521, 521, 521, 237, 521, 521, 240, 521, 238, 521, 521, 521, 521, 521, 242, 521, 239, 521, 521, 521, 521, 241, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 240, 521, 521, 521, 521, 521, 521, 521, 242, 521, 521, 521, 521, 243, 521, 241, 521, 521, 521, 244, 521, 521, 521, 521, 521, 521, 521, 521, 245, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 243, 521, 247, 521, 521, 521, 244, 521, 246, 521, 521, 521, 521, 521, 521, 245, 521, 248, 521, 521, 521, 521, 249, 521, 521, 521, 521, 521, 250, 247, 251, 521, 521, 521, 521, 246, 521, 521, 521, 521, 521, 521, 521, 521, 248, 521, 252, 521, 521, 249, 521, 521, 521, 521, 521, 250, 521, 251, 521, 253, 521, 521, 521, 521, 521, 521, 521, 521, 521, 255, 521, 521, 254, 252, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 253, 521, 521, 521, 256, 521, 521, 521, 521, 521, 255, 260, 521, 254, 521, 521, 521, 521, 521, 258, 259, 521, 521, 521, 257, 521, 521, 521, 521, 521, 521, 256, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 258, 259, 521, 521, 262, 257, 521, 521, 521, 521, 521, 521, 521, 263, 521, 261, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 264, 265, 521, 262, 521, 521, 521, 521, 521, 521, 521, 521, 263, 521, 261, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 266, 264, 265, 268, 521, 521, 267, 521, 521, 270, 521, 521, 521, 521, 521, 521, 521, 521, 521, 269, 521, 521, 521, 521, 521, 521, 521, 266, 521, 521, 268, 521, 521, 267, 521, 521, 521, 521, 521, 271, 521, 521, 521, 521, 521, 521, 269, 521, 521, 272, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 273, 521, 271, 521, 521, 521, 521, 521, 521, 521, 521, 521, 272, 521, 521, 521, 521, 521, 521, 521, 274, 521, 275, 521, 521, 521, 521, 273, 521, 521, 521, 521, 521, 276, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 274, 521, 275, 521, 521, 521, 278, 521, 280, 281, 521, 521, 279, 276, 521, 277, 521, 521, 521, 284, 521, 521, 521, 521, 521, 521, 521, 521, 282, 521, 521, 521, 521, 278, 283, 280, 281, 521, 521, 279, 521, 521, 277, 521, 521, 521, 284, 521, 521, 521, 521, 521, 521, 521, 521, 282, 521, 521, 285, 521, 521, 283, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 287, 521, 521, 285, 521, 521, 288, 521, 521, 521, 521, 521, 521, 286, 521, 521, 521, 521, 521, 521, 289, 521, 290, 521, 521, 521, 521, 287, 521, 291, 521, 521, 521, 288, 521, 521, 521, 521, 521, 521, 286, 521, 521, 521, 521, 521, 521, 289, 521, 290, 521, 521, 521, 521, 521, 521, 291, 521, 335, 521, 521, 521, 521, 292, 521, 521, 521, 293, 521, 521, 521, 521, 521, 521, 521, 227, 227, 227, 227, 227, 227, 227, 227, 521, 521, 521, 521, 521, 521, 521, 292, 521, 521, 521, 293, 294, 58, 58, 58, 58, 58, 58, 58, 321, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 223, 223, 223, 223, 223, 223, 223, 223, 130, 131, 521, 521, 521, 224, 224, 224, 224, 224, 224, 224, 224, 322, 225, 225, 225, 225, 225, 225, 225, 225, 221, 222, 521, 521, 521, 227, 227, 227, 227, 227, 227, 227, 227, 323, 521, 521, 521, 521, 322, 324, 325, 325, 325, 325, 325, 325, 325, 325, 326, 327, 327, 327, 327, 327, 327, 327, 327, 521, 521, 521, 323, 328, 329, 329, 329, 329, 329, 329, 329, 329, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 330, 521, 521, 521, 521, 331, 521, 332, 521, 521, 521, 521, 521, 333, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 330, 521, 521, 336, 521, 331, 521, 332, 339, 521, 521, 334, 521, 333, 521, 521, 337, 521, 521, 338, 521, 521, 521, 521, 521, 521, 521, 521, 521, 340, 336, 521, 521, 521, 521, 339, 521, 521, 334, 521, 521, 521, 521, 337, 521, 341, 338, 521, 521, 521, 521, 521, 521, 521, 521, 521, 340, 521, 521, 521, 521, 343, 521, 521, 521, 521, 521, 342, 521, 521, 345, 521, 341, 521, 521, 344, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 343, 347, 346, 521, 521, 521, 342, 521, 521, 345, 348, 521, 521, 349, 344, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 347, 346, 521, 521, 521, 351, 521, 521, 521, 348, 521, 521, 349, 521, 521, 521, 350, 521, 521, 352, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 351, 521, 521, 521, 353, 521, 355, 521, 521, 521, 354, 350, 521, 356, 352, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 353, 357, 355, 358, 521, 521, 354, 521, 521, 356, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 360, 521, 521, 361, 521, 357, 521, 358, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 362, 521, 521, 521, 521, 521, 521, 521, 360, 521, 521, 361, 521, 521, 363, 521, 521, 521, 521, 521, 521, 521, 521, 365, 521, 521, 521, 362, 364, 521, 521, 521, 521, 521, 367, 521, 521, 521, 521, 521, 521, 363, 521, 521, 521, 368, 366, 521, 521, 521, 365, 521, 521, 521, 521, 364, 521, 521, 521, 521, 521, 369, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 368, 366, 370, 521, 521, 521, 521, 521, 521, 521, 521, 371, 521, 521, 521, 521, 369, 521, 521, 521, 521, 521, 521, 521, 372, 373, 521, 521, 521, 370, 521, 374, 521, 521, 521, 521, 521, 375, 371, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 372, 373, 521, 521, 521, 521, 521, 374, 521, 521, 521, 521, 521, 375, 379, 521, 521, 376, 377, 521, 521, 521, 521, 378, 380, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 382, 521, 379, 521, 521, 376, 377, 381, 521, 521, 521, 378, 380, 521, 521, 521, 521, 383, 521, 521, 521, 521, 521, 521, 521, 521, 521, 382, 521, 521, 521, 521, 521, 521, 381, 384, 521, 521, 521, 521, 521, 521, 521, 521, 383, 385, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 386, 521, 521, 521, 384, 521, 387, 521, 521, 521, 388, 521, 521, 521, 385, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 386, 521, 521, 521, 521, 521, 387, 521, 521, 521, 388, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 389, 326, 390, 390, 390, 390, 390, 390, 390, 390, 328, 391, 391, 391, 391, 391, 391, 391, 391, 392, 392, 392, 392, 392, 392, 392, 392, 389, 393, 325, 325, 325, 325, 325, 325, 325, 325, 394, 394, 394, 394, 394, 394, 394, 394, 395, 327, 327, 327, 327, 327, 327, 327, 327, 397, 397, 397, 397, 397, 397, 397, 397, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 396, 521, 521, 521, 521, 521, 521, 521, 521, 521, 400, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 403, 521, 401, 521, 521, 521, 396, 398, 329, 329, 329, 329, 329, 329, 329, 329, 400, 402, 521, 521, 521, 521, 521, 521, 521, 521, 521, 403, 521, 401, 521, 521, 521, 521, 521, 399, 521, 521, 521, 521, 521, 521, 521, 521, 402, 521, 521, 521, 521, 404, 521, 521, 521, 406, 521, 521, 521, 521, 521, 521, 521, 407, 399, 521, 521, 521, 521, 521, 405, 521, 521, 521, 408, 521, 521, 521, 404, 521, 521, 521, 406, 521, 521, 521, 521, 521, 521, 521, 407, 521, 521, 521, 521, 521, 521, 405, 521, 521, 521, 408, 521, 521, 409, 521, 521, 521, 411, 521, 521, 521, 521, 521, 521, 410, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 412, 521, 521, 521, 409, 521, 521, 413, 411, 521, 521, 521, 521, 521, 521, 410, 521, 521, 521, 521, 521, 521, 521, 414, 521, 521, 521, 412, 521, 521, 415, 521, 521, 521, 413, 521, 521, 521, 521, 416, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 414, 521, 521, 417, 521, 521, 419, 415, 521, 521, 418, 521, 521, 521, 521, 521, 416, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 417, 521, 521, 419, 521, 521, 521, 418, 521, 521, 521, 521, 521, 521, 521, 521, 423, 521, 422, 521, 521, 421, 521, 521, 521, 521, 424, 425, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 426, 521, 423, 521, 422, 521, 521, 421, 521, 521, 521, 521, 424, 425, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 427, 521, 521, 426, 521, 521, 521, 428, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 429, 521, 427, 521, 521, 521, 431, 521, 521, 428, 521, 430, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 433, 521, 521, 521, 521, 429, 432, 521, 521, 521, 521, 431, 521, 521, 521, 521, 430, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 433, 521, 521, 521, 436, 521, 432, 434, 521, 521, 521, 521, 437, 521, 435, 521, 521, 521, 521, 521, 521, 521, 521, 521, 438, 521, 521, 521, 521, 521, 521, 436, 521, 521, 434, 521, 521, 521, 440, 437, 441, 435, 521, 439, 521, 521, 521, 521, 521, 521, 442, 438, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 440, 521, 441, 521, 521, 439, 521, 521, 521, 521, 521, 521, 442, 521, 443, 521, 444, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 394, 394, 394, 394, 394, 394, 394, 394, 443, 521, 444, 394, 394, 394, 394, 394, 394, 394, 394, 521, 521, 521, 521, 521, 521, 521, 521, 447, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 445, 397, 397, 397, 397, 397, 397, 397, 397, 521, 521, 521, 521, 521, 521, 521, 447, 397, 397, 397, 397, 397, 397, 397, 397, 521, 521, 445, 448, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 446, 521, 521, 449, 521, 521, 521, 521, 521, 521, 521, 448, 521, 521, 521, 521, 521, 521, 450, 521, 521, 521, 521, 521, 521, 521, 521, 446, 452, 521, 449, 521, 521, 521, 451, 521, 521, 521, 453, 521, 521, 521, 521, 521, 454, 450, 521, 521, 521, 521, 521, 521, 521, 521, 521, 452, 521, 521, 521, 521, 521, 451, 521, 521, 521, 453, 521, 521, 521, 521, 521, 521, 521, 521, 521, 456, 521, 521, 455, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 457, 521, 456, 521, 521, 455, 521, 460, 521, 521, 521, 458, 459, 521, 521, 521, 521, 461, 521, 521, 521, 521, 521, 521, 521, 521, 521, 457, 521, 521, 521, 521, 521, 462, 460, 521, 521, 521, 458, 459, 521, 521, 521, 521, 461, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 464, 521, 462, 521, 465, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 466, 464, 521, 521, 467, 465, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 468, 521, 521, 521, 521, 521, 466, 521, 521, 521, 467, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 468, 521, 521, 469, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 470, 521, 521, 521, 521, 471, 521, 521, 521, 521, 521, 521, 472, 521, 521, 521, 469, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 470, 521, 473, 521, 521, 471, 521, 521, 521, 521, 521, 521, 472, 521, 521, 521, 521, 521, 521, 521, 521, 521, 475, 474, 521, 521, 521, 521, 521, 473, 476, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 475, 474, 521, 521, 521, 521, 521, 478, 476, 477, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 478, 521, 477, 521, 521, 521, 521, 521, 480, 521, 521, 521, 479, 521, 521, 521, 521, 481, 521, 521, 482, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 480, 521, 521, 521, 479, 521, 521, 521, 521, 481, 521, 521, 482, 521, 521, 521, 521, 521, 521, 521, 521, 483, 521, 484, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 485, 521, 521, 521, 521, 521, 486, 521, 521, 521, 521, 483, 521, 484, 521, 521, 521, 521, 521, 521, 521, 521, 489, 521, 488, 521, 521, 485, 521, 521, 521, 521, 521, 486, 490, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 489, 521, 488, 521, 521, 521, 521, 521, 521, 521, 521, 521, 490, 491, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 492, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 494, 491, 521, 496, 521, 493, 495, 521, 521, 521, 521, 521, 521, 497, 492, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 494, 521, 521, 496, 521, 493, 495, 521, 521, 521, 521, 521, 521, 497, 498, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 499, 521, 521, 521, 521, 521, 521, 521, 501, 521, 521, 521, 500, 521, 521, 498, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 499, 521, 521, 521, 502, 521, 521, 521, 501, 521, 521, 521, 500, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 502, 521, 521, 521, 521, 521, 521, 521, 503, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 504, 521, 521, 505, 521, 503, 521, 521, 521, 521, 521, 521, 506, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 504, 521, 521, 505, 521, 521, 521, 521, 521, 521, 521, 521, 506, 521, 521, 507, 521, 521, 521, 521, 521, 508, 521, 521, 521, 521, 509, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 507, 521, 521, 521, 521, 521, 508, 521, 521, 521, 521, 509, 521, 521, 510, 521, 521, 521, 511, 521, 521, 521, 521, 521, 512, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 513, 510, 521, 521, 521, 511, 521, 514, 521, 521, 521, 512, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 513, 521, 521, 521, 521, 521, 521, 514, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 515, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 516, 521, 521, 521, 521, 521, 521, 517, 519, 521, 521, 515, 518, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 520, 521, 516, 521, 521, 521, 521, 521, 521, 517, 519, 521, 521, 521, 518, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 520, 42, 42, 42, 42, 46, 521, 46, 46, 48, 521, 48, 48, 58, 58, 126, 521, 126, 126, 128, 521, 128, 128, 5, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521 } ; static yyconst flex_int16_t yy_chk[4344] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 529, 528, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 420, 15, 15, 14, 14, 15, 126, 14, 14, 24, 24, 48, 46, 24, 15, 14, 24, 14, 40, 148, 25, 25, 24, 44, 25, 41, 11, 15, 15, 260, 14, 14, 15, 25, 14, 14, 10, 9, 25, 31, 31, 7, 14, 31, 14, 40, 148, 5, 359, 18, 18, 4, 31, 18, 15, 15, 260, 3, 390, 15, 16, 16, 18, 18, 16, 25, 16, 18, 21, 21, 463, 18, 21, 16, 16, 359, 0, 0, 16, 0, 0, 21, 21, 27, 27, 0, 390, 27, 16, 16, 18, 38, 38, 21, 18, 38, 27, 463, 18, 26, 26, 16, 0, 26, 38, 16, 22, 22, 391, 21, 22, 27, 26, 390, 0, 16, 16, 17, 0, 22, 21, 26, 28, 28, 22, 17, 28, 0, 22, 17, 29, 29, 0, 17, 29, 28, 391, 0, 27, 17, 17, 0, 17, 29, 0, 0, 0, 0, 26, 29, 28, 22, 17, 0, 0, 22, 17, 29, 0, 0, 17, 0, 0, 391, 0, 0, 17, 17, 0, 17, 19, 19, 0, 0, 19, 0, 29, 28, 32, 32, 0, 0, 32, 19, 29, 0, 19, 19, 0, 33, 33, 32, 0, 33, 0, 19, 0, 19, 0, 19, 0, 0, 33, 0, 0, 0, 32, 33, 0, 0, 0, 0, 32, 19, 19, 0, 0, 33, 0, 0, 0, 0, 19, 33, 19, 0, 19, 20, 20, 0, 0, 20, 0, 32, 33, 0, 0, 0, 0, 32, 20, 20, 0, 0, 33, 0, 0, 0, 0, 20, 33, 20, 35, 35, 0, 20, 35, 36, 36, 58, 58, 36, 0, 58, 0, 35, 0, 0, 20, 0, 36, 0, 58, 37, 37, 36, 20, 37, 20, 35, 0, 35, 20, 23, 23, 0, 37, 23, 0, 37, 0, 0, 0, 0, 0, 37, 23, 0, 0, 23, 62, 62, 36, 23, 62, 0, 35, 0, 35, 23, 23, 39, 39, 62, 0, 39, 37, 0, 0, 63, 63, 0, 37, 63, 39, 0, 23, 64, 64, 39, 23, 64, 63, 0, 0, 0, 23, 23, 30, 0, 64, 0, 0, 0, 0, 30, 30, 0, 30, 0, 0, 0, 30, 0, 0, 30, 39, 50, 50, 50, 50, 50, 50, 50, 50, 30, 0, 88, 88, 0, 0, 88, 30, 30, 0, 30, 88, 88, 0, 30, 88, 0, 30, 34, 34, 0, 0, 34, 57, 57, 57, 57, 57, 57, 57, 57, 34, 34, 0, 0, 0, 34, 0, 60, 60, 34, 60, 60, 60, 60, 60, 60, 60, 60, 34, 61, 61, 61, 61, 61, 61, 61, 61, 0, 34, 68, 68, 0, 34, 68, 0, 0, 34, 0, 0, 0, 0, 68, 68, 0, 0, 34, 51, 51, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 70, 70, 51, 51, 70, 0, 51, 51, 65, 65, 0, 0, 65, 70, 51, 0, 51, 0, 0, 0, 70, 65, 69, 69, 0, 0, 69, 74, 74, 51, 51, 74, 0, 51, 51, 69, 0, 65, 69, 0, 74, 51, 0, 51, 52, 52, 0, 70, 0, 52, 52, 52, 52, 52, 52, 52, 52, 0, 74, 0, 0, 52, 52, 0, 65, 69, 52, 0, 66, 66, 0, 0, 66, 52, 0, 52, 0, 0, 0, 71, 71, 66, 0, 71, 0, 74, 78, 78, 52, 52, 78, 0, 71, 52, 0, 66, 0, 0, 0, 78, 52, 0, 52, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 71, 0, 78, 0, 55, 55, 66, 72, 72, 55, 0, 72, 0, 82, 82, 0, 55, 82, 55, 0, 72, 72, 0, 0, 73, 73, 82, 71, 73, 78, 0, 55, 55, 0, 0, 82, 55, 73, 0, 0, 0, 0, 0, 55, 0, 55, 56, 56, 72, 73, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 0, 0, 82, 56, 56, 67, 67, 56, 56, 67, 0, 0, 0, 0, 0, 56, 73, 56, 67, 77, 77, 67, 0, 77, 76, 76, 0, 0, 76, 0, 56, 56, 77, 0, 56, 56, 67, 76, 76, 0, 0, 0, 56, 0, 56, 59, 59, 77, 67, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 75, 75, 0, 67, 75, 76, 80, 80, 81, 81, 80, 0, 81, 75, 77, 0, 0, 0, 0, 80, 80, 81, 0, 83, 83, 75, 75, 83, 84, 84, 85, 85, 84, 81, 85, 0, 83, 0, 86, 86, 0, 84, 86, 85, 85, 84, 0, 80, 83, 0, 0, 86, 75, 75, 79, 79, 0, 0, 79, 0, 81, 0, 0, 86, 0, 0, 0, 79, 0, 79, 0, 85, 84, 0, 79, 83, 87, 87, 0, 79, 87, 0, 89, 89, 91, 91, 89, 79, 91, 87, 86, 0, 0, 0, 87, 89, 79, 91, 90, 90, 0, 79, 90, 92, 92, 0, 79, 92, 0, 89, 0, 90, 91, 87, 79, 0, 92, 0, 93, 93, 0, 87, 93, 90, 0, 0, 0, 0, 92, 94, 94, 93, 0, 94, 0, 0, 89, 0, 93, 91, 87, 0, 94, 95, 95, 96, 96, 95, 0, 96, 90, 0, 0, 97, 97, 92, 95, 97, 96, 96, 94, 0, 0, 98, 98, 93, 97, 98, 98, 97, 95, 99, 99, 0, 0, 99, 98, 100, 100, 101, 101, 100, 0, 101, 99, 0, 96, 94, 0, 0, 100, 0, 101, 0, 102, 102, 97, 95, 102, 103, 103, 0, 0, 103, 100, 0, 0, 102, 0, 99, 0, 0, 103, 0, 101, 104, 104, 0, 103, 104, 105, 105, 106, 106, 105, 0, 106, 0, 104, 0, 0, 100, 0, 105, 0, 106, 99, 0, 107, 107, 0, 101, 107, 0, 0, 103, 0, 105, 108, 108, 0, 107, 108, 109, 109, 0, 107, 109, 110, 110, 106, 108, 110, 111, 111, 0, 109, 111, 0, 0, 108, 110, 0, 108, 105, 107, 111, 0, 0, 0, 0, 109, 0, 107, 0, 112, 112, 106, 111, 112, 0, 110, 113, 113, 0, 0, 113, 108, 112, 0, 108, 0, 107, 114, 114, 113, 0, 114, 109, 0, 112, 0, 0, 0, 0, 111, 114, 0, 110, 0, 115, 115, 0, 0, 115, 0, 113, 0, 0, 0, 0, 0, 114, 115, 116, 116, 0, 112, 116, 0, 115, 117, 117, 0, 0, 117, 0, 116, 118, 118, 0, 0, 118, 113, 117, 0, 119, 119, 0, 114, 119, 118, 0, 0, 0, 0, 117, 115, 0, 119, 0, 116, 120, 120, 121, 121, 120, 119, 121, 122, 122, 0, 118, 122, 0, 120, 0, 121, 119, 120, 121, 0, 122, 117, 0, 123, 123, 0, 116, 123, 0, 0, 0, 0, 119, 121, 0, 0, 123, 118, 0, 122, 123, 0, 0, 119, 120, 121, 124, 124, 0, 0, 124, 133, 133, 133, 133, 133, 133, 133, 133, 124, 121, 0, 0, 129, 129, 0, 122, 123, 129, 129, 129, 129, 129, 129, 129, 129, 132, 132, 124, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 134, 134, 0, 134, 134, 134, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 124, 135, 135, 135, 135, 135, 135, 135, 135, 142, 142, 0, 142, 142, 142, 142, 142, 142, 142, 142, 147, 147, 147, 147, 147, 147, 147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 0, 152, 152, 153, 153, 152, 0, 153, 0, 0, 0, 155, 155, 151, 152, 155, 153, 154, 154, 156, 156, 154, 0, 156, 155, 0, 152, 0, 0, 156, 154, 0, 156, 0, 157, 157, 0, 153, 157, 155, 151, 158, 158, 154, 0, 158, 0, 157, 0, 154, 0, 0, 0, 152, 158, 159, 159, 0, 157, 159, 0, 160, 160, 158, 153, 160, 155, 0, 159, 0, 154, 159, 0, 0, 160, 0, 154, 0, 161, 161, 162, 162, 161, 0, 162, 157, 0, 0, 160, 0, 158, 161, 0, 162, 0, 0, 162, 0, 159, 0, 163, 163, 0, 161, 163, 164, 164, 0, 0, 164, 0, 0, 0, 163, 0, 160, 165, 165, 164, 0, 165, 0, 0, 162, 0, 0, 0, 0, 163, 165, 161, 166, 166, 0, 164, 166, 167, 167, 168, 168, 167, 0, 168, 165, 166, 0, 169, 169, 0, 167, 169, 168, 0, 0, 0, 163, 0, 167, 0, 169, 0, 164, 0, 166, 0, 170, 170, 171, 171, 170, 165, 171, 168, 0, 0, 172, 172, 169, 170, 172, 171, 0, 0, 170, 167, 171, 0, 0, 172, 0, 166, 0, 173, 173, 174, 174, 173, 0, 174, 168, 0, 172, 175, 175, 169, 173, 175, 174, 0, 0, 170, 0, 171, 0, 173, 175, 176, 176, 177, 177, 176, 0, 177, 0, 175, 0, 0, 174, 172, 176, 0, 177, 0, 178, 178, 179, 179, 178, 0, 179, 0, 173, 0, 180, 180, 177, 178, 180, 179, 181, 181, 175, 181, 181, 174, 0, 180, 0, 0, 0, 179, 180, 181, 182, 182, 178, 0, 182, 0, 183, 183, 0, 177, 183, 0, 0, 182, 184, 184, 0, 0, 184, 183, 0, 0, 185, 185, 179, 180, 185, 184, 184, 178, 186, 186, 187, 187, 186, 185, 187, 185, 0, 183, 0, 0, 0, 186, 0, 187, 188, 188, 0, 0, 188, 0, 186, 187, 0, 184, 189, 189, 0, 188, 189, 190, 190, 0, 185, 190, 183, 0, 0, 189, 0, 0, 191, 191, 190, 0, 191, 0, 188, 186, 187, 190, 192, 192, 189, 191, 192, 192, 193, 193, 0, 0, 193, 0, 0, 192, 0, 191, 0, 194, 194, 193, 0, 194, 0, 188, 0, 0, 190, 195, 195, 189, 194, 195, 0, 196, 196, 194, 0, 196, 0, 0, 195, 0, 191, 197, 197, 195, 196, 197, 198, 198, 199, 199, 198, 0, 199, 0, 197, 0, 0, 0, 197, 198, 194, 199, 200, 200, 201, 201, 200, 0, 201, 0, 195, 0, 0, 0, 0, 200, 0, 201, 198, 0, 200, 0, 202, 202, 0, 197, 202, 0, 203, 203, 0, 201, 203, 207, 207, 202, 0, 207, 0, 204, 204, 203, 0, 204, 0, 198, 207, 200, 0, 0, 0, 203, 204, 204, 204, 205, 205, 203, 201, 205, 202, 206, 206, 0, 207, 206, 0, 0, 205, 0, 0, 0, 0, 205, 206, 0, 0, 0, 203, 206, 204, 204, 0, 0, 203, 208, 208, 202, 0, 208, 0, 207, 209, 209, 0, 0, 209, 0, 208, 0, 205, 0, 0, 208, 0, 209, 206, 210, 210, 211, 211, 210, 0, 211, 0, 212, 212, 0, 0, 212, 210, 0, 211, 0, 0, 213, 213, 211, 212, 213, 208, 214, 214, 212, 0, 214, 0, 0, 213, 0, 210, 0, 215, 215, 214, 0, 215, 213, 0, 214, 0, 0, 0, 0, 211, 215, 215, 216, 216, 0, 212, 216, 217, 217, 220, 220, 217, 210, 220, 0, 216, 0, 0, 0, 213, 217, 214, 220, 254, 254, 236, 236, 254, 215, 236, 236, 0, 0, 0, 0, 216, 254, 0, 236, 217, 0, 0, 219, 219, 0, 0, 219, 226, 226, 226, 226, 226, 226, 226, 226, 219, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 217, 218, 218, 218, 218, 218, 218, 218, 218, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 0, 0, 0, 224, 224, 224, 224, 224, 224, 224, 224, 223, 225, 225, 225, 225, 225, 225, 225, 225, 227, 227, 0, 0, 0, 227, 227, 227, 227, 227, 227, 227, 227, 225, 0, 0, 0, 0, 223, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 0, 0, 0, 225, 230, 230, 230, 230, 230, 230, 230, 230, 230, 231, 231, 232, 232, 231, 0, 232, 233, 233, 0, 0, 233, 0, 231, 0, 232, 0, 234, 234, 0, 233, 234, 231, 0, 235, 235, 0, 232, 235, 233, 234, 0, 237, 237, 0, 234, 237, 235, 238, 238, 240, 240, 238, 0, 240, 237, 239, 239, 0, 231, 239, 238, 237, 240, 232, 0, 233, 240, 0, 239, 235, 0, 234, 241, 241, 238, 0, 241, 239, 242, 242, 0, 0, 242, 0, 0, 241, 0, 241, 237, 0, 0, 242, 0, 240, 243, 243, 235, 0, 243, 0, 0, 238, 0, 242, 239, 244, 244, 243, 0, 244, 0, 245, 245, 0, 241, 245, 246, 246, 244, 244, 246, 0, 247, 247, 245, 243, 247, 0, 245, 246, 242, 0, 0, 244, 0, 247, 248, 248, 0, 0, 248, 249, 249, 0, 0, 249, 244, 247, 246, 248, 0, 0, 243, 0, 249, 245, 248, 250, 250, 249, 244, 250, 0, 251, 251, 252, 252, 251, 0, 252, 250, 0, 0, 0, 247, 246, 251, 0, 252, 251, 0, 253, 253, 248, 0, 253, 249, 255, 255, 0, 250, 255, 0, 252, 253, 256, 256, 0, 0, 256, 255, 257, 257, 0, 0, 257, 251, 0, 256, 0, 253, 0, 256, 0, 257, 0, 255, 250, 0, 257, 252, 258, 258, 259, 259, 258, 0, 259, 261, 261, 0, 0, 261, 0, 258, 0, 259, 253, 258, 256, 259, 261, 0, 255, 262, 262, 257, 0, 262, 263, 263, 264, 264, 263, 0, 264, 0, 262, 0, 0, 262, 0, 263, 263, 264, 258, 0, 259, 265, 265, 266, 266, 265, 0, 266, 0, 267, 267, 0, 264, 267, 265, 0, 266, 268, 268, 0, 262, 268, 267, 263, 269, 269, 265, 0, 269, 0, 268, 0, 0, 0, 0, 268, 0, 269, 0, 264, 267, 270, 270, 271, 271, 270, 270, 271, 272, 272, 0, 0, 272, 265, 270, 0, 271, 271, 269, 273, 273, 272, 268, 273, 274, 274, 0, 267, 274, 0, 275, 275, 273, 273, 275, 276, 276, 274, 0, 276, 0, 0, 0, 275, 271, 269, 274, 0, 276, 277, 277, 0, 0, 277, 0, 275, 0, 278, 278, 0, 273, 278, 277, 279, 279, 0, 0, 279, 276, 277, 278, 0, 0, 274, 0, 278, 279, 0, 0, 280, 280, 279, 275, 280, 0, 281, 281, 282, 282, 281, 0, 282, 280, 283, 283, 276, 277, 283, 281, 0, 282, 0, 278, 284, 284, 0, 283, 284, 279, 283, 285, 285, 280, 281, 285, 0, 284, 0, 282, 284, 286, 286, 0, 285, 286, 287, 287, 0, 0, 287, 0, 288, 288, 286, 286, 288, 283, 0, 287, 280, 281, 285, 0, 0, 288, 282, 284, 0, 0, 289, 289, 286, 0, 289, 290, 290, 0, 0, 290, 291, 291, 286, 289, 291, 0, 0, 0, 290, 285, 289, 292, 292, 291, 0, 292, 0, 0, 0, 286, 290, 293, 293, 0, 292, 293, 0, 294, 294, 0, 0, 294, 0, 291, 293, 0, 0, 289, 0, 292, 294, 295, 295, 293, 0, 295, 0, 290, 296, 296, 0, 0, 296, 0, 295, 297, 297, 0, 0, 297, 291, 296, 0, 298, 298, 0, 292, 298, 297, 0, 293, 299, 299, 300, 300, 299, 298, 300, 301, 301, 0, 0, 301, 0, 299, 0, 300, 0, 302, 302, 0, 301, 302, 303, 303, 304, 304, 303, 0, 304, 0, 302, 0, 305, 305, 0, 303, 305, 304, 306, 306, 307, 307, 306, 0, 307, 305, 308, 308, 309, 309, 308, 306, 309, 307, 310, 310, 311, 311, 310, 308, 311, 309, 312, 312, 313, 313, 312, 310, 313, 311, 314, 314, 315, 315, 314, 312, 315, 313, 316, 316, 317, 317, 316, 314, 317, 315, 318, 318, 319, 319, 318, 316, 319, 317, 320, 320, 321, 321, 320, 318, 321, 319, 334, 334, 0, 0, 334, 320, 0, 321, 0, 0, 0, 0, 0, 334, 0, 321, 322, 322, 322, 322, 322, 322, 322, 322, 322, 323, 323, 323, 323, 323, 323, 323, 323, 323, 324, 324, 324, 324, 324, 324, 324, 324, 321, 325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 326, 326, 326, 326, 326, 326, 326, 327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 328, 328, 328, 328, 328, 328, 328, 331, 331, 330, 330, 331, 0, 330, 0, 0, 0, 0, 327, 0, 331, 0, 330, 333, 333, 0, 0, 333, 330, 332, 332, 335, 335, 332, 0, 335, 333, 0, 0, 333, 0, 331, 332, 0, 335, 327, 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, 332, 336, 336, 337, 337, 336, 0, 337, 0, 0, 333, 0, 331, 0, 336, 0, 337, 0, 329, 0, 338, 338, 339, 339, 338, 0, 339, 332, 0, 0, 340, 340, 336, 338, 340, 339, 339, 341, 341, 0, 0, 341, 0, 340, 340, 329, 0, 0, 342, 342, 341, 338, 342, 343, 343, 341, 0, 343, 0, 336, 0, 342, 0, 339, 344, 344, 343, 0, 344, 0, 0, 340, 0, 0, 0, 345, 345, 344, 338, 345, 346, 346, 341, 0, 346, 343, 347, 347, 345, 345, 347, 348, 348, 346, 0, 348, 344, 349, 349, 347, 0, 349, 0, 0, 348, 351, 351, 0, 347, 351, 349, 0, 343, 350, 350, 349, 345, 350, 351, 0, 352, 352, 0, 344, 352, 0, 350, 0, 353, 353, 0, 350, 353, 352, 0, 347, 354, 354, 351, 0, 354, 353, 349, 0, 356, 356, 0, 352, 356, 354, 355, 355, 0, 0, 355, 0, 0, 356, 350, 0, 0, 353, 0, 355, 355, 351, 357, 357, 354, 0, 357, 358, 358, 0, 352, 358, 360, 360, 0, 357, 360, 361, 361, 0, 358, 361, 362, 362, 353, 360, 362, 355, 363, 363, 361, 354, 363, 364, 364, 362, 0, 364, 0, 0, 362, 363, 361, 365, 365, 360, 364, 365, 366, 366, 363, 364, 366, 367, 367, 0, 365, 367, 368, 368, 0, 366, 368, 0, 0, 366, 367, 362, 0, 361, 0, 368, 360, 0, 0, 369, 369, 363, 364, 369, 370, 370, 371, 371, 370, 0, 371, 0, 369, 368, 372, 372, 366, 370, 372, 371, 370, 373, 373, 0, 0, 373, 0, 372, 374, 374, 0, 0, 374, 0, 373, 375, 375, 0, 371, 375, 368, 374, 376, 376, 374, 0, 376, 370, 375, 373, 378, 378, 0, 0, 378, 376, 0, 377, 377, 0, 376, 377, 0, 378, 0, 371, 375, 0, 379, 379, 377, 374, 379, 380, 380, 0, 373, 380, 0, 381, 381, 379, 0, 381, 382, 382, 380, 376, 382, 0, 0, 380, 381, 375, 377, 0, 0, 382, 0, 381, 0, 379, 383, 383, 384, 384, 383, 0, 384, 385, 385, 382, 0, 385, 0, 383, 0, 384, 380, 386, 386, 377, 385, 386, 0, 384, 381, 385, 379, 0, 383, 0, 386, 0, 0, 387, 387, 386, 382, 387, 388, 388, 389, 389, 388, 0, 389, 0, 387, 0, 0, 0, 384, 388, 385, 389, 0, 383, 0, 0, 0, 0, 0, 0, 386, 0, 387, 0, 388, 392, 392, 392, 392, 392, 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, 393, 394, 394, 394, 394, 394, 394, 394, 394, 387, 0, 388, 395, 395, 395, 395, 395, 395, 395, 395, 396, 396, 399, 399, 396, 0, 399, 0, 394, 0, 0, 0, 0, 396, 0, 399, 0, 0, 0, 395, 397, 397, 397, 397, 397, 397, 397, 397, 0, 0, 0, 0, 0, 0, 0, 394, 398, 398, 398, 398, 398, 398, 398, 398, 400, 400, 395, 397, 400, 401, 401, 402, 402, 401, 0, 402, 0, 400, 0, 0, 0, 0, 401, 398, 402, 0, 400, 403, 403, 404, 404, 403, 0, 404, 397, 405, 405, 0, 0, 405, 403, 401, 404, 406, 406, 407, 407, 406, 405, 407, 398, 405, 0, 400, 0, 0, 406, 404, 407, 408, 408, 407, 0, 408, 0, 0, 0, 408, 401, 409, 409, 0, 408, 409, 0, 0, 410, 410, 405, 0, 410, 0, 409, 0, 404, 0, 411, 411, 407, 410, 411, 412, 412, 0, 0, 412, 414, 414, 410, 411, 414, 409, 413, 413, 412, 0, 413, 415, 415, 414, 0, 415, 0, 416, 416, 413, 0, 416, 417, 417, 415, 0, 417, 412, 0, 410, 416, 0, 409, 0, 416, 417, 419, 419, 413, 415, 419, 0, 418, 418, 417, 0, 418, 0, 0, 419, 0, 0, 0, 0, 412, 418, 0, 0, 0, 0, 418, 416, 0, 421, 421, 413, 415, 421, 422, 422, 0, 417, 422, 423, 423, 0, 421, 423, 424, 424, 0, 422, 424, 0, 0, 421, 423, 418, 0, 423, 0, 424, 425, 425, 0, 0, 425, 426, 426, 0, 0, 426, 0, 0, 0, 425, 0, 0, 0, 0, 426, 424, 421, 427, 427, 426, 423, 427, 428, 428, 429, 429, 428, 0, 429, 0, 427, 0, 0, 0, 0, 428, 428, 429, 0, 430, 430, 0, 424, 430, 431, 431, 426, 0, 431, 432, 432, 0, 430, 432, 433, 433, 0, 431, 433, 0, 434, 434, 432, 428, 434, 0, 430, 433, 435, 435, 436, 436, 435, 434, 436, 437, 437, 431, 0, 437, 0, 435, 432, 436, 0, 0, 438, 438, 437, 437, 438, 0, 0, 430, 439, 439, 0, 0, 439, 438, 0, 440, 440, 0, 431, 440, 438, 439, 0, 432, 0, 442, 442, 0, 440, 442, 437, 0, 441, 441, 0, 0, 441, 0, 442, 0, 440, 439, 443, 443, 0, 441, 443, 438, 441, 444, 444, 0, 0, 444, 0, 443, 449, 449, 0, 0, 449, 0, 444, 0, 0, 0, 0, 440, 439, 449, 0, 0, 0, 0, 449, 441, 444, 450, 450, 451, 451, 450, 0, 451, 452, 452, 0, 0, 452, 0, 450, 0, 451, 0, 453, 453, 0, 452, 453, 0, 0, 449, 0, 444, 454, 454, 0, 453, 454, 452, 455, 455, 0, 451, 455, 0, 0, 454, 453, 0, 0, 454, 0, 455, 456, 456, 457, 457, 456, 0, 457, 458, 458, 0, 0, 458, 452, 456, 0, 457, 451, 0, 459, 459, 458, 453, 459, 0, 454, 460, 460, 0, 0, 460, 0, 459, 0, 456, 0, 457, 0, 0, 460, 461, 461, 462, 462, 461, 0, 462, 465, 465, 0, 459, 465, 0, 461, 0, 462, 461, 0, 464, 464, 465, 456, 464, 457, 0, 0, 466, 466, 0, 0, 466, 464, 465, 0, 464, 0, 0, 459, 0, 466, 0, 467, 467, 461, 466, 467, 0, 468, 468, 469, 469, 468, 0, 469, 467, 0, 0, 0, 0, 465, 468, 464, 469, 470, 470, 471, 471, 470, 0, 471, 0, 466, 468, 472, 472, 0, 470, 472, 471, 473, 473, 0, 0, 473, 0, 470, 472, 474, 474, 475, 475, 474, 473, 475, 0, 0, 0, 0, 472, 468, 474, 474, 475, 471, 473, 0, 476, 476, 0, 0, 476, 475, 470, 477, 477, 0, 0, 477, 0, 476, 478, 478, 0, 0, 478, 472, 477, 0, 474, 0, 471, 473, 0, 478, 0, 0, 479, 479, 475, 476, 479, 480, 480, 481, 481, 480, 0, 481, 0, 479, 0, 478, 0, 0, 480, 0, 481, 482, 482, 480, 0, 482, 0, 479, 483, 483, 476, 0, 483, 0, 482, 484, 484, 0, 0, 484, 0, 483, 478, 485, 485, 0, 483, 485, 484, 0, 480, 486, 486, 0, 479, 486, 485, 488, 488, 489, 489, 488, 0, 489, 486, 490, 490, 491, 491, 490, 488, 491, 489, 483, 0, 492, 492, 0, 490, 492, 491, 489, 493, 493, 0, 0, 493, 0, 492, 0, 0, 0, 494, 494, 0, 493, 494, 495, 495, 0, 0, 495, 0, 492, 0, 494, 494, 0, 489, 0, 495, 0, 496, 496, 0, 495, 496, 0, 497, 497, 0, 0, 497, 498, 498, 496, 0, 498, 499, 499, 492, 497, 499, 494, 501, 501, 498, 0, 501, 500, 500, 499, 495, 500, 0, 496, 0, 501, 0, 502, 502, 497, 500, 502, 0, 0, 500, 503, 503, 0, 0, 503, 502, 504, 504, 0, 0, 504, 0, 0, 503, 0, 496, 0, 0, 0, 504, 0, 497, 0, 505, 505, 0, 500, 505, 0, 503, 506, 506, 0, 504, 506, 0, 505, 507, 507, 505, 0, 507, 0, 506, 508, 508, 0, 0, 508, 0, 507, 0, 0, 0, 0, 507, 503, 508, 0, 0, 504, 0, 508, 509, 509, 0, 505, 509, 510, 510, 511, 511, 510, 0, 511, 0, 509, 0, 0, 0, 0, 510, 507, 511, 512, 512, 513, 513, 512, 508, 513, 514, 514, 0, 0, 514, 0, 512, 0, 513, 0, 510, 515, 515, 514, 0, 515, 516, 516, 517, 517, 516, 0, 517, 0, 515, 0, 512, 0, 0, 516, 0, 517, 0, 515, 517, 518, 518, 510, 516, 518, 0, 519, 519, 520, 520, 519, 0, 520, 518, 0, 0, 518, 0, 512, 519, 0, 520, 0, 0, 0, 515, 517, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 518, 522, 522, 522, 522, 523, 0, 523, 523, 524, 0, 524, 524, 525, 525, 526, 0, 526, 526, 527, 0, 527, 527, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "ds9lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "ds9lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "ds9parser.H" extern YYSTYPE* mklval; extern mkFlexLexer* mklexx; /* rules */ #line 1555 "ds9lex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 30 "ds9lex.L" #line 1659 "ds9lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 522 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 521 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 32 "ds9lex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(mklval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 39 "ds9lex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 47 "ds9lex.L" {return AMPLIFIER_;} YY_BREAK case 4: YY_RULE_SETUP #line 48 "ds9lex.L" {return ANNULUS_;} YY_BREAK case 5: YY_RULE_SETUP #line 49 "ds9lex.L" {return ARCMIN_;} YY_BREAK case 6: YY_RULE_SETUP #line 50 "ds9lex.L" {return ARCSEC_;} YY_BREAK case 7: YY_RULE_SETUP #line 51 "ds9lex.L" {return ARROW_;} YY_BREAK case 8: YY_RULE_SETUP #line 52 "ds9lex.L" {return B1950_;} YY_BREAK case 9: YY_RULE_SETUP #line 53 "ds9lex.L" {return BACKGROUND_;} YY_BREAK case 10: YY_RULE_SETUP #line 54 "ds9lex.L" {return BEGIN_;} YY_BREAK case 11: YY_RULE_SETUP #line 55 "ds9lex.L" {return BOX_;} YY_BREAK case 12: YY_RULE_SETUP #line 56 "ds9lex.L" {return BOXCIRCLE_;} YY_BREAK case 13: YY_RULE_SETUP #line 57 "ds9lex.L" {return BPANDA_;} YY_BREAK case 14: YY_RULE_SETUP #line 58 "ds9lex.L" {return CALLBACK_;} YY_BREAK case 15: YY_RULE_SETUP #line 59 "ds9lex.L" {return CIRCLE_;} YY_BREAK case 16: YY_RULE_SETUP #line 60 "ds9lex.L" {return CIRCLE3D_;} YY_BREAK case 17: YY_RULE_SETUP #line 61 "ds9lex.L" {return COLOR_;} YY_BREAK case 18: YY_RULE_SETUP #line 62 "ds9lex.L" {return COMPASS_;} YY_BREAK case 19: YY_RULE_SETUP #line 63 "ds9lex.L" {return COMPOSITE_;} YY_BREAK case 20: YY_RULE_SETUP #line 64 "ds9lex.L" {return CPANDA_;} YY_BREAK case 21: YY_RULE_SETUP #line 65 "ds9lex.L" {return CROSS_;} YY_BREAK case 22: YY_RULE_SETUP #line 66 "ds9lex.L" {return DASH_;} YY_BREAK case 23: YY_RULE_SETUP #line 67 "ds9lex.L" {return DASHLIST_;} YY_BREAK case 24: YY_RULE_SETUP #line 68 "ds9lex.L" {return DEBUG_;} YY_BREAK case 25: YY_RULE_SETUP #line 69 "ds9lex.L" {return DEGREES_;} YY_BREAK case 26: YY_RULE_SETUP #line 70 "ds9lex.L" {return DELETE_;} YY_BREAK case 27: YY_RULE_SETUP #line 71 "ds9lex.L" {return DETECTOR_;} YY_BREAK case 28: YY_RULE_SETUP #line 72 "ds9lex.L" {return DIAMOND_;} YY_BREAK case 29: YY_RULE_SETUP #line 73 "ds9lex.L" {return EDIT_;} YY_BREAK case 30: YY_RULE_SETUP #line 74 "ds9lex.L" {return ELLIPSE_;} YY_BREAK case 31: YY_RULE_SETUP #line 75 "ds9lex.L" {return ECLIPTIC_;} YY_BREAK case 32: YY_RULE_SETUP #line 76 "ds9lex.L" {return EPANDA_;} YY_BREAK case 33: YY_RULE_SETUP #line 77 "ds9lex.L" {return END_;} YY_BREAK case 34: YY_RULE_SETUP #line 78 "ds9lex.L" {return FALSE_;} YY_BREAK case 35: YY_RULE_SETUP #line 79 "ds9lex.L" {return FIELD_;} YY_BREAK case 36: YY_RULE_SETUP #line 80 "ds9lex.L" {return FIXED_;} YY_BREAK case 37: YY_RULE_SETUP #line 81 "ds9lex.L" {return FK4_;} YY_BREAK case 38: YY_RULE_SETUP #line 82 "ds9lex.L" {return FK4_NO_E_;} YY_BREAK case 39: YY_RULE_SETUP #line 83 "ds9lex.L" {return FK5_;} YY_BREAK case 40: YY_RULE_SETUP #line 84 "ds9lex.L" {return FONT_;} YY_BREAK case 41: YY_RULE_SETUP #line 85 "ds9lex.L" {return GALACTIC_;} YY_BREAK case 42: YY_RULE_SETUP #line 86 "ds9lex.L" {return GLOBAL_;} YY_BREAK case 43: YY_RULE_SETUP #line 87 "ds9lex.L" {return HELIOECLIPTIC_;} YY_BREAK case 44: YY_RULE_SETUP #line 88 "ds9lex.L" {return HIGHLITE_;} YY_BREAK case 45: YY_RULE_SETUP #line 89 "ds9lex.L" {return ICRS_;} YY_BREAK case 46: YY_RULE_SETUP #line 90 "ds9lex.L" {return IGNORE_;} YY_BREAK case 47: YY_RULE_SETUP #line 91 "ds9lex.L" {return INCLUDE_;} YY_BREAK case 48: YY_RULE_SETUP #line 92 "ds9lex.L" {return IMAGE_;} YY_BREAK case 49: YY_RULE_SETUP #line 93 "ds9lex.L" {return KEY_;} YY_BREAK case 50: YY_RULE_SETUP #line 94 "ds9lex.L" {return J2000_;} YY_BREAK case 51: YY_RULE_SETUP #line 95 "ds9lex.L" {return LINE_;} YY_BREAK case 52: YY_RULE_SETUP #line 96 "ds9lex.L" {return LINEAR_;} YY_BREAK case 53: YY_RULE_SETUP #line 97 "ds9lex.L" {return MOVE_;} YY_BREAK case 54: YY_RULE_SETUP #line 98 "ds9lex.L" {return N_;} YY_BREAK case 55: YY_RULE_SETUP #line 99 "ds9lex.L" {return NO_;} YY_BREAK case 56: YY_RULE_SETUP #line 100 "ds9lex.L" {return OFF_;} YY_BREAK case 57: YY_RULE_SETUP #line 101 "ds9lex.L" {return ON_;} YY_BREAK case 58: YY_RULE_SETUP #line 102 "ds9lex.L" {return CPANDA_;} YY_BREAK case 59: YY_RULE_SETUP #line 103 "ds9lex.L" {return PHYSICAL_;} YY_BREAK case 60: YY_RULE_SETUP #line 104 "ds9lex.L" {return PIE_;} YY_BREAK case 61: YY_RULE_SETUP #line 105 "ds9lex.L" {return PIXELS_;} YY_BREAK case 62: YY_RULE_SETUP #line 106 "ds9lex.L" {return POINT_;} YY_BREAK case 63: YY_RULE_SETUP #line 107 "ds9lex.L" {return POLYGON_;} YY_BREAK case 64: YY_RULE_SETUP #line 108 "ds9lex.L" {return PROJECTION_;} YY_BREAK case 65: YY_RULE_SETUP #line 109 "ds9lex.L" {return PROPERTY_;} YY_BREAK case 66: YY_RULE_SETUP #line 110 "ds9lex.L" {return ROTATE_;} YY_BREAK case 67: YY_RULE_SETUP #line 111 "ds9lex.L" {return ROTBOX_;} YY_BREAK case 68: YY_RULE_SETUP #line 112 "ds9lex.L" {return RULER_;} YY_BREAK case 69: YY_RULE_SETUP #line 113 "ds9lex.L" {return SELECT_;} YY_BREAK case 70: YY_RULE_SETUP #line 114 "ds9lex.L" {return SOURCE_;} YY_BREAK case 71: YY_RULE_SETUP #line 115 "ds9lex.L" {return SUPERGALACTIC_;} YY_BREAK case 72: YY_RULE_SETUP #line 116 "ds9lex.L" {return TAG_;} YY_BREAK case 73: YY_RULE_SETUP #line 117 "ds9lex.L" {return TEXT_;} YY_BREAK case 74: YY_RULE_SETUP #line 118 "ds9lex.L" {return TEXTANGLE_;} YY_BREAK case 75: YY_RULE_SETUP #line 119 "ds9lex.L" {return TEXTROTATE_;} YY_BREAK case 76: YY_RULE_SETUP #line 120 "ds9lex.L" {return TILE_;} YY_BREAK case 77: YY_RULE_SETUP #line 121 "ds9lex.L" {return TRUE_;} YY_BREAK case 78: YY_RULE_SETUP #line 122 "ds9lex.L" {return VECTOR_;} YY_BREAK case 79: YY_RULE_SETUP #line 123 "ds9lex.L" {return VERSION_;} YY_BREAK case 80: YY_RULE_SETUP #line 124 "ds9lex.L" {return UPDATE_;} YY_BREAK case 81: YY_RULE_SETUP #line 125 "ds9lex.L" {return UNHIGHLITE_;} YY_BREAK case 82: YY_RULE_SETUP #line 126 "ds9lex.L" {return UNSELECT_;} YY_BREAK case 83: YY_RULE_SETUP #line 127 "ds9lex.L" {return WCS_;} YY_BREAK case 84: YY_RULE_SETUP #line 128 "ds9lex.L" {return WCSA_;} YY_BREAK case 85: YY_RULE_SETUP #line 129 "ds9lex.L" {return WCSB_;} YY_BREAK case 86: YY_RULE_SETUP #line 130 "ds9lex.L" {return WCSC_;} YY_BREAK case 87: YY_RULE_SETUP #line 131 "ds9lex.L" {return WCSD_;} YY_BREAK case 88: YY_RULE_SETUP #line 132 "ds9lex.L" {return WCSE_;} YY_BREAK case 89: YY_RULE_SETUP #line 133 "ds9lex.L" {return WCSF_;} YY_BREAK case 90: YY_RULE_SETUP #line 134 "ds9lex.L" {return WCSG_;} YY_BREAK case 91: YY_RULE_SETUP #line 135 "ds9lex.L" {return WCSH_;} YY_BREAK case 92: YY_RULE_SETUP #line 136 "ds9lex.L" {return WCSI_;} YY_BREAK case 93: YY_RULE_SETUP #line 137 "ds9lex.L" {return WCSJ_;} YY_BREAK case 94: YY_RULE_SETUP #line 138 "ds9lex.L" {return WCSK_;} YY_BREAK case 95: YY_RULE_SETUP #line 139 "ds9lex.L" {return WCSL_;} YY_BREAK case 96: YY_RULE_SETUP #line 140 "ds9lex.L" {return WCSM_;} YY_BREAK case 97: YY_RULE_SETUP #line 141 "ds9lex.L" {return WCSN_;} YY_BREAK case 98: YY_RULE_SETUP #line 142 "ds9lex.L" {return WCSO_;} YY_BREAK case 99: YY_RULE_SETUP #line 143 "ds9lex.L" {return WCSP_;} YY_BREAK case 100: YY_RULE_SETUP #line 144 "ds9lex.L" {return WCSQ_;} YY_BREAK case 101: YY_RULE_SETUP #line 145 "ds9lex.L" {return WCSR_;} YY_BREAK case 102: YY_RULE_SETUP #line 146 "ds9lex.L" {return WCSS_;} YY_BREAK case 103: YY_RULE_SETUP #line 147 "ds9lex.L" {return WCST_;} YY_BREAK case 104: YY_RULE_SETUP #line 148 "ds9lex.L" {return WCSU_;} YY_BREAK case 105: YY_RULE_SETUP #line 149 "ds9lex.L" {return WCSV_;} YY_BREAK case 106: YY_RULE_SETUP #line 150 "ds9lex.L" {return WCSW_;} YY_BREAK case 107: YY_RULE_SETUP #line 151 "ds9lex.L" {return WCSX_;} YY_BREAK case 108: YY_RULE_SETUP #line 152 "ds9lex.L" {return WCSY_;} YY_BREAK case 109: YY_RULE_SETUP #line 153 "ds9lex.L" {return WCSZ_;} YY_BREAK case 110: YY_RULE_SETUP #line 154 "ds9lex.L" {return WCS0_;} YY_BREAK case 111: YY_RULE_SETUP #line 155 "ds9lex.L" {return WIDTH_;} YY_BREAK case 112: YY_RULE_SETUP #line 156 "ds9lex.L" {return X_;} YY_BREAK case 113: YY_RULE_SETUP #line 157 "ds9lex.L" {return Y_;} YY_BREAK case 114: YY_RULE_SETUP #line 158 "ds9lex.L" {return YES_;} YY_BREAK case 115: YY_RULE_SETUP #line 161 "ds9lex.L" { // Integer mklval->integer = atoi(yytext); return INT; } YY_BREAK case 116: #line 167 "ds9lex.L" case 117: YY_RULE_SETUP #line 167 "ds9lex.L" { // Real Number mklval->real = atof(yytext); return REAL; } YY_BREAK case 118: #line 173 "ds9lex.L" case 119: YY_RULE_SETUP #line 173 "ds9lex.L" { // degrees yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ANGDEGREE; } YY_BREAK case 120: #line 180 "ds9lex.L" case 121: YY_RULE_SETUP #line 180 "ds9lex.L" { // radians yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ANGRADIAN; } YY_BREAK case 122: #line 187 "ds9lex.L" case 123: YY_RULE_SETUP #line 187 "ds9lex.L" { // physical coords yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return PHYCOORD; } YY_BREAK case 124: #line 194 "ds9lex.L" case 125: YY_RULE_SETUP #line 194 "ds9lex.L" { // image coords yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return IMGCOORD; } YY_BREAK case 126: #line 201 "ds9lex.L" case 127: #line 202 "ds9lex.L" case 128: #line 203 "ds9lex.L" case 129: YY_RULE_SETUP #line 203 "ds9lex.L" { // minutes of arc yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ARCMINUTE; } YY_BREAK case 130: #line 210 "ds9lex.L" case 131: #line 211 "ds9lex.L" case 132: #line 212 "ds9lex.L" case 133: YY_RULE_SETUP #line 212 "ds9lex.L" { // seconds of arc yytext[yyleng-1] = '\0'; mklval->real = atof(yytext); return ARCSECOND; } YY_BREAK case 134: #line 219 "ds9lex.L" case 135: YY_RULE_SETUP #line 219 "ds9lex.L" { // Sexagesimal int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 136: #line 227 "ds9lex.L" case 137: YY_RULE_SETUP #line 227 "ds9lex.L" { // HMS int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return HMSSTR; } YY_BREAK case 138: #line 235 "ds9lex.L" case 139: YY_RULE_SETUP #line 235 "ds9lex.L" { // DMS int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return DMSSTR; } YY_BREAK case 140: #line 243 "ds9lex.L" case 141: YY_RULE_SETUP #line 243 "ds9lex.L" { // Quoted String int ll = (yyleng-2)<(MKBUFSIZE-1) ? (yyleng-2):(MKBUFSIZE-1); strncpy(mklval->str,yytext+1,ll); // skip the " " mklval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 142: YY_RULE_SETUP #line 250 "ds9lex.L" { // Quoted String int ll = (yyleng-2)<(MKBUFSIZE-1) ? (yyleng-2):(MKBUFSIZE-1); strncpy(mklval->str,yytext+1,ll); // skip the '{' mklval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 143: YY_RULE_SETUP #line 257 "ds9lex.L" { // General String int ll = yyleng <(MKBUFSIZE-1) ? yyleng:(MKBUFSIZE-1); strncpy(mklval->str,yytext,ll); mklval->str[ll] = '\0'; return STRING; } YY_BREAK case 144: YY_RULE_SETUP #line 264 "ds9lex.L" { // White Spaces } YY_BREAK case 145: /* rule 145 can match eol */ YY_RULE_SETUP #line 267 "ds9lex.L" { // windows line feed return '\n'; } YY_BREAK case 146: YY_RULE_SETUP #line 271 "ds9lex.L" { // fake line feed return '\n'; } YY_BREAK case 147: /* rule 147 can match eol */ YY_RULE_SETUP #line 275 "ds9lex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 279 "ds9lex.L" { // eof return EOF_; } YY_BREAK case 148: YY_RULE_SETUP #line 283 "ds9lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 149: YY_RULE_SETUP #line 287 "ds9lex.L" ECHO; YY_BREAK #line 2528 "ds9lex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; mkfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); mkfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ mkrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) mkrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 522 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 522 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 521); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) mkalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) mkalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) mkfree((void *) b->yy_ch_buf ); mkfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)mkalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)mkrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) mkalloc(new_size ); else (yy_start_stack) = (int *) mkrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *mkalloc (yy_size_t size ) { return (void *) malloc( size ); } void *mkrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void mkfree (void * ptr ) { free( (char *) ptr ); /* see mkrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 287 "ds9lex.L" void mkDiscard(int doit) { if (mklexx) mklexx->begin(DISCARD, doit); } void mkFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudocolor.C�������������������������������������������������������������0000644�0001750�0001750�00000006307�12107012362�016773� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framepseudocolor.h" #include "fitsimage.h" #include "ps.h" #include "sigbus.h" FramePseudoColor::FramePseudoColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), Frame(i,c,item), FramePseudo(i,c,item) { } void FramePseudoColor::buildXImage(XImage* xmap, Coord::InternalSystem sys) { // we need a colorScale before we can render if (!validColorScale()) return; // make sure we have an image if (!context->cfits) return; int& width = xmap->width; int& height = xmap->height; int& bytesPerLine = xmap->bytes_per_line; char* data = XImageData(xmap); unsigned long bgc = getColor(bgColorName); unsigned long nanc = getColor(nanColorName); // set bg memset(data, bgc, bytesPerLine * height); // basics int length = colorScale->size() - 1; const unsigned char* table = colorScale->colors(); FitsImage* sptr = context->cfits; int mosaic = isMosaic(); // variable double* mm = sptr->matrixToData(sys).mm(); FitsBound* params = sptr->getDataParams(context->frScale.scanMode()); int srcw = sptr->width(); double ll = sptr->getLowDouble(); double hh = sptr->getHighDouble(); double diff = hh - ll; // main loop SETSIGBUS for (long jj=0; jj<height; jj++) { char* dest = data + jj*bytesPerLine; // may be padded at the end for (long ii=0; ii<width; ii++,dest++) { if (mosaic) { sptr = context->cfits; mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); if (isfinite(value)) { if (value <= ll) *dest = table[0]; else if (value >= hh) *dest = table[length]; else *dest = table[(int)(((value - ll)/diff * length) + .5)]; } else *dest = nanc; break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } } } } while (mosaic && sptr); } } CLEARSIGBUS } // Commands void FramePseudoColor::colormapCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) { cmapID = id; bias = b; contrast = c; invert = i; updateColorCells(index, cells, cnt); updateColorScale(); } void FramePseudoColor::colormapMotionCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) { // just remember for getColorbarCmd() cmapID = id; bias = b; contrast = c; invert = i; } void FramePseudoColor::colormapEndCmd() { update(BASE); // always update } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/projection.C�������������������������������������������������������������������0000644�0001750�0001750�00000023041�12057220627�015601� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "projection.h" #include "fitsimage.h" Projection::Projection(const Projection& a) : BaseLine(a) { width = a.width; p3 = a.p3; p4 = a.p4; } Projection::Projection(Base* p, const Vector& ptr1, const Vector& ptr2, double wd, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseLine(p, ptr1, ptr2, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { width = wd; strcpy(type_,"projection"); handle = new Vector[3]; numHandle = 3; analysis(PLOT2D,1); updateBBox(); } void Projection::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector aa = parent->mapFromRef(p1,sys); Vector bb = parent->mapFromRef(p2,sys); XDrawLine(display, drawable, lgc, aa[0], aa[1], bb[0], bb[1]); if (width>0) { renderXLineDash(lgc); Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector c = Vector(0,-width); Vector ll = fwdMap(a,sys); Vector lr = fwdMap(b,sys); Vector ul = fwdMap(a+c,sys); Vector ur = fwdMap(b+c,sys); XDrawLine(display, drawable, lgc, lr[0], lr[1], ur[0], ur[1]); XDrawLine(display, drawable, lgc, ur[0], ur[1], ul[0], ul[1]); XDrawLine(display, drawable, lgc, ul[0], ul[1], ll[0], ll[1]); } } GC Projection::renderXGC(RenderMode mode) { // set width, color, dash switch (mode) { case SRC: XSetForeground(display, gc, color); renderXLineNoDash(gc); return gc; case XOR: renderXLineDash(gcxor); return gcxor; } } void Projection::renderPS(int mode) { renderPSGC(mode); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); { ostringstream str; str << "newpath " << aa.TkCanvasPs(parent->canvas) << "moveto" << bb.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } if (width>0) { renderPSLineDash(); Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector c = Vector(0,-width); Vector ll = fwdMap(a,Coord::CANVAS); Vector lr = fwdMap(b,Coord::CANVAS); Vector ul = fwdMap(a+c,Coord::CANVAS); Vector ur = fwdMap(b+c,Coord::CANVAS); ostringstream str; str << "newpath " << lr.TkCanvasPs(parent->canvas) << "moveto" << ur.TkCanvasPs(parent->canvas) << "lineto" << ul.TkCanvasPs(parent->canvas) << "lineto" << ll.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } void Projection::renderPSGC(int mode) { renderPSColor(mode, parent->getXColor(colorName)); renderPSLineNoDash(); } #ifdef _MACOSX void Projection::renderMACOSX() { renderMACOSXGC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); macosxDrawLine(aa,bb); if (width>0) { renderMACOSXLineDash(); Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector c = Vector(0,-width); Vector ll = fwdMap(a,Coord::CANVAS); Vector lr = fwdMap(b,Coord::CANVAS); Vector ul = fwdMap(a+c,Coord::CANVAS); Vector ur = fwdMap(b+c,Coord::CANVAS); macosxDrawLine(lr,ur); macosxDrawLine(ur,ul); macosxDrawLine(ul,ll); } } void Projection::renderMACOSXGC() { macosxColor(parent->getXColor(colorName)); renderMACOSXLineNoDash(); } #endif #ifdef _WIN32 void Projection::renderWIN32() { renderWIN32GC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); win32DrawLine(aa,bb); if (width>0) { renderWIN32LineDash(); Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector c = Vector(0,-width); Vector ll = fwdMap(a,Coord::CANVAS); Vector lr = fwdMap(b,Coord::CANVAS); Vector ul = fwdMap(a+c,Coord::CANVAS); Vector ur = fwdMap(b+c,Coord::CANVAS); win32DrawLine(lr,ur); win32DrawLine(ur,ul); win32DrawLine(ul,ll); } } void Projection::renderWIN32GC() { win32Color(parent->getXColor(colorName)); renderWIN32LineNoDash(); } #endif // Support void Projection::updateHandles() { center = (p2-p1)/2 + p1; angle = (p2-p1).angle(); Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector c = Vector(0,-width); p3 = fwdMap(a+c,Coord::CANVAS); p4 = fwdMap(b+c,Coord::CANVAS); Vector hh = fwdMap(((b-a)/2+a)+c,Coord::CANVAS); // generate handles in Coord::CANVAS coords handle[0] = parent->mapFromRef(p1,Coord::CANVAS); handle[1] = parent->mapFromRef(p2,Coord::CANVAS); handle[2] = hh; } void Projection::calcAllBBox() { // p3/p4 are already in Coord::CANVAS coords bbox.bound(p3); bbox.bound(p4); Marker::calcAllBBox(); } void Projection::edit(const Vector& v, int h) { switch (h) { case 1: p1 = v; break; case 2: p2 = v; break; case 3: Matrix mm = bckMatrix(); width = -(v * mm)[1]; if (width<0) width = 0; break; } updateBBox(); doCallBack(CallBack::EDITCB); } int Projection::isIn(const Vector& v) { Vector zz = parent->zoom(); if (width * zz.length() > 3) { Matrix imm = bckMatrix(); Vector a = p1*imm; Vector b = p2*imm; Vector vv = -bckMap(v,Coord::CANVAS); return (vv[0]>a[0] && vv[0]<b[0] && vv[1]>0 && vv[1]<width); } else return BaseLine::isIn(v); } void Projection::set(const Vector& v1, const Vector& v2, double wd) { p1 = v1; p2 = v2; width = wd; updateBBox(); doCallBack(CallBack::EDITCB); } void Projection::setWidth(double wd) { width = wd; if (width<0) width = 0; updateBBox(); doCallBack(CallBack::EDITCB); } void Projection::updateCoords(const Matrix& mx) { width = (Vector(0,width) * Scale(mx))[1]; BaseLine::updateCoords(mx); } void Projection::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT2D: if (!analysisPlot2d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot2dCB_[1], parent->options->cmdName); } if (analysisPlot2d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot2dCB_[1]); } analysisPlot2d_ = which; break; } } void Projection::analysisPlot2d(char* xname, char* yname, char* xcname, char* ycname, Coord::CoordSystem sys, Coord::SkyFrame sky, Marker::AnalysisMethod method) { double* x; double* y; double* xc; double* yc; int num = parent->markerAnalysisPlot2d(this, &x, &y, &xc, &yc, p1, p2, width, sys, sky, method); analysisPlot2dResult(xname, yname, xcname, ycname, x, y, xc, yc, num); } // list void Projection::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ',' << ptr->mapLenFromRef(width,sys) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSEqu(sys)) { switch (format) { case Coord::DEGREES: { Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ',' << ptr->mapLenFromRef(width,sys,Coord::ARCSEC) << '"' << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra1[16], ra2[16]; char dec1[16], dec2[16]; { ptr->mapFromRef(p1,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra1 >> dec1; } { ptr->mapFromRef(p2,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra2 >> dec2; } str << type_ << '(' << ra1 << ',' << dec1 << ',' << ra2 << ',' << dec2 << ',' << ptr->mapLenFromRef(width,sys,Coord::ARCSEC) << '"' << ')'; } break; } } else { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ',' << ptr->mapLenFromRef(width,sys) << ')'; } } } if (conj) str << " ||"; listProperties(str, 0); } } void Projection::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); Vector vv[2]; vv[0] = p1; vv[1] = p2; double rr = ptr->mapLenFromRef(width,sys,Coord::ARCSEC); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowPoint(ptr,sys,sky,format,vv,2); XMLRow(XMLR,rr); XMLRowProps(ptr,sys); XMLRowEnd(str); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscale.h�������������������������������������������������������������������0000644�0001750�0001750�00000003462�11700666266�015634� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscale_h__ #define __colorscale_h__ #include <tcl.h> #include <X11/Xlib.h> #include "util.h" #define IISMIN 1 #define IISMAX 217 #define IISSIZE 217 #define IISCOLORS 200 class ColorScale { public: int size_; unsigned char* psColors_; // rgb for ps unsigned short* psIndex_; // index for ps unsigned char* colors_; // for render public: ColorScale(int); virtual ~ColorScale(); int size() {return size_;} const unsigned char* psColors() {return psColors_;} const unsigned short* psIndex() {return psIndex_;} const unsigned char* colors() {return colors_;} }; class LinearScale : public virtual ColorScale { public: LinearScale(int, unsigned short*, unsigned char*, int); }; class LogScale : public virtual ColorScale { public: LogScale(int, unsigned short*, unsigned char*, int, double); }; class PowScale : public virtual ColorScale { public: PowScale(int, unsigned short*, unsigned char*, int, double); }; class SqrtScale : public virtual ColorScale { public: SqrtScale(int, unsigned short*, unsigned char*, int); }; class SquaredScale : public virtual ColorScale { public: SquaredScale(int, unsigned short*, unsigned char*, int); }; class AsinhScale : public virtual ColorScale { public: AsinhScale(int, unsigned short*, unsigned char*, int); }; class SinhScale : public virtual ColorScale { public: SinhScale(int, unsigned short*, unsigned char*, int); }; class IISScale : public virtual ColorScale { public: IISScale(unsigned short*, unsigned char*, int); }; class HistEquScale : public virtual ColorScale { public: HistEquScale(int, unsigned short*, unsigned char*, int, double*, int); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/contour.h����������������������������������������������������������������������0000644�0001750�0001750�00000002351�11775636564�015205� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __contour_h__ #define __contour_h__ #include "vector.h" #include "vector3d.h" #include "list.h" #include "coord.h" class FitsImage; class Base; class Contour { protected: Base* parent; List<Vertex> contours_; char* colorName; unsigned long color; int lineWidth; int dash; Contour* previous_; Contour* next_; public: Contour(Base*, const char*, int, int); Contour(Base*, const char*, int, int, const List<Vertex>&); virtual ~Contour(); void render(Pixmap, Coord::InternalSystem, int, int); void ps(int); #ifdef _MACOSX void macosx(); #endif #ifdef _WIN32 void win32(); #endif const List<Vertex>& contours() {return contours_;} void updateCoords(const Matrix&); const char* getColorName() {return colorName;} void setColor(const char*); int getDash() {return dash;} void setDash(int); void setLineWidth(int); int getLineWidth() {return lineWidth;} Contour* previous() {return previous_;} void setPrevious(Contour* m) {previous_ = m;} Contour* next() {return next_;} void setNext(Contour* m) {next_ = m;} }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/boxannulus.h�������������������������������������������������������������������0000644�0001750�0001750�00000003330�12030663652�015667� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __boxannulus_h__ #define __boxannulus_h__ #include "basebox.h" class BoxAnnulus : public BaseBox { public: BoxAnnulus(const BoxAnnulus&); BoxAnnulus(Base* p, const Vector& ctr, const Vector& s, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); BoxAnnulus(Base* p, const Vector& ctr, const Vector& inner, const Vector& outer, int num, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); BoxAnnulus(Base* p, const Vector& ctr, int an, Vector* s, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new BoxAnnulus(*this);} void editBegin(int); void edit(const Vector&, int); void editEnd(); int addAnnuli(const Vector&); void analysis(AnalysisTask, int); void analysisRadial(char*, char*, char*, Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void listSAOimage(ostream&, int); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/baseline.h���������������������������������������������������������������������0000644�0001750�0001750�00000002455�11727727777�015307� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __baseline_h__ #define __baseline_h__ #include "marker.h" class BaseLine : public Marker { protected: Vector p1; Vector p2; void renderXInclude(Drawable, Coord::InternalSystem, RenderMode) {} void renderPSInclude(int) {} #ifdef _MACOSX void renderMACOSXInclude() {} #endif #ifdef _WIN32 void renderWIN32Include() {} #endif void updateHandles() {} public: BaseLine(const BaseLine&); BaseLine(Base* p, const Vector& ptr1, const Vector& ptr2, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual void updateCoords(const Matrix&); virtual int isIn(const Vector&); void centroid(); void move(const Vector&); void moveTo(const Vector&); virtual void edit(const Vector&, int); void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} const Vector& getP1() {return p1;} const Vector& getP2() {return p2;} virtual void setPoints(const Vector&, const Vector&); // special composite funtionality void setComposite(const Matrix&, double); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor.C�������������������������������������������������������������0000644�0001750�0001750�00000002276�12107012362�016703� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "frame3dtruecolor.h" #include "fitsimage.h" #include "ps.h" Frame3dTrueColor::Frame3dTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i,c,item), Frame3d(i,c,item), Frame3dTrue(i,c,item) { colormapData = NULL; } Frame3dTrueColor::~Frame3dTrueColor() { if (colormapData) delete [] colormapData; } void Frame3dTrueColor::buildXImage(XImage* ximage, Coord::InternalSystem sys) { // we need a colorScale before we can render if (!validColorScale()) return; unsigned char* img = fillImage(ximage->width, ximage->height, sys); if (img) encodeTrueColor(img, ximage); delete [] img; } // Commands void Frame3dTrueColor::colormapCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) { cmapID = id; bias = b; contrast = c; invert = i; updateColorCells(index, cells, cnt); updateColorScale(); update(BASE); } void Frame3dTrueColor::colormapEndCmd() { update(BASE); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ruler.h������������������������������������������������������������������������0000644�0001750�0001750�00000003567�11727730005�014635� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __ruler_h__ #define __ruler_h__ #include "baseline.h" class Ruler : public BaseLine { private: Vector p3; Coord::CoordSystem coordSystem; Coord::SkyFrame skyFrame; Coord::CoordSystem distSystem; Coord::SkyDist distDist; double dist; private: void renderX(Drawable, Coord::InternalSystem, RenderMode); GC renderXGC(RenderMode); void renderPS(int); void renderPSGC(int); #ifdef _MACOSX void renderMACOSX(); void renderMACOSXGC(); #endif #ifdef _WIN32 void renderWIN32(); void renderWIN32GC(); #endif void updateHandles(); void calcAllBBox(); int isOn(const Vector&, const Vector&, const Vector&); void distToStr(ostringstream&); public: Ruler(const Ruler&); Ruler(Base* p, const Vector& ptr1, const Vector& ptr2, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem distsys, Coord::SkyDist distfor, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Ruler(*this);} void updateCoords(const Matrix&); int isIn(const Vector&); const Vector& getP1() {return p1;} const Vector& getP2() {return p2;} const Vector& getP3() {return p3;} void setCoordSystem(Coord::CoordSystem, Coord::SkyFrame, Coord::CoordSystem, Coord::SkyDist); Coord::CoordSystem getSystem() {return coordSystem;} Coord::SkyFrame getSkyFrame() {return skyFrame;} Coord::CoordSystem getDistSystem() {return distSystem;} Coord::SkyDist getDistDist() {return distDist;} void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid2d.h�����������������������������������������������������������������������0000644�0001750�0001750�00000001436�12001331444�014636� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid2d_h__ #define __grid2d_h__ #include <tk.h> #include "grid.h" #include "grid2dbase.h" #include "coord.h" class Grid2d : public Grid, public Grid2dBase { private: int matrixMap(void*, Matrix&, const char*); int doit(RenderMode); public: Grid2d(Widget*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, GridType, const char*, const char*); ~Grid2d(); const char* option() {return GridBase::option();} void x11() {doit(X11);} void ps(int mode) {mode_=mode; doit(PS);} #ifdef _MACOSX void macosx() {doit(MACOSX);} #endif #ifdef _WIN32 void win32() {doit(GWIN32);} #endif }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor24.h����������������������������������������������������������0000644�0001750�0001750�00000001324�11700666267�017374� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framergbtruecolor24_h__ #define __framergbtruecolor24_h__ #include "framergbtruecolor.h" #include "truecolor24.h" class FrameRGBTrueColor24 : public virtual FrameBase, public FrameRGBTrueColor, public TrueColor24 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor24::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor24::encodeTrueColor(src, ximage);} public: FrameRGBTrueColor24(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameRGBTrueColor24(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frsave.C�����������������������������������������������������������������������0000644�0001750�0001750�00000026163�12131563542�014722� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "framebase.h" #include "framergb.h" #include "fitsimage.h" #include "outfile.h" #include "outchannel.h" #include "outsocket.h" #include "sigbus.h" void Base::saveFits(OutFitsStream& str) { FitsImage* ptr = currentContext->fits; int dd = currentContext->naxis(2); if (ptr) { ptr->saveFitsHeader(str,dd); size_t cnt =0; FitsImage* sptr = ptr; while (sptr) { cnt += sptr->saveFits(str); sptr = sptr->nextSlice(); } ptr->saveFitsPad(str,cnt,'\0'); } } void Base::saveFitsTable(OutFitsStream& str) { FitsImage* ptr = currentContext->fits; if (ptr) ptr->saveFitsTable(str); } void Base::saveFitsSlice(OutFitsStream& str) { FitsImage* ptr = currentContext->cfits; if (ptr) { ptr->saveFitsHeader(str,0); size_t cnt = ptr->saveFits(str); ptr->saveFitsPad(str,cnt,'\0'); } } void Base::saveFitsExtCube(OutFitsStream& str) { FitsImage* ptr = currentContext->fits; if (ptr) { ptr->saveFitsPrimHeader(str); while (ptr) { ptr->saveFitsXtHeader(str, 0); size_t cnt = ptr->saveFits(str); ptr->saveFitsPad(str,cnt,'\0'); ptr = ptr->nextSlice(); } } } void Base::saveFitsMosaic(OutFitsStream& str, int which) { FitsImage* ptr = currentContext->fits; int dd = currentContext->naxis(2); // which 1 to n which--; while (ptr && which) { ptr = ptr->nextMosaic(); which--; } if (ptr) { ptr->saveFitsHeader(str,dd); size_t cnt =0; FitsImage* sptr = ptr; while (sptr) { cnt += sptr->saveFits(str); sptr = sptr->nextSlice(); } ptr->saveFitsPad(str,cnt,'\0'); } } void Base::saveFitsMosaicImage(OutFitsStream& str) { FitsImage* ptr = currentContext->fits; int dd = currentContext->naxis(2); if (ptr) { ptr->saveFitsPrimHeader(str); while (ptr) { ptr->saveFitsXtHeader(str,dd); size_t cnt =0; FitsImage* sptr = ptr; while (sptr) { cnt += sptr->saveFits(str); sptr = sptr->nextSlice(); } ptr->saveFitsPad(str,cnt,'\0'); ptr = ptr->nextMosaic(); } } } void FrameRGB::saveFitsRGBImage(OutFitsStream& str) { FitsImage* ptr = keyContext->fits; if (ptr) { // fake primary header ptr->saveFitsPrimHeader(str); for (int ii=0; ii<3; ii++) { if (context[ii].fits) { context[ii].fits->saveFitsXtHeader(str,0); size_t cnt = context[ii].fits->saveFits(str); context[ii].fits->saveFitsPad(str,cnt,'\0'); } } } } void FrameRGB::saveFitsRGBCube(OutFitsStream& str) { FitsImage* ptr = keyContext->fits; if (ptr) { int ss =0; for (int ii=0; ii<3; ii++) if (context[ii].fits) ss++; ptr->saveFitsHeader(str,ss); size_t cnt =0; for (int ii=0; ii<3; ii++) if (context[ii].fits) cnt += context[ii].fits->saveFits(str); ptr->saveFitsPad(str,cnt,'\0'); } } void Base::saveArray(OutFitsStream& str, FitsFile::ArchType endian) { FitsImage* ptr = currentContext->fits; if (ptr) { // set endian if needed if (endian == FitsFile::NATIVE) { if (lsb()) endian = FitsFile::LITTLE; else endian = FitsFile::BIG; } if (ptr) { // dump each slice while (ptr) { ptr->saveArray(str,endian); ptr = ptr->nextSlice(); } } } } void FrameRGB::saveArrayRGBCube(OutFitsStream& str, FitsFile::ArchType endian) { FitsImage* ptr = keyContext->fits; if (ptr) { // set endian if needed if (endian == FitsFile::NATIVE) { if (lsb()) endian = FitsFile::LITTLE; else endian = FitsFile::BIG; } for (int ii=0; ii<3; ii++) if (context[ii].fits) context[ii].fits->saveArray(str,endian); } } void Base::saveNRRD(OutFitsStream& str, FitsFile::ArchType endian) { FitsImage* ptr = currentContext->fits; if (ptr) { // set endian if needed if (endian == FitsFile::NATIVE) { if (lsb()) endian = FitsFile::LITTLE; else endian = FitsFile::BIG; } // dump header ostringstream hstr; hstr << "NRRD0002" << endl; if (!ptr->naxis(2)) { hstr << "dimension: 2" << endl; hstr << "sizes: " << ptr->naxis(0) << ' ' << ptr->naxis(1) << endl; } else { hstr << "dimension: 3" << endl; hstr << "sizes: " << ptr->naxis(0) << ' ' << ptr->naxis(1) << ' ' << ptr->naxis(2) << endl; } switch (ptr->bitpix()) { case 8: hstr << "type: char" << endl; break; case 16: hstr << "type: short" << endl; break; case 32: hstr << "type: int" << endl; break; case 64: hstr << "type: longlong" << endl; break; case -32: hstr << "type: float" << endl; break; case -64: hstr << "type: double" << endl; break; } if (abs(ptr->bitpix()) > 8) { switch (endian) { case FitsFile::LITTLE: hstr << "endian: little" << endl; break; case FitsFile::BIG: hstr << "endian: big" << endl; break; } } hstr << "encoding: raw" << endl; // very important hstr << endl; char* ll = (char*)hstr.str().c_str(); str.write(ll, strlen(ll)); // now dump each slice while (ptr) { ptr->saveArray(str,endian); ptr = ptr->nextSlice(); } } } void FrameBase::saveFitsResample(OutFitsStream& str) { int& width = options->width; int& height = options->height; int bitpix_ = -32; int datapixels_ = width*height; int realbytes_ = datapixels_ * (abs(bitpix_)/8); int datablocks_ = (realbytes_ + (FTY_BLOCK-1))/FTY_BLOCK; int databytes_ = datablocks_ * FTY_BLOCK; // create header FitsHead hd(width, height, 1, bitpix_); // write keywords saveFitsResampleKeyword(str, hd); // write header str.write(hd.cards(), hd.headbytes()); // write data saveFitsResampleFits(str); // pad rest of block { int diff = databytes_ - realbytes_; char buf[diff]; memset(buf,'\0',diff); str.write(buf, diff); } } void FrameBase::saveFitsResampleKeyword(OutFitsStream& str, FitsHead& dst) { FitsHead* src = currentContext->fits->getHead(); Vector center = Vector(options->width, options->height)/2.; // OBJECT char* object = src->getString("OBJECT"); if (object) { dst.appendString("OBJECT", object, NULL); delete [] object; } // DATE-OBS char* date = src->getString("DATE"); if (date) { dst.appendString("DATE", date, NULL); delete [] date; } char* dateobs = src->getString("DATE-OBS"); if (dateobs) { dst.appendString("DATE-OBS", dateobs, NULL); delete [] dateobs; } char* timeobs = src->getString("TIME-OBS"); if (timeobs) { dst.appendString("TIME-OBS", timeobs, NULL); delete [] timeobs; } char* dateend = src->getString("DATE-END"); if (dateend) { dst.appendString("DATE-END", dateend, NULL); delete [] dateend; } char* timeend = src->getString("TIME-END"); if (timeend) { dst.appendString("TIME-END", timeend, NULL); delete [] timeend; } // LTMV,DTMV if (!isMosaic()) { if (currentContext->fits->hasLTMV()) { Matrix ltmv = currentContext->fits->physicalToRef * refToWidget * Translate(-center) * Translate(1,0) * FlipY() * Translate(center); dst.appendReal("LTM1_1", ltmv[0][0], 9, NULL); dst.appendReal("LTM1_2", ltmv[0][1], 9, NULL); dst.appendReal("LTM2_1", ltmv[1][0], 9, NULL); dst.appendReal("LTM2_2", ltmv[1][1], 9, NULL); dst.appendReal("LTV1", ltmv[2][0], 9, NULL); dst.appendReal("LTV2", ltmv[2][1], 9, NULL); } } else { if (currentContext->fits->hasDTMV()) { Matrix dtmv = currentContext->fits->detectorToRef * refToWidget * Translate(-center) * Translate(1,0) * FlipY() * Translate(center); dst.appendReal("DTM1_1", dtmv[0][0], 9, NULL); dst.appendReal("DTM1_2", dtmv[0][1], 9, NULL); dst.appendReal("DTM2_1", dtmv[1][0], 9, NULL); dst.appendReal("DTM2_2", dtmv[1][1], 9, NULL); dst.appendReal("DTV1", dtmv[2][0], 9, NULL); dst.appendReal("DTV2", dtmv[2][1], 9, NULL); } } // WCS if (currentContext->fits->hasWCS(Coord::WCS)) { WorldCoor* wcs = currentContext->fits->getWCS(Coord::WCS); // abort if this is a DSS, ZPN, TNX if (!strncmp(wcs->ptype,"DSS",3) || !strncmp(wcs->ptype,"ZPN",3) || !strncmp(wcs->ptype,"TNX",3)) return; dst.appendString("RADECSYS", wcs->radecsys, NULL); dst.appendReal("EQUINOX", wcs->equinox, 9, NULL); dst.appendString("CTYPE1", wcs->ctype[0], NULL); dst.appendString("CTYPE2", wcs->ctype[1], NULL); dst.appendReal("CRVAL1", wcs->crval[0], 9, NULL); dst.appendReal("CRVAL2", wcs->crval[1], 9, NULL); char* cunit1 = src->getString("CUNIT1"); if (cunit1) { dst.appendString("CUNIT1", cunit1, NULL); delete [] cunit1; } char* cunit2 = src->getString("CUNIT2"); if (cunit2) { dst.appendString("CUNIT2", cunit2, NULL); delete [] cunit2; } // crpix Vector crpix = Vector(wcs->crpix[0],wcs->crpix[1]) * currentContext->fits->imageToWidget * Translate(-center) * Translate(1,0) * FlipY() * Translate(center); dst.appendReal("CRPIX1", crpix[0], 9, NULL); dst.appendReal("CRPIX2", crpix[1], 9, NULL); // cd matrix Matrix cd = Matrix(wcs->cd[0],wcs->cd[1],wcs->cd[2],wcs->cd[3],0,0) * currentContext->fits->imageToRef * refToUser * wcsOrientationMatrix * Rotate(wcsRotation) * orientationMatrix * Scale(zoom_.invert()) * Rotate(rotation) * Translate(center) * Translate(-center) * Translate(1,0) * FlipY() * Translate(center); dst.appendReal("CD1_1", cd.matrix(0,0), 9, NULL); dst.appendReal("CD1_2", cd.matrix(0,1), 9, NULL); dst.appendReal("CD2_1", cd.matrix(1,0), 9, NULL); dst.appendReal("CD2_2", cd.matrix(1,1), 9, NULL); } } void FrameBase::saveFitsResampleFits(OutFitsStream& str) { int& width = options->width; int& height = options->height; // basics FitsImage* sptr = currentContext->fits; int mosaic = isMosaic(); // variable double* mm = sptr->matrixToData(Coord::WIDGET).mm(); FitsBound* params = sptr->getDataParams(currentContext->frScale.scanMode()); int srcw = sptr->width(); // main loop SETSIGBUS for (int jj=height-1; jj>=0; jj--) { for (int ii=0; ii<width; ii++) { if (mosaic) { sptr = currentContext->fits; mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(currentContext->frScale.scanMode()); srcw = sptr->width(); } float v = NAN; do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { v = sptr->getValueFloat(long(yy)*srcw + long(xx)); break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(currentContext->frScale.scanMode()); srcw = sptr->width(); } } } } while (mosaic && sptr); if (lsb()) str.writeSwap((char*)(&v), 4, -32); else str.write((char*)(&v), 4); } } CLEARSIGBUS } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/box.C��������������������������������������������������������������������������0000644�0001750�0001750�00000024644�12030663652�014227� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "box.h" #include "fitsimage.h" Box::Box(const Box& a) : BaseBox(a) {} Box::Box(Base* p, const Vector& ctr, const Vector& seg, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseBox(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = 1; annuli_ = new Vector[1]; annuli_[0] = seg; strcpy(type_,"box"); numHandle = 4; updateBBox(); } void Box::editBegin(int h) { switch (h) { case 1: return; case 2: annuli_[0] = Vector(-annuli_[0][0],annuli_[0][1]); return; case 3: annuli_[0] = -annuli_[0]; return; case 4: annuli_[0] = Vector(annuli_[0][0],-annuli_[0][1]); return; } doCallBack(CallBack::EDITBEGINCB); } void Box::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); Matrix nn = mm.invert(); // This annuli_s about the opposite node Vector ov = annuli_[0]/2 * nn; annuli_[0] = (annuli_[0]/2) - (v*mm); Vector nv = annuli_[0]/2 * nn; center -= nv-ov; updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); } void Box::editEnd() { annuli_[0] = annuli_[0].abs(); updateBBox(); doCallBack(CallBack::EDITENDCB); } void Box::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT3D: if (!analysisPlot3d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot3dCB_[1], parent->options->cmdName); } if (analysisPlot3d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot3dCB_[1]); } analysisPlot3d_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Box::analysisPlot3d(char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { double* x; double* y; Matrix mm = Rotate(angle) * Translate(center); // during resize, annuli_ can be negative Vector vv = annuli_[0].abs(); BBox bb(-vv * mm); bb.bound( vv * mm); bb.bound(Vector( vv[0],-vv[1]) * mm); bb.bound(Vector(-vv[0], vv[1]) * mm); int num = parent->markerAnalysisPlot3d(this, &x, &y, bb, sys, method); analysisPlot3dResult(xname, yname, x, y, num); } void Box::analysisStats(Coord::CoordSystem sys) { ostringstream str; Matrix mm = Rotate(angle) * Translate(center); // during resize, annuli_ can be negative Vector vv = annuli_[0].abs(); BBox bb(-vv * mm); bb.bound( vv * mm); bb.bound(Vector( vv[0],-vv[1]) * mm); bb.bound(Vector(-vv[0], vv[1]) * mm); parent->markerAnalysisStats(this, str, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Box::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << "\"" << ',' << r[1] << "\"" << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << r[0] << "\""<< ',' << r[1] << "\""<< ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void Box::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_[0]); XMLRowAng(sys,sky); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Box::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); listCiaoPre(str); // radius is always in image coords switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); Vector s = ptr->mapLenFromRef(annuli_[0],Coord::PHYSICAL); str << "rotbox(" << setprecision(8) << v[0] << ',' << v[1] << ',' << s[0] << ',' << s[1] << ',' << radToDeg(angle) << ')'; } break; default: if (ptr->hasWCSCel(sys)) { Vector s = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCMIN); char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << "rotbox(" << ra << ',' << dec << ',' << s[0] << '\'' << ',' << s[1] << '\'' << ',' << radToDeg(angle) << ')'; } } listCiaoPost(str, strip); } void Box::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); listSAOtngPre(str, strip); // radius is always in image coords switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::IMAGE); Vector s = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << s[0] << ',' << s[1] << ',' << radToDeg(angle) << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector s = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << s[0] << ',' << s[1] << ',' << radToDeg(angle) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); Vector s = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << s[0] << ',' << s[1] << ',' << radToDeg(angle) << ')'; } break; } } } listSAOtngPost(str,strip); } void Box::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); coord.listProsCoordSystem(str,sys,sky); str << "; "<< type_ << ' ' << setprecision(8) << v << r << radToDeg(angle); } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v[0] << "d " << v[1] << "d " << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << ra << ' ' << dec << ' ' << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); } break; } } } listProsPost(str, strip); } void Box::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[0][0] << ',' << annuli_[0][1] << ',' << radToDeg(angle) << ')'; listSAOimagePost(str, strip); } ��������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsdata.h���������������������������������������������������������������������0000644�0001750�0001750�00000007704�12107012361�015267� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsdata_h__ #define __fitsdata_h__ #include "base.h" #include "file.h" class ColorScale; class FitsFile; class FitsBound { public: int xmin; int xmax; int ymin; int ymax; int zmin; int zmax; FitsBound(int x0, int y0, int x1, int y1) {xmin=x0; xmax=x1; ymin=y0; ymax=y1; zmin=0; zmax=0;} FitsBound(int x0, int y0, int x1, int y1, int z0, int z1) {xmin=x0; xmax=x1; ymin=y0; ymax=y1; zmin=z0; zmax=z1;} FitsBound() {reset();} void reset() {xmin= xmax= ymin= ymax= zmin= zmax=0;} }; ostream& operator<<(ostream&, const FitsBound&); class FitsData { protected: Base* parent; long width; long height; char buf[32]; int byteswap; double bscale; double bzero; int hasScaling; int hasBlank; int blank; double high; // bscale applied double low; // bscale applied float zHigh; // bscale applied float zLow; // bscale applied double aLow; // bscale applied double aHigh; // bscale applied double uLow; // bscale applied double uHigh; // bscale applied int scanValid; int incr_; float zContrast; int zSample; int zLine; int zscaleValid; int autoCutValid; float autoCutPer; FrScale::ClipMode clipMode; FrScale::MinMaxMode mmMode; FrScale::ScanMode scanMode; double datamin; // bscale applied double datamax; // bscale applied int hasdatamin; double irafmin; // bscale applied double irafmax; // bscale applied int hasirafmin; // zscale constants enum PixelType {GOOD_PIXEL, BAD_PIXEL, REJECT_PIXEL}; int zSubSample(float*, float*, int, int); int zFitLine(float*, int, float*, float*, float, int, int); void zFlattenData (float*, float*, float*, int npix, float, float dz); int zComputeSigma (float*, short*, int npix, float*, float*); int zRejectPixels (float*, float*, float*, short*, int, double*, double*, double*, double*, float, int); protected: void autoCut(FitsBound*); int getIncr(); public: FitsData(FitsFile*, Base*); virtual ~FitsData(); virtual const char* getValue(const Vector&) =0; virtual float getValueFloat(const Vector&) =0; virtual double getValueDouble(const Vector&) =0; virtual int getValueMask(const Vector&) =0; virtual int getValueMask(double,double) =0; virtual float getValueFloat(long) =0; virtual double getValueDouble(long) =0; virtual int getValueMask(long) =0; virtual const char* getMin() =0; virtual const char* getMax() =0; virtual double getMinDouble() =0; virtual double getMaxDouble() =0; const char* getLow(); const char* getHigh(); double getLowDouble() {return low;} double getHighDouble() {return high;} void setClip(double l, double h) {low = l; high = h;} virtual void updateClip(FrScale*, FitsBound*) =0; int hasDATAMIN() {return hasdatamin;} int hasIRAFMIN() {return hasirafmin;} virtual void bin(double*,int,double,double,FitsBound*) =0; }; template<class T> class FitsDatam : public FitsData { private: T* data; T min; // bscale not applied T max; // bscale not applied void updateMinMax(FitsBound*); void scan(FitsBound*); void output(ostringstream&, T); void zscale(FitsBound*); int zSampleImage(float**,FitsBound*); public: FitsDatam(FitsFile*, Base*); T swap(T*); const char* getValue(const Vector&); float getValueFloat(const Vector&); double getValueDouble(const Vector&); int getValueMask(const Vector&); int getValueMask(double, double); float getValueFloat(long i); double getValueDouble(long i); int getValueMask(long i); const char* getMin(); const char* getMax(); double getMinDouble(); double getMaxDouble(); void updateClip(FrScale*, FitsBound*); void bin(double*, int, double, double, FitsBound*); }; #endif ������������������������������������������������������������./saods9/saotk/frame/tngparser.H��������������������������������������������������������������������0000644�0001750�0001750�00000007557�11626771530�015462� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, SEXSTR = 262, EOF_ = 263, B1950_ = 264, BACKGROUND_ = 265, BOX_ = 266, BLACK_ = 267, BLUE_ = 268, CIRCLE_ = 269, CYAN_ = 270, DATE_ = 271, DEBUG_ = 272, DEGREES_ = 273, ECLIPTIC_ = 274, ELLIPSE_ = 275, FILENAME_ = 276, FK4_ = 277, FK4_NO_E_ = 278, FK5_ = 279, FORMAT_ = 280, GALACTIC_ = 281, GREEN_ = 282, HELIOECLIPTIC_ = 283, HMS_ = 284, ICRS_ = 285, J2000_ = 286, LINE_ = 287, MAGENTA_ = 288, OFF_ = 289, ON_ = 290, PHYSICAL_ = 291, PIXELS_ = 292, POINT_ = 293, POLYGON_ = 294, RED_ = 295, SOURCE_ = 296, SUPERGALACTIC_ = 297, TEXT_ = 298, VERSION_ = 299, WHITE_ = 300, YELLOW_ = 301 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define SEXSTR 262 #define EOF_ 263 #define B1950_ 264 #define BACKGROUND_ 265 #define BOX_ 266 #define BLACK_ 267 #define BLUE_ 268 #define CIRCLE_ 269 #define CYAN_ 270 #define DATE_ 271 #define DEBUG_ 272 #define DEGREES_ 273 #define ECLIPTIC_ 274 #define ELLIPSE_ 275 #define FILENAME_ 276 #define FK4_ 277 #define FK4_NO_E_ 278 #define FK5_ 279 #define FORMAT_ 280 #define GALACTIC_ 281 #define GREEN_ 282 #define HELIOECLIPTIC_ 283 #define HMS_ 284 #define ICRS_ 285 #define J2000_ 286 #define LINE_ 287 #define MAGENTA_ 288 #define OFF_ 289 #define ON_ 290 #define PHYSICAL_ 291 #define PIXELS_ 292 #define POINT_ 293 #define POLYGON_ 294 #define RED_ 295 #define SOURCE_ 296 #define SUPERGALACTIC_ 297 #define TEXT_ 298 #define VERSION_ 299 #define WHITE_ 300 #define YELLOW_ 301 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 61 "tngparser.Y" { #define TNGBUFSIZE 2048 double real; int integer; char str[TNGBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 149 "tngparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/baseellipse.C������������������������������������������������������������������0000644�0001750�0001750�00000043446�12005552150�015720� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "baseellipse.h" #include "fitsimage.h" BaseEllipse::BaseEllipse(const BaseEllipse& a) : BaseMarker(a) {} BaseEllipse::BaseEllipse(Base* p, const Vector& ctr, double ang, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb) : BaseMarker(p, ctr, ang, clr, dsh, w, f, t, prop, c, tag, cb) { } BaseEllipse::~BaseEllipse() { } void BaseEllipse::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { double ang = calcAngle(); Vector r = annuli_[numAnnuli_-1]; Vector z = parent->zoom(); int isOrient = parent->getOrientation() == Coord::NORMAL && parent->getWCSOrientation() == Coord::NORMAL; int isRound = r[0] == r[1]; int isScale = z[0] == z[1]; int isAngle = teq(ang,0,FLT_EPSILON) || teq(ang,M_PI,FLT_EPSILON); if (isRound && isScale && isOrient && parent->isAzElZero()) renderXCircle(drawable, sys, ang, mode); else renderXEllipseCurve(drawable, sys, mode); } void BaseEllipse::renderXCircle(Drawable drawable, Coord::InternalSystem sys, double ang, RenderMode mode) { GC lgc = renderXGC(mode); // this routine is only valid for circles with equal zoom in x & y Vector cc = parent->mapFromRef(center,sys); for (int i=0; i<numAnnuli_; i++) { Vector r = annuli_[i]; Vector ur = fwdMap(r,sys); double l = (ur-cc).length() * cos(M_PI_4); Vector rr(l,l); Vector st = cc-rr; Vector size = rr*2; // Verify size is positive // XDrawArc is sensative to bad data, and may hang the XServer if (!size[0] || !size[1]) continue; // Must be very sure that a1<a2 double aa1 = startAng_ + ang; double aa2 = stopAng_ + ang; int a1 = radToDeg(aa1)*64; int a2 = radToDeg(aa2)*64; if (a2<=a1) a2 += 360*64; XDrawArc(display, drawable, lgc, st[0], st[1], size[0], size[1], a1, (a2-a1)); } } void BaseEllipse::renderXEllipseCurve(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { double a1 = startAng_; double a2 = stopAng_; if (a2<=a1) a2 += M_TWOPI; for (int i=0; i<numAnnuli_; i++) { Vector r = annuli_[i]; int s1 =0; int s2 =0; for (int i=0; i<8; i++) { double b1 = i*M_PI_2; double b2 = (i+1)*M_PI_2; if (!s1 && a1>=b1 && a1<b2) s1 =1; if (!s2 && a2>b1 && a2<=b2) s2 =1; if ((s1 && !s2) || (s1 && s2)) renderXEllipsePrep(drawable, sys, mode, a1,a2,b1,b2,r); if (s1&&s2) s1=s2=0; } } } void BaseEllipse::renderXEllipsePrep(Drawable drawable, Coord::InternalSystem sys, RenderMode mode, double a1, double a2, double b1, double b2, Vector& r) { if (!(a1 >= b1 && a1 <= b2)) a1 = b1; if (!(a2 >= b1 && a2 <= b2)) a2 = b2; if (a1>a2) { renderXEllipseArc(drawable, sys, mode, b1,a2,r); renderXEllipseArc(drawable, sys, mode, a1,b2,r); } else renderXEllipseArc(drawable, sys, mode, a1,a2,r); } void BaseEllipse::renderXEllipseArc(Drawable drawable, Coord::InternalSystem sys, RenderMode mode, double a1, double a2, Vector& rr) { // don't render if zero angle if (a1==a2) return; // don't render if zero length if (rr[0]==0 || rr[1]==0) return; // bezier curve, valid for arcs of <M_PI_2 double aa1 = xyz(rr,a1); double aa2 = xyz(rr,a2); double bcp = 4.0/3*(1-cos((aa2-aa1)/2))/sin((aa2-aa1)/2); Vector t0 = intersect(rr,a1); Vector x1 = Vector(rr[0]*(cos(aa1)-bcp*sin(aa1)), rr[1]*(sin(aa1)+bcp*cos(aa1))); Vector x2 = Vector(rr[0]*(cos(aa2)+bcp*sin(aa2)), rr[1]*(sin(aa2)-bcp*cos(aa2))); Vector t1 = intersect(rr,a2); Vector tt0 = fwdMap(t0*FlipY(),sys); Vector xx1 = fwdMap(x1*FlipY(),sys); Vector xx2 = fwdMap(x2*FlipY(),sys); Vector tt1 = fwdMap(t1*FlipY(),sys); XDrawCurve(drawable, mode, tt0, xx1, xx2, tt1); } void BaseEllipse::renderXInclude(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { if (!(properties & INCLUDE)) { Matrix mm = fwdMatrix(); double theta = degToRad(45); Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), annuli_[numAnnuli_-1][1]*sin(theta)), sys); Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), -annuli_[numAnnuli_-1][1]*sin(theta)), sys); GC lgc = renderXGC(mode); if (mode == SRC) XSetForeground(display, gc, parent->getColor("red")); XDrawLine(display, drawable, lgc, r1[0], r1[1], r2[0], r2[1]); } } void BaseEllipse::renderPS(int mode) { Vector r = annuli_[numAnnuli_-1]; Vector z = parent->zoom(); int isOrient = parent->getOrientation() == Coord::NORMAL && parent->getWCSOrientation() == Coord::NORMAL; int isRound = r[0] == r[1]; int isScale = z[0] == z[1]; if (isRound && isScale && isOrient && parent->isAzElZero()) renderPSCircle(mode); else renderPSEllipseCurve(mode); } void BaseEllipse::renderPSCircle(int mode) { renderPSGC(mode); Vector cc = parent->mapFromRef(center,Coord::CANVAS); double ang = calcAngle(); for (int ii=0; ii<numAnnuli_; ii++) { Vector r = annuli_[ii]; Vector ur = fwdMap(r,Coord::CANVAS); double l = (ur-cc).length() * cos(M_PI_4); // don't render zero length arcs if (!l) continue; // Must be very sure that a1<a2 double aa1 = startAng_ + ang; double aa2 = stopAng_ + ang; float a1 = radToDeg(aa1); float a2 = radToDeg(aa2); if (a2<=a1) a2 += 360; ostringstream str; str << "newpath " << cc.TkCanvasPs(parent->canvas) << l << ' ' << a1 << ' ' << a2 << " arc stroke " << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } void BaseEllipse::renderPSEllipseCurve(int mode) { renderPSGC(mode); double a1 = startAng_; double a2 = stopAng_; if (a2<=a1) a2 += M_TWOPI; for (int ii=0; ii<numAnnuli_; ii++) { Vector r = annuli_[ii]; int s1 =0; int s2 =0; for (int jj=0; jj<8; jj++) { double b1 = jj*M_PI_2; double b2 = (jj+1)*M_PI_2; if (!s1 && a1>=b1 && a1<b2) s1 =1; if (!s2 && a2>b1 && a2<=b2) s2 =1; if ((s1 && !s2) || (s1 && s2)) renderPSEllipsePrep(a1,a2,b1,b2,r); if (s1&&s2) s1=s2=0; } } } void BaseEllipse::renderPSEllipsePrep(double a1, double a2, double b1, double b2, Vector& rr) { if (!(a1 >= b1 && a1 <= b2)) a1 = b1; if (!(a2 >= b1 && a2 <= b2)) a2 = b2; if (a1>a2) { renderPSEllipseArc(b1,a2,rr); renderPSEllipseArc(a1,b2,rr); } else renderPSEllipseArc(a1,a2,rr); } void BaseEllipse::renderPSEllipseArc(double a1, double a2, Vector& rr) { // don't render zero length arcs if (a1 == a2) return; if (!rr[0] || !rr[1]) return; // bezier curve, valid for arcs of <M_PI_2 double aa1 = xyz(rr,a1); double aa2 = xyz(rr,a2); double bcp = 4.0/3*(1-cos((aa2-aa1)/2))/sin((aa2-aa1)/2); Vector t0 = intersect(rr,a1); Vector x1 = Vector(rr[0]*(cos(aa1)-bcp*sin(aa1)), rr[1]*(sin(aa1)+bcp*cos(aa1))); Vector x2 = Vector(rr[0]*(cos(aa2)+bcp*sin(aa2)), rr[1]*(sin(aa2)-bcp*cos(aa2))); Vector t1 = intersect(rr,a2); Vector tt0 = fwdMap(t0*FlipY(),Coord::CANVAS); Vector xx1 = fwdMap(x1*FlipY(),Coord::CANVAS); Vector xx2 = fwdMap(x2*FlipY(),Coord::CANVAS); Vector tt1 = fwdMap(t1*FlipY(),Coord::CANVAS); ostringstream str; str << "newpath " << tt0.TkCanvasPs(parent->canvas) << "moveto " << xx1.TkCanvasPs(parent->canvas) << xx2.TkCanvasPs(parent->canvas) << tt1.TkCanvasPs(parent->canvas) << " curveto stroke" << endl; str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } void BaseEllipse::renderPSInclude(int mode) { if (!(properties & INCLUDE)) { double theta = degToRad(45); Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), -annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); renderPSColor(mode, parent->getXColor("red")); ostringstream str; str << "newpath " << r1.TkCanvasPs(parent->canvas) << "moveto" << r2.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void BaseEllipse::renderMACOSX() { Vector r = annuli_[numAnnuli_-1]; Vector z = parent->zoom(); int isOrient = parent->getOrientation() == Coord::NORMAL && parent->getWCSOrientation() == Coord::NORMAL; int isRound = r[0] == r[1]; int isScale = z[0] == z[1]; if (isRound && isScale && isOrient & parent->isAzElZero()) renderMACOSXCircle(); else renderMACOSXEllipseCurve(); } void BaseEllipse::renderMACOSXCircle() { renderMACOSXGC(); Vector cc = parent->mapFromRef(center,Coord::CANVAS); double ang = calcAngle(); for (int ii=0; ii<numAnnuli_; ii++) { Vector r = annuli_[ii]; Vector ur = fwdMap(r,Coord::CANVAS); double l = (ur-cc).length() * cos(M_PI_4); // don't render zero length arcs if (!l) continue; double a1 = startAng_ + ang; double a2 = stopAng_ + ang; if (a2<=a1) a2 += M_TWOPI; macosxDrawArc(cc, l, a1, a2); } } void BaseEllipse::renderMACOSXEllipseCurve() { renderMACOSXGC(); double a1 = startAng_; double a2 = stopAng_; if (a2<=a1) a2 += M_TWOPI; for (int ii=0; ii<numAnnuli_; ii++) { Vector r = annuli_[ii]; int s1 =0; int s2 =0; for (int jj=0; jj<8; jj++) { double b1 = jj*M_PI_2; double b2 = (jj+1)*M_PI_2; if (!s1 && a1>=b1 && a1<b2) s1 =1; if (!s2 && a2>b1 && a2<=b2) s2 =1; if ((s1 && !s2) || (s1 && s2)) renderMACOSXEllipsePrep(a1,a2,b1,b2,r); if (s1&&s2) s1=s2=0; } } } void BaseEllipse::renderMACOSXEllipsePrep(double a1, double a2, double b1, double b2, Vector& rr) { if (!(a1 >= b1 && a1 <= b2)) a1 = b1; if (!(a2 >= b1 && a2 <= b2)) a2 = b2; if (a1>a2) { renderMACOSXEllipseArc(b1,a2,rr); renderMACOSXEllipseArc(a1,b2,rr); } else renderMACOSXEllipseArc(a1,a2,rr); } void BaseEllipse::renderMACOSXEllipseArc(double a1, double a2, Vector& rr) { // don't render zero length arcs if (a1 == a2) return; if (!rr[0] || !rr[1]) return; // bezier curve, valid for arcs of <M_PI_2 double aa1 = xyz(rr,a1); double aa2 = xyz(rr,a2); double bcp = 4.0/3*(1-cos((aa2-aa1)/2))/sin((aa2-aa1)/2); Vector t0 = intersect(rr,a1); Vector x1 = Vector(rr[0]*(cos(aa1)-bcp*sin(aa1)), rr[1]*(sin(aa1)+bcp*cos(aa1))); Vector x2 = Vector(rr[0]*(cos(aa2)+bcp*sin(aa2)), rr[1]*(sin(aa2)-bcp*cos(aa2))); Vector t1 = intersect(rr,a2); Vector tt0 = fwdMap(t0*FlipY(),Coord::CANVAS); Vector xx1 = fwdMap(x1*FlipY(),Coord::CANVAS); Vector xx2 = fwdMap(x2*FlipY(),Coord::CANVAS); Vector tt1 = fwdMap(t1*FlipY(),Coord::CANVAS); macosxDrawCurve(tt0, xx1, xx2, tt1); } void BaseEllipse::renderMACOSXInclude() { if (!(properties & INCLUDE)) { double theta = degToRad(45); Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), -annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); macosxColor(parent->getXColor("red")); macosxDrawLine(r1,r2); } } #endif #ifdef _WIN32 void BaseEllipse::renderWIN32() { Vector r = annuli_[numAnnuli_-1]; Vector z = parent->zoom(); int isOrient = parent->getOrientation() == Coord::NORMAL && parent->getWCSOrientation() == Coord::NORMAL; int isRound = r[0] == r[1]; int isScale = z[0] == z[1]; if (isRound && isScale && isOrient && parent->isAzElZero()) renderWIN32Circle(); else renderWIN32EllipseCurve(); } void BaseEllipse::renderWIN32Circle() { renderWIN32GC(); Vector cc = parent->mapFromRef(center,Coord::CANVAS); double ang = calcAngle(); for (int i=0; i<numAnnuli_; i++) { Vector r = annuli_[i]; Vector ur = fwdMap(r,Coord::CANVAS); double l = (ur-cc).length() * cos(M_PI_4); // don't render zero length arcs if (!l) continue; double a1 = startAng_ + ang; double a2 = stopAng_ + ang; if (a2<=a1) a2 += M_TWOPI; win32DrawArc(cc, l, a1, a2); } } void BaseEllipse::renderWIN32EllipseCurve() { renderWIN32GC(); double a1 = startAng_; double a2 = stopAng_; if (a2<=a1) a2 += M_TWOPI; for (int ii=0; ii<numAnnuli_; ii++) { Vector r = annuli_[ii]; int s1 =0; int s2 =0; for (int jj=0; jj<8; jj++) { double b1 = jj*M_PI_2; double b2 = (jj+1)*M_PI_2; if (!s1 && a1>=b1 && a1<b2) s1 =1; if (!s2 && a2>b1 && a2<=b2) s2 =1; if ((s1 && !s2) || (s1 && s2)) renderWIN32EllipsePrep(a1,a2,b1,b2,r); if (s1&&s2) s1=s2=0; } } } void BaseEllipse::renderWIN32EllipsePrep(double a1, double a2, double b1, double b2, Vector& rr) { if (!(a1 >= b1 && a1 <= b2)) a1 = b1; if (!(a2 >= b1 && a2 <= b2)) a2 = b2; if (a1>a2) { renderWIN32EllipseArc(b1,a2,rr); renderWIN32EllipseArc(a1,b2,rr); } else renderWIN32EllipseArc(a1,a2,rr); } void BaseEllipse::renderWIN32EllipseArc(double a1, double a2, Vector& rr) { // don't render zero length arcs if (a1 == a2) return; if (!rr[0] || !rr[1]) return; // bezier curve, valid for arcs of <M_PI_2 double aa1 = xyz(rr,a1); double aa2 = xyz(rr,a2); double bcp = 4.0/3*(1-cos((aa2-aa1)/2))/sin((aa2-aa1)/2); Vector t0 = intersect(rr,a1); Vector x1 = Vector(rr[0]*(cos(aa1)-bcp*sin(aa1)), rr[1]*(sin(aa1)+bcp*cos(aa1))); Vector x2 = Vector(rr[0]*(cos(aa2)+bcp*sin(aa2)), rr[1]*(sin(aa2)-bcp*cos(aa2))); Vector t1 = intersect(rr,a2); Vector tt0 = fwdMap(t0*FlipY(),Coord::CANVAS); Vector xx1 = fwdMap(x1*FlipY(),Coord::CANVAS); Vector xx2 = fwdMap(x2*FlipY(),Coord::CANVAS); Vector tt1 = fwdMap(t1*FlipY(),Coord::CANVAS); win32DrawCurve(tt0, xx1, xx2, tt1); } void BaseEllipse::renderWIN32Include() { if (!(properties & INCLUDE)) { double theta = degToRad(45); Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), -annuli_[numAnnuli_-1][1]*sin(theta)), Coord::CANVAS); win32Color(parent->getXColor("red")); win32DrawLine(r1,r2); } } #endif // Support void BaseEllipse::updateHandles() { // handles are in canvas coords // we can't garantee that the annuli_ have been sorted yet if (handle) delete [] handle; handle = new Vector[numHandle]; Vector max; for(int ii=0; ii<numAnnuli_; ii++) if (max[0]<annuli_[ii][0]) max = annuli_[ii]; Vector& r = max; handle[0] = fwdMap(Vector(-r[0],-r[1]),Coord::CANVAS); handle[1] = fwdMap(Vector( r[0],-r[1]),Coord::CANVAS); handle[2] = fwdMap(Vector( r[0], r[1]),Coord::CANVAS); handle[3] = fwdMap(Vector(-r[0], r[1]),Coord::CANVAS); // annuli_ if (numAnnuli_>1) for (int ii=0; ii<numAnnuli_; ii++) handle[ii+4] = fwdMap(Vector(annuli_[ii][0],0),Coord::CANVAS); } int BaseEllipse::isIn(const Vector& vv, Coord::InternalSystem sys, int nn) { Vector rr = annuli_[nn]; // zero radius if (!rr[0] || !rr[1]) return 0; Vector pp = bckMap(vv,sys); if ((pp[0]*pp[0])/(rr[0]*rr[0]) + (pp[1]*pp[1])/(rr[1]*rr[1]) <= 1) return 1; else return 0; } Vector BaseEllipse::intersect(Vector rr, double aa) { double tt = rr[1]*rr[1]*cos(aa)*cos(aa)+rr[0]*rr[0]*sin(aa)*sin(aa); double ss =0; if (tt>0) ss = rr[0]*rr[1]/sqrt(tt); return Vector(ss*cos(aa),ss*sin(aa)); } void BaseEllipse::XDrawCurve(Drawable drawable, RenderMode mode, Vector& t1, Vector& x1, Vector& x2, Vector& t2) { // if dashed, fake it GC lgc; if ((properties & SOURCE) && !(properties & DASH)) lgc = renderXGC(mode); else { // set width, color, dash switch (mode) { case SRC: XSetForeground(display, gc, color); renderXLineNoDash(gc); lgc = gc; break; case XOR: renderXLineNoDash(gcxor); lgc = gcxor; break; } } float t1x = t1[0]; float t1y = t1[1]; float t2x = t2[0]; float t2y = t2[1]; float x1x = x1[0]; float x1y = x1[1]; float x2x = x2[0]; float x2y = x2[1]; float rx = t1x; float ry = t1y; Vector dd = (t2-t1).abs(); float max = dd[0]>dd[1] ? dd[0] : dd[1]; // calculate incr // this is a crude attempt to limit the number of iterations // we want a min for very small segments, but not that large for // high zoom or elongated curves float aa = int(log(max))*5; float incr = 1./(aa > 2 ? aa : 2); int dash=0; float tt = incr; while (tt<=1+FLT_EPSILON) { float xx = pow(tt,3)*(t2x+3*(x1x-x2x)-t1x) +3*pow(tt,2)*(t1x-2*x1x+x2x) +3*tt*(x1x-t1x)+t1x; float yy = pow(tt,3)*(t2y+3*(x1y-x2y)-t1y) +3*pow(tt,2)*(t1y-2*x1y+x2y) +3*tt*(x1y-t1y)+t1y; // crude attempt to clip unwanted drawlines // only works for SRC if ((properties & SOURCE) && !(properties & DASH)) XDrawLine(display, drawable, lgc, rx, ry, xx, yy); else { if (dash) XDrawLine(display, drawable, lgc, rx, ry, xx, yy); dash = !dash; } rx = xx; ry = yy; tt += incr; } } // this routine maps the desired angle to an angle to be used with XDrawArc double BaseEllipse::xyz(Vector rr, double aa) { // just in case if (!rr[0] || !rr[1]) return aa; int flip=0; while (aa>M_PI) { aa -= M_PI; flip++; } double tt = rr[1]*rr[1]*cos(aa)*cos(aa)+rr[0]*rr[0]*sin(aa)*sin(aa); double ss =0; if (tt>0) ss = 1./sqrt(tt); double bb = rr[1]*ss*cos(aa); return acos(bb)+M_PI*flip; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametruecolor24.C�������������������������������������������������������������0000644�0001750�0001750�00000016511�11700666270�016632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frametruecolor24.h" #include "colorscaletrue24.h" #include "colorscaletrue32.h" // Tk Canvas Widget Function Declarations int FrameTrueColor24CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameTrueColor24 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameTrueColor24Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameTrueColor24Type = { (char*)"frametruecolor24", // name sizeof(WidgetOptions), // item size FrameTrueColor24CreateProc, // configProc frameTrueColor24Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameTrueColor24_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameTrueColor24Type); return TCL_OK; } int FrameTrueColor24CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameTrueColor24* frame = new FrameTrueColor24(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameTrueColor24 Member Functions FrameTrueColor24::FrameTrueColor24(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameTrueColor(i,c,item), TrueColor24(visual) { configSpecs = frameTrueColor24Specs; // frame configure options } FrameTrueColor24::~FrameTrueColor24() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void FrameTrueColor24::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells || !bitsperpixel_) return; if (colorScale) delete colorScale; // determine if we have 3 bytes or 4 bytes per pixel switch (bitsperpixel_) { case 24: updateColorScale24(); break; case 32: updateColorScale32(); break; } } void FrameTrueColor24::updateColorScale24() { switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor24(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor24(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor24(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } void FrameTrueColor24::updateColorScale32() { switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor32(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor32(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor32(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/tngparser.Y��������������������������������������������������������������������0000644�0001750�0001750�00000020256�11727715200�015464� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {tngFlexLexer* ll} %parse-param {tngFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; tngDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer tngFlexLexer #include <FlexLexer.h> extern int tnglex(void*, tngFlexLexer*); extern void tngerror(Base*, tngFlexLexer*, const char*); extern void tngDiscard(int); static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static unsigned short globalProps; static unsigned short localProps; static char globalColor[16]; static char localColor[16]; static int dash[] = {8,3}; static char globalFont[32]; static char globalText[80]; static char localText[80]; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); %} %union { #define TNGBUFSIZE 2048 double real; int integer; char str[TNGBUFSIZE]; double vector[3]; } %type <real> numeric %type <real> angle %type <real> optangle %type <real> value %type <vector> vvalue %type <real> sexagesimal %type <vector> coord %type <integer> skyFrame %token <integer> INT %token <real> REAL %token <str> STRING %token <real> ANGDEGREE %token <str> SEXSTR %token EOF_ %token B1950_ %token BACKGROUND_ %token BOX_ %token BLACK_ %token BLUE_ %token CIRCLE_ %token CYAN_ %token DATE_ %token DEBUG_ %token DEGREES_ %token ECLIPTIC_ %token ELLIPSE_ %token FILENAME_ %token FK4_ %token FK4_NO_E_ %token FK5_ %token FORMAT_ %token GALACTIC_ %token GREEN_ %token HELIOECLIPTIC_ %token HMS_ %token ICRS_ %token J2000_ %token LINE_ %token MAGENTA_ %token OFF_ %token ON_ %token PHYSICAL_ %token PIXELS_ %token POINT_ %token POLYGON_ %token RED_ %token SOURCE_ %token SUPERGALACTIC_ %token TEXT_ %token VERSION_ %token WHITE_ %token YELLOW_ %% start : initGlobal commands ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "SAOtng" << endl;} | initLocal include shape | generalComment ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; sp : /* empty */ | ',' ; bp : /* empty */ | '(' ; ep : /* emtpy */ | ')' ; optangle: /* empty */ {$$ = 0;} | angle {$$ = $1;} ; angle : numeric {$$ = degToRad($1);} /* assume degree */ | ANGDEGREE {$$ = degToRad($1);} ; value : numeric {$$ = FITSPTR->mapLenToRef($1,Coord::IMAGE);} ; vvalue : numeric sp numeric { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; coord : sexagesimal sp sexagesimal { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector($1,$3), sys, sky); else r = FITSPTR->mapToRef(Vector($1*360./24.,$3), sys, sky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3), localSystem, localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; skyFrame : FK4_ {$$ = Coord::FK4;} | B1950_ {$$ = Coord::FK4;} | FK4_NO_E_ {$$ = Coord::FK4_NO_E;} | FK5_ {$$ = Coord::FK5;} | J2000_ {$$ = Coord::FK5;} | ICRS_ {$$ = Coord::ICRS;} | GALACTIC_ {$$ = Coord::GALACTIC;} | SUPERGALACTIC_ {$$ = Coord::SUPERGALACTIC;} | ECLIPTIC_ {$$ = Coord::ECLIPTIC;} | HELIOECLIPTIC_ {$$ = Coord::HELIOECLIPTIC;} ; initGlobal:{ // global properties globalSystem = Coord::IMAGE; globalSky = Coord::FK5; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; strcpy(globalColor,"green"); strcpy(globalFont,"helvetica 10 normal roman"); strcpy(globalText,""); } ; initLocal : { // reset maperr flag maperr =0; // global properties localSystem = globalSystem; localSky = localSky; localProps = globalProps; strcpy(localColor,globalColor); strcpy(localText,globalText); strcpy(localComment,""); strcpy(globalText,""); } ; include : /* empty */ {setProps(&localProps, Marker::INCLUDE, 1);} | '+' {setProps(&localProps, Marker::INCLUDE, 1);} | '-' {setProps(&localProps, Marker::INCLUDE, 0);} ; shape : CIRCLE_ bp coord sp value ep shapeComment {fr->createCircleCmd(Vector($3), $5, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | ELLIPSE_ bp coord sp vvalue sp optangle ep shapeComment {fr->createEllipseCmd(Vector($3), Vector($5), $7, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | BOX_ bp coord sp vvalue sp optangle ep shapeComment {fr->createBoxCmd(Vector($3), Vector($5), $7, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | LINE_ bp coord sp coord ep shapeComment {fr->createLineCmd(Vector($3), Vector($5), 0,0, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | POINT_ bp coord ep shapeComment {fr->createPointCmd(Vector($3), Point::BOXCIRCLE, POINTSIZE, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | TEXT_ bp coord sp STRING ep {strncpy(localText,$5,80);} shapeComment {fr->createTextCmd(Vector($3), 0, 1, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} | POLYGON_ {polylist.deleteAll();} bp polyNodes ep shapeComment {fr->createPolygonCmd(polylist, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);} ; polyNodes : polyNodes sp polyNode | polyNode ; polyNode : coord {polylist.append(new Vertex($1));} ; generalComment : '#' FORMAT_ ':' tngFormat | '#' FILENAME_ ':' {DISCARD_(0)} STRING | '#' DATE_ ':' {DISCARD_(0)} STRING | '#' {DISCARD_(1)} STRING {strncpy(globalText,$3,80);} ; shapeComment : /* empty */ | '#' WHITE_ {strcpy(localColor,"white");} | '#' BLACK_ {strcpy(localColor,"black");} | '#' RED_ {strcpy(localColor,"red");} | '#' GREEN_ {strcpy(localColor,"green");} | '#' BLUE_ {strcpy(localColor,"blue");} | '#' CYAN_ {strcpy(localColor,"cyan");} | '#' MAGENTA_ {strcpy(localColor,"magenta");} | '#' YELLOW_ {strcpy(localColor,"yellow");} | '#' SOURCE_ { strcpy(localColor,"green"); setProps(&localProps,Marker::SOURCE,1); } | '#' BACKGROUND_ { strcpy(localColor,"red"); setProps(&localProps,Marker::SOURCE,0); } | '#' {DISCARD_(1)} STRING {strncpy(localComment,$3,80);} ; tngFormat : HMS_ tngWCS | DEGREES_ tngWCS | PIXELS_ {globalSystem = localSystem = Coord::IMAGE;} | PIXELS_ '(' PHYSICAL_ ')' {globalSystem = localSystem = Coord::IMAGE;} ; tngWCS : /* empty */ { globalSystem = localSystem = Coord::WCS; globalSky = localSky = Coord::FK5; } | '(' skyFrame ')' { globalSystem = localSystem = Coord::WCS; globalSky = localSky = (Coord::SkyFrame)$2; } ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/baseellipse.h������������������������������������������������������������������0000644�0001750�0001750�00000004477�12005552151�015767� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __baseellipse_h__ #define __baseellipse_h__ #include "basemarker.h" class BaseEllipse : public BaseMarker { private: double xyz(Vector rr, double ang); void XDrawCurve(Drawable, RenderMode, Vector&, Vector&, Vector&, Vector&); void renderXCircle(Drawable, Coord::InternalSystem, double, RenderMode); void renderXEllipseCurve(Drawable, Coord::InternalSystem, RenderMode); void renderXEllipsePrep(Drawable, Coord::InternalSystem, RenderMode, double, double, double, double, Vector&); void renderXEllipseArc(Drawable, Coord::InternalSystem, RenderMode, double, double, Vector&); void renderXInclude(Drawable, Coord::InternalSystem, RenderMode); void renderPSCircle(int); void renderPSEllipseCurve(int); void renderPSEllipsePrep(double, double, double, double, Vector&); void renderPSEllipseArc(double, double, Vector&); void renderPSInclude(int); #ifdef _MACOSX void renderMACOSXCircle(); void renderMACOSXEllipseCurve(); void renderMACOSXEllipsePrep(double, double, double, double, Vector&); void renderMACOSXEllipseArc(double, double, Vector&); void renderMACOSXInclude(); #endif #ifdef _WIN32 void renderWIN32Circle(); void renderWIN32EllipseCurve(); void renderWIN32EllipsePrep(double, double, double, double, Vector&); void renderWIN32EllipseArc(double, double, Vector&); void renderWIN32Include(); #endif protected: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif virtual void updateHandles(); Vector intersect(Vector, double); public: BaseEllipse(const BaseEllipse&); BaseEllipse(Base* p, const Vector& ctr, double a, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb); virtual ~BaseEllipse(); virtual Marker* dup() =0; int isIn(const Vector& vv) {return isIn(vv, Coord::CANVAS);} int isIn(const Vector& vv, Coord::InternalSystem sys) {return isIn(vv,sys,numAnnuli_-1);} int isIn(const Vector&, Coord::InternalSystem, int); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frmarker.C���������������������������������������������������������������������0000644�0001750�0001750�00000430403�12107476366�015253� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <fstream> #include "fdstream.hpp" #include "context.h" #include "base.h" #include "fitsimage.h" #include "fvcontour.h" #include "marker.h" #include "basemarker.h" #include "sigbus.h" #include "circle.h" #include "ellipse.h" #include "box.h" #include "polygon.h" #include "line.h" #include "vect.h" #include "text.h" #include "point.h" #include "ruler.h" #include "compass.h" #include "projection.h" #include "annulus.h" #include "ellipseannulus.h" #include "boxannulus.h" #include "cpanda.h" #include "epanda.h" #include "bpanda.h" #include "composite.h" #define LISTBUFSIZE 8192 // NOTE: all marker traversal routines use a local ptr as opposed to the // list current() because marker call backs may invoke another traversal // routine or the event loop, which may process pending events // DS9/Funtools Marker Parser Stuff // Parser Stuff #undef yyFlexLexer #define yyFlexLexer mkFlexLexer #include <FlexLexer.h> void* mklval; mkFlexLexer* mklexx; extern int mkparse(Base*, mkFlexLexer*); int mklex(void* vval, mkFlexLexer* ll) { mklval = vval; mklexx = ll; return ll ? ll->yylex() : 0; } void mkerror(Base* fr, mkFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // CIAO Marker Parser Stuff #undef yyFlexLexer #define yyFlexLexer ciaoFlexLexer #include <FlexLexer.h> void* ciaolval; extern int ciaoparse(Base*, ciaoFlexLexer*); int ciaolex(void* vval, ciaoFlexLexer* ll) { ciaolval = vval; return ll ? ll->yylex() : 0; } void ciaoerror(Base* fr, ciaoFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // PROS Marker Parser Stuff #undef yyFlexLexer #define yyFlexLexer prosFlexLexer #include <FlexLexer.h> void* proslval; prosFlexLexer* proslexx; extern int prosparse(Base*, prosFlexLexer*); int proslex(void* vval, prosFlexLexer* ll) { proslval = vval; proslexx = ll; return ll ? ll->yylex() : 0; } void proserror(Base* fr, prosFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // TNG Marker Parser Stuff #undef yyFlexLexer #define yyFlexLexer tngFlexLexer #include <FlexLexer.h> void* tnglval; tngFlexLexer* tnglexx; extern int tngparse(Base*, tngFlexLexer*); int tnglex(void* vval, tngFlexLexer* ll) { tnglval = vval; tnglexx = ll; return ll ? ll->yylex() : 0; } void tngerror(Base* fr, tngFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // SAO Marker Parser Stuff #undef yyFlexLexer #define yyFlexLexer saoFlexLexer #include <FlexLexer.h> void* saolval; saoFlexLexer* saolexx; extern int saoparse(Base*, saoFlexLexer*); int saolex(void* vval, saoFlexLexer* ll) { saolval = vval; saolexx = ll; return ll ? ll->yylex() : 0; } void saoerror(Base* fr, saoFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // XY Marker Parser Stuff #undef yyFlexLexer #define yyFlexLexer xyFlexLexer #include <FlexLexer.h> void* xylval; extern int xyparse(Base*, xyFlexLexer*); int xylex(void* vval, xyFlexLexer* ll) { xylval = vval; return ll ? ll->yylex() : 0; } void xyerror(Base* fr, xyFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // Marker Commands // Basic Regions void Base::createCircleCmd(const Vector& center, double radius, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Circle(this, center, radius, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createEllipseCmd(const Vector& center, const Vector& radius, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag,const List<CallBack>& cb) { createMarker(new Ellipse(this,center, radius, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createBoxCmd(const Vector& center, const Vector& size, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Box(this, center, size, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createPolygonCmd(const Vector& center, const Vector& bb, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Polygon(this, center, bb, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createPolygonCmd(const List<Vertex>& list, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Polygon(this, list, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createContourPolygonCmd( const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { // only create in the USER layer markerLayerCmd(USER); // main contour if (hasContour()) { List<Vertex>& c = (List<Vertex>&)(currentContext->contour->contours()); // build from back to front if (c.tail()) { List<Vertex> list; while (c.previous()) { if (c.current()->vector[0] != DBL_MAX) list.append(new Vertex(c.current()->vector)); else { if (list.count()>0) createMarker(new Polygon(this, list, color, dash, width, font, text, prop, NULL, tag, cb)); list.deleteAll(); } } if (list.count()>0) createMarker(new Polygon(this, list, color, dash, width, font, text, prop, comment, tag, cb)); } } // aux contours Contour* cptr = currentContext->auxcontours.head(); while (cptr) { List<Vertex>& c = (List<Vertex>&)(cptr->contours()); // build from back to front if (c.tail()) { List<Vertex> list; while (c.previous()) { if (c.current()->vector[0] != DBL_MAX) list.append(new Vertex(c.current()->vector)); else { if (list.count()>0) createMarker(new Polygon(this, list, color, dash, width, font, text, prop, NULL, tag, cb)); list.deleteAll(); } } if (list.count()>0) createMarker(new Polygon(this, list, color, dash, width, font, text, prop, comment, tag, cb)); } cptr = cptr->next(); } } void Base::createLineCmd(const Vector& center, const Vector& p2, int arrow1, int arrow2, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Line(this, center, p2, arrow1, arrow2, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createVectCmd(const Vector& center, const Vector& p2, int arrow, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Vect(this, center, p2, arrow, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createVectCmd(const Vector& center, double mag, double ang, int arrow, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Vect(this, center, mag, ang, arrow, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createTextCmd(const Vector& center, double angle, int rotate, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Text(this, center, angle, rotate, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createPointCmd(const Vector& center, Point::PointShape shape, int size, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Point(this, center, shape, size, color, dash, width, font, text, prop, comment, tag, cb)); } // Measurement Regions void Base::createRulerCmd(const Vector& center, const Vector& p2, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem distsys, Coord::SkyDist distdist, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Ruler(this, center, p2, sys, sky, distsys, distdist, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createCompassCmd(const Vector& center, double r, const char* north, const char* east, int na, int ea, Coord::CoordSystem sys, Coord::SkyFrame sky, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Compass(this, center, r, north, east, na, ea, sys, sky, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createProjectionCmd(const Vector& center, const Vector& p2, double w, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Projection(this, center, p2, w, color, dash, width, font, text, prop, comment, tag, cb)); } // Annulus Regions void Base::createAnnulusCmd(const Vector& center, double start, double stop, int num, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag,const List<CallBack>& cb) { createMarker(new Annulus(this, center, start, stop, num, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createAnnulusCmd(const Vector& center, int num, double* radii, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag,const List<CallBack>& cb) { createMarker(new Annulus(this, center, num, radii, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createEllipseAnnulusCmd(const Vector& center, const Vector& inner, const Vector& outer, int num, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new EllipseAnnulus(this, center, inner, outer, num, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createEllipseAnnulusCmd(const Vector& center, int num, Vector* radii, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new EllipseAnnulus(this, center, num, radii, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createBoxAnnulusCmd(const Vector& center, const Vector& inner, const Vector& outer, int num, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new BoxAnnulus(this, center, inner, outer, num, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createBoxAnnulusCmd(const Vector& center, int num, Vector* size, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new BoxAnnulus(this, center, num, size, angle, color, dash, width, font, text, prop, comment, tag, cb)); } // Panda Regions void Base::createCpandaCmd(const Vector& center, double ang1, double ang2, int an, double rad1, double rad2, int rn, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Cpanda(this, center, ang1, ang2, an, rad1, rad2, rn, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createCpandaCmd(const Vector& center, int an, double* a, int rn, double* r, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Cpanda(this, center, an, a, rn, r, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createEpandaCmd(const Vector& center, double ang1, double ang2, int an, const Vector& rad1, const Vector& rad2, int rn, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Epanda(this, center, ang1, ang2, an, rad1, rad2, rn, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createEpandaCmd(const Vector& center, int an, double* a, int rn, Vector* r, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Epanda(this, center, an, a, rn, r, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createBpandaCmd(const Vector& center, double ang1, double ang2, int an, const Vector& rad1, const Vector& rad2, int rn, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Bpanda(this, center, ang1, ang2, an, rad1, rad2, rn, angle, color, dash, width, font, text, prop, comment, tag, cb)); } void Base::createBpandaCmd(const Vector& center, int an, double* a, int rn, Vector* r, double angle, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { createMarker(new Bpanda(this, center, an, a, rn, r, angle, color, dash, width, font, text, prop, comment, tag, cb)); } // Composite Regions void Base::createCompositeCmd(const Vector& center, double angle, int global, const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { Composite* m = new Composite(this, center, angle, global, color, dash, width, font, text, prop, comment, tag, cb); createMarker(m); compositeMarker = m; } void Base::createCompositeCmd( const char* color, int* dash, int width, const char* font, const char* text, unsigned short prop, const char* comment, const List<Tag>& tag, const List<CallBack>& cb) { // find center Vector cc; int cnt=0; Marker* m=markers->head(); while (m) { if (m->isSelected() && strncmp(m->getType(),"composite", 9)) { cc += m->getCenter(); cnt++; } m=m->next(); } cc /= cnt; // create composite Composite* mk = new Composite(this, cc, 0, 1, color, dash, width, font, text, prop, comment, tag, cb); createMarker(mk); // append members m=markers->head(); while (m) { if (m->isSelected() && strncmp(m->getType(),"composite",9)) { m->unselect(); Marker* next = markers->extractNext(m); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); mk->append(m); m = next; } else m=m->next(); } // all done mk->updateBBox(); mk->select(); update(PIXMAP); } // Template Regions void Base::createTemplateCmd(const Vector& center, const char* fn) { ifstream str(fn); if (!str) { result = TCL_ERROR; return; } createTemplate(center,str); } void Base::createTemplateCmd(const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky, const char* fn) { ifstream str(fn); if (!str) { result = TCL_ERROR; return; } createTemplate(currentContext->cfits->mapToRef(v, sys, sky),str); } void Base::createTemplateVarCmd(const Vector& center, const char* var) { Tcl_Obj* obj = Tcl_GetVar2Ex(interp, (char*)var, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (!obj) return; // just in case Tcl_ConvertToType(interp, obj, Tcl_GetObjType("bytearray")); typedef struct ByteArray { int used; /* The number of bytes used in the byte * array. */ int allocated; /* The amount of space actually allocated * minus 1 byte. */ unsigned char bytes[4]; /* The array of bytes. The actual size of * this field depends on the 'allocated' field * above. */ } ByteArray; Tcl_IncrRefCount(obj); // only make command string as long as needed // or the rest will be processed as garbage ByteArray* ba = (ByteArray*)(obj->internalRep.otherValuePtr); int len = ba->used+2; char* buf = new char[len]; memcpy(buf, (char*)ba->bytes, ba->used); Tcl_DecrRefCount(obj); // add terminator to make parser happy buf[len-2] = '\n'; buf[len-1] = NULL; string x(buf); istringstream istr(x); createTemplate(center,istr); delete [] buf; } void Base::createTemplate(const Vector& center, istream& str) { FitsImage* ptr = keyContext->fits; while (ptr) { ptr->initWCS0(center); ptr = ptr->nextMosaic(); } mkFlexLexer* ll = new mkFlexLexer(&str); mkparse(this, ll); delete ll; Marker* mk = compositeMarker; resetCompositeMarker(); ptr = keyContext->fits; while (ptr) { ptr->resetWCS0(); ptr = ptr->nextMosaic(); } if (mk) { mk->moveTo(center); update(PIXMAP, mk->getAllBBox()); // and return id printInteger(mk->getId()); } } // Support void Base::createMarker(Marker* m) { if (maperr) { Tcl_SetVar2(INTERP, "ds9", "msg", "Bad Coordinate mapping, unable to create some region(s).", TCL_GLOBAL_ONLY); Tcl_SetVar2(INTERP, "ds9", "msg,level", "warning", TCL_GLOBAL_ONLY); delete m; return; } if (compositeMarker) { compositeMarker->append(m); compositeMarker->updateBBox(); } else { markers->append(m); // now update new marker update(PIXMAP, m->getAllBBox()); // can't do this for windows, threads are weird // parser.Y and ds9parser.Y are not thread safe // *bad* exectute any Edit CallBacks // m->doCallBack(CallBack::EDITCB); // and return id printInteger(m->getId()); } } Vector Base::centroid(const Vector& vv) { FitsImage* ptr = currentContext->cfits; while (ptr) { Vector img = vv * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (img[0]>=params->xmin && img[0]<params->xmax && img[1]>=params->ymin && img[1]<params->ymax) break; ptr = ptr->nextMosaic(); } if (!ptr) return vv; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); int srcw = ptr->width(); Vector cd = vv * ptr->refToData; float rr = centroidRadius; float rr2 = rr*rr; // main loop SETSIGBUS for (int kk=0; kk<centroidIteration; kk++) { Vector sum; double weight =0; for (long jj=-rr; jj<=rr; jj++) { for (long ii=-rr; ii<=rr; ii++) { Vector aa = cd + Vector(ii,jj); if (aa[0]>=params->xmin && aa[0]<params->xmax && aa[1]>=params->ymin && aa[1]<params->ymax) { if (ii*ii+jj*jj <= rr2) { double val = ptr->getValueDouble(aa); // check for nan if (isfinite(val)) { sum += aa*val; weight += val; } } } } } if (weight>0) cd = sum/weight; else break; } CLEARSIGBUS return cd * ptr->dataToRef; } void Base::getMarkerAnalysisPlot2dCmd(int id, char* xname, char* yname, char* xcname, char* ycname, Coord::CoordSystem sys, Coord::SkyFrame sky, Marker::AnalysisMethod method) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysisPlot2d(xname, yname, xcname, ycname, sys, sky, method); return; } m=m->next(); } } void Base::getMarkerAnalysisPlot3dCmd(int id, char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysisPlot3d(xname, yname, sys, method); return; } m=m->next(); } } void Base::getMarkerAnalysisPandaCmd(int id, Coord::CoordSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysisPanda(sys); return; } m=m->next(); } } void Base::getMarkerAnalysisRadialCmd(int id, char* xname, char* yname, char* yename, Coord::CoordSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysisRadial(xname, yname, yename, sys); return; } m=m->next(); } } void Base::getMarkerAnalysisStatsCmd(int id, Coord::CoordSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysisStats(sys); return; } m=m->next(); } } void Base::getMarkerAngleCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { printDouble(radToDeg(m->getAngle()), DEFAULT); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerAngleCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { printDouble(radToDeg(mapAngleFromRef(m->getAngle(), sys, sky)), DEFAULT); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerAnnulusRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Annulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Annulus*)m)->annuli(i); markerPrintDouble(r[0], sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerAnnulusRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Annulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Annulus*)m)->annuli(i); markerPrintDouble(m->getCenter(), r[0], sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBoxAnnulusRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((BoxAnnulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { markerPrintVector(((BoxAnnulus*)m)->annuli(i), sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBoxAnnulusRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((BoxAnnulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { markerPrintVector(m->getCenter(), ((BoxAnnulus*)m)->annuli(i), sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBoxRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintVector(((Box*)m)->annuli(0), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBoxRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintVector(m->getCenter(), ((Box*)m)->annuli(0), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBpandaAnglesCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Bpanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(((Bpanda*)m)->angles(ii)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } } void Base::getMarkerBpandaAnglesCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Bpanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(mapAngleFromRef(((Bpanda*)m)->angles(ii),sys,sky)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } } void Base::getMarkerBpandaRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Bpanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Bpanda*)m)->annuli(i); markerPrintVector(((EllipseAnnulus*)m)->annuli(i), sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerBpandaRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Bpanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Bpanda*)m)->annuli(i); markerPrintVector(m->getCenter(), ((EllipseAnnulus*)m)->annuli(i), sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCenterCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), sys); return; } m=m->next(); } } void Base::getMarkerCenterCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), m->getCenter(), sys, sky, format); return; } m=m->next(); } } void Base::getMarkerCircleRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Vector r = ((Circle*)m)->annuli(0); markerPrintDouble(r[0],sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCircleRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Vector r = ((Circle*)m)->annuli(0); markerPrintDouble(m->getCenter(),r[0],sys,dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCpandaAnglesCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Cpanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(((Cpanda*)m)->angles(ii)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCpandaAnglesCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Cpanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(mapAngleFromRef(((Cpanda*)m)->angles(ii),sys,sky)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCpandaRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Cpanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Cpanda*)m)->annuli(i); markerPrintDouble(r[0], sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCpandaRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Cpanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Cpanda*)m)->annuli(i); markerPrintDouble(m->getCenter(), r[0], sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerColorCmd() { // return first found Marker* m=markers->head(); while (m) { if (m->isSelected()) { Tcl_AppendResult(interp, m->getColorName(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerColorCmd(const char* tag) { // return first found Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { Tcl_AppendResult(interp, m->getColorName(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerColorCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, m->getColorName(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompassArrowCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (((Compass*)m)->getNorthArrow()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); if (((Compass*)m)->getEastArrow()) Tcl_AppendResult(interp, " 1", NULL); else Tcl_AppendResult(interp, " 0", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompassLabelCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendElement(interp, ((Compass*)m)->getNorthText()); Tcl_AppendElement(interp, ((Compass*)m)->getEastText()); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompassRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { double r = ((Compass*)m)->getRadius(); markerPrintDouble(((Compass*)m)->getRadius(), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompassRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(),((Compass*)m)->getRadius(),sys,dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompassSystemCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { printCoordSystem(((Compass*)m)->getSystem()); Tcl_AppendResult(interp, " ", NULL); printSkyFrame(((Compass*)m)->getSkyFrame()); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerCompositeCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (((Composite*)m)->getGlobal()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } } void Base::getMarkerEllipseRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintVector(((Ellipse*)m)->annuli(0),sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerEllipseRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintVector(m->getCenter(),((Ellipse*)m)->annuli(0),sys,dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerEllipseAnnulusRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((EllipseAnnulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { markerPrintVector(((EllipseAnnulus*)m)->annuli(i), sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerEllipseAnnulusRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((EllipseAnnulus*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { markerPrintVector(m->getCenter(), ((EllipseAnnulus*)m)->annuli(i), sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerEpandaAnglesCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Epanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(((Epanda*)m)->angles(ii)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } } void Base::getMarkerEpandaAnglesCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Epanda*)m)->numAngles(); double first=0; for (int ii=0; ii<cnt; ii++) { double ang = radToDeg(mapAngleFromRef(((Epanda*)m)->angles(ii),sys,sky)); if (!ii) first = ang; else if (ang<=first+FLT_EPSILON) ang += 360; printDouble(ang, DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } } void Base::getMarkerEpandaRadiusCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Epanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Epanda*)m)->annuli(i); markerPrintVector(((EllipseAnnulus*)m)->annuli(i), sys); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerEpandaRadiusCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { int cnt = ((Epanda*)m)->numAnnuli(); for (int i=0; i<cnt; i++) { Vector r = ((Epanda*)m)->annuli(i); markerPrintVector(m->getCenter(), ((EllipseAnnulus*)m)->annuli(i), sys, dist); Tcl_AppendResult(interp, "\n", NULL); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerFontCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected()) { Tcl_AppendResult(interp, m->getFont(), NULL); return; } m=m->next(); } } void Base::getMarkerFontCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { Tcl_AppendResult(interp, m->getFont(), NULL); return; } m=m->next(); } } void Base::getMarkerFontCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, m->getFont(), NULL); return; } m=m->next(); } } void Base::getMarkerHandleCmd(const Vector& v) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { int h = m->onHandle(v); if (h) { ostringstream str; str << m->getId() << ' ' << h << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } } m=m->next(); } Tcl_AppendResult(interp, "0 0", NULL); } void Base::getMarkerIdCmd(const char* tag) { // return first found Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { printInteger(m->getId()); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerIdCmd(const Vector& v) { // v is in canvas coords Marker* m=markers->head(); while (m) { if (m->isIn(v)) { printInteger(m->getId()); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerIdAllCmd() { Marker* m=markers->head(); while (m) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); m=m->next(); } } void Base::getMarkerLineCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(((Line*)m)->getP1(), sys); markerPrintCoord(((Line*)m)->getP2(), sys); return; } m=m->next(); } } void Base::getMarkerLineCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), ((Line*)m)->getP1(), sys, sky, format); markerPrintCoord(m->getCenter(), ((Line*)m)->getP2(), sys, sky, format); return; } m=m->next(); } } void Base::getMarkerLineArrowCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (((Line*)m)->getP1Arrow()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); if (((Line*)m)->getP2Arrow()) Tcl_AppendResult(interp, " 1", NULL); else Tcl_AppendResult(interp, " 0", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerLineLengthCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(((Line*)m)->getP2(),((Line*)m)->getP1(), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerLineLengthCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(),((Line*)m)->getP2(),((Line*)m)->getP1(), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerLineWidthCmd() { // return first found Marker* m=markers->head(); while (m) { if (m->isSelected()) { ostringstream str; str << m->getLineWidth() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerLineWidthCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { ostringstream str; str << m->getLineWidth() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerMapLenFromRefCmd(int id, double d, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { FitsImage* ptr = findFits(sys,m->getCenter()); printDouble(ptr->mapLenFromRef(d,sys,dist), DEFAULT); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerPointShapeCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, ((Point*)m)->shape(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerPointSizeCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { printInteger(((Point*)m)->size()); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerPolygonSegmentCmd(const Vector& v) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { int s = m->getSegment(v); if (s) { ostringstream str; str << m->getId() << ' ' << s << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } } m=m->next(); } Tcl_AppendResult(interp, "0 0", NULL); } void Base::getMarkerPreserveCmd() { if (preserveMarkers) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerProjectionPointsCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(((Projection*)m)->getP1(), sys); markerPrintCoord(((Projection*)m)->getP2(), sys); return; } m=m->next(); } } void Base::getMarkerProjectionPointsCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), ((Projection*)m)->getP1(), sys, sky, format); markerPrintCoord(m->getCenter(), ((Projection*)m)->getP2(), sys, sky, format); return; } m=m->next(); } } void Base::getMarkerProjectionLengthCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(((Projection*)m)->getP2(), ((Projection*)m)->getP1(), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerProjectionLengthCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(), ((Projection*)m)->getP2(), ((Projection*)m)->getP1(), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerProjectionWidthCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(((Projection*)m)->getWidth(), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerProjectionWidthCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(), ((Projection*)m)->getWidth(), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerPropertyCmd(unsigned short which) { // return first selected found Marker* m=markers->head(); while (m) { if (m->isSelected()) { m->getProperty(which) ? Tcl_AppendResult(interp, "1", NULL): Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } // else, return 'off' Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerPropertyCmd(const char* tag, unsigned short which) { // return first selected found Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { m->getProperty(which) ? Tcl_AppendResult(interp, "1", NULL): Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } // else, return 'off' Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerPropertyCmd(int id, unsigned short which) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->getProperty(which) ? Tcl_AppendResult(interp, "1", NULL): Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } // else, return 'off' Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerRulerLengthCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(((Ruler*)m)->getP2(),((Ruler*)m)->getP1(),sys); Tcl_AppendResult(interp, " ", NULL); markerPrintDouble(((Ruler*)m)->getP3(),((Ruler*)m)->getP1(),sys); Tcl_AppendResult(interp, " ", NULL); markerPrintDouble(((Ruler*)m)->getP3(),((Ruler*)m)->getP2(),sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerRulerLengthCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(), ((Ruler*)m)->getP2(), ((Ruler*)m)->getP1(), sys, dist); Tcl_AppendResult(interp, " ", NULL); markerPrintDouble(m->getCenter(), ((Ruler*)m)->getP3(), ((Ruler*)m)->getP1(), sys, dist); Tcl_AppendResult(interp, " ", NULL); markerPrintDouble(m->getCenter(), ((Ruler*)m)->getP3(), ((Ruler*)m)->getP2(), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerRulerPointCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(((Ruler*)m)->getP1(), sys); markerPrintCoord(((Ruler*)m)->getP2(), sys); return; } m=m->next(); } } void Base::getMarkerRulerPointCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), ((Ruler*)m)->getP1(), sys, sky, format); markerPrintCoord(m->getCenter(), ((Ruler*)m)->getP2(), sys, sky, format); return; } m=m->next(); } } void Base::getMarkerRulerSystemCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { printCoordSystem(((Ruler*)m)->getSystem()); Tcl_AppendResult(interp, " ", NULL); printSkyFrame(((Ruler*)m)->getSkyFrame()); Tcl_AppendResult(interp, " ", NULL); printCoordSystem(((Ruler*)m)->getDistSystem()); Tcl_AppendResult(interp, " ", NULL); printSkyDist(((Ruler*)m)->getDistDist()); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerSelectedCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected()) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } m=m->next(); } } void Base::getMarkerSelectedCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->isSelected()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } } void Base::getMarkerSelectedCmd(const Vector& v) { Marker* m=markers->head(); while (m) { if (m->isIn(v) && m->isSelected()) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerNumberCmd() { int count=0; Marker* m=markers->head(); while (m) { count++; m=m->next(); } printInteger(count); } void Base::getMarkerSelectedNumberCmd() { int count=0; Marker* m=markers->head(); while (m) { if (m->isSelected()) count++; m=m->next(); } printInteger(count); } void Base::getMarkerHighlitedCmd() { Marker* m=markers->head(); while (m) { if (m->isHighlited()) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } m=m->next(); } } void Base::getMarkerHighlitedCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->isHighlited()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } } void Base::getMarkerHighlitedCmd(const Vector& v) { Marker* m=markers->head(); while (m) { if (m->isIn(v) && m->isHighlited()) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerHighlitedNumberCmd() { int count=0; Marker* m=markers->head(); while (m) { if (m->isHighlited()) count++; m=m->next(); } printInteger(count); } void Base::getMarkerShowCmd() { if (showMarkers) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerShowTextCmd() { if (showMarkersText) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerCentroidAutoCmd() { if (centroidAuto) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getMarkerCentroidRadiusCmd() { ostringstream str; str << centroidRadius << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getMarkerCentroidIterationCmd() { ostringstream str; str << centroidIteration << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } // backup compatibility void Base::getMarkerCentroidOptionCmd() { ostringstream str; str << centroidIteration << centroidRadius << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getMarkerTagCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { ostringstream str; str << m->getId() << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } m=m->next(); } } void Base::getMarkerTagCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { const char* r = m->getTag(); while (r) { Tcl_AppendElement(interp, r); r = m->getNextTag(); } return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerTagCmd(int id, int num) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, m->getTag(num), NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerTagDefaultNameCmd() { int cnt = 1; again: ostringstream str; str << "Group " << cnt << ends; Marker* m = markers->head(); while (m) { if (m->hasTag(str.str().c_str())) { cnt++; goto again; } m=m->next(); } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getMarkerTagNumberCmd(const char* tag) { // return number of markers with tag int count=0; Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) count++; m=m->next(); } printInteger(count); } void Base::getMarkerTagsCmd() { // return all tags List<Tag> tags; // loop thru all markers Marker* m=markers->head(); while (m) { // loop thru all tags in markers const char* t = m->getTag(); while (t) { // loop thru our current list int found = 0; Tag* tt = tags.head(); while (tt) { if (!strcmp(tt->tag(), t)) { found =1; break; } tt = tt->next(); } // didn't find it, add it to the list if (!found) { tags.append(new Tag(t)); } t=m->getNextTag(); } m=m->next(); } // now sort // ok, dump the tags Tag* tt = tags.head(); while (tt) { Tcl_AppendElement(interp, tt->tag()); tt=tt->next(); } } void Base::getMarkerTextCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, m->getText(), NULL); return; } m=m->next(); } } void Base::getMarkerTextRotateCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (((Text*)m)->getRotate()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerTypeCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { Tcl_AppendResult(interp, m->getType(), NULL); return; } m=m->next(); } } void Base::getMarkerVectorCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(((Line*)m)->getP1(), sys); return; } m=m->next(); } } void Base::getMarkerVectorCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintCoord(m->getCenter(), ((Line*)m)->getP1(), sys, sky, format); return; } m=m->next(); } } void Base::getMarkerVectorArrowCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (((Vect*)m)->getArrow()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerVectorLengthCmd(int id, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(((Vect*)m)->getP2(), ((Vect*)m)->getP1(), sys); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::getMarkerVectorLengthCmd(int id, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { markerPrintDouble(m->getCenter(), ((Vect*)m)->getP2(), ((Vect*)m)->getP1(), sys, dist); return; } m=m->next(); } Tcl_AppendResult(interp, "", NULL); } void Base::hasMarkerHighlitedCmd() { Marker* m=markers->head(); while (m) { if (m->isHighlited()) { Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::hasMarkerPasteCmd() { if (!pasteMarkers->isEmpty()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasMarkerSelectedCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected()) { Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::hasMarkerUndoCmd() { if (!undoMarkers->isEmpty()) switch (undoMarkerType) { case MOVE: Tcl_AppendResult(interp, "move", NULL); return; case EDIT: Tcl_AppendResult(interp, "edit", NULL); return; case DELETE: Tcl_AppendResult(interp, "delete", NULL); return; default: Tcl_AppendResult(interp, "", NULL); return; } else Tcl_AppendResult(interp, "", NULL); } void Base::markerLayerCmd(MarkerLayer layer) { switch (layer) { case USER: markers = &userMarkers; undoMarkers = &undoUserMarkers; pasteMarkers = &pasteUserMarkers; break; case CATALOG: markers = &catalogMarkers; undoMarkers = &undoCatalogMarkers; pasteMarkers = &pasteCatalogMarkers; break; } } void Base::markerAnalysisCmd(int id, Marker::AnalysisTask aa, int which) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->analysis(aa,which); return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAngleCmd(int id, double angle) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canRotate()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); m->setAngle(angle); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAngleCmd(int id, double angle, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canRotate()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); m->setAngle(mapAngleToRef(angle,sys,sky)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAnnulusCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Annulus*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAnnulusDeleteRadiusCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Annulus*)m)->deleteAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerAnnulusRadiusCmd(int id, double inner, double outer, int num, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); double r1 = mapLenToRef(inner,sys); double r2 = mapLenToRef(outer,sys); ((Annulus*)m)->setAnnuli(Vector(r1,r1),Vector(r2,r2),num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAnnulusRadiusCmd(int id, double inner, double outer, int num, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); double r1 = ptr->mapLenToRef(inner, sys, dist); double r2 = ptr->mapLenToRef(outer, sys, dist); ((Annulus*)m)->setAnnuli(Vector(r1,r1),Vector(r2,r2),num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerAnnulusRadiusCmd(int id, const char* lev, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int cnt = 0; Vector radii[MAXANNULI]; string x(lev); istringstream str(x); while ((cnt<MAXANNULI) && (str >> radii[cnt][0])) { radii[cnt][1] = radii[cnt][0]; ++cnt; } FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<cnt; i++) radii[i] = ptr->mapLenToRef(radii[i], sys, dist); ((Annulus*)m)->setAnnuli(radii,cnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBackCmd() { Marker* m = markers->tail(); while (m) { if (m->isSelected()) { Marker* prev = markers->extractPrev(m); markers->append(m); update(PIXMAP, m->getAllBBox()); m = prev; } else m=m->previous(); } } void Base::markerBackCmd(const char* tag) { Marker* m = markers->tail(); while (m) { if (m->hasTag(tag)) { Marker* prev = markers->extractPrev(m); markers->append(m); update(PIXMAP, m->getAllBBox()); m = prev; } else m=m->previous(); } } void Base::markerBackCmd(int id) { Marker* m = markers->tail(); while (m) { if (m->getId() == id) { markers->extractPrev(m); markers->append(m); update(PIXMAP, m->getAllBBox()); return; } else m=m->previous(); } } void Base::markerBoxAnnulusRadiusCmd(int id, const Vector& inner, const Vector& outer, int num, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); Vector s1 = mapLenToRef(inner, sys); Vector s2 = mapLenToRef(outer, sys); ((BoxAnnulus*)(m))->setAnnuli(s1,s2,num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBoxAnnulusRadiusCmd(int id, const Vector& inner, const Vector& outer, int num, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); Vector s1 = ptr->mapLenToRef(inner, sys, dist); Vector s2 = ptr->mapLenToRef(outer, sys, dist); ((BoxAnnulus*)(m))->setAnnuli(s1,s2,num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBoxAnnulusRadiusCmd(int id,const char* lev, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int cnt = 0; Vector size[MAXANNULI]; string x(lev); istringstream str(x); while ((cnt<MAXANNULI) && (str >> size[cnt][0])) str >> size[cnt++][1]; // verify proper ratios for (int i=0; i<cnt; i++) size[i][1] = size[i][0]*size[cnt-1][1]/size[cnt-1][0]; // map to ref coord sys FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<cnt; i++) size[i] = ptr->mapLenToRef(size[i], sys, dist); ((BoxAnnulus*)m)->setAnnuli(size,cnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBoxAnnulusCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((BoxAnnulus*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBoxAnnulusDeleteRadiusCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((BoxAnnulus*)m)->deleteAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerBoxRadiusCmd(int id, const Vector& size, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Box*)(m))->setAnnuli(mapLenToRef(size, sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBoxRadiusCmd(int id, const Vector& size, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Box*)(m))->setAnnuli(ptr->mapLenToRef(size, sys, dist)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBpandaCreateAnglesCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Bpanda*)m)->addAngles(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBpandaCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Bpanda*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBpandaDeleteCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Bpanda*)m)->deleteAnglesAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerBpandaEditCmd(int id, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Bpanda*)m)->setAnglesAnnuli(a1,a2,an,r1,r2,rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBpandaEditCmd(int id, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Bpanda*)m)->setAnglesAnnuli(mapAngleToRef(a1,sys,sky), mapAngleToRef(a2,sys,sky),an,r1,r2,rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerBpandaEditCmd(int id, const char* a, const char* r, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem rsys, Coord::SkyDist rdist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int acnt = 0; double angles[MAXANGLES]; { string x(a); istringstream astr(x); while ((acnt<MAXANGLES) && (astr >> angles[acnt])) ++acnt; } for (int i=0; i<acnt; i++) angles[i] = mapAngleToRef(degToRad(angles[i]),sys,sky); int rcnt = 0; Vector radii[MAXANNULI]; { string x(r); istringstream rstr(x); while ((rcnt<MAXANNULI) && (rstr >> radii[rcnt][0])) rstr >> radii[rcnt++][1]; } // verify proper ratios for (int i=0; i<rcnt; i++) radii[i][1] = radii[i][0]*radii[rcnt-1][1]/radii[rcnt-1][0]; // map to ref coord sys FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<rcnt; i++) radii[i] = ptr->mapLenToRef(radii[i], rsys, rdist); ((Bpanda*)m)->setAnglesAnnuli(angles,acnt,radii,rcnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCallBackCmd(int id, CallBack::Type cb, const char* p, const char* a) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { result = m->addCallBack(cb, p, a); return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCentroidCmd() { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); m->centroid(); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerCentroidCmd(const char* tag) { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->canMove() && m->hasTag(tag)) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); m->centroid(); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerCentroidCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) { markerUndo(m, MOVE); update(PIXMAP, m->getAllBBox()); m->centroid(); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerCentroidAutoCmd(int which) { centroidAuto = which; } void Base::markerCentroidRadiusCmd(float rad) { centroidRadius = rad; } void Base::markerCentroidIterationCmd(int iter) { centroidIteration = iter; } void Base::markerCircleRadiusCmd(int id, double radius,Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); double r = mapLenToRef(radius, sys); ((Circle*)m)->setAnnuli(Vector(r,r)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCircleRadiusCmd(int id, double radius, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); double r = ptr->mapLenToRef(radius, sys, dist); ((Circle*)m)->setAnnuli(Vector(r,r)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerColorCmd(const char* clr) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { m->setColor(clr); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerColorCmd(const char* tag, const char* clr) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { m->setColor(clr); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerColorCmd(int id, const char* clr) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->setColor(clr); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } } void Base::markerCommandCmd(MarkerFormat fm, const char* ccmd) { // only make command string as long as needed // or the rest will be processed as garbage int len = strlen(ccmd)+2; char* buf = new char[len]; memcpy(buf, ccmd, len); // add terminator to make parser happy buf[len-2] = '\n'; buf[len-1] = NULL; string x(buf); istringstream istr(x); parseMarker(fm, istr); delete [] buf; } void Base::markerCommandVarCmd(MarkerFormat fm, const char* var) { const char* ccmd = Tcl_GetVar(interp, var, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (!ccmd) { result = TCL_ERROR; return; } // only make command string as long as needed // or the rest will be processed as garbage int len = strlen(ccmd)+2; char* buf = new char[len]; memcpy(buf, ccmd, len); // add terminator to make parser happy buf[len-2] = '\n'; buf[len-1] = NULL; string x(buf); istringstream istr(x); parseMarker(fm, istr); delete [] buf; } void Base::markerCompassArrowCmd(int id, int n, int e) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { ((Compass*)(m))->setArrows(n, e); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompassLabelCmd(int id, const char* n, const char* e) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { // it may shrink update(PIXMAP, m->getAllBBox()); ((Compass*)(m))->setLabels(n, e); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompassRadiusCmd(int id, double r, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); double rr = mapLenToRef(r, sys); ((Compass*)m)->setRadius(rr); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompassRadiusCmd(int id, double r, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); double rr = ptr->mapLenToRef(r, sys, dist); ((Compass*)m)->setRadius(rr); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompassSystemCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { // it may shrink update(PIXMAP, m->getAllBBox()); ((Compass*)(m))->setCoordSystem(sys, sky); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompositeCmd(int id, int gl) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { ((Composite*)(m))->setGlobal(gl); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCompositeDeleteCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected() && !strncmp(m->getType(),"composite",9)) { Marker* mm = ((Composite*)m)->extract(); while (mm) { markers->append(mm); mm = ((Composite*)m)->extract(); } Marker* next = markers->extractNext(m); delete m; m = next; update(PIXMAP); } else m=m->next(); } } void Base::markerCopyCmd() { undoMarkers->deleteAll(); pasteMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->isSelected()) pasteMarkers->append(m->dup()); m=m->next(); } } void Base::markerCopyCmd(const char* tag) { undoMarkers->deleteAll(); pasteMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->hasTag(tag)) pasteMarkers->append(m->dup()); m=m->next(); } } void Base::markerCpandaCreateAnglesCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Cpanda*)m)->addAngles(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCpandaCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Cpanda*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCpandaDeleteCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Cpanda*)m)->deleteAnglesAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerCpandaEditCmd(int id, double a1, double a2, int an, double r1, double r2, int rn) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Cpanda*)m)->setAnglesAnnuli(a1,a2,an,Vector(r1,r1),Vector(r2,r2),rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCpandaEditCmd(int id, double a1, double a2, int an, double r1, double r2, int rn, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Cpanda*)m)->setAnglesAnnuli(mapAngleToRef(a1,sys,sky), mapAngleToRef(a2,sys,sky), an, Vector(r1,r1),Vector(r2,r2),rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCpandaEditCmd(int id, const char* a, const char* r, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem rsys, Coord::SkyDist rdist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int acnt = 0; double angles[MAXANGLES]; { string x(a); istringstream astr(x); while ((acnt<MAXANGLES) && (astr >> angles[acnt])) ++acnt; } { for (int i=0; i<acnt; i++) angles[i] = mapAngleToRef(degToRad(angles[i]),sys,sky); } int rcnt = 0; Vector radii[MAXANNULI]; { string x(r); istringstream rstr(x); while ((rcnt<MAXANNULI) && (rstr >> radii[rcnt][0])) { radii[rcnt][1] = radii[rcnt][0]; ++rcnt; } } { FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<rcnt; i++) radii[i] = ptr->mapLenToRef(radii[i], rsys, rdist); } ((Cpanda*)m)->setAnglesAnnuli(angles,acnt,radii,rcnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerCutCmd() { undoMarkers->deleteAll(); pasteMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->isSelected() && m->canDelete()) { Marker* next = markers->extractNext(m); update(PIXMAP); pasteMarkers->append(m); m->doCallBack(CallBack::DELETECB); m->disableCB(); m = next; } else m=m->next(); } } void Base::markerCutCmd(const char* tag) { undoMarkers->deleteAll(); pasteMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->canDelete() && m->hasTag(tag)) { Marker* next = markers->extractNext(m); update(PIXMAP); pasteMarkers->append(m); m->doCallBack(CallBack::DELETECB); m->disableCB(); m = next; } else m=m->next(); } } void Base::markerDeleteCallBackCmd(int id, CallBack::Type cb, const char* p) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { result = m->deleteCallBack(cb, p); return; } m=m->next(); } result = TCL_ERROR; } void Base::markerDeleteCmd() { undoMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->isSelected() && m->canDelete()) { Marker* next = markers->extractNext(m); update(PIXMAP); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); undoMarkers->append(m); undoMarkerType = DELETE; m = next; } else m=m->next(); } } void Base::markerDeleteCmd(const char* tag) { undoMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->canDelete() && m->hasTag(tag)) { Marker* next = markers->extractNext(m); update(PIXMAP); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); undoMarkers->append(m); undoMarkerType = DELETE; m = next; } else m=m->next(); } } void Base::markerDeleteCmd(int id) { undoMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->getId() == id) { if (m->canDelete()) { markers->extractNext(m); update(PIXMAP); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); undoMarkers->append(m); undoMarkerType = DELETE; } return; } else m=m->next(); } } void Base::markerDeleteAllCmd() { undoMarkers->deleteAll(); Marker* m = markers->head(); while (m) { if (m->canDelete()) { update(PIXMAP); Marker* next = markers->extractNext(m); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); undoMarkers->append(m); undoMarkerType = DELETE; m = next; } else m=m->next(); } } void Base::markerDeleteLastCmd() { undoMarkers->deleteAll(); Marker* m=markers->tail(); if (m && m->canDelete()) { markers->extractNext(m); update(PIXMAP); m->doCallBack(CallBack::DELETECB); m->deleteCBs(); undoMarkers->append(m); undoMarkerType = DELETE; return; } } void Base::markerDeleteTagCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canDelete()) m->deleteTags(); return; } m=m->next(); } } void Base::markerDeleteTagCmd(int id, const char* tag) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canDelete()) m->deleteTag(tag); return; } m=m->next(); } } void Base::markerDeleteTagCmd(int id, int which) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canDelete()) m->deleteTag(which); return; } m=m->next(); } } void Base::markerEditBeginCmd(int id, int h) { // remember which marker is being edited Marker* m=markers->head(); while (m) { if (m->getId() == id && m->canEdit()) { markerUndo(m, EDIT); editMarker = m; editMarker->editBegin(h); return; } m=m->next(); } editMarker = NULL; } void Base::markerEditBeginCmd(const Vector& v, int h) { // remember which marker is being edited Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canEdit()) { markerUndo(m, EDIT); editMarker = m; editMarker->editBegin(h); return; } m=m->next(); } editMarker = NULL; } void Base::markerEditMotionCmd(const Vector& vv, int hh) { if (editMarker) { // erase current marker now redraw(editMarker->getAllBBox()); forceUpdate(); editMarker->edit(mapToRef(vv,Coord::CANVAS), hh); x11MarkerXOR(editMarker); } } void Base::markerEditEndCmd() { if (editMarker) editMarker->editEnd(); editMarker = NULL; update(PIXMAP); } void Base::markerEllipseRadiusCmd(int id, const Vector& radius, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); Vector r = mapLenToRef(radius, sys); ((Ellipse*)m)->setAnnuli(r); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseRadiusCmd(int id, const Vector& radius, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); Vector r = ptr->mapLenToRef(radius, sys, dist); ((Ellipse*)m)->setAnnuli(r); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseAnnulusRadiusCmd(int id, const Vector& inner, const Vector& outer, int num, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); Vector r1 = mapLenToRef(inner, sys); Vector r2 = mapLenToRef(outer, sys); ((EllipseAnnulus*)(m))->setAnnuli(r1,r2,num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseAnnulusRadiusCmd(int id, const Vector& inner, const Vector& outer, int num, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); Vector r1 = ptr->mapLenToRef(inner, sys, dist); Vector r2 = ptr->mapLenToRef(outer, sys, dist); ((EllipseAnnulus*)(m))->setAnnuli(r1,r2,num); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseAnnulusRadiusCmd(int id, const char* lev, Coord::CoordSystem sys,Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int cnt = 0; Vector radii[MAXANNULI]; string x(lev); istringstream str(x); while ((cnt<MAXANNULI) && (str >> radii[cnt][0])) str >> radii[cnt++][1]; // verify proper ratios for (int i=0; i<cnt; i++) radii[i][1] = radii[i][0]*radii[cnt-1][1]/radii[cnt-1][0]; // map to ref coord sys FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<cnt; i++) radii[i] = ptr->mapLenToRef(radii[i], sys, dist); ((EllipseAnnulus*)(m))->setAnnuli(radii,cnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseAnnulusCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((EllipseAnnulus*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEllipseAnnulusDeleteRadiusCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((EllipseAnnulus*)m)->deleteAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerEpandaCreateAnglesCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Epanda*)m)->addAngles(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEpandaCreateRadiusCmd(int id, const Vector& vv) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); printInteger(((Epanda*)m)->addAnnuli(mapToRef(vv,Coord::CANVAS))); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEpandaDeleteCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Epanda*)m)->deleteAnglesAnnuli(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerEpandaEditCmd(int id, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Epanda*)m)->setAnglesAnnuli(a1,a2,an,r1,r2,rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEpandaEditCmd(int id, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Epanda*)m)->setAnglesAnnuli(mapAngleToRef(a1,sys,sky), mapAngleToRef(a2,sys,sky),an,r1,r2,rn); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerEpandaEditCmd(int id, const char* a, const char* r, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem rsys, Coord::SkyDist rdist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); int acnt = 0; double angles[MAXANGLES]; { string x(a); istringstream astr(x); while ((acnt<MAXANGLES) && (astr >> angles[acnt])) ++acnt; } for (int i=0; i<acnt; i++) angles[i] = mapAngleToRef(degToRad(angles[i]),sys,sky); int rcnt = 0; Vector radii[MAXANNULI]; { string x(r); istringstream rstr(x); while ((rcnt<MAXANNULI) && (rstr >> radii[rcnt][0])) rstr >> radii[rcnt++][1]; } // verify proper ratios for (int i=0; i<rcnt; i++) radii[i][1] = radii[i][0]*radii[rcnt-1][1]/radii[rcnt-1][0]; // map to ref coord sys FitsImage* ptr = findFits(sys,m->getCenter()); for (int i=0; i<rcnt; i++) radii[i] = ptr->mapLenToRef(radii[i], rsys, rdist); ((Epanda*)m)->setAnglesAnnuli(angles,acnt,radii,rcnt); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerHighliteAllCmd() { Marker* m=markers->head(); while (m) { if (m->canHighlite()) { m->highlite(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerHighliteCmd(int id) { Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->getId() == id) { m->highlite(); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } } void Base::markerHighliteCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->hasTag(tag)) { m->highlite(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerHighliteToggleCmd(const Vector& v) { // toggle the highlite of the first found Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->isIn(v)) { m->toggleHighlite(); update(PIXMAP, m->getBBox()); Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::markerHighliteOnlyCmd(int id) { Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->getId() == id) { if (!m->isHighlited()) { m->highlite(); update(PIXMAP, m->getBBox()); } } else { if (m->isHighlited()) { m->unhighlite(); update(PIXMAP, m->getBBox()); } } m=m->next(); } } void Base::markerHighliteOnlyCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->hasTag(tag)) if (!m->isHighlited()) { m->highlite(); update(PIXMAP, m->getBBox()); } else if (m->isHighlited()) { m->unhighlite(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerHighliteOnlyCmd(const Vector& v) { // first, check to see if we clicked on an already highlited marker Marker* m=markers->head(); while (m) { if (m->canHighlite() && m->isIn(v) && m->isHighlited()) { Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } // ok, now highlite the first found, and unhighlite the rest int found = 0; m=markers->head(); while (m) { if (m->canHighlite() && m->isIn(v) && !found) { if (!m->isHighlited()) { m->highlite(); update(PIXMAP, m->getBBox()); } found = 1; } else { if (m->isHighlited()) { m->unhighlite(); update(PIXMAP, m->getBBox()); } } m=m->next(); } if (found) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::markerFontCmd(const char* f) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { // things can shrink, so do before and after update(PIXMAP, m->getAllBBox()); m->setFont(f); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerFontCmd(const char* tag, const char* f) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { // things can shrink, so do before and after update(PIXMAP, m->getAllBBox()); m->setFont(f); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerFontCmd(int id, const char* f) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { // things can shrink, so do before and after update(PIXMAP, m->getAllBBox()); m->setFont(f); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } } void Base::markerFrontCmd() { Marker* m = markers->head(); while (m) { if (m->isSelected()) { Marker* next = markers->extractNext(m); markers->insertHead(m); update(PIXMAP, m->getAllBBox()); m = next; } else m=m->next(); } } void Base::markerFrontCmd(const char* tag) { Marker* m = markers->head(); while (m) { if (m->hasTag(tag)) { Marker* next = markers->extractNext(m); markers->insertHead(m); update(PIXMAP, m->getAllBBox()); m = next; } else m=m->next(); } } void Base::markerFrontCmd(int id) { Marker* m = markers->head(); while (m) { if (m->getId() == id) { markers->extractNext(m); markers->insertHead(m); update(PIXMAP, m->getAllBBox()); return; } else m=m->next(); } } void Base::markerKeyCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected()) m->key(); m=m->next(); } } void Base::markerKeyCmd(const Vector& v) { // v is in canvas coords Marker* m=markers->head(); while (m) { if (m->isIn(v)) m->key(); m=m->next(); } } void Base::markerLineCmd(int id, const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Line*)(m))->setPoints(mapToRef(p1,sys),mapToRef(p2,sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerLineCmd(int id, const Vector& p1, const Vector& p2, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Line*)(m))->setPoints(ptr->mapToRef(p1,sys,sky), ptr->mapToRef(p2,sys,sky)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerLineArrowCmd(int id, int p1, int p2) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { ((Line*)(m))->setArrows(p1, p2); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerLineWidthCmd(int w) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { m->setLineWidth(w); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerLineWidthCmd(int id, int w) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->setLineWidth(w); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } } void Base::markerListCmd(MarkerFormat type, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip, int select, unsigned short mask, unsigned short value, List<Tag>& tags) { int doSys = 1; switch (type) { case DS9: { ostringstream str; markerListHeader(str, sys, sky, format, strip); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } break; case XML: { ostringstream str; markerListXMLHeader(str, sys, sky, format); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } break; case CIAO: { ostringstream str; markerListCiaoHeader(str, sys, sky, format, strip); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } break; case SAOTNG: { ostringstream str; markerListSAOtngHeader(str, sys, sky, format, strip); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } break; case PROS: break; case SAOIMAGE: break; case RAWXY: break; } Marker* m=markers->head(); while (m) { ostringstream str; Tag* t; // selected if (select) { if (!m->isSelected()) goto next; } // properties if (mask) { if (!((m->getProperty() & mask) == value)) goto next; } // tags if (t=tags.head()) { while (t) { if (!m->hasTag(t->tag())) goto next; t=t->next(); } } // ok, its passed the tests! switch (type) { case DS9: if (doSys) { coord.listCoordSystem(str, sys, sky, 1, keyContext->fits->hasWCSCel(sys)); str << (strip ? ';' : '\n'); doSys = 0; } m->list(str, sys, sky, format, 0, strip); break; case XML: m->listXML(str, sys, sky, format); break; case CIAO: m->listCiao(str, sys, strip); break; case SAOTNG: m->listSAOtng(str, sys, sky, format, strip); break; case SAOIMAGE: m->listSAOimage(str, strip); break; case PROS: m->listPros(str, sys, sky, format, strip); break; case RAWXY: m->listXY(str, sys, sky, format, strip); break; } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); next: m=m->next(); } switch (type) { case DS9: break; case XML: { ostringstream str; markerListXMLFooter(str); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } break; case CIAO: break; case SAOTNG: break; case PROS: break; case SAOIMAGE: break; case RAWXY: break; } } void Base::markerLoadCmd(MarkerFormat fm, const char* fn) { ifstream str(fn); if (!str) { result = TCL_ERROR; return; } parseMarker(fm, str); } void Base::markerLoadCmd(MarkerFormat fm, const char* fn, Coord::CoordSystem sys, Coord::SkyFrame sky) { xySystem_ = sys; xySky_ = sky; markerLoadCmd(fm,fn); } void Base::markerLoadCmd(MarkerFormat fm, int fd) { boost::fdistream str(fd); if (!str) { result = TCL_ERROR; return; } parseMarker(fm, str); } void Base::markerLoadCmd(MarkerFormat fm, int fd, Coord::CoordSystem sys, Coord::SkyFrame sky) { xySystem_ = sys; xySky_ = sky; markerLoadCmd(fm,fd); } void Base::markerLoadFitsCmd(const char* fn, const char* color, int* dash, int width, const char* font) { if (!keyContext->fits) return; // verify that we have an ext specified if (fn && (fn[strlen(fn)-1] != ']')) { result = TCL_ERROR; return; } // do we have a WCS? FitsImage* mkfits = NULL; { FitsHist::Function savBinFunction = binFunction_; int savBinBufferSize = binBufferSize_; int savBinDepth = binDepth_; Vector savBinFactor = binFactor_; mkfits = new FitsImageFitsMMap(this, fn, 1); if (!mkfits || !mkfits->isValid() || !mkfits->isBinTable()) { if (mkfits) delete mkfits; result = TCL_ERROR; return; } } // recenter if (keyContext->fits) { FitsImage* ptr = keyContext->fits; mkfits->nextHist(ptr->getHistCursor()); } FitsFile* mk = mkfits->fitsFile(); FitsHead* mkh = mk->head(); FitsTableHDU* mkhdu = (FitsTableHDU*)mkh->hdu(); // determine x and y column names // if image, hard code 'x' and 'y' // however, if table, find out the columns used to bin FitsColumn* x; FitsColumn* y; if (keyContext->fits) { FitsImage* ptr = keyContext->fits; if (ptr->isHist()) { x = mkhdu->find(ptr->getHistX()); y = mkhdu->find(ptr->getHistY()); } else { x = mkhdu->find("x"); y = mkhdu->find("y"); } } else { x = mkhdu->find("x"); y = mkhdu->find("y"); } FitsColumn* shape = mkhdu->find("shape"); FitsColumn* r = mkhdu->find("r"); FitsColumn* ang = mkhdu->find("rotang"); // manatory columns x and y if (!x || !y) { if (mkfits) delete mkfits; result = TCL_ERROR; return; } // and width should be the same if (((FitsBinColumn*)x)->repeat() != ((FitsBinColumn*)y)->repeat()) { if (mkfits) delete mkfits; result = TCL_ERROR; return; } int repeat = ((FitsBinColumn*)x)->repeat(); char* ptr = (char*)mk->data(); int rows = mkhdu->rows(); int rowlen = mkhdu->width(); char text[] = ""; List<Tag> taglist; List<CallBack> cblist; for (int i=0; i<rows; i++, ptr+=rowlen) { char* s1; if (shape) s1 = toUpper(shape->str(ptr)); else { s1 = new char[7]; strcpy(s1,"POINT "); } // look for '!', which sets include/exclude char* s2 = s1; unsigned short props = Marker::SELECT | Marker::HIGHLITE | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::SOURCE; if (s2[0]=='!') s2++; else props |= Marker::INCLUDE; Vector center(x->value(ptr,0),y->value(ptr,0)); if (!strncmp(s2, "CIRCLE", 6) && r) { Vector rr(r->value(ptr),0); createCircleCmd(keyContext->fits->mapToRef(center, Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr[0], Coord::PHYSICAL), color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "ANNULU", 6) && r) { Vector rr0(r->value(ptr,0),0); Vector rr1(r->value(ptr,1),0); createAnnulusCmd(keyContext->fits->mapToRef(center ,Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr1[0], Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr0[0], Coord::PHYSICAL), 1, color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "BOX ", 6) && r) { Vector rr(r->value(ptr,0),r->value(ptr,1)); createBoxCmd(keyContext->fits->mapToRef(center, Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr, Coord::PHYSICAL), 0, color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "ROTBOX", 6) && r && ang) { Vector rr(r->value(ptr,0),r->value(ptr,1)); createBoxCmd(keyContext->fits->mapToRef(center, Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr, Coord::PHYSICAL), degToRad(ang->value(ptr)), color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "RECTAN", 6)) { Vector v1(center); Vector v2(x->value(ptr,1), y->value(ptr,1)); Vector d = v2-v1; Vector c = d/2 + v1; createBoxCmd(keyContext->fits->mapToRef(c,Coord::PHYSICAL), keyContext->fits->mapLenToRef(d,Coord::PHYSICAL), 0, color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "ROTREC", 6) && ang) { Vector v1(center); Vector v2(x->value(ptr,1), y->value(ptr,1)); Vector d = v2-v1; Vector c = d/2 + v1; createBoxCmd(keyContext->fits->mapToRef(c,Coord::PHYSICAL), keyContext->fits->mapLenToRef(d,Coord::PHYSICAL), degToRad(ang->value(ptr)), color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "ELLIPS", 6) && r && ang) { Vector rr(r->value(ptr,0),r->value(ptr,1)); createEllipseCmd(keyContext->fits->mapToRef(center, Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr, Coord::PHYSICAL), degToRad(ang->value(ptr)), color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "PIE ", 6) && r && ang) { Vector rr0(r->value(ptr,0),0); Vector rr1(r->value(ptr,1),0); createCpandaCmd(keyContext->fits->mapToRef(center,Coord::PHYSICAL), degToRad(ang->value(ptr,0)-90), degToRad(ang->value(ptr,1)-90), 1, keyContext->fits->mapLenToRef(rr1[0],Coord::PHYSICAL), keyContext->fits->mapLenToRef(rr0[0],Coord::PHYSICAL), 1, color, dash, width, font, text, props, NULL, taglist,cblist); } else if (!strncmp(s2, "POINT ", 6)) createPointCmd(keyContext->fits->mapToRef(center,Coord::PHYSICAL), Point::BOXCIRCLE, POINTSIZE, color, dash, width, font, text, props, NULL, taglist,cblist); else if (!strncmp(s2, "POLYGO", 6)) { List<Vertex> list; for (int ii=0; ii<repeat; ii++) { Vector vv(x->value(ptr,ii), y->value(ptr,ii)); Vertex* n = new Vertex(keyContext->fits->mapToRef(vv, Coord::PHYSICAL)); if (ii+1 < repeat) { // check for endpoints matching or endpoints NULL after first if ((ii>0) && ( (x->value(ptr,ii) == x->value(ptr,0) && y->value(ptr,ii) == y->value(ptr,0)) || (x->value(ptr,ii) == NULL && y->value(ptr,ii) == NULL))) { delete n; break; } list.append(n); } else { // check for last point equals first point if (x->value(ptr,ii) != x->value(ptr,0) || y->value(ptr,ii) != y->value(ptr,0)) list.append(n); else delete n; } } if (!list.isEmpty()) createPolygonCmd(list, color, dash, width, font, text, props, NULL, taglist,cblist); } delete [] s1; } if (mkfits) delete mkfits; } void Base::markerMoveCmd(const Vector& v) { // use matrix, not map() undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; Vector c = m->getCenter() * refToCanvas; update(PIXMAP, m->getAllBBox()); m->moveTo((c + v) * canvasToRef); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveCmd(const char* tag, const Vector& v) { // use matrix, not map() undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->canMove() && m->hasTag(tag)) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; Vector c = m->getCenter() * refToCanvas; update(PIXMAP, m->getAllBBox()); m->moveTo((c + v) * canvasToRef); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveCmd(int id, const Vector& v) { // use matrix, not map() Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) { markerUndo(m, MOVE); Vector c = m->getCenter() * refToCanvas; update(PIXMAP, m->getAllBBox()); m->moveTo((c + v) * canvasToRef); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerMoveBeginCmd(const Vector& v) { markerBegin = mapToRef(v,Coord::CANVAS); undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; m->moveBegin(); } m=m->next(); } } void Base::markerMoveBeginCmd(int id, const Vector& v) { markerBegin = mapToRef(v,Coord::CANVAS); undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; m->moveBegin(); } return; } m=m->next(); } } void Base::markerMoveMotionCmd(const Vector& v) { // first, accumulate erase markers Marker* m=markers->head(); if (m) { while (m) { if (m->isSelected() && m->canMove()) redraw(m->getAllBBox()); m=m->next(); } // and erase now forceUpdate(); // ok, now draw selected markers in new location Vector markerEnd = mapToRef(v,Coord::CANVAS); Vector diff = markerEnd - markerBegin; markerBegin = markerEnd; m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { m->move(diff); x11MarkerXOR(m); } m=m->next(); } } } void Base::markerMoveMotionCmd(int id, const Vector& v) { // first, accumulate erase markers Marker* m=markers->head(); if (m) { while (m) { if (m->getId() && m->canMove()) { redraw(m->getAllBBox()); break; } m=m->next(); } if (!m) return; // can't find it Marker *ptr = m; // and erase now forceUpdate(); // ok, now draw selected markers in new location Vector markerEnd = mapToRef(v,Coord::CANVAS); Vector diff = markerEnd - markerBegin; markerBegin = markerEnd; ptr->move(diff); x11MarkerXOR(ptr); } } void Base::markerMoveEndCmd() { Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) m->moveEnd(); m=m->next(); } // update widget since we don't know where the selected markers came from update(PIXMAP); } void Base::markerMoveEndCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) m->moveEnd(); return; } m=m->next(); } // update widget since we don't know where the selected markers came from update(PIXMAP); } void Base::markerMoveToCmd(const Vector& v, Coord::InternalSystem sys) { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); m->moveTo(mapToRef(v,sys)); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveToCmd(const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky) { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canMove()) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); m->moveTo(ptr->mapToRef(v,sys,sky)); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveToCmd(const char* tag, const Vector& v, Coord::InternalSystem sys) { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->canMove() && m->hasTag(tag)) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); m->moveTo(mapToRef(v,sys)); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveToCmd(const char* tag, const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky) { undoMarkers->deleteAll(); Marker* m=markers->head(); while (m) { if (m->canMove() && m->hasTag(tag)) { undoMarkers->append(m->dup()); undoMarkerType = MOVE; update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); m->moveTo(ptr->mapToRef(v,sys,sky)); update(PIXMAP, m->getAllBBox()); } m=m->next(); } } void Base::markerMoveToCmd(int id, const Vector& v, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) { markerUndo(m, MOVE); update(PIXMAP, m->getAllBBox()); m->moveTo(mapToRef(v, sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerMoveToCmd(int id, const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canMove()) { markerUndo(m, MOVE); update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); m->moveTo(ptr->mapToRef(v,sys,sky)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerPasteCmd() { // unselect markers { Marker* m=markers->head(); while (m) { m->unselect(); m=m->next(); } } undoMarkers->deleteAll(); Marker* m=pasteMarkers->head(); while (m) { Marker* n = m->dup(); n->newIdentity(); markers->append(n); m = m->next(); } update(PIXMAP); } void Base::markerPasteCmd(Coord::CoordSystem from, Coord::CoordSystem to) { // sys is the coordinate system to specified in the header // use wcsSystem for markers MarkerFormat type = DS9; Coord::SkyFrame sky = Coord::FK5; Coord::SkyFormat format = Coord::DEGREES; { ostringstream str; markerListHeader(str, to, sky, format, 0); coord.listCoordSystem(str,to,sky,1,1); str << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } Marker* m=pasteMarkers->head(); while (m) { ostringstream str; m->list(str, from, sky, format, 0, 0); str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); m=m->next(); } } void Base::markerPointShapeCmd(int id, Point::PointShape shape) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Point*)m)->setShape(shape); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerPointSizeCmd(int id, int size) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Point*)m)->setSize(size); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerPolygonCreateVertexCmd(int id, int seg, const Vector& v) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); ((Polygon*)(m))->createVertex(seg, mapToRef(v,Coord::CANVAS)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerPolygonDeleteVertexCmd(int id, int h) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Polygon*)(m))->deleteVertex(h); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } } void Base::markerPolygonResetCmd(int id, const Vector& size, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Polygon*)(m))->reset(mapLenToRef(size, sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerPolygonResetCmd(int id, const Vector& size, Coord::CoordSystem sys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Polygon*)(m))->reset(ptr->mapLenToRef(size, sys, dist)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerProjectionCmd(int id,const Vector& p1,const Vector& p2, Coord::InternalSystem sys,double width) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Projection*)(m))->set(mapToRef(p1,sys), mapToRef(p2,sys), mapLenToRef(width,sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerProjectionCmd(int id, const Vector& p1, const Vector& p2, Coord::CoordSystem sys, Coord::SkyFrame sky, double width, Coord::CoordSystem wdsys, Coord::SkyDist wddist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Projection*)(m))->set(ptr->mapToRef(p1,sys,sky), ptr->mapToRef(p2,sys,sky), ptr->mapLenToRef(width, wdsys, wddist)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerPropertyCmd(unsigned short prop, int value) { Marker* m=markers->head(); while (m) { if (m->isSelected()) { if (prop == Marker::DASH || prop == Marker::FIXED || prop == Marker::INCLUDE || prop == Marker::SOURCE) { // marker will change bbox, so get before and after update(PIXMAP, m->getAllBBox()); m->setProperty(prop, value); update(PIXMAP, m->getAllBBox()); } else m->setProperty(prop, value); } m=m->next(); } } void Base::markerPropertyCmd(const char* tag, unsigned short prop, int value) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { if (prop == Marker::DASH || prop == Marker::FIXED || prop == Marker::INCLUDE || prop == Marker::SOURCE) { // marker will change bbox, so get before and after update(PIXMAP, m->getAllBBox()); m->setProperty(prop, value); update(PIXMAP, m->getAllBBox()); } else m->setProperty(prop, value); } m=m->next(); } } void Base::markerPropertyCmd(unsigned short prop, int value, const Vector& v) { // v is in canvas coords Marker* m=markers->head(); while (m) { if (m->isIn(v)) { if (prop == Marker::DASH || prop == Marker::FIXED || prop == Marker::INCLUDE || prop == Marker::SOURCE) { // marker will change bbox, so get before and after update(PIXMAP, m->getAllBBox()); m->setProperty(prop, value); update(PIXMAP, m->getAllBBox()); } else m->setProperty(prop, value); } m=m->next(); } } void Base::markerPropertyCmd(int id, unsigned short prop, int value) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (prop == Marker::DASH || prop == Marker::FIXED || prop == Marker::INCLUDE || prop == Marker::SOURCE) { // marker will change bbox, so get before and after update(PIXMAP, m->getAllBBox()); m->setProperty(prop, value); update(PIXMAP, m->getAllBBox()); } else m->setProperty(prop, value); return; } m=m->next(); } } void Base::markerRotateBeginCmd(int id) { // remember which marker is being edited Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canRotate()) { markerUndo(m, EDIT); rotateMarker = m; rotateMarker->rotateBegin(); } return; } m=m->next(); } rotateMarker = NULL; } void Base::markerRotateBeginCmd(const Vector& v) { // remember which marker is being edited Marker* m=markers->head(); while (m) { if (m->isSelected() && m->canRotate()) { markerUndo(m, EDIT); rotateMarker = m; rotateMarker->rotateBegin(); return; } m=m->next(); } rotateMarker = NULL; } void Base::markerRotateMotionCmd(const Vector& vv, int hh) { if (rotateMarker) { // erase current marker now redraw(rotateMarker->getAllBBox()); forceUpdate(); rotateMarker->rotate(mapToRef(vv,Coord::CANVAS), hh); x11MarkerXOR(rotateMarker); } } void Base::markerRotateEndCmd() { if (rotateMarker) rotateMarker->rotateEnd(); rotateMarker = NULL; update(PIXMAP); } void Base::markerRulerPointCmd(int id, const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Ruler*)(m))->setPoints(mapToRef(p1,sys),mapToRef(p2,sys)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerRulerPointCmd(int id, const Vector& p1, const Vector& p2, Coord::CoordSystem sys, Coord::SkyFrame sky) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Ruler*)(m))->setPoints(ptr->mapToRef(p1,sys,sky), ptr->mapToRef(p2,sys,sky)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerRulerSystemCmd(int id, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem dsys, Coord::SkyDist dist) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { // it may shrink update(PIXMAP, m->getAllBBox()); ((Ruler*)(m))->setCoordSystem(sys, sky, dsys, dist); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } result = TCL_ERROR; } void Base::markerSaveCmd(const char* fileName, MarkerFormat type, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { int doSys = 1; ofstream fn(fileName); if (fn) { switch (type) { case DS9: markerListHeader(fn, sys, sky, format, strip); break; case XML: markerListXMLHeader(fn, sys, sky, format); break; case CIAO: markerListCiaoHeader(fn, sys, sky, format, strip); break; case SAOTNG: markerListSAOtngHeader(fn, sys, sky, format, strip); break; case SAOIMAGE: break; case PROS: break; case RAWXY: break; } Marker* m=markers->head(); while (m) { switch (type) { case DS9: if (doSys) { coord.listCoordSystem(fn, sys, sky, 1, keyContext->fits->hasWCSCel(sys)); fn << (strip ? ';' : '\n'); doSys = 0; } m->list(fn, sys, sky, format, 0, strip); break; case XML: m->listXML(fn, sys, sky, format); break; case CIAO: m->listCiao(fn, sys, strip); break; case SAOTNG: m->listSAOtng(fn, sys, sky, format, strip); break; case SAOIMAGE: m->listSAOimage(fn, strip); break; case PROS: m->listPros(fn, sys, sky, format, strip); break; case RAWXY: m->listXY(fn, sys, sky, format, strip); break; } m=m->next(); } switch (type) { case DS9: break; case XML: markerListXMLFooter(fn); break; case CIAO: break; case SAOTNG: break; case SAOIMAGE: break; case PROS: break; case RAWXY: break; } } else { Tcl_AppendResult(interp, "Unable to open file ", fileName, NULL); result = TCL_ERROR; } } void Base::markerSaveTemplateCmd(const char* fileName) { Marker* m=markers->head(); if (keyContext->fits && m) { ofstream fn(fileName); if (fn) { FitsImage* ptr = keyContext->fits; while (ptr) { ptr->initWCS0(m->getCenter()); ptr = ptr->nextMosaic(); } markerListHeader(fn, Coord::WCS0, Coord::FK5, Coord::DEGREES, 0); coord.listCoordSystem(fn, Coord::WCS0, Coord::FK5, 1, keyContext->fits->hasWCSCel(Coord::WCS0)); fn << endl; while (m) { m->list(fn, Coord::WCS0, Coord::FK5, Coord::DEGREES, 0, 0); m=m->next(); } ptr = keyContext->fits; while (ptr) { ptr->resetWCS0(); ptr = ptr->nextMosaic(); } } else { Tcl_AppendResult(interp, "Unable to open file ", fileName, NULL); result = TCL_ERROR; } } } void Base::markerSelectAllCmd() { Marker* m=markers->head(); while (m) { if (m->canSelect()) { m->select(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerSelectCmd(int id) { Marker* m=markers->head(); while (m) { if (m->canSelect() && m->getId() == id) { m->select(); update(PIXMAP, m->getAllBBox()); return; } m=m->next(); } } void Base::markerSelectCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->canSelect() && m->hasTag(tag)) { m->select(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerSelectToggleCmd() { // toggle the select of the first found Marker* m=markers->head(); while (m) { if (m->canSelect()) { m->toggleSelect(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerSelectToggleCmd(const Vector& v) { // toggle the select of the first found Marker* m=markers->head(); while (m) { if (m->canSelect() && m->isIn(v)) { m->toggleSelect(); update(PIXMAP, m->getBBox()); Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } Tcl_AppendResult(interp, "0", NULL); } void Base::markerSelectOnlyCmd(int id) { Marker* m=markers->head(); while (m) { if (m->canSelect() && m->getId() == id) { if (!m->isSelected()) { m->select(); update(PIXMAP, m->getBBox()); } } else { if (m->isSelected()) { m->unselect(); update(PIXMAP, m->getBBox()); } } m=m->next(); } } void Base::markerSelectOnlyCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->canSelect() && m->hasTag(tag)) if (!m->isSelected()) { m->select(); update(PIXMAP, m->getBBox()); } else if (m->isSelected()) { m->unselect(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerSelectOnlyCmd(const Vector& v) { // first, check to see if we clicked on an already selected marker Marker* m=markers->head(); while (m) { if (m->canSelect() && m->isIn(v) && m->isSelected()) { Tcl_AppendResult(interp, "1", NULL); return; } m=m->next(); } // ok, now select the first found, and unselect the rest int found = 0; m=markers->head(); while (m) { if (m->canSelect() && m->isIn(v) && !found) { if (!m->isSelected()) { m->select(); update(PIXMAP, m->getBBox()); } found = 1; } else { if (m->isSelected()) { m->unselect(); update(PIXMAP, m->getBBox()); } } m=m->next(); } if (found) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::markerShowCmd(int which) { showMarkers = which; update(PIXMAP); } void Base::markerShowTextCmd(int which) { showMarkersText = which; update(PIXMAP); } void Base::markerTagCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->isSelected()) m->addTag(tag); m=m->next(); } } void Base::markerTagCmd(int id, const char* tag) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->addTag(tag); return; } m=m->next(); } } void Base::markerTagEditCmd(const char* from, const char* to) { Marker* m=markers->head(); while (m) { m->editTag(from, to); m=m->next(); } } void Base::markerTagDeleteCmd(const char* t) { Marker* m=markers->head(); while (m) { m->deleteTag(t); m=m->next(); } } void Base::markerTagDeleteAllCmd() { Marker* m=markers->head(); while (m) { m->deleteTags(); m=m->next(); } } void Base::markerTagUpdateCmd(const char* t) { markerTagDeleteCmd(t); markerTagCmd(t); } void Base::markerTextCmd(int id, const char* text) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { // things can shrink, so do before and after update(PIXMAP,m->getAllBBox()); m->setText(text); update(PIXMAP,m->getAllBBox()); return; } m=m->next(); } } void Base::markerTextRotateCmd(int id, int rot) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { ((Text*)(m))->setRotate(rot); update(PIXMAP); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerUndoCmd() { Marker* n=undoMarkers->head(); while (n) { Marker* next = n->next(); undoMarkers->extractPrev(n); switch (undoMarkerType) { case NONE: break; case DELETE: markers->append(n); n->updateBBox(); update(PIXMAP,n->getAllBBox()); break; case EDIT: case MOVE: { Marker* m=markers->head(); while (m) { if (m->getId() == n->getId()) { n->enableCB(); m->updateBBox(); update(PIXMAP,m->getAllBBox()); markers->insertNext(m,n); markers->extractNext(m); n->updateBBox(); update(PIXMAP,n->getAllBBox()); switch (undoMarkerType) { case EDIT: n->doCallBack(CallBack::EDITCB); break; case MOVE: n->doCallBack(CallBack::MOVECB); break; } m->disableCB(); delete m; break; } m=m->next(); } } break; } n=next; } undoMarkerType = NONE; } void Base::markerUnhighliteAllCmd() { Marker* m=markers->head(); while (m) { m->unhighlite(); update(PIXMAP, m->getBBox()); m=m->next(); } } void Base::markerUnhighliteCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->unhighlite(); update(PIXMAP, m->getBBox()); return; } m=m->next(); } } void Base::markerUnhighliteCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { m->unhighlite(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerUnselectAllCmd() { Marker* m=markers->head(); while (m) { m->unselect(); update(PIXMAP, m->getBBox()); m=m->next(); } } void Base::markerUnselectCmd(int id) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { m->unselect(); update(PIXMAP, m->getBBox()); return; } m=m->next(); } } void Base::markerUnselectCmd(const char* tag) { Marker* m=markers->head(); while (m) { if (m->hasTag(tag)) { m->unselect(); update(PIXMAP, m->getBBox()); } m=m->next(); } } void Base::markerVectorCmd(int id, const Vector& p, Coord::InternalSystem sys, double mag, double ang) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); ((Vect*)(m))->setPoints(mapToRef(p,sys),mapLenToRef(mag,sys),ang); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerVectorCmd(int id, const Vector& p, Coord::CoordSystem sys, Coord::SkyFrame sky, double mag, Coord::CoordSystem dsys, Coord::SkyDist dist, double ang) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { markerUndo(m, EDIT); // it may shrink update(PIXMAP, m->getAllBBox()); FitsImage* ptr = findFits(sys,m->getCenter()); ((Vect*)(m))->setPoints(ptr->mapToRef(p,sys,sky), ptr->mapLenToRef(mag,dsys,dist), mapAngleToRef(ang,sys,sky)); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::markerVectorArrowCmd(int id, int p) { Marker* m=markers->head(); while (m) { if (m->getId() == id) { if (m->canEdit()) { ((Vect*)(m))->setArrow(p); update(PIXMAP, m->getAllBBox()); } return; } m=m->next(); } result = TCL_ERROR; } void Base::regionHighliteEndCmd() { BBox bb(regionBegin, regionEnd); Marker* m=markers->head(); while (m) { if (bb.isIn(m->getBBox())==4 && m->canHighlite()) m->highlite(); else m->unhighlite(); m=m->next(); } update(PIXMAP, bb.expand(2)); } void Base::regionHighliteShiftEndCmd() { BBox bb(regionBegin, regionEnd); Marker* m=markers->head(); while (m) { if (bb.isIn(m->getBBox())==4 && m->canHighlite()) m->highlite(); m=m->next(); } update(PIXMAP, bb.expand(2)); } void Base::regionSelectBeginCmd(const Vector& vv) { regionBegin = vv; regionEnd = vv; } void Base::regionSelectMotionCmd(const Vector& vv) { // erase redrawNow((BBox(regionBegin, regionEnd)).expand(2)); // and draw to window regionEnd = vv; BBox cc = BBox(regionBegin, regionEnd) * canvasToWindow; Vector size = cc.size(); XDrawRectangle(display, Tk_WindowId(tkwin), selectGCXOR, cc.ll[0], cc.ll[1], size[0], size[1]); } void Base::regionSelectEndCmd() { BBox bb(regionBegin, regionEnd); Marker* m=markers->head(); while (m) { if (bb.isIn(m->getBBox())==4 && m->canSelect()) m->select(); else m->unselect(); m=m->next(); } update(PIXMAP, bb.expand(2)); } void Base::regionSelectShiftEndCmd() { BBox bb(regionBegin, regionEnd); Marker* m=markers->head(); while (m) { if (bb.isIn(m->getBBox())==4 && m->canSelect()) m->select(); m=m->next(); } update(PIXMAP, bb.expand(2)); } // Marker Support void Base::markerListCiaoHeader(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { // no comments for semicolons if (!strip) str << "# Region file format: CIAO version 1.0" << endl; } void Base::markerListHeader(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { // no comments for semicolons if (!strip) { // header str << "# Region file format: DS9 version 4.1" << endl; // don't output filename anymore // if (keyContext->fits) // str << "# Filename: " << keyContext->fits->getFullBaseFileName() << endl; str << "global color=green dashlist=8 3 width=1 font=\"helvetica 10 normal roman\" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1" << endl; } } void Base::markerListSAOtngHeader(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { // no comments for semicolons if (strip) return; // don't output filename anymore // if (keyContext->fits) // str << "# filename: " << keyContext->fits->getRootFileName() << endl; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::AMPLIFIER: case Coord::DETECTOR: str << "# format: pixels (physical)" << endl; break; default: str << "# format: "; switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: case Coord::GALACTIC: case Coord::SUPERGALACTIC: case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: switch (format) { case Coord::DEGREES: str << "degrees ("; break; case Coord::SEXAGESIMAL: str << "hms ("; break; } switch (sky) { case Coord::FK4: str << "fk4"; break; case Coord::FK4_NO_E: str << "fk4-no-e"; break; case Coord::FK5: str << "fk5"; break; case Coord::ICRS: str << "icrs"; break; case Coord::GALACTIC: str << "galactic"; break; case Coord::SUPERGALACTIC: str << "supergalactic"; break; case Coord::ECLIPTIC: str << "ecliptic"; break; case Coord::HELIOECLIPTIC: str << "helioecliptic"; break; } str << ')' << endl; break; } } } void Base::markerPrintCoord(const Vector& v, Coord::InternalSystem sys) { printVector(mapFromRef(v, sys), DEFAULT); } void Base::markerPrintCoord(const Vector& c, const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = findFits(sys,c); printFromRef(ptr, v, sys, sky, format, DEFAULT); } void Base::markerPrintDouble(double d, Coord::InternalSystem sys) { printDouble(mapLenFromRef(d,sys), DEFAULT); } void Base::markerPrintDouble(const Vector& c, double d, Coord::CoordSystem sys, Coord::SkyDist dist) { FitsImage* ptr = findFits(sys,c); printDouble(ptr->mapLenFromRef(d,sys,dist), DEFAULT); } void Base::markerPrintDouble(const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { printDouble(mapDistFromRef(p1,p2,sys), DEFAULT); } void Base::markerPrintDouble(const Vector& c, const Vector& p1, const Vector& p2, Coord::CoordSystem sys, Coord::SkyDist dist) { FitsImage* ptr = findFits(sys,c); printDouble(ptr->mapDistFromRef(p1,p2,sys,dist), DEFAULT); } void Base::markerPrintVector(const Vector& v, Coord::InternalSystem sys) { printVector(mapLenFromRef(v,sys), DEFAULT); } void Base::markerPrintVector(const Vector& c, const Vector& v, Coord::CoordSystem sys, Coord::SkyDist dist) { FitsImage* ptr = findFits(sys,c); printVector(ptr->mapLenFromRef((Vector&)v,sys,dist), DEFAULT); } void Base::markerUndo(Marker* m, UndoMarkerType t) { undoMarkers->deleteAll(); undoMarkers->append(m->dup()); undoMarkerType = t; } void Base::parseMarker(MarkerFormat fm, istream& str) { switch (fm) { case DS9: { mkFlexLexer* ll = new mkFlexLexer(&str); mkparse(this, ll); delete ll; resetCompositeMarker(); } break; case XML: xmlParse(str); break; case CIAO: { ciaoFlexLexer* ll = new ciaoFlexLexer(&str); ciaoparse(this, ll); delete ll; } break; case PROS: { prosFlexLexer* ll = new prosFlexLexer(&str); prosparse(this, ll); delete ll; } break; case SAOTNG: { tngFlexLexer* ll = new tngFlexLexer(&str); tngparse(this, ll); delete ll; } break; case SAOIMAGE: { saoFlexLexer* ll = new saoFlexLexer(&str); saoparse(this, ll); delete ll; } break; case RAWXY: { xyFlexLexer* ll = new xyFlexLexer(&str); xyparse(this, ll); delete ll; } break; } } void Base::psMarkers(List<Marker>* ml, int mode) { // render from back to front // bbox is in canvas coords const BBox bb = BBox(0, 0, options->width-1, options->height-1) * widgetToCanvas; Marker* m=ml->tail(); while (m) { if (m->isVisible(bb)) m->ps(mode, showMarkersText); m=m->previous(); } } void Base::x11MagnifierMarkers(List<Marker>* ml, const BBox& bb) { // render from back to front // bbox is in canvas coords Marker* m=ml->tail(); while (m) { if (m->isVisible(bb)) m->x11(magnifierPixmap, Coord::MAGNIFIER, showMarkersText, Marker::SRC, Marker::NOHANDLES); m=m->previous(); } } void Base::x11Markers(List<Marker>* ml, const BBox& bb) { // render from back to front // bbox is in canvas coords Marker* m=ml->tail(); while (m) { if (m->isVisible(bb)) m->x11(pixmap, Coord::WIDGET, showMarkersText, Marker::SRC, Marker::HANDLES); m=m->previous(); } } void Base::x11MarkerXOR(Marker* ptr) { if (ptr) ptr->x11(Tk_WindowId(tkwin), Coord::WINDOW, showMarkersText, Marker::XOR, Marker::NOHANDLES); } void Base::unselectMarkers(List<Marker>* ml) { Marker* m=ml->head(); while (m) { m->unselect(); m=m->next(); } } void Base::unhighliteMarkers() { Marker* m=markers->head(); while (m) { m->unhighlite(); m=m->next(); } } void Base::updateCBMarkers() { Marker* m=markers->head(); while (m) { m->doCallBack(CallBack::UPDATECB); m=m->next(); } } void Base::updateMarkers(List<Marker>* ml) { Marker* m=ml->head(); while (m) { m->updateBBox(); m=m->next(); } } void Base::updateMarkerCoords(List<Marker>* ml, const Matrix& mx) { Marker* m=ml->head(); while (m) { m->updateCoords(mx); m=m->next(); } } void Base::updateMarkerCBs(List<Marker>* ml) { Marker* m=ml->head(); while (m) { m->doCallBack(CallBack::MOVECB); m->doCallBack(CallBack::EDITCB); m->doCallBack(CallBack::ROTATECB); m=m->next(); } } #ifdef _MACOSX void Base::macosxMarkers(List<Marker>* ml) { // render from back to front // bbox is in canvas coords const BBox bb = BBox(0, 0, options->width-1, options->height-1) * widgetToCanvas; Marker* m=ml->tail(); while (m) { if (m->isVisible(bb)) m->macosx(showMarkersText); m=m->previous(); } } #endif #ifdef _WIN32 void Base::win32Markers(List<Marker>* ml) { // render from back to front // bbox is in canvas coords const BBox bb = BBox(0, 0, options->width-1, options->height-1) * widgetToCanvas; Marker* m=ml->tail(); while (m) { if (m->isVisible(bb)) m->win32(showMarkersText); m=m->previous(); } } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ds9parser.C��������������������������������������������������������������������0000644�0001750�0001750�00000531173�11734430017�015350� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse mkparse #define yylex mklex #define yyerror mkerror #define yylval mklval #define yychar mkchar #define yydebug mkdebug #define yynerrs mknerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, ANGRADIAN = 262, ARCMINUTE = 263, ARCSECOND = 264, PHYCOORD = 265, IMGCOORD = 266, SEXSTR = 267, HMSSTR = 268, DMSSTR = 269, EOF_ = 270, AMPLIFIER_ = 271, ANNULUS_ = 272, ARCMIN_ = 273, ARCSEC_ = 274, ARROW_ = 275, B1950_ = 276, BACKGROUND_ = 277, BEGIN_ = 278, BOX_ = 279, BOXCIRCLE_ = 280, BPANDA_ = 281, CALLBACK_ = 282, CIRCLE_ = 283, CIRCLE3D_ = 284, COLOR_ = 285, COMPASS_ = 286, COMPOSITE_ = 287, CPANDA_ = 288, CROSS_ = 289, DASH_ = 290, DASHLIST_ = 291, DEBUG_ = 292, DEGREES_ = 293, DELETE_ = 294, DETECTOR_ = 295, DIAMOND_ = 296, ECLIPTIC_ = 297, EDIT_ = 298, ELLIPSE_ = 299, END_ = 300, EPANDA_ = 301, FALSE_ = 302, FIELD_ = 303, FIXED_ = 304, FK4_ = 305, FK4_NO_E_ = 306, FK5_ = 307, FONT_ = 308, GALACTIC_ = 309, GLOBAL_ = 310, HELIOECLIPTIC_ = 311, HIGHLITE_ = 312, ICRS_ = 313, IGNORE_ = 314, IMAGE_ = 315, INCLUDE_ = 316, J2000_ = 317, KEY_ = 318, LINE_ = 319, LINEAR_ = 320, MOVE_ = 321, N_ = 322, NO_ = 323, OFF_ = 324, ON_ = 325, PHYSICAL_ = 326, PIE_ = 327, PIXELS_ = 328, POINT_ = 329, POLYGON_ = 330, PROJECTION_ = 331, PROPERTY_ = 332, ROTATE_ = 333, ROTBOX_ = 334, RULER_ = 335, SELECT_ = 336, SOURCE_ = 337, SUPERGALACTIC_ = 338, TAG_ = 339, TEXT_ = 340, TEXTANGLE_ = 341, TEXTROTATE_ = 342, TILE_ = 343, TRUE_ = 344, VECTOR_ = 345, VERSION_ = 346, UNHIGHLITE_ = 347, UNSELECT_ = 348, UPDATE_ = 349, WCS_ = 350, WCSA_ = 351, WCSB_ = 352, WCSC_ = 353, WCSD_ = 354, WCSE_ = 355, WCSF_ = 356, WCSG_ = 357, WCSH_ = 358, WCSI_ = 359, WCSJ_ = 360, WCSK_ = 361, WCSL_ = 362, WCSM_ = 363, WCSN_ = 364, WCSO_ = 365, WCSP_ = 366, WCSQ_ = 367, WCSR_ = 368, WCSS_ = 369, WCST_ = 370, WCSU_ = 371, WCSV_ = 372, WCSW_ = 373, WCSX_ = 374, WCSY_ = 375, WCSZ_ = 376, WCS0_ = 377, WIDTH_ = 378, X_ = 379, Y_ = 380, YES_ = 381 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define ANGRADIAN 262 #define ARCMINUTE 263 #define ARCSECOND 264 #define PHYCOORD 265 #define IMGCOORD 266 #define SEXSTR 267 #define HMSSTR 268 #define DMSSTR 269 #define EOF_ 270 #define AMPLIFIER_ 271 #define ANNULUS_ 272 #define ARCMIN_ 273 #define ARCSEC_ 274 #define ARROW_ 275 #define B1950_ 276 #define BACKGROUND_ 277 #define BEGIN_ 278 #define BOX_ 279 #define BOXCIRCLE_ 280 #define BPANDA_ 281 #define CALLBACK_ 282 #define CIRCLE_ 283 #define CIRCLE3D_ 284 #define COLOR_ 285 #define COMPASS_ 286 #define COMPOSITE_ 287 #define CPANDA_ 288 #define CROSS_ 289 #define DASH_ 290 #define DASHLIST_ 291 #define DEBUG_ 292 #define DEGREES_ 293 #define DELETE_ 294 #define DETECTOR_ 295 #define DIAMOND_ 296 #define ECLIPTIC_ 297 #define EDIT_ 298 #define ELLIPSE_ 299 #define END_ 300 #define EPANDA_ 301 #define FALSE_ 302 #define FIELD_ 303 #define FIXED_ 304 #define FK4_ 305 #define FK4_NO_E_ 306 #define FK5_ 307 #define FONT_ 308 #define GALACTIC_ 309 #define GLOBAL_ 310 #define HELIOECLIPTIC_ 311 #define HIGHLITE_ 312 #define ICRS_ 313 #define IGNORE_ 314 #define IMAGE_ 315 #define INCLUDE_ 316 #define J2000_ 317 #define KEY_ 318 #define LINE_ 319 #define LINEAR_ 320 #define MOVE_ 321 #define N_ 322 #define NO_ 323 #define OFF_ 324 #define ON_ 325 #define PHYSICAL_ 326 #define PIE_ 327 #define PIXELS_ 328 #define POINT_ 329 #define POLYGON_ 330 #define PROJECTION_ 331 #define PROPERTY_ 332 #define ROTATE_ 333 #define ROTBOX_ 334 #define RULER_ 335 #define SELECT_ 336 #define SOURCE_ 337 #define SUPERGALACTIC_ 338 #define TAG_ 339 #define TEXT_ 340 #define TEXTANGLE_ 341 #define TEXTROTATE_ 342 #define TILE_ 343 #define TRUE_ 344 #define VECTOR_ 345 #define VERSION_ 346 #define UNHIGHLITE_ 347 #define UNSELECT_ 348 #define UPDATE_ 349 #define WCS_ 350 #define WCSA_ 351 #define WCSB_ 352 #define WCSC_ 353 #define WCSD_ 354 #define WCSE_ 355 #define WCSF_ 356 #define WCSG_ 357 #define WCSH_ 358 #define WCSI_ 359 #define WCSJ_ 360 #define WCSK_ 361 #define WCSL_ 362 #define WCSM_ 363 #define WCSN_ 364 #define WCSO_ 365 #define WCSP_ 366 #define WCSQ_ 367 #define WCSR_ 368 #define WCSS_ 369 #define WCST_ 370 #define WCSU_ 371 #define WCSV_ 372 #define WCSW_ 373 #define WCSX_ 374 #define WCSY_ 375 #define WCSZ_ 376 #define WCS0_ 377 #define WIDTH_ 378 #define X_ 379 #define Y_ 380 #define YES_ 381 /* Copy the first part of user declarations. */ #line 10 "ds9parser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits(globalTile)) #define DISCARD_(x) {yyclearin; mkDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #include "point.h" #undef yyFlexLexer #define yyFlexLexer mkFlexLexer #include <FlexLexer.h> extern int mklex(void*, mkFlexLexer*); extern void mkerror(Base*, mkFlexLexer*, const char*); extern void mkDiscard(int); static Coord::CoordSystem globalSystem; static Coord::CoordSystem globalWCS; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static int globalTile; static unsigned short globalProps; static unsigned short localProps; static int globalDash[2]; static int localDash[2]; static int globalWidth; static int localWidth; static char globalColor[16]; static char localColor[16]; static char globalFont[32]; static char localFont[32]; static char globalText[80]; static char localText[80]; static char localComment[80]; static int globalLine1; static int localLine1; static int globalLine2; static int localLine2; static int globalVector; static int localVector; static int globalComposite; static int localComposite; static int globalPoint; static int localPoint; static int globalPointSize; static int localPointSize; static double globalTextAngle; static double localTextAngle; static int globalTextRotate; static int localTextRotate; static Coord::CoordSystem globalRulerCoordSystem; static Coord::CoordSystem localRulerCoordSystem; static Coord::SkyFrame globalRulerSkyFrame; static Coord::SkyFrame localRulerSkyFrame; static Coord::CoordSystem globalRulerDistSystem; static Coord::CoordSystem localRulerDistSystem; static Coord::SkyDist globalRulerDistFormat; static Coord::SkyDist localRulerDistFormat; static Coord::CoordSystem globalCompassCoordSystem; static Coord::SkyFrame globalCompassSkyFrame; static char globalCompassNorth[80]; static char globalCompassEast[80]; static int globalCompassNArrow; static int globalCompassEArrow; static Coord::CoordSystem localCompassCoordSystem; static Coord::SkyFrame localCompassSkyFrame; static char localCompassNorth[80]; static char localCompassEast[80]; static int localCompassNArrow; static int localCompassEArrow; static int localCpanda; static int localEpanda; static int localBpanda; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aNumsao; static int aStatus; static int cStatus; static Vector aCenter; static double aAngles[MAXANGLES]; static int aAngNum; static double aAngle; static unsigned short aProps; static char aColor[16]; static int aWidth; static int aDash[2]; static char aFont[32]; static char aText[80]; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 135 "ds9parser.Y" { #define MKBUFSIZE 2048 double real; int integer; char str[MKBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 489 "ds9parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 502 "ds9parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 2552 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 139 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 71 /* YYNRULES -- Number of rules. */ #define YYNRULES 324 /* YYNRULES -- Number of states. */ #define YYNSTATES 831 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 381 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 138, 2, 127, 2, 2, 137, 2, 131, 132, 2, 135, 130, 136, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 2, 134, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 133, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 7, 11, 14, 15, 18, 20, 24, 27, 28, 32, 33, 37, 38, 42, 45, 49, 53, 55, 58, 61, 62, 65, 66, 67, 71, 73, 74, 79, 83, 84, 90, 92, 93, 97, 100, 101, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150, 153, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 178, 182, 186, 190, 194, 198, 202, 204, 206, 208, 212, 216, 220, 224, 228, 232, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 359, 361, 364, 367, 369, 372, 375, 377, 380, 382, 384, 386, 388, 390, 392, 394, 396, 400, 402, 406, 410, 415, 420, 424, 428, 432, 434, 436, 438, 442, 447, 452, 456, 460, 464, 472, 476, 480, 484, 489, 492, 495, 498, 501, 504, 507, 509, 511, 514, 516, 518, 520, 521, 525, 527, 531, 535, 540, 545, 549, 553, 557, 561, 567, 569, 571, 573, 577, 582, 587, 591, 595, 599, 607, 611, 615, 619, 623, 627, 632, 635, 638, 641, 644, 647, 650, 652, 654, 657, 659, 661, 663, 664, 672, 674, 675, 686, 688, 689, 700, 702, 703, 705, 707, 709, 711, 713, 715, 717, 719, 721, 732, 739, 748, 757, 768, 777, 786, 795, 804, 815, 826, 837, 838, 846, 855, 866, 873, 874, 884, 891, 899, 907, 915, 923, 931, 939, 947, 956, 965, 976, 987, 1000, 1013, 1026, 1041, 1056, 1075, 1088, 1103, 1118, 1137, 1156, 1177, 1198, 1209, 1222, 1235, 1241, 1250, 1254, 1256, 1258, 1262, 1264, 1266, 1270, 1272, 1274, 1278, 1280, 1284 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 140, 0, -1, 183, 141, 209, -1, 141, 142, 156, -1, 142, 156, -1, -1, 37, 158, -1, 91, -1, 55, 179, 148, -1, 88, 3, -1, -1, 173, 143, 148, -1, -1, 175, 144, 148, -1, -1, 65, 145, 148, -1, 194, 198, -1, 194, 196, 198, -1, 194, 127, 146, -1, 197, -1, 196, 197, -1, 88, 3, -1, -1, 147, 5, -1, -1, -1, 127, 149, 5, -1, 209, -1, -1, 127, 151, 5, 209, -1, 127, 184, 209, -1, -1, 127, 184, 152, 5, 209, -1, 209, -1, -1, 154, 5, 209, -1, 184, 209, -1, -1, 184, 155, 5, 209, -1, 128, -1, 129, -1, 15, -1, 4, -1, 3, -1, 70, -1, 69, -1, 3, -1, 126, -1, 125, -1, 70, -1, 89, -1, 68, -1, 67, -1, 69, -1, 47, -1, -1, 130, -1, -1, 131, -1, -1, 132, -1, -1, 133, -1, 133, 133, -1, -1, 165, -1, 157, -1, 6, -1, 7, -1, 157, -1, 10, -1, 11, -1, 6, -1, 8, -1, 9, -1, 157, 160, 157, -1, 10, 160, 10, -1, 11, 160, 11, -1, 6, 160, 6, -1, 8, 160, 8, -1, 9, 160, 9, -1, 67, 134, 3, -1, 12, -1, 13, -1, 14, -1, 169, 160, 169, -1, 170, 160, 171, -1, 171, 160, 171, -1, 157, 160, 157, -1, 6, 160, 6, -1, 11, 160, 11, -1, 10, 160, 10, -1, 60, -1, 71, -1, 40, -1, 16, -1, 174, -1, 95, -1, 96, -1, 97, -1, 98, -1, 99, -1, 100, -1, 101, -1, 102, -1, 103, -1, 104, -1, 105, -1, 106, -1, 107, -1, 108, -1, 109, -1, 110, -1, 111, -1, 112, -1, 113, -1, 114, -1, 115, -1, 116, -1, 117, -1, 118, -1, 119, -1, 120, -1, 121, -1, 122, -1, 50, -1, 21, -1, 51, -1, 52, -1, 62, -1, 58, -1, 54, -1, 83, -1, 42, -1, 56, -1, 38, -1, 18, -1, 19, -1, 81, -1, 57, -1, 35, -1, 49, -1, 43, -1, 66, -1, 78, -1, 39, -1, 61, -1, 82, -1, 81, -1, 93, -1, 57, -1, 92, -1, 23, 66, -1, 66, -1, 45, 66, -1, 23, 43, -1, 43, -1, 45, 43, -1, 23, 78, -1, 78, -1, 45, 78, -1, 39, -1, 85, -1, 30, -1, 123, -1, 77, -1, 53, -1, 63, -1, 94, -1, 179, 160, 180, -1, 180, -1, 177, 134, 159, -1, 30, 134, 5, -1, 30, 134, 127, 5, -1, 36, 134, 3, 3, -1, 123, 134, 3, -1, 53, 134, 5, -1, 85, 134, 5, -1, 35, -1, 82, -1, 22, -1, 74, 134, 195, -1, 74, 134, 195, 3, -1, 64, 134, 3, 3, -1, 90, 134, 3, -1, 32, 134, 3, -1, 80, 134, 181, -1, 31, 134, 182, 5, 5, 3, 3, -1, 86, 134, 165, -1, 87, 134, 3, -1, 95, 134, 174, -1, 173, 175, 173, 176, -1, 173, 173, -1, 173, 176, -1, 175, 173, -1, 175, 176, -1, 65, 173, -1, 65, 176, -1, 176, -1, 73, -1, 173, 175, -1, 173, -1, 175, -1, 65, -1, -1, 184, 160, 185, -1, 185, -1, 177, 134, 159, -1, 30, 134, 5, -1, 30, 134, 127, 5, -1, 36, 134, 3, 3, -1, 123, 134, 3, -1, 53, 134, 5, -1, 85, 134, 5, -1, 84, 134, 5, -1, 27, 134, 178, 5, 5, -1, 35, -1, 82, -1, 22, -1, 74, 134, 195, -1, 74, 134, 195, 3, -1, 64, 134, 3, 3, -1, 90, 134, 3, -1, 32, 134, 3, -1, 80, 134, 186, -1, 31, 134, 187, 5, 5, 3, 3, -1, 86, 134, 165, -1, 87, 134, 3, -1, 33, 134, 188, -1, 46, 134, 190, -1, 26, 134, 192, -1, 173, 175, 173, 176, -1, 173, 173, -1, 173, 176, -1, 175, 173, -1, 175, 176, -1, 65, 173, -1, 65, 176, -1, 176, -1, 73, -1, 173, 175, -1, 173, -1, 175, -1, 65, -1, -1, 189, 131, 205, 132, 131, 203, 132, -1, 59, -1, -1, 191, 131, 205, 132, 131, 207, 132, 131, 165, 132, -1, 59, -1, -1, 193, 131, 205, 132, 131, 207, 132, 131, 165, 132, -1, 59, -1, -1, 28, -1, 24, -1, 41, -1, 34, -1, 124, -1, 20, -1, 25, -1, 135, -1, 136, -1, 90, 161, 172, 160, 166, 160, 165, 162, 163, 153, -1, 85, 161, 172, 162, 163, 153, -1, 80, 161, 172, 160, 172, 162, 163, 153, -1, 31, 161, 172, 160, 166, 162, 163, 153, -1, 76, 161, 172, 160, 172, 160, 166, 162, 163, 153, -1, 29, 161, 172, 160, 166, 162, 163, 153, -1, 32, 161, 172, 160, 164, 162, 163, 153, -1, 28, 161, 172, 160, 166, 162, 163, 150, -1, 29, 161, 172, 160, 166, 162, 163, 150, -1, 44, 161, 172, 160, 167, 160, 164, 162, 163, 150, -1, 24, 161, 172, 160, 167, 160, 164, 162, 163, 150, -1, 79, 161, 172, 160, 167, 160, 164, 162, 163, 150, -1, -1, 75, 199, 161, 201, 162, 163, 150, -1, 64, 161, 172, 160, 172, 162, 163, 150, -1, 90, 161, 172, 160, 166, 160, 165, 162, 163, 150, -1, 85, 161, 172, 162, 163, 150, -1, -1, 85, 161, 172, 160, 5, 162, 200, 163, 150, -1, 74, 161, 172, 162, 163, 150, -1, 28, 74, 161, 172, 162, 163, 150, -1, 24, 74, 161, 172, 162, 163, 150, -1, 41, 74, 161, 172, 162, 163, 150, -1, 34, 74, 161, 172, 162, 163, 150, -1, 124, 74, 161, 172, 162, 163, 150, -1, 20, 74, 161, 172, 162, 163, 150, -1, 25, 74, 161, 172, 162, 163, 150, -1, 80, 161, 172, 160, 172, 162, 163, 150, -1, 31, 161, 172, 160, 166, 162, 163, 150, -1, 76, 161, 172, 160, 172, 160, 166, 162, 163, 150, -1, 17, 161, 172, 160, 166, 160, 166, 162, 163, 150, -1, 17, 161, 172, 160, 166, 160, 166, 160, 203, 162, 163, 150, -1, 17, 161, 172, 160, 166, 160, 166, 160, 168, 162, 163, 150, -1, 44, 161, 172, 160, 167, 160, 167, 160, 164, 162, 163, 150, -1, 44, 161, 172, 160, 167, 160, 167, 160, 168, 160, 164, 162, 163, 150, -1, 44, 161, 172, 160, 167, 160, 167, 160, 207, 160, 164, 162, 163, 150, -1, 44, 161, 172, 160, 167, 160, 164, 162, 137, 138, 44, 161, 172, 160, 167, 160, 164, 162, -1, 24, 161, 172, 160, 167, 160, 167, 160, 164, 162, 163, 150, -1, 24, 161, 172, 160, 167, 160, 167, 160, 207, 160, 164, 162, 163, 150, -1, 24, 161, 172, 160, 167, 160, 167, 160, 168, 160, 164, 162, 163, 150, -1, 24, 161, 172, 160, 167, 160, 164, 162, 137, 138, 24, 161, 172, 160, 167, 160, 164, 162, -1, 33, 161, 172, 160, 165, 160, 165, 160, 3, 160, 166, 160, 166, 160, 3, 162, 163, 150, -1, 46, 161, 172, 160, 165, 160, 165, 160, 3, 160, 167, 160, 167, 160, 3, 160, 164, 162, 163, 150, -1, 26, 161, 172, 160, 165, 160, 165, 160, 3, 160, 167, 160, 167, 160, 3, 160, 164, 162, 163, 150, -1, 72, 161, 172, 160, 165, 160, 165, 162, 163, 150, -1, 72, 161, 172, 160, 165, 160, 165, 160, 205, 162, 163, 150, -1, 72, 161, 172, 160, 165, 160, 165, 160, 168, 162, 163, 150, -1, 48, 161, 162, 163, 150, -1, 32, 161, 172, 160, 164, 162, 163, 150, -1, 201, 160, 202, -1, 202, -1, 172, -1, 203, 160, 204, -1, 204, -1, 166, -1, 205, 160, 206, -1, 206, -1, 165, -1, 207, 160, 208, -1, 208, -1, 166, 160, 166, -1, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 294, 294, 297, 298, 301, 302, 303, 305, 306, 308, 308, 309, 309, 310, 310, 312, 313, 314, 317, 318, 319, 320, 320, 323, 324, 324, 327, 328, 328, 329, 330, 330, 334, 335, 335, 336, 337, 337, 340, 341, 342, 345, 346, 349, 350, 353, 355, 356, 357, 358, 360, 361, 362, 363, 366, 367, 370, 371, 374, 375, 378, 379, 380, 383, 384, 387, 388, 389, 392, 393, 394, 395, 396, 397, 400, 407, 414, 421, 428, 435, 444, 447, 450, 453, 456, 469, 477, 485, 492, 500, 507, 515, 516, 517, 518, 519, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 564, 565, 566, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 604, 605, 608, 613, 618, 623, 628, 629, 634, 639, 644, 649, 654, 655, 660, 665, 666, 670, 671, 680, 681, 682, 685, 692, 699, 706, 713, 720, 727, 734, 741, 750, 755, 760, 765, 772, 814, 815, 818, 819, 820, 824, 829, 830, 831, 832, 833, 835, 836, 837, 839, 840, 841, 842, 843, 844, 845, 852, 853, 854, 855, 856, 859, 866, 873, 880, 887, 894, 901, 908, 915, 924, 929, 934, 939, 946, 946, 947, 950, 950, 952, 955, 955, 957, 960, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1018, 1019, 1022, 1030, 1037, 1046, 1056, 1064, 1072, 1081, 1088, 1096, 1119, 1142, 1151, 1151, 1159, 1167, 1175, 1182, 1182, 1190, 1197, 1204, 1211, 1218, 1225, 1232, 1239, 1246, 1255, 1265, 1273, 1280, 1290, 1298, 1308, 1318, 1330, 1338, 1348, 1360, 1370, 1379, 1401, 1425, 1450, 1451, 1452, 1454, 1456, 1465, 1466, 1469, 1472, 1473, 1476, 1483, 1484, 1487, 1494, 1495, 1498, 1502 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "STRING", "ANGDEGREE", "ANGRADIAN", "ARCMINUTE", "ARCSECOND", "PHYCOORD", "IMGCOORD", "SEXSTR", "HMSSTR", "DMSSTR", "EOF_", "AMPLIFIER_", "ANNULUS_", "ARCMIN_", "ARCSEC_", "ARROW_", "B1950_", "BACKGROUND_", "BEGIN_", "BOX_", "BOXCIRCLE_", "BPANDA_", "CALLBACK_", "CIRCLE_", "CIRCLE3D_", "COLOR_", "COMPASS_", "COMPOSITE_", "CPANDA_", "CROSS_", "DASH_", "DASHLIST_", "DEBUG_", "DEGREES_", "DELETE_", "DETECTOR_", "DIAMOND_", "ECLIPTIC_", "EDIT_", "ELLIPSE_", "END_", "EPANDA_", "FALSE_", "FIELD_", "FIXED_", "FK4_", "FK4_NO_E_", "FK5_", "FONT_", "GALACTIC_", "GLOBAL_", "HELIOECLIPTIC_", "HIGHLITE_", "ICRS_", "IGNORE_", "IMAGE_", "INCLUDE_", "J2000_", "KEY_", "LINE_", "LINEAR_", "MOVE_", "N_", "NO_", "OFF_", "ON_", "PHYSICAL_", "PIE_", "PIXELS_", "POINT_", "POLYGON_", "PROJECTION_", "PROPERTY_", "ROTATE_", "ROTBOX_", "RULER_", "SELECT_", "SOURCE_", "SUPERGALACTIC_", "TAG_", "TEXT_", "TEXTANGLE_", "TEXTROTATE_", "TILE_", "TRUE_", "VECTOR_", "VERSION_", "UNHIGHLITE_", "UNSELECT_", "UPDATE_", "WCS_", "WCSA_", "WCSB_", "WCSC_", "WCSD_", "WCSE_", "WCSF_", "WCSG_", "WCSH_", "WCSI_", "WCSJ_", "WCSK_", "WCSL_", "WCSM_", "WCSN_", "WCSO_", "WCSP_", "WCSQ_", "WCSR_", "WCSS_", "WCST_", "WCSU_", "WCSV_", "WCSW_", "WCSX_", "WCSY_", "WCSZ_", "WCS0_", "WIDTH_", "X_", "Y_", "YES_", "'#'", "'\\n'", "';'", "','", "'('", "')'", "'|'", "'='", "'+'", "'-'", "'&'", "'!'", "$accept", "start", "commands", "command", "@1", "@2", "@3", "hash", "@4", "comment", "@5", "shapeComment", "@6", "@7", "nonshapeComment", "@8", "@9", "terminator", "numeric", "debug", "yesno", "sp", "bp", "ep", "conjuction", "optangle", "angle", "value", "vvalue", "numberof", "sexagesimal", "hms", "dms", "coord", "coordSystem", "wcsSystem", "skyFrame", "skyDist", "property", "callBack", "global", "globalProperty", "globalRuler", "globalCompass", "initGlobal", "local", "localProperty", "localRuler", "localCompass", "localCpanda", "@10", "localEpanda", "@11", "localBpanda", "@12", "initLocal", "pointShape", "include", "nonshape", "shape", "@13", "@14", "polyNodes", "polyNode", "aRads", "aRad", "aAngs", "aAng", "vRads", "vRad", "postLocal", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 35, 10, 59, 44, 40, 41, 124, 61, 43, 45, 38, 33 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 139, 140, 141, 141, 142, 142, 142, 142, 142, 143, 142, 144, 142, 145, 142, 142, 142, 142, 146, 146, 146, 147, 146, 148, 149, 148, 150, 151, 150, 150, 152, 150, 153, 154, 153, 153, 155, 153, 156, 156, 156, 157, 157, 158, 158, 159, 159, 159, 159, 159, 159, 159, 159, 159, 160, 160, 161, 161, 162, 162, 163, 163, 163, 164, 164, 165, 165, 165, 166, 166, 166, 166, 166, 166, 167, 167, 167, 167, 167, 167, 168, 169, 170, 171, 172, 172, 172, 172, 172, 172, 172, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 182, 183, 184, 184, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 187, 189, 188, 188, 191, 190, 190, 193, 192, 192, 194, 195, 195, 195, 195, 195, 195, 195, 196, 196, 197, 197, 197, 197, 197, 197, 197, 198, 198, 198, 198, 198, 199, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 201, 201, 202, 203, 203, 204, 205, 205, 206, 207, 207, 208, 209 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 3, 2, 0, 2, 1, 3, 2, 0, 3, 0, 3, 0, 3, 2, 3, 3, 1, 2, 2, 0, 2, 0, 0, 3, 1, 0, 4, 3, 0, 5, 1, 0, 3, 2, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 4, 4, 3, 3, 3, 1, 1, 1, 3, 4, 4, 3, 3, 3, 7, 3, 3, 3, 4, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 0, 3, 1, 3, 3, 4, 4, 3, 3, 3, 3, 5, 1, 1, 1, 3, 4, 4, 3, 3, 3, 7, 3, 3, 3, 3, 3, 4, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 0, 7, 1, 0, 10, 1, 0, 10, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 6, 8, 8, 10, 8, 8, 8, 8, 10, 10, 10, 0, 7, 8, 10, 6, 0, 9, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 10, 10, 12, 12, 12, 14, 14, 18, 12, 14, 14, 18, 18, 20, 20, 10, 12, 12, 5, 8, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 0 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint16 yydefact[] = { 204, 0, 253, 1, 95, 126, 0, 94, 133, 125, 127, 128, 131, 0, 134, 130, 92, 129, 14, 93, 132, 0, 7, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 253, 0, 10, 96, 12, 0, 45, 44, 6, 180, 0, 0, 0, 178, 0, 145, 142, 141, 0, 139, 146, 0, 143, 0, 144, 0, 138, 179, 0, 0, 0, 0, 0, 0, 0, 55, 170, 24, 9, 0, 2, 41, 39, 40, 4, 24, 24, 57, 0, 57, 0, 57, 57, 57, 57, 57, 57, 0, 0, 57, 57, 57, 57, 57, 57, 275, 57, 57, 57, 57, 57, 0, 22, 261, 262, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 56, 8, 0, 15, 3, 11, 13, 58, 0, 57, 57, 0, 57, 0, 57, 0, 0, 0, 0, 0, 57, 57, 0, 0, 59, 0, 0, 0, 57, 0, 0, 0, 0, 0, 57, 57, 57, 57, 57, 57, 57, 0, 57, 18, 0, 0, 19, 17, 172, 0, 203, 201, 202, 0, 185, 0, 176, 0, 259, 255, 260, 254, 257, 256, 258, 181, 136, 137, 135, 0, 199, 0, 0, 198, 186, 177, 43, 42, 67, 68, 66, 188, 189, 184, 190, 175, 46, 54, 52, 51, 53, 49, 50, 48, 47, 171, 0, 169, 55, 55, 55, 82, 83, 84, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 0, 55, 55, 55, 55, 55, 0, 0, 55, 55, 60, 61, 55, 55, 59, 0, 55, 55, 55, 59, 55, 0, 0, 0, 0, 0, 0, 0, 21, 0, 23, 20, 173, 200, 0, 174, 183, 182, 196, 197, 192, 0, 193, 194, 195, 26, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 0, 59, 0, 59, 0, 0, 0, 64, 0, 59, 59, 0, 0, 62, 324, 0, 0, 61, 314, 55, 313, 0, 0, 0, 0, 61, 0, 59, 55, 55, 55, 55, 55, 59, 55, 0, 0, 89, 91, 90, 88, 85, 86, 87, 72, 73, 74, 70, 71, 69, 55, 61, 61, 55, 55, 55, 55, 55, 55, 55, 61, 55, 61, 59, 59, 59, 59, 65, 55, 61, 61, 55, 55, 63, 28, 310, 27, 59, 55, 324, 0, 61, 55, 55, 59, 59, 324, 55, 61, 0, 0, 64, 0, 0, 61, 0, 0, 191, 0, 324, 324, 0, 0, 0, 0, 0, 0, 64, 324, 0, 324, 61, 61, 61, 61, 0, 324, 324, 64, 0, 218, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 55, 206, 61, 0, 282, 312, 324, 0, 64, 61, 280, 279, 0, 324, 59, 59, 59, 55, 59, 324, 55, 187, 55, 288, 284, 78, 79, 80, 76, 77, 75, 67, 66, 59, 55, 289, 55, 283, 324, 324, 324, 324, 55, 286, 285, 59, 55, 55, 250, 0, 0, 0, 0, 244, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 30, 324, 55, 276, 59, 59, 324, 61, 59, 287, 61, 61, 61, 0, 61, 264, 0, 55, 33, 0, 0, 61, 61, 64, 0, 270, 271, 291, 311, 0, 61, 64, 0, 252, 230, 0, 0, 163, 161, 156, 0, 166, 150, 167, 153, 165, 159, 148, 162, 151, 149, 168, 164, 0, 208, 0, 243, 241, 242, 0, 223, 246, 228, 0, 0, 249, 229, 0, 212, 0, 219, 0, 239, 0, 0, 238, 224, 214, 213, 226, 227, 222, 211, 29, 207, 324, 205, 277, 0, 61, 61, 61, 290, 324, 61, 324, 324, 324, 59, 324, 324, 0, 36, 59, 0, 317, 59, 55, 316, 324, 0, 324, 72, 69, 59, 55, 55, 55, 322, 55, 55, 0, 324, 59, 55, 55, 55, 0, 155, 152, 158, 157, 154, 160, 0, 209, 240, 0, 0, 210, 0, 221, 220, 236, 237, 232, 0, 233, 234, 235, 32, 320, 59, 59, 319, 324, 324, 324, 281, 324, 268, 266, 269, 61, 265, 35, 324, 61, 0, 61, 0, 61, 293, 0, 273, 61, 0, 64, 64, 0, 0, 0, 272, 61, 64, 64, 0, 55, 215, 0, 55, 55, 0, 61, 0, 61, 307, 292, 274, 278, 324, 38, 324, 81, 324, 315, 324, 57, 324, 323, 59, 59, 321, 55, 55, 57, 324, 59, 59, 55, 0, 0, 0, 0, 231, 324, 318, 324, 267, 263, 295, 294, 0, 300, 61, 61, 0, 0, 0, 296, 61, 61, 0, 0, 225, 0, 0, 309, 308, 55, 324, 324, 55, 55, 55, 324, 324, 55, 55, 55, 55, 0, 302, 301, 0, 0, 0, 297, 298, 0, 0, 0, 245, 0, 55, 55, 59, 55, 55, 0, 0, 64, 64, 61, 64, 64, 0, 0, 59, 59, 324, 59, 59, 251, 248, 303, 61, 304, 299, 61, 324, 324, 306, 305 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 51, 52, 96, 97, 88, 187, 188, 145, 240, 389, 455, 525, 542, 543, 628, 95, 248, 59, 239, 721, 152, 269, 328, 380, 381, 642, 373, 633, 249, 250, 251, 332, 53, 54, 55, 217, 456, 580, 86, 87, 218, 197, 2, 544, 458, 603, 586, 589, 590, 593, 594, 561, 562, 56, 209, 126, 190, 127, 172, 534, 333, 334, 634, 635, 680, 681, 644, 645, 390 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -615 static const yytype_int16 yypact[] = { -615, 60, 1544, -615, -615, -615, 50, -615, -615, -615, -615, -615, -615, 2401, -615, -615, -615, -615, -615, -615, -615, 47, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 1372, 39, -615, -615, -615, 1150, -615, -615, -615, -615, -63, -56, -39, -35, -31, -615, -615, -615, -28, -615, -615, 5, -615, 6, -615, 17, -615, 20, 38, 45, 53, 67, 76, 80, 81, 123, -615, -13, -615, 39, -615, -615, -615, -615, -615, -13, -13, 16, 126, -27, 145, 16, -26, 16, 16, 16, 16, 146, 148, 16, 16, 16, 16, 16, 16, -615, 16, 16, 16, 16, 16, 150, 403, -615, -615, 753, -615, 33, 1979, 222, 226, 225, 229, 93, 1658, 231, 119, 251, 252, 2430, 258, 139, -615, -615, -615, 2401, -615, -615, -615, -615, -615, 518, 16, 16, 518, 16, 518, 16, 518, 518, 518, 518, 518, 16, 16, 518, 518, 131, 518, 518, 518, 16, 518, 518, 518, 518, 518, 16, 16, 16, 16, 16, 16, 16, 263, 16, -615, 262, 261, -615, -615, -615, 274, -615, 578, -615, 275, -615, 265, -615, 268, -615, -615, -615, -615, -615, -615, -615, 285, -615, -615, -615, 2193, -615, 1872, 2193, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 286, -615, 165, 165, 165, -615, -615, -615, 165, 165, 165, 165, 165, 518, 518, 165, 518, 165, 518, 165, 165, 165, 165, 165, 518, 518, 165, 165, -615, 164, 165, 165, 131, 518, 165, 165, 165, 14, 165, 518, 518, 518, 518, 518, 518, 518, -615, 518, -615, -615, -615, -615, 293, -615, -615, -615, -615, -615, -615, 2300, -615, -615, -615, -615, 296, 294, 292, 125, 302, 291, 291, 358, 131, 131, 375, 131, 119, 131, 358, 358, 358, 119, 119, 131, 131, 375, 119, 185, 198, 518, 119, 164, -615, 116, -615, 518, 375, 518, 321, 164, 358, 131, 165, 165, 165, 165, 165, 131, 165, 324, 97, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 165, 164, 164, 165, 165, 165, 165, 165, 165, 165, 164, 165, 164, 131, 131, 131, 131, -615, 165, 164, 164, 165, 165, -615, 2302, -615, -615, 131, 165, 198, 518, 164, 165, 165, 131, 131, 198, 165, 164, 358, 358, 119, 518, 518, 164, 358, 326, -615, 358, 198, 198, 333, 332, 334, 335, 331, 125, 659, 198, 119, 198, 164, 164, 164, 164, 119, 198, 198, 659, 119, -615, 213, 216, 218, 219, 220, 223, -35, 224, 238, 239, 241, 242, 253, 20, 256, 260, 264, 267, 272, 276, 354, 277, 75, -615, 164, 119, -615, -615, 198, 358, 119, 164, -615, -615, 119, 198, 131, 131, 131, 165, 131, 1490, 165, -615, 116, -615, -615, -615, -615, -615, -615, -615, -615, 22, 29, 131, 165, -615, 165, -615, 198, 198, 198, 198, 165, -615, -615, 131, 165, 165, 301, 1017, 34, 2086, 360, 336, 389, 337, 392, 396, 93, 1765, 395, 404, 119, 411, 412, 413, -615, 139, 414, 2302, -615, 198, 116, -615, 131, 131, 198, 164, 131, -615, 164, 164, 164, 358, 164, -615, 415, 83, -615, 119, 313, 164, -71, 266, 418, -615, -615, -615, -615, 419, -64, 266, 420, -615, -615, 299, -8, -615, -615, -615, 58, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 426, -615, 431, -615, 578, -615, 432, -615, -615, -615, 307, 437, -615, -615, 310, -615, 439, 441, 2193, -615, 1872, 2193, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 234, 164, 164, 164, -615, 198, 164, 1490, 1490, 1490, 131, 1490, -615, 442, -615, 131, 312, -615, 131, 116, -615, 198, 311, 198, 180, 203, 131, 165, 165, 165, -615, 165, 165, 316, 198, 131, 165, 165, 165, 119, -615, -615, -615, -615, -615, -615, 443, -615, -615, 445, 119, -615, 119, -615, -615, -615, -615, -615, 2300, -615, -615, -615, -615, -615, 131, 23, -615, 198, 198, 198, -615, 198, -615, -615, -615, 164, -615, -615, -615, 164, 454, 164, 358, 164, -615, 435, -615, 164, 358, 119, 678, 375, 358, 416, -615, 164, 119, 678, 375, -96, -615, 458, -58, -53, 97, 164, 119, 164, -615, -615, -615, -615, 1490, -615, 1490, -615, 198, -615, 198, 16, 198, -615, 131, 131, -615, 165, 165, 16, 198, 131, 131, 165, 339, 459, 340, 341, -615, 198, -615, 198, -615, -615, -615, -615, 518, -615, 164, 164, 375, 358, 518, -615, 164, 164, 375, 358, -615, 358, 358, -615, -615, 165, 198, 198, 165, 165, 165, 198, 198, 165, -20, 13, 66, 375, -615, -615, 460, 462, 375, -615, -615, 463, 342, 358, -615, 344, 165, 165, 131, 165, 165, 119, 119, 119, 119, 164, 119, 119, 345, 346, 131, 131, 198, 131, 131, -615, -615, -615, 164, -615, -615, 164, 198, 198, -615, -615 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -615, -615, -615, 417, -615, -615, -615, -615, -615, -33, -615, 608, -615, -615, -530, -615, -615, 377, 183, -615, -48, -86, -97, 586, 585, -356, -95, -170, -324, -513, 173, -615, -127, 591, -83, 347, -104, -172, -9, -615, -615, 338, -615, -615, -615, 94, -41, -615, -615, -615, -615, -615, -615, -615, -615, -615, -29, 366, 303, 372, -615, -615, -615, 106, -266, -190, -614, -211, -547, -605, -49 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -325 static const yytype_int16 yytable[] = { 146, 385, 91, 155, 85, 157, 159, 160, 161, 162, 163, 652, 397, 166, 167, 168, 169, 170, 171, -55, 173, 174, 175, 176, 177, 196, -55, -55, -55, -55, -55, 216, -55, -55, 144, 655, 747, 643, 192, 581, 714, 297, 225, 300, 302, 651, 195, 154, 158, 473, 89, 717, 215, 718, 92, 147, 253, 254, 656, 256, 3, 258, 327, 149, 150, 490, 637, 264, 265, 327, 657, 128, 144, 648, 749, 273, 502, 144, 129, 750, -31, 279, 280, 281, 282, 283, 284, 285, -37, 287, -324, 291, 687, 688, 689, 130, 691, 491, -324, -140, 739, 658, 679, 131, 151, 151, 132, 739, 503, 532, 144, 299, 797, 202, 143, 210, 211, 203, 204, 57, 58, 205, 220, 221, 659, 222, 223, 206, 220, 221, 296, -59, 298, 301, 207, 212, 660, 85, -24, 133, 134, 364, 230, 144, 144, 799, 268, 151, 377, 378, 379, 135, 144, 144, -147, 268, 304, 305, 306, 144, 193, 582, 307, 308, 309, 310, 311, 93, 94, 314, 401, 316, 136, 318, 319, 320, 321, 322, 411, 137, 325, 326, 356, 357, 329, 330, 231, 138, 335, 336, 337, 338, 340, 739, 641, -67, 144, 755, 800, 756, 153, 139, 650, -324, -324, 144, 232, 233, 234, 235, 140, -324, -324, 144, 141, 142, 350, 208, -66, 156, 164, 375, 165, 785, 178, 198, 787, 382, 236, 199, 200, 386, 201, 471, 472, 392, 219, 220, 221, 477, 222, 223, 479, -59, -59, -59, 144, 394, 268, -59, 143, -24, -24, 144, 226, 227, 403, 404, 405, 406, 407, 229, 409, 268, 237, 238, 286, 288, 293, 220, 221, 294, 639, 223, 359, 360, 361, 362, 412, 290, 292, 415, 416, 417, 418, 419, 420, 421, 295, 423, 179, 303, 180, 181, 531, 144, 429, 327, 349, 432, 433, 631, 351, 353, 352, 247, 460, -67, -67, -67, 464, 465, -67, -67, 245, 469, 220, 221, 387, 358, 224, 359, 360, 361, 362, 388, 399, 410, 493, 478, -66, -66, -66, 631, 499, -66, -66, 182, 504, 482, 483, 183, 486, 484, 602, 485, 184, 505, 737, 738, 506, 186, 507, 508, 509, 744, 745, 510, 511, 523, 560, 220, 221, 587, 358, 529, 359, 360, 361, 362, 625, 526, 512, 513, 535, 514, 515, 632, 220, 221, 631, 367, 740, 368, 369, 370, 371, 516, 540, 746, 517, 546, 591, 547, 518, 588, 592, 595, 519, 596, 604, 520, 415, 420, 585, 550, 521, 551, 527, 605, 522, 524, 601, 556, 607, 608, 609, 558, 559, 612, 627, 646, 647, 653, 606, 584, 671, 545, 674, 676, 654, 661, 179, 600, 180, 181, 662, 664, 665, 779, 666, 667, 668, 615, 669, 784, 695, 693, 715, 700, 716, 630, 815, 816, 708, 818, 819, 730, 526, 734, 742, 748, 771, 802, 801, 803, 805, 148, 90, 804, 770, 772, 773, 806, 610, 807, 611, 820, 821, 182, 663, 355, 457, 183, 241, 613, 597, 228, 184, 189, 354, 185, 289, 186, 363, 629, 673, 372, 191, 224, 462, 363, 363, 363, 224, 224, 786, 732, 372, 224, 753, 0, 0, 224, 0, 670, 0, 672, 675, 372, 678, 220, 221, 363, 242, 0, 0, 632, 243, 244, 245, 246, 247, 736, 0, 0, 0, 741, 124, 125, 0, 0, 0, 0, 0, 0, 0, 751, 697, 0, 0, 0, 0, 0, 0, 0, 703, 704, 705, 678, 706, 707, 0, 677, 0, 711, 712, 713, 0, 0, 678, 0, 678, 545, 545, 545, 0, 545, 692, 0, 0, 0, 0, 0, 0, 0, 363, 363, 224, 0, 719, 0, 363, 0, 780, 363, 0, 0, 0, 5, 0, 0, 632, 487, 489, 0, 224, 0, 0, 0, 0, 0, 224, 0, 0, 489, 224, 0, 0, 0, 8, 0, 0, 0, 0, 0, 678, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 759, 0, 0, 17, 0, 0, 224, 728, 765, 0, 363, 224, 0, 0, 0, 224, 0, 763, 764, 0, 0, 0, 0, 769, 20, 220, 221, 0, 488, 223, 368, 369, 370, 371, 0, 0, 0, 0, 0, 0, 0, 545, 0, 545, 220, 221, 0, 639, 223, 359, 360, 361, 362, 788, 0, 0, 791, 792, 793, 0, 0, 796, 798, 697, 798, 224, 0, 0, 0, 0, 0, 0, 0, 0, 813, 814, 0, 0, 808, 809, 0, 811, 812, 0, 0, 0, 363, 0, 0, 0, 0, 0, 224, 363, 0, 0, 640, 0, 0, 0, 0, 0, 0, 0, 640, 0, 252, 0, 0, 255, 0, 257, 0, 259, 260, 261, 262, 263, 0, 0, 266, 267, 0, 270, 271, 272, 0, 274, 275, 276, 277, 278, 0, 98, 0, 0, 99, 0, 0, 0, 100, 101, 102, 0, 103, 104, 0, 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, 109, 0, 0, 110, 224, 111, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 114, 0, 115, 116, 117, 0, 0, 118, 119, 0, 0, 0, 224, 120, 0, 0, 0, 0, 121, 312, 313, 0, 315, 224, 317, 224, 0, 0, 0, 0, 323, 324, 0, 331, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 341, 342, 343, 344, 345, 346, 347, 122, 348, 0, 363, 0, 0, 0, 0, 0, 363, 224, 640, 372, 363, 0, 0, 0, 224, 640, 372, 0, 365, 366, 0, 374, 0, 376, 224, 0, 0, 0, 0, 383, 384, 0, 0, 0, 0, 0, 393, 0, 0, 395, 391, 0, 0, 0, 400, 0, 396, 402, 398, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 363, 0, 0, 413, 414, 372, 363, 0, 363, 363, 0, 0, 422, 0, 424, 0, 425, 426, 427, 428, 0, 430, 431, 0, 372, 0, 0, 0, 0, 372, 459, 0, 0, 463, 363, 0, 0, 466, 467, 0, 470, 0, 224, 224, 224, 224, 476, 224, 224, 0, 474, 475, 0, 0, 461, 0, 0, 0, 0, 0, 0, 468, 0, 495, 496, 497, 498, 0, 0, 0, 0, 0, 0, 0, 480, 481, 0, 0, 0, 0, 0, 0, 0, 492, 0, 494, 0, 0, 0, 0, 0, 500, 501, 563, 0, 0, 0, 528, 0, 0, 564, 0, 0, 0, 533, 0, 0, 0, 0, 565, 537, 538, 539, 566, 541, 567, 0, 0, 548, 0, 0, 0, 0, 568, 530, 0, 0, 569, 0, 549, 0, 536, 0, 570, 0, 0, 571, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 572, 573, 0, 0, 574, 0, 0, 0, 575, 552, 553, 554, 555, 0, 0, 576, 577, 578, 0, 0, 0, 616, 0, 617, 618, 620, 0, 621, 622, 623, 624, 0, 626, 0, 0, 0, 0, 0, 0, 636, 638, 0, 614, 0, 0, 0, 579, 619, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 99, 0, 0, 0, 100, 101, 102, 0, 103, 104, 0, 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, 109, 0, 0, 110, 0, 111, 0, 112, 0, 0, 682, 683, 684, 0, 0, 686, 0, 0, 0, 0, 690, 0, 0, 113, 0, 694, 0, 0, 696, 698, 0, 114, 0, 115, 116, 117, 702, 685, 118, 119, 0, 0, 0, 0, 120, 710, 0, 0, 0, 121, 0, 0, 0, 699, 0, 701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 720, 722, 0, 0, 0, 0, 0, 0, 0, 122, 727, 0, 123, 0, 729, 0, 731, 0, 733, 0, 124, 125, 735, 0, 0, 723, 724, 725, 0, 726, 743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 752, 0, 754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 761, 762, 0, 0, 0, 0, 0, 767, 768, 0, 0, 0, 0, 0, 0, 0, 757, 0, 758, 0, 760, 0, 0, 777, 778, 0, 0, 776, 766, 782, 783, 0, 0, 781, 0, 0, 0, 774, 0, 775, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 789, 790, -5, 4, 810, 794, 795, 0, 5, 0, 817, 0, 0, 0, 0, 0, 822, 823, 0, 825, 826, 0, 0, 827, 6, 0, 828, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 824, 12, 13, 14, 0, 15, 0, 16, 0, 17, 829, 830, 18, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 21, 0, 0, 22, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, -34, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 434, 0, 0, 0, 435, 436, 0, 0, 437, 438, 439, 440, 0, 441, 442, 0, 0, 66, 0, 0, 0, 67, 0, 0, 443, 0, 0, 68, 0, 0, 0, 444, 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 445, 0, 73, 0, 0, -5, 4, 0, 0, 0, 446, 5, 0, 0, 75, 0, 447, 77, 448, 0, 449, 450, 451, 452, 0, 0, 453, 6, 0, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 13, 14, 0, 15, 0, 16, 0, 17, 0, 0, 18, 0, 0, 0, 454, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 21, 0, 0, 22, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, 0, 0, -5, -5, 4, 0, 210, 211, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 0, 16, 0, 17, 0, 0, 213, 0, 0, 0, 0, 0, 19, 0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 210, 211, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 0, 16, 0, 17, 0, 0, 598, 0, 0, 0, 0, 0, 19, 0, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 210, 211, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 0, 16, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 0, 16, 0, 17, 0, 0, 194, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 0, 12, 0, 14, 0, 15, 0, 16, 0, 17, 0, 0, 583, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 210, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 4, 0, 0, 0, 0, 0, 0, 0, 434, 0, 0, 0, 435, 436, 0, 0, 437, 438, 439, 440, 0, 441, 442, 0, 7, 66, 0, 0, 0, 67, 0, 0, 443, 0, 0, 68, 0, 0, 0, 444, 0, 0, 0, 70, 16, 0, 0, 71, 0, 0, 445, 0, 73, 0, 0, 19, 0, 0, 0, 0, 446, 0, 0, 0, 75, 0, 447, 77, 448, 0, 449, 450, 451, 452, 0, 0, 453, 0, 0, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 0, 454, 0, 0, 0, 0, 0, 61, 62, 63, 0, 0, 64, 65, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 68, 0, 0, 0, 69, 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 72, 0, 73, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 75, 0, 76, 77, 78, 0, 0, 79, 80, 81, 0, 0, 82, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 }; static const yytype_int16 yycheck[] = { 86, 325, 51, 100, 13, 102, 103, 104, 105, 106, 107, 558, 336, 110, 111, 112, 113, 114, 115, 5, 117, 118, 119, 120, 121, 129, 3, 4, 6, 6, 7, 135, 3, 4, 130, 43, 132, 550, 5, 5, 654, 213, 137, 215, 216, 558, 129, 74, 74, 405, 3, 665, 135, 667, 15, 88, 153, 154, 66, 156, 0, 158, 133, 96, 97, 421, 137, 164, 165, 133, 78, 134, 130, 137, 132, 172, 432, 130, 134, 132, 5, 178, 179, 180, 181, 182, 183, 184, 5, 186, 15, 195, 622, 623, 624, 134, 626, 421, 15, 134, 705, 43, 615, 134, 131, 131, 134, 712, 432, 465, 130, 215, 132, 20, 127, 18, 19, 24, 25, 69, 70, 28, 3, 4, 66, 6, 7, 34, 3, 4, 213, 15, 215, 216, 41, 38, 78, 146, 15, 134, 134, 311, 3, 130, 130, 132, 132, 131, 318, 319, 320, 134, 130, 130, 134, 132, 242, 243, 244, 130, 127, 127, 248, 249, 250, 251, 252, 128, 129, 255, 340, 257, 134, 259, 260, 261, 262, 263, 350, 134, 266, 267, 309, 310, 270, 271, 47, 134, 274, 275, 276, 277, 278, 798, 550, 15, 130, 727, 132, 729, 74, 134, 558, 128, 129, 130, 67, 68, 69, 70, 134, 128, 129, 130, 134, 134, 299, 124, 15, 74, 74, 316, 74, 770, 74, 3, 773, 322, 89, 3, 5, 326, 3, 403, 404, 330, 5, 3, 4, 409, 6, 7, 412, 127, 128, 129, 130, 333, 132, 133, 127, 128, 129, 130, 3, 3, 342, 343, 344, 345, 346, 3, 348, 132, 125, 126, 3, 5, 3, 3, 4, 3, 6, 7, 8, 9, 10, 11, 364, 5, 5, 367, 368, 369, 370, 371, 372, 373, 3, 375, 29, 5, 31, 32, 464, 130, 382, 133, 5, 385, 386, 67, 6, 11, 10, 14, 392, 127, 128, 129, 396, 397, 132, 133, 12, 401, 3, 4, 133, 6, 137, 8, 9, 10, 11, 127, 5, 3, 423, 3, 127, 128, 129, 67, 429, 132, 133, 76, 433, 6, 8, 80, 11, 9, 516, 10, 85, 134, 704, 705, 134, 90, 134, 134, 134, 711, 712, 134, 134, 5, 59, 3, 4, 3, 6, 460, 8, 9, 10, 11, 540, 457, 134, 134, 469, 134, 134, 547, 3, 4, 67, 6, 706, 8, 9, 10, 11, 134, 474, 713, 134, 477, 3, 479, 134, 59, 59, 5, 134, 3, 5, 134, 488, 489, 508, 491, 134, 493, 457, 5, 134, 134, 516, 499, 3, 3, 3, 503, 504, 5, 5, 3, 3, 3, 519, 508, 598, 476, 600, 601, 131, 5, 29, 516, 31, 32, 5, 5, 131, 763, 3, 131, 3, 529, 3, 769, 134, 5, 5, 138, 5, 546, 808, 809, 138, 811, 812, 3, 544, 24, 44, 3, 3, 3, 788, 3, 3, 90, 51, 793, 131, 131, 131, 131, 523, 131, 524, 132, 132, 76, 584, 308, 388, 80, 146, 526, 515, 140, 85, 123, 307, 88, 189, 90, 311, 544, 600, 314, 126, 316, 394, 318, 319, 320, 321, 322, 772, 697, 325, 326, 721, -1, -1, 330, -1, 598, -1, 600, 601, 336, 615, 3, 4, 340, 6, -1, -1, 697, 10, 11, 12, 13, 14, 703, -1, -1, -1, 707, 135, 136, -1, -1, -1, -1, -1, -1, -1, 719, 634, -1, -1, -1, -1, -1, -1, -1, 642, 643, 644, 654, 646, 647, -1, 612, -1, 651, 652, 653, -1, -1, 665, -1, 667, 622, 623, 624, -1, 626, 627, -1, -1, -1, -1, -1, -1, -1, 403, 404, 405, -1, 673, -1, 409, -1, 764, 412, -1, -1, -1, 21, -1, -1, 772, 420, 421, -1, 423, -1, -1, -1, -1, -1, 429, -1, -1, 432, 433, -1, -1, -1, 42, -1, -1, -1, -1, -1, 721, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, 734, -1, -1, 62, -1, -1, 460, 693, 742, -1, 464, 465, -1, -1, -1, 469, -1, 740, 741, -1, -1, -1, -1, 746, 83, 3, 4, -1, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, 727, -1, 729, 3, 4, -1, 6, 7, 8, 9, 10, 11, 776, -1, -1, 779, 780, 781, -1, -1, 784, 785, 786, 787, 519, -1, -1, -1, -1, -1, -1, -1, -1, 806, 807, -1, -1, 801, 802, -1, 804, 805, -1, -1, -1, 540, -1, -1, -1, -1, -1, 546, 547, -1, -1, 550, -1, -1, -1, -1, -1, -1, -1, 558, -1, 152, -1, -1, 155, -1, 157, -1, 159, 160, 161, 162, 163, -1, -1, 166, 167, -1, 169, 170, 171, -1, 173, 174, 175, 176, 177, -1, 17, -1, -1, 20, -1, -1, -1, 24, 25, 26, -1, 28, 29, -1, 31, 32, 33, 34, -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, 615, 46, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, 72, -1, 74, 75, 76, -1, -1, 79, 80, -1, -1, -1, 654, 85, -1, -1, -1, -1, 90, 253, 254, -1, 256, 665, 258, 667, -1, -1, -1, -1, 264, 265, -1, 272, -1, -1, -1, -1, 277, -1, -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, 284, 285, 124, 287, -1, 697, -1, -1, -1, -1, -1, 703, 704, 705, 706, 707, -1, -1, -1, 711, 712, 713, -1, 312, 313, -1, 315, -1, 317, 721, -1, -1, -1, -1, 323, 324, -1, -1, -1, -1, -1, 331, -1, -1, 333, 329, -1, -1, -1, 339, -1, 335, 341, 337, -1, -1, -1, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 763, 764, -1, -1, 365, 366, 769, 770, -1, 772, 773, -1, -1, 374, -1, 376, -1, 377, 378, 379, 380, -1, 383, 384, -1, 788, -1, -1, -1, -1, 793, 391, -1, -1, 395, 798, -1, -1, 398, 399, -1, 402, -1, 806, 807, 808, 809, 408, 811, 812, -1, 406, 407, -1, -1, 393, -1, -1, -1, -1, -1, -1, 400, -1, 425, 426, 427, 428, -1, -1, -1, -1, -1, -1, -1, 413, 414, -1, -1, -1, -1, -1, -1, -1, 422, -1, 424, -1, -1, -1, -1, -1, 430, 431, 23, -1, -1, -1, 459, -1, -1, 30, -1, -1, -1, 466, -1, -1, -1, -1, 39, 471, 472, 473, 43, 475, 45, -1, -1, 479, -1, -1, -1, -1, 53, 463, -1, -1, 57, -1, 490, -1, 470, -1, 63, -1, -1, 66, -1, -1, -1, -1, 502, -1, -1, -1, -1, -1, 77, 78, -1, -1, 81, -1, -1, -1, 85, 495, 496, 497, 498, -1, -1, 92, 93, 94, -1, -1, -1, 529, -1, 531, 532, 534, -1, 535, 537, 538, 539, -1, 541, -1, -1, -1, -1, -1, -1, 548, 549, -1, 528, -1, -1, -1, 123, 533, 557, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 20, -1, -1, -1, 24, 25, 26, -1, 28, 29, -1, 31, 32, 33, 34, -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, 46, -1, 48, -1, -1, 616, 617, 618, -1, -1, 621, -1, -1, -1, -1, 625, -1, -1, 64, -1, 630, -1, -1, 633, 634, -1, 72, -1, 74, 75, 76, 641, 620, 79, 80, -1, -1, -1, -1, 85, 650, -1, -1, -1, 90, -1, -1, -1, 636, -1, 638, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 649, -1, -1, -1, -1, -1, -1, -1, 679, 680, -1, -1, -1, -1, -1, -1, -1, 124, 690, -1, 127, -1, 694, -1, 696, -1, 698, -1, 135, 136, 702, -1, -1, 682, 683, 684, -1, 686, 710, -1, -1, -1, -1, -1, -1, -1, -1, -1, 720, -1, 722, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 737, 738, -1, -1, -1, -1, -1, 744, 745, -1, -1, -1, -1, -1, -1, -1, 731, -1, 733, -1, 735, -1, -1, 761, 762, -1, -1, 759, 743, 767, 768, -1, -1, 765, -1, -1, -1, 752, -1, 754, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 777, 778, 15, 16, 803, 782, 783, -1, 21, -1, 810, -1, -1, -1, -1, -1, 815, 816, -1, 818, 819, -1, -1, 823, 37, -1, 826, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, 817, 54, 55, 56, -1, 58, -1, 60, -1, 62, 827, 828, 65, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, 88, -1, -1, 91, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 5, -1, -1, -1, -1, 128, 129, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, 26, 27, -1, -1, 30, 31, 32, 33, -1, 35, 36, -1, -1, 39, -1, -1, -1, 43, -1, -1, 46, -1, -1, 49, -1, -1, -1, 53, -1, -1, -1, 57, -1, -1, -1, 61, -1, -1, 64, -1, 66, -1, -1, 15, 16, -1, -1, -1, 74, 21, -1, -1, 78, -1, 80, 81, 82, -1, 84, 85, 86, 87, -1, -1, 90, 37, -1, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, 55, 56, -1, 58, -1, 60, -1, 62, -1, -1, 65, -1, -1, -1, 123, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, 88, -1, -1, 91, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, -1, -1, -1, -1, -1, 128, 129, 16, -1, 18, 19, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, -1, 60, -1, 62, -1, -1, 65, -1, -1, -1, -1, -1, 71, -1, 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, 18, 19, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, -1, 60, -1, 62, -1, -1, 65, -1, -1, -1, -1, -1, 71, -1, 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, 18, 19, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, -1, 60, -1, 62, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, -1, 60, -1, 62, -1, -1, 65, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, 42, -1, -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, 54, -1, 56, -1, 58, -1, 60, -1, 62, -1, -1, 65, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, 18, 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 16, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, 26, 27, -1, -1, 30, 31, 32, 33, -1, 35, 36, -1, 40, 39, -1, -1, -1, 43, -1, -1, 46, -1, -1, 49, -1, -1, -1, 53, -1, -1, -1, 57, 60, -1, -1, 61, -1, -1, 64, -1, 66, -1, -1, 71, -1, -1, -1, -1, 74, -1, -1, -1, 78, -1, 80, 81, 82, -1, 84, 85, 86, 87, -1, -1, 90, -1, -1, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 22, -1, 123, -1, -1, -1, -1, -1, 30, 31, 32, -1, -1, 35, 36, -1, -1, 39, -1, -1, -1, 43, -1, -1, -1, -1, -1, 49, -1, -1, -1, 53, -1, -1, -1, 57, -1, -1, -1, 61, -1, -1, 64, -1, 66, -1, -1, -1, -1, -1, -1, -1, 74, -1, -1, -1, 78, -1, 80, 81, 82, -1, -1, 85, 86, 87, -1, -1, 90, -1, -1, -1, -1, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 123, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 140, 183, 0, 16, 21, 37, 40, 42, 50, 51, 52, 54, 55, 56, 58, 60, 62, 65, 71, 83, 88, 91, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 141, 142, 173, 174, 175, 194, 69, 70, 158, 22, 30, 31, 32, 35, 36, 39, 43, 49, 53, 57, 61, 64, 66, 74, 78, 80, 81, 82, 85, 86, 87, 90, 95, 123, 177, 179, 180, 145, 3, 142, 209, 15, 128, 129, 156, 143, 144, 17, 20, 24, 25, 26, 28, 29, 31, 32, 33, 34, 41, 44, 46, 48, 64, 72, 74, 75, 76, 79, 80, 85, 90, 124, 127, 135, 136, 196, 198, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 127, 130, 148, 160, 148, 156, 148, 148, 131, 161, 74, 74, 161, 74, 161, 74, 161, 161, 161, 161, 161, 74, 74, 161, 161, 161, 161, 161, 161, 199, 161, 161, 161, 161, 161, 74, 29, 31, 32, 76, 80, 85, 88, 90, 146, 147, 196, 197, 198, 5, 127, 65, 173, 175, 182, 3, 3, 5, 3, 20, 24, 25, 28, 34, 41, 124, 195, 18, 19, 38, 65, 73, 173, 175, 176, 181, 5, 3, 4, 6, 7, 157, 165, 3, 3, 174, 3, 3, 47, 67, 68, 69, 70, 89, 125, 126, 159, 149, 180, 6, 10, 11, 12, 13, 14, 157, 169, 170, 171, 172, 161, 161, 172, 161, 172, 161, 172, 172, 172, 172, 172, 161, 161, 172, 172, 132, 162, 172, 172, 172, 161, 172, 172, 172, 172, 172, 161, 161, 161, 161, 161, 161, 161, 3, 161, 5, 197, 5, 175, 5, 3, 3, 3, 173, 176, 173, 175, 176, 173, 176, 5, 160, 160, 160, 160, 160, 160, 160, 160, 172, 172, 160, 172, 160, 172, 160, 160, 160, 160, 160, 172, 172, 160, 160, 133, 163, 160, 160, 162, 172, 201, 202, 160, 160, 160, 160, 162, 160, 172, 172, 172, 172, 172, 172, 172, 172, 5, 173, 6, 10, 11, 157, 169, 171, 171, 6, 8, 9, 10, 11, 157, 166, 162, 162, 6, 8, 9, 10, 11, 157, 167, 162, 165, 162, 166, 166, 166, 164, 165, 165, 162, 162, 167, 165, 133, 127, 150, 209, 172, 165, 163, 160, 162, 172, 167, 172, 5, 163, 166, 162, 160, 160, 160, 160, 160, 162, 160, 3, 176, 160, 163, 163, 160, 160, 160, 160, 160, 160, 160, 163, 160, 163, 162, 162, 162, 162, 160, 163, 163, 160, 160, 22, 26, 27, 30, 31, 32, 33, 35, 36, 46, 53, 64, 74, 80, 82, 84, 85, 86, 87, 90, 123, 151, 177, 184, 185, 162, 160, 150, 202, 163, 160, 160, 162, 162, 150, 160, 163, 166, 166, 164, 172, 172, 163, 166, 3, 166, 150, 150, 6, 8, 9, 10, 11, 157, 6, 157, 164, 167, 150, 165, 150, 163, 163, 163, 163, 165, 150, 150, 164, 167, 165, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 5, 134, 152, 160, 209, 163, 165, 150, 166, 164, 163, 200, 165, 150, 162, 162, 162, 160, 162, 153, 154, 184, 209, 160, 160, 162, 162, 160, 160, 150, 150, 150, 150, 160, 162, 160, 160, 59, 192, 193, 23, 30, 39, 43, 45, 53, 57, 63, 66, 77, 78, 81, 85, 92, 93, 94, 123, 178, 5, 127, 65, 173, 175, 187, 3, 59, 188, 189, 3, 59, 190, 191, 5, 3, 195, 65, 73, 173, 175, 176, 186, 5, 5, 165, 3, 3, 3, 209, 159, 5, 185, 150, 160, 162, 162, 162, 150, 163, 162, 163, 163, 163, 166, 163, 5, 155, 209, 165, 67, 166, 168, 203, 204, 163, 137, 163, 6, 157, 164, 166, 168, 207, 208, 3, 3, 137, 163, 164, 168, 207, 3, 131, 43, 66, 78, 43, 66, 78, 5, 5, 175, 5, 131, 3, 131, 3, 3, 173, 176, 173, 175, 176, 173, 176, 209, 165, 168, 205, 206, 163, 163, 163, 150, 163, 153, 153, 153, 162, 153, 209, 5, 162, 134, 162, 160, 162, 150, 138, 150, 162, 160, 160, 160, 160, 160, 138, 150, 162, 160, 160, 160, 205, 5, 5, 205, 205, 173, 162, 160, 162, 150, 150, 150, 150, 163, 209, 163, 3, 163, 204, 163, 24, 163, 166, 164, 164, 208, 167, 166, 44, 163, 164, 164, 167, 132, 3, 132, 132, 176, 163, 206, 163, 153, 153, 150, 150, 161, 150, 162, 162, 160, 160, 161, 150, 162, 162, 160, 131, 3, 131, 131, 150, 150, 172, 163, 163, 167, 166, 172, 163, 163, 167, 207, 203, 207, 160, 150, 150, 160, 160, 160, 150, 150, 160, 132, 160, 132, 132, 167, 3, 3, 167, 3, 131, 131, 160, 160, 162, 160, 160, 165, 165, 164, 164, 163, 164, 164, 132, 132, 162, 162, 150, 162, 162, 163, 163, 150, 150 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, mkFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; mkFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, mkFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; mkFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, mkFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; mkFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, mkFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; mkFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, mkFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, mkFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; mkFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 7: #line 303 "ds9parser.Y" {cerr << "DS9 Regions File 3.2" << endl;;} break; case 9: #line 306 "ds9parser.Y" {globalTile = (yyvsp[(2) - (2)].integer);;} break; case 10: #line 308 "ds9parser.Y" {globalSystem=(Coord::CoordSystem)(yyvsp[(1) - (1)].integer);;} break; case 12: #line 309 "ds9parser.Y" {globalSystem=globalWCS; globalSky=(Coord::SkyFrame)(yyvsp[(1) - (1)].integer);;} break; case 14: #line 310 "ds9parser.Y" {globalSystem=globalWCS; globalSky=Coord::FK5;;} break; case 21: #line 319 "ds9parser.Y" {globalTile = (yyvsp[(2) - (2)].integer);;} break; case 22: #line 320 "ds9parser.Y" {DISCARD_(1);} break; case 25: #line 324 "ds9parser.Y" {DISCARD_(1);} break; case 28: #line 328 "ds9parser.Y" {DISCARD_(1);} break; case 29: #line 328 "ds9parser.Y" {strncpy(localComment,(yyvsp[(3) - (4)].str),80);} break; case 31: #line 330 "ds9parser.Y" {DISCARD_(1);} break; case 32: #line 331 "ds9parser.Y" {strncpy(localComment,(yyvsp[(4) - (5)].str),80);} break; case 34: #line 335 "ds9parser.Y" {DISCARD_(1);} break; case 35: #line 335 "ds9parser.Y" {strncpy(localComment,(yyvsp[(2) - (3)].str),80);} break; case 37: #line 337 "ds9parser.Y" {DISCARD_(1);} break; case 38: #line 337 "ds9parser.Y" {strncpy(localComment,(yyvsp[(3) - (4)].str),80);} break; case 41: #line 342 "ds9parser.Y" {YYACCEPT;;} break; case 42: #line 345 "ds9parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 43: #line 346 "ds9parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 44: #line 349 "ds9parser.Y" {yydebug=1;;} break; case 45: #line 350 "ds9parser.Y" {yydebug=0;;} break; case 46: #line 353 "ds9parser.Y" {(yyval.integer)=((yyvsp[(1) - (1)].integer) ? 1 : 0);;} break; case 47: #line 355 "ds9parser.Y" {(yyval.integer)=1;;} break; case 48: #line 356 "ds9parser.Y" {(yyval.integer)=1;;} break; case 49: #line 357 "ds9parser.Y" {(yyval.integer)=1;;} break; case 50: #line 358 "ds9parser.Y" {(yyval.integer)=1;;} break; case 51: #line 360 "ds9parser.Y" {(yyval.integer)=0;;} break; case 52: #line 361 "ds9parser.Y" {(yyval.integer)=0;;} break; case 53: #line 362 "ds9parser.Y" {(yyval.integer)=0;;} break; case 54: #line 363 "ds9parser.Y" {(yyval.integer)=0;;} break; case 61: #line 378 "ds9parser.Y" {cStatus = 0;;} break; case 62: #line 379 "ds9parser.Y" {cStatus = 1;;} break; case 63: #line 380 "ds9parser.Y" {cStatus = 1;;} break; case 64: #line 383 "ds9parser.Y" {(yyval.real) = fr->mapAngleToRef(0,localSystem,localSky);;} break; case 65: #line 384 "ds9parser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 66: #line 387 "ds9parser.Y" {(yyval.real) = fr->mapAngleToRef(degToRad((yyvsp[(1) - (1)].real)),localSystem,localSky);;} break; case 67: #line 388 "ds9parser.Y" {(yyval.real) = fr->mapAngleToRef(degToRad((yyvsp[(1) - (1)].real)),localSystem,localSky);;} break; case 68: #line 389 "ds9parser.Y" {(yyval.real) = fr->mapAngleToRef((yyvsp[(1) - (1)].real),localSystem,localSky);;} break; case 69: #line 392 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), localSystem, Coord::DEGREE);;} break; case 70: #line 393 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::PHYSICAL);;} break; case 71: #line 394 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::IMAGE);;} break; case 72: #line 395 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::DEGREE);;} break; case 73: #line 396 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::ARCMIN);;} break; case 74: #line 397 "ds9parser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::ARCSEC);;} break; case 75: #line 401 "ds9parser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), localSystem, Coord::DEGREE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 76: #line 408 "ds9parser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::PHYSICAL); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 77: #line 415 "ds9parser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 78: #line 422 "ds9parser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::DEGREE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 79: #line 429 "ds9parser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::ARCMIN); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 80: #line 436 "ds9parser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::ARCSEC); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 81: #line 444 "ds9parser.Y" {(yyval.integer) = (yyvsp[(3) - (3)].integer);;} break; case 82: #line 447 "ds9parser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 83: #line 450 "ds9parser.Y" {(yyval.real) = parseHMSStr((yyvsp[(1) - (1)].str));;} break; case 84: #line 453 "ds9parser.Y" {(yyval.real) = parseDMSStr((yyvsp[(1) - (1)].str));;} break; case 85: #line 457 "ds9parser.Y" { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), sys, sky); else r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real)*360./24.,(yyvsp[(3) - (3)].real)), sys, sky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 86: #line 470 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 87: #line 478 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 88: #line 486 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), localSystem, localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 89: #line 493 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 90: #line 501 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 91: #line 508 "ds9parser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::PHYSICAL); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; ;} break; case 92: #line 515 "ds9parser.Y" {(yyval.integer) = Coord::IMAGE;;} break; case 93: #line 516 "ds9parser.Y" {(yyval.integer) = Coord::PHYSICAL;;} break; case 94: #line 517 "ds9parser.Y" {(yyval.integer) = Coord::DETECTOR;;} break; case 95: #line 518 "ds9parser.Y" {(yyval.integer) = Coord::AMPLIFIER;;} break; case 96: #line 519 "ds9parser.Y" {(yyval.integer) = (yyvsp[(1) - (1)].integer); globalWCS = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer);;} break; case 97: #line 522 "ds9parser.Y" {(yyval.integer) = Coord::WCS;;} break; case 98: #line 523 "ds9parser.Y" {(yyval.integer) = Coord::WCSA;;} break; case 99: #line 524 "ds9parser.Y" {(yyval.integer) = Coord::WCSB;;} break; case 100: #line 525 "ds9parser.Y" {(yyval.integer) = Coord::WCSC;;} break; case 101: #line 526 "ds9parser.Y" {(yyval.integer) = Coord::WCSD;;} break; case 102: #line 527 "ds9parser.Y" {(yyval.integer) = Coord::WCSE;;} break; case 103: #line 528 "ds9parser.Y" {(yyval.integer) = Coord::WCSF;;} break; case 104: #line 529 "ds9parser.Y" {(yyval.integer) = Coord::WCSG;;} break; case 105: #line 530 "ds9parser.Y" {(yyval.integer) = Coord::WCSH;;} break; case 106: #line 531 "ds9parser.Y" {(yyval.integer) = Coord::WCSI;;} break; case 107: #line 532 "ds9parser.Y" {(yyval.integer) = Coord::WCSJ;;} break; case 108: #line 533 "ds9parser.Y" {(yyval.integer) = Coord::WCSK;;} break; case 109: #line 534 "ds9parser.Y" {(yyval.integer) = Coord::WCSL;;} break; case 110: #line 535 "ds9parser.Y" {(yyval.integer) = Coord::WCSM;;} break; case 111: #line 536 "ds9parser.Y" {(yyval.integer) = Coord::WCSN;;} break; case 112: #line 537 "ds9parser.Y" {(yyval.integer) = Coord::WCSO;;} break; case 113: #line 538 "ds9parser.Y" {(yyval.integer) = Coord::WCSP;;} break; case 114: #line 539 "ds9parser.Y" {(yyval.integer) = Coord::WCSQ;;} break; case 115: #line 540 "ds9parser.Y" {(yyval.integer) = Coord::WCSR;;} break; case 116: #line 541 "ds9parser.Y" {(yyval.integer) = Coord::WCSS;;} break; case 117: #line 542 "ds9parser.Y" {(yyval.integer) = Coord::WCST;;} break; case 118: #line 543 "ds9parser.Y" {(yyval.integer) = Coord::WCSU;;} break; case 119: #line 544 "ds9parser.Y" {(yyval.integer) = Coord::WCSV;;} break; case 120: #line 545 "ds9parser.Y" {(yyval.integer) = Coord::WCSW;;} break; case 121: #line 546 "ds9parser.Y" {(yyval.integer) = Coord::WCSX;;} break; case 122: #line 547 "ds9parser.Y" {(yyval.integer) = Coord::WCSY;;} break; case 123: #line 548 "ds9parser.Y" {(yyval.integer) = Coord::WCSZ;;} break; case 124: #line 549 "ds9parser.Y" {(yyval.integer) = Coord::WCS0;;} break; case 125: #line 552 "ds9parser.Y" {(yyval.integer) = Coord::FK4;;} break; case 126: #line 553 "ds9parser.Y" {(yyval.integer) = Coord::FK4;;} break; case 127: #line 554 "ds9parser.Y" {(yyval.integer) = Coord::FK4_NO_E;;} break; case 128: #line 555 "ds9parser.Y" {(yyval.integer) = Coord::FK5;;} break; case 129: #line 556 "ds9parser.Y" {(yyval.integer) = Coord::FK5;;} break; case 130: #line 557 "ds9parser.Y" {(yyval.integer) = Coord::ICRS;;} break; case 131: #line 558 "ds9parser.Y" {(yyval.integer) = Coord::GALACTIC;;} break; case 132: #line 559 "ds9parser.Y" {(yyval.integer) = Coord::SUPERGALACTIC;;} break; case 133: #line 560 "ds9parser.Y" {(yyval.integer) = Coord::ECLIPTIC;;} break; case 134: #line 561 "ds9parser.Y" {(yyval.integer) = Coord::HELIOECLIPTIC;;} break; case 135: #line 564 "ds9parser.Y" {(yyval.integer)=Coord::DEGREE;;} break; case 136: #line 565 "ds9parser.Y" {(yyval.integer)=Coord::ARCMIN;;} break; case 137: #line 566 "ds9parser.Y" {(yyval.integer)=Coord::ARCSEC;;} break; case 138: #line 569 "ds9parser.Y" {(yyval.integer) = Marker::SELECT;;} break; case 139: #line 570 "ds9parser.Y" {(yyval.integer) = Marker::HIGHLITE;;} break; case 140: #line 571 "ds9parser.Y" {(yyval.integer) = Marker::DASH;;} break; case 141: #line 572 "ds9parser.Y" {(yyval.integer) = Marker::FIXED;;} break; case 142: #line 573 "ds9parser.Y" {(yyval.integer) = Marker::EDIT;;} break; case 143: #line 574 "ds9parser.Y" {(yyval.integer) = Marker::MOVE;;} break; case 144: #line 575 "ds9parser.Y" {(yyval.integer) = Marker::ROTATE;;} break; case 145: #line 576 "ds9parser.Y" {(yyval.integer) = Marker::DELETE;;} break; case 146: #line 577 "ds9parser.Y" {(yyval.integer) = Marker::INCLUDE;;} break; case 147: #line 578 "ds9parser.Y" {(yyval.integer) = Marker::SOURCE;;} break; case 148: #line 581 "ds9parser.Y" {(yyval.integer) = CallBack::SELECTCB;;} break; case 149: #line 582 "ds9parser.Y" {(yyval.integer) = CallBack::UNSELECTCB;;} break; case 150: #line 583 "ds9parser.Y" {(yyval.integer) = CallBack::HIGHLITECB;;} break; case 151: #line 584 "ds9parser.Y" {(yyval.integer) = CallBack::UNHIGHLITECB;;} break; case 152: #line 585 "ds9parser.Y" {(yyval.integer) = CallBack::MOVEBEGINCB;;} break; case 153: #line 586 "ds9parser.Y" {(yyval.integer) = CallBack::MOVECB;;} break; case 154: #line 587 "ds9parser.Y" {(yyval.integer) = CallBack::MOVEENDCB;;} break; case 155: #line 588 "ds9parser.Y" {(yyval.integer) = CallBack::EDITBEGINCB;;} break; case 156: #line 589 "ds9parser.Y" {(yyval.integer) = CallBack::EDITCB;;} break; case 157: #line 590 "ds9parser.Y" {(yyval.integer) = CallBack::EDITENDCB;;} break; case 158: #line 591 "ds9parser.Y" {(yyval.integer) = CallBack::ROTATEBEGINCB;;} break; case 159: #line 592 "ds9parser.Y" {(yyval.integer) = CallBack::ROTATECB;;} break; case 160: #line 593 "ds9parser.Y" {(yyval.integer) = CallBack::ROTATEENDCB;;} break; case 161: #line 594 "ds9parser.Y" {(yyval.integer) = CallBack::DELETECB;;} break; case 162: #line 595 "ds9parser.Y" {(yyval.integer) = CallBack::TEXTCB;;} break; case 163: #line 596 "ds9parser.Y" {(yyval.integer) = CallBack::COLORCB;;} break; case 164: #line 597 "ds9parser.Y" {(yyval.integer) = CallBack::LINEWIDTHCB;;} break; case 165: #line 598 "ds9parser.Y" {(yyval.integer) = CallBack::PROPERTYCB;;} break; case 166: #line 599 "ds9parser.Y" {(yyval.integer) = CallBack::FONTCB;;} break; case 167: #line 600 "ds9parser.Y" {(yyval.integer) = CallBack::KEYCB;;} break; case 168: #line 601 "ds9parser.Y" {(yyval.integer) = CallBack::UPDATECB;;} break; case 171: #line 609 "ds9parser.Y" { setProps(&globalProps,(yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer)); setProps(&localProps,(yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer)); ;} break; case 172: #line 614 "ds9parser.Y" { strncpy(globalColor,(yyvsp[(3) - (3)].str),16); strncpy(localColor,(yyvsp[(3) - (3)].str),16); ;} break; case 173: #line 618 "ds9parser.Y" { strcpy(globalColor,"#"); strncat(globalColor,(yyvsp[(4) - (4)].str),16); strncpy(localColor,globalColor,16); ;} break; case 174: #line 624 "ds9parser.Y" { globalDash[0] = localDash[0] =(yyvsp[(3) - (4)].integer); globalDash[1] = localDash[1] =(yyvsp[(4) - (4)].integer); ;} break; case 175: #line 628 "ds9parser.Y" {globalWidth = localWidth = (yyvsp[(3) - (3)].integer);;} break; case 176: #line 630 "ds9parser.Y" { strncpy(globalFont,(yyvsp[(3) - (3)].str),32); strncpy(localFont,(yyvsp[(3) - (3)].str),32); ;} break; case 177: #line 635 "ds9parser.Y" { strncpy(globalText,(yyvsp[(3) - (3)].str),80); strncpy(localText,(yyvsp[(3) - (3)].str),80); ;} break; case 178: #line 640 "ds9parser.Y" { setProps(&globalProps,Marker::DASH,1); setProps(&localProps,Marker::DASH,1); ;} break; case 179: #line 645 "ds9parser.Y" { setProps(&globalProps,Marker::SOURCE,1); setProps(&localProps,Marker::SOURCE,1); ;} break; case 180: #line 650 "ds9parser.Y" { setProps(&globalProps,Marker::SOURCE,0); setProps(&localProps,Marker::SOURCE,0); ;} break; case 181: #line 654 "ds9parser.Y" {globalPoint = localPoint = (yyvsp[(3) - (3)].integer);;} break; case 182: #line 656 "ds9parser.Y" { globalPoint = localPoint = (yyvsp[(3) - (4)].integer); globalPointSize = localPointSize = (yyvsp[(4) - (4)].integer); ;} break; case 183: #line 661 "ds9parser.Y" { globalLine1 = localLine1 = (yyvsp[(3) - (4)].integer); globalLine2 = localLine2 = (yyvsp[(4) - (4)].integer); ;} break; case 184: #line 665 "ds9parser.Y" {globalVector = localVector = (yyvsp[(3) - (3)].integer);;} break; case 185: #line 667 "ds9parser.Y" { globalComposite = localComposite = (yyvsp[(3) - (3)].integer); ;} break; case 186: #line 670 "ds9parser.Y" {;} break; case 187: #line 672 "ds9parser.Y" { strncpy(globalCompassNorth,(yyvsp[(4) - (7)].str),80); strncpy(globalCompassEast,(yyvsp[(5) - (7)].str),80); strncpy(localCompassNorth,(yyvsp[(4) - (7)].str),80); strncpy(localCompassEast,(yyvsp[(5) - (7)].str),80); globalCompassNArrow = localCompassNArrow = (yyvsp[(6) - (7)].integer); globalCompassEArrow = localCompassEArrow = (yyvsp[(7) - (7)].integer); ;} break; case 188: #line 680 "ds9parser.Y" {globalTextAngle = localTextAngle = (yyvsp[(3) - (3)].real);;} break; case 189: #line 681 "ds9parser.Y" {globalTextRotate = localTextRotate = (yyvsp[(3) - (3)].integer);;} break; case 190: #line 682 "ds9parser.Y" {globalWCS = (Coord::CoordSystem)(yyvsp[(3) - (3)].integer);;} break; case 191: #line 686 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (4)].integer); globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(2) - (4)].integer); globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(3) - (4)].integer); globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)(yyvsp[(4) - (4)].integer); ;} break; case 192: #line 693 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; ;} break; case 193: #line 700 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 194: #line 707 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (2)].integer); globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; ;} break; case 195: #line 714 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (2)].integer); globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 196: #line 721 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; ;} break; case 197: #line 728 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 198: #line 735 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::IMAGE; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)(yyvsp[(1) - (1)].integer); ;} break; case 199: #line 742 "ds9parser.Y" { globalRulerCoordSystem = localRulerCoordSystem = Coord::IMAGE; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::IMAGE; globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; ;} break; case 200: #line 751 "ds9parser.Y" { globalCompassCoordSystem = localCompassCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); globalCompassSkyFrame = localCompassSkyFrame = (Coord::SkyFrame)(yyvsp[(2) - (2)].integer); ;} break; case 201: #line 756 "ds9parser.Y" { globalCompassCoordSystem = localCompassCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer); globalCompassSkyFrame = localCompassSkyFrame = Coord::FK5; ;} break; case 202: #line 761 "ds9parser.Y" { globalCompassCoordSystem = localCompassCoordSystem = Coord::WCS; globalCompassSkyFrame = localCompassSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (1)].integer); ;} break; case 203: #line 766 "ds9parser.Y" { globalCompassCoordSystem = localCompassCoordSystem = Coord::WCS; globalCompassSkyFrame = localCompassSkyFrame = Coord::FK5; ;} break; case 204: #line 772 "ds9parser.Y" { // global properties globalSystem = Coord::PHYSICAL; globalWCS = fr->wcsSystem(); globalSky = fr->wcsSky(); globalTile = 1; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; strcpy(globalColor,"green"); globalDash[0] = 8; globalDash[1] = 3; globalWidth = 1; strcpy(globalFont,"helvetica 10 normal roman"); strcpy(globalText,""); // unique properties globalLine1 = 0; globalLine2 = 0; globalVector = 1; globalComposite = 1; globalRulerCoordSystem = Coord::PHYSICAL; globalRulerSkyFrame = Coord::FK5; globalRulerDistSystem = Coord::PHYSICAL; globalRulerDistFormat = Coord::DEGREE; globalCompassCoordSystem = Coord::PHYSICAL; globalCompassSkyFrame = Coord::FK5; strcpy(globalCompassNorth,"N"); strcpy(globalCompassEast,"E"); globalCompassNArrow = 1; globalCompassEArrow = 1; globalPoint = Point::BOXCIRCLE; globalPointSize = POINTSIZE; globalTextAngle=0; globalTextRotate=1; aStatus = 0; cStatus = 0; ;} break; case 207: #line 818 "ds9parser.Y" {setProps(&localProps,(yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 208: #line 819 "ds9parser.Y" {strncpy(localColor,(yyvsp[(3) - (3)].str),16);;} break; case 209: #line 820 "ds9parser.Y" { strcpy(localColor,"#"); strncat(localColor,(yyvsp[(4) - (4)].str),16); ;} break; case 210: #line 825 "ds9parser.Y" { localDash[0] =(yyvsp[(3) - (4)].integer); localDash[1] =(yyvsp[(4) - (4)].integer); ;} break; case 211: #line 829 "ds9parser.Y" {localWidth = (yyvsp[(3) - (3)].integer);;} break; case 212: #line 830 "ds9parser.Y" {strncpy(localFont,(yyvsp[(3) - (3)].str),32);;} break; case 213: #line 831 "ds9parser.Y" {strncpy(localText,(yyvsp[(3) - (3)].str),80);;} break; case 214: #line 832 "ds9parser.Y" {taglist.append(new Tag((yyvsp[(3) - (3)].str)));;} break; case 215: #line 833 "ds9parser.Y" {cblist.append( new CallBack(fr->getInterp(),(CallBack::Type)(yyvsp[(3) - (5)].integer),(yyvsp[(4) - (5)].str),(yyvsp[(5) - (5)].str)));;} break; case 216: #line 835 "ds9parser.Y" {setProps(&localProps,Marker::DASH,1);;} break; case 217: #line 836 "ds9parser.Y" {setProps(&localProps,Marker::SOURCE,1);;} break; case 218: #line 837 "ds9parser.Y" {setProps(&localProps,Marker::SOURCE,0);;} break; case 219: #line 839 "ds9parser.Y" {localPoint = (yyvsp[(3) - (3)].integer);;} break; case 220: #line 840 "ds9parser.Y" {localPoint = (yyvsp[(3) - (4)].integer); localPointSize = (yyvsp[(4) - (4)].integer);;} break; case 221: #line 841 "ds9parser.Y" {localLine1=(yyvsp[(3) - (4)].integer); localLine2=(yyvsp[(4) - (4)].integer);;} break; case 222: #line 842 "ds9parser.Y" {localVector=(yyvsp[(3) - (3)].integer);;} break; case 223: #line 843 "ds9parser.Y" {localComposite=(yyvsp[(3) - (3)].integer);;} break; case 225: #line 846 "ds9parser.Y" { strncpy(localCompassNorth,(yyvsp[(4) - (7)].str),80); strncpy(localCompassEast,(yyvsp[(5) - (7)].str),80); localCompassNArrow = (yyvsp[(6) - (7)].integer); localCompassEArrow = (yyvsp[(7) - (7)].integer); ;} break; case 226: #line 852 "ds9parser.Y" {localTextAngle=(yyvsp[(3) - (3)].real);;} break; case 227: #line 853 "ds9parser.Y" {localTextRotate=(yyvsp[(3) - (3)].integer);;} break; case 231: #line 860 "ds9parser.Y" { localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (4)].integer); localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(2) - (4)].integer); localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(3) - (4)].integer); localRulerDistFormat = (Coord::SkyDist)(yyvsp[(4) - (4)].integer); ;} break; case 232: #line 867 "ds9parser.Y" { localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); localRulerSkyFrame = Coord::FK5; localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); localRulerDistFormat = Coord::DEGREE; ;} break; case 233: #line 874 "ds9parser.Y" { localRulerCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 234: #line 881 "ds9parser.Y" { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (2)].integer); localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); localRulerDistFormat = Coord::DEGREE; ;} break; case 235: #line 888 "ds9parser.Y" { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (2)].integer); localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 236: #line 895 "ds9parser.Y" { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = (Coord::CoordSystem)(yyvsp[(2) - (2)].integer); localRulerDistFormat = Coord::DEGREE; ;} break; case 237: #line 902 "ds9parser.Y" { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)(yyvsp[(2) - (2)].integer); ;} break; case 238: #line 909 "ds9parser.Y" { localRulerCoordSystem = Coord::IMAGE; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)(yyvsp[(1) - (1)].integer); ;} break; case 239: #line 916 "ds9parser.Y" { localRulerCoordSystem = Coord::IMAGE; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::IMAGE; localRulerDistFormat = Coord::DEGREE; ;} break; case 240: #line 925 "ds9parser.Y" { localCompassCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (2)].integer); localCompassSkyFrame = (Coord::SkyFrame)(yyvsp[(2) - (2)].integer); ;} break; case 241: #line 930 "ds9parser.Y" { localCompassCoordSystem = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer); localCompassSkyFrame = Coord::FK5; ;} break; case 242: #line 935 "ds9parser.Y" { localCompassCoordSystem = Coord::WCS; localCompassSkyFrame = (Coord::SkyFrame)(yyvsp[(1) - (1)].integer); ;} break; case 243: #line 940 "ds9parser.Y" { localCompassCoordSystem = Coord::WCS; localCompassSkyFrame = Coord::FK5; ;} break; case 244: #line 946 "ds9parser.Y" {aNum=0; aAngNum=0;;} break; case 245: #line 946 "ds9parser.Y" {localCpanda = 2;;} break; case 246: #line 947 "ds9parser.Y" {localCpanda=0;;} break; case 247: #line 950 "ds9parser.Y" {aNum=0; aAngNum=0, aAngle=0;;} break; case 248: #line 951 "ds9parser.Y" {aAngle=(yyvsp[(9) - (10)].real);localEpanda=2;;} break; case 249: #line 952 "ds9parser.Y" {localEpanda=0;;} break; case 250: #line 955 "ds9parser.Y" {aNum=0; aAngNum=0, aAngle=0;;} break; case 251: #line 956 "ds9parser.Y" {aAngle=(yyvsp[(9) - (10)].real);localBpanda=2;;} break; case 252: #line 957 "ds9parser.Y" {localBpanda=0;;} break; case 253: #line 960 "ds9parser.Y" { // reset maperr flag maperr = 0; // needed for annulus, ellipse annulus, and box annulus aNum = 2; // composite (previous conjuction found?) if (!cStatus) fr->resetCompositeMarker(); // global properties localSystem = globalSystem; localSky = globalSky; localProps = globalProps; strcpy(localColor,globalColor); localDash[0] = globalDash[0]; localDash[1] = globalDash[1]; localWidth = globalWidth; strcpy(localFont,globalFont); strcpy(localText,globalText); strcpy(localComment,""); taglist.deleteAll(); cblist.deleteAll(); // unique properties localLine1 = globalLine1; localLine2 = globalLine2; localVector = globalVector; localComposite = globalComposite; localPoint = globalPoint; localPointSize = globalPointSize; localRulerCoordSystem = globalRulerCoordSystem; localRulerSkyFrame = globalRulerSkyFrame; localRulerDistSystem = globalRulerDistSystem; localRulerDistFormat = globalRulerDistFormat; localCompassCoordSystem = globalCompassCoordSystem; localCompassSkyFrame = globalCompassSkyFrame; strcpy(localCompassNorth,globalCompassNorth); strcpy(localCompassEast,globalCompassEast); localCompassNArrow = globalCompassNArrow; localCompassEArrow = globalCompassEArrow; localTextAngle = globalTextAngle; localTextRotate = globalTextRotate; localCpanda = 1; localEpanda = 1; localBpanda = 1; ;} break; case 254: #line 1009 "ds9parser.Y" {(yyval.integer) = Point::CIRCLE;;} break; case 255: #line 1010 "ds9parser.Y" {(yyval.integer) = Point::BOX;;} break; case 256: #line 1011 "ds9parser.Y" {(yyval.integer) = Point::DIAMOND;;} break; case 257: #line 1012 "ds9parser.Y" {(yyval.integer) = Point::CROSS;;} break; case 258: #line 1013 "ds9parser.Y" {(yyval.integer) = Point::EX;;} break; case 259: #line 1014 "ds9parser.Y" {(yyval.integer) = Point::ARROW;;} break; case 260: #line 1015 "ds9parser.Y" {(yyval.integer) = Point::BOXCIRCLE;;} break; case 261: #line 1018 "ds9parser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 262: #line 1019 "ds9parser.Y" {setProps(&localProps, Marker::INCLUDE, 0);;} break; case 263: #line 1023 "ds9parser.Y" { fr->createVectCmd(Vector((yyvsp[(3) - (10)].vector)), (yyvsp[(5) - (10)].real),(yyvsp[(7) - (10)].real), localVector, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 264: #line 1031 "ds9parser.Y" { fr->createTextCmd(Vector((yyvsp[(3) - (6)].vector)), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 265: #line 1038 "ds9parser.Y" { fr->createRulerCmd(Vector((yyvsp[(3) - (8)].vector)), Vector((yyvsp[(5) - (8)].vector)), localRulerCoordSystem, localRulerSkyFrame, localRulerDistSystem, localRulerDistFormat, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 266: #line 1047 "ds9parser.Y" { fr->createCompassCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localCompassNorth, localCompassEast, localCompassNArrow, localCompassEArrow, localCompassCoordSystem, localCompassSkyFrame, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 267: #line 1057 "ds9parser.Y" { fr->createProjectionCmd(Vector((yyvsp[(3) - (10)].vector)), Vector((yyvsp[(5) - (10)].vector)), (yyvsp[(7) - (10)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 268: #line 1065 "ds9parser.Y" { // backward compatibility fr->createCircleCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 269: #line 1073 "ds9parser.Y" { fr->createCompositeCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localComposite, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 270: #line 1082 "ds9parser.Y" { fr->createCircleCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 271: #line 1089 "ds9parser.Y" { // backwards compatibility fr->createCircleCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 272: #line 1097 "ds9parser.Y" { // for ellipse annulus aStatus = 1; aCenter = Vector((yyvsp[(3) - (10)].vector)); aAngles[0] = (yyvsp[(7) - (10)].real); aVector[0] = Vector((yyvsp[(5) - (10)].vector)); aNumsao = 1; strncpy(aColor,localColor,16); aDash[0] = localDash[0]; aDash[1] = localDash[1]; aWidth = localWidth; strncpy(aFont,localFont,32); strncpy(aText,localText,80); strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector((yyvsp[(3) - (10)].vector)), Vector((yyvsp[(5) - (10)].vector)), (yyvsp[(7) - (10)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 273: #line 1120 "ds9parser.Y" { // for box annulus aStatus = 3; aCenter = Vector((yyvsp[(3) - (10)].vector)); aAngles[0] = (yyvsp[(7) - (10)].real); aVector[0] = Vector((yyvsp[(5) - (10)].vector)); aNumsao = 1; strncpy(aColor,localColor,16); aDash[0] = localDash[0]; aDash[1] = localDash[1]; aWidth = localWidth; strncpy(aFont,localFont,32); strncpy(aText,localText,80); strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector((yyvsp[(3) - (10)].vector)), Vector((yyvsp[(5) - (10)].vector)), (yyvsp[(7) - (10)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 274: #line 1143 "ds9parser.Y" { // backwards compatibility fr->createBoxCmd(Vector((yyvsp[(3) - (10)].vector)), Vector((yyvsp[(5) - (10)].vector)), (yyvsp[(7) - (10)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 275: #line 1151 "ds9parser.Y" {polylist.deleteAll();;} break; case 276: #line 1153 "ds9parser.Y" { fr->createPolygonCmd(polylist, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 277: #line 1160 "ds9parser.Y" { fr->createLineCmd(Vector((yyvsp[(3) - (8)].vector)), Vector((yyvsp[(5) - (8)].vector)), localLine1,localLine2, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 278: #line 1168 "ds9parser.Y" { fr->createVectCmd(Vector((yyvsp[(3) - (10)].vector)), (yyvsp[(5) - (10)].real),(yyvsp[(7) - (10)].real), localVector, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 279: #line 1176 "ds9parser.Y" { fr->createTextCmd(Vector((yyvsp[(3) - (6)].vector)), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 280: #line 1182 "ds9parser.Y" {strncpy(localText,(yyvsp[(5) - (6)].str),80);;} break; case 281: #line 1184 "ds9parser.Y" { fr->createTextCmd(Vector((yyvsp[(3) - (9)].vector)), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 282: #line 1191 "ds9parser.Y" { fr->createPointCmd(Vector((yyvsp[(3) - (6)].vector)), (Point::PointShape)localPoint, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 283: #line 1198 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::CIRCLE, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 284: #line 1205 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::BOX, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 285: #line 1212 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::DIAMOND, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 286: #line 1219 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::CROSS, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 287: #line 1226 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::EX, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 288: #line 1233 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::ARROW, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 289: #line 1240 "ds9parser.Y" { // backwards compatibility fr->createPointCmd(Vector((yyvsp[(4) - (7)].vector)), Point::BOXCIRCLE, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 290: #line 1247 "ds9parser.Y" { fr->createRulerCmd(Vector((yyvsp[(3) - (8)].vector)), Vector((yyvsp[(5) - (8)].vector)), localRulerCoordSystem, localRulerSkyFrame, localRulerDistSystem, localRulerDistFormat, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 291: #line 1256 "ds9parser.Y" { fr->createCompassCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localCompassNorth, localCompassEast, localCompassNArrow, localCompassEArrow, localCompassCoordSystem, localCompassSkyFrame, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 292: #line 1266 "ds9parser.Y" { fr->createProjectionCmd(Vector((yyvsp[(3) - (10)].vector)), Vector((yyvsp[(5) - (10)].vector)), (yyvsp[(7) - (10)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 293: #line 1274 "ds9parser.Y" { fr->createAnnulusCmd(Vector((yyvsp[(3) - (10)].vector)), (yyvsp[(5) - (10)].real),(yyvsp[(7) - (10)].real),1, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 294: #line 1282 "ds9parser.Y" { aAnnuli[0] = (yyvsp[(5) - (12)].real); aAnnuli[1] = (yyvsp[(7) - (12)].real); fr->createAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), aNum,aAnnuli, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 295: #line 1292 "ds9parser.Y" { fr->createAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), (yyvsp[(5) - (12)].real),(yyvsp[(7) - (12)].real),(yyvsp[(9) - (12)].integer), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 296: #line 1300 "ds9parser.Y" { // prefered syntax fr->createEllipseAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), Vector((yyvsp[(5) - (12)].vector)),Vector((yyvsp[(7) - (12)].vector)),1, (yyvsp[(9) - (12)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 297: #line 1310 "ds9parser.Y" { // prefered syntax fr->createEllipseAnnulusCmd(Vector((yyvsp[(3) - (14)].vector)), Vector((yyvsp[(5) - (14)].vector)),Vector((yyvsp[(7) - (14)].vector)),(yyvsp[(9) - (14)].integer), (yyvsp[(11) - (14)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 298: #line 1320 "ds9parser.Y" { // prefered syntax aVector[0] = Vector((yyvsp[(5) - (14)].vector)); aVector[1] = Vector((yyvsp[(7) - (14)].vector)); fr->createEllipseAnnulusCmd(Vector((yyvsp[(3) - (14)].vector)), aNum,aVector, (yyvsp[(11) - (14)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 299: #line 1332 "ds9parser.Y" { // backwards compatibility // old saoimage syntax aStatus = 2; aVector[aNumsao++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 300: #line 1340 "ds9parser.Y" { // prefered syntax fr->createBoxAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), Vector((yyvsp[(5) - (12)].vector)),Vector((yyvsp[(7) - (12)].vector)),1, (yyvsp[(9) - (12)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 301: #line 1350 "ds9parser.Y" { // prefered syntax aVector[0] = Vector((yyvsp[(5) - (14)].vector)); aVector[1] = Vector((yyvsp[(7) - (14)].vector)); fr->createBoxAnnulusCmd(Vector((yyvsp[(3) - (14)].vector)), aNum,aVector, (yyvsp[(11) - (14)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 302: #line 1362 "ds9parser.Y" { // prefered syntax fr->createBoxAnnulusCmd(Vector((yyvsp[(3) - (14)].vector)), Vector((yyvsp[(5) - (14)].vector)),Vector((yyvsp[(7) - (14)].vector)),(yyvsp[(9) - (14)].integer), (yyvsp[(11) - (14)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 303: #line 1372 "ds9parser.Y" { // backwards compatibility // old saoimage syntax aStatus = 4; aVector[aNumsao++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 304: #line 1381 "ds9parser.Y" { switch (localCpanda) { case 0: /* ignore it */ break; case 1: /* normal cpanda */ fr->createCpandaCmd(Vector((yyvsp[(3) - (18)].vector)), (yyvsp[(5) - (18)].real),(yyvsp[(7) - (18)].real),(yyvsp[(9) - (18)].integer), (yyvsp[(11) - (18)].real),(yyvsp[(13) - (18)].real),(yyvsp[(15) - (18)].integer), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createCpandaCmd(Vector((yyvsp[(3) - (18)].vector)), aAngNum,aAngles, aNum,aAnnuli, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } ;} break; case 305: #line 1403 "ds9parser.Y" { switch (localEpanda) { case 0: /* ignore it */ break; case 1: /* normal epanda */ fr->createEpandaCmd(Vector((yyvsp[(3) - (20)].vector)), (yyvsp[(5) - (20)].real),(yyvsp[(7) - (20)].real),(yyvsp[(9) - (20)].integer), Vector((yyvsp[(11) - (20)].vector)),Vector((yyvsp[(13) - (20)].vector)),(yyvsp[(15) - (20)].integer), (yyvsp[(17) - (20)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createEpandaCmd(Vector((yyvsp[(3) - (20)].vector)), aAngNum,aAngles, aNum,aVector, aAngle, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } ;} break; case 306: #line 1427 "ds9parser.Y" { switch (localBpanda) { case 0: /* ignore it */ break; case 1: /* normal bpanda */ fr->createBpandaCmd(Vector((yyvsp[(3) - (20)].vector)), (yyvsp[(5) - (20)].real),(yyvsp[(7) - (20)].real),(yyvsp[(9) - (20)].integer), Vector((yyvsp[(11) - (20)].vector)),Vector((yyvsp[(13) - (20)].vector)),(yyvsp[(15) - (20)].integer), (yyvsp[(17) - (20)].real), localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createBpandaCmd(Vector((yyvsp[(3) - (20)].vector)), aAngNum,aAngles, aNum,aVector, aAngle, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } ;} break; case 311: #line 1457 "ds9parser.Y" { fr->createCompositeCmd(Vector((yyvsp[(3) - (8)].vector)), (yyvsp[(5) - (8)].real), localComposite, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); ;} break; case 314: #line 1469 "ds9parser.Y" {polylist.append(new Vertex((yyvsp[(1) - (1)].vector)));;} break; case 317: #line 1477 "ds9parser.Y" { if (aNum < MAXANNULI) aAnnuli[aNum++] = (yyvsp[(1) - (1)].real); ;} break; case 320: #line 1488 "ds9parser.Y" { if (aAngNum < MAXANGLES) aAngles[aAngNum++] = (yyvsp[(1) - (1)].real); ;} break; case 323: #line 1498 "ds9parser.Y" {aVector[aNum++] = Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real));;} break; case 324: #line 1502 "ds9parser.Y" { // old style annulus switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNumsao,aVector, aAngles[0], aColor,aDash,aWidth,aFont,aText,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNumsao,aVector, aAngles[0], aColor,aDash,aWidth,aFont,aText,aProps,aComment,taglist,cblist); break; } aStatus = 0; ;} break; /* Line 1267 of yacc.c. */ #line 4836 "ds9parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 1529 "ds9parser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ellipse.h����������������������������������������������������������������������0000644�0001750�0001750�00000002376�12030663652�015137� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __ellipse_h__ #define __ellipse_h__ #include "baseellipse.h" class Ellipse : public BaseEllipse { public: Ellipse(const Ellipse&); Ellipse(Base* p, const Vector& ctr, const Vector& r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Ellipse(*this);} void edit(const Vector&, int); void analysis(AnalysisTask, int); void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); virtual void listCiao(ostream&, Coord::CoordSystem, int); virtual void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOimage(ostream&, int); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ciaoparser.Y�������������������������������������������������������������������0000644�0001750�0001750�00000012275�11727715172�015621� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {ciaoFlexLexer* ll} %parse-param {ciaoFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer ciaoFlexLexer #include <FlexLexer.h> extern int ciaolex(void*, ciaoFlexLexer*); extern void ciaoerror(Base*, ciaoFlexLexer*, const char*); static char *color = "green"; static int dash[] = {8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static unsigned short props; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static void setProps(unsigned short* props, unsigned short prop, int value); %} %union { #define CIAOBUFSIZE 2048 double real; int integer; char str[CIAOBUFSIZE]; double vector[3]; } %type <real> numeric %type <real> angle %type <real> value %type <vector> vvalue %type <real> sexagesimal %type <real> hms %type <real> dms %type <vector> coord %token <integer> INT %token <real> REAL %token <real> ANGDEGREE %token <real> ARCMINUTE %token <real> ARCSECOND %token <str> SEXSTR %token <str> HMSSTR %token <str> DMSSTR %token EOF_ %token ANNULUS_ %token BOX_ %token CIRCLE_ %token DEBUG_ %token ELLIPSE_ %token OFF_ %token ON_ %token PIE_ %token POINT_ %token POLYGON_ %token ROTBOX_ %token VERSION_ %% commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "CIAO Regions File 1.0" << endl;} | init include shape ; terminator: ep | '\n' | EOF_ {YYACCEPT;} ; include : /* empty */ | '*' /* AND */ | '&' /* AND */ | '|' /* OR */ | '+' /* OR */ | '-' /* NOT */ {setProps(&props, Marker::INCLUDE, 0);} | '!''*' /* NOT */ {setProps(&props, Marker::INCLUDE, 0);} | '!' /* NOT */ {setProps(&props, Marker::INCLUDE, 0);} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; sp : ',' ; bp : '(' ; ep : ')' ; init: { // reset maperr flag maperr =0; props = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; } ; angle : numeric {$$ = degToRad($1);} ; value : numeric {$$ = FITSPTR->mapLenToRef($1, Coord::PHYSICAL);} | ANGDEGREE {$$ = FITSPTR->mapLenToRef($1, Coord::WCS, Coord::DEGREE);} | ARCMINUTE {$$ = FITSPTR->mapLenToRef($1, Coord::WCS, Coord::ARCMIN);} | ARCSECOND {$$ = FITSPTR->mapLenToRef($1, Coord::WCS, Coord::ARCSEC);} ; vvalue : numeric sp numeric { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::PHYSICAL); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCMINUTE sp ARCMINUTE { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::WCS, Coord::ARCMIN); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCSECOND sp ARCSECOND { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::WCS, Coord::ARCSEC); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; hms : HMSSTR {$$ = parseHMSStr($1);} ; dms : DMSSTR {$$ = parseDMSStr($1);} ; coord : sexagesimal sp sexagesimal { Vector r = FITSPTR->mapToRef(Vector($1*360./24.,$3), Coord::WCS,Coord::FK5); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | hms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3), Coord::WCS,Coord::FK5); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3), Coord::PHYSICAL); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; shape : CIRCLE_ bp coord sp value {fr->createCircleCmd(Vector($3), $5, color,dash,1,font,text,props,NULL,taglist,cblist);} | ELLIPSE_ bp coord sp vvalue sp angle {fr->createEllipseCmd(Vector($3), Vector($5),$7, color,dash,1,font,text,props,NULL,taglist,cblist);} | ANNULUS_ bp coord sp value sp value {fr->createAnnulusCmd(Vector($3), $5,$7,1, color,dash,1,font,text,props,NULL,taglist,cblist);} | PIE_ bp coord sp value sp value sp angle sp angle {fr->createCpandaCmd(Vector($3), $9,$11,1, $5,$7,1, color,dash,1,font,text,props,NULL,taglist,cblist);} | BOX_ bp coord sp vvalue {fr->createBoxCmd(Vector($3), Vector($5), 0, color,dash,1,font,text,props,NULL,taglist,cblist);} | ROTBOX_ bp coord sp vvalue sp angle {fr->createBoxCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,props,NULL,taglist,cblist);} | POINT_ bp coord {fr->createPointCmd(Vector($3), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,props,NULL,taglist,cblist);} | POLYGON_ {polylist.deleteAll();} bp polyNodes {fr->createPolygonCmd(polylist, color,dash,1,font,text,props,NULL,taglist,cblist);} ; polyNodes : polyNodes sp polyNode | polyNode ; polyNode : coord {polylist.append(new Vertex($1));} ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsbin.C����������������������������������������������������������������������0000644�0001750�0001750�00000015422�12107012361�015055� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" void FitsImage::initHist() { // make sure we have rows and cols { FitsHead* head = fits_->head(); if (head) { FitsTableHDU* hdu = (FitsTableHDU*)(head->hdu()); if (!hdu->width() || !hdu->rows()) return; } } // make sure we have cols to bin on if (!fits_->pBinX() || !fits_->pBinY()) { FitsHead* head = fits_->head(); if (head) { FitsTableHDU* hdu = (FitsTableHDU*)head->hdu(); // try for X and Y FitsColumn* x = hdu->find("X"); FitsColumn* y = hdu->find("Y"); // next, try for ra and dec if (!x) x = hdu->find("RA"); if (!y) y = hdu->find("DEC"); // last chance, try first and second column if (!x) x = hdu->find(0); if (!y) y = hdu->find(1); if (x) { char* str = trim(x->ttype()); fits_->setpBinX(str); delete [] str; } if (y) { char* str = trim(y->ttype()); fits_->setpBinY(str); delete [] str; } } } if (!fits_->pBinZ()) { FitsHead* head = fits_->head(); if (head) { FitsTableHDU* hdu = (FitsTableHDU*)head->hdu(); // try for TIME FitsColumn* z = hdu->find("TIME"); // last chance, try third column if (!z) z = hdu->find(2); if (z) { char* str = trim(z->ttype()); fits_->setpBinZ(str); delete [] str; } } } // update default values from parent binFunction_ = parent->binFunction_; binBufferSize_ = parent->binBufferSize_; binDepth_ = parent->binDepth_; binFactor_ = parent->binFactor_; nextHist(getHistCenter()); } int FitsImage::hasBinCol(const char* str) { if (fits_) { FitsHead* head = fits_->head(); if (head) { FitsTableHDU* hdu = (FitsTableHDU*)head->hdu(); return hdu->find(str) ? 1 : 0; } } return 0; } void FitsImage::setBinCursor(const Vector& v) { histCursor = v * refToPhysical; } void FitsImage::setBinFactor(const Vector& b) { Vector bb = b; binFactor_[0] *= bb[0] <= 0 ? 1 : bb[0]; binFactor_[1] *= bb[1] <= 0 ? 1 : bb[1]; } void FitsImage::setBinToFactor(const Vector& b) { Vector bb = b; binFactor_[0] = bb[0] <= 0 ? 1 : bb[0]; binFactor_[1] = bb[1] <= 0 ? 1 : bb[1]; } Matrix FitsImage::updateHistCenter() { return hist_ ? nextHist(getHistCenter()) : Matrix(); } Matrix FitsImage::updateHistCursor() { return hist_ ? nextHist(histCursor) : Matrix(); } Matrix FitsImage::updateHist(const Vector& v) { // v is in bin (physical) coords return hist_ ? nextHist(v) : Matrix(); } Matrix FitsImage::nextHist(const Vector& c) { // cursor, c is in bin (physical) coords // remember where we are pointing histCursor = c; // Vector s = getHistDim()/binFactor_; Vector d = getHistDim(); Vector s; s[0] = d[0]/binFactor_[0]; s[1] = d[1]/binFactor_[1]; // make sure that we have a width/height of at least 1 if (s[0]<1) s[0]=1; if (s[1]<1) s[1]=1; int width = (int)(s[0]<binBufferSize_? s[0] : binBufferSize_); int height= (int)(s[1]<binBufferSize_? s[1] : binBufferSize_); int depth = binDepth_; Vector center = Vector(width, height)/2; if (DebugBin) { cerr << "width height: " << width << ' ' << height << endl; cerr << "center: " << center << endl; cerr << "center.ceil(): " << center.ceil() << endl; } if (binFactor_[0]<1 || binFactor_[1]<1) { actualHistCursor = histCursor; if (DebugBin) cerr << "histCursor: " << histCursor << endl; } else { // force to a bin boundary, then translate to center of bin cell // actualHistCursor = ((histCursor/binFactor_).floor() * binFactor_) + // Vector(.5,.5); actualHistCursor[0] = (floor(histCursor[0]/binFactor_[0]) * binFactor_[0]) + .5; actualHistCursor[1] = (floor(histCursor[1]/binFactor_[1]) * binFactor_[1]) + .5; // now, figure out any offset due to mod(lowerleft,binFactor_) FitsTableHDU* hdu = (FitsTableHDU*)(fits_->head())->hdu(); Vector xd = hdu->dimension(fits_->pBinX()); Vector yd = hdu->dimension(fits_->pBinY()); Vector ll(xd[0],yd[0]); // Vector a = ((ll/binFactor_).floor() * binFactor_) + Vector(.5,.5); Vector a; a[0] = (floor(ll[0]/binFactor_[0]) * binFactor_[0]) + .5; a[1] = (floor(ll[1]/binFactor_[1]) * binFactor_[1]) + .5; Vector offset = a-ll; actualHistCursor -= offset; if (DebugBin) { cerr << "histCursor: " << histCursor << endl; cerr << "actualHistCursor: " << actualHistCursor << endl; cerr << "ll: " << ll << endl; cerr << "offset: " << offset << endl; } } // new physicalToData Matrix mm = Translate(-actualHistCursor) * Scale(1./binFactor_[0],1./binFactor_[1]) * Translate(center.ceil()); if (DebugBin) cerr << "mm: " << mm << endl << endl; if (hist_) delete hist_; hist_ = new FitsHist(fits_, width, height, depth, mm, binFunction_, binFactor_); // reset LTMV keywords keyLTMV = 0; if (!hist_->isValid()) { reset(); return Matrix(); } // reset scanmode parent->resetScanMode(); load(); // return matrix return refToPhysical * mm * dataToRef; } Vector FitsImage::getHistColMinMax(const char* col) { return fits_ ? fits_->getColMinMax(col) : Vector(); } Vector FitsImage::getHistColDim(const char* col) { return fits_ ? fits_->getColDim(col) : Vector(); } Vector FitsImage::getHistDim() { if (!isBinTable()) return Vector(); // assumes we aready have our columns FitsTableHDU* hdu = (FitsTableHDU*)(fits_->head())->hdu(); Vector xd = hdu->dimension(fits_->pBinX()); Vector yd = hdu->dimension(fits_->pBinY()); // if DBL_MAX, we will get nan Vector r(xd[1]-xd[0],yd[1]-yd[0]); if (isfinite(r[0]) && isfinite(r[1])) return r; else return Vector(DBL_MAX,DBL_MAX); } Vector FitsImage::getHistCenter() { // return bin (physical) coords if (!isBinTable()) return Vector(); // assumes we aready have our columns FitsTableHDU* hdu = (FitsTableHDU*)(fits_->head())->hdu(); Vector xd = hdu->dimension(fits_->pBinX()); Vector yd = hdu->dimension(fits_->pBinY()); // if DBL_MAX, we will get nan Vector r = Vector(xd[1]-xd[0],yd[1]-yd[0])/2 + Vector(xd[0],yd[0]); if (isfinite(r[0]) && isfinite(r[1])) return r; else return Vector(); } const char* FitsImage::getHistFilter() { return fits_ ? fits_->pFilter() : NULL; } const char* FitsImage::getHistX() { return fits_ ? fits_->pBinX() : NULL; } const char* FitsImage::getHistY() { return fits_ ? fits_->pBinY() : NULL; } const char* FitsImage::getHistZ() { return fits_ ? fits_->pBinZ() : NULL; } char* FitsImage::getHistList() { if (!isBinTable()) return NULL; FitsHead* head = fits_->head(); return ((FitsTableHDU*)head->hdu())->list(); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscalepseudo8.C������������������������������������������������������������0000644�0001750�0001750�00000007434�11725514403�017072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscalepseudo8.h" #include "base.h" ColorScalePseudoColor8::ColorScalePseudoColor8(int s) : ColorScale(s) { colors_ = new unsigned char[s]; for (int i=0; i<s; i++) colors_[i] = psIndex_[i]; } ColorScalePseudoColor8::~ColorScalePseudoColor8() { if (colors_) delete [] colors_; } LinearScalePseudoColor8::LinearScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count) : LinearScale(s, indexCells, colorCells, count), ColorScalePseudoColor8(s), ColorScale(s) {} LogScalePseudoColor8::LogScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp) : LogScale(s, indexCells, colorCells, count, exp), ColorScalePseudoColor8(s), ColorScale(s) {} PowScalePseudoColor8::PowScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp) : PowScale(s, indexCells, colorCells, count, exp), ColorScalePseudoColor8(s), ColorScale(s) {} SqrtScalePseudoColor8::SqrtScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count) : SqrtScale(s, indexCells, colorCells, count), ColorScalePseudoColor8(s), ColorScale(s) {} SquaredScalePseudoColor8::SquaredScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count) : SquaredScale(s, indexCells, colorCells, count), ColorScalePseudoColor8(s), ColorScale(s) {} AsinhScalePseudoColor8::AsinhScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count) : AsinhScale(s, indexCells, colorCells, count), ColorScalePseudoColor8(s), ColorScale(s) {} SinhScalePseudoColor8::SinhScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count) : SinhScale(s, indexCells, colorCells, count), ColorScalePseudoColor8(s), ColorScale(s) {} IISScalePseudoColor8::IISScalePseudoColor8(Base* parent, unsigned short* indexCells, unsigned char* colorCells, int count) : IISScale(indexCells, colorCells, count), ColorScalePseudoColor8(IISSIZE), ColorScale(IISSIZE) { colors_[200] = psIndex_[200] = parent->getColor("black"); colors_[201] = psIndex_[201] = parent->getColor("black"); colors_[202] = psIndex_[202] = parent->getColor("white"); colors_[203] = psIndex_[203] = parent->getColor("red"); colors_[204] = psIndex_[204] = parent->getColor("green"); colors_[205] = psIndex_[205] = parent->getColor("blue"); colors_[206] = psIndex_[206] = parent->getColor("yellow"); colors_[207] = psIndex_[207] = parent->getColor("cyan"); colors_[208] = psIndex_[208] = parent->getColor("magenta"); colors_[209] = psIndex_[209] = parent->getColor("coral"); colors_[210] = psIndex_[210] = parent->getColor("maroon"); colors_[211] = psIndex_[211] = parent->getColor("orange"); colors_[212] = psIndex_[212] = parent->getColor("khaki"); colors_[213] = psIndex_[213] = parent->getColor("orchid"); colors_[214] = psIndex_[214] = parent->getColor("turquoise"); colors_[215] = psIndex_[215] = parent->getColor("violet"); colors_[216] = psIndex_[216] = parent->getColor("wheat"); } HistEquScalePseudoColor8::HistEquScalePseudoColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize) : HistEquScale(s, indexCells, colorCells, count, hist, histsize), ColorScalePseudoColor8(s), ColorScale(s) {} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/callback.h���������������������������������������������������������������������0000644�0001750�0001750�00000002154�11700666266�015237� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __callback_h__ #define __callback_h__ #include <tcl.h> class CallBack { public: enum Type {SELECTCB, UNSELECTCB, HIGHLITECB, UNHIGHLITECB, EDITBEGINCB, EDITCB, EDITENDCB, MOVEBEGINCB, MOVECB, MOVEENDCB, ROTATEBEGINCB, ROTATECB, ROTATEENDCB, DELETECB, TEXTCB, COLORCB, LINEWIDTHCB, PROPERTYCB, FONTCB, KEYCB, UPDATECB}; private: Tcl_Interp* interp_; Type type_; char proc_[128]; char arg_[256]; CallBack* previous_; CallBack* next_; public: CallBack(const CallBack&); CallBack(Tcl_Interp*, Type, const char*, const char*); CallBack& operator=(const CallBack&); int eval(const char*); Type type() {return type_;} const char* proc() {return proc_;} const char* arg() {return arg_;} CallBack* previous() {return previous_;} void setPrevious(CallBack* cb) {previous_ = cb;} CallBack* next() {return next_;} void setNext(CallBack* cb) {next_ = cb;} }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/box.h��������������������������������������������������������������������������0000644�0001750�0001750�00000002427�12030663652�014267� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __box_h__ #define __box_h__ #include "basebox.h" class Box : public BaseBox { public: Box(const Box&); Box(Base* p, const Vector& ctr, const Vector& seg, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Box(*this);} void editBegin(int); void edit(const Vector&, int); void editEnd(); void analysis(AnalysisTask, int); void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); virtual void listCiao(ostream&, Coord::CoordSystem, int); virtual void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOimage(ostream&, int); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basepanda.C��������������������������������������������������������������������0000644�0001750�0001750�00000005702�12004561531�015341� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "basepanda.h" #include "fitsimage.h" BasePanda::BasePanda(const BasePanda& a) { numAngles_ = a.numAngles_; angles_ = new double[numAngles_]; for (int ii=0; ii<numAngles_; ii++) angles_[ii] = a.angles_[ii]; } BasePanda::BasePanda(double a1, double a2, int an) { angles_ = NULL; setAngles(a1,a2,an); } BasePanda::BasePanda(int an, double* a) { angles_ = NULL; setAngles(an,a); } BasePanda::~BasePanda() { if (angles_) delete [] angles_; } void BasePanda::sortAngles() { // first, all angles 0<=ang<2_PI for (int ii=0; ii<numAngles_; ii++) angles_[ii] = zeroTWOPI(angles_[ii]); // now, all angs incr in size for (int ii=1; ii<numAngles_; ii++) { if (angles_[ii] < angles_[ii-1]) angles_[ii] += M_TWOPI; } // last sanity check if (numAngles_>1 && angles_[0]==0 && angles_[numAngles_-1]==0) angles_[numAngles_-1] += M_TWOPI; } void BasePanda::setAngles(double a1, double a2, int an) { numAngles_ = an+1; if (angles_) delete [] angles_; angles_ = new double[numAngles_]; // yes this is really needed // for a2<a1 if (tle(a2,a1,FLT_EPSILON)) { a1 = zeroTWOPI(a1); a2 = zeroTWOPI(a2); if (tle(a2,a1,FLT_EPSILON)) a2 += M_TWOPI; } // for a1=a2 if (teq(a2,a1,FLT_EPSILON)) { a1 = zeroTWOPI(a1); a2 = zeroTWOPI(a2); if (a2<=a1) a2 += M_TWOPI; } // for a2>a1 very small if (teq(a2,a1,FLT_EPSILON)) { a1 = zeroTWOPI(a1); a2 = zeroTWOPI(a2); if (teq(a2,a1,FLT_EPSILON)) a2 += M_TWOPI; } for (int ii=0; ii<numAngles_; ii++) angles_[ii] = ii*(a2-a1)/an+a1; sortAngles(); } void BasePanda::setAngles(int an, const double* a) { numAngles_ = an; if (angles_) delete [] angles_; angles_ = new double[numAngles_]; for (int ii=0; ii<numAngles_; ii++) angles_[ii] = a[ii]; sortAngles(); } void BasePanda::addAngle(double aa) { // we need to insert into the next to the last location // new size array double* old = angles_; angles_ = new double[numAngles_+1]; // copy old values for (int ii=0; ii<numAngles_; ii++) angles_[ii] = old[ii]; // save last angles_[numAngles_] = old[numAngles_-1]; // delete old if (old) delete [] old; // new size on next to last angles_[numAngles_-1] = aa; numAngles_++; } void BasePanda::deleteAngle(int hh) { // new angles array double* old = angles_; angles_ = new double[numAngles_-1]; // copy up to angles in question for (int ii=0; ii<hh; ii++) angles_[ii] = old[ii]; // copy remainder for (int ii=hh; ii<numAngles_-1; ii++) angles_[ii] = old[ii+1]; if (old) delete [] old; numAngles_--; } int BasePanda::isIn(Vector& vv, int nn) { double aa = -vv.angle(); while (aa<angles_[0]) aa += M_TWOPI; return aa>=angles_[nn] && aa<angles_[nn+1]; } ��������������������������������������������������������������./saods9/saotk/frame/parser.H�����������������������������������������������������������������������0000644�0001750�0001750�00000035757�12076042216�014744� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, POINTER = 261, ANGDEGREE = 262, ANGRADIAN = 263, SEXSTR = 264, HMSSTR = 265, DMSSTR = 266, ABOUT_ = 267, AIP_ = 268, ALLOC_ = 269, ALLOCGZ_ = 270, ALIGN_ = 271, ALL_ = 272, ALT_ = 273, AMPLIFIER_ = 274, ANALYSIS_ = 275, ANGLE_ = 276, ANNULUS_ = 277, APPEND_ = 278, ARCMIN_ = 279, ARCSEC_ = 280, ARRAY_ = 281, ARROW_ = 282, ASINH_ = 283, AST_ = 284, AUTO_ = 285, AUX_ = 286, AVERAGE_ = 287, B1950_ = 288, BACK_ = 289, BASE_ = 290, BBOX_ = 291, BEGIN_ = 292, BG_ = 293, BIG_ = 294, BIGENDIAN_ = 295, BIN_ = 296, BITPIX_ = 297, BLOCK_ = 298, BLT_ = 299, BORDER_ = 300, BOX_ = 301, BOXANNULUS_ = 302, BOXCAR_ = 303, BOXCIRCLE_ = 304, BPANDA_ = 305, BUFFER_ = 306, BW_ = 307, CALLBACK_ = 308, CANVAS_ = 309, CATALOG_ = 310, CELESTRIAL_ = 311, CENTER_ = 312, CENTROID_ = 313, CHANNEL_ = 314, CIRCLE_ = 315, CIAO_ = 316, CLEAR_ = 317, CLIP_ = 318, COLOR_ = 319, COLORBAR_ = 320, COLORMAP_ = 321, COLORSCALE_ = 322, COLORSPACE_ = 323, COLS_ = 324, COLUMN_ = 325, COMMAND_ = 326, COMPASS_ = 327, COMPOSITE_ = 328, COMPRESS_ = 329, CONTOUR_ = 330, CONTRAST_ = 331, COORDINATES_ = 332, COPY_ = 333, COUNT_ = 334, CPANDA_ = 335, CREATE_ = 336, CROP_ = 337, CROSS_ = 338, CROSSHAIR_ = 339, CUBE_ = 340, CURSOR_ = 341, CUT_ = 342, CMYK_ = 343, DASH_ = 344, DASHLIST_ = 345, DATA_ = 346, DATAMIN_ = 347, DATASEC_ = 348, DEBUG_ = 349, DEGREES_ = 350, DEFAULT_ = 351, DELETE_ = 352, DEPTH_ = 353, DETECTOR_ = 354, DIAMOND_ = 355, DIM_ = 356, DS9_ = 357, EDIT_ = 358, ECLIPTIC_ = 359, ELLIPSE_ = 360, ELLIPSEANNULUS_ = 361, END_ = 362, EPANDA_ = 363, EQUATORIAL_ = 364, ERASE_ = 365, EXT_ = 366, FACTOR_ = 367, FALSE_ = 368, FILE_ = 369, FILTER_ = 370, FIT_ = 371, FITS_ = 372, FITSY_ = 373, FIXED_ = 374, FK4_ = 375, FK4_NO_E_ = 376, FK5_ = 377, FONT_ = 378, FROM_ = 379, FRONT_ = 380, FULL_ = 381, FUNCTION_ = 382, GALACTIC_ = 383, GAUSSIAN_ = 384, GET_ = 385, GLOBAL_ = 386, GRAPHICS_ = 387, GRAY_ = 388, GRID_ = 389, GZ_ = 390, HANDLE_ = 391, HAS_ = 392, HEAD_ = 393, HEADER_ = 394, HEIGHT_ = 395, HELIOECLIPTIC_ = 396, HIDE_ = 397, HIGH_ = 398, HIGHLITE_ = 399, HISTEQU_ = 400, HISTOGRAM_ = 401, HORIZONTAL_ = 402, ICRS_ = 403, ID_ = 404, IIS_ = 405, IMAGE_ = 406, INCLUDE_ = 407, INCR_ = 408, INFO_ = 409, INTEGER_ = 410, ITERATION_ = 411, IRAF_ = 412, IRAFMIN_ = 413, J2000_ = 414, KEY_ = 415, KEYWORD_ = 416, LABEL_ = 417, LENGTH_ = 418, LEVEL_ = 419, LITTLE_ = 420, LITTLEENDIAN_ = 421, LINE_ = 422, LINEAR_ = 423, LIST_ = 424, LOAD_ = 425, LOCAL_ = 426, LOG_ = 427, LOW_ = 428, MACOSX_ = 429, MAGNIFIER_ = 430, MATCH_ = 431, MAP_ = 432, MARK_ = 433, MARKER_ = 434, MASK_ = 435, MESSAGE_ = 436, METHOD_ = 437, MINMAX_ = 438, MIP_ = 439, MMAP_ = 440, MMAPINCR_ = 441, MOSAIC_ = 442, MODE_ = 443, MOTION_ = 444, MOVE_ = 445, NAME_ = 446, NAN_ = 447, NATIVE_ = 448, NAXES_ = 449, NEW_ = 450, NEXT_ = 451, NO_ = 452, NONE_ = 453, NOW_ = 454, NRRD_ = 455, NUMBER_ = 456, OBJECT_ = 457, OFF_ = 458, ON_ = 459, ONLY_ = 460, OPTION_ = 461, ORIENT_ = 462, PAN_ = 463, PANNER_ = 464, PARAM_ = 465, PARSER_ = 466, PASTE_ = 467, PERF_ = 468, PHOTO_ = 469, PHYSICAL_ = 470, PIXEL_ = 471, PLOT2D_ = 472, PLOT3D_ = 473, POINT_ = 474, POINTER_ = 475, POLYGON_ = 476, POSTSCRIPT_ = 477, POW_ = 478, PRINT_ = 479, PRESERVE_ = 480, PROJECTION_ = 481, PROPERTY_ = 482, PUBLICATION_ = 483, PROS_ = 484, RADIAL_ = 485, RADIUS_ = 486, REGION_ = 487, REPLACE_ = 488, RESAMPLE_ = 489, RESET_ = 490, RESOLUTION_ = 491, RGB_ = 492, ROOT_ = 493, ROTATE_ = 494, RULER_ = 495, SAMPLE_ = 496, SAOIMAGE_ = 497, SAOTNG_ = 498, SAVE_ = 499, SCALE_ = 500, SCAN_ = 501, SCIENTIFIC_ = 502, SCOPE_ = 503, SEGMENT_ = 504, SELECT_ = 505, SET_ = 506, SEXAGESIMAL_ = 507, SHAPE_ = 508, SHARED_ = 509, SHIFT_ = 510, SHMID_ = 511, SHOW_ = 512, SINH_ = 513, SIZE_ = 514, SLICE_ = 515, SMMAP_ = 516, SMOOTH_ = 517, SOCKET_ = 518, SOCKETGZ_ = 519, SOURCE_ = 520, SQRT_ = 521, SQUARED_ = 522, SSHARED_ = 523, STATS_ = 524, STATUS_ = 525, SUPERGALACTIC_ = 526, SUM_ = 527, SYSTEM_ = 528, TABLE_ = 529, TAG_ = 530, TEMPLATE_ = 531, TEXT_ = 532, THREADS_ = 533, THREED_ = 534, THRESHOLD_ = 535, THICK_ = 536, TRANSPARENCY_ = 537, TO_ = 538, TOGGLE_ = 539, TOPHAT_ = 540, TRUE_ = 541, TYPE_ = 542, UNDO_ = 543, UNHIGHLITE_ = 544, UNLOAD_ = 545, UNSELECT_ = 546, UPDATE_ = 547, USER_ = 548, VALUE_ = 549, VAR_ = 550, VIEW_ = 551, VECTOR_ = 552, VERSION_ = 553, VERTEX_ = 554, VERTICAL_ = 555, WARP_ = 556, WCS_ = 557, WCSA_ = 558, WCSB_ = 559, WCSC_ = 560, WCSD_ = 561, WCSE_ = 562, WCSF_ = 563, WCSG_ = 564, WCSH_ = 565, WCSI_ = 566, WCSJ_ = 567, WCSK_ = 568, WCSL_ = 569, WCSM_ = 570, WCSN_ = 571, WCSO_ = 572, WCSP_ = 573, WCSQ_ = 574, WCSR_ = 575, WCSS_ = 576, WCST_ = 577, WCSU_ = 578, WCSV_ = 579, WCSW_ = 580, WCSX_ = 581, WCSY_ = 582, WCSZ_ = 583, WCS0_ = 584, WFPC2_ = 585, WIDTH_ = 586, WIN32_ = 587, XML_ = 588, XY_ = 589, YES_ = 590, ZMAX_ = 591, ZSCALE_ = 592, ZOOM_ = 593 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define POINTER 261 #define ANGDEGREE 262 #define ANGRADIAN 263 #define SEXSTR 264 #define HMSSTR 265 #define DMSSTR 266 #define ABOUT_ 267 #define AIP_ 268 #define ALLOC_ 269 #define ALLOCGZ_ 270 #define ALIGN_ 271 #define ALL_ 272 #define ALT_ 273 #define AMPLIFIER_ 274 #define ANALYSIS_ 275 #define ANGLE_ 276 #define ANNULUS_ 277 #define APPEND_ 278 #define ARCMIN_ 279 #define ARCSEC_ 280 #define ARRAY_ 281 #define ARROW_ 282 #define ASINH_ 283 #define AST_ 284 #define AUTO_ 285 #define AUX_ 286 #define AVERAGE_ 287 #define B1950_ 288 #define BACK_ 289 #define BASE_ 290 #define BBOX_ 291 #define BEGIN_ 292 #define BG_ 293 #define BIG_ 294 #define BIGENDIAN_ 295 #define BIN_ 296 #define BITPIX_ 297 #define BLOCK_ 298 #define BLT_ 299 #define BORDER_ 300 #define BOX_ 301 #define BOXANNULUS_ 302 #define BOXCAR_ 303 #define BOXCIRCLE_ 304 #define BPANDA_ 305 #define BUFFER_ 306 #define BW_ 307 #define CALLBACK_ 308 #define CANVAS_ 309 #define CATALOG_ 310 #define CELESTRIAL_ 311 #define CENTER_ 312 #define CENTROID_ 313 #define CHANNEL_ 314 #define CIRCLE_ 315 #define CIAO_ 316 #define CLEAR_ 317 #define CLIP_ 318 #define COLOR_ 319 #define COLORBAR_ 320 #define COLORMAP_ 321 #define COLORSCALE_ 322 #define COLORSPACE_ 323 #define COLS_ 324 #define COLUMN_ 325 #define COMMAND_ 326 #define COMPASS_ 327 #define COMPOSITE_ 328 #define COMPRESS_ 329 #define CONTOUR_ 330 #define CONTRAST_ 331 #define COORDINATES_ 332 #define COPY_ 333 #define COUNT_ 334 #define CPANDA_ 335 #define CREATE_ 336 #define CROP_ 337 #define CROSS_ 338 #define CROSSHAIR_ 339 #define CUBE_ 340 #define CURSOR_ 341 #define CUT_ 342 #define CMYK_ 343 #define DASH_ 344 #define DASHLIST_ 345 #define DATA_ 346 #define DATAMIN_ 347 #define DATASEC_ 348 #define DEBUG_ 349 #define DEGREES_ 350 #define DEFAULT_ 351 #define DELETE_ 352 #define DEPTH_ 353 #define DETECTOR_ 354 #define DIAMOND_ 355 #define DIM_ 356 #define DS9_ 357 #define EDIT_ 358 #define ECLIPTIC_ 359 #define ELLIPSE_ 360 #define ELLIPSEANNULUS_ 361 #define END_ 362 #define EPANDA_ 363 #define EQUATORIAL_ 364 #define ERASE_ 365 #define EXT_ 366 #define FACTOR_ 367 #define FALSE_ 368 #define FILE_ 369 #define FILTER_ 370 #define FIT_ 371 #define FITS_ 372 #define FITSY_ 373 #define FIXED_ 374 #define FK4_ 375 #define FK4_NO_E_ 376 #define FK5_ 377 #define FONT_ 378 #define FROM_ 379 #define FRONT_ 380 #define FULL_ 381 #define FUNCTION_ 382 #define GALACTIC_ 383 #define GAUSSIAN_ 384 #define GET_ 385 #define GLOBAL_ 386 #define GRAPHICS_ 387 #define GRAY_ 388 #define GRID_ 389 #define GZ_ 390 #define HANDLE_ 391 #define HAS_ 392 #define HEAD_ 393 #define HEADER_ 394 #define HEIGHT_ 395 #define HELIOECLIPTIC_ 396 #define HIDE_ 397 #define HIGH_ 398 #define HIGHLITE_ 399 #define HISTEQU_ 400 #define HISTOGRAM_ 401 #define HORIZONTAL_ 402 #define ICRS_ 403 #define ID_ 404 #define IIS_ 405 #define IMAGE_ 406 #define INCLUDE_ 407 #define INCR_ 408 #define INFO_ 409 #define INTEGER_ 410 #define ITERATION_ 411 #define IRAF_ 412 #define IRAFMIN_ 413 #define J2000_ 414 #define KEY_ 415 #define KEYWORD_ 416 #define LABEL_ 417 #define LENGTH_ 418 #define LEVEL_ 419 #define LITTLE_ 420 #define LITTLEENDIAN_ 421 #define LINE_ 422 #define LINEAR_ 423 #define LIST_ 424 #define LOAD_ 425 #define LOCAL_ 426 #define LOG_ 427 #define LOW_ 428 #define MACOSX_ 429 #define MAGNIFIER_ 430 #define MATCH_ 431 #define MAP_ 432 #define MARK_ 433 #define MARKER_ 434 #define MASK_ 435 #define MESSAGE_ 436 #define METHOD_ 437 #define MINMAX_ 438 #define MIP_ 439 #define MMAP_ 440 #define MMAPINCR_ 441 #define MOSAIC_ 442 #define MODE_ 443 #define MOTION_ 444 #define MOVE_ 445 #define NAME_ 446 #define NAN_ 447 #define NATIVE_ 448 #define NAXES_ 449 #define NEW_ 450 #define NEXT_ 451 #define NO_ 452 #define NONE_ 453 #define NOW_ 454 #define NRRD_ 455 #define NUMBER_ 456 #define OBJECT_ 457 #define OFF_ 458 #define ON_ 459 #define ONLY_ 460 #define OPTION_ 461 #define ORIENT_ 462 #define PAN_ 463 #define PANNER_ 464 #define PARAM_ 465 #define PARSER_ 466 #define PASTE_ 467 #define PERF_ 468 #define PHOTO_ 469 #define PHYSICAL_ 470 #define PIXEL_ 471 #define PLOT2D_ 472 #define PLOT3D_ 473 #define POINT_ 474 #define POINTER_ 475 #define POLYGON_ 476 #define POSTSCRIPT_ 477 #define POW_ 478 #define PRINT_ 479 #define PRESERVE_ 480 #define PROJECTION_ 481 #define PROPERTY_ 482 #define PUBLICATION_ 483 #define PROS_ 484 #define RADIAL_ 485 #define RADIUS_ 486 #define REGION_ 487 #define REPLACE_ 488 #define RESAMPLE_ 489 #define RESET_ 490 #define RESOLUTION_ 491 #define RGB_ 492 #define ROOT_ 493 #define ROTATE_ 494 #define RULER_ 495 #define SAMPLE_ 496 #define SAOIMAGE_ 497 #define SAOTNG_ 498 #define SAVE_ 499 #define SCALE_ 500 #define SCAN_ 501 #define SCIENTIFIC_ 502 #define SCOPE_ 503 #define SEGMENT_ 504 #define SELECT_ 505 #define SET_ 506 #define SEXAGESIMAL_ 507 #define SHAPE_ 508 #define SHARED_ 509 #define SHIFT_ 510 #define SHMID_ 511 #define SHOW_ 512 #define SINH_ 513 #define SIZE_ 514 #define SLICE_ 515 #define SMMAP_ 516 #define SMOOTH_ 517 #define SOCKET_ 518 #define SOCKETGZ_ 519 #define SOURCE_ 520 #define SQRT_ 521 #define SQUARED_ 522 #define SSHARED_ 523 #define STATS_ 524 #define STATUS_ 525 #define SUPERGALACTIC_ 526 #define SUM_ 527 #define SYSTEM_ 528 #define TABLE_ 529 #define TAG_ 530 #define TEMPLATE_ 531 #define TEXT_ 532 #define THREADS_ 533 #define THREED_ 534 #define THRESHOLD_ 535 #define THICK_ 536 #define TRANSPARENCY_ 537 #define TO_ 538 #define TOGGLE_ 539 #define TOPHAT_ 540 #define TRUE_ 541 #define TYPE_ 542 #define UNDO_ 543 #define UNHIGHLITE_ 544 #define UNLOAD_ 545 #define UNSELECT_ 546 #define UPDATE_ 547 #define USER_ 548 #define VALUE_ 549 #define VAR_ 550 #define VIEW_ 551 #define VECTOR_ 552 #define VERSION_ 553 #define VERTEX_ 554 #define VERTICAL_ 555 #define WARP_ 556 #define WCS_ 557 #define WCSA_ 558 #define WCSB_ 559 #define WCSC_ 560 #define WCSD_ 561 #define WCSE_ 562 #define WCSF_ 563 #define WCSG_ 564 #define WCSH_ 565 #define WCSI_ 566 #define WCSJ_ 567 #define WCSK_ 568 #define WCSL_ 569 #define WCSM_ 570 #define WCSN_ 571 #define WCSO_ 572 #define WCSP_ 573 #define WCSQ_ 574 #define WCSR_ 575 #define WCSS_ 576 #define WCST_ 577 #define WCSU_ 578 #define WCSV_ 579 #define WCSW_ 580 #define WCSX_ 581 #define WCSY_ 582 #define WCSZ_ 583 #define WCS0_ 584 #define WFPC2_ 585 #define WIDTH_ 586 #define WIN32_ 587 #define XML_ 588 #define XY_ 589 #define YES_ 590 #define ZMAX_ 591 #define ZSCALE_ 592 #define ZOOM_ 593 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 51 "parser.Y" { #define FRBUFSIZE 4096 char chr; char str[FRBUFSIZE]; void* ptr; int integer; double real; double vector[3]; int dash[2]; } /* Line 1529 of yacc.c. */ #line 736 "parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �����������������./saods9/saotk/frame/frmarkerxml.C������������������������������������������������������������������0000644�0001750�0001750�00000103020�11734430020�015742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <fstream> #include "fdstream.hpp" #include <libxml/xmlreader.h> #include "context.h" #include "framebase.h" #include "fitsimage.h" static int xmlRead (void * context, char * buffer, int len) { istream* str=(istream*)context; str->read(buffer,len); return str->gcount(); } static int xmlClose (void * context) { return 1; } void Base::xmlParse(istream& str) { xmlTextReaderPtr reader = xmlReaderForIO(xmlRead, xmlClose, (void*)(&str), "", NULL, 0); if (reader) { char** cols=NULL; int colcnt=0; int id[128]; char* unit[128]; char* ref[128]; char* axis[128]; char* dir[128]; for (int ii=0; ii<128; ii++) { id[ii]=0; unit[ii]=NULL; ref[ii]=NULL; dir[ii]=NULL; } int cnt=0; int state=0; int ret = xmlTextReaderRead(reader); while (ret == 1) { int nodeType = xmlTextReaderNodeType(reader); char* key = (char*)xmlTextReaderConstName(reader); if (!strncmp(key,"VOTABLE",7) && (nodeType==1)) { } else if (!strncmp(key,"VOTABLE",7) && (nodeType==15)) { } else if (!strncmp(key,"DEFINITIONS",11) && (nodeType==1)) { } else if (!strncmp(key,"DEFINITIONS",11) && (nodeType==15)) { } else if (!strncmp(key,"COOSYS",6) && (nodeType==1)) { } else if (!strncmp(key,"COOSYS",6) && (nodeType==15)) { } else if (!strncmp(key,"RESOURCE",8) && (nodeType==1)) { } else if (!strncmp(key,"RESOURCE",8) && (nodeType==15)) { } else if (!strncmp(key,"TABLE",5) && (nodeType==1)) { } else if (!strncmp(key,"TABLE",5) && (nodeType==15)) { } else if (!strncmp(key,"FIELD",5) && (nodeType==1)) { xmlParseFIELD(reader,id,unit,ref,axis,dir,colcnt); state = 2; colcnt++; } else if (!strncmp(key,"FIELD",5) && (nodeType==15)) { state = 0; } else if (!strncmp(key,"DATA",4) && (nodeType==1)) { state = 0; } else if (!strncmp(key,"DATA",4) && (nodeType==15)) { } else if (!strncmp(key,"TABLEDATA",9) && (nodeType==1)) { state = 0; } else if (!strncmp(key,"TABLEDATA",9) && (nodeType==15)) { } else if (!strncmp(key,"TR",2) && (nodeType==1)) { if (cols) { for (int ii=0; ii<colcnt; ii++) if (cols[ii]) delete [] cols[ii]; delete [] cols; } cols = new char*[colcnt]; for (int ii=0; ii<colcnt; ii++) cols[ii] = NULL; cnt=0; } else if(!strncmp(key,"TR",2) && (nodeType==15)) { xmlParseTR(cols,id,unit,ref,axis,dir,colcnt); } else if (!strncmp(key,"TD",2) && (nodeType==1)) { state=1; } else if (!strncmp(key,"TD",2) && (nodeType==15)) { state=0; cnt++; } else if (!strncmp(key,"#text",5) && (nodeType==3)) { switch (state) { case 0: break; case 1: // td cols[cnt] = dupstr((char*)xmlTextReaderConstValue(reader)); break; case 2: // field break; } } ret = xmlTextReaderRead(reader); } xmlFreeTextReader(reader); if (ret != 0) cerr << "Failed to parse xml" << endl; xmlCleanupParser(); xmlMemoryDump(); } else cerr << "Unable to create xmlReader" << endl; } void Base::xmlParseFIELD(void* rr, int* id, char** unit, char** ref, char** axis, char** dir, int colcnt) { xmlTextReaderPtr reader = (xmlTextReaderPtr)rr; char* colname = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("name")); if (!colname) colname = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("NAME")); if (!colname) return; if (STRCMP(colname,"shape",5)) id[colcnt] = XMLSHAPE; else if (STRCMP(colname,"x",1)) id[colcnt] = XMLX; else if (STRCMP(colname,"y",1)) id[colcnt] = XMLY; else if (STRCMP(colname,"xv",2)) id[colcnt] = XMLXV; else if (STRCMP(colname,"yv",2)) id[colcnt] = XMLYV; else if (STRCMP(colname,"r",1)) id[colcnt] = XMLR; else if (STRCMP(colname,"r2",2)) id[colcnt] = XMLR2; else if (STRCMP(colname,"rv",2)) id[colcnt] = XMLRV; else if (STRCMP(colname,"rv2",3)) id[colcnt] = XMLRV2; else if (STRCMP(colname,"ang",3)) id[colcnt] = XMLANG; else if (STRCMP(colname,"angv",4)) id[colcnt] = XMLANGV; else if (STRCMP(colname,"tile",4)) id[colcnt] = XMLTILE; else if (STRCMP(colname,"color",5)) id[colcnt] = XMLCOLOR; else if (STRCMP(colname,"width",5)) id[colcnt] = XMLWIDTH; else if (STRCMP(colname,"text",4)) id[colcnt] = XMLTEXT; else if (STRCMP(colname,"font",4)) id[colcnt] = XMLFONT; else if (STRCMP(colname,"select",6)) id[colcnt] = XMLSELECT; else if (STRCMP(colname,"highlite",8)) id[colcnt] = XMLHIGHLITE; else if (STRCMP(colname,"edit",4)) id[colcnt] = XMLEDIT; else if (STRCMP(colname,"move",4)) id[colcnt] = XMLMOVE; else if (STRCMP(colname,"rotate",6)) id[colcnt] = XMLROTATE; else if (STRCMP(colname,"delete",6)) id[colcnt] = XMLDELETE; else if (STRCMP(colname,"fixed",5)) id[colcnt] = XMLFIXED; else if (STRCMP(colname,"include",7)) id[colcnt] = XMLINCLUDE; else if (STRCMP(colname,"source",6)) id[colcnt] = XMLSOURCE; else if (STRCMP(colname,"dash",4)) id[colcnt] = XMLDASH; else if (STRCMP(colname,"dashlist",8)) id[colcnt] = XMLDASHLIST; else if (STRCMP(colname,"tag",3)) id[colcnt] = XMLTAG; else if (STRCMP(colname,"param",5)) id[colcnt] = XMLPARAM; else if (STRCMP(colname,"param2",6)) id[colcnt] = XMLPARAM2; else if (STRCMP(colname,"param3",6)) id[colcnt] = XMLPARAM3; else if (STRCMP(colname,"param4",6)) id[colcnt] = XMLPARAM4; else if (STRCMP(colname,"param5",6)) id[colcnt] = XMLPARAM5; else if (STRCMP(colname,"comment",7)) id[colcnt] = XMLCOMMENT; unit[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("unit")); if (!unit[colcnt]) unit[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("UNIT")); ref[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("ref")); if (!ref[colcnt]) ref[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("REF")); axis[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("axis")); if (!axis[colcnt]) axis[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("AXIS")); dir[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("dir")); if (!dir[colcnt]) dir[colcnt] = (char*)xmlTextReaderGetAttribute(reader,(const xmlChar*)("DIR")); if (colname) free(colname); } void Base::xmlParseTR(char** cols, int* id, char** unit, char** ref, char** axis, char**dir, int colcnt) { // init region char* shape =NULL; char shapedef[] = "point"; shape = shapedef; // x,y char* x =NULL; char xdef[] = "0"; x = xdef; char* y =NULL; char ydef[] = "0"; y = ydef; Coord::CoordSystem sys =Coord::PHYSICAL; Coord::SkyFrame sky =Coord::FK5; Coord::SkyFormat format =Coord::DEGREES; // xv,yv char* xv =NULL; char xvdef[] = "0"; xv = xvdef; char* yv =NULL; char yvdef[] = "0"; yv = yvdef; Coord::CoordSystem vsys =Coord::PHYSICAL; Coord::SkyFrame vsky =Coord::FK5; Coord::SkyFormat vformat =Coord::DEGREES; // r,r2 char* r =NULL; char rdef[] = "0"; r = rdef; char* r2 =NULL; char r2def[] = "0"; r2 = r2def; Coord::CoordSystem rsys =Coord::PHYSICAL; Coord::SkyFrame rsky =Coord::FK5; Coord::SkyDist rdist =Coord::ARCMIN; // rv,rv2 char* rv =NULL; char rvdef[] = "0"; rv = rvdef; char* rv2 =NULL; char rv2def[] = "0"; rv2 = rv2def; Coord::CoordSystem rvsys =Coord::PHYSICAL; Coord::SkyFrame rvsky =Coord::FK5; Coord::SkyDist rvdist =Coord::ARCMIN; // ang char* ang =NULL; char angdef[] = "0"; ang = angdef; Coord::AngleFormat angformat =Coord::DEG; Coord::CoordSystem angsys =Coord::PHYSICAL; Coord::SkyFrame angsky =Coord::FK5; int angsign =1; double angoffset =0; // angv char* angv =NULL; char angvdef[] = "0"; angv = angvdef; Coord::AngleFormat angvformat =Coord::DEG; Coord::CoordSystem angvsys =Coord::PHYSICAL; Coord::SkyFrame angvsky =Coord::FK5; int angvsign =1; double angvoffset =0; // props int tile =1; char* color =NULL; char colordef[] = "green"; color = colordef; int width =1; char* text =NULL; char* font =NULL; char fontdef[] = "helvetica 10 normal roman"; font = fontdef; unsigned short props = Marker::SELECT | Marker::HIGHLITE | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::SOURCE | Marker::INCLUDE; int dash[2] = {8,3}; List<Tag> taglist; // params char* param =NULL; char* param2 =NULL; char* param3 =NULL; char* param4 =NULL; char* param5 =NULL; // comment char* comment=NULL; List<CallBack> cblist; // build it for (int ii=0; ii<colcnt; ii++) { if (cols[ii]) { switch (id[ii]) { case XMLSHAPE: shape = cols[ii]; break; case XMLX: // only check x col, y col better be the same x = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&sys,&sky); if (unit[ii]) coord.strToSkyFormat(unit[ii],&format); break; case XMLY: y = cols[ii]; break; case XMLXV: // only check x col, y col better be the same xv = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&vsys,&vsky); if (unit[ii]) coord.strToSkyFormat(unit[ii],&vformat); break; case XMLYV: yv = cols[ii]; break; case XMLR: // only check r col, r2 col better be the same r = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&rsys,&rsky); if (unit[ii]) coord.strToSkyDist(unit[ii],&rdist); break; case XMLR2: r2 = cols[ii]; break; case XMLRV: // only check rv col, r2 col better be the same rv = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&rvsys,&rvsky); if (unit[ii]) coord.strToSkyDist(unit[ii],&rvdist); break; case XMLRV2: rv2 = cols[ii]; break; case XMLANG: ang = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&angsys,&angsky); if (unit[ii]) coord.strToAngleFormat(unit[ii],&angformat); if (dir[ii]) if (STRCMP(dir[ii],"cw",2)) angsign = -1; if (axis[ii]) if (STRCMP(dir[ii],"x",1)) if (angsys == Coord::WCS) { switch (angsky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: angoffset = M_PI; } } else if (STRCMP(dir[ii],"-x",2)) if (angsys == Coord::WCS) { switch (angsky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: break; default: angoffset = M_PI; } } else if (STRCMP(dir[ii],"y",1)) angoffset = M_PI_2; else if (STRCMP(dir[ii],"-y",2)) angoffset = -M_PI_2; break; case XMLANGV: angv = cols[ii]; if (ref[ii]) coord.strToCoordSystem(ref[ii],wcsSystem_,&angvsys,&angvsky); if (unit[ii]) coord.strToAngleFormat(unit[ii],&angvformat); if (dir[ii]) if (STRCMP(dir[ii],"cw",2)) angvsign = -1; if (axis[ii]) if (STRCMP(dir[ii],"x",1)) ; else if (STRCMP(dir[ii],"-x",2)) angvoffset = M_PI; else if (STRCMP(dir[ii],"y",1)) angvoffset = M_PI_2; else if (STRCMP(dir[ii],"-y",2)) angvoffset = -M_PI_2; break; case XMLTILE: tile = atoi(cols[ii]); break; case XMLCOLOR: color = cols[ii]; break; case XMLWIDTH: width = atoi(cols[ii]); break; case XMLTEXT: text = cols[ii]; break; case XMLFONT: font = cols[ii]; break; case XMLSELECT: xmlSetProps(&props, Marker::SELECT, cols[ii]); break; case XMLHIGHLITE: xmlSetProps(&props, Marker::HIGHLITE, cols[ii]); break; case XMLEDIT: xmlSetProps(&props, Marker::EDIT, cols[ii]); break; case XMLMOVE: xmlSetProps(&props, Marker::MOVE, cols[ii]); break; case XMLROTATE: xmlSetProps(&props, Marker::ROTATE, cols[ii]); break; case XMLDELETE: xmlSetProps(&props, Marker::DELETE, cols[ii]); break; case XMLFIXED: xmlSetProps(&props, Marker::FIXED, cols[ii]); break; case XMLINCLUDE: xmlSetProps(&props, Marker::INCLUDE, cols[ii]); break; case XMLSOURCE: xmlSetProps(&props, Marker::SOURCE, cols[ii]); break; case XMLDASH: xmlSetProps(&props, Marker::DASH, cols[ii]); break; case XMLDASHLIST: { char* cc = dupstr(cols[ii]); char* tok = strtok(cc, ","); if (tok) dash[0] = atoi(tok); tok = strtok(NULL, ","); if (tok) dash[1] = atoi(tok); delete [] cc; } break; case XMLTAG: { char* cc = dupstr(cols[ii]); char* tok = strtok(cc, " "); while (tok) { // look for special #160 char* aa = dupstr(tok); char* dd = aa; char* ee = aa; while (*dd) if (*dd == -62) { *ee++ = ' '; dd +=2; } else *ee++ = *dd++; // NULL terminate if shortened *ee = *dd; taglist.append(new Tag(aa)); delete [] aa; tok = strtok(NULL, " "); } delete [] cc; } break; case XMLPARAM: param = cols[ii]; break; case XMLPARAM2: param2 = cols[ii]; break; case XMLPARAM3: param3 = cols[ii]; break; case XMLPARAM4: param4 = cols[ii]; break; case XMLPARAM5: param5 = cols[ii]; break; case XMLCOMMENT: comment = cols[ii]; break; } } } FitsImage* ptr = findFits(tile); // Basic Regions if (STRCMP(shape, "circle", 6)) { // will also capture circle3d createCircleCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(atof(r), rsys, rdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "ellipse", 7)) { createEllipseCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(Vector(atof(r),atof(r2)), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "box", 3) || STRCMP(shape, "rotbox", 6)) { createBoxCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(Vector(atof(r),atof(r2)), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "rectang", 6) || STRCMP(shape, "rotrec", 6)) { Vector v1 = xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0); Vector v2 = xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1); Vector d = v2-v1; Vector c = d/2 + v1; createBoxCmd(c,d, xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "polygon", 7)) { List<Vertex>* list = xmlVertex(ptr, xv, yv, vsys, vsky, vformat); createPolygonCmd(*list, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "line", 4)) { int arrow1 =1; int arrow2 =1; if (!param) arrow1 = atoi(param); if (!param2) arrow2 = atoi(param2); createLineCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), arrow1, arrow2, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "vector", 6)) { int arrow =1; if (!param) arrow = atoi(param); createVectCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(atof(r), rsys, rdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), arrow, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "text", 4)) { int rotate = 1; if (!param) rotate = atoi(param); createTextCmd(xmlPoint(ptr, x, y, sys, sky, format), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), rotate, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "point", 5)) { char* def = "circle"; Point::PointShape shape = Point::CIRCLE; if (!param) param = def; int size = 11; if (param2) size = atoi(param2); if (STRCMP(param, "circle", 6)) shape = Point::CIRCLE; else if (STRCMP(param, "box", 3)) shape = Point::BOX; else if (STRCMP(param, "diamond", 7)) shape = Point::DIAMOND; else if (STRCMP(param, "cross", 5)) shape = Point::CROSS; else if (STRCMP(param, "x", 1)) shape = Point::EX; else if (STRCMP(param, "arrow", 5)) shape = Point::ARROW; else if (STRCMP(param,"boxcircle",9)) shape = Point::BOXCIRCLE; createPointCmd(xmlPoint(ptr, x, y, sys, sky, format), shape, size, color, dash, width, font, text, props, comment, taglist, cblist); } // Measurement Regions else if (STRCMP(shape, "ruler", 5)) { Coord::CoordSystem rsys; Coord::SkyFrame rsky; coord.strToCoordSystem(param, wcsSystem_, &rsys, &rsky); Coord::CoordSystem dsys; Coord::SkyDist ddist; coord.strToDistSystem(param2, wcsSystem_, &dsys, &ddist); createRulerCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), rsys, rsky, dsys, ddist, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "compass", 7)) { Coord::CoordSystem csys; Coord::SkyFrame csky; coord.strToCoordSystem(param, wcsSystem_, &csys, &csky); char* param2def = "N"; if (!param2) param2 = param2def; char* param3def = "E"; if (!param3) param3 = param3def; int arrow1 =1; if (!param4) arrow1 = atoi(param4); int arrow2 =1; if (!param5) arrow2 = atoi(param5); createCompassCmd(xmlPoint(ptr, x, y, sys, sky, format), ptr->mapLenToRef(atof(r), rsys, rdist), param2, param3, arrow1, arrow2, csys, csky, color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "projection", 10)) { createProjectionCmd(xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 0), xmlPoint(ptr, xv, yv, vsys, vsky, vformat, 1), ptr->mapLenToRef(atof(r), rsys, rdist), color, dash, width, font, text, props, comment, taglist, cblist); } // Annulus Regions else if (STRCMP(shape, "annulus", 7)) { int num = xmlCount(rv); createAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, num, rvsys, rvdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "ellipseannulus", 14)) { int num = xmlCount(rv); createEllipseAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, rv2, num, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "boxannulus", 10)) { int num = xmlCount(rv); createBoxAnnulusCmd(xmlPoint(ptr, x, y, sys, sky, format), num, xmlDistance(ptr, rv, rv2, num, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } // Panda Regions else if (STRCMP(shape, "panda", 5) || STRCMP(shape, "pie", 3)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createCpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angvoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rnum, rvsys, rvdist), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "epanda", 6)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createEpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rv2, rnum, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } else if (STRCMP(shape, "bpanda", 6)) { int anum = xmlCount(angv); int rnum = xmlCount(rv); createBpandaCmd(xmlPoint(ptr, x, y, sys, sky, format), anum, xmlAngles(angv, angvsign, angvoffset, anum, angvformat, sys, sky), rnum, xmlDistance(ptr, rv, rv2, rnum, rvsys, rvdist), xmlAngle(ang, angsign, angoffset, angformat, sys, sky), color, dash, width, font, text, props, comment, taglist, cblist); } } void Base::xmlSetProps(unsigned short* props, unsigned short prop, char* str) { if (atoi(str)) *props |= prop; else *props &= ~prop; } int Base::xmlCount(const char* col) { int cnt=0; char* cc = dupstr(col); char* tok = strtok(cc, " "); while (tok) { cnt++; tok = strtok(NULL, " "); } delete [] cc; return cnt; } Vector Base::xmlPoint(FitsImage* ptr, const char* xstr, const char* ystr, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int which) { if (!xstr || !ystr) return Vector(); char* x =NULL; char* y =NULL; char* xcc =NULL; char* ycc =NULL; if (which>0) { xcc = dupstr(xstr); x = strtok(xcc, " "); for (int ii=0; ii<which; ii++) x = strtok(NULL, " "); ycc = dupstr(ystr); y = strtok(ycc, " ,"); for (int ii=0; ii<which; ii++) y = strtok(NULL, " "); } else { x = (char*)xstr; y = (char*)ystr; } Vector rr; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: rr = ptr->mapToRef(Vector(atof(x),atof(y)), sys); break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: rr = ptr->mapToRef(Vector(atof(x),atof(y)), sys, sky); break; case Coord::SEXAGESIMAL: { double xx=parseSEXStr(x); double yy=parseSEXStr(y); switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: xx = xx/24.*360.; break; case Coord::GALACTIC: case Coord::SUPERGALACTIC: case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: break; } rr = ptr->mapToRef(Vector(xx,yy), sys, sky); } } } else rr = ptr->mapToRef(Vector(atof(x),atof(y)), sys); } if (which>0) { if (xcc) delete [] xcc; if (ycc) delete [] ycc; } return rr; } List<Vertex>* Base::xmlVertex(FitsImage* ptr, const char* x, const char* y, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { List<Vertex>* list = new List<Vertex>; int cnt= xmlCount(x); for (int ii=0; ii<cnt; ii++) { Vector vv = xmlPoint(ptr,x,y,sys,sky,format,ii); Vertex* n = new Vertex(vv); list->append(n); } return list; } double* Base::xmlDistance(FitsImage* ptr, const char* r, int cnt, Coord::CoordSystem sys, Coord::SkyDist dist) { double* rr = new double[cnt]; char* cc = dupstr(r); char* tok = strtok(cc, " "); for (int ii=0; ii<cnt; ii++) { if (tok) rr[ii] = atof(tok); tok = strtok(NULL, " "); } delete [] cc; for (int ii=0; ii<cnt; ii++) rr[ii] = ptr->mapLenToRef(rr[ii], sys, dist); return rr; } Vector* Base::xmlDistance(FitsImage* ptr, const char* r, const char* r2, int cnt, Coord::CoordSystem sys, Coord::SkyDist dist) { Vector* vv = new Vector[cnt]; { char* cc = dupstr(r); char* tok = strtok(cc, " "); for (int ii=0; ii<cnt; ii++) { if (tok) vv[ii][0] = atof(tok); tok = strtok(NULL, " "); } delete [] cc; } { char* cc = dupstr(r2); char* tok = strtok(cc, " "); for (int ii=0; ii<cnt; ii++) { if (tok) vv[ii][1] = atof(tok); tok = strtok(NULL, " "); } delete [] cc; } for (int ii=0; ii<cnt; ii++) vv[ii] = ptr->mapLenToRef(vv[ii], sys, dist); return vv; } double Base::xmlAngle(const char* angle, int sign, double offset, Coord::AngleFormat format, Coord::CoordSystem sys, Coord::SkyFrame sky) { switch (format) { case Coord::DEG: return mapAngleToRef(sign*degToRad(atof(angle))+offset, sys, sky); case Coord::RAD: return mapAngleToRef(sign*atof(angle)+offset, sys, sky); } } double* Base::xmlAngles(const char* angle, int sign, double offset, int cnt, Coord::AngleFormat format, Coord::CoordSystem sys, Coord::SkyFrame sky) { double* ang = new double[cnt]; char* cc = dupstr(angle); char* tok = strtok(cc, " "); for (int ii=0; ii<cnt; ii++) { if (tok) switch (format) { case Coord::DEG: ang[ii] = mapAngleToRef(sign*degToRad(atof(tok))+offset, sys, sky); break; case Coord::RAD: ang[ii] = mapAngleToRef(sign*atof(tok)+offset, sys, sky); break; } tok = strtok(NULL, " "); } delete [] cc; return ang; } void Base::markerListXMLHeader(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<VOTABLE version=\"1.1\">" << endl << "<DEFINITIONS>" << endl << "<COOSYS ID=\"fk5\" system=\"eq_FK5\" equinox=\"J2000\"/>" << endl << "<COOSYS ID=\"fk4\" system=\"eq_FK4\" equinox=\"B1950\"/>" << endl << "</DEFINITIONS>" << endl << "<RESOURCE>" << endl << "<TABLE>" << endl << "<DESCRIPTION>DS9 version 4.1</DESCRIPTION>" << endl; str << "<FIELD ID=\"shape\" name=\"shape\" datatype=\"char\" arraysize=\"*\"/>" << endl; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: str << "<FIELD ID=\"x\" name=\"x\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"y\" name=\"y\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"xv\" name=\"xv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"yv\" name=\"yv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"r\" name=\"r\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"r2\" name=\"r2\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"rv\" name=\"rv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"rv2\" name=\"rv2\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"ang\" name=\"ang\" datatype=\"float\" precision=\"8\" unit=\"deg\" ref=\"" << coord.coordSystemStr(sys) << "\" axis=\"x\" dir=\"ccw\"/>" << endl; str << "<FIELD ID=\"angv\" name=\"angv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"deg\" ref=\"" << coord.coordSystemStr(sys) << "\" axis=\"x\" dir=\"ccw\"/>" << endl; break; default: if (keyContext->fits->hasWCS(sys)) { if (keyContext->fits->hasWCSCel(sys)) { // determine ucd char* xucd=NULL; char* yucd=NULL; switch (sky) { case Coord::FK4: case Coord::FK4_NO_E: case Coord::FK5: case Coord::ICRS: xucd = dupstr("pos.eq.ra;meta.main"); yucd = dupstr("pos.eq.dec;meta.main"); break; case Coord::GALACTIC: case Coord::SUPERGALACTIC: xucd = dupstr("pos.galactic.lon;meta.main"); yucd = dupstr("pos.galactic.lat;meta.main"); break; case Coord::ECLIPTIC: case Coord::HELIOECLIPTIC: xucd = dupstr("pos.ecliptic.lon;meta.main"); yucd = dupstr("pos.ecliptic.lat;meta.main"); break; } switch (format) { case Coord::DEGREES: str << "<FIELD ID=\"x\" name=\"x\" datatype=\"float\" precision=\"8\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\" ucd=\"" << xucd << "\"/>" << endl; str << "<FIELD ID=\"y\" name=\"y\" datatype=\"float\" precision=\"8\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\" ucd=\"" << yucd << "\"/>" << endl; str << "<FIELD ID=\"xv\" name=\"xv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"yv\" name=\"yv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; break; case Coord::SEXAGESIMAL: str << "<FIELD ID=\"x\" name=\"x\" datatype=\"char\" arraysize=\"*\" unit=\"&quot;h:m:s&quot;\" ref=\"" << coord.skyFrameStr(sky) << "\" ucd=\"" << xucd << "\"/>" << endl; str << "<FIELD ID=\"y\" name=\"y\" datatype=\"char\" arraysize=\"*\" unit=\"&quot;d:m:s&quot;\" ref=\"" << coord.skyFrameStr(sky) << "\" ucd=\"" << yucd << "\"/>" << endl; str << "<FIELD ID=\"xv\" name=\"xv\" datatype=\"char\" arraysize=\"*\" unit=\"&quot;h:m:s&quot;\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"yv\" name=\"yv\" datatype=\"char\" arraysize=\"*\" unit=\"&quot;d:m:s&quot;\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; break; } str << "<FIELD ID=\"r\" name=\"r\" datatype=\"float\" precision=\"8\" unit=\"arcsec\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"r2\" name=\"r2\" datatype=\"float\" precision=\"8\" unit=\"arcsec\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"rv\" name=\"rv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"arcsec\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"rv2\" name=\"rv2\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"arcsec\" ref=\"" << coord.skyFrameStr(sky) << "\"/>" << endl; str << "<FIELD ID=\"ang\" name=\"ang\" datatype=\"float\" precision=\"8\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\" axis=\"-x\" dir=\"ccw\"/>" << endl; str << "<FIELD ID=\"angv\" name=\"angv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"deg\" ref=\"" << coord.skyFrameStr(sky) << "\" axis=\"-x\" dir=\"ccw\"/>" << endl; } else { str << "<FIELD ID=\"x\" name=\"x\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"y\" name=\"y\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"xv\" name=\"xv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"yv\" name=\"yv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"r\" name=\"r\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"r2\" name=\"r2\" datatype=\"float\" precision=\"8\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"rv\" name=\"rv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"rv2\" name=\"rv2\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"pix\" ref=\"" << coord.coordSystemStr(sys) << "\"/>" << endl; str << "<FIELD ID=\"ang\" name=\"ang\" datatype=\"float\" precision=\"8\" unit=\"deg\" ref=\"" << coord.coordSystemStr(sys) << "\" axis=\"x\" dir=\"ccw\"/>" << endl; str << "<FIELD ID=\"angv\" name=\"angv\" datatype=\"float\" precision=\"8\" arraysize=\"*\" unit=\"deg\" ref=\"" << coord.coordSystemStr(sys) << "\" axis=\"x\" dir=\"ccw\"/>" << endl; } } } str << "<FIELD ID=\"tile\" name=\"tile\" datatype=\"int\"/>" << endl; str << "<FIELD ID=\"color\" name=\"color\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"width\" name=\"width\" datatype=\"int\"/>" << endl; str << "<FIELD ID=\"text\" name=\"text\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"font\" name=\"font\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"select\" name=\"select\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"highlite\" name=\"highlite\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"edit\" name=\"edit\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"move\" name=\"move\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"rotate\" name=\"rotate\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"delete\" name=\"delete\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"fixed\" name=\"fixed\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"include\" name=\"include\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"source\" name=\"source\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"dash\" name=\"dash\" datatype=\"boolean\"/>" << endl; str << "<FIELD ID=\"dashlist\" name=\"dashlist\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"tag\" name=\"tag\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"param\" name=\"param\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"param2\" name=\"param2\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"param3\" name=\"param3\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"param4\" name=\"param4\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"param5\" name=\"param5\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<FIELD ID=\"comment\" name=\"comment\" datatype=\"char\" arraysize=\"*\"/>" << endl; str << "<DATA>" << endl << "<TABLEDATA>" << endl; } void Base::markerListXMLFooter(ostream& str) { str << "</TABLEDATA>" << endl << "</DATA>" << endl << "</TABLE>" << endl << "</RESOURCE>" << endl << "</VOTABLE>" << endl; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/polygon.C����������������������������������������������������������������������0000644�0001750�0001750�00000044001�12057220627�015113� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "polygon.h" #include "fitsimage.h" Polygon::Polygon(const Polygon& a) : Marker(a) { vertex = a.vertex; } Polygon::Polygon(Base* p, const Vector& ctr, const Vector& b, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { angle = 0; strcpy(type_, "polygon"); Vector bb = b; vertex.append(new Vertex(-bb[0],-bb[1])); vertex.append(new Vertex( bb[0],-bb[1])); vertex.append(new Vertex( bb[0], bb[1])); vertex.append(new Vertex(-bb[0], bb[1])); updateBBox(); } Polygon::Polygon(Base* p, const List<Vertex>& v, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, Vector(0,0), 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { // Vertex list is in ref coords angle = 0; strcpy(type_, "polygon"); vertex = v; // check to see if the first and last node are the same if (vertex.head()->vector[0] == vertex.tail()->vector[0] && vertex.head()->vector[1] == vertex.tail()->vector[1]) delete vertex.pop(); // find center center = Vector(0,0); vertex.head(); do center += vertex.current()->vector; while (vertex.next()); center /= vertex.count(); // vertices are relative vertex.head(); do vertex.current()->vector *= Translate(-center) * FlipY(); // no rotation while (vertex.next()); updateBBox(); } void Polygon::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); vertex.head(); Vector v1; Vector v2 = fwdMap(vertex.current()->vector,sys); int done = 0; do { if (!vertex.next()) { done = 1; vertex.head(); } v1 = v2; v2 = fwdMap(vertex.current()->vector,sys); XDrawLine(display, drawable, lgc, v1[0], v1[1], v2[0], v2[1]); } while (!done); } void Polygon::renderPS(int mode) { renderPSGC(mode); vertex.head(); int first = 1; do { ostringstream str; Vector v = fwdMap(vertex.current()->vector,Coord::CANVAS); if (first) { str << "newpath " << endl << v.TkCanvasPs(parent->canvas) << " moveto" << endl << ends; first = 0; } else str << v.TkCanvasPs(parent->canvas) << " lineto" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } while (vertex.next()); ostringstream str; str << "closepath stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } #ifdef _MACOSX void Polygon::renderMACOSX() { renderMACOSXGC(); vertex.head(); Vector v1; Vector v2 = fwdMap(vertex.current()->vector,Coord::CANVAS); int done = 0; do { if (!vertex.next()) { done = 1; vertex.head(); } v1 = v2; v2 = fwdMap(vertex.current()->vector,Coord::CANVAS); macosxDrawLine(v1,v2); } while (!done); } #endif #ifdef _WIN32 void Polygon::renderWIN32() { renderWIN32GC(); vertex.head(); Vector v1; Vector v2 = fwdMap(vertex.current()->vector,Coord::CANVAS); int done = 0; do { if (!vertex.next()) { done = 1; vertex.head(); } v1 = v2; v2 = fwdMap(vertex.current()->vector,Coord::CANVAS); win32DrawLine(v1,v2); } while (!done); } #endif // Support void Polygon::updateHandles() { // generate handles numHandle = 4 + vertex.count(); if (handle) delete [] handle; handle = new Vector[numHandle]; // the first four are our control handles BBox bb; vertex.head(); do bb.bound(vertex.current()->vector); while (vertex.next()); Vector zz = parent->zoom(); float r = 10/zz.length(); bb.expand(r); // give us more room handle[0] = fwdMap(bb.ll,Coord::CANVAS); handle[1] = fwdMap(bb.lr(),Coord::CANVAS); handle[2] = fwdMap(bb.ur,Coord::CANVAS); handle[3] = fwdMap(bb.ul(),Coord::CANVAS); // and the rest are vertices int i=4; vertex.head(); do handle[i++] = fwdMap(vertex.current()->vector,Coord::CANVAS); while (vertex.next()); } void Polygon::updateCoords(const Matrix& mx) { Scale s(mx); vertex.head(); do vertex.current()->vector *= s; while (vertex.next()); Marker::updateCoords(mx); } void Polygon::edit(const Vector& v, int h) { if (h < 5) { Vector s1 = v * bckMatrix(); Vector s2 = bckMap(handle[h-1],Coord::CANVAS); if (s1[0] != 0 && s1[1] != 0 && s2[0] != 0 && s2[1] != 0) { double a = fabs(s1[0]/s2[0]); double b = fabs(s1[1]/s2[1]); double s = a > b ? a : b; vertex.head(); do vertex.current()->vector *= Scale(s); while (vertex.next()); } updateBBox(); doCallBack(CallBack::EDITCB); } else { moveVertex(v,h); updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); // center can change } } void Polygon::rotate(const Vector& v, int h) { if (h < 5) Marker::rotate(v,h); else { // we need to check this here, because we are really rotating if (canEdit()) { moveVertex(v,h); updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); // center can change } } } void Polygon::reset(const Vector& b) { angle = 0; vertex.deleteAll(); Vector bb = b; vertex.append(new Vertex(-bb[0],-bb[1])); vertex.append(new Vertex( bb[0],-bb[1])); vertex.append(new Vertex( bb[0], bb[1])); vertex.append(new Vertex(-bb[0], bb[1])); updateBBox(); } int Polygon::isIn(const Vector& vv, Coord::InternalSystem sys) { /* v[0]-- x value of point being tested v[1]-- y value of point being tested This algorithm is from "An Introduction to Ray Tracing", Academic Press, 1989, edited by Andrew Glassner, pg 53 -- a point lies in a polygon if a line is extended from the point to infinite in any direction and the number of intersections with the polygon is odd. This is valid for both concave and convex polygons. Points on a vertex are considered inside. Points on a edge are considered inside. */ Vector v = bckMap(vv,sys); int crossings = 0; // number of crossings vertex.head(); Vector v1; Vector v2 = vertex.current()->vector - v; int sign = ((v2[1])>=0) ? 1 : -1; // init sign // for all edges int done = 0; do { // look at next two vertices v1 = v2; if (!vertex.next()) { done = 1; vertex.head(); } v2 = vertex.current()->vector - v; int nextSign = (v2[1]>=0) ? 1 : -1; // sign holder for p2 if (sign != nextSign) { if (v1[0]>0 && v2[0]>0) crossings++; else if (v1[0]>0 || v2[0]>0) { if (v1[0]-(v1[1]*(v2[0]-v1[0])/(v2[1]-v1[1])) > 0) crossings++; } sign = nextSign; } } while (!done); return fmod(float(crossings),float(2)) ? 1 : 0; // if odd, point is inside } void Polygon::createVertex(int which, const Vector& v) { // which segment (1 to n) // v is in ref coords Matrix mm = bckMatrix(); int seg = which-1; if (seg>=0 && seg<vertex.count()) { Vertex* n = new Vertex(v * mm); vertex.insert(seg,n); recalcCenter(); updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); // center can change } } void Polygon::deleteVertex(int h) { if (h>4) { int hh = h-4-1; if (vertex.count() > 3) { Vertex* v = vertex[hh]; if (v) { vertex.extractNext(v); delete v; recalcCenter(); updateBBox(); doCallBack(CallBack::EDITCB); doCallBack(CallBack::MOVECB); // center can change } } } } int Polygon::getSegment(const Vector& v) { // v is in canvas coords Matrix mm = fwdMatrix(); vertex.head(); Vector v1; Vector v2 = vertex.current()->vector * mm; int done = 0; int i = 1; do { v1 = v2; if (!vertex.next()) { vertex.head(); done = 1; } v2 = vertex.current()->vector * mm; Vector l1 = parent->mapFromRef(v1,Coord::CANVAS); Vector l2 = parent->mapFromRef(v2,Coord::CANVAS); double a = (l2-l1).angle(); Matrix mx = Translate(-l1) * FlipY() * Rotate(-a); Vector end = l2*mx; Vector vv = v*mx; if (vv[0]>0 && vv[0]<end[0] && vv[1]>-3 && vv[1]<3) return i; i++; } while (!done); return 0; } void Polygon::moveVertex(const Vector& v, int h) { Matrix mm = bckMatrix(); if (vertex[h-5]) vertex.current()->vector = v * mm; recalcCenter(); } void Polygon::recalcCenter() { // recalculate center Vector nc; vertex.head(); do nc += vertex.current()->vector * Rotate(angle) * FlipY(); while (vertex.next()); nc /= vertex.count(); center += nc; // update all vertices vertex.head(); do vertex.current()->vector -= nc * FlipY() * Rotate(-angle); while (vertex.next()); } void Polygon::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT3D: if (!analysisPlot3d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot3dCB_[1], parent->options->cmdName); } if (analysisPlot3d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot3dCB_[1]); } analysisPlot3d_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Polygon::analysisPlot3d(char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { double* x; double* y; BBox bb(center); Matrix mm = Rotate(angle) * Translate(center); vertex.head(); do bb.bound(vertex.current()->vector * mm); while (vertex.next()); int num = parent->markerAnalysisPlot3d(this, &x, &y, bb, sys, method); analysisPlot3dResult(xname, yname, x, y, num); } void Polygon::analysisStats(Coord::CoordSystem sys) { ostringstream str; BBox bb(center); Matrix mm = Rotate(angle) * Translate(center); vertex.head(); do bb.bound(vertex.current()->vector * mm); while (vertex.next()); parent->markerAnalysisStats(this, str, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Polygon::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); Matrix mm = fwdMatrix(); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys,sky); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra[16]; char dec[16]; str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; ptr->mapFromRef(vertex.current()->vector*mm,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << ra << ',' << dec; } while (vertex.next()); str << ')'; } break; } } else { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } } } listPost(str, conj, strip); } void Polygon::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); Matrix mm = fwdMatrix(); Vector* vv = new Vector[vertex.count()]; XMLRowInit(); XMLRow(XMLSHAPE,type_); vertex.head(); int cnt =0; do vv[cnt++] =vertex.current()->vector*mm; while (vertex.next()); XMLRowPoint(ptr,sys,sky,format,vv,vertex.count()); delete [] vv; XMLRowProps(ptr,sys); XMLRowEnd(str); } void Polygon::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); Matrix mm = fwdMatrix(); listCiaoPre(str); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector * mm,Coord::PHYSICAL); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } break; default: if (ptr->hasWCSCel(sys)) { char buf[64]; char ra[16]; char dec[16]; str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; ptr->mapFromRef(vertex.current()->vector*mm,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << ra << ',' << dec; } while (vertex.next()); str << ')'; } } listCiaoPost(str, strip); } void Polygon::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); Matrix mm = fwdMatrix(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { coord.listProsCoordSystem(str,sys,sky); str << "; " << type_; vertex.head(); do { Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys); str << setprecision(8) << v; } while (vertex.next()); } break; default: if (ptr->hasWCSCel(sys)) { coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' '; switch (format) { case Coord::DEGREES: { vertex.head(); do { Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys,sky); str << setprecision(8) << v[0] << "d " << v[1] << "d "; } while (vertex.next()); } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra[16]; char dec[16]; vertex.head(); do { ptr->mapFromRef(vertex.current()->vector*mm,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') str << ' ' << ra << ' ' << dec+1; else str << ' ' << ra << ' ' << dec; } while (vertex.next()); } break; } } } listProsPost(str, strip); } void Polygon::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); Matrix mm = fwdMatrix(); listSAOtngPre(str, strip); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,sys,sky); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra[16]; char dec[16]; str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; ptr->mapFromRef(vertex.current()->vector*mm,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << ra << ',' << dec; } while (vertex.next()); str << ')'; } break; } } } listSAOtngPost(str, strip); } void Polygon::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); Matrix mm = fwdMatrix(); str << type_ << '('; int first=1; vertex.head(); do { if (!first) str << ','; first=0; Vector v = ptr->mapFromRef(vertex.current()->vector*mm,Coord::IMAGE); str << setprecision(8) << v[0] << ',' << v[1]; } while (vertex.next()); str << ')'; listSAOimagePost(str, strip); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frmap.C������������������������������������������������������������������������0000644�0001750�0001750�00000006204�11727744315�014544� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "framebase.h" #include "fitsimage.h" double Base::mapAngleFromRef(double angle, Coord::CoordSystem sys, Coord::SkyFrame sky) { double r = angle; FitsImage* ptr = currentContext->cfits; if (!ptr) return 0; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: break; default: switch (ptr->getWCSOrientation(sys,sky)) { case Coord::NORMAL: r = angle + ptr->getWCSRotation(sys,sky); break; case Coord::XX: r = -angle + ptr->getWCSRotation(sys,sky) + M_PI; break; } } return zeroTWOPI(r); } double Base::mapAngleToRef(double angle, Coord::CoordSystem sys, Coord::SkyFrame sky) { double r = angle; FitsImage* ptr = currentContext->cfits; if (!ptr) return 0; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: break; default: switch (ptr->getWCSOrientation(sys,sky)) { case Coord::NORMAL: r = angle - ptr->getWCSRotation(sys,sky); break; case Coord::XX: r = -angle + ptr->getWCSRotation(sys,sky) + M_PI; break; } } return zeroTWOPI(r); } double Base::mapDistFromRef(const Vector& v1, const Vector& v2, Coord::InternalSystem sys) { switch (sys) { case Coord::CANVAS: return (v2*refToCanvas - v1*refToCanvas).length(); case Coord::PANNER: return (v2*refToPanner - v1*refToPanner).length(); } } double Base::mapLenFromRef(double d, Coord::InternalSystem sys) { Vector r = mapLenFromRef(Vector(d,0),sys); return r[0]; } Vector Base::mapLenFromRef(const Vector& v, Coord::InternalSystem sys) { switch (sys) { case Coord::CANVAS: return mapLen(v,refToCanvas); case Coord::PANNER: return mapLen(v,refToPanner); } } double Base::mapLenToRef(double d, Coord::InternalSystem sys) { Vector r = mapLenToRef(Vector(d,0),sys); return r[0]; } Vector Base::mapLenToRef(const Vector& v, Coord::InternalSystem sys) { switch (sys) { case Coord::CANVAS: return mapLen(v,canvasToRef); case Coord::PANNER: return mapLen(v,pannerToRef); } } Vector FrameBase::mapFromRef(const Vector& vv, Coord::InternalSystem sys) { switch (sys) { case Coord::REF: return vv; case Coord::USER: return vv * refToUser; case Coord::WIDGET: return vv * refToWidget; case Coord::CANVAS: return vv * refToCanvas; case Coord::WINDOW: return vv * refToWindow; case Coord::PANNER: return vv * refToPanner; case Coord::MAGNIFIER: return vv * refToMagnifier; } } Vector FrameBase::mapToRef(const Vector& vv, Coord::InternalSystem sys) { switch (sys) { case Coord::REF: return vv; case Coord::USER: return vv * userToRef; case Coord::WIDGET: return vv * widgetToRef; case Coord::CANVAS: return vv * canvasToRef; case Coord::WINDOW: return vv * windowToRef; case Coord::PANNER: return vv * pannerToRef; case Coord::MAGNIFIER: return vv * magnifierToRef; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/proslex.L����������������������������������������������������������������������0000644�0001750�0001750�00000007746�11700666271�015153� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "prosparser.H" extern YYSTYPE* proslval; extern prosFlexLexer* proslexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(proslval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return STRING; } annulus {return ANNULUS_;} b1950 {return B1950_;} box {return BOX_;} circle {return CIRCLE_;} debug {return DEBUG_;} ellipse {return ELLIPSE_;} ecliptic {return ECLIPTIC_;} equatorial {return EQUATORIAL_;} galactic {return GALACTIC_;} j2000 {return J2000_;} logical {return LOGICAL_;} n {return N_;} off {return OFF_;} on {return ON_;} physical {return PHYSICAL_;} point {return POINT_;} polygon {return POLYGON_;} rotbox {return ROTBOX_;} version {return VERSION_;} [+-]?{D}+ { // Integer proslval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number proslval->real = atof(yytext); return REAL; } [+-]?{D}+"."?d | [+-]?{D}*"."{D}+d { // degrees yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ANGDEGREE; } [+-]?{D}+"."?r | [+-]?{D}*"."{D}+r { // radians yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ANGRADIAN; } {D}+"."?' | {D}*"."{D}+' | [+-]?{D}+"."?({E})?' | [+-]?{D}*"."{D}+({E})?' { // minutes of arc yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ARCMINUTE; } {D}+"."?\" | {D}*"."{D}+\" | [+-]?{D}+"."?({E})?\" | [+-]?{D}*"."{D}+({E})?\" { // seconds of arc yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ARCSECOND; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // Sexagesimal int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return SEXSTR; } [+-]?{D}+h{D}+m{D}+"."?s | [+-]?{D}+h{D}+m{D}*"."{D}+s { // HMS int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return HMSSTR; } [+-]?{D}+d{D}+m{D}+"."?s | [+-]?{D}+d{D}+m{D}*"."{D}+s { // DMS int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return DMSSTR; } \"[^\"\n]*\" | \'[^\'\n]*\' { // Quoted String int ll=(yyleng-2)<(PROSBUFSIZE-1)?(yyleng-2):(PROSBUFSIZE-1); strncpy(proslval->str,yytext+1,ll); // skip the " " proslval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}\n]*\} { // Quoted String int ll=(yyleng-2)<(PROSBUFSIZE-1)?(yyleng-2):(PROSBUFSIZE-1); strncpy(proslval->str,yytext+1,ll); // skip the '{' proslval->str[ll] = '\0'; // Remove the '}' return STRING; } [0-9A-Za-z]+ { // General String int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \\n { // fake line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% void prosDiscard(int doit) { if (proslexx) proslexx->begin(DISCARD, doit); } void prosFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ��������������������������./saods9/saotk/frame/framergbtruecolor16.C����������������������������������������������������������0000644�0001750�0001750�00000007322�11700666267�017334� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framergbtruecolor16.h" #include "fitsimage.h" // Tk Canvas Widget Function Declarations int FrameRGBTrueColor16CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameRGBTrueColor16 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameRGBTrueColor16Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "framergb", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameRGBTrueColor16Type = { (char*)"framergbtruecolor16", // name sizeof(WidgetOptions), // item size FrameRGBTrueColor16CreateProc, // configProc frameRGBTrueColor16Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameRGBTrueColor16_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameRGBTrueColor16Type); return TCL_OK; } int FrameRGBTrueColor16CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameRGBTrueColor16* frame = new FrameRGBTrueColor16(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameRGBTrueColor16 Member Functions FrameRGBTrueColor16::FrameRGBTrueColor16(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameRGBTrueColor(i,c,item), TrueColor16(visual) { configSpecs = frameRGBTrueColor16Specs; // frame configure options } FrameRGBTrueColor16::~FrameRGBTrueColor16() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fvcontour.C��������������������������������������������������������������������0000644�0001750�0001750�00000023013�12107012362�015440� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "base.h" #include "fitsimage.h" #include "fvcontour.h" #include "sigbus.h" #define INTERP (((Base*)parent)->interp) // It is a modified version of contour code found in Fv 2.4 // Fv may be obtained from the HEASARC (High Energy Astrophysics Science // Archive Research Center) FTOOLS Web site at: // http://heasarc.gsfc.nasa.gov/ftools/fv.html // The original author is unknown. FVContour::FVContour(Base* pp, FitsImage* fits, const char* cc, int ww, int dd, Method mm, int nn, int rr, const char* ll, FrScale::ColorScaleType sc, float exp, float cm, Vector lim, InverseScale* ss) : Contour(pp, cc, ww, dd) { method_ = mm; level_ = dupstr(ll); numLevel_ = nn; smooth_ = rr; colorScaleType_ = sc; expo_ = exp; clipMode_ = cm; limits_ = lim; scale = ss; append(fits); } FVContour::~FVContour() { if (level_) delete [] level_; if (scale) delete scale; } void FVContour::update(FitsImage* fits) { contours_.deleteAll(); append(fits); } void FVContour::append(FitsImage* fits) { if (smooth_ == 1) unity(fits); else switch (method_) { case SMOOTH: nobin(fits); break; case BLOCK: bin(fits); break; } } void FVContour::unity(FitsImage* fits) { FitsBound* params = fits->getDataParams(((Base*)parent)->currentContext->frScale.scanMode()); long width = fits->width(); long height = fits->height(); // blank img long size = width*height; double* img = new double[size]; if (!img) { internalError("FVContour could not allocate enough memory"); return; } for (long ii=0; ii<size; ii++) img[ii] = FLT_MIN; // fill img SETSIGBUS for(long jj=params->ymin; jj<params->ymax; jj++) { for(long ii=params->xmin; ii<params->xmax; ii++) { long kk = jj*width + ii; double vv = fits->getValueDouble(kk); if (isfinite(vv)) img[kk] = vv; } } CLEARSIGBUS // do contours int status = build(width, height, img, fits->dataToRef); // clean up delete img; if (status) internalError("Unknown FVContour error"); } void FVContour::nobin(FitsImage* fits) { long width = fits->width(); long height = fits->height(); // blank img long size = width*height; double* img = new double[size]; if (!img) { internalError("FVContour could not allocate enough memory"); return; } for (long ii=0; ii<size; ii++) img[ii] = FLT_MIN; // generate kernal int r = smooth_-1; double* kernal = gaussian(r); // convolve convolve(fits,kernal,img,r); // now, do contours int status = build(width, height, img, fits->dataToRef); // cleanup delete kernal; delete img; if (status) internalError("Unknown FVContour error"); } void FVContour::convolve(FitsImage* fits, double* kernal, double* dest, int r) { FitsBound* params = fits->getDataParams(((Base*)parent)->currentContext->frScale.scanMode()); long width = fits->width(); int rr = 2*r+1; SETSIGBUS for (long jj=params->ymin; jj<params->ymax; jj++) { for (long ii=params->xmin; ii<params->xmax; ii++) { long ir = ii-r; long irr = ii+r; long jr = jj-r; long jrr = jj+r; for (long n=jr, nn=0; n<=jrr; n++, nn++) { if (n>=params->ymin && n<params->ymax) { for (long m=ir, mm=0; m<=irr; m++, mm++) { if (m>=params->xmin && m<params->xmax) { double vv = fits->getValueDouble(n*width+m); if (isfinite(vv)) { double kk = kernal[nn*rr+mm]; double* ptr = dest+(jj*width+ii); if (*ptr == FLT_MIN) *ptr = vv*kk; else *ptr += vv*kk; } } } } } } } CLEARSIGBUS } double* FVContour::tophat(int r) { int rr = 2*r+1; int ksz = rr*rr; double* kernal = new double[ksz]; memset(kernal, 0, ksz*sizeof(double)); double kt = 0; for (int yy=-r; yy<=r; yy++) { for (int xx=-r; xx<=r; xx++) { if ((xx*xx + yy*yy) <= r*r) { kernal[(yy+r)*rr+(xx+r)] = 1; kt++; } } } // normalize kernal for (int aa=0; aa<ksz; aa++) kernal[aa] /= kt; return kernal; } double* FVContour::gaussian(int r) { int rr = 2*r+1; int ksz = rr*rr; double sigma = r/2.; double* kernal = new double[ksz]; memset(kernal, 0, ksz*sizeof(double)); double kt = 0; double aa = 1./(sigma*sigma); double cc = 1./(sigma*sigma); for (int yy=-r; yy<=r; yy++) { for (int xx=-r; xx<=r; xx++) { if ((xx*xx + yy*yy) <= r*r) { double vv = exp(-.5*(aa*xx*xx + cc*yy*yy)); kernal[(yy+r)*rr+(xx+r)] = vv; kt += vv; } } } // normalize kernal for (int aa=0; aa<ksz; aa++) kernal[aa] /= kt; return kernal; } void FVContour::bin(FitsImage* fits) { FitsBound* params = fits->getDataParams(((Base*)parent)->currentContext->frScale.scanMode()); long width = fits->width(); long height = fits->height(); int rr = smooth_; long w2 = (long)(width/rr); long h2 = (long)(height/rr); Matrix m = Translate((Vector(-width,-height)/2).floor()) * Scale(1./rr) * Translate((Vector(w2,h2)/2).floor()); Matrix n = m.invert(); double* mm = m.mm(); double* img = new double[w2 * h2]; { for (long jj=0; jj<h2; jj++) for (long ii=0; ii<w2; ii++) img[jj*w2 + ii] = FLT_MIN; } short* count = new short[w2 * h2]; memset(count, 0, w2*h2*sizeof(short)); SETSIGBUS for (long jj=params->ymin; jj<params->ymax; jj++) { for (long ii=params->xmin; ii<params->xmax; ii++) { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx >= 0 && xx < w2 && yy >= 0 && yy < h2) { long kk = (long(yy)*w2 + long(xx)); double v = fits->getValueDouble(jj*width + ii); if (isfinite(v)) { if (count[kk]) img[kk] += v; else img[kk] = v; count[kk]++; } } } } for (long kk=0; kk<w2*h2; kk++) if (count[kk]) img[kk] /= count[kk]; CLEARSIGBUS delete [] count; Matrix w = n * fits->dataToRef; int status = build(w2, h2, img, w); delete [] img; if (status) internalError("Unknown FVContour error"); } int FVContour::build(long xdim, long ydim, double *image, Matrix& mx) { int status = 0; long nelem = xdim*ydim; char* usedGrid = new char[nelem]; if (!usedGrid) return 1; double** rows = new double*[ydim]; if (!rows) return 1; for (long jj=0; jj<ydim; jj++) rows[jj] = image + jj*xdim; for (long c=0; c<scale->size() && !status; c++) { double cntour = scale->level(c); for (long elem=0; elem<nelem; elem++) usedGrid[elem] = 0; // Search outer edge long ii,jj; // Search top for (jj=0, ii=0; ii<xdim-1 && !status; ii++) if (rows[jj][ii]<cntour && cntour<=rows[jj][ii+1]) status = trace(xdim, ydim, cntour, ii, jj, top, rows, usedGrid, mx); // Search right for (jj=0; jj<ydim-1 && !status; jj++) if (rows[jj][ii]<cntour && cntour<=rows[jj+1][ii]) status = trace(xdim, ydim, cntour, ii-1, jj, right, rows, usedGrid, mx); // Search Bottom for (ii--; ii>=0 && !status; ii--) if (rows[jj][ii+1]<cntour && cntour<=rows[jj][ii]) status = trace(xdim, ydim, cntour, ii, jj-1, bottom, rows, usedGrid, mx); // Search Left for (ii=0, jj--; jj>=0 && !status; jj--) if (rows[jj+1][ii]<cntour && cntour<=rows[jj][ii]) status = trace(xdim, ydim, cntour, ii, jj, left, rows, usedGrid, mx); // Search each row of the image for (jj=1; jj<ydim-1 && !status; jj++) for (ii=0; ii<xdim-1 && !status; ii++) if (!usedGrid[jj*xdim + ii] && rows[jj][ii]<cntour && cntour<=rows[jj][ii+1]) status = trace(xdim, ydim, cntour, ii, jj, top, rows, usedGrid, mx); } delete [] usedGrid; delete [] rows; return status; } int FVContour::trace(long xdim, long ydim, double cntr, long xCell, long yCell, int side, double** rows, char* usedGrid, Matrix& mx) { long ii = xCell; long jj = yCell; int origSide = side; int init = 1; int done = (ii<0 || ii>=xdim-1 || jj<0 && jj>=ydim-1); while (!done) { int flag = 0; double a = rows[jj][ii]; double b = rows[jj][ii+1]; double c = rows[jj+1][ii+1]; double d = rows[jj+1][ii]; double X, Y; if (init) { init = 0; switch (side) { case top: X = (cntr-a) / (b-a) + ii; Y = jj; break; case right: X = ii+1; Y = (cntr-b) / (c-b) + jj; break; case bottom: X = (cntr-c) / (d-c) + ii; Y = jj+1; break; case left: X = ii; Y = (cntr-a) / (d-a) + jj; break; } } else { if (side==top) usedGrid[jj*xdim + ii] = 1; do { if (++side == none) side = top; switch (side) { case top: if (a>=cntr && cntr>b) { flag = 1; X = (cntr-a) / (b-a) + ii; Y = jj; jj--; } break; case right: if( b>=cntr && cntr>c ) { flag = 1; X = ii+1; Y = (cntr-b) / (c-b) + jj; ii++; } break; case bottom: if( c>=cntr && cntr>d ) { flag = 1; X = (cntr-d) / (c-d) + ii; Y = jj+1; jj++; } break; case left: if( d>=cntr && cntr>a ) { flag = 1; X = ii; Y = (cntr-a) / (d-a) + jj; ii--; } break; } } while (!flag); if (++side == none) side = top; if (++side == none) side = top; if (ii==xCell && jj==yCell && side==origSide) done = 1; if (ii<0 || ii>=xdim-1 || jj<0 || jj>=ydim-1) done = 1; } contours_.append(new Vertex(Vector(X+.5,Y+.5)*mx)); if (done) contours_.append(new Vertex(DBL_MAX, DBL_MAX)); } return 0; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsanalysis.C�����������������������������������������������������������������0000644�0001750�0001750�00000002035�11700666267�016146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" #include "smooth.h" int FitsImage::smooth() { // radius int r = parent->smoothRadius_; // src double* src = new double[width()*height()]; if (!src) return 0; double* ptr = src; for (long jj=0; jj<height(); jj++) for (long ii=0; ii<width(); ii++, ptr++) *ptr = basedata_->getValueDouble(jj*width()+ii); // dest double* dest = (double*)smooth_->data(); // kernel // create kernel int rr = 2*r+1; double* kernel = new double[rr*rr]; if (!kernel) return 0; memset(kernel, 0, rr*rr*sizeof(double)); switch (smoothFunction_) { case BOXCAR: boxcar(kernel,r); break; case TOPHAT: tophat(kernel,r); break; case GAUSSIAN: gaussian(kernel,r); break; } // convolve convolve(kernel,src,dest,width(),height(),r); // clean up delete [] kernel; delete [] src; return 1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/context.C����������������������������������������������������������������������0000644�0001750�0001750�00000073364�12130626344�015124� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "blt.h" #include "bltVector.h" #include "fitsimage.h" #include "fvcontour.h" #include "alloc.h" #include "allocgz.h" #include "channel.h" #include "mmap.h" #include "mmapincr.h" #include "share.h" #include "sshare.h" #include "socket.h" #include "socketgz.h" #include "var.h" Context::Context() { parent_ = NULL; fits = NULL; cfits = NULL; mosaicCount_ = 0; for (int ii=0; ii<FTY_MAXAXES; ii++) { naxis_[ii] =0; slice_[ii] =1; } mosaicType = Base::NOMOSAIC; mosaicSystem = Coord::WCS; contour = NULL; } Context::~Context() { if (contour) delete contour; } Context::Context(const Context& a) { mosaicCount_ = a.mosaicCount_; for (int ii=0; ii<FTY_MAXAXES; ii++) { naxis_[ii] = a.naxis_[ii]; slice_[ii] = a.slice_[ii]; } mosaicType = a.mosaicType; mosaicSystem = a.mosaicSystem; contour = a.contour; auxcontours = a.auxcontours; frScale = a.frScale; } Context& Context::operator=(const Context& a) { mosaicCount_ = a.mosaicCount_; for (int ii=0; ii<FTY_MAXAXES; ii++) { naxis_[ii] = a.naxis_[ii]; slice_[ii] = a.slice_[ii]; } mosaicType = a.mosaicType; mosaicSystem = a.mosaicSystem; if (contour) delete contour; contour = a.contour; auxcontours = a.auxcontours; frScale = a.frScale; } int Context::fitsCount() { int cnt =1; for (int ii=2; ii<FTY_MAXAXES; ii++) if (naxis_[ii]) cnt *= naxis_[ii]; return mosaicCount_ * cnt; } void Context::clearContour() { if (contour) delete contour; contour = NULL; } void Context::setContour(FVContour* cc) { if (contour) delete contour; contour = cc; } void Context::unload() { FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr->nextSlice(); while (sptr) { FitsImage* stmp = sptr->nextSlice(); delete sptr; sptr = stmp; } FitsImage* tmp = ptr->nextMosaic(); delete ptr; ptr = tmp; } fits = NULL; cfits = NULL; mask.deleteAll(); mosaicCount_ = 0; for (int ii=0; ii<FTY_MAXAXES; ii++) { naxis_[ii] =0; slice_[ii] =1; } mosaicType = Base::NOMOSAIC; mosaicSystem = Coord::WCS; if (contour) delete contour; contour = NULL; auxcontours.deleteAll(); frScale.resetScanMode(); updateClip(&frScale,0); frScale.clearHistequ(); frScale.clearHistogram(); } void Context::updateBin(Base* parent) { if (!fits->isHist()) return; if (DebugPerf) cerr << "updateBin " << endl; // delete any previous slices { FitsImage* ptr = fits->nextSlice(); fits->setNextSlice(NULL); while (ptr) { FitsImage* tmp = ptr->nextSlice(); delete ptr; ptr = tmp; } } // finish bin loadInit(Base::NOMOSAIC,Coord::WCS); for (int ii=0; ii<2; ii++) naxis_[ii] =fits->naxis(ii); // bin data cube int bd = fits->binDepth(); if (bd > 1) { naxis_[2] =1; // first FitsImage* ptr = fits; for (int ii=1; ii<bd; ii++) { FitsImage* next = NULL; next = new FitsImageFitsNextHist(parent, fits, ptr->baseFile(), 1); if (next && next->isValid()) { ptr->setNextSlice(next); ptr = next; naxis_[2]++; } else { if (next) delete next; break; } } } updateBinFileNames(); updateClip(&frScale,1); frScale.clearHistequ(); frScale.clearHistogram(); } void Context::updateBinFileNames() { if (!fits->isHist()) return; char* zcol = (char*)fits->getHistZ(); int bd = fits->binDepth(); if (bd>1 && zcol) { Vector zlim = fits->getHistColMinMax(zcol); double zlen = zlim[1]-zlim[0]; double zdelta = zlen/bd; double zptr = zlim[0]; FitsImage* ptr = fits; for (int ii=0; ii<fits->depth();ii++,ptr=ptr->nextSlice(),zptr+=zdelta) { ostringstream str; str << zcol << ">=" << zptr << '&' << zcol << '<' << zptr+zdelta << ends; ptr->setBinSliceFilter(str.str().c_str()); ptr->updateFileName(); } } else { fits->setBinSliceFilter(NULL); fits->updateFileName(); } } int Context::calcSlice() { int cnt =1; for (int jj=3; jj<FTY_MAXAXES; jj++) { int cc =1; for (int ii=2; ii<jj; ii++) cc *= naxis_[ii]; cnt += (slice_[jj]-1) * cc; } return cnt; } void Context::updateSlice(int id, int ss) { // updateSlice() ranges 1-n if (fits && (ss>0) && (ss<=naxis_[id])) { slice_[id] = ss; int cnt =slice_[2]; for (int jj=3; jj<FTY_MAXAXES; jj++) { int cc =1; for (int ii=2; ii<jj; ii++) cc *= naxis_[ii]; cnt += (slice_[jj]-1) * cc; } cfits = fits; for (int ii=1; ii<cnt; ii++) if (cfits) cfits = cfits->nextSlice(); } updateContours(); } void Context::updateContours() { // update any contours if (contour) contour->update(cfits); } void Context::updateContours(const Matrix& mx) { if (contour) contour->updateCoords(mx); Contour* ptr=auxcontours.head(); while (ptr) { ptr->updateCoords(mx); ptr=ptr->next(); } } void Context::analysis() { FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->analysis(); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } updateClip(&frScale,1); frScale.clearHistequ(); frScale.clearHistogram(); } void Context::updateClip() { updateClip(&frScale, 1); frScale.clearHistequ(); } void Context::updateClip(FrScale* fr, int force) { if (DebugPerf) cerr << "updateClip " << force << endl; // preserve if (fr->preserve() && !force) { // preserve current frscale low/high // update each fits, but don't update frscale FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateClip(fr); sptr->setClip(fr->low(), fr->high()); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } return; } // no fits if (!fits) { if (fr->clipMode() != FrScale::USERCLIP) { fr->setLow(DEFAULTLOW); fr->setHigh(DEFAULTHIGH); } else { fr->setLow(fr->uLow()); fr->setHigh(fr->uHigh()); } return; } // find min/max fr->setMin(DBL_MAX); fr->setMax(-DBL_MAX); fr->setLow(DBL_MAX); fr->setHigh(-DBL_MAX); FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateClip(fr); // find over-all min/max if (fr->min() > sptr->getMinDouble()) fr->setMin(sptr->getMinDouble()); if (fr->max() <= sptr->getMaxDouble()) fr->setMax(sptr->getMaxDouble()); // find low/high if (fr->low() > sptr->getLowDouble()) fr->setLow(sptr->getLowDouble()); if (fr->high() <= sptr->getHighDouble()) fr->setHigh(sptr->getHighDouble()); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } // set global if (fr->clipScope()==FrScale::GLOBAL) { FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->setClip(fr->low(), fr->high()); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } void Context::bltHist(char* xname, char* yname, int num) { if (!fits) return; frScale.histogram(fits,num); double* x = frScale.histogramX(); double* y = frScale.histogramY(); Blt_Vector* xx; Blt_GetVector(parent_->interp, xname, &xx); Blt_ResetVector(xx, x, num, num*sizeof(double), TCL_STATIC); Blt_Vector* yy; Blt_GetVector(parent_->interp, yname, &yy); Blt_ResetVector(yy, y, num, num*sizeof(double), TCL_STATIC); } Vector Context::getClip() { return Vector(frScale.low(), frScale.high()); } Vector Context::getClip(FrScale::ClipMode cm, float ac) { FrScale cl = frScale; cl.setClipMode(cm); cl.setAutoCutPer(ac); updateClip(&cl, 1); // now reset updateClip(&frScale, !frScale.preserve()); return Vector(cl.low(),cl.high()); } int Context::naxes() { for (int ii=FTY_MAXAXES-1; ii>=2; ii--) { if (naxis_[ii]) return ii; } return 2; } int Context::nhdu() { int dd =1; for (int ii=2; ii<FTY_MAXAXES; ii++) if (naxis_[ii]) dd *= naxis_[ii]; return dd; } void Context::loadInit(Base::MosaicType type, Coord::CoordSystem sys) { cfits = fits; mosaicCount_ = 1; for (int ii=0; ii<FTY_MAXAXES; ii++) { naxis_[ii] =0; slice_[ii] =1; } mosaicType = type; mosaicSystem = sys; } int Context::load(Base* parent, Base::MemType which, const char* fn, FitsImage* img, Base::LayerType ll) { if (!img || !img->isValid()) { if (img) delete img; switch (ll) { case Base::IMG: unload(); break; case Base::MASK: break; } return 0; } switch (ll) { case Base::IMG: fits = img; loadInit(Base::NOMOSAIC,Coord::WCS); for (int ii=0; ii<FTY_MAXAXES; ii++) naxis_[ii] = img->naxis(ii); break; case Base::MASK: mask.append(new FitsMask(parent, img, parent->maskColorName, parent->maskMark)); break; } if (img->isHist()) which = Base::HIST; else if (img->isCompress()) which = Base::COMPRESS; FitsImage* ptr = img; for (int ii=1; ii<img->nhdu(); ii++) { FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageFitsNextAlloc(parent, fn, ptr->fitsFile(), ii+1); break; case Base::ALLOCGZ: next = new FitsImageFitsNextAllocGZ(parent, fn, ptr->fitsFile(), ii+1); break; case Base::CHANNEL: next = new FitsImageFitsNextChannel(parent, fn, ptr->fitsFile(), ii+1); break; case Base::MMAP: next = new FitsImageFitsNextMMap(parent, fn, ptr->fitsFile(), ii+1); break; case Base::SMMAP: next = new FitsImageFitsNextSMMap(parent, fn, ptr->fitsFile(), ii+1); break; case Base::MMAPINCR: next = new FitsImageFitsNextMMapIncr(parent, fn, ptr->fitsFile(), ii+1); break; case Base::SHARE: next = new FitsImageFitsNextShare(parent, fn, ptr->fitsFile(), ii+1); break; case Base::SSHARE: next = new FitsImageFitsNextSShare(parent, fn, ptr->fitsFile(), ii+1); break; case Base::SOCKET: next = new FitsImageFitsNextSocket(parent, fn, ptr->fitsFile(), ii+1); break; case Base::SOCKETGZ: next = new FitsImageFitsNextSocketGZ(parent, fn, ptr->fitsFile(), ii+1); break; case Base::VAR: next = new FitsImageFitsNextVar(parent, fn, ptr->fitsFile(), ii+1); break; case Base::HIST: next = new FitsImageFitsNextHist(parent, img, ptr->baseFile(), ii+1); break; case Base::COMPRESS: next = new FitsImageFitsNextCompress(parent, img, ptr->baseFile(), ii+1); break; case Base::PHOTO: next = new FitsImagePhotoCubeNext(parent, fn, ptr->baseFile(), ii+1); break; } if (next && next->isValid()) { ptr->setNextSlice(next); ptr = next; } else { if (next) delete next; break; } } // check to see if img is really a binn'd data cube if (img->isHist() && ll == Base::IMG) updateBinFileNames(); // finish up img->close(); switch (ll) { case Base::IMG: loadFinish(); break; case Base::MASK: loadFinishMask(); break; } return 1; } int Context::loadExtCube(Base* parent, Base::MemType which, const char* fn, FitsImage* img) { if (!img || !img->isValid()) { if (img) delete img; unload(); return 0; } fits = img; loadInit(Base::NOMOSAIC,Coord::WCS); for (int ii=0; ii<2; ii++) naxis_[ii] = img->naxis(ii); naxis_[2] =1; // get the rest FitsImage* ptr = img; while (1) { FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageMosaicNextAlloc(parent, fn, ptr->fitsFile(), FitsFile::NOFLUSH ,1); break; case Base::ALLOCGZ: next = new FitsImageMosaicNextAllocGZ(parent,fn,ptr->fitsFile(), FitsFile::NOFLUSH ,1); break; case Base::CHANNEL: next = new FitsImageMosaicNextChannel(parent,fn,ptr->fitsFile(), FitsFile::NOFLUSH, 1); break; case Base::MMAP: next = new FitsImageMosaicNextMMap(parent, fn, ptr->fitsFile(), 1); break; case Base::MMAPINCR: next = new FitsImageMosaicNextMMapIncr(parent, fn, ptr->fitsFile(), 1); break; case Base::SHARE: next = new FitsImageMosaicNextShare(parent, fn, ptr->fitsFile(), 1); break; case Base::SOCKET: next = new FitsImageMosaicNextSocket(parent, fn,ptr->fitsFile(), FitsFile::FLUSH,1 ); break; case Base::SOCKETGZ: next =new FitsImageMosaicNextSocketGZ(parent,fn,ptr->fitsFile(), FitsFile::FLUSH,1 ); break; case Base::VAR: next = new FitsImageMosaicNextVar(parent, fn, ptr->fitsFile(), 1); break; } if (next && next->isValid() && (next->isImage() || next->isCompress())) { ptr->setNextSlice(next); ptr = next; naxis_[2]++; } else { if (next) delete next; break; } } // fix z params double ff=1-.5; double tt=naxis_[2]+.5; FitsImage* sptr = fits; while (sptr) { sptr->iparams.zmin =ff; sptr->iparams.zmax =tt; sptr->dparams.zmin =ff; sptr->dparams.zmax =tt; sptr->cparams.zmin =ff; sptr->cparams.zmax =tt; sptr = sptr->nextSlice(); } // finish up img->close(); loadFinish(); return 1; } int Context::loadSlice(Base* parent, Base::MemType which, const char* fn, FitsImage* img) { if (!img || !img->isValid()) { if (img) delete img; return 0; } if (fits) { FitsImage* ptr = fits; while (ptr && ptr->nextSlice()) ptr = ptr->nextSlice(); ptr->setNextSlice(img); naxis_[2]++; } else { fits = img; loadInit(Base::NOMOSAIC,Coord::WCS); for (int ii=0; ii<2; ii++) naxis_[ii] = img->naxis(ii); naxis_[2] =1; } // fix z params double ff=1-.5; double tt=naxis_[2]+.5; FitsImage* sptr = fits; while (sptr) { sptr->iparams.zmin =ff; sptr->iparams.zmax =tt; sptr->dparams.zmin =ff; sptr->dparams.zmax =tt; sptr->cparams.zmin =ff; sptr->cparams.zmax =tt; sptr = sptr->nextSlice(); } // finish up img->close(); loadFinish(); return 1; } int Context::loadMosaic(Base* parent, Base::MemType which, const char* fn, FitsImage* img, Base::LayerType ll, Base::MosaicType type, Coord::CoordSystem sys) { if (!img || !img->isValid()) { if (img) delete img; return 0; } switch (ll) { case Base::IMG: if (fits) { FitsImage* ptr = fits; while (ptr && ptr->nextMosaic()) ptr = ptr->nextMosaic(); ptr->setNextMosaic(img); mosaicCount_++; } else { fits = img; loadInit(type,sys); for (int ii=0; ii<FTY_MAXAXES; ii++) naxis_[ii] = img->naxis(ii); } break; case Base::MASK: FitsMask* msk = mask.tail(); if (msk) { FitsImage* mskimg = msk->mask(); while (mskimg && mskimg->nextMosaic()) mskimg = mskimg->nextMosaic(); mskimg->setNextMosaic(img); } else mask.append(new FitsMask(parent, img, parent->maskColorName, parent->maskMark)); break; } switch (mosaicType) { case Base::IRAF: if (!img->processKeywordsIRAF(fits)) return 0; break; case Base::WCSMOSAIC: if (!img->processKeywordsWCS(fits, mosaicSystem)) return 0; break; } if (img->isCompress()) which = Base::COMPRESS; // get the rest of slices FitsImage* sptr = img; for (int ii=1; ii<img->nhdu(); ii++) { FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageFitsNextAlloc(parent, fn, sptr->fitsFile(), ii+1); break; case Base::ALLOCGZ: next = new FitsImageFitsNextAllocGZ(parent, fn, sptr->fitsFile(), ii+1); break; case Base::CHANNEL: next = new FitsImageFitsNextChannel(parent, fn, sptr->fitsFile(), ii+1); break; case Base::MMAP: next = new FitsImageFitsNextMMap(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SMMAP: next = new FitsImageFitsNextSMMap(parent, fn, sptr->fitsFile(), ii+1); break; case Base::MMAPINCR: next = new FitsImageFitsNextMMapIncr(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SHARE: next = new FitsImageFitsNextShare(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SSHARE: next = new FitsImageFitsNextSShare(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SOCKET: next = new FitsImageFitsNextSocket(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SOCKETGZ: next = new FitsImageFitsNextSocketGZ(parent, fn, sptr->fitsFile(), ii+1); break; case Base::VAR: next = new FitsImageFitsNextVar(parent, fn, sptr->fitsFile(), ii+1); break; case Base::COMPRESS: next = new FitsImageFitsNextCompress(parent, img, sptr->baseFile(), ii+1); break; case Base::PHOTO: next = new FitsImagePhotoCubeNext(parent, fn, sptr->baseFile(), ii+1); break; } if (next && next->isValid()) { sptr->setNextSlice(next); sptr = next; switch (mosaicType) { case Base::IRAF: if (!next->processKeywordsIRAF(fits)) return 0; break; case Base::WCSMOSAIC: if (!next->processKeywordsWCS(fits, mosaicSystem)) return 0; break; } } else { if (next) delete next; break; } } // finish up img->close(); switch (ll) { case Base::IMG: loadFinish(); break; case Base::MASK: loadFinishMask(); break; } return 1; } int Context::loadMosaicImage(Base* parent, Base::MemType which, const char* fn, FitsImage* img, Base::LayerType ll, Base::MosaicType type, Coord::CoordSystem sys) { if (!img || !img->isValid()) { if (img) delete img; switch (ll) { case Base::IMG: unload(); break; case Base::MASK: break; } return 0; } switch (ll) { case Base::IMG: fits = img; loadInit(type,sys); for (int ii=0; ii<FTY_MAXAXES; ii++) naxis_[ii] = img->naxis(ii); break; case Base::MASK: mask.append(new FitsMask(parent, img, parent->maskColorName, parent->maskMark)); break; } Base::MemType sav = which; switch (type) { case Base::IRAF: if (!img->processKeywordsIRAF(fits)) { unload(); return 0; } break; case Base::WCSMOSAIC: if (!img->processKeywordsWCS(fits, mosaicSystem)) { unload(); return 0; } break; } // get the rest of slices FitsImage* sptr = img; if (img->isCompress()) which = Base::COMPRESS; for (int ii=1; ii<img->nhdu(); ii++) { FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageFitsNextAlloc(parent, fn, sptr->fitsFile(), ii+1); break; case Base::ALLOCGZ: next = new FitsImageFitsNextAllocGZ(parent, fn, sptr->fitsFile(), ii+1); break; case Base::CHANNEL: next = new FitsImageFitsNextChannel(parent, fn, sptr->fitsFile(), ii+1); break; case Base::MMAP: next = new FitsImageFitsNextMMap(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SMMAP: next = new FitsImageFitsNextSMMap(parent, fn, sptr->fitsFile(), ii+1); break; case Base::MMAPINCR: next = new FitsImageFitsNextMMapIncr(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SHARE: next = new FitsImageFitsNextShare(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SSHARE: next = new FitsImageFitsNextSShare(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SOCKET: next = new FitsImageFitsNextSocket(parent, fn, sptr->fitsFile(), ii+1); break; case Base::SOCKETGZ: next = new FitsImageFitsNextSocketGZ(parent, fn, sptr->fitsFile(), ii+1); break; case Base::VAR: next = new FitsImageFitsNextVar(parent, fn, sptr->fitsFile(), ii+1); break; case Base::COMPRESS: next = new FitsImageFitsNextCompress(parent, img, sptr->baseFile(), ii+1); break; } if (next && next->isValid()) { sptr->setNextSlice(next); sptr = next; switch (type) { case Base::IRAF: if (!next->processKeywordsIRAF(fits)) { unload(); return 0; } break; case Base::WCSMOSAIC: if (!next->processKeywordsWCS(fits, mosaicSystem)) { unload(); return 0; } break; } } else { if (next) delete next; break; } } // get the rest of mosaic FitsImage* ptr = img; while (1) { // restore which which = sav; FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageMosaicNextAlloc(parent, fn, ptr->fitsFile(), FitsFile::NOFLUSH, 1); break; case Base::ALLOCGZ: next = new FitsImageMosaicNextAllocGZ(parent,fn,ptr->fitsFile(), FitsFile::NOFLUSH, 1); break; case Base::CHANNEL: next = new FitsImageMosaicNextChannel(parent,fn,ptr->fitsFile(), FitsFile::NOFLUSH, 1); break; case Base::MMAP: next = new FitsImageMosaicNextMMap(parent, fn, ptr->fitsFile(), 1); break; case Base::MMAPINCR: next = new FitsImageMosaicNextMMapIncr(parent, fn, ptr->fitsFile(), 1); break; case Base::SHARE: next = new FitsImageMosaicNextShare(parent, fn, ptr->fitsFile(), 1); break; case Base::SOCKET: next = new FitsImageMosaicNextSocket(parent, fn,ptr->fitsFile(), FitsFile::FLUSH, 1); break; case Base::SOCKETGZ: next =new FitsImageMosaicNextSocketGZ(parent,fn,ptr->fitsFile(), FitsFile::FLUSH, 1); break; case Base::VAR: next = new FitsImageMosaicNextVar(parent, fn, ptr->fitsFile(), 1); break; } if (next && next->isValid() && (next->isImage() || next->isCompress())) { ptr->setNextMosaic(next); ptr = next; switch (type) { case Base::IRAF: if (!next->processKeywordsIRAF(fits)) { unload(); return 0; } break; case Base::WCSMOSAIC: if (!next->processKeywordsWCS(fits, mosaicSystem)) { unload(); return 0; } break; } if (ll == Base::IMG) mosaicCount_++; if (img->isCompress()) which = Base::COMPRESS; // get rest of slices for (int ii=1; ii<img->nhdu(); ii++) { FitsImage* snext = NULL; switch (which) { case Base::ALLOC: snext = new FitsImageFitsNextAlloc(parent, fn, next->fitsFile(), ii+1); break; case Base::ALLOCGZ: snext = new FitsImageFitsNextAllocGZ(parent, fn, next->fitsFile(),ii+1); break; case Base::CHANNEL: snext = new FitsImageFitsNextChannel(parent, fn, next->fitsFile(),ii+1); break; case Base::MMAP: snext = new FitsImageFitsNextMMap(parent, fn, next->fitsFile(), ii+1); break; case Base::SMMAP: snext = new FitsImageFitsNextSMMap(parent, fn, next->fitsFile(), ii+1); break; case Base::MMAPINCR: snext = new FitsImageFitsNextMMapIncr(parent,fn,next->fitsFile(), ii+1); break; case Base::SHARE: snext = new FitsImageFitsNextShare(parent, fn, next->fitsFile(), ii+1); break; case Base::SSHARE: snext = new FitsImageFitsNextSShare(parent, fn, next->fitsFile(), ii+1); break; case Base::SOCKET: snext = new FitsImageFitsNextSocket(parent, fn, next->fitsFile(), ii+1); break; case Base::SOCKETGZ: snext = new FitsImageFitsNextSocketGZ(parent,fn,next->fitsFile(), ii+1); break; case Base::VAR: snext = new FitsImageFitsNextVar(parent, fn, next->fitsFile(), ii+1); break; case Base::COMPRESS: snext = new FitsImageFitsNextCompress(parent, ptr, next->baseFile(), ii+1); break; } if (snext && snext->isValid()) { next->setNextSlice(snext); next = snext; switch (type) { case Base::IRAF: if (!snext->processKeywordsIRAF(fits)) { unload(); return 0; } break; case Base::WCSMOSAIC: if (!snext->processKeywordsWCS(fits, mosaicSystem)) { unload(); return 0; } break; } } else { if (snext) delete snext; break; } } } else { if (next) delete next; break; } } // finish up img->close(); switch (ll) { case Base::IMG: loadFinish(); break; case Base::MASK: loadFinishMask(); break; } return 1; } int Context::loadMosaicWFPC2(Base* parent, Base::MemType which, const char* fn, FitsImage* img) { if (!img || !img->isValid()) { if (img) delete img; unload(); return 0; } // Its legal, save it fits = img; loadInit(Base::WFPC2,Coord::WCS); // remember in case of compress Base::MemType sav = which; if (img->isCompress()) which = Base::COMPRESS; // get the rest { FitsImage* ptr = fits; for (int i=1; i<4; i++) { FitsImage* next = NULL; switch (which) { case Base::ALLOC: next = new FitsImageFitsNextAlloc(parent, fn, ptr->fitsFile(), 1); break; case Base::ALLOCGZ: next = new FitsImageFitsNextAllocGZ(parent, fn, ptr->fitsFile(), 1); break; case Base::CHANNEL: next = new FitsImageFitsNextChannel(parent, fn, ptr->fitsFile(), 1); break; case Base::MMAP: next = new FitsImageFitsNextMMap(parent, fn, ptr->fitsFile(), 1); break; case Base::MMAPINCR: next = new FitsImageFitsNextMMapIncr(parent, fn, ptr->fitsFile(), 1); break; case Base::SHARE: next = new FitsImageFitsNextShare(parent, fn, ptr->fitsFile(), 1); break; case Base::SOCKET: next = new FitsImageFitsNextSocket(parent, fn, ptr->fitsFile(), 1); break; case Base::SOCKETGZ: next = new FitsImageFitsNextSocketGZ(parent, fn, ptr->fitsFile(), 1); break; case Base::VAR: next = new FitsImageFitsNextVar(parent, fn, ptr->fitsFile(), 1); break; case Base::COMPRESS: next = new FitsImageFitsNextCompress(parent, img, ptr->baseFile(), 1); break; } if (next && next->isValid()) { ptr->setNextMosaic(next); ptr = next; mosaicCount_++; } else { if (next) delete next; break; } } } // restore which which = sav; // ok, do we have 4 images? if (mosaicCount_ != 4) { unload(); return 0; } // now, find WCS table FitsFile* table; switch (which) { case Base::ALLOC: table = new FitsMosaicNextAlloc(fits->fitsFile(), FitsFile::NOFLUSH); break; case Base::ALLOCGZ: table = new FitsMosaicNextAllocGZ(fits->fitsFile(), FitsFile::NOFLUSH); break; case Base::CHANNEL: table = new FitsMosaicNextChannel(fits->fitsFile(), FitsFile::NOFLUSH); break; case Base::MMAP: table = new FitsMosaicNextMMap(fits->fitsFile()); break; case Base::MMAPINCR: table = new FitsMosaicNextMMapIncr(fits->fitsFile()); break; case Base::SHARE: table = new FitsMosaicNextShare(fits->fitsFile()); break; case Base::SOCKET: table = new FitsMosaicNextSocket(fits->fitsFile(), FitsFile::FLUSH); break; case Base::SOCKETGZ: table = new FitsMosaicNextSocketGZ(fits->fitsFile(), FitsFile::FLUSH); break; case Base::VAR: table = new FitsMosaicNextVar(fits->fitsFile()); break; } if (!table || !table->isValid() || !table->isAsciiTable()) { if (table) delete table; unload(); return 0; } // read WCS from table { FitsHead* th = table->head(); if (th->naxes() != 2) { if (table) delete table; unload(); return 0; } FitsTableHDU* thdu = (FitsTableHDU*)th->hdu(); FitsColumn* crval1 = thdu->find("CRVAL1"); FitsColumn* crval2 = thdu->find("CRVAL2"); FitsColumn* crpix1 = thdu->find("CRPIX1"); FitsColumn* crpix2 = thdu->find("CRPIX2"); FitsColumn* cd1_1 = thdu->find("CD1_1"); FitsColumn* cd1_2 = thdu->find("CD1_2"); FitsColumn* cd2_1 = thdu->find("CD2_1"); FitsColumn* cd2_2 = thdu->find("CD2_2"); FitsColumn* ctype1 = thdu->find("CTYPE1"); FitsColumn* ctype2 = thdu->find("CTYPE2"); char* tptr = (char*)table->data(); int rows = thdu->rows(); int rowlen = thdu->width(); if (rows != 4) { unload(); return 0; } FitsImage* ptr = fits; // reset count for processKeyWords() mosaicCount_ =0; for (int i=0; i<rows; i++, tptr+=rowlen) { istringstream istr(ios::in|ios::out); ostream ostr(istr.rdbuf()); ostr << "CRVAL1 = " << crval1->str(tptr) << endl << "CRVAL2 = " << crval2->str(tptr) << endl << "CRPIX1 = " << crpix1->str(tptr) << endl << "CRPIX2 = " << crpix2->str(tptr) << endl << "CD1_1 = " << cd1_1->str(tptr) << endl << "CD1_2 = " << cd1_2->str(tptr) << endl << "CD2_1 = " << cd2_1->str(tptr) << endl << "CD2_2 = " << cd2_2->str(tptr) << endl << "CTYPE1 = " << '\'' << ctype1->str(tptr) << '\'' << endl << "CTYPE2 = " << '\'' << ctype2->str(tptr) << '\'' << endl << ends; FitsHead* r = parent->parseWCS(istr); // fix fitsimage params ptr->replaceWCS(r); ptr->processKeywordsWCS(fits, Coord::WCS); delete r; ptr = ptr->nextMosaic(); mosaicCount_++; } } if (table) delete table; // finish up img->close(); loadFinish(); return 1; } void Context::loadFinish() { FitsImage* ptr = fits; while (ptr && ptr->nextMosaic()) { int jj=0; FitsImage* sptr = ptr; while (sptr) { if (sptr->nextMosaic() == NULL) { // ok, let's figure out next inline FitsImage* mptr = ptr->nextMosaic(); for (int nn=0; nn<jj; nn++) mptr = mptr->nextSlice(); sptr->setNextMosaic(mptr); } jj++; sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } updateClip(&frScale,0); frScale.clearHistequ(); frScale.clearHistogram(); } void Context::loadFinishMask() { // only do last loaded Mask FitsMask* msk = mask.tail(); if (msk) { FitsImage* ptr = msk->mask(); while (ptr && ptr->nextMosaic()) { int jj=0; FitsImage* sptr = ptr; while (sptr) { if (sptr->nextMosaic() == NULL) { // ok, let's figure out next inline FitsImage* mptr = ptr->nextMosaic(); for (int nn=0; nn<jj; nn++) mptr = mptr->nextSlice(); sptr->setNextMosaic(mptr); } jj++; sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue32.h�������������������������������������������������������������0000644�0001750�0001750�00000004611�11700666266�016676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscaletrue32_h__ #define __colorscaletrue32_h__ #include "colorscale.h" #include "truecolor24.h" class ColorScaleTrueColor32 : public virtual ColorScale, public TrueColor24 { public: ColorScaleTrueColor32(int, Visual*, int); virtual ~ColorScaleTrueColor32(); }; class LinearScaleTrueColor32 : public virtual ColorScale, public LinearScale, public ColorScaleTrueColor32 { public: LinearScaleTrueColor32(int, unsigned short*, unsigned char*, int, Visual*, int); }; class LogScaleTrueColor32 : public virtual ColorScale, public LogScale, public ColorScaleTrueColor32 { public: LogScaleTrueColor32(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class PowScaleTrueColor32 : public virtual ColorScale, public PowScale, public ColorScaleTrueColor32 { public: PowScaleTrueColor32(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class SqrtScaleTrueColor32 : public virtual ColorScale, public SqrtScale, public ColorScaleTrueColor32 { public: SqrtScaleTrueColor32(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SquaredScaleTrueColor32 : public virtual ColorScale, public SquaredScale, public ColorScaleTrueColor32 { public: SquaredScaleTrueColor32(int, unsigned short*, unsigned char*, int, Visual*, int); }; class AsinhScaleTrueColor32 : public virtual ColorScale, public AsinhScale, public ColorScaleTrueColor32 { public: AsinhScaleTrueColor32(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SinhScaleTrueColor32 : public virtual ColorScale, public SinhScale, public ColorScaleTrueColor32 { public: SinhScaleTrueColor32(int, unsigned short*, unsigned char*, int, Visual*, int); }; class IISScaleTrueColor32 : public virtual ColorScale, public IISScale, public ColorScaleTrueColor32 { public: IISScaleTrueColor32(unsigned short*, unsigned char*, int, Visual*, int); }; class HistEquScaleTrueColor32 : public virtual ColorScale, public HistEquScale, public ColorScaleTrueColor32 { public: HistEquScaleTrueColor32(int, unsigned short*, unsigned char*, int, double*, int, Visual*, int); }; #endif �����������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergb.C���������������������������������������������������������������������0000644�0001750�0001750�00000103217�12107012362�015205� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framergb.h" #include "fitsimage.h" #include "ps.h" #include "outfile.h" #include "outchannel.h" #include "outsocket.h" #include "sigbus.h" // Frame Member Functions FrameRGB::FrameRGB(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item) { context = new Context[3]; context[0].parent(this); context[1].parent(this); context[2].parent(this); channel = 0; rgbSystem = Coord::WCS; for (int ii=0; ii<3; ii++) { view[ii] = 1; bias[ii] = .5; contrast[ii] = 1.0; colorScale[ii] = NULL; } colorCount = 0; colorCells = NULL; currentContext = &context[channel]; keyContext = &context[channel]; keyContextSet =0; } FrameRGB::~FrameRGB() { if (context) delete [] context; for (int ii=0; ii<3; ii++) { if (colorScale[ii]) delete colorScale[ii]; } if (colorCells) delete [] colorCells; } void FrameRGB::alignWCS() { if (!wcsAlign_ || !(keyContext->fits) || !keyContext->fits->hasWCS(wcsSystem_)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; } else calcAlignWCS(keyContext->fits, wcsSystem_, wcsSky_, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation); updateRGBMatrices(); } void FrameRGB::alignWCS(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!wcsAlign_ || !(keyContext->fits) || !keyContext->fits->hasWCS(sys)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; } else calcAlignWCS(keyContext->fits, sys, sky, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation); updateRGBMatrices(); } void FrameRGB::alignWCS(FitsImage* ptr, Coord::CoordSystem sys) { if (!wcsAlign_ || !(keyContext->fits) || !ptr || !keyContext->fits->hasWCS(wcsSystem_)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; } else calcAlignWCS(ptr, keyContext->fits, wcsSystem_, sys, wcsSky_, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation, &zoom_); updateRGBMatrices(); } int FrameRGB::doRender() { return ((context[0].fits&&view[0]) || (context[1].fits&&view[1]) || (context[2].fits&&view[2])); } unsigned char* FrameRGB::fillImage(int width, int height, Coord::InternalSystem sys) { // img unsigned char* img = new unsigned char[width*height*3]; memset(img,0,width*height*3); // mk char* mk = new char[width*height]; memset(mk,0,width*height); SETSIGBUS // one channel at a time for (int kk=0; kk<3; kk++) { if (!view[kk] || !context[kk].fits) continue; // basics int length = colorScale[kk]->size() - 1; const unsigned char* table = colorScale[kk]->psColors(); FitsImage* sptr = context[kk].cfits; int mosaic = context[kk].isMosaic(); // variable double* mm = sptr->matrixToData(sys).mm(); FitsBound* params = sptr->getDataParams(context[kk].frScale.scanMode()); int srcw = sptr->width(); double ll = sptr->getLowDouble(); double hh = sptr->getHighDouble(); double diff = hh - ll; // main loop unsigned char* dest = img; char* mkptr = mk; for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest+=3, mkptr++) { if (mosaic) { sptr = context[kk].cfits; mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context[kk].frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); if (isfinite(value)) { if (value <= ll) *(dest+kk) = *table; else if (value >= hh) *(dest+kk) = *(table+length); else *(dest+kk) = *(table+((int)(((value - ll)/diff * length) +.5))); *mkptr =2; } else if (*mkptr < 2) *mkptr =1; break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context[kk].frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } } } } while (mosaic && sptr); } } } // now fill in bg { unsigned char* dest = img; char* mkptr = mk; for (int jj=0; jj<height; jj++) for (int ii=0; ii<width; ii++, dest+=3, mkptr++) { if (*mkptr == 2) // good value ; else if (*mkptr == 1) { // nan *dest = (unsigned char)nanColor->red; *(dest+1) = (unsigned char)nanColor->green; *(dest+2) = (unsigned char)nanColor->blue; } else { // bg *dest = (unsigned char)bgColor->red; *(dest+1) = (unsigned char)bgColor->green; *(dest+2) = (unsigned char)bgColor->blue; } } } CLEARSIGBUS // clean up delete [] mk; return img; } BBox FrameRGB::imageBBox(FrScale::ScanMode mode) { // returns imageBBox in IMAGE coords // and extends edge to edge updateRGBMatrices(); BBox rr; int first=1; for (int ii=0; ii<3; ii++) { if (context[ii].fits) { FitsImage* ptr = context[ii].fits; while (ptr) { FitsBound* params = ptr->getDataParams(mode); Matrix mm = ptr->wcsToRef * rgb[ii] * dataToImage; Vector aa = Vector(params->xmin,params->ymin) * mm; if (first) { rr = BBox(aa,aa); first = 0; } else rr.bound(aa); rr.bound(Vector(params->xmax,params->ymin) * mm); rr.bound(Vector(params->xmax,params->ymax) * mm); rr.bound(Vector(params->xmin,params->ymax) * mm); ptr = ptr->nextMosaic(); } } } return rr; } void FrameRGB::loadRGBCube(MemType which, const char* fn, FitsImage* img) { if (!img || !img->isValid() || !(img->isImage() || img->isCompress()) || (img->depth() != 3)) goto error; context[0].fits = img; if (img->isCompress()) which = COMPRESS; switch (which) { case ALLOC: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextAlloc(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextAlloc(this, fn, context[1].fits->fitsFile(),3); break; case ALLOCGZ: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextAllocGZ(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextAllocGZ(this, fn, context[1].fits->fitsFile(),3); break; case CHANNEL: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextChannel(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextChannel(this, fn, context[1].fits->fitsFile(),3); break; case MMAP: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextMMap(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextMMap(this, fn, context[1].fits->fitsFile(),3); break; case SMMAP: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextSMMap(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextSMMap(this, fn, context[1].fits->fitsFile(),3); break; case MMAPINCR: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextMMapIncr(this, fn,context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextMMapIncr(this, fn,context[1].fits->fitsFile(),3); break; case SHARE: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextShare(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextShare(this, fn, context[1].fits->fitsFile(),3); break; case SSHARE: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextSShare(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextSShare(this, fn, context[1].fits->fitsFile(),3); break; case SOCKET: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextSocket(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextSocket(this, fn, context[1].fits->fitsFile(),3); break; case SOCKETGZ: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextSocketGZ(this, fn,context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextSocketGZ(this, fn,context[1].fits->fitsFile(),3); break; case VAR: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextVar(this, fn, context[0].fits->fitsFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextVar(this, fn, context[1].fits->fitsFile(),3); break; case COMPRESS: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImageFitsNextCompress(this, img,context[0].fits->baseFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImageFitsNextCompress(this, img,context[1].fits->baseFile(),3); break; case PHOTO: if (context[0].fits && context[0].fits->isValid()) context[1].fits = new FitsImagePhotoCubeNext(this, fn, context[0].fits->baseFile(),2); if (context[1].fits && context[1].fits->isValid()) context[2].fits = new FitsImagePhotoCubeNext(this, fn, context[1].fits->baseFile(),3); break; } // is everything ok? if (context[0].fits && context[0].fits->isValid() && (context[0].fits->isImage() || context[0].fits->isCompress()) && context[1].fits && context[1].fits->isValid() && (context[1].fits->isImage() || context[1].fits->isCompress()) && context[2].fits && context[2].fits->isValid() && (context[2].fits->isImage() || context[2].fits->isCompress())) { loadRGBFinish(); return; } error: context[0].unload(); context[1].unload(); context[2].unload(); reset(); updateColorScale(); Tcl_AppendResult(interp, "Unable to load rgb cube file", NULL); result = TCL_ERROR; return; } void FrameRGB::loadRGBImage(MemType which, const char* fn, FitsImage* img) { FitsImage* r = img; FitsImage* g = NULL; FitsImage* b = NULL; if (!img || !img->isValid() || !(img->isImage() || img->isCompress())) goto error; switch (which) { case ALLOC: if (r && r->isValid()) g = new FitsImageMosaicNextAlloc(this, fn, r->fitsFile(), FitsFile::NOFLUSH,1); if (g && g->isValid()) b = new FitsImageMosaicNextAlloc(this, fn, g->fitsFile(), FitsFile::NOFLUSH,1); break; case ALLOCGZ: if (r && r->isValid()) g = new FitsImageMosaicNextAllocGZ(this,fn,r->fitsFile(), FitsFile::NOFLUSH,1); if (g && g->isValid()) b = new FitsImageMosaicNextAllocGZ(this,fn,g->fitsFile(), FitsFile::NOFLUSH,1); break; case CHANNEL: if (r && r->isValid()) g = new FitsImageMosaicNextChannel(this,fn,r->fitsFile(), FitsFile::NOFLUSH,1); if (g && g->isValid()) b = new FitsImageMosaicNextChannel(this,fn,g->fitsFile(), FitsFile::NOFLUSH,1); break; case MMAP: if (r && r->isValid()) g = new FitsImageMosaicNextMMap(this, fn, r->fitsFile(),1); if (g && g->isValid()) b = new FitsImageMosaicNextMMap(this, fn, g->fitsFile(),1); break; case MMAPINCR: if (r && r->isValid()) g = new FitsImageMosaicNextMMapIncr(this, fn, r->fitsFile(),1); if (g && g->isValid()) b = new FitsImageMosaicNextMMapIncr(this, fn, g->fitsFile(),1); break; case SHARE: if (r && r->isValid()) g = new FitsImageMosaicNextShare(this,fn, r->fitsFile(),1); if (g && g->isValid()) b = new FitsImageMosaicNextShare(this,fn, g->fitsFile(),1); break; case SOCKET: if (r && r->isValid()) g = new FitsImageMosaicNextSocket(this,fn,r->fitsFile(), FitsFile::FLUSH,1); if (g && g->isValid()) b = new FitsImageMosaicNextSocket(this,fn,g->fitsFile(), FitsFile::FLUSH,1); break; case SOCKETGZ: if (r && r->isValid()) g = new FitsImageMosaicNextSocketGZ(this,fn,r->fitsFile(), FitsFile::FLUSH,1); if (g && g->isValid()) b = new FitsImageMosaicNextSocketGZ(this,fn,g->fitsFile(), FitsFile::FLUSH,1); break; case VAR: if (r && r->isValid()) g = new FitsImageMosaicNextVar(this, fn, r->fitsFile(),1); if (g && g->isValid()) b = new FitsImageMosaicNextVar(this, fn, g->fitsFile(),1); break; } // ok, figure out which is which channel context[0].fits = context[1].fits = context[2].fits = NULL; { const char* ext = r->fitsFile()->extname(); if (ext) { if (!strncmp(ext,"RED",3)) context[0].fits = r; else if (!strncmp(ext,"GREEN",3)) context[1].fits = r; else if (!strncmp(ext,"BLUE",3)) context[2].fits = r; else context[0].fits = r; } else context[0].fits = r; } { const char* ext = g->fitsFile()->extname(); if (ext) { if (!strncmp(ext,"RED",3)) context[0].fits = g; else if (!strncmp(ext,"GREEN",3)) context[1].fits = g; else if (!strncmp(ext,"BLUE",3)) context[2].fits = g; else context[1].fits = g; } else context[1].fits = g; } { const char* ext = b->fitsFile()->extname(); if (ext) { if (!strncmp(ext,"RED",3)) context[0].fits = b; else if (!strncmp(ext,"GREEN",3)) context[1].fits = b; else if (!strncmp(ext,"BLUE",3)) context[2].fits = b; else context[2].fits = b; } else context[2].fits = b; } // is everything ok? if (context[0].fits && context[0].fits->isValid() && (context[0].fits->isImage() || context[0].fits->isCompress()) && context[1].fits && context[1].fits->isValid() && (context[1].fits->isImage() || context[1].fits->isCompress()) && context[2].fits && context[2].fits->isValid() && (context[2].fits->isImage() || context[2].fits->isCompress())) { loadRGBFinish(); return; } error: context[0].unload(); context[1].unload(); context[2].unload(); reset(); updateColorScale(); Tcl_AppendResult(interp, "Unable to load rgb image file", NULL); result = TCL_ERROR; return; } void FrameRGB::loadRGBFinish() { for (int ii=0; ii<3; ii++) { context[ii].loadInit(NOMOSAIC,Coord::WCS); context[ii].loadFinish(); } channel = 0; currentContext = &context[channel]; keyContext = &context[channel]; keyContextSet =1; alignWCS(); if (!preservePan) { centerImage(); // cursor is in REF, crosshair in REF crosshair = cursor; } updateColorScale(); update(MATRIX); } void FrameRGB::pushMatrices() { for (int ii=0; ii<3; ii++) { FitsImage* ptr = context[ii].fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMatrices(rgb[ii], refToWidget, widgetToCanvas); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } void FrameRGB::pushMagnifierMatrices() { for (int ii=0; ii<3; ii++) { FitsImage* ptr = context[ii].fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMagnifierMatrices(refToMagnifier); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } void FrameRGB::pushPannerMatrices() { for (int ii=0; ii<3; ii++) { FitsImage* ptr = context[ii].fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updatePannerMatrices(refToPanner); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } void FrameRGB::pushPSMatrices(float scale, int width, int height) { Matrix mx = psMatrix(scale, width, height); for (int kk=0; kk<3; kk++) if (context[kk].fits) { FitsImage* ptr = context[kk].cfits; while (ptr) { ptr->updatePS(mx); ptr = ptr->nextMosaic(); } } } void FrameRGB::reset() { for (int ii=0; ii<3; ii++) { bias[ii] = 0.5; contrast[ii] = 1.0; context[ii].frScale.resetScanMode(); context[ii].updateClip(); } Base::reset(); } void FrameRGB::rgbAlignWCS(int ii) { if (keyContext->fits && keyContext->fits->hasWCS(rgbSystem)) rgb[ii] = calcAlignWCS(keyContext->fits, context[ii].fits, rgbSystem, rgbSystem, Coord::FK5); if (DebugRGB) cerr << "rgbAlignWCS " << rgb[ii] << endl; } void FrameRGB::saveFitsRGBImageFileCmd(const char* fn) { if (keyContext->fits) { OutFitsFile str(fn); saveFitsRGBImage(str); } } void FrameRGB::saveFitsRGBImageChannelCmd(const char* ch) { if (keyContext->fits) { OutFitsChannel str(interp, ch); saveFitsRGBImage(str); } } void FrameRGB::saveFitsRGBImageSocketCmd(int ss) { if (keyContext->fits) { OutFitsSocket str(ss); saveFitsRGBImage(str); } } void FrameRGB::saveFitsRGBCubeFileCmd(const char* fn) { if (keyContext->fits) { OutFitsFile str(fn); saveFitsRGBCube(str); } } void FrameRGB::saveFitsRGBCubeChannelCmd(const char* ch) { if (keyContext->fits) { OutFitsChannel str(interp, ch); saveFitsRGBCube(str); } } void FrameRGB::saveFitsRGBCubeSocketCmd(int ss) { if (keyContext->fits) { OutFitsSocket str(ss); saveFitsRGBCube(str); } } void FrameRGB::saveArrayRGBCubeFileCmd(const char* fn, FitsFile::ArchType endian) { if (keyContext->fits) { OutFitsFile str(fn); saveArrayRGBCube(str, endian); } } void FrameRGB::saveArrayRGBCubeChannelCmd(const char* ch, FitsFile::ArchType endian) { if (keyContext->fits) { OutFitsChannel str(interp, ch); saveArrayRGBCube(str, endian); } } void FrameRGB::saveArrayRGBCubeSocketCmd(int ss, FitsFile::ArchType endian) { if (keyContext->fits) { OutFitsSocket str(ss); saveArrayRGBCube(str, endian); } } void FrameRGB::savePhotoCmd(const char* ph) { // need to determine size from key context FitsImage* fits = keyContext->fits; if (!fits) return; // check size FitsBound* params = fits->getDataParams(context->frScale.scanMode()); for (int kk=0; kk<3; kk++) { if (!view[kk] || !context[kk].fits) continue; FitsImage* ptr = context[kk].fits; FitsBound* pptr = ptr->getDataParams(context[kk].frScale.scanMode()); if (params->xmin != pptr->xmin || params->xmax != pptr->xmax || params->ymin != pptr->ymin || params->ymax != pptr->ymax) { internalError("All channels need to be same size."); return; } } // width,height int width = params->xmax - params->xmin; int height = params->ymax - params->ymin; // photo if (*ph == '\0') { Tcl_AppendResult(interp, "bad image name ", NULL); return; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, ph); if (!photo) { Tcl_AppendResult(interp, "bad image handle ", NULL); return; } if (Tk_PhotoSetSize(interp, photo, width, height) != TCL_OK) { Tcl_AppendResult(interp, "bad photo set size ", NULL); return; } Tk_PhotoBlank(photo); Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block ", NULL); return; } if (block.pixelSize<4) { Tcl_AppendResult(interp, "bad pixel size ", NULL); return; } // clear, set alpha channel unsigned char* dest = block.pixelPtr; for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest+=block.pixelSize) { *(dest+block.offset[0]) = 0; // red *(dest+block.offset[1]) = 0; // green *(dest+block.offset[2]) = 0; // blue *(dest+block.offset[3]) = 255; // alpha } } // main loop SETSIGBUS // one channel at a time for (int kk=0; kk<3; kk++) { if (!view[kk] || !context[kk].fits) continue; // basics int length = colorScale[kk]->size() - 1; const unsigned char* table = colorScale[kk]->psColors(); // variable FitsImage* fits = context[kk].cfits; double ll = fits->getLowDouble(); double hh = fits->getHighDouble(); double diff = hh - ll; unsigned char* dest = block.pixelPtr; for (long jj=params->ymax-1; jj>=params->ymin; jj--) { for (long ii=params->xmin; ii<params->xmax; ii++, dest+=block.pixelSize) { double value = fits->getValueDouble(Vector(ii,jj)); if (isfinite(value)) { if (value <= ll) *(dest+block.offset[kk]) = table[0]; else if (value >= hh) *(dest+block.offset[kk]) = table[length]; else *(dest+block.offset[kk]) = table[(int)(((value - ll)/diff * length) + .5)]; } } } } CLEARSIGBUS if (Tk_PhotoPutBlock(interp, photo, &block, 0, 0, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { Tcl_AppendResult(interp, "bad put block ", NULL); return; } } void FrameRGB::setBinCursor() { for (int ii=0; ii<3; ii++) if (context[ii].fits) context[ii].fits->setBinCursor(cursor); } void FrameRGB::updateColorCells(unsigned char* cells, int cnt) { if (DebugRGB) cerr << "updateColorCells" << endl; // the colorbar widget will pass us a pointer to the indexCells colorCount = cnt; // copy the rgb vales to the colorCells array (for postscript printing) if (colorCells) delete [] colorCells; colorCells = new unsigned char[cnt*3]; if (!colorCells) { internalError("Unable to Alloc colorCells"); return; } memcpy(colorCells, cells, cnt*3); } void FrameRGB::updateColorScale() { // we need colors before we can construct a scale if (!colorCells) return; if (DebugRGB) cerr << "updateColorScale" << endl; for (int ii=0; ii<3; ii++) { if (colorScale[ii]) delete colorScale[ii]; switch (context[ii].frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale[ii] = new LinearScaleRGB(ii, colorCount, colorCells, colorCount); break; case FrScale::LOGSCALE: colorScale[ii] = new LogScaleRGB(ii, SCALESIZE, colorCells, colorCount, context[ii].frScale.expo()); break; case FrScale::POWSCALE: colorScale[ii] = new PowScaleRGB(ii, SCALESIZE, colorCells, colorCount, context[ii].frScale.expo()); break; case FrScale::SQRTSCALE: colorScale[ii] = new SqrtScaleRGB(ii, SCALESIZE, colorCells, colorCount); break; case FrScale::SQUAREDSCALE: colorScale[ii] = new SquaredScaleRGB(ii, SCALESIZE, colorCells, colorCount); break; case FrScale::ASINHSCALE: colorScale[ii] = new AsinhScaleRGB(ii, SCALESIZE, colorCells, colorCount); break; case FrScale::SINHSCALE: colorScale[ii] = new SinhScaleRGB(ii, SCALESIZE, colorCells, colorCount); break; case FrScale::HISTEQUSCALE: colorScale[ii] = new HistEquScaleRGB(ii, SCALESIZE, colorCells, colorCount, context[ii].histequ(), HISTEQUSIZE); break; } } } void FrameRGB::updateRGBMatrices() { // image,pysical,amplifier,detector are ok, check for wcs if (rgbSystem >= Coord::WCS) { for (int ii=0; ii<3; ii++) { if (context[ii].fits && !context[ii].fits->hasWCS(rgbSystem)) { // ok, don't have requested coordinate system // down grade to image rgbSystem = Coord::IMAGE; break; } } } // rgb align for (int ii=0; ii<3; ii++) { rgb[ii].identity(); if (context[ii].fits && keyContext->fits) { switch (rgbSystem) { case Coord::IMAGE: // nothing to do here break; case Coord::PHYSICAL: if (context[ii].fits != keyContext->fits) rgb[ii] = context[ii].fits->imageToPhysical * keyContext->fits->physicalToImage; break; case Coord::AMPLIFIER: if (context[ii].fits != keyContext->fits) rgb[ii] = context[ii].fits->imageToAmplifier * keyContext->fits->amplifierToImage; break; case Coord::DETECTOR: if (context[ii].fits != keyContext->fits) rgb[ii] = context[ii].fits->imageToDetector * keyContext->fits->detectorToImage; break; default: rgbAlignWCS(ii); break; } } if (DebugRGB) cerr << "rgb[" << ii << "] " << rgb[ii] << endl; } } void FrameRGB::unloadAllFits() { if (DebugPerf) cerr << "Frame::RGBunloadAllFits" << endl; for (int ii=0; ii<3; ii++) { rgb[ii].identity(); context[ii].unload(); // always (for HISTEQU and LOG) updateColorScale(); } channel =0; currentContext = &context[channel]; keyContext = &context[channel]; keyContextSet =0; FrameBase::unloadFits(); } void FrameRGB::unloadFits() { if (DebugPerf) cerr << "FrameRGB::unloadFits" << endl; rgb[channel].identity(); context[channel].unload(); // always (for HISTEQU and LOG) updateColorScale(); } // Commands void FrameRGB::getColorbarCmd() { ostringstream str; str << "rgb " << setiosflags(ios::fixed); for (int ii=0; ii<3; ii++) str << bias[ii] << ' '; for (int ii=0; ii<3; ii++) str << contrast[ii] << ' '; str << invert << ' ' << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void FrameRGB::getInfoCmd(const Vector& vv, Coord::InternalSystem ref, char* var) { FrameBase::getInfoCmd(vv, ref, var); if (!currentContext->cfits) return; char* array[3] = {"value,red","value,green","value,blue"}; SETSIGBUS for (int ii=0; ii<3; ii++) { // make sure we have an image FitsImage* sptr = context[ii].cfits; if (!sptr) continue; int mosaic = context[ii].isMosaic(); FitsBound* params = sptr->getDataParams(context[ii].frScale.scanMode()); do { Vector3d rr = mapToRef3d(vv,ref); Vector img = Vector(rr) * sptr->refToData; if (img[0]>=params->xmin && img[0]<params->xmax && img[1]>=params->ymin && img[1]<params->ymax) { Tcl_SetVar2(interp,var,array[ii],(char*)sptr->getValue(img),0); break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) params = sptr->getDataParams(context[ii].frScale.scanMode()); } } } while (mosaic && sptr); } CLEARSIGBUS } void FrameRGB::getRGBChannelCmd() { switch (channel) { case 0: Tcl_AppendResult(interp, "red", NULL); return; case 1: Tcl_AppendResult(interp, "green", NULL); return; case 2: Tcl_AppendResult(interp, "blue", NULL); return; } } void FrameRGB::getRGBSystemCmd() { printCoordSystem(rgbSystem); } void FrameRGB::getRGBViewCmd() { for (int ii=0; ii<3; ii++) Tcl_AppendElement(interp, view[ii] ? "1" : "0"); } void FrameRGB::getTypeCmd() { Tcl_AppendResult(interp, "rgb", NULL); } void FrameRGB::loadPhotoCmd(const char* ph, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImagePhotoCube(this, interp, ph, fn, 1); loadRGBCube(ALLOC,fn,img); } void FrameRGB::loadRGBCubeAllocCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(ALLOC,fn,img); } void FrameRGB::loadRGBCubeAllocGZCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(ALLOCGZ,fn,img); } void FrameRGB::loadRGBCubeChannelCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(CHANNEL,fn,img); } void FrameRGB::loadRGBCubeMMapCmd(const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadRGBCube(MMAP,fn,img); } void FrameRGB::loadRGBCubeSMMapCmd(const char* hdr, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsSMMap(this, hdr, fn, 1); setScanModeIncr(lm); loadRGBCube(SMMAP,fn,img); } void FrameRGB::loadRGBCubeMMapIncrCmd(const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadRGBCube(MMAPINCR,fn,img); } void FrameRGB::loadRGBCubeShareCmd(ShmType type, int id, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsShare(this, type, id, fn, 1); setScanModeIncr(lm); loadRGBCube(SHARE,fn,img); } void FrameRGB::loadRGBCubeSShareCmd(ShmType type, int hdr, int id, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsSShare(this, type, hdr, id, fn, 1); setScanModeIncr(lm); loadRGBCube(SSHARE,fn,img); } void FrameRGB::loadRGBCubeSocketCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::FLUSH, 1); loadRGBCube(SOCKET,fn,img); } void FrameRGB::loadRGBCubeSocketGZCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadRGBCube(SOCKETGZ,fn,img); } void FrameRGB::loadRGBCubeVarCmd(const char* ch, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadRGBCube(VAR,fn,img); } void FrameRGB::loadRGBImageAllocCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageMosaicAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBImage(ALLOC,fn,img); } void FrameRGB::loadRGBImageAllocGZCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageMosaicAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBImage(ALLOCGZ,fn,img); } void FrameRGB::loadRGBImageChannelCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageMosaicChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadRGBImage(CHANNEL,fn,img); } void FrameRGB::loadRGBImageMMapCmd(const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageMosaicMMap(this, fn, 1); setScanModeIncr(lm); loadRGBImage(MMAP,fn,img); } void FrameRGB::loadRGBImageMMapIncrCmd(const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageMosaicMMapIncr(this, fn, 1); setScanModeIncr(lm); loadRGBImage(MMAPINCR,fn,img); } void FrameRGB::loadRGBImageShareCmd(ShmType type, int id, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageMosaicShare(this, type, id, fn, 1); setScanModeIncr(lm); loadRGBImage(SHARE,fn,img); } void FrameRGB::loadRGBImageSocketCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageMosaicSocket(this, s, fn, FitsFile::FLUSH, 1); loadRGBImage(SOCKET,fn,img); } void FrameRGB::loadRGBImageSocketGZCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageMosaicSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadRGBImage(SOCKETGZ,fn,img); } void FrameRGB::loadRGBImageVarCmd(const char* ch, const char* fn, LoadMethod lm) { unloadAllFits(); FitsImage* img = new FitsImageMosaicVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadRGBImage(VAR,fn,img); } void FrameRGB::loadArrayRGBCubeAllocCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(ALLOC,fn,img); } void FrameRGB::loadArrayRGBCubeAllocGZCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(ALLOCGZ,fn,img); } void FrameRGB::loadArrayRGBCubeChannelCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadRGBCube(CHANNEL,fn,img); } void FrameRGB::loadArrayRGBCubeMMapCmd(const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrMMap(this, fn, 1); loadRGBCube(MMAP,fn,img); } void FrameRGB::loadArrayRGBCubeMMapIncrCmd(const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrMMapIncr(this, fn, 1); loadRGBCube(MMAPINCR,fn,img); } void FrameRGB::loadArrayRGBCubeShareCmd(ShmType type, int id, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrShare(this, type, id, fn, 1); loadRGBCube(SHARE,fn,img); } void FrameRGB::loadArrayRGBCubeSocketCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrSocket(this, s, fn, FitsFile::FLUSH, 1); loadRGBCube(SOCKET,fn,img); } void FrameRGB::loadArrayRGBCubeSocketGZCmd(int s, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadRGBCube(SOCKETGZ,fn,img); } void FrameRGB::loadArrayRGBCubeVarCmd(const char* ch, const char* fn) { unloadAllFits(); FitsImage* img = new FitsImageArrVar(this, interp, ch, fn, 1); loadRGBCube(VAR,fn,img); } void FrameRGB::setRGBChannelCmd(const char* c) { if (!strncmp(c,"red",3)) channel = 0; else if (!strncmp(c,"gre",3)) channel = 1; else if (!strncmp(c,"blu",3)) channel = 2; else channel = 0; currentContext = &context[channel]; // execute any update callbacks updateCBMarkers(); // always update update(BASE); } void FrameRGB::setRGBSystemCmd(Coord::CoordSystem sys) { rgbSystem = sys; // save current matrix Matrix old[3]; for (int ii=0; ii<3; ii++) old[ii] = rgb[ii]; alignWCS(); // fix any contours for(int ii=0; ii<3; ii++) if (context[ii].contour) { Matrix mm = old[ii].invert() * rgb[ii]; context[ii].contour->updateCoords(mm); } update(MATRIX); } void FrameRGB::setRGBViewCmd(int r, int g, int b) { view[0] = r ? 1 : 0; view[1] = g ? 1 : 0; view[2] = b ? 1 : 0; update(BASE); // always update } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frcommand.C��������������������������������������������������������������������0000644�0001750�0001750�00000024537�12102520405�015372� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <fstream> #include "fdstream.hpp" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "framebase.h" #include "fitsimage.h" #include "context.h" #include "marker.h" #include "outfile.h" #include "outchannel.h" #include "outsocket.h" #include "sigbus.h" void FrameBase::binToFitCmd() { if (currentContext->fits) { double bf = 1/calcZoom(currentContext->fits->getHistDim(), Vector(options->width,options->height)); // round up to next power of 2 if (bf < 1) { currentContext->fits->setBinToFactor(Vector(1,1)); binFactor_ = Vector(1,1); } else { int p=1; while (p<bf) p*=2; currentContext->fits->setBinToFactor(Vector(p,p)); binFactor_ = Vector(p,p); } updateBin(currentContext->cfits->updateHistCursor()); } } void FrameBase::get3dBorderCmd() { Tcl_AppendResult(interp, "1", NULL); } void FrameBase::get3dBorderColorCmd() { Tcl_AppendResult(interp, "blue", NULL); } void FrameBase::get3dCompassCmd() { Tcl_AppendResult(interp, "1", NULL); } void FrameBase::get3dCompassColorCmd() { Tcl_AppendResult(interp, "green", NULL); } void FrameBase::get3dHighliteCmd() { Tcl_AppendResult(interp, "1", NULL); } void FrameBase::get3dHighliteColorCmd() { Tcl_AppendResult(interp, "cyan", NULL); } void FrameBase::get3dRenderMethodCmd() { Tcl_AppendResult(interp, "mip", NULL); } void FrameBase::get3dScaleCmd() { Tcl_AppendResult(interp, "1", NULL); } void FrameBase::get3dViewCmd() { Tcl_AppendResult(interp, "0 0", NULL); } void FrameBase::get3dViewPointCmd() { Tcl_AppendResult(interp, "0 0 0 0 0", NULL); } void FrameBase::getCursorCmd(Coord::InternalSystem sys) { printVector(mapFromRef(cursor,sys), DEFAULT); } void FrameBase::getCursorCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Precision pp) { if (currentContext->cfits) printFromRef(currentContext->cfits, cursor, sys, sky, format, pp); else printVector(Vector(), DEFAULT); } void FrameBase::gridCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Grid::GridType type, const char* ops, const char* vars) { if (grid) delete grid; grid = new Grid2d(this, sys, sky, format, type, ops, vars); update(PIXMAP); } void FrameBase::iisCursorModeCmd(int state) { if (state) { // save cursor pos Window root, child; int rootx,rooty,winx,winy; unsigned int msk; XQueryPointer(display,Tk_WindowId(tkwin),&root,&child, &rootx,&rooty,&winx,&winy,&msk); if (!iisInteractive) { iisSaveRoot = root; iisSaveCursor = Vector(rootx,rooty); } iisInteractive++; // set iisLastCursor if first time thru if (iisLastCursor[0] == 0 && iisLastCursor[1] == 0) iisLastCursor = Vector(options->width,options->height)/2; // and move to last cursor position Vector r = iisLastCursor * widgetToWindow; XWarpPointer(display, None,Tk_WindowId(tkwin),0,0,0,0,(int)r[0],(int)r[1]); } else { // restore cursor pos if (!(--iisInteractive)) { XWarpPointer(display, None, iisSaveRoot, 0, 0, 0, 0, (int)iisSaveCursor[0], (int)iisSaveCursor[1]); iisSaveRoot = 0; iisSaveCursor = Vector(); } } } void FrameBase::iisGetCursorCmd() { printVector(iisLastCursor,DEFAULT); } void FrameBase::iisGetFileNameCmd() { FitsImage* ptr = currentContext->fits; while (ptr && ptr->nextMosaic()) ptr = ptr->nextMosaic(); if (ptr) Tcl_AppendResult(interp, ptr->iisGetFileName(), NULL); } void FrameBase::iisGetFileNameCmd(int which) { FitsImage* ptr = currentContext->fits; for (int i=0; i<(which-1); i++) { if (ptr) ptr = ptr->nextMosaic(); } if (ptr) Tcl_AppendResult(interp, ptr->iisGetFileName(), NULL); } void FrameBase::iisGetFileNameCmd(const Vector& vv) { if (FitsImage* ptr = isInCFits(vv, Coord::CANVAS, NULL)) Tcl_AppendResult(interp, ptr->iisGetFileName(), NULL); } void FrameBase::iisMessageCmd(const char* ptr) { if (!currentContext->cfits) return; // do we have something? if (!(ptr && *ptr)) return; // filename // note: the file name is the second value passed char fn[PATH_MAX]; string x(ptr); istringstream str(x); str >> fn >> fn; currentContext->cfits->setFileName(fn); // object name // first go to end char* sptr = (char*)ptr; while (*sptr) sptr++; // now work backwards to last '-' while (sptr != ptr) { if (*sptr == '-') break; sptr--; } // is it good? if (sptr != ptr) { // go forward 2 sptr += 2; currentContext->cfits->setObjectName(sptr); } } void FrameBase::iisSetCursorCmd(const Vector& v, Coord::InternalSystem sys) { // assume canvas if (!currentContext->cfits) return; iisLastCursor = v * canvasToWidget; Vector r = iisLastCursor * widgetToWindow; XWarpPointer(display, None, Tk_WindowId(tkwin), 0,0,0,0,(int)r[0],(int)r[1]); } void FrameBase::iisSetCursorCmd(const Vector& v, Coord::CoordSystem sys) { if (!currentContext->cfits) return; iisLastCursor = currentContext->cfits->mapToRef(v,sys) * refToWidget; Vector r = iisLastCursor * widgetToWindow; XWarpPointer(display, None, Tk_WindowId(tkwin), 0,0,0,0,(int)r[0],(int)r[1]); } void FrameBase::iisSetFileNameCmd(const char* fn) { FitsImage* ptr = currentContext->fits; while (ptr && ptr->nextMosaic()) ptr = ptr->nextMosaic(); if (ptr) ptr->iisSetFileName(fn); } void FrameBase::iisSetFileNameCmd(const char* fn, int which) { FitsImage* ptr = currentContext->fits; for (int i=0; i<(which-1); i++) { if (ptr) ptr = ptr->nextMosaic(); } if (ptr) ptr->iisSetFileName(fn); } void FrameBase::panCmd(const Vector& v1, const Vector& v2) { Vector start = mapToRef(v1,Coord::CANVAS); Vector stop = mapToRef(v2,Coord::CANVAS); cursor -= stop - start; setBinCursor(); update(MATRIX); } void FrameBase::panCmd(const Vector& vv) { Vector uu = mapFromRef(cursor,Coord::CANVAS); uu += vv; cursor = mapToRef(uu,Coord::CANVAS); setBinCursor(); update(MATRIX); } void FrameBase::panCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!currentContext->cfits) return; Vector uu = currentContext->cfits->mapFromRef(cursor, sys, sky); uu += vv; cursor = currentContext->cfits->mapToRef(uu, sys, sky); setBinCursor(); update(MATRIX); } void FrameBase::panToCmd(const Vector& vv) { cursor = mapToRef(vv,Coord::CANVAS); setBinCursor(); update(MATRIX); } void FrameBase::panToCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!currentContext->cfits) return; cursor = currentContext->cfits->mapToRef(vv, sys, sky); setBinCursor(); update(MATRIX); } void FrameBase::panBBoxCmd(const Vector& vv) { if (!currentContext->cfits) return; // we want to round to nearest pixel center Vector rr = vv * currentContext->cfits->pannerToData; cursor = (rr.floor() + Vector(.5,.5)) * currentContext->cfits->dataToRef; setBinCursor(); update(MATRIX); } void FrameBase::panEndCmd(const Vector& vv) { // vv and panCursor are in Coord::CANVAS coords // delete tmp pixmap if (panPM) Tk_FreePixmap(display, panPM); panPM = 0; // use matrix, not map() for 3d? Vector start = panCursor * canvasToRef; Vector stop = vv * canvasToRef; cursor -= stop - start; setBinCursor(); update(MATRIX); } void FrameBase::rotateBeginCmd() { // save the current rotation rotateRotation = rotation; // Create src XImage if (!(rotateSrcXM = XGetImage(display, pixmap, 0, 0, options->width, options->height, AllPlanes, ZPixmap))) { internalError("Unable to Create Rotate XImage"); return; } // Create dest XImage if (!(rotateDestXM = XGetImage(display, pixmap, 0, 0, options->width, options->height, AllPlanes, ZPixmap))) { internalError("Unable to Create Rotate XImage"); return; } // Create dest Pixmap rotatePM = Tk_GetPixmap(display, Tk_WindowId(tkwin), options->width, options->height, depth); if (!rotatePM) { internalError("Unable to Create Rotate Motion Pixmap"); return; } } void FrameBase::rotateMotionCmd(double angle) { rotation = rotateRotation + angle; rotateMotion(); } void FrameBase::rotateEndCmd() { // Clean up if (rotateSrcXM) XDestroyImage(rotateSrcXM); if (rotateDestXM) XDestroyImage(rotateDestXM); if (rotatePM) Tk_FreePixmap(display, rotatePM); update(MATRIX); } void FrameBase::saveFitsResampleFileCmd(const char* fn) { OutFitsFile str(fn); saveFitsResample(str); } void FrameBase::saveFitsResampleChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFitsResample(str); } void FrameBase::saveFitsResampleSocketCmd(int ss) { OutFitsSocket str(ss); saveFitsResample(str); } void FrameBase::zoomAboutCmd(const Vector& zz, const Vector& vv) { Vector az = ((Vector&)zz).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; cursor = mapToRef(vv,Coord::CANVAS); setBinCursor(); update(MATRIX); } void FrameBase::zoomAboutCmd(const Vector& z, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { Vector az = ((Vector&)z).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; if (currentContext->cfits) { cursor = currentContext->cfits->mapToRef(vv, sys, sky); setBinCursor(); } update(MATRIX); } void FrameBase::zoomToAboutCmd(const Vector& z, const Vector& vv) { zoom_ = ((Vector&)z).abs(); cursor = mapToRef(vv,Coord::CANVAS); setBinCursor(); update(MATRIX); } void FrameBase::zoomToAboutCmd(const Vector& z, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky) { zoom_ = ((Vector&)z).abs(); if (currentContext->cfits) { cursor = currentContext->cfits->mapToRef(vv, sys, sky); setBinCursor(); } update(MATRIX); } void FrameBase::zoomToFitCmd(double ss) { // will center image on center of pixel // with even number pixels, it will be shifted if (keyContext->fits) { centerImage(); Vector tt = imageSize(keyContext->frScale.scanMode()); // adjust image size to be odd (see above) double dd; // dummy if (!modf(tt[0]/2,&dd)) tt[0] +=1; if (!modf(tt[1]/2,&dd)) tt[1] +=1; double zz = calcZoom(tt,Vector(options->width,options->height)) * ss; zoom_ = Vector(zz,zz); update(MATRIX); } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/cpanda.h�����������������������������������������������������������������������0000644�0001750�0001750�00000004200�12030663652�014714� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __cpanda_h__ #define __cpanda_h__ #include "basepanda.h" #include "baseellipse.h" class Cpanda : public BasePanda, public BaseEllipse { private: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif void updateHandles(); void listA(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listB(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); int isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa); public: Cpanda(const Cpanda&); Cpanda(Base* p, const Vector& ctr, double a1, double a2, int an, double r1, double r2, int rn, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Cpanda(Base* p, const Vector& ctr, int an, double* a, int rn, double* r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Cpanda(*this);} void edit(const Vector&, int); void editEnd(); void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} int addAnnuli(const Vector&); int addAngles(const Vector&); void setAnglesAnnuli(double, double, int, Vector, Vector, int); void setAnglesAnnuli(const double*, int, const Vector*, int); void deleteAnglesAnnuli(int h); void analysis(AnalysisTask, int); void analysisPanda(Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listCiao(ostream&, Coord::CoordSystem, int); // special composite funtionality void setComposite(const Matrix&, double); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/parser.Y�����������������������������������������������������������������������0000644�0001750�0001750�00000267641�12131563554�014771� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {frFlexLexer* ll} %parse-param {frFlexLexer* ll} %{ #define YYDEBUG 1 #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "frame3d.h" #include "fitsimage.h" #include "marker.h" #undef yyFlexLexer #define yyFlexLexer frFlexLexer #include <FlexLexer.h> extern int frlex(void*, frFlexLexer*); extern void frerror(Base*, frFlexLexer*, const char*); static Coord::CoordSystem currentCoord = Coord::IMAGE; static Coord::SkyFrame currentSky = Coord::FK5; static unsigned short defaultProps = Marker::SELECT | Marker::HIGHLITE | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::INCLUDE | Marker::SOURCE; static unsigned short currentProps; static char currentColor[16]; static int currentWidth; static int currentDash[2]; static char currentFont[32]; static char currentText[80]; static List<Tag> taglist; static List<CallBack> cblist; static unsigned short propQMask; static unsigned short propQValue; static void setProps(unsigned short* props, unsigned short prop, int value); %} %union { #define FRBUFSIZE 4096 char chr; char str[FRBUFSIZE]; void* ptr; int integer; double real; double vector[3]; int dash[2]; } %type <real> numeric %type <integer> yesno %type <real> angle %type <real> optangle %type <integer> precision %type <real> sexagesimal %type <real> hms %type <real> dms %type <vector> coord %type <integer> coordSystem %type <integer> wcsSystem %type <integer> internalSystem %type <integer> skyFrame %type <integer> skyFormat %type <integer> skyDist %type <integer> markerProperty %type <integer> markerCallBack %type <integer> markerFormat %type <integer> markerLayer %type <dash> markerDash %type <integer> pscolorspace %type <integer> scaleType %type <real> contourClipMode %type <integer> shmType %type <integer> contourmethod %type <integer> incrLoad %type <integer> layerType %type <integer> gridType %type <integer> fileNameType %type <integer> smoothFunction %type <integer> pointShape %type <integer> pointSize %type <integer> endian %type <integer> renderMethod %type <integer> analysisMethod %type <integer> analysisParam %token <real> REAL %token <integer> INT %token <str> STRING %token <ptr> POINTER %token <real> ANGDEGREE %token <real> ANGRADIAN %token <str> SEXSTR %token <str> HMSSTR %token <str> DMSSTR %token ABOUT_ %token AIP_ %token ALLOC_ %token ALLOCGZ_ %token ALIGN_ %token ALL_ %token ALT_ %token AMPLIFIER_ %token ANALYSIS_ %token ANGLE_ %token ANNULUS_ %token APPEND_ %token ARCMIN_ %token ARCSEC_ %token ARRAY_ %token ARROW_ %token ASINH_ %token AST_ %token AUTO_ %token AUX_ %token AVERAGE_ %token B1950_ %token BACK_ %token BASE_ %token BBOX_ %token BEGIN_ %token BG_ %token BIG_ %token BIGENDIAN_ %token BIN_ %token BITPIX_ %token BLOCK_ %token BLT_ %token BORDER_ %token BOX_ %token BOXANNULUS_ %token BOXCAR_ %token BOXCIRCLE_ %token BPANDA_ %token BUFFER_ %token BW_ %token CALLBACK_ %token CANVAS_ %token CATALOG_ %token CELESTRIAL_ %token CENTER_ %token CENTROID_ %token CHANNEL_ %token CIRCLE_ %token CIAO_ %token CLEAR_ %token CLIP_ %token COLOR_ %token COLORBAR_ %token COLORMAP_ %token COLORSCALE_ %token COLORSPACE_ %token COLS_ %token COLUMN_ %token COMMAND_ %token COMPASS_ %token COMPOSITE_ %token COMPRESS_ %token CONTOUR_ %token CONTRAST_ %token COORDINATES_ %token COPY_ %token COUNT_ %token CPANDA_ %token CREATE_ %token CROP_ %token CROSS_ %token CROSSHAIR_ %token CUBE_ %token CURSOR_ %token CUT_ %token CMYK_ %token DASH_ %token DASHLIST_ %token DATA_ %token DATAMIN_ %token DATASEC_ %token DEBUG_ %token DEGREES_ %token DEFAULT_ %token DELETE_ %token DEPTH_ %token DETECTOR_ %token DIAMOND_ %token DIM_ %token DS9_ %token EDIT_ %token ECLIPTIC_ %token ELLIPSE_ %token ELLIPSEANNULUS_ %token END_ %token EPANDA_ %token EQUATORIAL_ %token ERASE_ %token EXT_ %token FACTOR_ %token FALSE_ %token FILE_ %token FILTER_ %token FIT_ %token FITS_ %token FITSY_ %token FIXED_ %token FK4_ %token FK4_NO_E_ %token FK5_ %token FONT_ %token FROM_ %token FRONT_ %token FULL_ %token FUNCTION_ %token GALACTIC_ %token GAUSSIAN_ %token GET_ %token GLOBAL_ %token GRAPHICS_ %token GRAY_ %token GRID_ %token GZ_ %token HANDLE_ %token HAS_ %token HEAD_ %token HEADER_ %token HEIGHT_ %token HELIOECLIPTIC_ %token HIDE_ %token HIGH_ %token HIGHLITE_ %token HISTEQU_ %token HISTOGRAM_ %token HORIZONTAL_ %token ICRS_ %token ID_ %token IIS_ %token IMAGE_ %token INCLUDE_ %token INCR_ %token INFO_ %token INTEGER_ %token ITERATION_ %token IRAF_ %token IRAFMIN_ %token J2000_ %token KEY_ %token KEYWORD_ %token LABEL_ %token LENGTH_ %token LEVEL_ %token LITTLE_ %token LITTLEENDIAN_ %token LINE_ %token LINEAR_ %token LIST_ %token LOAD_ %token LOCAL_ %token LOG_ %token LOW_ %token MACOSX_ %token MAGNIFIER_ %token MATCH_ %token MAP_ %token MARK_ %token MARKER_ %token MASK_ %token MESSAGE_ %token METHOD_ %token MINMAX_ %token MIP_ %token MMAP_ %token MMAPINCR_ %token MOSAIC_ %token MODE_ %token MOTION_ %token MOVE_ %token NAME_ %token NAN_ %token NATIVE_ %token NAXES_ %token NEW_ %token NEXT_ %token NO_ %token NONE_ %token NOW_ %token NRRD_ %token NUMBER_ %token OBJECT_ %token OFF_ %token ON_ %token ONLY_ %token OPTION_ %token ORIENT_ %token PAN_ %token PANNER_ %token PARAM_ %token PARSER_ %token PASTE_ %token PERF_ %token PHOTO_ %token PHYSICAL_ %token PIXEL_ %token PLOT2D_ %token PLOT3D_ %token POINT_ %token POINTER_ %token POLYGON_ %token POSTSCRIPT_ %token POW_ %token PRINT_ %token PRESERVE_ %token PROJECTION_ %token PROPERTY_ %token PUBLICATION_ %token PROS_ %token RADIAL_ %token RADIUS_ %token REGION_ %token REPLACE_ %token RESAMPLE_ %token RESET_ %token RESOLUTION_ %token RGB_ %token ROOT_ %token ROTATE_ %token RULER_ %token SAMPLE_ %token SAOIMAGE_ %token SAOTNG_ %token SAVE_ %token SCALE_ %token SCAN_ %token SCIENTIFIC_ %token SCOPE_ %token SEGMENT_ %token SELECT_ %token SET_ %token SEXAGESIMAL_ %token SHAPE_ %token SHARED_ %token SHIFT_ %token SHMID_ %token SHOW_ %token SINH_ %token SIZE_ %token SLICE_ %token SMMAP_ %token SMOOTH_ %token SOCKET_ %token SOCKETGZ_ %token SOURCE_ %token SQRT_ %token SQUARED_ %token SSHARED_ %token STATS_ %token STATUS_ %token SUPERGALACTIC_ %token SUM_ %token SYSTEM_ %token TABLE_ %token TAG_ %token TEMPLATE_ %token TEXT_ %token THREADS_ %token THREED_ %token THRESHOLD_ %token THICK_ %token TRANSPARENCY_ %token TO_ %token TOGGLE_ %token TOPHAT_ %token TRUE_ %token TYPE_ %token UNDO_ %token UNHIGHLITE_ %token UNLOAD_ %token UNSELECT_ %token UPDATE_ %token USER_ %token VALUE_ %token VAR_ %token VIEW_ %token VECTOR_ %token VERSION_ %token VERTEX_ %token VERTICAL_ %token WARP_ %token WCS_ %token WCSA_ %token WCSB_ %token WCSC_ %token WCSD_ %token WCSE_ %token WCSF_ %token WCSG_ %token WCSH_ %token WCSI_ %token WCSJ_ %token WCSK_ %token WCSL_ %token WCSM_ %token WCSN_ %token WCSO_ %token WCSP_ %token WCSQ_ %token WCSR_ %token WCSS_ %token WCST_ %token WCSU_ %token WCSV_ %token WCSW_ %token WCSX_ %token WCSY_ %token WCSZ_ %token WCS0_ %token WFPC2_ %token WIDTH_ %token WIN32_ %token XML_ %token XY_ %token YES_ %token ZMAX_ %token ZSCALE_ %token ZOOM_ %% command : DEBUG_ debug | BIN_ bin | BG_ COLOR_ STRING {fr->bgColorCmd($3);} | CENTER_ {fr->centerCmd();} | CLEAR_ {fr->clearCmd();} | CLIP_ clip | COLORBAR_ TAG_ STRING {fr->colorbarTagCmd($3);} | COLORMAP_ colormap | COLORSCALE_ colorscale | CONTOUR_ contour | CROP_ crop | CROSSHAIR_ crosshair | DATASEC_ yesno {fr->DATASECCmd($2);} | FITSY_ fitsy | GET_ get | GRID_ grid | HAS_ has | HIDE_ {fr->hideCmd();} | HIGHLITE_ yesno {fr->highliteCmd($2);} | IIS_ iis | LOAD_ load | MACOSX_ macosx | MAGNIFIER_ magnifier | MATCH_ STRING STRING wcsSystem skyFrame STRING STRING wcsSystem skyFrame numeric wcsSystem skyDist STRING { fr->matchCmd($2,$3,(Coord::CoordSystem)$4,(Coord::SkyFrame)$5, $6,$7,(Coord::CoordSystem)$8,(Coord::SkyFrame)$9, $10,(Coord::CoordSystem)$11,(Coord::SkyDist)$12, $13); } | MARKER_ markerLayer marker | MASK_ mask | NAN_ COLOR_ STRING {fr->nanColorCmd($3);} | ORIENT_ orient | PAN_ pan | PANNER_ panner | POSTSCRIPT_ postscript | RESET_ {fr->resetCmd();} | REGION_ markerLayer region | RGB_ rgb | ROTATE_ rotate | SAVE_ save | SHOW_ {fr->showCmd();} | SMOOTH_ smooth | THREADS_ INT {fr->threadsCmd($2);} | THREED_ threed | UNLOAD_ {fr->unloadFitsCmd();} | UPDATE_ update | VERSION_ {fr->msg("Frame 1.0");} | WARP_ warp | WCS_ wcs | WIN32_ win32 | ZOOM_ zoom ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} | AST_ yesno {DebugAST=$2;} | MOSAIC_ yesno {DebugMosaic=$2;} | PARSER_ yesno {yydebug=$2;} | PERF_ yesno {DebugPerf=$2;} | WCS_ yesno {DebugWCS=$2;} | BIN_ yesno {DebugBin=$2;} | COMPRESS_ yesno {DebugCompress=$2} | CROP_ yesno {DebugCrop=$2} | GZ_ yesno {DebugGZ=$2;} | RGB_ yesno {DebugRGB=$2;} ; yesno : INT {$$=($1 ? 1 : 0);} | YES_ {$$=1;} | 'Y' {$$=1;} | ON_ {$$=1;} | TRUE_ {$$=1;} | NO_ {$$=0;} | 'N' {$$=0;} | OFF_ {$$=0;} | FALSE_ {$$=0;} ; precision : /* empty */ {$$ = Base::DEFAULT;} | DEFAULT_ {$$ = Base::DEFAULT;} | FIXED_ {$$ = Base::FIXED;} | SCIENTIFIC_ {$$ = Base::SCIENTIFIC;} | INTEGER_ {$$ = Base::INTEGER;} ; fileNameType : /* empty */ {$$ = Base::ROOTBASE;} | ROOT_ BASE_ {$$ = Base::ROOTBASE;} | FULL_ BASE_ {$$ = Base::FULLBASE;} | ROOT_ {$$ = Base::ROOT;} | FULL_ {$$ = Base::FULL;} | ROOT_ THREED_ {$$ = Base::ROOT3D;} | FULL_ THREED_ {$$ = Base::FULL3D;} ; optangle : /* empty */ {$$ = 0;} | angle {$$ = $1;} ; angle : numeric {$$ = degToRad($1);} /* assume degree */ | ANGDEGREE {$$ = degToRad($1);} | ANGRADIAN {$$=$1;} ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; hms : HMSSTR {$$ = parseHMSStr($1);} ; dms : DMSSTR {$$ = parseDMSStr($1);} ; coord : sexagesimal sexagesimal { Vector r; if (currentSky == Coord::GALACTIC || currentSky == Coord::ECLIPTIC) r = Vector($1,$2); else r = Vector($1*360./24.,$2); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | hms dms { Vector r = Vector($1,$2); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | dms dms { Vector r = Vector($1,$2); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric numeric { $$[0] = $1; $$[1] = $2; $$[2] = 1; } ; coordSystem :IMAGE_ {$$ = currentCoord = Coord::IMAGE;} | PHYSICAL_ {$$ = currentCoord = Coord::PHYSICAL;} | DETECTOR_ {$$ = currentCoord = Coord::DETECTOR;} | AMPLIFIER_ {$$ = currentCoord = Coord::AMPLIFIER;} | wcsSystem {$$ = (Coord::CoordSystem)$1;} ; wcsSystem : WCS_ {$$ = currentCoord = Coord::WCS;} | WCSA_ {$$ = currentCoord = Coord::WCSA;} | WCSB_ {$$ = currentCoord = Coord::WCSB;} | WCSC_ {$$ = currentCoord = Coord::WCSC;} | WCSD_ {$$ = currentCoord = Coord::WCSD;} | WCSE_ {$$ = currentCoord = Coord::WCSE;} | WCSF_ {$$ = currentCoord = Coord::WCSF;} | WCSG_ {$$ = currentCoord = Coord::WCSG;} | WCSH_ {$$ = currentCoord = Coord::WCSH;} | WCSI_ {$$ = currentCoord = Coord::WCSI;} | WCSJ_ {$$ = currentCoord = Coord::WCSJ;} | WCSK_ {$$ = currentCoord = Coord::WCSK;} | WCSL_ {$$ = currentCoord = Coord::WCSL;} | WCSM_ {$$ = currentCoord = Coord::WCSM;} | WCSN_ {$$ = currentCoord = Coord::WCSN;} | WCSO_ {$$ = currentCoord = Coord::WCSO;} | WCSP_ {$$ = currentCoord = Coord::WCSP;} | WCSQ_ {$$ = currentCoord = Coord::WCSQ;} | WCSR_ {$$ = currentCoord = Coord::WCSR;} | WCSS_ {$$ = currentCoord = Coord::WCSS;} | WCST_ {$$ = currentCoord = Coord::WCST;} | WCSU_ {$$ = currentCoord = Coord::WCSU;} | WCSV_ {$$ = currentCoord = Coord::WCSV;} | WCSW_ {$$ = currentCoord = Coord::WCSW;} | WCSX_ {$$ = currentCoord = Coord::WCSX;} | WCSY_ {$$ = currentCoord = Coord::WCSY;} | WCSZ_ {$$ = currentCoord = Coord::WCSZ;} | WCS0_ {$$ = currentCoord = Coord::WCS0;} ; internalSystem : CANVAS_ {$$ = Coord::CANVAS;} | PANNER_ {$$ = Coord::PANNER;} ; scaleType: LINEAR_ {$$ = FrScale::LINEARSCALE;} | LOG_ {$$ = FrScale::LOGSCALE;} | POW_ {$$ = FrScale::POWSCALE;} | SQRT_ {$$ = FrScale::SQRTSCALE;} | SQUARED_ {$$ = FrScale::SQUAREDSCALE;} | ASINH_ {$$ = FrScale::ASINHSCALE;} | SINH_ {$$ = FrScale::SINHSCALE;} | HISTEQU_ {$$ = FrScale::HISTEQUSCALE;} ; skyFrame : /* empty */ {$$ = currentSky = Coord::FK5;} | FK4_ {$$ = currentSky = Coord::FK4;} | FK4_NO_E_ {$$ = currentSky = Coord::FK4_NO_E;} | B1950_ {$$ = currentSky = Coord::FK4;} | FK5_ {$$ = currentSky = Coord::FK5;} | J2000_ {$$ = currentSky = Coord::FK5;} | ICRS_ {$$ = currentSky = Coord::ICRS;} | GALACTIC_ {$$ = currentSky = Coord::GALACTIC;} | SUPERGALACTIC_ {$$ = currentSky = Coord::SUPERGALACTIC;} | ECLIPTIC_ {$$ = currentSky = Coord::ECLIPTIC;} | HELIOECLIPTIC_ {$$ = currentSky = Coord::HELIOECLIPTIC;} ; skyFormat : /* empty */ {$$=Coord::DEGREES;} | DEGREES_ {$$=Coord::DEGREES;} | SEXAGESIMAL_ {$$=Coord::SEXAGESIMAL;} ; skyDist : /* empty */ {$$=Coord::DEGREE;} | DEGREES_ {$$=Coord::DEGREE;} | ARCMIN_ {$$=Coord::ARCMIN;} | ARCSEC_ {$$=Coord::ARCSEC;} ; contourClipMode: numeric {$$ = $1;} | MINMAX_ {$$ = FrScale::MINMAX;} | ZSCALE_ {$$ = FrScale::ZSCALE;} | ZMAX_ {$$ = FrScale::ZMAX;} | USER_ {$$ = FrScale::USERCLIP;} ; shmType : /* empty */ {$$ = Base::SHMID;} | SHMID_ {$$ = Base::SHMID;} | KEY_ {$$ = Base::KEY;} ; incrLoad: /* empty */ {$$ = Base::LOADALL;} | ALL_ {$$ = Base::LOADALL;} | INCR_ {$$ = Base::INCR;} ; layerType : /* empty */ {$$ = Base::IMG;} | IMAGE_ {$$ = Base::IMG;} | MASK_ {$$ = Base::MASK;} ; pointShape: /* empty */ {$$ = Point::CIRCLE;} | CIRCLE_ {$$ = Point::CIRCLE;} | BOX_ {$$ = Point::BOX;} | DIAMOND_ {$$ = Point::DIAMOND;} | CROSS_ {$$ = Point::CROSS;} | 'X' {$$ = Point::EX;} | ARROW_ {$$ = Point::ARROW;} | BOXCIRCLE_ {$$ = Point::BOXCIRCLE;} ; pointSize: /* empty */ {$$ = POINTSIZE;} | INT {$$ = $1;} ; analysisMethod: CPANDA_ {$$ = Marker::PANDA;} | PLOT2D_ {$$ = Marker::PLOT2D;} | PLOT3D_ {$$ = Marker::PLOT3D;} | RADIAL_ {$$ = Marker::RADIAL;} | STATS_ {$$ = Marker::STATS;} ; analysisParam : /* emtpy */ {$$ = Marker::AVERAGE;} | AVERAGE_ {$$ = Marker::AVERAGE;} | SUM_ {$$ = Marker::SUM;} ; endian : /* empty */ {$$ = FitsFile::NATIVE;} | NATIVE_ {$$ = FitsFile::NATIVE;} | BIG_ {$$ = FitsFile::BIG;} | BIGENDIAN_ {$$ = FitsFile::BIG;} | LITTLE_ {$$ = FitsFile::LITTLE;} | LITTLEENDIAN_ {$$ = FitsFile::LITTLE;} ; threed : VIEW_ threedView | BORDER_ threedBorder | COMPASS_ threedCompass | HIGHLITE_ threedHighlite | METHOD_ renderMethod {fr->set3dRenderMethodCmd($2);} | SCALE_ numeric {fr->set3dScaleCmd($2);} | THRESHOLD_ numeric {/* needed for compatibility with old version of backup */} ; threedBorder : yesno {fr->set3dBorderCmd($1);} | COLOR_ STRING {fr->set3dBorderColorCmd($2);} ; threedCompass : yesno {fr->set3dCompassCmd($1);} | COLOR_ STRING {fr->set3dCompassColorCmd($2);} ; threedHighlite : yesno {fr->set3dHighliteCmd($1);} | COLOR_ STRING {fr->set3dHighliteColorCmd($2);} ; threedView : numeric numeric {fr->set3dViewCmd($1,$2);} | POINT_ numeric numeric numeric numeric numeric {fr->set3dViewPointCmd(Vector3d($2,$3,$4),Vector($5,$6));} ; bin : ABOUT_ binAbout | COLS_ STRING STRING STRING {fr->binColsCmd($2,$3,$4);} | DEPTH_ INT {fr->binDepthCmd($2);} | FACTOR_ binFactor | FUNCTION_ binFunction | BUFFER_ SIZE_ INT {fr->binBufferSizeCmd($3);} | TO_ binTo | FILTER_ STRING {fr->binFilterCmd($2);} ; binAbout : CENTER_ {fr->binAboutCmd();} | numeric numeric {fr->binAboutCmd(Vector($1,$2));} ; binFactor : numeric {fr->binFactorCmd(Vector($1,$1));} | numeric numeric {fr->binFactorCmd(Vector($1,$2));} | numeric ABOUT_ numeric numeric {fr->binFactorAboutCmd(Vector($1,$1), Vector($3,$4));} | numeric numeric ABOUT_ numeric numeric {fr->binFactorAboutCmd(Vector($1,$2), Vector($4,$5));} | TO_ numeric {fr->binFactorToCmd(Vector($2,$2));} | TO_ numeric numeric {fr->binFactorToCmd(Vector($2,$3));} | TO_ numeric ABOUT_ numeric numeric {fr->binFactorToAboutCmd(Vector($2,$2), Vector($4,$5));} | TO_ numeric numeric ABOUT_ numeric numeric {fr->binFactorToAboutCmd(Vector($2,$3), Vector($5,$6));} ; binFunction : AVERAGE_ {fr->binFunctionCmd(FitsHist::AVERAGE);} | SUM_ {fr->binFunctionCmd(FitsHist::SUM);} ; binTo : FIT_ {fr->binToFitCmd();} | numeric numeric ABOUT_ CENTER_ STRING STRING STRING {fr->binCmd(Vector($1,$2), $5, $6, $7);} | numeric numeric INT numeric numeric ABOUT_ CENTER_ STRING STRING STRING STRING {fr->binCmd(Vector($1,$2), $3, Vector($4,$5), $8, $9, $10, $11);} | numeric numeric ABOUT_ numeric numeric STRING STRING STRING {fr->binCmd(Vector($1,$2), Vector($4,$5), $6, $7, $8);} | numeric numeric INT numeric numeric ABOUT_ numeric numeric STRING STRING STRING STRING {fr->binCmd(Vector($1,$2), $3, Vector($4,$5), Vector($7,$8), $9, $10, $11, $12);} ; clip : SCOPE_ clipScope | MODE_ clipMode | MINMAX_ clipMinMax | USER_ clipUser | ZSCALE_ clipZScale | PRESERVE_ yesno {fr->clipPreserveCmd($2);} ; clipUser: numeric numeric {fr->clipUserCmd($1,$2);} | LOW_ numeric {fr->clipUserLowCmd($2);} | HIGH_ numeric {fr->clipUserHighCmd($2);} ; clipScope: GLOBAL_ {fr->clipScopeCmd(FrScale::GLOBAL);} | LOCAL_ {fr->clipScopeCmd(FrScale::LOCAL);} ; clipMode: numeric {fr->clipModeCmd($1);} | MINMAX_ {fr->clipModeCmd(FrScale::MINMAX);} | ZSCALE_ {fr->clipModeCmd(FrScale::ZSCALE);} | ZMAX_ {fr->clipModeCmd(FrScale::ZMAX);} | USER_ {fr->clipModeCmd(FrScale::USERCLIP);} ; clipMinMax : MODE_ clipMinMaxMode | SAMPLE_ INT {fr->clipMinMaxSampleCmd($2);} ; clipMinMaxMode : AUTO_ {fr->clipMinMaxModeCmd(FrScale::AUTOSCAN);} | SCAN_ {fr->clipMinMaxModeCmd(FrScale::SCAN);} | SAMPLE_ {fr->clipMinMaxModeCmd(FrScale::SAMPLE);} | DATAMIN_ {fr->clipMinMaxModeCmd(FrScale::DATAMIN);} | IRAFMIN_ {fr->clipMinMaxModeCmd(FrScale::IRAFMIN);} ; clipZScale: CONTRAST_ numeric {fr->clipZScaleContrastCmd($2);} | SAMPLE_ INT {fr->clipZScaleSampleCmd($2);} | LINE_ INT {fr->clipZScaleLineCmd($2);} ; colormap : INT numeric numeric INT POINTER POINTER INT {fr->colormapCmd($1, $2, $3, $4, (unsigned short*)$5, (unsigned char*)$6, $7);} | RGB_ numeric numeric numeric numeric numeric numeric INT POINTER INT {fr->colormapCmd($2,$3,$4,$5,$6,$7,$8,(unsigned char*)$9,$10);} | BEGIN_ {fr->colormapBeginCmd();} | MOTION_ colormapMotion | END_ {fr->colormapEndCmd();} ; colormapMotion: INT numeric numeric INT POINTER POINTER INT {fr->colormapMotionCmd($1, $2, $3, $4, (unsigned short*)$5, (unsigned char*)$6, $7);} | RGB_ numeric numeric numeric numeric numeric numeric INT POINTER INT {fr->colormapMotionCmd($2,$3,$4,$5,$6,$7,$8, (unsigned char*)$9,$10);} colorscale : scaleType {fr->colorScaleCmd((FrScale::ColorScaleType)$1);} | LOG_ numeric {fr->colorScaleLogCmd($2);} ; contour : AUX_ contourAux | COLOR_ STRING {fr->contourSetColorCmd($2);} | COPY_ coordSystem skyFrame {fr->contourCopyCmd((Coord::CoordSystem)$2, (Coord::SkyFrame)$3);} | CREATE_ contourCreate | DASH_ INT {fr->contourSetDashCmd($2);} | DELETE_ {fr->contourDeleteCmd();} | DELETE_ ALL_ {fr->contourDeleteAllCmd();} | LOAD_ STRING INT INT STRING coordSystem skyFrame {fr->contourLoadCmd($2, $3, $4, $5, (Coord::CoordSystem)$6, (Coord::SkyFrame)$7);} | PASTE_ STRING INT INT POINTER coordSystem skyFrame {fr->contourPasteCmd($2, $3, $4, $5, (Coord::CoordSystem)$6, (Coord::SkyFrame)$7);} | SAVE_ STRING coordSystem skyFrame {fr->contourSaveCmd($2, (Coord::CoordSystem)$3, (Coord::SkyFrame)$4);} | WIDTH_ INT {fr->contourSetLineWidthCmd($2);} ; contourAux : HEAD_ {fr->contourAuxHeadCmd();} | NEXT_ {fr->contourAuxNextCmd();} | SAVE_ STRING coordSystem skyFrame {fr->contourAuxSaveCmd($2, (Coord::CoordSystem)$3, (Coord::SkyFrame)$4);} ; contourCreate : STRING INT INT contourmethod INT INT scaleType numeric contourClipMode numeric numeric STRING {fr->contourCreateCmd($1,$2,$3,(FVContour::Method)$4,$5,$6,(FrScale::ColorScaleType)$7,$8,$9,Vector($10,$11),$12);} | POLYGON_ markerProperties {fr->createContourPolygonCmd(currentColor,currentDash,currentWidth, currentFont, currentText, currentProps, NULL, taglist,cblist);} ; contourmethod : SMOOTH_ {$$ = FVContour::SMOOTH;} | BLOCK_ {$$ = FVContour::BLOCK;} ; crop : /* empty */ {fr->cropCmd();} | numeric numeric numeric numeric coordSystem skyFrame {fr->cropCmd(Vector($1,$2), Vector($3,$4), (Coord::CoordSystem)$5, (Coord::SkyFrame)$6);} | CENTER_ coord coordSystem skyFrame numeric numeric coordSystem skyDist {fr->cropCenterCmd(Vector($2), (Coord::CoordSystem)$3, (Coord::SkyFrame)$4, Vector($5,$6), (Coord::CoordSystem)$7, (Coord::SkyDist)$8);} | THREED_ crop3d | BEGIN_ numeric numeric {fr->cropBeginCmd(Vector($2,$3));} | MOTION_ numeric numeric {fr->cropMotionCmd(Vector($2,$3));} | END_ numeric numeric {fr->cropEndCmd(Vector($2,$3));} ; crop3d : /* empty */ {fr->crop3dCmd();} | numeric numeric coordSystem {fr->crop3dCmd($1, $2, (Coord::CoordSystem)$3);} | BEGIN_ numeric numeric INT {fr->crop3dBeginCmd(Vector($2,$3),$4);} | MOTION_ numeric numeric INT {fr->crop3dMotionCmd(Vector($2,$3),$4);} | END_ numeric numeric INT {fr->crop3dEndCmd(Vector($2,$3),$4);} ; crosshair: internalSystem numeric numeric {fr->crosshairCmd(Vector($2,$3), (Coord::InternalSystem)$1);} | coordSystem skyFrame coord {fr->crosshairCmd(Vector($3), (Coord::CoordSystem)$1, (Coord::SkyFrame)$2);} | yesno {fr->crosshairCmd($1);} | WARP_ numeric numeric {fr->crosshairWarpCmd(Vector($2,$3));} | BEGIN_ MOTION_ internalSystem numeric numeric {fr->crosshairCmd(Vector($4,$5), (Coord::InternalSystem)$3);} | MOTION_ internalSystem numeric numeric {fr->crosshairCmd(Vector($3,$4), (Coord::InternalSystem)$2);} | BEGIN_ MOTION_ coordSystem coord {fr->crosshairCmd(Vector($4), (Coord::CoordSystem)$3);} | MOTION_ coordSystem coord {fr->crosshairCmd(Vector($3), (Coord::CoordSystem)$2);} ; fitsy : HAS_ EXT_ STRING {fr->fitsyHasExtCmd($3);} ; get : BG_ COLOR_ {fr->getBgColorCmd();} | BIN_ getBin | CLIP_ getClip | COLORMAP_ getColorMap | COLORBAR_ getColorbar | COLORSCALE_ getColorScale | CONTOUR_ getContour | COORDINATES_ getCoord | CROP_ getCrop | CROSSHAIR_ getCrosshair | CURSOR_ getCursor | DATA_ getData | DATASEC_ {fr->getDATASECCmd();} | FITS_ getFits | GRID_ getGrid | HISTOGRAM_ STRING STRING {fr->getHistogramCmd($2,$3);} | HORIZONTAL_ CUT_ STRING STRING numeric numeric internalSystem {fr->getHorzCutCmd($3,$4,Vector($5,$6),(Coord::InternalSystem)$7);} | IIS_ getiis | INFO_ getInfo | MINMAX_ {fr->getMinMaxCmd();} | MARKER_ markerLayer markerGet | MASK_ getMask | NAN_ COLOR_ {fr->getNANColorCmd();} | ORIENT_ {fr->getOrientCmd();} | PAN_ getPan | PIXEL_ TABLE_ internalSystem numeric numeric INT INT STRING {fr->getPixelTableCmd(Vector($4,$5), (Coord::InternalSystem)$3, $6, $7, $8);} | RGB_ getRGB | ROTATE_ getRotate | SMOOTH_ getSmooth | THREADS_ {fr->getThreadsCmd();} | THREED_ getThreed | TYPE_ {fr->getTypeCmd();} | VALUE_ internalSystem numeric numeric {fr->getValueCmd(Vector($3,$4),(Coord::InternalSystem)$2);} | VERTICAL_ CUT_ STRING STRING numeric numeric internalSystem {fr->getVertCutCmd($3,$4,Vector($5,$6),(Coord::InternalSystem)$7);} | WCS_ getWCS | ZOOM_ getZoom ; getBin : DEPTH_ {fr->getBinDepthCmd();} | FACTOR_ {fr->getBinFactorCmd();} | FUNCTION_ {fr->getBinFunctionCmd();} | BUFFER_ SIZE_ {fr->getBinBufferSizeCmd();} | CURSOR_ {fr->getBinCursorCmd();} | FILTER_ {fr->getBinFilterCmd();} | COLS_ getBinCols | LIST_ {fr->getBinListCmd();} ; getBinCols : /* empty */ {fr->getBinColsCmd();} | MINMAX_ STRING {fr->getBinColsMinMaxCmd($2);} | DIM_ STRING {fr->getBinColsDimCmd($2);} ; getClip : getClipLimits | SCOPE_ {fr->getClipScopeCmd();} | MODE_ {fr->getClipModeCmd();} | MINMAX_ getClipMinMax | USER_ LEVEL_ {fr->getClipUserCmd();} | ZSCALE_ getClipZScale | PRESERVE_ {fr->getClipPreserveCmd();} ; getClipLimits: /* empty */ {fr->getClipCmd();} | numeric {fr->getClipCmd($1);} | MINMAX_ {fr->getClipCmd(FrScale::MINMAX);} | ZSCALE_ {fr->getClipCmd(FrScale::ZSCALE);} | ZMAX_ {fr->getClipCmd(FrScale::ZMAX);} | USER_ {fr->getClipCmd(FrScale::USERCLIP);} ; getClipMinMax : MODE_ {fr->getClipMinMaxModeCmd();} | SAMPLE_ {fr->getClipMinMaxSampleCmd();} ; getClipZScale: CONTRAST_ {fr->getClipZScaleContrastCmd();} | SAMPLE_ {fr->getClipZScaleSampleCmd();} | LINE_ {fr->getClipZScaleLineCmd();} ; getColorbar: /* empty */ {fr->getColorbarCmd();} | TAG_ {fr->getColorbarTagCmd();} ; getColorMap : LEVEL_ getColorMapLevel ; getColorMapLevel: INT {fr->getColorMapLevelCmd($1);} | INT internalSystem numeric numeric {fr->getColorMapLevelCmd($1,Vector($3,$4),(Coord::InternalSystem)$2);} | INT numeric numeric scaleType numeric {fr->getColorMapLevelCmd($1,$2,$3,(FrScale::ColorScaleType)$4,$5);} ; getColorScale : /* empty */ {fr->getColorScaleCmd();} | LEVEL_ getColorScaleLevel | LOG_ {fr->getColorScaleLogCmd();} ; getColorScaleLevel: INT numeric numeric scaleType numeric {fr->getColorScaleLevelCmd($1,$2,$3,(FrScale::ColorScaleType)$4,$5);} ; getContour: coordSystem skyFrame {fr->getContourCmd((Coord::CoordSystem)$1,(Coord::SkyFrame)$2);} | AUX_ getContourAux | CLIP_ getContourClip | COLOR_ {fr->getContourColorNameCmd();} | DASH_ {fr->getContourDashCmd();} | LEVEL_ {fr->getContourLevelCmd();} | NUMBER_ LEVEL_ {fr->getContourNumLevelCmd();} | METHOD_ {fr->getContourMethodCmd();} | COLORSCALE_ getContourColorScale | SMOOTH_ {fr->getContourSmoothCmd();} | WIDTH_ {fr->getContourLineWidthCmd();} ; getContourAux: COLOR_ {fr->getContourAuxColorNameCmd();} | DASH_ {fr->getContourAuxDashCmd();} | WIDTH_ {fr->getContourAuxLineWidthCmd();} ; getContourClip : /* empty */ {fr->getContourClipCmd();} | MODE_ {fr->getContourClipModeCmd();} ; getContourColorScale : /* empty */ {fr->getContourScaleCmd();} | LOG_ {fr->getContourScaleLogCmd();} ; getCoord : numeric numeric coordSystem skyFrame skyFormat {fr->getCoordCmd(Vector($1,$2), (Coord::CoordSystem)$3, (Coord::SkyFrame)$4, (Coord::SkyFormat)$5);} | internalSystem numeric numeric coordSystem skyFrame skyFormat { // backward compatibility fr->getCoordCmd(Vector($2,$3), (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6); } | numeric coordSystem INT {fr->getCoordFromRefCmd($1, (Coord::CoordSystem)$2, $3);} | FROM_ numeric coordSystem INT {fr->getCoordFromRefCmd($2, (Coord::CoordSystem)$3, $4);} | TO_ numeric coordSystem INT {fr->getCoordToRefCmd($2, (Coord::CoordSystem)$3, $4);} ; getCrop : coordSystem skyFrame skyFormat {fr->getCropCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3);} | CENTER_ coordSystem skyFrame skyFormat coordSystem skyDist {fr->getCropCenterCmd((Coord::CoordSystem)$2, (Coord::SkyFrame)$3, (Coord::SkyFormat)$4, (Coord::CoordSystem)$5, (Coord::SkyDist)$6);} | THREED_ coordSystem {fr->getCrop3dCmd((Coord::CoordSystem)$2);} ; getCrosshair: internalSystem {fr->getCrosshairCmd((Coord::InternalSystem)$1);} | coordSystem skyFrame skyFormat precision {fr->getCrosshairCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3, (Base::Precision)$4)} | STATUS_ {fr->getCrosshairStatusCmd();} ; getCursor : internalSystem {fr->getCursorCmd((Coord::InternalSystem)$1);} | coordSystem skyFrame skyFormat precision {fr->getCursorCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3, (Base::Precision)$4);} ; getData : coordSystem skyFrame coord numeric numeric STRING {fr->getDataValuesCmd(1, Vector($3), (Coord::CoordSystem)$1, (Coord::SkyFrame)$2, Vector($4,$5), $6);} | INT coordSystem skyFrame coord numeric numeric STRING {fr->getDataValuesCmd($1, Vector($4), (Coord::CoordSystem)$2, (Coord::SkyFrame)$3, Vector($5,$6), $7);} | internalSystem numeric numeric INT INT {fr->getDataValuesCmd(Vector($2,$3),(Coord::InternalSystem)$1, Vector($4,$5));} ; getInfo : STRING {fr->getInfoCmd($1);} | CLIP_ {fr->getInfoClipCmd();} | internalSystem numeric numeric STRING {fr->getInfoCmd(Vector($2,$3), (Coord::InternalSystem)$1, $4);} ; getiis : POINTER INT INT INT INT {fr->iisGetCmd((char*)$1,$2,$3,$4,$5);} | CURSOR_ {fr->iisGetCursorCmd();} | WIDTH_ {fr->getWidthCmd();} | HEIGHT_ {fr->getHeightCmd();} | FILE_ NAME_ getIISFileName ; getIISFileName : /* empty */ {fr->iisGetFileNameCmd();} | INT {fr->iisGetFileNameCmd($1);} | numeric numeric {fr->iisGetFileNameCmd(Vector($1,$2));} ; getFits : NAXES_ /* empty */ {fr->getFitsNAxesCmd();} | CENTER_ coordSystem skyFrame skyFormat precision {fr->getFitsCenterCmd((Coord::CoordSystem)$2,(Coord::SkyFrame)$3,(Coord::SkyFormat)$4, (Base::Precision)$5);} | COUNT_ {fr->getFitsCountCmd();} | DEPTH_ getFitsDepth | BITPIX_ {fr->getBitpixCmd();} | EXT_ internalSystem numeric numeric {fr->getFitsExtCmd(Vector($3,$4),(Coord::InternalSystem)$2);} | FILE_ NAME_ getFitsFileName | HEADER_ getFitsHeader | HEIGHT_ {fr->getHeightCmd();} | OBJECT_ NAME_ {fr->getFitsObjectNameCmd();} | SIZE_ {fr->getFitsSizeCmd();} | SIZE_ coordSystem skyFrame skyDist precision {fr->getFitsSizeCmd((Coord::CoordSystem)$2,(Coord::SkyFrame)$3,(Coord::SkyDist)$4, (Base::Precision)$5);} | SLICE_ getFitsSlice | WIDTH_ {fr->getWidthCmd();} ; getFitsHeader : INT {fr->getFitsHeaderCmd($1);} | INT KEYWORD_ STRING {fr->getFitsHeaderKeywordCmd($1,$3);} | WCS_ INT {fr->getFitsHeaderWCSCmd($2);} ; getFitsDepth : /* empty */ {fr->getFitsDepthCmd(2);} | INT {fr->getFitsDepthCmd($1);} ; getFitsFileName: fileNameType {fr->getFitsFileNameCmd((Base::FileNameType)$1);} | fileNameType internalSystem numeric numeric {fr->getFitsFileNameCmd(Vector($3,$4), (Coord::InternalSystem)$2, (Base::FileNameType)$1);} | fileNameType INT {fr->getFitsFileNameCmd($2, (Base::FileNameType)$1);} ; getFitsSlice : /* empty */ {fr->getFitsSliceCmd(2);} | INT {fr->getFitsSliceCmd($1);} ; getGrid : /* empty */ {fr->getGridCmd();} | OPTION_ {fr->getGridOptionCmd();} | VAR_ {fr->getGridVarsCmd();} ; getMask : COLOR_ {fr->getMaskColorCmd();} | MARK_ {fr->getMaskMarkCmd();} | TRANSPARENCY_{fr->getMaskTransparencyCmd();} ; getPan : PRESERVE_ {fr->getPanPreserveCmd();} ; getRGB : CHANNEL_ {fr->getRGBChannelCmd();} | SYSTEM_ {fr->getRGBSystemCmd();} | VIEW_ {fr->getRGBViewCmd();} ; getRotate : precision {fr->getRotateCmd((Base::Precision)$1);} ; getSmooth : FUNCTION_ {fr->getSmoothFunctionCmd();} | RADIUS_ {fr->getSmoothRadiusCmd();} ; getThreed : VIEW_ getThreedView | BORDER_ getThreedBorder | COMPASS_ getThreedCompass | HIGHLITE_ getThreedHighlite | METHOD_ {fr->get3dRenderMethodCmd();} | SCALE_ {fr->get3dScaleCmd();} ; getThreedBorder : {fr->get3dBorderCmd();} | COLOR_ {fr->get3dBorderColorCmd();} ; getThreedCompass : {fr->get3dCompassCmd();} | COLOR_ {fr->get3dCompassColorCmd();} ; getThreedHighlite : {fr->get3dHighliteCmd();} | COLOR_ {fr->get3dHighliteColorCmd();} ; getThreedView : {fr->get3dViewCmd();} | POINT_ {fr->get3dViewPointCmd();} ; getWCS : /* empty */ {fr->getWCSCmd();} | ALIGN_ getWCSAlign | NAME_ wcsSystem {fr->getWCSNameCmd((Coord::CoordSystem)$2);} ; getWCSAlign : /* empty */ {fr->getWCSAlignCmd();} | POINTER_ {fr->getWCSAlignPointerCmd();} ; getZoom : precision {fr->getZoomCmd((Base::Precision)$1);} ; grid : CREATE_ gridCreate | DELETE_ {fr->gridDeleteCmd();} ; gridCreate: coordSystem skyFrame skyFormat gridType STRING STRING {fr->gridCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3, (Grid2d::GridType)$4, $5, $6);} | coordSystem skyFrame skyFormat gridType STRING { // backward compatibility with backup fr->gridCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3, (Grid2d::GridType)$4, $5, ""); } ; gridType : ANALYSIS_ {$$=Grid2d::ANALYSIS;} | PUBLICATION_ {$$=Grid2d::PUBLICATION;} ; has : AMPLIFIER_ {fr->hasAmplifierCmd();} | BIN_ hasBin | CONTOUR_ hasContour | CROP_ {fr->hasCropCmd();} | DATAMIN_ {fr->hasDATAMINCmd();} | DATASEC_ {fr->hasDATASECCmd();} | DETECTOR_ {fr->hasDetectorCmd();} | FITS_ hasFits | GRID_ {fr->hasGridCmd();} | IIS_ {fr->hasIISCmd();} | IRAFMIN_ {fr->hasIRAFMINCmd();} | MARKER_ hasMarker | PHYSICAL_ {fr->hasPhysicalCmd();} | SMOOTH_ {fr->hasSmoothCmd();} | SYSTEM_ coordSystem {fr->hasSystemCmd((Coord::CoordSystem)$2);} | WCS_ hasWCS ; hasBin : COLUMN_ STRING {fr->hasBinColCmd($2);} ; hasContour : /* empty */ {fr->hasContourCmd();} | AUX_ {fr->hasContourAuxCmd();} ; hasFits : /* empty */ {fr->hasFitsCmd();} | BIN_ {fr->hasFitsBinCmd();} | CUBE_ {fr->hasFitsCubeCmd();} | MOSAIC_ {fr->hasFitsMosaicCmd();} ; hasMarker : HIGHLITE_ {fr->hasMarkerHighlitedCmd();} | SELECT_ {fr->hasMarkerSelectedCmd();} | PASTE_ {fr->hasMarkerPasteCmd();} | UNDO_ {fr->hasMarkerUndoCmd();} ; hasWCS : coordSystem {fr->hasWCSCmd((Coord::CoordSystem)$1);} | EQUATORIAL_ coordSystem {fr->hasWCSEquCmd((Coord::CoordSystem)$2);} | CELESTRIAL_ coordSystem {fr->hasWCSCelCmd((Coord::CoordSystem)$2);} | ALT_ {fr->hasWCSAltCmd();} | THREED_ coordSystem {fr->hasWCSxCmd((Coord::CoordSystem)$2);} ; iis : NEW_ INT INT {fr->iisCmd($2,$3);} | ERASE_ {fr->iisEraseCmd();} | MESSAGE_ STRING {fr->iisMessageCmd($2);} | CURSOR_ iiscursor | SET_ FILE_ NAME_ iisSetFileName | SET_ POINTER INT INT INT INT {fr->iisSetCmd((const char*)$2,$3,$4,$5,$6);} | UPDATE_ {fr->iisUpdateCmd();} | WCS_ numeric numeric numeric numeric numeric numeric numeric numeric INT {fr->iisWCSCmd(Matrix($2,$3,$4,$5,$6,$7),Vector($8,$9),$10);} ; iisSetFileName : STRING {fr->iisSetFileNameCmd($1);} | STRING INT {fr->iisSetFileNameCmd($1,$2);} ; iiscursor: INT INT CANVAS_ {fr->iisSetCursorCmd(Vector($1,$2),Coord::CANVAS);} | INT INT coordSystem {fr->iisSetCursorCmd(Vector($1,$2),(Coord::CoordSystem)$3);} | MODE_ yesno {fr->iisCursorModeCmd($2);} ; load : ARRAY_ loadArr | FITS_ loadFits | INCR_ loadIncr | NRRD_ loadNRRD | PHOTO_ loadPhoto ; loadArr : STRING ALLOC_ STRING layerType {fr->loadArrAllocCmd($3, $1, (Base::LayerType)$4);} | STRING ALLOCGZ_ STRING layerType {fr->loadArrAllocGZCmd($3, $1, (Base::LayerType)$4);} | STRING CHANNEL_ STRING layerType {fr->loadArrChannelCmd($3, $1, (Base::LayerType)$4);} | STRING MMAP_ layerType {fr->loadArrMMapCmd($1, (Base::LayerType)$3);} | STRING MMAPINCR_ layerType {fr->loadArrMMapIncrCmd($1, (Base::LayerType)$3);} | STRING SHARED_ shmType INT layerType {fr->loadArrShareCmd((Base::ShmType)$3, $4, $1, (Base::LayerType)$5);} | STRING SOCKET_ INT layerType {fr->loadArrSocketCmd($3, $1, (Base::LayerType)$4);} | STRING SOCKETGZ_ INT layerType {fr->loadArrSocketGZCmd($3, $1, (Base::LayerType)$4);} | STRING VAR_ STRING layerType {fr->loadArrVarCmd($3, $1, (Base::LayerType)$4);} | RGB_ CUBE_ loadArrayRGBCube ; loadArrayRGBCube : STRING ALLOC_ STRING {fr->loadArrayRGBCubeAllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadArrayRGBCubeAllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadArrayRGBCubeChannelCmd($3, $1);} | STRING MMAP_ {fr->loadArrayRGBCubeMMapCmd($1);} | STRING MMAPINCR_ {fr->loadArrayRGBCubeMMapIncrCmd($1);} | STRING SHARED_ shmType INT {fr->loadArrayRGBCubeShareCmd((Base::ShmType)$3, $4, $1);} | STRING SOCKET_ INT {fr->loadArrayRGBCubeSocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadArrayRGBCubeSocketGZCmd($3, $1);} | STRING VAR_ STRING {fr->loadArrayRGBCubeVarCmd($3, $1);} ; loadFits: STRING ALLOC_ STRING layerType {fr->loadFitsAllocCmd($3, $1, (Base::LayerType)$4);} | STRING ALLOCGZ_ STRING layerType {fr->loadFitsAllocGZCmd($3, $1, (Base::LayerType)$4);} | STRING CHANNEL_ STRING layerType {fr->loadFitsChannelCmd($3, $1, (Base::LayerType)$4);} | STRING MMAP_ incrLoad layerType {fr->loadFitsMMapCmd($1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING STRING SMMAP_ incrLoad layerType {fr->loadFitsSMMapCmd($1, $2,(Base::LoadMethod)$4, (Base::LayerType)$5);} | STRING MMAPINCR_ incrLoad layerType {fr->loadFitsMMapIncrCmd($1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING SHARED_ shmType INT incrLoad layerType {fr->loadFitsShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5,(Base::LayerType)$6);} | STRING SSHARED_ shmType INT INT incrLoad layerType {fr->loadFitsSShareCmd((Base::ShmType)$3, $4, $5, $1, (Base::LoadMethod)$6,(Base::LayerType)$7);} | STRING SOCKET_ INT layerType {fr->loadFitsSocketCmd($3, $1, (Base::LayerType)$4);} | STRING SOCKETGZ_ INT layerType {fr->loadFitsSocketGZCmd($3, $1, (Base::LayerType)$4);} | STRING VAR_ STRING incrLoad layerType {fr->loadFitsVarCmd($3, $1, (Base::LoadMethod)$4, (Base::LayerType)$5);} | SLICE_ loadFitsSlice | EXT_ CUBE_ loadFitsExtCube | RGB_ IMAGE_ loadFitsRGBImage | RGB_ CUBE_ loadFitsRGBCube | MOSAIC_ loadFitsMosaic ; loadFitsSlice:STRING ALLOC_ STRING {fr->loadSliceAllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadSliceAllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadSliceChannelCmd($3, $1);} | STRING MMAP_ incrLoad {fr->loadSliceMMapCmd($1, (Base::LoadMethod)$3);} | STRING STRING SMMAP_ incrLoad {fr->loadSliceSMMapCmd($1, $2, (Base::LoadMethod)$4);} | STRING MMAPINCR_ incrLoad {fr->loadSliceMMapIncrCmd($1, (Base::LoadMethod)$3);} | STRING SHARED_ shmType INT incrLoad {fr->loadSliceShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5);} | STRING SSHARED_ shmType INT INT incrLoad {fr->loadSliceSShareCmd((Base::ShmType)$3, $4, $5, $1, (Base::LoadMethod)$6);} | STRING SOCKET_ INT {fr->loadSliceSocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadSliceSocketGZCmd($3, $1);} | STRING VAR_ STRING incrLoad {fr->loadSliceVarCmd($3, $1, (Base::LoadMethod)$4);} ; loadFitsExtCube: STRING ALLOC_ STRING {fr->loadExtCubeAllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadExtCubeAllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadExtCubeChannelCmd($3, $1);} | STRING MMAP_ incrLoad {fr->loadExtCubeMMapCmd($1, (Base::LoadMethod)$3);} | STRING MMAPINCR_ incrLoad {fr->loadExtCubeMMapIncrCmd($1, (Base::LoadMethod)$3);} | STRING SHARED_ shmType INT incrLoad {fr->loadExtCubeShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5);} | STRING SOCKET_ INT {fr->loadExtCubeSocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadExtCubeSocketGZCmd($3, $1);} | STRING VAR_ STRING incrLoad {fr->loadExtCubeVarCmd($3, $1, (Base::LoadMethod)$4);} ; loadFitsMosaic : IMAGE_ IRAF_ loadFitsMosaicImageIRAF | IRAF_ loadFitsMosaicIRAF | IMAGE_ loadFitsMosaicImageWCS | loadFitsMosaicWCS | IMAGE_ WFPC2_ loadFitsMosaicImageWFPC2 ; loadFitsMosaicImageIRAF : STRING ALLOC_ STRING layerType {fr->loadMosaicImageAllocCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING ALLOCGZ_ STRING layerType {fr->loadMosaicImageAllocGZCmd(Base::IRAF, Coord::WCS, $3, $1,(Base::LayerType)$4);} | STRING CHANNEL_ STRING layerType {fr->loadMosaicImageChannelCmd(Base::IRAF, Coord::WCS, $3, $1,(Base::LayerType)$4);} | STRING MMAP_ incrLoad layerType {fr->loadMosaicImageMMapCmd(Base::IRAF, Coord::WCS, $1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING MMAPINCR_ incrLoad layerType {fr->loadMosaicImageMMapIncrCmd(Base::IRAF, Coord::WCS, $1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING SHARED_ shmType INT incrLoad layerType {fr->loadMosaicImageShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5, (Base::LayerType)$6);} | STRING SOCKET_ INT layerType {fr->loadMosaicImageSocketCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING SOCKETGZ_ INT layerType {fr->loadMosaicImageSocketGZCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING VAR_ STRING incrLoad layerType {fr->loadMosaicImageVarCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LoadMethod)$4, (Base::LayerType)$5);} ; loadFitsMosaicIRAF : STRING ALLOC_ STRING layerType {fr->loadMosaicAllocCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING ALLOCGZ_ STRING layerType {fr->loadMosaicAllocGZCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING CHANNEL_ STRING layerType {fr->loadMosaicChannelCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING MMAP_ incrLoad layerType {fr->loadMosaicMMapCmd(Base::IRAF, Coord::WCS, $1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING STRING SMMAP_ incrLoad layerType {fr->loadMosaicSMMapCmd(Base::IRAF, Coord::WCS, $1, $2,(Base::LoadMethod)$4, (Base::LayerType)$5);} | STRING MMAPINCR_ incrLoad layerType {fr->loadMosaicMMapIncrCmd(Base::IRAF, Coord::WCS, $1,(Base::LoadMethod)$3, (Base::LayerType)$4);} | STRING SHARED_ shmType INT incrLoad layerType {fr->loadMosaicShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5, (Base::LayerType)$6);} | STRING SSHARED_ shmType INT INT incrLoad layerType {fr->loadMosaicSShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)$3, $4, $5, $1, (Base::LoadMethod)$6, (Base::LayerType)$7);} | STRING SOCKET_ INT layerType {fr->loadMosaicSocketCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING SOCKETGZ_ INT layerType {fr->loadMosaicSocketGZCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LayerType)$4);} | STRING VAR_ STRING incrLoad layerType {fr->loadMosaicVarCmd(Base::IRAF, Coord::WCS, $3, $1, (Base::LoadMethod)$4, (Base::LayerType)$5);} ; loadFitsMosaicImageWCS : wcsSystem STRING ALLOC_ STRING layerType {fr->loadMosaicImageAllocCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING ALLOCGZ_ STRING layerType {fr->loadMosaicImageAllocGZCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING CHANNEL_ STRING layerType {fr->loadMosaicImageChannelCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING MMAP_ incrLoad layerType {fr->loadMosaicImageMMapCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $2, (Base::LoadMethod)$4, (Base::LayerType)$5);} | wcsSystem STRING MMAPINCR_ incrLoad layerType {fr->loadMosaicImageMMapIncrCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $2, (Base::LoadMethod)$4, (Base::LayerType)$5);} | wcsSystem STRING SHARED_ shmType INT incrLoad layerType {fr->loadMosaicImageShareCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, (Base::ShmType)$4, $5, $2, (Base::LoadMethod)$6, (Base::LayerType)$7);} | wcsSystem STRING SOCKET_ INT layerType {fr->loadMosaicImageSocketCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING SOCKETGZ_ INT layerType {fr->loadMosaicImageSocketGZCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING VAR_ STRING incrLoad layerType {fr->loadMosaicImageVarCmd(Base::WCSMOSAIC, (Coord::CoordSystem)$1, $4, $2, (Base::LoadMethod)$5, (Base::LayerType)$6);} ; loadFitsMosaicWCS : wcsSystem STRING ALLOC_ STRING layerType {fr->loadMosaicAllocCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING ALLOCGZ_ STRING layerType {fr->loadMosaicAllocGZCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING CHANNEL_ STRING layerType {fr->loadMosaicChannelCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING MMAP_ incrLoad layerType {fr->loadMosaicMMapCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $2, (Base::LoadMethod)$4, (Base::LayerType)$5);} | wcsSystem STRING STRING SMMAP_ incrLoad layerType {fr->loadMosaicSMMapCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $2, $3, (Base::LoadMethod)$5, (Base::LayerType)$6);} | wcsSystem STRING MMAPINCR_ incrLoad layerType {fr->loadMosaicMMapIncrCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $2, (Base::LoadMethod)$4, (Base::LayerType)$5);} | wcsSystem STRING SHARED_ shmType INT incrLoad layerType {fr->loadMosaicShareCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, (Base::ShmType)$4, $5, $2, (Base::LoadMethod)$6, (Base::LayerType)$7);} | wcsSystem STRING SSHARED_ shmType INT INT incrLoad layerType {fr->loadMosaicSShareCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, (Base::ShmType)$4, $5, $6, $2, (Base::LoadMethod)$7, (Base::LayerType)$8);} | wcsSystem STRING SOCKET_ INT layerType {fr->loadMosaicSocketCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING SOCKETGZ_ INT layerType {fr->loadMosaicSocketGZCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LayerType)$5);} | wcsSystem STRING VAR_ STRING incrLoad layerType {fr->loadMosaicVarCmd((Base::WCSMOSAIC), (Coord::CoordSystem)$1, $4, $2, (Base::LoadMethod)$5, (Base::LayerType)$6);} ; loadFitsMosaicImageWFPC2 : STRING ALLOC_ STRING {fr->loadMosaicImageWFPC2AllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadMosaicImageWFPC2AllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadMosaicImageWFPC2ChannelCmd($3, $1);} | STRING MMAP_ incrLoad {fr->loadMosaicImageWFPC2MMapCmd($1,(Base::LoadMethod)$3);} | STRING MMAPINCR_ incrLoad {fr->loadMosaicImageWFPC2MMapIncrCmd($1,(Base::LoadMethod)$3);} | STRING SHARED_ shmType INT incrLoad {fr->loadMosaicImageWFPC2ShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5);} | STRING SOCKET_ INT {fr->loadMosaicImageWFPC2SocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadMosaicImageWFPC2SocketGZCmd($3, $1);} | STRING VAR_ STRING incrLoad {fr->loadMosaicImageWFPC2VarCmd($3, $1, (Base::LoadMethod)$4);} ; loadFitsRGBCube: STRING ALLOC_ STRING {fr->loadRGBCubeAllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadRGBCubeAllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadRGBCubeChannelCmd($3, $1);} | STRING MMAP_ incrLoad {fr->loadRGBCubeMMapCmd($1, (Base::LoadMethod)$3);} | STRING STRING SMMAP_ incrLoad {fr->loadRGBCubeSMMapCmd($1, $2, (Base::LoadMethod)$4);} | STRING MMAPINCR_ incrLoad {fr->loadRGBCubeMMapIncrCmd($1, (Base::LoadMethod)$3);} | STRING SHARED_ shmType INT incrLoad {fr->loadRGBCubeShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5);} | STRING SSHARED_ shmType INT INT incrLoad {fr->loadRGBCubeSShareCmd((Base::ShmType)$3, $4, $5, $1, (Base::LoadMethod)$6);} | STRING SOCKET_ INT {fr->loadRGBCubeSocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadRGBCubeSocketGZCmd($3, $1);} | STRING VAR_ STRING incrLoad {fr->loadRGBCubeVarCmd($3, $1, (Base::LoadMethod)$4);} ; loadFitsRGBImage: STRING ALLOC_ STRING {fr->loadRGBImageAllocCmd($3, $1);} | STRING ALLOCGZ_ STRING {fr->loadRGBImageAllocGZCmd($3, $1);} | STRING CHANNEL_ STRING {fr->loadRGBImageChannelCmd($3, $1);} | STRING MMAP_ incrLoad {fr->loadRGBImageMMapCmd($1, (Base::LoadMethod)$3);} | STRING MMAPINCR_ incrLoad {fr->loadRGBImageMMapIncrCmd($1, (Base::LoadMethod)$3);} | STRING SHARED_ shmType INT incrLoad {fr->loadRGBImageShareCmd((Base::ShmType)$3, $4, $1, (Base::LoadMethod)$5);} | STRING SOCKET_ INT {fr->loadRGBImageSocketCmd($3, $1);} | STRING SOCKETGZ_ INT {fr->loadRGBImageSocketGZCmd($3, $1);} | STRING VAR_ STRING incrLoad {fr->loadRGBImageVarCmd($3, $1, (Base::LoadMethod)$4);} ; loadNRRD : STRING ALLOC_ STRING layerType {fr->loadNRRDAllocCmd($3, $1, (Base::LayerType)$4);} | STRING CHANNEL_ STRING layerType {fr->loadNRRDChannelCmd($3, $1, (Base::LayerType)$4);} | STRING MMAP_ layerType {fr->loadNRRDMMapCmd($1, (Base::LayerType)$3);} | STRING SHARED_ shmType INT layerType {fr->loadNRRDShareCmd((Base::ShmType)$3, $4, $1, (Base::LayerType)$5);} | STRING SOCKET_ INT layerType {fr->loadNRRDSocketCmd($3, $1, (Base::LayerType)$4);} | STRING VAR_ STRING layerType {fr->loadNRRDVarCmd($3, $1, (Base::LayerType)$4);} ; loadPhoto: /* empty */ STRING STRING {fr->loadPhotoCmd($1,$2);} | SLICE_ STRING STRING {fr->loadSlicePhotoCmd($2,$3);} ; loadIncr: DATA_ INT INT INT INT INT {fr->loadIncrDataCmd($2,$3,$4,$5,$6);} | MINMAX_ INT INT INT INT INT {fr->loadIncrMinMaxCmd($2,$3,$4,$5,$6);} | END_ {fr->loadIncrEndCmd();} ; macosx : PRINT_ { #ifdef _MACOSX fr->macosxPrintCmd(); #endif } ; magnifier: yesno {fr->magnifierCmd($1);} | GRAPHICS_ yesno {fr->magnifierGraphicsCmd($2);} | CURSOR_ yesno {fr->magnifierCursorCmd($2);} | COLOR_ STRING {fr->magnifierColorCmd($2);} | STRING INT INT {fr->magnifierCmd($1, $2, $3);} | UPDATE_ numeric numeric {fr->updateMagnifierCmd(Vector($2, $3));} | ZOOM_ numeric {fr->magnifierZoomCmd($2);} ; marker : CENTROID_ markerCentroid | COLOR_ STRING {fr->markerColorCmd($2);} | COPY_ {fr->markerCopyCmd();} | COMMAND_ markerFormat STRING {fr->markerCommandCmd((Base::MarkerFormat)$2,$3);} | COMMAND_ markerFormat VAR_ STRING {fr->markerCommandVarCmd((Base::MarkerFormat)$2,$4);} | COMPOSITE_ DELETE_ {fr->markerCompositeDeleteCmd();} | CREATE_ {maperr =0;} markerCreate | CUT_ {fr->markerCutCmd();} | DELETE_ {fr->markerDeleteCmd();} | DELETE_ ALL_ {fr->markerDeleteAllCmd();} | EDIT_ markerEdit | FONT_ STRING {fr->markerFontCmd($2);} | HIGHLITE_ ALL_ {fr->markerHighliteAllCmd();} | HIGHLITE_ ONLY_ numeric numeric {fr->markerHighliteOnlyCmd(Vector($3,$4));} | HIGHLITE_ TOGGLE_ numeric numeric {fr->markerHighliteToggleCmd(Vector($3,$4));} | INT ANALYSIS_ analysisMethod yesno {fr->markerAnalysisCmd($1, (Marker::AnalysisTask)$3, $4);} | INT ANGLE_ angle {fr->markerAngleCmd($1,$3);} | INT ANGLE_ angle internalSystem {fr->markerAngleCmd($1,$3);} | INT ANGLE_ angle coordSystem skyFrame {fr->markerAngleCmd($1,$3,(Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT ANNULUS_ RADIUS_ numeric numeric INT internalSystem {fr->markerAnnulusRadiusCmd($1, $4, $5, $6, (Coord::InternalSystem)$7);} | INT ANNULUS_ RADIUS_ numeric numeric INT coordSystem skyDist {fr->markerAnnulusRadiusCmd($1, $4, $5, $6, (Coord::CoordSystem)$7, (Coord::SkyDist)$8);} | INT ANNULUS_ RADIUS_ STRING coordSystem skyDist {fr->markerAnnulusRadiusCmd($1, $4,(Coord::CoordSystem)$5,(Coord::SkyDist)$6);} | INT BOXANNULUS_ RADIUS_ numeric numeric numeric INT internalSystem {fr->markerBoxAnnulusRadiusCmd($1, Vector($4, $5), Vector($6, $6*$5/$4), $7, (Coord::InternalSystem)$8);} | INT BOXANNULUS_ RADIUS_ numeric numeric numeric INT coordSystem skyDist {fr->markerBoxAnnulusRadiusCmd($1, Vector($4, $5), Vector($6, $6*$5/$4), $7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT BOXANNULUS_ RADIUS_ STRING coordSystem skyDist {fr->markerBoxAnnulusRadiusCmd($1,$4,(Coord::CoordSystem)$5,(Coord::SkyDist)$6);} | INT BOX_ RADIUS_ numeric numeric internalSystem {fr->markerBoxRadiusCmd($1, Vector($4,$5), (Coord::InternalSystem)$6);} | INT BOX_ RADIUS_ numeric numeric coordSystem skyDist {fr->markerBoxRadiusCmd($1, Vector($4,$5), (Coord::CoordSystem)$6, (Coord::SkyDist)$7);} | INT BPANDA_ EDIT_ angle angle INT numeric numeric numeric INT {fr->markerBpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10);} | INT BPANDA_ EDIT_ angle angle INT numeric numeric numeric INT internalSystem {fr->markerBpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10);} | INT BPANDA_ EDIT_ angle angle INT numeric numeric numeric INT coordSystem skyFrame {fr->markerBpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10, (Coord::CoordSystem)$11, (Coord::SkyFrame)$12);} | INT BPANDA_ EDIT_ STRING STRING coordSystem skyFrame coordSystem skyDist {fr->markerBpandaEditCmd($1, $4, $5, (Coord::CoordSystem)$6, (Coord::SkyFrame)$7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT CALLBACK_ markerCallBack STRING STRING {fr->markerCallBackCmd($1,(CallBack::Type)$3,$4,$5);} | INT CIRCLE_ RADIUS_ numeric internalSystem {fr->markerCircleRadiusCmd($1, $4, (Coord::InternalSystem)$5);} | INT CIRCLE_ RADIUS_ numeric coordSystem skyDist {fr->markerCircleRadiusCmd($1, $4, (Coord::CoordSystem)$5, (Coord::SkyDist)$6);} | INT COLOR_ STRING {fr->markerColorCmd($1,$3);} | INT COMPASS_ ARROW_ yesno yesno {fr->markerCompassArrowCmd($1,$4,$5);} | INT COMPASS_ LABEL_ STRING STRING {fr->markerCompassLabelCmd($1,$4,$5);} | INT COMPASS_ RADIUS_ numeric internalSystem {fr->markerCompassRadiusCmd($1,$4,(Coord::InternalSystem)$5);} | INT COMPASS_ RADIUS_ numeric coordSystem skyDist {fr->markerCompassRadiusCmd($1,$4,(Coord::CoordSystem)$5,(Coord::SkyDist)$6);} | INT COMPASS_ SYSTEM_ coordSystem skyFrame {fr->markerCompassSystemCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT COMPOSITE_ GLOBAL_ yesno {fr->markerCompositeCmd($1,$4);} | INT CPANDA_ EDIT_ angle angle INT numeric numeric INT {fr->markerCpandaEditCmd($1, $4, $5, $6, $7, $8, $9);} | INT CPANDA_ EDIT_ angle angle INT numeric numeric INT internalSystem {fr->markerCpandaEditCmd($1, $4, $5, $6, $7, $8, $9);} | INT CPANDA_ EDIT_ angle angle INT numeric numeric INT coordSystem skyFrame {fr->markerCpandaEditCmd($1, $4, $5, $6, $7, $8, $9, (Coord::CoordSystem)$10, (Coord::SkyFrame)$11);} | INT CPANDA_ EDIT_ STRING STRING coordSystem skyFrame coordSystem skyDist {fr->markerCpandaEditCmd($1, $4, $5, (Coord::CoordSystem)$6, (Coord::SkyFrame)$7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT CREATE_ ANNULUS_ RADIUS_ numeric numeric {fr->markerAnnulusCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ BOXANNULUS_ RADIUS_ numeric numeric {fr->markerBoxAnnulusCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ BPANDA_ ANGLE_ numeric numeric {fr->markerBpandaCreateAnglesCmd($1,Vector($5,$6));} | INT CREATE_ BPANDA_ RADIUS_ numeric numeric {fr->markerBpandaCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ ELLIPSEANNULUS_ RADIUS_ numeric numeric {fr->markerEllipseAnnulusCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ EPANDA_ ANGLE_ numeric numeric {fr->markerEpandaCreateAnglesCmd($1,Vector($5,$6));} | INT CREATE_ EPANDA_ RADIUS_ numeric numeric {fr->markerEpandaCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ CPANDA_ ANGLE_ numeric numeric {fr->markerCpandaCreateAnglesCmd($1,Vector($5,$6));} | INT CREATE_ CPANDA_ RADIUS_ numeric numeric {fr->markerCpandaCreateRadiusCmd($1,Vector($5,$6));} | INT CREATE_ POLYGON_ VERTEX_ INT numeric numeric {fr->markerPolygonCreateVertexCmd($1,$5,Vector($6,$7));} | INT DELETE_ {fr->markerDeleteCmd($1);} | INT DELETE_ ANNULUS_ INT {fr->markerAnnulusDeleteRadiusCmd($1,$4);} | INT DELETE_ BOXANNULUS_ INT {fr->markerBoxAnnulusDeleteRadiusCmd($1,$4);} | INT DELETE_ BPANDA_ INT {fr->markerBpandaDeleteCmd($1,$4);} | INT DELETE_ ELLIPSEANNULUS_ INT {fr->markerEllipseAnnulusDeleteRadiusCmd($1,$4);} | INT DELETE_ CALLBACK_ markerCallBack STRING {fr->markerDeleteCallBackCmd($1,(CallBack::Type)$4,$5);} | INT DELETE_ EPANDA_ INT {fr->markerEpandaDeleteCmd($1,$4);} | INT DELETE_ CPANDA_ INT {fr->markerCpandaDeleteCmd($1,$4);} | INT DELETE_ POLYGON_ VERTEX_ INT {fr->markerPolygonDeleteVertexCmd($1,$5);} | INT DELETE_ TAG_ {fr->markerDeleteTagCmd($1);} | INT DELETE_ TAG_ STRING {fr->markerDeleteTagCmd($1,$4);} | INT DELETE_ TAG_ INT {fr->markerDeleteTagCmd($1,$4);} | INT EDIT_ BEGIN_ INT {fr->markerEditBeginCmd($1,$4);} | INT ELLIPSE_ RADIUS_ numeric numeric internalSystem {fr->markerEllipseRadiusCmd($1, Vector($4, $5), (Coord::InternalSystem)$6);} | INT ELLIPSE_ RADIUS_ numeric numeric coordSystem skyDist {fr->markerEllipseRadiusCmd($1, Vector($4, $5), (Coord::CoordSystem)$6, (Coord::SkyDist)$7);} | INT ELLIPSEANNULUS_ RADIUS_ numeric numeric numeric INT internalSystem {fr->markerEllipseAnnulusRadiusCmd($1, Vector($4,$5), Vector($6,$6*$5/$4), $7, (Coord::InternalSystem)$8);} | INT ELLIPSEANNULUS_ RADIUS_ numeric numeric numeric INT coordSystem skyDist {fr->markerEllipseAnnulusRadiusCmd($1, Vector($4,$5), Vector($6,$6*$5/$4), $7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT ELLIPSEANNULUS_ RADIUS_ STRING coordSystem skyDist {fr->markerEllipseAnnulusRadiusCmd($1, $4, (Coord::CoordSystem)$5, (Coord::SkyDist)$6);} | INT EPANDA_ EDIT_ angle angle INT numeric numeric numeric INT {fr->markerEpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10);} | INT EPANDA_ EDIT_ angle angle INT numeric numeric numeric INT internalSystem {fr->markerEpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10);} | INT EPANDA_ EDIT_ angle angle INT numeric numeric numeric INT coordSystem skyFrame {fr->markerEpandaEditCmd($1, $4, $5, $6, Vector($7,$8), Vector($9,$9*$8/$7), $10, (Coord::CoordSystem)$11, (Coord::SkyFrame)$12);} | INT EPANDA_ EDIT_ STRING STRING coordSystem skyFrame coordSystem skyDist {fr->markerEpandaEditCmd($1, $4, $5, (Coord::CoordSystem)$6, (Coord::SkyFrame)$7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT FONT_ STRING {fr->markerFontCmd($1,$3);} | INT HIGHLITE_ {fr->markerHighliteCmd($1);} | INT HIGHLITE_ ONLY_{fr->markerHighliteOnlyCmd($1);} | INT LINE_ ARROW_ yesno yesno {fr->markerLineArrowCmd($1,$4,$5);} | INT LINE_ POINT_ internalSystem coord coord {fr->markerLineCmd($1, Vector($5), Vector($6), (Coord::InternalSystem)$4);} | INT LINE_ POINT_ coordSystem skyFrame coord coord {fr->markerLineCmd($1, Vector($6), Vector($7), (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT MOVE_ numeric numeric {fr->markerMoveCmd($1, Vector($3,$4));} | INT MOVE_ FRONT_ {fr->markerFrontCmd($1);} | INT MOVE_ BACK_ {fr->markerBackCmd($1);} | INT MOVE_ TO_ internalSystem numeric numeric {fr->markerMoveToCmd($1, Vector($5,$6), (Coord::InternalSystem)$4);} | INT MOVE_ TO_ coordSystem skyFrame coord {fr->markerMoveToCmd($1,Vector($6),(Coord::CoordSystem)$4,(Coord::SkyFrame)$5);} | INT POLYGON_ RESET_ numeric numeric internalSystem {fr->markerPolygonResetCmd($1, Vector($4,$5),(Coord::InternalSystem)$6);} | INT POLYGON_ RESET_ numeric numeric coordSystem skyDist {fr->markerPolygonResetCmd($1, Vector($4,$5), (Coord::CoordSystem)$6, (Coord::SkyDist)$7);} | INT POINT_ SHAPE_ pointShape {fr->markerPointShapeCmd($1,(Point::PointShape)$4);} | INT POINT_ SIZE_ INT {fr->markerPointSizeCmd($1,$4);} | INT PROJECTION_ internalSystem coord coord numeric {fr->markerProjectionCmd($1, Vector($4), Vector($5), (Coord::InternalSystem)$3, $6);} | INT PROJECTION_ coordSystem skyFrame coord coord numeric coordSystem skyDist {fr->markerProjectionCmd($1, Vector($5), Vector($6), (Coord::CoordSystem)$3, (Coord::SkyFrame)$4, $7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9);} | INT PROPERTY_ markerProperty yesno {fr->markerPropertyCmd($1,$3,$4);} | INT ROTATE_ BEGIN_ {fr->markerRotateBeginCmd($1);} | INT RULER_ POINT_ internalSystem coord coord {fr->markerRulerPointCmd($1, Vector($5), Vector($6), (Coord::InternalSystem)$4);} | INT RULER_ POINT_ coordSystem skyFrame coord coord {fr->markerRulerPointCmd($1, Vector($6), Vector($7), (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT RULER_ SYSTEM_ coordSystem skyFrame coordSystem skyDist {fr->markerRulerSystemCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::CoordSystem)$6, (Coord::SkyDist)$7);} | INT SELECT_ {fr->markerSelectCmd($1);} | INT SELECT_ ONLY_ {fr->markerSelectOnlyCmd($1);} | INT TAG_ STRING {fr->markerTagCmd($1,$3);} | INT TEXT_ STRING {fr->markerTextCmd($1,$3);} | INT TEXT_ ROTATE_ yesno {fr->markerTextRotateCmd($1,$4);} | INT UNHIGHLITE_ {fr->markerUnhighliteCmd($1);} | INT UNSELECT_ {fr->markerUnselectCmd($1);} | INT VECTOR_ ARROW_ yesno {fr->markerVectorArrowCmd($1,$4);} | INT VECTOR_ POINT_ internalSystem coord numeric angle {fr->markerVectorCmd($1, Vector($5), (Coord::InternalSystem)$4, $6, $7);} | INT VECTOR_ POINT_ coordSystem skyFrame coord coordSystem skyDist numeric angle {fr->markerVectorCmd($1, Vector($6), (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, $9, (Coord::CoordSystem)$7, (Coord::SkyDist)$8, $10);} | INT WIDTH_ INT {fr->markerLineWidthCmd($1,$3);} | KEY_ {fr->markerKeyCmd();} | KEY_ numeric numeric {fr->markerKeyCmd(Vector($2,$3));} | LIST_ markerList | LOAD_ markerLoad | MOVE_ markerMoveSelected | PRESERVE_ yesno {fr->markerPreserveCmd($2);} | PROPERTY_ markerProperty yesno {fr->markerPropertyCmd($2,$3);} | PROPERTY_ markerProperty yesno numeric numeric {fr->markerPropertyCmd($2,$3,Vector($4,$5));} | ROTATE_ BEGIN_ numeric numeric {fr->markerRotateBeginCmd(Vector($3,$4));} | ROTATE_ MOTION_ numeric numeric INT {fr->markerRotateMotionCmd(Vector($3,$4),$5);} | ROTATE_ END_ {fr->markerRotateEndCmd();} | SAVE_ STRING markerFormat coordSystem skyFrame skyFormat yesno {fr->markerSaveCmd($2, (Base::MarkerFormat)$3, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6, $7);} | SAVE_ TEMPLATE_ STRING {fr->markerSaveTemplateCmd($3);} | SELECT_ markerSelect | SHOW_ markerShow | STRING COLOR_ STRING {fr->markerColorCmd($1,$3);} | STRING COPY_ {fr->markerCopyCmd($1);} | STRING DELETE_ {fr->markerDeleteCmd($1);} | STRING CUT_ {fr->markerCutCmd($1);} | STRING FONT_ STRING {fr->markerFontCmd($1,$3);} | STRING HIGHLITE_ {fr->markerHighliteCmd($1);} | STRING HIGHLITE_ ONLY_ {fr->markerHighliteOnlyCmd($1);} | STRING MOVE_ numeric numeric {fr->markerMoveCmd($1,Vector($3,$4));} | STRING MOVE_ FRONT_ {fr->markerFrontCmd($1);} | STRING MOVE_ BACK_ {fr->markerBackCmd($1);} | STRING MOVE_ TO_ internalSystem coord {fr->markerMoveToCmd($1,Vector($5),(Coord::InternalSystem)$4);} | STRING MOVE_ TO_ coordSystem skyFrame coord {fr->markerMoveToCmd($1,Vector($6),(Coord::CoordSystem)$4,(Coord::SkyFrame)$5);} | STRING PROPERTY_ markerProperty yesno {fr->markerPropertyCmd($1,$3,$4);} | STRING SELECT_ {fr->markerSelectCmd($1);} | STRING SELECT_ ONLY_ {fr->markerSelectOnlyCmd($1);} | STRING UNHIGHLITE_ {fr->markerUnhighliteCmd($1);} | STRING UNSELECT_ {fr->markerUnselectCmd($1);} | TAG_ EDIT_ STRING STRING {fr->markerTagEditCmd($3,$4);} | TAG_ DELETE_ STRING {fr->markerTagDeleteCmd($3);} | TAG_ DELETE_ ALL_ {fr->markerTagDeleteAllCmd();} | TAG_ STRING {fr->markerTagCmd($2);} | TAG_ UPDATE_ STRING {fr->markerTagUpdateCmd($3);} | PASTE_ {fr->markerPasteCmd();} | PASTE_ coordSystem coordSystem {fr->markerPasteCmd((Coord::CoordSystem)$2, (Coord::CoordSystem)$3);} | UNDO_ {fr->markerUndoCmd();} | UNHIGHLITE_ ALL_ {fr->markerUnhighliteAllCmd();} | UNSELECT_ ALL_ {fr->markerUnselectAllCmd();} | WIDTH_ INT {fr->markerLineWidthCmd($2);} ; markerCallBack : SELECT_ {$$ = CallBack::SELECTCB;} | UNSELECT_ {$$ = CallBack::UNSELECTCB;} | HIGHLITE_ {$$ = CallBack::HIGHLITECB;} | UNHIGHLITE_ {$$ = CallBack::UNHIGHLITECB;} | BEGIN_ MOVE_ {$$ = CallBack::MOVEBEGINCB;} | MOVE_ {$$ = CallBack::MOVECB;} | END_ MOVE_ {$$ = CallBack::MOVEENDCB;} | BEGIN_ EDIT_ {$$ = CallBack::EDITBEGINCB;} | EDIT_ {$$ = CallBack::EDITCB;} | END_ EDIT_ {$$ = CallBack::EDITENDCB;} | BEGIN_ ROTATE_ {$$ = CallBack::ROTATEBEGINCB;} | ROTATE_ {$$ = CallBack::ROTATECB;} | END_ ROTATE_ {$$ = CallBack::ROTATEENDCB;} | DELETE_ {$$ = CallBack::DELETECB;} | TEXT_ {$$ = CallBack::TEXTCB;} | COLOR_ {$$ = CallBack::COLORCB;} | WIDTH_ {$$ = CallBack::LINEWIDTHCB;} | PROPERTY_ {$$ = CallBack::PROPERTYCB;} | FONT_ {$$ = CallBack::FONTCB;} | KEY_ {$$ = CallBack::KEYCB;} | UPDATE_ {$$ = CallBack::UPDATECB;} ; markerCentroid : /* empty */ {fr->markerCentroidCmd();} | INT {fr->markerCentroidCmd($1);} | AUTO_ yesno {fr->markerCentroidAutoCmd($2);} | RADIUS_ numeric {fr->markerCentroidRadiusCmd($2);} | ITERATION_ INT {fr->markerCentroidIterationCmd($2);} | OPTION_ INT numeric { fr->markerCentroidIterationCmd($2); fr->markerCentroidRadiusCmd($3); } ; markerCreate : CIRCLE_ numeric numeric numeric markerProperties {fr->createCircleCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | ELLIPSE_ numeric numeric numeric numeric optangle markerProperties {fr->createEllipseCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), Vector($4,$5), $6, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | BOX_ numeric numeric numeric numeric optangle markerProperties {fr->createBoxCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), Vector($4,$5), $6, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | POLYGON_ numeric numeric numeric numeric markerProperties {fr->createPolygonCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), Vector($4,$5), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | LINE_ numeric numeric numeric numeric markerProperties {fr->createLineCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), fr->mapToRef(Vector($4,$5),Coord::CANVAS), 0, 0, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | VECTOR_ numeric numeric numeric numeric markerProperties {fr->createVectCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), fr->mapToRef(Vector($4,$5),Coord::CANVAS), 1, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | TEXT_ numeric numeric optangle markerProperties {fr->createTextCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4, 1, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | CIRCLE_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::CIRCLE, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | BOX_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::BOX, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | DIAMOND_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::DIAMOND, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | CROSS_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::CROSS, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | 'X' POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::EX, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | ARROW_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::ARROW, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | BOXCIRCLE_ POINT_ numeric numeric pointSize markerProperties {fr->createPointCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), Point::BOXCIRCLE, $5, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | RULER_ numeric numeric numeric numeric coordSystem skyFrame coordSystem skyDist markerProperties {fr->createRulerCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), fr->mapToRef(Vector($4,$5),Coord::CANVAS), (Coord::CoordSystem)$6, (Coord::SkyFrame)$7, (Coord::CoordSystem)$8, (Coord::SkyDist)$9, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | COMPASS_ numeric numeric numeric coordSystem skyFrame markerProperties {fr->createCompassCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4, "N", "E", 1, 1, (Coord::CoordSystem)$5, (Coord::SkyFrame)$6, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | PROJECTION_ numeric numeric numeric numeric numeric markerProperties {fr->createProjectionCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), fr->mapToRef(Vector($4,$5),Coord::CANVAS), $6, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | ANNULUS_ numeric numeric numeric numeric INT markerProperties {fr->createAnnulusCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4,$5,$6, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | ELLIPSEANNULUS_ numeric numeric numeric numeric numeric INT optangle markerProperties {fr->createEllipseAnnulusCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), Vector($4,$5), Vector($6,$6*$4/$5),$7, $8, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | BOXANNULUS_ numeric numeric numeric numeric numeric INT optangle markerProperties {fr->createBoxAnnulusCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), Vector($4,$5),Vector($6,$6*$4/$5),$7, $8, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | CPANDA_ numeric numeric angle angle INT numeric numeric INT markerProperties {fr->createCpandaCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4,$5,$6, $7,$8,$9, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | EPANDA_ numeric numeric angle angle INT numeric numeric numeric INT optangle markerProperties {fr->createEpandaCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4,$5,$6, Vector($7,$8), Vector($9,$9*$7/$8),$10, $11, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | BPANDA_ numeric numeric angle angle INT numeric numeric numeric INT optangle markerProperties {fr->createBpandaCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $4,$5,$6, Vector($7,$8), Vector($9,$9*$7/$8),$10, $11, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | COMPOSITE_ markerProperties {fr->createCompositeCmd( currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);} | TEMPLATE_ markerCreateTemplate ; markerCreateTemplate : STRING numeric numeric {fr->createTemplateCmd(fr->mapToRef(Vector($2,$3),Coord::CANVAS), $1);} | VAR_ STRING numeric numeric {fr->createTemplateVarCmd(fr->mapToRef(Vector($3,$4),Coord::CANVAS), $2);} | numeric numeric VAR_ STRING { // backward compatibility fr->createTemplateVarCmd(fr->mapToRef(Vector($1,$2),Coord::CANVAS), $4); } | STRING coordSystem skyFrame coord {fr->createTemplateCmd(Vector($4),(Coord::CoordSystem)$2,(Coord::SkyFrame)$3, $1);} ; markerDash : INT INT {$$[0] = $1; $$[1] = $2;} ; markerEdit : BEGIN_ numeric numeric INT {fr->markerEditBeginCmd(Vector($2,$3),$4);} | MOTION_ numeric numeric INT {fr->markerEditMotionCmd(Vector($2,$3),$4);} | END_ {fr->markerEditEndCmd();} ; markerFormat : DS9_ {$$ = Base::DS9;} | XML_ {$$ = Base::XML;} | CIAO_ {$$ = Base::CIAO;} | SAOTNG_ {$$ = Base::SAOTNG;} | SAOIMAGE_ {$$ = Base::SAOIMAGE;} | PROS_ {$$ = Base::PROS;} | XY_ {$$ = Base::RAWXY;} ; markerGet : CENTROID_ markerGetCentroid | COLOR_ {fr->getMarkerColorCmd();} | FONT_ {fr->getMarkerFontCmd();} | HANDLE_ numeric numeric {fr->getMarkerHandleCmd(Vector($2,$3));} | ID_ numeric numeric {fr->getMarkerIdCmd(Vector($2,$3));} | INT ANALYSIS_ PLOT2D_ STRING STRING STRING STRING coordSystem skyFrame analysisParam {fr->getMarkerAnalysisPlot2dCmd($1,$4,$5,$6,$7,(Coord::CoordSystem)$8, (Coord::SkyFrame)$9, (Marker::AnalysisMethod)$10);} | INT ANALYSIS_ PLOT3D_ STRING STRING coordSystem analysisParam {fr->getMarkerAnalysisPlot3dCmd($1,$4,$5,(Coord::CoordSystem)$6,(Marker::AnalysisMethod)$7);} | INT ANALYSIS_ CPANDA_ coordSystem {fr->getMarkerAnalysisPandaCmd($1,(Coord::CoordSystem)$4);} | INT ANALYSIS_ RADIAL_ STRING STRING STRING coordSystem {fr->getMarkerAnalysisRadialCmd($1,$4,$5,$6,(Coord::CoordSystem)$7);} | INT ANALYSIS_ STATS_ coordSystem {fr->getMarkerAnalysisStatsCmd($1,(Coord::CoordSystem)$4);} | ID_ ALL_ {fr->getMarkerIdAllCmd();} | INT ANGLE_ {fr->getMarkerAngleCmd($1);} | INT ANGLE_ internalSystem {fr->getMarkerAngleCmd($1);} | INT ANGLE_ coordSystem skyFrame {fr->getMarkerAngleCmd($1,(Coord::CoordSystem)$3, (Coord::SkyFrame)$4);} | INT ANNULUS_ RADIUS_ internalSystem {fr->getMarkerAnnulusRadiusCmd($1, (Coord::InternalSystem)$4);} | INT ANNULUS_ RADIUS_ coordSystem skyDist {fr->getMarkerAnnulusRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT BOXANNULUS_ RADIUS_ internalSystem {fr->getMarkerBoxAnnulusRadiusCmd($1,(Coord::InternalSystem)$4);} | INT BOXANNULUS_ RADIUS_ coordSystem skyDist {fr->getMarkerBoxAnnulusRadiusCmd($1,(Coord::CoordSystem)$4,(Coord::SkyDist)$5);} | INT BOX_ RADIUS_ internalSystem {fr->getMarkerBoxRadiusCmd($1,(Coord::InternalSystem)$4);} | INT BOX_ RADIUS_ coordSystem skyDist {fr->getMarkerBoxRadiusCmd($1,(Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT BPANDA_ ANGLE_ {fr->getMarkerBpandaAnglesCmd($1);} | INT BPANDA_ ANGLE_ internalSystem {fr->getMarkerBpandaAnglesCmd($1);} | INT BPANDA_ ANGLE_ coordSystem skyFrame {fr->getMarkerBpandaAnglesCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT BPANDA_ RADIUS_ internalSystem {fr->getMarkerBpandaRadiusCmd($1, (Coord::InternalSystem)$4);} | INT BPANDA_ RADIUS_ coordSystem skyDist {fr->getMarkerBpandaRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT CENTER_ internalSystem {fr->getMarkerCenterCmd($1, (Coord::InternalSystem)$3);} | INT CENTER_ coordSystem skyFrame skyFormat {fr->getMarkerCenterCmd($1, (Coord::CoordSystem)$3, (Coord::SkyFrame)$4, (Coord::SkyFormat)$5);} | INT CIRCLE_ RADIUS_ internalSystem {fr->getMarkerCircleRadiusCmd($1, (Coord::InternalSystem)$4);} | INT CIRCLE_ RADIUS_ coordSystem skyDist {fr->getMarkerCircleRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT COLOR_ {fr->getMarkerColorCmd($1);} | INT COMPASS_ ARROW_ {fr->getMarkerCompassArrowCmd($1);} | INT COMPASS_ LABEL_ {fr->getMarkerCompassLabelCmd($1);} | INT COMPASS_ RADIUS_ internalSystem {fr->getMarkerCompassRadiusCmd($1, (Coord::InternalSystem)$4);} | INT COMPASS_ RADIUS_ coordSystem skyDist {fr->getMarkerCompassRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT COMPASS_ SYSTEM_ {fr->getMarkerCompassSystemCmd($1);} | INT COMPOSITE_ GLOBAL_ {fr->getMarkerCompositeCmd($1);} | INT CPANDA_ ANGLE_ {fr->getMarkerCpandaAnglesCmd($1);} | INT CPANDA_ ANGLE_ internalSystem {fr->getMarkerCpandaAnglesCmd($1);} | INT CPANDA_ ANGLE_ coordSystem skyFrame {fr->getMarkerCpandaAnglesCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT CPANDA_ RADIUS_ internalSystem {fr->getMarkerCpandaRadiusCmd($1, (Coord::InternalSystem)$4);} | INT CPANDA_ RADIUS_ coordSystem skyDist {fr->getMarkerCpandaRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT ELLIPSE_ RADIUS_ internalSystem {fr->getMarkerEllipseRadiusCmd($1, (Coord::InternalSystem)$4);} | INT ELLIPSE_ RADIUS_ coordSystem skyDist {fr->getMarkerEllipseRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT ELLIPSEANNULUS_ RADIUS_ internalSystem {fr->getMarkerEllipseAnnulusRadiusCmd($1, (Coord::InternalSystem)$4);} | INT ELLIPSEANNULUS_ RADIUS_ coordSystem skyDist {fr->getMarkerEllipseAnnulusRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT EPANDA_ ANGLE_ {fr->getMarkerEpandaAnglesCmd($1);} | INT EPANDA_ ANGLE_ internalSystem {fr->getMarkerEpandaAnglesCmd($1);} | INT EPANDA_ ANGLE_ coordSystem skyFrame {fr->getMarkerEpandaAnglesCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} | INT EPANDA_ RADIUS_ internalSystem {fr->getMarkerEpandaRadiusCmd($1, (Coord::InternalSystem)$4);} | INT EPANDA_ RADIUS_ coordSystem skyDist {fr->getMarkerEpandaRadiusCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT FONT_ {fr->getMarkerFontCmd($1);} | INT HIGHLITE_ {fr->getMarkerHighlitedCmd($1);} | INT LINE_ ARROW_ {fr->getMarkerLineArrowCmd($1);} | INT LINE_ LENGTH_ coordSystem skyDist {fr->getMarkerLineLengthCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT LINE_ POINT_ internalSystem {fr->getMarkerLineCmd($1, (Coord::InternalSystem)$4);} | INT LINE_ POINT_ coordSystem skyFrame skyFormat {fr->getMarkerLineCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6);} | INT MAP_ LENGTH_ numeric coordSystem skyDist {fr->getMarkerMapLenFromRefCmd($1, $4, (Coord::CoordSystem)$5,(Coord::SkyDist)$6);} | INT POINT_ SHAPE_ {fr->getMarkerPointShapeCmd($1);} | INT POINT_ SIZE_ {fr->getMarkerPointSizeCmd($1);} | INT PROJECTION_ POINT_ internalSystem {fr->getMarkerProjectionPointsCmd($1, (Coord::InternalSystem)$4);} | INT PROJECTION_ POINT_ coordSystem skyFrame skyFormat {fr->getMarkerProjectionPointsCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6);} | INT PROJECTION_ LENGTH_ coordSystem skyDist {fr->getMarkerProjectionLengthCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT PROJECTION_ THICK_ internalSystem {fr->getMarkerProjectionWidthCmd($1, (Coord::InternalSystem)$4);} | INT PROJECTION_ THICK_ coordSystem skyDist {fr->getMarkerProjectionWidthCmd($1,(Coord::CoordSystem)$4,(Coord::SkyDist)$5);} | INT PROPERTY_ {fr->getMarkerPropertyCmd($1);} | INT PROPERTY_ markerProperty {fr->getMarkerPropertyCmd($1,$3);} | INT RULER_ LENGTH_ coordSystem skyDist {fr->getMarkerRulerLengthCmd($1,(Coord::CoordSystem)$4,(Coord::SkyDist)$5);} | INT RULER_ POINT_ internalSystem {fr->getMarkerRulerPointCmd($1, (Coord::InternalSystem)$4);} | INT RULER_ POINT_ coordSystem skyFrame skyFormat {fr->getMarkerRulerPointCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6);} | INT RULER_ SYSTEM_ {fr->getMarkerRulerSystemCmd($1);} | INT SELECT_ {fr->getMarkerSelectedCmd($1);} | INT TAG_ {fr->getMarkerTagCmd($1);} | INT TAG_ INT {fr->getMarkerTagCmd($1,$3);} | INT TEXT_ {fr->getMarkerTextCmd($1);} | INT TEXT_ ROTATE_ {fr->getMarkerTextRotateCmd($1);} | INT TYPE_ {fr->getMarkerTypeCmd($1);} | INT VECTOR_ ARROW_ {fr->getMarkerVectorArrowCmd($1);} | INT VECTOR_ LENGTH_ coordSystem skyDist {fr->getMarkerVectorLengthCmd($1, (Coord::CoordSystem)$4, (Coord::SkyDist)$5);} | INT VECTOR_ POINT_ internalSystem {fr->getMarkerVectorCmd($1, (Coord::InternalSystem)$4);} | INT VECTOR_ POINT_ coordSystem skyFrame skyFormat {fr->getMarkerVectorCmd($1, (Coord::CoordSystem)$4, (Coord::SkyFrame)$5, (Coord::SkyFormat)$6);} | INT WIDTH_ {fr->getMarkerLineWidthCmd($1);} | HIGHLITE_ markerGetHighlite | HIGHLITE_ NUMBER_ {fr->getMarkerHighlitedNumberCmd();} | NUMBER_ {fr->getMarkerNumberCmd();} | POLYGON_ SEGMENT_ numeric numeric {fr->getMarkerPolygonSegmentCmd(Vector($3,$4));} | PRESERVE_ {fr->getMarkerPreserveCmd();} | PROPERTY_ markerProperty {fr->getMarkerPropertyCmd($2);} | SELECT_ markerGetSelect | SELECT_ NUMBER_ {fr->getMarkerSelectedNumberCmd();} | SHOW_ markerGetShow | STRING COLOR_ {fr->getMarkerColorCmd($1);} | STRING FONT_ {fr->getMarkerFontCmd($1);} | STRING ID_ {fr->getMarkerIdCmd($1);} | STRING PROPERTY_ markerProperty {fr->getMarkerPropertyCmd($1,$3);} | STRING TAG_ {fr->getMarkerTagCmd($1);} | STRING TAG_ NUMBER_ {fr->getMarkerTagNumberCmd($1);} | TAG_ ALL_ {fr->getMarkerTagsCmd();} | TAG_ DEFAULT_ NAME_ {fr->getMarkerTagDefaultNameCmd();} | WIDTH_ {fr->getMarkerLineWidthCmd();} ; markerGetCentroid : AUTO_ {fr->getMarkerCentroidAutoCmd();} | RADIUS_ {fr->getMarkerCentroidRadiusCmd();} | ITERATION_ {fr->getMarkerCentroidIterationCmd();} | OPTION_ {fr->getMarkerCentroidOptionCmd();} ; markerGetHighlite : /* empty */ {fr->getMarkerHighlitedCmd();} | numeric numeric {fr->getMarkerHighlitedCmd(Vector($1,$2));} ; markerGetSelect : /* empty */ {fr->getMarkerSelectedCmd();} | numeric numeric {fr->getMarkerSelectedCmd(Vector($1,$2));} ; markerGetShow : /* empty */ {fr->getMarkerShowCmd();} | TEXT_ {fr->getMarkerShowTextCmd();} ; markerInitProp : { strncpy(currentFont, "helvetica 10 normal roman", 32); strncpy(currentColor, "green", 16); currentDash[0] = 8; currentDash[1] = 3; currentWidth = 1; strncpy(currentText, "", 80); currentProps = defaultProps; taglist.deleteAll(); cblist.deleteAll(); } ; markerLayer : /* empty */ {fr->markerLayerCmd(Base::USER);} | POINTER_ {fr->markerLayerCmd(Base::USER);} | USER_ {fr->markerLayerCmd(Base::USER);} | CATALOG_ {fr->markerLayerCmd(Base::CATALOG);} ; markerList : markerFormat coordSystem skyFrame skyFormat yesno markerQuery markerTags {fr->markerListCmd((Base::MarkerFormat)$1, (Coord::CoordSystem)$2, (Coord::SkyFrame)$3, (Coord::SkyFormat)$4, $5, 0, propQMask, propQValue, taglist);} | SELECT_ markerFormat coordSystem skyFrame skyFormat yesno markerQuery markerTags {fr->markerListCmd((Base::MarkerFormat)$2, (Coord::CoordSystem)$3, (Coord::SkyFrame)$4, (Coord::SkyFormat)$5, $6, 1, propQMask, propQValue, taglist);} ; markerLoad : markerFormat STRING {fr->markerLoadCmd((Base::MarkerFormat)$1,$2);} | markerFormat STRING coordSystem skyFrame {fr->markerLoadCmd((Base::MarkerFormat)$1,$2, (Coord::CoordSystem)$3,(Coord::SkyFrame)$4);} | markerFormat INT {fr->markerLoadCmd((Base::MarkerFormat)$1,$2);} | markerFormat INT coordSystem skyFrame {fr->markerLoadCmd((Base::MarkerFormat)$1,$2, (Coord::CoordSystem)$3,(Coord::SkyFrame)$4);} | FITS_ STRING STRING markerDash INT STRING {fr->markerLoadFitsCmd($2, $3, $4, $5, $6);} ; markerMoveSelected : numeric numeric {fr->markerMoveCmd(Vector($1,$2));} | FRONT_ {fr->markerFrontCmd();} | BACK_ {fr->markerBackCmd();} | BEGIN_ numeric numeric {fr->markerMoveBeginCmd(Vector($2,$3));} | MOTION_ numeric numeric {fr->markerMoveMotionCmd(Vector($2,$3));} | END_ {fr->markerMoveEndCmd();} | TO_ internalSystem coord {fr->markerMoveToCmd(Vector($3), (Coord::InternalSystem)$2);} | TO_ coordSystem skyFrame coord {fr->markerMoveToCmd(Vector($4), (Coord::CoordSystem)$2, (Coord::SkyFrame)$3);} ; markerProps : markerProps markerProp | markerProp ; markerProp : markerProperty '=' yesno {setProps(&currentProps,$1,$3);} | COLOR_ '=' STRING {strncpy(currentColor,$3,16);} | DASHLIST_ '=' INT INT {currentDash[0]=$3;currentDash[1]=$4;} | WIDTH_ '=' INT {currentWidth = $3;} | FONT_ '=' STRING {strncpy(currentFont,$3,32);} | TEXT_ '=' STRING {strncpy(currentText,$3,80);} | tag | callback ; markerProperty : NONE_ {$$ = Marker::NONE;} | SELECT_ {$$ = Marker::SELECT;} | HIGHLITE_ {$$ = Marker::HIGHLITE;} | DASH_ {$$ = Marker::DASH;} | FIXED_ {$$ = Marker::FIXED;} | EDIT_ {$$ = Marker::EDIT;} | MOVE_ {$$ = Marker::MOVE;} | ROTATE_ {$$ = Marker::ROTATE;} | DELETE_ {$$ = Marker::DELETE;} | INCLUDE_ {$$ = Marker::INCLUDE;} | SOURCE_ {$$ = Marker::SOURCE;} ; markerProperties : /* empty */ markerInitProp | markerInitProp markerProps ; markerQuery: /* empty */ {propQMask=0;propQValue=0;} | {propQMask=0;propQValue=0;} queries ; markerSelect : ALL_ {fr->markerSelectAllCmd();} | ONLY_ numeric numeric {fr->markerSelectOnlyCmd(Vector($2,$3));} | TOGGLE_ {fr->markerSelectToggleCmd();} | TOGGLE_ numeric numeric {fr->markerSelectToggleCmd(Vector($2,$3));} ; markerShow : yesno {fr->markerShowCmd($1);} | TEXT_ yesno {fr->markerShowTextCmd($2);} ; queries : queries query | query ; query : markerProperty '=' yesno {propQMask |= $1; setProps(&propQValue,$1,$3);} ; markerTags: /* empty */ {taglist.deleteAll()} | {taglist.deleteAll()} tags ; tags : tags tag | tag ; tag : TAG_ '=' STRING {taglist.append(new Tag($3));} ; callback : CALLBACK_ '=' markerCallBack STRING STRING {cblist.append( new CallBack(fr->getInterp(),(CallBack::Type)$3,$4,$5));} ; mask : CLEAR_ {fr->maskClearCmd();} | COLOR_ STRING {fr->maskColorCmd($2);} | MARK_ INT {fr->maskMarkCmd($2);} | TRANSPARENCY_ numeric {fr->maskTransparencyCmd($2);} ; orient : 'X' {fr->orientCmd(Coord::XX);} | 'Y' {fr->orientCmd(Coord::YY);} | XY_ {fr->orientCmd(Coord::XY);} | NONE_ {fr->orientCmd(Coord::NORMAL);} ; pan : numeric numeric numeric numeric {fr->panCmd(Vector($1,$2),Vector($3,$4));} | numeric numeric {fr->panCmd(Vector($1,$2));} | internalSystem numeric numeric { // backward compatibility fr->panCmd(Vector($2,$3)); } | coordSystem skyFrame coord {fr->panCmd(Vector($3), (Coord::CoordSystem)$1, (Coord::SkyFrame)$2);} | TO_ panTo | BBOX_ numeric numeric {fr->panBBoxCmd(Vector($2,$3));} | MOTION_ panMotion | PRESERVE_ yesno {fr->panPreserveCmd($2);} ; panTo : numeric numeric {fr->panToCmd(Vector($1,$2));} | internalSystem numeric numeric { // backward compatibility fr->panToCmd(Vector($2,$3)); } | coordSystem skyFrame coord {fr->panToCmd(Vector($3), (Coord::CoordSystem)$1, (Coord::SkyFrame)$2);} ; panMotion : BEGIN_ numeric numeric {fr->panBeginCmd(Vector($2,$3));} | numeric numeric {fr->panMotionCmd(Vector($1,$2));} | END_ numeric numeric {fr->panEndCmd(Vector($2,$3));} ; panner : yesno {fr->pannerCmd($1);} | WCS_ wcsSystem skyFrame { // backward compatibility fr->pannerCmd((Coord::CoordSystem)$2,(Coord::SkyFrame)$3); } | STRING INT INT {fr->pannerCmd($1, $2, $3);} | UPDATE_ {fr->updatePannerCmd();} ; postscript : COLORSPACE_ pscolorspace {fr->psColorSpaceCmd((Widget::PSColorSpace)$2);} | LEVEL_ INT {fr->psLevelCmd($2);} | RESOLUTION_ INT {fr->psResolutionCmd($2);} | SCALE_ numeric {fr->psScaleCmd($2);} ; pscolorspace : BW_ {$$ = Widget::BW;} | GRAY_ {$$ = Widget::GRAY;} | RGB_ {$$ = Widget::RGB;} | CMYK_ {$$ = Widget::CMYK;} ; region : HIGHLITE_ regionHighlite | SELECT_ regionSelect ; regionHighlite : BEGIN_ numeric numeric {fr->regionHighliteBeginCmd(Vector($2,$3));} | MOTION_ numeric numeric {fr->regionHighliteMotionCmd(Vector($2,$3));} | END_ {fr->regionHighliteEndCmd();} | SHIFT_ END_ {fr->regionHighliteShiftEndCmd();} ; regionSelect : BEGIN_ numeric numeric {fr->regionSelectBeginCmd(Vector($2,$3));} | MOTION_ numeric numeric {fr->regionSelectMotionCmd(Vector($2,$3));} | END_ {fr->regionSelectEndCmd();} | SHIFT_ END_ {fr->regionSelectShiftEndCmd();} ; renderMethod: MIP_ {$$ = Frame3dBase::MIP;} | AIP_ {$$ = Frame3dBase::AIP;} ; rgb : CHANNEL_ STRING {fr->setRGBChannelCmd($2);} | SYSTEM_ coordSystem {fr->setRGBSystemCmd((Coord::CoordSystem)$2);} | VIEW_ INT INT INT {fr->setRGBViewCmd($2,$3,$4);} ; rotate : numeric {fr->rotateCmd(degToRad($1));} | numeric DEGREES_ {fr->rotateCmd(degToRad($1));} | MOTION_ rotateMotion | TO_ numeric {fr->rotateToCmd(degToRad($2));} | TO_ numeric DEGREES_ {fr->rotateToCmd(degToRad($2));} ; rotateMotion : BEGIN_ {fr->rotateBeginCmd();} | numeric {fr->rotateMotionCmd(degToRad($1));} | END_ {fr->rotateEndCmd();} ; save : ARRAY_ saveArray | FITS_ saveFits | NRRD_ saveNRRD | PHOTO_ STRING {fr->savePhotoCmd($2);} ; saveArray : FILE_ STRING endian {fr->saveArrayFileCmd($2, (FitsFile::ArchType)$3);} | CHANNEL_ STRING endian {fr->saveArrayChannelCmd($2, (FitsFile::ArchType)$3);} | SOCKET_ INT endian {fr->saveArraySocketCmd($2, (FitsFile::ArchType)$3);} | RGB_ CUBE_ saveArrayRGBCube ; saveArrayRGBCube : FILE_ STRING endian {fr->saveArrayRGBCubeFileCmd($2, (FitsFile::ArchType)$3);} | CHANNEL_ STRING endian {fr->saveArrayRGBCubeChannelCmd($2, (FitsFile::ArchType)$3);} | SOCKET_ INT endian {fr->saveArrayRGBCubeSocketCmd($2, (FitsFile::ArchType)$3);} saveFits: /* empty */ saveFitsImage | IMAGE_ saveFitsImage | TABLE_ saveFitsTable | SLICE_ saveFitsSlice | EXT_ CUBE_ saveFitsExtCube | MOSAIC_ saveFitsMosaic | RGB_ IMAGE_ saveFitsRGBImage | RGB_ CUBE_ saveFitsRGBCube | RESAMPLE_ saveFitsResample ; saveFitsImage : FILE_ STRING {fr->saveFitsFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsChannelCmd($2);} | SOCKET_ INT {fr->saveFitsSocketCmd($2);} ; saveFitsTable : FILE_ STRING {fr->saveFitsTableFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsTableChannelCmd($2);} | SOCKET_ INT {fr->saveFitsTableSocketCmd($2);} ; saveFitsSlice : FILE_ STRING {fr->saveFitsSliceFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsSliceChannelCmd($2);} | SOCKET_ INT {fr->saveFitsSliceSocketCmd($2);} ; saveFitsExtCube : FILE_ STRING {fr->saveFitsExtCubeFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsExtCubeChannelCmd($2);} | SOCKET_ INT {fr->saveFitsExtCubeSocketCmd($2);} ; saveFitsMosaic : IMAGE_ saveFitsMosaicImage | FILE_ STRING INT {fr->saveFitsMosaicFileCmd($2,$3);} | CHANNEL_ STRING INT {fr->saveFitsMosaicChannelCmd($2,$3);} | SOCKET_ INT INT {fr->saveFitsMosaicSocketCmd($2,$3);} ; saveFitsMosaicImage : FILE_ STRING {fr->saveFitsMosaicImageFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsMosaicImageChannelCmd($2);} | SOCKET_ INT {fr->saveFitsMosaicImageSocketCmd($2);} ; saveFitsRGBImage : FILE_ STRING {fr->saveFitsRGBImageFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsRGBImageChannelCmd($2);} | SOCKET_ INT {fr->saveFitsRGBImageSocketCmd($2);} ; saveFitsRGBCube : FILE_ STRING {fr->saveFitsRGBCubeFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsRGBCubeChannelCmd($2);} | SOCKET_ INT {fr->saveFitsRGBCubeSocketCmd($2);} ; saveFitsResample : FILE_ STRING {fr->saveFitsResampleFileCmd($2);} | CHANNEL_ STRING {fr->saveFitsResampleChannelCmd($2);} | SOCKET_ INT {fr->saveFitsResampleSocketCmd($2);} ; saveNRRD : FILE_ STRING endian {fr->saveNRRDFileCmd($2, (FitsFile::ArchType)$3);} | CHANNEL_ STRING endian {fr->saveNRRDChannelCmd($2, (FitsFile::ArchType)$3);} | SOCKET_ INT endian {fr->saveNRRDSocketCmd($2, (FitsFile::ArchType)$3);} ; smooth : smoothFunction INT {fr->smoothCmd((FitsImage::SmoothFunction)$1,$2);} | DELETE_ {fr->smoothDeleteCmd();} ; smoothFunction : BOXCAR_ {$$ = FitsImage::BOXCAR;} | GAUSSIAN_ {$$ = FitsImage::GAUSSIAN;} | TOPHAT_ {$$ = FitsImage::TOPHAT;} ; update : /* empty */ {fr->updateFitsCmd(0);} | INT numeric numeric numeric numeric {fr->updateFitsCmd($1,BBox($2,$3,$4,$5),0);} | NOW_ {fr->updateFitsCmd(1);} | NOW_ INT numeric numeric numeric numeric {fr->updateFitsCmd($2,BBox($3,$4,$5,$6),1);} | FITS_ SLICE_ updateFitsSlice ; updateFitsSlice : INT {fr->sliceCmd(2, $1);} | INT INT {fr->sliceCmd($1, $2);} ; warp : numeric numeric {fr->warpCmd(Vector($1,$2));} | TO_ numeric numeric {fr->warpToCmd(Vector($2,$3));} ; wcs : wcsSystem skyFrame skyFormat {fr->wcsCmd((Coord::CoordSystem)$1, (Coord::SkyFrame)$2, (Coord::SkyFormat)$3);} | ALIGN_ wcsAlign | RESET_ INT {fr->wcsResetCmd($2);} | REPLACE_ wcsReplace | APPEND_ wcsAppend ; wcsAppend : INT INT {fr->wcsAppendCmd($1,$2);} | INT STRING {fr->wcsAppendCmd($1,$2);} | TEXT_ INT STRING {fr->wcsAppendTxtCmd($2,$3);} ; wcsReplace : INT INT {fr->wcsReplaceCmd($1,$2);} | INT STRING {fr->wcsReplaceCmd($1,$2);} | TEXT_ INT STRING {fr->wcsReplaceTxtCmd($2,$3);} ; wcsAlign : INT {fr->wcsAlignCmd($1);} | INT wcsSystem skyFrame { // used by backup fr->wcsAlignCmd($1, (Coord::CoordSystem)$2, (Coord::SkyFrame)$3); } | INT POINTER wcsSystem skyFrame { fr->wcsAlignCmd($1, (FitsImage*)$2, (Coord::CoordSystem)$3, (Coord::SkyFrame)$4); } ; win32 : PRINT_ { #ifdef _WIN32 fr->win32PrintCmd(); #endif } ; zoom : numeric numeric {fr->zoomCmd(Vector($1,$2));} | numeric numeric ABOUT_ numeric numeric {fr->zoomAboutCmd(Vector($1,$2),Vector($4,$5));} | numeric numeric ABOUT_ internalSystem numeric numeric { // backward compatibility fr->zoomAboutCmd(Vector($1,$2),Vector($5,$6)); } | numeric numeric ABOUT_ coordSystem skyFrame coord {fr->zoomAboutCmd(Vector($1,$2),Vector($6), (Coord::CoordSystem)$4,(Coord::SkyFrame)$5);} | TO_ zoomTo ; zoomTo : FIT_ {fr->zoomToFitCmd(1);} | FIT_ numeric {fr->zoomToFitCmd($2);} | numeric numeric {fr->zoomToCmd(Vector($1,$2));} | numeric numeric ABOUT_ numeric numeric {fr->zoomToAboutCmd(Vector($1,$2),Vector($4,$5));} | numeric numeric ABOUT_ internalSystem numeric numeric { // backward compatibility fr->zoomToAboutCmd(Vector($1,$2),Vector($5,$6)); } | numeric numeric ABOUT_ coordSystem skyFrame coord {fr->zoomToAboutCmd(Vector($1,$2), Vector($6), (Coord::CoordSystem)$4, (Coord::SkyFrame)$5);} ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } �����������������������������������������������������������������������������������������������./saods9/saotk/frame/frblt.C������������������������������������������������������������������������0000644�0001750�0001750�00000052350�12107012362�014532� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "base.h" #include "context.h" #include "fitsimage.h" #include "blt.h" #include "bltVector.h" #include "projection.h" #include "sigbus.h" int Base::markerAnalysisPlot2d(Marker* pp, double** x, double** y, double** xc, double** yc, Vector& p1, Vector& p2, int width, Coord::CoordSystem sys, Coord::SkyFrame sky, Marker::AnalysisMethod method) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); Vector vv = p2-p1; int num = vv.length() +1; Vector s = vv.normalize(); int cnt[num]; *x = (double*)malloc(num*sizeof(double)); *y = (double*)malloc(num*sizeof(double)); *xc = (double*)malloc(num*sizeof(double)); *yc = (double*)malloc(num*sizeof(double)); // main loop SETSIGBUS for (long ii=0; ii<num; ii++) { Vector t = p1 + s*ii; (*x)[ii] = ii+1; (*y)[ii] = 0; cnt[ii] = 0; Vector tv = ptr->mapFromRef(t, sys, sky); (*xc)[ii] = tv[0]; (*yc)[ii] = tv[1]; Vector z = t * ptr->refToData; if (z[0]>=params->xmin && z[0]<params->xmax && z[1]>=params->ymin && z[1]<params->ymax) { // check for nan double v = ptr->getValueDouble(z); if (isfinite(v)) { (*y)[ii] = v; cnt[ii] = 1; } Vector ss = Vector(-s[1],s[0]); for (long jj=1; jj<width; jj++) { Vector tt = p1 + s*ii + ss*jj; Vector zz = tt * ptr->refToData; if (zz[0]>=params->xmin && zz[0]<params->xmax && zz[1]>=params->ymin && zz[1]<params->ymax) { double vvalue = ptr->getValueDouble(zz); // check for nan if (isfinite(vvalue)) { (*y)[ii] += vvalue; cnt[ii]++; } } } } } // average if needed if (method == Marker::AVERAGE) for (long ii=0; ii<num; ii++) if (isfinite((*y)[ii]) && cnt[ii]!=0) (*y)[ii] /= cnt[ii]; CLEARSIGBUS return num; } int Base::markerAnalysisPlot3d(Marker* pp, double** x, double** y, const BBox& bb, Coord::CoordSystem sys, Marker::AnalysisMethod method) { // does not extend across mosaic boundries // different, need all slices FitsImage* ptr = isInFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->fits; // if more than 3 axes, walk it forward int num = currentContext->calcSlice(); for (int ii=1; ii<num; ii++) if (ptr) ptr = ptr->nextSlice(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); int srcw = ptr->width(); int srcd = params->zmax-params->zmin; // slice jump vector FitsImage* sjv[srcd]; FitsImage* sptr = ptr; for (int ii=0; ii<params->zmin; ii++) sptr = sptr->nextSlice(); for (int ii=0; ii<srcd; ii++) { sjv[ii] = sptr; sptr = sptr->nextSlice(); } // init int cnt[srcd]; *x = (double*)malloc(srcd*sizeof(double)); *y = (double*)malloc(srcd*sizeof(double)); for (long kk=0; kk<srcd; kk++) { (*x)[kk] = 0; (*y)[kk] = 0; cnt[kk] = 0; } // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb.ll*ptr->refToData).floor(); Vector ur = (bb.ur*ptr->refToData).ceil(); // main loop SETSIGBUS for (int kk=0; kk<srcd; kk++) { (*x)[kk] = ptr->mapFromRef3(kk+.5+params->zmin, sys, 2); for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); if (pp->isIn(rr*ptr->dataToRef,Coord::REF)) { double val =sjv[kk]->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { (*y)[kk] += val; cnt[kk]++; } } } } } } CLEARSIGBUS // average if needed if (method == Marker::AVERAGE) for (long kk=0; kk<srcd; kk++) if (cnt[kk]!=0) (*y)[kk] /= cnt[kk]; return srcd; } // for annulus regions int Base::markerAnalysisRadial(Marker* pp, double** x, double** y, double** e, int num, Vector* annuli, BBox* bb, Coord::CoordSystem sys) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; int srcw = ptr->width(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double sum[num]; memset(sum,0,num*sizeof(double)); int cnt[num]; memset(cnt,0,num*sizeof(int)); for (int kk=0; kk<num; kk++) { // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb[kk+1].ll*ptr->refToData).floor(); Vector ur = (bb[kk+1].ur*ptr->refToData).ceil(); // main loop SETSIGBUS for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); Vector ss = rr*ptr->dataToRef; if (pp->isIn(ss,Coord::REF,kk+1) && !pp->isIn(ss,Coord::REF,kk)) { double val =ptr->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { sum[kk] += val; cnt[kk]++; } } } } } CLEARSIGBUS } *x = (double*)malloc(num*sizeof(double)); *y = (double*)malloc(num*sizeof(double)); *e = (double*)malloc(num*sizeof(double)); int unit; Vector cdelt; double xaxis =1; if (ptr->hasWCS(sys)) if (ptr->hasWCSCel(sys)) { unit =1; cdelt= ptr->getWCScdelt(sys); xaxis = fabs(cdelt[0]*60*60); } else { unit =2; cdelt= ptr->getWCScdelt(sys); xaxis = fabs(cdelt[0]); } else { unit =0; xaxis =1; } for (int kk=0; kk<num; kk++) { double err = sqrt(fabs(sum[kk])); double area =0; double bri =0; double brierr =0; switch (unit) { case 0: // pixels area = abs(cnt[kk]); break; case 1: // Cel WCS area = fabs(cdelt[0]*cdelt[1]*60*60*60*60*cnt[kk]); break; case 2: // Linear WCS area = fabs(cdelt[0]*cdelt[1]*cnt[kk]); break; } // area can be zero if (area) { bri = sum[kk]/area; brierr = err/area; } double rr0 = (annuli[kk+1][0]-annuli[kk][0])/2. +annuli[kk][0]; double rr1 = (annuli[kk+1][1]-annuli[kk][1])/2. +annuli[kk][1]; double rad = (rr0 + rr1)/2.; (*x)[kk] = rad*xaxis; (*y)[kk] = bri; (*e)[kk] = brierr; } return num; } // for panda regions int Base::markerAnalysisPanda(Marker* pp, double** x, double** y, double** e, int num, Vector* annuli, int aa, double* angles, BBox* bb, Coord::CoordSystem sys) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; int srcw = ptr->width(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double sum[num][aa]; memset(sum,0,num*aa*sizeof(double)); int cnt[num][aa]; memset(cnt,0,num*aa*sizeof(int)); for (int kk=0; kk<num; kk++) { // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb[kk+1].ll*ptr->refToData).floor(); Vector ur = (bb[kk+1].ur*ptr->refToData).ceil(); // main loop SETSIGBUS for (int qq=0; qq<aa; qq++) { for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); Vector ss = rr*ptr->dataToRef; if (pp->isIn(ss,Coord::REF,kk+1,qq) && !pp->isIn(ss,Coord::REF,kk,qq)) { double val =ptr->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { sum[kk][qq] += val; cnt[kk][qq]++; } } } } } } CLEARSIGBUS } *x = (double*)malloc(num*aa*sizeof(double)); *y = (double*)malloc(num*aa*sizeof(double)); *e = (double*)malloc(num*aa*sizeof(double)); int unit; Vector cdelt; double xaxis =1; if (ptr->hasWCS(sys)) if (ptr->hasWCSCel(sys)) { unit =1; cdelt= ptr->getWCScdelt(sys); xaxis = fabs(cdelt[0]*60*60); } else { unit =2; cdelt= ptr->getWCScdelt(sys); xaxis = fabs(cdelt[0]); } else { unit =0; xaxis =1; } for (int qq=0; qq<aa; qq++) { for (int kk=0; kk<num; kk++) { double err = sqrt(fabs(sum[kk][qq])); double area =0; double bri =0; double brierr =0; switch (unit) { case 0: // pixels area = abs(cnt[kk][qq]); break; case 1: // Cel WCS area = fabs(cdelt[0]*cdelt[1]*60*60*60*60*cnt[kk][qq]); break; case 2: // Linear WCS area = fabs(cdelt[0]*cdelt[1]*cnt[kk][qq]); break; } // area can be zero if (area) { bri = sum[kk][qq]/area; brierr = err/area; } double rr0 = (annuli[kk+1][0]-annuli[kk][0])/2. +annuli[kk][0]; double rr1 = (annuli[kk+1][1]-annuli[kk][1])/2. +annuli[kk][1]; double rad = (rr0 + rr1)/2.; (*x)[qq*num+kk] = rad*xaxis; (*y)[qq*num+kk] = bri; (*e)[qq*num+kk] = brierr; } } return num*aa; } // for simple regions void Base::markerAnalysisStats(Marker* pp, ostream& str, const BBox& bb, Coord::CoordSystem sys) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; int srcw = ptr->width(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double sum =0; double sum2 =0; int cnt =0; double min =DBL_MAX; double max =DBL_MIN; // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb.ll*ptr->refToData).floor(); Vector ur = (bb.ur*ptr->refToData).ceil(); int msize = int(ur[1]-ll[1])*int(ur[0]-ll[0]); double* marr = new double[msize]; memset(marr,0,msize*sizeof(double)); // main loop SETSIGBUS for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); Vector ss = rr*ptr->dataToRef; if (pp->isIn(ss,Coord::REF)) { double val =ptr->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { sum += val; sum2 += val*val; if (cnt<msize) marr[cnt] = val; if (val<min) min =val; if (val>max) max =val; cnt++; } } } } } CLEARSIGBUS qsort((void*)marr,cnt,sizeof(double),dCompare); double median = marr[int(cnt/2.)]; if (marr) delete [] marr; int unit = markerAnalysisStats1(ptr,str,sys); markerAnalysisStats2(ptr,str,sys,0,cnt,sum,unit); markerAnalysisStats3(str); markerAnalysisStats4(str,0,cnt,sum,sum2,median,min,max); } // for annulus regions void Base::markerAnalysisStats(Marker* pp, ostream& str, int num, BBox* bb, Coord::CoordSystem sys) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; int srcw = ptr->width(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double sum[num]; memset(sum,0,num*sizeof(double)); double sum2[num]; memset(sum2,0,num*sizeof(double)); int cnt[num]; memset(cnt,0,num*sizeof(int)); double min[num]; double max[num]; for (int ii=0; ii<num; ii++) { min[ii] =DBL_MAX; max[ii] =DBL_MIN; } double median[num]; memset(median,0,num*sizeof(double)); for (int kk=0; kk<num; kk++) { // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb[kk+1].ll*ptr->refToData).floor(); Vector ur = (bb[kk+1].ur*ptr->refToData).ceil(); int msize = int(ur[1]-ll[1])*int(ur[0]-ll[0]); double* marr = new double[msize]; memset(marr,0,msize*sizeof(double)); // main loop SETSIGBUS for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); Vector ss = rr*ptr->dataToRef; if (pp->isIn(ss,Coord::REF,kk+1) && !pp->isIn(ss,Coord::REF,kk)) { double val =ptr->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { sum[kk] += val; sum2[kk] += val*val; if (cnt[kk]<msize) marr[cnt[kk]] = val; if (val<min[kk]) min[kk] =val; if (val>max[kk]) max[kk] =val; cnt[kk]++; } } } } } CLEARSIGBUS qsort((void*)marr,cnt[kk],sizeof(double),dCompare); median[kk] = marr[int(cnt[kk]/2.)]; if (marr) delete [] marr; } int unit = markerAnalysisStats1(ptr,str,sys); for (int kk=0; kk<num; kk++) markerAnalysisStats2(ptr,str,sys,kk,cnt[kk],sum[kk],unit); markerAnalysisStats3(str); for (int kk=0; kk<num; kk++) markerAnalysisStats4(str,kk,cnt[kk],sum[kk],sum2[kk], median[kk],min[kk],max[kk]); } // for panda regions void Base::markerAnalysisStats(Marker* pp, ostream& str, int num, int aa, BBox* bb, Coord::CoordSystem sys) { // does not extend across mosaic boundries // uses currentContext FitsImage* ptr = isInCFits(pp->getCenter(),Coord::REF,NULL); if (!ptr) ptr = currentContext->cfits; int srcw = ptr->width(); FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double sum[num][aa]; memset(sum,0,num*aa*sizeof(double)); double sum2[num][aa]; memset(sum2,0,num*aa*sizeof(double)); int cnt[num][aa]; memset(cnt,0,num*aa*sizeof(int)); double min[num][aa]; double max[num][aa]; for (int ii=0; ii<num; ii++) { for (int jj=0; jj<aa; jj++) { min[ii][jj] =DBL_MAX; max[ii][jj] =DBL_MIN; } } double median[num][aa]; memset(median,0,num*aa*sizeof(double)); for (int kk=0; kk<num; kk++) { // take the bbox and extend to lower/upper pixel boundaries Vector ll = (bb[kk+1].ll*ptr->refToData).floor(); Vector ur = (bb[kk+1].ur*ptr->refToData).ceil(); int msize = int(ur[1]-ll[1])*int(ur[0]-ll[0]); double* marr = new double[msize]; // main loop SETSIGBUS for (int qq=0; qq<aa; qq++) { memset(marr,0,msize*sizeof(double)); for (int jj=ll[1]; jj<ur[1]; jj++) { for (int ii=ll[0]; ii<ur[0]; ii++) { if (ii>=params->xmin && ii<params->xmax && jj>=params->ymin && jj<params->ymax) { // shift to center of pixel in DATA Vector rr = Vector(ii,jj)+Vector(.5,.5); Vector ss = rr*ptr->dataToRef; if (pp->isIn(ss,Coord::REF,kk+1,qq) && !pp->isIn(ss,Coord::REF,kk,qq)) { double val =ptr->getValueDouble(long(jj)*srcw+long(ii)); // check for nan if (isfinite(val)) { sum[kk][qq] += val; sum2[kk][qq] += val*val; if (cnt[kk][qq]<msize) marr[cnt[kk][qq]] = val; if (val<min[kk][qq]) min[kk][qq] = val; if (val>max[kk][qq]) max[kk][qq] = val; cnt[kk][qq]++; } } } } } qsort((void*)marr,cnt[kk][qq],sizeof(double),dCompare); median[kk][qq] = marr[int(cnt[kk][qq]/2.)]; } CLEARSIGBUS if (marr) delete [] marr; } int unit = markerAnalysisStats1(ptr,str,sys); for (int kk=0; kk<num; kk++) for (int qq=0; qq<aa; qq++) markerAnalysisStats2(ptr,str,sys,kk*aa+qq,cnt[kk][qq],sum[kk][qq],unit); markerAnalysisStats3(str); for (int kk=0; kk<num; kk++) for (int qq=0; qq<aa; qq++) markerAnalysisStats4(str,kk*aa+qq,cnt[kk][qq],sum[kk][qq],sum2[kk][qq], median[kk][qq],min[kk][qq],max[kk][qq]); } int Base::markerAnalysisStats1(FitsImage* ptr, ostream& str, Coord::CoordSystem sys) { int unit; if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { unit =1; Vector cdelt= ptr->getWCScdelt(sys); str << "1 pixel = "<< fabs(cdelt[0]*60*60) << " arcsec" << endl << endl << "reg\t" << "sum\t" << "error\t\t" << "area\t\t" << "surf_bri\t\t" << "surf_err" << endl << "\t" << "\t" << "\t\t" << "(arcsec**2)\t\t" << "(sum/arcsec**2)\t" << "(sum/arcsec**2)" << endl << "---\t" << "---\t" << "-----\t\t" << "-----------\t\t" << "---------------\t" << "---------------" << endl; } else { unit =2; Vector cdelt= ptr->getWCScdelt(sys); str << "1 pixel = "<< fabs(cdelt[0]) << endl << endl << "reg\t" << "sum\t" << "error\t\t" << "area\t\t" << "surf_bri\t\t" << "surf_err" << endl << "\t" << "\t" << "\t\t" << "(pix**2)\t\t" << "(sum/pix**2)\t\t" << "(sum/pix**2)" << endl << "---\t" << "---\t" << "-----\t\t" << "--------\t\t" << "------------\t\t" << "------------" << endl; } } else { unit =0; str << endl << endl << "reg\t" << "sum\t" << "error\t\t" << "area\t\t" << "surf_bri\t\t" << "surf_err" << endl << "\t" << "\t" << "\t\t" << "(pix**2)\t\t" << "(sum/pix**2)\t\t" << "(sum/pix**2)" << endl << "---\t" << "---\t" << "-----\t\t" << "--------\t\t" << "------------\t\t" << "------------" << endl; } return unit; } void Base::markerAnalysisStats2(FitsImage* ptr, ostream& str, Coord::CoordSystem sys, int kk, int cnt, double sum, int unit) { double area =0; switch (unit) { case 0: // pixels area = cnt; break; case 1: { // Cel WCS Vector cdelt= ptr->getWCScdelt(sys); area = fabs(cdelt[0]*cdelt[1]*60*60*60*60*cnt); } break; case 2: { // Linear WCS Vector cdelt= ptr->getWCScdelt(sys); area = fabs(cdelt[0]*cdelt[1]*cnt); } break; } double err = sqrt(fabs(sum)); double bri = sum/area; double brierr = err/area; str << kk+1 << '\t' << sum << '\t' << err << "\t\t" << area << "\t\t" << bri << "\t\t" << brierr << endl; } void Base::markerAnalysisStats3(ostream& str) { str << endl << "reg\t" << "sum\t" << "npix\t" << "mean\t" << "median\t" << "min\t" << "max\t" << "var\t" << "stddev\t" << "rms\t" << endl << "---\t" << "---\t" << "----\t" << "----\t" << "------\t" << "---\t" << "---\t" << "---\t" << "------\t" << "---\t" << endl; } void Base::markerAnalysisStats4(ostream& str, int kk, int cnt, double sum, double sum2, double median, double min, double max) { double mean =0; double std =0; double var =0; double rms =0; if (cnt) { mean = sum/cnt; var = fabs(sum2/cnt - (sum*sum)/(cnt*cnt)); std = sqrt(var); rms = sqrt(sum2/cnt); } str << kk+1 << '\t' << sum << '\t' << cnt << '\t' << mean << '\t' << median << '\t' << min << '\t' << max << '\t' << var << '\t' << std << '\t' << rms << '\t' << endl; } void Base::bltCut(char* xname, char* yname, Coord::Orientation axis, const Vector& rr) { int size; if (axis == Coord::XX) size = options->width; else size = options->height; long length = (size+1) * 2; double* xx = (double*)malloc(sizeof(double)*length); double* yy = (double*)malloc(sizeof(double)*length); if (!currentContext->cfits) { for (int ii=0; ii<=size; ii++) { xx[ii*2] = ii; xx[ii*2+1] = ii; yy[ii*2] = 0; yy[ii*2+1] = 0; } } else bltCutFits(xx, yy, size, axis, rr); Blt_Vector* xv; if (Blt_GetVector(interp, xname, &xv) != TCL_OK) goto error; if (Blt_ResetVector(xv, xx, length, length*sizeof(double), TCL_DYNAMIC) != TCL_OK) goto error; Blt_Vector* yv; if (Blt_GetVector(interp, yname, &yv) != TCL_OK) goto error; if (Blt_ResetVector(yv, yy, length, length*sizeof(double), TCL_DYNAMIC) != TCL_OK) goto error; return; error: result = TCL_ERROR; return; } void Base::bltCutFits(double* xx, double* yy, int size, Coord::Orientation axis, const Vector& r) { // Widget Vector rr = r * refToWidget; // basics FitsImage* sptr = currentContext->cfits; int mosaic = isMosaic(); // variable FitsBound* params = sptr->getDataParams(currentContext->frScale.scanMode()); double prev = currentContext->frScale.low(); // main loop SETSIGBUS for (int ii=0; ii<=size; ii++) { double vv = currentContext->frScale.low(); if (mosaic) { sptr = currentContext->cfits; params = sptr->getDataParams(currentContext->frScale.scanMode()); } do { Vector img; if (axis == Coord::XX) img = Vector(1+ii,rr[1]) * sptr->widgetToData; else img = Vector(rr[0],1+ii) * sptr->widgetToData; if (img[0]>=params->xmin && img[0]<params->xmax && img[1]>=params->ymin && img[1]<params->ymax) { double value = sptr->getValueDouble(img); if (isfinite(value)) vv = value; break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) params = sptr->getDataParams(currentContext->frScale.scanMode()); } } } while (mosaic && sptr); xx[2*ii] = ii; xx[2*ii +1] = ii; yy[2*ii] = prev; yy[2*ii +1] = vv; prev = vv; } CLEARSIGBUS } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudo.h������������������������������������������������������������������0000644�0001750�0001750�00000000712�11700666267�016014� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framepseudo_h__ #define __framepseudo_h__ #include "framebase.h" class FramePseudo : public virtual FrameBase { protected: void encodeTrueColor(int,int) {} void rotateMotion(); public: FramePseudo(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FramePseudo(); }; #endif ������������������������������������������������������./saods9/saotk/frame/frame3dbase.h������������������������������������������������������������������0000644�0001750�0001750�00000013233�12011262056�015640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3dbase_h__ #define __frame3dbase_h__ #include "base.h" class Grid3d; class Frame3dBase : public Base { friend class Grid3d; public: enum RenderMethod {MIP,AIP}; protected: float* zbufWidget_; unsigned char* mkzbufWidget_; float* zbufPanner_; unsigned char* mkzbufPanner_; float* zbufMagnifier_; unsigned char* mkzbufMagnifier_; float* zbufPS_; unsigned char* mkzbufPS_; int zdepth_; double zzoom_; double zscale_; Vector3d vp_; Vector viewCursor_; float az_; float el_; RenderMethod renderMethod_; GC threedGC; int border_; char* borderColorName_; int compass_; char* compassColorName_; int highlite_; char* highliteColorName_; double cropsl_; Matrix3d dataToImage3d; Matrix3d imageToData3d; Matrix3d canvasToRef3d; Matrix3d canvasToUser3d; Matrix3d canvasToWindow3d; Matrix3d canvasToWidget3d; Matrix3d magnifierToRef3d; Matrix3d magnifierToUser3d; Matrix3d magnifierToWidget3d; Matrix3d pannerToRef3d; Matrix3d pannerToUser3d; Matrix3d pannerToWidget3d; Matrix3d refToCanvas3d; Matrix3d refToMagnifier3d; Matrix3d refToPanner3d; Matrix3d refToUser3d; Matrix3d refToWidget3d; Matrix3d refToWindow3d; Matrix3d userToCanvas3d; Matrix3d userToMagnifier3d; Matrix3d userToPanner3d; Matrix3d userToRef3d; Matrix3d userToWidget3d; Matrix3d widgetToCanvas3d; Matrix3d widgetToMagnifier3d; Matrix3d widgetToPanner3d; Matrix3d widgetToRef3d; Matrix3d widgetToUser3d; Matrix3d widgetToWindow3d; Matrix3d windowToCanvas3d; Matrix3d windowToRef3d; Matrix3d windowToWidget3d; private: void calcBorder(Coord::InternalSystem, FrScale::ScanMode mode, Vector3d* vv, int* dd); void calcHighlite(Coord::InternalSystem, Vector*, int*); protected: virtual void cancelImage() =0; double calcZoomPanner(); double calcZoom3d(Vector3d, Vector); void centerImage(); int isAzElZero() {return !az_ && !el_;} Vector3d imageCenter3d(FrScale::ScanMode); Vector3d imageSize3d(FrScale::ScanMode); void psColor(PSColorSpace, const char*); void psLine(Vector&, Vector&, int); void psWidth(int); void psGraphics(PSColorSpace mode); void psBorder(PSColorSpace mode); void psCompass(PSColorSpace mode); void psHighlite(PSColorSpace mode); Matrix3d psMatrix(float scale, int width, int height); void setBinCursor() {} void updateBin(const Matrix&); void updateGCs(); void updateMagnifierMatrices(); void updatePannerMatrices(); void updateMatrices(); void updatePanner(); void x11Line(Vector, Vector, int, GC, Pixmap); void x11Graphics(); void x11Border(Coord::InternalSystem, FrScale::ScanMode, GC, Pixmap); void x11Compass(); void x11Highlite(); void ximageToPixmapMagnifier(); public: Frame3dBase(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Frame3dBase(); Vector mapFromRef(const Vector& vv, Coord::InternalSystem sys) {return mapFromRef3d(vv,sys);} Vector3d mapFromRef3d(const Vector&, Coord::InternalSystem); Vector3d mapFromRef3d(const Vector&, Coord::InternalSystem, double); Vector mapToRef(const Vector& vv, Coord::InternalSystem sys) {return mapToRef3d(vv,sys);} Vector3d mapToRef3d(const Vector&, Coord::InternalSystem); Vector3d mapToRef3d(const Vector&, Coord::InternalSystem, double); // Bin Commands void binToFitCmd(); // Clip Commands void clipScopeCmd(FrScale::ClipScope) {} // scope is always GLOBAL // Coordinate Commands void getCursorCmd(Coord::InternalSystem); void getCursorCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Precision); // Crop Commands void crop3dBeginCmd(const Vector&, int); void crop3dMotionCmd(const Vector&, int); void crop3dEndCmd(const Vector&, int); // Grid Commands void gridCmd(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Grid::GridType, const char*, const char*); // Pan Zoom Rotate Orient Commands void panCmd(const Vector&); void panCmd(const Vector&, const Vector&); void panCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame); void panToCmd(const Vector&); void panToCmd(const Vector&, Coord::CoordSystem, Coord::SkyFrame); void panBBoxCmd(const Vector&); void panEndCmd(const Vector&); void rotateBeginCmd(); void rotateMotionCmd(double); void rotateEndCmd(); void zoomAboutCmd(const Vector&, const Vector&); void zoomAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void zoomToAboutCmd(const Vector&, const Vector&); void zoomToAboutCmd(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyFrame); void zoomToFitCmd(double); // 3d Commands void get3dBorderCmd(); void get3dBorderColorCmd(); void get3dCompassCmd(); void get3dCompassColorCmd(); void get3dHighliteCmd(); void get3dHighliteColorCmd(); void get3dRenderMethodCmd(); void get3dScaleCmd(); void get3dViewCmd(); void get3dViewPointCmd(); void set3dBorderCmd(int); void set3dBorderColorCmd(const char*); void set3dCompassCmd(int); void set3dCompassColorCmd(const char*); void set3dHighliteCmd(int); void set3dHighliteColorCmd(const char*); void set3dRenderMethodCmd(int); void set3dScaleCmd(double); void set3dViewCmd(float, float); void set3dViewPointCmd(const Vector3d&, const Vector&); #ifdef _MACOSX void macosxLine(Vector&, Vector&, int); void macosxGraphics(); void macosxBorder(); void macosxCompass(); void macosxHighlite(); #endif #ifdef _WIN32 void win32Line(Vector&, Vector&, int); void win32Graphics(); void win32Border(); void win32Compass(); void win32Highlite(); #endif }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frload.C�����������������������������������������������������������������������0000644�0001750�0001750�00000053453�12041601172�014675� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "fitsimage.h" #include "alloc.h" #include "allocgz.h" #include "channel.h" #include "mmap.h" #include "mmapincr.h" #include "share.h" #include "sshare.h" #include "socket.h" #include "socketgz.h" #include "var.h" // *** Fits *** void Base::loadFitsAllocCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, ALLOC, fn, img, ll),ll); } void Base::loadFitsAllocGZCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, ALLOCGZ, fn, img, ll),ll); } void Base::loadFitsChannelCmd(const char* ch, const char* fn,LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, CHANNEL, fn, img, ll),ll); } void Base::loadFitsMMapCmd(const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, MMAP, fn, img, ll),ll); } void Base::loadFitsSMMapCmd(const char* hdr, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsSMMap(this, hdr, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, SMMAP, fn, img, ll),ll); } void Base::loadFitsMMapIncrCmd(const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, MMAPINCR, fn, img, ll),ll); } void Base::loadFitsShareCmd(ShmType stype, int id, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, SHARE, fn, img, ll),ll); } void Base::loadFitsSShareCmd(ShmType stype, int hdr, int id, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsSShare(this, stype, hdr, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, SSHARE, fn, img, ll),ll); } void Base::loadFitsSocketCmd(int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->load(this, SOCKET, fn, img, ll),ll); } void Base::loadFitsSocketGZCmd(int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->load(this, SOCKETGZ, fn, img, ll),ll); } void Base::loadFitsVarCmd(const char* ch, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->load(this, VAR, fn, img, ll),ll); } // *** Array *** void Base::loadArrAllocCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, ALLOC, fn, img, ll),ll); } void Base::loadArrAllocGZCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, ALLOCGZ, fn, img, ll),ll); } void Base::loadArrChannelCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, CHANNEL, fn, img, ll),ll); } void Base::loadArrMMapCmd(const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrMMap(this, fn, 1); loadDone(currentContext->load(this, MMAP, fn, img, ll),ll); } void Base::loadArrMMapIncrCmd(const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrMMapIncr(this, fn, 1); loadDone(currentContext->load(this, MMAPINCR, fn, img, ll),ll); } void Base::loadArrShareCmd(ShmType stype, int id, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrShare(this, stype, id, fn, 1); loadDone(currentContext->load(this, SHARE, fn, img, ll),ll); } void Base::loadArrSocketCmd(int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrSocket(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->load(this, SOCKET, fn, img, ll),ll); } void Base::loadArrSocketGZCmd(int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->load(this, SOCKETGZ, fn, img, ll),ll); } void Base::loadArrVarCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageArrVar(this, interp, ch, fn, 1); loadDone(currentContext->load(this, VAR, fn, img, ll),ll); } // *** NRRD *** void Base::loadNRRDAllocCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, ALLOC, fn, img, ll),ll); } void Base::loadNRRDChannelCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->load(this, CHANNEL, fn, img, ll),ll); } void Base::loadNRRDMMapCmd(const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDMMap(this, fn, 1); loadDone(currentContext->load(this, MMAP, fn, img, ll),ll); } void Base::loadNRRDShareCmd(ShmType stype, int id, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDShare(this, stype, id, fn, 1); loadDone(currentContext->load(this, SHARE, fn, img, ll),ll); } void Base::loadNRRDSocketCmd(int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDSocket(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->load(this, SOCKET, fn, img, ll),ll); } void Base::loadNRRDVarCmd(const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageNRRDVar(this, interp, ch, fn, 1); loadDone(currentContext->load(this, VAR, fn, img, ll),ll); } // *** Photo *** void Base::loadPhotoCmd(const char* ph, const char* fn) { unloadFits(); FitsImage* img = new FitsImagePhoto(this, interp, ph, fn, 1); loadDone(currentContext->load(this, PHOTO, fn, img, IMG), IMG); } void Base::loadSlicePhotoCmd(const char* ph, const char* fn) { FitsImage* img = new FitsImagePhoto(this, interp, ph, fn, 1); loadDone(currentContext->loadSlice(this, PHOTO, fn, img), IMG); } // *** Data Cube *** void Base::loadExtCubeAllocCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadExtCube(this, ALLOC, fn, img), IMG); } void Base::loadExtCubeAllocGZCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadExtCube(this, ALLOCGZ, fn, img), IMG); } void Base::loadExtCubeChannelCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadExtCube(this, CHANNEL, fn, img), IMG); } void Base::loadExtCubeMMapCmd(const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadExtCube(this, MMAP, fn, img), IMG); } void Base::loadExtCubeMMapIncrCmd(const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadExtCube(this, MMAPINCR, fn, img), IMG); } void Base::loadExtCubeShareCmd(ShmType stype, int id, const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadExtCube(this, SHARE, fn, img), IMG); } void Base::loadExtCubeSocketCmd(int s, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadExtCube(this, SOCKET, fn, img), IMG); } void Base::loadExtCubeSocketGZCmd(int s, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadExtCube(this, SOCKETGZ, fn, img), IMG); } void Base::loadExtCubeVarCmd(const char* ch, const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadExtCube(this, VAR, fn, img), IMG); } // *** Slice *** void Base::loadSliceAllocCmd(const char* ch, const char* fn) { FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadSlice(this, ALLOC, fn, img), IMG); } void Base::loadSliceAllocGZCmd(const char* ch, const char* fn) { FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadSlice(this, ALLOCGZ, fn, img), IMG); } void Base::loadSliceChannelCmd(const char* ch, const char* fn) { FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadSlice(this, CHANNEL, fn, img), IMG); } void Base::loadSliceMMapCmd(const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, SMMAP, fn, img), IMG); } void Base::loadSliceSMMapCmd(const char* hdr, const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsSMMap(this, hdr, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, MMAP, fn, img), IMG); } void Base::loadSliceMMapIncrCmd(const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, MMAPINCR, fn, img), IMG); } void Base::loadSliceShareCmd(ShmType stype, int id, const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, SHARE, fn, img), IMG); } void Base::loadSliceSShareCmd(ShmType stype, int hdr, int id, const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsSShare(this, stype, hdr, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, SSHARE, fn, img), IMG); } void Base::loadSliceSocketCmd(int s, const char* fn) { FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->loadSlice(this, SOCKET, fn, img), IMG); } void Base::loadSliceSocketGZCmd(int s, const char* fn) { FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->loadSlice(this, SOCKETGZ, fn, img), IMG); } void Base::loadSliceVarCmd(const char* ch, const char* fn, LoadMethod lm) { FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadSlice(this, VAR, fn, img), IMG); } // *** Mosaic Image *** void Base::loadMosaicImageAllocCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicImage(this, ALLOC, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageAllocGZCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicImage(this, ALLOCGZ, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageChannelCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicImage(this, CHANNEL, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageMMapCmd(MosaicType type, Coord::CoordSystem sys, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicImage(this, MMAP, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageMMapIncrCmd(MosaicType type, Coord::CoordSystem sys, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicImage(this, MMAPINCR, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageShareCmd(MosaicType type, Coord::CoordSystem sys, ShmType stype, int id, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicImage(this, SHARE, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageSocketCmd(MosaicType type, Coord::CoordSystem sys, int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicSocket(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicImage(this, SOCKET, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageSocketGZCmd(MosaicType type, Coord::CoordSystem sys, int s, const char* fn, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicSocketGZ(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicImage(this, SOCKETGZ, fn, img, ll,type,sys),ll); } void Base::loadMosaicImageVarCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LoadMethod lm, LayerType ll) { if (ll == IMG) unloadFits(); FitsImage* img = new FitsImageMosaicVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicImage(this, VAR, fn, img, ll,type,sys),ll); } // *** Mosaic *** void Base::loadMosaicAllocCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaic(this, ALLOC, fn, img, ll,type,sys),ll); } void Base::loadMosaicAllocGZCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaic(this, ALLOCGZ, fn, img, ll,type,sys),ll); } void Base::loadMosaicChannelCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LayerType ll) { FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaic(this, CHANNEL, fn, img, ll,type,sys),ll); } void Base::loadMosaicMMapCmd(MosaicType type, Coord::CoordSystem sys, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, SMMAP, fn, img, ll,type,sys),ll); } void Base::loadMosaicSMMapCmd(MosaicType type, Coord::CoordSystem sys, const char* hdr, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsSMMap(this, hdr, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, MMAP, fn, img, ll,type,sys),ll); } void Base::loadMosaicMMapIncrCmd(MosaicType type, Coord::CoordSystem sys, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, MMAPINCR, fn, img, ll,type,sys),ll); } void Base::loadMosaicShareCmd(MosaicType type, Coord::CoordSystem sys, ShmType stype, int id, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, SHARE, fn, img, ll,type,sys),ll); } void Base::loadMosaicSShareCmd(MosaicType type, Coord::CoordSystem sys, ShmType stype, int hdr, int id, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsSShare(this, stype, hdr, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, SSHARE, fn, img, ll,type,sys),ll); } void Base::loadMosaicSocketCmd(MosaicType type, Coord::CoordSystem sys, int s, const char* fn, LayerType ll) { FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->loadMosaic(this, SOCKET, fn, img, ll,type,sys),ll); } void Base::loadMosaicSocketGZCmd(MosaicType type, Coord::CoordSystem sys, int s, const char* fn, LayerType ll) { FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::FLUSH, 1); loadDone(currentContext->loadMosaic(this, SOCKETGZ, fn, img, ll,type,sys),ll); } void Base::loadMosaicVarCmd(MosaicType type, Coord::CoordSystem sys, const char* ch, const char* fn, LoadMethod lm, LayerType ll) { FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaic(this, VAR, fn, img, ll,type,sys),ll); } // *** Mosaic Image WFPC2 *** void Base::loadMosaicImageWFPC2AllocCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsAlloc(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicWFPC2(this, ALLOC, fn, img), IMG); } void Base::loadMosaicImageWFPC2AllocGZCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsAllocGZ(this, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicWFPC2(this, ALLOCGZ, fn, img), IMG); } void Base::loadMosaicImageWFPC2ChannelCmd(const char* ch, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsChannel(this, interp, ch, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicWFPC2(this, CHANNEL, fn, img), IMG); } void Base::loadMosaicImageWFPC2MMapCmd(const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsMMap(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicWFPC2(this, MMAP, fn, img), IMG); } void Base::loadMosaicImageWFPC2MMapIncrCmd(const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsMMapIncr(this, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicWFPC2(this, MMAPINCR, fn, img), IMG); } void Base::loadMosaicImageWFPC2ShareCmd(ShmType stype, int id, const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsShare(this, stype, id, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicWFPC2(this, SHARE, fn, img), IMG); } void Base::loadMosaicImageWFPC2SocketCmd(int s, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsSocket(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicWFPC2(this, SOCKET, fn, img), IMG); } void Base::loadMosaicImageWFPC2SocketGZCmd(int s, const char* fn) { unloadFits(); FitsImage* img = new FitsImageFitsSocketGZ(this, s, fn, FitsFile::NOFLUSH, 1); loadDone(currentContext->loadMosaicWFPC2(this, SOCKETGZ, fn, img), IMG); } void Base::loadMosaicImageWFPC2VarCmd(const char* ch, const char* fn, LoadMethod lm) { unloadFits(); FitsImage* img = new FitsImageFitsVar(this, interp, ch, fn, 1); setScanModeIncr(lm); loadDone(currentContext->loadMosaicWFPC2(this, VAR, fn, img), IMG); } // *** void Base::loadDone(int rr, LayerType ll) { if (rr) { if (ll == IMG) { if (!keyContextSet) { keyContext = currentContext; keyContextSet =1; } } alignWCS(); if (!preservePan) { centerImage(); crosshair = cursor; } // set default scope if (currentContext->fits && !isCube() && !isMosaic()) currentContext->frScale.setClipScope(FrScale::LOCAL); } else { reset(); Tcl_AppendResult(interp, "Unable to load file", NULL); result = TCL_ERROR; } // adjust current slice if needed if (currentContext->fits && isCube() && currentContext->frScale.scanMode()==FrScale::CROPSEC) { // context->slice() IMAGE (ranges 1-n) // params are in DATA coords, edge to edge // setSlice() IMAGE (ranges 1-n) double sl = currentContext->slice(2)-.5; FitsBound* params = currentContext->fits->getDataParams(currentContext->frScale.scanMode()); double ff = params->zmin+.5; double tt = params->zmax-.5; if (sl<ff) setSlice(2,ff+.5); if (sl>tt) setSlice(2,tt+.5); } currentContext->updateClip(); updateColorScale(); update(MATRIX); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue16.C�������������������������������������������������������������0000644�0001750�0001750�00000010076�11700666266�016635� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscaletrue16.h" ColorScaleTrueColor16::ColorScaleTrueColor16(int s, Visual* visual, int msb) : ColorScale(s), TrueColor16(visual) { colors_ = new unsigned char[s*2]; // we need to check to byteswap when we have cross platforms if ((!msb && lsb()) || (msb && !lsb())) { for (int i=0; i<s; i++) { unsigned short r = psColors_[i*3+2]; unsigned short g = psColors_[i*3+1]; unsigned short b = psColors_[i*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); memcpy(colors_+i*2, &a, 2); } } else { for (int i=0; i<s; i++) { unsigned short r = psColors_[i*3+2]; unsigned short g = psColors_[i*3+1]; unsigned short b = psColors_[i*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&a); *(colors_+i*2) = *(rr+1); *(colors_+i*2+1) = *(rr); } } } ColorScaleTrueColor16::~ColorScaleTrueColor16() { if (colors_) delete [] colors_; } LinearScaleTrueColor16::LinearScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : LinearScale(s, indexCells, colorCells, count), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} LogScaleTrueColor16::LogScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : LogScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} PowScaleTrueColor16::PowScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : PowScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} SqrtScaleTrueColor16::SqrtScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SqrtScale(s, indexCells, colorCells, count), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} SquaredScaleTrueColor16::SquaredScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SquaredScale(s,indexCells,colorCells,count), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} AsinhScaleTrueColor16::AsinhScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : AsinhScale(s,indexCells,colorCells,count), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} SinhScaleTrueColor16::SinhScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SinhScale(s,indexCells,colorCells,count), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} IISScaleTrueColor16::IISScaleTrueColor16(unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : IISScale(indexCells, colorCells, count), ColorScaleTrueColor16(IISSIZE, visual, msb), ColorScale(IISSIZE) {} HistEquScaleTrueColor16::HistEquScaleTrueColor16(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize, Visual* visual, int msb) : HistEquScale(s, indexCells, colorCells, count, hist, histsize), ColorScaleTrueColor16(s, visual, msb), ColorScale(s) {} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ruler.C������������������������������������������������������������������������0000644�0001750�0001750�00000032205�12057220627�014560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "ruler.h" #include "fitsimage.h" Ruler::Ruler(const Ruler& a) : BaseLine(a) { p3 = a.p3; coordSystem = a.coordSystem; skyFrame = a.skyFrame; distSystem = a.distSystem; distDist = a.distDist; dist = a.dist; } Ruler::Ruler(Base* p, const Vector& ptr1, const Vector& ptr2, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem distsys, Coord::SkyDist distfor, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseLine(p, ptr1, ptr2, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { coordSystem = sys; skyFrame = sky; distSystem = distsys; distDist = distfor; dist = 0; strcpy(type_,"ruler"); handle = new Vector[2]; numHandle = 2; updateBBox(); } void Ruler::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector aa = parent->mapFromRef(p1,sys); Vector bb = parent->mapFromRef(p2,sys); Vector cc = parent->mapFromRef(p3,sys); Vector dd = modifyArrow(p2,p1,sys); Vector ee = modifyArrow(p1,p2,sys); // line XDrawLine(display, drawable, lgc, dd[0], dd[1], ee[0], ee[1]); renderXArrow(drawable, p2, p1, sys, lgc); renderXArrow(drawable, p1, p2, sys, lgc); // axes renderXLineDash(lgc); XDrawLine(display, drawable, lgc, aa[0], aa[1], cc[0], cc[1]); XDrawLine(display, drawable, lgc, bb[0], bb[1], cc[0], cc[1]); // dist ostringstream str; distToStr(str); if (tkfont_) { XSetFont(display, lgc, Tk_FontId(tkfont_)); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); char* buf = dupstr(str.str().c_str()); int width = Tk_TextWidth(tkfont_, buf, strlen(buf)); Vector tt = ((bb-aa)/2+aa) * Translate(-width/2.,-metrics.descent); Tk_DrawChars(display, drawable, lgc, tkfont_, buf, strlen(buf), tt[0], tt[1]); if (buf) delete [] buf; } } GC Ruler::renderXGC(RenderMode mode) { // set width, color, dash switch (mode) { case SRC: XSetForeground(display, gc, color); renderXLineNoDash(gc); return gc; case XOR: renderXLineDash(gcxor); return gcxor; } } void Ruler::renderPS(int mode) { renderPSGC(mode); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); Vector cc = parent->mapFromRef(p3,Coord::CANVAS); Vector dd = modifyArrow(p2,p1,Coord::CANVAS); Vector ee = modifyArrow(p1,p2,Coord::CANVAS); // line { ostringstream str; str << "newpath " << dd.TkCanvasPs(parent->canvas) << "moveto" << ee.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); renderPSArrow(p2,p1,Coord::CANVAS); renderPSArrow(p1,p2,Coord::CANVAS); } // axes renderPSLineDash(); { ostringstream str; str << "newpath " << aa.TkCanvasPs(parent->canvas) << "moveto" << cc.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl; str << "newpath " << bb.TkCanvasPs(parent->canvas) << "moveto" << cc.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl; str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // dist if (psfont_) { ostringstream vstr; ostringstream str; const char* ff = Tk_NameOfFont(psfont_); str << '/' << psFontName(ff) << " findfont " << int(psFontSize(ff)*parent->getDisplayRatio()) << " scalefont setfont" << endl; distToStr(vstr); char* buf = dupstr(vstr.str().c_str()); Vector tt = ((bb-aa)/2 + aa).TkCanvasPs(parent->canvas); str << "gsave" << endl << "newpath " << endl << tt << " moveto" << endl << '(' << psQuote(buf) << ')' << endl << "dup true charpath pathbbox " << endl << "closepath " << endl << "3 -1 roll sub 2.5 div " << endl << "3 1 roll sub 2 div exch " << endl << tt << " moveto rmoveto show " << endl << "grestore" << endl; str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); if (buf) delete buf; } } void Ruler::renderPSGC(int mode) { renderPSColor(mode, parent->getXColor(colorName)); renderPSLineNoDash(); } #ifdef _MACOSX void Ruler::renderMACOSX() { renderMACOSXGC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); Vector cc = parent->mapFromRef(p3,Coord::CANVAS); Vector dd = modifyArrow(p2,p1,Coord::CANVAS); Vector ee = modifyArrow(p1,p2,Coord::CANVAS); // line macosxDrawLine(dd,ee); renderMACOSXArrow(p2,p1,Coord::CANVAS); renderMACOSXArrow(p1,p2,Coord::CANVAS); // axes renderMACOSXLineDash(); macosxDrawLine(aa,cc); macosxDrawLine(bb,cc); // dist { ostringstream vstr; distToStr(vstr); if (psfont_) { Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(psfont_, &psdstr); macosxFont(Tcl_DStringValue(&psdstr), psSize); Tcl_DStringFree(&psdstr); Tk_FontMetrics metrics; Tk_GetFontMetrics(psfont_, &metrics); char* buf = dupstr(vstr.str().c_str()); int width = Tk_TextWidth(psfont_, vbuf, strlen(buf)); Vector tt = ((bb-aa)/2 + aa) * Translate(-width/2., -metrics.descent); macosxDrawText(tt, 0, buf); if (buf) delete buf; } } } void Ruler::renderMACOSXGC() { macosxColor(parent->getXColor(colorName)); renderMACOSXLineNoDash(); } #endif // WIN32 #ifdef _WIN32 void Ruler::renderWIN32() { renderWIN32GC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); Vector cc = parent->mapFromRef(p3,Coord::CANVAS); Vector dd = modifyArrow(p2,p1,Coord::CANVAS); Vector ee = modifyArrow(p1,p2,Coord::CANVAS); // line win32DrawLine(dd,ee); renderWIN32Arrow(p2,p1,Coord::CANVAS); renderWIN32Arrow(p1,p2,Coord::CANVAS); // axes renderWIN32LineDash(); win32DrawLine(aa,cc); win32DrawLine(bb,cc); // dist { ostringstream vstr; distToStr(vstr); if (tkfont_) { win32Font(tkfont_); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); char* buf = dupstr(vstr.str().c_str()); int width = Tk_TextWidth(tkfont_, buf, strlen(buf)); Vector tt = ((bb-aa)/2 + aa) * Translate(-width/2., -metrics.descent); win32DrawText(tt, 0, buf); if (buf) delete buf; } } } void Ruler::renderWIN32GC() { win32Color(parent->getXColor(colorName)); renderWIN32LineNoDash(); } #endif // Support void Ruler::updateHandles() { center = (p2-p1)/2 + p1; angle = (p2-p1).angle(); // calc p3, dist FitsImage* ptr = parent->findFits(coordSystem,center); Vector a = ptr->mapFromRef(p1,coordSystem,skyFrame); Vector b = ptr->mapFromRef(p2,coordSystem,skyFrame); p3 = ptr->mapToRef(Vector(b[0],a[1]),coordSystem,skyFrame); dist = ptr->mapDistFromRef(p2, p1, distSystem, distDist); // generate handles in canvas coords handle[0] = parent->mapFromRef(p1,Coord::CANVAS); handle[1] = parent->mapFromRef(p2,Coord::CANVAS); } void Ruler::calcAllBBox() { // P3 bbox.bound(parent->mapFromRef(p3,Coord::CANVAS)); // make room for text if (tkfont_) { Vector v = (p2-p1)/2 + p1; ostringstream str; distToStr(str); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); char* buf = dupstr(str.str().c_str()); int width = Tk_TextWidth(tkfont_, buf, strlen(buf)); Vector ll = parent->mapFromRef(v,Coord::CANVAS) * Translate(-width/2.,-metrics.descent); Vector ur = parent->mapFromRef(v,Coord::CANVAS) * Translate(width/2.,metrics.ascent); bbox.bound(ll); bbox.bound(ur); if (buf) delete [] buf; } Marker::calcAllBBox(); } void Ruler::updateCoords(const Matrix& mx) { p3*=mx; BaseLine::updateCoords(mx); } int Ruler::isOn(const Vector& v, const Vector& v1, const Vector& v2) { // v : canvas coords // v1: ref coords // v2: ref coords // do this in canvas coords, not ref coords Vector l1 = parent->mapFromRef(v1,Coord::CANVAS); Vector l2 = parent->mapFromRef(v2,Coord::CANVAS); double a = (l2-l1).angle(); Matrix m = Translate(-l1) * Rotate(a); Vector end = l2*m; Vector vv = v*m; return (vv[0]>0 && vv[0]<end[0] && vv[1]>-3 && vv[1]<3); } int Ruler::isIn(const Vector& vv) { // test to see if point is on edge, if so, considered inside if (isOn(vv,p1,p2) || isOn(vv,p1,p3) || isOn(vv,p2,p3)) return 1; /* v[0]-- x value of point being tested v[1]-- y value of point being tested This algorithm is from "An Introduction to Ray Tracing", Academic Press, 1989, edited by Andrew Glassner, pg 53 -- a point lies in a polygon if a line is extended from the point to infinite in any direction and the number of intersections with the polygon is odd. This is valid for both concave and convex polygons. Points on a vertex are considered inside. Points on a edge are considered inside. */ // analysis in ref coords Vector v = parent->mapToRef(vv,Coord::CANVAS); int crossings = 0; // number of crossings int sign; // for all edges for (int i=0; i<3; i++) { Vector v1, v2; switch (i) { case 0: v1 = p1-v; v2 = p2-v; sign = ((v1[1])>=0) ? 1 : -1; // init sign break; case 1: v1 = p2-v; v2 = p3-v; break; case 2: v1 = p3-v; v2 = p1-v; break; } int nextSign = (v2[1]>=0) ? 1 : -1; // sign holder for p2 if (sign != nextSign) { if (v1[0]>0 && v2[0]>0) crossings++; else if (v1[0]>0 || v2[0]>0) { if (v1[0]-(v1[1]*(v2[0]-v1[0])/(v2[1]-v1[1])) > 0) crossings++; } sign = nextSign; } } return fmod(float(crossings),float(2)) ? 1 : 0; // if odd, point is inside } void Ruler::setCoordSystem(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::CoordSystem dsys, Coord::SkyDist dist) { coordSystem = sys; skyFrame = sky; distSystem = dsys; distDist = dist; updateBBox(); } void Ruler::distToStr(ostringstream& str) { switch (distSystem) { case Coord::IMAGE: str << dist << " img"; break; case Coord::PHYSICAL: str << dist << " phy"; break; case Coord::AMPLIFIER: str << dist << " amp"; break; case Coord::DETECTOR: str << dist << " det"; break; default: if (parent->findFits()->hasWCSCel(distSystem)) switch (distDist) { case Coord::DEGREE: str << dist << " deg"; break; case Coord::ARCMIN: str << dist << '\''; break; case Coord::ARCSEC: str << dist << '"'; break; } else str << dist << " lin"; } } // list void Ruler::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra1[16], ra2[16]; char dec1[16], dec2[16]; { ptr->mapFromRef(p1,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra1 >> dec1; } { ptr->mapFromRef(p2,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra2 >> dec2; } str << type_ << '(' << ra1 << ',' << dec1 << ',' << ra2 << ',' << dec2 << ')'; } break; } } else { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } } } if (conj) str << " ||"; str << " ruler="; coord.listCoordSystem(str, coordSystem, skyFrame, 1, ptr->hasWCSCel(coordSystem)); str << ' '; coord.listDistSystem(str, distSystem, distDist, ptr->hasWCSCel(distSystem)); listProperties(str, 0); } } void Ruler::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); Vector vv[2]; vv[0] = p1; vv[1] = p2; ostringstream sysstr; coord.listCoordSystem(sysstr,coordSystem,skyFrame,0,ptr->hasWCSCel(coordSystem)); ostringstream diststr; coord.listDistSystem(diststr,distSystem,distDist,ptr->hasWCSCel(distSystem)); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowPoint(ptr,sys,sky,format,vv,2); XMLRow(XMLPARAM,(char*)(sysstr.str().c_str())); XMLRow(XMLPARAM2,(char*)(diststr.str().c_str())); XMLRowProps(ptr,sys); XMLRowEnd(str); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ellipse.C����������������������������������������������������������������������0000644�0001750�0001750�00000023502�12030663652�015064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "ellipse.h" #include "fitsimage.h" Ellipse::Ellipse(const Ellipse& a) : BaseEllipse(a) {} Ellipse::Ellipse(Base* p, const Vector& ctr, const Vector& r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = 1; annuli_ = new Vector[numAnnuli_]; annuli_[0] = r; strcpy(type_,"ellipse"); numHandle = 4; updateBBox(); } void Ellipse::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); annuli_[0] = (v * mm).abs(); updateBBox(); doCallBack(CallBack::EDITCB); } void Ellipse::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT3D: if (!analysisPlot3d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot3dCB_[1], parent->options->cmdName); } if (analysisPlot3d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot3dCB_[1]); } analysisPlot3d_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::ROTATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::ROTATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Ellipse::analysisPlot3d(char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { double* x; double* y; Matrix mm = Rotate(angle) * Translate(center); Vector vv = annuli_[0]; BBox bb(-vv * mm); bb.bound( vv * mm); bb.bound(Vector( vv[0],-vv[1]) * mm); bb.bound(Vector(-vv[0], vv[1]) * mm); int num = parent->markerAnalysisPlot3d(this, &x, &y, bb, sys, method); analysisPlot3dResult(xname, yname, x, y, num); } void Ellipse::analysisStats(Coord::CoordSystem sys) { ostringstream str; Matrix mm = Rotate(angle) * Translate(center); Vector vv = annuli_[0]; BBox bb(-vv * mm); bb.bound( vv * mm); bb.bound(Vector( vv[0],-vv[1]) * mm); bb.bound(Vector(-vv[0], vv[1]) * mm); parent->markerAnalysisStats(this, str, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Ellipse::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << "\"" << ',' << r[1] << "\"" << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << r[0] << "\""<< ',' << r[1] << "\""<< ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } listPost(str, conj, strip); } void Ellipse::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadius(ptr,sys,annuli_[0]); XMLRowAng(sys,sky); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Ellipse::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); listCiaoPre(str); // radius is always in image coords switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::PHYSICAL); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(angle) << ')'; } break; default: if (ptr->hasWCSCel(sys)) { Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCMIN); char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << r[0] << '\'' << ',' << r[1] << '\'' << ',' << radToDeg(angle) << ')'; } break; } listCiaoPost(str, strip); } void Ellipse::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); listSAOtngPre(str, strip); // radius is always in image coords switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::IMAGE); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(angle) << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r[0] << ',' << r[1] << ',' << radToDeg(angle) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << r[0] << ',' << r[1] << ',' << radToDeg(angle) << ')'; } break; } } } listSAOtngPost(str, strip); } void Ellipse::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); Vector r = ptr->mapLenFromRef(annuli_[0],Coord::IMAGE); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v << r << radToDeg(angle); } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v[0] << "d " << v[1] << "d " << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; Vector r = ptr->mapLenFromRef(annuli_[0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << ra << ' ' << dec << ' ' << r[0] << "\" " << r[1] << "\" " << radToDeg(angle); } break; } } } listProsPost(str, strip); } void Ellipse::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[0][0] << ',' << annuli_[0][1] << ',' << radToDeg(angle) << ')'; listSAOimagePost(str, strip); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frscale.C����������������������������������������������������������������������0000644�0001750�0001750�00000012602�11741350537�015050� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frscale.h" #include "fitsimage.h" FrScale::FrScale() { colorScaleType_ = LINEARSCALE; clipScope_ = LOCAL; clipMode_ = MINMAX; mmMode_ = SCAN; low_ = 1; high_ = 100; min_ = 1; max_ = 100; uLow_ = 1; uHigh_ = 100; expo_ = 1000; zContrast_ = .25; zSample_ = 600; zLine_ = 120; mmIncr_ = 10; autoCutPer_ = 1; scanMode_ = IMGSEC; preserve_ = 0; histequ_ = NULL; histequSize_ = 0; histogramX_ = NULL; histogramY_ = NULL; histogramSize_ = 0; datasec_ = 1; } FrScale::~FrScale() { if (histequ_) delete [] histequ_; if (histogramX_) free(histogramX_); if (histogramY_) free(histogramY_); } FrScale::FrScale(const FrScale& a) { colorScaleType_ = a.colorScaleType_; clipScope_ = a.clipScope_; clipMode_ = a.clipMode_; mmMode_ = a.mmMode_; low_ = a.low_; high_ = a.high_; min_ = a.min_; max_ = a.max_; uLow_ = a.uLow_; uHigh_ = a.uHigh_; expo_ = a.expo_; zContrast_ = a.zContrast_; zSample_ = a.zSample_; zLine_ = a.zLine_; mmIncr_ = a.mmIncr_; autoCutPer_ = a.autoCutPer_; scanMode_ = a.scanMode_; preserve_ = a.preserve_; if (a.histequ_) { histequ_ = new double[a.histequSize_]; memcpy(histequ_,a.histequ_,a.histequSize_*sizeof(double)); } else histequ_ = NULL; histequSize_ = a.histequSize_; if (a.histogramX_) { histogramX_ = (double*)calloc(a.histogramSize_, sizeof(double)); memcpy(histogramX_,a.histogramX_,a.histogramSize_*sizeof(double)); } else histogramX_ = NULL; if (a.histogramY_) { histogramY_ = (double*)calloc(a.histogramSize_, sizeof(double)); memcpy(histogramY_,a.histogramY_,a.histogramSize_*sizeof(double)); } else histogramY_ = NULL; histogramSize_ = a.histogramSize_; } FrScale& FrScale::operator=(const FrScale& a) { colorScaleType_ = a.colorScaleType_; clipScope_ = a.clipScope_; clipMode_ = a.clipMode_; mmMode_ = a.mmMode_; low_ = a.low_; high_ = a.high_; min_ = a.min_; max_ = a.max_; uLow_ = a.uLow_; uHigh_ = a.uHigh_; expo_ = a.expo_; zContrast_ = a.zContrast_; zSample_ = a.zSample_; zLine_ = a.zLine_; mmIncr_ = a.mmIncr_; autoCutPer_ = a.autoCutPer_; scanMode_ = a.scanMode_; preserve_ = a.preserve_; if (histequ_) delete histequ_; histequ_ = NULL; if (a.histequ_) { histequ_ = new double[a.histequSize_]; memcpy(histequ_,a.histequ_,a.histequSize_*sizeof(double)); } histequSize_ = a.histequSize_; if (histogramX_) free(histogramX_); histogramX_ = NULL; if (a.histogramX_) { histogramX_ = (double*)calloc(a.histogramSize_, sizeof(double)); memcpy(histogramX_,a.histogramX_,a.histogramSize_*sizeof(double)); } if (histogramY_) free(histogramY_); histogramY_ = NULL; if (a.histogramY_) { histogramY_ = (double*)calloc(a.histogramSize_, sizeof(double)); memcpy(histogramY_,a.histogramY_,a.histogramSize_*sizeof(double)); } histogramSize_ = a.histogramSize_; } double* FrScale::histequ(FitsImage* fits) { // if we don't have any data, bail if (!fits) return NULL; // if we already have it, bail if (histequ_) return histequ_; if (DebugPerf) cerr << "histequ..."; // create pdf or histogram double* pdf = new double[HISTEQUSIZE]; memset(pdf,0,HISTEQUSIZE*sizeof(double)); FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->bin(pdf, HISTEQUSIZE, low_, high_, scanMode_); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } // find a total/average double total, average; { total = 0; for (int ii=0; ii<HISTEQUSIZE; ii++) total += pdf[ii]; average = total/HISTEQUSIZE; } // build transfer function (cdf) histequSize_ = HISTEQUSIZE; histequ_ = new double[HISTEQUSIZE]; double bin = 0; int color,level; for (color=level=0; level<HISTEQUSIZE && color<HISTEQUSIZE; level++) { histequ_[level] = (double)color/HISTEQUSIZE; bin += pdf[level]; while (bin>=average && color<HISTEQUSIZE) { bin -= average; color++; } } while (level<HISTEQUSIZE) histequ_[level++] = (double)(HISTEQUSIZE-1)/HISTEQUSIZE; delete [] pdf; if (DebugPerf) cerr << "end" << endl; return histequ_; } void FrScale::clearHistequ() { if (histequ_) delete [] histequ_; histequ_ = NULL; histequSize_ = 0; } void FrScale::histogram(FitsImage* fits, int num) { if (!histogramX_ || !histogramY_) { if (DebugPerf) cerr << "histogram " << endl; if (histogramX_) free(histogramX_); histogramX_ = (double*)calloc(num, sizeof(double)); if (histogramY_) free(histogramY_); histogramY_ = (double*)calloc(num, sizeof(double)); histogramSize_ = num; for (int ii=0; ii<num; ii++) histogramX_[ii] = (double)ii/(num-1)*(max_-min_) + min_; memset(histogramY_,0,sizeof(double)*num); if (max_ > min_) { FitsImage* ptr = fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->bin(histogramY_, num, min_, max_, scanMode_); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } } } void FrScale::clearHistogram() { if (histogramX_) free(histogramX_); histogramX_ = NULL; if (histogramY_) free(histogramY_); histogramY_ = NULL; histogramSize_ = 0; } ������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basecommand.C������������������������������������������������������������������0000644�0001750�0001750�00000231612�12131563542�015702� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <fstream> #include "fdstream.hpp" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "base.h" #include "context.h" #include "fitsimage.h" #include "mmap.h" #include "outfile.h" #include "outchannel.h" #include "outsocket.h" #include "sigbus.h" void Base::binCmd(const Vector& b, const Vector& v, const char* x, const char* y, const char* filter) { binFactor_ = b; binDepth_ = 1; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); currentContext->fits->setBinDepth(1); currentContext->fits->setBinX(x); currentContext->fits->setBinY(y); currentContext->fits->setBinFilter(filter); updateBin(currentContext->fits->updateHist(v)); } } void Base::binCmd(const Vector& b, const char* x, const char* y, const char* filter) { binFactor_ = b; binDepth_ = 1; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); currentContext->fits->setBinDepth(1); currentContext->fits->setBinX(x); currentContext->fits->setBinY(y); currentContext->fits->setBinFilter(filter); updateBin(currentContext->fits->updateHistCenter()); } } void Base::binCmd(const Vector& b, int d, const Vector& lim, const Vector& v, const char* x, const char* y, const char* z, const char* filter) { binFactor_ = b; binDepth_ = d; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); currentContext->fits->setBinDepth(d); currentContext->fits->setBinX(x); currentContext->fits->setBinY(y); currentContext->fits->setBinZ(z); currentContext->fits->setBinFilter(filter); currentContext->fits->setBinColMinMax(z,lim); updateBin(currentContext->fits->updateHist(v)); } } void Base::binCmd(const Vector& b, int d, const Vector& lim, const char* x, const char* y, const char* z, const char* filter) { binFactor_ = b; binDepth_ = d; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); currentContext->fits->setBinDepth(d); currentContext->fits->setBinX(x); currentContext->fits->setBinY(y); currentContext->fits->setBinZ(z); currentContext->fits->setBinFilter(filter); currentContext->fits->setBinColMinMax(z,lim); updateBin(currentContext->fits->updateHistCenter()); } } void Base::binAboutCmd() { if (currentContext->fits) updateBin(currentContext->fits->updateHistCenter()); } void Base::binAboutCmd(const Vector& v) { if (currentContext->fits) updateBin(currentContext->fits->updateHist(v)); } void Base::binBufferSizeCmd(int size) { binBufferSize_ = size; if (currentContext->fits) { currentContext->fits->setBinBufferSize(size); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binColsCmd(const char* x, const char* y, const char* z) { if (currentContext->fits) { currentContext->fits->setBinX(x); currentContext->fits->setBinY(y); currentContext->fits->setBinZ(z); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binDepthCmd(int d) { binDepth_ = d; if (currentContext->fits) { currentContext->fits->setBinDepth(d); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binFactorCmd(const Vector& b) { Vector bb = b; binFactor_[0] *= bb[0]; binFactor_[1] *= bb[1]; if (currentContext->fits) { currentContext->fits->setBinFactor(b); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binFactorAboutCmd(const Vector& b, const Vector& v) { Vector bb = b; binFactor_[0] *= bb[0]; binFactor_[1] *= bb[1]; if (currentContext->fits) { currentContext->fits->setBinFactor(b); updateBin(currentContext->fits->updateHist(v)); } } void Base::binFactorToCmd(const Vector& b) { Vector bb = b; binFactor_[0] = bb[0]; binFactor_[1] = bb[1]; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binFactorToAboutCmd(const Vector& b, const Vector& v) { Vector bb = b; binFactor_[0] = bb[0]; binFactor_[1] = bb[1]; if (currentContext->fits) { currentContext->fits->setBinToFactor(b); updateBin(currentContext->fits->updateHist(v)); } } void Base::binFunctionCmd(FitsHist::Function func) { binFunction_ = func; if (currentContext->fits) { currentContext->fits->setBinFunction(func); updateBin(currentContext->fits->updateHistCursor()); } } void Base::binFilterCmd(const char* filter) { if (currentContext->fits) { currentContext->fits->setBinFilter(filter); updateBin(currentContext->fits->updateHistCursor()); } } void Base::bgColorCmd(const char* color) { if (bgColorName) delete [] bgColorName; bgColorName = dupstr(color); bgColor = getXColor(bgColorName); update(BASE); } void Base::centerCmd() { centerImage(); update(MATRIX); } void Base::clearCmd() { unloadAllFits(); reset(); } void Base::clipMinMaxModeCmd(FrScale::MinMaxMode m) { if (currentContext->frScale.mmMode() != m) { currentContext->frScale.setMMMode(m); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipMinMaxSampleCmd(int i) { if (currentContext->frScale.mmIncr() != i) { currentContext->frScale.setMMIncr(i); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipModeCmd(float per) { if (per == 100) { if (currentContext->frScale.clipMode() != FrScale::MINMAX) { currentContext->frScale.setClipMode(FrScale::MINMAX); currentContext->updateClip(); updateColorScale(); update(BASE); } } else { if (currentContext->frScale.clipMode() != FrScale::AUTOCUT || currentContext->frScale.autoCutPer() != per) { currentContext->frScale.setAutoCutPer(per); currentContext->frScale.setClipMode(FrScale::AUTOCUT); currentContext->updateClip(); updateColorScale(); update(BASE); } } } void Base::clipModeCmd(FrScale::ClipMode m) { if (currentContext->frScale.clipMode() != m) { currentContext->frScale.setClipMode(m); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipPreserveCmd(int r) { if (currentContext->frScale.preserve() != r) { currentContext->frScale.setPreserve(r); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipScopeCmd(FrScale::ClipScope s) { if (!currentContext->fits) currentContext->frScale.setClipScope(s); else if (!isCube() && !isMosaic()) currentContext->frScale.setClipScope(FrScale::LOCAL); else currentContext->frScale.setClipScope(s); currentContext->updateClip(); updateColorScale(); update(BASE); } void Base::clipUserCmd(double l, double h) { if (currentContext->frScale.uLow() != l || currentContext->frScale.uHigh() != h) { currentContext->frScale.setULow(l); currentContext->frScale.setUHigh(h); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipUserLowCmd(double l) { if (currentContext->frScale.uLow() != l) { currentContext->frScale.setULow(l); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipUserHighCmd(double h) { if (currentContext->frScale.uHigh() != h) { currentContext->frScale.setUHigh(h); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipZScaleContrastCmd(float c) { if (currentContext->frScale.zContrast() != c) { currentContext->frScale.setZContrast(c); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipZScaleSampleCmd(int s) { if (currentContext->frScale.zSample() != s) { currentContext->frScale.setZSample(s); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::clipZScaleLineCmd(int l) { if (currentContext->frScale.zLine() != l) { currentContext->frScale.setZLine(l); currentContext->updateClip(); updateColorScale(); update(BASE); } } void Base::colorbarTagCmd(const char* str) { if (colorbartag) delete [] colorbartag; colorbartag = dupstr(str); } void Base::cropCmd() { currentContext->frScale.resetScanMode(); FitsImage* sptr = currentContext->fits; while (sptr) { sptr->setCropParams(currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } currentContext->frScale.clearHistogram(); currentContext->updateClip(); currentContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } // used for Backup void Base::cropCmd(const Vector& aa, const Vector& bb, Coord::CoordSystem sys, Coord::SkyFrame sky) { FitsImage* ptr = currentContext->fits; if (!ptr) return; Vector ss = ptr->mapToRef(aa,sys,sky); Vector tt = ptr->mapToRef(bb,sys,sky); currentContext->frScale.setScanMode(FrScale::CROPSEC); FitsImage* sptr = ptr; while (sptr) { sptr->setCropParams(ss*sptr->refToData, tt*sptr->refToData, currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } currentContext->frScale.clearHistogram(); currentContext->updateClip(); currentContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::cropCenterCmd(const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky, const Vector& wh, Coord::CoordSystem dsys, Coord::SkyDist dist) { FitsImage* ptr = currentContext->fits; if (!ptr) return; // params are in DATA coords Vector cc = ptr->mapToRef(vv,sys,sky)*ptr->refToData; Vector dd = ptr->mapLenToImage(wh,dsys,dist); Vector ll = (cc-dd/2).round(); Vector ur = (cc+dd/2).round(); currentContext->frScale.setScanMode(FrScale::CROPSEC); FitsImage* sptr = ptr; while (sptr) { sptr->setCropParams(ll,ur,currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } currentContext->frScale.clearHistogram(); currentContext->updateClip(); currentContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::cropBeginCmd(const Vector& vv) { cropBegin = vv; cropEnd = vv; } void Base::cropMotionCmd(const Vector& vv) { Vector ss = mapToRef(cropBegin, Coord::CANVAS); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector tt = mapToRef(cropEnd, Coord::CANVAS); Vector ll = mapFromRef(ss, Coord::CANVAS); Vector lr = mapFromRef(Vector(tt[0],ss[1]), Coord::CANVAS); Vector ur = mapFromRef(tt, Coord::CANVAS); Vector ul = mapFromRef(Vector(ss[0],tt[1]), Coord::CANVAS); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } cropEnd = vv; // and draw to window { Vector tt = mapToRef(cropEnd, Coord::CANVAS); Vector ll = mapFromRef(ss, Coord::WINDOW); Vector lr = mapFromRef(Vector(tt[0],ss[1]), Coord::WINDOW); Vector ur = mapFromRef(tt, Coord::WINDOW); Vector ul = mapFromRef(Vector(ss[0],tt[1]), Coord::WINDOW); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ll[0],ll[1],lr[0],lr[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,lr[0],lr[1],ur[0],ur[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ur[0],ur[1],ul[0],ul[1]); XDrawLine(display,Tk_WindowId(tkwin),selectGCXOR,ul[0],ul[1],ll[0],ll[1]); } } void Base::cropEndCmd(const Vector& vv) { Vector ss = mapToRef(cropBegin, Coord::CANVAS); // erase if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector tt = mapToRef(cropEnd, Coord::CANVAS); Vector ll = mapFromRef(ss, Coord::CANVAS); Vector lr = mapFromRef(Vector(tt[0],ss[1]), Coord::CANVAS); Vector ur = mapFromRef(tt, Coord::CANVAS); Vector ul = mapFromRef(Vector(ss[0],tt[1]), Coord::CANVAS); BBox bb(ll); bb.bound(lr); bb.bound(ur); bb.bound(ul); redrawNow(bb.expand(2)); } // and crop cropEnd = vv; if (cropBegin[0]!=cropEnd[0] || cropBegin[1]!=cropEnd[1]) { Vector tt = mapToRef(cropEnd, Coord::CANVAS); if (!isMosaic()) { currentContext->frScale.setScanMode(FrScale::CROPSEC); FitsImage* sptr = currentContext->fits; while (sptr) { sptr->setCropParams(ss*sptr->refToData, tt*sptr->refToData, currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } } else { FitsImage* ptr1 =NULL; FitsImage* ptr2 =NULL; if ((ptr1=isInFits(cropBegin,Coord::CANVAS,NULL)) == (ptr2=isInFits(cropEnd,Coord::CANVAS,NULL))) { currentContext->frScale.setScanMode(FrScale::CROPSEC); // clear any previous params FitsImage* ptr = currentContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->setCropParams(currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } FitsImage* sptr = ptr1; while (sptr) { sptr->setCropParams(ss*sptr->refToData, tt*sptr->refToData, currentContext->frScale.datasec()); sptr->updateFileName(); sptr = sptr->nextSlice(); } } } else { currentContext->frScale.resetScanMode(); FitsImage* sptr = currentContext->fits; while (sptr) { sptr->setCropParams(currentContext->frScale.datasec()); sptr->setCrop3dParams(); sptr->updateFileName(); sptr = sptr->nextSlice(); } } currentContext->frScale.clearHistogram(); currentContext->updateClip(); currentContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::crop3dCmd() { currentContext->frScale.resetScanMode(); // update filenames FitsImage* sptr = currentContext->fits; while (sptr) { sptr->setCrop3dParams(); sptr->updateFileName(); sptr = sptr->nextSlice(); } currentContext->frScale.clearHistogram(); currentContext->updateClip(); currentContext->updateContours(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::crop3dCmd(double z0, double z1, Coord::CoordSystem sys) { // use first slice FitsImage* ptr = currentContext->fits; if (!ptr) return; // ff/tt ranges 0-n double ff = ptr->mapToRef3(z0,sys,2); double tt = ptr->mapToRef3(z1,sys,2); // params is a BBOX in DATA coords 0-n FitsImage* sptr = ptr; while (sptr) { sptr->setCrop3dParams(ff-.5,tt+.5); sptr->updateFileName(); sptr = sptr->nextSlice(); } // set current slice if needed // setSlice() IMAGE (ranges 1-n) // context->slice() IMAGE (ranges 1-n) double sl = currentContext->slice(2)-.5; if (sl<ff) setSlice(2,ff+.5); if (sl>tt) setSlice(2,tt+.5); currentContext->frScale.setScanMode(FrScale::CROPSEC); currentContext->frScale.clearHistogram(); currentContext->updateClip(); updateColorScale(); update(MATRIX); updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::crosshairCmd(int which) { useCrosshair = which ? 1 : 0; update(PIXMAP); } void Base::crosshairCmd(const Vector& vv, Coord::InternalSystem sys) { useCrosshair = 1; crosshair = mapToRef(vv, sys); update(PIXMAP); } void Base::crosshairCmd(const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky) { useCrosshair = 1; if (currentContext->cfits) crosshair = currentContext->cfits->mapToRef(v, sys, sky); update(PIXMAP); } void Base::crosshairWarpCmd(const Vector& vv) { useCrosshair = 1; // use matrix, not map() for 3d Vector rr = crosshair*refToCanvas; rr += vv; crosshair = rr*canvasToRef; update(PIXMAP); updateMagnifier(); } void Base::colorScaleCmd(FrScale::ColorScaleType s) { if (currentContext->frScale.colorScaleType() != s) { currentContext->frScale.setColorScaleType(s); updateColorScale(); update(BASE); } } void Base::colorScaleLogCmd(double exp) { if (currentContext->frScale.expo() != exp) { currentContext->frScale.setExpo(exp); if (currentContext->frScale.colorScaleType() == FrScale::LOGSCALE) { updateColorScale(); update(BASE); } } } void Base::contourAuxHeadCmd() { currentContext->contourAuxHead(); } void Base::contourAuxNextCmd() { currentContext->contourAuxNext(); } void Base::contourAuxSaveCmd(const char* fn, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (currentContext->cfits && hasContourAux()) { ofstream str(fn); if (str) { List<Vertex>& c = (List<Vertex>&)(currentContext->auxcontours.current()->contours()); if (c.head()) do { Vector v = c.current()->vector; if (v[0] != DBL_MAX) str << setiosflags(ios::scientific) << setprecision(8) << currentContext->cfits->mapFromRef(v, sys, sky); str << endl; } while (c.next()); } } } void Base::contourCopyCmd(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (currentContext->cfits && hasContour()) { List<Vertex>* v = new List<Vertex>(currentContext->contour->contours()); if (v->head()) do { Vector& w = v->current()->vector; if (w[0] != DBL_MAX) w = currentContext->cfits->mapFromRef(w, sys, sky); } while (v->next()); ostringstream str; str << hex << v << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::contourCreateCmd(const char* color, int width, int dash, FVContour::Method method, int numlevel, int smooth, FrScale::ColorScaleType colorScaleType, float expo, float clipMode, Vector limits, const char* level) { if (DebugPerf) cerr << "contourCreate" << endl; currentContext->clearContour(); InverseScale* scale =NULL; if (level && strlen(level)>0) { int cnt = 0; double levels[100]; string x(level); istringstream str(x); while ((cnt<100) && (str >> levels[cnt])) cnt++; scale = new InverseScale(cnt, levels); } else { switch (colorScaleType) { case FrScale::IISSCALE: case FrScale::LINEARSCALE: scale = new LinearInverseScale(numlevel, limits[0], limits[1]); break; case FrScale::LOGSCALE: scale = new LogInverseScale(numlevel, limits[0], limits[1], expo); break; case FrScale::POWSCALE: scale = new PowInverseScale(numlevel, limits[0], limits[1], expo); break; case FrScale::SQRTSCALE: scale = new SqrtInverseScale(numlevel, limits[0], limits[1]); break; case FrScale::SQUAREDSCALE: scale = new SquaredInverseScale(numlevel, limits[0], limits[1]); break; case FrScale::ASINHSCALE: scale = new AsinhInverseScale(numlevel, limits[0], limits[1]); break; case FrScale::SINHSCALE: scale = new SinhInverseScale(numlevel, limits[0], limits[1]); break; case FrScale::HISTEQUSCALE: scale = new HistEquInverseScale(numlevel, limits[0], limits[1], currentContext->histequ(), HISTEQUSIZE); break; } } if (!isMosaic()) { if (currentContext->cfits) currentContext->setContour(new FVContour(this, currentContext->cfits, color, width, dash, method, numlevel, smooth, level, colorScaleType, expo, clipMode, limits, scale)); } else { if (currentContext->fits) { currentContext->setContour(new FVContour(this, currentContext->fits, color, width, dash, method, numlevel, smooth, level, colorScaleType, expo, clipMode, limits, scale)); FitsImage* ptr = currentContext->fits->nextMosaic(); while (ptr) { currentContext->contour->append(ptr); ptr = ptr->nextMosaic(); } } } update(PIXMAP); } void Base::contourDeleteCmd() { currentContext->clearContour(); update(PIXMAP); } void Base::contourDeleteAllCmd() { currentContext->clearContour(); currentContext->auxcontours.deleteAll(); update(PIXMAP); } void Base::contourLoadCmd(const char* color, int w, int d, const char* fn, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!currentContext->cfits) return; ifstream str(fn); if (str) { List<Vertex> c; while (!str.eof()) { Vertex* vv; char buf[64]; str.getline(buf,64,'\n'); if (strlen(buf) > 0) { Vector v; string x(buf); istringstream sstr(x); sstr >> v[0] >> v[1]; vv = new Vertex(currentContext->fits->mapToRef(v, sys, sky)); } else vv = new Vertex(Vector(DBL_MAX, DBL_MAX)); c.append(vv); } currentContext->auxcontours.append(new Contour(this, color, w, d, c)); } update(PIXMAP); } void Base::contourPasteCmd(const char* c, int w, int d, void* u, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!currentContext->cfits) return; List<Vertex>* v = (List<Vertex>*)u; if (v->head()) do { Vector& w = v->current()->vector; if (w[0] != DBL_MAX) w = currentContext->fits->mapToRef(w, sys, sky); } while (v->next()); currentContext->auxcontours.append(new Contour(this, c, w, d, *v)); delete v; update(PIXMAP); } void Base::contourSaveCmd(const char* fn, Coord::CoordSystem sys, Coord::SkyFrame sky) { if (currentContext->cfits && hasContour()) { ofstream str(fn); if (str) { List<Vertex>& c = (List<Vertex>&)(currentContext->contour->contours()); if (c.head()) do { Vector v = (c.current())->vector; if (v[0] != DBL_MAX && v[1] != DBL_MAX) str << setiosflags(ios::scientific) << setprecision(8) << currentContext->cfits->mapFromRef(v, sys, sky) << endl; else str << endl; } while (c.next()); } } } void Base::contourSetColorCmd(const char* clr) { if (hasContour()) { currentContext->contour->setColor(clr); update(PIXMAP); } } void Base::contourSetDashCmd(int d) { if (hasContour()) { currentContext->contour->setDash(d); update(PIXMAP); } } void Base::contourSetLineWidthCmd(int w) { if (hasContour()) { currentContext->contour->setLineWidth(w); update(PIXMAP); } } void Base::DATASECCmd(int which) { currentContext->frScale.setDataSec(which); currentContext->frScale.resetScanMode(); currentContext->updateClip(); updateColorScale(); update(MATRIX); } void Base::fitsyHasExtCmd(const char* fn) { // verify that we have an ext specified if (fn && (fn[strlen(fn)-1] != ']')) { Tcl_AppendResult(interp, "0", NULL); return; } FitsFile* ext = new FitsFitsMMap(fn, FitsFile::EXACT); if (ext->isValid()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); delete ext; return; } void Base::getBinCursorCmd() { if (currentContext->fits) printVector(currentContext->fits->getHistCursor(), DEFAULT); } void Base::getBinColsCmd() { if (currentContext->fits && currentContext->fits->isHist()) if (currentContext->fits->binDepth()>1) Tcl_AppendResult(interp, currentContext->fits->getHistX(), " ", currentContext->fits->getHistY(), " ", currentContext->fits->getHistZ(), NULL); else Tcl_AppendResult(interp, currentContext->fits->getHistX(), " ", currentContext->fits->getHistY(), NULL); else Tcl_AppendResult(interp, "", NULL); } void Base::getBinColsMinMaxCmd(const char* col) { if (currentContext->fits && col && *col) printVector(currentContext->fits->getHistColMinMax(col), DEFAULT); } void Base::getBinColsDimCmd(const char* col) { if (currentContext->fits && col && *col) printVector(currentContext->fits->getHistColDim(col), DEFAULT); } void Base::getBinDepthCmd() { if (currentContext->fits) binDepth_ = currentContext->fits->binDepth(); printDouble(binDepth_, DEFAULT); } void Base::getBinFactorCmd() { if (currentContext->fits) binFactor_ = currentContext->fits->binFactor(); printVector(binFactor_, DEFAULT); } void Base::getBinFunctionCmd() { if (currentContext->fits) binFunction_ = currentContext->fits->binFunction(); switch (binFunction_) { case FitsHist::AVERAGE: Tcl_AppendResult(interp, "average", NULL); return; case FitsHist::SUM: Tcl_AppendResult(interp, "sum", NULL); return; } } void Base::getBinBufferSizeCmd() { if (currentContext->fits) binBufferSize_ = currentContext->fits->binBufferSize(); printInteger(binBufferSize_); } void Base::getBinFilterCmd() { if (currentContext->fits && currentContext->fits->isHist()) Tcl_AppendResult(interp, currentContext->fits->getHistFilter(), NULL); else Tcl_AppendResult(interp, "", NULL); } void Base::getBinListCmd() { if (currentContext->fits && currentContext->fits->isHist()) { char* cols = currentContext->fits->getHistList(); Tcl_AppendResult(interp, cols, NULL); delete [] cols; } else Tcl_AppendResult(interp, "", NULL); } void Base::getBitpixCmd() { if (currentContext->cfits) printInteger(currentContext->cfits->bitpix()); } void Base::getBgColorCmd() { Tcl_AppendResult(interp, bgColorName, NULL); } void Base::getClipCmd() { printVector(currentContext->getClip(), DEFAULT); } void Base::getClipCmd(float per) { FrScale::ClipMode cm = (per == 100) ? FrScale::MINMAX : FrScale::AUTOCUT; float ac = per; ostringstream str; str << currentContext->getClip(cm, ac) << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getClipCmd(FrScale::ClipMode cm) { ostringstream str; str << currentContext->getClip(cm, currentContext->frScale.autoCutPer()) << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getClipMinMaxModeCmd() { switch (currentContext->frScale.mmMode()) { case FrScale::AUTOSCAN: Tcl_AppendResult(interp, "auto", NULL); return; case FrScale::SCAN: Tcl_AppendResult(interp, "scan", NULL); return; case FrScale::SAMPLE: Tcl_AppendResult(interp, "sample", NULL); return; case FrScale::DATAMIN: Tcl_AppendResult(interp, "datamin", NULL); return; case FrScale::IRAFMIN: Tcl_AppendResult(interp, "irafmin", NULL); return; } } void Base::getClipMinMaxSampleCmd() { printInteger(currentContext->frScale.mmIncr()); } void Base::getClipModeCmd() { switch (currentContext->frScale.clipMode()) { case FrScale::MINMAX: Tcl_AppendResult(interp, "minmax", NULL); break; case FrScale::ZSCALE: Tcl_AppendResult(interp, "zscale", NULL); break; case FrScale::ZMAX: Tcl_AppendResult(interp, "zmax", NULL); break; case FrScale::AUTOCUT: printDouble(currentContext->frScale.autoCutPer(), DEFAULT); break; case FrScale::USERCLIP: Tcl_AppendResult(interp, "user", NULL); break; } } void Base::getClipPreserveCmd() { if (currentContext->frScale.preserve()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getClipScopeCmd() { switch (currentContext->frScale.clipScope()) { case FrScale::GLOBAL: Tcl_AppendResult(interp, "global", NULL); break; case FrScale::LOCAL: Tcl_AppendResult(interp, "local", NULL); break; } } void Base::getClipUserCmd() { printVector(Vector(currentContext->frScale.uLow(), currentContext->frScale.uHigh()), DEFAULT); } void Base::getClipZScaleContrastCmd() { ostringstream str; str << currentContext->frScale.zContrast() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getClipZScaleSampleCmd() { ostringstream str; str << currentContext->frScale.zSample() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getClipZScaleLineCmd() { ostringstream str; str << currentContext->frScale.zLine() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getColorbarTagCmd() { if (colorbartag) Tcl_AppendResult(interp, colorbartag, NULL); } void Base::getColorMapLevelCmd(int count) { if (currentContext->cfits) { getColorMapLevelCmd(count, currentContext->cfits->getLowDouble(), currentContext->cfits->getHighDouble(), currentContext->frScale.colorScaleType(), currentContext->frScale.expo()); } else getColorMapLevelCmd(count, currentContext->frScale.low(), currentContext->frScale.high(), currentContext->frScale.colorScaleType(), currentContext->frScale.expo()); } void Base::getColorMapLevelCmd(int count, const Vector& vv, Coord::InternalSystem ref) { if (currentContext->cfits) { if (FitsImage* ptr=isInCFits(vv,ref,NULL)) { getColorMapLevelCmd(count, ptr->getLowDouble(), ptr->getHighDouble(), currentContext->frScale.colorScaleType(), currentContext->frScale.expo()); return; } } getColorMapLevelCmd(count, currentContext->frScale.low(), currentContext->frScale.high(), currentContext->frScale.colorScaleType(), currentContext->frScale.expo()); } void Base::getColorMapLevelCmd(int count, double ll, double hh, FrScale::ColorScaleType scaleType, float expo) { if (inverseScale) delete inverseScale; inverseScale = NULL; switch (scaleType) { case FrScale::LINEARSCALE: case FrScale::IISSCALE: inverseScale = new LinearInverseScale(count, ll, hh); break; case FrScale::LOGSCALE: inverseScale = new LogInverseScale(count, ll, hh, expo); break; case FrScale::POWSCALE: inverseScale = new PowInverseScale(count, ll, hh, expo); break; case FrScale::SQRTSCALE: inverseScale = new SqrtInverseScale(count, ll, hh); break; case FrScale::SQUAREDSCALE: inverseScale = new SquaredInverseScale(count, ll, hh); break; case FrScale::ASINHSCALE: inverseScale = new AsinhInverseScale(count, ll, hh); break; case FrScale::SINHSCALE: inverseScale = new SinhInverseScale(count, ll, hh); break; case FrScale::HISTEQUSCALE: inverseScale = new HistEquInverseScale(count, ll, hh, currentContext->histequ(), HISTEQUSIZE); break; } if (inverseScale) { ostringstream str; str << inverseScale->size() << ' ' << inverseScale->level() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getColorScaleCmd() { switch (currentContext->frScale.colorScaleType()) { case FrScale::LINEARSCALE: Tcl_AppendResult(interp, "linear", NULL); break; case FrScale::LOGSCALE: Tcl_AppendResult(interp, "log", NULL); break; case FrScale::POWSCALE: Tcl_AppendResult(interp, "pow", NULL); break; case FrScale::SQRTSCALE: Tcl_AppendResult(interp, "sqrt", NULL); break; case FrScale::SQUAREDSCALE: Tcl_AppendResult(interp, "squared", NULL); break; case FrScale::ASINHSCALE: Tcl_AppendResult(interp, "asinh", NULL); break; case FrScale::SINHSCALE: Tcl_AppendResult(interp, "sinh", NULL); break; case FrScale::IISSCALE: Tcl_AppendResult(interp, "linear", NULL); break; case FrScale::HISTEQUSCALE: Tcl_AppendResult(interp, "histequ", NULL); break; } } void Base::getColorScaleLevelCmd(int count, double ll, double hh, FrScale::ColorScaleType scaleType, float expo) { InverseScale* scale; switch (scaleType) { case FrScale::LINEARSCALE: case FrScale::IISSCALE: scale = new LinearInverseScale(count, ll, hh); break; case FrScale::LOGSCALE: scale = new LogInverseScale(count, ll, hh, expo); break; case FrScale::POWSCALE: scale = new PowInverseScale(count, ll, hh, expo); break; case FrScale::SQRTSCALE: scale = new SqrtInverseScale(count, ll, hh); break; case FrScale::SQUAREDSCALE: scale = new SquaredInverseScale(count, ll, hh); break; case FrScale::ASINHSCALE: scale = new AsinhInverseScale(count, ll, hh); break; case FrScale::SINHSCALE: scale = new SinhInverseScale(count, ll, hh); break; case FrScale::HISTEQUSCALE: scale = new HistEquInverseScale(count, ll, hh, currentContext->histequ(), HISTEQUSIZE); break; } ostringstream str; str << *scale << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); delete scale; } void Base::getColorScaleLogCmd() { ostringstream str; str << currentContext->frScale.expo() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getContourCmd(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (currentContext->cfits && hasContour()) { List<Vertex>& v = (List<Vertex>&)(currentContext->contour->contours()); if (v.head()) do { Vector w = v.current()->vector; if (w[0] != DBL_MAX) printVector(currentContext->cfits->mapFromRef(w, sys, sky),DEFAULT); Tcl_AppendResult(interp, "\n", NULL); } while (v.next()); } } void Base::getContourMethodCmd() { if (hasContour()) Tcl_AppendResult(interp, currentContext->contour->methodName(), NULL); } void Base::getContourClipCmd() { if (hasContour()) printVector(currentContext->contour->limits(),DEFAULT); } void Base::getContourClipModeCmd() { if (hasContour()) if (currentContext->contour->clipMode() == FrScale::MINMAX) Tcl_AppendResult(interp, "minmax", NULL); else if (currentContext->contour->clipMode() == FrScale::ZSCALE) Tcl_AppendResult(interp, "zscale", NULL); else if (currentContext->contour->clipMode() == FrScale::ZMAX) Tcl_AppendResult(interp, "zmax", NULL); else if (currentContext->contour->clipMode() == FrScale::USERCLIP) Tcl_AppendResult(interp, "user", NULL); else { ostringstream str; str << currentContext->contour->clipMode() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getContourColorNameCmd() { if (hasContour()) Tcl_AppendResult(interp, currentContext->contour->getColorName(), NULL); } void Base::getContourAuxColorNameCmd() { if (hasContourAux()) Tcl_AppendResult(interp, currentContext->auxcontours.current()->getColorName(), NULL); } void Base::getContourDashCmd() { if (hasContour() && currentContext->contour->getDash()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getContourAuxDashCmd() { if (hasContourAux() && currentContext->auxcontours.current()->getDash()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getContourLevelCmd() { if (hasContour()) Tcl_AppendResult(interp, currentContext->contour->level(), NULL); } void Base::getContourLineWidthCmd() { if (hasContour()) { ostringstream str; str << currentContext->contour->getLineWidth() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getContourAuxLineWidthCmd() { if (hasContourAux()) { ostringstream str; str << currentContext->auxcontours.current()->getLineWidth() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getContourNumLevelCmd() { if (hasContour()) { ostringstream str; str << currentContext->contour->numLevel() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getContourSmoothCmd() { if (hasContour()) { ostringstream str; str << currentContext->contour->smooth() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getContourScaleCmd() { if (hasContour()) switch (currentContext->contour->colorScaleType()) { case FrScale::LINEARSCALE: Tcl_AppendResult(interp, "linear", NULL); break; case FrScale::LOGSCALE: Tcl_AppendResult(interp, "log", NULL); break; case FrScale::POWSCALE: Tcl_AppendResult(interp, "pow", NULL); break; case FrScale::SQRTSCALE: Tcl_AppendResult(interp, "sqrt", NULL); break; case FrScale::SQUAREDSCALE: Tcl_AppendResult(interp, "squared", NULL); break; case FrScale::ASINHSCALE: Tcl_AppendResult(interp, "asinh", NULL); break; case FrScale::SINHSCALE: Tcl_AppendResult(interp, "sinh", NULL); break; case FrScale::IISSCALE: Tcl_AppendResult(interp, "linear", NULL); break; case FrScale::HISTEQUSCALE: Tcl_AppendResult(interp, "histequ", NULL); break; } } void Base::getContourScaleLogCmd() { if (hasContour()) { ostringstream str; str << currentContext->contour->expo() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::getCoordCmd(const Vector& vv, Coord::CoordSystem out, Coord::SkyFrame sky, Coord::SkyFormat format) { if (FitsImage* ptr=isInCFits(vv,Coord::CANVAS,NULL)) printFromRef(ptr, mapToRef(vv,Coord::CANVAS), out, sky, format, DEFAULT); } void Base::getCoordFromRefCmd(double vv, Coord::CoordSystem out, int ss) { if (currentContext->cfits) // use first slice printDouble(currentContext->fits->mapFromRef3(vv-.5,out,ss), DEFAULT); else printDouble(0,DEFAULT); } void Base::getCoordToRefCmd(double vv, Coord::CoordSystem in, int ss) { if (currentContext->cfits) // use first slice printDouble(currentContext->fits->mapToRef3(vv,in,ss), DEFAULT); else printDouble(0,DEFAULT); } // used for Backup void Base::getCropCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = currentContext->fits; if (!ptr) return; // params are in DATA coords FitsBound* params =ptr->getDataParams(currentContext->frScale.scanMode()); Vector ll = Vector(params->xmin,params->ymin); Vector ur = Vector(params->xmax,params->ymax); printFromRef(ptr, ll*ptr->dataToRef, sys, sky, format, DEFAULT); printFromRef(ptr, ur*ptr->dataToRef, sys, sky, format, DEFAULT); } void Base::getCropCenterCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Coord::CoordSystem dcoord, Coord::SkyDist dist) { FitsImage* ptr = currentContext->fits; if (!ptr) return; // params are in DATA coords FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); Vector ll = Vector(params->xmin,params->ymin); Vector ur = Vector(params->xmax,params->ymax); Vector cc = (ur-ll)/2.+ll; Vector dd = ur-ll; printFromRef(ptr, cc*ptr->dataToRef , sys, sky, format, DEFAULT); printVector(ptr->mapLenFromImage(dd, dcoord, dist), DEFAULT); } void Base::getCrop3dCmd(Coord::CoordSystem sys) { // use first slice FitsImage* ptr = currentContext->fits; if (!ptr) return; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); double ff = ptr->mapFromRef3(params->zmin+.5,sys,2); double tt = ptr->mapFromRef3(params->zmax-.5,sys,2); ostringstream str; str << ff << ' ' << tt << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getCrosshairCmd(Coord::InternalSystem sys) { printVector(mapFromRef(crosshair, sys), DEFAULT); } void Base::getCrosshairCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Precision pp) { if (currentContext->cfits) printFromRef(currentContext->cfits, crosshair, sys, sky, format, pp); else printVector(Vector(), DEFAULT); } void Base::getCrosshairStatusCmd() { if (useCrosshair) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getDATASECCmd() { if (currentContext->frScale.datasec()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getDataValuesCmd(const Vector& vv, Coord::InternalSystem ref, const Vector& ss) { Vector rr; FitsImage* ptr = isInCFits(vv, ref, &rr); if (!ptr) return; Vector ll = rr - Vector((((Vector&)ss)[0]-1)/2,(((Vector&)ss)[1]-1)/2); SETSIGBUS for (int jj=0; jj<((Vector&)ss)[1]; jj++) { for (int ii=0; ii<((Vector&)ss)[0]; ii++) { Vector dd = (ll+Vector(ii,jj)) * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (dd[0]>=params->xmin && dd[0]<params->xmax && dd[1]>=params->ymin && dd[1]<params->ymax) Tcl_AppendResult(interp, (char*)ptr->getValue(dd), " ", NULL); } } CLEARSIGBUS } void Base::getDataValuesCmd(int which, const Vector& vv, Coord::CoordSystem sys, Coord::SkyFrame sky, const Vector& dd, char* var) { // clear an previous values Tcl_UnsetVar(interp,var,0); // find anchor point FitsImage* base = currentContext->cfits; for (int ii=1; ii<which; ii++) if (base) base = base->nextMosaic(); if (!base) { Tcl_SetVar(interp,var,"",0); result = TCL_ERROR; return; } Vector ll = base->mapLenToRef(dd,sys,Coord::DEGREE); Vector bb = base->mapToRef(vv,sys,sky); SETSIGBUS for (int ii=0; ii<ll[0]; ii++) { for (int jj=0; jj<ll[1]; jj++) { Vector rr = bb+Vector(ii,jj); // index is in terms of native coords Vector in = base->mapFromRef(rr,sys,sky); ostringstream str; str << setprecision(12) << in[0] << ',' << in[1] << ends; int found = 0; FitsImage* ptr = currentContext->fits; while (ptr) { Vector ss = rr * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (ss[0]>=params->xmin && ss[0]<params->xmax && ss[1]>=params->ymin && ss[1]<params->ymax) { Tcl_SetVar2(interp,var,str.str().c_str(),(char*)ptr->getValue(ss),0); found = 1; break; } ptr = ptr->nextMosaic(); } if (!found) Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } } CLEARSIGBUS } void Base::getFitsNAxesCmd() { printInteger(currentContext->naxes()); } void Base::getFitsCenterCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Precision pp) { if (keyContext && keyContext->fits) printFromRef(keyContext->fits, imageCenter(keyContext->frScale.scanMode())* keyContext->fits->imageToRef, sys, sky, format, pp); else printVector(Vector(), DEFAULT); } void Base::getFitsCountCmd() { printInteger(fitsCount()); } void Base::getFitsDepthCmd(int ii) { // sanity check if (ii<2) ii=2; int dd = currentContext->naxis(ii); if (dd>1) printInteger(dd); else printInteger(1); } void Base::getFitsExtCmd(const Vector& vv, Coord::InternalSystem ref) { if (FitsImage* ptr=isInCFits(vv,ref,NULL)) { ostringstream str; str << ptr->ext() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } else { Tcl_AppendResult(interp, "", NULL); } } void Base::getFitsHeaderCmd(int which) { int prim = which < 0 ? 1:0; which = abs(which); // modified for medatacube FitsImage* rr = findAllFits(which); if (rr) { char* hh = !prim ? rr->displayHeader() : rr->displayPrimary(); Tcl_AppendResult(interp, hh, NULL); delete [] hh; } else result = TCL_ERROR; } void Base::getFitsHeaderWCSCmd(int which) { // no primary FitsImage* rr = findAllFits(which); if (rr) { char* hh = rr->displayWCS(); Tcl_AppendResult(interp, hh, NULL); delete [] hh; } else result = TCL_ERROR; } void Base::getFitsHeaderKeywordCmd(int which, const char* key) { which = abs(which); FitsImage* rr = findAllFits(which); if (rr) { char* value = rr->getKeyword(key); if (value) { Tcl_AppendResult(interp, value, NULL); delete [] value; return; } } else result = TCL_ERROR; } void Base::getFitsFileNameCmd(FileNameType type) { if (currentContext->cfits) { switch (type) { case ROOTBASE: Tcl_AppendResult(interp, currentContext->cfits->getRootBaseFileName(), NULL); break; case FULLBASE: Tcl_AppendResult(interp, currentContext->cfits->getFullBaseFileName(), NULL); break; case ROOT: Tcl_AppendResult(interp, currentContext->cfits->getRootFileName(), NULL); break; case FULL: Tcl_AppendResult(interp, currentContext->cfits->getFullFileName(), NULL); break; case ROOT3D: Tcl_AppendResult(interp, currentContext->cfits->getRootFileName3d(),NULL); break; case FULL3D: Tcl_AppendResult(interp, currentContext->cfits->getFullFileName3d(),NULL); break; } } } void Base::getFitsFileNameCmd(int which, FileNameType type) { FitsImage* rr = findAllFits(which); if (rr) { switch (type) { case ROOTBASE: Tcl_AppendResult(interp, rr->getRootBaseFileName(), NULL); break; case FULLBASE: Tcl_AppendResult(interp, rr->getFullBaseFileName(), NULL); break; case ROOT: Tcl_AppendResult(interp, rr->getRootFileName(), NULL); break; case FULL: Tcl_AppendResult(interp, rr->getFullFileName(), NULL); break; case ROOT3D: Tcl_AppendResult(interp, rr->getRootFileName3d(), NULL); break; case FULL3D: Tcl_AppendResult(interp, rr->getFullFileName3d(), NULL); break; } } else result = TCL_ERROR; } void Base::getFitsFileNameCmd(const Vector& vv, Coord::InternalSystem ref, FileNameType type) { if (FitsImage* ptr=isInCFits(vv,ref,NULL)) { switch (type) { case ROOTBASE: Tcl_AppendResult(interp, ptr->getRootBaseFileName(), NULL); break; case FULLBASE: Tcl_AppendResult(interp, ptr->getFullBaseFileName(), NULL); break; case ROOT: Tcl_AppendResult(interp, ptr->getRootFileName(), NULL); break; case FULL: Tcl_AppendResult(interp, ptr->getFullFileName(), NULL); break; case ROOT3D: Tcl_AppendResult(interp, ptr->getRootFileName3d(), NULL); break; case FULL3D: Tcl_AppendResult(interp, ptr->getFullFileName3d(), NULL); break; } } } void Base::getFitsObjectNameCmd() { if (currentContext->cfits) Tcl_AppendResult(interp, currentContext->cfits->getObjectName(), NULL); } void Base::getFitsSizeCmd() { if (keyContext->fits) printVector(Vector(keyContext->fits->width(), keyContext->fits->height()), DEFAULT); else printVector(Vector(), DEFAULT); } void Base::getFitsSizeCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyDist dist, Precision pp) { if (keyContext->fits) { if (!keyContext->fits->hasWCSCel(sys)) { printVector(Vector(), DEFAULT); return; } BBox bb = imageBBox(keyContext->frScale.scanMode()); Matrix mm = keyContext->fits->imageToRef; Vector ll = bb.ll * mm; Vector lr = bb.lr() * mm; Vector ur = bb.ur * mm; Vector ul = bb.ul() * mm; Vector ww[4]; ww[0] = keyContext->fits->mapFromRef(ll,sys,sky); ww[1] = keyContext->fits->mapFromRef(lr,sys,sky); ww[2] = keyContext->fits->mapFromRef(ur,sys,sky); ww[3] = keyContext->fits->mapFromRef(ul,sys,sky); // we need to check for the case of crossing 0 in ra // since ra is returned as 0 > ra > 360 { float min = 360; float max = 0; for (int ii=0; ii<4; ii++) { if (ww[ii][0]<min) min=ww[ii][0]; if (ww[ii][0]>max) max=ww[ii][0]; } // ok, we have a problem if (max-min > 180) for (int ii=0; ii<4; ii++) if (ww[ii][0] > 180) ww[ii][0] -= 360; } BBox wbb(ww[0],ww[0]); for (int ii=1; ii<4; ii++) wbb.bound(ww[ii]); Vector ss(keyContext->fits->wcsdist(wbb.ll,wbb.lr(),sys), keyContext->fits->wcsdist(wbb.ll,wbb.ul(),sys)); switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: ss *= 60; break; case Coord::ARCSEC: ss *= 60*60; break; } printVector(ss,pp); } else printVector(Vector(), DEFAULT); } void Base::getFitsSliceCmd(int ii) { int ss = currentContext->slice(ii); if (ss>1) printInteger(ss); else printInteger(1); } void Base::getGridCmd() { if (grid) { Tcl_AppendElement(interp, coord.coordSystemStr((grid->system()))); Tcl_AppendElement(interp, coord.skyFrameStr((grid->sky()))); Tcl_AppendElement(interp, coord.skyFormatStr(grid->skyFormat())); switch (grid->type()) { case Grid::ANALYSIS: Tcl_AppendElement(interp, "analysis"); break; case Grid::PUBLICATION: Tcl_AppendElement(interp, "publication"); break; } } else Tcl_AppendResult(interp, "", NULL); } void Base::getGridOptionCmd() { if (grid) Tcl_AppendResult(interp, grid->option(), NULL); else Tcl_AppendResult(interp, "", NULL); } void Base::getGridVarsCmd() { if (grid) Tcl_AppendResult(interp, grid->vars(), NULL); else Tcl_AppendResult(interp, "", NULL); } void Base::getHeightCmd() { if (currentContext->cfits) printInteger(currentContext->cfits->height()); } void Base::getHistogramCmd(char* xName, char* yName) { currentContext->bltHist(xName, yName, 256); } void Base::getHorzCutCmd(char* xx, char* yy, const Vector& vv, Coord::InternalSystem ref) { Vector rr; if (FitsImage* ptr = isInCFits(vv, ref, &rr)) bltCut(xx, yy, Coord::XX, rr); } void Base::getInfoCmd(char* var) { if (currentContext->cfits) { Tcl_SetVar2(interp,var,"filename", (char*)currentContext->cfits->getRootBaseFileName(),0); Tcl_SetVar2(interp,var,"object", (char*)currentContext->cfits->getObjectName(),0); Tcl_SetVar2(interp,var,"min",(char*)currentContext->cfits->getMin(),0); Tcl_SetVar2(interp,var,"max",(char*)currentContext->cfits->getMax(),0); Tcl_SetVar2(interp,var,"low",(char*)currentContext->cfits->getLow(),0); Tcl_SetVar2(interp,var,"high",(char*)currentContext->cfits->getHigh(),0); } else getInfoClearName(var); getInfoClearValue(var); getInfoClearWCS(var); } void Base::getInfoCmd(const Vector& vv, Coord::InternalSystem ref, char* var) { FitsBound* params; int mosaic; Vector3d rr = mapToRef3d(vv,ref); // make sure we have an image FitsImage* ptr = currentContext->cfits; FitsImage* sptr = currentContext->cfits; if (!ptr) goto noFits; mosaic = isMosaic(); params = sptr->getDataParams(currentContext->frScale.scanMode()); if (!mosaic) { Tcl_SetVar2(interp,var,"filename",(char*)sptr->getRootBaseFileName(),0); Tcl_SetVar2(interp,var,"object",(char*)sptr->getObjectName(),0); Tcl_SetVar2(interp,var,"min",(char*)sptr->getMin(),0); Tcl_SetVar2(interp,var,"max",(char*)sptr->getMax(),0); Tcl_SetVar2(interp,var,"low",(char*)sptr->getLow(),0); Tcl_SetVar2(interp,var,"high",(char*)sptr->getHigh(),0); } if (((Vector&)vv)[0]<0 && ((Vector&)vv)[1]<0) goto noImage; // clear values Tcl_SetVar2(interp,var,"value","",0); Tcl_SetVar2(interp,var,"value,red","",0); Tcl_SetVar2(interp,var,"value,green","",0); Tcl_SetVar2(interp,var,"value,blue","",0); do { Vector img = Vector(rr) * sptr->refToData; if (img[0]>=params->xmin && img[0]<params->xmax && img[1]>=params->ymin && img[1]<params->ymax) { if (mosaic) { Tcl_SetVar2(interp,var,"filename",(char*)sptr->getRootBaseFileName(),0); Tcl_SetVar2(interp,var,"object",(char*)sptr->getObjectName(),0); Tcl_SetVar2(interp,var,"min",(char*)sptr->getMin(),0); Tcl_SetVar2(interp,var,"max",(char*)sptr->getMax(),0); Tcl_SetVar2(interp,var,"low",(char*)sptr->getLow(),0); Tcl_SetVar2(interp,var,"high",(char*)sptr->getHigh(),0); } SETSIGBUS Tcl_SetVar2(interp,var,"value",(char*)sptr->getValue(img),0); CLEARSIGBUS coordToTclArray(sptr,rr,Coord::IMAGE,FIXED,var,"image"); // use first slice coord3ToTclArray(ptr,rr,Coord::IMAGE,FIXED,var,"image"); coordToTclArray(sptr,rr,Coord::PHYSICAL,FIXED,var,"physical"); // use first slice coord3ToTclArray(ptr,rr,Coord::PHYSICAL,FIXED,var,"physical"); if (hasATMV()) { coordToTclArray(sptr,rr,Coord::AMPLIFIER,FIXED,var,"amplifier"); // use first slice coord3ToTclArray(ptr,rr,Coord::AMPLIFIER,FIXED,var,"amplifier"); } else { Tcl_SetVar2(interp,var,"amplifier,x","",0); Tcl_SetVar2(interp,var,"amplifier,y","",0); Tcl_SetVar2(interp,var,"amplifier,z","",0); } if (hasDTMV()) { coordToTclArray(sptr,rr,Coord::DETECTOR,FIXED,var,"detector"); // use first slice coord3ToTclArray(ptr,rr,Coord::DETECTOR,FIXED,var,"detector"); } else { Tcl_SetVar2(interp,var,"detector,x","",0); Tcl_SetVar2(interp,var,"detector,y","",0); Tcl_SetVar2(interp,var,"detector,z","",0); } getInfoWCS(var,rr,ptr,sptr); return; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) params = sptr->getDataParams(currentContext->frScale.scanMode()); } else { getInfoWCS(var,rr,ptr,sptr); goto noImage; } } } while (mosaic && sptr); // mosaic gap getInfoWCS(var,rr,ptr,ptr); // else, return blanks noFits: getInfoClearName(var); noImage: getInfoClearValue(var); } void Base::getInfoClipCmd() { if (currentContext->cfits) { Tcl_AppendElement(interp, (char*)currentContext->cfits->getLow()); Tcl_AppendElement(interp, (char*)currentContext->cfits->getHigh()); } else { Tcl_AppendElement(interp, "0"); Tcl_AppendElement(interp, "0"); } } void Base::getMaskColorCmd() { Tcl_AppendResult(interp, maskColorName, NULL); } void Base::getMaskMarkCmd() { if (maskMark) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getMaskTransparencyCmd() { printDouble((1-maskAlpha)*100., DEFAULT); } void Base::getMinMaxCmd() { printVector(Vector(currentContext->frScale.min(), currentContext->frScale.max()), DEFAULT); } void Base::getNANColorCmd() { Tcl_AppendResult(interp, nanColorName, NULL); } void Base::getOrientCmd() { switch (orientation) { case Coord::NORMAL: Tcl_AppendResult(interp, "none", NULL); return; case Coord::XX: Tcl_AppendResult(interp, "x", NULL); return; case Coord::YY: Tcl_AppendResult(interp, "y", NULL); return; case Coord::XY: Tcl_AppendResult(interp, "xy", NULL); return; } } void Base::getPanPreserveCmd() { if (preservePan) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::getPixelTableCmd(const Vector& vv, Coord::InternalSystem ref, int ww, int hh, char* var) { Vector rr; FitsImage* ptr = isInCFits(vv, ref, &rr); if (!ptr) { // else return blank for (int jj=0; jj<=hh; jj++) { for (int ii=0; ii<=ww; ii++) { ostringstream str; str << ii << ',' << jj << ends; Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } } return; } Vector half((ww-1)/2,(hh-1)/2); Vector ur = rr+half; Vector ll = rr-half; int ii,jj; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); // x (columns) for (ii=0,jj=0; ii<ww; ii++) { ostringstream str; str << jj << ',' << ii+1 << ends; if (ur[0]>=params->xmin && ll[0]<params->xmax && ur[1]>=params->ymin && ll[1]<params->ymax) { Vector pt = ((ll+Vector(ii,jj)) * dataToImage).round(); if (pt[0]>params->xmin && pt[0]<=params->xmax) { ostringstream lstr; lstr << pt[0] << ends; Tcl_SetVar2(interp,var,str.str().c_str(),lstr.str().c_str(),0); } else Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } else Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } // y (rows) for (ii=0,jj=0; jj<hh; jj++) { ostringstream str; str << hh-jj << ',' << ii << ends; if (ur[0]>=params->xmin && ll[0]<params->xmax && ur[1]>=params->ymin && ll[1]<params->ymax) { Vector pt = ((ll+Vector(ii,jj)) * dataToImage).round(); if (pt[1]>params->ymin && pt[1]<=params->ymax) { ostringstream lstr; lstr << pt[1] << ends; Tcl_SetVar2(interp,var,str.str().c_str(),lstr.str().c_str(),0); } else Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } else Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } // body SETSIGBUS for (jj=0; jj<hh; jj++) { for (ii=0; ii<ww; ii++) { Vector pt = ll+Vector(ii,jj); ostringstream str; str << hh-jj << ',' << ii+1 << ends; if (pt[0]>=params->xmin && pt[0]<params->xmax && pt[1]>=params->ymin && pt[1]<params->ymax) Tcl_SetVar2(interp,var,str.str().c_str(),(char*)ptr->getValue(pt),0); else Tcl_SetVar2(interp,var,str.str().c_str(),"",0); } } CLEARSIGBUS } void Base::getRotateCmd(Precision p) { printDouble(radToDeg(rotation), p); } void Base::getSmoothFunctionCmd() { if (currentContext->fits) smoothFunction_ = currentContext->fits->smoothFunction(); switch (smoothFunction_) { case FitsImage::BOXCAR: Tcl_AppendResult(interp, "boxcar", NULL); return; case FitsImage::TOPHAT: Tcl_AppendResult(interp, "tophat", NULL); return; case FitsImage::GAUSSIAN: Tcl_AppendResult(interp, "gaussian", NULL); return; } } void Base::getSmoothRadiusCmd() { if (currentContext->fits) smoothRadius_ = currentContext->fits->smoothRadius(); printInteger(smoothRadius_); } void Base::getThreadsCmd() { ostringstream str; str << threads_ << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::getValueCmd(const Vector& vv, Coord::InternalSystem sys) { Vector rr; SETSIGBUS if (FitsImage* ptr=isInCFits(vv,sys,&rr)) Tcl_AppendResult(interp, ptr->getValue(rr), NULL); CLEARSIGBUS } void Base::getVertCutCmd(char* xx, char* yy, const Vector& vv, Coord::InternalSystem ref) { Vector rr; if (FitsImage* ptr = isInCFits(vv, ref, &rr)) bltCut(xx, yy, Coord::YY, rr); } void Base::getWCSCmd() { Tcl_AppendResult(interp, coord.coordSystemStr(wcsSystem_), " ", coord.skyFrameStr(wcsSky_), " ", coord.skyFormatStr(wcsSkyFormat_), NULL); } void Base::getWCSAlignCmd() { Tcl_AppendResult(interp, (wcsAlign_ ? "1" : "0"), NULL); } void Base::getWCSAlignPointerCmd() { ostringstream str; if (keyContext->fits) str << (unsigned short*)keyContext->fits << ends; else str << (unsigned short*)NULL << ends; Tcl_AppendResult(interp, (wcsAlign_ ? "1" : "0"), " ", str.str().c_str(), " ", coord.coordSystemStr(wcsSystem_), " ", coord.skyFrameStr(wcsSky_), NULL); } void Base::getWCSNameCmd(Coord::CoordSystem sys) { if (currentContext->cfits && currentContext->cfits->hasWCS(sys)) { char* wcsname = (char*)currentContext->cfits->getWCSName(sys); if (wcsname) { Tcl_AppendResult(interp, wcsname, NULL); return; } } Tcl_AppendResult(interp, NULL); } void Base::getWidthCmd() { if (currentContext->cfits) printInteger(currentContext->cfits->width()); } void Base::getZoomCmd(Precision p) { printVector(zoom_, p); } void Base::gridDeleteCmd() { if (grid) delete grid; grid = NULL; update(PIXMAP); } void Base::hasAmplifierCmd() { if (hasATMV()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasBinColCmd(const char* str) { if (currentContext->fits) { if (currentContext->fits->hasBinCol(str)) { Tcl_AppendResult(interp, "1", NULL); return; } } Tcl_AppendResult(interp, "0", NULL); } void Base::hasContourCmd() { if (hasContour()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasContourAuxCmd() { if (hasContourAux()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasCropCmd() { switch (currentContext->frScale.scanMode()) { case FrScale::IMGSEC: case FrScale::DATASEC: Tcl_AppendResult(interp, "0", NULL); break; case FrScale::CROPSEC: Tcl_AppendResult(interp, "1", NULL); break; } } void Base::hasDATAMINCmd() { if (currentContext->cfits && currentContext->cfits->hasDATAMIN()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasDATASECCmd() { if (currentContext->cfits && currentContext->cfits->hasDATASEC()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasDetectorCmd() { if (hasDTMV()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasFitsCmd() { if (currentContext->fits) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasFitsHPXCmd() { if (currentContext->fits && currentContext->fits->isHPX()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasFitsBinCmd() { if (currentContext->fits && currentContext->fits->isHist()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasFitsCubeCmd() { if (isCube()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasFitsMosaicCmd() { if (isMosaic()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasGridCmd() { if (grid) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasIISCmd() { if (isIIS()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasIRAFMINCmd() { if (currentContext->cfits && currentContext->cfits->hasIRAFMIN()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasPhysicalCmd() { if (hasLTMV()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasSmoothCmd() { if (doSmooth_) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void Base::hasSystemCmd(Coord::CoordSystem sys) { switch (sys) { case Coord::IMAGE: Tcl_AppendResult(interp, "1", NULL); return; case Coord::PHYSICAL: hasPhysicalCmd(); return; case Coord::AMPLIFIER: hasAmplifierCmd(); return; case Coord::DETECTOR: hasDetectorCmd(); return; default: hasWCSCmd(sys); return; } } void Base::hasWCSCmd(Coord::CoordSystem sys) { Tcl_AppendResult(interp, (hasWCS(sys) ? "1" : "0"), NULL); } void Base::hasWCSAltCmd() { Tcl_AppendResult(interp, (wcsAlt_ ? "1" : "0"), NULL); } void Base::hasWCSEquCmd(Coord::CoordSystem sys) { Tcl_AppendResult(interp, (hasWCSEqu(sys) ? "1" : "0"), NULL); } void Base::hasWCSCelCmd(Coord::CoordSystem sys) { Tcl_AppendResult(interp, (hasWCSCel(sys) ? "1" : "0"), NULL); } void Base::hasWCSxCmd(Coord::CoordSystem sys) { Tcl_AppendResult(interp, (hasWCSx(sys) ? "1" : "0"), NULL); } // loadIncr is only used by LICK OBS // maintained for backward compatibility void Base::loadIncrDataCmd(int which, int x0, int y0, int x1, int y1) { // don't set scanMode (done by setScanModeIncr()) // don't trigger update (done by updateFitsCmd() / loadIncrEndCmd()) FitsImage* ptr = currentContext->fits; if (which > 0) { for (int i=0; i<(which-1); i++) { if (ptr) ptr = ptr->nextMosaic(); } } FitsImage* sptr = ptr; while (sptr) { ptr->setCropParams(x0,y0,x1,y1,currentContext->frScale.datasec()); sptr = sptr->nextSlice(); } } void Base::loadIncrMinMaxCmd(int which, int x0, int y0, int x1, int y1) { // don't trigger update (done by updateFitsCmd() / loadIncrEndCmd()) FitsImage* ptr = currentContext->fits; if (which > 0) { for (int ii=0; ii<(which-1); ii++) { if (ptr) ptr = ptr->nextMosaic(); } } FitsImage* sptr = ptr; while (sptr) { ptr->setMinMaxParams(x0,y0,x1,y1); sptr = sptr->nextSlice(); } currentContext->updateClip(); updateColorScale(); } void Base::loadIncrEndCmd() { // turn off special minmax bounds FitsImage* ptr = currentContext->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->setMinMaxParams(); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } currentContext->frScale.resetScanMode(); currentContext->updateClip(); updateColorScale(); update(MATRIX); } void Base::highliteCmd(int which) { useHighlite = which ? 1 : 0; update(PIXMAP); } void Base::magnifierCmd(int s) { useMagnifier = s; updateMagnifier(); } void Base::magnifierCmd(char* n, int w, int h) { strcpy(magnifierName,n); magnifierWidth = w; magnifierHeight = h; if (magnifierPixmap) Tk_FreePixmap(display, magnifierPixmap); magnifierPixmap = 0; if (magnifierXImage) XDestroyImage(magnifierXImage); magnifierXImage = NULL; if (magnifierWidth > 0 && magnifierHeight > 0) { magnifierPixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), magnifierWidth, magnifierHeight, depth); if (!magnifierPixmap) { internalError("Unable to Create Magnifier Pixmap"); return; } if (!magnifierXImage) { if (!(magnifierXImage = XGetImage(display, magnifierPixmap, 0, 0, magnifierWidth, magnifierHeight, AllPlanes, ZPixmap))){ internalError("Unable to Create Magnifier XImage"); return; } } } } void Base::magnifierCursorCmd(int which) { useMagnifierCursor = which; updateMagnifier(); } void Base::magnifierColorCmd(const char* color) { if (magnifierColorName) delete [] magnifierColorName; magnifierColorName = dupstr(color); updateMagnifier(); } void Base::magnifierGraphicsCmd(int which) { useMagnifierGraphics = which; updateMagnifier(); } void Base::magnifierZoomCmd(double z) { magnifierZoom_ = fabs(z); updateMagnifier(); } void Base::matchCmd(const char* xxname1, const char* yyname1, Coord::CoordSystem sys1, Coord::SkyFrame sky1, const char* xxname2, const char* yyname2, Coord::CoordSystem sys2, Coord::SkyFrame sky2, double rad, Coord::CoordSystem sys, Coord::SkyDist dist, const char* rrname) { if (keyContext && keyContext->fits) keyContext->fits->match(xxname1, yyname1, sys1, sky1, xxname2, yyname2, sys2, sky2, rad, sys, dist, rrname); } void Base::maskClearCmd() { currentContext->mask.deleteAll(); update(BASE); } void Base::maskColorCmd(const char* color) { if (maskColorName) delete [] maskColorName; maskColorName = dupstr(color); } void Base::maskTransparencyCmd(float t) { maskAlpha = 1-(t/100.); update(BASE); } void Base::nanColorCmd(const char* color) { if (nanColorName) delete [] nanColorName; nanColorName = dupstr(color); nanColor = getXColor(nanColorName); update(BASE); } void Base::orientCmd(Coord::Orientation which) { orientation = which; switch (orientation) { case Coord::NORMAL: orientationMatrix.identity(); break; case Coord::XX: orientationMatrix = FlipX(); break; case Coord::YY: orientationMatrix = FlipY(); break; case Coord::XY: orientationMatrix = FlipXY(); break; } update(MATRIX); } void Base::panBeginCmd(const Vector& vv) { // vv and panCursor are in CANVAS coords panCursor = vv; // copy tmp pixmap panPM = Tk_GetPixmap(display, Tk_WindowId(tkwin), options->width, options->height, depth); if (!panPM) { internalError("Unable to Create Pan Motion Pixmap"); return; } XCopyArea(display, pixmap, panPM, gc, 0, 0, options->width, options->height, 0,0); } void Base::panMotionCmd(const Vector& vv) { // vv and panCursor are in CANVAS coords // Clear Vector diff = (vv*canvasToWidget) - (panCursor*canvasToWidget); BBox hh,ww; if (diff[0]>0 && diff[1]>0) { hh = BBox(Vector(0,0), Vector(options->width, diff[1])); ww = BBox(Vector(0,0), Vector(diff[0], options->height)); } else if (diff[0]>0 && diff[1]<0) { hh = BBox(Vector(options->width,options->height), Vector(0,options->height+diff[1])); ww = BBox(Vector(0,0), Vector(diff[0], options->height)); } else if (diff[0]<0 && diff[1]>0) { hh = BBox(Vector(0,0), Vector(options->width, diff[1])); ww = BBox(Vector(options->width,options->height), Vector(options->width+diff[0], 0)); } else if (diff[0]<0 && diff[1]<0) { hh = BBox(Vector(options->width,options->height), Vector(0,options->height+diff[1])); ww = BBox(Vector(options->width,options->height), Vector(options->width+diff[0], 0)); } hh = hh * widgetToWindow; ww = ww * widgetToWindow; XSetForeground(display, gc, getColor(bgColorName)); Vector hs = hh.size(); XFillRectangle(display, Tk_WindowId(tkwin), gc, (int)hh.ll[0], (int)hh.ll[1], (int)hs[0], (int)hs[1]); Vector ws = ww.size(); XFillRectangle(display, Tk_WindowId(tkwin), gc, (int)ww.ll[0], (int)ww.ll[1], (int)ws[0], (int)ws[1]); // display tmp pixmap at new location Vector dd = ((vv * canvasToWidget) - (panCursor * canvasToWidget)) * widgetToWindow; XCopyArea(display, panPM, Tk_WindowId(tkwin), panGCXOR, 0, 0, options->width, options->height, dd[0], dd[1]); } void Base::pannerCmd(int s) { usePanner = s; updatePanner(); } void Base::pannerCmd(char* n, int w, int h) { strcpy(pannerName,n); pannerWidth = w; pannerHeight = h; if (pannerPixmap) Tk_FreePixmap(display, pannerPixmap); pannerPixmap = 0; if (pannerXImage) XDestroyImage(pannerXImage); pannerXImage = NULL; if (pannerWidth > 0 && pannerHeight > 0) { if (!(pannerPixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), pannerWidth, pannerHeight, depth))) { internalError("Unable to Create Panner Pixmap"); return; } if (!(pannerXImage = XGetImage(display, pannerPixmap, 0, 0, pannerWidth, pannerHeight, AllPlanes, ZPixmap))){ internalError("Unable to Create Panner XImage"); return; } } // update panner matrices update(MATRIX); } void Base::rotateCmd(double r) { rotation += r; update(MATRIX); } void Base::rotateToCmd(double r) { rotation = r; update(MATRIX); } void Base::saveFitsFileCmd(const char* fn) { OutFitsFile str(fn); saveFits(str); } void Base::saveFitsChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFits(str); } void Base::saveFitsSocketCmd(int ss) { OutFitsSocket str(ss); saveFits(str); } void Base::saveFitsTableFileCmd(const char* fn) { OutFitsFile str(fn); saveFitsTable(str); } void Base::saveFitsTableChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFitsTable(str); } void Base::saveFitsTableSocketCmd(int ss) { OutFitsSocket str(ss); saveFitsTable(str); } void Base::saveFitsSliceFileCmd(const char* fn) { OutFitsFile str(fn); saveFitsSlice(str); } void Base::saveFitsSliceChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFitsSlice(str); } void Base::saveFitsSliceSocketCmd(int ss) { OutFitsSocket str(ss); saveFitsSlice(str); } void Base::saveFitsExtCubeFileCmd(const char* fn) { OutFitsFile str(fn); saveFitsExtCube(str); } void Base::saveFitsExtCubeChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFitsExtCube(str); } void Base::saveFitsExtCubeSocketCmd(int ss) { OutFitsSocket str(ss); saveFitsExtCube(str); } void Base::saveFitsMosaicFileCmd(const char* fn, int which) { OutFitsFile str(fn); saveFitsMosaic(str, which); } void Base::saveFitsMosaicChannelCmd(const char* ch, int which) { OutFitsChannel str(interp, ch); saveFitsMosaic(str, which); } void Base::saveFitsMosaicSocketCmd(int ss, int which) { OutFitsSocket str(ss); saveFitsMosaic(str, which); } void Base::saveFitsMosaicImageFileCmd(const char* fn) { OutFitsFile str(fn); saveFitsMosaicImage(str); } void Base::saveFitsMosaicImageChannelCmd(const char* ch) { OutFitsChannel str(interp, ch); saveFitsMosaicImage(str); } void Base::saveFitsMosaicImageSocketCmd(int ss) { OutFitsSocket str(ss); saveFitsMosaicImage(str); } void Base::saveArrayFileCmd(const char* fn, FitsFile::ArchType endian) { if (currentContext->cfits) { OutFitsFile str(fn); saveArray(str, endian); } } void Base::saveArrayChannelCmd(const char* ch, FitsFile::ArchType endian) { OutFitsChannel str(interp, ch); saveArray(str, endian); } void Base::saveArraySocketCmd(int ss, FitsFile::ArchType endian) { OutFitsSocket str(ss); saveArray(str, endian); } void Base::saveNRRDFileCmd(const char* fn, FitsFile::ArchType endian) { OutFitsFile str(fn); saveNRRD(str, endian); } void Base::saveNRRDChannelCmd(const char* ch, FitsFile::ArchType endian) { OutFitsChannel str(interp, ch); saveNRRD(str, endian); } void Base::saveNRRDSocketCmd(int ss, FitsFile::ArchType endian) { OutFitsSocket str(ss); saveNRRD(str, endian); } void Base::sliceCmd(int ii, int ss) { // IMAGE (ranges 1-n) setSlice(ii,ss); updateMagnifier(); } void Base::smoothCmd(int f, int r) { doSmooth_ = 1; smoothFunction_ = f; smoothRadius_ = r; if (currentContext->fits) { currentContext->fits->setDoSmooth(doSmooth_); currentContext->fits->setSmoothFunction((FitsImage::SmoothFunction)smoothFunction_); currentContext->fits->setSmoothRadius(smoothRadius_); } currentContext->analysis(); updateColorScale(); // for 3d, rebuffer update(MATRIX); } void Base::smoothDeleteCmd() { doSmooth_ = 0; if (currentContext->fits) currentContext->fits->setDoSmooth(doSmooth_); currentContext->analysis(); updateColorScale(); // for 3d, rebuffer update(MATRIX); } void Base::threadsCmd(int th) { if (th>=1) threads_ = th; } // not used // don't know if this is used by anyone else void Base::unloadFitsCmd() { unloadAllFits(); update(MATRIX); } void Base::updateFitsCmd(int now) { // for 3d, rebuffer if (now) { syncUpdate =1; updateNow(MATRIX); syncUpdate =0; } else update(MATRIX); } void Base::updateFitsCmd(int which, BBox bb, int now) { // Note: bb is in IMAGE coords FitsImage* ptr = currentContext->fits; if (which > 0) { for (int ii=0; ii<(which-1); ii++) { if (ptr) ptr = ptr->nextMosaic(); } } if (ptr) { BBox bbb = bb*ptr->imageToRef; Vector ll = mapFromRef(bbb.ll,Coord::CANVAS); Vector lr = mapFromRef(bbb.lr(),Coord::CANVAS); Vector ur = mapFromRef(bbb.ur,Coord::CANVAS); Vector ul = mapFromRef(bbb.ul(),Coord::CANVAS); BBox rr(ll); rr.bound(lr); rr.bound(ur); rr.bound(ul); if (now) { syncUpdate =1; updateNow(BASE, rr); syncUpdate =0; } else update(BASE, rr); } } void Base::updateMagnifierCmd(const Vector& v) { updateMagnifier(v); } void Base::updatePannerCmd() { updatePanner(); } void Base::warpCmd(const Vector& vv) { Vector aa=vv; XWarpPointer(display, None, None, 0, 0, 0, 0, aa[0], aa[1]); } void Base::warpToCmd(const Vector& vv) { Vector aa =vv*canvasToWindow; XWarpPointer(display, None, Tk_WindowId(tkwin), 0, 0, 0, 0, aa[0], aa[1]); } void Base::wcsCmd(Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { wcsSystem_ = sys; wcsSky_ = sky; wcsSkyFormat_ = format; } void Base::wcsAlignCmd(int which) { wcsAlign_ = which; alignWCS(); update(MATRIX); } // used by backup void Base::wcsAlignCmd(int which, Coord::CoordSystem sys, Coord::SkyFrame sky) { wcsAlign_ = which; alignWCS(sys, sky); update(MATRIX); } void Base::wcsAlignCmd(int which, FitsImage* ptr, Coord::CoordSystem sys, Coord::SkyFrame sky) { wcsAlign_ = which; wcsSky_ = sky; alignWCS(ptr, sys); update(MATRIX); } void Base::wcsAppendCmd(int which, int fd) { if (!currentContext->cfits) return; boost::fdistream str(fd); if (!str) { Tcl_AppendResult(interp, " unable to read wcs infomation", NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->appendWCS(hh); rr=rr->nextSlice(); } delete hh; } else result = TCL_ERROR; } void Base::wcsAppendCmd(int which, const char* fn) { if (!currentContext->cfits) return; ifstream str(fn); if (!str) { Tcl_AppendResult(interp, " unable to load wcs file ", fn, NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->appendWCS(hh); rr=rr->nextSlice(); } delete hh; } else result = TCL_ERROR; } void Base::wcsAppendTxtCmd(int which, const char* txt) { if (!currentContext->cfits) return; istringstream str(txt); if (!str) { Tcl_AppendResult(interp, " unable to process text", NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->appendWCS(hh); rr=rr->nextSlice(); } delete hh; } else result = TCL_ERROR; } void Base::wcsResetCmd(int which) { wcsAlt_ =0; if (!currentContext->cfits) return; FitsImage* rr = findAllFits(which); if (rr) while (rr) { rr->resetWCS(); rr=rr->nextSlice(); } else result = TCL_ERROR; } void Base::wcsReplaceCmd(int which, int fd) { if (!currentContext->cfits) return; boost::fdistream str(fd); if (!str) { Tcl_AppendResult(interp, " unable to read wcs infomation", NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->replaceWCS(hh); rr=rr->nextSlice(); } delete hh; wcsAlt_ =1; } else result = TCL_ERROR; } void Base::wcsReplaceCmd(int which, const char* fn) { if (!currentContext->cfits) return; ifstream str(fn); if (!str) { Tcl_AppendResult(interp, " unable to load wcs file ", fn, NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->replaceWCS(hh); rr=rr->nextSlice(); } delete hh; wcsAlt_ =1; } else result = TCL_ERROR; } void Base::wcsReplaceTxtCmd(int which, const char* txt) { if (!currentContext->cfits) return; istringstream str(txt); if (!str) { Tcl_AppendResult(interp, " unable to process text", NULL); result = TCL_ERROR; return; } FitsImage* rr = findAllFits(which); if (rr) { FitsHead* hh = parseWCS(str); while (rr) { rr->replaceWCS(hh); rr=rr->nextSlice(); } delete hh; wcsAlt_ =1; } else result = TCL_ERROR; } void Base::zoomCmd(const Vector& z) { Vector az = ((Vector&)z).abs(); zoom_[0] *= az[0]; zoom_[1] *= az[1]; update(MATRIX); } void Base::zoomToCmd(const Vector& z) { zoom_ = ((Vector&)z).abs(); update(MATRIX); } ����������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametrue.h��������������������������������������������������������������������0000644�0001750�0001750�00000001446�11700666267�015501� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametrue_h__ #define __frametrue_h__ #include "framebase.h" class FrameTrue : public virtual FrameBase { protected: XImage* colormapXM; // rotate dest ximage Pixmap colormapPM; // rotate pixmap GC colormapGCXOR; // GC for interactive rotation int byteorder_; int bitsperpixel_; protected: void encodeTrueColor(int oo, int bb) {byteorder_ = oo; bitsperpixel_ = bb;} virtual void encodeTrueColor(XColor*, char*) =0; virtual void encodeTrueColor(unsigned char*, XImage*) =0; void rotateMotion(); public: FrameTrue(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FrameTrue(); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ciaolex.C����������������������������������������������������������������������0000644�0001750�0001750�00000140053�12032637771�015061� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "ciaolex.C" #line 4 "ciaolex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer ciaoFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *ciaoalloc (yy_size_t ); void *ciaorealloc (void *,yy_size_t ); void ciaofree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 42 #define YY_END_OF_BUFFER 43 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[127] = { 0, 0, 0, 43, 41, 37, 40, 41, 36, 41, 41, 13, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 37, 39, 36, 0, 13, 15, 22, 18, 14, 13, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 38, 15, 24, 20, 14, 23, 19, 17, 0, 26, 16, 0, 0, 0, 14, 0, 0, 2, 0, 0, 0, 6, 8, 0, 0, 0, 0, 25, 21, 28, 27, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 30, 0, 0, 0, 0, 0, 0, 4, 0, 9, 0, 0, 0, 31, 30, 0, 0, 34, 0, 0, 32, 0, 3, 0, 0, 11, 0, 35, 33, 1, 5, 10, 12, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 6, 1, 1, 1, 7, 1, 1, 1, 8, 1, 8, 9, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 1, 1, 1, 1, 1, 1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 1, 21, 22, 23, 24, 25, 1, 26, 27, 28, 29, 30, 1, 31, 32, 1, 1, 33, 1, 1, 1, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 1, 1, 43, 44, 45, 46, 47, 1, 48, 49, 50, 51, 52, 1, 53, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[55] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[128] = { 0, 0, 0, 261, 268, 258, 268, 256, 0, 46, 248, 52, 35, 36, 44, 49, 45, 52, 50, 48, 57, 53, 255, 268, 0, 246, 74, 94, 268, 248, 98, 0, 244, 243, 92, 242, 62, 75, 85, 99, 94, 99, 268, 101, 98, 92, 95, 268, 139, 268, 243, 143, 268, 241, 268, 114, 268, 268, 67, 135, 237, 120, 141, 118, 268, 138, 127, 140, 268, 268, 138, 130, 151, 138, 268, 235, 268, 268, 229, 161, 163, 179, 181, 149, 154, 175, 169, 167, 178, 174, 179, 268, 228, 191, 227, 195, 157, 197, 174, 192, 268, 182, 268, 186, 180, 188, 119, 116, 192, 213, 268, 216, 218, 268, 186, 268, 198, 204, 268, 206, 268, 268, 268, 268, 268, 268, 268, 122 } ; static yyconst flex_int16_t yy_def[128] = { 0, 126, 1, 126, 126, 126, 126, 126, 127, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 126, 11, 126, 126, 126, 126, 11, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 0, 126 } ; static yyconst flex_int16_t yy_nxt[323] = { 0, 4, 5, 6, 7, 4, 8, 4, 9, 10, 11, 4, 12, 13, 14, 15, 16, 4, 4, 4, 4, 4, 4, 4, 17, 18, 19, 4, 4, 4, 20, 4, 4, 21, 12, 13, 14, 15, 16, 4, 4, 4, 4, 4, 4, 4, 17, 18, 19, 4, 4, 4, 20, 4, 4, 25, 26, 28, 36, 29, 37, 30, 31, 32, 38, 39, 40, 33, 34, 41, 43, 35, 45, 46, 44, 42, 47, 58, 80, 49, 36, 50, 37, 51, 26, 63, 38, 39, 40, 33, 34, 41, 43, 35, 45, 46, 44, 42, 47, 52, 60, 53, 61, 28, 27, 29, 64, 63, 27, 54, 55, 65, 66, 57, 34, 67, 68, 69, 70, 71, 72, 73, 78, 24, 79, 49, 106, 50, 64, 106, 61, 54, 55, 65, 66, 57, 34, 67, 68, 69, 70, 71, 72, 73, 74, 59, 75, 83, 49, 48, 50, 62, 84, 48, 54, 55, 85, 81, 57, 34, 86, 87, 88, 82, 89, 90, 74, 111, 75, 83, 98, 79, 92, 93, 84, 99, 54, 55, 85, 81, 57, 34, 86, 87, 88, 82, 89, 90, 94, 95, 96, 97, 98, 100, 101, 102, 103, 99, 104, 105, 107, 93, 108, 114, 109, 95, 112, 97, 115, 116, 117, 118, 119, 122, 123, 100, 101, 102, 103, 120, 104, 105, 110, 108, 113, 114, 111, 124, 111, 125, 115, 116, 117, 118, 119, 122, 123, 108, 106, 79, 110, 120, 91, 121, 110, 113, 113, 61, 77, 124, 76, 125, 62, 59, 58, 56, 48, 22, 27, 23, 22, 126, 110, 126, 126, 121, 126, 113, 3, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 } ; static yyconst flex_int16_t yy_chk[323] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 11, 12, 11, 13, 11, 11, 11, 14, 15, 16, 11, 11, 17, 18, 11, 19, 20, 18, 17, 21, 58, 58, 26, 12, 26, 13, 26, 26, 36, 14, 15, 16, 11, 11, 17, 18, 11, 19, 20, 18, 17, 21, 27, 34, 27, 34, 30, 27, 30, 37, 36, 30, 27, 27, 38, 39, 30, 30, 40, 41, 43, 44, 44, 45, 46, 55, 127, 55, 61, 107, 61, 37, 106, 61, 27, 27, 38, 39, 30, 30, 40, 41, 43, 44, 44, 45, 46, 48, 59, 48, 63, 51, 48, 51, 62, 65, 51, 48, 48, 66, 59, 51, 51, 67, 70, 71, 62, 72, 73, 79, 96, 79, 63, 83, 79, 80, 80, 65, 84, 48, 48, 66, 59, 51, 51, 67, 70, 71, 62, 72, 73, 81, 81, 82, 82, 83, 85, 86, 87, 88, 84, 89, 90, 93, 93, 108, 98, 95, 95, 97, 97, 99, 101, 103, 104, 105, 114, 116, 85, 86, 87, 88, 108, 89, 90, 95, 109, 97, 98, 111, 117, 112, 119, 99, 101, 103, 104, 105, 114, 116, 94, 92, 78, 109, 108, 75, 111, 95, 112, 97, 60, 53, 117, 50, 119, 35, 33, 32, 29, 25, 22, 10, 7, 5, 3, 109, 0, 0, 111, 0, 112, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "ciaolex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "ciaolex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "ciaoparser.H" extern YYSTYPE* ciaolval; /* rules */ #line 535 "ciaolex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 27 "ciaolex.L" #line 638 "ciaolex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 127 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 126 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 29 "ciaolex.L" {return ANNULUS_;} YY_BREAK case 2: YY_RULE_SETUP #line 30 "ciaolex.L" {return BOX_;} YY_BREAK case 3: YY_RULE_SETUP #line 31 "ciaolex.L" {return CIRCLE_;} YY_BREAK case 4: YY_RULE_SETUP #line 32 "ciaolex.L" {return DEBUG_;} YY_BREAK case 5: YY_RULE_SETUP #line 33 "ciaolex.L" {return ELLIPSE_;} YY_BREAK case 6: YY_RULE_SETUP #line 34 "ciaolex.L" {return OFF_;} YY_BREAK case 7: YY_RULE_SETUP #line 35 "ciaolex.L" {return ON_;} YY_BREAK case 8: YY_RULE_SETUP #line 36 "ciaolex.L" {return PIE_;} YY_BREAK case 9: YY_RULE_SETUP #line 37 "ciaolex.L" {return POINT_;} YY_BREAK case 10: YY_RULE_SETUP #line 38 "ciaolex.L" {return POLYGON_;} YY_BREAK case 11: YY_RULE_SETUP #line 39 "ciaolex.L" {return ROTBOX_;} YY_BREAK case 12: YY_RULE_SETUP #line 40 "ciaolex.L" {return VERSION_;} YY_BREAK case 13: YY_RULE_SETUP #line 42 "ciaolex.L" { // Integer ciaolval->integer = atoi(yytext); return INT; } YY_BREAK case 14: #line 48 "ciaolex.L" case 15: YY_RULE_SETUP #line 48 "ciaolex.L" { // Real Number ciaolval->real = atof(yytext); return REAL; } YY_BREAK case 16: #line 54 "ciaolex.L" case 17: YY_RULE_SETUP #line 54 "ciaolex.L" { // degrees yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ANGDEGREE; } YY_BREAK case 18: #line 61 "ciaolex.L" case 19: #line 62 "ciaolex.L" case 20: #line 63 "ciaolex.L" case 21: YY_RULE_SETUP #line 63 "ciaolex.L" { // minutes of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCMINUTE; } YY_BREAK case 22: #line 70 "ciaolex.L" case 23: #line 71 "ciaolex.L" case 24: #line 72 "ciaolex.L" case 25: YY_RULE_SETUP #line 72 "ciaolex.L" { // seconds of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCSECOND; } YY_BREAK case 26: #line 79 "ciaolex.L" case 27: #line 80 "ciaolex.L" case 28: #line 81 "ciaolex.L" case 29: YY_RULE_SETUP #line 81 "ciaolex.L" { // seconds of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCSECOND; } YY_BREAK case 30: #line 88 "ciaolex.L" case 31: YY_RULE_SETUP #line 88 "ciaolex.L" { // Sexagesimal int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 32: #line 96 "ciaolex.L" case 33: YY_RULE_SETUP #line 96 "ciaolex.L" { // HMS int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return HMSSTR; } YY_BREAK case 34: #line 104 "ciaolex.L" case 35: YY_RULE_SETUP #line 104 "ciaolex.L" { // DMS int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return DMSSTR; } YY_BREAK case 36: YY_RULE_SETUP #line 111 "ciaolex.L" { // comment, eat it } YY_BREAK case 37: YY_RULE_SETUP #line 114 "ciaolex.L" { // White Spaces } YY_BREAK case 38: YY_RULE_SETUP #line 117 "ciaolex.L" { // fake line feed return '\n'; } YY_BREAK case 39: /* rule 39 can match eol */ YY_RULE_SETUP #line 121 "ciaolex.L" { // windows line feed return '\n'; } YY_BREAK case 40: /* rule 40 can match eol */ YY_RULE_SETUP #line 125 "ciaolex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 129 "ciaolex.L" { // eof return EOF_; } YY_BREAK case 41: YY_RULE_SETUP #line 133 "ciaolex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 42: YY_RULE_SETUP #line 137 "ciaolex.L" ECHO; YY_BREAK #line 940 "ciaolex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; ciaofree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); ciaofree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ciaorealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ciaorealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 127 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 127 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 126); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) ciaoalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) ciaoalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) ciaofree((void *) b->yy_ch_buf ); ciaofree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)ciaoalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)ciaorealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) ciaoalloc(new_size ); else (yy_start_stack) = (int *) ciaorealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *ciaoalloc (yy_size_t size ) { return (void *) malloc( size ); } void *ciaorealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void ciaofree (void * ptr ) { free( (char *) ptr ); /* see ciaorealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 137 "ciaolex.L" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor8.C�����������������������������������������������������������0000644�0001750�0001750�00000007275�11700666267�017264� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framergbtruecolor8.h" #include "fitsimage.h" // Tk Canvas Widget Function Declarations int FrameRGBTrueColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameRGBTrueColor8 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameRGBTrueColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "framergb", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameRGBTrueColor8Type = { (char*)"framergbtruecolor8", // name sizeof(WidgetOptions), // item size FrameRGBTrueColor8CreateProc, // configProc frameRGBTrueColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameRGBTrueColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameRGBTrueColor8Type); return TCL_OK; } int FrameRGBTrueColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameRGBTrueColor8* frame = new FrameRGBTrueColor8(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameRGBTrueColor8 Member Functions FrameRGBTrueColor8::FrameRGBTrueColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameRGBTrueColor(i,c,item), TrueColor8(visual) { configSpecs = frameRGBTrueColor8Specs; // frame configure options } FrameRGBTrueColor8::~FrameRGBTrueColor8() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/compass.h����������������������������������������������������������������������0000644�0001750�0001750�00000004221�11727727777�015163� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __compass_h__ #define __compass_h__ #include "marker.h" class Compass : public Marker { private: Vector p1; Vector p2; Vector pp1; Vector pp2; double radius; Coord::CoordSystem coordSystem; Coord::SkyFrame skyFrame; char* northText; char* eastText; int northArrow; int eastArrow; private: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderXInclude(Drawable, Coord::InternalSystem, RenderMode) {} GC renderXGC(RenderMode); void renderPS(int); void renderPSInclude(int) {} void renderPSGC(int); #ifdef _MACOSX void renderMACOSX(); void renderMACOSXInclude() {} void renderMACOSXGC(); #endif #ifdef _WIN32 void renderWIN32(); void renderWIN32Include() {} void renderWIN32GC(); #endif void updateHandles(); public: Compass(const Compass&); Compass(Base* parent, const Vector& ctr, double r, const char* n, const char* e, int na, int ea, Coord::CoordSystem, Coord::SkyFrame, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb); ~Compass(); Marker* dup() {return new Compass(*this);} void calcAllBBox(); void edit(const Vector&, int); void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} int isIn(const Vector&); double getRadius() {return radius;} void setRadius(double); void setCoordSystem(Coord::CoordSystem, Coord::SkyFrame); void setLabels(const char*, const char*); void setArrows(int,int); Coord::CoordSystem getSystem() {return coordSystem;} Coord::SkyFrame getSkyFrame() {return skyFrame;} const char* getNorthText() {return northText;} const char* getEastText() {return eastText;} int getNorthArrow() {return northArrow;} int getEastArrow() {return eastArrow;} void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ellipseannulus.h���������������������������������������������������������������0000644�0001750�0001750�00000003301�12030663652�016532� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __ellipseannulus_h__ #define __ellipseannulus_h__ #include "baseellipse.h" class EllipseAnnulus : public BaseEllipse { public: EllipseAnnulus(const EllipseAnnulus&); EllipseAnnulus(Base* p, const Vector& ctr, const Vector& r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); EllipseAnnulus(Base* p, const Vector& ctr, const Vector& inner, const Vector& outer, int num, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); EllipseAnnulus(Base* p, const Vector& ctr, int an, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new EllipseAnnulus(*this);} void edit(const Vector&, int); void editEnd(); int addAnnuli(const Vector&); void analysis(AnalysisTask, int); void analysisRadial(char*, char*, char*, Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void listSAOimage(ostream&, int); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ds9parser.H��������������������������������������������������������������������0000644�0001750�0001750�00000015604�11734430017�015351� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, ANGRADIAN = 262, ARCMINUTE = 263, ARCSECOND = 264, PHYCOORD = 265, IMGCOORD = 266, SEXSTR = 267, HMSSTR = 268, DMSSTR = 269, EOF_ = 270, AMPLIFIER_ = 271, ANNULUS_ = 272, ARCMIN_ = 273, ARCSEC_ = 274, ARROW_ = 275, B1950_ = 276, BACKGROUND_ = 277, BEGIN_ = 278, BOX_ = 279, BOXCIRCLE_ = 280, BPANDA_ = 281, CALLBACK_ = 282, CIRCLE_ = 283, CIRCLE3D_ = 284, COLOR_ = 285, COMPASS_ = 286, COMPOSITE_ = 287, CPANDA_ = 288, CROSS_ = 289, DASH_ = 290, DASHLIST_ = 291, DEBUG_ = 292, DEGREES_ = 293, DELETE_ = 294, DETECTOR_ = 295, DIAMOND_ = 296, ECLIPTIC_ = 297, EDIT_ = 298, ELLIPSE_ = 299, END_ = 300, EPANDA_ = 301, FALSE_ = 302, FIELD_ = 303, FIXED_ = 304, FK4_ = 305, FK4_NO_E_ = 306, FK5_ = 307, FONT_ = 308, GALACTIC_ = 309, GLOBAL_ = 310, HELIOECLIPTIC_ = 311, HIGHLITE_ = 312, ICRS_ = 313, IGNORE_ = 314, IMAGE_ = 315, INCLUDE_ = 316, J2000_ = 317, KEY_ = 318, LINE_ = 319, LINEAR_ = 320, MOVE_ = 321, N_ = 322, NO_ = 323, OFF_ = 324, ON_ = 325, PHYSICAL_ = 326, PIE_ = 327, PIXELS_ = 328, POINT_ = 329, POLYGON_ = 330, PROJECTION_ = 331, PROPERTY_ = 332, ROTATE_ = 333, ROTBOX_ = 334, RULER_ = 335, SELECT_ = 336, SOURCE_ = 337, SUPERGALACTIC_ = 338, TAG_ = 339, TEXT_ = 340, TEXTANGLE_ = 341, TEXTROTATE_ = 342, TILE_ = 343, TRUE_ = 344, VECTOR_ = 345, VERSION_ = 346, UNHIGHLITE_ = 347, UNSELECT_ = 348, UPDATE_ = 349, WCS_ = 350, WCSA_ = 351, WCSB_ = 352, WCSC_ = 353, WCSD_ = 354, WCSE_ = 355, WCSF_ = 356, WCSG_ = 357, WCSH_ = 358, WCSI_ = 359, WCSJ_ = 360, WCSK_ = 361, WCSL_ = 362, WCSM_ = 363, WCSN_ = 364, WCSO_ = 365, WCSP_ = 366, WCSQ_ = 367, WCSR_ = 368, WCSS_ = 369, WCST_ = 370, WCSU_ = 371, WCSV_ = 372, WCSW_ = 373, WCSX_ = 374, WCSY_ = 375, WCSZ_ = 376, WCS0_ = 377, WIDTH_ = 378, X_ = 379, Y_ = 380, YES_ = 381 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define ANGRADIAN 262 #define ARCMINUTE 263 #define ARCSECOND 264 #define PHYCOORD 265 #define IMGCOORD 266 #define SEXSTR 267 #define HMSSTR 268 #define DMSSTR 269 #define EOF_ 270 #define AMPLIFIER_ 271 #define ANNULUS_ 272 #define ARCMIN_ 273 #define ARCSEC_ 274 #define ARROW_ 275 #define B1950_ 276 #define BACKGROUND_ 277 #define BEGIN_ 278 #define BOX_ 279 #define BOXCIRCLE_ 280 #define BPANDA_ 281 #define CALLBACK_ 282 #define CIRCLE_ 283 #define CIRCLE3D_ 284 #define COLOR_ 285 #define COMPASS_ 286 #define COMPOSITE_ 287 #define CPANDA_ 288 #define CROSS_ 289 #define DASH_ 290 #define DASHLIST_ 291 #define DEBUG_ 292 #define DEGREES_ 293 #define DELETE_ 294 #define DETECTOR_ 295 #define DIAMOND_ 296 #define ECLIPTIC_ 297 #define EDIT_ 298 #define ELLIPSE_ 299 #define END_ 300 #define EPANDA_ 301 #define FALSE_ 302 #define FIELD_ 303 #define FIXED_ 304 #define FK4_ 305 #define FK4_NO_E_ 306 #define FK5_ 307 #define FONT_ 308 #define GALACTIC_ 309 #define GLOBAL_ 310 #define HELIOECLIPTIC_ 311 #define HIGHLITE_ 312 #define ICRS_ 313 #define IGNORE_ 314 #define IMAGE_ 315 #define INCLUDE_ 316 #define J2000_ 317 #define KEY_ 318 #define LINE_ 319 #define LINEAR_ 320 #define MOVE_ 321 #define N_ 322 #define NO_ 323 #define OFF_ 324 #define ON_ 325 #define PHYSICAL_ 326 #define PIE_ 327 #define PIXELS_ 328 #define POINT_ 329 #define POLYGON_ 330 #define PROJECTION_ 331 #define PROPERTY_ 332 #define ROTATE_ 333 #define ROTBOX_ 334 #define RULER_ 335 #define SELECT_ 336 #define SOURCE_ 337 #define SUPERGALACTIC_ 338 #define TAG_ 339 #define TEXT_ 340 #define TEXTANGLE_ 341 #define TEXTROTATE_ 342 #define TILE_ 343 #define TRUE_ 344 #define VECTOR_ 345 #define VERSION_ 346 #define UNHIGHLITE_ 347 #define UNSELECT_ 348 #define UPDATE_ 349 #define WCS_ 350 #define WCSA_ 351 #define WCSB_ 352 #define WCSC_ 353 #define WCSD_ 354 #define WCSE_ 355 #define WCSF_ 356 #define WCSG_ 357 #define WCSH_ 358 #define WCSI_ 359 #define WCSJ_ 360 #define WCSK_ 361 #define WCSL_ 362 #define WCSM_ 363 #define WCSN_ 364 #define WCSO_ 365 #define WCSP_ 366 #define WCSQ_ 367 #define WCSR_ 368 #define WCSS_ 369 #define WCST_ 370 #define WCSU_ 371 #define WCSV_ 372 #define WCSW_ 373 #define WCSX_ 374 #define WCSY_ 375 #define WCSZ_ 376 #define WCS0_ 377 #define WIDTH_ 378 #define X_ 379 #define Y_ 380 #define YES_ 381 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 135 "ds9parser.Y" { #define MKBUFSIZE 2048 double real; int integer; char str[MKBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 309 "ds9parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ����������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscalergb.h����������������������������������������������������������������0000644�0001750�0001750�00000002644�11700666266�016330� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscalergb_h__ #define __colorscalergb_h__ #include <tcl.h> #include <X11/Xlib.h> #include "util.h" class ColorScaleRGB { protected: int size_; unsigned char* psColors_; public: ColorScaleRGB(int); virtual ~ColorScaleRGB(); int size() {return size_;} const unsigned char* psColors() {return psColors_;} }; class LinearScaleRGB : public virtual ColorScaleRGB { public: LinearScaleRGB(int, int, unsigned char*, int); }; class LogScaleRGB : public virtual ColorScaleRGB { public: LogScaleRGB(int, int, unsigned char*, int, double); }; class PowScaleRGB : public virtual ColorScaleRGB { public: PowScaleRGB(int, int, unsigned char*, int, double); }; class SqrtScaleRGB : public virtual ColorScaleRGB { public: SqrtScaleRGB(int, int, unsigned char*, int); }; class SquaredScaleRGB : public virtual ColorScaleRGB { public: SquaredScaleRGB(int, int, unsigned char*, int); }; class AsinhScaleRGB : public virtual ColorScaleRGB { public: AsinhScaleRGB(int, int, unsigned char*, int); }; class SinhScaleRGB : public virtual ColorScaleRGB { public: SinhScaleRGB(int, int, unsigned char*, int); }; class HistEquScaleRGB : public virtual ColorScaleRGB { public: HistEquScaleRGB(int, int, unsigned char*, int, double*, int); }; #endif ��������������������������������������������������������������������������������������������./saods9/saotk/frame/compass.C����������������������������������������������������������������������0000644�0001750�0001750�00000040025�11771121477�015100� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "compass.h" #include "fitsimage.h" Compass::Compass(const Compass& a) : Marker(a) { p1 = a.p1; p2 = a.p2; pp1 = a.pp1; pp2 = a.pp2; radius = a.radius; coordSystem = a.coordSystem; skyFrame = a.skyFrame; northText = dupstr(a.northText); eastText = dupstr(a.eastText); northArrow = a.northArrow; eastArrow = a.eastArrow; } Compass::Compass(Base* p, const Vector& ctr, double r, const char* n, const char* e, int na, int ea, Coord::CoordSystem sys, Coord::SkyFrame sky, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb) : Marker(p, ctr, 0, clr, dsh, w, f, t, prop, c, tag, cb) { coordSystem = sys; skyFrame = sky; radius = r; northText = dupstr(n); eastText = dupstr(e); northArrow = na; eastArrow = ea; strcpy(type_,"compass"); handle = new Vector[3]; numHandle = 3; updateBBox(); } Compass::~Compass() { if (northText) delete [] northText; if (eastText) delete [] eastText; } void Compass::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector aa = parent->mapFromRef(center,sys); Vector bb = parent->mapFromRef(p1,sys); Vector cc = parent->mapFromRef(p2,sys); Vector dd = parent->mapFromRef(pp1,sys); Vector ee = parent->mapFromRef(pp2,sys); if (northArrow) { bb = modifyArrow(center,p1,sys); renderXArrow(drawable, center, p1, sys, lgc); } if (eastArrow) { cc = modifyArrow(center,p2,sys); renderXArrow(drawable, center, p2, sys, lgc); } XDrawLine(display, drawable, lgc, aa[0], aa[1], bb[0], bb[1]); XDrawLine(display, drawable, lgc, aa[0], aa[1], cc[0], cc[1]); if (tkfont_) { XSetFont(display, lgc, Tk_FontId(tkfont_)); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); if (northText) { float r1 = Tk_TextWidth(tkfont_, northText, strlen(northText))/2.; float r2 = metrics.linespace/2.; double angle = (bb-aa).angle(); Vector ddd = dd * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); Tk_DrawChars(display, drawable, lgc, tkfont_, northText, strlen(northText), ddd[0], ddd[1]); } if (eastText) { float r1 = Tk_TextWidth(tkfont_, eastText, strlen(eastText))/2.; float r2 = metrics.linespace/2.; double angle = (cc-aa).angle(); Vector eee = ee * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); Tk_DrawChars(display, drawable, lgc, tkfont_, eastText, strlen(eastText), eee[0], eee[1]); } } } GC Compass::renderXGC(RenderMode mode) { switch (mode) { case SRC: XSetForeground(display, gc, color); renderXLineNoDash(gc); return gc; case XOR: renderXLineDash(gcxor); return gcxor; } } void Compass::renderPS(int mode) { renderPSGC(mode); Vector aa = parent->mapFromRef(center,Coord::CANVAS); Vector bb = parent->mapFromRef(p1,Coord::CANVAS); Vector cc = parent->mapFromRef(p2,Coord::CANVAS); Vector dd = parent->mapFromRef(pp1,Coord::CANVAS); Vector ee = parent->mapFromRef(pp2,Coord::CANVAS); if (northArrow) { bb = modifyArrow(center,p1,Coord::CANVAS); renderPSArrow(center,p1,Coord::CANVAS); } if (eastArrow) { cc = modifyArrow(center,p2,Coord::CANVAS); renderPSArrow(center,p2,Coord::CANVAS); } { ostringstream str; str << "newpath " << aa.TkCanvasPs(parent->canvas) << "moveto" << bb.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl; str << "newpath " << aa.TkCanvasPs(parent->canvas) << "moveto" << cc.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl; str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } if (psfont_) { ostringstream str; const char* ff = Tk_NameOfFont(psfont_); str << '/' << psFontName(ff) << " findfont " << int(psFontSize(ff)*parent->getDisplayRatio()) << " scalefont setfont" << endl; if (northText) { double angle = (bb-aa).angle(); Vector ddd = dd.TkCanvasPs(parent->canvas); str << "gsave" << endl << "newpath " << endl << ddd << " moveto" << endl << '(' << psQuote(northText) << ')' << endl // bbox << "dup true charpath pathbbox " << endl << "closepath " << endl // text llx lly urx ury // dup bbox << "3 index 3 index 3 index 3 index " << endl // text llx lly urx ury llx lly urx ury // Translate(-r1,(metrics.ascent-metrics.descent)/2.) << "3 -1 roll sub 3.6 div neg " << endl << "3 1 roll sub 2 div exch " << endl // text llx lly urx ury Sx Sy // reorder << "6 1 roll 6 1 roll " << endl // text Sx Sy llx lly urx ury // Translate(r1*cos(angle),r2*sin(angle)) << "3 -1 roll sub 2 div neg " << endl << "3 1 roll sub 2 div exch " << endl << radToDeg(angle) << " sin mul exch " << endl << radToDeg(angle) << " cos mul neg exch " << endl // text Sx Sy Tx Ty // add << "3 -1 roll add " << endl << "3 1 roll add exch " << endl // text Fx Fy << ddd << " moveto rmoveto show " << endl << "grestore" << endl; } if (eastText) { double angle = (cc-aa).angle(); Vector eee = ee.TkCanvasPs(parent->canvas); str << "gsave" << endl << "newpath " << endl << eee << " moveto" << endl << '(' << psQuote(eastText) << ')' << endl << "dup true charpath pathbbox " << "closepath " << endl << "3 index 3 index 3 index 3 index " << endl << "3 -1 roll sub 3.6 div neg " << "3 1 roll sub 2 div exch " << endl << "6 1 roll 6 1 roll " << endl << "3 -1 roll sub 2 div neg " << "3 1 roll sub 2 div exch " << endl << radToDeg(angle) << " sin mul exch " << radToDeg(angle) << " cos mul neg exch " << endl << "3 -1 roll add " << "3 1 roll add exch " << endl << eee << " moveto rmoveto show " << endl << "grestore" << endl; } str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } void Compass::renderPSGC(int mode) { renderPSColor(mode, parent->getXColor(colorName)); renderPSLineNoDash(); } #ifdef _MACOSX void Compass::renderMACOSX() { renderMACOSXGC(); Vector aa = parent->mapFromRef(center,Coord::CANVAS); Vector bb = parent->mapFromRef(p1,Coord::CANVAS); Vector cc = parent->mapFromRef(p2,Coord::CANVAS); Vector dd = parent->mapFromRef(pp1,Coord::CANVAS); Vector ee = parent->mapFromRef(pp2,Coord::CANVAS); if (northArrow) { bb = modifyArrow(center,p1,Coord::CANVAS); renderMACOSXArrow(center,p1,Coord::CANVAS); } if (eastArrow) { cc = modifyArrow(center,p2,Coord::CANVAS); renderMACOSXArrow(center,p2,Coord::CANVAS); } macosxDrawLine(aa,bb); macosxDrawLine(aa,cc); if (psfont_) { Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(psfont_, &psdstr); macosxFont(Tcl_DStringValue(&psdstr), psSize); Tcl_DStringFree(&psdstr); Tk_FontMetrics metrics; Tk_GetFontMetrics(psfont_, &metrics); if (northText) { float r1 = Tk_TextWidth(psfont_, northText, strlen(northText))/2.; float r2 = metrics.linespace/2.; double angle = (bb-aa).angle(); Vector ddd = dd * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); macosxDrawText(ddd, 0, northText); } if (eastText) { float r1 = Tk_TextWidth(psfont_, eastText, strlen(eastText))/2.; float r2 = metrics.linespace/2.; double angle = (c-a).angle(); Vector eee = ee * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); macosxDrawText(eee, 0, eastText); } } } void Compass::renderMACOSXGC() { macosxColor(parent->getXColor(colorName)); renderMACOSXLineNoDash(); } #endif #ifdef _WIN32 void Compass::renderWIN32() { renderWIN32GC(); Vector aa = parent->mapFromRef(center,Coord::CANVAS); Vector bb = parent->mapFromRef(p1,Coord::CANVAS); Vector cc = parent->mapFromRef(p2,Coord::CANVAS); Vector dd = parent->mapFromRef(pp1,Coord::CANVAS); Vector ee = parent->mapFromRef(pp2,Coord::CANVAS); if (northArrow) { bb = modifyArrow(center,p1,Coord::CANVAS); renderWIN32Arrow(center,p1,Coord::CANVAS); } if (eastArrow) { cc = modifyArrow(center,p2,Coord::CANVAS); renderWIN32Arrow(center,p2,Coord::CANVAS); } win32DrawLine(aa,bb); win32DrawLine(aa,cc); if (tkfont_) { win32Font(tkfont_); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); if (northText) { float r1 = Tk_TextWidth(tkfont_, northText, strlen(northText))/2.; float r2 = metrics.linespace/2.; double angle = (bb-aa).angle(); Vector ddd = dd * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); win32DrawText(ddd, 0, northText); } if (eastText) { float r1 = Tk_TextWidth(tkfont_, eastText, strlen(eastText))/2.; float r2 = metrics.linespace/2.; double angle = (cc-aa).angle(); Vector eee = ee * Translate(r1*cos(angle),r2*sin(angle)) * Translate(-r1,(metrics.ascent-metrics.descent)/2.); win32DrawText(eee, 0, eastText); } } } void Compass::renderWIN32GC() { win32Color(parent->getXColor(colorName)); renderWIN32LineNoDash(); } #endif void Compass::updateHandles() { // calc p1, p2 FitsImage* ptr = parent->findFits(coordSystem,center); Vector orval = ptr->mapFromRef(center, coordSystem, skyFrame); double delta = ptr->mapLenFromRef(1, coordSystem); Vector npix = ptr->mapToRef(Vector(orval[0],orval[1]+delta), coordSystem, skyFrame); Vector epix = ptr->mapToRef(Vector(orval[0]+delta,orval[1]), coordSystem, skyFrame); Vector north = (npix - center).normalize(); Vector east = (epix - center).normalize(); // calc text points pp1,pp2 Matrix r = Scale(radius)*Scale(parent->zoom()).invert(); Matrix rr = Scale(5)*Scale(parent->zoom()).invert(); p1 = center + north*r; p2 = center + east*r; pp1 = p1 + north*rr; pp2 = p2 + east*rr; // generate handles handle[0] = parent->mapFromRef(center,Coord::CANVAS); handle[1] = parent->mapFromRef(p1,Coord::CANVAS); handle[2] = parent->mapFromRef(p2,Coord::CANVAS); } void Compass::calcAllBBox() { // make room for text Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); Vector a = parent->mapFromRef(center,Coord::CANVAS); Vector b = parent->mapFromRef(p1,Coord::CANVAS); Vector c = parent->mapFromRef(p2,Coord::CANVAS); Vector bb = parent->mapFromRef(pp1,Coord::CANVAS); Vector cc = parent->mapFromRef(pp2,Coord::CANVAS); if (northText) { float r1 = Tk_TextWidth(tkfont_, northText, strlen(northText))/2.; float r2 = metrics.linespace/2.; double angle = (b-a).angle(); Vector bbb = bb * Translate(r1*cos(angle),r2*sin(angle)); bbox.bound(bbb * Translate(-r1,(metrics.ascent-metrics.descent)/2.)); bbox.bound(bbb * Translate(-r1,-metrics.ascent/2.-3*metrics.descent/2.)); bbox.bound(bbb * Translate(r1,(metrics.ascent-metrics.descent)/2.)); bbox.bound(bbb * Translate(r1,-metrics.ascent/2.-3*metrics.descent/2.)); } if (eastText) { float r1 = Tk_TextWidth(tkfont_, eastText, strlen(eastText))/2.; float r2 = metrics.linespace/2.; double angle = (c-a).angle(); Vector ccc = cc * Translate(r1*cos(angle),r2*sin(angle)); bbox.bound(ccc * Translate(-r1,(metrics.ascent-metrics.descent)/2.)); bbox.bound(ccc * Translate(-r1,-metrics.ascent/2.-3*metrics.descent/2.)); bbox.bound(ccc * Translate(r1,(metrics.ascent-metrics.descent)/2.)); bbox.bound(ccc * Translate(r1,-metrics.ascent/2.-3*metrics.descent/2.)); } Marker::calcAllBBox(); } void Compass::edit(const Vector& v, int h) { radius = (v * Translate(-center) * Scale(parent->zoom())).length(); updateBBox(); doCallBack(CallBack::EDITCB); } int Compass::isIn(const Vector& vv) { /* v[0]-- x value of point being tested v[1]-- y value of point being tested This algorithm is from "An Introduction to Ray Tracing", Academic Press, 1989, edited by Andrew Glassner, pg 53 -- a point lies in a polygon if a line is extended from the point to infinite in any direction and the number of intersections with the polygon is odd. This is valid for both concave and convex polygons. Points on a vertex are considered inside. Points on a edge are considered inside. */ Vector v = parent->mapToRef(vv,Coord::CANVAS); int crossings = 0; // number of crossings Vector bb[4]; bb[0] = center - v; bb[1] = p1 - v; bb[2] = p2 - v; bb[3] = bb[0]; Vector v1; Vector v2 = bb[0]; int sign = ((v2[1])>=0) ? 1 : -1; // init sign // for all edges int done = 0; for (int j=1; j<4; j++) { // look at next two vertices v1 = v2; v2 = bb[j]; int nextSign = (v2[1]>=0) ? 1 : -1; // sign holder for p2 if (sign != nextSign) { if (v1[0]>0 && v2[0]>0) crossings++; else if (v1[0]>0 || v2[0]>0) { if (v1[0]-(v1[1]*(v2[0]-v1[0])/(v2[1]-v1[1])) > 0) crossings++; } sign = nextSign; } } return fmod(float(crossings),float(2)) ? 1 : 0; // if odd, point is inside } void Compass::setRadius(double r) { radius = r; updateBBox(); doCallBack(CallBack::EDITCB); } void Compass::setArrows(int n, int e) { northArrow = n; eastArrow = e; updateBBox(); doCallBack(CallBack::EDITCB); } void Compass::setLabels(const char* n, const char* e) { northText = dupstr(n); eastText = dupstr(e); updateBBox(); doCallBack(CallBack::EDITCB); } void Compass::setCoordSystem(Coord::CoordSystem sys, Coord::SkyFrame sky) { coordSystem = sys; skyFrame = sky; updateBBox(); } // list void Compass::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ptr->mapLenFromRef(radius,sys) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ptr->mapLenFromRef(radius,sys,Coord::ARCSEC) << '"' << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << ptr->mapLenFromRef(radius,sys,Coord::ARCSEC) << '"' << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << ptr->mapLenFromRef(radius,sys) << ')'; } } } if (conj) str << " ||"; str << " compass="; coord.listCoordSystem(str, coordSystem, skyFrame, 1, ptr->hasWCSCel(coordSystem)); str << " {" << northText << "} {" << eastText << "} " << northArrow << ' ' << eastArrow; listProperties(str, 0); } } void Compass::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); double rr = ptr->mapLenFromRef(radius,sys,Coord::ARCSEC); ostringstream pstr; coord.listCoordSystem(pstr, coordSystem, skyFrame, 0, ptr->hasWCSCel(coordSystem)); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRow(XMLR,rr); XMLRow(XMLPARAM,(char*)(pstr.str().c_str())); XMLRow(XMLPARAM2,northText); XMLRow(XMLPARAM3,eastText); XMLRow(XMLPARAM4,northArrow); XMLRow(XMLPARAM5,eastArrow); XMLRowProps(ptr,sys); XMLRowEnd(str); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/parser.C�����������������������������������������������������������������������0000644�0001750�0001750�00001470155�12131563542�014735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse frparse #define yylex frlex #define yyerror frerror #define yylval frlval #define yychar frchar #define yydebug frdebug #define yynerrs frnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, POINTER = 261, ANGDEGREE = 262, ANGRADIAN = 263, SEXSTR = 264, HMSSTR = 265, DMSSTR = 266, ABOUT_ = 267, AIP_ = 268, ALLOC_ = 269, ALLOCGZ_ = 270, ALIGN_ = 271, ALL_ = 272, ALT_ = 273, AMPLIFIER_ = 274, ANALYSIS_ = 275, ANGLE_ = 276, ANNULUS_ = 277, APPEND_ = 278, ARCMIN_ = 279, ARCSEC_ = 280, ARRAY_ = 281, ARROW_ = 282, ASINH_ = 283, AST_ = 284, AUTO_ = 285, AUX_ = 286, AVERAGE_ = 287, B1950_ = 288, BACK_ = 289, BASE_ = 290, BBOX_ = 291, BEGIN_ = 292, BG_ = 293, BIG_ = 294, BIGENDIAN_ = 295, BIN_ = 296, BITPIX_ = 297, BLOCK_ = 298, BLT_ = 299, BORDER_ = 300, BOX_ = 301, BOXANNULUS_ = 302, BOXCAR_ = 303, BOXCIRCLE_ = 304, BPANDA_ = 305, BUFFER_ = 306, BW_ = 307, CALLBACK_ = 308, CANVAS_ = 309, CATALOG_ = 310, CELESTRIAL_ = 311, CENTER_ = 312, CENTROID_ = 313, CHANNEL_ = 314, CIRCLE_ = 315, CIAO_ = 316, CLEAR_ = 317, CLIP_ = 318, COLOR_ = 319, COLORBAR_ = 320, COLORMAP_ = 321, COLORSCALE_ = 322, COLORSPACE_ = 323, COLS_ = 324, COLUMN_ = 325, COMMAND_ = 326, COMPASS_ = 327, COMPOSITE_ = 328, COMPRESS_ = 329, CONTOUR_ = 330, CONTRAST_ = 331, COORDINATES_ = 332, COPY_ = 333, COUNT_ = 334, CPANDA_ = 335, CREATE_ = 336, CROP_ = 337, CROSS_ = 338, CROSSHAIR_ = 339, CUBE_ = 340, CURSOR_ = 341, CUT_ = 342, CMYK_ = 343, DASH_ = 344, DASHLIST_ = 345, DATA_ = 346, DATAMIN_ = 347, DATASEC_ = 348, DEBUG_ = 349, DEGREES_ = 350, DEFAULT_ = 351, DELETE_ = 352, DEPTH_ = 353, DETECTOR_ = 354, DIAMOND_ = 355, DIM_ = 356, DS9_ = 357, EDIT_ = 358, ECLIPTIC_ = 359, ELLIPSE_ = 360, ELLIPSEANNULUS_ = 361, END_ = 362, EPANDA_ = 363, EQUATORIAL_ = 364, ERASE_ = 365, EXT_ = 366, FACTOR_ = 367, FALSE_ = 368, FILE_ = 369, FILTER_ = 370, FIT_ = 371, FITS_ = 372, FITSY_ = 373, FIXED_ = 374, FK4_ = 375, FK4_NO_E_ = 376, FK5_ = 377, FONT_ = 378, FROM_ = 379, FRONT_ = 380, FULL_ = 381, FUNCTION_ = 382, GALACTIC_ = 383, GAUSSIAN_ = 384, GET_ = 385, GLOBAL_ = 386, GRAPHICS_ = 387, GRAY_ = 388, GRID_ = 389, GZ_ = 390, HANDLE_ = 391, HAS_ = 392, HEAD_ = 393, HEADER_ = 394, HEIGHT_ = 395, HELIOECLIPTIC_ = 396, HIDE_ = 397, HIGH_ = 398, HIGHLITE_ = 399, HISTEQU_ = 400, HISTOGRAM_ = 401, HORIZONTAL_ = 402, ICRS_ = 403, ID_ = 404, IIS_ = 405, IMAGE_ = 406, INCLUDE_ = 407, INCR_ = 408, INFO_ = 409, INTEGER_ = 410, ITERATION_ = 411, IRAF_ = 412, IRAFMIN_ = 413, J2000_ = 414, KEY_ = 415, KEYWORD_ = 416, LABEL_ = 417, LENGTH_ = 418, LEVEL_ = 419, LITTLE_ = 420, LITTLEENDIAN_ = 421, LINE_ = 422, LINEAR_ = 423, LIST_ = 424, LOAD_ = 425, LOCAL_ = 426, LOG_ = 427, LOW_ = 428, MACOSX_ = 429, MAGNIFIER_ = 430, MATCH_ = 431, MAP_ = 432, MARK_ = 433, MARKER_ = 434, MASK_ = 435, MESSAGE_ = 436, METHOD_ = 437, MINMAX_ = 438, MIP_ = 439, MMAP_ = 440, MMAPINCR_ = 441, MOSAIC_ = 442, MODE_ = 443, MOTION_ = 444, MOVE_ = 445, NAME_ = 446, NAN_ = 447, NATIVE_ = 448, NAXES_ = 449, NEW_ = 450, NEXT_ = 451, NO_ = 452, NONE_ = 453, NOW_ = 454, NRRD_ = 455, NUMBER_ = 456, OBJECT_ = 457, OFF_ = 458, ON_ = 459, ONLY_ = 460, OPTION_ = 461, ORIENT_ = 462, PAN_ = 463, PANNER_ = 464, PARAM_ = 465, PARSER_ = 466, PASTE_ = 467, PERF_ = 468, PHOTO_ = 469, PHYSICAL_ = 470, PIXEL_ = 471, PLOT2D_ = 472, PLOT3D_ = 473, POINT_ = 474, POINTER_ = 475, POLYGON_ = 476, POSTSCRIPT_ = 477, POW_ = 478, PRINT_ = 479, PRESERVE_ = 480, PROJECTION_ = 481, PROPERTY_ = 482, PUBLICATION_ = 483, PROS_ = 484, RADIAL_ = 485, RADIUS_ = 486, REGION_ = 487, REPLACE_ = 488, RESAMPLE_ = 489, RESET_ = 490, RESOLUTION_ = 491, RGB_ = 492, ROOT_ = 493, ROTATE_ = 494, RULER_ = 495, SAMPLE_ = 496, SAOIMAGE_ = 497, SAOTNG_ = 498, SAVE_ = 499, SCALE_ = 500, SCAN_ = 501, SCIENTIFIC_ = 502, SCOPE_ = 503, SEGMENT_ = 504, SELECT_ = 505, SET_ = 506, SEXAGESIMAL_ = 507, SHAPE_ = 508, SHARED_ = 509, SHIFT_ = 510, SHMID_ = 511, SHOW_ = 512, SINH_ = 513, SIZE_ = 514, SLICE_ = 515, SMMAP_ = 516, SMOOTH_ = 517, SOCKET_ = 518, SOCKETGZ_ = 519, SOURCE_ = 520, SQRT_ = 521, SQUARED_ = 522, SSHARED_ = 523, STATS_ = 524, STATUS_ = 525, SUPERGALACTIC_ = 526, SUM_ = 527, SYSTEM_ = 528, TABLE_ = 529, TAG_ = 530, TEMPLATE_ = 531, TEXT_ = 532, THREADS_ = 533, THREED_ = 534, THRESHOLD_ = 535, THICK_ = 536, TRANSPARENCY_ = 537, TO_ = 538, TOGGLE_ = 539, TOPHAT_ = 540, TRUE_ = 541, TYPE_ = 542, UNDO_ = 543, UNHIGHLITE_ = 544, UNLOAD_ = 545, UNSELECT_ = 546, UPDATE_ = 547, USER_ = 548, VALUE_ = 549, VAR_ = 550, VIEW_ = 551, VECTOR_ = 552, VERSION_ = 553, VERTEX_ = 554, VERTICAL_ = 555, WARP_ = 556, WCS_ = 557, WCSA_ = 558, WCSB_ = 559, WCSC_ = 560, WCSD_ = 561, WCSE_ = 562, WCSF_ = 563, WCSG_ = 564, WCSH_ = 565, WCSI_ = 566, WCSJ_ = 567, WCSK_ = 568, WCSL_ = 569, WCSM_ = 570, WCSN_ = 571, WCSO_ = 572, WCSP_ = 573, WCSQ_ = 574, WCSR_ = 575, WCSS_ = 576, WCST_ = 577, WCSU_ = 578, WCSV_ = 579, WCSW_ = 580, WCSX_ = 581, WCSY_ = 582, WCSZ_ = 583, WCS0_ = 584, WFPC2_ = 585, WIDTH_ = 586, WIN32_ = 587, XML_ = 588, XY_ = 589, YES_ = 590, ZMAX_ = 591, ZSCALE_ = 592, ZOOM_ = 593 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define POINTER 261 #define ANGDEGREE 262 #define ANGRADIAN 263 #define SEXSTR 264 #define HMSSTR 265 #define DMSSTR 266 #define ABOUT_ 267 #define AIP_ 268 #define ALLOC_ 269 #define ALLOCGZ_ 270 #define ALIGN_ 271 #define ALL_ 272 #define ALT_ 273 #define AMPLIFIER_ 274 #define ANALYSIS_ 275 #define ANGLE_ 276 #define ANNULUS_ 277 #define APPEND_ 278 #define ARCMIN_ 279 #define ARCSEC_ 280 #define ARRAY_ 281 #define ARROW_ 282 #define ASINH_ 283 #define AST_ 284 #define AUTO_ 285 #define AUX_ 286 #define AVERAGE_ 287 #define B1950_ 288 #define BACK_ 289 #define BASE_ 290 #define BBOX_ 291 #define BEGIN_ 292 #define BG_ 293 #define BIG_ 294 #define BIGENDIAN_ 295 #define BIN_ 296 #define BITPIX_ 297 #define BLOCK_ 298 #define BLT_ 299 #define BORDER_ 300 #define BOX_ 301 #define BOXANNULUS_ 302 #define BOXCAR_ 303 #define BOXCIRCLE_ 304 #define BPANDA_ 305 #define BUFFER_ 306 #define BW_ 307 #define CALLBACK_ 308 #define CANVAS_ 309 #define CATALOG_ 310 #define CELESTRIAL_ 311 #define CENTER_ 312 #define CENTROID_ 313 #define CHANNEL_ 314 #define CIRCLE_ 315 #define CIAO_ 316 #define CLEAR_ 317 #define CLIP_ 318 #define COLOR_ 319 #define COLORBAR_ 320 #define COLORMAP_ 321 #define COLORSCALE_ 322 #define COLORSPACE_ 323 #define COLS_ 324 #define COLUMN_ 325 #define COMMAND_ 326 #define COMPASS_ 327 #define COMPOSITE_ 328 #define COMPRESS_ 329 #define CONTOUR_ 330 #define CONTRAST_ 331 #define COORDINATES_ 332 #define COPY_ 333 #define COUNT_ 334 #define CPANDA_ 335 #define CREATE_ 336 #define CROP_ 337 #define CROSS_ 338 #define CROSSHAIR_ 339 #define CUBE_ 340 #define CURSOR_ 341 #define CUT_ 342 #define CMYK_ 343 #define DASH_ 344 #define DASHLIST_ 345 #define DATA_ 346 #define DATAMIN_ 347 #define DATASEC_ 348 #define DEBUG_ 349 #define DEGREES_ 350 #define DEFAULT_ 351 #define DELETE_ 352 #define DEPTH_ 353 #define DETECTOR_ 354 #define DIAMOND_ 355 #define DIM_ 356 #define DS9_ 357 #define EDIT_ 358 #define ECLIPTIC_ 359 #define ELLIPSE_ 360 #define ELLIPSEANNULUS_ 361 #define END_ 362 #define EPANDA_ 363 #define EQUATORIAL_ 364 #define ERASE_ 365 #define EXT_ 366 #define FACTOR_ 367 #define FALSE_ 368 #define FILE_ 369 #define FILTER_ 370 #define FIT_ 371 #define FITS_ 372 #define FITSY_ 373 #define FIXED_ 374 #define FK4_ 375 #define FK4_NO_E_ 376 #define FK5_ 377 #define FONT_ 378 #define FROM_ 379 #define FRONT_ 380 #define FULL_ 381 #define FUNCTION_ 382 #define GALACTIC_ 383 #define GAUSSIAN_ 384 #define GET_ 385 #define GLOBAL_ 386 #define GRAPHICS_ 387 #define GRAY_ 388 #define GRID_ 389 #define GZ_ 390 #define HANDLE_ 391 #define HAS_ 392 #define HEAD_ 393 #define HEADER_ 394 #define HEIGHT_ 395 #define HELIOECLIPTIC_ 396 #define HIDE_ 397 #define HIGH_ 398 #define HIGHLITE_ 399 #define HISTEQU_ 400 #define HISTOGRAM_ 401 #define HORIZONTAL_ 402 #define ICRS_ 403 #define ID_ 404 #define IIS_ 405 #define IMAGE_ 406 #define INCLUDE_ 407 #define INCR_ 408 #define INFO_ 409 #define INTEGER_ 410 #define ITERATION_ 411 #define IRAF_ 412 #define IRAFMIN_ 413 #define J2000_ 414 #define KEY_ 415 #define KEYWORD_ 416 #define LABEL_ 417 #define LENGTH_ 418 #define LEVEL_ 419 #define LITTLE_ 420 #define LITTLEENDIAN_ 421 #define LINE_ 422 #define LINEAR_ 423 #define LIST_ 424 #define LOAD_ 425 #define LOCAL_ 426 #define LOG_ 427 #define LOW_ 428 #define MACOSX_ 429 #define MAGNIFIER_ 430 #define MATCH_ 431 #define MAP_ 432 #define MARK_ 433 #define MARKER_ 434 #define MASK_ 435 #define MESSAGE_ 436 #define METHOD_ 437 #define MINMAX_ 438 #define MIP_ 439 #define MMAP_ 440 #define MMAPINCR_ 441 #define MOSAIC_ 442 #define MODE_ 443 #define MOTION_ 444 #define MOVE_ 445 #define NAME_ 446 #define NAN_ 447 #define NATIVE_ 448 #define NAXES_ 449 #define NEW_ 450 #define NEXT_ 451 #define NO_ 452 #define NONE_ 453 #define NOW_ 454 #define NRRD_ 455 #define NUMBER_ 456 #define OBJECT_ 457 #define OFF_ 458 #define ON_ 459 #define ONLY_ 460 #define OPTION_ 461 #define ORIENT_ 462 #define PAN_ 463 #define PANNER_ 464 #define PARAM_ 465 #define PARSER_ 466 #define PASTE_ 467 #define PERF_ 468 #define PHOTO_ 469 #define PHYSICAL_ 470 #define PIXEL_ 471 #define PLOT2D_ 472 #define PLOT3D_ 473 #define POINT_ 474 #define POINTER_ 475 #define POLYGON_ 476 #define POSTSCRIPT_ 477 #define POW_ 478 #define PRINT_ 479 #define PRESERVE_ 480 #define PROJECTION_ 481 #define PROPERTY_ 482 #define PUBLICATION_ 483 #define PROS_ 484 #define RADIAL_ 485 #define RADIUS_ 486 #define REGION_ 487 #define REPLACE_ 488 #define RESAMPLE_ 489 #define RESET_ 490 #define RESOLUTION_ 491 #define RGB_ 492 #define ROOT_ 493 #define ROTATE_ 494 #define RULER_ 495 #define SAMPLE_ 496 #define SAOIMAGE_ 497 #define SAOTNG_ 498 #define SAVE_ 499 #define SCALE_ 500 #define SCAN_ 501 #define SCIENTIFIC_ 502 #define SCOPE_ 503 #define SEGMENT_ 504 #define SELECT_ 505 #define SET_ 506 #define SEXAGESIMAL_ 507 #define SHAPE_ 508 #define SHARED_ 509 #define SHIFT_ 510 #define SHMID_ 511 #define SHOW_ 512 #define SINH_ 513 #define SIZE_ 514 #define SLICE_ 515 #define SMMAP_ 516 #define SMOOTH_ 517 #define SOCKET_ 518 #define SOCKETGZ_ 519 #define SOURCE_ 520 #define SQRT_ 521 #define SQUARED_ 522 #define SSHARED_ 523 #define STATS_ 524 #define STATUS_ 525 #define SUPERGALACTIC_ 526 #define SUM_ 527 #define SYSTEM_ 528 #define TABLE_ 529 #define TAG_ 530 #define TEMPLATE_ 531 #define TEXT_ 532 #define THREADS_ 533 #define THREED_ 534 #define THRESHOLD_ 535 #define THICK_ 536 #define TRANSPARENCY_ 537 #define TO_ 538 #define TOGGLE_ 539 #define TOPHAT_ 540 #define TRUE_ 541 #define TYPE_ 542 #define UNDO_ 543 #define UNHIGHLITE_ 544 #define UNLOAD_ 545 #define UNSELECT_ 546 #define UPDATE_ 547 #define USER_ 548 #define VALUE_ 549 #define VAR_ 550 #define VIEW_ 551 #define VECTOR_ 552 #define VERSION_ 553 #define VERTEX_ 554 #define VERTICAL_ 555 #define WARP_ 556 #define WCS_ 557 #define WCSA_ 558 #define WCSB_ 559 #define WCSC_ 560 #define WCSD_ 561 #define WCSE_ 562 #define WCSF_ 563 #define WCSG_ 564 #define WCSH_ 565 #define WCSI_ 566 #define WCSJ_ 567 #define WCSK_ 568 #define WCSL_ 569 #define WCSM_ 570 #define WCSN_ 571 #define WCSO_ 572 #define WCSP_ 573 #define WCSQ_ 574 #define WCSR_ 575 #define WCSS_ 576 #define WCST_ 577 #define WCSU_ 578 #define WCSV_ 579 #define WCSW_ 580 #define WCSX_ 581 #define WCSY_ 582 #define WCSZ_ 583 #define WCS0_ 584 #define WFPC2_ 585 #define WIDTH_ 586 #define WIN32_ 587 #define XML_ 588 #define XY_ 589 #define YES_ 590 #define ZMAX_ 591 #define ZSCALE_ 592 #define ZOOM_ 593 /* Copy the first part of user declarations. */ #line 10 "parser.Y" #define YYDEBUG 1 #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "frame3d.h" #include "fitsimage.h" #include "marker.h" #undef yyFlexLexer #define yyFlexLexer frFlexLexer #include <FlexLexer.h> extern int frlex(void*, frFlexLexer*); extern void frerror(Base*, frFlexLexer*, const char*); static Coord::CoordSystem currentCoord = Coord::IMAGE; static Coord::SkyFrame currentSky = Coord::FK5; static unsigned short defaultProps = Marker::SELECT | Marker::HIGHLITE | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::INCLUDE | Marker::SOURCE; static unsigned short currentProps; static char currentColor[16]; static int currentWidth; static int currentDash[2]; static char currentFont[32]; static char currentText[80]; static List<Tag> taglist; static List<CallBack> cblist; static unsigned short propQMask; static unsigned short propQValue; static void setProps(unsigned short* props, unsigned short prop, int value); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 51 "parser.Y" { #define FRBUFSIZE 4096 char chr; char str[FRBUFSIZE]; void* ptr; int integer; double real; double vector[3]; int dash[2]; } /* Line 193 of yacc.c. */ #line 832 "parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 845 "parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 333 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 5095 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 343 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 206 /* YYNRULES -- Number of rules. */ #define YYNRULES 1229 /* YYNRULES -- Number of states. */ #define YYNSTATES 2685 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 593 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint16 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 342, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 340, 2, 2, 2, 2, 2, 2, 2, 2, 2, 341, 339, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 6, 9, 13, 15, 17, 20, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 56, 59, 62, 65, 68, 71, 85, 89, 92, 96, 99, 102, 105, 108, 110, 114, 117, 120, 123, 125, 128, 131, 134, 136, 139, 141, 144, 147, 150, 153, 155, 157, 159, 161, 164, 167, 170, 173, 176, 179, 182, 185, 188, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 210, 212, 214, 216, 218, 219, 222, 225, 227, 229, 232, 235, 236, 238, 240, 242, 244, 246, 248, 250, 253, 256, 259, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 370, 372, 374, 375, 377, 379, 381, 383, 385, 387, 389, 391, 392, 394, 396, 397, 399, 401, 402, 404, 406, 407, 409, 411, 413, 415, 417, 419, 421, 422, 424, 426, 428, 430, 432, 434, 435, 437, 439, 440, 442, 444, 446, 448, 450, 453, 456, 459, 462, 465, 468, 471, 473, 476, 478, 481, 483, 486, 489, 496, 499, 504, 507, 510, 513, 517, 520, 523, 525, 528, 530, 533, 538, 544, 547, 551, 557, 564, 566, 568, 570, 578, 590, 599, 612, 615, 618, 621, 624, 627, 630, 633, 636, 639, 641, 643, 645, 647, 649, 651, 653, 656, 659, 661, 663, 665, 667, 669, 672, 675, 678, 686, 697, 699, 702, 704, 712, 723, 725, 728, 731, 734, 738, 741, 744, 746, 749, 757, 765, 770, 773, 775, 777, 782, 795, 798, 800, 802, 803, 810, 819, 822, 826, 830, 834, 835, 839, 844, 849, 854, 858, 862, 864, 868, 874, 879, 884, 888, 892, 895, 898, 901, 904, 907, 910, 913, 916, 919, 922, 925, 928, 930, 933, 936, 940, 948, 951, 954, 956, 960, 963, 966, 968, 971, 980, 983, 986, 989, 991, 994, 996, 1001, 1009, 1012, 1015, 1017, 1019, 1021, 1024, 1026, 1028, 1031, 1033, 1034, 1037, 1040, 1042, 1044, 1046, 1049, 1052, 1055, 1057, 1058, 1060, 1062, 1064, 1066, 1068, 1070, 1072, 1074, 1076, 1078, 1079, 1081, 1084, 1086, 1091, 1097, 1098, 1101, 1103, 1109, 1112, 1115, 1118, 1120, 1122, 1124, 1127, 1129, 1132, 1134, 1136, 1138, 1140, 1142, 1143, 1145, 1146, 1148, 1154, 1161, 1165, 1170, 1175, 1179, 1186, 1189, 1191, 1196, 1198, 1200, 1205, 1212, 1220, 1226, 1228, 1230, 1235, 1241, 1243, 1245, 1247, 1251, 1252, 1254, 1257, 1259, 1265, 1267, 1270, 1272, 1277, 1281, 1284, 1286, 1289, 1291, 1297, 1300, 1302, 1304, 1308, 1311, 1312, 1314, 1316, 1321, 1324, 1325, 1327, 1328, 1330, 1332, 1334, 1336, 1338, 1340, 1342, 1344, 1346, 1348, 1350, 1352, 1355, 1358, 1361, 1364, 1366, 1368, 1369, 1371, 1372, 1374, 1375, 1377, 1378, 1380, 1381, 1384, 1387, 1388, 1390, 1392, 1395, 1397, 1404, 1410, 1412, 1414, 1416, 1419, 1422, 1424, 1426, 1428, 1430, 1433, 1435, 1437, 1439, 1442, 1444, 1446, 1449, 1452, 1455, 1456, 1458, 1459, 1461, 1463, 1465, 1467, 1469, 1471, 1473, 1475, 1478, 1481, 1483, 1486, 1490, 1492, 1495, 1498, 1503, 1510, 1512, 1523, 1525, 1528, 1532, 1536, 1539, 1542, 1545, 1548, 1551, 1554, 1559, 1564, 1569, 1573, 1577, 1583, 1588, 1593, 1598, 1602, 1606, 1610, 1614, 1617, 1620, 1625, 1629, 1633, 1637, 1642, 1647, 1652, 1657, 1663, 1668, 1675, 1683, 1688, 1693, 1699, 1702, 1706, 1710, 1714, 1717, 1721, 1725, 1729, 1733, 1738, 1742, 1748, 1755, 1759, 1763, 1768, 1772, 1776, 1780, 1784, 1788, 1794, 1798, 1802, 1807, 1811, 1814, 1817, 1819, 1823, 1828, 1833, 1838, 1843, 1848, 1855, 1860, 1865, 1871, 1876, 1881, 1886, 1891, 1897, 1902, 1909, 1917, 1922, 1927, 1933, 1939, 1945, 1951, 1957, 1963, 1971, 1977, 1983, 1990, 1996, 2002, 2008, 2014, 2021, 2027, 2035, 2044, 2050, 2056, 2063, 2067, 2071, 2075, 2079, 2083, 2089, 2093, 2097, 2102, 2106, 2110, 2114, 2118, 2123, 2127, 2133, 2140, 2144, 2148, 2153, 2157, 2161, 2165, 2169, 2173, 2179, 2183, 2187, 2192, 2197, 2202, 2206, 2212, 2217, 2222, 2225, 2229, 2236, 2243, 2245, 2247, 2249, 2252, 2255, 2258, 2262, 2266, 2269, 2272, 2275, 2277, 2281, 2286, 2289, 2290, 2294, 2296, 2298, 2301, 2304, 2307, 2310, 2315, 2320, 2325, 2329, 2334, 2340, 2348, 2357, 2364, 2373, 2383, 2390, 2397, 2405, 2416, 2428, 2441, 2451, 2457, 2463, 2470, 2474, 2480, 2486, 2492, 2499, 2505, 2510, 2520, 2531, 2543, 2553, 2560, 2567, 2574, 2581, 2588, 2595, 2602, 2609, 2616, 2624, 2627, 2632, 2637, 2642, 2647, 2653, 2658, 2663, 2669, 2673, 2678, 2683, 2688, 2695, 2703, 2712, 2722, 2729, 2740, 2752, 2765, 2775, 2779, 2782, 2786, 2792, 2799, 2807, 2812, 2816, 2820, 2827, 2834, 2841, 2849, 2854, 2859, 2866, 2876, 2881, 2885, 2892, 2900, 2908, 2911, 2915, 2919, 2923, 2928, 2931, 2934, 2939, 2947, 2958, 2962, 2964, 2968, 2971, 2974, 2977, 2980, 2984, 2990, 2995, 3001, 3004, 3012, 3016, 3019, 3022, 3026, 3029, 3032, 3035, 3039, 3042, 3046, 3051, 3055, 3059, 3065, 3072, 3077, 3080, 3084, 3087, 3090, 3095, 3099, 3103, 3106, 3110, 3112, 3116, 3118, 3121, 3124, 3127, 3129, 3131, 3133, 3135, 3138, 3140, 3143, 3146, 3148, 3151, 3154, 3156, 3159, 3161, 3163, 3165, 3167, 3169, 3171, 3173, 3175, 3176, 3178, 3181, 3184, 3187, 3191, 3197, 3205, 3213, 3220, 3227, 3234, 3240, 3247, 3254, 3261, 3268, 3275, 3282, 3289, 3300, 3308, 3316, 3324, 3334, 3344, 3355, 3368, 3381, 3384, 3387, 3391, 3396, 3401, 3406, 3409, 3414, 3419, 3421, 3423, 3425, 3427, 3429, 3431, 3433, 3435, 3438, 3440, 3442, 3446, 3450, 3461, 3469, 3474, 3482, 3487, 3490, 3493, 3497, 3502, 3507, 3513, 3518, 3524, 3529, 3535, 3539, 3544, 3550, 3555, 3561, 3565, 3571, 3576, 3582, 3585, 3589, 3593, 3598, 3604, 3608, 3612, 3616, 3621, 3627, 3632, 3638, 3643, 3649, 3654, 3660, 3664, 3669, 3675, 3680, 3686, 3689, 3692, 3696, 3702, 3707, 3714, 3721, 3725, 3729, 3734, 3741, 3747, 3752, 3758, 3761, 3765, 3771, 3776, 3783, 3787, 3790, 3793, 3797, 3800, 3804, 3807, 3811, 3817, 3822, 3829, 3832, 3835, 3838, 3840, 3845, 3847, 3850, 3853, 3856, 3859, 3862, 3865, 3868, 3872, 3875, 3879, 3882, 3886, 3888, 3890, 3892, 3894, 3896, 3897, 3900, 3901, 3904, 3905, 3907, 3908, 3909, 3911, 3913, 3915, 3923, 3932, 3935, 3940, 3943, 3948, 3955, 3958, 3960, 3962, 3966, 3970, 3972, 3976, 3981, 3984, 3986, 3990, 3994, 3999, 4003, 4007, 4011, 4013, 4015, 4017, 4019, 4021, 4023, 4025, 4027, 4029, 4031, 4033, 4035, 4037, 4039, 4042, 4043, 4044, 4047, 4049, 4053, 4055, 4059, 4061, 4064, 4067, 4069, 4073, 4074, 4075, 4078, 4081, 4083, 4087, 4093, 4095, 4098, 4101, 4104, 4106, 4108, 4110, 4112, 4117, 4120, 4124, 4128, 4131, 4135, 4138, 4141, 4144, 4148, 4152, 4156, 4159, 4163, 4165, 4169, 4173, 4175, 4178, 4181, 4184, 4187, 4189, 4191, 4193, 4195, 4198, 4201, 4205, 4209, 4211, 4214, 4218, 4222, 4224, 4227, 4229, 4231, 4234, 4237, 4242, 4244, 4247, 4250, 4253, 4257, 4259, 4261, 4263, 4266, 4269, 4272, 4275, 4279, 4283, 4287, 4291, 4295, 4299, 4303, 4305, 4308, 4311, 4314, 4318, 4321, 4325, 4329, 4332, 4335, 4338, 4341, 4344, 4347, 4350, 4353, 4356, 4359, 4362, 4365, 4368, 4371, 4375, 4379, 4383, 4386, 4389, 4392, 4395, 4398, 4401, 4404, 4407, 4410, 4413, 4416, 4419, 4423, 4427, 4431, 4434, 4436, 4438, 4440, 4442, 4443, 4449, 4451, 4458, 4462, 4464, 4467, 4470, 4474, 4478, 4481, 4484, 4487, 4490, 4493, 4496, 4500, 4503, 4506, 4510, 4512, 4516, 4521, 4523, 4526, 4532, 4539, 4546, 4549, 4551, 4554, 4557, 4563, 4570 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 344, 0, -1, 94, 346, -1, 41, 377, -1, 38, 64, 5, -1, 57, -1, 62, -1, 63, 382, -1, 65, 275, 5, -1, 66, 389, -1, 67, 391, -1, 75, 392, -1, 82, 396, -1, 84, 398, -1, 93, 347, -1, 118, 399, -1, 130, 400, -1, 134, 443, -1, 137, 446, -1, 142, -1, 144, 347, -1, 150, 452, -1, 170, 455, -1, 174, 472, -1, 175, 473, -1, 176, 5, 5, 357, 360, 5, 5, 357, 360, 345, 357, 362, 5, -1, 179, 489, 474, -1, 180, 508, -1, 192, 64, 5, -1, 207, 509, -1, 208, 510, -1, 209, 513, -1, 222, 514, -1, 235, -1, 232, 489, 516, -1, 237, 520, -1, 239, 521, -1, 244, 523, -1, 257, -1, 262, 537, -1, 278, 4, -1, 279, 372, -1, 290, -1, 292, 539, -1, 298, -1, 301, 541, -1, 302, 542, -1, 332, 546, -1, 338, 547, -1, 3, -1, 4, -1, 204, -1, 203, -1, 29, 347, -1, 187, 347, -1, 211, 347, -1, 213, 347, -1, 302, 347, -1, 41, 347, -1, 74, 347, -1, 82, 347, -1, 135, 347, -1, 237, 347, -1, 4, -1, 335, -1, 339, -1, 204, -1, 286, -1, 197, -1, 340, -1, 203, -1, 113, -1, -1, 96, -1, 119, -1, 247, -1, 155, -1, -1, 238, 35, -1, 126, 35, -1, 238, -1, 126, -1, 238, 279, -1, 126, 279, -1, -1, 351, -1, 345, -1, 7, -1, 8, -1, 9, -1, 10, -1, 11, -1, 352, 352, -1, 353, 354, -1, 354, 354, -1, 345, 345, -1, 151, -1, 215, -1, 99, -1, 19, -1, 357, -1, 302, -1, 303, -1, 304, -1, 305, -1, 306, -1, 307, -1, 308, -1, 309, -1, 310, -1, 311, -1, 312, -1, 313, -1, 314, -1, 315, -1, 316, -1, 317, -1, 318, -1, 319, -1, 320, -1, 321, -1, 322, -1, 323, -1, 324, -1, 325, -1, 326, -1, 327, -1, 328, -1, 329, -1, 54, -1, 209, -1, 168, -1, 172, -1, 223, -1, 266, -1, 267, -1, 28, -1, 258, -1, 145, -1, -1, 120, -1, 121, -1, 33, -1, 122, -1, 159, -1, 148, -1, 128, -1, 271, -1, 104, -1, 141, -1, -1, 95, -1, 252, -1, -1, 95, -1, 24, -1, 25, -1, 345, -1, 183, -1, 337, -1, 336, -1, 293, -1, -1, 256, -1, 160, -1, -1, 17, -1, 153, -1, -1, 151, -1, 180, -1, -1, 60, -1, 46, -1, 100, -1, 83, -1, 341, -1, 27, -1, 49, -1, -1, 4, -1, 80, -1, 217, -1, 218, -1, 230, -1, 269, -1, -1, 32, -1, 272, -1, -1, 193, -1, 39, -1, 40, -1, 165, -1, 166, -1, 296, 376, -1, 45, 373, -1, 72, 374, -1, 144, 375, -1, 182, 519, -1, 245, 345, -1, 280, 345, -1, 347, -1, 64, 5, -1, 347, -1, 64, 5, -1, 347, -1, 64, 5, -1, 345, 345, -1, 219, 345, 345, 345, 345, 345, -1, 12, 378, -1, 69, 5, 5, 5, -1, 98, 4, -1, 112, 379, -1, 127, 380, -1, 51, 259, 4, -1, 283, 381, -1, 115, 5, -1, 57, -1, 345, 345, -1, 345, -1, 345, 345, -1, 345, 12, 345, 345, -1, 345, 345, 12, 345, 345, -1, 283, 345, -1, 283, 345, 345, -1, 283, 345, 12, 345, 345, -1, 283, 345, 345, 12, 345, 345, -1, 32, -1, 272, -1, 116, -1, 345, 345, 12, 57, 5, 5, 5, -1, 345, 345, 4, 345, 345, 12, 57, 5, 5, 5, 5, -1, 345, 345, 12, 345, 345, 5, 5, 5, -1, 345, 345, 4, 345, 345, 12, 345, 345, 5, 5, 5, 5, -1, 248, 384, -1, 188, 385, -1, 183, 386, -1, 293, 383, -1, 337, 388, -1, 225, 347, -1, 345, 345, -1, 173, 345, -1, 143, 345, -1, 131, -1, 171, -1, 345, -1, 183, -1, 337, -1, 336, -1, 293, -1, 188, 387, -1, 241, 4, -1, 30, -1, 246, -1, 241, -1, 92, -1, 158, -1, 76, 345, -1, 241, 4, -1, 167, 4, -1, 4, 345, 345, 4, 6, 6, 4, -1, 237, 345, 345, 345, 345, 345, 345, 4, 6, 4, -1, 37, -1, 189, 390, -1, 107, -1, 4, 345, 345, 4, 6, 6, 4, -1, 237, 345, 345, 345, 345, 345, 345, 4, 6, 4, -1, 359, -1, 172, 345, -1, 31, 393, -1, 64, 5, -1, 78, 356, 360, -1, 81, 394, -1, 89, 4, -1, 97, -1, 97, 17, -1, 170, 5, 4, 4, 5, 356, 360, -1, 212, 5, 4, 4, 6, 356, 360, -1, 244, 5, 356, 360, -1, 331, 4, -1, 138, -1, 196, -1, 244, 5, 356, 360, -1, 5, 4, 4, 395, 4, 4, 359, 345, 363, 345, 345, 5, -1, 221, 496, -1, 262, -1, 43, -1, -1, 345, 345, 345, 345, 356, 360, -1, 57, 355, 356, 360, 345, 345, 356, 362, -1, 279, 397, -1, 37, 345, 345, -1, 189, 345, 345, -1, 107, 345, 345, -1, -1, 345, 345, 356, -1, 37, 345, 345, 4, -1, 189, 345, 345, 4, -1, 107, 345, 345, 4, -1, 358, 345, 345, -1, 356, 360, 355, -1, 347, -1, 301, 345, 345, -1, 37, 189, 358, 345, 345, -1, 189, 358, 345, 345, -1, 37, 189, 356, 355, -1, 189, 356, 355, -1, 137, 111, 5, -1, 38, 64, -1, 41, 401, -1, 63, 403, -1, 66, 408, -1, 65, 407, -1, 67, 410, -1, 75, 412, -1, 77, 416, -1, 82, 417, -1, 84, 418, -1, 86, 419, -1, 91, 420, -1, 93, -1, 117, 424, -1, 134, 429, -1, 146, 5, 5, -1, 147, 87, 5, 5, 345, 345, 358, -1, 150, 422, -1, 154, 421, -1, 183, -1, 179, 489, 483, -1, 180, 430, -1, 192, 64, -1, 207, -1, 208, 431, -1, 216, 274, 358, 345, 345, 4, 4, 5, -1, 237, 432, -1, 239, 433, -1, 262, 434, -1, 278, -1, 279, 435, -1, 287, -1, 294, 358, 345, 345, -1, 300, 87, 5, 5, 345, 345, 358, -1, 302, 440, -1, 338, 442, -1, 98, -1, 112, -1, 127, -1, 51, 259, -1, 86, -1, 115, -1, 69, 402, -1, 169, -1, -1, 183, 5, -1, 101, 5, -1, 404, -1, 248, -1, 188, -1, 183, 405, -1, 293, 164, -1, 337, 406, -1, 225, -1, -1, 345, -1, 183, -1, 337, -1, 336, -1, 293, -1, 188, -1, 241, -1, 76, -1, 241, -1, 167, -1, -1, 275, -1, 164, 409, -1, 4, -1, 4, 358, 345, 345, -1, 4, 345, 345, 359, 345, -1, -1, 164, 411, -1, 172, -1, 4, 345, 345, 359, 345, -1, 356, 360, -1, 31, 413, -1, 63, 414, -1, 64, -1, 89, -1, 164, -1, 201, 164, -1, 182, -1, 67, 415, -1, 262, -1, 331, -1, 64, -1, 89, -1, 331, -1, -1, 188, -1, -1, 172, -1, 345, 345, 356, 360, 361, -1, 358, 345, 345, 356, 360, 361, -1, 345, 356, 4, -1, 124, 345, 356, 4, -1, 283, 345, 356, 4, -1, 356, 360, 361, -1, 57, 356, 360, 361, 356, 362, -1, 279, 356, -1, 358, -1, 356, 360, 361, 348, -1, 270, -1, 358, -1, 356, 360, 361, 348, -1, 356, 360, 355, 345, 345, 5, -1, 4, 356, 360, 355, 345, 345, 5, -1, 358, 345, 345, 4, 4, -1, 5, -1, 63, -1, 358, 345, 345, 5, -1, 6, 4, 4, 4, 4, -1, 86, -1, 331, -1, 140, -1, 114, 191, 423, -1, -1, 4, -1, 345, 345, -1, 194, -1, 57, 356, 360, 361, 348, -1, 79, -1, 98, 426, -1, 42, -1, 111, 358, 345, 345, -1, 114, 191, 427, -1, 139, 425, -1, 140, -1, 202, 191, -1, 259, -1, 259, 356, 360, 362, 348, -1, 260, 428, -1, 331, -1, 4, -1, 4, 161, 5, -1, 302, 4, -1, -1, 4, -1, 349, -1, 349, 358, 345, 345, -1, 349, 4, -1, -1, 4, -1, -1, 206, -1, 295, -1, 64, -1, 178, -1, 282, -1, 225, -1, 59, -1, 273, -1, 296, -1, 348, -1, 127, -1, 231, -1, 296, 439, -1, 45, 436, -1, 72, 437, -1, 144, 438, -1, 182, -1, 245, -1, -1, 64, -1, -1, 64, -1, -1, 64, -1, -1, 219, -1, -1, 16, 441, -1, 191, 357, -1, -1, 220, -1, 348, -1, 81, 444, -1, 97, -1, 356, 360, 361, 445, 5, 5, -1, 356, 360, 361, 445, 5, -1, 20, -1, 228, -1, 19, -1, 41, 447, -1, 75, 448, -1, 82, -1, 92, -1, 93, -1, 99, -1, 117, 449, -1, 134, -1, 150, -1, 158, -1, 179, 450, -1, 215, -1, 262, -1, 273, 356, -1, 302, 451, -1, 70, 5, -1, -1, 31, -1, -1, 41, -1, 85, -1, 187, -1, 144, -1, 250, -1, 212, -1, 288, -1, 356, -1, 109, 356, -1, 56, 356, -1, 18, -1, 279, 356, -1, 195, 4, 4, -1, 110, -1, 181, 5, -1, 86, 454, -1, 251, 114, 191, 453, -1, 251, 6, 4, 4, 4, 4, -1, 292, -1, 302, 345, 345, 345, 345, 345, 345, 345, 345, 4, -1, 5, -1, 5, 4, -1, 4, 4, 54, -1, 4, 4, 356, -1, 188, 347, -1, 26, 456, -1, 117, 458, -1, 153, 471, -1, 200, 469, -1, 214, 470, -1, 5, 14, 5, 366, -1, 5, 15, 5, 366, -1, 5, 59, 5, 366, -1, 5, 185, 366, -1, 5, 186, 366, -1, 5, 254, 364, 4, 366, -1, 5, 263, 4, 366, -1, 5, 264, 4, 366, -1, 5, 295, 5, 366, -1, 237, 85, 457, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, -1, 5, 186, -1, 5, 254, 364, 4, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, -1, 5, 14, 5, 366, -1, 5, 15, 5, 366, -1, 5, 59, 5, 366, -1, 5, 185, 365, 366, -1, 5, 5, 261, 365, 366, -1, 5, 186, 365, 366, -1, 5, 254, 364, 4, 365, 366, -1, 5, 268, 364, 4, 4, 365, 366, -1, 5, 263, 4, 366, -1, 5, 264, 4, 366, -1, 5, 295, 5, 365, 366, -1, 260, 459, -1, 111, 85, 460, -1, 237, 151, 468, -1, 237, 85, 467, -1, 187, 461, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, 365, -1, 5, 5, 261, 365, -1, 5, 186, 365, -1, 5, 254, 364, 4, 365, -1, 5, 268, 364, 4, 4, 365, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, 365, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, 365, -1, 5, 186, 365, -1, 5, 254, 364, 4, 365, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, 365, -1, 151, 157, 462, -1, 157, 463, -1, 151, 464, -1, 465, -1, 151, 330, 466, -1, 5, 14, 5, 366, -1, 5, 15, 5, 366, -1, 5, 59, 5, 366, -1, 5, 185, 365, 366, -1, 5, 186, 365, 366, -1, 5, 254, 364, 4, 365, 366, -1, 5, 263, 4, 366, -1, 5, 264, 4, 366, -1, 5, 295, 5, 365, 366, -1, 5, 14, 5, 366, -1, 5, 15, 5, 366, -1, 5, 59, 5, 366, -1, 5, 185, 365, 366, -1, 5, 5, 261, 365, 366, -1, 5, 186, 365, 366, -1, 5, 254, 364, 4, 365, 366, -1, 5, 268, 364, 4, 4, 365, 366, -1, 5, 263, 4, 366, -1, 5, 264, 4, 366, -1, 5, 295, 5, 365, 366, -1, 357, 5, 14, 5, 366, -1, 357, 5, 15, 5, 366, -1, 357, 5, 59, 5, 366, -1, 357, 5, 185, 365, 366, -1, 357, 5, 186, 365, 366, -1, 357, 5, 254, 364, 4, 365, 366, -1, 357, 5, 263, 4, 366, -1, 357, 5, 264, 4, 366, -1, 357, 5, 295, 5, 365, 366, -1, 357, 5, 14, 5, 366, -1, 357, 5, 15, 5, 366, -1, 357, 5, 59, 5, 366, -1, 357, 5, 185, 365, 366, -1, 357, 5, 5, 261, 365, 366, -1, 357, 5, 186, 365, 366, -1, 357, 5, 254, 364, 4, 365, 366, -1, 357, 5, 268, 364, 4, 4, 365, 366, -1, 357, 5, 263, 4, 366, -1, 357, 5, 264, 4, 366, -1, 357, 5, 295, 5, 365, 366, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, 365, -1, 5, 186, 365, -1, 5, 254, 364, 4, 365, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, 365, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, 365, -1, 5, 5, 261, 365, -1, 5, 186, 365, -1, 5, 254, 364, 4, 365, -1, 5, 268, 364, 4, 4, 365, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, 365, -1, 5, 14, 5, -1, 5, 15, 5, -1, 5, 59, 5, -1, 5, 185, 365, -1, 5, 186, 365, -1, 5, 254, 364, 4, 365, -1, 5, 263, 4, -1, 5, 264, 4, -1, 5, 295, 5, 365, -1, 5, 14, 5, 366, -1, 5, 59, 5, 366, -1, 5, 185, 366, -1, 5, 254, 364, 4, 366, -1, 5, 263, 4, 366, -1, 5, 295, 5, 366, -1, 5, 5, -1, 260, 5, 5, -1, 91, 4, 4, 4, 4, 4, -1, 183, 4, 4, 4, 4, 4, -1, 107, -1, 224, -1, 347, -1, 132, 347, -1, 86, 347, -1, 64, 5, -1, 5, 4, 4, -1, 292, 345, 345, -1, 338, 345, -1, 58, 477, -1, 64, 5, -1, 78, -1, 71, 482, 5, -1, 71, 482, 295, 5, -1, 73, 97, -1, -1, 81, 475, 478, -1, 87, -1, 97, -1, 97, 17, -1, 103, 481, -1, 123, 5, -1, 144, 17, -1, 144, 205, 345, 345, -1, 144, 284, 345, 345, -1, 4, 20, 369, 347, -1, 4, 21, 351, -1, 4, 21, 351, 358, -1, 4, 21, 351, 356, 360, -1, 4, 22, 231, 345, 345, 4, 358, -1, 4, 22, 231, 345, 345, 4, 356, 362, -1, 4, 22, 231, 5, 356, 362, -1, 4, 47, 231, 345, 345, 345, 4, 358, -1, 4, 47, 231, 345, 345, 345, 4, 356, 362, -1, 4, 47, 231, 5, 356, 362, -1, 4, 46, 231, 345, 345, 358, -1, 4, 46, 231, 345, 345, 356, 362, -1, 4, 50, 103, 351, 351, 4, 345, 345, 345, 4, -1, 4, 50, 103, 351, 351, 4, 345, 345, 345, 4, 358, -1, 4, 50, 103, 351, 351, 4, 345, 345, 345, 4, 356, 360, -1, 4, 50, 103, 5, 5, 356, 360, 356, 362, -1, 4, 53, 476, 5, 5, -1, 4, 60, 231, 345, 358, -1, 4, 60, 231, 345, 356, 362, -1, 4, 64, 5, -1, 4, 72, 27, 347, 347, -1, 4, 72, 162, 5, 5, -1, 4, 72, 231, 345, 358, -1, 4, 72, 231, 345, 356, 362, -1, 4, 72, 273, 356, 360, -1, 4, 73, 131, 347, -1, 4, 80, 103, 351, 351, 4, 345, 345, 4, -1, 4, 80, 103, 351, 351, 4, 345, 345, 4, 358, -1, 4, 80, 103, 351, 351, 4, 345, 345, 4, 356, 360, -1, 4, 80, 103, 5, 5, 356, 360, 356, 362, -1, 4, 81, 22, 231, 345, 345, -1, 4, 81, 47, 231, 345, 345, -1, 4, 81, 50, 21, 345, 345, -1, 4, 81, 50, 231, 345, 345, -1, 4, 81, 106, 231, 345, 345, -1, 4, 81, 108, 21, 345, 345, -1, 4, 81, 108, 231, 345, 345, -1, 4, 81, 80, 21, 345, 345, -1, 4, 81, 80, 231, 345, 345, -1, 4, 81, 221, 299, 4, 345, 345, -1, 4, 97, -1, 4, 97, 22, 4, -1, 4, 97, 47, 4, -1, 4, 97, 50, 4, -1, 4, 97, 106, 4, -1, 4, 97, 53, 476, 5, -1, 4, 97, 108, 4, -1, 4, 97, 80, 4, -1, 4, 97, 221, 299, 4, -1, 4, 97, 275, -1, 4, 97, 275, 5, -1, 4, 97, 275, 4, -1, 4, 103, 37, 4, -1, 4, 105, 231, 345, 345, 358, -1, 4, 105, 231, 345, 345, 356, 362, -1, 4, 106, 231, 345, 345, 345, 4, 358, -1, 4, 106, 231, 345, 345, 345, 4, 356, 362, -1, 4, 106, 231, 5, 356, 362, -1, 4, 108, 103, 351, 351, 4, 345, 345, 345, 4, -1, 4, 108, 103, 351, 351, 4, 345, 345, 345, 4, 358, -1, 4, 108, 103, 351, 351, 4, 345, 345, 345, 4, 356, 360, -1, 4, 108, 103, 5, 5, 356, 360, 356, 362, -1, 4, 123, 5, -1, 4, 144, -1, 4, 144, 205, -1, 4, 167, 27, 347, 347, -1, 4, 167, 219, 358, 355, 355, -1, 4, 167, 219, 356, 360, 355, 355, -1, 4, 190, 345, 345, -1, 4, 190, 125, -1, 4, 190, 34, -1, 4, 190, 283, 358, 345, 345, -1, 4, 190, 283, 356, 360, 355, -1, 4, 221, 235, 345, 345, 358, -1, 4, 221, 235, 345, 345, 356, 362, -1, 4, 219, 253, 367, -1, 4, 219, 259, 4, -1, 4, 226, 358, 355, 355, 345, -1, 4, 226, 356, 360, 355, 355, 345, 356, 362, -1, 4, 227, 495, 347, -1, 4, 239, 37, -1, 4, 240, 219, 358, 355, 355, -1, 4, 240, 219, 356, 360, 355, 355, -1, 4, 240, 273, 356, 360, 356, 362, -1, 4, 250, -1, 4, 250, 205, -1, 4, 275, 5, -1, 4, 277, 5, -1, 4, 277, 239, 347, -1, 4, 289, -1, 4, 291, -1, 4, 297, 27, 347, -1, 4, 297, 219, 358, 355, 345, 351, -1, 4, 297, 219, 356, 360, 355, 356, 362, 345, 351, -1, 4, 331, 4, -1, 160, -1, 160, 345, 345, -1, 169, 490, -1, 170, 491, -1, 190, 492, -1, 225, 347, -1, 227, 495, 347, -1, 227, 495, 347, 345, 345, -1, 239, 37, 345, 345, -1, 239, 189, 345, 345, 4, -1, 239, 107, -1, 244, 5, 482, 356, 360, 361, 347, -1, 244, 276, 5, -1, 250, 499, -1, 257, 500, -1, 5, 64, 5, -1, 5, 78, -1, 5, 97, -1, 5, 87, -1, 5, 123, 5, -1, 5, 144, -1, 5, 144, 205, -1, 5, 190, 345, 345, -1, 5, 190, 125, -1, 5, 190, 34, -1, 5, 190, 283, 358, 355, -1, 5, 190, 283, 356, 360, 355, -1, 5, 227, 495, 347, -1, 5, 250, -1, 5, 250, 205, -1, 5, 289, -1, 5, 291, -1, 275, 103, 5, 5, -1, 275, 97, 5, -1, 275, 97, 17, -1, 275, 5, -1, 275, 292, 5, -1, 212, -1, 212, 356, 356, -1, 288, -1, 289, 17, -1, 291, 17, -1, 331, 4, -1, 250, -1, 291, -1, 144, -1, 289, -1, 37, 190, -1, 190, -1, 107, 190, -1, 37, 103, -1, 103, -1, 107, 103, -1, 37, 239, -1, 239, -1, 107, 239, -1, 97, -1, 277, -1, 64, -1, 331, -1, 227, -1, 123, -1, 160, -1, 292, -1, -1, 4, -1, 30, 347, -1, 231, 345, -1, 156, 4, -1, 206, 4, 345, -1, 60, 345, 345, 345, 496, -1, 105, 345, 345, 345, 345, 350, 496, -1, 46, 345, 345, 345, 345, 350, 496, -1, 221, 345, 345, 345, 345, 496, -1, 167, 345, 345, 345, 345, 496, -1, 297, 345, 345, 345, 345, 496, -1, 277, 345, 345, 350, 496, -1, 60, 219, 345, 345, 368, 496, -1, 46, 219, 345, 345, 368, 496, -1, 100, 219, 345, 345, 368, 496, -1, 83, 219, 345, 345, 368, 496, -1, 341, 219, 345, 345, 368, 496, -1, 27, 219, 345, 345, 368, 496, -1, 49, 219, 345, 345, 368, 496, -1, 240, 345, 345, 345, 345, 356, 360, 356, 362, 496, -1, 72, 345, 345, 345, 356, 360, 496, -1, 226, 345, 345, 345, 345, 345, 496, -1, 22, 345, 345, 345, 345, 4, 496, -1, 106, 345, 345, 345, 345, 345, 4, 350, 496, -1, 47, 345, 345, 345, 345, 345, 4, 350, 496, -1, 80, 345, 345, 351, 351, 4, 345, 345, 4, 496, -1, 108, 345, 345, 351, 351, 4, 345, 345, 345, 4, 350, 496, -1, 50, 345, 345, 351, 351, 4, 345, 345, 345, 4, 350, 496, -1, 73, 496, -1, 276, 479, -1, 5, 345, 345, -1, 295, 5, 345, 345, -1, 345, 345, 295, 5, -1, 5, 356, 360, 355, -1, 4, 4, -1, 37, 345, 345, 4, -1, 189, 345, 345, 4, -1, 107, -1, 102, -1, 333, -1, 61, -1, 243, -1, 242, -1, 229, -1, 334, -1, 58, 484, -1, 64, -1, 123, -1, 136, 345, 345, -1, 149, 345, 345, -1, 4, 20, 217, 5, 5, 5, 5, 356, 360, 370, -1, 4, 20, 218, 5, 5, 356, 370, -1, 4, 20, 80, 356, -1, 4, 20, 230, 5, 5, 5, 356, -1, 4, 20, 269, 356, -1, 149, 17, -1, 4, 21, -1, 4, 21, 358, -1, 4, 21, 356, 360, -1, 4, 22, 231, 358, -1, 4, 22, 231, 356, 362, -1, 4, 47, 231, 358, -1, 4, 47, 231, 356, 362, -1, 4, 46, 231, 358, -1, 4, 46, 231, 356, 362, -1, 4, 50, 21, -1, 4, 50, 21, 358, -1, 4, 50, 21, 356, 360, -1, 4, 50, 231, 358, -1, 4, 50, 231, 356, 362, -1, 4, 57, 358, -1, 4, 57, 356, 360, 361, -1, 4, 60, 231, 358, -1, 4, 60, 231, 356, 362, -1, 4, 64, -1, 4, 72, 27, -1, 4, 72, 162, -1, 4, 72, 231, 358, -1, 4, 72, 231, 356, 362, -1, 4, 72, 273, -1, 4, 73, 131, -1, 4, 80, 21, -1, 4, 80, 21, 358, -1, 4, 80, 21, 356, 360, -1, 4, 80, 231, 358, -1, 4, 80, 231, 356, 362, -1, 4, 105, 231, 358, -1, 4, 105, 231, 356, 362, -1, 4, 106, 231, 358, -1, 4, 106, 231, 356, 362, -1, 4, 108, 21, -1, 4, 108, 21, 358, -1, 4, 108, 21, 356, 360, -1, 4, 108, 231, 358, -1, 4, 108, 231, 356, 362, -1, 4, 123, -1, 4, 144, -1, 4, 167, 27, -1, 4, 167, 163, 356, 362, -1, 4, 167, 219, 358, -1, 4, 167, 219, 356, 360, 361, -1, 4, 177, 163, 345, 356, 362, -1, 4, 219, 253, -1, 4, 219, 259, -1, 4, 226, 219, 358, -1, 4, 226, 219, 356, 360, 361, -1, 4, 226, 163, 356, 362, -1, 4, 226, 281, 358, -1, 4, 226, 281, 356, 362, -1, 4, 227, -1, 4, 227, 495, -1, 4, 240, 163, 356, 362, -1, 4, 240, 219, 358, -1, 4, 240, 219, 356, 360, 361, -1, 4, 240, 273, -1, 4, 250, -1, 4, 275, -1, 4, 275, 4, -1, 4, 277, -1, 4, 277, 239, -1, 4, 287, -1, 4, 297, 27, -1, 4, 297, 163, 356, 362, -1, 4, 297, 219, 358, -1, 4, 297, 219, 356, 360, 361, -1, 4, 331, -1, 144, 485, -1, 144, 201, -1, 201, -1, 221, 249, 345, 345, -1, 225, -1, 227, 495, -1, 250, 486, -1, 250, 201, -1, 257, 487, -1, 5, 64, -1, 5, 123, -1, 5, 149, -1, 5, 227, 495, -1, 5, 275, -1, 5, 275, 201, -1, 275, 17, -1, 275, 96, 191, -1, 331, -1, 30, -1, 231, -1, 156, -1, 206, -1, -1, 345, 345, -1, -1, 345, 345, -1, -1, 277, -1, -1, -1, 220, -1, 293, -1, 55, -1, 482, 356, 360, 361, 347, 497, 503, -1, 250, 482, 356, 360, 361, 347, 497, 503, -1, 482, 5, -1, 482, 5, 356, 360, -1, 482, 4, -1, 482, 4, 356, 360, -1, 117, 5, 5, 480, 4, 5, -1, 345, 345, -1, 125, -1, 34, -1, 37, 345, 345, -1, 189, 345, 345, -1, 107, -1, 283, 358, 355, -1, 283, 356, 360, 355, -1, 493, 494, -1, 494, -1, 495, 342, 347, -1, 64, 342, 5, -1, 90, 342, 4, 4, -1, 331, 342, 4, -1, 123, 342, 5, -1, 277, 342, 5, -1, 506, -1, 507, -1, 198, -1, 250, -1, 144, -1, 89, -1, 119, -1, 103, -1, 190, -1, 239, -1, 97, -1, 152, -1, 265, -1, 488, -1, 488, 493, -1, -1, -1, 498, 501, -1, 17, -1, 205, 345, 345, -1, 284, -1, 284, 345, 345, -1, 347, -1, 277, 347, -1, 501, 502, -1, 502, -1, 495, 342, 347, -1, -1, -1, 504, 505, -1, 505, 506, -1, 506, -1, 275, 342, 5, -1, 53, 342, 476, 5, 5, -1, 62, -1, 64, 5, -1, 178, 4, -1, 282, 345, -1, 341, -1, 339, -1, 334, -1, 198, -1, 345, 345, 345, 345, -1, 345, 345, -1, 358, 345, 345, -1, 356, 360, 355, -1, 283, 511, -1, 36, 345, 345, -1, 189, 512, -1, 225, 347, -1, 345, 345, -1, 358, 345, 345, -1, 356, 360, 355, -1, 37, 345, 345, -1, 345, 345, -1, 107, 345, 345, -1, 347, -1, 302, 357, 360, -1, 5, 4, 4, -1, 292, -1, 68, 515, -1, 164, 4, -1, 236, 4, -1, 245, 345, -1, 52, -1, 133, -1, 237, -1, 88, -1, 144, 517, -1, 250, 518, -1, 37, 345, 345, -1, 189, 345, 345, -1, 107, -1, 255, 107, -1, 37, 345, 345, -1, 189, 345, 345, -1, 107, -1, 255, 107, -1, 184, -1, 13, -1, 59, 5, -1, 273, 356, -1, 296, 4, 4, 4, -1, 345, -1, 345, 95, -1, 189, 522, -1, 283, 345, -1, 283, 345, 95, -1, 37, -1, 345, -1, 107, -1, 26, 524, -1, 117, 526, -1, 200, 536, -1, 214, 5, -1, 114, 5, 371, -1, 59, 5, 371, -1, 263, 4, 371, -1, 237, 85, 525, -1, 114, 5, 371, -1, 59, 5, 371, -1, 263, 4, 371, -1, 527, -1, 151, 527, -1, 274, 528, -1, 260, 529, -1, 111, 85, 530, -1, 187, 531, -1, 237, 151, 533, -1, 237, 85, 534, -1, 234, 535, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 151, 532, -1, 114, 5, 4, -1, 59, 5, 4, -1, 263, 4, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, -1, 59, 5, -1, 263, 4, -1, 114, 5, 371, -1, 59, 5, 371, -1, 263, 4, 371, -1, 538, 4, -1, 97, -1, 48, -1, 129, -1, 285, -1, -1, 4, 345, 345, 345, 345, -1, 199, -1, 199, 4, 345, 345, 345, 345, -1, 117, 260, 540, -1, 4, -1, 4, 4, -1, 345, 345, -1, 283, 345, 345, -1, 357, 360, 361, -1, 16, 545, -1, 235, 4, -1, 233, 544, -1, 23, 543, -1, 4, 4, -1, 4, 5, -1, 277, 4, 5, -1, 4, 4, -1, 4, 5, -1, 277, 4, 5, -1, 4, -1, 4, 357, 360, -1, 4, 6, 357, 360, -1, 224, -1, 345, 345, -1, 345, 345, 12, 345, 345, -1, 345, 345, 12, 358, 345, 345, -1, 345, 345, 12, 356, 360, 355, -1, 283, 548, -1, 116, -1, 116, 345, -1, 345, 345, -1, 345, 345, 12, 345, 345, -1, 345, 345, 12, 358, 345, 345, -1, 345, 345, 12, 356, 360, 355, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 443, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 498, 499, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 516, 518, 519, 520, 521, 523, 524, 525, 526, 529, 530, 531, 532, 533, 536, 537, 538, 539, 540, 541, 542, 545, 546, 549, 550, 551, 554, 557, 560, 563, 575, 582, 589, 597, 598, 599, 600, 601, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 634, 635, 638, 639, 640, 641, 642, 643, 644, 645, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 661, 662, 663, 666, 667, 668, 669, 672, 673, 674, 675, 676, 679, 680, 681, 684, 685, 686, 689, 690, 691, 694, 695, 696, 697, 698, 699, 700, 701, 704, 705, 708, 709, 710, 711, 712, 715, 716, 717, 720, 721, 722, 723, 724, 725, 728, 729, 730, 731, 732, 733, 734, 738, 739, 742, 743, 746, 747, 750, 751, 755, 756, 757, 758, 759, 760, 761, 762, 765, 766, 769, 770, 771, 773, 775, 776, 777, 779, 783, 784, 787, 788, 790, 793, 795, 801, 802, 803, 804, 805, 806, 809, 810, 811, 814, 815, 818, 819, 820, 821, 822, 825, 826, 829, 830, 831, 832, 833, 836, 837, 838, 841, 844, 846, 847, 848, 851, 854, 858, 859, 862, 863, 864, 866, 867, 868, 869, 870, 872, 874, 876, 879, 880, 881, 885, 887, 892, 893, 896, 897, 900, 903, 904, 905, 906, 909, 910, 911, 912, 913, 916, 918, 920, 921, 923, 925, 927, 929, 933, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 954, 955, 956, 957, 958, 959, 960, 961, 962, 964, 965, 966, 967, 968, 969, 970, 972, 974, 975, 978, 979, 980, 981, 982, 983, 984, 985, 988, 989, 990, 993, 994, 995, 996, 997, 998, 999, 1002, 1003, 1004, 1005, 1006, 1007, 1010, 1011, 1014, 1015, 1016, 1019, 1020, 1023, 1026, 1027, 1029, 1033, 1034, 1035, 1038, 1042, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1056, 1057, 1058, 1061, 1062, 1065, 1066, 1069, 1072, 1078, 1080, 1082, 1086, 1088, 1091, 1094, 1095, 1098, 1101, 1102, 1107, 1110, 1113, 1118, 1119, 1120, 1124, 1125, 1126, 1127, 1128, 1131, 1132, 1133, 1136, 1137, 1140, 1141, 1142, 1143, 1145, 1146, 1147, 1148, 1149, 1150, 1153, 1154, 1157, 1158, 1159, 1162, 1163, 1166, 1168, 1171, 1175, 1176, 1179, 1180, 1181, 1184, 1185, 1186, 1189, 1192, 1193, 1194, 1197, 1200, 1201, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1216, 1217, 1220, 1221, 1224, 1225, 1228, 1229, 1230, 1233, 1234, 1237, 1240, 1241, 1244, 1247, 1254, 1255, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1276, 1279, 1280, 1283, 1284, 1285, 1286, 1289, 1290, 1291, 1292, 1295, 1296, 1297, 1298, 1299, 1302, 1303, 1304, 1305, 1306, 1307, 1309, 1310, 1315, 1316, 1319, 1321, 1323, 1326, 1327, 1328, 1329, 1330, 1333, 1335, 1337, 1339, 1341, 1343, 1346, 1348, 1350, 1352, 1355, 1356, 1357, 1358, 1359, 1360, 1362, 1363, 1364, 1367, 1369, 1371, 1373, 1376, 1379, 1382, 1385, 1388, 1390, 1392, 1395, 1396, 1397, 1398, 1399, 1402, 1404, 1406, 1408, 1410, 1412, 1414, 1416, 1418, 1420, 1422, 1426, 1428, 1430, 1432, 1434, 1436, 1439, 1441, 1443, 1447, 1448, 1449, 1450, 1451, 1454, 1457, 1460, 1463, 1466, 1469, 1473, 1476, 1479, 1484, 1487, 1490, 1493, 1496, 1499, 1502, 1506, 1510, 1513, 1516, 1521, 1524, 1527, 1530, 1533, 1536, 1540, 1543, 1546, 1551, 1554, 1557, 1560, 1563, 1566, 1569, 1573, 1577, 1580, 1583, 1588, 1590, 1592, 1594, 1596, 1598, 1601, 1603, 1605, 1608, 1609, 1610, 1611, 1613, 1615, 1617, 1620, 1623, 1624, 1625, 1629, 1630, 1631, 1632, 1634, 1636, 1639, 1640, 1641, 1645, 1647, 1649, 1651, 1654, 1656, 1660, 1661, 1664, 1665, 1666, 1669, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1685, 1686, 1687, 1688, 1690, 1692, 1693, 1693, 1694, 1695, 1696, 1697, 1698, 1700, 1701, 1703, 1706, 1709, 1710, 1711, 1714, 1716, 1719, 1722, 1725, 1729, 1732, 1734, 1737, 1740, 1744, 1749, 1754, 1756, 1758, 1760, 1761, 1763, 1765, 1767, 1769, 1771, 1772, 1774, 1776, 1780, 1785, 1787, 1789, 1791, 1793, 1795, 1797, 1799, 1801, 1803, 1806, 1807, 1809, 1811, 1812, 1814, 1816, 1817, 1818, 1820, 1821, 1822, 1824, 1825, 1827, 1830, 1834, 1838, 1841, 1844, 1848, 1853, 1859, 1860, 1861, 1863, 1864, 1866, 1870, 1872, 1873, 1874, 1876, 1879, 1881, 1884, 1886, 1888, 1891, 1896, 1899, 1900, 1903, 1906, 1910, 1911, 1913, 1914, 1915, 1917, 1918, 1920, 1921, 1923, 1928, 1930, 1931, 1933, 1934, 1935, 1936, 1937, 1938, 1940, 1942, 1944, 1945, 1948, 1949, 1951, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1965, 1967, 1969, 1970, 1971, 1972, 1974, 1975, 1976, 1977, 1978, 1980, 1981, 1983, 1984, 1985, 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2014, 2015, 2016, 2017, 2024, 2031, 2040, 2049, 2056, 2064, 2072, 2079, 2084, 2089, 2094, 2099, 2104, 2109, 2115, 2124, 2134, 2144, 2151, 2161, 2171, 2180, 2192, 2205, 2210, 2213, 2215, 2217, 2222, 2226, 2229, 2231, 2233, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2245, 2246, 2247, 2248, 2249, 2251, 2253, 2255, 2257, 2259, 2262, 2263, 2264, 2265, 2267, 2269, 2272, 2274, 2276, 2278, 2280, 2281, 2282, 2284, 2286, 2289, 2291, 2294, 2296, 2298, 2299, 2300, 2301, 2303, 2305, 2306, 2307, 2308, 2309, 2311, 2313, 2315, 2317, 2319, 2321, 2324, 2325, 2326, 2328, 2330, 2332, 2333, 2334, 2335, 2337, 2339, 2342, 2346, 2347, 2348, 2350, 2353, 2356, 2358, 2360, 2361, 2362, 2364, 2366, 2369, 2370, 2372, 2373, 2374, 2375, 2376, 2378, 2379, 2381, 2383, 2386, 2387, 2388, 2389, 2390, 2392, 2393, 2394, 2395, 2397, 2399, 2400, 2401, 2402, 2403, 2404, 2406, 2407, 2409, 2412, 2413, 2414, 2415, 2418, 2419, 2422, 2423, 2426, 2427, 2430, 2443, 2444, 2445, 2446, 2449, 2454, 2461, 2463, 2466, 2468, 2471, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2483, 2487, 2488, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2514, 2515, 2518, 2519, 2519, 2522, 2523, 2524, 2525, 2528, 2529, 2532, 2533, 2536, 2540, 2541, 2541, 2544, 2545, 2548, 2551, 2555, 2556, 2557, 2558, 2561, 2562, 2563, 2564, 2567, 2569, 2570, 2575, 2577, 2578, 2579, 2580, 2583, 2584, 2589, 2593, 2594, 2595, 2598, 2599, 2604, 2605, 2608, 2610, 2611, 2612, 2615, 2616, 2617, 2618, 2621, 2622, 2625, 2627, 2629, 2630, 2633, 2635, 2636, 2637, 2640, 2641, 2644, 2645, 2646, 2649, 2650, 2651, 2652, 2653, 2656, 2657, 2658, 2661, 2662, 2663, 2664, 2667, 2669, 2671, 2673, 2676, 2678, 2680, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2694, 2695, 2696, 2699, 2700, 2701, 2704, 2705, 2706, 2709, 2710, 2711, 2714, 2715, 2716, 2717, 2720, 2721, 2722, 2725, 2726, 2727, 2730, 2731, 2732, 2735, 2736, 2737, 2740, 2742, 2744, 2748, 2749, 2752, 2753, 2754, 2757, 2758, 2760, 2761, 2763, 2766, 2767, 2770, 2771, 2774, 2776, 2777, 2778, 2779, 2782, 2783, 2784, 2787, 2788, 2789, 2792, 2793, 2798, 2805, 2812, 2813, 2815, 2820, 2823, 2826, 2827, 2828, 2829, 2831, 2836 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "REAL", "INT", "STRING", "POINTER", "ANGDEGREE", "ANGRADIAN", "SEXSTR", "HMSSTR", "DMSSTR", "ABOUT_", "AIP_", "ALLOC_", "ALLOCGZ_", "ALIGN_", "ALL_", "ALT_", "AMPLIFIER_", "ANALYSIS_", "ANGLE_", "ANNULUS_", "APPEND_", "ARCMIN_", "ARCSEC_", "ARRAY_", "ARROW_", "ASINH_", "AST_", "AUTO_", "AUX_", "AVERAGE_", "B1950_", "BACK_", "BASE_", "BBOX_", "BEGIN_", "BG_", "BIG_", "BIGENDIAN_", "BIN_", "BITPIX_", "BLOCK_", "BLT_", "BORDER_", "BOX_", "BOXANNULUS_", "BOXCAR_", "BOXCIRCLE_", "BPANDA_", "BUFFER_", "BW_", "CALLBACK_", "CANVAS_", "CATALOG_", "CELESTRIAL_", "CENTER_", "CENTROID_", "CHANNEL_", "CIRCLE_", "CIAO_", "CLEAR_", "CLIP_", "COLOR_", "COLORBAR_", "COLORMAP_", "COLORSCALE_", "COLORSPACE_", "COLS_", "COLUMN_", "COMMAND_", "COMPASS_", "COMPOSITE_", "COMPRESS_", "CONTOUR_", "CONTRAST_", "COORDINATES_", "COPY_", "COUNT_", "CPANDA_", "CREATE_", "CROP_", "CROSS_", "CROSSHAIR_", "CUBE_", "CURSOR_", "CUT_", "CMYK_", "DASH_", "DASHLIST_", "DATA_", "DATAMIN_", "DATASEC_", "DEBUG_", "DEGREES_", "DEFAULT_", "DELETE_", "DEPTH_", "DETECTOR_", "DIAMOND_", "DIM_", "DS9_", "EDIT_", "ECLIPTIC_", "ELLIPSE_", "ELLIPSEANNULUS_", "END_", "EPANDA_", "EQUATORIAL_", "ERASE_", "EXT_", "FACTOR_", "FALSE_", "FILE_", "FILTER_", "FIT_", "FITS_", "FITSY_", "FIXED_", "FK4_", "FK4_NO_E_", "FK5_", "FONT_", "FROM_", "FRONT_", "FULL_", "FUNCTION_", "GALACTIC_", "GAUSSIAN_", "GET_", "GLOBAL_", "GRAPHICS_", "GRAY_", "GRID_", "GZ_", "HANDLE_", "HAS_", "HEAD_", "HEADER_", "HEIGHT_", "HELIOECLIPTIC_", "HIDE_", "HIGH_", "HIGHLITE_", "HISTEQU_", "HISTOGRAM_", "HORIZONTAL_", "ICRS_", "ID_", "IIS_", "IMAGE_", "INCLUDE_", "INCR_", "INFO_", "INTEGER_", "ITERATION_", "IRAF_", "IRAFMIN_", "J2000_", "KEY_", "KEYWORD_", "LABEL_", "LENGTH_", "LEVEL_", "LITTLE_", "LITTLEENDIAN_", "LINE_", "LINEAR_", "LIST_", "LOAD_", "LOCAL_", "LOG_", "LOW_", "MACOSX_", "MAGNIFIER_", "MATCH_", "MAP_", "MARK_", "MARKER_", "MASK_", "MESSAGE_", "METHOD_", "MINMAX_", "MIP_", "MMAP_", "MMAPINCR_", "MOSAIC_", "MODE_", "MOTION_", "MOVE_", "NAME_", "NAN_", "NATIVE_", "NAXES_", "NEW_", "NEXT_", "NO_", "NONE_", "NOW_", "NRRD_", "NUMBER_", "OBJECT_", "OFF_", "ON_", "ONLY_", "OPTION_", "ORIENT_", "PAN_", "PANNER_", "PARAM_", "PARSER_", "PASTE_", "PERF_", "PHOTO_", "PHYSICAL_", "PIXEL_", "PLOT2D_", "PLOT3D_", "POINT_", "POINTER_", "POLYGON_", "POSTSCRIPT_", "POW_", "PRINT_", "PRESERVE_", "PROJECTION_", "PROPERTY_", "PUBLICATION_", "PROS_", "RADIAL_", "RADIUS_", "REGION_", "REPLACE_", "RESAMPLE_", "RESET_", "RESOLUTION_", "RGB_", "ROOT_", "ROTATE_", "RULER_", "SAMPLE_", "SAOIMAGE_", "SAOTNG_", "SAVE_", "SCALE_", "SCAN_", "SCIENTIFIC_", "SCOPE_", "SEGMENT_", "SELECT_", "SET_", "SEXAGESIMAL_", "SHAPE_", "SHARED_", "SHIFT_", "SHMID_", "SHOW_", "SINH_", "SIZE_", "SLICE_", "SMMAP_", "SMOOTH_", "SOCKET_", "SOCKETGZ_", "SOURCE_", "SQRT_", "SQUARED_", "SSHARED_", "STATS_", "STATUS_", "SUPERGALACTIC_", "SUM_", "SYSTEM_", "TABLE_", "TAG_", "TEMPLATE_", "TEXT_", "THREADS_", "THREED_", "THRESHOLD_", "THICK_", "TRANSPARENCY_", "TO_", "TOGGLE_", "TOPHAT_", "TRUE_", "TYPE_", "UNDO_", "UNHIGHLITE_", "UNLOAD_", "UNSELECT_", "UPDATE_", "USER_", "VALUE_", "VAR_", "VIEW_", "VECTOR_", "VERSION_", "VERTEX_", "VERTICAL_", "WARP_", "WCS_", "WCSA_", "WCSB_", "WCSC_", "WCSD_", "WCSE_", "WCSF_", "WCSG_", "WCSH_", "WCSI_", "WCSJ_", "WCSK_", "WCSL_", "WCSM_", "WCSN_", "WCSO_", "WCSP_", "WCSQ_", "WCSR_", "WCSS_", "WCST_", "WCSU_", "WCSV_", "WCSW_", "WCSX_", "WCSY_", "WCSZ_", "WCS0_", "WFPC2_", "WIDTH_", "WIN32_", "XML_", "XY_", "YES_", "ZMAX_", "ZSCALE_", "ZOOM_", "'Y'", "'N'", "'X'", "'='", "$accept", "command", "numeric", "debug", "yesno", "precision", "fileNameType", "optangle", "angle", "sexagesimal", "hms", "dms", "coord", "coordSystem", "wcsSystem", "internalSystem", "scaleType", "skyFrame", "skyFormat", "skyDist", "contourClipMode", "shmType", "incrLoad", "layerType", "pointShape", "pointSize", "analysisMethod", "analysisParam", "endian", "threed", "threedBorder", "threedCompass", "threedHighlite", "threedView", "bin", "binAbout", "binFactor", "binFunction", "binTo", "clip", "clipUser", "clipScope", "clipMode", "clipMinMax", "clipMinMaxMode", "clipZScale", "colormap", "colormapMotion", "colorscale", "contour", "contourAux", "contourCreate", "contourmethod", "crop", "crop3d", "crosshair", "fitsy", "get", "getBin", "getBinCols", "getClip", "getClipLimits", "getClipMinMax", "getClipZScale", "getColorbar", "getColorMap", "getColorMapLevel", "getColorScale", "getColorScaleLevel", "getContour", "getContourAux", "getContourClip", "getContourColorScale", "getCoord", "getCrop", "getCrosshair", "getCursor", "getData", "getInfo", "getiis", "getIISFileName", "getFits", "getFitsHeader", "getFitsDepth", "getFitsFileName", "getFitsSlice", "getGrid", "getMask", "getPan", "getRGB", "getRotate", "getSmooth", "getThreed", "getThreedBorder", "getThreedCompass", "getThreedHighlite", "getThreedView", "getWCS", "getWCSAlign", "getZoom", "grid", "gridCreate", "gridType", "has", "hasBin", "hasContour", "hasFits", "hasMarker", "hasWCS", "iis", "iisSetFileName", "iiscursor", "load", "loadArr", "loadArrayRGBCube", "loadFits", "loadFitsSlice", "loadFitsExtCube", "loadFitsMosaic", "loadFitsMosaicImageIRAF", "loadFitsMosaicIRAF", "loadFitsMosaicImageWCS", "loadFitsMosaicWCS", "loadFitsMosaicImageWFPC2", "loadFitsRGBCube", "loadFitsRGBImage", "loadNRRD", "loadPhoto", "loadIncr", "macosx", "magnifier", "marker", "@1", "markerCallBack", "markerCentroid", "markerCreate", "markerCreateTemplate", "markerDash", "markerEdit", "markerFormat", "markerGet", "markerGetCentroid", "markerGetHighlite", "markerGetSelect", "markerGetShow", "markerInitProp", "markerLayer", "markerList", "markerLoad", "markerMoveSelected", "markerProps", "markerProp", "markerProperty", "markerProperties", "markerQuery", "@2", "markerSelect", "markerShow", "queries", "query", "markerTags", "@3", "tags", "tag", "callback", "mask", "orient", "pan", "panTo", "panMotion", "panner", "postscript", "pscolorspace", "region", "regionHighlite", "regionSelect", "renderMethod", "rgb", "rotate", "rotateMotion", "save", "saveArray", "saveArrayRGBCube", "saveFits", "saveFitsImage", "saveFitsTable", "saveFitsSlice", "saveFitsExtCube", "saveFitsMosaic", "saveFitsMosaicImage", "saveFitsRGBImage", "saveFitsRGBCube", "saveFitsResample", "saveNRRD", "smooth", "smoothFunction", "update", "updateFitsSlice", "warp", "wcs", "wcsAppend", "wcsReplace", "wcsAlign", "win32", "zoom", "zoomTo", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 89, 78, 88, 61 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { 0, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 345, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 347, 347, 347, 347, 347, 347, 347, 347, 347, 348, 348, 348, 348, 348, 349, 349, 349, 349, 349, 349, 349, 350, 350, 351, 351, 351, 352, 353, 354, 355, 355, 355, 355, 356, 356, 356, 356, 356, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 358, 358, 359, 359, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 361, 361, 361, 362, 362, 362, 362, 363, 363, 363, 363, 363, 364, 364, 364, 365, 365, 365, 366, 366, 366, 367, 367, 367, 367, 367, 367, 367, 367, 368, 368, 369, 369, 369, 369, 369, 370, 370, 370, 371, 371, 371, 371, 371, 371, 372, 372, 372, 372, 372, 372, 372, 373, 373, 374, 374, 375, 375, 376, 376, 377, 377, 377, 377, 377, 377, 377, 377, 378, 378, 379, 379, 379, 379, 379, 379, 379, 379, 380, 380, 381, 381, 381, 381, 381, 382, 382, 382, 382, 382, 382, 383, 383, 383, 384, 384, 385, 385, 385, 385, 385, 386, 386, 387, 387, 387, 387, 387, 388, 388, 388, 389, 389, 389, 389, 389, 390, 390, 391, 391, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 393, 393, 393, 394, 394, 395, 395, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 398, 398, 398, 398, 398, 398, 398, 398, 399, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 401, 401, 401, 401, 401, 401, 401, 401, 402, 402, 402, 403, 403, 403, 403, 403, 403, 403, 404, 404, 404, 404, 404, 404, 405, 405, 406, 406, 406, 407, 407, 408, 409, 409, 409, 410, 410, 410, 411, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 413, 413, 413, 414, 414, 415, 415, 416, 416, 416, 416, 416, 417, 417, 417, 418, 418, 418, 419, 419, 420, 420, 420, 421, 421, 421, 422, 422, 422, 422, 422, 423, 423, 423, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 425, 425, 425, 426, 426, 427, 427, 427, 428, 428, 429, 429, 429, 430, 430, 430, 431, 432, 432, 432, 433, 434, 434, 435, 435, 435, 435, 435, 435, 436, 436, 437, 437, 438, 438, 439, 439, 440, 440, 440, 441, 441, 442, 443, 443, 444, 444, 445, 445, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 447, 448, 448, 449, 449, 449, 449, 450, 450, 450, 450, 451, 451, 451, 451, 451, 452, 452, 452, 452, 452, 452, 452, 452, 453, 453, 454, 454, 454, 455, 455, 455, 455, 455, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 457, 457, 457, 457, 457, 457, 457, 457, 457, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 460, 460, 460, 460, 460, 460, 460, 460, 460, 461, 461, 461, 461, 461, 462, 462, 462, 462, 462, 462, 462, 462, 462, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 464, 464, 464, 464, 464, 464, 464, 464, 464, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 468, 468, 468, 468, 468, 468, 468, 468, 468, 469, 469, 469, 469, 469, 469, 470, 470, 471, 471, 471, 472, 473, 473, 473, 473, 473, 473, 473, 474, 474, 474, 474, 474, 474, 475, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, 477, 477, 477, 477, 477, 477, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 479, 479, 479, 479, 480, 481, 481, 481, 482, 482, 482, 482, 482, 482, 482, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 484, 484, 484, 484, 485, 485, 486, 486, 487, 487, 488, 489, 489, 489, 489, 490, 490, 491, 491, 491, 491, 491, 492, 492, 492, 492, 492, 492, 492, 492, 493, 493, 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 496, 496, 497, 498, 497, 499, 499, 499, 499, 500, 500, 501, 501, 502, 503, 504, 503, 505, 505, 506, 507, 508, 508, 508, 508, 509, 509, 509, 509, 510, 510, 510, 510, 510, 510, 510, 510, 511, 511, 511, 512, 512, 512, 513, 513, 513, 513, 514, 514, 514, 514, 515, 515, 515, 515, 516, 516, 517, 517, 517, 517, 518, 518, 518, 518, 519, 519, 520, 520, 520, 521, 521, 521, 521, 521, 522, 522, 522, 523, 523, 523, 523, 524, 524, 524, 524, 525, 525, 525, 526, 526, 526, 526, 526, 526, 526, 526, 526, 527, 527, 527, 528, 528, 528, 529, 529, 529, 530, 530, 530, 531, 531, 531, 531, 532, 532, 532, 533, 533, 533, 534, 534, 534, 535, 535, 535, 536, 536, 536, 537, 537, 538, 538, 538, 539, 539, 539, 539, 539, 540, 540, 541, 541, 542, 542, 542, 542, 542, 543, 543, 543, 544, 544, 544, 545, 545, 545, 546, 547, 547, 547, 547, 547, 548, 548, 548, 548, 548, 548 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 2, 3, 1, 1, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 13, 3, 2, 3, 2, 2, 2, 2, 1, 3, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 2, 2, 1, 1, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 2, 6, 2, 4, 2, 2, 2, 3, 2, 2, 1, 2, 1, 2, 4, 5, 2, 3, 5, 6, 1, 1, 1, 7, 11, 8, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 7, 10, 1, 2, 1, 7, 10, 1, 2, 2, 2, 3, 2, 2, 1, 2, 7, 7, 4, 2, 1, 1, 4, 12, 2, 1, 1, 0, 6, 8, 2, 3, 3, 3, 0, 3, 4, 4, 4, 3, 3, 1, 3, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 3, 7, 2, 2, 1, 3, 2, 2, 1, 2, 8, 2, 2, 2, 1, 2, 1, 4, 7, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 0, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 1, 4, 5, 0, 2, 1, 5, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 0, 1, 0, 1, 5, 6, 3, 4, 4, 3, 6, 2, 1, 4, 1, 1, 4, 6, 7, 5, 1, 1, 4, 5, 1, 1, 1, 3, 0, 1, 2, 1, 5, 1, 2, 1, 4, 3, 2, 1, 2, 1, 5, 2, 1, 1, 3, 2, 0, 1, 1, 4, 2, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 0, 1, 1, 2, 1, 6, 5, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 2, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 3, 1, 2, 2, 4, 6, 1, 10, 1, 2, 3, 3, 2, 2, 2, 2, 2, 2, 4, 4, 4, 3, 3, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 4, 3, 3, 3, 4, 4, 4, 4, 5, 4, 6, 7, 4, 4, 5, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 3, 5, 6, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 4, 3, 2, 2, 1, 3, 4, 4, 4, 4, 4, 6, 4, 4, 5, 4, 4, 4, 4, 5, 4, 6, 7, 4, 4, 5, 5, 5, 5, 5, 5, 7, 5, 5, 6, 5, 5, 5, 5, 6, 5, 7, 8, 5, 5, 6, 3, 3, 3, 3, 3, 5, 3, 3, 4, 3, 3, 3, 3, 4, 3, 5, 6, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 4, 3, 5, 4, 4, 2, 3, 6, 6, 1, 1, 1, 2, 2, 2, 3, 3, 2, 2, 2, 1, 3, 4, 2, 0, 3, 1, 1, 2, 2, 2, 2, 4, 4, 4, 3, 4, 5, 7, 8, 6, 8, 9, 6, 6, 7, 10, 11, 12, 9, 5, 5, 6, 3, 5, 5, 5, 6, 5, 4, 9, 10, 11, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 2, 4, 4, 4, 4, 5, 4, 4, 5, 3, 4, 4, 4, 6, 7, 8, 9, 6, 10, 11, 12, 9, 3, 2, 3, 5, 6, 7, 4, 3, 3, 6, 6, 6, 7, 4, 4, 6, 9, 4, 3, 6, 7, 7, 2, 3, 3, 3, 4, 2, 2, 4, 7, 10, 3, 1, 3, 2, 2, 2, 2, 3, 5, 4, 5, 2, 7, 3, 2, 2, 3, 2, 2, 2, 3, 2, 3, 4, 3, 3, 5, 6, 4, 2, 3, 2, 2, 4, 3, 3, 2, 3, 1, 3, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 2, 2, 3, 5, 7, 7, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 10, 7, 7, 7, 9, 9, 10, 12, 12, 2, 2, 3, 4, 4, 4, 2, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 10, 7, 4, 7, 4, 2, 2, 3, 4, 4, 5, 4, 5, 4, 5, 3, 4, 5, 4, 5, 3, 5, 4, 5, 2, 3, 3, 4, 5, 3, 3, 3, 4, 5, 4, 5, 4, 5, 4, 5, 3, 4, 5, 4, 5, 2, 2, 3, 5, 4, 6, 6, 3, 3, 4, 6, 5, 4, 5, 2, 3, 5, 4, 6, 3, 2, 2, 3, 2, 3, 2, 3, 5, 4, 6, 2, 2, 2, 1, 4, 1, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 1, 0, 0, 1, 1, 1, 7, 8, 2, 4, 2, 4, 6, 2, 1, 1, 3, 3, 1, 3, 4, 2, 1, 3, 3, 4, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 2, 1, 3, 1, 3, 1, 2, 2, 1, 3, 0, 0, 2, 2, 1, 3, 5, 1, 2, 2, 2, 1, 1, 1, 1, 4, 2, 3, 3, 2, 3, 2, 2, 2, 3, 3, 3, 2, 3, 1, 3, 3, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 3, 3, 1, 2, 3, 3, 1, 2, 1, 1, 2, 2, 4, 1, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 2, 2, 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, 0, 5, 1, 6, 3, 1, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 1, 3, 4, 1, 2, 5, 6, 6, 2, 1, 2, 2, 5, 6, 6 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint16 yydefact[] = { 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 1021, 0, 0, 0, 0, 0, 0, 1021, 33, 0, 0, 0, 38, 0, 0, 0, 42, 1195, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 0, 263, 265, 0, 0, 9, 136, 138, 131, 132, 133, 137, 134, 135, 268, 10, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 11, 49, 50, 0, 0, 0, 0, 295, 0, 12, 63, 99, 0, 129, 98, 71, 96, 0, 68, 70, 66, 130, 97, 67, 0, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 64, 65, 69, 302, 139, 100, 0, 13, 14, 0, 0, 0, 0, 0, 0, 52, 51, 0, 0, 0, 0, 2, 0, 15, 0, 0, 363, 374, 0, 380, 0, 0, 0, 0, 0, 0, 321, 0, 453, 0, 0, 0, 0, 1021, 0, 328, 0, 332, 0, 0, 0, 72, 0, 338, 0, 340, 0, 0, 480, 72, 16, 0, 487, 17, 492, 0, 509, 495, 496, 497, 498, 511, 500, 501, 502, 0, 504, 505, 0, 0, 18, 20, 0, 525, 0, 0, 0, 530, 0, 21, 0, 0, 0, 0, 0, 22, 682, 23, 0, 0, 0, 0, 0, 0, 683, 24, 0, 1024, 1022, 1023, 0, 1082, 0, 0, 0, 27, 0, 1089, 1088, 1087, 1086, 29, 0, 0, 0, 0, 0, 139, 0, 30, 0, 1107, 0, 1104, 31, 0, 0, 0, 0, 32, 0, 0, 0, 0, 35, 0, 0, 1131, 36, 0, 0, 0, 0, 37, 1192, 1191, 1193, 1194, 39, 0, 40, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 1197, 43, 0, 0, 45, 0, 0, 0, 0, 139, 46, 1218, 47, 0, 0, 48, 1, 4, 218, 0, 210, 0, 0, 212, 0, 220, 213, 217, 228, 229, 214, 230, 0, 216, 0, 0, 237, 247, 250, 249, 248, 246, 236, 240, 244, 245, 235, 0, 0, 0, 238, 0, 0, 0, 239, 8, 0, 0, 0, 264, 0, 269, 281, 282, 0, 270, 271, 139, 0, 1020, 273, 274, 276, 0, 0, 0, 280, 0, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 142, 148, 140, 141, 143, 146, 149, 145, 144, 147, 0, 0, 53, 58, 59, 60, 61, 54, 55, 56, 62, 57, 0, 309, 0, 353, 349, 345, 346, 350, 347, 352, 310, 365, 358, 362, 357, 368, 367, 366, 364, 311, 356, 375, 313, 0, 312, 0, 382, 314, 0, 398, 387, 400, 388, 389, 391, 0, 393, 394, 139, 315, 0, 0, 0, 0, 316, 0, 0, 139, 317, 412, 139, 410, 318, 139, 413, 319, 0, 139, 0, 320, 433, 0, 431, 446, 0, 0, 0, 437, 429, 0, 439, 451, 442, 322, 454, 455, 323, 0, 0, 0, 422, 0, 424, 423, 326, 418, 419, 0, 327, 0, 456, 457, 458, 330, 331, 459, 333, 0, 460, 461, 462, 335, 73, 74, 76, 75, 463, 336, 464, 465, 337, 472, 474, 476, 470, 471, 478, 339, 0, 0, 483, 0, 343, 485, 344, 139, 486, 0, 493, 510, 494, 512, 513, 514, 499, 515, 517, 516, 518, 503, 506, 522, 0, 0, 0, 519, 507, 0, 0, 527, 526, 0, 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 538, 0, 681, 0, 539, 0, 540, 0, 0, 541, 0, 686, 685, 684, 0, 689, 0, 0, 0, 865, 0, 0, 0, 692, 696, 698, 699, 0, 0, 0, 801, 0, 0, 0, 838, 0, 0, 0, 0, 0, 0, 0, 840, 0, 0, 0, 26, 1083, 1084, 1085, 28, 0, 0, 0, 0, 1096, 1097, 0, 139, 0, 1094, 1091, 0, 0, 0, 139, 1112, 1115, 1113, 1114, 1108, 1109, 1110, 1111, 0, 0, 34, 1128, 1129, 0, 1136, 1138, 1137, 1133, 1134, 1132, 0, 0, 0, 0, 1139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1140, 1150, 0, 0, 0, 1141, 1142, 1190, 0, 202, 196, 0, 204, 197, 0, 206, 198, 1127, 1126, 199, 200, 201, 0, 0, 195, 0, 0, 0, 0, 1202, 1215, 1205, 0, 0, 1208, 0, 0, 1207, 1206, 150, 1224, 0, 1223, 1219, 219, 215, 0, 224, 0, 221, 0, 253, 256, 257, 255, 254, 251, 252, 243, 242, 241, 258, 260, 259, 0, 0, 0, 0, 0, 272, 0, 1061, 285, 0, 0, 139, 292, 95, 92, 93, 94, 139, 294, 293, 0, 0, 0, 0, 0, 0, 0, 307, 0, 303, 301, 300, 308, 348, 0, 0, 351, 369, 370, 359, 360, 371, 373, 372, 361, 377, 376, 0, 381, 395, 396, 397, 385, 399, 386, 401, 392, 390, 384, 0, 0, 0, 0, 0, 139, 409, 150, 150, 150, 139, 0, 0, 139, 447, 432, 0, 77, 443, 0, 436, 438, 139, 452, 441, 324, 0, 0, 426, 0, 0, 0, 0, 912, 913, 0, 1014, 0, 994, 0, 996, 0, 1016, 1018, 0, 1009, 329, 0, 473, 467, 475, 468, 477, 469, 479, 466, 0, 0, 484, 481, 482, 150, 508, 521, 520, 523, 0, 536, 524, 0, 0, 0, 0, 0, 0, 168, 168, 162, 0, 0, 0, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 162, 0, 0, 0, 0, 0, 576, 600, 0, 0, 0, 572, 0, 0, 0, 0, 168, 162, 0, 0, 677, 0, 687, 688, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 746, 0, 0, 0, 0, 0, 769, 0, 0, 0, 0, 0, 0, 0, 0, 790, 0, 0, 795, 796, 0, 0, 0, 817, 819, 818, 0, 821, 0, 0, 829, 831, 832, 866, 0, 0, 0, 0, 690, 691, 906, 904, 909, 908, 907, 905, 910, 0, 695, 0, 700, 0, 903, 0, 701, 702, 703, 0, 0, 0, 0, 0, 803, 0, 0, 804, 1034, 0, 1037, 1033, 0, 0, 0, 805, 0, 806, 1053, 1058, 1055, 1054, 1052, 1059, 1056, 1050, 1057, 1051, 1060, 0, 0, 811, 0, 0, 0, 1066, 0, 1068, 814, 0, 1070, 815, 836, 0, 0, 0, 841, 842, 843, 1095, 0, 0, 1102, 1098, 0, 0, 0, 1093, 1092, 1106, 1105, 0, 1120, 0, 0, 1116, 0, 1124, 0, 0, 1117, 0, 1135, 189, 189, 0, 189, 1160, 0, 1159, 1151, 0, 0, 0, 0, 1155, 0, 0, 0, 1158, 0, 0, 0, 0, 0, 1153, 1161, 0, 0, 0, 1152, 189, 189, 189, 203, 205, 207, 0, 208, 0, 1200, 1199, 0, 1203, 0, 139, 1209, 1210, 0, 1212, 1213, 0, 151, 152, 1204, 1225, 1226, 0, 211, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 1062, 1041, 0, 1048, 1049, 0, 0, 279, 0, 0, 0, 0, 296, 0, 306, 0, 305, 355, 354, 0, 0, 0, 0, 0, 139, 404, 0, 150, 407, 72, 72, 0, 0, 0, 150, 0, 81, 80, 448, 435, 0, 445, 153, 0, 0, 50, 0, 425, 0, 0, 922, 0, 0, 0, 0, 0, 0, 940, 0, 0, 0, 0, 0, 0, 961, 962, 0, 0, 0, 0, 975, 0, 981, 982, 984, 986, 0, 991, 1001, 1002, 1003, 0, 1005, 1010, 1012, 1013, 1011, 911, 0, 993, 0, 992, 921, 0, 0, 997, 999, 0, 998, 1019, 1000, 1007, 0, 0, 341, 0, 0, 534, 535, 0, 532, 528, 0, 168, 168, 168, 169, 170, 545, 546, 164, 163, 0, 168, 168, 168, 0, 551, 165, 168, 168, 168, 166, 167, 168, 168, 0, 168, 168, 0, 165, 0, 573, 0, 0, 0, 599, 0, 598, 0, 0, 575, 0, 574, 0, 0, 0, 0, 165, 165, 162, 0, 0, 162, 0, 0, 0, 168, 168, 673, 0, 168, 168, 678, 0, 181, 182, 183, 184, 185, 0, 87, 88, 86, 707, 0, 0, 0, 0, 0, 859, 857, 852, 0, 862, 846, 863, 849, 861, 855, 844, 858, 847, 845, 864, 860, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 755, 0, 0, 0, 0, 768, 770, 0, 0, 776, 775, 0, 0, 171, 0, 0, 139, 0, 0, 786, 0, 0, 791, 792, 793, 0, 0, 0, 800, 816, 820, 822, 825, 824, 0, 0, 0, 830, 867, 869, 0, 868, 693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 697, 0, 0, 0, 0, 802, 0, 139, 0, 1029, 1027, 0, 0, 139, 0, 1032, 839, 807, 0, 0, 0, 813, 0, 0, 1071, 834, 835, 0, 837, 1101, 1103, 1100, 1099, 1090, 0, 0, 1121, 0, 0, 1125, 1130, 191, 192, 193, 194, 190, 1144, 1143, 0, 0, 0, 1146, 1145, 0, 0, 0, 1154, 0, 0, 0, 0, 0, 1171, 0, 1185, 1184, 1186, 0, 0, 0, 1157, 0, 0, 0, 1156, 1166, 1165, 1167, 1163, 1162, 1164, 1188, 1187, 1189, 0, 0, 1201, 0, 139, 1216, 1211, 1214, 0, 0, 139, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 283, 287, 286, 0, 0, 0, 0, 0, 0, 0, 0, 1040, 0, 0, 0, 0, 297, 299, 298, 139, 304, 0, 0, 0, 405, 406, 150, 139, 0, 411, 414, 0, 0, 0, 72, 434, 79, 83, 78, 82, 450, 0, 444, 155, 156, 154, 72, 0, 0, 428, 420, 0, 0, 0, 0, 0, 139, 923, 0, 0, 0, 931, 0, 139, 936, 0, 941, 942, 0, 945, 946, 947, 0, 0, 0, 956, 0, 963, 0, 0, 0, 968, 969, 0, 0, 0, 976, 0, 0, 980, 983, 985, 987, 0, 0, 1004, 1006, 914, 1015, 915, 0, 1017, 1008, 0, 0, 490, 491, 0, 0, 533, 0, 542, 543, 544, 168, 548, 549, 550, 0, 0, 0, 555, 556, 162, 0, 0, 0, 168, 561, 562, 563, 564, 566, 165, 569, 570, 0, 168, 0, 0, 0, 165, 165, 162, 0, 0, 0, 0, 597, 0, 601, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 162, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 162, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 162, 0, 0, 0, 0, 165, 165, 162, 0, 0, 0, 165, 577, 578, 579, 580, 582, 0, 585, 586, 0, 165, 0, 0, 671, 672, 168, 675, 676, 0, 706, 139, 708, 0, 0, 0, 0, 0, 0, 0, 851, 848, 854, 853, 850, 856, 0, 0, 0, 0, 0, 139, 731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 747, 748, 749, 0, 753, 750, 752, 0, 757, 756, 758, 0, 0, 0, 0, 0, 0, 139, 0, 139, 0, 774, 177, 173, 178, 172, 175, 174, 176, 781, 782, 0, 0, 0, 785, 139, 0, 139, 794, 797, 139, 0, 139, 0, 823, 828, 870, 694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 895, 0, 0, 0, 0, 0, 704, 705, 139, 150, 0, 139, 139, 1035, 1036, 0, 1038, 0, 809, 0, 139, 1067, 1069, 833, 1118, 1119, 1122, 1123, 189, 189, 189, 1169, 1168, 1170, 1173, 1172, 1176, 1175, 1177, 1174, 1182, 1181, 1183, 1179, 1178, 1180, 0, 1196, 0, 1217, 0, 139, 0, 1220, 0, 0, 226, 0, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1043, 0, 1046, 1080, 1047, 1045, 1042, 139, 139, 0, 289, 132, 0, 378, 0, 402, 150, 153, 0, 0, 417, 430, 0, 440, 0, 421, 918, 0, 0, 0, 920, 924, 153, 925, 153, 929, 153, 927, 139, 932, 153, 934, 150, 153, 938, 153, 943, 139, 948, 153, 950, 153, 952, 153, 954, 139, 957, 153, 959, 153, 139, 965, 0, 153, 139, 970, 153, 973, 153, 139, 978, 153, 139, 989, 995, 0, 0, 489, 529, 0, 547, 552, 553, 554, 0, 558, 559, 560, 565, 168, 165, 571, 588, 589, 590, 591, 592, 0, 594, 595, 165, 0, 0, 0, 165, 165, 162, 0, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 0, 0, 0, 0, 165, 165, 162, 0, 0, 0, 165, 168, 168, 168, 168, 168, 0, 168, 168, 0, 165, 165, 168, 168, 168, 168, 168, 0, 168, 168, 0, 165, 165, 651, 652, 653, 654, 656, 0, 659, 660, 0, 165, 662, 663, 664, 665, 666, 0, 668, 669, 165, 581, 165, 0, 587, 0, 0, 674, 0, 709, 153, 0, 0, 153, 0, 0, 0, 722, 153, 723, 726, 727, 153, 728, 730, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 751, 754, 0, 153, 0, 0, 0, 771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 84, 0, 0, 901, 902, 150, 0, 0, 0, 1030, 1028, 1039, 808, 810, 150, 1148, 1147, 1149, 0, 1198, 1227, 0, 0, 1222, 1221, 227, 0, 0, 0, 261, 0, 0, 0, 0, 0, 1044, 277, 278, 153, 379, 383, 403, 408, 0, 415, 449, 325, 0, 0, 0, 926, 930, 928, 933, 935, 937, 939, 944, 949, 951, 953, 955, 958, 960, 964, 150, 153, 972, 150, 974, 977, 150, 988, 150, 0, 342, 488, 0, 557, 567, 168, 165, 596, 168, 168, 168, 168, 168, 0, 168, 168, 165, 642, 643, 644, 645, 646, 0, 648, 649, 165, 168, 168, 168, 168, 168, 0, 168, 168, 165, 168, 611, 612, 613, 614, 616, 165, 619, 620, 0, 168, 168, 631, 632, 633, 634, 636, 165, 639, 640, 0, 168, 655, 165, 0, 661, 165, 670, 583, 165, 679, 680, 139, 712, 0, 153, 716, 715, 0, 139, 0, 724, 729, 139, 0, 736, 737, 738, 739, 743, 744, 740, 741, 742, 0, 153, 759, 763, 0, 139, 0, 0, 772, 778, 777, 153, 779, 0, 783, 0, 787, 153, 0, 0, 827, 0, 179, 179, 0, 0, 179, 0, 179, 1020, 0, 0, 179, 179, 0, 0, 0, 0, 0, 0, 0, 896, 0, 0, 0, 1020, 85, 0, 179, 0, 1064, 900, 0, 0, 209, 1229, 1228, 0, 0, 231, 0, 266, 0, 0, 0, 1081, 290, 416, 0, 186, 0, 966, 967, 971, 979, 990, 334, 0, 568, 593, 602, 603, 604, 605, 606, 165, 608, 609, 168, 165, 650, 622, 623, 624, 625, 626, 165, 628, 629, 168, 615, 168, 165, 621, 635, 168, 165, 641, 657, 165, 667, 584, 0, 153, 710, 717, 0, 0, 0, 0, 0, 745, 760, 0, 0, 0, 773, 780, 0, 788, 789, 153, 798, 0, 180, 1020, 1020, 84, 0, 1020, 0, 1020, 871, 139, 0, 1020, 1020, 84, 0, 0, 1020, 1020, 0, 0, 899, 897, 898, 877, 1020, 1020, 1064, 1075, 0, 1031, 812, 0, 0, 233, 0, 0, 0, 0, 187, 188, 917, 919, 0, 168, 610, 647, 168, 630, 617, 168, 637, 168, 658, 0, 711, 153, 713, 153, 0, 153, 0, 153, 761, 153, 0, 153, 0, 1020, 883, 879, 1020, 0, 884, 0, 878, 1020, 0, 881, 880, 1020, 0, 0, 875, 874, 1020, 139, 876, 882, 1075, 1025, 0, 0, 1065, 1073, 0, 0, 0, 262, 158, 161, 160, 159, 157, 0, 139, 531, 607, 627, 618, 638, 153, 714, 721, 0, 735, 732, 762, 767, 0, 784, 0, 888, 873, 84, 0, 886, 0, 872, 84, 0, 887, 0, 1026, 1077, 1079, 0, 1072, 0, 0, 267, 0, 186, 0, 718, 139, 733, 764, 799, 1020, 0, 0, 1020, 0, 153, 1078, 1074, 232, 0, 0, 916, 25, 139, 719, 734, 139, 765, 890, 0, 1020, 889, 0, 1020, 234, 284, 720, 766, 84, 891, 84, 885, 1020, 1020, 893, 892 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 48, 398, 167, 149, 543, 1197, 2412, 2413, 399, 400, 401, 402, 150, 151, 152, 81, 425, 1135, 1609, 2604, 1281, 1293, 1277, 1840, 2502, 1339, 2541, 1502, 314, 711, 714, 717, 725, 58, 337, 343, 347, 350, 65, 367, 363, 359, 353, 757, 371, 72, 376, 82, 93, 382, 387, 1566, 102, 409, 153, 169, 206, 447, 801, 456, 457, 804, 809, 459, 461, 811, 464, 813, 476, 817, 819, 821, 481, 485, 489, 492, 496, 525, 521, 1206, 510, 844, 839, 1198, 848, 513, 530, 533, 538, 544, 547, 554, 873, 875, 877, 879, 559, 883, 561, 209, 563, 1670, 226, 565, 567, 571, 576, 583, 235, 1270, 586, 241, 594, 1286, 600, 926, 1301, 921, 1711, 1307, 1305, 922, 1713, 1310, 1312, 606, 609, 604, 243, 251, 646, 1002, 1365, 991, 1456, 1883, 2211, 1007, 1000, 870, 1246, 1250, 1257, 1259, 772, 256, 1015, 1018, 1026, 1159, 1160, 1161, 773, 2528, 2529, 1049, 1052, 2593, 2594, 2590, 2591, 2634, 1162, 1163, 261, 267, 275, 660, 655, 280, 285, 670, 676, 1076, 1081, 720, 290, 294, 683, 299, 690, 1507, 701, 702, 1111, 1106, 1512, 1096, 1518, 1530, 1526, 1100, 706, 304, 305, 318, 1122, 321, 327, 735, 738, 732, 329, 332, 743 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -2064 static const yytype_int16 yypact[] = { 4693, 71, 423, -2064, -2064, 704, -158, 333, 1138, 75, 509, 3850, 261, 1480, 21, 4728, 510, 1209, -2064, 261, 880, 997, -47, 37, 207, 93, -4, 402, 566, 1784, 6, 871, 93, -2064, 126, 108, 897, -2064, 49, 238, 407, -2064, 572, -2064, 76, 3208, 265, 96, 508, 529, 1097, 296, 588, 565, 156, 601, -3, 1070, -2064, -58, 92, 261, 2, 609, 444, -2064, 616, 178, -2064, -2064, 20, 178, -2064, -2064, -2064, -2064, 178, -2064, -2064, -2064, -2064, -2064, -2064, -25, 643, 4401, 46, 646, 677, 696, 722, 737, 744, -2064, -2064, -2064, 178, 1276, 178, 178, 1118, 178, -2064, -2064, -2064, 607, -2064, -2064, -2064, -2064, 3243, -2064, -2064, -2064, -2064, -2064, -2064, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 712, -2064, 178, -2064, -2064, 261, 261, 261, 261, 261, 261, -2064, -2064, 261, 261, 261, 261, -2064, 694, -2064, 689, 1596, 248, 577, 634, -23, 4031, 172, 4342, 3994, 3243, 2671, -2064, 26, -72, 852, 795, 17, 592, 93, 58, -2064, 827, -2064, 663, 612, 157, 361, -29, -2064, 740, -2064, 22, 808, 438, 361, -2064, 4401, -2064, -2064, -2064, 840, 868, -2064, -2064, -2064, -2064, 661, -2064, -2064, -2064, -51, -2064, -2064, 4401, 3603, -2064, -2064, 27, -2064, 907, 911, 81, -2064, 178, -2064, 51, 506, 849, 923, 16, -2064, -2064, -2064, 926, 929, 261, 261, 178, 178, -2064, -2064, 937, -2064, -2064, -2064, 3097, -2064, 942, 945, 178, -2064, 949, -2064, -2064, -2064, -2064, -2064, 178, 1157, 261, 1983, 178, 712, 178, -2064, 959, -2064, 3963, -2064, -2064, 1011, 963, 966, 178, -2064, -36, 974, 4401, 984, -2064, 1159, 178, 908, -2064, 641, 1498, 540, 987, -2064, -2064, -2064, -2064, -2064, -2064, 1020, -2064, 3, 147, 240, 69, 178, 178, 183, -2064, 178, 767, 1030, -2064, 178, 178, -2064, 1042, 39, 45, 1050, 712, -2064, -2064, -2064, 1115, 178, -2064, -2064, -2064, -2064, 178, -2064, 1075, 1079, -2064, 178, 1139, -2064, -2064, -2064, -2064, -2064, -2064, 178, -2064, 464, 1076, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 178, 178, -2064, 178, 1085, 1101, -2064, -2064, 178, 178, 178, -2064, 178, -2064, -2064, -2064, 1107, -2064, -2064, 712, 1116, -2064, -2064, -2064, -2064, 1119, 1120, 4401, -2064, 178, -2064, -2064, -2064, 178, 1128, 1134, 1134, 4401, 178, 178, 178, 178, 178, 178, -2064, 178, 3243, 1276, 178, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1276, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1148, -2064, 899, 348, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 342, -2064, -2064, -2064, 992, -2064, 842, -2064, -2064, -2064, -2064, -2064, 1163, -2064, 1169, -2064, -2064, 5, 988, -2064, 1003, -2064, -2064, -2064, 1019, -2064, -2064, 712, -2064, 178, 178, 2437, 178, -2064, 4401, 4401, 712, -2064, -2064, 712, -2064, -2064, 712, -2064, -2064, 4401, 712, 178, -2064, -2064, 4401, -2064, 1183, 22, 999, 9, -2064, -2064, 1000, 4401, 1184, -2064, -2064, -2064, -2064, -2064, 1188, 1197, 1202, -2064, 1016, -2064, -2064, -2064, -2064, -2064, 178, -2064, 302, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 22, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1152, 1172, 1176, -2064, -2064, 993, -2064, 178, 1222, 1024, 3963, -2064, -2064, -2064, 712, -2064, 1240, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 4401, 4401, 4401, -2064, -2064, 1243, 261, -2064, -2064, 1245, 1247, 1062, 178, 550, 1173, -2064, 241, 1182, 4730, 43, 1267, -2064, 1272, -2064, 1274, -2064, 129, -2064, 1285, 1287, -2064, 1277, -2064, -2064, -2064, 178, -2064, 3963, 687, 838, 489, 1288, 726, 1199, -2064, -2064, -2064, 1280, 40, 1309, 85, 178, 389, 762, 503, 4401, 261, 1782, 804, 15, 163, 204, 7, -2064, 1298, 1299, 1313, -2064, -2064, -2064, -2064, -2064, 178, 178, 178, 178, -2064, -2064, 178, 712, 178, -2064, 178, 1276, 178, 1316, 712, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 435, 523, -2064, -2064, -2064, 1317, -2064, -2064, -2064, -2064, 1228, -2064, 1320, 1327, 1248, 1334, -2064, 1337, 1262, 1343, 640, 70, 685, 67, 710, 1346, 732, -2064, -2064, 1348, 1349, 1347, -2064, -2064, -2064, 1352, -2064, -2064, 1353, -2064, -2064, 1357, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 178, -2064, 178, 1364, 178, 178, -2064, 355, -2064, 630, 1366, -2064, 633, 1367, -2064, -2064, 130, 178, 178, -2064, 1361, -2064, -2064, 1370, 1214, 178, 1365, 578, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1372, 178, 178, 178, 4401, -2064, 1380, 2389, -2064, 1382, 1383, 712, -2064, -2064, -2064, -2064, -2064, 712, -2064, -2064, 178, 178, 178, 4401, 178, 1276, 178, -2064, 178, -2064, -2064, -2064, -2064, -2064, 1387, 1393, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 495, -2064, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 4401, 4401, 4401, 1396, 178, 712, -2064, 130, 130, 130, 712, 1276, 178, 712, -2064, -2064, 178, -42, 1242, 1402, -2064, -2064, 712, -2064, -2064, -2064, 1403, 1406, 954, 178, 4343, 666, 480, -2064, -2064, 178, 186, 623, -2064, 1166, -2064, 1782, 564, 1135, 97, -2064, -2064, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 1411, -2064, -2064, -2064, 130, -2064, -2064, -2064, -2064, 4373, -2064, -2064, 1413, 1415, 178, 1417, 1422, 1426, 308, 308, -39, 1414, 1429, 1446, 1449, 1201, 1455, 1461, 1462, 466, 466, -39, 1466, 1468, -39, 1472, 1481, 4765, 1484, 1485, -2064, -2064, 1487, 1488, 543, -2064, 1490, 1500, 1503, 1508, 308, -39, 1501, 1510, -2064, 1512, -2064, -2064, 712, -26, 1252, 1254, 1289, 1292, 1400, 1409, 1293, 1514, 301, 1397, 1431, 1305, 1124, 1492, 1306, 1318, 1437, 1539, 1342, 44, 11, 462, 1315, 3243, 1782, 1518, -110, 1351, 1553, 113, -2064, -2064, 498, 1562, 1566, -2064, -2064, -2064, 1568, 1362, 29, 1782, 1369, -2064, -2064, -2064, 261, 1572, 1573, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 0, -2064, 998, -2064, 178, -2064, 178, -2064, -2064, -2064, 178, 178, 178, 726, 4401, -2064, 1574, 757, -2064, -2064, 178, -2064, -2064, 178, 3243, 178, -2064, 4401, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 261, 178, -2064, 178, 726, 1575, -2064, 178, 178, -2064, 261, -2064, -2064, -2064, 598, 1577, 1578, -2064, -2064, -2064, -2064, 178, 178, -2064, -2064, 1276, 178, 178, -2064, -2064, -2064, -2064, 178, -2064, 178, 1482, -2064, 178, -2064, 178, 1489, -2064, 1584, -2064, 421, 421, 766, 421, -2064, 776, -2064, -2064, 1586, 1587, 803, 1594, -2064, 1597, 1598, 1601, -2064, 824, 839, 1602, 1603, 1606, -2064, -2064, 1611, 1612, 1607, -2064, 421, 421, 421, -2064, -2064, -2064, 178, -2064, 178, 1615, -2064, 178, -2064, 3963, 712, -2064, -2064, 1616, -2064, -2064, 1618, -2064, -2064, -2064, -2064, 1589, 1983, -2064, 178, 1613, 178, 178, 178, 1122, 1621, 1620, 178, 178, 712, -13, 1236, 1286, 1290, 1295, 1296, 1300, 1301, 2389, -2064, 1302, -2064, -2064, 1624, 1625, -2064, 178, 1626, 1630, 1631, -2064, 4401, -2064, 178, -2064, -2064, -2064, 178, 178, 178, 1636, 1642, 712, -2064, 4401, 130, -2064, 361, 361, 1276, 178, 1647, 130, 178, 1, 4, 18, -2064, 1649, -2064, 102, 178, 1648, 1655, 178, -2064, 1651, 742, 3243, 1427, 1433, 1435, 104, 3243, 1439, -2064, 322, 1529, 149, 1440, 1442, 158, -2064, -2064, 35, 1515, 606, 700, 1782, 299, -2064, 1658, 1448, -2064, 561, -2064, -2064, -2064, -2064, 1782, 1491, -2064, -2064, -2064, -2064, -2064, 178, -2064, 178, -2064, -2064, 178, 178, -2064, -2064, 178, -2064, -2064, -2064, -2064, 1497, 178, -2064, 178, 228, -2064, -2064, 1677, 1685, -2064, 178, 308, 308, 308, -2064, -2064, -2064, -2064, -2064, -2064, 1686, 308, 308, 308, 682, -2064, 466, 308, 308, 308, -2064, -2064, 308, 308, 1691, 308, 308, 1692, 466, 711, -2064, 1694, 1697, 1699, -2064, 758, -2064, 822, 1035, -2064, 735, -2064, 1436, 1700, 1701, 1702, 466, 466, -39, 1705, 1706, -39, 1713, 1720, 1727, 308, 308, -2064, 1730, 308, 308, -2064, 1731, -2064, -2064, -2064, -2064, -2064, 261, -2064, -2064, -2064, 3243, 816, 178, 1230, 1471, 829, -2064, -2064, -2064, 969, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1732, 178, -2064, 261, 1736, 178, 4401, 261, 1494, 1513, 1516, 184, 192, 1519, 201, 1444, 1742, 1745, 1747, 1409, 1748, 1749, 1750, 1456, 1012, 1752, 178, 1266, 1556, -2064, -2064, 261, 3243, -2064, -2064, 3243, 178, 32, 1753, 178, 712, 1276, 261, -2064, 3243, 4401, -2064, -2064, -2064, 261, 261, 3243, -2064, -2064, -2064, -2064, -2064, -2064, 3243, 178, 261, -2064, -2064, -2064, 178, -2064, -2064, 1754, 178, 1541, 229, 178, 1543, 178, 472, 178, -2064, 178, 1544, 1545, 178, 178, 178, 178, 178, 178, 178, 23, 178, 178, 1547, -2064, 178, 178, 178, 178, -2064, 4401, 712, 1763, 4401, 4401, 178, 178, 712, 1276, -2064, -2064, 178, 178, 178, 4401, -2064, 178, 178, -2064, -2064, -2064, 1764, -2064, -2064, -2064, -2064, -2064, -2064, 178, 178, -2064, 178, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1769, 1771, 1773, -2064, -2064, 1774, 1775, 1777, -2064, 1779, 1781, 1795, 1796, 1785, -2064, 1798, -2064, -2064, -2064, 1799, 1800, 1802, -2064, 1803, 1804, 1806, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 178, -2064, 178, 712, -2064, -2064, -2064, 1983, 178, 712, 178, 178, 178, -2064, 178, 178, 1808, 178, 1772, 1780, 178, 178, -2064, -2064, -2064, 1807, 1409, 1810, 1813, 1814, 1817, 1818, 1820, -2064, 261, 4401, 4401, 178, -2064, -2064, -2064, 712, -2064, 1229, 178, 1229, -2064, -2064, 130, 712, 4401, -2064, -2064, 178, 178, 1821, 361, -2064, -2064, -2064, -2064, -2064, -2064, 178, -2064, -2064, -2064, -2064, 361, 178, 1822, -2064, -2064, 4401, 1823, 1825, 1826, 4401, 712, -2064, 3243, 3243, 3243, 3243, 3243, 712, -2064, 3243, -2064, -2064, 3243, -2064, -2064, 3243, 3243, 3243, 3243, 3243, 3243, -2064, 4401, 3243, 178, -2064, -2064, 4401, 3243, 3243, -2064, 4401, 3243, -2064, -2064, -2064, -2064, 4401, 3243, -2064, -2064, -2064, -2064, -2064, 178, -2064, -2064, 1829, 178, -2064, -2064, 1830, 1832, -2064, 178, -2064, -2064, -2064, 308, -2064, -2064, -2064, 1834, 1835, 1836, -2064, -2064, -39, 1833, 1838, 1839, 308, -2064, -2064, -2064, -2064, -2064, 466, -2064, -2064, 1841, 308, 1842, 1843, 1854, 466, 466, -39, 1869, 1873, 1875, 1077, -2064, 1126, -2064, 1350, 1546, 1876, 1881, 1884, 466, 466, -39, 1874, 1878, -39, 1886, 1557, 1887, 1888, 1890, 466, 466, -39, 1892, 1893, -39, 1894, 1582, 1895, 1897, 1898, 466, 466, -39, 1900, 1901, -39, 1906, 1907, 1909, 1912, 466, 466, -39, 1902, 1918, 1919, 466, -2064, -2064, -2064, -2064, -2064, 1923, -2064, -2064, 1925, 466, 1927, 1928, -2064, -2064, 308, -2064, -2064, 1931, -2064, 712, -2064, 4401, 178, 178, 4401, 178, 1934, 1252, -2064, -2064, -2064, -2064, -2064, -2064, 1935, 3243, 261, 1936, 3243, 712, -2064, 1937, 1252, 178, 178, 178, 178, 178, 178, 178, 178, 178, 1929, -2064, -2064, -2064, 1938, -2064, -2064, -2064, 1940, -2064, -2064, -2064, 178, 4401, 178, 1941, 1252, 261, 712, 1276, 712, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 1276, 1276, -2064, 712, 1276, 712, -2064, -2064, 712, 1276, 712, 1276, -2064, -2064, -2064, -2064, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -2064, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 2437, 1942, 178, -2064, 178, 178, 178, 1944, 1945, -2064, -2064, 712, 130, 1946, 712, 712, -2064, -2064, 1276, -2064, 178, -2064, 1947, 712, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 421, 421, 421, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, -2064, 178, -2064, 178, 712, 178, -2064, 1276, 178, -2064, 178, -2064, 1815, 1949, 1951, 1948, 1828, 178, 178, 1953, 1955, -2064, 1957, -2064, -2064, -2064, -2064, -2064, 712, 712, 4401, -2064, -2064, 178, -2064, 178, -2064, 130, 102, 178, 1959, -2064, -2064, 178, -2064, 22, -2064, -2064, 1960, 1961, 1963, -2064, -2064, 102, -2064, 102, -2064, 102, -2064, 712, -2064, 102, -2064, 130, 102, -2064, 102, -2064, 712, -2064, 102, -2064, 102, -2064, 102, -2064, 712, -2064, 102, -2064, 102, 712, -2064, 4401, 102, 712, -2064, 102, -2064, 102, 712, -2064, 102, 712, -2064, -2064, 1958, 22, 1964, -2064, 178, -2064, -2064, -2064, -2064, 1966, -2064, -2064, -2064, -2064, 308, 466, -2064, -2064, -2064, -2064, -2064, -2064, 1967, -2064, -2064, 466, 1969, 1971, 1972, 466, 466, -39, 1977, 1978, 1979, 1980, 1985, 1986, 466, 466, -39, 1984, 1988, 1990, 1991, 1992, 1993, 466, 466, -39, 1996, 1997, 1999, 466, 308, 308, 308, 308, 308, 2001, 308, 308, 2002, 466, 466, 308, 308, 308, 308, 308, 2003, 308, 308, 2004, 466, 466, -2064, -2064, -2064, -2064, -2064, 2006, -2064, -2064, 2007, 466, -2064, -2064, -2064, -2064, -2064, 2008, -2064, -2064, 466, -2064, 466, 2009, -2064, 2010, 2011, -2064, 3963, -2064, 102, 2012, 3243, 102, 178, 4401, 2013, -2064, 102, -2064, -2064, -2064, 102, -2064, -2064, 4401, 2014, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -2064, -2064, 3243, 102, 178, 4401, 2015, -2064, 1276, 1276, 1276, 178, 3243, 1276, 178, 1276, 1276, 4401, 1276, 178, 1276, -2064, 178, 178, 178, 178, 178, 178, 1252, 178, 178, 178, 1252, 178, 178, 178, 178, 1252, 178, 178, 178, 178, 178, 712, 178, 1551, 1252, 178, 178, -2064, -2064, 130, 261, 2018, 2019, -2064, -2064, -2064, -2064, -2064, 130, -2064, -2064, -2064, 178, -2064, -2064, 1276, 178, -2064, -2064, -2064, 1144, 2020, 2021, -2064, 2023, 178, 2024, 1229, 2025, -2064, -2064, -2064, 102, -2064, -2064, -2064, -2064, 2026, -2064, -2064, -2064, 2028, 4401, 2029, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 130, 102, -2064, 130, -2064, -2064, 130, -2064, 130, 2030, -2064, -2064, 178, -2064, -2064, 308, 466, -2064, 308, 308, 308, 308, 308, 2032, 308, 308, 466, -2064, -2064, -2064, -2064, -2064, 2034, -2064, -2064, 466, 308, 308, 308, 308, 308, 2035, 308, 308, 466, 308, -2064, -2064, -2064, -2064, -2064, 466, -2064, -2064, 2036, 308, 308, -2064, -2064, -2064, -2064, -2064, 466, -2064, -2064, 2037, 308, -2064, 466, 2038, -2064, 466, -2064, -2064, 466, -2064, -2064, 712, -2064, 3243, 102, -2064, -2064, 2040, 712, 178, -2064, -2064, 712, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 178, 102, -2064, -2064, 2041, 712, 178, 1276, -2064, -2064, -2064, 102, -2064, 178, -2064, 1276, -2064, 102, 4401, 1252, -2064, 178, 2042, 2042, 178, 178, 2042, 1252, 2042, -2064, 4401, 1252, 2042, 2042, 178, 178, 1252, 178, 178, 178, 178, -2064, 1276, 178, 2044, -2064, -2064, 178, 2042, 261, 52, -2064, 2045, 261, -2064, -2064, -2064, 2046, 178, -2064, 2047, -2064, 2049, 1939, 178, -2064, -2064, -2064, 2050, 53, 4401, -2064, -2064, -2064, -2064, -2064, -2064, 178, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 466, -2064, -2064, 308, 466, -2064, -2064, -2064, -2064, -2064, -2064, 466, -2064, -2064, 308, -2064, 308, 466, -2064, -2064, 308, 466, -2064, -2064, 466, -2064, -2064, 178, 102, -2064, -2064, 3243, 4401, 178, 4401, 178, -2064, -2064, 3243, 4401, 178, -2064, -2064, 4401, -2064, -2064, 102, -2064, 2052, -2064, -2064, -2064, 1252, 178, -2064, 2053, -2064, -2064, 712, 2054, -2064, -2064, 1252, 178, 2055, -2064, -2064, 178, 4401, -2064, -2064, -2064, -2064, -2064, -2064, 52, 1708, 1782, -2064, -2064, 2056, 2057, -2064, 2048, 2059, 141, 4401, -2064, -2064, -2064, -2064, 2060, 308, -2064, -2064, 308, -2064, -2064, 308, -2064, 308, -2064, 3963, -2064, 102, -2064, 102, 178, 102, 2061, 102, -2064, 102, 178, 102, 178, -2064, -2064, -2064, -2064, 2064, -2064, 178, -2064, -2064, 178, -2064, -2064, -2064, 2065, 178, -2064, -2064, -2064, 712, -2064, -2064, 1708, -2064, 1797, 1682, 1782, -2064, 2066, 2068, 2070, -2064, -2064, -2064, -2064, -2064, -2064, 178, 712, -2064, -2064, -2064, -2064, -2064, 102, -2064, -2064, 2074, -2064, 3243, -2064, -2064, 2075, -2064, 1252, -2064, -2064, 1252, 178, -2064, 178, -2064, 1252, 178, -2064, 4401, -2064, 1797, -2064, 261, -2064, 2078, 2079, -2064, 178, 53, 2109, 3243, 712, -2064, 3243, -2064, -2064, 178, 2076, -2064, 178, 102, -2064, -2064, -2064, 2110, 2111, -2064, -2064, 712, -2064, -2064, 712, -2064, -2064, 2115, -2064, -2064, 2116, -2064, -2064, -2064, -2064, -2064, 1252, -2064, 1252, -2064, -2064, -2064, -2064, -2064 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -2064, -2064, -10, -2064, 254, -202, -2064, -1059, -876, 1661, -2064, 642, -257, 1496, -43, 91, -1580, 1877, -815, 933, -2064, -877, 1132, 1499, -2064, -1071, -2064, -613, -1039, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -1320, -2064, -2064, -2064, -2064, -2064, -623, -2064, -2064, -2064, -2064, -2064, -2064, 409, -2064, -2064, -2064, -2064, 962, -635, -1303, -457, -2064, -2064, -2064, -2064, -471, -466, -2064, -2064, -2063, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, 1432, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064, -2064 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1077 static const yytype_int16 yytable[] = { 101, 1040, 326, 560, 1963, 1431, 1965, 103, 1014, 1017, 103, 276, 1053, 842, 94, 95, 1187, 1188, 1189, 272, 1044, 607, 1603, 516, 374, 293, 94, 95, 1880, 345, 1564, 584, 94, 95, 320, 1295, 1599, 331, 1298, 1601, 336, 103, 244, 733, 342, 1398, 1503, 349, 1508, 736, 358, 385, -1063, 366, 1334, 1329, 592, 373, 257, 1833, 258, 377, 1640, 1421, 1814, 1343, 378, 709, 497, 814, 1265, 1396, 106, 1537, 1538, 1539, 106, 1004, 1834, 94, 95, 1835, 718, 498, 1195, 2539, 394, 589, 403, 404, 408, 410, 1836, 572, 815, 94, 95, 300, 545, 94, 95, 245, 1009, 517, 1054, 499, 83, 414, 674, 1409, 1055, 94, 95, 379, 1260, 1837, 108, 66, 1413, 108, 274, 1279, 527, 246, 500, 1624, 1606, 1607, 923, 1092, 351, 518, 1838, 361, 511, 49, 1399, 501, 1869, 84, 502, 462, 426, 929, 94, 95, 301, 1005, 253, 463, 108, 103, 1101, 85, 1422, 792, 86, 519, 168, 94, 95, 573, 455, 1410, 87, 503, 504, 479, 795, 247, 1634, 380, 88, 362, 259, 94, 95, 242, 302, 1638, 1046, 94, 95, 352, 1093, 287, 94, 95, 930, 94, 95, 1335, 1336, 1261, 924, 590, 1196, 1608, 1641, 574, 111, 413, 546, 111, 1337, 1803, 112, 113, 103, 112, 113, 712, 252, 1805, 675, 585, 535, 1280, 1102, 381, 505, 1094, 1808, 512, 591, 1133, 106, 114, 506, 1006, 1254, 114, 94, 95, 111, 665, 528, 575, 614, 615, 112, 113, 306, 1338, 103, 89, 906, 1950, 1668, 1565, 649, 94, 95, 719, 1642, 907, 908, 375, 651, 654, 108, 657, 661, 1397, 663, 103, 154, 386, 480, 346, 488, 491, 495, 227, 673, 354, 608, 250, 260, 524, 1600, 682, 684, 1602, 279, 507, 508, 90, 593, 116, 1010, 1045, 116, 555, 1400, 1432, 477, 291, 277, 1056, 909, 721, 722, 724, 715, 726, 854, 855, 278, 729, 730, 843, 1423, 254, 931, 360, 734, 108, 1881, 91, 742, 744, 737, 116, 2599, 2540, 745, -1063, 1368, 248, 1407, 748, 750, 1095, 303, 1625, 816, 67, 146, 751, 529, 146, 147, 148, 111, 147, 148, 1425, 520, 1629, 112, 113, 1414, 108, 759, 760, 761, 509, 762, 319, 856, 1125, 659, 765, 766, 767, 857, 768, 1047, 1011, 68, 1591, 146, 1839, 108, 249, 147, 148, 1597, 330, 1635, 114, 1134, 932, 777, 355, 255, 1248, 778, 1639, 1462, 292, 933, 783, 784, 785, 786, 787, 788, 288, 789, 111, 723, 793, 794, 1068, 92, 112, 113, 427, 428, 429, 430, 431, 432, 1804, 796, 433, 434, 435, 436, 1476, 289, 1806, 934, 858, 910, 911, 356, 357, 536, 448, 1809, 116, 2600, 50, 449, 111, 859, 341, 69, 286, 1763, 112, 113, 1766, 860, 1048, 1861, 799, 993, 861, 307, 537, 557, 478, 1669, 539, 111, 1275, 1497, 1498, 1650, 1369, 112, 113, 262, 824, 825, 826, 828, 1785, 1072, 450, 51, 94, 95, 2601, 2602, 308, 540, 1050, 146, 1291, 1630, 836, 147, 148, 1276, 328, 116, 994, 52, 986, 752, 912, 451, 1800, 94, 95, 612, 613, 791, 862, 913, 914, 94, 95, 333, 915, 1242, 595, 94, 95, 853, 884, 541, 1826, 1651, 987, 368, 53, 70, 863, 656, 1415, 116, 864, 2635, 865, 802, 800, 1370, 1173, 334, 54, 916, 1019, 55, 146, 1020, 452, 1073, 147, 148, 880, 96, 116, 1313, 106, 56, 309, 866, 1631, 920, 338, 753, 1314, 1315, 867, 1077, 710, 713, 716, 896, 897, 97, 94, 95, 340, 71, 2655, 1652, 939, 1371, 146, 315, 868, 1191, 147, 148, 895, 1144, 803, 453, 454, 1499, 1500, 1655, 310, 1145, 207, 840, 339, 1649, 1632, 146, 522, 526, 703, 147, 148, 1316, 1481, 938, 1658, 344, 208, 542, 898, 1021, 369, 94, 95, 1501, 1482, 98, 596, 995, 1292, 1012, 372, 754, 1025, 1074, 871, 94, 95, 1022, 558, 1078, 996, 997, 869, 1127, 1128, 1243, 1130, 1131, 1013, 1251, 1060, 1061, 1062, 1063, 988, 106, 1064, 383, 1066, 388, 1067, 311, 1069, 704, 523, 2431, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 370, 1244, 312, 1126, 316, 1075, 1866, 1023, 597, 389, 989, 1681, 1682, 99, 691, 686, 390, 568, 313, 114, 755, 57, 940, 941, 942, 756, 1245, 1079, 1118, 1119, 1402, 1120, 1416, 1123, 1124, 990, 1403, 998, 999, 1656, 1701, 1702, 391, 1317, 1318, 1237, 1136, 1137, 943, 944, 899, 900, 945, 1141, 1142, 946, 1683, 392, 598, 1097, 415, 569, 947, 393, 1748, 1749, 948, 364, 438, 693, 687, 1147, 1148, 1149, 949, 950, 1465, 1466, 1715, 263, 1255, 599, 951, 952, 1103, 1703, 317, 1716, 1717, 1966, 1168, 1169, 1170, 1080, 1172, 1657, 1174, 365, 1175, 953, 548, 1024, 993, 100, 1238, 954, 1108, 955, 956, 1750, 957, 411, 1319, 460, 1098, 1178, 114, 1180, 705, 901, 437, 1320, 1321, 1487, 2035, 958, 1322, 549, 902, 903, 1239, 416, 1718, 1185, 94, 95, 1779, 1614, 993, 1104, 1504, 1192, 1726, 994, 2048, 1194, 959, 417, 418, 419, 1509, 1727, 1728, 1323, 891, 420, 1041, 1205, 1207, 2085, 904, 1109, 2088, 570, 1247, 1249, 1252, 458, 421, 960, 2096, 1256, 514, 2099, 1644, 422, 1262, 1515, 1646, 994, 1645, 2107, 1684, 1685, 2110, 1263, 423, 2218, 2219, 2220, 1304, 2117, 961, 688, 1016, 1505, 1729, 515, 1523, 550, 1271, 534, 59, 532, 1028, 1510, 531, 60, 1240, 1051, 556, 1704, 1705, 1527, 566, 264, 1179, 975, 699, 689, 265, 962, 266, 963, 2136, 564, 1042, 587, 964, 965, 588, 976, 1516, 806, 1647, 1751, 1752, 551, 295, 2146, 977, 966, 967, 605, 61, 610, 1342, 1786, 1594, 611, 978, 1686, 968, 1524, 281, 601, 1241, 616, 1719, 1720, 1687, 1688, 647, 1099, 648, 2163, 1401, 62, 1528, 650, 995, 602, 94, 1204, 1615, 1616, 979, 969, 664, 970, 1706, 228, 671, 996, 997, 672, 1424, 1617, 1105, 1707, 1708, 971, 1689, 972, 677, 1430, 1648, 980, 424, 973, 552, 1592, 1593, 679, 1753, 229, 995, 707, 1043, 1457, 1110, 1458, 63, 1754, 1755, 1459, 1460, 1461, 685, 996, 997, 1709, 1730, 1731, 807, 1467, 1618, 1721, 1468, 296, 1471, 1819, 1820, 974, 1787, 1433, 1722, 1723, 236, 708, 1434, 1724, 727, 981, 1506, 1756, 1474, 603, 1475, 728, 282, 553, 1478, 1479, 1511, 1737, 64, 780, 781, 1435, 1436, 731, 1437, 1438, 1738, 1739, 1485, 1486, 1725, 739, 1406, 1488, 1489, 1439, 998, 999, 230, 1490, 666, 1491, 982, 1517, 1493, 1788, 1494, 1440, 1441, 1789, 94, 95, 231, 1732, 2209, 1442, 746, 758, 1443, 1544, 808, 747, 1733, 1734, 1525, 983, 763, 1735, 2052, 2053, 2509, 1740, 998, 999, 297, 1444, 667, 94, 95, 1529, 1445, 1446, 764, 1447, 283, 1540, 2524, 1541, 298, 769, 1543, 237, 1470, 284, 1736, 94, 95, 771, 94, 95, 774, 775, 94, 95, 984, 1549, 985, 1552, 232, 1554, 1555, 1556, 1558, 2054, 395, 1561, 1562, 2061, 2062, 94, 95, 668, 397, 1381, 94, 95, 1844, 238, 749, 2244, 797, 335, 405, 805, 1578, 798, 1790, 94, 95, 94, 95, 1583, 1448, 73, 810, 1584, 1585, 1586, 1382, 233, 812, 1383, 820, 818, 1384, 2258, 1557, 2291, 1595, 234, 822, 1598, 2063, 348, 838, 847, 2300, 841, 845, 1610, 849, 652, 1612, 680, 239, 2309, 2569, 2570, 2424, 850, 2573, 1385, 2575, 851, 852, 1791, 2578, 2579, 240, 878, 1899, 2583, 2584, 872, 94, 95, 1449, 1741, 1742, 2587, 2588, 1450, 406, 1140, 881, 210, 1551, 1386, 741, 1387, 94, 95, 1782, 874, 1660, 1451, 1661, 876, 1427, 1662, 1663, 882, 886, 1664, 890, 669, 892, 211, 893, 1666, 894, 1667, 94, 95, 73, 905, 1340, 1341, 1673, 2055, 2056, 653, 2622, 681, 917, 2623, 94, 95, 1823, 925, 2626, 1452, 1453, 927, 2628, 928, 94, 95, 937, 2631, 74, 212, 395, 396, 397, 1604, 1743, 935, 213, 936, 992, 1473, 1454, 1001, 1003, 1744, 1745, 1620, 214, 215, 1746, 1480, 1627, 75, 407, 216, 2394, 76, 2064, 2065, 2398, 1008, 1057, 1058, 1059, 2403, 2503, 1070, 1082, 2506, 1083, 2508, 1084, 217, 1374, 2512, 2513, 1747, 2057, 1085, 1086, 1780, 1781, 1783, 1342, 1087, 1455, 2058, 2059, 1088, 218, 2526, 1388, 2667, 1089, 1090, 2670, 1107, 1114, 1375, 1112, 1113, 1376, 1793, 1115, 1116, 219, 1796, 77, 1117, 1342, 2070, 2071, 2678, 220, 1121, 2680, 1129, 1132, 2060, 1138, 74, 1139, 1146, 1143, 2683, 2684, 2066, 1822, 1824, 1342, 1151, 1377, 1164, 1165, 221, 2067, 2068, 1832, 1176, 2416, 1842, 1972, 78, 75, 1177, 1389, 1184, 1962, 2420, 1199, 79, 80, 1200, 1974, 1202, 2072, 1203, 1378, 1258, 1379, 1855, 1253, 1264, 1268, 1282, 1857, 1269, 2069, 1272, 1859, 222, 1862, 1863, 1273, 1865, 1867, 1868, 1274, 1870, 1283, 1778, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1882, 1884, 1885, 2571, 1348, 1887, 1888, 1889, 1890, 1284, 77, 2438, 1285, 2580, 2440, 1896, 1897, 2441, 1288, 2442, 1287, 1900, 1901, 1902, 1289, 1290, 1904, 1905, 1296, 223, 1297, 1349, 94, 95, 1784, 1299, 1340, 1341, 1907, 1908, 224, 1909, 1910, 1344, 1300, 78, 1829, 1306, 1308, 1831, 1309, 1311, 1324, 79, 80, 94, 95, 1799, 1847, 1340, 1341, 1347, 1325, 1330, 1350, 1852, 1326, 155, 2499, 225, 1351, 1327, 1854, 1331, 1352, 1332, 2507, 1367, 1345, 156, 2511, 1346, 1366, 273, 1380, 2516, 1372, 1390, 1929, 1930, 1353, 1931, 1373, 2073, 2074, 1391, 1933, 1936, 1393, 1938, 1939, 1940, 1394, 1941, 1942, 1395, 1944, 1392, 1404, 1947, 1948, 1354, 157, 1408, 1411, 691, 1412, 94, 95, 1825, 158, 1340, 1341, 2649, 1417, 1420, 1960, 1355, 2652, 1418, 2166, 1419, 1426, 1964, 1428, 1429, 1567, 1464, 1477, 384, 1483, 1484, 1969, 1970, 2170, 2171, 1496, 1492, 2173, 1513, 1514, 1776, 1973, 2176, 1495, 2178, 1519, 1356, 1975, 1548, 1520, 1521, 2075, 1522, 412, 1531, 1532, 692, 1533, 1536, 693, 2076, 2077, 159, 1534, 1535, 2681, 1542, 2682, 1546, 1794, 1547, 1560, 1553, 1798, 1559, 1568, 1576, 1579, 1577, 1569, 2013, 1580, 1581, 1357, 1570, 1571, 1935, 1587, 2214, 1572, 1573, 1575, 2078, 1588, 439, 1358, 694, 1827, 1596, 1611, 2025, 1605, -427, 1613, 2027, 1621, 1359, 1633, 1845, 1653, 2030, 1622, 440, 1623, 160, 1849, 1850, 1628, 1636, 475, 1637, 484, 487, 490, 494, 1643, 1856, 2226, 1671, 441, 161, 162, 695, 1360, 1654, 1665, 1672, 1677, 163, 1659, 164, 442, 1696, 1699, 1757, 1361, 1710, 1362, 1363, 1712, 562, 1714, 1758, 1759, 1760, 443, 1764, 1765, 444, 1984, 1986, 1988, 1990, 1992, 165, 1767, 1995, 577, 582, 1997, 445, 1768, 1999, 2001, 2003, 2005, 2007, 2009, 1769, 696, 2012, 1772, 697, 1775, 1792, 2016, 2018, 1364, 1795, 2021, 1810, 1801, 2648, 1811, 1802, 2024, 1812, 1807, 1813, 1815, 1816, 1817, 1818, 1821, 1841, 698, 1858, 1860, 699, 1864, 1871, 1872, 446, 1886, 658, 1893, 1906, 2131, 2132, 700, 2134, 1911, 1342, 1912, 1913, 1945, 1914, 1915, 1916, 166, 1917, 678, 1918, 1946, 94, 95, 1921, 1342, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 1919, 1920, 1922, 104, 1923, 1924, 1925, 2079, 1926, 1927, 1928, 1949, 2159, 1943, 2161, 1951, 1342, 1952, 2090, 1953, 268, 2168, 1954, 1955, 1956, 1971, 1976, 2229, 1978, 1957, 1979, 1980, 2169, 2026, 2233, 2028, 2029, 2036, 106, 2032, 2033, 2034, 2037, 2101, 2038, 2041, 2411, 2043, 2044, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2045, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 1029, 2202, 2049, 2203, 2204, 2205, 2050, 2086, 1030, 2051, 2080, 2087, 107, 2139, 1031, 2081, 2143, 776, 2082, 2215, 2089, 2091, 2092, 2592, 2093, 2097, 2098, 782, 2100, 2102, 1032, 2103, 2104, 2108, 2109, 2118, 790, 2374, 2375, 2376, 2111, 2112, 2380, 2113, 2382, 2383, 2114, 2385, 2221, 2387, 2222, 2119, 2223, 2120, 2225, 1033, 2122, 2227, 2123, 2228, 2125, 2126, 2156, 1034, 109, 2128, 2234, 2235, 2135, 2137, 2141, 2145, 2157, 2158, 2536, 2162, 2201, 2206, 2207, 2210, 2216, 2232, 2242, 2230, 2243, 2231, 2236, 2592, 2246, 2237, 2238, 2277, 2248, 2247, 2250, 2251, 2422, 2252, 2279, 2281, 2284, 1035, 269, 2286, 827, 2287, 2288, 829, 830, 1036, 2292, 2293, -1076, 2294, 2295, 94, 95, 2301, 834, 2296, 2297, 2302, 114, 837, 2303, 2304, 2305, 2306, 115, 2310, 2311, 104, 846, 2312, 2319, 2322, 2330, 2333, 270, 2336, 2337, 2339, 2342, 2343, 2344, 2347, 2353, 2357, 2373, 2280, 1037, 2418, 2419, 2636, 2426, 2427, 2428, 2430, 2660, 2432, 2434, 1038, 2435, 2437, 2443, 2452, 106, 2456, 2463, 2469, 2473, 2476, 1294, 2483, 2490, 2501, 1039, 2140, 2523, 2530, 2532, 2534, 2535, 2597, 2538, 2568, 2574, 2577, 2582, 779, 2595, 2596, 2598, 2606, 2616, 2249, 271, 2624, 2629, 2589, 2638, 1156, 2639, 2640, 887, 888, 889, 2644, 2647, 2669, 2164, 107, 2657, 2658, 2345, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 2661, 2673, 2674, 2493, 2278, 2677, 2679, 1574, 2637, 2633, 2351, 2496, 1091, 0, 0, 0, 1027, 0, 0, 0, 109, 0, 0, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 0, 0, 0, 662, 2371, 2521, 0, 0, 0, 0, 0, 2377, 0, 0, 2381, 0, 0, 0, 0, 2386, 0, 0, 2388, 2389, 2390, 2391, 2392, 2393, 1342, 2395, 2396, 2397, 1342, 2399, 2400, 2401, 2402, 1342, 2404, 2405, 2406, 2407, 2408, 0, 2410, 114, 1342, 2414, 2415, 0, 0, 115, 0, 0, 0, 0, 740, 0, 0, 0, 0, 0, 0, 0, 2421, 0, 0, 0, 2423, 0, 0, 0, 2425, 0, 0, 0, 2349, 2429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2379, 770, 0, 0, 0, 1150, 0, 0, 0, 0, 2444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1171, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 0, 0, 0, 0, 0, 1181, 1182, 1183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2485, 0, 0, 0, 2487, 0, 0, 0, 0, 823, 0, 0, 0, 0, 2488, 0, 0, 0, 831, 0, 2492, 832, 0, 0, 833, 0, 0, 2495, 835, 0, 0, 0, 0, 1342, 0, 2500, 0, 0, 2504, 2505, 0, 1342, 0, 1267, 0, 1342, 0, 0, 2514, 2515, 1342, 2517, 2518, 2519, 2520, 0, 1278, 2522, 0, 0, 0, 2525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2533, 0, 0, 0, 1690, 0, 2537, 0, 0, 0, 0, 0, 0, 0, 0, 1328, 1700, 0, 0, 2543, 0, 0, 0, 2481, 885, 94, 95, 1152, 0, 0, 0, 0, 0, 0, 1761, 1762, 0, 0, 1153, 0, 0, 104, 0, 0, 0, 1405, 0, 0, 2417, 0, 0, 0, 0, 0, 2554, 0, 0, 0, 0, 0, 2559, 0, 2561, 1029, 1154, 0, 0, 2565, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 1031, 0, 1342, 2572, 0, 0, 0, 0, 0, 0, 0, 0, 1342, 2581, 0, 0, 1032, 2585, 1463, 2611, 1155, 0, 0, 0, 0, 0, 0, 0, 1469, 0, 0, 1472, 0, 0, 0, 2603, 0, 0, 0, 0, 0, 1033, 0, 1065, 107, 0, 0, 0, 0, 1034, 1071, 0, 0, 0, 0, 0, 0, 2614, 0, 0, 0, 0, 0, 2619, 0, 2621, 0, 0, 0, 0, 0, 0, 2625, 0, 0, 2627, 0, 0, 0, 0, 2630, 0, 2557, 0, 0, 0, 0, 1035, 0, 2563, 0, 0, 0, 0, 0, 1036, 109, 0, 0, 0, 0, 0, 2641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1342, 0, 0, 1342, 2650, 0, 2651, 0, 1342, 2653, 0, 0, 0, 0, 0, 0, 0, 1037, 0, 0, 2659, 0, 0, 1550, 0, 0, 0, 0, 1038, 2668, 0, 0, 2671, 0, 0, 0, 0, 0, 0, 0, 0, 115, 1166, 1039, 0, 0, 0, 0, 1167, 0, 0, 0, 0, 1156, 0, 1157, 1342, 1582, 1342, 2527, 0, 0, 0, 2531, 493, 0, 0, 0, 0, 0, 1590, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1619, 1186, 2646, 0, 0, 1626, 1190, 0, 0, 1193, 0, 0, 0, 0, 0, 1158, 0, 0, 1201, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2663, 0, 0, 2666, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 0, 107, 1674, 1675, 1676, 0, 0, 0, 0, 0, 0, 0, 1678, 1679, 1680, 0, 0, 0, 1691, 1692, 1693, 0, 0, 1694, 1695, 0, 1697, 1698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 109, 0, 0, 1770, 1771, 0, 2040, 1773, 1774, 0, 0, 0, 0, 0, 2046, 2047, 0, 1777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2083, 2084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2094, 2095, 0, 0, 0, 1797, 0, 0, 0, 0, 0, 2105, 2106, 0, 0, 0, 0, 0, 114, 0, 0, 2115, 2116, 0, 115, 0, 0, 2121, 2656, 0, 0, 1828, 0, 0, 1830, 0, 0, 2124, 0, 2245, 0, 0, 0, 1846, 1848, 0, 0, 0, 0, 0, 1851, 0, 0, 0, 2253, 0, 2254, 1853, 2255, 0, 0, 0, 2257, 0, 0, 2259, 0, 2260, 0, 0, 0, 2262, 0, 2263, 0, 2264, 0, 0, 0, 2266, 0, 2267, 0, 0, 0, 2270, 0, 0, 2272, 0, 2273, 0, 0, 2275, 0, 0, 1891, 0, 0, 1894, 1895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1903, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 1545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1589, 0, 0, 2346, 0, 0, 2350, 0, 0, 0, 0, 2354, 1958, 1959, 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1968, 0, 0, 0, 0, 0, 2370, 0, 0, 0, 0, 0, 0, 0, 617, 618, 0, 0, 0, 0, 0, 0, 0, 1977, 0, 0, 0, 1981, 0, 0, 1983, 1985, 1987, 1989, 1991, 0, 0, 1994, 0, 0, 1996, 0, 0, 1998, 2000, 2002, 2004, 2006, 2008, 0, 2010, 2011, 0, 0, 0, 2014, 2015, 2017, 0, 2019, 2020, 0, 0, 0, 0, 2022, 2023, 0, 619, 0, 0, 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, 621, 0, 622, 0, 0, 2283, 2433, 623, 2031, 0, 624, 0, 0, 0, 0, 2285, 625, 0, 0, 2289, 2290, 2039, 0, 0, 0, 0, 626, 0, 2298, 2299, 0, 2042, 627, 0, 2439, 0, 0, 2307, 2308, 0, 0, 0, 0, 2313, 0, 0, 0, 0, 0, 0, 0, 0, 628, 2323, 2324, 0, 322, 0, 0, 0, 0, 0, 0, 323, 2334, 2335, 0, 0, 0, 0, 0, 0, 0, 629, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 2340, 0, 2341, 0, 0, 630, 0, 0, 0, 0, 104, 0, 0, 0, 631, 632, 0, 0, 0, 2127, 0, 0, 0, 2130, 0, 0, 2133, 0, 0, 2482, 1843, 0, 0, 0, 0, 633, 0, 2138, 0, 0, 2142, 0, 0, 0, 0, 106, 0, 0, 0, 2489, 0, 0, 0, 0, 0, 0, 0, 634, 0, 2494, 0, 0, 0, 0, 0, 2497, 0, 2160, 0, 0, 635, 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 1892, 638, 107, 0, 0, 0, 1898, 639, 0, 0, 0, 0, 0, 0, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, 0, 0, 0, 2200, 0, 0, 0, 0, 0, 0, 0, 0, 642, 643, 0, 644, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2555, 0, 0, 2446, 0, 0, 0, 0, 1932, 0, 0, 0, 0, 2455, 1937, 645, 0, 0, 2567, 0, 0, 0, 2457, 0, 0, 0, 0, 0, 324, 0, 325, 2466, 0, 0, 0, 0, 0, 0, 2468, 114, 0, 0, 0, 2241, 0, 115, 1961, 0, 0, 2472, 0, 0, 0, 0, 1967, 2475, 0, 0, 2477, 0, 0, 2478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2612, 0, 2613, 0, 2615, 0, 2617, 1982, 2618, 0, 2620, 0, 0, 0, 1993, 0, 0, 0, 0, 0, 2269, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 2282, 0, 0, 0, 0, 2643, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 0, 0, 0, 0, 2314, 2315, 2316, 2317, 2318, 2544, 2320, 2321, 2672, 2546, 0, 2325, 2326, 2327, 2328, 2329, 2547, 2331, 2332, 0, 0, 0, 2550, 0, 0, 0, 2552, 0, 0, 2553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 578, 104, 0, 0, 0, 0, 0, 2348, 0, 0, 2352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2129, 2368, 0, 0, 2372, 579, 0, 0, 0, 0, 0, 2378, 0, 0, 0, 0, 2384, 0, 0, 0, 2144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 2165, 0, 2167, 0, 0, 0, 0, 580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2172, 0, 2174, 0, 0, 2175, 0, 2177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2436, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2208, 0, 0, 2212, 2213, 0, 0, 0, 0, 0, 0, 0, 2217, 0, 2445, 0, 0, 2447, 2448, 2449, 2450, 2451, 0, 2453, 2454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2458, 2459, 2460, 2461, 2462, 0, 2464, 2465, 2224, 2467, 0, 0, 0, 0, 0, 115, 0, 0, 0, 2470, 2471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2474, 0, 2239, 2240, 0, 0, 0, 0, 0, 0, 2480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2256, 0, 0, 104, 0, 0, 0, 0, 0, 2261, 0, 0, 0, 0, 0, 2498, 581, 2265, 0, 0, 0, 105, 2268, 0, 0, 0, 2271, 2510, 0, 0, 0, 2274, 0, 0, 2276, 0, 0, 0, 106, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 2542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 2545, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 2548, 0, 2549, 0, 0, 0, 2551, 0, 0, 0, 0, 0, 0, 0, 2556, 2558, 0, 2560, 0, 0, 0, 2562, 2564, 0, 0, 0, 2566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 2586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2605, 0, 0, 0, 0, 110, 0, 0, 0, 2607, 0, 0, 2608, 111, 106, 2609, 104, 2610, 0, 112, 113, 0, 0, 0, 0, 114, 0, 0, 465, 0, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 466, 467, 0, 0, 468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2645, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, 2654, 0, 107, 0, 0, 0, 0, 0, 116, 0, 0, 0, 2662, 0, 0, 2665, 0, 109, 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 109, 0, 0, 146, 0, 0, 0, 147, 148, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 0, 0, 115, 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, 0, 0, 2479, 0, 0, 0, 0, 0, 0, 2484, 0, 0, 472, 2486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, 2491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 486, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 473, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 104, 474, 1208, 1209, 1210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2576, 0, 1211, 1212, 0, 104, 1213, 0, 0, 0, 0, 0, 482, 1214, 0, 0, 1215, 0, 0, 0, 1216, 0, 0, 0, 0, 0, 0, 0, 1217, 1218, 0, 0, 0, 104, 0, 0, 1219, 0, 0, 0, 1266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 1220, 1221, 0, 1222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2632, 0, 0, 1223, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2642, 0, 0, 0, 0, 1224, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1226, 0, 2664, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2675, 0, 0, 2676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 0, 115, 0, 0, 0, 0, 1227, 0, 0, 0, 0, 0, 0, 1228, 1229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1230, 0, 0, 0, 0, 115, 0, 0, 0, 0, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 0, 1232, 0, 1233, 483, 0, 0, 0, 0, 0, 0, 0, 0, 1234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1235, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 1236, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 5, 0, 6, 7, 8, 0, 0, 0, 0, 0, 170, 0, 9, 171, 0, 0, 0, 0, 0, 10, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 172, 0, 173, 174, 175, 0, 0, 0, 0, 0, 0, 0, 176, 0, 177, 0, 0, 0, 0, 178, 14, 179, 0, 180, 0, 0, 0, 0, 181, 0, 182, 0, 15, 0, 0, 0, 16, 0, 0, 17, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0, 20, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 21, 0, 0, 0, 22, 23, 24, 0, 0, 25, 26, 185, 186, 0, 0, 187, 0, 0, 918, 188, 0, 0, 27, 0, 919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 30, 0, 0, 0, 0, 189, 190, 0, 0, 191, 0, 0, 0, 31, 0, 0, 0, 0, 192, 0, 1302, 0, 0, 32, 0, 0, 33, 0, 34, 0, 35, 0, 0, 193, 194, 36, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 197, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 42, 0, 0, 0, 0, 198, 43, 0, 0, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 200, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 202, 0, 0, 46, 0, 0, 203, 0, 204, 47, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 0, 0, 0, 0, 0, 205, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 1303 }; static const yytype_int16 yycheck[] = { 10, 636, 45, 205, 1584, 5, 1586, 4, 631, 632, 4, 5, 5, 4, 3, 4, 831, 832, 833, 29, 5, 5, 4, 6, 4, 35, 3, 4, 5, 32, 43, 4, 3, 4, 44, 912, 35, 47, 915, 35, 50, 4, 5, 4, 54, 34, 1085, 57, 1087, 4, 60, 5, 0, 63, 80, 932, 5, 67, 62, 27, 64, 71, 27, 34, 1384, 941, 76, 64, 42, 64, 885, 27, 54, 1112, 1113, 1114, 54, 37, 46, 3, 4, 49, 13, 57, 126, 32, 96, 6, 98, 99, 100, 101, 60, 144, 89, 3, 4, 48, 127, 3, 4, 64, 17, 86, 97, 79, 31, 117, 144, 219, 103, 3, 4, 138, 17, 83, 113, 275, 5, 113, 29, 160, 64, 86, 98, 21, 24, 25, 85, 59, 188, 114, 100, 131, 206, 64, 125, 111, 1441, 64, 114, 164, 152, 14, 3, 4, 97, 107, 55, 172, 113, 4, 85, 78, 125, 412, 81, 140, 137, 3, 4, 212, 172, 273, 89, 139, 140, 177, 425, 132, 21, 196, 97, 171, 178, 3, 4, 224, 129, 21, 17, 3, 4, 241, 114, 59, 3, 4, 59, 3, 4, 217, 218, 96, 151, 114, 238, 95, 163, 250, 197, 110, 231, 197, 230, 21, 203, 204, 4, 203, 204, 64, 5, 21, 250, 188, 59, 256, 151, 244, 194, 151, 21, 295, 234, 95, 54, 209, 202, 189, 865, 209, 3, 4, 197, 278, 178, 288, 248, 249, 203, 204, 4, 269, 4, 170, 5, 1567, 20, 262, 260, 3, 4, 184, 219, 14, 15, 237, 268, 269, 113, 271, 272, 219, 274, 4, 12, 221, 177, 272, 179, 180, 181, 19, 284, 183, 260, 23, 282, 188, 279, 291, 292, 279, 30, 259, 260, 212, 237, 286, 205, 276, 286, 202, 283, 295, 124, 189, 292, 292, 59, 311, 312, 313, 64, 315, 4, 5, 302, 319, 320, 302, 283, 220, 185, 61, 277, 113, 295, 244, 330, 331, 277, 286, 183, 272, 336, 275, 27, 292, 965, 341, 342, 263, 285, 231, 331, 4, 335, 349, 282, 335, 339, 340, 197, 339, 340, 982, 331, 27, 203, 204, 239, 113, 364, 365, 366, 331, 368, 283, 58, 6, 271, 373, 374, 375, 64, 377, 205, 284, 37, 1186, 335, 341, 113, 338, 339, 340, 1193, 283, 231, 209, 252, 254, 394, 293, 293, 201, 398, 231, 1013, 283, 263, 403, 404, 405, 406, 407, 408, 273, 410, 197, 219, 413, 414, 662, 331, 203, 204, 155, 156, 157, 158, 159, 160, 231, 426, 163, 164, 165, 166, 1044, 296, 231, 295, 123, 185, 186, 336, 337, 273, 183, 231, 286, 293, 12, 188, 197, 136, 283, 107, 32, 1319, 203, 204, 1322, 144, 284, 219, 101, 61, 149, 45, 296, 16, 283, 228, 96, 197, 151, 39, 40, 163, 162, 203, 204, 64, 477, 478, 479, 480, 1347, 37, 225, 51, 3, 4, 336, 337, 72, 119, 277, 335, 17, 162, 495, 339, 340, 180, 224, 286, 102, 69, 4, 30, 254, 248, 1373, 3, 4, 246, 247, 411, 201, 263, 264, 3, 4, 0, 268, 30, 5, 3, 4, 524, 558, 155, 1393, 219, 30, 76, 98, 189, 221, 270, 27, 286, 225, 2591, 227, 188, 183, 231, 790, 5, 112, 295, 34, 115, 335, 37, 293, 107, 339, 340, 555, 37, 286, 5, 54, 127, 144, 250, 231, 597, 259, 92, 14, 15, 257, 37, 307, 308, 309, 14, 15, 57, 3, 4, 4, 237, 2634, 273, 616, 273, 335, 4, 275, 835, 339, 340, 591, 4, 241, 336, 337, 165, 166, 27, 182, 12, 81, 501, 5, 1229, 273, 335, 5, 189, 59, 339, 340, 59, 5, 614, 1240, 5, 97, 247, 59, 107, 167, 3, 4, 193, 17, 107, 111, 229, 153, 630, 5, 158, 633, 189, 534, 3, 4, 125, 191, 107, 242, 243, 331, 4, 5, 156, 4, 5, 250, 17, 651, 652, 653, 654, 156, 54, 657, 5, 659, 4, 661, 245, 663, 114, 63, 2236, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 241, 206, 280, 731, 117, 255, 219, 189, 187, 17, 206, 14, 15, 189, 59, 59, 5, 41, 296, 209, 241, 283, 20, 21, 22, 246, 231, 189, 723, 724, 253, 726, 219, 728, 729, 231, 259, 333, 334, 163, 14, 15, 5, 185, 186, 64, 741, 742, 46, 47, 185, 186, 50, 748, 749, 53, 59, 5, 237, 59, 33, 85, 60, 4, 14, 15, 64, 143, 64, 114, 114, 766, 767, 768, 72, 73, 4, 5, 5, 198, 201, 260, 80, 81, 59, 59, 199, 14, 15, 1589, 785, 786, 787, 255, 789, 219, 791, 173, 793, 97, 45, 283, 61, 279, 123, 103, 59, 105, 106, 59, 108, 189, 254, 164, 114, 810, 209, 812, 263, 254, 111, 263, 264, 1065, 1686, 123, 268, 72, 263, 264, 149, 104, 59, 828, 3, 4, 5, 80, 61, 114, 59, 836, 5, 102, 1706, 840, 144, 120, 121, 122, 59, 14, 15, 295, 585, 128, 37, 852, 853, 1721, 295, 114, 1724, 187, 859, 860, 861, 275, 141, 167, 1732, 866, 5, 1735, 253, 148, 871, 59, 163, 102, 259, 1743, 185, 186, 1746, 880, 159, 1911, 1912, 1913, 918, 1753, 190, 237, 117, 114, 59, 87, 59, 144, 895, 274, 183, 225, 635, 114, 64, 188, 227, 640, 87, 185, 186, 59, 31, 334, 810, 64, 263, 263, 339, 219, 341, 221, 1785, 70, 107, 5, 226, 227, 4, 78, 114, 76, 219, 185, 186, 182, 26, 1800, 87, 239, 240, 5, 225, 4, 941, 103, 1190, 5, 97, 254, 250, 114, 68, 91, 275, 5, 185, 186, 263, 264, 5, 263, 4, 1826, 961, 248, 114, 5, 229, 107, 3, 4, 217, 218, 123, 275, 4, 277, 254, 86, 4, 242, 243, 4, 981, 230, 263, 263, 264, 289, 295, 291, 5, 990, 281, 144, 271, 297, 245, 1188, 1189, 4, 254, 110, 229, 5, 189, 1004, 263, 1006, 293, 263, 264, 1010, 1011, 1012, 95, 242, 243, 295, 185, 186, 167, 1020, 269, 254, 1023, 117, 1025, 4, 5, 331, 190, 22, 263, 264, 26, 4, 27, 268, 260, 190, 263, 295, 1041, 183, 1043, 4, 164, 296, 1047, 1048, 263, 5, 337, 400, 401, 46, 47, 4, 49, 50, 14, 15, 1061, 1062, 295, 4, 964, 1066, 1067, 60, 333, 334, 181, 1072, 52, 1074, 227, 263, 1077, 239, 1079, 72, 73, 103, 3, 4, 195, 254, 1892, 80, 4, 4, 83, 1125, 241, 5, 263, 264, 263, 250, 4, 268, 14, 15, 2396, 59, 333, 334, 200, 100, 88, 3, 4, 263, 105, 106, 4, 108, 236, 1118, 2412, 1120, 214, 5, 1123, 117, 1024, 245, 295, 3, 4, 4, 3, 4, 4, 4, 3, 4, 289, 1138, 291, 1140, 251, 1142, 1143, 1144, 1145, 59, 9, 1148, 1149, 14, 15, 3, 4, 133, 11, 22, 3, 4, 1406, 153, 12, 1967, 5, 57, 37, 164, 1167, 259, 190, 3, 4, 3, 4, 1174, 167, 28, 4, 1178, 1179, 1180, 47, 292, 4, 50, 172, 188, 53, 1993, 57, 2057, 1191, 302, 164, 1194, 59, 116, 4, 4, 2066, 191, 191, 1202, 5, 37, 1205, 37, 200, 2075, 2502, 2503, 57, 5, 2506, 80, 2508, 4, 191, 239, 2512, 2513, 214, 219, 1470, 2517, 2518, 64, 3, 4, 221, 185, 186, 2525, 2526, 226, 107, 12, 5, 19, 1138, 106, 116, 108, 3, 4, 5, 64, 1247, 240, 1249, 64, 987, 1252, 1253, 220, 5, 1256, 4, 237, 4, 41, 4, 1262, 191, 1264, 3, 4, 28, 85, 7, 8, 1271, 185, 186, 107, 2568, 107, 85, 2571, 3, 4, 5, 5, 2576, 276, 277, 4, 2580, 4, 3, 4, 4, 2585, 145, 75, 9, 10, 11, 1197, 254, 5, 82, 5, 5, 1040, 297, 97, 17, 263, 264, 1209, 92, 93, 268, 1050, 1214, 168, 189, 99, 2185, 172, 185, 186, 2189, 5, 17, 17, 4, 2194, 2390, 4, 4, 2393, 95, 2395, 5, 117, 22, 2399, 2400, 295, 254, 5, 85, 1344, 1345, 1346, 1347, 4, 341, 263, 264, 5, 134, 2415, 221, 2649, 85, 5, 2652, 4, 4, 47, 5, 5, 50, 1366, 5, 5, 150, 1370, 223, 5, 1373, 14, 15, 2669, 158, 4, 2672, 4, 4, 295, 12, 145, 5, 4, 12, 2681, 2682, 254, 1391, 1392, 1393, 4, 80, 4, 4, 179, 263, 264, 1401, 5, 2208, 1404, 1597, 258, 168, 5, 275, 4, 172, 2217, 161, 266, 267, 4, 1609, 5, 59, 4, 106, 277, 108, 1424, 249, 5, 4, 4, 1429, 5, 295, 5, 1433, 215, 1435, 1436, 5, 1438, 1439, 1440, 5, 1442, 4, 1343, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 2504, 37, 1457, 1458, 1459, 1460, 5, 223, 2268, 5, 2514, 2271, 1467, 1468, 2274, 5, 2276, 261, 1473, 1474, 1475, 5, 5, 1478, 1479, 4, 262, 4, 64, 3, 4, 5, 5, 7, 8, 1490, 1491, 273, 1493, 1494, 231, 5, 258, 1397, 5, 5, 1400, 5, 5, 4, 266, 267, 3, 4, 5, 1409, 7, 8, 103, 4, 4, 97, 1416, 5, 29, 2386, 302, 103, 5, 1423, 5, 107, 5, 2394, 5, 231, 41, 2398, 231, 231, 29, 221, 2403, 131, 37, 1540, 1541, 123, 1543, 103, 185, 186, 231, 1548, 1549, 103, 1551, 1552, 1553, 5, 1555, 1556, 205, 1558, 231, 235, 1561, 1562, 144, 74, 37, 205, 59, 5, 3, 4, 5, 82, 7, 8, 2624, 4, 205, 1578, 160, 2629, 5, 1829, 5, 205, 1585, 4, 4, 342, 5, 5, 85, 5, 5, 1594, 1595, 1843, 1844, 4, 107, 1847, 5, 5, 1339, 1604, 1852, 107, 1854, 4, 190, 1610, 12, 5, 5, 254, 4, 110, 5, 5, 111, 4, 4, 114, 263, 264, 135, 5, 5, 2677, 4, 2679, 5, 1368, 5, 4, 12, 1372, 6, 342, 5, 4, 6, 342, 1643, 4, 4, 227, 342, 342, 1548, 4, 1898, 342, 342, 342, 295, 4, 51, 239, 151, 1396, 4, 4, 1663, 5, 0, 5, 1667, 231, 250, 131, 1407, 4, 1673, 231, 69, 231, 187, 1414, 1415, 231, 231, 176, 231, 178, 179, 180, 181, 163, 1425, 1937, 4, 86, 203, 204, 187, 277, 239, 191, 4, 4, 211, 201, 213, 98, 4, 4, 261, 289, 5, 291, 292, 5, 207, 5, 5, 5, 5, 112, 4, 4, 115, 1621, 1622, 1623, 1624, 1625, 237, 5, 1628, 224, 225, 1631, 127, 4, 1634, 1635, 1636, 1637, 1638, 1639, 4, 234, 1642, 4, 237, 5, 5, 1647, 1648, 331, 5, 1651, 299, 231, 2621, 4, 231, 1657, 4, 231, 4, 4, 4, 4, 299, 4, 4, 260, 5, 219, 263, 219, 219, 219, 169, 219, 271, 5, 5, 1780, 1781, 274, 1783, 5, 1785, 5, 4, 6, 5, 5, 4, 302, 4, 288, 4, 6, 3, 4, 4, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 5, 5, 4, 19, 5, 5, 4, 261, 5, 5, 4, 4, 1822, 5, 1824, 5, 1826, 4, 261, 5, 36, 1831, 5, 5, 4, 4, 4, 12, 5, 1575, 5, 5, 1842, 4, 6, 5, 4, 4, 54, 5, 5, 5, 4, 261, 5, 4, 295, 5, 5, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 5, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 89, 1882, 4, 1884, 1885, 1886, 4, 4, 97, 5, 5, 4, 99, 1793, 103, 5, 1796, 392, 5, 1900, 5, 5, 5, 2529, 5, 4, 4, 402, 5, 5, 119, 5, 5, 4, 4, 4, 411, 2165, 2166, 2167, 5, 5, 2170, 5, 2172, 2173, 5, 2175, 1929, 2177, 1931, 4, 1933, 5, 1935, 144, 4, 1938, 4, 1940, 4, 4, 4, 152, 151, 5, 1947, 1948, 5, 5, 5, 5, 5, 4, 6, 5, 5, 4, 4, 4, 4, 4, 1963, 5, 1965, 5, 4, 2593, 1969, 5, 4, 4, 1973, 5, 5, 5, 2224, 5, 5, 4, 4, 190, 189, 5, 479, 5, 5, 482, 483, 198, 4, 4, 275, 5, 5, 3, 4, 4, 493, 5, 5, 4, 209, 498, 5, 5, 5, 5, 215, 4, 4, 19, 507, 5, 4, 4, 4, 4, 225, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2030, 239, 4, 4, 342, 5, 5, 4, 4, 2642, 5, 5, 250, 5, 5, 5, 4, 54, 4, 4, 4, 4, 4, 911, 4, 4, 4, 265, 1794, 5, 5, 5, 5, 4, 6, 5, 4, 4, 4, 4, 399, 5, 5, 4, 4, 4, 1975, 283, 4, 4, 2527, 5, 275, 5, 4, 579, 580, 581, 4, 4, 4, 1827, 99, 5, 5, 2128, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 5, 5, 5, 2374, 2027, 4, 4, 1159, 2593, 2589, 2134, 2382, 694, -1, -1, -1, 634, -1, -1, -1, 151, -1, -1, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, -1, -1, -1, 273, 2161, 2409, -1, -1, -1, -1, -1, 2168, -1, -1, 2171, -1, -1, -1, -1, 2176, -1, -1, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, -1, 2201, 209, 2203, 2204, 2205, -1, -1, 215, -1, -1, -1, -1, 326, -1, -1, -1, -1, -1, -1, -1, 2221, -1, -1, -1, 2225, -1, -1, -1, 2229, -1, -1, -1, 2132, 2234, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2159, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2169, 384, -1, -1, -1, 769, -1, -1, -1, -1, 2280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 788, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, -1, -1, -1, -1, 824, 825, 826, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2353, -1, -1, -1, 2357, -1, -1, -1, -1, 475, -1, -1, -1, -1, 2367, -1, -1, -1, 484, -1, 2373, 487, -1, -1, 490, -1, -1, 2380, 494, -1, -1, -1, -1, 2386, -1, 2388, -1, -1, 2391, 2392, -1, 2394, -1, 890, -1, 2398, -1, -1, 2401, 2402, 2403, 2404, 2405, 2406, 2407, -1, 900, 2410, -1, -1, -1, 2414, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2425, -1, -1, -1, 1287, -1, 2431, -1, -1, -1, -1, -1, -1, -1, -1, 931, 1299, -1, -1, 2444, -1, -1, -1, 2347, 562, 3, 4, 53, -1, -1, -1, -1, -1, -1, 1317, 1318, -1, -1, 64, -1, -1, 19, -1, -1, -1, 964, -1, -1, 2209, -1, -1, -1, -1, -1, 2479, -1, -1, -1, -1, -1, 2485, -1, 2487, 89, 90, -1, -1, 2492, -1, -1, -1, 97, -1, -1, -1, -1, -1, 103, -1, 2504, 2505, -1, -1, -1, -1, -1, -1, -1, -1, 2514, 2515, -1, -1, 119, 2519, 1014, 2554, 123, -1, -1, -1, -1, -1, -1, -1, 1024, -1, -1, 1027, -1, -1, -1, 2537, -1, -1, -1, -1, -1, 144, -1, 658, 99, -1, -1, -1, -1, 152, 665, -1, -1, -1, -1, -1, -1, 2559, -1, -1, -1, -1, -1, 2565, -1, 2567, -1, -1, -1, -1, -1, -1, 2574, -1, -1, 2577, -1, -1, -1, -1, 2582, -1, 2483, -1, -1, -1, -1, 190, -1, 2490, -1, -1, -1, -1, -1, 198, 151, -1, -1, -1, -1, -1, 2604, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2621, -1, -1, 2624, 2625, -1, 2627, -1, 2629, 2630, -1, -1, -1, -1, -1, -1, -1, 239, -1, -1, 2641, -1, -1, 1138, -1, -1, -1, -1, 250, 2650, -1, -1, 2653, -1, -1, -1, -1, -1, -1, -1, -1, 215, 776, 265, -1, -1, -1, -1, 782, -1, -1, -1, -1, 275, -1, 277, 2677, 1172, 2679, 2416, -1, -1, -1, 2420, 4, -1, -1, -1, -1, -1, 1185, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1209, 829, 2616, -1, -1, 1214, 834, -1, -1, 837, -1, -1, -1, -1, -1, 331, -1, -1, 846, -1, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2644, -1, -1, 2647, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 99, 1272, 1273, 1274, -1, -1, -1, -1, -1, -1, -1, 1282, 1283, 1284, -1, -1, -1, 1288, 1289, 1290, -1, -1, 1293, 1294, -1, 1296, 1297, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 939, -1, -1, -1, -1, -1, 151, -1, -1, 1326, 1327, -1, 1696, 1330, 1331, -1, -1, -1, -1, -1, 1704, 1705, -1, 1343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1719, 1720, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1730, 1731, -1, -1, -1, 1371, -1, -1, -1, -1, -1, 1741, 1742, -1, -1, -1, -1, -1, 209, -1, -1, 1751, 1752, -1, 215, -1, -1, 1757, 2636, -1, -1, 1397, -1, -1, 1400, -1, -1, 1767, -1, 1968, -1, -1, -1, 1409, 1410, -1, -1, -1, -1, -1, 1416, -1, -1, -1, 1983, -1, 1985, 1423, 1987, -1, -1, -1, 1991, -1, -1, 1994, -1, 1996, -1, -1, -1, 2000, -1, 2002, -1, 2004, -1, -1, -1, 2008, -1, 2010, -1, -1, -1, 2014, -1, -1, 2017, -1, 2019, -1, -1, 2022, -1, -1, 1462, -1, -1, 1465, 1466, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1476, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1150, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1548, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1183, -1, -1, 2130, -1, -1, 2133, -1, -1, -1, -1, 2138, 1576, 1577, -1, 2142, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1591, -1, -1, -1, -1, -1, 2160, -1, -1, -1, -1, -1, -1, -1, 4, 5, -1, -1, -1, -1, -1, -1, -1, 1614, -1, -1, -1, 1618, -1, -1, 1621, 1622, 1623, 1624, 1625, -1, -1, 1628, -1, -1, 1631, -1, -1, 1634, 1635, 1636, 1637, 1638, 1639, -1, 1641, 1642, -1, -1, -1, 1646, 1647, 1648, -1, 1650, 1651, -1, -1, -1, -1, 1656, 1657, -1, 58, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, 71, -1, 73, -1, -1, 2041, 2241, 78, 1677, -1, 81, -1, -1, -1, -1, 2051, 87, -1, -1, 2055, 2056, 1690, -1, -1, -1, -1, 97, -1, 2064, 2065, -1, 1700, 103, -1, 2269, -1, -1, 2073, 2074, -1, -1, -1, -1, 2079, -1, -1, -1, -1, -1, -1, -1, -1, 123, 2089, 2090, -1, 16, -1, -1, -1, -1, -1, -1, 23, 2100, 2101, -1, -1, -1, -1, -1, -1, -1, 144, -1, 2111, -1, -1, -1, -1, -1, -1, -1, -1, 2120, -1, 2122, -1, -1, 160, -1, -1, -1, -1, 19, -1, -1, -1, 169, 170, -1, -1, -1, 1772, -1, -1, -1, 1779, -1, -1, 1782, -1, -1, 2348, 1405, -1, -1, -1, -1, 190, -1, 1793, -1, -1, 1796, -1, -1, -1, -1, 54, -1, -1, -1, 2368, -1, -1, -1, -1, -1, -1, -1, 212, -1, 2378, -1, -1, -1, -1, -1, 2384, -1, 1823, -1, -1, 225, -1, 227, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 239, -1, -1, -1, 1463, 244, 99, -1, -1, -1, 1469, 250, -1, -1, -1, -1, -1, -1, 257, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 275, -1, -1, -1, 1880, -1, -1, -1, -1, -1, -1, -1, -1, 288, 289, -1, 291, -1, -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2480, -1, -1, 2284, -1, -1, -1, -1, 1544, -1, -1, -1, -1, 2294, 1550, 331, -1, -1, 2498, -1, -1, -1, 2303, -1, -1, -1, -1, -1, 233, -1, 235, 2312, -1, -1, -1, -1, -1, -1, 2319, 209, -1, -1, -1, 1960, -1, 215, 1582, -1, -1, 2330, -1, -1, -1, -1, 1590, 2336, -1, -1, 2339, -1, -1, 2342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2556, -1, 2558, -1, 2560, -1, 2562, 1619, 2564, -1, 2566, -1, -1, -1, 1626, -1, -1, -1, -1, -1, 2013, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, 2040, -1, -1, -1, -1, 2611, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, -1, -1, -1, 2080, 2081, 2082, 2083, 2084, 2452, 2086, 2087, 2654, 2456, -1, 2091, 2092, 2093, 2094, 2095, 2463, 2097, 2098, -1, -1, -1, 2469, -1, -1, -1, 2473, -1, -1, 2476, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, -1, -1, -1, -1, -1, 2132, -1, -1, 2135, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2145, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1777, 2159, -1, -1, 2162, 56, -1, -1, -1, -1, -1, 2169, -1, -1, -1, -1, 2174, -1, -1, -1, 1797, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 99, -1, -1, 1828, -1, 1830, -1, -1, -1, -1, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1846, -1, 1848, -1, -1, 1851, -1, 1853, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2251, -1, -1, -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1891, -1, -1, 1894, 1895, -1, -1, -1, -1, -1, -1, -1, 1903, -1, 2283, -1, -1, 2286, 2287, 2288, 2289, 2290, -1, 2292, 2293, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2304, 2305, 2306, 2307, 2308, -1, 2310, 2311, 1934, 2313, -1, -1, -1, -1, -1, 215, -1, -1, -1, 2323, 2324, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2334, -1, 1958, 1959, -1, -1, -1, -1, -1, -1, 2347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1989, -1, -1, 19, -1, -1, -1, -1, -1, 1998, -1, -1, -1, -1, -1, 2385, 279, 2006, -1, -1, -1, 37, 2011, -1, -1, -1, 2015, 2397, -1, -1, -1, 2020, -1, -1, 2023, -1, -1, -1, 54, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, 2455, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, 2466, -1, 2468, -1, -1, -1, 2472, -1, -1, -1, -1, -1, -1, -1, 2483, 2484, -1, 2486, -1, -1, -1, 2490, 2491, -1, -1, -1, 2495, -1, -1, -1, -1, -1, -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, 2520, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2538, -1, -1, -1, -1, 189, -1, -1, -1, 2544, -1, -1, 2547, 197, 54, 2550, 19, 2552, -1, 203, 204, -1, -1, -1, -1, 209, -1, -1, 31, -1, -1, 215, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 99, 63, 64, -1, -1, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2616, -1, -1, -1, -1, -1, -1, -1, 89, -1, -1, -1, -1, -1, -1, -1, 2632, -1, 99, -1, -1, -1, -1, -1, 286, -1, -1, -1, 2644, -1, -1, 2647, -1, 151, -1, -1, -1, -1, -1, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, 151, -1, -1, 335, -1, -1, -1, 339, 340, -1, -1, -1, -1, 164, -1, -1, -1, -1, -1, -1, -1, 209, -1, -1, -1, -1, -1, 215, -1, -1, -1, 182, -1, -1, -1, -1, -1, -1, -1, -1, 2345, -1, -1, -1, -1, -1, -1, 2352, -1, -1, 201, 2356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, -1, -1, 2372, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 270, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 262, -1, -1, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 19, 331, 20, 21, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2510, -1, 46, 47, -1, 19, 50, -1, -1, -1, -1, -1, 57, 57, -1, -1, 60, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, 72, 73, -1, -1, -1, 19, -1, -1, 80, -1, -1, -1, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, -1, 105, 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2586, -1, -1, 123, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2605, -1, -1, -1, -1, 144, -1, -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, -1, -1, 167, -1, -1, -1, -1, -1, -1, -1, -1, -1, 177, -1, 2645, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2662, -1, -1, 2665, -1, -1, -1, -1, -1, -1, -1, -1, -1, 151, -1, -1, -1, -1, 215, -1, -1, -1, -1, 219, -1, -1, -1, -1, -1, -1, 226, 227, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 240, -1, -1, -1, -1, 215, -1, -1, -1, -1, 250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, -1, 275, -1, 277, 279, -1, -1, -1, -1, -1, -1, -1, -1, 287, -1, -1, -1, -1, -1, -1, -1, -1, -1, 297, -1, -1, -1, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, 331, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 38, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, 62, 63, -1, 65, 66, 67, -1, -1, -1, -1, -1, 38, -1, 75, 41, -1, -1, -1, -1, -1, 82, -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, 93, 94, -1, -1, -1, 63, -1, 65, 66, 67, -1, -1, -1, -1, -1, -1, -1, 75, -1, 77, -1, -1, -1, -1, 82, 118, 84, -1, 86, -1, -1, -1, -1, 91, -1, 93, -1, 130, -1, -1, -1, 134, -1, -1, 137, -1, -1, -1, -1, 142, -1, 144, -1, -1, -1, -1, -1, 150, -1, 117, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134, 170, -1, -1, -1, 174, 175, 176, -1, -1, 179, 180, 146, 147, -1, -1, 150, -1, -1, 151, 154, -1, -1, 192, -1, 157, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 207, 208, 209, -1, -1, -1, -1, 179, 180, -1, -1, 183, -1, -1, -1, 222, -1, -1, -1, -1, 192, -1, 157, -1, -1, 232, -1, -1, 235, -1, 237, -1, 239, -1, -1, 207, 208, 244, -1, -1, -1, -1, -1, -1, 216, -1, -1, -1, -1, -1, 257, -1, -1, -1, -1, 262, -1, -1, -1, -1, -1, -1, -1, -1, -1, 237, -1, 239, -1, -1, -1, 278, 279, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 290, -1, 292, -1, -1, -1, -1, 262, 298, -1, -1, 301, 302, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 278, 279, -1, -1, -1, -1, -1, -1, -1, 287, -1, -1, -1, -1, -1, -1, 294, -1, -1, 332, -1, -1, 300, -1, 302, 338, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, -1, -1, -1, 338, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { 0, 38, 41, 57, 62, 63, 65, 66, 67, 75, 82, 84, 93, 94, 118, 130, 134, 137, 142, 144, 150, 170, 174, 175, 176, 179, 180, 192, 207, 208, 209, 222, 232, 235, 237, 239, 244, 257, 262, 278, 279, 290, 292, 298, 301, 302, 332, 338, 344, 64, 12, 51, 69, 98, 112, 115, 127, 283, 377, 183, 188, 225, 248, 293, 337, 382, 275, 4, 37, 107, 189, 237, 389, 28, 145, 168, 172, 223, 258, 266, 267, 359, 391, 31, 64, 78, 81, 89, 97, 170, 212, 244, 331, 392, 3, 4, 37, 57, 107, 189, 279, 345, 396, 4, 19, 37, 54, 99, 113, 151, 189, 197, 203, 204, 209, 215, 286, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 335, 339, 340, 347, 356, 357, 358, 398, 347, 29, 41, 74, 82, 135, 187, 203, 204, 211, 213, 237, 302, 346, 137, 399, 38, 41, 63, 65, 66, 67, 75, 77, 82, 84, 86, 91, 93, 117, 134, 146, 147, 150, 154, 179, 180, 183, 192, 207, 208, 216, 237, 239, 262, 278, 279, 287, 294, 300, 302, 338, 400, 81, 97, 443, 19, 41, 75, 82, 92, 93, 99, 117, 134, 150, 158, 179, 215, 262, 273, 302, 446, 347, 86, 110, 181, 195, 251, 292, 302, 452, 26, 117, 153, 200, 214, 455, 224, 472, 5, 64, 86, 132, 292, 338, 347, 473, 5, 55, 220, 293, 489, 62, 64, 178, 282, 508, 64, 198, 334, 339, 341, 509, 36, 189, 225, 283, 345, 356, 358, 510, 5, 292, 302, 347, 513, 68, 164, 236, 245, 514, 489, 59, 273, 296, 520, 189, 283, 345, 521, 26, 117, 200, 214, 523, 48, 97, 129, 285, 537, 538, 4, 45, 72, 144, 182, 245, 280, 296, 372, 4, 117, 199, 539, 283, 345, 541, 16, 23, 233, 235, 357, 542, 224, 546, 283, 345, 547, 0, 5, 57, 345, 378, 259, 5, 4, 283, 345, 379, 5, 32, 272, 380, 116, 345, 381, 188, 241, 386, 183, 293, 336, 337, 345, 385, 347, 131, 171, 384, 143, 173, 345, 383, 76, 167, 241, 388, 5, 345, 4, 237, 390, 345, 345, 138, 196, 244, 393, 5, 356, 5, 221, 394, 4, 17, 5, 5, 5, 4, 345, 9, 10, 11, 345, 352, 353, 354, 355, 345, 345, 37, 107, 189, 345, 397, 345, 189, 356, 358, 345, 33, 104, 120, 121, 122, 128, 141, 148, 159, 271, 360, 345, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 111, 64, 51, 69, 86, 98, 112, 115, 127, 169, 401, 183, 188, 225, 248, 293, 336, 337, 345, 403, 404, 275, 407, 164, 408, 164, 172, 410, 31, 63, 64, 67, 89, 164, 182, 201, 262, 331, 356, 412, 124, 283, 345, 358, 416, 57, 279, 356, 417, 270, 356, 358, 418, 356, 358, 419, 4, 356, 358, 420, 42, 57, 79, 98, 111, 114, 139, 140, 194, 202, 259, 260, 331, 424, 206, 295, 429, 5, 87, 6, 86, 114, 140, 331, 422, 5, 63, 358, 421, 489, 64, 178, 282, 430, 64, 225, 431, 274, 59, 273, 296, 432, 96, 119, 155, 247, 348, 433, 127, 231, 434, 45, 72, 144, 182, 245, 296, 435, 358, 87, 16, 191, 440, 348, 442, 356, 444, 70, 447, 31, 448, 41, 85, 187, 449, 144, 212, 250, 288, 450, 356, 18, 56, 109, 279, 356, 451, 4, 188, 454, 5, 4, 6, 114, 345, 5, 237, 456, 5, 111, 187, 237, 260, 458, 91, 107, 183, 471, 5, 469, 5, 260, 470, 4, 5, 347, 347, 345, 345, 5, 4, 5, 58, 64, 71, 73, 78, 81, 87, 97, 103, 123, 144, 160, 169, 170, 190, 212, 225, 227, 239, 244, 250, 257, 275, 288, 289, 291, 331, 474, 5, 4, 345, 5, 345, 37, 107, 345, 512, 347, 345, 356, 358, 511, 345, 360, 345, 4, 357, 52, 88, 133, 237, 515, 4, 4, 345, 144, 250, 516, 5, 356, 4, 37, 107, 345, 522, 345, 95, 59, 114, 237, 263, 524, 59, 111, 114, 151, 187, 234, 237, 260, 263, 274, 526, 527, 59, 114, 263, 536, 5, 4, 64, 347, 373, 64, 347, 374, 64, 347, 375, 13, 184, 519, 345, 345, 219, 345, 376, 345, 260, 4, 345, 345, 4, 545, 4, 277, 543, 4, 277, 544, 4, 360, 116, 345, 548, 345, 345, 4, 5, 345, 12, 345, 345, 30, 92, 158, 241, 246, 387, 4, 345, 345, 345, 345, 4, 4, 345, 345, 345, 345, 5, 360, 4, 488, 496, 4, 4, 356, 345, 345, 352, 354, 354, 356, 345, 345, 345, 345, 345, 345, 345, 356, 358, 355, 345, 345, 355, 345, 5, 259, 101, 183, 402, 188, 241, 405, 164, 76, 167, 241, 406, 4, 409, 4, 411, 64, 89, 331, 413, 188, 414, 172, 415, 164, 360, 345, 345, 345, 356, 345, 356, 356, 360, 360, 360, 356, 360, 345, 356, 4, 426, 358, 191, 4, 302, 425, 191, 356, 4, 428, 5, 5, 4, 191, 345, 4, 5, 58, 64, 123, 136, 144, 149, 201, 221, 225, 227, 250, 257, 275, 331, 483, 358, 64, 436, 64, 437, 64, 438, 219, 439, 345, 5, 220, 441, 357, 360, 5, 356, 356, 356, 4, 347, 4, 4, 191, 345, 14, 15, 59, 185, 186, 254, 263, 264, 295, 85, 5, 14, 15, 59, 185, 186, 254, 263, 264, 268, 295, 85, 151, 157, 357, 461, 465, 85, 151, 5, 459, 4, 4, 14, 59, 185, 254, 263, 295, 5, 5, 4, 345, 357, 20, 21, 22, 46, 47, 50, 53, 60, 64, 72, 73, 80, 81, 97, 103, 105, 106, 108, 123, 144, 167, 190, 219, 221, 226, 227, 239, 240, 250, 275, 277, 289, 291, 297, 331, 64, 78, 87, 97, 123, 144, 190, 227, 250, 289, 291, 4, 30, 156, 206, 231, 477, 5, 61, 102, 229, 242, 243, 333, 334, 482, 97, 475, 17, 37, 107, 189, 481, 5, 17, 205, 284, 345, 250, 482, 490, 117, 482, 491, 34, 37, 107, 125, 189, 283, 345, 492, 356, 347, 89, 97, 103, 119, 144, 152, 190, 198, 239, 250, 265, 495, 37, 107, 189, 5, 276, 17, 205, 284, 499, 277, 347, 500, 5, 97, 103, 292, 17, 17, 4, 345, 345, 345, 345, 345, 360, 345, 345, 355, 345, 4, 360, 37, 107, 189, 255, 517, 37, 107, 189, 255, 518, 4, 95, 5, 5, 85, 4, 5, 85, 5, 527, 59, 114, 151, 263, 531, 59, 114, 263, 535, 85, 151, 59, 114, 263, 529, 4, 59, 114, 263, 528, 5, 5, 4, 5, 5, 5, 345, 345, 345, 4, 540, 345, 345, 6, 357, 4, 5, 4, 4, 5, 4, 95, 252, 361, 345, 345, 12, 5, 12, 345, 345, 12, 4, 12, 4, 345, 345, 345, 356, 4, 53, 64, 90, 123, 275, 277, 331, 493, 494, 495, 506, 507, 4, 4, 360, 360, 345, 345, 345, 356, 345, 355, 345, 345, 5, 5, 345, 358, 345, 356, 356, 356, 4, 345, 360, 361, 361, 361, 360, 355, 345, 360, 345, 126, 238, 349, 427, 161, 4, 360, 5, 4, 4, 345, 423, 345, 20, 21, 22, 46, 47, 50, 57, 60, 64, 72, 73, 80, 105, 106, 108, 123, 144, 167, 177, 219, 226, 227, 240, 250, 275, 277, 287, 297, 331, 64, 123, 149, 227, 275, 30, 156, 206, 231, 484, 345, 201, 345, 485, 17, 345, 249, 495, 201, 345, 486, 277, 487, 17, 96, 345, 345, 5, 361, 54, 356, 4, 5, 453, 345, 5, 5, 5, 151, 180, 366, 366, 160, 256, 364, 4, 4, 5, 5, 457, 261, 5, 5, 5, 17, 153, 365, 365, 364, 4, 4, 364, 5, 5, 460, 157, 330, 357, 464, 5, 463, 5, 5, 467, 5, 468, 5, 14, 15, 59, 185, 186, 254, 263, 264, 268, 295, 4, 4, 5, 5, 366, 364, 4, 5, 5, 360, 80, 217, 218, 230, 269, 369, 7, 8, 345, 351, 231, 231, 231, 103, 37, 64, 97, 103, 107, 123, 144, 160, 190, 227, 239, 250, 277, 289, 291, 292, 331, 476, 231, 5, 27, 162, 231, 273, 131, 103, 22, 47, 50, 80, 106, 108, 221, 22, 47, 50, 53, 80, 106, 108, 221, 275, 37, 231, 231, 103, 5, 205, 27, 219, 34, 125, 283, 345, 253, 259, 235, 356, 358, 495, 37, 219, 273, 205, 5, 5, 239, 27, 219, 4, 5, 5, 205, 34, 125, 283, 345, 495, 205, 347, 4, 4, 345, 5, 295, 22, 27, 46, 47, 49, 50, 60, 72, 73, 80, 83, 100, 105, 106, 108, 167, 221, 226, 240, 276, 277, 297, 341, 478, 345, 345, 345, 345, 345, 482, 356, 5, 4, 5, 345, 345, 356, 358, 345, 356, 347, 345, 345, 482, 5, 345, 345, 347, 5, 17, 5, 5, 345, 345, 355, 345, 345, 345, 345, 107, 345, 345, 107, 4, 39, 40, 165, 166, 193, 371, 371, 59, 114, 263, 525, 371, 59, 114, 263, 530, 5, 5, 59, 114, 263, 532, 4, 5, 5, 4, 59, 114, 263, 534, 59, 114, 263, 533, 5, 5, 4, 5, 5, 4, 371, 371, 371, 345, 345, 4, 345, 357, 360, 5, 5, 12, 345, 356, 358, 345, 12, 345, 345, 345, 57, 345, 6, 4, 345, 345, 360, 43, 262, 395, 342, 342, 342, 342, 342, 342, 342, 494, 342, 5, 6, 345, 4, 4, 4, 356, 345, 345, 345, 345, 4, 4, 360, 356, 361, 348, 348, 355, 345, 4, 361, 345, 35, 279, 35, 279, 4, 358, 5, 24, 25, 95, 362, 345, 4, 345, 5, 80, 217, 218, 230, 269, 356, 358, 231, 231, 231, 21, 231, 356, 358, 231, 27, 162, 231, 273, 131, 21, 231, 231, 231, 21, 231, 27, 163, 219, 163, 253, 259, 163, 219, 281, 495, 163, 219, 273, 4, 239, 27, 163, 219, 495, 201, 345, 345, 345, 345, 345, 191, 345, 345, 20, 228, 445, 4, 4, 345, 366, 366, 366, 4, 366, 366, 366, 14, 15, 59, 185, 186, 254, 263, 264, 295, 365, 366, 366, 366, 366, 366, 4, 366, 366, 4, 365, 14, 15, 59, 185, 186, 254, 263, 264, 295, 5, 462, 5, 466, 5, 5, 14, 15, 59, 185, 186, 254, 263, 264, 268, 295, 5, 14, 15, 59, 185, 186, 254, 263, 264, 268, 295, 5, 14, 15, 59, 185, 186, 254, 263, 264, 268, 295, 14, 15, 59, 185, 186, 254, 263, 264, 295, 261, 5, 5, 5, 365, 365, 364, 4, 4, 364, 5, 4, 4, 366, 366, 4, 366, 366, 5, 347, 356, 358, 5, 345, 345, 5, 345, 5, 351, 103, 190, 239, 103, 190, 239, 5, 345, 347, 5, 345, 356, 347, 5, 351, 231, 231, 21, 231, 21, 231, 231, 21, 231, 299, 4, 4, 4, 476, 4, 4, 4, 299, 4, 5, 4, 345, 5, 345, 5, 351, 347, 356, 358, 356, 358, 345, 27, 46, 49, 60, 83, 100, 341, 367, 4, 345, 360, 355, 347, 356, 358, 356, 347, 347, 356, 358, 356, 358, 345, 347, 345, 5, 345, 219, 219, 345, 345, 219, 345, 219, 345, 345, 496, 345, 219, 219, 345, 345, 345, 345, 345, 345, 345, 5, 295, 345, 479, 345, 345, 219, 345, 345, 345, 345, 356, 360, 5, 356, 356, 345, 345, 360, 355, 345, 345, 345, 356, 345, 345, 5, 345, 345, 345, 345, 5, 5, 4, 5, 5, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 5, 5, 4, 345, 345, 345, 360, 345, 356, 358, 345, 360, 345, 345, 345, 345, 345, 5, 345, 6, 6, 345, 345, 4, 476, 5, 4, 5, 5, 5, 4, 347, 356, 356, 345, 360, 172, 359, 345, 359, 361, 360, 356, 345, 345, 4, 348, 345, 348, 345, 4, 356, 5, 5, 5, 356, 360, 356, 358, 356, 358, 356, 358, 356, 358, 356, 358, 360, 356, 358, 356, 358, 356, 358, 356, 358, 356, 358, 356, 358, 356, 358, 356, 358, 356, 356, 358, 345, 356, 356, 358, 356, 358, 356, 356, 358, 356, 356, 358, 345, 4, 345, 5, 4, 345, 366, 5, 5, 5, 364, 4, 4, 5, 366, 365, 4, 366, 5, 5, 5, 365, 365, 364, 4, 4, 5, 14, 15, 59, 185, 186, 254, 263, 264, 295, 14, 15, 59, 185, 186, 254, 263, 264, 295, 14, 15, 59, 185, 186, 254, 263, 264, 295, 261, 5, 5, 5, 365, 365, 364, 4, 4, 364, 5, 261, 5, 5, 5, 365, 365, 364, 4, 4, 364, 5, 261, 5, 5, 5, 365, 365, 364, 4, 4, 364, 5, 5, 5, 5, 365, 365, 364, 4, 4, 5, 365, 4, 4, 365, 4, 4, 366, 5, 360, 356, 345, 345, 356, 345, 5, 351, 5, 356, 358, 347, 5, 356, 358, 360, 5, 351, 345, 345, 345, 345, 345, 345, 345, 345, 345, 4, 5, 4, 345, 356, 345, 5, 351, 347, 360, 355, 360, 345, 345, 355, 355, 360, 355, 360, 360, 355, 360, 355, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 356, 5, 345, 345, 345, 345, 4, 4, 360, 361, 4, 480, 360, 360, 355, 345, 4, 360, 371, 371, 371, 345, 345, 345, 360, 345, 355, 345, 345, 12, 5, 5, 4, 6, 345, 345, 4, 5, 4, 360, 360, 356, 345, 345, 361, 362, 345, 5, 345, 358, 5, 5, 5, 362, 362, 362, 360, 362, 361, 362, 362, 360, 362, 362, 362, 360, 362, 362, 360, 356, 362, 360, 362, 362, 360, 362, 360, 4, 358, 5, 345, 4, 366, 365, 4, 365, 5, 5, 5, 365, 365, 364, 4, 4, 5, 5, 5, 5, 365, 365, 364, 4, 4, 5, 5, 5, 5, 365, 365, 364, 4, 4, 5, 365, 366, 366, 366, 366, 366, 4, 366, 366, 4, 365, 365, 366, 366, 366, 366, 366, 4, 366, 366, 4, 365, 365, 4, 4, 365, 4, 365, 365, 4, 4, 4, 357, 362, 4, 356, 358, 362, 345, 356, 4, 362, 362, 356, 4, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 356, 358, 362, 345, 356, 4, 355, 355, 355, 345, 356, 358, 355, 345, 355, 355, 356, 355, 345, 355, 345, 345, 345, 345, 345, 345, 351, 345, 345, 345, 351, 345, 345, 345, 345, 351, 345, 345, 345, 345, 345, 360, 345, 295, 350, 351, 345, 345, 361, 347, 4, 4, 361, 345, 355, 345, 57, 345, 5, 5, 4, 345, 4, 359, 5, 362, 5, 5, 356, 5, 361, 362, 361, 361, 361, 5, 345, 366, 365, 366, 366, 366, 366, 366, 4, 366, 366, 365, 4, 365, 366, 366, 366, 366, 366, 4, 366, 366, 365, 366, 365, 4, 366, 366, 365, 4, 366, 365, 4, 365, 365, 360, 356, 358, 362, 4, 360, 345, 360, 345, 345, 362, 4, 360, 345, 355, 362, 345, 355, 362, 356, 351, 345, 4, 368, 368, 345, 345, 368, 351, 368, 496, 356, 351, 368, 368, 345, 345, 351, 345, 345, 345, 345, 355, 345, 5, 496, 345, 368, 347, 497, 498, 5, 347, 5, 345, 5, 4, 6, 345, 5, 32, 272, 370, 356, 345, 365, 366, 365, 365, 366, 366, 365, 366, 365, 365, 345, 362, 356, 358, 356, 345, 356, 345, 356, 358, 356, 345, 356, 362, 4, 496, 496, 350, 345, 496, 4, 496, 360, 4, 496, 496, 350, 345, 4, 496, 496, 345, 356, 496, 496, 497, 503, 504, 495, 501, 502, 5, 5, 6, 4, 183, 293, 336, 337, 345, 363, 356, 4, 366, 366, 366, 366, 357, 362, 362, 345, 362, 4, 362, 362, 345, 362, 345, 496, 496, 4, 345, 496, 345, 496, 4, 345, 496, 360, 503, 505, 506, 342, 502, 5, 5, 4, 345, 360, 362, 4, 356, 358, 4, 351, 350, 345, 345, 350, 345, 356, 506, 347, 5, 5, 345, 370, 5, 356, 358, 360, 356, 358, 496, 345, 4, 496, 345, 362, 5, 5, 360, 360, 4, 496, 4, 496, 350, 350, 496, 496 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, frFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; frFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, frFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; frFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, frFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; frFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, frFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; frFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, frFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, frFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; frFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 4: #line 445 "parser.Y" {fr->bgColorCmd((yyvsp[(3) - (3)].str));;} break; case 5: #line 446 "parser.Y" {fr->centerCmd();;} break; case 6: #line 447 "parser.Y" {fr->clearCmd();;} break; case 8: #line 449 "parser.Y" {fr->colorbarTagCmd((yyvsp[(3) - (3)].str));;} break; case 14: #line 455 "parser.Y" {fr->DATASECCmd((yyvsp[(2) - (2)].integer));;} break; case 19: #line 460 "parser.Y" {fr->hideCmd();;} break; case 20: #line 461 "parser.Y" {fr->highliteCmd((yyvsp[(2) - (2)].integer));;} break; case 25: #line 467 "parser.Y" { fr->matchCmd((yyvsp[(2) - (13)].str),(yyvsp[(3) - (13)].str),(Coord::CoordSystem)(yyvsp[(4) - (13)].integer),(Coord::SkyFrame)(yyvsp[(5) - (13)].integer), (yyvsp[(6) - (13)].str),(yyvsp[(7) - (13)].str),(Coord::CoordSystem)(yyvsp[(8) - (13)].integer),(Coord::SkyFrame)(yyvsp[(9) - (13)].integer), (yyvsp[(10) - (13)].real),(Coord::CoordSystem)(yyvsp[(11) - (13)].integer),(Coord::SkyDist)(yyvsp[(12) - (13)].integer), (yyvsp[(13) - (13)].str)); ;} break; case 28: #line 475 "parser.Y" {fr->nanColorCmd((yyvsp[(3) - (3)].str));;} break; case 33: #line 480 "parser.Y" {fr->resetCmd();;} break; case 38: #line 485 "parser.Y" {fr->showCmd();;} break; case 40: #line 487 "parser.Y" {fr->threadsCmd((yyvsp[(2) - (2)].integer));;} break; case 42: #line 489 "parser.Y" {fr->unloadFitsCmd();;} break; case 44: #line 491 "parser.Y" {fr->msg("Frame 1.0");;} break; case 49: #line 498 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 50: #line 499 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 51: #line 502 "parser.Y" {yydebug=1;;} break; case 52: #line 503 "parser.Y" {yydebug=0;;} break; case 53: #line 504 "parser.Y" {DebugAST=(yyvsp[(2) - (2)].integer);;} break; case 54: #line 505 "parser.Y" {DebugMosaic=(yyvsp[(2) - (2)].integer);;} break; case 55: #line 506 "parser.Y" {yydebug=(yyvsp[(2) - (2)].integer);;} break; case 56: #line 507 "parser.Y" {DebugPerf=(yyvsp[(2) - (2)].integer);;} break; case 57: #line 508 "parser.Y" {DebugWCS=(yyvsp[(2) - (2)].integer);;} break; case 58: #line 509 "parser.Y" {DebugBin=(yyvsp[(2) - (2)].integer);;} break; case 59: #line 510 "parser.Y" {DebugCompress=(yyvsp[(2) - (2)].integer);} break; case 60: #line 511 "parser.Y" {DebugCrop=(yyvsp[(2) - (2)].integer);} break; case 61: #line 512 "parser.Y" {DebugGZ=(yyvsp[(2) - (2)].integer);;} break; case 62: #line 513 "parser.Y" {DebugRGB=(yyvsp[(2) - (2)].integer);;} break; case 63: #line 516 "parser.Y" {(yyval.integer)=((yyvsp[(1) - (1)].integer) ? 1 : 0);;} break; case 64: #line 518 "parser.Y" {(yyval.integer)=1;;} break; case 65: #line 519 "parser.Y" {(yyval.integer)=1;;} break; case 66: #line 520 "parser.Y" {(yyval.integer)=1;;} break; case 67: #line 521 "parser.Y" {(yyval.integer)=1;;} break; case 68: #line 523 "parser.Y" {(yyval.integer)=0;;} break; case 69: #line 524 "parser.Y" {(yyval.integer)=0;;} break; case 70: #line 525 "parser.Y" {(yyval.integer)=0;;} break; case 71: #line 526 "parser.Y" {(yyval.integer)=0;;} break; case 72: #line 529 "parser.Y" {(yyval.integer) = Base::DEFAULT;;} break; case 73: #line 530 "parser.Y" {(yyval.integer) = Base::DEFAULT;;} break; case 74: #line 531 "parser.Y" {(yyval.integer) = Base::FIXED;;} break; case 75: #line 532 "parser.Y" {(yyval.integer) = Base::SCIENTIFIC;;} break; case 76: #line 533 "parser.Y" {(yyval.integer) = Base::INTEGER;;} break; case 77: #line 536 "parser.Y" {(yyval.integer) = Base::ROOTBASE;;} break; case 78: #line 537 "parser.Y" {(yyval.integer) = Base::ROOTBASE;;} break; case 79: #line 538 "parser.Y" {(yyval.integer) = Base::FULLBASE;;} break; case 80: #line 539 "parser.Y" {(yyval.integer) = Base::ROOT;;} break; case 81: #line 540 "parser.Y" {(yyval.integer) = Base::FULL;;} break; case 82: #line 541 "parser.Y" {(yyval.integer) = Base::ROOT3D;;} break; case 83: #line 542 "parser.Y" {(yyval.integer) = Base::FULL3D;;} break; case 84: #line 545 "parser.Y" {(yyval.real) = 0;;} break; case 85: #line 546 "parser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 86: #line 549 "parser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 87: #line 550 "parser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 88: #line 551 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 89: #line 554 "parser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 90: #line 557 "parser.Y" {(yyval.real) = parseHMSStr((yyvsp[(1) - (1)].str));;} break; case 91: #line 560 "parser.Y" {(yyval.real) = parseDMSStr((yyvsp[(1) - (1)].str));;} break; case 92: #line 564 "parser.Y" { Vector r; if (currentSky == Coord::GALACTIC || currentSky == Coord::ECLIPTIC) r = Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)); else r = Vector((yyvsp[(1) - (2)].real)*360./24.,(yyvsp[(2) - (2)].real)); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 93: #line 576 "parser.Y" { Vector r = Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 94: #line 583 "parser.Y" { Vector r = Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 95: #line 590 "parser.Y" { (yyval.vector)[0] = (yyvsp[(1) - (2)].real); (yyval.vector)[1] = (yyvsp[(2) - (2)].real); (yyval.vector)[2] = 1; ;} break; case 96: #line 597 "parser.Y" {(yyval.integer) = currentCoord = Coord::IMAGE;;} break; case 97: #line 598 "parser.Y" {(yyval.integer) = currentCoord = Coord::PHYSICAL;;} break; case 98: #line 599 "parser.Y" {(yyval.integer) = currentCoord = Coord::DETECTOR;;} break; case 99: #line 600 "parser.Y" {(yyval.integer) = currentCoord = Coord::AMPLIFIER;;} break; case 100: #line 601 "parser.Y" {(yyval.integer) = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer);;} break; case 101: #line 604 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCS;;} break; case 102: #line 605 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSA;;} break; case 103: #line 606 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSB;;} break; case 104: #line 607 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSC;;} break; case 105: #line 608 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSD;;} break; case 106: #line 609 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSE;;} break; case 107: #line 610 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSF;;} break; case 108: #line 611 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSG;;} break; case 109: #line 612 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSH;;} break; case 110: #line 613 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSI;;} break; case 111: #line 614 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSJ;;} break; case 112: #line 615 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSK;;} break; case 113: #line 616 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSL;;} break; case 114: #line 617 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSM;;} break; case 115: #line 618 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSN;;} break; case 116: #line 619 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSO;;} break; case 117: #line 620 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSP;;} break; case 118: #line 621 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSQ;;} break; case 119: #line 622 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSR;;} break; case 120: #line 623 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSS;;} break; case 121: #line 624 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCST;;} break; case 122: #line 625 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSU;;} break; case 123: #line 626 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSV;;} break; case 124: #line 627 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSW;;} break; case 125: #line 628 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSX;;} break; case 126: #line 629 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSY;;} break; case 127: #line 630 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCSZ;;} break; case 128: #line 631 "parser.Y" {(yyval.integer) = currentCoord = Coord::WCS0;;} break; case 129: #line 634 "parser.Y" {(yyval.integer) = Coord::CANVAS;;} break; case 130: #line 635 "parser.Y" {(yyval.integer) = Coord::PANNER;;} break; case 131: #line 638 "parser.Y" {(yyval.integer) = FrScale::LINEARSCALE;;} break; case 132: #line 639 "parser.Y" {(yyval.integer) = FrScale::LOGSCALE;;} break; case 133: #line 640 "parser.Y" {(yyval.integer) = FrScale::POWSCALE;;} break; case 134: #line 641 "parser.Y" {(yyval.integer) = FrScale::SQRTSCALE;;} break; case 135: #line 642 "parser.Y" {(yyval.integer) = FrScale::SQUAREDSCALE;;} break; case 136: #line 643 "parser.Y" {(yyval.integer) = FrScale::ASINHSCALE;;} break; case 137: #line 644 "parser.Y" {(yyval.integer) = FrScale::SINHSCALE;;} break; case 138: #line 645 "parser.Y" {(yyval.integer) = FrScale::HISTEQUSCALE;;} break; case 139: #line 648 "parser.Y" {(yyval.integer) = currentSky = Coord::FK5;;} break; case 140: #line 649 "parser.Y" {(yyval.integer) = currentSky = Coord::FK4;;} break; case 141: #line 650 "parser.Y" {(yyval.integer) = currentSky = Coord::FK4_NO_E;;} break; case 142: #line 651 "parser.Y" {(yyval.integer) = currentSky = Coord::FK4;;} break; case 143: #line 652 "parser.Y" {(yyval.integer) = currentSky = Coord::FK5;;} break; case 144: #line 653 "parser.Y" {(yyval.integer) = currentSky = Coord::FK5;;} break; case 145: #line 654 "parser.Y" {(yyval.integer) = currentSky = Coord::ICRS;;} break; case 146: #line 655 "parser.Y" {(yyval.integer) = currentSky = Coord::GALACTIC;;} break; case 147: #line 656 "parser.Y" {(yyval.integer) = currentSky = Coord::SUPERGALACTIC;;} break; case 148: #line 657 "parser.Y" {(yyval.integer) = currentSky = Coord::ECLIPTIC;;} break; case 149: #line 658 "parser.Y" {(yyval.integer) = currentSky = Coord::HELIOECLIPTIC;;} break; case 150: #line 661 "parser.Y" {(yyval.integer)=Coord::DEGREES;;} break; case 151: #line 662 "parser.Y" {(yyval.integer)=Coord::DEGREES;;} break; case 152: #line 663 "parser.Y" {(yyval.integer)=Coord::SEXAGESIMAL;;} break; case 153: #line 666 "parser.Y" {(yyval.integer)=Coord::DEGREE;;} break; case 154: #line 667 "parser.Y" {(yyval.integer)=Coord::DEGREE;;} break; case 155: #line 668 "parser.Y" {(yyval.integer)=Coord::ARCMIN;;} break; case 156: #line 669 "parser.Y" {(yyval.integer)=Coord::ARCSEC;;} break; case 157: #line 672 "parser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 158: #line 673 "parser.Y" {(yyval.real) = FrScale::MINMAX;;} break; case 159: #line 674 "parser.Y" {(yyval.real) = FrScale::ZSCALE;;} break; case 160: #line 675 "parser.Y" {(yyval.real) = FrScale::ZMAX;;} break; case 161: #line 676 "parser.Y" {(yyval.real) = FrScale::USERCLIP;;} break; case 162: #line 679 "parser.Y" {(yyval.integer) = Base::SHMID;;} break; case 163: #line 680 "parser.Y" {(yyval.integer) = Base::SHMID;;} break; case 164: #line 681 "parser.Y" {(yyval.integer) = Base::KEY;;} break; case 165: #line 684 "parser.Y" {(yyval.integer) = Base::LOADALL;;} break; case 166: #line 685 "parser.Y" {(yyval.integer) = Base::LOADALL;;} break; case 167: #line 686 "parser.Y" {(yyval.integer) = Base::INCR;;} break; case 168: #line 689 "parser.Y" {(yyval.integer) = Base::IMG;;} break; case 169: #line 690 "parser.Y" {(yyval.integer) = Base::IMG;;} break; case 170: #line 691 "parser.Y" {(yyval.integer) = Base::MASK;;} break; case 171: #line 694 "parser.Y" {(yyval.integer) = Point::CIRCLE;;} break; case 172: #line 695 "parser.Y" {(yyval.integer) = Point::CIRCLE;;} break; case 173: #line 696 "parser.Y" {(yyval.integer) = Point::BOX;;} break; case 174: #line 697 "parser.Y" {(yyval.integer) = Point::DIAMOND;;} break; case 175: #line 698 "parser.Y" {(yyval.integer) = Point::CROSS;;} break; case 176: #line 699 "parser.Y" {(yyval.integer) = Point::EX;;} break; case 177: #line 700 "parser.Y" {(yyval.integer) = Point::ARROW;;} break; case 178: #line 701 "parser.Y" {(yyval.integer) = Point::BOXCIRCLE;;} break; case 179: #line 704 "parser.Y" {(yyval.integer) = POINTSIZE;;} break; case 180: #line 705 "parser.Y" {(yyval.integer) = (yyvsp[(1) - (1)].integer);;} break; case 181: #line 708 "parser.Y" {(yyval.integer) = Marker::PANDA;;} break; case 182: #line 709 "parser.Y" {(yyval.integer) = Marker::PLOT2D;;} break; case 183: #line 710 "parser.Y" {(yyval.integer) = Marker::PLOT3D;;} break; case 184: #line 711 "parser.Y" {(yyval.integer) = Marker::RADIAL;;} break; case 185: #line 712 "parser.Y" {(yyval.integer) = Marker::STATS;;} break; case 186: #line 715 "parser.Y" {(yyval.integer) = Marker::AVERAGE;;} break; case 187: #line 716 "parser.Y" {(yyval.integer) = Marker::AVERAGE;;} break; case 188: #line 717 "parser.Y" {(yyval.integer) = Marker::SUM;;} break; case 189: #line 720 "parser.Y" {(yyval.integer) = FitsFile::NATIVE;;} break; case 190: #line 721 "parser.Y" {(yyval.integer) = FitsFile::NATIVE;;} break; case 191: #line 722 "parser.Y" {(yyval.integer) = FitsFile::BIG;;} break; case 192: #line 723 "parser.Y" {(yyval.integer) = FitsFile::BIG;;} break; case 193: #line 724 "parser.Y" {(yyval.integer) = FitsFile::LITTLE;;} break; case 194: #line 725 "parser.Y" {(yyval.integer) = FitsFile::LITTLE;;} break; case 199: #line 732 "parser.Y" {fr->set3dRenderMethodCmd((yyvsp[(2) - (2)].integer));;} break; case 200: #line 733 "parser.Y" {fr->set3dScaleCmd((yyvsp[(2) - (2)].real));;} break; case 201: #line 735 "parser.Y" {/* needed for compatibility with old version of backup */;} break; case 202: #line 738 "parser.Y" {fr->set3dBorderCmd((yyvsp[(1) - (1)].integer));;} break; case 203: #line 739 "parser.Y" {fr->set3dBorderColorCmd((yyvsp[(2) - (2)].str));;} break; case 204: #line 742 "parser.Y" {fr->set3dCompassCmd((yyvsp[(1) - (1)].integer));;} break; case 205: #line 743 "parser.Y" {fr->set3dCompassColorCmd((yyvsp[(2) - (2)].str));;} break; case 206: #line 746 "parser.Y" {fr->set3dHighliteCmd((yyvsp[(1) - (1)].integer));;} break; case 207: #line 747 "parser.Y" {fr->set3dHighliteColorCmd((yyvsp[(2) - (2)].str));;} break; case 208: #line 750 "parser.Y" {fr->set3dViewCmd((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real));;} break; case 209: #line 752 "parser.Y" {fr->set3dViewPointCmd(Vector3d((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 211: #line 756 "parser.Y" {fr->binColsCmd((yyvsp[(2) - (4)].str),(yyvsp[(3) - (4)].str),(yyvsp[(4) - (4)].str));;} break; case 212: #line 757 "parser.Y" {fr->binDepthCmd((yyvsp[(2) - (2)].integer));;} break; case 215: #line 760 "parser.Y" {fr->binBufferSizeCmd((yyvsp[(3) - (3)].integer));;} break; case 217: #line 762 "parser.Y" {fr->binFilterCmd((yyvsp[(2) - (2)].str));;} break; case 218: #line 765 "parser.Y" {fr->binAboutCmd();;} break; case 219: #line 766 "parser.Y" {fr->binAboutCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 220: #line 769 "parser.Y" {fr->binFactorCmd(Vector((yyvsp[(1) - (1)].real),(yyvsp[(1) - (1)].real)));;} break; case 221: #line 770 "parser.Y" {fr->binFactorCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 222: #line 772 "parser.Y" {fr->binFactorAboutCmd(Vector((yyvsp[(1) - (4)].real),(yyvsp[(1) - (4)].real)), Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 223: #line 774 "parser.Y" {fr->binFactorAboutCmd(Vector((yyvsp[(1) - (5)].real),(yyvsp[(2) - (5)].real)), Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)));;} break; case 224: #line 775 "parser.Y" {fr->binFactorToCmd(Vector((yyvsp[(2) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 225: #line 776 "parser.Y" {fr->binFactorToCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 226: #line 778 "parser.Y" {fr->binFactorToAboutCmd(Vector((yyvsp[(2) - (5)].real),(yyvsp[(2) - (5)].real)), Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)));;} break; case 227: #line 780 "parser.Y" {fr->binFactorToAboutCmd(Vector((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real)), Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 228: #line 783 "parser.Y" {fr->binFunctionCmd(FitsHist::AVERAGE);;} break; case 229: #line 784 "parser.Y" {fr->binFunctionCmd(FitsHist::SUM);;} break; case 230: #line 787 "parser.Y" {fr->binToFitCmd();;} break; case 231: #line 789 "parser.Y" {fr->binCmd(Vector((yyvsp[(1) - (7)].real),(yyvsp[(2) - (7)].real)), (yyvsp[(5) - (7)].str), (yyvsp[(6) - (7)].str), (yyvsp[(7) - (7)].str));;} break; case 232: #line 792 "parser.Y" {fr->binCmd(Vector((yyvsp[(1) - (11)].real),(yyvsp[(2) - (11)].real)), (yyvsp[(3) - (11)].integer), Vector((yyvsp[(4) - (11)].real),(yyvsp[(5) - (11)].real)), (yyvsp[(8) - (11)].str), (yyvsp[(9) - (11)].str), (yyvsp[(10) - (11)].str), (yyvsp[(11) - (11)].str));;} break; case 233: #line 794 "parser.Y" {fr->binCmd(Vector((yyvsp[(1) - (8)].real),(yyvsp[(2) - (8)].real)), Vector((yyvsp[(4) - (8)].real),(yyvsp[(5) - (8)].real)), (yyvsp[(6) - (8)].str), (yyvsp[(7) - (8)].str), (yyvsp[(8) - (8)].str));;} break; case 234: #line 797 "parser.Y" {fr->binCmd(Vector((yyvsp[(1) - (12)].real),(yyvsp[(2) - (12)].real)), (yyvsp[(3) - (12)].integer), Vector((yyvsp[(4) - (12)].real),(yyvsp[(5) - (12)].real)), Vector((yyvsp[(7) - (12)].real),(yyvsp[(8) - (12)].real)), (yyvsp[(9) - (12)].str), (yyvsp[(10) - (12)].str), (yyvsp[(11) - (12)].str), (yyvsp[(12) - (12)].str));;} break; case 240: #line 806 "parser.Y" {fr->clipPreserveCmd((yyvsp[(2) - (2)].integer));;} break; case 241: #line 809 "parser.Y" {fr->clipUserCmd((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real));;} break; case 242: #line 810 "parser.Y" {fr->clipUserLowCmd((yyvsp[(2) - (2)].real));;} break; case 243: #line 811 "parser.Y" {fr->clipUserHighCmd((yyvsp[(2) - (2)].real));;} break; case 244: #line 814 "parser.Y" {fr->clipScopeCmd(FrScale::GLOBAL);;} break; case 245: #line 815 "parser.Y" {fr->clipScopeCmd(FrScale::LOCAL);;} break; case 246: #line 818 "parser.Y" {fr->clipModeCmd((yyvsp[(1) - (1)].real));;} break; case 247: #line 819 "parser.Y" {fr->clipModeCmd(FrScale::MINMAX);;} break; case 248: #line 820 "parser.Y" {fr->clipModeCmd(FrScale::ZSCALE);;} break; case 249: #line 821 "parser.Y" {fr->clipModeCmd(FrScale::ZMAX);;} break; case 250: #line 822 "parser.Y" {fr->clipModeCmd(FrScale::USERCLIP);;} break; case 252: #line 826 "parser.Y" {fr->clipMinMaxSampleCmd((yyvsp[(2) - (2)].integer));;} break; case 253: #line 829 "parser.Y" {fr->clipMinMaxModeCmd(FrScale::AUTOSCAN);;} break; case 254: #line 830 "parser.Y" {fr->clipMinMaxModeCmd(FrScale::SCAN);;} break; case 255: #line 831 "parser.Y" {fr->clipMinMaxModeCmd(FrScale::SAMPLE);;} break; case 256: #line 832 "parser.Y" {fr->clipMinMaxModeCmd(FrScale::DATAMIN);;} break; case 257: #line 833 "parser.Y" {fr->clipMinMaxModeCmd(FrScale::IRAFMIN);;} break; case 258: #line 836 "parser.Y" {fr->clipZScaleContrastCmd((yyvsp[(2) - (2)].real));;} break; case 259: #line 837 "parser.Y" {fr->clipZScaleSampleCmd((yyvsp[(2) - (2)].integer));;} break; case 260: #line 838 "parser.Y" {fr->clipZScaleLineCmd((yyvsp[(2) - (2)].integer));;} break; case 261: #line 842 "parser.Y" {fr->colormapCmd((yyvsp[(1) - (7)].integer), (yyvsp[(2) - (7)].real), (yyvsp[(3) - (7)].real), (yyvsp[(4) - (7)].integer), (unsigned short*)(yyvsp[(5) - (7)].ptr), (unsigned char*)(yyvsp[(6) - (7)].ptr), (yyvsp[(7) - (7)].integer));;} break; case 262: #line 845 "parser.Y" {fr->colormapCmd((yyvsp[(2) - (10)].real),(yyvsp[(3) - (10)].real),(yyvsp[(4) - (10)].real),(yyvsp[(5) - (10)].real),(yyvsp[(6) - (10)].real),(yyvsp[(7) - (10)].real),(yyvsp[(8) - (10)].integer),(unsigned char*)(yyvsp[(9) - (10)].ptr),(yyvsp[(10) - (10)].integer));;} break; case 263: #line 846 "parser.Y" {fr->colormapBeginCmd();;} break; case 265: #line 848 "parser.Y" {fr->colormapEndCmd();;} break; case 266: #line 852 "parser.Y" {fr->colormapMotionCmd((yyvsp[(1) - (7)].integer), (yyvsp[(2) - (7)].real), (yyvsp[(3) - (7)].real), (yyvsp[(4) - (7)].integer), (unsigned short*)(yyvsp[(5) - (7)].ptr), (unsigned char*)(yyvsp[(6) - (7)].ptr), (yyvsp[(7) - (7)].integer));;} break; case 267: #line 855 "parser.Y" {fr->colormapMotionCmd((yyvsp[(2) - (10)].real),(yyvsp[(3) - (10)].real),(yyvsp[(4) - (10)].real),(yyvsp[(5) - (10)].real),(yyvsp[(6) - (10)].real),(yyvsp[(7) - (10)].real),(yyvsp[(8) - (10)].integer), (unsigned char*)(yyvsp[(9) - (10)].ptr),(yyvsp[(10) - (10)].integer));;} break; case 268: #line 858 "parser.Y" {fr->colorScaleCmd((FrScale::ColorScaleType)(yyvsp[(1) - (1)].integer));;} break; case 269: #line 859 "parser.Y" {fr->colorScaleLogCmd((yyvsp[(2) - (2)].real));;} break; case 271: #line 863 "parser.Y" {fr->contourSetColorCmd((yyvsp[(2) - (2)].str));;} break; case 272: #line 865 "parser.Y" {fr->contourCopyCmd((Coord::CoordSystem)(yyvsp[(2) - (3)].integer), (Coord::SkyFrame)(yyvsp[(3) - (3)].integer));;} break; case 274: #line 867 "parser.Y" {fr->contourSetDashCmd((yyvsp[(2) - (2)].integer));;} break; case 275: #line 868 "parser.Y" {fr->contourDeleteCmd();;} break; case 276: #line 869 "parser.Y" {fr->contourDeleteAllCmd();;} break; case 277: #line 871 "parser.Y" {fr->contourLoadCmd((yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].integer), (yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].str), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyFrame)(yyvsp[(7) - (7)].integer));;} break; case 278: #line 873 "parser.Y" {fr->contourPasteCmd((yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].integer), (yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].ptr), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyFrame)(yyvsp[(7) - (7)].integer));;} break; case 279: #line 875 "parser.Y" {fr->contourSaveCmd((yyvsp[(2) - (4)].str), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (Coord::SkyFrame)(yyvsp[(4) - (4)].integer));;} break; case 280: #line 876 "parser.Y" {fr->contourSetLineWidthCmd((yyvsp[(2) - (2)].integer));;} break; case 281: #line 879 "parser.Y" {fr->contourAuxHeadCmd();;} break; case 282: #line 880 "parser.Y" {fr->contourAuxNextCmd();;} break; case 283: #line 882 "parser.Y" {fr->contourAuxSaveCmd((yyvsp[(2) - (4)].str), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (Coord::SkyFrame)(yyvsp[(4) - (4)].integer));;} break; case 284: #line 886 "parser.Y" {fr->contourCreateCmd((yyvsp[(1) - (12)].str),(yyvsp[(2) - (12)].integer),(yyvsp[(3) - (12)].integer),(FVContour::Method)(yyvsp[(4) - (12)].integer),(yyvsp[(5) - (12)].integer),(yyvsp[(6) - (12)].integer),(FrScale::ColorScaleType)(yyvsp[(7) - (12)].integer),(yyvsp[(8) - (12)].real),(yyvsp[(9) - (12)].real),Vector((yyvsp[(10) - (12)].real),(yyvsp[(11) - (12)].real)),(yyvsp[(12) - (12)].str));;} break; case 285: #line 888 "parser.Y" {fr->createContourPolygonCmd(currentColor,currentDash,currentWidth, currentFont, currentText, currentProps, NULL, taglist,cblist);;} break; case 286: #line 892 "parser.Y" {(yyval.integer) = FVContour::SMOOTH;;} break; case 287: #line 893 "parser.Y" {(yyval.integer) = FVContour::BLOCK;;} break; case 288: #line 896 "parser.Y" {fr->cropCmd();;} break; case 289: #line 898 "parser.Y" {fr->cropCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)), Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)), (Coord::CoordSystem)(yyvsp[(5) - (6)].integer), (Coord::SkyFrame)(yyvsp[(6) - (6)].integer));;} break; case 290: #line 901 "parser.Y" {fr->cropCenterCmd(Vector((yyvsp[(2) - (8)].vector)), (Coord::CoordSystem)(yyvsp[(3) - (8)].integer), (Coord::SkyFrame)(yyvsp[(4) - (8)].integer), Vector((yyvsp[(5) - (8)].real),(yyvsp[(6) - (8)].real)), (Coord::CoordSystem)(yyvsp[(7) - (8)].integer), (Coord::SkyDist)(yyvsp[(8) - (8)].integer));;} break; case 292: #line 904 "parser.Y" {fr->cropBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 293: #line 905 "parser.Y" {fr->cropMotionCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 294: #line 906 "parser.Y" {fr->cropEndCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 295: #line 909 "parser.Y" {fr->crop3dCmd();;} break; case 296: #line 910 "parser.Y" {fr->crop3dCmd((yyvsp[(1) - (3)].real), (yyvsp[(2) - (3)].real), (Coord::CoordSystem)(yyvsp[(3) - (3)].integer));;} break; case 297: #line 911 "parser.Y" {fr->crop3dBeginCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].integer));;} break; case 298: #line 912 "parser.Y" {fr->crop3dMotionCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].integer));;} break; case 299: #line 913 "parser.Y" {fr->crop3dEndCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].integer));;} break; case 300: #line 917 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)), (Coord::InternalSystem)(yyvsp[(1) - (3)].integer));;} break; case 301: #line 919 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(3) - (3)].vector)), (Coord::CoordSystem)(yyvsp[(1) - (3)].integer), (Coord::SkyFrame)(yyvsp[(2) - (3)].integer));;} break; case 302: #line 920 "parser.Y" {fr->crosshairCmd((yyvsp[(1) - (1)].integer));;} break; case 303: #line 921 "parser.Y" {fr->crosshairWarpCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 304: #line 924 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)), (Coord::InternalSystem)(yyvsp[(3) - (5)].integer));;} break; case 305: #line 926 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)), (Coord::InternalSystem)(yyvsp[(2) - (4)].integer));;} break; case 306: #line 928 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(4) - (4)].vector)), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer));;} break; case 307: #line 930 "parser.Y" {fr->crosshairCmd(Vector((yyvsp[(3) - (3)].vector)), (Coord::CoordSystem)(yyvsp[(2) - (3)].integer));;} break; case 308: #line 933 "parser.Y" {fr->fitsyHasExtCmd((yyvsp[(3) - (3)].str));;} break; case 309: #line 936 "parser.Y" {fr->getBgColorCmd();;} break; case 321: #line 948 "parser.Y" {fr->getDATASECCmd();;} break; case 324: #line 951 "parser.Y" {fr->getHistogramCmd((yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 325: #line 953 "parser.Y" {fr->getHorzCutCmd((yyvsp[(3) - (7)].str),(yyvsp[(4) - (7)].str),Vector((yyvsp[(5) - (7)].real),(yyvsp[(6) - (7)].real)),(Coord::InternalSystem)(yyvsp[(7) - (7)].integer));;} break; case 328: #line 956 "parser.Y" {fr->getMinMaxCmd();;} break; case 331: #line 959 "parser.Y" {fr->getNANColorCmd();;} break; case 332: #line 960 "parser.Y" {fr->getOrientCmd();;} break; case 334: #line 963 "parser.Y" {fr->getPixelTableCmd(Vector((yyvsp[(4) - (8)].real),(yyvsp[(5) - (8)].real)), (Coord::InternalSystem)(yyvsp[(3) - (8)].integer), (yyvsp[(6) - (8)].integer), (yyvsp[(7) - (8)].integer), (yyvsp[(8) - (8)].str));;} break; case 338: #line 967 "parser.Y" {fr->getThreadsCmd();;} break; case 340: #line 969 "parser.Y" {fr->getTypeCmd();;} break; case 341: #line 971 "parser.Y" {fr->getValueCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)),(Coord::InternalSystem)(yyvsp[(2) - (4)].integer));;} break; case 342: #line 973 "parser.Y" {fr->getVertCutCmd((yyvsp[(3) - (7)].str),(yyvsp[(4) - (7)].str),Vector((yyvsp[(5) - (7)].real),(yyvsp[(6) - (7)].real)),(Coord::InternalSystem)(yyvsp[(7) - (7)].integer));;} break; case 345: #line 978 "parser.Y" {fr->getBinDepthCmd();;} break; case 346: #line 979 "parser.Y" {fr->getBinFactorCmd();;} break; case 347: #line 980 "parser.Y" {fr->getBinFunctionCmd();;} break; case 348: #line 981 "parser.Y" {fr->getBinBufferSizeCmd();;} break; case 349: #line 982 "parser.Y" {fr->getBinCursorCmd();;} break; case 350: #line 983 "parser.Y" {fr->getBinFilterCmd();;} break; case 352: #line 985 "parser.Y" {fr->getBinListCmd();;} break; case 353: #line 988 "parser.Y" {fr->getBinColsCmd();;} break; case 354: #line 989 "parser.Y" {fr->getBinColsMinMaxCmd((yyvsp[(2) - (2)].str));;} break; case 355: #line 990 "parser.Y" {fr->getBinColsDimCmd((yyvsp[(2) - (2)].str));;} break; case 357: #line 994 "parser.Y" {fr->getClipScopeCmd();;} break; case 358: #line 995 "parser.Y" {fr->getClipModeCmd();;} break; case 360: #line 997 "parser.Y" {fr->getClipUserCmd();;} break; case 362: #line 999 "parser.Y" {fr->getClipPreserveCmd();;} break; case 363: #line 1002 "parser.Y" {fr->getClipCmd();;} break; case 364: #line 1003 "parser.Y" {fr->getClipCmd((yyvsp[(1) - (1)].real));;} break; case 365: #line 1004 "parser.Y" {fr->getClipCmd(FrScale::MINMAX);;} break; case 366: #line 1005 "parser.Y" {fr->getClipCmd(FrScale::ZSCALE);;} break; case 367: #line 1006 "parser.Y" {fr->getClipCmd(FrScale::ZMAX);;} break; case 368: #line 1007 "parser.Y" {fr->getClipCmd(FrScale::USERCLIP);;} break; case 369: #line 1010 "parser.Y" {fr->getClipMinMaxModeCmd();;} break; case 370: #line 1011 "parser.Y" {fr->getClipMinMaxSampleCmd();;} break; case 371: #line 1014 "parser.Y" {fr->getClipZScaleContrastCmd();;} break; case 372: #line 1015 "parser.Y" {fr->getClipZScaleSampleCmd();;} break; case 373: #line 1016 "parser.Y" {fr->getClipZScaleLineCmd();;} break; case 374: #line 1019 "parser.Y" {fr->getColorbarCmd();;} break; case 375: #line 1020 "parser.Y" {fr->getColorbarTagCmd();;} break; case 377: #line 1026 "parser.Y" {fr->getColorMapLevelCmd((yyvsp[(1) - (1)].integer));;} break; case 378: #line 1028 "parser.Y" {fr->getColorMapLevelCmd((yyvsp[(1) - (4)].integer),Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)),(Coord::InternalSystem)(yyvsp[(2) - (4)].integer));;} break; case 379: #line 1030 "parser.Y" {fr->getColorMapLevelCmd((yyvsp[(1) - (5)].integer),(yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real),(FrScale::ColorScaleType)(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].real));;} break; case 380: #line 1033 "parser.Y" {fr->getColorScaleCmd();;} break; case 382: #line 1035 "parser.Y" {fr->getColorScaleLogCmd();;} break; case 383: #line 1039 "parser.Y" {fr->getColorScaleLevelCmd((yyvsp[(1) - (5)].integer),(yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real),(FrScale::ColorScaleType)(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].real));;} break; case 384: #line 1043 "parser.Y" {fr->getContourCmd((Coord::CoordSystem)(yyvsp[(1) - (2)].integer),(Coord::SkyFrame)(yyvsp[(2) - (2)].integer));;} break; case 387: #line 1046 "parser.Y" {fr->getContourColorNameCmd();;} break; case 388: #line 1047 "parser.Y" {fr->getContourDashCmd();;} break; case 389: #line 1048 "parser.Y" {fr->getContourLevelCmd();;} break; case 390: #line 1049 "parser.Y" {fr->getContourNumLevelCmd();;} break; case 391: #line 1050 "parser.Y" {fr->getContourMethodCmd();;} break; case 393: #line 1052 "parser.Y" {fr->getContourSmoothCmd();;} break; case 394: #line 1053 "parser.Y" {fr->getContourLineWidthCmd();;} break; case 395: #line 1056 "parser.Y" {fr->getContourAuxColorNameCmd();;} break; case 396: #line 1057 "parser.Y" {fr->getContourAuxDashCmd();;} break; case 397: #line 1058 "parser.Y" {fr->getContourAuxLineWidthCmd();;} break; case 398: #line 1061 "parser.Y" {fr->getContourClipCmd();;} break; case 399: #line 1062 "parser.Y" {fr->getContourClipModeCmd();;} break; case 400: #line 1065 "parser.Y" {fr->getContourScaleCmd();;} break; case 401: #line 1066 "parser.Y" {fr->getContourScaleLogCmd();;} break; case 402: #line 1070 "parser.Y" {fr->getCoordCmd(Vector((yyvsp[(1) - (5)].real),(yyvsp[(2) - (5)].real)), (Coord::CoordSystem)(yyvsp[(3) - (5)].integer), (Coord::SkyFrame)(yyvsp[(4) - (5)].integer), (Coord::SkyFormat)(yyvsp[(5) - (5)].integer));;} break; case 403: #line 1073 "parser.Y" { // backward compatibility fr->getCoordCmd(Vector((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real)), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer), (Coord::SkyFormat)(yyvsp[(6) - (6)].integer)); ;} break; case 404: #line 1079 "parser.Y" {fr->getCoordFromRefCmd((yyvsp[(1) - (3)].real), (Coord::CoordSystem)(yyvsp[(2) - (3)].integer), (yyvsp[(3) - (3)].integer));;} break; case 405: #line 1081 "parser.Y" {fr->getCoordFromRefCmd((yyvsp[(2) - (4)].real), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (yyvsp[(4) - (4)].integer));;} break; case 406: #line 1083 "parser.Y" {fr->getCoordToRefCmd((yyvsp[(2) - (4)].real), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (yyvsp[(4) - (4)].integer));;} break; case 407: #line 1087 "parser.Y" {fr->getCropCmd((Coord::CoordSystem)(yyvsp[(1) - (3)].integer), (Coord::SkyFrame)(yyvsp[(2) - (3)].integer), (Coord::SkyFormat)(yyvsp[(3) - (3)].integer));;} break; case 408: #line 1089 "parser.Y" {fr->getCropCenterCmd((Coord::CoordSystem)(yyvsp[(2) - (6)].integer), (Coord::SkyFrame)(yyvsp[(3) - (6)].integer), (Coord::SkyFormat)(yyvsp[(4) - (6)].integer), (Coord::CoordSystem)(yyvsp[(5) - (6)].integer), (Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 409: #line 1091 "parser.Y" {fr->getCrop3dCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 410: #line 1094 "parser.Y" {fr->getCrosshairCmd((Coord::InternalSystem)(yyvsp[(1) - (1)].integer));;} break; case 411: #line 1096 "parser.Y" {fr->getCrosshairCmd((Coord::CoordSystem)(yyvsp[(1) - (4)].integer), (Coord::SkyFrame)(yyvsp[(2) - (4)].integer), (Coord::SkyFormat)(yyvsp[(3) - (4)].integer), (Base::Precision)(yyvsp[(4) - (4)].integer));} break; case 412: #line 1098 "parser.Y" {fr->getCrosshairStatusCmd();;} break; case 413: #line 1101 "parser.Y" {fr->getCursorCmd((Coord::InternalSystem)(yyvsp[(1) - (1)].integer));;} break; case 414: #line 1103 "parser.Y" {fr->getCursorCmd((Coord::CoordSystem)(yyvsp[(1) - (4)].integer), (Coord::SkyFrame)(yyvsp[(2) - (4)].integer), (Coord::SkyFormat)(yyvsp[(3) - (4)].integer), (Base::Precision)(yyvsp[(4) - (4)].integer));;} break; case 415: #line 1108 "parser.Y" {fr->getDataValuesCmd(1, Vector((yyvsp[(3) - (6)].vector)), (Coord::CoordSystem)(yyvsp[(1) - (6)].integer), (Coord::SkyFrame)(yyvsp[(2) - (6)].integer), Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)), (yyvsp[(6) - (6)].str));;} break; case 416: #line 1111 "parser.Y" {fr->getDataValuesCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(4) - (7)].vector)), (Coord::CoordSystem)(yyvsp[(2) - (7)].integer), (Coord::SkyFrame)(yyvsp[(3) - (7)].integer), Vector((yyvsp[(5) - (7)].real),(yyvsp[(6) - (7)].real)), (yyvsp[(7) - (7)].str));;} break; case 417: #line 1114 "parser.Y" {fr->getDataValuesCmd(Vector((yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real)),(Coord::InternalSystem)(yyvsp[(1) - (5)].integer), Vector((yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].integer)));;} break; case 418: #line 1118 "parser.Y" {fr->getInfoCmd((yyvsp[(1) - (1)].str));;} break; case 419: #line 1119 "parser.Y" {fr->getInfoClipCmd();;} break; case 420: #line 1121 "parser.Y" {fr->getInfoCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)), (Coord::InternalSystem)(yyvsp[(1) - (4)].integer), (yyvsp[(4) - (4)].str));;} break; case 421: #line 1124 "parser.Y" {fr->iisGetCmd((char*)(yyvsp[(1) - (5)].ptr),(yyvsp[(2) - (5)].integer),(yyvsp[(3) - (5)].integer),(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].integer));;} break; case 422: #line 1125 "parser.Y" {fr->iisGetCursorCmd();;} break; case 423: #line 1126 "parser.Y" {fr->getWidthCmd();;} break; case 424: #line 1127 "parser.Y" {fr->getHeightCmd();;} break; case 426: #line 1131 "parser.Y" {fr->iisGetFileNameCmd();;} break; case 427: #line 1132 "parser.Y" {fr->iisGetFileNameCmd((yyvsp[(1) - (1)].integer));;} break; case 428: #line 1133 "parser.Y" {fr->iisGetFileNameCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 429: #line 1136 "parser.Y" {fr->getFitsNAxesCmd();;} break; case 430: #line 1138 "parser.Y" {fr->getFitsCenterCmd((Coord::CoordSystem)(yyvsp[(2) - (5)].integer),(Coord::SkyFrame)(yyvsp[(3) - (5)].integer),(Coord::SkyFormat)(yyvsp[(4) - (5)].integer), (Base::Precision)(yyvsp[(5) - (5)].integer));;} break; case 431: #line 1140 "parser.Y" {fr->getFitsCountCmd();;} break; case 433: #line 1142 "parser.Y" {fr->getBitpixCmd();;} break; case 434: #line 1144 "parser.Y" {fr->getFitsExtCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)),(Coord::InternalSystem)(yyvsp[(2) - (4)].integer));;} break; case 437: #line 1147 "parser.Y" {fr->getHeightCmd();;} break; case 438: #line 1148 "parser.Y" {fr->getFitsObjectNameCmd();;} break; case 439: #line 1149 "parser.Y" {fr->getFitsSizeCmd();;} break; case 440: #line 1151 "parser.Y" {fr->getFitsSizeCmd((Coord::CoordSystem)(yyvsp[(2) - (5)].integer),(Coord::SkyFrame)(yyvsp[(3) - (5)].integer),(Coord::SkyDist)(yyvsp[(4) - (5)].integer), (Base::Precision)(yyvsp[(5) - (5)].integer));;} break; case 442: #line 1154 "parser.Y" {fr->getWidthCmd();;} break; case 443: #line 1157 "parser.Y" {fr->getFitsHeaderCmd((yyvsp[(1) - (1)].integer));;} break; case 444: #line 1158 "parser.Y" {fr->getFitsHeaderKeywordCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 445: #line 1159 "parser.Y" {fr->getFitsHeaderWCSCmd((yyvsp[(2) - (2)].integer));;} break; case 446: #line 1162 "parser.Y" {fr->getFitsDepthCmd(2);;} break; case 447: #line 1163 "parser.Y" {fr->getFitsDepthCmd((yyvsp[(1) - (1)].integer));;} break; case 448: #line 1167 "parser.Y" {fr->getFitsFileNameCmd((Base::FileNameType)(yyvsp[(1) - (1)].integer));;} break; case 449: #line 1169 "parser.Y" {fr->getFitsFileNameCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)), (Coord::InternalSystem)(yyvsp[(2) - (4)].integer), (Base::FileNameType)(yyvsp[(1) - (4)].integer));;} break; case 450: #line 1172 "parser.Y" {fr->getFitsFileNameCmd((yyvsp[(2) - (2)].integer), (Base::FileNameType)(yyvsp[(1) - (2)].integer));;} break; case 451: #line 1175 "parser.Y" {fr->getFitsSliceCmd(2);;} break; case 452: #line 1176 "parser.Y" {fr->getFitsSliceCmd((yyvsp[(1) - (1)].integer));;} break; case 453: #line 1179 "parser.Y" {fr->getGridCmd();;} break; case 454: #line 1180 "parser.Y" {fr->getGridOptionCmd();;} break; case 455: #line 1181 "parser.Y" {fr->getGridVarsCmd();;} break; case 456: #line 1184 "parser.Y" {fr->getMaskColorCmd();;} break; case 457: #line 1185 "parser.Y" {fr->getMaskMarkCmd();;} break; case 458: #line 1186 "parser.Y" {fr->getMaskTransparencyCmd();;} break; case 459: #line 1189 "parser.Y" {fr->getPanPreserveCmd();;} break; case 460: #line 1192 "parser.Y" {fr->getRGBChannelCmd();;} break; case 461: #line 1193 "parser.Y" {fr->getRGBSystemCmd();;} break; case 462: #line 1194 "parser.Y" {fr->getRGBViewCmd();;} break; case 463: #line 1197 "parser.Y" {fr->getRotateCmd((Base::Precision)(yyvsp[(1) - (1)].integer));;} break; case 464: #line 1200 "parser.Y" {fr->getSmoothFunctionCmd();;} break; case 465: #line 1201 "parser.Y" {fr->getSmoothRadiusCmd();;} break; case 470: #line 1208 "parser.Y" {fr->get3dRenderMethodCmd();;} break; case 471: #line 1209 "parser.Y" {fr->get3dScaleCmd();;} break; case 472: #line 1212 "parser.Y" {fr->get3dBorderCmd();;} break; case 473: #line 1213 "parser.Y" {fr->get3dBorderColorCmd();;} break; case 474: #line 1216 "parser.Y" {fr->get3dCompassCmd();;} break; case 475: #line 1217 "parser.Y" {fr->get3dCompassColorCmd();;} break; case 476: #line 1220 "parser.Y" {fr->get3dHighliteCmd();;} break; case 477: #line 1221 "parser.Y" {fr->get3dHighliteColorCmd();;} break; case 478: #line 1224 "parser.Y" {fr->get3dViewCmd();;} break; case 479: #line 1225 "parser.Y" {fr->get3dViewPointCmd();;} break; case 480: #line 1228 "parser.Y" {fr->getWCSCmd();;} break; case 482: #line 1230 "parser.Y" {fr->getWCSNameCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 483: #line 1233 "parser.Y" {fr->getWCSAlignCmd();;} break; case 484: #line 1234 "parser.Y" {fr->getWCSAlignPointerCmd();;} break; case 485: #line 1237 "parser.Y" {fr->getZoomCmd((Base::Precision)(yyvsp[(1) - (1)].integer));;} break; case 487: #line 1241 "parser.Y" {fr->gridDeleteCmd();;} break; case 488: #line 1245 "parser.Y" {fr->gridCmd((Coord::CoordSystem)(yyvsp[(1) - (6)].integer), (Coord::SkyFrame)(yyvsp[(2) - (6)].integer), (Coord::SkyFormat)(yyvsp[(3) - (6)].integer), (Grid2d::GridType)(yyvsp[(4) - (6)].integer), (yyvsp[(5) - (6)].str), (yyvsp[(6) - (6)].str));;} break; case 489: #line 1248 "parser.Y" { // backward compatibility with backup fr->gridCmd((Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (Coord::SkyFrame)(yyvsp[(2) - (5)].integer), (Coord::SkyFormat)(yyvsp[(3) - (5)].integer), (Grid2d::GridType)(yyvsp[(4) - (5)].integer), (yyvsp[(5) - (5)].str), ""); ;} break; case 490: #line 1254 "parser.Y" {(yyval.integer)=Grid2d::ANALYSIS;;} break; case 491: #line 1255 "parser.Y" {(yyval.integer)=Grid2d::PUBLICATION;;} break; case 492: #line 1258 "parser.Y" {fr->hasAmplifierCmd();;} break; case 495: #line 1261 "parser.Y" {fr->hasCropCmd();;} break; case 496: #line 1262 "parser.Y" {fr->hasDATAMINCmd();;} break; case 497: #line 1263 "parser.Y" {fr->hasDATASECCmd();;} break; case 498: #line 1264 "parser.Y" {fr->hasDetectorCmd();;} break; case 500: #line 1266 "parser.Y" {fr->hasGridCmd();;} break; case 501: #line 1267 "parser.Y" {fr->hasIISCmd();;} break; case 502: #line 1268 "parser.Y" {fr->hasIRAFMINCmd();;} break; case 504: #line 1270 "parser.Y" {fr->hasPhysicalCmd();;} break; case 505: #line 1271 "parser.Y" {fr->hasSmoothCmd();;} break; case 506: #line 1272 "parser.Y" {fr->hasSystemCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 508: #line 1276 "parser.Y" {fr->hasBinColCmd((yyvsp[(2) - (2)].str));;} break; case 509: #line 1279 "parser.Y" {fr->hasContourCmd();;} break; case 510: #line 1280 "parser.Y" {fr->hasContourAuxCmd();;} break; case 511: #line 1283 "parser.Y" {fr->hasFitsCmd();;} break; case 512: #line 1284 "parser.Y" {fr->hasFitsBinCmd();;} break; case 513: #line 1285 "parser.Y" {fr->hasFitsCubeCmd();;} break; case 514: #line 1286 "parser.Y" {fr->hasFitsMosaicCmd();;} break; case 515: #line 1289 "parser.Y" {fr->hasMarkerHighlitedCmd();;} break; case 516: #line 1290 "parser.Y" {fr->hasMarkerSelectedCmd();;} break; case 517: #line 1291 "parser.Y" {fr->hasMarkerPasteCmd();;} break; case 518: #line 1292 "parser.Y" {fr->hasMarkerUndoCmd();;} break; case 519: #line 1295 "parser.Y" {fr->hasWCSCmd((Coord::CoordSystem)(yyvsp[(1) - (1)].integer));;} break; case 520: #line 1296 "parser.Y" {fr->hasWCSEquCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 521: #line 1297 "parser.Y" {fr->hasWCSCelCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 522: #line 1298 "parser.Y" {fr->hasWCSAltCmd();;} break; case 523: #line 1299 "parser.Y" {fr->hasWCSxCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 524: #line 1302 "parser.Y" {fr->iisCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 525: #line 1303 "parser.Y" {fr->iisEraseCmd();;} break; case 526: #line 1304 "parser.Y" {fr->iisMessageCmd((yyvsp[(2) - (2)].str));;} break; case 529: #line 1308 "parser.Y" {fr->iisSetCmd((const char*)(yyvsp[(2) - (6)].ptr),(yyvsp[(3) - (6)].integer),(yyvsp[(4) - (6)].integer),(yyvsp[(5) - (6)].integer),(yyvsp[(6) - (6)].integer));;} break; case 530: #line 1309 "parser.Y" {fr->iisUpdateCmd();;} break; case 531: #line 1312 "parser.Y" {fr->iisWCSCmd(Matrix((yyvsp[(2) - (10)].real),(yyvsp[(3) - (10)].real),(yyvsp[(4) - (10)].real),(yyvsp[(5) - (10)].real),(yyvsp[(6) - (10)].real),(yyvsp[(7) - (10)].real)),Vector((yyvsp[(8) - (10)].real),(yyvsp[(9) - (10)].real)),(yyvsp[(10) - (10)].integer));;} break; case 532: #line 1315 "parser.Y" {fr->iisSetFileNameCmd((yyvsp[(1) - (1)].str));;} break; case 533: #line 1316 "parser.Y" {fr->iisSetFileNameCmd((yyvsp[(1) - (2)].str),(yyvsp[(2) - (2)].integer));;} break; case 534: #line 1320 "parser.Y" {fr->iisSetCursorCmd(Vector((yyvsp[(1) - (3)].integer),(yyvsp[(2) - (3)].integer)),Coord::CANVAS);;} break; case 535: #line 1322 "parser.Y" {fr->iisSetCursorCmd(Vector((yyvsp[(1) - (3)].integer),(yyvsp[(2) - (3)].integer)),(Coord::CoordSystem)(yyvsp[(3) - (3)].integer));;} break; case 536: #line 1323 "parser.Y" {fr->iisCursorModeCmd((yyvsp[(2) - (2)].integer));;} break; case 542: #line 1334 "parser.Y" {fr->loadArrAllocCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 543: #line 1336 "parser.Y" {fr->loadArrAllocGZCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 544: #line 1338 "parser.Y" {fr->loadArrChannelCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 545: #line 1340 "parser.Y" {fr->loadArrMMapCmd((yyvsp[(1) - (3)].str), (Base::LayerType)(yyvsp[(3) - (3)].integer));;} break; case 546: #line 1342 "parser.Y" {fr->loadArrMMapIncrCmd((yyvsp[(1) - (3)].str), (Base::LayerType)(yyvsp[(3) - (3)].integer));;} break; case 547: #line 1344 "parser.Y" {fr->loadArrShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 548: #line 1347 "parser.Y" {fr->loadArrSocketCmd((yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 549: #line 1349 "parser.Y" {fr->loadArrSocketGZCmd((yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 550: #line 1351 "parser.Y" {fr->loadArrVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 552: #line 1355 "parser.Y" {fr->loadArrayRGBCubeAllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 553: #line 1356 "parser.Y" {fr->loadArrayRGBCubeAllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 554: #line 1357 "parser.Y" {fr->loadArrayRGBCubeChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 555: #line 1358 "parser.Y" {fr->loadArrayRGBCubeMMapCmd((yyvsp[(1) - (2)].str));;} break; case 556: #line 1359 "parser.Y" {fr->loadArrayRGBCubeMMapIncrCmd((yyvsp[(1) - (2)].str));;} break; case 557: #line 1361 "parser.Y" {fr->loadArrayRGBCubeShareCmd((Base::ShmType)(yyvsp[(3) - (4)].integer), (yyvsp[(4) - (4)].integer), (yyvsp[(1) - (4)].str));;} break; case 558: #line 1362 "parser.Y" {fr->loadArrayRGBCubeSocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 559: #line 1363 "parser.Y" {fr->loadArrayRGBCubeSocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 560: #line 1364 "parser.Y" {fr->loadArrayRGBCubeVarCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 561: #line 1368 "parser.Y" {fr->loadFitsAllocCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 562: #line 1370 "parser.Y" {fr->loadFitsAllocGZCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 563: #line 1372 "parser.Y" {fr->loadFitsChannelCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 564: #line 1374 "parser.Y" {fr->loadFitsMMapCmd((yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 565: #line 1377 "parser.Y" {fr->loadFitsSMMapCmd((yyvsp[(1) - (5)].str), (yyvsp[(2) - (5)].str),(Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 566: #line 1380 "parser.Y" {fr->loadFitsMMapIncrCmd((yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 567: #line 1383 "parser.Y" {fr->loadFitsShareCmd((Base::ShmType)(yyvsp[(3) - (6)].integer), (yyvsp[(4) - (6)].integer), (yyvsp[(1) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer),(Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 568: #line 1386 "parser.Y" {fr->loadFitsSShareCmd((Base::ShmType)(yyvsp[(3) - (7)].integer), (yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].integer), (yyvsp[(1) - (7)].str), (Base::LoadMethod)(yyvsp[(6) - (7)].integer),(Base::LayerType)(yyvsp[(7) - (7)].integer));;} break; case 569: #line 1389 "parser.Y" {fr->loadFitsSocketCmd((yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 570: #line 1391 "parser.Y" {fr->loadFitsSocketGZCmd((yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 571: #line 1393 "parser.Y" {fr->loadFitsVarCmd((yyvsp[(3) - (5)].str), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 577: #line 1403 "parser.Y" {fr->loadSliceAllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 578: #line 1405 "parser.Y" {fr->loadSliceAllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 579: #line 1407 "parser.Y" {fr->loadSliceChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 580: #line 1409 "parser.Y" {fr->loadSliceMMapCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 581: #line 1411 "parser.Y" {fr->loadSliceSMMapCmd((yyvsp[(1) - (4)].str), (yyvsp[(2) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 582: #line 1413 "parser.Y" {fr->loadSliceMMapIncrCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 583: #line 1415 "parser.Y" {fr->loadSliceShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(5) - (5)].integer));;} break; case 584: #line 1417 "parser.Y" {fr->loadSliceSShareCmd((Base::ShmType)(yyvsp[(3) - (6)].integer), (yyvsp[(4) - (6)].integer), (yyvsp[(5) - (6)].integer), (yyvsp[(1) - (6)].str), (Base::LoadMethod)(yyvsp[(6) - (6)].integer));;} break; case 585: #line 1419 "parser.Y" {fr->loadSliceSocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 586: #line 1421 "parser.Y" {fr->loadSliceSocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 587: #line 1423 "parser.Y" {fr->loadSliceVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 588: #line 1427 "parser.Y" {fr->loadExtCubeAllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 589: #line 1429 "parser.Y" {fr->loadExtCubeAllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 590: #line 1431 "parser.Y" {fr->loadExtCubeChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 591: #line 1433 "parser.Y" {fr->loadExtCubeMMapCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 592: #line 1435 "parser.Y" {fr->loadExtCubeMMapIncrCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 593: #line 1437 "parser.Y" {fr->loadExtCubeShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(5) - (5)].integer));;} break; case 594: #line 1440 "parser.Y" {fr->loadExtCubeSocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 595: #line 1442 "parser.Y" {fr->loadExtCubeSocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 596: #line 1444 "parser.Y" {fr->loadExtCubeVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 602: #line 1455 "parser.Y" {fr->loadMosaicImageAllocCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 603: #line 1458 "parser.Y" {fr->loadMosaicImageAllocGZCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str),(Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 604: #line 1461 "parser.Y" {fr->loadMosaicImageChannelCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str),(Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 605: #line 1464 "parser.Y" {fr->loadMosaicImageMMapCmd(Base::IRAF, Coord::WCS, (yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 606: #line 1467 "parser.Y" {fr->loadMosaicImageMMapIncrCmd(Base::IRAF, Coord::WCS, (yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 607: #line 1470 "parser.Y" {fr->loadMosaicImageShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)(yyvsp[(3) - (6)].integer), (yyvsp[(4) - (6)].integer), (yyvsp[(1) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer), (Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 608: #line 1474 "parser.Y" {fr->loadMosaicImageSocketCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 609: #line 1477 "parser.Y" {fr->loadMosaicImageSocketGZCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 610: #line 1480 "parser.Y" {fr->loadMosaicImageVarCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (5)].str), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 611: #line 1485 "parser.Y" {fr->loadMosaicAllocCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 612: #line 1488 "parser.Y" {fr->loadMosaicAllocGZCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 613: #line 1491 "parser.Y" {fr->loadMosaicChannelCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 614: #line 1494 "parser.Y" {fr->loadMosaicMMapCmd(Base::IRAF, Coord::WCS, (yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 615: #line 1497 "parser.Y" {fr->loadMosaicSMMapCmd(Base::IRAF, Coord::WCS, (yyvsp[(1) - (5)].str), (yyvsp[(2) - (5)].str),(Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 616: #line 1500 "parser.Y" {fr->loadMosaicMMapIncrCmd(Base::IRAF, Coord::WCS, (yyvsp[(1) - (4)].str),(Base::LoadMethod)(yyvsp[(3) - (4)].integer), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 617: #line 1503 "parser.Y" {fr->loadMosaicShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)(yyvsp[(3) - (6)].integer), (yyvsp[(4) - (6)].integer), (yyvsp[(1) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer), (Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 618: #line 1507 "parser.Y" {fr->loadMosaicSShareCmd(Base::IRAF, Coord::WCS, (Base::ShmType)(yyvsp[(3) - (7)].integer), (yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].integer), (yyvsp[(1) - (7)].str), (Base::LoadMethod)(yyvsp[(6) - (7)].integer), (Base::LayerType)(yyvsp[(7) - (7)].integer));;} break; case 619: #line 1511 "parser.Y" {fr->loadMosaicSocketCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 620: #line 1514 "parser.Y" {fr->loadMosaicSocketGZCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 621: #line 1517 "parser.Y" {fr->loadMosaicVarCmd(Base::IRAF, Coord::WCS, (yyvsp[(3) - (5)].str), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 622: #line 1522 "parser.Y" {fr->loadMosaicImageAllocCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 623: #line 1525 "parser.Y" {fr->loadMosaicImageAllocGZCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 624: #line 1528 "parser.Y" {fr->loadMosaicImageChannelCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 625: #line 1531 "parser.Y" {fr->loadMosaicImageMMapCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 626: #line 1534 "parser.Y" {fr->loadMosaicImageMMapIncrCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 627: #line 1537 "parser.Y" {fr->loadMosaicImageShareCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (7)].integer), (Base::ShmType)(yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].integer), (yyvsp[(2) - (7)].str), (Base::LoadMethod)(yyvsp[(6) - (7)].integer), (Base::LayerType)(yyvsp[(7) - (7)].integer));;} break; case 628: #line 1541 "parser.Y" {fr->loadMosaicImageSocketCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 629: #line 1544 "parser.Y" {fr->loadMosaicImageSocketGZCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 630: #line 1547 "parser.Y" {fr->loadMosaicImageVarCmd(Base::WCSMOSAIC, (Coord::CoordSystem)(yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].str), (yyvsp[(2) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer), (Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 631: #line 1552 "parser.Y" {fr->loadMosaicAllocCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 632: #line 1555 "parser.Y" {fr->loadMosaicAllocGZCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 633: #line 1558 "parser.Y" {fr->loadMosaicChannelCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].str), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 634: #line 1561 "parser.Y" {fr->loadMosaicMMapCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 635: #line 1564 "parser.Y" {fr->loadMosaicSMMapCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (6)].integer), (yyvsp[(2) - (6)].str), (yyvsp[(3) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer), (Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 636: #line 1567 "parser.Y" {fr->loadMosaicMMapIncrCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LoadMethod)(yyvsp[(4) - (5)].integer), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 637: #line 1570 "parser.Y" {fr->loadMosaicShareCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (7)].integer), (Base::ShmType)(yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].integer), (yyvsp[(2) - (7)].str), (Base::LoadMethod)(yyvsp[(6) - (7)].integer), (Base::LayerType)(yyvsp[(7) - (7)].integer));;} break; case 638: #line 1574 "parser.Y" {fr->loadMosaicSShareCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (8)].integer), (Base::ShmType)(yyvsp[(4) - (8)].integer), (yyvsp[(5) - (8)].integer), (yyvsp[(6) - (8)].integer), (yyvsp[(2) - (8)].str), (Base::LoadMethod)(yyvsp[(7) - (8)].integer), (Base::LayerType)(yyvsp[(8) - (8)].integer));;} break; case 639: #line 1578 "parser.Y" {fr->loadMosaicSocketCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 640: #line 1581 "parser.Y" {fr->loadMosaicSocketGZCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(2) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 641: #line 1584 "parser.Y" {fr->loadMosaicVarCmd((Base::WCSMOSAIC), (Coord::CoordSystem)(yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].str), (yyvsp[(2) - (6)].str), (Base::LoadMethod)(yyvsp[(5) - (6)].integer), (Base::LayerType)(yyvsp[(6) - (6)].integer));;} break; case 642: #line 1589 "parser.Y" {fr->loadMosaicImageWFPC2AllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 643: #line 1591 "parser.Y" {fr->loadMosaicImageWFPC2AllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 644: #line 1593 "parser.Y" {fr->loadMosaicImageWFPC2ChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 645: #line 1595 "parser.Y" {fr->loadMosaicImageWFPC2MMapCmd((yyvsp[(1) - (3)].str),(Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 646: #line 1597 "parser.Y" {fr->loadMosaicImageWFPC2MMapIncrCmd((yyvsp[(1) - (3)].str),(Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 647: #line 1599 "parser.Y" {fr->loadMosaicImageWFPC2ShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(5) - (5)].integer));;} break; case 648: #line 1602 "parser.Y" {fr->loadMosaicImageWFPC2SocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 649: #line 1604 "parser.Y" {fr->loadMosaicImageWFPC2SocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 650: #line 1606 "parser.Y" {fr->loadMosaicImageWFPC2VarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 651: #line 1608 "parser.Y" {fr->loadRGBCubeAllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 652: #line 1609 "parser.Y" {fr->loadRGBCubeAllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 653: #line 1610 "parser.Y" {fr->loadRGBCubeChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 654: #line 1612 "parser.Y" {fr->loadRGBCubeMMapCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 655: #line 1614 "parser.Y" {fr->loadRGBCubeSMMapCmd((yyvsp[(1) - (4)].str), (yyvsp[(2) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 656: #line 1616 "parser.Y" {fr->loadRGBCubeMMapIncrCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 657: #line 1618 "parser.Y" {fr->loadRGBCubeShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(5) - (5)].integer));;} break; case 658: #line 1621 "parser.Y" {fr->loadRGBCubeSShareCmd((Base::ShmType)(yyvsp[(3) - (6)].integer), (yyvsp[(4) - (6)].integer), (yyvsp[(5) - (6)].integer), (yyvsp[(1) - (6)].str), (Base::LoadMethod)(yyvsp[(6) - (6)].integer));;} break; case 659: #line 1623 "parser.Y" {fr->loadRGBCubeSocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 660: #line 1624 "parser.Y" {fr->loadRGBCubeSocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 661: #line 1626 "parser.Y" {fr->loadRGBCubeVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 662: #line 1629 "parser.Y" {fr->loadRGBImageAllocCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 663: #line 1630 "parser.Y" {fr->loadRGBImageAllocGZCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 664: #line 1631 "parser.Y" {fr->loadRGBImageChannelCmd((yyvsp[(3) - (3)].str), (yyvsp[(1) - (3)].str));;} break; case 665: #line 1633 "parser.Y" {fr->loadRGBImageMMapCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 666: #line 1635 "parser.Y" {fr->loadRGBImageMMapIncrCmd((yyvsp[(1) - (3)].str), (Base::LoadMethod)(yyvsp[(3) - (3)].integer));;} break; case 667: #line 1637 "parser.Y" {fr->loadRGBImageShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LoadMethod)(yyvsp[(5) - (5)].integer));;} break; case 668: #line 1639 "parser.Y" {fr->loadRGBImageSocketCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 669: #line 1640 "parser.Y" {fr->loadRGBImageSocketGZCmd((yyvsp[(3) - (3)].integer), (yyvsp[(1) - (3)].str));;} break; case 670: #line 1642 "parser.Y" {fr->loadRGBImageVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LoadMethod)(yyvsp[(4) - (4)].integer));;} break; case 671: #line 1646 "parser.Y" {fr->loadNRRDAllocCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 672: #line 1648 "parser.Y" {fr->loadNRRDChannelCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 673: #line 1650 "parser.Y" {fr->loadNRRDMMapCmd((yyvsp[(1) - (3)].str), (Base::LayerType)(yyvsp[(3) - (3)].integer));;} break; case 674: #line 1652 "parser.Y" {fr->loadNRRDShareCmd((Base::ShmType)(yyvsp[(3) - (5)].integer), (yyvsp[(4) - (5)].integer), (yyvsp[(1) - (5)].str), (Base::LayerType)(yyvsp[(5) - (5)].integer));;} break; case 675: #line 1655 "parser.Y" {fr->loadNRRDSocketCmd((yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 676: #line 1657 "parser.Y" {fr->loadNRRDVarCmd((yyvsp[(3) - (4)].str), (yyvsp[(1) - (4)].str), (Base::LayerType)(yyvsp[(4) - (4)].integer));;} break; case 677: #line 1660 "parser.Y" {fr->loadPhotoCmd((yyvsp[(1) - (2)].str),(yyvsp[(2) - (2)].str));;} break; case 678: #line 1661 "parser.Y" {fr->loadSlicePhotoCmd((yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 679: #line 1664 "parser.Y" {fr->loadIncrDataCmd((yyvsp[(2) - (6)].integer),(yyvsp[(3) - (6)].integer),(yyvsp[(4) - (6)].integer),(yyvsp[(5) - (6)].integer),(yyvsp[(6) - (6)].integer));;} break; case 680: #line 1665 "parser.Y" {fr->loadIncrMinMaxCmd((yyvsp[(2) - (6)].integer),(yyvsp[(3) - (6)].integer),(yyvsp[(4) - (6)].integer),(yyvsp[(5) - (6)].integer),(yyvsp[(6) - (6)].integer));;} break; case 681: #line 1666 "parser.Y" {fr->loadIncrEndCmd();;} break; case 682: #line 1669 "parser.Y" { #ifdef _MACOSX fr->macosxPrintCmd(); #endif ;} break; case 683: #line 1676 "parser.Y" {fr->magnifierCmd((yyvsp[(1) - (1)].integer));;} break; case 684: #line 1677 "parser.Y" {fr->magnifierGraphicsCmd((yyvsp[(2) - (2)].integer));;} break; case 685: #line 1678 "parser.Y" {fr->magnifierCursorCmd((yyvsp[(2) - (2)].integer));;} break; case 686: #line 1679 "parser.Y" {fr->magnifierColorCmd((yyvsp[(2) - (2)].str));;} break; case 687: #line 1680 "parser.Y" {fr->magnifierCmd((yyvsp[(1) - (3)].str), (yyvsp[(2) - (3)].integer), (yyvsp[(3) - (3)].integer));;} break; case 688: #line 1681 "parser.Y" {fr->updateMagnifierCmd(Vector((yyvsp[(2) - (3)].real), (yyvsp[(3) - (3)].real)));;} break; case 689: #line 1682 "parser.Y" {fr->magnifierZoomCmd((yyvsp[(2) - (2)].real));;} break; case 691: #line 1686 "parser.Y" {fr->markerColorCmd((yyvsp[(2) - (2)].str));;} break; case 692: #line 1687 "parser.Y" {fr->markerCopyCmd();;} break; case 693: #line 1689 "parser.Y" {fr->markerCommandCmd((Base::MarkerFormat)(yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 694: #line 1691 "parser.Y" {fr->markerCommandVarCmd((Base::MarkerFormat)(yyvsp[(2) - (4)].integer),(yyvsp[(4) - (4)].str));;} break; case 695: #line 1692 "parser.Y" {fr->markerCompositeDeleteCmd();;} break; case 696: #line 1693 "parser.Y" {maperr =0;;} break; case 698: #line 1694 "parser.Y" {fr->markerCutCmd();;} break; case 699: #line 1695 "parser.Y" {fr->markerDeleteCmd();;} break; case 700: #line 1696 "parser.Y" {fr->markerDeleteAllCmd();;} break; case 702: #line 1698 "parser.Y" {fr->markerFontCmd((yyvsp[(2) - (2)].str));;} break; case 703: #line 1700 "parser.Y" {fr->markerHighliteAllCmd();;} break; case 704: #line 1702 "parser.Y" {fr->markerHighliteOnlyCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 705: #line 1704 "parser.Y" {fr->markerHighliteToggleCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 706: #line 1707 "parser.Y" {fr->markerAnalysisCmd((yyvsp[(1) - (4)].integer), (Marker::AnalysisTask)(yyvsp[(3) - (4)].integer), (yyvsp[(4) - (4)].integer));;} break; case 707: #line 1709 "parser.Y" {fr->markerAngleCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].real));;} break; case 708: #line 1710 "parser.Y" {fr->markerAngleCmd((yyvsp[(1) - (4)].integer),(yyvsp[(3) - (4)].real));;} break; case 709: #line 1712 "parser.Y" {fr->markerAngleCmd((yyvsp[(1) - (5)].integer),(yyvsp[(3) - (5)].real),(Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyFrame)(yyvsp[(5) - (5)].integer));;} break; case 710: #line 1715 "parser.Y" {fr->markerAnnulusRadiusCmd((yyvsp[(1) - (7)].integer), (yyvsp[(4) - (7)].real), (yyvsp[(5) - (7)].real), (yyvsp[(6) - (7)].integer), (Coord::InternalSystem)(yyvsp[(7) - (7)].integer));;} break; case 711: #line 1717 "parser.Y" {fr->markerAnnulusRadiusCmd((yyvsp[(1) - (8)].integer), (yyvsp[(4) - (8)].real), (yyvsp[(5) - (8)].real), (yyvsp[(6) - (8)].integer), (Coord::CoordSystem)(yyvsp[(7) - (8)].integer), (Coord::SkyDist)(yyvsp[(8) - (8)].integer));;} break; case 712: #line 1720 "parser.Y" {fr->markerAnnulusRadiusCmd((yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].str),(Coord::CoordSystem)(yyvsp[(5) - (6)].integer),(Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 713: #line 1723 "parser.Y" {fr->markerBoxAnnulusRadiusCmd((yyvsp[(1) - (8)].integer), Vector((yyvsp[(4) - (8)].real), (yyvsp[(5) - (8)].real)), Vector((yyvsp[(6) - (8)].real), (yyvsp[(6) - (8)].real)*(yyvsp[(5) - (8)].real)/(yyvsp[(4) - (8)].real)), (yyvsp[(7) - (8)].integer), (Coord::InternalSystem)(yyvsp[(8) - (8)].integer));;} break; case 714: #line 1727 "parser.Y" {fr->markerBoxAnnulusRadiusCmd((yyvsp[(1) - (9)].integer), Vector((yyvsp[(4) - (9)].real), (yyvsp[(5) - (9)].real)), Vector((yyvsp[(6) - (9)].real), (yyvsp[(6) - (9)].real)*(yyvsp[(5) - (9)].real)/(yyvsp[(4) - (9)].real)), (yyvsp[(7) - (9)].integer), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 715: #line 1730 "parser.Y" {fr->markerBoxAnnulusRadiusCmd((yyvsp[(1) - (6)].integer),(yyvsp[(4) - (6)].str),(Coord::CoordSystem)(yyvsp[(5) - (6)].integer),(Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 716: #line 1733 "parser.Y" {fr->markerBoxRadiusCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)), (Coord::InternalSystem)(yyvsp[(6) - (6)].integer));;} break; case 717: #line 1735 "parser.Y" {fr->markerBoxRadiusCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real)), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyDist)(yyvsp[(7) - (7)].integer));;} break; case 718: #line 1738 "parser.Y" {fr->markerBpandaEditCmd((yyvsp[(1) - (10)].integer), (yyvsp[(4) - (10)].real), (yyvsp[(5) - (10)].real), (yyvsp[(6) - (10)].integer), Vector((yyvsp[(7) - (10)].real),(yyvsp[(8) - (10)].real)), Vector((yyvsp[(9) - (10)].real),(yyvsp[(9) - (10)].real)*(yyvsp[(8) - (10)].real)/(yyvsp[(7) - (10)].real)), (yyvsp[(10) - (10)].integer));;} break; case 719: #line 1742 "parser.Y" {fr->markerBpandaEditCmd((yyvsp[(1) - (11)].integer), (yyvsp[(4) - (11)].real), (yyvsp[(5) - (11)].real), (yyvsp[(6) - (11)].integer), Vector((yyvsp[(7) - (11)].real),(yyvsp[(8) - (11)].real)), Vector((yyvsp[(9) - (11)].real),(yyvsp[(9) - (11)].real)*(yyvsp[(8) - (11)].real)/(yyvsp[(7) - (11)].real)), (yyvsp[(10) - (11)].integer));;} break; case 720: #line 1746 "parser.Y" {fr->markerBpandaEditCmd((yyvsp[(1) - (12)].integer), (yyvsp[(4) - (12)].real), (yyvsp[(5) - (12)].real), (yyvsp[(6) - (12)].integer), Vector((yyvsp[(7) - (12)].real),(yyvsp[(8) - (12)].real)), Vector((yyvsp[(9) - (12)].real),(yyvsp[(9) - (12)].real)*(yyvsp[(8) - (12)].real)/(yyvsp[(7) - (12)].real)), (yyvsp[(10) - (12)].integer), (Coord::CoordSystem)(yyvsp[(11) - (12)].integer), (Coord::SkyFrame)(yyvsp[(12) - (12)].integer));;} break; case 721: #line 1751 "parser.Y" {fr->markerBpandaEditCmd((yyvsp[(1) - (9)].integer), (yyvsp[(4) - (9)].str), (yyvsp[(5) - (9)].str), (Coord::CoordSystem)(yyvsp[(6) - (9)].integer), (Coord::SkyFrame)(yyvsp[(7) - (9)].integer), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 722: #line 1755 "parser.Y" {fr->markerCallBackCmd((yyvsp[(1) - (5)].integer),(CallBack::Type)(yyvsp[(3) - (5)].integer),(yyvsp[(4) - (5)].str),(yyvsp[(5) - (5)].str));;} break; case 723: #line 1757 "parser.Y" {fr->markerCircleRadiusCmd((yyvsp[(1) - (5)].integer), (yyvsp[(4) - (5)].real), (Coord::InternalSystem)(yyvsp[(5) - (5)].integer));;} break; case 724: #line 1759 "parser.Y" {fr->markerCircleRadiusCmd((yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].real), (Coord::CoordSystem)(yyvsp[(5) - (6)].integer), (Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 725: #line 1760 "parser.Y" {fr->markerColorCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 726: #line 1762 "parser.Y" {fr->markerCompassArrowCmd((yyvsp[(1) - (5)].integer),(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].integer));;} break; case 727: #line 1764 "parser.Y" {fr->markerCompassLabelCmd((yyvsp[(1) - (5)].integer),(yyvsp[(4) - (5)].str),(yyvsp[(5) - (5)].str));;} break; case 728: #line 1766 "parser.Y" {fr->markerCompassRadiusCmd((yyvsp[(1) - (5)].integer),(yyvsp[(4) - (5)].real),(Coord::InternalSystem)(yyvsp[(5) - (5)].integer));;} break; case 729: #line 1768 "parser.Y" {fr->markerCompassRadiusCmd((yyvsp[(1) - (6)].integer),(yyvsp[(4) - (6)].real),(Coord::CoordSystem)(yyvsp[(5) - (6)].integer),(Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 730: #line 1770 "parser.Y" {fr->markerCompassSystemCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyFrame)(yyvsp[(5) - (5)].integer));;} break; case 731: #line 1771 "parser.Y" {fr->markerCompositeCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 732: #line 1773 "parser.Y" {fr->markerCpandaEditCmd((yyvsp[(1) - (9)].integer), (yyvsp[(4) - (9)].real), (yyvsp[(5) - (9)].real), (yyvsp[(6) - (9)].integer), (yyvsp[(7) - (9)].real), (yyvsp[(8) - (9)].real), (yyvsp[(9) - (9)].integer));;} break; case 733: #line 1775 "parser.Y" {fr->markerCpandaEditCmd((yyvsp[(1) - (10)].integer), (yyvsp[(4) - (10)].real), (yyvsp[(5) - (10)].real), (yyvsp[(6) - (10)].integer), (yyvsp[(7) - (10)].real), (yyvsp[(8) - (10)].real), (yyvsp[(9) - (10)].integer));;} break; case 734: #line 1778 "parser.Y" {fr->markerCpandaEditCmd((yyvsp[(1) - (11)].integer), (yyvsp[(4) - (11)].real), (yyvsp[(5) - (11)].real), (yyvsp[(6) - (11)].integer), (yyvsp[(7) - (11)].real), (yyvsp[(8) - (11)].real), (yyvsp[(9) - (11)].integer), (Coord::CoordSystem)(yyvsp[(10) - (11)].integer), (Coord::SkyFrame)(yyvsp[(11) - (11)].integer));;} break; case 735: #line 1782 "parser.Y" {fr->markerCpandaEditCmd((yyvsp[(1) - (9)].integer), (yyvsp[(4) - (9)].str), (yyvsp[(5) - (9)].str), (Coord::CoordSystem)(yyvsp[(6) - (9)].integer), (Coord::SkyFrame)(yyvsp[(7) - (9)].integer), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 736: #line 1786 "parser.Y" {fr->markerAnnulusCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 737: #line 1788 "parser.Y" {fr->markerBoxAnnulusCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 738: #line 1790 "parser.Y" {fr->markerBpandaCreateAnglesCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 739: #line 1792 "parser.Y" {fr->markerBpandaCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 740: #line 1794 "parser.Y" {fr->markerEllipseAnnulusCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 741: #line 1796 "parser.Y" {fr->markerEpandaCreateAnglesCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 742: #line 1798 "parser.Y" {fr->markerEpandaCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 743: #line 1800 "parser.Y" {fr->markerCpandaCreateAnglesCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 744: #line 1802 "parser.Y" {fr->markerCpandaCreateRadiusCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)));;} break; case 745: #line 1804 "parser.Y" {fr->markerPolygonCreateVertexCmd((yyvsp[(1) - (7)].integer),(yyvsp[(5) - (7)].integer),Vector((yyvsp[(6) - (7)].real),(yyvsp[(7) - (7)].real)));;} break; case 746: #line 1806 "parser.Y" {fr->markerDeleteCmd((yyvsp[(1) - (2)].integer));;} break; case 747: #line 1808 "parser.Y" {fr->markerAnnulusDeleteRadiusCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 748: #line 1810 "parser.Y" {fr->markerBoxAnnulusDeleteRadiusCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 749: #line 1811 "parser.Y" {fr->markerBpandaDeleteCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 750: #line 1813 "parser.Y" {fr->markerEllipseAnnulusDeleteRadiusCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 751: #line 1815 "parser.Y" {fr->markerDeleteCallBackCmd((yyvsp[(1) - (5)].integer),(CallBack::Type)(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].str));;} break; case 752: #line 1816 "parser.Y" {fr->markerEpandaDeleteCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 753: #line 1817 "parser.Y" {fr->markerCpandaDeleteCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 754: #line 1819 "parser.Y" {fr->markerPolygonDeleteVertexCmd((yyvsp[(1) - (5)].integer),(yyvsp[(5) - (5)].integer));;} break; case 755: #line 1820 "parser.Y" {fr->markerDeleteTagCmd((yyvsp[(1) - (3)].integer));;} break; case 756: #line 1821 "parser.Y" {fr->markerDeleteTagCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].str));;} break; case 757: #line 1822 "parser.Y" {fr->markerDeleteTagCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 758: #line 1824 "parser.Y" {fr->markerEditBeginCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 759: #line 1826 "parser.Y" {fr->markerEllipseRadiusCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(4) - (6)].real), (yyvsp[(5) - (6)].real)), (Coord::InternalSystem)(yyvsp[(6) - (6)].integer));;} break; case 760: #line 1828 "parser.Y" {fr->markerEllipseRadiusCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(4) - (7)].real), (yyvsp[(5) - (7)].real)), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyDist)(yyvsp[(7) - (7)].integer));;} break; case 761: #line 1832 "parser.Y" {fr->markerEllipseAnnulusRadiusCmd((yyvsp[(1) - (8)].integer), Vector((yyvsp[(4) - (8)].real),(yyvsp[(5) - (8)].real)), Vector((yyvsp[(6) - (8)].real),(yyvsp[(6) - (8)].real)*(yyvsp[(5) - (8)].real)/(yyvsp[(4) - (8)].real)), (yyvsp[(7) - (8)].integer), (Coord::InternalSystem)(yyvsp[(8) - (8)].integer));;} break; case 762: #line 1836 "parser.Y" {fr->markerEllipseAnnulusRadiusCmd((yyvsp[(1) - (9)].integer), Vector((yyvsp[(4) - (9)].real),(yyvsp[(5) - (9)].real)), Vector((yyvsp[(6) - (9)].real),(yyvsp[(6) - (9)].real)*(yyvsp[(5) - (9)].real)/(yyvsp[(4) - (9)].real)), (yyvsp[(7) - (9)].integer), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 763: #line 1839 "parser.Y" {fr->markerEllipseAnnulusRadiusCmd((yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].str), (Coord::CoordSystem)(yyvsp[(5) - (6)].integer), (Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 764: #line 1842 "parser.Y" {fr->markerEpandaEditCmd((yyvsp[(1) - (10)].integer), (yyvsp[(4) - (10)].real), (yyvsp[(5) - (10)].real), (yyvsp[(6) - (10)].integer), Vector((yyvsp[(7) - (10)].real),(yyvsp[(8) - (10)].real)), Vector((yyvsp[(9) - (10)].real),(yyvsp[(9) - (10)].real)*(yyvsp[(8) - (10)].real)/(yyvsp[(7) - (10)].real)), (yyvsp[(10) - (10)].integer));;} break; case 765: #line 1846 "parser.Y" {fr->markerEpandaEditCmd((yyvsp[(1) - (11)].integer), (yyvsp[(4) - (11)].real), (yyvsp[(5) - (11)].real), (yyvsp[(6) - (11)].integer), Vector((yyvsp[(7) - (11)].real),(yyvsp[(8) - (11)].real)), Vector((yyvsp[(9) - (11)].real),(yyvsp[(9) - (11)].real)*(yyvsp[(8) - (11)].real)/(yyvsp[(7) - (11)].real)), (yyvsp[(10) - (11)].integer));;} break; case 766: #line 1850 "parser.Y" {fr->markerEpandaEditCmd((yyvsp[(1) - (12)].integer), (yyvsp[(4) - (12)].real), (yyvsp[(5) - (12)].real), (yyvsp[(6) - (12)].integer), Vector((yyvsp[(7) - (12)].real),(yyvsp[(8) - (12)].real)), Vector((yyvsp[(9) - (12)].real),(yyvsp[(9) - (12)].real)*(yyvsp[(8) - (12)].real)/(yyvsp[(7) - (12)].real)), (yyvsp[(10) - (12)].integer), (Coord::CoordSystem)(yyvsp[(11) - (12)].integer), (Coord::SkyFrame)(yyvsp[(12) - (12)].integer));;} break; case 767: #line 1855 "parser.Y" {fr->markerEpandaEditCmd((yyvsp[(1) - (9)].integer), (yyvsp[(4) - (9)].str), (yyvsp[(5) - (9)].str), (Coord::CoordSystem)(yyvsp[(6) - (9)].integer), (Coord::SkyFrame)(yyvsp[(7) - (9)].integer), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 768: #line 1859 "parser.Y" {fr->markerFontCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 769: #line 1860 "parser.Y" {fr->markerHighliteCmd((yyvsp[(1) - (2)].integer));;} break; case 770: #line 1861 "parser.Y" {fr->markerHighliteOnlyCmd((yyvsp[(1) - (3)].integer));;} break; case 771: #line 1863 "parser.Y" {fr->markerLineArrowCmd((yyvsp[(1) - (5)].integer),(yyvsp[(4) - (5)].integer),(yyvsp[(5) - (5)].integer));;} break; case 772: #line 1865 "parser.Y" {fr->markerLineCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(5) - (6)].vector)), Vector((yyvsp[(6) - (6)].vector)), (Coord::InternalSystem)(yyvsp[(4) - (6)].integer));;} break; case 773: #line 1867 "parser.Y" {fr->markerLineCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(6) - (7)].vector)), Vector((yyvsp[(7) - (7)].vector)), (Coord::CoordSystem)(yyvsp[(4) - (7)].integer), (Coord::SkyFrame)(yyvsp[(5) - (7)].integer));;} break; case 774: #line 1871 "parser.Y" {fr->markerMoveCmd((yyvsp[(1) - (4)].integer), Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 775: #line 1872 "parser.Y" {fr->markerFrontCmd((yyvsp[(1) - (3)].integer));;} break; case 776: #line 1873 "parser.Y" {fr->markerBackCmd((yyvsp[(1) - (3)].integer));;} break; case 777: #line 1875 "parser.Y" {fr->markerMoveToCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)), (Coord::InternalSystem)(yyvsp[(4) - (6)].integer));;} break; case 778: #line 1877 "parser.Y" {fr->markerMoveToCmd((yyvsp[(1) - (6)].integer),Vector((yyvsp[(6) - (6)].vector)),(Coord::CoordSystem)(yyvsp[(4) - (6)].integer),(Coord::SkyFrame)(yyvsp[(5) - (6)].integer));;} break; case 779: #line 1880 "parser.Y" {fr->markerPolygonResetCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)),(Coord::InternalSystem)(yyvsp[(6) - (6)].integer));;} break; case 780: #line 1882 "parser.Y" {fr->markerPolygonResetCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real)), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyDist)(yyvsp[(7) - (7)].integer));;} break; case 781: #line 1885 "parser.Y" {fr->markerPointShapeCmd((yyvsp[(1) - (4)].integer),(Point::PointShape)(yyvsp[(4) - (4)].integer));;} break; case 782: #line 1886 "parser.Y" {fr->markerPointSizeCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 783: #line 1889 "parser.Y" {fr->markerProjectionCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(4) - (6)].vector)), Vector((yyvsp[(5) - (6)].vector)), (Coord::InternalSystem)(yyvsp[(3) - (6)].integer), (yyvsp[(6) - (6)].real));;} break; case 784: #line 1893 "parser.Y" {fr->markerProjectionCmd((yyvsp[(1) - (9)].integer), Vector((yyvsp[(5) - (9)].vector)), Vector((yyvsp[(6) - (9)].vector)), (Coord::CoordSystem)(yyvsp[(3) - (9)].integer), (Coord::SkyFrame)(yyvsp[(4) - (9)].integer), (yyvsp[(7) - (9)].real), (Coord::CoordSystem)(yyvsp[(8) - (9)].integer), (Coord::SkyDist)(yyvsp[(9) - (9)].integer));;} break; case 785: #line 1897 "parser.Y" {fr->markerPropertyCmd((yyvsp[(1) - (4)].integer),(yyvsp[(3) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 786: #line 1899 "parser.Y" {fr->markerRotateBeginCmd((yyvsp[(1) - (3)].integer));;} break; case 787: #line 1901 "parser.Y" {fr->markerRulerPointCmd((yyvsp[(1) - (6)].integer), Vector((yyvsp[(5) - (6)].vector)), Vector((yyvsp[(6) - (6)].vector)), (Coord::InternalSystem)(yyvsp[(4) - (6)].integer));;} break; case 788: #line 1904 "parser.Y" {fr->markerRulerPointCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(6) - (7)].vector)), Vector((yyvsp[(7) - (7)].vector)), (Coord::CoordSystem)(yyvsp[(4) - (7)].integer), (Coord::SkyFrame)(yyvsp[(5) - (7)].integer));;} break; case 789: #line 1907 "parser.Y" {fr->markerRulerSystemCmd((yyvsp[(1) - (7)].integer), (Coord::CoordSystem)(yyvsp[(4) - (7)].integer), (Coord::SkyFrame)(yyvsp[(5) - (7)].integer), (Coord::CoordSystem)(yyvsp[(6) - (7)].integer), (Coord::SkyDist)(yyvsp[(7) - (7)].integer));;} break; case 790: #line 1910 "parser.Y" {fr->markerSelectCmd((yyvsp[(1) - (2)].integer));;} break; case 791: #line 1911 "parser.Y" {fr->markerSelectOnlyCmd((yyvsp[(1) - (3)].integer));;} break; case 792: #line 1913 "parser.Y" {fr->markerTagCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 793: #line 1914 "parser.Y" {fr->markerTextCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 794: #line 1915 "parser.Y" {fr->markerTextRotateCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 795: #line 1917 "parser.Y" {fr->markerUnhighliteCmd((yyvsp[(1) - (2)].integer));;} break; case 796: #line 1918 "parser.Y" {fr->markerUnselectCmd((yyvsp[(1) - (2)].integer));;} break; case 797: #line 1920 "parser.Y" {fr->markerVectorArrowCmd((yyvsp[(1) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 798: #line 1922 "parser.Y" {fr->markerVectorCmd((yyvsp[(1) - (7)].integer), Vector((yyvsp[(5) - (7)].vector)), (Coord::InternalSystem)(yyvsp[(4) - (7)].integer), (yyvsp[(6) - (7)].real), (yyvsp[(7) - (7)].real));;} break; case 799: #line 1925 "parser.Y" {fr->markerVectorCmd((yyvsp[(1) - (10)].integer), Vector((yyvsp[(6) - (10)].vector)), (Coord::CoordSystem)(yyvsp[(4) - (10)].integer), (Coord::SkyFrame)(yyvsp[(5) - (10)].integer), (yyvsp[(9) - (10)].real), (Coord::CoordSystem)(yyvsp[(7) - (10)].integer), (Coord::SkyDist)(yyvsp[(8) - (10)].integer), (yyvsp[(10) - (10)].real));;} break; case 800: #line 1928 "parser.Y" {fr->markerLineWidthCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 801: #line 1930 "parser.Y" {fr->markerKeyCmd();;} break; case 802: #line 1931 "parser.Y" {fr->markerKeyCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 806: #line 1936 "parser.Y" {fr->markerPreserveCmd((yyvsp[(2) - (2)].integer));;} break; case 807: #line 1937 "parser.Y" {fr->markerPropertyCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 808: #line 1939 "parser.Y" {fr->markerPropertyCmd((yyvsp[(2) - (5)].integer),(yyvsp[(3) - (5)].integer),Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)));;} break; case 809: #line 1941 "parser.Y" {fr->markerRotateBeginCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 810: #line 1943 "parser.Y" {fr->markerRotateMotionCmd(Vector((yyvsp[(3) - (5)].real),(yyvsp[(4) - (5)].real)),(yyvsp[(5) - (5)].integer));;} break; case 811: #line 1944 "parser.Y" {fr->markerRotateEndCmd();;} break; case 812: #line 1946 "parser.Y" {fr->markerSaveCmd((yyvsp[(2) - (7)].str), (Base::MarkerFormat)(yyvsp[(3) - (7)].integer), (Coord::CoordSystem)(yyvsp[(4) - (7)].integer), (Coord::SkyFrame)(yyvsp[(5) - (7)].integer), (Coord::SkyFormat)(yyvsp[(6) - (7)].integer), (yyvsp[(7) - (7)].integer));;} break; case 813: #line 1948 "parser.Y" {fr->markerSaveTemplateCmd((yyvsp[(3) - (3)].str));;} break; case 816: #line 1953 "parser.Y" {fr->markerColorCmd((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 817: #line 1954 "parser.Y" {fr->markerCopyCmd((yyvsp[(1) - (2)].str));;} break; case 818: #line 1955 "parser.Y" {fr->markerDeleteCmd((yyvsp[(1) - (2)].str));;} break; case 819: #line 1956 "parser.Y" {fr->markerCutCmd((yyvsp[(1) - (2)].str));;} break; case 820: #line 1957 "parser.Y" {fr->markerFontCmd((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 821: #line 1958 "parser.Y" {fr->markerHighliteCmd((yyvsp[(1) - (2)].str));;} break; case 822: #line 1959 "parser.Y" {fr->markerHighliteOnlyCmd((yyvsp[(1) - (3)].str));;} break; case 823: #line 1960 "parser.Y" {fr->markerMoveCmd((yyvsp[(1) - (4)].str),Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 824: #line 1961 "parser.Y" {fr->markerFrontCmd((yyvsp[(1) - (3)].str));;} break; case 825: #line 1962 "parser.Y" {fr->markerBackCmd((yyvsp[(1) - (3)].str));;} break; case 826: #line 1964 "parser.Y" {fr->markerMoveToCmd((yyvsp[(1) - (5)].str),Vector((yyvsp[(5) - (5)].vector)),(Coord::InternalSystem)(yyvsp[(4) - (5)].integer));;} break; case 827: #line 1966 "parser.Y" {fr->markerMoveToCmd((yyvsp[(1) - (6)].str),Vector((yyvsp[(6) - (6)].vector)),(Coord::CoordSystem)(yyvsp[(4) - (6)].integer),(Coord::SkyFrame)(yyvsp[(5) - (6)].integer));;} break; case 828: #line 1968 "parser.Y" {fr->markerPropertyCmd((yyvsp[(1) - (4)].str),(yyvsp[(3) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 829: #line 1969 "parser.Y" {fr->markerSelectCmd((yyvsp[(1) - (2)].str));;} break; case 830: #line 1970 "parser.Y" {fr->markerSelectOnlyCmd((yyvsp[(1) - (3)].str));;} break; case 831: #line 1971 "parser.Y" {fr->markerUnhighliteCmd((yyvsp[(1) - (2)].str));;} break; case 832: #line 1972 "parser.Y" {fr->markerUnselectCmd((yyvsp[(1) - (2)].str));;} break; case 833: #line 1974 "parser.Y" {fr->markerTagEditCmd((yyvsp[(3) - (4)].str),(yyvsp[(4) - (4)].str));;} break; case 834: #line 1975 "parser.Y" {fr->markerTagDeleteCmd((yyvsp[(3) - (3)].str));;} break; case 835: #line 1976 "parser.Y" {fr->markerTagDeleteAllCmd();;} break; case 836: #line 1977 "parser.Y" {fr->markerTagCmd((yyvsp[(2) - (2)].str));;} break; case 837: #line 1978 "parser.Y" {fr->markerTagUpdateCmd((yyvsp[(3) - (3)].str));;} break; case 838: #line 1980 "parser.Y" {fr->markerPasteCmd();;} break; case 839: #line 1982 "parser.Y" {fr->markerPasteCmd((Coord::CoordSystem)(yyvsp[(2) - (3)].integer), (Coord::CoordSystem)(yyvsp[(3) - (3)].integer));;} break; case 840: #line 1983 "parser.Y" {fr->markerUndoCmd();;} break; case 841: #line 1984 "parser.Y" {fr->markerUnhighliteAllCmd();;} break; case 842: #line 1985 "parser.Y" {fr->markerUnselectAllCmd();;} break; case 843: #line 1986 "parser.Y" {fr->markerLineWidthCmd((yyvsp[(2) - (2)].integer));;} break; case 844: #line 1989 "parser.Y" {(yyval.integer) = CallBack::SELECTCB;;} break; case 845: #line 1990 "parser.Y" {(yyval.integer) = CallBack::UNSELECTCB;;} break; case 846: #line 1991 "parser.Y" {(yyval.integer) = CallBack::HIGHLITECB;;} break; case 847: #line 1992 "parser.Y" {(yyval.integer) = CallBack::UNHIGHLITECB;;} break; case 848: #line 1993 "parser.Y" {(yyval.integer) = CallBack::MOVEBEGINCB;;} break; case 849: #line 1994 "parser.Y" {(yyval.integer) = CallBack::MOVECB;;} break; case 850: #line 1995 "parser.Y" {(yyval.integer) = CallBack::MOVEENDCB;;} break; case 851: #line 1996 "parser.Y" {(yyval.integer) = CallBack::EDITBEGINCB;;} break; case 852: #line 1997 "parser.Y" {(yyval.integer) = CallBack::EDITCB;;} break; case 853: #line 1998 "parser.Y" {(yyval.integer) = CallBack::EDITENDCB;;} break; case 854: #line 1999 "parser.Y" {(yyval.integer) = CallBack::ROTATEBEGINCB;;} break; case 855: #line 2000 "parser.Y" {(yyval.integer) = CallBack::ROTATECB;;} break; case 856: #line 2001 "parser.Y" {(yyval.integer) = CallBack::ROTATEENDCB;;} break; case 857: #line 2002 "parser.Y" {(yyval.integer) = CallBack::DELETECB;;} break; case 858: #line 2003 "parser.Y" {(yyval.integer) = CallBack::TEXTCB;;} break; case 859: #line 2004 "parser.Y" {(yyval.integer) = CallBack::COLORCB;;} break; case 860: #line 2005 "parser.Y" {(yyval.integer) = CallBack::LINEWIDTHCB;;} break; case 861: #line 2006 "parser.Y" {(yyval.integer) = CallBack::PROPERTYCB;;} break; case 862: #line 2007 "parser.Y" {(yyval.integer) = CallBack::FONTCB;;} break; case 863: #line 2008 "parser.Y" {(yyval.integer) = CallBack::KEYCB;;} break; case 864: #line 2009 "parser.Y" {(yyval.integer) = CallBack::UPDATECB;;} break; case 865: #line 2012 "parser.Y" {fr->markerCentroidCmd();;} break; case 866: #line 2013 "parser.Y" {fr->markerCentroidCmd((yyvsp[(1) - (1)].integer));;} break; case 867: #line 2014 "parser.Y" {fr->markerCentroidAutoCmd((yyvsp[(2) - (2)].integer));;} break; case 868: #line 2015 "parser.Y" {fr->markerCentroidRadiusCmd((yyvsp[(2) - (2)].real));;} break; case 869: #line 2016 "parser.Y" {fr->markerCentroidIterationCmd((yyvsp[(2) - (2)].integer));;} break; case 870: #line 2017 "parser.Y" { fr->markerCentroidIterationCmd((yyvsp[(2) - (3)].integer)); fr->markerCentroidRadiusCmd((yyvsp[(3) - (3)].real)); ;} break; case 871: #line 2027 "parser.Y" {fr->createCircleCmd(fr->mapToRef(Vector((yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real)),Coord::CANVAS), (yyvsp[(4) - (5)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 872: #line 2035 "parser.Y" {fr->createEllipseCmd(fr->mapToRef(Vector((yyvsp[(2) - (7)].real),(yyvsp[(3) - (7)].real)),Coord::CANVAS), Vector((yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real)), (yyvsp[(6) - (7)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 873: #line 2044 "parser.Y" {fr->createBoxCmd(fr->mapToRef(Vector((yyvsp[(2) - (7)].real),(yyvsp[(3) - (7)].real)),Coord::CANVAS), Vector((yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real)), (yyvsp[(6) - (7)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 874: #line 2052 "parser.Y" {fr->createPolygonCmd(fr->mapToRef(Vector((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real)),Coord::CANVAS), Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 875: #line 2059 "parser.Y" {fr->createLineCmd(fr->mapToRef(Vector((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real)),Coord::CANVAS), fr->mapToRef(Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)),Coord::CANVAS), 0, 0, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 876: #line 2067 "parser.Y" {fr->createVectCmd(fr->mapToRef(Vector((yyvsp[(2) - (6)].real),(yyvsp[(3) - (6)].real)),Coord::CANVAS), fr->mapToRef(Vector((yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real)),Coord::CANVAS), 1, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 877: #line 2075 "parser.Y" {fr->createTextCmd(fr->mapToRef(Vector((yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real)),Coord::CANVAS), (yyvsp[(4) - (5)].real), 1, currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 878: #line 2080 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::CIRCLE, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 879: #line 2085 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::BOX, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 880: #line 2090 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::DIAMOND, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 881: #line 2095 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::CROSS, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 882: #line 2100 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::EX, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 883: #line 2105 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::ARROW, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 884: #line 2110 "parser.Y" {fr->createPointCmd(fr->mapToRef(Vector((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real)),Coord::CANVAS), Point::BOXCIRCLE, (yyvsp[(5) - (6)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 885: #line 2119 "parser.Y" {fr->createRulerCmd(fr->mapToRef(Vector((yyvsp[(2) - (10)].real),(yyvsp[(3) - (10)].real)),Coord::CANVAS), fr->mapToRef(Vector((yyvsp[(4) - (10)].real),(yyvsp[(5) - (10)].real)),Coord::CANVAS), (Coord::CoordSystem)(yyvsp[(6) - (10)].integer), (Coord::SkyFrame)(yyvsp[(7) - (10)].integer), (Coord::CoordSystem)(yyvsp[(8) - (10)].integer), (Coord::SkyDist)(yyvsp[(9) - (10)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 886: #line 2128 "parser.Y" {fr->createCompassCmd(fr->mapToRef(Vector((yyvsp[(2) - (7)].real),(yyvsp[(3) - (7)].real)),Coord::CANVAS), (yyvsp[(4) - (7)].real), "N", "E", 1, 1, (Coord::CoordSystem)(yyvsp[(5) - (7)].integer), (Coord::SkyFrame)(yyvsp[(6) - (7)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 887: #line 2138 "parser.Y" {fr->createProjectionCmd(fr->mapToRef(Vector((yyvsp[(2) - (7)].real),(yyvsp[(3) - (7)].real)),Coord::CANVAS), fr->mapToRef(Vector((yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real)),Coord::CANVAS), (yyvsp[(6) - (7)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 888: #line 2147 "parser.Y" {fr->createAnnulusCmd(fr->mapToRef(Vector((yyvsp[(2) - (7)].real),(yyvsp[(3) - (7)].real)),Coord::CANVAS), (yyvsp[(4) - (7)].real),(yyvsp[(5) - (7)].real),(yyvsp[(6) - (7)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 889: #line 2155 "parser.Y" {fr->createEllipseAnnulusCmd(fr->mapToRef(Vector((yyvsp[(2) - (9)].real),(yyvsp[(3) - (9)].real)),Coord::CANVAS), Vector((yyvsp[(4) - (9)].real),(yyvsp[(5) - (9)].real)), Vector((yyvsp[(6) - (9)].real),(yyvsp[(6) - (9)].real)*(yyvsp[(4) - (9)].real)/(yyvsp[(5) - (9)].real)),(yyvsp[(7) - (9)].integer), (yyvsp[(8) - (9)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 890: #line 2165 "parser.Y" {fr->createBoxAnnulusCmd(fr->mapToRef(Vector((yyvsp[(2) - (9)].real),(yyvsp[(3) - (9)].real)),Coord::CANVAS), Vector((yyvsp[(4) - (9)].real),(yyvsp[(5) - (9)].real)),Vector((yyvsp[(6) - (9)].real),(yyvsp[(6) - (9)].real)*(yyvsp[(4) - (9)].real)/(yyvsp[(5) - (9)].real)),(yyvsp[(7) - (9)].integer), (yyvsp[(8) - (9)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 891: #line 2175 "parser.Y" {fr->createCpandaCmd(fr->mapToRef(Vector((yyvsp[(2) - (10)].real),(yyvsp[(3) - (10)].real)),Coord::CANVAS), (yyvsp[(4) - (10)].real),(yyvsp[(5) - (10)].real),(yyvsp[(6) - (10)].integer), (yyvsp[(7) - (10)].real),(yyvsp[(8) - (10)].real),(yyvsp[(9) - (10)].integer), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 892: #line 2185 "parser.Y" {fr->createEpandaCmd(fr->mapToRef(Vector((yyvsp[(2) - (12)].real),(yyvsp[(3) - (12)].real)),Coord::CANVAS), (yyvsp[(4) - (12)].real),(yyvsp[(5) - (12)].real),(yyvsp[(6) - (12)].integer), Vector((yyvsp[(7) - (12)].real),(yyvsp[(8) - (12)].real)), Vector((yyvsp[(9) - (12)].real),(yyvsp[(9) - (12)].real)*(yyvsp[(7) - (12)].real)/(yyvsp[(8) - (12)].real)),(yyvsp[(10) - (12)].integer), (yyvsp[(11) - (12)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 893: #line 2197 "parser.Y" {fr->createBpandaCmd(fr->mapToRef(Vector((yyvsp[(2) - (12)].real),(yyvsp[(3) - (12)].real)),Coord::CANVAS), (yyvsp[(4) - (12)].real),(yyvsp[(5) - (12)].real),(yyvsp[(6) - (12)].integer), Vector((yyvsp[(7) - (12)].real),(yyvsp[(8) - (12)].real)), Vector((yyvsp[(9) - (12)].real),(yyvsp[(9) - (12)].real)*(yyvsp[(7) - (12)].real)/(yyvsp[(8) - (12)].real)),(yyvsp[(10) - (12)].integer), (yyvsp[(11) - (12)].real), currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 894: #line 2206 "parser.Y" {fr->createCompositeCmd( currentColor,currentDash,currentWidth,currentFont, currentText,currentProps,NULL,taglist,cblist);;} break; case 896: #line 2214 "parser.Y" {fr->createTemplateCmd(fr->mapToRef(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)),Coord::CANVAS), (yyvsp[(1) - (3)].str));;} break; case 897: #line 2216 "parser.Y" {fr->createTemplateVarCmd(fr->mapToRef(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)),Coord::CANVAS), (yyvsp[(2) - (4)].str));;} break; case 898: #line 2218 "parser.Y" { // backward compatibility fr->createTemplateVarCmd(fr->mapToRef(Vector((yyvsp[(1) - (4)].real),(yyvsp[(2) - (4)].real)),Coord::CANVAS), (yyvsp[(4) - (4)].str)); ;} break; case 899: #line 2223 "parser.Y" {fr->createTemplateCmd(Vector((yyvsp[(4) - (4)].vector)),(Coord::CoordSystem)(yyvsp[(2) - (4)].integer),(Coord::SkyFrame)(yyvsp[(3) - (4)].integer), (yyvsp[(1) - (4)].str));;} break; case 900: #line 2226 "parser.Y" {(yyval.dash)[0] = (yyvsp[(1) - (2)].integer); (yyval.dash)[1] = (yyvsp[(2) - (2)].integer);;} break; case 901: #line 2230 "parser.Y" {fr->markerEditBeginCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].integer));;} break; case 902: #line 2232 "parser.Y" {fr->markerEditMotionCmd(Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].integer));;} break; case 903: #line 2233 "parser.Y" {fr->markerEditEndCmd();;} break; case 904: #line 2236 "parser.Y" {(yyval.integer) = Base::DS9;;} break; case 905: #line 2237 "parser.Y" {(yyval.integer) = Base::XML;;} break; case 906: #line 2238 "parser.Y" {(yyval.integer) = Base::CIAO;;} break; case 907: #line 2239 "parser.Y" {(yyval.integer) = Base::SAOTNG;;} break; case 908: #line 2240 "parser.Y" {(yyval.integer) = Base::SAOIMAGE;;} break; case 909: #line 2241 "parser.Y" {(yyval.integer) = Base::PROS;;} break; case 910: #line 2242 "parser.Y" {(yyval.integer) = Base::RAWXY;;} break; case 912: #line 2246 "parser.Y" {fr->getMarkerColorCmd();;} break; case 913: #line 2247 "parser.Y" {fr->getMarkerFontCmd();;} break; case 914: #line 2248 "parser.Y" {fr->getMarkerHandleCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 915: #line 2249 "parser.Y" {fr->getMarkerIdCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 916: #line 2252 "parser.Y" {fr->getMarkerAnalysisPlot2dCmd((yyvsp[(1) - (10)].integer),(yyvsp[(4) - (10)].str),(yyvsp[(5) - (10)].str),(yyvsp[(6) - (10)].str),(yyvsp[(7) - (10)].str),(Coord::CoordSystem)(yyvsp[(8) - (10)].integer), (Coord::SkyFrame)(yyvsp[(9) - (10)].integer), (Marker::AnalysisMethod)(yyvsp[(10) - (10)].integer));;} break; case 917: #line 2254 "parser.Y" {fr->getMarkerAnalysisPlot3dCmd((yyvsp[(1) - (7)].integer),(yyvsp[(4) - (7)].str),(yyvsp[(5) - (7)].str),(Coord::CoordSystem)(yyvsp[(6) - (7)].integer),(Marker::AnalysisMethod)(yyvsp[(7) - (7)].integer));;} break; case 918: #line 2256 "parser.Y" {fr->getMarkerAnalysisPandaCmd((yyvsp[(1) - (4)].integer),(Coord::CoordSystem)(yyvsp[(4) - (4)].integer));;} break; case 919: #line 2258 "parser.Y" {fr->getMarkerAnalysisRadialCmd((yyvsp[(1) - (7)].integer),(yyvsp[(4) - (7)].str),(yyvsp[(5) - (7)].str),(yyvsp[(6) - (7)].str),(Coord::CoordSystem)(yyvsp[(7) - (7)].integer));;} break; case 920: #line 2260 "parser.Y" {fr->getMarkerAnalysisStatsCmd((yyvsp[(1) - (4)].integer),(Coord::CoordSystem)(yyvsp[(4) - (4)].integer));;} break; case 921: #line 2262 "parser.Y" {fr->getMarkerIdAllCmd();;} break; case 922: #line 2263 "parser.Y" {fr->getMarkerAngleCmd((yyvsp[(1) - (2)].integer));;} break; case 923: #line 2264 "parser.Y" {fr->getMarkerAngleCmd((yyvsp[(1) - (3)].integer));;} break; case 924: #line 2266 "parser.Y" {fr->getMarkerAngleCmd((yyvsp[(1) - (4)].integer),(Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (Coord::SkyFrame)(yyvsp[(4) - (4)].integer));;} break; case 925: #line 2268 "parser.Y" {fr->getMarkerAnnulusRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 926: #line 2270 "parser.Y" {fr->getMarkerAnnulusRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 927: #line 2273 "parser.Y" {fr->getMarkerBoxAnnulusRadiusCmd((yyvsp[(1) - (4)].integer),(Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 928: #line 2275 "parser.Y" {fr->getMarkerBoxAnnulusRadiusCmd((yyvsp[(1) - (5)].integer),(Coord::CoordSystem)(yyvsp[(4) - (5)].integer),(Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 929: #line 2277 "parser.Y" {fr->getMarkerBoxRadiusCmd((yyvsp[(1) - (4)].integer),(Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 930: #line 2279 "parser.Y" {fr->getMarkerBoxRadiusCmd((yyvsp[(1) - (5)].integer),(Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 931: #line 2280 "parser.Y" {fr->getMarkerBpandaAnglesCmd((yyvsp[(1) - (3)].integer));;} break; case 932: #line 2281 "parser.Y" {fr->getMarkerBpandaAnglesCmd((yyvsp[(1) - (4)].integer));;} break; case 933: #line 2283 "parser.Y" {fr->getMarkerBpandaAnglesCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyFrame)(yyvsp[(5) - (5)].integer));;} break; case 934: #line 2285 "parser.Y" {fr->getMarkerBpandaRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 935: #line 2287 "parser.Y" {fr->getMarkerBpandaRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 936: #line 2290 "parser.Y" {fr->getMarkerCenterCmd((yyvsp[(1) - (3)].integer), (Coord::InternalSystem)(yyvsp[(3) - (3)].integer));;} break; case 937: #line 2292 "parser.Y" {fr->getMarkerCenterCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(3) - (5)].integer), (Coord::SkyFrame)(yyvsp[(4) - (5)].integer), (Coord::SkyFormat)(yyvsp[(5) - (5)].integer));;} break; case 938: #line 2295 "parser.Y" {fr->getMarkerCircleRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 939: #line 2297 "parser.Y" {fr->getMarkerCircleRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 940: #line 2298 "parser.Y" {fr->getMarkerColorCmd((yyvsp[(1) - (2)].integer));;} break; case 941: #line 2299 "parser.Y" {fr->getMarkerCompassArrowCmd((yyvsp[(1) - (3)].integer));;} break; case 942: #line 2300 "parser.Y" {fr->getMarkerCompassLabelCmd((yyvsp[(1) - (3)].integer));;} break; case 943: #line 2302 "parser.Y" {fr->getMarkerCompassRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 944: #line 2304 "parser.Y" {fr->getMarkerCompassRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 945: #line 2305 "parser.Y" {fr->getMarkerCompassSystemCmd((yyvsp[(1) - (3)].integer));;} break; case 946: #line 2306 "parser.Y" {fr->getMarkerCompositeCmd((yyvsp[(1) - (3)].integer));;} break; case 947: #line 2307 "parser.Y" {fr->getMarkerCpandaAnglesCmd((yyvsp[(1) - (3)].integer));;} break; case 948: #line 2308 "parser.Y" {fr->getMarkerCpandaAnglesCmd((yyvsp[(1) - (4)].integer));;} break; case 949: #line 2310 "parser.Y" {fr->getMarkerCpandaAnglesCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyFrame)(yyvsp[(5) - (5)].integer));;} break; case 950: #line 2312 "parser.Y" {fr->getMarkerCpandaRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 951: #line 2314 "parser.Y" {fr->getMarkerCpandaRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 952: #line 2316 "parser.Y" {fr->getMarkerEllipseRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 953: #line 2318 "parser.Y" {fr->getMarkerEllipseRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 954: #line 2320 "parser.Y" {fr->getMarkerEllipseAnnulusRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 955: #line 2322 "parser.Y" {fr->getMarkerEllipseAnnulusRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 956: #line 2324 "parser.Y" {fr->getMarkerEpandaAnglesCmd((yyvsp[(1) - (3)].integer));;} break; case 957: #line 2325 "parser.Y" {fr->getMarkerEpandaAnglesCmd((yyvsp[(1) - (4)].integer));;} break; case 958: #line 2327 "parser.Y" {fr->getMarkerEpandaAnglesCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyFrame)(yyvsp[(5) - (5)].integer));;} break; case 959: #line 2329 "parser.Y" {fr->getMarkerEpandaRadiusCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 960: #line 2331 "parser.Y" {fr->getMarkerEpandaRadiusCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 961: #line 2332 "parser.Y" {fr->getMarkerFontCmd((yyvsp[(1) - (2)].integer));;} break; case 962: #line 2333 "parser.Y" {fr->getMarkerHighlitedCmd((yyvsp[(1) - (2)].integer));;} break; case 963: #line 2334 "parser.Y" {fr->getMarkerLineArrowCmd((yyvsp[(1) - (3)].integer));;} break; case 964: #line 2336 "parser.Y" {fr->getMarkerLineLengthCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 965: #line 2338 "parser.Y" {fr->getMarkerLineCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 966: #line 2340 "parser.Y" {fr->getMarkerLineCmd((yyvsp[(1) - (6)].integer), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer), (Coord::SkyFormat)(yyvsp[(6) - (6)].integer));;} break; case 967: #line 2343 "parser.Y" {fr->getMarkerMapLenFromRefCmd((yyvsp[(1) - (6)].integer), (yyvsp[(4) - (6)].real), (Coord::CoordSystem)(yyvsp[(5) - (6)].integer),(Coord::SkyDist)(yyvsp[(6) - (6)].integer));;} break; case 968: #line 2346 "parser.Y" {fr->getMarkerPointShapeCmd((yyvsp[(1) - (3)].integer));;} break; case 969: #line 2347 "parser.Y" {fr->getMarkerPointSizeCmd((yyvsp[(1) - (3)].integer));;} break; case 970: #line 2349 "parser.Y" {fr->getMarkerProjectionPointsCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 971: #line 2351 "parser.Y" {fr->getMarkerProjectionPointsCmd((yyvsp[(1) - (6)].integer), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer), (Coord::SkyFormat)(yyvsp[(6) - (6)].integer));;} break; case 972: #line 2354 "parser.Y" {fr->getMarkerProjectionLengthCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 973: #line 2357 "parser.Y" {fr->getMarkerProjectionWidthCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 974: #line 2359 "parser.Y" {fr->getMarkerProjectionWidthCmd((yyvsp[(1) - (5)].integer),(Coord::CoordSystem)(yyvsp[(4) - (5)].integer),(Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 975: #line 2360 "parser.Y" {fr->getMarkerPropertyCmd((yyvsp[(1) - (2)].integer));;} break; case 976: #line 2361 "parser.Y" {fr->getMarkerPropertyCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 977: #line 2363 "parser.Y" {fr->getMarkerRulerLengthCmd((yyvsp[(1) - (5)].integer),(Coord::CoordSystem)(yyvsp[(4) - (5)].integer),(Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 978: #line 2365 "parser.Y" {fr->getMarkerRulerPointCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 979: #line 2367 "parser.Y" {fr->getMarkerRulerPointCmd((yyvsp[(1) - (6)].integer), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer), (Coord::SkyFormat)(yyvsp[(6) - (6)].integer));;} break; case 980: #line 2369 "parser.Y" {fr->getMarkerRulerSystemCmd((yyvsp[(1) - (3)].integer));;} break; case 981: #line 2370 "parser.Y" {fr->getMarkerSelectedCmd((yyvsp[(1) - (2)].integer));;} break; case 982: #line 2372 "parser.Y" {fr->getMarkerTagCmd((yyvsp[(1) - (2)].integer));;} break; case 983: #line 2373 "parser.Y" {fr->getMarkerTagCmd((yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 984: #line 2374 "parser.Y" {fr->getMarkerTextCmd((yyvsp[(1) - (2)].integer));;} break; case 985: #line 2375 "parser.Y" {fr->getMarkerTextRotateCmd((yyvsp[(1) - (3)].integer));;} break; case 986: #line 2376 "parser.Y" {fr->getMarkerTypeCmd((yyvsp[(1) - (2)].integer));;} break; case 987: #line 2378 "parser.Y" {fr->getMarkerVectorArrowCmd((yyvsp[(1) - (3)].integer));;} break; case 988: #line 2380 "parser.Y" {fr->getMarkerVectorLengthCmd((yyvsp[(1) - (5)].integer), (Coord::CoordSystem)(yyvsp[(4) - (5)].integer), (Coord::SkyDist)(yyvsp[(5) - (5)].integer));;} break; case 989: #line 2382 "parser.Y" {fr->getMarkerVectorCmd((yyvsp[(1) - (4)].integer), (Coord::InternalSystem)(yyvsp[(4) - (4)].integer));;} break; case 990: #line 2384 "parser.Y" {fr->getMarkerVectorCmd((yyvsp[(1) - (6)].integer), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer), (Coord::SkyFormat)(yyvsp[(6) - (6)].integer));;} break; case 991: #line 2386 "parser.Y" {fr->getMarkerLineWidthCmd((yyvsp[(1) - (2)].integer));;} break; case 993: #line 2388 "parser.Y" {fr->getMarkerHighlitedNumberCmd();;} break; case 994: #line 2389 "parser.Y" {fr->getMarkerNumberCmd();;} break; case 995: #line 2391 "parser.Y" {fr->getMarkerPolygonSegmentCmd(Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 996: #line 2392 "parser.Y" {fr->getMarkerPreserveCmd();;} break; case 997: #line 2393 "parser.Y" {fr->getMarkerPropertyCmd((yyvsp[(2) - (2)].integer));;} break; case 999: #line 2395 "parser.Y" {fr->getMarkerSelectedNumberCmd();;} break; case 1001: #line 2399 "parser.Y" {fr->getMarkerColorCmd((yyvsp[(1) - (2)].str));;} break; case 1002: #line 2400 "parser.Y" {fr->getMarkerFontCmd((yyvsp[(1) - (2)].str));;} break; case 1003: #line 2401 "parser.Y" {fr->getMarkerIdCmd((yyvsp[(1) - (2)].str));;} break; case 1004: #line 2402 "parser.Y" {fr->getMarkerPropertyCmd((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].integer));;} break; case 1005: #line 2403 "parser.Y" {fr->getMarkerTagCmd((yyvsp[(1) - (2)].str));;} break; case 1006: #line 2404 "parser.Y" {fr->getMarkerTagNumberCmd((yyvsp[(1) - (3)].str));;} break; case 1007: #line 2406 "parser.Y" {fr->getMarkerTagsCmd();;} break; case 1008: #line 2407 "parser.Y" {fr->getMarkerTagDefaultNameCmd();;} break; case 1009: #line 2409 "parser.Y" {fr->getMarkerLineWidthCmd();;} break; case 1010: #line 2412 "parser.Y" {fr->getMarkerCentroidAutoCmd();;} break; case 1011: #line 2413 "parser.Y" {fr->getMarkerCentroidRadiusCmd();;} break; case 1012: #line 2414 "parser.Y" {fr->getMarkerCentroidIterationCmd();;} break; case 1013: #line 2415 "parser.Y" {fr->getMarkerCentroidOptionCmd();;} break; case 1014: #line 2418 "parser.Y" {fr->getMarkerHighlitedCmd();;} break; case 1015: #line 2419 "parser.Y" {fr->getMarkerHighlitedCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1016: #line 2422 "parser.Y" {fr->getMarkerSelectedCmd();;} break; case 1017: #line 2423 "parser.Y" {fr->getMarkerSelectedCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1018: #line 2426 "parser.Y" {fr->getMarkerShowCmd();;} break; case 1019: #line 2427 "parser.Y" {fr->getMarkerShowTextCmd();;} break; case 1020: #line 2430 "parser.Y" { strncpy(currentFont, "helvetica 10 normal roman", 32); strncpy(currentColor, "green", 16); currentDash[0] = 8; currentDash[1] = 3; currentWidth = 1; strncpy(currentText, "", 80); currentProps = defaultProps; taglist.deleteAll(); cblist.deleteAll(); ;} break; case 1021: #line 2443 "parser.Y" {fr->markerLayerCmd(Base::USER);;} break; case 1022: #line 2444 "parser.Y" {fr->markerLayerCmd(Base::USER);;} break; case 1023: #line 2445 "parser.Y" {fr->markerLayerCmd(Base::USER);;} break; case 1024: #line 2446 "parser.Y" {fr->markerLayerCmd(Base::CATALOG);;} break; case 1025: #line 2451 "parser.Y" {fr->markerListCmd((Base::MarkerFormat)(yyvsp[(1) - (7)].integer), (Coord::CoordSystem)(yyvsp[(2) - (7)].integer), (Coord::SkyFrame)(yyvsp[(3) - (7)].integer), (Coord::SkyFormat)(yyvsp[(4) - (7)].integer), (yyvsp[(5) - (7)].integer), 0, propQMask, propQValue, taglist);;} break; case 1026: #line 2456 "parser.Y" {fr->markerListCmd((Base::MarkerFormat)(yyvsp[(2) - (8)].integer), (Coord::CoordSystem)(yyvsp[(3) - (8)].integer), (Coord::SkyFrame)(yyvsp[(4) - (8)].integer), (Coord::SkyFormat)(yyvsp[(5) - (8)].integer), (yyvsp[(6) - (8)].integer), 1, propQMask, propQValue, taglist);;} break; case 1027: #line 2462 "parser.Y" {fr->markerLoadCmd((Base::MarkerFormat)(yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].str));;} break; case 1028: #line 2464 "parser.Y" {fr->markerLoadCmd((Base::MarkerFormat)(yyvsp[(1) - (4)].integer),(yyvsp[(2) - (4)].str), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer),(Coord::SkyFrame)(yyvsp[(4) - (4)].integer));;} break; case 1029: #line 2467 "parser.Y" {fr->markerLoadCmd((Base::MarkerFormat)(yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 1030: #line 2469 "parser.Y" {fr->markerLoadCmd((Base::MarkerFormat)(yyvsp[(1) - (4)].integer),(yyvsp[(2) - (4)].integer), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer),(Coord::SkyFrame)(yyvsp[(4) - (4)].integer));;} break; case 1031: #line 2472 "parser.Y" {fr->markerLoadFitsCmd((yyvsp[(2) - (6)].str), (yyvsp[(3) - (6)].str), (yyvsp[(4) - (6)].dash), (yyvsp[(5) - (6)].integer), (yyvsp[(6) - (6)].str));;} break; case 1032: #line 2475 "parser.Y" {fr->markerMoveCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1033: #line 2476 "parser.Y" {fr->markerFrontCmd();;} break; case 1034: #line 2477 "parser.Y" {fr->markerBackCmd();;} break; case 1035: #line 2478 "parser.Y" {fr->markerMoveBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1036: #line 2479 "parser.Y" {fr->markerMoveMotionCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1037: #line 2480 "parser.Y" {fr->markerMoveEndCmd();;} break; case 1038: #line 2482 "parser.Y" {fr->markerMoveToCmd(Vector((yyvsp[(3) - (3)].vector)), (Coord::InternalSystem)(yyvsp[(2) - (3)].integer));;} break; case 1039: #line 2484 "parser.Y" {fr->markerMoveToCmd(Vector((yyvsp[(4) - (4)].vector)), (Coord::CoordSystem)(yyvsp[(2) - (4)].integer), (Coord::SkyFrame)(yyvsp[(3) - (4)].integer));;} break; case 1042: #line 2491 "parser.Y" {setProps(&currentProps,(yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 1043: #line 2492 "parser.Y" {strncpy(currentColor,(yyvsp[(3) - (3)].str),16);;} break; case 1044: #line 2493 "parser.Y" {currentDash[0]=(yyvsp[(3) - (4)].integer);currentDash[1]=(yyvsp[(4) - (4)].integer);;} break; case 1045: #line 2494 "parser.Y" {currentWidth = (yyvsp[(3) - (3)].integer);;} break; case 1046: #line 2495 "parser.Y" {strncpy(currentFont,(yyvsp[(3) - (3)].str),32);;} break; case 1047: #line 2496 "parser.Y" {strncpy(currentText,(yyvsp[(3) - (3)].str),80);;} break; case 1050: #line 2501 "parser.Y" {(yyval.integer) = Marker::NONE;;} break; case 1051: #line 2502 "parser.Y" {(yyval.integer) = Marker::SELECT;;} break; case 1052: #line 2503 "parser.Y" {(yyval.integer) = Marker::HIGHLITE;;} break; case 1053: #line 2504 "parser.Y" {(yyval.integer) = Marker::DASH;;} break; case 1054: #line 2505 "parser.Y" {(yyval.integer) = Marker::FIXED;;} break; case 1055: #line 2506 "parser.Y" {(yyval.integer) = Marker::EDIT;;} break; case 1056: #line 2507 "parser.Y" {(yyval.integer) = Marker::MOVE;;} break; case 1057: #line 2508 "parser.Y" {(yyval.integer) = Marker::ROTATE;;} break; case 1058: #line 2509 "parser.Y" {(yyval.integer) = Marker::DELETE;;} break; case 1059: #line 2510 "parser.Y" {(yyval.integer) = Marker::INCLUDE;;} break; case 1060: #line 2511 "parser.Y" {(yyval.integer) = Marker::SOURCE;;} break; case 1063: #line 2518 "parser.Y" {propQMask=0;propQValue=0;;} break; case 1064: #line 2519 "parser.Y" {propQMask=0;propQValue=0;;} break; case 1066: #line 2522 "parser.Y" {fr->markerSelectAllCmd();;} break; case 1067: #line 2523 "parser.Y" {fr->markerSelectOnlyCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1068: #line 2524 "parser.Y" {fr->markerSelectToggleCmd();;} break; case 1069: #line 2525 "parser.Y" {fr->markerSelectToggleCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1070: #line 2528 "parser.Y" {fr->markerShowCmd((yyvsp[(1) - (1)].integer));;} break; case 1071: #line 2529 "parser.Y" {fr->markerShowTextCmd((yyvsp[(2) - (2)].integer));;} break; case 1074: #line 2537 "parser.Y" {propQMask |= (yyvsp[(1) - (3)].integer); setProps(&propQValue,(yyvsp[(1) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 1075: #line 2540 "parser.Y" {taglist.deleteAll();} break; case 1076: #line 2541 "parser.Y" {taglist.deleteAll();} break; case 1080: #line 2548 "parser.Y" {taglist.append(new Tag((yyvsp[(3) - (3)].str)));;} break; case 1081: #line 2551 "parser.Y" {cblist.append( new CallBack(fr->getInterp(),(CallBack::Type)(yyvsp[(3) - (5)].integer),(yyvsp[(4) - (5)].str),(yyvsp[(5) - (5)].str)));;} break; case 1082: #line 2555 "parser.Y" {fr->maskClearCmd();;} break; case 1083: #line 2556 "parser.Y" {fr->maskColorCmd((yyvsp[(2) - (2)].str));;} break; case 1084: #line 2557 "parser.Y" {fr->maskMarkCmd((yyvsp[(2) - (2)].integer));;} break; case 1085: #line 2558 "parser.Y" {fr->maskTransparencyCmd((yyvsp[(2) - (2)].real));;} break; case 1086: #line 2561 "parser.Y" {fr->orientCmd(Coord::XX);;} break; case 1087: #line 2562 "parser.Y" {fr->orientCmd(Coord::YY);;} break; case 1088: #line 2563 "parser.Y" {fr->orientCmd(Coord::XY);;} break; case 1089: #line 2564 "parser.Y" {fr->orientCmd(Coord::NORMAL);;} break; case 1090: #line 2568 "parser.Y" {fr->panCmd(Vector((yyvsp[(1) - (4)].real),(yyvsp[(2) - (4)].real)),Vector((yyvsp[(3) - (4)].real),(yyvsp[(4) - (4)].real)));;} break; case 1091: #line 2569 "parser.Y" {fr->panCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1092: #line 2571 "parser.Y" { // backward compatibility fr->panCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real))); ;} break; case 1093: #line 2576 "parser.Y" {fr->panCmd(Vector((yyvsp[(3) - (3)].vector)), (Coord::CoordSystem)(yyvsp[(1) - (3)].integer), (Coord::SkyFrame)(yyvsp[(2) - (3)].integer));;} break; case 1095: #line 2578 "parser.Y" {fr->panBBoxCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1097: #line 2580 "parser.Y" {fr->panPreserveCmd((yyvsp[(2) - (2)].integer));;} break; case 1098: #line 2583 "parser.Y" {fr->panToCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1099: #line 2585 "parser.Y" { // backward compatibility fr->panToCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real))); ;} break; case 1100: #line 2590 "parser.Y" {fr->panToCmd(Vector((yyvsp[(3) - (3)].vector)), (Coord::CoordSystem)(yyvsp[(1) - (3)].integer), (Coord::SkyFrame)(yyvsp[(2) - (3)].integer));;} break; case 1101: #line 2593 "parser.Y" {fr->panBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1102: #line 2594 "parser.Y" {fr->panMotionCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1103: #line 2595 "parser.Y" {fr->panEndCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1104: #line 2598 "parser.Y" {fr->pannerCmd((yyvsp[(1) - (1)].integer));;} break; case 1105: #line 2600 "parser.Y" { // backward compatibility fr->pannerCmd((Coord::CoordSystem)(yyvsp[(2) - (3)].integer),(Coord::SkyFrame)(yyvsp[(3) - (3)].integer)); ;} break; case 1106: #line 2604 "parser.Y" {fr->pannerCmd((yyvsp[(1) - (3)].str), (yyvsp[(2) - (3)].integer), (yyvsp[(3) - (3)].integer));;} break; case 1107: #line 2605 "parser.Y" {fr->updatePannerCmd();;} break; case 1108: #line 2609 "parser.Y" {fr->psColorSpaceCmd((Widget::PSColorSpace)(yyvsp[(2) - (2)].integer));;} break; case 1109: #line 2610 "parser.Y" {fr->psLevelCmd((yyvsp[(2) - (2)].integer));;} break; case 1110: #line 2611 "parser.Y" {fr->psResolutionCmd((yyvsp[(2) - (2)].integer));;} break; case 1111: #line 2612 "parser.Y" {fr->psScaleCmd((yyvsp[(2) - (2)].real));;} break; case 1112: #line 2615 "parser.Y" {(yyval.integer) = Widget::BW;;} break; case 1113: #line 2616 "parser.Y" {(yyval.integer) = Widget::GRAY;;} break; case 1114: #line 2617 "parser.Y" {(yyval.integer) = Widget::RGB;;} break; case 1115: #line 2618 "parser.Y" {(yyval.integer) = Widget::CMYK;;} break; case 1118: #line 2626 "parser.Y" {fr->regionHighliteBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1119: #line 2628 "parser.Y" {fr->regionHighliteMotionCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1120: #line 2629 "parser.Y" {fr->regionHighliteEndCmd();;} break; case 1121: #line 2630 "parser.Y" {fr->regionHighliteShiftEndCmd();;} break; case 1122: #line 2634 "parser.Y" {fr->regionSelectBeginCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1123: #line 2635 "parser.Y" {fr->regionSelectMotionCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1124: #line 2636 "parser.Y" {fr->regionSelectEndCmd();;} break; case 1125: #line 2637 "parser.Y" {fr->regionSelectShiftEndCmd();;} break; case 1126: #line 2640 "parser.Y" {(yyval.integer) = Frame3dBase::MIP;;} break; case 1127: #line 2641 "parser.Y" {(yyval.integer) = Frame3dBase::AIP;;} break; case 1128: #line 2644 "parser.Y" {fr->setRGBChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1129: #line 2645 "parser.Y" {fr->setRGBSystemCmd((Coord::CoordSystem)(yyvsp[(2) - (2)].integer));;} break; case 1130: #line 2646 "parser.Y" {fr->setRGBViewCmd((yyvsp[(2) - (4)].integer),(yyvsp[(3) - (4)].integer),(yyvsp[(4) - (4)].integer));;} break; case 1131: #line 2649 "parser.Y" {fr->rotateCmd(degToRad((yyvsp[(1) - (1)].real)));;} break; case 1132: #line 2650 "parser.Y" {fr->rotateCmd(degToRad((yyvsp[(1) - (2)].real)));;} break; case 1134: #line 2652 "parser.Y" {fr->rotateToCmd(degToRad((yyvsp[(2) - (2)].real)));;} break; case 1135: #line 2653 "parser.Y" {fr->rotateToCmd(degToRad((yyvsp[(2) - (3)].real)));;} break; case 1136: #line 2656 "parser.Y" {fr->rotateBeginCmd();;} break; case 1137: #line 2657 "parser.Y" {fr->rotateMotionCmd(degToRad((yyvsp[(1) - (1)].real)));;} break; case 1138: #line 2658 "parser.Y" {fr->rotateEndCmd();;} break; case 1142: #line 2664 "parser.Y" {fr->savePhotoCmd((yyvsp[(2) - (2)].str));;} break; case 1143: #line 2668 "parser.Y" {fr->saveArrayFileCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1144: #line 2670 "parser.Y" {fr->saveArrayChannelCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1145: #line 2672 "parser.Y" {fr->saveArraySocketCmd((yyvsp[(2) - (3)].integer), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1147: #line 2677 "parser.Y" {fr->saveArrayRGBCubeFileCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1148: #line 2679 "parser.Y" {fr->saveArrayRGBCubeChannelCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1149: #line 2681 "parser.Y" {fr->saveArrayRGBCubeSocketCmd((yyvsp[(2) - (3)].integer), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1159: #line 2694 "parser.Y" {fr->saveFitsFileCmd((yyvsp[(2) - (2)].str));;} break; case 1160: #line 2695 "parser.Y" {fr->saveFitsChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1161: #line 2696 "parser.Y" {fr->saveFitsSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1162: #line 2699 "parser.Y" {fr->saveFitsTableFileCmd((yyvsp[(2) - (2)].str));;} break; case 1163: #line 2700 "parser.Y" {fr->saveFitsTableChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1164: #line 2701 "parser.Y" {fr->saveFitsTableSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1165: #line 2704 "parser.Y" {fr->saveFitsSliceFileCmd((yyvsp[(2) - (2)].str));;} break; case 1166: #line 2705 "parser.Y" {fr->saveFitsSliceChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1167: #line 2706 "parser.Y" {fr->saveFitsSliceSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1168: #line 2709 "parser.Y" {fr->saveFitsExtCubeFileCmd((yyvsp[(2) - (2)].str));;} break; case 1169: #line 2710 "parser.Y" {fr->saveFitsExtCubeChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1170: #line 2711 "parser.Y" {fr->saveFitsExtCubeSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1172: #line 2715 "parser.Y" {fr->saveFitsMosaicFileCmd((yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].integer));;} break; case 1173: #line 2716 "parser.Y" {fr->saveFitsMosaicChannelCmd((yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].integer));;} break; case 1174: #line 2717 "parser.Y" {fr->saveFitsMosaicSocketCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 1175: #line 2720 "parser.Y" {fr->saveFitsMosaicImageFileCmd((yyvsp[(2) - (2)].str));;} break; case 1176: #line 2721 "parser.Y" {fr->saveFitsMosaicImageChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1177: #line 2722 "parser.Y" {fr->saveFitsMosaicImageSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1178: #line 2725 "parser.Y" {fr->saveFitsRGBImageFileCmd((yyvsp[(2) - (2)].str));;} break; case 1179: #line 2726 "parser.Y" {fr->saveFitsRGBImageChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1180: #line 2727 "parser.Y" {fr->saveFitsRGBImageSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1181: #line 2730 "parser.Y" {fr->saveFitsRGBCubeFileCmd((yyvsp[(2) - (2)].str));;} break; case 1182: #line 2731 "parser.Y" {fr->saveFitsRGBCubeChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1183: #line 2732 "parser.Y" {fr->saveFitsRGBCubeSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1184: #line 2735 "parser.Y" {fr->saveFitsResampleFileCmd((yyvsp[(2) - (2)].str));;} break; case 1185: #line 2736 "parser.Y" {fr->saveFitsResampleChannelCmd((yyvsp[(2) - (2)].str));;} break; case 1186: #line 2737 "parser.Y" {fr->saveFitsResampleSocketCmd((yyvsp[(2) - (2)].integer));;} break; case 1187: #line 2741 "parser.Y" {fr->saveNRRDFileCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1188: #line 2743 "parser.Y" {fr->saveNRRDChannelCmd((yyvsp[(2) - (3)].str), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1189: #line 2745 "parser.Y" {fr->saveNRRDSocketCmd((yyvsp[(2) - (3)].integer), (FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 1190: #line 2748 "parser.Y" {fr->smoothCmd((FitsImage::SmoothFunction)(yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 1191: #line 2749 "parser.Y" {fr->smoothDeleteCmd();;} break; case 1192: #line 2752 "parser.Y" {(yyval.integer) = FitsImage::BOXCAR;;} break; case 1193: #line 2753 "parser.Y" {(yyval.integer) = FitsImage::GAUSSIAN;;} break; case 1194: #line 2754 "parser.Y" {(yyval.integer) = FitsImage::TOPHAT;;} break; case 1195: #line 2757 "parser.Y" {fr->updateFitsCmd(0);;} break; case 1196: #line 2759 "parser.Y" {fr->updateFitsCmd((yyvsp[(1) - (5)].integer),BBox((yyvsp[(2) - (5)].real),(yyvsp[(3) - (5)].real),(yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)),0);;} break; case 1197: #line 2760 "parser.Y" {fr->updateFitsCmd(1);;} break; case 1198: #line 2762 "parser.Y" {fr->updateFitsCmd((yyvsp[(2) - (6)].integer),BBox((yyvsp[(3) - (6)].real),(yyvsp[(4) - (6)].real),(yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real)),1);;} break; case 1200: #line 2766 "parser.Y" {fr->sliceCmd(2, (yyvsp[(1) - (1)].integer));;} break; case 1201: #line 2767 "parser.Y" {fr->sliceCmd((yyvsp[(1) - (2)].integer), (yyvsp[(2) - (2)].integer));;} break; case 1202: #line 2770 "parser.Y" {fr->warpCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1203: #line 2771 "parser.Y" {fr->warpToCmd(Vector((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real)));;} break; case 1204: #line 2775 "parser.Y" {fr->wcsCmd((Coord::CoordSystem)(yyvsp[(1) - (3)].integer), (Coord::SkyFrame)(yyvsp[(2) - (3)].integer), (Coord::SkyFormat)(yyvsp[(3) - (3)].integer));;} break; case 1206: #line 2777 "parser.Y" {fr->wcsResetCmd((yyvsp[(2) - (2)].integer));;} break; case 1209: #line 2782 "parser.Y" {fr->wcsAppendCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 1210: #line 2783 "parser.Y" {fr->wcsAppendCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].str));;} break; case 1211: #line 2784 "parser.Y" {fr->wcsAppendTxtCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 1212: #line 2787 "parser.Y" {fr->wcsReplaceCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 1213: #line 2788 "parser.Y" {fr->wcsReplaceCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].str));;} break; case 1214: #line 2789 "parser.Y" {fr->wcsReplaceTxtCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].str));;} break; case 1215: #line 2792 "parser.Y" {fr->wcsAlignCmd((yyvsp[(1) - (1)].integer));;} break; case 1216: #line 2794 "parser.Y" { // used by backup fr->wcsAlignCmd((yyvsp[(1) - (3)].integer), (Coord::CoordSystem)(yyvsp[(2) - (3)].integer), (Coord::SkyFrame)(yyvsp[(3) - (3)].integer)); ;} break; case 1217: #line 2799 "parser.Y" { fr->wcsAlignCmd((yyvsp[(1) - (4)].integer), (FitsImage*)(yyvsp[(2) - (4)].ptr), (Coord::CoordSystem)(yyvsp[(3) - (4)].integer), (Coord::SkyFrame)(yyvsp[(4) - (4)].integer)); ;} break; case 1218: #line 2805 "parser.Y" { #ifdef _WIN32 fr->win32PrintCmd(); #endif ;} break; case 1219: #line 2812 "parser.Y" {fr->zoomCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1220: #line 2814 "parser.Y" {fr->zoomAboutCmd(Vector((yyvsp[(1) - (5)].real),(yyvsp[(2) - (5)].real)),Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)));;} break; case 1221: #line 2816 "parser.Y" { // backward compatibility fr->zoomAboutCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real))); ;} break; case 1222: #line 2821 "parser.Y" {fr->zoomAboutCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)),Vector((yyvsp[(6) - (6)].vector)), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer),(Coord::SkyFrame)(yyvsp[(5) - (6)].integer));;} break; case 1224: #line 2826 "parser.Y" {fr->zoomToFitCmd(1);;} break; case 1225: #line 2827 "parser.Y" {fr->zoomToFitCmd((yyvsp[(2) - (2)].real));;} break; case 1226: #line 2828 "parser.Y" {fr->zoomToCmd(Vector((yyvsp[(1) - (2)].real),(yyvsp[(2) - (2)].real)));;} break; case 1227: #line 2830 "parser.Y" {fr->zoomToAboutCmd(Vector((yyvsp[(1) - (5)].real),(yyvsp[(2) - (5)].real)),Vector((yyvsp[(4) - (5)].real),(yyvsp[(5) - (5)].real)));;} break; case 1228: #line 2832 "parser.Y" { // backward compatibility fr->zoomToAboutCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)),Vector((yyvsp[(5) - (6)].real),(yyvsp[(6) - (6)].real))); ;} break; case 1229: #line 2837 "parser.Y" {fr->zoomToAboutCmd(Vector((yyvsp[(1) - (6)].real),(yyvsp[(2) - (6)].real)), Vector((yyvsp[(6) - (6)].vector)), (Coord::CoordSystem)(yyvsp[(4) - (6)].integer), (Coord::SkyFrame)(yyvsp[(5) - (6)].integer));;} break; /* Line 1267 of yacc.c. */ #line 10606 "parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 2841 "parser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/text.h�������������������������������������������������������������������������0000644�0001750�0001750�00000003065�11732712252�014461� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __text_h__ #define __text_h__ #include "marker.h" class Text : public Marker { private: int rotate; private: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderXText(Drawable, Coord::InternalSystem, RenderMode) {} void renderXInclude(Drawable, Coord::InternalSystem, RenderMode) {} void renderPS(int); void renderPSText(int) {} void renderPSInclude(int) {} #ifdef _MACOSX void renderMACOSX(); void renderMACOSXText() {} void renderMACOSXInclude() {} #endif #ifdef _WIN32 void renderWIN32(); void renderWIN32Text() {} void renderWIN32Include() {} #endif void updateHandles(); void calcAllBBox(); public: Text(const Text&); Text(Base* p, const Vector& ctr, double a, int r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Text(*this);} int isIn(const Vector&); void editBegin(int) {} void edit(const Vector& v, int h) {} void editEnd() {} void setRotate(int); int getRotate() {return rotate;} void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/polygon.h����������������������������������������������������������������������0000644�0001750�0001750�00000004054�12030663665�015170� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __polygon_h__ #define __polygon_h__ #include "marker.h" #include "list.h" class Polygon : public Marker { protected: List<Vertex> vertex; void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif void updateHandles(); void moveVertex(const Vector&, int); void recalcCenter(); public: Polygon(const Polygon&); Polygon(Base* p, const Vector& ctr, const Vector& b, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Polygon(Base* p, const List<Vertex>& v, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Polygon(*this);} void updateCoords(const Matrix&); void edit(const Vector&, int); void rotate(const Vector&, int); int isIn(const Vector& vv) {return isIn(vv, Coord::CANVAS);} int isIn(const Vector&, Coord::InternalSystem); void analysis(AnalysisTask, int); void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod); void analysisStats(Coord::CoordSystem); void createVertex(int, const Vector&); void deleteVertex(int); int getSegment(const Vector&); void reset(const Vector&); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); virtual void listCiao(ostream&, Coord::CoordSystem, int); virtual void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOimage(ostream&, int); virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3d.h����������������������������������������������������������������������0000644�0001750�0001750�00000004154�12075052321�015011� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3d_h__ #define __frame3d_h__ #include "context.h" #include "frame3dbase.h" #include "colorscale.h" typedef struct { Frame3dBase::RenderMethod renderMethod; int width; Coord::InternalSystem sys; float** zbuf; unsigned char** mkzbuf; Context* context; int* xid; int* yid; int start; int stop; int zstart; int zstop; int rays; int abort; int done; } t_arg; class Frame3d : public virtual Frame3dBase { protected: float** zbuf; unsigned char** mkzbuf; int cmapID; // current colormap id float bias; // current colormap bias float contrast; // current colormap contrast int colorCount; // number of dynamic colors ColorScale* colorScale; // current color scale unsigned char* colorCells; // current color values unsigned short* indexCells; // current color indices pthread_t* thread; t_arg* targ; int nrays; int* xid; int* yid; Tcl_TimerToken timer; private: BBox3d imageBounds(int, int, Coord::InternalSystem); void cancelImage(); unsigned char* fillImageColor(int, int); unsigned char* fillImageJoin(int, int, Coord::InternalSystem); unsigned char* fillImageDetach(int, int, Coord::InternalSystem); void reset(); void setKeyFits() {} void pushMatrices(); void pushMagnifierMatrices(); void pushPannerMatrices(); void pushPSMatrices(float, int, int); void unloadFits(); protected: int isFrame3d() {return 1;} unsigned char* fillImage(int width, int height, Coord::InternalSystem); void updateColorCells(unsigned short*, unsigned char*, int); int validColorScale() {return colorScale ? 1 : 0;} public: Frame3d(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Frame3d(); void setTimer(Tcl_TimerToken tt) {timer = tt;} int updateImage(); void getColorbarCmd(); void getRGBChannelCmd(); void getRGBSystemCmd(); void getRGBViewCmd(); void getTypeCmd(); void savePhotoCmd(const char*); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/coord.C������������������������������������������������������������������������0000644�0001750�0001750�00000015626�11727743761�014561� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "coord.h" #include "util.h" Coord coord; char* Coord::coordSystemStr_[] = { "data", "image", "physical", "amplifier", "detector", "wcs", "wcsa", "wcsb", "wcsc", "wcsd", "wcse", "wcsf", "wcsg", "wcsh", "wcsi", "wcsj", "wcsk", "wcsl", "wcsm", "wcsn", "wcso", "wcsp", "wcsq", "wcsr", "wcss", "wcst", "wcsu", "wcsv", "wcsw", "wcsx", "wcsy", "wcsz", "wcs0" }; char* Coord::skyFrameStr_[] = { "fk4", "fk4-no-e", "fk5", "icrs", "galactic", "supergalactic", "ecliptic", "helioecliptic", "gappt" }; char* Coord::skyFormatStr_[] = { "degrees", "sexagesimal", }; char* Coord::skyDistStr_[] = { "degrees", "arcmin", "arcsec" }; void Coord::listCoordSystem(ostream& str, CoordSystem sys, SkyFrame sky, int wcs, int wcsequ) { switch (sys) { case IMAGE: str << "image"; return; case PHYSICAL: str << "physical"; return; case DETECTOR: str << "detector"; return; case AMPLIFIER: str << "amplifier"; return; default: { if (wcs) if (sys == WCS0) str << "wcs0" << ';'; else if (sys == WCS && !wcsequ) str << "wcs" << ';'; else if (sys > WCS && !wcsequ) str << "wcs" << (char)(sys-WCS+'`') << ';'; if (wcsequ) { switch (sky) { case FK4: str << "fk4"; return; case FK4_NO_E: str << "fk4-no-e"; return; case FK5: str << "fk5"; return; case ICRS: str << "icrs"; return; case GALACTIC: str << "galactic"; return; case SUPERGALACTIC: str << "supergalactic"; return; case ECLIPTIC: str << "ecliptic"; return; case HELIOECLIPTIC: str << "helioecliptic"; return; } } } } } void Coord::listDistSystem(ostream& str, CoordSystem sys, SkyDist format, int wcsequ) { switch (sys) { case IMAGE: str << "image"; return; case PHYSICAL: str << "physical"; return; case DETECTOR: str << "detector"; return; case AMPLIFIER: str << "amplifier"; return; default: if (wcsequ) switch (format) { case DEGREE: str << "degrees"; return; case ARCMIN: str << "arcmin"; return; case ARCSEC: str << "arcsec"; return; } else { str << "pixels"; return; } } } void Coord::listProsCoordSystem(ostream& str, CoordSystem sys, SkyFrame sky) { switch (sys) { case IMAGE: str << "logical"; return; case PHYSICAL: str << "physical"; return; case DETECTOR: str << "detector"; return; case AMPLIFIER: str << "amplifier"; return; default: switch (sky) { case FK4: str << "b1950"; return; case FK4_NO_E: str << "fk4-no-e"; return; case FK5: str << "j2000"; return; case ICRS: str << "icrs"; return; case GALACTIC: str << "galactic"; return; case SUPERGALACTIC: str << "supergalactic"; return; case ECLIPTIC: str << "ecliptic"; return; case HELIOECLIPTIC: str << "helioecliptic"; return; } } } void Coord::strToCoordSystem(const char* str, CoordSystem wcssys, CoordSystem* sys, SkyFrame* sky) { if (!str) { *sys = PHYSICAL; *sky = FK5; } else if (STRCMP(str,"image",5)) { *sys = IMAGE; *sky = FK5; } else if (STRCMP(str,"physical",8)) { *sys = PHYSICAL; *sky = FK5; } else if (STRCMP(str,"amplifier",9)) { *sys = AMPLIFIER; *sky = FK5; } else if (STRCMP(str,"detector",9)) { *sys = DETECTOR; *sky = FK5; } else if (STRCMP(str,"fk4-no-e",8)) { *sys = wcssys; *sky = FK4_NO_E; } else if (STRCMP(str,"fk4",3)) { *sys = wcssys; *sky = FK4; } else if (STRCMP(str,"fk5",3)) { *sys = wcssys; *sky = FK5; } else if (STRCMP(str,"icrs",4)) { *sys = wcssys; *sky = ICRS; } else if (STRCMP(str,"galactic",8)) { *sys = wcssys; *sky = GALACTIC; } else if (STRCMP(str,"supergalactic",12)) { *sys = wcssys; *sky = SUPERGALACTIC; } else if (STRCMP(str,"ecliptic",8)) { *sys = wcssys; *sky = ECLIPTIC; } else if (STRCMP(str,"helioecliptic",12)) { *sys = wcssys; *sky = HELIOECLIPTIC; } else if (STRCMP(str,"wcs",3)) { *sys = wcssys; *sky = FK5; } else if (STRCMP(str,"linear",6)) { *sys = wcssys; *sky = FK5; } else { *sys = PHYSICAL; *sky = FK5; } } void Coord::strToSkyFormat(const char* str, SkyFormat* format) { if (!str) *format = DEGREES; else if (STRCMP(str,"degrees",7)) *format = DEGREES; else if (STRCMP(str,"degree",6)) *format = DEGREES; else if (STRCMP(str,"deg",3)) *format = DEGREES; else if (STRCMP(str,"hms",3)) *format = SEXAGESIMAL; else if (STRCMP(str,"h:m:s",5)) *format = SEXAGESIMAL; else if (STRCMP(str,"\"h:m:s\"",7)) *format = SEXAGESIMAL; else if (STRCMP(str,"dms",3)) *format = SEXAGESIMAL; else if (STRCMP(str,"d:m:s",5)) *format = SEXAGESIMAL; else if (STRCMP(str,"\"d:m:s\"",7)) *format = SEXAGESIMAL; else *format = DEGREES; } void Coord::strToSkyDist(const char* str, SkyDist* dist) { if (!str) *dist = DEGREE; else if (STRCMP(str,"degrees",7)) *dist = DEGREE; else if (STRCMP(str,"degree",6)) *dist = DEGREE; else if (STRCMP(str,"deg",3)) *dist = DEGREE; else if (STRCMP(str,"arcminute",9)) *dist = ARCMIN; else if (STRCMP(str,"arcmin",6)) *dist = ARCMIN; else if (STRCMP(str,"arcsecond",9)) *dist = ARCSEC; else if (STRCMP(str,"arcsec",6)) *dist = ARCSEC; else *dist = DEGREE; } void Coord::strToAngleFormat(const char* str, AngleFormat* format) { if (!str) *format = DEG; else if (STRCMP(str,"degrees",7)) *format = DEG; else if (STRCMP(str,"degree",6)) *format = DEG; else if (STRCMP(str,"deg",3)) *format = DEG; else if (STRCMP(str,"radian",6)) *format = RAD; else if (STRCMP(str,"rad",3)) *format = RAD; else *format = DEG; } void Coord::strToDistSystem(const char* str, CoordSystem wcssys, CoordSystem* sys, SkyDist* dist) { if (!str) { *sys = PHYSICAL; *dist = DEGREE; } else if (STRCMP(str,"image",5)) { *sys = IMAGE; *dist = DEGREE; } else if (STRCMP(str,"physical",8)) { *sys = PHYSICAL; *dist = DEGREE; } else if (STRCMP(str,"amplifier",9)) { *sys = AMPLIFIER; *dist = DEGREE; } else if (STRCMP(str,"detector",8)) { *sys = DETECTOR; *dist = DEGREE; } else if (STRCMP(str,"degrees",7)) { *sys = wcssys; *dist = DEGREE; } else if (STRCMP(str,"arcmin",6)) { *sys = wcssys; *dist = ARCMIN; } else if (STRCMP(str,"arcsec",6)) { *sys = wcssys; *dist = ARCSEC; } else if (STRCMP(str,"pixels",6)) { *sys = PHYSICAL; *dist = DEGREE; } else { *sys = PHYSICAL; *dist = DEGREE; } } ����������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsnrrd.C���������������������������������������������������������������������0000644�0001750�0001750�00000002025�12044046255�015256� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" #include "nrrdgzip.h" void FitsImage::initNRRD() { if (compress_) delete compress_; compress_ = NULL; switch (fits_->pNRRDEncoding()) { case FitsFile::RAW: break; case FitsFile::GZIP: switch (fits_->pBitpix()) { case 8: compress_ = new FitsNRRDGzipm<unsigned char>(fits_); break; case 16: compress_ = new FitsNRRDGzipm<short>(fits_); break; case -16: compress_ = new FitsNRRDGzipm<unsigned short>(fits_); break; case 32: compress_ = new FitsNRRDGzipm<int>(fits_); break; case 64: compress_ = new FitsNRRDGzipm<long long>(fits_); break; case -32: compress_ = new FitsNRRDGzipm<float>(fits_); break; case -64: compress_ = new FitsNRRDGzipm<double>(fits_); break; } break; default: break; } return; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametruecolor.h���������������������������������������������������������������0000644�0001750�0001750�00000002126�11727730000�016516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametruecolor_h__ #define __frametruecolor_h__ #include "frame.h" #include "frametrue.h" class FrameTrueColor : public virtual FrameBase, public Frame, public FrameTrue { protected: long* colormapData; private: unsigned char* blend(unsigned char*, unsigned char*, int, int); void buildXImage(XImage*, Coord::InternalSystem); unsigned char* fillImage(int, int, Coord::InternalSystem); unsigned char* fillMask(FitsMask*, int, int, Coord::InternalSystem); void pushMatrices(); void pushMagnifierMatrices(); void pushPannerMatrices(); void pushPSMatrices(float, int, int); public: FrameTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~FrameTrueColor(); void colormapCmd(int, float, float, int, unsigned short*, unsigned char*, int); void colormapBeginCmd(); void colormapMotionCmd(int, float, float, int, unsigned short*, unsigned char*, int); void colormapEndCmd(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid.h�������������������������������������������������������������������������0000644�0001750�0001750�00000001711�12001327760�014412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid_h__ #define __grid_h__ #include <tk.h> #include "coord.h" class Grid { public: enum GridType {ANALYSIS,PUBLICATION}; protected: GridType type_; Coord::CoordSystem system_; Coord::SkyFrame sky_; Coord::SkyFormat skyFormat_; char* vars_; public: Grid(Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, GridType, const char*); virtual ~Grid(); virtual const char* option() =0; virtual void x11() =0; virtual void ps(int) =0; #ifdef _MACOSX virtual void macosx() =0; #endif #ifdef _WIN32 virtual void win32() =0; #endif GridType type() {return type_;} Coord::CoordSystem system() {return system_;} Coord::SkyFrame sky() {return sky_;} Coord::SkyFormat skyFormat() {return skyFormat_;} const char* vars() {return vars_;} }; #endif �������������������������������������������������������./saods9/saotk/frame/base.C�������������������������������������������������������������������������0000644�0001750�0001750�00000150301�12075344650�014342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "base.h" #include "context.h" #include "fitsimage.h" #include "marker.h" #include "ps.h" #include "tkpostscript.h" // Debug int DebugAST= 0; int DebugBin= 0; int DebugCompress= 0; int DebugCrop= 0; int DebugGZ= 0; int DebugMosaic= 0; int DebugPerf= 0; int DebugRGB= 0; int DebugWCS= 0; // Parser Stuff #undef yyFlexLexer #define yyFlexLexer frFlexLexer #include <FlexLexer.h> void* frlval; extern int frparse(Base*, frFlexLexer*); int frlex(void* vval, frFlexLexer* ll) { frlval = vval; return ll ? ll->yylex() : 0; } void frerror(Base* fr, frFlexLexer* ll, const char* m) { fr->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { fr->error(": "); fr->error(cmd); } } // Base Member Functions Base::Base(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Widget(i, c, item) { threads_ = 4; baseXImage = NULL; basePixmap = 0; needsUpdate = NOUPDATE; syncUpdate = 0; currentContext = NULL; keyContext = NULL; keyContextSet =0; orientation = Coord::NORMAL; zoom_ = Vector(1,1); rotation = 0; rotateRotation = 0; preservePan = 0; panPM = 0; panGCXOR = NULL; rotateGCXOR = NULL; pannerPixmap = 0; pannerXImage = NULL; pannerWidth = 0; pannerHeight = 0; pannerName[0] = '\0'; usePanner = 0; pannerGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetLineAttributes(display, pannerGC, 1, LineSolid, CapButt, JoinMiter); magnifierPixmap = 0; magnifierXImage = NULL; magnifierWidth = 0; magnifierHeight = 0; magnifierZoom_ = 4; magnifierName[0] = '\0'; useMagnifier = 0; useMagnifierGraphics = 1; useMagnifierCursor = 1; magnifierColorName = dupstr("white"); wcsSystem_ = Coord::WCS; wcsSky_ = Coord::FK5; wcsSkyFormat_ = Coord::DEGREES; wcsAlign_ = 0; wcsAlt_ =0; xySystem_ = Coord::IMAGE; xySky_ = Coord::FK5; wcsOrientation = Coord::NORMAL; wcsRotation = 0; irafOrientation = (Coord::Orientation)-1; maskColorName = dupstr("red"); maskAlpha = 1; maskMark = 1; invert = 0; binFunction_ = FitsHist::SUM; binFactor_ = Vector(1,1); binBufferSize_ = 1024; binDepth_ = 1; doSmooth_ = 0; smoothFunction_ = FitsImage::GAUSSIAN; smoothRadius_ = 3; highliteGC = NULL; useHighlite = 0; useCrosshair = 0; showMarkers = 1; showMarkersText = 1; centroidAuto = 0; centroidIteration = 5; centroidRadius = 10; preserveMarkers = 0; markerGC = NULL; markerGCXOR = NULL; selectGCXOR = NULL; grid = NULL; gridGC = NULL; contourGC = NULL; bgColorName = dupstr("white"); bgColor = getXColor("white"); memset(bgTrueColor_,255,4); nanColorName = dupstr("white"); nanColor = getXColor("white"); memset(nanTrueColor_,255,4); dlist[0] = 8; dlist[1] = 3; colorbartag =NULL; markers = &userMarkers; undoMarkers = &undoUserMarkers; pasteMarkers = &pasteUserMarkers; undoMarkerType = NONE; editMarker = NULL; rotateMarker = NULL; compositeMarker = NULL; imageToData = Translate(-.5, -.5); dataToImage = Translate( .5, .5); inverseScale = NULL; } Base::~Base() { if (basePixmap) Tk_FreePixmap(display, basePixmap); if (baseXImage) XDestroyImage(baseXImage); if (pannerPixmap) Tk_FreePixmap(display, pannerPixmap); if (pannerXImage) XDestroyImage(pannerXImage); if (panPM) Tk_FreePixmap(display, panPM); if (panGCXOR) XFreeGC(display, panGCXOR); if (rotateGCXOR) XFreeGC(display, rotateGCXOR); if (pannerGC) XFreeGC(display, pannerGC); if (magnifierPixmap) Tk_FreePixmap(display, magnifierPixmap); if (magnifierXImage) XDestroyImage(magnifierXImage); if (highliteGC) XFreeGC(display, highliteGC); if (maskColorName) delete [] maskColorName; if (markerGC) XFreeGC(display, markerGC); if (markerGCXOR) XFreeGC(display, markerGCXOR); if (selectGCXOR) XFreeGC(display, selectGCXOR); if (grid) delete grid; if (gridGC) XFreeGC(display, gridGC); if (contourGC) XFreeGC(display, contourGC); if (bgColorName) delete [] bgColorName; if (nanColorName) delete [] nanColorName; if (colorbartag) delete [] colorbartag; if (magnifierColorName) delete [] magnifierColorName; if (inverseScale) delete inverseScale; } void Base::alignWCS() { if (!wcsAlign_ || !context->cfits || !hasWCS(wcsSystem_)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; return; } calcAlignWCS(context->cfits, wcsSystem_, wcsSky_, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation); } void Base::alignWCS(Coord::CoordSystem sys, Coord::SkyFrame sky) { if (!wcsAlign_ || !context->cfits || !hasWCS(sys)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; return; } calcAlignWCS(context->cfits, sys, sky, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation); } void Base::alignWCS(FitsImage* ptr, Coord::CoordSystem sys) { if (!wcsAlign_ || !ptr || !context->cfits || !hasWCS(wcsSystem_)) { wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; return; } calcAlignWCS(ptr, context->cfits, sys, wcsSystem_, wcsSky_, &wcsOrientation, &wcsOrientationMatrix, &wcsRotation, &zoom_); } void Base::calcAlignWCS(FitsImage* fits1, Coord::CoordSystem sys1, Coord::SkyFrame sky, Coord::Orientation* orientation, Matrix* oo, double* rotation) { // init *orientation = Coord::NORMAL; oo->identity(); *rotation = 0; if (!fits1 || !fits1->hasWCS(sys1)) return; // orientation *orientation = fits1->getWCSOrientation(sys1,sky); switch (*orientation) { case Coord::NORMAL: oo->identity(); break; case Coord::XX: *oo = FlipX(); break; } // rotation *rotation = fits1->getWCSRotation(sys1,sky); } void Base::calcAlignWCS(FitsImage* fits1, FitsImage* fits2, Coord::CoordSystem sys1, Coord::CoordSystem sys2, Coord::SkyFrame sky, Coord::Orientation* orientation, Matrix* oo, double* rotation, Vector* zoom) { // init *orientation = Coord::NORMAL; oo->identity(); *rotation = 0; if ((!fits1 || !fits2) || (fits1 == fits2) || !(fits1->hasWCS(sys1)) || !(fits2->hasWCS(sys2))) return; Vector org1 = fits1->center(); Vector orval1 = fits1->pix2wcs(org1,sys1,sky); // orientation *orientation = fits2->getWCSOrientation(sys2,sky); switch (*orientation) { case Coord::NORMAL: oo->identity(); break; case Coord::XX: *oo = FlipX(); break; } // rotation Vector orpix = fits2->wcs2pix(orval1, sys2, sky); Vector delta = fits2->getWCScdelt(sys2).abs(); Vector npix = fits2->wcs2pix(Vector(orval1[0],orval1[1]+delta[1]),sys2,sky); Vector north = (npix-orpix).normalize(); Vector epix = fits2->wcs2pix(Vector(orval1[0]+delta[0],orval1[1]),sys2,sky); Vector east = (epix-orpix).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) { *rotation = 0; *orientation = Coord::NORMAL; oo->identity(); return; } if ((fits2->getWCS(sys2))->imflip) *rotation = (north.angle()-M_PI_2); else *rotation = -(north.angle()-M_PI_2); // zoom Vector cd1 = fits1->getWCScdelt(sys1); Vector cd2 = fits2->getWCScdelt(sys2); *zoom = Vector((*zoom)[0]/fabs(cd1[0]/cd2[0]), (*zoom)[1]/fabs(cd1[1]/cd2[1])); } Matrix Base::calcAlignWCS(FitsImage* fits1, FitsImage* fits2, Coord::CoordSystem sys1, Coord::CoordSystem sys2, Coord::SkyFrame sky) { if ((!fits1 || !fits2) || (fits1 == fits2) || !(fits1->hasWCS(sys1)) || !(fits2->hasWCS(sys2))) return Matrix(); Vector org1 = fits1->center(); Vector orval1 = fits1->pix2wcs(org1,sys1,sky); Vector org2 = fits2->center(); Vector orval2 = fits2->pix2wcs(org2,sys2,sky); // orientation Coord::Orientation orientation =Coord::NORMAL; { Coord::Orientation o1 = fits1->getWCSOrientation(sys1,sky); Coord::Orientation o2 = fits2->getWCSOrientation(sys2,sky); switch (o1) { case Coord::NORMAL: { switch (o2) { case Coord::NORMAL: orientation = Coord::NORMAL; break; case Coord::XX: orientation = Coord::XX; break; } } break; case Coord::XX: { switch (o2) { case Coord::NORMAL: orientation = Coord::XX; break; case Coord::XX: orientation = Coord::NORMAL; break; } } break; } } // zoom Vector zoom =Vector(1,1); { Vector cd1 = fits1->getWCScdelt(sys1); Vector cd2 = fits2->getWCScdelt(sys2); zoom = Vector(cd2[0]/cd1[0], cd2[1]/cd1[1]).abs(); } // rotation double rotation =0; { double r1 =0; { Vector orpix = fits1->wcs2pix(orval1, sys1, sky); Vector delta = fits1->getWCScdelt(sys1).abs(); Vector npix = fits1->wcs2pix(Vector(orval1[0],orval1[1]+delta[1]),sys1,sky); Vector north = (npix-orpix).normalize(); Vector epix = fits1->wcs2pix(Vector(orval1[0]+delta[0],orval1[1]),sys1,sky); Vector east = (epix-orpix).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) return Matrix(); if ((fits1->getWCS(sys1))->imflip) r1 = (north.angle()-M_PI_2); else r1 = -(north.angle()-M_PI_2); } double r2 =0; { Vector orpix = fits2->wcs2pix(orval1, sys2, sky); Vector delta = fits2->getWCScdelt(sys2).abs(); Vector npix = fits2->wcs2pix(Vector(orval1[0],orval1[1]+delta[1]),sys2,sky); Vector north = (npix-orpix).normalize(); Vector epix = fits2->wcs2pix(Vector(orval1[0]+delta[0],orval1[1]),sys2,sky); Vector east = (epix-orpix).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) return Matrix(); if ((fits2->getWCS(sys2))->imflip) r2 = north.angle()-M_PI_2; else r2 = -(north.angle()-M_PI_2); } if ((fits1->getWCS(sys1))->imflip) rotation = -(r1-r2); else rotation = r1-r2; } // origin Vector origin; { Vector orpix1 = fits1->wcs2pix(orval2,sys1,sky) * imageToData; Vector orpix2 = fits2->wcs2pix(orval2,sys2,sky) * imageToData; origin = orpix1 - orpix2; } // matrix { Matrix flip; switch (orientation) { case Coord::NORMAL: break; case Coord::XX: flip = FlipX(); break; } Vector orpix2 = fits2->wcs2pix(orval2,sys2,sky) * imageToData; return Translate(-orpix2) * flip * Scale(zoom) * Rotate(rotation) * Translate(orpix2) * Translate(origin); } } double Base::calcZoom(Vector src, Vector dest) { // we need to calculate the width and height of the rotated image // so we can derived a zoom factor to shrink it to fit the requested size Vector cc = src/2.; Vector ll; Vector lr(src[0],0); Vector ur(src); Vector ul(0,src[1]); Matrix mm = Translate(-cc) * Rotate(wcsRotation) * Rotate(rotation); BBox bb(ll*mm); bb.bound(lr*mm); bb.bound(ur*mm); bb.bound(ul*mm); Vector bs = bb.size(); double r0 = dest[0]/bs[0]; double r1 = dest[1]/bs[1]; return r0>r1 ? r1:r0; } void Base::centerImage() { if (!keyContext->fits) { cursor = Vector(); return; } // This is here because we need mapToRef to be up-to-date updateMatrices(); updatePannerMatrices(); // imageCenter is in IMAGE coords Vector aa = imageCenter(keyContext->frScale.scanMode()); // always center to center of pixel, even for even sized image Vector bb = (aa*Translate(.5,.5)).floor(); // cursor is in REF coords cursor = keyContext->fits->mapToRef(bb,Coord::IMAGE,Coord::FK5); } void Base::coordToTclArray(FitsImage* ptr, const Vector3d& vv, Coord::CoordSystem out, Precision pp, const char* var, const char* base) { Vector rr = ptr->mapFromRef(vv, out); doubleToTclArray(rr[0], pp, var, base, "x"); doubleToTclArray(rr[1], pp, var, base, "y"); } void Base::coord3ToTclArray(FitsImage* ptr, const Vector3d& vv, Coord::CoordSystem out, Precision pp, const char* var, const char* base) { double ss = ptr->mapFromRef3(((Vector3d&)vv)[2]+.5,out,2); doubleToTclArray(ss, pp, var, base, "z"); } int Base::doRender() { return context->cfits ? 1 : 0; } void Base::doubleToTclArray(double d, Precision p, const char* var, const char* base, const char* mod) { ostringstream str; str << base << "," << mod << ends; ostringstream vstr; switch (p) { case DEFAULT: vstr << d << ends; break; case FIXED: vstr << setiosflags(ios::fixed) << setw(9) << setprecision(3) << d << ends; break; case SCIENTIFIC: vstr << setiosflags(ios::scientific) << setprecision(8) << d << ends; break; case INTEGER: vstr << (int)d << ends; break; } Tcl_SetVar2(interp, (char*)var, str.str().c_str(), vstr.str().c_str(), 0); } FitsImage* Base::findFits() { return keyContext->fits; } FitsImage* Base::findFits(Coord::CoordSystem sys, const Vector& vv) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: return findFits(vv); default: if (keyContext->fits && keyContext->fits->hasWCSCel(sys)) return keyContext->fits; else return findFits(vv); } } FitsImage* Base::findFits(const Vector& vv) { FitsImage* ptr = keyContext->fits; while (ptr) { Vector img = vv * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (img[0]>=params->xmin && img[0]<params->xmax && img[1]>=params->ymin && img[1]<params->ymax) return ptr; ptr = ptr->nextMosaic(); } return keyContext->fits; } FitsImage* Base::findFits(int which) { FitsImage* ptr = keyContext->fits; for (int ii=1; ii<which; ii++) if (ptr) ptr = ptr->nextMosaic(); return (ptr ? ptr : keyContext->fits); } int Base::findFits(FitsImage* p) { FitsImage* ptr = keyContext->fits; int rr = 0; while (ptr) { rr++; if (ptr == p) return rr; ptr = ptr->nextMosaic(); } return rr; } FitsImage* Base::findAllFits(int which) { // modified for medatacube FitsImage* rr = NULL; FitsImage* ptr = currentContext->fits; while (ptr && which) { FitsImage* sptr = ptr; while (sptr && which) { which--; if (!which) { rr = sptr; break; } sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } return rr; } int Base::fitsCount() { return currentContext->fitsCount(); } void Base::getInfoClearName(char* var) { Tcl_SetVar2(interp,var,"filename","",0); Tcl_SetVar2(interp,var,"object","",0); Tcl_SetVar2(interp,var,"min","",0); Tcl_SetVar2(interp,var,"max","",0); Tcl_SetVar2(interp,var,"low","",0); Tcl_SetVar2(interp,var,"high","",0); } void Base::getInfoClearValue(char* var) { Tcl_SetVar2(interp,var,"value","",0); Tcl_SetVar2(interp,var,"value,red","",0); Tcl_SetVar2(interp,var,"value,green","",0); Tcl_SetVar2(interp,var,"value,blue","",0); Tcl_SetVar2(interp,var,"image,x","",0); Tcl_SetVar2(interp,var,"image,y","",0); Tcl_SetVar2(interp,var,"image,z","",0); Tcl_SetVar2(interp,var,"physical,x","",0); Tcl_SetVar2(interp,var,"physical,y","",0); Tcl_SetVar2(interp,var,"physical,z","",0); Tcl_SetVar2(interp,var,"amplifier,x","",0); Tcl_SetVar2(interp,var,"amplifier,y","",0); Tcl_SetVar2(interp,var,"amplifier,z","",0); Tcl_SetVar2(interp,var,"detector,x","",0); Tcl_SetVar2(interp,var,"detector,y","",0); Tcl_SetVar2(interp,var,"detector,z","",0); } void Base::getInfoClearWCS(char* var) { for (int i=0; i<MULTWCS; i++) { char buf[64]; char w = !i ? NULL : '`'+i; Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",x"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",y"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",z"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",sys"),"",0); } } void Base::getInfoWCS(char* var, const Vector3d& rr, FitsImage* ptr, FitsImage* sptr) { Vector img = Vector(rr) * sptr->refToData; for (int i=0; i<MULTWCS; i++) { char buf[64]; char w = !i ? NULL : '`'+i; Coord::CoordSystem www = (Coord::CoordSystem)(Coord::WCS+i); if (hasWCS(www)) { char buff[128]; Vector uu = img * dataToImage; sptr->pix2wcs(uu, www, wcsSky_, wcsSkyFormat_, buff, 128); int argc; const char** argv; Tcl_SplitList(interp, buff, &argc, &argv); if (argc > 0 && argv && argv[0]) Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",x"),argv[0],0); else Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",x"),"",0); if (argc > 1 && argv && argv[1]) Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",y"),argv[1],0); else Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",y"),"",0); // use first slice coord3ToTclArray(ptr,rr,www,FIXED,var,"wcs"); char* wcsname = (char*)sptr->getWCSName(www); if (wcsname) Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",sys"),wcsname,0); else if (argc > 2 && argv && argv[2]) Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",sys"),argv[2],0); else Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",sys"),"",0); Tcl_Free((char*)argv); } else { Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",x"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",y"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",z"),"",0); Tcl_SetVar2(interp,var,varcat(buf,"wcs",w,",sys"),"",0); } } } int Base::hasATMV() { return currentContext->cfits && currentContext->cfits->hasATMV(); } int Base::hasContour() { return currentContext->hasContour(); } int Base::hasContourAux() { return currentContext->hasContourAux(); } int Base::hasDTMV() { return currentContext->cfits && currentContext->cfits->hasDTMV(); } int Base::hasLTMV() { return currentContext->cfits && currentContext->cfits->hasLTMV(); } int Base::hasWCS(Coord::CoordSystem sys) { return currentContext->cfits && currentContext->cfits->hasWCS(sys); } int Base::hasWCSEqu(Coord::CoordSystem sys) { return currentContext->cfits && currentContext->cfits->hasWCSEqu(sys); } int Base::hasWCSCel(Coord::CoordSystem sys) { return currentContext->cfits && currentContext->cfits->hasWCSCel(sys); } int Base::hasWCSx(Coord::CoordSystem sys) { return currentContext->cfits && currentContext->cfits->hasWCSx(sys,2); } Vector Base::imageCenter(FrScale::ScanMode mode) { return imageBBox(mode).center(); } Vector Base::imageSize(FrScale::ScanMode mode) { return imageBBox(mode).size(); } BBox Base::imageBBox(FrScale::ScanMode mode) { // returns imageBBox in IMAGE coords // params are in DATA coords and extends edge to edge BBox rr; int first=1; FitsImage* ptr = context->fits; while (ptr) { FitsBound* params = ptr->getDataParams(mode); Matrix mm = ptr->wcsToRef * dataToImage; Vector aa = Vector(params->xmin,params->ymin) * mm; if (first) { rr = BBox(aa,aa); first = 0; } else rr.bound(aa); rr.bound(Vector(params->xmax,params->ymin) * mm); rr.bound(Vector(params->xmax,params->ymax) * mm); rr.bound(Vector(params->xmin,params->ymax) * mm); ptr = ptr->nextMosaic(); } return rr; } int Base::isIIS() { return 0; } int Base::isCube() { return currentContext->isCube(); } int Base::isBinTable() { return (currentContext->fits && currentContext->fits->isBinTable()) ? 1 : 0; } int Base::isMosaic() { return currentContext->isMosaic(); } FitsImage* Base::isInFits(const Vector& vv, Coord::InternalSystem ref, Vector* rv) { Vector ss = mapToRef(vv,ref); FitsImage* ptr = currentContext->fits; while (ptr) { Vector rr = ss * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (rr[0]>=params->xmin && rr[0]<params->xmax && rr[1]>=params->ymin && rr[1]<params->ymax) { if (rv) *rv = rr; return ptr; } ptr = ptr->nextMosaic(); } return NULL; } FitsImage* Base::isInCFits(const Vector& vv, Coord::InternalSystem ref, Vector* rv) { Vector ss = mapToRef(vv,ref); FitsImage* ptr = currentContext->cfits; while (ptr) { Vector rr = ss * ptr->refToData; FitsBound* params = ptr->getDataParams(currentContext->frScale.scanMode()); if (rr[0]>=params->xmin && rr[0]<params->xmax && rr[1]>=params->ymin && rr[1]<params->ymax) { if (rv) *rv = rr; return ptr; } ptr = ptr->nextMosaic(); } return NULL; } void Base::invalidPixmap() { Widget::invalidPixmap(); if (basePixmap) Tk_FreePixmap(display, basePixmap); basePixmap = 0; if (baseXImage) XDestroyImage(baseXImage); baseXImage = NULL; needsUpdate = MATRIX; } Coord::Orientation Base::IRAFOrientation(Coord::Orientation oo) { if (irafOrientation == (Coord::Orientation)-1) irafOrientation = oo; return irafOrientation; } int Base::parse(istringstream& istr) { result = TCL_OK; frFlexLexer* ll = new frFlexLexer(&istr); frparse(this, ll); delete ll; return result; } FitsHead* Base::parseWCS(istream& str) { if (!currentContext->cfits) return NULL; FitsHead* head = currentContext->cfits->getHead(); FitsHead* rr = new FitsHead(head->naxis(0), head->naxis(1), head->naxis(2), head->bitpix()); // this works for both terminated (\n) and non-terminated (fits) headers while (!str.eof()) { char buf[256]; str.get(buf,81,'\n'); if (strlen(buf) > 0) { string x(buf); istringstream sstr(x); char keyword[32]; sstr >> keyword; if (strchr(buf,'=')) { char dummy; sstr >> dummy; } if (strchr(buf,'\'')) { char val[64]; char* ss = strchr(buf,'\'')+1; char* ee = strrchr(buf,'\''); int ll = ee-ss; if (ll<0 || ll>63) ll =0; strncpy(val,ss,ll); val[ll] = '\0'; rr->appendString(keyword, val, ""); } else { double val; sstr >> val; rr->appendReal(keyword, val, 15, ""); } if (strlen(buf) < 80) { // eat the \n char b; str.get(b); } } else break; } return rr; } int Base::postscriptProc(int prepass) { if (!visible) return TCL_OK; if (prepass) return TCL_OK; ps(); switch (psLevel) { case 1: switch (psColorSpace) { case BW: case GRAY: if (grid) grid->ps(GRAY); psContours(GRAY); if (showMarkers) { psMarkers(&catalogMarkers, GRAY); psMarkers(&userMarkers, GRAY); } psCrosshair(GRAY); psGraphics(GRAY); break; case RGB: case CMYK: if (grid) grid->ps(RGB); psContours(RGB); if (showMarkers) { psMarkers(&catalogMarkers, RGB); psMarkers(&userMarkers, RGB); } psCrosshair(RGB); psGraphics(RGB); break; } break; case 2: case 3: if (grid) grid->ps(psColorSpace); psContours(psColorSpace); if (showMarkers) { psMarkers(&catalogMarkers, psColorSpace); psMarkers(&userMarkers, psColorSpace); } psCrosshair(psColorSpace); psGraphics(psColorSpace); break; } return TCL_OK; } void Base::printCoordSystem(Coord::CoordSystem sys) { Tcl_AppendResult(interp, coord.coordSystemStr(sys), NULL); } void Base::printDouble(double d, Precision p) { ostringstream str; switch (p) { case DEFAULT: str << d << ends; break; case FIXED: str << setiosflags(ios::fixed) << setw(9) << setprecision(3) << d << ends; break; case SCIENTIFIC: str << setiosflags(ios::scientific) << setprecision(8) << d << ends; break; case INTEGER: str << (int)d << ends; break; } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::printInteger(int i) { ostringstream str; str << i << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::printSkyFrame(Coord::SkyFrame sky) { Tcl_AppendResult(interp, coord.skyFrameStr(sky), NULL); } void Base::printSkyFormat(Coord::SkyFormat format) { Tcl_AppendResult(interp, coord.skyFormatStr(format), NULL); } void Base::printSkyDist(Coord::SkyDist dist) { Tcl_AppendResult(interp, coord.skyDistStr(dist), NULL); } void Base::printVector(const Vector& v, Precision p) { ostringstream str; switch (p) { case DEFAULT: str << setprecision(8) << v << ends; break; case FIXED: str << setiosflags(ios::fixed) << setw(9) << setprecision(3) << v << ends; break; case SCIENTIFIC: str << setiosflags(ios::scientific) << setprecision(8) << v << ends; break; case INTEGER: { Vector z = v; str << z.round() << ends; break; } } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::printVector(const Vector3d& v, Precision p) { ostringstream str; switch (p) { case DEFAULT: str << setprecision(8) << v << ends; break; case FIXED: str << setiosflags(ios::fixed) << setw(9) << setprecision(3) << v << ends; break; case SCIENTIFIC: str << setiosflags(ios::scientific) << setprecision(8) << v << ends; break; case INTEGER: { Vector z = v; str << z.round() << ends; break; } } Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Base::printFromRef(FitsImage* ptr, const Vector& v, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Precision p) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: printVector(ptr->mapFromRef(v, sys, sky), p); return; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: printVector(ptr->mapFromRef(v, sys, sky), p); break; case Coord::SEXAGESIMAL: { char buf[64]; buf[0] = '\0'; ptr->mapFromRef(v, sys, sky, format, buf, 64); // grap only the first two items char* ptr = buf; while (*ptr) ptr++; while (*ptr != ' ' && ptr >= buf) ptr--; *ptr = '\0'; Tcl_AppendResult(interp, buf, " ", NULL); } break; } } else printVector(ptr->mapFromRef(v, sys), p); } else printVector(Vector(),p); return; } } void Base::ps() { Vector org = psOrigin(); if (currentContext->fits) { Tcl_AppendResult(interp, "gsave\n", NULL); TkPostscriptInfo* psInfo = (TkPostscriptInfo*)(((TkCanvas*)canvas)->psInfo); double ss = psInfo->scale * psResolution / 72.; int ww = options->width*ss; int hh = options->height*ss; { ostringstream str; str << org[0] << ' ' << org[1] << " translate" << endl << setprecision(12) << 1/ss << ' ' << 1/ss << " scale" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } switch (psLevel) { case 1: { psHead1(ww, hh); NoCompressAsciiHex filter(psLevel); psImage(filter, psColorSpace, ww, hh, ss); } break; case 2: { psHead2(ww, hh, "RunLength", "ASCII85"); RLEAscii85 filter(psLevel); psImage(filter, psColorSpace, ww, hh, ss); } break; case 3: { psHead2(ww, hh, "Flate", "ASCII85"); GZIPAscii85 filter(psLevel); psImage(filter, psColorSpace, ww, hh, ss); } break; } Tcl_AppendResult(interp, "grestore\n", NULL); } // Markers & Contours & Grids clip path { ostringstream str; str << org[0] << ' ' << org[1] << ' ' << options->width << ' ' << options->height << " rectclip" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::psContours(PSColorSpace cs) { // render back to front // aux contours Contour* ptr=currentContext->auxcontours.tail(); while (ptr) { ptr->ps(cs); ptr=ptr->previous(); } // main contour if (hasContour()) currentContext->contour->ps(cs); } void Base::psCrosshair(PSColorSpace mode) { if (!useCrosshair) return; Vector rr = mapFromRef(crosshair, Coord::WIDGET); Vector aa = Vector(rr[0],1) * widgetToCanvas; Vector bb = Vector(rr[0],options->height) * widgetToCanvas; Vector cc = Vector(1,rr[1]) * widgetToCanvas; Vector dd = Vector(options->width,rr[1]) * widgetToCanvas; { ostringstream str; switch ((PSColorSpace)mode) { case BW: case GRAY: psColorGray(getXColor("green"), str); str << " setgray"; break; case RGB: psColorRGB(getXColor("green"), str); str << " setrgbcolor"; break; case CMYK: psColorCMYK(getXColor("green"), str); str << " setcmykcolor"; break; } str << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } { ostringstream str; str << 1 << " setlinewidth" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } { ostringstream str; str << "newpath " << aa.TkCanvasPs(canvas) << "moveto" << bb.TkCanvasPs(canvas) << "lineto" << " stroke" << endl << "newpath " << cc.TkCanvasPs(canvas) << "moveto" << dd.TkCanvasPs(canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Base::psImage(Filter& filter, PSColorSpace mode, int width, int height, float scale) { pushPSMatrices(scale, width, height); unsigned char* img = fillImage(width, height, Coord::PS); if (!img) return; unsigned char* ptr = img; for (long jj=0; jj<height; jj++) { ostringstream str; for (long ii=0; ii<width; ii++, ptr+=3) { unsigned char red = ptr[0]; unsigned char green = ptr[1]; unsigned char blue = ptr[2]; switch (mode) { case BW: case GRAY: filter << RGB2Gray(red, green, blue); break; case RGB: filter << red << green << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter; } str << ends; psFix(str); Tcl_AppendResult(interp, str.str().c_str(), NULL); } ostringstream str; filter.flush(str); psFix(str); Tcl_AppendResult(interp, str.str().c_str(), NULL); if (img) delete [] img; } Matrix Base::psMatrix(float scale, int width, int height) { Matrix userToPS = wcsOrientationMatrix * // flip x/y axis about center orientationMatrix * // flip x/y axis about cursor position Rotate(wcsRotation) * // rotate about center position Rotate(rotation) * // rotate about cursor position Scale(zoom_) * // scale about cursor position Scale(scale) * FlipY() * Translate(Vector(width,height)/2.); return refToUser * userToPS; } void Base::pushMatrices() { // alway identity Matrix rgbToRef; FitsImage* ptr = context->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMatrices(rgbToRef, refToWidget, widgetToCanvas); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Base::pushMagnifierMatrices() { FitsImage* ptr = context->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updateMagnifierMatrices(refToMagnifier); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Base::pushPannerMatrices() { FitsImage* ptr = context->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updatePannerMatrices(refToPanner); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Base::pushPSMatrices(float scale, int width, int height) { Matrix mx = psMatrix(scale, width, height); FitsImage* ptr = context->fits; while (ptr) { FitsImage* sptr = ptr; while (sptr) { sptr->updatePS(mx); sptr = sptr->nextSlice(); } ptr = ptr->nextMosaic(); } } void Base::reset() { centerImage(); crosshair = cursor; invert = 0; orientation = Coord::NORMAL; orientationMatrix.identity(); zoom_ = Vector(1,1); rotation = 0; wcsAlign_ = 0; wcsAlt_ =0; wcsOrientation = Coord::NORMAL; wcsOrientationMatrix.identity(); wcsRotation = 0; unselectMarkers(&userMarkers); unselectMarkers(&catalogMarkers); update(MATRIX); } FrScale::ScanMode Base::scanMode() { return currentContext->frScale.scanMode(); } void Base::resetScanMode() { currentContext->frScale.resetScanMode(); } void Base::setScanMode(FrScale::ScanMode mode) { currentContext->frScale.setScanMode(mode); } // backward compatibility void Base::setScanModeIncr(LoadMethod lm) { switch (lm) { case LOADALL: // do nothing (leave the current setting), will use incr end to reset break; case INCR: currentContext->frScale.setScanMode(FrScale::CROPSEC); break; } } void Base::setSlice(int ii, int ss) { // IMAGE (ranges 1-n) currentContext->updateSlice(ii, ss); updateMarkers(&userMarkers); updateMarkers(&catalogMarkers); // execute any update callbacks updateCBMarkers(); if (ii==2) update(BASE); else { // load the next cube currentContext->updateClip(); updateColorScale(); update(MATRIX); } } void Base::unloadAllFits() { unloadFits(); } void Base::unloadFits() { if (DebugPerf) cerr << "Base::unloadFits" << endl; if (!preserveMarkers) { // delete markers userMarkers.deleteAll(); undoUserMarkers.deleteAll(); pasteUserMarkers.deleteAll(); } catalogMarkers.deleteAll(); undoCatalogMarkers.deleteAll(); pasteCatalogMarkers.deleteAll(); if (grid) delete grid; grid = NULL; irafOrientation = (Coord::Orientation)-1; updateColorScale(); } void Base::update(UpdateType flag) { if (DebugPerf) cerr << "update " << flag << endl; // Be careful, someone may have already set the flag at a lower level // therefor, only change the flag if we need more to be done if (flag < needsUpdate) needsUpdate = flag; redraw(); } void Base::update(UpdateType flag, BBox bb) { if (DebugPerf) cerr << "update " << flag << ' ' << bb << endl; // bb is in canvas coords if (flag < needsUpdate) needsUpdate = flag; redraw(bb); } void Base::updateBase() { if (DebugPerf) cerr << "updateBase..."; int& width = options->width; int& height = options->height; if (!basePixmap) { if (!(basePixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth))){ internalError("Unable to Create Pixmap"); return; } // Geometry has changed, redefine our marker GCs including clip regions updateGCs(); } if (!baseXImage) { if (!(baseXImage = XGetImage(display, basePixmap, 0, 0, width, height, AllPlanes, ZPixmap))) { internalError("Unable to Create XImage"); return; } // we have to wait until now, since the encodings depend on baseXImage encodeTrueColor(baseXImage->byte_order, baseXImage->bits_per_pixel); encodeTrueColor(bgColor, bgTrueColor_); encodeTrueColor(nanColor, nanTrueColor_); // we have a race condition. Some Truecolor ColorScales need to know the // bytes per pixel, RGB masks, and byte order, from XImage struct. // yet, we receive colormap commands well before we render to the // screen and have a valid XImage. // So, we put off creating a colorscale until we are ready to render. if (!validColorScale()) updateColorScale(); } if (doRender()) ximageToPixmap(basePixmap, baseXImage, Coord::WIDGET); else { XSetForeground(display, gc, getColor(bgColorName)); XFillRectangle(display, basePixmap, gc, 0,0,options->width,options->height); } if (DebugPerf) cerr << "end" << endl; } void Base::updateBin(const Matrix& mx) { currentContext->updateBin(this); if (keyContext->fits && (keyContext->fits == currentContext->fits)) { crosshair *= mx; currentContext->updateContours(mx); updateMarkerCoords(&userMarkers, mx); updateMarkerCoords(&catalogMarkers, mx); } alignWCS(); updateColorScale(); updateNow(MATRIX); // because we have changed zoom // update markers call backs // wait til matrices have been updated so that any dialogs will print // the correct coords updateMarkerCBs(&userMarkers); updateMarkerCBs(&catalogMarkers); } void Base::updateGCs() { // widget clip region BBox bbWidget = BBox(0, 0, options->width, options->height); Vector sizeWidget = bbWidget.size(); rectWidget[0].x = (int)bbWidget.ll[0]; rectWidget[0].y = (int)bbWidget.ll[1]; rectWidget[0].width = (int)sizeWidget[0]; rectWidget[0].height = (int)sizeWidget[1]; // window clip region BBox bbWindow = bbWidget * widgetToWindow; Vector sizeWindow = bbWindow.size(); rectWindow[0].x = (int)bbWindow.ll[0]; rectWindow[0].y = (int)bbWindow.ll[1]; rectWindow[0].width = (int)sizeWindow[0]; rectWindow[0].height = (int)sizeWindow[1]; if (!highliteGC) { highliteGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetLineAttributes(display, highliteGC, 2, LineSolid, CapButt, JoinMiter); XSetForeground(display, highliteGC, getColor("blue")); } XSetClipRectangles(display, highliteGC, 0, 0, rectWidget, 1, Unsorted); // panGCXOR if (!panGCXOR) panGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetClipRectangles(display, panGCXOR, 0, 0, rectWindow, 1, Unsorted); // rotateGCXOR if (!rotateGCXOR) rotateGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetClipRectangles(display, rotateGCXOR, 0, 0, rectWindow, 1, Unsorted); // markerGC if (!markerGC) markerGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetClipRectangles(display, markerGC, 0, 0, rectWidget, 1, Unsorted); if (!markerGCXOR) { markerGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetForeground(display, markerGCXOR, getColor("white")); } XSetClipRectangles(display, markerGCXOR, 0, 0, rectWindow, 1, Unsorted); if (!selectGCXOR) { selectGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetForeground(display, selectGCXOR, getColor("white")); x11Dash(selectGCXOR,1); } XSetClipRectangles(display, selectGCXOR, 0, 0, rectWindow, 1, Unsorted); // gridGC if (!gridGC) gridGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetClipRectangles(display, gridGC, 0, 0, rectWidget, 1, Unsorted); // contourGC if (!contourGC) { contourGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetLineAttributes(display, contourGC, 1, LineSolid, CapButt, JoinMiter); } XSetClipRectangles(display, contourGC, 0, 0, rectWidget, 1, Unsorted); } void Base::updateMagnifier() { updateMagnifier(magnifierCursor); } void Base::updateMagnifier(const Vector& vv) { // vv is in CANVAS coords // save it, we may need it later magnifierCursor = vv; if (!(magnifierXImage && magnifierPixmap)) return; if (useMagnifier) { updateMagnifierMatrices(); if (doRender()) { ximageToPixmapMagnifier(); if (useMagnifierGraphics) { // render markers // markers bounding box is in canvas coords // map the magnifier to a bounding box in canvas coords Matrix mm = magnifierToRef * refToCanvas; Vector ll = Vector(0,0) * mm; Vector ur = Vector(magnifierWidth,magnifierHeight) * mm; BBox bb = BBox(vv,vv); bb.bound(ll); bb.bound(ur); if (showMarkers) { x11MagnifierMarkers(&userMarkers, bb); x11MagnifierMarkers(&catalogMarkers, bb); } // render crosshair if (useCrosshair) x11Crosshair(magnifierPixmap, Coord::MAGNIFIER, magnifierWidth, magnifierHeight); // render contours x11Contours(magnifierPixmap, Coord::MAGNIFIER, magnifierWidth, magnifierHeight); } // render cursor if (useMagnifierCursor) x11MagnifierCursor(vv); } else { XSetForeground(display, gc, getColor(bgColorName)); XFillRectangle(display, magnifierPixmap, gc, 0, 0, magnifierXImage->width, magnifierXImage->height); } // notify the magnifier widget ostringstream str; str << magnifierName << " update " << (void*)magnifierPixmap << ends; Tcl_Eval(interp, str.str().c_str()); } } void Base::updateMatrices() { // refToUser refToUser = Translate(-cursor) * FlipY(); // flip y axis for X Windows userToRef = refToUser.invert(); // userToWidget userToWidget = wcsOrientationMatrix * // flip x/y axis about center orientationMatrix * // flip x/y axis about cursor position Rotate(wcsRotation) * // rotate about center position Rotate(rotation) * // rotate about cursor position Scale(zoom_) * // scale about cursor position // must be int to align with screen pixels Translate((int)(options->width/2.), (int)(options->height/2.)); widgetToUser = userToWidget.invert(); // widgetToCanvas widgetToCanvas = Translate(originX, originY); canvasToWidget = widgetToCanvas.invert(); // canvasToWindow short xx, yy; Tk_CanvasWindowCoords(canvas, 0, 0, &xx, &yy); canvasToWindow = Translate(xx, yy); windowToCanvas = canvasToWindow.invert(); // These are derived Transformation Matrices refToWidget = refToUser * userToWidget; widgetToRef = refToWidget.invert(); refToCanvas = refToWidget * widgetToCanvas; canvasToRef = refToCanvas.invert(); refToWindow = refToCanvas * canvasToWindow; windowToRef = refToWindow.invert(); userToCanvas = userToWidget * widgetToCanvas; canvasToUser = userToCanvas.invert(); widgetToWindow = widgetToCanvas * canvasToWindow; windowToWidget = widgetToWindow.invert(); // Markers updateMarkers(&userMarkers); updateMarkers(&catalogMarkers); pushMatrices(); } void Base::updateMagnifierMatrices() { // magnifierCursor is in CANVAS Vector ww = magnifierCursor*canvasToRef; // refToUser Matrix refToUser; refToUser = Translate(-ww) * FlipY(); // userToMagnifier userToMagnifier = wcsOrientationMatrix * // flip x/y axis about center orientationMatrix * // flip x/y axis about cursor position Rotate(wcsRotation) * // rotate about center position Rotate(rotation) * // rotate about cursor position Scale(zoom_) * // scale about cursor position Scale(magnifierZoom_) * // scale // must be int to align with screen pixels Translate((int)(magnifierWidth/2.), (int)(magnifierHeight/2.)); magnifierToUser = userToMagnifier.invert(); refToMagnifier = refToUser * userToMagnifier; magnifierToRef = refToMagnifier.invert(); magnifierToWidget = magnifierToUser * userToWidget; widgetToMagnifier = magnifierToWidget.invert(); pushMagnifierMatrices(); } void Base::updatePannerMatrices() { Vector center = imageCenter(FrScale::IMGSEC) * imageToData; // refToUser Matrix refToUser; refToUser = Translate(-center) * FlipY(); // flip y axis for X Windows userToRef = refToUser.invert(); // userToPanner userToPanner = wcsOrientationMatrix * // flip x/y axis about center orientationMatrix * // flip x/y axis about cursor position Rotate(wcsRotation) * // rotate about center position Rotate(rotation) * // rotate about cursor position Scale(calcZoomPanner()) * // must be int to align with screen pixels Translate((int)(pannerWidth/2.), (int)(pannerHeight/2.)); pannerToUser = userToPanner.invert(); refToPanner = refToUser * userToPanner; pannerToRef = refToPanner.invert(); pannerToWidget = pannerToRef * refToWidget; widgetToPanner = pannerToWidget.invert(); pushPannerMatrices(); } void Base::updateNow(UpdateType flag) { if (DebugPerf) cerr << "updateNow " << flag << endl; if (flag < needsUpdate) needsUpdate = flag; redrawNow(); } void Base::updateNow(UpdateType flag, BBox bb) { if (DebugPerf) cerr << "updateNow BB " << flag << ' ' << bb << endl; // bb is in canvas coords if (flag < needsUpdate) needsUpdate = flag; redrawNow(bb); } void Base::updatePanner() { if (usePanner) { if (doRender()) ximageToPixmap(pannerPixmap, pannerXImage, Coord::PANNER); else { XSetForeground(display, pannerGC, getColor(bgColorName)); XFillRectangle(display, pannerPixmap, pannerGC, 0, 0, pannerWidth, pannerHeight); } } } int Base::updatePixmap(const BBox& bb) { // bbox is in canvas coords // Note: lack of breaks-- on purpose. // If Matrices are update, both Base and Pixmap // also need to be updated. Same for Base-- ie, pixmap is also updated. switch (needsUpdate) { case MATRIX: updateMatrices(); updatePannerMatrices(); case BASE: updateBase(); updatePanner(); case PIXMAP: updatePM(bb); break; } needsUpdate = NOUPDATE; return TCL_OK; } void Base::updatePM(const BBox& bbox) { // bbox is in Canvas Coords if (DebugPerf) cerr << "updatePM..."; int& width = options->width; int& height = options->height; if (!pixmap) { if (!(pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth))) { internalError("Unable to Create Pixmap"); return; } } if (!bbox.isEmpty()) { BBox bb = bbox * canvasToWidget; int x0 = (int)bb.ll[0] > 0 ? (int)bb.ll[0] : 0; int y0 = (int)bb.ll[1] > 0 ? (int)bb.ll[1] : 0; int x1 = (int)bb.ur[0] < width ? (int)bb.ur[0] : width; int y1 = (int)bb.ur[1] < height ? (int)bb.ur[1] : height; int sx = x1-x0; int sy = y1-y0; if (DebugPerf) cerr << ' ' << x0 << ' ' << y0 << ' ' << x1 << ' ' << y1 << ' '; XCopyArea(display, basePixmap, pixmap, gc, x0, y0, sx, sy, x0, y0); } // grid if (grid) grid->x11(); // contours x11Contours(pixmap, Coord::WIDGET, options->width, options->height); // markers if (showMarkers) { x11Markers(&catalogMarkers, bbox); x11Markers(&userMarkers, bbox); } // crosshair x11Crosshair(pixmap, Coord::WIDGET, options->width, options->height); // highlite bbox x11Graphics(); if (DebugPerf) cerr << "end" << endl; } char* Base::varcat(char* buf, char* base, char id, char* mod) { int ll = strlen(base); strcpy(buf,base); buf[ll++] = id; buf[ll++] = NULL; strcat(buf,mod); return buf; } void Base::x11Contours(Pixmap pm, Coord::InternalSystem sys, int width, int height) { // render from back to front // aux contours Contour* ptr=currentContext->auxcontours.tail(); while (ptr) { ptr->render(pm, sys, width, height); ptr=ptr->previous(); } // main contour if (hasContour()) currentContext->contour->render(pm, sys, width, height); } void Base::x11Crosshair(Pixmap pm, Coord::InternalSystem sys, int width, int height) { if (useCrosshair) { Vector rr = mapFromRef(crosshair,sys); XSetForeground(display, gc, getColor("green")); if (rr[0]>=0 && rr[0]<width) XDrawLine(display, pm, gc, rr[0], 1, rr[0], height); if (rr[1]>=0 && rr[1]<height) XDrawLine(display, pm, gc, 1, rr[1], width, rr[1]); } } void Base::x11Dash(GC lgc, int which) { if (which) { char dl[2]; #ifdef _WIN32 dl[0] = dlist[0]/2; dl[1] = dlist[1]/2; #else dl[0] = dlist[0]; dl[1] = dlist[1]; #endif XSetLineAttributes(display, lgc, 1, LineOnOffDash, CapButt,JoinMiter); XSetDashes(display, lgc, 0, dl, 2); } else XSetLineAttributes(display, lgc, 1, LineSolid, CapButt, JoinMiter); } void Base::x11Graphics() { if (useHighlite) XDrawRectangle(display, pixmap, highliteGC, 1, 1, options->width-2, options->height-2); } void Base::ximageToPixmap(Pixmap pmap, XImage* xmap, Coord::InternalSystem sys) { buildXImage(xmap, sys); XPutImage(display, pmap, gc, xmap, 0, 0, 0, 0, xmap->width, xmap->height); } void Base::ximageToPixmapMagnifier() { ximageToPixmap (magnifierPixmap, magnifierXImage, Coord::MAGNIFIER); } #ifdef _MACOSX void Base::macosx() { // clip rect XRectangle* rr = rectWidget; Vector v1 = Vector(rr->x, rr->y) * widgetToCanvas; Vector v2 = Vector(rr->x+rr->width, rr->y+rr->height) * widgetToCanvas; macosxClip(v1,v2-v1); if (currentContext->fits) { // scale double scale = 150 / 72.; int width = options->width*scale; int height = options->height*scale; // image macosxImage(scale, width, height, v1, v2-v1); } } void Base::macosxContours() { // render back to front // aux contours Contour* ptr=currentContext->auxcontours.tail(); while (ptr) { ptr->macosx(); ptr=ptr->previous(); } // main contour if (hasContour()) currentContext->contour->macosx(); } void Base::macosxCrosshair() { if (!useCrosshair) return; Vector rr = mapFromRef(crosshair,WIDGET); Vector aa = Vector(rr[0],1) * widgetToCanvas; Vector bb = Vector(rr[0],options->height) * widgetToCanvas; Vector cc = Vector(1,rr[1]) * widgetToCanvas; Vector dd = Vector(options->width,rr[1]) * widgetToCanvas; macosxColor(getXColor("green")); macosxWidth(1); macosxDrawLine(aa,bb); macosxDrawLine(cc,dd); } void Base::macosxImage(float scale, int width, int height, const Vector& v, const Vector& s) { // we need a colorScale before we can render if (!validColorScale()) return; pushPSMatrices(scale, width, height); // source unsigned char* src = fillImage(width, height, Coord::PS); if (!src) return; // destination unsigned char* dst = new unsigned char[width*height*4]; if (!dst) return; unsigned char* sptr = src; unsigned char* dptr = dst; for (int ii=0; ii<width*height; ii++) { *dptr++ = *sptr++; *dptr++ = *sptr++; *dptr++ = *sptr++; *dptr++ = 0; } if (src) delete [] src; macosxBitmapCreate(dst, width, height, v, s); if (dst) delete [] dst; } void Base::macosxPrintCmd() { if (!visible) return; // init macosxBegin(); // image macosx(); // grid if (grid) grid->macosx(); // contours macosxContours(); // markers if (showMarkers) { macosxMarkers(&catalogMarkers); macosxMarkers(&userMarkers); } macosxCrosshair(); macosxGraphics(); // cleanup macosxEnd(); } #endif #ifdef _WIN32 void Base::win32() { // clip rect XRectangle* rr = rectWidget; Vector v1 = Vector(rr->x, rr->y) * widgetToCanvas; Vector v2 = Vector(rr->x+rr->width, rr->y+rr->height) * widgetToCanvas; win32Clip(v1,v2-v1); if (currentContext->fits) { // scale double scale = 1.0; int width = options->width*scale; int height = options->height*scale; // image win32Image(scale, width, height, v1, v2-v1); } } void Base::win32Contours() { // render back to front // aux contours Contour* ptr=currentContext->auxcontours.tail(); while (ptr) { ptr->win32(); ptr=ptr->previous(); } // main contour if (hasContour()) currentContext->contour->win32(); } void Base::win32Crosshair() { if (!useCrosshair) return; Vector rr = mapFromRef(crosshair,Coord::WIDGET); Vector aa = Vector(rr[0],1) * widgetToCanvas; Vector bb = Vector(rr[0],options->height) * widgetToCanvas; Vector cc = Vector(1,rr[1]) * widgetToCanvas; Vector dd = Vector(options->width,rr[1]) * widgetToCanvas; win32Color(getXColor("green")); win32Width(1); win32Dash(NULL,0); win32DrawLine(aa,bb); win32DrawLine(cc,dd); } void Base::win32Image(float scale, int width, int height, const Vector& v, const Vector& s) { // we need a colorScale before we can render if (!validColorScale()) return; pushPSMatrices(scale, width, height); // source unsigned char* src = fillImage(width, height, Coord::PS); if (!src) return; // destination (width must be aligned on 4-byte DWORD boundary) int jjwidth=(((width+3)/4)*4); // extra alignment padding which we have to skip over for each row int jjpad=(jjwidth-width)*3; unsigned char* dst = new unsigned char[jjwidth*height*3]; if (!dst) return; memset(dst, '\0', jjwidth*height*3); unsigned char* sptr = src; unsigned char* dptr = dst; unsigned char red, green, blue; for (int jj=0; jj<height; jj++) { for (int ii=0; ii<width; ii++) { red = *sptr++; green = *sptr++; blue = *sptr++; *dptr++ = blue; *dptr++ = green; *dptr++ = red; } dptr += jjpad; } if (src) delete [] src; win32BitmapCreate(dst, jjwidth, height, v, s); if (dst) delete [] dst; } void Base::win32PrintCmd() { if (!visible) return; // init win32Begin(); // image win32(); // grid if (grid) grid->win32(); // contours win32Contours(); // markers if (showMarkers) { win32Markers(&userMarkers); win32Markers(&catalogMarkers); } win32Crosshair(); win32Graphics(); // cleanup win32End(); } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid25d.h����������������������������������������������������������������������0000644�0001750�0001750�00000001442�12001331444�014720� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid25d_h__ #define __grid25d_h__ #include <tk.h> #include "grid.h" #include "grid25dbase.h" #include "coord.h" class Grid25d : public Grid, public Grid25dBase { private: void* matrixMap(Matrix&, const char*); int doit(RenderMode); public: Grid25d(Widget*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, GridType, const char*, const char*); ~Grid25d(); const char* option() {return GridBase::option();} void x11() {doit(X11);} void ps(int mode) {mode_=mode; doit(PS);} #ifdef _MACOSX void macosx() {doit(MACOSX);} #endif #ifdef _WIN32 void win32() {doit(GWIN32);} #endif }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsimage.h��������������������������������������������������������������������0000644�0001750�0001750�00000055573�12122377573�015467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsimage_h__ #define __fitsimage_h__ #include "vector.h" #include "vector3d.h" #include "fitsdata.h" #include "coord.h" #include "file.h" #include "wcs.h" extern "C" { #include "ast.h" } #define WCSXMAX 7 class FitsImage { public: enum CompressType {GZIP, RICE, PLIO, HCOMPRESS}; enum SmoothFunction {BOXCAR, TOPHAT, GAUSSIAN}; protected: Base* parent; // pointer to parent char* objectName; // object name char* rootBaseFileName; // base root filename char* fullBaseFileName; // base full filename char* rootFileName; // root filename char* fullFileName; // full filename char* rootFileName3d; // root filename char* fullFileName3d; // full filename char* iisFileName; // alt file name for iis // native fits file FitsFile* fits_; // base FitsFile* compress_; // fits compressed FitsFile* hpx_; // healpix FitsFile* hist_; // fits bin FitsFile* base_; FitsData* basedata_; // analysis FitsFile* smooth_; FitsData* smoothdata_; // final FitsFile* image_; FitsData* data_; int naxis_[FTY_MAXAXES]; int bitpix_; Vector histCursor; // start point to bin about (physical coords) Vector actualHistCursor; // actual bin center (physical coords) int doSmooth_; SmoothFunction smoothFunction_; int smoothRadius_; FitsHist::Function binFunction_; // binning operation Vector binFactor_; // binning factor int binBufferSize_; // size of bin buffer int binDepth_; // binning depth char* binSliceFilter; char buf[32]; // tmp storage for returning strings // Mosaic items int keyLTMV; int keyATMV; int keyDTMV; int keyDATASEC; BBox datasec; // DATASEC keyword FitsBound* mparams; // minmax bbox int iisMode; // flag to indicate if iis Vector iisz; // z1 and z2 int iiszt; // 0-Uniary, 1-Linear, 2-Log FitsImage* nextMosaic_; // next mosaic FitsImage* nextSlice_; // next slice int address[FTY_MAXAXES]; WorldCoor** wcs; // wcs list FitsHead* wcsHeader; // alt wcs header AstFrameSet** ast; // ast frameset; int wcsx[WCSXMAX*MULTWCS]; // xth Axis WCS public: // for AST double crpixx[WCSXMAX*MULTWCS]; double crvalx[WCSXMAX*MULTWCS]; double cdx[WCSXMAX*MULTWCS]; protected: void reset(); void process(const char*, int); void initCompress(); void initNRRD(); void initHist(); Vector getHistCenter(); int initHPX(); char* root(const char*); char* strip(const char*); int parseSection(char*, Vector*, Vector*); int smooth(); void wcsShow(WorldCoor*); void astinit(int, FitsHead*); int checkAst(double, double); AstFrameSet* fits2ast(FitsHead*); AstFrameSet* wcs2ast(int); void putFitsCard(void* chan, const char* key, const char* value); void putFitsCard(void* chan, const char* key, int value); void putFitsCard(void* chan, const char* key, double value); char* ASTpix2wcs(Vector, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, char*, int); Vector ASTpix2wcs(Vector, Coord::CoordSystem, Coord::SkyFrame); Vector* ASTpix2wcs(Vector*, int, Coord::CoordSystem, Coord::SkyFrame); Vector ASTwcs2pix(Vector, Coord::CoordSystem, Coord::SkyFrame); Vector* ASTwcs2pix(Vector*, int, Coord::CoordSystem, Coord::SkyFrame); double ASTwcsdist(Vector, Vector, Coord::CoordSystem); char* WCSpix2wcs(Vector, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, char*, int); Vector WCSpix2wcs(Vector, Coord::CoordSystem, Coord::SkyFrame); Vector WCSwcs2pix(Vector, Coord::CoordSystem, Coord::SkyFrame); double WCSwcsdist(Vector, Vector, Coord::CoordSystem); public: Matrix wcsToRef; // iraf/wcs matrix Matrix irafToRef; Matrix amplifierToImage; Matrix amplifierToPhysical; Matrix amplifierToRef; Matrix canvasToRef; Matrix dataToImage; Matrix imageToData; Matrix dataToRef; Matrix dataToWidget; Matrix detectorToImage; Matrix detectorToPhysical; Matrix detectorToRef; Matrix imageToAmplifier; Matrix imageToDetector; Matrix imageToPhysical; Matrix imageToRef; Matrix imageToWidget; Matrix physicalToAmplifier; Matrix physicalToDetector; Matrix physicalToImage; Matrix physicalToRef; Matrix refToAmplifier; Matrix refToCanvas; Matrix refToData; Matrix refToDetector; Matrix refToImage; Matrix refToPhysical; Matrix widgetToData; Matrix widgetToImage; Matrix3d dataToImage3d; Matrix3d dataToRef3d; Matrix3d dataToWidget3d; Matrix3d imageToData3d; Matrix3d refToData3d; Matrix3d widgetToData3d; Matrix magnifierToData; Matrix dataToMagnifier; Matrix3d magnifierToData3d; Matrix3d dataToMagnifier3d; Matrix pannerToData; Matrix dataToPanner; Matrix3d pannerToData3d; Matrix3d dataToPanner3d; Matrix psToData; Matrix dataToPS; Matrix3d psToData3d; Matrix3d dataToPS3d; FitsBound iparams; // image bbox FitsBound dparams; // DATASEC bbox FitsBound cparams; // crop bbox public: FitsImage(Base*); virtual ~FitsImage(); void load(); void analysis(); FitsImage* nextMosaic() {return nextMosaic_;} FitsImage* nextSlice() {return nextSlice_;} void setNextMosaic(FitsImage* n) {nextMosaic_ = n;} void setNextSlice(FitsImage* n) {nextSlice_ = n;} FitsFile* fitsFile() {return fits_;} FitsFile* baseFile() {return base_;} FitsFile* imageFile() {return image_;} int isValid() {return image_ ? 1 : 0;} int isCompress() {return compress_ ? 1 : 0;} int isHist() {return hist_ ? 1 : 0;} int isHPX() {return hpx_ ? 1 : 0;} int isImage() {return fits_ ? fits_->isImage() : 0;} int isBinTable() {return fits_ ? fits_->isBinTable() : 0;} void close() {if (fits_) fits_->done();} void match(const char* xxname1, const char* yyname1, Coord::CoordSystem sys1, Coord::SkyFrame sky1, const char* xxname2, const char* yyname2, Coord::CoordSystem sys2, Coord::SkyFrame sky2, double rad, Coord::CoordSystem sys, Coord::SkyDist dist, const char* rrname); Matrix updateHistCenter(); Matrix updateHistCursor(); Matrix updateHist(const Vector&); Matrix nextHist(const Vector&); void calcHistSize(); Vector getHistDim(); Vector getHistColMinMax(const char*); Vector getHistColDim(const char*); Vector getHistCursor() {return actualHistCursor;} const char* getHistFilter(); const char* getHistX(); const char* getHistY(); const char* getHistZ(); char* getHistList(); int doSmooth() {return doSmooth_;} SmoothFunction smoothFunction() {return smoothFunction_;} int smoothRadius() {return smoothRadius_;} void setDoSmooth(int d) {doSmooth_ = d;} void setSmoothFunction(SmoothFunction f) {smoothFunction_ = f;} void setSmoothRadius(int r) {smoothRadius_ = r;} FitsHist::Function binFunction() {return binFunction_;} Vector binFactor() {return binFactor_;} int binBufferSize() {return binBufferSize_;} int binDepth() {return binDepth_;} void setBinCursor(const Vector&); void setBinFunction(FitsHist::Function f) {binFunction_ = f;} void setBinFactor(const Vector&); void setBinToFactor(const Vector&); void setBinBufferSize(int s) {binBufferSize_ = s;} void setBinDepth(int d) {binDepth_ = d < 1 ? 1 : d;} void setBinX(const char* str) {if (fits_) fits_->setpBinX(str);} void setBinY(const char* str) {if (fits_) fits_->setpBinY(str);} void setBinZ(const char* str) {if (fits_) fits_->setpBinZ(str);} void setBinFilter(const char* fil) {if (fits_) fits_->setpFilter(fil);} void setBinSliceFilter(const char*); void setBinColMinMax(const char* str, const Vector& lim) {if (fits_) fits_->setColMinMax(str,lim);} int hasBinCol(const char*); const char* getObjectName() {return objectName;} void setObjectName(const char*); const char* getRootBaseFileName() {return rootBaseFileName;} const char* getFullBaseFileName() {return fullBaseFileName;} const char* getRootFileName() {return rootFileName;} const char* getFullFileName() {return fullFileName;} const char* getRootFileName3d() {return rootFileName3d;} const char* getFullFileName3d() {return fullFileName3d;} const char* iisGetFileName() {return iisFileName;} void iisSetFileName(const char*); void setFileName(const char*); void updateFileName(); long naxis(int ii) {return naxis_[ii];} long width() {return naxis_[0];} long height() {return naxis_[1];} long depth() {return naxis_[2]>0?naxis_[2]:1;} Vector center() {return Vector(naxis_[0],naxis_[1])/2.;} int nhdu(); int bitpix() {return bitpix_;} int ext() {return fits_->ext();} FitsBound* getDataParams(FrScale::ScanMode); // return bbox in IMAGE void setCropParams(int); void setCropParams(int,int,int,int,int); void setCropParams(const Vector&, const Vector&, int); void setCrop3dParams(); void setCrop3dParams(int,int); void setCrop3dParams(double, double); void setMinMaxParams(); void setMinMaxParams(int,int,int,int); int hasLTMV() {return keyLTMV;} int hasATMV() {return keyATMV;} int hasDTMV() {return keyDTMV;} int isIIS() {return iisMode;} char* pix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, char* lbuf, int len) {return ASTpix2wcs(in, sys, sky, format, lbuf, len);} Vector pix2wcs(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) {return ASTpix2wcs(in, sys, sky);} Vector wcs2pix(Vector in, Coord::CoordSystem sys, Coord::SkyFrame sky) {return ASTwcs2pix(in, sys, sky);} double wcsdist(Vector aa, Vector bb, Coord::CoordSystem sys) {return ASTwcsdist(aa, bb, sys);} double pix2wcsx(double, Coord::CoordSystem, int); double wcs2pixx(double, Coord::CoordSystem, int); void initWCS(FitsHead*, FitsHead*); void listWCS(ostream&, Coord::CoordSystem); void resetWCS(); void replaceWCS(FitsHead*); void appendWCS(FitsHead*); void initWCS0(const Vector&); void resetWCS0(); void processKeywords(); int processKeywordsIRAF(FitsImage*); int processKeywordsWCS(FitsImage*, Coord::CoordSystem); WorldCoor* getWCS(Coord::CoordSystem sys) {return (wcs && wcs[sys-Coord::WCS]) ? wcs[sys-Coord::WCS] : NULL;} const char* getWCSName(Coord::CoordSystem sys) {return (wcs && wcs[sys-Coord::WCS]) ? wcs[sys-Coord::WCS]->wcsname : NULL;} Coord::Orientation getWCSOrientation(Coord::CoordSystem, Coord::SkyFrame); double getWCSRotation(Coord::CoordSystem, Coord::SkyFrame); Vector getWCScdelt(Coord::CoordSystem); Vector getWCScrpix(Coord::CoordSystem); Vector getWCScrval(Coord::CoordSystem); void setAstSkyFrame(AstFrameSet*, Coord::SkyFrame); void setAstFormat(AstFrameSet*, int, const char*); AstFrameSet* getAST(Coord::CoordSystem sys) {return (ast && ast[sys-Coord::WCS]) ? ast[sys-Coord::WCS] : NULL;} int hasWCS(Coord::CoordSystem); int hasWCSx(Coord::CoordSystem, int); int hasWCSEqu(Coord::CoordSystem); int hasWCSCel(Coord::CoordSystem); void updateMatrices(Matrix&, Matrix&, Matrix&); void updateMatrices(Matrix3d&); void updatePannerMatrices(Matrix&); void updatePannerMatrices(Matrix3d&); void updateMagnifierMatrices(Matrix&); void updateMagnifierMatrices(Matrix3d&); void updatePS(Matrix); void updatePS(Matrix3d); Matrix& matrixFromData(Coord::InternalSystem); Matrix& matrixToData(Coord::InternalSystem); Matrix3d& matrixFromData3d(Coord::InternalSystem); Matrix3d& matrixToData3d(Coord::InternalSystem); Vector mapFromRef(const Vector&, Coord::CoordSystem, Coord::SkyFrame =Coord::FK5); double mapFromRef3(double, Coord::CoordSystem, int); void mapFromRef(const Vector&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, char*,int); Vector mapToRef(const Vector&, Coord::CoordSystem, Coord::SkyFrame =Coord::FK5); double mapToRef3(double, Coord::CoordSystem, int); double mapLenFromRef(double, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); Vector mapLenFromRef(const Vector&, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); double mapLenToRef(double, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); Vector mapLenToRef(const Vector&, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); Vector mapLenFromImage(const Vector&, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); Vector mapLenToImage(const Vector&, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); double mapDistFromRef(const Vector&, const Vector&, Coord::CoordSystem, Coord::SkyDist =Coord::DEGREE); // we assume that 'data' is valid const char* getValue(const Vector& v); float getValueFloat(const Vector& v) {return data_->getValueFloat(v);} double getValueDouble(const Vector& v) {return data_->getValueDouble(v);} int getValueMask(const Vector& v) {return data_->getValueMask(v);} int getValueMask(double x, double y) {return data_->getValueMask(x,y);} float getValueFloat(long i) {return data_->getValueFloat(i);} double getValueDouble(long i) {return data_->getValueDouble(i);} int getValueMask(long i) {return data_->getValueMask(i);} void setClip(double l, double h) {data_->setClip(l,h);} const char* getMin() {return data_ ? data_->getMin() : NULL;} const char* getMax() {return data_ ? data_->getMax() : NULL;} double getMinDouble() {return data_ ? data_->getMinDouble() : 0;} double getMaxDouble() {return data_ ? data_->getMaxDouble() : 0;} const char* getLow() {return data_ ? data_->getLow() : NULL;} const char* getHigh() {return data_ ? data_->getHigh() : NULL;} double getLowDouble() {return data_ ? data_->getLowDouble() : 0;} double getHighDouble() {return data_ ? data_->getHighDouble() : 0;} void updateClip(FrScale*); int hasDATAMIN() {return data_ ? data_->hasDATAMIN() : 0;} int hasDATASEC() {return keyDATASEC;} int hasIRAFMIN() {return data_ ? data_->hasIRAFMIN() : 0;} void bin(double* b, int l, double mn, double mx, FrScale::ScanMode ds) {data_->bin(b,l,mn,mx,getDataParams(ds));} char* display(FitsHead*); char* displayHeader(); char* displayPrimary(); char* displayWCS(); FitsHead* getHead(); char* getKeyword(const char*); int findKeyword(const char*); int saveFitsPrimHeader(OutFitsStream& str) {return image_ ? image_->saveFitsPrimHeader(str) : 0;} int saveFitsXtHeader(OutFitsStream& str, int dd) {return image_ ? image_->saveFitsXtHeader(str, dd) : 0;} int saveFitsHeader(OutFitsStream& str, int dd) {return image_ ? image_->saveFitsHeader(str, dd) : 0;} int saveFits(OutFitsStream& str) {return image_ ? image_->saveFits(str) : 0;} int saveFitsPad(OutFitsStream& str, size_t cnt, char fil) {return image_ ? image_->saveFitsPad(str, cnt, fil) : 0;} int saveFitsTable(OutFitsStream& str) {return fits_ ? fits_->saveFitsTable(str) : 0;} int saveArray(OutFitsStream& str, FitsFile::ArchType endian) {return image_ ? image_->saveArray(str, endian) : 0;} }; // Fits class FitsImageFitsAlloc : public FitsImage { public: FitsImageFitsAlloc(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageFitsAllocGZ : public FitsImage { public: FitsImageFitsAllocGZ(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageFitsChannel : public FitsImage { public: FitsImageFitsChannel(Base*, Tcl_Interp*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageFitsMMap : public FitsImage { public: FitsImageFitsMMap(Base*, const char*, int); }; class FitsImageFitsSMMap : public FitsImage { public: FitsImageFitsSMMap(Base*, const char*, const char*, int); }; class FitsImageFitsMMapIncr : public FitsImage { public: FitsImageFitsMMapIncr(Base*, const char*, int); }; class FitsImageFitsShare : public FitsImage { public: FitsImageFitsShare(Base*, Base::ShmType, int, const char*, int); }; class FitsImageFitsSShare : public FitsImage { public: FitsImageFitsSShare(Base*, Base::ShmType, int, int, const char*, int); }; class FitsImageFitsSocket : public FitsImage { public: FitsImageFitsSocket(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageFitsSocketGZ : public FitsImage { public: FitsImageFitsSocketGZ(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageFitsVar : public FitsImage { public: FitsImageFitsVar(Base*, Tcl_Interp*, const char*, const char*, int); }; // Fits Next class FitsImageFitsNextAlloc : public FitsImage { public: FitsImageFitsNextAlloc(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextAllocGZ : public FitsImage { public: FitsImageFitsNextAllocGZ(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextChannel : public FitsImage { public: FitsImageFitsNextChannel(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextMMap : public FitsImage { public: FitsImageFitsNextMMap(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextSMMap : public FitsImage { public: FitsImageFitsNextSMMap(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextMMapIncr : public FitsImage { public: FitsImageFitsNextMMapIncr(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextShare : public FitsImage { public: FitsImageFitsNextShare(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextSShare : public FitsImage { public: FitsImageFitsNextSShare(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextSocket : public FitsImage { public: FitsImageFitsNextSocket(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextSocketGZ : public FitsImage { public: FitsImageFitsNextSocketGZ(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextVar : public FitsImage { public: FitsImageFitsNextVar(Base*, const char*, FitsFile*, int); }; class FitsImageFitsNextHist : public FitsImage { public: FitsImageFitsNextHist(Base*, FitsImage*, FitsFile*, int); }; class FitsImageFitsNextCompress : public FitsImage { public: FitsImageFitsNextCompress(Base*, FitsImage*, FitsFile*, int); }; // Array class FitsImageArrAlloc : public FitsImage { public: FitsImageArrAlloc(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageArrAllocGZ : public FitsImage { public: FitsImageArrAllocGZ(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageArrChannel : public FitsImage { public: FitsImageArrChannel(Base*, Tcl_Interp*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageArrMMap : public FitsImage { public: FitsImageArrMMap(Base*, const char*, int); }; class FitsImageArrMMapIncr : public FitsImage { public: FitsImageArrMMapIncr(Base*, const char*, int); }; class FitsImageArrShare : public FitsImage { public: FitsImageArrShare(Base*, Base::ShmType, int, const char*, int); }; class FitsImageArrSocket : public FitsImage { public: FitsImageArrSocket(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageArrSocketGZ : public FitsImage { public: FitsImageArrSocketGZ(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageArrVar : public FitsImage { public: FitsImageArrVar(Base*, Tcl_Interp*, const char*, const char*, int); }; // NRRD class FitsImageNRRDAlloc : public FitsImage { public: FitsImageNRRDAlloc(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageNRRDChannel : public FitsImage { public: FitsImageNRRDChannel(Base*, Tcl_Interp*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageNRRDMMap : public FitsImage { public: FitsImageNRRDMMap(Base*, const char*, int); }; class FitsImageNRRDShare : public FitsImage { public: FitsImageNRRDShare(Base*, Base::ShmType, int, const char*, int); }; class FitsImageNRRDSocket : public FitsImage { public: FitsImageNRRDSocket(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageNRRDVar : public FitsImage { public: FitsImageNRRDVar(Base*, Tcl_Interp*, const char*, const char*, int); }; // Photo class FitsImagePhoto : public FitsImage { public: FitsImagePhoto(Base*, Tcl_Interp*, const char*, const char*, int); }; class FitsImagePhotoCube : public FitsImage { public: FitsImagePhotoCube(Base*, Tcl_Interp*, const char*, const char*, int); }; class FitsImagePhotoCubeNext : public FitsImage { public: FitsImagePhotoCubeNext(Base*, const char*, FitsFile*, int); }; // Mosaic class FitsImageMosaicAlloc : public FitsImage { public: FitsImageMosaicAlloc(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageMosaicAllocGZ : public FitsImage { public: FitsImageMosaicAllocGZ(Base*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageMosaicChannel : public FitsImage { public: FitsImageMosaicChannel(Base*, Tcl_Interp*, const char*, const char*, FitsFile::FlushMode, int); }; class FitsImageMosaicMMap : public FitsImage { public: FitsImageMosaicMMap(Base*, const char*, int); }; class FitsImageMosaicMMapIncr : public FitsImage { public: FitsImageMosaicMMapIncr(Base*, const char*, int); }; class FitsImageMosaicShare : public FitsImage { public: FitsImageMosaicShare(Base*, Base::ShmType, int, const char*, int); }; class FitsImageMosaicSocket : public FitsImage { public: FitsImageMosaicSocket(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageMosaicSocketGZ : public FitsImage { public: FitsImageMosaicSocketGZ(Base*, int, const char*, FitsFile::FlushMode, int); }; class FitsImageMosaicVar : public FitsImage { public: FitsImageMosaicVar(Base*, Tcl_Interp*, const char*, const char*, int); }; // Mosaic Next class FitsImageMosaicNextAlloc : public FitsImage { public: FitsImageMosaicNextAlloc(Base*, const char*, FitsFile*, FitsFile::FlushMode, int); }; class FitsImageMosaicNextAllocGZ : public FitsImage { public: FitsImageMosaicNextAllocGZ(Base*, const char*, FitsFile*, FitsFile::FlushMode, int); }; class FitsImageMosaicNextChannel : public FitsImage { public: FitsImageMosaicNextChannel(Base*, const char*, FitsFile*, FitsFile::FlushMode, int); }; class FitsImageMosaicNextMMap : public FitsImage { public: FitsImageMosaicNextMMap(Base*, const char*, FitsFile*, int); }; class FitsImageMosaicNextMMapIncr : public FitsImage { public: FitsImageMosaicNextMMapIncr(Base*, const char*, FitsFile*, int); }; class FitsImageMosaicNextShare : public FitsImage { public: FitsImageMosaicNextShare(Base*, const char*, FitsFile*, int); }; class FitsImageMosaicNextSocket : public FitsImage { public: FitsImageMosaicNextSocket(Base*, const char*, FitsFile*, FitsFile::FlushMode, int); }; class FitsImageMosaicNextSocketGZ : public FitsImage { public: FitsImageMosaicNextSocketGZ(Base*, const char*, FitsFile*, FitsFile::FlushMode, int); }; class FitsImageMosaicNextVar : public FitsImage { public: FitsImageMosaicNextVar(Base*, const char*, FitsFile*, int); }; // IIS class FitsImageIIS : public FitsImage { public: FitsImageIIS(Base*, int, int); void iisErase(); char* iisGet(int xx, int yy, int dx, int dy); void iisSet(const char* src, int xx, int yy, int dx, int dy); void iisWCS(const Matrix&, const Vector&, int); }; #endif �������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsdata.C���������������������������������������������������������������������0000644�0001750�0001750�00000145103�12107012361�015216� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsdata.h" #include "colorscale.h" #include "sigbus.h" #define INTERP (((Base*)parent)->interp) // ZSCALE #define ZSMAX(a,b) ((a) > (b) ? (a) : (b)) #define ZSMIN(a,b) ((a) < (b) ? (a) : (b)) #define ZSMOD(a,b) ((a) % (b)) #define ZSNINT(a) ((int)(a + 0.5)) #define ZSINDEF 0 // smallest permissible sample #define ZSMIN_NPIXELS 5 // max frac. of pixels to be rejected #define ZSMAX_REJECT 0.5 // k-sigma pixel rejection factor #define ZSKREJ 2.5 // maximum number of fitline iterations #define ZSMAX_ITERATIONS 5 // FitsData ostream& operator<<(ostream& ss, const FitsBound& fb) { ss << ' ' << fb.xmin << ' ' << fb.ymin << ' ' << fb.zmin << ' ' << fb.xmax << ' ' << fb.ymax << ' ' << fb.zmax; return ss; } FitsData::FitsData(FitsFile* fits, Base* p) { parent = p; FitsImageHDU* hdu = (FitsImageHDU*)fits->head()->hdu(); width = hdu->naxis(0); height = hdu->naxis(1); buf[0] = '\0'; byteswap = fits->byteswap(); bscale = hdu->bscale(); bzero = hdu->bzero(); blank = hdu->blank(); hasScaling = hdu->hasscaling(); switch (hdu->bitpix()) { case 8: case 16: case -16: case 32: case 64: hasBlank = hdu->hasblank(); break; case -32: case -64: hasBlank = 0; break; } low = high = 0; zLow = zHigh = 0; aLow = aHigh = 0; uLow = uHigh = 0; scanValid = 0; incr_ = 100; zContrast = .5; zSample = 600; zLine = 5; zscaleValid = 0; autoCutValid = 0; autoCutPer = 0; clipMode = FrScale::MINMAX; mmMode = FrScale::SAMPLE; if (fits->find("DATAMIN") && fits->find("DATAMAX")) { hasdatamin = 1; datamin = fits->getReal("DATAMIN", 0); datamax = fits->getReal("DATAMAX", 0); } else { hasdatamin = 0; datamin = datamax = 0; } if (fits->find("IRAF-MIN") && fits->find("IRAF-MAX")) { hasirafmin = 1; irafmin = fits->getReal("IRAF-MIN", 0); irafmax = fits->getReal("IRAF-MAX", 0); } else { hasirafmin = 0; irafmin = irafmax = 0; } scanMode = FrScale::IMGSEC; } FitsData::~FitsData() { } const char* FitsData::getLow() { ostringstream str; str << low << ends; memcpy(buf,str.str().c_str(),str.str().length()); return buf; } const char* FitsData::getHigh() { ostringstream str; str << high << ends; memcpy(buf,str.str().c_str(),str.str().length()); return buf; } int FitsData::getIncr() { switch (mmMode) { case FrScale::AUTOSCAN: if (width*height*parent->fitsCount() > 1e8) return incr_; else return 1; case FrScale::SCAN: return 1; case FrScale::SAMPLE: return incr_; } } // AutoCut #define AUTOCUTSIZE 10240 void FitsData::autoCut(FitsBound* params) { double amin = getMinDouble(); double amax = getMaxDouble(); // bin it up double hist[AUTOCUTSIZE]; memset(hist,0,sizeof(double)*AUTOCUTSIZE); bin(hist, AUTOCUTSIZE, amin, amax, params); // find total number of pixels int total = 0; for (int ii=0; ii<AUTOCUTSIZE; ii++) total += hist[ii]; // calc cut off int cutoff = (total*(100.-autoCutPer)/100.)/2.; int count; int ll, hh; for (ll=0,count=0; ll<AUTOCUTSIZE; ll++) { count += hist[ll]; if (count > cutoff) break; } for (hh=AUTOCUTSIZE-1,count=0; hh>ll+1; hh--) { count += hist[hh]; if (count > cutoff) break; } aLow = (amax-amin)/AUTOCUTSIZE*ll + amin; aHigh = (amax-amin)/AUTOCUTSIZE*hh + amin; } // FitsDatam template<class T> FitsDatam<T>::FitsDatam(FitsFile* fits, Base* p) : FitsData(fits,p) { data = (T*)fits->data(); min=max=0; } // swap (optimized) template <> unsigned char FitsDatam<unsigned char>::swap(unsigned char* ptr) { return *ptr; } template <> short FitsDatam<short>::swap(short* ptr) { const char* p = (const char*)ptr; union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> unsigned short FitsDatam<unsigned short>::swap(unsigned short* ptr) { const char* p = (const char*)ptr; union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> int FitsDatam<int>::swap(int* ptr) { const char* p = (const char*)ptr; union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> long long FitsDatam<long long>::swap(long long* ptr) { const char* p = (const char*)ptr; union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> float FitsDatam<float>::swap(float* ptr) { const char* p = (const char*)ptr; union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.f; } template <> double FitsDatam<double>::swap(double* ptr) { const char* p = (const char*)ptr; union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.d; } // Private/Protected // output template<class T> void FitsDatam<T>::output(ostringstream& str, T value) { str << value << ends; } template <> void FitsDatam<unsigned char>::output(ostringstream& str, unsigned char value) { str << (unsigned short)value << ends; } template <> void FitsDatam<unsigned short>::output(ostringstream& str, unsigned short value) { str << (unsigned short)value << ends; } // updateMinMax template<class T> void FitsDatam<T>::updateMinMax(FitsBound* params) { if (!scanValid) { scan(params); scanValid = 1; } } // scan (optimized) template <> void FitsDatam<unsigned char>::scan(FitsBound* params) { min = UCHAR_MAX; max = 0; int incr = getIncr(); if (DebugPerf) cerr << "scan char... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { unsigned char* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register unsigned char value = *ptr; if (hasBlank && value == blank) continue; // skip nan's if (value < min) min = value; else if (value > max) max = value; } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << (unsigned short)min << " max: " << (unsigned short)max << endl; } } template <> void FitsDatam<short>::scan(FitsBound* params) { min = SHRT_MAX; max = SHRT_MIN; int incr = getIncr(); if (DebugPerf) cerr << "scan short... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { short* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register short value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; value = u.s; } if (hasBlank && value == blank) continue; // skip nan's if (value < min) min = value; else if (value > max) max = value; } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } template <> void FitsDatam<unsigned short>::scan(FitsBound* params) { min = USHRT_MAX; max = 0; int incr = getIncr(); if (DebugPerf) cerr << "scan unsigned short... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { unsigned short* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register unsigned short value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; value = u.s; } if (hasBlank && value == blank) continue; // skip nan's if (value < min) min = value; else if (value > max) max = value; } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } template <> void FitsDatam<int>::scan(FitsBound* params) { min = INT_MAX; max = INT_MIN; int incr = getIncr(); if (DebugPerf) cerr << "scan int... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { int* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register int value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; value = u.i; } if (hasBlank && value == blank) continue; // skip nan's if (value < min) min = value; else if (value > max) max = value; } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } template <> void FitsDatam<long long>::scan(FitsBound* params) { min = INT_MAX; max = INT_MIN; int incr = getIncr(); if (DebugPerf) cerr << "scan long long... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { long long* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register long long value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; value = u.i; } if (hasBlank && value == blank) continue; // skip nan's if (value < min) min = value; else if (value > max) max = value; } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } template <> void FitsDatam<float>::scan(FitsBound* params) { min = FLT_MAX; max = -FLT_MAX; int incr = getIncr(); if (DebugPerf) cerr << "scan float... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { float* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register float value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; value = u.f; } if (isfinite(value)) { if (value < min) min = value; else if (value > max) max = value; } } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } template <> void FitsDatam<double>::scan(FitsBound* params) { min = DBL_MAX; max = -DBL_MAX; int incr = getIncr(); if (DebugPerf) cerr << "scan double... incr=" << incr << " (" << params->xmin << ',' << params->ymin << ") to (" << params->xmax << ',' << params->ymax << ") "; SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { double* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register double value; if (!byteswap) value = *ptr; else { const char* p = (const char*)ptr; union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; value = u.d; } if (isfinite(value)) { if (value < min) min = value; else if (value > max) max = value; } } } CLEARSIGBUS if (DebugPerf) { cerr << "end" << endl; cerr << "min: " << min << " max: " << max << endl; } } // Public // updateClip template<class T> void FitsDatam<T>::updateClip(FrScale* fr, FitsBound* params) { // we do not check for blank/nan since this should never be set to nan clipMode = fr->clipMode(); uLow = fr->uLow(); uHigh = fr->uHigh(); // DATASEC if (scanMode != fr->scanMode()) { if (DebugPerf) cerr << "reset updateClip" << endl; scanValid = 0; zscaleValid = 0; autoCutValid = 0; } scanMode = fr->scanMode(); // MINMAX if (mmMode != fr->mmMode() || incr_ != fr->mmIncr()) scanValid = 0; mmMode = fr->mmMode(); incr_ = fr->mmIncr(); // ZSCALE if (zContrast != fr->zContrast() || zSample != fr->zSample() || zLine != fr->zLine()) zscaleValid = 0; zContrast = fr->zContrast(); zSample = fr->zSample(); zLine = fr->zLine(); // AUTOCUT if (mmMode != fr->mmMode() || autoCutPer != fr->autoCutPer()) autoCutValid = 0; autoCutPer = fr->autoCutPer(); // always update min/max because everyone needs it updateMinMax(params); switch (clipMode) { case FrScale::MINMAX: low = getMinDouble(); high = getMaxDouble(); break; case FrScale::ZSCALE: if (!zscaleValid) { if (DebugPerf) cerr << "zscale..."; zscale(params); zscaleValid = 1; if (DebugPerf) cerr << "end" << endl; } low = zLow; high = zHigh; break; case FrScale::ZMAX: // set low via zscale, high via minmax if (!zscaleValid) { if (DebugPerf) cerr << "zscale..."; zscale(params); zscaleValid = 1; if (DebugPerf) cerr << "end" << endl; } low = zLow; high = getMaxDouble(); break; case FrScale::AUTOCUT: if (!autoCutValid) { if (DebugPerf) cerr << "autocut..."; autoCut(params); autoCutValid = 1; if (DebugPerf) cerr << "end" << endl; } low = aLow; high = aHigh; break; case FrScale::USERCLIP: low = uLow; high = uHigh; break; } } // getValue template<class T> const char* FitsDatam<T>::getValue(const Vector& vv) { Vector v(vv); long x = (long)v[0]; long y = (long)v[1]; ostringstream str; if (x >= 0 && x < width && y >= 0 && y < height) { register T value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (hasBlank && value == blank) str << "blank" << ends; else if (hasScaling) str << value * bscale + bzero << ends; else output(str, value); } else str << ends; memcpy(buf,str.str().c_str(),str.str().length()); return buf; } template <> const char* FitsDatam<float>::getValue(const Vector& vv) { Vector v(vv); long x = (long)v[0]; long y = (long)v[1]; ostringstream str; if (x >= 0 && x < width && y >= 0 && y < height) { register float value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isinf(value)) str << "inf" << ends; else if (isnan(value)) str << "nan" << ends; else if (hasScaling) str << value * bscale + bzero << ends; else str << value << ends; } else str << ends; memcpy(buf,str.str().c_str(),str.str().length()); return buf; } template <> const char* FitsDatam<double>::getValue(const Vector& vv) { Vector v(vv); long x = (long)v[0]; long y = (long)v[1]; ostringstream str; if (x >= 0 && x < width && y >= 0 && y < height) { register double value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isinf(value)) str << "inf" << ends; else if (isnan(value)) str << "nan" << ends; else if (hasScaling) str << value * bscale + bzero << ends; else str << value << ends; } else str << ends; memcpy(buf,str.str().c_str(),str.str().length()); return buf; } // getValueFloat(long) (optimized) // no bounds checking, we need the speed template <> float FitsDatam<unsigned char>::getValueFloat(long i) { if (!hasBlank && !hasScaling) return data[i]; if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } template <> float FitsDatam<short>::getValueFloat(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.s; if (hasBlank && u.s == blank) return NAN; else return hasScaling ? u.s * bscale + bzero : u.s; } } template <> float FitsDatam<unsigned short>::getValueFloat(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.s; if (hasBlank && u.s == blank) return NAN; else return hasScaling ? u.s * bscale + bzero : u.s; } } template <> float FitsDatam<int>::getValueFloat(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.i; if (hasBlank && u.i == blank) return NAN; else return hasScaling ? u.i * bscale + bzero : u.i; } } template <> float FitsDatam<long long>::getValueFloat(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.i; if (hasBlank && u.i == blank) return NAN; else return hasScaling ? u.i * bscale + bzero : u.i; } } template <> float FitsDatam<float>::getValueFloat(long i) { if (!byteswap) if (isfinite(data[i])) return hasScaling ? data[i] * bscale + bzero : data[i]; else return NAN; else { const char* p = (const char*)(data+i); union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (isfinite(u.f)) return hasScaling ? u.f * bscale + bzero : u.f; else return NAN; } } template <> float FitsDatam<double>::getValueFloat(long i) { if (!byteswap) if (isfinite(data[i])) return hasScaling ? (float)data[i] * bscale + bzero : (float)data[i]; else return NAN; else { const char* p = (const char*)(data+i); union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (isfinite(u.d)) return hasScaling ? (float)u.d * bscale + bzero : (float)u.d; else return NAN; } } // getValueFloat(const Vector&) template<class T> float FitsDatam<T>::getValueFloat(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register T value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (hasBlank && value == blank) return NAN; return hasScaling ? value * bscale + bzero : value; } else return NAN; } template <> float FitsDatam<float>::getValueFloat(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register float value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isfinite(value)) return hasScaling ? value * bscale + bzero : value; else return NAN; } else return NAN; } template <> float FitsDatam<double>::getValueFloat(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register double value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isfinite(value)) return hasScaling ? (float)value * bscale + bzero : (float)value; else return NAN; } else return NAN; } // getValueDouble(long) (optimized) // no bounds checking, we need the speed template <> double FitsDatam<unsigned char>::getValueDouble(long i) { if (!hasBlank && !hasScaling) return data[i]; if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } template <> double FitsDatam<short>::getValueDouble(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.s; if (hasBlank && u.s == blank) return NAN; else return hasScaling ? u.s * bscale + bzero : u.s; } } template <> double FitsDatam<unsigned short>::getValueDouble(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.s; if (hasBlank && u.s == blank) return NAN; else return hasScaling ? u.s * bscale + bzero : u.s; } } template <> double FitsDatam<int>::getValueDouble(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.i; if (hasBlank && u.i == blank) return NAN; else return hasScaling ? u.i * bscale + bzero : u.i; } } template <> double FitsDatam<long long>::getValueDouble(long i) { if (!byteswap && !hasBlank && !hasScaling) return data[i]; if (!byteswap) { if (hasBlank && data[i] == blank) return NAN; else return hasScaling ? data[i] * bscale + bzero : data[i]; } else { const char* p = (const char*)(data+i); union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (!hasBlank && !hasScaling) return u.i; if (hasBlank && u.i == blank) return NAN; else return hasScaling ? u.i * bscale + bzero : u.i; } } template <> double FitsDatam<float>::getValueDouble(long i) { if (!byteswap && !hasScaling) return (double)data[i]; if (!byteswap) { if (isfinite(data[i])) return hasScaling ? (double)data[i] * bscale + bzero : (double)data[i]; else return NAN; } else { const char* p = (const char*)(data+i); union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (isfinite(u.f)) return hasScaling ? (double)u.f * bscale + bzero : (double)u.f; else return NAN; } } template <> double FitsDatam<double>::getValueDouble(long i) { if (!byteswap && !hasScaling) return (double)data[i]; if (!byteswap) { if (isfinite(data[i])) return hasScaling ? data[i] * bscale + bzero : data[i]; else return NAN; } else { const char* p = (const char*)(data+i); union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; if (isfinite(u.d)) return hasScaling ? u.d * bscale + bzero : u.d; else return NAN; } } // getValueDouble(const Vector&) template<class T> double FitsDatam<T>::getValueDouble(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register T value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (hasBlank && value == blank) return NAN; return hasScaling ? value * bscale + bzero : value; } else return NAN; } template <> double FitsDatam<float>::getValueDouble(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register float value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isfinite(value)) return hasScaling ? (double)value * bscale + bzero : (double)value; else return NAN; } else return NAN; } template <> double FitsDatam<double>::getValueDouble(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) { register double value = !byteswap ? data[y*width + x] : swap(data+(y*width + x)); if (isfinite(value)) return hasScaling ? value * bscale + bzero : value; else return NAN; } else return NAN; } // getValueMask template <class T> int FitsDatam<T>::getValueMask(const Vector& v) { Vector r = v; long x = (long)r[0]; long y = (long)r[1]; if (x >= 0 && x < width && y >= 0 && y < height) return data[y*width + x] ? 1 : 0; else return 0; } template <class T> int FitsDatam<T>::getValueMask(double xx, double yy) { long x = (long)xx; long y = (long)yy; if (x >= 0 && x < width && y >= 0 && y < height) return data[y*width + x] ? 1 : 0; else return 0; } template<class T> int FitsDatam<T>::getValueMask(long i) { return data[i] ? 1 : 0; } // getMin template<class T> const char* FitsDatam<T>::getMin() { // we do not check for blank since this should never be set to nan ostringstream str; switch (mmMode) { case FrScale::AUTOSCAN: case FrScale::SCAN: case FrScale::SAMPLE: if (hasScaling) str << min * bscale + bzero << ends; else output(str,min); break; case FrScale::DATAMIN: if (hasdatamin) str << datamin << ends; else str << ends; break; case FrScale::IRAFMIN: if (hasirafmin) str << irafmin << ends; else str << ends; break; } memcpy(buf,str.str().c_str(),str.str().length()); return buf; } // getMax template<class T> const char* FitsDatam<T>::getMax() { // we do not check for blank since this should never be set to nan ostringstream str; switch (mmMode) { case FrScale::AUTOSCAN: case FrScale::SCAN: case FrScale::SAMPLE: if (hasScaling) str << max * bscale + bzero << ends; else output(str,max); break; case FrScale::DATAMIN: if (hasdatamin) str << datamax << ends; else str << ends; break; case FrScale::IRAFMIN: if (hasirafmin) str << irafmax << ends; else str << ends; break; } memcpy(buf,str.str().c_str(),str.str().length()); return buf; } // getMinDouble template<class T> double FitsDatam<T>::getMinDouble() { // we do not check for blank since this should never be set to nan switch (mmMode) { case FrScale::AUTOSCAN: case FrScale::SCAN: case FrScale::SAMPLE: if (hasScaling) return min * bscale + bzero; else return min; case FrScale::DATAMIN: if (hasdatamin) return datamin; else return 0; case FrScale::IRAFMIN: if (hasirafmin) return irafmin; else return 0; } } // getMaxDouble template<class T> double FitsDatam<T>::getMaxDouble() { // we do not check for blank since this should never be set to nan switch (mmMode) { case FrScale::AUTOSCAN: case FrScale::SCAN: case FrScale::SAMPLE: if (hasScaling) return max * bscale + bzero; else return max; case FrScale::DATAMIN: if (hasdatamin) return datamax; else return 0; case FrScale::IRAFMIN: if (hasirafmin) return irafmax; return 0; } } // bin template<class T> void FitsDatam<T>::bin(double* arr, int length, double mn, double mx, FitsBound* params) { if (DebugPerf) cerr << "bin..."; double diff = mx-mn; int last = length-1; int incr = getIncr(); // special case: mx-mn=0 if (!diff) { arr[0] = (params->xmax-params->xmin)*(params->ymax-params->ymin); return; } SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { T* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register double value = !byteswap ? *ptr : swap(ptr); if (hasBlank && value == blank) continue; // skip nan's if (hasScaling) value = value * bscale + bzero; if (value>=mn && value <=mx) arr[(int)(((value-mn)/diff)*last+.5)]++; } } CLEARSIGBUS } template <> void FitsDatam<float>::bin(double* arr, int length, double mn, double mx, FitsBound* params) { if (DebugPerf) cerr << "bin..."; double diff = mx-mn; int last = length-1; int incr = getIncr(); // special case: mx-mn=0 if (!diff) { arr[0] = (params->xmax-params->xmin)*(params->ymax-params->ymin); return; } SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { float* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register double value = !byteswap ? *ptr : swap(ptr); if (!isfinite(value)) continue; // skip nan's if (hasScaling) value = value * bscale + bzero; if (value>=mn && value <=mx) arr[(int)(((value-mn)/diff)*last+.5)]++; } } CLEARSIGBUS } template <> void FitsDatam<double>::bin(double* arr, int length, double mn, double mx, FitsBound* params) { if (DebugPerf) cerr << "bin..."; double diff = mx-mn; int last = length-1; int incr = getIncr(); // special case: mx-mn=0 if (!diff) { arr[0] = (params->xmax-params->xmin)*(params->ymax-params->ymin); return; } SETSIGBUS for (int j=params->ymin; j<params->ymax; j+=incr) { double* ptr = data + j*long(width) + long(params->xmin); for (int i=params->xmin; i<params->xmax; i+=incr, ptr+=incr) { register double value = !byteswap ? *ptr : swap(ptr); if (!isfinite(value)) continue; // skip nan's if (hasScaling) value = value * bscale + bzero; if (value>=mn && value <=mx) arr[(int)(((value-mn)/diff)*last+.5)]++; } } CLEARSIGBUS } // ZSCALE // ZSCALE -- Compute the optimal Z1, Z2 (range of greyscale values to be // displayed) of an image. For efficiency a statistical subsample of an image // is used. The pixel sample evenly subsamples the image in x and y. The // entire image is used if the number of pixels in the image is smaller than // the desired sample. // // The sample is accumulated in a buffer and sorted by greyscale value. // The median value is the central value of the sorted array. The slope of a // straight line fitted to the sorted sample is a measure of the standard // deviation of the sample about the median value. Our algorithm is to sort // the sample and perform an iterative fit of a straight line to the sample, // using pixel rejection to omit gross deviants near the endpoints. The fitted // straight line is the transfer function used to map image Z into display Z. // If more than half the pixels are rejected the full range is used. The slope // of the fitted line is divided by the user-supplied contrast factor and the // final Z1 and Z2 are computed, taking the origin of the fitted line at the // median value. template<class T> void FitsDatam<T>::zscale(FitsBound* params) { // Subsample the image float* sample; int npix = zSampleImage(&sample,params); int center_pixel = ZSMAX(1, (npix + 1) / 2); // Sort the sample, compute the minimum, maximum, and median pixel values qsort((void*)sample, npix, sizeof(float), fCompare); float zmin = *sample; float zmax = *(sample+ZSMAX(npix,1)-1); // The median value is the average of the two central values if there // are an even number of pixels in the sample. float* left = &(sample[center_pixel - 1]); float median; if (ZSMOD(npix, 2) == 1 || center_pixel >= npix) median = *left; else median = (*left + *(left+1)) / 2; // Fit a line to the sorted sample vector. If more than half of the // pixels in the sample are rejected give up and return the full range. // If the user-supplied contrast factor is not 1.0 adjust the scale // accordingly and compute zLow and zHigh, the y intercepts at indices 1 and // npix. int minpix = ZSMAX(ZSMIN_NPIXELS, (int)(npix * ZSMAX_REJECT)); int ngrow = ZSMAX(1, ZSNINT(npix * .01)); float zstart, zslope; int ngoodpix = zFitLine(sample, npix, &zstart, &zslope, ZSKREJ, ngrow, ZSMAX_ITERATIONS); if (ngoodpix < minpix) { zLow = zmin; zHigh = zmax; } else { if (zContrast > 0) zslope = zslope / zContrast; zLow = ZSMAX(zmin, median - (center_pixel - 1) * zslope); zHigh = ZSMIN(zmax, median + (npix - center_pixel) * zslope); } delete [] sample; } // sampleImage -- Extract an evenly gridded subsample of the pixels from // a two-dimensional image into a one-dimensional vector. template<class T> int FitsDatam<T>::zSampleImage(float** sample, FitsBound* params) { // Compute the number of pixels each line will contribute to the sample, // and the subsampling step size for a line. The sampling grid must // span the whole line on a uniform grid. int wd = params->xmax - params->xmin; int opt_npix_per_line = ZSMAX(1, ZSMIN(wd, zLine)); int col_step = ZSMAX(2, (wd + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (wd + col_step-1) / col_step); /* int opt_npix_per_line = ZSMAX(1, ZSMIN(width, zLine)); int col_step = ZSMAX(2, (width + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (width + col_step-1) / col_step); */ // Compute the number of lines to sample and the spacing between lines. // We must ensure that the image is adequately sampled despite its // size, hence there is a lower limit on the number of lines in the // sample. We also want to minimize the number of lines accessed when // accessing a large image, because each disk seek and read is ex- // pensive. The number of lines extracted will be roughly the sample // size divided by zLine, possibly more if the lines are very // short. int hd = params->ymax-params->ymin; int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(hd, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, hd / opt_nlines_in_sample); int max_nlines_in_sample = (hd + line_step-1) / line_step; /* int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(height, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, height / opt_nlines_in_sample); int max_nlines_in_sample = (height + line_step-1) / line_step; */ // Allocate space for the output vector. Buffer must be freed by our caller. int maxpix = npix_per_line * max_nlines_in_sample; *sample = new float[maxpix]; // float* row = new float[width]; float* row = new float[wd]; // Extract the vector int npix = 0; float* op = *sample; // for (int line = (line_step + 1)/2; line < height; line+=line_step) { for (int line = (line_step + 1)/2 + params->ymin; line < params->ymax; line+=line_step) { // Load a row of values from the image // for (int i=0; i < width; i++) { for (int i=0; i<wd; i++) { // T* ptr = data + (line-1)*width + i; T* ptr = data + (line-1)*long(width) + i + long(params->xmin); T value = !byteswap ? *ptr : swap(ptr); if (hasBlank && (value == blank)) row[i] = NAN; else row[i] = hasScaling ? value * bscale + bzero : value; } int got = zSubSample(row, op, npix_per_line, col_step); op += got; npix += got; if (npix >= maxpix) break; } delete [] row; return npix; } template <> int FitsDatam<float>::zSampleImage(float** sample, FitsBound* params) { // Compute the number of pixels each line will contribute to the sample, // and the subsampling step size for a line. The sampling grid must // span the whole line on a uniform grid. int wd = params->xmax - params->xmin; int opt_npix_per_line = ZSMAX(1, ZSMIN(wd, zLine)); int col_step = ZSMAX(2, (wd + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (wd + col_step-1) / col_step); /* int opt_npix_per_line = ZSMAX(1, ZSMIN(width, zLine)); int col_step = ZSMAX(2, (width + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (width + col_step-1) / col_step); */ // Compute the number of lines to sample and the spacing between lines. // We must ensure that the image is adequately sampled despite its // size, hence there is a lower limit on the number of lines in the // sample. We also want to minimize the number of lines accessed when // accessing a large image, because each disk seek and read is ex- // pensive. The number of lines extracted will be roughly the sample // size divided by zLine, possibly more if the lines are very // short. int hd = params->ymax-params->ymin; int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(hd, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, hd / opt_nlines_in_sample); int max_nlines_in_sample = (hd + line_step-1) / line_step; /* int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(height, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, height / opt_nlines_in_sample); int max_nlines_in_sample = (height + line_step-1) / line_step; */ // Allocate space for the output vector. Buffer must be freed by our caller. int maxpix = npix_per_line * max_nlines_in_sample; *sample = new float[maxpix]; // float* row = new float[width]; float* row = new float[wd]; // Extract the vector int npix = 0; float* op = *sample; // for (int line = (line_step + 1)/2; line < height; line+=line_step) { for (int line = (line_step + 1)/2 + params->ymin; line < params->ymax; line+=line_step) { // Load a row of values from the image // for (int i=0; i < width; i++) { for (int i=0; i<wd; i++) { // T* ptr = data + (line-1)*width + i; float* ptr = data + (line-1)*long(width) + i + long(params->xmin); float value = !byteswap ? *ptr : swap(ptr); if (isfinite(value)) row[i] = hasScaling ? value * bscale + bzero : value; else row[i] = NAN; } int got = zSubSample(row, op, npix_per_line, col_step); op += got; npix += got; if (npix >= maxpix) break; } delete [] row; return npix; } template <> int FitsDatam<double>::zSampleImage(float** sample, FitsBound* params) { // Compute the number of pixels each line will contribute to the sample, // and the subsampling step size for a line. The sampling grid must // span the whole line on a uniform grid. int wd = params->xmax - params->xmin; int opt_npix_per_line = ZSMAX(1, ZSMIN(wd, zLine)); int col_step = ZSMAX(2, (wd + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (wd + col_step-1) / col_step); /* int opt_npix_per_line = ZSMAX(1, ZSMIN(width, zLine)); int col_step = ZSMAX(2, (width + opt_npix_per_line-1) / opt_npix_per_line); int npix_per_line = ZSMAX(1, (width + col_step-1) / col_step); */ // Compute the number of lines to sample and the spacing between lines. // We must ensure that the image is adequately sampled despite its // size, hence there is a lower limit on the number of lines in the // sample. We also want to minimize the number of lines accessed when // accessing a large image, because each disk seek and read is ex- // pensive. The number of lines extracted will be roughly the sample // size divided by zLine, possibly more if the lines are very // short. int hd = params->ymax-params->ymin; int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(hd, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, hd / opt_nlines_in_sample); int max_nlines_in_sample = (hd + line_step-1) / line_step; /* int min_nlines_in_sample = ZSMAX(1, zSample / zLine); int opt_nlines_in_sample = ZSMAX(min_nlines_in_sample, ZSMIN(height, (zSample + npix_per_line-1) / npix_per_line)); int line_step = ZSMAX(2, height / opt_nlines_in_sample); int max_nlines_in_sample = (height + line_step-1) / line_step; */ // Allocate space for the output vector. Buffer must be freed by our caller. int maxpix = npix_per_line * max_nlines_in_sample; *sample = new float[maxpix]; // float* row = new float[width]; float* row = new float[wd]; // Extract the vector int npix = 0; float* op = *sample; // for (int line = (line_step + 1)/2; line < height; line+=line_step) { for (int line = (line_step + 1)/2 + params->ymin; line < params->ymax; line+=line_step) { // Load a row of values from the image // for (int i=0; i < width; i++) { for (int i=0; i<wd; i++) { // T* ptr = data + (line-1)*width + i; double* ptr = data + (line-1)*long(width) + i + long(params->xmin); double value = !byteswap ? *ptr : swap(ptr); if (isfinite(value)) row[i] = hasScaling ? (float)value * bscale + bzero : (float)value; else row[i] = NAN; } int got = zSubSample(row, op, npix_per_line, col_step); op += got; npix += got; if (npix >= maxpix) break; } delete [] row; return npix; } // subSample -- Subsample an image line. Extract the first pixel and // every "step"th pixel thereafter for a total of npix pixels. int FitsData::zSubSample(float* a, float* b, int npix, int step) { if (step <= 1) step = 1; int got = 0; int ip = 0; for (int i=0; i<npix; i++) { if (isfinite(a[ip])) // we skip over the nan pixels b[got++] = a[ip]; ip += step; } return got; } // fitLine -- Fit a straight line to a data array of type real. This is // an iterative fitting algorithm, wherein points further than ksigma from the // current fit are excluded from the next fit. Convergence occurs when the // next iteration does not decrease the number of pixels in the fit, or when // there are no pixels left. The number of pixels left after pixel rejection // is returned as the function value. int FitsData::zFitLine (float* sampleData, int npix, float* zstart, float* zslope, float krej, int ngrow, int maxiter) { float xscale; if (npix <= 0) return (0); else if (npix == 1) { *zstart = sampleData[1]; *zslope = 0.0; return (1); } else xscale = 2.0 / (npix - 1); // Allocate a buffer for data minus fitted curve, another for the // normalized X values, and another to flag rejected pixels. float* flat = new float[npix]; float* normx = new float[npix]; short* badpix = new short[npix]; for (int k=0; k<npix; k++) badpix[k]=0; // Compute normalized X vector. The data X values [1:npix] are // normalized to the range [-1:1]. This diagonalizes the lsq matrix // and reduces its condition number. for (int i=0; i<npix; i++) normx[i] = i * xscale - 1.0; // Fit a line with no pixel rejection. Accumulate the elements of the // matrix and data vector. The matrix M is diagonal with // M[1,1] = sum x**2 and M[2,2] = ngoodpix. The data vector is // DV[1] = sum (data[i] * x[i]) and DV[2] = sum (data[i]). double sumxsqr = 0; double sumxz = 0; double sumx = 0; double sumz = 0; for (int j=0; j<npix; j++) { float x = normx[j]; float z = sampleData[j]; sumxsqr = sumxsqr + (x * x); sumxz = sumxz + z * x; sumz = sumz + z; } // Solve for the coefficients of the fitted line float z0 = sumz / npix; float dz = sumxz / sumxsqr; // Iterate, fitting a new line in each iteration. Compute the flattened // data vector and the sigma of the flat vector. Compute the lower and // upper k-sigma pixel rejection thresholds. Run down the flat array // and detect pixels to be rejected from the fit. Reject pixels from // the fit by subtracting their contributions from the matrix sums and // marking the pixel as rejected. int ngoodpix = npix; int last_ngoodpix; int minpix = ZSMAX(ZSMIN_NPIXELS, (int) (npix * ZSMAX_REJECT)); for (int niter=0; niter < maxiter; niter++) { last_ngoodpix = ngoodpix; // Subtract the fitted line from the data array zFlattenData(sampleData, flat, normx, npix, z0, dz); // Compute the k-sigma rejection threshold. In principle this // could be more efficiently computed using the matrix sums // accumulated when the line was fitted, but there are problems with // numerical stability with that approach. float mean; float sigma; ngoodpix = zComputeSigma (flat, badpix, npix, &mean, &sigma); float threshold = sigma * krej; // Detect and reject pixels further than ksigma from the fitted // line. ngoodpix = zRejectPixels(sampleData, flat, normx, badpix, npix, &sumxsqr, &sumxz, &sumx, &sumz, threshold, ngrow); // Solve for the coefficients of the fitted line. Note that after // pixel rejection the sum of the X values need no longer be zero. if (ngoodpix > 0) { double rowrat = sumx / sumxsqr; z0 = (sumz - rowrat * sumxz) / (ngoodpix - rowrat * sumx); dz = (sumxz - z0 * sumx) / sumxsqr; } if (ngoodpix >= last_ngoodpix || ngoodpix < minpix) break; } // Transform the line coefficients back to the X range [1:npix] *zstart = z0 - dz; *zslope = dz * xscale; delete [] flat; delete [] normx; delete [] badpix; return ngoodpix; } // flattenData -- Compute and subtract the fitted line from the data array, // returned the flattened data in FLAT. void FitsData::zFlattenData(float* sampleData, float* flat, float* x, int npix, float z0, float dz) { for (int i=0; i < npix; i++) flat[i] = sampleData[i] - (x[i] * dz + z0); } // computeSigma -- Compute the root mean square deviation from the // mean of a flattened array. Ignore rejected pixels. int FitsData::zComputeSigma(float* a, short* badpix, int npix, float* mean, float* sigma) { int ngoodpix = 0; double sum = 0.0; double sumsq = 0.0; // Accumulate sum and sum of squares for (int i=0; i < npix; i++) if (badpix[i] == GOOD_PIXEL) { float pixval = a[i]; ngoodpix = ngoodpix + 1; sum = sum + pixval; sumsq = sumsq + pixval * pixval; } // Compute mean and sigma switch (ngoodpix) { case 0: *mean = ZSINDEF; *sigma = ZSINDEF; break; case 1: *mean = sum; *sigma = ZSINDEF; break; default: *mean = sum / ngoodpix; double temp = sumsq / (ngoodpix-1) - (sum*sum) / (ngoodpix*(ngoodpix - 1)); if (temp < 0) // possible with roundoff error *sigma = 0.0; else *sigma = sqrt(temp); } return ngoodpix; } // rejectPixels -- Detect and reject pixels more than "threshold" greyscale // units from the fitted line. The residuals about the fitted line are given // by the "flat" array, while the raw data is in "data". Each time a pixel // is rejected subtract its contributions from the matrix sums and flag the // pixel as rejected. When a pixel is rejected reject its neighbors out to // a specified radius as well. This speeds up convergence considerably and // produces a more stringent rejection criteria which takes advantage of the // fact that bad pixels tend to be clumped. The number of pixels left in the // fit is returned as the function value. int FitsData::zRejectPixels(float* sampleData, float* flat, float *normx, short *badpix, int npix, double* sumxsqr, double* sumxz, double* sumx, double* sumz, float threshold, int ngrow) { int ngoodpix = npix; float lcut = -threshold; float hcut = threshold; for (int i=0; i < npix; i++) { if (badpix[i] == BAD_PIXEL) ngoodpix = ngoodpix - 1; else { float residual = flat[i]; if (residual < lcut || residual > hcut) { // Reject the pixel and its neighbors out to the growing // radius. We must be careful how we do this to avoid // directional effects. Do not turn off thresholding on // pixels in the forward direction; mark them for rejection // but do not reject until they have been thresholded. // If this is not done growing will not be symmetric. for (int j=ZSMAX(0,i-ngrow); j < ZSMIN(npix,i+ngrow); j++) { if (badpix[j] != BAD_PIXEL) { if (j <= i) { double x = normx[j]; double z = sampleData[j]; *sumxsqr = *sumxsqr - (x * x); *sumxz = *sumxz - z * x; *sumx = *sumx - x; *sumz = *sumz - z; badpix[j] = BAD_PIXEL; ngoodpix = ngoodpix - 1; } else badpix[j] = REJECT_PIXEL; } } } } } return ngoodpix; } template class FitsDatam<unsigned char>; template class FitsDatam<short>; template class FitsDatam<unsigned short>; template class FitsDatam<int>; template class FitsDatam<long long>; template class FitsDatam<float>; template class FitsDatam<double>; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fvcontour.h��������������������������������������������������������������������0000644�0001750�0001750�00000003154�11700666270�015524� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fvcontour_h__ #define __fvcontour_h__ #include "vector.h" #include "contour.h" #include "frscale.h" #include "inversescale.h" static char *methodName_[] = { "smooth", "block" }; class FVContour : public Contour { public: enum Method {SMOOTH, BLOCK}; private: enum {top, right, bottom, left, none}; Method method_; char* level_; int numLevel_; int smooth_; FrScale::ColorScaleType colorScaleType_; float expo_; float clipMode_; Vector limits_; InverseScale* scale; void unity(FitsImage*); void bin(FitsImage*); void nobin(FitsImage*); void convolve(FitsImage*, double*, double*, int); double* tophat(int); double* gaussian(int); int build(long xdim, long ydim, double *image, Matrix&); int trace(long xdim, long ydim, double cntr, long xCell, long yCell, int side, double** rows, char* useGrid, Matrix&); public: FVContour(Base*, FitsImage*, const char*, int, int, Method, int, int, const char*, FrScale::ColorScaleType, float, float, Vector, InverseScale*); ~FVContour(); void append(FitsImage*); void update(FitsImage*); int method() {return method_;} const char* methodName() {return methodName_[method_];} char* level() {return level_;} int numLevel() {return numLevel_;} int smooth() {return smooth_;} int colorScaleType() {return colorScaleType_;} float expo() {return expo_;} float clipMode() {return clipMode_;} Vector limits() {return limits_;} }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/contour.C����������������������������������������������������������������������0000644�0001750�0001750�00000012262�12000067147�015113� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "contour.h" #include "base.h" #include "context.h" Contour::Contour(Base* p, const char* c, int w, int d) : parent(p), lineWidth(w), dash(d) { colorName = dupstr(c); color = parent->getColor(colorName); previous_ = NULL; next_ = NULL; } Contour::Contour(Base* p, const char* c, int w, int d, const List<Vertex>& cont) : parent(p), lineWidth(w), dash(d) { contours_ = cont; colorName = dupstr(c); color = parent->getColor(colorName); previous_ = NULL; next_ = NULL; } Contour::~Contour() { if (colorName) delete [] colorName; } void Contour::render(Pixmap pmap, Coord::InternalSystem sys, int width, int height) { if (contours_.head()) { XSetForeground(parent->display, parent->contourGC, color); int ww = lineWidth>=1 ? lineWidth : 1; if (!dash) XSetLineAttributes(parent->display, parent->contourGC, ww, LineSolid, CapButt, JoinMiter); else { char dl[2]; #ifdef _WIN32 dl[0] = parent->dlist[0]/2; dl[1] = parent->dlist[1]/2; #else dl[0] = parent->dlist[0]; dl[1] = parent->dlist[1]; #endif XSetDashes(parent->display, parent->contourGC, 0, dl, 2); XSetLineAttributes(parent->display, parent->contourGC, ww, LineOnOffDash, CapButt, JoinMiter); } BBox bb = BBox(0, 0, width, height); Vector u1 = contours_.current()->vector; while (contours_.next()) { Vector u2 = contours_.current()->vector; if (u1[0] != DBL_MAX && u2[0] != DBL_MAX) { Vector v1 = parent->mapFromRef(u1,sys); Vector v2 = parent->mapFromRef(u2,sys); if (bb.isIn(v1) || bb.isIn(v2)) XDrawLine(parent->display, pmap, parent->contourGC, (int)v1[0], (int)v1[1], (int)v2[0], (int)v2[1]); } u1 = u2; } } } void Contour::ps(int mode) { if (contours_.head()) { { ostringstream str; switch ((Widget::PSColorSpace)mode) { case Widget::BW: case Widget::GRAY: psColorGray(parent->getXColor(colorName), str); str << " setgray"; break; case Widget::RGB: psColorRGB(parent->getXColor(colorName), str); str << " setrgbcolor"; break; case Widget::CMYK: psColorCMYK(parent->getXColor(colorName), str); str << " setcmykcolor"; break; } str << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } { ostringstream str; if (!dash) { str << lineWidth << " setlinewidth" << endl << "[] 0 setdash"; } else { str << lineWidth << " setlinewidth" << endl << '[' << parent->dlist[0] << ' ' << parent->dlist[1] << "] 0 setdash"; } str << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // output stroke paths do { Vector u = contours_.current()->vector; if (u[0] != DBL_MAX) { ostringstream str; Vector v = parent->mapFromRef(u,Coord::CANVAS); str << "newpath " << endl << v.TkCanvasPs(parent->canvas) << " moveto" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); while (contours_.next()) { Vector uu = contours_.current()->vector; if (uu[0] != DBL_MAX) { ostringstream str; Vector vv = parent->mapFromRef(uu,Coord::CANVAS); str << vv.TkCanvasPs(parent->canvas) << " lineto" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } else break; } Tcl_AppendResult(parent->interp, "stroke\n", NULL); } } while (contours_.next()); } } #ifdef _MACOSX void Contour::macosx() { if (contours_.head()) { // color, width, and dash macosxColor(parent->getXColor(colorName)); macosxWidth(lineWidth); if (dash) macosxDash(parent->dlist,2); else macosxDash(NULL,0); Vector u1 = contours_.current()->vector; while (contours_.next()) { Vector u2 = contours_.current()->vector; if (u1[0] != DBL_MAX && u2[0] != DBL_MAX) { Vector v1 = parent->mapFromRef(u1,Coord::CANVAS); Vector v2 = parent->mapFromRef(u2,Coord::CANVAS); macosxDrawLine(v1,v2); } u1 = u2; } } } #endif #ifdef _WIN32 void Contour::win32() { if (contours_.head()) { // color and width win32Color(parent->getXColor(colorName)); win32Width(lineWidth); if (dash) win32Dash(parent->dlist,2); else win32Dash(NULL,0); Vector u1 = contours_.current()->vector; while (contours_.next()) { Vector u2 = contours_.current()->vector; if (u1[0] != DBL_MAX && u2[0] != DBL_MAX) { Vector v1 = parent->mapFromRef(u1,Coord::CANVAS); Vector v2 = parent->mapFromRef(u2,Coord::CANVAS); win32DrawLine(v1,v2); } u1 = u2; } } } #endif void Contour::updateCoords(const Matrix& mx) { if (contours_.head()) do { Vector& v = contours_.current()->vector; if (v[0] != DBL_MAX) v *= mx; } while (contours_.next()); } void Contour::setLineWidth(int w) { lineWidth = w; } void Contour::setDash(int d) { dash = d; } void Contour::setColor(const char* clr) { if (colorName) delete [] colorName; colorName = dupstr(clr); color = parent->getColor(colorName); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametruecolor16.C�������������������������������������������������������������0000644�0001750�0001750�00000012635�11700666270�016636� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frametruecolor16.h" #include "colorscaletrue16.h" // Tk Canvas Widget Function Declarations int FrameTrueColor16CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameTrueColor16 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameTrueColor16Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameTrueColor16Type = { (char*)"frametruecolor16", // name sizeof(WidgetOptions), // item size FrameTrueColor16CreateProc, // configProc frameTrueColor16Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameTrueColor16_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameTrueColor16Type); return TCL_OK; } int FrameTrueColor16CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameTrueColor16* frame = new FrameTrueColor16(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameTrueColor16 Member Functions FrameTrueColor16::FrameTrueColor16(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameTrueColor(i,c,item), TrueColor16(visual) { configSpecs = frameTrueColor16Specs; // frame configure options } FrameTrueColor16::~FrameTrueColor16() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void FrameTrueColor16::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells) return; if (colorScale) delete colorScale; switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor16(colorCount, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual, byteorder_); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor16(indexCells, colorCells, colorCount, visual, byteorder_); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor16(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual, byteorder_); break; } } ���������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dbase.C������������������������������������������������������������������0000644�0001750�0001750�00000074103�12060211302�015566� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "frame3dbase.h" #include "fitsimage.h" #include "marker.h" #include "context.h" #include "ps.h" #include "sigbus.h" Frame3dBase::Frame3dBase(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Base(i, c, item) { zbufWidget_ = NULL; mkzbufWidget_ = NULL; zbufPanner_ = NULL; mkzbufPanner_ = NULL; zbufMagnifier_ = NULL; mkzbufMagnifier_ = NULL; zbufPS_ = NULL; mkzbufPS_ = NULL; zdepth_ =100000; zzoom_ =1; zscale_ =1; az_ =0; el_ =0; renderMethod_ = MIP; threedGC = NULL; border_ =0; borderColorName_ = dupstr("blue"); compass_ =0; compassColorName_ = dupstr("green"); highlite_ =1; highliteColorName_ = dupstr("cyan"); cropsl_ =0; imageToData3d = Translate3d(-.5, -.5, -.5); dataToImage3d = Translate3d( .5, .5, .5); } Frame3dBase::~Frame3dBase() { // just in case, cancelImage() should clean this up if (zbufWidget_) delete [] zbufWidget_; if (mkzbufWidget_) delete [] mkzbufWidget_; if (zbufPanner_) delete [] zbufPanner_; if (mkzbufPanner_) delete [] mkzbufPanner_; if (zbufMagnifier_) delete [] zbufMagnifier_; if (mkzbufMagnifier_) delete [] mkzbufMagnifier_; if (zbufPS_) delete [] zbufPS_; if (mkzbufPS_) delete [] mkzbufPS_; if (threedGC) XFreeGC(display, threedGC); if (borderColorName_) delete [] borderColorName_; if (compassColorName_) delete [] compassColorName_; if (highliteColorName_) delete [] highliteColorName_; } void Frame3dBase::calcBorder(Coord::InternalSystem sys, FrScale::ScanMode mode, Vector3d* vv, int* dd) { if (!keyContext->fits) return; FitsBound* params = keyContext->fits->getDataParams(mode); Vector3d llf(params->xmin,params->ymin,params->zmin); Vector3d lrf(params->xmax,params->ymin,params->zmin); Vector3d urf(params->xmax,params->ymax,params->zmin); Vector3d ulf(params->xmin,params->ymax,params->zmin); Vector3d llb(params->xmin,params->ymin,params->zmax); Vector3d lrb(params->xmax,params->ymin,params->zmax); Vector3d urb(params->xmax,params->ymax,params->zmax); Vector3d ulb(params->xmin,params->ymax,params->zmax); Matrix3d& mm = keyContext->fits->matrixFromData3d(sys); vv[0] = llf * mm; vv[1] = lrf * mm; vv[2] = urf * mm; vv[3] = ulf * mm; vv[4] = llb * mm; vv[5] = lrb * mm; vv[6] = urb * mm; vv[7] = ulb * mm; // init for dash for (int ii=0; ii<12; ii++) dd[ii] =1; // front { Vector3d aa = vv[1]-vv[0]; Vector3d cc = vv[3]-vv[0]; Vector3d ff = cross(aa,cc); for (int ii=0; ii<4; ii++) dd[ii] &= ff[2]>0; } // right { Vector3d aa = vv[5]-vv[1]; Vector3d cc = vv[2]-vv[1]; Vector3d ff = cross(aa,cc); int ww = ff[2]>0; dd[1] &= ww; dd[9] &= ww; dd[5] &= ww; dd[10] &= ww; } // top { Vector3d aa = vv[6]-vv[2]; Vector3d cc = vv[3]-vv[2]; Vector3d ff = cross(aa,cc); int ww = ff[2]>0; dd[2] &= ww; dd[10] &= ww; dd[6] &= ww; dd[11] &= ww; } // left { Vector3d aa = vv[7]-vv[3]; Vector3d cc = vv[0]-vv[3]; Vector3d ff = cross(aa,cc); int ww = ff[2]>0; dd[3] &= ww; dd[8] &= ww; dd[7] &= ww; dd[11] &= ww; } // bottom { Vector3d aa = vv[4]-vv[0]; Vector3d cc = vv[1]-vv[0]; Vector3d ff = cross(aa,cc); int ww = ff[2]>0; dd[0] &= ww; dd[9] &= ww; dd[4] &= ww; dd[8] &= ww; } // back { Vector3d aa = vv[4]-vv[5]; Vector3d cc = vv[6]-vv[5]; Vector3d ff = cross(aa,cc); for (int ii=4; ii<8; ii++) dd[ii] &= ff[2]>0; } } void Frame3dBase::calcHighlite(Coord::InternalSystem sys, Vector* vv, int* rr) { if (!keyContext->fits) return; FitsBound* params = keyContext->fits->getDataParams(keyContext->frScale.scanMode()); Vector ss(params->xmin,params->ymin); Vector tt(params->xmax,params->ymax); Vector ll = mapFromRef3d(ss,sys); Vector lr = mapFromRef3d(Vector(tt[0],ss[1]),sys); Vector ur = mapFromRef3d(tt,sys); Vector ul = mapFromRef3d(Vector(ss[0],tt[1]),sys); // context->slice() IMAGE (ranges 1-n) double sl = keyContext->slice(2)-.5; Vector3d ll1 = mapFromRef3d(ss,sys); Vector3d lr1 = mapFromRef3d(Vector(tt[0],ss[1]),sys); Vector3d ur1 = mapFromRef3d(tt,sys); Vector3d ul1 = mapFromRef3d(Vector3d(ss[0],tt[1]),sys); Vector3d ll0 = mapFromRef3d(ss,sys,sl-1); Vector3d lr0 = mapFromRef3d(Vector3d(tt[0],ss[1]),sys,sl-1); Vector3d ur0 = mapFromRef3d(tt,sys,sl-1); Vector3d ul0 = mapFromRef3d(Vector3d(ss[0],tt[1]),sys,sl-1); Vector3d aa1 = (ll0-ll1).normalize(); Vector3d aa2 = (lr0-lr1).normalize(); Vector3d aa3 = (ur0-ur1).normalize(); Vector3d aa4 = (ul0-ul1).normalize(); Vector3d bb1 = (lr1-ll1).normalize(); Vector3d bb2 = (ur1-lr1).normalize(); Vector3d bb3 = (ul1-ur1).normalize(); Vector3d bb4 = (ll1-ul1).normalize(); Vector3d cc1 = cross(bb1,aa1); Vector3d cc2 = cross(bb2,aa2); Vector3d cc3 = cross(bb3,aa3); Vector3d cc4 = cross(bb4,aa4); vv[0] = ll; vv[1] = lr; vv[2] = ur; vv[3] = ul; rr[0] = cc1[2]>0; rr[1] = cc2[2]>0; rr[2] = cc3[2]>0; rr[3] = cc4[2]>0; } double Frame3dBase::calcZoom3d(Vector3d src, Vector dest) { Vector3d cc = src/2.; Vector3d llf(0,0,0); Vector3d lrf(0,src[1],0); Vector3d urf(src[0],src[1],0); Vector3d ulf(src[0],0,0); Vector3d llb(0,0,src[2]); Vector3d lrb(0,src[1],src[2]); Vector3d urb(src[0],src[1],src[2]); Vector3d ulb(src[0],0,src[2]); Matrix3d mx = Translate3d(-cc) * RotateZ3d(-wcsRotation) * RotateZ3d(-rotation) * RotateY3d(az_) * RotateX3d(el_); BBox3d bb(llf*mx); bb.bound(lrf*mx); bb.bound(urf*mx); bb.bound(ulf*mx); bb.bound(llb*mx); bb.bound(lrb*mx); bb.bound(urb*mx); bb.bound(ulb*mx); Vector3d bs = bb.size(); double r0 = dest[0]/bs[0]; double r1 = dest[1]/bs[1]; return r0>r1 ? r1:r0; } double Frame3dBase::calcZoomPanner() { if (!keyContext->fits) return 1; if (!pannerPixmap) return 1; Vector3d src = imageSize3d(keyContext->frScale.datasec() ? FrScale::DATASEC : FrScale::IMGSEC) * Scale3d(1,zscale_); Vector dest(pannerWidth,pannerHeight); Vector3d cc = src/2.; Vector3d llf = Vector3d(0,0,0); Vector3d lrf = Vector3d(0,src[1],0); Vector3d urf = Vector3d(src[0],src[1],0); Vector3d ulf = Vector3d(src[0],0,0); Vector3d llb = Vector3d(0,0,src[2]); Vector3d lrb = Vector3d(0,src[1],src[2]); Vector3d urb = Vector3d(src[0],src[1],src[2]); Vector3d ulb = Vector3d(src[0],0,src[2]); BBox3d bb; // 0, 0 Matrix3d m0000 = Translate3d(-cc) * RotateY3d(degToRad(0)) * RotateX3d(degToRad(0)); bb.bound(llf*m0000); bb.bound(llf*m0000); bb.bound(lrf*m0000); bb.bound(urf*m0000); bb.bound(ulf*m0000); bb.bound(llb*m0000); bb.bound(lrb*m0000); bb.bound(urb*m0000); bb.bound(ulb*m0000); // 0, 90 Matrix3d m0090 = Translate3d(-cc) * RotateY3d(degToRad(90)) * RotateX3d(degToRad(0)); bb.bound(llf*m0090); bb.bound(llf*m0090); bb.bound(lrf*m0090); bb.bound(urf*m0090); bb.bound(ulf*m0090); bb.bound(llb*m0090); bb.bound(lrb*m0090); bb.bound(urb*m0090); bb.bound(ulb*m0090); // 90, 0 Matrix3d m9000 = Translate3d(-cc) * RotateY3d(degToRad(0)) * RotateX3d(-degToRad(90)); bb.bound(llf*m9000); bb.bound(llf*m9000); bb.bound(lrf*m9000); bb.bound(urf*m9000); bb.bound(ulf*m9000); bb.bound(llb*m9000); bb.bound(lrb*m9000); bb.bound(urb*m9000); bb.bound(ulb*m9000); // 45, 45 Matrix3d m4545 = Translate3d(-cc) * RotateY3d(degToRad(45)) * RotateX3d(-degToRad(45)); bb.bound(llf*m4545); bb.bound(llf*m4545); bb.bound(lrf*m4545); bb.bound(urf*m4545); bb.bound(ulf*m4545); bb.bound(llb*m4545); bb.bound(lrb*m4545); bb.bound(urb*m4545); bb.bound(ulb*m4545); // 45, 90 Matrix3d m4590 = Translate3d(-cc) * RotateY3d(degToRad(90)) * RotateX3d(-degToRad(45)); bb.bound(llf*m4590); bb.bound(lrf*m4590); bb.bound(urf*m4590); bb.bound(ulf*m4590); bb.bound(llb*m4590); bb.bound(lrb*m4590); bb.bound(urb*m4590); bb.bound(ulb*m4590); // 90, 45 Matrix3d m9045 = Translate3d(-cc) * RotateY3d(degToRad(45)) * RotateX3d(-degToRad(90)); bb.bound(llf*m9045); bb.bound(lrf*m9045); bb.bound(urf*m9045); bb.bound(ulf*m9045); bb.bound(llb*m9045); bb.bound(lrb*m9045); bb.bound(urb*m9045); bb.bound(ulb*m9045); Vector3d bs = bb.size(); double ll = bs[0] > bs[1] ? bs[0] : bs[1]; double mm = dest[0] > dest[1] ? dest[0] : dest[1]; return 1/ll*mm; } void Frame3dBase::centerImage() { Base::centerImage(); viewCursor_ = Vector(); if (keyContext->fits) { // imageCenter is in IMAGE coords Vector3d aa = imageCenter3d(keyContext->frScale.scanMode()); // always center to center of pixel, even for even sized image Vector3d bb = (aa*Translate3d(.5,.5,.5)).floor(); // vp_ is in REF coords vp_ = bb*imageToData3d; } else vp_ = Vector(); } Vector3d Frame3dBase::imageCenter3d(FrScale::ScanMode mode) { if (!keyContext->fits) return Vector3d(); // params is a BBOX in DATA coords 0-n FitsBound* pp = keyContext->fits->getDataParams(mode); // Note: imageCenter() is in IMAGE coords return Vector3d((pp->xmax-pp->xmin)/2.+pp->xmin, (pp->ymax-pp->ymin)/2.+pp->ymin, (pp->zmax-pp->zmin)/2.+pp->zmin) * dataToImage3d; } Vector3d Frame3dBase::imageSize3d(FrScale::ScanMode mode ) { if (!keyContext->fits) return Vector3d(); // params is a BBOX in DATA coords 0-n FitsBound* params = keyContext->fits->getDataParams(mode); // return in IMAGE coords and extends edge to edge return Vector3d(params->xmax-params->xmin, params->ymax-params->ymin, params->zmax-params->zmin); } void Frame3dBase::psColor(PSColorSpace mode, const char* color) { ostringstream str; switch (mode) { case BW: case GRAY: psColorGray(getXColor(color), str); str << " setgray"; break; case RGB: psColorRGB(getXColor(color), str); str << " setrgbcolor"; break; case CMYK: psColorCMYK(getXColor(color), str); str << " setcmykcolor"; break; } str << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::psLine(Vector& ss, Vector& tt, int dd) { ostringstream str; if (dd) str << '[' << dlist[0] << ' ' << dlist[1] << "] 0 setdash" << endl; else str << "[] 0 setdash" << endl; str << "newpath " << ss.TkCanvasPs(canvas) << " moveto" << endl << tt.TkCanvasPs(canvas) << " lineto stroke" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::psWidth(int dd) { ostringstream str; str << dd << " setlinewidth" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Frame3dBase::psGraphics(PSColorSpace mode) { if (!keyContext->fits) return; if (border_) psBorder(mode); if (compass_) psCompass(mode); if (highlite_) psHighlite(mode); } void Frame3dBase::psBorder(PSColorSpace mode) { Vector3d vv[8]; int dd[12]; calcBorder(Coord::WIDGET, keyContext->frScale.scanMode(), vv, dd); Vector uu[8]; for (int ii=0; ii<8; ii++) uu[ii] = Vector(vv[ii])*widgetToCanvas; psColor(mode, borderColorName_); psWidth(1); // front psLine(uu[0],uu[1],dd[0]); psLine(uu[1],uu[2],dd[1]); psLine(uu[2],uu[3],dd[2]); psLine(uu[3],uu[0],dd[3]); // back psLine(uu[4],uu[5],dd[4]); psLine(uu[5],uu[6],dd[5]); psLine(uu[6],uu[7],dd[6]); psLine(uu[7],uu[4],dd[7]); // other psLine(uu[0],uu[4],dd[8]); psLine(uu[1],uu[5],dd[9]); psLine(uu[2],uu[6],dd[10]); psLine(uu[3],uu[7],dd[11]); } void Frame3dBase::psCompass(PSColorSpace mode) { Matrix3d& mm = keyContext->fits->matrixFromData3d(Coord::WIDGET); double ss = 100./(zoom_[0]+zoom_[1]); Vector3d oo = vp_*mm; Vector3d xx = Vector3d(1,0,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d yy = Vector3d(0,1,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d zz = Vector3d(0,0,1) * Scale3d(ss) * Translate3d(vp_) * mm; Vector o = Vector(oo)*widgetToCanvas; Vector x = Vector(xx)*widgetToCanvas; Vector y = Vector(yy)*widgetToCanvas; Vector z = Vector(zz)*widgetToCanvas; psColor(mode, compassColorName_); psWidth(1); psLine(o,x,0); psLine(o,y,0); psLine(o,z,0); } void Frame3dBase::psHighlite(PSColorSpace mode) { Vector vv[4]; int rr[4]; calcHighlite(Coord::CANVAS,vv,rr); psColor(mode, highliteColorName_); psWidth(1); psLine(vv[0],vv[1],rr[0]); psLine(vv[1],vv[2],rr[1]); psLine(vv[2],vv[3],rr[2]); psLine(vv[3],vv[0],rr[4]); } Matrix3d Frame3dBase::psMatrix(float scale, int width, int height) { Matrix3d userToPS3d = Matrix3d(wcsOrientationMatrix) * Matrix3d(orientationMatrix) * RotateZ3d(-wcsRotation) * RotateZ3d(-rotation) * RotateY3d(az_) * RotateX3d(el_) * Translate3d(viewCursor_) * Scale3d(zoom_, zzoom_) * Scale3d(scale,1) * FlipY3d() * Translate3d(width/2., height/2., zdepth_/2.); return refToUser3d*userToPS3d; } void Frame3dBase::updateBin(const Matrix& mx) { centerImage(); Base::updateBin(mx); } void Frame3dBase::updateGCs() { Base::updateGCs(); // widget clip region BBox bbWidget = BBox(0, 0, options->width, options->height); Vector sizeWidget = bbWidget.size(); rectWidget[0].x = (int)bbWidget.ll[0]; rectWidget[0].y = (int)bbWidget.ll[1]; rectWidget[0].width = (int)sizeWidget[0]; rectWidget[0].height = (int)sizeWidget[1]; // window clip region BBox bbWindow = bbWidget * widgetToWindow; Vector sizeWindow = bbWindow.size(); rectWindow[0].x = (int)bbWindow.ll[0]; rectWindow[0].y = (int)bbWindow.ll[1]; rectWindow[0].width = (int)sizeWindow[0]; rectWindow[0].height = (int)sizeWindow[1]; // 3d highlite if (!threedGC) { threedGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetLineAttributes(display, threedGC, 1, LineSolid, CapButt, JoinMiter); } XSetClipRectangles(display, threedGC, 0, 0, rectWidget, 1, Unsorted); } void Frame3dBase::updateMatrices() { if (DebugPerf) cerr << "updateMatrices..." << endl; zzoom_ = (zoom_[0]+zoom_[1])/2.; if (zzoom_<1) zzoom_ = 1; // if othogonal, reset zzoom if ((teq(az_,0,.001) || teq(fabs(az_),M_PI_2,.001) || teq(fabs(az_),M_PI,.001)) && (teq(el_,0,.001) || teq(fabs(el_),M_PI_2,.001))) zzoom_ =1; // These are the basic tranformation matrices // Note: imageCenter() is in IMAGE coords refToUser3d = Translate3d(-vp_) * Scale3d(1,zscale_) * FlipY3d(); userToRef3d = refToUser3d.invert(); // userToWidget3d userToWidget3d = Matrix3d(wcsOrientationMatrix) * Matrix3d(orientationMatrix) * RotateZ3d(-wcsRotation) * RotateZ3d(-rotation) * RotateY3d(az_) * RotateX3d(el_) * Translate3d(viewCursor_) * Scale3d(zoom_, zzoom_) * // must be int to align with screen pixels Translate3d((int)(options->width/2.), (int)(options->height/2.), (int)(zdepth_/2.)); widgetToUser3d = userToWidget3d.invert(); // widgetToCanvas widgetToCanvas3d = Translate3d(originX, originY, 0); canvasToWidget3d = widgetToCanvas3d.invert(); // canvasToWindow short xx, yy; Tk_CanvasWindowCoords(canvas, 0, 0, &xx, &yy); canvasToWindow3d = Translate3d(xx, yy, 0); windowToCanvas3d = canvasToWindow3d.invert(); // These are derived Transformation Matrices refToWidget3d = refToUser3d * userToWidget3d; widgetToRef3d = refToWidget3d.invert(); refToCanvas3d = refToWidget3d * widgetToCanvas3d; canvasToRef3d = refToCanvas3d.invert(); refToWindow3d = refToCanvas3d * canvasToWindow3d; windowToRef3d = refToWindow3d.invert(); userToCanvas3d = userToWidget3d * widgetToCanvas3d; canvasToUser3d = userToCanvas3d.invert(); widgetToWindow3d = widgetToCanvas3d * canvasToWindow3d; windowToWidget3d = widgetToWindow3d.invert(); Base::updateMatrices(); // delete current zbuffer since matrices have changed cancelImage(); if (DebugPerf) cerr << "updateMatrices end" << endl; } void Frame3dBase::updateMagnifierMatrices() { // vv is in CANVAS coords Vector ww = magnifierCursor*canvasToRef; // refToUser3d Matrix3d refToUser3d = Translate3d(Vector3d(-ww,-vp_[2])) * FlipY3d(); // userToMagnifier userToMagnifier3d = Matrix3d(wcsOrientationMatrix) * Matrix3d(orientationMatrix) * RotateZ3d(-wcsRotation) * RotateZ3d(-rotation) * RotateY3d(az_) * RotateX3d(el_) * Translate3d(viewCursor_) * Scale3d(zoom_, zzoom_) * Scale3d(magnifierZoom_,magnifierZoom_) * Translate3d((int)(magnifierWidth/2.), (int)(magnifierHeight/2.), (int)(zdepth_/2.)); magnifierToUser3d = userToMagnifier3d.invert(); refToMagnifier3d = refToUser3d * userToMagnifier3d; magnifierToRef3d = refToMagnifier3d.invert(); magnifierToWidget3d = magnifierToRef3d * refToWidget3d; widgetToMagnifier3d = magnifierToWidget3d.invert(); Base::updateMagnifierMatrices(); } void Frame3dBase::updatePannerMatrices() { Vector3d center = imageCenter3d(FrScale::IMGSEC) * imageToData3d; // refToUser3d Matrix3d refToUser3d = Translate3d(-center) * Scale3d(1,zscale_) * FlipY3d(); // userToPanner3d double pz = calcZoomPanner(); double zz = zzoom_*pz; if (zz<1) zz =1; userToPanner3d = Matrix3d(wcsOrientationMatrix) * Matrix3d(orientationMatrix) * RotateZ3d(-wcsRotation) * RotateZ3d(-rotation) * RotateY3d(az_) * RotateX3d(el_) * Scale3d(pz, zz) * Translate3d((int)(pannerWidth/2.), (int)(pannerHeight/2.), (int)(zdepth_/2.)); pannerToUser3d = userToPanner3d.invert(); refToPanner3d = refToUser3d * userToPanner3d; pannerToRef3d = refToPanner3d.invert(); pannerToWidget3d = pannerToRef3d * refToWidget3d; widgetToPanner3d = pannerToWidget3d.invert(); Base::updatePannerMatrices(); } void Frame3dBase::updatePanner() { // do this first Base::updatePanner(); // always render (to update panner background color) if (usePanner) { if (keyContext->fits) { XSetForeground(display, pannerGC, getColor("black")); x11Border(Coord::PANNER,FrScale::IMGSEC,pannerGC,pannerPixmap); } ostringstream str; str << pannerName << " update " << (void*)pannerPixmap << ";"; // calculate bbox Vector ll = Vector(0,0) * widgetToPanner3d; Vector lr = Vector(options->width,0) * widgetToPanner3d; Vector ur = Vector(options->width,options->height) * widgetToPanner3d; Vector ul = Vector(0,options->height) * widgetToPanner3d; str << pannerName << " update bbox " << ll << lr << ur << ul << ";"; // calculate image compass vectors Matrix3d mm = Matrix3d(wcsOrientationMatrix) * Matrix3d(orientationMatrix) * RotateZ3d(wcsRotation) * RotateZ3d(rotation) * RotateY3d(az_) * RotateX3d(-el_) * FlipY3d(); Vector xx = (Vector3d(1,0,0)*mm).normalize(); Vector yy = (Vector3d(0,1,0)*mm).normalize(); Vector zz = (Vector3d(0,0,1)*mm).normalize(); str << pannerName << " update image compass " << xx << yy << zz << ";"; if (keyContext->fits && keyContext->fits->hasWCS(wcsSystem_)) { Vector orpix = keyContext->fits->center(); Vector orval=keyContext->fits->pix2wcs(orpix, wcsSystem_, wcsSky_); Vector orpix2 = keyContext->fits->wcs2pix(orval, wcsSystem_,wcsSky_); Vector delta = keyContext->fits->getWCScdelt(wcsSystem_).abs(); // find normalized north Vector npix = keyContext->fits->wcs2pix(Vector(orval[0],orval[1]+delta[1]), wcsSystem_,wcsSky_); Vector north = (Vector3d(npix-orpix2)*mm).normalize(); // find normalized east Vector epix = keyContext->fits->wcs2pix(Vector(orval[0]+delta[0],orval[1]), wcsSystem_,wcsSky_); Vector east = (Vector3d(epix-orpix2)*mm).normalize(); // sanity check Vector diff = (north-east).abs(); if ((north[0]==0 && north[1]==0) || (east[0]==0 && east[1]==0) || (diff[0]<.01 && diff[1]<.01)) { north = (Vector3d(0,1)*mm).normalize(); east = (Vector3d(-1,0)*mm).normalize(); } // and update the panner str << pannerName << " update wcs compass " << north << east << ends; } else str << pannerName << " update wcs compass invalid" << ends; Tcl_Eval(interp, str.str().c_str()); } } void Frame3dBase::x11Graphics() { Base::x11Graphics(); if (!keyContext->fits) return; if (border_) { XSetForeground(display, threedGC, getColor(borderColorName_)); x11Border(Coord::WIDGET, keyContext->frScale.scanMode(), threedGC, pixmap); } if (compass_) x11Compass(); if (highlite_) x11Highlite(); } void Frame3dBase::x11Line(Vector ss, Vector tt, int dd, GC gc, Pixmap pm) { x11Dash(gc, dd); XDrawLine(display, pm, gc, ss[0], ss[1], tt[0], tt[1]); } void Frame3dBase::x11Border(Coord::InternalSystem sys, FrScale::ScanMode mode, GC gc, Pixmap pm) { Vector3d vv[8]; int dd[12]; calcBorder(sys, mode, vv, dd); // front x11Line(vv[0], vv[1], dd[0], gc, pm); x11Line(vv[1], vv[2], dd[1], gc, pm); x11Line(vv[2], vv[3], dd[2], gc, pm); x11Line(vv[3], vv[0], dd[3], gc, pm); // back x11Line(vv[4], vv[5], dd[4], gc, pm); x11Line(vv[5], vv[6], dd[5], gc, pm); x11Line(vv[6], vv[7], dd[6], gc, pm); x11Line(vv[7], vv[4], dd[7], gc, pm); // other x11Line(vv[0], vv[4], dd[8], gc, pm); x11Line(vv[1], vv[5], dd[9], gc, pm); x11Line(vv[2], vv[6], dd[10], gc, pm); x11Line(vv[3], vv[7], dd[11], gc, pm); } void Frame3dBase::x11Compass() { Matrix3d& mm = keyContext->fits->matrixFromData3d(Coord::WIDGET); double ss = 100./(zoom_[0]+zoom_[1]); Vector3d oo = vp_*mm; Vector3d xx = Vector3d(1,0,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d yy = Vector3d(0,1,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d zz = Vector3d(0,0,1) * Scale3d(ss) * Translate3d(vp_) * mm; x11Dash(threedGC, 0); XSetForeground(display, threedGC, getColor(compassColorName_)); XDrawLine(display, pixmap, threedGC, oo[0], oo[1], xx[0], xx[1]); XDrawLine(display, pixmap, threedGC, oo[0], oo[1], yy[0], yy[1]); XDrawLine(display, pixmap, threedGC, oo[0], oo[1], zz[0], zz[1]); } /* void Frame3dBase::renderArm(int length, Vector center, Rotate rot, const char* str, int color) { if (!tkfont_) { ostringstream fstr; fstr << '{' << options->helvetica << '}' << " 9 roman normal" << ends; tkfont_ = Tk_GetFont(interp, tkwin, fstr.str().c_str()); if (tkfont_) Tk_GetFontMetrics(tkfont_, &metric); } if (!compassGC) { compassGC = XCreateGC(display, pixmap, 0, NULL); XSetLineAttributes(display, compassGC, 1, LineSolid, CapButt, JoinMiter); if (tkfont_) XSetFont(display, compassGC, Tk_FontId(tkfont_)); } if (length<=0) return; // set GC XSetForeground(display, compassGC, color); const int textOffset = 15; // Text offset const int tip = 6; // length from end of line to tip of arrow const int tail = 2; // length from end of line to tails of arrow const int wc = 2; // width of arrow at end of line const int wt = 3; // width of arrow at tails // Arrow-- oriented on Y axis Vector arrow[6]; arrow[0] = Vector(0, tip); arrow[1] = Vector(-wc, 0); arrow[2] = Vector(-wt, -tail); arrow[3] = Vector(0, 0); arrow[4] = Vector(wt, -tail); arrow[5] = Vector(wc, 0); // Staff-- oriented on X axis XPoint arrowArray[6]; Matrix arrowMatrix = Rotate(M_PI_2) * Translate(length,0) * rot * Translate(center); for (int i=0; i<6; i++) { Vector r = (arrow[i] * arrowMatrix).round(); arrowArray[i].x = (int)r[0]; arrowArray[i].y = (int)r[1]; } Vector c = ((Vector&)center).round(); Vector end = (Vector(length, 0) * rot * Translate(center)).round(); XDrawLine(display, pixmap, compassGC, (int)c[0], (int)c[1], (int)end[0], (int)end[1]); XFillPolygon(display, pixmap, compassGC, arrowArray, 6, Nonconvex, CoordModeOrigin); if (useFont && tkfont_) { Vector et = Vector((length + textOffset), 0) * rot * Translate(center) * Translate(-Tk_TextWidth(tkfont_, str, 1)/2., metric.ascent/2.); Tk_DrawChars(display, pixmap, compassGC, tkfont_, str, 1, (int)et[0], (int)et[1]); } } */ void Frame3dBase::x11Highlite() { Vector vv[4]; int rr[4]; calcHighlite(Coord::WIDGET,vv,rr); XSetForeground(display, threedGC, getColor(highliteColorName_)); x11Line(vv[0], vv[1], rr[0], threedGC, pixmap); x11Line(vv[1], vv[2], rr[1], threedGC, pixmap); x11Line(vv[2], vv[3], rr[2], threedGC, pixmap); x11Line(vv[3], vv[0], rr[3], threedGC, pixmap); } void Frame3dBase::ximageToPixmapMagnifier() { if (!basePixmap || !baseXImage || !magnifierPixmap || !magnifierXImage) return; // magnifier int& ww = magnifierXImage->width; int& hh = magnifierXImage->height; Vector wh(ww,hh); Vector cc = magnifierCursor * canvasToWidget; Vector ll =cc-wh/2.; Vector ur =cc+wh/2.; // clip to base BBox bb(0,0,baseXImage->width,baseXImage->height); Vector uu(ll); Vector vv(ur); uu.clip(bb); vv.clip(bb); Vector zz = vv-uu; Vector oo = uu-ll; // sanity check if (zz[0]<=0 || zz[1]<=0) return; XImage* srcXImage = XGetImage(display, basePixmap, uu[0], uu[1], zz[0], zz[1], AllPlanes, ZPixmap); char* src = XImageData(srcXImage); int srcBytesPerLine = srcXImage->bytes_per_line; char* dst = XImageData(magnifierXImage); int dstBytesPerLine = magnifierXImage->bytes_per_line; int bytesPerPixel = magnifierXImage->bits_per_pixel/8; Matrix mx = Translate(-wh/2.) * Translate(oo) * Translate(-.5,-.5) * Scale(magnifierZoom_) * Translate(wh/2.); Matrix mm = mx.invert(); for (int jj=0; jj<hh; jj++) { char* dest = dst + jj*dstBytesPerLine; for (int ii=0; ii<ww; ii++, dest+=bytesPerPixel) { Vector vv = Vector(ii,jj)*mm; if (vv[0] >= 0 && vv[0] < zz[0] && vv[1] >= 0 && vv[1] < zz[1]) memcpy(dest, src + ((int)vv[1])*srcBytesPerLine + ((int)vv[0])*bytesPerPixel, bytesPerPixel); else memcpy(dest, bgTrueColor_, bytesPerPixel); } } XPutImage(display, magnifierPixmap, gc, magnifierXImage, 0, 0, 0, 0, magnifierXImage->width, magnifierXImage->height); if (srcXImage) XDestroyImage(srcXImage); } #ifdef _MACOSX void Frame3dBase::macosxLine(Vector& ss, Vector& tt, int dd) { if (dd) macosxDash(dlist,2); else macosxDash(NULL,0); macosxDrawLine(ss,tt); } void Frame3dBase::macosxGraphics() { if (!keyContext->fits) return; if (border_) macosxBorder(); if (compass_) macosxCompass(); if (highlite_) macosxHighlite(); } void Frame3dBase::macosxBorder() { Vector3d vv[8]; int dd[12]; calcBorder(Coord::WIDGET, keyContext->frScale.scanMode(), vv, dd); Vector uu[8]; for (int ii=0; ii<8; ii++) uu[ii] = Vector(vv[ii])*widgetToCanvas; macosxColor(getXColor(borderColorName_)); macosxWidth(1); // front macosxLine(uu[0],uu[1],dd[0]); macosxLine(uu[1],uu[2],dd[1]); macosxLine(uu[2],uu[3],dd[2]); macosxLine(uu[3],uu[0],dd[3]); // back macosxLine(uu[4],uu[5],dd[4]); macosxLine(uu[5],uu[6],dd[5]); macosxLine(uu[6],uu[7],dd[6]); macosxLine(uu[7],uu[4],dd[7]); // other macosxLine(uu[0],uu[4],dd[8]); macosxLine(uu[1],uu[5],dd[9]); macosxLine(uu[2],uu[6],dd[10]); macosxLine(uu[3],uu[7],dd[11]); } void Frame3dBase::macosxCompass() { Matrix3d& mm = keyContext->fits->matrixFromData3d(Coord::WIDGET); double ss = 100./(zoom_[0]+zoom_[1]); Vector3d oo = vp_*mm; Vector3d xx = Vector3d(1,0,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d yy = Vector3d(0,1,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d zz = Vector3d(0,0,1) * Scale3d(ss) * Translate3d(vp_) * mm; Vector o = Vector(oo)*widgetToCanvas; Vector x = Vector(xx)*widgetToCanvas; Vector y = Vector(yy)*widgetToCanvas; Vector z = Vector(zz)*widgetToCanvas; macosxColor(getXColor(compassColorName_)); macosxWidth(1); macosxLine(o,x,0); macosxLine(o,y,0); macosxLine(o,z,0); } void Frame3dBase::macosxHighlite() { Vector vv[4]; int rr[4]; calcHighlite(CANVAS,vv,rr); macosxColor(getXColor(highliteColorName_)); macosxWidth(1); macosxLine(vv[0],vv[1],rr[0]); macosxLine(vv[1],vv[2],rr[1]); macosxLine(vv[2],vv[3],rr[2]); macosxLine(vv[3],vv[0],rr[3]); } #endif #ifdef _WIN32 void Frame3dBase::win32Line(Vector& ss, Vector& tt, int dd) { if (dd) win32Dash(dlist,2); else win32Dash(NULL,0); win32DrawLine(ss,tt); } void Frame3dBase::win32Graphics() { if (!keyContext->fits) return; if (border_) win32Border(); if (compass_) win32Compass(); if (highlite_) win32Highlite(); } void Frame3dBase::win32Border() { Vector3d vv[8]; int dd[12]; calcBorder(Coord::WIDGET, keyContext->frScale.scanMode(), vv, dd); Vector uu[8]; for (int ii=0; ii<8; ii++) uu[ii] = Vector(vv[ii])*widgetToCanvas; win32Color(getXColor(borderColorName_)); win32Width(1); // front win32Line(uu[0],uu[1],dd[0]); win32Line(uu[1],uu[2],dd[1]); win32Line(uu[2],uu[3],dd[2]); win32Line(uu[3],uu[0],dd[3]); // back win32Line(uu[4],uu[5],dd[4]); win32Line(uu[5],uu[6],dd[5]); win32Line(uu[6],uu[7],dd[6]); win32Line(uu[7],uu[4],dd[7]); // other win32Line(uu[0],uu[4],dd[8]); win32Line(uu[1],uu[5],dd[9]); win32Line(uu[2],uu[6],dd[10]); win32Line(uu[3],uu[7],dd[11]); } void Frame3dBase::win32Compass() { Matrix3d& mm = keyContext->fits->matrixFromData3d(Coord::WIDGET); double ss = 100./(zoom_[0]+zoom_[1]); Vector3d oo = vp_*mm; Vector3d xx = Vector3d(1,0,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d yy = Vector3d(0,1,0) * Scale3d(ss) * Translate3d(vp_) * mm; Vector3d zz = Vector3d(0,0,1) * Scale3d(ss) * Translate3d(vp_) * mm; Vector o = Vector(oo)*widgetToCanvas; Vector x = Vector(xx)*widgetToCanvas; Vector y = Vector(yy)*widgetToCanvas; Vector z = Vector(zz)*widgetToCanvas; win32Color(getXColor(compassColorName_)); win32Width(1); win32Line(o,x,0); win32Line(o,y,0); win32Line(o,z,0); } void Frame3dBase::win32Highlite() { Vector vv[4]; int rr[4]; calcHighlite(Coord::CANVAS,vv,rr); win32Color(getXColor(highliteColorName_)); win32Width(1); win32Line(vv[0],vv[1],rr[0]); win32Line(vv[1],vv[2],rr[1]); win32Line(vv[2],vv[3],rr[2]); win32Line(vv[3],vv[0],rr[3]); } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/inversescale.C�����������������������������������������������������������������0000644�0001750�0001750�00000006713�12107012362�016106� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "inversescale.h" #include "framebase.h" InverseScale::InverseScale(int ss) : size_(ss) { level_ = new double[size_]; for (int ii=0; ii<size_; ii++) level_[ii] = 0; } InverseScale::InverseScale(int ss, double* ll) : size_(ss) { level_ = new double[size_]; for (int ii=0; ii<size_; ii++) level_[ii] = ll[ii]; } InverseScale::~InverseScale() { if (level_) delete [] level_; } ostream& operator<<(ostream& s, const InverseScale& c) { for (int ii=0; ii<c.size_; ii++) if (isfinite(c.level_[ii])) s << c.level_[ii] << ' '; else s << 0 << ' '; return s; } // Note: this an inverse algorithm. We have y, we need x LinearInverseScale::LinearInverseScale(int ss, double low, double high) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = double(ii)/(size_-1); level_[ii] = aa*dd +low; } } LogInverseScale::LogInverseScale(int ss, double low, double high, double exp) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = (::pow(exp,double(ii)/(size_-1)) -1) / exp; level_[ii] = aa*dd +low; } } PowInverseScale::PowInverseScale(int ss, double low, double high, double exp) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = log10(exp*double(ii)/(size_-1) +1) / log10(exp); level_[ii] = aa*dd +low; } } SqrtInverseScale::SqrtInverseScale(int ss, double low, double high) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = double(ii)/(size_-1); level_[ii] = (aa*aa)*dd +low; } } SquaredInverseScale::SquaredInverseScale(int ss, double low, double high) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = sqrt(double(ii)/(size_-1)); level_[ii] = aa*dd +low; } } AsinhInverseScale::AsinhInverseScale(int ss, double low, double high) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = sinh(3*double(ii)/(size_-1))/10; level_[ii] = aa*dd +low; } } SinhInverseScale::SinhInverseScale(int ss, double low, double high) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; for (int ii=0; ii<size_; ii++) { double aa = asinh(10*double(ii)/(size_-1))/3; level_[ii] = aa*dd +low; } } HistEquInverseScale::HistEquInverseScale(int ss, double low, double high, double* hist, int histsize) : InverseScale(ss) { if (size_==1) { level_[0] = high; return; } double dd = high-low; if (!hist) { for (int ii=0; ii<size_; ii++) { double aa = double(ii)/(size_-1); level_[ii] = aa*dd +low; } } else { for (int ii=0; ii<size_; ii++) { double vv = double(ii)/(size_-1); int jj=0; while (jj<histsize-1) { if (hist[jj]>vv) break; jj++; } double aa = double(jj)/histsize; level_[ii] = aa*dd +low; } } } �����������������������������������������������������./saods9/saotk/frame/tngparser.C��������������������������������������������������������������������0000644�0001750�0001750�00000173626�11727715200�015450� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse tngparse #define yylex tnglex #define yyerror tngerror #define yylval tnglval #define yychar tngchar #define yydebug tngdebug #define yynerrs tngnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, SEXSTR = 262, EOF_ = 263, B1950_ = 264, BACKGROUND_ = 265, BOX_ = 266, BLACK_ = 267, BLUE_ = 268, CIRCLE_ = 269, CYAN_ = 270, DATE_ = 271, DEBUG_ = 272, DEGREES_ = 273, ECLIPTIC_ = 274, ELLIPSE_ = 275, FILENAME_ = 276, FK4_ = 277, FK4_NO_E_ = 278, FK5_ = 279, FORMAT_ = 280, GALACTIC_ = 281, GREEN_ = 282, HELIOECLIPTIC_ = 283, HMS_ = 284, ICRS_ = 285, J2000_ = 286, LINE_ = 287, MAGENTA_ = 288, OFF_ = 289, ON_ = 290, PHYSICAL_ = 291, PIXELS_ = 292, POINT_ = 293, POLYGON_ = 294, RED_ = 295, SOURCE_ = 296, SUPERGALACTIC_ = 297, TEXT_ = 298, VERSION_ = 299, WHITE_ = 300, YELLOW_ = 301 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define SEXSTR 262 #define EOF_ 263 #define B1950_ 264 #define BACKGROUND_ 265 #define BOX_ 266 #define BLACK_ 267 #define BLUE_ 268 #define CIRCLE_ 269 #define CYAN_ 270 #define DATE_ 271 #define DEBUG_ 272 #define DEGREES_ 273 #define ECLIPTIC_ 274 #define ELLIPSE_ 275 #define FILENAME_ 276 #define FK4_ 277 #define FK4_NO_E_ 278 #define FK5_ 279 #define FORMAT_ 280 #define GALACTIC_ 281 #define GREEN_ 282 #define HELIOECLIPTIC_ 283 #define HMS_ 284 #define ICRS_ 285 #define J2000_ 286 #define LINE_ 287 #define MAGENTA_ 288 #define OFF_ 289 #define ON_ 290 #define PHYSICAL_ 291 #define PIXELS_ 292 #define POINT_ 293 #define POLYGON_ 294 #define RED_ 295 #define SOURCE_ 296 #define SUPERGALACTIC_ 297 #define TEXT_ 298 #define VERSION_ 299 #define WHITE_ 300 #define YELLOW_ 301 /* Copy the first part of user declarations. */ #line 10 "tngparser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; tngDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer tngFlexLexer #include <FlexLexer.h> extern int tnglex(void*, tngFlexLexer*); extern void tngerror(Base*, tngFlexLexer*, const char*); extern void tngDiscard(int); static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static unsigned short globalProps; static unsigned short localProps; static char globalColor[16]; static char localColor[16]; static int dash[] = {8,3}; static char globalFont[32]; static char globalText[80]; static char localText[80]; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 61 "tngparser.Y" { #define TNGBUFSIZE 2048 double real; int integer; char str[TNGBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 255 "tngparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 268 "tngparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 155 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 56 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 33 /* YYNRULES -- Number of rules. */ #define YYNRULES 85 /* YYNRULES -- Number of states. */ #define YYNSTATES 148 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 301 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 54, 2, 2, 2, 2, 50, 51, 2, 52, 49, 53, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 6, 10, 13, 14, 17, 19, 23, 25, 27, 29, 31, 33, 35, 37, 39, 40, 42, 43, 45, 46, 48, 49, 51, 53, 55, 57, 61, 63, 67, 71, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 96, 97, 98, 100, 102, 110, 120, 130, 138, 144, 145, 154, 155, 162, 166, 168, 170, 175, 176, 182, 183, 189, 190, 194, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 226, 230, 233, 236, 238, 243, 244 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 57, 0, -1, 73, 58, -1, 58, 59, 60, -1, 59, 60, -1, -1, 17, 62, -1, 44, -1, 74, 75, 76, -1, 81, -1, 47, -1, 48, -1, 8, -1, 4, -1, 3, -1, 35, -1, 34, -1, -1, 49, -1, -1, 50, -1, -1, 51, -1, -1, 67, -1, 61, -1, 6, -1, 61, -1, 61, 63, 61, -1, 7, -1, 70, 63, 70, -1, 61, 63, 61, -1, 6, 63, 6, -1, 22, -1, 9, -1, 23, -1, 24, -1, 31, -1, 30, -1, 26, -1, 42, -1, 19, -1, 28, -1, -1, -1, -1, 52, -1, 53, -1, 14, 64, 71, 63, 68, 65, 85, -1, 20, 64, 71, 63, 69, 63, 66, 65, 85, -1, 11, 64, 71, 63, 69, 63, 66, 65, 85, -1, 32, 64, 71, 63, 71, 65, 85, -1, 38, 64, 71, 65, 85, -1, -1, 43, 64, 71, 63, 5, 65, 77, 85, -1, -1, 39, 78, 64, 79, 65, 85, -1, 79, 63, 80, -1, 80, -1, 71, -1, 54, 25, 55, 87, -1, -1, 54, 21, 55, 82, 5, -1, -1, 54, 16, 55, 83, 5, -1, -1, 54, 84, 5, -1, -1, 54, 45, -1, 54, 12, -1, 54, 40, -1, 54, 27, -1, 54, 13, -1, 54, 15, -1, 54, 33, -1, 54, 46, -1, 54, 41, -1, 54, 10, -1, -1, 54, 86, 5, -1, 29, 88, -1, 18, 88, -1, 37, -1, 37, 50, 36, 51, -1, -1, 50, 72, 51, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 130, 130, 133, 134, 137, 138, 139, 140, 141, 144, 145, 146, 149, 150, 153, 154, 157, 158, 161, 162, 165, 166, 169, 170, 173, 174, 177, 180, 189, 192, 206, 213, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 235, 249, 265, 266, 267, 270, 276, 283, 290, 297, 302, 302, 308, 308, 314, 315, 318, 321, 322, 322, 323, 323, 324, 324, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 341, 346, 346, 349, 350, 351, 352, 356, 360 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "STRING", "ANGDEGREE", "SEXSTR", "EOF_", "B1950_", "BACKGROUND_", "BOX_", "BLACK_", "BLUE_", "CIRCLE_", "CYAN_", "DATE_", "DEBUG_", "DEGREES_", "ECLIPTIC_", "ELLIPSE_", "FILENAME_", "FK4_", "FK4_NO_E_", "FK5_", "FORMAT_", "GALACTIC_", "GREEN_", "HELIOECLIPTIC_", "HMS_", "ICRS_", "J2000_", "LINE_", "MAGENTA_", "OFF_", "ON_", "PHYSICAL_", "PIXELS_", "POINT_", "POLYGON_", "RED_", "SOURCE_", "SUPERGALACTIC_", "TEXT_", "VERSION_", "WHITE_", "YELLOW_", "'\\n'", "';'", "','", "'('", "')'", "'+'", "'-'", "'#'", "':'", "$accept", "start", "commands", "command", "terminator", "numeric", "debug", "sp", "bp", "ep", "optangle", "angle", "value", "vvalue", "sexagesimal", "coord", "skyFrame", "initGlobal", "initLocal", "include", "shape", "@1", "@2", "polyNodes", "polyNode", "generalComment", "@3", "@4", "@5", "shapeComment", "@6", "tngFormat", "tngWCS", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 10, 59, 44, 40, 41, 43, 45, 35, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 56, 57, 58, 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 69, 70, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 74, 75, 75, 75, 76, 76, 76, 76, 76, 77, 76, 78, 76, 79, 79, 80, 81, 82, 81, 83, 81, 84, 81, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 87, 87, 87, 87, 88, 88 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 3, 2, 0, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 7, 9, 9, 7, 5, 0, 8, 0, 6, 3, 1, 1, 4, 0, 5, 0, 5, 0, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 3, 2, 2, 1, 4, 0, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 43, 0, 44, 1, 0, 7, 65, 44, 0, 45, 9, 16, 15, 6, 0, 0, 0, 0, 0, 12, 10, 11, 4, 46, 47, 0, 63, 61, 0, 66, 3, 19, 19, 19, 19, 19, 55, 19, 8, 0, 0, 84, 84, 82, 60, 20, 0, 0, 0, 0, 0, 19, 0, 64, 62, 0, 81, 80, 0, 14, 13, 17, 29, 17, 17, 17, 17, 17, 17, 21, 0, 17, 34, 41, 33, 35, 36, 39, 42, 38, 37, 40, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 22, 67, 59, 17, 58, 0, 85, 83, 32, 31, 30, 17, 17, 27, 21, 17, 21, 78, 52, 0, 67, 21, 0, 23, 67, 23, 67, 77, 69, 72, 73, 71, 74, 70, 76, 68, 75, 0, 57, 56, 53, 28, 26, 25, 21, 24, 48, 21, 51, 79, 67, 67, 67, 54, 50, 49 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 7, 8, 22, 63, 13, 85, 46, 93, 136, 137, 106, 104, 64, 94, 82, 2, 9, 25, 38, 142, 51, 95, 96, 10, 40, 39, 17, 110, 129, 44, 56 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -108 static const yytype_int8 yypact[] = { -108, 2, -5, -108, -21, -108, 67, 0, -7, -46, -108, -108, -108, -108, -45, -30, -17, 40, -7, -108, -108, -108, -108, -108, -108, 105, -108, -108, -14, -108, -108, -4, -4, -4, -4, -4, -108, -4, -108, 45, 46, 3, 3, 11, -108, -108, 127, 127, 127, 127, 127, -4, 127, -108, -108, 87, -108, -108, 16, -108, -108, 15, -108, 15, 15, 15, 15, 15, 15, 14, 127, 15, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 17, 18, -108, 70, 29, 78, 29, 29, 29, 127, -108, 32, -108, 8, -108, 82, -108, -108, -108, -108, -108, 15, 15, -108, 14, 15, 14, 62, -108, 127, 32, 14, 29, 117, 32, 117, 32, -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, 85, -108, -108, -108, -108, -108, -108, 14, -108, -108, 14, -108, -108, 32, 32, 32, -108, -108, -108 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -108, -108, -108, 84, 75, 38, -108, -37, 47, -35, -23, -108, -108, 7, 12, -28, -108, -108, -108, -108, -108, -108, -108, -108, -11, -108, -108, -108, -108, -107, -108, -108, 63 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -22 static const yytype_int16 yytable[] = { -2, 19, 3, -5, 41, 131, 23, 24, -5, 138, 26, 140, 4, 11, 12, 42, -21, 4, 65, 66, 67, 68, 69, 43, 71, 27, 86, 87, 88, 89, 90, 91, 59, 60, 97, 145, 146, 147, 28, 5, 20, 21, -5, -5, 5, 29, 45, -5, -5, 6, 53, 54, 83, 55, 6, -21, -21, 84, 111, 92, 112, 58, -21, 108, 84, 92, 114, 115, 98, 99, 117, 116, 119, 118, 120, 121, 100, 122, 132, 47, 48, 49, 50, 14, 52, 62, 109, 113, 15, 123, 141, 18, 16, 30, 139, 124, 72, 107, 70, 102, 130, 143, 125, 126, 144, 57, 73, 127, 128, 74, 75, 76, 0, 77, 0, 78, 31, 79, 80, 32, 59, 60, 0, 134, 101, 33, 103, 105, 103, 81, 59, 60, 0, 61, 62, 0, 0, 34, 0, 0, 0, 0, 0, 35, 36, 0, 0, 0, 37, 0, 0, 0, 133, 135, 0, 135 }; static const yytype_int16 yycheck[] = { 0, 8, 0, 8, 18, 112, 52, 53, 8, 116, 55, 118, 17, 34, 35, 29, 8, 17, 46, 47, 48, 49, 50, 37, 52, 55, 63, 64, 65, 66, 67, 68, 3, 4, 71, 142, 143, 144, 55, 44, 47, 48, 47, 48, 44, 5, 50, 47, 48, 54, 5, 5, 36, 50, 54, 47, 48, 49, 95, 51, 95, 50, 54, 91, 49, 51, 103, 104, 51, 51, 107, 106, 10, 108, 12, 13, 6, 15, 113, 32, 33, 34, 35, 16, 37, 7, 54, 5, 21, 27, 5, 7, 25, 18, 117, 33, 9, 90, 51, 87, 111, 136, 40, 41, 139, 42, 19, 45, 46, 22, 23, 24, -1, 26, -1, 28, 11, 30, 31, 14, 3, 4, -1, 6, 86, 20, 88, 89, 90, 42, 3, 4, -1, 6, 7, -1, -1, 32, -1, -1, -1, -1, -1, 38, 39, -1, -1, -1, 43, -1, -1, -1, 114, 115, -1, 117 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 57, 73, 0, 17, 44, 54, 58, 59, 74, 81, 34, 35, 62, 16, 21, 25, 84, 59, 8, 47, 48, 60, 52, 53, 75, 55, 55, 55, 5, 60, 11, 14, 20, 32, 38, 39, 43, 76, 83, 82, 18, 29, 37, 87, 50, 64, 64, 64, 64, 64, 78, 64, 5, 5, 50, 88, 88, 50, 3, 4, 6, 7, 61, 70, 71, 71, 71, 71, 71, 64, 71, 9, 19, 22, 23, 24, 26, 28, 30, 31, 42, 72, 36, 49, 63, 63, 63, 63, 63, 63, 63, 51, 65, 71, 79, 80, 63, 51, 51, 6, 61, 70, 61, 69, 61, 68, 69, 71, 54, 85, 63, 65, 5, 63, 63, 65, 63, 65, 10, 12, 13, 15, 27, 33, 40, 41, 45, 46, 86, 80, 85, 65, 61, 6, 61, 66, 67, 85, 66, 85, 5, 77, 65, 65, 85, 85, 85 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, tngFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; tngFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, tngFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; tngFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, tngFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; tngFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, tngFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; tngFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, tngFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, tngFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; tngFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 7: #line 139 "tngparser.Y" {cerr << "SAOtng" << endl;;} break; case 12: #line 146 "tngparser.Y" {YYACCEPT;;} break; case 13: #line 149 "tngparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 14: #line 150 "tngparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 15: #line 153 "tngparser.Y" {yydebug=1;;} break; case 16: #line 154 "tngparser.Y" {yydebug=0;;} break; case 23: #line 169 "tngparser.Y" {(yyval.real) = 0;;} break; case 24: #line 170 "tngparser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 25: #line 173 "tngparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 26: #line 174 "tngparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 27: #line 177 "tngparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real),Coord::IMAGE);;} break; case 28: #line 181 "tngparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 29: #line 189 "tngparser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 30: #line 193 "tngparser.Y" { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), sys, sky); else r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real)*360./24.,(yyvsp[(3) - (3)].real)), sys, sky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 31: #line 207 "tngparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), localSystem, localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 32: #line 214 "tngparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 33: #line 223 "tngparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 34: #line 224 "tngparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 35: #line 225 "tngparser.Y" {(yyval.integer) = Coord::FK4_NO_E;;} break; case 36: #line 226 "tngparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 37: #line 227 "tngparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 38: #line 228 "tngparser.Y" {(yyval.integer) = Coord::ICRS;;} break; case 39: #line 229 "tngparser.Y" {(yyval.integer) = Coord::GALACTIC;;} break; case 40: #line 230 "tngparser.Y" {(yyval.integer) = Coord::SUPERGALACTIC;;} break; case 41: #line 231 "tngparser.Y" {(yyval.integer) = Coord::ECLIPTIC;;} break; case 42: #line 232 "tngparser.Y" {(yyval.integer) = Coord::HELIOECLIPTIC;;} break; case 43: #line 235 "tngparser.Y" { // global properties globalSystem = Coord::IMAGE; globalSky = Coord::FK5; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; strcpy(globalColor,"green"); strcpy(globalFont,"helvetica 10 normal roman"); strcpy(globalText,""); ;} break; case 44: #line 249 "tngparser.Y" { // reset maperr flag maperr =0; // global properties localSystem = globalSystem; localSky = localSky; localProps = globalProps; strcpy(localColor,globalColor); strcpy(localText,globalText); strcpy(localComment,""); strcpy(globalText,""); ;} break; case 45: #line 265 "tngparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 46: #line 266 "tngparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 47: #line 267 "tngparser.Y" {setProps(&localProps, Marker::INCLUDE, 0);;} break; case 48: #line 271 "tngparser.Y" {fr->createCircleCmd(Vector((yyvsp[(3) - (7)].vector)), (yyvsp[(5) - (7)].real), localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 49: #line 277 "tngparser.Y" {fr->createEllipseCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 50: #line 284 "tngparser.Y" {fr->createBoxCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 51: #line 291 "tngparser.Y" {fr->createLineCmd(Vector((yyvsp[(3) - (7)].vector)), Vector((yyvsp[(5) - (7)].vector)), 0,0, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 52: #line 298 "tngparser.Y" {fr->createPointCmd(Vector((yyvsp[(3) - (5)].vector)), Point::BOXCIRCLE, POINTSIZE, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 53: #line 302 "tngparser.Y" {strncpy(localText,(yyvsp[(5) - (6)].str),80);;} break; case 54: #line 303 "tngparser.Y" {fr->createTextCmd(Vector((yyvsp[(3) - (8)].vector)), 0, 1, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 55: #line 308 "tngparser.Y" {polylist.deleteAll();;} break; case 56: #line 309 "tngparser.Y" {fr->createPolygonCmd(polylist, localColor,dash,1,globalFont,localText, localProps,localComment,taglist,cblist);;} break; case 59: #line 318 "tngparser.Y" {polylist.append(new Vertex((yyvsp[(1) - (1)].vector)));;} break; case 61: #line 322 "tngparser.Y" {DISCARD_(0);} break; case 63: #line 323 "tngparser.Y" {DISCARD_(0);} break; case 65: #line 324 "tngparser.Y" {DISCARD_(1);} break; case 66: #line 324 "tngparser.Y" {strncpy(globalText,(yyvsp[(3) - (3)].str),80);;} break; case 68: #line 328 "tngparser.Y" {strcpy(localColor,"white");;} break; case 69: #line 329 "tngparser.Y" {strcpy(localColor,"black");;} break; case 70: #line 330 "tngparser.Y" {strcpy(localColor,"red");;} break; case 71: #line 331 "tngparser.Y" {strcpy(localColor,"green");;} break; case 72: #line 332 "tngparser.Y" {strcpy(localColor,"blue");;} break; case 73: #line 333 "tngparser.Y" {strcpy(localColor,"cyan");;} break; case 74: #line 334 "tngparser.Y" {strcpy(localColor,"magenta");;} break; case 75: #line 335 "tngparser.Y" {strcpy(localColor,"yellow");;} break; case 76: #line 337 "tngparser.Y" { strcpy(localColor,"green"); setProps(&localProps,Marker::SOURCE,1); ;} break; case 77: #line 342 "tngparser.Y" { strcpy(localColor,"red"); setProps(&localProps,Marker::SOURCE,0); ;} break; case 78: #line 346 "tngparser.Y" {DISCARD_(1);} break; case 79: #line 346 "tngparser.Y" {strncpy(localComment,(yyvsp[(3) - (3)].str),80);;} break; case 82: #line 351 "tngparser.Y" {globalSystem = localSystem = Coord::IMAGE;;} break; case 83: #line 352 "tngparser.Y" {globalSystem = localSystem = Coord::IMAGE;;} break; case 84: #line 356 "tngparser.Y" { globalSystem = localSystem = Coord::WCS; globalSky = localSky = Coord::FK5; ;} break; case 85: #line 361 "tngparser.Y" { globalSystem = localSystem = Coord::WCS; globalSky = localSky = (Coord::SkyFrame)(yyvsp[(2) - (3)].integer); ;} break; /* Line 1267 of yacc.c. */ #line 2007 "tngparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 367 "tngparser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } ����������������������������������������������������������������������������������������������������������./saods9/saotk/frame/proslex.C����������������������������������������������������������������������0000644�0001750�0001750�00000207417�12032640000�015114� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "proslex.C" #line 4 "proslex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer prosFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *prosalloc (yy_size_t ); void *prosrealloc (void *,yy_size_t ); void prosfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 52 #define YY_END_OF_BUFFER 53 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[198] = { 0, 0, 0, 2, 2, 53, 51, 47, 50, 51, 51, 51, 51, 51, 22, 46, 46, 46, 46, 46, 46, 46, 46, 46, 14, 46, 46, 46, 46, 51, 51, 2, 1, 47, 48, 0, 43, 0, 44, 0, 22, 24, 33, 29, 23, 22, 0, 46, 25, 46, 46, 27, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 16, 46, 46, 46, 46, 49, 0, 45, 2, 24, 35, 31, 23, 25, 0, 0, 27, 34, 30, 26, 0, 28, 25, 0, 46, 0, 23, 46, 46, 46, 5, 46, 46, 46, 46, 46, 46, 46, 46, 15, 46, 46, 46, 46, 46, 36, 32, 0, 23, 0, 0, 24, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 37, 0, 46, 0, 46, 46, 4, 46, 7, 46, 46, 46, 46, 12, 46, 46, 18, 46, 46, 46, 0, 0, 38, 37, 0, 0, 41, 0, 0, 39, 46, 6, 46, 46, 46, 46, 46, 46, 46, 20, 46, 41, 39, 42, 40, 3, 46, 8, 46, 46, 13, 46, 19, 21, 9, 46, 11, 17, 46, 10, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 1, 1, 6, 1, 1, 1, 7, 1, 7, 8, 1, 9, 10, 11, 12, 12, 13, 12, 12, 12, 14, 15, 1, 1, 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 26, 38, 39, 26, 1, 40, 1, 1, 1, 1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 26, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 26, 62, 63, 26, 64, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[66] = { 0, 1, 1, 2, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1 } ; static yyconst flex_int16_t yy_base[204] = { 0, 0, 0, 134, 131, 130, 1540, 123, 1540, 121, 116, 114, 58, 64, 74, 94, 98, 90, 121, 162, 127, 138, 150, 154, 166, 170, 187, 182, 214, 62, 52, 0, 1540, 114, 1540, 96, 1540, 86, 1540, 233, 255, 308, 1540, 1540, 361, 414, 239, 222, 467, 478, 270, 281, 286, 318, 330, 301, 342, 380, 385, 396, 489, 433, 495, 500, 438, 459, 520, 524, 528, 1540, 25, 1540, 0, 581, 1540, 1540, 634, 539, 553, 563, 1540, 1540, 1540, 1540, 595, 1540, 1540, 606, 621, 646, 105, 673, 656, 455, 573, 688, 692, 705, 709, 729, 733, 660, 745, 751, 756, 767, 771, 783, 787, 1540, 1540, 794, 818, 826, 838, 850, 857, 872, 880, 890, 894, 905, 811, 913, 918, 930, 942, 946, 961, 966, 972, 978, 986, 990, 1009, 1024, 863, 1033, 999, 1041, 1047, 1093, 1057, 1061, 1065, 1073, 1081, 1103, 1114, 1118, 1126, 1130, 1142, 1150, 1158, 1164, 1175, 1183, 1210, 1197, 1221, 1236, 1242, 1252, 1252, 1268, 1282, 1290, 1298, 1303, 1314, 1325, 1330, 1336, 1356, 1341, 1360, 1375, 1540, 1540, 1540, 1540, 1380, 1393, 1397, 1401, 1409, 1414, 1426, 1432, 1440, 1451, 1455, 1459, 1467, 1473, 1478, 1540, 1524, 1527, 1530, 78, 1533, 1536 } ; static yyconst flex_int16_t yy_def[204] = { 0, 197, 1, 198, 198, 197, 197, 197, 197, 197, 199, 200, 197, 197, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 202, 203, 197, 197, 197, 199, 197, 200, 197, 197, 197, 197, 197, 197, 197, 201, 197, 201, 201, 201, 49, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 202, 197, 203, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 49, 197, 49, 49, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 197, 197, 197, 197, 197, 197, 197, 49, 49, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 197, 197, 197, 197, 49, 197, 49, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 197, 197, 197, 197, 197, 201, 197, 197, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 197, 197, 197, 197, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 0, 197, 197, 197, 197, 197, 197 } ; static yyconst flex_int16_t yy_nxt[1606] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14, 6, 15, 16, 17, 18, 19, 20, 21, 20, 20, 22, 20, 23, 20, 24, 25, 26, 20, 27, 20, 20, 20, 28, 20, 20, 29, 15, 16, 17, 18, 19, 20, 21, 20, 20, 22, 23, 20, 24, 25, 26, 20, 27, 20, 20, 20, 28, 20, 20, 30, 6, 39, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 42, 43, 47, 44, 45, 45, 45, 45, 45, 45, 46, 71, 69, 38, 48, 49, 197, 197, 50, 197, 197, 197, 36, 197, 197, 197, 197, 197, 51, 53, 197, 74, 75, 197, 197, 55, 69, 33, 71, 48, 49, 38, 36, 50, 52, 34, 33, 197, 197, 54, 197, 197, 51, 197, 197, 32, 197, 197, 32, 197, 55, 197, 56, 197, 197, 197, 197, 197, 52, 197, 197, 197, 197, 54, 197, 60, 197, 197, 197, 197, 197, 197, 61, 197, 197, 197, 197, 56, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 60, 57, 197, 197, 197, 62, 197, 197, 197, 197, 58, 197, 63, 197, 197, 59, 197, 197, 197, 197, 64, 197, 197, 197, 197, 197, 57, 197, 197, 62, 197, 65, 197, 67, 58, 197, 197, 63, 66, 59, 197, 197, 197, 197, 64, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 68, 65, 67, 197, 197, 197, 197, 66, 73, 73, 73, 73, 73, 73, 87, 87, 87, 87, 87, 87, 197, 197, 197, 197, 197, 68, 74, 75, 197, 76, 40, 40, 40, 40, 40, 40, 46, 197, 197, 197, 77, 78, 197, 197, 79, 91, 91, 91, 91, 91, 91, 197, 197, 197, 80, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 77, 78, 197, 197, 79, 197, 197, 197, 197, 197, 197, 197, 197, 80, 81, 82, 92, 197, 41, 41, 41, 41, 41, 41, 197, 197, 197, 197, 83, 84, 197, 197, 197, 93, 197, 95, 197, 197, 197, 197, 92, 197, 85, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 83, 84, 197, 197, 197, 197, 95, 96, 197, 197, 197, 197, 197, 85, 42, 43, 94, 197, 41, 41, 41, 41, 41, 41, 197, 197, 197, 197, 86, 78, 197, 197, 96, 197, 197, 197, 197, 197, 197, 197, 94, 197, 80, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 86, 78, 97, 197, 197, 197, 197, 98, 197, 197, 197, 197, 197, 80, 42, 43, 197, 44, 45, 45, 45, 45, 45, 45, 46, 197, 97, 99, 48, 49, 197, 98, 50, 197, 197, 197, 197, 101, 197, 197, 197, 197, 51, 197, 197, 197, 197, 197, 197, 197, 197, 99, 197, 48, 49, 197, 197, 50, 197, 197, 197, 197, 197, 120, 197, 197, 51, 197, 197, 197, 197, 88, 88, 88, 88, 88, 88, 197, 197, 197, 89, 197, 90, 90, 90, 90, 90, 90, 197, 197, 197, 197, 197, 104, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 100, 102, 197, 197, 197, 103, 104, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 100, 197, 102, 197, 105, 197, 103, 106, 111, 111, 111, 111, 111, 111, 197, 197, 197, 197, 197, 107, 89, 108, 112, 112, 112, 112, 112, 112, 197, 105, 197, 106, 113, 113, 113, 113, 113, 113, 197, 197, 197, 197, 197, 107, 197, 108, 109, 110, 197, 197, 73, 73, 73, 73, 73, 73, 197, 197, 197, 197, 83, 84, 114, 197, 115, 115, 115, 115, 115, 115, 197, 197, 197, 197, 85, 87, 87, 87, 87, 87, 87, 116, 197, 197, 197, 83, 84, 197, 197, 197, 88, 88, 88, 88, 88, 88, 197, 197, 85, 74, 75, 197, 197, 73, 73, 73, 73, 73, 73, 117, 197, 197, 197, 86, 78, 112, 112, 112, 112, 112, 112, 197, 197, 197, 197, 197, 197, 80, 197, 127, 197, 197, 197, 117, 197, 197, 197, 197, 86, 78, 197, 197, 91, 91, 91, 91, 91, 91, 197, 197, 197, 80, 119, 197, 197, 197, 197, 197, 197, 197, 197, 118, 197, 197, 197, 197, 121, 197, 197, 197, 197, 197, 197, 197, 197, 197, 119, 197, 197, 197, 197, 197, 197, 197, 197, 118, 197, 197, 122, 123, 197, 121, 197, 124, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 125, 197, 197, 197, 126, 197, 197, 122, 197, 123, 197, 197, 197, 124, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 128, 125, 197, 197, 197, 126, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 129, 197, 197, 197, 128, 197, 130, 197, 197, 197, 132, 197, 197, 111, 111, 111, 111, 111, 111, 197, 131, 197, 197, 197, 129, 197, 197, 197, 197, 197, 130, 133, 134, 74, 75, 132, 197, 112, 112, 112, 112, 112, 112, 145, 131, 113, 113, 113, 113, 113, 113, 197, 197, 197, 197, 133, 134, 115, 115, 115, 115, 115, 115, 197, 135, 109, 110, 197, 145, 115, 115, 115, 115, 115, 115, 136, 137, 137, 137, 137, 137, 137, 159, 159, 159, 159, 159, 159, 135, 197, 138, 139, 139, 139, 139, 139, 139, 197, 140, 141, 141, 141, 141, 141, 141, 197, 197, 197, 197, 197, 197, 197, 197, 143, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 142, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 144, 197, 197, 197, 197, 197, 197, 197, 197, 142, 197, 197, 146, 197, 197, 197, 197, 147, 197, 197, 197, 197, 197, 150, 144, 197, 197, 197, 149, 197, 197, 197, 197, 148, 197, 197, 146, 197, 197, 197, 197, 147, 197, 197, 197, 197, 197, 151, 197, 197, 197, 197, 197, 149, 197, 197, 197, 148, 152, 197, 197, 197, 197, 197, 197, 197, 197, 197, 154, 197, 197, 197, 151, 197, 197, 153, 161, 161, 161, 161, 161, 161, 156, 152, 155, 138, 157, 157, 157, 157, 157, 157, 197, 154, 197, 197, 197, 197, 197, 153, 140, 158, 158, 158, 158, 158, 158, 156, 155, 160, 137, 137, 137, 137, 137, 137, 197, 162, 139, 139, 139, 139, 139, 139, 164, 164, 164, 164, 164, 164, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 163, 197, 197, 197, 197, 197, 197, 197, 197, 197, 168, 197, 197, 197, 197, 197, 197, 197, 167, 197, 197, 197, 197, 197, 163, 197, 165, 141, 141, 141, 141, 141, 141, 197, 197, 168, 197, 197, 197, 197, 197, 169, 167, 197, 197, 197, 197, 197, 197, 197, 197, 197, 166, 197, 197, 197, 197, 197, 197, 197, 197, 197, 170, 197, 197, 169, 197, 197, 197, 171, 197, 173, 197, 197, 197, 197, 166, 197, 172, 197, 197, 197, 197, 197, 197, 174, 170, 197, 197, 197, 197, 197, 197, 171, 197, 197, 173, 197, 197, 197, 197, 197, 172, 197, 197, 197, 197, 197, 197, 197, 174, 197, 197, 175, 197, 197, 162, 157, 157, 157, 157, 157, 157, 197, 197, 197, 197, 176, 197, 197, 177, 159, 159, 159, 159, 159, 159, 175, 197, 197, 197, 197, 178, 165, 158, 158, 158, 158, 158, 158, 197, 176, 197, 197, 177, 159, 159, 159, 159, 159, 159, 197, 197, 197, 197, 197, 178, 197, 197, 179, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 197, 197, 197, 197, 164, 164, 164, 164, 164, 164, 197, 179, 197, 180, 197, 197, 197, 197, 197, 178, 164, 164, 164, 164, 164, 164, 197, 197, 197, 181, 197, 197, 197, 197, 197, 197, 197, 180, 197, 197, 197, 197, 197, 178, 197, 179, 197, 197, 197, 197, 197, 197, 197, 181, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 182, 197, 179, 183, 197, 197, 197, 197, 197, 197, 184, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 182, 197, 197, 197, 183, 197, 186, 197, 197, 197, 185, 184, 197, 197, 197, 187, 197, 197, 197, 197, 197, 197, 189, 197, 188, 197, 197, 197, 197, 197, 197, 186, 197, 197, 185, 197, 197, 197, 197, 187, 197, 197, 197, 197, 197, 197, 189, 197, 197, 188, 197, 197, 197, 197, 197, 197, 190, 197, 197, 197, 197, 197, 197, 191, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 192, 197, 193, 190, 197, 197, 197, 197, 197, 197, 197, 191, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 192, 197, 193, 194, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 197, 197, 197, 197, 197, 194, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 195, 197, 197, 197, 196, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 31, 31, 31, 35, 197, 35, 37, 197, 37, 70, 197, 70, 72, 197, 72, 5, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197 } ; static yyconst flex_int16_t yy_chk[1606] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 201, 14, 14, 14, 14, 14, 14, 14, 14, 70, 29, 37, 14, 14, 17, 17, 14, 17, 15, 15, 35, 15, 16, 16, 17, 16, 14, 16, 15, 90, 90, 90, 16, 17, 29, 33, 30, 14, 14, 11, 10, 14, 15, 9, 7, 18, 18, 16, 18, 5, 14, 20, 20, 4, 20, 18, 3, 0, 17, 0, 18, 20, 21, 21, 0, 21, 15, 0, 0, 0, 0, 16, 21, 21, 22, 22, 0, 22, 23, 23, 22, 23, 0, 0, 22, 18, 19, 19, 23, 19, 24, 24, 0, 24, 25, 25, 19, 25, 21, 19, 24, 0, 0, 23, 25, 0, 27, 27, 19, 27, 25, 26, 26, 19, 26, 0, 27, 0, 25, 0, 0, 26, 0, 0, 19, 0, 0, 23, 0, 26, 0, 27, 19, 0, 0, 25, 26, 19, 28, 28, 0, 28, 25, 0, 0, 0, 47, 47, 28, 47, 0, 0, 0, 28, 26, 27, 47, 0, 0, 0, 26, 39, 39, 39, 39, 39, 39, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 28, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 0, 50, 40, 50, 50, 50, 50, 50, 50, 0, 51, 51, 40, 51, 0, 52, 52, 0, 52, 0, 51, 0, 0, 40, 40, 52, 0, 40, 0, 0, 55, 55, 0, 55, 0, 0, 40, 41, 41, 52, 55, 41, 41, 41, 41, 41, 41, 53, 53, 0, 53, 41, 41, 0, 0, 0, 53, 53, 55, 54, 54, 0, 54, 52, 0, 41, 0, 0, 0, 54, 0, 56, 56, 0, 56, 0, 41, 41, 0, 0, 0, 56, 55, 56, 0, 0, 0, 0, 0, 41, 44, 44, 54, 0, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 44, 44, 0, 0, 56, 57, 57, 0, 57, 0, 58, 58, 54, 58, 44, 57, 0, 0, 0, 0, 58, 59, 59, 0, 59, 44, 44, 57, 0, 0, 0, 59, 58, 0, 0, 0, 0, 0, 44, 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, 45, 0, 57, 59, 45, 45, 0, 58, 45, 61, 61, 0, 61, 61, 64, 64, 0, 64, 45, 61, 0, 0, 0, 0, 64, 0, 0, 59, 0, 45, 45, 93, 93, 45, 93, 65, 65, 0, 65, 93, 0, 93, 45, 48, 48, 65, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 60, 60, 0, 60, 65, 0, 62, 62, 0, 62, 60, 63, 63, 0, 63, 0, 62, 0, 0, 0, 0, 63, 60, 62, 0, 0, 0, 63, 65, 0, 0, 66, 66, 0, 66, 67, 67, 0, 67, 68, 68, 66, 68, 0, 0, 67, 60, 0, 62, 68, 66, 0, 63, 66, 77, 77, 77, 77, 77, 77, 0, 0, 0, 0, 0, 67, 78, 68, 78, 78, 78, 78, 78, 78, 0, 66, 0, 66, 79, 79, 79, 79, 79, 79, 94, 94, 0, 94, 0, 67, 0, 68, 73, 73, 94, 0, 73, 73, 73, 73, 73, 73, 0, 0, 0, 0, 73, 73, 84, 0, 84, 84, 84, 84, 84, 84, 0, 0, 0, 0, 73, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, 73, 73, 0, 88, 0, 88, 88, 88, 88, 88, 88, 0, 0, 73, 76, 76, 0, 0, 76, 76, 76, 76, 76, 76, 88, 0, 0, 0, 76, 76, 89, 89, 89, 89, 89, 89, 92, 92, 0, 92, 101, 101, 76, 101, 101, 0, 92, 0, 88, 0, 101, 0, 0, 76, 76, 91, 0, 91, 91, 91, 91, 91, 91, 0, 0, 0, 76, 92, 95, 95, 0, 95, 96, 96, 0, 96, 91, 0, 95, 0, 0, 95, 96, 0, 0, 97, 97, 0, 97, 98, 98, 92, 98, 0, 0, 97, 0, 0, 0, 98, 91, 0, 0, 96, 97, 0, 95, 0, 98, 99, 99, 0, 99, 100, 100, 0, 100, 0, 0, 99, 99, 0, 0, 100, 100, 102, 102, 96, 102, 97, 0, 103, 103, 98, 103, 102, 104, 104, 0, 104, 0, 103, 0, 0, 102, 99, 104, 105, 105, 100, 105, 106, 106, 0, 106, 0, 0, 105, 0, 0, 0, 106, 0, 107, 107, 104, 107, 108, 108, 102, 108, 105, 0, 107, 0, 107, 0, 108, 111, 111, 111, 111, 111, 111, 0, 106, 0, 0, 0, 104, 0, 122, 122, 0, 122, 105, 108, 111, 112, 112, 107, 122, 112, 112, 112, 112, 112, 112, 122, 106, 113, 113, 113, 113, 113, 113, 0, 0, 0, 0, 108, 111, 114, 114, 114, 114, 114, 114, 0, 113, 115, 115, 0, 122, 115, 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, 136, 136, 136, 136, 136, 136, 113, 117, 117, 117, 117, 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 0, 119, 120, 120, 0, 120, 120, 0, 119, 0, 0, 0, 120, 121, 121, 0, 121, 0, 0, 0, 119, 123, 123, 121, 123, 0, 124, 124, 0, 124, 0, 123, 0, 0, 0, 121, 124, 0, 125, 125, 0, 125, 0, 0, 119, 0, 0, 123, 125, 0, 126, 126, 124, 126, 127, 127, 0, 127, 127, 121, 126, 0, 0, 126, 127, 0, 0, 0, 125, 128, 128, 123, 128, 0, 129, 129, 124, 129, 0, 128, 130, 130, 128, 130, 129, 0, 131, 131, 126, 131, 130, 0, 125, 129, 132, 132, 131, 132, 133, 133, 0, 133, 0, 131, 132, 0, 0, 128, 133, 0, 130, 138, 138, 138, 138, 138, 138, 133, 129, 132, 134, 134, 134, 134, 134, 134, 134, 0, 131, 0, 0, 0, 0, 0, 130, 135, 135, 135, 135, 135, 135, 135, 133, 132, 137, 137, 137, 137, 137, 137, 137, 139, 139, 139, 139, 139, 139, 139, 139, 140, 140, 140, 140, 140, 140, 142, 142, 0, 142, 143, 143, 0, 143, 144, 144, 142, 144, 0, 139, 143, 0, 145, 145, 144, 145, 0, 0, 0, 144, 146, 146, 145, 146, 0, 0, 0, 142, 0, 0, 146, 0, 0, 139, 141, 141, 141, 141, 141, 141, 141, 141, 147, 147, 144, 147, 0, 0, 0, 0, 146, 142, 147, 148, 148, 0, 148, 149, 149, 0, 149, 141, 0, 148, 0, 150, 150, 149, 150, 151, 151, 147, 151, 0, 146, 150, 0, 0, 148, 151, 151, 152, 152, 0, 152, 141, 0, 149, 0, 153, 153, 152, 153, 0, 152, 147, 0, 154, 154, 153, 154, 0, 148, 155, 155, 151, 155, 154, 0, 0, 0, 149, 0, 155, 156, 156, 0, 156, 0, 152, 0, 0, 154, 0, 156, 157, 157, 157, 157, 157, 157, 157, 0, 0, 0, 0, 155, 0, 0, 156, 159, 159, 159, 159, 159, 159, 154, 0, 0, 0, 0, 157, 158, 158, 158, 158, 158, 158, 158, 0, 155, 0, 0, 156, 160, 160, 160, 160, 160, 160, 0, 0, 0, 0, 0, 157, 0, 0, 158, 161, 161, 161, 161, 161, 161, 162, 162, 162, 162, 162, 162, 163, 163, 0, 163, 164, 164, 164, 164, 164, 164, 163, 158, 0, 161, 0, 0, 0, 0, 0, 162, 165, 165, 165, 165, 165, 165, 0, 0, 0, 164, 166, 166, 0, 166, 0, 0, 0, 161, 167, 167, 166, 167, 0, 162, 0, 165, 168, 168, 167, 168, 0, 169, 169, 164, 169, 0, 168, 0, 0, 0, 0, 169, 170, 170, 0, 170, 0, 167, 0, 165, 169, 0, 170, 171, 171, 0, 171, 170, 172, 172, 0, 172, 0, 171, 173, 173, 0, 173, 172, 175, 175, 167, 175, 0, 173, 169, 0, 172, 0, 175, 0, 171, 170, 0, 174, 174, 173, 174, 176, 176, 0, 176, 0, 175, 174, 174, 0, 0, 176, 0, 0, 0, 172, 177, 177, 171, 177, 0, 182, 182, 173, 182, 0, 177, 0, 0, 0, 175, 182, 0, 174, 183, 183, 0, 183, 184, 184, 177, 184, 185, 185, 183, 185, 0, 183, 184, 0, 186, 186, 185, 186, 0, 187, 187, 0, 187, 0, 186, 185, 0, 186, 177, 187, 0, 188, 188, 0, 188, 0, 183, 189, 189, 0, 189, 188, 0, 0, 0, 190, 190, 189, 190, 0, 185, 0, 186, 188, 0, 190, 191, 191, 0, 191, 192, 192, 0, 192, 193, 193, 191, 193, 0, 0, 192, 192, 194, 194, 193, 194, 0, 188, 195, 195, 0, 195, 194, 196, 196, 0, 196, 0, 195, 0, 0, 0, 0, 196, 0, 0, 192, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 198, 198, 198, 199, 0, 199, 200, 0, 200, 202, 0, 202, 203, 0, 203, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "proslex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "proslex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "prosparser.H" extern YYSTYPE* proslval; extern prosFlexLexer* proslexx; /* rules */ #line 846 "proslex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 30 "proslex.L" #line 950 "proslex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 198 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 197 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 32 "proslex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(proslval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 39 "proslex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 47 "proslex.L" {return ANNULUS_;} YY_BREAK case 4: YY_RULE_SETUP #line 48 "proslex.L" {return B1950_;} YY_BREAK case 5: YY_RULE_SETUP #line 49 "proslex.L" {return BOX_;} YY_BREAK case 6: YY_RULE_SETUP #line 50 "proslex.L" {return CIRCLE_;} YY_BREAK case 7: YY_RULE_SETUP #line 51 "proslex.L" {return DEBUG_;} YY_BREAK case 8: YY_RULE_SETUP #line 52 "proslex.L" {return ELLIPSE_;} YY_BREAK case 9: YY_RULE_SETUP #line 53 "proslex.L" {return ECLIPTIC_;} YY_BREAK case 10: YY_RULE_SETUP #line 54 "proslex.L" {return EQUATORIAL_;} YY_BREAK case 11: YY_RULE_SETUP #line 55 "proslex.L" {return GALACTIC_;} YY_BREAK case 12: YY_RULE_SETUP #line 56 "proslex.L" {return J2000_;} YY_BREAK case 13: YY_RULE_SETUP #line 57 "proslex.L" {return LOGICAL_;} YY_BREAK case 14: YY_RULE_SETUP #line 58 "proslex.L" {return N_;} YY_BREAK case 15: YY_RULE_SETUP #line 59 "proslex.L" {return OFF_;} YY_BREAK case 16: YY_RULE_SETUP #line 60 "proslex.L" {return ON_;} YY_BREAK case 17: YY_RULE_SETUP #line 61 "proslex.L" {return PHYSICAL_;} YY_BREAK case 18: YY_RULE_SETUP #line 62 "proslex.L" {return POINT_;} YY_BREAK case 19: YY_RULE_SETUP #line 63 "proslex.L" {return POLYGON_;} YY_BREAK case 20: YY_RULE_SETUP #line 64 "proslex.L" {return ROTBOX_;} YY_BREAK case 21: YY_RULE_SETUP #line 65 "proslex.L" {return VERSION_;} YY_BREAK case 22: YY_RULE_SETUP #line 67 "proslex.L" { // Integer proslval->integer = atoi(yytext); return INT; } YY_BREAK case 23: #line 73 "proslex.L" case 24: YY_RULE_SETUP #line 73 "proslex.L" { // Real Number proslval->real = atof(yytext); return REAL; } YY_BREAK case 25: #line 79 "proslex.L" case 26: YY_RULE_SETUP #line 79 "proslex.L" { // degrees yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ANGDEGREE; } YY_BREAK case 27: #line 86 "proslex.L" case 28: YY_RULE_SETUP #line 86 "proslex.L" { // radians yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ANGRADIAN; } YY_BREAK case 29: #line 93 "proslex.L" case 30: #line 94 "proslex.L" case 31: #line 95 "proslex.L" case 32: YY_RULE_SETUP #line 95 "proslex.L" { // minutes of arc yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ARCMINUTE; } YY_BREAK case 33: #line 102 "proslex.L" case 34: #line 103 "proslex.L" case 35: #line 104 "proslex.L" case 36: YY_RULE_SETUP #line 104 "proslex.L" { // seconds of arc yytext[yyleng-1] = '\0'; proslval->real = atof(yytext); return ARCSECOND; } YY_BREAK case 37: #line 111 "proslex.L" case 38: YY_RULE_SETUP #line 111 "proslex.L" { // Sexagesimal int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 39: #line 119 "proslex.L" case 40: YY_RULE_SETUP #line 119 "proslex.L" { // HMS int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return HMSSTR; } YY_BREAK case 41: #line 127 "proslex.L" case 42: YY_RULE_SETUP #line 127 "proslex.L" { // DMS int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return DMSSTR; } YY_BREAK case 43: #line 135 "proslex.L" case 44: YY_RULE_SETUP #line 135 "proslex.L" { // Quoted String int ll=(yyleng-2)<(PROSBUFSIZE-1)?(yyleng-2):(PROSBUFSIZE-1); strncpy(proslval->str,yytext+1,ll); // skip the " " proslval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 45: YY_RULE_SETUP #line 142 "proslex.L" { // Quoted String int ll=(yyleng-2)<(PROSBUFSIZE-1)?(yyleng-2):(PROSBUFSIZE-1); strncpy(proslval->str,yytext+1,ll); // skip the '{' proslval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 46: YY_RULE_SETUP #line 149 "proslex.L" { // General String int ll = yyleng <(PROSBUFSIZE-1) ? yyleng:(PROSBUFSIZE-1); strncpy(proslval->str,yytext,ll); proslval->str[ll] = '\0'; return STRING; } YY_BREAK case 47: YY_RULE_SETUP #line 156 "proslex.L" { // White Spaces } YY_BREAK case 48: /* rule 48 can match eol */ YY_RULE_SETUP #line 159 "proslex.L" { // windows line feed return '\n'; } YY_BREAK case 49: YY_RULE_SETUP #line 163 "proslex.L" { // fake line feed return '\n'; } YY_BREAK case 50: /* rule 50 can match eol */ YY_RULE_SETUP #line 167 "proslex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 171 "proslex.L" { // eof return EOF_; } YY_BREAK case 51: YY_RULE_SETUP #line 175 "proslex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 52: YY_RULE_SETUP #line 179 "proslex.L" ECHO; YY_BREAK #line 1332 "proslex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; prosfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); prosfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ prosrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) prosrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 198 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 198 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 197); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) prosalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) prosalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) prosfree((void *) b->yy_ch_buf ); prosfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)prosalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)prosrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) prosalloc(new_size ); else (yy_start_stack) = (int *) prosrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *prosalloc (yy_size_t size ) { return (void *) malloc( size ); } void *prosrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void prosfree (void * ptr ) { free( (char *) ptr ); /* see prosrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 179 "proslex.L" void prosDiscard(int doit) { if (proslexx) proslexx->begin(DISCARD, doit); } void prosFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/prosparser.Y�������������������������������������������������������������������0000644�0001750�0001750�00000024235�11727715200�015660� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {prosFlexLexer* ll} %parse-param {prosFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; prosDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer prosFlexLexer #include <FlexLexer.h> extern int proslex(void*, prosFlexLexer*); extern void proserror(Base*, prosFlexLexer*, const char*); extern void prosDiscard(int); static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static unsigned short globalProps; static unsigned short localProps; static char *color = "green"; static int dash[] ={8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aStatus; static Vector aCenter; static double aAngle; static unsigned short aProps; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); %} %union { #define PROSBUFSIZE 2048 double real; int integer; char str[PROSBUFSIZE]; double vector[3]; } %type <real> numeric %type <real> angle %type <real> optangle %type <real> value %type <vector> vvalue %type <real> sexagesimal %type <real> hms %type <real> dms %type <vector> coord %type <integer> coordSystem %type <integer> skyFrame %type <integer> equatorial %type <integer> numberof %token <integer> INT %token <real> REAL %token <str> STRING %token <real> ANGDEGREE %token <real> ARCMINUTE %token <real> ARCSECOND %token <real> ANGRADIAN %token <str> SEXSTR %token <str> HMSSTR %token <str> DMSSTR %token EOF_ %token ANNULUS_ %token B1950_ %token BOX_ %token CIRCLE_ %token DEBUG_ %token ECLIPTIC_ %token ELLIPSE_ %token EQUATORIAL_ %token GALACTIC_ %token J2000_ %token LOGICAL_ %token N_ %token OFF_ %token ON_ %token PHYSICAL_ %token POINT_ %token POLYGON_ %token ROTBOX_ %token VERSION_ %% start : initGlobal commands processAnnulus ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "PROS" << endl;} | coordSystem {globalSystem = (Coord::CoordSystem)$1;} comment | skyFrame {globalSystem = Coord::WCS; globalSky = (Coord::SkyFrame)$1;} comment | initLocal include shape | generalComment ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; sp : /* empty */ | ',' ; bp : /* empty */ | '(' ; ep : /* emtpy */ | ')' ; optangle: /* empty */ {$$ = 0;} | angle {$$ = $1;} ; angle : numeric {$$ = degToRad($1);} /* assume degree */ | ANGDEGREE {$$ = degToRad($1);} | ANGRADIAN {$$=$1;} ; value : numeric {$$ = FITSPTR->mapLenToRef($1, Coord::IMAGE);} | ANGDEGREE {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::DEGREE);} | ARCMINUTE {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::ARCMIN);} | ARCSECOND {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::ARCSEC);} ; vvalue : numeric sp numeric { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::DEGREE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCMINUTE sp ARCMINUTE { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::ARCMIN); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCSECOND sp ARCSECOND { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::ARCSEC); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; numberof: N_ '=' INT {$$ = $3;} ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; hms : HMSSTR {$$ = parseHMSStr($1);} ; dms : DMSSTR {$$ = parseDMSStr($1);} ; coord : sexagesimal sp sexagesimal { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector($1,$3), sys, sky); else r = FITSPTR->mapToRef(Vector($1*360./24.,$3), sys, sky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | hms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | dms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3), localSystem, localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; coordSystem : LOGICAL_ {$$ = Coord::IMAGE;} | PHYSICAL_ {$$ = Coord::PHYSICAL;} ; skyFrame : EQUATORIAL_ equatorial {$$ = $2;} | B1950_ {$$ = Coord::FK4;} | J2000_ {$$ = Coord::FK5;} | GALACTIC_ {$$ = Coord::GALACTIC;} | ECLIPTIC_ {$$ = Coord::ECLIPTIC;} ; equatorial : B1950_ {$$ = Coord::FK4;} | J2000_ {$$ = Coord::FK5;} ; initGlobal:{ // global properties globalSystem = Coord::IMAGE; globalSky = Coord::FK5; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; } ; initLocal : { // reset maperr flag maperr =0; // global properties localSystem = globalSystem; localSky = globalSky; localProps = globalProps; strcpy(localComment,""); } ; include : /* empty */ {setProps(&localProps, Marker::INCLUDE, 1);} | '+' {setProps(&localProps, Marker::INCLUDE, 1);} | '-' {setProps(&localProps, Marker::INCLUDE, 0);} ; shape : CIRCLE_ bp coord sp value ep shapeComment {fr->createCircleCmd(Vector($3), $5, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ANNULUS_ bp coord sp value sp value ep shapeComment {fr->createAnnulusCmd(Vector($3), $5,$7,1, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ANNULUS_ bp coord sp value sp value sp {aNum=2;} aRads ep shapeComment { aAnnuli[0] = $5; aAnnuli[1] = $7; fr->createAnnulusCmd(Vector($3), aNum,aAnnuli, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ANNULUS_ bp coord sp value sp value sp numberof ep shapeComment {fr->createAnnulusCmd(Vector($3), $5,$7,$9, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | ELLIPSE_ bp coord sp vvalue sp optangle ep shapeComment { // for ellipse annulus aStatus = 1; aCenter = Vector($3); aAngle = $7; aVector[0] = Vector($5); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp optangle ep '&' '!' ELLIPSE_ bp coord sp vvalue sp optangle ep { aStatus = 2; aVector[aNum++] = Vector($5); } | BOX_ bp coord sp vvalue sp optangle ep shapeComment { // for box annulus aStatus = 3; aCenter = Vector($3); aAngle = $7; aVector[0] = Vector($5); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist); } | ROTBOX_ bp coord sp vvalue sp optangle ep shapeComment {fr->createBoxCmd(Vector($3), Vector($5), $7, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | BOX_ bp coord sp vvalue sp optangle ep '&' '!' BOX_ bp coord sp vvalue sp optangle ep { aStatus = 4; aVector[aNum++] = Vector($5); } | POINT_ bp coord ep shapeComment {fr->createPointCmd(Vector($3), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,localProps,localComment,taglist,cblist);} | POLYGON_ {polylist.deleteAll();} bp polyNodes ep shapeComment {fr->createPolygonCmd(polylist, color,dash,1,font,text,localProps,localComment,taglist,cblist);} ; polyNodes : polyNodes sp polyNode | polyNode ; polyNode : coord {polylist.append(new Vertex($1));} ; aRads : aRads sp aRad | aRad ; aRad : value {aAnnuli[aNum++] = $1;} ; processAnnulus : /* empty */ { switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; } aStatus = 0; } ; comment : /* empty */ | '#' {DISCARD_(1)} STRING ; generalComment : '#' {DISCARD_(1)} STRING ; shapeComment : /* empty */ processAnnulus | '#' {DISCARD_(0)} STRING processAnnulus {strncpy(localComment,$3,80);} ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametruecolor24.h�������������������������������������������������������������0000644�0001750�0001750�00000001421�11700666270�016671� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frametruecolor24_h__ #define __frametruecolor24_h__ #include "frametruecolor.h" #include "truecolor24.h" class FrameTrueColor24 : public virtual FrameBase, public FrameTrueColor, public TrueColor24 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor24::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor24::encodeTrueColor(src, ximage);} void updateColorScale(); void updateColorScale24(); void updateColorScale32(); public: FrameTrueColor24(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameTrueColor24(); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/prosparser.H�������������������������������������������������������������������0000644�0001750�0001750�00000006523�11626771530�015645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, ARCMINUTE = 262, ARCSECOND = 263, ANGRADIAN = 264, SEXSTR = 265, HMSSTR = 266, DMSSTR = 267, EOF_ = 268, ANNULUS_ = 269, B1950_ = 270, BOX_ = 271, CIRCLE_ = 272, DEBUG_ = 273, ECLIPTIC_ = 274, ELLIPSE_ = 275, EQUATORIAL_ = 276, GALACTIC_ = 277, J2000_ = 278, LOGICAL_ = 279, N_ = 280, OFF_ = 281, ON_ = 282, PHYSICAL_ = 283, POINT_ = 284, POLYGON_ = 285, ROTBOX_ = 286, VERSION_ = 287 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define ARCMINUTE 262 #define ARCSECOND 263 #define ANGRADIAN 264 #define SEXSTR 265 #define HMSSTR 266 #define DMSSTR 267 #define EOF_ 268 #define ANNULUS_ 269 #define B1950_ 270 #define BOX_ 271 #define CIRCLE_ 272 #define DEBUG_ 273 #define ECLIPTIC_ 274 #define ELLIPSE_ 275 #define EQUATORIAL_ 276 #define GALACTIC_ 277 #define J2000_ 278 #define LOGICAL_ 279 #define N_ 280 #define OFF_ 281 #define ON_ 282 #define PHYSICAL_ 283 #define POINT_ 284 #define POLYGON_ 285 #define ROTBOX_ 286 #define VERSION_ 287 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 65 "prosparser.Y" { #define PROSBUFSIZE 2048 double real; int integer; char str[PROSBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 121 "prosparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/point.h������������������������������������������������������������������������0000644�0001750�0001750�00000005264�12002337011�014614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __point_h__ #define __point_h__ #include "marker.h" class Point : public Marker { public: enum PointShape {CIRCLE,BOX,DIAMOND,CROSS,EX,ARROW,BOXCIRCLE}; protected: PointShape shape_; char* shapestr_; int size_; Vector* generateCircle(Coord::InternalSystem, int); Vector* generateBox(Coord::InternalSystem); Vector* generateDiamond(Coord::InternalSystem); Vector* generateCross(Coord::InternalSystem); Vector* generateEx(Coord::InternalSystem); Vector* generateArrow(Coord::InternalSystem); void renderXCircle(Drawable, Coord::InternalSystem, RenderMode, int); void renderXBox(Drawable drawable, Coord::InternalSystem sys, RenderMode mode); void renderXLineDash(GC lgc); void renderPSCircle(int,int); void renderPSBox(int); void renderPSLineDash(); #ifdef _MACOSX void renderMACOSXCircle(int); void renderMACOSXBox(); void renderMACOSXLineDash(); #endif #ifdef _WIN32 void renderWIN32Circle(int); void renderWIN32Box(); void renderWIN32LineDash(); #endif void shapeStr(PointShape); void updateHandles(); public: Point(const Point&); Point(Base* p, const Vector& ctr, PointShape shape, int size, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual ~Point(); virtual Marker* dup() {return new Point(*this);} void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int mode); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif const char* shape() {return shapestr_;} void setShape(PointShape); int size() {return size_;} void setSize(int); int isIn(const Vector&, Coord::InternalSystem); void editBegin(int) {} void edit(const Vector& v, int h) {} void editEnd() {} void rotateBegin() {} void rotate(const Vector& v, int h) {} void rotateEnd() {} void analysis(AnalysisTask, int); void analysisPlot3d(char*, char*, Coord::CoordSystem sys, Marker::AnalysisMethod); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listPost(ostream&, int, int); virtual void listCiao(ostream&, Coord::CoordSystem, int); virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); virtual void listSAOimage(ostream&, int); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudo.C������������������������������������������������������������������0000644�0001750�0001750�00000002663�11700666267�015756� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framepseudo.h" FramePseudo::FramePseudo(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i, c, item) { } FramePseudo::~FramePseudo() { } void FramePseudo::rotateMotion() { // Rotate from src to dest Vector c = Vector(options->width,options->height)/2; Matrix m = (Translate(-c) * Rotate(rotation-rotateRotation) * Translate(c)).invert(); double* mm = m.mm(); unsigned long bgc = getColor(bgColorName); int& width = options->width; int& height = options->height; char* src = XImageData(rotateSrcXM); for (int j=0; j<height; j++) { // the line may be padded at the end char* dest = XImageData(rotateDestXM) + j*rotateDestXM->bytes_per_line; for (int i=0; i<width; i++, dest++) { double x = i*mm[0] + j*mm[3] + mm[6]; double y = i*mm[1] + j*mm[4] + mm[7]; if (x >= 0 && x < width && y >= 0 && y < height) *dest = src[((int)y)*rotateSrcXM->bytes_per_line + (int)x]; else *dest = bgc; } } // XImage to Pixmap XPutImage(display, rotatePM, gc, rotateDestXM, 0, 0, 0, 0, options->width, options->height); // Display Pixmap Vector dd = Vector() * widgetToWindow; XCopyArea(display, rotatePM, Tk_WindowId(tkwin), rotateGCXOR, 0, 0, options->width, options->height, dd[0], dd[1]); } �����������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor8.C������������������������������������������������������������0000644�0001750�0001750�00000012571�11700666267�017013� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "frame3dtruecolor8.h" #include "colorscaletrue8.h" // Tk Canvas Widget Function Declarations int Frame3dTrueColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Frame3dTrueColor8 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frame3dTrueColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "frame3d", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frame3dTrueColor8Type = { (char*)"frame3dtruecolor8", // name sizeof(WidgetOptions), // item size Frame3dTrueColor8CreateProc, // configProc frame3dTrueColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int Frame3dTrueColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frame3dTrueColor8Type); return TCL_OK; } int Frame3dTrueColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { Frame3dTrueColor8* frame = new Frame3dTrueColor8(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // Frame3dTrueColor8 Member Functions Frame3dTrueColor8::Frame3dTrueColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i,c,item), Frame3dTrueColor(i,c,item), TrueColor8(visual) { configSpecs = frame3dTrueColor8Specs; // frame configure options } Frame3dTrueColor8::~Frame3dTrueColor8() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } void Frame3dTrueColor8::updateColorScale() { // we need colors before we can construct a scale if (!indexCells || !colorCells) return; if (colorScale) delete colorScale; switch (context->frScale.colorScaleType()) { case FrScale::LINEARSCALE: colorScale = new LinearScaleTrueColor8(colorCount, indexCells, colorCells, colorCount, visual); break; case FrScale::LOGSCALE: colorScale = new LogScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual); break; case FrScale::POWSCALE: colorScale = new PowScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->frScale.expo(), visual); break; case FrScale::SQRTSCALE: colorScale = new SqrtScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::SQUAREDSCALE: colorScale = new SquaredScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::ASINHSCALE: colorScale = new AsinhScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::SINHSCALE: colorScale = new SinhScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, visual); break; case FrScale::IISSCALE: colorScale = new IISScaleTrueColor8(indexCells, colorCells, colorCount, visual); break; case FrScale::HISTEQUSCALE: colorScale = new HistEquScaleTrueColor8(SCALESIZE, indexCells, colorCells, colorCount, context->histequ(), HISTEQUSIZE, visual); break; } } ���������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/saoparser.H��������������������������������������������������������������������0000644�0001750�0001750�00000005402�11626771530�015437� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, EOF_ = 261, ANNULUS_ = 262, BOX_ = 263, CIRCLE_ = 264, DEBUG_ = 265, ELLIPSE_ = 266, N_ = 267, OFF_ = 268, ON_ = 269, POINT_ = 270, POLYGON_ = 271, ROTBOX_ = 272, VERSION_ = 273 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define EOF_ 261 #define ANNULUS_ 262 #define BOX_ 263 #define CIRCLE_ 264 #define DEBUG_ 265 #define ELLIPSE_ 266 #define N_ 267 #define OFF_ 268 #define ON_ 269 #define POINT_ 270 #define POLYGON_ 271 #define ROTBOX_ 272 #define VERSION_ 273 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 59 "saoparser.Y" { #define SAOBUFSIZE 2048 double real; int integer; char str[SAOBUFSIZE]; double vector[3]; } /* Line 1529 of yacc.c. */ #line 93 "saoparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xml.h��������������������������������������������������������������������������0000644�0001750�0001750�00000001035�11734430025�014265� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __xml_h__ #define __xml_h__ #define XMLNUMCOL 34 enum XMLColName {XMLSHAPE,XMLX,XMLY,XMLXV,XMLYV,XMLR,XMLR2,XMLRV,XMLRV2,XMLANG,XMLANGV,XMLTILE,XMLCOLOR,XMLWIDTH,XMLTEXT,XMLFONT,XMLSELECT,XMLHIGHLITE,XMLEDIT,XMLMOVE,XMLROTATE,XMLDELETE,XMLFIXED,XMLINCLUDE,XMLSOURCE,XMLDASH,XMLDASHLIST,XMLTAG,XMLPARAM,XMLPARAM2,XMLPARAM3,XMLPARAM4,XMLPARAM5,XMLCOMMENT}; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ciaolex.L����������������������������������������������������������������������0000644�0001750�0001750�00000005123�11700666266�015072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "ciaoparser.H" extern YYSTYPE* ciaolval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% annulus {return ANNULUS_;} box {return BOX_;} circle {return CIRCLE_;} debug {return DEBUG_;} ellipse {return ELLIPSE_;} off {return OFF_;} on {return ON_;} pie {return PIE_;} point {return POINT_;} polygon {return POLYGON_;} rotbox {return ROTBOX_;} version {return VERSION_;} [+-]?{D}+ { // Integer ciaolval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number ciaolval->real = atof(yytext); return REAL; } [+-]?{D}+"."?d | [+-]?{D}*"."{D}+d { // degrees yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ANGDEGREE; } {D}+"."?' | {D}*"."{D}+' | [+-]?{D}+"."?({E})?' | [+-]?{D}*"."{D}+({E})?' { // minutes of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCMINUTE; } {D}+"."?\" | {D}*"."{D}+\" | [+-]?{D}+"."?({E})?\" | [+-]?{D}*"."{D}+({E})?\" { // seconds of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCSECOND; } {D}+"."?\'\' | {D}*"."{D}+\'\' | [+-]?{D}+"."?({E})?\'\' | [+-]?{D}*"."{D}+({E})?\'\' { // seconds of arc yytext[yyleng-1] = '\0'; ciaolval->real = atof(yytext); return ARCSECOND; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // Sexagesimal int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return SEXSTR; } [+-]?{D}+h{D}+m{D}+"."?s | [+-]?{D}+h{D}+m{D}*"."{D}+s { // HMS int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return HMSSTR; } [+-]?{D}+d{D}+m{D}+"."?s | [+-]?{D}+d{D}+m{D}*"."{D}+s { // DMS int ll = yyleng <(CIAOBUFSIZE-1) ? yyleng:(CIAOBUFSIZE-1); strncpy(ciaolval->str,yytext,ll); ciaolval->str[ll] = '\0'; return DMSSTR; } #.* { // comment, eat it } [ \t]+ { // White Spaces } \\n { // fake line feed return '\n'; } \r\n { // windows line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudocolor8.h������������������������������������������������������������0000644�0001750�0001750�00000001072�11700666267�017143� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framepseudocolor8_h__ #define __framepseudocolor8_h__ #include "framepseudocolor.h" class FramePseudoColor8 : public virtual FrameBase, public FramePseudoColor { private: void encodeTrueColor(XColor*, char*) {} void encodeTrueColor(unsigned char*, XImage*) {} void updateColorScale(); public: FramePseudoColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FramePseudoColor8(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/tag.h��������������������������������������������������������������������������0000644�0001750�0001750�00000001215�11700666271�014247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __tag_h__ #define __tag_h__ #include <iostream> #include <sstream> #include <iomanip> using namespace std; class Tag { char* tag_; Tag* previous_; Tag* next_; public: Tag(const char*); Tag(const Tag&); Tag& operator=(const Tag&); ~Tag(); const char* tag() {return tag_;} void set(const char*); Tag* previous() {return previous_;} void setPrevious(Tag* t) {previous_ = t;} Tag* next() {return next_;} void setNext(Tag* t) {next_ = t;} }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/circle.C�����������������������������������������������������������������������0000644�0001750�0001750�00000021463�12030663652�014674� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "circle.h" #include "fitsimage.h" Circle::Circle(const Circle& a) : BaseEllipse(a) {} Circle::Circle(Base* p, const Vector& ctr, double r, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseEllipse(p, ctr, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { numAnnuli_ = 1; annuli_ = new Vector[numAnnuli_]; annuli_[0] = Vector(r,r); strcpy(type_, "circle"); numHandle = 4; updateBBox(); } void Circle::edit(const Vector& v, int h) { Matrix mm = bckMatrix(); // calc dist between edge of circle and handle double d = annuli_[0].length() - annuli_[0][0]; double r = (v * mm).length() - d; annuli_[0] = Vector(r,r); updateBBox(); doCallBack(CallBack::EDITCB); } void Circle::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT3D: if (!analysisPlot3d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot3dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot3dCB_[1], parent->options->cmdName); } if (analysisPlot3d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot3dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot3dCB_[1]); } analysisPlot3d_ = which; break; case STATS: if (!analysisStats_ && which) { addCallBack(CallBack::MOVECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisStatsCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisStatsCB_[1], parent->options->cmdName); } if (analysisStats_ && !which) { deleteCallBack(CallBack::MOVECB, analysisStatsCB_[0]); deleteCallBack(CallBack::EDITCB, analysisStatsCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisStatsCB_[0]); deleteCallBack(CallBack::DELETECB, analysisStatsCB_[1]); } analysisStats_ = which; break; } } void Circle::analysisPlot3d(char* xname, char* yname, Coord::CoordSystem sys, Marker::AnalysisMethod method) { double* x; double* y; Vector ll = -annuli_[0] * Translate(center); Vector ur = annuli_[0] * Translate(center); BBox bb(ll,ur) ; int num = parent->markerAnalysisPlot3d(this, &x, &y, bb, sys, method); analysisPlot3dResult(xname, yname, x, y, num); } void Circle::analysisStats(Coord::CoordSystem sys) { ostringstream str; Vector ll = -annuli_[0] * Translate(center); Vector ur = annuli_[0] * Translate(center); BBox bb(ll,ur) ; parent->markerAnalysisStats(this, str, bb, sys); Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } // list void Circle::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); double r = ptr->mapLenFromRef(annuli_[0][0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); double r = ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] <<',' << r << '"' << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; double r = ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC); str << type_ << '(' << ra << ',' << dec << ',' << r << '"' << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); double r = ptr->mapLenFromRef(annuli_[0][0],sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] <<',' << r << ')'; } } } listPost(str, conj, strip); } void Circle::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowRadiusX(ptr,sys,annuli_[0]); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Circle::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { FitsImage* ptr = parent->findFits(); listCiaoPre(str); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::PHYSICAL); double r = ptr->mapLenFromRef(annuli_[0][0],Coord::PHYSICAL); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r << ')'; } break; default: if (ptr->hasWCSCel(sys)) { double r = ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCMIN); char buf[64]; ptr->mapFromRef(center,sys,Coord::FK5,Coord::SEXAGESIMAL,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << r << '\'' << ')'; } } listCiaoPost(str, strip); } void Circle::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); listSAOtngPre(str, strip); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::IMAGE); double r = ptr->mapLenFromRef(annuli_[0][0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); double r = ptr->mapLenFromRef(annuli_[0][0],Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << r << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); double r = ptr->mapLenFromRef(annuli_[0][0],Coord::IMAGE); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << r << ')'; } break; } } } listSAOtngPost(str,strip); } void Circle::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::DETECTOR: case Coord::AMPLIFIER: sys = Coord::IMAGE; case Coord::PHYSICAL: { Vector v = ptr->mapFromRef(center,sys); double r = ptr->mapLenFromRef(annuli_[0][0],Coord::IMAGE); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v << r; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); double r = ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << setprecision(8) << v[0] << "d " << v[1] << "d " << r << "\" "; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char decc[16]; char *dec = decc; string x(buf); istringstream wcs(x); wcs >> ra >> dec; if (dec[0]=='+') dec++; double r = ptr->mapLenFromRef(annuli_[0][0],sys,Coord::ARCSEC); coord.listProsCoordSystem(str,sys,sky); str << "; " << type_ << ' ' << ra << ' ' << dec << ' ' << r << "\" "; } break; } } } listProsPost(str, strip); } void Circle::listSAOimage(ostream& str, int strip) { FitsImage* ptr = parent->findFits(); listSAOimagePre(str); Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << annuli_[0][0] << ')'; listSAOimagePost(str, strip); } // special composite funtionallity void Circle::setComposite(const Matrix& mx, double aa) { center *= mx; updateBBox(); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frametrue.C��������������������������������������������������������������������0000644�0001750�0001750�00000003550�11700666267�015432� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "frametrue.h" FrameTrue::FrameTrue(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i, c, item) { colormapXM = NULL; colormapPM = 0; colormapGCXOR = 0; byteorder_ = 0; bitsperpixel_ = 0; } FrameTrue::~FrameTrue() { if (colormapXM) XDestroyImage(colormapXM); if (colormapPM) Tk_FreePixmap(display, colormapPM); if (colormapGCXOR) XFreeGC(display, colormapGCXOR); } void FrameTrue::rotateMotion() { // Rotate from src to dest Vector cc = Vector(options->width,options->height)/2; Matrix m = (Translate(-cc) * Rotate(rotation-rotateRotation) * Translate(cc)).invert(); double* mm = m.mm(); int& width = options->width; int& height = options->height; char* src = XImageData(rotateSrcXM); int bytesPerPixel = rotateDestXM->bits_per_pixel/8; for (int j=0; j<height; j++) { // the line may be padded at the end char* dest = XImageData(rotateDestXM) + j*rotateDestXM->bytes_per_line; for (int i=0; i<width; i++, dest+=bytesPerPixel) { double x = i*mm[0] + j*mm[3] + mm[6]; double y = i*mm[1] + j*mm[4] + mm[7]; if (x >= 0 && x < width && y >= 0 && y < height) memcpy(dest, src + ((int)y)*rotateDestXM->bytes_per_line+ ((int)x)*bytesPerPixel, bytesPerPixel); else memcpy(dest, bgTrueColor_, bytesPerPixel); } } // XImage to Pixmap XPutImage(display, rotatePM, gc, rotateDestXM, 0, 0, 0, 0, options->width, options->height); // Display Pixmap Vector dd = Vector() * widgetToWindow; XCopyArea(display, rotatePM, Tk_WindowId(tkwin), rotateGCXOR, 0, 0, options->width, options->height, dd[0], dd[1]); } ��������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xylex.C������������������������������������������������������������������������0000644�0001750�0001750�00000156232�12032640000�014567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "xylex.C" #line 4 "xylex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer xyFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *xyalloc (yy_size_t ); void *xyrealloc (void *,yy_size_t ); void xyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 61 #define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[197] = { 0, 0, 0, 62, 60, 59, 60, 57, 60, 59, 60, 48, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 58, 57, 0, 48, 50, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 3, 0, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 21, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 51, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 13, 14, 0, 0, 0, 0, 52, 51, 0, 0, 55, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 54, 0, 0, 0, 0, 0, 0, 15, 0, 0, 20, 0, 5, 6, 8, 10, 0, 18, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 9, 10, 11, 12, 13, 14, 12, 12, 12, 15, 16, 6, 1, 1, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 1, 1, 1, 1, 1, 1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[69] = { 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[198] = { 0, 0, 0, 303, 615, 615, 300, 0, 61, 615, 68, 76, 64, 291, 75, 74, 79, 72, 84, 81, 84, 289, 73, 84, 81, 70, 87, 90, 615, 0, 132, 0, 139, 152, 165, 178, 191, 198, 78, 224, 91, 179, 84, 102, 127, 128, 123, 141, 212, 136, 146, 615, 128, 182, 182, 182, 215, 222, 235, 242, 256, 263, 230, 205, 615, 222, 239, 236, 211, 615, 245, 238, 244, 257, 163, 256, 615, 247, 262, 256, 302, 284, 301, 363, 371, 379, 370, 162, 373, 378, 366, 369, 381, 370, 615, 381, 161, 384, 379, 371, 381, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 398, 425, 405, 433, 440, 448, 442, 615, 615, 429, 430, 436, 433, 449, 615, 615, 454, 453, 450, 443, 466, 492, 501, 508, 615, 515, 542, 615, 457, 501, 508, 111, 509, 516, 509, 521, 522, 510, 615, 615, 520, 508, 525, 524, 527, 519, 615, 520, 521, 615, 544, 615, 615, 615, 615, 554, 615, 563, 615, 549, 563, 547, 548, 560, 561, 568, 569, 615, 615, 615, 116 } ; static yyconst flex_int16_t yy_def[198] = { 0, 196, 1, 196, 196, 196, 196, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 196, 11, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 0, 196 } ; static yyconst flex_int16_t yy_nxt[684] = { 0, 4, 5, 6, 7, 8, 9, 8, 10, 11, 11, 11, 11, 11, 11, 11, 4, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 4, 22, 4, 4, 23, 24, 4, 4, 25, 4, 4, 26, 27, 4, 4, 4, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 4, 22, 4, 4, 23, 24, 4, 4, 25, 4, 4, 26, 27, 4, 4, 4, 30, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 31, 31, 31, 31, 31, 31, 31, 34, 38, 40, 41, 35, 36, 42, 43, 37, 44, 45, 46, 49, 52, 50, 53, 54, 55, 62, 64, 67, 47, 51, 68, 69, 29, 170, 38, 40, 41, 35, 36, 42, 43, 37, 44, 45, 46, 49, 52, 50, 53, 54, 55, 62, 64, 67, 47, 51, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 70, 71, 72, 73, 75, 56, 32, 32, 32, 32, 32, 32, 32, 76, 77, 142, 134, 96, 36, 57, 57, 57, 57, 57, 57, 57, 70, 71, 72, 73, 75, 56, 58, 58, 58, 58, 58, 58, 58, 76, 77, 59, 65, 59, 36, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 78, 66, 79, 80, 91, 87, 81, 74, 81, 65, 82, 82, 82, 82, 82, 82, 82, 57, 57, 57, 57, 57, 57, 57, 83, 63, 78, 66, 79, 80, 58, 58, 58, 58, 58, 58, 58, 60, 60, 60, 60, 60, 60, 60, 86, 88, 89, 90, 92, 93, 84, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 94, 95, 97, 98, 99, 86, 88, 89, 90, 92, 93, 84, 100, 85, 82, 82, 82, 82, 82, 82, 82, 48, 39, 28, 196, 196, 94, 95, 97, 98, 99, 82, 82, 82, 82, 82, 82, 82, 100, 85, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 128, 128, 128, 128, 128, 128, 129, 130, 130, 130, 130, 130, 130, 130, 131, 132, 132, 132, 132, 132, 132, 132, 133, 135, 136, 137, 138, 139, 140, 141, 143, 144, 145, 146, 147, 147, 147, 147, 147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 133, 135, 136, 137, 138, 139, 140, 141, 143, 144, 145, 146, 148, 128, 128, 128, 128, 128, 128, 128, 150, 130, 130, 130, 130, 130, 130, 130, 152, 152, 152, 152, 152, 152, 152, 153, 132, 132, 132, 132, 132, 132, 132, 155, 156, 157, 158, 151, 159, 160, 161, 162, 163, 164, 147, 147, 147, 147, 147, 147, 147, 167, 154, 196, 196, 196, 196, 196, 196, 155, 156, 157, 158, 151, 159, 160, 161, 162, 163, 164, 147, 147, 147, 147, 147, 147, 147, 167, 154, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 152, 152, 152, 152, 152, 152, 152, 196, 168, 169, 171, 172, 165, 173, 174, 175, 176, 177, 178, 151, 179, 180, 181, 182, 183, 184, 166, 152, 152, 152, 152, 152, 152, 152, 168, 169, 171, 172, 165, 173, 174, 175, 176, 177, 178, 151, 179, 180, 181, 182, 183, 184, 166, 154, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 154, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 3, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 } ; static yyconst flex_int16_t yy_chk[684] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 14, 15, 11, 11, 16, 17, 11, 18, 19, 20, 22, 24, 23, 25, 26, 27, 38, 40, 42, 20, 23, 43, 43, 197, 158, 12, 14, 15, 11, 11, 16, 17, 11, 18, 19, 20, 22, 24, 23, 25, 26, 27, 38, 40, 42, 20, 23, 30, 30, 30, 30, 30, 30, 30, 32, 32, 32, 32, 32, 32, 32, 44, 45, 46, 47, 49, 32, 33, 33, 33, 33, 33, 33, 33, 50, 52, 96, 87, 74, 33, 34, 34, 34, 34, 34, 34, 34, 44, 45, 46, 47, 49, 32, 35, 35, 35, 35, 35, 35, 35, 50, 52, 36, 41, 36, 33, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 53, 41, 54, 55, 68, 63, 56, 48, 56, 41, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 39, 53, 41, 54, 55, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 62, 65, 66, 67, 70, 71, 58, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 72, 73, 75, 77, 78, 62, 65, 66, 67, 70, 71, 58, 79, 61, 81, 81, 81, 81, 81, 81, 81, 21, 13, 6, 3, 0, 72, 73, 75, 77, 78, 82, 82, 82, 82, 82, 82, 82, 79, 61, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 86, 88, 89, 90, 91, 92, 93, 95, 97, 98, 99, 100, 127, 127, 127, 127, 127, 127, 127, 129, 129, 129, 129, 129, 129, 129, 86, 88, 89, 90, 91, 92, 93, 95, 97, 98, 99, 100, 128, 128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, 132, 132, 132, 132, 133, 136, 137, 138, 130, 139, 140, 143, 144, 145, 146, 147, 147, 147, 147, 147, 147, 147, 155, 132, 0, 0, 0, 0, 0, 0, 133, 136, 137, 138, 130, 139, 140, 143, 144, 145, 146, 148, 148, 148, 148, 148, 148, 148, 155, 132, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, 150, 150, 150, 152, 152, 152, 152, 152, 152, 152, 0, 156, 157, 159, 160, 149, 161, 162, 163, 164, 167, 168, 150, 169, 170, 171, 172, 174, 175, 152, 153, 153, 153, 153, 153, 153, 153, 156, 157, 159, 160, 149, 161, 162, 163, 164, 167, 168, 150, 169, 170, 171, 172, 174, 175, 152, 153, 177, 182, 184, 186, 187, 188, 189, 190, 191, 192, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 177, 182, 184, 186, 187, 188, 189, 190, 191, 192, 193, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "xylex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "xylex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "xyparser.H" extern YYSTYPE* xylval; /* rules */ #line 638 "xylex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 27 "xylex.L" #line 741 "xylex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 197 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 196 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 29 "xylex.L" {return AMPLIFIER_;} YY_BREAK case 2: YY_RULE_SETUP #line 30 "xylex.L" {return B1950_;} YY_BREAK case 3: YY_RULE_SETUP #line 31 "xylex.L" {return CCD_;} YY_BREAK case 4: YY_RULE_SETUP #line 32 "xylex.L" {return DEBUG_;} YY_BREAK case 5: YY_RULE_SETUP #line 33 "xylex.L" {return DETECTOR_;} YY_BREAK case 6: YY_RULE_SETUP #line 34 "xylex.L" {return ECLIPTIC_;} YY_BREAK case 7: YY_RULE_SETUP #line 35 "xylex.L" {return FK4_;} YY_BREAK case 8: YY_RULE_SETUP #line 36 "xylex.L" {return FK4_NO_E_;} YY_BREAK case 9: YY_RULE_SETUP #line 37 "xylex.L" {return FK5_;} YY_BREAK case 10: YY_RULE_SETUP #line 38 "xylex.L" {return GALACTIC_;} YY_BREAK case 11: YY_RULE_SETUP #line 39 "xylex.L" {return HELIOECLIPTIC_;} YY_BREAK case 12: YY_RULE_SETUP #line 40 "xylex.L" {return ICRS_;} YY_BREAK case 13: YY_RULE_SETUP #line 41 "xylex.L" {return IMAGE_;} YY_BREAK case 14: YY_RULE_SETUP #line 42 "xylex.L" {return J2000_;} YY_BREAK case 15: YY_RULE_SETUP #line 43 "xylex.L" {return LOGICAL_;} YY_BREAK case 16: YY_RULE_SETUP #line 44 "xylex.L" {return OFF_;} YY_BREAK case 17: YY_RULE_SETUP #line 45 "xylex.L" {return ON_;} YY_BREAK case 18: YY_RULE_SETUP #line 46 "xylex.L" {return PHYSICAL_;} YY_BREAK case 19: YY_RULE_SETUP #line 47 "xylex.L" {return SUPERGALACTIC_;} YY_BREAK case 20: YY_RULE_SETUP #line 48 "xylex.L" {return VERSION_;} YY_BREAK case 21: YY_RULE_SETUP #line 49 "xylex.L" {return WCS_;} YY_BREAK case 22: YY_RULE_SETUP #line 50 "xylex.L" {return WCSA_;} YY_BREAK case 23: YY_RULE_SETUP #line 51 "xylex.L" {return WCSB_;} YY_BREAK case 24: YY_RULE_SETUP #line 52 "xylex.L" {return WCSC_;} YY_BREAK case 25: YY_RULE_SETUP #line 53 "xylex.L" {return WCSD_;} YY_BREAK case 26: YY_RULE_SETUP #line 54 "xylex.L" {return WCSE_;} YY_BREAK case 27: YY_RULE_SETUP #line 55 "xylex.L" {return WCSF_;} YY_BREAK case 28: YY_RULE_SETUP #line 56 "xylex.L" {return WCSG_;} YY_BREAK case 29: YY_RULE_SETUP #line 57 "xylex.L" {return WCSH_;} YY_BREAK case 30: YY_RULE_SETUP #line 58 "xylex.L" {return WCSI_;} YY_BREAK case 31: YY_RULE_SETUP #line 59 "xylex.L" {return WCSJ_;} YY_BREAK case 32: YY_RULE_SETUP #line 60 "xylex.L" {return WCSK_;} YY_BREAK case 33: YY_RULE_SETUP #line 61 "xylex.L" {return WCSL_;} YY_BREAK case 34: YY_RULE_SETUP #line 62 "xylex.L" {return WCSM_;} YY_BREAK case 35: YY_RULE_SETUP #line 63 "xylex.L" {return WCSN_;} YY_BREAK case 36: YY_RULE_SETUP #line 64 "xylex.L" {return WCSO_;} YY_BREAK case 37: YY_RULE_SETUP #line 65 "xylex.L" {return WCSP_;} YY_BREAK case 38: YY_RULE_SETUP #line 66 "xylex.L" {return WCSQ_;} YY_BREAK case 39: YY_RULE_SETUP #line 67 "xylex.L" {return WCSR_;} YY_BREAK case 40: YY_RULE_SETUP #line 68 "xylex.L" {return WCSS_;} YY_BREAK case 41: YY_RULE_SETUP #line 69 "xylex.L" {return WCST_;} YY_BREAK case 42: YY_RULE_SETUP #line 70 "xylex.L" {return WCSU_;} YY_BREAK case 43: YY_RULE_SETUP #line 71 "xylex.L" {return WCSV_;} YY_BREAK case 44: YY_RULE_SETUP #line 72 "xylex.L" {return WCSW_;} YY_BREAK case 45: YY_RULE_SETUP #line 73 "xylex.L" {return WCSX_;} YY_BREAK case 46: YY_RULE_SETUP #line 74 "xylex.L" {return WCSY_;} YY_BREAK case 47: YY_RULE_SETUP #line 75 "xylex.L" {return WCSZ_;} YY_BREAK case 48: YY_RULE_SETUP #line 77 "xylex.L" { // Integer xylval->integer = atoi(yytext); return INT; } YY_BREAK case 49: #line 83 "xylex.L" case 50: YY_RULE_SETUP #line 83 "xylex.L" { // Real Number xylval->real = atof(yytext); return REAL; } YY_BREAK case 51: #line 89 "xylex.L" case 52: YY_RULE_SETUP #line 89 "xylex.L" { // Sexagesimal int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 53: #line 97 "xylex.L" case 54: YY_RULE_SETUP #line 97 "xylex.L" { // HMS int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return HMSSTR; } YY_BREAK case 55: #line 105 "xylex.L" case 56: YY_RULE_SETUP #line 105 "xylex.L" { // DMS int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return DMSSTR; } YY_BREAK case 57: YY_RULE_SETUP #line 112 "xylex.L" { // comment, eat it } YY_BREAK case 58: /* rule 58 can match eol */ YY_RULE_SETUP #line 115 "xylex.L" { // windows line feed return '\n'; } YY_BREAK case 59: /* rule 59 can match eol */ YY_RULE_SETUP #line 119 "xylex.L" { // special chars return yytext[0]; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 123 "xylex.L" { // eof return EOF_; } YY_BREAK case 60: YY_RULE_SETUP #line 127 "xylex.L" { // Else, eat it } YY_BREAK case 61: YY_RULE_SETUP #line 130 "xylex.L" ECHO; YY_BREAK #line 1148 "xylex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; xyfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); xyfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ xyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) xyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 197 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 197 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 196); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) xyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) xyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) xyfree((void *) b->yy_ch_buf ); xyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)xyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)xyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) xyalloc(new_size ); else (yy_start_stack) = (int *) xyrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *xyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *xyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void xyfree (void * ptr ) { free( (char *) ptr ); /* see xyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 130 "xylex.L" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/marker.h�����������������������������������������������������������������������0000644�0001750�0001750�00000024605�12057220722�014756� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __marker_h__ #define __marker_h__ #include <tk.h> #include "vector.h" #include "vector3d.h" #include "callback.h" #include "list.h" #include "tag.h" #include "coord.h" #include "xml.h" #define POINTSIZE 11 class Base; class FitsImage; class Marker { public: // Select-- user may select the marker // Highlite-- user may highlite the marker // Edit-- user may edit the marker // Move-- user may move the marker // Rotate-- user may rotate the marker // Delete-- user may delete the marker // Fixed-- marker is fixed in size (not scaled based on zoom) // Include-- marker is 'included' or 'excluded' ie '+' or '-' // Source-- marker is a 'source' or 'background' marker // Dash-- render with dashed line enum Property {NONE=0, SELECT=1, HIGHLITE=2, EDIT=4, MOVE=8, ROTATE=16, DELETE=32, FIXED=64, INCLUDE=128, SOURCE=256, DASH=512}; enum RenderMode {SRC,XOR}; enum HandleMode {HANDLES,NOHANDLES}; enum AnalysisTask {STATS,PLOT2D,PLOT3D,RADIAL,PANDA}; enum AnalysisMethod {SUM,AVERAGE}; protected: int id; char type_[64]; Base* parent; Vector center; // ref coordinates BBox bbox; // canvas coordinates BBox allBBox; // canvas coordinates double angle; // radians Vector* handle; // canvas coordinates int numHandle; char* colorName; unsigned long color; int lineWidth; unsigned short properties; int selected; int highlited; float dlist[2]; char* text; Tk_Font tkfont_; Tk_Font psfont_; char* comment; Display* display; GC gc; GC gcxor; int doCB; List<Tag> tags; List<CallBack> callbacks; Marker* previous_; Marker* next_; Vector* arrow(const Vector&, const Vector&, Coord::InternalSystem); char* XMLCol[XMLNUMCOL]; int analysisPlot2d_; static char* analysisPlot2dCB_[]; int analysisPlot3d_; static char* analysisPlot3dCB_[]; int analysisPanda_; static char* analysisPandaCB_[]; int analysisRadial_; static char* analysisRadialCB_[]; int analysisStats_; static char* analysisStatsCB_[]; protected: virtual void renderX(Drawable, Coord::InternalSystem, RenderMode) =0; virtual void renderXInclude(Drawable drawable, Coord::InternalSystem, RenderMode mode); virtual void renderXText(Drawable, Coord::InternalSystem, RenderMode); void renderXArrow(Drawable, const Vector&, const Vector&, Coord::InternalSystem, GC); void renderXHandles(Drawable); virtual GC renderXGC(RenderMode); virtual void renderXLineDash(GC); void renderXLineNoDash(GC); virtual void renderPS(int mode) =0; virtual void renderPSInclude(int); virtual void renderPSText(int); void renderPSArrow(const Vector&, const Vector&, Coord::InternalSystem); virtual void renderPSGC(int); virtual void renderPSLineDash(); void renderPSLineNoDash(); void renderPSColor(int, XColor*); #ifdef _MACOSX virtual void renderMACOSX() =0; virtual void renderMACOSXInclude(); virtual void renderMACOSXText(); void renderMACOSXArrow(const Vector&, const Vector&, Coord::InternalSystem); virtual void renderMACOSXGC(); virtual void renderMACOSXLineDash(); void renderMACOSXLineNoDash(); #endif #ifdef _WIN32 virtual void renderWIN32() =0; virtual void renderWIN32Include(); virtual void renderWIN32Text(); void renderWIN32Arrow(const Vector&, const Vector&, Coord::InternalSystem); virtual void renderWIN32GC(); virtual void renderWIN32LineDash(); void renderWIN32LineNoDash(); #endif void analysisPlot2dResult(char*, char*, char*, char*, double*, double*, double*, double*, int); void analysisPlot3dResult(char*, char*, double*, double*, int); void analysisPandaResult(double*, double*, double*, int); void analysisRadialResult(char*, char*, char*, double*, double*, double*, int); void setMatrices(Coord::InternalSystem, Matrix*, Matrix*); double calcAngle(); Vector modifyArrow(const Vector&, const Vector&, Coord::InternalSystem); virtual void updateHandles() =0; virtual void calcAllBBox(); void initFonts(const char*); void listPre(ostream&, Coord::CoordSystem, Coord::SkyFrame, FitsImage*, int, int); virtual void listPost(ostream&, int, int); void listCiaoPre(ostream&); void listCiaoPost(ostream&, int); void listProsPost(ostream&, int); void listSAOtngPre(ostream&, int); void listSAOtngPost(ostream&, int); void listSAOimagePre(ostream&); void listSAOimagePost(ostream&, int); void listProps(ostream&); void listProperties(ostream&, int); virtual Matrix fwdMatrix(); virtual Matrix bckMatrix(); virtual Vector fwdMap(const Vector&, Coord::InternalSystem); virtual Vector bckMap(const Vector&, Coord::InternalSystem); void XMLRowInit(); void XMLRow(XMLColName,int); void XMLRow(XMLColName,int*,int); void XMLRow(XMLColName,double); void XMLRow(XMLColName,double*,int); void XMLRow(XMLColName,char*); void XMLRow(XMLColName,char**, int); void XMLRowProps(FitsImage*, Coord::CoordSystem); void XMLRowEnd(ostream&); void XMLRowProp(XMLColName, Property); void XMLRowCenter(FitsImage* fits, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) {XMLRowPoint(fits, sys, sky, format, center);} void XMLRowPoint(FitsImage*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Vector); void XMLRowPoint(FitsImage*, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, Vector*, int); void XMLRowRadiusX(FitsImage*, Coord::CoordSystem, Vector); void XMLRowRadiusX(FitsImage*, Coord::CoordSystem, Vector*, int); void XMLRowRadius(FitsImage*, Coord::CoordSystem, Vector); void XMLRowRadius(FitsImage*, Coord::CoordSystem, Vector*, int); void XMLRowAng(Coord::CoordSystem, Coord::SkyFrame); void XMLRowAng(Coord::CoordSystem, Coord::SkyFrame, double*, int); char* XMLQuote(char*); public: Marker(const Marker&); Marker(Base* p, const Vector& v, double ang, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb); virtual ~Marker(); virtual void x11(Drawable, Coord::InternalSystem, int, RenderMode,HandleMode); virtual void ps(int,int); #ifdef _MACOSX virtual void macosx(int); #endif #ifdef _WIN32 virtual void win32(int); #endif virtual Marker* dup() =0; void newIdentity(); virtual void updateBBox(); virtual void updateCoords(const Matrix&); virtual void moveTo(const Vector& v); virtual void moveBegin(); virtual void move(const Vector& v); virtual void moveEnd(); virtual void centroid(); virtual void editBegin(int); virtual void edit(const Vector& v, int h); virtual void editEnd(); virtual void rotateBegin(); virtual void rotate(const Vector& v, int h); virtual void rotateEnd(); virtual int isIn(const Vector& vv) {return bbox.isIn(vv);} virtual int isIn(const Vector& vv, Coord::InternalSystem sys); virtual int isIn(const Vector& vv, Coord::InternalSystem sys, int nn) {return isIn(vv,sys);} virtual int isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa) {return isIn(vv,sys);} void setAngle(double); double getAngle() {return angle;} int getNumHandle() {return numHandle;} Vector getHandle(int); virtual int getSegment(const Vector&) {return 0;} virtual void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int) =0; virtual void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat) {} virtual void listCiao(ostream&, Coord::CoordSystem, int) {} virtual void listSAOtng(ostream&,Coord::CoordSystem,Coord::SkyFrame,Coord::SkyFormat, int) {} virtual void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int) {} virtual void listSAOimage(ostream&, int) {} virtual void listXY(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); const BBox& getBBox() {return bbox;} const BBox& getAllBBox() {return allBBox;} int isVisible(const BBox&); void select(); void unselect(); void toggleSelect(); int isSelected() {return selected;} void highlite(); void unhighlite(); void toggleHighlite(); int isHighlited() {return highlited;} void key(); void setColor(const char*); const char* getColorName() {return colorName;} void setLineWidth(int); int getLineWidth() {return lineWidth;} void setText(const char*); const char* getText() {return text;} void setFont(const char*); const char* getFont(); void addTag(const char*); void editTag(const char*, const char*); void deleteTags(); void deleteTag(int); void deleteTag(const char*); const char* getTag(); const char* getNextTag(); const char* getTag(int); int hasTag(const char*); int onHandle(const Vector& v); int getId() {return id;} const char* getType() {return type_;} Vector getCenter() {return center;} int canSelect() {return (properties & SELECT) ? 1:0;} int canHighlite() {return (properties & HIGHLITE) ? 1:0;} int canEdit() {return (properties & EDIT) ? 1:0;} int canMove() {return (properties & MOVE) ? 1:0;} int canRotate() {return (properties & ROTATE) ? 1:0;} int canDelete() {return (properties & DELETE) ? 1:0;} int isFixed() {return (properties & FIXED) ? 1:0;} void setProperty(unsigned short, int); int getProperty(unsigned short); unsigned short getProperty() {return properties;} int addCallBack(CallBack::Type, const char*, const char*); int deleteCallBack(CallBack::Type, const char*); void deleteCallBack(CallBack::Type); void doCallBack(CallBack::Type); Marker* previous() {return previous_;} void setPrevious(Marker* m) {previous_ = m;} Marker* next() {return next_;} void setNext(Marker* m) {next_ = m;} void enableCB() {doCB = 1;} void disableCB() {doCB = 0;} void deleteCBs(); virtual void analysis(AnalysisTask, int) {} virtual void analysisPanda(Coord::CoordSystem) {} virtual void analysisRadial(char*, char*, char*, Coord::CoordSystem) {} virtual void analysisStats(Coord::CoordSystem) {} virtual void analysisPlot2d(char*, char*, char*, char*, Coord::CoordSystem, Coord::SkyFrame, Marker::AnalysisMethod) {} virtual void analysisPlot3d(char*, char*, Coord::CoordSystem, Marker::AnalysisMethod) {} // special composite funtionality virtual void setComposite(const Matrix&, double); void setComposite(const char*, int, int); }; #endif ���������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue16.h�������������������������������������������������������������0000644�0001750�0001750�00000004610�11700666266�016677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorscaletrue16_h__ #define __colorscaletrue16_h__ #include "colorscale.h" #include "truecolor16.h" class ColorScaleTrueColor16 : public virtual ColorScale, public TrueColor16 { public: ColorScaleTrueColor16(int, Visual*, int); virtual ~ColorScaleTrueColor16(); }; class LinearScaleTrueColor16 : public virtual ColorScale, public LinearScale, public ColorScaleTrueColor16 { public: LinearScaleTrueColor16(int, unsigned short*, unsigned char*, int, Visual*, int); }; class LogScaleTrueColor16 : public virtual ColorScale, public LogScale, public ColorScaleTrueColor16 { public: LogScaleTrueColor16(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class PowScaleTrueColor16 : public virtual ColorScale, public PowScale, public ColorScaleTrueColor16 { public: PowScaleTrueColor16(int, unsigned short*, unsigned char*, int, double, Visual*, int); }; class SqrtScaleTrueColor16 : public virtual ColorScale, public SqrtScale, public ColorScaleTrueColor16 { public: SqrtScaleTrueColor16(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SquaredScaleTrueColor16 : public virtual ColorScale, public SquaredScale, public ColorScaleTrueColor16 { public: SquaredScaleTrueColor16(int, unsigned short*, unsigned char*, int, Visual*, int); }; class AsinhScaleTrueColor16 : public virtual ColorScale, public AsinhScale, public ColorScaleTrueColor16 { public: AsinhScaleTrueColor16(int, unsigned short*, unsigned char*, int, Visual*, int); }; class SinhScaleTrueColor16 : public virtual ColorScale, public SinhScale, public ColorScaleTrueColor16 { public: SinhScaleTrueColor16(int, unsigned short*, unsigned char*, int, Visual*, int); }; class IISScaleTrueColor16 : public virtual ColorScale, public IISScale, public ColorScaleTrueColor16 { public: IISScaleTrueColor16(unsigned short*, unsigned char*, int, Visual*, int); }; class HistEquScaleTrueColor16 : public virtual ColorScale, public HistEquScale, public ColorScaleTrueColor16 { public: HistEquScaleTrueColor16(int, unsigned short*, unsigned char*, int, double*, int, Visual*, int); }; #endif ������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/prosparser.C�������������������������������������������������������������������0000644�0001750�0001750�00000204535�11727715200�015635� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse prosparse #define yylex proslex #define yyerror proserror #define yylval proslval #define yychar proschar #define yydebug prosdebug #define yynerrs prosnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, ANGDEGREE = 261, ARCMINUTE = 262, ARCSECOND = 263, ANGRADIAN = 264, SEXSTR = 265, HMSSTR = 266, DMSSTR = 267, EOF_ = 268, ANNULUS_ = 269, B1950_ = 270, BOX_ = 271, CIRCLE_ = 272, DEBUG_ = 273, ECLIPTIC_ = 274, ELLIPSE_ = 275, EQUATORIAL_ = 276, GALACTIC_ = 277, J2000_ = 278, LOGICAL_ = 279, N_ = 280, OFF_ = 281, ON_ = 282, PHYSICAL_ = 283, POINT_ = 284, POLYGON_ = 285, ROTBOX_ = 286, VERSION_ = 287 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define ANGDEGREE 261 #define ARCMINUTE 262 #define ARCSECOND 263 #define ANGRADIAN 264 #define SEXSTR 265 #define HMSSTR 266 #define DMSSTR 267 #define EOF_ 268 #define ANNULUS_ 269 #define B1950_ 270 #define BOX_ 271 #define CIRCLE_ 272 #define DEBUG_ 273 #define ECLIPTIC_ 274 #define ELLIPSE_ 275 #define EQUATORIAL_ 276 #define GALACTIC_ 277 #define J2000_ 278 #define LOGICAL_ 279 #define N_ 280 #define OFF_ 281 #define ON_ 282 #define PHYSICAL_ 283 #define POINT_ 284 #define POLYGON_ 285 #define ROTBOX_ 286 #define VERSION_ 287 /* Copy the first part of user declarations. */ #line 10 "prosparser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; prosDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer prosFlexLexer #include <FlexLexer.h> extern int proslex(void*, prosFlexLexer*); extern void proserror(Base*, prosFlexLexer*, const char*); extern void prosDiscard(int); static Coord::CoordSystem globalSystem; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static unsigned short globalProps; static unsigned short localProps; static char *color = "green"; static int dash[] ={8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aStatus; static Vector aCenter; static double aAngle; static unsigned short aProps; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 65 "prosparser.Y" { #define PROSBUFSIZE 2048 double real; int integer; char str[PROSBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 231 "prosparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 244 "prosparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 215 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 44 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 41 /* YYNRULES -- Number of rules. */ #define YYNRULES 90 /* YYNRULES -- Number of states. */ #define YYNSTATES 187 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 287 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 2, 43, 2, 2, 41, 2, 36, 37, 2, 39, 35, 40, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 2, 38, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 7, 11, 14, 15, 18, 20, 21, 25, 26, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 64, 66, 68, 70, 72, 74, 76, 80, 84, 88, 92, 96, 98, 100, 102, 106, 110, 114, 118, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141, 142, 143, 144, 146, 148, 156, 166, 167, 180, 192, 202, 221, 231, 241, 260, 266, 267, 274, 278, 280, 282, 286, 288, 290, 291, 292, 293, 297, 298, 302, 304, 305 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 45, 0, -1, 68, 46, 78, -1, 46, 47, 50, -1, 47, 50, -1, -1, 18, 52, -1, 32, -1, -1, 65, 48, 79, -1, -1, 66, 49, 79, -1, 69, 70, 71, -1, 81, -1, 33, -1, 34, -1, 13, -1, 4, -1, 3, -1, 27, -1, 26, -1, -1, 35, -1, -1, 36, -1, -1, 37, -1, -1, 57, -1, 51, -1, 6, -1, 9, -1, 51, -1, 6, -1, 7, -1, 8, -1, 51, 53, 51, -1, 6, 53, 6, -1, 7, 53, 7, -1, 8, 53, 8, -1, 25, 38, 3, -1, 10, -1, 11, -1, 12, -1, 61, 53, 61, -1, 62, 53, 63, -1, 63, 53, 63, -1, 51, 53, 51, -1, 6, 53, 6, -1, 24, -1, 28, -1, 21, 67, -1, 15, -1, 23, -1, 22, -1, 19, -1, 15, -1, 23, -1, -1, -1, -1, 39, -1, 40, -1, 17, 54, 64, 53, 58, 55, 83, -1, 14, 54, 64, 53, 58, 53, 58, 55, 83, -1, -1, 14, 54, 64, 53, 58, 53, 58, 53, 72, 76, 55, 83, -1, 14, 54, 64, 53, 58, 53, 58, 53, 60, 55, 83, -1, 20, 54, 64, 53, 59, 53, 56, 55, 83, -1, 20, 54, 64, 53, 59, 53, 56, 55, 41, 42, 20, 54, 64, 53, 59, 53, 56, 55, -1, 16, 54, 64, 53, 59, 53, 56, 55, 83, -1, 31, 54, 64, 53, 59, 53, 56, 55, 83, -1, 16, 54, 64, 53, 59, 53, 56, 55, 41, 42, 16, 54, 64, 53, 59, 53, 56, 55, -1, 29, 54, 64, 55, 83, -1, -1, 30, 73, 54, 74, 55, 83, -1, 74, 53, 75, -1, 75, -1, 64, -1, 76, 53, 77, -1, 77, -1, 58, -1, -1, -1, -1, 43, 80, 5, -1, -1, 43, 82, 5, -1, 78, -1, -1, 43, 84, 5, 78, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 125, 125, 128, 129, 132, 133, 134, 135, 135, 136, 136, 137, 138, 141, 142, 143, 146, 147, 150, 151, 154, 155, 158, 159, 162, 163, 166, 167, 170, 171, 172, 175, 176, 177, 178, 181, 188, 195, 202, 211, 214, 217, 220, 223, 236, 244, 252, 259, 269, 270, 273, 274, 275, 276, 277, 280, 281, 284, 295, 307, 308, 309, 313, 317, 321, 321, 330, 335, 351, 358, 374, 379, 386, 390, 390, 395, 396, 399, 402, 403, 406, 410, 437, 438, 438, 441, 441, 444, 445, 445 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "STRING", "ANGDEGREE", "ARCMINUTE", "ARCSECOND", "ANGRADIAN", "SEXSTR", "HMSSTR", "DMSSTR", "EOF_", "ANNULUS_", "B1950_", "BOX_", "CIRCLE_", "DEBUG_", "ECLIPTIC_", "ELLIPSE_", "EQUATORIAL_", "GALACTIC_", "J2000_", "LOGICAL_", "N_", "OFF_", "ON_", "PHYSICAL_", "POINT_", "POLYGON_", "ROTBOX_", "VERSION_", "'\\n'", "';'", "','", "'('", "')'", "'='", "'+'", "'-'", "'&'", "'!'", "'#'", "$accept", "start", "commands", "command", "@1", "@2", "terminator", "numeric", "debug", "sp", "bp", "ep", "optangle", "angle", "value", "vvalue", "numberof", "sexagesimal", "hms", "dms", "coord", "coordSystem", "skyFrame", "equatorial", "initGlobal", "initLocal", "include", "shape", "@3", "@4", "polyNodes", "polyNode", "aRads", "aRad", "processAnnulus", "comment", "@5", "generalComment", "@6", "shapeComment", "@7", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 10, 59, 44, 40, 41, 61, 43, 45, 38, 33, 35 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 44, 45, 46, 46, 47, 47, 47, 48, 47, 49, 47, 47, 47, 50, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 65, 65, 66, 66, 66, 66, 66, 67, 67, 68, 69, 70, 70, 70, 71, 71, 72, 71, 71, 71, 71, 71, 71, 71, 71, 73, 71, 74, 74, 75, 76, 76, 77, 78, 79, 80, 79, 82, 81, 83, 84, 83 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 3, 2, 0, 2, 1, 0, 3, 0, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 7, 9, 0, 12, 11, 9, 18, 9, 9, 18, 5, 0, 6, 3, 1, 1, 3, 1, 1, 0, 0, 0, 3, 0, 3, 1, 0, 4 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 58, 0, 59, 1, 52, 0, 55, 0, 54, 53, 49, 50, 7, 86, 59, 0, 8, 10, 60, 13, 20, 19, 6, 56, 57, 51, 0, 0, 2, 16, 14, 15, 4, 83, 83, 61, 62, 0, 87, 3, 84, 9, 11, 23, 23, 23, 23, 23, 74, 23, 12, 0, 24, 0, 0, 0, 0, 0, 23, 0, 85, 18, 17, 21, 41, 42, 43, 21, 21, 21, 21, 21, 21, 21, 21, 25, 0, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 82, 78, 21, 77, 0, 48, 47, 44, 45, 46, 33, 34, 35, 32, 21, 21, 21, 21, 21, 21, 25, 21, 89, 88, 73, 0, 82, 21, 0, 0, 0, 0, 0, 27, 82, 27, 0, 76, 75, 27, 21, 37, 38, 39, 36, 30, 31, 29, 25, 28, 63, 25, 82, 25, 65, 82, 82, 82, 90, 82, 0, 25, 0, 64, 0, 70, 0, 68, 71, 0, 82, 81, 21, 80, 0, 0, 40, 67, 0, 82, 23, 23, 79, 66, 0, 0, 21, 21, 0, 0, 21, 21, 27, 27, 25, 25, 72, 69 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 14, 15, 33, 34, 32, 67, 22, 79, 53, 89, 137, 138, 160, 108, 150, 68, 69, 70, 90, 16, 17, 25, 2, 18, 37, 50, 151, 58, 91, 92, 161, 162, 112, 41, 51, 19, 26, 113, 125 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -92 static const yytype_int16 yypact[] = { -92, 2, 163, -92, -92, 17, -92, 19, -92, -92, -92, -92, -92, -92, 132, 7, -92, -92, 6, -92, -92, -92, -92, -92, -92, -92, 13, 7, -92, -92, -92, -92, -92, -36, -36, -92, -92, 72, -92, -92, -92, -92, -92, 12, 12, 12, 12, 12, -92, 12, -92, 48, -92, 197, 197, 197, 197, 197, 12, 197, -92, -92, -92, 32, -92, -92, -92, 32, 32, 32, 32, 32, 32, 32, 32, 33, 197, 32, -92, 63, 52, 65, 61, 61, 118, 207, 118, 207, -92, 40, -92, 155, -92, 207, -92, -92, -92, -92, -92, -92, -92, -92, -92, 32, 32, 32, 32, 32, 32, 33, 32, -92, -92, -92, 197, 40, 32, 118, 90, 91, 89, 52, 102, 40, 102, 105, -92, -92, 102, 155, -92, -92, -92, -92, -92, -92, -92, 33, -92, -92, 33, -92, 33, 82, 40, -19, -5, -92, 40, 74, 33, 118, -92, 73, -92, 75, -92, -92, 115, 40, -92, 155, -92, 107, 116, -92, -92, 118, 40, 12, 12, -92, -92, 197, 197, 32, 32, 207, 207, 32, 32, 102, 102, 33, 33, -92, -92 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -92, -92, -92, 121, -92, -92, 112, -8, -92, -42, -41, -90, -91, -92, -63, -78, -92, 59, -92, -25, -43, -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, 27, -92, -23, -14, 108, -92, -92, -92, -64, -92 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -83 static const yytype_int16 yytable[] = { 28, 115, 3, 54, 55, 56, 57, 40, 59, 110, 71, 72, 73, 74, 75, 116, 77, 76, 38, 123, 29, 103, 153, 109, 111, 80, 81, 82, 83, 84, 85, 86, 87, 140, 23, 93, 155, 142, 111, 144, 30, 31, 24, 20, 21, 35, 36, 145, 52, 114, 146, 127, 148, 60, 129, 61, 62, 97, 98, 139, 159, 117, 118, 119, 120, 121, 122, 78, 124, 94, 88, 168, 95, 66, 128, 64, 102, 107, 102, 107, 152, 154, 156, 111, 157, 107, 43, 143, 44, 45, 183, 184, 46, 185, 186, 166, 130, 132, 131, 179, 180, 47, 48, 49, 172, 61, 62, 149, 134, 102, 141, 135, 158, 133, 136, 163, 136, 164, 165, 167, 136, 61, 62, 169, 99, 100, 101, 147, 173, 174, 175, 176, -82, 177, 178, 27, 170, 181, 182, 39, 96, 126, 42, 102, 171, -5, 0, 4, 0, 0, 5, 6, 0, 7, 8, 9, 10, 0, 0, 102, 11, 0, 0, 0, 12, -5, -5, 0, -25, 107, 107, 0, 0, 136, 136, 13, -5, 0, 4, 0, 0, 5, 6, 0, 7, 8, 9, 10, -25, -25, 78, 11, 88, 0, 0, 12, -5, -5, -25, 0, 61, 62, 0, 63, 0, 0, 13, 64, 65, 66, 61, 62, 0, 104, 105, 106 }; static const yytype_int16 yycheck[] = { 14, 91, 0, 44, 45, 46, 47, 43, 49, 87, 53, 54, 55, 56, 57, 93, 59, 58, 5, 109, 13, 84, 41, 86, 43, 67, 68, 69, 70, 71, 72, 73, 74, 124, 15, 77, 41, 128, 43, 129, 33, 34, 23, 26, 27, 39, 40, 137, 36, 91, 140, 115, 142, 5, 117, 3, 4, 82, 83, 123, 150, 103, 104, 105, 106, 107, 108, 35, 110, 6, 37, 161, 80, 12, 116, 10, 84, 85, 86, 87, 144, 145, 146, 43, 148, 93, 14, 129, 16, 17, 181, 182, 20, 183, 184, 159, 6, 8, 7, 177, 178, 29, 30, 31, 168, 3, 4, 25, 6, 117, 5, 9, 38, 121, 122, 42, 124, 42, 3, 161, 128, 3, 4, 16, 6, 7, 8, 141, 169, 170, 173, 174, 0, 175, 176, 14, 20, 179, 180, 27, 81, 114, 34, 151, 167, 13, -1, 15, -1, -1, 18, 19, -1, 21, 22, 23, 24, -1, -1, 167, 28, -1, -1, -1, 32, 33, 34, -1, 13, 177, 178, -1, -1, 181, 182, 43, 13, -1, 15, -1, -1, 18, 19, -1, 21, 22, 23, 24, 33, 34, 35, 28, 37, -1, -1, 32, 33, 34, 43, -1, 3, 4, -1, 6, -1, -1, 43, 10, 11, 12, 3, 4, -1, 6, 7, 8 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 45, 68, 0, 15, 18, 19, 21, 22, 23, 24, 28, 32, 43, 46, 47, 65, 66, 69, 81, 26, 27, 52, 15, 23, 67, 82, 47, 78, 13, 33, 34, 50, 48, 49, 39, 40, 70, 5, 50, 43, 79, 79, 14, 16, 17, 20, 29, 30, 31, 71, 80, 36, 54, 54, 54, 54, 54, 73, 54, 5, 3, 4, 6, 10, 11, 12, 51, 61, 62, 63, 64, 64, 64, 64, 64, 54, 64, 35, 53, 53, 53, 53, 53, 53, 53, 53, 53, 37, 55, 64, 74, 75, 53, 6, 51, 61, 63, 63, 6, 7, 8, 51, 58, 6, 7, 8, 51, 59, 58, 59, 43, 78, 83, 53, 55, 59, 53, 53, 53, 53, 53, 53, 55, 53, 84, 75, 83, 53, 58, 6, 7, 8, 51, 6, 9, 51, 56, 57, 83, 56, 5, 56, 53, 55, 55, 55, 78, 55, 25, 60, 72, 83, 41, 83, 41, 83, 83, 38, 55, 58, 76, 77, 42, 42, 3, 83, 53, 55, 16, 20, 77, 83, 54, 54, 64, 64, 53, 53, 59, 59, 53, 53, 56, 56, 55, 55 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, prosFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; prosFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, prosFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; prosFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, prosFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; prosFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, prosFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; prosFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, prosFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, prosFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; prosFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 7: #line 134 "prosparser.Y" {cerr << "PROS" << endl;;} break; case 8: #line 135 "prosparser.Y" {globalSystem = (Coord::CoordSystem)(yyvsp[(1) - (1)].integer);;} break; case 10: #line 136 "prosparser.Y" {globalSystem = Coord::WCS; globalSky = (Coord::SkyFrame)(yyvsp[(1) - (1)].integer);;} break; case 16: #line 143 "prosparser.Y" {YYACCEPT;;} break; case 17: #line 146 "prosparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 18: #line 147 "prosparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 19: #line 150 "prosparser.Y" {yydebug=1;;} break; case 20: #line 151 "prosparser.Y" {yydebug=0;;} break; case 27: #line 166 "prosparser.Y" {(yyval.real) = 0;;} break; case 28: #line 167 "prosparser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 29: #line 170 "prosparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 30: #line 171 "prosparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 31: #line 172 "prosparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 32: #line 175 "prosparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::IMAGE);;} break; case 33: #line 176 "prosparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::DEGREE);;} break; case 34: #line 177 "prosparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::ARCMIN);;} break; case 35: #line 178 "prosparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), checkWCSSystem(), Coord::ARCSEC);;} break; case 36: #line 182 "prosparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 37: #line 189 "prosparser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::DEGREE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 38: #line 196 "prosparser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::ARCMIN); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 39: #line 203 "prosparser.Y" { Vector r=FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)),checkWCSSystem(),Coord::ARCSEC); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 40: #line 211 "prosparser.Y" {(yyval.integer) = (yyvsp[(3) - (3)].integer);;} break; case 41: #line 214 "prosparser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 42: #line 217 "prosparser.Y" {(yyval.real) = parseHMSStr((yyvsp[(1) - (1)].str));;} break; case 43: #line 220 "prosparser.Y" {(yyval.real) = parseDMSStr((yyvsp[(1) - (1)].str));;} break; case 44: #line 224 "prosparser.Y" { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), sys, sky); else r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real)*360./24.,(yyvsp[(3) - (3)].real)), sys, sky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 45: #line 237 "prosparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 46: #line 245 "prosparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 47: #line 253 "prosparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), localSystem, localSky); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 48: #line 260 "prosparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), checkWCSSystem(), checkWCSSky()); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 49: #line 269 "prosparser.Y" {(yyval.integer) = Coord::IMAGE;;} break; case 50: #line 270 "prosparser.Y" {(yyval.integer) = Coord::PHYSICAL;;} break; case 51: #line 273 "prosparser.Y" {(yyval.integer) = (yyvsp[(2) - (2)].integer);;} break; case 52: #line 274 "prosparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 53: #line 275 "prosparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 54: #line 276 "prosparser.Y" {(yyval.integer) = Coord::GALACTIC;;} break; case 55: #line 277 "prosparser.Y" {(yyval.integer) = Coord::ECLIPTIC;;} break; case 56: #line 280 "prosparser.Y" {(yyval.integer) = Coord::FK4;;} break; case 57: #line 281 "prosparser.Y" {(yyval.integer) = Coord::FK5;;} break; case 58: #line 284 "prosparser.Y" { // global properties globalSystem = Coord::IMAGE; globalSky = Coord::FK5; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; ;} break; case 59: #line 295 "prosparser.Y" { // reset maperr flag maperr =0; // global properties localSystem = globalSystem; localSky = globalSky; localProps = globalProps; strcpy(localComment,""); ;} break; case 60: #line 307 "prosparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 61: #line 308 "prosparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 62: #line 309 "prosparser.Y" {setProps(&localProps, Marker::INCLUDE, 0);;} break; case 63: #line 314 "prosparser.Y" {fr->createCircleCmd(Vector((yyvsp[(3) - (7)].vector)), (yyvsp[(5) - (7)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 64: #line 318 "prosparser.Y" {fr->createAnnulusCmd(Vector((yyvsp[(3) - (9)].vector)), (yyvsp[(5) - (9)].real),(yyvsp[(7) - (9)].real),1, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 65: #line 321 "prosparser.Y" {aNum=2;;} break; case 66: #line 323 "prosparser.Y" { aAnnuli[0] = (yyvsp[(5) - (12)].real); aAnnuli[1] = (yyvsp[(7) - (12)].real); fr->createAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), aNum,aAnnuli, color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 67: #line 331 "prosparser.Y" {fr->createAnnulusCmd(Vector((yyvsp[(3) - (11)].vector)), (yyvsp[(5) - (11)].real),(yyvsp[(7) - (11)].real),(yyvsp[(9) - (11)].integer), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 68: #line 336 "prosparser.Y" { // for ellipse annulus aStatus = 1; aCenter = Vector((yyvsp[(3) - (9)].vector)); aAngle = (yyvsp[(7) - (9)].real); aVector[0] = Vector((yyvsp[(5) - (9)].vector)); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 69: #line 353 "prosparser.Y" { aStatus = 2; aVector[aNum++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 70: #line 359 "prosparser.Y" { // for box annulus aStatus = 3; aCenter = Vector((yyvsp[(3) - (9)].vector)); aAngle = (yyvsp[(7) - (9)].real); aVector[0] = Vector((yyvsp[(5) - (9)].vector)); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 71: #line 375 "prosparser.Y" {fr->createBoxCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 72: #line 381 "prosparser.Y" { aStatus = 4; aVector[aNum++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 73: #line 387 "prosparser.Y" {fr->createPointCmd(Vector((yyvsp[(3) - (5)].vector)), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 74: #line 390 "prosparser.Y" {polylist.deleteAll();;} break; case 75: #line 391 "prosparser.Y" {fr->createPolygonCmd(polylist, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 78: #line 399 "prosparser.Y" {polylist.append(new Vertex((yyvsp[(1) - (1)].vector)));;} break; case 81: #line 406 "prosparser.Y" {aAnnuli[aNum++] = (yyvsp[(1) - (1)].real);;} break; case 82: #line 410 "prosparser.Y" { switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; } aStatus = 0; ;} break; case 84: #line 438 "prosparser.Y" {DISCARD_(1);} break; case 86: #line 441 "prosparser.Y" {DISCARD_(1);} break; case 89: #line 445 "prosparser.Y" {DISCARD_(0);} break; case 90: #line 446 "prosparser.Y" {strncpy(localComment,(yyvsp[(3) - (4)].str),80);;} break; /* Line 1267 of yacc.c. */ #line 2090 "prosparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 449 "prosparser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/vect.h�������������������������������������������������������������������������0000644�0001750�0001750�00000002353�11727715200�014435� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __vect_h__ #define __vect_h__ #include "line.h" class Vect : public Line { public: Vect(Base* p, const Vector& ptr1, const Vector& ptr2, int arr, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Vect(Base* p, const Vector& pt, double mag, double ang, int arr, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); virtual Marker* dup() {return new Vect(*this);} int getArrow() {return p2Arrow;} void setArrow(int w) {p2Arrow = w ? 1 : 0;} void setPoints(const Vector& pt, double mag, double ang); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int) {} }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/tnglex.C�����������������������������������������������������������������������0000644�0001750�0001750�00000200446�12032640000�014714� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "tnglex.C" #line 4 "tnglex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer tngFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *tngalloc (yy_size_t ); void *tngrealloc (void *,yy_size_t ); void tngfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 57 #define YY_END_OF_BUFFER 58 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[250] = { 0, 0, 0, 2, 2, 58, 56, 52, 55, 56, 56, 56, 56, 56, 41, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 56, 56, 2, 1, 52, 53, 0, 48, 0, 49, 0, 41, 43, 42, 41, 0, 51, 44, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 29, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 54, 0, 50, 2, 44, 0, 45, 0, 0, 0, 42, 51, 51, 51, 51, 5, 51, 51, 51, 51, 51, 51, 51, 51, 16, 18, 51, 51, 51, 51, 23, 51, 51, 51, 51, 28, 51, 51, 51, 51, 34, 51, 51, 51, 51, 51, 51, 42, 0, 43, 0, 51, 51, 51, 7, 51, 9, 10, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 24, 51, 26, 51, 51, 51, 51, 51, 51, 51, 37, 51, 51, 51, 0, 46, 3, 51, 6, 51, 11, 51, 51, 51, 51, 0, 51, 51, 21, 51, 25, 51, 51, 51, 32, 51, 51, 51, 51, 39, 51, 47, 46, 51, 8, 51, 51, 51, 51, 0, 19, 51, 51, 51, 51, 31, 51, 35, 51, 51, 40, 51, 12, 51, 13, 51, 0, 51, 51, 27, 51, 33, 51, 38, 51, 14, 15, 17, 20, 51, 30, 51, 51, 51, 51, 4, 51, 51, 51, 51, 51, 51, 22, 36, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 1, 1, 6, 1, 1, 1, 7, 1, 8, 9, 1, 10, 11, 12, 13, 14, 15, 13, 13, 13, 16, 17, 1, 1, 1, 1, 1, 1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 34, 1, 43, 1, 1, 1, 1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 34, 60, 61, 62, 63, 64, 65, 66, 67, 34, 68, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[70] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1 } ; static yyconst flex_int16_t yy_base[257] = { 0, 0, 0, 210, 208, 195, 1179, 187, 1179, 164, 155, 133, 61, 68, 76, 85, 90, 86, 87, 97, 104, 124, 148, 120, 137, 138, 154, 152, 168, 164, 165, 170, 193, 182, 199, 87, 58, 0, 1179, 118, 1179, 111, 1179, 109, 1179, 224, 239, 184, 221, 279, 260, 171, 205, 321, 208, 293, 302, 300, 248, 298, 288, 334, 249, 289, 338, 345, 339, 340, 354, 361, 364, 363, 377, 374, 368, 380, 250, 379, 392, 398, 405, 402, 395, 421, 425, 430, 426, 1179, 42, 1179, 0, 1179, 456, 1179, 481, 463, 488, 496, 442, 505, 506, 507, 268, 508, 510, 521, 522, 523, 525, 527, 528, 428, 305, 540, 547, 564, 554, 432, 557, 578, 575, 581, 585, 590, 591, 600, 602, 605, 607, 611, 618, 628, 621, 623, 660, 680, 687, 695, 637, 632, 703, 644, 704, 651, 668, 705, 706, 707, 708, 717, 94, 718, 729, 730, 728, 670, 733, 735, 747, 754, 756, 759, 760, 772, 773, 774, 786, 792, 785, 812, 835, 788, 820, 790, 843, 822, 844, 825, 847, 850, 118, 860, 861, 854, 864, 865, 867, 879, 884, 886, 896, 893, 897, 900, 902, 909, 923, 949, 934, 907, 933, 931, 958, 959, 102, 935, 961, 962, 968, 979, 964, 986, 981, 982, 993, 984, 1002, 1005, 1011, 1012, 1016, 360, 1025, 1018, 1027, 1032, 1037, 1039, 1042, 1043, 1046, 1049, 1179, 1053, 1058, 1060, 1063, 1069, 1076, 1079, 1074, 1080, 1086, 1089, 1095, 1109, 1110, 1096, 1105, 1179, 1156, 1160, 1164, 1166, 1170, 1174, 96 } ; static yyconst flex_int16_t yy_def[257] = { 0, 249, 1, 250, 250, 249, 249, 249, 249, 249, 251, 252, 249, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 254, 255, 249, 249, 249, 251, 249, 252, 249, 249, 249, 256, 256, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 254, 249, 255, 249, 249, 249, 249, 249, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 249, 249, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 249, 253, 253, 253, 253, 253, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 249, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 0, 249, 249, 249, 249, 249, 249, 249 } ; static yyconst flex_int16_t yy_nxt[1249] = { 0, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14, 6, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 15, 25, 26, 15, 27, 28, 15, 29, 30, 31, 15, 32, 33, 15, 34, 35, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 15, 25, 26, 15, 27, 28, 29, 30, 31, 15, 32, 33, 15, 34, 36, 6, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 48, 49, 49, 49, 49, 49, 49, 49, 50, 249, 249, 249, 52, 53, 249, 47, 54, 249, 249, 249, 60, 249, 249, 55, 61, 221, 89, 58, 249, 249, 44, 42, 62, 87, 56, 39, 249, 57, 52, 53, 180, 63, 89, 59, 249, 64, 60, 65, 249, 55, 61, 66, 249, 58, 44, 71, 249, 67, 62, 87, 56, 249, 249, 57, 72, 204, 180, 63, 59, 249, 249, 64, 249, 65, 68, 42, 249, 66, 249, 73, 249, 71, 40, 67, 249, 69, 249, 74, 249, 249, 75, 204, 249, 70, 249, 249, 249, 249, 76, 68, 249, 80, 249, 249, 39, 73, 249, 83, 77, 78, 249, 69, 81, 74, 249, 79, 75, 249, 82, 70, 93, 94, 85, 249, 76, 249, 38, 80, 38, 249, 84, 249, 249, 83, 77, 78, 86, 249, 81, 98, 249, 79, 249, 82, 249, 249, 93, 94, 85, 47, 47, 47, 47, 47, 47, 47, 84, 91, 92, 249, 249, 249, 86, 48, 46, 46, 46, 46, 46, 46, 46, 50, 249, 249, 249, 91, 92, 249, 249, 249, 249, 249, 249, 91, 92, 95, 95, 95, 95, 95, 95, 95, 249, 108, 249, 249, 249, 249, 103, 249, 249, 91, 92, 48, 49, 49, 49, 49, 49, 49, 49, 50, 249, 249, 249, 52, 53, 249, 249, 108, 249, 249, 249, 103, 249, 249, 249, 249, 99, 249, 249, 104, 249, 109, 249, 100, 249, 249, 249, 249, 105, 52, 53, 96, 96, 249, 97, 97, 97, 97, 97, 97, 97, 249, 99, 101, 102, 104, 249, 109, 249, 100, 249, 249, 249, 105, 249, 249, 106, 249, 249, 249, 249, 107, 111, 112, 249, 249, 249, 249, 101, 102, 110, 249, 114, 249, 249, 249, 249, 113, 249, 115, 249, 249, 106, 249, 249, 232, 249, 107, 249, 249, 119, 249, 249, 116, 249, 121, 110, 249, 114, 249, 249, 118, 113, 117, 249, 115, 122, 249, 120, 249, 249, 232, 249, 249, 249, 249, 249, 249, 249, 116, 249, 121, 249, 249, 123, 249, 118, 125, 117, 127, 126, 129, 122, 249, 120, 249, 124, 249, 249, 150, 249, 249, 249, 128, 249, 249, 249, 249, 249, 123, 249, 249, 249, 125, 249, 127, 126, 129, 133, 132, 138, 124, 249, 131, 249, 130, 96, 96, 128, 134, 134, 134, 134, 134, 134, 134, 95, 95, 95, 95, 95, 95, 95, 137, 133, 132, 249, 249, 131, 249, 130, 135, 135, 249, 136, 136, 136, 136, 136, 136, 136, 134, 134, 134, 134, 134, 134, 134, 249, 97, 97, 97, 97, 97, 97, 97, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 140, 249, 142, 141, 249, 249, 249, 139, 249, 249, 249, 249, 249, 249, 249, 143, 249, 144, 249, 249, 249, 249, 249, 249, 149, 147, 140, 148, 142, 141, 249, 249, 146, 139, 145, 249, 249, 249, 249, 152, 249, 143, 249, 144, 151, 249, 249, 249, 249, 249, 149, 147, 249, 148, 154, 249, 249, 146, 249, 145, 153, 249, 156, 249, 249, 152, 249, 155, 249, 249, 151, 157, 249, 249, 249, 249, 249, 158, 249, 249, 154, 249, 249, 249, 249, 249, 153, 160, 249, 249, 249, 249, 155, 249, 249, 249, 249, 157, 249, 249, 159, 249, 249, 158, 249, 161, 249, 164, 249, 249, 249, 249, 249, 160, 249, 249, 163, 249, 162, 249, 249, 171, 249, 249, 249, 159, 168, 249, 249, 165, 172, 161, 167, 164, 249, 249, 249, 249, 166, 249, 249, 163, 249, 162, 134, 134, 134, 134, 134, 134, 134, 249, 168, 249, 165, 249, 172, 167, 249, 249, 249, 249, 249, 166, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 169, 170, 170, 170, 170, 170, 170, 170, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 176, 175, 249, 173, 249, 174, 249, 249, 181, 249, 249, 249, 177, 178, 249, 185, 249, 249, 249, 249, 179, 182, 249, 249, 249, 249, 176, 175, 249, 173, 249, 174, 184, 183, 181, 249, 249, 249, 177, 178, 249, 249, 249, 249, 249, 249, 179, 182, 249, 249, 186, 249, 187, 249, 249, 249, 190, 188, 184, 183, 249, 249, 249, 249, 191, 249, 249, 249, 189, 249, 249, 249, 249, 249, 249, 249, 186, 249, 187, 249, 192, 249, 190, 188, 193, 249, 194, 249, 249, 195, 191, 249, 249, 189, 196, 196, 196, 196, 196, 196, 196, 249, 249, 249, 249, 192, 249, 249, 249, 249, 193, 249, 194, 249, 249, 195, 197, 170, 170, 170, 170, 170, 170, 170, 249, 249, 249, 198, 249, 249, 249, 249, 249, 249, 201, 249, 249, 199, 200, 249, 203, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 198, 249, 249, 202, 249, 249, 207, 201, 249, 249, 249, 199, 200, 249, 203, 249, 249, 205, 206, 209, 249, 249, 249, 249, 208, 249, 249, 249, 202, 249, 249, 249, 207, 249, 249, 212, 249, 249, 249, 249, 210, 213, 205, 206, 249, 209, 249, 249, 211, 208, 249, 249, 214, 196, 196, 196, 196, 196, 196, 196, 249, 212, 249, 249, 249, 210, 249, 213, 249, 215, 249, 249, 249, 249, 211, 249, 249, 218, 214, 196, 196, 196, 196, 196, 196, 196, 216, 249, 249, 217, 249, 249, 249, 249, 215, 249, 249, 249, 249, 249, 219, 249, 223, 218, 249, 249, 224, 222, 249, 220, 249, 249, 216, 249, 217, 249, 249, 225, 249, 249, 227, 249, 249, 249, 249, 249, 219, 249, 223, 249, 249, 249, 224, 222, 249, 220, 249, 226, 249, 249, 249, 249, 249, 225, 228, 249, 227, 249, 249, 249, 249, 230, 249, 249, 249, 249, 249, 249, 231, 249, 229, 249, 249, 226, 249, 233, 249, 234, 249, 249, 228, 249, 249, 249, 249, 249, 249, 230, 249, 249, 249, 235, 249, 249, 231, 229, 249, 249, 236, 249, 249, 233, 249, 234, 237, 249, 249, 249, 249, 249, 249, 239, 249, 249, 238, 249, 249, 235, 249, 249, 240, 249, 249, 249, 236, 249, 249, 249, 249, 242, 237, 249, 249, 249, 249, 249, 249, 239, 249, 241, 238, 249, 249, 249, 249, 245, 240, 243, 249, 249, 249, 246, 249, 244, 249, 242, 249, 249, 249, 247, 248, 249, 249, 249, 249, 241, 249, 249, 249, 249, 249, 245, 243, 249, 249, 249, 249, 246, 244, 249, 249, 249, 249, 249, 249, 247, 248, 37, 37, 37, 37, 41, 249, 41, 41, 43, 249, 43, 43, 51, 51, 88, 249, 88, 88, 90, 249, 90, 90, 5, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249 } ; static yyconst flex_int16_t yy_chk[1249] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 17, 18, 14, 14, 16, 256, 16, 15, 17, 18, 18, 19, 16, 16, 18, 204, 88, 17, 20, 19, 43, 41, 19, 35, 16, 39, 20, 16, 14, 14, 150, 19, 36, 17, 23, 20, 18, 20, 21, 16, 18, 20, 23, 17, 11, 23, 21, 21, 19, 35, 16, 24, 25, 16, 24, 180, 150, 19, 17, 24, 25, 20, 22, 20, 21, 10, 27, 20, 26, 25, 22, 23, 9, 21, 27, 22, 26, 26, 29, 30, 27, 180, 28, 22, 31, 51, 29, 30, 27, 21, 28, 29, 31, 51, 7, 25, 33, 31, 28, 28, 5, 22, 30, 26, 33, 28, 27, 32, 30, 22, 47, 47, 33, 34, 27, 32, 4, 29, 3, 52, 32, 34, 54, 31, 28, 28, 34, 52, 30, 54, 54, 28, 0, 30, 0, 0, 47, 47, 33, 45, 45, 45, 45, 45, 45, 45, 32, 48, 48, 0, 0, 0, 34, 46, 46, 46, 46, 46, 46, 46, 46, 46, 58, 62, 76, 46, 46, 0, 0, 0, 58, 62, 76, 48, 48, 50, 50, 50, 50, 50, 50, 50, 102, 62, 0, 0, 0, 0, 58, 0, 102, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 49, 60, 63, 0, 49, 49, 55, 0, 62, 60, 63, 59, 58, 57, 55, 56, 0, 55, 112, 59, 59, 57, 63, 56, 56, 0, 112, 0, 0, 60, 49, 49, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 55, 56, 57, 59, 61, 63, 0, 56, 64, 66, 67, 60, 61, 0, 61, 65, 64, 66, 67, 61, 65, 65, 0, 65, 68, 0, 56, 57, 64, 0, 67, 69, 68, 71, 70, 66, 0, 68, 74, 69, 61, 71, 70, 221, 73, 61, 74, 72, 72, 77, 75, 69, 73, 74, 64, 72, 67, 77, 75, 71, 66, 70, 78, 68, 75, 82, 73, 0, 79, 221, 78, 0, 81, 82, 0, 80, 79, 69, 0, 74, 81, 0, 77, 80, 71, 79, 70, 80, 79, 82, 75, 83, 73, 0, 78, 84, 86, 111, 111, 83, 85, 81, 117, 84, 86, 0, 111, 77, 85, 0, 117, 79, 98, 80, 79, 82, 86, 85, 98, 78, 98, 84, 0, 83, 92, 92, 81, 92, 92, 92, 92, 92, 92, 92, 95, 95, 95, 95, 95, 95, 95, 95, 86, 85, 0, 0, 84, 0, 83, 94, 94, 0, 94, 94, 94, 94, 94, 94, 94, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 99, 100, 101, 103, 0, 104, 0, 0, 99, 100, 101, 103, 100, 104, 103, 101, 105, 106, 107, 99, 108, 0, 109, 110, 105, 106, 107, 104, 108, 105, 109, 110, 0, 0, 0, 113, 110, 108, 100, 109, 103, 101, 114, 113, 107, 99, 106, 0, 0, 116, 114, 114, 118, 104, 0, 105, 113, 116, 0, 115, 118, 0, 110, 108, 0, 109, 116, 115, 0, 107, 120, 106, 115, 119, 119, 0, 121, 114, 120, 118, 122, 119, 113, 120, 121, 123, 124, 0, 122, 121, 0, 0, 116, 123, 124, 125, 0, 126, 115, 124, 127, 0, 128, 125, 118, 126, 129, 0, 127, 120, 128, 0, 123, 130, 129, 121, 132, 125, 133, 129, 0, 130, 0, 131, 132, 124, 133, 139, 128, 0, 126, 131, 138, 138, 0, 139, 0, 123, 133, 141, 138, 130, 139, 125, 132, 129, 143, 141, 0, 0, 131, 0, 0, 128, 143, 126, 134, 134, 134, 134, 134, 134, 134, 144, 133, 155, 130, 0, 139, 132, 0, 144, 0, 155, 0, 131, 135, 135, 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, 140, 142, 145, 146, 147, 148, 0, 0, 140, 142, 145, 146, 147, 148, 149, 151, 146, 145, 0, 140, 0, 142, 149, 151, 151, 154, 152, 153, 147, 148, 156, 156, 157, 154, 152, 153, 149, 152, 156, 0, 157, 0, 146, 145, 158, 140, 0, 142, 154, 153, 151, 159, 158, 160, 147, 148, 161, 162, 0, 159, 0, 160, 149, 152, 161, 162, 158, 0, 159, 163, 164, 165, 162, 160, 154, 153, 0, 163, 164, 165, 163, 0, 168, 166, 161, 171, 0, 173, 0, 167, 168, 166, 158, 171, 159, 173, 164, 167, 162, 160, 166, 0, 167, 0, 0, 168, 163, 0, 0, 161, 169, 169, 169, 169, 169, 169, 169, 172, 0, 175, 0, 164, 177, 0, 0, 172, 166, 175, 167, 0, 177, 168, 170, 170, 170, 170, 170, 170, 170, 170, 174, 176, 0, 172, 178, 0, 0, 179, 174, 176, 177, 183, 178, 174, 176, 179, 179, 181, 182, 183, 0, 184, 185, 0, 186, 181, 182, 0, 172, 184, 185, 178, 186, 0, 184, 177, 187, 0, 0, 174, 176, 188, 179, 189, 187, 181, 182, 187, 0, 188, 191, 189, 186, 190, 192, 0, 178, 193, 191, 194, 184, 190, 192, 191, 199, 193, 195, 194, 188, 192, 181, 182, 199, 187, 195, 0, 190, 186, 0, 0, 193, 196, 196, 196, 196, 196, 196, 196, 201, 191, 200, 198, 205, 188, 0, 192, 201, 195, 200, 198, 205, 0, 190, 0, 0, 201, 193, 197, 197, 197, 197, 197, 197, 197, 198, 202, 203, 200, 206, 207, 0, 210, 195, 202, 203, 208, 206, 207, 202, 210, 207, 201, 0, 208, 208, 206, 209, 203, 212, 213, 198, 215, 200, 211, 209, 209, 212, 213, 213, 215, 214, 211, 0, 0, 202, 0, 207, 0, 214, 216, 208, 206, 217, 203, 0, 211, 0, 216, 218, 219, 217, 209, 214, 220, 213, 223, 218, 219, 0, 218, 0, 220, 222, 223, 224, 0, 220, 0, 216, 225, 222, 211, 224, 222, 226, 223, 227, 225, 214, 228, 229, 0, 226, 230, 227, 218, 231, 228, 229, 225, 233, 230, 220, 216, 231, 234, 227, 235, 233, 222, 236, 223, 229, 234, 0, 235, 237, 0, 236, 236, 0, 240, 234, 238, 237, 225, 239, 241, 237, 240, 0, 238, 227, 242, 239, 241, 243, 239, 229, 0, 0, 242, 244, 247, 243, 236, 0, 238, 234, 0, 244, 247, 248, 243, 237, 241, 245, 246, 0, 244, 248, 242, 0, 239, 245, 246, 0, 245, 246, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 243, 241, 0, 0, 0, 0, 244, 242, 0, 0, 0, 0, 0, 0, 245, 246, 250, 250, 250, 250, 251, 0, 251, 251, 252, 0, 252, 252, 253, 253, 254, 0, 254, 254, 255, 0, 255, 255, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "tnglex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "tnglex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "tngparser.H" extern YYSTYPE* tnglval; extern tngFlexLexer* tnglexx; /* rules */ #line 781 "tnglex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 30 "tnglex.L" #line 885 "tnglex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 250 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 249 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 32 "tnglex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(tnglval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 39 "tnglex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(TNGBUFSIZE-1) ? yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 47 "tnglex.L" {return B1950_;} YY_BREAK case 4: YY_RULE_SETUP #line 48 "tnglex.L" {return BACKGROUND_;} YY_BREAK case 5: YY_RULE_SETUP #line 49 "tnglex.L" {return BOX_;} YY_BREAK case 6: YY_RULE_SETUP #line 50 "tnglex.L" {return BLACK_;} YY_BREAK case 7: YY_RULE_SETUP #line 51 "tnglex.L" {return BLUE_;} YY_BREAK case 8: YY_RULE_SETUP #line 52 "tnglex.L" {return CIRCLE_;} YY_BREAK case 9: YY_RULE_SETUP #line 53 "tnglex.L" {return CYAN_;} YY_BREAK case 10: YY_RULE_SETUP #line 54 "tnglex.L" {return DATE_;} YY_BREAK case 11: YY_RULE_SETUP #line 55 "tnglex.L" {return DEBUG_;} YY_BREAK case 12: YY_RULE_SETUP #line 56 "tnglex.L" {return DEGREES_;} YY_BREAK case 13: YY_RULE_SETUP #line 57 "tnglex.L" {return ELLIPSE_;} YY_BREAK case 14: YY_RULE_SETUP #line 58 "tnglex.L" {return ECLIPTIC_;} YY_BREAK case 15: YY_RULE_SETUP #line 59 "tnglex.L" {return FILENAME_;} YY_BREAK case 16: YY_RULE_SETUP #line 60 "tnglex.L" {return FK4_;} YY_BREAK case 17: YY_RULE_SETUP #line 61 "tnglex.L" {return FK4_NO_E_;} YY_BREAK case 18: YY_RULE_SETUP #line 62 "tnglex.L" {return FK5_;} YY_BREAK case 19: YY_RULE_SETUP #line 63 "tnglex.L" {return FORMAT_;} YY_BREAK case 20: YY_RULE_SETUP #line 64 "tnglex.L" {return GALACTIC_;} YY_BREAK case 21: YY_RULE_SETUP #line 65 "tnglex.L" {return GREEN_;} YY_BREAK case 22: YY_RULE_SETUP #line 66 "tnglex.L" {return HELIOECLIPTIC_;} YY_BREAK case 23: YY_RULE_SETUP #line 67 "tnglex.L" {return HMS_;} YY_BREAK case 24: YY_RULE_SETUP #line 68 "tnglex.L" {return ICRS_;} YY_BREAK case 25: YY_RULE_SETUP #line 69 "tnglex.L" {return J2000_;} YY_BREAK case 26: YY_RULE_SETUP #line 70 "tnglex.L" {return LINE_;} YY_BREAK case 27: YY_RULE_SETUP #line 71 "tnglex.L" {return MAGENTA_;} YY_BREAK case 28: YY_RULE_SETUP #line 72 "tnglex.L" {return OFF_;} YY_BREAK case 29: YY_RULE_SETUP #line 73 "tnglex.L" {return ON_;} YY_BREAK case 30: YY_RULE_SETUP #line 74 "tnglex.L" {return PHYSICAL_;} YY_BREAK case 31: YY_RULE_SETUP #line 75 "tnglex.L" {return PIXELS_;} YY_BREAK case 32: YY_RULE_SETUP #line 76 "tnglex.L" {return POINT_;} YY_BREAK case 33: YY_RULE_SETUP #line 77 "tnglex.L" {return POLYGON_;} YY_BREAK case 34: YY_RULE_SETUP #line 78 "tnglex.L" {return RED_;} YY_BREAK case 35: YY_RULE_SETUP #line 79 "tnglex.L" {return SOURCE_;} YY_BREAK case 36: YY_RULE_SETUP #line 80 "tnglex.L" {return SUPERGALACTIC_;} YY_BREAK case 37: YY_RULE_SETUP #line 81 "tnglex.L" {return TEXT_;} YY_BREAK case 38: YY_RULE_SETUP #line 82 "tnglex.L" {return VERSION_;} YY_BREAK case 39: YY_RULE_SETUP #line 83 "tnglex.L" {return WHITE_;} YY_BREAK case 40: YY_RULE_SETUP #line 84 "tnglex.L" {return YELLOW_;} YY_BREAK case 41: YY_RULE_SETUP #line 86 "tnglex.L" { // Integer tnglval->integer = atoi(yytext); return INT; } YY_BREAK case 42: #line 92 "tnglex.L" case 43: YY_RULE_SETUP #line 92 "tnglex.L" { // Real Number tnglval->real = atof(yytext); return REAL; } YY_BREAK case 44: #line 98 "tnglex.L" case 45: YY_RULE_SETUP #line 98 "tnglex.L" { // degrees yytext[yyleng-1] = '\0'; tnglval->real = atof(yytext); return ANGDEGREE; } YY_BREAK case 46: #line 105 "tnglex.L" case 47: YY_RULE_SETUP #line 105 "tnglex.L" { // Sexagesimal int ll = yyleng <(TNGBUFSIZE-1)?yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 48: #line 113 "tnglex.L" case 49: YY_RULE_SETUP #line 113 "tnglex.L" { // Quoted String int ll = (yyleng-2)<(TNGBUFSIZE-1)?(yyleng-2):(TNGBUFSIZE-1); strncpy(tnglval->str,yytext+1,yyleng-2); // skip the " " tnglval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 50: YY_RULE_SETUP #line 120 "tnglex.L" { // Quoted String int ll = (yyleng-2)<(TNGBUFSIZE-1)?(yyleng-2):(TNGBUFSIZE-1); strncpy(tnglval->str,yytext+1,yyleng-2); // skip the '{' tnglval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 51: YY_RULE_SETUP #line 127 "tnglex.L" { // General String int ll = yyleng <(TNGBUFSIZE-1) ? yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return STRING; } YY_BREAK case 52: YY_RULE_SETUP #line 134 "tnglex.L" { // White Spaces } YY_BREAK case 53: /* rule 53 can match eol */ YY_RULE_SETUP #line 137 "tnglex.L" { // windows line feed return '\n'; } YY_BREAK case 54: YY_RULE_SETUP #line 141 "tnglex.L" { // fake line feed return '\n'; } YY_BREAK case 55: /* rule 55 can match eol */ YY_RULE_SETUP #line 145 "tnglex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 149 "tnglex.L" { // eof return EOF_; } YY_BREAK case 56: YY_RULE_SETUP #line 153 "tnglex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 57: YY_RULE_SETUP #line 157 "tnglex.L" ECHO; YY_BREAK #line 1297 "tnglex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; tngfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); tngfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ tngrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) tngrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 250 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 250 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 249); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) tngalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) tngalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) tngfree((void *) b->yy_ch_buf ); tngfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)tngalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)tngrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) tngalloc(new_size ); else (yy_start_stack) = (int *) tngrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *tngalloc (yy_size_t size ) { return (void *) malloc( size ); } void *tngrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void tngfree (void * ptr ) { free( (char *) ptr ); /* see tngrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 157 "tnglex.L" void tngDiscard(int doit) { if (tnglexx) tnglexx->begin(DISCARD, doit); } void tngFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/projection.h�������������������������������������������������������������������0000644�0001750�0001750�00000003070�12002337011�015630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __projection_h__ #define __projection_h__ #include "baseline.h" class Projection : public BaseLine { private: double width; Vector p3; // used for bbox Vector p4; private: void renderX(Drawable, Coord::InternalSystem, RenderMode); GC renderXGC(RenderMode); void renderPS(int); void renderPSGC(int); #ifdef _MACOSX void renderMACOSX(); void renderMACOSXGC(); #endif #ifdef _WIN32 void renderWIN32(); void renderWIN32GC(); #endif void updateHandles(); void calcAllBBox(); public: Projection(const Projection&); Projection(Base* p, const Vector& ptr1, const Vector& ptr2, double wd, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Projection(*this);} int isIn(const Vector&); void updateCoords(const Matrix&); void edit(const Vector&, int); void analysis(AnalysisTask, int); void analysisPlot2d(char*, char*, char*, char*, Coord::CoordSystem, Coord::SkyFrame, Marker::AnalysisMethod); void set(const Vector&, const Vector&, double); void setWidth(double); double getWidth() {return width;} void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/text.C�������������������������������������������������������������������������0000644�0001750�0001750�00000017623�11771124437�014426� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "text.h" #include "fitsimage.h" #include "rotstr.h" #include <tcl.h> #include <X11/Xlib.h> #include <X11/Xutil.h> Text::Text(const Text& a) : Marker(a) { rotate = a.rotate; } Text::Text(Base* p, const Vector& ctr, double ang, int rot, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { strcpy(type_,"text"); handle = new Vector[4]; numHandle = 4; rotate = rot; updateBBox(); } void Text::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { if (text && *text && tkfont_) { GC lgc = renderXGC(mode); XSetFont(display, lgc, Tk_FontId(tkfont_)); // origin is center of text Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); int delta = (metrics.ascent-metrics.descent)/2.; double ang = rotate ? calcAngle() : 0; Vector cc = parent->mapFromRef(center,sys); Matrix mm = Translate(-cc) * Translate(-width/2., delta) * Rotate(ang) * Translate(cc); Vector vv = cc * mm; #if !(_WIN32 || _MACOSX) XDrawRotString(display, drawable, lgc, vv, ang, text, tkfont_, parent); #else XDrawRotString(display, drawable, lgc, vv, ang, text); #endif } } void Text::renderPS(int mode) { renderPSGC(mode); if (text && *text && psfont_) { ostringstream str; const char* ff = Tk_NameOfFont(psfont_); str << '/' << psFontName(ff) << " findfont " << int(psFontSize(ff)*parent->getDisplayRatio()) << " scalefont setfont" << endl; double ang = rotate ? calcAngle() : 0; Vector cc = (parent->mapFromRef(center,Coord::CANVAS)).TkCanvasPs(parent->canvas); str << "gsave" << endl << "newpath " << endl << cc << " moveto" << endl << '(' << psQuote(text) << ')' << endl << "dup true charpath pathbbox " << endl << "closepath " << endl << "3 -1 roll sub 3.6 div neg " << endl << "3 1 roll sub 2 div exch " << endl << cc << " moveto " << endl << radToDeg(ang) << " rotate " << endl << " rmoveto show" << endl << "grestore" << endl; str << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void Text::renderMACOSX() { renderMACOSXGC(); if (text && *text && psfont_) { Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(psfont_, &psdstr); macosxFont(Tcl_DStringValue(&psdstr), psSize); Tcl_DStringFree(&psdstr); Tk_FontMetrics metrics; Tk_GetFontMetrics(psfont_, &metrics); int width = Tk_TextWidth(psfont_, text, strlen(text)); double ang = rotate ? calcAngle() : 0; Vector cc = parent->mapFromRef(center,Coord::CANVAS); Matrix mm = Translate(-cc) * Translate(-width/2.,metrics.descent) * Rotate(ang) * Translate(cc); macosxDrawText(cc*mm, 0, text); } } #endif #ifdef _WIN32 void Text::renderWIN32() { renderWIN32GC(); if (text && *text && tkfont_) { win32Font(tkfont_); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); int delta = (metrics.ascent-metrics.descent)/2.; double ang = rotate ? calcAngle() : 0; Vector cc = parent->mapFromRef(center,Coord::CANVAS); Matrix mm = Translate(-cc) * Translate(-width/2., delta) * Rotate(ang) * Translate(cc); Vector vv = cc * mm; win32DrawText(vv, 0, text); } } #endif // Support void Text::updateHandles() { Vector cc = parent->mapFromRef(center,Coord::CANVAS); if (text && *text && tkfont_) { Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); Vector s(width, metrics.linespace); double ang = rotate ? calcAngle() : 0; Matrix mm = Rotate(ang) * Translate(cc); handle[0] = Vector(-s[0],-s[1])/2 * mm; handle[1] = Vector( s[0],-s[1])/2 * mm; handle[2] = Vector( s[0], s[1])/2 * mm; handle[3] = Vector(-s[0], s[1])/2 * mm; } else { Vector s(10,10); Matrix mm = Translate(cc); handle[0] = Vector(-s[0],-s[1])/2 * mm; handle[1] = Vector( s[0],-s[1])/2 * mm; handle[2] = Vector( s[0], s[1])/2 * mm; handle[3] = Vector(-s[0], s[1])/2 * mm; } } void Text::calcAllBBox() { allBBox = bbox; } int Text::isIn(const Vector& vv) { if (text && *text && tkfont_) { // origin is center of text Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); float ww = Tk_TextWidth(tkfont_, text, strlen(text))/2./parent->zoom_[0]; float hh = metrics.linespace/2./parent->zoom_[1]; Vector pp = bckMap(vv,Coord::CANVAS); if (pp[0]<-ww || pp[0]>ww || pp[1]<-hh || pp[1]>hh) return 0; else return 1; } else return 0; } void Text::setRotate(int rot) { rotate = rot ? 1 : 0; updateBBox(); } // list void Text::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ')'; } } } if (conj) str << " ||"; if (angle != 0) str << " textangle=" << radToDeg(parent->mapAngleFromRef(angle,sys,sky)); if (!rotate) str << " textrotate=" << 0; listProperties(str, 0); } } void Text::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowCenter(ptr,sys,sky,format); XMLRowAng(sys,sky); XMLRow(XMLPARAM,rotate); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Text::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); if (properties&INCLUDE) str << '+'; else str << '-'; switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ", \"" << text << "\")"; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] <<", \"" << text << "\")"; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ", \"" << text << "\")"; } break; } } } listSAOtngPost(str, strip); } �������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/ds9parser.Y��������������������������������������������������������������������0000644�0001750�0001750�00000117234�11734430017�015374� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Base* fr} %lex-param {mkFlexLexer* ll} %parse-param {mkFlexLexer* ll} %{ #define YYDEBUG 1 #define FITSPTR (fr->findFits(globalTile)) #define DISCARD_(x) {yyclearin; mkDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #include "point.h" #undef yyFlexLexer #define yyFlexLexer mkFlexLexer #include <FlexLexer.h> extern int mklex(void*, mkFlexLexer*); extern void mkerror(Base*, mkFlexLexer*, const char*); extern void mkDiscard(int); static Coord::CoordSystem globalSystem; static Coord::CoordSystem globalWCS; static Coord::SkyFrame globalSky; static Coord::CoordSystem localSystem; static Coord::SkyFrame localSky; static int globalTile; static unsigned short globalProps; static unsigned short localProps; static int globalDash[2]; static int localDash[2]; static int globalWidth; static int localWidth; static char globalColor[16]; static char localColor[16]; static char globalFont[32]; static char localFont[32]; static char globalText[80]; static char localText[80]; static char localComment[80]; static int globalLine1; static int localLine1; static int globalLine2; static int localLine2; static int globalVector; static int localVector; static int globalComposite; static int localComposite; static int globalPoint; static int localPoint; static int globalPointSize; static int localPointSize; static double globalTextAngle; static double localTextAngle; static int globalTextRotate; static int localTextRotate; static Coord::CoordSystem globalRulerCoordSystem; static Coord::CoordSystem localRulerCoordSystem; static Coord::SkyFrame globalRulerSkyFrame; static Coord::SkyFrame localRulerSkyFrame; static Coord::CoordSystem globalRulerDistSystem; static Coord::CoordSystem localRulerDistSystem; static Coord::SkyDist globalRulerDistFormat; static Coord::SkyDist localRulerDistFormat; static Coord::CoordSystem globalCompassCoordSystem; static Coord::SkyFrame globalCompassSkyFrame; static char globalCompassNorth[80]; static char globalCompassEast[80]; static int globalCompassNArrow; static int globalCompassEArrow; static Coord::CoordSystem localCompassCoordSystem; static Coord::SkyFrame localCompassSkyFrame; static char localCompassNorth[80]; static char localCompassEast[80]; static int localCompassNArrow; static int localCompassEArrow; static int localCpanda; static int localEpanda; static int localBpanda; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aNumsao; static int aStatus; static int cStatus; static Vector aCenter; static double aAngles[MAXANGLES]; static int aAngNum; static double aAngle; static unsigned short aProps; static char aColor[16]; static int aWidth; static int aDash[2]; static char aFont[32]; static char aText[80]; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); static Coord::CoordSystem checkWCSSystem(); static Coord::SkyFrame checkWCSSky(); %} %union { #define MKBUFSIZE 2048 double real; int integer; char str[MKBUFSIZE]; double vector[3]; } %type <real> numeric %type <integer> yesno %type <real> angle %type <real> optangle %type <real> value %type <vector> vvalue %type <real> sexagesimal %type <real> hms %type <real> dms %type <vector> coord %type <integer> coordSystem %type <integer> wcsSystem %type <integer> skyFrame %type <integer> skyDist %type <integer> property %type <integer> callBack %type <integer> pointShape %type <integer> numberof %token <integer> INT %token <real> REAL %token <str> STRING %token <real> ANGDEGREE %token <real> ANGRADIAN %token <real> ARCMINUTE %token <real> ARCSECOND %token <real> PHYCOORD %token <real> IMGCOORD %token <str> SEXSTR %token <str> HMSSTR %token <str> DMSSTR %token EOF_ %token AMPLIFIER_ %token ANNULUS_ %token ARCMIN_ %token ARCSEC_ %token ARROW_ %token B1950_ %token BACKGROUND_ %token BEGIN_ %token BOX_ %token BOXCIRCLE_ %token BPANDA_ %token CALLBACK_ %token CIRCLE_ %token CIRCLE3D_ %token COLOR_ %token COMPASS_ %token COMPOSITE_ %token CPANDA_ %token CROSS_ %token DASH_ %token DASHLIST_ %token DEBUG_ %token DEGREES_ %token DELETE_ %token DETECTOR_ %token DIAMOND_ %token ECLIPTIC_ %token EDIT_ %token ELLIPSE_ %token END_ %token EPANDA_ %token FALSE_ %token FIELD_ %token FIXED_ %token FK4_ %token FK4_NO_E_ %token FK5_ %token FONT_ %token GALACTIC_ %token GLOBAL_ %token HELIOECLIPTIC_ %token HIGHLITE_ %token ICRS_ %token IGNORE_ %token IMAGE_ %token INCLUDE_ %token J2000_ %token KEY_ %token LINE_ %token LINEAR_ %token MOVE_ %token N_ %token NO_ %token OFF_ %token ON_ %token PHYSICAL_ %token PIE_ %token PIXELS_ %token POINT_ %token POLYGON_ %token PROJECTION_ %token PROPERTY_ %token ROTATE_ %token ROTBOX_ %token RULER_ %token SELECT_ %token SOURCE_ %token SUPERGALACTIC_ %token TAG_ %token TEXT_ %token TEXTANGLE_ %token TEXTROTATE_ %token TILE_ %token TRUE_ %token VECTOR_ %token VERSION_ %token UNHIGHLITE_ %token UNSELECT_ %token UPDATE_ %token WCS_ %token WCSA_ %token WCSB_ %token WCSC_ %token WCSD_ %token WCSE_ %token WCSF_ %token WCSG_ %token WCSH_ %token WCSI_ %token WCSJ_ %token WCSK_ %token WCSL_ %token WCSM_ %token WCSN_ %token WCSO_ %token WCSP_ %token WCSQ_ %token WCSR_ %token WCSS_ %token WCST_ %token WCSU_ %token WCSV_ %token WCSW_ %token WCSX_ %token WCSY_ %token WCSZ_ %token WCS0_ %token WIDTH_ %token X_ %token Y_ %token YES_ %% start : initGlobal commands postLocal ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | VERSION_ {cerr << "DS9 Regions File 3.2" << endl;} | GLOBAL_ global comment | TILE_ INT {globalTile = $2;} | coordSystem {globalSystem=(Coord::CoordSystem)$1;} comment | skyFrame {globalSystem=globalWCS; globalSky=(Coord::SkyFrame)$1;} comment | LINEAR_ {globalSystem=globalWCS; globalSky=Coord::FK5;} comment | initLocal shape | initLocal include shape | initLocal '#' hash ; hash : nonshape | include nonshape | TILE_ INT {globalTile = $2;} | {DISCARD_(1)} STRING ; comment : /* empty */ | '#' {DISCARD_(1)} STRING ; shapeComment : /* empty */ postLocal | '#' {DISCARD_(1)} STRING postLocal {strncpy(localComment,$3,80)} | '#' local postLocal | '#' local {DISCARD_(1)} STRING postLocal {strncpy(localComment,$4,80)} ; nonshapeComment : /* empty */ postLocal | {DISCARD_(1)} STRING postLocal {strncpy(localComment,$2,80)} | local postLocal | local {DISCARD_(1)} STRING postLocal {strncpy(localComment,$3,80)} ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; yesno : INT {$$=($1 ? 1 : 0);} | YES_ {$$=1;} | Y_ {$$=1;} | ON_ {$$=1;} | TRUE_ {$$=1;} | NO_ {$$=0;} | N_ {$$=0;} | OFF_ {$$=0;} | FALSE_ {$$=0;} ; sp : /* empty */ | ',' ; bp : /* empty */ | '(' ; ep : /* emtpy */ | ')' ; conjuction : /* empty */ {cStatus = 0;} | '|' {cStatus = 1;} | '|' '|' {cStatus = 1;} ; optangle: /* empty */ {$$ = fr->mapAngleToRef(0,localSystem,localSky);} | angle {$$ = $1;} ; angle : numeric {$$ = fr->mapAngleToRef(degToRad($1),localSystem,localSky);} | ANGDEGREE {$$ = fr->mapAngleToRef(degToRad($1),localSystem,localSky);} | ANGRADIAN {$$ = fr->mapAngleToRef($1,localSystem,localSky);} ; value : numeric {$$ = FITSPTR->mapLenToRef($1, localSystem, Coord::DEGREE);} | PHYCOORD {$$ = FITSPTR->mapLenToRef($1, Coord::PHYSICAL);} | IMGCOORD {$$ = FITSPTR->mapLenToRef($1, Coord::IMAGE);} | ANGDEGREE {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::DEGREE);} | ARCMINUTE {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::ARCMIN);} | ARCSECOND {$$ = FITSPTR->mapLenToRef($1, checkWCSSystem(), Coord::ARCSEC);} ; vvalue : numeric sp numeric { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), localSystem, Coord::DEGREE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | PHYCOORD sp PHYCOORD { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::PHYSICAL); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | IMGCOORD sp IMGCOORD { Vector r = FITSPTR->mapLenToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::DEGREE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCMINUTE sp ARCMINUTE { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::ARCMIN); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ARCSECOND sp ARCSECOND { Vector r=FITSPTR->mapLenToRef(Vector($1,$3),checkWCSSystem(),Coord::ARCSEC); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } ; numberof: N_ '=' INT {$$ = $3;} ; sexagesimal: SEXSTR {$$ = parseSEXStr($1);} ; hms : HMSSTR {$$ = parseHMSStr($1);} ; dms : DMSSTR {$$ = parseDMSStr($1);} ; coord : sexagesimal sp sexagesimal { Vector r; Coord::CoordSystem sys = checkWCSSystem(); Coord::SkyFrame sky = checkWCSSky(); if (sky == Coord::GALACTIC || sky == Coord::ECLIPTIC) r = FITSPTR->mapToRef(Vector($1,$3), sys, sky); else r = FITSPTR->mapToRef(Vector($1*360./24.,$3), sys, sky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | hms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | dms sp dms { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | numeric sp numeric { Vector r = FITSPTR->mapToRef(Vector($1,$3), localSystem, localSky); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | ANGDEGREE sp ANGDEGREE { Vector r = FITSPTR->mapToRef(Vector($1,$3), checkWCSSystem(), checkWCSSky()); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | IMGCOORD sp IMGCOORD { Vector r = FITSPTR->mapToRef(Vector($1,$3), Coord::IMAGE); $$[0] = r[0]; $$[1] = r[1]; $$[2] = r[2]; } | PHYCOORD sp PHYCOORD { Vector r = FITSPTR->mapToRef(Vector($1,$3), Coord::PHYSICAL); $$[0] = r[0]; $$[1] = r[1]; } ; coordSystem :IMAGE_ {$$ = Coord::IMAGE;} | PHYSICAL_ {$$ = Coord::PHYSICAL;} | DETECTOR_ {$$ = Coord::DETECTOR;} | AMPLIFIER_ {$$ = Coord::AMPLIFIER;} | wcsSystem {$$ = $1; globalWCS = (Coord::CoordSystem)$1;} ; wcsSystem : WCS_ {$$ = Coord::WCS;} | WCSA_ {$$ = Coord::WCSA;} | WCSB_ {$$ = Coord::WCSB;} | WCSC_ {$$ = Coord::WCSC;} | WCSD_ {$$ = Coord::WCSD;} | WCSE_ {$$ = Coord::WCSE;} | WCSF_ {$$ = Coord::WCSF;} | WCSG_ {$$ = Coord::WCSG;} | WCSH_ {$$ = Coord::WCSH;} | WCSI_ {$$ = Coord::WCSI;} | WCSJ_ {$$ = Coord::WCSJ;} | WCSK_ {$$ = Coord::WCSK;} | WCSL_ {$$ = Coord::WCSL;} | WCSM_ {$$ = Coord::WCSM;} | WCSN_ {$$ = Coord::WCSN;} | WCSO_ {$$ = Coord::WCSO;} | WCSP_ {$$ = Coord::WCSP;} | WCSQ_ {$$ = Coord::WCSQ;} | WCSR_ {$$ = Coord::WCSR;} | WCSS_ {$$ = Coord::WCSS;} | WCST_ {$$ = Coord::WCST;} | WCSU_ {$$ = Coord::WCSU;} | WCSV_ {$$ = Coord::WCSV;} | WCSW_ {$$ = Coord::WCSW;} | WCSX_ {$$ = Coord::WCSX;} | WCSY_ {$$ = Coord::WCSY;} | WCSZ_ {$$ = Coord::WCSZ;} | WCS0_ {$$ = Coord::WCS0;} ; skyFrame : FK4_ {$$ = Coord::FK4;} | B1950_ {$$ = Coord::FK4;} | FK4_NO_E_ {$$ = Coord::FK4_NO_E;} | FK5_ {$$ = Coord::FK5;} | J2000_ {$$ = Coord::FK5;} | ICRS_ {$$ = Coord::ICRS;} | GALACTIC_ {$$ = Coord::GALACTIC;} | SUPERGALACTIC_ {$$ = Coord::SUPERGALACTIC;} | ECLIPTIC_ {$$ = Coord::ECLIPTIC;} | HELIOECLIPTIC_ {$$ = Coord::HELIOECLIPTIC;} ; skyDist : DEGREES_ {$$=Coord::DEGREE;} | ARCMIN_ {$$=Coord::ARCMIN;} | ARCSEC_ {$$=Coord::ARCSEC;} ; property : SELECT_ {$$ = Marker::SELECT;} | HIGHLITE_ {$$ = Marker::HIGHLITE;} | DASH_ {$$ = Marker::DASH;} | FIXED_ {$$ = Marker::FIXED;} | EDIT_ {$$ = Marker::EDIT;} | MOVE_ {$$ = Marker::MOVE;} | ROTATE_ {$$ = Marker::ROTATE;} | DELETE_ {$$ = Marker::DELETE;} | INCLUDE_ {$$ = Marker::INCLUDE;} | SOURCE_ {$$ = Marker::SOURCE;} ; callBack : SELECT_ {$$ = CallBack::SELECTCB;} | UNSELECT_ {$$ = CallBack::UNSELECTCB;} | HIGHLITE_ {$$ = CallBack::HIGHLITECB;} | UNHIGHLITE_ {$$ = CallBack::UNHIGHLITECB;} | BEGIN_ MOVE_ {$$ = CallBack::MOVEBEGINCB;} | MOVE_ {$$ = CallBack::MOVECB;} | END_ MOVE_ {$$ = CallBack::MOVEENDCB;} | BEGIN_ EDIT_ {$$ = CallBack::EDITBEGINCB;} | EDIT_ {$$ = CallBack::EDITCB;} | END_ EDIT_ {$$ = CallBack::EDITENDCB;} | BEGIN_ ROTATE_ {$$ = CallBack::ROTATEBEGINCB;} | ROTATE_ {$$ = CallBack::ROTATECB;} | END_ ROTATE_ {$$ = CallBack::ROTATEENDCB;} | DELETE_ {$$ = CallBack::DELETECB;} | TEXT_ {$$ = CallBack::TEXTCB;} | COLOR_ {$$ = CallBack::COLORCB;} | WIDTH_ {$$ = CallBack::LINEWIDTHCB;} | PROPERTY_ {$$ = CallBack::PROPERTYCB;} | FONT_ {$$ = CallBack::FONTCB;} | KEY_ {$$ = CallBack::KEYCB;} | UPDATE_ {$$ = CallBack::UPDATECB;} ; global : global sp globalProperty | globalProperty ; globalProperty : property '=' yesno { setProps(&globalProps,$1,$3); setProps(&localProps,$1,$3); } | COLOR_ '=' STRING { strncpy(globalColor,$3,16); strncpy(localColor,$3,16); } | COLOR_ '=' '#' STRING { strcpy(globalColor,"#"); strncat(globalColor,$4,16); strncpy(localColor,globalColor,16); } | DASHLIST_ '=' INT INT { globalDash[0] = localDash[0] =$3; globalDash[1] = localDash[1] =$4; } | WIDTH_ '=' INT {globalWidth = localWidth = $3;} | FONT_ '=' STRING { strncpy(globalFont,$3,32); strncpy(localFont,$3,32); } | TEXT_ '=' STRING { strncpy(globalText,$3,80); strncpy(localText,$3,80); } | DASH_ { setProps(&globalProps,Marker::DASH,1); setProps(&localProps,Marker::DASH,1); } | SOURCE_ { setProps(&globalProps,Marker::SOURCE,1); setProps(&localProps,Marker::SOURCE,1); } | BACKGROUND_ { setProps(&globalProps,Marker::SOURCE,0); setProps(&localProps,Marker::SOURCE,0); } | POINT_ '=' pointShape {globalPoint = localPoint = $3;} | POINT_ '=' pointShape INT { globalPoint = localPoint = $3; globalPointSize = localPointSize = $4; } | LINE_ '=' INT INT { globalLine1 = localLine1 = $3; globalLine2 = localLine2 = $4; } | VECTOR_ '=' INT {globalVector = localVector = $3;} | COMPOSITE_ '=' INT { globalComposite = localComposite = $3; } | RULER_ '=' globalRuler {} | COMPASS_ '=' globalCompass STRING STRING INT INT { strncpy(globalCompassNorth,$4,80); strncpy(globalCompassEast,$5,80); strncpy(localCompassNorth,$4,80); strncpy(localCompassEast,$5,80); globalCompassNArrow = localCompassNArrow = $6; globalCompassEArrow = localCompassEArrow = $7; } | TEXTANGLE_ '=' angle {globalTextAngle = localTextAngle = $3;} | TEXTROTATE_ '=' INT {globalTextRotate = localTextRotate = $3;} | WCS_ '=' wcsSystem {globalWCS = (Coord::CoordSystem)$3;} ; globalRuler : coordSystem skyFrame coordSystem skyDist { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)$1; globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)$2; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)$3; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)$4; } | coordSystem coordSystem { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)$1; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)$2; globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; } | coordSystem skyDist { globalRulerCoordSystem = localRulerCoordSystem = (Coord::CoordSystem)$1; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)$2; } | skyFrame coordSystem { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)$1; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)$2; globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; } | skyFrame skyDist { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = (Coord::SkyFrame)$1; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)$2; } | LINEAR_ coordSystem { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = (Coord::CoordSystem)$2; globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; } | LINEAR_ skyDist { globalRulerCoordSystem = localRulerCoordSystem = Coord::WCS; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)$2; } | skyDist { globalRulerCoordSystem = localRulerCoordSystem = Coord::IMAGE; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::WCS; globalRulerDistFormat = localRulerDistFormat = (Coord::SkyDist)$1; } | PIXELS_ { globalRulerCoordSystem = localRulerCoordSystem = Coord::IMAGE; globalRulerSkyFrame = localRulerSkyFrame = Coord::FK5; globalRulerDistSystem = localRulerDistSystem = Coord::IMAGE; globalRulerDistFormat = localRulerDistFormat = Coord::DEGREE; } ; globalCompass : coordSystem skyFrame { globalCompassCoordSystem = localCompassCoordSystem = (Coord::CoordSystem)$1; globalCompassSkyFrame = localCompassSkyFrame = (Coord::SkyFrame)$2; } | coordSystem { globalCompassCoordSystem = localCompassCoordSystem = (Coord::CoordSystem)$1; globalCompassSkyFrame = localCompassSkyFrame = Coord::FK5; } | skyFrame { globalCompassCoordSystem = localCompassCoordSystem = Coord::WCS; globalCompassSkyFrame = localCompassSkyFrame = (Coord::SkyFrame)$1; } | LINEAR_ { globalCompassCoordSystem = localCompassCoordSystem = Coord::WCS; globalCompassSkyFrame = localCompassSkyFrame = Coord::FK5; } ; initGlobal:{ // global properties globalSystem = Coord::PHYSICAL; globalWCS = fr->wcsSystem(); globalSky = fr->wcsSky(); globalTile = 1; globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; strcpy(globalColor,"green"); globalDash[0] = 8; globalDash[1] = 3; globalWidth = 1; strcpy(globalFont,"helvetica 10 normal roman"); strcpy(globalText,""); // unique properties globalLine1 = 0; globalLine2 = 0; globalVector = 1; globalComposite = 1; globalRulerCoordSystem = Coord::PHYSICAL; globalRulerSkyFrame = Coord::FK5; globalRulerDistSystem = Coord::PHYSICAL; globalRulerDistFormat = Coord::DEGREE; globalCompassCoordSystem = Coord::PHYSICAL; globalCompassSkyFrame = Coord::FK5; strcpy(globalCompassNorth,"N"); strcpy(globalCompassEast,"E"); globalCompassNArrow = 1; globalCompassEArrow = 1; globalPoint = Point::BOXCIRCLE; globalPointSize = POINTSIZE; globalTextAngle=0; globalTextRotate=1; aStatus = 0; cStatus = 0; } ; local : local sp localProperty | localProperty ; localProperty : property '=' yesno {setProps(&localProps,$1,$3);} | COLOR_ '=' STRING {strncpy(localColor,$3,16);} | COLOR_ '=' '#' STRING { strcpy(localColor,"#"); strncat(localColor,$4,16); } | DASHLIST_ '=' INT INT { localDash[0] =$3; localDash[1] =$4; } | WIDTH_ '=' INT {localWidth = $3;} | FONT_ '=' STRING {strncpy(localFont,$3,32);} | TEXT_ '=' STRING {strncpy(localText,$3,80);} | TAG_ '=' STRING {taglist.append(new Tag($3));} | CALLBACK_ '=' callBack STRING STRING {cblist.append( new CallBack(fr->getInterp(),(CallBack::Type)$3,$4,$5));} | DASH_ {setProps(&localProps,Marker::DASH,1);} | SOURCE_ {setProps(&localProps,Marker::SOURCE,1);} | BACKGROUND_ {setProps(&localProps,Marker::SOURCE,0);} | POINT_ '=' pointShape {localPoint = $3;} | POINT_ '=' pointShape INT {localPoint = $3; localPointSize = $4;} | LINE_ '=' INT INT {localLine1=$3; localLine2=$4;} | VECTOR_ '=' INT {localVector=$3;} | COMPOSITE_ '=' INT {localComposite=$3;} | RULER_ '=' localRuler | COMPASS_ '=' localCompass STRING STRING INT INT { strncpy(localCompassNorth,$4,80); strncpy(localCompassEast,$5,80); localCompassNArrow = $6; localCompassEArrow = $7; } | TEXTANGLE_ '=' angle {localTextAngle=$3;} | TEXTROTATE_ '=' INT {localTextRotate=$3;} | CPANDA_ '=' localCpanda | EPANDA_ '=' localEpanda | BPANDA_ '=' localBpanda ; localRuler : coordSystem skyFrame coordSystem skyDist { localRulerCoordSystem = (Coord::CoordSystem)$1; localRulerSkyFrame = (Coord::SkyFrame)$2; localRulerDistSystem = (Coord::CoordSystem)$3; localRulerDistFormat = (Coord::SkyDist)$4; } | coordSystem coordSystem { localRulerCoordSystem = (Coord::CoordSystem)$1; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = (Coord::CoordSystem)$2; localRulerDistFormat = Coord::DEGREE; } | coordSystem skyDist { localRulerCoordSystem = (Coord::CoordSystem)$1; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)$2; } | skyFrame coordSystem { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = (Coord::SkyFrame)$1; localRulerDistSystem = (Coord::CoordSystem)$2; localRulerDistFormat = Coord::DEGREE; } | skyFrame skyDist { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = (Coord::SkyFrame)$1; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)$2; } | LINEAR_ coordSystem { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = (Coord::CoordSystem)$2; localRulerDistFormat = Coord::DEGREE; } | LINEAR_ skyDist { localRulerCoordSystem = Coord::WCS; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)$2; } | skyDist { localRulerCoordSystem = Coord::IMAGE; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::WCS; localRulerDistFormat = (Coord::SkyDist)$1; } | PIXELS_ { localRulerCoordSystem = Coord::IMAGE; localRulerSkyFrame = Coord::FK5; localRulerDistSystem = Coord::IMAGE; localRulerDistFormat = Coord::DEGREE; } ; localCompass : coordSystem skyFrame { localCompassCoordSystem = (Coord::CoordSystem)$1; localCompassSkyFrame = (Coord::SkyFrame)$2; } | coordSystem { localCompassCoordSystem = (Coord::CoordSystem)$1; localCompassSkyFrame = Coord::FK5; } | skyFrame { localCompassCoordSystem = Coord::WCS; localCompassSkyFrame = (Coord::SkyFrame)$1; } | LINEAR_ { localCompassCoordSystem = Coord::WCS; localCompassSkyFrame = Coord::FK5; } ; localCpanda: {aNum=0; aAngNum=0;} '(' aAngs ')' '(' aRads ')' {localCpanda = 2;} | IGNORE_ {localCpanda=0;} ; localEpanda: {aNum=0; aAngNum=0, aAngle=0;} '(' aAngs ')' '(' vRads ')' '(' angle ')' {aAngle=$9;localEpanda=2;} | IGNORE_ {localEpanda=0;} ; localBpanda: {aNum=0; aAngNum=0, aAngle=0;} '(' aAngs ')' '(' vRads ')' '(' angle ')' {aAngle=$9;localBpanda=2;} | IGNORE_ {localBpanda=0;} ; initLocal : { // reset maperr flag maperr = 0; // needed for annulus, ellipse annulus, and box annulus aNum = 2; // composite (previous conjuction found?) if (!cStatus) fr->resetCompositeMarker(); // global properties localSystem = globalSystem; localSky = globalSky; localProps = globalProps; strcpy(localColor,globalColor); localDash[0] = globalDash[0]; localDash[1] = globalDash[1]; localWidth = globalWidth; strcpy(localFont,globalFont); strcpy(localText,globalText); strcpy(localComment,""); taglist.deleteAll(); cblist.deleteAll(); // unique properties localLine1 = globalLine1; localLine2 = globalLine2; localVector = globalVector; localComposite = globalComposite; localPoint = globalPoint; localPointSize = globalPointSize; localRulerCoordSystem = globalRulerCoordSystem; localRulerSkyFrame = globalRulerSkyFrame; localRulerDistSystem = globalRulerDistSystem; localRulerDistFormat = globalRulerDistFormat; localCompassCoordSystem = globalCompassCoordSystem; localCompassSkyFrame = globalCompassSkyFrame; strcpy(localCompassNorth,globalCompassNorth); strcpy(localCompassEast,globalCompassEast); localCompassNArrow = globalCompassNArrow; localCompassEArrow = globalCompassEArrow; localTextAngle = globalTextAngle; localTextRotate = globalTextRotate; localCpanda = 1; localEpanda = 1; localBpanda = 1; } ; pointShape : CIRCLE_ {$$ = Point::CIRCLE;} | BOX_ {$$ = Point::BOX;} | DIAMOND_ {$$ = Point::DIAMOND;} | CROSS_ {$$ = Point::CROSS;} | X_ {$$ = Point::EX;} | ARROW_ {$$ = Point::ARROW;} | BOXCIRCLE_ {$$ = Point::BOXCIRCLE;} ; include : '+' {setProps(&localProps, Marker::INCLUDE, 1);} | '-' {setProps(&localProps, Marker::INCLUDE, 0);} ; nonshape : VECTOR_ bp coord sp value sp angle ep conjuction nonshapeComment { fr->createVectCmd(Vector($3), $5,$7, localVector, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | TEXT_ bp coord ep conjuction nonshapeComment { fr->createTextCmd(Vector($3), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | RULER_ bp coord sp coord ep conjuction nonshapeComment { fr->createRulerCmd(Vector($3), Vector($5), localRulerCoordSystem, localRulerSkyFrame, localRulerDistSystem, localRulerDistFormat, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | COMPASS_ bp coord sp value ep conjuction nonshapeComment { fr->createCompassCmd(Vector($3), $5, localCompassNorth, localCompassEast, localCompassNArrow, localCompassEArrow, localCompassCoordSystem, localCompassSkyFrame, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | PROJECTION_ bp coord sp coord sp value ep conjuction nonshapeComment { fr->createProjectionCmd(Vector($3), Vector($5), $7, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | CIRCLE3D_ bp coord sp value ep conjuction nonshapeComment { // backward compatibility fr->createCircleCmd(Vector($3), $5, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | COMPOSITE_ bp coord sp optangle ep conjuction nonshapeComment { fr->createCompositeCmd(Vector($3), $5, localComposite, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } ; shape : CIRCLE_ bp coord sp value ep conjuction shapeComment { fr->createCircleCmd(Vector($3), $5, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | CIRCLE3D_ bp coord sp value ep conjuction shapeComment { // backwards compatibility fr->createCircleCmd(Vector($3), $5, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp optangle ep conjuction shapeComment { // for ellipse annulus aStatus = 1; aCenter = Vector($3); aAngles[0] = $7; aVector[0] = Vector($5); aNumsao = 1; strncpy(aColor,localColor,16); aDash[0] = localDash[0]; aDash[1] = localDash[1]; aWidth = localWidth; strncpy(aFont,localFont,32); strncpy(aText,localText,80); strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector($3), Vector($5), $7, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOX_ bp coord sp vvalue sp optangle ep conjuction shapeComment { // for box annulus aStatus = 3; aCenter = Vector($3); aAngles[0] = $7; aVector[0] = Vector($5); aNumsao = 1; strncpy(aColor,localColor,16); aDash[0] = localDash[0]; aDash[1] = localDash[1]; aWidth = localWidth; strncpy(aFont,localFont,32); strncpy(aText,localText,80); strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector($3), Vector($5), $7, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ROTBOX_ bp coord sp vvalue sp optangle ep conjuction shapeComment { // backwards compatibility fr->createBoxCmd(Vector($3), Vector($5), $7, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | POLYGON_ {polylist.deleteAll();} bp polyNodes ep conjuction shapeComment { fr->createPolygonCmd(polylist, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | LINE_ bp coord sp coord ep conjuction shapeComment { fr->createLineCmd(Vector($3), Vector($5), localLine1,localLine2, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | VECTOR_ bp coord sp value sp angle ep conjuction shapeComment { fr->createVectCmd(Vector($3), $5,$7, localVector, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | TEXT_ bp coord ep conjuction shapeComment { fr->createTextCmd(Vector($3), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | TEXT_ bp coord sp STRING ep {strncpy(localText,$5,80);} conjuction shapeComment { fr->createTextCmd(Vector($3), localTextAngle,localTextRotate, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | POINT_ bp coord ep conjuction shapeComment { fr->createPointCmd(Vector($3), (Point::PointShape)localPoint, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | CIRCLE_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::CIRCLE, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOX_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::BOX, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | DIAMOND_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::DIAMOND, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | CROSS_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::CROSS, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | X_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::EX, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ARROW_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::ARROW, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOXCIRCLE_ POINT_ bp coord ep conjuction shapeComment { // backwards compatibility fr->createPointCmd(Vector($4), Point::BOXCIRCLE, localPointSize, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | RULER_ bp coord sp coord ep conjuction shapeComment { fr->createRulerCmd(Vector($3), Vector($5), localRulerCoordSystem, localRulerSkyFrame, localRulerDistSystem, localRulerDistFormat, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | COMPASS_ bp coord sp value ep conjuction shapeComment { fr->createCompassCmd(Vector($3), $5, localCompassNorth, localCompassEast, localCompassNArrow, localCompassEArrow, localCompassCoordSystem, localCompassSkyFrame, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | PROJECTION_ bp coord sp coord sp value ep conjuction shapeComment { fr->createProjectionCmd(Vector($3), Vector($5), $7, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ANNULUS_ bp coord sp value sp value ep conjuction shapeComment { fr->createAnnulusCmd(Vector($3), $5,$7,1, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ANNULUS_ bp coord sp value sp value sp aRads ep conjuction shapeComment { aAnnuli[0] = $5; aAnnuli[1] = $7; fr->createAnnulusCmd(Vector($3), aNum,aAnnuli, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ANNULUS_ bp coord sp value sp value sp numberof ep conjuction shapeComment { fr->createAnnulusCmd(Vector($3), $5,$7,$9, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp vvalue sp optangle ep conjuction shapeComment { // prefered syntax fr->createEllipseAnnulusCmd(Vector($3), Vector($5),Vector($7),1, $9, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp vvalue sp numberof sp optangle ep conjuction shapeComment { // prefered syntax fr->createEllipseAnnulusCmd(Vector($3), Vector($5),Vector($7),$9, $11, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp vvalue sp vRads sp optangle ep conjuction shapeComment { // prefered syntax aVector[0] = Vector($5); aVector[1] = Vector($7); fr->createEllipseAnnulusCmd(Vector($3), aNum,aVector, $11, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | ELLIPSE_ bp coord sp vvalue sp optangle ep '&' '!' ELLIPSE_ bp coord sp vvalue sp optangle ep { // backwards compatibility // old saoimage syntax aStatus = 2; aVector[aNumsao++] = Vector($5); } | BOX_ bp coord sp vvalue sp vvalue sp optangle ep conjuction shapeComment { // prefered syntax fr->createBoxAnnulusCmd(Vector($3), Vector($5),Vector($7),1, $9, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOX_ bp coord sp vvalue sp vvalue sp vRads sp optangle ep conjuction shapeComment { // prefered syntax aVector[0] = Vector($5); aVector[1] = Vector($7); fr->createBoxAnnulusCmd(Vector($3), aNum,aVector, $11, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOX_ bp coord sp vvalue sp vvalue sp numberof sp optangle ep conjuction shapeComment { // prefered syntax fr->createBoxAnnulusCmd(Vector($3), Vector($5),Vector($7),$9, $11, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } | BOX_ bp coord sp vvalue sp optangle ep '&' '!' BOX_ bp coord sp vvalue sp optangle ep { // backwards compatibility // old saoimage syntax aStatus = 4; aVector[aNumsao++] = Vector($5); } | CPANDA_ bp coord sp angle sp angle sp INT sp value sp value sp INT ep conjuction shapeComment { switch (localCpanda) { case 0: /* ignore it */ break; case 1: /* normal cpanda */ fr->createCpandaCmd(Vector($3), $5,$7,$9, $11,$13,$15, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createCpandaCmd(Vector($3), aAngNum,aAngles, aNum,aAnnuli, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } } | EPANDA_ bp coord sp angle sp angle sp INT sp vvalue sp vvalue sp INT sp optangle ep conjuction shapeComment { switch (localEpanda) { case 0: /* ignore it */ break; case 1: /* normal epanda */ fr->createEpandaCmd(Vector($3), $5,$7,$9, Vector($11),Vector($13),$15, $17, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createEpandaCmd(Vector($3), aAngNum,aAngles, aNum,aVector, aAngle, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } } | BPANDA_ bp coord sp angle sp angle sp INT sp vvalue sp vvalue sp INT sp optangle ep conjuction shapeComment { switch (localBpanda) { case 0: /* ignore it */ break; case 1: /* normal bpanda */ fr->createBpandaCmd(Vector($3), $5,$7,$9, Vector($11),Vector($13),$15, $17, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; case 2: /* one of our special pandas */ fr->createBpandaCmd(Vector($3), aAngNum,aAngles, aNum,aVector, aAngle, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); break; } } | PIE_ bp coord sp angle sp angle ep conjuction shapeComment | PIE_ bp coord sp angle sp angle sp aAngs ep conjuction shapeComment | PIE_ bp coord sp angle sp angle sp numberof ep conjuction shapeComment | FIELD_ bp ep conjuction shapeComment | COMPOSITE_ bp coord sp optangle ep conjuction shapeComment { fr->createCompositeCmd(Vector($3), $5, localComposite, localColor,localDash,localWidth,localFont, localText,localProps,localComment,taglist,cblist); } ; polyNodes : polyNodes sp polyNode | polyNode ; polyNode : coord {polylist.append(new Vertex($1));} ; aRads : aRads sp aRad | aRad ; aRad : value { if (aNum < MAXANNULI) aAnnuli[aNum++] = $1; } ; aAngs : aAngs sp aAng | aAng ; aAng : angle { if (aAngNum < MAXANGLES) aAngles[aAngNum++] = $1; } ; vRads : vRads sp vRad | vRad ; vRad : value sp value {aVector[aNum++] = Vector($1,$3);} ; postLocal : /* empty */ { // old style annulus switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNumsao,aVector, aAngles[0], aColor,aDash,aWidth,aFont,aText,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNumsao,aVector, aAngles[0], aColor,aDash,aWidth,aFont,aText,aProps,aComment,taglist,cblist); break; } aStatus = 0; } ; %% static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } static Coord::CoordSystem checkWCSSystem() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::WCS; default: return localSystem; } } static Coord::SkyFrame checkWCSSky() { switch (localSystem) { case Coord::IMAGE: case Coord::PHYSICAL: return Coord::FK5; default: return localSky; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor16.h����������������������������������������������������������0000644�0001750�0001750�00000001324�11700666267�017375� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framergbtruecolor16_h__ #define __framergbtruecolor16_h__ #include "framergbtruecolor.h" #include "truecolor16.h" class FrameRGBTrueColor16 : public virtual FrameBase, public FrameRGBTrueColor, public TrueColor16 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor16::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor16::encodeTrueColor(src, ximage);} public: FrameRGBTrueColor16(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameRGBTrueColor16(); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscalergb.C����������������������������������������������������������������0000644�0001750�0001750�00000005722�11700666266�016263� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscalergb.h" ColorScaleRGB::ColorScaleRGB(int s) { size_ = s; psColors_ = new unsigned char[s]; memset(psColors_, '0', size_); } ColorScaleRGB::~ColorScaleRGB() { if (psColors_) delete [] psColors_; } LinearScaleRGB::LinearScaleRGB(int jj, int ss, unsigned char* colorCells, int count) : ColorScaleRGB(ss) { for (int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } LogScaleRGB::LogScaleRGB(int jj, int ss, unsigned char* colorCells, int count, double exp) : ColorScaleRGB(ss) { for (int ii=0; ii<ss; ii++) { double aa = log10(exp*double(ii)/ss +1) / log10(exp); int ll = (int)(aa * count); // aa can grow slightly greater than 1 if (ll>=count) ll = count-1; memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } PowScaleRGB::PowScaleRGB(int jj, int ss, unsigned char* colorCells, int count, double exp) : ColorScaleRGB(ss) { for (int ii=0; ii<ss; ii++) { double aa = (::pow(exp,double(ii)/ss) -1) / exp; int ll = (int)(aa * count); // should not be needed if (ll>=count) ll = count-1; memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } SqrtScaleRGB::SqrtScaleRGB(int jj, int ss, unsigned char* colorCells, int count) : ColorScaleRGB(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(sqrt(aa) * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } SquaredScaleRGB::SquaredScaleRGB(int jj, int ss, unsigned char* colorCells, int count) : ColorScaleRGB(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa*aa * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } AsinhScaleRGB::AsinhScaleRGB(int jj, int ss, unsigned char* colorCells, int count) : ColorScaleRGB(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(asinh(10*aa)/3 * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } SinhScaleRGB::SinhScaleRGB(int jj, int ss, unsigned char* colorCells, int count) : ColorScaleRGB(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(sinh(3*aa)/10 * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } HistEquScaleRGB::HistEquScaleRGB(int jj, int ss, unsigned char* colorCells, int count, double* hist, int histsize) : ColorScaleRGB(ss) { // if no histogram, return linear distribution if (!hist) for (int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } else for (int ii=0; ii<ss; ii++) { double aa = hist[ii*histsize/ss]; int ll = (int)(aa * count); memcpy(psColors_+ii, colorCells+ll*3+jj,1); } } ����������������������������������������������./saods9/saotk/frame/frametruecolor.C���������������������������������������������������������������0000644�0001750�0001750�00000024125�12107012362�016451� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "frametruecolor.h" #include "fitsimage.h" #include "ps.h" #include "sigbus.h" FrameTrueColor::FrameTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), Frame(i,c,item), FrameTrue(i,c,item) { colormapData =NULL; } FrameTrueColor::~FrameTrueColor() { if (colormapData) delete [] colormapData; } unsigned char* FrameTrueColor::blend(unsigned char* src, unsigned char* msk, int width, int height) { unsigned char* sptr = src; // 3 component unsigned char* mptr = msk; // 4 component, premultiplied for (int jj=0; jj<height; jj++) for (int ii=0; ii<width; ii++) { if (*(mptr+3)) { float aa = 1-maskAlpha; *sptr++ = *mptr++ + *sptr * aa; *sptr++ = *mptr++ + *sptr * aa; *sptr++ = *mptr++ + *sptr * aa; mptr++; } else { mptr+=4; sptr+=3; } } return src; } void FrameTrueColor::buildXImage(XImage* ximage, Coord::InternalSystem sys) { // we need a colorScale before we can render if (!validColorScale()) return; unsigned char* img = fillImage(ximage->width, ximage->height, sys); if (img) encodeTrueColor(img, ximage); delete [] img; } void FrameTrueColor::colormapCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) { cmapID = id; bias = b; contrast = c; invert = i; updateColorCells(index, cells, cnt); updateColorScale(); update(BASE); } void FrameTrueColor::colormapBeginCmd() { // we need a colorScale before we can render if (!validColorScale()) return; // we need some fits data // we assume the colorScale length will not change during motion calls if (!context->cfits) return; int width = options->width; int height = options->height; // Create XImage if (!(colormapXM = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap))) { internalError("Unable to Create Colormap XImage"); return; } // Create Pixmap colormapPM = Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth); if (!colormapPM) { internalError("Unable to Create Colormap Pixmap"); return; } // colormapGCXOR colormapGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); // Create table index array if (colormapData) delete [] colormapData; colormapData = new long[width*height]; if (!colormapData) { internalError("Unable to alloc tmp data array"); return; } // fill data array // basics int bytesPerPixel = colormapXM->bits_per_pixel/8; int length = colorScale->size() - 1; int last = length * bytesPerPixel; FitsImage* sptr = context->cfits; int mosaic = isMosaic(); long* dest = colormapData; // variable double* mm = sptr->matrixToData(Coord::WIDGET).mm(); FitsBound* params = sptr->getDataParams(context->frScale.scanMode()); int srcw = sptr->width(); double ll = sptr->getLowDouble(); double hh = sptr->getHighDouble(); double diff = hh - ll; // main loop SETSIGBUS for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest++) { // default is bg *dest = -2; if (mosaic) { sptr = context->cfits; mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); if (isfinite(value)) { if (value <= ll) *dest = 0; else if (value >= hh) *dest = last; else *dest = (int)(((value - ll)/diff * length) + .5)*bytesPerPixel; } else *dest = -1; break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(Coord::WIDGET).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); ll = sptr->getLowDouble(); hh = sptr->getHighDouble(); diff = hh - ll; } } } } while (mosaic && sptr); } } CLEARSIGBUS } void FrameTrueColor::colormapMotionCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) { // we need a colorScale before we can render if (!validColorScale()) return; // first check for change if (cmapID == id && bias == b && contrast == c && invert == i && colorCells) return; // we got a change cmapID = id; bias = b; contrast = c; invert = i; updateColorCells(index, cells, cnt); updateColorScale(); // if we have no data, stop now if (!context->cfits) return; // clear ximage int& width = colormapXM->width; int& height = colormapXM->height; char* data = XImageData(colormapXM); int bytesPerPixel = colormapXM->bits_per_pixel/8; int& bytesPerLine = colormapXM->bytes_per_line; const unsigned char* table = colorScale->colors(); long* src = colormapData; for (long jj=0; jj<height; jj++) { // line may be padded at end char* dest = data + jj*bytesPerLine; for (long ii=0; ii<width; ii++, src++, dest+=bytesPerPixel) switch (*src) { case -1: memcpy(dest, nanTrueColor_, bytesPerPixel); break; case -2: memcpy(dest, bgTrueColor_, bytesPerPixel); break; default: memcpy(dest, table+(*src), bytesPerPixel); break; } } // XImage to Pixmap XPutImage(display, colormapPM, gc, colormapXM, 0, 0, 0, 0, width, height); // Display Pixmap Vector dd = Vector() * widgetToWindow; XCopyArea(display, colormapPM, Tk_WindowId(tkwin), colormapGCXOR, 0, 0, width, height, dd[0], dd[1]); // update panner updatePanner(); } void FrameTrueColor::colormapEndCmd() { if (colormapXM) { XDestroyImage(colormapXM); colormapXM = NULL; } if (colormapPM) { Tk_FreePixmap(display, colormapPM); colormapPM = 0; } if (colormapGCXOR) { XFreeGC(display, colormapGCXOR); colormapGCXOR = 0; } if (colormapData) { delete [] colormapData; colormapData = NULL; } update(BASE); // always update } unsigned char* FrameTrueColor::fillImage(int width, int height, Coord::InternalSystem sys) { unsigned char* img = Frame::fillImage(width, height, sys); if (context->mask.head()) { FitsMask* mptr = context->mask.tail(); while (mptr) { unsigned char* msk = fillMask(mptr, width, height, sys); blend(img,msk,width,height); delete [] msk; mptr = mptr->previous(); } } return img; } unsigned char* FrameTrueColor::fillMask(FitsMask* msk, int width, int height, Coord::InternalSystem sys) { FitsImage* currentMsk = msk->current(); XColor* maskColor = msk->color(); int mark = msk->mark(); // img unsigned char* img = new unsigned char[width*height*4]; memset(img,0,width*height*4); if (!currentMsk) return img; // basics FitsImage* sptr = currentMsk; int mosaic = isMosaic(); // variable double* mm = sptr->matrixToData(sys).mm(); FitsBound* params = sptr->getDataParams(context->frScale.scanMode()); int srcw = sptr->width(); // main loop unsigned char* dest = img; SETSIGBUS for (long jj=0; jj<height; jj++) { for (long ii=0; ii<width; ii++, dest+=4) { if (mosaic) { sptr = currentMsk; mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); } do { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx>=params->xmin && xx<params->xmax && yy>=params->ymin && yy<params->ymax) { int value = sptr->getValueMask(long(yy)*srcw + long(xx)); if ((mark && value) || (!mark && !value)) { *dest = ((unsigned char)maskColor->red)*maskAlpha; *(dest+1) = ((unsigned char)maskColor->green)*maskAlpha; *(dest+2) = ((unsigned char)maskColor->blue)*maskAlpha; *(dest+3) = 1; } break; } else { if (mosaic) { sptr = sptr->nextMosaic(); if (sptr) { mm = sptr->matrixToData(sys).mm(); params = sptr->getDataParams(context->frScale.scanMode()); srcw = sptr->width(); } } } } while (mosaic && sptr); } } CLEARSIGBUS return img; } void FrameTrueColor::pushMatrices() { Base::pushMatrices(); // alway identity Matrix rgbToRef; // now any masks FitsMask* msk = currentContext->mask.tail(); while (msk) { FitsImage* mskimg = msk->mask(); while (mskimg) { FitsImage* sptr = mskimg; while (sptr) { sptr->updateMatrices(rgbToRef, refToWidget, widgetToCanvas); sptr = sptr->nextSlice(); } mskimg = mskimg->nextMosaic(); } msk = msk->previous(); } } void FrameTrueColor::pushMagnifierMatrices() { Base::pushMagnifierMatrices(); FitsMask* msk = context->mask.tail(); while (msk) { FitsImage* mskimg = msk->mask(); while (mskimg) { FitsImage* sptr = mskimg; while (sptr) { sptr->updateMagnifierMatrices(refToMagnifier); sptr = sptr->nextSlice(); } mskimg = mskimg->nextMosaic(); } msk = msk->previous(); } } void FrameTrueColor::pushPannerMatrices() { Base::pushPannerMatrices(); FitsMask* msk = context->mask.tail(); while (msk) { FitsImage* mskimg = msk->mask(); while (mskimg) { FitsImage* sptr = mskimg; while (sptr) { sptr->updatePannerMatrices(refToPanner); sptr = sptr->nextSlice(); } mskimg = mskimg->nextMosaic(); } msk = msk->previous(); } } void FrameTrueColor::pushPSMatrices(float scale, int width, int height) { Base::pushPSMatrices(scale, width, height); Matrix mx = psMatrix(scale, width, height); FitsMask* msk = context->mask.tail(); while (msk) { FitsImage* ptr = msk->current(); while (ptr) { ptr->updatePS(mx); ptr = ptr->nextMosaic(); } msk = msk->previous(); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/marker.C�����������������������������������������������������������������������0000644�0001750�0001750�00000115776�12057220626�014726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "marker.h" #include "fitsimage.h" #include "blt.h" #include "bltVector.h" static int markerSeqID = 1; // hard coded char* Marker::analysisPlot2dCB_[] = { "MarkerAnalysisPlot2dCB", "MarkerAnalysisPlot2dDeleteCB" }; char* Marker::analysisPlot3dCB_[] = { "MarkerAnalysisPlot3dCB", "MarkerAnalysisPlot3dDeleteCB" }; char* Marker::analysisPandaCB_[] = { "MarkerAnalysisPandaCB", "MarkerAnalysisPandaDeleteCB" }; char* Marker::analysisRadialCB_[] = { "MarkerAnalysisRadialCB", "MarkerAnalysisRadialDeleteCB" }; char* Marker::analysisStatsCB_[] = { "MarkerAnalysisStatsCB", "MarkerAnalysisStatsDeleteCB" }; // Marker Members Public Marker::Marker(const Marker& a) { id = a.id; strcpy(type_, a.type_); parent = a.parent; center = a.center; bbox = a.bbox; allBBox = a.allBBox; angle = a.angle; numHandle = a.numHandle; if (numHandle) { handle = new Vector[numHandle]; for (int i=0; i<numHandle; i++) handle[i] = a.handle[i]; } else handle = NULL; colorName = dupstr(a.colorName); color = a.color; lineWidth = a.lineWidth; properties = a.properties; selected = a.selected; highlited = a.highlited; dlist[0] = a.dlist[0]; dlist[1] = a.dlist[1]; text = dupstr(a.text); tkfont_ = Tk_GetFont(parent->interp, parent->tkwin, Tk_NameOfFont(a.tkfont_)); psfont_ = Tk_GetFont(parent->interp, parent->tkwin, Tk_NameOfFont(a.psfont_)); comment = dupstr(a.comment); display = a.display; gc = a.gc; gcxor = a.gcxor; for (int ii=0; ii<XMLNUMCOL; ii++) XMLCol[ii] = NULL; // disable Callbacks by default doCB = 0; tags = a.tags; callbacks = a.callbacks; previous_ = NULL; next_ = NULL; analysisPlot2d_ = a.analysisPlot2d_; analysisPlot3d_ = a.analysisPlot3d_; analysisPanda_ = a.analysisPanda_; analysisRadial_ = a.analysisRadial_; analysisStats_ = a.analysisStats_; } Marker::Marker(Base* p, const Vector& ctr, double ang, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tg, const List<CallBack>& cb) { id = markerSeqID++; type_[0] = '\0'; parent = p; center = ctr; angle = ang; handle = NULL; numHandle = 0; colorName = dupstr(clr); color = parent->getColor(colorName); lineWidth = w; properties = prop; selected = 0; highlited = 0; dlist[0] = dsh[0]; dlist[1] = dsh[1]; text = dupstr(t); tkfont_ =NULL; psfont_ =NULL; initFonts(f); comment = dupstr(c); display = parent->display; gc = parent->markerGC; gcxor = parent->markerGCXOR; for (int ii=0; ii<XMLNUMCOL; ii++) XMLCol[ii] = NULL; doCB = 1; tags = tg; callbacks = cb; previous_ = NULL; next_ = NULL; analysisPlot2d_ =0; analysisPlot3d_ =0; analysisPanda_ =0; analysisRadial_ =0; analysisStats_ =0; } Marker::~Marker() { if (colorName) delete [] colorName; if (text) delete [] text; if (comment) delete [] comment; if (tkfont_) Tk_FreeFont(tkfont_); if (psfont_) Tk_FreeFont(psfont_); if (handle) delete [] handle; for (int ii=0; ii<XMLNUMCOL; ii++) if (XMLCol[ii]) delete [] XMLCol[ii]; doCallBack(CallBack::DELETECB); } void Marker::x11(Drawable drawable, Coord::InternalSystem sys, int tt, RenderMode mode, HandleMode hh) { if (hh==HANDLES) renderXHandles(drawable); if (tt) renderXText(drawable, sys, mode); renderX(drawable, sys, mode); renderXInclude(drawable, sys, mode); } void Marker::renderXInclude(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { if (!(properties & INCLUDE)) { GC lgc = renderXGC(mode); Vector ll = (handle[0]*parent->canvasToWidget).round(); Vector ur = (handle[2]*parent->canvasToWidget).round(); if (mode==SRC) XSetForeground(display, gc, parent->getColor("red")); XDrawLine(display, drawable, lgc, ll[0], ll[1], ur[0], ur[1]); } } void Marker::renderXText(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { if (text && *text && tkfont_) { GC lgc; switch (mode) { case SRC: lgc = gc; XSetForeground(display, gc, color); break; case XOR: lgc = gcxor; break; } XSetFont(display, lgc, Tk_FontId(tkfont_)); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); Matrix mm; Matrix nn; setMatrices(sys,&mm,&nn); Vector ll0 = bbox.ll*parent->canvasToRef; Vector ll = ll0*mm; Vector ur0 = bbox.ur*parent->canvasToRef; Vector ur = ur0*mm; BBox bb(ll,ur); Vector bbc = bb.center(); Vector tt = Vector(bbc[0], bb.ll[1]) * Translate(-width/2., -metrics.descent); Tk_DrawChars(display, drawable, lgc, tkfont_, text, strlen(text), tt[0], tt[1]); } } void Marker::renderXArrow(Drawable drawable, const Vector& p1, const Vector& p2, Coord::InternalSystem sys, GC lgc) { Vector* vv = arrow(p1,p2,sys); XPoint dd[6]; for (int ii=0; ii<6; ii++) { dd[ii].x = (short)vv[ii][0]; dd[ii].y = (short)vv[ii][1]; } XFillPolygon(display, drawable, lgc, dd, 6, Nonconvex, CoordModeOrigin); delete [] vv; } void Marker::renderXHandles(Drawable drawable) { // handles are of length 5 if (selected && canSelect()) { XSetForeground(display, gc, color); for (int ii=0; ii<numHandle; ii++) { Vector vv = (handle[ii]*parent->canvasToWidget - Vector(2,2)).round(); XFillRectangle(display, drawable, gc, vv[0], vv[1], 5, 5); } } } GC Marker::renderXGC(RenderMode mode) { // set width, color, dash switch (mode) { case SRC: XSetForeground(display, gc, color); if ((properties & SOURCE) && !(properties & DASH)) renderXLineNoDash(gc); else renderXLineDash(gc); return gc; case XOR: renderXLineDash(gcxor); return gcxor; } } void Marker::renderXLineDash(GC lgc) { char dl[2]; #ifdef _WIN32 dl[0] = dlist[0]/2; dl[1] = dlist[1]/2; #else dl[0] = dlist[0]; dl[1] = dlist[1]; #endif int ww = (highlited && canHighlite()) ? lineWidth*2 : lineWidth; XSetDashes(display, lgc, 0, dl, 2); XSetLineAttributes(display, lgc, ww, LineOnOffDash, CapButt, JoinMiter); } void Marker::renderXLineNoDash(GC lgc) { int ww = (highlited && canHighlite()) ? lineWidth*2 : lineWidth; XSetLineAttributes(display, lgc, ww, LineSolid, CapButt, JoinMiter); } void Marker::ps(int mode, int tt) { if (tt) renderPSText(mode); renderPS(mode); renderPSInclude(mode); } void Marker::renderPSInclude(int mode) { if (!(properties & INCLUDE)) { renderPSColor(mode, parent->getXColor("red")); Vector ll = handle[0]; Vector ur = handle[2]; ostringstream str; str << "newpath " << ll.TkCanvasPs(parent->canvas) << "moveto" << ur.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } void Marker::renderPSText(int mode) { if (text && *text && psfont_) { renderPSColor(mode, parent->getXColor(colorName)); ostringstream str; const char* ff = Tk_NameOfFont(psfont_); str << '/' << psFontName(ff) << " findfont " << int(psFontSize(ff)*parent->getDisplayRatio()) << " scalefont setfont" << endl; Vector bbc = bbox.center(); Vector tt = Vector(bbc[0], bbox.ll[1]).TkCanvasPs(parent->canvas); str << "gsave" << endl << "newpath " << endl << tt << " moveto" << endl << '(' << psQuote(text) << ')' << endl << "dup true charpath pathbbox " << endl << "closepath " << endl << "3 -1 roll sub 2.5 div " << endl << "3 1 roll sub 2 div exch " << endl << tt << " moveto rmoveto show " << endl << "grestore" << endl; str << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); } } void Marker::renderPSArrow(const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { Vector* vv = arrow(p1,p2,sys); ostringstream str; str << "newpath " << endl << vv[0].TkCanvasPs(parent->canvas) << " moveto" << endl; for (int ii=1; ii<6; ii++) str << vv[ii].TkCanvasPs(parent->canvas) << " lineto" << endl; str << "closepath fill" << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); delete [] vv; } void Marker::renderPSGC(int mode) { // set width, color, dash renderPSColor(mode, parent->getXColor(colorName)); if ((properties & SOURCE) && !(properties & DASH)) renderPSLineNoDash(); else renderPSLineDash(); } void Marker::renderPSLineDash() { ostringstream str; str << lineWidth << " setlinewidth" << endl << '[' << dlist[0] << ' ' << dlist[1] << "] 0 setdash" << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); } void Marker::renderPSLineNoDash() { ostringstream str; str << lineWidth << " setlinewidth" << endl << "[] 0 setdash" << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); } void Marker::renderPSColor(int mode, XColor* clr) { ostringstream str; switch ((Widget::PSColorSpace)mode) { case Widget::BW: case Widget::GRAY: psColorGray(clr, str); str << " setgray"; break; case Widget::RGB: psColorRGB(clr, str); str << " setrgbcolor"; break; case Widget::CMYK: psColorCMYK(clr, str); str << " setcmykcolor"; break; } str << endl << ends; Tcl_AppendResult(parent->interp, (char*)str.str().c_str(), NULL); } #ifdef _MACOSX void Marker::macosx(int tt) { if (tt) renderMACOSXText(); renderMACOSX(); renderMACOSXInclude(); } void Marker::renderMACOSXInclude() { if (!(properties & INCLUDE)) { macosxColor(parent->getXColor("red")); Vector ll = handle[0]; Vector ur = handle[2]; macosxDrawLine(ll,ur); } } void Marker::renderMACOSXText() { if (text && *text && psfont_) { macosxColor(parent->getXColor(colorName)); Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(psfont_, &psdstr); macosxFont(Tcl_DStringValue(&psdstr), psSize); Tcl_DStringFree(&psdstr); Tk_FontMetrics metrics; Tk_GetFontMetrics(psfont_, &metrics); int width = Tk_TextWidth(psfont_, text, strlen(text)); Vector bbc = bbox.center(); Vector tt = Vector(bbc[0], bbox.ll[1]) * Translate(-width/2., -metrics.descent); macosxDrawText(tt, 0, text); } } void Marker::renderMACOSXArrow(const Vector& p1, const Vector& p2, InternalSystem sys) { Vector* vv = arrow(p1,p2,sys); Vector dd[6]; for (int ii=0; ii<6; ii++) dd[ii] = vv[ii]; macosxFillPolygon(dd,6); delete [] vv; } void Marker::renderMACOSXGC() { // set width, color, dash macosxColor(parent->getXColor(colorName)); if ((properties & SOURCE) && !(properties & DASH)) renderMACOSXLineNoDash(); else renderMACOSXLineDash(); } void Marker::renderMACOSXLineDash() { macosxWidth(lineWidth); macosxDash(dlist,2); } void Marker::renderMACOSXLineNoDash() { macosxWidth(lineWidth); macosxDash(NULL,0); } #endif #ifdef _WIN32 void Marker::win32(int tt) { if (tt) renderWIN32Text(); renderWIN32(); renderWIN32Include(); } void Marker::renderWIN32Include() { if (!(properties & INCLUDE)) { win32Color(parent->getXColor("red")); Vector ll = handle[0]; Vector ur = handle[2]; win32DrawLine(ll,ur); } } void Marker::renderWIN32Text() { if (text && *text && tkfont_) { win32Color(parent->getXColor(colorName)); win32Font(tkfont_); Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); BBox bb = bbox; Vector bbc = bb.center(); Vector tt = Vector(bbc[0], bbox.ll[1]) * Translate(-width/2., -metrics.descent); win32DrawText(tt, 0, text); } } void Marker::renderWIN32Arrow(const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { Vector* vv = arrow(p1,p2,sys); Vector dd[6]; for (int ii=0; ii<6; ii++) dd[ii] = vv[ii]; win32FillPolygon(dd,6); delete [] vv; } void Marker::renderWIN32GC() { // set width, color, dash win32Color(parent->getXColor(colorName)); if ((properties & SOURCE) && !(properties & DASH)) renderWIN32LineNoDash(); else renderWIN32LineDash(); } void Marker::renderWIN32LineDash() { win32Width(lineWidth); win32Dash(dlist,2); } void Marker::renderWIN32LineNoDash() { win32Width(lineWidth); win32Dash(NULL,0); } #endif // Support void Marker::updateBBox() { // generate handles updateHandles(); // bound handles bbox = BBox(handle[0]); for (int ii=1; ii<numHandle; ii++) bbox.bound(handle[ii]); // make room for handles bbox.expand(3); // calculate overall bbox calcAllBBox(); } void Marker::calcAllBBox() { allBBox = bbox; if (text && *text && tkfont_) { Tk_FontMetrics metrics; Tk_GetFontMetrics(tkfont_, &metrics); int width = Tk_TextWidth(tkfont_, text, strlen(text)); Vector bbc = bbox.center(); Vector ll = Vector(bbc[0], bbox.ll[1]) * Translate(-width/2., 0); Vector ur = ll * Translate(width, -(metrics.linespace)); allBBox.bound(ll); allBBox.bound(ur); } } void Marker::deleteCBs() { callbacks.deleteAll(); } void Marker::newIdentity() { id = markerSeqID++; doCB = 1; // deleteCBs(); updateBBox(); } void Marker::updateCoords(const Matrix& mx) { center*=mx; updateBBox(); } void Marker::centroid() { center = parent->centroid(center); updateBBox(); doCallBack(CallBack::MOVECB); } void Marker::moveTo(const Vector& v) { center=v; updateBBox(); doCallBack(CallBack::MOVECB); } void Marker::moveBegin() { doCallBack(CallBack::MOVEBEGINCB); } void Marker::move(const Vector& v) { center+=v; updateBBox(); doCallBack(CallBack::MOVECB); } void Marker::moveEnd() { doCallBack(CallBack::MOVEENDCB); } void Marker::editBegin(int) { doCallBack(CallBack::EDITBEGINCB); } void Marker::edit(const Vector& v, int h) { doCallBack(CallBack::EDITCB); } void Marker::editEnd() { doCallBack(CallBack::EDITENDCB); } void Marker::rotateBegin() { doCallBack(CallBack::ROTATEBEGINCB); } void Marker::rotate(const Vector& v, int h) { // v is in ref coords // handles are in canvas coords double a = (v * Translate(-center) * FlipY()).angle(); double b = ((parent->mapToRef(handle[h-1],Coord::CANVAS) * Translate(-center) * FlipY())).angle(); angle -= a-b; updateBBox(); doCallBack(CallBack::ROTATECB); } void Marker::rotateEnd() { doCallBack(CallBack::ROTATEENDCB); } void Marker::select() { // only call the CB if not already selected if (!selected) doCallBack(CallBack::SELECTCB); selected = 1; } void Marker::unselect() { // only call the CB if already selected if (selected) doCallBack(CallBack::UNSELECTCB); selected = 0; } void Marker::toggleSelect() { selected = !selected; if (selected) doCallBack(CallBack::SELECTCB); else doCallBack(CallBack::UNSELECTCB); } void Marker::highlite() { // only call the CB if not already highlited if (!highlited) doCallBack(CallBack::HIGHLITECB); highlited = 1; } void Marker::unhighlite() { // only call the CB if already highlited if (highlited) doCallBack(CallBack::UNHIGHLITECB); highlited = 0; } void Marker::toggleHighlite() { highlited = !highlited; if (highlited) doCallBack(CallBack::HIGHLITECB); else doCallBack(CallBack::UNHIGHLITECB); } void Marker::key() { doCallBack(CallBack::KEYCB); } Vector Marker::getHandle(int h) { if (h<numHandle) return handle[h]; else return Vector(); } void Marker::setAngle(double a) { angle = a; updateBBox(); doCallBack(CallBack::ROTATECB); } void Marker::setColor(const char* clr) { if (colorName) delete [] colorName; colorName = dupstr(clr); color = parent->getColor(colorName); doCallBack(CallBack::COLORCB); } void Marker::setLineWidth(int w) { lineWidth = w; doCallBack(CallBack::LINEWIDTHCB); } void Marker::setFont(const char* f) { initFonts(f); updateBBox(); doCallBack(CallBack::FONTCB); } void Marker::initFonts(const char* ff) { if (tkfont_) Tk_FreeFont(tkfont_); tkfont_ = NULL; if (psfont_) Tk_FreeFont(psfont_); psfont_ = NULL; char* dd = "helvetica 9 roman normal"; if (!ff) ff = dd; psfont_ = Tk_GetFont(parent->interp, parent->tkwin, ff); // determine tkfont from psfont char* ptr = (char*)ff; while (*ptr && *ptr != ' ') ptr++; ostringstream fstr; if (!strncmp(ff,"helvetica",4)) fstr << '{' << parent->options->helvetica << '}' << ptr << ends; else if (!strncmp(ff,"times",4)) fstr << '{' << parent->options->times << '}' << ptr << ends; else if (!strncmp(ff,"courier",4)) fstr << '{' << parent->options->courier << '}' << ptr << ends; else fstr << '{' << parent->options->helvetica << '}' << ptr << ends; tkfont_ = Tk_GetFont(parent->getInterp(), parent->getTkwin(), fstr.str().c_str()); } const char* Marker::getFont() { if (psfont_) return Tk_NameOfFont(psfont_); else return NULL; } void Marker::addTag(const char* tg) { Tag* t = new Tag(tg); tags.append(t); } void Marker::editTag(const char* from, const char* to) { // change any tags { Tag* t = tags.head(); while (t) { if (!strcmp(t->tag(),from)) { t->set(to); } t=t->next(); } } // now, remove duplicates { Tag* t = tags.head(); while (t) { Tag* tt=t->next(); while (tt) { if (!strcmp(t->tag(),tt->tag())) { Tag* ntt = tags.extractNext(tt); delete tt; tt = ntt; } else tt=tt->next(); } t=t->next(); } } } void Marker::deleteTags() { tags.deleteAll(); } void Marker::deleteTag(const char* tg) { Tag* t = tags.head(); while (t) { if (!strcmp(t->tag(),tg)) { tags.extractNext(t); delete t; return; } t = t->next(); } } void Marker::deleteTag(int w) { Tag* t = tags.head(); for (int i=0; i<w; i++) if (t) t = t->next(); else break; if (t) { tags.extractNext(t); delete t; } } const char* Marker::getTag() { Tag* t = tags.head(); if (t) return t->tag(); else return NULL; } const char* Marker::getNextTag() { Tag* t = tags.next(); if (t) return t->tag(); else return NULL; } const char* Marker::getTag(int w) { Tag* t = tags.head(); for (int i=0; i<w; i++) if (t) t = t->next(); else break; if (t) return t->tag(); else return NULL; } int Marker::hasTag(const char* tg) { Tag* t = tags.head(); while (t) { if (!strcmp(t->tag(),tg)) return 1; t = t->next(); } return 0; } int Marker::onHandle(const Vector& v) { // return handle number // work last to first for annuli for (int ii=numHandle-1; ii>=0; ii--) { BBox bb(handle[ii]); bb.expand(2); if (bb.isIn(v)) return ii+1; } return 0; } int Marker::getProperty(unsigned short which) { return (properties & which) ? 1 : 0; } void Marker::setText(const char* str) { if (text) delete [] text; text = dupstr(str); updateBBox(); doCallBack(CallBack::TEXTCB); } void Marker::setProperty(unsigned short prop, int value) { if (value) properties |= prop; else properties &= ~prop; if (prop == FIXED) // bbox will change updateBBox(); doCallBack(CallBack::PROPERTYCB); } int Marker::addCallBack(CallBack::Type t, const char* proc, const char* arg) { CallBack* cb = new CallBack(parent->interp, t, proc, arg); if (cb) { callbacks.append(cb); return TCL_OK; } return TCL_ERROR; } void Marker::deleteCallBack(CallBack::Type t) { CallBack* cb = callbacks.head(); while (cb) { if (cb->type() == t) { CallBack* next = callbacks.extractNext(cb); delete cb; cb = next; } else cb = cb->next(); } } int Marker::deleteCallBack(CallBack::Type t, const char* proc) { CallBack* cb = callbacks.head(); while (cb) { if (cb->type() == t && (!strcmp(cb->proc(), proc))) { callbacks.extractNext(cb); delete cb; return TCL_OK; } else cb = cb->next(); } return TCL_ERROR; } int Marker::isIn(const Vector& vv, Coord::InternalSystem sys) { Vector rr = parent->mapToRef(vv,sys); Vector ss = parent->mapFromRef(rr,Coord::CANVAS); return bbox.isIn(ss); } int Marker::isVisible(const BBox& b) { // assume visible, prove otherwise // all coords are in canvas coords BBox bb(b); return !((allBBox.ur[0] < bb.ll[0]) || (allBBox.ll[0] > bb.ur[0]) || (allBBox.ur[1] < bb.ll[1]) || (allBBox.ll[1] > bb.ur[1])); } void Marker::doCallBack(CallBack::Type t) { if (!doCB) return; ostringstream str; str << id << ends; CallBack* cb=callbacks.head(); while (cb) { if (cb->type() == t) if (cb->eval(str.str().c_str())) { ostringstream estr; estr << "Unable to eval Marker CallBack " << cb->proc() << " : " << parent->interp->result << ends; internalError(estr.str().c_str()); } cb=cb->next(); } } double Marker::calcAngle() { switch (parent->getOrientation()) { case Coord::NORMAL: case Coord::XY: return angle + parent->getRotation(); case Coord::XX: case Coord::YY: return -angle + parent->getRotation(); } } Vector Marker::modifyArrow(const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { const int tip = 6; // length from end of line to tip of arrow Vector aa = parent->mapFromRef(p1,sys); Vector bb = parent->mapFromRef(p2,sys); Vector nn = (bb-aa).normalize(); double ll = (bb-aa).length(); return nn * Scale(ll-tip) * Translate(aa); } Vector* Marker::arrow(const Vector& p1, const Vector& p2, Coord::InternalSystem sys) { Vector p3; if (((p2-p1)[0]) == 0) p3 = p1+Vector(1,0); else p3 = p1+Vector(0,1); Vector3d aa = parent->mapFromRef3d(p1,sys); Vector3d bb = parent->mapFromRef3d(p2,sys); Vector3d cc = parent->mapFromRef3d(p3,sys); const int tip = 6; // length from end of line to tip of arrow const int tail = 2; // length from end of line to tails of arrow const int wc = 2; // width of arrow at end of line const int wt = 3; // width of arrow at tails // build in Y-Z plane, align on z axis Vector3d vv[6]; vv[0] = Vector3d(0,0,tip); vv[1] = Vector3d(0,-wc,0); vv[2] = Vector3d(0,-wt,-tail); vv[3] = Vector3d(0,0,0); vv[4] = Vector3d(0,wt,-tail); vv[5] = Vector3d(0,wc,0); Vector3d l1 = (aa-bb).normalize(); Vector3d l2 = (aa-cc).normalize(); Vector3d rz = -l1; Vector3d rx = (cross(l1,l2)).normalize(); Vector3d ry = cross(rz,rx); Matrix3d rr(rx,ry,rz); Matrix3d mm = Translate3d(0,0,-tip) * Scale3d(1.5) * rr.invert() * Translate3d(bb); Vector* ww = new Vector[6]; for (int ii=0; ii<6; ii++) ww[ii] = vv[ii]*mm; return ww; } void Marker::analysisPlot2dResult(char* xname, char* yname, char* xcname, char* ycname, double* x, double* y, double* xc, double* yc, int num) { Blt_Vector* xx; Blt_GetVector(parent->getInterp(), xname, &xx); Blt_ResetVector(xx, x, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* yy; Blt_GetVector(parent->getInterp(), yname, &yy); Blt_ResetVector(yy, y, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* xxc; Blt_GetVector(parent->getInterp(), xcname, &xxc); Blt_ResetVector(xxc, xc, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* yyc; Blt_GetVector(parent->getInterp(), ycname, &yyc); Blt_ResetVector(yyc, yc, num, num*sizeof(double), TCL_DYNAMIC); } void Marker::analysisPlot3dResult(char* xname, char* yname, double* x, double* y, int num) { Blt_Vector* xx; Blt_GetVector(parent->getInterp(), xname, &xx); Blt_ResetVector(xx, x, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* yy; Blt_GetVector(parent->getInterp(), yname, &yy); Blt_ResetVector(yy, y, num, num*sizeof(double), TCL_DYNAMIC); } void Marker::analysisPandaResult(double* x, double* y, double* e, int num) { for (int ii=0; ii<num; ii++) { ostringstream str; str << x[ii] << ' ' << y[ii] << ' ' << e[ii] << endl; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } } void Marker::analysisRadialResult(char* xname, char* yname, char* ename, double* x, double* y, double* e, int num) { Blt_Vector* xx; Blt_GetVector(parent->getInterp(), xname, &xx); Blt_ResetVector(xx, x, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* yy; Blt_GetVector(parent->getInterp(), yname, &yy); Blt_ResetVector(yy, y, num, num*sizeof(double), TCL_DYNAMIC); Blt_Vector* ee; Blt_GetVector(parent->getInterp(), ename, &ee); Blt_ResetVector(ee, e, num, num*sizeof(double), TCL_DYNAMIC); } Matrix Marker::fwdMatrix() { return Rotate(angle) * FlipY() * Translate(center); } Matrix Marker::bckMatrix() { return Translate(-center) * FlipY() * Rotate(-angle); } Vector Marker::fwdMap(const Vector& vv, Coord::InternalSystem sys) { return parent->mapFromRef(vv * Rotate(angle) * FlipY() * Translate(center),sys); } Vector Marker::bckMap(const Vector& vv, Coord::InternalSystem sys) { return parent->mapToRef(vv,sys) * Translate(-center) * FlipY() * Rotate(-angle); } void Marker::setMatrices(Coord::InternalSystem sys, Matrix* fwd, Matrix* bck) { switch (sys) { case Coord::WIDGET: *fwd = parent->refToWidget; *bck = parent->widgetToRef; break; case Coord::CANVAS: *fwd = parent->refToCanvas; *bck = parent->canvasToRef; break; case Coord::WINDOW: *fwd = parent->refToWindow; *bck = parent->windowToRef; break; case Coord::MAGNIFIER: *fwd = parent->refToMagnifier; *bck = parent->magnifierToRef; break; } } // list void Marker::listPre(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, FitsImage* ptr, int strip, int hash) { // no props for semicolons if (!strip) { FitsImage* fits = parent->findFits(); if (fits && fits->nextMosaic()) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: str << "# tile " << parent->findFits(ptr) << endl; break; default: if (!parent->findFits()->hasWCSCel(sys)) str << "# tile " << parent->findFits(ptr) << endl; } } if (hash) str << "# "; } if (!(properties&INCLUDE)) str << '-'; } void Marker::listPost(ostream& str, int conj, int strip) { // no props for semicolons if (!strip) { if (conj) str << " ||"; listProperties(str,1); } else { if (conj) str << "||"; else str << ';'; } } void Marker::listProperties(ostream& str, int hash) { if (strncmp("green",colorName,5) || dlist[0] != 8 || dlist[1] != 3 || (lineWidth != 1) || strncmp("helvetica 10 normal roman",getFont(),25) || text[0] || !(properties&SELECT) || !(properties&HIGHLITE) || (properties&DASH) || (properties&FIXED) || !(properties&EDIT) || !(properties&MOVE) || !(properties&ROTATE) || !(properties&DELETE) || !(properties&SOURCE) || (tags.count() > 0) || (comment && *comment)) { if (hash) str << " #"; listProps(str); } str << endl; } void Marker::listProps(ostream& str) { if (strncmp("green",colorName,5)) str << " color=" << colorName; if (dlist[0] != 8 || dlist[1] != 3) str << " dashlist=" << dlist[0] << ' ' << dlist[1]; if (lineWidth != 1) str << " width=" << lineWidth; if (strncmp("helvetica 10 normal roman", getFont(), 25)) str << " font=\"" << getFont() << '"'; if (text && *text) // only list text if there is something to list str << " text={" << text << '}'; if (!(properties&SELECT)) str << " select=0"; if (!(properties&HIGHLITE)) str << " highlite=0"; if (properties&DASH) str << " dash=1"; if (properties&FIXED) str << " fixed=1"; if (!(properties&EDIT)) str << " edit=0"; if (!(properties&MOVE)) str << " move=0"; if (!(properties&ROTATE)) str << " rotate=0"; if (!(properties&DELETE)) str << " delete=0"; if (!(properties&SOURCE)) str << " background"; // tags Tag* t = tags.head(); while (t) { str << " tag={" << t->tag() << '}'; t = t->next(); } if (comment && *comment) str << ' ' << comment; } void Marker::listCiaoPre(ostream& str) { if (!(properties&INCLUDE)) str << '-'; } void Marker::listCiaoPost(ostream& str, int strip) { str << (strip ? ';' : '\n'); } void Marker::listProsPost(ostream& str, int strip) { str << (strip ? ';' : '\n'); } void Marker::listSAOtngPre(ostream& str, int strip) { if (!strip && text[0]) str << '#' << text << endl; if (properties&INCLUDE) str << '+'; else str << '-'; } void Marker::listSAOtngPost(ostream& str, int strip) { if (!strip) { str << " # "; if (comment && *comment) str << comment; else if (!(properties&SOURCE)) str << "background"; else str << colorName; } str << (strip ? ';' : '\n'); } void Marker::listSAOimagePre(ostream& str) { if (!(properties&INCLUDE)) str << '-'; } void Marker::listSAOimagePost(ostream& str, int strip) { str << (strip ? ';' : '\n'); } void Marker::listXY(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: str << setprecision(8) << ptr->mapFromRef(center,sys); break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: str << setprecision(8) << ptr->mapFromRef(center,sys,sky); break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << ra << ' ' << dec; } break; } } else { str << setprecision(8) << ptr->mapFromRef(center,sys); } } break; } str << (strip ? ';' : '\n'); } void Marker::XMLRowInit() { for (int ii=0; ii<XMLNUMCOL; ii++) { if (XMLCol[ii]) delete [] XMLCol[ii]; XMLCol[ii] = NULL; } } void Marker::XMLRow(XMLColName col, int val) { ostringstream str; str << val << ends; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRow(XMLColName col, int* val, int cnt) { ostringstream str; for (int ii=0; ii<cnt; ii++) { str << val[ii]; if (ii!=cnt-1) str << ' '; else str << ends; } if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRow(XMLColName col, double val) { ostringstream str; str << setprecision(8) << val << ends; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRow(XMLColName col, double* val, int cnt) { ostringstream str; for (int ii=0; ii<cnt; ii++) { str << setprecision(8) << val[ii]; if (ii!=cnt-1) str << ' '; else str << ends; } if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRow(XMLColName col, char* val) { if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(val); } void Marker::XMLRow(XMLColName col, char** val, int cnt) { ostringstream str; for (int ii=0; ii<cnt; ii++) { str << val[ii]; if (ii!=cnt-1) str << ' '; else str << ends; } if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRowProps(FitsImage* ptr, Coord::CoordSystem sys) { // tile { ostringstream str; XMLColName col = XMLTILE; FitsImage* fits = parent->findFits(); if (fits && fits->nextMosaic()) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: str << parent->findFits(ptr) << ends; break; default: if (!parent->findFits()->hasWCSCel(sys)) str << parent->findFits(ptr) << ends; break; } } if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } // color { XMLColName col = XMLCOLOR; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(colorName); } // width { ostringstream str; str << lineWidth << ends; XMLColName col = XMLWIDTH; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } // text if (text && *text) { XMLColName col = XMLTEXT; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(text); } // font { XMLColName col = XMLFONT; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(getFont()); } XMLRowProp(XMLSELECT,SELECT); XMLRowProp(XMLHIGHLITE,HIGHLITE); XMLRowProp(XMLEDIT,EDIT); XMLRowProp(XMLMOVE,MOVE); XMLRowProp(XMLROTATE,ROTATE); XMLRowProp(XMLDELETE,DELETE); XMLRowProp(XMLFIXED,FIXED); XMLRowProp(XMLINCLUDE,INCLUDE); XMLRowProp(XMLSOURCE,SOURCE); XMLRowProp(XMLDASH,DASH); // dashlist { ostringstream str; str << dlist[0] << ',' << dlist[1] << ends; XMLColName col = XMLDASHLIST; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } // tags { ostringstream str; Tag* start = tags.head(); Tag* ptr = start; while (ptr) { if (ptr != start) str << ' '; char* tag = (char*)ptr->tag(); while (*tag) { if (*tag == ' ') str << "&#160;"; else str << *tag; tag++; } ptr = ptr->next(); } str << ends; XMLColName col = XMLTAG; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(str.str().c_str()); } // comment if (comment && *comment) { XMLColName col = XMLCOMMENT; if (XMLCol[col]) delete [] XMLCol[col]; XMLCol[col] = dupstr(comment); } } void Marker::XMLRowEnd(ostream& str) { str << "<TR>"; for (int ii=0; ii<XMLNUMCOL; ii++) { str << "<TD>"; if (XMLCol[ii]) { char* ss = XMLQuote(XMLCol[ii]); str << ss; delete [] XMLCol[ii]; delete [] ss; XMLCol[ii] = NULL; } str << "</TD>"; } str << "</TR>" << endl; } void Marker::XMLRowProp(XMLColName col, Property prop) { ostringstream str; if (properties & prop) str << "1"; else str << "0" << ends; XMLCol[col] = dupstr(str.str().c_str()); } void Marker::XMLRowPoint(FitsImage* ptr, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Vector vv) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(vv,sys); XMLRow(XMLX,v[0]); XMLRow(XMLY,v[1]); } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(vv,sys,sky); XMLRow(XMLX,v[0]); XMLRow(XMLY,v[1]); } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(vv,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; XMLRow(XMLX,ra); XMLRow(XMLY,dec); } break; } } else { Vector v = ptr->mapFromRef(vv,sys); XMLRow(XMLX,v[0]); XMLRow(XMLY,v[1]); } } } } void Marker::XMLRowPoint(FitsImage* ptr, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, Vector* vv, int cnt) { switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { double xx[cnt]; double yy[cnt]; for (int ii=0; ii<cnt; ii++) { Vector v = ptr->mapFromRef(vv[ii],sys); xx[ii] = v[0]; yy[ii] = v[1]; } XMLRow(XMLXV,xx,cnt); XMLRow(XMLYV,yy,cnt); } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { double xx[cnt]; double yy[cnt]; for (int ii=0; ii<cnt; ii++) { Vector v = ptr->mapFromRef(vv[ii],sys,sky); xx[ii] = v[0]; yy[ii] = v[1]; } XMLRow(XMLXV,xx,cnt); XMLRow(XMLYV,yy,cnt); } break; case Coord::SEXAGESIMAL: { char* xx[cnt]; char* yy[cnt]; for (int ii=0; ii<cnt; ii++) { char buf[64]; ptr->mapFromRef(vv[ii],sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; xx[ii] = dupstr(ra); yy[ii] = dupstr(dec); } XMLRow(XMLXV,xx,cnt); XMLRow(XMLYV,yy,cnt); for (int ii=0; ii<cnt; ii++) { delete [] xx[ii]; delete [] yy[ii]; } } break; } } else { double xx[cnt]; double yy[cnt]; for (int ii=0; ii<cnt; ii++) { Vector v = ptr->mapFromRef(vv[ii],sys); xx[ii] = v[0]; yy[ii] = v[1]; } XMLRow(XMLXV,xx,cnt); XMLRow(XMLYV,yy,cnt); } } } } void Marker::XMLRowRadiusX(FitsImage* ptr, Coord::CoordSystem sys, Vector vv) { double rr = ptr->mapLenFromRef(vv[0],sys,Coord::ARCSEC); XMLRow(XMLR,rr); } void Marker::XMLRowRadiusX(FitsImage* ptr, Coord::CoordSystem sys, Vector* vv, int cnt) { double rr[cnt]; for (int ii=0; ii<cnt; ii++) rr[ii] = ptr->mapLenFromRef(vv[ii][0],sys,Coord::ARCSEC); XMLRow(XMLRV,rr,cnt); } void Marker::XMLRowRadius(FitsImage* ptr, Coord::CoordSystem sys, Vector vv) { Vector v = ptr->mapLenFromRef(vv,sys,Coord::ARCSEC); XMLRow(XMLR,v[0]); XMLRow(XMLR2,v[1]); } void Marker::XMLRowRadius(FitsImage* ptr, Coord::CoordSystem sys, Vector* vv, int cnt) { double rr[cnt]; double rr2[cnt]; for (int ii=0; ii<cnt; ii++) { Vector v = ptr->mapLenFromRef(vv[ii],sys,Coord::ARCSEC); rr[ii] = v[0]; rr2[ii] = v[1]; } XMLRow(XMLRV,rr,cnt); XMLRow(XMLRV2,rr2,cnt); } void Marker::XMLRowAng(Coord::CoordSystem sys, Coord::SkyFrame sky) { XMLRow(XMLANG, radToDeg(parent->mapAngleFromRef(angle,sys,sky))); } void Marker::XMLRowAng(Coord::CoordSystem sys, Coord::SkyFrame sky, double* ang, int cnt) { double aa[cnt]; for (int ii=0; ii<cnt; ii++) aa[ii] = radToDeg(parent->mapAngleFromRef(ang[ii],sys,sky)); XMLRow(XMLANGV,aa,cnt); } char* Marker::XMLQuote(char* src) { char* dest = new char[strlen(src)*7+1]; char* sptr = src; char* dptr = dest; while (sptr && *sptr) { if (*sptr == '&') { // special case, char entities if (*(sptr+1) == '#') { *dptr++ = *sptr; } else { memcpy(dptr,"&amp;",5); dptr += 5; } } else if (*sptr == '<') { memcpy(dptr,"&lt;",4); dptr += 4; } else if (*sptr == '>') { memcpy(dptr,"&gt;",4); dptr += 4; } else if (*sptr == '\'') { memcpy(dptr,"&apos;",6); dptr += 6; } else if (*sptr == '"') { memcpy(dptr,"&quot;",6); dptr += 6; } else *dptr++ = *sptr; sptr++; } *dptr = NULL; return dest; } // special composite funtionallity void Marker::setComposite(const Matrix& mx, double aa) { center *= mx; angle += aa; updateBBox(); } void Marker::setComposite(const char* clr, int w, int h) { lineWidth = w; if (colorName) delete [] colorName; colorName = dupstr(clr); color = parent->getColor(colorName); highlited = h; } ��./saods9/saotk/frame/frame3dtrue.C������������������������������������������������������������������0000644�0001750�0001750�00000000657�11700666267�015666� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "frame3dtrue.h" Frame3dTrue::Frame3dTrue(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Frame3dBase(i, c, item) { byteorder_ = 0; bitsperpixel_ = 0; } Frame3dTrue::~Frame3dTrue() { } ���������������������������������������������������������������������������������./saods9/saotk/frame/bpanda.h�����������������������������������������������������������������������0000644�0001750�0001750�00000003734�12030663652�014726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __bpanda_h__ #define __bpanda_h__ #include "basepanda.h" #include "basebox.h" class Bpanda : public BasePanda, public BaseBox { private: void renderX(Drawable, Coord::InternalSystem, RenderMode); void renderPS(int); #ifdef _MACOSX void renderMACOSX(); #endif #ifdef _WIN32 void renderWIN32(); #endif void updateHandles(); void listA(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listB(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); int isIn(const Vector& vv, Coord::InternalSystem sys, int nn, int aa); public: Bpanda(const Bpanda&); Bpanda(Base* p, const Vector& ctr, double a1, double a2, int an, const Vector& r1, const Vector& r2, int rn, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Bpanda(Base* p, const Vector& ctr, int an, double* a, int rn, Vector* r, double ang, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Bpanda(*this);} void editBegin(int); void edit(const Vector&, int); void editEnd(); int addAnnuli(const Vector&); int addAngles(const Vector&); void setAnglesAnnuli(double, double, int, Vector, Vector, int); void setAnglesAnnuli(const double*, int, const Vector*, int); void deleteAnglesAnnuli(int h); void analysis(AnalysisTask, int); void analysisPanda(Coord::CoordSystem sys); void analysisStats(Coord::CoordSystem); void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat); }; #endif ������������������������������������./saods9/saotk/frame/ciaoparser.C�������������������������������������������������������������������0000644�0001750�0001750�00000153643�11727715172�015600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse ciaoparse #define yylex ciaolex #define yyerror ciaoerror #define yylval ciaolval #define yychar ciaochar #define yydebug ciaodebug #define yynerrs ciaonerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, ANGDEGREE = 260, ARCMINUTE = 261, ARCSECOND = 262, SEXSTR = 263, HMSSTR = 264, DMSSTR = 265, EOF_ = 266, ANNULUS_ = 267, BOX_ = 268, CIRCLE_ = 269, DEBUG_ = 270, ELLIPSE_ = 271, OFF_ = 272, ON_ = 273, PIE_ = 274, POINT_ = 275, POLYGON_ = 276, ROTBOX_ = 277, VERSION_ = 278 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define ANGDEGREE 260 #define ARCMINUTE 261 #define ARCSECOND 262 #define SEXSTR 263 #define HMSSTR 264 #define DMSSTR 265 #define EOF_ 266 #define ANNULUS_ 267 #define BOX_ 268 #define CIRCLE_ 269 #define DEBUG_ 270 #define ELLIPSE_ 271 #define OFF_ 272 #define ON_ 273 #define PIE_ 274 #define POINT_ 275 #define POLYGON_ 276 #define ROTBOX_ 277 #define VERSION_ 278 /* Copy the first part of user declarations. */ #line 10 "ciaoparser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer ciaoFlexLexer #include <FlexLexer.h> extern int ciaolex(void*, ciaoFlexLexer*); extern void ciaoerror(Base*, ciaoFlexLexer*, const char*); static char *color = "green"; static int dash[] = {8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static unsigned short props; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static void setProps(unsigned short* props, unsigned short prop, int value); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 43 "ciaoparser.Y" { #define CIAOBUFSIZE 2048 double real; int integer; char str[CIAOBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 191 "ciaoparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 204 "ciaoparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 9 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 114 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 34 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 22 /* YYNRULES -- Number of rules. */ #define YYNRULES 52 /* YYNRULES -- Number of states. */ #define YYNSTATES 109 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 278 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 26, 2, 32, 33, 25, 28, 31, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 27, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 7, 10, 11, 14, 16, 20, 22, 24, 26, 27, 29, 31, 33, 35, 37, 40, 42, 44, 46, 48, 50, 52, 54, 56, 57, 59, 61, 63, 65, 67, 71, 75, 79, 81, 83, 85, 89, 93, 97, 103, 111, 119, 131, 137, 145, 149, 150, 155, 159, 161 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 35, 0, -1, 35, 36, 37, -1, 36, 37, -1, -1, 15, 40, -1, 23, -1, 44, 38, 52, -1, 43, -1, 24, -1, 11, -1, -1, 25, -1, 26, -1, 27, -1, 28, -1, 29, -1, 30, 25, -1, 30, -1, 4, -1, 3, -1, 18, -1, 17, -1, 31, -1, 32, -1, 33, -1, -1, 39, -1, 39, -1, 5, -1, 6, -1, 7, -1, 39, 41, 39, -1, 6, 41, 6, -1, 7, 41, 7, -1, 8, -1, 9, -1, 10, -1, 48, 41, 48, -1, 49, 41, 50, -1, 39, 41, 39, -1, 14, 42, 51, 41, 46, -1, 16, 42, 51, 41, 47, 41, 45, -1, 12, 42, 51, 41, 46, 41, 46, -1, 19, 42, 51, 41, 46, 41, 46, 41, 45, 41, 45, -1, 13, 42, 51, 41, 47, -1, 22, 42, 51, 41, 47, 41, 45, -1, 20, 42, 51, -1, -1, 21, 53, 42, 54, -1, 54, 41, 55, -1, 55, -1, 51, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 89, 89, 90, 93, 94, 95, 96, 99, 100, 101, 104, 105, 106, 107, 108, 109, 110, 111, 114, 115, 118, 119, 122, 125, 128, 131, 142, 145, 146, 147, 148, 151, 158, 165, 174, 177, 180, 183, 190, 197, 206, 211, 216, 221, 227, 233, 239, 243, 243, 248, 249, 252 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "ANGDEGREE", "ARCMINUTE", "ARCSECOND", "SEXSTR", "HMSSTR", "DMSSTR", "EOF_", "ANNULUS_", "BOX_", "CIRCLE_", "DEBUG_", "ELLIPSE_", "OFF_", "ON_", "PIE_", "POINT_", "POLYGON_", "ROTBOX_", "VERSION_", "'\\n'", "'*'", "'&'", "'|'", "'+'", "'-'", "'!'", "','", "'('", "')'", "$accept", "commands", "command", "terminator", "include", "numeric", "debug", "sp", "bp", "ep", "init", "angle", "value", "vvalue", "sexagesimal", "hms", "dms", "coord", "shape", "@1", "polyNodes", "polyNode", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 10, 42, 38, 124, 43, 45, 33, 44, 40, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 40, 40, 41, 42, 43, 44, 45, 46, 46, 46, 46, 47, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 53, 52, 54, 54, 55 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 2, 0, 2, 1, 3, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 3, 3, 3, 5, 7, 7, 11, 5, 7, 3, 0, 4, 3, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 26, 0, 6, 26, 0, 11, 22, 21, 5, 1, 0, 10, 9, 25, 3, 8, 12, 13, 14, 15, 16, 18, 0, 2, 17, 0, 0, 0, 0, 0, 0, 48, 0, 7, 24, 0, 0, 0, 0, 0, 0, 0, 0, 20, 19, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 52, 49, 51, 0, 40, 38, 37, 39, 29, 30, 31, 28, 0, 0, 0, 0, 45, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 43, 33, 34, 32, 27, 42, 0, 46, 0, 0, 0, 44 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 3, 4, 14, 22, 47, 8, 59, 35, 15, 5, 102, 79, 83, 48, 49, 74, 67, 33, 41, 68, 69 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -79 static const yytype_int8 yypact[] = { 51, 46, -79, 36, 17, 79, -79, -79, -79, -79, 17, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -14, 73, -79, -79, -15, -15, -15, -15, -15, -15, -79, -15, -79, -79, 4, 4, 4, 4, 4, 4, -15, 4, -79, -79, -79, -79, -10, -10, -10, -10, -10, -10, -10, -10, -79, 4, -10, -79, 67, 27, 38, 107, 39, 107, 39, 107, -79, -10, -79, 39, -79, -79, -79, -79, -79, -79, -79, -79, -10, -10, -10, -10, -79, -79, -10, -10, 4, -10, 107, 55, 65, 67, 67, 107, -79, 67, -79, -79, -79, -79, -79, -79, -10, -79, 67, -10, 67, -79 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -79, -79, 54, 58, -79, -40, -79, -48, 50, -79, -79, -78, -50, -55, 13, -79, -79, 61, -79, -79, -79, -6 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -5 static const yytype_int8 yytable[] = { 60, 61, 62, 63, 64, 65, 66, 43, 44, 70, 85, 24, 45, 46, 84, 88, 86, 34, 104, 71, 87, 58, 78, 82, 78, 82, 78, 106, 11, 108, 82, 89, 90, 91, 92, 45, 9, 93, 94, 97, 96, 12, 43, 44, 103, 80, 81, -4, 73, 78, 13, 1, 100, 101, 78, 105, 101, 10, 107, 2, -4, 98, -4, 6, 7, 101, 1, 101, 23, -4, 43, 44, 99, 72, 2, -4, 36, 37, 38, 39, 40, 95, 42, 0, -4, 25, 26, 27, 0, 28, 0, 56, 29, 30, 31, 32, 50, 51, 52, 53, 54, 55, 0, 57, 16, 17, 18, 19, 20, 21, 43, 44, 75, 76, 77 }; static const yytype_int8 yycheck[] = { 48, 49, 50, 51, 52, 53, 54, 3, 4, 57, 65, 25, 8, 9, 64, 70, 66, 32, 96, 59, 68, 31, 62, 63, 64, 65, 66, 105, 11, 107, 70, 79, 80, 81, 82, 8, 0, 85, 86, 89, 88, 24, 3, 4, 94, 6, 7, 11, 10, 89, 33, 15, 92, 93, 94, 103, 96, 3, 106, 23, 24, 6, 11, 17, 18, 105, 15, 107, 10, 33, 3, 4, 7, 60, 23, 24, 26, 27, 28, 29, 30, 87, 32, -1, 33, 12, 13, 14, -1, 16, -1, 41, 19, 20, 21, 22, 35, 36, 37, 38, 39, 40, -1, 42, 25, 26, 27, 28, 29, 30, 3, 4, 5, 6, 7 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 15, 23, 35, 36, 44, 17, 18, 40, 0, 36, 11, 24, 33, 37, 43, 25, 26, 27, 28, 29, 30, 38, 37, 25, 12, 13, 14, 16, 19, 20, 21, 22, 52, 32, 42, 42, 42, 42, 42, 42, 53, 42, 3, 4, 8, 9, 39, 48, 49, 51, 51, 51, 51, 51, 51, 42, 51, 31, 41, 41, 41, 41, 41, 41, 41, 41, 51, 54, 55, 41, 39, 48, 10, 50, 5, 6, 7, 39, 46, 6, 7, 39, 47, 46, 47, 46, 41, 47, 41, 41, 41, 41, 41, 41, 55, 41, 46, 6, 7, 39, 39, 45, 46, 45, 41, 45, 41, 45 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, ciaoFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; ciaoFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, ciaoFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; ciaoFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, ciaoFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; ciaoFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, ciaoFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; ciaoFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, ciaoFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, ciaoFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; ciaoFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 6: #line 95 "ciaoparser.Y" {cerr << "CIAO Regions File 1.0" << endl;;} break; case 10: #line 101 "ciaoparser.Y" {YYACCEPT;;} break; case 16: #line 109 "ciaoparser.Y" {setProps(&props, Marker::INCLUDE, 0);;} break; case 17: #line 110 "ciaoparser.Y" {setProps(&props, Marker::INCLUDE, 0);;} break; case 18: #line 111 "ciaoparser.Y" {setProps(&props, Marker::INCLUDE, 0);;} break; case 19: #line 114 "ciaoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 20: #line 115 "ciaoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 21: #line 118 "ciaoparser.Y" {yydebug=1;;} break; case 22: #line 119 "ciaoparser.Y" {yydebug=0;;} break; case 26: #line 131 "ciaoparser.Y" { // reset maperr flag maperr =0; props = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; ;} break; case 27: #line 142 "ciaoparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 28: #line 145 "ciaoparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::PHYSICAL);;} break; case 29: #line 146 "ciaoparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::WCS, Coord::DEGREE);;} break; case 30: #line 147 "ciaoparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::WCS, Coord::ARCMIN);;} break; case 31: #line 148 "ciaoparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::WCS, Coord::ARCSEC);;} break; case 32: #line 152 "ciaoparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::PHYSICAL); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 33: #line 159 "ciaoparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::WCS, Coord::ARCMIN); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 34: #line 166 "ciaoparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::WCS, Coord::ARCSEC); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 35: #line 174 "ciaoparser.Y" {(yyval.real) = parseSEXStr((yyvsp[(1) - (1)].str));;} break; case 36: #line 177 "ciaoparser.Y" {(yyval.real) = parseHMSStr((yyvsp[(1) - (1)].str));;} break; case 37: #line 180 "ciaoparser.Y" {(yyval.real) = parseDMSStr((yyvsp[(1) - (1)].str));;} break; case 38: #line 184 "ciaoparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real)*360./24.,(yyvsp[(3) - (3)].real)), Coord::WCS,Coord::FK5); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 39: #line 191 "ciaoparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::WCS,Coord::FK5); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 40: #line 198 "ciaoparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::PHYSICAL); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 41: #line 207 "ciaoparser.Y" {fr->createCircleCmd(Vector((yyvsp[(3) - (5)].vector)), (yyvsp[(5) - (5)].real), color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 42: #line 212 "ciaoparser.Y" {fr->createEllipseCmd(Vector((yyvsp[(3) - (7)].vector)), Vector((yyvsp[(5) - (7)].vector)),(yyvsp[(7) - (7)].real), color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 43: #line 217 "ciaoparser.Y" {fr->createAnnulusCmd(Vector((yyvsp[(3) - (7)].vector)), (yyvsp[(5) - (7)].real),(yyvsp[(7) - (7)].real),1, color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 44: #line 222 "ciaoparser.Y" {fr->createCpandaCmd(Vector((yyvsp[(3) - (11)].vector)), (yyvsp[(9) - (11)].real),(yyvsp[(11) - (11)].real),1, (yyvsp[(5) - (11)].real),(yyvsp[(7) - (11)].real),1, color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 45: #line 228 "ciaoparser.Y" {fr->createBoxCmd(Vector((yyvsp[(3) - (5)].vector)), Vector((yyvsp[(5) - (5)].vector)), 0, color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 46: #line 234 "ciaoparser.Y" {fr->createBoxCmd(Vector((yyvsp[(3) - (7)].vector)), Vector((yyvsp[(5) - (7)].vector)), (yyvsp[(7) - (7)].real), color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 47: #line 240 "ciaoparser.Y" {fr->createPointCmd(Vector((yyvsp[(3) - (3)].vector)), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 48: #line 243 "ciaoparser.Y" {polylist.deleteAll();;} break; case 49: #line 244 "ciaoparser.Y" {fr->createPolygonCmd(polylist, color,dash,1,font,text,props,NULL,taglist,cblist);;} break; case 52: #line 252 "ciaoparser.Y" {polylist.append(new Vertex((yyvsp[(1) - (1)].vector)));;} break; /* Line 1267 of yacc.c. */ #line 1724 "ciaoparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 255 "ciaoparser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } ���������������������������������������������������������������������������������������������./saods9/saotk/frame/baseline.C���������������������������������������������������������������������0000644�0001750�0001750�00000003710�11727727777�015235� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "baseline.h" #include "fitsimage.h" BaseLine::BaseLine(const BaseLine& a) : Marker(a) { p1 = a.p1; p2 = a.p2; } BaseLine::BaseLine(Base* p, const Vector& ptr1, const Vector& ptr2, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, ptr1, 0, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { p1 = ptr1; p2 = ptr2; } void BaseLine::updateCoords(const Matrix& mx) { p1*=mx; p2*=mx; Marker::updateCoords(mx); } void BaseLine::centroid() { p1 = parent->centroid(p1); p2 = parent->centroid(p2); updateBBox(); doCallBack(CallBack::MOVECB); } void BaseLine::move(const Vector& v) { p1+=v; p2+=v; updateBBox(); doCallBack(CallBack::MOVECB); } void BaseLine::moveTo(const Vector& v) { // v is the new location of the center Vector diff = v - center; p1+=diff; p2+=diff; updateBBox(); doCallBack(CallBack::MOVECB); } int BaseLine::isIn(const Vector& v) { // do this in canvas coords, not ref coords Vector l1 = parent->mapFromRef(p1,Coord::CANVAS); Vector l2 = parent->mapFromRef(p2,Coord::CANVAS); double a = (l2-l1).angle(); Matrix m = Translate(-l1) * Rotate(a); Vector vv = v*m; Vector end = l2*m; return (vv[0]>0 && vv[0]<end[0] && vv[1]>-6 && vv[1]<6); } void BaseLine::edit(const Vector& v, int h) { switch (h) { case 1: p1 = v; break; case 2: p2 = v; break; } updateBBox(); doCallBack(CallBack::EDITCB); } void BaseLine::setPoints(const Vector& v1, const Vector& v2) { p1 = v1; p2 = v2; updateBBox(); doCallBack(CallBack::EDITCB); } // special composite funtionallity void BaseLine::setComposite(const Matrix& mx, double aa) { p1 *= mx; p2 *= mx; updateBBox(); } ��������������������������������������������������������./saods9/saotk/frame/colorscale.C�������������������������������������������������������������������0000644�0001750�0001750�00000012332�11700666266�015563� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscale.h" ColorScale::ColorScale(int ss) { size_ = ss; psColors_ = new unsigned char[ss*3]; psIndex_ = new unsigned short[ss]; memset(psColors_, '0', size_*3); memset(psIndex_, '0', size_*sizeof(unsigned short)); } ColorScale::~ColorScale() { if (psColors_) delete [] psColors_; if (psIndex_) delete [] psIndex_; } LinearScale::LinearScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(ss) { for (int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } LogScale::LogScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count, double exp) : ColorScale(ss) { for (int ii=0; ii<ss; ii++) { double aa = log10(exp*double(ii)/ss +1) / log10(exp); int ll = (int)(aa * count); // aa can grow slightly greater than 1 if (ll>=count) ll = count-1; psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3, 3); } } PowScale::PowScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count, double exp) : ColorScale(ss) { for (int ii=0; ii<ss; ii++) { double aa = (::pow(exp,double(ii)/ss) -1) / exp; int ll = (int)(aa * count); // should not be needed if (ll>=count) ll = count-1; psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3, 3); } } SqrtScale::SqrtScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(sqrt(aa) * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } SquaredScale::SquaredScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa*aa * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } AsinhScale::AsinhScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(asinh(10*aa)/3 * count); // it can spill over if (ll>=count) ll = count-1; psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } SinhScale::SinhScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(ss) { for(int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(sinh(3*aa)/10 * count); // it can spill over if (ll>=count) ll = count-1; psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } HistEquScale::HistEquScale(int ss, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize) : ColorScale(ss) { // if no histogram, return linear distribution if (!hist) for (int ii=0; ii<ss; ii++) { double aa = double(ii)/ss; int ll = (int)(aa * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } else { for (int ii=0; ii<ss; ii++) { double aa = hist[ii*histsize/ss]; int ll = (int)(aa * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } } IISScale::IISScale(unsigned short* indexCells, unsigned char* colorCells, int count) : ColorScale(IISSIZE) { { for (int ii=0; ii<IISCOLORS; ii++) { double aa = double(ii)/IISCOLORS; int ll = (int)(aa * count); psIndex_[ii] = indexCells[ll]; memcpy(psColors_+ii*3, colorCells+ll*3,3); } } { for (int ii=IISCOLORS; ii<IISSIZE; ii++) psIndex_[ii] = ii; unsigned char* ptr = psColors_+200*3; // 200 black *ptr++ = 0; *ptr++ = 0; *ptr++ = 0; // 201 black *ptr++ = 0; *ptr++ = 0; *ptr++ = 0; // 202 white *ptr++ = 255; *ptr++ = 255; *ptr++ = 255; // 203 red *ptr++ = 0; *ptr++ = 0; *ptr++ = 255; // 204 green *ptr++ = 0; *ptr++ = 255; *ptr++ = 0; // 205 blue *ptr++ = 255; *ptr++ = 0; *ptr++ = 0; // 206 yellow *ptr++ = 0; *ptr++ = 255; *ptr++ = 255; // 207 cyan *ptr++ = 255; *ptr++ = 255; *ptr++ = 0; // 208 magenta *ptr++ = 255; *ptr++ = 0; *ptr++ = 255; // 209 coral *ptr++ = 80; *ptr++ = 127; *ptr++ = 255; // 210 maroon *ptr++ = 96; *ptr++ = 48; *ptr++ = 176; // 211 orange *ptr++ = 0; *ptr++ = 165; *ptr++ = 255; // 212 khaki *ptr++ = 140; *ptr++ = 230; *ptr++ = 240; // 213 orchid *ptr++ = 214; *ptr++ = 112; *ptr++ = 218; // 214 turquoise *ptr++ = 208; *ptr++ = 224; *ptr++ = 64; // 215 violet *ptr++ = 238; *ptr++ = 130; *ptr++ = 238; // 216 wheat *ptr++ = 179; *ptr++ = 222; *ptr++ = 245; } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue32.C�������������������������������������������������������������0000644�0001750�0001750�00000007624�11700666266�016640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscaletrue32.h" ColorScaleTrueColor32::ColorScaleTrueColor32(int s, Visual* visual, int msb) : ColorScale(s), TrueColor24(visual) { colors_ = new unsigned char[s*4]; // we need to check to byteswap when we have cross platforms if ((!msb && lsb()) || (msb && !lsb())) { for (int i=0; i<s; i++) { unsigned int r = psColors_[i*3+2]; unsigned int g = psColors_[i*3+1]; unsigned int b = psColors_[i*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; memcpy(colors_+i*4, &a, 4); } } else { for (int i=0; i<s; i++) { unsigned int r = psColors_[i*3+2]; unsigned int g = psColors_[i*3+1]; unsigned int b = psColors_[i*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(colors_+i*4) = *(rr+3); *(colors_+i*4+1) = *(rr+2); *(colors_+i*4+2) = *(rr+1); *(colors_+i*4+3) = *(rr); } } } ColorScaleTrueColor32::~ColorScaleTrueColor32() { if (colors_) delete [] colors_; } LinearScaleTrueColor32::LinearScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : LinearScale(s, indexCells, colorCells, count), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} LogScaleTrueColor32::LogScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : LogScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} PowScaleTrueColor32::PowScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : PowScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} SqrtScaleTrueColor32::SqrtScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SqrtScale(s, indexCells, colorCells, count), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} SquaredScaleTrueColor32::SquaredScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SquaredScale(s, indexCells, colorCells, count), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} AsinhScaleTrueColor32::AsinhScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : AsinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} SinhScaleTrueColor32::SinhScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} IISScaleTrueColor32::IISScaleTrueColor32(unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : IISScale(indexCells, colorCells, count), ColorScaleTrueColor32(IISSIZE, visual, msb), ColorScale(IISSIZE) {} HistEquScaleTrueColor32::HistEquScaleTrueColor32(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize, Visual* visual, int msb) : HistEquScale(s, indexCells, colorCells, count, hist, histsize), ColorScaleTrueColor32(s, visual, msb), ColorScale(s) {} ������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitsmap.C����������������������������������������������������������������������0000644�0001750�0001750�00000015061�11727715172�015102� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" // Map Point Vector FitsImage::mapFromRef(const Vector& vv, Coord::CoordSystem out, Coord::SkyFrame sky) { switch (out) { case Coord::IMAGE: return vv * refToImage; case Coord::PHYSICAL: return vv * refToPhysical; case Coord::AMPLIFIER: return vv * refToAmplifier; case Coord::DETECTOR: return vv * refToDetector; default: if (hasWCS(out)) return pix2wcs(vv * refToImage, out, sky); } maperr =1; return vv; } void FitsImage::mapFromRef(const Vector& vv, Coord::CoordSystem out, Coord::SkyFrame sky, Coord::SkyFormat format, char* buf, int length) { if (hasWCS(out)) { pix2wcs(vv * refToImage, out, sky, format, buf, length); return; } maperr =1; strcpy(buf,""); } Vector FitsImage::mapToRef(const Vector& vv, Coord::CoordSystem in, Coord::SkyFrame sky) { switch (in) { case Coord::IMAGE: return vv * imageToRef; case Coord::PHYSICAL: return vv * physicalToRef; case Coord::AMPLIFIER: return vv * amplifierToRef; case Coord::DETECTOR: return vv * detectorToRef; default: if (hasWCS(in)) return wcs2pix(vv, in, sky) * imageToRef; } maperr =1; return vv; } // Map Length double FitsImage::mapLenFromRef(double dd, Coord::CoordSystem sys, Coord::SkyDist dist) { Vector rr = mapLenFromRef(Vector(dd,0),sys,dist); return rr[0]; } Vector FitsImage::mapLenFromRef(const Vector& vv, Coord::CoordSystem sys, Coord::SkyDist dist) { // really from image coords switch (sys) { case Coord::IMAGE: return mapLen(vv,refToImage); case Coord::PHYSICAL: return mapLen(vv,refToPhysical); case Coord::AMPLIFIER: return mapLen(vv,refToPhysical * physicalToAmplifier); case Coord::DETECTOR: return mapLen(vv,refToPhysical * physicalToDetector); default: if (hasWCS(sys)) { Vector cd = getWCScdelt(sys); Vector in = mapLen(vv,refToImage); Vector out = Vector(in[0]*cd[0], in[1]*cd[1]).abs(); if (hasWCSCel(sys)) { switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: out *= 60; break; case Coord::ARCSEC: out *=60*60; break; } } return out; } } maperr =1; return Vector(); } double FitsImage::mapLenToRef(double dd, Coord::CoordSystem sys, Coord::SkyDist dist) { Vector rr = mapLenToRef(Vector(dd,0), sys, dist); return rr[0]; } Vector FitsImage::mapLenToRef(const Vector& vv,Coord::CoordSystem sys, Coord::SkyDist dist) { switch (sys) { case Coord::IMAGE: return mapLen(vv,imageToRef); case Coord::PHYSICAL: return mapLen(vv,physicalToRef); case Coord::AMPLIFIER: return mapLen(vv,amplifierToPhysical * physicalToRef); case Coord::DETECTOR: return mapLen(vv,detectorToPhysical * physicalToRef); default: if (hasWCS(sys)) { Vector cd = getWCScdelt(sys); Vector in = mapLen(vv,refToImage); Vector out = Vector(in[0]/cd[0], in[1]/cd[1]).abs(); if (hasWCSCel(sys)) { switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: out /= 60; break; case Coord::ARCSEC: out /= 60*60; break; } } return out; } } maperr =1; return Vector(); } Vector FitsImage::mapLenFromImage(const Vector& vv, Coord::CoordSystem sys, Coord::SkyDist dist) { switch (sys) { case Coord::IMAGE: return vv; case Coord::PHYSICAL: return mapLen(vv,imageToPhysical); case Coord::AMPLIFIER: return mapLen(vv,imageToPhysical * physicalToAmplifier); case Coord::DETECTOR: return mapLen(vv,imageToPhysical * physicalToDetector); default: if (hasWCS(sys)) { Vector cd = getWCScdelt(sys); Vector in = vv; Vector out = Vector(in[0]*cd[0], in[1]*cd[1]).abs(); if (hasWCSCel(sys)) { switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: out *= 60; break; case Coord::ARCSEC: out *=60*60; break; } } return out; } } maperr =1; return Vector(); } Vector FitsImage::mapLenToImage(const Vector& vv,Coord::CoordSystem sys, Coord::SkyDist dist) { switch (sys) { case Coord::IMAGE: return vv; case Coord::PHYSICAL: return mapLen(vv,physicalToImage); case Coord::AMPLIFIER: return mapLen(vv,amplifierToPhysical * physicalToImage); case Coord::DETECTOR: return mapLen(vv,detectorToPhysical * physicalToImage); default: if (hasWCS(sys)) { Vector cd = getWCScdelt(sys); Vector in = vv; Vector out = Vector(in[0]/cd[0], in[1]/cd[1]).abs(); if (hasWCSCel(sys)) { switch (dist) { case Coord::DEGREE: break; case Coord::ARCMIN: out /= 60; break; case Coord::ARCSEC: out /= 60*60; break; } } return out; } } maperr =1; return Vector(); } // Map Distance double FitsImage::mapDistFromRef(const Vector& vv1, const Vector& vv2, Coord::CoordSystem sys, Coord::SkyDist dist) { switch (sys) { case Coord::IMAGE: { Vector v1 = vv1 * refToImage; Vector v2 = vv2 * refToImage; return (v2-v1).length(); } case Coord::PHYSICAL: { Vector v1 = vv1 * refToPhysical; Vector v2 = vv2 * refToPhysical; return (v2-v1).length(); } case Coord::AMPLIFIER: { Vector v1 = vv1 * refToPhysical * physicalToAmplifier; Vector v2 = vv2 * refToPhysical * physicalToAmplifier; return (v2-v1).length(); } case Coord::DETECTOR: { Vector v1 = vv1 * refToPhysical * physicalToDetector; Vector v2 = vv2 * refToPhysical * physicalToDetector; return (v2-v1).length(); } default: if (hasWCS(sys)) { Vector v1 = pix2wcs(vv1 * refToImage, sys, Coord::FK5); Vector v2 = pix2wcs(vv2 * refToImage, sys, Coord::FK5); if (hasWCSCel(sys)) { switch (dist) { case Coord::DEGREE: return wcsdist(v1,v2,sys); case Coord::ARCMIN: return wcsdist(v1,v2,sys)*60; case Coord::ARCSEC: return wcsdist(v1,v2,sys)*60*60; } } else return wcsdist(v1,v2,sys); } } maperr =1; return 0; } double FitsImage::mapFromRef3(double vv, Coord::CoordSystem out, int ss) { switch (out) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::AMPLIFIER: case Coord::DETECTOR: return vv+.5; default: return pix2wcsx(vv+.5,out,ss); } } double FitsImage::mapToRef3(double vv, Coord::CoordSystem in, int ss) { switch (in) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::AMPLIFIER: case Coord::DETECTOR: return vv-.5; default: return wcs2pixx(vv,in,ss) -.5; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/frame3dtruecolor.h�������������������������������������������������������������0000644�0001750�0001750�00000001461�11727730000�016746� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __frame3dtruecolor_h__ #define __frame3dtruecolor_h__ #include "frame3d.h" #include "frame3dtrue.h" class Frame3dTrueColor : public Frame3d, public Frame3dTrue { protected: long* colormapData; private: void buildXImage(XImage*, Coord::InternalSystem); public: Frame3dTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Frame3dTrueColor(); void colormapCmd(int, float, float, int, unsigned short*, unsigned char*, int); void colormapEndCmd(); void colormapMotionCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt) {colormapCmd(id,b,c,i,index,cells,cnt);} }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fr3dmap.C����������������������������������������������������������������������0000644�0001750�0001750�00000004310�11730673060�014757� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "context.h" #include "frame3dbase.h" #include "fitsimage.h" Vector3d Frame3dBase::mapFromRef3d(const Vector& vv, Coord::InternalSystem sys) { // context->slice() IMAGE (ranges 1-n) double sl = keyContext->slice(2)-.5; return mapFromRef3d(vv,sys,sl); } Vector3d Frame3dBase::mapFromRef3d(const Vector& vv, Coord::InternalSystem sys, double sl) { // note: sl is in REF=DATA coordinates Matrix3d mm; switch (sys) { case Coord::REF: return Vector3d(vv,sl); case Coord::USER: mm = refToUser3d; break; case Coord::WIDGET: mm = refToWidget3d; break; case Coord::CANVAS: mm = refToCanvas3d; break; case Coord::WINDOW: mm = refToWindow3d; break; case Coord::PANNER: mm = refToPanner3d; break; case Coord::MAGNIFIER: mm = refToMagnifier3d; break; } return Vector3d(vv,sl)*mm; } Vector3d Frame3dBase::mapToRef3d(const Vector& vv, Coord::InternalSystem sys) { // context->slice() IMAGE (ranges 1-n) double sl = keyContext->slice(2)-.5; return mapToRef3d(vv,sys,sl); } Vector3d Frame3dBase::mapToRef3d(const Vector& vv, Coord::InternalSystem sys, double sl) { switch (sys) { case Coord::REF: return Vector3d(vv,sl); case Coord::USER: return Vector3d(vv,sl)*userToRef3d; } // note: sl is in REF=DATA coordinates Vector3d xx = Vector3d(1,0,sl)*refToWidget3d; Vector3d yy = Vector3d(0,1,sl)*refToWidget3d; Vector3d zz = Vector3d(0,0,sl)*refToWidget3d; Vector3d ii=xx-zz; Vector3d jj=yy-zz; Vector3d nn = cross(jj,ii).normalize(); double& a = nn[0]; double& b = nn[1]; double& c = nn[2]; double d = -a*xx[0] -b*xx[1] -c*xx[2]; Vector ww; switch (sys) { case Coord::WIDGET: ww = vv; break; case Coord::CANVAS: ww = vv*canvasToWidget; break; case Coord::WINDOW: ww = vv*windowToWidget; break; case Coord::PANNER: ww = vv*pannerToWidget; break; case Coord::MAGNIFIER: ww = vv*magnifierToWidget; break; } double z = (-a*ww[0] -b*ww[1] -d)/c; return Vector3d(ww,z)*widgetToRef3d; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framepseudocolor.h�������������������������������������������������������������0000644�0001750�0001750�00000001343�11727730000�017036� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framepseudocolor_h__ #define __framepseudocolor_h__ #include "frame.h" #include "framepseudo.h" class FramePseudoColor : public virtual FrameBase, public Frame, public FramePseudo { private: void buildXImage(XImage* xmap, Coord::InternalSystem); public: FramePseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); void colormapCmd(int, float, float, int, unsigned short*, unsigned char*, int); void colormapMotionCmd(int id, float b, float c, int i, unsigned short* index, unsigned char* cells, int cnt); void colormapEndCmd(); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/composite.C��������������������������������������������������������������������0000644�0001750�0001750�00000015440�12065125235�015431� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "composite.h" #include "fitsimage.h" Composite::Composite(const Composite& a) : Marker(a) { members = a.members; global = a.global; } Composite::Composite(Base* p, const Vector& ctr, double ang, int gl, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : Marker(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { strcpy(type_, "composite"); global = gl; handle = new Vector[4]; numHandle = 4; updateBBox(); } void Composite::x11(Drawable drawable, Coord::InternalSystem sys, int tt, RenderMode mode, HandleMode hh) { if (hh==HANDLES) renderXHandles(drawable); if (tt) renderXText(drawable, sys, mode); Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); if (global) m->setComposite(colorName, lineWidth, highlited); m->x11(drawable, sys, tt, mode, hh); delete m; mk=mk->next(); } } void Composite::ps(int mode, int tt) { if (tt) renderPSText(mode); Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); if (global) m->setComposite(colorName, lineWidth, highlited); m->ps(mode,tt); delete m; mk=mk->next(); } } #ifdef _MACOSX void Composite::macosx(int tt) { if (tt) renderMACOSXText(); Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); if (global) m->setComposite(colorName, lineWidth, highlited); m->macosx(tt); delete m; mk=mk->next(); } } #endif #ifdef _WIN32 void Composite::win32(int tt) { if (tt) renderWIN32Text(); Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); if (global) m->setComposite(colorName, lineWidth, highlited); m->win32(tt); delete m; mk=mk->next(); } } #endif // Support void Composite::updateHandles() { BBox bb(center * bckMatrix()); Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); for(int ii=0; ii<m->getNumHandle(); ii++) bb.bound(bckMap(m->getHandle(ii),Coord::CANVAS)); delete m; mk=mk->next(); } bb.expand(3); // a little more room around the edges handle[0] = fwdMap(bb.ll,Coord::CANVAS); handle[1] = fwdMap(bb.lr(),Coord::CANVAS); handle[2] = fwdMap(bb.ur,Coord::CANVAS); handle[3] = fwdMap(bb.ul(),Coord::CANVAS); } void Composite::updateCoords(const Matrix& mx) { Marker* mk=members.head(); while (mk) { Vector cc = center; mk->setComposite(fwdMatrix(), angle); mk->updateCoords(mx); center = cc*mx; mk->setComposite(bckMatrix(), -angle); center = cc; mk=mk->next(); } Marker::updateCoords(mx); } int Composite::isIn(const Vector& v) { if (!bbox.isIn(v)) return 0; Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); if (m->isIn(v)) { delete m; return 1; } delete m; mk=mk->next(); } return 0; } void Composite::append(Marker* m) { m->setComposite(bckMatrix(), -angle); members.append(m); } Marker* Composite::extract() { Marker* mk=members.head(); if (mk) { members.extractNext(mk); mk->setComposite(fwdMatrix(), angle); } return mk; } // list void Composite::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { if (!strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 1); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v = ptr->mapFromRef(center,sys,sky); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; ptr->mapFromRef(center,sys,sky,format,buf,64); char ra[16]; char dec[16]; string x(buf); istringstream wcs(x); wcs >> ra >> dec; str << type_ << '(' << ra << ',' << dec << ',' << radToDeg(parent->mapAngleFromRef(angle,sys,sky)) << ')'; } break; } } else { Vector v = ptr->mapFromRef(center,sys); str << type_ << '(' << setprecision(8) << v[0] << ',' << v[1] << ',' << radToDeg(parent->mapAngleFromRef(angle,sys)) << ')'; } } } str << " ||"; str << " composite=" << global; listProperties(str, 0); } Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); mk=mk->next(); m->setComposite(fwdMatrix(), angle); m->list(str, sys, sky, format, (mk?1:0), strip); delete m; } } void Composite::listCiao(ostream& str, Coord::CoordSystem sys, int strip) { Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); mk=mk->next(); m->setComposite(fwdMatrix(), angle); m->listCiao(str, sys, strip); delete m; } } void Composite::listPros(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); m->listPros(str, sys, sky, format, strip); delete m; mk=mk->next(); } } void Composite::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); m->listSAOtng(str, sys, sky, format, strip); delete m; mk=mk->next(); } } void Composite::listSAOimage(ostream& str, int strip) { Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); m->listSAOimage(str, strip); delete m; mk=mk->next(); } } void Composite::listXY(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { Marker* mk=members.head(); while (mk) { Marker* m = mk->dup(); m->setComposite(fwdMatrix(), angle); m->listXY(str, sys, sky, format, strip); delete m; mk=mk->next(); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/grid3d.C�����������������������������������������������������������������������0000644�0001750�0001750�00000013711�12001331444�014571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid3d.h" #include "context.h" #include "frame3dbase.h" #include "fitsimage.h" extern "C" { #include "ast.h" } static FitsImage* foobar; void bar(AstMapping* that, int npoint, int ncoord_in, const double* ptr_in[], int forward, int ncoord_out, double* ptr_out[]) { if (forward) { for (int ii=0; ii<npoint; ii++) (*ptr_out)[ii] = (.5+(*ptr_in)[ii]-foobar->crpixx[0])*foobar->cdx[0] + foobar->crvalx[0]; } else { for (int ii=0; ii<npoint; ii++) (*ptr_out)[ii] = ((*ptr_in)[ii]-foobar->crvalx[0])/foobar->cdx[0] + foobar->crpixx[0] -.5; } } extern Grid3dBase* astGrid3dPtr; Grid3d::Grid3d(Widget* p, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, GridType t, const char* o, const char* v) : Grid(sys, sky, format, t, v), Grid3dBase(p,o) {} Grid3d::~Grid3d() {} int Grid3d::doit(RenderMode rm) { Frame3dBase* pp = (Frame3dBase*)parent_; mx_ = pp->refToWidget3d; rx_ = Matrix3d(pp->wcsOrientationMatrix) * Matrix3d(pp->orientationMatrix) * RotateZ3d(-pp->wcsRotation) * RotateZ3d(-pp->rotation) * RotateY3d(pp->az_) * RotateX3d(pp->el_); matrix_ = pp->widgetToCanvas; gc_ = pp->gridGC; pixmap_ = pp->pixmap; renderMode_ = rm; Context* context = pp->keyContext; FitsImage* fits = context->fits; foobar = fits; if (!fits) return 1; int width = fits->width(); int height = fits->height(); astClearStatus; // just to make sure astBegin; // start memory management AstFrameSet* frameSet = NULL; AstPlot3D* plot = NULL; FitsBound* params = fits->getDataParams(context->frScale.scanMode()); switch (system_) { case Coord::IMAGE: frameSet = (AstFrameSet*)matrixMap(fits->refToImage,"Domain=IMAGE"); break; case Coord::PHYSICAL: frameSet = (AstFrameSet*)matrixMap(fits->refToPhysical,"Domain=PHYSICAL"); break; case Coord::AMPLIFIER: frameSet = (AstFrameSet*)matrixMap(fits->refToAmplifier,"Domain=AMPLIFIER"); break; case Coord::DETECTOR: frameSet = (AstFrameSet*)matrixMap(fits->refToDetector,"Domain=DETECTOR"); break; default: { // imageToData frame/map double ss[] = {-.5, -.5}; AstShiftMap *sm = astShiftMap(2, ss, " "); AstFrame *df = astFrame(2, "Domain=DATA"); // Get 2D SkyFrame AstFrameSet* wcs = (AstFrameSet*)astCopy(fits->getAST(system_)); if (astIsASkyFrame(astGetFrame(wcs, AST__CURRENT))) fits->setAstSkyFrame(wcs, sky_); // Record the index of the current Frame int isky = astGetI(wcs, "Current"); // Add the new DATA Frame into the FrameSet, using the ShiftMap to // connect it to the existing IMAGE Frame. astAddFrame(wcs, AST__BASE, sm, df); // The above call to astAddFrame will have changed the current Frame // in the FrameSet to be the new DATA Frame. First record the index of // the DATA Frame, and then re-instate the original current Frame (i.e. // the SKY Frame). int idata = astGetI(wcs, "Current"); astSetI(wcs, "Current", isky); // make the DATA Frame the new base Frame astSetI(wcs, "Base", idata); // Create two 1D Frames and a 1D Mapping describing the third axis AstFrame* zbase = astFrame(1,""); AstFrame* zcurr = astFrame(1,""); AstMapping* zmap; if (fits->hasWCSx(system_,2)) { astIntraReg("foo",1,1,bar,0,"testing","me","you"); if (!(zmap = (AstMapping*)astIntraMap("foo",1,1,""))) return 0; } else zmap = (AstMapping*)astUnitMap(1,""); // Use astGetFrame and astGetMapping to get the base and current // Frames from the 2D FrameSet, and the base->current Mapping. AstFrame* wcsbase = (AstFrame*)astGetFrame(wcs,AST__BASE); AstFrame* wcscurr = (AstFrame*)astGetFrame(wcs,AST__CURRENT); AstMapping* wcsmap = (AstMapping*)astGetMapping(wcs,AST__BASE,AST__CURRENT); // Combine the 2D and 1D base Frames into a 3D CmpFrame // Likewise, combine the 2D and 1D current Frames into a 3D CmpFrame AstCmpFrame* cmpwcsbase = astCmpFrame(wcsbase,zbase,""); AstCmpFrame* cmpwcscurr = astCmpFrame(wcscurr,zcurr,""); // Combine the 2D and 1D Mappings into a 3D CmpMap AstCmpMap* cmpwcsmap = astCmpMap(wcsmap,zmap,0,""); // Construct the 3D FrameSet from the new 3D Frames and Mapping frameSet = astFrameSet(cmpwcsbase,""); astAddFrame(frameSet, AST__CURRENT, cmpwcsmap, cmpwcscurr); } } if (!frameSet) return 0; astSet(frameSet,"Title=%s", " "); // create astPlot float gbox[6]; double pbox[6]; // params is a BBOX in DATA coords 0-n Vector3d ll = Vector3d(params->xmin,params->ymin,params->zmin); Vector3d ur = Vector3d(params->xmax,params->ymax,params->zmax); pbox[0] = gbox[0] = ll[0]; pbox[1] = gbox[1] = ll[1]; pbox[2] = gbox[2] = ll[2]; pbox[3] = gbox[3] = ur[0]; pbox[4] = gbox[4] = ur[1]; pbox[5] = gbox[5] = ur[2]; // and now create astGrid astGrid3dPtr = this; renderMode_ = rm; plot = astPlot3D(frameSet, gbox, pbox, option_); // astShow(plot); astGrid(plot); astEnd; // now, clean up memory astGrid3dPtr =NULL; return 1; } void* Grid3d::matrixMap(Matrix& mx, const char* str) { double ss[] = {mx.matrix(0,0),mx.matrix(1,0), mx.matrix(0,1),mx.matrix(1,1)}; AstMatrixMap* mm; if (!(mm= astMatrixMap(2,2,0,ss,""))) return NULL; double tt[] = {mx.matrix(2,0),mx.matrix(2,1)}; AstShiftMap* sm; if (!(sm = astShiftMap(2,tt,""))) return NULL; AstCmpMap* mapxy; if (!(mapxy = astCmpMap(mm,sm,1,""))) return NULL; AstFrame* in = astFrame(3,"Domain=REF"); AstFrame* out = astFrame(3,str); double uu =.5; AstShiftMap* mapz = astShiftMap(1,&uu,""); AstCmpMap* cmap = astCmpMap(mapxy,mapz,0,""); AstFrameSet* frameSet = astFrameSet(in,""); astAddFrame(frameSet,AST__CURRENT,cmap,out); return frameSet; } �������������������������������������������������������./saods9/saotk/frame/lex.C��������������������������������������������������������������������������0000644�0001750�0001750�00000370075�12076042210�014220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lex.C" #line 4 "lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer frFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *fralloc (yy_size_t ); void *frrealloc (void *,yy_size_t ); void frfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 349 #define YY_END_OF_BUFFER 350 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[1239] = { 0, 0, 0, 350, 348, 347, 349, 348, 348, 348, 348, 348, 329, 329, 329, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 347, 346, 0, 346, 343, 0, 346, 344, 346, 329, 331, 330, 329, 346, 333, 346, 346, 346, 269, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 27, 346, 346, 346, 346, 346, 41, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 124, 346, 346, 346, 346, 346, 138, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 186, 346, 346, 346, 346, 193, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 273, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 324, 346, 346, 346, 346, 0, 346, 345, 343, 344, 331, 330, 335, 334, 346, 333, 346, 346, 346, 330, 346, 332, 346, 2, 346, 6, 7, 346, 346, 346, 346, 346, 346, 346, 346, 18, 346, 20, 346, 346, 346, 346, 346, 346, 28, 30, 346, 346, 32, 346, 35, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 76, 346, 346, 346, 346, 346, 346, 346, 346, 346, 90, 91, 346, 346, 346, 96, 346, 346, 346, 100, 346, 346, 346, 105, 346, 109, 111, 346, 346, 346, 346, 346, 346, 119, 346, 346, 346, 346, 126, 346, 346, 346, 346, 346, 346, 346, 346, 139, 346, 346, 346, 346, 346, 346, 346, 149, 346, 346, 346, 346, 346, 346, 346, 346, 161, 162, 346, 346, 166, 346, 346, 346, 346, 346, 346, 173, 346, 346, 346, 346, 346, 346, 181, 346, 346, 184, 346, 346, 188, 346, 346, 346, 192, 346, 346, 346, 197, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 213, 346, 346, 346, 346, 346, 346, 346, 346, 227, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 241, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 261, 346, 346, 346, 265, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 285, 346, 346, 346, 346, 292, 346, 346, 346, 323, 325, 346, 346, 346, 345, 336, 346, 331, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 19, 346, 346, 23, 24, 25, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 49, 346, 346, 52, 77, 346, 58, 346, 346, 346, 346, 346, 67, 346, 346, 346, 69, 346, 74, 346, 78, 80, 346, 346, 346, 346, 346, 346, 346, 346, 95, 346, 346, 346, 346, 346, 346, 103, 346, 106, 346, 346, 112, 113, 346, 115, 346, 346, 346, 346, 346, 122, 123, 346, 127, 346, 346, 131, 132, 346, 346, 137, 346, 346, 142, 143, 346, 146, 346, 346, 346, 346, 346, 346, 156, 158, 346, 159, 346, 346, 346, 167, 169, 346, 346, 346, 346, 174, 176, 346, 346, 179, 180, 346, 346, 185, 187, 189, 346, 346, 194, 346, 346, 346, 346, 346, 346, 346, 203, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 218, 346, 346, 346, 346, 346, 346, 346, 228, 346, 346, 346, 346, 346, 234, 346, 236, 346, 346, 346, 346, 346, 346, 346, 346, 346, 247, 248, 249, 346, 346, 346, 346, 346, 256, 346, 346, 346, 346, 346, 346, 346, 267, 346, 346, 346, 346, 346, 276, 277, 278, 346, 346, 346, 346, 283, 346, 346, 346, 346, 286, 291, 319, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 346, 346, 346, 326, 328, 346, 346, 337, 346, 346, 346, 346, 1, 5, 3, 346, 346, 10, 346, 346, 346, 346, 15, 16, 17, 346, 22, 26, 346, 346, 33, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 51, 53, 346, 346, 346, 346, 346, 346, 346, 346, 68, 346, 346, 70, 346, 346, 346, 346, 83, 346, 346, 346, 87, 346, 346, 346, 346, 346, 346, 99, 346, 102, 346, 107, 108, 346, 114, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 140, 346, 346, 346, 346, 148, 346, 151, 346, 153, 346, 346, 160, 346, 346, 346, 165, 346, 346, 346, 346, 346, 346, 346, 183, 346, 346, 346, 346, 198, 346, 200, 346, 202, 204, 346, 206, 346, 346, 209, 346, 346, 346, 214, 346, 346, 346, 346, 346, 346, 346, 346, 225, 346, 346, 230, 346, 346, 346, 235, 346, 238, 346, 346, 346, 243, 346, 245, 246, 250, 251, 346, 346, 346, 346, 346, 259, 346, 346, 346, 264, 346, 271, 346, 346, 346, 346, 346, 346, 346, 346, 346, 284, 346, 346, 346, 346, 320, 321, 322, 346, 338, 337, 346, 346, 341, 346, 346, 339, 346, 346, 346, 346, 12, 13, 14, 346, 346, 31, 34, 346, 37, 346, 39, 40, 346, 43, 346, 346, 46, 346, 346, 50, 346, 346, 346, 59, 346, 346, 346, 346, 346, 346, 346, 71, 72, 346, 75, 346, 346, 346, 346, 346, 86, 346, 346, 346, 346, 97, 346, 101, 104, 346, 346, 346, 346, 120, 346, 125, 128, 129, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 152, 157, 154, 163, 346, 168, 346, 171, 172, 346, 177, 178, 182, 190, 191, 195, 196, 199, 201, 346, 207, 208, 346, 346, 346, 346, 346, 346, 346, 220, 221, 222, 346, 346, 346, 229, 231, 346, 233, 346, 346, 240, 346, 244, 252, 253, 255, 346, 346, 260, 346, 263, 346, 346, 346, 274, 275, 346, 346, 279, 346, 282, 287, 346, 289, 346, 327, 342, 340, 4, 346, 346, 11, 21, 346, 346, 346, 346, 44, 346, 346, 48, 346, 346, 346, 346, 60, 61, 346, 346, 64, 346, 346, 346, 346, 81, 82, 85, 84, 346, 89, 346, 93, 346, 346, 346, 346, 346, 346, 346, 346, 134, 346, 346, 141, 144, 147, 346, 150, 346, 346, 170, 346, 346, 210, 211, 346, 346, 346, 346, 346, 223, 346, 346, 346, 346, 239, 346, 346, 257, 258, 346, 346, 268, 346, 346, 346, 346, 288, 346, 346, 9, 346, 346, 346, 42, 346, 47, 54, 55, 346, 346, 346, 63, 65, 346, 346, 79, 88, 92, 346, 346, 110, 116, 117, 118, 121, 346, 133, 346, 346, 346, 346, 346, 175, 205, 346, 215, 346, 217, 346, 224, 346, 232, 346, 346, 254, 346, 266, 346, 346, 346, 281, 290, 8, 29, 346, 38, 346, 346, 346, 62, 346, 73, 346, 346, 346, 135, 346, 145, 346, 164, 346, 346, 346, 346, 346, 346, 346, 270, 346, 346, 36, 45, 56, 57, 346, 346, 98, 346, 136, 346, 212, 216, 346, 226, 237, 346, 346, 346, 280, 66, 346, 346, 346, 219, 242, 346, 346, 346, 346, 155, 346, 272, 346, 130, 262, 94, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 4, 4, 4, 4, 6, 4, 4, 4, 7, 4, 8, 9, 4, 10, 11, 12, 13, 14, 15, 16, 16, 16, 17, 18, 4, 4, 4, 4, 4, 4, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 4, 4, 4, 4, 4, 4, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 4, 72, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[73] = { 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } ; static yyconst flex_int16_t yy_base[1246] = { 0, 0, 0, 335, 2881, 332, 2881, 0, 72, 77, 75, 83, 92, 69, 90, 141, 197, 246, 94, 291, 341, 140, 97, 386, 319, 96, 192, 291, 190, 296, 432, 346, 479, 530, 91, 244, 433, 105, 103, 155, 257, 294, 0, 287, 164, 0, 284, 360, 0, 415, 591, 650, 690, 85, 599, 607, 624, 632, 730, 664, 96, 130, 337, 145, 249, 161, 336, 346, 202, 205, 271, 398, 228, 250, 0, 415, 245, 427, 296, 293, 0, 469, 346, 300, 451, 389, 312, 751, 369, 423, 483, 513, 797, 489, 269, 359, 396, 411, 442, 485, 472, 496, 501, 531, 529, 67, 522, 522, 528, 652, 519, 529, 545, 0, 593, 665, 646, 532, 533, 0, 533, 607, 710, 609, 606, 274, 627, 665, 697, 698, 746, 841, 651, 734, 671, 766, 827, 691, 757, 657, 738, 742, 749, 756, 762, 775, 805, 782, 812, 778, 790, 846, 837, 805, 832, 873, 836, 856, 844, 881, 889, 881, 898, 886, 899, 908, 907, 914, 909, 939, 928, 923, 943, 933, 942, 946, 954, 932, 961, 948, 951, 972, 982, 958, 969, 973, 977, 990, 984, 0, 978, 997, 987, 1000, 175, 1024, 0, 2881, 2881, 1087, 1027, 0, 0, 1044, 0, 1054, 1101, 1067, 1114, 1128, 0, 1023, 0, 1068, 1061, 0, 1065, 1077, 1078, 1083, 1114, 1115, 1128, 1118, 0, 1118, 0, 1117, 219, 1125, 1132, 1114, 1130, 1137, 0, 1128, 1143, 0, 1143, 1147, 1135, 1145, 1140, 1131, 1155, 1152, 1146, 1157, 1165, 1178, 1183, 1169, 1175, 1172, 1182, 1168, 1171, 1165, 1180, 1182, 1198, 1184, 1196, 1183, 0, 1196, 1204, 1187, 1208, 1200, 1218, 1212, 1228, 1223, 0, 0, 1228, 1218, 1230, 0, 1226, 1240, 1223, 0, 1223, 1226, 1241, 1228, 1243, 225, 0, 1230, 1238, 1241, 1251, 1254, 1237, 0, 1255, 1259, 1256, 1266, 0, 1281, 1281, 1280, 1285, 1283, 1272, 1284, 1275, 0, 1288, 1285, 1283, 1294, 1294, 1284, 222, 1281, 1300, 1299, 1302, 1303, 1289, 1292, 1309, 1321, 0, 0, 1312, 1322, 0, 1326, 1329, 1338, 1323, 1335, 1331, 0, 1329, 1341, 1346, 1340, 1345, 1346, 0, 1343, 1349, 0, 1335, 1351, 0, 1353, 1356, 1354, 0, 1335, 1352, 1359, 1375, 1373, 1345, 1382, 1373, 1375, 1390, 1376, 1383, 1373, 1379, 0, 1382, 1388, 1393, 1392, 1397, 1398, 1396, 1435, 0, 1391, 1412, 1411, 1401, 1432, 1426, 1432, 1440, 1431, 1435, 1444, 0, 1450, 1437, 1448, 1447, 1435, 1451, 1455, 1458, 1462, 1449, 1454, 1450, 1449, 1482, 1487, 1472, 0, 1488, 1476, 1485, 0, 1482, 1479, 1497, 1496, 1495, 1495, 1490, 1500, 1501, 1492, 1499, 1495, 1506, 1511, 1495, 1494, 0, 1496, 1501, 1494, 1519, 1576, 1628, 1612, 187, 0, 0, 1609, 1621, 1634, 2881, 0, 1556, 1644, 1653, 1671, 1680, 1634, 1641, 1653, 1674, 1659, 1680, 1674, 1673, 1679, 1684, 1665, 1668, 1684, 0, 1692, 183, 0, 0, 0, 1680, 1681, 1687, 1686, 1693, 1685, 1699, 1697, 1697, 1701, 1703, 1693, 1687, 1728, 1721, 0, 1724, 1719, 0, 0, 1720, 0, 1726, 1739, 1740, 1727, 1739, 0, 1724, 1743, 1728, 0, 1730, 0, 1735, 1739, 1741, 1745, 1732, 1751, 1737, 1777, 1784, 1773, 1773, 0, 1774, 1787, 1772, 1788, 1779, 1790, 0, 1791, 1772, 1794, 1785, 0, 0, 1780, 0, 1781, 1799, 1784, 1803, 1797, 0, 0, 1794, 1802, 1800, 1794, 0, 1798, 1832, 1786, 0, 1834, 1819, 0, 0, 1834, 1829, 1842, 181, 1829, 1833, 1826, 1836, 1848, 0, 1838, 0, 1839, 1833, 1844, 1849, 0, 1847, 1855, 1842, 1857, 1850, 0, 1851, 1846, 0, 0, 1840, 1845, 0, 0, 0, 1884, 1888, 0, 1877, 1879, 1893, 1890, 1883, 1892, 1893, 0, 1884, 1891, 1889, 170, 1882, 1896, 1885, 1900, 1886, 1902, 1903, 0, 1900, 1915, 1896, 1911, 1900, 1894, 1929, 0, 1923, 1926, 1933, 1933, 1933, 0, 1943, 0, 1935, 1945, 1946, 1949, 1946, 1949, 1950, 1936, 1953, 0, 0, 0, 1953, 1943, 1940, 1956, 1960, 0, 1946, 1947, 1947, 1970, 1988, 1990, 1984, 0, 1986, 1997, 1987, 1999, 1982, 0, 0, 0, 1995, 2002, 1992, 1985, 0, 2001, 1992, 1999, 2004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 2002, 121, 0, 0, 1999, 2051, 2060, 2068, 2077, 2085, 2132, 0, 0, 2005, 2009, 2066, 0, 2065, 2083, 2074, 2086, 0, 0, 0, 2083, 0, 0, 2087, 2068, 0, 2075, 2080, 2077, 2088, 2106, 2090, 2108, 2091, 2122, 2118, 2121, 2125, 2136, 2137, 0, 2141, 2130, 2131, 2127, 2128, 2143, 2128, 2149, 2143, 0, 2152, 2150, 2148, 2139, 2149, 2150, 2156, 0, 2150, 2184, 2185, 0, 2171, 2178, 2173, 2175, 2194, 2181, 0, 2179, 0, 2180, 0, 0, 2184, 0, 2191, 2181, 2193, 2191, 2195, 2200, 2188, 2187, 2203, 2200, 2193, 2204, 2197, 0, 2209, 2209, 2232, 2222, 0, 2225, 0, 2236, 0, 2227, 2241, 0, 2223, 2242, 2231, 0, 2243, 2247, 2228, 2239, 2251, 2241, 2251, 0, 2239, 2238, 2245, 2240, 0, 2243, 0, 2244, 0, 0, 2260, 0, 2260, 2261, 2261, 2278, 2291, 2277, 0, 2293, 2279, 2295, 2287, 2281, 2287, 2299, 2287, 0, 2283, 2300, 0, 2301, 2306, 2301, 0, 2289, 0, 2296, 2291, 2307, 0, 2309, 0, 0, 0, 0, 2306, 2295, 2311, 2312, 2313, 0, 2326, 2339, 2334, 0, 2347, 0, 2345, 2342, 2346, 2332, 2337, 2346, 2351, 2351, 2352, 0, 2340, 2344, 2336, 2358, 0, 0, 0, 2357, 2105, 2371, 2397, 2405, 0, 2413, 2441, 0, 2389, 2408, 2409, 2400, 0, 0, 0, 2415, 2412, 0, 0, 2401, 0, 2420, 0, 0, 2422, 0, 2419, 2409, 0, 2419, 2417, 0, 2429, 2430, 2456, 0, 2457, 2443, 2454, 2445, 2447, 2447, 2453, 0, 0, 2467, 0, 2450, 2456, 2468, 2453, 2455, 0, 2460, 2472, 2468, 2473, 0, 2461, 0, 0, 114, 2465, 2472, 2481, 0, 2480, 0, 0, 0, 2481, 2491, 2491, 2495, 2500, 2510, 2498, 2503, 2509, 2515, 0, 0, 2515, 0, 2512, 0, 2517, 0, 0, 2520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2523, 0, 0, 2507, 2512, 2509, 2506, 2509, 2510, 2530, 0, 0, 0, 2527, 2521, 2514, 0, 0, 2528, 0, 2527, 2543, 0, 2545, 0, 0, 2558, 0, 2562, 2563, 0, 2567, 0, 2549, 2551, 2556, 0, 0, 2571, 2561, 0, 2571, 0, 0, 2561, 0, 2575, 0, 0, 0, 0, 2572, 2559, 0, 0, 2578, 2568, 2569, 2571, 0, 2574, 2580, 0, 2567, 2570, 2586, 2587, 0, 0, 2595, 2597, 0, 2597, 2617, 2610, 2600, 0, 0, 0, 0, 2603, 0, 2619, 2622, 2615, 2620, 2612, 2624, 2614, 2610, 2618, 2626, 0, 2631, 2613, 0, 0, 0, 2619, 0, 2621, 2631, 0, 2619, 2626, 0, 0, 2630, 2635, 2658, 2643, 2649, 0, 2665, 2662, 2667, 2667, 0, 2665, 2649, 0, 0, 2664, 2672, 0, 2666, 2661, 2671, 2661, 0, 2670, 2665, 0, 2670, 2664, 2681, 0, 2686, 0, 0, 0, 2676, 2686, 2685, 0, 0, 2671, 2674, 0, 0, 0, 2705, 2719, 0, 0, 0, 0, 0, 2712, 0, 2709, 2722, 2710, 2721, 2708, 0, 0, 2711, 0, 2713, 0, 2720, 0, 2715, 0, 2722, 2719, 0, 2732, 0, 2730, 2730, 2716, 0, 0, 0, 0, 2718, 0, 2726, 2734, 2735, 0, 2736, 0, 2728, 2731, 2728, 0, 2759, 0, 2763, 0, 2753, 2760, 2760, 2762, 2774, 2777, 2776, 0, 2766, 2776, 0, 0, 0, 0, 2763, 2762, 0, 2764, 0, 2784, 0, 0, 2772, 0, 0, 2775, 2768, 2786, 0, 0, 2778, 2782, 2778, 0, 0, 2784, 2769, 2774, 2793, 0, 2820, 0, 2805, 0, 0, 0, 2881, 74, 2868, 2870, 2872, 2874, 2876, 2878 } ; static yyconst flex_int16_t yy_def[1246] = { 0, 1238, 1, 1238, 1238, 1238, 1238, 1239, 1240, 1241, 1239, 1239, 1239, 12, 12, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1242, 1238, 1239, 1243, 1240, 1239, 1244, 1241, 1239, 1239, 12, 1239, 1239, 12, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1245, 1242, 1239, 1238, 1238, 1239, 199, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 58, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1238, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1238, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 0, 1238, 1238, 1238, 1238, 1238, 1238, 1238 } ; static yyconst flex_int16_t yy_nxt[2954] = { 0, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 13, 13, 13, 13, 7, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 7, 31, 32, 33, 34, 35, 36, 37, 38, 39, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 7, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 7, 43, 43, 43, 42, 45, 46, 46, 46, 289, 290, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 53, 53, 53, 53, 53, 53, 53, 54, 42, 59, 91, 55, 56, 114, 92, 57, 126, 115, 93, 1074, 178, 116, 179, 190, 42, 180, 211, 117, 94, 42, 888, 58, 886, 188, 42, 59, 91, 55, 56, 114, 92, 57, 126, 115, 93, 189, 178, 116, 179, 190, 42, 180, 211, 117, 94, 42, 109, 58, 60, 188, 110, 212, 43, 43, 43, 61, 45, 111, 62, 63, 64, 189, 65, 112, 66, 67, 216, 68, 69, 826, 827, 113, 109, 191, 60, 192, 110, 212, 794, 193, 720, 61, 220, 111, 62, 63, 64, 696, 65, 112, 66, 67, 216, 68, 69, 70, 136, 113, 127, 191, 137, 192, 128, 71, 72, 193, 129, 73, 220, 74, 138, 75, 130, 139, 76, 227, 140, 77, 78, 554, 526, 466, 136, 79, 127, 80, 137, 225, 128, 71, 72, 226, 129, 73, 444, 74, 138, 75, 130, 139, 76, 227, 140, 77, 78, 194, 194, 194, 231, 79, 181, 80, 81, 225, 182, 217, 82, 226, 183, 83, 84, 218, 232, 85, 86, 236, 87, 88, 219, 89, 237, 318, 90, 275, 231, 228, 181, 198, 81, 197, 182, 217, 82, 41, 183, 83, 84, 218, 232, 85, 86, 236, 87, 88, 219, 89, 237, 131, 90, 95, 96, 132, 240, 141, 241, 133, 247, 142, 97, 134, 98, 135, 99, 100, 101, 143, 196, 144, 125, 145, 102, 41, 1238, 131, 1238, 95, 96, 132, 240, 141, 241, 133, 247, 142, 97, 134, 98, 135, 99, 100, 101, 143, 252, 144, 221, 145, 102, 103, 46, 46, 46, 213, 154, 48, 214, 104, 155, 105, 156, 222, 223, 106, 215, 245, 107, 246, 157, 108, 252, 1238, 221, 224, 158, 103, 1238, 259, 276, 213, 154, 1238, 214, 104, 155, 105, 156, 222, 223, 106, 215, 245, 107, 246, 157, 108, 118, 119, 1238, 224, 158, 250, 120, 259, 276, 251, 121, 122, 229, 1238, 1238, 123, 277, 124, 199, 199, 199, 199, 199, 199, 199, 199, 118, 119, 230, 1238, 1238, 250, 120, 233, 278, 251, 121, 122, 229, 260, 234, 123, 277, 124, 146, 184, 235, 185, 147, 261, 186, 148, 149, 187, 230, 150, 238, 279, 151, 233, 278, 152, 239, 248, 153, 260, 234, 1238, 1238, 1238, 146, 184, 235, 185, 147, 261, 186, 148, 149, 187, 249, 150, 238, 279, 151, 1238, 1238, 152, 239, 248, 153, 159, 242, 160, 243, 161, 262, 280, 162, 163, 244, 273, 164, 165, 281, 166, 249, 167, 282, 168, 169, 170, 263, 274, 264, 171, 1238, 159, 242, 160, 243, 161, 262, 280, 162, 163, 244, 273, 164, 165, 281, 166, 283, 167, 282, 168, 169, 170, 263, 274, 264, 171, 172, 265, 266, 284, 173, 291, 292, 174, 297, 293, 286, 294, 285, 298, 175, 299, 283, 176, 287, 309, 310, 311, 288, 300, 177, 1238, 172, 265, 266, 284, 173, 291, 292, 174, 297, 293, 286, 294, 285, 298, 175, 299, 1238, 176, 287, 309, 310, 311, 288, 300, 177, 200, 50, 50, 50, 50, 50, 50, 50, 50, 205, 205, 205, 205, 205, 205, 205, 205, 206, 206, 206, 206, 206, 206, 206, 206, 301, 312, 201, 316, 317, 302, 207, 207, 42, 208, 208, 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 209, 209, 1238, 301, 312, 201, 316, 317, 302, 1238, 1238, 42, 51, 51, 51, 51, 51, 51, 51, 51, 306, 1238, 319, 307, 202, 203, 206, 206, 206, 206, 206, 206, 206, 206, 295, 308, 303, 320, 1238, 1238, 336, 337, 340, 296, 304, 353, 306, 305, 319, 307, 202, 203, 51, 51, 51, 51, 51, 51, 51, 51, 295, 308, 303, 320, 204, 56, 336, 337, 340, 296, 304, 353, 1238, 305, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 321, 323, 313, 349, 350, 314, 324, 325, 322, 204, 56, 210, 210, 210, 210, 210, 210, 210, 210, 315, 210, 210, 210, 210, 210, 210, 321, 323, 313, 349, 350, 314, 324, 325, 322, 1238, 326, 338, 327, 339, 354, 355, 328, 1238, 356, 315, 210, 210, 210, 210, 210, 210, 253, 254, 255, 256, 257, 357, 329, 341, 351, 258, 326, 338, 327, 339, 354, 355, 328, 352, 356, 358, 1238, 359, 342, 343, 1238, 344, 253, 254, 255, 256, 257, 357, 329, 341, 351, 258, 267, 363, 1238, 366, 268, 269, 367, 352, 375, 358, 270, 359, 342, 343, 271, 344, 1238, 1238, 272, 1238, 360, 1238, 1238, 1238, 361, 362, 267, 363, 364, 366, 268, 269, 367, 1238, 375, 1238, 270, 376, 365, 380, 271, 345, 346, 372, 272, 330, 360, 373, 347, 331, 361, 362, 348, 374, 364, 1238, 368, 383, 332, 369, 333, 334, 335, 376, 365, 380, 370, 345, 346, 372, 371, 330, 381, 373, 347, 331, 1238, 382, 348, 374, 1238, 377, 368, 383, 332, 369, 333, 334, 335, 390, 378, 387, 370, 379, 391, 384, 371, 385, 381, 388, 394, 398, 392, 382, 386, 389, 393, 377, 395, 400, 1238, 403, 396, 399, 397, 390, 378, 387, 407, 379, 391, 384, 401, 385, 402, 388, 394, 398, 392, 404, 386, 389, 393, 405, 395, 400, 406, 403, 396, 399, 397, 408, 409, 411, 407, 410, 412, 414, 401, 422, 402, 413, 416, 427, 418, 404, 420, 428, 415, 405, 1238, 417, 406, 419, 433, 1238, 423, 408, 409, 411, 424, 410, 412, 414, 425, 422, 421, 413, 416, 427, 418, 426, 420, 428, 415, 429, 431, 417, 434, 419, 433, 430, 423, 435, 436, 437, 424, 439, 440, 441, 425, 432, 421, 442, 443, 438, 1238, 426, 194, 194, 194, 429, 431, 1238, 434, 1238, 1238, 430, 1238, 435, 436, 437, 1238, 439, 440, 441, 1238, 432, 1238, 442, 443, 438, 204, 56, 446, 446, 1238, 447, 447, 447, 447, 447, 447, 447, 447, 451, 201, 205, 205, 205, 205, 205, 205, 205, 205, 448, 1238, 1238, 204, 56, 208, 208, 208, 208, 208, 208, 208, 208, 1238, 1238, 1238, 451, 201, 1238, 1238, 1238, 452, 453, 454, 196, 199, 199, 199, 199, 199, 199, 199, 199, 1238, 1238, 455, 456, 202, 203, 206, 206, 206, 206, 206, 206, 206, 206, 452, 453, 454, 457, 445, 208, 208, 208, 208, 208, 208, 208, 208, 449, 455, 456, 202, 203, 458, 209, 209, 209, 209, 209, 209, 209, 209, 459, 461, 457, 445, 463, 464, 460, 465, 467, 468, 469, 470, 449, 450, 471, 462, 472, 458, 473, 474, 475, 477, 476, 478, 479, 480, 459, 461, 481, 482, 463, 464, 460, 465, 467, 468, 469, 470, 483, 450, 471, 462, 472, 484, 473, 474, 475, 477, 476, 478, 479, 480, 485, 486, 481, 482, 487, 488, 489, 490, 495, 496, 497, 491, 483, 492, 498, 493, 499, 484, 494, 500, 501, 503, 504, 502, 505, 506, 485, 486, 507, 508, 487, 488, 489, 490, 495, 496, 497, 491, 509, 492, 498, 493, 499, 510, 494, 500, 501, 503, 504, 502, 505, 506, 511, 512, 507, 508, 513, 514, 515, 516, 517, 518, 519, 520, 509, 521, 522, 524, 525, 510, 527, 528, 529, 530, 531, 532, 533, 534, 511, 512, 537, 523, 513, 514, 515, 516, 517, 518, 519, 520, 538, 521, 522, 524, 525, 535, 527, 528, 529, 530, 531, 532, 533, 534, 536, 539, 537, 523, 540, 541, 542, 543, 544, 545, 546, 547, 538, 548, 550, 551, 552, 535, 553, 549, 555, 556, 557, 558, 559, 560, 536, 539, 561, 562, 540, 541, 542, 543, 544, 545, 546, 547, 563, 548, 550, 551, 552, 564, 553, 549, 555, 556, 557, 558, 559, 560, 565, 566, 561, 562, 567, 568, 569, 570, 571, 572, 573, 574, 563, 575, 576, 577, 578, 564, 579, 580, 581, 582, 583, 584, 585, 586, 565, 566, 587, 592, 567, 568, 569, 570, 571, 572, 573, 574, 590, 575, 576, 577, 578, 588, 579, 580, 581, 582, 583, 584, 585, 586, 593, 589, 587, 592, 591, 594, 595, 596, 597, 598, 599, 600, 590, 601, 602, 603, 606, 588, 607, 608, 609, 604, 1238, 613, 605, 614, 593, 589, 615, 616, 591, 594, 595, 596, 597, 598, 599, 600, 1238, 601, 602, 603, 606, 619, 607, 608, 609, 604, 610, 613, 605, 614, 611, 617, 615, 616, 620, 622, 621, 623, 624, 625, 612, 626, 618, 627, 629, 628, 630, 619, 631, 632, 633, 634, 610, 635, 636, 637, 611, 617, 638, 639, 620, 622, 621, 623, 624, 625, 612, 626, 618, 627, 629, 628, 630, 640, 631, 632, 633, 634, 641, 635, 636, 637, 642, 643, 638, 639, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 640, 657, 658, 659, 660, 641, 661, 662, 665, 642, 643, 663, 664, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 666, 657, 658, 659, 660, 1238, 661, 662, 665, 1238, 1238, 663, 664, 447, 447, 447, 447, 447, 447, 447, 447, 1238, 1238, 1238, 1238, 1238, 666, 42, 42, 42, 42, 42, 42, 667, 42, 42, 42, 42, 42, 42, 42, 42, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 42, 42, 694, 695, 697, 698, 699, 447, 447, 447, 447, 447, 447, 447, 447, 700, 701, 701, 701, 701, 701, 701, 701, 701, 1238, 706, 707, 708, 694, 695, 697, 698, 699, 702, 703, 703, 703, 703, 703, 703, 703, 703, 704, 705, 705, 705, 705, 705, 705, 705, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 721, 722, 723, 724, 725, 726, 727, 729, 730, 731, 732, 733, 734, 1238, 728, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 721, 722, 723, 724, 725, 726, 727, 729, 730, 731, 732, 733, 734, 735, 728, 737, 738, 739, 740, 741, 742, 743, 746, 748, 749, 747, 736, 750, 751, 752, 753, 754, 757, 758, 755, 744, 759, 760, 745, 735, 756, 737, 738, 739, 740, 741, 742, 743, 746, 748, 749, 747, 736, 750, 751, 752, 753, 754, 757, 758, 755, 744, 759, 760, 745, 761, 756, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 761, 788, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 788, 789, 790, 791, 792, 793, 795, 796, 797, 787, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 786, 813, 789, 790, 791, 792, 793, 795, 796, 797, 787, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 814, 813, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 828, 829, 830, 831, 832, 833, 834, 835, 1238, 838, 839, 840, 841, 814, 836, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 828, 829, 830, 831, 832, 833, 834, 835, 837, 838, 839, 840, 841, 842, 836, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 837, 862, 863, 864, 865, 842, 866, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 867, 862, 863, 864, 865, 868, 866, 869, 870, 871, 872, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 887, 889, 898, 885, 867, 899, 873, 1238, 1238, 868, 1238, 869, 870, 871, 872, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 887, 889, 898, 885, 1238, 899, 873, 890, 890, 890, 890, 890, 890, 890, 890, 891, 701, 701, 701, 701, 701, 701, 701, 701, 892, 892, 892, 892, 892, 892, 892, 892, 893, 703, 703, 703, 703, 703, 703, 703, 703, 895, 895, 895, 895, 895, 895, 895, 895, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 894, 890, 890, 890, 890, 890, 890, 890, 890, 1238, 911, 912, 913, 914, 915, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 894, 896, 705, 705, 705, 705, 705, 705, 705, 705, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 925, 926, 927, 928, 929, 930, 931, 897, 932, 933, 923, 934, 935, 936, 937, 938, 924, 939, 940, 916, 917, 918, 919, 920, 921, 922, 925, 926, 927, 928, 929, 930, 931, 897, 932, 933, 923, 934, 935, 936, 937, 938, 924, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 890, 890, 890, 890, 890, 890, 890, 890, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 895, 895, 895, 895, 895, 895, 895, 895, 1238, 1238, 1039, 1037, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 894, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1038, 895, 895, 895, 895, 895, 895, 895, 895, 1039, 1037, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 894, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1038, 1054, 897, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1055, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1075, 1076, 1077, 1078, 1079, 1054, 897, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1055, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1236, 1237, 44, 44, 47, 47, 195, 195, 43, 43, 46, 46, 194, 194, 3, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238 } ; static yyconst flex_int16_t yy_chk[2954] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 1239, 8, 9, 9, 9, 105, 105, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 14, 18, 12, 12, 22, 18, 12, 25, 22, 18, 951, 34, 22, 34, 38, 53, 34, 60, 22, 18, 14, 696, 12, 694, 37, 13, 14, 18, 12, 12, 22, 18, 12, 25, 22, 18, 37, 34, 22, 34, 38, 53, 34, 60, 22, 18, 14, 21, 12, 15, 37, 21, 61, 44, 44, 44, 15, 44, 21, 15, 15, 15, 37, 15, 21, 15, 15, 63, 15, 15, 597, 597, 21, 21, 39, 15, 39, 21, 61, 554, 39, 466, 15, 65, 21, 15, 15, 15, 438, 15, 21, 15, 15, 63, 15, 15, 16, 28, 21, 26, 39, 28, 39, 26, 16, 16, 39, 26, 16, 65, 16, 28, 16, 26, 28, 16, 69, 28, 16, 16, 318, 289, 228, 28, 16, 26, 16, 28, 68, 26, 16, 16, 68, 26, 16, 194, 16, 28, 16, 26, 28, 16, 69, 28, 16, 16, 40, 40, 40, 72, 16, 35, 16, 17, 68, 35, 64, 17, 68, 35, 17, 17, 64, 73, 17, 17, 76, 17, 17, 64, 17, 76, 125, 17, 94, 72, 70, 35, 46, 17, 43, 35, 64, 17, 41, 35, 17, 17, 64, 73, 17, 17, 76, 17, 17, 64, 17, 76, 27, 17, 19, 19, 27, 78, 29, 79, 27, 83, 29, 19, 27, 19, 27, 19, 19, 19, 29, 40, 29, 24, 29, 19, 5, 3, 27, 0, 19, 19, 27, 78, 29, 79, 27, 83, 29, 19, 27, 19, 27, 19, 19, 19, 29, 86, 29, 66, 29, 19, 20, 47, 47, 47, 62, 31, 47, 62, 20, 31, 20, 31, 66, 67, 20, 62, 82, 20, 82, 31, 20, 86, 0, 66, 67, 31, 20, 0, 88, 95, 62, 31, 0, 62, 20, 31, 20, 31, 66, 67, 20, 62, 82, 20, 82, 31, 20, 23, 23, 0, 67, 31, 85, 23, 88, 95, 85, 23, 23, 71, 0, 0, 23, 96, 23, 49, 49, 49, 49, 49, 49, 49, 49, 23, 23, 71, 0, 0, 85, 23, 75, 97, 85, 23, 23, 71, 89, 75, 23, 96, 23, 30, 36, 75, 36, 30, 89, 36, 30, 30, 36, 71, 30, 77, 98, 30, 75, 97, 30, 77, 84, 30, 89, 75, 0, 0, 0, 30, 36, 75, 36, 30, 89, 36, 30, 30, 36, 84, 30, 77, 98, 30, 0, 0, 30, 77, 84, 30, 32, 81, 32, 81, 32, 90, 99, 32, 32, 81, 93, 32, 32, 100, 32, 84, 32, 101, 32, 32, 32, 90, 93, 90, 32, 0, 32, 81, 32, 81, 32, 90, 99, 32, 32, 81, 93, 32, 32, 100, 32, 102, 32, 101, 32, 32, 32, 90, 93, 90, 32, 33, 91, 91, 103, 33, 106, 107, 33, 110, 108, 104, 108, 103, 111, 33, 112, 102, 33, 104, 117, 118, 120, 104, 112, 33, 0, 33, 91, 91, 103, 33, 106, 107, 33, 110, 108, 104, 108, 103, 111, 33, 112, 0, 33, 104, 117, 118, 120, 104, 112, 33, 50, 50, 50, 50, 50, 50, 50, 50, 50, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 114, 121, 50, 123, 124, 114, 56, 56, 50, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 0, 114, 121, 50, 123, 124, 114, 0, 0, 50, 51, 51, 51, 51, 51, 51, 51, 51, 116, 0, 126, 116, 51, 51, 59, 59, 59, 59, 59, 59, 59, 59, 109, 116, 115, 127, 0, 0, 132, 132, 134, 109, 115, 139, 116, 115, 126, 116, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 109, 116, 115, 127, 52, 52, 132, 132, 134, 109, 115, 139, 0, 115, 0, 0, 0, 0, 0, 0, 0, 128, 129, 122, 137, 137, 122, 129, 129, 128, 52, 52, 58, 58, 58, 58, 58, 58, 58, 58, 122, 58, 58, 58, 58, 58, 58, 128, 129, 122, 137, 137, 122, 129, 129, 128, 0, 130, 133, 130, 133, 140, 141, 130, 0, 142, 122, 58, 58, 58, 58, 58, 58, 87, 87, 87, 87, 87, 143, 130, 135, 138, 87, 130, 133, 130, 133, 140, 141, 130, 138, 142, 144, 0, 145, 135, 135, 0, 135, 87, 87, 87, 87, 87, 143, 130, 135, 138, 87, 92, 147, 0, 149, 92, 92, 150, 138, 153, 144, 92, 145, 135, 135, 92, 135, 0, 0, 92, 0, 146, 0, 0, 0, 146, 146, 92, 147, 148, 149, 92, 92, 150, 0, 153, 0, 92, 154, 148, 156, 92, 136, 136, 152, 92, 131, 146, 152, 136, 131, 146, 146, 136, 152, 148, 0, 151, 158, 131, 151, 131, 131, 131, 154, 148, 156, 151, 136, 136, 152, 151, 131, 157, 152, 136, 131, 0, 157, 136, 152, 0, 155, 151, 158, 131, 151, 131, 131, 131, 161, 155, 160, 151, 155, 161, 159, 151, 159, 157, 160, 162, 163, 161, 157, 159, 160, 161, 155, 162, 164, 0, 166, 162, 163, 162, 161, 155, 160, 168, 155, 161, 159, 165, 159, 165, 160, 162, 163, 161, 166, 159, 160, 161, 167, 162, 164, 167, 166, 162, 163, 162, 169, 170, 171, 168, 170, 172, 173, 165, 177, 165, 172, 174, 179, 175, 166, 176, 180, 173, 167, 0, 174, 167, 175, 183, 0, 178, 169, 170, 171, 178, 170, 172, 173, 178, 177, 176, 172, 174, 179, 175, 178, 176, 180, 173, 181, 182, 174, 184, 175, 183, 181, 178, 185, 186, 187, 178, 188, 190, 191, 178, 182, 176, 192, 193, 187, 0, 178, 195, 195, 195, 181, 182, 0, 184, 0, 0, 181, 0, 185, 186, 187, 0, 188, 190, 191, 0, 182, 0, 192, 193, 187, 200, 200, 203, 203, 0, 203, 203, 203, 203, 203, 203, 203, 203, 211, 200, 205, 205, 205, 205, 205, 205, 205, 205, 205, 0, 0, 200, 200, 207, 207, 207, 207, 207, 207, 207, 207, 0, 0, 0, 211, 200, 0, 0, 0, 213, 214, 216, 195, 199, 199, 199, 199, 199, 199, 199, 199, 0, 0, 217, 218, 199, 199, 206, 206, 206, 206, 206, 206, 206, 206, 213, 214, 216, 219, 199, 208, 208, 208, 208, 208, 208, 208, 208, 206, 217, 218, 199, 199, 220, 209, 209, 209, 209, 209, 209, 209, 209, 221, 222, 219, 199, 223, 225, 221, 227, 229, 230, 231, 232, 206, 209, 233, 222, 235, 220, 236, 238, 239, 240, 239, 241, 242, 243, 221, 222, 244, 245, 223, 225, 221, 227, 229, 230, 231, 232, 246, 209, 233, 222, 235, 247, 236, 238, 239, 240, 239, 241, 242, 243, 248, 249, 244, 245, 250, 251, 252, 253, 255, 256, 257, 253, 246, 253, 258, 254, 259, 247, 254, 260, 261, 262, 263, 261, 265, 266, 248, 249, 267, 268, 250, 251, 252, 253, 255, 256, 257, 253, 269, 253, 258, 254, 259, 270, 254, 260, 261, 262, 263, 261, 265, 266, 271, 272, 267, 268, 273, 276, 277, 278, 280, 281, 282, 284, 269, 285, 286, 287, 288, 270, 291, 292, 292, 293, 294, 295, 296, 298, 271, 272, 300, 286, 273, 276, 277, 278, 280, 281, 282, 284, 301, 285, 286, 287, 288, 299, 291, 292, 292, 293, 294, 295, 296, 298, 299, 303, 300, 286, 304, 305, 306, 307, 308, 309, 310, 312, 301, 313, 314, 315, 316, 299, 317, 313, 319, 320, 321, 322, 323, 324, 299, 303, 325, 326, 304, 305, 306, 307, 308, 309, 310, 312, 327, 313, 314, 315, 316, 330, 317, 313, 319, 320, 321, 322, 323, 324, 331, 333, 325, 326, 334, 335, 336, 337, 338, 340, 341, 342, 327, 343, 344, 345, 347, 330, 348, 350, 351, 353, 354, 355, 357, 358, 331, 333, 359, 362, 334, 335, 336, 337, 338, 340, 341, 342, 361, 343, 344, 345, 347, 360, 348, 350, 351, 353, 354, 355, 357, 358, 363, 360, 359, 362, 361, 364, 365, 366, 367, 368, 369, 370, 361, 372, 373, 374, 375, 360, 376, 377, 378, 374, 0, 381, 374, 382, 363, 360, 383, 384, 361, 364, 365, 366, 367, 368, 369, 370, 0, 372, 373, 374, 375, 386, 376, 377, 378, 374, 379, 381, 374, 382, 379, 385, 383, 384, 387, 388, 387, 389, 390, 391, 379, 393, 385, 394, 395, 394, 396, 386, 397, 398, 399, 400, 379, 401, 402, 403, 379, 385, 404, 405, 387, 388, 387, 389, 390, 391, 379, 393, 385, 394, 395, 394, 396, 406, 397, 398, 399, 400, 407, 401, 402, 403, 408, 410, 404, 405, 411, 412, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 406, 425, 426, 427, 428, 407, 429, 431, 433, 408, 410, 432, 432, 411, 412, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 434, 425, 426, 427, 428, 0, 429, 431, 433, 0, 0, 432, 432, 446, 446, 446, 446, 446, 446, 446, 446, 0, 0, 0, 0, 0, 434, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 436, 437, 441, 442, 443, 447, 447, 447, 447, 447, 447, 447, 447, 448, 448, 448, 448, 448, 448, 448, 448, 448, 0, 451, 452, 453, 436, 437, 441, 442, 443, 449, 449, 449, 449, 449, 449, 449, 449, 449, 450, 450, 450, 450, 450, 450, 450, 450, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 465, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 0, 476, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 465, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 476, 484, 486, 487, 490, 492, 493, 494, 495, 496, 498, 495, 483, 499, 500, 502, 504, 505, 507, 508, 506, 494, 509, 510, 494, 483, 506, 484, 486, 487, 490, 492, 493, 494, 495, 496, 498, 495, 483, 499, 500, 502, 504, 505, 507, 508, 506, 494, 509, 510, 494, 511, 506, 512, 513, 514, 516, 517, 518, 519, 520, 521, 523, 524, 525, 526, 529, 531, 532, 533, 534, 535, 538, 539, 540, 541, 543, 511, 545, 512, 513, 514, 516, 517, 518, 519, 520, 521, 523, 524, 525, 526, 529, 531, 532, 533, 534, 535, 538, 539, 540, 541, 543, 544, 545, 547, 548, 551, 552, 553, 555, 556, 557, 544, 558, 559, 561, 563, 564, 565, 566, 568, 569, 570, 571, 572, 574, 575, 578, 544, 579, 547, 548, 551, 552, 553, 555, 556, 557, 544, 558, 559, 561, 563, 564, 565, 566, 568, 569, 570, 571, 572, 574, 575, 578, 583, 579, 584, 586, 587, 588, 589, 590, 591, 592, 594, 595, 596, 598, 599, 600, 601, 602, 603, 604, 606, 0, 608, 609, 610, 611, 583, 607, 584, 586, 587, 588, 589, 590, 591, 592, 594, 595, 596, 598, 599, 600, 601, 602, 603, 604, 606, 607, 608, 609, 610, 611, 612, 607, 614, 615, 616, 617, 618, 620, 622, 623, 624, 625, 626, 627, 628, 629, 630, 634, 635, 636, 637, 607, 638, 640, 641, 642, 612, 642, 614, 615, 616, 617, 618, 620, 622, 623, 624, 625, 626, 627, 628, 629, 630, 634, 635, 636, 637, 643, 638, 640, 641, 642, 644, 642, 645, 646, 648, 649, 650, 651, 652, 656, 657, 658, 659, 661, 662, 663, 664, 695, 699, 708, 664, 643, 709, 649, 0, 0, 644, 0, 645, 646, 648, 649, 650, 651, 652, 656, 657, 658, 659, 661, 662, 663, 664, 695, 699, 708, 664, 0, 709, 649, 700, 700, 700, 700, 700, 700, 700, 700, 701, 701, 701, 701, 701, 701, 701, 701, 701, 702, 702, 702, 702, 702, 702, 702, 702, 703, 703, 703, 703, 703, 703, 703, 703, 703, 704, 704, 704, 704, 704, 704, 704, 704, 710, 712, 713, 714, 715, 719, 722, 723, 725, 726, 727, 703, 890, 890, 890, 890, 890, 890, 890, 890, 0, 728, 729, 730, 731, 732, 710, 712, 713, 714, 715, 719, 722, 723, 725, 726, 727, 703, 705, 705, 705, 705, 705, 705, 705, 705, 705, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 740, 741, 742, 743, 744, 745, 746, 747, 705, 748, 750, 740, 751, 752, 753, 754, 755, 740, 756, 758, 733, 734, 735, 736, 737, 738, 740, 741, 742, 743, 744, 745, 746, 747, 705, 748, 750, 740, 751, 752, 753, 754, 755, 740, 756, 758, 759, 760, 762, 763, 764, 765, 766, 767, 769, 771, 774, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 790, 791, 759, 760, 762, 763, 764, 765, 766, 767, 769, 771, 774, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 790, 791, 792, 793, 795, 797, 799, 800, 802, 803, 804, 806, 807, 808, 809, 810, 811, 812, 814, 815, 816, 817, 819, 821, 824, 826, 827, 828, 792, 793, 795, 797, 799, 800, 802, 803, 804, 806, 807, 808, 809, 810, 811, 812, 814, 815, 816, 817, 819, 821, 824, 826, 827, 828, 829, 830, 831, 833, 834, 835, 836, 837, 838, 839, 840, 842, 843, 845, 846, 847, 849, 851, 852, 853, 855, 860, 861, 862, 863, 864, 829, 830, 831, 833, 834, 835, 836, 837, 838, 839, 840, 842, 843, 845, 846, 847, 849, 851, 852, 853, 855, 860, 861, 862, 863, 864, 866, 867, 868, 870, 872, 873, 874, 875, 876, 877, 878, 879, 880, 882, 883, 884, 885, 889, 891, 891, 891, 891, 891, 891, 891, 891, 866, 867, 868, 870, 872, 873, 874, 875, 876, 877, 878, 879, 880, 882, 883, 884, 885, 889, 892, 892, 892, 892, 892, 892, 892, 892, 893, 893, 893, 893, 893, 893, 893, 893, 895, 895, 895, 895, 895, 895, 895, 895, 0, 0, 898, 892, 899, 900, 901, 905, 906, 909, 911, 893, 914, 916, 917, 919, 920, 922, 923, 895, 896, 896, 896, 896, 896, 896, 896, 896, 898, 892, 899, 900, 901, 905, 906, 909, 911, 893, 914, 916, 917, 919, 920, 922, 923, 895, 924, 896, 926, 927, 928, 929, 930, 931, 932, 935, 937, 938, 939, 924, 940, 941, 943, 944, 945, 946, 948, 952, 953, 954, 956, 960, 924, 896, 926, 927, 928, 929, 930, 931, 932, 935, 937, 938, 939, 924, 940, 941, 943, 944, 945, 946, 948, 952, 953, 954, 956, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 972, 974, 976, 979, 989, 992, 993, 994, 995, 996, 997, 998, 1002, 1003, 1004, 1007, 1009, 961, 962, 963, 964, 965, 966, 967, 968, 969, 972, 974, 976, 979, 989, 992, 993, 994, 995, 996, 997, 998, 1002, 1003, 1004, 1007, 1009, 1010, 1012, 1015, 1017, 1018, 1020, 1022, 1023, 1024, 1027, 1028, 1030, 1033, 1035, 1040, 1041, 1044, 1045, 1046, 1047, 1049, 1050, 1052, 1053, 1054, 1055, 1010, 1012, 1015, 1017, 1018, 1020, 1022, 1023, 1024, 1027, 1028, 1030, 1033, 1035, 1040, 1041, 1044, 1045, 1046, 1047, 1049, 1050, 1052, 1053, 1054, 1055, 1058, 1059, 1061, 1062, 1063, 1064, 1069, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1082, 1083, 1087, 1089, 1090, 1092, 1093, 1096, 1097, 1058, 1059, 1061, 1062, 1063, 1064, 1069, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1082, 1083, 1087, 1089, 1090, 1092, 1093, 1096, 1097, 1098, 1099, 1100, 1102, 1103, 1104, 1105, 1107, 1108, 1111, 1112, 1114, 1115, 1116, 1117, 1119, 1120, 1122, 1123, 1124, 1126, 1130, 1131, 1132, 1135, 1136, 1098, 1099, 1100, 1102, 1103, 1104, 1105, 1107, 1108, 1111, 1112, 1114, 1115, 1116, 1117, 1119, 1120, 1122, 1123, 1124, 1126, 1130, 1131, 1132, 1135, 1136, 1140, 1141, 1147, 1149, 1150, 1151, 1152, 1153, 1156, 1158, 1160, 1162, 1164, 1165, 1167, 1169, 1170, 1171, 1176, 1178, 1179, 1180, 1182, 1184, 1185, 1186, 1140, 1141, 1147, 1149, 1150, 1151, 1152, 1153, 1156, 1158, 1160, 1162, 1164, 1165, 1167, 1169, 1170, 1171, 1176, 1178, 1179, 1180, 1182, 1184, 1185, 1186, 1188, 1190, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1200, 1201, 1206, 1207, 1209, 1211, 1214, 1217, 1218, 1219, 1222, 1223, 1224, 1227, 1228, 1229, 1230, 1188, 1190, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1200, 1201, 1206, 1207, 1209, 1211, 1214, 1217, 1218, 1219, 1222, 1223, 1224, 1227, 1228, 1229, 1230, 1232, 1234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1232, 1234, 1240, 1240, 1241, 1241, 1242, 1242, 1243, 1243, 1244, 1244, 1245, 1245, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "parser.H" extern YYSTYPE* frlval; /* rules */ #line 1484 "lex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 28 "lex.L" #line 1587 "lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 1239 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 1238 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 30 "lex.L" {return ABOUT_;} YY_BREAK case 2: YY_RULE_SETUP #line 31 "lex.L" {return AIP_;} YY_BREAK case 3: YY_RULE_SETUP #line 32 "lex.L" {return ALLOC_;} YY_BREAK case 4: YY_RULE_SETUP #line 33 "lex.L" {return ALLOCGZ_;} YY_BREAK case 5: YY_RULE_SETUP #line 34 "lex.L" {return ALIGN_;} YY_BREAK case 6: YY_RULE_SETUP #line 35 "lex.L" {return ALL_;} YY_BREAK case 7: YY_RULE_SETUP #line 36 "lex.L" {return ALT_;} YY_BREAK case 8: YY_RULE_SETUP #line 37 "lex.L" {return AMPLIFIER_;} YY_BREAK case 9: YY_RULE_SETUP #line 38 "lex.L" {return ANALYSIS_;} YY_BREAK case 10: YY_RULE_SETUP #line 39 "lex.L" {return ANGLE_;} YY_BREAK case 11: YY_RULE_SETUP #line 40 "lex.L" {return ANNULUS_;} YY_BREAK case 12: YY_RULE_SETUP #line 41 "lex.L" {return APPEND_;} YY_BREAK case 13: YY_RULE_SETUP #line 42 "lex.L" {return ARCMIN_;} YY_BREAK case 14: YY_RULE_SETUP #line 43 "lex.L" {return ARCSEC_;} YY_BREAK case 15: YY_RULE_SETUP #line 44 "lex.L" {return ARRAY_;} YY_BREAK case 16: YY_RULE_SETUP #line 45 "lex.L" {return ARROW_;} YY_BREAK case 17: YY_RULE_SETUP #line 46 "lex.L" {return ASINH_;} YY_BREAK case 18: YY_RULE_SETUP #line 47 "lex.L" {return AST_;} YY_BREAK case 19: YY_RULE_SETUP #line 48 "lex.L" {return AUTO_;} YY_BREAK case 20: YY_RULE_SETUP #line 49 "lex.L" {return AUX_;} YY_BREAK case 21: YY_RULE_SETUP #line 50 "lex.L" {return AVERAGE_;} YY_BREAK case 22: YY_RULE_SETUP #line 51 "lex.L" {return B1950_;} YY_BREAK case 23: YY_RULE_SETUP #line 52 "lex.L" {return BACK_;} YY_BREAK case 24: YY_RULE_SETUP #line 53 "lex.L" {return BASE_;} YY_BREAK case 25: YY_RULE_SETUP #line 54 "lex.L" {return BBOX_;} YY_BREAK case 26: YY_RULE_SETUP #line 55 "lex.L" {return BEGIN_;} YY_BREAK case 27: YY_RULE_SETUP #line 56 "lex.L" {return BG_;} YY_BREAK case 28: YY_RULE_SETUP #line 57 "lex.L" {return BIGENDIAN_;} YY_BREAK case 29: YY_RULE_SETUP #line 58 "lex.L" {return BIGENDIAN_;} YY_BREAK case 30: YY_RULE_SETUP #line 59 "lex.L" {return BIN_;} YY_BREAK case 31: YY_RULE_SETUP #line 60 "lex.L" {return BITPIX_;} YY_BREAK case 32: YY_RULE_SETUP #line 61 "lex.L" {return BLT_;} YY_BREAK case 33: YY_RULE_SETUP #line 62 "lex.L" {return BLOCK_;} YY_BREAK case 34: YY_RULE_SETUP #line 63 "lex.L" {return BORDER_;} YY_BREAK case 35: YY_RULE_SETUP #line 64 "lex.L" {return BOX_;} YY_BREAK case 36: YY_RULE_SETUP #line 65 "lex.L" {return BOXANNULUS_;} YY_BREAK case 37: YY_RULE_SETUP #line 66 "lex.L" {return BOXCAR_;} YY_BREAK case 38: YY_RULE_SETUP #line 67 "lex.L" {return BOXCIRCLE_;} YY_BREAK case 39: YY_RULE_SETUP #line 68 "lex.L" {return BPANDA_;} YY_BREAK case 40: YY_RULE_SETUP #line 69 "lex.L" {return BUFFER_;} YY_BREAK case 41: YY_RULE_SETUP #line 70 "lex.L" {return BW_;} YY_BREAK case 42: YY_RULE_SETUP #line 71 "lex.L" {return CALLBACK_;} YY_BREAK case 43: YY_RULE_SETUP #line 72 "lex.L" {return CANVAS_;} YY_BREAK case 44: YY_RULE_SETUP #line 73 "lex.L" {return CATALOG_;} YY_BREAK case 45: YY_RULE_SETUP #line 74 "lex.L" {return CELESTRIAL_;} YY_BREAK case 46: YY_RULE_SETUP #line 75 "lex.L" {return CENTER_;} YY_BREAK case 47: YY_RULE_SETUP #line 76 "lex.L" {return CENTROID_;} YY_BREAK case 48: YY_RULE_SETUP #line 77 "lex.L" {return CHANNEL_;} YY_BREAK case 49: YY_RULE_SETUP #line 78 "lex.L" {return CIAO_;} YY_BREAK case 50: YY_RULE_SETUP #line 79 "lex.L" {return CIRCLE_;} YY_BREAK case 51: YY_RULE_SETUP #line 80 "lex.L" {return CLEAR_;} YY_BREAK case 52: YY_RULE_SETUP #line 81 "lex.L" {return CLIP_;} YY_BREAK case 53: YY_RULE_SETUP #line 82 "lex.L" {return COLOR_;} YY_BREAK case 54: YY_RULE_SETUP #line 83 "lex.L" {return COLORBAR_;} YY_BREAK case 55: YY_RULE_SETUP #line 84 "lex.L" {return COLORMAP_;} YY_BREAK case 56: YY_RULE_SETUP #line 85 "lex.L" {return COLORSCALE_;} YY_BREAK case 57: YY_RULE_SETUP #line 86 "lex.L" {return COLORSPACE_;} YY_BREAK case 58: YY_RULE_SETUP #line 87 "lex.L" {return COLS_;} YY_BREAK case 59: YY_RULE_SETUP #line 88 "lex.L" {return COLUMN_;} YY_BREAK case 60: YY_RULE_SETUP #line 89 "lex.L" {return COMMAND_;} YY_BREAK case 61: YY_RULE_SETUP #line 90 "lex.L" {return COMPASS_;} YY_BREAK case 62: YY_RULE_SETUP #line 91 "lex.L" {return COMPOSITE_;} YY_BREAK case 63: YY_RULE_SETUP #line 92 "lex.L" {return COMPRESS_;} YY_BREAK case 64: YY_RULE_SETUP #line 93 "lex.L" {return CONTOUR_;} YY_BREAK case 65: YY_RULE_SETUP #line 94 "lex.L" {return CONTRAST_;} YY_BREAK case 66: YY_RULE_SETUP #line 95 "lex.L" {return COORDINATES_;} YY_BREAK case 67: YY_RULE_SETUP #line 96 "lex.L" {return COPY_;} YY_BREAK case 68: YY_RULE_SETUP #line 97 "lex.L" {return COUNT_;} YY_BREAK case 69: YY_RULE_SETUP #line 98 "lex.L" {return CROP_;} YY_BREAK case 70: YY_RULE_SETUP #line 99 "lex.L" {return CROSS_;} YY_BREAK case 71: YY_RULE_SETUP #line 100 "lex.L" {return CPANDA_;} YY_BREAK case 72: YY_RULE_SETUP #line 101 "lex.L" {return CREATE_;} YY_BREAK case 73: YY_RULE_SETUP #line 102 "lex.L" {return CROSSHAIR_;} YY_BREAK case 74: YY_RULE_SETUP #line 103 "lex.L" {return CUBE_;} YY_BREAK case 75: YY_RULE_SETUP #line 104 "lex.L" {return CURSOR_;} YY_BREAK case 76: YY_RULE_SETUP #line 105 "lex.L" {return CUT_;} YY_BREAK case 77: YY_RULE_SETUP #line 106 "lex.L" {return CMYK_;} YY_BREAK case 78: YY_RULE_SETUP #line 107 "lex.L" {return DASH_;} YY_BREAK case 79: YY_RULE_SETUP #line 108 "lex.L" {return DASHLIST_;} YY_BREAK case 80: YY_RULE_SETUP #line 109 "lex.L" {return DATA_;} YY_BREAK case 81: YY_RULE_SETUP #line 110 "lex.L" {return DATAMIN_;} YY_BREAK case 82: YY_RULE_SETUP #line 111 "lex.L" {return DATASEC_;} YY_BREAK case 83: YY_RULE_SETUP #line 112 "lex.L" {return DEBUG_;} YY_BREAK case 84: YY_RULE_SETUP #line 113 "lex.L" {return DEGREES_;} YY_BREAK case 85: YY_RULE_SETUP #line 114 "lex.L" {return DEFAULT_;} YY_BREAK case 86: YY_RULE_SETUP #line 115 "lex.L" {return DELETE_;} YY_BREAK case 87: YY_RULE_SETUP #line 116 "lex.L" {return DEPTH_;} YY_BREAK case 88: YY_RULE_SETUP #line 117 "lex.L" {return DETECTOR_;} YY_BREAK case 89: YY_RULE_SETUP #line 118 "lex.L" {return DIAMOND_;} YY_BREAK case 90: YY_RULE_SETUP #line 119 "lex.L" {return DIM_;} YY_BREAK case 91: YY_RULE_SETUP #line 120 "lex.L" {return DS9_;} YY_BREAK case 92: YY_RULE_SETUP #line 121 "lex.L" {return ECLIPTIC_;} YY_BREAK case 93: YY_RULE_SETUP #line 122 "lex.L" {return ELLIPSE_;} YY_BREAK case 94: YY_RULE_SETUP #line 123 "lex.L" {return ELLIPSEANNULUS_;} YY_BREAK case 95: YY_RULE_SETUP #line 124 "lex.L" {return EDIT_;} YY_BREAK case 96: YY_RULE_SETUP #line 125 "lex.L" {return END_;} YY_BREAK case 97: YY_RULE_SETUP #line 126 "lex.L" {return EPANDA_;} YY_BREAK case 98: YY_RULE_SETUP #line 127 "lex.L" {return EQUATORIAL_;} YY_BREAK case 99: YY_RULE_SETUP #line 128 "lex.L" {return ERASE_;} YY_BREAK case 100: YY_RULE_SETUP #line 129 "lex.L" {return EXT_;} YY_BREAK case 101: YY_RULE_SETUP #line 130 "lex.L" {return FACTOR_;} YY_BREAK case 102: YY_RULE_SETUP #line 131 "lex.L" {return FALSE_;} YY_BREAK case 103: YY_RULE_SETUP #line 132 "lex.L" {return FILE_;} YY_BREAK case 104: YY_RULE_SETUP #line 133 "lex.L" {return FILTER_;} YY_BREAK case 105: YY_RULE_SETUP #line 134 "lex.L" {return FIT_;} YY_BREAK case 106: YY_RULE_SETUP #line 135 "lex.L" {return FITS_;} YY_BREAK case 107: YY_RULE_SETUP #line 136 "lex.L" {return FITSY_;} YY_BREAK case 108: YY_RULE_SETUP #line 137 "lex.L" {return FIXED_;} YY_BREAK case 109: YY_RULE_SETUP #line 138 "lex.L" {return FK4_;} YY_BREAK case 110: YY_RULE_SETUP #line 139 "lex.L" {return FK4_NO_E_;} YY_BREAK case 111: YY_RULE_SETUP #line 140 "lex.L" {return FK5_;} YY_BREAK case 112: YY_RULE_SETUP #line 141 "lex.L" {return FONT_;} YY_BREAK case 113: YY_RULE_SETUP #line 142 "lex.L" {return FROM_;} YY_BREAK case 114: YY_RULE_SETUP #line 143 "lex.L" {return FRONT_;} YY_BREAK case 115: YY_RULE_SETUP #line 144 "lex.L" {return FULL_;} YY_BREAK case 116: YY_RULE_SETUP #line 145 "lex.L" {return FUNCTION_;} YY_BREAK case 117: YY_RULE_SETUP #line 146 "lex.L" {return GALACTIC_;} YY_BREAK case 118: YY_RULE_SETUP #line 147 "lex.L" {return GAUSSIAN_;} YY_BREAK case 119: YY_RULE_SETUP #line 148 "lex.L" {return GET_;} YY_BREAK case 120: YY_RULE_SETUP #line 149 "lex.L" {return GLOBAL_;} YY_BREAK case 121: YY_RULE_SETUP #line 150 "lex.L" {return GRAPHICS_;} YY_BREAK case 122: YY_RULE_SETUP #line 151 "lex.L" {return GRAY_;} YY_BREAK case 123: YY_RULE_SETUP #line 152 "lex.L" {return GRID_;} YY_BREAK case 124: YY_RULE_SETUP #line 153 "lex.L" {return GZ_;} YY_BREAK case 125: YY_RULE_SETUP #line 154 "lex.L" {return HANDLE_;} YY_BREAK case 126: YY_RULE_SETUP #line 155 "lex.L" {return HAS_;} YY_BREAK case 127: YY_RULE_SETUP #line 156 "lex.L" {return HEAD_;} YY_BREAK case 128: YY_RULE_SETUP #line 157 "lex.L" {return HEADER_;} YY_BREAK case 129: YY_RULE_SETUP #line 158 "lex.L" {return HEIGHT_;} YY_BREAK case 130: YY_RULE_SETUP #line 159 "lex.L" {return HELIOECLIPTIC_;} YY_BREAK case 131: YY_RULE_SETUP #line 160 "lex.L" {return HIDE_;} YY_BREAK case 132: YY_RULE_SETUP #line 161 "lex.L" {return HIGH_;} YY_BREAK case 133: YY_RULE_SETUP #line 162 "lex.L" {return HIGHLITE_;} YY_BREAK case 134: YY_RULE_SETUP #line 163 "lex.L" {return HISTEQU_;} YY_BREAK case 135: YY_RULE_SETUP #line 164 "lex.L" {return HISTOGRAM_;} YY_BREAK case 136: YY_RULE_SETUP #line 165 "lex.L" {return HORIZONTAL_;} YY_BREAK case 137: YY_RULE_SETUP #line 166 "lex.L" {return ICRS_;} YY_BREAK case 138: YY_RULE_SETUP #line 167 "lex.L" {return ID_;} YY_BREAK case 139: YY_RULE_SETUP #line 168 "lex.L" {return IIS_;} YY_BREAK case 140: YY_RULE_SETUP #line 169 "lex.L" {return IMAGE_;} YY_BREAK case 141: YY_RULE_SETUP #line 170 "lex.L" {return INCLUDE_;} YY_BREAK case 142: YY_RULE_SETUP #line 171 "lex.L" {return INCR_;} YY_BREAK case 143: YY_RULE_SETUP #line 172 "lex.L" {return INFO_;} YY_BREAK case 144: YY_RULE_SETUP #line 173 "lex.L" {return INTEGER_;} YY_BREAK case 145: YY_RULE_SETUP #line 174 "lex.L" {return ITERATION_;} YY_BREAK case 146: YY_RULE_SETUP #line 175 "lex.L" {return IRAF_;} YY_BREAK case 147: YY_RULE_SETUP #line 176 "lex.L" {return IRAFMIN_;} YY_BREAK case 148: YY_RULE_SETUP #line 177 "lex.L" {return J2000_;} YY_BREAK case 149: YY_RULE_SETUP #line 178 "lex.L" {return KEY_;} YY_BREAK case 150: YY_RULE_SETUP #line 179 "lex.L" {return KEYWORD_;} YY_BREAK case 151: YY_RULE_SETUP #line 180 "lex.L" {return LABEL_;} YY_BREAK case 152: YY_RULE_SETUP #line 181 "lex.L" {return LENGTH_;} YY_BREAK case 153: YY_RULE_SETUP #line 182 "lex.L" {return LEVEL_;} YY_BREAK case 154: YY_RULE_SETUP #line 183 "lex.L" {return LITTLEENDIAN_;} YY_BREAK case 155: YY_RULE_SETUP #line 184 "lex.L" {return LITTLEENDIAN_;} YY_BREAK case 156: YY_RULE_SETUP #line 185 "lex.L" {return LINE_;} YY_BREAK case 157: YY_RULE_SETUP #line 186 "lex.L" {return LINEAR_;} YY_BREAK case 158: YY_RULE_SETUP #line 187 "lex.L" {return LIST_;} YY_BREAK case 159: YY_RULE_SETUP #line 188 "lex.L" {return LOAD_;} YY_BREAK case 160: YY_RULE_SETUP #line 189 "lex.L" {return LOCAL_;} YY_BREAK case 161: YY_RULE_SETUP #line 190 "lex.L" {return LOG_;} YY_BREAK case 162: YY_RULE_SETUP #line 191 "lex.L" {return LOW_;} YY_BREAK case 163: YY_RULE_SETUP #line 192 "lex.L" {return MACOSX_;} YY_BREAK case 164: YY_RULE_SETUP #line 193 "lex.L" {return MAGNIFIER_;} YY_BREAK case 165: YY_RULE_SETUP #line 194 "lex.L" {return MATCH_;} YY_BREAK case 166: YY_RULE_SETUP #line 195 "lex.L" {return MAP_;} YY_BREAK case 167: YY_RULE_SETUP #line 196 "lex.L" {return MARK_;} YY_BREAK case 168: YY_RULE_SETUP #line 197 "lex.L" {return MARKER_;} YY_BREAK case 169: YY_RULE_SETUP #line 198 "lex.L" {return MASK_;} YY_BREAK case 170: YY_RULE_SETUP #line 199 "lex.L" {return MESSAGE_;} YY_BREAK case 171: YY_RULE_SETUP #line 200 "lex.L" {return METHOD_;} YY_BREAK case 172: YY_RULE_SETUP #line 201 "lex.L" {return MINMAX_;} YY_BREAK case 173: YY_RULE_SETUP #line 202 "lex.L" {return MIP_;} YY_BREAK case 174: YY_RULE_SETUP #line 203 "lex.L" {return MMAP_;} YY_BREAK case 175: YY_RULE_SETUP #line 204 "lex.L" {return MMAPINCR_;} YY_BREAK case 176: YY_RULE_SETUP #line 205 "lex.L" {return MODE_;} YY_BREAK case 177: YY_RULE_SETUP #line 206 "lex.L" {return MOSAIC_;} YY_BREAK case 178: YY_RULE_SETUP #line 207 "lex.L" {return MOTION_;} YY_BREAK case 179: YY_RULE_SETUP #line 208 "lex.L" {return MOVE_;} YY_BREAK case 180: YY_RULE_SETUP #line 209 "lex.L" {return NAME_;} YY_BREAK case 181: YY_RULE_SETUP #line 210 "lex.L" {return NAN_;} YY_BREAK case 182: YY_RULE_SETUP #line 211 "lex.L" {return NATIVE_;} YY_BREAK case 183: YY_RULE_SETUP #line 212 "lex.L" {return NAXES_;} YY_BREAK case 184: YY_RULE_SETUP #line 213 "lex.L" {return NEW_;} YY_BREAK case 185: YY_RULE_SETUP #line 214 "lex.L" {return NEXT_;} YY_BREAK case 186: YY_RULE_SETUP #line 215 "lex.L" {return NO_;} YY_BREAK case 187: YY_RULE_SETUP #line 216 "lex.L" {return NONE_;} YY_BREAK case 188: YY_RULE_SETUP #line 217 "lex.L" {return NOW_;} YY_BREAK case 189: YY_RULE_SETUP #line 218 "lex.L" {return NRRD_;} YY_BREAK case 190: YY_RULE_SETUP #line 219 "lex.L" {return NUMBER_;} YY_BREAK case 191: YY_RULE_SETUP #line 220 "lex.L" {return OBJECT_;} YY_BREAK case 192: YY_RULE_SETUP #line 221 "lex.L" {return OFF_;} YY_BREAK case 193: YY_RULE_SETUP #line 222 "lex.L" {return ON_;} YY_BREAK case 194: YY_RULE_SETUP #line 223 "lex.L" {return ONLY_;} YY_BREAK case 195: YY_RULE_SETUP #line 224 "lex.L" {return OPTION_;} YY_BREAK case 196: YY_RULE_SETUP #line 225 "lex.L" {return ORIENT_;} YY_BREAK case 197: YY_RULE_SETUP #line 226 "lex.L" {return PAN_;} YY_BREAK case 198: YY_RULE_SETUP #line 227 "lex.L" {return CPANDA_;} YY_BREAK case 199: YY_RULE_SETUP #line 228 "lex.L" {return PANNER_;} YY_BREAK case 200: YY_RULE_SETUP #line 229 "lex.L" {return PARAM_;} YY_BREAK case 201: YY_RULE_SETUP #line 230 "lex.L" {return PARSER_;} YY_BREAK case 202: YY_RULE_SETUP #line 231 "lex.L" {return PASTE_;} YY_BREAK case 203: YY_RULE_SETUP #line 232 "lex.L" {return PERF_;} YY_BREAK case 204: YY_RULE_SETUP #line 233 "lex.L" {return PHOTO_;} YY_BREAK case 205: YY_RULE_SETUP #line 234 "lex.L" {return PHYSICAL_;} YY_BREAK case 206: YY_RULE_SETUP #line 235 "lex.L" {return PIXEL_;} YY_BREAK case 207: YY_RULE_SETUP #line 236 "lex.L" {return PLOT2D_;} YY_BREAK case 208: YY_RULE_SETUP #line 237 "lex.L" {return PLOT3D_;} YY_BREAK case 209: YY_RULE_SETUP #line 238 "lex.L" {return POINT_;} YY_BREAK case 210: YY_RULE_SETUP #line 239 "lex.L" {return POINTER_;} YY_BREAK case 211: YY_RULE_SETUP #line 240 "lex.L" {return POLYGON_;} YY_BREAK case 212: YY_RULE_SETUP #line 241 "lex.L" {return POSTSCRIPT_;} YY_BREAK case 213: YY_RULE_SETUP #line 242 "lex.L" {return POW_;} YY_BREAK case 214: YY_RULE_SETUP #line 243 "lex.L" {return PRINT_;} YY_BREAK case 215: YY_RULE_SETUP #line 244 "lex.L" {return PRESERVE_;} YY_BREAK case 216: YY_RULE_SETUP #line 245 "lex.L" {return PROJECTION_;} YY_BREAK case 217: YY_RULE_SETUP #line 246 "lex.L" {return PROPERTY_;} YY_BREAK case 218: YY_RULE_SETUP #line 247 "lex.L" {return PROS_;} YY_BREAK case 219: YY_RULE_SETUP #line 248 "lex.L" {return PUBLICATION_;} YY_BREAK case 220: YY_RULE_SETUP #line 249 "lex.L" {return RADIAL_;} YY_BREAK case 221: YY_RULE_SETUP #line 250 "lex.L" {return RADIUS_;} YY_BREAK case 222: YY_RULE_SETUP #line 251 "lex.L" {return REGION_;} YY_BREAK case 223: YY_RULE_SETUP #line 252 "lex.L" {return REPLACE_;} YY_BREAK case 224: YY_RULE_SETUP #line 253 "lex.L" {return RESAMPLE_;} YY_BREAK case 225: YY_RULE_SETUP #line 254 "lex.L" {return RESET_;} YY_BREAK case 226: YY_RULE_SETUP #line 255 "lex.L" {return RESOLUTION_;} YY_BREAK case 227: YY_RULE_SETUP #line 256 "lex.L" {return RGB_;} YY_BREAK case 228: YY_RULE_SETUP #line 257 "lex.L" {return ROOT_;} YY_BREAK case 229: YY_RULE_SETUP #line 258 "lex.L" {return ROTATE_;} YY_BREAK case 230: YY_RULE_SETUP #line 259 "lex.L" {return RULER_;} YY_BREAK case 231: YY_RULE_SETUP #line 260 "lex.L" {return SAMPLE_;} YY_BREAK case 232: YY_RULE_SETUP #line 261 "lex.L" {return SAOIMAGE_;} YY_BREAK case 233: YY_RULE_SETUP #line 262 "lex.L" {return SAOTNG_;} YY_BREAK case 234: YY_RULE_SETUP #line 263 "lex.L" {return SAVE_;} YY_BREAK case 235: YY_RULE_SETUP #line 264 "lex.L" {return SCALE_;} YY_BREAK case 236: YY_RULE_SETUP #line 265 "lex.L" {return SCAN_;} YY_BREAK case 237: YY_RULE_SETUP #line 266 "lex.L" {return SCIENTIFIC_;} YY_BREAK case 238: YY_RULE_SETUP #line 267 "lex.L" {return SCOPE_;} YY_BREAK case 239: YY_RULE_SETUP #line 268 "lex.L" {return SEGMENT_;} YY_BREAK case 240: YY_RULE_SETUP #line 269 "lex.L" {return SELECT_;} YY_BREAK case 241: YY_RULE_SETUP #line 270 "lex.L" {return SET_;} YY_BREAK case 242: YY_RULE_SETUP #line 271 "lex.L" {return SEXAGESIMAL_;} YY_BREAK case 243: YY_RULE_SETUP #line 272 "lex.L" {return SHAPE_;} YY_BREAK case 244: YY_RULE_SETUP #line 273 "lex.L" {return SHARED_;} YY_BREAK case 245: YY_RULE_SETUP #line 274 "lex.L" {return SHIFT_;} YY_BREAK case 246: YY_RULE_SETUP #line 275 "lex.L" {return SHMID_;} YY_BREAK case 247: YY_RULE_SETUP #line 276 "lex.L" {return SHOW_;} YY_BREAK case 248: YY_RULE_SETUP #line 277 "lex.L" {return SINH_;} YY_BREAK case 249: YY_RULE_SETUP #line 278 "lex.L" {return SIZE_;} YY_BREAK case 250: YY_RULE_SETUP #line 279 "lex.L" {return SLICE_;} YY_BREAK case 251: YY_RULE_SETUP #line 280 "lex.L" {return SMMAP_;} YY_BREAK case 252: YY_RULE_SETUP #line 281 "lex.L" {return SMOOTH_;} YY_BREAK case 253: YY_RULE_SETUP #line 282 "lex.L" {return SOCKET_;} YY_BREAK case 254: YY_RULE_SETUP #line 283 "lex.L" {return SOCKETGZ_;} YY_BREAK case 255: YY_RULE_SETUP #line 284 "lex.L" {return SOURCE_;} YY_BREAK case 256: YY_RULE_SETUP #line 285 "lex.L" {return SQRT_;} YY_BREAK case 257: YY_RULE_SETUP #line 286 "lex.L" {return SQUARED_;} YY_BREAK case 258: YY_RULE_SETUP #line 287 "lex.L" {return SSHARED_;} YY_BREAK case 259: YY_RULE_SETUP #line 288 "lex.L" {return STATS_;} YY_BREAK case 260: YY_RULE_SETUP #line 289 "lex.L" {return STATUS_;} YY_BREAK case 261: YY_RULE_SETUP #line 290 "lex.L" {return SUM_;} YY_BREAK case 262: YY_RULE_SETUP #line 291 "lex.L" {return SUPERGALACTIC_;} YY_BREAK case 263: YY_RULE_SETUP #line 292 "lex.L" {return SYSTEM_;} YY_BREAK case 264: YY_RULE_SETUP #line 293 "lex.L" {return TABLE_;} YY_BREAK case 265: YY_RULE_SETUP #line 294 "lex.L" {return TAG_;} YY_BREAK case 266: YY_RULE_SETUP #line 295 "lex.L" {return TEMPLATE_;} YY_BREAK case 267: YY_RULE_SETUP #line 296 "lex.L" {return TEXT_;} YY_BREAK case 268: YY_RULE_SETUP #line 297 "lex.L" {return THREADS_;} YY_BREAK case 269: YY_RULE_SETUP #line 298 "lex.L" {return THREED_;} YY_BREAK case 270: YY_RULE_SETUP #line 299 "lex.L" {return THRESHOLD_;} YY_BREAK case 271: YY_RULE_SETUP #line 300 "lex.L" {return THICK_;} YY_BREAK case 272: YY_RULE_SETUP #line 301 "lex.L" {return TRANSPARENCY_;} YY_BREAK case 273: YY_RULE_SETUP #line 302 "lex.L" {return TO_;} YY_BREAK case 274: YY_RULE_SETUP #line 303 "lex.L" {return TOGGLE_;} YY_BREAK case 275: YY_RULE_SETUP #line 304 "lex.L" {return TOPHAT_;} YY_BREAK case 276: YY_RULE_SETUP #line 305 "lex.L" {return TRUE_;} YY_BREAK case 277: YY_RULE_SETUP #line 306 "lex.L" {return TYPE_;} YY_BREAK case 278: YY_RULE_SETUP #line 307 "lex.L" {return UNDO_;} YY_BREAK case 279: YY_RULE_SETUP #line 308 "lex.L" {return UNLOAD_;} YY_BREAK case 280: YY_RULE_SETUP #line 309 "lex.L" {return UNHIGHLITE_;} YY_BREAK case 281: YY_RULE_SETUP #line 310 "lex.L" {return UNSELECT_;} YY_BREAK case 282: YY_RULE_SETUP #line 311 "lex.L" {return UPDATE_;} YY_BREAK case 283: YY_RULE_SETUP #line 312 "lex.L" {return USER_;} YY_BREAK case 284: YY_RULE_SETUP #line 313 "lex.L" {return VALUE_;} YY_BREAK case 285: YY_RULE_SETUP #line 314 "lex.L" {return VAR_;} YY_BREAK case 286: YY_RULE_SETUP #line 315 "lex.L" {return VIEW_;} YY_BREAK case 287: YY_RULE_SETUP #line 316 "lex.L" {return VECTOR_;} YY_BREAK case 288: YY_RULE_SETUP #line 317 "lex.L" {return VERSION_;} YY_BREAK case 289: YY_RULE_SETUP #line 318 "lex.L" {return VERTEX_;} YY_BREAK case 290: YY_RULE_SETUP #line 319 "lex.L" {return VERTICAL_;} YY_BREAK case 291: YY_RULE_SETUP #line 320 "lex.L" {return WARP_;} YY_BREAK case 292: YY_RULE_SETUP #line 321 "lex.L" {return WCS_;} YY_BREAK case 293: YY_RULE_SETUP #line 322 "lex.L" {return WCSA_;} YY_BREAK case 294: YY_RULE_SETUP #line 323 "lex.L" {return WCSB_;} YY_BREAK case 295: YY_RULE_SETUP #line 324 "lex.L" {return WCSC_;} YY_BREAK case 296: YY_RULE_SETUP #line 325 "lex.L" {return WCSD_;} YY_BREAK case 297: YY_RULE_SETUP #line 326 "lex.L" {return WCSE_;} YY_BREAK case 298: YY_RULE_SETUP #line 327 "lex.L" {return WCSF_;} YY_BREAK case 299: YY_RULE_SETUP #line 328 "lex.L" {return WCSG_;} YY_BREAK case 300: YY_RULE_SETUP #line 329 "lex.L" {return WCSH_;} YY_BREAK case 301: YY_RULE_SETUP #line 330 "lex.L" {return WCSI_;} YY_BREAK case 302: YY_RULE_SETUP #line 331 "lex.L" {return WCSJ_;} YY_BREAK case 303: YY_RULE_SETUP #line 332 "lex.L" {return WCSK_;} YY_BREAK case 304: YY_RULE_SETUP #line 333 "lex.L" {return WCSL_;} YY_BREAK case 305: YY_RULE_SETUP #line 334 "lex.L" {return WCSM_;} YY_BREAK case 306: YY_RULE_SETUP #line 335 "lex.L" {return WCSN_;} YY_BREAK case 307: YY_RULE_SETUP #line 336 "lex.L" {return WCSO_;} YY_BREAK case 308: YY_RULE_SETUP #line 337 "lex.L" {return WCSP_;} YY_BREAK case 309: YY_RULE_SETUP #line 338 "lex.L" {return WCSQ_;} YY_BREAK case 310: YY_RULE_SETUP #line 339 "lex.L" {return WCSR_;} YY_BREAK case 311: YY_RULE_SETUP #line 340 "lex.L" {return WCSS_;} YY_BREAK case 312: YY_RULE_SETUP #line 341 "lex.L" {return WCST_;} YY_BREAK case 313: YY_RULE_SETUP #line 342 "lex.L" {return WCSU_;} YY_BREAK case 314: YY_RULE_SETUP #line 343 "lex.L" {return WCSV_;} YY_BREAK case 315: YY_RULE_SETUP #line 344 "lex.L" {return WCSW_;} YY_BREAK case 316: YY_RULE_SETUP #line 345 "lex.L" {return WCSX_;} YY_BREAK case 317: YY_RULE_SETUP #line 346 "lex.L" {return WCSY_;} YY_BREAK case 318: YY_RULE_SETUP #line 347 "lex.L" {return WCSZ_;} YY_BREAK case 319: YY_RULE_SETUP #line 348 "lex.L" {return WCS0_;} YY_BREAK case 320: YY_RULE_SETUP #line 349 "lex.L" {return WFPC2_;} YY_BREAK case 321: YY_RULE_SETUP #line 350 "lex.L" {return WIDTH_;} YY_BREAK case 322: YY_RULE_SETUP #line 351 "lex.L" {return WIN32_;} YY_BREAK case 323: YY_RULE_SETUP #line 352 "lex.L" {return XML_;} YY_BREAK case 324: YY_RULE_SETUP #line 353 "lex.L" {return XY_;} YY_BREAK case 325: YY_RULE_SETUP #line 354 "lex.L" {return YES_;} YY_BREAK case 326: YY_RULE_SETUP #line 355 "lex.L" {return ZMAX_;} YY_BREAK case 327: YY_RULE_SETUP #line 356 "lex.L" {return ZSCALE_;} YY_BREAK case 328: YY_RULE_SETUP #line 357 "lex.L" {return ZOOM_;} YY_BREAK case 329: YY_RULE_SETUP #line 359 "lex.L" { // Integer frlval->integer = atoi(yytext); return INT; } YY_BREAK case 330: #line 365 "lex.L" case 331: YY_RULE_SETUP #line 365 "lex.L" { // Real Number frlval->real = atof(yytext); return REAL; } YY_BREAK case 332: YY_RULE_SETUP #line 370 "lex.L" { // Pointer frlval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } YY_BREAK case 333: #line 376 "lex.L" case 334: YY_RULE_SETUP #line 376 "lex.L" { // degrees yytext[yyleng-1] = '\0'; frlval->real = atof(yytext); return ANGDEGREE; } YY_BREAK case 335: #line 383 "lex.L" case 336: YY_RULE_SETUP #line 383 "lex.L" { // radians yytext[yyleng-1] = '\0'; frlval->real = atof(yytext); return ANGRADIAN; } YY_BREAK case 337: #line 390 "lex.L" case 338: YY_RULE_SETUP #line 390 "lex.L" { // sexagesimal int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return SEXSTR; } YY_BREAK case 339: #line 398 "lex.L" case 340: YY_RULE_SETUP #line 398 "lex.L" { // HMS int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return HMSSTR; } YY_BREAK case 341: #line 406 "lex.L" case 342: YY_RULE_SETUP #line 406 "lex.L" { // DMS int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return DMSSTR; } YY_BREAK case 343: /* rule 343 can match eol */ #line 414 "lex.L" case 344: /* rule 344 can match eol */ YY_RULE_SETUP #line 414 "lex.L" { // Quoted String int ll = (yyleng-2)<(FRBUFSIZE-1) ? (yyleng-2):(FRBUFSIZE-1); strncpy(frlval->str,yytext+1,ll); // skip the " " frlval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 345: /* rule 345 can match eol */ YY_RULE_SETUP #line 421 "lex.L" { // Quoted String int ll = (yyleng-2)<(FRBUFSIZE-1) ? (yyleng-2):(FRBUFSIZE-1); strncpy(frlval->str,yytext+1,ll); // skip the '{' frlval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 346: YY_RULE_SETUP #line 428 "lex.L" { // General String-- at least 2 printable chars int ll = yyleng <(FRBUFSIZE-1) ? yyleng:(FRBUFSIZE-1); strncpy(frlval->str,yytext,ll); frlval->str[ll] = '\0'; return STRING; } YY_BREAK case 347: YY_RULE_SETUP #line 435 "lex.L" { // White Spaces } YY_BREAK case 348: YY_RULE_SETUP #line 438 "lex.L" { // Else, return the char return toupper(yytext[0]); } YY_BREAK case 349: YY_RULE_SETUP #line 442 "lex.L" ECHO; YY_BREAK #line 3443 "lex.C" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; frfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); frfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ frrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) frrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 1239 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 1239 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 1238); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) fralloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) fralloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) frfree((void *) b->yy_ch_buf ); frfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)fralloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)frrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) fralloc(new_size ); else (yy_start_stack) = (int *) frrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *fralloc (yy_size_t size ) { return (void *) malloc( size ); } void *frrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void frfree (void * ptr ) { free( (char *) ptr ); /* see frrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 442 "lex.L" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/composite.h��������������������������������������������������������������������0000644�0001750�0001750�00000003401�11766434541�015502� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __composite_h__ #define __composite_h__ #include "marker.h" #include "list.h" class Composite : public Marker { private: List<Marker> members; int global; void renderX(Drawable, Coord::InternalSystem, RenderMode) {} void renderPS(int mode) {} #ifdef _MACOSX void renderMACOSX() {} #endif #ifdef _WIN32 void renderWIN32() {} #endif protected: void updateHandles(); public: Composite(const Composite&); Composite(Base* p, const Vector& ctr, double ang, int gl, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb); Marker* dup() {return new Composite(*this);} void x11(Drawable, Coord::InternalSystem, int, RenderMode, HandleMode); void ps(int,int); #ifdef _MACOSX void macosx(int); #endif #ifdef _WIN32 void win32(int); #endif void updateCoords(const Matrix&); int isIn(const Vector& v); void append(Marker*); Marker* extract(); void setGlobal(int w) {global = w ? 1 : 0;} int getGlobal() {return global;} void list(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int, int); void listXML(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat) {} void listCiao(ostream&, Coord::CoordSystem, int); void listSAOtng(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void listSAOimage(ostream&, int); void listPros(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); void listXY(ostream&, Coord::CoordSystem, Coord::SkyFrame, Coord::SkyFormat, int); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/saoparser.C��������������������������������������������������������������������0000644�0001750�0001750�00000161724�11727715200�015436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse saoparse #define yylex saolex #define yyerror saoerror #define yylval saolval #define yychar saochar #define yydebug saodebug #define yynerrs saonerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, EOF_ = 261, ANNULUS_ = 262, BOX_ = 263, CIRCLE_ = 264, DEBUG_ = 265, ELLIPSE_ = 266, N_ = 267, OFF_ = 268, ON_ = 269, POINT_ = 270, POLYGON_ = 271, ROTBOX_ = 272, VERSION_ = 273 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define EOF_ 261 #define ANNULUS_ 262 #define BOX_ 263 #define CIRCLE_ 264 #define DEBUG_ 265 #define ELLIPSE_ 266 #define N_ 267 #define OFF_ 268 #define ON_ 269 #define POINT_ 270 #define POLYGON_ 271 #define ROTBOX_ 272 #define VERSION_ 273 /* Copy the first part of user declarations. */ #line 10 "saoparser.Y" #define YYDEBUG 1 #define FITSPTR (fr->findFits()) #define DISCARD_(x) {yyclearin; saoDiscard(x);} #include <math.h> #include <string.h> #include <iostream> #include "base.h" #include "fitsimage.h" #include "basemarker.h" #undef yyFlexLexer #define yyFlexLexer saoFlexLexer #include <FlexLexer.h> extern int saolex(void*, saoFlexLexer*); extern void saoerror(Base*, saoFlexLexer*, const char*); extern void saoDiscard(int); static unsigned short globalProps; static unsigned short localProps; static char *color = "green"; static int dash[] = {8,3}; static char *font = "helvetica 10 normal roman"; static char *text = ""; static char localComment[80]; static List<Vertex> polylist; static List<Tag> taglist; static List<CallBack> cblist; static double aAnnuli[MAXANNULI]; static Vector aVector[MAXANNULI]; static int aNum; static int aStatus; static Vector aCenter; static double aAngle; static unsigned short aProps; static char aComment[80]; static void setProps(unsigned short* props, unsigned short prop, int value); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 59 "saoparser.Y" { #define SAOBUFSIZE 2048 double real; int integer; char str[SAOBUFSIZE]; double vector[3]; } /* Line 193 of yacc.c. */ #line 197 "saoparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 210 "saoparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 160 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 30 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 31 /* YYNRULES -- Number of rules. */ #define YYNRULES 59 /* YYNRULES -- Number of states. */ #define YYNSTATES 139 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 273 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 28, 2, 29, 2, 2, 27, 2, 22, 23, 2, 25, 21, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 7, 11, 14, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 54, 56, 60, 64, 68, 69, 70, 71, 73, 75, 83, 93, 94, 107, 119, 129, 148, 158, 168, 187, 193, 194, 201, 205, 207, 209, 213, 215, 217, 218, 219, 223, 225, 226 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 31, 0, -1, 46, 32, 56, -1, 32, 33, 34, -1, 33, 34, -1, -1, 10, 36, -1, 18, -1, 47, 48, 49, -1, 57, -1, 19, -1, 20, -1, 6, -1, 4, -1, 3, -1, 14, -1, 13, -1, -1, 21, -1, -1, 22, -1, -1, 23, -1, -1, 41, -1, 35, -1, 35, -1, 35, 37, 35, -1, 12, 24, 3, -1, 35, 37, 35, -1, -1, -1, -1, 25, -1, 26, -1, 9, 38, 45, 37, 42, 39, 59, -1, 7, 38, 45, 37, 42, 37, 42, 39, 59, -1, -1, 7, 38, 45, 37, 42, 37, 42, 37, 50, 54, 39, 59, -1, 7, 38, 45, 37, 42, 37, 42, 37, 44, 39, 59, -1, 11, 38, 45, 37, 43, 37, 40, 39, 59, -1, 11, 38, 45, 37, 43, 37, 40, 39, 27, 28, 11, 38, 45, 37, 43, 37, 40, 39, -1, 8, 38, 45, 37, 43, 37, 40, 39, 59, -1, 17, 38, 45, 37, 43, 37, 40, 39, 59, -1, 8, 38, 45, 37, 43, 37, 40, 39, 27, 28, 8, 38, 45, 37, 43, 37, 40, 39, -1, 15, 38, 45, 39, 59, -1, -1, 16, 51, 38, 52, 39, 59, -1, 52, 37, 53, -1, 53, -1, 45, -1, 54, 37, 55, -1, 55, -1, 42, -1, -1, -1, 29, 58, 5, -1, 56, -1, -1, 29, 60, 5, 56, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 97, 97, 100, 101, 104, 105, 106, 107, 108, 111, 112, 113, 116, 117, 120, 121, 124, 125, 128, 129, 132, 133, 136, 137, 140, 143, 146, 155, 158, 167, 175, 183, 184, 185, 188, 192, 196, 196, 205, 211, 227, 234, 250, 255, 262, 266, 266, 271, 272, 275, 278, 279, 282, 286, 313, 313, 316, 317, 317 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "STRING", "EOF_", "ANNULUS_", "BOX_", "CIRCLE_", "DEBUG_", "ELLIPSE_", "N_", "OFF_", "ON_", "POINT_", "POLYGON_", "ROTBOX_", "VERSION_", "'\\n'", "';'", "','", "'('", "')'", "'='", "'+'", "'-'", "'&'", "'!'", "'#'", "$accept", "start", "commands", "command", "terminator", "numeric", "debug", "sp", "bp", "ep", "optangle", "angle", "value", "vvalue", "numberof", "coord", "initGlobal", "initLocal", "include", "shape", "@1", "@2", "polyNodes", "polyNode", "aRads", "aRad", "processAnnulus", "generalComment", "@3", "shapeComment", "@4", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 10, 59, 44, 40, 41, 61, 43, 45, 38, 33, 35 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 30, 31, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 48, 48, 49, 49, 50, 49, 49, 49, 49, 49, 49, 49, 49, 51, 49, 52, 52, 53, 54, 54, 55, 56, 58, 57, 59, 60, 59 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 3, 2, 0, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 3, 3, 3, 0, 0, 0, 1, 1, 7, 9, 0, 12, 11, 9, 18, 9, 9, 18, 5, 0, 6, 3, 1, 1, 3, 1, 1, 0, 0, 3, 1, 0, 4 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 30, 0, 31, 1, 0, 7, 55, 31, 0, 32, 9, 16, 15, 6, 0, 0, 2, 12, 10, 11, 4, 33, 34, 0, 56, 3, 19, 19, 19, 19, 19, 46, 19, 8, 20, 0, 0, 0, 0, 0, 19, 0, 14, 13, 17, 17, 17, 17, 17, 21, 0, 17, 18, 0, 0, 0, 0, 0, 22, 54, 50, 21, 49, 0, 29, 26, 17, 17, 17, 21, 17, 58, 57, 45, 0, 54, 17, 0, 0, 23, 54, 23, 0, 48, 47, 23, 21, 27, 25, 21, 24, 35, 21, 54, 21, 37, 54, 54, 54, 59, 54, 0, 21, 0, 36, 0, 42, 0, 40, 43, 0, 54, 53, 21, 52, 0, 0, 28, 39, 0, 54, 19, 19, 51, 38, 0, 0, 17, 17, 0, 0, 17, 17, 23, 23, 21, 21, 44, 41 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 1, 7, 8, 20, 44, 13, 53, 35, 59, 89, 90, 112, 68, 102, 60, 2, 9, 23, 33, 103, 40, 61, 62, 113, 114, 72, 10, 14, 73, 82 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -71 static const yytype_int16 yypact[] = { -71, 21, 119, -71, 11, -71, -71, 116, 16, 31, -71, -71, -71, -71, 22, 16, -71, -71, -71, -71, -71, -71, -71, 135, -71, -71, 9, 9, 9, 9, 9, -71, 9, -71, -71, 69, 69, 69, 69, 69, 9, 69, -71, -71, 20, 20, 20, 20, 20, 26, 69, 20, -71, 69, 69, 69, 69, 69, -71, 33, -71, 56, -71, 69, -71, -71, 20, 20, 20, 26, 20, -71, -71, -71, 69, 33, 20, 69, 69, 69, 33, 69, 61, -71, -71, 69, 137, -71, -71, 26, -71, -71, 26, -71, 26, 58, 33, -1, 3, -71, 33, 52, 26, 69, -71, 50, -71, 53, -71, -71, 79, 33, -71, 56, -71, 75, 73, -71, -71, 69, 33, 9, 9, -71, -71, 69, 69, 20, 20, 69, 69, 20, 20, 69, 69, 26, 26, -71, -71 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -71, -71, -71, 80, 71, -10, -71, -28, -27, 19, -70, -71, -40, -2, -71, -29, -71, -71, -71, -71, -71, -71, -71, 15, -71, -21, -3, -71, -71, -46, -71 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -55 static const yytype_int16 yytable[] = { 36, 37, 38, 39, 16, 41, 45, 46, 47, 48, 49, 92, 51, 50, 66, 94, 69, 54, 55, 56, 57, 3, 17, 63, 11, 12, 105, 24, 71, 84, 107, 34, 71, 74, 91, 18, 19, 86, 77, 78, 79, 52, 81, 64, 65, 67, 65, 67, 85, 58, 104, 106, 108, 67, 109, 70, 21, 22, 95, -17, -17, 76, 71, 135, 136, 118, 93, 65, 87, 88, 101, 88, 42, 43, 124, 88, 110, 52, 115, 58, 75, 116, 117, 121, 122, 119, 25, 15, 80, 83, 99, 0, 0, 65, 125, 126, 127, 128, 123, 129, 130, 0, 0, 133, 134, 96, 0, 0, 97, 65, 0, 98, 0, 100, 0, 0, -54, 0, 0, 67, 67, 111, -5, 88, 88, -5, 4, 131, 132, 4, 0, 0, 120, 0, 5, -5, -5, 5, -5, -5, -17, -17, 26, 27, 28, 6, 29, 0, 6, -17, 30, 31, 32, 0, 137, 138, 0, 0, 52, 0, 58 }; static const yytype_int16 yycheck[] = { 27, 28, 29, 30, 7, 32, 35, 36, 37, 38, 39, 81, 41, 40, 54, 85, 56, 45, 46, 47, 48, 0, 6, 51, 13, 14, 27, 5, 29, 75, 27, 22, 29, 61, 80, 19, 20, 77, 66, 67, 68, 21, 70, 53, 54, 55, 56, 57, 76, 23, 96, 97, 98, 63, 100, 57, 25, 26, 86, 3, 4, 63, 29, 133, 134, 111, 5, 77, 78, 79, 12, 81, 3, 4, 120, 85, 24, 21, 28, 23, 61, 28, 3, 8, 11, 113, 15, 7, 69, 74, 93, -1, -1, 103, 121, 122, 125, 126, 119, 127, 128, -1, -1, 131, 132, 86, -1, -1, 89, 119, -1, 92, -1, 94, -1, -1, 0, -1, -1, 129, 130, 102, 6, 133, 134, 6, 10, 129, 130, 10, -1, -1, 113, -1, 18, 19, 20, 18, 19, 20, 3, 4, 7, 8, 9, 29, 11, -1, 29, 12, 15, 16, 17, -1, 135, 136, -1, -1, 21, -1, 23 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 31, 46, 0, 10, 18, 29, 32, 33, 47, 57, 13, 14, 36, 58, 33, 56, 6, 19, 20, 34, 25, 26, 48, 5, 34, 7, 8, 9, 11, 15, 16, 17, 49, 22, 38, 38, 38, 38, 38, 51, 38, 3, 4, 35, 45, 45, 45, 45, 45, 38, 45, 21, 37, 37, 37, 37, 37, 23, 39, 45, 52, 53, 37, 35, 35, 42, 35, 43, 42, 43, 29, 56, 59, 37, 39, 43, 37, 37, 37, 39, 37, 60, 53, 59, 37, 42, 35, 35, 40, 41, 59, 40, 5, 40, 37, 39, 39, 39, 56, 39, 12, 44, 50, 59, 27, 59, 27, 59, 59, 24, 39, 42, 54, 55, 28, 28, 3, 59, 37, 39, 8, 11, 55, 59, 38, 38, 45, 45, 37, 37, 43, 43, 37, 37, 40, 40, 39, 39 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (fr, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, fr, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, saoFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; saoFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (fr); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Base* fr, saoFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, fr, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Base* fr; saoFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, fr, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Base* fr, saoFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, fr, ll) YYSTYPE *yyvsp; int yyrule; Base* fr; saoFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , fr, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, fr, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Base* fr, saoFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, fr, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Base* fr; saoFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (fr); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Base* fr, saoFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Base* fr, saoFlexLexer* ll) #else int yyparse (fr, ll) Base* fr; saoFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 7: #line 106 "saoparser.Y" {cerr << "SAOimage" << endl;;} break; case 12: #line 113 "saoparser.Y" {YYACCEPT;;} break; case 13: #line 116 "saoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 14: #line 117 "saoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 15: #line 120 "saoparser.Y" {yydebug=1;;} break; case 16: #line 121 "saoparser.Y" {yydebug=0;;} break; case 23: #line 136 "saoparser.Y" {(yyval.real) = 0;;} break; case 24: #line 137 "saoparser.Y" {(yyval.real) = (yyvsp[(1) - (1)].real);;} break; case 25: #line 140 "saoparser.Y" {(yyval.real) = degToRad((yyvsp[(1) - (1)].real));;} break; case 26: #line 143 "saoparser.Y" {(yyval.real) = FITSPTR->mapLenToRef((yyvsp[(1) - (1)].real), Coord::IMAGE);;} break; case 27: #line 147 "saoparser.Y" { Vector r = FITSPTR->mapLenToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 28: #line 155 "saoparser.Y" {(yyval.integer) = (yyvsp[(3) - (3)].integer);;} break; case 29: #line 159 "saoparser.Y" { Vector r = FITSPTR->mapToRef(Vector((yyvsp[(1) - (3)].real),(yyvsp[(3) - (3)].real)), Coord::IMAGE); (yyval.vector)[0] = r[0]; (yyval.vector)[1] = r[1]; (yyval.vector)[2] = r[2]; ;} break; case 30: #line 167 "saoparser.Y" { globalProps = Marker::SELECT | Marker::EDIT | Marker::MOVE | Marker::ROTATE | Marker::DELETE | Marker::HIGHLITE | Marker::INCLUDE | Marker::SOURCE; ;} break; case 31: #line 175 "saoparser.Y" { // reset maperr flag maperr =0; localProps = globalProps; ;} break; case 32: #line 183 "saoparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 33: #line 184 "saoparser.Y" {setProps(&localProps, Marker::INCLUDE, 1);;} break; case 34: #line 185 "saoparser.Y" {setProps(&localProps, Marker::INCLUDE, 0);;} break; case 35: #line 189 "saoparser.Y" {fr->createCircleCmd(Vector((yyvsp[(3) - (7)].vector)), (yyvsp[(5) - (7)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 36: #line 193 "saoparser.Y" {fr->createAnnulusCmd(Vector((yyvsp[(3) - (9)].vector)), (yyvsp[(5) - (9)].real),(yyvsp[(7) - (9)].real),1, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 37: #line 196 "saoparser.Y" {aNum=2;;} break; case 38: #line 198 "saoparser.Y" { aAnnuli[0] = (yyvsp[(5) - (12)].real); aAnnuli[1] = (yyvsp[(7) - (12)].real); fr->createAnnulusCmd(Vector((yyvsp[(3) - (12)].vector)), aNum,aAnnuli, color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 39: #line 206 "saoparser.Y" {fr->createAnnulusCmd(Vector((yyvsp[(3) - (11)].vector)), (yyvsp[(5) - (11)].real),(yyvsp[(7) - (11)].real),(yyvsp[(9) - (11)].integer), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 40: #line 212 "saoparser.Y" { // for ellipse annulus aStatus = 1; aCenter = Vector((yyvsp[(3) - (9)].vector)); aAngle = (yyvsp[(7) - (9)].real); aVector[0] = Vector((yyvsp[(5) - (9)].vector)); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createEllipseCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 41: #line 229 "saoparser.Y" { aStatus = 2; aVector[aNum++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 42: #line 235 "saoparser.Y" { // for box annulus aStatus = 3; aCenter = Vector((yyvsp[(3) - (9)].vector)); aAngle = (yyvsp[(7) - (9)].real); aVector[0] = Vector((yyvsp[(5) - (9)].vector)); aNum = 1; strncpy(aComment,localComment,80); aProps = localProps; fr->createBoxCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist); ;} break; case 43: #line 251 "saoparser.Y" {fr->createBoxCmd(Vector((yyvsp[(3) - (9)].vector)), Vector((yyvsp[(5) - (9)].vector)), (yyvsp[(7) - (9)].real), color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 44: #line 257 "saoparser.Y" { aStatus = 4; aVector[aNum++] = Vector((yyvsp[(5) - (18)].vector)); ;} break; case 45: #line 263 "saoparser.Y" {fr->createPointCmd(Vector((yyvsp[(3) - (5)].vector)), Point::BOXCIRCLE, POINTSIZE, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 46: #line 266 "saoparser.Y" {polylist.deleteAll();;} break; case 47: #line 267 "saoparser.Y" {fr->createPolygonCmd(polylist, color,dash,1,font,text,localProps,localComment,taglist,cblist);;} break; case 50: #line 275 "saoparser.Y" {polylist.append(new Vertex((yyvsp[(1) - (1)].vector)));;} break; case 53: #line 282 "saoparser.Y" {aAnnuli[aNum++] = (yyvsp[(1) - (1)].real);;} break; case 54: #line 286 "saoparser.Y" { switch (aStatus) { case 0: // do nothing break; case 1: // we found just an ellipse, do nothing break; case 2: // ok we have an ellipse annulus fr->markerDeleteLastCmd(); // delete the previous ellipse fr->createEllipseAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; case 3: // we found just a box, do nothing break; case 4: // ok, we have a box annulus fr->markerDeleteLastCmd(); // delete the previous box fr->createBoxAnnulusCmd(aCenter, aNum,aVector, aAngle, color,dash,1,font,text,aProps,aComment,taglist,cblist); break; } aStatus = 0; ;} break; case 55: #line 313 "saoparser.Y" {DISCARD_(1);} break; case 58: #line 317 "saoparser.Y" {DISCARD_(0);} break; case 59: #line 318 "saoparser.Y" {strncpy(localComment,(yyvsp[(3) - (4)].str),80);;} break; /* Line 1267 of yacc.c. */ #line 1813 "saoparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (fr, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (fr, ll, yymsg); } else { yyerror (fr, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, fr, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, fr, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (fr, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, fr, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, fr, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 321 "saoparser.Y" static void setProps(unsigned short* props, unsigned short prop, int value) { if (value) *props |= prop; else *props &= ~prop; } ��������������������������������������������./saods9/saotk/frame/line.C�������������������������������������������������������������������������0000644�0001750�0001750�00000017441�12057220642�014360� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "line.h" #include "fitsimage.h" Line::Line(const Line& a) : BaseLine(a) { p1Arrow = a.p1Arrow; p2Arrow = a.p2Arrow; } Line::Line(Base* p, const Vector& ptr1, const Vector& ptr2, int a1, int a2, const char* clr, int* dsh, int wth, const char* fnt, const char* txt, unsigned short prop, const char* cmt, const List<Tag>& tg, const List<CallBack>& cb) : BaseLine(p, ptr1, ptr2, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) { p1Arrow = a1; p2Arrow = a2; strcpy(type_,"line"); handle = new Vector[2]; numHandle = 2; updateBBox(); } void Line::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { GC lgc = renderXGC(mode); Vector aa = parent->mapFromRef(p1,sys); Vector bb = parent->mapFromRef(p2,sys); if (p1Arrow) { aa = modifyArrow(p2,p1,sys); renderXArrow(drawable,p2,p1,sys,lgc); } if (p2Arrow) { bb = modifyArrow(p1,p2,sys); renderXArrow(drawable,p1,p2,sys,lgc); } XDrawLine(display, drawable, lgc, aa[0], aa[1], bb[0], bb[1]); } void Line::renderPS(int mode) { renderPSGC(mode); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); if (p1Arrow) { aa = modifyArrow(p2,p1,Coord::CANVAS); renderPSArrow(p2,p1,Coord::CANVAS); } if (p2Arrow) { bb = modifyArrow(p1,p2,Coord::CANVAS); renderPSArrow(p1,p2,Coord::CANVAS); } ostringstream str; str << "newpath " << aa.TkCanvasPs(parent->canvas) << "moveto" << bb.TkCanvasPs(parent->canvas) << "lineto" << " stroke" << endl << ends; Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } #ifdef _MACOSX void Line::renderMACOSX() { renderMACOSXGC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); if (p1Arrow) { aa = modifyArrow(p2,p1,Coord::CANVAS); renderMACOSXArrow(p2,p1,Coord::CANVAS); } if (p2Arrow) { bb = modifyArrow(p1,p2,Coord::CANVAS); renderMACOSXArrow(p1,p2,Coord::CANVAS); } macosxDrawLine(aa,bb); } #endif #ifdef _WIN32 void Line::renderWIN32() { renderWIN32GC(); Vector aa = parent->mapFromRef(p1,Coord::CANVAS); Vector bb = parent->mapFromRef(p2,Coord::CANVAS); if (p1Arrow) { aa = modifyArrow(p2,p1,Coord::CANVAS); renderWIN32Arrow(p2,p1,Coord::CANVAS); } if (p2Arrow) { bb = modifyArrow(p1,p2,Coord::CANVAS); renderWIN32Arrow(p1,p2,Coord::CANVAS); } win32DrawLine(aa,bb); } #endif // Support void Line::updateHandles() { center = (p2-p1)/2 + p1; angle = (p2-p1).angle(); // generate handles in Coord::CANVAS coords handle[0] = parent->mapFromRef(p1,Coord::CANVAS); handle[1] = parent->mapFromRef(p2,Coord::CANVAS); } void Line::setArrows(int w1, int w2) { p1Arrow = w1 ? 1 : 0; p2Arrow = w2 ? 1 : 0; updateBBox(); } void Line::analysis(AnalysisTask mm, int which) { switch (mm) { case PLOT2D: if (!analysisPlot2d_ && which) { addCallBack(CallBack::MOVECB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::EDITCB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0], parent->options->cmdName); addCallBack(CallBack::DELETECB, analysisPlot2dCB_[1], parent->options->cmdName); } if (analysisPlot2d_ && !which) { deleteCallBack(CallBack::MOVECB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::EDITCB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0]); deleteCallBack(CallBack::DELETECB, analysisPlot2dCB_[1]); } analysisPlot2d_ = which; break; } } void Line::analysisPlot2d(char* xname, char* yname, char* xcname, char* ycname, Coord::CoordSystem sys, Coord::SkyFrame sky, Marker::AnalysisMethod method) { double* x; double* y; double* xc; double* yc; int num = parent->markerAnalysisPlot2d(this, &x, &y, &xc, &yc, p1, p2, 0, sys, sky, method); analysisPlot2dResult(xname, yname, xcname, ycname, x, y, xc, yc, num); } // list void Line::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int conj, int strip) { FitsImage* ptr = parent->findFits(sys,center); listPre(str, sys, sky, ptr, strip, 0); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; default: if (ptr->hasWCS(sys)) { if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra1[16], ra2[16]; char dec1[16], dec2[16]; { ptr->mapFromRef(p1,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra1 >> dec1; } { ptr->mapFromRef(p2,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra2 >> dec2; } str << type_ << '(' << ra1 << ',' << dec1 << ',' << ra2 << ',' << dec2 << ')'; } break; } } else { Vector v1 = ptr->mapFromRef(p1,sys); Vector v2 = ptr->mapFromRef(p2,sys); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } } } listPost(str, conj, strip); } void Line::listPost(ostream& str, int conj, int strip) { // no props for semicolons if (!strip) { if (conj) str << " ||"; str << " # line=" << p1Arrow << ' ' << p2Arrow; listProperties(str, 0); } else { if (conj) str << "||"; else str << ';'; } } void Line::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format) { FitsImage* ptr = parent->findFits(sys,center); Vector vv[2]; vv[0] = p1; vv[1] = p2; XMLRowInit(); XMLRow(XMLSHAPE,type_); XMLRowPoint(ptr,sys,sky,format,vv,2); XMLRow(XMLPARAM,p1Arrow); XMLRow(XMLPARAM2,p2Arrow); XMLRowProps(ptr,sys); XMLRowEnd(str); } void Line::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, Coord::SkyFormat format, int strip) { FitsImage* ptr = parent->findFits(); listSAOtngPre(str, strip); switch (sys) { case Coord::IMAGE: case Coord::PHYSICAL: case Coord::DETECTOR: case Coord::AMPLIFIER: { Vector v1 = ptr->mapFromRef(p1,Coord::IMAGE); Vector v2 = ptr->mapFromRef(p2,Coord::IMAGE); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; default: if (ptr->hasWCSCel(sys)) { switch (format) { case Coord::DEGREES: { Vector v1 = ptr->mapFromRef(p1,sys,sky); Vector v2 = ptr->mapFromRef(p2,sys,sky); str << type_ << '(' << setprecision(8) << v1[0] << ',' << v1[1] << ',' << v2[0] << ',' << v2[1] << ')'; } break; case Coord::SEXAGESIMAL: { char buf[64]; char ra1[16], ra2[16]; char dec1[16], dec2[16]; { ptr->mapFromRef(p1,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra1 >> dec1; } { ptr->mapFromRef(p2,sys,sky,format,buf,64); string x(buf); istringstream wcs(x); wcs >> ra2 >> dec2; } str << type_ << '(' << ra1 << ',' << dec1 << ',' << ra2 << ',' << dec2 << ')'; } break; } } } listSAOtngPost(str, strip); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/xylex.L������������������������������������������������������������������������0000644�0001750�0001750�00000005073�11700666272�014620� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "xyparser.H" extern YYSTYPE* xylval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% amplifier {return AMPLIFIER_;} b1950 {return B1950_;} ccd {return CCD_;} debug {return DEBUG_;} detector {return DETECTOR_;} ecliptic {return ECLIPTIC_;} fk4 {return FK4_;} fk4-no-e {return FK4_NO_E_;} fk5 {return FK5_;} galactic {return GALACTIC_;} helioecliptic {return HELIOECLIPTIC_;} icrs {return ICRS_;} image {return IMAGE_;} j2000 {return J2000_;} logical {return LOGICAL_;} off {return OFF_;} on {return ON_;} physical {return PHYSICAL_;} supergalactic {return SUPERGALACTIC_;} version {return VERSION_;} wcs {return WCS_;} wcsa {return WCSA_;} wcsb {return WCSB_;} wcsc {return WCSC_;} wcsd {return WCSD_;} wcse {return WCSE_;} wcsf {return WCSF_;} wcsg {return WCSG_;} wcsh {return WCSH_;} wcsi {return WCSI_;} wcsj {return WCSJ_;} wcsk {return WCSK_;} wcsl {return WCSL_;} wcsm {return WCSM_;} wcsn {return WCSN_;} wcso {return WCSO_;} wcsp {return WCSP_;} wcsq {return WCSQ_;} wcsr {return WCSR_;} wcss {return WCSS_;} wcst {return WCST_;} wcsu {return WCSU_;} wcsv {return WCSV_;} wcsw {return WCSW_;} wcsx {return WCSX_;} wcsy {return WCSY_;} wcsz {return WCSZ_;} [+-]?{D}+ { // Integer xylval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number xylval->real = atof(yytext); return REAL; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // Sexagesimal int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return SEXSTR; } [+-]?{D}+h{D}+m{D}+"."?s | [+-]?{D}+h{D}+m{D}*"."{D}+s { // HMS int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return HMSSTR; } [+-]?{D}+d{D}+m{D}+"."?s | [+-]?{D}+d{D}+m{D}*"."{D}+s { // DMS int ll = yyleng <(XYBUFSIZE-1) ? yyleng:(XYBUFSIZE-1); strncpy(xylval->str,yytext,ll); xylval->str[ll] = '\0'; return DMSSTR; } #.* { // comment, eat it } \r\n { // windows line feed return '\n'; } [\n;,] { // special chars return yytext[0]; } <<EOF>> { // eof return EOF_; } . { // Else, eat it } %% ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/coord.h������������������������������������������������������������������������0000644�0001750�0001750�00000003424�11727743761�014617� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __coord_h__ #define __coord_h__ #include <string.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; class Coord { public: enum InternalSystem {WINDOW, CANVAS, WIDGET, USER, REF, PANNER, MAGNIFIER, PS}; enum CoordSystem {DATA, IMAGE, PHYSICAL, AMPLIFIER, DETECTOR, WCS, WCSA, WCSB, WCSC, WCSD, WCSE, WCSF, WCSG, WCSH, WCSI, WCSJ, WCSK, WCSL, WCSM, WCSN, WCSO, WCSP, WCSQ, WCSR, WCSS, WCST, WCSU, WCSV, WCSW, WCSX, WCSY, WCSZ, WCS0}; enum SkyFrame {FK4, FK4_NO_E, FK5, ICRS, GALACTIC, SUPERGALACTIC, ECLIPTIC, HELIOECLIPTIC}; enum SkyFormat {DEGREES, SEXAGESIMAL}; enum SkyDist {DEGREE, ARCMIN, ARCSEC}; enum AngleFormat {DEG, RAD}; enum Orientation {NORMAL, XX, YY, XY}; static char *coordSystemStr_[]; static char *skyFrameStr_[]; static char *skyFormatStr_[]; static char *skyDistStr_[]; public: void listCoordSystem(ostream&, CoordSystem, SkyFrame, int, int); void listDistSystem(ostream&, CoordSystem, SkyDist, int); void listProsCoordSystem(ostream&, CoordSystem, SkyFrame); void strToCoordSystem(const char*, CoordSystem, CoordSystem*, SkyFrame*); void strToSkyFormat(const char*, SkyFormat*); void strToSkyDist(const char*, SkyDist*); void strToDistSystem(const char*, CoordSystem, CoordSystem*, SkyDist*); void strToAngleFormat(const char*, AngleFormat*); char* coordSystemStr(int ii) {return coordSystemStr_[ii];} char* skyFrameStr(int ii) {return skyFrameStr_[ii];} char* skyFormatStr(int ii) {return skyFormatStr_[ii];} char* skyDistStr(int ii) {return skyDistStr_[ii];} }; extern Coord coord; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor8.h�����������������������������������������������������������0000644�0001750�0001750�00000001313�11700666267�017314� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __framergbtruecolor8_h__ #define __framergbtruecolor8_h__ #include "framergbtruecolor.h" #include "truecolor8.h" class FrameRGBTrueColor8 : public virtual FrameBase, public FrameRGBTrueColor, public TrueColor8 { private: void encodeTrueColor(XColor* src, char* dest) {TrueColor8::encodeTrueColor(src,dest,baseXImage);} void encodeTrueColor(unsigned char* src, XImage* ximage) {TrueColor8::encodeTrueColor(src, ximage);} public: FrameRGBTrueColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); ~FrameRGBTrueColor8(); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/context.h����������������������������������������������������������������������0000644�0001750�0001750�00000004600�11741350537�015161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __context_h__ #define __context_h__ #include "tcl.h" #include "base.h" #include "coord.h" #include "frscale.h" #include "list.h" #include "fitsmask.h" class Base; class FVContour; class Context { public: FitsImage* fits; FitsImage* cfits; List <FitsMask> mask; FVContour* contour; List<Contour> auxcontours; FrScale frScale; private: Base* parent_; int mosaicCount_; int naxis_[FTY_MAXAXES]; // the first two are ignored int slice_[FTY_MAXAXES]; // the first two are ignored Base::MosaicType mosaicType; Coord::CoordSystem mosaicSystem; int nhdu(); void updateClip(FrScale*, int); public: Context(); ~Context(); Context(const Context&); Context& operator=(const Context&); void analysis(); void bltHist(char*, char*, int); int calcSlice(); void clearContour(); void contourAuxHead() {auxcontours.head();} void contourAuxNext() {auxcontours.next();} int fitsCount(); Vector getClip(FrScale::ClipMode, float); Vector getClip(); int hasContour() {return contour ? 1 : 0;} int hasContourAux() {return auxcontours.current() ? 1 : 0;} double* histequ() {return frScale.histequ(fits);} int isMosaic() {return mosaicCount_>1 ? 1 : 0;} int isCube() {return nhdu()>1 ? 1 : 0;} int load(Base*, Base::MemType, const char*, FitsImage*, Base::LayerType); int loadExtCube(Base*, Base::MemType, const char*, FitsImage*); int loadSlice(Base*, Base::MemType, const char*, FitsImage*); int loadMosaic(Base*, Base::MemType, const char*, FitsImage*, Base::LayerType, Base::MosaicType, Coord::CoordSystem); int loadMosaicImage(Base*, Base::MemType, const char*, FitsImage*, Base::LayerType, Base::MosaicType, Coord::CoordSystem); int loadMosaicWFPC2(Base*, Base::MemType, const char*, FitsImage*); void loadInit(Base::MosaicType, Coord::CoordSystem); void loadFinish(); void loadFinishMask(); int naxis(int ii) {return naxis_[ii];} int naxes(); void parent(Base* pp) {parent_ = pp;} void setContour(FVContour*); int slice(int ii) {return slice_[ii];} void unload(); void updateBin(Base*); void updateBinFileNames(); void updateClip(); void updateContours(); void updateContours(const Matrix&); void updateSlice(int, int); }; #endif ��������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/framergbtruecolor24.C����������������������������������������������������������0000644�0001750�0001750�00000007324�11700666267�017335� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "framergbtruecolor24.h" #include "fitsimage.h" // Tk Canvas Widget Function Declarations int FrameRGBTrueColor24CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // FrameRGBTrueColor24 Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec frameRGBTrueColor24Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "framergb", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "512", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType frameRGBTrueColor24Type = { (char*)"framergbtruecolor24", // name sizeof(WidgetOptions), // item size FrameRGBTrueColor24CreateProc, // configProc frameRGBTrueColor24Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int FrameRGBTrueColor24_Init(Tcl_Interp* interp) { Tk_CreateItemType(&frameRGBTrueColor24Type); return TCL_OK; } int FrameRGBTrueColor24CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { FrameRGBTrueColor24* frame = new FrameRGBTrueColor24(interp, canvas, item); // and set default configuration if (frame->configure(argc, (const char**)argv, 0) != TCL_OK) { delete frame; Tcl_AppendResult(interp, " error occured while creating frame.", NULL); return TCL_ERROR; } return TCL_OK; } // FrameRGBTrueColor24 Member Functions FrameRGBTrueColor24::FrameRGBTrueColor24(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : FrameBase(i,c,item), FrameRGBTrueColor(i, c, item), TrueColor24(visual) { configSpecs = frameRGBTrueColor24Specs; // frame configure options } FrameRGBTrueColor24::~FrameRGBTrueColor24() { // we must do this at this level, because updateColorScale is called unloadAllFits(); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue8.C��������������������������������������������������������������0000644�0001750�0001750�00000006234�11700666266�016557� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscaletrue8.h" ColorScaleTrueColor8::ColorScaleTrueColor8(int s, Visual* visual) : ColorScale(s), TrueColor8(visual) { colors_ = new unsigned char[s]; for (int i=0; i<s; i++) colors_[i] = ((psColors_[i*3] & bm_) >> bs_) | // blue ((psColors_[i*3+1] & gm_) >> gs_) | // green ((psColors_[i*3+2] & rm_) >> rs_); // red } ColorScaleTrueColor8::~ColorScaleTrueColor8() { if (colors_) delete [] colors_; } LinearScaleTrueColor8::LinearScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : LinearScale(s, indexCells, colorCells, count), ColorScaleTrueColor8(s, visual), ColorScale(s) {} LogScaleTrueColor8::LogScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual) : LogScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor8(s, visual), ColorScale(s) {} PowScaleTrueColor8::PowScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual) : PowScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor8(s, visual), ColorScale(s) {} SqrtScaleTrueColor8::SqrtScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : SqrtScale(s, indexCells, colorCells, count), ColorScaleTrueColor8(s, visual), ColorScale(s) {} SquaredScaleTrueColor8::SquaredScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : SquaredScale(s, indexCells, colorCells, count), ColorScaleTrueColor8(s, visual), ColorScale(s) {} AsinhScaleTrueColor8::AsinhScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : AsinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor8(s, visual), ColorScale(s) {} SinhScaleTrueColor8::SinhScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : SinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor8(s, visual), ColorScale(s) {} IISScaleTrueColor8::IISScaleTrueColor8(unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual) : IISScale(indexCells, colorCells, count), ColorScaleTrueColor8(IISSIZE, visual), ColorScale(IISSIZE) {} HistEquScaleTrueColor8::HistEquScaleTrueColor8(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize, Visual* visual) : HistEquScale(s, indexCells, colorCells, count, hist, histsize), ColorScaleTrueColor8(s, visual), ColorScale(s) {} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/tnglex.L�����������������������������������������������������������������������0000644�0001750�0001750�00000006734�11700666271�014754� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "tngparser.H" extern YYSTYPE* tnglval; extern tngFlexLexer* tnglexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(tnglval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(TNGBUFSIZE-1) ? yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return STRING; } b1950 {return B1950_;} background {return BACKGROUND_;} box {return BOX_;} black {return BLACK_;} blue {return BLUE_;} circle {return CIRCLE_;} cyan {return CYAN_;} date {return DATE_;} debug {return DEBUG_;} degrees {return DEGREES_;} ellipse {return ELLIPSE_;} ecliptic {return ECLIPTIC_;} filename {return FILENAME_;} fk4 {return FK4_;} fk4-no-e {return FK4_NO_E_;} fk5 {return FK5_;} format {return FORMAT_;} galactic {return GALACTIC_;} green {return GREEN_;} helioecliptic {return HELIOECLIPTIC_;} hms {return HMS_;} icrs {return ICRS_;} j2000 {return J2000_;} lin[e] {return LINE_;} magenta {return MAGENTA_;} off {return OFF_;} on {return ON_;} physical {return PHYSICAL_;} pixels {return PIXELS_;} point {return POINT_;} polygon {return POLYGON_;} red {return RED_;} source {return SOURCE_;} supergalactic {return SUPERGALACTIC_;} text {return TEXT_;} version {return VERSION_;} white {return WHITE_;} yellow {return YELLOW_;} [+-]?{D}+ { // Integer tnglval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number tnglval->real = atof(yytext); return REAL; } [+-]?{D}+"."?d | [+-]?{D}*"."{D}+d { // degrees yytext[yyleng-1] = '\0'; tnglval->real = atof(yytext); return ANGDEGREE; } [+-]?{D}+:{D}+:{D}+"."? | [+-]?{D}+:{D}+:{D}*"."{D}+ { // Sexagesimal int ll = yyleng <(TNGBUFSIZE-1)?yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return SEXSTR; } \"[^\"\n]*\" | \'[^\'\n]*\' { // Quoted String int ll = (yyleng-2)<(TNGBUFSIZE-1)?(yyleng-2):(TNGBUFSIZE-1); strncpy(tnglval->str,yytext+1,yyleng-2); // skip the " " tnglval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}\n]*\} { // Quoted String int ll = (yyleng-2)<(TNGBUFSIZE-1)?(yyleng-2):(TNGBUFSIZE-1); strncpy(tnglval->str,yytext+1,yyleng-2); // skip the '{' tnglval->str[ll] = '\0'; // Remove the '}' return STRING; } [0-9A-Za-z]+ { // General String int ll = yyleng <(TNGBUFSIZE-1) ? yyleng:(TNGBUFSIZE-1); strncpy(tnglval->str,yytext,ll); tnglval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \\n { // fake line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% void tngDiscard(int doit) { if (tnglexx) tnglexx->begin(DISCARD, doit); } void tngFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ������������������������������������./saods9/saotk/frame/basemarker.C�������������������������������������������������������������������0000644�0001750�0001750�00000010057�11727727777�015571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "basemarker.h" #include "base.h" // Base Markers Public BaseMarker::BaseMarker(const BaseMarker& a) : Marker(a) { startAng_ = a.startAng_; stopAng_ = a.stopAng_; numAnnuli_ = a.numAnnuli_; annuli_ = new Vector[a.numAnnuli_]; for (int i=0; i<a.numAnnuli_; i++) annuli_[i] = a.annuli_[i]; } BaseMarker::BaseMarker(Base* p, const Vector& ctr, double ang, const char* clr, int* dsh, int w, const char* f, const char* t, unsigned short prop, const char* c, const List<Tag>& tag, const List<CallBack>& cb) : Marker(p, ctr, ang, clr, dsh, w, f, t, prop, c, tag, cb) { startAng_ = 0; stopAng_ = M_TWOPI; numAnnuli_ = 0; annuli_ = NULL; } BaseMarker::~BaseMarker() { if (annuli_) delete [] annuli_; } void BaseMarker::updateCoords(const Matrix& mx) { for (int i=0; i<numAnnuli_; i++) annuli_[i] *= Scale(mx); Marker::updateCoords(mx); } void BaseMarker::setAnnuli(const Vector& r) { annuli_[0] = r; updateBBox(); doCallBack(CallBack::EDITCB); } void BaseMarker::setAnnuli(const Vector& r1, const Vector& r2, int rn) { numAnnuli_ = rn+1; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = ((r2-r1)/rn)*i+r1; sortAnnuli(); numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } void BaseMarker::setAnnuli(const Vector* r, int rn) { numAnnuli_ = rn; if (annuli_) delete [] annuli_; annuli_ = new Vector[numAnnuli_]; for (int i=0; i<numAnnuli_; i++) annuli_[i] = r[i]; sortAnnuli(); numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } int BaseMarker::insertAnnuli(Vector r) { // new size array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_+1]; // copy old values for (int i=0; i<numAnnuli_; i++) annuli_[i] = old[i]; // delete old if (old) delete [] old; // new size on end annuli_[numAnnuli_] = r; numAnnuli_++; numHandle++; updateBBox(); // return handle number return numAnnuli_+4; } void BaseMarker::deleteAnnuli(int h) { if (h>4) { int hh = h-4-1; if (numAnnuli_>2 && hh<numAnnuli_) { // new radii array Vector* old = annuli_; annuli_ = new Vector[numAnnuli_-1]; // copy up to radii in question for (int i=0; i<hh; i++) annuli_[i] = old[i]; // copy remainder for (int i=hh; i<numAnnuli_-1; i++) annuli_[i] = old[i+1]; if (old) delete [] old; numAnnuli_--; numHandle = 4 + numAnnuli_; updateBBox(); doCallBack(CallBack::EDITCB); } } } void BaseMarker::sortAnnuli() { for (int i=0; i<numAnnuli_; i++) for (int j=i+1; j<numAnnuli_; j++) if (annuli_[i][0]>annuli_[j][0]) { Vector d = annuli_[i]; annuli_[i] = annuli_[j]; annuli_[j] = d; } } Matrix BaseMarker::fwdMatrix() { if (properties & FIXED) { Vector cc = center * parent->refToCanvas; return Rotate(calcAngle()) * Translate(cc) * parent->canvasToRef; } else return Marker::fwdMatrix(); } Matrix BaseMarker::bckMatrix() { if (properties & FIXED) { Vector cc = center * parent->refToCanvas; return parent->refToCanvas * Translate(-cc) * Rotate(-calcAngle()); } else return Marker::bckMatrix(); } Vector BaseMarker::fwdMap(const Vector& vv, Coord::InternalSystem sys) { if (properties & FIXED) { Vector cc = center * parent->refToCanvas; Vector dd = vv * Rotate(calcAngle()) * Translate(cc); Vector ee = dd*parent->canvasToRef; return parent->mapFromRef(ee,sys); } else return Marker::fwdMap(vv,sys); } Vector BaseMarker::bckMap(const Vector& vv, Coord::InternalSystem sys) { if (properties & FIXED) { Vector aa = parent->mapToRef(vv,sys); Vector bb = aa*parent->refToCanvas; Vector cc = center * parent->refToCanvas; return bb * Translate(-cc) * Rotate(-calcAngle()); } else return Marker::bckMap(vv,sys); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/basepanda.h��������������������������������������������������������������������0000644�0001750�0001750�00000001306�12004561531�015402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __basepanda_h__ #define __basepanda_h__ #include "vector.h" class BasePanda { protected: double *angles_; int numAngles_; void sortAngles(); void setAngles(double, double, int); void setAngles(int, const double*); void addAngle(double); void deleteAngle(int); int isIn(Vector&, int); public: BasePanda(const BasePanda& a); BasePanda(double a1, double a2, int an); BasePanda(int an, double* a); ~BasePanda(); int numAngles() {return numAngles_;} double angles(int i) {return angles_[i];} }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/colorscaletrue24.C�������������������������������������������������������������0000644�0001750�0001750�00000007545�11700666266�016643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorscaletrue24.h" ColorScaleTrueColor24::ColorScaleTrueColor24(int s, Visual* visual, int msb) : ColorScale(s), TrueColor24(visual) { colors_ = new unsigned char[s*3]; // we need to check to byteswap when we have cross platforms if ((!msb && lsb()) || (msb && !lsb())) { for (int i=0; i<s; i++) { unsigned int r = psColors_[i*3+2]; unsigned int g = psColors_[i*3+1]; unsigned int b = psColors_[i*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; memcpy(colors_+i*3, &a, 3); } } else { for (int i=0; i<s; i++) { unsigned int r = psColors_[i*3+2]; unsigned int g = psColors_[i*3+1]; unsigned int b = psColors_[i*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(colors_+i*3) = *(rr+3); *(colors_+i*3+1) = *(rr+2); *(colors_+i*3+2) = *(rr+1); } } } ColorScaleTrueColor24::~ColorScaleTrueColor24() { if (colors_) delete [] colors_; } LinearScaleTrueColor24::LinearScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : LinearScale(s, indexCells, colorCells, count), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} LogScaleTrueColor24::LogScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : LogScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} PowScaleTrueColor24::PowScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double exp, Visual* visual, int msb) : PowScale(s, indexCells, colorCells, count, exp), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} SqrtScaleTrueColor24::SqrtScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SqrtScale(s, indexCells, colorCells, count), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} SquaredScaleTrueColor24::SquaredScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SquaredScale(s, indexCells, colorCells, count), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} AsinhScaleTrueColor24::AsinhScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : AsinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} SinhScaleTrueColor24::SinhScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : SinhScale(s, indexCells, colorCells, count), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} IISScaleTrueColor24::IISScaleTrueColor24(unsigned short* indexCells, unsigned char* colorCells, int count, Visual* visual, int msb) : IISScale(indexCells, colorCells, count), ColorScaleTrueColor24(IISSIZE, visual, msb), ColorScale(IISSIZE) {} HistEquScaleTrueColor24::HistEquScaleTrueColor24(int s, unsigned short* indexCells, unsigned char* colorCells, int count, double* hist, int histsize, Visual* visual, int msb) : HistEquScale(s, indexCells, colorCells, count, hist, histsize), ColorScaleTrueColor24(s, visual, msb), ColorScale(s) {} �����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/frame/fitshealpix.C������������������������������������������������������������������0000644�0001750�0001750�00000003317�12107012362�015740� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "fitsimage.h" #include "hpx.h" int FitsImage::initHPX() { // make sure we have rows and cols FitsHead* head = fits_->head(); FitsTableHDU* hdu = NULL; if (head) { hdu = (FitsTableHDU*)(head->hdu()); if (!hdu->width() || !hdu->rows()) return 0; } // coordinate system identifier? FitsHPX::CoordSys coord = FitsHPX::UNKNOWN; if (fits_->pHPXSystem() >= 0) coord = (FitsHPX::CoordSys)fits_->pHPXSystem(); else { char* str = head->getString("COORDSYS"); if (str) { if (str[0] == 'G') coord = FitsHPX::GAL; else if (str[0] == 'E') coord = FitsHPX::ECL; else if (str[0] == 'C') coord = FitsHPX::EQU; else if (str[0] == 'Q') coord = FitsHPX::EQU; delete [] str; } } // Nested or ring order? FitsHPX::Order order = FitsHPX::RING; if (fits_->pHPXOrder() >=0) order = (FitsHPX::Order)fits_->pHPXOrder(); else { char* str = head->getString("ORDERING"); if (str) { if (str[0] == 'N') order = FitsHPX::NESTED; else if (str[0] == 'R') order = FitsHPX::RING; delete [] str; } } // Layout FitsHPX::Layout layout = FitsHPX::EQUATOR; if (fits_->pHPXLayout() >=0) layout = (FitsHPX::Layout)fits_->pHPXLayout(); // Col int col =0; if (fits_->pHPXColumn() >=0) col = fits_->pHPXColumn(); if (col<0) col =0; // Quad int quad = 0; if (fits_->pHPXQuad() >=0) quad = fits_->pHPXQuad(); if (quad<0 || quad>3) quad =0; if (hpx_) delete hpx_; hpx_ = new FitsHPX(fits_, order, coord, layout, col, quad); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/���������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014152� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/Makefile�������������������������������������������������������������������0000644�0001750�0001750�00000001362�11517372163�015635� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) \ -I. -I.. -I../widget -I../vector -I../util \ -I../../include -I$(X11INCLUDE) SS = \ magnifier.C \ magnifiertrue.C ifeq ($(OS),unix) SSP = \ magnifierpseudo.C endif SRC = $(SS) $(SSP) \ parser.C \ lex.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o $(LIB) parser.output ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif parsers : parser parser : FORCE bison -d -p mg -o parser.C parser.Y flex -Pmg -olex.C lex.L FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/lex.L����������������������������������������������������������������������0000644�0001750�0001750�00000002124�11775376666�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* mglval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% bbox {return BBOX_;} clear {return CLEAR_;} debug {return DEBUG_;} false {return FALSE_;} get {return GET_;} height {return HEIGHT_;} hide {return HIDE_;} off {return OFF_;} on {return ON_;} n {return N_;} no {return NO_;} reset {return RESET_;} show {return SHOW_;} true {return TRUE_;} update {return UPDATE_;} version {return VERSION_;} width {return WIDTH_;} y {return Y_;} yes {return YES_;} [+-]?{D}+ { // Integer mglval->integer = atoi(yytext); return INT; } 0[xX][0-9a-fA-F]+ { // Pointer mglval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } [ \t]+ { // White Spaces } . { // Else, return the char return yytext[0]; } %% ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/magnifiertrue.h������������������������������������������������������������0000644�0001750�0001750�00000000622�11700666272�017206� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __magnifiertrue_h__ #define __magnifiertrue_h__ #include "magnifier.h" class MagnifierTrueColor : public Magnifier { private: void clearPixmap(); public: MagnifierTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ��������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/magnifier.C����������������������������������������������������������������0000644�0001750�0001750�00000004137�12042560016�016233� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <math.h> #include "magnifier.h" #include "util.h" // Parser Stuff #undef yyFlexLexer #define yyFlexLexer mgFlexLexer #include <FlexLexer.h> void* mglval; extern int mgparse(Magnifier*, mgFlexLexer*); int mglex(void* vval, mgFlexLexer* ll) { mglval = vval; return ll ? ll->yylex() : 0; } void mgerror(Magnifier* mg, mgFlexLexer* ll, const char* m) { mg->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { mg->error(": "); mg->error(cmd); } } // Public Member Functions Magnifier::Magnifier(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Widget(i, c, item) { thumbnail = 0; needsUpdate = 0; } int Magnifier::parse(istringstream& istr) { result = TCL_OK; mgFlexLexer* ll = new mgFlexLexer(&istr); mgparse(this, ll); delete ll; return result; } void Magnifier::update() { needsUpdate = 1; redrawNow(); } // Required Virtual Functions // UpdatePixmap. This function is responsable for creating a valid // pixmap the size of the current Magnifier int Magnifier::updatePixmap(const BBox& bb) { // create a valid pixmap if needed // bb is in canvas coords if (!pixmap) if (!(pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), options->width, options->height, depth))) { internalError("Magnifier: Unable to Create Pixmap"); return TCL_OK; } if (needsUpdate) { if (thumbnail) { XSetClipOrigin(display, gc, 0, 0); XCopyArea(display, thumbnail, pixmap, gc, 0, 0, options->width, options->height, 0, 0); } else clearPixmap(); needsUpdate = 0; } return TCL_OK; } void Magnifier::invalidPixmap() { Widget::invalidPixmap(); update(); } // Command Functions void Magnifier::getBBoxCmd() { ostringstream str; str << options->width << " " << options->height << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Magnifier::updateCmd(void* p) { thumbnail = (Pixmap)p; update(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/magnifiertrue.C������������������������������������������������������������0000644�0001750�0001750�00000007707�11700666272�017154� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include "magnifiertrue.h" #include "util.h" // Tk Canvas Widget Function Declarations int MagnifierTrueColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // MagnifierTrueColor Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec magnifierTrueColorSpecs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "magnifier", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType magnifierTrueColorType = { (char*)"magnifiertruecolor", // name sizeof(WidgetOptions), // size MagnifierTrueColorCreateProc, // configProc magnifierTrueColorSpecs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int MagnifierTrueColor_Init(Tcl_Interp* interp) { Tk_CreateItemType(&magnifierTrueColorType); return TCL_OK; } int MagnifierTrueColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { MagnifierTrueColor* magnifier = new MagnifierTrueColor(interp, canvas, item); // and set default configuration if (magnifier->configure(argc, (const char**)argv, 0) != TCL_OK) { delete magnifier; Tcl_AppendResult(interp, " error occured while creating magnifier.", NULL); return TCL_ERROR; } return TCL_OK; } MagnifierTrueColor::MagnifierTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Magnifier(i, c, item) { configSpecs = magnifierTrueColorSpecs; // magnifier configure options } void MagnifierTrueColor::clearPixmap() { XImage* xmap = XGetImage(display, pixmap, 0, 0, options->width, options->height, AllPlanes, ZPixmap); if (!xmap) { internalError("MagnifierTrueColor: Unable to Create XImage"); return; } memset(XImageData(xmap), 255, xmap->bytes_per_line * xmap->height); XPutImage(display, pixmap, gc, xmap, 0, 0, 0, 0, options->width, options->height); XDestroyImage(xmap); } ���������������������������������������������������������./saods9/saotk/magnifier/magnifier.h����������������������������������������������������������������0000644�0001750�0001750�00000001771�11775376666�016335� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __magnifier_h__ #define __magnifier_h__ #include "widget.h" class Magnifier : public Widget { private: Pixmap thumbnail; // current gterm thumbnail pixmap double crosshairSize; // size of crosshair (diameter) double crosshairAngle; // angle of rotation (radians) GC crosshairGC; // gc for crosshairs int useCrosshair; // flag to render crosshair int needsUpdate; // flag to indicate update needed protected: virtual void clearPixmap() =0; private: int updatePixmap(const BBox&); // renders image/graphics into pixmap void update(); void invalidPixmap(); public: Magnifier(Tcl_Interp*, Tk_Canvas, Tk_Item*); int parse(istringstream&); // parse subcommands // SubCommandFunctions void crosshairCmd(int); void getBBoxCmd(); void updateCmd(void*); }; #endif �������./saods9/saotk/magnifier/parser.H�������������������������������������������������������������������0000644�0001750�0001750�00000005571�11775376666�015632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, POINTER = 259, BBOX_ = 260, CLEAR_ = 261, DEBUG_ = 262, FALSE_ = 263, GET_ = 264, HEIGHT_ = 265, HIDE_ = 266, OFF_ = 267, ON_ = 268, N_ = 269, NO_ = 270, RESET_ = 271, SHOW_ = 272, TRUE_ = 273, UPDATE_ = 274, VERSION_ = 275, WIDTH_ = 276, Y_ = 277, YES_ = 278 }; #endif /* Tokens. */ #define INT 258 #define POINTER 259 #define BBOX_ 260 #define CLEAR_ 261 #define DEBUG_ 262 #define FALSE_ 263 #define GET_ 264 #define HEIGHT_ 265 #define HIDE_ 266 #define OFF_ 267 #define ON_ 268 #define N_ 269 #define NO_ 270 #define RESET_ 271 #define SHOW_ 272 #define TRUE_ 273 #define UPDATE_ 274 #define VERSION_ 275 #define WIDTH_ 276 #define Y_ 277 #define YES_ 278 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 24 "parser.Y" { float real; int integer; void* ptr; char str[1024]; } /* Line 1529 of yacc.c. */ #line 102 "parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ���������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/magnifierpseudo.C����������������������������������������������������������0000644�0001750�0001750�00000007234�11700666272�017467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "magnifierpseudo.h" // Tk Canvas Widget Function Declarations int MagnifierPseudoColorCreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // MagnifierPseudoColor Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec magnifierPseudoColorSpecs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "magnifier", Tk_Offset(WidgetOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(WidgetOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(WidgetOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "256", Tk_Offset(WidgetOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "256", Tk_Offset(WidgetOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(WidgetOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(WidgetOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(WidgetOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(WidgetOptions, times), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType magnifierPseudoColorType = { (char*)"magnifierpseudocolor", // name sizeof(WidgetOptions), // size MagnifierPseudoColorCreateProc, // configProc magnifierPseudoColorSpecs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int MagnifierPseudoColor_Init(Tcl_Interp* interp) { Tk_CreateItemType(&magnifierPseudoColorType); return TCL_OK; } int MagnifierPseudoColorCreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { MagnifierPseudoColor* magnifier = new MagnifierPseudoColor(interp, canvas, item); // and set default configuration if (magnifier->configure(argc, (const char**)argv, 0) != TCL_OK) { delete magnifier; Tcl_AppendResult(interp, " error occured while creating magnifier.", NULL); return TCL_ERROR; } return TCL_OK; } MagnifierPseudoColor::MagnifierPseudoColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Magnifier(i, c, item) { configSpecs = magnifierPseudoColorSpecs; // magnifier configure options } void MagnifierPseudoColor::clearPixmap() { XSetForeground(display, gc, getColor("white")); XFillRectangle(display, pixmap, gc, 0, 0, options->width, options->height); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/parser.Y�������������������������������������������������������������������0000644�0001750�0001750�00000002363�12042571357�015625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {Magnifier* mg} %lex-param {mgFlexLexer* ll} %parse-param {mgFlexLexer* ll} %{ #define YYDEBUG 1 #include <stdlib.h> #include "magnifier.h" #undef yyFlexLexer #define yyFlexLexer mgFlexLexer #include <FlexLexer.h> extern int mglex(void*, mgFlexLexer*); extern void mgerror(Magnifier*, mgFlexLexer*, const char*); %} %union { float real; int integer; void* ptr; char str[1024]; } %token <integer> INT %token <ptr> POINTER %token BBOX_ %token CLEAR_ %token DEBUG_ %token FALSE_ %token GET_ %token HEIGHT_ %token HIDE_ %token OFF_ %token ON_ %token N_ %token NO_ %token RESET_ %token SHOW_ %token TRUE_ %token UPDATE_ %token VERSION_ %token WIDTH_ %token Y_ %token YES_ %% command : DEBUG_ debug | CLEAR_ {mg->updateCmd(0);} | GET_ get | HIDE_ {mg->hideCmd();} | RESET_ {mg->resetCmd();} | SHOW_ {mg->showCmd();} | UPDATE_ POINTER {mg->updateCmd($2);} | VERSION_ {mg->msg("Magnifier 1.0");} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; get : BBOX_ {mg->getBBoxCmd();} | HEIGHT_ {mg->getHeightCmd();} | WIDTH_ {mg->getWidthCmd();} ; %% �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/parser.C�������������������������������������������������������������������0000644�0001750�0001750�00000125415�12042571357�015603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse mgparse #define yylex mglex #define yyerror mgerror #define yylval mglval #define yychar mgchar #define yydebug mgdebug #define yynerrs mgnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, POINTER = 259, BBOX_ = 260, CLEAR_ = 261, DEBUG_ = 262, FALSE_ = 263, GET_ = 264, HEIGHT_ = 265, HIDE_ = 266, OFF_ = 267, ON_ = 268, N_ = 269, NO_ = 270, RESET_ = 271, SHOW_ = 272, TRUE_ = 273, UPDATE_ = 274, VERSION_ = 275, WIDTH_ = 276, Y_ = 277, YES_ = 278 }; #endif /* Tokens. */ #define INT 258 #define POINTER 259 #define BBOX_ 260 #define CLEAR_ 261 #define DEBUG_ 262 #define FALSE_ 263 #define GET_ 264 #define HEIGHT_ 265 #define HIDE_ 266 #define OFF_ 267 #define ON_ 268 #define N_ 269 #define NO_ 270 #define RESET_ 271 #define SHOW_ 272 #define TRUE_ 273 #define UPDATE_ 274 #define VERSION_ 275 #define WIDTH_ 276 #define Y_ 277 #define YES_ 278 /* Copy the first part of user declarations. */ #line 10 "parser.Y" #define YYDEBUG 1 #include <stdlib.h> #include "magnifier.h" #undef yyFlexLexer #define yyFlexLexer mgFlexLexer #include <FlexLexer.h> extern int mglex(void*, mgFlexLexer*); extern void mgerror(Magnifier*, mgFlexLexer*, const char*); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 24 "parser.Y" { float real; int integer; void* ptr; char str[1024]; } /* Line 193 of yacc.c. */ #line 171 "parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 184 "parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 18 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 21 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 24 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ #define YYNRULES 14 /* YYNRULES -- Number of states. */ #define YYNSTATES 19 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 278 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 6, 8, 11, 13, 15, 17, 20, 22, 24, 26, 28, 30 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 25, 0, -1, 7, 26, -1, 6, -1, 9, 27, -1, 11, -1, 16, -1, 17, -1, 19, 4, -1, 20, -1, 13, -1, 12, -1, 5, -1, 10, -1, 21, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 56, 56, 57, 58, 59, 60, 61, 62, 63, 66, 67, 70, 71, 72 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "POINTER", "BBOX_", "CLEAR_", "DEBUG_", "FALSE_", "GET_", "HEIGHT_", "HIDE_", "OFF_", "ON_", "N_", "NO_", "RESET_", "SHOW_", "TRUE_", "UPDATE_", "VERSION_", "WIDTH_", "Y_", "YES_", "$accept", "command", "debug", "get", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 27, 27, 27 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 3, 0, 0, 5, 6, 7, 0, 9, 0, 11, 10, 2, 12, 13, 14, 4, 8, 1 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 9, 12, 16 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -12 static const yytype_int8 yypact[] = { 1, -12, -11, -5, -12, -12, -12, -1, -12, 4, -12, -12, -12, -12, -12, -12, -12, -12, -12 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -12, -12, -12, -12 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 13, 10, 11, 17, 18, 14, 0, 1, 2, 0, 3, 0, 4, 0, 0, 0, 15, 5, 6, 0, 7, 8 }; static const yytype_int8 yycheck[] = { 5, 12, 13, 4, 0, 10, -1, 6, 7, -1, 9, -1, 11, -1, -1, -1, 21, 16, 17, -1, 19, 20 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 6, 7, 9, 11, 16, 17, 19, 20, 25, 12, 13, 26, 5, 10, 21, 27, 4, 0 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (mg, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, mg, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Magnifier* mg, mgFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, mg, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Magnifier* mg; mgFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (mg); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Magnifier* mg, mgFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, mg, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Magnifier* mg; mgFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, mg, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Magnifier* mg, mgFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, mg, ll) YYSTYPE *yyvsp; int yyrule; Magnifier* mg; mgFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , mg, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, mg, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Magnifier* mg, mgFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, mg, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Magnifier* mg; mgFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (mg); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (Magnifier* mg, mgFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Magnifier* mg, mgFlexLexer* ll) #else int yyparse (mg, ll) Magnifier* mg; mgFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: #line 57 "parser.Y" {mg->updateCmd(0);;} break; case 5: #line 59 "parser.Y" {mg->hideCmd();;} break; case 6: #line 60 "parser.Y" {mg->resetCmd();;} break; case 7: #line 61 "parser.Y" {mg->showCmd();;} break; case 8: #line 62 "parser.Y" {mg->updateCmd((yyvsp[(2) - (2)].ptr));;} break; case 9: #line 63 "parser.Y" {mg->msg("Magnifier 1.0");;} break; case 10: #line 66 "parser.Y" {yydebug=1;;} break; case 11: #line 67 "parser.Y" {yydebug=0;;} break; case 12: #line 70 "parser.Y" {mg->getBBoxCmd();;} break; case 13: #line 71 "parser.Y" {mg->getHeightCmd();;} break; case 14: #line 72 "parser.Y" {mg->getWidthCmd();;} break; /* Line 1267 of yacc.c. */ #line 1451 "parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (mg, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (mg, ll, yymsg); } else { yyerror (mg, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, mg, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, mg, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (mg, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, mg, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, mg, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 75 "parser.Y" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/lex.C����������������������������������������������������������������������0000644�0001750�0001750�00000130076�12032640000�015053� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lex.C" #line 4 "lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer mgFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *mgalloc (yy_size_t ); void *mgrealloc (void *,yy_size_t ); void mgfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 24 #define YY_END_OF_BUFFER 25 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[86] = { 0, 0, 0, 25, 23, 22, 24, 23, 20, 20, 23, 23, 23, 23, 23, 23, 10, 23, 23, 23, 23, 23, 23, 23, 18, 22, 20, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 9, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 7, 0, 13, 14, 0, 0, 0, 2, 3, 4, 0, 12, 0, 0, 17, 6, 15, 0, 16, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 1, 1, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 1, 16, 1, 17, 18, 19, 1, 20, 21, 22, 23, 24, 25, 26, 27, 1, 1, 1, 1, 1, 1, 1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 1, 1, 37, 1, 38, 39, 40, 1, 41, 42, 43, 44, 45, 46, 47, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[49] = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[87] = { 0, 0, 0, 159, 175, 154, 175, 44, 46, 48, 47, 40, 46, 51, 48, 49, 43, 50, 52, 51, 46, 49, 58, 55, 60, 153, 68, 0, 57, 83, 87, 81, 76, 84, 90, 175, 89, 175, 81, 85, 81, 95, 86, 97, 87, 0, 83, 103, 88, 91, 175, 100, 103, 175, 106, 111, 126, 132, 119, 119, 175, 175, 122, 130, 133, 131, 175, 124, 175, 175, 125, 133, 135, 175, 175, 175, 128, 175, 140, 134, 175, 175, 175, 136, 175, 175, 152 } ; static yyconst flex_int16_t yy_def[87] = { 0, 85, 1, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 85 } ; static yyconst flex_int16_t yy_nxt[224] = { 0, 4, 5, 6, 7, 8, 9, 4, 10, 11, 12, 4, 13, 14, 15, 4, 4, 16, 17, 4, 18, 19, 20, 21, 22, 23, 4, 24, 4, 10, 11, 12, 4, 13, 14, 15, 4, 4, 16, 17, 4, 18, 19, 20, 21, 22, 23, 4, 24, 26, 26, 26, 26, 26, 26, 28, 29, 30, 31, 32, 33, 35, 36, 38, 34, 39, 40, 37, 41, 42, 43, 44, 27, 26, 26, 46, 28, 29, 30, 31, 32, 33, 35, 36, 38, 34, 39, 40, 37, 41, 42, 43, 44, 27, 47, 48, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 47, 48, 67, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 45, 25, 25, 68, 69, 85, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 3, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 } ; static yyconst flex_int16_t yy_chk[224] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 15, 19, 20, 17, 21, 22, 23, 24, 8, 26, 26, 28, 10, 11, 12, 13, 14, 15, 16, 17, 18, 15, 19, 20, 17, 21, 22, 23, 24, 8, 29, 30, 28, 31, 32, 33, 34, 36, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 29, 30, 54, 31, 32, 33, 34, 36, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 55, 56, 54, 57, 58, 59, 62, 63, 64, 65, 67, 70, 71, 72, 76, 78, 79, 83, 86, 25, 5, 55, 56, 3, 57, 58, 59, 62, 63, 64, 65, 67, 70, 71, 72, 76, 78, 79, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* mglval; /* rules */ #line 496 "lex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 26 "lex.L" #line 599 "lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 86 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 85 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 28 "lex.L" {return BBOX_;} YY_BREAK case 2: YY_RULE_SETUP #line 29 "lex.L" {return CLEAR_;} YY_BREAK case 3: YY_RULE_SETUP #line 30 "lex.L" {return DEBUG_;} YY_BREAK case 4: YY_RULE_SETUP #line 31 "lex.L" {return FALSE_;} YY_BREAK case 5: YY_RULE_SETUP #line 32 "lex.L" {return GET_;} YY_BREAK case 6: YY_RULE_SETUP #line 33 "lex.L" {return HEIGHT_;} YY_BREAK case 7: YY_RULE_SETUP #line 34 "lex.L" {return HIDE_;} YY_BREAK case 8: YY_RULE_SETUP #line 35 "lex.L" {return OFF_;} YY_BREAK case 9: YY_RULE_SETUP #line 36 "lex.L" {return ON_;} YY_BREAK case 10: YY_RULE_SETUP #line 37 "lex.L" {return N_;} YY_BREAK case 11: YY_RULE_SETUP #line 38 "lex.L" {return NO_;} YY_BREAK case 12: YY_RULE_SETUP #line 39 "lex.L" {return RESET_;} YY_BREAK case 13: YY_RULE_SETUP #line 40 "lex.L" {return SHOW_;} YY_BREAK case 14: YY_RULE_SETUP #line 41 "lex.L" {return TRUE_;} YY_BREAK case 15: YY_RULE_SETUP #line 42 "lex.L" {return UPDATE_;} YY_BREAK case 16: YY_RULE_SETUP #line 43 "lex.L" {return VERSION_;} YY_BREAK case 17: YY_RULE_SETUP #line 44 "lex.L" {return WIDTH_;} YY_BREAK case 18: YY_RULE_SETUP #line 45 "lex.L" {return Y_;} YY_BREAK case 19: YY_RULE_SETUP #line 46 "lex.L" {return YES_;} YY_BREAK case 20: YY_RULE_SETUP #line 48 "lex.L" { // Integer mglval->integer = atoi(yytext); return INT; } YY_BREAK case 21: YY_RULE_SETUP #line 53 "lex.L" { // Pointer mglval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } YY_BREAK case 22: YY_RULE_SETUP #line 58 "lex.L" { // White Spaces } YY_BREAK case 23: YY_RULE_SETUP #line 61 "lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 24: YY_RULE_SETUP #line 65 "lex.L" ECHO; YY_BREAK #line 807 "lex.C" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; mgfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); mgfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ mgrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) mgrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 86 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 86 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 85); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) mgalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) mgalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) mgfree((void *) b->yy_ch_buf ); mgfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)mgalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)mgrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) mgalloc(new_size ); else (yy_start_stack) = (int *) mgrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *mgalloc (yy_size_t size ) { return (void *) malloc( size ); } void *mgrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void mgfree (void * ptr ) { free( (char *) ptr ); /* see mgrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 65 "lex.L" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/magnifier/magnifierpseudo.h����������������������������������������������������������0000644�0001750�0001750�00000000632�11700666272�017527� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __magnifierpseudo_h__ #define __magnifierpseudo_h__ #include "magnifier.h" class MagnifierPseudoColor : public Magnifier { private: void clearPixmap(); public: MagnifierPseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/�����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013475� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/smap.C�����������������������������������������������������������������������0000644�0001750�0001750�00000003654�12075360501�014563� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "smap.h" #include "head.h" FitsSMap::FitsSMap() { hmapdata_ = NULL; hmapsize_ = 0; mapdata_ = NULL; mapsize_ = 0; } FitsFitsSMap::FitsFitsSMap(FitsHead::Memory mem) { if (!valid_) return; // simple check for fits file if (strncmp(hmapdata_,"SIMPLE ",8) && strncmp(hmapdata_,"XTENSION",8)) { data_ = NULL; dataSize_ = 0; dataSkip_ = 0; valid_ = 0; } head_ = new FitsHead(hmapdata_, hmapsize_, mem); if (head_->isValid()) { data_ = mapdata_; dataSize_ = mapsize_; dataSkip_ = 0; inherit_ = head_->inherit(); valid_ = 1; return; } else { if (manageHead_ && head_) delete head_; head_ = NULL; if (managePrimary_ && primary_) delete primary_; primary_ = NULL; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; valid_ = 0; } } FitsFitsNextSMap::FitsFitsNextSMap(FitsFile* p) { FitsSMap* prev = (FitsSMap*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); coord_ = prev->coord(); xvalid_ = prev->xvalid(); xmin_ = prev->xmin(); xmax_ = prev->xmax(); yvalid_ = prev->yvalid(); ymin_ = prev->ymin(); ymax_ = prev->ymax(); zvalid_ = prev->zvalid(); zmin_ = prev->zmin(); zmax_ = prev->zmax(); mapdata_ = prev->mapdata(); mapsize_ = prev->mapsize(); return; } ������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hcompress.h������������������������������������������������������������������0000644�0001750�0001750�00000000725�11700666265�015701� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitshcompress_h__ #define __fitshcompress_h__ #include "compress.h" template<class T> class FitsHcompressm : public FitsCompressm<T> { protected: int smooth_; private: int compressed(T*, char*, char*, int, int, int, int, int, int); public: FitsHcompressm(FitsFile*); }; #endif �������������������������������������������./saods9/saotk/fitsy++/Makefile���������������������������������������������������������������������0000644�0001750�0001750�00000002631�12106546556�015164� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include include ../../make.pkgs CXXFLAGS = $(CXXOPT) -I. -I.. -I../vector -I../util \ -I../../include -I$(X11INCLUDE) \ -I../../$(FUNTOOLSDIR)/filter -I../../$(FUNTOOLSDIR)/fitsy \ -I../../$(FUNTOOLSDIR)/util SS = \ alloc.C \ allocgz.C \ analysis.C \ card.C \ channel.C \ column.C \ compress.C \ gzip.C \ gzraw.C \ iis.C \ hcompress.C \ hdu.C \ head.C \ hist.C \ hpx.C \ file.C \ map.C \ mapincr.C \ mmap.C \ mmapincr.C \ nrrd.C \ nrrdgzip.C \ outchannel.C \ outfile.C \ outfits.C \ outsocket.C \ photo.C \ plio.C \ rice.C \ savefits.C \ share.C \ sshare.C \ smap.C \ smmap.C \ socket.C \ socketgz.C \ strm.C \ var.C SRC = $(SS) \ parser.C \ lex.C \ nrrdparser.C \ nrrdlex.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o parser.output nrrdparser.output ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif parsers : parser nrrdparser parser : FORCE bison -d -p ff -o parser.C parser.Y flex -Pff -olex.C lex.L nrrdparser : FORCE bison -d -p nrrd -o nrrdparser.C nrrdparser.Y flex -Pnrrd -onrrdlex.C nrrdlex.L shmload : shmload.C $(RM) $@ $(CXX) $(CXXOPT) -o $@ $< cp $@ ../../bin/. FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SS:.C=.d) endif �������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mapincr.C��������������������������������������������������������������������0000644�0001750�0001750�00000026731�12075360501�015255� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <unistd.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include "mapincr.h" #include "head.h" //#define PAGELIMIT 1073741824 #define PAGELIMIT 536870912 FitsMapIncr::FitsMapIncr() { mapdata_ = NULL; mapsize_ = 0; page_ = 0; filesize_ = 0; seek_ = 0; dseek_ = 0; nseek_ = 0; } FitsMapIncr::~FitsMapIncr() { if (mapdata_>0) munmap((caddr_t)mapdata_, mapsize_); } FitsHead* FitsMapIncr::headRead() { // NOTE: the hdu cleans up after the hdu, // here we only clean up after the data segment // mmap will return valid if seek_ is at end of file, so check first if (filesize_-seek_<=0) return NULL; // read first BLOCK // seek_ needs to be an increment of getpagesize int pagesize = getpagesize(); off_t mmseek = (seek_/pagesize)*pagesize; size_t offset = seek_ - mmseek; int fd = open(pName_, O_RDONLY); size_t mmsize = offset+FTY_BLOCK; char* mmdata = (char*)mmap(NULL, mmsize, PROT_READ, MAP_SHARED, fd, mmseek); close(fd); // are we valid? if ((long)mmdata == -1) return NULL; // simple test if (strncmp(mmdata+offset,"SIMPLE ",8) && strncmp(mmdata+offset,"XTENSION",8)) { munmap((caddr_t)mmdata, mmsize); return NULL; } // can we find 'END'? while (mmsize-offset-FTY_BLOCK < filesize_-seek_) { if (findEnd(mmdata+mmsize-FTY_BLOCK)) break; // add another BLOCK munmap((caddr_t)mmdata, mmsize); fd = open(pName_, O_RDONLY); mmdata = (char*)mmap(NULL, mmsize+FTY_BLOCK, PROT_READ, MAP_SHARED, fd, mmseek); close(fd); // are we valid? if ((long)mmdata == -1) return NULL; mmsize += FTY_BLOCK; } // do we have a header? FitsHead* hd = new FitsHead(mmdata+offset, mmsize-offset, mmdata, mmsize, FitsHead::MMAP); if (!hd || !hd->isValid()) { delete hd; return NULL; } seek_ += mmsize-offset; // success! return hd; } void FitsMapIncr::dataSkip(size_t bytes) { seek_ += bytes; } void FitsMapIncr::dataSkipBlock(size_t blk) { seek_ += blk*FTY_BLOCK; } void FitsMapIncr::found() { // at this point we mmap the data segment // must find a page boundary int pagesize = getpagesize(); off_t mmseek = (seek_/pagesize)*pagesize; size_t offset = seek_ - mmseek; int fd = open(pName_, O_RDONLY); // determine internal page mode if (!head_->isTable() || !head_->isAsciiTable() || head_->isHeap()) { // no internal paging mapsize_ = head_->databytes()+offset; page_ = 0; } else { // if mapsize_ will exceed our inernal page limit, turn on internal paging if (head_->databytes()+offset > PAGELIMIT) { mapsize_ = PAGELIMIT; page_ = 1; dseek_ = seek_; nseek_ = seek_-offset; } else { // small enough, no internal paging mapsize_ = head_->databytes()+offset; page_ = 0; } } mapdata_ = (char*)mmap(NULL, mapsize_, PROT_READ, MAP_SHARED, fd, mmseek); close(fd); // are we valid? (we'd better be!) if ((long)mapdata_ == -1) { mapsize_ = 0; mapdata_ = NULL; error(); return; } // seek to next hdu, even if we are internal paging seek_ += head_->databytes(); // data starts after any page boundary data_ = mapdata_+offset; dataSize_ = mapsize_; dataSkip_ = 0; inherit_ = head_->inherit(); valid_ = 1; } char* FitsMapIncr::page(char* ptr, size_t row) { if (!page_) // no paging, just return return ptr; else { // be sure that at least 'row' bytes are still available if (ptr <= mapdata_+mapsize_-row) // no problem yet return ptr; else { // how far did we get nseek_ += ptr-mapdata_; // unmap the old segment munmap((caddr_t)mapdata_, mapsize_); // next mmap segment int pagesize = getpagesize(); off_t mmseek = (nseek_/pagesize)*pagesize; size_t offset = nseek_ - mmseek; int fd = open(pName_, O_RDONLY); // calc next internal page size if (head_->databytes()+offset-(nseek_-dseek_) > PAGELIMIT) mapsize_ = PAGELIMIT; else mapsize_ = head_->databytes()+offset-(nseek_-dseek_); mapdata_ =(char*)mmap(NULL, mapsize_, PROT_READ, MAP_SHARED, fd, mmseek); close(fd); // are we valid? (we'd better be!) if ((long)mapdata_ == -1) { //*** what to do here? internalError("Fitsy++ mapincr page() error"); mapsize_ = 0; mapdata_ = NULL; } nseek_ -= offset; return mapdata_+offset; } } } void FitsMapIncr::resetpage() { if (page_) { // ok, get a new page munmap((caddr_t)mapdata_, mapsize_); // remap original page int pagesize = getpagesize(); off_t mmseek = (dseek_/pagesize)*pagesize; size_t offset = dseek_ - mmseek; int fd = open(pName_, O_RDONLY); if (head_->databytes()+offset > PAGELIMIT) mapsize_ = PAGELIMIT; else mapsize_ = head_->databytes()+offset; mapdata_ =(char*)mmap(NULL, mapsize_, PROT_READ, MAP_SHARED, fd, mmseek); close(fd); // are we valid? (we'd better be!) if ((long)mapdata_ == -1) { //*** what to do here? internalError("Fitsy++ mapincr resetpage() error"); mapsize_ = 0; mapdata_ = NULL; } // reset, we may have moved in memory // found the data, save it nseek_ = dseek_-offset; data_ = mapdata_+offset; dataSize_ = mapsize_; dataSkip_ = offset; } } void FitsMapIncr::error() { if (manageHead_ && head_) delete head_; head_ = NULL; if (managePrimary_ && primary_) delete primary_; primary_ = NULL; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; valid_ = 0; } FitsFitsMapIncr::FitsFitsMapIncr(ScanMode mode) { if (!valid_) return; if (mode == EXACT || pExt_ || pIndex_>-1) processExact(); else processRelax(); } void FitsFitsMapIncr::processExact() { // simple check for fits file if (!(pExt_ || (pIndex_>0))) { // we are only looking for a primary image head_ = headRead(); if (head_ && head_->isValid()) { found(); return; } } else { // we are looking for an extension // keep the primary header primary_ = headRead(); managePrimary_ = 1; if (!(primary_ && primary_->isValid())) { error(); return; } dataSkipBlock(primary_->datablocks()); if (pExt_) { while (seek_ < filesize_) { head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } ext_++; if (head_->extname()) { char* a = toUpper(head_->extname()); char* b = toUpper(pExt_); if (!strncmp(a,b,strlen(b))) { delete [] a; delete [] b; found(); return; } delete [] a; delete [] b; } dataSkipBlock(head_->datablocks()); delete head_; head_ = NULL; } } else { for (int i=1; i<pIndex_ && seek_<filesize_; i++) { head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } ext_++; dataSkipBlock(head_->datablocks()); delete head_; head_ = NULL; } head_ = headRead(); if (head_ && head_->isValid()) { ext_++; found(); return; } } } // Must have an error error(); } void FitsFitsMapIncr::processRelax() { // check to see if there is an image in the primary head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } if (head_ && head_->isValid() && head_->naxes() > 0 && head_->naxis(0) > 0 && head_->naxis(1) > 0) { found(); return; } // ok, no image, save primary and lets check extensions primary_ = head_; managePrimary_ = 1; dataSkipBlock(head_->datablocks()); head_ = NULL; while (seek_ < filesize_) { head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } ext_++; // check for image if (head_->isImage()) { found(); return; } // else, check for compressed image if (head_->isBinTable() && head_->find("ZIMAGE")) { found(); return; } // else, check for bin table named STDEVT, EVENTS, RAYEVENT if (head_->isBinTable() && head_->extname()) { char* a = toUpper(head_->extname()); if (!strncmp("STDEVT", a, 6) || !strncmp("EVENTS", a, 6) || !strncmp("RAYEVENT", a, 8)) { delete [] a; found(); return; } else delete [] a; } // else, check for bin table with keyword PIXTYPE = 'HEALPIX ' if (head_->isBinTable() && head_->find("PIXTYPE") && (!strncmp(head_->getString("PIXTYPE"),"HEALPIX",4))) { found(); return; } // else, check for bin table with keyword NSIDE (also HEALPIX) if (head_->isBinTable() && head_->find("NSIDE")) { found(); return; } dataSkipBlock(head_->datablocks()); delete head_; head_ = NULL; } // did not find anything, bail out error(); } FitsFitsNextMapIncr::FitsFitsNextMapIncr(FitsFile* p) { FitsMapIncr* prev = (FitsMapIncr*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); coord_ = prev->coord(); xvalid_ = prev->xvalid(); xmin_ = prev->xmin(); xmax_ = prev->xmax(); yvalid_ = prev->yvalid(); ymin_ = prev->ymin(); ymax_ = prev->ymax(); zvalid_ = prev->zvalid(); zmin_ = prev->zmin(); zmax_ = prev->zmax(); filesize_ = prev->filesize(); seek_ = prev->seek(); return; } FitsArrMapIncr::FitsArrMapIncr() { if (!valid_) return; // reset valid_ = 0; // check to see if we have a nonzero width, height, and bitpix if (!validParams()) return; // check to see if dimensions equal mapped space size_t mmsize = ((size_t)pWidth_*pHeight_*pDepth_*abs(pBitpix_)/8) + pSkip_; if (mmsize > filesize_) return; // skip to start of data int fd = open(pName_, O_RDONLY); char* mmdata = (char*)mmap(NULL, mmsize, PROT_READ, MAP_SHARED, fd, 0); close(fd); // are we valid? if ((long)mmdata == -1) return; // new header head_ = new FitsHead(pWidth_, pHeight_, pDepth_, pBitpix_, mmdata, mmsize, FitsHead::ALLOC); if (!head_->isValid()) return; seek_ = mmsize; data_ = mmdata + pSkip_; dataSize_ = mapsize_; dataSkip_ = pSkip_; // do we byteswap? setByteSwap(); // made it this far, must be valid orgFits_ = 0; valid_ = 1; } FitsMosaicMapIncr::FitsMosaicMapIncr() { if (!valid_) return; // keep the primary header primary_ = headRead(); managePrimary_ = 1; if (!(primary_ && primary_->isValid())) { error(); return; } dataSkipBlock(primary_->datablocks()); // first extension head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } ext_++; found(); } FitsMosaicNextMapIncr::FitsMosaicNextMapIncr(FitsFile* p) { FitsMapIncr* prev = (FitsMapIncr*)p; pName_ = dupstr(prev->pName_); filesize_ = prev->filesize(); seek_ = prev->seek(); primary_ = prev->primary(); managePrimary_ = 0; ext_ = prev->ext(); head_ = headRead(); if (!(head_ && head_->isValid())) { error(); return; } ext_++; found(); } ���������������������������������������./saods9/saotk/fitsy++/analysis.h�������������������������������������������������������������������0000644�0001750�0001750�00000000532�11700666264�015514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsanalysis_h__ #define __fitsanalysis_h__ #include "file.h" class FitsAnalysis : public FitsFile { public: FitsAnalysis(FitsFile*); ~FitsAnalysis(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/strm.h�����������������������������������������������������������������������0000644�0001750�0001750�00000003467�12075604063�014663� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsstream_h__ #define __fitsstream_h__ #include "file.h" #include "zlib.h" typedef struct gzStream_ { z_stream zstream; int id; int transparent; unsigned char header[2]; int useHeader; unsigned char* buf; } *gzStream; template<class T> class FitsStream : public FitsFile { protected: T stream_; FitsFile::FlushMode flush_; int dataManage_; // flag, true if we manage data FitsHead* headRead(); int dataRead(size_t bytes, int validate =1); void dataSkip(size_t); void dataSkipBlock(size_t); void skipEnd(); size_t read(char*, size_t); void close(); void found(); void error(); public: FitsStream(); virtual ~FitsStream(); T stream() {return stream_;} FitsFile::FlushMode flush() {return flush_;} int dataManage() {return dataManage_;} void done() {close();} }; template<class T> class FitsFitsStream : public virtual FitsStream<T> { protected: void processExact(); void processRelax(); public: FitsFitsStream(FitsFile::ScanMode, FitsFile::FlushMode); }; template<class T> class FitsFitsNextStream : public FitsStream<T> { public: FitsFitsNextStream(FitsFile* prev); }; template<class T> class FitsArrStream : public virtual FitsStream<T> { public: FitsArrStream(FitsFile::FlushMode); }; template<class T> class FitsNRRDStream : public virtual FitsStream<T> { public: FitsNRRDStream(FitsFile::FlushMode); }; template<class T> class FitsMosaicStream : public virtual FitsStream<T> { public: FitsMosaicStream(FitsFile::FlushMode); }; template<class T> class FitsMosaicNextStream : public FitsStream<T> { public: FitsMosaicNextStream(FitsFile* prev, FitsFile::FlushMode); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/smmap.C����������������������������������������������������������������������0000644�0001750�0001750�00000002756�11700666265�014754� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include "smmap.h" FitsSMMap::FitsSMMap(const char* hdr, const char* fn) { // header { // Map the header. int file = open(hdr, O_RDONLY); if (file == -1) return; struct stat info; if (fstat(file, &info) < 0) return; // check for empty file if (info.st_size == 0) return; // map it hmapsize_ = info.st_size; hmapdata_ = (char*)mmap(NULL, hmapsize_, PROT_READ, MAP_SHARED, file, 0); // close the file close(file); // are we valid? if ((long)hmapdata_ == -1) return; } // data { // parse the fn and options parse(fn); if (!pName_) return; // Map the file. int file = open(pName_, O_RDONLY); if (file == -1) return; struct stat info; if (fstat(file, &info) < 0) return; // check for empty file if (info.st_size == 0) return; // map it mapsize_ = info.st_size; mapdata_ = (char*)mmap(NULL, mapsize_, PROT_READ, MAP_SHARED, file, 0); // close the file close(file); // are we valid? if ((long)mapdata_ == -1) return; } // so far, so good valid_ = 1; } FitsSMMap::~FitsSMMap() { if (mapdata_>0) munmap((caddr_t)mapdata_, mapsize_); } ������������������./saods9/saotk/fitsy++/lex.L������������������������������������������������������������������������0000644�0001750�0001750�00000005121�12044277032�014415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "parser.H" extern YYSTYPE* fflval; extern ffFlexLexer* fflexx; extern char ff_filter[]; #define RET(x) {strcat(ff_filter,yytext);return x;} #define CLEARFILTER {ff_filter[0]='\0';} %} %x EXT %x FILTER %x ARRAY /* rules */ %% [^[\]\t]+ { // File strcpy(fflval->str,yytext); return STRING; } \[ { // first bracket BEGIN EXT; CLEARFILTER return yytext[0]; } [ \t]+ { // White Spaces } . { // Else, return the char return yytext[0]; } <EXT>{ arch {RET(ARCH_)} array {RET(ARRAY_)} big {RET(BIG_)} bigendian {RET(BIGENDIAN_)} bin {RET(BIN_)} binkey {RET(BINKEY_)} bincol {RET(BINCOL_)} bitpix {RET(BITPIX_)} col {RET(COL_)} dim {RET(DIM_)} dims {RET(DIMS_)} ecliptic {RET(ECLIPTIC_)} endian {RET(ENDIAN_)} equatorial {RET(EQUATORIAL_)} galactic {RET(GALACTIC_)} key {RET(KEY_)} layout {RET(LAYOUT_)} little {RET(LITTLE_)} littleendian {RET(LITTLEENDIAN_)} nested {RET(NESTED_)} north {RET(NORTH_)} order {RET(ORDER_)} quad {RET(QUAD_)} ring {RET(RING_)} skip {RET(SKIP_)} south {RET(SOUTH_)} system {RET(SYSTEM_)} unknown {RET(UNKNOWN_)} xdim {RET(XDIM_)} ydim {RET(YDIM_)} zdim {RET(ZDIM_)} [-+]?[0-9]+ { // Integer fflval->integer = atoi(yytext); RET(INT) } [-+]?[0-9]+p { // Integer with PHYSICAL fflval->integer = atoi(yytext); RET(INTP) } [0-9A-Za-z_]+ { // Extn/Col Name strcpy(fflval->str,yytext); RET(STRING) } \[ { // bracket CLEARFILTER return yytext[0]; } , { // comma CLEARFILTER return yytext[0]; } [ \t]+ { // White Spaces strcat(ff_filter,yytext); } . { // Else, return the char strcat(ff_filter,yytext); return yytext[0]; } } <FILTER>.* { // rest of Filter strcpy(fflval->str,yytext); fflval->str[yyleng-1] = '\0'; // Remove the ']' strcat(ff_filter,fflval->str); return STRING; } <ARRAY>{ [-+]?[0-9]+ { // Integer fflval->integer = atoi(yytext); return INT; } . { // Else, return the char return yytext[0]; } } %% void ffFilter(int doit) { if (fflexx) fflexx->begin(FILTER, doit); } void ffArray(int doit) { if (fflexx) fflexx->begin(ARRAY, doit); } void ffFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/socket.C���������������������������������������������������������������������0000644�0001750�0001750�00000000460�11700666265�015115� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "socket.h" FitsSocket::FitsSocket(int s, const char* ext) { parse(ext); stream_ = s; if (stream_) valid_ = 1; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outchannel.C�����������������������������������������������������������������0000644�0001750�0001750�00000001157�12075604063�015763� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "outchannel.h" OutFitsChannel::OutFitsChannel(Tcl_Interp* interp, const char* ch) { int tclMode; if (ch_ = Tcl_GetChannel(interp, (char*)ch, &tclMode)) valid_ = 1; } int OutFitsChannel::write(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = Tcl_Write(ch_, where+rr, (ss>B1MB) ? B1MB : ss); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/channel.h��������������������������������������������������������������������0000644�0001750�0001750�00000003337�12041601171�015270� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitschannel_h__ #define __fitschannel_h__ #include "strm.h" class FitsChannel : public virtual FitsStream<Tcl_Channel> { public: FitsChannel(Tcl_Interp*, const char*, const char*); }; class FitsFitsChannel : public FitsChannel, public FitsFitsStream<Tcl_Channel>{ public: FitsFitsChannel(Tcl_Interp* interp, const char* ch, const char* ext, ScanMode mode, FlushMode flush) : FitsChannel(interp, ch, ext), FitsFitsStream<Tcl_Channel>(mode, flush) {} }; class FitsFitsNextChannel : public FitsFitsNextStream<Tcl_Channel> { public: FitsFitsNextChannel(FitsFile* prev) : FitsFitsNextStream<Tcl_Channel>(prev) {} }; class FitsArrChannel : public FitsChannel, FitsArrStream<Tcl_Channel> { public: FitsArrChannel(Tcl_Interp* interp, const char* ch, const char* ext, FlushMode flush) : FitsChannel(interp, ch, ext), FitsArrStream<Tcl_Channel>(flush) {} }; class FitsNRRDChannel : public FitsChannel, FitsNRRDStream<Tcl_Channel> { public: FitsNRRDChannel(Tcl_Interp* interp, const char* ch, const char* ext, FlushMode flush) : FitsChannel(interp, ch, ext), FitsNRRDStream<Tcl_Channel>(flush) {} }; class FitsMosaicChannel : public FitsChannel, FitsMosaicStream<Tcl_Channel> { public: FitsMosaicChannel(Tcl_Interp* interp, const char* ch, FlushMode flush) : FitsChannel(interp, ch, ""), FitsMosaicStream<Tcl_Channel>(flush) {} }; class FitsMosaicNextChannel : public FitsMosaicNextStream<Tcl_Channel> { public: FitsMosaicNextChannel(FitsFile* prev, FlushMode flush) : FitsMosaicNextStream<Tcl_Channel>(prev, flush) {} }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/savefits.C�������������������������������������������������������������������0000644�0001750�0001750�00000017364�12122377573�015464� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "file.h" #include "outfile.h" #include "outchannel.h" #include "outsocket.h" int FitsFile::saveFitsPrimHeader(OutFitsStream& str) { // write fake primary header char buf[FTY_BLOCK]; memset(buf,' ',FTY_BLOCK); char* hdu = buf; memcpy(hdu,"SIMPLE = ",10); memcpy(hdu+32-3,"T /",3); hdu += FTY_CARDLEN; memcpy(hdu,"BITPIX = ",10); memcpy(hdu+32-3,"8 /",3); hdu += FTY_CARDLEN; memcpy(hdu,"NAXIS = ",10); memcpy(hdu+32-3,"0 /",3); hdu += FTY_CARDLEN; memcpy(hdu,"END",3); str.write(buf, FTY_BLOCK); return FTY_BLOCK; } int FitsFile::saveFitsHeader(OutFitsStream& str, int depth) { int cnt =0; char buf[FTY_CARDLEN]; memset(buf,' ',FTY_CARDLEN); memcpy(buf,"SIMPLE = ",10); memcpy(buf+32-3,"T /",3); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; char* ptr = head()->cards()+FTY_CARDLEN; char* end = head()->cards() + head()->headbytes(); while (ptr<end) { if (!strncmp(ptr,"NAXIS ",6)) { memset(buf,' ',FTY_CARDLEN); memcpy(buf,"NAXIS = ",10); if (!depth) memcpy(buf+32-3,"2 /",3); else memcpy(buf+32-3,"3 /",3); str.write(buf, FTY_CARDLEN); } else if (!strncmp(ptr,"NAXIS2",6)) { str.write(ptr, FTY_CARDLEN); if (depth) { ostringstream ddstr; ddstr << depth << " /" << ends; const char* ddptr = ddstr.str().c_str(); int ll = strlen(ddptr); memset(buf,' ',FTY_CARDLEN); memcpy(buf,"NAXIS3 = ",10); memcpy(buf+32-ll, ddptr, ll); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; } } else if (!strncmp(ptr,"NAXIS3",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"NAXIS4",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"NAXIS5",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"PCOUNT",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"GCOUNT",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"END ",6)) { // skip cnt -= FTY_CARDLEN; } else str.write(ptr, FTY_CARDLEN); ptr+=FTY_CARDLEN; cnt += FTY_CARDLEN; } // final END memset(buf,' ',FTY_CARDLEN); memcpy(buf,"END",3); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; cnt += saveFitsPad(str,cnt,' '); return cnt; } int FitsFile::saveFitsXtHeader(OutFitsStream& str, int depth) { // write xtension header // the header may be an xtension, or primary, so lets force a // first line of 'SIMPLE' and then write the rest of the header int cnt =0; char buf[FTY_CARDLEN]; memset(buf,' ',FTY_CARDLEN); memcpy(buf,"XTENSION= 'IMAGE '",20); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; char* ptr = head()->cards()+FTY_CARDLEN; char* end = head()->cards() + head()->headbytes(); while (ptr<end) { if (!strncmp(ptr,"NAXIS ",6)) { memset(buf,' ',FTY_CARDLEN); memcpy(buf,"NAXIS = ",10); if (!depth) memcpy(buf+32-3,"2 /",3); else memcpy(buf+32-3,"3 /",3); str.write(buf, FTY_CARDLEN); } else if (!strncmp(ptr,"NAXIS2",6)) { str.write(ptr, FTY_CARDLEN); if (depth) { ostringstream ddstr; ddstr << depth << " /" << ends; const char* ddptr = ddstr.str().c_str(); int ll = strlen(ddptr); memset(buf,' ',FTY_CARDLEN); memcpy(buf,"NAXIS3 = ",10); memcpy(buf+32-ll, ddptr, ll); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; } memset(buf,' ',FTY_CARDLEN); memcpy(buf,"PCOUNT = ",10); memcpy(buf+32-3,"0 /",3); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; memset(buf,' ',FTY_CARDLEN); memcpy(buf,"GCOUNT = ",10); memcpy(buf+32-3,"1 /",3); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; } else if (!strncmp(ptr,"NAXIS3",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"NAXIS4",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"NAXIS5",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"PCOUNT",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"GCOUNT",6)) { // skip cnt -= FTY_CARDLEN; } else if (!strncmp(ptr,"END ",6)) { // skip cnt -= FTY_CARDLEN; } else str.write(ptr, FTY_CARDLEN); ptr+=FTY_CARDLEN; cnt += FTY_CARDLEN; } // final END memset(buf,' ',FTY_CARDLEN); memcpy(buf,"END",3); str.write(buf, FTY_CARDLEN); cnt += FTY_CARDLEN; cnt += saveFitsPad(str,cnt,' '); return cnt; } int FitsFile::saveFits(OutFitsStream& str) { FitsImageHDU* hdu = (FitsImageHDU*)(head()->hdu()); if (orgFits_) str.write((char*)data(), hdu->imgbytes()); else { switch (pArch_) { case NATIVE: if (!lsb()) str.write((char*)data(), hdu->imgbytes()); else str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix()); break; case BIG: str.write((char*)data(), hdu->imgbytes()); break; case LITTLE: str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix()); break; } } return hdu->imgbytes(); } int FitsFile::saveFitsPad(OutFitsStream& str, size_t cnt, char fil) { // write any padding char buf[FTY_BLOCK]; memset(buf,fil,FTY_BLOCK); int npad = FTY_BLOCK - (cnt % FTY_BLOCK); if (npad == FTY_BLOCK) npad = 0; if( npad > 0 ) str.write(buf, npad); return npad; } int FitsFile::saveFitsTable(OutFitsStream& str) { int cnt =0; // primary header str.write(primary()->cards(), primary()->headbytes()); cnt += primary()->headbytes(); // now, ext header str.write(head()->cards(), head()->headbytes()); cnt += head()->headbytes(); // write valid data // our data may be short (mmap or bad fits), so write valid data // then write the pad, becareful with arch, if array if (orgFits_) str.write((char*)data(), head()->allbytes()); else { switch (pArch_) { case NATIVE: if (!lsb()) str.write((char*)data(), head()->allbytes()); else str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix()); break; case BIG: str.write((char*)data(), head()->allbytes()); break; case LITTLE: str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix()); break; } } cnt += head()->allbytes(); // we may need to add a buffer to round out to block size int diff = head()->padbytes(); if (diff>0) { char* buf = new char[diff]; memset(buf,'\0',diff); str.write(buf, diff); delete [] buf; } cnt += head()->padbytes(); return cnt; } int FitsFile::saveArray(OutFitsStream& str, ArchType endian) { // only save one slice size_t size = head_->naxis(0)*head_->naxis(1)*abs(head_->bitpix()/8); int bitpix = head_->bitpix(); switch (endian) { case NATIVE: case BIG: { if (orgFits_) str.write((char*)data(), size); else { switch (pArch_) { case NATIVE: if (!lsb()) str.write((char*)data(), size); else str.writeSwap((char*)data(), size, bitpix); break; case BIG: str.write((char*)data(), size); break; case LITTLE: str.writeSwap((char*)data(), size, bitpix); break; } } } break; case LITTLE: { if (orgFits_) str.writeSwap((char*)data(), size, bitpix); else { switch (pArch_) { case NATIVE: if (!lsb()) str.writeSwap((char*)data(), size, bitpix); else str.write((char*)data(), size); break; case BIG: str.writeSwap((char*)data(), size, bitpix); break; case LITTLE: str.write((char*)data(), size); break; } } } break; } return size; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/compress.C�������������������������������������������������������������������0000644�0001750�0001750�00000032610�12107012361�015442� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "compress.h" #include "head.h" FitsCompress::FitsCompress(FitsFile* fits) { bitpix_ = fits->getInteger("ZBITPIX",0); int naxes = fits->getInteger("ZNAXIS",0); width_ = fits->getInteger("ZNAXIS1",0); height_ = fits->getInteger("ZNAXIS2",0); depth_ = fits->getInteger("ZNAXIS3",1); ww_ = fits->getInteger("ZTILE1",width_); hh_ = fits->getInteger("ZTILE2",1); dd_ = fits->getInteger("ZTILE3",1); bscale_ = fits->getReal("ZSCALE",1); bzero_ = fits->getReal("ZZERO",0); blank_ = fits->getInteger("ZBLANK",0); zmaskcmp_ = fits->getString("ZMASKCMP"); tilesize_ = (size_t)ww_*hh_*dd_; size_ = (size_t)width_*height_*depth_; FitsHead* srcHead = fits->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); uncompress_ = srcHDU->find("UNCOMPRESSED_DATA"); compress_ = srcHDU->find("GZIP_COMPRESSED_DATA"); if (!compress_) compress_ = srcHDU->find("COMPRESSED_DATA"); zscale_ = srcHDU->find("ZSCALE"); zzero_ = srcHDU->find("ZZERO"); zblank_ = srcHDU->find("ZBLANK"); null_ = srcHDU->find("NULL_PIXEL_MASK"); hasScaling_ = (zscale_ && zzero_) || (fits->find("ZSCALE") && fits->find("ZZERO")) ? 1 : 0; hasBlank_ = zblank_ || fits->find("ZBLANK") ? 1 : 0; } FitsCompress::~FitsCompress() { if (zmaskcmp_) delete [] zmaskcmp_; if (data_) delete [] (char*)data_; } int FitsCompress::initHeader(FitsFile* fits) { // simple check if (!compress_ || !width_ || !height_ || !bitpix_) return 0; // create header FitsHead* srcHead = fits->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); if (srcHead->find("ZTENSION")) { char* str = srcHead->getString("ZTENSION"); head_ = new FitsHead(width_, height_, depth_, bitpix_, str); delete [] str; } else head_ = new FitsHead(width_, height_, depth_, bitpix_); if (!head_->isValid()) return 0; char* ptr = srcHead->cards(); for (int ii=0; ii<srcHead->ncard(); ii++, ptr+=80) { char key[9]; key[8] = '\0'; memcpy(key,ptr,8); if (!strncmp(key,"ZIMAGE",6) || !strncmp(key,"ZCMPTYPE",8) || !strncmp(key,"ZBITPIX",7) || !strncmp(key,"ZNAXIS",6) || !strncmp(key,"ZTILE",5) || !strncmp(key,"ZNAME",5) || !strncmp(key,"ZVAL",4) || !strncmp(key,"ZMASKCMP",8) || !strncmp(key,"ZSIMPLE",7) || !strncmp(key,"ZTENSION",8) || !strncmp(key,"ZEXTEND",7) || !strncmp(key,"SIMPLE",6) || !strncmp(key,"BITPIX",6) || !strncmp(key,"NAXIS",5) || !strncmp(key,"END",3) || !strncmp(key,"XTENSION",8) || !strncmp(key,"PCOUNT",6) || !strncmp(key,"GCOUNT",6) || !strncmp(key,"EXTEND",6) || !strncmp(key,"CHECKSUM",8) || !strncmp(key,"DATASUM",7) || !strncmp(key,"TFIELDS",7) || !strncmp(key,"TBCOL",5) || !strncmp(key,"TFORM",5) || !strncmp(key,"TSCAL",5) || !strncmp(key,"TZERO",5) || !strncmp(key,"TNULL",5) || !strncmp(key,"TTYPE",5) || !strncmp(key,"TUNIT",5) || !strncmp(key,"TDISP",5) || !strncmp(key,"THEAP",5) || !strncmp(key,"TDIM",4)) continue; // eat this one if (!strncmp(key,"EXTNAME",7)) { FitsCard cc(ptr); char* str = cc.getString(); if (str) { if (!strncmp(str,"COMPRESSED_IMAGE",8)) { delete [] str; continue; } delete [] str; } } // substitute these if (!strncmp(key,"ZBLOCK",6)) { FitsCard cc(ptr); head_->appendInteger("BLOCK",cc.getInteger(),NULL); continue; } if (!strncmp(key,"ZPCOUNT",7)) { FitsCard cc(ptr); head_->appendInteger("PCOUNT",cc.getInteger(),NULL); continue; } if (!strncmp(key,"ZGCOUNT",7)) { FitsCard cc(ptr); head_->appendInteger("GCOUNT",cc.getInteger(),NULL); continue; } if (!strncmp(key,"ZHECKSUM",8)) { FitsCard cc(ptr); char* str = cc.getString(); if (str) { head_->appendString("CHECKSUM",str,NULL); delete [] str; continue; } } if (!strncmp(key,"ZDATASUM",8)) { FitsCard cc(ptr); char* str = cc.getString(); if (str) { head_->appendString("DATASUM",str,NULL); delete [] str; continue; } } // pass these unaltered head_->cardins(ptr,NULL); } // we added cards head_->updateHDU(); // other primary_ = fits->primary(); managePrimary_ = 0; inherit_ = head_->inherit(); return 1; } template<class T> FitsCompressm<T>::FitsCompressm(FitsFile* fits) : FitsCompress(fits) {} template <class T> void FitsCompressm<T>::uncompress(FitsFile* fits) { if (!initHeader(fits)) return; if (!inflate(fits)) return; swapBytes(); // all done valid_ = 1; } template <class T> int FitsCompressm<T>::inflate(FitsFile* fits) { FitsHead* srcHead = fits->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); T* dest = new T[size_]; if (!dest) { internalError("Fitsy++ compress unable to allocate memory"); return 0; } // init image memset(dest, 0, size_*sizeof(T)); // src char* sdata = (char*)fits->data(); char* sptr = sdata; int heap = srcHDU->realbytes(); int rowlen = srcHDU->width(); int rows = srcHDU->rows(); // dest int iistart =0; int iistop =ww_; if (iistop > width_) iistop = width_; int jjstart =0; int jjstop =hh_; if (jjstop > height_) jjstop = height_; int kkstart =0; int kkstop =dd_; if (kkstop > depth_) kkstop = depth_; for (int aa=0; aa<rows; aa++, sptr+=rowlen) { // we can't use incr paging due to the location of the heap // sptr = fits->page(sptr, rowlen); if (compress_) if (!compressed(dest, sptr, sdata+heap, kkstart, kkstop, jjstart, jjstop, iistart, iistop)) return 0; if (uncompress_) { int ocnt=0; T* obuf = (T*)(((FitsBinColumnArray*)uncompress_)->get(sdata+heap, sptr, &ocnt)); // obuf can be NULL if (obuf && ocnt>0) { int ll=0; for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*width_*height_ + jj*width_ + ii] = obuf[ll]; } } // tiles may not be an even multiple of the image size iistart += ww_; iistop += ww_; if (iistop > width_) iistop = width_; if (iistart >= width_) { iistart = 0; iistop = ww_; if (iistop > width_) iistop = width_; jjstart += hh_; jjstop += hh_; if (jjstop > height_) jjstop = height_; if (jjstart >= height_) { jjstart = 0; jjstop = hh_; if (jjstop > height_) jjstop = height_; kkstart += dd_; kkstop += dd_; // we only do up to 3 dimensions if (kkstart >= depth_) break; } } } // we can't use incr paging due to the location of the heap // fits->resetpage(); data_ = dest; dataSize_ = size_; dataSkip_ = 0; return 1; } template<class T> void FitsCompressm<T>::swapBytes() { if (byteswap_) { T* dest = (T*)data_; for (int i=0; i<size_; i++) dest[i] = swap(dest+i); } } template <> unsigned char FitsCompressm<unsigned char>::swap(unsigned char* ptr) { return *ptr; } template <> short FitsCompressm<short>::swap(short* ptr) { const char* p = (const char*)ptr; union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> unsigned short FitsCompressm<unsigned short>::swap(unsigned short* ptr) { const char* p = (const char*)ptr; union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> int FitsCompressm<int>::swap(int* ptr) { const char* p = (const char*)ptr; union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> long long FitsCompressm<long long>::swap(long long* ptr) { const char* p = (const char*)ptr; union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> float FitsCompressm<float>::swap(float* ptr) { const char* p = (const char*)ptr; union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.f; } template <> double FitsCompressm<double>::swap(double* ptr) { const char* p = (const char*)ptr; union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.d; } // getValue char template <class T> T FitsCompressm<T>::getValue(char* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(char* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(char* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } // getValue short template <class T> T FitsCompressm<T>::getValue(short* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(short* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(short* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } // getValue int template <class T> T FitsCompressm<T>::getValue(int* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(int* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(int* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } // getValue long long template <class T> T FitsCompressm<T>::getValue(long long* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(long long* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(long long* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } // getValue float template <class T> T FitsCompressm<T>::getValue(float* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(float* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(float* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } // getValue double template <class T> T FitsCompressm<T>::getValue(double* ptr, double zs, double zz, int blank) { return hasScaling_ ? T((*ptr)*zs + zz) : *ptr; } template <> float FitsCompressm<float>::getValue(double* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template <> double FitsCompressm<double>::getValue(double* ptr, double zs, double zz, int blank) { if (!hasBlank_ && !hasScaling_) return *ptr; if (hasBlank_ && *ptr == blank) return NAN; return hasScaling_ ? (*ptr)*zs + zz : *ptr; } template class FitsCompressm<unsigned char>; template class FitsCompressm<short>; template class FitsCompressm<unsigned short>; template class FitsCompressm<int>; template class FitsCompressm<long long>; template class FitsCompressm<float>; template class FitsCompressm<double>; FitsCompressNext::FitsCompressNext(FitsFile* p) { FitsCompress* prev = (FitsCompress*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = head_->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); return; } ������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/map.h������������������������������������������������������������������������0000644�0001750�0001750�00000002063�12041601171�014430� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsmap_h__ #define __fitsmap_h__ #include "file.h" class FitsMap : public FitsFile { protected: char* mapdata_; size_t mapsize_; public: FitsMap(); virtual ~FitsMap() {} char* mapdata() {return mapdata_;} size_t mapsize() {return mapsize_;} void found(char*); void error(); char* enddata(); size_t endsize(); }; class FitsFitsMap : public virtual FitsMap { protected: void processExact(); void processRelax(); public: FitsFitsMap(ScanMode); }; class FitsFitsNextMap : public FitsMap { public: FitsFitsNextMap(FitsFile* prev); }; class FitsArrMap : public virtual FitsMap { public: FitsArrMap(); }; class FitsNRRDMap : public virtual FitsMap { public: FitsNRRDMap(); }; class FitsMosaicMap : public virtual FitsMap { public: FitsMosaicMap(); }; class FitsMosaicNextMap : public FitsMap { public: FitsMosaicNextMap(FitsFile* prev); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrd.C�����������������������������������������������������������������������0000644�0001750�0001750�00000010260�12107012361�014551� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "nrrd.h" #include "head.h" FitsNRRD::FitsNRRD(FitsFile* fits) { bitpix_ = fits->pBitpix(); width_ = fits->pWidth(); height_ = fits->pHeight(); depth_ = fits->pDepth(); size_ = (size_t)width_*height_*depth_; } FitsNRRD::~FitsNRRD() { if (data_) delete [] (char*)data_; } int FitsNRRD::initHeader(FitsFile* fits) { // simple check if (!width_ || !height_ || !bitpix_) return 0; // create header head_ = new FitsHead(width_, height_, depth_, bitpix_); if (!head_->isValid()) return 0; // other primary_ = fits->primary(); managePrimary_ = 0; inherit_ = head_->inherit(); return 1; } template<class T> FitsNRRDm<T>::FitsNRRDm(FitsFile* fits) : FitsNRRD(fits) {} template <class T> void FitsNRRDm<T>::uncompress(FitsFile* fits) { if (!initHeader(fits)) return; T* dest = new T[size_]; if (!dest) { internalError("Fitsy++ nrrd unable to allocate memory"); return; } memset(dest, 0, size_*sizeof(T)); compressed(dest, (char*)fits->data(), fits->dataSize()-fits->dataSkip()); data_ = dest; dataSize_ = size_; dataSkip_ = 0; swapBytes(fits->pArch()); // all done valid_ = 1; } template<class T> void FitsNRRDm<T>::swapBytes(FitsFile::ArchType arch) { switch (arch) { case FitsFile::NATIVE: break; case FitsFile::BIG: if (!byteswap_) { T* dest = (T*)data_; for (int i=0; i<size_; i++) dest[i] = swap(dest+i); } break; case FitsFile::LITTLE: if (byteswap_) { T* dest = (T*)data_; for (int i=0; i<size_; i++) dest[i] = swap(dest+i); } break; } } template <> unsigned char FitsNRRDm<unsigned char>::swap(unsigned char* ptr) { return *ptr; } template <> short FitsNRRDm<short>::swap(short* ptr) { const char* p = (const char*)ptr; union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> unsigned short FitsNRRDm<unsigned short>::swap(unsigned short* ptr) { const char* p = (const char*)ptr; union { char c[2]; unsigned short s; } u; u.c[1] = *p++; u.c[0] = *p; return u.s; } template <> int FitsNRRDm<int>::swap(int* ptr) { const char* p = (const char*)ptr; union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> long long FitsNRRDm<long long>::swap(long long* ptr) { const char* p = (const char*)ptr; union { char c[8]; long long i; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.i; } template <> float FitsNRRDm<float>::swap(float* ptr) { const char* p = (const char*)ptr; union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.f; } template <> double FitsNRRDm<double>::swap(double* ptr) { const char* p = (const char*)ptr; union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.d; } template class FitsNRRDm<unsigned char>; template class FitsNRRDm<short>; template class FitsNRRDm<unsigned short>; template class FitsNRRDm<int>; template class FitsNRRDm<long long>; template class FitsNRRDm<float>; template class FitsNRRDm<double>; FitsNRRDNext::FitsNRRDNext(FitsFile* p) { FitsNRRD* prev = (FitsNRRD*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); pNRRDEncoding_ = prev->pNRRDEncoding(); pNRRDDimension_ = prev->pNRRDDimension(); return; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hpx.C������������������������������������������������������������������������0000644�0001750�0001750�00000040615�12107012361�014412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" // This source has been modified from the original authored by // Dr. Mark Calabretta as distributed with WCSLIBS under GNU GPL version 3 // WCSLIB 4.7 - an implementation of the FITS WCS standard. // Copyright (C) 1995-2011, Mark Calabretta #include <string.h> #include <ctype.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "hpx.h" #include "util.h" #include "fitsy.h" FitsHPX::FitsHPX(FitsFile* fits, Order oo, CoordSys ss, Layout ll, int cc, int qq) : order_(oo), coord_(ss), layout_(ll), quad_(qq) { FitsHead* head = fits->head(); FitsTableHDU* hdu = (FitsTableHDU*)(head->hdu()); col_ = (FitsBinColumn*)hdu->find(cc); if (!col_) return; int nrow = hdu->rows(); int nelem = col_->repeat(); nside_ = head->getInteger("NSIDE",0); long firstpix = head->getInteger("FIRSTPIX",-1); long lastpix = head->getInteger("LASTPIX",-1); if (!nside_) // If LASTPIX is present without NSIDE we can only assume it's npix. if (lastpix >= 0) nside_ = (int)(sqrt((double)((lastpix+1) / 12)) + 0.5); else if (nrow) nside_ = (int)(sqrt((double)((nrow * nelem) / 12)) + 0.5); long npix = 12*nside_*nside_; if (firstpix < 0) firstpix = 0; if (lastpix < 0) lastpix = npix - 1; // Number of facets on a side of each layout. const int NFACET[] = {5, 4, 4}; nfacet_ = NFACET[layout_]; width_ = nfacet_*nside_; height_ = width_; size_ = (size_t)width_*height_; if (!initHeader(fits)) return; build(fits); if (byteswap_) swap(); valid_ = 1; } FitsHPX::~FitsHPX() { if (data_) delete [] (float*)data_; } void FitsHPX::build(FitsFile* fits) { FitsHead* head = fits->head(); FitsTableHDU* hdu = (FitsTableHDU*)(head->hdu()); int rowlen = hdu->width(); int nrow = hdu->rows(); int nelem = col_->repeat(); char* data = (char*)fits->data(); // create image space float* dest = new float[size_]; for (longlong ii=0; ii<size_; ii++) dest[ii] = NAN; // Arrays that define the facet location and rotation for each recognised // layout. Bear in mind that these appear to be upside-down, i.e. the top // line contains facet numbers for the bottom row of the output image. // Facets numbered -1 are blank. // Equatorial (diagonal) facet layout. const int FACETS[][5][5] = {{{ 6, 9, -1, -1, -1}, { 1, 5, 8, -1, -1}, {-1, 0, 4, 11, -1}, {-1, -1, 3, 7, 10}, {-1, -1, -1, 2, 6}}, // North polar (X) facet layout. {{ 8, 4, 4, 11, -1}, { 5, 0, 3, 7, -1}, { 5, 1, 2, 7, -1}, { 9, 6, 6, 10, -1}, {-1, -1, -1, -1, -1}}, // South polar (X) facet layout. {{ 1, 6, 6, 2, -1}, { 5, 9, 10, 7, -1}, { 5, 8, 11, 7, -1}, { 0, 4, 4, 3, -1}, {-1, -1, -1, -1, -1}}}; // All facets of the equatorial layout are rotated by +45 degrees with // respect to the normal orientation, i.e. that with the equator running // horizontally. The rotation recorded for the polar facets is the number // of additional positive (anti-clockwise) 90 degree turns with respect to // the equatorial layout. // Equatorial (diagonal), no facet rotation. const int FROTAT[][5][5] = {{{ 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}}, // North polar (X) facet rotation. {{ 3, 3, 0, 0, 0}, { 3, 3, 0, 0, 0}, { 2, 2, 1, 1, 0}, { 2, 2, 1, 1, 0}, { 0, 0, 0, 0, 0}}, // South polar (X) facet rotation. {{ 1, 1, 2, 2, 0}, { 1, 1, 2, 2, 0}, { 0, 0, 3, 3, 0}, { 0, 0, 3, 3, 0}, { 0, 0, 0, 0, 0}}}; // Facet halving codes. 0: the facet is whole (or wholly blank), // 1: blanked bottom-right, 2: top-right, 3: top-left, 4: bottom-left. // Positive values mean that the diagonal is included, otherwise not. // Equatorial (diagonal), no facet halving. const int FHALVE[][5][5] = {{{ 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}}, // North polar (X) facet halving. {{ 0, 1, -4, 0, 0}, {-3, 0, 0, 2, 0}, { 4, 0, 0, -1, 0}, { 0, -2, 3, 0, 0}, { 0, 0, 0, 0, 0}}, // South polar (X) facet halving. {{ 0, 1, -4, 0, 0}, {-3, 0, 0, 2, 0}, { 4, 0, 0, -1, 0}, { 0, -2, 3, 0, 0}, { 0, 0, 0, 0, 0}}}; // Allocate arrays long healidx[nside_]; float row[nside_]; // Loop vertically facet-by-facet. longlong fpixel = 0; for (int jfacet = 0; jfacet<nfacet_; jfacet++) { // Loop row-by-row. for (int jj = 0; jj<nside_; jj++) { // Loop horizontally facet-by-facet for (int ifacet = 0; ifacet<nfacet_; ifacet++, fpixel += nside_) { int facet = FACETS[layout_][jfacet][ifacet]; int rotn = FROTAT[layout_][jfacet][ifacet]; int halve = FHALVE[layout_][jfacet][ifacet]; // Recentre longitude? if (quad_ && facet >= 0) { if (facet <= 3) { facet += quad_; if (facet > 3) facet -= 4; } else if (facet <= 7) { facet += quad_; if (facet > 7) facet -= 4; } else { facet += quad_; if (facet > 11) facet -= 4; } } // Write out the data if (facet >= 0) { switch (order_) { case NESTED: NESTidx(facet, rotn, jj, healidx); break; case RING: RINGidx(facet, rotn, jj, healidx); break; } // Gather data into the output vector. for (int ii=0; ii<nside_; ii++) { int aa = healidx[ii]/nelem; int bb = healidx[ii] - (aa*nelem); if (aa<nrow) row[ii] = col_->value(data+aa*rowlen,bb); else row[ii] = 0; } // Apply blanking to halved facets. if (halve) { int i1; int i2; if (abs(halve) == 1) { // Blank bottom-right. i1 = jj; i2 = nside_; if (halve > 0) i1++; } else if (abs(halve) == 2) { // Blank top-right. i1 = nside_ - jj; i2 = nside_; if (halve < 0) i1--; } else if (abs(halve) == 3) { // Blank top-left. i1 = 0; i2 = jj; if (halve < 0) i2++; } else { // Blank bottom-left. i1 = 0; i2 = nside_ - jj; if (halve > 0) i2--; } for (int ii=i1; ii<i2; ii++) row[ii] = NAN; } // Write out this facet's contribution to this row of the map. memcpy(dest+fpixel, row, nside_*sizeof(float)); } } } } data_ = dest; dataSize_ = size_; dataSkip_ = 0; } // (imap,jmap) are 0-relative pixel coordinates in the output map with origin // at the bottom-left corner of the specified facet which is rotated by // (45 + rotn * 90) degrees from its natural orientation; imap increases to // the right and jmap upwards. void FitsHPX::NESTidx(int facet, int rotn, int jmap, long *healidx) { // Nested index (0-relative) of the first pixel in this facet. int hh = facet*nside_*nside_; int nside1 = nside_ - 1; long* hp = healidx; for (int imap = 0; imap < nside_; imap++, hp++) { // (ii,jj) are 0-relative pixel coordinates with origin in the southern // corner of the facet; i increases to the north-east and j to the // north-west. int ii,jj; if (rotn == 0) { ii = nside1 - imap; jj = jmap; } else if (rotn == 1) { ii = nside1 - jmap; jj = nside1 - imap; } else if (rotn == 2) { ii = imap; jj = nside1 - jmap; } else if (rotn == 3) { ii = jmap; jj = imap; } *hp = 0; int bit = 1; while (ii || jj) { if (ii & 1) *hp |= bit; bit <<= 1; if (jj & 1) *hp |= bit; bit <<= 1; ii >>= 1; jj >>= 1; } *hp += hh; } } // (imap,jmap) pixel coordinates are as described above for NESTidx(). This // function computes the double-pixelisation index then converts it to the // regular ring index. void FitsHPX::RINGidx(int facet, int rotn, int jmap, long *healidx) { const int I0[] = { 1, 3, -3, -1, 0, 2, 4, -2, 1, 3, -3, -1}; const int J0[] = { 1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, -1}; int n2side = 2 * nside_; int n8side = 8 * nside_; // Double-pixelisation index of the last pixel in the north polar cap. */ int npole = (n2side - 1) * (n2side - 1) - 1; // Double-pixelisation pixel coordinates of the centre of the facet. */ int i0 = nside_ * I0[facet]; int j0 = nside_ * J0[facet]; int nside1 = nside_ - 1; long* hp = healidx; for (int imap = 0; imap < nside_; imap++, hp++) { // (ii,jj) are 0-relative, double-pixelisation pixel coordinates. The // origin is at the intersection of the equator and prime meridian, // i increases to the east (N.B.) and j to the north. int ii, jj; if (rotn == 0) { ii = i0 + nside1 - (jmap + imap); jj = j0 + jmap - imap; } else if (rotn == 1) { ii = i0 + imap - jmap; jj = j0 + nside1 - (imap + jmap); } else if (rotn == 2) { ii = i0 + (imap + jmap) - nside1; jj = j0 + imap - jmap; } else if (rotn == 3) { ii = i0 + jmap - imap; jj = j0 + jmap + imap - nside1; } // Convert i for counting pixels if (ii < 0) ii += n8side; ii++; if (jj > nside_) { // North polar regime. if (jj == n2side) { *hp = 0; } else { // Number of pixels in a polar facet with this value of jj. int npj = 2 * (n2side - jj); // Index of the last pixel in the row above this. *hp = (npj - 1) * (npj - 1) - 1; // Number of pixels in this row in the polar facets before this. *hp += npj * (ii/n2side); // Pixel number in this polar facet. *hp += ii%n2side - (jj - nside_) - 1; } } else if (jj >= -nside_) { // Equatorial regime. *hp = npole + n8side * (nside_ - jj) + ii; } else { // South polar regime. *hp = 24 * nside_ * nside_ + 1; if (jj > -n2side) { // Number of pixels in a polar facet with this value of jj. int npj = 2 * (jj + n2side); // Total number of pixels in this row or below it. *hp -= (npj + 1) * (npj + 1); // Number of pixels in this row in the polar facets before this. *hp += npj * (ii/n2side); // Pixel number in this polar facet. *hp += ii%n2side + (nside_ + jj) - 1; } } // Convert double-pixelisation index to regular. *hp -= 1; *hp /= 2; } } int FitsHPX::initHeader(FitsFile* fits) { FitsHead* src = fits->head(); // create header head_ = new FitsHead(width_, height_, 1, -32); if (!head_->isValid()) return 0; // OBJECT char* object = src->getString("OBJECT"); if (object) { head_->appendString("OBJECT", object, NULL); delete [] object; } // CRPIX1/2 float crpix1; switch (layout_) { case EQUATOR: crpix1 = (5 * nside_ + 1) / 2.0f; break; case NORTH: case SOUTH: crpix1 = (4 * nside_ + 1) / 2.0f; break; } float crpix2 = crpix1; head_->appendReal("CRPIX1", crpix1, 8, "Coordinate reference pixel"); head_->appendReal("CRPIX2", crpix2, 8, "Coordinate reference pixel"); // PCx_y if (layout_ == EQUATOR) { head_->appendReal("PC1_1", 0.5f, 1, "Transformation matrix element"); head_->appendReal("PC1_2", 0.5f, 1, "Transformation matrix element"); head_->appendReal("PC2_1", -0.5f, 1, "Transformation matrix element"); head_->appendReal("PC2_2", 0.5f, 1, "Transformation matrix element"); } // CDELT1/2 float cdelt1 = -90.0 / nside_; float cdelt2 = -cdelt1; head_->appendReal("CDELT1", cdelt1, 8, "[deg] Coordinate increment"); head_->appendReal("CDELT2", cdelt2, 8, "[deg] Coordinate increment"); // CTYPE1/2 const char* pcode; switch (layout_) { case EQUATOR: pcode = "HPX"; break; case NORTH: case SOUTH: pcode = "XPH"; break; } const char* ctype1; const char* ctype2; const char* descr1; const char* descr2; switch (coord_) { case EQU: ctype1 = "RA--"; ctype2 = "DEC-"; descr1 = "Right ascension"; descr2 = "Declination"; break; case GAL: ctype1 = "GLON"; ctype2 = "GLAT"; descr1 = "Galactic longitude"; descr2 = "Galactic latitude"; break; case ECL: ctype1 = "ELON"; ctype2 = "ELAT"; descr1 = "Ecliptic longitude"; descr2 = "Ecliptic latitude"; break; case UNKNOWN: ctype1 = "XLON"; ctype2 = "XLAT"; descr1 = "Longitude"; descr2 = " Latitude"; } { ostringstream cval; cval << ctype1 << '-' << pcode << ends; ostringstream comm; comm << descr1 << " in an " << pcode << " projection" << ends; head_->appendString("CTYPE1", cval.str().c_str(), comm.str().c_str()); } { ostringstream cval; cval << ctype2 << '-' << pcode << ends; ostringstream comm; comm << descr2 << " in an " << pcode << " projection" << ends; head_->appendString("CTYPE2", cval.str().c_str(), comm.str().c_str()); } // CRVAL1/CRVAL2 float crval1 = 0 + 90*quad_; float crval2; switch (layout_) { case EQUATOR: crval2 = 0; break; case NORTH: crval2 = 90; break; case SOUTH: crval2 = -90; break; } { ostringstream comm; comm << "[deg] " << descr1 << " at the reference point" << ends; head_->appendReal("CRVAL1", crval1, 8, comm.str().c_str()); } { ostringstream comm; comm << "[deg] " << descr2 << " at the reference point" << ends; head_->appendReal("CRVAL2", crval2, 8, comm.str().c_str()); } // PV2_1/2 switch (layout_) { case EQUATOR: head_->appendInteger("PV2_1", 4, "HPX H parameter (longitude)"); head_->appendInteger("PV2_2", 3, "HPX K parameter (latitude)"); break; case NORTH: case SOUTH: break; } // we added cards head_->updateHDU(); } void FitsHPX::swap() { if (!data_) return; // we now need to byteswap back to native form float* dest = (float*)data_; for (int i=0; i<size_; i++) { const char* p = (char*)(dest+i); union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; dest[i] = u.f; } } FitsHPXNext::FitsHPXNext(FitsFile* prev) { primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); pHPXOrder_ = prev->pHPXColumn(); pHPXSystem_ = prev->pHPXColumn(); pHPXLayout_ = prev->pHPXColumn(); pHPXColumn_ = prev->pHPXColumn(); pHPXQuad_ = prev->pHPXQuad(); return; } �������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/alloc.h����������������������������������������������������������������������0000644�0001750�0001750�00000002635�12041601171�014752� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsalloc_h__ #define __fitsalloc_h__ #include "strm.h" class FitsAlloc : public virtual FitsStream<FILE*> { public: FitsAlloc(const char*); virtual ~FitsAlloc() {} }; class FitsFitsAlloc : public FitsAlloc, public FitsFitsStream<FILE*> { public: FitsFitsAlloc(const char* fn, ScanMode mode, FlushMode flush) : FitsAlloc(fn), FitsFitsStream<FILE*>(mode, flush) {} }; class FitsFitsNextAlloc : public FitsFitsNextStream<FILE*> { public: FitsFitsNextAlloc(FitsFile* prev) : FitsFitsNextStream<FILE*>(prev) {} }; class FitsArrAlloc : public FitsAlloc, FitsArrStream<FILE*> { public: FitsArrAlloc(const char* fn, FlushMode flush) : FitsAlloc(fn), FitsArrStream<FILE*>(flush) {} }; class FitsNRRDAlloc : public FitsAlloc, FitsNRRDStream<FILE*> { public: FitsNRRDAlloc(const char* fn, FlushMode flush) : FitsAlloc(fn), FitsNRRDStream<FILE*>(flush) {} }; class FitsMosaicAlloc : public FitsAlloc, FitsMosaicStream<FILE*> { public: FitsMosaicAlloc(const char* fn, FlushMode flush) : FitsAlloc(fn), FitsMosaicStream<FILE*>(flush) {} }; class FitsMosaicNextAlloc : public FitsMosaicNextStream<FILE*> { public: FitsMosaicNextAlloc(FitsFile* prev, FlushMode flush) : FitsMosaicNextStream<FILE*>(prev, flush) {} }; #endif ���������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/analysis.C�������������������������������������������������������������������0000644�0001750�0001750�00000002112�12075360500�015431� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "analysis.h" FitsAnalysis::FitsAnalysis(FitsFile* src) { primary_ = src->primary(); managePrimary_ = 0; head_ = new FitsHead(*(src->head())); manageHead_ = 1; ext_ = src->ext(); inherit_ = src->inherit(); byteswap_ = 0; // change bitpix to double head_->setInteger("BITPIX", -64, ""); // unset BZERO/BSCALE if present if (head_->find("BZERO")) head_->setReal("BZERO",0,2,NULL); if (head_->find("BSCALE")) head_->setReal("BSCALE",1,2,NULL); head_->updateHDU(); int width = head_->naxis(0); int height = head_->naxis(1); // alloc memory size_t size = (size_t)width*height; data_ = new double[size]; if (!data_) return; dataSize_ = size; dataSkip_ = 0; // clear memory memset(data_, 0, size*sizeof(double)); // made it this far, must be valid orgFits_ = 0; valid_ = 1; } FitsAnalysis::~FitsAnalysis() { if (data_) delete [] (char*)data_; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/card.C�����������������������������������������������������������������������0000644�0001750�0001750�00000012423�12012245442�014523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "card.h" FitsCard::FitsCard() { card_ = new char[FTY_CARDLEN]; managed = 1; } FitsCard::FitsCard(char* c) { card_ = c; managed = 0; } FitsCard::FitsCard(const FitsCard& a) { card_ = new char[FTY_CARDLEN]; managed = 1; memcpy(card_, a.card_, FTY_CARDLEN); } FitsCard::~FitsCard() { if (managed) delete [] card_; } FitsCard& FitsCard::operator=(const FitsCard& a) { memcpy(card_, a.card_, FTY_CARDLEN); return *this; } FitsCard& FitsCard::clear() { memset(card_, ' ', FTY_CARDLEN); return *this; } FitsCard& FitsCard::setKey(const char* name) { if (name) { memset(card_, ' ', 8); ostringstream str; str << name; memcpy(card_,str.str().c_str(),str.str().length()); } return *this; } FitsCard& FitsCard::setLogical(const char* name, int value, const char* comment) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= " << (value ? 'T' : 'F'); if (comment) str << " / " << comment; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } FitsCard& FitsCard::setInteger(const char* name, int value, const char* comment) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= " << setw(20) << value; if (comment) str << " / " << comment; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } FitsCard& FitsCard::setReal(const char* name, double value, int prec, const char* comment) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= " << setw(20) << setprecision(prec) << value; if (comment) str << " / " << comment; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } FitsCard& FitsCard::setComplex(const char* name, double real, double img, int prec, const char* comment) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= " << setw(20) << setprecision(prec) << real << img; if (comment) str << " / " << comment; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } FitsCard& FitsCard::setString(const char* name, const char* value, const char* comment) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= '" << value << '\''; if (comment) str << " / " << comment; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } FitsCard& FitsCard::setComment(const char* name, const char* value) { setKey(name); memset(card_+8, ' ', FTY_CARDLEN-8); ostringstream str; str << "= " << value; memcpy(card_+8,str.str().c_str(),str.str().length()); return *this; } int FitsCard::getLogical() { for (int i=10; i<80; i++) if (card_[i] != ' ') return (card_[i] == 'T' || card_[i] == 't'); return 0; } int FitsCard::getInteger() { string x(card_+10,FTY_CARDLEN-10); istringstream str(x); int r; str >> r; return r; } double FitsCard::getReal() { // support 'D' as well as 'E' format char buf[FTY_CARDLEN-10+1]; memcpy(buf, card_+10, FTY_CARDLEN-10); buf[FTY_CARDLEN-10] = '\0'; char* ptr = buf; while (*ptr && *ptr != '/') { if (*ptr == 'D' || *ptr == 'E') { *ptr = 'E'; break; } ptr++; } string x(buf,FTY_CARDLEN-10); istringstream str(x); double r; str >> r; return r; } void FitsCard::getComplex(double* r, double* i) { // support 'D' as well as 'E' format char buf[FTY_CARDLEN-10+1]; memcpy(buf, card_+10, FTY_CARDLEN-10); buf[FTY_CARDLEN-10] = '\0'; char* ptr = buf; while (*ptr && *ptr != '/') { if (*ptr == 'D' || *ptr == 'E') { *ptr = 'E'; } ptr++; } string x(buf,FTY_CARDLEN-10); istringstream str(x); str >> *r >> *i; } char* FitsCard::getString() { char value[FTY_CARDLEN]; value[0] = '\0'; value[FTY_CARDLEN-1] = '\0'; int i,j; // find first ' for (i=10; i<FTY_CARDLEN; i++) if (card_[i] == '\'') break; // now find last ' i++; for (j=0; i<FTY_CARDLEN; i++,j++) { if (card_[i] == '\'') if (i+1 == FTY_CARDLEN || card_[i+1] != '\'') break; else i++; value[j] = card_[i]; } // DON'T strip any spaces // for (; j && value[j-1]==' '; j--); value[j] = '\0'; // return result char* cpy = new char[strlen(value)+1]; strcpy(cpy, value); return cpy; } char* FitsCard::getComment() { char* cpy = new char[FTY_CARDLEN-7]; memcpy(cpy, card_+8, FTY_CARDLEN-8); cpy[FTY_CARDLEN-8] = '\0'; return cpy; } char* FitsCard::getAsString() { char value[FTY_CARDLEN]; value[0] = '\0'; int ii,jj; int str =0; for (ii=10; ii<FTY_CARDLEN; ii++) { if (card_[ii] != ' ') { if (card_[ii] == '\'' || card_[ii] == '\"') { str = 1; ii++; } break; } } for (jj=0; ii<FTY_CARDLEN; ii++,jj++) { if (!str) { if (card_[ii] == '/') break; } else { if (card_[ii] == '\'' || card_[ii] == '\"') break; } value[jj] = card_[ii]; } // strip any spaces for (; jj && value[jj-1]==' '; jj--); value[jj] = '\0'; // return result char* cpy = new char[strlen(value)+1]; strcpy(cpy, value); return cpy; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/gzraw.h����������������������������������������������������������������������0000644�0001750�0001750�00000000667�12106546556�015036� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsgzraw_h__ #define __fitsgzraw_h__ #include "compress.h" template<class T> class FitsGzrawm : public FitsCompressm<T> { private: int compressed(T*, char*, char*, int, int, int, int, int, int); T swap(T*); public: FitsGzrawm(FitsFile*); }; #endif �������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdlex.L��������������������������������������������������������������������0000644�0001750�0001750�00000012005�12042560016�015275� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "nrrdparser.H" extern YYSTYPE* nrrdlval; extern nrrdFlexLexer* nrrdlexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(nrrdlval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(NRRDPARSERSIZE-1) ? yyleng:(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext,ll); nrrdlval->str[ll] = '\0'; return STRING; } debug {return DEBUG_;} on {return ON_;} off {return OFF_;} NRRD0001 {return NRRD0001_;} NRRD0002 {return NRRD0002_;} NRRD0003 {return NRRD0003_;} NRRD0004 {return NRRD0004_;} NRRD0005 {return NRRD0005_;} data {return DATA_;} file {return FILE_;} space {return SPACE_;} units {return UNITS_;} dimentions {return DIMENSIONS_;} origin {return ORIGIN_;} directions {return DIRECTIONS_;} dimension {return DIMENSION_;} type {return TYPE_;} signed {return SIGNED_;} unsigned {return UNSIGNED_;} char {return CHAR_;} int8 {return INT8_;} int8_t {return INT8_T_;} uchar {return UCHAR_;} uint8 {return UINT8_;} uint8_t {return UINT8_T_;} short {return SHORT_;} int {return INT_;} int16 {return INT16_;} int16_t {return INT16_T_;} ushort {return USHORT_;} unint16 {return UINT16_;} unint16_t {return UINT16_T_;} int32 {return INT32_;} int32_t {return INT32_T_;} uint {return UINT_;} uint32 {return UINT32_;} uint32_t {return UINT32_T_;} long {return LONG_;} longlong {return LONGLONG_;} int64 {return INT64_;} int64_t {return INT64_T_;} unlonglong {return ULONGLONG_;} unint64 {return UINT64_;} unint64_t {return UINT64_T_;} float {return FLOAT_;} double {return DOUBLE_;} block {return BLOCK_;} size {return SIZE_;} blocksize {return BLOCKSIZE_;} encoding {return ENCODING_;} raw {return RAW_;} txt {return TXT_;} text {return TEXT_;} ascii {return ASCII_;} hex {return HEX_;} gz {return GZ_;} gzip {return GZIP_;} bz2 {return BZ2_;} bzip2 {return BZIP2_;} endian {return ENDIAN_;} big {return BIG_;} little {return LITTLE_;} content {return CONTENT_;} old {return OLD_;} min {return MIN_;} oldmin {return OLDMIN_;} max {return MAX_;} oldmax {return OLDMAX_;} skip {return SKIP_;} line {return LINE_;} lineskip {return LINESKIP_;} byte {return BYTE_;} byteskip {return BYTESKIP_;} number {return NUMBER_;} sample {return SAMPLE_;} sampleunits {return SAMPLEUNITS_;} sizes {return SIZES_;} spacings {return SPACINGS_;} thickness {return THICKNESSES_;} axis {return AXIS_;} mins {return MINS_;} axismins {return AXISMINS_;} maxs {return MAXS_;} axismaxs {return AXISMAXS_;} centers {return CENTERS_;} centerings {return CENTERINGS_;} cell {return CELL_;} node {return NODE_;} none {return NONE_;} labels {return LABELS_;} kinds {return KINDS_;} domains {return DOMAINS_;} [+-]?{D}+ { // Integer nrrdlval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number nrrdlval->real = atof(yytext); return REAL; } \{[^\}\n]*\} { // Quoted String int ll = (yyleng-2)<(NRRDPARSERSIZE-1) ? (yyleng-2):(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext+1,ll); // skip the '{' nrrdlval->str[ll] = '\0'; // Remove the '}' return STRING; } [0-9A-Za-z]+ { // General String int ll = yyleng <(NRRDPARSERSIZE-1) ? yyleng:(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext,ll); nrrdlval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \\n { // fake line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return yytext[0]; } %% void nrrdDiscard(int doit) { if (nrrdlexx) nrrdlexx->begin(DISCARD, doit); } void nrrdFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mmapincr.C�������������������������������������������������������������������0000644�0001750�0001750�00000001347�12044561570�015433� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include "mmapincr.h" FitsMMapIncr::FitsMMapIncr(const char* fn) { // parse the fn and options parse(fn); if (!pName_) return; // Map the file. int fd = open(pName_, O_RDONLY); if (fd == -1) return; struct stat info; if (fstat(fd, &info) < 0) return; close(fd); // check to see if we have something, we may have a small array if (info.st_size <= 0) return; filesize_ = info.st_size; // so far, so good valid_ = 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/sshare.h���������������������������������������������������������������������0000644�0001750�0001750�00000002237�11700666265�015163� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitssshare_h__ #define __fitssshare_h__ #include "smap.h" class FitsSShareID : public virtual FitsSMap { public: FitsSShareID(int, int, const char*); virtual ~FitsSShareID(); }; class FitsSShareKey : public virtual FitsSMap { public: FitsSShareKey(int, int, const char*); virtual ~FitsSShareKey(); }; class FitsFitsSShare : public virtual FitsSMap, public FitsFitsSMap { public: FitsFitsSShare() : FitsSMap(), FitsFitsSMap(FitsHead::SHARE) {} }; class FitsFitsNextSShare : public FitsFitsNextSMap { public: FitsFitsNextSShare(FitsFile* prev) : FitsFitsNextSMap(prev) {} }; class FitsFitsSShareID : public FitsSShareID, public FitsFitsSShare { public: FitsFitsSShareID(int hdrid, int shmid, const char* filter) : FitsSShareID(hdrid, shmid, filter), FitsFitsSShare() {} }; class FitsFitsSShareKey : public FitsSShareKey, public FitsFitsSShare { public: FitsFitsSShareKey(int hdr, int key, const char* filter) : FitsSShareKey(hdr, key, filter), FitsFitsSShare() {} }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdlex.C��������������������������������������������������������������������0000644�0001750�0001750�00000211024�12047246743�015303� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "nrrdlex.C" #line 4 "nrrdlex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer nrrdFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *nrrdalloc (yy_size_t ); void *nrrdrealloc (void *,yy_size_t ); void nrrdfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 105 #define YY_END_OF_BUFFER 106 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[359] = { 0, 0, 0, 2, 2, 106, 104, 100, 103, 104, 104, 104, 95, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 104, 104, 2, 1, 100, 101, 0, 95, 97, 96, 95, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 58, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 4, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 102, 0, 98, 2, 0, 0, 0, 96, 99, 99, 63, 99, 99, 60, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 57, 29, 99, 99, 99, 99, 99, 69, 67, 99, 99, 99, 99, 5, 66, 99, 53, 99, 99, 99, 99, 99, 99, 99, 99, 54, 99, 99, 99, 99, 99, 99, 99, 96, 0, 97, 99, 82, 99, 74, 99, 89, 99, 22, 99, 11, 99, 99, 99, 99, 99, 99, 99, 12, 99, 59, 99, 99, 99, 23, 99, 99, 72, 99, 40, 85, 83, 90, 91, 99, 99, 99, 99, 99, 99, 99, 50, 71, 99, 55, 99, 19, 99, 37, 99, 99, 99, 99, 99, 56, 99, 49, 99, 61, 99, 99, 3, 99, 99, 99, 99, 99, 99, 47, 30, 35, 42, 0, 93, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 28, 99, 79, 13, 99, 99, 25, 99, 26, 99, 14, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 48, 99, 62, 0, 0, 0, 24, 92, 99, 64, 99, 99, 76, 70, 68, 16, 77, 20, 99, 99, 38, 0, 99, 99, 99, 99, 32, 99, 99, 99, 99, 99, 87, 65, 99, 99, 99, 94, 99, 31, 36, 43, 99, 99, 99, 99, 99, 99, 0, 27, 33, 45, 99, 99, 86, 84, 99, 75, 99, 99, 99, 99, 52, 73, 41, 6, 7, 8, 9, 10, 99, 80, 99, 39, 0, 0, 99, 21, 51, 99, 18, 99, 99, 99, 81, 34, 46, 99, 88, 15, 17, 99, 44, 78, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 6, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 25, 32, 33, 34, 35, 25, 36, 37, 38, 39, 1, 40, 1, 1, 41, 1, 42, 43, 44, 45, 46, 47, 48, 49, 50, 25, 51, 52, 53, 54, 55, 56, 25, 57, 58, 59, 60, 25, 61, 62, 63, 64, 65, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[67] = { 0, 1, 1, 2, 1, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1 } ; static yyconst flex_int16_t yy_base[367] = { 0, 0, 0, 1080, 1073, 1060, 1098, 1055, 1098, 1051, 1047, 60, 70, 80, 81, 91, 106, 89, 82, 85, 83, 96, 1046, 104, 135, 147, 149, 141, 158, 204, 176, 218, 69, 985, 0, 1098, 1047, 1098, 270, 166, 81, 137, 280, 1042, 322, 174, 152, 169, 201, 101, 199, 205, 210, 215, 160, 223, 290, 310, 295, 292, 244, 291, 305, 314, 296, 306, 340, 346, 318, 347, 352, 345, 350, 351, 360, 1040, 358, 197, 356, 355, 382, 362, 377, 353, 383, 386, 385, 390, 389, 405, 411, 1098, 979, 1098, 0, 1039, 1038, 457, 467, 434, 429, 1036, 408, 195, 1035, 430, 477, 479, 482, 483, 484, 485, 486, 487, 489, 491, 488, 497, 490, 493, 492, 1034, 441, 496, 505, 510, 506, 522, 513, 516, 544, 546, 518, 551, 1032, 547, 554, 1026, 548, 549, 553, 552, 555, 571, 561, 578, 1023, 563, 572, 567, 574, 587, 581, 591, 640, 649, 658, 668, 585, 593, 579, 87, 1022, 669, 1021, 670, 1013, 671, 672, 673, 674, 675, 676, 678, 1012, 677, 1011, 86, 239, 259, 98, 679, 680, 681, 682, 698, 1010, 1009, 1008, 1005, 257, 702, 707, 704, 724, 699, 723, 729, 1004, 732, 955, 734, 949, 735, 438, 736, 738, 739, 741, 740, 889, 749, 747, 753, 841, 758, 755, 840, 768, 760, 769, 794, 782, 801, 837, 265, 267, 269, 391, 771, 775, 777, 804, 805, 297, 780, 807, 810, 812, 811, 700, 823, 697, 694, 816, 819, 693, 418, 381, 610, 691, 814, 832, 815, 828, 846, 847, 848, 852, 845, 853, 857, 872, 850, 690, 876, 639, 576, 833, 850, 1098, 637, 882, 635, 883, 618, 634, 633, 630, 626, 881, 624, 895, 874, 521, 859, 621, 354, 907, 905, 623, 909, 913, 885, 908, 915, 495, 453, 893, 920, 922, 436, 925, 1098, 1098, 1098, 923, 934, 975, 939, 930, 932, 899, 1098, 921, 929, 966, 947, 431, 425, 954, 422, 972, 951, 970, 983, 417, 348, 315, 311, 303, 301, 299, 261, 985, 255, 989, 1098, 964, 967, 996, 237, 231, 997, 181, 998, 1000, 1002, 172, 1098, 1098, 991, 163, 161, 109, 1001, 94, 88, 1098, 1061, 1065, 1067, 1074, 1081, 1084, 1089, 1092 } ; static yyconst flex_int16_t yy_def[367] = { 0, 358, 1, 359, 359, 358, 358, 358, 358, 358, 360, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 362, 363, 358, 358, 358, 358, 360, 364, 364, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 362, 358, 363, 365, 366, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 358, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 358, 358, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 358, 358, 361, 361, 361, 361, 361, 361, 358, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 358, 358, 361, 361, 361, 361, 361, 361, 361, 361, 361, 358, 358, 361, 361, 361, 361, 361, 361, 361, 0, 358, 358, 358, 358, 358, 358, 358, 358 } ; static yyconst flex_int16_t yy_nxt[1165] = { 0, 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 22, 28, 29, 30, 31, 22, 22, 22, 22, 32, 6, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 22, 28, 29, 30, 31, 22, 22, 22, 22, 33, 6, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 358, 358, 358, 358, 44, 358, 358, 358, 358, 358, 214, 358, 91, 225, 358, 96, 358, 62, 358, 47, 59, 358, 48, 60, 358, 51, 358, 45, 52, 358, 44, 46, 58, 49, 50, 53, 54, 91, 61, 63, 55, 96, 64, 62, 56, 47, 59, 48, 60, 103, 57, 51, 45, 228, 52, 358, 46, 58, 49, 50, 53, 358, 54, 61, 63, 65, 55, 358, 64, 358, 56, 95, 358, 66, 103, 57, 73, 68, 358, 67, 358, 358, 74, 358, 75, 69, 41, 76, 77, 358, 100, 65, 358, 70, 358, 71, 358, 95, 72, 66, 95, 358, 73, 68, 67, 101, 99, 74, 110, 75, 83, 69, 76, 84, 77, 358, 100, 358, 70, 358, 71, 358, 104, 72, 358, 358, 95, 85, 86, 160, 358, 101, 99, 110, 78, 358, 83, 105, 358, 84, 108, 79, 80, 358, 81, 102, 106, 137, 107, 82, 87, 358, 85, 86, 111, 160, 88, 358, 109, 358, 78, 89, 226, 105, 358, 90, 108, 79, 80, 81, 102, 106, 137, 107, 82, 358, 87, 358, 234, 358, 111, 358, 88, 109, 227, 358, 89, 358, 119, 358, 90, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 358, 358, 358, 119, 44, 358, 358, 358, 275, 358, 267, 358, 268, 358, 269, 358, 358, 116, 117, 120, 358, 358, 112, 118, 358, 358, 113, 124, 358, 123, 44, 97, 358, 98, 98, 98, 98, 98, 98, 98, 98, 98, 114, 116, 117, 120, 121, 112, 118, 115, 358, 113, 122, 124, 123, 358, 358, 358, 358, 128, 358, 358, 358, 358, 358, 358, 358, 114, 358, 315, 358, 121, 358, 125, 115, 130, 134, 122, 126, 127, 129, 132, 133, 135, 128, 131, 136, 358, 138, 139, 142, 358, 358, 358, 144, 358, 358, 143, 125, 358, 358, 130, 134, 126, 127, 129, 132, 133, 140, 135, 131, 145, 136, 138, 139, 358, 142, 148, 358, 144, 147, 358, 149, 143, 146, 141, 285, 358, 358, 270, 159, 284, 358, 150, 140, 358, 151, 145, 153, 358, 358, 358, 152, 148, 358, 147, 358, 149, 358, 146, 141, 358, 247, 177, 270, 178, 159, 248, 179, 150, 180, 151, 157, 358, 153, 161, 158, 152, 154, 154, 154, 154, 154, 154, 154, 154, 154, 358, 98, 98, 98, 98, 98, 98, 98, 98, 98, 358, 157, 358, 161, 158, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 166, 358, 358, 358, 162, 170, 168, 169, 171, 175, 174, 358, 358, 163, 164, 181, 358, 165, 172, 358, 167, 173, 358, 176, 358, 182, 166, 358, 358, 162, 183, 170, 168, 169, 171, 175, 174, 190, 163, 164, 184, 181, 165, 172, 185, 167, 186, 173, 176, 187, 358, 182, 358, 358, 358, 358, 183, 358, 358, 358, 358, 358, 312, 190, 188, 184, 189, 358, 191, 358, 185, 186, 197, 358, 187, 192, 193, 358, 358, 194, 358, 195, 196, 202, 358, 358, 198, 358, 203, 199, 188, 358, 189, 358, 191, 200, 201, 358, 197, 358, 192, 204, 193, 205, 194, 208, 195, 196, 206, 202, 303, 198, 213, 211, 203, 199, 358, 207, 286, 212, 200, 209, 201, 287, 358, 308, 204, 358, 205, 358, 358, 208, 358, 206, 314, 303, 358, 213, 211, 358, 358, 358, 207, 358, 212, 358, 209, 154, 154, 154, 154, 154, 154, 154, 154, 154, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 215, 216, 219, 210, 217, 223, 222, 358, 358, 220, 358, 358, 218, 221, 358, 358, 358, 358, 230, 358, 232, 358, 224, 229, 358, 231, 215, 216, 219, 210, 217, 223, 222, 235, 236, 220, 233, 218, 221, 238, 358, 358, 237, 230, 240, 232, 358, 224, 229, 358, 231, 358, 358, 358, 241, 358, 358, 358, 358, 235, 236, 233, 239, 243, 358, 238, 358, 244, 237, 240, 358, 245, 358, 242, 252, 358, 254, 358, 246, 251, 241, 249, 250, 253, 255, 358, 358, 239, 358, 243, 257, 256, 358, 244, 358, 259, 245, 358, 242, 358, 252, 258, 254, 246, 251, 262, 249, 250, 253, 263, 255, 358, 260, 261, 272, 257, 256, 265, 358, 271, 259, 358, 358, 276, 358, 264, 258, 358, 358, 358, 262, 358, 358, 358, 263, 273, 358, 260, 261, 272, 358, 266, 280, 265, 271, 358, 274, 288, 276, 358, 278, 264, 279, 281, 358, 277, 282, 358, 358, 283, 290, 273, 358, 358, 358, 358, 266, 358, 280, 358, 358, 274, 289, 288, 358, 278, 291, 279, 304, 281, 277, 282, 293, 294, 283, 290, 292, 295, 298, 358, 297, 358, 299, 358, 301, 305, 296, 289, 358, 358, 358, 291, 358, 304, 313, 311, 358, 300, 293, 294, 358, 292, 358, 295, 298, 297, 302, 306, 299, 301, 305, 296, 358, 307, 358, 358, 358, 309, 310, 313, 358, 311, 358, 300, 323, 320, 317, 358, 358, 358, 358, 302, 358, 306, 337, 316, 358, 358, 307, 358, 321, 358, 309, 318, 310, 322, 358, 319, 326, 323, 320, 324, 317, 325, 358, 327, 358, 328, 358, 337, 316, 358, 358, 338, 335, 321, 336, 341, 318, 334, 322, 339, 319, 358, 326, 342, 324, 358, 325, 358, 327, 344, 358, 328, 329, 330, 331, 332, 333, 335, 358, 336, 358, 341, 334, 343, 358, 340, 358, 349, 345, 342, 350, 358, 358, 358, 344, 358, 358, 358, 347, 358, 358, 346, 356, 358, 358, 358, 358, 358, 358, 343, 340, 348, 349, 345, 351, 350, 358, 358, 358, 352, 353, 358, 354, 357, 347, 355, 346, 358, 356, 358, 358, 358, 155, 97, 93, 358, 348, 358, 36, 351, 93, 358, 38, 37, 352, 353, 36, 354, 357, 358, 355, 34, 34, 34, 34, 34, 34, 34, 39, 39, 43, 43, 43, 43, 92, 35, 92, 92, 92, 92, 92, 94, 35, 94, 94, 94, 94, 94, 40, 358, 40, 154, 358, 154, 156, 358, 156, 5, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358 } ; static yyconst flex_int16_t yy_chk[1165] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 14, 18, 20, 12, 19, 177, 161, 357, 17, 161, 15, 32, 177, 356, 40, 21, 20, 180, 14, 18, 49, 14, 18, 23, 15, 16, 13, 15, 354, 12, 13, 17, 14, 14, 15, 16, 32, 19, 21, 16, 40, 23, 20, 16, 14, 18, 14, 18, 49, 16, 15, 13, 180, 15, 24, 13, 17, 14, 14, 15, 27, 16, 19, 21, 24, 16, 25, 23, 26, 16, 41, 46, 24, 49, 16, 27, 25, 28, 24, 54, 353, 27, 352, 27, 25, 39, 27, 28, 47, 46, 24, 348, 26, 45, 26, 30, 41, 26, 24, 39, 344, 27, 25, 24, 47, 45, 27, 54, 27, 30, 25, 27, 30, 28, 103, 46, 77, 26, 50, 26, 48, 50, 26, 29, 51, 39, 30, 30, 103, 52, 47, 45, 54, 29, 53, 30, 50, 31, 30, 52, 29, 29, 55, 29, 48, 51, 77, 51, 29, 31, 342, 30, 30, 55, 103, 31, 341, 53, 178, 29, 31, 178, 50, 60, 31, 52, 29, 29, 29, 48, 51, 77, 51, 29, 335, 31, 190, 190, 179, 55, 333, 31, 53, 179, 225, 31, 226, 60, 227, 31, 38, 38, 38, 38, 38, 38, 38, 38, 38, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 56, 61, 59, 60, 42, 58, 64, 234, 234, 332, 225, 331, 226, 330, 227, 62, 65, 58, 58, 61, 57, 329, 56, 59, 63, 328, 56, 65, 68, 64, 42, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 58, 58, 61, 62, 56, 59, 57, 66, 56, 63, 65, 64, 71, 67, 69, 327, 68, 72, 73, 70, 83, 287, 79, 78, 57, 76, 287, 74, 62, 81, 66, 57, 70, 73, 63, 66, 67, 69, 71, 72, 74, 68, 70, 76, 82, 78, 79, 81, 248, 80, 84, 83, 86, 85, 82, 66, 88, 87, 70, 73, 66, 67, 69, 71, 72, 80, 74, 70, 84, 76, 78, 79, 89, 81, 87, 102, 83, 86, 90, 88, 82, 85, 80, 248, 326, 247, 228, 102, 247, 321, 89, 80, 319, 89, 84, 90, 100, 105, 318, 89, 87, 99, 86, 301, 88, 204, 85, 80, 122, 204, 122, 228, 122, 102, 204, 122, 89, 122, 89, 99, 297, 90, 105, 100, 89, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 106, 99, 107, 105, 100, 108, 109, 110, 111, 112, 113, 116, 114, 118, 115, 120, 119, 110, 296, 123, 117, 106, 114, 112, 113, 115, 119, 118, 124, 126, 107, 108, 123, 125, 109, 116, 128, 111, 117, 129, 120, 132, 124, 110, 284, 127, 106, 125, 114, 112, 113, 115, 119, 118, 132, 107, 108, 126, 123, 109, 116, 127, 111, 128, 117, 120, 129, 130, 124, 131, 135, 138, 139, 125, 133, 141, 140, 136, 142, 284, 132, 130, 126, 131, 144, 133, 147, 127, 128, 141, 149, 129, 135, 136, 143, 148, 138, 150, 139, 140, 147, 145, 160, 142, 152, 148, 143, 130, 158, 131, 151, 133, 144, 145, 153, 141, 159, 135, 149, 136, 150, 138, 152, 139, 140, 150, 147, 267, 142, 160, 158, 148, 143, 249, 151, 249, 159, 144, 153, 145, 249, 275, 275, 149, 286, 150, 290, 281, 152, 279, 150, 286, 267, 278, 160, 158, 277, 276, 273, 151, 271, 159, 266, 153, 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, 155, 155, 155, 155, 155, 155, 155, 155, 156, 156, 156, 156, 156, 156, 156, 156, 156, 157, 163, 165, 167, 168, 169, 170, 171, 172, 175, 173, 181, 182, 183, 184, 163, 165, 169, 157, 167, 173, 172, 264, 250, 170, 246, 243, 168, 171, 242, 185, 195, 240, 182, 191, 184, 193, 175, 181, 192, 183, 163, 165, 169, 157, 167, 173, 172, 191, 192, 170, 185, 168, 171, 193, 196, 194, 192, 182, 195, 184, 197, 175, 181, 199, 183, 201, 203, 205, 196, 206, 207, 209, 208, 191, 192, 185, 194, 199, 212, 193, 211, 199, 192, 195, 213, 201, 216, 197, 208, 215, 211, 219, 203, 207, 196, 205, 206, 209, 211, 218, 220, 194, 229, 199, 213, 212, 230, 199, 231, 216, 201, 235, 197, 222, 208, 215, 211, 203, 207, 219, 205, 206, 209, 220, 211, 221, 218, 218, 231, 213, 212, 222, 223, 230, 216, 232, 233, 235, 236, 221, 215, 237, 239, 238, 219, 251, 253, 244, 220, 232, 245, 218, 218, 231, 241, 223, 239, 222, 230, 254, 233, 251, 235, 252, 237, 221, 238, 241, 224, 236, 244, 217, 214, 245, 253, 232, 259, 255, 256, 257, 223, 263, 239, 258, 260, 233, 252, 251, 261, 237, 254, 238, 268, 241, 236, 244, 256, 257, 245, 253, 255, 258, 260, 262, 259, 283, 261, 265, 263, 269, 258, 252, 280, 272, 274, 254, 293, 268, 285, 283, 210, 262, 256, 257, 298, 255, 282, 258, 260, 259, 265, 272, 261, 263, 269, 258, 289, 274, 288, 294, 291, 280, 282, 285, 292, 283, 295, 262, 298, 293, 289, 299, 314, 300, 306, 265, 302, 272, 312, 288, 315, 310, 274, 311, 294, 307, 280, 291, 282, 295, 309, 292, 302, 298, 293, 299, 289, 300, 317, 306, 202, 307, 323, 312, 288, 320, 200, 314, 310, 294, 311, 317, 291, 309, 295, 315, 292, 316, 302, 320, 299, 324, 300, 322, 306, 323, 308, 307, 308, 308, 308, 308, 308, 310, 325, 311, 334, 317, 309, 322, 336, 316, 351, 338, 324, 320, 339, 340, 343, 345, 323, 346, 355, 347, 334, 198, 189, 325, 351, 188, 187, 186, 176, 174, 166, 322, 316, 336, 338, 324, 340, 339, 164, 162, 146, 343, 345, 137, 346, 355, 334, 347, 325, 134, 351, 121, 104, 101, 96, 95, 92, 75, 336, 43, 36, 340, 33, 22, 10, 9, 343, 345, 7, 346, 355, 5, 347, 359, 359, 359, 359, 359, 359, 359, 360, 360, 361, 361, 361, 361, 362, 4, 362, 362, 362, 362, 362, 363, 3, 363, 363, 363, 363, 363, 364, 0, 364, 365, 0, 365, 366, 0, 366, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "nrrdlex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 11 "nrrdlex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "nrrdparser.H" extern YYSTYPE* nrrdlval; extern nrrdFlexLexer* nrrdlexx; /* rules */ #line 799 "nrrdlex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 29 "nrrdlex.L" #line 903 "nrrdlex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 359 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 358 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 31 "nrrdlex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(nrrdlval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 38 "nrrdlex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(NRRDPARSERSIZE-1) ? yyleng:(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext,ll); nrrdlval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 46 "nrrdlex.L" {return DEBUG_;} YY_BREAK case 4: YY_RULE_SETUP #line 47 "nrrdlex.L" {return ON_;} YY_BREAK case 5: YY_RULE_SETUP #line 48 "nrrdlex.L" {return OFF_;} YY_BREAK case 6: YY_RULE_SETUP #line 50 "nrrdlex.L" {return NRRD0001_;} YY_BREAK case 7: YY_RULE_SETUP #line 51 "nrrdlex.L" {return NRRD0002_;} YY_BREAK case 8: YY_RULE_SETUP #line 52 "nrrdlex.L" {return NRRD0003_;} YY_BREAK case 9: YY_RULE_SETUP #line 53 "nrrdlex.L" {return NRRD0004_;} YY_BREAK case 10: YY_RULE_SETUP #line 54 "nrrdlex.L" {return NRRD0005_;} YY_BREAK case 11: YY_RULE_SETUP #line 56 "nrrdlex.L" {return DATA_;} YY_BREAK case 12: YY_RULE_SETUP #line 57 "nrrdlex.L" {return FILE_;} YY_BREAK case 13: YY_RULE_SETUP #line 59 "nrrdlex.L" {return SPACE_;} YY_BREAK case 14: YY_RULE_SETUP #line 60 "nrrdlex.L" {return UNITS_;} YY_BREAK case 15: YY_RULE_SETUP #line 61 "nrrdlex.L" {return DIMENSIONS_;} YY_BREAK case 16: YY_RULE_SETUP #line 62 "nrrdlex.L" {return ORIGIN_;} YY_BREAK case 17: YY_RULE_SETUP #line 63 "nrrdlex.L" {return DIRECTIONS_;} YY_BREAK case 18: YY_RULE_SETUP #line 65 "nrrdlex.L" {return DIMENSION_;} YY_BREAK case 19: YY_RULE_SETUP #line 67 "nrrdlex.L" {return TYPE_;} YY_BREAK case 20: YY_RULE_SETUP #line 68 "nrrdlex.L" {return SIGNED_;} YY_BREAK case 21: YY_RULE_SETUP #line 69 "nrrdlex.L" {return UNSIGNED_;} YY_BREAK case 22: YY_RULE_SETUP #line 70 "nrrdlex.L" {return CHAR_;} YY_BREAK case 23: YY_RULE_SETUP #line 71 "nrrdlex.L" {return INT8_;} YY_BREAK case 24: YY_RULE_SETUP #line 72 "nrrdlex.L" {return INT8_T_;} YY_BREAK case 25: YY_RULE_SETUP #line 73 "nrrdlex.L" {return UCHAR_;} YY_BREAK case 26: YY_RULE_SETUP #line 74 "nrrdlex.L" {return UINT8_;} YY_BREAK case 27: YY_RULE_SETUP #line 75 "nrrdlex.L" {return UINT8_T_;} YY_BREAK case 28: YY_RULE_SETUP #line 76 "nrrdlex.L" {return SHORT_;} YY_BREAK case 29: YY_RULE_SETUP #line 77 "nrrdlex.L" {return INT_;} YY_BREAK case 30: YY_RULE_SETUP #line 78 "nrrdlex.L" {return INT16_;} YY_BREAK case 31: YY_RULE_SETUP #line 79 "nrrdlex.L" {return INT16_T_;} YY_BREAK case 32: YY_RULE_SETUP #line 80 "nrrdlex.L" {return USHORT_;} YY_BREAK case 33: YY_RULE_SETUP #line 81 "nrrdlex.L" {return UINT16_;} YY_BREAK case 34: YY_RULE_SETUP #line 82 "nrrdlex.L" {return UINT16_T_;} YY_BREAK case 35: YY_RULE_SETUP #line 83 "nrrdlex.L" {return INT32_;} YY_BREAK case 36: YY_RULE_SETUP #line 84 "nrrdlex.L" {return INT32_T_;} YY_BREAK case 37: YY_RULE_SETUP #line 85 "nrrdlex.L" {return UINT_;} YY_BREAK case 38: YY_RULE_SETUP #line 86 "nrrdlex.L" {return UINT32_;} YY_BREAK case 39: YY_RULE_SETUP #line 87 "nrrdlex.L" {return UINT32_T_;} YY_BREAK case 40: YY_RULE_SETUP #line 88 "nrrdlex.L" {return LONG_;} YY_BREAK case 41: YY_RULE_SETUP #line 89 "nrrdlex.L" {return LONGLONG_;} YY_BREAK case 42: YY_RULE_SETUP #line 90 "nrrdlex.L" {return INT64_;} YY_BREAK case 43: YY_RULE_SETUP #line 91 "nrrdlex.L" {return INT64_T_;} YY_BREAK case 44: YY_RULE_SETUP #line 92 "nrrdlex.L" {return ULONGLONG_;} YY_BREAK case 45: YY_RULE_SETUP #line 93 "nrrdlex.L" {return UINT64_;} YY_BREAK case 46: YY_RULE_SETUP #line 94 "nrrdlex.L" {return UINT64_T_;} YY_BREAK case 47: YY_RULE_SETUP #line 95 "nrrdlex.L" {return FLOAT_;} YY_BREAK case 48: YY_RULE_SETUP #line 96 "nrrdlex.L" {return DOUBLE_;} YY_BREAK case 49: YY_RULE_SETUP #line 98 "nrrdlex.L" {return BLOCK_;} YY_BREAK case 50: YY_RULE_SETUP #line 99 "nrrdlex.L" {return SIZE_;} YY_BREAK case 51: YY_RULE_SETUP #line 100 "nrrdlex.L" {return BLOCKSIZE_;} YY_BREAK case 52: YY_RULE_SETUP #line 102 "nrrdlex.L" {return ENCODING_;} YY_BREAK case 53: YY_RULE_SETUP #line 103 "nrrdlex.L" {return RAW_;} YY_BREAK case 54: YY_RULE_SETUP #line 104 "nrrdlex.L" {return TXT_;} YY_BREAK case 55: YY_RULE_SETUP #line 105 "nrrdlex.L" {return TEXT_;} YY_BREAK case 56: YY_RULE_SETUP #line 106 "nrrdlex.L" {return ASCII_;} YY_BREAK case 57: YY_RULE_SETUP #line 107 "nrrdlex.L" {return HEX_;} YY_BREAK case 58: YY_RULE_SETUP #line 108 "nrrdlex.L" {return GZ_;} YY_BREAK case 59: YY_RULE_SETUP #line 109 "nrrdlex.L" {return GZIP_;} YY_BREAK case 60: YY_RULE_SETUP #line 110 "nrrdlex.L" {return BZ2_;} YY_BREAK case 61: YY_RULE_SETUP #line 111 "nrrdlex.L" {return BZIP2_;} YY_BREAK case 62: YY_RULE_SETUP #line 113 "nrrdlex.L" {return ENDIAN_;} YY_BREAK case 63: YY_RULE_SETUP #line 114 "nrrdlex.L" {return BIG_;} YY_BREAK case 64: YY_RULE_SETUP #line 115 "nrrdlex.L" {return LITTLE_;} YY_BREAK case 65: YY_RULE_SETUP #line 117 "nrrdlex.L" {return CONTENT_;} YY_BREAK case 66: YY_RULE_SETUP #line 119 "nrrdlex.L" {return OLD_;} YY_BREAK case 67: YY_RULE_SETUP #line 120 "nrrdlex.L" {return MIN_;} YY_BREAK case 68: YY_RULE_SETUP #line 121 "nrrdlex.L" {return OLDMIN_;} YY_BREAK case 69: YY_RULE_SETUP #line 122 "nrrdlex.L" {return MAX_;} YY_BREAK case 70: YY_RULE_SETUP #line 123 "nrrdlex.L" {return OLDMAX_;} YY_BREAK case 71: YY_RULE_SETUP #line 125 "nrrdlex.L" {return SKIP_;} YY_BREAK case 72: YY_RULE_SETUP #line 126 "nrrdlex.L" {return LINE_;} YY_BREAK case 73: YY_RULE_SETUP #line 127 "nrrdlex.L" {return LINESKIP_;} YY_BREAK case 74: YY_RULE_SETUP #line 128 "nrrdlex.L" {return BYTE_;} YY_BREAK case 75: YY_RULE_SETUP #line 129 "nrrdlex.L" {return BYTESKIP_;} YY_BREAK case 76: YY_RULE_SETUP #line 131 "nrrdlex.L" {return NUMBER_;} YY_BREAK case 77: YY_RULE_SETUP #line 133 "nrrdlex.L" {return SAMPLE_;} YY_BREAK case 78: YY_RULE_SETUP #line 134 "nrrdlex.L" {return SAMPLEUNITS_;} YY_BREAK case 79: YY_RULE_SETUP #line 136 "nrrdlex.L" {return SIZES_;} YY_BREAK case 80: YY_RULE_SETUP #line 137 "nrrdlex.L" {return SPACINGS_;} YY_BREAK case 81: YY_RULE_SETUP #line 138 "nrrdlex.L" {return THICKNESSES_;} YY_BREAK case 82: YY_RULE_SETUP #line 139 "nrrdlex.L" {return AXIS_;} YY_BREAK case 83: YY_RULE_SETUP #line 140 "nrrdlex.L" {return MINS_;} YY_BREAK case 84: YY_RULE_SETUP #line 141 "nrrdlex.L" {return AXISMINS_;} YY_BREAK case 85: YY_RULE_SETUP #line 142 "nrrdlex.L" {return MAXS_;} YY_BREAK case 86: YY_RULE_SETUP #line 143 "nrrdlex.L" {return AXISMAXS_;} YY_BREAK case 87: YY_RULE_SETUP #line 144 "nrrdlex.L" {return CENTERS_;} YY_BREAK case 88: YY_RULE_SETUP #line 145 "nrrdlex.L" {return CENTERINGS_;} YY_BREAK case 89: YY_RULE_SETUP #line 146 "nrrdlex.L" {return CELL_;} YY_BREAK case 90: YY_RULE_SETUP #line 147 "nrrdlex.L" {return NODE_;} YY_BREAK case 91: YY_RULE_SETUP #line 148 "nrrdlex.L" {return NONE_;} YY_BREAK case 92: YY_RULE_SETUP #line 149 "nrrdlex.L" {return LABELS_;} YY_BREAK case 93: YY_RULE_SETUP #line 150 "nrrdlex.L" {return KINDS_;} YY_BREAK case 94: YY_RULE_SETUP #line 151 "nrrdlex.L" {return DOMAINS_;} YY_BREAK case 95: YY_RULE_SETUP #line 153 "nrrdlex.L" { // Integer nrrdlval->integer = atoi(yytext); return INT; } YY_BREAK case 96: #line 159 "nrrdlex.L" case 97: YY_RULE_SETUP #line 159 "nrrdlex.L" { // Real Number nrrdlval->real = atof(yytext); return REAL; } YY_BREAK case 98: YY_RULE_SETUP #line 165 "nrrdlex.L" { // Quoted String int ll = (yyleng-2)<(NRRDPARSERSIZE-1) ? (yyleng-2):(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext+1,ll); // skip the '{' nrrdlval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 99: YY_RULE_SETUP #line 172 "nrrdlex.L" { // General String int ll = yyleng <(NRRDPARSERSIZE-1) ? yyleng:(NRRDPARSERSIZE-1); strncpy(nrrdlval->str,yytext,ll); nrrdlval->str[ll] = '\0'; return STRING; } YY_BREAK case 100: YY_RULE_SETUP #line 179 "nrrdlex.L" { // White Spaces } YY_BREAK case 101: /* rule 101 can match eol */ YY_RULE_SETUP #line 182 "nrrdlex.L" { // windows line feed return '\n'; } YY_BREAK case 102: YY_RULE_SETUP #line 186 "nrrdlex.L" { // fake line feed return '\n'; } YY_BREAK case 103: /* rule 103 can match eol */ YY_RULE_SETUP #line 190 "nrrdlex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 194 "nrrdlex.L" { // eof return EOF_; } YY_BREAK case 104: YY_RULE_SETUP #line 198 "nrrdlex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 105: YY_RULE_SETUP #line 202 "nrrdlex.L" ECHO; YY_BREAK #line 1550 "nrrdlex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; nrrdfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); nrrdfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ nrrdrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) nrrdrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 359 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 359 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 358); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) nrrdalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) nrrdalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) nrrdfree((void *) b->yy_ch_buf ); nrrdfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)nrrdalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)nrrdrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) nrrdalloc(new_size ); else (yy_start_stack) = (int *) nrrdrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *nrrdalloc (yy_size_t size ) { return (void *) malloc( size ); } void *nrrdrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void nrrdfree (void * ptr ) { free( (char *) ptr ); /* see nrrdrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 202 "nrrdlex.L" void nrrdDiscard(int doit) { if (nrrdlexx) nrrdlexx->begin(DISCARD, doit); } void nrrdFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/photo.h����������������������������������������������������������������������0000644�0001750�0001750�00000001113�11746063021�015006� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsphoto_h__ #define __fitsphoto_h__ #include "vector.h" #include "file.h" class FitsPhoto : public FitsFile { public: FitsPhoto(Tcl_Interp* interp, const char*); ~FitsPhoto(); }; class FitsPhotoCube : public FitsFile { public: FitsPhotoCube(Tcl_Interp* interp, const char*); ~FitsPhotoCube(); }; class FitsPhotoCubeNext : public FitsFile { public: FitsPhotoCubeNext(FitsFile*); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdgzip.h�������������������������������������������������������������������0000644�0001750�0001750�00000000620�12044247745�015527� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsnrrdgzip_h__ #define __fitsnrrdgzip_h__ #include "nrrd.h" template<class T> class FitsNRRDGzipm : public FitsNRRDm<T> { private: int compressed(T*, char*, size_t); public: FitsNRRDGzipm(FitsFile*); }; #endif ����������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/rice.h�����������������������������������������������������������������������0000644�0001750�0001750�00000000741�11700666265�014616� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsrice_h__ #define __fitsrice_h__ #include "compress.h" template<class T> class FitsRicem : public FitsCompressm<T> { protected: int block_; int bytepix_; int noisebit_; private: int compressed(T*, char*, char*, int, int, int, int, int, int); public: FitsRicem(FitsFile*); }; #endif �������������������������������./saods9/saotk/fitsy++/share.h����������������������������������������������������������������������0000644�0001750�0001750�00000005226�12041601171�014761� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsshare_h__ #define __fitsshare_h__ #include "map.h" class FitsShareID : public virtual FitsMap { public: FitsShareID(int, const char*); virtual ~FitsShareID(); }; class FitsShareKey : public virtual FitsMap { public: FitsShareKey(int, const char*); virtual ~FitsShareKey(); }; class FitsFitsShare : public virtual FitsMap, public FitsFitsMap { public: FitsFitsShare(ScanMode mode) : FitsMap(), FitsFitsMap(mode) {} }; class FitsFitsNextShare : public FitsFitsNextMap { public: FitsFitsNextShare(FitsFile* prev) : FitsFitsNextMap(prev) {} }; class FitsArrShare : public virtual FitsMap, public FitsArrMap { public: FitsArrShare() : FitsMap(), FitsArrMap() {} }; class FitsNRRDShare : public virtual FitsMap, public FitsNRRDMap { public: FitsNRRDShare() : FitsMap(), FitsNRRDMap() {} }; class FitsMosaicShare : public virtual FitsMap, public FitsMosaicMap { public: FitsMosaicShare() : FitsMap(), FitsMosaicMap() {} }; class FitsMosaicNextShare : public FitsMosaicNextMap { public: FitsMosaicNextShare(FitsFile* prev) : FitsMosaicNextMap(prev) {} }; class FitsFitsShareID : public FitsShareID, public FitsFitsShare { public: FitsFitsShareID(int shmid, const char* filter, ScanMode mode) : FitsShareID(shmid, filter), FitsFitsShare(mode) {} }; class FitsFitsShareKey : public FitsShareKey, public FitsFitsShare { public: FitsFitsShareKey(int key, const char* filter, ScanMode mode) : FitsShareKey(key, filter), FitsFitsShare(mode) {} }; class FitsArrShareID : public FitsShareID, public FitsArrShare { public: FitsArrShareID(int shmid, const char* filter) : FitsShareID(shmid, filter), FitsArrShare() {} }; class FitsArrShareKey : public FitsShareKey, public FitsArrShare { public: FitsArrShareKey(int key, const char* filter) : FitsShareKey(key, filter), FitsArrShare() {} }; class FitsNRRDShareID : public FitsShareID, public FitsNRRDShare { public: FitsNRRDShareID(int shmid, const char* filter) : FitsShareID(shmid, filter), FitsNRRDShare() {} }; class FitsNRRDShareKey : public FitsShareKey, public FitsNRRDShare { public: FitsNRRDShareKey(int key, const char* filter) : FitsShareKey(key, filter), FitsNRRDShare() {} }; class FitsMosaicShareID : public FitsShareID, public FitsMosaicShare { public: FitsMosaicShareID(int shmid) : FitsShareID(shmid, ""), FitsMosaicShare() {} }; class FitsMosaicShareKey : public FitsShareKey, public FitsMosaicShare { public: FitsMosaicShareKey(int key) : FitsShareKey(key, ""), FitsMosaicShare() {} }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/strm.C�����������������������������������������������������������������������0000644�0001750�0001750�00000041516�12075604063�014613� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <string.h> #include <stdio.h> #include <sys/socket.h> #include "strm.h" #include "util.h" template<class T> FitsStream<T>::FitsStream() { stream_ =0; flush_ = NOFLUSH; dataManage_ = 0; } template<class T> FitsStream<T>::~FitsStream() { if (dataManage_ && data_) delete [] (T*)data_; } // FILE* template <> size_t FitsStream<FILE*>::read(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = fread(where+rr, 1, (ss>B1MB) ? B1MB : ss, stream_); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } template <> void FitsStream<FILE*>::close() { fclose(stream_); } // Socket template <> size_t FitsStream<int>::read(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr =0; int r; do { r = recv(stream_ , where+rr, (ss>B4KB) ? B4KB : ss, 0); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } template <> void FitsStream<int>::close() {} // gzStream template <> size_t FitsStream<gzStream>::read(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; if (stream_->transparent) { if (stream_->useHeader) { memcpy(where,stream_->header,2); ss -= 2; rr += 2; stream_->useHeader = 0; } do { r = recv(stream_->id , where+rr, (ss>B4KB) ? B4KB : ss, 0); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } else { ((z_stream*)stream_)->avail_out = size; ((z_stream*)stream_)->next_out = (unsigned char*)where; if (DebugGZ) cerr << "***read init " << ((z_stream*)stream_)->avail_out << " bytes" << endl; do { if (((z_stream*)stream_)->avail_in == 0) { ((z_stream*)stream_)->next_in = stream_->buf; int aa = recv(stream_->id , stream_->buf, B4KB, 0); if (aa<0) return rr; ((z_stream*)stream_)->avail_in = aa; if (DebugGZ) cerr << " read from socket " << aa << " bytes" << endl; } if (DebugGZ) cerr << " inflate Start: avail_in " << ((z_stream*)stream_)->avail_in << " avail_out " << ((z_stream*)stream_)->avail_out << endl; int before = ((z_stream*)stream_)->avail_out; int result = inflate(((z_stream*)stream_), Z_NO_FLUSH); r = before - ((z_stream*)stream_)->avail_out; rr += r; switch (result) { case Z_OK: if (DebugGZ) cerr << " inflate OK: avail_in " << ((z_stream*)stream_)->avail_in << " avail_out " << ((z_stream*)stream_)->avail_out << endl; break; case Z_STREAM_END: if (DebugGZ) cerr << " inflate STRM_END: avail_in " << ((z_stream*)stream_)->avail_in << " avail_out " << ((z_stream*)stream_)->avail_out << " total_in " << ((z_stream*)stream_)->total_in << " total_out " << ((z_stream*)stream_)->total_out << endl; return rr; default: internalError("Fitsy++ strm inflate error"); return rr; } } while (r>0 && rr<size); if (DebugGZ) cerr << "***read finish" << endl; return rr; } } template <> void FitsStream<gzStream>::close() { if (!stream_->transparent) { if (inflateEnd((z_stream*)stream_) != Z_OK) internalError("Fitsy++ strm inflateEnd error"); if (DebugGZ) cerr << "inflateEnd: avail_in " << ((z_stream*)stream_)->avail_in << " avail_out " << ((z_stream*)stream_)->avail_out << endl; } } // Tcl_Channel template <> size_t FitsStream<Tcl_Channel>::read(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = Tcl_Read(stream_, where+rr, (ss>B1MB) ? B1MB : ss); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } template <> void FitsStream<Tcl_Channel>::close() {} // gzFile template <> size_t FitsStream<gzFile>::read(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = gzread(stream_, where+rr, (ss>B1MB) ? B1MB : ss); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } template <> void FitsStream<gzFile>::close() { gzclose(stream_); } template<class T> FitsHead* FitsStream<T>::headRead() { // read first block char* cards = new char[FTY_BLOCK]; if (!cards) return NULL; memset(cards, ' ', FTY_BLOCK); if (read(cards, FTY_BLOCK) != FTY_BLOCK) { delete [] cards; return NULL; } // simple FITS file check if (strncmp(cards, "SIMPLE =", 9) && strncmp(cards, "XTENSION=", 9)) { delete [] cards; return NULL; } // read remaining blocks int numblks = 1; char* current = cards; while (1) { if (findEnd(current)) break; // this is check // for TCL channels, the stream gets corrupted, so END is never found // so bail out after an extreme number of blocks have been read // // this does not work because some fits files have 100's or 1000's of // history/comments. lets hope a corrupted stream is caught below // if (numblks>10) { // delete [] cards; // return NULL; // } char* tmp = new char[(numblks+1)*FTY_BLOCK]; memcpy(tmp, cards, numblks*FTY_BLOCK); delete [] cards; cards = tmp; current = cards + numblks*FTY_BLOCK; memset(current, ' ', FTY_BLOCK); if (read(current, FTY_BLOCK) != FTY_BLOCK) { delete [] cards; return NULL; } numblks++; } // create header FitsHead* fits = new FitsHead(cards, numblks*FTY_BLOCK, FitsHead::ALLOC); if (!fits->isValid()) { delete fits; return NULL; } return fits; } template<class T> int FitsStream<T>::dataRead(size_t bytes, int validate) { data_ = NULL; dataSize_ = 0; dataSkip_ = 0; dataManage_ = 0; if (!bytes) return 0; data_ = new char[bytes]; if (!data_) return 0; size_t rr = read((char*)data_, bytes); if (validate && rr != bytes) { delete (char*)data_; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; dataManage_ = 0; return 0; } dataSize_ = bytes; dataManage_ = 1; return 1; } template<class T> void FitsStream<T>::dataSkip(size_t bytes) { // size_t bytes is unsigned if (bytes) { char block[FTY_BLOCK]; do { read(block, (bytes < FTY_BLOCK ? bytes : FTY_BLOCK)); if (bytes>FTY_BLOCK) bytes -= FTY_BLOCK; else break; } while (1); } } template<class T> void FitsStream<T>::dataSkipBlock(size_t blk) { char block[FTY_BLOCK]; for (size_t ii=0; ii<blk; ii++) read(block, FTY_BLOCK); } template<class T> void FitsStream<T>::skipEnd() { char block[FTY_BLOCK]; int bytes; do bytes = read(block, FTY_BLOCK); while (bytes > 0); } template<class T> void FitsStream<T>::found() { // only read allbytes, since the data seg maybe short if (!this->dataRead(head_->allbytes())) { error(); return; } // read any dead space til next block if (head_->padbytes()>0) this->dataSkip(head_->padbytes()); inherit_ = head_->inherit(); valid_ = 1; if (flush_ == FLUSH) skipEnd(); } template<class T> void FitsStream<T>::error() { // try to clean up if ((flush_ == FLUSH) && (head_ || primary_)) skipEnd(); if (manageHead_ && head_) delete head_; head_ = NULL; if (managePrimary_ && primary_) delete primary_; primary_ = NULL; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; dataManage_ = 0; valid_ = 0; } template class FitsStream<FILE*>; template class FitsStream<Tcl_Channel>; template class FitsStream<int>; template class FitsStream<gzFile>; template class FitsStream<gzStream>; template<class T> FitsFitsStream<T>::FitsFitsStream(FitsFile::ScanMode mode, FitsFile::FlushMode f) { if (!this->valid_) return; this->flush_ = f; if (mode == this->EXACT || this->pExt_ || this->pIndex_>-1) processExact(); else processRelax(); } template<class T> void FitsFitsStream<T>::processExact() { if (!(this->pExt_ || (this->pIndex_>0))) { // we are only looking for a primary image if (this->head_ = this->headRead()) { this->found(); return; } } else { // we are looking for an extension // keep the primary header this->primary_ = this->headRead(); this->managePrimary_ = 1; if (!this->primary_) { this->error(); return; } this->dataSkipBlock(this->primary_->datablocks()); if (this->pExt_) { while (1) { if (!(this->head_ = this->headRead())) { this->error(); return; } this->ext_++; if (this->head_->extname()) { char* a = toUpper(this->head_->extname()); char* b = toUpper(this->pExt_); if (!strncmp(a,b,strlen(b))) { delete [] a; delete [] b; this->found(); return; } delete [] a; delete [] b; } this->dataSkipBlock(this->head_->datablocks()); delete this->head_; this->head_ = NULL; } } else { for (int i=1; i<this->pIndex_; i++) { if (!(this->head_ = this->headRead())) { this->error(); return; } this->ext_++; this->dataSkipBlock(this->head_->datablocks()); delete this->head_; this->head_ = NULL; } if (this->head_ = this->headRead()) { this->ext_++; this->found(); return; } } } // we must have an error this->error(); } template<class T> void FitsFitsStream<T>::processRelax() { // check to see if there is an image in the primary if (!(this->head_ = this->headRead())) { this->error(); return; } else { if (this->head_->isValid() && this->head_->naxes() > 0 && this->head_->naxis(0) > 0 && this->head_->naxis(1) > 0) { this->found(); return; } } // ok, no image, save primary and lets check extensions this->primary_ = this->head_; this->managePrimary_ = 1; this->dataSkipBlock(this->head_->datablocks()); this->head_ = NULL; // ok, no image, lets check extensions while (1) { if (!(this->head_ = this->headRead())) { this->error(); return; } this->ext_++; if (this->head_->isImage()) { this->found(); return; } // else, check for compressed image if (this->head_->isBinTable() && this->head_->find("ZIMAGE")) { this->found(); return; } // else, check for bin table named STDEVT, EVENTS, RAYEVENT if (this->head_->isBinTable() && this->head_->extname()) { char* a = toUpper(this->head_->extname()); if (!strncmp("STDEVT", a, 6) || !strncmp("EVENTS", a, 6) || !strncmp("RAYEVENT", a, 8)) { delete [] a; this->found(); return; } else delete [] a; } // else, check for bin table with keyword PIXTYPE = 'HEALPIX ' if (this->head_->isBinTable() && this->head_->find("PIXTYPE") && (!strncmp(this->head_->getString("PIXTYPE"),"HEALPIX",4))) { this->found(); return; } // else, check for bin table with keyword NSIDE (also HEALPIX) if (this->head_->isBinTable() && this->head_->find("NSIDE")) { this->found(); return; } this->dataSkipBlock(this->head_->datablocks()); delete this->head_; this->head_ = NULL; } this->error(); } template class FitsFitsStream<FILE*>; template class FitsFitsStream<Tcl_Channel>; template class FitsFitsStream<int>; template class FitsFitsStream<gzFile>; template class FitsFitsStream<gzStream>; template<class T> FitsFitsNextStream<T>::FitsFitsNextStream(FitsFile* p) { FitsStream<T>* prev = (FitsStream<T>*)p; this->primary_ = prev->primary(); this->managePrimary_ = 0; this->head_ = prev->head(); this->manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)this->head_->hdu(); this->data_ = (char*)prev->data() + hdu->imgbytes(); this->dataSize_ = 0; this->dataSkip_ = 0; this->ext_ = prev->ext(); this->inherit_ = prev->inherit(); this->byteswap_ = prev->byteswap(); this->orgFits_ = prev->orgFits(); this->valid_ = 1; this->pWidth_ = prev->pWidth(); this->pHeight_ = prev->pHeight(); this->pDepth_ = prev->pDepth(); this->pBitpix_ = prev->pBitpix(); this->pSkip_ = prev->pSkip(); this->pArch_ = prev->pArch(); this->coord_ = prev->coord(); this->xvalid_ = prev->xvalid(); this->xmin_ = prev->xmin(); this->xmax_ = prev->xmax(); this->yvalid_ = prev->yvalid(); this->ymin_ = prev->ymin(); this->ymax_ = prev->ymax(); this->zvalid_ = prev->zvalid(); this->zmin_ = prev->zmin(); this->zmax_ = prev->zmax(); this->stream_ = prev->stream(); this->flush_ = prev->flush(); this->dataManage_ = 0; } template class FitsFitsNextStream<FILE*>; template class FitsFitsNextStream<Tcl_Channel>; template class FitsFitsNextStream<int>; template class FitsFitsNextStream<gzFile>; template class FitsFitsNextStream<gzStream>; template<class T> FitsArrStream<T>::FitsArrStream(FitsFile::FlushMode f) { if (!this->valid_) return; this->flush_ = f; this->valid_=0; // check to see if we have a nonzero width, height, and bitpix if (!this->validParams()) { return; } // skip header if (this->pSkip_) this->dataSkip(this->pSkip_); // read data if (!this->dataRead((size_t)this->pWidth_*this->pHeight_*this->pDepth_*abs(this->pBitpix_)/8)) { if ((this->flush_ == this->FLUSH) && this->data_) this->skipEnd(); return; } // create blank header this->head_ = new FitsHead(this->pWidth_, this->pHeight_, this->pDepth_, this->pBitpix_); if (!this->head_->isValid()) { this->error(); return; } // do we need to byteswap? this->setByteSwap(); // made it this far, must be good this->valid_ = 1; this->orgFits_ = 0; if (this->flush_ == this->FLUSH) this->skipEnd(); } template class FitsArrStream<FILE*>; template class FitsArrStream<Tcl_Channel>; template class FitsArrStream<int>; template class FitsArrStream<gzFile>; template class FitsArrStream<gzStream>; template<class T> FitsNRRDStream<T>::FitsNRRDStream(FitsFile::FlushMode f) { if (!this->valid_) return; this->flush_ = f; this->valid_=0; // header { char buf[1024]; char* dptr = buf; int cnt =0; do { int cc = this->read(dptr,1); if (cc != 1 || (*dptr == '\n' && *(dptr-1) == '\n')) { break; } cnt++; dptr++; } while (cnt<1024); *dptr = '\0'; string x(buf); istringstream str(x); this->parseNRRD(str); } // check to see if we have a nonzero width, height, and bitpix if (!this->validParams()) return; // read data this->dataRead((size_t)this->pWidth_*this->pHeight_*this->pDepth_*abs(this->pBitpix_)/8, 0); // create blank header this->head_ = new FitsHead(this->pWidth_, this->pHeight_, this->pDepth_, this->pBitpix_); if (!this->head_->isValid()) { this->error(); return; } // do we need to byteswap? this->setByteSwap(); // made it this far, must be good this->valid_ = 1; this->orgFits_ = 0; if (this->flush_ == this->FLUSH) this->skipEnd(); } template class FitsNRRDStream<FILE*>; template class FitsNRRDStream<Tcl_Channel>; template class FitsNRRDStream<int>; template class FitsNRRDStream<gzFile>; template class FitsNRRDStream<gzStream>; template<class T> FitsMosaicStream<T>::FitsMosaicStream(FitsFile::FlushMode f) { if (!this->valid_) return; this->flush_ = f; this->primary_ = this->headRead(); this->managePrimary_ = 1; if (!(this->primary_ && this->primary_->isValid())) { this->error(); return; } this->dataSkipBlock(this->primary_->datablocks()); // first extension this->head_ = this->headRead(); if (!(this->head_ && this->head_->isValid())) { this->error(); return; } this->ext_++; // be sure to read all blocks, so that the next call starts on a boundary if (!this->dataRead(this->head_->datablocks()*FTY_BLOCK)) { this->error(); return; } // don't flush, more to come this->inherit_ = this->head_->inherit(); this->valid_ = 1; } template class FitsMosaicStream<FILE*>; template class FitsMosaicStream<Tcl_Channel>; template class FitsMosaicStream<int>; template class FitsMosaicStream<gzFile>; template class FitsMosaicStream<gzStream>; template<class T> FitsMosaicNextStream<T>::FitsMosaicNextStream(FitsFile* p, FitsFile::FlushMode f) { this->flush_ = f; FitsStream<T>* prev = (FitsStream<T>*)p; this->primary_ = prev->primary(); this->managePrimary_ = 0; this->stream_ = prev->stream(); this->ext_ = prev->ext(); this->head_ = this->headRead(); if (!(this->head_ && this->head_->isValid())) { this->error(); return; } this->ext_++; // be sure to read all blocks, so that the next call starts on a boundary if (!this->dataRead(this->head_->datablocks()*FTY_BLOCK)) { this->error(); return; } this->inherit_ = this->head_->inherit(); this->valid_ = 1; } template class FitsMosaicNextStream<FILE*>; template class FitsMosaicNextStream<Tcl_Channel>; template class FitsMosaicNextStream<int>; template class FitsMosaicNextStream<gzFile>; template class FitsMosaicNextStream<gzStream>; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/shmload.C��������������������������������������������������������������������0000644�0001750�0001750�00000003314�12132047320�015236� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <iostream> #include <fstream> using namespace std; main(int argc, char* argv[]) { int q=0; // check for args if (argc != 2 && argc != 3){ cerr << "usage: shmload [-q] fits" << endl; exit(1); } if (!strncmp(argv[1],"-q",2)) q=1; // find the file char* fn = argv[1+q]; struct stat statb; if (stat(fn, &statb) < 0){ cerr << "can't find file: " << fn << endl; exit(1); } size_t fnsize = statb.st_size; if (!q) cerr << fn << " size " << fnsize << endl; // calculate shmsize size_t shmsize = ((fnsize/2880)+1)*2880; // get shmid int shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT|0666); if (shmid == -1) { // give up, its bad perror("shmid is bad"); exit(1); } if (!q) cerr << "shmid " << shmid << endl; else cout << shmid << endl; // get shm stats struct shmid_ds sbuf; if (shmctl(shmid, IPC_STAT, &sbuf)<0) { perror("shmctl is bad"); exit(1); } if (!q) cerr << "size of shared segment: " << sbuf.shm_segsz << endl; char* addr = (char*)shmat(shmid, NULL, 0); // if (addr == -1){ // perror("shmat failed"); // exit(1); // } // load image ifstream fd(fn); fd.read(addr,fnsize); if (!q) { cerr << fd.gcount() << " bytes read" << endl; if (fd.gcount() != fnsize) cerr << "File read error" << endl; else cerr << "success!" << endl; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/rice.C�����������������������������������������������������������������������0000644�0001750�0001750�00000007623�12106546556�014560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "rice.h" extern "C" { int fits_rdecomp (unsigned char *c, int clen, unsigned int array[], int nx, int nblock); int fits_rdecomp_short (unsigned char *c, int clen, unsigned short array[], int nx, int nblock); int fits_rdecomp_byte (unsigned char *c, int clen, unsigned char array[], int nx, int nblock); void ffpmsg(const char* str) { if (DebugCompress) cerr << str << endl; } } template<class T> FitsRicem<T>::FitsRicem(FitsFile* fits) : FitsCompressm<T>(fits) { // rice parameters block_ = 32; bytepix_ = 4; noisebit_ = 4; char name[] = "ZNAME "; char val[] = "ZVAL "; for (int ii=0; ii<9; ii++) { name[5] = '0'+ii; val[4] = '0'+ii; if (fits->find(name)) { char* which = fits->getString(name); if (!strncmp(which,"BLOCK",4)) block_ = fits->getInteger(val,32); else if (!strncmp(which,"BYTEPIX",4)) bytepix_ = fits->getInteger(val,4); else if (!strncmp(which,"NOISEBIT",4)) noisebit_ = fits->getInteger(val,4); delete [] which; } } FitsCompressm<T>::uncompress(fits); } template <class T> int FitsRicem<T>::compressed(T* dest, char* sptr, char* heap, int kkstart, int kkstop, int jjstart, int jjstop, int iistart, int iistop) { double zs = FitsCompressm<T>::bscale_; if (FitsCompressm<T>::zscale_) zs = FitsCompressm<T>::zscale_->value(sptr,0); double zz = FitsCompressm<T>::bzero_; if (FitsCompressm<T>::zzero_) zz = FitsCompressm<T>::zzero_->value(sptr,0); int blank = FitsCompressm<T>::blank_; if (FitsCompressm<T>::zblank_) blank = (int)FitsCompressm<T>::zblank_->value(sptr,0); int icnt=0; unsigned char* ibuf = (unsigned char*)((FitsBinColumnArray*)FitsCompressm<T>::compress_)->get(heap, sptr, &icnt); // ibuf can be NULL if (ibuf && icnt>0) { int ocnt = FitsCompressm<T>::ww_ * FitsCompressm<T>::hh_ * FitsCompressm<T>::dd_; int ll=0; switch (bytepix_) { case 1: { char obuf[ocnt]; if (fits_rdecomp_byte(ibuf, icnt, (unsigned char*)obuf, ocnt, block_)) { internalError("Fitsy++ rice bad inflate result"); return 0; } for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); } break; case 2: { short obuf[ocnt]; if (fits_rdecomp_short(ibuf, icnt, (unsigned short*)obuf, ocnt, block_)) { internalError("Fitsy++ rice bad inflate result"); return 0; } for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); } break; case 4: { int obuf[ocnt]; if (fits_rdecomp(ibuf, icnt, (unsigned int*)obuf, ocnt, block_)) { internalError("Fitsy++ rice bad inflate result"); return 0; } for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); } break; } } return 1; } template class FitsRicem<unsigned char>; template class FitsRicem<short>; template class FitsRicem<unsigned short>; template class FitsRicem<int>; template class FitsRicem<long long>; template class FitsRicem<float>; template class FitsRicem<double>; �������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hpx.h������������������������������������������������������������������������0000644�0001750�0001750�00000001676�11777647374�014521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitshpx_h__ #define __fitshpx_h__ #include "vector.h" #include "file.h" class FitsHPX : public FitsFile { public: enum Order {RING, NESTED}; enum CoordSys {UNKNOWN, EQU, GAL, ECL}; enum Layout {EQUATOR=0, NORTH=1, SOUTH=2}; private: Order order_; CoordSys coord_; Layout layout_; int quad_; int width_; int height_; size_t size_; FitsBinColumn* col_; long nside_; long nfacet_; void build(FitsFile*); int initHeader(FitsFile*); void swap(); void NESTidx(int facet, int rotn, int jmap, long *healidx); void RINGidx(int facet, int rotn, int jmap, long *healidx); public: FitsHPX(FitsFile*, Order, CoordSys, Layout, int, int); ~FitsHPX(); }; class FitsHPXNext : public FitsFile { public: FitsHPXNext(FitsFile* prev); }; #endif ������������������������������������������������������������������./saods9/saotk/fitsy++/var.h������������������������������������������������������������������������0000644�0001750�0001750�00000002577�12041601171�014455� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsvar_h__ #define __fitsvar_h__ #include "map.h" class FitsVar : public virtual FitsMap { Tcl_Obj* obj; public: FitsVar(Tcl_Interp*, const char*, const char*); virtual ~FitsVar(); }; class FitsFitsVar : public FitsVar, public FitsFitsMap { public: FitsFitsVar(Tcl_Interp* interp, const char* var, const char* fn, ScanMode mode) : FitsVar(interp, var, fn), FitsFitsMap(mode) {} }; class FitsFitsNextVar : public FitsFitsNextMap { public: FitsFitsNextVar(FitsFile* prev) : FitsFitsNextMap(prev) {} }; class FitsArrVar : public FitsVar, public FitsArrMap { public: FitsArrVar(Tcl_Interp* interp, const char* var, const char* fn) : FitsVar(interp, var, fn), FitsArrMap() {} }; class FitsNRRDVar : public FitsVar, public FitsNRRDMap { public: FitsNRRDVar(Tcl_Interp* interp, const char* var, const char* fn) : FitsVar(interp, var, fn), FitsNRRDMap() {} }; class FitsMosaicVar : public FitsVar, public FitsMosaicMap { public: FitsMosaicVar(Tcl_Interp* interp, const char* var, const char* fn) : FitsVar(interp, var, fn), FitsMosaicMap() {} }; class FitsMosaicNextVar : public FitsMosaicNextMap { public: FitsMosaicNextVar(FitsFile* prev) : FitsMosaicNextMap(prev) {} }; #endif ���������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outchannel.h�����������������������������������������������������������������0000644�0001750�0001750�00000000642�12001356756�016030� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __outchannel_h__ #define __outchannel_h__ #include "outfits.h" class OutFitsChannel : public virtual OutFitsStream { private: Tcl_Channel ch_; public: OutFitsChannel(Tcl_Interp*, const char*); int write(char*, size_t); }; #endif ����������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outsocket.C������������������������������������������������������������������0000644�0001750�0001750�00000006351�12075604063�015644� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <sys/types.h> #include <sys/socket.h> #include "outsocket.h" #include "file.h" OutFitsSocket::OutFitsSocket(int s) { id_ = s; valid_ = 1; } int OutFitsSocket::write(char* where, size_t size) { // size_t size is unsigned long long ss = size; size_t rr =0; int r; do { r = (ss>B4KB) ? B4KB : ss; send(id_, where+rr, r, 0); if (r == -1) { internalError("Fitsy++ outsocket write error"); return -1; } ss -= r; rr += r; } while (r>0 && rr<size); return rr; } OutFitsSocketGZ::OutFitsSocketGZ(int s) { id_ = s; stream_ = new z_stream; buf_ = new unsigned char[B4KB]; crc_ = crc32(0L, Z_NULL, 0); stream_->next_in = NULL; stream_->avail_in = 0; stream_->next_out = NULL; stream_->avail_out = 0; stream_->zalloc = NULL; stream_->zfree = NULL; stream_->opaque = NULL; if (deflateInit2(stream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) { internalError("Fitsy++ outsocket deflateInit error"); return; } // dump simple header char header[10] = {0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x03}; send(id_, header, 10, 0); stream_->next_out = buf_; stream_->avail_out = B4KB; valid_ = 1; } OutFitsSocketGZ::~OutFitsSocketGZ() { // flush any pending output while (deflategz(Z_FINISH) == Z_OK); // output crc/length putlong(crc_); putlong(stream_->total_in); if (deflateEnd(stream_) != Z_OK) internalError("Fitsy++ outsocket deflateEnd error"); if (stream_) delete stream_; if (buf_) delete [] buf_; } int OutFitsSocketGZ::write(char* where, size_t size) { stream_->next_in = (unsigned char*)where; stream_->avail_in = size; if (DebugGZ) cerr << "write " << size << endl; while (stream_->avail_in > 0 && deflategz(Z_NO_FLUSH) == Z_OK); // update crc crc_ = crc32(crc_, (const Bytef *)where, size); return size - stream_->avail_in; } int OutFitsSocketGZ::deflategz(int flush) { int result = deflate(stream_, flush); switch (result) { case Z_OK: if (DebugGZ) cerr << "deflate OK: avail_in " << stream_->avail_in << " avail_out " << stream_->avail_out << endl; break; case Z_STREAM_END: if (DebugGZ) cerr << "deflate STRM_END: avail_in " << stream_->avail_in << " avail_out " << stream_->avail_out << endl; break; default: if (DebugGZ) cerr << "deflate Error " << result << endl; return result; } if (stream_->avail_out == 0 || result != Z_OK) { int s = B4KB - stream_->avail_out; unsigned char* d = buf_; while (s>0) { int r = send(id_, d, s, 0); if (r == -1) { internalError("Fitsy++ outsocket deflate send error"); return Z_ERRNO; } if (DebugGZ) cerr << "deflate send " << r << " out of " << s << endl; s -= r; d += r; } stream_->next_out = buf_; stream_->avail_out = B4KB; } return result; } void OutFitsSocketGZ::putlong(unsigned long l) { // dump in LSB order for (int n = 0; n < 4; n++) { unsigned char foo = (int)(l & 0xff); send(id_, &foo, 1, 0); l >>= 8; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdparser.Y�����������������������������������������������������������������0000644�0001750�0001750�00000015447�12044561570�016043� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {FitsFile* nrrd} %lex-param {nrrdFlexLexer* ll} %parse-param {nrrdFlexLexer* ll} %{ #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; nrrdDiscard(x);} #include "file.h" #undef yyFlexLexer #define yyFlexLexer nrrdFlexLexer #include <FlexLexer.h> extern int nrrdlex(void*, nrrdFlexLexer*); extern void nrrderror(FitsFile*, nrrdFlexLexer*, const char*); extern void nrrdDiscard(int); int dim; %} %union { #define NRRDPARSERSIZE 256 float real; int integer; char str[NRRDPARSERSIZE]; } %type <real> numeric // Basic %token EOF_ %token <integer> INT %token <real> REAL %token <str> STRING %token DEBUG_ %token ON_ %token OFF_ // Magic %token NRRD0001_ %token NRRD0002_ %token NRRD0003_ %token NRRD0004_ %token NRRD0005_ // 3. Headers %token DATA_ %token FILE_ // 4. Space %token SPACE_ %token UNITS_ %token DIMENSIONS_ %token ORIGIN_ %token DIRECTIONS_ // 5.1 Dimension %token DIMENSION_ // 5.2 Type %token TYPE_ %token SIGNED_ %token UNSIGNED_ %token CHAR_ %token INT8_ %token INT8_T_ %token UCHAR_ %token UINT8_ %token UINT8_T_ %token SHORT_ %token INT_ %token INT16_ %token INT16_T_ %token USHORT_ %token UINT16_ %token UINT16_T_ %token INT32_ %token INT32_T_ %token UINT_ %token UINT32_ %token UINT32_T_ %token LONG_ %token LONGLONG_ %token INT64_ %token INT64_T_ %token ULONGLONG_ %token UINT64_ %token UINT64_T_ %token FLOAT_ %token DOUBLE_ // 5.3 Block %token BLOCK_ %token SIZE_ %token BLOCKSIZE_ // 5.4 ENCODING %token ENCODING_ %token RAW_ %token TXT_ %token TEXT_ %token ASCII_ %token HEX_ %token GZ_ %token GZIP_ %token BZ2_ %token BZIP2_ // 5.5 Endian %token ENDIAN_ %token BIG_ %token LITTLE_ // 5.6 Content %token CONTENT_ // 5.7 MinMax %token OLD_ %token MIN_ %token OLDMIN_ %token MAX_ %token OLDMAX_ // 5.8 Skip %token SKIP_ %token LINE_ %token LINESKIP_ %token BYTE_ %token BYTESKIP_ // 5.9 Number %token NUMBER_ // 5.10 Sample %token SAMPLE_ %token SAMPLEUNITS_ // 6 Per Axis %token SIZES_ %token SPACINGS_ %token THICKNESSES_ %token AXIS_ %token MINS_ %token AXISMINS_ %token MAXS_ %token AXISMAXS_ %token CENTERS_ %token CENTERINGS_ %token CELL_ %token NODE_ %token NONE_ %token LABELS_ %token KINDS_ %token DOMAINS_ %% start : {dim=0;} commands ; commands: commands command terminator | command terminator ; command : /* empty */ | DEBUG_ debug | magic | comment | DATA_ FILE_ ':' STRING | SPACE_ space | DIMENSION_ ':' INT | TYPE_ ':' type | block | ENCODING_ ':' encoding | ENDIAN_ ':' endian | CONTENT_ ':' {DISCARD_(1)} STRING | MIN_ ':' numeric | MAX_ ':' numeric | oldmin | oldmax | lineskip | byteskip | NUMBER_ ':' STRING | SIZES_ ':' sizes | SPACINGS_ ':' spacings | THICKNESSES_ ':' thicknesses | AXIS_ MINS_ ':' axismins | AXISMINS_ ':' axismins | AXIS_ MAXS_ ':' axismaxs | AXISMAXS_ ':' axismaxs | CENTERS_ ':' centers | CENTERINGS_ ':' centers | LABELS_ ':' labels | UNITS_ ':' units | KINDS_ ':' kinds ; magic : NRRD0001_ | NRRD0002_ | NRRD0003_ | NRRD0004_ | NRRD0005_ ; comment : '#' {DISCARD_(1)} STRING ; terminator: '\n' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; space : ':' {DISCARD_(1)} STRING | DIMENSION_ ':' INT | UNITS_ ':' {DISCARD_(1)} STRING | ORIGIN_ ':' {DISCARD_(1)} STRING | DIRECTIONS_ ':' {DISCARD_(1)} STRING ; type : char {nrrd->setpBitpix(8);} | uchar {nrrd->setpBitpix(8);} | short {nrrd->setpBitpix(16);} | ushort {nrrd->setpBitpix(16);} | int {nrrd->setpBitpix(32);} | uint {nrrd->setpBitpix(32);} | long {nrrd->setpBitpix(64);} | ulong {nrrd->setpBitpix(64);} | FLOAT_ {nrrd->setpBitpix(-32);} | DOUBLE_ {nrrd->setpBitpix(-64);} | BLOCK_ ; char : CHAR_ | SIGNED_ CHAR_ | INT8_ | INT8_T_ ; uchar : UCHAR_ | UNSIGNED_ CHAR_ | UINT8_ | UINT8_T_ ; short : SHORT_ | SHORT_ INT_ | SIGNED_ SHORT_ | SIGNED_ SHORT_ INT_ | INT16_ | INT16_T_ ; ushort : USHORT_ | UNSIGNED_ SHORT_ | UNSIGNED_ SHORT_ INT_ | UINT16_ | UINT16_T_ ; int : INT_ | SIGNED_ INT_ | INT32_ | INT32_T_ ; uint : UINT_ | UNSIGNED_ INT_ | UINT32_ | UINT32_T_ ; long : LONGLONG_ | LONG_ LONG_ | LONG_ LONG_ INT_ | SIGNED_ LONG_ LONG_ | SIGNED_ LONG_ LONG_ INT_ | INT64_ | INT64_T_ ; ulong : ULONGLONG_ | UNSIGNED_ LONG_ LONG_ | UNSIGNED_ LONG_ LONG_ INT_ | UINT64_ | UINT64_T_ ; block : BLOCK_ SIZE_ ':' INT | BLOCKSIZE_ ':' INT ; encoding : RAW_ {nrrd->setpNRRDEncoding(FitsFile::RAW);} | TXT_ {nrrd->setpNRRDEncoding(FitsFile::ASCII);} | TEXT_ {nrrd->setpNRRDEncoding(FitsFile::ASCII);} | ASCII_ {nrrd->setpNRRDEncoding(FitsFile::ASCII);} | HEX_ {nrrd->setpNRRDEncoding(FitsFile::HEX);} | GZ_ {nrrd->setpNRRDEncoding(FitsFile::GZIP);} | GZIP_ {nrrd->setpNRRDEncoding(FitsFile::GZIP);} | BZ2_ {nrrd->setpNRRDEncoding(FitsFile::BZ2);} | BZIP2_ {nrrd->setpNRRDEncoding(FitsFile::BZ2);} ; endian : BIG_ {nrrd->setpArch(FitsFile::BIG);} | LITTLE_ {nrrd->setpArch(FitsFile::LITTLE);} ; oldmin : OLD_ MIN_ ':' numeric | OLDMIN_ ':' numeric ; oldmax : OLD_ MAX_ ':' numeric | OLDMAX_ ':' numeric ; lineskip : LINE_ SKIP_ ':' INT | LINESKIP_ ':' INT ; byteskip : BYTE_ SKIP_ ':' INT | BYTESKIP_ ':' INT ; sizes : sizes size | size ; size : INT { switch (dim) { case 0: nrrd->setpWidth($1); break; case 1: nrrd->setpHeight($1); break; case 2: nrrd->setpDepth($1); break; } dim++; nrrd->setpNRRDDimension(dim); } ; spacings : spacings numeric | numeric ; thicknesses : thicknesses numeric | numeric ; axismins : axismins numeric | numeric ; axismaxs : axismaxs numeric | numeric ; centers : centers center | center ; center : CELL_ | NODE_ | NONE_ ; labels : labels STRING | STRING ; units : units STRING | STRING ; kinds : kinds STRING | STRING ; %% �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/compress.h�������������������������������������������������������������������0000644�0001750�0001750�00000002672�11777365507�015545� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitscompress_h__ #define __fitscompress_h__ #include "file.h" class FitsCompress : public FitsFile { protected: int bitpix_; int width_; int height_; int depth_; int ww_; int hh_; int dd_; double bscale_; double bzero_; unsigned int blank_; char* zmaskcmp_; size_t tilesize_; size_t size_; FitsColumn* compress_; FitsColumn* uncompress_; FitsColumn* zscale_; FitsColumn* zzero_; FitsColumn* zblank_; FitsColumn* null_; int hasScaling_; int hasBlank_; protected: int initHeader(FitsFile*); public: FitsCompress(FitsFile*); virtual ~FitsCompress(); }; template<class T> class FitsCompressm : public FitsCompress { private: int inflate(FitsFile*); void swapBytes(); protected: T swap(T* ptr); protected: void uncompress(FitsFile* fits); virtual int compressed(T*, char*, char*, int, int, int, int, int, int) =0; T getValue(char*, double, double, int); T getValue(short*, double, double, int); T getValue(int*, double, double, int); T getValue(long long*, double, double, int); T getValue(float*, double, double, int); T getValue(double*, double, double, int); public: FitsCompressm(FitsFile*); }; class FitsCompressNext : public FitsFile { public: FitsCompressNext(FitsFile* prev); }; #endif ����������������������������������������������������������������������./saods9/saotk/fitsy++/iis.h������������������������������������������������������������������������0000644�0001750�0001750�00000000673�12057474474�014471� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsiis_h__ #define __fitsiis_h__ #include "file.h" class FitsIIS : public FitsFile { public: FitsIIS(int, int); ~FitsIIS(); void erase(); char* get(int xx, int yy, int dx, int dy); void set(const char* src, int xx, int yy, int dx, int dy); }; #endif ���������������������������������������������������������������������./saods9/saotk/fitsy++/parser.H���������������������������������������������������������������������0000644�0001750�0001750�00000006644�12044277032�015130� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, INTP = 259, STRING = 260, ARCH_ = 261, ARRAY_ = 262, BIG_ = 263, BIGENDIAN_ = 264, BIN_ = 265, BINKEY_ = 266, BINCOL_ = 267, BITPIX_ = 268, COL_ = 269, DIM_ = 270, DIMS_ = 271, ECLIPTIC_ = 272, ENDIAN_ = 273, EQUATORIAL_ = 274, GALACTIC_ = 275, KEY_ = 276, LAYOUT_ = 277, LITTLE_ = 278, LITTLEENDIAN_ = 279, NESTED_ = 280, NORTH_ = 281, ORDER_ = 282, QUAD_ = 283, RING_ = 284, SKIP_ = 285, SOUTH_ = 286, SYSTEM_ = 287, UNKNOWN_ = 288, XDIM_ = 289, YDIM_ = 290, ZDIM_ = 291 }; #endif /* Tokens. */ #define INT 258 #define INTP 259 #define STRING 260 #define ARCH_ 261 #define ARRAY_ 262 #define BIG_ 263 #define BIGENDIAN_ 264 #define BIN_ 265 #define BINKEY_ 266 #define BINCOL_ 267 #define BITPIX_ 268 #define COL_ 269 #define DIM_ 270 #define DIMS_ 271 #define ECLIPTIC_ 272 #define ENDIAN_ 273 #define EQUATORIAL_ 274 #define GALACTIC_ 275 #define KEY_ 276 #define LAYOUT_ 277 #define LITTLE_ 278 #define LITTLEENDIAN_ 279 #define NESTED_ 280 #define NORTH_ 281 #define ORDER_ 282 #define QUAD_ 283 #define RING_ 284 #define SKIP_ 285 #define SOUTH_ 286 #define SYSTEM_ 287 #define UNKNOWN_ 288 #define XDIM_ 289 #define YDIM_ 290 #define ZDIM_ 291 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 32 "parser.Y" { float real; int integer; char str[256]; void* ptr; } /* Line 1529 of yacc.c. */ #line 128 "parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ��������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/share.C����������������������������������������������������������������������0000644�0001750�0001750�00000003335�11700666265�014733� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifdef HAVE_SYS_SHM_H #include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> #include "share.h" FitsShareID::FitsShareID(int shmid, const char* filter) { parse(filter); // find size struct shmid_ds info; if (shmctl(shmid, IPC_STAT, &info)) { internalError("Fitsy++ share shctl failed"); return; } mapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(mapdata_ = (char*)shmat(shmid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ share shctl failed"); return; } // so far so good valid_ = 1; } FitsShareID::~FitsShareID() { shmdt(mapdata_); } FitsShareKey::FitsShareKey(int key, const char* filter) { parse(filter); // get shmid int shmid; if ((shmid = shmget(key, 0, 0)) < 0) { internalError("Fitsy++ share shmget failed"); return; } // find size struct shmid_ds info; if (shmctl(shmid, IPC_STAT, &info)) { internalError("Fitsy++ share shctl failed"); return; } mapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(mapdata_ = (char*)shmat(shmid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ share shmat failed"); return; } // so far so good valid_ = 1; } FitsShareKey::~FitsShareKey() { if (mapdata_>0) shmdt(mapdata_); } #else #include "share.h" FitsShareID::FitsShareID(int shmid, const char* filter) { // shared memory not supported valid_ = 0; } FitsShareID::~FitsShareID() {} FitsShareKey::FitsShareKey(int key, const char* filter) { // shared memory not supported valid_ = 0; } FitsShareKey::~FitsShareKey() {} #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/alloc.C����������������������������������������������������������������������0000644�0001750�0001750�00000001002�12121676022�014676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "alloc.h" FitsAlloc::FitsAlloc(const char* fn) { parse(fn); // we need the 'b' for windows... if (!strncmp(pName_, "stdin", 5) || !strncmp(pName_, "STDIN", 5) || !strncmp(pName_, "-", 1)) stream_ = fdopen(dup(fileno(stdin)), "rb"); else stream_ = fopen(pName_, "rb"); if (stream_) valid_ = 1; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mapincr.h��������������������������������������������������������������������0000644�0001750�0001750�00000002645�11777647374�015350� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsmapincr_h__ #define __fitsmapincr_h__ #include "file.h" class FitsMapIncr : public FitsFile { protected: char* mapdata_; // mmap segment ptr size_t mapsize_; // mmap segment size int page_; // flag to indicate paging mode size_t filesize_; // size of the total segment size_t seek_; // offset into segment size_t dseek_; // offset to data segment size_t nseek_; // offset into next page data segment FitsHead* headRead(); void dataSkip(size_t); void dataSkipBlock(size_t); void found(); void error(); public: FitsMapIncr(); virtual ~FitsMapIncr(); char* page(char*, size_t); void resetpage(); size_t filesize() {return filesize_;} size_t seek() {return seek_;} }; class FitsFitsMapIncr : public virtual FitsMapIncr { protected: void processExact(); void processRelax(); public: FitsFitsMapIncr(ScanMode); }; class FitsFitsNextMapIncr : public FitsMapIncr { public: FitsFitsNextMapIncr(FitsFile* prev); }; class FitsArrMapIncr : public virtual FitsMapIncr { public: FitsArrMapIncr(); }; class FitsMosaicMapIncr : public virtual FitsMapIncr { public: FitsMosaicMapIncr(); }; class FitsMosaicNextMapIncr : public FitsMapIncr { public: FitsMosaicNextMapIncr(FitsFile* prev); }; #endif �������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/socketgz.C�������������������������������������������������������������������0000644�0001750�0001750�00000006244�12075604063�015456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <sys/types.h> #include <sys/socket.h> #include "socketgz.h" #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ FitsSocketGZ::FitsSocketGZ(int s, const char* ext) { parse(ext); if (!s) return; stream_ = new gzStream_; stream_->id = s; stream_->transparent = 0; memset(stream_->header,'\0',2); stream_->useHeader = 0; stream_->buf = new unsigned char[B4KB]; // magic bytes if (recv(stream_->id , stream_->header, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read magic bytes in header"); return; } if (stream_->header[0] != 0x1f || stream_->header[1] != 0x8b) { stream_->transparent = 1; stream_->useHeader = 1; } else { ((z_stream*)stream_)->next_in = NULL; ((z_stream*)stream_)->avail_in = 0; ((z_stream*)stream_)->zalloc = NULL; ((z_stream*)stream_)->zfree = NULL; ((z_stream*)stream_)->opaque = NULL; if (inflateInit2((z_stream*)stream_, -MAX_WBITS) != Z_OK) { internalError("Fitsy++ socketgz inflateInit error"); return; } unsigned char buf[128]; // method/flags if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read method/flags bytes in header"); return; } int method = buf[0]; int flags = buf[1]; if (method != Z_DEFLATED || (flags & RESERVED) != 0) { internalError("Fitsy++ socketgz bad method/flags"); return; } // Discard time, xflags and OS code if (recv(stream_->id , buf, 6, 0) != 6) { internalError("Fitsy++ socketgz can't read time/xflags/os bytes in header"); return; } // skip the extra field if ((flags & EXTRA_FIELD) != 0) { if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read extra field length bytes in header"); return; } int len = buf[0]; len += buf[1]<<8; if (recv(stream_->id , buf, len, 0) != len) { internalError("Fitsy++ socketgz can't read extra field bytes in header"); return; } } // skip the original file name if ((flags & ORIG_NAME) != 0) { while (recv(stream_->id , buf, 1, 0) == 1 && buf[0] != 0) ; } // skip the .gz file comment if ((flags & COMMENT) != 0) { while (recv(stream_->id , buf, 1, 0) == 1 && buf[0] != 0) ; } // skip the header crc if ((flags & HEAD_CRC) != 0) { if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read header crc bytes in header"); return; } } } if (DebugGZ) cerr << "inflateInt Complete" << endl; valid_ = 1; } FitsSocketGZ::~FitsSocketGZ() { if (stream_->buf) delete [] stream_->buf; if (stream_) delete stream_; stream_ = NULL; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/file.h�����������������������������������������������������������������������0000644�0001750�0001750�00000015050�12122377573�014612� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsfile_h__ #define __fitsfile_h__ #include <tcl.h> #include "head.h" #define B4KB 4096 #define B1MB 1048576 extern int DebugGZ; extern int DebugCompress; class OutFitsStream; class FitsFile { public: enum FlushMode {NOFLUSH,FLUSH}; enum ScanMode {RELAX, EXACT}; enum ArchType {NATIVE,BIG,LITTLE}; enum EncodingType {RAW,ASCII,HEX,GZIP,BZ2}; char* pName_; // parsed file name protected: FitsHead* primary_; // pointer to primary header int managePrimary_; // flag, true if we manage primary header FitsHead* head_; // pointer to header int manageHead_; // flag, true if we manage header void* data_; // pointer to raw data size_t dataSize_; // size of data memory segment size_t dataSkip_; // skip into data memory segment int ext_; // extension number int inherit_; // do we have inheritence? int byteswap_; // flag, true if byteswap is needed int orgFits_; // flag to indicate origin int valid_; // flag, true if file is valid char* pExt_; // parsed ext name int pIndex_; // parsed ext number char* pFilter_; // unparsed filter spec char* pBinX_; // parsed bin table x col name char* pBinY_; // parsed bin table y col name char* pBinZ_; // parsed bin table z col name int pWidth_; // parsed array width int pHeight_; // parsed array height int pDepth_; // parsed array depth int pBitpix_; // parsed array bitpix size_t pSkip_; // parsed array skip size ArchType pArch_; // parsed array arch type EncodingType pNRRDEncoding_; int pNRRDDimension_; int pHPXOrder_; // parsed HPX params int pHPXSystem_; int pHPXLayout_; int pHPXColumn_; int pHPXQuad_; int coord_; int xvalid_; int xmin_; int xmax_; int yvalid_; int ymin_; int ymax_; int zvalid_; int zmin_; int zmax_; protected: void parse(const char*); void parseNRRD(istream&); int validParams(); int findEnd(const char*); void setByteSwap(); public: FitsFile(); virtual ~FitsFile(); virtual void done() {} virtual char* page(char* ptr, size_t r) {return ptr;} virtual void resetpage() {} void error(const char*); void* data() {return data_;} size_t dataSize() {return dataSize_;} size_t dataSkip() {return dataSkip_;} FitsHead* head() {return head_;} FitsHead* primary() {return primary_;} int ext() {return ext_;} const char* extname() {return head_ ? head_->extname() : NULL;} int inherit() {return inherit_;} int isValid() {return valid_;} int isImage() {return head_ ? head_->isImage() : 0;} int isTable() {return head_ ? head_->isTable() : 0;} int isAsciiTable() {return head_ ? head_->isAsciiTable() : 0;} int isBinTable() {return head_ ? head_->isBinTable() : 0;} int byteswap() {return byteswap_;} int orgFits() {return orgFits_;} void setpName(const char*); void setpExt(const char*); void setpIndex(int i) {pIndex_ = i;} void setpFilter(const char*); void setpBinX(const char*); void setpBinY(const char*); void setpBinZ(const char*); void setpBinXY(const char* x, const char* y) {setpBinX(x); setpBinY(y);} void setpBinXYZ(const char* x, const char* y, const char* z) {setpBinX(x); setpBinY(y); setpBinZ(z);} const char* pName() {return pName_;} const char* pExt() {return pExt_;} int pIndex() {return pIndex_;} const char* pFilter() {return pFilter_;} const char* pBinX() {return pBinX_;} const char* pBinY() {return pBinY_;} const char* pBinZ() {return pBinZ_;} int pWidth() {return pWidth_;} int pHeight() {return pHeight_;} int pDepth() {return pDepth_;} int pBitpix() {return pBitpix_;} size_t pSkip() {return pSkip_;} ArchType pArch() {return pArch_;} void setpWidth(int i) {pWidth_ = i;} void setpHeight(int i) {pHeight_ = i;} void setpDepth(int i) {pDepth_ = i;} void setpBitpix(int b) {pBitpix_ = b;} void setpSkip(size_t s) {pSkip_ = s;} void setpArch(ArchType a) {pArch_ = a;} EncodingType pNRRDEncoding() {return pNRRDEncoding_;} int pNRRDDimension() {return pNRRDDimension_;} void setpNRRDEncoding(EncodingType e) {pNRRDEncoding_ = e;} void setpNRRDDimension(int d) {pNRRDDimension_ = d;} int pHPXOrder() {return pHPXOrder_;} int pHPXSystem() {return pHPXSystem_;} int pHPXLayout() {return pHPXLayout_;} int pHPXColumn() {return pHPXColumn_;} int pHPXQuad() {return pHPXQuad_;} void setpHPXOrder(int oo) {pHPXOrder_ = oo;} void setpHPXSystem(int ss) {pHPXSystem_ = ss;} void setpHPXLayout(int ll) {pHPXLayout_ = ll;} void setpHPXColumn(int cc) {pHPXColumn_ = cc-1;} void setpHPXQuad(int qq) {pHPXQuad_ = qq-1;} int coord() {return coord_;} int xvalid() {return xvalid_;} int xmin() {return xmin_;} int xmax() {return xmax_;} int yvalid() {return yvalid_;} int ymin() {return ymin_;} int ymax() {return ymax_;} int zvalid() {return zvalid_;} int zmin() {return zmin_;} int zmax() {return zmax_;} void setCoord(int vv) {coord_ = vv;} void setXValid(int vv) {xvalid_ = vv;} void setXMin(int vv) {xmin_ = vv;} void setXMax(int vv) {xmax_ = vv;} void setYValid(int vv) {yvalid_ = vv;} void setYMin(int vv) {ymin_ = vv;} void setYMax(int vv) {ymax_ = vv;} void setZValid(int vv) {zvalid_ = vv;} void setZMin(int vv) {zmin_ = vv;} void setZMax(int vv) {zmax_ = vv;} Vector getColMinMax(const char*); Vector getColDim(const char*); void setColMinMax(const char*, const Vector&); int find(const char* name, FitsHead* alt=NULL); int getLogical(const char* name, int def, FitsHead* alt=NULL); int getInteger(const char* name, int def, FitsHead* alt=NULL); double getReal(const char* name, double def, FitsHead* alt=NULL); void getComplex(const char* name, double* real, double* img, double rdef, double idef, FitsHead* alt=NULL); char* getString(const char* name, FitsHead* alt=NULL); char* getComment(const char* name, FitsHead* alt=NULL); char* getKeyword(const char* name, FitsHead* alt=NULL); int saveFitsPrimHeader(OutFitsStream&); int saveFitsHeader(OutFitsStream&, int); int saveFitsXtHeader(OutFitsStream&, int); int saveFits(OutFitsStream&); int saveFitsPad(OutFitsStream&, size_t, char); int saveFitsTable(OutFitsStream&); int saveArray(OutFitsStream&, ArchType); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/gzip.C�����������������������������������������������������������������������0000644�0001750�0001750�00000012573�11744322655�014606� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "gzip.h" #include "zlib.h" #include "util.h" template<class T> FitsGzipm<T>::FitsGzipm(FitsFile* fits) : FitsCompressm<T>(fits) { noquantize_ = 0; char keyword[] = "ZQUANTIZ"; if (fits->find(keyword)) { char* which = fits->getString(keyword); if (!strncmp(which,"NONE",4)) noquantize_ = 1; delete [] which; } FitsCompressm<T>::uncompress(fits); } template <class T> int FitsGzipm<T>::compressed(T* dest, char* sptr, char* heap, int kkstart, int kkstop, int jjstart, int jjstop, int iistart, int iistop) { double zs = FitsCompressm<T>::bscale_; if (FitsCompressm<T>::zscale_) zs = FitsCompressm<T>::zscale_->value(sptr,0); double zz = FitsCompressm<T>::bzero_; if (FitsCompressm<T>::zzero_) zz = FitsCompressm<T>::zzero_->value(sptr,0); int blank = FitsCompressm<T>::blank_; if (FitsCompressm<T>::zblank_) blank = (int)FitsCompressm<T>::zblank_->value(sptr,0); int icnt=0; unsigned char* ibuf = (unsigned char*)((FitsBinColumnArray*)FitsCompressm<T>::compress_)->get(heap, sptr, &icnt); // ibuf can be NULL if (ibuf && icnt>0) { int ocnt = FitsCompressm<T>::ww_ * FitsCompressm<T>::hh_ * FitsCompressm<T>::dd_; char obuf[ocnt*sizeof(int)]; z_stream zstrm; zstrm.next_in = NULL; zstrm.avail_in = 0; zstrm.zalloc = NULL; zstrm.zfree = NULL; zstrm.opaque = NULL; // look for both zlib and gzip headers if (inflateInit2(&zstrm, MAX_WBITS+32) != Z_OK) { internalError("Fitsy++ gzip inflateInit error"); return 0; } zstrm.avail_in = icnt; zstrm.next_in = ibuf; zstrm.avail_out = ocnt*sizeof(int); zstrm.next_out = (Bytef*)obuf; if (DebugCompress) cerr << " inflate START: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; int result = ::inflate(&zstrm, Z_FINISH); switch (result) { case Z_OK: if (DebugCompress) cerr << " inflate OK: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_STREAM_END: if (DebugCompress) cerr << " inflate STREAM_END: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_BUF_ERROR: if (DebugCompress) cerr << " inflate BUF_ERROR: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << endl; return 0; default: internalError("Fitsy++ gzip inflate error"); return 0; } int bytepix = zstrm.total_out/FitsCompressm<T>::tilesize_; inflateEnd(&zstrm); int ll=0; switch (bytepix) { case 1: for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); break; case 2: for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) { // swap if needed if (FitsCompressm<T>::byteswap_) { const char* p = (const char*)((short*)obuf+ll); union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; *((short*)obuf+ll) = u.s; } dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue((short*)obuf+ll,zs,zz,blank); } break; case 4: // special case if (noquantize_) { for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) { // swap if needed if (FitsCompressm<T>::byteswap_) { const char* p = (const char*)((float*)obuf+ll); union { char c[4]; float i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; *((float*)obuf+ll) = u.i; } dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue((float*)obuf+ll,zs,zz,blank); } } else { for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) { // swap if needed if (FitsCompressm<T>::byteswap_) { const char* p = (const char*)((int*)obuf+ll); union { char c[4]; int i; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; *((int*)obuf+ll) = u.i; } dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue((int*)obuf+ll,zs,zz,blank); } } break; } } return 1; } template class FitsGzipm<unsigned char>; template class FitsGzipm<short>; template class FitsGzipm<unsigned short>; template class FitsGzipm<int>; template class FitsGzipm<long long>; template class FitsGzipm<float>; template class FitsGzipm<double>; �������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/column.C���������������������������������������������������������������������0000644�0001750�0001750�00000026556�12077017542�015134� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <stdlib.h> #include <string.h> #include <ctype.h> #include <limits.h> #include <float.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "column.h" #include "file.h" #include "head.h" FitsColumn::FitsColumn(FitsHead* head, int i, int off) { index_ = i; width_ = 0; offset_ = off; type_ = ' '; tform_ = head->getString(keycat("TFORM",i)); ttype_ = head->getString(keycat("TTYPE",i)); tunit_ = head->getString(keycat("TUNIT",i)); tscal_ = head->getReal(keycat("TSCAL",i), 1); tzero_ = head->getReal(keycat("TZERO",i), 0); hastnull_ = head->find(keycat("TNULL",i)) ? 1:0; tnull_ = head->getInteger(keycat("TNULL",i), 0); char* td = head->find(keycat("TDMAX",i)); char* tl = head->find(keycat("TLMAX",i)); char* ta = head->find(keycat("TALEN",i)); char* ax = head->find(keycat("AXLEN",i)); // this provides backward compatibility if (td) { hastlmin_ = head->find(keycat("TDMIN",i)) ? 1:0; hastlmax_ = 1; tlmin_ = head->getReal(keycat("TDMIN",i), 0); tlmax_ = head->getReal(keycat("TDMAX",i), 0); } else if (tl) { hastlmin_ = head->find(keycat("TLMIN",i)) ? 1:0; hastlmax_ = 1; tlmin_ = head->getReal(keycat("TLMIN",i), 0); tlmax_ = head->getReal(keycat("TLMAX",i), 0); } else if (ta) { hastlmin_ = 0; hastlmax_ = 1; tlmin_ = 1; tlmax_ = head->getReal(keycat("TALEN",i), 0); } else if (ax) { hastlmin_ = 0; hastlmax_ = 1; tlmin_ = 1; tlmax_ = head->getReal(keycat("AXLEN",i), 0); } else { hastlmin_ = 0; hastlmax_ = 0; tlmin_ = 0; tlmax_ = 0; } // now, make sure they are valid if (tlmin_>tlmax_) { hastlmin_ = 0; hastlmax_ = 0; tlmin_ = 0; tlmax_ = 0; } // use tlmin/tlmax if available if (hastlmin_ || hastlmax_) { min_ = tlmin_; max_ = tlmax_; } else { min_ = -DBL_MAX; max_ = DBL_MAX; } } FitsColumn::~FitsColumn() { if (tform_) delete [] tform_; if (tunit_) delete [] tunit_; if (ttype_) delete [] ttype_; } char* FitsColumn::keycat(const char* name, int i) { ostringstream str; str << name << i << ends; memcpy(keybuf,str.str().c_str(),str.str().length()); return keybuf; } // FitsAsciiColumn FitsAsciiColumn::FitsAsciiColumn(FitsHead* head, int i, int offset) : FitsColumn(head, i, offset) { int tbcol = head->getInteger(keycat("TBCOL",i),0); if (tbcol) offset_ = tbcol-1; } char* FitsAsciiColumn::str(const char* ptr, int i) { strncpy(buf_, ptr+offset_, width_); buf_[width_] = '\0'; return buf_; } FitsAsciiColumnStr::FitsAsciiColumnStr(FitsHead* head, int i, int offset) : FitsAsciiColumn(head, i, offset) { if (tform_) { string x(tform_); istringstream str(x); str >> type_ >> width_; } } FitsAsciiColumnA::FitsAsciiColumnA(FitsHead* head, int i, int offset) : FitsAsciiColumn(head, i, offset) { prec_ = 0; if (tform_) { char s; string x(tform_); istringstream str(x); str >> type_ >> width_ >> s >> prec_; } } double FitsAsciiColumnA::value(const char* ptr, int i) { string x(ptr+offset_); istringstream str(x); double r; str >> r; return r; } template<class T> FitsAsciiColumnT<T>::FitsAsciiColumnT(FitsHead* head, int i, int off) : FitsAsciiColumnA(head, i, off) {} template <> Vector FitsAsciiColumnT<int>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_,tlmax_) : Vector(INT_MIN,INT_MAX); } template <> Vector FitsAsciiColumnT<float>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_,tlmax_) : Vector(FLT_MIN,FLT_MAX); } template <> Vector FitsAsciiColumnT<double>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_,tlmax_) : Vector(DBL_MIN,DBL_MAX); } // FitsBinColumn FitsBinColumn::FitsBinColumn(FitsHead* head, int i, int offset) : FitsColumn(head, i, offset) { tdisp_ = head->getString(keycat("TDISP",i)); repeat_ = 1; if (tform_) { string x(tform_); istringstream str(x); if (isalpha(tform_[0])) str >> type_; else str >> repeat_ >> type_; } } FitsBinColumn::~FitsBinColumn() { if (tdisp_) delete [] tdisp_; } // FitsBinColumnStr FitsBinColumnStr::FitsBinColumnStr(FitsHead* head, int i, int offset) : FitsBinColumn(head, i, offset) { width_ = repeat_; } char* FitsBinColumnStr::str(const char* ptr, int i) { strncpy(buf_, ptr+offset_, width_); buf_[width_] = '\0'; return buf_; } // FitsBinColumnLogical FitsBinColumnLogical::FitsBinColumnLogical(FitsHead* head, int i, int offset) : FitsBinColumn(head, i, offset) { width_ = repeat_; } char* FitsBinColumnLogical::str(const char* ptr, int i) { strncpy(buf_, ptr+offset_+i, 1); buf_[width_] = '\0'; return buf_; } // FitsBinColumnArray FitsBinColumnArray::FitsBinColumnArray(FitsHead* head, int i, int offset) : FitsBinColumn(head, i, offset) { width_ = 8; ptype_ = ' '; psize_ = 1; pmax_ = 0; abuf_ = NULL; byteswap_ = lsb(); if (tform_) { int rr; char tt; string x(tform_); istringstream str(x); if (isalpha(tform_[0])) str >> tt; else str >> rr >> tt; char s; str >> ptype_ >> s >> pmax_ >> s; switch (ptype_) { case 'B': psize_ = 1; break; case 'I': psize_ = 2; break; case 'J': psize_ = 4; break; case 'E': psize_ = 4; break; case 'D': psize_ = 4; break; default: internalError("Fitsy++ column unknown table column type."); return; } // sanity check if (!pmax_) pmax_ = 8; pmax_ *= psize_; if (pmax_ > 0) abuf_ = new char[pmax_]; } } FitsBinColumnArray::~FitsBinColumnArray() { if (abuf_) delete [] abuf_; } void* FitsBinColumnArray::get(const char* heap, const char* ptr, int* cnt) { *cnt = swap(ptr,0); if (*cnt > pmax_) { // just in case internalError("Fitsy++ column variable array size greater than specified"); *cnt = pmax_; } int pp = swap(ptr,1); if (abuf_) { memset(abuf_,pmax_,0); memcpy(abuf_,heap+pp,(*cnt)*psize_); } return abuf_; } int FitsBinColumnArray::swap(const char* ptr, int i) { const char* p = ptr+offset_+i*4; union { char c[4]; int i; } u; if (byteswap_) { u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,4); return u.i; } // FitsbinColumnBit FitsBinColumnBit::FitsBinColumnBit(FitsHead* head, int i, int off) : FitsBinColumn(head, i, off) { width_ = (repeat_+7)/8; } // FitsBinColumnB FitsBinColumnB::FitsBinColumnB(FitsHead* head, int i, int offset) : FitsBinColumn(head, i, offset) { byteswap_ = lsb(); } // FitsBinColumnT template<class T> FitsBinColumnT<T>::FitsBinColumnT(FitsHead* head, int i, int off) : FitsBinColumnB(head, i, off) { width_ = repeat_ * sizeof(T); } template <> double FitsBinColumnT<unsigned char>::value(const char* ptr, int i) { return (unsigned char)(*(ptr+offset_+i)); } template <> double FitsBinColumnT<short>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*2; union { char c[2]; short s; } u; if (byteswap_) { u.c[1] = *p++; u.c[0] = *p; } else { u.c[0] = *p++; u.c[1] = *p; } return u.s; } template <> double FitsBinColumnT<unsigned short>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*2; union { char c[2]; unsigned short s; } u; if (byteswap_) { u.c[1] = *p++; u.c[0] = *p; } else { u.c[0] = *p++; u.c[1] = *p; } return u.s; } template <> double FitsBinColumnT<int>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*4; union { char c[4]; int i; } u; if (byteswap_) { u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,4); return u.i; } template <> double FitsBinColumnT<unsigned int>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*4; union { char c[4]; unsigned int i; } u; if (byteswap_) { u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,4); return u.i; } template <> double FitsBinColumnT<long long>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*8; union { char c[8]; long long i; } u; if (byteswap_) { u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,8); return u.i; } template <> double FitsBinColumnT<float>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*4; union { char c[4]; float f; } u; if (byteswap_) { u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,4); return u.f; } template <> double FitsBinColumnT<double>::value(const char* ptr, int i) { const char* p = ptr+offset_+i*8; union { char c[8]; double d; } u; if (byteswap_) { u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; } else memcpy(u.c,p,8); return u.d; } template<class T> char* FitsBinColumnT<T>::str(const char* ptr, int i) { ostringstream ost; ost << value(ptr,i) << ends; return (char*)ost.str().c_str(); } template <> Vector FitsBinColumnT<unsigned char>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(0,UCHAR_MAX); } template <> Vector FitsBinColumnT<short>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(SHRT_MIN,SHRT_MAX); } template <> Vector FitsBinColumnT<unsigned short>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(0,USHRT_MAX); } template <> Vector FitsBinColumnT<int>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(INT_MIN,INT_MAX); } template <> Vector FitsBinColumnT<unsigned int>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(0,UINT_MAX); } // some older versions of gcc do not have LLONG #ifndef LLONG_MIN # ifdef LONG_LONG_MIN # define LLONG_MIN LONG_LONG_MIN # else # define LLONG_MIN LONG_MIN # endif #endif #ifndef LLONG_MAX # ifdef LONG_LONG_MAX # define LLONG_MAX LONG_LONG_MAX # else # define LLONG_MAX LONG_MAX # endif #endif template <> Vector FitsBinColumnT<long long>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_-.5,tlmax_+.5) : Vector(LLONG_MIN,LLONG_MAX); } template <> Vector FitsBinColumnT<float>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_,tlmax_) : Vector(-FLT_MAX,FLT_MAX); } template <> Vector FitsBinColumnT<double>::dimension() { return (hastlmin_ || hastlmax_) ? Vector(tlmin_,tlmax_) : Vector(-DBL_MAX,DBL_MAX); } template class FitsAsciiColumnT<int>; template class FitsAsciiColumnT<float>; template class FitsAsciiColumnT<double>; template class FitsBinColumnT<unsigned char>; template class FitsBinColumnT<short>; template class FitsBinColumnT<unsigned short>; template class FitsBinColumnT<int>; template class FitsBinColumnT<unsigned int>; template class FitsBinColumnT<long long>; template class FitsBinColumnT<float>; template class FitsBinColumnT<double>; ��������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hist.h�����������������������������������������������������������������������0000644�0001750�0001750�00000002776�11777647374�014673� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitshist_h__ #define __fitshist_h__ #include "vector.h" #include "file.h" class FitsHist : public FitsFile { public: enum Function {SUM, AVERAGE}; private: int width_; int height_; int depth_; size_t size_; FitsColumn* xcol_; FitsColumn* ycol_; FitsColumn* zcol_; void* fitsy_; void* filter_; int initHeader(FitsFile*); void initLTMV(Matrix&); void initWCS(FitsFile*, Matrix&, Vector); void mapWCSMatrix(FitsHead*, char* w, const char* out, const char* in, Vector); void mapWCSReal(FitsHead* head, const char* out, const char* in); void mapWCSReal(FitsHead* head, char* w, const char* out, const char* in); void mapWCSReal(FitsHead*, char* w, const char* out, const char* prim, const char* alt, Matrix); void mapWCSString(FitsHead*, char* w, const char* out, const char* prim); void mapWCSString(FitsHead*, char* w, const char* out, const char* prim, const char* alt); void mapWCSVector(FitsHead*, char* w, const char* out, const char* in); void initFilter(FitsFile*); void deleteFilter(); void bin(FitsFile*, Matrix&, Function, Vector); void swap(); public: FitsHist(FitsFile* src, int width, int height, int depth, Matrix& m, Function func, Vector block); ~FitsHist(); }; class FitsHistNext : public FitsFile { public: FitsHistNext(FitsFile* prev); }; #endif ��./saods9/saotk/fitsy++/outfile.h��������������������������������������������������������������������0000644�0001750�0001750�00000001121�12001356756�015330� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __outfile_h__ #define __outfile_h__ #include "outfits.h" #include "zlib.h" class OutFitsFile : public virtual OutFitsStream { private: FILE* fd_; public: OutFitsFile(const char*); ~OutFitsFile(); int write(char*, size_t); }; class OutFitsFileGZ : public virtual OutFitsStream { private: gzFile fd_; public: OutFitsFileGZ(const char*); ~OutFitsFileGZ(); int write(char*, size_t); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrd.h�����������������������������������������������������������������������0000644�0001750�0001750�00000001461�12044561570�014634� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsnrrd_h__ #define __fitsnrrd_h__ #include "file.h" class FitsNRRD : public FitsFile { protected: int bitpix_; int width_; int height_; int depth_; size_t size_; protected: int initHeader(FitsFile*); public: FitsNRRD(FitsFile*); virtual ~FitsNRRD(); }; template<class T> class FitsNRRDm : public FitsNRRD { private: void swapBytes(FitsFile::ArchType); protected: T swap(T* ptr); protected: void uncompress(FitsFile* fits); virtual int compressed(T*, char*, size_t) =0; public: FitsNRRDm(FitsFile*); }; class FitsNRRDNext : public FitsFile { public: FitsNRRDNext(FitsFile* prev); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/gzip.h�����������������������������������������������������������������������0000644�0001750�0001750�00000000705�11744322655�014645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsgzip_h__ #define __fitsgzip_h__ #include "compress.h" template<class T> class FitsGzipm : public FitsCompressm<T> { protected: int noquantize_; private: int compressed(T*, char*, char*, int, int, int, int, int, int); public: FitsGzipm(FitsFile*); }; #endif �����������������������������������������������������������./saods9/saotk/fitsy++/parser.Y���������������������������������������������������������������������0000644�0001750�0001750�00000015066�12101570555�015147� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {FitsFile* ff} %lex-param {ffFlexLexer* ll} %parse-param {ffFlexLexer* ll} %{ #define YYDEBUG 1 #define GOTOFILT(x) {yyclearin; ffFilter(x);} #define GOTOARR(x) {yyclearin; ffArray(x);} #include "file.h" #include "hpx.h" #undef yyFlexLexer #define yyFlexLexer ffFlexLexer #include <FlexLexer.h> extern int fflex(void*, ffFlexLexer*); extern void fferror(FitsFile*, ffFlexLexer*, const char*); char ff_filter[512]; extern void ffFilter(int); extern void ffArray(int); %} %union { float real; int integer; char str[256]; void* ptr; } %type <integer> endian %token <integer> INT %token <integer> INTP %token <str> STRING %token ARCH_ %token ARRAY_ %token BIG_ %token BIGENDIAN_ %token BIN_ %token BINKEY_ %token BINCOL_ %token BITPIX_ %token COL_ %token DIM_ %token DIMS_ %token ECLIPTIC_ %token ENDIAN_ %token EQUATORIAL_ %token GALACTIC_ %token KEY_ %token LAYOUT_ %token LITTLE_ %token LITTLEENDIAN_ %token NESTED_ %token NORTH_ %token ORDER_ %token QUAD_ %token RING_ %token SKIP_ %token SOUTH_ %token SYSTEM_ %token UNKNOWN_ %token XDIM_ %token YDIM_ %token ZDIM_ %% //start : {yydebug=1;} command // assume any error is the start of a filter command : filename | filename ext | filename sect | filename bin | filename ext sect | filename ext bin | filename ext sect bin | filename '[' extb sectb ']' | filename '[' extb binb ']' | filename '[' arrs ']' | filename '[' ARRAY_ {GOTOARR(0)} '(' array ')' ']' | filename '[' hpxs ']' | filename '[' extb hpxs ']' | error {GOTOFILT(0)} STRING {ff->setpFilter(ff_filter);} ; filename : /* empty */ | STRING {ff->setpName($1);} ; // we must do it this way so that a bare filter will be accepted //ext : '[' extb ']' // ; //extb : STRING {ff->setpExt($1);} // | INT {ff->setpIndex($1);} // ; ext : '[' STRING ']' {ff->setpExt($2);} | '[' INT ']' {ff->setpIndex($2);} ; extb : STRING ',' {ff->setpExt($1);} | INT ',' {ff->setpIndex($1);} ; sect : '[' sectb ']' sectb : rangex ',' rangey | rangex ',' rangey ',' rangez | INT '@' INT '@' INT { ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1); ff->setYMin($5-$1/2); ff->setYMax($5+$1/2); ff->setYValid(1); } | INT '@' INT '@' INT '@' INT { ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1); ff->setYMin($5-$1/2); ff->setYMax($5+$1/2); ff->setYValid(1); ff->setZMin($7-$1/2); ff->setZMax($7+$1/2); ff->setZValid(1); } | INT '@' INT '@' INTP { ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1); ff->setYMin($5-$1/2); ff->setYMax($5+$1/2); ff->setYValid(1); ff->setCoord(1); } | INT '@' INT '@' INT '@' INTP { ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1); ff->setYMin($5-$1/2); ff->setYMax($5+$1/2); ff->setYValid(1); ff->setZMin($7-$1/2); ff->setZMax($7+$1/2); ff->setZValid(1); ff->setCoord(1); } ; rangex : INT ':' INT {ff->setXMin($1); ff->setXMax($3); ff->setXValid(1);} | INT ':' INTP { ff->setXMin($1); ff->setXMax($3); ff->setXValid(1); ff->setCoord(1); } | INT '@' INT {ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1);} | INT '@' INTP { ff->setXMin($3-$1/2); ff->setXMax($3+$1/2); ff->setXValid(1); ff->setCoord(1); } | '*' {ff->setXValid(0);} ; rangey : INT ':' INT {ff->setYMin($1); ff->setYMax($3); ff->setYValid(1);} | INT ':' INTP { ff->setYMin($1); ff->setYMax($3); ff->setYValid(1); ff->setCoord(1); } | INT '@' INT {ff->setYMin($3-$1/2); ff->setYMax($3+$1/2); ff->setYValid(1);} | INT '@' INTP { ff->setYMin($3-$1/2); ff->setYMax($3+$1/2); ff->setYValid(1); ff->setCoord(1); } | '*' {ff->setYValid(0);} ; rangez : INT ':' INT {ff->setZMin($1); ff->setZMax($3); ff->setZValid(1);} | INT ':' INTP { ff->setZMin($1); ff->setZMax($3); ff->setZValid(1); ff->setCoord(1); } | INT '@' INT {ff->setZMin($3-$1/2); ff->setZMax($3+$1/2); ff->setZValid(1);} | INT '@' INTP { ff->setZMin($3-$1/2); ff->setZMax($3+$1/2); ff->setZValid(1); ff->setCoord(1); } | '*' {ff->setZValid(0);} ; bin : '[' binb ']' binb : binword '=' binkey | binword binkey ; binword : BIN_ | BINKEY_ | BINCOL_ | KEY_ ; binkey : '(' STRING ',' STRING ')' {ff->setpBinXY($2,$4);} | STRING ',' STRING {ff->setpBinXY($1,$3);} | '(' STRING ',' STRING ',' STRING ')' {ff->setpBinXYZ($2,$4,$6);} | STRING ',' STRING ',' STRING {ff->setpBinXYZ($1,$3,$5);} | '(' STRING ')' {ff->setpBinZ($2);} | STRING {ff->setpBinZ($1);} ; arrs : arrs ',' arr | arr ; arr : XDIM_ '=' INT {ff->setpWidth($3);} | YDIM_ '=' INT {ff->setpHeight($3);} | ZDIM_ '=' INT {ff->setpDepth($3);} | DIM_ '=' INT {ff->setpWidth($3);ff->setpHeight($3);} | DIMS_ '=' INT {ff->setpWidth($3);ff->setpHeight($3);} | BITPIX_ '=' INT {ff->setpBitpix($3);} | SKIP_ '=' INT {ff->setpSkip($3);} | ARCH_ '=' endian {ff->setpArch((FitsFile::ArchType)$3);} | ENDIAN_ '=' endian {ff->setpArch((FitsFile::ArchType)$3);} | endian {ff->setpArch((FitsFile::ArchType)$1);} ; endian : /* empty */ {$$ = FitsFile::BIG;} | BIG_ {$$ = FitsFile::BIG;} | BIGENDIAN_ {$$ = FitsFile::BIG;} | LITTLE_ {$$ = FitsFile::LITTLE;} | LITTLEENDIAN_ {$$ = FitsFile::LITTLE;} ; array : atype adims askip aendian ; atype : 'b' {ff->setpBitpix(8);} | 's' {ff->setpBitpix(16);} | 'u' {ff->setpBitpix(-16);} | 'i' {ff->setpBitpix(32);} | 'l' {ff->setpBitpix(64);} | 'r' {ff->setpBitpix(-32);} | 'f' {ff->setpBitpix(-32);} | 'd' {ff->setpBitpix(-64);} ; adims : INT {ff->setpWidth($1);ff->setpHeight($1);} | INT '.' INT {ff->setpWidth($1);ff->setpHeight($3);} | INT '.' INT '.' INT {ff->setpWidth($1);ff->setpHeight($3);ff->setpDepth($5);} ; askip : /* empty */ | ':' INT {ff->setpSkip($2);} ; aendian : /* empty */ | 'l' {ff->setpArch(FitsFile::LITTLE);} | 'b' {ff->setpArch(FitsFile::BIG);} ; hpxs : hpxs ',' hpx | hpx ; hpx : SYSTEM_ '=' hpxSystem | ORDER_ '=' hpxOrder | LAYOUT_ '=' hpxLayout | COL_ '=' INT {ff->setpHPXColumn($3);} | QUAD_ '=' INT {ff->setpHPXQuad($3);} ; hpxSystem : EQUATORIAL_ {ff->setpHPXSystem(FitsHPX::EQU);} | GALACTIC_ {ff->setpHPXSystem(FitsHPX::GAL);} | ECLIPTIC_ {ff->setpHPXSystem(FitsHPX::ECL);} | UNKNOWN_ {ff->setpHPXSystem(FitsHPX::UNKNOWN);} ; hpxOrder : RING_ {ff->setpHPXOrder(FitsHPX::RING);} | NESTED_ {ff->setpHPXOrder(FitsHPX::NESTED);} ; hpxLayout : EQUATORIAL_ {ff->setpHPXLayout(FitsHPX::EQUATOR);} | NORTH_ {ff->setpHPXLayout(FitsHPX::NORTH);} | SOUTH_ {ff->setpHPXLayout(FitsHPX::SOUTH);} ; %% ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mmap.C�����������������������������������������������������������������������0000644�0001750�0001750�00000001740�12044561570�014554� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include "mmap.h" FitsMMap::FitsMMap(const char* fn) { // parse the fn and options parse(fn); if (!pName_) return; // Map the file. int file = open(pName_, O_RDONLY); if (file == -1) return; struct stat info; if (fstat(file, &info) < 0) return; // check to see if we have something, we may have a small array if (info.st_size <= 0) return; // map it mapsize_ = info.st_size; mapdata_ = (char*)mmap(NULL, mapsize_, PROT_READ, MAP_SHARED, file, 0); // close the file close(file); // are we valid? if ((long)mapdata_ == -1) return; // so far, so good valid_ = 1; } FitsMMap::~FitsMMap() { if (mapdata_>0) munmap((caddr_t)mapdata_, mapsize_); } ��������������������������������./saods9/saotk/fitsy++/hdu.C������������������������������������������������������������������������0000644�0001750�0001750�00000015516�11777365613�014424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <stdlib.h> #include <string.h> #include <ctype.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "hdu.h" #include "head.h" FitsHDU::FitsHDU(FitsHead* head) { extname_ = head->getString("EXTNAME"); // trim any spaces at end if (extname_) { for (int ii=strlen(extname_)-1; ii>=0; ii--) { if (extname_[ii] == ' ') extname_[ii] = '\0'; else break; } } extver_ = head->getInteger("EXTVER", 0); bitpix_ = head->getInteger("BITPIX", 0); naxes_ = head->getInteger("NAXIS", 0); if (naxes_>FTY_MAXAXES) naxes_ = FTY_MAXAXES; for(int i=0; i<naxes_; i++) naxis_[i] = head->getInteger(keycat("NAXIS",(i+1)), 0); realbytes_ = 0; heapbytes_ = head->getInteger("PCOUNT",0); allbytes_ = 0; padbytes_ = 0; databytes_ = 0; datablocks_ = 0; } FitsHDU::~FitsHDU() { if (extname_) delete [] extname_; } char* FitsHDU::keycat(const char* name, int i) { ostringstream str; str << name << i << ends; memcpy(keybuf,str.str().c_str(),str.str().length()); return keybuf; } void FitsHDU::updateCards(FitsHead* head) { head->setInteger("BITPIX", bitpix_, NULL); head->setInteger("NAXIS", naxes_, NULL); for (int i=1; i<=naxes_; i++) head->setInteger(keycat("NAXIS", i), naxis_[i-1], NULL); } // FitsImageHDU FitsImageHDU::FitsImageHDU(FitsHead* head) : FitsHDU(head) { size_t imgpixels = (size_t)naxis_[0]*naxis_[1]; imgbytes_ = imgpixels * (abs(bitpix_)/8); size_t realpixels; if (naxes_>0) { realpixels = 1; for (int i=0; i<naxes_; i++ ) realpixels *= naxis_[i]; } else realpixels = 0; realbytes_ = realpixels * (abs(bitpix_)/8); allbytes_ = realbytes_ + heapbytes_; datablocks_ = (allbytes_ + (FTY_BLOCK-1))/FTY_BLOCK; databytes_ = datablocks_ * FTY_BLOCK; padbytes_ = databytes_ - allbytes_; bzero_ = head->getReal("BZERO", 0.0); bscale_ = head->getReal("BSCALE", 1.0); hasblank_ = head->find("BLANK") ? 1:0; blank_ = head->getInteger("BLANK", 0); } void FitsImageHDU::updateCards(FitsHead* head) { FitsHDU::updateCards(head); if (blank_) if (bitpix_ > 0) head->setInteger("BLANK", blank_, NULL); if (bzero_) head->setReal("BZERO", bzero_ , 7, NULL); if (bscale_ != 1) head->setReal("BSCALE", bscale_, 7, NULL); } // FitsTableHDU FitsTableHDU::FitsTableHDU(FitsHead* head) : FitsHDU(head) { tfields_ = head->getInteger("TFIELDS", 0); cols_ = NULL; realbytes_ = (size_t)naxis_[0]*naxis_[1]; // number of rows * width of row in bytes allbytes_ = realbytes_ + heapbytes_; datablocks_ = (allbytes_ + (FTY_BLOCK-1))/FTY_BLOCK; databytes_ = datablocks_ * FTY_BLOCK; padbytes_ = databytes_ - allbytes_; } FitsTableHDU::~FitsTableHDU() { if (cols_) { for (int i=0; i<tfields_; i++) if (cols_[i]) delete cols_[i]; delete [] cols_; } } char* FitsTableHDU::list() { char buf[1024]; // make it big buf[0] = '\0'; ostringstream str; for (int i=0; i<tfields_; i++) if (cols_[i]) str << cols_[i]->ttype() << ' '; str << ends; return dupstr(str.str().c_str()); } FitsColumn* FitsTableHDU::find(const char* name) { char* n = toUpper(name); // trim any spaces char* nn = n; while (*nn) nn++; nn--; while (*nn == ' ') *nn-- = NULL; for (int i=0; i<tfields_; i++) { if (cols_[i]) { char* t = toUpper(cols_[i]->ttype()); // trim any spaces char* tt=t; while (*tt) tt++; tt--; while (*tt == ' ') *tt-- = NULL; if (!strncmp(n,t,strlen(n)) && strlen(n)==strlen(t)) { delete [] n; delete [] t; return cols_[i]; } delete [] t; } } delete [] n; return NULL; } FitsColumn* FitsTableHDU::find(int i) { if (i>=0 && i<tfields_) return cols_[i]; return NULL; } Vector FitsTableHDU::dimension(const char* name) { FitsColumn* col = find(name); return col ? col->dimension() : Vector(); } FitsAsciiTableHDU::FitsAsciiTableHDU(FitsHead* head) : FitsTableHDU(head) { cols_ = new FitsColumn*[tfields_]; size_t offset = 0; for (int i=0; i<tfields_; i++) { char* tform = head->getString(keycat("TFORM",i+1)); char type; if (tform) { string x(tform); istringstream str(x); str >> type; } switch (type) { case 'A': cols_[i] = new FitsAsciiColumnStr(head, i+1, offset); break; case 'I': cols_[i] = new FitsAsciiColumnT<int>(head, i+1, offset); break; case 'F': cols_[i] = new FitsAsciiColumnT<float>(head, i+1, offset); break; case 'E': cols_[i] = new FitsAsciiColumnT<float>(head, i+1, offset); break; case 'D': cols_[i] = new FitsAsciiColumnT<double>(head, i+1, offset); break; } delete [] tform; if (cols_[i]) offset += cols_[i]->width(); } } FitsBinTableHDU::FitsBinTableHDU(FitsHead* head) : FitsTableHDU(head) { cols_ = new FitsColumn*[tfields_]; int offset =0; for (int i=0; i<tfields_; i++) { char* tform = head->getString(keycat("TFORM",i+1)); int repeat; char type; if (tform) { string x(tform); istringstream str(x); if (isalpha(tform[0])) str >> type; else str >> repeat >> type; } switch (type) { case 'A': cols_[i] = new FitsBinColumnStr(head, i+1, offset); break; case 'L': cols_[i] = new FitsBinColumnLogical(head, i+1, offset); break; case 'P': cols_[i] = new FitsBinColumnArray(head, i+1, offset); break; case 'X': cols_[i] = new FitsBinColumnBit(head, i+1, offset); break; case 'B': cols_[i] = new FitsBinColumnT<unsigned char>(head, i+1, offset); break; case 'I': cols_[i] = new FitsBinColumnT<short>(head, i+1, offset); break; case 'U': cols_[i] = new FitsBinColumnT<unsigned short>(head, i+1, offset); break; case 'J': cols_[i] = new FitsBinColumnT<int>(head, i+1, offset); break; case 'V': cols_[i] = new FitsBinColumnT<unsigned int>(head, i+1, offset); break; case 'K': cols_[i] = new FitsBinColumnT<long long>(head, i+1, offset); break; case 'E': cols_[i] = new FitsBinColumnT<float>(head, i+1, offset); break; case 'D': cols_[i] = new FitsBinColumnT<double>(head, i+1, offset); break; case 'C': cols_[i] = NULL; internalError("Fitsy++ hdu single precision complex column type not supported"); break; case 'M': cols_[i] = NULL; internalError("Fitsy++ hdu double precision complex column type not supported"); break; default: cols_[i] = NULL; internalError("Fitsy++ hdu unknown table column type"); break; } delete [] tform; if (cols_[i]) offset += cols_[i]->width(); } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/iis.C������������������������������������������������������������������������0000644�0001750�0001750�00000002732�12075360501�014403� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "iis.h" FitsIIS::FitsIIS(int width, int height) { // new header head_ = new FitsHead(width, height, 1, 8); if (!head_->isValid()) return; // alloc memory size_t size = (size_t)width*height; data_ = new char[size]; if (!data_) return; dataSize_ = size; dataSkip_ = 0; // clear memory memset(data_, '\0', size); // made it this far, must be valid valid_ = 1; } FitsIIS::~FitsIIS() { if (data_) delete [] (char*)data_; } void FitsIIS::erase() { // clear memory FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); memset(data_, '\0', hdu->realbytes()); } char* FitsIIS::get(int xx, int yy, int dx, int dy) { // fill-in in reverse order int ll = dx*dy; char* dest = new char[ll]; int ww = head_->naxis(0); int hh = head_->naxis(1); char* dptr = dest; char* sptr = (char*)data_ + ((hh-1)-yy)*ww + xx; while (ll) { memcpy(dptr, sptr, ww); sptr -= ww; dptr += ww; ll -= ww; } return dest; } void FitsIIS::set(const char* src, int xx, int yy, int dx, int dy) { // fill-in in reverse order int ll = dx*dy; int ww = head_->naxis(0); int hh = head_->naxis(1); char* sptr = (char*)src; char* dptr = (char*)data_ + ((hh-1)-yy)*ww + xx; while (ll) { memcpy(dptr, sptr, ww); sptr += ww; dptr -= ww; ll -= ww; } } ��������������������������������������./saods9/saotk/fitsy++/socketgz.h�������������������������������������������������������������������0000644�0001750�0001750�00000002572�11700666265�015531� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitssocketgz_h__ #define __fitssocketgz_h__ #include "strm.h" class FitsSocketGZ : public virtual FitsStream<gzStream> { public: FitsSocketGZ(int, const char*); virtual ~FitsSocketGZ(); }; class FitsFitsSocketGZ : public FitsSocketGZ, public FitsFitsStream<gzStream> { public: FitsFitsSocketGZ(int s, const char* ext, ScanMode mode, FlushMode flush) : FitsSocketGZ(s, ext), FitsFitsStream<gzStream>(mode, flush) {} }; class FitsFitsNextSocketGZ : public FitsFitsNextStream<gzStream> { public: FitsFitsNextSocketGZ(FitsFile* prev) : FitsFitsNextStream<gzStream>(prev) {} }; class FitsArrSocketGZ : public FitsSocketGZ, public FitsArrStream<gzStream> { public: FitsArrSocketGZ(int s, const char* ext, FlushMode flush) : FitsSocketGZ(s, ext), FitsArrStream<gzStream>(flush) {} }; class FitsMosaicSocketGZ : public FitsSocketGZ, public FitsMosaicStream<gzStream> { public: FitsMosaicSocketGZ(int s, FlushMode flush) : FitsSocketGZ(s, ""), FitsMosaicStream<gzStream>(flush) {} }; class FitsMosaicNextSocketGZ : public FitsMosaicNextStream<gzStream> { public: FitsMosaicNextSocketGZ(FitsFile* prev, FlushMode flush) : FitsMosaicNextStream<gzStream>(prev, flush) {} }; #endif ��������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mmapincr.h�������������������������������������������������������������������0000644�0001750�0001750�00000002160�11700666265�015477� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsmmapincr_h__ #define __fitsmmapincr_h__ #include "mapincr.h" class FitsMMapIncr : public virtual FitsMapIncr { public: FitsMMapIncr(const char*); }; class FitsFitsMMapIncr : public FitsMMapIncr, public FitsFitsMapIncr { public: FitsFitsMMapIncr(const char* fn, ScanMode mode) : FitsMMapIncr(fn), FitsFitsMapIncr(mode) {} }; class FitsFitsNextMMapIncr : public FitsFitsNextMapIncr { public: FitsFitsNextMMapIncr(FitsFile* prev) : FitsFitsNextMapIncr(prev) {} }; class FitsArrMMapIncr : public FitsMMapIncr, public FitsArrMapIncr { public: FitsArrMMapIncr(const char* fn) : FitsMMapIncr(fn), FitsArrMapIncr() {} }; class FitsMosaicMMapIncr : public FitsMMapIncr, public FitsMosaicMapIncr { public: FitsMosaicMMapIncr(const char* fn) : FitsMMapIncr(fn), FitsMosaicMapIncr() {} }; class FitsMosaicNextMMapIncr : public FitsMosaicNextMapIncr { public: FitsMosaicNextMMapIncr(FitsFile* prev) : FitsMosaicNextMapIncr(prev) {} }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/smmap.h����������������������������������������������������������������������0000644�0001750�0001750�00000001237�11700666265�015012� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitssmmap_h__ #define __fitssmmap_h__ #include "smap.h" class FitsSMMap : public virtual FitsSMap { public: FitsSMMap(const char*, const char*); virtual ~FitsSMMap(); }; class FitsFitsSMMap : public FitsSMMap, public FitsFitsSMap { public: FitsFitsSMMap(const char* hdr, const char* fn) : FitsSMMap(hdr,fn), FitsFitsSMap(FitsHead::MMAP) {} }; class FitsFitsNextSMMap : public FitsFitsNextSMap { public: FitsFitsNextSMMap(FitsFile* prev) : FitsFitsNextSMap(prev) {} }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hcompress.C������������������������������������������������������������������0000644�0001750�0001750�00000006635�11700666265�015642� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; // Note: currently, hcompress will not work with float or double data with // BLANK defined, due to the fact that the decompress code takes a int() and // not an unsigned int() #include "hcompress.h" #include "util.h" extern "C" { int fits_hdecompress(unsigned char *input, int smooth, int *a, int *ny, int *nx, int *scale, int *status); int fits_hdecompress64(unsigned char *input, int smooth, long long *a, int *ny, int *nx, int *scale, int *status); } template<class T> FitsHcompressm<T>::FitsHcompressm(FitsFile* fits) : FitsCompressm<T>(fits) { // hcompress parameters smooth_ = 0; char name[] = "ZNAME "; char val[] = "ZVAL "; for (int ii=0; ii<9; ii++) { name[5] = '0'+ii; val[4] = '0'+ii; if (fits->find(name)) { char* which = fits->getString(name); if (!strncmp(which,"SMOOTH",4)) smooth_ = fits->getInteger(val,4); delete [] which; } } FitsCompressm<T>::uncompress(fits); } template <class T> int FitsHcompressm<T>::compressed(T* dest, char* sptr, char* heap, int kkstart, int kkstop, int jjstart, int jjstop, int iistart, int iistop) { double zs = FitsCompressm<T>::bscale_; if (FitsCompressm<T>::zscale_) zs = FitsCompressm<T>::zscale_->value(sptr,0); double zz = FitsCompressm<T>::bzero_; if (FitsCompressm<T>::zzero_) zz = FitsCompressm<T>::zzero_->value(sptr,0); int blank = FitsCompressm<T>::blank_; if (FitsCompressm<T>::zblank_) blank = (int)FitsCompressm<T>::zblank_->value(sptr,0); int icnt=0; unsigned char* ibuf = (unsigned char*)((FitsBinColumnArray*)FitsCompressm<T>::compress_)->get(heap, sptr, &icnt); // ibuf can be NULL if (ibuf && icnt>0) { int ocnt = FitsCompressm<T>::ww_ * FitsCompressm<T>::hh_ * FitsCompressm<T>::dd_; int nx,ny,scale; int status=0; int ll=0; switch (FitsCompressm<T>::bitpix_) { case 8: case 16: { int obuf[ocnt]; if (fits_hdecompress(ibuf, smooth_, obuf, &nx, &ny, &scale, &status)) { internalError("Fitsy++ hcompress bad inflate result"); return 0; } for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); } break; case 32: case -32: case -64: { long long obuf[ocnt]; if (fits_hdecompress64(ibuf, smooth_, obuf, &nx, &ny, &scale, &status)) { internalError("Fitsy++ hcompress bad inflate result"); return 0; } for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue((int*)obuf+ll,zs,zz,blank); } break; } } return 1; } template class FitsHcompressm<unsigned char>; template class FitsHcompressm<short>; template class FitsHcompressm<unsigned short>; template class FitsHcompressm<int>; template class FitsHcompressm<long long>; template class FitsHcompressm<float>; template class FitsHcompressm<double>; ���������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/parser.C���������������������������������������������������������������������0000644�0001750�0001750�00000200673�12101570555�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse ffparse #define yylex fflex #define yyerror fferror #define yylval fflval #define yychar ffchar #define yydebug ffdebug #define yynerrs ffnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, INTP = 259, STRING = 260, ARCH_ = 261, ARRAY_ = 262, BIG_ = 263, BIGENDIAN_ = 264, BIN_ = 265, BINKEY_ = 266, BINCOL_ = 267, BITPIX_ = 268, COL_ = 269, DIM_ = 270, DIMS_ = 271, ECLIPTIC_ = 272, ENDIAN_ = 273, EQUATORIAL_ = 274, GALACTIC_ = 275, KEY_ = 276, LAYOUT_ = 277, LITTLE_ = 278, LITTLEENDIAN_ = 279, NESTED_ = 280, NORTH_ = 281, ORDER_ = 282, QUAD_ = 283, RING_ = 284, SKIP_ = 285, SOUTH_ = 286, SYSTEM_ = 287, UNKNOWN_ = 288, XDIM_ = 289, YDIM_ = 290, ZDIM_ = 291 }; #endif /* Tokens. */ #define INT 258 #define INTP 259 #define STRING 260 #define ARCH_ 261 #define ARRAY_ 262 #define BIG_ 263 #define BIGENDIAN_ 264 #define BIN_ 265 #define BINKEY_ 266 #define BINCOL_ 267 #define BITPIX_ 268 #define COL_ 269 #define DIM_ 270 #define DIMS_ 271 #define ECLIPTIC_ 272 #define ENDIAN_ 273 #define EQUATORIAL_ 274 #define GALACTIC_ 275 #define KEY_ 276 #define LAYOUT_ 277 #define LITTLE_ 278 #define LITTLEENDIAN_ 279 #define NESTED_ 280 #define NORTH_ 281 #define ORDER_ 282 #define QUAD_ 283 #define RING_ 284 #define SKIP_ 285 #define SOUTH_ 286 #define SYSTEM_ 287 #define UNKNOWN_ 288 #define XDIM_ 289 #define YDIM_ 290 #define ZDIM_ 291 /* Copy the first part of user declarations. */ #line 10 "parser.Y" #define YYDEBUG 1 #define GOTOFILT(x) {yyclearin; ffFilter(x);} #define GOTOARR(x) {yyclearin; ffArray(x);} #include "file.h" #include "hpx.h" #undef yyFlexLexer #define yyFlexLexer ffFlexLexer #include <FlexLexer.h> extern int fflex(void*, ffFlexLexer*); extern void fferror(FitsFile*, ffFlexLexer*, const char*); char ff_filter[512]; extern void ffFilter(int); extern void ffArray(int); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 32 "parser.Y" { float real; int integer; char str[256]; void* ptr; } /* Line 193 of yacc.c. */ #line 205 "parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 218 "parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 6 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 206 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 55 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 29 /* YYNRULES -- Number of rules. */ #define YYNRULES 108 /* YYNRULES -- Number of states. */ #define YYNSTATES 184 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 291 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 39, 40, 44, 2, 41, 2, 54, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 43, 2, 2, 45, 2, 2, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 38, 2, 2, 2, 2, 46, 2, 53, 2, 52, 2, 2, 49, 2, 2, 50, 2, 2, 2, 2, 2, 51, 47, 2, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 5, 8, 11, 14, 18, 22, 27, 33, 39, 44, 45, 54, 59, 65, 66, 70, 71, 73, 77, 81, 84, 87, 91, 95, 101, 107, 115, 121, 129, 133, 137, 141, 145, 147, 151, 155, 159, 163, 165, 169, 173, 177, 181, 183, 187, 191, 194, 196, 198, 200, 202, 208, 212, 220, 226, 230, 232, 236, 238, 242, 246, 250, 254, 258, 262, 266, 270, 274, 276, 277, 279, 281, 283, 285, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 312, 318, 319, 322, 323, 325, 327, 331, 333, 337, 341, 345, 349, 353, 355, 357, 359, 361, 363, 365, 367, 369 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 56, 0, -1, 59, -1, 59, 60, -1, 59, 62, -1, 59, 67, -1, 59, 60, 62, -1, 59, 60, 67, -1, 59, 60, 62, 67, -1, 59, 37, 61, 63, 38, -1, 59, 37, 61, 68, 38, -1, 59, 37, 71, 38, -1, -1, 59, 37, 7, 57, 39, 74, 40, 38, -1, 59, 37, 79, 38, -1, 59, 37, 61, 79, 38, -1, -1, 1, 58, 5, -1, -1, 5, -1, 37, 5, 38, -1, 37, 3, 38, -1, 5, 41, -1, 3, 41, -1, 37, 63, 38, -1, 64, 41, 65, -1, 64, 41, 65, 41, 66, -1, 3, 42, 3, 42, 3, -1, 3, 42, 3, 42, 3, 42, 3, -1, 3, 42, 3, 42, 4, -1, 3, 42, 3, 42, 3, 42, 4, -1, 3, 43, 3, -1, 3, 43, 4, -1, 3, 42, 3, -1, 3, 42, 4, -1, 44, -1, 3, 43, 3, -1, 3, 43, 4, -1, 3, 42, 3, -1, 3, 42, 4, -1, 44, -1, 3, 43, 3, -1, 3, 43, 4, -1, 3, 42, 3, -1, 3, 42, 4, -1, 44, -1, 37, 68, 38, -1, 69, 45, 70, -1, 69, 70, -1, 10, -1, 11, -1, 12, -1, 21, -1, 39, 5, 41, 5, 40, -1, 5, 41, 5, -1, 39, 5, 41, 5, 41, 5, 40, -1, 5, 41, 5, 41, 5, -1, 39, 5, 40, -1, 5, -1, 71, 41, 72, -1, 72, -1, 34, 45, 3, -1, 35, 45, 3, -1, 36, 45, 3, -1, 15, 45, 3, -1, 16, 45, 3, -1, 13, 45, 3, -1, 30, 45, 3, -1, 6, 45, 73, -1, 18, 45, 73, -1, 73, -1, -1, 8, -1, 9, -1, 23, -1, 24, -1, 75, 76, 77, 78, -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, -1, 51, -1, 52, -1, 53, -1, 3, -1, 3, 54, 3, -1, 3, 54, 3, 54, 3, -1, -1, 43, 3, -1, -1, 50, -1, 46, -1, 79, 41, 80, -1, 80, -1, 32, 45, 81, -1, 27, 45, 82, -1, 22, 45, 83, -1, 14, 45, 3, -1, 28, 45, 3, -1, 19, -1, 20, -1, 17, -1, 33, -1, 29, -1, 25, -1, 19, -1, 26, -1, 31, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 92, 93, 94, 95, 95, 98, 99, 108, 109, 112, 113, 116, 118, 119, 120, 125, 131, 137, 146, 148, 153, 155, 160, 163, 165, 170, 172, 177, 180, 182, 187, 189, 194, 197, 199, 200, 203, 204, 205, 206, 209, 210, 211, 212, 213, 214, 217, 218, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 233, 234, 235, 236, 237, 240, 243, 244, 245, 246, 247, 248, 249, 250, 253, 254, 255, 259, 260, 263, 264, 265, 268, 269, 272, 273, 274, 275, 276, 279, 280, 281, 282, 285, 286, 289, 290, 291 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "INTP", "STRING", "ARCH_", "ARRAY_", "BIG_", "BIGENDIAN_", "BIN_", "BINKEY_", "BINCOL_", "BITPIX_", "COL_", "DIM_", "DIMS_", "ECLIPTIC_", "ENDIAN_", "EQUATORIAL_", "GALACTIC_", "KEY_", "LAYOUT_", "LITTLE_", "LITTLEENDIAN_", "NESTED_", "NORTH_", "ORDER_", "QUAD_", "RING_", "SKIP_", "SOUTH_", "SYSTEM_", "UNKNOWN_", "XDIM_", "YDIM_", "ZDIM_", "'['", "']'", "'('", "')'", "','", "'@'", "':'", "'*'", "'='", "'b'", "'s'", "'u'", "'i'", "'l'", "'r'", "'f'", "'d'", "'.'", "$accept", "command", "@1", "@2", "filename", "ext", "extb", "sect", "sectb", "rangex", "rangey", "rangez", "bin", "binb", "binword", "binkey", "arrs", "arr", "endian", "array", "atype", "adims", "askip", "aendian", "hpxs", "hpx", "hpxSystem", "hpxOrder", "hpxLayout", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 91, 93, 40, 41, 44, 64, 58, 42, 61, 98, 115, 117, 105, 108, 114, 102, 100, 46 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 56, 56, 56, 58, 56, 59, 59, 60, 60, 61, 61, 62, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 67, 68, 68, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 74, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 77, 77, 78, 78, 78, 79, 79, 80, 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 83, 83, 83 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 2, 2, 2, 3, 3, 4, 5, 5, 4, 0, 8, 4, 5, 0, 3, 0, 1, 3, 3, 2, 2, 3, 3, 5, 5, 7, 5, 7, 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, 2, 1, 1, 1, 1, 5, 3, 7, 5, 3, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 0, 2, 0, 1, 1, 3, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 16, 19, 0, 2, 0, 1, 71, 3, 4, 5, 17, 0, 0, 0, 12, 72, 73, 49, 50, 51, 0, 0, 0, 0, 0, 52, 0, 74, 75, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 60, 70, 0, 94, 0, 6, 7, 21, 23, 0, 0, 20, 22, 71, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 46, 58, 0, 0, 48, 11, 71, 14, 0, 0, 8, 33, 34, 31, 32, 68, 0, 66, 98, 64, 65, 69, 106, 107, 108, 97, 105, 104, 96, 99, 67, 102, 100, 101, 103, 95, 61, 62, 63, 9, 10, 15, 0, 40, 25, 0, 0, 47, 59, 93, 0, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, 54, 57, 0, 27, 29, 0, 85, 88, 38, 39, 36, 37, 0, 45, 26, 0, 0, 0, 13, 0, 0, 90, 0, 0, 56, 53, 0, 28, 30, 86, 89, 92, 91, 76, 43, 44, 41, 42, 0, 0, 55, 87 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 3, 58, 5, 4, 8, 38, 9, 39, 40, 122, 156, 10, 41, 42, 82, 43, 44, 45, 137, 138, 149, 163, 175, 46, 47, 113, 106, 103 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -37 static const yytype_int16 yypact[] = { 43, -37, -37, 16, -36, 33, -37, -3, 3, -37, -37, -37, 80, 32, 0, -37, -37, -37, -37, -37, -37, 18, 60, 72, 83, 109, -37, 110, -37, -37, 111, 112, 113, 114, 115, 116, 117, -37, 25, 40, 84, 125, 17, 78, -37, -37, 86, -37, 39, 128, -37, -37, -37, 91, 127, -37, -37, 68, 129, 161, 163, 164, 166, 68, 35, 1, 167, 168, 87, 169, 170, 171, 90, 138, 140, 88, -37, 11, -37, 134, 172, 29, -37, -37, 66, -37, 71, 76, -37, 141, -37, -37, -37, -37, 62, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, 92, -37, 143, 174, 96, -37, -37, -37, 135, -37, -37, -37, -37, -37, -37, -37, -37, 142, 177, 137, 139, 14, 144, -37, 176, 146, -37, 148, 133, 150, -37, -37, -37, -37, 102, -37, -37, 184, 106, 145, -37, 187, 188, 21, 147, 149, -37, -37, 189, -37, -37, 151, -37, -37, -37, -37, -37, -37, -37, -37, 152, 192, -37, -37 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -37, -37, -37, -37, -37, -37, -37, 190, 158, -37, -37, -37, 15, 159, -37, 118, -37, 119, 2, -37, -37, -37, -37, -37, 162, 120, -37, -37, -37 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -19 static const yytype_int16 yytable[] = { 12, 7, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 120, 25, 6, 154, 26, 27, 28, 29, 79, 50, 30, 31, 104, 32, 72, 33, 105, 34, 35, 36, 79, 18, 19, 20, 11, 22, 48, 37, 72, -18, 1, 57, 26, 27, 2, 18, 19, 20, 30, 31, 100, 121, 80, 33, 155, 93, 26, 101, 81, 59, 88, 99, 102, 173, 80, 37, 55, 174, 14, 56, 16, 17, 16, 17, 76, 21, -18, 23, 24, 37, 25, 22, 18, 19, 20, 28, 29, 28, 29, 27, 89, 90, 32, 26, 30, 31, 34, 35, 36, 33, 109, 60, 110, 111, 129, 130, 131, 132, 133, 134, 135, 136, 83, 61, 51, 84, 112, 52, 53, 54, 85, 77, 119, 86, 62, 86, 91, 92, 53, 54, 139, 140, 143, 144, 145, 146, 150, 151, 152, 153, 164, 165, 167, 168, 169, 170, 176, 177, 178, 179, 63, 64, 65, 66, 67, 68, 69, 70, 71, 78, 95, 87, 96, 97, 94, 98, 107, 108, 114, 115, 116, 123, 117, 124, 118, 142, 148, 158, 147, 128, 141, 157, 160, 161, 159, 166, 171, 172, 182, 162, 180, 183, 73, 74, 49, 125, 75, 0, 0, 126, 0, 181, 127 }; static const yytype_int8 yycheck[] = { 3, 37, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 18, 0, 3, 21, 22, 23, 24, 5, 8, 27, 28, 25, 30, 3, 32, 29, 34, 35, 36, 5, 10, 11, 12, 5, 14, 37, 44, 3, 0, 1, 45, 21, 22, 5, 10, 11, 12, 27, 28, 19, 44, 39, 32, 44, 57, 21, 26, 45, 45, 49, 63, 31, 46, 39, 44, 38, 50, 6, 41, 8, 9, 8, 9, 38, 13, 37, 15, 16, 44, 18, 14, 10, 11, 12, 23, 24, 23, 24, 22, 3, 4, 30, 21, 27, 28, 34, 35, 36, 32, 17, 45, 19, 20, 46, 47, 48, 49, 50, 51, 52, 53, 38, 45, 38, 41, 33, 41, 42, 43, 38, 41, 38, 41, 45, 41, 3, 4, 42, 43, 42, 43, 40, 41, 3, 4, 3, 4, 3, 4, 42, 43, 40, 41, 3, 4, 3, 4, 3, 4, 45, 45, 45, 45, 45, 45, 45, 45, 45, 38, 3, 37, 3, 3, 39, 3, 3, 3, 3, 3, 3, 41, 38, 5, 38, 5, 3, 5, 40, 42, 41, 41, 38, 54, 42, 5, 3, 3, 40, 43, 5, 3, 38, 38, 8, 81, 38, -1, -1, 84, -1, 54, 86 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 1, 5, 56, 59, 58, 0, 37, 60, 62, 67, 5, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 22, 23, 24, 27, 28, 30, 32, 34, 35, 36, 44, 61, 63, 64, 68, 69, 71, 72, 73, 79, 80, 37, 62, 67, 38, 41, 42, 43, 38, 41, 45, 57, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 3, 63, 68, 79, 38, 41, 38, 5, 39, 45, 70, 38, 41, 38, 41, 37, 67, 3, 4, 3, 4, 73, 39, 3, 3, 3, 3, 73, 19, 26, 31, 83, 25, 29, 82, 3, 3, 17, 19, 20, 33, 81, 3, 3, 3, 38, 38, 38, 3, 44, 65, 41, 5, 70, 72, 80, 42, 46, 47, 48, 49, 50, 51, 52, 53, 74, 75, 42, 43, 41, 5, 40, 41, 3, 4, 40, 3, 76, 3, 4, 3, 4, 3, 44, 66, 41, 5, 42, 38, 54, 43, 77, 42, 43, 5, 40, 41, 3, 4, 3, 3, 46, 50, 78, 3, 4, 3, 4, 5, 54, 40, 3 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (ff, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, ff, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, FitsFile* ff, ffFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, ff, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; FitsFile* ff; ffFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (ff); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, FitsFile* ff, ffFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, ff, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; FitsFile* ff; ffFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, ff, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, FitsFile* ff, ffFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, ff, ll) YYSTYPE *yyvsp; int yyrule; FitsFile* ff; ffFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , ff, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, ff, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, FitsFile* ff, ffFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, ff, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; FitsFile* ff; ffFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (ff); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (FitsFile* ff, ffFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (FitsFile* ff, ffFlexLexer* ll) #else int yyparse (ff, ll) FitsFile* ff; ffFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 12: #line 92 "parser.Y" {GOTOARR(0);} break; case 16: #line 95 "parser.Y" {GOTOFILT(0);} break; case 17: #line 95 "parser.Y" {ff->setpFilter(ff_filter);;} break; case 19: #line 99 "parser.Y" {ff->setpName((yyvsp[(1) - (1)].str));;} break; case 20: #line 108 "parser.Y" {ff->setpExt((yyvsp[(2) - (3)].str));;} break; case 21: #line 109 "parser.Y" {ff->setpIndex((yyvsp[(2) - (3)].integer));;} break; case 22: #line 112 "parser.Y" {ff->setpExt((yyvsp[(1) - (2)].str));;} break; case 23: #line 113 "parser.Y" {ff->setpIndex((yyvsp[(1) - (2)].integer));;} break; case 27: #line 121 "parser.Y" { ff->setXMin((yyvsp[(3) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setXMax((yyvsp[(3) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setXValid(1); ff->setYMin((yyvsp[(5) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setYMax((yyvsp[(5) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setYValid(1); ;} break; case 28: #line 126 "parser.Y" { ff->setXMin((yyvsp[(3) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setXMax((yyvsp[(3) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setXValid(1); ff->setYMin((yyvsp[(5) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setYMax((yyvsp[(5) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setYValid(1); ff->setZMin((yyvsp[(7) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setZMax((yyvsp[(7) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setZValid(1); ;} break; case 29: #line 132 "parser.Y" { ff->setXMin((yyvsp[(3) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setXMax((yyvsp[(3) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setXValid(1); ff->setYMin((yyvsp[(5) - (5)].integer)-(yyvsp[(1) - (5)].integer)/2); ff->setYMax((yyvsp[(5) - (5)].integer)+(yyvsp[(1) - (5)].integer)/2); ff->setYValid(1); ff->setCoord(1); ;} break; case 30: #line 138 "parser.Y" { ff->setXMin((yyvsp[(3) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setXMax((yyvsp[(3) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setXValid(1); ff->setYMin((yyvsp[(5) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setYMax((yyvsp[(5) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setYValid(1); ff->setZMin((yyvsp[(7) - (7)].integer)-(yyvsp[(1) - (7)].integer)/2); ff->setZMax((yyvsp[(7) - (7)].integer)+(yyvsp[(1) - (7)].integer)/2); ff->setZValid(1); ff->setCoord(1); ;} break; case 31: #line 147 "parser.Y" {ff->setXMin((yyvsp[(1) - (3)].integer)); ff->setXMax((yyvsp[(3) - (3)].integer)); ff->setXValid(1);;} break; case 32: #line 149 "parser.Y" { ff->setXMin((yyvsp[(1) - (3)].integer)); ff->setXMax((yyvsp[(3) - (3)].integer)); ff->setXValid(1); ff->setCoord(1); ;} break; case 33: #line 154 "parser.Y" {ff->setXMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setXMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setXValid(1);;} break; case 34: #line 156 "parser.Y" { ff->setXMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setXMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setXValid(1); ff->setCoord(1); ;} break; case 35: #line 160 "parser.Y" {ff->setXValid(0);;} break; case 36: #line 164 "parser.Y" {ff->setYMin((yyvsp[(1) - (3)].integer)); ff->setYMax((yyvsp[(3) - (3)].integer)); ff->setYValid(1);;} break; case 37: #line 166 "parser.Y" { ff->setYMin((yyvsp[(1) - (3)].integer)); ff->setYMax((yyvsp[(3) - (3)].integer)); ff->setYValid(1); ff->setCoord(1); ;} break; case 38: #line 171 "parser.Y" {ff->setYMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setYMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setYValid(1);;} break; case 39: #line 173 "parser.Y" { ff->setYMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setYMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setYValid(1); ff->setCoord(1); ;} break; case 40: #line 177 "parser.Y" {ff->setYValid(0);;} break; case 41: #line 181 "parser.Y" {ff->setZMin((yyvsp[(1) - (3)].integer)); ff->setZMax((yyvsp[(3) - (3)].integer)); ff->setZValid(1);;} break; case 42: #line 183 "parser.Y" { ff->setZMin((yyvsp[(1) - (3)].integer)); ff->setZMax((yyvsp[(3) - (3)].integer)); ff->setZValid(1); ff->setCoord(1); ;} break; case 43: #line 188 "parser.Y" {ff->setZMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setZMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setZValid(1);;} break; case 44: #line 190 "parser.Y" { ff->setZMin((yyvsp[(3) - (3)].integer)-(yyvsp[(1) - (3)].integer)/2); ff->setZMax((yyvsp[(3) - (3)].integer)+(yyvsp[(1) - (3)].integer)/2); ff->setZValid(1); ff->setCoord(1); ;} break; case 45: #line 194 "parser.Y" {ff->setZValid(0);;} break; case 53: #line 209 "parser.Y" {ff->setpBinXY((yyvsp[(2) - (5)].str),(yyvsp[(4) - (5)].str));;} break; case 54: #line 210 "parser.Y" {ff->setpBinXY((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 55: #line 211 "parser.Y" {ff->setpBinXYZ((yyvsp[(2) - (7)].str),(yyvsp[(4) - (7)].str),(yyvsp[(6) - (7)].str));;} break; case 56: #line 212 "parser.Y" {ff->setpBinXYZ((yyvsp[(1) - (5)].str),(yyvsp[(3) - (5)].str),(yyvsp[(5) - (5)].str));;} break; case 57: #line 213 "parser.Y" {ff->setpBinZ((yyvsp[(2) - (3)].str));;} break; case 58: #line 214 "parser.Y" {ff->setpBinZ((yyvsp[(1) - (1)].str));;} break; case 61: #line 221 "parser.Y" {ff->setpWidth((yyvsp[(3) - (3)].integer));;} break; case 62: #line 222 "parser.Y" {ff->setpHeight((yyvsp[(3) - (3)].integer));;} break; case 63: #line 223 "parser.Y" {ff->setpDepth((yyvsp[(3) - (3)].integer));;} break; case 64: #line 224 "parser.Y" {ff->setpWidth((yyvsp[(3) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;} break; case 65: #line 225 "parser.Y" {ff->setpWidth((yyvsp[(3) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;} break; case 66: #line 226 "parser.Y" {ff->setpBitpix((yyvsp[(3) - (3)].integer));;} break; case 67: #line 227 "parser.Y" {ff->setpSkip((yyvsp[(3) - (3)].integer));;} break; case 68: #line 228 "parser.Y" {ff->setpArch((FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 69: #line 229 "parser.Y" {ff->setpArch((FitsFile::ArchType)(yyvsp[(3) - (3)].integer));;} break; case 70: #line 230 "parser.Y" {ff->setpArch((FitsFile::ArchType)(yyvsp[(1) - (1)].integer));;} break; case 71: #line 233 "parser.Y" {(yyval.integer) = FitsFile::BIG;;} break; case 72: #line 234 "parser.Y" {(yyval.integer) = FitsFile::BIG;;} break; case 73: #line 235 "parser.Y" {(yyval.integer) = FitsFile::BIG;;} break; case 74: #line 236 "parser.Y" {(yyval.integer) = FitsFile::LITTLE;;} break; case 75: #line 237 "parser.Y" {(yyval.integer) = FitsFile::LITTLE;;} break; case 77: #line 243 "parser.Y" {ff->setpBitpix(8);;} break; case 78: #line 244 "parser.Y" {ff->setpBitpix(16);;} break; case 79: #line 245 "parser.Y" {ff->setpBitpix(-16);;} break; case 80: #line 246 "parser.Y" {ff->setpBitpix(32);;} break; case 81: #line 247 "parser.Y" {ff->setpBitpix(64);;} break; case 82: #line 248 "parser.Y" {ff->setpBitpix(-32);;} break; case 83: #line 249 "parser.Y" {ff->setpBitpix(-32);;} break; case 84: #line 250 "parser.Y" {ff->setpBitpix(-64);;} break; case 85: #line 253 "parser.Y" {ff->setpWidth((yyvsp[(1) - (1)].integer));ff->setpHeight((yyvsp[(1) - (1)].integer));;} break; case 86: #line 254 "parser.Y" {ff->setpWidth((yyvsp[(1) - (3)].integer));ff->setpHeight((yyvsp[(3) - (3)].integer));;} break; case 87: #line 256 "parser.Y" {ff->setpWidth((yyvsp[(1) - (5)].integer));ff->setpHeight((yyvsp[(3) - (5)].integer));ff->setpDepth((yyvsp[(5) - (5)].integer));;} break; case 89: #line 260 "parser.Y" {ff->setpSkip((yyvsp[(2) - (2)].integer));;} break; case 91: #line 264 "parser.Y" {ff->setpArch(FitsFile::LITTLE);;} break; case 92: #line 265 "parser.Y" {ff->setpArch(FitsFile::BIG);;} break; case 98: #line 275 "parser.Y" {ff->setpHPXColumn((yyvsp[(3) - (3)].integer));;} break; case 99: #line 276 "parser.Y" {ff->setpHPXQuad((yyvsp[(3) - (3)].integer));;} break; case 100: #line 279 "parser.Y" {ff->setpHPXSystem(FitsHPX::EQU);;} break; case 101: #line 280 "parser.Y" {ff->setpHPXSystem(FitsHPX::GAL);;} break; case 102: #line 281 "parser.Y" {ff->setpHPXSystem(FitsHPX::ECL);;} break; case 103: #line 282 "parser.Y" {ff->setpHPXSystem(FitsHPX::UNKNOWN);;} break; case 104: #line 285 "parser.Y" {ff->setpHPXOrder(FitsHPX::RING);;} break; case 105: #line 286 "parser.Y" {ff->setpHPXOrder(FitsHPX::NESTED);;} break; case 106: #line 289 "parser.Y" {ff->setpHPXLayout(FitsHPX::EQUATOR);;} break; case 107: #line 290 "parser.Y" {ff->setpHPXLayout(FitsHPX::NORTH);;} break; case 108: #line 291 "parser.Y" {ff->setpHPXLayout(FitsHPX::SOUTH);;} break; /* Line 1267 of yacc.c. */ #line 2002 "parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (ff, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (ff, ll, yymsg); } else { yyerror (ff, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, ff, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, ff, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (ff, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, ff, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, ff, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 294 "parser.Y" ���������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdparser.C�����������������������������������������������������������������0000644�0001750�0001750�00000203254�12047246743�016015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse nrrdparse #define yylex nrrdlex #define yyerror nrrderror #define yylval nrrdlval #define yychar nrrdchar #define yydebug nrrddebug #define yynerrs nrrdnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { EOF_ = 258, INT = 259, REAL = 260, STRING = 261, DEBUG_ = 262, ON_ = 263, OFF_ = 264, NRRD0001_ = 265, NRRD0002_ = 266, NRRD0003_ = 267, NRRD0004_ = 268, NRRD0005_ = 269, DATA_ = 270, FILE_ = 271, SPACE_ = 272, UNITS_ = 273, DIMENSIONS_ = 274, ORIGIN_ = 275, DIRECTIONS_ = 276, DIMENSION_ = 277, TYPE_ = 278, SIGNED_ = 279, UNSIGNED_ = 280, CHAR_ = 281, INT8_ = 282, INT8_T_ = 283, UCHAR_ = 284, UINT8_ = 285, UINT8_T_ = 286, SHORT_ = 287, INT_ = 288, INT16_ = 289, INT16_T_ = 290, USHORT_ = 291, UINT16_ = 292, UINT16_T_ = 293, INT32_ = 294, INT32_T_ = 295, UINT_ = 296, UINT32_ = 297, UINT32_T_ = 298, LONG_ = 299, LONGLONG_ = 300, INT64_ = 301, INT64_T_ = 302, ULONGLONG_ = 303, UINT64_ = 304, UINT64_T_ = 305, FLOAT_ = 306, DOUBLE_ = 307, BLOCK_ = 308, SIZE_ = 309, BLOCKSIZE_ = 310, ENCODING_ = 311, RAW_ = 312, TXT_ = 313, TEXT_ = 314, ASCII_ = 315, HEX_ = 316, GZ_ = 317, GZIP_ = 318, BZ2_ = 319, BZIP2_ = 320, ENDIAN_ = 321, BIG_ = 322, LITTLE_ = 323, CONTENT_ = 324, OLD_ = 325, MIN_ = 326, OLDMIN_ = 327, MAX_ = 328, OLDMAX_ = 329, SKIP_ = 330, LINE_ = 331, LINESKIP_ = 332, BYTE_ = 333, BYTESKIP_ = 334, NUMBER_ = 335, SAMPLE_ = 336, SAMPLEUNITS_ = 337, SIZES_ = 338, SPACINGS_ = 339, THICKNESSES_ = 340, AXIS_ = 341, MINS_ = 342, AXISMINS_ = 343, MAXS_ = 344, AXISMAXS_ = 345, CENTERS_ = 346, CENTERINGS_ = 347, CELL_ = 348, NODE_ = 349, NONE_ = 350, LABELS_ = 351, KINDS_ = 352, DOMAINS_ = 353 }; #endif /* Tokens. */ #define EOF_ 258 #define INT 259 #define REAL 260 #define STRING 261 #define DEBUG_ 262 #define ON_ 263 #define OFF_ 264 #define NRRD0001_ 265 #define NRRD0002_ 266 #define NRRD0003_ 267 #define NRRD0004_ 268 #define NRRD0005_ 269 #define DATA_ 270 #define FILE_ 271 #define SPACE_ 272 #define UNITS_ 273 #define DIMENSIONS_ 274 #define ORIGIN_ 275 #define DIRECTIONS_ 276 #define DIMENSION_ 277 #define TYPE_ 278 #define SIGNED_ 279 #define UNSIGNED_ 280 #define CHAR_ 281 #define INT8_ 282 #define INT8_T_ 283 #define UCHAR_ 284 #define UINT8_ 285 #define UINT8_T_ 286 #define SHORT_ 287 #define INT_ 288 #define INT16_ 289 #define INT16_T_ 290 #define USHORT_ 291 #define UINT16_ 292 #define UINT16_T_ 293 #define INT32_ 294 #define INT32_T_ 295 #define UINT_ 296 #define UINT32_ 297 #define UINT32_T_ 298 #define LONG_ 299 #define LONGLONG_ 300 #define INT64_ 301 #define INT64_T_ 302 #define ULONGLONG_ 303 #define UINT64_ 304 #define UINT64_T_ 305 #define FLOAT_ 306 #define DOUBLE_ 307 #define BLOCK_ 308 #define SIZE_ 309 #define BLOCKSIZE_ 310 #define ENCODING_ 311 #define RAW_ 312 #define TXT_ 313 #define TEXT_ 314 #define ASCII_ 315 #define HEX_ 316 #define GZ_ 317 #define GZIP_ 318 #define BZ2_ 319 #define BZIP2_ 320 #define ENDIAN_ 321 #define BIG_ 322 #define LITTLE_ 323 #define CONTENT_ 324 #define OLD_ 325 #define MIN_ 326 #define OLDMIN_ 327 #define MAX_ 328 #define OLDMAX_ 329 #define SKIP_ 330 #define LINE_ 331 #define LINESKIP_ 332 #define BYTE_ 333 #define BYTESKIP_ 334 #define NUMBER_ 335 #define SAMPLE_ 336 #define SAMPLEUNITS_ 337 #define SIZES_ 338 #define SPACINGS_ 339 #define THICKNESSES_ 340 #define AXIS_ 341 #define MINS_ 342 #define AXISMINS_ 343 #define MAXS_ 344 #define AXISMAXS_ 345 #define CENTERS_ 346 #define CENTERINGS_ 347 #define CELL_ 348 #define NODE_ 349 #define NONE_ 350 #define LABELS_ 351 #define KINDS_ 352 #define DOMAINS_ 353 /* Copy the first part of user declarations. */ #line 10 "nrrdparser.Y" #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; nrrdDiscard(x);} #include "file.h" #undef yyFlexLexer #define yyFlexLexer nrrdFlexLexer #include <FlexLexer.h> extern int nrrdlex(void*, nrrdFlexLexer*); extern void nrrderror(FitsFile*, nrrdFlexLexer*, const char*); extern void nrrdDiscard(int); int dim; /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "nrrdparser.Y" { #define NRRDPARSERSIZE 256 float real; int integer; char str[NRRDPARSERSIZE]; } /* Line 193 of yacc.c. */ #line 326 "nrrdparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 339 "nrrdparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 245 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 102 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 44 /* YYNRULES -- Number of rules. */ #define YYNRULES 152 /* YYNRULES -- Number of states. */ #define YYNSTATES 240 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 353 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 4, 7, 11, 14, 15, 18, 20, 22, 27, 30, 34, 38, 40, 44, 48, 49, 54, 58, 62, 64, 66, 68, 70, 74, 78, 82, 86, 91, 95, 100, 104, 108, 112, 116, 120, 124, 126, 128, 130, 132, 134, 135, 139, 141, 143, 145, 147, 149, 151, 152, 156, 160, 161, 166, 167, 172, 173, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 205, 207, 209, 211, 214, 216, 218, 220, 223, 226, 230, 232, 234, 236, 239, 243, 245, 247, 249, 252, 254, 256, 258, 261, 263, 265, 267, 270, 274, 278, 283, 285, 287, 289, 293, 298, 300, 302, 307, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 338, 342, 347, 351, 356, 360, 365, 369, 372, 374, 376, 379, 381, 384, 386, 389, 391, 394, 396, 399, 401, 403, 405, 407, 410, 412, 415, 417, 420 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 103, 0, -1, -1, 104, 105, -1, 105, 106, 111, -1, 106, 111, -1, -1, 7, 113, -1, 108, -1, 109, -1, 15, 16, 99, 6, -1, 17, 114, -1, 22, 99, 4, -1, 23, 99, 119, -1, 128, -1, 56, 99, 129, -1, 66, 99, 130, -1, -1, 69, 99, 107, 6, -1, 71, 99, 112, -1, 73, 99, 112, -1, 131, -1, 132, -1, 133, -1, 134, -1, 80, 99, 6, -1, 83, 99, 135, -1, 84, 99, 137, -1, 85, 99, 138, -1, 86, 87, 99, 139, -1, 88, 99, 139, -1, 86, 89, 99, 140, -1, 90, 99, 140, -1, 91, 99, 141, -1, 92, 99, 141, -1, 96, 99, 143, -1, 18, 99, 144, -1, 97, 99, 145, -1, 10, -1, 11, -1, 12, -1, 13, -1, 14, -1, -1, 100, 110, 6, -1, 101, -1, 3, -1, 5, -1, 4, -1, 8, -1, 9, -1, -1, 99, 115, 6, -1, 22, 99, 4, -1, -1, 18, 99, 116, 6, -1, -1, 20, 99, 117, 6, -1, -1, 21, 99, 118, 6, -1, 120, -1, 121, -1, 122, -1, 123, -1, 124, -1, 125, -1, 126, -1, 127, -1, 51, -1, 52, -1, 53, -1, 26, -1, 24, 26, -1, 27, -1, 28, -1, 29, -1, 25, 26, -1, 30, -1, 31, -1, 32, -1, 32, 33, -1, 24, 32, -1, 24, 32, 33, -1, 34, -1, 35, -1, 36, -1, 25, 32, -1, 25, 32, 33, -1, 37, -1, 38, -1, 33, -1, 24, 33, -1, 39, -1, 40, -1, 41, -1, 25, 33, -1, 42, -1, 43, -1, 45, -1, 44, 44, -1, 44, 44, 33, -1, 24, 44, 44, -1, 24, 44, 44, 33, -1, 46, -1, 47, -1, 48, -1, 25, 44, 44, -1, 25, 44, 44, 33, -1, 49, -1, 50, -1, 53, 54, 99, 4, -1, 55, 99, 4, -1, 57, -1, 58, -1, 59, -1, 60, -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, -1, 67, -1, 68, -1, 70, 71, 99, 112, -1, 72, 99, 112, -1, 70, 73, 99, 112, -1, 74, 99, 112, -1, 76, 75, 99, 4, -1, 77, 99, 4, -1, 78, 75, 99, 4, -1, 79, 99, 4, -1, 135, 136, -1, 136, -1, 4, -1, 137, 112, -1, 112, -1, 138, 112, -1, 112, -1, 139, 112, -1, 112, -1, 140, 112, -1, 112, -1, 141, 142, -1, 142, -1, 93, -1, 94, -1, 95, -1, 143, 6, -1, 6, -1, 144, 6, -1, 6, -1, 145, 6, -1, 6, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 168, 168, 168, 171, 172, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 208, 209, 210, 211, 212, 215, 215, 218, 219, 222, 223, 226, 227, 230, 230, 231, 232, 232, 233, 233, 234, 234, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 250, 251, 252, 253, 256, 257, 258, 259, 262, 263, 264, 265, 266, 267, 270, 271, 272, 273, 274, 277, 278, 279, 280, 283, 284, 285, 286, 289, 290, 291, 292, 293, 294, 295, 298, 299, 300, 301, 302, 305, 306, 309, 310, 311, 312, 313, 314, 315, 316, 317, 320, 321, 324, 325, 328, 329, 332, 333, 336, 337, 340, 341, 344, 362, 363, 366, 367, 370, 371, 374, 375, 378, 379, 382, 383, 384, 387, 388, 391, 392, 395, 396 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "EOF_", "INT", "REAL", "STRING", "DEBUG_", "ON_", "OFF_", "NRRD0001_", "NRRD0002_", "NRRD0003_", "NRRD0004_", "NRRD0005_", "DATA_", "FILE_", "SPACE_", "UNITS_", "DIMENSIONS_", "ORIGIN_", "DIRECTIONS_", "DIMENSION_", "TYPE_", "SIGNED_", "UNSIGNED_", "CHAR_", "INT8_", "INT8_T_", "UCHAR_", "UINT8_", "UINT8_T_", "SHORT_", "INT_", "INT16_", "INT16_T_", "USHORT_", "UINT16_", "UINT16_T_", "INT32_", "INT32_T_", "UINT_", "UINT32_", "UINT32_T_", "LONG_", "LONGLONG_", "INT64_", "INT64_T_", "ULONGLONG_", "UINT64_", "UINT64_T_", "FLOAT_", "DOUBLE_", "BLOCK_", "SIZE_", "BLOCKSIZE_", "ENCODING_", "RAW_", "TXT_", "TEXT_", "ASCII_", "HEX_", "GZ_", "GZIP_", "BZ2_", "BZIP2_", "ENDIAN_", "BIG_", "LITTLE_", "CONTENT_", "OLD_", "MIN_", "OLDMIN_", "MAX_", "OLDMAX_", "SKIP_", "LINE_", "LINESKIP_", "BYTE_", "BYTESKIP_", "NUMBER_", "SAMPLE_", "SAMPLEUNITS_", "SIZES_", "SPACINGS_", "THICKNESSES_", "AXIS_", "MINS_", "AXISMINS_", "MAXS_", "AXISMAXS_", "CENTERS_", "CENTERINGS_", "CELL_", "NODE_", "NONE_", "LABELS_", "KINDS_", "DOMAINS_", "':'", "'#'", "'\\n'", "$accept", "start", "@1", "commands", "command", "@2", "magic", "comment", "@3", "terminator", "numeric", "debug", "space", "@4", "@5", "@6", "@7", "type", "char", "uchar", "short", "ushort", "int", "uint", "long", "ulong", "block", "encoding", "endian", "oldmin", "oldmax", "lineskip", "byteskip", "sizes", "size", "spacings", "thicknesses", "axismins", "axismaxs", "centers", "center", "labels", "units", "kinds", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 58, 35, 10 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 102, 104, 103, 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 108, 108, 108, 108, 108, 110, 109, 111, 111, 112, 112, 113, 113, 115, 114, 114, 116, 114, 117, 114, 118, 114, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 120, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 128, 128, 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 142, 143, 143, 144, 144, 145, 145 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 3, 2, 0, 2, 1, 1, 4, 2, 3, 3, 1, 3, 3, 0, 4, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 4, 3, 4, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 3, 0, 4, 0, 4, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 3, 4, 1, 1, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, 4, 3, 4, 3, 4, 3, 2, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 2, 0, 6, 1, 0, 38, 39, 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 6, 0, 8, 9, 14, 21, 22, 23, 24, 49, 50, 7, 0, 0, 0, 0, 0, 51, 11, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 45, 5, 0, 54, 56, 58, 0, 0, 150, 36, 12, 0, 0, 71, 73, 74, 75, 77, 78, 79, 90, 83, 84, 85, 88, 89, 92, 93, 94, 96, 97, 0, 98, 103, 104, 105, 108, 109, 68, 69, 70, 13, 60, 61, 62, 63, 64, 65, 66, 67, 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 15, 121, 122, 16, 0, 0, 0, 48, 47, 19, 124, 20, 126, 0, 128, 0, 130, 25, 133, 26, 132, 135, 27, 137, 28, 0, 0, 139, 30, 141, 32, 144, 145, 146, 33, 143, 34, 148, 35, 152, 37, 44, 4, 10, 0, 0, 0, 53, 52, 149, 72, 81, 91, 0, 76, 86, 95, 0, 80, 99, 110, 18, 123, 125, 127, 129, 131, 134, 136, 29, 31, 138, 140, 142, 147, 151, 55, 57, 59, 82, 101, 87, 106, 100, 102, 107 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 41, 42, 158, 43, 44, 90, 94, 181, 52, 59, 100, 198, 199, 200, 134, 135, 136, 137, 138, 139, 140, 141, 142, 45, 154, 157, 46, 47, 48, 49, 173, 174, 176, 178, 182, 184, 188, 189, 192, 102, 194 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -138 static const yytype_int16 yypact[] = { -138, 4, 145, -138, 79, -138, -138, -138, -138, -138, 52, -13, -36, -28, -16, 31, -4, -3, -2, -1, -25, 0, 2, 6, 8, 34, 12, 53, 16, 30, 35, 37, 41, -37, 42, 43, 46, 49, 50, 51, -138, 47, 3, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 62, 65, 66, 67, 70, -138, -138, 116, 142, -8, 71, 147, 17, 24, -138, 72, 73, 89, 89, 89, 89, 74, 170, 76, 172, 171, 174, 89, 89, 80, 81, 89, 89, -81, -81, 175, 176, 177, 3, -138, -138, -138, 178, -138, -138, -138, 181, 180, -138, 182, -138, 23, 40, -138, -138, -138, -138, -138, -138, 154, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 146, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 185, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 186, 89, 89, -138, -138, -138, -138, -138, -138, 187, -138, 189, -138, -138, -138, 174, -138, -138, 89, -138, 89, 89, 89, -138, 89, -138, 89, -138, -138, -138, -81, -138, -81, -138, 188, -138, 190, -138, -138, -138, 191, 193, 196, -138, -138, -138, -138, 162, -138, 159, -138, 173, -138, 160, -138, 179, -138, -138, -138, -138, -138, -138, -138, -138, -138, 89, 89, -138, -138, -138, -138, -138, -138, -138, -138, -138, 194, -138, 199, -138, -138, -138 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -138, -138, -138, -138, 164, -138, -138, -138, -138, 117, -70, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, 36, -138, -138, 28, 33, 123, -137, -138, -138, -138 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -4 static const yytype_int16 yytable[] = { 163, 164, 165, 166, 3, 54, 92, 55, 56, 57, 175, 177, 185, 186, 187, 183, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 68, -3, 69, 204, 82, 227, 83, 227, 4, 205, 206, 5, 6, 7, 8, 9, 10, 60, 11, 12, 208, 207, 53, 13, 14, 61, 209, 210, 145, 146, 147, 148, 149, 150, 151, 152, 153, 62, 211, 63, 58, 50, 51, 216, 217, 155, 156, 161, 162, 64, 65, 66, 67, 70, 15, 71, 16, 17, 93, 72, 221, 73, 222, 74, 183, 75, 225, 18, 226, 77, 19, 20, 21, 22, 23, 24, 101, 25, 26, 27, 28, 29, 76, 78, 30, 31, 32, 33, 79, 34, 80, 35, 36, 37, 81, 84, 85, 38, 39, 86, 103, 40, 87, 88, 89, 144, 4, 225, 226, 5, 6, 7, 8, 9, 10, 95, 11, 12, 96, 97, 98, 13, 14, 99, 143, 159, 160, 167, 168, 169, 170, 171, 172, 179, 180, 191, 193, 195, 197, 201, 202, 212, 203, 214, 213, 218, 215, 219, 228, 233, 229, 230, 15, 231, 16, 17, 232, 234, 236, 91, 235, 223, 196, 220, 190, 18, 237, 224, 19, 20, 21, 22, 23, 24, 0, 25, 26, 27, 28, 29, 0, 238, 30, 31, 32, 33, 239, 34, 0, 35, 36, 37, 0, 0, 0, 38, 39, 0, 0, 40 }; static const yytype_int16 yycheck[] = { 70, 71, 72, 73, 0, 18, 3, 20, 21, 22, 80, 81, 93, 94, 95, 85, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 71, 0, 73, 26, 87, 188, 89, 190, 7, 32, 33, 10, 11, 12, 13, 14, 15, 99, 17, 18, 26, 44, 16, 22, 23, 99, 32, 33, 57, 58, 59, 60, 61, 62, 63, 64, 65, 99, 44, 54, 99, 8, 9, 159, 160, 67, 68, 4, 5, 99, 99, 99, 99, 99, 53, 99, 55, 56, 101, 99, 176, 99, 178, 75, 180, 99, 182, 66, 184, 99, 69, 70, 71, 72, 73, 74, 6, 76, 77, 78, 79, 80, 75, 99, 83, 84, 85, 86, 99, 88, 99, 90, 91, 92, 99, 99, 99, 96, 97, 99, 4, 100, 99, 99, 99, 4, 7, 223, 224, 10, 11, 12, 13, 14, 15, 99, 17, 18, 99, 99, 99, 22, 23, 99, 99, 99, 99, 99, 4, 99, 4, 6, 4, 99, 99, 6, 6, 6, 6, 4, 6, 33, 6, 4, 44, 4, 6, 4, 6, 33, 6, 6, 53, 6, 55, 56, 6, 44, 44, 41, 33, 179, 91, 173, 87, 66, 33, 180, 69, 70, 71, 72, 73, 74, -1, 76, 77, 78, 79, 80, -1, 33, 83, 84, 85, 86, 33, 88, -1, 90, 91, 92, -1, -1, -1, 96, 97, -1, -1, 100 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 103, 104, 0, 7, 10, 11, 12, 13, 14, 15, 17, 18, 22, 23, 53, 55, 56, 66, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 83, 84, 85, 86, 88, 90, 91, 92, 96, 97, 100, 105, 106, 108, 109, 128, 131, 132, 133, 134, 8, 9, 113, 16, 18, 20, 21, 22, 99, 114, 99, 99, 99, 54, 99, 99, 99, 99, 71, 73, 99, 99, 99, 99, 75, 99, 75, 99, 99, 99, 99, 99, 87, 89, 99, 99, 99, 99, 99, 99, 110, 106, 3, 101, 111, 99, 99, 99, 99, 99, 115, 6, 144, 4, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 119, 120, 121, 122, 123, 124, 125, 126, 127, 99, 4, 57, 58, 59, 60, 61, 62, 63, 64, 65, 129, 67, 68, 130, 107, 99, 99, 4, 5, 112, 112, 112, 112, 99, 4, 99, 4, 6, 4, 135, 136, 112, 137, 112, 138, 99, 99, 112, 139, 112, 140, 93, 94, 95, 141, 142, 141, 6, 143, 6, 145, 6, 111, 6, 116, 117, 118, 4, 6, 6, 26, 32, 33, 44, 26, 32, 33, 44, 33, 44, 4, 6, 112, 112, 4, 4, 136, 112, 112, 139, 140, 112, 112, 142, 6, 6, 6, 6, 6, 33, 44, 33, 44, 33, 33, 33 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (nrrd, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, nrrd, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, FitsFile* nrrd, nrrdFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, nrrd, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; FitsFile* nrrd; nrrdFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (nrrd); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, FitsFile* nrrd, nrrdFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, nrrd, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; FitsFile* nrrd; nrrdFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, nrrd, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, FitsFile* nrrd, nrrdFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, nrrd, ll) YYSTYPE *yyvsp; int yyrule; FitsFile* nrrd; nrrdFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , nrrd, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, nrrd, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, FitsFile* nrrd, nrrdFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, nrrd, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; FitsFile* nrrd; nrrdFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (nrrd); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (FitsFile* nrrd, nrrdFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (FitsFile* nrrd, nrrdFlexLexer* ll) #else int yyparse (nrrd, ll) FitsFile* nrrd; nrrdFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 168 "nrrdparser.Y" {dim=0;;} break; case 17: #line 186 "nrrdparser.Y" {DISCARD_(1);} break; case 43: #line 215 "nrrdparser.Y" {DISCARD_(1);} break; case 46: #line 219 "nrrdparser.Y" {YYACCEPT;;} break; case 47: #line 222 "nrrdparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 48: #line 223 "nrrdparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 49: #line 226 "nrrdparser.Y" {yydebug=1;;} break; case 50: #line 227 "nrrdparser.Y" {yydebug=0;;} break; case 51: #line 230 "nrrdparser.Y" {DISCARD_(1);} break; case 54: #line 232 "nrrdparser.Y" {DISCARD_(1);} break; case 56: #line 233 "nrrdparser.Y" {DISCARD_(1);} break; case 58: #line 234 "nrrdparser.Y" {DISCARD_(1);} break; case 60: #line 237 "nrrdparser.Y" {nrrd->setpBitpix(8);;} break; case 61: #line 238 "nrrdparser.Y" {nrrd->setpBitpix(8);;} break; case 62: #line 239 "nrrdparser.Y" {nrrd->setpBitpix(16);;} break; case 63: #line 240 "nrrdparser.Y" {nrrd->setpBitpix(16);;} break; case 64: #line 241 "nrrdparser.Y" {nrrd->setpBitpix(32);;} break; case 65: #line 242 "nrrdparser.Y" {nrrd->setpBitpix(32);;} break; case 66: #line 243 "nrrdparser.Y" {nrrd->setpBitpix(64);;} break; case 67: #line 244 "nrrdparser.Y" {nrrd->setpBitpix(64);;} break; case 68: #line 245 "nrrdparser.Y" {nrrd->setpBitpix(-32);;} break; case 69: #line 246 "nrrdparser.Y" {nrrd->setpBitpix(-64);;} break; case 112: #line 309 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::RAW);;} break; case 113: #line 310 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::ASCII);;} break; case 114: #line 311 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::ASCII);;} break; case 115: #line 312 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::ASCII);;} break; case 116: #line 313 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::HEX);;} break; case 117: #line 314 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::GZIP);;} break; case 118: #line 315 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::GZIP);;} break; case 119: #line 316 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::BZ2);;} break; case 120: #line 317 "nrrdparser.Y" {nrrd->setpNRRDEncoding(FitsFile::BZ2);;} break; case 121: #line 320 "nrrdparser.Y" {nrrd->setpArch(FitsFile::BIG);;} break; case 122: #line 321 "nrrdparser.Y" {nrrd->setpArch(FitsFile::LITTLE);;} break; case 133: #line 345 "nrrdparser.Y" { switch (dim) { case 0: nrrd->setpWidth((yyvsp[(1) - (1)].integer)); break; case 1: nrrd->setpHeight((yyvsp[(1) - (1)].integer)); break; case 2: nrrd->setpDepth((yyvsp[(1) - (1)].integer)); break; } dim++; nrrd->setpNRRDDimension(dim); ;} break; /* Line 1267 of yacc.c. */ #line 1982 "nrrdparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (nrrd, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (nrrd, ll, yymsg); } else { yyerror (nrrd, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, nrrd, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, nrrd, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (nrrd, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, nrrd, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, nrrd, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 399 "nrrdparser.Y" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/head.C�����������������������������������������������������������������������0000644�0001750�0001750�00000025612�12006561044�014521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/shm.h> #include "file.h" #include "head.h" FitsHead::FitsHead(char* raw, size_t bytes, Memory mem) { cards_ = raw; mapdata_ = raw; mapsize_ = bytes; memory_ = mem; ncard_ = 0; acard_ = 0; index_ = NULL; valid_ = 0; inherit_ = 0; hdu_ = NULL; char* c; int i; for (c = cards_, i=0; c < cards_+bytes; c+=FTY_CARDLEN, i++) { // only compare 4 chars if (!strncmp(c, "END ", 4)) { ncard_ = i + 1; acard_ = ((ncard_+FTY_CARDS-1)/FTY_CARDS) * FTY_CARDS; valid_ = 1; buildIndex(); updateHDU(); return; } } } FitsHead::FitsHead(char* raw, size_t bytes, char* mm, size_t sz, Memory mem) { cards_ = raw; mapdata_ = mm; mapsize_ = sz; memory_ = mem; ncard_ = 0; acard_ = 0; index_ = NULL; valid_ = 0; inherit_ = 0; hdu_ = NULL; char* c; int i; for (c = cards_, i=0; c < cards_+bytes; c+=FTY_CARDLEN, i++) { // only compare 4 chars if (!strncmp(c, "END ", 4)) { ncard_ = i + 1; acard_ = ((ncard_+FTY_CARDS-1)/FTY_CARDS) * FTY_CARDS; valid_ = 1; buildIndex(); updateHDU(); return; } } } // Create Image FitsHead FitsHead::FitsHead(int width, int height, int depth, int bitpix, char* xtension) { cards_ = new char[FTY_BLOCK]; memset(cards_, ' ', FTY_BLOCK); memcpy(cards_, "END", 3); mapdata_ = NULL; mapsize_ = 0; memory_ = ALLOC; ncard_ = 1; acard_ = FTY_CARDS; index_ = NULL; if (!xtension) appendLogical("SIMPLE", 1, "Fits Standard"); else appendString("XTENSION", xtension, "Fits Standard"); appendInteger("BITPIX", bitpix, "Bits per pixel"); appendInteger("NAXIS", depth>1 ? 3 : 2, "Number of axes"); appendInteger("NAXIS1", width, "Axis Length"); appendInteger("NAXIS2", height, "Axis Length"); if (depth>1) appendInteger("NAXIS3", depth, "Axis Length"); valid_ = 1; inherit_ = 0; hdu_ = NULL; buildIndex(); updateHDU(); } FitsHead::FitsHead(int width, int height, int depth, int bitpix, char* mm, size_t sz, Memory mem) { cards_ = new char[FTY_BLOCK]; memset(cards_, ' ', FTY_BLOCK); memcpy(cards_, "END", 3); mapdata_ = mm; mapsize_ = sz; memory_ = mem; ncard_ = 1; acard_ = FTY_CARDS; index_ = NULL; appendLogical("SIMPLE", 1, "Fits Standard"); appendInteger("BITPIX", bitpix, "Bits per pixel"); appendInteger("NAXIS", depth==1 ? 2 : 3, "Number of axes"); appendInteger("NAXIS1", width, "Axis Length"); appendInteger("NAXIS2", height, "Axis Length"); if (depth>1) appendInteger("NAXIS3", depth, "Axis Length"); valid_ = 1; inherit_ = 0; hdu_ = NULL; buildIndex(); updateHDU(); } FitsHead::FitsHead(const FitsHead& a) { cards_ = new char[a.acard_*FTY_CARDLEN]; memmove(cards_, a.cards_, a.acard_*FTY_CARDLEN); mapdata_ = NULL; mapsize_ = 0; memory_ = ALLOC; index_ = NULL; acard_ = a.acard_; ncard_ = a.ncard_; valid_ = 1; inherit_ = 0; hdu_ = NULL; buildIndex(); updateHDU(); } FitsHead::~FitsHead() { if (index_) delete [] index_; if (hdu_) delete hdu_; switch (memory_) { case ALLOC: if (cards_) delete [] cards_; break; case MMAP: if (mapdata_>0) munmap((caddr_t)mapdata_, mapsize_); break; case SHARE: if (mapdata_>0) shmdt(mapdata_); case EXTERNAL: break; } } int FitsHead::isImage() { // just look for SIMPLE, if present it may be of value 'F' char* xtension = getString("XTENSION"); char* simple = find("SIMPLE"); int r = (simple || (xtension && !strncmp(xtension, "IMAGE", 5))) && naxes() > 0 && naxis(0) > 0 && naxis(1) > 0; delete [] xtension; return r; } int FitsHead::isTable() { char* xtension = getString("XTENSION"); int r = (xtension && (!strncmp(xtension, "TABLE", 5) || !strncmp(xtension, "BINTABLE", 8))); delete [] xtension; return r; } int FitsHead::isAsciiTable() { char* xtension = getString("XTENSION"); int r = (xtension && (!strncmp(xtension, "TABLE", 5))); delete [] xtension; return r; } int FitsHead::isBinTable() { char* xtension = getString("XTENSION"); int r = (xtension && (!strncmp(xtension, "BINTABLE", 8))); delete [] xtension; return r; } int FitsHead::isHeap() { return getInteger("PCOUNT",0) ? 1 : 0; } void FitsHead::updateHDU() { if (hdu_) delete hdu_; hdu_ = NULL; // just find simple, it might be present but of value 'F' char* simple = find("SIMPLE"); char* xtension = getString("XTENSION"); if (xtension) inherit_ = getLogical("INHERIT",0); if (simple || (xtension && !strncmp(xtension, "IMAGE", 5))) hdu_ = new FitsImageHDU(this); if (xtension && !strncmp(xtension, "TABLE", 5)) hdu_ = new FitsAsciiTableHDU(this); if (xtension && !strncmp(xtension, "BINTABLE", 8)) hdu_ = new FitsBinTableHDU(this); delete [] xtension; } int FitsHead::getLogical(const char* name, int def) { char* card = find(name); if (card) { FitsCard c(card); return c.getLogical(); } else return def; } int FitsHead::getInteger(const char* name, int def) { char* card = find(name); if (card) { FitsCard c(card); return c.getInteger(); } else return def; } double FitsHead::getReal(const char* name, double def) { char* card = find(name); if (card) { FitsCard c(card); return c.getReal(); } else return def; } void FitsHead::getComplex(const char* name, double* real, double* img, double rdef, double idef) { char* card = find(name); if (card) { FitsCard c(card); c.getComplex(real, img); } else { *real = rdef; *img = idef; } } char* FitsHead::getString(const char* name) { char* card = find(name); if (card) { FitsCard c(card); return c.getString(); } else return NULL; } char* FitsHead::getComment(const char* name) { char* card = find(name); if (card) { FitsCard c(card); return c.getComment(); } else return NULL; } char* FitsHead::getKeyword(const char* name) { char* card = find(name); if (card) { FitsCard c(card); return c.getAsString(); } else return NULL; } char* FitsHead::setLogical(const char* name, int value, const char* comm) { char* card = find(name); if (card) FitsCard(card).setLogical(value, comm); return card; } char* FitsHead::setInteger(const char* name, int value, const char* comm) { char* card = find(name); if (card) FitsCard(card).setInteger(value, comm); return card; } char* FitsHead::setReal(const char* name, double value, int prec, const char* comm) { char* card = find(name); if (card) FitsCard(card).setReal(value, prec, comm); return card; } char* FitsHead::setComplex(const char* name, double real, double img, int prec, const char* comm) { char* card = find(name); if (card) FitsCard(card).setComplex(real, img, prec, comm); return card; } char* FitsHead::setString(const char* name, const char* value, const char* comm) { char* card = find(name); if (card) FitsCard(card).setString(value, comm); return card; } char* FitsHead::setComment(const char* name, const char* value) { char* card = find(name); if (card) FitsCard(card).setComment(value); return card; } char* FitsHead::cardins(char* card, char* here) { // do we need to allocate another block? if (ncard_+1 > acard_) { switch (memory_) { case ALLOC: { char* old = cards_; int oldsz = acard_*FTY_CARDLEN; int sz = oldsz+FTY_BLOCK; acard_ = sz/FTY_CARDLEN; cards_ = new char[sz]; memset(cards_, ' ', sz); memcpy(cards_, old, oldsz); delete [] old; } break; case MMAP: case EXTERNAL: internalError("Fitsy++ head can't add card: readonly memory"); return NULL; } } char* where = here ? here : cards_+((ncard_-1)*FTY_CARDLEN); memmove(where+FTY_CARDLEN, where, (cards_+(ncard_*FTY_CARDLEN))-where); memmove(where, card, FTY_CARDLEN); ncard_++; if (index_) buildIndex(); return where; } char* FitsHead::carddel(char* card) { return card; } char* FitsHead::insertLogical(const char* name, int value, const char* comm, const char* here) { FitsCard key; key.setLogical(name, value, comm); return cardins(key.card(), (char*)here); } char* FitsHead::insertInteger(const char* name, int value, const char* comm, const char* here) { FitsCard key; key.setInteger(name, value, comm); return cardins(key.card(), (char*)here); } char* FitsHead::insertReal(const char* name, double value, int prec, const char* comm, const char* here) { FitsCard key; key.setReal(name, value, prec, comm); return cardins(key.card(), (char*)here); } char* FitsHead::insertComplex(const char* name, double real, double img, int prec, const char* comm, const char* here) { FitsCard key; key.setComplex(name, real, img, prec, comm); return cardins(key.card(), (char*)here); } char* FitsHead::insertString(const char* name, const char* value, const char* comm, const char* here) { FitsCard key; key.setString(name, value, comm); return cardins(key.card(), (char*)here); } char* FitsHead::insertComment(const char* name, const char* value, const char* here) { FitsCard key; key.setComment(name, value); return cardins(key.card(), (char*)here); } char* FitsHead::find(const char* key) { if (index_) return findIndex(key); else return findSeq(key); } char* FitsHead::findSeq(const char* key) { if (key == NULL) return NULL; char k[8]; memset(k,' ',8); int len = strlen(key); // convert to uppercase int l = (len>8 ? 8 : len); for (int i=0; i<l; i++) k[i] = toupper(key[i]); for (char* card=cards_; card!=&cards_[ncard_*FTY_CARDLEN]; card+=FTY_CARDLEN) if (!strncmp(k, card, 8)) return card; return NULL; } char* FitsHead::findIndex(const char* key) { if (key == NULL) return NULL; char k[8]; memset(k,' ',8); int len = strlen(key); // convert to uppercase int l = (len>8 ? 8 : len); for (int i=0; i<l; i++) k[i] = toupper(key[i]); char** base = index_; int length = ncard_; int lo = -1; int hi = length; int cut = length/2; while (hi-lo > 1) { int i = strncmp(k, base[cut], 8); if (!i) return base[cut]; if (i < 0) { hi = cut; cut = (lo+hi)/2; } else { lo = cut; cut = (lo+hi)/2; } } if (!strncmp(k, base[cut], 8)) return base[cut]; return NULL; } static int compare(const void* a, const void* b) { char** aa = (char**)a; char** bb = (char**)b; return strncmp(*aa, *bb, 8); } void FitsHead::buildIndex() { if (index_) delete [] index_; index_ = new char*[ncard_]; for (int i=0; i<ncard_; i++) index_[i] = cards_ + (i*FTY_CARDLEN); qsort(index_, ncard_, sizeof(char**), compare); } ����������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/photo.C����������������������������������������������������������������������0000644�0001750�0001750�00000006724�12075360501�014755� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "photo.h" FitsPhoto::FitsPhoto(Tcl_Interp* interp, const char* ph) { // reset valid_ = 0; if (*ph == '\0') { Tcl_AppendResult(interp, "bad image name ", NULL); return; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, ph); if (!photo) { Tcl_AppendResult(interp, "bad image handle ", NULL); return; } Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block ", NULL); return; } int width =0; int height =0; Tk_PhotoGetSize(photo, &width, &height); // new header head_ = new FitsHead(width, height, 1, 8); if (!head_->isValid()) return; size_t size = (size_t)width*height; unsigned char* dest = new unsigned char[size]; data_ = dest; dataSize_ = size; dataSkip_ = 0; unsigned char* src = block.pixelPtr; for (int jj=height-1; jj>=0; jj--) for (int ii=0; ii<width; ii++) { int pp = (jj*width+ii)*block.pixelSize; unsigned char rr = src[pp+block.offset[0]]; unsigned char gg = src[pp+block.offset[1]]; unsigned char bb = src[pp+block.offset[2]]; //unsigned char vv = (rr+gg+bb)/3.; //unsigned char vv = .2126*rr + .7152*gg + .0722*bb; unsigned char vv = .299*rr + .587*gg + .114*bb; *dest++ = vv; } // made it this far, must be valid byteswap_ = 0; valid_ = 1; orgFits_ = 0; } FitsPhoto::~FitsPhoto() { if (data_) delete [] (unsigned char*)data_; } FitsPhotoCube::FitsPhotoCube(Tcl_Interp* interp, const char* ph) { // reset valid_ = 0; if (*ph == '\0') { Tcl_AppendResult(interp, "bad image name ", NULL); return; } Tk_PhotoHandle photo = Tk_FindPhoto(interp, ph); if (!photo) { Tcl_AppendResult(interp, "bad image handle ", NULL); return; } Tk_PhotoImageBlock block; if (!Tk_PhotoGetImage(photo,&block)) { Tcl_AppendResult(interp, "bad image block ", NULL); return; } int width =0; int height =0; int depth =3; Tk_PhotoGetSize(photo, &width, &height); // new header head_ = new FitsHead(width, height, depth, 8); if (!head_->isValid()) return; size_t size = (size_t)width*height*depth; unsigned char* dest = new unsigned char[size]; data_ = dest; dataSize_ = size; dataSkip_ = 0; unsigned char* src = block.pixelPtr; for (int kk=0; kk<depth; kk++) { for (int jj=height-1; jj>=0; jj--) { for (int ii=0; ii<width; ii++) { int pp = (jj*width+ii)*block.pixelSize; *dest++ = src[pp+block.offset[kk]]; } } } // made it this far, must be valid byteswap_ = 0; valid_ = 1; orgFits_ = 0; } FitsPhotoCube::~FitsPhotoCube() { if (data_) delete [] (unsigned char*)data_; } FitsPhotoCubeNext::FitsPhotoCubeNext(FitsFile* prev) { primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = head_->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); return; } ��������������������������������������������./saods9/saotk/fitsy++/channel.C��������������������������������������������������������������������0000644�0001750�0001750�00000000612�11700666264�015233� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "channel.h" FitsChannel::FitsChannel(Tcl_Interp* interp, const char* ch, const char* ext) { parse(ext); int tclMode; stream_ = Tcl_GetChannel(interp, (char*)ch, &tclMode); if (stream_) valid_ = 1; } ����������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/plio.h�����������������������������������������������������������������������0000644�0001750�0001750�00000000645�11700666265�014642� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsplio_h__ #define __fitsplio_h__ #include "compress.h" template<class T> class FitsPliom : public FitsCompressm<T> { private: int compressed(T*, char*, char*, int, int, int, int, int, int); public: FitsPliom(FitsFile*); }; #endif �������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/plio.C�����������������������������������������������������������������������0000644�0001750�0001750�00000004325�11700666265�014574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "plio.h" extern "C" { int pl_l2pi(short *ll_src, int xs, int *px_dst, int npix); } template<class T> FitsPliom<T>::FitsPliom(FitsFile* fits) : FitsCompressm<T>(fits) { FitsCompressm<T>::uncompress(fits); } template <class T> int FitsPliom<T>::compressed(T* dest, char* sptr, char* heap, int kkstart, int kkstop, int jjstart, int jjstop, int iistart, int iistop) { double zs = FitsCompressm<T>::bscale_; if (FitsCompressm<T>::zscale_) zs = FitsCompressm<T>::zscale_->value(sptr,0); double zz = FitsCompressm<T>::bzero_; if (FitsCompressm<T>::zzero_) zz = FitsCompressm<T>::zzero_->value(sptr,0); int blank = FitsCompressm<T>::blank_; if (FitsCompressm<T>::zblank_) blank = (int)FitsCompressm<T>::zblank_->value(sptr,0); int icnt=0; short* ibuf = (short*)((FitsBinColumnArray*)FitsCompressm<T>::compress_)->get(heap, sptr, &icnt); // swap if needed if (FitsCompressm<T>::byteswap_) for (int ii=0; ii<icnt; ii++) { const char* p = (const char*)(ibuf+ii); union { char c[2]; short s; } u; u.c[1] = *p++; u.c[0] = *p; *(ibuf+ii) = u.s; } // ibuf can be NULL if (ibuf && icnt>0) { int ocnt = FitsCompressm<T>::ww_ * FitsCompressm<T>::hh_ * FitsCompressm<T>::dd_; int obuf[ocnt]; int cc = pl_l2pi(ibuf, 1, obuf, ocnt); if (cc != ocnt) { internalError("Fitsy++ plio error"); return 0; } int ll=0; for (int kk=kkstart; kk<kkstop; kk++) for (int jj=jjstart; jj<jjstop; jj++) for (int ii=iistart; ii<iistop; ii++,ll++) dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = FitsCompressm<T>::getValue(obuf+ll,zs,zz,blank); } return 1; } template class FitsPliom<unsigned char>; template class FitsPliom<short>; template class FitsPliom<unsigned short>; template class FitsPliom<int>; template class FitsPliom<long long>; template class FitsPliom<float>; template class FitsPliom<double>; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outsocket.h������������������������������������������������������������������0000644�0001750�0001750�00000001272�12075604063�015706� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __outfitssocket_h__ #define __outfitssocket_h__ #include "outfits.h" #include "zlib.h" class OutFitsSocket : public virtual OutFitsStream { private: int id_; public: OutFitsSocket(int s); int write(char*, size_t); }; class OutFitsSocketGZ : public virtual OutFitsStream { private: int id_; z_stream* stream_; unsigned char* buf_; unsigned long crc_; int deflategz(int); void putlong(unsigned long); public: OutFitsSocketGZ(int); ~OutFitsSocketGZ(); int write(char*, size_t); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hist.C�����������������������������������������������������������������������0000644�0001750�0001750�00000032326�12075360501�014570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <string.h> #include <ctype.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "hist.h" #include "util.h" #include "fitsy.h" #include "filter.h" #define FILTERSIZE 262144 #define MULTWCS 27 char *gerrorstring(void); FitsHist::FitsHist(FitsFile* fits, int w, int h, int d, Matrix& m, Function func, Vector block) : width_(w), height_(h), depth_(d) { size_ = (size_t)width_*height_*depth_; xcol_ = NULL; ycol_ = NULL; zcol_ = NULL; fitsy_ = NULL; filter_ = NULL; valid_ = 0; if (!initHeader(fits)) return; // we need to translate by another .5 for the offset from Data to Image Matrix mm = m * Translate(.5,.5); initLTMV(mm); initWCS(fits, mm, block); initFilter(fits); bin(fits, m, func, block); if (byteswap_) swap(); deleteFilter(); valid_ = 1; } FitsHist::~FitsHist() { if (data_) delete [] (float*)data_; } int FitsHist::initHeader(FitsFile* fits) { FitsHead* srcHead = fits->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); // make sure we have a table with columns, X, Y if (!fits->isBinTable()) return 0; // make sure we have rows and cols if (!srcHDU->width() || !srcHDU->rows()) return 0; // get X column if (fits->pBinX()) xcol_ = srcHDU->find(fits->pBinX()); if (!xcol_) return 0; // get Y column if (fits->pBinY()) ycol_ = srcHDU->find(fits->pBinY()); if (!ycol_) return 0; // get Z column (if specified) if (fits->pBinZ() && depth_ > 1) zcol_ = srcHDU->find(fits->pBinZ()); else zcol_ = NULL; // create header head_ = new FitsHead(width_, height_, depth_, -32); if (!head_->isValid()) return 0; // OBJECT char* object = srcHead->getString("OBJECT"); if (object) { head_->appendString("OBJECT", object, NULL); delete [] object; } // DATE-OBS char* dateobs = srcHead->getString("DATE-OBS"); if (dateobs) { head_->appendString("DATE-OBS", dateobs, NULL); delete [] dateobs; } char* timeobs = srcHead->getString("TIME-OBS"); if (timeobs) { head_->appendString("TIME-OBS", timeobs, NULL); delete [] timeobs; } char* dateend = srcHead->getString("DATE-END"); if (dateend) { head_->appendString("DATE-END", dateend, NULL); delete [] dateend; } char* timeend = srcHead->getString("TIME-END"); if (timeend) { head_->appendString("TIME-END", timeend, NULL); delete [] timeend; } // we added cards head_->updateHDU(); return 1; } void FitsHist::initFilter(FitsFile* fits) { char *s=NULL; FitsHead* srcHead = fits->head(); const char* filtstr = fits->pFilter(); if (filtstr && *filtstr) { ostringstream str; str << "bincols=(" << fits->pBinX() << ',' << fits->pBinY() << ')'; if (byteswap_) str << ",convert=true"; str << ends; if (!(fitsy_ = ft_headinit(srcHead->cards(), srcHead->headbytes()))) internalError("Fitsy++ hist bad filter head"); else { if (!(filter_ = FilterOpen((FITSHead)fitsy_, (char*)filtstr, (char*)str.str().c_str()))){ internalError("Fitsy++ hist unable to build filter"); } } } } void FitsHist::deleteFilter() { if (filter_) { FilterClose((Filter)filter_); filter_ = NULL; } if (fitsy_) { ft_headfree((FITSHead)fitsy_,0); fitsy_ = NULL; } } void FitsHist::bin(FitsFile* fits, Matrix& m, Function func, Vector block) { FitsHead* srcHead = fits->head(); FitsTableHDU* srcHDU = (FitsTableHDU*)(srcHead->hdu()); // create image space float* dest = new float[size_]; memset(dest, 0, size_*sizeof(float)); // bin it up char* ptr = (char*)fits->data(); int rowlen = srcHDU->width(); int rows = srcHDU->rows(); // third dimension double zmin; double zlength; if (zcol_) { zmin = zcol_->getMin(); zlength = zcol_->getMax() - zcol_->getMin(); } // filter int goodincr = 0; int goodindex = FILTERSIZE; int* good = NULL; if (filter_) good = new int[FILTERSIZE]; // matrix register double m00 = m.matrix(0,0); register double m10 = m.matrix(1,0); register double m20 = m.matrix(2,0); register double m01 = m.matrix(0,1); register double m11 = m.matrix(1,1); register double m21 = m.matrix(2,1); for (int ii=0; ii<rows; ii++, ptr+=rowlen, goodindex++) { // incr filter block, if needed if (good && (goodindex>=FILTERSIZE)) { // for memory models that support internal paging // need at lease FILTERSIZE rows ptr = fits->page(ptr, rowlen*FILTERSIZE); int diff = srcHDU->rows() - (goodincr * FILTERSIZE); if (FilterEvents((Filter)filter_, ptr, srcHDU->width(), (diff<FILTERSIZE) ? diff : FILTERSIZE, good)) { goodincr++; goodindex = 0; } else { if (good) delete [] good; good = NULL; internalError("Fitsy++ hist filter failed"); } } else { // for memory models that support internal paging // all we need is just one row ptr = fits->page(ptr, rowlen); } if (!good || (good && good[goodindex])) { register double x = xcol_->value(ptr); register double y = ycol_->value(ptr); register double X = x*m00 + y*m10 + m20; register double Y = x*m01 + y*m11 + m21; if (X >= 0 && X < width_ && Y >= 0 && Y < height_) { if (!zcol_) dest[((int)Y)*width_ + (int)X]++; else { int zz = (int)((zcol_->value(ptr)-zmin)/zlength*depth_); if (zz>=0 && zz<depth_) dest[(zz*width_*height_) + ((int)Y)*width_ + (int)X]++; } } } } // for memory models that support internal paging fits->resetpage(); // Average if (func==AVERAGE) for (int k=0; k<size_; k++) dest[k] /= (block[0]*block[1]); if (good) delete [] good; data_ = dest; dataSize_ = size_; dataSkip_ = 0; } void FitsHist::swap() { if (!data_) return; // we now need to byteswap back to native form float* dest = (float*)data_; for (int i=0; i<size_; i++) { const char* p = (char*)(dest+i); union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; dest[i] = u.f; } } void FitsHist::initLTMV(Matrix& m) { head_->appendReal("LTM1_1", m[0][0], 10, NULL); head_->appendReal("LTM1_2", m[0][1], 10, NULL); head_->appendReal("LTM2_1", m[1][0], 10, NULL); head_->appendReal("LTM2_2", m[1][1], 10, NULL); head_->appendReal("LTV1" , m[2][0], 10, NULL); head_->appendReal("LTV2" , m[2][1], 10, NULL); } void FitsHist::mapWCSString(FitsHead* head, char* w, const char* out, const char* prim) { ostringstream istr; istr << prim << xcol_->index() << w << ends; if (head->find(istr.str().c_str())) { char* cc = head->getString(istr.str().c_str()); head_->appendString(out, cc, NULL); delete [] cc; } } void FitsHist::mapWCSString(FitsHead* head, char* w, const char* out, const char* prim, const char* alt) { ostringstream istr1, istr2; if (!w[0]) { istr1 << prim << xcol_->index() << w << ends; istr2 << prim << ycol_->index() << w << ends; } else { istr1 << alt << xcol_->index() << w << ends; istr2 << alt << ycol_->index() << w << ends; } ostringstream ostr1, ostr2; ostr1 << out << "1" << w << ends; ostr2 << out << "2" << w << ends; if (head->find(istr1.str().c_str()) || head->find(istr2.str().c_str())) { char* cc1 = head->getString(istr1.str().c_str()); char* cc2 = head->getString(istr2.str().c_str()); head_->appendString(ostr1.str().c_str(), cc1, NULL); head_->appendString(ostr2.str().c_str(), cc2, NULL); delete [] cc1; delete [] cc2; } } void FitsHist::mapWCSReal(FitsHead* head, const char* out, const char* in) { ostringstream istr; istr << in << xcol_->index() << ends; if (head->find(istr.str().c_str())) { float cc = head->getReal(istr.str().c_str(), 0); head_->appendReal(out, cc, 10, NULL); } } void FitsHist::mapWCSReal(FitsHead* head, char* w, const char* out, const char* in) { ostringstream istr; istr << in << xcol_->index() << w << ends; if (head->find(istr.str().c_str())) { float cc = head->getReal(istr.str().c_str(), 0); head_->appendReal(out, cc, 10, NULL); } } void FitsHist::mapWCSReal(FitsHead* head, char* w, const char* out, const char* prim, const char* alt, Matrix mm) { ostringstream istr1, istr2; if (!w[0]) { istr1 << prim << xcol_->index() << w << ends; istr2 << prim << ycol_->index() << w << ends; } else { istr1 << alt << xcol_->index() << w << ends; istr2 << alt << ycol_->index() << w << ends; } ostringstream ostr1, ostr2; ostr1 << out << "1" << w << ends; ostr2 << out << "2" << w << ends; if (head->find(istr1.str().c_str()) || head->find(istr2.str().c_str())) { float cc1 = head->getReal(istr1.str().c_str(),0); float cc2 = head->getReal(istr2.str().c_str(),0); Vector cc = Vector(cc1,cc2) * mm; head_->appendReal(ostr1.str().c_str(), cc[0], 10, NULL); head_->appendReal(ostr2.str().c_str(), cc[1], 10, NULL); } } void FitsHist::mapWCSMatrix(FitsHead* head, char* w, const char* out, const char* in, Vector vv) { ostringstream istr1, istr2, istr3, istr4; istr1 << in << xcol_->index() << "_" << xcol_->index() << w << ends; istr2 << in << xcol_->index() << "_" << ycol_->index() << w << ends; istr3 << in << ycol_->index() << "_" << xcol_->index() << w << ends; istr4 << in << ycol_->index() << "_" << ycol_->index() << w << ends; ostringstream ostr1, ostr2, ostr3, ostr4; ostr1 << out << "1_1" << w << ends; ostr2 << out << "1_2" << w << ends; ostr3 << out << "2_1" << w << ends; ostr4 << out << "2_2" << w << ends; if (head->find(istr1.str().c_str()) || head->find(istr2.str().c_str()) || head->find(istr3.str().c_str()) || head->find(istr4.str().c_str())) { float cc11 = head->getReal(istr1.str().c_str(), 0); float cc12 = head->getReal(istr2.str().c_str(), 0); float cc21 = head->getReal(istr3.str().c_str(), 0); float cc22 = head->getReal(istr4.str().c_str(), 0); Matrix cc = Matrix(cc11*vv[0], cc12*vv[0], cc21*vv[1], cc22*vv[1], 0, 0); head_->appendReal(ostr1.str().c_str(), cc[0][0], 10, NULL); head_->appendReal(ostr2.str().c_str(), cc[0][1], 10, NULL); head_->appendReal(ostr3.str().c_str(), cc[1][0], 10, NULL); head_->appendReal(ostr4.str().c_str(), cc[1][1], 10, NULL); } } void FitsHist::mapWCSVector(FitsHead* head, char* w, const char* out, const char* in) { for (int ii=0; ii<=9; ii++) { ostringstream istr1, istr2; istr1 << in << xcol_->index() << "_" << ii << w << ends; istr2 << in << ycol_->index() << "_" << ii << w << ends; ostringstream ostr1, ostr2; ostr1 << out << "1_" << ii << ends; ostr2 << out << "2_" << ii << ends; if (head->find(istr1.str().c_str()) || head->find(istr2.str().c_str())) { float cc1 = head->getReal(istr1.str().c_str(), 0); float cc2 = head->getReal(istr1.str().c_str(), 0); head_->appendReal(ostr1.str().c_str(), cc1, 10, NULL); head_->appendReal(ostr2.str().c_str(), cc1, 10, NULL); } } } void FitsHist::initWCS(FitsFile* fits, Matrix& mm, Vector block) { FitsHead* srcHead = fits->head(); char w[2]; w[1] = '\0'; for (int i=0; i<MULTWCS; i++) { if (!i) w[0] = '\0'; else w[0] = '@'+i; mapWCSString(srcHead, w, "CTYPE", "TCTYP", "TCTY"); mapWCSString(srcHead, w, "CUNIT", "TCUNI", "TCUN"); mapWCSReal(srcHead, w, "CRVAL", "TCRVL", "TCRV", Matrix()); mapWCSReal(srcHead, w, "CDELT", "TCDLT", "TCDE", Scale(block)); mapWCSReal(srcHead, w, "CRPIX", "TCRPX", "TCRP", mm); mapWCSReal(srcHead, w, "CROTA", "TCROT", "TCRO", Matrix()); mapWCSMatrix(srcHead, w, "PC", "TP", Vector(1,1)); mapWCSMatrix(srcHead, w, "CD", "TC", block); mapWCSVector(srcHead, w, "PV", "TV"); mapWCSVector(srcHead, w, "PS", "TS"); mapWCSString(srcHead, w, "WCSNAME", "TWCS"); // alt mapWCSMatrix(srcHead, w, "PC", "TPC", Vector(1,1)); mapWCSMatrix(srcHead, w, "CD", "TCD", block); mapWCSVector(srcHead, w, "PV", "TPV"); mapWCSVector(srcHead, w, "PS", "TPS"); mapWCSString(srcHead, w, "WCSNAME", "WCS"); mapWCSReal(srcHead, w, "LONPOLE", "LONP"); mapWCSReal(srcHead, w, "LATPOLE", "LATP"); mapWCSReal(srcHead, w, "EQUINOX", "EQUI"); mapWCSString(srcHead, w, "RADESYS", "RADE"); mapWCSReal(srcHead, "MJD-OBS", "MJDOB"); mapWCSReal(srcHead, "DATE-OBS", "DOBS"); // EPOCH if (head_->find("EPOCH")) { char* cc = head_->getString("EPOCH"); head_->appendString("EPOCH", cc, NULL); delete [] cc; } } } FitsHistNext::FitsHistNext(FitsFile* prev) { primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); return; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/map.C������������������������������������������������������������������������0000644�0001750�0001750�00000020313�12075360501�014367� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "map.h" #include "head.h" FitsMap::FitsMap() { mapdata_ = NULL; mapsize_ = 0; } char* FitsMap::enddata() { // return the address of the first data byte pass the end of data return head_ ? (char*)data_+head_->databytes() : NULL; } size_t FitsMap::endsize() { // return the size - (header+data) return head_ ? (mapsize_ - (size_t)((char*)data_+head_->databytes()-mapdata_)) : 0; } void FitsMap::found(char* here) { data_ = here + head_->headbytes(); dataSize_ = mapsize_; dataSkip_ = here - mapdata_ + head_->headbytes(); inherit_ = head_->inherit(); valid_ = 1; } void FitsMap::error() { if (manageHead_ && head_) delete head_; head_ = NULL; if (managePrimary_ && primary_) delete primary_; primary_ = NULL; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; valid_ = 0; } FitsFitsMap::FitsFitsMap(ScanMode mode) { if (!valid_) return; if (mode == EXACT || pExt_ || pIndex_>-1) processExact(); else processRelax(); } void FitsFitsMap::processExact() { // find head and data for specified unit char* here = mapdata_; size_t size = mapsize_; // simple check for fits file if (strncmp(mapdata_,"SIMPLE ",8) && strncmp(mapdata_,"XTENSION",8)) { error(); return; } if (!(pExt_ || (pIndex_>0))) { // we are only looking for a primary image head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid()) { found(here); return; } } else { // we are looking for an extension // keep the primary header primary_ = new FitsHead(here, size, FitsHead::EXTERNAL); managePrimary_ = 1; if (!primary_->isValid()) { error(); return; } here += primary_->headbytes() + primary_->databytes(); size -= primary_->headbytes() + primary_->databytes(); if (pExt_) { while (size > 0) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; if (head_->extname()) { char* a = toUpper(head_->extname()); char* b = toUpper(pExt_); if (!strncmp(a,b,strlen(b))) { delete [] a; delete [] b; found(here); return; } delete [] a; delete [] b; } here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } } else { for (int i=1; i<pIndex_ && size>0; i++) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid()) { ext_++; found(here); return; } } } // Must have an error error(); } void FitsFitsMap::processRelax() { char* here = mapdata_; size_t size = mapsize_; // simple check for fits file if (strncmp(mapdata_,"SIMPLE ",8) && strncmp(mapdata_,"XTENSION",8)) { error(); return; } // check to see if there is an image in the primary head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid() && head_->naxes() > 0 && head_->naxis(0) > 0 && head_->naxis(1) > 0) { found(here); return; } // ok, no image, save primary and lets check extensions here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); primary_ = head_; managePrimary_ = 1; head_ = NULL; while (size > 0) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; // check for image if (head_->isImage()) { found(here); return; } // else, check for compressed image if (head_->isBinTable() && head_->find("ZIMAGE")) { found(here); return; } // else, check for bin table named STDEVT, EVENTS, RAYEVENT if (head_->isBinTable() && head_->extname()) { char* a = toUpper(head_->extname()); if (!strncmp("STDEVT", a, 6) || !strncmp("EVENTS", a, 6) || !strncmp("RAYEVENT", a, 8)) { delete [] a; found(here); return; } } // else, check for bin table with keyword PIXTYPE = 'HEALPIX ' if (head_->isBinTable() && head_->find("PIXTYPE") && (!strncmp(head_->getString("PIXTYPE"),"HEALPIX",4))) { found(here); return; } // else, check for bin table with keyword NSIDE (also HEALPIX) if (head_->isBinTable() && head_->find("NSIDE")) { found(here); return; } here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } // did not find anything, bail out error(); } FitsFitsNextMap::FitsFitsNextMap(FitsFile* p) { FitsMap* prev = (FitsMap*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); orgFits_ = prev->orgFits(); valid_ = 1; pWidth_ = prev->pWidth(); pHeight_ = prev->pHeight(); pDepth_ = prev->pDepth(); pBitpix_ = prev->pBitpix(); pSkip_ = prev->pSkip(); pArch_ = prev->pArch(); coord_ = prev->coord(); xvalid_ = prev->xvalid(); xmin_ = prev->xmin(); xmax_ = prev->xmax(); yvalid_ = prev->yvalid(); ymin_ = prev->ymin(); ymax_ = prev->ymax(); zvalid_ = prev->zvalid(); zmin_ = prev->zmin(); zmax_ = prev->zmax(); mapdata_ = prev->mapdata(); mapsize_ = prev->mapsize(); return; } FitsArrMap::FitsArrMap() { if (!valid_) return; // reset valid_ = 0; // check to see if we have a nonzero width, height, and bitpix if (!validParams()) return; // check to see if dimensions equal mapped space if (((size_t)pWidth_*pHeight_*pDepth_*abs(pBitpix_)/8)+pSkip_ > mapsize_) return; // skip to start of data data_ = mapdata_ + pSkip_; dataSize_ = mapsize_; dataSkip_ = pSkip_; // new header head_ = new FitsHead(pWidth_, pHeight_, pDepth_, pBitpix_); if (!head_->isValid()) return; // do we byteswap? setByteSwap(); // made it this far, must be valid valid_ = 1; orgFits_ = 0; } FitsNRRDMap::FitsNRRDMap() { if (!valid_) return; // reset valid_ = 0; // header { char buf[1024]; char* dptr = buf; char* sptr = mapdata_; int cnt =0; do { *dptr++ = *sptr++; if (cnt>0 && (*sptr == '\n' && *(sptr-1) == '\n')) { pSkip_ = cnt+2; break; } cnt++; } while (cnt<1024); *dptr = '\0'; string x(buf); istringstream str(x); this->parseNRRD(str); } // check to see if we have a nonzero width, height, and bitpix if (!validParams()) return; // skip to start of data data_ = mapdata_ + pSkip_; dataSize_ = mapsize_; dataSkip_ = pSkip_; // new header head_ = new FitsHead(pWidth_, pHeight_, pDepth_, pBitpix_); if (!head_->isValid()) return; // do we byteswap? setByteSwap(); // made it this far, must be valid valid_ = 1; orgFits_ = 0; } FitsMosaicMap::FitsMosaicMap() { if (!valid_) return; char* here = mapdata_; size_t size = mapsize_; // keep the primary header primary_ = new FitsHead(here, size, FitsHead::EXTERNAL); managePrimary_ = 1; if (!primary_->isValid()) { error(); return; } here += primary_->headbytes() + primary_->databytes(); size -= primary_->headbytes() + primary_->databytes(); // first extension head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; found(here); } FitsMosaicNextMap::FitsMosaicNextMap(FitsFile* p) { FitsMap* prev = (FitsMap*)p; primary_ = prev->primary(); managePrimary_ = 0; ext_ = prev->ext(); mapdata_ = prev->enddata(); mapsize_ = prev->endsize(); head_ = new FitsHead(mapdata_, mapsize_, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; found(mapdata_); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdparser.H�����������������������������������������������������������������0000644�0001750�0001750�00000013547�12047246743�016026� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { EOF_ = 258, INT = 259, REAL = 260, STRING = 261, DEBUG_ = 262, ON_ = 263, OFF_ = 264, NRRD0001_ = 265, NRRD0002_ = 266, NRRD0003_ = 267, NRRD0004_ = 268, NRRD0005_ = 269, DATA_ = 270, FILE_ = 271, SPACE_ = 272, UNITS_ = 273, DIMENSIONS_ = 274, ORIGIN_ = 275, DIRECTIONS_ = 276, DIMENSION_ = 277, TYPE_ = 278, SIGNED_ = 279, UNSIGNED_ = 280, CHAR_ = 281, INT8_ = 282, INT8_T_ = 283, UCHAR_ = 284, UINT8_ = 285, UINT8_T_ = 286, SHORT_ = 287, INT_ = 288, INT16_ = 289, INT16_T_ = 290, USHORT_ = 291, UINT16_ = 292, UINT16_T_ = 293, INT32_ = 294, INT32_T_ = 295, UINT_ = 296, UINT32_ = 297, UINT32_T_ = 298, LONG_ = 299, LONGLONG_ = 300, INT64_ = 301, INT64_T_ = 302, ULONGLONG_ = 303, UINT64_ = 304, UINT64_T_ = 305, FLOAT_ = 306, DOUBLE_ = 307, BLOCK_ = 308, SIZE_ = 309, BLOCKSIZE_ = 310, ENCODING_ = 311, RAW_ = 312, TXT_ = 313, TEXT_ = 314, ASCII_ = 315, HEX_ = 316, GZ_ = 317, GZIP_ = 318, BZ2_ = 319, BZIP2_ = 320, ENDIAN_ = 321, BIG_ = 322, LITTLE_ = 323, CONTENT_ = 324, OLD_ = 325, MIN_ = 326, OLDMIN_ = 327, MAX_ = 328, OLDMAX_ = 329, SKIP_ = 330, LINE_ = 331, LINESKIP_ = 332, BYTE_ = 333, BYTESKIP_ = 334, NUMBER_ = 335, SAMPLE_ = 336, SAMPLEUNITS_ = 337, SIZES_ = 338, SPACINGS_ = 339, THICKNESSES_ = 340, AXIS_ = 341, MINS_ = 342, AXISMINS_ = 343, MAXS_ = 344, AXISMAXS_ = 345, CENTERS_ = 346, CENTERINGS_ = 347, CELL_ = 348, NODE_ = 349, NONE_ = 350, LABELS_ = 351, KINDS_ = 352, DOMAINS_ = 353 }; #endif /* Tokens. */ #define EOF_ 258 #define INT 259 #define REAL 260 #define STRING 261 #define DEBUG_ 262 #define ON_ 263 #define OFF_ 264 #define NRRD0001_ 265 #define NRRD0002_ 266 #define NRRD0003_ 267 #define NRRD0004_ 268 #define NRRD0005_ 269 #define DATA_ 270 #define FILE_ 271 #define SPACE_ 272 #define UNITS_ 273 #define DIMENSIONS_ 274 #define ORIGIN_ 275 #define DIRECTIONS_ 276 #define DIMENSION_ 277 #define TYPE_ 278 #define SIGNED_ 279 #define UNSIGNED_ 280 #define CHAR_ 281 #define INT8_ 282 #define INT8_T_ 283 #define UCHAR_ 284 #define UINT8_ 285 #define UINT8_T_ 286 #define SHORT_ 287 #define INT_ 288 #define INT16_ 289 #define INT16_T_ 290 #define USHORT_ 291 #define UINT16_ 292 #define UINT16_T_ 293 #define INT32_ 294 #define INT32_T_ 295 #define UINT_ 296 #define UINT32_ 297 #define UINT32_T_ 298 #define LONG_ 299 #define LONGLONG_ 300 #define INT64_ 301 #define INT64_T_ 302 #define ULONGLONG_ 303 #define UINT64_ 304 #define UINT64_T_ 305 #define FLOAT_ 306 #define DOUBLE_ 307 #define BLOCK_ 308 #define SIZE_ 309 #define BLOCKSIZE_ 310 #define ENCODING_ 311 #define RAW_ 312 #define TXT_ 313 #define TEXT_ 314 #define ASCII_ 315 #define HEX_ 316 #define GZ_ 317 #define GZIP_ 318 #define BZ2_ 319 #define BZIP2_ 320 #define ENDIAN_ 321 #define BIG_ 322 #define LITTLE_ 323 #define CONTENT_ 324 #define OLD_ 325 #define MIN_ 326 #define OLDMIN_ 327 #define MAX_ 328 #define OLDMAX_ 329 #define SKIP_ 330 #define LINE_ 331 #define LINESKIP_ 332 #define BYTE_ 333 #define BYTESKIP_ 334 #define NUMBER_ 335 #define SAMPLE_ 336 #define SAMPLEUNITS_ 337 #define SIZES_ 338 #define SPACINGS_ 339 #define THICKNESSES_ 340 #define AXIS_ 341 #define MINS_ 342 #define AXISMINS_ 343 #define MAXS_ 344 #define AXISMAXS_ 345 #define CENTERS_ 346 #define CENTERINGS_ 347 #define CELL_ 348 #define NODE_ 349 #define NONE_ 350 #define LABELS_ 351 #define KINDS_ 352 #define DOMAINS_ 353 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "nrrdparser.Y" { #define NRRDPARSERSIZE 256 float real; int integer; char str[NRRDPARSERSIZE]; } /* Line 1529 of yacc.c. */ #line 252 "nrrdparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/column.h���������������������������������������������������������������������0000644�0001750�0001750�00000007257�11700666264�015201� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitscolumn_h__ #define __fitscolumn_h__ #include "vector.h" class FitsHead; class FitsColumn { protected: int index_; // col number 1 to n int width_; // overall width of field in chars int offset_; // offset in chars from start of row char type_; // type char* tform_; char* ttype_; char* tunit_; float tscal_; float tzero_; int tnull_; int hastnull_; float tlmin_; float tlmax_; int hastlmin_; int hastlmax_; double min_; double max_; int validmm_; char buf_[128]; char keybuf[9]; char* keycat(const char*, int); public: FitsColumn(FitsHead*, int, int); virtual ~FitsColumn(); int width() {return width_;} int offset() {return offset_;} int index() {return index_;} const char* tform() {return tform_;} const char* ttype() {return ttype_;} const char* tunit() {return tunit_;} float tscal() {return tscal_;} float tzero() {return tzero_;} int tnull() {return tnull_;} float tlmin() {return tlmin_;} float tlmax() {return tlmax_;} int hasscaling() {return tscal_ != 1 || tzero_ != 0;} int hastnull() {return hastnull_;} virtual double value(const char* ptr, int i =0) {return 0;} virtual char* str(const char* ptr, int i =0) {return NULL;} virtual Vector dimension() {return Vector();} virtual int repeat() {return 1;} void setMin(double m) {min_=m;} void setMax(double m) {max_=m;} double getMin() {return min_;} double getMax() {return max_;} int hasMinMax() {return min_ != -DBL_MAX ? 1 : 0;} int hasTLMinTLMax() {return hastlmin_ && hastlmax_;} }; // FitsAsciiColumn class FitsAsciiColumn : public FitsColumn { public: FitsAsciiColumn(FitsHead*, int, int); char* str(const char* ptr, int i =0); }; class FitsAsciiColumnStr : public FitsAsciiColumn { public: FitsAsciiColumnStr(FitsHead*, int, int); }; class FitsAsciiColumnA : public FitsAsciiColumn { private: int prec_; public: FitsAsciiColumnA(FitsHead*, int, int); double value(const char*, int i =0); }; template<class T> class FitsAsciiColumnT : public FitsAsciiColumnA { public: FitsAsciiColumnT(FitsHead*, int, int); Vector dimension(); }; // FitsBinColumn class FitsBinColumn : public FitsColumn { protected: char* tdisp_; int repeat_; // repeat count public: FitsBinColumn(FitsHead*, int, int); ~FitsBinColumn(); int repeat() {return repeat_;} }; class FitsBinColumnStr : public FitsBinColumn { public: FitsBinColumnStr(FitsHead*, int, int); char* str(const char* ptr, int i =0); }; class FitsBinColumnLogical : public FitsBinColumn { public: FitsBinColumnLogical(FitsHead*, int, int); double value(const char* ptr, int i =0) {return (*(ptr+offset_+i) == 'T') ? 1 : 0;} char* str(const char* ptr, int i =0); }; class FitsBinColumnArray : public FitsBinColumn { private: int byteswap_; char ptype_; int psize_; int pmax_; char* abuf_; int swap(const char* ptr, int i =0); public: FitsBinColumnArray(FitsHead*, int, int); virtual ~FitsBinColumnArray(); void* get(const char* heap, const char* ptr, int* cnt); }; class FitsBinColumnBit : public FitsBinColumn { public: FitsBinColumnBit(FitsHead*, int, int); }; class FitsBinColumnB : public FitsBinColumn { protected: int byteswap_; public: FitsBinColumnB(FitsHead*, int, int); }; template<class T> class FitsBinColumnT : public FitsBinColumnB { private: T swap(T*); public: FitsBinColumnT(FitsHead*, int, int); double value(const char*, int i =0); char* str(const char* ptr, int i =0); Vector dimension(); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/socket.h���������������������������������������������������������������������0000644�0001750�0001750�00000002672�12041601171�015151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitssocket_h__ #define __fitssocket_h__ #include "strm.h" class FitsSocket : public virtual FitsStream<int> { public: FitsSocket(int, const char*); }; class FitsFitsSocket : public FitsSocket, public FitsFitsStream<int> { public: FitsFitsSocket(int s, const char* ext, ScanMode mode, FlushMode flush) : FitsSocket(s, ext), FitsFitsStream<int>(mode, flush) {} }; class FitsFitsNextSocket : public FitsFitsNextStream<int> { public: FitsFitsNextSocket(FitsFile* prev) : FitsFitsNextStream<int>(prev) {} }; class FitsArrSocket : public FitsSocket, public FitsArrStream<int> { public: FitsArrSocket(int s, const char* ext, FlushMode flush) : FitsSocket(s, ext), FitsArrStream<int>(flush) {} }; class FitsNRRDSocket : public FitsSocket, public FitsNRRDStream<int> { public: FitsNRRDSocket(int s, const char* ext, FlushMode flush) : FitsSocket(s, ext), FitsNRRDStream<int>(flush) {} }; class FitsMosaicSocket : public FitsSocket, public FitsMosaicStream<int> { public: FitsMosaicSocket(int s, FlushMode flush) : FitsSocket(s, ""), FitsMosaicStream<int>(flush) {} }; class FitsMosaicNextSocket : public FitsMosaicNextStream<int> { public: FitsMosaicNextSocket(FitsFile* prev, FlushMode flush) : FitsMosaicNextStream<int>(prev, flush) {} }; #endif ����������������������������������������������������������������������./saods9/saotk/fitsy++/allocgz.h��������������������������������������������������������������������0000644�0001750�0001750�00000002461�11700666264�015327� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsallocgz_h__ #define __fitsallocgz_h__ #include "strm.h" #include "zlib.h" class FitsAllocGZ : public virtual FitsStream<gzFile> { public: FitsAllocGZ(const char*); virtual ~FitsAllocGZ() {} }; class FitsFitsAllocGZ : public FitsAllocGZ, public FitsFitsStream<gzFile> { public: FitsFitsAllocGZ(const char* fn, ScanMode mode, FlushMode flush) : FitsAllocGZ(fn), FitsFitsStream<gzFile>(mode, flush) {} }; class FitsFitsNextAllocGZ : public FitsFitsNextStream<gzFile> { public: FitsFitsNextAllocGZ(FitsFile* prev) : FitsFitsNextStream<gzFile>(prev) {} }; class FitsArrAllocGZ : public FitsAllocGZ, FitsArrStream<gzFile> { public: FitsArrAllocGZ(const char* fn, FlushMode flush) : FitsAllocGZ(fn), FitsArrStream<gzFile>(flush) {} }; class FitsMosaicAllocGZ : public FitsAllocGZ, FitsMosaicStream<gzFile> { public: FitsMosaicAllocGZ(const char* fn, FlushMode flush) : FitsAllocGZ(fn), FitsMosaicStream<gzFile>(flush) {} }; class FitsMosaicNextAllocGZ : public FitsMosaicNextStream<gzFile> { public: FitsMosaicNextAllocGZ(FitsFile* prev, FlushMode flush) : FitsMosaicNextStream<gzFile>(prev, flush) {} }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/allocgz.C��������������������������������������������������������������������0000644�0001750�0001750�00000001035�11700666264�015256� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <unistd.h> #include "allocgz.h" FitsAllocGZ::FitsAllocGZ(const char* fn) { parse(fn); // we need the 'b' for windows... if (!strncmp(pName_, "stdin", 5) || !strncmp(pName_, "STDIN", 5) || !strncmp(pName_, "-", 1)) stream_ = gzdopen(dup(STDIN_FILENO), "rb"); else stream_ = gzopen(pName_, "rb"); if (stream_) valid_ = 1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outfits.h��������������������������������������������������������������������0000644�0001750�0001750�00000000777�12075604063�015374� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __outfits_h__ #define __outfits_h__ #include <tcl.h> #include "util.h" #define B4KB 4096 #define B1MB 1048576 class OutFitsStream { protected: int valid_; public: OutFitsStream(); virtual ~OutFitsStream(); virtual int write(char*, size_t) =0; int writeSwap(char*, int, int); int valid() {return valid_;} }; #endif �./saods9/saotk/fitsy++/smap.h�����������������������������������������������������������������������0000644�0001750�0001750�00000001254�11777365670�014646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitssmap_h__ #define __fitssmap_h__ #include "file.h" class FitsSMap : public FitsFile { protected: char* hmapdata_; size_t hmapsize_; char* mapdata_; size_t mapsize_; public: FitsSMap(); virtual ~FitsSMap() {} char* mapdata() {return mapdata_;} size_t mapsize() {return mapsize_;} }; class FitsFitsSMap : public virtual FitsSMap { public: FitsFitsSMap(FitsHead::Memory); }; class FitsFitsNextSMap : public FitsSMap { public: FitsFitsNextSMap(FitsFile* prev); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/var.C������������������������������������������������������������������������0000644�0001750�0001750�00000002023�11700666265�014412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "var.h" FitsVar::FitsVar(Tcl_Interp* interp, const char* var, const char* fn) { parse(fn); obj = Tcl_GetVar2Ex(interp, (char*)var, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (!obj) return; // just in case Tcl_ConvertToType(interp, obj, Tcl_GetObjType("bytearray")); typedef struct ByteArray { int used; /* The number of bytes used in the byte * array. */ int allocated; /* The amount of space actually allocated * minus 1 byte. */ unsigned char bytes[4]; /* The array of bytes. The actual size of * this field depends on the 'allocated' field * above. */ } ByteArray; ByteArray* ba = (ByteArray*)(obj->internalRep.otherValuePtr); mapsize_ = ba->used; mapdata_ = (char*)ba->bytes; Tcl_IncrRefCount(obj); valid_ = 1; } FitsVar::~FitsVar() { if (obj) Tcl_DecrRefCount(obj); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/sshare.C���������������������������������������������������������������������0000644�0001750�0001750�00000005334�11700666265�015117� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifdef HAVE_SYS_SHM_H #include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> #include "sshare.h" FitsSShareID::FitsSShareID(int hdrid, int shmid, const char* filter) { { // find size struct shmid_ds info; if (shmctl(hdrid, IPC_STAT, &info)) { internalError("Fitsy++ sshare shctl failed"); return; } hmapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(hmapdata_ = (char*)shmat(hdrid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ sshare shmat failed"); return; } } { parse(filter); // find size struct shmid_ds info; if (shmctl(shmid, IPC_STAT, &info)) { internalError("Fitsy++ sshare shctl failed"); return; } mapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(mapdata_ = (char*)shmat(shmid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ sshare shmat failed"); return; } } // so far so good valid_ = 1; } FitsSShareID::~FitsSShareID() { shmdt(mapdata_); } FitsSShareKey::FitsSShareKey(int hdr, int key, const char* filter) { { // get shmid int shmid; if ((shmid = shmget(hdr, 0, 0)) < 0) { internalError("Fitsy++ sshare shmget failed"); return; } // find size struct shmid_ds info; if (shmctl(shmid, IPC_STAT, &info)) { internalError("Fitsy++ sshare shctl failed"); return; } mapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(mapdata_ = (char*)shmat(shmid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ sshare shmat failed"); return; } } { parse(filter); // get shmid int shmid; if ((shmid = shmget(key, 0, 0)) < 0) { internalError("Fitsy++ sshare shmget failed"); return; } // find size struct shmid_ds info; if (shmctl(shmid, IPC_STAT, &info)) { internalError("Fitsy++ sshare shmctl failed"); return; } mapsize_ = info.shm_segsz; // Attach the memory segment if ((long)(mapdata_ = (char*)shmat(shmid, 0, SHM_RDONLY)) == -1) { internalError("Fitsy++ sshare shmat failed"); return; } } // so far so good valid_ = 1; } FitsSShareKey::~FitsSShareKey() { shmdt(mapdata_); } #else #include "sshare.h" FitsSShareID::FitsSShareID(int hdrid, int shmid, const char* filter) { // shared memory not supported valid_ = 0; } FitsSShareID::~FitsSShareID() {} FitsSShareKey::FitsSShareKey(int hdr, int key, const char* filter) { // shared memory not supported valid_ = 0; } FitsSShareKey::~FitsSShareKey() {} #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/head.h�����������������������������������������������������������������������0000644�0001750�0001750�00000010747�12102027745�014573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitshead_h__ #define __fitshead_h__ #define FTY_BLOCK 2880 #define FTY_CARDS (FTY_BLOCK/FTY_CARDLEN) #include "card.h" #include "hdu.h" #include "util.h" class FitsHead { public: enum Memory {ALLOC, EXTERNAL, MMAP, SHARE}; private: char* cards_; // pointer to start of cards char* mapdata_; // pointer to start of memory segment size_t mapsize_; // size of memory segment Memory memory_; // type memory mangement int ncard_; // actual number of cards int acard_; // number of cards block filled char** index_; int valid_; int inherit_; FitsHDU* hdu_; private: void buildIndex(); public: FitsHead(char*, size_t, Memory); FitsHead(char*, size_t, char*, size_t, Memory); FitsHead(int width, int height, int depth, int bitpix, char* =NULL); FitsHead(int width, int height, int depth, int bitpix, char*, size_t, Memory); FitsHead(const FitsHead&); ~FitsHead(); char* cards() {return cards_;} int ncard() {return ncard_;} int acard() {return acard_;} FitsHDU* hdu() {return hdu_;} int inherit() {return inherit_;} int isValid() {return valid_;} int isImage(); int isTable(); int isAsciiTable(); int isBinTable(); int isHeap(); int cardblocks() {return ncard_/FTY_CARDS;} int cardbytes() {return ncard_*FTY_CARDLEN;} int headblocks() {return acard_/FTY_CARDS;} int headbytes() {return acard_*FTY_CARDLEN;} const char* extname() {return hdu_ ? hdu_->extname() : NULL;} int extver() {return hdu_ ? hdu_->extver() : 0;} int bitpix() {return hdu_ ? hdu_->bitpix() : 0;} int naxes() {return hdu_ ? hdu_->naxes() : 0;} int naxis(int ii) {return hdu_ ? hdu_->naxis(ii) : 0;} size_t realbytes() {return hdu_ ? hdu_->realbytes() : 0;} size_t heapbytes() {return hdu_ ? hdu_->heapbytes() : 0;} size_t allbytes() {return hdu_ ? hdu_->allbytes() : 0;} size_t padbytes() {return hdu_ ? hdu_->padbytes() : 0;} size_t databytes() {return hdu_ ? hdu_->databytes() : 0;} size_t datablocks() {return hdu_ ? hdu_->datablocks() : 0;} void updateHDU(); void updateCards() {if (hdu_) hdu_->updateCards(this);} char* find(const char* name); char* findSeq(const char* name); char* findIndex(const char* name); char* cardins(char* card, char* here); char* carddel(char* card); char* setLogical(const char* name, int value, const char* comm); char* setInteger(const char* name, int value, const char* comm); char* setReal(const char* name, double value, int prec, const char* comm); char* setComplex(const char* name, double real, double img, int prec, const char* comm); char* setString(const char* name, const char* value, const char* comm); char* setComment(const char* name, const char* value); char* insertLogical(const char* name, int value, const char* comm, const char* here); char* insertInteger(const char* name, int value, const char* comm, const char* here); char* insertReal(const char* name, double value, int prec, const char* comm, const char* here); char* insertComplex(const char* name, double real, double img, int prec, const char* comm, const char* here); char* insertString(const char* name, const char* value, const char* comm, const char* here); char* insertComment(const char* name, const char* value, const char* here); char* appendLogical(const char* name, int value, const char* comm) {return insertLogical(name, value, comm, NULL);} char* appendInteger(const char* name, int value, const char* comm) {return insertInteger(name, value, comm, NULL);} char* appendReal(const char* name, double value, int prec, const char* comm) {return insertReal(name, value, prec, comm, NULL);} char* appendComplex(const char* name, double real, double img, int prec, const char* comm) {return insertComplex(name, real, img, prec, comm, NULL);} char* appendString(const char* name, const char* value, const char* comm) {return insertString(name, value, comm, NULL);} int getLogical(const char* name, int def); int getInteger(const char* name, int def); double getReal(const char* name, double def); void getComplex(const char* name, double* real, double* img, double rdef, double idef); char* getString(const char* name); char* getComment(const char* name); char* getKeyword(const char* name); char* deleteCard(const char* name) {return carddel(find(name));} }; #endif �������������������������./saods9/saotk/fitsy++/lex.C������������������������������������������������������������������������0000644�0001750�0001750�00000146464�12044277032�014424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lex.C" #line 4 "lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer ffFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *ffalloc (yy_size_t ); void *ffrealloc (void *,yy_size_t ); void fffree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 46 #define YY_END_OF_BUFFER 47 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[179] = { 0, 0, 0, 0, 0, 43, 43, 0, 0, 47, 1, 3, 1, 1, 2, 4, 42, 41, 46, 42, 40, 36, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 43, 45, 45, 44, 1, 3, 1, 41, 36, 36, 38, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 43, 44, 37, 38, 38, 7, 9, 38, 13, 14, 38, 38, 38, 38, 20, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 5, 38, 38, 38, 38, 38, 15, 38, 38, 38, 38, 38, 38, 38, 38, 38, 27, 28, 29, 38, 38, 38, 33, 34, 35, 6, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 25, 26, 30, 38, 38, 38, 11, 10, 12, 38, 17, 38, 38, 21, 22, 24, 31, 38, 38, 38, 38, 38, 38, 32, 38, 16, 38, 19, 38, 8, 38, 38, 18, 38, 38, 23, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 5, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 13, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 13, 28, 29, 30, 31, 32, 1, 33, 1, 13, 1, 34, 35, 36, 37, 38, 13, 39, 40, 41, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 13, 53, 54, 55, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[57] = { 0, 1, 2, 3, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } ; static yyconst flex_int16_t yy_base[185] = { 0, 0, 3, 36, 0, 98, 31, 5, 6, 31, 0, 12, 0, 13, 390, 390, 390, 16, 390, 23, 390, 86, 70, 79, 75, 81, 89, 0, 90, 88, 94, 92, 82, 80, 95, 97, 95, 92, 105, 112, 390, 0, 390, 22, 21, 0, 17, 20, 21, 134, 137, 0, 0, 136, 131, 130, 131, 135, 143, 131, 143, 132, 133, 138, 140, 142, 156, 160, 151, 158, 150, 154, 175, 179, 181, 182, 0, 20, 390, 185, 193, 191, 195, 185, 0, 183, 193, 194, 205, 206, 0, 190, 190, 192, 193, 209, 213, 212, 206, 204, 212, 222, 226, 227, 229, 0, 219, 232, 233, 244, 242, 0, 237, 252, 236, 254, 239, 250, 257, 257, 251, 0, 0, 0, 261, 266, 259, 0, 0, 0, 0, 270, 267, 258, 260, 266, 274, 275, 272, 273, 290, 292, 0, 0, 0, 287, 280, 293, 0, 0, 0, 295, 0, 288, 299, 0, 304, 0, 0, 298, 312, 312, 309, 316, 310, 0, 312, 0, 319, 0, 324, 0, 320, 323, 0, 333, 324, 0, 390, 369, 373, 377, 381, 22, 385 } ; static yyconst flex_int16_t yy_def[185] = { 0, 179, 179, 178, 3, 180, 180, 181, 181, 178, 182, 178, 182, 182, 178, 178, 178, 178, 178, 178, 178, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 178, 184, 178, 178, 178, 182, 178, 182, 178, 178, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 178, 178, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 0, 178, 178, 178, 178, 178, 178 } ; static yyconst flex_int16_t yy_nxt[447] = { 0, 178, 11, 12, 13, 11, 12, 13, 18, 18, 43, 43, 44, 44, 46, 46, 46, 47, 48, 46, 48, 46, 46, 48, 47, 48, 51, 77, 77, 77, 49, 178, 14, 15, 18, 14, 15, 16, 17, 18, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 27, 27, 29, 30, 27, 31, 32, 27, 33, 34, 35, 27, 36, 27, 37, 38, 39, 40, 16, 22, 23, 24, 25, 26, 28, 27, 27, 29, 30, 27, 31, 32, 27, 33, 34, 35, 27, 36, 27, 37, 38, 39, 50, 53, 54, 55, 56, 60, 57, 61, 18, 62, 73, 64, 178, 66, 67, 52, 58, 63, 68, 59, 65, 69, 72, 74, 178, 70, 53, 54, 55, 56, 75, 60, 57, 61, 71, 62, 73, 64, 66, 67, 52, 58, 63, 68, 59, 65, 69, 72, 49, 74, 70, 50, 81, 79, 178, 84, 75, 85, 82, 71, 86, 87, 178, 78, 83, 88, 52, 80, 89, 90, 91, 92, 93, 94, 95, 96, 178, 81, 97, 79, 84, 98, 85, 82, 99, 86, 100, 87, 78, 83, 88, 52, 80, 89, 90, 91, 92, 93, 94, 101, 95, 96, 102, 97, 103, 104, 98, 105, 106, 99, 107, 100, 108, 178, 110, 111, 112, 113, 116, 109, 114, 115, 178, 117, 101, 118, 119, 102, 120, 103, 104, 121, 105, 122, 106, 123, 107, 124, 108, 110, 111, 112, 113, 116, 109, 125, 114, 115, 117, 126, 118, 119, 127, 128, 120, 129, 130, 121, 122, 131, 123, 132, 124, 133, 178, 134, 135, 136, 178, 137, 125, 138, 178, 139, 126, 140, 141, 127, 128, 142, 129, 130, 143, 144, 131, 145, 132, 146, 147, 133, 134, 135, 148, 136, 137, 149, 150, 138, 139, 151, 140, 152, 141, 153, 142, 154, 155, 143, 144, 156, 157, 145, 146, 158, 147, 159, 160, 148, 161, 162, 149, 150, 163, 164, 151, 165, 152, 166, 153, 167, 154, 155, 168, 169, 172, 156, 157, 170, 158, 171, 159, 160, 173, 161, 162, 174, 175, 163, 176, 164, 165, 177, 178, 166, 178, 167, 178, 168, 178, 169, 172, 178, 170, 178, 171, 178, 178, 178, 173, 178, 174, 175, 178, 178, 176, 178, 177, 10, 10, 10, 10, 41, 41, 41, 41, 42, 42, 42, 42, 45, 178, 45, 45, 76, 76, 178, 76, 9, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178 } ; static yyconst flex_int16_t yy_chk[447] = { 0, 0, 1, 1, 1, 2, 2, 2, 7, 8, 7, 8, 7, 8, 11, 13, 11, 13, 17, 46, 17, 46, 47, 48, 47, 48, 183, 77, 44, 43, 19, 9, 1, 1, 6, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 21, 22, 23, 24, 25, 28, 26, 29, 5, 30, 37, 31, 0, 32, 33, 21, 26, 30, 34, 26, 31, 35, 36, 38, 0, 35, 22, 23, 24, 25, 39, 28, 26, 29, 35, 30, 37, 31, 32, 33, 21, 26, 30, 34, 26, 31, 35, 36, 49, 38, 35, 50, 54, 53, 0, 55, 39, 56, 54, 35, 57, 58, 0, 49, 54, 59, 50, 53, 60, 61, 62, 63, 64, 65, 66, 67, 0, 54, 68, 53, 55, 69, 56, 54, 70, 57, 71, 58, 49, 54, 59, 50, 53, 60, 61, 62, 63, 64, 65, 72, 66, 67, 73, 68, 74, 75, 69, 79, 80, 70, 81, 71, 82, 0, 83, 85, 86, 87, 91, 82, 88, 89, 0, 92, 72, 93, 94, 73, 95, 74, 75, 96, 79, 97, 80, 98, 81, 99, 82, 83, 85, 86, 87, 91, 82, 100, 88, 89, 92, 101, 93, 94, 102, 103, 95, 104, 106, 96, 97, 107, 98, 108, 99, 109, 0, 110, 112, 113, 0, 114, 100, 115, 0, 116, 101, 117, 118, 102, 103, 119, 104, 106, 120, 124, 107, 125, 108, 126, 131, 109, 110, 112, 132, 113, 114, 133, 134, 115, 116, 135, 117, 136, 118, 137, 119, 138, 139, 120, 124, 140, 141, 125, 126, 145, 131, 146, 147, 132, 151, 153, 133, 134, 154, 156, 135, 159, 136, 160, 137, 161, 138, 139, 162, 163, 168, 140, 141, 164, 145, 166, 146, 147, 170, 151, 153, 172, 173, 154, 175, 156, 159, 176, 0, 160, 0, 161, 0, 162, 0, 163, 168, 0, 164, 0, 166, 0, 0, 0, 170, 0, 172, 173, 0, 0, 175, 0, 176, 179, 179, 179, 179, 180, 180, 180, 180, 181, 181, 181, 181, 182, 0, 182, 182, 184, 184, 0, 184, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 11 "lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "parser.H" extern YYSTYPE* fflval; extern ffFlexLexer* fflexx; extern char ff_filter[]; #define RET(x) {strcat(ff_filter,yytext);return x;} #define CLEARFILTER {ff_filter[0]='\0';} /* rules */ #line 586 "lex.C" #define INITIAL 0 #define EXT 1 #define FILTER 2 #define ARRAY 3 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 32 "lex.L" #line 692 "lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 179 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 178 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 34 "lex.L" { // File strcpy(fflval->str,yytext); return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 39 "lex.L" { // first bracket BEGIN EXT; CLEARFILTER return yytext[0]; } YY_BREAK case 3: YY_RULE_SETUP #line 45 "lex.L" { // White Spaces } YY_BREAK case 4: YY_RULE_SETUP #line 48 "lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 5: YY_RULE_SETUP #line 54 "lex.L" {RET(ARCH_)} YY_BREAK case 6: YY_RULE_SETUP #line 55 "lex.L" {RET(ARRAY_)} YY_BREAK case 7: YY_RULE_SETUP #line 56 "lex.L" {RET(BIG_)} YY_BREAK case 8: YY_RULE_SETUP #line 57 "lex.L" {RET(BIGENDIAN_)} YY_BREAK case 9: YY_RULE_SETUP #line 58 "lex.L" {RET(BIN_)} YY_BREAK case 10: YY_RULE_SETUP #line 59 "lex.L" {RET(BINKEY_)} YY_BREAK case 11: YY_RULE_SETUP #line 60 "lex.L" {RET(BINCOL_)} YY_BREAK case 12: YY_RULE_SETUP #line 61 "lex.L" {RET(BITPIX_)} YY_BREAK case 13: YY_RULE_SETUP #line 62 "lex.L" {RET(COL_)} YY_BREAK case 14: YY_RULE_SETUP #line 63 "lex.L" {RET(DIM_)} YY_BREAK case 15: YY_RULE_SETUP #line 64 "lex.L" {RET(DIMS_)} YY_BREAK case 16: YY_RULE_SETUP #line 65 "lex.L" {RET(ECLIPTIC_)} YY_BREAK case 17: YY_RULE_SETUP #line 66 "lex.L" {RET(ENDIAN_)} YY_BREAK case 18: YY_RULE_SETUP #line 67 "lex.L" {RET(EQUATORIAL_)} YY_BREAK case 19: YY_RULE_SETUP #line 68 "lex.L" {RET(GALACTIC_)} YY_BREAK case 20: YY_RULE_SETUP #line 69 "lex.L" {RET(KEY_)} YY_BREAK case 21: YY_RULE_SETUP #line 70 "lex.L" {RET(LAYOUT_)} YY_BREAK case 22: YY_RULE_SETUP #line 71 "lex.L" {RET(LITTLE_)} YY_BREAK case 23: YY_RULE_SETUP #line 72 "lex.L" {RET(LITTLEENDIAN_)} YY_BREAK case 24: YY_RULE_SETUP #line 73 "lex.L" {RET(NESTED_)} YY_BREAK case 25: YY_RULE_SETUP #line 74 "lex.L" {RET(NORTH_)} YY_BREAK case 26: YY_RULE_SETUP #line 75 "lex.L" {RET(ORDER_)} YY_BREAK case 27: YY_RULE_SETUP #line 76 "lex.L" {RET(QUAD_)} YY_BREAK case 28: YY_RULE_SETUP #line 77 "lex.L" {RET(RING_)} YY_BREAK case 29: YY_RULE_SETUP #line 78 "lex.L" {RET(SKIP_)} YY_BREAK case 30: YY_RULE_SETUP #line 79 "lex.L" {RET(SOUTH_)} YY_BREAK case 31: YY_RULE_SETUP #line 80 "lex.L" {RET(SYSTEM_)} YY_BREAK case 32: YY_RULE_SETUP #line 81 "lex.L" {RET(UNKNOWN_)} YY_BREAK case 33: YY_RULE_SETUP #line 82 "lex.L" {RET(XDIM_)} YY_BREAK case 34: YY_RULE_SETUP #line 83 "lex.L" {RET(YDIM_)} YY_BREAK case 35: YY_RULE_SETUP #line 84 "lex.L" {RET(ZDIM_)} YY_BREAK case 36: YY_RULE_SETUP #line 86 "lex.L" { // Integer fflval->integer = atoi(yytext); RET(INT) } YY_BREAK case 37: YY_RULE_SETUP #line 91 "lex.L" { // Integer with PHYSICAL fflval->integer = atoi(yytext); RET(INTP) } YY_BREAK case 38: YY_RULE_SETUP #line 96 "lex.L" { // Extn/Col Name strcpy(fflval->str,yytext); RET(STRING) } YY_BREAK case 39: YY_RULE_SETUP #line 101 "lex.L" { // bracket CLEARFILTER return yytext[0]; } YY_BREAK case 40: YY_RULE_SETUP #line 106 "lex.L" { // comma CLEARFILTER return yytext[0]; } YY_BREAK case 41: YY_RULE_SETUP #line 111 "lex.L" { // White Spaces strcat(ff_filter,yytext); } YY_BREAK case 42: YY_RULE_SETUP #line 115 "lex.L" { // Else, return the char strcat(ff_filter,yytext); return yytext[0]; } YY_BREAK case 43: YY_RULE_SETUP #line 122 "lex.L" { // rest of Filter strcpy(fflval->str,yytext); fflval->str[yyleng-1] = '\0'; // Remove the ']' strcat(ff_filter,fflval->str); return STRING; } YY_BREAK case 44: YY_RULE_SETUP #line 131 "lex.L" { // Integer fflval->integer = atoi(yytext); return INT; } YY_BREAK case 45: YY_RULE_SETUP #line 136 "lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 46: YY_RULE_SETUP #line 142 "lex.L" ECHO; YY_BREAK #line 1046 "lex.C" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(EXT): case YY_STATE_EOF(FILTER): case YY_STATE_EOF(ARRAY): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; fffree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); fffree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ffrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ffrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 179 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 179 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 178); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) ffalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) ffalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) fffree((void *) b->yy_ch_buf ); fffree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)ffalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)ffrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) ffalloc(new_size ); else (yy_start_stack) = (int *) ffrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *ffalloc (yy_size_t size ) { return (void *) malloc( size ); } void *ffrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void fffree (void * ptr ) { free( (char *) ptr ); /* see ffrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 142 "lex.L" void ffFilter(int doit) { if (fflexx) fflexx->begin(FILTER, doit); } void ffArray(int doit) { if (fflexx) fflexx->begin(ARRAY, doit); } void ffFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/mmap.h�����������������������������������������������������������������������0000644�0001750�0001750�00000002216�12041601171�014605� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitsmmap_h__ #define __fitsmmap_h__ #include "map.h" class FitsMMap : public virtual FitsMap { public: FitsMMap(const char*); virtual ~FitsMMap(); }; class FitsFitsMMap : public FitsMMap, public FitsFitsMap { public: FitsFitsMMap(const char* fn, ScanMode mode) : FitsMMap(fn), FitsFitsMap(mode) {} }; class FitsFitsNextMMap : public FitsFitsNextMap { public: FitsFitsNextMMap(FitsFile* prev) : FitsFitsNextMap(prev) {} }; class FitsArrMMap : public FitsMMap, public FitsArrMap { public: FitsArrMMap(const char* fn) : FitsMMap(fn), FitsArrMap() {} }; class FitsNRRDMMap : public FitsMMap, public FitsNRRDMap { public: FitsNRRDMMap(const char* fn) : FitsMMap(fn), FitsNRRDMap() {} }; class FitsMosaicMMap : public FitsMMap, public FitsMosaicMap { public: FitsMosaicMMap(const char* fn) : FitsMMap(fn), FitsMosaicMap() {} }; class FitsMosaicNextMMap : public FitsMosaicNextMap { public: FitsMosaicNextMMap(FitsFile* prev) : FitsMosaicNextMap(prev) {} }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/file.C�����������������������������������������������������������������������0000644�0001750�0001750�00000020571�12102520404�014526� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "file.h" // extention parser #undef yyFlexLexer #define yyFlexLexer ffFlexLexer #include <FlexLexer.h> void* fflval; ffFlexLexer* fflexx; extern int ffparse(FitsFile*, ffFlexLexer*); int fflex(void* vval, ffFlexLexer* ll) { fflval = vval; fflexx = ll; return ll ? ll->yylex() : 0; } void fferror(FitsFile* ff, ffFlexLexer* ll, const char* m) { // ff->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { // ff->error(": "); // ff->error(cmd); } } // nrrd parser #undef yyFlexLexer #define yyFlexLexer nrrdFlexLexer #include <FlexLexer.h> void* nrrdlval; nrrdFlexLexer* nrrdlexx; extern int nrrdparse(FitsFile*, nrrdFlexLexer*); int nrrdlex(void* vval, nrrdFlexLexer* ll) { nrrdlval = vval; nrrdlexx = ll; return ll ? ll->yylex() : 0; } void nrrderror(FitsFile* nrrd, nrrdFlexLexer* ll, const char* m) { // nrrd->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { // nrrd->error(": "); // nrrd->error(cmd); } } FitsFile::FitsFile() { primary_ = NULL; managePrimary_ = 0; head_ = NULL; manageHead_ = 1; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; ext_ = 0; inherit_ = 0; byteswap_ = lsb(); orgFits_ = 1; valid_ = 0; pName_ = NULL; pExt_ = NULL; pIndex_ = -1; pFilter_ = NULL; pBinX_ = NULL; pBinY_ = NULL; pBinZ_ = NULL; pWidth_ = 0; pHeight_ = 0; pDepth_ = 1; pBitpix_ = 0; pSkip_ = 0; pArch_ = NATIVE; pNRRDEncoding_ = RAW; pNRRDDimension_ = 0; pHPXOrder_ =-1; pHPXSystem_ =-1; pHPXLayout_ =-1; pHPXColumn_ =-1; pHPXQuad_ =-1; coord_ =0; xvalid_ =0; xmin_ =0; xmax_ =0; yvalid_ =0; ymin_ =0; ymax_ =0; zvalid_ =0; zmin_ =0; zmax_ =0; } FitsFile::~FitsFile() { if (manageHead_ && head_) delete head_; if (managePrimary_ && primary_) delete primary_; if (pName_) delete [] pName_; if (pExt_) delete [] pExt_; if (pFilter_) delete [] pFilter_; if (pBinX_) delete [] pBinX_; if (pBinY_) delete [] pBinY_; if (pBinZ_) delete [] pBinZ_; } void FitsFile::parse(const char* fn) { if (fn) { string x(fn); istringstream str(x); ffFlexLexer* ll = new ffFlexLexer(&str); ffparse(this, ll); delete ll; } if (!pBinX_ && !pBinY_) { char *env; if ((env = getenv("DS9_BINKEY"))) { string x(env); istringstream str(x); ffFlexLexer* ll = new ffFlexLexer(&str); ffparse(this, ll); delete ll; } } if (!pWidth_ && !pHeight_ && !pBitpix_) { char *env; if ((env = getenv("DS9_ARRAY"))) { string x(env); istringstream str(x); ffFlexLexer* ll = new ffFlexLexer(&str); ffparse(this, ll); delete ll; } } } void FitsFile::error(const char* m) { // do nothing for now cerr << m << endl; } int FitsFile::findEnd(const char* blk) { for (int j=0; j<FTY_BLOCK; j+=FTY_CARDLEN) // only check for 4 chars if (!strncmp("END ", blk+j,4)) return 1; return 0; } void FitsFile::setpName(const char* n) { if (pName_) delete [] pName_; pName_ = dupstr(n); } void FitsFile::setpExt(const char* n) { if (pExt_) delete [] pExt_; pExt_ = dupstr(n); } void FitsFile::setpBinX(const char* x) { if (pBinX_) delete [] pBinX_; pBinX_ = dupstr(x); } void FitsFile::setpBinY(const char* y) { if (pBinY_) delete [] pBinY_; pBinY_ = dupstr(y); } void FitsFile::setpBinZ(const char* z) { if (pBinZ_) delete [] pBinZ_; pBinZ_ = dupstr(z); } void FitsFile::setpFilter(const char* filt) { if (pFilter_) delete [] pFilter_; pFilter_ = dupstr(filt); } Vector FitsFile::getColMinMax(const char* name) { if (isBinTable()) { FitsTableHDU* hdu = (FitsTableHDU*)(head()->hdu()); FitsColumn* col = hdu->find(name); if (col) { if (!col->hasMinMax()) { double zmin = DBL_MAX; double zmax = -DBL_MIN; int rowlen = hdu->width(); int numrow = hdu->rows(); char* ptr = (char*)data(); for (int i=0; i<numrow; i++, ptr+=rowlen) { // for memory models that support internal paging ptr = page(ptr, rowlen); register double z = col->value(ptr); if (z < zmin) zmin = z; if (z > zmax) zmax = z; } // for memory models that support internal paging resetpage(); col->setMin(zmin); col->setMax(zmax); return Vector(zmin,zmax); } else return Vector(col->getMin(), col->getMax()); } } return Vector(); } void FitsFile::setColMinMax(const char* name, const Vector& lim) { if (isBinTable()) { FitsTableHDU* hdu = (FitsTableHDU*)(head()->hdu()); FitsColumn* col = hdu->find(name); if (col) { Vector ll=lim; col->setMin(ll[0]); col->setMax(ll[1]); } } } Vector FitsFile::getColDim(const char* name) { if (isBinTable()) { FitsTableHDU* hdu = (FitsTableHDU*)(head()->hdu()); FitsColumn* col = hdu->find(name); if (col) { if (col->hasTLMinTLMax()) { Vector lim = col->dimension(); col->setMin(lim[0]); col->setMax(lim[1]); return lim; } else return getColMinMax(name); } } else return Vector(); } int FitsFile::validParams() { if (!pWidth_ || !pHeight_ || !pBitpix_) return 0; // check for valid bitpix switch (pBitpix_) { case 8: case 16: case -16: case 32: case 64: case -32: case -64: break; default: return 0; } return 1; } void FitsFile::setByteSwap() { switch (pArch_) { case NATIVE: byteswap_ = 0; break; case BIG: byteswap_ = lsb(); break; case LITTLE: byteswap_ = !lsb(); break; } } void FitsFile::parseNRRD(istream& str) { nrrdFlexLexer* ll = new nrrdFlexLexer(&str); nrrdparse(this, ll); delete ll; } int FitsFile::find(const char* name, FitsHead* alt) { if (alt) return alt->find(name) ? 1 : 0; if (head_) if (head_->find(name)) return 1; else if (primary_ && inherit_) if (primary_->find(name)) return 1; return 0; } int FitsFile::getLogical(const char* name, int def, FitsHead* alt) { if (alt) return alt->getLogical(name,def); if (head_) { int r = head_->getLogical(name,def); if (r != def) return r; else if (primary_ && inherit_) return primary_->getLogical(name,def); } return def; } int FitsFile::getInteger(const char* name, int def, FitsHead* alt) { if (alt) return alt->getInteger(name,def); if (head_) { int r = head_->getInteger(name,def); if (r != def) return r; else if (primary_ && inherit_) return primary_->getInteger(name,def); } return def; } double FitsFile::getReal(const char* name, double def, FitsHead* alt) { if (alt) return alt->getReal(name,def); if (head_) { double r = head_->getReal(name,def); if (r != def) return r; else if (primary_ && inherit_) return primary_->getReal(name,def); } return def; } void FitsFile::getComplex(const char* name, double* real, double* img, double rdef, double idef, FitsHead* alt) { if (alt) { alt->getComplex(name, real, img, rdef, idef); return; } if (head_) { head_->getComplex(name, real, img, rdef, idef); if (*real != rdef || *img != idef) return; else if (primary_ && inherit_) { primary_->getComplex(name, real, img, rdef, idef); return; } } *real = rdef; *img = idef; } char* FitsFile::getString(const char* name, FitsHead* alt) { if (alt) return alt->getString(name); if (head_) { char* r = head_->getString(name); if (r) return r; else if (primary_ && inherit_) return primary_->getString(name); } return NULL; } char* FitsFile::getComment(const char* name, FitsHead* alt) { if (alt) return alt->getComment(name); if (head_) { char* r = head_->getComment(name); if (r) return r; else if (primary_ && inherit_) return primary_->getComment(name); } return NULL; } char* FitsFile::getKeyword(const char* name, FitsHead* alt) { if (alt) return alt->getKeyword(name); if (head_) { char* r = head_->getKeyword(name); if (r) return r; else if (primary_ && inherit_) return primary_->getKeyword(name); } return NULL; } ���������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/card.h�����������������������������������������������������������������������0000644�0001750�0001750�00000003570�12102520404�014565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitscard_h__ #define __fitscard_h__ #define FTY_CARDLEN 80 #include <string.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; class FitsCard { private: char* card_; int managed; public: FitsCard(); FitsCard(char*); FitsCard(const FitsCard&); ~FitsCard(); FitsCard& operator=(const FitsCard&); char* card() {return card_;} FitsCard& clear(); FitsCard& setKey(const char *name); FitsCard& setLogical(const char* name, int value, const char* comment); FitsCard& setLogical(int value, const char *comment) {return setLogical(NULL, value, comment);} FitsCard& setInteger(const char* name, int value, const char *comment); FitsCard& setInteger(int value, const char *comment) {return setInteger(NULL, value, comment);} FitsCard& setReal(const char* name, double value, int prec, const char *comment); FitsCard& setReal(double value, int prec, const char *comment) {return setReal(NULL, value, prec, comment);} FitsCard& setComplex(const char* name, double real, double img, int prec, const char *comment); FitsCard& setComplex(double real, double img, int prec, const char *comment) {return setComplex(NULL, real, img, prec, comment);} FitsCard& setString(const char* name, const char *value, const char *comm); FitsCard& setString(const char *value, const char *comment) {return setString(NULL, value, comment);} FitsCard& setComment(const char* name, const char* value); FitsCard& setComment(const char *value) {return setComment(NULL, value);} int getLogical(); int getInteger(); double getReal(); void getComplex(double*, double*); char* getString(); char* getComment(); char* getAsString(); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/nrrdgzip.C�������������������������������������������������������������������0000644�0001750�0001750�00000004271�12044247745�015470� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "nrrdgzip.h" #include "zlib.h" #include "util.h" template<class T> FitsNRRDGzipm<T>::FitsNRRDGzipm(FitsFile* fits) : FitsNRRDm<T>(fits) { FitsNRRDm<T>::uncompress(fits); } template <class T> int FitsNRRDGzipm<T>::compressed(T* dest, char* src, size_t sz) { z_stream zstrm; zstrm.zalloc = NULL; zstrm.zfree = NULL; zstrm.opaque = NULL; zstrm.avail_in = sz; zstrm.next_in = (Bytef*)src; zstrm.avail_out = this->size_*sizeof(T); zstrm.next_out = (Bytef*)dest; // look for both zlib and gzip headers if (inflateInit2(&zstrm, MAX_WBITS+32) != Z_OK) { internalError("Fitsy++ gzip inflateInit error"); return 0; } if (DebugCompress) cerr << " inflate START: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; int result = ::inflate(&zstrm, Z_FINISH); switch (result) { case Z_OK: if (DebugCompress) cerr << " inflate OK: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_STREAM_END: if (DebugCompress) cerr << " inflate STREAM_END: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_BUF_ERROR: if (DebugCompress) cerr << " inflate BUF_ERROR: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << endl; return 0; default: internalError("Fitsy++ gzip inflate error"); return 0; } inflateEnd(&zstrm); return 1; } template class FitsNRRDGzipm<unsigned char>; template class FitsNRRDGzipm<short>; template class FitsNRRDGzipm<unsigned short>; template class FitsNRRDGzipm<int>; template class FitsNRRDGzipm<long long>; template class FitsNRRDGzipm<float>; template class FitsNRRDGzipm<double>; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/hdu.h������������������������������������������������������������������������0000644�0001750�0001750�00000005057�12075344647�014464� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fitshdu_h__ #define __fitshdu_h__ #include <stdlib.h> #include "column.h" #define FTY_MAXAXES 10 class FitsHead; class FitsHDU { protected: char* extname_; // EXTNAME keyword int extver_; // EXTVER keyword int bitpix_; // BITPIX keyword int naxes_; // NAXIS keyword int naxis_[FTY_MAXAXES]; // NAXIS[i] keywords size_t realbytes_; // Number of real bytes size_t heapbytes_; // Number of heap bytes size_t allbytes_; // Number of real bytes + heap bytes size_t padbytes_; // Number of pad bytes size_t databytes_; // Number of total bytes (padded) size_t datablocks_; // Number of total blocks char keybuf[9]; char* keycat(const char*, int); public: FitsHDU(FitsHead*); virtual ~FitsHDU(); virtual void updateCards(FitsHead*); const char* extname() {return extname_;} int extver() {return extver_;} int bitpix() {return bitpix_;} int naxes() {return naxes_;} int naxis(int ii) {return ii<naxes_ ? naxis_[ii] : 0;} size_t realbytes() {return realbytes_;} size_t heapbytes() {return heapbytes_;} size_t allbytes() {return allbytes_;} size_t padbytes() {return padbytes_;} size_t databytes() {return databytes_;} size_t datablocks() {return datablocks_;} }; class FitsImageHDU : public FitsHDU { private: size_t imgbytes_; // number of image bytes double bscale_; double bzero_; int hasblank_; int blank_; public: FitsImageHDU(FitsHead*); void updateCards(FitsHead*); size_t imgbytes() {return imgbytes_;} void setScaling(double t,double z) {bscale_=t; bzero_=z;} double bscale() {return bscale_;} double bzero() {return bzero_;} int hasscaling() {return bscale_ != 1 || bzero_ != 0;} int hasblank() {return hasblank_;} int blank() {return blank_;} }; class FitsTableHDU : public FitsHDU { protected: int tfields_; FitsColumn** cols_; public: FitsTableHDU(FitsHead*); virtual ~FitsTableHDU(); int tfields() {return tfields_;} int rows() {return naxis_[1];} int cols() {return tfields_;} int width() {return naxis_[0];} char* list(); FitsColumn* find(const char*); FitsColumn* find(int); Vector dimension(const char*); }; class FitsBinTableHDU : public FitsTableHDU { public: FitsBinTableHDU(FitsHead*); }; class FitsAsciiTableHDU : public FitsTableHDU { public: FitsAsciiTableHDU(FitsHead*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/gzraw.C����������������������������������������������������������������������0000644�0001750�0001750�00000006530�12106552151�014750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "gzraw.h" #include "zlib.h" #include "util.h" template<class T> FitsGzrawm<T>::FitsGzrawm(FitsFile* fits) : FitsCompressm<T>(fits) { FitsCompressm<T>::uncompress(fits); } template <class T> int FitsGzrawm<T>::compressed(T* dest, char* sptr, char* heap, int kkstart, int kkstop, int jjstart, int jjstop, int iistart, int iistop) { int icnt=0; unsigned char* ibuf = (unsigned char*)((FitsBinColumnArray*)FitsCompressm<T>::compress_)->get(heap, sptr, &icnt); // ibuf can be NULL if (ibuf && icnt>0) { int ocnt = FitsCompressm<T>::ww_ * FitsCompressm<T>::hh_ * FitsCompressm<T>::dd_; char obuf[ocnt*sizeof(T)]; z_stream zstrm; zstrm.next_in = NULL; zstrm.avail_in = 0; zstrm.zalloc = NULL; zstrm.zfree = NULL; zstrm.opaque = NULL; // look for both zlib and gzraw headers if (inflateInit2(&zstrm, MAX_WBITS+32) != Z_OK) { internalError("Fitsy++ gzraw inflateInit error"); return 0; } zstrm.avail_in = icnt; zstrm.next_in = ibuf; zstrm.avail_out = ocnt*sizeof(T); zstrm.next_out = (Bytef*)obuf; if (DebugCompress) cerr << " inflate START: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; int result = ::inflate(&zstrm, Z_FINISH); switch (result) { case Z_OK: if (DebugCompress) cerr << " inflate OK: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_STREAM_END: if (DebugCompress) cerr << " inflate STREAM_END: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << " total_in " << zstrm.total_in << " total_out " << zstrm.total_out << endl; break; case Z_BUF_ERROR: if (DebugCompress) cerr << " inflate BUF_ERROR: avail_in " << zstrm.avail_in << " avail_out " << zstrm.avail_out << endl; return 0; default: internalError("Fitsy++ gzraw inflate error"); return 0; } inflateEnd(&zstrm); int ll=0; for (int kk=kkstart; kk<kkstop; kk++) { for (int jj=jjstart; jj<jjstop; jj++) { for (int ii=iistart; ii<iistop; ii++,ll++) { // swap if needed if (FitsCompressm<T>::byteswap_) *((T*)obuf+ll) = swap((T*)obuf+ll); dest[kk*FitsCompressm<T>::width_*FitsCompressm<T>::height_ + jj*FitsCompressm<T>::width_ + ii] = *((T*)obuf+ll); } } } } return 1; } template class FitsGzrawm<float>; template class FitsGzrawm<double>; template <> float FitsGzrawm<float>::swap(float* ptr) { const char* p = (const char*)ptr; union { char c[4]; float f; } u; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.f; } template <> double FitsGzrawm<double>::swap(double* ptr) { const char* p = (const char*)ptr; union { char c[8]; double d; } u; u.c[7] = *p++; u.c[6] = *p++; u.c[5] = *p++; u.c[4] = *p++; u.c[3] = *p++; u.c[2] = *p++; u.c[1] = *p++; u.c[0] = *p; return u.d; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outfile.C��������������������������������������������������������������������0000644�0001750�0001750�00000002020�12075604063�015260� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "outfile.h" OutFitsFile::OutFitsFile(const char* fn) { if (fd_ = fopen(fn, "wb")) valid_ = 1; } OutFitsFile::~OutFitsFile() { if (fd_) fclose(fd_); } int OutFitsFile::write(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = fwrite(where+rr, 1, (ss>B1MB) ? B1MB : ss, fd_); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } OutFitsFileGZ::OutFitsFileGZ(const char* fn) { if (fd_ = gzopen(fn, "wb")) valid_ = 1; } OutFitsFileGZ::~OutFitsFileGZ() { if (fd_) gzclose(fd_); } int OutFitsFileGZ::write(char* where, size_t size) { // size_t size is unsigned long long ss =size; size_t rr = 0; int r = 0; do { r = gzwrite(fd_, where+rr, (ss>B1MB) ? B1MB : ss); ss -= r; rr += r; } while (r>0 && rr<size); return rr; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/fitsy++/outfits.C��������������������������������������������������������������������0000644�0001750�0001750�00000001773�12075605607�015331� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "outfits.h" #include "util.h" OutFitsStream::OutFitsStream() { valid_ = 0; } OutFitsStream::~OutFitsStream() { } int OutFitsStream::writeSwap(char* where, int size, int bitpix) { char* buf = new char[B4KB]; // size_t size is unsigned long long ss = size; size_t rr =0; int r; do { r = (ss>B4KB) ? B4KB : ss; switch (bitpix) { case 8: memcpy(buf, where+rr, r); break; case 16: case -16: for (int ii=0; ii<r; ii+=2) swap2(where+rr+ii,buf+ii); break; case 32: case -32: for (int ii=0; ii<r; ii+=4) swap4(where+rr+ii,buf+ii); break; case 64: case -64: for (int ii=0; ii<r; ii+=8) swap8(where+rr+ii,buf+ii); break; } write(buf,r); ss -= r; rr += r; } while (r>0 && rr<size); if (buf) delete [] buf; return rr; } �����./saods9/saotk/util/��������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013166� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/Makefile������������������������������������������������������������������������0000644�0001750�0001750�00000001363�11702635275�014654� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include include ../../make.pkgs CXXFLAGS = $(CXXOPT) -w \ -I. -I.. -I../widget -I../vector -I../frame -I../fitsy++ -I../list \ -I../../include -I$(X11INCLUDE) \ -I../../$(FUNTOOLSDIR)/util \ -I../../$(ASTDIR) SRC = attribute.C \ grf.C \ grf3d.C \ gridbase.C \ grid2dbase.C \ grid25dbase.C \ grid3dbase.C \ ps.C \ smooth.C \ saotk.C \ util.C INCLS = smooth.h \ util.h OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grid25dbase.C�������������������������������������������������������������������0000644�0001750�0001750�00000007363�12046547424�015421� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid25dbase.h" #include "attribute.h" #include "widget.h" #include "frame3dbase.h" extern "C" { #include "ast.h" #include "grf.h" } Grid25dBase* astGrid25dPtr = NULL; Grid25dBase::Grid25dBase(Widget* p) : GridBase(p) {} Grid25dBase::Grid25dBase(Widget* p, const char* o) : GridBase(p,o) {} Grid25dBase::~Grid25dBase() {} int Grid25dBase::gLine(int n, float* x, float* y) { Frame3dBase* pp = (Frame3dBase*)parent_; float xx[n]; float yy[n]; for (int ii=0; ii<n; ii++) { Vector vv = pp->mapFromRef(Vector(x[ii],y[ii]),Coord::WIDGET); xx[ii] = vv[0]; yy[ii] = vv[1]; } switch (renderMode_) { case X11: x11Line(n,xx,yy); break; case PS: psLine(n,xx,yy); break; #ifdef _MACOSX case MACOSX: macosxLine(n,xx,yy); break; #endif #ifdef _WIN32 case GWIN32: win32Line(n,xx,yy); break; #endif } return 1; } int Grid25dBase::gQch(float* chv, float* chh) { Tk_Font font =NULL; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } if (font) { Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); *chv = (float)metrics.linespace; *chh = (float)metrics.linespace; return 1; } else { *chv = *chh = 0; return 0; } } int Grid25dBase::gText(const char* txt, float x, float y, const char* just, float upx, float upy) { if (!(txt && txt[0] && just && just[0] && just[1])) return 0; Frame3dBase* pp = (Frame3dBase*)parent_; Vector vv = pp->mapFromRef(Vector(x,y),Coord::WIDGET); switch (renderMode_) { case X11: return x11Text(txt,vv[0],vv[1],just,Vector(0,1)); case PS: return psText(txt,vv[0],vv[1],just,Vector(0,1)); #ifdef _MACOSX case MACOSX: return macosxText(txt,vv[0],vv[1],just,Vector(0,1)); #endif #ifdef _WIN32 case GWIN32: return win32Text(txt,vv[0],vv[1],just,Vector(0,1)); #endif } return 0; } int Grid25dBase::gTxExt(const char* txt, float x, float y, const char* just, float upx, float upy, float* xb, float* yb) { if (!(txt && txt[0] && just)) { xb[0] = xb[1] = xb[2] = xb[3] = 0; yb[0] = yb[1] = yb[2] = yb[3] = 0; return 0; } Tk_Font font; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } Frame3dBase* pp = (Frame3dBase*)parent_; Vector vv = pp->mapFromRef(Vector(x,y),Coord::WIDGET); double angle = 0; Vector cc = vv * calcTextPos(vv, angle, txt, just, Vector(0, 1), font); Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int width = Tk_TextWidth(font, txt, strlen(txt)); BBox nn = BBox(Vector(0,-metrics.descent), Vector(width,metrics.ascent)); BBox bb = nn * Rotate(angle) * Translate(cc); xb[0] = bb.ll[0]; yb[0] = bb.ll[1]; xb[1] = bb.ur[0]; yb[1] = bb.ll[1]; xb[2] = bb.ur[0]; yb[2] = bb.ur[1]; xb[3] = bb.ll[0]; yb[3] = bb.ur[1]; return 1; } int Grid25dBase::gScales(float* alpha, float* beta) { /* *alpha = float(DisplayWidthMM(parent_->getDisplay(),parent_->screenNumber)) / float(DisplayWidth(parent_->getDisplay(),parent_->screenNumber)); *beta = float(DisplayHeightMM(parent_->getDisplay(),parent_->screenNumber)) / float(DisplayHeight(parent_->getDisplay(),parent_->screenNumber)); */ return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grf.C���������������������������������������������������������������������������0000644�0001750�0001750�00000052124�11702635275�014077� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������extern "C" { #include "grf.h" } #include "grid2dbase.h" #include "grid25dbase.h" extern Grid2dBase* astGrid2dPtr; extern Grid25dBase* astGrid25dPtr; /* * Name: * astGFlush * * Purpose: * Flush all pending graphics to the output device * * Synopsis: * #include "grf.h" * int astGFlush( void ) * * Description: * This function ensures that the display device is up-to-date, * by flushing any pending graphics to the output device. * * Parameters: * None * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise */ int astGFlush(void) { if (astGrid2dPtr) return astGrid2dPtr->gFlush(); else if (astGrid25dPtr) return astGrid25dPtr->gFlush(); } /* * Name: * astGLine * * Purpose: * Draw a polyline (i.e. a set of connected lines) * * Synopsis: * #include "grf.h" * int astGLine( int n, const float *x, const float *y ) * * Description: * This function displays lines joining the given positions * * Parameters: * n * The number of positions to be joined together * x * A pointer to an array holding the "n" x values * y * A pointer to an array holding the "n" y values * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise * * Notes: * - Nothing is done if "n" is less than 2, or if a NULL pointer is * given for either "x" or "y" */ int astGLine(int n, const float *x, const float *y) { if (astGrid2dPtr) return astGrid2dPtr->gLine(n, (float*)x, (float*)y); else if (astGrid25dPtr) return astGrid25dPtr->gLine(n, (float*)x, (float*)y); } /* * Name: * astGQch * * Purpose: * Return the character height in world cooridnates * * Synopsis: * #include "grf.h" * int astGQch( float *chv, float *chh ) * * Description: * This function returns the heights of characters drawn vertically and * horizontally in world coordinates * * Parameters: * chv * A pointer to the double which is to receive the height of * characters drawn vertically. This will be an increment in the X * axis * chh * A pointer to the double which is to receive the height of * characters drawn vertically. This will be an increment in the Y * axis * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise */ int astGQch(float *chv, float *chh) { if (astGrid2dPtr) return astGrid2dPtr->gQch(chv, chh); else if (astGrid25dPtr) return astGrid25dPtr->gQch(chv, chh); } /* * Name: * astGMark * * Purpose: * Draw a set of markers * * Synopsis: * #include "grf.h" * int astGMark( int n, const float *x, const float *y, int type ) * * Description: * This function displays markers at the given positions * * Parameters: * n * The number of markers to draw * x * A pointer to an array holding the "n" x values * y * A pointer to an array holding the "n" y values * type * An integer which can be used to indicate the type of marker symbol * required * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise * * Notes: * - Nothing is done if "n" is less than 1, or if a NULL pointer is * given for either "x" or "y" * */ int astGMark(int n, const float *x, const float *y, int type) { if (astGrid2dPtr) return astGrid2dPtr->gMark(n, x, y, type); else if (astGrid25dPtr) return astGrid25dPtr->gMark(n, x, y, type); } /* * Name: * astGText * * Purpose: * Draw a character string * * Synopsis: * #include "grf.h" * int astGText( const char *text, float x, float y, const char *just, * float upx, float upy ) * * Description: * This function displays a character string at a given position * using a specified justification and up-vector * * Parameters: * text * Pointer to a null-terminated character string to be displayed * x * The reference x coordinate * y * The reference y coordinate * just * A character string which specifies the location within the * text string which is to be placed at the reference position * given by x and y. The first character may be 'T' for "top", * 'C' for "centre", or 'B' for "bottom", and specifies the * vertical location of the reference position. Note, "bottom" * corresponds to the base-line of normal text. Some characters * (eg "y", "g", "p", etc) descend below the base-line. The second * character may be 'L' for "left", 'C' for "centre", or 'R' * for "right", and specifies the horizontal location of the * reference position. If the string has less than 2 characters * then 'C' is used for the missing characters * upx * The x component of the up-vector for the text, in graphics world * coordinates. If necessary the supplied value should be negated * to ensure that positive values always refer to displacements from * left to right on the screen * upy * The y component of the up-vector for the text, in graphics world * coordinates. If necessary the supplied value should be negated * to ensure that positive values always refer to displacements from * bottom to top on the screen * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise * * Notes: * - Any graphics within the rotated box enclosing the text are erased * - A NULL value for "just" causes a value of "CC" to be used * - Both "upx" and "upy" being zero causes an error * - Any unrecognised character in "just" causes an error */ int astGText(const char *text, float x, float y, const char *just, float upx, float upy) { if (astGrid2dPtr) return astGrid2dPtr->gText(text, x ,y, just, upx, upy); else if (astGrid25dPtr) return astGrid25dPtr->gText(text, x ,y, just, upx, upy); } /* * Name: * astGTxExt * * Purpose: * Get the extent of a character string * * Synopsis: * #include "grf.h" * int astGTxExt( const char *text, float x, float y, const char *just, * float upx, float upy, float *xb, float *yb ) * * Description: * This function returns the corners of a box which would enclose the * supplied character string if it were displayed using astGText * * The returned box INCLUDES any leading or trailing spaces * * Parameters: * text * Pointer to a null-terminated character string to be displayed * x * The reference x coordinate * y * The reference y coordinate * just * A character string which specifies the location within the * text string which is to be placed at the reference position * given by x and y. The first character may be 'T' for "top", * 'C' for "centre", or 'B' for "bottom", and specifies the * vertical location of the reference position. Note, "bottom" * corresponds to the base-line of normal text. Some characters * (eg "y", "g", "p", etc) descend below the base-line. The second * character may be 'L' for "left", 'C' for "centre", or 'R' * for "right", and specifies the horizontal location of the * reference position. If the string has less than 2 characters * then 'C' is used for the missing characters * upx * The x component of the up-vector for the text, in graphics world * coordinates. If necessary the supplied value should be negated * to ensure that positive values always refer to displacements from * left to right on the screen * upy * The y component of the up-vector for the text, in graphics world * coordinates. If necessary the supplied value should be negated * to ensure that positive values always refer to displacements from * bottom to top on the screen * xb * An array of 4 elements in which to return the x coordinate of * each corner of the bounding box * yb * An array of 4 elements in which to return the y coordinate of * each corner of the bounding box * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise * * Notes: * - The order of the corners is anti-clockwise (in world coordinates) * starting at the bottom left * - A NULL value for "just" causes a value of "CC" to be used * - Both "upx" and "upy" being zero causes an error * - Any unrecognised character in "just" causes an error * - Zero is returned for all bounds of the box if an error occurs */ int astGTxExt(const char *text, float x, float y, const char *just, float upx, float upy, float *xb, float *yb) { if (astGrid2dPtr) return astGrid2dPtr->gTxExt(text, x, y, just, upx, upy, xb, yb); else if (astGrid25dPtr) return astGrid25dPtr->gTxExt(text, x, y, just, upx, upy, xb, yb); } /* * Name: * astGAttr * * Purpose: * Enquire or set a graphics attribute value * * Synopsis: * #include "grf.h" * int int astGAttr( int attr, double value, double *old_value, int prim ) * * Description: * This function returns the current value of a specified graphics * attribute, and optionally establishes a new value. The supplied * value is converted to an integer value if necessary before use * * Parameters: * attr * An integer value identifying the required attribute. The * following symbolic values are defined in grf.h: * * GRF__STYLE - Line style * GRF__WIDTH - Line width * GRF__SIZE - Character and marker size scale factor * GRF__FONT - Character font * GRF__COLOUR - Colour index * value * A new value to store for the attribute. If this is AST__BAD * no value is stored * old_value * A pointer to a double in which to return the attribute value * If this is NULL, no value is returned * prim * The sort of graphics primative to be drawn with the new attribute * Identified by the following values defined in grf.h: * GRF__LINE * GRF__MARK * GRF__TEXT * * Returned Value: * A value of 0 is returned if an error occurrs, and 1 is returned * otherwise * * Notes: */ int astGAttr(int attr, double value, double *old, int prim) { if (astGrid2dPtr) return astGrid2dPtr->gAttr(attr, value, old, prim); else if (astGrid25dPtr) return astGrid25dPtr->gAttr(attr, value, old, prim); } /* * Name: * astGScales * * Purpose: * Get the axis scales. * * Synopsis: * #include "grf.h" * int astGScales( float *alpha, float *beta ) * * Description: * This function returns two values (one for each axis) which scale * increments on the corresponding axis into a "normal" coordinate * system in which: * 1 - The axes have equal scale in terms of (for instance) * millimetres per unit distance. * 2 - X values increase from left to right. * 3 - Y values increase from bottom to top. * * Parameters: * alpha * A pointer to the location at which to return the scale for the * X axis (i.e. Xnorm = alpha*Xworld). * beta * A pointer to the location at which to return the scale for the * Y axis (i.e. Ynorm = beta*Yworld). * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. */ int astGScales(float *alpha, float *beta) { if (astGrid2dPtr) return astGrid2dPtr->gScales(alpha,beta); else if (astGrid25dPtr) return astGrid25dPtr->gScales(alpha,beta); } /* * Name: * astGCap * * Purpose: * Indicate if this grf module has a given capability. * * Synopsis: * #include "grf.h" * int astGCap( int cap, int value ) * * Description: * This function is called by the AST Plot class to determine if the * grf module has a given capability, as indicated by the "cap" * argument. * * Parameters: * cap * The capability being inquired about. This will be one of the * following constants defined in grf.h: * * GRF__SCALES: This function should return a non-zero value if * it implements the astGScales function, and zero otherwise. The * supplied "value" argument should be ignored. * * GRF__MJUST: This function should return a non-zero value if * the astGText and astGTxExt functions recognise "M" as a * character in the justification string. If the first character of * a justification string is "M", then the text should be justified * with the given reference point at the bottom of the bounding box. * This is different to "B" justification, which requests that the * reference point be put on the baseline of the text, since some * characters hang down below the baseline. If the astGText or * astGTxExt function cannot differentiate between "M" and "B", * then this function should return zero, in which case "M" * justification will never be requested by Plot. The supplied * "value" argument should be ignored. * * GRF__ESC: This function should return a non-zero value if the * astGText and astGTxExt functions can recognise and interpret * graphics escape sequences within the supplied string. These * escape sequences are described below. Zero should be returned * if escape sequences cannot be interpreted (in which case the * Plot class will interpret them itself if needed). The supplied * "value" argument should be ignored only if escape sequences cannot * be interpreted by astGText and astGTxExt. Otherwise, "value" * indicates whether astGText and astGTxExt should interpret escape * sequences in subsequent calls. If "value" is non-zero then * escape sequences should be interpreted by astGText and * astGTxExt. Otherwise, they should be drawn as literal text. * * Returned Value: * The return value, as described above. Zero should be returned if * the supplied capability is not recognised. * * Escape Sequences: * Escape sequences are introduced into the text string by a percent * "%" character. The following escape sequences are currently recognised * ("..." represents a string of one or more decimal digits): * * %% - Print a literal "%" character (type GRF__ESPER ). * * %^...+ - Draw subsequent characters as super-scripts. The digits * "..." give the distance from the base-line of "normal" * text to the base-line of the super-script text, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESSUP ). * %^+ - Draw subsequent characters with the normal base-line. * * %v...+ - Draw subsequent characters as sub-scripts. The digits * "..." give the distance from the base-line of "normal" * text to the base-line of the sub-script text, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESSUB ). * * %v+ - Draw subsequent characters with the normal base-line * (equivalent to %^+). * * %>...+ - Leave a gap before drawing subsequent characters. * The digits "..." give the size of the gap, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESGAP ). * * %<...+ - Move backwards before drawing subsequent characters. * The digits "..." give the size of the movement, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF_ESBAC). * * %s...+ - Change the Size attribute for subsequent characters. The * digits "..." give the new Size as a fraction of the * "normal" Size, scaled so that a value of "100" corresponds * to 1.0 (type GRF__ESSIZ ). * * %s+ - Reset the Size attribute to its "normal" value. * * %w...+ - Change the Width attribute for subsequent characters. The * digits "..." give the new width as a fraction of the * "normal" Width, scaled so that a value of "100" corresponds * to 1.0 (type GRF__ESWID ). * * %w+ - Reset the Size attribute to its "normal" value. * * %f...+ - Change the Font attribute for subsequent characters. The * digits "..." give the new Font value (type GRF__ESFON ). * * %f+ - Reset the Font attribute to its "normal" value. * * %c...+ - Change the Colour attribute for subsequent characters. The * digits "..." give the new Colour value (type GRF__ESCOL ). * * %c+ - Reset the Colour attribute to its "normal" value. * * %t...+ - Change the Style attribute for subsequent characters. The * digits "..." give the new Style value (type GRF__ESSTY ). * * %t+ - Reset the Style attribute to its "normal" value. * * %- - Push the current graphics attribute values onto the top of * the stack - see "%+" (type GRF__ESPSH). * * %+ - Pop attributes values of the top the stack - see "%-". If * the stack is empty, "normal" attribute values are restored * (type GRF__ESPOP). * * The astFindEscape function (in libast.a) can be used to locate escape * sequences within a text string. It has the following signature: * * #include "plot.h" * int astFindEscape( const char *text, int *type, int *value, int *nc ) * * Parameters: * text * Pointer to the string to be checked. * type * Pointer to a location at which to return the type of escape * sequence. Each type is identified by a symbolic constant defined * in grf.h and is indicated in the above section. The returned value * is undefined if the supplied text does not begin with an escape * sequence. * value * Pointer to a lcation at which to return the integer value * associated with the escape sequence. All usable values will be * positive. Zero is returned if the escape sequence has no associated * integer. A value of -1 indicates that the attribute identified by * "type" should be reset to its "normal" value (as established using * the astGAttr function, etc). The returned value is undefined if * the supplied text does not begin with an escape sequence. * nc * Pointer to a location at which to return the number of * characters read by this call. If the text starts with an escape * sequence, the returned value will be the number of characters in * the escape sequence. Otherwise, the returned value will be the * number of characters prior to the first escape sequence, or the * length of the supplied text if no escape sequence is found. * * Returned Value: * A non-zero value is returned if the supplied text starts with a * graphics escape sequence, and zero is returned otherwise. */ int astGCap(int cap, int value) { if (astGrid2dPtr) return astGrid2dPtr->gCap(cap,value); else if (astGrid25dPtr) return astGrid25dPtr->gCap(cap,value); } /* * Name: * astGBBuf * * Purpose: * Start a new graphics buffering context. * * Synopsis: * #include "grf.h" * int astGBBuf( void ) * * Description: * This function begins saving graphical output commands in an * internal buffer; the commands are held until a matching astGEBuf * call (or until the buffer is emptied by astGFlush). This can * greatly improve the efficiency of some graphics systems. astGBBuf * increments an internal counter, while astGEBuf decrements this * counter and flushes the buffer to the output device when the * counter drops to zero. astGBBuf and astGEBuf calls should always * be paired. * * Parameters: * None. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * */ int astGBBuf(void) { return 1; } /* * Name: * astGEBuf * * Purpose: * End a graphics buffering context. * * Synopsis: * #include "grf.h" * int astGEBuf( void ) * * Description: * This function marks the end of a batch of graphical output begun * with the last call of astGBBuf. astGBBuf and astGEBUF calls should * always be paired. Each call to astGBBuf increments a counter, while * each call to astGEBuf decrements the counter. When the counter * reaches 0, the batch of output is written on the output device. * * Parameters: * None. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * */ int astGEBuf(void) { return 1; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grid3dbase.C��������������������������������������������������������������������0000644�0001750�0001750�00000010723�12046547424�015327� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid3dbase.h" #include "attribute.h" #include "widget.h" extern "C" { #include "ast.h" #include "grf.h" } Grid3dBase* astGrid3dPtr = NULL; Grid3dBase::Grid3dBase(Widget* p) : GridBase(p) {} Grid3dBase::Grid3dBase(Widget* p, const char* o) : GridBase(p,o) {} Grid3dBase::~Grid3dBase() {} int Grid3dBase::gLine(int n, float* x, float* y, float* z) { float xx[n]; float yy[n]; for (int ii=0; ii<n; ii++) { Vector3d vv = Vector3d(x[ii],y[ii],z[ii])*mx_; xx[ii] = vv[0]; yy[ii] = vv[1]; } switch (renderMode_) { case X11: x11Line(n,xx,yy); break; case PS: psLine(n,xx,yy); break; #ifdef _MACOSX case MACOSX: macosxLine(n,xx,yy); break; #endif #ifdef _WIN32 case GWIN32: win32Line(n,xx,yy); break; #endif } return 1; } int Grid3dBase::gQch(float* ch) { Tk_Font font =NULL; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } if (font) { Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); *ch = (float)metrics.linespace; return 1; } else { *ch = 0; return 0; } } int Grid3dBase::gText(const char* txt, float* ref, const char* just, float* up, float* norm) { if (!(txt && txt[0] && just && just[0] && just[1])) return 0; Vector3d vv = Vector3d(ref[0],ref[1],ref[2])*mx_; switch (renderMode_) { case X11: return x11Text(txt,vv[0],vv[1],just,Vector(0,1)); case PS: return psText(txt,vv[0],vv[1],just,Vector(0,1)); #ifdef _MACOSX case MACOSX: return macosxText(txt,vv[0],vv[1],just,Vector(0,1)); #endif #ifdef _WIN32 case GWIN32: return win32Text(txt,vv[0],vv[1],just,Vector(0,1)); #endif } return 0; } int Grid3dBase::gTxExt(const char* txt, float* ref, const char* just, float* up, float* norm, float* xb, float* yb, float* zb, float* bl) { if (!(txt && txt[0] && just)) { xb[0] = xb[1] = xb[2] = xb[3] = 0; yb[0] = yb[1] = yb[2] = yb[3] = 0; zb[0] = zb[1] = zb[2] = zb[3] = 0; return 0; } /* cerr << txt << Vector3d(ref[0],ref[1],ref[2]) << ' ' << just[0] << just[1] << Vector3d(up[0],up[1],up[2]) << Vector3d(norm[0],norm[1],norm[2]) << endl; */ Tk_Font font; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } Vector3d vv = Vector3d(ref[0],ref[1],ref[2])*mx_; // cerr << " vv: " << vv << endl; Vector3d cc = vv * calcTextPos(vv, txt, just, font); // cerr << " cc: " << cc << endl; Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int width = Tk_TextWidth(font, txt, strlen(txt)); BBox3d nn(Vector3d(0,-metrics.descent,0), Vector3d(width,metrics.ascent,0)); // cerr << " nn: " << nn << endl; Matrix3d mm = Translate3d(-nn.center()) * rx_ * Translate3d(nn.center()); // cerr << mm << endl; BBox3d bb = nn * mm * Translate3d(cc); // cerr << " bb: " << bb << endl; Vector3d ll = cc * mm; xb[0] = bb.ll[0]; yb[0] = bb.ll[1]; zb[0] = bb.ll[2]; xb[1] = bb.ur[0]; yb[1] = bb.ll[1]; zb[1] = bb.ll[2]; xb[2] = bb.ur[0]; yb[2] = bb.ur[1]; zb[2] = bb.ll[2]; xb[3] = bb.ll[0]; yb[3] = bb.ur[1]; zb[3] = bb.ll[2]; bl[0] = ll[0]; bl[1] = ll[1]; bl[2] = ll[2]; return 1; } Matrix3d Grid3dBase::calcTextPos(const Vector3d& vv, const char* txt, const char* just, Tk_Font font) { Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int width = Tk_TextWidth(font, txt, strlen(txt)); Matrix3d m1,m2; switch (just[0]) { case 'T': break; case 'C': m1 = Translate3d(0,metrics.linespace/2,0); break; case 'B': m1 = Translate3d(0,metrics.ascent,0); break; case 'M': m1 = Translate3d(0,metrics.linespace,0); break; } switch (just[1]) { case 'L': break; case 'C': m2 = Translate3d(-width/2.,0,0); break; case 'R': m2 = Translate3d(-width,0,0); break; } return Translate3d(-vv) * m1 * m2 * Translate3d(vv); } ���������������������������������������������./saods9/saotk/util/util.h��������������������������������������������������������������������������0000644�0001750�0001750�00000006054�11750561001�014330� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __util_h__ #define __util_h__ #include <stdlib.h> #include <string.h> #include <limits.h> #include <float.h> #include <math.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "fuzzy.h" #include "vector.h" #ifndef PATH_MAX #define PATH_MAX 1024 #endif #define XImageData(x) x->data #ifdef _WIN32 #include <xxlib.h> #include <win32lib.h> #define XQueryPointer XXQueryPointer #define XWarpPointer XXWarpPointer #endif #ifdef _MACOSX #undef XImageData #include <xxlib.h> #include <macosxlib.h> #define XGetImage XXGetImage #define XQueryPointer XXQueryPointer #define XWarpPointer XXWarpPointer #endif #define STRCMP(which,str,cnt) (!strncmp(toConstLower(which), str, cnt) && strlen(which)==cnt) static const char psFonts[12][32] = { {"Helvetica"}, {"Helvetica-Oblique"}, {"Helvetica-Bold"}, {"Helvetica-BoldOblique"}, {"Times-Roman"}, {"Times-Italic"}, {"Times-Bold"}, {"Times-BoldItalic"}, {"Courier"}, {"Courier-Oblique"}, {"Courier-Bold"}, {"Courier-BoldOblique"} }; #ifndef _WIN32 static const double M_TWOPI = 2*M_PI; #endif static const double M_THREEPI = 3*M_PI; static const double M_FOURPI = 4*M_PI; extern int maperr; extern int lsb(); extern void swap2(char* src, char* dest); extern void swap4(char* src, char* dest); extern void swap8(char* src, char* dest); // defined in ds9.C extern void internalError(const char*); extern char* dupstr(const char*); extern char* trim(const char*); extern char* toLower(const char*); extern char* toUpper(const char*); extern char* toConstLower(const char*); extern char* toConstUpper(const char*); extern double zeroTWOPI(double); extern double zero360(double); extern double m180To180(double); extern double degToRad(double); extern double radToDeg(double); extern double dmsToDegree(int, int, int, double); extern double parseSEXStr(const char*); extern double parseHMSStr(const char*); extern double parseDMSStr(const char*); extern double RGB2Gray(double, double, double); extern unsigned char RGB2Gray(unsigned char, unsigned char, unsigned char); extern void RGB2CMYK(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned char*, unsigned char*, unsigned char*); extern void RGB2CMYK(unsigned short, unsigned short, unsigned short, unsigned short*, unsigned short*, unsigned short*, unsigned short*); extern ostream& psColorGray(XColor*, ostream&); extern ostream& psColorRGB(XColor*, ostream&); extern ostream& psColorCMYK(XColor*, ostream&); extern char* psQuote(const char*); extern const char* psFontName(const char*); extern int psFontSize(const char*); extern const char* psFontName(const char*, const char*, const char*); extern int fCompare(const void*, const void*); extern int dCompare(const void*, const void*); extern Vector mapLen(const Vector& v, const Matrix& mx); extern "C" { extern void conputs(FILE *fd, char *format, ...); } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grid2dbase.h��������������������������������������������������������������������0000644�0001750�0001750�00000001367�11701670604�015371� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid2dbase_h__ #define __grid2dbase_h__ #include <tk.h> #include "gridbase.h" class Grid2dBase : public GridBase { public: Grid2dBase(Widget*); Grid2dBase(Widget*, const char*); virtual ~Grid2dBase(); int gLine(int n, float* x, float* y); int gQch(float*, float*); int gMark(int, const float*, const float*, int) {return 1;} int gText(const char* txt, float x, float y, const char* just, float upx, float upy); int gTxExt(const char*, float, float, const char*, float, float, float*, float*); int gScales(float *alpha, float *beta); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/attribute.h���������������������������������������������������������������������0000644�0001750�0001750�00000002151�11700666272�015363� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __attribute_h__ #define __attribute_h__ #include <tk.h> #include "vector.h" class Widget; class Attribute { public: enum Style {SOLID,DASH}; enum Colour {BLACK,WHITE,RED,GREEN,BLUE,CYAN,MAGENTA,YELLOW}; private: Widget* parent; Style style_; float width_; int font_; int size_; Tk_Font tkfont_; Tk_Font psfont_; unsigned long colour_; char* colorName_; unsigned long color_; private: void initFonts(); public: Attribute(Widget*); ~Attribute(); void setStyle(double); void setWidth(double); void setSize(double); void setFont(double); void setColour(double); Style style() {return style_;} float width() {return width_;} int size() {return size_;} int font() {return font_;} Tk_Font tkfont() {return tkfont_;} Tk_Font psfont() {return psfont_;} unsigned long colour() {return colour_;} char* colorName() {return colorName_;} unsigned long color() {return color_;} }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grid3dbase.h��������������������������������������������������������������������0000644�0001750�0001750�00000001644�11757464372�015406� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid3dbase_h__ #define __grid3dbase_h__ #include <tk.h> #include "gridbase.h" #include "vector3d.h" class Grid3dBase : public GridBase { protected: Matrix3d mx_; Matrix3d rx_; Matrix3d calcTextPos(const Vector3d&, const char*, const char*, Tk_Font); public: Grid3dBase(Widget*); Grid3dBase(Widget*, const char*); virtual ~Grid3dBase(); int gLine(int n, float* x, float* y, float* z); int gQch(float* ch); int gMark(int n, float* x, float* y, float* z, int type, float* norm) {return 1;} int gText(const char* txt, float* ref, const char* just, float* up, float* norm); int gTxExt(const char* txt, float* ref, const char* just, float* up, float* norm, float* xb, float* yb, float* zb, float* bl); }; #endif ��������������������������������������������������������������������������������������������./saods9/saotk/util/grf3d.C�������������������������������������������������������������������������0000644�0001750�0001750�00000043002�11702635275�014321� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������extern "C" { #include "grf3d.h" } #include "grid3dbase.h" extern Grid3dBase* astGrid3dPtr; /* * Name: * astG3DCap * * Purpose: * Indicate if this grf3d module has a given capability. * * Synopsis: * #include "grf3d.h" * int astG3DCap( int cap, int value ) * * Description: * This function is called by the AST Plot class to determine if the * grf3d module has a given capability, as indicated by the "cap" * argument. * * Parameters: * cap * The capability being inquired about. This will be one of the * following constants defined in grf3d.h: * * GRF3D__ESC: This function should return a non-zero value if the * astG3DText and astG3DTxExt functions can recognise and interpret * graphics escape sequences within the supplied string. These * escape sequences are described below. Zero should be returned * if escape sequences cannot be interpreted (in which case the * Plot class will interpret them itself if needed). The supplied * "value" argument should be ignored only if escape sequences cannot * be interpreted by astG3DText and astG3DTxExt. Otherwise, "value" * indicates whether astG3DText and astG3DTxExt should interpret escape * sequences in subsequent calls. If "value" is non-zero then * escape sequences should be interpreted by astG3DText and * astG3DTxExt. Otherwise, they should be drawn as literal text. * * Returned Value: * The return value, as described above. Zero should be returned if * the supplied capability is not recognised. * * Escape Sequences: * Escape sequences are introduced into the text string by a percent * "%" character. The following escape sequences are currently recognised * ("..." represents a string of one or more decimal digits): * * %% - Print a literal "%" character (type GRF__ESPER ). * * %^...+ - Draw subsequent characters as super-scripts. The digits * "..." give the distance from the base-line of "normal" * text to the base-line of the super-script text, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESSUP ). * %^+ - Draw subsequent characters with the normal base-line. * * %v...+ - Draw subsequent characters as sub-scripts. The digits * "..." give the distance from the base-line of "normal" * text to the base-line of the sub-script text, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESSUB ). * * %v+ - Draw subsequent characters with the normal base-line * (equivalent to %^+). * * %>...+ - Leave a gap before drawing subsequent characters. * The digits "..." give the size of the gap, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF__ESGAP ). * * %<...+ - Move backwards before drawing subsequent characters. * The digits "..." give the size of the movement, scaled * so that a value of "100" corresponds to the height of * "normal" text (type GRF_ESBAC). * * %s...+ - Change the Size attribute for subsequent characters. The * digits "..." give the new Size as a fraction of the * "normal" Size, scaled so that a value of "100" corresponds * to 1.0 (type GRF__ESSIZ ). * * %s+ - Reset the Size attribute to its "normal" value. * * %w...+ - Change the Width attribute for subsequent characters. The * digits "..." give the new width as a fraction of the * "normal" Width, scaled so that a value of "100" corresponds * to 1.0 (type GRF__ESWID ). * * %w+ - Reset the Size attribute to its "normal" value. * * %f...+ - Change the Font attribute for subsequent characters. The * digits "..." give the new Font value (type GRF__ESFON ). * * %f+ - Reset the Font attribute to its "normal" value. * * %c...+ - Change the Colour attribute for subsequent characters. The * digits "..." give the new Colour value (type GRF__ESCOL ). * * %c+ - Reset the Colour attribute to its "normal" value. * * %t...+ - Change the Style attribute for subsequent characters. The * digits "..." give the new Style value (type GRF__ESSTY ). * * %t+ - Reset the Style attribute to its "normal" value. * * %- - Push the current graphics attribute values onto the top of * the stack - see "%+" (type GRF__ESPSH). * * %+ - Pop attributes values of the top the stack - see "%-". If * the stack is empty, "normal" attribute values are restored * (type GRF__ESPOP). * * The astFindEscape function (in libast.a) can be used to locate escape * sequences within a text string. It has the following signature: * * #include "plot.h" * int astFindEscape( const char *text, int *type, int *value, int *nc ) * * Parameters: * text * Pointer to the string to be checked. * type * Pointer to a location at which to return the type of escape * sequence. Each type is identified by a symbolic constant defined * in grf.h and is indicated in the above section. The returned value * is undefined if the supplied text does not begin with an escape * sequence. * value * Pointer to a lcation at which to return the integer value * associated with the escape sequence. All usable values will be * positive. Zero is returned if the escape sequence has no associated * integer. A value of -1 indicates that the attribute identified by * "type" should be reset to its "normal" value (as established using * the astG3DAttr function, etc). The returned value is undefined if * the supplied text does not begin with an escape sequence. * nc * Pointer to a location at which to return the number of * characters read by this call. If the text starts with an escape * sequence, the returned value will be the number of characters in * the escape sequence. Otherwise, the returned value will be the * number of characters prior to the first escape sequence, or the * length of the supplied text if no escape sequence is found. * * Returned Value: * A non-zero value is returned if the supplied text starts with a * graphics escape sequence, and zero is returned otherwise. * */ int astG3DCap(int cap, int value) { if (astGrid3dPtr) return astGrid3dPtr->gCap(cap, value); } /* * Name: * astG3DFlush * * Purpose: * Flush all pending graphics to the output device. * * Synopsis: * #include "grf3d.h" * int astG3DFlush( void ) * * Description: * This function ensures that the display device is up-to-date, * by flushing any pending graphics to the output device. * * Parameters: * None. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * */ int astG3DFlush(void) { if (astGrid3dPtr) return astGrid3dPtr->gFlush(); } /* * Name: * astG3DLine * * Purpose: * Draw a polyline (i.e. a set of connected lines). * * Synopsis: * #include "grf3d.h" * int astG3DLine( int n, float *x, float *y, float *z ) * * Description: * This function displays lines joining the given positions. * * Parameters: * n * The number of positions to be joined together. * x * A pointer to an array holding the "n" x values. * y * A pointer to an array holding the "n" y values. * z * A pointer to an array holding the "n" z values. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * - A camera must have been established prior to calling this * function using either astG3DSetCamera or astG3DAutoCamera. * - Nothing is done if "n" is less than 2, or if a NULL pointer is * given for either "x", "y" or "z". * */ int astG3DLine(int n, float *x, float *y, float *z) { if (astGrid3dPtr) return astGrid3dPtr->gLine(n, x, y, z); } /* * Name: * astG3DQch * * Purpose: * Return the character height in world coordinates. * * Synopsis: * #include "grf3d.h" * int astG3DQch( float *ch ) * * Description: * This function returns the height of characters drawn using astG3DText. * * Parameters: * ch * A pointer to the double which is to receive the height of * characters drawn with astG3DText. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * - Since the 3D world coordinate axes are assumed to be equally * scaled, the height of text in world coordinate units is independent * of the orientation of the text. Therefore, this function returns * only one height value, unlike the equivalent 2D astGQch function * that returns two heights. */ int astG3DQch(float *ch) { if (astGrid3dPtr) return astGrid3dPtr->gQch(ch); } /* * Name: * astG3DMark * * Purpose: * Draw a set of markers. * * Synopsis: * #include "grf.h" * int astG3DMark( int n, float *x, float *y, float *z, int type, * float norm[3] ) * * Description: * This function draws markers centred at the given positions, on a * plane with a specified normal vector. * * Parameters: * n * The number of markers to draw. * x * A pointer to an array holding the "n" x values. * y * A pointer to an array holding the "n" y values. * z * A pointer to an array holding the "n" z values. * type * An integer which can be used to indicate the type of marker symbol * required. See the description of routine PGPT in the PGPLOT manual. * norm * The (x,y,z) components of a vector that is normal to the plane * containing the marker. The given vector passes through the marker * from the back to the front. If all components of this vector are * zero, then a normal vector pointing from the position of the * first marker towards the camera eye is used. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * - Nothing is done if "n" is less than 1, or if a NULL pointer is * given for "x", "y" or "z". * */ int astG3DMark(int n, float *x, float *y, float *z, int type, float norm[3]) { if (astGrid3dPtr) return astGrid3dPtr->gMark(n, x, y, z, type, norm); } /* * Name: * astG3DText * * Purpose: * Draw a character string. * * Synopsis: * #include "grf3d.h" * int astG3DText( const char *text, float ref[3], const char *just, * float up[3], float norm[3] ) * * Description: * This function displays a character string at a given position * on a given plane in 3D world coords, using a specified * justification and up-vector. * * Parameters: * text * Pointer to a null-terminated character string to be displayed. * ref * The reference (x,y,z) coordinates. * just * A character string which specifies the location within the * text string which is to be placed at the reference position * given by x and y. The first character may be 'T' for "top", * 'C' for "centre", or 'B' for "bottom", and specifies the * vertical location of the reference position. Note, "bottom" * corresponds to the base-line of normal text. Some characters * (eg "y", "g", "p", etc) descend below the base-line. The second * character may be 'L' for "left", 'C' for "centre", or 'R' * for "right", and specifies the horizontal location of the * reference position. If the string has less than 2 characters * then 'C' is used for the missing characters. * up * The (x,y,z) up-vector for the text. The actual up vector used is * the projection of the supplied vector onto the plane specified by * "norm". * norm * The (x,y,z) components of a vector that is normal to the plane * containing the text. The given vector passes through the text * from the back to the front. If all components of this vector are * zero, then a normal vector pointing towards the camera eye is used. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * - This routine does not recognise PGPLOT escape sequences. * - A NULL value for "just" causes a value of "CC" to be used. */ int astG3DText(const char *text, float ref[3], const char *just, float up[3], float norm[3] ) { if (astGrid3dPtr) return astGrid3dPtr->gText(text, ref, just, up, norm); } /* * Name: * astG3DTxExt * * Purpose: * Get the extent of a character string. * * Synopsis: * #include "grf3d.h" * int astG3DTxExt( const char *text, float ref[3], const char *just, * float up[3], float norm[3], float *xb, float *yb, * float *zb, float bl[3] ) * * Description: * This function returns the corners of a box which would enclose the * supplied character string if it were displayed using astG3DText. * * The returned box INCLUDES any leading or trailing spaces. * * Parameters: * text * Pointer to a null-terminated character string to be displayed. * ref * The reference (x,y,z) coordinates. * just * A character string which specifies the location within the * text string which is to be placed at the reference position * given by x and y. The first character may be 'T' for "top", * 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and * specifies the vertical location of the reference position. Note, * "baseline" corresponds to the base-line of normal text. Some * characters (eg "y", "g", "p", etc) descend below the base-line, * and so "M" and "B" will produce different effects for such * characters. The second character may be 'L' for "left", 'C' for * "centre", or 'R' for "right", and specifies the horizontal * location of the reference position. If the string has less than * 2 characters then 'C' is used for the missing characters. * up * The (x,y,z) up-vector for the text. The actual up vector used is * the projection of the supplied vector onto the plane specified by * "norm". * norm * The (x,y,z) components of a vector that is normal to the plane * containing the text. The given vector passes through the text * from the back to the front. If all components of this vector are * zero, then a normal vector pointing towards the camera eye is used. * xb * An array of 4 elements in which to return the x coordinate of * each corner of the bounding box. * yb * An array of 4 elements in which to return the y coordinate of * each corner of the bounding box. * zb * An array of 4 elements in which to return the z coordinate of * each corner of the bounding box. * bl * The 3D world coordinates at the left hand end of the text * baseline. * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * - The order of the corners is anti-clockwise starting at the * bottom left when viewing the text normally (i.e. face on). * - This routine does not recognise PGPLOT escape sequences. * - A NULL value for "just" causes a value of "CC" to be used. */ int astG3DTxExt(const char *text, float ref[3], const char *just, float up[3], float norm[3], float *xb, float *yb, float *zb, float bl[3]) { if (astGrid3dPtr) return astGrid3dPtr->gTxExt(text, ref, just, up, norm, xb, yb, zb, bl); } /* * Name: * astG3DAttr * * Purpose: * Enquire or set a 3D graphics attribute value. * * Synopsis: * #include "grf3d.h" * int int astG3DAttr( int attr, double value, double *old_value, int prim ) * * Description: * This function returns the current value of a specified 3D graphics * attribute, and optionally establishes a new value. The supplied * value is converted to an integer value if necessary before use. * * Parameters: * attr * An integer value identifying the required attribute. The * following symbolic values are defined in grf3d.h: * * GRF__STYLE - Line style. * GRF__WIDTH - Line width. * GRF__SIZE - Character and marker size scale factor. * GRF__FONT - Character font. * GRF__COLOUR - Colour index. * value * A new value to store for the attribute. If this is AST__BAD * no value is stored. * old_value * A pointer to a double in which to return the attribute value. * If this is NULL, no value is returned. * prim * The sort of graphics primitive to be drawn with the new attribute. * Identified by the following values defined in grf.h: * GRF__LINE * GRF__MARK * GRF__TEXT * * Returned Value: * A value of 0 is returned if an error occurs, and 1 is returned * otherwise. * * Notes: * */ int astG3DAttr(int attr, double value, double *old_value, int prim) { if (astGrid3dPtr) return astGrid3dPtr->gAttr(attr, value, old_value, prim); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/saotk.C�������������������������������������������������������������������������0000644�0001750�0001750�00000006741�11700666272�014445� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tk.h" extern int FrameTrueColor8_Init(Tcl_Interp*); extern int FrameTrueColor16_Init(Tcl_Interp*); extern int FrameTrueColor24_Init(Tcl_Interp*); extern int FrameRGBTrueColor8_Init(Tcl_Interp*); extern int FrameRGBTrueColor16_Init(Tcl_Interp*); extern int FrameRGBTrueColor24_Init(Tcl_Interp*); extern int Frame3dTrueColor8_Init(Tcl_Interp*); extern int Frame3dTrueColor16_Init(Tcl_Interp*); extern int Frame3dTrueColor24_Init(Tcl_Interp*); extern int ColorbarTrueColor8_Init(Tcl_Interp*); extern int ColorbarTrueColor16_Init(Tcl_Interp*); extern int ColorbarTrueColor24_Init(Tcl_Interp*); extern int ColorbarRGBTrueColor8_Init(Tcl_Interp*); extern int ColorbarRGBTrueColor16_Init(Tcl_Interp*); extern int ColorbarRGBTrueColor24_Init(Tcl_Interp*); extern int PannerTrueColor_Init(Tcl_Interp*); extern int MagnifierTrueColor_Init(Tcl_Interp*); #if !(_WIN32 || _MACOSX) extern int FramePseudoColor8_Init(Tcl_Interp*); extern int ColorbarPseudoColor8_Init(Tcl_Interp*); extern int MagnifierPseudoColor_Init(Tcl_Interp*); extern int PannerPseudoColor_Init(Tcl_Interp*); #endif extern "C" { int Saotk_Init(Tcl_Interp* interp); int SaotkCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]); } int Saotk_Init(Tcl_Interp* interp) { // TrueColor if (FrameTrueColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (FrameTrueColor16_Init(interp) == TCL_ERROR) return TCL_ERROR; if (FrameTrueColor24_Init(interp) == TCL_ERROR) return TCL_ERROR; if (FrameRGBTrueColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (FrameRGBTrueColor16_Init(interp) == TCL_ERROR) return TCL_ERROR; if (FrameRGBTrueColor24_Init(interp) == TCL_ERROR) return TCL_ERROR; if (Frame3dTrueColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (Frame3dTrueColor16_Init(interp) == TCL_ERROR) return TCL_ERROR; if (Frame3dTrueColor24_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarTrueColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarTrueColor16_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarTrueColor24_Init(interp) == TCL_ERROR) return TCL_ERROR; if (PannerTrueColor_Init(interp) == TCL_ERROR) return TCL_ERROR; if (MagnifierTrueColor_Init(interp) == TCL_ERROR) return TCL_ERROR; // RGBTrueColor if (ColorbarRGBTrueColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarRGBTrueColor16_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarRGBTrueColor24_Init(interp) == TCL_ERROR) return TCL_ERROR; // PseudoColor #if !(_WIN32 || _MACOSX) if (FramePseudoColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (ColorbarPseudoColor8_Init(interp) == TCL_ERROR) return TCL_ERROR; if (PannerPseudoColor_Init(interp) == TCL_ERROR) return TCL_ERROR; if (MagnifierPseudoColor_Init(interp) == TCL_ERROR) return TCL_ERROR; #endif // dummy command // needed for auto_load, since all of our real work are canvas widgets, // tcl commands Tcl_CreateCommand(interp, "saotk", (Tcl_CmdProc* )SaotkCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); // Define Package Name if (Tcl_PkgProvide(interp, "saotk", "1.0") == TCL_ERROR) return TCL_ERROR; return TCL_OK; } int SaotkCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]) { return TCL_OK; } �������������������������������./saods9/saotk/util/smooth.h������������������������������������������������������������������������0000644�0001750�0001750�00000000651�11700666272�014674� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __smooth_h__ #define __smooth_h__ void boxcar(double* kernel, int r); void tophat(double* kernel, int r); void gaussian(double* kernel, int r); void convolve(double* kernel, double* src, double* dest, int width, int height, int r); #endif ���������������������������������������������������������������������������������������./saods9/saotk/util/gridbase.h����������������������������������������������������������������������0000644�0001750�0001750�00000002643�11701400210�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __gridbase_h__ #define __gridbase_h__ #include <tk.h> #include "vector.h" class Widget; class Attribute; class GridBase { public: enum RenderMode {X11, PS, MACOSX, GWIN32}; protected: Widget* parent_; char* option_; RenderMode renderMode_; Attribute* line_; Attribute* text_; GC gc_; Pixmap pixmap_; Matrix matrix_; int mode_; protected: int x11Line(int n, float* x, float* y); int x11Text(const char*, float, float, const char*, Vector); int psLine(int n, float* x, float* y); int psText(const char*, float, float, const char*, Vector); void psColor(Attribute*); #ifdef _MACOSX int macosxLine(int n, float* x, float* y); int macosxText(const char*, float, float, const char*, Vector); #endif #ifdef _WIN32 int win32Line(int n, float* x, float* y); int win32Text(const char*, float, float, const char*, Vector); #endif double calcTextAngle(const char*, Vector); Matrix calcTextPos(const Vector&, double, const char*, const char*, Vector, Tk_Font); public: GridBase(Widget*); GridBase(Widget*, const char*); virtual ~GridBase(); int gAttr(int attr, double value, double* old, int prim); int gCap(int, int); int gFlush() {return 1;} const char* option() {return option_;} }; #endif ���������������������������������������������������������������������������������������������./saods9/saotk/util/grid25dbase.h�������������������������������������������������������������������0000644�0001750�0001750�00000001377�11702635275�015465� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __grid25dbase_h__ #define __grid25dbase_h__ #include <tk.h> #include "gridbase.h" class Grid25dBase : public GridBase { public: Grid25dBase(Widget*); Grid25dBase(Widget*, const char*); virtual ~Grid25dBase(); int gLine(int n, float* x, float* y); int gQch(float*, float*); int gMark(int, const float*, const float*, int) {return 1;} int gText(const char* txt, float x, float y, const char* just, float upx, float upy); int gTxExt(const char*, float, float, const char*, float, float, float*, float*); int gScales(float *alpha, float *beta); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/smooth.C������������������������������������������������������������������������0000644�0001750�0001750�00000003373�12107012362�014616� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <math.h> #include "smooth.h" void boxcar(double* kernel, int r) { int rr = 2*r+1; int ksz = rr*rr; double* ptr = kernel; for (int jj=0; jj<rr; jj++) for (int ii=0; ii<rr; ii++, ptr++) *ptr = 1./ksz; } void tophat(double* kernel, int r) { int rr = 2*r+1; int ksz = rr*rr; double kt = 0; for (int y=-r; y<=r; y++) { for (int x=-r; x<=r; x++) { if ((x*x + y*y) <= r*r) { kernel[(y+r)*rr+(x+r)] = 1; kt++; } } } // normalize kernel for (int aa=0; aa<ksz; aa++) kernel[aa] /= kt; } void gaussian(double* kernel, int r) { int rr = 2*r+1; int ksz = rr*rr; double sigma = r/2.; double s2 = sigma*sigma; double kt = 0; for (int y=-r; y<=r; y++) { for (int x=-r; x<=r; x++) { if ((x*x + y*y) <= r*r) { double vv = exp(-.5*((x*x + y*y)/s2)); kernel[(y+r)*rr+(x+r)] = vv; kt += vv; } } } // normalize kernel for (int aa=0; aa<ksz; aa++) kernel[aa] /= kt; } void convolve(double* kernel, double* src, double* dest, int width, int height, int r) { int rr = 2*r+1; double* dptr = dest; for (int jj=0; jj<height; jj++) { for (int ii=0; ii<width; ii++, dptr++) { for (int nn=jj-r, qq=0; nn<=jj+r; nn++, qq++) { if (nn>=0 && nn<height) { register int nd = nn*width; register int qd = qq*rr; for (int mm=ii-r, pp=0; mm<=ii+r; mm++, pp++) { if (mm>=0 && mm<width) { double vv = src[nd+mm]; if (isfinite(vv)) *dptr += vv*kernel[qd+pp]; } } } } } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/fdstream.hpp��������������������������������������������������������������������0000644�0001750�0001750�00000011234�07611565102�015523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* The following code declares classes to read from and write to * file descriptore or file handles. * * See * http://www.josuttis.com/cppcode * for details and the latest version. * * - open: * - integrating BUFSIZ on some systems? * - optimized reading of multiple characters * - stream for reading AND writing * - i18n * * (C) Copyright Nicolai M. Josuttis 2001. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. * * Version: Jul 28, 2002 * History: * Jul 28, 2002: bugfix memcpy() => memmove() * fdinbuf::underflow(): cast for return statements * Aug 05, 2001: first public version */ #ifndef BOOST_FDSTREAM_HPP #define BOOST_FDSTREAM_HPP #include <istream> #include <ostream> #include <streambuf> // for EOF: #include <cstdio> // for memmove(): #include <cstring> // low-level read and write functions #ifdef _MSC_VER # include <io.h> #else # include <unistd.h> //extern "C" { // int write (int fd, const char* buf, int num); // int read (int fd, char* buf, int num); //} #endif // BEGIN namespace BOOST namespace boost { /************************************************************ * fdostream * - a stream that writes on a file descriptor ************************************************************/ class fdoutbuf : public std::streambuf { protected: int fd; // file descriptor public: // constructor fdoutbuf (int _fd) : fd(_fd) { } protected: // write one character virtual int_type overflow (int_type c) { if (c != EOF) { char z = c; if (write (fd, &z, 1) != 1) { return EOF; } } return c; } // write multiple characters virtual std::streamsize xsputn (const char* s, std::streamsize num) { return write(fd,s,num); } }; class fdostream : public std::ostream { protected: fdoutbuf buf; public: fdostream (int fd) : std::ostream(0), buf(fd) { rdbuf(&buf); } }; /************************************************************ * fdistream * - a stream that reads on a file descriptor ************************************************************/ class fdinbuf : public std::streambuf { protected: int fd; // file descriptor protected: /* data buffer: * - at most, pbSize characters in putback area plus * - at most, bufSize characters in ordinary read buffer */ static const int pbSize = 4; // size of putback area static const int bufSize = 1024; // size of the data buffer char buffer[bufSize+pbSize]; // data buffer public: /* constructor * - initialize file descriptor * - initialize empty data buffer * - no putback area * => force underflow() */ fdinbuf (int _fd) : fd(_fd) { setg (buffer+pbSize, // beginning of putback area buffer+pbSize, // read position buffer+pbSize); // end position } protected: // insert new characters into the buffer virtual int_type underflow () { #ifndef _MSC_VER using std::memmove; #endif // is read position before end of buffer? if (gptr() < egptr()) { return traits_type::to_int_type(*gptr()); } /* process size of putback area * - use number of characters read * - but at most size of putback area */ int numPutback; numPutback = gptr() - eback(); if (numPutback > pbSize) { numPutback = pbSize; } /* copy up to pbSize characters previously read into * the putback area */ memmove (buffer+(pbSize-numPutback), gptr()-numPutback, numPutback); // read at most bufSize new characters int num; num = read (fd, buffer+pbSize, bufSize); if (num <= 0) { // ERROR or EOF return EOF; } // reset buffer pointers setg (buffer+(pbSize-numPutback), // beginning of putback area buffer+pbSize, // read position buffer+pbSize+num); // end of buffer // return next character return traits_type::to_int_type(*gptr()); } }; class fdistream : public std::istream { protected: fdinbuf buf; public: fdistream (int fd) : std::istream(0), buf(fd) { rdbuf(&buf); } }; } // END namespace boost #endif /*BOOST_FDSTREAM_HPP*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/FlexLexer.h���������������������������������������������������������������������0000644�0001750�0001750�00000014163�12032640000�015240� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*-C++-*- // FlexLexer.h -- define interfaces for lexical analyzer classes generated // by flex // Copyright (c) 1993 The Regents of the University of California. // All rights reserved. // // This code is derived from software contributed to Berkeley by // Kent Williams and Tom Epperly. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // Neither the name of the University nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE. // This file defines FlexLexer, an abstract class which specifies the // external interface provided to flex C++ lexer objects, and yyFlexLexer, // which defines a particular lexer class. // // If you want to create multiple lexer classes, you use the -P flag // to rename each yyFlexLexer to some other xxFlexLexer. You then // include <FlexLexer.h> in your other sources once per lexer class: // // #undef yyFlexLexer // #define yyFlexLexer xxFlexLexer // #include <FlexLexer.h> // // #undef yyFlexLexer // #define yyFlexLexer zzFlexLexer // #include <FlexLexer.h> // ... #ifndef __FLEX_LEXER_H // Never included before - need to define base class. #define __FLEX_LEXER_H #include <iostream> # ifndef FLEX_STD # define FLEX_STD std:: # endif extern "C++" { struct yy_buffer_state; typedef int yy_state_type; class FlexLexer { public: virtual ~FlexLexer() { } const char* YYText() const { return yytext; } size_t YYLeng() const { return yyleng; } virtual void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; virtual struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ) = 0; virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; virtual void yyrestart( FLEX_STD istream* s ) = 0; virtual int yylex() = 0; // Call yylex with new input/output sources. int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) { switch_streams( new_in, new_out ); return yylex(); } // Switch to new input/output streams. A nil stream pointer // indicates "keep the current one". virtual void switch_streams( FLEX_STD istream* new_in = 0, FLEX_STD ostream* new_out = 0 ) = 0; int lineno() const { return yylineno; } int debug() const { return yy_flex_debug; } void set_debug( int flag ) { yy_flex_debug = flag; } protected: char* yytext; size_t yyleng; int yylineno; // only maintained if you use %option yylineno int yy_flex_debug; // only has effect with -d or "%option debug" }; } #endif // FLEXLEXER_H #if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) // Either this is the first time through (yyFlexLexerOnce not defined), // or this is a repeated include to define a different flavor of // yyFlexLexer, as discussed in the flex manual. #define yyFlexLexerOnce extern "C++" { class yyFlexLexer : public FlexLexer { public: // arg_yyin and arg_yyout default to the cin and cout, but we // only make that assignment when initializing in yylex(). yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); virtual ~yyFlexLexer(); void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); void yy_delete_buffer( struct yy_buffer_state* b ); void yyrestart( FLEX_STD istream* s ); void yypush_buffer_state( struct yy_buffer_state* new_buffer ); void yypop_buffer_state(); virtual int yylex(); virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); virtual int yywrap(); void begin(int,int); protected: virtual size_t LexerInput( char* buf, size_t max_size ); virtual void LexerOutput( const char* buf, size_t size ); virtual void LexerError( const char* msg ); void yyunput( int c, char* buf_ptr ); int yyinput(); void yy_load_buffer_state(); void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); void yy_flush_buffer( struct yy_buffer_state* b ); int yy_start_stack_ptr; int yy_start_stack_depth; int* yy_start_stack; void yy_push_state( int new_state ); void yy_pop_state(); int yy_top_state(); yy_state_type yy_get_previous_state(); yy_state_type yy_try_NUL_trans( yy_state_type current_state ); int yy_get_next_buffer(); FLEX_STD istream* yyin; // input source for default LexerInput FLEX_STD ostream* yyout; // output sink for default LexerOutput // yy_hold_char holds the character lost when yytext is formed. char yy_hold_char; // Number of characters read into yy_ch_buf. size_t yy_n_chars; // Points to current character in buffer. char* yy_c_buf_p; int yy_init; // whether we need to initialize int yy_start; // start state number // Flag which is used to allow yywrap()'s to do buffer switches // instead of setting up a fresh yyin. A bit of a hack ... int yy_did_buffer_switch_on_eof; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ void yyensure_buffer_stack(void); // The following are not always needed, but may be depending // on use of certain flex features (like REJECT or yymore()). yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; yy_state_type* yy_state_buf; yy_state_type* yy_state_ptr; char* yy_full_match; int* yy_full_state; int yy_full_lp; int yy_lp; int yy_looking_for_trail_begin; int yy_more_flag; int yy_more_len; int yy_more_offset; int yy_prev_more_offset; }; } #endif // yyFlexLexer || ! yyFlexLexerOnce �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/attribute.C���������������������������������������������������������������������0000644�0001750�0001750�00000010744�11700666272�015325� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "attribute.h" #include "util.h" #include "widget.h" Attribute::Attribute(Widget* p) : parent(p) { style_ = SOLID; width_ = 1; font_ = 2; // helvetica normal roman size_ = 10; tkfont_ = NULL; psfont_ = NULL; initFonts(); colour_ = 0xffffff; // white colorName_ = dupstr("white"); color_ = parent->getColor("white"); } Attribute::~Attribute() { if (tkfont_) Tk_FreeFont(tkfont_); if (psfont_) Tk_FreeFont(psfont_); if (colorName_) delete [] colorName_; } void Attribute::setStyle(double v) { switch ((int)v) { case SOLID: case DASH: break; default: return; } style_ = (Style)((int)v); } void Attribute::setWidth(double v) { if (v>0) width_ = v; else width_ = 1; } void Attribute::setSize(double v) { if (v >= 1) { size_ = (int)v; initFonts(); } } void Attribute::setFont(double v) { font_ = (int)v; initFonts(); } void Attribute::initFonts() { if (tkfont_) Tk_FreeFont(tkfont_); tkfont_ = NULL; if (psfont_) Tk_FreeFont(psfont_); psfont_ = NULL; WidgetOptions* opts = parent->options; ostringstream fstr; ostringstream pstr; switch (font_) { case 0: case 2: case 3: fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal roman" << ends; pstr << "helvetica " << size_ << " normal roman" << ends; break; case 1: fstr << '{' << opts->times << '}' << ' ' << size_ << " normal roman" << ends; pstr << "times " << size_ << " normal roman" << ends; break; case 4: fstr << '{' << opts->courier << '}' << ' ' << size_ << " normal roman" << ends; pstr << "courier " << size_ << " normal roman" << ends; break; case 10: case 12: case 13: fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " bold roman" << ends; pstr << "helvetica " << size_ << " bold roman" << ends; break; case 11: fstr << '{' << opts->times << '}' << ' ' << size_ << " bold roman" << ends; pstr << "times " << size_ << " bold roman" << ends; break; case 14: fstr << '{' << opts->courier << '}' << ' ' << size_ << " bold roman" << ends; pstr << "courier " << size_ << " bold roman" << ends; break; case 20: case 22: case 23: fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal italic" << ends; pstr << "helvetica " << size_ << " normal italic" << ends; break; case 21: fstr << '{' << opts->times << '}' << ' ' << size_ << " normal italic" << ends; pstr << "times " << size_ << " normal italic" << ends; break; case 24: fstr << '{' << opts->courier << '}' << ' ' << size_ << " normal italic" << ends; pstr << "courier " << size_ << " normal italic" << ends; break; case 30: case 32: case 33: fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " bold italic" << ends; pstr << "helvetica " << size_ << " bold italic" << ends; break; case 31: fstr << '{' << opts->times << '}' << ' ' << size_ << " bold italic" << ends; pstr << "times " << size_ << " bold italic" << ends; break; case 34: fstr << '{' << opts->courier << '}' << ' ' << size_ << " bold italic" << ends; pstr << "courier " << size_ << " bold italic" << ends; break; default: fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal roman" << ends; pstr << "helvetica " << size_ << " normal roman" << ends; font_ = 2; break; } tkfont_ = Tk_GetFont(parent->getInterp(), parent->getTkwin(), fstr.str().c_str()); psfont_ = Tk_GetFont(parent->getInterp(), parent->getTkwin(), pstr.str().c_str()); } void Attribute::setColour(double v) { if (v == colour_) return; if (colorName_) delete [] colorName_; colorName_ = NULL; // still provide backward compatibility for old color scheme if (v==1) colour_ = (int)0xffffff; // white else if (v==2) colour_ = (int)0xff0000; // red else if (v==3) colour_ = (int)0x00ff00; // green else if (v==4) colour_ = (int)0x0000ff; // blue else if (v==5) colour_ = (int)0x00ffff; // cyan else if (v==6) colour_ = (int)0xff00ff; // magneta else if (v==7) colour_ = (int)0xffff00; // yellow else colour_ = (int)v; ostringstream str; str << '#' << setw(6) << setfill('0') << hex << colour_ << ends; colorName_ = dupstr(str.str().c_str()); color_ = parent->getColor(str.str().c_str()); } ����������������������������./saods9/saotk/util/tkpostscript.h������������������������������������������������������������������0000644�0001750�0001750�00000005035�11700666272�016135� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" // copied from tkInt.h #ifndef MODULE_SCOPE # ifdef __cplusplus # define MODULE_SCOPE extern "C" # else # define MODULE_SCOPE extern # endif #endif // copied from tkCanvPs.c #include "../../tk8.5.9/generic/tkCanvas.h" typedef struct TkPostscriptInfo { Tk_Window tkwin; /* The canvas being printed. */ int x, y, width, height; /* Area to print, in canvas pixel * coordinates. */ int x2, y2; /* x+width and y+height. */ char *pageXString; /* String value of "-pagex" option or NULL. */ char *pageYString; /* String value of "-pagey" option or NULL. */ double pageX, pageY; /* Postscript coordinates (in points) * corresponding to pageXString and * pageYString. Don't forget that y-values * grow upwards for Postscript! */ char *pageWidthString; /* Printed width of output. */ char *pageHeightString; /* Printed height of output. */ double scale; /* Scale factor for conversion: each pixel * maps into this many points. */ Tk_Anchor pageAnchor; /* How to anchor bbox on Postscript page. */ int rotate; /* Non-zero means output should be rotated on * page (landscape mode). */ char *fontVar; /* If non-NULL, gives name of global variable * containing font mapping information. * Malloc'ed. */ char *colorVar; /* If non-NULL, give name of global variable * containing color mapping information. * Malloc'ed. */ char *colorMode; /* Mode for handling colors: "monochrome", * "gray", or "color". Malloc'ed. */ int colorLevel; /* Numeric value corresponding to colorMode: 0 * for mono, 1 for gray, 2 for color. */ char *fileName; /* Name of file in which to write Postscript; * NULL means return Postscript info as * result. Malloc'ed. */ char *channelName; /* If -channel is specified, the name of the * channel to use. */ Tcl_Channel chan; /* Open channel corresponding to fileName. */ Tcl_HashTable fontTable; /* Hash table containing names of all font * families used in output. The hash table * values are not used. */ int prepass; /* Non-zero means that we're currently in the * pre-pass that collects font information, so * the Postscript generated isn't relevant. */ int prolog; /* Non-zero means output should contain the * prolog definitions in the header. */ } TkPostscriptInfo; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/ps.h����������������������������������������������������������������������������0000644�0001750�0001750�00000006107�11745303601�014000� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __ps_h__ #define __ps_h__ #include <stdint.h> #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "zlib.h" extern int DebugGZ; // we need this large for gzip #define GZIPSIZE 65536 #define BUFSIZE GZIPSIZE*2 #define RLESIZE 128 #define LINELIMIT 80 // Filter Base Class class Filter { protected: unsigned char buf[BUFSIZE]; unsigned char* ptr; virtual void cflush() =0; virtual void eflush(ostream&) =0; public: Filter(); virtual void in(unsigned char) =0; virtual void out(ostream&) =0; void flush(ostream&); friend Filter& operator<<(Filter& f, unsigned char c) {f.in(c); return f;} friend ostream& operator<<(ostream& s, Filter& f) {f.out(s); return s;} }; // Compress Base Class class Compress : public virtual Filter { public: virtual void in(unsigned char) =0; virtual void cflush() =0; }; class NoCompress : public virtual Filter, public Compress { public: void in(unsigned char); void cflush() {} }; // RLE class RLE : public virtual Filter, public Compress { private: int state; unsigned char current; unsigned char rle[RLESIZE]; int num; void dumpNonRepeat(); void dumpRepeat(); public: RLE(); void in(unsigned char); void cflush(); }; // GZIP class GZIP : public virtual Filter, public Compress { private: z_stream* stream_; unsigned char gzip[GZIPSIZE]; unsigned long crc; int deflategz(int); void putlong(unsigned long); public: GZIP(); ~GZIP(); void in(unsigned char); void cflush(); }; // Encode Base Class class Encode : public virtual Filter { protected: int level; int lineCount; public: Encode(int); virtual void out(ostream&) =0; virtual void eflush(ostream&) =0; }; // AsciiHex class AsciiHex : public virtual Filter, public Encode { public: AsciiHex(int); void out(ostream&); void eflush(ostream&); }; // Ascii85 class Ascii85 : public virtual Filter, public Encode { private: int index; int byteswap; union { unsigned char b[4]; uint32_t c; } buf85; void dump(ostream&); int32_t swap(uint32_t* ptr); public: Ascii85(int); void out(ostream&); void eflush(ostream&); }; // PS Filters class NoCompressAsciiHex : public virtual Filter, public NoCompress, public AsciiHex { public: NoCompressAsciiHex(int l) : AsciiHex(l) {}; }; class NoCompressAscii85 : public virtual Filter, public NoCompress, public Ascii85 { public: NoCompressAscii85(int l) : Ascii85(l) {}; }; class RLEAsciiHex : public virtual Filter, public RLE, public AsciiHex { public: RLEAsciiHex(int l) : AsciiHex(l) {}; }; class RLEAscii85 : public virtual Filter, public RLE, public Ascii85 { public: RLEAscii85(int l) : Ascii85(l) {}; }; class GZIPAsciiHex : public virtual Filter, public GZIP, public AsciiHex { public: GZIPAsciiHex(int l) : AsciiHex(l) {}; }; class GZIPAscii85 : public virtual Filter, public GZIP, public Ascii85 { public: GZIPAscii85(int l) : Ascii85(l) {}; }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/gridbase.C����������������������������������������������������������������������0000644�0001750�0001750�00000023134�11756762111�015077� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "gridbase.h" #include "attribute.h" #include "widget.h" #include "rotstr.h" #include "util.h" extern "C" { #include "ast.h" #include "grf.h" } GridBase::GridBase(Widget* p) : parent_(p) { option_ = NULL; renderMode_ = X11; line_ = new Attribute(parent_); text_ = new Attribute(parent_); gc_ = NULL; pixmap_ = 0; mode_ = Widget::RGB; } GridBase::GridBase(Widget* p, const char* o) : parent_(p) { option_ = dupstr(o); renderMode_ = X11; line_ = new Attribute(parent_); text_ = new Attribute(parent_); gc_ = NULL; pixmap_ = 0; mode_ = Widget::RGB; } GridBase::~GridBase() { if (option_) delete [] option_; if (line_) delete line_; if (text_) delete text_; } int GridBase::gAttr(int which, double value, double* old, int prim) { Attribute* attr; switch (prim) { case GRF__TEXT: attr = text_; switch (which) { case GRF__STYLE: break; case GRF__WIDTH: break; case GRF__SIZE: if (old) *old = attr->size(); if (value != AST__BAD) attr->setSize(value); break; case GRF__FONT: if (old) *old = attr->font(); if (value != AST__BAD) attr->setFont(value); break; case GRF__COLOUR: if (old) *old = attr->colour(); if (value != AST__BAD) attr->setColour(value); break; } break; case GRF__LINE: attr = line_; switch (which) { case GRF__STYLE: if (old) *old = attr->style(); if (value != AST__BAD) attr->setStyle(value); break; case GRF__WIDTH: if (old) *old = attr->width(); if (value != AST__BAD) attr->setWidth(value); break; case GRF__SIZE: break; case GRF__FONT: break; case GRF__COLOUR: if (old) *old = attr->colour(); if (value != AST__BAD) attr->setColour(value); break; } break; } return 1; } int GridBase::gCap(int cap, int value) { switch (cap) { case GRF__SCALES: return 0; case GRF__MJUST: return 1; case GRF__ESC: return 0; } } // X11 Render functions int GridBase::x11Line(int n, float* x, float* y) { if (n<2 || !x || !y) return 1; XSetForeground(parent_->getDisplay(), gc_, line_->color()); int w = (int)line_->width(); if (w<1) w = 1; switch (line_->style()) { case Attribute::SOLID: XSetLineAttributes(parent_->getDisplay(), gc_, w, LineSolid, CapButt, JoinMiter); break; case Attribute::DASH: XSetLineAttributes(parent_->getDisplay(), gc_, w, LineOnOffDash, CapButt, JoinMiter); char dlist[] = {8,3}; XSetDashes(parent_->getDisplay(), gc_, 0, dlist, 2); break; } for (int i=0; i<n-1; i++) { Vector s = Vector(x[i],y[i]).round(); Vector e = Vector(x[i+1],y[i+1]).round(); XDrawLine(parent_->getDisplay(), pixmap_, gc_, (int)s[0],(int)s[1],(int)e[0],(int)e[1]); } return 1; } int GridBase::x11Text(const char* txt, float x, float y, const char* just, Vector up) { XSetFont(parent_->getDisplay(), gc_, Tk_FontId(text_->tkfont())); XSetForeground(parent_->getDisplay(), gc_, text_->color()); Vector vv = Vector(x,y); double angle = calcTextAngle(just, up); Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); #if !(_WIN32 || _MACOSX) XDrawRotString(parent_->getDisplay(), pixmap_, gc_, cc, angle, txt, text_->tkfont(), parent_); #else XDrawRotString(parent_->getDisplay(), pixmap_, gc_, cc, angle, txt); #endif return 1; } // PS Render functions int GridBase::psLine(int n, float* x, float* y) { if (n<2 || !x || !y) return 1; psColor(line_); { ostringstream str; str << line_->width() << " setlinewidth" << endl << ends; Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); } { ostringstream str; switch (line_->style()) { case Attribute::SOLID: str << "[] 0 setdash" << endl << ends; break; case Attribute::DASH: str << "[8 3] 0 setdash" << endl << ends; break; } Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); } for (int i=0; i<n; i++) { Vector v = Vector(x[i],y[i]) * matrix_; ostringstream str; if (i == 0) { str << "newpath " << endl; str << v.TkCanvasPs(parent_->getCanvas()) << " moveto" << endl << ends; } else str << v.TkCanvasPs(parent_->getCanvas()) << " lineto" << endl << ends; Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); } ostringstream str; str << "stroke" << endl << ends; Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); return 1; } int GridBase::psText(const char* txt, float x, float y, const char* just, Vector up) { Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(text_->psfont(), &psdstr) * parent_->getDisplayRatio(); Vector vv = Vector(x,y) * matrix_; double angle = calcTextAngle(just, up); Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->psfont()); ostringstream str; const char* ff = Tk_NameOfFont(text_->psfont()); str << '/' << psFontName(ff) << " findfont " << int(psFontSize(ff)*parent_->getDisplayRatio()) << " scalefont setfont" << endl; psColor(text_); str << "gsave " << cc.TkCanvasPs(parent_->getCanvas()) << " moveto" << endl << radToDeg(angle) << " rotate " << '(' << psQuote(txt) << ')' << " show" << " grestore" << endl << ends; Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); return 1; } void GridBase::psColor(Attribute* attr) { ostringstream str; switch ((Widget::PSColorSpace)mode_) { case Widget::BW: case Widget::GRAY: psColorGray(parent_->getXColor(attr->colorName()), str); str << " setgray"; break; case Widget::RGB: psColorRGB(parent_->getXColor(attr->colorName()), str); str << " setrgbcolor"; break; case Widget::CMYK: psColorCMYK(parent_->getXColor(attr->colorName()), str); str << " setcmykcolor"; break; } str << endl << ends; Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); } #ifdef _MACOSX int GridBase::macosxLine(int n, float* x, float* y) { if (n<2 || !x || !y) return 1; macosxColor(parent_->getXColor(line_->colorName())); macosxWidth(line_->width()); switch (line_->style()) { case Attribute::SOLID: macosxDash(NULL,0); break; case Attribute::DASH: float dlist[] = {8,3}; macosxDash(dlist,2); break; } Vector v[n]; for (int i=0; i<n; i++) v[i] = Vector(x[i],y[i]) * matrix_; macosxDrawLines(v, n); return 1; } int GridBase::macosxText(const char* txt, float x, float y, const char* just, Vector up) { // change this later Tcl_DString psdstr; Tcl_DStringInit(&psdstr); int psSize = Tk_PostscriptFontName(text_->tkfont(), &psdstr); macosxFont(Tcl_DStringValue(&psdstr),psSize); Tcl_DStringFree(&psdstr); Vector vv = Vector(x,y) * matrix_; double angle = calcTextAngle(just, up); Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); macosxColor(parent_->getXColor(text_->colorName())); macosxDrawText(cc, angle, txt); return 1; } #endif #ifdef _WIN32 int GridBase::win32Line(int n, float* x, float* y) { if (n<2 || !x || !y) return 1; win32Color(parent_->getXColor(line_->colorName())); win32Width(line_->width()); switch (line_->style()) { case Attribute::SOLID: win32Dash(NULL,0); break; case Attribute::DASH: float dlist[] = {8,3}; win32Dash(dlist,2); break; } Vector v[n]; for (int i=0; i<n; i++) v[i] = Vector(x[i],y[i]) * matrix_; win32DrawLines(v, n); return 1; } int GridBase::win32Text(const char* txt, float x, float y, const char* just, Vector up) { win32Font(text_->tkfont()); win32Color(parent_->getXColor(text_->colorName())); Vector vv = Vector(x,y) * matrix_; double angle = calcTextAngle(just, up);; Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); win32DrawText(cc, angle, txt); return 1; } #endif // Support double GridBase::calcTextAngle(const char* just, Vector up) { double a = up.angle(); // our angle is 90 off from ast's, and the other direction double rr = -(a - M_PI_2); // special case for text rotated exactly 90 if (up[0]==-1 && up[1]==0) rr += M_PI; // normalize if (rr>0) while (rr>M_TWOPI) rr -= M_TWOPI; else while (rr<0) rr += M_TWOPI; return rr; } Matrix GridBase::calcTextPos(const Vector& vv, double angle, const char* txt, const char* just, Vector up, Tk_Font font) { Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int width = Tk_TextWidth(font, txt, strlen(txt)); Matrix m1,m2; switch (just[0]) { case 'T': break; case 'C': m1 = Translate(0,metrics.linespace/2); break; case 'B': m1 = Translate(0,metrics.ascent); break; case 'M': m1 = Translate(0,metrics.linespace); break; } switch (just[1]) { case 'L': break; case 'C': m2 = Translate(-width/2.,0); break; case 'R': m2 = Translate(-width,0); break; } Matrix rr = Translate(-vv) * Rotate(-angle) * m1 * m2 * Rotate(angle) * Translate(vv); // special case for text rotated exactly 90 Matrix mm; if (up[0] == -1 && up[1] == 0) { Vector cc = vv*rr; mm = Translate(-cc) * Rotate(-angle) * Translate(-width/2.,metrics.linespace/2.) * FlipY() * Translate(width/2.,-metrics.linespace/2.) * Rotate(angle) * Translate(cc); } return rr*mm; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/grid2dbase.C��������������������������������������������������������������������0000644�0001750�0001750�00000006524�12001327766�015326� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "grid2dbase.h" #include "attribute.h" #include "widget.h" extern "C" { #include "ast.h" #include "grf.h" } Grid2dBase* astGrid2dPtr = NULL; Grid2dBase::Grid2dBase(Widget* p) : GridBase(p) {} Grid2dBase::Grid2dBase(Widget* p, const char* o) : GridBase(p,o) {} Grid2dBase::~Grid2dBase() {} int Grid2dBase::gLine(int n, float* x, float* y) { switch (renderMode_) { case X11: x11Line(n,x,y); break; case PS: psLine(n,x,y); break; #ifdef _MACOSX case MACOSX: macosxLine(n,x,y); break; #endif #ifdef _WIN32 case GWIN32: win32Line(n,x,y); break; #endif } return 1; } int Grid2dBase::gQch(float* chv, float* chh) { Tk_Font font =NULL; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } if (font) { Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); *chv = (float)metrics.linespace; *chh = (float)metrics.linespace; return 1; } else { *chv = *chh = 0; return 0; } } int Grid2dBase::gText(const char* txt, float x, float y, const char* just, float upx, float upy) { if (!(txt && txt[0] && just && just[0] && just[1])) return 0; switch (renderMode_) { case X11: return x11Text(txt,x,y,just,Vector(upx,upy)); case PS: return psText(txt,x,y,just,Vector(upx,upy)); #ifdef _MACOSX case MACOSX: return macosxText(txt,x,y,just,Vector(upx,upy)); #endif #ifdef _WIN32 case GWIN32: return win32Text(txt,x,y,just,Vector(upx,upy)); #endif } return 0; } int Grid2dBase::gTxExt(const char* txt, float x, float y, const char* just, float upx, float upy, float* xb, float* yb) { if (!(txt && txt[0] && just)) { xb[0] = xb[1] = xb[2] = xb[3] = 0; yb[0] = yb[1] = yb[2] = yb[3] = 0; return 0; } Tk_Font font; switch (renderMode_) { case X11: font = text_->tkfont(); break; case PS: font = text_->psfont(); break; #ifdef _MACOSX case MACOSX: font = text_->tkfont(); break; #endif #ifdef _WIN32 case GWIN32: font = text_->tkfont(); break; #endif } Vector vv = Vector(x,y); double angle = calcTextAngle(just, Vector(upx, upy)); Vector cc = vv * calcTextPos(vv, angle, txt, just, Vector(upx, upy), font); Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int width = Tk_TextWidth(font, txt, strlen(txt)); BBox nn = BBox(Vector(0,-metrics.descent), Vector(width,metrics.ascent)); BBox bb = nn * Rotate(angle) * Translate(cc); xb[0] = bb.ll[0]; yb[0] = bb.ll[1]; xb[1] = bb.ur[0]; yb[1] = bb.ll[1]; xb[2] = bb.ur[0]; yb[2] = bb.ur[1]; xb[3] = bb.ll[0]; yb[3] = bb.ur[1]; return 1; } int Grid2dBase::gScales(float* alpha, float* beta) { /* *alpha = float(DisplayWidthMM(parent_->getDisplay(),parent_->screenNumber)) / float(DisplayWidth(parent_->getDisplay(),parent_->screenNumber)); *beta = float(DisplayHeightMM(parent_->getDisplay(),parent_->screenNumber)) / float(DisplayHeight(parent_->getDisplay(),parent_->screenNumber)); */ return 1; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/fuzzy.h�������������������������������������������������������������������������0000644�0001750�0001750�00000002004�11700666272�014544� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __fuzzy_h__ #define __fuzzy_h__ #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <float.h> inline void tzero(double* ff, const double epsilon= DBL_EPSILON) {if (*ff>=-epsilon && *ff<=epsilon) *ff = 0;} inline bool teq(const double f1, const double f2, const double epsilon= DBL_EPSILON) {return f1-f2 >= -epsilon && f1-f2 <= epsilon;} inline bool tlt(const double f1, const double f2, const double epsilon= DBL_EPSILON) {return f1-f2 < -epsilon;} inline bool tle(const double f1, const double f2, const double epsilon= DBL_EPSILON) {return f1-f2 <= -epsilon; } inline bool tgt(const double f1, const double f2, const double epsilon= DBL_EPSILON) {return f1-f2 > epsilon;} inline bool tge(const double f1, const double f2, const double epsilon= DBL_EPSILON) {return f1-f2 >= epsilon;} #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/ps.C����������������������������������������������������������������������������0000644�0001750�0001750�00000015037�11745303601�013735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <string.h> #include "ps.h" #include "util.h" Filter::Filter() { ptr = buf; } void Filter::flush(ostream& str) { cflush(); eflush(str); } // Compress void NoCompress::in(unsigned char c) { *ptr++ = c; } // RLE RLE::RLE() { state = 0; num = 0; } void RLE::in(unsigned char c) { current = c; switch (state) { case 0: // start state if (num == 0) // not enough info yet rle[num++] = current; else { if (current != rle[num-1]) { // looks like non repeating rle[num++] = current; state = 1; } else { // looks like repeating num++; state = 2; } } break; case 1: // non repeat state if (current != rle[num-1]) { rle[num++] = current; if (num >= RLESIZE) { // time to dump the rlefer dumpNonRepeat(); // dump the buffer num = 0; // and reset counter state = 0; } } else { num--; // decr dumpNonRepeat(); // dump the buffer state = 2; // repeat state rle[0] = current; // save repeat char num = 2; // we aready have two now } break; case 2: // repeat state if (current == rle[0]) { if (++num >= RLESIZE) { dumpRepeat(); // dump the repeat count state = 0; num = 0; } } else { dumpRepeat(); // dump the repeat count state = 1; // back to non repeat state rle[0] = current; // save first char num = 1; // we have one now } break; } } void RLE::dumpNonRepeat() { if (num) { *ptr++ = (unsigned char)(num-1); for (int i=0; i<num; i++) *ptr++ = rle[i]; } } void RLE::dumpRepeat() { if (num) { *ptr++ = (unsigned char)(257-num); *ptr++ = rle[0]; } } void RLE::cflush() { switch (state) { case 0: case 1: dumpNonRepeat(); break; case 2: dumpRepeat(); break; } } // GZIP GZIP::GZIP() { stream_ = new z_stream; crc = crc32(0L, Z_NULL, 0); stream_->next_in = NULL; stream_->avail_in = 0; stream_->next_out = NULL; stream_->avail_out = 0; stream_->zalloc = NULL; stream_->zfree = NULL; stream_->opaque = NULL; if (deflateInit(stream_, Z_DEFAULT_COMPRESSION) != Z_OK) { if (DebugGZ) cerr << "deflateInit error" << endl; return; } stream_->next_out = gzip; stream_->avail_out = GZIPSIZE; } GZIP::~GZIP() { if (deflateEnd(stream_) != Z_OK) if (DebugGZ) cerr << "deflateEnd error" << endl; if (stream_) delete stream_; } void GZIP::in(unsigned char c) { stream_->next_in = &c; stream_->avail_in = 1; while (stream_->avail_in > 0 && deflategz(Z_NO_FLUSH) == Z_OK); // update crc crc = crc32(crc, (const Bytef *)&c, 1); } void GZIP::cflush() { // flush any pending output while (deflategz(Z_FINISH) == Z_OK); // output crc/length putlong(crc); putlong(stream_->total_in); } int GZIP::deflategz(int flush) { int result = deflate(stream_, flush); switch (result) { case Z_OK: if (DebugGZ) cerr << "deflate OK: avail_in " << stream_->avail_in << " avail_out " << stream_->avail_out << endl; break; case Z_STREAM_END: if (DebugGZ) cerr << "deflate STRM_END: avail_in " << stream_->avail_in << " avail_out " << stream_->avail_out << endl; break; default: if (DebugGZ) cerr << "deflate Error " << result << endl; return result; } if (stream_->avail_out == 0 || result != Z_OK) { int s = GZIPSIZE - stream_->avail_out; unsigned char* d = gzip; if (s>0) { if (ptr+s > buf+BUFSIZE) { cerr << "deflate buffer overflow " << stream_->avail_out << ' ' << result << endl; return result; } memcpy(ptr,d,s); ptr += s; if (DebugGZ) cerr << "deflate send " << s << ' ' << result << endl; } stream_->next_out = gzip; stream_->avail_out = GZIPSIZE; } return result; } void GZIP::putlong(unsigned long l) { // dump in LSB order for (int n = 0; n < 4; n++) { unsigned char foo = (int)(l & 0xff); memcpy(ptr,&foo,1); ptr++; l >>= 8; } } // Encode Encode::Encode(int l) { level = l; lineCount = 0; } // AsciiHex AsciiHex::AsciiHex(int l) : Encode(l) {} void AsciiHex::out(ostream& str) { unsigned char* p = buf; while (p < ptr) { unsigned short c = *p++; str << hex << setfill('0') << setw(2) << c; lineCount += 2; if (lineCount >= LINELIMIT) { str << endl; lineCount = 0; } } ptr = buf; // reset buffer } void AsciiHex::eflush(ostream& str) { out(str); switch (level) { case 1: str << endl << ends; break; case 2: case 3: str << endl << '>' << endl << ends; break; } } // Ascii85 Ascii85::Ascii85(int l) : Encode(l) { byteswap = (*(short *)"\001\000" & 0x0001); buf85.c = 0; index = 0; } int32_t Ascii85::swap(uint32_t* p) { int32_t r; swap4((char*)p, (char*)&r); return r; } void Ascii85::out(ostream& str) { unsigned char* p = buf; while (p < ptr) { buf85.b[index++] = *p++; if (index==4) { dump(str); } } ptr = buf; // reset buffer } void Ascii85::dump(ostream& str) { // all zeros? if (buf85.c == 0) { str << 'z'; if (++lineCount >= LINELIMIT) { str << endl; lineCount = 0; } } else { uint32_t b; if (!byteswap) b = buf85.c; else b = swap(&buf85.c); for (int ii=4; ii>=0 ; ii--) { uint32_t base = 1; for (int jj=0; jj<ii; jj++) base *= 85; uint32_t a = b / base; b -= a * base; str << (char)(a + '!'); if (++lineCount >= LINELIMIT) { str << endl; lineCount = 0; } } } index = 0; buf85.c = 0; } void Ascii85::eflush(ostream& str) { // dump the remainder out(str); // we can't have any z's here // also, only write index+1 chars if (index) { uint32_t b; if (!byteswap) b = buf85.c; else b = swap(&buf85.c); for (int ii=4; ii>=(4-index); ii--) { uint32_t base = 1; for (int jj=0; jj<ii; jj++) base *= 85; uint32_t a = b / base; b -= a * base; str << (char)(a + '!'); if (++lineCount >= LINELIMIT) { str << endl; lineCount = 0; } } } index = 0; buf85.c = 0; switch (level) { case 1: str << endl << ends; break; case 2: case 3: str << endl << "~>" << endl << ends; break; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/util/util.C��������������������������������������������������������������������������0000644�0001750�0001750�00000020533�11750561001�014261� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "util.h" #ifdef _MACOSX void macosxGetMasks(long*,long*,long*); #endif // Error in mapping int maperr= 0; static char tobuf[1024]; int sexSign; // used by parser and lex to indicate sign of dms or hms void swap2(char* src, char* dest) { *(dest ) = *(src+1); *(dest+1) = *(src ); } void swap4(char* src, char* dest) { *(dest ) = *(src+3); *(dest+1) = *(src+2); *(dest+2) = *(src+1); *(dest+3) = *(src ); } void swap8(char* src, char* dest) { *(dest ) = *(src+7); *(dest+1) = *(src+6); *(dest+2) = *(src+5); *(dest+3) = *(src+4); *(dest+4) = *(src+3); *(dest+5) = *(src+2); *(dest+6) = *(src+1); *(dest+7) = *(src ); } int lsb() { return (*(short *)"\001\000" & 0x0001); } char* dupstr(const char* str) { char* copy; if (str) { copy=new char[strlen(str)+1]; strcpy(copy,str); } else copy=NULL; return copy; } char* trim(const char* str) { char* rr = dupstr(str); char* ptr = rr; while (ptr && *ptr) ptr++; ptr--; while (ptr && (*ptr == ' ')) ptr--; ptr++; *ptr = NULL; return rr; } char* toLower(const char* str) { char* rr = dupstr(str); char* ptr = rr; while (*ptr) { *ptr = (char)(tolower(((int)(*ptr)))); ptr++; } return rr; } char* toUpper(const char* str) { char* rr = dupstr(str); char* ptr = rr; while (*ptr) { *ptr = (char)(toupper(((int)(*ptr)))); ptr++; } return rr; } char* toConstLower(const char* str) { strncpy(tobuf,str,1024); char* ptr = tobuf; while (*ptr) { *ptr = (char)(tolower(((int)(*ptr)))); ptr++; } return tobuf; } char* toConstUpper(const char* str) { strncpy(tobuf,str,1024); char* ptr = tobuf; while (*ptr) { *ptr = (char)(toupper(((int)(*ptr)))); ptr++; } return tobuf; } double zeroTWOPI(double aa) { double rr = aa; if (rr>0) while (rr>=M_TWOPI) rr -= M_TWOPI; else while (rr<0) rr += M_TWOPI; return rr; } double zero360(double aa) { double rr = aa; if (rr>=0) while (rr>360) rr -= 360; else while (rr<0) rr += 360; return rr; } double m180To180(double aa) { // incoming 0-360 double rr = aa; if (rr>180) rr -= 360; return rr; } double degToRad(double dd) { double rr = M_PI*dd/180.; return zeroTWOPI(rr); } double radToDeg(double rr) { double dd = 180.*rr/M_PI; return zero360(dd); } double dmsToDegree(int sign, int degree, int min, double sec) { // sign is needed because of -00 vs +00 return double(sign) * (abs(degree) + (min/60.) + (sec/60./60.)); } double parseSEXStr(const char* d) { char* dms = dupstr(d); // its going to get clobbered char* ptr = dms; int sign = 1; int degree = atoi(strtok(ptr,":")); int minute = atoi(strtok(NULL,":")); float sec = atof(strtok(NULL,":")); // assumes the minus sign is the first char if (degree != 0) sign = degree>0 ? 1 : -1; else sign = d[0] == '-' ? -1 : 1; delete [] dms; return dmsToDegree(sign,abs(degree),minute,sec); } double parseHMSStr(const char* str) { char* hms = dupstr(str); // its going to get clobbered char* ptr = hms; int sign = 1; int hour = atoi(strtok(ptr,"h")); int minute = atoi(strtok(NULL,"m")); float second = atof(strtok(NULL,"s")); // assumes the minus sign is the first char if (hour != 0) sign = hour>0 ? 1 : -1; else sign = str[0] == '-' ? -1 : 1; delete [] hms; return dmsToDegree(sign,abs(hour),minute,second)/24.*360.; } double parseDMSStr(const char* str) { char* dms = dupstr(str); // its going to get clobbered char* ptr = dms; int sign = 1; int degree = atoi(strtok(ptr,"d")); int minute = atoi(strtok(NULL,"m")); float sec = atof(strtok(NULL,"s")); // assumes the minus sign is the first char if (degree != 0) sign = degree>0 ? 1 : -1; else sign = str[0] == '-' ? -1 : 1; delete [] dms; return dmsToDegree(sign,abs(degree),minute,sec); } double RGB2Gray(double red, double green, double blue) { return 0.30*red + 0.59*green + 0.11*blue; } unsigned char RGB2Gray(unsigned char red, unsigned char green, unsigned char blue) { // we have a round off problem here, add FLT_EPSILON to kick it over return (unsigned char)(0.30*red + 0.59*green + 0.11*blue + FLT_EPSILON); } void RGB2CMYK(unsigned char red, unsigned char green, unsigned char blue, unsigned char* cyan, unsigned char* magenta, unsigned char* yellow, unsigned char* black) { // convert To CMY *cyan = UCHAR_MAX-red; *magenta = UCHAR_MAX-green; *yellow = UCHAR_MAX-blue; *black =0; // determine black *black = UCHAR_MAX; if (*cyan < *black) *black = *cyan; if (*magenta < *black) *black = *magenta; if (*yellow < *black) *black = *yellow; // substract out black *cyan -= *black; *magenta -= *black; *yellow -= *black; } void RGB2CMYK(unsigned short red, unsigned short green, unsigned short blue, unsigned short* cyan, unsigned short* magenta, unsigned short* yellow, unsigned short* black) { // convert To CMY *cyan = USHRT_MAX-red; *magenta = USHRT_MAX-green; *yellow = USHRT_MAX-blue; *black =0; // determine black *black = USHRT_MAX; if (*cyan < *black) *black = *cyan; if (*magenta < *black) *black = *magenta; if (*yellow < *black) *black = *yellow; // substract out black *cyan -= *black; *magenta -= *black; *yellow -= *black; } ostream& psColorGray(XColor* clr, ostream& str) { if (clr) { float red = clr->red/float(USHRT_MAX); float green = clr->green/float(USHRT_MAX); float blue = clr->blue/float(USHRT_MAX); str << dec << RGB2Gray(red,green,blue); } return str; } ostream& psColorRGB(XColor* clr, ostream& str) { if (clr) { float red = clr->red/float(USHRT_MAX); float green = clr->green/float(USHRT_MAX); float blue = clr->blue/float(USHRT_MAX); str << dec << red << ' ' << green << ' ' << blue; } return str; } ostream& psColorCMYK(XColor* clr, ostream& str) { if (clr) { unsigned short cyan; unsigned short magenta; unsigned short yellow; unsigned short black; RGB2CMYK(clr->red, clr->green, clr->blue, &cyan, &magenta, &yellow, &black); str << dec << cyan/float(USHRT_MAX) << ' ' << magenta/float(USHRT_MAX) << ' ' << yellow/float(USHRT_MAX) << ' ' << black/float(USHRT_MAX); } return str; } char* psStr = NULL; // psQuote returned string char* psQuote(const char* str) { // we must must quote '(', ')', and '\' if (psStr) delete [] psStr; psStr = new char[strlen(str)*2+1]; // worst case size char* out = psStr; const char* in = str; while (in && *in) { if (*in == '(' || *in == ')' || *in == '\\') *out++ = '\\'; *out++ = *in++; } *out++ = '\0'; // terminating char return psStr; } const char* psFontName(const char* font) { char* str = (char*)font; char* ff = str; while (*str && *str++ != ' '); char* zz = str; while (*str && *str++ != ' '); char* ww = str; while (*str && *str++ != ' '); char* ss = str; if (ff && ww && ss) return psFontName(ff,ww,ss); else return psFonts[0]; } int psFontSize(const char* font) { char* str = (char*)font; while (*str && *str++ != ' '); return atoi(str); } const char* psFontName(const char* font, const char* weight, const char* slant) { int ptr = 0; if (!strncmp(font,"helvetica",4)) ptr = 0; else if (!strncmp(font,"times",4)) ptr = 4; else if (!strncmp(font,"courier",4)) ptr = 8; if (!strncmp(weight,"normal",4)) ; else if (!strncmp(weight,"bold",4)) ptr +=2; if (!strncmp(slant,"roman",4)) ; else if (!strncmp(slant,"italic",4)) ptr++; return psFonts[ptr]; } int fCompare(const void* a, const void* b) { float* aa = (float*)a; float* bb = (float*)b; if (*aa < *bb) return -1; if (*aa > *bb) return 1; return 0; } int dCompare(const void* a, const void* b) { double* aa = (double*)a; double* bb = (double*)b; if (*aa < *bb) return -1; if (*aa > *bb) return 1; return 0; } Vector mapLen(const Vector& v, const Matrix& mx) { // remove translation Vector t = Vector() * mx; Matrix sr = mx * Translate(-t); // remove rotation Vector r = Vector(1,0) * sr; Matrix s = sr * Rotate(r.angle()); // all that is left is Scaling return (v*s).abs(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/���������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012756� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frblock.html���������������������������������������������������������������������0000644�0001750�0001750�00000012263�07001716532�015306� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame FITS Binary Table Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame FITS Binary Table Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#block factor">block factor</a></font></li> <li> <font face="Arial,Helvetica"><a href="#block function">block function</a></font></li> <li> <font face="Arial,Helvetica"><a href="#block buffer size">block buffer size</a></font></li> <li> <font face="Arial,Helvetica"><a href="#block to fit">block to fit</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get block factor">get block factor</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get block function">get block function</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get block buffer size">get block buffer size</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get block cursor">get block cursor</a></font></li> <li> <font face="Arial,Helvetica"><a href="#has block">has block</a></font></li> </blockquote> <h3> <a NAME="block factor"></a><font face="Arial,Helvetica">block factor</font></h3> <font face="Arial,Helvetica">Set the current blocking factor. It does not have to be an integer.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>block factor</b> numeric</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>block factor to</b> numeric</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>block factor to</b> numeric <b>about</b> <a href="frame.html#coordinate">coordinate</a> # in physical coordinates</font> <br><tt>Example: block factor 4</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block factor to 2</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block factor to 2 about 100 100</tt></blockquote> <blockquote> <h3> <a NAME="block function"></a><font face="Arial,Helvetica">block function</font></h3> <font face="Arial,Helvetica">Set the current blocking mode.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>block function</b> [average | sum]</font> <br><tt>Example: block function sum</tt> <h3> <a NAME="block buffer size"></a><font face="Arial,Helvetica">block buffer size</font></h3> <font face="Arial,Helvetica">Set the current blocking buffer size.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>block buffer size</b> integer</font> <br><tt>Example: block buffer size 1024</tt> <h3> <a NAME="block to fit"></a><font face="Arial,Helvetica">block to fit</font></h3> <font face="Arial,Helvetica">Set the current blocking factor such that the entire image will fit the current frame size. The blocking factor will be rounded up to the next power of 2.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>block to fit</b></font> <br><tt>Example: block to fit</tt> <h3> <a NAME="get block factor"></a><font face="Arial,Helvetica">get block factor</font></h3> <font face="Arial,Helvetica">Return the current blocking factor.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>block factor </b><a href="frame.html#precision">precision</a></font> <br><tt>Example: get block factor default</tt> <h3> <a NAME="get block function"></a><font face="Arial,Helvetica">get block function</font></h3> <font face="Arial,Helvetica">Return the current blocking function. A value of </font><font face="Courier New,Courier">AVERAGE</font><font face="Arial,Helvetica"> or </font><font face="Courier New,Courier">SUM</font><font face="Arial,Helvetica"> is returned.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>block function</b></font> <br><tt>Example: get block function</tt> <h3> <a NAME="get block buffer size"></a><font face="Arial,Helvetica">get block buffer size</font></h3> <font face="Arial,Helvetica">Return the current blocking buffer size.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>block buffer size</b></font> <br><tt>Example: get block buffer size</tt> <h3> <a NAME="get block cursor"></a><font face="Arial,Helvetica">get block cursor</font></h3> <font face="Arial,Helvetica">Return the coordinate in physical coordinates that is the center of the blocking operation.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>block cursor</b></font> <br><tt>Example: get block cursor</tt> <h3> <a NAME="has block"></a><font face="Arial,Helvetica">has block</font></h3> <font face="Arial,Helvetica">Return true if FITS is a binary table</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>has block</b></font> <br><tt>Example: has block</tt></blockquote> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frscale.html���������������������������������������������������������������������0000644�0001750�0001750�00000023251�07001716533�015303� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Scale Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Scale Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#clip scope">clip scope</a></font></li> <li> <font face="Arial,Helvetica"><a href="#clip mode">clip mode</a></font></li> <li> <font face="Arial,Helvetica"><a href="#clip minmax">clip minmax</a></font></li> <li> <font face="Arial,Helvetica"><a href="#clip user">clip user</a></font></li> <li> <font face="Arial,Helvetica"><a href="#clip zscale">clip zscale</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip">get clip</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip scope">get clip scope</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip mode">get clip mode</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip minmax">get clip minmax</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip user">get clip user</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get clip zscale">get clip zscale</a></font></li> <li> <font face="Arial,Helvetica"><a href="#has datamin">has datamin</a></font></li> <li> <font face="Arial,Helvetica"><a href="#has irafmin">has irafmin</a></font></li> </blockquote> <h3> <a NAME="clip scope"></a><font face="Arial,Helvetica">clip scope</font></h3> <font face="Arial,Helvetica">Set the scope of clip parameters. This only affects mosaics. The value of </font><font face="Courier New,Courier">LOCAL</font><font face="Arial,Helvetica"> implies each mosaic segment has its own clip values. The value of </font><font face="Courier New,Courier">GLOBAL</font><font face="Arial,Helvetica"> implies a max and min of the current clip values of each segment.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; clip scope [local | global]</font> <br><tt>Example: clip scope local</tt> <h3> <a NAME="clip mode"></a><font face="Arial,Helvetica">clip mode</font></h3> <font face="Arial,Helvetica">Set the current clipping algorithm. </font><font face="Courier New,Courier">MINMAX</font><font face="Arial,Helvetica"> uses the min and max values of the image to set the clip low and high values. </font><font face="Courier New,Courier">ZSCALE</font><font face="Arial,Helvetica"> uses the IRAF zscale algorithm to determine the values. </font><font face="Courier New,Courier">USER</font><font face="Arial,Helvetica"> allows the user to set the values.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; clip mode [minmax | zscale | user]</font> <br><tt>Example: clip mode zscale</tt> <h3> <a NAME="clip minmax"></a><font face="Arial,Helvetica">clip minmax</font></h3> <font face="Arial,Helvetica">Set the clip algorithm MINMAX parameters. If the minmax mode is </font><font face="Courier New,Courier">SCAN</font><font face="Arial,Helvetica">, the entire image is scanned. A value of </font><font face="Courier New,Courier">SAMPLE</font><font face="Arial,Helvetica"> implies the image is sampled at a specified increment. A value of </font><font face="Courier New,Courier">DATAMIN</font><font face="Arial,Helvetica"> implies, the keywords </font><font face="Courier New,Courier">DATAMIN</font><font face="Arial,Helvetica"> and </font><font face="Courier New,Courier">DATAMAX</font><font face="Arial,Helvetica"> are used. A value of </font><font face="Courier New,Courier">IRAFMIN</font><font face="Arial,Helvetica"> implies the keywords </font><font face="Courier New,Courier">IRAFMIN</font><font face="Arial,Helvetica"> and </font><font face="Courier New,Courier">IRAFMAX</font><font face="Arial,Helvetica"> are used.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>clip minmax mode</b> [scan | sample | datamin | irafmin] # set min max mode</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>clip minmax param</b> integer # set min max sample increment</font> <br><tt>Example: clip minmax mode scan</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clip minmax param 10</tt> <h3> <a NAME="clip user"></a><font face="Arial,Helvetica">clip user</font></h3> <font face="Arial,Helvetica">Set the clip values.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>clip user </b>numeric numeric</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>clip user low</b> numeric</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>clip user high</b> numeric</font> <br><tt>Example: clip user 1 1000</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clip user low 1</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clip user high 1000</tt> <h3> <a NAME="clip zscale"></a><font face="Arial,Helvetica">clip zscale</font></h3> <font face="Arial,Helvetica">Set the zscale parameter values. The arguments are contrast, sample size, and sample line.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>clip zscale param</b> numeric integer integer</font> <br><tt>Example: clip zscale param .25 600 120</tt> <h3> <a NAME="get clip"></a><font face="Arial,Helvetica">get clip</font></h3> <font face="Arial,Helvetica">Return the current clip values low high.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip </b><a href="frame.html#precision">precision</a></font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get clip <a href="frame.html#canvas coordinate system">canvas coordinate system</a> <a href="frame.html#coordinate">coordinate</a> <a href="frame.html#precision">precision</a></font> <br><tt>Example: get clip default</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get clip canvas 100 100 default</tt> <h3> <a NAME="get clip scope"></a><font face="Arial,Helvetica">get clip scope</font></h3> <font face="Arial,Helvetica">Return the current clipping scope. A value of </font><font face="Courier New,Courier">LOCAL</font><font face="Arial,Helvetica"> or </font><font face="Courier New,Courier">GLOBAL</font><font face="Arial,Helvetica"> is returned.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip scope</b></font> <br><tt>Example: get clip scope</tt> <h3> <a NAME="get clip mode"></a><font face="Arial,Helvetica">get clip mode</font></h3> <font face="Arial,Helvetica">Return the current clipping mode. A value of </font><font face="Courier New,Courier">MINMAX</font><font face="Arial,Helvetica">, </font><font face="Courier New,Courier">ZSCALE</font><font face="Arial,Helvetica">, or </font><font face="Courier New,Courier">USER</font><font face="Arial,Helvetica"> is returned.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip mode</b></font> <br><tt>Example: get clip mode</tt> <h3> <a NAME="get clip minmax"></a><font face="Arial,Helvetica">get clip minmax</font></h3> <font face="Arial,Helvetica">Return the current minmax parameters.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip minmax mode </b># returns one of </font><font face="Courier New,Courier">SCAN</font><font face="Arial,Helvetica">, </font><font face="Courier New,Courier">SAMPLE</font><font face="Arial,Helvetica">, </font><font face="Courier New,Courier">DATAMIN</font><font face="Arial,Helvetica">, or </font><font face="Courier New,Courier">IRAFMIN</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>get clip minmax param </b># returns the sample increment value</font> <br><font face="Arial,Helvetica">Example: get clip minmax mode</font> <h3> <a NAME="get clip user"></a><font face="Arial,Helvetica">get clip user</font></h3> <font face="Arial,Helvetica">Return the current user parameters of low and high.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip user</b></font> <br><tt>Example: get clip user</tt> <h3> <a NAME="get clip zscale"></a><font face="Arial,Helvetica">get clip zscale</font></h3> <font face="Arial,Helvetica">Return the current zscale parameters of contrast, sample size, sample line</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get clip zscale</b></font> <br><tt>Example: get clip zscale</tt> <h3> <a NAME="has datamin"></a><font face="Arial,Helvetica">has datamin</font></h3> <font face="Arial,Helvetica">Returns true if keywords </font><font face="Courier New,Courier">DATAMIN</font><font face="Arial,Helvetica"> and </font><font face="Courier New,Courier">DATAMAX</font><font face="Arial,Helvetica"> are available</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; has datamin</font> <br><tt>Example: has datamin</tt> <h3> <a NAME="has irafmin"></a><font face="Arial,Helvetica">has irafmin</font></h3> <font face="Arial,Helvetica">Returns true if keywords </font><font face="Courier New,Courier">IRAFMIN</font><font face="Arial,Helvetica"> and </font><font face="Courier New,Courier">IRAFMAX</font><font face="Arial,Helvetica"> are available</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; has irafmin</font> <br><tt>Example: has irafmin</tt> <br><tt></tt>&nbsp; <br><tt></tt>&nbsp; <br><tt></tt>&nbsp;</blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frcontour.html�������������������������������������������������������������������0000644�0001750�0001750�00000001444�06774760553�015726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Contour Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Contour Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">Sorry, not available at this time.</font></h2> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frcoord.html���������������������������������������������������������������������0000644�0001750�0001750�00000001452�06774760553�015342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Coordinate Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Coordinate Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">Sorry, not available at this time.</font></h2> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frgeneral.html�������������������������������������������������������������������0000644�0001750�0001750�00000001444�06774760554�015653� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame General Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame General Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">Sorry, not available at this time.</font></h2> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frcross.html���������������������������������������������������������������������0000644�0001750�0001750�00000010504�07001676540�015345� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Crosshair Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Crosshair Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#crosshair">crosshair</a></font></li> <li> <font face="Arial,Helvetica"><a href="#crosshair begin motion">crosshair begin motion</a></font></li> <li> <font face="Arial,Helvetica"><a href="#crosshair motion">crosshair motion</a></font></li> <li> <font face="Arial,Helvetica"><a href="#crosshair warp">crosshair warp</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get crosshair">get crosshair</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get crosshair status">get crosshair status</a></font></li> </blockquote> <h3> <a NAME="crosshair"></a><font face="Arial,Helvetica">crosshair</font></h3> <font face="Arial,Helvetica">Turn crosshairs on or off or set the current crosshair location</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>crosshair</b> <a href="frame.html#yes no">yes no</a> # control crosshairs</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>crosshair</b> <a href="frame.html#coordinate">coordinate</a> <a href="frame.html#canvas coordinate system">canvas coordinate system</a> # set current position</font> <br><tt>Example: crosshair on</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; crosshair 22 58 fk5</tt> <h3> <a NAME="crosshair begin motion"></a><font face="Arial,Helvetica">crosshair begin motion</font></h3> <font face="Arial,Helvetica">Begin interactive crosshair motion. Bind this command to a mouse down event. Crosshairs become active, if currently inactive</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>crosshair begin motion</b> numeric numeric <a href="frame.html#canvas coordinate system">canvas coordinate system</a></font> <br><tt>Example: crosshair begin motion 10 20 canvas</tt> <h3> <a NAME="crosshair motion"></a><font face="Arial,Helvetica">crosshair motion</font></h3> <font face="Arial,Helvetica">Current crosshair motion command. Bind this command to mouse down motion events</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>crosshair motion</b> numeric numeric <a href="frame.html#canvas coordinate system">canvas coordinate system</a></font> <br><tt>Example: crosshair motion 20 20 canvas</tt> <h3> <a NAME="crosshair warp"></a><font face="Arial,Helvetica">crosshair warp</font></h3> <font face="Arial,Helvetica">Moves the crosshairs by specified amount in pixels. Crosshairs become active, if currently inactive</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>crosshair warp</b> integer integer</font> <br><tt>Example: crosshair warp 1 1</tt> <h3> <a NAME="get crosshair"></a><font face="Arial,Helvetica">get crosshair</font></h3> <font face="Arial,Helvetica">Returns the current crosshair coordinates</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get crosshair&nbsp;&nbsp;</b> # return canvas coords at default precision</font> <br><font face="Arial,Helvetica"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get crosshair </b><a href="frame.html#canvas coordinate system">canvas coordinate system</a> <a href="frame.html#precision">precision</a> # return specified coord system</font> <br><tt>Example: get crosshair physical default</tt> <h3> <a NAME="get crosshair status"></a><font face="Arial,Helvetica">get crosshair status</font></h3> <font face="Arial,Helvetica">Returns 1 if crosshairs are active, 0 if inactive</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get crosshair status</b></font> <br><tt>Example: get crosshair status</tt> <br>&nbsp; <br>&nbsp; <br>&nbsp; <br>&nbsp; <br>&nbsp; <br>&nbsp;</blockquote> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frfits.html����������������������������������������������������������������������0000644�0001750�0001750�00000035625�07001676540�015174� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame FITS Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame FITS Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#get fits count">get fits count</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits header">get fits header</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits file name">get fits file name</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits file names">get fits file names</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits full file name">get fits full file name</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits full file names">get fits full file names</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get fits object name">get fits object name</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits alloc">load fits alloc</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits channel">load fits channel</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mmap">load fits mmap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits shared">load fits shared</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load array alloc">load array alloc</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load array channel">load array channel</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load array mmap">load array mmap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load array shared">load array shared</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic alloc">load fits mosaic alloc</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic channel">load fits mosaic channel</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic mmap">load fits mosaic mmap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic shared">load fits mosaic shared</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic ext alloc">load fits mosaic ext alloc</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic ext channel">load fits mosaic ext channel</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic ext mmap">load fits mosaic ext mmap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load fits mosaic ext shared">load fits mosaic ext shared</a></font></li> </blockquote> <h3> <a NAME="get fits count"></a><font face="Arial,Helvetica">get fits count</font></h3> <font face="Arial,Helvetica">Return the number of FITS files currently loaded</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits count</b></font> <br><tt>Example: get fits count</tt> <h3> <a NAME="get fits header"></a><font face="Arial,Helvetica">get fits header</font></h3> <font face="Arial,Helvetica">Return the header of the specified FITS file loaded. The first FITS file loaded is number 1.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits header number </b>integer</font> <br><tt>Example: get fits header number 2</tt> <h3> <a NAME="get fits file name"></a><font face="Arial,Helvetica">get fits file name</font></h3> <font face="Arial,Helvetica">Return the file name of the specified loaded FITS file.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits file number </b>integer # return file name of FITS file numer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>get fits file </b><a href="frame.html#canvas coordinate system">canvas<b> </b>coordinate system</a> <a href="frame.html#coordinate">coordinate</a> # return file name based on the specified coordinate.</font> <br><tt>Example: get fits file name 2</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get fits file canvas 10 10</tt> <h3> <a NAME="get fits file names"></a><font face="Arial,Helvetica">get fits file names</font></h3> <font face="Arial,Helvetica">Return the file names of all loaded FITS files</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits file names</b></font> <br><tt>Example: get fits file names</tt> <h3> <a NAME="get fits full file name"></a><font face="Arial,Helvetica">get fits full file name</font></h3> <font face="Arial,Helvetica">Return the full file name of the specified loaded FITS file.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits full file number </b>integer # return full file name of FITS file numer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>get fits full file </b><a href="frame.html#canvas coordinate system">canvas<b> </b>coordinate system</a> <a href="frame.html#coordinate">coordinate</a> # return full file name based on the specified coordinate.</font> <br><tt>Example: get fits full file name 2</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get fits full file canvas 10 10</tt> <h3> <a NAME="get fits full file names"></a><font face="Arial,Helvetica">get fits full file names</font></h3> <font face="Arial,Helvetica">Return the full file names of all loaded FITS files</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits full file names</b></font> <br><tt>Example: get fits full file names</tt> <h3> <a NAME="get fits object name"></a><font face="Arial,Helvetica">get fits object name</font></h3> <font face="Arial,Helvetica">Return the FITS keyword OBJECT value for specified FITS file loaded.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get fits object name </b><a href="frame.html#canvas coordinate system">canvas<b> </b>coordinate system</a> <a href="frame.html#coordinate">coordinate</a></font> <br><tt>Example: get fits object name canvas 100 200</tt> <h3> <a NAME="load fits alloc"></a><font face="Arial,Helvetica">load fits alloc</font></h3> <font face="Arial,Helvetica">Load a FITS file from file or stdin and use allocated memory</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits alloc</b> string</font> <br><tt>Example: load fits alloc foo.fits</tt> <h3> <a NAME="load fits channel"></a><font face="Arial,Helvetica">load fits channel</font></h3> <font face="Arial,Helvetica">Load a FITS file from a TCL channel and use allocated memory. The first argument is the channel name and the second argument is the optional extension/binning parameters.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits channel</b> string</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> load fits channel </b>string string</font> <br><tt>Example: load fits channel file2</tt> <h3> <a NAME="load fits mmap"></a><font face="Arial,Helvetica">load fits mmap</font></h3> <font face="Arial,Helvetica">Load a FITS file from file and use mmap memory. This is the default method.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits </b>string</font> <br><font face="Arial,Helvetica"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load fits mmap </b>string</font> <br><tt>Example: load fits mmap foo.fits</tt> <h3> <a NAME="load fits shared"></a><font face="Arial,Helvetica">load fits shared</font></h3> <font face="Arial,Helvetica">Use shared memory segment which contains a vaild FITS file. The first argment is the shared memory id, the second is the size of the segment, and the optional third parameter is the optional extension/binning parameters.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits shared</b> integer integer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load fits shared</b> integer integer string</font> <br><tt>Example: load fits shared 15 4096 [bin=x,y]</tt> <h3> <a NAME="load array alloc"></a><font face="Arial,Helvetica">load array alloc</font></h3> <font face="Arial,Helvetica">Load a raw data array file from file or stdin and use allocated memory</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load array alloc</b> string</font> <br><tt>Example: load fits alloc foo.arr[xdim=512,ydim=512,bitpix=16]</tt> <h3> <a NAME="load array channel"></a><font face="Arial,Helvetica">load array channel</font></h3> <font face="Arial,Helvetica">Load a fits file from a TCL channel and use allocated memory. The first argument is the channel name and the second argument is the array parameters</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load array channel </b>string</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load array channel</b> string string</font> <br><tt>Example: load array channel file2 [xdim=512,ydim=512,bitpix=16]</tt> <h3> <a NAME="load array mmap"></a><font face="Arial,Helvetica">load array mmap</font></h3> <font face="Arial,Helvetica">Load a fits file from file and use mmap memory.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load array </b>string</font> <br><font face="Arial,Helvetica"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load array mmap </b>string</font> <br><tt>Example: load array mmap foo.arr[xdim=512,ydim=512,bitpix=16]</tt> <h3> <a NAME="load array shared"></a><font face="Arial,Helvetica">load array shared</font></h3> <font face="Arial,Helvetica">Use shared memory segment which contains a raw data array file. The first argment is the shared memory id, the second is the size of the segment, and the optional third parameter is the optional extension/binning parameters.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load array shared</b> integer integer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load array shared</b> integer integer string</font> <br><tt>Example: load array shared 15 4096 [xdim=512,ydim=512,bitpix=16]</tt> <h3> <a NAME="load fits mosaic alloc"></a><font face="Arial,Helvetica">load fits mosaic alloc</font></h3> <font face="Arial,Helvetica">Load a FITS mosic file from file or stdin and use allocated memory</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosic alloc</b> string</font> <br><tt>Example: load fits mosaic alloc foo.fits</tt> <h3> <a NAME="load fits mosaic channel"></a><font face="Arial,Helvetica">load fits mosaic channel</font></h3> <font face="Arial,Helvetica">Load a FITS mosaic file from a TCL channel and use allocated memory. The first argument is the channel name and the second argument is the optional file name.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosaic channel</b> string</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> load fits mosaic channel </b>string string</font> <br><tt>Example: load fits mosaic channel file2</tt> <h3> <a NAME="load fits mosaic mmap"></a><font face="Arial,Helvetica">load fits mosaic mmap</font></h3> <font face="Arial,Helvetica">Load a FITS mosaic file from file and use mmap memory. This is the default method.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosaic </b>string</font> <br><font face="Arial,Helvetica"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load fits mosaic mmap </b>string</font> <br><tt>Example: load fits mosaic mmap foo.fits</tt> <h3> <a NAME="load fits mosaic shared"></a><font face="Arial,Helvetica">load fits mosaic shared</font></h3> <font face="Arial,Helvetica">Use shared memory segment which contains a vaild FITS mosaic file. The first argment is the shared memory id, the second is the size of the segment, and the optional third parameter is the optional file name.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosaic shared</b> integer integer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load fits mosaic shared</b> integer integer string</font> <br><tt>Example: load fits mosaic shared 15 4096</tt> <h3> <a NAME="load fits mosaic ext alloc"></a><font face="Arial,Helvetica">load fits mosaic ext alloc</font></h3> <font face="Arial,Helvetica">Load a FITS mosic file segment from file or stdin and use allocated memory</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosic ext alloc</b> string</font> <br><tt>Example: load fits mosaic ext alloc foo.fits</tt> <h3> <a NAME="load fits mosaic ext channel"></a><font face="Arial,Helvetica">load fits mosaic ext channel</font></h3> <font face="Arial,Helvetica">Load a FITS mosaic file segment from a TCL channel and use allocated memory. The first argument is the channel name and the second argument is the optional file name.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosaic ext channel</b> string</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> load fits mosaic ext channel </b>string string</font> <br><tt>Example: load fits mosaic ext channel file2</tt> <h3> <a NAME="load fits mosaic ext mmap"></a><font face="Arial,Helvetica">load fits mosaic ext mmap</font></h3> <font face="Arial,Helvetica">Load a FITS mosaic file segment from file and use mmap memory. This is the default method.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits ext mosaic </b>string</font> <br><font face="Arial,Helvetica"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load fits ext mosaic mmap </b>string</font> <br><tt>Example: load fits mosaic ext mmap foo.fits</tt> <h3> <a NAME="load fits mosaic ext shared"></a><font face="Arial,Helvetica">load fits mosaic ext shared</font></h3> <font face="Arial,Helvetica">Use shared memory segment which contains a vaild FITS mosaic file segment . The first argment is the shared memory id, the second is the size of the segment, and the optional third parameter is the optional file name.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>load fits mosaic ext shared</b> integer integer</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load fits mosaic ext shared</b> integer integer string</font> <br><tt>Example: load fits mosaic ext shared 15 4096</tt> <br>&nbsp; <br>&nbsp; <br>&nbsp;</blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frame.html�����������������������������������������������������������������������0000644�0001750�0001750�00000016403�07001676537�014770� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Widget</font></h2> <blockquote> <h2> <font face="Arial,Helvetica"><a href="frintro.html">introduction</a></font></h2> <font face="Arial,Helvetica">The Frame widget is used to display FITS data. It supports both FITS images and binary tables. Multiple extension files are also supported. The widget supports arbitrary zoom, rotation, orientation, and panning. The Frame widget is designed to support rendering of large FITS images and binary tables.</font> <h2> <font face="Arial,Helvetica">synopsis</font></h2> <h3> <font face="Arial,Helvetica">framepseudocolor8<br> frametruecolor8<br> frametruecolor16<br> frametruecolor24</font></h3> <font face="Arial,Helvetica">Create frame canvas widget for pseudocolor or truecolor visual.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; standard canvas widget options, see canvas(n) for more info.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width of magnifier, default 512</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height of magnifier, default 512</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -anchor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anchor mode, default nw</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -tags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; canvas tag</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -command&nbsp; tcl command for this widget, default 'frame'</font> <p><tt>Example: create framepseudocolor8 -width 512 -height 512 -command frame1</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create frametruecolor24 -width 512 -height 512 -command frame2</tt> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="frgeneral.html">General Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frscale.html">Scale Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frcross.html">Crosshair Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frfits.html">FITS Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frcoord.html">Coordinate Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frmarker.html">Marker Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frpan.html">Pan Zoom Rotate Orient Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frmagnifier.html">Magnifier Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frpanner.html">Panner Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frps.html">Postscript Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frblock.html">FITS Binary Table Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="frcontour.html">Contour Commands</a></font></li> <li> <font face="Arial,Helvetica"><a href="friis.html">IIS Commands</a></font></li> </blockquote> <h2> <font face="Arial,Helvetica">conventions</font></h2> <blockquote> <li> <a NAME="yes no"></a><b><font face="Arial,Helvetica">yes no</font></b></li> <br><font face="Arial,Helvetica">Select one of the following:</font> <br><font face="Courier New,Courier">[yes | no | true | false | on | off | 1 | 0]</font> <li> <a NAME="coordinate"></a><b><font face="Arial,Helvetica">coordinate</font></b></li> <br><font face="Arial,Helvetica">Specify one of the following:</font> <br><font face="Arial,Helvetica"><b>canvas</b>: integer integer</font> <br><font face="Arial,Helvetica"><b>reference</b>: numeric numeric</font> <br><font face="Arial,Helvetica"><b>image</b>: integer integer</font> <br><font face="Arial,Helvetica"><b>physical</b>: numeric numeric</font> <br><font face="Arial,Helvetica"><b>detector</b>: numeric numeric</font> <br><font face="Arial,Helvetica"><b>amplifier</b>: numeric numeric</font> <br><font face="Arial,Helvetica"><b>wcs</b>: numeric numeric # degrees</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hh:mm:ss.ss dd:mm:ss.ss # hms dms</font> <li> <a NAME="coordinate system"></a><b><font face="Arial,Helvetica">coordinate system</font></b></li> <br><font face="Arial,Helvetica">Specify one of the following coordinate sytems:</font> <br><font face="Arial,Helvetica">[i</font><font face="Courier New,Courier">mage | physical | detector | amplifier | fk4 | fk5 | b1950 | j2000 | galactic | ecliptic | linear | icrs | equatorial b1950 | equatorial j2000 | equatorial fk4 | equatorial fk5]</font> <li> <a NAME="canvas coordinate system"></a><b><font face="Arial,Helvetica">canvas coordinate system</font></b></li> <br><font face="Arial,Helvetica">Specify one of the following coordinate sytems:</font> <br><font face="Courier New,Courier">[canvas | panner | image | physical | detector | amplifier | fk4 | fk5 | b1950 | j2000 | galactic | ecliptic | linear | icrs | equatorial b1950 | equatorial j2000 | equatorial fk4 | equatorial fk5]</font> <li> <a NAME="wcs coordinate system"></a><b><font face="Arial,Helvetica">wcs coordinate system</font></b></li> <br><font face="Arial,Helvetica">Specify one of the following coordinate sytems:</font> <br><font face="Courier New,Courier">[fk4 | fk5 | b1950 | j2000 | galactic | ecliptic | linear | icrs | equatorial b1950 | equatorial j2000 | equatorial fk4 | equatorial fk5]</font> <li> <a NAME="orientation"></a><b><font face="Arial,Helvetica">orientation</font></b></li> <br><font face="Arial,Helvetica">Specify one of the following orientations:</font> <br><font face="Courier New,Courier">[none | x | y | xy]</font> <li> <a NAME="precision"></a><b><font face="Arial,Helvetica">precision</font></b></li> <br><font face="Arial,Helvetica">Specify the precision of the requested value.</font> <br><font face="Courier New,Courier">[default | fixed | scientific | integer]</font></blockquote> <blockquote>&nbsp;</blockquote> </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frps.html������������������������������������������������������������������������0000644�0001750�0001750�00000005126�07001676541�014643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Postscript Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Postscript Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#postscript colorspace">postscript colorpace</a></font></li> <li> <font face="Arial,Helvetica"><a href="#postscript interpolate">postscript interpolate</a></font></li> <li> <font face="Arial,Helvetica"><a href="#postscript level">postscript level</a></font></li> <li> <font face="Arial,Helvetica"><a href="#postscript resolution">postscript resolution</a></font></li> </blockquote> <h3> <a NAME="postscript colorspace"></a><font face="Arial,Helvetica">postscript colorspace</font></h3> <font face="Arial,Helvetica">Set the current postscript colorspace</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>postscript</b> [gray | rgb | cmyk]</font> <br><tt>Example: postscript rgb</tt> <h3> <a NAME="postscript interpolate"></a><font face="Arial,Helvetica">postscript interpolate</font></h3> <font face="Arial,Helvetica">Turn crosshairs on or off or set the current crosshair location</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>postscript interpolate</b> <a href="frame.html#yes no">yes no</a></font> <br><tt>Example: postscript interpolate on</tt> <h3> <a NAME="postscript level"></a><font face="Arial,Helvetica">postscript level</font></h3> <font face="Arial,Helvetica">Select postscript driver level. Default is Level 2.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>postscript</b> <b>level</b>&nbsp; [1 | 2]</font> <br><tt>Example: postscript level 2</tt> <h3> <a NAME="postscript resolution"></a><font face="Arial,Helvetica">postscript resolution</font></h3> <font face="Arial,Helvetica">Select postscript resolution. Selecting a lower resolution will generate smaller ps files.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>postscript resolution</b> integer</font> <br><tt>Example: postscript resolution 75</tt> <br>&nbsp; <br>&nbsp; <br>&nbsp; <h2> </h2> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frmarker.html��������������������������������������������������������������������0000644�0001750�0001750�00000001442�06774761061�015507� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Marker Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Marker Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">Sorry, not available at this time.</font></h2> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/friis.html�����������������������������������������������������������������������0000644�0001750�0001750�00000010105�07001676540�014775� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Panner Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame IIS Commands</font></h2> <blockquote><font face="Arial,Helvetica">IIS Commands are provided as a method to interface with IRAF via the IIS protocol.</font> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#iis new">iis new</a></font></li> <li> <font face="Arial,Helvetica"><a href="#iis erase">iis erase</a></font></li> <li> <font face="Arial,Helvetica"><a href="#iis set">iis set</a></font></li> <li> <font face="Arial,Helvetica"><a href="#iis wcs">iis wcs</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get iis">get iis</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get iis wcs">get iis wcs</a></font></li> </blockquote> <h3> <a NAME="iis new"></a><font face="Arial,Helvetica">iis new</font></h3> <font face="Arial,Helvetica">Create a new IIS image. The arguments are the width and height of the new buffer.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>iis new</b> integer integer</font> <br><tt>Example: iis new 512 512</tt> <h3> <a NAME="iis erase"></a><font face="Arial,Helvetica">iis erase</font></h3> <font face="Arial,Helvetica">Clear the iis buffer.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>iis erase</b></font> <br><tt>Example: iis erase</tt> <h3> <a NAME="iis set"></a><font face="Arial,Helvetica">iis set</font></h3> <font face="Arial,Helvetica">Set the values of the iis buffer starting at x,y in Image coordinates, with values at pointer ptr of length l. Arguments are: x, y, ptr, l. The values are copied into the iis buffer. You are responsible for management of the memory pointed to by pointer.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>iis set </b><a href="frame.html#coordinate">coordinate</a> pointer integer</font> <br><tt>Example: iis set 0 128 0x123AB 256</tt> <h3> <a NAME="iis wcs"></a><font face="Arial,Helvetica">iis wcs</font></h3> <font face="Arial,Helvetica">Set the WCS for the iis buffer. Note, this is NOT World Coordinate System, as you know it. It's really defining the Physical to Image coordinate translation, along with scaling translation information. The first argment is the filename associated with the image. The next six arguments define the Physical to Image Matrix (00,01,10,11,20,21). The next two arguments are the low and high values of the unscale image. The last argment is unknown.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>iis wcs </b>stringnumeric numeric numeric numeric numeric numeric numeric numeric numeric</font> <br><tt>Example: iis wcs foo.fits 1 0 0 1 512 512 0 4096 0</tt> <h3> <a NAME="get iis"></a><font face="Arial,Helvetica">get iis</font></h3> <font face="Arial,Helvetica">Returns a pointer to a block of the iis buffer at location x,y in Image coordinates. This memory is managed by the frame widget, therefor, copy its contents and do not modify. The arguments are x and y.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>iis </b><a href="frame.html#coordinate">coordinate</a></font> <br><tt>Example: get iis 0 128</tt> <h3> <a NAME="get iis wcs"></a><font face="Arial,Helvetica">get iis wcs</font></h3> <font face="Arial,Helvetica">Returns the iis WCS values previous defined. The values returned are: filename, Physical to Image Matrix (00, 01, 10, 11, 20, 21), Scale Translation (low, high), and Unknown.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get</b> <b>iis wcs</b></font> <br><tt>Example: get iis wcs</tt> <br>&nbsp;</blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/magnifier.html�������������������������������������������������������������������0000644�0001750�0001750�00000013354�06774243146�015643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Magnifier</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Magnifier Widget</font></h2> <blockquote><font face="Arial,Helvetica">The Magnifier widget provides a magnified view into the data. Pseudocolor and Truecolor visuals are supported. Two magnification algorithms are available: <i>Fast</i> and <i>More Accurate.</i> The later is especially useful for non-integer zoom and rotation values. The magnification value may be user specified, but usually is a power of 2.</font> <br>&nbsp; <h2> <font face="Arial,Helvetica">synopsis</font></h2> <h3> <font face="Arial,Helvetica">magnifierpseudocolor<br> magnifiertruecolor</font></h3> <font face="Arial,Helvetica">Create magnifier canvas widget for pseudocolor or truecolor visual.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; standard canvas widget options, see canvas(n) for more info.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width of magnifier, default 256</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height of magnifier, default 256</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -anchor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anchor mode, default nw</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -tags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; canvas tag</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -command&nbsp; tcl command for this widget, default 'magnifier'</font><font face="Arial,Helvetica"></font> <p><tt>Example: create magnifierpseudocolor -width 128 -height 128 -command mymag</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create magnifiertruecolor -width 128 -height 128 -command mymag</tt> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#clear">clear</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get bbox">get bbox</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get height">get height</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get width">get width</a></font></li> <li> <font face="Arial,Helvetica"><a href="#hide">hide</a></font></li> <li> <font face="Arial,Helvetica"><a href="#reset">reset</a></font></li> <li> <font face="Arial,Helvetica"><a href="#show">show</a></font></li> <li> <font face="Arial,Helvetica"><a href="#update">update</a></font></li> <li> <font face="Arial,Helvetica"><a href="#version">version</a></font></li> </blockquote> <h3> <a NAME="clear"></a><font face="Arial,Helvetica">clear</font></h3> <font face="Arial,Helvetica">Clear the magnifer.</font> <br><tt>Example: magnifier clear</tt> <h3> <a NAME="get bbox"></a><font face="Arial,Helvetica">get bbox</font></h3> <font face="Arial,Helvetica">Returns current magnifier width and height</font> <br><tt>Example: magnifier get bbox</tt> <h3> <a NAME="get height"></a><font face="Arial,Helvetica">get height</font></h3> <font face="Arial,Helvetica">Returns current magnifier height.</font> <br><tt>Example: magnifier get height</tt> <h3> <a NAME="get width"></a><font face="Arial,Helvetica">get width</font></h3> <font face="Arial,Helvetica">Return current magnifier width</font> <br><tt>Example: magnifier get width</tt> <h3> <a NAME="hide"></a><font face="Arial,Helvetica">hide</font></h3> <font face="Arial,Helvetica">Hide the magnifier if visible. No effect otherwise.</font> <br><tt>Example: magnifier hide</tt> <h3> <a NAME="reset"></a><font face="Arial,Helvetica">reset</font></h3> <font face="Arial,Helvetica">Reset the magnifier.</font> <br><tt>Example: magnifier reset</tt> <h3> <a NAME="show"></a><font face="Arial,Helvetica">show</font></h3> <font face="Arial,Helvetica">Show the magnifier if previously hidden. No effect otherwise.</font> <br><tt>Example: magnifier show</tt> <h3> <a NAME="update"></a><font face="Arial,Helvetica">update</font></h3> <font face="Arial,Helvetica">Refresh the magnifer. The pixmap id must be a valid pixmap id returned from a frame widget. This command is generated automatically by the frame magnifier update command.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>update</b> integer</font> <br><tt>Example: magnifier update 57</tt> <h3> <a NAME="version"></a><font face="Arial,Helvetica">version</font></h3> <font face="Arial,Helvetica">Return the current magnifier verison.</font> <br><tt>Example: magnifier version</tt></blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frintro.html���������������������������������������������������������������������0000644�0001750�0001750�00000010773�06774247222�015366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Introduction</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Introduction</font></h2> <blockquote><font face="Arial,Helvetica">The Frame widget is used to display FITS data. It supports both FITS images and binary tables. Multiple extension files are also supported. The widget supports arbitrary zoom, rotation, orientation, and panning. The FITS data is maintained in raw form.&nbsp; BSCALE, BZERO, and BLANK keywords are supported.</font><font face="Arial,Helvetica"></font> <p><font face="Arial,Helvetica">The Frame widget is designed to support rendering of large FITS images and binary tables. For images, the rendering time is constant, and is based on the size of the screen, not the size of the data. Thus, the widget is capable of rendering very large images (8k x 8k or larger), or a large mosaic of images (such as 36 images, each 2k x 4k). Since all rendering is done directly from the raw FITS data, memory requirements are very small.</font> <p><font face="Arial,Helvetica">For binary tables, the rendering time is based on the number of rows or events. Since the the image is binned on the fly, and then rendered to the screen, memory requirements again are very small.</font> <p><font face="Arial,Helvetica">The Frame widget supports a mosaic of images, where each image segment is a separate FITS image. These segments may be located in one multi-extension file, or may be located in a number of different files. The widget uses NOAO mosaic keywords to place each image in its proper place in the overall image space.</font> <p><font face="Arial,Helvetica">One special feature of the Frame widget is the ability to rotate, orient, and zoom an image to align its display to an arbitrary WCS. This feature is very useful for comparisons between images from different instruments or telescopes that have different WCS values.</font> <p><font face="Arial,Helvetica">The Frame widget supports Pseudocolor8, Truecolor8, Truecolor16, and Truecolor24 color environments. The mapping from the raw data to the scaled value is based on the start/stop clip values and the scaling algorithm. Clipping values can be defined using minimum/maximum data values, IRAF zscale, or user specified values. Scaling algorithms currently available are linear, ln (from SAOImage), log (from IRAF), and sqrt.</font> <p><font face="Arial,Helvetica">If the data is a binary table, the data is fbinned in real time, again based on the current block, pan, zoom and rotation values.</font> <p><font face="Arial,Helvetica">The Frame widget can read FITS data from a file, STDIN, or a TCL Channel.</font> <p><font face="Arial,Helvetica">The Frame widget supports a number of different memory management options: memory can be allocated as needed (and swapped to disk), memory can be mapped directly to the FITS file (mmap), or the FITS data can be accessed from a shared memory segment. The default is mmap.</font> <p><font face="Arial,Helvetica">The Frame widget supports a variety of coordinate systems, all defined in the FITS header: Image, Physical, Detector, Amplifier, WCS (FK4, FK5, Galactic, Ecliptic, Linear).</font> <p><font face="Arial,Helvetica">The Frame widget supports PostScript level 1 and level 2 printing. This is not a screen capture process, but a full-featured PostScript driver. A variety of document sizes are available, and grayscale and color imaging is supported. Level 2 output is compressed via RLE and encoded via ASCII85, so the output PostScript size is usually very small.</font> <p><font face="Arial,Helvetica">The Frame widget also supports a variety of markers or regions, including Circle, Ellipse, Rectangle, Polygon, Line, and Point. A marker's position is attached to the image and may be specified in any of the supported coordinated systems. Each marker has a number of properties, including Color, Text, and Name. Each marker's bindings allows specification of behavior such as: whether the marker can be selected, edited, moved, rotated, deleted, etc.</font></blockquote> </body> </html> �����./saods9/saotk/doc/frpanner.html��������������������������������������������������������������������0000644�0001750�0001750�00000004304�07001676541�015501� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Panner Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Panner Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#panner">panner</a></font></li> <li> <font face="Arial,Helvetica"><a href="#panner update">panner update</a></font></li> </blockquote> <h3> <a NAME="panner"></a><font face="Arial,Helvetica">panner</font></h3> <font face="Arial,Helvetica">Control and define the panner for this frame widget. In the second form, the existing panner widget specified is assigned to this frame widget. When the update command is executed, the frame widget will calulate the proper image to be displayed and will automatically notified the named panner widget.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>panner</b> <a href="frame.html#yes no">yes no</a> # activate or deactivate current magnifier</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>panner</b>&nbsp; string integer integer # assign a particular panner widget to this frame</font> <br><tt>Example: panner on</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner mypanner 128 128</tt> <h3> <a NAME="panner update"></a><font face="Arial,Helvetica">panner update</font></h3> <font face="Arial,Helvetica">Update the panner based on the current zoom, rotation, and orientation.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>panner</b> <b>update</b> # activate or deactivate current magnifier</font> <br><tt>Example: panner update</tt> <br><tt></tt>&nbsp;</blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/colorbar.html��������������������������������������������������������������������0000644�0001750�0001750�00000034200�07000712057�015457� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]"> <title>SAOTk Colorbar</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Colorbar Widget</font></h2> <blockquote><font face="Arial,Helvetica">The Colorbar widget controls the color environment for the application. Pseudocolor8, Truecolor8, Truecolor16, and Truecolor24 visuals are supported.</font> <p><font face="Arial,Helvetica">The Colorbar widget supports a variety of colormap formats including colormaps from SAOImage, SAOtng/Ximtool, and other display programs. There are a number of built-in maps, and new maps may be loaded, edited, and saved.</font> <p><font face="Arial,Helvetica">In a Pseudocolor environment, the widget will request a minimum number of colors in the default colormap. If these are not available, it will use a private colormap. The private colormap will be populated with colors from the current colormap to minimize color flashing.</font> <h2> <font face="Arial,Helvetica">synopsis</font></h2> <h3> <font face="Arial,Helvetica">colorbarpseudocolor8<br> colorbartruecolor8<br> colorbartruecolor16<br> colorbartruecolor24</font></h3> <font face="Arial,Helvetica">Create magnifier canvas widget for pseudocolor or truecolor visual.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; standard canvas widget options, see canvas(n) for more info.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width of magnifier, default 512</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height of magnifier, default 22</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -anchor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anchor mode, default nw</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -tags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; canvas tag</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -command&nbsp; tcl command for this widget, default 'colorbar'</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -min&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minimum number of colors, default 80</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -max&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maximum number of colors, default 200</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -private&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (colorbarpseudocolor8 only) use private colormap, default false</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -privatecolors (colorbarpseudocolor8 only) number of colors in private colormap</font> <p><tt>Example: create colorbarpseudocolor8 -width 500 -height 20 -private</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create colorbartruecolor16 -width 500 -height 20</tt> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#adjust">adjust</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get colormap">get colormap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get height">get height</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get id">get id</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get invert">get invert</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get name">get name</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get file name">get file name</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get width">get width</a></font></li> <li> <font face="Arial,Helvetica"><a href="#hide">hide</a></font></li> <li> <font face="Arial,Helvetica"><a href="#itt">itt</a></font></li> <li> <font face="Arial,Helvetica"><a href="#list">list</a></font></li> <li> <font face="Arial,Helvetica"><a href="#load">load</a></font></li> <li> <font face="Arial,Helvetica"><a href="#map">map</a></font></li> <li> <font face="Arial,Helvetica"><a href="#reset">reset</a></font></li> <li> <font face="Arial,Helvetica"><a href="#save">save</a></font></li> <li> <font face="Arial,Helvetica"><a href="#set colormap">set colormap</a></font></li> <li> <font face="Arial,Helvetica"><a href="#show">show</a></font></li> <li> <font face="Arial,Helvetica"><a href="#version">version</a></font></li> </blockquote> <h3> <a NAME="adjust"></a><font face="Arial,Helvetica">adjust</font></h3> <font face="Arial,Helvetica">Adjust the contrast and bias for the current distribution of colors within the colorbar.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>adjust</b> numeric numeric</font> <br><tt>Example: colorbar adjust 1 .5</tt> <h3> <a NAME="get colormap"></a><font face="Arial,Helvetica">get colormap</font></h3> <font face="Arial,Helvetica">Returns the following information: colormap id, bias, contrast, invert, pointer to color cells, number of color cells. The output of this command is input for the frame colormap command.</font> <br><tt>Example: colorbar get colormap</tt> <h3> <a NAME="get height"></a><font face="Arial,Helvetica">get height</font></h3> <font face="Arial,Helvetica">Returns current colorbar height.</font> <br><tt>Example: colorbar get height</tt> <h3> <a NAME="get id"></a><font face="Arial,Helvetica">get id</font></h3> <font face="Arial,Helvetica">Returns current colormap id.</font> <br><tt>Example: colorbar get id</tt> <h3> <a NAME="get invert"></a><font face="Arial,Helvetica">get invert</font></h3> <font face="Arial,Helvetica">Returns true if current colormap is inverted.</font> <br><tt>Example: colorbar get invert</tt> <h3> <a NAME="get name"></a><font face="Arial,Helvetica">get name</font></h3> <font face="Arial,Helvetica">Returns colormap name.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>get name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b>Return current colormap name</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>get name</b> integer&nbsp; Return colormap id name</font> <br><tt>Example: colorbar get name</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colorbar get name 5</tt> <h3> <a NAME="get file name"></a><font face="Arial,Helvetica">get file name</font></h3> <font face="Arial,Helvetica">Returns current colormap file name.</font> <br><tt>Example: colorbar get file name</tt> <h3> <a NAME="get width"></a><font face="Arial,Helvetica">get width</font></h3> <font face="Arial,Helvetica">Return current colorbar width</font> <br><tt>Example: colorbar get width</tt> <h3> <a NAME="hide"></a><font face="Arial,Helvetica">hide</font></h3> <font face="Arial,Helvetica">Hide the colorbar if visible. No effect otherwise.</font> <br><tt>Example: colorbar hide</tt> <h3> <a NAME="invert"></a><font face="Arial,Helvetica">invert</font></h3> <font face="Arial,Helvetica">Invert the current colormap.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>invert</b> [true | false | yes | no | on | off | 1 | 0]</font> <br><tt>Example: colorbar invert yes</tt> <h3> <a NAME="itt"></a><font face="Arial,Helvetica">itt</font></h3> <font face="Arial,Helvetica">Use a RTD ITT colormap</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>itt</b> name<b>&nbsp;&nbsp;&nbsp;&nbsp; </b>use itt name</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>itt</b> integer&nbsp;&nbsp; use itt id</font> <br><tt>Example: colorbar itt foo.itt</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colorbar itt 4</tt> <h3> <a NAME="list"></a><font face="Arial,Helvetica">list</font></h3> <font face="Arial,Helvetica">Return list of loaded colormaps.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>list</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of colormap names</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> list&nbsp;</b> id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of colormap ids</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>list</b> name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of colormap names</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>list</b> <b>itt</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of itt colormap names</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>list</b> <b>itt</b> id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of itt colormap ids</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>list</b> <b>itt</b> name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return list of itt colormap names</font> <br><tt>Example: colorbar list name</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colorbar list id</tt> <h3> <a NAME="load"></a><font face="Arial,Helvetica">load</font></h3> <font face="Arial,Helvetica">Load new colormap.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load</b> filename&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Load SAOimage colormap file</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load</b> filename type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Load colormap of type (lut, lasc, other) file</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>load</b> <b>itt</b> filename&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Load ITT colormap file</font> <br><tt>Example: colorbar load foo.lut</tt> <h3> <a NAME="map"></a><font face="Arial,Helvetica">map</font></h3> <font face="Arial,Helvetica">Set the current colormap.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>map</b> name&nbsp;&nbsp;&nbsp;&nbsp; Use colormap name. The name is case insensitive.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>map</b> id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Use colormap id</font> <br><tt>Example: colorbar map heat</tt> <h3> <a NAME="reset"></a><font face="Arial,Helvetica">reset</font></h3> <font face="Arial,Helvetica">Reset the colorbar.</font> <br><tt>Example: colorbar reset</tt> <h3> <a NAME="save"></a><font face="Arial,Helvetica">save</font></h3> <font face="Arial,Helvetica">Save the current colormap to a file.</font> <br><font face="Arial,Helvetica">Syntax: <b>save</b> filename</font> <br><tt>Example: colorbar map heat</tt> <h3> <a NAME="set colormap"></a><font face="Arial,Helvetica">set colormap</font></h3> <font face="Arial,Helvetica">Set the current colormap.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>set colormap</b> name&nbsp; numeric numeric integer&nbsp; Set colormap name, bias, contrast, invert</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>set colormap</b> integer numeric numeric integer Set colormap id, bias, contrast, invert</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>set colormap</b> <b>window</b> windowname&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Apply colomap name to tk window name</font> <br><tt>Example: colorbar set colormap heat 1 .5 0</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colorbar set colormap .simple</tt> <h3> <a NAME="show"></a><font face="Arial,Helvetica">show</font></h3> <font face="Arial,Helvetica">Show the colorbar if previously hidden. No effect otherwise.</font> <br><tt>Example: colorbar show</tt> <h3> <a NAME="version"></a><font face="Arial,Helvetica">version</font></h3> <font face="Arial,Helvetica">Return the current colorbar verison.</font> <br><tt>Example: colorbar version</tt></blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/panner.html����������������������������������������������������������������������0000644�0001750�0001750�00000027245�07000712061�015145� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]"> <title>SAOTk Panner</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Panner Widget</font></h2> <blockquote><font face="Arial,Helvetica">The Panner widget displays a thumbnail image of the data that supports position control. It also overlays an image orientation compass and a WCS orientation compass. The WCS compass may be positioned at the center of the image or at the tangent point.</font> <h2> <font face="Arial,Helvetica">synopsis</font></h2> <h3> <font face="Arial,Helvetica">pannerpseudocolor<br> pannertruecolor</font></h3> <font face="Arial,Helvetica">Create magnifier canvas widget for pseudocolor or truecolor visual.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; standard canvas widget options, see canvas(n) for more info.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width of magnifier, default 256</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height of magnifier, default 256</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; location of anchor point in canvas, default 1</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -anchor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anchor mode, default nw</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -tags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; canvas tag</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -command&nbsp; tcl command for this widget, default 'panner'</font> <p><tt>Example: create pannerpseudocolor -width 128 -height 128 -command mypanner</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create pannertruecolor -width 128 -height 128 -command mypanner</tt> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#bbox">bbox</a></font></li> <li> <font face="Arial,Helvetica"><a href="#clear">clear</a></font></li> <li> <font face="Arial,Helvetica"><a href="#image compass">image compass</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get bbox">get bbox</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get height">get height</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get width">get width</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get size">get size</a></font></li> <li> <font face="Arial,Helvetica"><a href="#hide">hide</a></font></li> <li> <font face="Arial,Helvetica"><a href="#highlite">highlite</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan">pan</a></font></li> <li> <font face="Arial,Helvetica"><a href="#reset">reset</a></font></li> <li> <font face="Arial,Helvetica"><a href="#show">show</a></font></li> <li> <font face="Arial,Helvetica"><a href="#update">update</a></font></li> <li> <font face="Arial,Helvetica"><a href="#update bbox">update bbox</a></font></li> <li> <font face="Arial,Helvetica"><a href="#update image compass">update image compass</a></font></li> <li> <font face="Arial,Helvetica"><a href="#update wcs compass">update wcs compass</a></font></li> <li> <font face="Arial,Helvetica"><a href="#version">version</a></font></li> <li> <font face="Arial,Helvetica"><a href="#warp">warp</a></font></li> <li> <font face="Arial,Helvetica"><a href="#wcs compass">wcs compass</a></font></li> </blockquote> <h3> <a NAME="bbox"></a><font face="Arial,Helvetica">bbox</font></h3> <font face="Arial,Helvetica">Show/Hide the current bounding box.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>bbox</b> [on | off | true | false | yes | no | 1 | 0]</font> <br><tt>Example: panner bbox on</tt> <h3> <a NAME="clear"></a><font face="Arial,Helvetica">clear</font></h3> <font face="Arial,Helvetica">Clear the panner.</font> <br><tt>Example: panner clear</tt> <h3> <a NAME="image compass"></a><font face="Arial,Helvetica">image compass</font></h3> <font face="Arial,Helvetica">Show/Hide the image compass.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>image</b> <b>compass</b> [on | off | true | false | yes | no | 1 | 0]</font> <br><tt>Example: panner image compass on</tt> <h3> <a NAME="get bbox"></a><font face="Arial,Helvetica">get bbox</font></h3> <font face="Arial,Helvetica">Returns current panner bounding box in panner coords</font> <br><tt>Example: panner get bbox</tt> <h3> <a NAME="get height"></a><font face="Arial,Helvetica">get height</font></h3> <font face="Arial,Helvetica">Returns current panner height in pixels.</font> <br><tt>Example: panner get height</tt> <h3> <a NAME="get width"></a><font face="Arial,Helvetica">get width</font></h3> <font face="Arial,Helvetica">Return current panner width in pixels.</font> <br><tt>Example: panner get width</tt> <h3> <a NAME="get size"></a><font face="Arial,Helvetica">get size</font></h3> <font face="Arial,Helvetica">Returns current panner width and height in pixels.</font> <br><tt>Example: panner get size</tt> <h3> <a NAME="hide"></a><font face="Arial,Helvetica">hide</font></h3> <font face="Arial,Helvetica">Hide the panner if visible. No effect otherwise.</font> <br><tt>Example: panner hide</tt> <h3> <a NAME="highlite"></a><font face="Arial,Helvetica">highlite</font></h3> <font face="Arial,Helvetica">Control the hightlite function of the bounding box</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>hightlite</b> numeric numeric&nbsp;&nbsp; Panner coords. Hightlite if point is inside bounding box.</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>hightlite</b> [on | off | true | false | yes | no | 1 | 0]&nbsp; Turn highlite function on or off</font> <br><tt>Example: panner hightlite on</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner hightlite 45 56</tt> <h3> <a NAME="pan"></a><font face="Arial,Helvetica">pan</font></h3> <font face="Arial,Helvetica">Controls the pan function of the bounding box.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>pan</b> <b>begin</b> numeric numeric&nbsp; Start the pan process</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>pan</b> numeric numeric&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Update the pan process</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>pan</b> <b>end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b>End the pan process</font> <br><tt>Example: panner pan begin 10 10</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner pan 15 15</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner pan end</tt> <h3> <a NAME="reset"></a><font face="Arial,Helvetica">reset</font></h3> <font face="Arial,Helvetica">Reset the panner.</font> <br><tt>Example: panner reset</tt> <h3> <a NAME="show"></a><font face="Arial,Helvetica">show</font></h3> <font face="Arial,Helvetica">Show the panner if previously hidden. No effect otherwise.</font> <br><tt>Example: panner show</tt> <h3> <a NAME="update"></a><font face="Arial,Helvetica">update</font></h3> <font face="Arial,Helvetica">Refresh the panner. The pixmap id must be a valid pixmap id returned from a frame widget. This command is generated automatically by the frame panner update command.</font> <br><font face="Arial,Helvetica">Syntax: <b>update</b> integer</font> <br><tt>Example: panner update 57</tt> <h3> <a NAME="update bbox"></a><font face="Arial,Helvetica">update bbox</font></h3> <font face="Arial,Helvetica">Update the panner bounding box. The bounding box is defined by two points, lower left and upper right. This command is generated automatically by the frame panner update command.</font> <br><font face="Arial,Helvetica">Syntax: <b>update bbox</b> numeric numeric numeric numeric</font> <br><tt>Example: panner update bbox 10 10 40 40</tt> <h3> <a NAME="update image compass"></a><font face="Arial,Helvetica">update image compass</font></h3> <font face="Arial,Helvetica">Update the panner image compass. The 4 arguments defines a rotation matrix. This command is generated automatically by the frame panner update command.</font> <br><font face="Arial,Helvetica">Syntax: update image compass numeric numeric numeric numeric</font> <br><tt>Example: panner update image compass 1 0 0 1</tt> <h3> <a NAME="update wcs compass"></a><font face="Arial,Helvetica">update wcs compass</font></h3> <font face="Arial,Helvetica">Update the wcs compass. The 6 arguments are the origin of the compass, normalized north vector, and normalized east vector. This command is generated automatically by the frame panner update command.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>update wcs compass</b> numeric numeric numeric numeric numeric numeric</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>update wcs compass</b> invalid</font> <br><tt>Example: panner update wcs compass 100 100 1 0 0 -1</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner update wcs compass invalid</tt> <h3> <a NAME="version"></a><font face="Arial,Helvetica">version</font></h3> <font face="Arial,Helvetica">Return the current panner verison.</font> <br><tt>Example: panner version</tt> <h3> <a NAME="warp"></a><font face="Arial,Helvetica">warp</font></h3> <font face="Arial,Helvetica">Move the current pointer in the panner.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>warp</b> integer integer</font> <br><tt>Example: panner warp 1 1</tt> <h3> <a NAME="wcs compass"></a><font face="Arial,Helvetica">wcs compass</font></h3> <font face="Arial,Helvetica">Control the wcs compass.</font> <br><font face="Arial,Helvetica">Syntax:</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>wcs compass</b> [on | off | true | off | yes | no | 1 | 0]&nbsp;&nbsp;&nbsp; Turn wcs compass on or off</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>wcs compass</b> <b>tangent</b> <b>point</b> [on | off | true | off | yes | no | 1 | 0]&nbsp; Display wcs compass at tangent point.</font> <br><tt>Example: panner wcs compass on</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; panner wcs compass tangent point off</tt></blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/saotk.html�����������������������������������������������������������������������0000644�0001750�0001750�00000003617�06774763015�015026� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Reference Manual</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual</font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Reference Manual</font></h2> <blockquote><font face="Arial,Helvetica">SAOTk is an integrated set of Tk/Tcl canvas widgets for astronomical imaging and data visualization. The widget set is composed of the Frame, Panner, Magnifier, and Colorbar widget. The Frame widget is FITS viewer for one image or a mosaic of images . The Panner widget&nbsp; provides a thumbnail image for position control. The Magnifier widget provides a magnified view of part of the image. And the Colorbar widget provides&nbsp; control of imaging color environment for application.</font> <p><font face="Arial,Helvetica">In addition to `classical' support for imaging FITS data, manipulating colormaps, region marking, coordinate readout (including WCS), etc, SAOTk widgets also support arbitrary image scaling and rotation, advanced printing and graphics, image mosaics, and shared memory.</font> <h3> <font face="Arial,Helvetica"><a href="frame.html">Frame Widget</a></font></h3> <h3> <font face="Arial,Helvetica"><a href="colorbar.html">Colorbar Widget</a></font></h3> <h3> <font face="Arial,Helvetica"><a href="panner.html">Panner Widget</a></font></h3> <h3> <font face="Arial,Helvetica"><a href="magnifier.html">Magnifier Widget</a></font></h3> <h3> <font face="Arial,Helvetica"><a href="sample.html">Sample Code</a></font></h3> </blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/frpan.html�����������������������������������������������������������������������0000644�0001750�0001750�00000030736�07005346362�015003� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Pan Zoom Rotate Orient Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Pan Zoom Rotate Orient Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> </blockquote> <blockquote> <blockquote> <li> <font face="Arial,Helvetica"><a href="#center">center</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get pan">get pan</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get orient">get orient</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get rotate">get rotate</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get wcs align">get wcs align</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get wcs zoom">get wcs zoom</a></font></li> <li> <font face="Arial,Helvetica"><a href="#get zoom">get zoom</a></font></li> <li> <font face="Arial,Helvetica"><a href="#orient">orient</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan">pan</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan bbox">pan bbox</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan motion begin">pan motion begin</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan motion">pan motion</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan motion end">pan motion end</a></font></li> <li> <font face="Arial,Helvetica"><a href="#pan to">pan to</a></font></li> <li> <font face="Arial,Helvetica"><a href="#rotate">rotate</a></font></li> <li> <font face="Arial,Helvetica"><a href="#rotate to">rotate to</a></font></li> <li> <font face="Arial,Helvetica"><a href="#rotate motion begin">rotate motion begin</a></font></li> <li> <font face="Arial,Helvetica"><a href="#rotate motion">rotate motion</a></font></li> <li> <font face="Arial,Helvetica"><a href="#rotate motion end">rotate motion end</a></font></li> <li> <font face="Arial,Helvetica"><a href="#wcs align">wcs align</a></font></li> <li> <font face="Arial,Helvetica"><a href="#wcs zoom">wcs zoom</a></font></li> <li> <font face="Arial,Helvetica"><a href="#zoom">zoom</a></font></li> <li> <font face="Arial,Helvetica"><a href="#zoom about">zoom about</a></font></li> <li> <font face="Arial,Helvetica"><a href="#zoom to">zoom to</a></font></li> <li> <font face="Arial,Helvetica"><a href="#zoom to about">zoom to about</a></font></li> <li> <font face="Arial,Helvetica"><a href="#zoom to fit">zoom to fit</a></font></li> </blockquote> <h3> <a NAME="center"></a><font face="Arial,Helvetica">center</font></h3> <font face="Arial,Helvetica">Center the current image in the frame. The center is determined by FITS keywords, or data type if the keywords are not available.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>center</b></font> <br><tt>Example: center</tt> <h3> <a NAME="get pan"></a><font face="Arial,Helvetica">get pan</font></h3> <font face="Arial,Helvetica">Return the current pan position in the specified coordinate system and precision</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get pan</b> <a href="frame.html#coordinate system">coordinate system</a> <a href="frame.html#precision">precision</a></font> <br><tt>Example: get pan fk5 default</tt> <h3> <a NAME="get orient"></a><font face="Arial,Helvetica">get orient</font></h3> <font face="Arial,Helvetica">Returns the current <a href="frame.html#orientation">orientation</a>.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get orient</b></font> <br><tt>Example: get orient</tt> <h3> <a NAME="get rotate"></a><font face="Arial,Helvetica">get rotate</font></h3> <font face="Arial,Helvetica">Returns the current image rotation</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get rotate</b> <a href="frame.html#precision">precision</a></font> <br><tt>Example: get rotate fixed</tt> <h3> <a NAME="get wcs align"></a><font face="Arial,Helvetica">get wcs align</font></h3> <font face="Arial,Helvetica">Returns 1 or 0 if the current image is aligned based on wcs</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get wcs align</b></font> <br><tt>Example: get wcs align</tt> <h3> <a NAME="get wcs zoom"></a><font face="Arial,Helvetica">get wcs zoom</font></h3> <font face="Arial,Helvetica">Returns the cdelt scale factor of the wcs if available</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get wcs zoom </b><a href="frame.html#precision">precision</a></font> <br><tt>Example: get wcs zoom default</tt> <h3> <a NAME="get zoom"></a><font face="Arial,Helvetica">get zoom</font></h3> <font face="Arial,Helvetica">Returns the current zoom factor</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>get zoom </b><a href="frame.html#precision">precision</a></font> <br><tt>Example: get wcs zoom fixed</tt> <h3> <a NAME="orient"></a><font face="Arial,Helvetica">orient</font></h3> <font face="Arial,Helvetica">Orient the current image</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>orient</b> <a href="frame.html#orientation">orientation</a></font> <br><tt>Example: orient xy</tt> <h3> <a NAME="pan"></a><font face="Arial,Helvetica">pan</font></h3> <font face="Arial,Helvetica">Pan by the specified value or coordinate</font> <br><font face="Arial,Helvetica">Syntax:</font> <blockquote><font face="Arial,Helvetica"><b>pan</b> <a href="frame.html#coordinate">coordinate</a>&nbsp; <a href="frame.html#coordinate">coordinate</a>&nbsp; # start and stop canvas coordinates. Bind this command to a button up event</font> <br><font face="Arial,Helvetica"><b>pan</b>&nbsp; <a href="frame.html#coordinate">coordinate</a>&nbsp; <a href="frame.html#canvas coordinate system">canvas coordinate system</a> # move current postion by specified values in specified coordinate system</font></blockquote> <tt>Example: pan 10 10 20 20</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pan 1.5 2.5 fk5</tt> <h3> <a NAME="pan bbox"></a><font face="Arial,Helvetica">pan bbox</font></h3> <font face="Arial,Helvetica">Pan the current image to the specified bounding box. Use this command in conjuction with the Panner widget. The bound box is in panner coordinates. Set the precision parameter to INTEGER to force alignment on pixel boundaries.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>pan bbox</b> <a href="frame.html#coordinate">coordinate</a>&nbsp; <a href="frame.html#coordinate">coordinate</a>&nbsp; <a href="frame.html#precision">precision</a></font> <br><tt>Example: pan bbox 10 10 20 20 integer</tt> <h3> <a NAME="pan motion begin"></a><font face="Arial,Helvetica">pan motion begin</font></h3> <font face="Arial,Helvetica">Start an interactive pan operation. Values are in canvas coordinates. Bind this command to a Button Down event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>pan motion begin </b><a href="frame.html#coordinate">coordinate</a></font> <br><tt>Example: pan motion begin 10 10</tt> <h3> <a NAME="pan motion"></a><font face="Arial,Helvetica">pan motion</font></h3> <font face="Arial,Helvetica">Continue an interactive pan operation. Values are in canvas coordinates. Bind this command to a Button Motion event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>pan motion</b> <a href="frame.html#coordinate">coordinate</a></font> <br><tt>Example: pan motion 10 10</tt> <h3> <a NAME="pan motion end"></a><font face="Arial,Helvetica">pan motion end</font></h3> <font face="Arial,Helvetica">Endan interactive pan operation. Values are in canvas coordinates. Bind this command to a Button Release event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>pan motion</b> <b>end </b><a href="frame.html#coordinate">coordinate</a></font> <br><tt>Example: pan motion end 10 10</tt> <h3> <a NAME="pan to"></a><font face="Arial,Helvetica">pan to</font></h3> <font face="Arial,Helvetica">Pan to specified position or coordinate in coordinate system.</font> <br><font face="Arial,Helvetica">Syntax: <b>pan to</b> <a href="frame.html#coordinate">coordinate</a>&nbsp; <a href="frame.html#canvas coordinate system">canvas coordinate system</a></font> <br><tt>Example: pan to 20 58 fk5</tt> <h3> <a NAME="rotate"></a><font face="Arial,Helvetica">rotate</font></h3> <font face="Arial,Helvetica">Add to the current rotation value. The value is in degrees.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>rotate</b> numeric</font> <br><tt>Example: rotate 10.5</tt> <h3> <a NAME="rotate to"></a><font face="Arial,Helvetica">rotate to</font></h3> <font face="Arial,Helvetica">Rotate to the specified value. The value is in degrees.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>rotate</b> <b>to</b> numeric</font> <br><tt>Example: rotate to 45</tt> <h3> <a NAME="rotate motion begin"></a><font face="Arial,Helvetica">rotate motion begin</font></h3> <font face="Arial,Helvetica">Start interactive rotation. Bind this command to a Mouse Button Down Event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>rotate motion begin</b></font> <br><tt>Example: rotate motion begin</tt> <h3> <a NAME="rotate motion"></a><font face="Arial,Helvetica">rotate motion</font></h3> <font face="Arial,Helvetica">Continue interactive rotation. The value in the angle in degrees to be added to the current value. Bind this command to a Mouse Motion Event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>rotate motion </b>numeric</font> <br><tt>Example: rotate motion 3.5</tt> <h3> <a NAME="rotate motion end"></a><font face="Arial,Helvetica">rotate motion end</font></h3> <font face="Arial,Helvetica">End interactive rotation. Bind this command to a Mouse Button Release Event.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>rotate motion end</b></font> <br><tt>Example: rotate motion end</tt> <h3> <a NAME="wcs align"></a><font face="Arial,Helvetica">wcs align</font></h3> <font face="Arial,Helvetica">Activate or deactivate the wcs alignment function.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>wcs align</b> <a href="frame.html#yes no">yes no</a></font> <br><tt>Example: wcs align on</tt> <h3> <a NAME="wcs zoom"></a><font face="Arial,Helvetica">wcs zoom</font></h3> <font face="Arial,Helvetica">Set the wcs zoom factor. 1 is the default value. Use this command to scale the current image to match the wcs of another image.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>wcs zoom</b> numeric</font> <br><tt>Example: wcs zoom .5</tt> <h3> <a NAME="zoom"></a><font face="Arial,Helvetica">zoom</font></h3> <font face="Arial,Helvetica">Increase (or decrease) the current zoom factor.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>zoom</b> numeric</font> <br><tt>Example: zoom .5 # zoom in by factor of 2</tt> <h3> <a NAME="zoom about"></a><font face="Arial,Helvetica">zoom about</font></h3> <font face="Arial,Helvetica">Increase (or decrease) the current zoom factor about the specified position in canvas coordinates.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>zoom</b> numeric <b>about</b> <a href="frame.html#coordinate">coordinate</a> <a href="frame.html#canvas coordinate system">canvas coordinate system</a></font> <br><tt>Example: zoom .5 about 25 25 canvas</tt> <h3> <a NAME="zoom to"></a><font face="Arial,Helvetica">zoom to</font></h3> <font face="Arial,Helvetica">Zoom to specified value.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>zoom</b> <b>to</b> numeric</font> <br><tt>Example: zoom .5 # set zoom factor to .5</tt> <h3> <a NAME="zoom to about"></a><font face="Arial,Helvetica">zoom to about</font></h3> <font face="Arial,Helvetica">Set the current zoom factor about the specified position in the specified coordinate system.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>zoom</b> <b>to</b> numeric <b>about </b><a href="frame.html#coordinate">coordinate</a> <a href="frame.html#canvas coordinate system">canvas coordinate system</a></font> <br><tt>Example: zoom to .5 about 40 58 fk5</tt> <h3> <a NAME="zoom to fit"></a><font face="Arial,Helvetica">zoom to fit</font></h3> <font face="Arial,Helvetica">Set the current zoom factor that fills the current frame size.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>zoom</b> <b>to</b> <b>fit</b></font> <br><tt>Example: zoom to fit</tt></blockquote> </body> </html> ����������������������������������./saods9/saotk/doc/frmagnifier.html�����������������������������������������������������������������0000644�0001750�0001750�00000010474�07003722421�016153� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Frame Magnifier Commands</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Frame Magnifier Commands</font></h2> <blockquote> <h2> <font face="Arial,Helvetica">commands</font></h2> <blockquote> <li> <font face="Arial,Helvetica"><a href="#magnifier">magnifier</a></font></li> <li> <font face="Arial,Helvetica"><a href="#magnifier marker">magnifier graphics</a></font></li> <li> <font face="Arial,Helvetica"><a href="#magnifier cursor">magnifier cursor</a></font></li> <li> <font face="Arial,Helvetica"><a href="#magnifier mode">magnifier mode</a></font></li> <li> <font face="Arial,Helvetica"><a href="#magnifier update">magnifier update</a></font></li> <li> <font face="Arial,Helvetica"><a href="#magnifier zoom">magnifier zoom</a></font></li> </blockquote> <h3> <a NAME="magnifier"></a><font face="Arial,Helvetica">magnifier</font></h3> <font face="Arial,Helvetica">Control and define the magnifier for this frame widget. In the second form, the existing magnifier widget specified is assigned to this frame widget. When the update command is executed, the frame widget will calulate the proper image to be displayed and will automatically notified the named magnifier widget.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <a href="frame.html#yes no">yes no</a> # activate or deactivate current magnifier</font> <br><font face="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>magnifer</b> string integer integer # assign a particular magnifier widget to this frame</font> <br><tt>Example: magnifier on</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; magnifier mymagnifier 128 128</tt> <h3> <a NAME="magnifier marker"></a><font face="Arial,Helvetica">magnifier graphics</font></h3> <font face="Arial,Helvetica">Specify if markers and crosshair appear in the current magnifier.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <b>graphics </b><a href="frame.html#yes no">yes no</a></font> <br><tt>Example: magnifier graphics yes</tt> <h3> <a NAME="magnifier cursor"></a><font face="Arial,Helvetica">magnifier cursor</font></h3> <font face="Arial,Helvetica">Specify if the pixel cursor appears in the current magnifier.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <b>cursor </b><a href="frame.html#yes no">yes no</a></font> <br><tt>Example: magnifier cursor yes</tt> <h3> <a NAME="magnifier mode"></a><font face="Arial,Helvetica">magnifier mode</font></h3> <font face="Arial,Helvetica">Specify the algorithm to be used in calculating the magnifier image. The algorithm FAST&nbsp; can only be used for power of two magnification and results are poor for angles not of 0, 90, 270 degrees. Use the algorithm ACCURATE unless performance is unacceptable.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <b>mode </b>[fast | accurate]</font> <br><tt>Example: magnifier mode accurate</tt> <br>&nbsp; <h3> <a NAME="magnifier update"></a><font face="Arial,Helvetica">magnifier update</font></h3> <font face="Arial,Helvetica">Update the current magnifier based on the current cursor position. The coordinates are in canvas coordinates.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <b>update </b>numeric numeric</font> <br><tt>Example: magnifier update 100 200</tt> <h3> <a NAME="magnifier zoom"></a><font face="Arial,Helvetica">magnifier zoom</font></h3> <font face="Arial,Helvetica">Set the current zoom value for the magnifier. For algorithm ACCURATE, all values, including non-integer values are valid. For algorithm FAST, only values of power of two are valid.</font> <br><font face="Arial,Helvetica">Syntax:&nbsp; <b>magnifer</b> <b>zoom </b>numeric</font> <br><tt>Example: magnifier zoom 4</tt> <br>&nbsp; <br>&nbsp; <br>&nbsp;</blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/doc/sample.html����������������������������������������������������������������������0000644�0001750�0001750�00000025407�06774763015�015167� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; SunOS 5.5 sun4m) [Netscape]"> <title>SAOTk Sample Code</title> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000"> <div ALIGN=right> <h2> <font face="Arial,Helvetica"><font size=-1>SAOTk Reference Manual<br> <a href="saotk.html">Table of Contents</a></font></font></h2></div> <h2> <img SRC="sun.gif" height=120 width=120 align=CENTER><font face="Arial,Helvetica">SAOTk Sample Code</font></h2> <blockquote><font face="Arial,Helvetica">Simple Display is a sample FITS Image application using SAOTk. Examples on the use of the Frame and Colorbar widget are given.</font><tt></tt> <p><tt>lappend auto_path .</tt> <br><tt>package require saotk</tt><tt></tt> <p><tt># Variables</tt><tt></tt> <p><tt>set simple(visual) [winfo visual .]</tt> <br><tt>set simple(depth) [winfo depth .]</tt> <br><tt>set current(zoom) 1</tt> <br><tt>set current(orient) none</tt> <br><tt>set current(rotate) 0</tt> <br><tt>set canvas(width) 518</tt> <br><tt>set canvas(height) 518</tt> <br><tt>set colorbar(width) 512</tt> <br><tt>set colorbar(height) 15</tt> <br><tt>set colorbar(map) Grey</tt> <br><tt>set colorbar(invert) 0</tt> <br><tt>set scale(mode) minmax</tt><tt></tt> <p><tt># Procedures</tt><tt></tt> <p><tt>proc OpenFile {} {</tt> <br><tt>&nbsp; set fileName [tk_getOpenFile -parent .]</tt> <br><tt>&nbsp; if {$fileName != ""} {</tt> <br><tt>&nbsp;&nbsp;&nbsp; if [catch {frame1 load $fileName}] {</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp; tk_messageBox -message "Unable to load Fits Image $fileName." \</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -type ok -icon error</tt> <br><tt>&nbsp;&nbsp;&nbsp; }</tt> <br><tt>&nbsp; }</tt> <br><tt>}</tt><tt></tt> <p><tt>proc AdjustColormap {x y} {</tt> <br><tt>&nbsp; global canvas</tt> <br><tt>&nbsp; set cursorX [expr double($x-$canvas(width)/2+512/2) / 512</tt> <br><tt>&nbsp; set cursorY [expr double($y)/512 * 10]</tt> <br><tt>&nbsp; colorbar adjust $cursorX $cursorY</tt> <br><tt>&nbsp; frame1 colormap [colorbar get colormap]</tt> <br><tt>}</tt><tt></tt> <p><tt>proc UpdateColorbarGeometry {} {</tt> <br><tt>&nbsp; global colorbar</tt> <br><tt>&nbsp; set colorbar(width) [expr [winfo width .simple.colorbar]-2]</tt> <br><tt>&nbsp; set colorbar(height) [expr [winfo height .simple.colorbar]-2]</tt> <br><tt>&nbsp; colorbar configure -width $colorbar(width) -height $colorbar(height)</tt> <br><tt>}</tt><tt></tt> <p><tt>proc UpdateCanvasGeometry {} {</tt> <br><tt>&nbsp; global canvas</tt> <br><tt>&nbsp; set canvas(width) [expr [winfo width .simple.image] - 4]</tt> <br><tt>&nbsp; set canvas(height) [expr [winfo height .simple.image] - 4]</tt> <br><tt>&nbsp; set w $canvas(width)</tt> <br><tt>&nbsp; set h $canvas(height)</tt> <br><tt>&nbsp; set x [expr int($canvas(width)/2.) + 2]</tt> <br><tt>&nbsp; set y [expr int($canvas(height)/2.) + 2]</tt> <br><tt>&nbsp; frame1 configure -x $x -y $y -width $w -height $h -anchor center</tt> <br><tt>}</tt><tt></tt> <p><tt>proc CreateColorMenu {} {</tt> <br><tt>&nbsp; global colorbar</tt> <br><tt>&nbsp; set id [colorbar list id]</tt> <br><tt>&nbsp; set count 0</tt> <br><tt>&nbsp; foreach i $id {</tt> <br><tt>&nbsp;&nbsp;&nbsp; set name [colorbar get name $i]</tt> <br><tt>&nbsp;&nbsp;&nbsp; .menuBar.color insert $count radiobutton -label "$name" \</tt> <br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -command "ChangeColormap $i" -variable colorbar(map)</tt> <br><tt>&nbsp;&nbsp;&nbsp; incr count</tt> <br><tt>&nbsp; }</tt> <br><tt>}</tt><tt></tt> <p><tt>proc ChangeColormap {id} {</tt> <br><tt>&nbsp; global colorbar</tt> <br><tt>&nbsp; colorbar map $id</tt> <br><tt>&nbsp; frame1 colormap [colorbar get colormap]</tt> <br><tt>&nbsp; set colorbar(map) [colorbar get name]</tt> <br><tt>&nbsp; set colorbar(invert) [colorbar get invert]</tt> <br><tt>}</tt><tt></tt> <p><tt>proc ScaleMode {} {</tt> <br><tt>&nbsp; global scale</tt> <br><tt>&nbsp; frame1 clip mode $scale(mode)</tt> <br><tt>}</tt><tt></tt> <p><tt># Set Application Behavior</tt><tt></tt> <p><tt>set tk_strictMotif 1</tt> <br><tt>wm title . "Simple Image Display"</tt> <br><tt>. configure -menu .menuBar</tt><tt></tt> <p><tt># Base Frame</tt><tt></tt> <p><tt>frame .simple</tt><tt></tt> <p><tt># Create Colorbar</tt><tt></tt> <p><tt>canvas .simple.colorbar -width $colorbar(width) \</tt> <br><tt>&nbsp; -height $colorbar(height) \</tt> <br><tt>&nbsp; -bd 2 -relief groove -insertofftime 0</tt> <br><tt>.simple.colorbar create colorbar$simple(visual)$simple(depth) \</tt> <br><tt>&nbsp; -width $colorbar(width) -height $colorbar(height) -anchor nw</tt><tt></tt> <p><tt>colorbar set colormap window .simple</tt><tt></tt> <p><tt># Create Image</tt><tt></tt> <p><tt>canvas .simple.image -width $canvas(width) -height $canvas(height) \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -bd 2 -relief groove -highlightthickness 0 -insertofftime 0</tt><tt></tt> <p><tt># Display the Widgets</tt><tt></tt> <p><tt>pack .simple.image -side top -expand true -fill both</tt> <br><tt>pack .simple.colorbar -side bottom -fill x</tt> <br><tt>pack .simple -expand true -fill both</tt><tt></tt> <p><tt># Menu Bar</tt><tt></tt> <p><tt>menu .menuBar -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar add cascade -label "File" -menu .menuBar.file</tt> <br><tt>.menuBar add cascade -label "Color" -menu .menuBar.color</tt> <br><tt>.menuBar add cascade -label "Zoom" -menu .menuBar.zoom</tt> <br><tt>.menuBar add cascade -label "Orient" -menu .menuBar.orient</tt> <br><tt>.menuBar add cascade -label "Scale" -menu .menuBar.scale</tt><tt></tt> <p><tt>menu .menuBar.file -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar.file add command -label "Open..." -command OpenFile</tt> <br><tt>.menuBar.file add separator</tt> <br><tt>.menuBar.file add command -label "Exit" -command exit</tt><tt></tt> <p><tt>menu .menuBar.color -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar.color add separator</tt> <br><tt>.menuBar.color add checkbutton -label "Invert Colormap" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable colorbar(invert) -command {colorbar invert $colorbar(invert)}</tt><tt></tt> <p><tt>CreateColorMenu</tt><tt></tt> <p><tt>menu .menuBar.zoom -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar.zoom add command -label "Zoom In" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -command {frame1 zoom 2; set current(zoom) [frame1 get zoom]}</tt> <br><tt>.menuBar.zoom add command -label "Zoom Out" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -command {frame1 zoom .5; set current(zoom) [frame1 get zoom]}</tt> <br><tt>.menuBar.zoom add separator</tt> <br><tt>.menuBar.zoom add radiobutton -label "1/16" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 0.0625 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "1/8" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 0.125 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "1/4" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 0.25 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "1/2" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 0.5 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "1" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 1 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "2" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 2 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "4" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 4 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "8" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 8 -command {frame1 zoom to $current(zoom)}</tt> <br><tt>.menuBar.zoom add radiobutton -label "16" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(zoom) -value 16 -command {frame1 zoom to $current(zoom)}</tt><tt></tt> <p><tt>menu .menuBar.orient -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar.orient add radiobutton&nbsp; -label "None" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(orient) -value none -command {frame1 orient $current(orient)}</tt> <br><tt>.menuBar.orient add radiobutton&nbsp; -label "Invert X" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(orient) -value x -command {frame1 orient $current(orient)}</tt> <br><tt>.menuBar.orient add radiobutton -label "Invert Y" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(orient) -value y -command {frame1 orient $current(orient)}</tt> <br><tt>.menuBar.orient add radiobutton -label "Invert X&amp;Y" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(orient) -value xy -command {frame1 orient $current(orient)}</tt> <br><tt>.menuBar.orient add separator</tt> <br><tt>.menuBar.orient add radiobutton -label "0 deg" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(rotate) -value 0 -command {frame1 rotate to $current(rotate)}</tt> <br><tt>.menuBar.orient add radiobutton -label "90 deg" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(rotate) -value 90 -command {frame1 rotate to $current(rotate)}</tt> <br><tt>.menuBar.orient add radiobutton -label "180 deg" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(rotate) -value 180 -command {frame1 rotate to $current(rotate)}</tt> <br><tt>.menuBar.orient add radiobutton -label "270 deg" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable current(rotate) -value 270 -command {frame1 rotate to $current(rotate)}</tt><tt></tt> <p><tt># Scale Menu</tt><tt></tt> <p><tt>menu .menuBar.scale -tearoff 0 -selectcolor red</tt> <br><tt>.menuBar.scale add radiobutton -label "Min Max" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable scale(mode) -command ScaleMode -value minmax</tt> <br><tt>.menuBar.scale add radiobutton -label "IRAF ZScale" \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -variable scale(mode) -command ScaleMode -value zscale</tt><tt></tt> <p><tt># Make sure that the wm knows when to swap in the colormap (if needed)</tt><tt></tt> <p><tt>wm colormapwindows . ".simple .simple.image"</tt><tt></tt> <p><tt># Init Colorbar</tt><tt></tt> <p><tt>bind .simple.colorbar &lt;Configure> [list UpdateColorbarGeometry]</tt> <br><tt>colorbar map $colorbar(map)</tt> <br><tt>colorbar invert $colorbar(invert)</tt><tt></tt> <p><tt># Init Frame</tt><tt></tt> <p><tt>bind .simple.image &lt;Configure> [list UpdateCanvasGeometry]</tt> <br><tt>bind .simple.image &lt;Button-3> {AdjustColormap %x %y}</tt> <br><tt>bind .simple.image &lt;B3-Motion> {AdjustColormap %x %y}</tt><tt></tt> <p><tt>.simple.image create frame$simple(visual)$simple(depth) \</tt> <br><tt>&nbsp;&nbsp;&nbsp; -x 0 -y 0 -anchor nw -command frame1</tt><tt></tt> <p><tt>frame1 colormap [colorbar get colormap]</tt> <br><font face="Arial,Helvetica"></font>&nbsp;</blockquote> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013513� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/Makefile����������������������������������������������������������������������0000644�0001750�0001750�00000000770�11641400041�015161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) -I. -I../util -I../../include -I$(X11INCLUDE) SRC = vector.C vector3d.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o $(LIB) ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ��������./saods9/saotk/vector/vector.h����������������������������������������������������������������������0000644�0001750�0001750�00000020413�11700666272�015210� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __vector_h__ #define __vector_h__ #include <math.h> #include <float.h> #include <iostream> using namespace std; #include "tk.h" class Vector3d; class Matrix; class BBox; class Vector { public: double v[3]; public: Vector() {v[0]=0; v[1]=0; v[2]=1;} Vector(double* f) {v[0]=f[0]; v[1]=f[1]; v[2]=1;} Vector(double x, double y) {v[0]=x; v[1]=y; v[2]=1;} Vector(const Vector& a) {v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2];} Vector& operator=(const Vector& a) {v[0]=a.v[0]; v[1]=a.v[1]; v[2]=a.v[2]; return *this;} Vector(const Vector3d&); Vector& operator=(const Vector3d&); double& operator[](int i) {return v[i];} // return element double* vv() {return v;} // return vector Vector& operator+=(const Vector& a) // addition {v[0]+=a.v[0]; v[1]+=a.v[1]; return *this;} Vector& operator-=(const Vector& a) // subtraction {v[0]-=a.v[0]; v[1]-=a.v[1]; return *this;} Vector& operator*=(double f) // scalar multipy {v[0]*=f; v[1]*=f; return *this;} Vector& operator/=(double f) // scalar division {v[0]/=f; v[1]/=f; return *this;} Vector& operator*=(const Matrix& m); // vector multipy Vector abs() {return Vector(fabs(v[0]),fabs(v[1]));} double angle() {return atan2(v[1],v[0]);} Vector ceil() {return Vector(::ceil(v[0]),::ceil(v[1]));} Vector floor() {return Vector(::floor(v[0]),::floor(v[1]));} Vector invert() {return Vector(1/v[0],1/v[1]);} double length() {return sqrt(v[0]*v[0]+v[1]*v[1]);} Vector round() {return Vector((int)(v[0]+.5),(int)(v[1]+.5));} Vector normalize() {double d = sqrt(v[0]*v[0]+v[1]*v[1]); return d ? Vector(v[0]/d,v[1]/d) : Vector();} Vector& clip(const BBox&); Vector TkCanvasPs(Tk_Canvas canvas) {return Vector(v[0], Tk_CanvasPsY(canvas, v[1]));} }; ostream& operator<<(ostream&, const Vector&); istream& operator>>(istream&, Vector&); inline Vector operator-(const Vector& a) {return Vector(-a.v[0],-a.v[1]);} inline Vector operator+(const Vector& a, const Vector& b) {return Vector(a) +=b;} inline Vector operator-(const Vector& a, const Vector& b) {return Vector(a) -=b;} inline Vector operator*(const Vector& a, double b) {return Vector(a) *=b;} inline Vector operator/(const Vector& a, double b) {return Vector(a) /=b;} inline Vector operator*(const Vector& v, const Matrix& m) {return Vector(v) *=m;} inline double operator*(const Vector& a, const Vector& b) // dot product {double r =0; r+=a.v[0]*b.v[0]; r+=a.v[1]*b.v[1]; return r;} class Vertex { public: Vector vector; private: Vertex* next_; Vertex* previous_; public: Vertex() {next_=NULL; previous_=NULL;} Vertex(double x, double y) {vector=Vector(x,y); next_=NULL; previous_=NULL;} Vertex(const Vector& a) {vector=a; next_=NULL; previous_=NULL;} Vertex(const Vertex& a) {vector=a.vector; next_=a.next_; previous_=a.previous_;} Vertex& operator=(const Vertex& a) {vector=a.vector; next_=a.next_; previous_=a.previous_; return *this;} Vertex* next() {return next_;} Vertex* previous() {return previous_;} void setNext(Vertex* v) {next_=v;} void setPrevious(Vertex* v) {previous_=v;} }; ostream& operator<<(ostream&, const Vertex&); class Matrix { public: double m[3][3]; public: Matrix() { m[0][0]=1; m[0][1]=0; m[0][2]=0; m[1][0]=0; m[1][1]=1; m[1][2]=0; m[2][0]=0; m[2][1]=0; m[2][2]=1;} Matrix(double a, double b, double c, double d, double e, double f) { m[0][0]=a; m[0][1]=b; m[0][2]=0; m[1][0]=c; m[1][1]=d; m[1][2]=0; m[2][0]=e; m[2][1]=f; m[2][2]=1;} Matrix(double a, double b, double c, double d, double e, double f, double g, double h, double i) { m[0][0]=a; m[0][1]=b; m[0][2]=c; m[1][0]=d; m[1][1]=e; m[1][2]=f; m[2][0]=g; m[2][1]=h; m[2][2]=i;} Matrix(const Matrix& a) { m[0][0]=a.m[0][0]; m[0][1]=a.m[0][1]; m[0][2]=a.m[0][2]; m[1][0]=a.m[1][0]; m[1][1]=a.m[1][1]; m[1][2]=a.m[1][2]; m[2][0]=a.m[2][0]; m[2][1]=a.m[2][1]; m[2][2]=a.m[2][2];} Matrix& operator=(const Matrix& a) { m[0][0]=a.m[0][0]; m[0][1]=a.m[0][1]; m[0][2]=a.m[0][2]; m[1][0]=a.m[1][0]; m[1][1]=a.m[1][1]; m[1][2]=a.m[1][2]; m[2][0]=a.m[2][0]; m[2][1]=a.m[2][1]; m[2][2]=a.m[2][2]; return *this;} double matrix(int i, int j) // return element {return m[i][j];} Vector operator[](int i) // return row {return Vector(m[i]);} double* mm() const // return matrix {return (double*)m;} Matrix& identity() { m[0][0]=1; m[0][1]=0; m[0][2]=0; m[1][0]=0; m[1][1]=1; m[1][2]=0; m[2][0]=0; m[2][1]=0; m[2][2]=1; return *this;} Matrix& operator*=(const Matrix&); // matrix multiply Matrix invert(); Matrix cofactor(); Matrix adjoint(); double det(); }; ostream& operator<<(ostream&, const Matrix&); istream& operator>>(istream&, Matrix&); inline Matrix operator*(const Matrix& a, const Matrix& b) {return Matrix(a) *= b;} inline Vector& Vector::operator*=(const Matrix& m) { double vv[3]; double* mm = (double*)(m.m); vv[0] = v[0]*mm[0] + v[1]*mm[3] + v[2]*mm[6]; vv[1] = v[0]*mm[1] + v[1]*mm[4] + v[2]*mm[7]; vv[2] = v[0]*mm[2] + v[1]*mm[5] + v[2]*mm[8]; v[0] = vv[0]; v[1] = vv[1]; v[2] = vv[2]; return *this; } class Translate : public Matrix { public: Translate() {}; Translate(double x, double y) {m[2][0]=x; m[2][1]=y;} Translate(const Vector& v) {m[2][0]=v.v[0]; m[2][1]=v.v[1];} Translate(const Matrix& a) {m[2][0] = a.m[2][0]; m[2][1] = a.m[2][1];} }; ostream& operator<<(ostream&, const Translate&); istream& operator>>(istream&, Translate&); class Scale : public Matrix { public: Scale() {}; Scale(double a) {m[0][0]=a; m[1][1]=a;} Scale(double a, double b) {m[0][0]=a; m[1][1]=b;} Scale(const Vector& v) {m[0][0]=v.v[0]; m[1][1]=v.v[1];} Scale(const Matrix& a) {m[0][0] = a.m[0][0]; m[1][1] = a.m[1][1];} }; ostream& operator<<(ostream&, const Scale&); istream& operator>>(istream&, Scale&); class FlipX : public Matrix { public: FlipX() {m[0][0] = -1;} }; class FlipY : public Matrix { public: FlipY() {m[1][1] = -1;} }; class FlipXY : public Matrix { public: FlipXY() {m[0][0] = -1; m[1][1] = -1;} }; class Rotate : public Matrix { public: Rotate() {}; Rotate(double); Rotate(double a, double b, double c, double d) {m[0][0] = a; m[0][1] = b; m[1][0] = c; m[1][1] = d;} Rotate(const Matrix& a) { m[0][0]=a.m[0][0]; m[0][1]=a.m[0][1]; m[1][0]=a.m[1][0]; m[1][1]=a.m[1][1];} }; ostream& operator<<(ostream&, const Rotate&); istream& operator>>(istream&, Rotate&); class BBox { public: Vector ll; Vector ur; public: BBox() {} BBox(double w, double h) {ll.v[0] = 0; ll.v[1] = 0; ur.v[0] = w; ur.v[1] = h;} BBox(const Vector& v) {ll=v; ur=v;} BBox(double, double, double, double); BBox(const Vector&, const Vector&); BBox(const BBox& a) {ll=a.ll; ur=a.ur;} BBox& operator=(const BBox& a) {ll=a.ll; ur=a.ur; return *this;} Vector lr() {return Vector(ur[0],ll[1]);} Vector ul() {return Vector(ll[0],ur[1]);} BBox& operator+=(const Vector& v) // addition {ll+=v; ur+=v; return *this;} BBox& operator-=(const Vector& a) // subtraction {ll-=a; ur-=a; return *this;} BBox& operator*=(const Matrix& m) // multiply {ll*=m; ur*=m; return *this;} Vector center() {return (ur-ll)/2 + ll;} Vector size() {return ur - ll;} int isEmpty() const {Vector v = ur-ll; return (v[0]==0 && v[1]==0);} int isIn(const Vector&) const; int isIn(const BBox&) const; BBox& expand(double a) {ll-=Vector(a,a); ur+=Vector(a,a); return *this;} BBox& expand(const Vector& v) {ll-=v; ur+=v; return *this;} BBox& shrink(double a) {ll+=Vector(a,a); ur-=Vector(a,a); return *this;} BBox& shrink(const Vector& v) {ll+=v; ur-=v; return *this;} BBox& bound(BBox); BBox& bound(const Vector&); }; ostream& operator<<(ostream&, const BBox&); inline BBox operator+(const BBox& b, const Vector& v) {return BBox(b) += v;} inline BBox operator-(const BBox& b, const Vector& v) {return BBox(b) -= v;} inline BBox operator*(const BBox& b, const Matrix& m) {return BBox(b) *= m;} BBox intersect(const BBox&, const BBox&); #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/vector3d.C��������������������������������������������������������������������0000644�0001750�0001750�00000023340�11703626104�015365� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "vector3d.h" #include "vector.h" #include "fuzzy.h" // Vector3d Vector3d::Vector3d(const Vector& a) { v[0]=a.v[0]; v[1]=a.v[1]; v[2]=0; v[3]=1; } Vector3d::Vector3d(const Vector& a, double z) { v[0]=a.v[0]; v[1]=a.v[1]; v[2]=z; v[3]=1; } Vector3d& Vector3d::operator=(const Vector& a) { v[0]=a.v[0]; v[1]=a.v[1]; v[2]=0; v[3]=1; return *this; } Vector Vector3d::TkCanvasPs(Tk_Canvas canvas) { return Vector(v[0], Tk_CanvasPsY(canvas, v[1])); } ostream& operator<<(ostream& s, const Vector3d& v) { s << ' ' << v.v[0] << ' ' << v.v[1] << ' ' << v.v[2]; return s; } istream& operator>>(istream& s, Vector3d& v) { s >> v.v[0] >> v.v[1] >> v.v[2]; return s; } // Vertex3d ostream& operator<<(ostream& s, const Vertex3d& v) { s << v.vector; return s; } // Matrix3d Matrix3d& Matrix3d::operator*=(const Matrix3d& a) { Matrix3d r; for (int ii=0; ii<4; ii++) for (int jj=0; jj<4; jj++) r.m[ii][jj] = m[ii][0]*a.m[0][jj] + m[ii][1]*a.m[1][jj] + m[ii][2]*a.m[2][jj] + m[ii][3]*a.m[3][jj]; return *this=r; } Matrix3d::Matrix3d(const Matrix& a) { m[0][0]=a.m[0][0]; m[0][1]=a.m[0][1]; m[0][2]=0; m[0][3]=0; m[1][0]=a.m[1][0]; m[1][1]=a.m[1][1]; m[1][2]=0; m[1][3]=0; m[2][0]=0; m[2][1]=0; m[2][2]=1; m[2][3]=0; m[3][0]=a.m[2][0]; m[3][1]=a.m[2][1]; m[3][2]=0; m[3][3]=1; } Matrix3d Matrix3d::invert() { Matrix3d cc = this->cofactor(); Matrix3d aa = cc.adjoint(); double dd = m[0][0]*aa.m[0][0] + m[0][1]*aa.m[1][0] + m[0][2]*aa.m[2][0] + m[0][3]*aa.m[3][0]; Matrix3d rr; for (int ii=0; ii<4; ii++ ) for (int jj=0; jj<4; jj++) rr.m[ii][jj] = aa.m[ii][jj]/dd; return rr; } Matrix3d Matrix3d::cofactor() { Matrix3d rr; rr.m[0][0] = +det2d(m[1][1],m[1][2],m[1][3], m[2][1],m[2][2],m[2][3], m[3][1],m[3][2],m[3][3]); rr.m[0][1] = -det2d(m[1][0],m[1][2],m[1][3], m[2][0],m[2][2],m[2][3], m[3][0],m[3][2],m[3][3]); rr.m[0][2] = +det2d(m[1][0],m[1][1],m[1][3], m[2][0],m[2][1],m[2][3], m[3][0],m[3][1],m[3][3]); rr.m[0][3] = -det2d(m[1][0],m[1][1],m[1][2], m[2][0],m[2][1],m[2][2], m[3][0],m[3][1],m[3][2]); rr.m[1][0] = -det2d(m[0][1],m[0][2],m[0][3], m[2][1],m[2][2],m[2][3], m[3][1],m[3][2],m[3][3]); rr.m[1][1] = +det2d(m[0][0],m[0][2],m[0][3], m[2][0],m[2][2],m[2][3], m[3][0],m[3][2],m[3][3]); rr.m[1][2] = -det2d(m[0][0],m[0][1],m[0][3], m[2][0],m[2][1],m[2][3], m[3][0],m[3][1],m[3][3]); rr.m[1][3] = +det2d(m[0][0],m[0][1],m[0][2], m[2][0],m[2][1],m[2][2], m[3][0],m[3][1],m[3][2]); rr.m[2][0] = +det2d(m[0][1],m[0][2],m[0][3], m[1][1],m[1][2],m[1][3], m[3][1],m[3][2],m[3][3]); rr.m[2][1] = -det2d(m[0][0],m[0][2],m[0][3], m[1][0],m[1][2],m[1][3], m[3][0],m[3][2],m[3][3]); rr.m[2][2] = +det2d(m[0][0],m[0][1],m[0][3], m[1][0],m[1][1],m[1][3], m[3][0],m[3][1],m[3][3]); rr.m[2][3] = -det2d(m[0][0],m[0][1],m[0][2], m[1][0],m[1][1],m[1][2], m[3][0],m[3][1],m[3][2]); rr.m[3][0] = -det2d(m[0][1],m[0][2],m[0][3], m[1][1],m[1][2],m[1][3], m[2][1],m[2][2],m[2][3]); rr.m[3][1] = +det2d(m[0][0],m[0][2],m[0][3], m[1][0],m[1][2],m[1][3], m[2][0],m[2][2],m[2][3]); rr.m[3][2] = -det2d(m[0][0],m[0][1],m[0][3], m[1][0],m[1][1],m[1][3], m[2][0],m[2][1],m[2][3]); rr.m[3][3] = +det2d(m[0][0],m[0][1],m[0][2], m[1][0],m[1][1],m[1][2], m[2][0],m[2][1],m[2][2]); return rr; } Matrix3d Matrix3d::adjoint() { Matrix3d rr; for (int ii=0; ii<4; ii++) for (int jj=0; jj<4; jj++) rr.m[jj][ii] = m[ii][jj]; return rr; } double Matrix3d::det() { Matrix3d cc = this->cofactor(); Matrix3d aa = cc.adjoint(); return m[0][0]*aa.m[0][0] + m[0][1]*aa.m[1][0] + m[0][2]*aa.m[2][0] + m[0][3]*aa.m[3][0]; } void Matrix3d::dump() { for (int ii=0; ii<4; ii++) { for (int jj=0; jj<4; jj++) cerr << m[ii][jj] << ' '; cerr << endl; } cerr << endl; } ostream& operator<<(ostream& s, const Matrix3d& m) { s << ' '; for (int ii=0; ii<4; ii++) for (int jj=0; jj<3; jj++) s << m.m[ii][jj] << ' '; return s; } istream& operator>>(istream& s, Matrix3d& m) { for (int ii=0; ii<4; ii++ ) for (int jj=0; jj<3; jj++) s >> m.m[ii][jj]; return s; } // Translate3d Translate3d::Translate3d(const Vector& v) { m[3][0]=v.v[0]; m[3][1]=v.v[1]; m[3][2]=0; } Translate3d::Translate3d(const Vector& v, double z) { m[3][0]=v.v[0]; m[3][1]=v.v[1]; m[3][2]=z; } ostream& operator<<(ostream& s, const Translate3d& m) { s << ' ' << m.m[3][0] << ' ' << m.m[3][1] << ' ' << m.m[3][2] << ' '; return s; } istream& operator>>(istream& s, Translate3d& m) { s >> m.m[3][0] >> m.m[3][1] >> m.m[3][2]; return s; } // Scale3d Scale3d::Scale3d(const Vector& v) { m[0][0]=v.v[0]; m[1][1]=v.v[1]; m[2][2]=1; } Scale3d::Scale3d(const Vector& v, double c) { m[0][0]=v.v[0]; m[1][1]=v.v[1]; m[2][2]=c; } ostream& operator<<(ostream& s, const Scale3d& m) { s << ' ' << m.m[0][0] << ' ' << m.m[1][1] << ' ' << m.m[2][2] << ' '; return s; } istream& operator>>(istream& s, Scale3d& m) { s >> m.m[0][0] >> m.m[1][1] >> m.m[2][2]; return s; } // RotateX3d RotateX3d::RotateX3d(double a) : Matrix3d() { m[1][1] = cos(a); m[1][2] = sin(a); m[2][1] = -sin(a); m[2][2] = cos(a); // this fixes a problem with numbers too small and tring to invert the matrix tzero(&m[1][1]); tzero(&m[1][2]); tzero(&m[2][1]); tzero(&m[2][2]); } ostream& operator<<(ostream& s, const RotateX3d& m) { s << ' ' << m.m[1][1] << ' ' << m.m[1][2] << ' ' << m.m[2][1] << ' ' << m.m[2][2] << ' '; return s; } istream& operator>>(istream& s, RotateX3d& m) { s >> m.m[1][1] >> m.m[1][2] >> m.m[2][1] >> m.m[2][2]; return s; } // RotateY3d RotateY3d::RotateY3d(double a) : Matrix3d() { m[0][0] = cos(a); m[0][2] = -sin(a); m[2][0] = sin(a); m[2][2] = cos(a); // this fixes a problem with numbers too small and tring to invert the matrix tzero(&m[0][0]); tzero(&m[0][2]); tzero(&m[2][0]); tzero(&m[2][2]); } ostream& operator<<(ostream& s, const RotateY3d& m) { s << ' ' << m.m[0][0] << ' ' << m.m[0][2] << ' ' << m.m[2][0] << ' ' << m.m[2][2] << ' '; return s; } istream& operator>>(istream& s, RotateY3d& m) { s >> m.m[0][0] >> m.m[0][2] >> m.m[2][0] >> m.m[2][2]; return s; } // RotateZ3d RotateZ3d::RotateZ3d(double a) : Matrix3d() { m[0][0] = cos(a); m[0][1] = sin(a); m[1][0] = -sin(a); m[1][1] = cos(a); // this fixes a problem with numbers too small and tring to invert the matrix tzero(&m[0][0]); tzero(&m[0][1]); tzero(&m[1][0]); tzero(&m[1][1]); } ostream& operator<<(ostream& s, const RotateZ3d& m) { s << ' ' << m.m[0][0] << ' ' << m.m[0][1] << ' ' << m.m[1][0] << ' ' << m.m[1][1] << ' '; return s; } istream& operator>>(istream& s, RotateZ3d& m) { s >> m.m[0][0] >> m.m[0][1] >> m.m[1][0] >> m.m[1][1]; return s; } // BBox3d BBox3d::BBox3d(double a, double b, double c, double d, double e, double f) { // we want a 'positive' cube ll.v[0] = a < d ? a : d; ll.v[1] = b < e ? b : e; ll.v[2] = c < f ? c : f; ur.v[0] = a < d ? d : a; ur.v[1] = b < e ? e : b; ur.v[2] = c < f ? f : c; } BBox3d::BBox3d(const Vector3d& l, const Vector3d& h) { // we want a 'positive' cube ll.v[0] = l.v[0] < h.v[0] ? l.v[0] : h.v[0]; ll.v[1] = l.v[1] < h.v[1] ? l.v[1] : h.v[1]; ll.v[2] = l.v[2] < h.v[2] ? l.v[2] : h.v[2]; ur.v[0] = l.v[0] < h.v[0] ? h.v[0] : l.v[0]; ur.v[1] = l.v[1] < h.v[1] ? h.v[1] : l.v[1]; ur.v[2] = l.v[2] < h.v[2] ? h.v[2] : l.v[2]; } int BBox3d::isIn(const Vector3d& v) const { return !(v.v[0] < ll.v[0] || v.v[1] < ll.v[1] || v.v[2] < ll.v[2] || v.v[0] > ur.v[0] || v.v[1] > ur.v[1] || v.v[2] > ur.v[2]); } BBox3d& BBox3d::bound(const Vector3d& v) { if (v.v[0] < ll[0]) ll[0] = v.v[0]; if (v.v[1] < ll[1]) ll[1] = v.v[1]; if (v.v[2] < ll[2]) ll[2] = v.v[2]; if (v.v[0] > ur[0]) ur[0] = v.v[0]; if (v.v[1] > ur[1]) ur[1] = v.v[1]; if (v.v[2] > ur[2]) ur[2] = v.v[2]; return *this; } BBox3d& BBox3d::clip(const Vector3d& v) { if (ll[0]<0) ll[0] = 0; if (ll[1]<0) ll[1] = 0; if (ll[2]<0) ll[2] = 0; if (ur[0]<0) ur[0] = 0; if (ur[1]<0) ur[1] = 0; if (ur[2]<0) ur[2] = 0; if (ll[0]>v.v[0]) ll[0] = v.v[0]; if (ll[1]>v.v[1]) ll[1] = v.v[1]; if (ll[2]>v.v[2]) ll[2] = v.v[2]; if (ur[0]>v.v[0]) ur[0] = v.v[0]; if (ur[1]>v.v[1]) ur[1] = v.v[1]; if (ur[2]>v.v[2]) ur[2] = v.v[2]; return *this; } ostream& operator<<(ostream& s, const BBox3d& b) { s << b.ll << b.ur; return s; } // WorldToView Matrix3d WorldToView3d(const Vector3d& cop, const Vector3d& vpn, const Vector3d& vup) { Vector3d zv = ((Vector3d)vpn).normalize(); Vector3d xv = cross(zv,(Vector3d&)vup).normalize(); Vector3d yv = cross(xv,zv).normalize(); return Translate3d(-cop) * Matrix3d(xv[0],yv[0],zv[0], xv[1],yv[1],zv[1], xv[2],yv[2],zv[2], 0, 0, 0); } Matrix3d WorldToView3d(const Vector3d& cop, double head, double pitch, double bank) { return Translate3d(-cop) * RotateY3d(head) * RotateX3d(pitch) * RotateZ3d(bank) * Scale3d(1,1,-1); } Matrix3d WorldToView3d(const Vector3d& cop, const Vector3d& vpn, double bank) { Vector3d zv = -((Vector3d)vpn).normalize(); double l=sqrt(zv[0]*zv[0]+zv[2]*zv[2]); return Translate3d(-cop) * RotateY3d(zv[2]/l,zv[0]/l,-zv[0]/l,zv[2]/l) * RotateX3d(l,zv[1],-zv[1],l) * RotateZ3d(bank) * Scale3d(1,1,-1); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/vectorold.h�������������������������������������������������������������������0000644�0001750�0001750�00000015502�11700666272�015712� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __vector_h__ #define __vector_h__ #include <math.h> #include <float.h> #include <iostream> using namespace std; #include "tk.h" class Vector; class Vertex; class Matrix; class Translate; class Rotate; class Scale; class FlipX; class FlipY; class FlipXY; class BBox; class Vector { friend class Matrix; friend class Translate; friend class Scale; friend class BBox; public: double v[3]; public: Vector() {v[0]=0;v[1]=0;v[2]=1;} // constructor Vector(double* f) {v[0]=f[0];v[1]=f[1];v[2]=f[2];} // constructor Vector(double x, double y) {v[0]=x;v[1]=y;v[2]=1;} // constructor Vector(double x, double y, double z) {v[0]=x;v[1]=y;v[2]=z;} // constructor Vector(const Vector& a) {v[0]=a.v[0];v[1]=a.v[1];v[2]=a.v[2];} // copy Vector& operator=(const Vector& a) {v[0]=a.v[0];v[1]=a.v[1];v[2]=a.v[2];return *this;} double& operator[](int i) {return v[i];} Vector abs(); double length(); double angle(); double avg(); double max(); double min(); Vector round(); Vector floor(); Vector ceil(); Vector invert(); Vector normalize(); Vector TkCanvasPs(Tk_Canvas); friend Vector operator-(const Vector&); // unary minus friend Vector operator*(const Vector&, const Matrix&); // vector/matrix mult friend double operator*(const Vector&, const Vector&); // dot product friend ostream& operator<<(ostream&, const Vector&); friend istream& operator>>(istream&, Vector&); Vector& operator+=(const Vector&); // addition Vector& operator-=(const Vector&); // subtraction Vector& operator*=(double); // scalar multipy Vector& operator/=(double); // scalar division Vector& operator*=(const Matrix&); // vector multiply friend BBox intersect(const BBox&, const BBox&); // the following are not valid for 2D graphics: Vector& div(double); Vector& minus(const Vector&); friend Vector mult(const Vector&, double); Vector& operator*=(const Vector&); Vector& operator/=(const Vector&); }; Vector operator+(const Vector&, const Vector&); // addition Vector operator-(const Vector&, const Vector&); // subtration Vector operator*(const Vector&, double); // scalar multiply Vector operator/(const Vector&, double); // scalar division Vector cross(Vector&, Vector&); class Vertex { public: Vector vector; private: Vertex* next_; Vertex* previous_; public: Vertex(); Vertex(double, double); Vertex(const Vector&); Vertex* next() {return next_;} Vertex* previous() {return previous_;} void setNext(Vertex* v) {next_ = v;} void setPrevious(Vertex* v) {previous_ = v;} friend ostream& operator<<(ostream&, const Vertex&); }; class Matrix { friend class Vector; friend class Translate; friend class Rotate; friend class Scale; protected: double m[3][3]; public: Matrix(); // constructor Matrix(const Vector&, const Vector&, const Vector&); // constructor Matrix(double, double, double, double, double, double); Matrix(const Matrix&); // copy constructor Matrix& operator=(const Matrix&); // assignment Vector operator[](int); // return row double matrix(int i, int j) {return m[i][j];} // return element Matrix& operator*=(double); // scalar multiply Matrix& operator/=(double); // scalar division Matrix& operator*=(const Matrix&); // matrix multiply Matrix invert(); // matrix inverse Matrix invert2(); Matrix cofactor(); Matrix adjoint(); Matrix abs(); // returns abs with no translation Matrix& identity(); // sets to identity matrix; int isIdentity(); double* mm() {return (double*)m;} friend Vector operator*(const Vector&, const Matrix&); // vector/matrix mult friend ostream& operator<<(ostream&, const Matrix&); friend istream& operator>>(istream&, Matrix&); }; Matrix operator*(const Matrix&, double); // scalar multiply Matrix operator/(const Matrix&, double); // scalar division Matrix operator*(const Matrix&, const Matrix&); // matrix multiply class Translate : public Matrix { public: Translate() {}; // constructor Translate(double, double); // constructor Translate(const Vector&); // constructor Translate(const Matrix&); // copy constructor Translate& operator=(const Matrix&); // assignment friend ostream& operator<<(ostream&, const Translate&); friend istream& operator>>(istream&, Translate&); }; class Rotate : public Matrix { public: Rotate() {}; // constructor Rotate(double); // constructor Rotate(double, double, double, double); // constructor Rotate(const Matrix&); // copy constructor Rotate& operator=(const Matrix&); // assignment friend ostream& operator<<(ostream&, const Rotate&); friend istream& operator>>(istream&, Rotate&); }; class Scale : public Matrix { public: Scale() {}; // constructor Scale(double); // constructor Scale(double, double); // constructor Scale(const Vector&); // constructor Scale(const Matrix&); // copy constructor Scale& operator=(const Matrix&); // assignment friend ostream& operator<<(ostream&, const Scale&); friend istream& operator>>(istream&, Scale&); }; class FlipX : public Matrix { public: FlipX(); // constructor }; class FlipY : public Matrix { public: FlipY(); // constructor }; class FlipXY : public Matrix { public: FlipXY(); // constructor }; class BBox { public: Vector ll; Vector ur; public: BBox() {} BBox(const Vector&, const Vector&); BBox(const Vector&); BBox(double, double); BBox(double, double, double, double); BBox& operator+=(const Vector&); // addition BBox& operator-=(const Vector&); // subtraction BBox& operator*=(const Matrix&); // multiplication int isIn(const Vector&) const; int isIn(const BBox&) const; int isEmpty() const; Vector center(); Vector size(); Vector lr() {return Vector(ur[0],ll[1]);} Vector ul() {return Vector(ll[0],ur[1]);} BBox& expand(double); BBox& expand(const Vector&); BBox& shrink(double); BBox& shrink(const Vector&); BBox& bound(const Vector&); BBox& bound(BBox); friend ostream& operator<<(ostream&, const BBox&); }; BBox operator+(const BBox&, const Vector&); // addition BBox operator-(const BBox&, const Vector&); // subtraction BBox operator*(const BBox&, const Matrix&); BBox intersect(const BBox&, const BBox&); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/vector.C����������������������������������������������������������������������0000644�0001750�0001750�00000013120�11700666272�015140� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "vector.h" #include "vector3d.h" #include "fuzzy.h" // Vector Vector::Vector(const Vector3d& a) { v[0]=a.v[0]; v[1]=a.v[1]; v[2]=1; } Vector& Vector::operator=(const Vector3d& a) { v[0]=a.v[0]; v[1]=a.v[1]; v[2]=1; return *this; } Vector& Vector::clip(const BBox& bb) { Vector ll=bb.ll; Vector ur=bb.ur; if (v[0]<ll[0]) v[0]=ll[0]; if (v[0]>ur[0]) v[0]=ur[0]; if (v[1]<ll[1]) v[1]=ll[1]; if (v[1]>ur[1]) v[1]=ur[1]; return *this; } ostream& operator<<(ostream& s, const Vector& v) { s << ' ' << v.v[0] << ' ' << v.v[1] << ' '; return s; } istream& operator>>(istream& s, Vector& v) { s >> v.v[0] >> v.v[1]; return s; } // Vertex ostream& operator<<(ostream& s, const Vertex& v) { s << v.vector; return s; } // Matrix Matrix& Matrix::operator*=(const Matrix& a) { Matrix r; for (int i=0; i<3; i++) for (int j=0; j<3; j++) r.m[i][j] = m[i][0]*a.m[0][j] + m[i][1]*a.m[1][j] + m[i][2]*a.m[2][j]; return *this=r; } Matrix Matrix::invert() { Matrix cc = this->cofactor(); Matrix aa = cc.adjoint(); double dd = m[0][0]*aa.m[0][0] + m[0][1]*aa.m[1][0] + m[0][2]*aa.m[2][0]; Matrix rr; for (int ii=0; ii<3; ii++ ) for (int jj=0; jj<3; jj++) rr.m[ii][jj] = aa.m[ii][jj]/dd; return rr; } Matrix Matrix::cofactor() { Matrix rr; rr.m[0][0] = +(m[1][1]*m[2][2]-m[1][2]*m[2][1]); rr.m[0][1] = -(m[1][0]*m[2][2]-m[1][2]*m[2][0]); rr.m[0][2] = +(m[1][0]*m[2][1]-m[1][1]*m[2][0]); rr.m[1][0] = -(m[0][1]*m[2][2]-m[0][2]*m[2][1]); rr.m[1][1] = +(m[0][0]*m[2][2]-m[0][2]*m[2][0]); rr.m[1][2] = -(m[0][0]*m[2][1]-m[0][1]*m[2][0]); rr.m[2][0] = +(m[0][1]*m[1][2]-m[0][2]*m[1][1]); rr.m[2][1] = -(m[0][0]*m[1][2]-m[0][2]*m[1][0]); rr.m[2][2] = +(m[0][0]*m[1][1]-m[0][1]*m[1][0]); return rr; } double Matrix::det() { return + m[0][0]*(m[1][1]*m[2][2]-m[1][2]*m[2][1]) - m[0][1]*(m[1][0]*m[2][2]-m[1][2]*m[2][0]) + m[0][2]*(m[1][0]*m[2][1]-m[1][1]*m[2][0]); } Matrix Matrix::adjoint() { Matrix rr; for (int ii=0; ii<3; ii++) for (int jj=0; jj<3; jj++) rr.m[jj][ii] = m[ii][jj]; return rr; } ostream& operator<<(ostream& s, const Matrix& m) { s << ' '; for (int i=0; i<3; i++) for (int j=0; j<2; j++) s << m.m[i][j] << ' '; return s; } istream& operator>>(istream& s, Matrix& m) { for (int i=0; i<3; i++ ) for (int j=0; j<2; j++) s >> m.m[i][j]; return s; } // Translate ostream& operator<<(ostream& s, const Translate& m) { s << ' ' << m.m[2][0] << ' ' << m.m[2][1] << ' '; return s; } istream& operator>>(istream& s, Translate& m) { s >> m.m[2][0] >> m.m[2][1]; return s; } // Scale ostream& operator<<(ostream& s, const Scale& m) { s << ' ' << m.m[0][0] << ' ' << m.m[1][1] << ' '; return s; } istream& operator>>(istream& s, Scale& m) { s >> m.m[0][0] >> m.m[1][1]; return s; } // Rotate Rotate::Rotate(double a) : Matrix() { // note: signs reverse for X-Windows (origin is upper left) m[0][0] = cos(a); m[0][1] = -sin(a); m[1][0] = sin(a); m[1][1] = cos(a); // this fixes a problem with numbers too small and tring to invert the matrix tzero(&m[0][0]); tzero(&m[0][1]); tzero(&m[1][0]); tzero(&m[1][1]); } ostream& operator<<(ostream& s, const Rotate& m) { s << ' ' << m.m[0][0] << ' ' << m.m[0][1] << ' ' << m.m[1][0] << ' ' << m.m[1][1] << ' '; return s; } istream& operator>>(istream& s, Rotate& m) { s >> m.m[0][0] >> m.m[0][1] >> m.m[1][0] >> m.m[1][1]; return s; } // BBox BBox::BBox(double a, double b, double c, double d) { // we want a 'positive' box ll.v[0] = a < c ? a : c; ll.v[1] = b < d ? b : d; ur.v[0] = a < c ? c : a; ur.v[1] = b < d ? d : b; } BBox::BBox(const Vector& l, const Vector& h) { // we want a 'positive' box ll.v[0] = l.v[0] < h.v[0] ? l.v[0] : h.v[0]; ll.v[1] = l.v[1] < h.v[1] ? l.v[1] : h.v[1]; ur.v[0] = l.v[0] < h.v[0] ? h.v[0] : l.v[0]; ur.v[1] = l.v[1] < h.v[1] ? h.v[1] : l.v[1]; } int BBox::isIn(const Vector& v) const { return !(v.v[0] < ll.v[0] || v.v[1] < ll.v[1] || v.v[0] > ur.v[0] || v.v[1] > ur.v[1]); } int BBox::isIn(const BBox& bb) const { // return 0 if outside, > 0 if intersection // = 4 if inside BBox b = bb; return isIn(b.ll) + isIn(b.ur) + isIn(b.ul()) + isIn(b.lr()); } BBox& BBox::bound(const Vector& v) { if (v.v[0] < ll[0]) ll[0] = v.v[0]; if (v.v[1] < ll[1]) ll[1] = v.v[1]; if (v.v[0] > ur[0]) ur[0] = v.v[0]; if (v.v[1] > ur[1]) ur[1] = v.v[1]; return *this; } BBox& BBox::bound(BBox b) { this->bound(b.ll); this->bound(b.lr()); this->bound(b.ur); this->bound(b.ul()); return *this; } BBox intersect(const BBox& a, const BBox& b) { // test for obvious int ab = a.isIn(b); int ba = b.isIn(a); // no intersection? if (ab==0 && ba == 0) { // maybe they are just crossed, check the centers int abc = a.isIn(((BBox&)b).center()); int bac = b.isIn(((BBox&)a).center()); if (abc==0 && bac==0) return BBox(); } if (ab == 4) // b is inside a return b; if (ba == 4) // a is inside b return a; // else, there seems to be some overlap BBox r; r.ll.v[0] = (a.ll.v[0] > b.ll.v[0]) ? a.ll.v[0] : b.ll.v[0]; r.ll.v[1] = (a.ll.v[1] > b.ll.v[1]) ? a.ll.v[1] : b.ll.v[1]; r.ur.v[0] = (a.ur.v[0] < b.ur.v[0]) ? a.ur.v[0] : b.ur.v[0]; r.ur.v[1] = (a.ur.v[1] < b.ur.v[1]) ? a.ur.v[1] : b.ur.v[1]; return r; } ostream& operator<<(ostream& s, const BBox& b) { s << b.ll << b.ur; return s; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/vectorold.C�������������������������������������������������������������������0000644�0001750�0001750�00000033543�11700666272�015652� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "vector.h" // Vector Vector operator-(const Vector& a) { return Vector(-a.v[0], -a.v[1]); } Vector& Vector::operator+=(const Vector& a) { v[0]+=a.v[0]; v[1]+=a.v[1]; return *this; } Vector operator+(const Vector& a, const Vector& b) { Vector r=a; r+=b; return r; } Vector& Vector::operator-=(const Vector& a) { v[0]-=a.v[0]; v[1]-=a.v[1]; return *this; } Vector operator-(const Vector& a, const Vector& b) { Vector r=a; r-=b; return r; } Vector& Vector::operator*=(double f) { v[0]*=f; v[1]*=f; return *this; } Vector operator*(const Vector& a, double b) { Vector r=a; r*=b; return r; } Vector& Vector::operator/=(double f) { v[0]/=f; v[1]/=f; return *this; } Vector operator/(const Vector& a, double b) { Vector r=a; r/=b; return r; } double operator*(const Vector& a, const Vector& b) // 2D dot product { double r = 0; for (int i=0; i<2; i++) r += a.v[i]*b.v[i]; return r; } Vector Vector::normalize() // 2D normalize { Vector r = *this; double d = sqrt(v[0]*v[0]+v[1]*v[1]); if (d) { r[0] /= d; r[1] /= d; } else { r[0] = 0; r[1] = 0; } return r; } Vector Vector::abs() // absolute value { Vector r; r[0] = fabs(v[0]); r[1] = fabs(v[1]); r[2] = 1; return r; } double Vector::length() { return sqrt(v[0]*v[0] + v[1]*v[1]); } double Vector::angle() { return atan2(v[1],v[0]); } double Vector::avg() { return (v[0]+v[1])/2; } double Vector::max() { return v[0]>v[1]?v[0]:v[1]; } double Vector::min() { return v[0]<v[1]?v[0]:v[1]; } Vector Vector::round() { return Vector((int)(v[0]+.5), (int)(v[1]+.5)); } Vector Vector::floor() { return Vector(::floor(v[0]), ::floor(v[1])); } Vector Vector::ceil() { return Vector(::ceil(v[0]), ::ceil(v[1])); } Vector Vector::invert() { Vector r = *this; r[0]=1/r[0]; r[1]=1/r[1]; r[2]=1; return r; } Vector Vector::TkCanvasPs(Tk_Canvas canvas) { return Vector(v[0], Tk_CanvasPsY(canvas, v[1])); } Vector& Vector::operator*=(const Matrix& m) { Vector vv = *this; for (int i=0; i<3; i++) v[i] = vv.v[0]*m.m[0][i] + vv.v[1]*m.m[1][i] + vv.v[2]*m.m[2][i]; return *this; } Vector operator*(const Vector& v, const Matrix& m) { Vector r; for (int i=0; i<3; i++) r.v[i] = v.v[0]*m.m[0][i] + v.v[1]*m.m[1][i] + v.v[2]*m.m[2][i]; return r; } ostream& operator<<(ostream& s, const Vector& v) { s << ' ' << v.v[0] << ' ' << v.v[1] << ' '; return s; } istream& operator>>(istream& s, Vector& v) { s >> v.v[0] >> v.v[1]; return s; } Vector cross(Vector& a, Vector& b) { return Vector(a[1]*b[2]-b[1]*a[2], a[2]*b[0]-b[2]*a[0], a[0]*b[1]-b[0]*a[1]); } // the following are not valid for 2D graphics: Vector& Vector::div(double f) { v[0]/=f; v[1]/=f; v[2]/=f; return *this; } Vector& Vector::minus(const Vector& a) { v[0]-=a.v[0]; v[1]-=a.v[1]; v[2]-=a.v[2]; return *this; } Vector mult(const Vector& a, double f) { Vector r = a; r.v[0]*= f; r.v[1]*= f; r.v[2]*= f; return r; } Vector& Vector::operator*=(const Vector& b) { v[0]*=b.v[0]; v[1]*=b.v[1]; v[2]=1; return *this; } Vector& Vector::operator/=(const Vector& b) { v[0]/=b.v[0]; v[1]/=b.v[1]; v[2]=1; return *this; } // Vertex Vertex::Vertex() { next_ = NULL; previous_ = NULL; } Vertex::Vertex(double x, double y) { vector = Vector(x,y); next_ = NULL; previous_ = NULL; } Vertex::Vertex(const Vector& a) { vector = a; next_ = NULL; previous_ = NULL; } ostream& operator<<(ostream& s, const Vertex& v) { s << v.vector; return s; } // Matrix Matrix::Matrix() { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] = (i==j ? 1 : 0); } Matrix::Matrix(const Matrix& a) { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] = a.m[i][j]; } Matrix& Matrix::operator=(const Matrix& a) { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] = a.m[i][j]; return *this; } Matrix::Matrix(const Vector& v0, const Vector& v1, const Vector& v2) { int i; for (i=0; i<3; i++) m[0][i] = v0.v[i]; for (i=0; i<3; i++) m[1][i] = v1.v[i]; for (i=0; i<3; i++) m[2][i] = v2.v[i]; } Matrix::Matrix(double a, double b, double c, double d, double e, double f) { m[0][0]=a; m[0][1]=b; m[0][2]=0; m[1][0]=c; m[1][1]=d; m[1][2]=0; m[2][0]=e; m[2][1]=f; m[2][2]=1; } Matrix& Matrix::identity() { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] = (i==j ? 1 : 0); return *this; } int Matrix::isIdentity() { return ((m[0][0]==1) && (m[0][1]==0) && (m[0][2]==0) && (m[1][0]==0) && (m[1][1]==1) && (m[1][2]==0) && (m[2][0]==0) && (m[2][1]==0) && (m[2][2]==1)); } Matrix Matrix::abs() { Matrix r; r.m[0][0] = fabs(m[0][0]); r.m[1][1] = fabs(m[1][1]); return r; } Matrix& Matrix::operator*=(double a) { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] *= a; return *this; } Matrix& Matrix::operator/=(double a) { for (int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] /= a; return *this; } Matrix& Matrix::operator*=(const Matrix& a) { Matrix r; for (int i=0; i<3; i++) for (int j=0; j<3; j++) r.m[i][j] = m[i][0]*a.m[0][j] + m[i][1]*a.m[1][j] + m[i][2]*a.m[2][j]; return *this=r; } Matrix Matrix::invert() { // Method of Row Reduction-- Calculus and Analylic Geometry, A-13 Matrix r; // identy matrix Vector m0 = m[0]; Vector m1 = m[1]; Vector m2 = m[2]; Vector r0 = r[0]; Vector r1 = r[1]; Vector r2 = r[2]; // check for 0 in m[0], swap rows 0 and 1 if so. // this seems to be a problem only in the case of rotation of 90/270 degress if ((m0[0]==0) || (m0[0]>0 && m0[0]<DBL_EPSILON) || (m0[0]<0 && m0[0]>-DBL_EPSILON)) { Vector tm0 = m0; Vector tr0 = r0; m0 = m1; r0 = r1; m1 = tm0; r1 = tr0; } // scale first row by 1/m0[0] r0.div(m0[0]); m0.div(m0[0]); // zero out m1[0] and m2[0] r1.minus(mult(r0,m1[0])); m1.minus(mult(m0,m1[0])); r2.minus(mult(r0,m2[0])); m2.minus(mult(m0,m2[0])); // scale second row by 1/m1[1] r1.div(m1[1]); m1.div(m1[1]); // zero out m0[1] and m2[1] r0.minus(mult(r1,m0[1])); m0.minus(mult(m1,m0[1])); r2.minus(mult(r1,m2[1])); m2.minus(mult(m1,m2[1])); // scale third row by 1/m[2] r2.div(m2[2]); m2.div(m2[2]); // and zero out m0[2] and m1[2] r0.minus(mult(r2,m0[2])); m0.minus(mult(m2,m0[2])); r1.minus(mult(r2,m1[2])); m2.minus(mult(m2,m1[2])); return Matrix(r0,r1,r2); } Matrix Matrix::invert2() { Matrix cc = this->cofactor(); Matrix aa = cc.adjoint(); double det = m[0][0]*aa.m[0][0] + m[0][1]*aa.m[1][0] + m[0][2]*aa.m[2][0]; Matrix rr; for (int ii=0; ii<3; ii++ ) for (int jj=0; jj<3; jj++) rr.m[ii][jj] = aa.m[ii][jj]/det; return rr; } Matrix Matrix::cofactor() { Matrix rr; rr.m[0][0] = +(m[1][1]*m[2][2]-m[1][2]*m[2][1]); rr.m[0][1] = -(m[1][0]*m[2][2]-m[1][2]*m[2][0]); rr.m[0][2] = +(m[1][0]*m[2][1]-m[1][1]*m[2][0]); rr.m[1][0] = -(m[0][1]*m[2][2]-m[0][2]*m[2][1]); rr.m[1][1] = +(m[0][0]*m[2][2]-m[0][2]*m[2][0]); rr.m[1][2] = -(m[0][0]*m[2][1]-m[0][1]*m[2][0]); rr.m[2][0] = +(m[0][1]*m[1][2]-m[0][2]*m[1][1]); rr.m[2][1] = -(m[0][0]*m[1][2]-m[0][2]*m[1][0]); rr.m[2][2] = +(m[0][0]*m[1][1]-m[0][1]*m[1][0]); return rr; } Matrix Matrix::adjoint() { Matrix rr; for (int ii=0; ii<3; ii++) for (int jj=0; jj<3; jj++) rr.m[jj][ii] = m[ii][jj]; return rr; } Matrix operator*(const Matrix& a, double b) { Matrix r=a; return r*=b; } Matrix operator/(const Matrix& a, double b) { Matrix r=a; return r/=b; } Matrix operator*(const Matrix& a, const Matrix& b) { Matrix r=a; return r*=b; } Vector Matrix::operator[](int i) { return Vector(m[i]); } ostream& operator<<(ostream& s, const Matrix& m) { s << ' '; for (int i=0; i<3; i++) for (int j=0; j<2; j++) s << m.m[i][j] << ' '; return s; } istream& operator>>(istream& s, Matrix& m) { for (int i=0; i<3; i++ ) for (int j=0; j<2; j++) s >> m.m[i][j]; return s; } // Translate Translate::Translate(double x, double y) : Matrix() { m[2][0]=x; m[2][1]=y; } Translate::Translate(const Vector& v) : Matrix() { m[2][0]=v.v[0]; m[2][1]=v.v[1]; } Translate::Translate(const Matrix& a) : Matrix() { m[2][0] = a.m[2][0]; m[2][1] = a.m[2][1]; } Translate& Translate::operator=(const Matrix& a) { m[2][0] = a.m[2][0]; m[2][1] = a.m[2][1]; return *this; } ostream& operator<<(ostream& s, const Translate& m) { s << ' ' << m.m[2][0] << ' ' << m.m[2][1] << ' '; return s; } istream& operator>>(istream& s, Translate& m) { s >> m.m[2][0] >> m.m[2][1]; return s; } // Rotate Rotate::Rotate(double a) : Matrix() { // note: signs reverse for X-Windows (origin is upper left) m[0][0] = cos(a); m[0][1] = -sin(a); m[1][0] = sin(a); m[1][1] = cos(a); // this fixes a problem with numbers too small and tring to invert the matrix if ((m[0][0]>0 && m[0][0]<DBL_EPSILON) || (m[0][0]<0 && m[0][0]>-DBL_EPSILON)) m[0][0] = 0; if ((m[0][1]>0 && m[0][1]<DBL_EPSILON) || (m[0][1]<0 && m[0][1]>-DBL_EPSILON)) m[0][1] = 0; if ((m[1][0]>0 && m[1][0]<DBL_EPSILON) || (m[1][0]<0 && m[1][0]>-DBL_EPSILON)) m[1][0] = 0; if ((m[1][1]>0 && m[1][1]<DBL_EPSILON) || (m[1][1]<0 && m[1][1]>-DBL_EPSILON)) m[1][1] = 0; } Rotate::Rotate(double a, double b, double c, double d) : Matrix() { m[0][0] = a; m[0][1] = b; m[1][0] = c; m[1][1] = d; } Rotate::Rotate(const Matrix& a) : Matrix() { for (int i=0; i<2; i++) for (int j=0; j<2; j++) m[i][j] = a.m[i][j]; } Rotate& Rotate::operator=(const Matrix& a) { for (int i=0; i<2; i++) for (int j=0; j<2; j++) m[i][j] = a.m[i][j]; return *this; } ostream& operator<<(ostream& s, const Rotate& m) { s << ' ' << m.m[0][0] << ' ' << m.m[0][1] << ' ' << m.m[1][0] << ' ' << m.m[1][1] << ' '; return s; } istream& operator>>(istream& s, Rotate& m) { s >> m.m[0][0] >> m.m[0][1] >> m.m[1][0] >> m.m[1][1]; return s; } // Scale Scale::Scale(double a) : Matrix() { m[0][0]=a; m[1][1]=a; } Scale::Scale(double a, double b) : Matrix() { m[0][0]=a; m[1][1]=b; } Scale::Scale(const Vector& v) : Matrix() { m[0][0]=v.v[0]; m[1][1]=v.v[1]; } Scale::Scale(const Matrix& a) : Matrix() { m[0][0] = a.m[0][0]; m[1][1] = a.m[1][1]; } Scale& Scale::operator=(const Matrix& a) { m[0][0] = a.m[0][0]; m[1][1] = a.m[1][1]; return *this; } ostream& operator<<(ostream& s, const Scale& m) { s << ' ' << m.m[0][0] << ' ' << m.m[1][1] << ' '; return s; } istream& operator>>(istream& s, Scale& m) { s >> m.m[0][0] >> m.m[1][1]; return s; } // Flip FlipX::FlipX() : Matrix() { m[0][0] = -1; } FlipY::FlipY() : Matrix() { m[1][1] = -1; } FlipXY::FlipXY() : Matrix() { m[0][0] = -1; m[1][1] = -1; } // BBox BBox::BBox(double a, double b, double c, double d) { // we want a 'positive' box ll.v[0] = a < c ? a : c; ll.v[1] = b < d ? b : d; ur.v[0] = a < c ? c : a; ur.v[1] = b < d ? d : b; } BBox::BBox(double w, double h) { ll.v[0] = 0; ll.v[1] = 0; ur.v[0] = w; ur.v[1] = h; } BBox::BBox(const Vector& l, const Vector& h) { // we want a 'positive' box ll.v[0] = l.v[0] < h.v[0] ? l.v[0] : h.v[0]; ll.v[1] = l.v[1] < h.v[1] ? l.v[1] : h.v[1]; ur.v[0] = l.v[0] < h.v[0] ? h.v[0] : l.v[0]; ur.v[1] = l.v[1] < h.v[1] ? h.v[1] : l.v[1]; } BBox::BBox(const Vector& v) { ll = v; ur = v; } BBox& BBox::operator+=(const Vector& v) { ll+=v; ur+=v; return *this; } BBox operator+(const BBox& b, const Vector& v) { BBox r=b; r+=v; return r; } BBox& BBox::operator-=(const Vector& a) { ll-=a; ur-=a; return *this; } BBox operator-(const BBox& b, const Vector& v) { BBox r=b; r-=v; return r; } int BBox::isIn(const Vector& v) const { if (v.v[0] < ll.v[0] || v.v[1] < ll.v[1] || v.v[0] > ur.v[0] || v.v[1] > ur.v[1]) return 0; else return 1; } int BBox::isIn(const BBox& bb) const { // return 0 if outside, > 0 if intersection // = 4 if inside BBox b = bb; return isIn(b.ll) + isIn(b.ur) + isIn(b.ul()) + isIn(b.lr()); } int BBox::isEmpty() const { Vector v = ur-ll; return (v[0]==0 && v[1]==0); } Vector BBox::center() { return (ur-ll)/2 + ll; } Vector BBox::size() { return ur - ll; } BBox& BBox::operator*=(const Matrix& m) { ll *= m; ur *= m; return *this; } BBox operator*(const BBox& bb, const Matrix& m) { BBox r = bb; r*=m; return r; } BBox& BBox::expand(double a) { ll -= Vector(a,a); ur += Vector(a,a); return *this; } BBox& BBox::expand(const Vector& v) { ll -= v; ur += v; return *this; } BBox& BBox::shrink(double a) { ll += Vector(a,a); ur -= Vector(a,a); return *this; } BBox& BBox::shrink(const Vector& v) { ll += v; ur -= v; return *this; } BBox& BBox::bound(const Vector& v) { if (v.v[0] < ll[0]) ll[0] = v.v[0]; if (v.v[1] < ll[1]) ll[1] = v.v[1]; if (v.v[0] > ur[0]) ur[0] = v.v[0]; if (v.v[1] > ur[1]) ur[1] = v.v[1]; return *this; } BBox& BBox::bound(BBox b) { this->bound(b.ll); this->bound(b.lr()); this->bound(b.ur); this->bound(b.ul()); return *this; } BBox intersect(const BBox& a, const BBox& b) { // test for obvious int ab = a.isIn(b); int ba = b.isIn(a); // we are missing a case here! two bbox's that cross if (ab==0 && ba == 0) // outside each other return BBox(); if (ab == 4) // b is inside a return b; if (ba == 4) // a is inside b return a; // else, there seems to be some overlap BBox r; r.ll.v[0] = (a.ll.v[0] > b.ll.v[0]) ? a.ll.v[0] : b.ll.v[0]; r.ll.v[1] = (a.ll.v[1] > b.ll.v[1]) ? a.ll.v[1] : b.ll.v[1]; r.ur.v[0] = (a.ur.v[0] < b.ur.v[0]) ? a.ur.v[0] : b.ur.v[0]; r.ur.v[1] = (a.ur.v[1] < b.ur.v[1]) ? a.ur.v[1] : b.ur.v[1]; return r; } ostream& operator<<(ostream& s, const BBox& b) { s << b.ll << b.ur; return s; } �������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/vector/vector3d.h��������������������������������������������������������������������0000644�0001750�0001750�00000027230�11722720323�015433� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __vector3d_h__ #define __vector3d_h__ #include <math.h> #include <float.h> #include <iostream> using namespace std; #include "tk.h" class Vector; class Matrix; class Matrix3d; class Vector3d { public: double v[4]; public: Vector3d() {v[0]=0;v[1]=0;v[2]=0;v[3]=1;} Vector3d(double* f) {v[0]=f[0]; v[1]=f[1]; v[2]=f[2]; v[3]=1;} Vector3d(double x, double y) {v[0]=x;v[1]=y;v[2]=0;v[3]=1;} Vector3d(double x, double y, double z) {v[0]=x;v[1]=y;v[2]=z;v[3]=1;} Vector3d(const Vector&); Vector3d(const Vector&, double); Vector3d& operator=(const Vector&); Vector3d(const Vector3d& a) {v[0]=a.v[0];v[1]=a.v[1];v[2]=a.v[2];v[3]=a.v[3];} Vector3d& operator=(const Vector3d& a) {v[0]=a.v[0];v[1]=a.v[1];v[2]=a.v[2];v[3]=a.v[3]; return *this;} double& operator[](int i) {return v[i];} // return element double* vv() {return v;} // return vector Vector3d& operator+=(const Vector3d& a) // addition {v[0]+=a.v[0]; v[1]+=a.v[1]; v[2]+=a.v[2]; return *this;} Vector3d& operator-=(const Vector3d& a) // subtraction {v[0]-=a.v[0]; v[1]-=a.v[1]; v[2]-=a.v[2]; return *this;} Vector3d& operator*=(double f) // scalar multiply {v[0]*=f; v[1]*=f; v[2]*=f; return *this;} Vector3d& operator/=(double f) // scalar division {v[0]/=f; v[1]/=f; v[2]/=f; return *this;} Vector3d& operator*=(const Matrix3d&); // vector multiply Vector3d abs() {return Vector3d(fabs(v[0]),fabs(v[1]),fabs(v[2]));} double angleX() {return atan2(v[2],v[1]);} double angleY() {return atan2(v[0],v[2]);} double angleZ() {return atan2(v[1],v[0]);} Vector3d ceil() {return Vector3d(::ceil(v[0]),::ceil(v[1]),::ceil(v[2]));} Vector3d floor() {return Vector3d(::floor(v[0]),::floor(v[1]),::floor(v[2]));} Vector3d invert() {return Vector3d(1/v[0],1/v[1],1/v[2]);} double length() {return sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);} Vector3d round() {return Vector3d((int)(v[0]+.5),(int)(v[1]+.5),(int)(v[2]+.5));} Vector3d normalize() {double d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); return d ? Vector3d(v[0]/d,v[1]/d,v[2]/d) : Vector3d();} Vector3d project() {return (v[3]!=1) ? Vector3d(v[0]/v[3],v[1]/v[3],v[2]/v[3]) : *this;} Vector TkCanvasPs(Tk_Canvas canvas); }; ostream& operator<<(ostream&, const Vector3d&); istream& operator>>(istream&, Vector3d&); inline Vector3d operator-(const Vector3d& a) {return Vector3d(-a.v[0],-a.v[1],-a.v[2]);} inline Vector3d operator+(const Vector3d& a, const Vector3d& b) {return Vector3d(a) +=b;} inline Vector3d operator-(const Vector3d& a, const Vector3d& b) {return Vector3d(a) -=b;} inline Vector3d operator*(const Vector3d& a, double b) {return Vector3d(a) *=b;} inline Vector3d operator/(const Vector3d& a, double b) {return Vector3d(a) /=b;} inline Vector3d operator*(const Vector3d& v, const Matrix3d& m) {return Vector3d(v) *=m;} inline double operator*(const Vector3d& a, const Vector3d& b) // dot product {double r=0; r+=a.v[0]*b.v[0]; r+=a.v[1]*b.v[1]; r+=a.v[2]*b.v[2]; return r;} inline Vector3d cross(Vector3d& a, Vector3d& b) // cross product {return Vector3d(a[1]*b[2]-b[1]*a[2],a[2]*b[0]-b[2]*a[0],a[0]*b[1]-b[0]*a[1]);} class Vertex3d { public: Vector3d vector; private: Vertex3d* next_; Vertex3d* previous_; public: Vertex3d() {next_=NULL; previous_=NULL;} Vertex3d(double x, double y, double z) {vector=Vector3d(x,y,z); next_=NULL; previous_=NULL;} Vertex3d(const Vector3d& a) {vector=a; next_=NULL; previous_=NULL;} Vertex3d(const Vertex3d& a) {vector=a.vector; next_=a.next_; previous_=a.previous_;} Vertex3d& operator=(const Vertex3d& a) {vector=a.vector; next_=a.next_; previous_=a.previous_; return *this;} Vertex3d* next() {return next_;} Vertex3d* previous() {return previous_;} void setNext(Vertex3d* v) {next_ = v;} void setPrevious(Vertex3d* v) {previous_ = v;} }; ostream& operator<<(ostream&, const Vertex3d&); class Matrix3d { public: double m[4][4]; public: Matrix3d() { m[0][0]=1; m[0][1]=0; m[0][2]=0; m[0][3]=0; m[1][0]=0; m[1][1]=1; m[1][2]=0; m[1][3]=0; m[2][0]=0; m[2][1]=0; m[2][2]=1; m[2][3]=0; m[3][0]=0; m[3][1]=0; m[3][2]=0; m[3][3]=1; } Matrix3d(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l) { m[0][0]=a; m[0][1]=b; m[0][2]=c; m[0][3]=0; m[1][0]=d; m[1][1]=e; m[1][2]=f; m[1][3]=0; m[2][0]=g; m[2][1]=h; m[2][2]=i; m[2][3]=0; m[3][0]=j; m[3][1]=k; m[3][2]=l; m[3][3]=1; } Matrix3d(Vector3d& x, Vector3d& y, Vector3d& z) { m[0][0]=x[0]; m[0][1]=y[0]; m[0][2]=z[0]; m[0][3]=0; m[1][0]=x[1]; m[1][1]=y[1]; m[1][2]=z[1]; m[1][3]=0; m[2][0]=x[2]; m[2][1]=y[2]; m[2][2]=z[2]; m[2][3]=0; m[3][0]=0; m[3][1]=0; m[3][2]=0; m[3][3]=1; } Matrix3d(const Matrix3d& a) { m[0][0]=a.m[0][0];m[0][1]=a.m[0][1];m[0][2]=a.m[0][2];m[0][3]=a.m[0][3]; m[1][0]=a.m[1][0];m[1][1]=a.m[1][1];m[1][2]=a.m[1][2];m[1][3]=a.m[1][3]; m[2][0]=a.m[2][0];m[2][1]=a.m[2][1];m[2][2]=a.m[2][2];m[2][3]=a.m[2][3]; m[3][0]=a.m[3][0];m[3][1]=a.m[3][1];m[3][2]=a.m[3][2];m[3][3]=a.m[3][3]; } Matrix3d& operator=(const Matrix3d& a) { m[0][0]=a.m[0][0];m[0][1]=a.m[0][1];m[0][2]=a.m[0][2];m[0][3]=a.m[0][3]; m[1][0]=a.m[1][0];m[1][1]=a.m[1][1];m[1][2]=a.m[1][2];m[1][3]=a.m[1][3]; m[2][0]=a.m[2][0];m[2][1]=a.m[2][1];m[2][2]=a.m[2][2];m[2][3]=a.m[2][3]; m[3][0]=a.m[3][0];m[3][1]=a.m[3][1];m[3][2]=a.m[3][2];m[3][3]=a.m[3][3]; return *this;} Matrix3d(const Matrix& a); double matrix(int i, int j) {return m[i][j];} // return element Vector3d operator[](int i) {return Vector3d(m[i]);} // return row double* mm() {return (double*)m;} // return matrix Matrix3d& identity() { m[0][0]=1; m[0][1]=0; m[0][2]=0; m[0][3]=0; m[1][0]=0; m[1][1]=1; m[1][2]=0; m[1][3]=0; m[2][0]=0; m[2][1]=0; m[2][2]=1; m[2][3]=0; m[3][0]=0; m[3][1]=0; m[3][2]=0; m[3][3]=1; return *this;} Matrix3d& operator*=(const Matrix3d&); // matrix multiply Matrix3d invert(); Matrix3d cofactor(); Matrix3d adjoint(); double det(); double det2d(double& a, double& b, double& c, double& d, double& e, double& f, double& g, double& h, double& i) {return a*(e*i-f*h) - b*(d*i-f*g) + c*(d*h-e*g);} void dump(); }; ostream& operator<<(ostream&, const Matrix3d&); istream& operator>>(istream&, Matrix3d&); inline Matrix3d operator*(const Matrix3d& a, const Matrix3d& b) {return Matrix3d(a) *= b;} inline Vector3d& Vector3d::operator*=(const Matrix3d& m) { double vv[4]; double* mm = (double*)(m.m); vv[0] = v[0]*mm[0] + v[1]*mm[4] + v[2]*mm[8] + v[3]*mm[12]; vv[1] = v[0]*mm[1] + v[1]*mm[5] + v[2]*mm[9] + v[3]*mm[13]; vv[2] = v[0]*mm[2] + v[1]*mm[6] + v[2]*mm[10] + v[3]*mm[14]; vv[3] = v[0]*mm[3] + v[1]*mm[7] + v[2]*mm[11] + v[3]*mm[15]; v[0] = vv[0]; v[1] = vv[1]; v[2] = vv[2]; v[3] = vv[3]; return *this; } class Translate3d : public Matrix3d { public: Translate3d() {}; Translate3d(double x, double y, double z) {m[3][0]=x; m[3][1]=y; m[3][2]=z;} Translate3d(const Vector3d& v) {m[3][0]=v.v[0]; m[3][1]=v.v[1]; m[3][2]=v.v[2];} Translate3d(const Vector& v); Translate3d(const Vector& v, double z); Translate3d(const Matrix3d& a) {m[3][0] = a.m[3][0]; m[3][1] = a.m[3][1]; m[3][2] = a.m[3][2];} }; ostream& operator<<(ostream&, const Translate3d&); istream& operator>>(istream&, Translate3d&); class Scale3d : public Matrix3d { public: Scale3d() {}; Scale3d(double a) {m[0][0]=a; m[1][1]=a; m[2][2]=a;} Scale3d(double a, double b) {m[0][0]=a; m[1][1]=a; m[2][2]=b;} Scale3d(double a, double b, double c) {m[0][0]=a; m[1][1]=b; m[2][2]=c;} Scale3d(const Vector& v); Scale3d(const Vector& v, double c); Scale3d(const Vector3d& v) {m[0][0]=v.v[0]; m[1][1]=v.v[1]; m[2][2]=v.v[2];} Scale3d(const Matrix3d& a) {m[0][0] = a.m[0][0]; m[1][1] = a.m[1][1]; m[2][2] = a.m[2][2];} }; ostream& operator<<(ostream&, const Scale3d&); istream& operator>>(istream&, Scale3d&); class FlipX3d : public Matrix3d { public: FlipX3d() {m[0][0] = -1;} }; class FlipY3d : public Matrix3d { public: FlipY3d() {m[1][1] = -1;} }; class FlipZ3d : public Matrix3d { public: FlipZ3d() {m[2][2] = -1;} }; class FlipXY3d : public Matrix3d { public: FlipXY3d() {m[0][0] = -1; m[1][1] = -1;} }; class FlipXYZ3d : public Matrix3d { public: FlipXYZ3d() {m[0][0] = -1; m[1][1] = -1; m[2][2] = -1;} }; class RotateX3d : public Matrix3d { public: RotateX3d() {}; RotateX3d(double); RotateX3d(double a, double b, double c, double d) {m[1][1] = a; m[1][2] = b; m[2][1] = c; m[2][2] = d;} }; ostream& operator<<(ostream&, const RotateX3d&); istream& operator>>(istream&, RotateX3d&); class RotateY3d : public Matrix3d { public: RotateY3d() {}; RotateY3d(double); RotateY3d(double a, double b, double c, double d) {m[0][0] = a; m[0][2] = b; m[2][0] = c; m[2][2] = d;} }; ostream& operator<<(ostream&, const RotateY3d&); istream& operator>>(istream&, RotateY3d&); class RotateZ3d : public Matrix3d { public: RotateZ3d() {}; RotateZ3d(double); RotateZ3d(double a, double b, double c, double d) {m[0][0] = a; m[0][1] = b; m[1][0] = c; m[1][1] = d;} }; ostream& operator<<(ostream&, const RotateZ3d&); istream& operator>>(istream&, RotateZ3d&); class Shear3d : public Matrix3d { public: Shear3d(double x, double y, double dist) {m[2][0] = -x/dist; m[2][1] = -y/dist;} }; class Perspective3d : public Matrix3d { public: Perspective3d(double front, double back, double dist) { m[2][2] = back/(back-front); m[2][3] = 1; m[3][2] = -front*back/(dist*(back-front)); m[3][3] = 0;} }; class BBox3d { public: Vector3d ll; Vector3d ur; public: BBox3d() {} BBox3d(double w, double h, double d) {ll.v[0]=0; ll.v[1]=0; ll.v[2]=0; ur.v[0]=w; ur.v[1]=h; ur.v[2]=d;} BBox3d(const Vector3d& v) {ll=v; ur=v;} BBox3d(double, double, double, double, double, double); BBox3d(const Vector3d&, const Vector3d&); BBox3d(const BBox3d& a) {ll=a.ll; ur=a.ur;} BBox3d& operator=(const BBox3d& a) {ll=a.ll; ur=a.ur; return *this;} BBox3d& operator+=(const Vector3d& v) // addition {ll+=v; ur+=v; return *this;} BBox3d& operator-=(const Vector3d& a) // subtraction {ll-=a; ur-=a; return *this;} BBox3d& operator*=(const Matrix3d& m) // multiplication {ll*=m; ur*=m; return *this;} Vector3d center() {return (ur-ll)/2 + ll;} Vector3d size() {return ur - ll;} int isEmpty() const {Vector3d v = ur-ll; return (v[0]==0 && v[1]==0 && v[2]==0);} int isIn(const Vector3d&) const; BBox3d& expand(double a) {ll-=Vector3d(a,a,a); ur+=Vector3d(a,a,a); return *this;} BBox3d& expand(const Vector3d& v) {ll-=v; ur+=v; return *this;} BBox3d& shrink(double a) {ll+=Vector3d(a,a,a); ur-=Vector3d(a,a,a); return *this;} BBox3d& shrink(const Vector3d& v) {ll+=v; ur-=v; return *this;} BBox3d& bound(const Vector3d&); BBox3d& clip(const Vector3d&); }; ostream& operator<<(ostream&, const BBox3d&); inline BBox3d operator+(const BBox3d& b, const Vector3d& v) {return BBox3d(b) += v;} inline BBox3d operator-(const BBox3d& b, const Vector3d& v) {return BBox3d(b) -= v;} inline BBox3d operator*(const BBox3d& b, const Matrix3d& m) {return BBox3d(b) *= m;} // WorldToView Matrix3d WorldToView3d(const Vector3d& cop, const Vector3d& vpn, const Vector3d& vup); Matrix3d WorldToView3d(const Vector3d& cop, double head, double pitch, double bank); Matrix3d WorldToView3d(const Vector3d& cop, const Vector3d& vpn, double bank); #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014014� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/Makefile��������������������������������������������������������������������0000644�0001750�0001750�00000002603�11752025335�015473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) \ -I. -I.. -I../widget -I../vector -I../list -I../util \ -I../../include -I$(X11INCLUDE) SS = \ cbgrid.C \ colorbarbase.C \ colorbar.C \ colortag.C \ colorbartrue.C \ colorbartruecolor.C \ colorbartruecolor8.C \ colorbartruecolor16.C \ colorbartruecolor24.C \ colorbarrgb.C \ colorbarrgbtruecolor.C \ colorbarrgbtruecolor8.C \ colorbarrgbtruecolor16.C \ colorbarrgbtruecolor24.C \ colormap.C \ lut.C \ sao.C \ default.C ifeq ($(OS),unix) SSP = \ colorbarpseudo.C \ colorbarpseudocolor.C \ colorbarpseudocolor8.C endif SRC = $(SS) $(SSP) \ parser.C \ lex.C \ lutparser.C \ lutlex.C \ saoparser.C \ saolex.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o parser.output lutparser.output saoparser.output ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif parsers : parser lutparser saoparser parser : FORCE bison -d -p cb -o parser.C parser.Y flex -Pcb -olex.C lex.L lutparser: FORCE bison -d -p rgb -o lutparser.C lutparser.Y flex -Prgb -olutlex.C lutlex.L saoparser: FORCE bison -d -p li -o saoparser.C saoparser.Y flex -Pli -osaolex.C saolex.L FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif �����������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudo.h������������������������������������������������������������0000644�0001750�0001750�00000000572�11700666264�017237� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarpseudo_h__ #define __colorbarpseudo_h__ #include "colorbarbase.h" class ColorbarPseudo : public virtual ColorbarBase { public: ColorbarPseudo(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ��������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudo.C������������������������������������������������������������0000644�0001750�0001750�00000000460�11700666264�017166� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarpseudo.h" ColorbarPseudo::ColorbarPseudo(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item) { } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colortag.C������������������������������������������������������������������0000644�0001750�0001750�00000002523�11752046251�015752� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colortag.h" #include "colorbar.h" #include "util.h" static int colorTagSeqID = 1; ColorTag::ColorTag(Colorbar* p, int b, int e, const char* clr) : parent_(p), start_(b), stop_(e) { id_ = colorTagSeqID++; colorname_ = dupstr(clr); color_ = parent_->getXColor(colorname_); next_ =NULL; previous_ =NULL; } ColorTag::~ColorTag() { if (colorname_) delete [] colorname_; } void ColorTag::move(int xx, int yy) { int aa = start_+xx; int bb = stop_+yy; if (aa>=bb-20) bb = aa+20; if (bb>parent_->colorCount) { bb = parent_->colorCount; aa = parent_->colorCount - (stop_-start_); } if (aa<0) { aa = 0; bb = stop_-start_; } start_ =aa; stop_ =bb; } void ColorTag::set(int start, int stop, const char* color) { start_ = start; stop_ = stop; if (colorname_) delete [] colorname_; colorname_ = dupstr(color); color_ = parent_->getXColor(colorname_); } void ColorTag::width(int size) { int aa = start_-size/2; int bb = stop_+size/2; if (bb>parent_->colorCount) { bb = parent_->colorCount; aa = parent_->colorCount - size; } if (aa<0) { aa = 0; bb = size; } start_ =aa; stop_ =bb; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lex.L�����������������������������������������������������������������������0000644�0001750�0001750�00000005201�11752046251�014735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* cblval; %} D [0-9] E [Ee][+-]?{D}+ /* rules */ %% adjust {return ADJUST_;} begin {return BEGIN_;} bias {return BIAS_;} bw {return BW_;} channel {return CHANNEL_;} cmyk {return CMYK_;} colormap {return COLORMAP_;} colorbar {return COLORBAR_;} colorspace {return COLORSPACE_;} contrast {return CONTRAST_;} debug {return DEBUG_;} delete {return DELETE_;} edit {return EDIT_;} end {return END_;} get {return GET_;} gray {return GRAY_;} false {return FALSE_;} file {return FILE_;} height {return HEIGHT_;} hide {return HIDE_;} id {return ID_;} invert {return INVERT_;} itt {return ITT_;} level {return LEVEL_;} list {return LIST_;} load {return LOAD_;} macosx {return MACOSX_;} map {return MAP_;} motion {return MOTION_;} n {return N_;} name {return NAME_;} no {return NO_;} off {return OFF_;} on {return ON_;} postscript {return POSTSCRIPT_;} print {return PRINT_;} reset {return RESET_;} resolution {return RESOLUTION_;} rgb {return RGB_;} save {return SAVE_;} show {return SHOW_;} tag {return TAG_;} true {return TRUE_;} value {return VALUE_;} var {return VAR_;} version {return VERSION_;} width {return WIDTH_;} win32 {return WIN32_;} window {return WINDOW_;} y {return Y_;} yes {return YES_;} [+-]?{D}+ { // Integer cblval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number cblval->real = atof(yytext); return REAL; } 0[xX][0-9a-fA-F]+ { // Pointer cblval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } \"[^\"\n]*\" | \'[^\'\n]*\' { // Quoted String int ll = (yyleng-2)<(CBBUFSIZE-1) ? (yyleng-2):(CBBUFSIZE-1); strncpy(cblval->str,yytext+1,ll); // skip the " " cblval->str[ll] = '\0'; // Remove the '"' return STRING; } \{[^\}\n]*\} { // Quoted String int ll = (yyleng-2)<(CBBUFSIZE-1) ? (yyleng-2):(CBBUFSIZE-1); strncpy(cblval->str,yytext+1,ll); // skip the '{' cblval->str[ll] = '\0'; // Remove the '}' return STRING; } [!-~][!-~]+ { // General String-- at least 2 printable chars int ll = yyleng <(CBBUFSIZE-1) ? yyleng:(CBBUFSIZE-1); strncpy(cblval->str,yytext,ll); cblval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } . { // Else, return the char return yytext[0]; } %% �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor.C������������������������������������������������������0000644�0001750�0001750�00000002517�11700666264�020405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "colorbarrgbtruecolor.h" #include "util.h" ColorbarRGBTrueColor::ColorbarRGBTrueColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarRGB(i,c,item), ColorbarTrue(i,c,item) { colorCount = 0; } int ColorbarRGBTrueColor::initColormap() { colorCount = (((ColorbarBaseOptions*)options)->colors); colorCells = new unsigned char[colorCount*3]; // needed to initialize colorCells reset(); return TCL_OK; } void ColorbarRGBTrueColor::updateColorCells() { // fill rgb table // note: its filled bgr to match XImage // for(int i=0; i<colorCount; i++) { for(int i=0, j=colorCount-1; i<colorCount; i++, j--) { int idr = invert ? calcContrastBias(j,bias[0],contrast[0]) : calcContrastBias(i,bias[0],contrast[0]); int idg = invert ? calcContrastBias(j,bias[1],contrast[1]) : calcContrastBias(i,bias[1],contrast[1]); int idb = invert ? calcContrastBias(j,bias[2],contrast[2]) : calcContrastBias(i,bias[2],contrast[2]); colorCells[i*3] = (int)(256.*idr/colorCount); colorCells[i*3+1] = (int)(256.*idg/colorCount); colorCells[i*3+2] = (int)(256.*idb/colorCount); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgb.h���������������������������������������������������������������0000644�0001750�0001750�00000002271�11700666264�016510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarrgb_h__ #define __colorbarrgb_h__ #include "colorbarbase.h" class Filter; class ColorbarRGB : public virtual ColorbarBase { protected: int channel; float bias[3]; float contrast[3]; private: void psHorz(Filter&, int, int); void psVert(Filter&, int, int); protected: void reset(); int calcContrastBias(int, float, float); #ifdef _MACOSX void macosx(float, int, int, const Vector&, const Vector&); #endif #ifdef _WIN32 void win32(float, int, int, const Vector&, const Vector&); #endif public: ColorbarRGB(Tcl_Interp*, Tk_Canvas, Tk_Item*); // SubCommandFunctions void adjustCmd(float, float); void getBiasCmd(); void getColorbarCmd(); void getColormapCmd(); void getColormapNameCmd(int); void getColormapFileNameCmd(int); void getContrastCmd(); void getCurrentFileNameCmd(); void getCurrentIDCmd(); void getCurrentNameCmd(); void setColorbarCmd(float, float, float, float, float, float, int); void getRGBChannelCmd(); void setRGBChannelCmd(const char*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/sao.C�����������������������������������������������������������������������0000644�0001750�0001750�00000010772�12042560016�014720� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "sao.h" #include "colorbar.h" SAOColorMap* cm; // SAO Parser Stuf #undef yyFlexLexer #define yyFlexLexer liFlexLexer #include <FlexLexer.h> void* lilval; liFlexLexer* lilexx; extern int liparse(SAOColorMap*, liFlexLexer*); int lilex(void* vval, liFlexLexer* ll) { lilval = vval; lilexx = ll; return ll ? ll->yylex() : 0; } void lierror(SAOColorMap* cm, liFlexLexer* ll, const char* m) {} // LIColor ostream& operator<<(ostream& s, LIColor& c) { s << "(" << c.x << "," << c.y << ")"; return s; } // SAOColorMap SAOColorMap::SAOColorMap(Colorbar* p) : ColorMapInfo(p) { current =&red; } void SAOColorMap::newLIColor(float aa, float bb) { current->append(new LIColor(aa,bb)); } void SAOColorMap::setChannel(ChannelType which) { switch (which) { case RED: current = &red; break; case GREEN: current = &green; break; case BLUE: current = &blue; break; } } int SAOColorMap::load() { ifstream str(fileName); if (!str) return 0; liFlexLexer* ll = new liFlexLexer(&str); liparse(this, ll); delete ll; if (red.isEmpty() || green.isEmpty() || blue.isEmpty()) return 0; // something is missing, bailout else return 1; // we found at least one LIColor for each RGB } int SAOColorMap::load(const char* var) { const char* ccmd = Tcl_GetVar(parent_->getInterp(), var, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (!ccmd) return 0; // only make command string as long as needed // or the rest will be processed as garbage int len = strlen(ccmd)+2; char* buf = new char[len]; memcpy(buf, ccmd, len); // add terminator to make parser happy buf[len-2] = '\n'; buf[len-1] = NULL; string x(buf); istringstream istr(x); liFlexLexer* ll = new liFlexLexer(&istr); liparse(this, ll); delete ll; delete [] buf; if (red.isEmpty() || green.isEmpty() || blue.isEmpty()) return 0; // something is missing, bailout else return 1; // we found at least one LIColor for each RGB } void SAOColorMap::save(const char* fn) { ofstream f(fn); if (!f) return; f << *this; } unsigned char SAOColorMap::getColorChar(int i, int count, List<LIColor>* cc) { float x = (float)i/count; LIColor* head = cc->head(); LIColor* tail = NULL; while (head && (head->getX() < x)) if (head) { tail = head; head = head->next(); } if (tail && head) { // interpolate between head and tail float m = (head->getY() - tail->getY()) / (head->getX() - tail->getX()); if (m) { float y = m * (x - tail->getX()) + tail->getY(); //point slope form return (unsigned char)(y * UCHAR_MAX); } else return (unsigned char)(head->getY() * UCHAR_MAX); } else if (!tail && head) // return first LIColor return (unsigned char)(head->getY() * UCHAR_MAX); else if (tail && !head) // return last LIColor return (unsigned char)(tail->getY() * UCHAR_MAX); else return 0; // there is something very wrong-- bail out } unsigned short SAOColorMap::getColorShrt(int i, int count, List<LIColor>* cc) { float x = (float)i/count; LIColor* head = cc->head(); LIColor* tail = NULL; while (head && (head->getX() < x)) if (head) { tail = head; head = head->next(); } if (tail && head) { // interpolate between head and tail float m = (head->getY() - tail->getY()) / (head->getX() - tail->getX()); if (m) { float y = m * (x - tail->getX()) + tail->getY(); //point slope form return (unsigned short)(y * USHRT_MAX); } else return (unsigned short)(head->getY() * USHRT_MAX); } else if (!tail && head) // return first LIColor return (unsigned short)(head->getY() * USHRT_MAX); else if (tail && !head) // return last LIColor return (unsigned short)(tail->getY() * USHRT_MAX); else return 0; // there is something very wrong-- bail out } ostream& operator<<(ostream& str, SAOColorMap& c) { str << "# SAOimage color table" << endl; str << "PSEUDOCOLOR" << endl; str << "RED:" << endl; c.red.head(); do str << *c.red.current(); while (c.red.next()); str << endl; str << "GREEN:" << endl; c.green.head(); do str << *c.green.current(); while (c.green.next()); str << endl; str << "BLUE:" << endl; c.blue.head(); do str << *c.blue.current(); while (c.blue.next()); str << endl; return str; } ������./saods9/saotk/colorbar/colorbartruecolor8.h��������������������������������������������������������0000644�0001750�0001750�00000000760�11700666264�020045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbartruecolor8_h__ #define __colorbartruecolor8_h__ #include "colorbartruecolor.h" #include "truecolor8.h" class ColorbarTrueColor8 : public ColorbarTrueColor, TrueColor8 { private: void updateColorsHorz(); void updateColorsVert(); public: ColorbarTrueColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ����������������./saods9/saotk/colorbar/saoparser.Y�����������������������������������������������������������������0000644�0001750�0001750�00000003067�12064133240�016161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {SAOColorMap* cm} %lex-param {liFlexLexer* ll} %parse-param {liFlexLexer* ll} %{ #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; liDiscard(x);} #include <string.h> #include <iostream> #include "sao.h" #undef yyFlexLexer #define yyFlexLexer liFlexLexer #include <FlexLexer.h> extern int lilex(void*, liFlexLexer*); extern void lierror(SAOColorMap*, liFlexLexer*, const char*); extern void liDiscard(int); %} %union { #define SAOBUFSIZE 4096 char str[SAOBUFSIZE]; int integer; float real; } %type <real> numeric %token <real> REAL %token <integer> INT %token <str> STRING %token EOF_ %token BLUE_ %token DEBUG_ %token GAMMA_ %token GREEN_ %token FALSE_ %token NO_ %token OFF_ %token ON_ %token PSEUDOCOLOR_ %token RED_ %token TRUE_ %token YES_ %% commands: commands command terminator | command terminator ; command : DEBUG_ debug | color | PSEUDOCOLOR_ | '#' {DISCARD_(1)} STRING | lis ; color : RED_ ':' gamma {cm->setChannel(SAOColorMap::RED);} | GREEN_ ':' gamma {cm->setChannel(SAOColorMap::GREEN);} | BLUE_ ':' gamma {cm->setChannel(SAOColorMap::BLUE);} ; gamma : /* empty */ | GAMMA_ numeric ; lis : lis li | li ; li : '(' numeric ',' numeric ')' {cm->newLIColor($2,$4);} ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; %% �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor16.h�������������������������������������������������������0000644�0001750�0001750�00000000766�11700666264�020132� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbartruecolor16_h__ #define __colorbartruecolor16_h__ #include "colorbartruecolor.h" #include "truecolor16.h" class ColorbarTrueColor16 : public ColorbarTrueColor, TrueColor16 { private: void updateColorsHorz(); void updateColorsVert(); public: ColorbarTrueColor16(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ����������./saods9/saotk/colorbar/lutparser.C�����������������������������������������������������������������0000644�0001750�0001750�00000124570�12042570564�016172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse rgbparse #define yylex rgblex #define yyerror rgberror #define yylval rgblval #define yychar rgbchar #define yydebug rgbdebug #define yynerrs rgbnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, EOF_ = 261, DEBUG_ = 262, FALSE_ = 263, NO_ = 264, OFF_ = 265, ON_ = 266, TRUE_ = 267, YES_ = 268 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define EOF_ 261 #define DEBUG_ 262 #define FALSE_ 263 #define NO_ 264 #define OFF_ 265 #define ON_ 266 #define TRUE_ 267 #define YES_ 268 /* Copy the first part of user declarations. */ #line 10 "lutparser.Y" #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; rgbDiscard(x);} #include <string.h> #include <iostream> #include "lut.h" #undef yyFlexLexer #define yyFlexLexer rgbFlexLexer #include <FlexLexer.h> extern int rgblex(void*, rgbFlexLexer*); extern void rgberror(LUTColorMap*, rgbFlexLexer*, const char*); extern void rgbDiscard(int); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "lutparser.Y" { #define LUTBUFSIZE 4096 char str[LUTBUFSIZE]; int integer; float real; } /* Line 193 of yacc.c. */ #line 156 "lutparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 169 "lutparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 12 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 20 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 17 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 7 /* YYNRULES -- Number of rules. */ #define YYNRULES 14 /* YYNRULES -- Number of states. */ #define YYNSTATES 22 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 268 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 7, 10, 13, 17, 18, 22, 24, 26, 28, 30, 32, 34 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 18, 0, -1, 18, 19, 21, -1, 19, 21, -1, 7, 23, -1, 22, 22, 22, -1, -1, 14, 20, 5, -1, 15, -1, 16, -1, 6, -1, 3, -1, 4, -1, 11, -1, 10, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 54, 54, 55, 58, 59, 60, 60, 63, 64, 65, 68, 69, 72, 73 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "REAL", "INT", "STRING", "EOF_", "DEBUG_", "FALSE_", "NO_", "OFF_", "ON_", "TRUE_", "YES_", "'#'", "'\\n'", "';'", "$accept", "commands", "command", "@1", "terminator", "numeric", "debug", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 35, 10, 59 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 17, 18, 18, 19, 19, 20, 19, 21, 21, 21, 22, 22, 23, 23 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 2, 2, 3, 0, 3, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 11, 12, 0, 6, 0, 0, 0, 14, 13, 4, 0, 1, 0, 10, 8, 9, 3, 0, 7, 2, 5 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 5, 6, 11, 17, 7, 10 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -6 static const yytype_int8 yypact[] = { -2, -6, -6, 5, -6, 0, 3, 7, -6, -6, -6, 8, -6, 3, -6, -6, -6, -6, 7, -6, -6, -6 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -6, -6, 15, -6, -5, -1, -6 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 12, 1, 2, 1, 2, 3, 18, 3, 20, 14, 1, 2, 4, 19, 4, 8, 9, 21, 15, 16, 13 }; static const yytype_uint8 yycheck[] = { 0, 3, 4, 3, 4, 7, 7, 7, 13, 6, 3, 4, 14, 5, 14, 10, 11, 18, 15, 16, 5 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 3, 4, 7, 14, 18, 19, 22, 10, 11, 23, 20, 0, 19, 6, 15, 16, 21, 22, 5, 21, 22 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (cm, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, cm, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, LUTColorMap* cm, rgbFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, cm, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; LUTColorMap* cm; rgbFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (cm); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, LUTColorMap* cm, rgbFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, cm, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; LUTColorMap* cm; rgbFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, cm, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, LUTColorMap* cm, rgbFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, cm, ll) YYSTYPE *yyvsp; int yyrule; LUTColorMap* cm; rgbFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , cm, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, cm, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, LUTColorMap* cm, rgbFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, cm, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; LUTColorMap* cm; rgbFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (cm); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (LUTColorMap* cm, rgbFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (LUTColorMap* cm, rgbFlexLexer* ll) #else int yyparse (cm, ll) LUTColorMap* cm; rgbFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 5: #line 59 "lutparser.Y" {cm->newRGBColor((yyvsp[(1) - (3)].real),(yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real));;} break; case 6: #line 60 "lutparser.Y" {DISCARD_(1);} break; case 10: #line 65 "lutparser.Y" {YYACCEPT;;} break; case 11: #line 68 "lutparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 12: #line 69 "lutparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 13: #line 72 "lutparser.Y" {yydebug=1;;} break; case 14: #line 73 "lutparser.Y" {yydebug=0;;} break; /* Line 1267 of yacc.c. */ #line 1417 "lutparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (cm, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (cm, ll, yymsg); } else { yyerror (cm, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, cm, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, cm, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (cm, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, cm, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, cm, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 75 "lutparser.Y" ����������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/saolex.L��������������������������������������������������������������������0000644�0001750�0001750�00000003665�12064133240�015444� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "saoparser.H" extern YYSTYPE* lilval; extern liFlexLexer* lilexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(lilval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(lilval->str,yytext,ll); lilval->str[ll] = '\0'; return STRING; } blue {return BLUE_;} debug {return DEBUG_;} gamma {return GAMMA_;} green {return GREEN_;} false {return FALSE_;} no {return NO_;} off {return OFF_;} on {return ON_;} pseudocolor {return PSEUDOCOLOR_;} red {return RED_;} true {return TRUE_;} yes {return YES_;} [+-]?{D}+ { // Integer lilval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number lilval->real = atof(yytext); return REAL; } [0-9A-Za-z]+ { // General String int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(lilval->str,yytext,ll); lilval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return toupper(yytext[0]); } %% void liDiscard(int doit) { if (lilexx) lilexx->begin(DISCARD, doit); } void liFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ���������������������������������������������������������������������������./saods9/saotk/colorbar/saolex.C��������������������������������������������������������������������0000644�0001750�0001750�00000132733�12064133240�015432� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "saolex.C" #line 4 "saolex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer liFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *lialloc (yy_size_t ); void *lirealloc (void *,yy_size_t ); void lifree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 23 #define YY_END_OF_BUFFER 24 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[84] = { 0, 0, 0, 2, 2, 24, 22, 19, 21, 22, 22, 22, 15, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 1, 19, 20, 0, 15, 17, 16, 15, 18, 18, 18, 18, 18, 18, 18, 8, 18, 10, 18, 18, 18, 18, 2, 0, 0, 0, 16, 18, 18, 18, 18, 18, 9, 18, 12, 18, 14, 16, 0, 17, 3, 18, 18, 18, 18, 18, 13, 4, 7, 5, 6, 18, 18, 18, 18, 18, 18, 11, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 6, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 16, 17, 18, 19, 20, 15, 21, 22, 23, 24, 15, 15, 15, 25, 15, 1, 1, 1, 1, 1, 1, 26, 27, 28, 29, 30, 31, 32, 15, 15, 15, 15, 33, 34, 35, 36, 37, 15, 38, 39, 40, 41, 15, 15, 15, 42, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[43] = { 0, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } ; static yyconst flex_int16_t yy_base[87] = { 0, 0, 0, 217, 210, 212, 222, 209, 222, 206, 37, 200, 39, 200, 41, 42, 44, 47, 43, 53, 54, 52, 57, 69, 0, 222, 202, 222, 196, 80, 82, 84, 91, 196, 95, 84, 100, 99, 101, 107, 195, 98, 194, 110, 117, 114, 111, 0, 60, 119, 192, 124, 130, 128, 135, 137, 133, 189, 138, 186, 147, 184, 182, 158, 144, 143, 150, 155, 160, 152, 167, 142, 141, 77, 74, 71, 169, 166, 174, 175, 178, 177, 55, 222, 215, 53, 218 } ; static yyconst flex_int16_t yy_def[87] = { 0, 83, 1, 84, 84, 83, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 83, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 83, 83, 83 } ; static yyconst flex_int16_t yy_nxt[265] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13, 15, 13, 16, 17, 13, 13, 13, 18, 19, 20, 21, 13, 22, 13, 23, 13, 14, 13, 15, 13, 16, 17, 13, 13, 18, 19, 20, 21, 13, 22, 13, 23, 28, 29, 31, 32, 83, 83, 83, 83, 34, 37, 83, 36, 38, 33, 35, 83, 83, 83, 83, 40, 83, 44, 50, 41, 62, 39, 34, 37, 42, 36, 38, 35, 83, 43, 83, 45, 40, 83, 46, 44, 83, 41, 39, 31, 29, 42, 30, 83, 30, 48, 43, 49, 45, 48, 31, 32, 46, 50, 83, 51, 34, 83, 83, 83, 83, 52, 53, 48, 57, 49, 83, 48, 54, 83, 83, 55, 56, 83, 34, 58, 83, 63, 52, 64, 53, 59, 57, 83, 51, 54, 61, 83, 55, 83, 56, 60, 83, 58, 83, 65, 83, 83, 69, 59, 83, 83, 83, 61, 64, 66, 83, 68, 60, 83, 67, 83, 71, 65, 83, 70, 69, 72, 64, 83, 73, 74, 66, 75, 68, 83, 83, 67, 83, 78, 71, 76, 70, 83, 83, 72, 83, 83, 73, 74, 75, 77, 62, 83, 80, 83, 79, 78, 83, 76, 81, 82, 62, 83, 83, 83, 30, 26, 77, 83, 30, 80, 27, 79, 26, 83, 25, 81, 82, 24, 24, 24, 47, 25, 47, 5, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83 } ; static yyconst flex_int16_t yy_chk[265] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 12, 12, 14, 15, 18, 16, 12, 16, 17, 15, 17, 85, 14, 21, 19, 20, 82, 18, 22, 21, 48, 19, 48, 17, 12, 16, 19, 15, 17, 14, 23, 20, 75, 22, 18, 74, 23, 21, 73, 19, 17, 29, 29, 19, 30, 35, 31, 29, 20, 30, 22, 31, 32, 32, 23, 34, 34, 34, 32, 41, 37, 36, 38, 35, 36, 29, 41, 30, 39, 31, 37, 43, 46, 38, 39, 45, 32, 43, 44, 49, 35, 49, 36, 44, 41, 51, 51, 37, 46, 53, 38, 52, 39, 45, 56, 43, 54, 52, 55, 58, 56, 44, 72, 71, 65, 46, 64, 53, 60, 55, 45, 66, 54, 69, 60, 52, 67, 58, 56, 66, 63, 68, 67, 68, 53, 69, 55, 77, 70, 54, 76, 77, 60, 70, 58, 78, 79, 66, 81, 80, 67, 68, 69, 76, 62, 61, 79, 59, 78, 77, 57, 70, 80, 81, 50, 42, 40, 33, 28, 26, 76, 13, 11, 79, 9, 78, 7, 5, 4, 80, 81, 84, 84, 84, 86, 3, 86, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "saolex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "saolex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "saoparser.H" extern YYSTYPE* lilval; extern liFlexLexer* lilexx; /* rules */ #line 508 "saolex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 31 "saolex.L" #line 612 "saolex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 84 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 83 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 33 "saolex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(lilval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 40 "saolex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(lilval->str,yytext,ll); lilval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 48 "saolex.L" {return BLUE_;} YY_BREAK case 4: YY_RULE_SETUP #line 49 "saolex.L" {return DEBUG_;} YY_BREAK case 5: YY_RULE_SETUP #line 50 "saolex.L" {return GAMMA_;} YY_BREAK case 6: YY_RULE_SETUP #line 51 "saolex.L" {return GREEN_;} YY_BREAK case 7: YY_RULE_SETUP #line 52 "saolex.L" {return FALSE_;} YY_BREAK case 8: YY_RULE_SETUP #line 53 "saolex.L" {return NO_;} YY_BREAK case 9: YY_RULE_SETUP #line 54 "saolex.L" {return OFF_;} YY_BREAK case 10: YY_RULE_SETUP #line 55 "saolex.L" {return ON_;} YY_BREAK case 11: YY_RULE_SETUP #line 56 "saolex.L" {return PSEUDOCOLOR_;} YY_BREAK case 12: YY_RULE_SETUP #line 57 "saolex.L" {return RED_;} YY_BREAK case 13: YY_RULE_SETUP #line 58 "saolex.L" {return TRUE_;} YY_BREAK case 14: YY_RULE_SETUP #line 59 "saolex.L" {return YES_;} YY_BREAK case 15: YY_RULE_SETUP #line 61 "saolex.L" { // Integer lilval->integer = atoi(yytext); return INT; } YY_BREAK case 16: #line 67 "saolex.L" case 17: YY_RULE_SETUP #line 67 "saolex.L" { // Real Number lilval->real = atof(yytext); return REAL; } YY_BREAK case 18: YY_RULE_SETUP #line 72 "saolex.L" { // General String int ll = yyleng <(SAOBUFSIZE-1) ? yyleng:(SAOBUFSIZE-1); strncpy(lilval->str,yytext,ll); lilval->str[ll] = '\0'; return STRING; } YY_BREAK case 19: YY_RULE_SETUP #line 79 "saolex.L" { // White Spaces } YY_BREAK case 20: /* rule 20 can match eol */ YY_RULE_SETUP #line 82 "saolex.L" { // windows line feed return '\n'; } YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP #line 86 "saolex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 90 "saolex.L" { // eof return EOF_; } YY_BREAK case 22: YY_RULE_SETUP #line 94 "saolex.L" { // Else, return the char return toupper(yytext[0]); } YY_BREAK case 23: YY_RULE_SETUP #line 98 "saolex.L" ECHO; YY_BREAK #line 842 "saolex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; lifree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); lifree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ lirealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) lirealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 84 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 84 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 83); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) lialloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) lialloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) lifree((void *) b->yy_ch_buf ); lifree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)lialloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)lirealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) lialloc(new_size ); else (yy_start_stack) = (int *) lirealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *lialloc (yy_size_t size ) { return (void *) malloc( size ); } void *lirealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void lifree (void * ptr ) { free( (char *) ptr ); /* see lirealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 98 "saolex.L" void liDiscard(int doit) { if (lilexx) lilexx->begin(DISCARD, doit); } void liFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } �������������������������������������./saods9/saotk/colorbar/lut.C�����������������������������������������������������������������������0000644�0001750�0001750�00000007326�12042560016�014743� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-200 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "lut.h" #include "colorbar.h" // LUT Parser Stuf #undef yyFlexLexer #define yyFlexLexer rgbFlexLexer #include <FlexLexer.h> void* rgblval; rgbFlexLexer* rgblexx; extern int rgbparse(LUTColorMap*, rgbFlexLexer*); int rgblex(void* vval, rgbFlexLexer* ll) { rgblval = vval; rgblexx = ll; return ll ? ll->yylex() : 0; } void rgberror(LUTColorMap* cm, rgbFlexLexer* ll, const char* m) {} // RGBColor istream& operator>>(istream& str, RGBColor& cc) { str >> cc.red_ >> cc.green_ >> cc.blue_; return str; } ostream& operator<<(ostream& str, RGBColor& cc) { str.setf(ios::fixed, ios::floatfield); str << setw(8) << setprecision(6) << cc.red_ << " " << cc.green_ << " " << cc.blue_ << endl; return str; } // LUTColorMap LUTColorMap::LUTColorMap(Colorbar* p) : ColorMapInfo(p) { } void LUTColorMap::newRGBColor(float r, float g, float b) { colors.append(new RGBColor(r,g,b)); } int LUTColorMap::load() { ifstream str(fileName); if (!str) return 0; rgbFlexLexer* ll = new rgbFlexLexer(&str); rgbparse(this, ll); delete ll; if (colors.isEmpty()) return 0; // bailout else return 1; // we found at least one RGBColor } int LUTColorMap::load(const char* var) { const char* ccmd = Tcl_GetVar(parent_->getInterp(), var, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (!ccmd) return 0; // only make command string as long as needed // or the rest will be processed as garbage int len = strlen(ccmd)+2; char* buf = new char[len]; memcpy(buf, ccmd, len); // add terminator to make parser happy buf[len-2] = '\n'; buf[len-1] = NULL; string x(buf); istringstream istr(x); rgbFlexLexer* ll = new rgbFlexLexer(&istr); rgbparse(this, ll); delete ll; delete [] buf; if (colors.isEmpty()) return 0; // bailout else return 1; // we found at least one RGBColor } void LUTColorMap::save(const char* fn) { ofstream fstr(fn); if (!fstr) return; fstr << *this; } unsigned char LUTColorMap::getRedChar(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index>=0 && index<size) return (unsigned char)(colors[index]->red() * UCHAR_MAX); else return 0; } unsigned char LUTColorMap::getGreenChar(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index>=0 && index<size) return (unsigned char)(colors[index]->green() * UCHAR_MAX); else return 0; } unsigned char LUTColorMap::getBlueChar(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index>=0 && index<size) return (unsigned char)(colors[index]->blue() * UCHAR_MAX); else return 0; } unsigned short LUTColorMap::getRedShrt(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index >=0 && index < size) return (unsigned short)(colors[index]->red() * USHRT_MAX); else return 0; } unsigned short LUTColorMap::getGreenShrt(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index>=0 && index<size) return (unsigned short)(colors[index]->green() * USHRT_MAX); else return 0; } unsigned short LUTColorMap::getBlueShrt(int ii, int count) { int size = colors.count(); int index = (int)((ii*size/count) + .5); if (index>=0 && index<size) return (unsigned short)(colors[index]->blue() * USHRT_MAX); else return 0; } ostream& operator<<(ostream& str, LUTColorMap& cc) { cc.colors.head(); do str << *cc.colors.current(); while (cc.colors.next()); return str; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbar.C������������������������������������������������������������������0000644�0001750�0001750�00000044550�11755217460�015756� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <fstream> #include "colorbar.h" #include "util.h" #include "ps.h" #include "lut.h" #include "sao.h" #include "default.h" Colorbar::Colorbar(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item) { colorIndex = NULL; bias = .5; contrast = 1.0; tag =NULL; tagaction =NONE; taginit =0; } Colorbar::~Colorbar() { if (colorIndex) delete [] colorIndex; } void Colorbar::adjustCmd(float c, float b) { contrast = c; bias = b; updateColors(); } void Colorbar::getBiasCmd() { ostringstream str; str << bias << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Colorbar::getColorbarCmd() { if (cmaps.current()) { ostringstream str; str << cmaps.current()->getID() << ' ' << bias << ' ' << contrast << ' ' << invert << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } else result = TCL_ERROR; } void Colorbar::getColormapCmd() { if (cmaps.current()) { ostringstream str; str << cmaps.current()->getID() << ' ' << bias << ' ' << contrast << ' ' << invert << ' ' << colorIndex << ' ' << (unsigned short*)colorCells << ' ' << colorCount << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } else result = TCL_ERROR; } void Colorbar::getColormapNameCmd(int id) { ColorMapInfo* ptr = cmaps.begin(); while (ptr) { if (ptr->getID() == id) { Tcl_AppendResult(interp, (char*)ptr->getName(), NULL); return; } ptr = ptr->next(); } // if we got this far, we did not find it, bail out Tcl_AppendResult(interp, " colormap not found.", NULL); result = TCL_ERROR; } void Colorbar::getColormapFileNameCmd(int id) { ColorMapInfo* ptr = cmaps.begin(); while (ptr) { if (ptr->getID() == id) { Tcl_AppendResult(interp, (char*)ptr->getFileName(), NULL); return; } ptr = ptr->next(); } // if we got this far, we did not find it, bail out Tcl_AppendResult(interp, " colormap not found.", NULL); result = TCL_ERROR; } void Colorbar::getContrastCmd() { ostringstream str; str << contrast << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Colorbar::getCurrentIDCmd() { if (cmaps.current()) { ostringstream str; str << cmaps.current()->getID() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } else result = TCL_ERROR; } void Colorbar::getCurrentNameCmd() { if (cmaps.current()) Tcl_AppendElement(interp, (char*)cmaps.current()->getName()); else result = TCL_ERROR; } void Colorbar::getCurrentFileNameCmd() { if (cmaps.current()) Tcl_AppendElement(interp, (char*)cmaps.current()->getFileName()); else result = TCL_ERROR; } void Colorbar::getRGBChannelCmd() { Tcl_AppendResult(interp, "red", NULL); } void Colorbar::listIDCmd() { ColorMapInfo* ptr = cmaps.begin(); while (ptr) { ostringstream str; str << ptr->getID() << ends; Tcl_AppendElement(interp, str.str().c_str()); ptr = ptr->next(); } } void Colorbar::listNameCmd() { ColorMapInfo* ptr = cmaps.begin(); while (ptr) { Tcl_AppendElement(interp, (char*)ptr->getName()); ptr = ptr->next(); } } void Colorbar::loadCmd(const char* fn, const char* type) { ColorMapInfo* map = newColorMap(fn, type); if (map && map->load()) { // add new colormap to end of the list cmaps.append(map); reset(); } else { // something has gone wrong, clean up, and bail out delete map; Tcl_AppendResult(interp, " unable to load colormap: ", fn, NULL); result = TCL_ERROR; } } void Colorbar::loadCmd(const char* fn, const char* type, const char* var) { ColorMapInfo* map = newColorMap(fn, type); if (map && map->load(var)) { // add new colormap to end of the list cmaps.append(map); reset(); } else { // something has gone wrong, clean up, and bail out delete map; Tcl_AppendResult(interp, " unable to load colormap: ", fn, NULL); result = TCL_ERROR; } } void Colorbar::mapCmd(char* which) { char* a = toLower(which); cmaps.head(); do { char* b = toLower(cmaps.current()->getName()); if (!strcmp(a,b)) { reset(); delete [] a; delete [] b; return; } delete [] b; } while (cmaps.next()); // if we got this far, we did not find it, bail out cmaps.head(); delete [] a; result = TCL_ERROR; } void Colorbar::mapCmd(int id) { cmaps.head(); do { if (cmaps.current()->getID() == id) { reset(); return; } } while (cmaps.next()); // if we got this far, we did not find it, bail out cmaps.head(); result = TCL_ERROR; } void Colorbar::saveCmd(const char* fn) { cmaps.current()->save(fn); } void Colorbar::saveCmd(int id, const char* fn) { ColorMapInfo* ptr = cmaps.begin(); while (ptr) { if (ptr->getID() == id) { ptr->save(fn); return; } ptr = ptr->next(); } result = TCL_ERROR; } void Colorbar::setColorbarCmd(int id, float b, float c, int i) { cmaps.head(); while (cmaps.current()) { if (cmaps.current()->getID() == id) { bias = b; contrast = c; invert = i; updateColors(); return; } cmaps.next(); } // if we got this far, we did not find it, bail out cmaps.head(); result = TCL_ERROR; } void Colorbar::getTagCmd() { ostringstream str; ctags.head(); while (ctags.current()) { str << ctags.current()->start() << ' ' << ctags.current()->stop() << ' ' << ctags.current()->colorname() << ' '; ctags.next(); } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void Colorbar::getTagCmd(int xx, int yy) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int rr,ss; if (!opts->orientation) { rr = xx; ss = float(rr)/opts->width * colorCount; } else { rr = yy; ss = (1-float(rr)/opts->height) * colorCount; } ctags.head(); while (ctags.current()) { if (ss>ctags.current()->start() && ss<ctags.current()->stop()) { int startid = float(ctags.current()->start())/colorCount * cnt; int stopid = float(ctags.current()->stop())/colorCount * cnt; if (startid<0) startid = 0; if (startid>=cnt) startid = cnt-1; if (stopid<0) stopid = 0; if (stopid>=cnt) stopid = cnt-1; ostringstream str; str << ctags.current()->id() << ' ' << lut[startid] << ' ' << lut[stopid] << ' ' << ctags.current()->colorname() << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); return; } ctags.next(); } } void Colorbar::tagCmd(const char* txt) { ctags.deleteAll(); istringstream str(txt); while (!str.eof()) { int aa =0; int bb =0; char color[32]; *color =NULL; str >> aa >> bb >> color; if (aa && bb && *color) ctags.append(new ColorTag(this,aa,bb,color)); } updateColors(); } void Colorbar::tagCmd(int id, const Vector& v, const char* color) { Vector vv = v; int mm=0; int nn=0; ctags.head(); while (ctags.current()) { if (ctags.current()->id() == id) { // special case if (vv[0]>lut[cnt-1] && vv[1]>lut[cnt-1]) return; else if (vv[0]<lut[0] && vv[1]<lut[0]) return; mm =0; for (int ii=0; ii<cnt; ii++) if (vv[0]<lut[ii]) { mm=ii; break; } nn =cnt-1; for (int ii=cnt-1; ii>=0; ii--) if (vv[1]>lut[ii]) { nn=ii; break; } Vector rr = Vector(mm,nn)/cnt*colorCount; ctags.current()->set(rr[0],rr[1],color); updateColors(); return; } ctags.next(); } } void Colorbar::tagDeleteCmd() { ctags.deleteAll(); updateColors(); } void Colorbar::tagDeleteCmd(int xx, int yy) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int rr,ss; if (!opts->orientation) { rr = xx; ss = float(rr)/opts->width * colorCount; } else { rr = yy; ss = (1-float(rr)/opts->height) * colorCount; } ctags.head(); while (ctags.current()) { if (ss>ctags.current()->start() && ss<ctags.current()->stop()) { ColorTag* ct = ctags.extract(); if (ct) delete ct; updateColors(); return; } ctags.next(); } } void Colorbar::tagEditBeginCmd(int xx, int yy, const char* color) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; tag= NULL; tagaction =NONE; taginit =0; int rr,ss; if (!opts->orientation) { rr = xx; ss = float(rr)/opts->width * colorCount; } else { rr = yy; ss = (1-float(rr)/opts->height) * colorCount; } ctags.head(); while (ctags.current()) { int start = ctags.current()->start(); int stop = ctags.current()->stop(); if (ss>start && ss<stop) { if (ss>stop-10 && ss<stop) { tagaction =STOP; } else if (ss>start && ss<start+10) { tagaction =START; } else { tagaction =MOVE; } tag = ctags.current(); taginit =rr; return; } ctags.next(); } // else create a new tag ctags.append(new ColorTag(this,ss,ss,color)); tag = ctags.current(); tagaction =CREATE; taginit =rr; } void Colorbar::tagEditMotionCmd(int xx, int yy) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (tag) { int rr,ss,tt; if (!opts->orientation) { rr = xx; ss = float(rr)/opts->width * colorCount; tt = float(taginit)/opts->width *colorCount; } else { rr = yy; ss = (1-float(rr)/opts->height) * colorCount; tt = (1-float(taginit)/opts->height) *colorCount; } switch (tagaction) { case NONE: break; case CREATE: tagaction =STOP; tag->move(0,ss-tt); break; case START: tag->move(ss-tt,0); break; case STOP: tag->move(0,ss-tt); break; case MOVE: tag->move(ss-tt,ss-tt); break; } taginit = rr; updateColors(); } } void Colorbar::tagEditEndCmd(int xx, int yy) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (tag) { int rr,ss,tt; if (!opts->orientation) { rr = xx; ss = float(rr)/opts->width * colorCount; tt = float(taginit)/opts->width *colorCount; } else { rr = yy; ss = (1-float(rr)/opts->height) * colorCount; tt = (1-float(taginit)/opts->height) *colorCount; } switch (tagaction) { case NONE: break; case CREATE: tag->width(100); break; case START: break; case STOP: break; case MOVE: break; } updateColors(); } } void Colorbar::tagLoadCmd(const char* fn) { ifstream str(fn); if (str) { ctags.deleteAll(); while (!str.eof()) { int mm=0; int nn=0; double aa =0; double bb =0; char color[32]; *color =NULL; str >> aa >> bb >> color; if (aa && bb && *color) { // special case if (aa>lut[cnt-1] && bb>lut[cnt-1]) continue; else if (aa<lut[0] && bb<lut[0]) continue; mm =0; for (int ii=0; ii<cnt; ii++) if (aa<lut[ii]) { mm=ii; break; } nn =cnt-1; for (int ii=cnt-1; ii>=0; ii--) if (bb>lut[ii]) { nn=ii; break; } Vector rr = Vector(mm,nn)/cnt*colorCount; ctags.append(new ColorTag(this,rr[0],rr[1],color)); } } updateColors(); } } void Colorbar::tagSaveCmd(const char* fn) { ofstream str(fn); if (str) { ctags.head(); while (ctags.current()) { int startid = float(ctags.current()->start())/colorCount * cnt; int stopid = float(ctags.current()->stop())/colorCount * cnt; if (startid<0) startid = 0; if (startid>=cnt) startid = cnt-1; if (stopid<0) stopid = 0; if (stopid>=cnt) stopid = cnt-1; str << lut[startid] << ' ' << lut[stopid] << ' ' << ctags.current()->colorname() << endl; ctags.next(); } } } // private int Colorbar::calcContrastBias(int i) { // if default (contrast = 1.0 && bias = .5) return if (fabs(bias - 0.5) < 0.0001 && fabs(contrast - 1.0) < 0.0001) return i; // map i to range of 0 to 1.0 // shift by bias (if invert, bias = 1-bias) // multiply by contrast // shift to center of region // expand back to number of dynamic colors float b = invert ? 1-bias : bias; int r = (int)(((((float)i / colorCount) - b) * contrast + .5 ) * colorCount); // clip to bounds if out of range if (r < 0) return 0; else if (r >= colorCount) return colorCount-1; else return r; } void Colorbar::reset() { bias = 0.5; contrast = 1.0; invert = 0; updateColors(); } void Colorbar::loadDefaultCMaps() { cmaps.append(new GreyColorMap(this)); cmaps.append(new RedColorMap(this)); cmaps.append(new GreenColorMap(this)); cmaps.append(new BlueColorMap(this)); cmaps.append(new AColorMap(this)); cmaps.append(new BColorMap(this)); cmaps.append(new BBColorMap(this)); cmaps.append(new HEColorMap(this)); cmaps.append(new I8ColorMap(this)); cmaps.append(new AIPSColorMap(this)); cmaps.append(new SLSColorMap(this)); cmaps.append(new HSVColorMap(this)); cmaps.append(new HeatColorMap(this)); cmaps.append(new CoolColorMap(this)); cmaps.append(new RainbowColorMap(this)); cmaps.append(new StandardColorMap(this)); cmaps.append(new StaircaseColorMap(this)); cmaps.append(new ColorColorMap(this)); cmaps.head(); } ColorMapInfo* Colorbar::newColorMap(const char* fn, const char* type) { // determine colormap type char* tmp = dupstr(fn); // tmp memory, we will mangle it char* ptr = tmp; while (*ptr++); // walk forward till end of string ptr--; // backup one while (ptr != tmp && *ptr != '.') // march backward looking for '.' ptr--; if (ptr != tmp) { // are we at '.' or start of string *ptr = '\0'; // mark end of string at '.' ptr++; } // Create ColorMap ColorMapInfo* map = NULL; // if type specified, use it, otherwise, use file extension if (type) ptr = (char*)type; if (strncmp(ptr, "lut", 3) == 0) map = new LUTColorMap(this); else map = new SAOColorMap(this); // Bail out if we don't have a new ColorMap if (!map) return NULL; // Extract a name from the file name. Any extension has already been removed. ptr = tmp; while (*ptr++); // walk forward till end of string while (ptr != tmp && *ptr != '/') // march backward looking for '/' ptr--; if (ptr != tmp) // see if we found '/' or at begining of string ptr++; map->setName(ptr); map->setFileName(fn); delete [] tmp; // clean up return map; } void Colorbar::psHorz(Filter& filter, int width, int height) { for (int jj=0; jj<height; jj++) { ostringstream str; for (int ii=0; ii<width; ii++) { int kk = (int)(double(ii)/width*colorCount)*3; unsigned char red = colorCells[kk+2]; unsigned char green = colorCells[kk+1]; unsigned char blue = colorCells[kk]; switch (psColorSpace) { case BW: case GRAY: filter << RGB2Gray(red, green, blue); break; case RGB: filter << red << green << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter; } str << ends; psFix(str); Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void Colorbar::psVert(Filter& filter, int width, int height) { for (int jj=0; jj<height; jj++) { ostringstream str; int kk = (int)(double(jj)/height*colorCount)*3; unsigned char red = colorCells[kk+2]; unsigned char green = colorCells[kk+1]; unsigned char blue = colorCells[kk]; switch (psColorSpace) { case BW: case GRAY: for (int ii=0; ii<width; ii++) filter << RGB2Gray(red, green, blue); break; case RGB: for (int ii=0; ii<width; ii++) filter << red << green << blue; break; case CMYK: for (int ii=0; ii<width; ii++) { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter << ends; psFix(str); Tcl_AppendResult(interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void Colorbar::macosx(float scale, int width, int height, const Vector& v, const Vector& s) { if (!colorCells) return; // destination unsigned char* dst = new unsigned char[width*height*4]; unsigned char* dptr = dst; if (!((ColorbarBaseOptions*)options)->orientation) { for (int jj=0; jj<height; jj++) for (int ii=0; ii<width; ii++) { int kk = (int)(double(ii)/width*colorCount)*3; *dptr++ = colorCells[kk+2]; *dptr++ = colorCells[kk+1]; *dptr++ = colorCells[kk]; *dptr++ = 0; } } else { for (int jj=0; jj<height; jj++) { int kk = (int)(double(jj)/height*colorCount)*3; unsigned char rr = colorCells[kk+2]; unsigned char gg = colorCells[kk+1]; unsigned char bb = colorCells[kk]; for (int ii=0; ii<width; ii++) { *dptr++ = rr; *dptr++ = gg; *dptr++ = bb; *dptr++ = 0; } } } macosxBitmapCreate(dst, width, height, v, s); if (dst) delete [] dst; } #endif #ifdef _WIN32 void Colorbar::win32(float scale, int width, int height, const Vector& v, const Vector& s) { if (!colorCells) return; // destination (width must be aligned on 4-byte DWORD boundary) int jjwidth=(((width+3)/4)*4); // extra alignment padding which we have to skip over for each row int jjpad=(jjwidth-width)*3; unsigned char* dst = new unsigned char[jjwidth*height*3]; if (!dst) return; memset(dst, '\0', jjwidth*height*3); unsigned char* dptr = dst; if (!((ColorbarBaseOptions*)options)->orientation) { for (int jj=0; jj<height; jj++) { for (int ii=0; ii<width; ii++) { int kk = (int)(double(ii)/width*colorCount)*3; *dptr++ = colorCells[kk]; *dptr++ = colorCells[kk+1]; *dptr++ = colorCells[kk+2]; } dptr += jjpad; } } else { for (int jj=0; jj<height; jj++) { int kk = (int)(double(jj)/height*colorCount)*3; unsigned char rr = colorCells[kk]; unsigned char gg = colorCells[kk+1]; unsigned char bb = colorCells[kk+2]; for (int ii=0; ii<width; ii++) { *dptr++ = rr; *dptr++ = gg; *dptr++ = bb; } dptr += jjpad; } } win32Clip(v,s); win32BitmapCreate(dst, jjwidth, height, v, s); win32Clip(Vector(INT_MIN,INT_MIN),Vector(INT_MAX,INT_MAX)); if (dst) delete [] dst; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor.C���������������������������������������������������������0000644�0001750�0001750�00000002725�11752025335�017706� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "colorbartruecolor.h" #include "util.h" ColorbarTrueColor::ColorbarTrueColor(Tcl_Interp* i,Tk_Canvas c,Tk_Item* item) : ColorbarBase(i,c,item), Colorbar(i,c,item), ColorbarTrue(i,c,item) { colorCount = 0; } int ColorbarTrueColor::initColormap() { colorCount = (((ColorbarBaseOptions*)options)->colors); colorIndex = new unsigned short[colorCount]; for (int i=0; i<colorCount; i++) colorIndex[i] = i; colorCells = new unsigned char[colorCount*3]; return TCL_OK; } void ColorbarTrueColor::updateColorCells() { // fill rgb table // note: its filled bgr to match XImage if (cmaps.current()) for(int i=0, j=colorCount-1; i<colorCount; i++, j--) { int index = invert ? calcContrastBias(j) : calcContrastBias(i); colorCells[i*3] = cmaps.current()->getBlueChar(index, colorCount); colorCells[i*3+1] = cmaps.current()->getGreenChar(index, colorCount); colorCells[i*3+2] = cmaps.current()->getRedChar(index, colorCount); } ctags.head(); while (ctags.current()) { for (int ii=ctags.current()->start(); ii<ctags.current()->stop(); ii++) { colorCells[ii*3] = ctags.current()->colorBlue(); colorCells[ii*3+1] = ctags.current()->colorGreen(); colorCells[ii*3+2] = ctags.current()->colorRed(); } ctags.next(); } } �������������������������������������������./saods9/saotk/colorbar/colortag.h������������������������������������������������������������������0000644�0001750�0001750�00000002426�11752046251�016021� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colortag_h__ #define __colortag_h__ #include <string.h> #include <stdlib.h> #include <limits.h> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> using namespace std; #include <tcl.h> #include <tk.h> class Colorbar; class ColorTag { protected: int id_; Colorbar* parent_; const char* colorname_; XColor* color_; int start_; int stop_; ColorTag* next_; ColorTag* previous_; public: ColorTag(Colorbar*, int, int, const char*); virtual ~ColorTag(); int id() {return id_;} Colorbar* parent() {return parent_;} int start() {return start_;} int stop() {return stop_;} const char* colorname() {return colorname_;} void move(int,int); void set(int,int,const char*); void width(int); unsigned short colorRed() {return color_ ? color_->red : 0;} unsigned short colorGreen() {return color_ ? color_->green : 0;} unsigned short colorBlue() {return color_ ? color_->blue : 0;} ColorTag* next() {return next_;} ColorTag* previous() {return previous_;} void setNext(ColorTag* n) {next_ = n;} void setPrevious(ColorTag* p) {previous_=p;} }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudocolor8.h������������������������������������������������������0000644�0001750�0001750�00000001171�11700666264�020362� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarpseudocolor8_h__ #define __colorbarpseudocolor8_h__ #include "colorbarpseudocolor.h" // Colomap(s) will contain a variable number of color cells, based on // available color cells and if a private Colormap is used. class ColorbarPseudoColor8 : public ColorbarPseudoColor { private: void ximageToPixmap(); void ximageToPixmapHorz(); void ximageToPixmapVert(); public: ColorbarPseudoColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudocolor.h�������������������������������������������������������0000644�0001750�0001750�00000001355�11700666264�020276� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarpseudocolor_h__ #define __colorbarpseudocolor_h__ #include "colorbarpseudo.h" #include "colorbar.h" class ColorbarPseudoColor : public virtual ColorbarBase, public Colorbar, public ColorbarPseudo { protected: int privateUsed; // flag to indicate private allocated Colormap colormap; // current Colormap private: int initDefaultMap(); int initPrivateMap(); protected: int initColormap(); void updateColors(); public: ColorbarPseudoColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); void setColormapWindowCmd(char*); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colormap.C������������������������������������������������������������������0000644�0001750�0001750�00000001320�11743600735�015751� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colormap.h" #include "util.h" static int squenceID = 1; // ColorMapInfo ColorMapInfo::ColorMapInfo(Colorbar* p) : parent_(p) { id = squenceID++; name =NULL; fileName =NULL; next_ =NULL; previous_ =NULL; } ColorMapInfo::~ColorMapInfo() { if (name) delete [] name; if (fileName) delete [] fileName; } void ColorMapInfo::setName(const char* n) { if (name) delete [] name; name = dupstr(n); } void ColorMapInfo::setFileName(const char* n) { if (fileName) delete [] fileName; fileName = dupstr(n); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor8.h�����������������������������������������������������0000644�0001750�0001750�00000001002�11700666264�020526� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarrgbtruecolor8_h__ #define __colorbarrgbtruecolor8_h__ #include "colorbarrgbtruecolor.h" #include "truecolor8.h" class ColorbarRGBTrueColor8 : public ColorbarRGBTrueColor, TrueColor8 { private: void updateColorsHorz(); void updateColorsVert(); public: ColorbarRGBTrueColor8(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor.h������������������������������������������������������0000644�0001750�0001750�00000001040�11700666264�020440� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarrgbtruecolor_h__ #define __colorbarrgbtruecolor_h__ #include "colorbarrgb.h" #include "colorbartrue.h" class ColorbarRGBTrueColor : public virtual ColorbarBase, public ColorbarRGB, public ColorbarTrue { private: int initColormap(); protected: void updateColorCells(); public: ColorbarRGBTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/parser.H��������������������������������������������������������������������0000644�0001750�0001750�00000010247�11752046251�015443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, POINTER = 261, ADJUST_ = 262, BEGIN_ = 263, BIAS_ = 264, BW_ = 265, CHANNEL_ = 266, CMYK_ = 267, COLORMAP_ = 268, COLORBAR_ = 269, COLORSPACE_ = 270, CONTRAST_ = 271, DEBUG_ = 272, DELETE_ = 273, EDIT_ = 274, END_ = 275, GET_ = 276, GRAY_ = 277, FALSE_ = 278, FILE_ = 279, HEIGHT_ = 280, HIDE_ = 281, ID_ = 282, INVERT_ = 283, ITT_ = 284, LEVEL_ = 285, LIST_ = 286, LOAD_ = 287, MACOSX_ = 288, MAP_ = 289, MOTION_ = 290, N_ = 291, NAME_ = 292, NO_ = 293, OFF_ = 294, ON_ = 295, POSTSCRIPT_ = 296, PRINT_ = 297, RESET_ = 298, RESOLUTION_ = 299, RGB_ = 300, SAVE_ = 301, SHOW_ = 302, TAG_ = 303, TRUE_ = 304, VALUE_ = 305, VAR_ = 306, VERSION_ = 307, WIDTH_ = 308, WIN32_ = 309, WINDOW_ = 310, Y_ = 311, YES_ = 312 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define POINTER 261 #define ADJUST_ 262 #define BEGIN_ 263 #define BIAS_ 264 #define BW_ 265 #define CHANNEL_ 266 #define CMYK_ 267 #define COLORMAP_ 268 #define COLORBAR_ 269 #define COLORSPACE_ 270 #define CONTRAST_ 271 #define DEBUG_ 272 #define DELETE_ 273 #define EDIT_ 274 #define END_ 275 #define GET_ 276 #define GRAY_ 277 #define FALSE_ 278 #define FILE_ 279 #define HEIGHT_ 280 #define HIDE_ 281 #define ID_ 282 #define INVERT_ 283 #define ITT_ 284 #define LEVEL_ 285 #define LIST_ 286 #define LOAD_ 287 #define MACOSX_ 288 #define MAP_ 289 #define MOTION_ 290 #define N_ 291 #define NAME_ 292 #define NO_ 293 #define OFF_ 294 #define ON_ 295 #define POSTSCRIPT_ 296 #define PRINT_ 297 #define RESET_ 298 #define RESOLUTION_ 299 #define RGB_ 300 #define SAVE_ 301 #define SHOW_ 302 #define TAG_ 303 #define TRUE_ 304 #define VALUE_ 305 #define VAR_ 306 #define VERSION_ 307 #define WIDTH_ 308 #define WIN32_ 309 #define WINDOW_ 310 #define Y_ 311 #define YES_ 312 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 25 "parser.Y" { #define CBBUFSIZE 1024 float real; int integer; char str[CBBUFSIZE]; void* ptr; } /* Line 1529 of yacc.c. */ #line 171 "parser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudocolor.C�������������������������������������������������������0000644�0001750�0001750�00000011451�11714322407�020220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "colorbarpseudocolor.h" #include "util.h" ColorbarPseudoColor::ColorbarPseudoColor(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), Colorbar(i,c,item), ColorbarPseudo(i,c,item) { colormap = 0; privateUsed = 0; } // initColormap allocates the requested number of color colorCells int ColorbarPseudoColor::initColormap() { // initialize default or private colormap if (((ColorbarBaseOptions*)options)->privateCmap) { if (initPrivateMap() == TCL_ERROR) return TCL_ERROR; } else if (initDefaultMap() == TCL_ERROR) if (initPrivateMap() == TCL_ERROR) return TCL_ERROR; // by now, we should have a map with at least min colors updateColors(); return TCL_OK; } int ColorbarPseudoColor::initDefaultMap() { // grap default colormap colormap = Tk_Colormap(tkwin); // see if we can allocate at least min number of colors requested int minColors = ((ColorbarBaseOptions*)options)->minColors; int maxColors = ((ColorbarBaseOptions*)options)->maxColors; unsigned long* cells = new unsigned long[((ColorbarBaseOptions*)options)->maxColors]; for (int k=maxColors; k>=minColors-1; k--) if (XAllocColorCells(display, colormap, False, 0, 0, cells, k)) { colorCount = k; // copy from long to unsign short colorIndex = new unsigned short[colorCount]; for (int i=0; i<colorCount; i++) colorIndex[i] = cells[i]; colorCells = new unsigned char[colorCount*3]; delete [] cells; return TCL_OK; } delete [] cells; return TCL_ERROR; } int ColorbarPseudoColor::initPrivateMap() { int privateColors = ((ColorbarBaseOptions*)options)->privateColors; int defCount = 254 - 8 - 8 - privateColors; // first, grap most of the default colors from the current color map Colormap defColormap = Tk_Colormap(tkwin); XColor* defColors= new XColor[defCount]; for (int i=0; i<defCount; i++) defColors[i].pixel = i; XQueryColors(display, defColormap, defColors, defCount); // now, allocate a new private map colormap = Tk_GetColormap(interp, tkwin, "new"); // allocate the default colors unsigned long* defCells = new unsigned long[defCount]; if (!XAllocColorCells(display, colormap, False, 0, 0, defCells, defCount)) { Tcl_AppendResult(interp, " unable to allocate default colors", " in private colormap.", NULL); return TCL_ERROR; } // store default colors XStoreColors(display, colormap, defColors, defCount); // and finally, allocate the dynamic colors colorCount = privateColors; unsigned long* cells = new unsigned long[colorCount]; if (!XAllocColorCells(display, colormap, False, 0, 0, cells, colorCount)) { Tcl_AppendResult(interp, " unable to allocate maxium number of colors", " in private colormap.", NULL); return TCL_ERROR; } // copy from long to unsign char colorIndex = new unsigned short[colorCount]; for (int j=0; j<colorCount; j++) colorIndex[j] = cells[j]; colorCells = new unsigned char[colorCount*3]; // and init the first DEFCMAP colors privateUsed = 1; // assign private map to this window Tk_SetWindowColormap(tkwin, colormap); // force the private map to be loaded now XInstallColormap(display, colormap); delete [] cells; delete [] defCells; delete [] defColors; return TCL_OK; } void ColorbarPseudoColor::updateColors() { XColor* colors = new XColor[colorCount]; if (cmaps.current()) for(int ii=0, jj=colorCount-1; ii<colorCount; ii++, jj--) { int index = invert ? calcContrastBias(jj) : calcContrastBias(ii); // fill in colors colors[ii].pixel = colorIndex[ii]; colors[ii].red = cmaps.current()->getRedShrt(index, colorCount); colors[ii].green = cmaps.current()->getGreenShrt(index, colorCount); colors[ii].blue = cmaps.current()->getBlueShrt(index, colorCount); colors[ii].flags = DoRed | DoGreen | DoBlue; // fill in rest of colorCells // Note: we fill the array bgr colorCells[ii*3] = cmaps.current()->getBlueChar(index, colorCount); colorCells[ii*3+1] = cmaps.current()->getGreenChar(index, colorCount); colorCells[ii*3+2] = cmaps.current()->getRedChar(index, colorCount); } XStoreColors(display, colormap, colors, colorCount); delete [] colors; } void ColorbarPseudoColor::setColormapWindowCmd(char* str) { Tk_Window win = Tk_NameToWindow(interp, str, tkwin); // Check to see if we have the same visual (and depth) if (Tk_Visual(tkwin) == Tk_Visual(win) && Tk_Depth(tkwin) == Tk_Depth(win)) { if (win) Tk_SetWindowColormap(win, colormap); else result = TCL_ERROR; } else internalError("Colorbar: Visual mismatch"); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/cbgrid.C��������������������������������������������������������������������0000644�0001750�0001750�00000011721�11701400210�015351� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "cbgrid.h" #include "colorbarbase.h" #include "util.h" extern "C" { #include "ast.h" } extern Grid2dBase* astGrid2dPtr; CBGrid::CBGrid(Widget* p, int cc, double* ll) : cnt_(cc), lut_(ll), Grid2dBase(p) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)(((ColorbarBase*)parent_)->options); ostringstream str; // basics str << "Grid=0, DrawAxes=0, MinTickLen(1)=0, MinTickLen(2)=0, Colour(ticks)=0, Width(ticks)=.5, Style(ticks)=0, Border=1, Colour(border)=0, Width(border)=.5, Style(border)=0, Labelling=exterior, Colour(numlab)=0, TextLab=0, DrawTitle=0"; if (!opts->orientation) { // horizontal str << ", Edge(1)=top, Edge(2)=left, LabelUp(1)=1, MajTickLen(1)=-.15, MajTickLen(2)=0, NumLab(1)=1, NumLab(2)=0, NumLabGap(1)=.5"; } else { // vertical str << ", Edge(1)=bottom, Edge(2)=right, LabelUp(2)=1, MajTickLen(1)=0, MajTickLen(2)=-.15, NumLab(1)=0, NumLab(2)=1, NumLabGap(2)=.5"; } // font { char* fn = opts->font; int fz = opts->fontSize; char* fw = opts->fontWeight; char* fs = opts->fontSlant; int ff; if (!(strncmp(fn,"times",4) || strncmp(fw,"normal",4) || strncmp(fs,"roman",4))) ff = 1; else if (!(strncmp(fn,"helvetica",4) || strncmp(fw,"normal",4) || strncmp(fs,"roman",4))) ff = 2; else if (!(strncmp(fn,"courier",4) || strncmp(fw,"normal",4) || strncmp(fs,"roman",4))) ff = 4; else if (!(strncmp(fn,"times",4) || strncmp(fw,"bold",4) || strncmp(fs,"roman",4))) ff = 11; else if (!(strncmp(fn,"helvetica",4) || strncmp(fw,"bold",4) || strncmp(fs,"roman",4))) ff = 12; else if (!(strncmp(fn,"courier",4) || strncmp(fw,"bold",4) || strncmp(fs,"roman",4))) ff = 14; else if (!(strncmp(fn,"times",4) || strncmp(fw,"normal",4) || strncmp(fs,"italic",4))) ff = 21; else if (!(strncmp(fn,"helvetica",4) || strncmp(fw,"normal",4) || strncmp(fs,"italic",4))) ff = 22; else if (!(strncmp(fn,"courier",4) || strncmp(fw,"normal",4) || strncmp(fs,"italic",4))) ff = 24; else if (!(strncmp(fn,"times",4) || strncmp(fw,"bold",4) || strncmp(fs,"italic",4))) ff = 31; else if (!(strncmp(fn,"helvetica",4) || strncmp(fw,"bold",4) || strncmp(fs,"italic",4))) ff = 32; else if (!(strncmp(fn,"courier",4) || strncmp(fw,"bold",4) || strncmp(fs,"italic",4))) ff = 34; else ff = 1; str << ", Font(numlab)=" << ff << ", Size(numlab)=" << fz << ends; } option_ = dupstr(str.str().c_str()); } int CBGrid::render() { gc_ = ((ColorbarBase*)parent_)->gc; pixmap_ = ((ColorbarBase*)parent_)->pixmap; return doit(X11); } int CBGrid::ps(int mode, int x, int y) { matrix_ = Translate(x,y); mode_ = mode; return doit(PS); } #ifdef _MACOSX int CBGrid::macosx(int x, int y) { matrix_ = Translate(x,y); return doit(MACOSX); } #endif #ifdef _WIN32 int CBGrid::win32(int x, int y) { matrix_ = Translate(x,y); return doit(GWIN32); } #endif int CBGrid::doit(RenderMode rm) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)(((ColorbarBase*)parent_)->options); astClearStatus; // just to make sure astBegin; // start memory management AstFrameSet* frameSet = NULL; AstCmpMap* cmp = NULL; AstLutMap* aa = NULL; AstUnitMap* bb = NULL; AstPlot* plot = NULL; if (!(frameSet = astFrameSet(astFrame(2,"Domain=WIDGET"),""))) goto error; if (!(bb = astUnitMap(1,""))) goto error; if (!opts->orientation) { if (!(aa = astLutMap(cnt_, lut_, 0, double(opts->width)/(cnt_-1), ""))) goto error; if (!(cmp = astCmpMap(aa, bb, 0, ""))) goto error; } else { if (!(aa = astLutMap(cnt_, lut_, 0, double(opts->height)/(cnt_-1), ""))) goto error; if (!(cmp = astCmpMap(bb, aa, 0, ""))) goto error; } astAddFrame(frameSet, AST__CURRENT, cmp, astFrame(2, "Domain=LUT")); astSet(frameSet,"Title=%s", " "); if (0) { int status = astStatus; astClearStatus; astShow(frameSet); astSetStatus(status); } // create astPlot float gbox[4]; double pbox[4]; int ww,hh,zz; if (!opts->orientation) { ww = opts->width; hh = opts->size; } else { ww = opts->size; hh = opts->height; } zz =0; switch (rm) { case X11: ww -= 1; hh -= 1; break; case PS: zz = 1; break; case MACOSX: break; case GWIN32: break; } if (!opts->orientation) { gbox[0] = pbox[0] = 0; gbox[1] = pbox[1] = zz; gbox[2] = pbox[2] = ww; gbox[3] = pbox[3] = hh; } else { gbox[0] = 0; gbox[1] = zz; gbox[2] = ww; gbox[3] = hh; pbox[0] = zz; pbox[1] = hh; pbox[2] = ww; pbox[3] = 0; } plot = astPlot(frameSet, gbox, pbox, option_); // and now create astGrid astGrid2dPtr = this; renderMode_ = rm; astGrid(plot); astEnd; // now, clean up memory return 1; error: astEnd; return 0; } �����������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor16.C����������������������������������������������������0000644�0001750�0001750�00000023611�11700666264�020552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarrgbtruecolor16.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarRGBTrueColor16CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // ColorbarRGB Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarRGBTrueColor16Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbarrgb", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED,NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarRGBTrueColor16Type = { (char*)"colorbarrgbtruecolor16", // name sizeof(ColorbarBaseOptions), // size ColorbarRGBTrueColor16CreateProc, // configProc colorbarRGBTrueColor16Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarRGBTrueColor16_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarRGBTrueColor16Type); return TCL_OK; } int ColorbarRGBTrueColor16CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarRGBTrueColor16* colorbar = new ColorbarRGBTrueColor16(interp, canvas, item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarRGBTrueColor16 ColorbarRGBTrueColor16::ColorbarRGBTrueColor16(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarRGBTrueColor(i,c,item), TrueColor16(visual) { configSpecs = colorbarRGBTrueColor16Specs; // colorbar configure options } void ColorbarRGBTrueColor16::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); // if we have cross platforms, we need to byte swap unsigned char row[xmap->bytes_per_line]; if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { // red for (int ii=0; ii<width; ii++) { unsigned short r = colorCells[((int)(double(ii)/width*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); memcpy(row+ii*2, &a, 2); } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { unsigned short g = colorCells[((int)(double(ii)/width*colorCount))*3+1]; unsigned short a = 0; a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); memcpy(row+ii*2, &a, 2); } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { unsigned short b = colorCells[((int)(double(ii)/width*colorCount))*3+2]; unsigned short a = 0; a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); memcpy(row+ii*2, &a, 2); } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } else { // red for (int ii=0; ii<width; ii++) { unsigned short r = colorCells[((int)(double(ii)/width*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); unsigned char* rr = (unsigned char*)(&a); *(row+ii*2) = *(rr+1); *(row+ii*2+1) = *(rr); } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { unsigned short g = colorCells[((int)(double(ii)/width*colorCount))*3+1]; unsigned short a = 0; a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); unsigned char* rr = (unsigned char*)(&a); *(row+ii*2) = *(rr+1); *(row+ii*2+1) = *(rr); } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { unsigned short b = colorCells[((int)(double(ii)/width*colorCount))*3+2]; unsigned short a = 0; a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&a); *(row+ii*2) = *(rr+1); *(row+ii*2+1) = *(rr); } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } } void ColorbarRGBTrueColor16::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned short r = colorCells[((int)(double(jj)/height*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); for (int ii=0; ii<(int)(width/3.); ii++) memcpy(data+ii*2, &a, 2); } // green { unsigned short g =colorCells[((int)(double(jj)/height*colorCount))*3+1]; unsigned short a = 0; a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) memcpy(data+ii*2, &a, 2); } // blue { unsigned short b =colorCells[((int)(double(jj)/height*colorCount))*3+2]; unsigned short a = 0; a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); for (int ii=(int)(width*2/3.); ii<width; ii++) memcpy(data+ii*2, &a, 2); } } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned short r = colorCells[((int)(double(jj)/height*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<(int)(width/3.); ii++) { *(data+ii*2) = *(rr+1); *(data+ii*2+1) = *(rr); } } // green { unsigned short g =colorCells[((int)(double(jj)/height*colorCount))*3+1]; unsigned short a = 0; a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { *(data+ii*2) = *(rr+1); *(data+ii*2+1) = *(rr); } } // blue { unsigned short b =colorCells[((int)(double(jj)/height*colorCount))*3+2]; unsigned short a = 0; a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width*2/3.); ii<width; ii++) { *(data+ii*2) = *(rr+1); *(data+ii*2+1) = *(rr); } } } } } �����������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/parser.Y��������������������������������������������������������������������0000644�0001750�0001750�00000011117�12042571351�015456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {ColorbarBase* cb} %lex-param {cbFlexLexer* ll} %parse-param {cbFlexLexer* ll} %{ #define YYDEBUG 1 #include <stdlib.h> #include "colorbarbase.h" #undef yyFlexLexer #define yyFlexLexer cbFlexLexer #include <FlexLexer.h> extern int cblex(void*, cbFlexLexer*); extern void cberror(ColorbarBase*, cbFlexLexer*, const char*); %} %union { #define CBBUFSIZE 1024 float real; int integer; char str[CBBUFSIZE]; void* ptr; } %type <real> numeric %type <integer> yesno %type <integer> pscolorspace %token <integer> INT %token <real> REAL %token <str> STRING %token <ptr> POINTER %token ADJUST_ %token BEGIN_ %token BIAS_ %token BW_ %token CHANNEL_ %token CMYK_ %token COLORMAP_ %token COLORBAR_ %token COLORSPACE_ %token CONTRAST_ %token DEBUG_ %token DELETE_ %token EDIT_ %token END_ %token GET_ %token GRAY_ %token FALSE_ %token FILE_ %token HEIGHT_ %token HIDE_ %token ID_ %token INVERT_ %token ITT_ %token LEVEL_ %token LIST_ %token LOAD_ %token MACOSX_ %token MAP_ %token MOTION_ %token N_ %token NAME_ %token NO_ %token OFF_ %token ON_ %token POSTSCRIPT_ %token PRINT_ %token RESET_ %token RESOLUTION_ %token RGB_ %token SAVE_ %token SHOW_ %token TAG_ %token TRUE_ %token VALUE_ %token VAR_ %token VERSION_ %token WIDTH_ %token WIN32_ %token WINDOW_ %token Y_ %token YES_ %% command : DEBUG_ debug | ADJUST_ numeric numeric {cb->adjustCmd($2,$3);} | COLORBAR_ colorbar | COLORMAP_ colormap | GET_ get | HIDE_ {cb->hideCmd();} | INVERT_ yesno {cb->invertCmd($2 );} | ITT_ itt | LIST_ list | LOAD_ load | MACOSX_ macosx | MAP_ map | POSTSCRIPT_ postscript | RESET_ {cb->resetCmd();} | RGB_ CHANNEL_ STRING {cb->setRGBChannelCmd($3);} | TAG_ tag | SAVE_ save | SHOW_ {cb->showCmd();} | VERSION_ {cb->msg("Colorbar 1.0");} | WIN32_ win32 ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; yesno : INT {$$=($1 ? 1 : 0);} | YES_ {$$=1;} | Y_ {$$=1;} | ON_ {$$=1;} | TRUE_ {$$=1;} | NO_ {$$=0;} | N_ {$$=0;} | OFF_ {$$=0;} | FALSE_ {$$=0;} ; colorbar: INT numeric numeric INT {cb->setColorbarCmd($1, $2, $3, $4);} | RGB_ numeric numeric numeric numeric numeric numeric INT {cb->setColorbarCmd($2, $3, $4, $5, $6, $7, $8);} ; colormap: LEVEL_ colormaplevel | WINDOW_ STRING {cb->setColormapWindowCmd($2);} ; colormaplevel : /* empty */ {cb->setColormapLevelCmd();} | INT POINTER {cb->setColormapLevelCmd($1, (double*)$2);} ; get : BIAS_ {cb->getBiasCmd();} | COLORBAR_ {cb->getColorbarCmd();} | COLORMAP_ {cb->getColormapCmd();} | CONTRAST_ {cb->getContrastCmd();} | FILE_ NAME_ {cb->getCurrentFileNameCmd();} | FILE_ NAME_ INT {cb->getColormapFileNameCmd($3);} | HEIGHT_ {cb->getHeightCmd();} | ID_ {cb->getCurrentIDCmd();} | INVERT_ {cb->getInvertCmd();} | NAME_ {cb->getCurrentNameCmd();} | NAME_ INT {cb->getColormapNameCmd($2);} | RGB_ CHANNEL_ {cb->getRGBChannelCmd();} | VALUE_ INT INT {cb->getValueCmd($2,$3);} | TAG_ getTag | WIDTH_ {cb->getWidthCmd();} ; getTag : /* empty */ {cb->getTagCmd();} | INT INT {cb->getTagCmd($1,$2);} ; itt : STRING {} | INT {} ; list : /* empty */ {cb->listNameCmd();} | ID_ {cb->listIDCmd();} | NAME_ {cb->listNameCmd();} | ITT_ {} | ITT_ ID_ {} | ITT_ NAME_ {} ; load : STRING {cb->loadCmd($1,NULL);} | STRING STRING {cb->loadCmd($1,$2);} | VAR_ loadVar | ITT_ STRING {} ; loadVar : STRING STRING {cb->loadCmd($1,NULL,$2);} | STRING STRING STRING {cb->loadCmd($1,$2,$3);} ; macosx : PRINT_ { #ifdef _MACOSX cb->macosxPrintCmd(); #endif } ; map : STRING {cb->mapCmd($1);} | INT {cb->mapCmd($1);} ; postscript : COLORSPACE_ pscolorspace {cb->psColorSpaceCmd((Widget::PSColorSpace)$2);} | LEVEL_ INT {cb->psLevelCmd($2);} | RESOLUTION_ INT {cb->psResolutionCmd($2);} ; pscolorspace : BW_ {$$ = Widget::BW;} | GRAY_ {$$ = Widget::GRAY;} | RGB_ {$$ = Widget::RGB;} | CMYK_ {$$ = Widget::CMYK;} ; tag : DELETE_ tagdelete | EDIT_ tagedit | LOAD_ STRING {cb->tagLoadCmd($2);} | SAVE_ STRING {cb->tagSaveCmd($2);} | INT numeric numeric STRING {cb->tagCmd($1,Vector($2,$3),$4);} | STRING {cb->tagCmd($1);} ; tagdelete: /* empty */ {cb->tagDeleteCmd();} | INT INT {cb->tagDeleteCmd($1,$2);} ; tagedit : BEGIN_ INT INT STRING {cb->tagEditBeginCmd($2,$3,$4);} | MOTION_ INT INT {cb->tagEditMotionCmd($2,$3);} | END_ INT INT {cb->tagEditEndCmd($2,$3);} ; save : STRING {cb->saveCmd($1);} | INT STRING {cb->saveCmd($1,$2);} ; win32 : PRINT_ { #ifdef _WIN32 cb->win32PrintCmd(); #endif } ; %% �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor8.C��������������������������������������������������������0000644�0001750�0001750�00000013661�11700666264�020004� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbartruecolor8.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarTrueColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Colorbar Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarTrueColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbar", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarTrueColor8Type = { (char*)"colorbartruecolor8", // name sizeof(ColorbarBaseOptions), // size ColorbarTrueColor8CreateProc, // configProc colorbarTrueColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarTrueColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarTrueColor8Type); return TCL_OK; } int ColorbarTrueColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarTrueColor8* colorbar = new ColorbarTrueColor8(interp, canvas, item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarTrueColor8 ColorbarTrueColor8::ColorbarTrueColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarTrueColor(i,c,item), TrueColor8(visual) { configSpecs = colorbarTrueColor8Specs; // colorbar configure options loadDefaultCMaps(); } void ColorbarTrueColor8::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); for (int ii=0; ii<width; ii++) data[ii] = ((colorCells[((int)(double(ii)/width*colorCount))*3] & bm_) >> bs_) | ((colorCells[((int)(double(ii)/width*colorCount))*3+1] & gm_) >> gs_) | ((colorCells[((int)(double(ii)/width*colorCount))*3+2] & rm_) >> rs_); // --and duplicate for remaining rows for (int jj=1; jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line); } void ColorbarTrueColor8::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { char a = ((colorCells[((int)(double(jj)/height*colorCount))*3] & bm_) >> bs_) | ((colorCells[((int)(double(jj)/height*colorCount))*3+1] & gm_) >> gs_) | ((colorCells[((int)(double(jj)/height*colorCount))*3+2] & rm_) >> rs_); for (int ii=0; ii<width; ii++) data[ii] = a; } } �������������������������������������������������������������������������������./saods9/saotk/colorbar/lutlex.L��������������������������������������������������������������������0000644�0001750�0001750�00000003475�11714557444�015506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ %option noyywrap %option caseless %option never-interactive %option c++ %{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "lutparser.H" extern YYSTYPE* rgblval; extern rgbFlexLexer* rgblexx; %} %x DISCARD D [0-9] E [Ee][+-]?{D}+ /* rules */ %% <DISCARD>[\n] { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(rgblval->str,""); // feed a blank string return STRING; } <DISCARD>[^\n]* { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(LUTBUFSIZE-1) ? yyleng:(LUTBUFSIZE-1); strncpy(rgblval->str,yytext,ll); rgblval->str[ll] = '\0'; return STRING; } debug {return DEBUG_;} false {return FALSE_;} no {return NO_;} off {return OFF_;} on {return ON_;} true {return TRUE_;} yes {return YES_;} [+-]?{D}+ { // Integer rgblval->integer = atoi(yytext); return INT; } [+-]?{D}+"."?({E})? | [+-]?{D}*"."{D}+({E})? { // Real Number rgblval->real = atof(yytext); return REAL; } [0-9A-Za-z]+ { // General String int ll = yyleng <(LUTBUFSIZE-1) ? yyleng:(LUTBUFSIZE-1); strncpy(rgblval->str,yytext,ll); rgblval->str[ll] = '\0'; return STRING; } [ \t]+ { // White Spaces } \r\n { // windows line feed return '\n'; } \n { // linefeed return '\n'; } <<EOF>> { // eof return EOF_; } . { // Else, return the char return toupper(yytext[0]); } %% void rgbDiscard(int doit) { if (rgblexx) rgblexx->begin(DISCARD, doit); } void rgbFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lutparser.Y�����������������������������������������������������������������0000644�0001750�0001750�00000002277�12042570565�016220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" %pure-parser %parse-param {LUTColorMap* cm} %lex-param {rgbFlexLexer* ll} %parse-param {rgbFlexLexer* ll} %{ #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; rgbDiscard(x);} #include <string.h> #include <iostream> #include "lut.h" #undef yyFlexLexer #define yyFlexLexer rgbFlexLexer #include <FlexLexer.h> extern int rgblex(void*, rgbFlexLexer*); extern void rgberror(LUTColorMap*, rgbFlexLexer*, const char*); extern void rgbDiscard(int); %} %union { #define LUTBUFSIZE 4096 char str[LUTBUFSIZE]; int integer; float real; } %type <real> numeric %token <real> REAL %token <integer> INT %token <str> STRING %token EOF_ %token DEBUG_ %token FALSE_ %token NO_ %token OFF_ %token ON_ %token TRUE_ %token YES_ %% commands: commands command terminator | command terminator ; command : DEBUG_ debug | numeric numeric numeric {cm->newRGBColor($1,$2,$3);} | '#' {DISCARD_(1)} STRING ; terminator: '\n' | ';' | EOF_ {YYACCEPT;} ; numeric : REAL {$$=$1;} | INT {$$=$1;} ; debug : ON_ {yydebug=1;} | OFF_ {yydebug=0;} ; %% ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartrue.h��������������������������������������������������������������0000644�0001750�0001750�00000001057�11700666264�016716� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbartrue_h__ #define __colorbartrue_h__ #include "colorbar.h" class ColorbarTrue : public virtual ColorbarBase { protected: void updateColors(); virtual void updateColorCells() =0; virtual void updateColorsHorz() =0; virtual void updateColorsVert() =0; void ximageToPixmap() {updateColors();} public: ColorbarTrue(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor8.C�����������������������������������������������������0000644�0001750�0001750�00000015255�11700666264�020500� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarrgbtruecolor8.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarRGBTrueColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Colorbar Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarRGBTrueColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbarrgb", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarRGBTrueColor8Type = { (char*)"colorbarrgbtruecolor8", // name sizeof(ColorbarBaseOptions), // size ColorbarRGBTrueColor8CreateProc, // configProc colorbarRGBTrueColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarRGBTrueColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarRGBTrueColor8Type); return TCL_OK; } int ColorbarRGBTrueColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarRGBTrueColor8* colorbar = new ColorbarRGBTrueColor8(interp, canvas, item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarRGBTrueColor8 ColorbarRGBTrueColor8::ColorbarRGBTrueColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarRGBTrueColor(i,c,item), TrueColor8(visual) { configSpecs = colorbarRGBTrueColor8Specs; // colorbar configure options } void ColorbarRGBTrueColor8::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); unsigned char row[xmap->bytes_per_line]; // red for (int ii=0; ii<width; ii++) { char r = colorCells[((int)(double(ii)/width*colorCount))*3]; row[ii] = (r & rm_) >> rs_; } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { char g = colorCells[((int)(double(ii)/width*colorCount))*3+1]; row[ii] = (g & gm_) >> gs_; } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { char b =colorCells[((int)(double(ii)/width*colorCount))*3+2]; row[ii] = (b & bm_) >> bs_; } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } void ColorbarRGBTrueColor8::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { char r = colorCells[((int)(double(jj)/height*colorCount))*3]; char a = (r & rm_) >> rs_; for (int ii=0; ii<(int)(width/3.); ii++) data[ii] = a; } // green { char g = colorCells[((int)(double(jj)/height*colorCount))*3+1]; char a = (g & gm_) >> gs_; for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) data[ii] = a; } // blue { char b =colorCells[((int)(double(jj)/height*colorCount))*3+2]; char a = (b & bm_) >> bs_; for (int ii=(int)(width*2/3.); ii<width; ii++) data[ii] = a; } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor.h���������������������������������������������������������0000644�0001750�0001750�00000001016�11700666264�017750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbartruecolor_h__ #define __colorbartruecolor_h__ #include "colorbar.h" #include "colorbartrue.h" class ColorbarTrueColor : public virtual ColorbarBase, public Colorbar, public ColorbarTrue { private: int initColormap(); protected: void updateColorCells(); public: ColorbarTrueColor(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/parser.C��������������������������������������������������������������������0000644�0001750�0001750�00000167360�12042571351�015444� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse cbparse #define yylex cblex #define yyerror cberror #define yylval cblval #define yychar cbchar #define yydebug cbdebug #define yynerrs cbnerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { INT = 258, REAL = 259, STRING = 260, POINTER = 261, ADJUST_ = 262, BEGIN_ = 263, BIAS_ = 264, BW_ = 265, CHANNEL_ = 266, CMYK_ = 267, COLORMAP_ = 268, COLORBAR_ = 269, COLORSPACE_ = 270, CONTRAST_ = 271, DEBUG_ = 272, DELETE_ = 273, EDIT_ = 274, END_ = 275, GET_ = 276, GRAY_ = 277, FALSE_ = 278, FILE_ = 279, HEIGHT_ = 280, HIDE_ = 281, ID_ = 282, INVERT_ = 283, ITT_ = 284, LEVEL_ = 285, LIST_ = 286, LOAD_ = 287, MACOSX_ = 288, MAP_ = 289, MOTION_ = 290, N_ = 291, NAME_ = 292, NO_ = 293, OFF_ = 294, ON_ = 295, POSTSCRIPT_ = 296, PRINT_ = 297, RESET_ = 298, RESOLUTION_ = 299, RGB_ = 300, SAVE_ = 301, SHOW_ = 302, TAG_ = 303, TRUE_ = 304, VALUE_ = 305, VAR_ = 306, VERSION_ = 307, WIDTH_ = 308, WIN32_ = 309, WINDOW_ = 310, Y_ = 311, YES_ = 312 }; #endif /* Tokens. */ #define INT 258 #define REAL 259 #define STRING 260 #define POINTER 261 #define ADJUST_ 262 #define BEGIN_ 263 #define BIAS_ 264 #define BW_ 265 #define CHANNEL_ 266 #define CMYK_ 267 #define COLORMAP_ 268 #define COLORBAR_ 269 #define COLORSPACE_ 270 #define CONTRAST_ 271 #define DEBUG_ 272 #define DELETE_ 273 #define EDIT_ 274 #define END_ 275 #define GET_ 276 #define GRAY_ 277 #define FALSE_ 278 #define FILE_ 279 #define HEIGHT_ 280 #define HIDE_ 281 #define ID_ 282 #define INVERT_ 283 #define ITT_ 284 #define LEVEL_ 285 #define LIST_ 286 #define LOAD_ 287 #define MACOSX_ 288 #define MAP_ 289 #define MOTION_ 290 #define N_ 291 #define NAME_ 292 #define NO_ 293 #define OFF_ 294 #define ON_ 295 #define POSTSCRIPT_ 296 #define PRINT_ 297 #define RESET_ 298 #define RESOLUTION_ 299 #define RGB_ 300 #define SAVE_ 301 #define SHOW_ 302 #define TAG_ 303 #define TRUE_ 304 #define VALUE_ 305 #define VAR_ 306 #define VERSION_ 307 #define WIDTH_ 308 #define WIN32_ 309 #define WINDOW_ 310 #define Y_ 311 #define YES_ 312 /* Copy the first part of user declarations. */ #line 10 "parser.Y" #define YYDEBUG 1 #include <stdlib.h> #include "colorbarbase.h" #undef yyFlexLexer #define yyFlexLexer cbFlexLexer #include <FlexLexer.h> extern int cblex(void*, cbFlexLexer*); extern void cberror(ColorbarBase*, cbFlexLexer*, const char*); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 25 "parser.Y" { #define CBBUFSIZE 1024 float real; int integer; char str[CBBUFSIZE]; void* ptr; } /* Line 193 of yacc.c. */ #line 241 "parser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 254 "parser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 91 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 136 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 58 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 23 /* YYNRULES -- Number of rules. */ #define YYNRULES 95 /* YYNRULES -- Number of states. */ #define YYNSTATES 152 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 312 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 6, 10, 13, 16, 19, 21, 24, 27, 30, 33, 36, 39, 42, 44, 48, 51, 54, 56, 58, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 92, 101, 104, 107, 108, 111, 113, 115, 117, 119, 122, 126, 128, 130, 132, 134, 137, 140, 144, 147, 149, 150, 153, 155, 157, 158, 160, 162, 164, 167, 170, 172, 175, 178, 181, 184, 188, 190, 192, 194, 197, 200, 203, 205, 207, 209, 211, 214, 217, 220, 223, 228, 230, 231, 234, 239, 243, 247, 249, 252 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 59, 0, -1, 17, 61, -1, 7, 60, 60, -1, 14, 63, -1, 13, 64, -1, 21, 66, -1, 26, -1, 28, 62, -1, 29, 68, -1, 31, 69, -1, 32, 70, -1, 33, 72, -1, 34, 73, -1, 41, 74, -1, 43, -1, 45, 11, 5, -1, 48, 76, -1, 46, 79, -1, 47, -1, 52, -1, 54, 80, -1, 4, -1, 3, -1, 40, -1, 39, -1, 3, -1, 57, -1, 56, -1, 40, -1, 49, -1, 38, -1, 36, -1, 39, -1, 23, -1, 3, 60, 60, 3, -1, 45, 60, 60, 60, 60, 60, 60, 3, -1, 30, 65, -1, 55, 5, -1, -1, 3, 6, -1, 9, -1, 14, -1, 13, -1, 16, -1, 24, 37, -1, 24, 37, 3, -1, 25, -1, 27, -1, 28, -1, 37, -1, 37, 3, -1, 45, 11, -1, 50, 3, 3, -1, 48, 67, -1, 53, -1, -1, 3, 3, -1, 5, -1, 3, -1, -1, 27, -1, 37, -1, 29, -1, 29, 27, -1, 29, 37, -1, 5, -1, 5, 5, -1, 51, 71, -1, 29, 5, -1, 5, 5, -1, 5, 5, 5, -1, 42, -1, 5, -1, 3, -1, 15, 75, -1, 30, 3, -1, 44, 3, -1, 10, -1, 22, -1, 45, -1, 12, -1, 18, 77, -1, 19, 78, -1, 32, 5, -1, 46, 5, -1, 3, 60, 60, 5, -1, 5, -1, -1, 3, 3, -1, 8, 3, 3, 5, -1, 35, 3, 3, -1, 20, 3, 3, -1, 5, -1, 3, 5, -1, 42, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 96, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 122, 123, 126, 128, 129, 130, 131, 133, 134, 135, 136, 139, 140, 144, 145, 148, 149, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 169, 170, 173, 174, 177, 178, 179, 180, 181, 182, 185, 186, 187, 188, 191, 192, 195, 202, 203, 206, 208, 209, 212, 213, 214, 215, 218, 219, 220, 221, 222, 223, 226, 227, 230, 231, 232, 235, 236, 239 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "INT", "REAL", "STRING", "POINTER", "ADJUST_", "BEGIN_", "BIAS_", "BW_", "CHANNEL_", "CMYK_", "COLORMAP_", "COLORBAR_", "COLORSPACE_", "CONTRAST_", "DEBUG_", "DELETE_", "EDIT_", "END_", "GET_", "GRAY_", "FALSE_", "FILE_", "HEIGHT_", "HIDE_", "ID_", "INVERT_", "ITT_", "LEVEL_", "LIST_", "LOAD_", "MACOSX_", "MAP_", "MOTION_", "N_", "NAME_", "NO_", "OFF_", "ON_", "POSTSCRIPT_", "PRINT_", "RESET_", "RESOLUTION_", "RGB_", "SAVE_", "SHOW_", "TAG_", "TRUE_", "VALUE_", "VAR_", "VERSION_", "WIDTH_", "WIN32_", "WINDOW_", "Y_", "YES_", "$accept", "command", "numeric", "debug", "yesno", "colorbar", "colormap", "colormaplevel", "get", "getTag", "itt", "list", "load", "loadVar", "macosx", "map", "postscript", "pscolorspace", "tag", "tagdelete", "tagedit", "save", "win32", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 68, 68, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 72, 73, 73, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 77, 77, 78, 78, 78, 79, 79, 80 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 3, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 8, 2, 2, 0, 2, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 2, 2, 3, 2, 1, 0, 2, 1, 1, 0, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 4, 1, 0, 2, 4, 3, 3, 1, 2, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 0, 0, 7, 0, 0, 60, 0, 0, 0, 0, 15, 0, 0, 19, 0, 20, 0, 0, 23, 22, 0, 39, 0, 5, 0, 0, 4, 25, 24, 2, 41, 43, 42, 44, 0, 47, 48, 49, 50, 0, 56, 0, 55, 6, 26, 34, 32, 31, 33, 29, 30, 28, 27, 8, 59, 58, 9, 61, 63, 62, 10, 66, 0, 0, 11, 72, 12, 74, 73, 13, 0, 0, 0, 14, 0, 0, 93, 18, 0, 87, 88, 0, 0, 0, 17, 95, 21, 1, 3, 0, 37, 38, 0, 0, 45, 51, 52, 0, 54, 0, 64, 65, 67, 69, 0, 68, 78, 81, 79, 80, 75, 76, 77, 16, 94, 0, 0, 82, 0, 0, 0, 83, 84, 85, 40, 0, 0, 46, 57, 53, 70, 0, 89, 0, 0, 0, 35, 0, 71, 86, 0, 92, 91, 0, 90, 0, 0, 36 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 21, 24, 33, 57, 30, 27, 94, 47, 102, 60, 64, 68, 109, 70, 73, 77, 114, 88, 121, 125, 81, 90 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -28 static const yytype_int8 yypact[] = { 35, 29, -27, -1, 6, 83, -28, -2, 10, -18, 2, -25, 21, -5, -28, 9, 57, -28, 11, -28, 17, 27, -28, -28, 29, 37, 46, -28, 29, 29, -28, -28, -28, -28, -28, -28, -28, -28, 28, -28, -28, -28, 67, 60, 71, 72, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -15, -28, -28, 74, 79, 80, -28, -28, -28, -28, -28, -28, -4, 85, 87, -28, 81, 86, -28, -28, 29, -28, 90, 15, 89, 93, -28, -28, -28, -28, -28, 94, -28, -28, 29, 29, 98, -28, -28, 99, -28, 100, -28, -28, -28, -28, 104, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, 29, 101, -28, 102, 109, 110, -28, -28, -28, -28, 111, 29, -28, -28, -28, 113, 114, -28, 112, 118, 119, -28, 29, -28, -28, 121, -28, -28, 29, -28, 29, 124, -28 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -28, -28, -24, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 92, 48, 28, 25, 96, 97, 110, 65, 111, 61, 74, 62, 104, 58, 82, 59, 83, 69, 112, 63, 78, 49, 105, 122, 71, 75, 72, 91, 26, 84, 85, 66, 22, 23, 50, 123, 51, 52, 53, 76, 93, 113, 1, 86, 29, 31, 32, 54, 2, 3, 124, 95, 4, 67, 55, 56, 5, 87, 119, 89, 79, 6, 80, 7, 8, 98, 9, 10, 11, 12, 99, 100, 129, 130, 101, 103, 13, 0, 14, 106, 15, 16, 17, 18, 107, 108, 117, 19, 115, 20, 116, 118, 34, 120, 126, 135, 35, 36, 127, 37, 128, 131, 132, 133, 136, 137, 141, 38, 39, 134, 40, 41, 138, 139, 140, 144, 0, 147, 142, 143, 42, 145, 146, 149, 0, 150, 148, 151, 43, 0, 0, 44, 0, 45, 0, 0, 46 }; static const yytype_int16 yycheck[] = { 24, 3, 3, 30, 28, 29, 10, 5, 12, 27, 15, 29, 27, 3, 3, 5, 5, 42, 22, 37, 11, 23, 37, 8, 3, 30, 5, 0, 55, 18, 19, 29, 3, 4, 36, 20, 38, 39, 40, 44, 3, 45, 7, 32, 45, 39, 40, 49, 13, 14, 35, 5, 17, 51, 56, 57, 21, 46, 82, 42, 3, 26, 5, 28, 29, 37, 31, 32, 33, 34, 3, 11, 96, 97, 3, 3, 41, -1, 43, 5, 45, 46, 47, 48, 5, 5, 5, 52, 3, 54, 3, 5, 9, 3, 5, 119, 13, 14, 5, 16, 6, 3, 3, 3, 3, 3, 130, 24, 25, 5, 27, 28, 3, 3, 3, 3, -1, 141, 5, 5, 37, 3, 3, 147, -1, 149, 5, 3, 45, -1, -1, 48, -1, 50, -1, -1, 53 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 7, 13, 14, 17, 21, 26, 28, 29, 31, 32, 33, 34, 41, 43, 45, 46, 47, 48, 52, 54, 59, 3, 4, 60, 30, 55, 64, 3, 45, 63, 39, 40, 61, 9, 13, 14, 16, 24, 25, 27, 28, 37, 45, 48, 50, 53, 66, 3, 23, 36, 38, 39, 40, 49, 56, 57, 62, 3, 5, 68, 27, 29, 37, 69, 5, 29, 51, 70, 42, 72, 3, 5, 73, 15, 30, 44, 74, 11, 3, 5, 79, 3, 5, 18, 19, 32, 46, 76, 42, 80, 0, 60, 3, 65, 5, 60, 60, 37, 3, 11, 3, 67, 3, 27, 37, 5, 5, 5, 71, 10, 12, 22, 45, 75, 3, 3, 5, 5, 60, 3, 77, 8, 20, 35, 78, 5, 5, 6, 60, 60, 3, 3, 3, 5, 60, 3, 3, 3, 3, 3, 60, 5, 5, 3, 3, 3, 60, 5, 60, 60, 3 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (cb, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, cb, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ColorbarBase* cb, cbFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, cb, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; ColorbarBase* cb; cbFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (cb); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, ColorbarBase* cb, cbFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, cb, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; ColorbarBase* cb; cbFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, cb, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, ColorbarBase* cb, cbFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, cb, ll) YYSTYPE *yyvsp; int yyrule; ColorbarBase* cb; cbFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , cb, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, cb, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, ColorbarBase* cb, cbFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, cb, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; ColorbarBase* cb; cbFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (cb); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (ColorbarBase* cb, cbFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (ColorbarBase* cb, cbFlexLexer* ll) #else int yyparse (cb, ll) ColorbarBase* cb; cbFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: #line 97 "parser.Y" {cb->adjustCmd((yyvsp[(2) - (3)].real),(yyvsp[(3) - (3)].real));;} break; case 7: #line 101 "parser.Y" {cb->hideCmd();;} break; case 8: #line 102 "parser.Y" {cb->invertCmd((yyvsp[(2) - (2)].integer) );;} break; case 15: #line 109 "parser.Y" {cb->resetCmd();;} break; case 16: #line 110 "parser.Y" {cb->setRGBChannelCmd((yyvsp[(3) - (3)].str));;} break; case 19: #line 113 "parser.Y" {cb->showCmd();;} break; case 20: #line 114 "parser.Y" {cb->msg("Colorbar 1.0");;} break; case 22: #line 118 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 23: #line 119 "parser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 24: #line 122 "parser.Y" {yydebug=1;;} break; case 25: #line 123 "parser.Y" {yydebug=0;;} break; case 26: #line 126 "parser.Y" {(yyval.integer)=((yyvsp[(1) - (1)].integer) ? 1 : 0);;} break; case 27: #line 128 "parser.Y" {(yyval.integer)=1;;} break; case 28: #line 129 "parser.Y" {(yyval.integer)=1;;} break; case 29: #line 130 "parser.Y" {(yyval.integer)=1;;} break; case 30: #line 131 "parser.Y" {(yyval.integer)=1;;} break; case 31: #line 133 "parser.Y" {(yyval.integer)=0;;} break; case 32: #line 134 "parser.Y" {(yyval.integer)=0;;} break; case 33: #line 135 "parser.Y" {(yyval.integer)=0;;} break; case 34: #line 136 "parser.Y" {(yyval.integer)=0;;} break; case 35: #line 139 "parser.Y" {cb->setColorbarCmd((yyvsp[(1) - (4)].integer), (yyvsp[(2) - (4)].real), (yyvsp[(3) - (4)].real), (yyvsp[(4) - (4)].integer));;} break; case 36: #line 141 "parser.Y" {cb->setColorbarCmd((yyvsp[(2) - (8)].real), (yyvsp[(3) - (8)].real), (yyvsp[(4) - (8)].real), (yyvsp[(5) - (8)].real), (yyvsp[(6) - (8)].real), (yyvsp[(7) - (8)].real), (yyvsp[(8) - (8)].integer));;} break; case 38: #line 145 "parser.Y" {cb->setColormapWindowCmd((yyvsp[(2) - (2)].str));;} break; case 39: #line 148 "parser.Y" {cb->setColormapLevelCmd();;} break; case 40: #line 149 "parser.Y" {cb->setColormapLevelCmd((yyvsp[(1) - (2)].integer), (double*)(yyvsp[(2) - (2)].ptr));;} break; case 41: #line 152 "parser.Y" {cb->getBiasCmd();;} break; case 42: #line 153 "parser.Y" {cb->getColorbarCmd();;} break; case 43: #line 154 "parser.Y" {cb->getColormapCmd();;} break; case 44: #line 155 "parser.Y" {cb->getContrastCmd();;} break; case 45: #line 156 "parser.Y" {cb->getCurrentFileNameCmd();;} break; case 46: #line 157 "parser.Y" {cb->getColormapFileNameCmd((yyvsp[(3) - (3)].integer));;} break; case 47: #line 158 "parser.Y" {cb->getHeightCmd();;} break; case 48: #line 159 "parser.Y" {cb->getCurrentIDCmd();;} break; case 49: #line 160 "parser.Y" {cb->getInvertCmd();;} break; case 50: #line 161 "parser.Y" {cb->getCurrentNameCmd();;} break; case 51: #line 162 "parser.Y" {cb->getColormapNameCmd((yyvsp[(2) - (2)].integer));;} break; case 52: #line 163 "parser.Y" {cb->getRGBChannelCmd();;} break; case 53: #line 164 "parser.Y" {cb->getValueCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 55: #line 166 "parser.Y" {cb->getWidthCmd();;} break; case 56: #line 169 "parser.Y" {cb->getTagCmd();;} break; case 57: #line 170 "parser.Y" {cb->getTagCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 58: #line 173 "parser.Y" {;} break; case 59: #line 174 "parser.Y" {;} break; case 60: #line 177 "parser.Y" {cb->listNameCmd();;} break; case 61: #line 178 "parser.Y" {cb->listIDCmd();;} break; case 62: #line 179 "parser.Y" {cb->listNameCmd();;} break; case 63: #line 180 "parser.Y" {;} break; case 64: #line 181 "parser.Y" {;} break; case 65: #line 182 "parser.Y" {;} break; case 66: #line 185 "parser.Y" {cb->loadCmd((yyvsp[(1) - (1)].str),NULL);;} break; case 67: #line 186 "parser.Y" {cb->loadCmd((yyvsp[(1) - (2)].str),(yyvsp[(2) - (2)].str));;} break; case 69: #line 188 "parser.Y" {;} break; case 70: #line 191 "parser.Y" {cb->loadCmd((yyvsp[(1) - (2)].str),NULL,(yyvsp[(2) - (2)].str));;} break; case 71: #line 192 "parser.Y" {cb->loadCmd((yyvsp[(1) - (3)].str),(yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].str));;} break; case 72: #line 195 "parser.Y" { #ifdef _MACOSX cb->macosxPrintCmd(); #endif ;} break; case 73: #line 202 "parser.Y" {cb->mapCmd((yyvsp[(1) - (1)].str));;} break; case 74: #line 203 "parser.Y" {cb->mapCmd((yyvsp[(1) - (1)].integer));;} break; case 75: #line 207 "parser.Y" {cb->psColorSpaceCmd((Widget::PSColorSpace)(yyvsp[(2) - (2)].integer));;} break; case 76: #line 208 "parser.Y" {cb->psLevelCmd((yyvsp[(2) - (2)].integer));;} break; case 77: #line 209 "parser.Y" {cb->psResolutionCmd((yyvsp[(2) - (2)].integer));;} break; case 78: #line 212 "parser.Y" {(yyval.integer) = Widget::BW;;} break; case 79: #line 213 "parser.Y" {(yyval.integer) = Widget::GRAY;;} break; case 80: #line 214 "parser.Y" {(yyval.integer) = Widget::RGB;;} break; case 81: #line 215 "parser.Y" {(yyval.integer) = Widget::CMYK;;} break; case 84: #line 220 "parser.Y" {cb->tagLoadCmd((yyvsp[(2) - (2)].str));;} break; case 85: #line 221 "parser.Y" {cb->tagSaveCmd((yyvsp[(2) - (2)].str));;} break; case 86: #line 222 "parser.Y" {cb->tagCmd((yyvsp[(1) - (4)].integer),Vector((yyvsp[(2) - (4)].real),(yyvsp[(3) - (4)].real)),(yyvsp[(4) - (4)].str));;} break; case 87: #line 223 "parser.Y" {cb->tagCmd((yyvsp[(1) - (1)].str));;} break; case 88: #line 226 "parser.Y" {cb->tagDeleteCmd();;} break; case 89: #line 227 "parser.Y" {cb->tagDeleteCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].integer));;} break; case 90: #line 230 "parser.Y" {cb->tagEditBeginCmd((yyvsp[(2) - (4)].integer),(yyvsp[(3) - (4)].integer),(yyvsp[(4) - (4)].str));;} break; case 91: #line 231 "parser.Y" {cb->tagEditMotionCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 92: #line 232 "parser.Y" {cb->tagEditEndCmd((yyvsp[(2) - (3)].integer),(yyvsp[(3) - (3)].integer));;} break; case 93: #line 235 "parser.Y" {cb->saveCmd((yyvsp[(1) - (1)].str));;} break; case 94: #line 236 "parser.Y" {cb->saveCmd((yyvsp[(1) - (2)].integer),(yyvsp[(2) - (2)].str));;} break; case 95: #line 239 "parser.Y" { #ifdef _WIN32 cb->win32PrintCmd(); #endif ;} break; /* Line 1267 of yacc.c. */ #line 1991 "parser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (cb, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (cb, ll, yymsg); } else { yyerror (cb, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, cb, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, cb, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (cb, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, cb, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, cb, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 246 "parser.Y" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor24.h�������������������������������������������������������0000644�0001750�0001750�00000001255�11700666264�020123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbartruecolor24_h__ #define __colorbartruecolor24_h__ #include "colorbartruecolor.h" #include "truecolor24.h" class ColorbarTrueColor24 : public ColorbarTrueColor, public TrueColor24 { private: void updateColorsHorz(); void updateColorsVert(); void updateColors24Horz(int, int, char*); void updateColors24Vert(int, int, char*); void updateColors32Horz(int, int, char*); void updateColors32Vert(int, int, char*); public: ColorbarTrueColor24(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarbase.C��������������������������������������������������������������0000644�0001750�0001750�00000056460�12042560016�016600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarbase.h" #include "util.h" #include "tkpostscript.h" #include "cbgrid.h" #include "ps.h" #define TICKLEN 3 #define TICKGAP 7 // Parser Stuff #undef yyFlexLexer #define yyFlexLexer cbFlexLexer #include <FlexLexer.h> void* cblval; extern int cbparse(ColorbarBase*, cbFlexLexer*); int cblex(void* vval, cbFlexLexer* ll) { cblval = vval; return ll ? ll->yylex() : 0; } void cberror(ColorbarBase* cb, cbFlexLexer* ll, const char* m) { cb->error(m); const char* cmd = ll ? ll->YYText() : (const char*)NULL; if (cmd && cmd[0] != '\n') { cb->error(": "); cb->error(cmd); } } // Public Member Functions ColorbarBase::ColorbarBase(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Widget(i,c,item) { // this is needed because of a problem with Tk_ConfigureWidget ((ColorbarBaseOptions*)options)->font = NULL; ((ColorbarBaseOptions*)options)->fontWeight = NULL; ((ColorbarBaseOptions*)options)->fontSlant = NULL; xmap = NULL; colorCells = NULL; colorCount = 0; grid = NULL; gc = NULL; cnt = 0; lut = NULL; invert = 0; ticktxt = NULL; tickcnt =0; skipcnt =0; } ColorbarBase::~ColorbarBase() { if (xmap) XDestroyImage(xmap); if (colorCells) delete [] colorCells; if (grid) delete grid; if (gc) XFreeGC(display, gc); if (lut) delete [] lut; if (ticktxt) { for (int ii=0; ii<tickcnt; ii++) if (ticktxt[ii]) delete [] ticktxt[ii]; delete [] ticktxt; } } int ColorbarBase::configure(int argc, const char* argv[], int flags) { if (Widget::configure(argc, argv, flags) == TCL_ERROR) return TCL_ERROR; // only valid for the initial configuration call if (flags != TK_CONFIG_ARGV_ONLY) return initColormap(); else { if ((configSpecs[CONFIGORIENTATION].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGNUMERICS].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGSIZE].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGFONT].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGFONTSTYLE].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGFONTSIZE].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGSPACE].specFlags & TK_CONFIG_OPTION_SPECIFIED) || (configSpecs[CONFIGTICKS].specFlags & TK_CONFIG_OPTION_SPECIFIED)) { updateBBox(); invalidPixmap(); redraw(); } } return TCL_OK; } void ColorbarBase::getInvertCmd() { if (invert) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); } void ColorbarBase::getValueCmd(int x, int y) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (lut && cnt) { int id =0; ostringstream str; if (!opts->orientation) { // horizontal id = (int)(x/float(options->width) * cnt); } else { // vertical id = (int)((options->height -y)/float(options->height) * cnt); } if (id<0) id = 0; if (id>=cnt) id = cnt-1; str << lut[id] << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } else Tcl_AppendResult(interp, NULL); } void ColorbarBase::invalidPixmap() { Widget::invalidPixmap(); if (xmap) XDestroyImage(xmap); xmap = NULL; } void ColorbarBase::invertCmd(int ii) { invert = ii ? 1 : 0; updateColors(); } int ColorbarBase::parse(istringstream& istr) { result = TCL_OK; cbFlexLexer* ll = new cbFlexLexer(&istr); cbparse(this, ll); delete ll; return result; } Tk_Font ColorbarBase::getFont() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; ostringstream fstr; if (!strncmp(opts->font,"helvetica",4)) fstr << '{' << opts->helvetica << '}' << ' ' << opts->fontSize << ' ' << opts->fontWeight << ' ' << opts->fontSlant << ends; else if (!strncmp(opts->font,"courier",4)) fstr << '{' << opts->courier << '}' << ' ' << opts->fontSize << ' ' << opts->fontWeight << ' ' << opts->fontSlant << ends; else if (!strncmp(opts->font,"times",4)) fstr << '{' << opts->times << '}' << ' ' << opts->fontSize << ' ' << opts->fontWeight << ' ' << opts->fontSlant << ends; else fstr << '{' << opts->helvetica << '}' << ' ' << opts->fontSize << ' ' << opts->fontWeight << ' ' << opts->fontSlant << ends; return Tk_GetFont(interp, tkwin, fstr.str().c_str()); } void ColorbarBase::lutToText(Tk_Font font) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; // init if (ticktxt) for (int ii=0; ii<tickcnt; ii++) delete [] ticktxt[ii]; delete [] ticktxt; tickcnt = opts->ticks; ticktxt = new char*[opts->ticks]; for (int ii=0; ii<opts->ticks; ii++) ticktxt[ii] = NULL; skipcnt =0; // first estimate of prec int prec; { int aa = (int)(log10(fabs(lut[0]))); int bb = (int)(log10(fabs(lut[cnt-1]))); if (aa != bb) prec = aa>bb ? aa : bb; else prec = 1; } // up to three tries for (int jj=0; jj<3; jj++) { // render text for (int ii=0; ii<opts->ticks; ii++) { int id = ii/double(opts->ticks-1)*cnt; // the last one will be one over if (id>=cnt) id = cnt-1; ostringstream str; if (prec < -2) str << scientific << setprecision(2+jj) << lut[id] << ends; else if (prec < 0) str << fixed << setprecision(abs(prec)+3+jj) << lut[id] << ends; else if (prec < 2) str << setprecision(2+jj) << lut[id] << ends; else if (prec < 5) str << fixed << setprecision(0+jj) << lut[id] << ends; else str << scientific << setprecision(2+jj) << lut[id] << ends; if (ticktxt[ii]) delete [] ticktxt[ii]; ticktxt[ii] = new char[strlen(str.str().c_str())+1]; strcpy(ticktxt[ii],str.str().c_str()); } // now see if all is unique int ok=1; for (int ii=1; ii<opts->ticks; ii++) { if (!strcmp(ticktxt[ii-1],ticktxt[ii])) ok=0; } if (ok) break; } // determine skipcnt Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); if (!opts->orientation) { // horizontal int ww =0; for (int ii=0; ii<opts->ticks; ii++) { if (ticktxt[ii]) { int aa = Tk_TextWidth(font, ticktxt[ii], strlen(ticktxt[ii])); if (aa>ww) ww = aa; } } skipcnt = (ww+2)*opts->ticks/opts->width; } else { // vertical int total = (metrics.linespace+1)*opts->ticks; skipcnt = total/opts->height; } } void ColorbarBase::setColormapLevelCmd() { if (lut) delete [] lut; lut = NULL; cnt = 0; invalidPixmap(); redraw(); } void ColorbarBase::setColormapLevelCmd(int cc, double* ff) { // check for the same if (cnt == cc) { int same = 1; for (int ii=0; ii<cc; ii++) same &= (lut[ii] == ff[ii]); if (same) return; } // remove the old if (lut) delete [] lut; lut = NULL; cnt = 0; invalidPixmap(); redraw(); // now check for repeat values, including zeros double* gg = new double[cc]; int dd = 1; gg[0] = ff[0]; for (int ii=1; ii<cc; ii++) if (gg[dd-1]!=ff[ii]) gg[dd++] = ff[ii]; // we have new data cnt = dd; lut = new double[cnt]; for (int ii=0; ii<cnt; ii++) lut[ii] = gg[ii]; delete [] gg; } // X11 int ColorbarBase::updatePixmap(const BBox& bb) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (pixmap) return TCL_OK; // create a valid pixmap // assume if no pixmap, no xmap // bb is in canvas coords if (!(pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), options->width, options->height, depth))) { internalError("Colorbar: Unable to Create Pixmap"); return TCL_OK; } if (!gc) gc = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); XSetForeground(display, gc, getColor("white")); XFillRectangle(display, pixmap, gc, 0, 0, options->width,options->height); if (!opts->orientation) { if (!(xmap = XGetImage(display, pixmap, 1, 1, options->width-2, opts->size-2, AllPlanes, ZPixmap))){ internalError("Colorbar: Unable to Create XImage"); return TCL_OK; } } else { if (!(xmap = XGetImage(display, pixmap, 1, 1, opts->size-2, options->height-2, AllPlanes, ZPixmap))){ internalError("Colorbar: Unable to Create XImage"); return TCL_OK; } } ximageToPixmap(); if (opts->numerics && opts->space) { renderGridAST(); return TCL_OK; } // we want a border, even with no numerics renderGrid(); return TCL_OK; } void ColorbarBase::renderGrid() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; // box XSetForeground(display, gc, getColor("black")); if (!opts->orientation) XDrawRectangle(display, pixmap, gc, 0, 0, options->width-1, opts->size-1); else XDrawRectangle(display, pixmap, gc, 0, 0, opts->size-1, options->height-1); if (opts->numerics && lut) renderGridNumerics(); } void ColorbarBase::renderGridNumerics() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; // font Tk_Font font = getFont(); if (!font) return; // bad font, we're done Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); // set font XSetFont(display, gc, Tk_FontId(font)); // generate text lutToText(font); // tick marks int incrcnt=0; for (int ii=1; ii<opts->ticks-1; ii++) { if (!opts->orientation) { // horizontal int ww = (int)(ii/double(opts->ticks-1)*opts->width); int h = opts->size-1; int hh = opts->size-1 + TICKLEN; XDrawLine(display, pixmap, gc, ww, h, ww, hh); if (!incrcnt) { int txtwidth = Tk_TextWidth(font, ticktxt[ii], strlen(ticktxt[ii])); int www = ww - txtwidth/2.; int hhh = hh + TICKGAP + metrics.ascent; Tk_DrawChars(display, pixmap, gc, font, ticktxt[ii], strlen(ticktxt[ii]), www, hhh); } } else { // vertical int w = opts->size-1; int ww = opts->size-1 + TICKLEN; int hh = opts->height - (int)(ii/double(opts->ticks-1)*opts->height); XDrawLine(display, pixmap, gc, w, hh, ww, hh); if (!incrcnt) { int www = ww + TICKGAP; int hhh = hh + (metrics.ascent-metrics.descent)/2.; Tk_DrawChars(display, pixmap, gc, font, ticktxt[ii], strlen(ticktxt[ii]), www, hhh); } } if (incrcnt<skipcnt) incrcnt++; else incrcnt=0; } Tk_FreeFont(font); } void ColorbarBase::renderGridAST() { if (grid) delete grid; grid = NULL; if (cnt>1 && lut) { grid = new CBGrid(this, cnt, lut); if (grid) grid->render(); } } // PS int ColorbarBase::postscriptProc(int prepass) { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (!visible) return TCL_OK; if (prepass) return TCL_OK; // bar Tcl_AppendResult(interp, "gsave\n", NULL); ps(); Tcl_AppendResult(interp, "grestore\n", NULL); // numerics Tcl_AppendResult(interp, "gsave\n", NULL); if (opts->numerics && opts->space && grid) { psGridAST(); Tcl_AppendResult(interp, "grestore\n", NULL); return TCL_OK; } // we want a border, even if no numerics psGrid(); Tcl_AppendResult(interp, "grestore\n", NULL); return TCL_OK; } void ColorbarBase::ps() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int& width = options->width; int& height = options->height; int& size = opts->size; // image int ww,hh; Vector org = psOrigin(); if (!opts->orientation) { ww = width; hh = size; org += Vector(0,height-size); } else { ww = size; hh = height; } ostringstream str; str << org[0] << ' ' << org[1] << " translate" << endl << 1 << ' ' << 1 << " scale" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); switch (psLevel) { case 1: { psHead1(ww, hh); NoCompressAsciiHex filter(psLevel); psHV(filter, ww, hh); } break; case 2: { psHead2(ww, hh, "RunLength", "ASCII85"); RLEAscii85 filter(psLevel); psHV(filter, ww, hh); } break; case 3: { psHead2(ww, hh, "Flate", "ASCII85"); GZIPAscii85 filter(psLevel); psHV(filter, ww, hh); } break; } } void ColorbarBase::psHV(Filter& filter, int width, int height) { if (!((ColorbarBaseOptions*)options)->orientation) psHorz(filter, width, height); else psVert(filter, width, height); ostringstream str; filter.flush(str); psFix(str); Tcl_AppendResult(interp, str.str().c_str(), NULL); } void ColorbarBase::psGrid() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int& width = options->width; int& height = options->height; int& size = opts->size; // box int ww,hh; Vector org = psOrigin(); if (!opts->orientation) { ww = width; hh = size; org += Vector(0,height-size); } else { ww = size; hh = height; } Vector ll = Vector(0,0); Vector lr = Vector(ww,0); Vector ur = Vector(ww,hh); Vector ul = Vector(0,hh); ostringstream str; str << org[0] << ' ' << org[1] << " translate " << endl << "newpath " << endl << ll << "moveto " << endl << lr << "lineto " << endl << ur << "lineto " << endl << ul << "lineto " << endl << ll << "lineto " << endl << "closepath " << endl << .5 << " setlinewidth" << endl << " stroke" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); // numerics if (opts->numerics && lut) psGridNumerics(); } void ColorbarBase::psGridNumerics() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; // font Tk_Font font = NULL; { ostringstream fstr; fstr << opts->font << ' ' << opts->fontSize << ' ' << opts->fontWeight << ' ' << opts->fontSlant << ends; font = Tk_GetFont(interp, tkwin, fstr.str().c_str()); if (!font) return; // bad font, we're done } // set font { ostringstream str; str << '/' << psFontName(opts->font, opts->fontWeight, opts->fontSlant) << " findfont " << int(opts->fontSize*getDisplayRatio()) << " scalefont setfont" << endl; Tcl_AppendResult(interp, str.str().c_str(), NULL); } // generate text lutToText(font); // tick marks int incrcnt=0; for (int ii=0; ii<opts->ticks; ii++) { if (!opts->orientation) { // horizontal int ww = (int)(ii/double(opts->ticks-1)*opts->width); int h = 0; int hh = h-TICKLEN; ostringstream str; str << "newpath " << endl << Vector(ww,h) << "moveto " << endl << Vector(ww,hh) << "lineto " << endl << "closepath " << endl << .5 << " setlinewidth" << endl << " stroke" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); if (!incrcnt) { ostringstream str; Vector tt = Vector(ww,hh-TICKGAP); str << "newpath " << endl << tt << " moveto" << endl << '(' << psQuote(ticktxt[ii]) << ')' << "dup true charpath pathbbox " << endl << "closepath " << endl << "3 -1 roll sub 1.2 mul neg " << endl << "3 1 roll sub 2 div exch " << endl << tt << " moveto rmoveto show " << endl; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } else { // vertical int w = opts->size; int ww = opts->size + TICKLEN; int hh = (int)(ii/double(opts->ticks-1)*opts->height); ostringstream str; str << "newpath " << endl << Vector(w,hh) << "moveto " << endl << Vector(ww,hh) << "lineto " << endl << "closepath " << endl << .5 << " setlinewidth" << endl << " stroke" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); if (!incrcnt) { ostringstream str; Vector tt = Vector(ww+TICKGAP,hh); str << "newpath " << endl << tt << " moveto" << endl << '(' << psQuote(ticktxt[ii]) << ')' << "dup true charpath pathbbox " << endl << "closepath " << endl << "3 -1 roll sub 2 div neg " << endl << "3 1 roll pop pop 0 exch " << endl << tt << " moveto rmoveto show " << endl; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } if (incrcnt<skipcnt) incrcnt++; else incrcnt=0; } Tk_FreeFont(font); } void ColorbarBase::psGridAST() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; Vector oo; Vector uu(options->width, options->height); float delta = 4*opts->fontSize; // clip rect (to remove ticks on inside) if (!opts->orientation) { oo += Vector(-delta,-.5); uu += Vector(2*delta,-.75); } else { oo += Vector(-.25,-delta); uu += Vector(0,2*delta); } Matrix mm = Translate(psOrigin()); Vector ll = oo*mm; Vector lr = Vector(uu[0],oo[1])*mm; Vector ur = uu*mm; Vector ul = Vector(oo[0],uu[1])*mm; ostringstream str; str << "newpath " << endl << ll << "moveto " << endl << lr << "lineto " << endl << ur << "lineto " << endl << ul << "lineto " << endl << ll << "lineto " << endl << "closepath clip" << endl << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); // grid if (grid) grid->ps(psColorSpace, originX, originY); } // MacOSX #ifdef _MACOSX void ColorbarBase::macosxPrintCmd() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (!visible) return; // init macosxBegin(); int ww,hh; if (!opts->orientation) { ww = options->width; hh = opts->size; } else { ww = opts->size; hh = options->height; } // image macosx(1, ww, hh, Vector(originX,originY), Vector(ww,hh)); // grid if (opts->numerics && opts->space && grid) { macosxGridAST(); macosxEnd(); return; } // we want a border, even if no numerics macosxGrid(); macosxEnd(); } void ColorbarBase::macosxGrid() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int& width = options->width; int& height = options->height; int& size = opts->size; Matrix mm = Translate(originX, originY); macosxColor(getXColor("black")); macosxDash(NULL,0); macosxWidth(.5); // Box int ww,hh; if (!opts->orientation) { ww = width; hh = size; } else { ww = size; hh = height; } Vector v[5]; v[0] = Vector(0,0) * mm; v[1] = Vector(ww,0) * mm; v[2] = Vector(ww,hh) * mm; v[3] = Vector(0,hh) * mm; v[4] = Vector(0,0) * mm; macosxDrawLines(v,5); // numerics if (opts->numerics && lut) macosxGridNumerics(); } void ColorbarBase::macosxGridNumerics() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; Matrix mm = Translate(originX, originY); // font Tk_Font font = getFont(); if (!font) return; // bad font, we're done Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); // set font Tcl_DString psFont; Tcl_DStringInit(&psFont); int psSize = Tk_PostscriptFontName(font, &psFont); macosxFont(Tcl_DStringValue(&psFont), psSize); Tcl_DStringFree(&psFont); // generate text lutToText(font); // tick marks int incrcnt=0; for (int ii=0; ii<opts->ticks; ii++) { if (!opts->orientation) { // horizontal int ww = (int)(ii/double(opts->ticks-1)*opts->width); int h = opts->size; int hh = opts->size + TICKLEN; Vector vv[2]; vv[0] = Vector(ww,h)*mm; vv[1] = Vector(ww,hh)*mm; macosxDrawLines(vv,2); if (!incrcnt) { int txtwidth = Tk_TextWidth(font, ticktxt[ii], strlen(ticktxt[ii])); int www = ww - txtwidth/2.; int hhh = hh + TICKGAP + metrics.ascent; macosxDrawText(Vector(www,hhh)*mm, 0, ticktxt[ii]); } } else { // vertical int w = opts->size; int ww = opts->size + TICKLEN; int hh = opts->height - (int)(ii/double(opts->ticks-1)*opts->height); Vector vv[2]; vv[0] = Vector(w,hh)*mm; vv[1] = Vector(ww,hh)*mm; macosxDrawLines(vv,2); if (!incrcnt) { int www = ww + TICKGAP; int hhh = hh + (metrics.ascent-metrics.descent)/2.; macosxDrawText(Vector(www,hhh)*mm, 0, ticktxt[ii]); } } if (incrcnt<skipcnt) incrcnt++; else incrcnt=0; } Tk_FreeFont(font); } void ColorbarBase::macosxGridAST() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; Vector oo(originX, originY); Vector uu(options->width, options->height); float delta = 4*opts->fontSize; if (!opts->orientation) { oo += Vector(-delta,-.2); uu += Vector(2*delta,-.2); } else { oo += Vector(-.2,-delta); uu += Vector(0,2*delta); } macosxClip(oo,uu); if (grid) grid->macosx(originX, originY); } #endif // WIN32 #ifdef _WIN32 void ColorbarBase::win32PrintCmd() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; if (!visible) return; // init win32Begin(); int ww,hh; if (!opts->orientation) { ww = options->width; hh = opts->size; } else { ww = opts->size; hh = options->height; } // image win32(1, ww, hh, Vector(originX,originY), Vector(ww,hh)); // grid if (opts->numerics && opts->space && grid) { win32GridAST(); win32End(); } // we want a border, even if no numerics win32Grid(); win32End(); } void ColorbarBase::win32Grid() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; int& width = options->width; int& height = options->height; int& size = opts->size; Matrix mm = Translate(originX, originY); win32Color(getXColor("black")); win32Dash(NULL,0); win32Width(.5); // box int ww,hh; if (!opts->orientation) { ww = width; hh = size; } else { ww = size; hh = height; } Vector v[5]; v[0] = Vector(0,0) * mm; v[1] = Vector(ww,0) * mm; v[2] = Vector(ww,hh) * mm; v[3] = Vector(0,hh) * mm; v[4] = Vector(0,0) * mm; win32DrawLines(v,5); // numerics if (opts->numerics && lut) win32GridNumerics(); } void ColorbarBase::win32GridNumerics() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; Matrix mm = Translate(originX, originY); // font Tk_Font font = getFont(); if (!font) return; // bad font, we're done Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); win32Font(font); // generate text lutToText(font); // tick marks int incrcnt=0; for (int ii=0; ii<opts->ticks; ii++) { if (!opts->orientation) { // horizontal int ww = ii/double(opts->ticks-1)*opts->width; int h = opts->size; int hh = opts->size + TICKLEN; Vector vv[2]; vv[0] = Vector(ww,h)*mm; vv[1] = Vector(ww,hh)*mm; win32DrawLines(vv,2); if (!incrcnt) { int txtwidth = Tk_TextWidth(font, ticktxt[ii], strlen(ticktxt[ii])); int www = ww - txtwidth/2.; int hhh = hh + TICKGAP + metrics.ascent; win32DrawText(Vector(www,hhh)*mm, 0, ticktxt[ii]); } } else { // vertical int w = opts->size; int ww = opts->size + TICKLEN; int hh = opts->height - (int)(ii/double(opts->ticks-1)*opts->height); Vector vv[2]; vv[0] = Vector(w,hh)*mm; vv[1] = Vector(ww,hh)*mm; win32DrawLines(vv,2); if (!incrcnt) { int www = ww + TICKGAP; int hhh = hh + (metrics.ascent-metrics.descent)/2.; win32DrawText(Vector(www,hhh)*mm, 0, ticktxt[ii]); } } if (incrcnt<skipcnt) incrcnt++; else incrcnt=0; } Tk_FreeFont(font); } void ColorbarBase::win32GridAST() { ColorbarBaseOptions* opts = (ColorbarBaseOptions*)options; Vector oo(originX, originY); Vector uu(options->width, options->height); float delta = 4*opts->fontSize; if (!opts->orientation) { oo += Vector(-delta,-.2); uu += Vector(2*delta,-.2); } else { oo += Vector(-.2,-delta); uu += Vector(0,2*delta); } win32Clip(oo,uu); if (grid) grid->win32(originX, originY); } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor24.C�������������������������������������������������������0000644�0001750�0001750�00000025102�11752025335�020046� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbartruecolor24.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarTrueColor24CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Colorbar Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarTrueColor24Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbar", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarTrueColor24Type = { (char*)"colorbartruecolor24", // name sizeof(ColorbarBaseOptions), // size ColorbarTrueColor24CreateProc, // configProc colorbarTrueColor24Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc WidgetICursorProc, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarTrueColor24_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarTrueColor24Type); return TCL_OK; } int ColorbarTrueColor24CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarTrueColor24* colorbar = new ColorbarTrueColor24(interp,canvas,item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarTrueColor24 ColorbarTrueColor24::ColorbarTrueColor24(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarTrueColor(i,c,item), TrueColor24(visual) { configSpecs = colorbarTrueColor24Specs; // colorbar configure options loadDefaultCMaps(); } void ColorbarTrueColor24::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); switch (xmap->bits_per_pixel) { case 32: updateColors32Horz(width, height, data); break; case 24: updateColors24Horz(width, height, data); break; default: internalError("Colorbar: bad bits/pixel"); return; } } void ColorbarTrueColor24::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); switch (xmap->bits_per_pixel) { case 32: updateColors32Vert(width, height, data); break; case 24: updateColors24Vert(width, height, data); break; default: internalError("Colorbar: bad bits/pixel"); return; } } void ColorbarTrueColor24::updateColors24Horz(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; memcpy(data+ii*3, &a, 3); } } else { for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(data+ii*3) = *(rr+3); *(data+ii*3+1) = *(rr+2); *(data+ii*3+2) = *(rr+1); } } // --and duplicate for remaining rows for (int jj=1; jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line); } void ColorbarTrueColor24::updateColors24Vert(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; for (int ii=0; ii<width; ii++) memcpy(data+ii*3, &a, 3); } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<width; ii++) { *(data+ii*3) = *(rr+3); *(data+ii*3+1) = *(rr+2); *(data+ii*3+2) = *(rr+1); } } } } void ColorbarTrueColor24::updateColors32Horz(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; memcpy(data+ii*4, &a, 4); } } else { for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(data+ii*4) = *(rr+3); *(data+ii*4+1) = *(rr+2); *(data+ii*4+2) = *(rr+1); *(data+ii*4+3) = *(rr); } } // --and duplicate for remaining rows for (int jj=1; jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line); } void ColorbarTrueColor24::updateColors32Vert(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; for (int ii=0; ii<width; ii++) memcpy(data+ii*4, &a, 4); } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; a |= g << gs_; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<width; ii++) { *(data+ii*4) = *(rr+3); *(data+ii*4+1) = *(rr+2); *(data+ii*4+2) = *(rr+1); *(data+ii*4+3) = *(rr); } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/cbgrid.h��������������������������������������������������������������������0000644�0001750�0001750�00000001055�11701140711�015424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __cbgrid_h__ #define __cbgrid_h__ #include <tk.h> #include "grid2dbase.h" #include "vector.h" class CBGrid : public Grid2dBase { private: int cnt_; double* lut_; int doit(RenderMode); public: CBGrid(Widget*, int, double*); int render(); int ps(int, int, int); #ifdef _MACOSX int macosx(int, int); #endif #ifdef _WIN32 int win32(int, int); #endif }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/saoparser.H�����������������������������������������������������������������0000644�0001750�0001750�00000005337�12064133240�016142� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, EOF_ = 261, BLUE_ = 262, DEBUG_ = 263, GAMMA_ = 264, GREEN_ = 265, FALSE_ = 266, NO_ = 267, OFF_ = 268, ON_ = 269, PSEUDOCOLOR_ = 270, RED_ = 271, TRUE_ = 272, YES_ = 273 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define EOF_ 261 #define BLUE_ 262 #define DEBUG_ 263 #define GAMMA_ 264 #define GREEN_ 265 #define FALSE_ 266 #define NO_ 267 #define OFF_ 268 #define ON_ 269 #define PSEUDOCOLOR_ 270 #define RED_ 271 #define TRUE_ 272 #define YES_ 273 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "saoparser.Y" { #define SAOBUFSIZE 4096 char str[SAOBUFSIZE]; int integer; float real; } /* Line 1529 of yacc.c. */ #line 92 "saoparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/default.C�������������������������������������������������������������������0000644�0001750�0001750�00000053574�11743600735�015603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <math.h> #include "default.h" #include "util.h" GreyColorMap::GreyColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("grey"); fileName = dupstr("grey.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(1,1)); } RedColorMap::RedColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("red"); fileName = dupstr("red.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(0,0)); blue.append(new LIColor(0,0)); blue.append(new LIColor(0,0)); } GreenColorMap::GreenColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("green"); fileName = dupstr("green.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(0,0)); green.append(new LIColor(0,0)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(0,0)); } BlueColorMap::BlueColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("blue"); fileName = dupstr("blue.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(0,0)); green.append(new LIColor(0,0)); green.append(new LIColor(0,0)); blue.append(new LIColor(0,0)); blue.append(new LIColor(1,1)); } AColorMap::AColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("a"); fileName = dupstr("a.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.25,0)); red.append(new LIColor(.5,1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.25,1)); green.append(new LIColor(.5,0)); green.append(new LIColor(.77,0)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.125,0)); blue.append(new LIColor(.5,1)); blue.append(new LIColor(.64,.5)); blue.append(new LIColor(.77,0)); blue.append(new LIColor(1,0)); } BColorMap::BColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("b"); fileName = dupstr("b.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.25,0)); red.append(new LIColor(.5,1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.5,0)); green.append(new LIColor(.75,1)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.25,1)); blue.append(new LIColor(.5,0)); blue.append(new LIColor(.75,0)); blue.append(new LIColor(1,1)); } BBColorMap::BBColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("bb"); fileName = dupstr("bb.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.5,1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.25,0)); green.append(new LIColor(.75,1)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.5,0)); blue.append(new LIColor(1,1)); } HEColorMap::HEColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("he"); fileName = dupstr("he.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.015,.5)); red.append(new LIColor(.25,.5)); red.append(new LIColor(.5,.75)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.065,0)); green.append(new LIColor(.125,.5)); green.append(new LIColor(.25,.75)); green.append(new LIColor(.5,.81)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.015,.125)); blue.append(new LIColor(.03,.375)); blue.append(new LIColor(.065,.625)); blue.append(new LIColor(.25,.25)); blue.append(new LIColor(1,1)); } I8ColorMap::I8ColorMap(Colorbar* p) : LUTColorMap(p) { name = dupstr("i8"); fileName = dupstr("i8.lut"); colors.append(new RGBColor(0,0,0)); colors.append(new RGBColor(0,1,0)); colors.append(new RGBColor(0,0,1)); colors.append(new RGBColor(0,1,1)); colors.append(new RGBColor(1,0,0)); colors.append(new RGBColor(1,1,0)); colors.append(new RGBColor(1,0,1)); colors.append(new RGBColor(1,1,1)); } AIPSColorMap::AIPSColorMap(Colorbar* p) : LUTColorMap(p) { name = dupstr("aips0"); fileName = dupstr("aips0.lut"); colors.append(new RGBColor(.196,.196,.196)); colors.append(new RGBColor(.475,.000,.608)); colors.append(new RGBColor(.000,.000,.785)); colors.append(new RGBColor(.373,.655,.925)); colors.append(new RGBColor(.000,.596,.000)); colors.append(new RGBColor(.000,.965,.000)); colors.append(new RGBColor(1.00,1.00,.000)); colors.append(new RGBColor(1.00,.694,.000)); colors.append(new RGBColor(1.00,.000,.000)); } HeatColorMap::HeatColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("heat"); fileName = dupstr("heat.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.34,1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.65,0)); blue.append(new LIColor(.98,1)); blue.append(new LIColor(1,1)); } CoolColorMap::CoolColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("cool"); fileName = dupstr("cool.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.29,0)); red.append(new LIColor(.76,.1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.22,0)); green.append(new LIColor(.96,1)); green.append(new LIColor(1,1)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.53,1)); blue.append(new LIColor(1,1)); } RainbowColorMap::RainbowColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("rainbow"); fileName = dupstr("rainbow.sao"); red.append(new LIColor(0,1)); red.append(new LIColor(.2,0)); red.append(new LIColor(.6,0)); red.append(new LIColor(.8,1)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.2,0)); green.append(new LIColor(.4,1)); green.append(new LIColor(.8,1)); green.append(new LIColor(1,0)); blue.append(new LIColor(0,1)); blue.append(new LIColor(.4,1)); blue.append(new LIColor(.6,0)); blue.append(new LIColor(1,0)); } StandardColorMap::StandardColorMap(Colorbar* p) : SAOColorMap(p) { name = dupstr("standard"); fileName = dupstr("standard.sao"); red.append(new LIColor(0,0)); red.append(new LIColor(.333,.3)); red.append(new LIColor(.333,0)); red.append(new LIColor(.666,.3)); red.append(new LIColor(.666,.3)); red.append(new LIColor(1,1)); green.append(new LIColor(0,0)); green.append(new LIColor(.333,.3)); green.append(new LIColor(.333,.3)); green.append(new LIColor(.666,1)); green.append(new LIColor(.666,0)); green.append(new LIColor(1,.3)); blue.append(new LIColor(0,0)); blue.append(new LIColor(.333,1)); blue.append(new LIColor(.333,0)); blue.append(new LIColor(.666,.3)); blue.append(new LIColor(.666,0)); blue.append(new LIColor(1,.3)); } StaircaseColorMap::StaircaseColorMap(Colorbar* p) : LUTColorMap(p) { name = dupstr("staircase"); fileName = dupstr("staircase.lut"); for (int ii=1; ii<=5; ii++) { float kk = ii/5.; colors.append(new RGBColor(kk*.3,kk*.3,kk*1)); } for (int ii=1; ii<=5; ii++) { float kk = ii/5.; colors.append(new RGBColor(kk*.3,kk*1,kk*.3)); } for (int ii=1; ii<=5; ii++) { float kk = ii/5.; colors.append(new RGBColor(kk*1,kk*.3,kk*.3)); } } ColorColorMap::ColorColorMap(Colorbar* p) : LUTColorMap(p) { name = dupstr("color"); fileName = dupstr("color.lut"); colors.append(new RGBColor(0,0,0)); colors.append(new RGBColor(0.18431, 0.18431, 0.18431)); colors.append(new RGBColor(0.37255, 0.37255, 0.37255)); colors.append(new RGBColor(0.56078, 0.56078, 0.56078)); colors.append(new RGBColor(0.74902, 0.74902, 0.74902)); colors.append(new RGBColor(0.93725, 0.93725, 0.93725)); colors.append(new RGBColor(0.00000, 0.18431, 0.93725)); colors.append(new RGBColor(0.00000, 0.37255, 0.74902)); colors.append(new RGBColor(0.00000, 0.49804, 0.49804)); colors.append(new RGBColor(0.00000, 0.74902, 0.30980)); colors.append(new RGBColor(0.00000, 0.93725, 0.00000)); colors.append(new RGBColor(0.30980, 0.62353, 0.00000)); colors.append(new RGBColor(0.49804, 0.49804, 0.00000)); colors.append(new RGBColor(0.62353, 0.30980, 0.00000)); colors.append(new RGBColor(0.93725, 0.00000, 0.00000)); colors.append(new RGBColor(0.74902, 0.00000, 0.30980)); } SLSColorMap::SLSColorMap(Colorbar* p) : LUTColorMap(p) { name = dupstr("sls"); fileName = dupstr("sls.lut"); colors.append(new RGBColor(0.000000, 0.000000, 0.000000)); colors.append(new RGBColor(0.043442, 0.000000, 0.052883)); colors.append(new RGBColor(0.086883, 0.000000, 0.105767)); colors.append(new RGBColor(0.130325, 0.000000, 0.158650)); colors.append(new RGBColor(0.173767, 0.000000, 0.211533)); colors.append(new RGBColor(0.217208, 0.000000, 0.264417)); colors.append(new RGBColor(0.260650, 0.000000, 0.317300)); colors.append(new RGBColor(0.304092, 0.000000, 0.370183)); colors.append(new RGBColor(0.347533, 0.000000, 0.423067)); colors.append(new RGBColor(0.390975, 0.000000, 0.475950)); colors.append(new RGBColor(0.434417, 0.000000, 0.528833)); colors.append(new RGBColor(0.477858, 0.000000, 0.581717)); colors.append(new RGBColor(0.521300, 0.000000, 0.634600)); colors.append(new RGBColor(0.506742, 0.000000, 0.640217)); colors.append(new RGBColor(0.492183, 0.000000, 0.645833)); colors.append(new RGBColor(0.477625, 0.000000, 0.651450)); colors.append(new RGBColor(0.463067, 0.000000, 0.657067)); colors.append(new RGBColor(0.448508, 0.000000, 0.662683)); colors.append(new RGBColor(0.433950, 0.000000, 0.668300)); colors.append(new RGBColor(0.419392, 0.000000, 0.673917)); colors.append(new RGBColor(0.404833, 0.000000, 0.679533)); colors.append(new RGBColor(0.390275, 0.000000, 0.685150)); colors.append(new RGBColor(0.375717, 0.000000, 0.690767)); colors.append(new RGBColor(0.361158, 0.000000, 0.696383)); colors.append(new RGBColor(0.346600, 0.000000, 0.702000)); colors.append(new RGBColor(0.317717, 0.000000, 0.712192)); colors.append(new RGBColor(0.288833, 0.000000, 0.722383)); colors.append(new RGBColor(0.259950, 0.000000, 0.732575)); colors.append(new RGBColor(0.231067, 0.000000, 0.742767)); colors.append(new RGBColor(0.202183, 0.000000, 0.752958)); colors.append(new RGBColor(0.173300, 0.000000, 0.763150)); colors.append(new RGBColor(0.144417, 0.000000, 0.773342)); colors.append(new RGBColor(0.115533, 0.000000, 0.783533)); colors.append(new RGBColor(0.086650, 0.000000, 0.793725)); colors.append(new RGBColor(0.057767, 0.000000, 0.803917)); colors.append(new RGBColor(0.028883, 0.000000, 0.814108)); colors.append(new RGBColor(0.000000, 0.000000, 0.824300)); colors.append(new RGBColor(0.000000, 0.019817, 0.838942)); colors.append(new RGBColor(0.000000, 0.039633, 0.853583)); colors.append(new RGBColor(0.000000, 0.059450, 0.868225)); colors.append(new RGBColor(0.000000, 0.079267, 0.882867)); colors.append(new RGBColor(0.000000, 0.099083, 0.897508)); colors.append(new RGBColor(0.000000, 0.118900, 0.912150)); colors.append(new RGBColor(0.000000, 0.138717, 0.926792)); colors.append(new RGBColor(0.000000, 0.158533, 0.941433)); colors.append(new RGBColor(0.000000, 0.178350, 0.956075)); colors.append(new RGBColor(0.000000, 0.198167, 0.970717)); colors.append(new RGBColor(0.000000, 0.217983, 0.985358)); colors.append(new RGBColor(0.000000, 0.237800, 1.000000)); colors.append(new RGBColor(0.000000, 0.268533, 1.000000)); colors.append(new RGBColor(0.000000, 0.299267, 1.000000)); colors.append(new RGBColor(0.000000, 0.330000, 1.000000)); colors.append(new RGBColor(0.000000, 0.360733, 1.000000)); colors.append(new RGBColor(0.000000, 0.391467, 1.000000)); colors.append(new RGBColor(0.000000, 0.422200, 1.000000)); colors.append(new RGBColor(0.000000, 0.452933, 1.000000)); colors.append(new RGBColor(0.000000, 0.483667, 1.000000)); colors.append(new RGBColor(0.000000, 0.514400, 1.000000)); colors.append(new RGBColor(0.000000, 0.545133, 1.000000)); colors.append(new RGBColor(0.000000, 0.575867, 1.000000)); colors.append(new RGBColor(0.000000, 0.606600, 1.000000)); colors.append(new RGBColor(0.000000, 0.631733, 0.975300)); colors.append(new RGBColor(0.000000, 0.656867, 0.950600)); colors.append(new RGBColor(0.000000, 0.682000, 0.925900)); colors.append(new RGBColor(0.000000, 0.707133, 0.901200)); colors.append(new RGBColor(0.000000, 0.732267, 0.876500)); colors.append(new RGBColor(0.000000, 0.757400, 0.851800)); colors.append(new RGBColor(0.000000, 0.782533, 0.827100)); colors.append(new RGBColor(0.000000, 0.807667, 0.802400)); colors.append(new RGBColor(0.000000, 0.832800, 0.777700)); colors.append(new RGBColor(0.000000, 0.857933, 0.753000)); colors.append(new RGBColor(0.000000, 0.883067, 0.728300)); colors.append(new RGBColor(0.000000, 0.908200, 0.703600)); colors.append(new RGBColor(0.000000, 0.901908, 0.676675)); colors.append(new RGBColor(0.000000, 0.895617, 0.649750)); colors.append(new RGBColor(0.000000, 0.889325, 0.622825)); colors.append(new RGBColor(0.000000, 0.883033, 0.595900)); colors.append(new RGBColor(0.000000, 0.876742, 0.568975)); colors.append(new RGBColor(0.000000, 0.870450, 0.542050)); colors.append(new RGBColor(0.000000, 0.864158, 0.515125)); colors.append(new RGBColor(0.000000, 0.857867, 0.488200)); colors.append(new RGBColor(0.000000, 0.851575, 0.461275)); colors.append(new RGBColor(0.000000, 0.845283, 0.434350)); colors.append(new RGBColor(0.000000, 0.838992, 0.407425)); colors.append(new RGBColor(0.000000, 0.832700, 0.380500)); colors.append(new RGBColor(0.000000, 0.832308, 0.354858)); colors.append(new RGBColor(0.000000, 0.831917, 0.329217)); colors.append(new RGBColor(0.000000, 0.831525, 0.303575)); colors.append(new RGBColor(0.000000, 0.831133, 0.277933)); colors.append(new RGBColor(0.000000, 0.830742, 0.252292)); colors.append(new RGBColor(0.000000, 0.830350, 0.226650)); colors.append(new RGBColor(0.000000, 0.829958, 0.201008)); colors.append(new RGBColor(0.000000, 0.829567, 0.175367)); colors.append(new RGBColor(0.000000, 0.829175, 0.149725)); colors.append(new RGBColor(0.000000, 0.828783, 0.124083)); colors.append(new RGBColor(0.000000, 0.828392, 0.098442)); colors.append(new RGBColor(0.000000, 0.828000, 0.072800)); colors.append(new RGBColor(0.033167, 0.834167, 0.066733)); colors.append(new RGBColor(0.066333, 0.840333, 0.060667)); colors.append(new RGBColor(0.099500, 0.846500, 0.054600)); colors.append(new RGBColor(0.132667, 0.852667, 0.048533)); colors.append(new RGBColor(0.165833, 0.858833, 0.042467)); colors.append(new RGBColor(0.199000, 0.865000, 0.036400)); colors.append(new RGBColor(0.232167, 0.871167, 0.030333)); colors.append(new RGBColor(0.265333, 0.877333, 0.024267)); colors.append(new RGBColor(0.298500, 0.883500, 0.018200)); colors.append(new RGBColor(0.331667, 0.889667, 0.012133)); colors.append(new RGBColor(0.364833, 0.895833, 0.006067)); colors.append(new RGBColor(0.398000, 0.902000, 0.000000)); colors.append(new RGBColor(0.430950, 0.902000, 0.000000)); colors.append(new RGBColor(0.463900, 0.902000, 0.000000)); colors.append(new RGBColor(0.496850, 0.902000, 0.000000)); colors.append(new RGBColor(0.529800, 0.902000, 0.000000)); colors.append(new RGBColor(0.562750, 0.902000, 0.000000)); colors.append(new RGBColor(0.595700, 0.902000, 0.000000)); colors.append(new RGBColor(0.628650, 0.902000, 0.000000)); colors.append(new RGBColor(0.661600, 0.902000, 0.000000)); colors.append(new RGBColor(0.694550, 0.902000, 0.000000)); colors.append(new RGBColor(0.727500, 0.902000, 0.000000)); colors.append(new RGBColor(0.760450, 0.902000, 0.000000)); colors.append(new RGBColor(0.793400, 0.902000, 0.000000)); colors.append(new RGBColor(0.810617, 0.897133, 0.003983)); colors.append(new RGBColor(0.827833, 0.892267, 0.007967)); colors.append(new RGBColor(0.845050, 0.887400, 0.011950)); colors.append(new RGBColor(0.862267, 0.882533, 0.015933)); colors.append(new RGBColor(0.879483, 0.877667, 0.019917)); colors.append(new RGBColor(0.896700, 0.872800, 0.023900)); colors.append(new RGBColor(0.913917, 0.867933, 0.027883)); colors.append(new RGBColor(0.931133, 0.863067, 0.031867)); colors.append(new RGBColor(0.948350, 0.858200, 0.035850)); colors.append(new RGBColor(0.965567, 0.853333, 0.039833)); colors.append(new RGBColor(0.982783, 0.848467, 0.043817)); colors.append(new RGBColor(1.000000, 0.843600, 0.047800)); colors.append(new RGBColor(0.995725, 0.824892, 0.051600)); colors.append(new RGBColor(0.991450, 0.806183, 0.055400)); colors.append(new RGBColor(0.987175, 0.787475, 0.059200)); colors.append(new RGBColor(0.982900, 0.768767, 0.063000)); colors.append(new RGBColor(0.978625, 0.750058, 0.066800)); colors.append(new RGBColor(0.974350, 0.731350, 0.070600)); colors.append(new RGBColor(0.970075, 0.712642, 0.074400)); colors.append(new RGBColor(0.965800, 0.693933, 0.078200)); colors.append(new RGBColor(0.961525, 0.675225, 0.082000)); colors.append(new RGBColor(0.957250, 0.656517, 0.085800)); colors.append(new RGBColor(0.952975, 0.637808, 0.089600)); colors.append(new RGBColor(0.948700, 0.619100, 0.093400)); colors.append(new RGBColor(0.952975, 0.600408, 0.085617)); colors.append(new RGBColor(0.957250, 0.581717, 0.077833)); colors.append(new RGBColor(0.961525, 0.563025, 0.070050)); colors.append(new RGBColor(0.965800, 0.544333, 0.062267)); colors.append(new RGBColor(0.970075, 0.525642, 0.054483)); colors.append(new RGBColor(0.974350, 0.506950, 0.046700)); colors.append(new RGBColor(0.978625, 0.488258, 0.038917)); colors.append(new RGBColor(0.982900, 0.469567, 0.031133)); colors.append(new RGBColor(0.987175, 0.450875, 0.023350)); colors.append(new RGBColor(0.991450, 0.432183, 0.015567)); colors.append(new RGBColor(0.995725, 0.413492, 0.007783)); colors.append(new RGBColor(1.000000, 0.394800, 0.000000)); colors.append(new RGBColor(0.998342, 0.361900, 0.000000)); colors.append(new RGBColor(0.996683, 0.329000, 0.000000)); colors.append(new RGBColor(0.995025, 0.296100, 0.000000)); colors.append(new RGBColor(0.993367, 0.263200, 0.000000)); colors.append(new RGBColor(0.991708, 0.230300, 0.000000)); colors.append(new RGBColor(0.990050, 0.197400, 0.000000)); colors.append(new RGBColor(0.988392, 0.164500, 0.000000)); colors.append(new RGBColor(0.986733, 0.131600, 0.000000)); colors.append(new RGBColor(0.985075, 0.098700, 0.000000)); colors.append(new RGBColor(0.983417, 0.065800, 0.000000)); colors.append(new RGBColor(0.981758, 0.032900, 0.000000)); colors.append(new RGBColor(0.980100, 0.000000, 0.000000)); colors.append(new RGBColor(0.955925, 0.000000, 0.000000)); colors.append(new RGBColor(0.931750, 0.000000, 0.000000)); colors.append(new RGBColor(0.907575, 0.000000, 0.000000)); colors.append(new RGBColor(0.883400, 0.000000, 0.000000)); colors.append(new RGBColor(0.859225, 0.000000, 0.000000)); colors.append(new RGBColor(0.835050, 0.000000, 0.000000)); colors.append(new RGBColor(0.810875, 0.000000, 0.000000)); colors.append(new RGBColor(0.786700, 0.000000, 0.000000)); colors.append(new RGBColor(0.762525, 0.000000, 0.000000)); colors.append(new RGBColor(0.738350, 0.000000, 0.000000)); colors.append(new RGBColor(0.714175, 0.000000, 0.000000)); colors.append(new RGBColor(0.690000, 0.000000, 0.000000)); colors.append(new RGBColor(0.715833, 0.083333, 0.083333)); colors.append(new RGBColor(0.741667, 0.166667, 0.166667)); colors.append(new RGBColor(0.767500, 0.250000, 0.250000)); colors.append(new RGBColor(0.793333, 0.333333, 0.333333)); colors.append(new RGBColor(0.819167, 0.416667, 0.416667)); colors.append(new RGBColor(0.845000, 0.500000, 0.500000)); colors.append(new RGBColor(0.870833, 0.583333, 0.583333)); colors.append(new RGBColor(0.896667, 0.666667, 0.666667)); colors.append(new RGBColor(0.922500, 0.750000, 0.750000)); colors.append(new RGBColor(0.948333, 0.833333, 0.833333)); colors.append(new RGBColor(0.974167, 0.916667, 0.916667)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); colors.append(new RGBColor(1.000000, 1.000000, 1.000000)); } HSVColorMap::HSVColorMap(Colorbar* p) : LUTColorMap(p) { /* HSV: hue varies uniformly from 270 to 360 and back to 270. * Value varies from zero to one using a cube root relation * which causes the value to approach 1.0 rapidly away from zero. * Saturation is zero near the endpoints, causing the curve * to range from black to white at the endpoints, but ranges * to 1.0 at the halfway point, causing nearly saturated colors * in the middle of the range. */ name = dupstr("hsv"); fileName = dupstr("hsv.lut"); int size = 200; for (int i=0; i<size; i++) { // generate in hsv float frac = 1.0 - ((float)i / (float)(size - 1)); float h = frac * 360.0 + 270.0; float s = fabs(sin (frac * 3.1416)); float v = pow((1.0 - frac), (1.0 / 3.0)); // convert to rgb while (h >= 360.0) h -= 360.0; h /= 60.0; int ii = (int)h; float f = h - ii; float p = v * (1 - s); float q = v * (1 - s*f); float t = v * (1 - s * (1.0 - f)); switch (ii) { case 0: colors.append(new RGBColor(v,t,p)); break; case 1: colors.append(new RGBColor(q,v,p)); break; case 2: colors.append(new RGBColor(p,v,t)); break; case 3: colors.append(new RGBColor(p,q,v)); break; case 4: colors.append(new RGBColor(t,p,v)); break; case 5: colors.append(new RGBColor(v,p,q)); break; } } } ������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lutlex.C��������������������������������������������������������������������0000644�0001750�0001750�00000127010�12032637771�015461� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lutlex.C" #line 4 "lutlex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer rgbFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *rgballoc (yy_size_t ); void *rgbrealloc (void *,yy_size_t ); void rgbfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 18 #define YY_END_OF_BUFFER 19 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[57] = { 0, 0, 0, 2, 2, 19, 17, 14, 16, 17, 17, 17, 10, 13, 13, 13, 13, 13, 13, 13, 2, 1, 14, 15, 0, 10, 12, 11, 10, 13, 13, 13, 13, 5, 13, 7, 13, 13, 2, 0, 0, 0, 11, 13, 13, 6, 13, 9, 11, 0, 12, 13, 13, 8, 3, 4, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 6, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, 11, 12, 13, 14, 10, 10, 10, 10, 15, 10, 16, 17, 10, 10, 18, 19, 20, 21, 10, 10, 10, 22, 10, 1, 1, 1, 1, 1, 1, 23, 24, 10, 25, 26, 27, 28, 10, 10, 10, 10, 29, 10, 30, 31, 10, 10, 32, 33, 34, 35, 10, 10, 10, 36, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[37] = { 0, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } ; static yyconst flex_int16_t yy_base[60] = { 0, 0, 0, 139, 138, 140, 143, 137, 143, 135, 31, 129, 33, 123, 35, 40, 36, 38, 37, 44, 0, 143, 124, 143, 117, 65, 50, 66, 68, 117, 76, 78, 80, 116, 83, 115, 58, 79, 0, 53, 83, 113, 93, 95, 98, 113, 99, 112, 108, 101, 96, 100, 101, 91, 60, 46, 143, 131, 46, 134 } ; static yyconst flex_int16_t yy_def[60] = { 0, 56, 1, 57, 57, 56, 56, 56, 56, 56, 56, 56, 58, 58, 58, 58, 58, 58, 58, 58, 59, 56, 56, 56, 56, 56, 56, 56, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 56, 56, 56, 58, 58, 58, 58, 58, 58, 56, 56, 56, 58, 58, 58, 58, 58, 0, 56, 56, 56 } ; static yyconst flex_int16_t yy_nxt[180] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 13, 15, 13, 13, 16, 17, 13, 13, 18, 13, 19, 13, 13, 14, 13, 15, 13, 13, 16, 17, 13, 13, 18, 13, 19, 24, 25, 27, 28, 56, 56, 56, 56, 30, 56, 31, 32, 29, 56, 34, 56, 33, 35, 36, 37, 26, 41, 30, 48, 31, 40, 32, 56, 34, 56, 33, 35, 36, 37, 27, 25, 26, 27, 28, 40, 39, 39, 46, 30, 41, 56, 42, 56, 56, 56, 43, 49, 56, 50, 39, 39, 46, 30, 44, 45, 56, 47, 56, 42, 56, 43, 50, 56, 56, 56, 56, 50, 44, 45, 53, 47, 55, 54, 48, 51, 52, 56, 56, 48, 56, 56, 56, 26, 53, 22, 55, 54, 56, 51, 52, 20, 20, 20, 38, 26, 38, 23, 22, 56, 21, 21, 5, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 } ; static yyconst flex_int16_t yy_chk[180] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 12, 12, 14, 16, 18, 17, 12, 15, 14, 15, 58, 19, 17, 55, 16, 17, 18, 19, 26, 39, 12, 39, 14, 26, 15, 36, 17, 54, 16, 17, 18, 19, 25, 25, 27, 28, 28, 26, 25, 27, 36, 28, 30, 30, 30, 31, 37, 32, 31, 40, 34, 40, 25, 27, 36, 28, 32, 34, 53, 37, 42, 42, 43, 31, 50, 44, 46, 51, 52, 49, 32, 34, 46, 37, 52, 51, 48, 43, 44, 47, 45, 41, 35, 33, 29, 24, 46, 22, 52, 51, 13, 43, 44, 57, 57, 57, 59, 11, 59, 9, 7, 5, 4, 3, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lutlex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "lutlex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "util.h" #include "lutparser.H" extern YYSTYPE* rgblval; extern rgbFlexLexer* rgblexx; /* rules */ #line 478 "lutlex.C" #define INITIAL 0 #define DISCARD 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 31 "lutlex.L" #line 582 "lutlex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 57 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 56 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 33 "lutlex.L" { // special case-- #\n BEGIN INITIAL; yyless(0); // put back the terminator strcpy(rgblval->str,""); // feed a blank string return STRING; } YY_BREAK case 2: YY_RULE_SETUP #line 40 "lutlex.L" { // Discard reset of line BEGIN INITIAL; int ll = yyleng <(LUTBUFSIZE-1) ? yyleng:(LUTBUFSIZE-1); strncpy(rgblval->str,yytext,ll); rgblval->str[ll] = '\0'; return STRING; } YY_BREAK case 3: YY_RULE_SETUP #line 48 "lutlex.L" {return DEBUG_;} YY_BREAK case 4: YY_RULE_SETUP #line 49 "lutlex.L" {return FALSE_;} YY_BREAK case 5: YY_RULE_SETUP #line 50 "lutlex.L" {return NO_;} YY_BREAK case 6: YY_RULE_SETUP #line 51 "lutlex.L" {return OFF_;} YY_BREAK case 7: YY_RULE_SETUP #line 52 "lutlex.L" {return ON_;} YY_BREAK case 8: YY_RULE_SETUP #line 53 "lutlex.L" {return TRUE_;} YY_BREAK case 9: YY_RULE_SETUP #line 54 "lutlex.L" {return YES_;} YY_BREAK case 10: YY_RULE_SETUP #line 56 "lutlex.L" { // Integer rgblval->integer = atoi(yytext); return INT; } YY_BREAK case 11: #line 62 "lutlex.L" case 12: YY_RULE_SETUP #line 62 "lutlex.L" { // Real Number rgblval->real = atof(yytext); return REAL; } YY_BREAK case 13: YY_RULE_SETUP #line 67 "lutlex.L" { // General String int ll = yyleng <(LUTBUFSIZE-1) ? yyleng:(LUTBUFSIZE-1); strncpy(rgblval->str,yytext,ll); rgblval->str[ll] = '\0'; return STRING; } YY_BREAK case 14: YY_RULE_SETUP #line 74 "lutlex.L" { // White Spaces } YY_BREAK case 15: /* rule 15 can match eol */ YY_RULE_SETUP #line 77 "lutlex.L" { // windows line feed return '\n'; } YY_BREAK case 16: /* rule 16 can match eol */ YY_RULE_SETUP #line 81 "lutlex.L" { // linefeed return '\n'; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DISCARD): #line 85 "lutlex.L" { // eof return EOF_; } YY_BREAK case 17: YY_RULE_SETUP #line 89 "lutlex.L" { // Else, return the char return toupper(yytext[0]); } YY_BREAK case 18: YY_RULE_SETUP #line 93 "lutlex.L" ECHO; YY_BREAK #line 787 "lutlex.C" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; rgbfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); rgbfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ rgbrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) rgbrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 57 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 57 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 56); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) rgballoc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) rgballoc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) rgbfree((void *) b->yy_ch_buf ); rgbfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)rgballoc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)rgbrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) rgballoc(new_size ); else (yy_start_stack) = (int *) rgbrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *rgballoc (yy_size_t size ) { return (void *) malloc( size ); } void *rgbrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void rgbfree (void * ptr ) { free( (char *) ptr ); /* see rgbrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 93 "lutlex.L" void rgbDiscard(int doit) { if (rgblexx) rgblexx->begin(DISCARD, doit); } void rgbFlexLexer::begin(int which, int doit) { BEGIN which; if (doit) yyless(0); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbar.h������������������������������������������������������������������0000644�0001750�0001750�00000004443�11755003411�016005� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbar_h__ #define __colorbar_h__ #include "colorbarbase.h" #include "colormap.h" #include "colortag.h" #include "list.h" // Colormap(s) are X window Colormap ID's. ColorMapInfo(s) contain a fixed // number of real RGB color cells. RGB Values of ColorMapInfo(s) are // never altered. Colormap(s) are initialized from ColorMapInfo values. // Colormap RGB values will changed, based on user input. class Filter; class Colorbar : public virtual ColorbarBase { public: enum ColorTagAction {NONE,CREATE,START,STOP,MOVE}; protected: List<ColorMapInfo> cmaps; List<ColorTag> ctags; unsigned short* colorIndex; float bias; float contrast; ColorTag* tag; ColorTagAction tagaction; int taginit; private: ColorMapInfo* newColorMap(const char*, const char*); void psHorz(Filter&, int, int); void psVert(Filter&, int, int); protected: void loadDefaultCMaps(); void reset(); int calcContrastBias(int); #ifdef _MACOSX void macosx(float, int, int, const Vector&, const Vector&); #endif #ifdef _WIN32 void win32(float, int, int, const Vector&, const Vector&); #endif public: Colorbar(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~Colorbar(); // commands void adjustCmd(float, float); void getBiasCmd(); void getColorbarCmd(); void getColormapCmd(); void getColormapNameCmd(int); void getColormapFileNameCmd(int); void getContrastCmd(); void getCurrentFileNameCmd(); void getCurrentIDCmd(); void getCurrentNameCmd(); void listIDCmd(); void listNameCmd(); void loadCmd(const char*, const char*); void loadCmd(const char*, const char*, const char*); void mapCmd(char*); void mapCmd(int); void saveCmd(const char*); void saveCmd(int, const char*); void setColorbarCmd(int, float, float, int); void getTagCmd(); void getTagCmd(int,int); void tagCmd(const char*); void tagCmd(int, const Vector&, const char*); void tagDeleteCmd(); void tagDeleteCmd(int,int); void tagEditBeginCmd(int,int,const char*); void tagEditMotionCmd(int,int); void tagEditEndCmd(int,int); void tagLoadCmd(const char*); void tagSaveCmd(const char*); void getRGBChannelCmd(); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgb.C���������������������������������������������������������������0000644�0001750�0001750�00000025360�11700666264�016447� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarrgb.h" #include "util.h" #include "ps.h" ColorbarRGB::ColorbarRGB(Tcl_Interp* i,Tk_Canvas c,Tk_Item* item) : ColorbarBase(i,c,item) { channel = 0; for (int i=0; i<3; i++) { bias[i] = .5; contrast[i] = 1.0; } } // Public Member Functions void ColorbarRGB::adjustCmd(float c, float b) { contrast[channel] = c; bias[channel] = b; updateColors(); } void ColorbarRGB::getBiasCmd() { ostringstream str; str << bias[channel] << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void ColorbarRGB::getColorbarCmd() { ostringstream str; str << "rgb "; for (int i=0; i<3; i++) str << bias[i] << ' '; for (int i=0; i<3; i++) str << contrast[i] << ' '; str << invert << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void ColorbarRGB::getColormapCmd() { // use fixed so that the frame parser will not be confused with an int // as the first number ostringstream str; str << "rgb " << setiosflags(ios::fixed); for (int i=0; i<3; i++) str << bias[i] << ' '; for (int i=0; i<3; i++) str << contrast[i] << ' '; str << invert << ' '; str << (unsigned short*)colorCells << ' ' << colorCount << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void ColorbarRGB::getColormapNameCmd(int id) { Tcl_AppendResult(interp, "rgb", NULL); } void ColorbarRGB::getColormapFileNameCmd(int id) { Tcl_AppendResult(interp, "rgb.rgb", NULL); } void ColorbarRGB::getContrastCmd() { ostringstream str; str << contrast[channel] << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } void ColorbarRGB::getCurrentNameCmd() { Tcl_AppendResult(interp, "rgb", NULL); } void ColorbarRGB::getCurrentIDCmd() { Tcl_AppendResult(interp, "rgb", NULL); } void ColorbarRGB::getCurrentFileNameCmd() { Tcl_AppendResult(interp, "rgb", NULL); } void ColorbarRGB::getRGBChannelCmd() { switch (channel) { case 0: Tcl_AppendResult(interp, "red", NULL); return; case 1: Tcl_AppendResult(interp, "green", NULL); return; case 2: Tcl_AppendResult(interp, "blue", NULL); return; } } void ColorbarRGB::setColorbarCmd(float rb, float gb, float bb, float rc, float gc, float bc, int i) { bias[0] = rb; bias[1] = gb; bias[2] = bb; contrast[0] = rc; contrast[1] = gc; contrast[2] = bc; invert = i; updateColors(); } void ColorbarRGB::setRGBChannelCmd(const char* c) { if (!strncmp(c,"red",3)) channel = 0; else if (!strncmp(c,"gre",3)) channel = 1; else if (!strncmp(c,"blu",3)) channel = 2; else channel = 0; } // Private Member Functions void ColorbarRGB::reset() { for (int i=0; i<3; i++) { bias[i] = .5; contrast[i] = 1.0; } invert = 0; updateColors(); } int ColorbarRGB::calcContrastBias(int i, float bb, float cc) { if (fabs(bb - 0.5) < 0.0001 && fabs(cc - 1.0) < 0.0001) return i; // map i to range of 0 to 1.0 // shift by bias (if invert, bias = 1-bias) // multiply by contrast // shift to center of region // expand back to number of dynamic colors float b = invert ? 1-bb : bb; int r = (int)(((((float)i / colorCount) - b) * cc + .5 ) * colorCount); // clip to bounds if out of range if (r < 0) return 0; else if (r >= colorCount) return colorCount-1; else return r; } void ColorbarRGB::psHorz(Filter& filter, int width, int height) { // red for (int jj=0; jj<(int)(height/3.); jj++) { ostringstream str; for (int ii=0; ii<width; ii++) { unsigned char red = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned char green = 0; unsigned char blue = 0; switch (psColorSpace) { case BW: case GRAY: filter << RGB2Gray(red, green, blue); break; case RGB: filter << red << green << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter; } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } // green for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) { ostringstream str; for (int ii=0; ii<width; ii++) { unsigned char red = 0; unsigned char green = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned char blue = 0; switch (psColorSpace) { case BW: case GRAY: filter << RGB2Gray(red, green, blue); break; case RGB: filter << red << green << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter; } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } // blue for (int jj=(int)(height*2/3.); jj<height; jj++) { ostringstream str; for (int ii=0; ii<width; ii++) { unsigned char red = 0; unsigned char green = 0; unsigned char blue = colorCells[(int)(double(ii)/width*colorCount)*3]; switch (psColorSpace) { case BW: case GRAY: filter << RGB2Gray(red, green, blue); break; case RGB: filter << red << green << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; RGB2CMYK(red, green, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } break; } str << filter; } str << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } void ColorbarRGB::psVert(Filter& filter, int width, int height) { for (int jj=0; jj<height; jj++) { ostringstream str; int kk = (int)(double(jj)/height*colorCount)*3; unsigned char red = colorCells[kk+2]; unsigned char green = colorCells[kk+1]; unsigned char blue = colorCells[kk]; switch (psColorSpace) { case BW: case GRAY: for (int ii=0; ii<(int)(width/3.); ii++) filter << RGB2Gray(red, 0, 0); for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) filter << RGB2Gray(0, green, 0); for (int ii=(int)(width*2/3.); ii<width; ii++) filter << RGB2Gray(0, 0, blue); break; case RGB: for (int ii=0; ii<(int)(width/3.); ii++) filter << red << 0 << 0; for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) filter << 0 << green << 0; for (int ii=(int)(width*2/3.); ii<width; ii++) filter << 0 << 0 << blue; break; case CMYK: { unsigned char cyan, magenta, yellow, black; for (int ii=0; ii<(int)(width/3.); ii++) { RGB2CMYK(red, 0, 0, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { RGB2CMYK(0, green, 0, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } for (int ii=(int)(width*2/3.); ii<width; ii++) { RGB2CMYK(0, 0, blue, &cyan, &magenta, &yellow, &black); filter << cyan << magenta << yellow << black; } } break; } str << filter << ends; Tcl_AppendResult(interp, str.str().c_str(), NULL); } } #ifdef _MACOSX void ColorbarRGB::macosx(float scale, int width, int height, const Vector& v, const Vector& s) { if (!colorCells) return; // destination unsigned char* dst = new unsigned char[width*height*4]; unsigned char* dptr = dst; if (!((ColorbarBaseOptions*)options)->orientation) { // blue for (int jj=0; jj<(int)(height/3.); jj++) for (int ii=0; ii<width; ii++) { *dptr++ = 0; *dptr++ = 0; *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3]; *dptr++ = 0; } // green for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) for (int ii=0; ii<width; ii++) { *dptr++ = 0; *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3+1]; *dptr++ = 0; *dptr++ = 0; } // red for (int jj=(int)(height*2/3.); jj<height; jj++) for (int ii=0; ii<width; ii++) { *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3+2]; *dptr++ = 0; *dptr++ = 0; *dptr++ = 0; } } else { for (int jj=0; jj<height; jj++) { int kk = (int)(double(jj)/height*colorCount)*3; // blue for (int ii=0; ii<(int)(width/3.); ii++) { *dptr++ = 0; *dptr++ = 0; *dptr++ = colorCells[kk]; *dptr++ = 0; } // green for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { *dptr++ = 0; *dptr++ = colorCells[kk+1]; *dptr++ = 0; *dptr++ = 0; } // red for (int ii=(int)(width*2/3.); ii<width; ii++) { *dptr++ = colorCells[kk+2]; *dptr++ = 0; *dptr++ = 0; *dptr++ = 0; } } } macosxBitmapCreate(dst, width, height, v, s); if (dst) delete [] dst; } #endif #ifdef _WIN32 void ColorbarRGB::win32(float scale, int width, int height, const Vector& v, const Vector& s) { if (!colorCells) return; // destination (width must be aligned on 4-byte DWORD boundary) int jjwidth=(((width+3)/4)*4); // extra alignment padding which we have to skip over for each row int jjpad=(jjwidth-width)*3; unsigned char* dst = new unsigned char[jjwidth*height*3]; if (!dst) return; memset(dst, '\0', jjwidth*height*3); unsigned char* dptr = dst; if (!((ColorbarBaseOptions*)options)->orientation) { // blue for (int jj=0; jj<(int)(height/3.); jj++) { for (int ii=0; ii<width; ii++) { *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3]; *dptr++ = 0; *dptr++ = 0; } dptr += jjpad; } // green for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) { for (int ii=0; ii<width; ii++) { *dptr++ = 0; *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3+1]; *dptr++ = 0; } dptr += jjpad; } // red for (int jj=(int)(height*2/3.); jj<height; jj++) { for (int ii=0; ii<width; ii++) { *dptr++ = 0; *dptr++ = 0; *dptr++ = colorCells[(int)(double(ii)/width*colorCount)*3+2]; } dptr += jjpad; } } else { for (int jj=0; jj<height; jj++) { int kk = (int)(double(jj)/height*colorCount)*3; // blue for (int ii=0; ii<(int)(width/3.); ii++) { *dptr++ = colorCells[kk]; *dptr++ = 0; *dptr++ = 0; } dptr += jjpad; // green for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { *dptr++ = 0; *dptr++ = colorCells[kk+1]; *dptr++ = 0; } dptr += jjpad; // red for (int ii=(int)(width*2/3.); ii<width; ii++) { *dptr++ = 0; *dptr++ = 0; *dptr++ = colorCells[kk+2]; } dptr += jjpad; } } win32Clip(v,s); win32BitmapCreate(dst, jjwidth, height, v, s); win32Clip(Vector(INT_MIN,INT_MIN),Vector(INT_MAX,INT_MAX)); if (dst) delete [] dst; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lut.h�����������������������������������������������������������������������0000644�0001750�0001750�00000003317�11743600735�015016� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __lut_h__ #define __lut_h__ #include "colormap.h" #include "list.h" // RGBColor class RGBColor { private: float red_; float green_; float blue_; RGBColor* next_; RGBColor* previous_; public: RGBColor() {red_=green_=blue_=0;} RGBColor(float r, float g, float b) {red_=r; green_=g; blue_=b;} RGBColor(const RGBColor& a) { red_=a.red_; green_=a.green_; blue_=a.blue_; next_=a.next_; previous_=a.previous_; } RGBColor& operator=(const RGBColor& a) { red_=a.red_; green_=a.green_; blue_=a.blue_; next_=a.next_; previous_=a.previous_; return *this; } RGBColor* next() {return next_;} RGBColor* previous() {return previous_;} void setNext(RGBColor* n) {next_ = n;} void setPrevious(RGBColor* p) {previous_=p;} float red() {return red_;} float green() {return green_;} float blue() {return blue_;} friend istream& operator>>(istream&, RGBColor&); friend ostream& operator<<(ostream&, RGBColor&); }; // LUTColorMap class LUTColorMap : public ColorMapInfo { protected: List<RGBColor> colors; public: LUTColorMap(Colorbar* p); ColorMapInfo* dup() {return new LUTColorMap(*this);} int load(); int load(const char* var); void save(const char*); unsigned char getRedChar(int, int); unsigned char getGreenChar(int, int); unsigned char getBlueChar(int, int); unsigned short getRedShrt(int, int); unsigned short getGreenShrt(int, int); unsigned short getBlueShrt(int, int); void newRGBColor(float,float,float); friend ostream& operator<<(ostream&, LUTColorMap&); }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarpseudocolor8.C������������������������������������������������������0000644�0001750�0001750�00000014770�11700666264�020326� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "colorbarpseudocolor8.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarPseudoColor8CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Colorbar Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarPseudoColor8Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbar", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-min", NULL, NULL, "80", Tk_Offset(ColorbarBaseOptions, minColors), 0, NULL}, {TK_CONFIG_INT, (char*)"-max", NULL, NULL, "200", Tk_Offset(ColorbarBaseOptions, maxColors), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-private", NULL, NULL, "false", Tk_Offset(ColorbarBaseOptions, privateCmap), 0, NULL}, {TK_CONFIG_INT, (char*)"-privatecolors", NULL, NULL, "128", Tk_Offset(ColorbarBaseOptions, privateColors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarPseudoColor8Type = { (char*)"colorbarpseudocolor8", // name sizeof(ColorbarBaseOptions), // size ColorbarPseudoColor8CreateProc, // configProc colorbarPseudoColor8Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarPseudoColor8_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarPseudoColor8Type); return TCL_OK; } int ColorbarPseudoColor8CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarPseudoColor8* colorbar = new ColorbarPseudoColor8(interp, canvas, item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarPseudoColor8 ColorbarPseudoColor8::ColorbarPseudoColor8(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarPseudoColor(i,c,item) { configSpecs = colorbarPseudoColor8Specs; // colorbar configure options loadDefaultCMaps(); } // UpdatePixmap. This function is responsable for creating a valid // pixmap the size of the current Colorbar void ColorbarPseudoColor8::ximageToPixmap() { if (!((ColorbarBaseOptions*)options)->orientation) { ximageToPixmapHorz(); XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, options->width-2, ((ColorbarBaseOptions*)options)->size-2); } else { ximageToPixmapVert(); XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, ((ColorbarBaseOptions*)options)->size-2, options->height-2); } } void ColorbarPseudoColor8::ximageToPixmapHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); // Fill in colorbar data // --Calculate first row for (int ii=0; ii<width; ii++) data[ii] = (char)colorIndex[ii*colorCount/width]; // --and duplicate for remaining rows for (int jj=1; jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line); } void ColorbarPseudoColor8::ximageToPixmapVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { char a = (char)colorIndex[jj*colorCount/height]; for (int ii=0; ii<width; ii++) data[ii] = a; } } ��������./saods9/saotk/colorbar/colorbarrgbtruecolor24.h����������������������������������������������������0000644�0001750�0001750�00000001277�11700666264�020622� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarrgbtruecolor24_h__ #define __colorbarrgbtruecolor24_h__ #include "colorbarrgbtruecolor.h" #include "truecolor24.h" class ColorbarRGBTrueColor24 : public ColorbarRGBTrueColor, public TrueColor24 { private: void updateColorsHorz(); void updateColorsVert(); void updateColors24Horz(int, int, char*); void updateColors24Vert(int, int, char*); void updateColors32Horz(int, int, char*); void updateColors32Vert(int, int, char*); public: ColorbarRGBTrueColor24(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor16.h����������������������������������������������������0000644�0001750�0001750�00000001010�11700666264�020604� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarrgbtruecolor16_h__ #define __colorbarrgbtruecolor16_h__ #include "colorbarrgbtruecolor.h" #include "truecolor16.h" class ColorbarRGBTrueColor16 : public ColorbarRGBTrueColor, TrueColor16 { private: void updateColorsHorz(); void updateColorsVert(); public: ColorbarRGBTrueColor16(Tcl_Interp*, Tk_Canvas, Tk_Item*); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarbase.h��������������������������������������������������������������0000644�0001750�0001750�00000011014�11755003411�016630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colorbarbase_h__ #define __colorbarbase_h__ #include "widget.h" #include <X11/Xlib.h> #include <X11/Xutil.h> // Widget ConfigSpecs Defines #define CONFIGORIENTATION 7 #define CONFIGSIZE 8 #define CONFIGFONT 9 #define CONFIGFONTSTYLE 10 #define CONFIGFONTSIZE 11 #define CONFIGNUMERICS 12 #define CONFIGSPACE 13 #define CONFIGTICKS 14 // ColorbarBase class CBGrid; class Filter; class ColorTag; struct ColorbarBaseOptions { Tk_Item item; // required by tk int x, y; // Coordinates of positioning point on canvas int width; // widget width int height; // widget height Tk_Anchor anchor; // Where to anchor widget relative to x,y char* cmdName; // Suggested Tcl command name char* helvetica; // name of X11 font char* courier; // name of X11 font char* times; // name of X11 font Widget* widget; // pointer to widget class int orientation; // 0-horizontal, 1-vertical int size; char* font; int fontSize; char* fontWeight; char* fontSlant; int numerics; int space; // 0-distance (linear), 1-value (AST) int ticks; int colors; int minColors; int maxColors; int privateCmap; int privateColors; }; class ColorbarBase : public Widget { friend class CBGrid; friend class ColorTag; protected: XImage* xmap; unsigned char* colorCells; int colorCount; CBGrid* grid; GC gc; int cnt; double* lut; int invert; char** ticktxt; int tickcnt; int skipcnt; private: Tk_Font getFont(); void lutToText(Tk_Font); void renderGrid(); void renderGridNumerics(); void renderGridAST(); void ps(); void psHV(Filter&, int, int); void psGrid(); void psGridNumerics(); void psGridAST(); #ifdef _MACOSX void macosxGrid(); void macosxGridNumerics(); void macosxGridAST(); #endif #ifdef _WIN32 void win32Grid(); void win32GridNumerics(); void win32GridAST(); #endif protected: virtual int initColormap() =0; void invalidPixmap(); int postscriptProc(int); // generate postscript virtual void psHorz(Filter&, int, int) =0; virtual void psVert(Filter&, int, int) =0; virtual void reset() =0; virtual void updateColors() =0; int updatePixmap(const BBox&); virtual void ximageToPixmap() =0; #ifdef _MACOSX virtual void macosx(float, int, int, const Vector&, const Vector&) =0; #endif #ifdef _WIN32 virtual void win32(float, int, int, const Vector&, const Vector&) =0; #endif public: ColorbarBase(Tcl_Interp*, Tk_Canvas, Tk_Item*); virtual ~ColorbarBase(); virtual void adjustCmd(float, float) =0; int configure(int, const char* [], int); virtual void getBiasCmd() =0; virtual void getColorbarCmd() =0; virtual void getColormapCmd() =0; virtual void getColormapNameCmd(int) =0; virtual void getColormapFileNameCmd(int) =0; virtual void getContrastCmd() =0; virtual void getCurrentFileNameCmd() =0; virtual void getCurrentIDCmd() =0; virtual void getCurrentNameCmd() =0; void getInvertCmd(); void getNumericsCmd(); virtual void getRGBChannelCmd() =0; void getValueCmd(int,int); void invertCmd(int); virtual void listIDCmd() {} virtual void listNameCmd() {} virtual void loadCmd(const char*, const char*) {} virtual void loadCmd(const char*, const char*, const char*) {} virtual void mapCmd(char*) {} virtual void mapCmd(int) {} int parse(istringstream&); virtual void saveCmd(const char*) {} virtual void saveCmd(int, const char*) {} virtual void setColorbarCmd(int, float, float, int) {} virtual void setColorbarCmd(float, float, float, float, float, float, int) {} void setColormapLevelCmd(); void setColormapLevelCmd(int, double*); virtual void setColormapWindowCmd(char*) {} virtual void setRGBChannelCmd(const char*) {} virtual void getTagCmd() {} virtual void getTagCmd(int,int) {} virtual void tagCmd(const char*) {} virtual void tagCmd(int, const Vector&, const char*) {} virtual void tagDeleteCmd() {} virtual void tagDeleteCmd(int,int) {} virtual void tagEditBeginCmd(int,int,const char*) {} virtual void tagEditMotionCmd(int,int) {} virtual void tagEditEndCmd(int,int) {} virtual void tagLoadCmd(const char*) {} virtual void tagSaveCmd(const char*) {} #ifdef _MACOSX void macosxPrintCmd(); #endif #ifdef _WIN32 void win32PrintCmd(); #endif }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbartrue.C��������������������������������������������������������������0000644�0001750�0001750�00000001534�11700666264�016651� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "tcl.h" #include "colorbartrue.h" #include "util.h" ColorbarTrue::ColorbarTrue(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item) { } void ColorbarTrue::updateColors() { updateColorCells(); // fill in xmap // make sure we have a pixmap if (!pixmap || !xmap) return; if (!((ColorbarBaseOptions*)options)->orientation) { updateColorsHorz(); XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, options->width-2, ((ColorbarBaseOptions*)options)->size-2); } else { updateColorsVert(); XPutImage(display, pixmap, gc, xmap, 0, 0, 1, 1, ((ColorbarBaseOptions*)options)->size-2, options->height-2); } redraw(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lex.C�����������������������������������������������������������������������0000644�0001750�0001750�00000156202�12032637771�014741� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "lex.C" #line 4 "lex.C" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* The c++ scanner is a mess. The FlexLexer.h header file relies on the * following macro. This is required in order to pass the c++-multiple-scanners * test in the regression suite. We get reports that it breaks inheritance. * We will address this in a future release of flex, or omit the C++ scanner * altogether. */ #define yyFlexLexer cbFlexLexer /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ #include <iostream> #include <errno.h> #include <cstdlib> #include <cstring> /* end standard C++ headers. */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { std::istream* yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] void *cballoc (yy_size_t ); void *cbrealloc (void *,yy_size_t ); void cbfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; #define yytext_ptr yytext #include <FlexLexer.h> int yyFlexLexer::yywrap() { return 1; } /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 62 #define YY_END_OF_BUFFER 63 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[234] = { 0, 0, 0, 63, 61, 60, 62, 61, 61, 61, 61, 61, 52, 52, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 30, 61, 61, 61, 61, 61, 61, 61, 50, 61, 60, 59, 0, 59, 56, 0, 59, 57, 59, 52, 54, 53, 59, 59, 59, 59, 59, 4, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 21, 59, 59, 59, 59, 59, 59, 59, 59, 32, 59, 34, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 59, 58, 56, 57, 59, 59, 53, 55, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 14, 59, 59, 15, 59, 59, 59, 59, 23, 59, 59, 59, 59, 28, 59, 59, 33, 59, 59, 59, 39, 59, 59, 42, 59, 59, 45, 59, 59, 59, 51, 58, 59, 54, 59, 59, 3, 59, 6, 59, 59, 59, 59, 13, 59, 18, 16, 59, 20, 59, 59, 25, 26, 59, 59, 31, 59, 59, 59, 59, 40, 41, 43, 59, 59, 59, 59, 59, 59, 2, 59, 59, 59, 11, 59, 17, 59, 59, 24, 59, 59, 59, 36, 37, 59, 44, 59, 47, 48, 59, 1, 59, 59, 59, 59, 59, 12, 19, 22, 27, 29, 59, 59, 59, 49, 5, 59, 59, 59, 59, 59, 59, 46, 8, 7, 59, 10, 59, 59, 59, 59, 59, 9, 35, 38, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 4, 4, 4, 4, 6, 4, 4, 4, 7, 4, 7, 8, 4, 9, 10, 11, 12, 10, 10, 10, 10, 10, 10, 4, 4, 4, 4, 4, 4, 4, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 4, 29, 30, 31, 32, 33, 34, 35, 36, 4, 4, 4, 4, 4, 4, 4, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 4, 53, 54, 55, 56, 57, 58, 59, 60, 4, 61, 4, 62, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[63] = { 0, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } ; static yyconst flex_int16_t yy_base[241] = { 0, 0, 0, 183, 557, 180, 557, 0, 62, 64, 63, 67, 72, 82, 69, 80, 75, 69, 72, 83, 86, 112, 114, 115, 121, 122, 125, 117, 133, 142, 134, 124, 66, 160, 116, 114, 0, 103, 179, 0, 100, 187, 0, 185, 194, 198, 207, 216, 240, 168, 179, 199, 0, 200, 184, 214, 245, 200, 225, 218, 219, 215, 234, 239, 245, 0, 230, 237, 239, 243, 261, 260, 245, 261, 0, 271, 0, 260, 270, 264, 281, 268, 275, 284, 272, 282, 276, 291, 278, 43, 319, 0, 557, 557, 222, 327, 333, 0, 277, 295, 292, 297, 301, 307, 318, 318, 334, 321, 0, 323, 337, 0, 319, 337, 342, 343, 0, 344, 331, 347, 337, 0, 344, 349, 0, 336, 342, 355, 0, 352, 336, 0, 354, 365, 0, 368, 368, 388, 0, 557, 398, 402, 371, 376, 0, 377, 0, 376, 386, 397, 386, 0, 401, 0, 0, 399, 0, 391, 400, 0, 0, 400, 404, 0, 402, 402, 403, 411, 0, 0, 0, 419, 416, 418, 58, 418, 415, 0, 430, 438, 436, 0, 433, 0, 420, 422, 0, 429, 439, 451, 0, 0, 435, 0, 445, 0, 0, 444, 0, 455, 467, 468, 454, 453, 0, 0, 0, 0, 0, 455, 454, 460, 0, 0, 464, 466, 482, 466, 477, 478, 0, 0, 0, 485, 0, 473, 484, 495, 482, 488, 0, 0, 0, 557, 65, 538, 541, 544, 547, 550, 553 } ; static yyconst flex_int16_t yy_def[241] = { 0, 233, 1, 233, 233, 233, 233, 234, 235, 236, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 237, 233, 234, 238, 235, 234, 239, 236, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 240, 237, 234, 233, 233, 234, 234, 234, 48, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 0, 233, 233, 233, 233, 233, 233, 233 } ; static yyconst flex_int16_t yy_nxt[620] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 7, 7, 23, 24, 25, 26, 27, 28, 29, 30, 7, 31, 32, 7, 33, 14, 15, 16, 17, 18, 19, 20, 21, 22, 7, 7, 23, 24, 25, 26, 27, 28, 29, 30, 7, 31, 32, 7, 33, 34, 7, 37, 37, 40, 40, 39, 36, 196, 42, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 44, 44, 44, 44, 49, 56, 87, 57, 47, 46, 44, 44, 44, 44, 53, 59, 50, 58, 47, 54, 51, 55, 61, 60, 139, 93, 48, 92, 49, 56, 87, 57, 47, 52, 62, 35, 89, 89, 53, 59, 50, 58, 47, 54, 51, 55, 61, 60, 63, 65, 48, 68, 64, 71, 73, 69, 85, 52, 62, 66, 86, 70, 75, 77, 67, 78, 83, 72, 74, 79, 76, 80, 63, 65, 81, 68, 64, 71, 73, 69, 85, 82, 84, 66, 86, 70, 75, 77, 67, 78, 83, 72, 74, 79, 76, 80, 88, 91, 81, 37, 37, 35, 233, 39, 233, 82, 84, 40, 40, 98, 233, 233, 42, 45, 45, 45, 45, 99, 233, 233, 88, 46, 44, 44, 44, 44, 45, 45, 45, 45, 47, 100, 101, 98, 94, 45, 45, 45, 45, 102, 107, 99, 95, 47, 96, 96, 96, 96, 140, 233, 141, 141, 141, 141, 47, 100, 101, 103, 94, 104, 108, 109, 110, 102, 107, 111, 112, 47, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 105, 113, 114, 103, 115, 104, 108, 109, 110, 116, 106, 111, 112, 117, 118, 119, 120, 122, 97, 97, 97, 97, 97, 97, 105, 113, 114, 123, 115, 121, 124, 125, 126, 116, 106, 127, 128, 117, 118, 119, 120, 122, 129, 130, 131, 132, 135, 133, 136, 138, 142, 123, 134, 121, 124, 125, 126, 143, 137, 127, 128, 89, 89, 144, 145, 146, 129, 130, 131, 132, 135, 133, 136, 138, 142, 147, 134, 96, 96, 96, 96, 143, 137, 96, 96, 96, 96, 144, 145, 146, 148, 149, 150, 151, 152, 153, 154, 155, 233, 147, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 168, 169, 170, 166, 148, 149, 150, 151, 152, 153, 154, 155, 91, 167, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 168, 169, 170, 166, 171, 172, 173, 174, 176, 177, 178, 175, 179, 167, 141, 141, 141, 141, 141, 141, 141, 141, 180, 181, 182, 183, 184, 185, 171, 172, 173, 186, 176, 177, 178, 175, 179, 187, 188, 189, 190, 191, 192, 193, 194, 195, 180, 181, 182, 183, 184, 185, 197, 198, 199, 186, 203, 204, 205, 200, 206, 187, 188, 189, 190, 191, 192, 193, 194, 195, 201, 207, 208, 209, 210, 202, 197, 198, 199, 211, 203, 204, 205, 200, 206, 212, 213, 214, 215, 216, 217, 218, 219, 220, 201, 207, 208, 209, 210, 202, 221, 222, 223, 211, 224, 225, 226, 227, 228, 212, 213, 214, 215, 216, 217, 218, 219, 220, 229, 230, 231, 232, 233, 233, 221, 222, 223, 233, 224, 225, 226, 227, 228, 233, 233, 233, 233, 233, 233, 233, 233, 233, 229, 230, 231, 232, 38, 233, 38, 41, 233, 41, 90, 233, 90, 37, 233, 37, 40, 233, 40, 89, 233, 89, 3, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233 } ; static yyconst flex_int16_t yy_chk[620] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 9, 9, 8, 234, 174, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 14, 17, 32, 18, 12, 13, 13, 13, 13, 13, 16, 19, 15, 18, 13, 16, 15, 16, 20, 19, 89, 40, 12, 37, 14, 17, 32, 18, 12, 15, 20, 35, 34, 34, 16, 19, 15, 18, 13, 16, 15, 16, 20, 19, 21, 22, 12, 23, 21, 24, 25, 23, 31, 15, 20, 22, 31, 23, 26, 27, 22, 27, 30, 24, 25, 28, 26, 28, 21, 22, 29, 23, 21, 24, 25, 23, 31, 29, 30, 22, 31, 23, 26, 27, 22, 27, 30, 24, 25, 28, 26, 28, 33, 34, 29, 38, 38, 5, 3, 38, 0, 29, 30, 41, 41, 49, 0, 0, 41, 43, 43, 43, 43, 50, 0, 0, 33, 44, 44, 44, 44, 44, 45, 45, 45, 45, 44, 51, 53, 49, 45, 46, 46, 46, 46, 54, 57, 50, 47, 46, 47, 47, 47, 47, 94, 0, 94, 94, 94, 94, 44, 51, 53, 55, 45, 55, 58, 59, 60, 54, 57, 61, 62, 46, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, 63, 64, 55, 66, 55, 58, 59, 60, 67, 56, 61, 62, 68, 69, 70, 71, 72, 48, 48, 48, 48, 48, 48, 56, 63, 64, 73, 66, 71, 75, 77, 78, 67, 56, 79, 80, 68, 69, 70, 71, 72, 81, 82, 83, 84, 86, 85, 87, 88, 98, 73, 85, 71, 75, 77, 78, 99, 87, 79, 80, 90, 90, 100, 101, 102, 81, 82, 83, 84, 86, 85, 87, 88, 98, 103, 85, 95, 95, 95, 95, 99, 87, 96, 96, 96, 96, 100, 101, 102, 104, 105, 106, 107, 109, 110, 112, 113, 0, 103, 114, 115, 117, 118, 119, 120, 122, 123, 125, 126, 129, 130, 132, 127, 104, 105, 106, 107, 109, 110, 112, 113, 90, 127, 114, 115, 117, 118, 119, 120, 122, 123, 125, 126, 129, 130, 132, 127, 133, 135, 136, 137, 142, 143, 145, 137, 147, 127, 140, 140, 140, 140, 141, 141, 141, 141, 148, 149, 150, 152, 155, 157, 133, 135, 136, 158, 142, 143, 145, 137, 147, 161, 162, 164, 165, 166, 167, 171, 172, 173, 148, 149, 150, 152, 155, 157, 175, 176, 178, 158, 180, 182, 184, 179, 185, 161, 162, 164, 165, 166, 167, 171, 172, 173, 179, 187, 188, 189, 192, 179, 175, 176, 178, 194, 180, 182, 184, 179, 185, 197, 199, 200, 201, 202, 203, 209, 210, 211, 179, 187, 188, 189, 192, 179, 214, 215, 216, 194, 217, 218, 219, 223, 225, 197, 199, 200, 201, 202, 203, 209, 210, 211, 226, 227, 228, 229, 0, 0, 214, 215, 216, 0, 217, 218, 219, 223, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 227, 228, 229, 235, 0, 235, 236, 0, 236, 237, 0, 237, 238, 0, 238, 239, 0, 239, 240, 0, 240, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "lex.L" /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ #line 12 "lex.L" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "parser.H" extern YYSTYPE* cblval; /* rules */ #line 635 "lex.C" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO #define ECHO LexerOutput( yytext, yyleng ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) LexerError( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 #define YY_DECL int yyFlexLexer::yylex() #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 26 "lex.L" #line 738 "lex.C" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = & std::cin; if ( ! yyout ) yyout = & std::cout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 234 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 233 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 28 "lex.L" {return ADJUST_;} YY_BREAK case 2: YY_RULE_SETUP #line 29 "lex.L" {return BEGIN_;} YY_BREAK case 3: YY_RULE_SETUP #line 30 "lex.L" {return BIAS_;} YY_BREAK case 4: YY_RULE_SETUP #line 31 "lex.L" {return BW_;} YY_BREAK case 5: YY_RULE_SETUP #line 32 "lex.L" {return CHANNEL_;} YY_BREAK case 6: YY_RULE_SETUP #line 33 "lex.L" {return CMYK_;} YY_BREAK case 7: YY_RULE_SETUP #line 34 "lex.L" {return COLORMAP_;} YY_BREAK case 8: YY_RULE_SETUP #line 35 "lex.L" {return COLORBAR_;} YY_BREAK case 9: YY_RULE_SETUP #line 36 "lex.L" {return COLORSPACE_;} YY_BREAK case 10: YY_RULE_SETUP #line 37 "lex.L" {return CONTRAST_;} YY_BREAK case 11: YY_RULE_SETUP #line 38 "lex.L" {return DEBUG_;} YY_BREAK case 12: YY_RULE_SETUP #line 39 "lex.L" {return DELETE_;} YY_BREAK case 13: YY_RULE_SETUP #line 40 "lex.L" {return EDIT_;} YY_BREAK case 14: YY_RULE_SETUP #line 41 "lex.L" {return END_;} YY_BREAK case 15: YY_RULE_SETUP #line 42 "lex.L" {return GET_;} YY_BREAK case 16: YY_RULE_SETUP #line 43 "lex.L" {return GRAY_;} YY_BREAK case 17: YY_RULE_SETUP #line 44 "lex.L" {return FALSE_;} YY_BREAK case 18: YY_RULE_SETUP #line 45 "lex.L" {return FILE_;} YY_BREAK case 19: YY_RULE_SETUP #line 46 "lex.L" {return HEIGHT_;} YY_BREAK case 20: YY_RULE_SETUP #line 47 "lex.L" {return HIDE_;} YY_BREAK case 21: YY_RULE_SETUP #line 48 "lex.L" {return ID_;} YY_BREAK case 22: YY_RULE_SETUP #line 49 "lex.L" {return INVERT_;} YY_BREAK case 23: YY_RULE_SETUP #line 50 "lex.L" {return ITT_;} YY_BREAK case 24: YY_RULE_SETUP #line 51 "lex.L" {return LEVEL_;} YY_BREAK case 25: YY_RULE_SETUP #line 52 "lex.L" {return LIST_;} YY_BREAK case 26: YY_RULE_SETUP #line 53 "lex.L" {return LOAD_;} YY_BREAK case 27: YY_RULE_SETUP #line 54 "lex.L" {return MACOSX_;} YY_BREAK case 28: YY_RULE_SETUP #line 55 "lex.L" {return MAP_;} YY_BREAK case 29: YY_RULE_SETUP #line 56 "lex.L" {return MOTION_;} YY_BREAK case 30: YY_RULE_SETUP #line 57 "lex.L" {return N_;} YY_BREAK case 31: YY_RULE_SETUP #line 58 "lex.L" {return NAME_;} YY_BREAK case 32: YY_RULE_SETUP #line 59 "lex.L" {return NO_;} YY_BREAK case 33: YY_RULE_SETUP #line 60 "lex.L" {return OFF_;} YY_BREAK case 34: YY_RULE_SETUP #line 61 "lex.L" {return ON_;} YY_BREAK case 35: YY_RULE_SETUP #line 62 "lex.L" {return POSTSCRIPT_;} YY_BREAK case 36: YY_RULE_SETUP #line 63 "lex.L" {return PRINT_;} YY_BREAK case 37: YY_RULE_SETUP #line 64 "lex.L" {return RESET_;} YY_BREAK case 38: YY_RULE_SETUP #line 65 "lex.L" {return RESOLUTION_;} YY_BREAK case 39: YY_RULE_SETUP #line 66 "lex.L" {return RGB_;} YY_BREAK case 40: YY_RULE_SETUP #line 67 "lex.L" {return SAVE_;} YY_BREAK case 41: YY_RULE_SETUP #line 68 "lex.L" {return SHOW_;} YY_BREAK case 42: YY_RULE_SETUP #line 69 "lex.L" {return TAG_;} YY_BREAK case 43: YY_RULE_SETUP #line 70 "lex.L" {return TRUE_;} YY_BREAK case 44: YY_RULE_SETUP #line 71 "lex.L" {return VALUE_;} YY_BREAK case 45: YY_RULE_SETUP #line 72 "lex.L" {return VAR_;} YY_BREAK case 46: YY_RULE_SETUP #line 73 "lex.L" {return VERSION_;} YY_BREAK case 47: YY_RULE_SETUP #line 74 "lex.L" {return WIDTH_;} YY_BREAK case 48: YY_RULE_SETUP #line 75 "lex.L" {return WIN32_;} YY_BREAK case 49: YY_RULE_SETUP #line 76 "lex.L" {return WINDOW_;} YY_BREAK case 50: YY_RULE_SETUP #line 77 "lex.L" {return Y_;} YY_BREAK case 51: YY_RULE_SETUP #line 78 "lex.L" {return YES_;} YY_BREAK case 52: YY_RULE_SETUP #line 80 "lex.L" { // Integer cblval->integer = atoi(yytext); return INT; } YY_BREAK case 53: #line 86 "lex.L" case 54: YY_RULE_SETUP #line 86 "lex.L" { // Real Number cblval->real = atof(yytext); return REAL; } YY_BREAK case 55: YY_RULE_SETUP #line 91 "lex.L" { // Pointer cblval->ptr = (void*)strtoul(yytext,NULL,16); return POINTER; } YY_BREAK case 56: #line 97 "lex.L" case 57: YY_RULE_SETUP #line 97 "lex.L" { // Quoted String int ll = (yyleng-2)<(CBBUFSIZE-1) ? (yyleng-2):(CBBUFSIZE-1); strncpy(cblval->str,yytext+1,ll); // skip the " " cblval->str[ll] = '\0'; // Remove the '"' return STRING; } YY_BREAK case 58: YY_RULE_SETUP #line 104 "lex.L" { // Quoted String int ll = (yyleng-2)<(CBBUFSIZE-1) ? (yyleng-2):(CBBUFSIZE-1); strncpy(cblval->str,yytext+1,ll); // skip the '{' cblval->str[ll] = '\0'; // Remove the '}' return STRING; } YY_BREAK case 59: YY_RULE_SETUP #line 111 "lex.L" { // General String-- at least 2 printable chars int ll = yyleng <(CBBUFSIZE-1) ? yyleng:(CBBUFSIZE-1); strncpy(cblval->str,yytext,ll); cblval->str[ll] = '\0'; return STRING; } YY_BREAK case 60: YY_RULE_SETUP #line 118 "lex.L" { // White Spaces } YY_BREAK case 61: YY_RULE_SETUP #line 121 "lex.L" { // Else, return the char return yytext[0]; } YY_BREAK case 62: YY_RULE_SETUP #line 125 "lex.L" ECHO; YY_BREAK #line 1148 "lex.C" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) { yyin = arg_yyin; yyout = arg_yyout; yy_c_buf_p = 0; yy_init = 0; yy_start = 0; yy_flex_debug = 0; yylineno = 1; // this will only get updated if %option yylineno yy_did_buffer_switch_on_eof = 0; yy_looking_for_trail_begin = 0; yy_more_flag = 0; yy_more_len = 0; yy_more_offset = yy_prev_more_offset = 0; yy_start_stack_ptr = yy_start_stack_depth = 0; yy_start_stack = NULL; yy_buffer_stack = 0; yy_buffer_stack_top = 0; yy_buffer_stack_max = 0; yy_state_buf = 0; } /* The contents of this function are C++ specific, so the () macro is not used. */ yyFlexLexer::~yyFlexLexer() { delete [] yy_state_buf; cbfree(yy_start_stack ); yy_delete_buffer( YY_CURRENT_BUFFER ); cbfree(yy_buffer_stack ); } /* The contents of this function are C++ specific, so the () macro is not used. */ void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) { if ( new_in ) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); } if ( new_out ) yyout = new_out; } #ifdef YY_INTERACTIVE size_t yyFlexLexer::LexerInput( char* buf, size_t /* max_size */ ) #else size_t yyFlexLexer::LexerInput( char* buf, size_t max_size ) #endif { if ( yyin->eof() || yyin->fail() ) return 0; #ifdef YY_INTERACTIVE yyin->get( buf[0] ); if ( yyin->eof() ) return 0; if ( yyin->bad() ) return -1; return 1; #else (void) yyin->read( buf, max_size ); if ( yyin->bad() ) return -1; else return yyin->gcount(); #endif } void yyFlexLexer::LexerOutput( const char* buf, size_t size ) { (void) yyout->write( buf, size ); } /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ int yyFlexLexer::yy_get_next_buffer() { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ cbrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cbrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ yy_state_type yyFlexLexer::yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 234 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 234 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 233); return yy_is_jam ? 0 : yy_current_state; } void yyFlexLexer::yyunput( int c, register char* yy_bp) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } int yyFlexLexer::yyinput() { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyFlexLexer::yyrestart( std::istream* input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } void yyFlexLexer::yy_load_buffer_state() { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) cballoc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) cballoc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) cbfree((void *) b->yy_ch_buf ); cbfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yyFlexLexer::yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ void yyFlexLexer::yyensure_buffer_stack(void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)cballoc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)cbrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } void yyFlexLexer::yy_push_state( int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) cballoc(new_size ); else (yy_start_stack) = (int *) cbrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } void yyFlexLexer::yy_pop_state() { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } int yyFlexLexer::yy_top_state() { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif void yyFlexLexer::LexerError( yyconst char msg[] ) { std::cerr << msg << std::endl; exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *cballoc (yy_size_t size ) { return (void *) malloc( size ); } void *cbrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void cbfree (void * ptr ) { free( (char *) ptr ); /* see cbrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 125 "lex.L" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/saoparser.C�����������������������������������������������������������������0000644�0001750�0001750�00000130216�12064133240�016130� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse liparse #define yylex lilex #define yyerror lierror #define yylval lilval #define yychar lichar #define yydebug lidebug #define yynerrs linerrs /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, EOF_ = 261, BLUE_ = 262, DEBUG_ = 263, GAMMA_ = 264, GREEN_ = 265, FALSE_ = 266, NO_ = 267, OFF_ = 268, ON_ = 269, PSEUDOCOLOR_ = 270, RED_ = 271, TRUE_ = 272, YES_ = 273 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define EOF_ 261 #define BLUE_ 262 #define DEBUG_ 263 #define GAMMA_ 264 #define GREEN_ 265 #define FALSE_ 266 #define NO_ 267 #define OFF_ 268 #define ON_ 269 #define PSEUDOCOLOR_ 270 #define RED_ 271 #define TRUE_ 272 #define YES_ 273 /* Copy the first part of user declarations. */ #line 10 "saoparser.Y" #define YYDEBUG 1 #define DISCARD_(x) {yyclearin; liDiscard(x);} #include <string.h> #include <iostream> #include "sao.h" #undef yyFlexLexer #define yyFlexLexer liFlexLexer #include <FlexLexer.h> extern int lilex(void*, liFlexLexer*); extern void lierror(SAOColorMap*, liFlexLexer*, const char*); extern void liDiscard(int); /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "saoparser.Y" { #define SAOBUFSIZE 4096 char str[SAOBUFSIZE]; int integer; float real; } /* Line 193 of yacc.c. */ #line 166 "saoparser.C" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 179 "saoparser.C" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 23 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 36 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 26 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 11 /* YYNRULES -- Number of rules. */ #define YYNRULES 24 /* YYNRULES -- Number of states. */ #define YYNSTATES 40 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 273 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, 2, 2, 21, 23, 2, 2, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20, 25, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 7, 10, 13, 15, 17, 18, 22, 24, 28, 32, 36, 37, 40, 43, 45, 51, 53, 55, 57, 59, 61, 63 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 27, 0, -1, 27, 28, 34, -1, 28, 34, -1, 8, 36, -1, 30, -1, 15, -1, -1, 19, 29, 5, -1, 32, -1, 16, 20, 31, -1, 10, 20, 31, -1, 7, 20, 31, -1, -1, 9, 35, -1, 32, 33, -1, 33, -1, 21, 35, 22, 35, 23, -1, 24, -1, 25, -1, 6, -1, 3, -1, 4, -1, 14, -1, 13, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 59, 59, 60, 63, 64, 65, 66, 66, 67, 70, 71, 72, 75, 76, 79, 80, 83, 86, 87, 88, 91, 92, 95, 96 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "REAL", "INT", "STRING", "EOF_", "BLUE_", "DEBUG_", "GAMMA_", "GREEN_", "FALSE_", "NO_", "OFF_", "ON_", "PSEUDOCOLOR_", "RED_", "TRUE_", "YES_", "'#'", "':'", "'('", "','", "')'", "'\\n'", "';'", "$accept", "commands", "command", "@1", "color", "gamma", "lis", "li", "terminator", "numeric", "debug", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 35, 58, 40, 44, 41, 10, 59 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 26, 27, 27, 28, 28, 28, 29, 28, 28, 30, 30, 30, 31, 31, 32, 32, 33, 34, 34, 34, 35, 35, 36, 36 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 2, 2, 1, 1, 0, 3, 1, 3, 3, 3, 0, 2, 2, 1, 5, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 6, 0, 7, 0, 0, 0, 5, 9, 16, 13, 24, 23, 4, 13, 13, 0, 21, 22, 0, 1, 0, 20, 18, 19, 3, 15, 0, 12, 11, 10, 8, 0, 2, 14, 0, 17 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 8, 9, 19, 10, 31, 11, 12, 28, 22, 16 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -30 static const yytype_int8 yypact[] = { 10, -15, -11, 4, -30, 7, -30, 8, 0, -2, -30, -12, -30, 19, -30, -30, -30, 19, 19, 25, -30, -30, 11, -30, -2, -30, -30, -30, -30, -30, 8, -30, -30, -30, -30, 8, -30, -30, 9, -30 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -30, -30, 26, -30, -30, -4, -30, 24, 12, -29, -30 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 23, 37, 14, 15, 25, 13, 38, 1, 2, 7, 3, 20, 21, 32, 33, 4, 5, 1, 2, 6, 3, 7, 26, 27, 17, 4, 5, 18, 30, 6, 34, 7, 39, 35, 24, 29, 36 }; static const yytype_uint8 yycheck[] = { 0, 30, 13, 14, 6, 20, 35, 7, 8, 21, 10, 3, 4, 17, 18, 15, 16, 7, 8, 19, 10, 21, 24, 25, 20, 15, 16, 20, 9, 19, 5, 21, 23, 22, 8, 11, 24 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 7, 8, 10, 15, 16, 19, 21, 27, 28, 30, 32, 33, 20, 13, 14, 36, 20, 20, 29, 3, 4, 35, 0, 28, 6, 24, 25, 34, 33, 9, 31, 31, 31, 5, 22, 34, 35, 35, 23 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (cm, ll, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, ll) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, cm, ll); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, SAOColorMap* cm, liFlexLexer* ll) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, cm, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; SAOColorMap* cm; liFlexLexer* ll; #endif { if (!yyvaluep) return; YYUSE (cm); YYUSE (ll); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, SAOColorMap* cm, liFlexLexer* ll) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, cm, ll) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; SAOColorMap* cm; liFlexLexer* ll; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, cm, ll); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, SAOColorMap* cm, liFlexLexer* ll) #else static void yy_reduce_print (yyvsp, yyrule, cm, ll) YYSTYPE *yyvsp; int yyrule; SAOColorMap* cm; liFlexLexer* ll; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , cm, ll); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, cm, ll); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, SAOColorMap* cm, liFlexLexer* ll) #else static void yydestruct (yymsg, yytype, yyvaluep, cm, ll) const char *yymsg; int yytype; YYSTYPE *yyvaluep; SAOColorMap* cm; liFlexLexer* ll; #endif { YYUSE (yyvaluep); YYUSE (cm); YYUSE (ll); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (SAOColorMap* cm, liFlexLexer* ll); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (SAOColorMap* cm, liFlexLexer* ll) #else int yyparse (cm, ll) SAOColorMap* cm; liFlexLexer* ll; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 7: #line 66 "saoparser.Y" {DISCARD_(1);} break; case 10: #line 70 "saoparser.Y" {cm->setChannel(SAOColorMap::RED);;} break; case 11: #line 71 "saoparser.Y" {cm->setChannel(SAOColorMap::GREEN);;} break; case 12: #line 72 "saoparser.Y" {cm->setChannel(SAOColorMap::BLUE);;} break; case 17: #line 83 "saoparser.Y" {cm->newLIColor((yyvsp[(2) - (5)].real),(yyvsp[(4) - (5)].real));;} break; case 20: #line 88 "saoparser.Y" {YYACCEPT;;} break; case 21: #line 91 "saoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].real);;} break; case 22: #line 92 "saoparser.Y" {(yyval.real)=(yyvsp[(1) - (1)].integer);;} break; case 23: #line 95 "saoparser.Y" {yydebug=1;;} break; case 24: #line 96 "saoparser.Y" {yydebug=0;;} break; /* Line 1267 of yacc.c. */ #line 1459 "saoparser.C" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (cm, ll, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (cm, ll, yymsg); } else { yyerror (cm, ll, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, cm, ll); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, cm, ll); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (cm, ll, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, cm, ll); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, cm, ll); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 98 "saoparser.Y" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/sao.h�����������������������������������������������������������������������0000644�0001750�0001750�00000004032�11743600735�014767� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __sao_h__ #define __sao_h__ #include "colormap.h" #include "list.h" class Colorbar; // LIColor class LIColor { private: float x; float y; LIColor* next_; LIColor* previous_; public: LIColor() {x=0; y=0; next_=NULL; previous_=NULL;} LIColor(float ll, float ii) {x=ll; y=ii, next_=NULL; previous_=NULL;} LIColor(const LIColor& a) {x=a.x; y=a.y; next_=a.next_; previous_=a.previous_;} LIColor& operator=(const LIColor& a) {x=a.x; y=a.y; next_=a.next_; previous_=a.previous_; return *this;} LIColor* next() {return next_;} LIColor* previous() {return previous_;} void setNext(LIColor* n) {next_ = n;} void setPrevious(LIColor* p) {previous_=p;} float getX() {return x;} float getY() {return y;} friend ostream& operator<<(ostream&, LIColor&); }; // SAOColorMap class SAOColorMap : public ColorMapInfo { public: enum ChannelType {RED,GREEN,BLUE}; protected: List<LIColor> red; List<LIColor> green; List<LIColor> blue; List<LIColor>* current; protected: unsigned char getColorChar(int, int, List<LIColor>*); unsigned short getColorShrt(int, int, List<LIColor>*); public: SAOColorMap(Colorbar* p); ColorMapInfo* dup() {return new SAOColorMap(*this);} int load(); int load(const char* var); void save(const char*); unsigned char getRedChar(int i, int c) {return getColorChar(i,c,&red);} unsigned char getGreenChar(int i, int c) {return getColorChar(i,c,&green);} unsigned char getBlueChar(int i, int c) {return getColorChar(i,c,&blue);} unsigned short getRedShrt(int i, int c) {return getColorShrt(i,c,&red);} unsigned short getGreenShrt(int i, int c) {return getColorShrt(i,c,&green);} unsigned short getBlueShrt(int i, int c) {return getColorShrt(i,c,&blue);} void setChannel(ChannelType); void newLIColor(float,float); friend ostream& operator<<(ostream&, SAOColorMap&); }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/default.h�������������������������������������������������������������������0000644�0001750�0001750�00000003301�11743600735�015627� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __default_h__ #define __default_h__ #include "sao.h" #include "lut.h" class Colorbar; class GreyColorMap : public SAOColorMap { public: GreyColorMap(Colorbar*); }; class RedColorMap : public SAOColorMap { public: RedColorMap(Colorbar*); }; class GreenColorMap : public SAOColorMap { public: GreenColorMap(Colorbar*); }; class BlueColorMap : public SAOColorMap { public: BlueColorMap(Colorbar*); }; class AColorMap : public SAOColorMap { public: AColorMap(Colorbar*); }; class BColorMap : public SAOColorMap { public: BColorMap(Colorbar*); }; class BBColorMap : public SAOColorMap { public: BBColorMap(Colorbar*); }; class HEColorMap : public SAOColorMap { public: HEColorMap(Colorbar*); }; class I8ColorMap : public LUTColorMap { public: I8ColorMap(Colorbar*); }; class AIPSColorMap : public LUTColorMap { public: AIPSColorMap(Colorbar*); }; class HeatColorMap : public SAOColorMap { public: HeatColorMap(Colorbar*); }; class CoolColorMap : public SAOColorMap { public: CoolColorMap(Colorbar*); }; class RainbowColorMap : public SAOColorMap { public: RainbowColorMap(Colorbar*); }; class StandardColorMap : public SAOColorMap { public: StandardColorMap(Colorbar*); }; class StaircaseColorMap : public LUTColorMap { public: StaircaseColorMap(Colorbar*); }; class ColorColorMap : public LUTColorMap { public: ColorColorMap(Colorbar*); }; class SLSColorMap : public LUTColorMap { public: SLSColorMap(Colorbar*); }; class HSVColorMap : public LUTColorMap { public: HSVColorMap(Colorbar*); }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colormap.h������������������������������������������������������������������0000644�0001750�0001750�00000002711�11743600735�016023� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __colormap_h__ #define __colormap_h__ #include <string.h> #include <stdlib.h> #include <limits.h> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> using namespace std; class Colorbar; // ColorMapInfo class ColorMapInfo { protected: Colorbar* parent_; int id; char* name; char* fileName; ColorMapInfo* next_; ColorMapInfo* previous_; public: ColorMapInfo(Colorbar* p); virtual ~ColorMapInfo(); Colorbar* parent() {return parent_;} const char* getName() {return name;} int getID() {return id;} void setName(const char*); const char* getFileName() {return fileName;} void setFileName(const char*); ColorMapInfo* next() {return next_;} ColorMapInfo* previous() {return previous_;} void setNext(ColorMapInfo* n) {next_ = n;} void setPrevious(ColorMapInfo* p) {previous_=p;} virtual ColorMapInfo* dup() =0; virtual int load() =0; virtual int load(const char*) =0; virtual void save(const char*) =0; virtual unsigned char getRedChar(int, int) =0; virtual unsigned char getGreenChar(int, int) =0; virtual unsigned char getBlueChar(int, int) =0; virtual unsigned short getRedShrt(int, int) =0; virtual unsigned short getGreenShrt(int, int) =0; virtual unsigned short getBlueShrt(int, int) =0; }; #endif �������������������������������������������������������./saods9/saotk/colorbar/colorbartruecolor16.C�������������������������������������������������������0000644�0001750�0001750�00000017627�11700666264�020071� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbartruecolor16.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarTrueColor16CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // Colorbar Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarTrueColor16Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbar", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarTrueColor16Type = { (char*)"colorbartruecolor16", // name sizeof(ColorbarBaseOptions), // size ColorbarTrueColor16CreateProc, // configProc colorbarTrueColor16Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarTrueColor16_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarTrueColor16Type); return TCL_OK; } int ColorbarTrueColor16CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarTrueColor16* colorbar = new ColorbarTrueColor16(interp, canvas, item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarTrueColor16 ColorbarTrueColor16::ColorbarTrueColor16(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarTrueColor(i,c,item), TrueColor16(visual) { configSpecs = colorbarTrueColor16Specs; // colorbar configure options loadDefaultCMaps(); } void ColorbarTrueColor16::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int ii=0; ii<width; ii++) { unsigned short r = colorCells[((int)(double(ii)/width*colorCount))*3+2]; unsigned short g = colorCells[((int)(double(ii)/width*colorCount))*3+1]; unsigned short b = colorCells[((int)(double(ii)/width*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); memcpy(data+ii*2, &a, 2); } } else { for (int ii=0; ii<width; ii++) { unsigned short r = colorCells[((int)(double(ii)/width*colorCount))*3+2]; unsigned short g = colorCells[((int)(double(ii)/width*colorCount))*3+1]; unsigned short b = colorCells[((int)(double(ii)/width*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&a); *(data+ii*2) = *(rr+1); *(data+ii*2+1) = *(rr); } } // --and duplicate for remaining rows for (int jj=1; jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), data, xmap->bytes_per_line); } void ColorbarTrueColor16::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned short r = colorCells[((int)(double(jj)/height*colorCount))*3+2]; unsigned short g = colorCells[((int)(double(jj)/height*colorCount))*3+1]; unsigned short b = colorCells[((int)(double(jj)/height*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); for (int ii=0; ii<width; ii++) memcpy(data+ii*2, &a, 2); } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { unsigned short r = colorCells[((int)(double(jj)/height*colorCount))*3+2]; unsigned short g = colorCells[((int)(double(jj)/height*colorCount))*3+1]; unsigned short b = colorCells[((int)(double(jj)/height*colorCount))*3]; unsigned short a = 0; a |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); a |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); a |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<width; ii++) { *(data+ii*2) = *(rr+1); *(data+ii*2+1) = *(rr); } } } } ���������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/lutparser.H�����������������������������������������������������������������0000644�0001750�0001750�00000005033�11714557444�016176� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { REAL = 258, INT = 259, STRING = 260, EOF_ = 261, DEBUG_ = 262, FALSE_ = 263, NO_ = 264, OFF_ = 265, ON_ = 266, TRUE_ = 267, YES_ = 268 }; #endif /* Tokens. */ #define REAL 258 #define INT 259 #define STRING 260 #define EOF_ 261 #define DEBUG_ 262 #define FALSE_ 263 #define NO_ 264 #define OFF_ 265 #define ON_ 266 #define TRUE_ 267 #define YES_ 268 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 29 "lutparser.Y" { #define LUTBUFSIZE 4096 char str[LUTBUFSIZE]; int integer; float real; } /* Line 1529 of yacc.c. */ #line 82 "lutparser.H" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/colorbar/colorbarrgbtruecolor24.C����������������������������������������������������0000644�0001750�0001750�00000035471�11700666264�020560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "colorbarrgbtruecolor24.h" #include "util.h" // Tk Canvas Widget Function Declarations int ColorbarRGBTrueColor24CreateProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); // ColorbarRGB Specs static Tk_CustomOption tagsOption = { Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; static Tk_ConfigSpec colorbarRGBTrueColor24Specs[] = { {TK_CONFIG_STRING, (char*)"-command", NULL, NULL, "colorbarrgb", Tk_Offset(ColorbarBaseOptions, cmdName), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-x", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, x), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-y", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, y), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-width", NULL, NULL, "512", Tk_Offset(ColorbarBaseOptions, width), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_INT, (char*)"-height", NULL, NULL, "22", Tk_Offset(ColorbarBaseOptions, height), TK_CONFIG_OPTION_SPECIFIED, NULL}, {TK_CONFIG_ANCHOR, (char*)"-anchor", NULL, NULL, "nw", Tk_Offset(ColorbarBaseOptions, anchor), 0, NULL}, {TK_CONFIG_CUSTOM, (char*)"-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char*)"-helvetica", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, helvetica), 0, NULL}, {TK_CONFIG_STRING, (char*)"-courier", NULL, NULL, "courier", Tk_Offset(ColorbarBaseOptions, courier), 0, NULL}, {TK_CONFIG_STRING, (char*)"-times", NULL, NULL, "times", Tk_Offset(ColorbarBaseOptions, times), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-orientation", NULL, NULL, "0", Tk_Offset(ColorbarBaseOptions, orientation), 0, NULL}, {TK_CONFIG_INT, (char*)"-size", NULL, NULL, "20", Tk_Offset(ColorbarBaseOptions, size), 0, NULL}, {TK_CONFIG_STRING, (char*)"-font", NULL, NULL, "helvetica", Tk_Offset(ColorbarBaseOptions, font), 0, NULL}, {TK_CONFIG_INT, (char*)"-fontsize", NULL, NULL, "10", Tk_Offset(ColorbarBaseOptions, fontSize), 0, NULL}, {TK_CONFIG_STRING, (char*)"-fontweight", "fontweight", NULL, "normal", Tk_Offset(ColorbarBaseOptions, fontWeight), 0, NULL}, {TK_CONFIG_SYNONYM, (char*)"-fontstyle", "fontweight", NULL, NULL, 0, 0}, {TK_CONFIG_STRING, (char*)"-fontslant", NULL, NULL, "roman", Tk_Offset(ColorbarBaseOptions, fontSlant), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-numerics", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, numerics), 0, NULL}, {TK_CONFIG_BOOLEAN, (char*)"-space", NULL, NULL, "1", Tk_Offset(ColorbarBaseOptions, space), 0, NULL}, {TK_CONFIG_INT, (char*)"-ticks", NULL, NULL, "11", Tk_Offset(ColorbarBaseOptions, ticks), 0, NULL}, {TK_CONFIG_INT, (char*)"-colors", NULL, NULL, "1024", Tk_Offset(ColorbarBaseOptions, colors), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}, }; // Tk Static Structure static Tk_ItemType colorbarRGBTrueColor24Type = { (char*)"colorbarrgbtruecolor24", // name sizeof(ColorbarBaseOptions), // size ColorbarRGBTrueColor24CreateProc, // configProc colorbarRGBTrueColor24Specs, // configSpecs WidgetConfigProc, // configProc WidgetCoordProc, // coordProc WidgetDeleteProc, // deleteProc WidgetDisplayProc, // displayProc 0, // alwaysRedraw WidgetPointProc, // pointProc WidgetAreaProc, // areaProc WidgetPostscriptProc, // postscriptProc WidgetScaleProc, // scaleProc WidgetTranslateProc, // translateProc (Tk_ItemIndexProc*)NULL, // indexProc (Tk_ItemCursorProc*)NULL, // icursorProc (Tk_ItemSelectionProc*)NULL, // selectionProc (Tk_ItemInsertProc*)NULL, // insertProc (Tk_ItemDCharsProc*)NULL, // dCharsProc (Tk_ItemType*)NULL // nextPtr }; // Non-Member Functions int ColorbarRGBTrueColor24_Init(Tcl_Interp* interp) { Tk_CreateItemType(&colorbarRGBTrueColor24Type); return TCL_OK; } int ColorbarRGBTrueColor24CreateProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, int argc, Tcl_Obj *const argv[]) { ColorbarRGBTrueColor24* colorbar = new ColorbarRGBTrueColor24(interp,canvas,item); // and set default configuration if (colorbar->configure(argc, (const char**)argv, 0) != TCL_OK) { delete colorbar; Tcl_AppendResult(interp, " error occured while creating colorbar.", NULL); return TCL_ERROR; } return TCL_OK; } // ColorbarRGBTrueColor24 ColorbarRGBTrueColor24::ColorbarRGBTrueColor24(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : ColorbarBase(i,c,item), ColorbarRGBTrueColor(i,c,item), TrueColor24(visual) { configSpecs = colorbarRGBTrueColor24Specs; // colorbar configure options } void ColorbarRGBTrueColor24::updateColorsHorz() { int width = options->width-2; int height = ((ColorbarBaseOptions*)options)->size-2; char* data = XImageData(xmap); switch (xmap->bits_per_pixel) { case 32: updateColors32Horz(width, height, data); break; case 24: updateColors24Horz(width, height, data); break; default: internalError("Colorbar: bad bits/pixel"); return; } } void ColorbarRGBTrueColor24::updateColorsVert() { int width = ((ColorbarBaseOptions*)options)->size-2; int height = options->height-2; char* data = XImageData(xmap); switch (xmap->bits_per_pixel) { case 32: updateColors32Vert(width, height, data); break; case 24: updateColors24Vert(width, height, data); break; default: internalError("Colorbar: bad bits/pixel"); return; } } void ColorbarRGBTrueColor24::updateColors24Horz(int width, int height, char* data) { // if we have cross platforms, we need to byte swap unsigned char row[xmap->bytes_per_line]; if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { // red for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; memcpy(row+ii*3, &a, 3); } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; memcpy(row+ii*3, &a, 3); } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; memcpy(row+ii*3, &a, 3); } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } else { // red for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; unsigned char* rr = (unsigned char*)(&a); *(row+ii*3) = *(rr+3); *(row+ii*3+1) = *(rr+2); *(row+ii*3+2) = *(rr+1); } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; unsigned char* rr = (unsigned char*)(&a); *(row+ii*3) = *(rr+3); *(row+ii*3+1) = *(rr+2); *(row+ii*3+2) = *(rr+1); } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(row+ii*3) = *(rr+3); *(row+ii*3+1) = *(rr+2); *(row+ii*3+2) = *(rr+1); } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } } void ColorbarRGBTrueColor24::updateColors24Vert(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; for (int ii=0; ii<(int)(width/3.); ii++) memcpy(data+ii*3, &a, 3); } // green { unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) memcpy(data+ii*3, &a, 3); } // blue { unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; for (int ii=(int)(width*2/3.); ii<width; ii++) memcpy(data+ii*3, &a, 3); } } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<(int)(width/3.); ii++) { *(data+ii*3) = *(rr+3); *(data+ii*3+1) = *(rr+2); *(data+ii*3+2) = *(rr+1); } } // green { unsigned int g = colorCells[(int)(double(jj)/width*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { *(data+ii*3) = *(rr+3); *(data+ii*3+1) = *(rr+2); *(data+ii*3+2) = *(rr+1); } } // blue { unsigned int b = colorCells[(int)(double(jj)/width*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width*2/3.); ii<width; ii++) { *(data+ii*3) = *(rr+3); *(data+ii*3+1) = *(rr+2); *(data+ii*3+2) = *(rr+1); } } } } } void ColorbarRGBTrueColor24::updateColors32Horz(int width, int height, char* data) { // if we have cross platforms, we need to byte swap unsigned char row[xmap->bytes_per_line]; if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { //red for (int ii=0; ii<width; ii++) { unsigned int r = colorCells[(int)(double(ii)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; memcpy(row+ii*4, &a, 4); } for (int jj=0; jj<(int)(height/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int ii=0; ii<width; ii++) { unsigned int g = colorCells[(int)(double(ii)/width*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; memcpy(row+ii*4, &a, 4); } for (int jj=(int)(height/3.); jj<(int)(height*2/3.); jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int ii=0; ii<width; ii++) { unsigned int b = colorCells[(int)(double(ii)/width*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; memcpy(row+ii*4, &a, 4); } for (int jj=(int)(height*2/3.); jj<height; jj++) memcpy(data+(jj*xmap->bytes_per_line), row, xmap->bytes_per_line); } else { // red for (int i=0; i<width; i++) { unsigned int r = colorCells[(int)(double(i)/width*colorCount)*3]; unsigned int a = 0; a |= r << rs_; unsigned char* rr = (unsigned char*)(&a); *(row+i*4) = *(rr+3); *(row+i*4+1) = *(rr+2); *(row+i*4+2) = *(rr+1); *(row+i*4+3) = *(rr); } for (int j=0; j<(int)(height/3.); j++) memcpy(data+(j*xmap->bytes_per_line), row, xmap->bytes_per_line); // green for (int i=0; i<width; i++) { unsigned int g = colorCells[(int)(double(i)/width*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; unsigned char* rr = (unsigned char*)(&a); *(row+i*4) = *(rr+3); *(row+i*4+1) = *(rr+2); *(row+i*4+2) = *(rr+1); *(row+i*4+3) = *(rr); } for (int j=(int)(height/3.); j<(int)(height*2/3.); j++) memcpy(data+(j*xmap->bytes_per_line), row, xmap->bytes_per_line); // blue for (int i=0; i<width; i++) { unsigned int b = colorCells[(int)(double(i)/width*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); *(row+i*4) = *(rr+3); *(row+i*4+1) = *(rr+2); *(row+i*4+2) = *(rr+1); *(row+i*4+3) = *(rr); } for (int j=(int)(height*2/3.); j<height; j++) memcpy(data+(j*xmap->bytes_per_line), row, xmap->bytes_per_line); } } void ColorbarRGBTrueColor24::updateColors32Vert(int width, int height, char* data) { // if we have cross platforms, we need to byte swap if ((!xmap->byte_order && lsb()) || (xmap->byte_order && !lsb())) { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; for (int ii=0; ii<(int)(width/3.); ii++) memcpy(data+ii*4, &a, 4); } // green { unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) memcpy(data+ii*4, &a, 4); } // blue { unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; for (int ii=(int)(width*2/3.); ii<width; ii++) memcpy(data+ii*4, &a, 4); } } } else { for (int jj=height-1; jj>=0; jj--, data+=xmap->bytes_per_line) { // red { unsigned int r = colorCells[(int)(double(jj)/height*colorCount)*3]; unsigned int a = 0; a |= r << rs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=0; ii<(int)(width/3.); ii++) { *(data+ii*4) = *(rr+3); *(data+ii*4+1) = *(rr+2); *(data+ii*4+2) = *(rr+1); *(data+ii*4+3) = *(rr); } } // green { unsigned int g = colorCells[(int)(double(jj)/height*colorCount)*3+1]; unsigned int a = 0; a |= g << gs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width/3.); ii<(int)(width*2/3.); ii++) { *(data+ii*4) = *(rr+3); *(data+ii*4+1) = *(rr+2); *(data+ii*4+2) = *(rr+1); *(data+ii*4+3) = *(rr); } } // blue { unsigned int b = colorCells[(int)(double(jj)/height*colorCount)*3+2]; unsigned int a = 0; a |= b << bs_; unsigned char* rr = (unsigned char*)(&a); for (int ii=(int)(width*2/3.); ii<width; ii++) { *(data+ii*4) = *(rr+3); *(data+ii*4+1) = *(rr+2); *(data+ii*4+2) = *(rr+1); *(data+ii*4+3) = *(rr); } } } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/list/��������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013164� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/list/Makefile������������������������������������������������������������������������0000644�0001750�0001750�00000001010�11713050135�014623� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../make.include CXXFLAGS = $(CXXOPT) \ -I. -I../vector -I../frame -I../colorbar -I../../include -I$(X11INCLUDE) SRC = list.C INCLS = $(wildcard *.h) OBJS = $(SRC:%.C=%.o) all : $(OBJS) TAGS clean : FORCE rm -f core *~ *# distclean : clean rm -f TAGS *.o $(LIB) ifdef DEPENDS TAGS : $(SS) $(INCLS) etags $+ else TAGS : FORCE endif FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/list/list.h��������������������������������������������������������������������������0000644�0001750�0001750�00000002262�11752025335�014330� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __list_h__ #define __list_h__ #include <stdlib.h> template<class T> class List { private: T* head_; T* tail_; int count_; T* current_; public: List(); List(const List&); ~List(); List& operator=(const List&); void insertHead(T*); void insert(int, T*); void insertNext(T*,T*); void insertPrev(T*,T*); void append(T*); T* pop(); T* extract(); T* extractNext(T*); T* extractPrev(T*); void deleteAll(); T* begin() {return head_;} T* end() {return tail_;} T* head() {return current_ = head_;} T* tail() {return current_ = tail_;} T* next() {return current_ ? current_ = current_->next() : NULL;} int isNext() {return current_->next() ? 1 : 0;} T* previous() {return current_ ? current_ = current_->previous() : NULL;} int isPrevious() {return current_->previous() ? 1 : 0;} T* current() {return current_;} int count() {return count_;} int isEmpty() {return (count_==0) ? 1 : 0;} T* operator[](int i); int index(T*); void transverse(void (*proc)(T*)); }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/saotk/list/list.C��������������������������������������������������������������������������0000644�0001750�0001750�00000013455�11752025335�014271� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "list.h" #include "vector.h" #include "marker.h" #include "callback.h" #include "contour.h" #include "fitsmask.h" #include "sao.h" #include "lut.h" #include "colormap.h" #include "colortag.h" template<class T> List<T>::List() { head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; } template<class T> List<T>::List(const List<T>& aa) { head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; List<T>& a = (List<T>&)aa; if (a.head()) do append(new T((T)(*(a.current_)))); while (a.next()); } // this is needed because of Marker virtual functions template <> List<Marker>::List(const List<Marker>& aa) { head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; List<Marker>& a = (List<Marker>&)aa; if (a.head()) do append(a.current_->dup()); while (a.next()); } // this is needed because of ColorMapInfo virtual functions template <> List<ColorMapInfo>::List(const List<ColorMapInfo>& aa) { head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; List<ColorMapInfo>& a = (List<ColorMapInfo>&)aa; if (a.head()) do append(a.current_->dup()); while (a.next()); } template<class T> List<T>::~List() { T* ptr = head_; while (ptr) { T* tmp = ptr->next(); delete ptr; ptr = tmp; } } template<class T> List<T>& List<T>::operator=(const List<T>& aa) { deleteAll(); List<T>& a = (List<T>&)aa; if (a.head()) do append(new T((T)(*(a.current_)))); while (a.next()); return *this; } // this is needed because of Marker virtual functions template <> List<Marker>& List<Marker>::operator=(const List<Marker>& aa) { deleteAll(); List<Marker>& a = (List<Marker>&)aa; if (a.head()) do append(a.current_->dup()); while (a.next()); return *this; } // this is needed because of ColorMapInfo virtual functions template <> List<ColorMapInfo>& List<ColorMapInfo>::operator=(const List<ColorMapInfo>& aa) { deleteAll(); List<ColorMapInfo>& a = (List<ColorMapInfo>&)aa; if (a.head()) do append(a.current_->dup()); while (a.next()); return *this; } template<class T> void List<T>::insertHead(T* t) { if (head_ && t) { t->setNext(head_); t->setPrevious(NULL); head_->setPrevious(t); head_ = t; } else { head_ = t; tail_ = t; } current_ = head_; count_++; } template<class T> void List<T>::insert(int which, T* t) { head(); for (int i=0; i<which; i++) next(); if (current_ && t) { T* n = current_->next(); t->setPrevious(current_); t->setNext(n); current_->setNext(t); if (n) n->setPrevious(t); else tail_ = t; count_++; } } template<class T> void List<T>::insertNext(T* c, T* t) { if (c && t) { T* n = c->next(); t->setPrevious(c); t->setNext(n); c->setNext(t); if (n) n->setPrevious(t); else tail_ = t; count_++; } } template<class T> void List<T>::insertPrev(T* c, T* t) { if (c && t) { T* p = c->previous(); t->setPrevious(p); t->setNext(c); c->setPrevious(t); if (p) p->setNext(t); else head_ = t; count_++; } } template<class T> void List<T>::append(T* p) { if (tail_) { p->setPrevious(tail_); p->setNext(NULL); tail_->setNext(p); tail_ = p; } else { p->setPrevious(NULL); p->setNext(NULL); head_ = p; tail_ = p; } current_ = tail_; count_++; } template<class T> void List<T>::deleteAll() { T* ptr = head_; while (ptr) { T* tmp = ptr->next(); delete ptr; ptr = tmp; } head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; } template<class T> T* List<T>::pop() { if (tail_) { T* m = tail_; if (tail_ != head_) { T* p = tail_->previous(); p->setNext(NULL); tail_ = p; current_ = p; count_--; } else { head_ = NULL; tail_ = NULL; current_ = NULL; count_ = 0; } return m; } return NULL; } template<class T> T* List<T>::extract() { T* ptr = current_; T* p = ptr->previous(); T* n = ptr->next(); if (p) p->setNext(n); if (n) n->setPrevious(p); if (head_ == ptr) head_ = n; if (tail_ == ptr) tail_ = p; current_ = NULL; count_--; ptr->setNext(NULL); ptr->setPrevious(NULL); return ptr; } template<class T> T* List<T>::extractNext(T* ptr) { T* p = ptr->previous(); T* n = ptr->next(); if (p) p->setNext(n); if (n) n->setPrevious(p); if (head_ == ptr) head_ = n; if (tail_ == ptr) tail_ = p; current_ = NULL; count_--; ptr->setNext(NULL); ptr->setPrevious(NULL); return n; } template<class T> T* List<T>::extractPrev(T* ptr) { T* p = ptr->previous(); T* n = ptr->next(); if (p) p->setNext(n); if (n) n->setPrevious(p); if (head_ == ptr) head_ = n; if (tail_ == ptr) tail_ = p; current_ = NULL; count_--; ptr->setNext(NULL); ptr->setPrevious(NULL); return p; } template<class T> T* List<T>::operator[](int which) { head(); for (int i=0; i<which; i++) next(); return current_; } template<class T> int List<T>::index(T* t) { int cnt=0; head(); while (current_) { if (current_ == t) return cnt; cnt++; next(); } return -1; } template<class T> void List<T>::transverse(void (*proc)(T*)) { if (head()) do proc(current_); while (next()); } template class List<Vertex>; template class List<Tag>; template class List<Marker>; template class List<CallBack>; template class List<Contour>; template class List<FitsMask>; template class List<LIColor>; template class List<RGBColor>; template class List<ColorTag>; template class List<ColorMapInfo>; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinx86snowleopard������������������������������������������������������������������0000644�0001750�0001750�00000001047�12127331353�016054� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinx86snowleopard X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz JOBS = 4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/rice/��������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012012� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/rice/Makefile������������������������������������������������������������������������������0000644�0001750�0001750�00000000422�11021274737�013467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include CFLAGS = $(CCOPT) -I. SRC = ricecomp.c OBJS = $(SRC:%.c=%.o) LIB = librice.a $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) install : $(LIB) cp $(LIB) ../lib/. clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.a *.so FORCE : ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/rice/ricecomp.c����������������������������������������������������������������������������0000644�0001750�0001750�00000105543�11277317437�014016� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. These routines were originally contained in 2 source files: rcomp.c and rdecomp.c, and the 'include' file now called ricecomp.h was originally called buffer.h. */ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rcomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rcomp.c 1.5 99/03/01 12:40:27 */ /* rcomp.c Compress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns number of bytes written to code buffer or * -1 on failure */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned char Buffer_t; typedef struct { int bitbuffer; /* bit buffer */ int bits_to_go; /* bits to go in buffer */ Buffer_t *start; /* start of buffer */ Buffer_t *current; /* current position in buffer */ Buffer_t *end; /* end of buffer */ } Buffer; #define putcbuf(c,mf) ((*(mf->current)++ = c), 0) /*#include "fitsio2.h"*/ #define FFLOCK #define FFUNLOCK static void start_outputing_bits(Buffer *buffer); static int done_outputing_bits(Buffer *buffer); static int output_nbits(Buffer *buffer, int bits, int n); /* this routine used to be called 'rcomp' (WDP) */ /*---------------------------------------------------------------------------*/ int fits_rcomp(int a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; int lastpix, nextpix, pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; unsigned int psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 4; */ /* nblock = 32; now an input parameter*/ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move out of switch block, to tweak performance */ fsbits = 5; fsmax = 25; bbits = 1<<fsbits; /* * Set up buffer pointers */ buffer->start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first int value to the first 4 bytes of the buffer */ if (output_nbits(buffer, a[0], 32) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i<nx; i += nblock) { /* last block may be shorter */ if (nx-i < nblock) thisblock = nx-i; /* * Compute differences of adjacent pixels and map them to unsigned values. * Note that this may overflow the integer variables -- that's * OK, because we can recover when decompressing. If we were * compressing shorts or bytes, would want to do this arithmetic * with short/byte working variables (though diff will still be * passed as an int.) * * compute sum of mapped pixel values at same time * use double precision for sum to allow 32-bit integer inputs */ pixelsum = 0.0; for (j=0; j<thisblock; j++) { nextpix = a[i+j]; pdiff = nextpix - lastpix; diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1)); pixelsum += diff[j]; lastpix = nextpix; } /* * compute number of bits to split from sum */ dpsum = (pixelsum - (thisblock/2) - 1)/thisblock; if (dpsum < 0) dpsum = 0.0; psum = ((unsigned int) dpsum ) >> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; j<thisblock; j++) { if (output_nbits(buffer, diff[j], bbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } } else if (fs == 0 && pixelsum == 0) { /* * special low entropy case when FS = 0 and pixelsum=0 (all * pixels in block are zero.) * Output a 0 and return */ if (output_nbits(buffer, 0, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } else { /* normal case: not either very high or very low entropy */ if (output_nbits(buffer, fs+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } fsmask = (1<<fs) - 1; /* * local copies of bit buffer to improve optimization */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j<thisblock; j++) { v = diff[j]; top = v >> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ int fits_rcomp_short( short a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; /* NOTE: in principle, the following 2 variable could be declared as 'short' but in fact the code runs faster (on 32-bit Linux at least) as 'int' */ int lastpix, nextpix; /* int pdiff; */ short pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; /* unsigned int psum; */ unsigned short psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 2; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move these out of switch block to further tweak performance */ fsbits = 4; fsmax = 14; bbits = 1<<fsbits; /* * Set up buffer pointers */ buffer->start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first short value to the first 2 bytes of the buffer */ if (output_nbits(buffer, a[0], 16) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i<nx; i += nblock) { /* last block may be shorter */ if (nx-i < nblock) thisblock = nx-i; /* * Compute differences of adjacent pixels and map them to unsigned values. * Note that this may overflow the integer variables -- that's * OK, because we can recover when decompressing. If we were * compressing shorts or bytes, would want to do this arithmetic * with short/byte working variables (though diff will still be * passed as an int.) * * compute sum of mapped pixel values at same time * use double precision for sum to allow 32-bit integer inputs */ pixelsum = 0.0; for (j=0; j<thisblock; j++) { nextpix = a[i+j]; pdiff = nextpix - lastpix; diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1)); pixelsum += diff[j]; lastpix = nextpix; } /* * compute number of bits to split from sum */ dpsum = (pixelsum - (thisblock/2) - 1)/thisblock; if (dpsum < 0) dpsum = 0.0; /* psum = ((unsigned int) dpsum ) >> 1; */ psum = ((unsigned short) dpsum ) >> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; j<thisblock; j++) { if (output_nbits(buffer, diff[j], bbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } } else if (fs == 0 && pixelsum == 0) { /* * special low entropy case when FS = 0 and pixelsum=0 (all * pixels in block are zero.) * Output a 0 and return */ if (output_nbits(buffer, 0, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } else { /* normal case: not either very high or very low entropy */ if (output_nbits(buffer, fs+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } fsmask = (1<<fs) - 1; /* * local copies of bit buffer to improve optimization */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j<thisblock; j++) { v = diff[j]; top = v >> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ int fits_rcomp_byte( signed char a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; /* int bsize; */ int i, j, thisblock; /* NOTE: in principle, the following 2 variable could be declared as 'short' but in fact the code runs faster (on 32-bit Linux at least) as 'int' */ int lastpix, nextpix; /* int pdiff; */ signed char pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; /* unsigned int psum; */ unsigned char psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 1; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } */ /* move these out of switch block to further tweak performance */ fsbits = 3; fsmax = 6; bbits = 1<<fsbits; /* * Set up buffer pointers */ buffer->start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first byte value to the first byte of the buffer */ if (output_nbits(buffer, a[0], 8) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i<nx; i += nblock) { /* last block may be shorter */ if (nx-i < nblock) thisblock = nx-i; /* * Compute differences of adjacent pixels and map them to unsigned values. * Note that this may overflow the integer variables -- that's * OK, because we can recover when decompressing. If we were * compressing shorts or bytes, would want to do this arithmetic * with short/byte working variables (though diff will still be * passed as an int.) * * compute sum of mapped pixel values at same time * use double precision for sum to allow 32-bit integer inputs */ pixelsum = 0.0; for (j=0; j<thisblock; j++) { nextpix = a[i+j]; pdiff = nextpix - lastpix; diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1)); pixelsum += diff[j]; lastpix = nextpix; } /* * compute number of bits to split from sum */ dpsum = (pixelsum - (thisblock/2) - 1)/thisblock; if (dpsum < 0) dpsum = 0.0; /* psum = ((unsigned int) dpsum ) >> 1; */ psum = ((unsigned char) dpsum ) >> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; j<thisblock; j++) { if (output_nbits(buffer, diff[j], bbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } } else if (fs == 0 && pixelsum == 0) { /* * special low entropy case when FS = 0 and pixelsum=0 (all * pixels in block are zero.) * Output a 0 and return */ if (output_nbits(buffer, 0, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } else { /* normal case: not either very high or very low entropy */ if (output_nbits(buffer, fs+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } fsmask = (1<<fs) - 1; /* * local copies of bit buffer to improve optimization */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j<thisblock; j++) { v = diff[j]; top = v >> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; putcbuf(lbitbuffer & 0xff,buffer); for (top -= lbits_to_go; top>=8; top -= 8) { putcbuf(0, buffer); } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } } } /* check if overflowed output buffer */ if (buffer->current > buffer->end) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ /* bit_output.c * * Bit output routines * Procedures return zero on success, EOF on end-of-buffer * * Programmer: R. White Date: 20 July 1998 */ /* Initialize for bit output */ static void start_outputing_bits(Buffer *buffer) { /* * Buffer is empty to start with */ buffer->bitbuffer = 0; buffer->bits_to_go = 8; } /*---------------------------------------------------------------------------*/ /* Output N bits (N must be <= 32) */ static int output_nbits(Buffer *buffer, int bits, int n) { /* local copies */ int lbitbuffer; int lbits_to_go; /* AND mask for the right-most n bits */ static unsigned int mask[33] = {0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; /* * insert bits at end of bitbuffer */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; if (lbits_to_go+n > 32) { /* * special case for large n: put out the top lbits_to_go bits first * note that 0 < lbits_to_go <= 8 */ lbitbuffer <<= lbits_to_go; /* lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<<lbits_to_go)-1); */ lbitbuffer |= (bits>>(n-lbits_to_go)) & *(mask+lbits_to_go); putcbuf(lbitbuffer & 0xff,buffer); n -= lbits_to_go; lbits_to_go = 8; } lbitbuffer <<= n; /* lbitbuffer |= ( bits & ((1<<n)-1) ); */ lbitbuffer |= ( bits & *(mask+n) ); lbits_to_go -= n; while (lbits_to_go <= 0) { /* * bitbuffer full, put out top 8 bits */ putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer); lbits_to_go += 8; } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; return(0); } /*---------------------------------------------------------------------------*/ /* Flush out the last bits */ static int done_outputing_bits(Buffer *buffer) { if(buffer->bits_to_go < 8) { putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer); /* if (putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer) == EOF) return(EOF); */ } return(0); } /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rdecomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rdecomp.c 1.4 99/03/01 12:38:41 */ /* rdecomp.c Decompress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns 0 on success or 1 on failure */ /* moved these 'includes' to the beginning of the file (WDP) #include <stdio.h> #include <stdlib.h> */ /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned int array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { /* int bsize; */ int i, k, imax; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; static int *nonzero_count = (int *)NULL; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 4; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 5; fsmax = 25; bbits = 1<<fsbits; FFLOCK; if (nonzero_count == (int *) NULL) { /* * nonzero_count is lookup table giving number of bits * in 8-bit values not including leading zeros */ /* NOTE!!! This memory never gets freed */ nonzero_count = (int *) malloc(256*sizeof(int)); if (nonzero_count == (int *) NULL) { ffpmsg("rdecomp: insufficient memory"); FFUNLOCK; return 1; } nzero = 8; k = 128; for (i=255; i>=0; ) { for ( ; i>=k; i--) nonzero_count[i] = nzero; k = k/2; nzero--; } } FFUNLOCK; /* * Decode in blocks of nblock pixels */ /* first 4 bytes of input buffer contain the value of the first */ /* 4 byte integer value, without any encoding */ lastpix = 0; bytevalue = c[0]; lastpix = lastpix | (bytevalue<<24); bytevalue = c[1]; lastpix = lastpix | (bytevalue<<16); bytevalue = c[2]; lastpix = lastpix | (bytevalue<<8); bytevalue = c[3]; lastpix = lastpix | bytevalue; c += 4; cend = c + clen - 4; b = *c++; /* bit buffer */ nbits = 8; /* number of bits remaining in b */ for (i = 0; i<nx; ) { /* get the FS value from first fsbits */ nbits -= fsbits; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } fs = (b >> nbits) - 1; b &= (1<<nbits)-1; /* loop over the next block */ imax = i + nblock; if (imax > nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i<imax; i++) array[i] = lastpix; } else if (fs==fsmax) { /* high-entropy case, directly coded pixel values */ for ( ; i<imax; i++) { k = bbits - nbits; diff = b<<k; for (k -= 8; k >= 0; k -= 8) { b = *c++; diff |= b<<k; } if (nbits>0) { b = *c++; diff |= b>>(-k); b &= (1<<nbits)-1; } else { b = 0; } /* * undo mapping and differencing * Note that some of these operations will overflow the * unsigned int arithmetic -- that's OK, it all works * out to give the right answers in the output file. */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i<imax; i++) { /* count number of leading zeros */ while (b == 0) { nbits += 8; b = *c++; } nzero = nbits - nonzero_count[b]; nbits -= nzero+1; /* flip the leading one-bit */ b ^= 1<<nbits; /* get the FS trailing bits */ nbits -= fs; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } diff = (nzero<<fs) | (b>>nbits); b &= (1<<nbits)-1; /* undo mapping and differencing */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp_short (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned short array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int i, imax; /* int bsize; */ int k; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; static int *nonzero_count = (int *)NULL; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 2; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 4; fsmax = 14; bbits = 1<<fsbits; FFLOCK; if (nonzero_count == (int *) NULL) { /* * nonzero_count is lookup table giving number of bits * in 8-bit values not including leading zeros */ /* NOTE!!! This memory never gets freed */ nonzero_count = (int *) malloc(256*sizeof(int)); if (nonzero_count == (int *) NULL) { ffpmsg("rdecomp: insufficient memory"); FFUNLOCK; return 1; } nzero = 8; k = 128; for (i=255; i>=0; ) { for ( ; i>=k; i--) nonzero_count[i] = nzero; k = k/2; nzero--; } } FFUNLOCK; /* * Decode in blocks of nblock pixels */ /* first 2 bytes of input buffer contain the value of the first */ /* 2 byte integer value, without any encoding */ lastpix = 0; bytevalue = c[0]; lastpix = lastpix | (bytevalue<<8); bytevalue = c[1]; lastpix = lastpix | bytevalue; c += 2; cend = c + clen - 2; b = *c++; /* bit buffer */ nbits = 8; /* number of bits remaining in b */ for (i = 0; i<nx; ) { /* get the FS value from first fsbits */ nbits -= fsbits; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } fs = (b >> nbits) - 1; b &= (1<<nbits)-1; /* loop over the next block */ imax = i + nblock; if (imax > nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i<imax; i++) array[i] = lastpix; } else if (fs==fsmax) { /* high-entropy case, directly coded pixel values */ for ( ; i<imax; i++) { k = bbits - nbits; diff = b<<k; for (k -= 8; k >= 0; k -= 8) { b = *c++; diff |= b<<k; } if (nbits>0) { b = *c++; diff |= b>>(-k); b &= (1<<nbits)-1; } else { b = 0; } /* * undo mapping and differencing * Note that some of these operations will overflow the * unsigned int arithmetic -- that's OK, it all works * out to give the right answers in the output file. */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i<imax; i++) { /* count number of leading zeros */ while (b == 0) { nbits += 8; b = *c++; } nzero = nbits - nonzero_count[b]; nbits -= nzero+1; /* flip the leading one-bit */ b ^= 1<<nbits; /* get the FS trailing bits */ nbits -= fs; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } diff = (nzero<<fs) | (b>>nbits); b &= (1<<nbits)-1; /* undo mapping and differencing */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } /*---------------------------------------------------------------------------*/ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp_byte (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned char array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int i, imax; /* int bsize; */ int k; int nbits, nzero, fs; unsigned char *cend; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; static int *nonzero_count = (int *)NULL; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ /* bsize = 1; */ /* nblock = 32; now an input parameter */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ /* switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } */ /* move out of switch block, to tweak performance */ fsbits = 3; fsmax = 6; bbits = 1<<fsbits; FFLOCK; if (nonzero_count == (int *) NULL) { /* * nonzero_count is lookup table giving number of bits * in 8-bit values not including leading zeros */ /* NOTE!!! This memory never gets freed */ nonzero_count = (int *) malloc(256*sizeof(int)); if (nonzero_count == (int *) NULL) { ffpmsg("rdecomp: insufficient memory"); FFUNLOCK; return 1; } nzero = 8; k = 128; for (i=255; i>=0; ) { for ( ; i>=k; i--) nonzero_count[i] = nzero; k = k/2; nzero--; } } FFUNLOCK; /* * Decode in blocks of nblock pixels */ /* first byte of input buffer contain the value of the first */ /* byte integer value, without any encoding */ lastpix = c[0]; c += 1; cend = c + clen - 1; b = *c++; /* bit buffer */ nbits = 8; /* number of bits remaining in b */ for (i = 0; i<nx; ) { /* get the FS value from first fsbits */ nbits -= fsbits; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } fs = (b >> nbits) - 1; b &= (1<<nbits)-1; /* loop over the next block */ imax = i + nblock; if (imax > nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i<imax; i++) array[i] = lastpix; } else if (fs==fsmax) { /* high-entropy case, directly coded pixel values */ for ( ; i<imax; i++) { k = bbits - nbits; diff = b<<k; for (k -= 8; k >= 0; k -= 8) { b = *c++; diff |= b<<k; } if (nbits>0) { b = *c++; diff |= b>>(-k); b &= (1<<nbits)-1; } else { b = 0; } /* * undo mapping and differencing * Note that some of these operations will overflow the * unsigned int arithmetic -- that's OK, it all works * out to give the right answers in the output file. */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i<imax; i++) { /* count number of leading zeros */ while (b == 0) { nbits += 8; b = *c++; } nzero = nbits - nonzero_count[b]; nbits -= nzero+1; /* flip the leading one-bit */ b ^= 1<<nbits; /* get the FS trailing bits */ nbits -= fs; while (nbits < 0) { b = (b<<8) | (*c++); nbits += 8; } diff = (nzero<<fs) | (b>>nbits); b &= (1<<nbits)-1; /* undo mapping and differencing */ if ((diff & 1) == 0) { diff = diff>>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/���������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201303�011664� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/Makefile�������������������������������������������������������������������������������0000644�0001750�0001750�00000001234�11516404165�013343� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include include ../make.pkgs CXXFLAGS = $(CXXOPT) -I../include -I../saotk/vector \ -I../$(TKDIR)/generic -I../$(TKDIR)/win \ -I$(X11INCLUDE) SRC = rotstr.C \ tkwin32.C \ win32lib.C \ xxlib.C \ OBJS = $(SRC:%.C=%.o) INCLS = tkwin32.h win32lib.h xxlib.h rotstr.h LIB = libxxlib.a all : $(LIB) install : all cp $(INCLS) ../include/. cp $(LIB) ../lib/. $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.so *.a FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/rotstr.C�������������������������������������������������������������������������������0000644�0001750�0001750�00000004464�11700667477�013370� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "tk.h" #include "tkWinInt.h" #include "tkFont.h" #include "vector.h" #include "rotstr.h" #define R2D(x) ((x*180)/M_PI) void XDrawRotString(Display* display, Drawable drawable, GC gc, Vector& vv, double angle, const char* text) { // assumes gc->function == GXcopy long angle10 = R2D(angle)*10; TkFont* font = (TkFont*)(gc->font); if (!font) return; TkWinDCState state; HDC hdc = TkWinGetDrawableDC(display, drawable, &state); // logfont LOGFONT logfont; ZeroMemory(&logfont, sizeof(logfont)); int size = MulDiv(font->fa.size, GetDeviceCaps(hdc, LOGPIXELSY), 72); logfont.lfHeight = -size; logfont.lfWidth = 0; logfont.lfEscapement = angle10; logfont.lfOrientation = angle10; logfont.lfWeight = (font->fa.weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; logfont.lfItalic = font->fa.slant; logfont.lfUnderline = font->fa.underline; logfont.lfStrikeOut = font->fa.overstrike; logfont.lfCharSet = DEFAULT_CHARSET; logfont.lfOutPrecision = OUT_TT_PRECIS; logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; strcpy(logfont.lfFaceName, font->fa.family); // hfont HFONT hfont = CreateFontIndirect(&logfont); if (!hfont) return; HFONT ohfont = (HFONT)SelectObject(hdc, hfont); // clip TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { SelectClipRgn(hdc, (HRGN) clipPtr->value.region); OffsetClipRgn(hdc, gc->clip_x_origin, gc->clip_y_origin); } // We need a slight shift in Y, I don't know why Matrix mm = Translate(-vv) * Rotate(-angle) * Translate(0,-int(size/10.)) * Rotate(angle) * Translate(vv); Vector tt = vv*mm; // do it SetTextAlign(hdc, TA_LEFT | TA_BASELINE); SetTextColor(hdc, gc->foreground); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, (int)tt[0], (int)tt[1], text, strlen(text)); // cleanup SelectClipRgn(hdc, NULL); SelectObject(hdc, ohfont); DeleteObject(hfont); TkWinReleaseDrawableDC(drawable, hdc, &state); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/win32lib.C�����������������������������������������������������������������������������0000755�0001750�0001750�00000006534�11761167304�013456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <windows.h> #include "tkwin32.h" #include "win32lib.h" void win32Begin() { if (tkwin32) tkwin32->begin(); } void win32End() { if (tkwin32) tkwin32->end(); } void win32Color(XColor* clr) { if (clr) { int red = clr->red >> 8; int green = clr->green >> 8; int blue = clr->blue >> 8; if (tkwin32) tkwin32->color(red,green,blue); } } void win32Width(float w) { float ww = w * tkwin32->getPageScale(); if (tkwin32) tkwin32->width(ww); } void win32Dash(float* d, int n) { int i; if (tkwin32){ float *dd=NULL; if( (dd=(float *)calloc(n, sizeof(float))) ){ for(i=0; i<n; i++){ dd[i] = d[i] * tkwin32->getPageScale(); } } else dd = d; tkwin32->dash(dd,n); if(dd) free(dd); } } void win32Font(Tk_Font f) { if (tkwin32) tkwin32->font(f); } void win32Clip(Vector v, Vector s) { if (tkwin32) { Vector vv1 = v*tkwin32->getCanvasToPage(); Vector vv2 = (v+s)*tkwin32->getCanvasToPage(); Vector ss = vv2-vv1; tkwin32->clip(vv1[0],vv1[1],ss[0],ss[1]); } } void win32DrawText(Vector v, float ang, const char* text) { if (tkwin32) { Vector vv = v*tkwin32->getCanvasToPage(); tkwin32->drawText(vv[0], vv[1], ang, text); } } void win32DrawLine(Vector v0, Vector v1) { if (tkwin32) { Vector vv0 = v0*tkwin32->getCanvasToPage(); Vector vv1 = v1*tkwin32->getCanvasToPage(); int n = 2; float x[2]; float y[2]; x[0] = vv0[0]; y[0] = vv0[1]; x[1] = vv1[0]; y[1] = vv1[1]; tkwin32->drawLines(x,y,n); } } void win32DrawLines(Vector* v, int n) { if (tkwin32) { float xx[n]; float yy[n]; for(int ii=0; ii<n; ii++) { Vector vv = v[ii]*tkwin32->getCanvasToPage(); xx[ii] = vv[0]; yy[ii] = vv[1]; } tkwin32->drawLines(xx,yy,n); } } void win32DrawRect(Vector v, Vector s) { if (tkwin32) { Vector vv1 = v*tkwin32->getCanvasToPage(); Vector ss = s*tkwin32->getPageScale(); tkwin32->drawRect(vv1[0], vv1[1], ss[0], ss[1]); } } void win32DrawArc(Vector v, float rad, float ang1, float ang2) { if (tkwin32) { Vector vv = v*tkwin32->getCanvasToPage(); float rr = rad*tkwin32->getPageScale(); tkwin32->drawArc(vv[0], vv[1], rr, ang1, ang2); } } void win32DrawCurve(Vector v0, Vector t0, Vector t1, Vector v1) { if (tkwin32) { Vector vv0 = v0*tkwin32->getCanvasToPage(); Vector tt0 = t0*tkwin32->getCanvasToPage(); Vector tt1 = t1*tkwin32->getCanvasToPage(); Vector vv1 = v1*tkwin32->getCanvasToPage(); tkwin32->drawCurve(vv0[0], vv0[1], tt0[0], tt0[1], tt1[0], tt1[1], vv1[0], vv1[1]); } } void win32FillPolygon(Vector* v, int n) { if (tkwin32) { float xx[n]; float yy[n]; for(int ii=0; ii<n; ii++) { Vector vv = v[ii]*tkwin32->getCanvasToPage(); xx[ii] = vv[0]; yy[ii] = vv[1]; } tkwin32->fillPolygon(xx,yy,n); } } void win32BitmapCreate(void* img, int width, int height, const Vector& v, const Vector& s) { if (tkwin32) { Vector vv1 = v*tkwin32->getCanvasToPage(); Vector vv2 = (v+s)*tkwin32->getCanvasToPage(); Vector ss = vv2-vv1; tkwin32->bitmapCreate(img, width, height, vv1[0], vv1[1], ss[0], ss[1]); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/rotstr.h�������������������������������������������������������������������������������0000644�0001750�0001750�00000000557�11700667477�013434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __rotstr_h__ #define __rotstr_h__ #include <tk.h> class Vector; void XDrawRotString(Display* display, Drawable drawable, GC gc, Vector& v, double angle, const char* text); #endif �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/xxlib.C��������������������������������������������������������������������������������0000644�0001750�0001750�00000003031�11700667477�013146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include "tk.h" #include "tkWinInt.h" extern "C" { void XXWarpPointer(Display* display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y) { if (dest_w != None) // move to absolute location XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y); else { // move to relative location POINT p; GetCursorPos(&p); SetCursorPos(p.x+dest_x, p.y+dest_y); } } Bool XXQueryPointer(Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, unsigned int* mask_return) { XQueryPointer(display, w, root_return, child_return, root_x_return, root_y_return, win_x_return, win_y_return, mask_return); *root_return = w; *child_return = w; *win_x_return = *root_x_return; *win_y_return = *root_y_return; } void XPutImage(Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height) { TkPutImage(NULL, 0, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/win32lib.h�����������������������������������������������������������������������������0000755�0001750�0001750�00000001417�11700667477�013527� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __win32lib_h__ #define __win32lib_h__ #include "vector.h" void win32Begin(); void win32End(); void win32Color(XColor*); void win32Width(float); void win32Dash(float*,int); void win32Font(Tk_Font); void win32Clip(Vector, Vector); void win32DrawText(Vector, float, const char*); void win32DrawLine(Vector, Vector); void win32DrawLines(Vector*, int); void win32DrawRect(Vector, Vector); void win32DrawArc(Vector, float, float, float); void win32DrawCurve(Vector, Vector, Vector, Vector); void win32FillPolygon(Vector*, int); void win32BitmapCreate(void*, int, int, const Vector&, const Vector&); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/xxlib.h��������������������������������������������������������������������������������0000644�0001750�0001750�00000002007�11700667477�013215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __xxlib_h__ #define __xxlib_h__ #include <tk.h> extern "C" { // Redefined Routines void XXWarpPointer(Display* display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); Bool XXQueryPointer(Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, unsigned int* mask_return); void XPutImage(Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); // Not Supported inline void XSetClipRectangles(Display* display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle* r, int n, int ordering) {} } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/win/tkwin32.C������������������������������������������������������������������������������0000755�0001750�0001750�00000046737�11761211215�013326� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <unistd.h> #include "tkInt.h" #include "tkFont.h" #include "tkwin32.h" #define R2D(x) ((x*180)/M_PI) using namespace std; extern "C" { int Tkwin32_Init(Tcl_Interp* interp); int Tkwin32Cmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]); HWND Tk_GetHWND(Window window); } TkWin32* tkwin32=NULL; int Tkwin32_Init(Tcl_Interp* interp) { // Define Package Name if (Tcl_PkgProvide(interp, "tkwin32", "1.0") == TCL_ERROR) return TCL_ERROR; // Commands Tcl_CreateCommand(interp, "win32", Tkwin32Cmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); tkwin32 = new TkWin32(interp); if (tkwin32) return TCL_OK; else return TCL_ERROR; } int Tkwin32Cmd(ClientData data,Tcl_Interp *interp,int argc,const char* argv[]) { if (argc>=2) { if (!strncmp(argv[1], "pm", 2)) return tkwin32->pm(argc, argv); else { Tcl_AppendResult(interp, "tkwin32: unknown command: ", argv[1], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkwin32 ?pm?", NULL); return TCL_ERROR; } } TkWin32::TkWin32(Tcl_Interp* intp) { interp = intp; tkwin = Tk_MainWindow(interp); // page setup dialog ZeroMemory(&psd, sizeof(psd)); psd.lStructSize = sizeof(psd); psd.Flags = PSD_RETURNDEFAULT; PageSetupDlg(&psd); // print dialog ZeroMemory(&pd, sizeof(pd)); pd.lStructSize = sizeof(pd); pd.Flags = PD_RETURNDEFAULT; PrintDlg(&pd); // reasonable defaults penStyle = PS_SOLID; penWidth = 1; penColor = RGB(0,0,0); font_ = NULL; dwStyleCount = 0; lpStyle = NULL; pageScale =1; fontScale =1; } // Image Print Mangager int TkWin32::pm(int argc, const char* argv[]) { if (argc >= 3) { if (!strncmp(argv[2], "print", 3)) return tkwin32->pmPrint(argc, argv); else if (!strncmp(argv[2], "pagesetup", 3)) return tkwin32->pmPageSetup(); else { Tcl_AppendResult(interp, "tkwin32 pm: unknown command: ", argv[2], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkwin32 pm ?print?pagesetup?", NULL); return TCL_ERROR; } return TCL_OK; } int TkWin32::pmPrint(int argc, const char* argv[]) { if (argc >= 4) { if (!strncmp(argv[3], "begin", 3)) return tkwin32->pmPrintBegin(argc, argv); else if (!strncmp(argv[3], "end", 3)) return tkwin32->pmPrintEnd(); else if (!strncmp(argv[3], "text", 3)) return tkwin32->pmPrintText(argc, argv); else { Tcl_AppendResult(interp, "tkwin32 pm print: unknown command: ", argv[2], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkwin32 pm print: ?begin?end?text?", NULL); return TCL_ERROR; } return TCL_OK; } int TkWin32::pmPrintBegin(int argc, const char* argv[]) { DOCINFO di; HFONT hfont; TEXTMETRIC tm; int iLinesPerPage; int iHeaderHeight=0; // canvas width and height double width =0; double height =0; if (argc >= 7) { string w(argv[4]); istringstream ww(w); ww >> width; string h(argv[5]); istringstream hh(h); hh >> height; if (width <=0 || height <=0) { Tcl_AppendResult(interp, "Invalid width and/or height.", NULL); return TCL_ERROR; } if (!strncmp(argv[6], "yes", 2)) showDialog = 1; else if (!strncmp(argv[6], "no", 2)) showDialog = 0; } else { Tcl_AppendResult(interp, "usage: tkwin32 pm print begin: ?width height yes|no?", NULL); return TCL_ERROR; } // show dialog, if necessary pd.nFromPage =0; pd.nToPage =0; pd.nMinPage =0; pd.nMaxPage =0; if (!WinPrintDialog()) { Tcl_AppendResult(interp, "0", NULL); return TCL_OK; } // get document info GetDocInfo(&di); // calculate margins GetMarginInfo(); // get font hfont = (HFONT)GetStockObject(ANSI_FIXED_FONT); SelectObject(pd.hDC, hfont); // scaling factors { Vector canvas(width,height); Vector page(iWidth, iHeight); Vector paper(iPhysWidth, iPhysHeight); if (page[0]/canvas[0] < page[1]/canvas[1]) { pageScale = page[0]/canvas[0]; fontScale = double(iWidth)/iHorzRes; } else { pageScale = page[1]/canvas[1]; fontScale = double(iHeight)/iVertRes; } // build coordinate matrix canvasToPage = Translate(-canvas/2) * Scale(pageScale) * Translate(paper/2); } // work out the character and line dimensions for the current font GetTextMetrics(pd.hDC, &tm); yChar = tm.tmHeight; iLinesPerPage = (iHeight - iHeaderHeight) / yChar; // start document and page if (StartDoc(pd.hDC, &di) <= 0) return TCL_ERROR; if (StartPage(pd.hDC) <= 0) return TCL_ERROR; // ok, we are good for go Tcl_AppendResult(interp, "1", NULL); return TCL_OK; } int TkWin32::pmPrintEnd() { // end of page -- send to printer if (EndPage(pd.hDC) <= 0) return TCL_ERROR; if (EndDoc(pd.hDC) <= 0) return TCL_ERROR; // close file and release graphics context WinPrintRelease(); return TCL_OK; } int TkWin32::pmPrintText(int argc, const char* argv[]) { // text if( argc < 5 ){ Tcl_AppendResult(interp, "usage: tkwin32 pm print text: ?text?", NULL); return TCL_ERROR; } // show dialog pd.nFromPage =1; pd.nToPage = 0xFFFF; pd.nMinPage =1; pd.nMaxPage = 0xFFFF; if (!WinPrintDialog()) { // user cancelled Tcl_AppendResult(interp, "0", NULL); return TCL_OK; } if (!WinPrintText(argv[4], TYPE_STRING)) return TCL_ERROR; // Tcl_AppendResult(interp, "1", NULL); return TCL_OK; } int TkWin32::pmPageSetup() { if (WinPrintPageSetup()) Tcl_AppendResult(interp, "1", NULL); else Tcl_AppendResult(interp, "0", NULL); return TCL_OK; } UINT TkWin32::QueryAbort() { MSG msg; BOOL bAbort = FALSE; while (!bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); switch(msg.message){ case WM_QUIT: PostQuitMessage(0); bAbort = TRUE; break; case WM_KEYDOWN: if(msg.wParam == VK_ESCAPE){ bAbort = TRUE; } break; } DispatchMessage(&msg); } return !bAbort; } // routines for handling documents (files or string buffers) BOOL TkWin32::DocOpen(const char *s, int xmaxline, int xtype) { // sanity check if( !s || !*s ){ return FALSE; } type = xtype; switch(type){ case TYPE_FILE: if( !(fd= fopen(s, "r")) ){ return FALSE; } break; case TYPE_STRING: buf = strdup(s); bptr = buf; break; default: return FALSE; } /* allocate space for individual lines */ maxline = xmaxline; if( !(lines=(char **)calloc(maxline, sizeof(char *))) ){ return FALSE; } nline = 0; return TRUE; } int TkWin32::DocNextPage() { int i; char lbuf[SZ_LINE]; nline = 0; switch(type){ case TYPE_FILE: for(i=0; i<maxline && fgets(lbuf, SZ_LINE, fd); i++){ lines[nline++] = strdup(lbuf); } break; case TYPE_STRING: for(i=0; i<maxline; i++){ if( !*bptr ) break; // start of new line lines[nline++] = bptr; // skip to end of line or end of string while( *bptr && (*bptr != '\n') ){ bptr++; } // remove CR from string and bump ptr if( *bptr == '\n' ){ *bptr++ = '\0'; } } break; default: break; } return nline; } void TkWin32::DocClose() { int i; switch(type){ case TYPE_FILE: if( nline ){ for(i=0; i<nline; i++){ if( lines[i] ){ free(lines[i]); lines[i] = NULL; } } nline = 0; } maxline = 0; if( fd ){ fclose(fd); fd = NULL; } break; case TYPE_STRING: if( buf ) free(buf); bptr = NULL; break; default: break; } type = 0; } BOOL TkWin32::GetDocInfo(DOCINFO *di) { // document information ZeroMemory(di, sizeof(*di)); di->cbSize = sizeof(DOCINFO); di->lpszDocName = DEF_DOCNAME; di->lpszOutput = (LPTSTR) NULL; di->lpszDatatype = (LPTSTR) NULL; di->fwType = 0; return TRUE; } BOOL TkWin32::GetMarginInfo() { RECT rc; // physical properties of paper iPhysWidth = GetDeviceCaps(pd.hDC, PHYSICALWIDTH); iPhysHeight = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT); iPhysOffX = GetDeviceCaps(pd.hDC, PHYSICALOFFSETX); iPhysOffY = GetDeviceCaps(pd.hDC, PHYSICALOFFSETY); iHorzRes = GetDeviceCaps(pd.hDC, HORZRES); iVertRes = GetDeviceCaps(pd.hDC, VERTRES); // raw margins rc = psd.rtMargin; margins.left = MulDiv(rc.left, GetDeviceCaps(pd.hDC, LOGPIXELSX), 1000); margins.top = MulDiv(rc.top, GetDeviceCaps(pd.hDC, LOGPIXELSY), 1000); margins.right = MulDiv(rc.right, GetDeviceCaps(pd.hDC, LOGPIXELSX), 1000); margins.bottom = MulDiv(rc.bottom,GetDeviceCaps(pd.hDC, LOGPIXELSY),1000); // adjusted margins iLeftAdjust = margins.left - iPhysOffX; iTopAdjust = margins.top - iPhysOffY; iRightAdjust = margins.right - (iPhysWidth - iPhysOffX - iHorzRes); iBottomAdjust = margins.right - (iPhysHeight - iPhysOffY - iVertRes); // size of printable area iWidth = iHorzRes - (iLeftAdjust + iRightAdjust); iHeight = iVertRes - (iTopAdjust + iBottomAdjust); return TRUE; } BOOL TkWin32::WinPrintPageSetup() { Tk_MakeWindowExist(tkwin); psd.hwndOwner = Tk_GetHWND(Tk_WindowId(tkwin)); psd.Flags = PSD_MARGINS; if (PageSetupDlg(&psd)) return TRUE; else return FALSE; } BOOL TkWin32::WinPrintDialog() { Tk_MakeWindowExist(tkwin); pd.hwndOwner = Tk_GetHWND(Tk_WindowId(tkwin)); pd.Flags = PD_RETURNDC | PD_ALLPAGES | PD_NOSELECTION; pd.nCopies =1; if (PrintDlg(&pd)) { psd.hDevMode = pd.hDevMode; psd.hDevNames = pd.hDevNames; return TRUE; } else return FALSE; } BOOL TkWin32::WinPrintText(const char *s, int type) { int iLine; int iCurPage; int iColCopy, iColCopies; int iNonCopy, iNonColCopies; int iLinesPerPage; int yChar; int iHeaderHeight=0; BOOL bSuccess=TRUE, bUserAbort=FALSE; DOCINFO di; HFONT hfont; TEXTMETRIC tm; HANDLE hold; // get document info GetDocInfo(&di); // calculate margins GetMarginInfo(); // get font hfont = (HFONT)GetStockObject(ANSI_FIXED_FONT); // Setup the current device context SetMapMode(pd.hDC, MM_TEXT); SelectObject(pd.hDC, hfont); // work out the character and line dimensions for the current font GetTextMetrics(pd.hDC, &tm); yChar = tm.tmHeight; iLinesPerPage = (iHeight - iHeaderHeight) / yChar; // print loop if(StartDoc(pd.hDC, &di) > 0){ // loop for collated printing: print multiple copies of the whole doc iColCopies = ((pd.Flags & PD_COLLATE) ? pd.nCopies : 1); for(iColCopy = 0; iColCopy < iColCopies; iColCopy++){ // open or re-open the document if( DocOpen(s, iLinesPerPage, type) == FALSE ){ return FALSE; } // get next page for(iCurPage=1; DocNextPage(); iCurPage++){ // skip if we are not up to first desired page if( iCurPage < pd.nFromPage ) continue; // done if we are past the last desired page if( iCurPage > pd.nToPage ) break; // loop for non-collated printing: print each page multiple times iNonColCopies = ((pd.Flags & PD_COLLATE) ? 1 : pd.nCopies); for(iNonCopy = 0; iNonCopy < iNonColCopies; iNonCopy++){ if(StartPage(pd.hDC) <= 0) { bSuccess = FALSE; break; } // printing is offset by the amount specified for the margins SetViewportOrgEx(pd.hDC, iLeftAdjust, iTopAdjust, NULL); // select the fixed-width font into the printer DC hold = SelectObject(pd.hDC, hfont); // print the current file line by line for(iLine=0; iLine < nline; iLine++) { // output a line of text to the printer TextOut(pd.hDC, 0, yChar * iLine + iHeaderHeight, lines[iLine], lstrlen(lines[iLine]) - 1); bUserAbort = !QueryAbort(); } SelectObject(pd.hDC, hold); if( EndPage(pd.hDC ) < 0){ bSuccess = FALSE; break; } bUserAbort = !QueryAbort(); if(bUserAbort) break; } if(!bSuccess || bUserAbort) break; } // close the document, free up internal memory DocClose(); if(!bSuccess || bUserAbort) break; } } else{ bSuccess = FALSE; } // send to printer if(bSuccess && !bUserAbort) { EndDoc(pd.hDC); return TRUE; } // abort print job else{ AbortDoc(pd.hDC); return FALSE; } } BOOL TkWin32::WinPrintRelease() { if (pd.hDC) { DeleteDC(pd.hDC); return TRUE; } else return FALSE; } void TkWin32::SetPen(int flag) { LOGBRUSH lb; int mystyle; DWORD mydwStyleCount=0; DWORD *mylpStyle=NULL; if( flag ){ // CreatePen: non-solid lines must be width 1 // hPen = CreatePen(penStyle, penWidth, penColor); lb.lbStyle = BS_SOLID; lb.lbColor = penColor; lb.lbHatch = 0; mystyle = penStyle; // don't use userstyle unless width is small if( mystyle == PS_USERSTYLE ){ if( (penWidth / pageScale) < 2 ){ mydwStyleCount = dwStyleCount; mylpStyle = lpStyle; } else { mystyle = PS_DOT; } } mystyle |= PS_GEOMETRIC; mystyle |= PS_ENDCAP_SQUARE; mystyle |= PS_JOIN_BEVEL; hPen = ExtCreatePen(mystyle, penWidth, &lb, mydwStyleCount, mylpStyle); ohPen = (HPEN)SelectObject(pd.hDC, hPen); hBrush = CreateSolidBrush(penColor); ohBrush = (HBRUSH)SelectObject(pd.hDC, hBrush); SetTextColor(pd.hDC, penColor); } else{ SelectObject(pd.hDC, ohPen); DeleteObject(hPen); SelectObject(pd.hDC, ohBrush); DeleteObject(hBrush); } } // drawing routines called by routines in win32lib.C void TkWin32::begin() { SaveDC(pd.hDC); } void TkWin32::end() { RestoreDC(pd.hDC, -1); } void TkWin32::color(int red, int green, int blue) { penColor = RGB(red, green, blue); } void TkWin32::width(float ww) { penWidth = (int)ww; } void TkWin32::dash(float* dd, int nn) { int i; if(nn){ penStyle = PS_USERSTYLE; if(lpStyle) free(lpStyle); if((lpStyle = (DWORD *)calloc(nn, sizeof(DWORD)))) { dwStyleCount = nn; for(i=0; i<nn; i++) lpStyle[i] = (DWORD)dd[i]; } } else{ penStyle = PS_SOLID; if(lpStyle) free(lpStyle); lpStyle = NULL; dwStyleCount = 0; } } void TkWin32::font(Tk_Font ff) { font_ = (TkFont*)ff; } void TkWin32::clip(float x, float y, float w, float h) { /* sigh ... the subtracted offets were determine empirically: they are what is required to remove unwanted edges */ HRGN hRgn = CreateRectRgn((int)x, (int)y, (int)(x+w-1), (int)(y+h-3)); SelectClipRgn(pd.hDC, hRgn); DeleteObject(hRgn); } void TkWin32::drawText(float x, float y, float angle, const char* text) { Vector vv(x,y); long angle10 = R2D(angle)*10; if (!font_) return; // TkWinDCState state; // HDC hdc = TkWinGetDrawableDC(display, drawable, &state); // logfont LOGFONT logfont; ZeroMemory(&logfont, sizeof(logfont)); // int size = MulDiv(font_->fa.size, GetDeviceCaps(hdc, LOGPIXELSY), 72); int size = MulDiv(font_->fa.size, 96, 72) * pageScale; logfont.lfHeight = -size; logfont.lfWidth = 0; logfont.lfEscapement = angle10; logfont.lfOrientation = angle10; logfont.lfWeight = (font_->fa.weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; logfont.lfItalic = font_->fa.slant; logfont.lfUnderline = font_->fa.underline; logfont.lfStrikeOut = font_->fa.overstrike; logfont.lfCharSet = DEFAULT_CHARSET; logfont.lfOutPrecision = OUT_TT_PRECIS; logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; // logfont.lfQuality = PROOF_QUALITY; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; strcpy(logfont.lfFaceName, font_->fa.family); // hfont HFONT hfont = CreateFontIndirect(&logfont); if (!hfont) return; HFONT ohfont = (HFONT)SelectObject(pd.hDC, hfont); // We need a slight shift in Y, I don't know why Matrix mm = Translate(-vv) * Rotate(-angle) * Translate(0,-int(size/10.)) * Rotate(angle) * Translate(vv); Vector tt = vv*mm; // do it SetTextAlign(pd.hDC, TA_LEFT | TA_BASELINE); SetTextColor(pd.hDC, penColor); SetBkMode(pd.hDC, TRANSPARENT); TextOut(pd.hDC, (int)tt[0], (int)tt[1], text, strlen(text)); // cleanup SelectObject(pd.hDC, ohfont); DeleteObject(hfont); // TkWinReleaseDrawableDC(drawable, hdc, &state); } void TkWin32::drawLines(float* x, float* y, int n) { int ii; SetPen(1); MoveToEx(pd.hDC, (int)x[0], (int)y[0], NULL); for (int ii=1; ii<n; ii++){ LineTo(pd.hDC, (int)x[ii], (int)y[ii]); } SetPen(0); } void TkWin32::drawRect(float x, float y, float w, float h) { float xx[5]; float yy[5]; xx[0] = x; yy[0] = y; xx[1] = x+w; yy[1] = y; xx[2] = x+w; yy[2] = y-h; xx[3] = x; yy[3] = y-h; xx[4] = xx[0]; yy[4] = yy[0]; SetPen(1); TkWin32::drawLines(xx, yy, 5); SetPen(0); } void TkWin32::drawArc(float x, float y, float rad, float ang1, float ang2) { double xscal1, yscal1, xscal2, yscal2; ang1 += M_PI/2; ang2 += M_PI/2; xscal1 = sin(ang1); yscal1 = cos(ang1); xscal2 = sin(ang2); yscal2 = cos(ang2); SetPen(1); Arc(pd.hDC, (int)(x-rad), (int)(y-rad), (int)(x+rad), (int)(y+rad), (int)(x+(xscal1*rad)), (int)(y+(yscal1*rad)), (int)(x+(xscal2*rad)), (int)(y+(yscal2*rad))); SetPen(0); } void TkWin32::drawCurve(float x0, float y0, float u0, float v0, float u1, float v1, float x1, float y1) { POINT apt[4]; apt[0].x = (int)x0; apt[0].y = (int)y0; apt[1].x = (int)u0; apt[1].y = (int)v0; apt[2].x = (int)u1; apt[2].y = (int)v1; apt[3].x = (int)x1; apt[3].y = (int)y1; SetPen(1); PolyBezier(pd.hDC, apt, 4); SetPen(0); } void TkWin32::fillPolygon(float* x, float* y, int n) { int ii; POINT *apt; if( !(apt=(POINT *)calloc(n+1, sizeof(POINT))) ){ return; } for(ii=0; ii<n; ii++){ apt[ii].x = (int)x[ii]; apt[ii].y = (int)y[ii]; } SetPen(1); Polygon(pd.hDC, apt, n); SetPen(0); free(apt); } void TkWin32::bitmapCreate(void* data, int width, int height, float x, float y, float w, float h) { HDC dcMem; BITMAPINFO *infoPtr; HBITMAP hBitmap; XFORM xForm; int ogm; // create in-memoy DIB bitmap dcMem = CreateCompatibleDC(pd.hDC); infoPtr = (BITMAPINFO*) ckalloc(sizeof(BITMAPINFOHEADER)); infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); infoPtr->bmiHeader.biWidth = (int)width; infoPtr->bmiHeader.biHeight = (int)height; infoPtr->bmiHeader.biPlanes = 1; infoPtr->bmiHeader.biBitCount = 24; infoPtr->bmiHeader.biCompression = BI_RGB; infoPtr->bmiHeader.biSizeImage = 0; infoPtr->bmiHeader.biXPelsPerMeter = 0; infoPtr->bmiHeader.biYPelsPerMeter = 0; infoPtr->bmiHeader.biClrImportant = 0; infoPtr->bmiHeader.biClrUsed = 0; hBitmap = CreateDIBitmap(pd.hDC, &infoPtr->bmiHeader, CBM_INIT, data, infoPtr, DIB_RGB_COLORS); hBitmap = (HBITMAP)SelectObject(dcMem, hBitmap); // set up scale and translation of bitmap on to page ogm = SetGraphicsMode(pd.hDC, GM_ADVANCED); xForm.eM11 = (FLOAT) pageScale; xForm.eM12 = (FLOAT) 0.0; xForm.eM21 = (FLOAT) 0.0; xForm.eM22 = (FLOAT) pageScale; xForm.eDx = (FLOAT) x; xForm.eDy = (FLOAT) y; SetWorldTransform(pd.hDC, &xForm); // send to printer BitBlt(pd.hDC, 0, 0, (int)w, (int)h, dcMem, 0, 0, SRCCOPY); // reset scale and translation xForm.eM11 = (FLOAT) 1.0; xForm.eM12 = (FLOAT) 0.0; xForm.eM21 = (FLOAT) 0.0; xForm.eM22 = (FLOAT) 1.0; xForm.eDx = (FLOAT) 0; xForm.eDy = (FLOAT) 0; SetWorldTransform(pd.hDC, &xForm); SetGraphicsMode(pd.hDC, ogm); // clean up DeleteObject(SelectObject(dcMem, hBitmap)); DeleteDC(dcMem); } ���������������������������������./saods9/win/tkwin32.h������������������������������������������������������������������������������0000755�0001750�0001750�00000004773�11700667477�013407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __tkwin32_h__ #define __tkwin32_h__ #include <tk.h> // must define vector.h before windows.h to avoid conflicts with min,max #include "vector.h" #include <Windows.h> #define DEF_DOCNAME "SAO/DS9" #define SZ_LINE 1024 #define TYPE_FILE 1 #define TYPE_STRING 2 struct TkFont; class TkWin32 { private: Tcl_Interp* interp; Tk_Window tkwin; // print information PRINTDLG pd; PAGESETUPDLG psd; HPEN hPen; HPEN ohPen; HBRUSH hBrush; HBRUSH ohBrush; int penStyle; int penWidth; COLORREF penColor; DWORD dwStyleCount; DWORD *lpStyle; int showDialog; // font info TkFont* font_; // margin info RECT margins; int iLeftAdjust; int iTopAdjust; int iRightAdjust; int iBottomAdjust; int iPhysWidth; int iPhysHeight; int iPhysOffX; int iPhysOffY; int iHorzRes; int iVertRes; int iWidth; int iHeight; int yChar; // doc info int type; char *buf; char *bptr; FILE *fd; int nline; int maxline; char **lines; // scaling double pageScale; double fontScale; Matrix canvasToPage; // UINT CALLBACK QueryAbort(); UINT QueryAbort(); BOOL DocNew(); BOOL DocOpen(const char *s, int maxline, int type); int DocNextPage(); void DocClose(); BOOL DocFree(); BOOL GetDocInfo(DOCINFO *di); BOOL GetMarginInfo(); void SetPen(int flag); BOOL WinPrintPageSetup(); BOOL WinPrintDialog(); BOOL WinPrintText(const char *s, int type); BOOL WinPrintRelease(); int pmPrint(int, const char**); int pmPrintBegin(int, const char**); int pmPrintEnd(); int pmPrintText(int, const char**); int pmPageSetup(); public: TkWin32(Tcl_Interp*); ~TkWin32() {}; int pm(int, const char**); double getPageScale() {return pageScale;} const Matrix& getCanvasToPage() {return canvasToPage;} void begin(); void end(); void color(int red, int green, int blue); void width(float); void dash(float*,int); void font(Tk_Font); void clip(float, float, float, float); void drawText(float, float, float, const char*); void drawLines(float*, float*, int); void drawRect(float, float, float, float); void drawArc(float, float, float, float, float); void drawCurve(float, float, float, float, float, float, float, float); void fillPolygon(float*, float*, int); void bitmapCreate(void*, int, int, float, float, float, float); }; extern TkWin32* tkwin32; #endif �����./saods9/COPYING������������������������������������������������������������������������������������0000644�0001750�0001750�00000077330�12061452202�012142� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/�������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012232� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/mosaic.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000011442�12131345761�014064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** Mosaic Image ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" echo " -mosaic" ds9 -mosaic mosaic/mosaicimage.fits & KillIt echo " -mosaic wcs" ds9 -mosaic wcs mosaic/mosaicimage.fits & KillIt echo " -mosaicwcs" ds9 -mosaicwcs mosaic/mosaicimage.fits & KillIt echo " -mosaic iraf" ds9 -mosaic iraf mosaic/mosaicimage.fits & KillIt echo " -mosaiciraf" ds9 -mosaiciraf mosaic/mosaicimage.fits & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" echo " -mosaic" cat mosaic/mosaicimage.fits | ds9 -mosaic -& KillIt echo " -mosaic wcs" cat mosaic/mosaicimage.fits | ds9 -mosaic wcs -& KillIt echo " -mosaicwcs" cat mosaic/mosaicimage.fits | ds9 -mosaicwcs -& KillIt echo " -mosaic iraf" cat mosaic/mosaicimage.fits | ds9 -mosaic iraf -& KillIt echo " -mosaiciraf" cat mosaic/mosaicimage.fits | ds9 -mosaiciraf -& KillIt echo "PASSED" fi # Save if [ "$1" = "save" -o -z "$1" ]; then echo "Testing Command Save" echo " -mosaic" opt="" opt="$opt -save mosaic foo.fits -sleep .1" opt="$opt -frame new -mosaic foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaic mosaic/mosaicimage.fits "$opt" -exit echo " -mosaic wcs" opt="" opt="$opt -save mosaic wcs foo.fits -sleep .1" opt="$opt -frame new -mosaic wcs foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaic wcs mosaic/mosaicimage.fits "$opt" -exit echo " -mosaicwcs" opt="" opt="$opt -save mosaicwcs foo.fits -sleep .1" opt="$opt -frame new -mosaicwcs foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaicwcs mosaic/mosaicimage.fits "$opt" -exit echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 echo " -mosaic" xpaset -p ds9 mosaic mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaic wcs" xpaset -p ds9 mosaic wcs mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicwcs" xpaset -p ds9 mosaicwcs mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaic iraf" xpaset -p ds9 mosaic iraf mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaiciraf" xpaset -p ds9 mosaiciraf mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 echo " -mosaic" cat mosaic/mosaicimage.fits | xpaset ds9 mosaic if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaic wcs" cat mosaic/mosaicimage.fits | xpaset ds9 mosaic wcs if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicwcs" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicwcs if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaic iraf" cat mosaic/mosaicimage.fits | xpaset ds9 mosaic iraf if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaiciraf" cat mosaic/mosaicimage.fits | xpaset ds9 mosaiciraf if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 echo " -mosaic" xpaset -p ds9 tile xpaset -p ds9 mosaic mosaic/mosaicimage.fits xpaget ds9 mosaic > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaic foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear echo " -mosaic wcs" xpaset -p ds9 tile xpaset -p ds9 mosaic wcs mosaic/mosaicimage.fits xpaget ds9 mosaic wcs > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaic wcs foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear echo " -mosaicwcs" xpaset -p ds9 tile xpaset -p ds9 mosaicwcs mosaic/mosaicimage.fits xpaget ds9 mosaicwcs > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaicwcs foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/all.sh�������������������������������������������������������������������������������0000755�0001750�0001750�00000000307�12132057400�013346� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#io.sh #xpa.sh #command.sh #samp.sh parse.sh crop.sh regions.sh regions3d.sh plot.sh scale.sh lock.sh prefs.sh matrix.sh align.sh wcs.sh wcs2.sh vo.sh xpa vo.sh mime print.sh backup.sh analysis.sh �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/rgbcube.sh���������������������������������������������������������������������������0000755�0001750�0001750�00000000051�12107266155�014216� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fullrgb.sh RGBCube rgbcube rgbcube $1 $2 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000000600�12073112720�013712� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "Prefs Tests" doit() { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ]; do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } echo echo "*** prefs.sh ***" for f in prefs/*.prf do echo "Testing $f" rm -f ~/.ds9.prf cp $f ~/.ds9.prf doit xpaset -p ds9 exit rm -f ~/.ds9.prf echo "PASSED" done ��������������������������������������������������������������������������������������������������������������������������������./saods9/tests/cube.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000045�12113456763�013531� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������full.sh Cube rgbcube fits save $1 $2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/array.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000042605�12131345761�013734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } DoXPA () { echo "$1" xpaset -p ds9 array $2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdin () { echo "$1" cat $2 | xpaset ds9 array $3 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdout () { echo "$1" xpaset -p ds9 tile xpaset -p ds9 array $2 xpaget ds9 array $3 > foo.arr xpaset -p ds9 frame new xpaset -p ds9 array foo.arr$4 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear } initit () { echo "Testing $1" unset opt } testit () { opt="$opt -export array foo.arr $1 -sleep .1" opt="$opt -frame new -array foo.arr$2" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" } doit () { eval ds9 -tile -array $1 "$opt" -exit echo "PASSED" } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** array.sh ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command File" echo ".. char" ds9 -array array/char.arr[dim=256,bitpix=8] & KillIt echo ".. char gzip" ds9 -array array/char.arr.gz[dim=256,bitpix=8] & KillIt echo ".. short little" ds9 -array array/short_little.arr[dim=256,bitpix=16,arch=little] & KillIt echo ".. short little gzip" ds9 -array array/short_little.arr.gz[dim=256,bitpix=16,arch=little] & KillIt echo ".. short big" ds9 -array array/short_big.arr[dim=256,bitpix=16,arch=big] & KillIt echo ".. short big gzip" ds9 -array array/short_big.arr.gz[dim=256,bitpix=16,arch=big] & KillIt echo ".. ushort little" ds9 -array array/ushort_little.arr[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" ds9 -array array/ushort_little.arr.gz[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort big" ds9 -array array/ushort_big.arr[dim=256,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" ds9 -array array/ushort_big.arr.gz[dim=256,bitpix=-16,arch=big] & KillIt echo ".. int little" ds9 -array array/int_little.arr[dim=256,bitpix=32,arch=little] & KillIt echo ".. int little gzip" ds9 -array array/int_little.arr.gz[dim=256,bitpix=32,arch=little] & KillIt echo ".. int big" ds9 -array array/int_big.arr[dim=256,bitpix=32,arch=big] & KillIt echo ".. int big gzip" ds9 -array array/int_big.arr.gz[dim=256,bitpix=32,arch=big] & KillIt echo ".. longlong little" ds9 -array array/longlong_little.arr[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" ds9 -array array/longlong_little.arr.gz[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong big" ds9 -array array/longlong_big.arr[dim=256,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" ds9 -array array/longlong_big.arr.gz[dim=256,bitpix=64,arch=big] & KillIt echo ".. float little" ds9 -array array/float_little.arr[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" ds9 -array array/float_little.arr.gz[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float big" ds9 -array array/float_big.arr[dim=256,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" ds9 -array array/float_big.arr.gz[dim=256,bitpix=-32,arch=big] & KillIt echo ".. double little" ds9 -array array/double_little.arr[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" ds9 -array array/double_little.arr.gz[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double big" ds9 -array array/double_big.arr[dim=256,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" ds9 -array array/double_big.arr.gz[dim=256,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Command Stdin" echo ".. char" cat array/char.arr | ds9 -array -[dim=256,bitpix=8] & KillIt echo ".. char gzip" cat array/char.arr.gz | ds9 -array -[dim=256,bitpix=8] & KillIt echo ".. short little" cat array/short_little.arr | ds9 -array -[dim=256,bitpix=16,arch=little] & KillIt echo ".. short little gzip" cat array/short_little.arr.gz | ds9 -array -[dim=256,bitpix=16,arch=little] & KillIt echo ".. short big" cat array/short_big.arr | ds9 -array -[dim=256,bitpix=16,arch=big] & KillIt echo ".. short big gzip" cat array/short_big.arr.gz | ds9 -array -[dim=256,bitpix=16,arch=big] & KillIt echo ".. ushort little" cat array/ushort_little.arr | ds9 -array -[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" cat array/ushort_little.arr.gz | ds9 -array -[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort big" cat array/ushort_big.arr | ds9 -array -[dim=256,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" cat array/ushort_big.arr.gz | ds9 -array -[dim=256,bitpix=-16,arch=big] & KillIt echo ".. int little" cat array/int_little.arr | ds9 -array -[dim=256,bitpix=32,arch=little] & KillIt echo ".. int little gzip" cat array/int_little.arr.gz | ds9 -array -[dim=256,bitpix=32,arch=little] & KillIt echo ".. int big" cat array/int_big.arr | ds9 -array -[dim=256,bitpix=32,arch=big] & KillIt echo ".. int big gzip" cat array/int_big.arr.gz | ds9 -array -[dim=256,bitpix=32,arch=big] & KillIt echo ".. longlong little" cat array/longlong_little.arr | ds9 -array -[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" cat array/longlong_little.arr.gz | ds9 -array -[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong big" cat array/longlong_big.arr | ds9 -array -[dim=256,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" cat array/longlong_big.arr.gz | ds9 -array -[dim=256,bitpix=64,arch=big] & KillIt echo ".. float little" cat array/float_little.arr | ds9 -array -[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" cat array/float_little.arr.gz | ds9 -array -[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float big" cat array/float_big.arr | ds9 -array -[dim=256,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" cat array/float_big.arr.gz | ds9 -array -[dim=256,bitpix=-32,arch=big] & KillIt echo ".. double little" cat array/double_little.arr | ds9 -array -[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" cat array/double_little.arr.gz | ds9 -array -[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double big" cat array/double_big.arr | ds9 -array -[dim=256,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" cat array/double_big.arr.gz | ds9 -array -[dim=256,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # export if [ "$1" = "export" -o -z "$1" ]; then echo "Testing Command export" initit ".. char" testit little [dim=256,bitpix=8] doit array/char.arr[dim=256,bitpix=8] initit ".. short little little" testit little [dim=256,bitpix=16,arch=little] doit array/short_little.arr[dim=256,bitpix=16,arch=little] initit ".. short little big" testit big [dim=256,bitpix=16,arch=big] doit array/short_little.arr[dim=256,bitpix=16,arch=little] initit ".. short big little" testit little [dim=256,bitpix=16,arch=little] doit array/short_big.arr[dim=256,bitpix=16,arch=big] initit ".. short big big" testit big [dim=256,bitpix=16,arch=big] doit array/short_big.arr[dim=256,bitpix=16,arch=big] initit ".. ushort little little" testit little [dim=256,bitpix=-16,arch=little] doit array/ushort_little.arr[dim=256,bitpix=-16,arch=little] initit ".. ushort little big" testit big [dim=256,bitpix=-16,arch=big] doit array/ushort_little.arr[dim=256,bitpix=-16,arch=little] initit ".. ushort big little" testit little [dim=256,bitpix=-16,arch=little] doit array/ushort_big.arr[dim=256,bitpix=-16,arch=big] initit ".. ushort big big" testit big [dim=256,bitpix=-16,arch=big] doit array/ushort_big.arr[dim=256,bitpix=-16,arch=big] initit ".. int little little" testit little [dim=256,bitpix=32,arch=little] doit array/int_little.arr[dim=256,bitpix=32,arch=little] initit ".. int little big" testit big [dim=256,bitpix=32,arch=big] doit array/int_little.arr[dim=256,bitpix=32,arch=little] initit ".. int big little" testit little [dim=256,bitpix=32,arch=little] doit array/int_big.arr[dim=256,bitpix=32,arch=big] initit ".. int big big" testit big [dim=256,bitpix=32,arch=big] doit array/int_big.arr[dim=256,bitpix=32,arch=big] initit ".. longlong little little" testit little [dim=256,bitpix=64,arch=little] doit array/longlong_little.arr[dim=256,bitpix=64,arch=little] initit ".. longlong little big" testit big [dim=256,bitpix=64,arch=big] doit array/longlong_little.arr[dim=256,bitpix=64,arch=little] initit ".. longlong big little" testit little [dim=256,bitpix=64,arch=little] doit array/longlong_big.arr[dim=256,bitpix=64,arch=big] initit ".. longlong big big" testit big [dim=256,bitpix=64,arch=big] doit array/longlong_big.arr[dim=256,bitpix=64,arch=big] initit ".. float little little" testit little [dim=256,bitpix=-32,arch=little] doit array/float_little.arr[dim=256,bitpix=-32,arch=little] initit ".. float little big" testit big [dim=256,bitpix=-32,arch=big] doit array/float_little.arr[dim=256,bitpix=-32,arch=little] initit ".. float big little" testit little [dim=256,bitpix=-32,arch=little] doit array/float_big.arr[dim=256,bitpix=-32,arch=big] initit ".. float big big" testit big [dim=256,bitpix=-32,arch=big] doit array/float_big.arr[dim=256,bitpix=-32,arch=big] initit ".. double little little" testit little [dim=256,bitpix=-64,arch=little] doit array/double_little.arr[dim=256,bitpix=-64,arch=little] initit ".. double little big" testit big [dim=256,bitpix=-64,arch=big] doit array/double_little.arr[dim=256,bitpix=-64,arch=little] initit ".. double big little" testit little [dim=256,bitpix=-64,arch=little] doit array/double_big.arr[dim=256,bitpix=-64,arch=big] initit ".. double big big" testit big [dim=256,bitpix=-64,arch=big] doit array/double_big.arr[dim=256,bitpix=-64,arch=big] fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 DoXPA ".. char" array/char.arr[dim=256,bitpix=8] DoXPA ".. char gzip" array/char.arr.gz[dim=256,bitpix=8] DoXPA ".. short little" array/short_little.arr[dim=256,bitpix=16,arch=little] DoXPA ".. short little gzip" array/short_little.arr.gz[dim=256,bitpix=16,arch=little] DoXPA ".. short big" array/short_big.arr[dim=256,bitpix=16,arch=big] DoXPA ".. short big gzip" array/short_big.arr.gz[dim=256,bitpix=16,arch=big] DoXPA ".. ushort little" array/ushort_little.arr[dim=256,bitpix=-16,arch=little] DoXPA ".. ushort little gzip" array/ushort_little.arr.gz[dim=256,bitpix=-16,arch=little] DoXPA ".. ushort big" array/ushort_big.arr[dim=256,bitpix=-16,arch=big] DoXPA ".. ushort big gzip" array/ushort_big.arr.gz[dim=256,bitpix=-16,arch=big] DoXPA ".. int little" array/int_little.arr[dim=256,bitpix=32,arch=little] DoXPA ".. int little gzip" array/int_little.arr.gz[dim=256,bitpix=32,arch=little] DoXPA ".. int big" array/int_big.arr[dim=256,bitpix=32,arch=big] DoXPA ".. int big gzip" array/int_big.arr.gz[dim=256,bitpix=32,arch=big] DoXPA ".. longlong little" array/longlong_little.arr[dim=256,bitpix=64,arch=little] DoXPA ".. longlong little gzip" array/longlong_little.arr.gz[dim=256,bitpix=64,arch=little] DoXPA ".. longlong big" array/longlong_big.arr[dim=256,bitpix=64,arch=big] DoXPA ".. longlong big gzip" array/longlong_big.arr.gz[dim=256,bitpix=64,arch=big] DoXPA ".. float little" array/float_little.arr[dim=256,bitpix=-32,arch=little] DoXPA ".. float little gzip" array/float_little.arr.gz[dim=256,bitpix=-32,arch=little] DoXPA ".. float big" array/float_big.arr[dim=256,bitpix=-32,arch=big] DoXPA ".. float big gzip" array/float_big.arr.gz[dim=256,bitpix=-32,arch=big] DoXPA ".. double little" array/double_little.arr[dim=256,bitpix=-64,arch=little] DoXPA ".. double little gzip" array/double_little.arr.gz[dim=256,bitpix=-64,arch=little] DoXPA ".. double big" array/double_big.arr[dim=256,bitpix=-64,arch=big] DoXPA ".. double big gzip" array/double_big.arr.gz[dim=256,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi # XPA if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 DoXPAStdin ".. char" array/char.arr [dim=256,bitpix=8] DoXPAStdin ".. char gzip" array/char.arr.gz [dim=256,bitpix=8] DoXPAStdin ".. short little" array/short_little.arr [dim=256,bitpix=16,arch=little] DoXPAStdin ".. short little gzip" array/short_little.arr.gz [dim=256,bitpix=16,arch=little] DoXPAStdin ".. short big" array/short_big.arr [dim=256,bitpix=16,arch=big] DoXPAStdin ".. short big gzip" array/short_big.arr.gz [dim=256,bitpix=16,arch=big] DoXPAStdin ".. ushort little" array/ushort_little.arr [dim=256,bitpix=-16,arch=little] DoXPAStdin ".. ushort little gzip" array/ushort_little.arr.gz [dim=256,bitpix=-16,arch=little] DoXPAStdin ".. ushort big" array/ushort_big.arr [dim=256,bitpix=-16,arch=big] DoXPAStdin ".. ushort big gzip" array/ushort_big.arr.gz [dim=256,bitpix=-16,arch=big] DoXPAStdin ".. int little" array/int_little.arr [dim=256,bitpix=32,arch=little] DoXPAStdin ".. int little gzip" array/int_little.arr.gz [dim=256,bitpix=32,arch=little] DoXPAStdin ".. int big" array/int_big.arr [dim=256,bitpix=32,arch=big] DoXPAStdin ".. int big gzip" array/int_big.arr.gz [dim=256,bitpix=32,arch=big] DoXPAStdin ".. longlong little" array/longlong_little.arr [dim=256,bitpix=64,arch=little] DoXPAStdin ".. longlong little gzip" array/longlong_little.arr.gz [dim=256,bitpix=64,arch=little] DoXPAStdin ".. longlong big" array/longlong_big.arr [dim=256,bitpix=64,arch=big] DoXPAStdin ".. longlong big gzip" array/longlong_big.arr.gz [dim=256,bitpix=64,arch=big] DoXPAStdin ".. float little" array/float_little.arr [dim=256,bitpix=-32,arch=little] DoXPAStdin ".. float little gzip" array/float_little.arr.gz [dim=256,bitpix=-32,arch=little] DoXPAStdin ".. float big" array/float_big.arr [dim=256,bitpix=-32,arch=big] DoXPAStdin ".. float big gzip" array/float_big.arr.gz [dim=256,bitpix=-32,arch=big] DoXPAStdin ".. double little" array/double_little.arr [dim=256,bitpix=-64,arch=little] DoXPAStdin ".. double little gzip" array/double_little.arr.gz [dim=256,bitpix=-64,arch=little] DoXPAStdin ".. double big" array/double_big.arr [dim=256,bitpix=-64,arch=big] DoXPAStdin ".. double big gzip" array/double_big.arr.gz [dim=256,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 DoXPAStdout ".. char" array/char.arr[dim=256,bitpix=8] little [dim=256,bitpix=8] DoXPAStdout ".. short little little" array/short_little.arr[dim=256,bitpix=16,arch=little] little [dim=256,bitpix=16,arch=little] DoXPAStdout ".. short little big" array/short_little.arr[dim=256,bitpix=16,arch=little] big [dim=256,bitpix=16,arch=big] DoXPAStdout ".. short big little" array/short_big.arr[dim=256,bitpix=16,arch=big] little [dim=256,bitpix=16,arch=little] DoXPAStdout ".. short big big" array/short_big.arr[dim=256,bitpix=16,arch=big] big [dim=256,bitpix=16,arch=big] DoXPAStdout ".. ushort little little" array/ushort_little.arr[dim=256,bitpix=-16,arch=little] little [dim=256,bitpix=-16,arch=little] DoXPAStdout ".. ushort little big" array/ushort_little.arr[dim=256,bitpix=-16,arch=little] big [dim=256,bitpix=-16,arch=big] DoXPAStdout ".. ushort big little" array/ushort_big.arr[dim=256,bitpix=-16,arch=big] little [dim=256,bitpix=-16,arch=little] DoXPAStdout ".. ushort big big" array/ushort_big.arr[dim=256,bitpix=-16,arch=big] big [dim=256,bitpix=-16,arch=big] DoXPAStdout ".. int little little" array/int_little.arr[dim=256,bitpix=32,arch=little] little [dim=256,bitpix=32,arch=little] DoXPAStdout ".. int little big" array/int_little.arr[dim=256,bitpix=32,arch=little] big [dim=256,bitpix=32,arch=big] DoXPAStdout ".. int big little" array/int_big.arr[dim=256,bitpix=32,arch=big] little [dim=256,bitpix=32,arch=little] DoXPAStdout ".. int big big" array/int_big.arr[dim=256,bitpix=32,arch=big] big [dim=256,bitpix=32,arch=big] DoXPAStdout ".. longlong little little" array/longlong_little.arr[dim=256,bitpix=64,arch=little] little [dim=256,bitpix=64,arch=little] DoXPAStdout ".. longlong little big" array/longlong_little.arr[dim=256,bitpix=64,arch=little] big [dim=256,bitpix=64,arch=big] DoXPAStdout ".. longlong big little" array/longlong_big.arr[dim=256,bitpix=64,arch=big] little [dim=256,bitpix=64,arch=little] DoXPAStdout ".. longlong big big" array/longlong_big.arr[dim=256,bitpix=64,arch=big] big [dim=256,bitpix=64,arch=big] DoXPAStdout ".. float little little" array/float_little.arr[dim=256,bitpix=-32,arch=little] little [dim=256,bitpix=-32,arch=little] DoXPAStdout ".. float little big" array/float_little.arr[dim=256,bitpix=-32,arch=little] big [dim=256,bitpix=-32,arch=big] DoXPAStdout ".. float big little" array/float_big.arr[dim=256,bitpix=-32,arch=big] little [dim=256,bitpix=-32,arch=little] DoXPAStdout ".. float big big" array/float_big.arr[dim=256,bitpix=-32,arch=big] big [dim=256,bitpix=-32,arch=big] DoXPAStdout ".. double little little" array/double_little.arr[dim=256,bitpix=-64,arch=little] little [dim=256,bitpix=-64,arch=little] DoXPAStdout ".. double little big" array/double_little.arr[dim=256,bitpix=-64,arch=little] big [dim=256,bitpix=-64,arch=big] DoXPAStdout ".. double big little" array/double_big.arr[dim=256,bitpix=-64,arch=big] little [dim=256,bitpix=-64,arch=little] DoXPAStdout ".. double big big" array/double_big.arr[dim=256,bitpix=-64,arch=big] big [dim=256,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" ���������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/��������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013172� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/file.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000011364�12131601437�015011� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get file # default... set {} frame new set {} file fits/float.fits set {} frame delete set {} file new fits/float.fits set {} file slice fits/float.fits set {} file mask fits/float.fits set {} frame delete # fits... set {} frame new set {} file fits fits/float.fits set {} frame delete set {} file new fits fits/float.fits set {} file fits slice fits/float.fits set {} file mask fits fits/float.fits set {} frame delete # sfits... set {} frame new set {} file sfits sfits/float.hdr sfits/float.arr set {} frame delete set {} file new sfits sfits/float.hdr sfits/float.arr set {} file mask sfits sfits/float.hdr sfits/float.arr set {} frame delete # url... set {} frame new set {} file url http://hea-www.harvard.edu/RD/ds9/data/img.fits set {} frame delete # rgbimage... set {} frame new rgb set {} file rgbimage mecube/float.fits set {} frame delete set {} file new rgbimage mecube/float.fits set {} frame delete # rgbcube... set {} frame new rgb set {} file rgbcube rgbcube/float.fits set {} frame delete set {} file new rgbcube rgbcube/float.fits set {} frame delete # srgbcube... set {} frame new rgb set {} file srgbcube srgbcube/float.hdr srgbcube/float.arr set {} frame delete set {} file new srgbcube srgbcube/float.hdr srgbcube/float.arr set {} frame delete # mecube... set {} frame new set {} file mecube mecube/float.fits set {} frame delete set {} file new mecube mecube/float.fits set {} frame delete # multiframe... set {} frame new set {} file multiframe mecube/float.fits set {} frame delete set {} frame delete set {} frame delete set {} file new multiframe mecube/float.fits set {} frame delete set {} frame delete set {} frame delete set {} single # mosaic... set {} frame new set {} file mosaic mosaic/mosaicimage.fits set {} frame clear set {} file mosaic wcs mosaic/mosaicimage.fits set {} frame clear set {} file mosaic iraf mosaic/mosaicimage.fits set {} frame delete set {} file new mosaic mosaic/mosaicimage.fits set {} file mask mosaic mosaic/mosaicimage.fits set {} frame delete set {} file new mosaic wcs mosaic/mosaicimage.fits set {} file mask mosaic wcs mosaic/mosaicimage.fits set {} frame delete # mosaicimage... set {} frame new set {} file mosaicimage mosaic/mosaicimage.fits set {} frame clear set {} file mosaicimage wcs mosaic/mosaicimage.fits set {} frame clear set {} file mosaicimage iraf mosaic/mosaicimage.fits set {} frame clear set {} file mosaicimage wfpc2 mosaic/hst.fits set {} frame delete set {} file new mosaicimage mosaic/mosaicimage.fits set {} file mask mosaicimage mosaic/mosaicimage.fits set {} frame delete set {} file new mosaicimage wcs mosaic/mosaicimage.fits set {} file mask mosaicimage wcs mosaic/mosaicimage.fits set {} frame delete # mosaicwcs... set {} frame new set {} file mosaicwcs mosaic/mosaicimage.fits set {} frame delete set {} file new mosaicwcs mosaic/mosaicimage.fits set {} file mask mosaicwcs mosaic/mosaicimage.fits set {} frame delete # mosaiciraf... set {} frame new set {} file mosaiciraf mosaic/mosaicimage.fits set {} frame delete set {} file new mosaiciraf mosaic/mosaicimage.fits set {} file mask mosaiciraf mosaic/mosaicimage.fits set {} frame delete # mosaicimagewcs... set {} frame new set {} file mosaicimagewcs mosaic/mosaicimage.fits set {} frame delete set {} file new mosaicimagewcs mosaic/mosaicimage.fits set {} file mask mosaicimagewcs mosaic/mosaicimage.fits set {} frame delete # mosaicimageiraf... set {} frame new set {} file mosaicimageiraf mosaic/mosaicimage.fits set {} frame delete set {} file new mosaicimageiraf mosaic/mosaicimage.fits set {} file mask mosaicimageiraf mosaic/mosaicimage.fits set {} frame delete # mosaicimagewfpc2... set {} frame new set {} file mosaicimagewfpc2 mosaic/hst.fits set {} frame delete set {} file new mosaicimagewfpc2 mosaic/hst.fits set {} frame delete # smosaic...no test... # smosaiciraf...no test... # smosaicwcs...no test... # array... set {} frame new set {} file array array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} frame delete set {} file new array array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} file mask array array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} frame delete # rgbarray... set {} frame new rgb set {} file rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] set {} frame delete set {} file new rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] set {} frame delete # photo... set {} frame new set {} file photo photo/rose.png set {} frame delete set {} file new photo photo/rose.png set {} file photo slice photo/rose.png set {} frame delete # file save... set {} file save foo.fits # file save gz... set {} file save gz foo.fits.gz # file save resample... set {} file save resample foo.fits # file save resample gz... set {} file save resample gz foo.fits.gz set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/movie.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000476�12126606406�015220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} width 715 set {} height 450 set {} movie foo.mpg set {} movie frame foo.mpg set {} movie slice foo.mpg set {} frame new 3d set {} movie 3d foo.mpg number 1 azfrom 0 azto 0 elfrom 0 elto 0 slfrom 1 slto 1 repeat 1 set {} frame delete # backward compatibility set {} savempeg foo.mpg set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/jpeg.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000377�12126623076�015030� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} jpeg photo/rose.jpeg set file://localhost/Users/joye/saods9/tests/photo/rose.jpeg jpeg get jpeg set {} frame delete set {} jpeg new photo/rose.jpeg set {} jpeg slice photo/rose.jpeg set {} frame delete set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/source.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000071�12131336426�015366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} source aux/source.tcl set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaicimage.samp����������������������������������������������������������������0000644�0001750�0001750�00000001344�12131307543�016346� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaicimage mosaic/mosaicimage.fits get mosaicimage set {} frame clear set {} mosaicimage wcs mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaicimage wcs set {} frame clear set {} mosaicimage iraf mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaicimage iraf set {} frame clear set {} mosaicimage wfpc2 mosaic/hst.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/hst.fits mosaicimage wfpc2 set {} frame delete set {} mosaicimage new mosaic/mosaicimage.fits set {} mosaicimage mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/blink.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000310�12125354777�015175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get blink get blink interval set {} frame new set {} blink set {} blink yes set {} blink interval .5 set {} single set {} frame first set {} frame next set {} frame delete set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mecube.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000262�12126623076�015334� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mecube mecube/float.fits set file://localhost/Users/joye/saods9/tests/mecube/float.fits mecube get mecube set {} frame delete set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/magnifier.samp������������������������������������������������������������������0000644�0001750�0001750�00000000332�12126603214�016023� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get magnifier color get magnifier zoom get magnifier cursor get magnifier region set {} magnifier color white set {} magnifier zoom 4 set {} magnifier cursor yes set {} magnifier region yes set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/array.samp����������������������������������������������������������������������0000644�0001750�0001750�00000001010�12125354777�015212� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} array array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} frame delete set {} array new array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} array mask array/float_big.arr[dim=256,bitpix=-32,endian=big] set {} frame delete # backward compatibiliy set {} frame new rgb set {} array rgb rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] set {} frame delete set {} array new rgb rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] set {} frame delete set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/rotate.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000206�12126634102�015360� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get rotate set {} rotate open set {} rotate to 30 set {} rotate 15 set {} rotate close set {} frame reset set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/regions.samp��������������������������������������������������������������������0000644�0001750�0001750�00000005455�12126626244�015553� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} regions delete all set {} regions system physical set {} regions sky fk5 set {} regions skyformat degrees set file://localhost/Users/joye/saods9/tests/regions/samp.reg regions get regions get regions show get regions showtext get regions centroid auto get regions centroid radius get regions centroid iteration get regions -format pros -system wcs -sky fk5 -skyformat sexagesimal -delim nl -prop edit 1 -group foo -strip yes get regions include get regions exclude get regions source get regions background get regions selected get regions format get regions system get regions sky get regions skyformat get regions strip get regions shape get regions color get regions width get regions delim get regions groups set {} regions delete all set {} regions regions/ds9.physical.reg set {} regions delete all set {} regions load regions/ds9.physical.reg set {} regions delete all set {} regions load regions/ds9.fk5*.reg set {} regions delete all set {} regions load all regions/ds9.physical.reg set {} regions save foo.reg set {} regions list set {} regions list close set {} regions delete all set {} regions show yes set {} regions showtext yes set {} regions centroid set {} regions centroid auto no set {} regions centroid radius 10 set {} regions centroid iteration 30 #set {} regions getinfo set {} regions move front set {} regions move back set {} regions select all set {} regions select none set {} regions delete all set {} regions delete select set {} regions format ds9 set {} regions system physical set {} regions sky fk5 set {} regions skyformat degrees set {} regions delim nl set {} regions strip no set {} regions shape circle set {} regions color green set {} regions edit yes set {} regions include set {} regions width 1 set {} regions command "circle 100 100 20" set {} regions group new set {} regions group foo new set {} regions group foo update set {} regions group foo select set {} regions group foo color red set {} regions group foo copy set {} regions group foo delete set {} regions group foo cut set {} regions group foo font 'time 14 bold' set {} regions group foo move 100 100 set {} regions group foo movefront set {} regions group foo moveback set {} regions group foo property delete no set {} regions delete all set {} regions command "circle 100 100 20" set {} regions select all set {} regions copy set {} regions cut set {} regions paste set {} regions undo set {} regions delete all set {} regions load regions/ds9.physical.reg set {} regions select all set {} regions composite set {} regions desolve set {} regions delete all set {} regions command "circle 100 100 20" set {} regions savetemplate foo.tpl set {} regions delete all set {} regions template foo.tpl set {} regions delete all set {} regions template foo.tpl at 202.46963 47.19556 fk5 set {} regions delete all set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/cd.samp�������������������������������������������������������������������������0000644�0001750�0001750�00000000060�12125354777�014466� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get cd set {} cd . set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/bg.samp�������������������������������������������������������������������������0000644�0001750�0001750�00000000140�12125405766�014462� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get background get bg set {} background red set {} background white set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mask.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000233�12126603214�015015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get mask color get mask mark get mask transparency set {} mask open set {} mask color cyan set {} mask clear set {} mask close set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/rgbcube.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000366�12126634102�015502� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new rgb set {} rgbcube rgbcube/float.fits set file://localhost/Users/joye/saods9/tests/rgbcube/float.fits rgbcube get rgbcube set {} frame delete set {} rgbcube new rgbcube/float.fits set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/samp.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000244�12126642367�015040� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} samp no set {} samp yes set {} samp broadcast set {} samp broadcast image set {} samp send aladin set {} samp send image aladin set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/raise.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000066�12126626256�015204� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} lower set {} raise set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/png.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000366�12126626244�014665� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} png photo/rose.png set file://localhost/Users/joye/saods9/tests/photo/rose.png png get png set {} frame delete set {} png new photo/rose.png set {} png slice photo/rose.png set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/imexam.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000722�12126603214�015345� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "Select coordinate point:" get imexam coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Press key:" get imexam key coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Press either:" get imexam any coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Select value point:" get imexam data echo " ok" sleep .5 echo "Press key:" get imexam key data echo " ok" sleep .5 echo "Press any:" get imexam any data echo " ok" sleep .5 set {} single set {} raise ����������������������������������������������./saods9/tests/samp/rgb.samp������������������������������������������������������������������������0000644�0001750�0001750�00000001123�12126626244�014643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} rgb open set {} rgb close set {} rgb get rgb channel get rgb view red get rgb view green get rgb view blue get rgb system get rgb lock wcs get rgb lock crop get rgb lock slice get rgb lock bin get rgb lock scale get rgb lock colorbar get rgb lock smooth set {} rgb green set {} rgb channel blue set {} rgb view blue off set {} rgb system wcs set {} rgb lock wcs yes set {} rgb lock crop yes set {} rgb lock slice yes set {} rgb lock bin yes set {} rgb lock scale yes set {} rgb lock colorbar yes set {} rgb lock smooth yes set {} rgb close set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/nameserver.samp�����������������������������������������������������������������0000644�0001750�0001750�00000000634�12126606406�016244� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} nameserver open set {} nameserver close set {} nameserver m51 get nameserver get nameserver server get nameserver skyformat get nameserver m51 set {} nameserver name m51 set {} nameserver server simbad-cds set {} nameserver skyformat degrees set {} mode crosshair set {} nameserver crosshair set {} nameserver pan set {} nameserver close set {} mode pointer set {} frame reset set {} single set {} raise ����������������������������������������������������������������������������������������������������./saods9/tests/samp/threads.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000071�12126640714�015522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get threads set {} threads 8 set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/frame.samp����������������������������������������������������������������������0000644�0001750�0001750�00000003007�12126364474�015172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get frame lock get frame has amplifier get frame has datamin get frame has datasec get frame has detector get frame has grid get frame has iis get frame has irafmin get frame has physical get frame has smooth get frame has contour get frame has contour aux get frame has fits get frame has fits bin get frame has fits cube get frame has fits mosaic get frame has marker highlite get frame has marker paste get frame has marker select get frame has marker undo get frame has system physical get frame has wcs wcsa get frame has wcs equatorial wcsa set {} frame new rgb set {} frame delete set {} frame new 3d set {} frame delete set {} frame new set {} file data/img.fits get frame get frame frameno get frame all get frame active set {} frame center set {} frame center 1 set {} frame center all set {} frame reset set {} frame reset 1 set {} frame reset all set {} frame refresh set {} frame refresh 1 set {} frame refresh all set {} frame hide set {} frame hide 1 set {} frame hide all set {} frame show set {} frame show 1 set {} frame show all set {} frame move first set {} frame move back set {} frame move forward set {} frame move last set {} frame first set {} frame prev set {} frame next set {} frame last set {} frame frameno 1 set {} frame 2 set {} frame match wcs set {} frame lock wcs set {} frame lock none set {} frame clear set {} frame clear 1 set {} frame clear all set {} frame delete set {} frame delete 1 set {} frame delete all set {} file new data/img.fits set {} rgb close set {} 3d close set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/plot.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000006750�12126621321�015051� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# empty plot... set {} plot get plot set {} sleep .5 set {} plot close set {} plot new set {} plot new bar set {} plot new scatter set {} sleep .5 set {} plot close set {} plot close set {} plot close set {} plot new name foo set {} plot new name foo bar set {} plot new name foo scatter set {} sleep .5 set {} plot close set {} plot close set {} plot close set {} plot new name foo "The Title" "X Axis" "Y Axis" xy set {} plot new name foo bar "The Title" "X Axis" "Y Axis" xy set {} plot new name foo scatter "The Title" "X Axis" "Y Axis" xy set {} sleep .5 set {} plot close set {} plot close set {} plot close # data... set {} plot new name foo set {} plot new set file://localhost/Users/joye/saods9/tests/plot/xy.dat plot foo data xy set file://localhost/Users/joye/saods9/tests/plot/xy.dat plot data xy set {} sleep .5 set {} plot close set {} plot close # clear/close... set file://localhost/Users/joye/saods9/tests/plot/stdin.xy.dat plot new stdin set {} sleep .5 set {} plot clear set {} plot close # save/load... set {} plot new set {} plot load plot/xy.dat xy set {} plot save foo.dat set {} plot saveconfig foo.plt set {} plot loadconfig foo.plt set {} sleep .5 set {} plot close # config... set {} plot new set {} plot saveconfig foo.cfg set {} plot loadconfig foo.cfg set {} sleep .5 set {} plot close # print... set {} plot new #set {} plot print set {} plot print destination printer set {} plot print command "lp" set {} plot print filename "foo.ps" set {} plot print color rgb set {} plot pagesetup orient portrait set {} plot pagesetup size letter set {} sleep .5 set {} plot close # graph... set {} plot new set {} plot load plot/xy.dat xy set {} plot graph grid x no set {} plot graph grid y yes set {} plot graph log x no set {} plot graph log y no set {} plot graph flip x no set {} plot graph flip y no set {} plot graph range x min 1 set {} plot graph range x max 100 set {} plot graph range y min 1 set {} plot graph range y max 100 set {} plot graph range x auto yes set {} plot graph range y auto yes set {} plot graph format x {} set {} plot graph format y {} set {} plot graph labels title "The Title" set {} plot graph labels xaxis "X Axis" set {} plot graph labels yaxis "Y Axis" set {} plot font numbers font times set {} plot font numbers size 12 set {} plot font numbers weight bold set {} plot font numbers slant roman set {} plot font labels font times set {} plot font labels size 12 set {} plot font labels weight bold set {} plot font labels slant roman set {} plot font title font times set {} plot font title size 12 set {} plot font title weight bold set {} plot font title slant roman set {} sleep .5 set {} plot close # dataset... set {} plot new set file://localhost/Users/joye/saods9/tests/plot/xy.dat plot data xy set file://localhost/Users/joye/saods9/tests/plot/xyey.dat plot data xyey set {} plot dataset 2 set {} plot view discrete yes set {} plot view line yes set {} plot view step yes set {} plot view quadratic yes set {} plot view errorbar yes set {} plot color discrete red set {} plot color line green set {} plot color step blue set {} plot color quadratic cyan set {} plot color errorbar yellow set {} plot color errorbar magenta set {} plot line discrete cross set {} plot line line width 2 set {} plot line line dash yes set {} plot line step width 2 set {} plot line step dash yes set {} plot line quadratic width 2 set {} plot line quadratic dash yes set {} plot line errorbar width 2 set {} plot line errorbar style 2 set {} sleep .5 set {} plot close set {} single set {} raise ������������������������./saods9/tests/samp/console.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000053�12125362316�015530� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} console set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/web.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000404�12131316277�014645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} web hea-www.harvard.edu/RD/ds9/acknowledgment.html sleep .5 get web set {} web hea-www.harvard.edu/RD/ds9/helpdesk.html sleep .5 set {} web hvweb click back sleep .5 set {} web click forward set {} web clear set {} web close set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/sleep.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000070�12126635566�015210� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} sleep set {} sleep 2 set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/restore.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000112�12126626244�015551� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} backup foo.bck set {} restore foo.bck set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/crosshair.samp������������������������������������������������������������������0000644�0001750�0001750�00000000414�12125362316�016064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} mode crosshair get crosshair get crosshair wcs fk5 sexagesimal get crosshair lock set {} crosshair 13:29:55.287 +47:11:37.73 wcs fk5 set {} crosshair match wcs set {} crosshair lock wcs set {} crosshair lock none set {} mode pointer set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/colorbar.samp�������������������������������������������������������������������0000644�0001750�0001750�00000001414�12125362316�015673� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get colorbar get colorbar orientation get colorbar numerics get colorbar space get colorbar font get colorbar fontsize get colorbar fontweight get colorbar fontslant get colorbar size get colorbar ticks set {} colorbar no set {} colorbar yes set {} colorbar vertical set {} colorbar horizontal set {} colorbar numerics no set {} colorbar numerics yes set {} colorbar space value set {} colorbar space distance set {} colorbar font times set {} colorbar fontsize 30 set {} colorbar fontweight bold set {} colorbar fontslant roman set {} colorbar font helvetica set {} colorbar fontsize 10 set {} colorbar fontweight normal set {} colorbar fontslant roman set {} colorbar size 30 set {} colorbar ticks 9 set {} colorbar size 20 set {} colorbar ticks 11 set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/tiff.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000415�12127370217�015021� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} tiff photo/rose.tiff set file://localhost/Users/joye/saods9/tests/photo/rose.tiff tiff get tiff get tiff jpeg set {} frame delete set {} tiff new photo/rose.tiff set {} tiff slice photo/rose.tiff set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/header.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000177�12126603214�015321� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} header set {} header save foo.txt set {} header close set {} header 1 set {} header close 1 set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/rgbimage.samp�������������������������������������������������������������������0000644�0001750�0001750�00000000367�12126634102�015647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new rgb set {} rgbimage mecube/float.fits set file://localhost/Users/joye/saods9/tests/mecube/float.fits rgbimage get rgbimage set {} frame delete set {} rgbimage new mecube/float.fits set {} frame delete set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/wcs.samp������������������������������������������������������������������������0000644�0001750�0001750�00000001067�12131335202�014657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get wcs get wcs system get wcs sky get wcs skyformat get wcs align set {} wcs open set {} wcs wcs set {} wcs align yes set {} wcs system wcs set {} wcs sky galactic set {} wcs skyformat sexagesimal set {} wcs align no set {} wcs sky fk5 set {} wcs skyformat degrees set file://localhost/Users/joye/saods9/tests/aux/image.wcs wcs append set file://localhost/Users/joye/saods9/tests/aux/image.wcs wcs replace set {} wcs append aux/image.wcs set {} wcs replace aux/image.wcs set {} wcs reset set {} wcs skyformat sexagesimal set {} wcs close set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/theme.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000072�12126640714�015173� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get theme set {} theme native set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/vo.samp�������������������������������������������������������������������������0000644�0001750�0001750�00000000537�12126640714�014523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get vo method get vo server get vo internal get vo delay get vo connect get vo set {} vo open set {} vo method set {} vo server "http://cxc.harvard.edu/chandraed/list.txt" set {} vo internal yes set {} vo delay 10 set {} vo connect foo set {} vo chandra-ed set {} vo disconnect chandra-ed set {} vo close set {} web close set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/dssstsci.samp�������������������������������������������������������������������0000644�0001750�0001750�00000001271�12125362316�015730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} dssstsci open set {} dssstsci close set {} dssstsci survey all get dssstsci survey set {} dssstsci size 30 30 arcsec get dssstsci size set {} dssstsci save no get dssstsci save set {} dssstsci frame new get dssstsci frame set {} dssstsci update frame set {} dssstsci m1 set {} dssstsci name m51 get dssstsci name set {} dssstsci name {} set {} dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal get dssstsci coord set {} dssstsci update frame set {} mode crosshair set {} dssstsci update crosshair set {} dssstsci close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/iconify.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000134�12126603214�015522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get iconify set {} iconify set {} iconify yes set {} iconify no set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/lock.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000001250�12126603214�015012� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get lock frame get lock crosshair get lock crop get lock slice get lock bin get lock scale get lock colorbar get lock smooth set {} file new data/img.fits set {} tile set {} mode crosshair set {} lock frame wcs set {} lock frame none set {} lock crosshair wcs set {} crosshair 13:29:56 +47:11:38 wcs fk5 set {} lock crosshair none set {} lock crop wcs set {} lock crop none set {} lock slice yes set {} lock slice no set {} lock bin yes set {} lock bin no set {} lock scale yes set {} lock scale no set {} lock colorbar yes set {} lock colorbar no set {} lock smooth yes set {} lock smooth no set {} mode pointer set {} frame delete set {} wcs align no set {} single set {} raise��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/minmax.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000216�12126604644�015364� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get minmax get minmax mode get minmax sample set {} minmax scan set {} minmax mode scan set {} minmax interval 10 set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/srgbcube.samp�������������������������������������������������������������������0000644�0001750�0001750�00000000312�12126640714�015662� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new rgb set {} srgbcube srgbcube/float.hdr srgbcube/float.arr set {} frame delete set {} srgbcube new srgbcube/float.hdr srgbcube/float.arr set {} frame delete set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/cursor.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000132�12125362316�015401� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} mode crosshair set {} cursor 10 10 set {} mode pointer set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/multiframe.samp�����������������������������������������������������������������0000644�0001750�0001750�00000000216�12126606406�016236� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} multiframe mecube/float.fits set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaicwcs.samp������������������������������������������������������������������0000644�0001750�0001750�00000000513�12131307543�016055� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaicwcs mosaic/mosaicimage.fits get mosaicwcs set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaicwcs set {} frame delete set {} mosaicwcs new mosaic/mosaicimage.fits set {} mosaicwcs mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/saveimage.samp������������������������������������������������������������������0000644�0001750�0001750�00000000733�12126634102�016030� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} saveimage fits foo.fits set {} saveimage foo.fits set {} saveimage eps foo.eps set {} saveimage foo.eps set {} saveimage foo.gif set {} saveimage tiff foo.tiff none set {} saveimage foo.tiff set {} saveimage jpeg foo.jpeg 100 set {} saveimage foo.jpeg set {} saveimage png foo.png set {} saveimage foo.png # backward compatibility (6.2) set {} saveimage tiff none foo.tiff set {} saveimage jpeg 100 foo.jpeg set {} saveimage mpeg foo.mpeg set {} single set {} raise �������������������������������������./saods9/tests/samp/mosaicimageiraf.samp������������������������������������������������������������0000644�0001750�0001750�00000000524�12131307543�017207� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaicimageiraf mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaicimageiraf set {} frame delete set {} mosaicimageiraf new mosaic/mosaicimage.fits set {} mosaicimageiraf mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/prefs.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000316�12126626244�015213� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} prefs clear # backward compatibility get prefs bgcolor get prefs nancolor get prefs threads set {} prefs bgcolor white set {} prefs nancolor white set {} prefs threads 8 set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/single.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000127�12126635566�015364� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get single set {} tile get single set {} single get single set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/tile.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000347�12126640714�015033� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get tile get tile mode set {} fits new data/img.fits set {} fits new data/img.fits set {} tile set {} tile yes set {} tile row set {} tile column set {} tile grid set {} frame delete set {} frame delete set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/pixeltable.samp�����������������������������������������������������������������0000644�0001750�0001750�00000000227�12126621321�016215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get pixeltable set {} pixeltable set {} pixeltable yes set {} pixeltable no set {} pixeltable open set {} pixeltable close set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/skyview.samp��������������������������������������������������������������������0000644�0001750�0001750�00000001247�12126635566�015610� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} skyview open set {} skyview close set {} skyview survey sdssi get skyview survey set {} skyview size 30 30 arcsec get skyview size set {} skyview save no get skyview save set {} skyview frame new get skyview frame set {} skyview update frame set {} skyview m3 set {} skyview name m51 get skyview name set {} skyview name {} set {} skyview coord 13:29:55.301 +47:11:37.73 sexagesimal get skyview coord set {} skyview update frame set {} mode crosshair set {} skyview update crosshair set {} skyview close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/first.samp����������������������������������������������������������������������0000644�0001750�0001750�00000001123�12126351517�015216� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} first open set {} first close set {} first size 30 30 arcsec get first size set {} first save no get first save set {} first frame new get first frame set {} first update frame set {} first m3 set {} first name m51 get first name set {} first name {} set {} first coord 13:29:52.37 +47:11:40.8 sexagesimal get first coord set {} first update frame set {} mode crosshair set {} first update crosshair set {} first close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/url.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000140�12131601437�014662� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} url http://hea-www.harvard.edu/RD/ds9/data/img.fits set {} frame delete ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/grid.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000005747�12126603214�015026� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} wcs wcs get grid get grid type get grid system get grid sky get grid skyformat get grid grid get grid grid color get grid grid width get grid grid style get grid grid gap1 get grid grid gap2 get grid axes get grid axes color get grid axes width get grid axes style get grid axes type get grid axes origin get grid format1 get grid format2 get grid tickmarks get grid tickmarks color get grid tickmarks width get grid tickmarks style get grid border get grid border color get grid border width get grid border style get grid numlab get grid numlab font get grid numlab fontweight get grid numlab fontslant get grid numlab fontsize get grid numlab color get grid numlab gap1 get grid numlab gap2 get grid numlab type get grid numlab vertical get grid title get grid title text get grid title def get grid title gap get grid title font get grid title fontweight get grid title fontslant get grid title fontsize get grid title color get grid textlab get grid textlab text1 get grid textlab def1 get grid textlab gap1 get grid textlab text2 get grid textlab def2 get grid textlab gap2 get grid textlab font get grid textlab fontweight get grid textlab fontslant get grid textlab fontsize get grid textlab color set {} grid open set {} grid close set {} grid set {} grid yes set {} grid type analysis set {} grid system wcs set {} grid sky fk5 set {} grid skyformat degrees set {} grid grid yes set {} grid grid color red set {} grid grid width 2 set {} grid grid style 1 set {} grid grid gap1 .01 set {} grid grid gap2 .01 set {} grid axes yes set {} grid axes color red set {} grid axes width 2 set {} grid axes style 1 set {} grid axes type exterior set {} grid format1 d.2 set {} grid format2 d.2 set {} grid tickmarks yes set {} grid tickmarks color red set {} grid tickmarks width 2 set {} grid tickmarks style 1 set {} grid border yes set {} grid border color red set {} grid border width 2 set {} grid border style 1 set {} grid numerics yes set {} grid numerics font courier set {} grid numerics fontweigth bold set {} grid numerics fontslant roman set {} grid numerics fontsize 12 set {} grid numerics color red set {} grid numerics gap1 10 set {} grid numerics gap2 10 set {} grid numerics type exterior set {} grid numerics vertical yes set {} grid title yes set {} grid title text {Hello World} set {} grid title def yes set {} grid title gap 10 set {} grid title font courier set {} grid title fontweight bold set {} grid title fontslant roman set {} grid title fontsize 12 set {} grid title color red set {} grid labels yes set {} grid labels text1 {Hello World} set {} grid labels def1 yes set {} grid labels gap1 10 set {} grid labels text2 {Hello World} set {} grid labels def2 yes set {} grid labels gap2 10 set {} grid labels font courier set {} grid labels fontweight bold set {} grid labels fontslant roman set {} grid labels fontsize 12 set {} grid labels color red set {} grid save foo.grd set {} grid load foo.grd set {} grid reset set {} grid no set {} grid close set {} single set {} raise �������������������������./saods9/tests/samp/tcl.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000200�12131335202�014631� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set file://localhost/Users/joye/saods9/tests/aux/hello.tcl tcl set {} tcl puts "Hello Again, World" set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/zscale.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000235�12126640714�015353� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get zscale contrast get zscale sample get zscale line set {} zscale contrast .25 set {} zscale sample 600 set {} zscale line 120 set {} scale set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaic.samp���������������������������������������������������������������������0000644�0001750�0001750�00000001037�12131307543�015342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaic mosaic/mosaicimage.fits get mosaic set {} frame clear set {} mosaic wcs mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaic wcs set {} frame clear set {} mosaic iraf mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaic iraf set {} frame delete set {} mosaic new mosaic/mosaicimage.fits set {} mosaic mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/3d.samp�������������������������������������������������������������������������0000644�0001750�0001750�00000001021�12125354777�014404� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} 3d open set {} 3d close set {} 3d set {} 3d vp 45 30 get 3d vp get 3d az get 3d el get 3d scale get 3d method get 3d border get 3d border color get 3d compass get 3d compass color get 3d highlite get 3d highlite color set {} 3d vp 45 30 set {} 3d az 45 set {} 3d el 30 set {} 3d scale 5 set {} 3d method mip set {} 3d border yes set {} 3d border color red set {} 3d compass yes set {} 3d compass color red set {} 3d highlite yes set {} 3d highlite color red set {} 3d close set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/iis.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000174�12126603214�014652� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get iis filename get iis filename 1 set {} iis filename foo.fits set {} iis filename foo.fits 1 set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/catalog.samp��������������������������������������������������������������������0000644�0001750�0001750�00000003764�12131334246�015512� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} catalog cds 2mass get catalog get catalog header get catalog cat2mass header set {} catalog clear set {} catalog close set {} catalog set {} catalog close set {} catalog cds {I/284} set {} catalog clear set {} catalog close set {} catalog import sb aux/ds9.cat set {} catalog clear set {} catalog close set {} catalog cds 2mass set {} raise set {} catalog plot {$Jmag} {$Hmag} {$e_Jmag} {$e_Hmag} set {} catalog symbol condition {$Jmag>15} set {} catalog symbol shape {boxcircle point} set {} catalog symbol color red set {} catalog symbol condition {} set {} catalog symbol color red set {} catalog symbol shape text set {} catalog symbol font times set {} catalog symbol fontsize 14 set {} catalog symbol fontweight bold set {} catalog symbol fontslant italic set {} catalog symbol add set {} catalog symbol remove set {} catalog symbol load aux/ds9.sym set {} catalog symbol save foo.sym set {} catalog name m51 set {} catalog coordinate 202.48 47.21 fk5 set {} catalog system wcs set {} catalog sky fk5 set {} catalog skyformat degrees set {} catalog size 22 22 arcmin set {} catalog save foo.cat set {} catalog filter {$Jmag>15} set {} catalog filter load aux/ds9.flt set {} catalog retrieve set {} catalog cancel #set {} catalog print set {} catalog server sao set {} catalog sort {Jmag} incr set {} catalog maxrows 3000 set {} catalog allcols set {} catalog allrows set {} catalog ra {RAJ2000} set {} catalog dec {DEJ2000} set {} catalog psystem wcs set {} catalog psky fk5 set {} catalog hide set {} catalog show set {} catalog panto no #set {} catalog edit yes set {} catalog location 400 set {} catalog header set {} catalog clear set {} catalog close set {} catalog 2mass set {} catalog xmm set {} catalog match function 1and2 set {} catalog match error 2 arcsec set {} catalog match return 1only set {} catalog match unique no set {} catalog match 2mass xmm set {} catalog clear set {} catalog close set {} catalog clear set {} catalog close set {} catalog clear set {} catalog close set {} single set {} raise ������������./saods9/tests/samp/height.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000071�12126603214�015332� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get height set {} height 443 set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/nrrd.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000453�12127371452�015042� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} nrrd nrrd/float_big_raw.nrrd set file://localhost/Users/joye/saods9/tests/nrrd/float_big_raw.nrrd nrrd get nrrd get nrrd big set {} frame delete set {} nrrd new nrrd/float_big_raw.nrrd set {} nrrd mask nrrd/float_big_raw.nrrd set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaicimagewfpc2.samp�����������������������������������������������������������0000644�0001750�0001750�00000000313�12131307543�017303� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaicimage wfpc2 mosaic/hst.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/hst.fits mosaicimagewfpc2 set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/nan.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000105�12130630775�014643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get nan set {} nan blue set {} nan white set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/align.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000106�12125354777�015173� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get align set {} align set {} frame reset set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/analysis.samp�������������������������������������������������������������������0000644�0001750�0001750�00000001241�12125354777�015725� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} analysis clear set {} analysis analysis/analysis.ans get analysis get analysis task #get analysis entry hello world set {} analysis 0 set {} analysis task 1 set {} analysis task '{Basic Help}' set {} analysis clear set {} analysis load analysis/analysis.ans set {} analysis clear load analysis/analysis.ans set {} analysis clear set file://localhost/Users/joye/saods9/tests/analysis/analysis.ans analysis load set {} analysis clear #set {} analysis message {This is a message} #set {} analysis message yesno {This is a message} set {} analysis text {This is text} set file://localhost/Users/joye/saods9/tests/analysis.txt analysis text set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/export.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000762�12126351517�015420� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} export array foo.arr little set {} export foo.arr little set {} export nrrd foo.nrrd big set {} export foo.nrrd set {} export gif foo.gif set {} export foo.gif set {} export tiff foo.tiff none set {} export foo.tiff set {} export jpeg foo.jpeg 10 set {} export foo.jpeg set {} export png foo.png set {} export foo.png set {} frame new rgb set {} rgbcube rgbcube/float.fits set {} export rgbarray foo.rgb little set {} export foo.rgb little set {} frame delete set {} single set {} raise ��������������./saods9/tests/samp/contour.samp��������������������������������������������������������������������0000644�0001750�0001750�00000002074�12131334246�015562� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} contour yes get contour get contour wcs fk5 get contour color get contour width get contour smooth get contour method get contour nlevels get contour scale get contour log exp get contour mode get contour limits get contour levels set {} contour open set {} contour set {} contour yes set {} contour clear set {} contour yes set {} contour load aux/ds9.con wcs fk5 red 2 set {} contour save foo.con wcs fk5 set {} contour clear set {} contour yes set {} contour convert set {} regions delete all set {} contour loadlevels aux/ds9.lev set {} contour savelevels foo.lev set {} contour clear set {} contour yes set {} contour copy set {} contour paste wcs red 2 set {} contour clear set {} contour yes set {} contour color yellow set {} contour width 2 set {} contour smooth 5 set {} contour method block set {} contour nlevels 10 set {} contour width 2 set {} contour scale sqrt set {} contour log exp 1000 set {} contour mode zscale set {} contour limits 1 100 set {} contour levels "{1 10 100 1000}" set {} contour clear set {} contour close set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/preserve.samp�������������������������������������������������������������������0000644�0001750�0001750�00000000241�12126626244�015724� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get preserve scale get preserve pan get preserve regions set {} preserve scale no set {} preserve pan no set {} preserve regions no set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/cmap.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000631�12131334246�015006� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get cmap get cmap file get cmap invert get cmap value get cmap lock set {} cmap open set {} cmap Heat set {} cmap load aux/ds9.sao set {} cmap save foo.sao set {} cmap invert yes set {} cmap value 5 .2 set {} cmap tag load aux/ds9.tag set {} cmap tag save foo.tag set {} cmap tag delete set {} cmap match set {} cmap lock yes set {} cmap lock no set {} cmap Grey set {} cmap close set {} single set {} raise �������������������������������������������������������������������������������������������������������./saods9/tests/samp/backup.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000062�12125354777�015347� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} backup foo.bck set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/fits.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000003365�12131563554�015050� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get fits get fits image get fits slice set {} frame new set file://localhost/Users/joye/saods9/tests/fits/table.fits fits get fits table set {} frame delete set {} frame new set {} fits fits/float.fits set {} frame delete set {} fits new fits/float.fits set {} fits slice fits/float.fits set {} fits mask fits/float.fits set {} frame delete get fits size get fits width get fits height get fits depth get fits bitpix get fits type get fits size wcs fk5 arcsec get fits header get fits header 1 get fits header keyword "'BITPIX'" get fits header 1 keyword "'BITPIX'" set {} single # backward compatibility get fits image get fits image gz get fits resample get fits resample gz set {} frame new set {} fits fits/table.fits get fits table get fits table gz set {} frame delete set {} frame new set file://localhost/Users/joye/saods9/tests/mecube/float.fits fits mecube set {} frame delete set file://localhost/Users/joye/saods9/tests/mecube/float.fits fits new mecube set {} frame delete set {} frame new set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits mosaicimage set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits mosaicimage wcs set {} frame delete set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits new mosaicimage set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits mask mosaicimage set {} frame delete set {} frame new set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits mosaicimagewcs set {} frame delete set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits new mosaicimagewcs set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits fits mask mosaicimagewcs set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/lower.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000065�12126603214�015215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get iconify set {} lower set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/exit.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000014�11236363301�015031� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} quit ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/match.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000511�12126603214�015155� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} file new data/img.fits set {} tile set {} mode crosshair set {} match frames wcs set {} match frames image set {} match crosshairs wcs set {} match crop wcs set {} match slice set {} match bin set {} match scale set {} match colorbar set {} match smooth set {} frame delete set {} mode pointer set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/width.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000067�12126640714�015214� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get width set {} width 600 set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/gif.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000366�12126626244�014646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} gif photo/rose.gif set file://localhost/Users/joye/saods9/tests/photo/rose.gif gif get gif set {} frame delete set {} gif new photo/rose.gif set {} gif slice photo/rose.gif set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/version.samp��������������������������������������������������������������������0000644�0001750�0001750�00000000050�12126640714�015552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get version set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/about.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000046�12125354777�015216� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get about set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/dsseso.samp���������������������������������������������������������������������0000644�0001750�0001750�00000001226�12125362316�015371� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} dsseso open set {} dsseso close set {} dsseso survey DSS2-red get dsseso survey set {} dsseso size 30 30 arcsec get dsseso size set {} dsseso save no get dsseso save set {} dsseso frame new get dsseso frame set {} dsseso update frame set {} dsseso m1 set {} dsseso name m51 get dsseso name set {} dsseso name {} set {} dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal get dsseso coord set {} dsseso update frame set {} mode crosshair set {} dsseso update crosshair set {} dsseso close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/sfits.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000431�12126635566�015231� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} sfits sfits/float.hdr sfits/float.arr set {} frame delete set {} sfits new sfits/float.hdr sfits/float.arr set {} sfits slice sfits/float.hdr sfits/float.arr set {} sfits mask sfits/float.hdr sfits/float.arr set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/zoom.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000260�12126640714�015054� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} zoom open set {} zoom 2 set {} zoom 2 4 set {} zoom to 4 set {} zoom to 2 4 set {} zoom to fit set {} zoom close get zoom set {} frame reset set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/data.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000322�12125362316�014776� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get data image 450 520 3 3 yes get data physical 899 1039 6 6 no get data fk5 202.4709 47.19681 0.00016517 0.00016517 yes get data wcs fk5 202.4709 47.19681 0.00016517 0.00016517 no set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/pagesetup.samp������������������������������������������������������������������0000644�0001750�0001750�00000000275�12126621321�016064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get pspagesetup orient get pspagesetup scale get pspagesetup size set {} pspagesetup orient portrait set {} pspagesetup scale 100 set {} pspagesetup size letter set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/update.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000243�12126640714�015353� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} update set {} update 1 100 100 300 400 set {} update now set {} update now 1 100 100 300 400 set {} update off set {} update on set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaicimagewcs.samp�������������������������������������������������������������0000644�0001750�0001750�00000000544�12131307543�017064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaicimagewcs mosaic/mosaicimage.fits get mosaicimagewcs set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaicimagewcs set {} frame delete set {} mosaicimagewcs new mosaic/mosaicimage.fits set {} mosaicimagewcs mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/print.samp����������������������������������������������������������������������0000644�0001750�0001750�00000000475�12126626244�015236� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get psprint destination get psprint command get psprint color get psprint level get psprint resolution #set {} psprint set {} psprint destination printer set {} psprint command lp set {} psprint filename ds9.ps set {} psprint color rgb set {} psprint level 2 set {} psprint resolution 150 set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/view.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000003030�12126640714�015040� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame delete get view layout get view info get view panner get view magnifier get view buttons get view colorbar get view graph horizontal get view graph vertical get view filename get view object get view minmax get view lowhigh get view frame get view wcs get view detector get view amplifier get view physical get view image set {} view layout vertical set {} sleep .5 set {} view layout horizontal set {} sleep .5 set {} view info no set {} view info yes set {} view panner no set {} view panner yes set {} view magnifier no set {} view magnifier yes set {} view buttons no set {} view buttons yes set {} view colorbar no set {} view colorbar yes set {} view graph horizontal yes set {} view graph horizontal no set {} view graph vertical yes set {} view graph vertical no set {} view filename no set {} view filename yes set {} view object no set {} view object yes set {} view minmax yes set {} view minmax no set {} view lowhigh yes set {} view lowhigh no set {} view frame no set {} view frame yes set {} view wcs no set {} view wcs yes set {} view wcsa yes set {} view wcsa no set {} view detector yes set {} view detector no set {} view amplifier yes set {} view amplifier no set {} view physical no set {} view physical yes set {} view image no set {} view image yes set {} sleep .5 set {} frame new rgb set {} view red no set {} view red yes set {} view green no set {} view green yes set {} view blue no set {} view blue yes set {} frame delete set {} sleep .5 set {} file new data/img.fits set {} rgb close set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/save.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000002113�12131563554�015027� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# fits... set {} save foo.fits set {} save fits foo.fits set {} save foo.fits image set {} save fits foo.fits image set {} save foo.fits slice set {} save fits foo.fits slice set {} frame new set {} fits fits/table.fits set {} save foo.fits set {} save fits foo.fits set {} save foo.fits image set {} save fits foo.fits image set {} save foo.fits table set {} save fits foo.fits table set {} frame delete # rgbimage... set {} frame new rgb set {} rgbimage mecube/float.fits set {} save rgbimage foo.fits set {} frame delete # rgbcube... set {} frame new rgb set {} rgbcube rgbcube/float.fits set {} save rgbcube foo.fits set {} frame delete # mecube... set {} frame new set {} mecube mecube/float.fits set {} save mecube foo.fits set {} frame delete # mosaicimage... set {} frame new set {} mosaicimage mosaic/mosaicimage.fits set {} save mosaicimage foo.fits set {} frame delete # mosaic... set {} frame new set {} mosaicimage mosaic/mosaicimage.fits set {} save mosaic foo.fits set {} frame delete # backward compatibility # savefits... set {} savefits foo.fits set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/pan.samp������������������������������������������������������������������������0000644�0001750�0001750�00000000306�12126621321�014640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get pan physical get pan wcs fk5 sexagesimal set {} pan open set {} pan 100 100 image set {} pan to 13:29:55.666 +47:12:16.29 wcs fk5 set {} pan close set {} frame reset set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/rgbarray.samp�������������������������������������������������������������������0000644�0001750�0001750�00000000373�12126634102�015700� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new rgb set {} rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] get rgbarray big set {} frame delete set {} rgbarray new rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mosaiciraf.samp�����������������������������������������������������������������0000644�0001750�0001750�00000000500�12131307543�016176� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} frame new set {} mosaiciraf mosaic/mosaicimage.fits set {} frame clear set file://localhost/Users/joye/saods9/tests/mosaic/mosaicimage.fits mosaiciraf set {} frame delete set {} mosaiciraf new mosaic/mosaicimage.fits set {} mosaiciraf mask mosaic/mosaicimage.fits set {} frame delete set {} single set {} raise ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/mode.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000321�12126604644�015014� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get mode set {} mode none set {} mode crosshair set {} mode colorbar set {} mode pan set {} mode zoom set {} mode rotate set {} mode catalog set {} mode examine set {} mode pointer set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/nvss.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000001100�12126621321�015044� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} nvss open set {} nvss close set {} nvss size 30 30 arcsec get nvss size set {} nvss save no get nvss save set {} nvss frame new get nvss frame set {} nvss update frame set {} nvss m3 set {} nvss name m51 get nvss name set {} nvss name {} set {} nvss coord 13:29:52.37 +47:11:40.8 sexagesimal get nvss coord set {} nvss update frame set {} mode crosshair set {} nvss update crosshair set {} nvss close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/smooth.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000414�12021722226�015373� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get smooth get smooth function get smooth radius set {} smooth open set {} smooth set {} smooth yes set {} smooth function tophat set {} smooth radius 5 set {} smooth match set {} smooth lock yes set {} smooth lock no set {} smooth no set {} smooth close set {} raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/scale.samp����������������������������������������������������������������������0000644�0001750�0001750�00000001504�12126635566�015172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������get scale get scale log exp get scale limits get scale mode get scale scope get scale datasec get scale lock set {} scale open set {} scale linear set {} scale log set {} scale pow set {} scale sqrt set {} scale squared set {} scale asinh set {} scale sinh set {} scale histequ set {} scale log exp 1000 set {} scale log exp 10000 set {} scale linear set {} scale minmax set {} scale zscale set {} scale zmax set {} scale user set {} scale mode zscale set {} scale mode zmax set {} scale mode 95 set {} scale mode minmax set {} scale limits 0 100 set {} scale global set {} scale local set {} scale scope global set {} scale scope local set {} scale mode minmax set {} scale linear set {} scale zscale set {} scale datasec yes set {} scale match set {} scale lock yes set {} scale lock no set {} scale close set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/orient.samp���������������������������������������������������������������������0000644�0001750�0001750�00000000245�12126621321�015364� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} orient open set {} orient none set {} orient x set {} orient y set {} orient xy set {} orient close get orient set {} frame reset set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/2mass.samp����������������������������������������������������������������������0000644�0001750�0001750�00000001173�12125354777�015133� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} 2mass open set {} 2mass close set {} 2mass survey h get 2mass survey set {} 2mass size 30 30 arcsec get 2mass size set {} 2mass save no get 2mass save set {} 2mass frame new get 2mass frame set {} 2mass update frame set {} 2mass m1 set {} 2mass name m51 get 2mass name set {} 2mass name {} set {} 2mass coord 00:42:44.404 +41:16:08.78 sexagesimal get 2mass coord set {} 2mass update frame set {} mode crosshair set {} 2mass update crosshair set {} 2mass close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/cube.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000517�12125362316�015011� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} cube open set {} cube close set {} file new data/3d.fits get cube get cube interval get cube axis get cube lock set {} cube 2 set {} cube interval .5 set {} cube axis 3 set {} cube play set {} cube stop set {} cube match set {} cube lock yes set {} cube lock no set {} cube close set {} frame delete set {} single set {} raise ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/dsssao.samp���������������������������������������������������������������������0000644�0001750�0001750�00000001146�12125362316�015366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} dsssao open set {} dsssao close set {} dsssao size 30 30 arcsec get dsssao size set {} dsssao save no get dsssao save set {} dsssao frame new get dsssao frame set {} dsssao update frame set {} dsssao m1 set {} dsssao name m51 get dsssao name set {} dsssao name {} set {} dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal get dsssao coord set {} dsssao update frame set {} mode crosshair set {} dsssao update crosshair set {} dsssao close set {} mode pointer set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} frame delete set {} single set {} raise ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp/crop.samp�����������������������������������������������������������������������0000644�0001750�0001750�00000000730�12125362316�015033� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} mode crop set {} crop 978 970 356 308 get crop get crop wcs fk5 sexagesimal arcsec get crop lock set {} crop 978 970 356 308 set {} crop 13:29:52.908 +47:11:38.19 35.279606 30.522805 wcs fk5 arcsec set {} crop reset set {} 3d set {} file data/3d.fits set {} 3d vp 45 30 set {} crop 3d 25 75 set {} crop reset set {} crop match wcs set {} crop lock wcs set {} crop lock none set {} 3d close set {} frame delete set {} mode pointer set {} single set {} raise ����������������������������������������./saods9/tests/samp/bin.samp������������������������������������������������������������������������0000644�0001750�0001750�00000001163�12131306044�014632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set {} file new fits/table.fits set {} bin open set {} bin factor 4 set {} bin factor 8 8 set {} scale log set {} scale minmax set {} bin buffersize 1024 set {} bin filter 'circle(4096,4096,200)' set {} bin filter {} set {} bin cols rawx rawy set {} bin about center set {} bin colsz x y pha set {} bin depth 10 set {} bin about 4096 4096 set {} bin depth 1 set {} bin function sum set {} bin to fit set {} bin match set {} bin lock yes set {} bin lock no set {} bin close get bin about get bin buffersize get bin cols get bin factor get bin filter get bin function get bin lock set {} frame delete set {} single set {} raise �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/backup.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000007105�12131336167�014057� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TEMP=/tmp testfull () { # $1 title # $2 type # $3 file # $4 params # $5 cmd echo -n "$1" echo -n "." ds9 $5 -$2 $3$4 -backup foo.bck -sleep 1 -exit echo -n "*" ds9 -restore foo.bck -sleep 1 -exit rm -rf foo.bck* echo -n "." cat $3 | ds9 $5 -$2 -$4 -backup foo.bck -sleep 1 -exit echo -n "*" ds9 -restore foo.bck -sleep 1 -exit rm -rf foo.bck* echo -n "." echo "PASSED" } testhalf () { # $1 title # $2 type # $3 file echo -n "$1" echo -n "." ds9 -$2 ${3%.arr}.hdr $3 -backup foo.bck -sleep 1 -exit echo -n "*" ds9 -restore foo.bck -sleep 1 -exit rm -rf foo.bck* echo -n "." echo "PASSED" } echo echo "*** backup.sh ***" rm -rf foo.bck* if [ "$TEMP" = "" ]; then echo "No TEMP directory defined." echo "Be sure to define TEMP first..." exit fi if [ "$1" = "fits" -o -z "$1" ]; then testfull fits fits fits/float.fits testfull "fits original" fits fits/float.fits " -source aux/pds9.tcl " fi if [ "$1" = "rgbcube" -o -z "$1" ]; then testfull rgbcube rgbcube rgbcube/float.fits testfull "rgbcube original" rgbcube rgbcube/float.fits " -source aux/pds9.tcl " fi if [ "$1" = "rgbimage" -o -z "$1" ]; then testfull rgbimage rgbimage mecube/float.fits testfull "rgbimage original" rgbimage mecube/float.fits " -source aux/pds9.tcl " fi if [ "$1" = "mecube" -o -z "$1" ]; then testfull mecube mecube mecube/float.fits testfull "mecube original" mecube mecube/float.fits " -source aux/pds9.tcl " fi if [ "$1" = "multiframe" -o -z "$1" ]; then testfull multiframe multiframe mecube/float.fits testfull "multiframe original" multiframe mecube/float.fits " -source aux/pds9.tcl " fi if [ "$1" = "mosaicimage" -o -z "$1" ]; then testfull mosaicimagewcs mosaicimagewcs mosaic/mosaicimage.fits testfull "mosaicimagewcs original" mosaicimagewcs mosaic/mosaicimage.fits " -source aux/pds9.tcl " fi if [ "$1" = "mosaic" -o -z "$1" ]; then testfull mosaicwcs mosaicwcs mosaic/mosaicimage.fits testfull "mosaicwcs original" mosaicwcs mosaic/mosaicimage.fits " -source aux/pds9.tcl " fi if [ "$1" = "sfits" -o -z "$1" ]; then testhalf sfits sfits sfits/float.arr testhalf "sfits original" sfits sfits/float.arr " -source aux/pds9.tcl " fi if [ "$1" = "srgbcube" -o -z "$1" ]; then testhalf srgbcube srgbcube srgbcube/float.arr testhalf "srgbcube original" srgbcube srgbcube/float.arr " -source aux/pds9.tcl " fi if [ "$1" = "array" -o -z "$1" ]; then testfull array array array/float_big.arr [dim=256,bitpix=-32,endian=big] testfull "array original" array array/float_big.arr [dim=256,bitpix=-32,endian=big] " -source aux/pds9.tcl " fi if [ "$1" = "rgbarray" -o -z "$1" ]; then testfull rgbarray rgbarray rgbarray/float_big.rgb [dim=256,bitpix=-32,endian=big] -rgb testfull "rgbarray original" rgbarray rgbarray/float_big.rgb [dim=256,bitpix=-32,endian=big] " -rgb -source aux/pds9.tcl " fi if [ "$1" = "nrrd" -o -z "$1" ]; then testfull nrrd nrrd nrrd/float_big_raw.nrrd testfull "nrrd original" nrrd nrrd/float_big_raw.nrrd " -source aux/pds9.tcl " fi if [ "$1" = "photo" -o -z "$1" ]; then testfull photo tiff photo/rose.tiff testfull "photo original" tiff photo/rose.tiff " -source aux/pds9.tcl " fi if [ "$1" = "photorgb" -o -z "$1" ]; then testfull photorgb tiff photo/rose.tiff "" -rgb testfull "photorgb original" tiff photo/rose.tiff "" " -rgb -source aux/pds9.tcl " fi # previous backups if [ "$1" = "old" -o -z "$1" ]; then for f in backup/*.bck do echo "Testing $f" ds9 -restore $f echo "PASSED" done fi echo "DONE" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/incr_load.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000001517�07660243212�014711� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartLoad Frame1 load fits {mosaic image iraf} mosaicimage.fits mmap incr Frame1 load incr data 1 1 1 2080 1000 Frame1 load incr minmax 1 1 1 2080 1000 Frame1 update 1 1 1 2080 1000 Frame1 load incr data 2 1 1 2080 1000 Frame1 load incr minmax 2 1 1 2080 1000 Frame1 update 2 1 1 2080 1000 Frame1 load incr data 3 1 1 2080 1000 Frame1 load incr minmax 3 1 1 2080 1000 Frame1 update 3 1 1 2080 1000 Frame1 load incr data 4 1 1 2080 1000 Frame1 load incr minmax 4 1 1 2080 1000 Frame1 update 4 1 1 2080 1000 Frame1 load incr data 1 1 1 2080 2064 Frame1 update 1 1 1001 2080 2064 Frame1 load incr data 2 1 1 2080 2064 Frame1 update 2 1 1001 2080 2064 Frame1 load incr data 3 1 1 2080 2064 Frame1 update 3 1 1001 2080 2064 Frame1 load incr data 4 1 1 2080 2064 Frame1 update 4 1 1001 2080 2064 Frame1 load incr end FinishLoad ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/srgbcube.sh��������������������������������������������������������������������������0000755�0001750�0001750�00000000102�12122431011�014354� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������spartial.sh SRGBCube srgbcube srgbcube "-frame delete -rgb" $1 $2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/crop.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000002545�12131345054�013553� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** crop.sh ***" echo "..fits[xmin:xmax,ymin:ymax]" ds9 -zscale data/img.fits[100:300,100:300] & KillIt echo "..fits[*,ymin:ymax]" ds9 -zscale data/img.fits[*,100:300] & KillIt echo "..fits[xmin:xmax,*]" ds9 -zscale data/img.fits[100:300,*] & KillIt echo "..fits[xdim@xcen,ydim@ycen]" ds9 -zscale data/img.fits[256@400,256@400] & KillIt echo "..fits[dim@xcen@ycen]" ds9 -zscale data/img.fits[256@400@400] & KillIt echo "..fits[xmin:xmax,ymin:ymax,zmin:zmax]" ds9 -zscale -3d data/3d.fits[100:300,100:300,25:75] -3d vp 45 30& KillIt echo "..fits[*,*,zmin:zmax]" ds9 -zscale -3d data/3d.fits[*,*,25:75] -3d vp 45 30& KillIt echo "..fits[xdim@xcen,ydim@ycen,zdim@zcen]" ds9 -zscale -3d data/3d.fits[100@150,100@150,25@50] -3d vp 45 30& KillIt echo "..fits[dim@xcen@ycen@zcen]" ds9 -zscale -3d data/3d.fits[25@150@150@50] -3d vp 45 30& KillIt echo "DONE" �����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/���������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013022� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/dsseso.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000107�11241073001�015032� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������DSS2-red 30 30 arcsec no new m51 00:42:44.404 +41:16:08.78 sexagesimal ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/prefs.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000016�12126626244�014670� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������white white 8 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/lock.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000036�12021722226�014472� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������none none none no no no no no ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/print.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000025�11533775540�014712� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������printer lp rgb 2 150 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/pixeltable.xpa�������������������������������������������������������������������0000644�0001750�0001750�00000000777�11232370251�015707� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ----------- ----------- ----------- ----------- ----------- | | | | | �./saods9/tests/xpa/catalog.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000000011�11232370250�015144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cat2mass �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/frame.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000114�11715044514�014637� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������none no yes no no no no yes yes no no no yes no no no no no no no yes no no ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/single.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000013�12113740635�015024� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yes no yes ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/3d.xpa���������������������������������������������������������������������������0000644�0001750�0001750�00000000050�12012240444�014041� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������45 30 45 30 1 mip 1 blue 0 green 1 cyan ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/align.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000003�11311767244�014640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/scale.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000053�11715044514�014636� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������linear 1000 -1 66.151024 zscale local 1 no �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/regions.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000002525�12113731142�015214� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical circle(957,1027,40) # tag={foo} yes yes no 10 30 j2000; circle 13:29:52.683 47:11:43.75 3.964" ;# Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical circle(957,1027,40) # tag={foo} # Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 # Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical circle(957,1027,40) # tag={foo} # Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 # Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 ds9 physical fk5 degrees no circle green 1 nl foo ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/rgb.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000051�11717276366�014335� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������red yes yes yes wcs no no no no no no no ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/theme.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000007�11534002410�014634� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������native �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/vo.xpa���������������������������������������������������������������������������0000644�0001750�0001750�00000000564�12124141160�014170� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mime http://cxc.harvard.edu/chandraed/list.txt yes 15 chandra-ed.cfa.harvard.edu:28571 Chandra-Ed Archive Server http://chandra-ed.cfa.harvard.edu/archive.html 0 chandra-ed.rutgers.edu:28571 New Rutgers X-ray Analysis Server http://chandra-ed.rutgers.edu/archive.html 0 basho.rutgers.edu:28571 Back-up Rutgers X-ray Analysis Server http://basho.rutgers.edu/archive.html 0 ��������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/bin.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000051�11715044514�014315� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 4096.5 4096.5 1024 x y 32 32 sum no ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/fits.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000027421�12113733451�014522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 800 800 800 800 1 -32 image 224.1726 224.04129 SIMPLE = T / Standard FITS BITPIX = -32 / bits/pixel NAXIS = 2 / number of axes NAXIS1 = 800 / x axis dimension NAXIS2 = 800 / y axis dimension EXTEND = F / File may contain extensions IRAF-TLM= '11:49:54 (09/03/1998)' / Time of last modification OBJECT = 'TT_HST3728A[1/4]' / ORIGIN = 'KPNO-IRAF' / DATE = '04/01/99' / IRAFNAME= 'tt_scaled3728n' / NAME OF IRAF IMAGE FILE IRAF-MAX= 2.706860E5 / DATA MAX IRAF-MIN= -2.404023E2 / DATA MIN IRAF-BPX= 32 / DATA BITS/PIXEL IRAFTYPE= 'REAL ' / PIXEL TYPE CRVAL1 = 47.2097404068078 CRVAL2 = 202.481101229926 CRPIX1 = 198.5000000 / reference point CRPIX2 = 607.7500000 / reference point CD1_1 = -3.7266660e-05 / WCS matrix value CD1_2 = 4.0525440e-05 / WCS matrix value CD2_1 = -4.0525440e-05 / WCS matrix value CD2_2 = -3.7266660e-05 / WCS matrix value DATAMIN = -240.4023 DATAMAX = 270686. MIR_REVR= T ORIENTAT= -131.863 FILLCNT = 0 ERRCNT = 0 FPKTTIME= 49741.978982527 LPKTTIME= 49741.9791503511 CTYPE1 = 'DEC--TAN' CTYPE2 = 'RA---TAN' DETECTOR= 4 DEZERO = 311.8649 BIASEVEN= 311.8772 BIASODD = 311.8526 GOODMIN = -240.4023 GOODMAX = 270686. DATAMEAN= 24.99208 GPIXELS = 626299 SOFTERRS= 0 CALIBDEF= 7126 STATICD = 0 ATODSAT = 18 DATALOST= 0 BADPIXEL= 0 WCSDIM = 2 LTV1 = 0.5000000 / IRAF ref. point LTV2 = 0.5000000 / IRAF ref. point LTM1_1 = 0.5000000 / IRAF matrix value LTM1_2 = 0.0000000e+00 / IRAF matrix value LTM2_2 = 0.5000000 / IRAF matrix value LTM2_1 = 0.0000000e+00 / IRAF matrix value WAT0_001= 'system=image ' WAT1_001= 'wtype=tan axtype=dec ' WAT2_001= 'wtype=tan axtype=ra ' HISTORY New copy of tt_hst3728a.c0h[1/4] HISTORY New copy of tt_mosaic3728d[-*,*] HISTORY New copy of tt_mosaiced3728b HISTORY New copy of tt_mosaiced3728b HISTORY New copy of tt_real3728h HISTORY New copy of tt_clean3728i HISTORY New copy of tt_median3728j HISTORY New copy of tt_gaussian3728k HISTORY New copy of tt_scaled3728n HISTORY New copy of tt_scaled3728n END SIMPLE = T / Standard FITS BITPIX = -32 / bits/pixel NAXIS = 2 / number of axes NAXIS1 = 800 / x axis dimension NAXIS2 = 800 / y axis dimension EXTEND = F / File may contain extensions IRAF-TLM= '11:49:54 (09/03/1998)' / Time of last modification OBJECT = 'TT_HST3728A[1/4]' / ORIGIN = 'KPNO-IRAF' / DATE = '04/01/99' / IRAFNAME= 'tt_scaled3728n' / NAME OF IRAF IMAGE FILE IRAF-MAX= 2.706860E5 / DATA MAX IRAF-MIN= -2.404023E2 / DATA MIN IRAF-BPX= 32 / DATA BITS/PIXEL IRAFTYPE= 'REAL ' / PIXEL TYPE CRVAL1 = 47.2097404068078 CRVAL2 = 202.481101229926 CRPIX1 = 198.5000000 / reference point CRPIX2 = 607.7500000 / reference point CD1_1 = -3.7266660e-05 / WCS matrix value CD1_2 = 4.0525440e-05 / WCS matrix value CD2_1 = -4.0525440e-05 / WCS matrix value CD2_2 = -3.7266660e-05 / WCS matrix value DATAMIN = -240.4023 DATAMAX = 270686. MIR_REVR= T ORIENTAT= -131.863 FILLCNT = 0 ERRCNT = 0 FPKTTIME= 49741.978982527 LPKTTIME= 49741.9791503511 CTYPE1 = 'DEC--TAN' CTYPE2 = 'RA---TAN' DETECTOR= 4 DEZERO = 311.8649 BIASEVEN= 311.8772 BIASODD = 311.8526 GOODMIN = -240.4023 GOODMAX = 270686. DATAMEAN= 24.99208 GPIXELS = 626299 SOFTERRS= 0 CALIBDEF= 7126 STATICD = 0 ATODSAT = 18 DATALOST= 0 BADPIXEL= 0 WCSDIM = 2 LTV1 = 0.5000000 / IRAF ref. point LTV2 = 0.5000000 / IRAF ref. point LTM1_1 = 0.5000000 / IRAF matrix value LTM1_2 = 0.0000000e+00 / IRAF matrix value LTM2_2 = 0.5000000 / IRAF matrix value LTM2_1 = 0.0000000e+00 / IRAF matrix value WAT0_001= 'system=image ' WAT1_001= 'wtype=tan axtype=dec ' WAT2_001= 'wtype=tan axtype=ra ' HISTORY New copy of tt_hst3728a.c0h[1/4] HISTORY New copy of tt_mosaic3728d[-*,*] HISTORY New copy of tt_mosaiced3728b HISTORY New copy of tt_mosaiced3728b HISTORY New copy of tt_real3728h HISTORY New copy of tt_clean3728i HISTORY New copy of tt_median3728j HISTORY New copy of tt_gaussian3728k HISTORY New copy of tt_scaled3728n HISTORY New copy of tt_scaled3728n END -32 -32 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/pan.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000045�11670473306�014333� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 801 801 13:29:55.287 +47:11:37.73 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/iis.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000034�12113731142�014323� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������data/img.fits data/img.fits ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/iconify.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000000003�11232370250�015173� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/nameserver.xpa�������������������������������������������������������������������0000644�0001750�0001750�00000000055�12131310156�015707� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������m51 simbad-cds degrees 202.469575 47.1952583 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/plot.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000003�11243057721�014520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ap �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/dssstsci.xpa���������������������������������������������������������������������0000644�0001750�0001750�00000000102�11241073001�015364� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������all 30 30 arcsec no new m51 00:42:44.404 +41:16:08.78 sexagesimal ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/rotate.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000002�11232370251�015031� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/preserve.xpa���������������������������������������������������������������������0000644�0001750�0001750�00000000011�11232370251�015366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no no no �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/zscale.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000014�11232370251�015017� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.25 600 120 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/2mass.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000100�11241063563�014564� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h 30 30 arcsec no new m51 00:42:44.404 +41:16:08.78 sexagesimal ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/first.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000074�11241074745�014704� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 30 arcsec no new m51 13:29:52.37 +47:11:40.8 sexagesimal ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/cube.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000013�11715044514�014461� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 0.5 2 no ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/cmap.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000032�11755007521�014465� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������grey grey.sao no 1 0.5 no ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/threads.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000000002�11761437235�015202� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������8 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/contour.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000701654�11575465117�015271� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yes 202.47278 47.218812 202.47282 47.218782 202.47257 47.21864 202.47235 47.218484 202.4721 47.218342 202.47183 47.218216 202.47374 47.219408 202.47378 47.219379 202.47353 47.219237 202.47326 47.21911 202.47803 47.222092 202.47807 47.222062 202.47786 47.221896 202.47756 47.221794 202.47994 47.223284 202.47997 47.223263 202.47974 47.223106 202.47947 47.222986 202.48365 47.223802 202.48335 47.223919 202.48316 47.224099 202.48299 47.224289 202.50389 47.182003 202.50373 47.181955 202.50374 47.181907 202.50378 47.181913 202.50389 47.182003 202.49291 47.175441 202.49272 47.175447 202.49266 47.175287 202.49286 47.175344 202.49291 47.175441 202.51263 47.18806 202.5123 47.187984 202.51227 47.187836 202.51251 47.187823 202.51263 47.18806 202.49885 47.179449 202.49878 47.179429 202.49877 47.179402 202.49881 47.179409 202.49885 47.179449 202.4897 47.173733 202.48931 47.173744 202.48929 47.173482 202.48968 47.173467 202.4897 47.173733 202.4818 47.168799 202.48143 47.168831 202.48132 47.168795 202.48096 47.168869 202.48089 47.168905 202.48072 47.169017 202.48035 47.168977 202.48011 47.168828 202.47987 47.168681 202.47986 47.16848 202.48003 47.168288 202.48025 47.168124 202.48058 47.168037 202.4807 47.168069 202.48098 47.168183 202.48118 47.168365 202.48149 47.168462 202.48178 47.168573 202.4818 47.168799 202.52011 47.193026 202.52001 47.193017 202.52001 47.192963 202.52012 47.192942 202.52011 47.193026 202.49835 47.179441 202.49831 47.179448 202.49832 47.17942 202.49836 47.179414 202.49835 47.179441 202.49717 47.178702 202.49728 47.178907 202.4973 47.179079 202.49709 47.179249 202.49686 47.179225 202.49658 47.179232 202.49632 47.179366 202.49642 47.179549 202.49643 47.179734 202.49635 47.179922 202.49633 47.179972 202.49635 47.180251 202.49675 47.180278 202.49689 47.1805 202.49695 47.180656 202.49695 47.180779 202.49723 47.180832 202.4973 47.180847 202.4973 47.18088 202.49739 47.18111 202.49773 47.181146 202.49777 47.181151 202.49804 47.181277 202.4984 47.181266 202.49848 47.181281 202.49878 47.181381 202.49906 47.181498 202.49903 47.181656 202.49897 47.18189 202.49923 47.182024 202.49947 47.182171 202.49945 47.182221 202.49947 47.182499 202.49988 47.182487 202.49993 47.182485 202.49993 47.182519 202.49973 47.182697 202.49988 47.182842 202.49999 47.183091 202.50035 47.183081 202.50045 47.183078 202.50073 47.183196 202.50078 47.183352 202.50083 47.183442 202.50103 47.183623 202.50104 47.183812 202.50108 47.183913 202.50123 47.183929 202.50151 47.183921 202.50178 47.183975 202.50188 47.183972 202.50209 47.184138 202.50209 47.184171 202.50205 47.184173 202.50164 47.184185 202.50165 47.184463 202.50168 47.18451 202.5018 47.184679 202.50197 47.184692 202.50205 47.184499 202.50206 47.184451 202.50211 47.18445 202.50252 47.184438 202.50259 47.184419 202.50292 47.184504 202.50293 47.184693 202.50271 47.184855 202.50263 47.185042 202.50264 47.185108 202.50256 47.185093 202.50215 47.185105 202.50217 47.185383 202.5022 47.185432 202.50198 47.185594 202.50199 47.185839 202.50223 47.18599 202.5026 47.18598 202.50273 47.185764 202.50295 47.185784 202.50326 47.185883 202.50354 47.186 202.50353 47.186263 202.50314 47.186291 202.50303 47.186249 202.50306 47.18635 202.50321 47.186366 202.50345 47.186391 202.50372 47.186516 202.50377 47.186715 202.50381 47.186774 202.50402 47.186872 202.50412 47.186869 202.50436 47.187018 202.5046 47.187167 202.50496 47.187157 202.50503 47.187171 202.50504 47.187204 202.50516 47.1874 202.50522 47.187616 202.50509 47.187776 202.50547 47.187822 202.50565 47.188015 202.50566 47.188195 202.50545 47.188359 202.50546 47.188484 202.5057 47.188633 202.50583 47.188863 202.50624 47.188851 202.50628 47.18885 202.50629 47.188883 202.50609 47.189061 202.50619 47.189242 202.50637 47.189237 202.50665 47.189229 202.50662 47.189388 202.50656 47.189621 202.5069 47.189565 202.50708 47.18956 202.50714 47.189716 202.50692 47.189878 202.50661 47.189981 202.50674 47.190141 202.50686 47.190375 202.5071 47.190524 202.50734 47.190673 202.50732 47.190724 202.50734 47.191002 202.50757 47.191151 202.5076 47.1912 202.50773 47.19136 202.50797 47.191509 202.50809 47.191502 202.50843 47.191492 202.5087 47.191621 202.5087 47.191887 202.5083 47.191917 202.5081 47.191809 202.50811 47.192054 202.50812 47.19212 202.50813 47.192365 202.50849 47.192429 202.50861 47.192663 202.50885 47.192812 202.50906 47.192984 202.50933 47.19311 202.5093 47.19316 202.50923 47.193179 202.50887 47.193189 202.50865 47.193351 202.50878 47.193513 202.50875 47.193711 202.50846 47.193749 202.50834 47.193754 202.50809 47.193897 202.50812 47.193998 202.50837 47.194073 202.50844 47.19382 202.50879 47.193833 202.5089 47.194074 202.5089 47.194107 202.50883 47.194126 202.50847 47.194136 202.50838 47.194376 202.50835 47.194479 202.50837 47.194668 202.50809 47.194676 202.50791 47.194681 202.50797 47.194765 202.50819 47.194927 202.5082 47.195165 202.5082 47.195243 202.50835 47.195259 202.50855 47.19531 202.50875 47.195489 202.50879 47.19553 202.50893 47.195679 202.50904 47.195686 202.50938 47.195676 202.50954 47.19588 202.5098 47.196017 202.50983 47.196181 202.50983 47.196316 202.51014 47.196376 202.51037 47.196219 202.51043 47.196195 202.51076 47.196281 202.51072 47.196439 202.51048 47.196586 202.51032 47.196604 202.51011 47.196653 202.50983 47.196777 202.50977 47.19701 202.50976 47.197035 202.50987 47.197264 202.51006 47.197448 202.51007 47.197524 202.50994 47.197746 202.50993 47.197871 202.51007 47.198092 202.51032 47.198236 202.51036 47.198304 202.51033 47.198553 202.51063 47.198475 202.5108 47.198279 202.51118 47.198222 202.51125 47.198198 202.51149 47.198347 202.51149 47.198413 202.51164 47.198563 202.51177 47.198589 202.51198 47.198631 202.51201 47.19874 202.51202 47.198925 202.51231 47.199042 202.51248 47.19924 202.51256 47.199379 202.51248 47.199566 202.51248 47.199632 202.51239 47.199872 202.51228 47.200039 202.51226 47.200089 202.51228 47.200367 202.51269 47.200356 202.51276 47.200337 202.51276 47.200403 202.51278 47.200648 202.51278 47.200714 202.5128 47.200959 202.51312 47.201044 202.51302 47.201161 202.5128 47.201323 202.51259 47.201494 202.51233 47.201632 202.51218 47.201834 202.51197 47.202001 202.51168 47.202119 202.51163 47.20215 202.51126 47.20216 202.5112 47.20214 202.51077 47.202153 202.51056 47.202319 202.51069 47.202517 202.51065 47.202676 202.5107 47.202837 202.51063 47.202963 202.51039 47.203111 202.51027 47.203154 202.51003 47.203005 202.50997 47.202849 202.5099 47.202772 202.5097 47.2026 202.50965 47.20235 202.50979 47.202203 202.50958 47.202037 202.50934 47.201888 202.50931 47.201839 202.50917 47.201689 202.50893 47.20154 202.50873 47.201359 202.50872 47.201171 202.50888 47.20097 202.50913 47.20083 202.50921 47.200683 202.50901 47.200753 202.50867 47.200753 202.50847 47.200579 202.50833 47.200352 202.50832 47.200325 202.50823 47.200104 202.50817 47.199931 202.50826 47.199753 202.50792 47.199683 202.50764 47.199598 202.50777 47.199796 202.50792 47.200008 202.5079 47.200059 202.50783 47.200077 202.50761 47.200176 202.50724 47.200186 202.5071 47.200159 202.50716 47.200242 202.50718 47.200507 202.50679 47.200519 202.50669 47.200266 202.50647 47.200363 202.50611 47.200371 202.50602 47.200111 202.50602 47.20008 202.50597 47.199819 202.506 47.199768 202.50598 47.19949 202.50574 47.199341 202.50543 47.199247 202.50542 47.199109 202.50549 47.198875 202.50549 47.198855 202.50558 47.198614 202.50558 47.198486 202.50557 47.198303 202.50578 47.198138 202.50577 47.198015 202.50581 47.197857 202.50586 47.197623 202.50562 47.197474 202.50532 47.197373 202.50508 47.197399 202.50486 47.197388 202.50468 47.197194 202.50428 47.197201 202.50418 47.197438 202.50402 47.197639 202.50363 47.19765 202.50353 47.197395 202.50353 47.197329 202.50342 47.197148 202.50322 47.196975 202.50321 47.196832 202.50342 47.196826 202.50375 47.196871 202.50382 47.196853 202.50406 47.197002 202.50442 47.196991 202.50441 47.196746 202.5044 47.19668 202.50427 47.19652 202.50411 47.196317 202.5041 47.196191 202.50404 47.196045 202.50379 47.195903 202.50366 47.195915 202.5037 47.195964 202.50369 47.196235 202.5033 47.196267 202.50319 47.196219 202.50291 47.196224 202.5028 47.196277 202.50248 47.196378 202.50228 47.196368 202.50222 47.196216 202.5023 47.196027 202.50229 47.195961 202.50216 47.195801 202.50201 47.195785 202.50178 47.195761 202.5018 47.19565 202.50175 47.195454 202.50148 47.19545 202.50125 47.195504 202.50128 47.195328 202.50141 47.195108 202.50154 47.194958 202.50154 47.194892 202.50161 47.194912 202.50197 47.194859 202.5021 47.194873 202.50245 47.194941 202.50273 47.195061 202.50281 47.195086 202.50311 47.194977 202.50309 47.194794 202.50301 47.194612 202.50298 47.19455 202.50293 47.194564 202.50252 47.194564 202.50227 47.194453 202.50223 47.194449 202.50183 47.194425 202.50165 47.194229 202.50134 47.194168 202.5013 47.194161 202.50101 47.194049 202.5008 47.19413 202.50045 47.19414 202.50026 47.19409 202.50003 47.194128 202.49987 47.193915 202.49966 47.193749 202.49932 47.193672 202.49931 47.1935 202.49949 47.19331 202.49962 47.193126 202.49928 47.193182 202.49912 47.193171 202.49886 47.193215 202.49859 47.193239 202.49862 47.193067 202.49877 47.192863 202.49879 47.19276 202.4987 47.192819 202.49825 47.192837 202.49827 47.192549 202.49867 47.192502 202.49855 47.192289 202.49831 47.19214 202.49813 47.191953 202.4981 47.191844 202.49802 47.191707 202.49797 47.191467 202.49799 47.191401 202.4979 47.191419 202.49757 47.19139 202.4975 47.19117 202.49754 47.191082 202.49739 47.190869 202.49712 47.190741 202.49683 47.190635 202.49655 47.190581 202.49648 47.190567 202.49613 47.190501 202.49617 47.190338 202.4961 47.190193 202.49581 47.190118 202.49577 47.190114 202.4954 47.190161 202.49526 47.190164 202.49489 47.190139 202.49466 47.190298 202.49464 47.190302 202.49437 47.190176 202.49401 47.190186 202.49379 47.190348 202.4938 47.190593 202.49381 47.19066 202.49371 47.190662 202.49347 47.190513 202.49347 47.190447 202.49336 47.190266 202.49321 47.190053 202.49301 47.189881 202.49297 47.189838 202.49295 47.189593 202.49298 47.189543 202.49289 47.189313 202.49289 47.189187 202.49294 47.188953 202.49259 47.188885 202.4923 47.188824 202.49226 47.188806 202.49225 47.188793 202.49223 47.1885 202.49188 47.188438 202.49186 47.18825 202.49183 47.188148 202.49162 47.187978 202.49161 47.187789 202.4916 47.187667 202.49145 47.187454 202.49109 47.18739 202.49088 47.18722 202.49064 47.187071 202.49045 47.186889 202.49011 47.186852 202.49019 47.187082 202.49047 47.187198 202.49048 47.187387 202.49022 47.187519 202.49003 47.187524 202.48968 47.187483 202.48964 47.187484 202.48962 47.187448 202.48951 47.187259 202.48925 47.187129 202.48912 47.187132 202.48912 47.18722 202.48925 47.18745 202.48923 47.187501 202.48931 47.187731 202.48966 47.187767 202.4897 47.187766 202.48973 47.187815 202.48983 47.187996 202.48996 47.188226 202.4902 47.188375 202.49019 47.188403 202.49015 47.188409 202.48974 47.188421 202.48967 47.18844 202.48945 47.188538 202.48909 47.188612 202.48924 47.188759 202.48937 47.188788 202.48965 47.18878 202.48994 47.188891 202.49016 47.189057 202.49039 47.189215 202.4904 47.189428 202.49013 47.189405 202.48988 47.189266 202.4897 47.189292 202.48958 47.189484 202.48961 47.189533 202.48951 47.189535 202.48915 47.189546 202.48905 47.189548 202.48873 47.189463 202.48846 47.189335 202.48838 47.189361 202.488 47.189354 202.48787 47.189343 202.48755 47.189441 202.48745 47.189432 202.48745 47.189378 202.48744 47.189116 202.48733 47.189008 202.48751 47.18906 202.48778 47.188986 202.48777 47.188873 202.48747 47.188798 202.48737 47.188843 202.48743 47.188769 202.48741 47.188484 202.48738 47.188439 202.48748 47.188436 202.48786 47.188478 202.48806 47.188568 202.48816 47.188585 202.48838 47.188747 202.48875 47.188697 202.48879 47.188443 202.48848 47.188348 202.4882 47.188356 202.48797 47.188394 202.48774 47.188245 202.48746 47.188191 202.48736 47.188194 202.48739 47.188144 202.48749 47.187907 202.48745 47.187806 202.4873 47.18779 202.48709 47.187748 202.48683 47.187616 202.48677 47.18746 202.48673 47.187359 202.48649 47.187284 202.48659 47.187465 202.48655 47.187623 202.48639 47.187612 202.4861 47.187504 202.48596 47.187282 202.48562 47.187338 202.48549 47.187557 202.4852 47.187678 202.48489 47.18778 202.48467 47.187942 202.48463 47.187938 202.48459 47.187895 202.48481 47.187733 202.48496 47.187527 202.48505 47.187299 202.4848 47.187159 202.48441 47.187122 202.48417 47.18703 202.48419 47.187283 202.4842 47.187349 202.48409 47.187582 202.48382 47.187559 202.48377 47.18738 202.48389 47.187183 202.4835 47.187211 202.48338 47.187434 202.48338 47.187556 202.48361 47.187714 202.48367 47.187914 202.48364 47.188017 202.48365 47.188205 202.48371 47.188289 202.48398 47.188416 202.48403 47.188442 202.48429 47.188513 202.48459 47.18849 202.48479 47.188467 202.48512 47.18852 202.48519 47.188502 202.4855 47.188595 202.48578 47.188714 202.48579 47.188944 202.48583 47.188999 202.48585 47.189278 202.48544 47.189291 202.48521 47.189136 202.48509 47.1891 202.48481 47.189107 202.48451 47.189001 202.48428 47.188897 202.48418 47.189131 202.48388 47.189139 202.48368 47.189121 202.4834 47.189242 202.4833 47.189245 202.48293 47.189247 202.48285 47.189249 202.48261 47.189346 202.48226 47.18943 202.48236 47.189612 202.48249 47.189571 202.48287 47.18956 202.48296 47.189564 202.48319 47.189412 202.48353 47.189402 202.48368 47.189418 202.48402 47.189331 202.48407 47.189329 202.48435 47.189446 202.48454 47.189633 202.48457 47.189676 202.48467 47.189857 202.48468 47.190046 202.48472 47.190145 202.48484 47.190382 202.48511 47.190313 202.48542 47.190209 202.48552 47.190206 202.48553 47.190272 202.48566 47.190432 202.4859 47.190507 202.48589 47.190262 202.48588 47.190196 202.48598 47.190193 202.48622 47.190342 202.48646 47.190491 202.48646 47.190558 202.48656 47.190739 202.48674 47.190734 202.48682 47.190547 202.48682 47.190481 202.48672 47.190298 202.48648 47.190149 202.48624 47.190002 202.48611 47.189772 202.48581 47.189671 202.48562 47.189482 202.48562 47.189433 202.48569 47.189434 202.48598 47.18954 202.48618 47.18972 202.48654 47.18971 202.48664 47.189707 202.48697 47.189784 202.48711 47.190011 202.48716 47.190094 202.48711 47.190333 202.48711 47.190367 202.48713 47.190645 202.48742 47.19056 202.48773 47.190524 202.48775 47.190764 202.48751 47.190917 202.48718 47.191005 202.48719 47.19125 202.48755 47.191239 202.48773 47.191051 202.48795 47.191013 202.48814 47.191006 202.48821 47.190819 202.48821 47.190753 202.48811 47.190572 202.4881 47.190383 202.48809 47.190261 202.48794 47.190048 202.48797 47.190003 202.48795 47.189714 202.48794 47.189686 202.48798 47.189691 202.48834 47.189753 202.48861 47.189807 202.48871 47.189804 202.48906 47.189868 202.48908 47.190097 202.48886 47.190259 202.48883 47.190362 202.48911 47.190416 202.48933 47.190254 202.48931 47.190009 202.48931 47.189943 202.48953 47.18978 202.48962 47.189778 202.48959 47.189823 202.48974 47.190017 202.4898 47.190253 202.48943 47.190317 202.48944 47.190562 202.48945 47.190628 202.48935 47.190631 202.48899 47.190641 202.48877 47.190803 202.48878 47.191048 202.48902 47.191198 202.48903 47.191264 202.4892 47.191392 202.48937 47.191594 202.48949 47.191552 202.48977 47.191427 202.48985 47.19124 202.48988 47.191195 202.48981 47.190944 202.48973 47.190804 202.49004 47.190701 202.48994 47.19052 202.48993 47.190331 202.49021 47.190323 202.49036 47.190536 202.49072 47.190526 202.49082 47.190523 202.49111 47.19047 202.49129 47.190496 202.4916 47.190478 202.49174 47.190488 202.49194 47.190669 202.49218 47.190818 202.49219 47.190845 202.49212 47.190864 202.49188 47.190715 202.49166 47.190812 202.49161 47.19091 202.49162 47.191091 202.49132 47.191198 202.49125 47.191453 202.49111 47.191605 202.49133 47.191507 202.49155 47.191345 202.49191 47.191271 202.49198 47.191291 202.49234 47.191348 202.49264 47.191453 202.49285 47.191619 202.49293 47.191887 202.4932 47.192013 202.49356 47.192077 202.49368 47.192311 202.4939 47.192214 202.49409 47.192032 202.49416 47.191958 202.49415 47.191769 202.49437 47.191607 202.49436 47.191484 202.49421 47.191272 202.49397 47.191123 202.49374 47.191217 202.49339 47.191225 202.49341 47.191011 202.49372 47.190907 202.49382 47.190905 202.49404 47.191071 202.49428 47.19122 202.49468 47.191208 202.49476 47.19119 202.49499 47.191101 202.49536 47.191033 202.4954 47.19104 202.49564 47.191189 202.49589 47.19133 202.49619 47.19143 202.49625 47.191586 202.49603 47.191748 202.49595 47.191935 202.49619 47.192084 202.49619 47.19215 202.49621 47.192395 202.49647 47.192529 202.4965 47.192639 202.49627 47.192677 202.49599 47.192623 202.49592 47.192609 202.49551 47.19262 202.49553 47.192899 202.49555 47.192947 202.49546 47.19295 202.49522 47.192801 202.49501 47.192629 202.49465 47.192679 202.49447 47.1927 202.49428 47.192516 202.49392 47.192527 202.49394 47.192772 202.49394 47.192838 202.49372 47.193 202.49348 47.193146 202.49363 47.193327 202.49364 47.193547 202.4934 47.193696 202.49322 47.193886 202.4931 47.194042 202.49331 47.194214 202.49358 47.194341 202.49358 47.194407 202.49368 47.194588 202.49369 47.194776 202.4934 47.194893 202.4932 47.194947 202.49302 47.194952 202.49274 47.19496 202.49273 47.194771 202.49272 47.194648 202.49244 47.194595 202.49235 47.194598 202.49234 47.194532 202.49221 47.194372 202.49209 47.194137 202.49209 47.194071 202.49207 47.193826 202.49207 47.19376 202.49205 47.193515 202.49205 47.193449 202.49195 47.193268 202.49179 47.193055 202.49158 47.192889 202.49157 47.192853 202.49162 47.192854 202.49203 47.192843 202.49195 47.192613 202.49167 47.192496 202.49152 47.192284 202.49119 47.192198 202.49107 47.192242 202.49067 47.192291 202.49044 47.192448 202.49026 47.192631 202.49019 47.192611 202.49016 47.192568 202.49014 47.192323 202.48986 47.192381 202.48966 47.192356 202.48941 47.192216 202.4894 47.192094 202.48938 47.191907 202.4891 47.19179 202.48883 47.191737 202.48873 47.19174 202.48837 47.19175 202.48815 47.191912 202.48825 47.192093 202.48855 47.1922 202.48876 47.192296 202.48884 47.19231 202.48884 47.192343 202.48896 47.192549 202.48897 47.192721 202.48881 47.192921 202.48854 47.193053 202.48852 47.193195 202.48853 47.193347 202.48841 47.19357 202.48802 47.193564 202.48776 47.193465 202.48757 47.193643 202.4877 47.193803 202.48771 47.194033 202.48772 47.194114 202.48796 47.194189 202.48821 47.194043 202.48825 47.19405 202.48828 47.194088 202.48807 47.194252 202.48806 47.194516 202.48806 47.194547 202.48821 47.194724 202.48833 47.194714 202.48862 47.194749 202.4889 47.194864 202.48894 47.195097 202.48855 47.195124 202.4885 47.195125 202.48846 47.195195 202.48872 47.195329 202.48864 47.195511 202.48844 47.195684 202.48815 47.195745 202.48818 47.195518 202.48821 47.195379 202.48788 47.195332 202.488 47.195536 202.48805 47.195739 202.48802 47.19584 202.48829 47.195968 202.48831 47.196198 202.48831 47.196279 202.48844 47.19628 202.4887 47.19632 202.48885 47.19653 202.48885 47.196539 202.48882 47.196551 202.48844 47.19658 202.48834 47.19682 202.48835 47.196902 202.48845 47.197153 202.48848 47.197202 202.48858 47.197383 202.48854 47.197542 202.48849 47.197775 202.48849 47.197808 202.48839 47.198045 202.48844 47.198136 202.48862 47.198325 202.48864 47.198497 202.48861 47.198661 202.48862 47.198786 202.48856 47.19902 202.48889 47.199104 202.48895 47.199291 202.48866 47.199409 202.48854 47.199636 202.48841 47.199787 202.48839 47.199838 202.48833 47.200104 202.48807 47.200236 202.48799 47.200423 202.48799 47.200489 202.48801 47.200734 202.48824 47.200641 202.48858 47.200637 202.4886 47.200869 202.48857 47.200968 202.48858 47.201157 202.48827 47.20126 202.48837 47.201441 202.48838 47.20163 202.4883 47.201816 202.48828 47.201867 202.48823 47.201868 202.48782 47.20188 202.48778 47.201875 202.48777 47.201848 202.48769 47.201618 202.48735 47.201582 202.48731 47.201577 202.48699 47.201659 202.48694 47.201848 202.48694 47.201928 202.48676 47.201979 202.4866 47.202013 202.48626 47.202097 202.48636 47.202278 202.48664 47.202339 202.48669 47.202358 202.48692 47.202511 202.48716 47.202364 202.48758 47.202352 202.4876 47.202639 202.48738 47.202799 202.48697 47.202805 202.4868 47.202735 202.48661 47.20274 202.48641 47.202567 202.48606 47.20257 202.48584 47.202732 202.48594 47.202913 202.48611 47.203112 202.48637 47.203244 202.48643 47.2034 202.48646 47.203501 202.48666 47.20368 202.48687 47.203854 202.48692 47.204009 202.48663 47.204126 202.48643 47.204179 202.48625 47.204185 202.48597 47.204193 202.48585 47.204237 202.48583 47.204294 202.4858 47.204508 202.48563 47.204695 202.4853 47.204791 202.48511 47.204829 202.48492 47.204643 202.48461 47.204545 202.48437 47.204394 202.48425 47.204164 202.48424 47.204131 202.48413 47.203925 202.48412 47.203753 202.48402 47.203679 202.48378 47.20353 202.48358 47.20342 202.48351 47.203405 202.48352 47.203378 202.4835 47.203088 202.4835 47.203066 202.48343 47.202815 202.48319 47.202666 202.483 47.202479 202.48299 47.202452 202.48306 47.202196 202.48343 47.202128 202.48335 47.201898 202.48334 47.201772 202.4834 47.201538 202.4834 47.201511 202.48338 47.201221 202.48339 47.201202 202.4833 47.200959 202.4832 47.200789 202.48323 47.200686 202.48322 47.200497 202.48316 47.200413 202.48317 47.200172 202.4833 47.199983 202.48327 47.199934 202.48314 47.199774 202.4829 47.199625 202.48271 47.199446 202.48265 47.199246 202.48284 47.199068 202.48288 47.198992 202.48287 47.198782 202.48296 47.198606 202.48296 47.19854 202.48305 47.1983 202.48327 47.198137 202.48329 47.198034 202.48333 47.197876 202.48329 47.197715 202.48321 47.197499 202.48321 47.197444 202.4833 47.197257 202.48332 47.197036 202.48326 47.196932 202.48316 47.19683 202.48315 47.196564 202.48313 47.196527 202.48305 47.196503 202.48268 47.196571 202.48246 47.196733 202.48263 47.196898 202.48283 47.19708 202.48279 47.197238 202.48267 47.197462 202.48245 47.197626 202.48215 47.197739 202.48211 47.197936 202.48211 47.198011 202.48197 47.198223 202.48182 47.198427 202.48181 47.198481 202.48183 47.19873 202.4817 47.198887 202.48168 47.198938 202.48176 47.199168 202.48177 47.199293 202.48156 47.199461 202.48154 47.199657 202.48157 47.199767 202.48138 47.199951 202.48108 47.200061 202.48096 47.200282 202.48094 47.200425 202.48095 47.200576 202.48091 47.200773 202.4809 47.200845 202.4808 47.200857 202.48041 47.200814 202.48036 47.200804 202.48013 47.200961 202.48012 47.201033 202.48022 47.201284 202.48046 47.201433 202.48046 47.201466 202.48047 47.201744 202.48059 47.201846 202.48038 47.202014 202.48038 47.202136 202.48065 47.202264 202.48068 47.202504 202.48029 47.202531 202.48016 47.2023 202.47993 47.20233 202.4799 47.202498 202.4799 47.202615 202.47993 47.202797 202.47989 47.202905 202.48002 47.203055 202.48004 47.203298 202.47964 47.20335 202.47954 47.203412 202.4794 47.203496 202.47939 47.203519 202.47938 47.203787 202.47911 47.203912 202.47908 47.204075 202.47914 47.204231 202.47888 47.204369 202.47881 47.204603 202.4788 47.204622 202.47876 47.204896 202.47851 47.205034 202.47821 47.205146 202.47793 47.20527 202.47777 47.20547 202.47749 47.205597 202.47743 47.205621 202.47721 47.205719 202.47701 47.205891 202.47698 47.205953 202.47692 47.206139 202.47666 47.206192 202.47657 47.206219 202.47632 47.206359 202.47625 47.206494 202.47622 47.206595 202.47603 47.206657 202.47585 47.206663 202.47567 47.206855 202.47555 47.207011 202.47552 47.207056 202.47548 47.207334 202.47539 47.207453 202.4754 47.207579 202.47517 47.207617 202.47489 47.207496 202.47476 47.207478 202.47445 47.207587 202.47442 47.207843 202.47444 47.20788 202.47456 47.208069 202.47471 47.208282 202.47469 47.208332 202.47461 47.208351 202.47425 47.208361 202.47408 47.208554 202.47378 47.208664 202.47374 47.208671 202.4734 47.208727 202.47324 47.208716 202.47316 47.208576 202.47316 47.208449 202.47297 47.208459 202.47275 47.208621 202.47257 47.208802 202.47235 47.208964 202.47201 47.208974 202.4719 47.208987 202.47154 47.208998 202.47143 47.20899 202.47109 47.209 202.47099 47.209013 202.47078 47.209182 202.47055 47.209073 202.47025 47.209151 202.47 47.209291 202.46971 47.209409 202.46963 47.209427 202.46936 47.209494 202.46909 47.209502 202.46891 47.209509 202.46892 47.209632 202.46917 47.20977 202.46938 47.209806 202.46955 47.209612 202.46979 47.209636 202.47006 47.209631 202.47028 47.209469 202.47051 47.209431 202.47063 47.20939 202.47085 47.209227 202.47109 47.209076 202.47144 47.209065 202.47168 47.209147 202.47178 47.209144 202.47214 47.209134 202.47224 47.209131 202.47256 47.209217 202.47257 47.209405 202.47226 47.209508 202.47216 47.209743 202.47178 47.209804 202.47176 47.209809 202.47141 47.209874 202.47125 47.209863 202.47087 47.209838 202.47065 47.21 202.47059 47.210023 202.47023 47.210034 202.47013 47.210036 202.46991 47.210135 202.46957 47.210222 202.46929 47.210347 202.46926 47.210356 202.46895 47.210435 202.4687 47.210442 202.46852 47.210461 202.46819 47.210495 202.46808 47.210488 202.46771 47.210556 202.46749 47.210718 202.46745 47.210714 202.46708 47.210666 202.46684 47.210608 202.46675 47.210583 202.4664 47.210515 202.46629 47.210567 202.46587 47.210579 202.46576 47.210533 202.46548 47.210541 202.4653 47.210546 202.46502 47.210554 202.46475 47.210501 202.46461 47.210714 202.46436 47.210721 202.46405 47.21066 202.46401 47.210656 202.46364 47.210702 202.4635 47.210706 202.46312 47.210681 202.46308 47.210687 202.46282 47.210555 202.46247 47.210491 202.46226 47.210321 202.46197 47.210204 202.46184 47.210177 202.46184 47.210299 202.46186 47.210488 202.46158 47.210496 202.4613 47.210442 202.46104 47.210579 202.46101 47.21059 202.46075 47.210697 202.46047 47.210662 202.46028 47.210476 202.46016 47.210327 202.46016 47.210245 202.46 47.210229 202.45983 47.210158 202.45984 47.210123 202.46005 47.209959 202.46024 47.209778 202.46043 47.209596 202.46065 47.209434 202.46088 47.209281 202.46108 47.209107 202.46129 47.208935 202.46152 47.208783 202.46177 47.208637 202.46201 47.208491 202.46227 47.208352 202.46246 47.208171 202.46266 47.207999 202.46289 47.207839 202.46309 47.207671 202.46331 47.207504 202.46356 47.207361 202.4638 47.207217 202.46399 47.207037 202.46421 47.206874 202.46443 47.206712 202.46463 47.206536 202.46485 47.206374 202.46508 47.206216 202.46534 47.206083 202.46547 47.205866 202.46567 47.205689 202.46594 47.205557 202.46615 47.205391 202.46636 47.205225 202.46653 47.205028 202.46672 47.204852 202.46696 47.204703 202.46702 47.204525 202.46707 47.204468 202.46722 47.204266 202.46745 47.204108 202.46768 47.203957 202.46791 47.203866 202.46802 47.203868 202.46826 47.203717 202.46828 47.203597 202.46836 47.203481 202.46851 47.203276 202.46869 47.203086 202.46897 47.202965 202.46922 47.202821 202.46947 47.202681 202.46966 47.202497 202.46988 47.202335 202.47011 47.202178 202.4703 47.202001 202.47021 47.201848 202.46997 47.201695 202.46974 47.201538 202.46948 47.201411 202.46922 47.201272 202.46899 47.201119 202.46879 47.200945 202.46854 47.200804 202.4683 47.200655 202.46807 47.200499 202.46779 47.200379 202.46756 47.200224 202.46731 47.200086 202.46709 47.199923 202.46684 47.19978 202.46659 47.199637 202.46635 47.19949 202.4661 47.199351 202.46585 47.199207 202.46563 47.199051 202.46538 47.198908 202.46514 47.198762 202.46497 47.19867 202.46486 47.198643 202.46455 47.19854 202.46444 47.19834 202.46442 47.198316 202.46417 47.198171 202.46417 47.19817 202.46384 47.198089 202.46363 47.197919 202.4634 47.197764 202.46315 47.197624 202.46296 47.197438 202.46286 47.197348 202.46275 47.197272 202.46252 47.197112 202.46229 47.196957 202.46209 47.196869 202.46201 47.196844 202.46199 47.196806 202.46184 47.196642 202.46162 47.196477 202.46137 47.196335 202.46108 47.196227 202.46086 47.196063 202.4606 47.195932 202.46058 47.195925 202.46026 47.195855 202.46022 47.195699 202.46022 47.195562 202.46024 47.195416 202.46047 47.195254 202.46072 47.195117 202.46091 47.194936 202.46113 47.194774 202.46132 47.194594 202.4615 47.194404 202.46174 47.194255 202.46199 47.194114 202.46215 47.193915 202.46235 47.193741 202.46259 47.19359 202.46283 47.193444 202.46308 47.193295 202.46327 47.193121 202.46349 47.192954 202.46372 47.1928 202.46393 47.192634 202.46415 47.192468 202.46436 47.192303 202.46457 47.192135 202.4648 47.191978 202.465 47.191806 202.46521 47.191639 202.46543 47.191476 202.46566 47.191317 202.4659 47.19117 202.4661 47.190997 202.46633 47.190843 202.46656 47.190689 202.46678 47.190523 202.467 47.19036 202.46721 47.190196 202.46742 47.190027 202.46766 47.189877 202.46788 47.189719 202.4681 47.189553 202.46831 47.189383 202.46852 47.18922 202.46873 47.189052 202.46896 47.188896 202.46917 47.188728 202.46916 47.18863 202.46895 47.188462 202.46874 47.188293 202.46853 47.188121 202.46826 47.187996 202.46801 47.187853 202.46777 47.187708 202.46755 47.187542 202.46733 47.187381 202.46708 47.187241 202.46684 47.187092 202.46662 47.186928 202.46639 47.186773 202.46616 47.186624 202.46595 47.186453 202.46572 47.186294 202.46545 47.186168 202.46522 47.186015 202.46496 47.185878 202.46474 47.185719 202.4645 47.185569 202.46422 47.185449 202.46409 47.185253 202.46424 47.185111 202.46426 47.18506 202.4643 47.185065 202.46473 47.185053 202.46491 47.184869 202.46516 47.184723 202.46521 47.184722 202.46555 47.184666 202.46578 47.184628 202.46596 47.184623 202.46603 47.184436 202.46606 47.184391 202.46613 47.184368 202.46636 47.184279 202.46635 47.184205 202.46637 47.183986 202.46652 47.183776 202.46659 47.183703 202.46662 47.183544 202.46685 47.183506 202.46713 47.18356 202.46722 47.183557 202.46759 47.183547 202.46783 47.183401 202.46788 47.183399 202.46818 47.1835 202.46846 47.183496 202.46867 47.18333 202.46866 47.183145 202.4685 47.182942 202.4685 47.18292 202.46856 47.182896 202.46888 47.182981 202.46904 47.183194 202.46927 47.183106 202.4693 47.183003 202.46928 47.182814 202.4696 47.182711 202.46969 47.182708 202.46996 47.182639 202.47024 47.182631 202.47025 47.18282 202.47026 47.182942 202.47044 47.182937 202.47043 47.182814 202.47042 47.182626 202.4707 47.182618 202.47088 47.182613 202.47087 47.18249 202.47074 47.182259 202.47074 47.182228 202.47079 47.182227 202.47117 47.182198 202.47125 47.182213 202.47151 47.182111 202.47187 47.18208 202.47209 47.182172 202.47216 47.182187 202.47257 47.182175 202.47262 47.182174 202.47303 47.182162 202.47325 47.182 202.47323 47.181722 202.47323 47.181689 202.47345 47.181527 202.47349 47.181531 202.47391 47.181519 202.47398 47.181495 202.47398 47.181561 202.47386 47.181782 202.47354 47.181885 202.47357 47.182123 202.4738 47.18228 202.47406 47.182211 202.47426 47.182035 202.47429 47.181917 202.47428 47.181746 202.47434 47.181551 202.47434 47.181485 202.47444 47.181482 202.4748 47.181472 202.47502 47.18131 202.47519 47.181119 202.47537 47.181114 202.47572 47.181151 202.47575 47.181158 202.476 47.181298 202.47629 47.18121 202.47655 47.181219 202.47672 47.181417 202.47699 47.18135 202.47722 47.181375 202.47728 47.181527 202.47734 47.181612 202.47744 47.181627 202.47777 47.181617 202.47793 47.181633 202.4782 47.181625 202.47835 47.181601 202.47869 47.181591 202.47881 47.181825 202.47879 47.181876 202.47891 47.182081 202.47896 47.182281 202.47862 47.182365 202.47852 47.182367 202.47816 47.182378 202.47803 47.182598 202.47804 47.182721 202.47822 47.182716 202.47844 47.182554 202.47872 47.182546 202.47899 47.182599 202.47921 47.182437 202.47943 47.182275 202.47933 47.182094 202.47937 47.181936 202.47936 47.18175 202.47931 47.1816 202.47951 47.181635 202.47988 47.181661 202.47995 47.181637 202.47993 47.181687 202.47971 47.181849 202.47972 47.182128 202.47996 47.182282 202.48038 47.18227 202.48031 47.182017 202.48029 47.181911 202.48034 47.181676 202.48031 47.181627 202.48037 47.18165 202.48067 47.181753 202.48085 47.181663 202.48112 47.181537 202.48145 47.181502 202.48156 47.181509 202.48185 47.18153 202.48209 47.181546 202.48228 47.181541 202.48259 47.181636 202.48281 47.1818 202.48299 47.181809 202.48308 47.181598 202.48309 47.181572 202.48318 47.181325 202.48344 47.181335 202.4837 47.181469 202.48382 47.181705 202.48419 47.181658 202.48431 47.181664 202.48455 47.181813 202.4846 47.181913 202.48464 47.182074 202.48489 47.182215 202.4852 47.182289 202.48523 47.182288 202.4855 47.182414 202.48577 47.182345 202.48604 47.182337 202.48617 47.182567 202.4862 47.182616 202.48595 47.182757 202.48591 47.182764 202.48557 47.182687 202.48544 47.182457 202.4851 47.18253 202.48489 47.182542 202.48463 47.182535 202.48444 47.182546 202.48413 47.18252 202.484 47.18274 202.48406 47.182831 202.48425 47.183012 202.48445 47.183194 202.48479 47.18323 202.48501 47.183068 202.48506 47.183067 202.4853 47.183216 202.48563 47.18316 202.48586 47.183122 202.48614 47.183175 202.4862 47.183195 202.48649 47.183307 202.48675 47.18344 202.48681 47.183595 202.48687 47.183681 202.48695 47.183948 202.48697 47.183997 202.48707 47.184178 202.48735 47.184232 202.48742 47.184246 202.48783 47.184234 202.4879 47.184216 202.4882 47.184166 202.48835 47.184212 202.4886 47.184352 202.4886 47.184418 202.48871 47.184599 202.48892 47.184764 202.48905 47.184698 202.48906 47.18466 202.48897 47.184408 202.48896 47.184342 202.48886 47.18416 202.4887 47.183952 202.48839 47.183854 202.48821 47.183664 202.48813 47.183525 202.48835 47.183362 202.48869 47.183275 202.48876 47.183256 202.48897 47.183152 202.4893 47.183055 202.48948 47.183051 202.48946 47.183159 202.48943 47.183416 202.48944 47.183442 202.48955 47.183648 202.48956 47.18382 202.48947 47.184032 202.48976 47.184148 202.49004 47.184263 202.49008 47.184443 202.48996 47.18465 202.48998 47.184682 202.48992 47.184677 202.48968 47.18479 202.48954 47.184957 202.48984 47.185066 202.49015 47.185161 202.49027 47.185158 202.49038 47.184991 202.49037 47.184925 202.49047 47.184922 202.49083 47.184912 202.49093 47.184909 202.49129 47.184899 202.49136 47.184913 202.4917 47.184857 202.49175 47.184623 202.49173 47.184574 202.49156 47.184438 202.49132 47.184291 202.49136 47.184043 202.49141 47.183899 202.49141 47.18378 202.49165 47.183627 202.49155 47.183469 202.4913 47.18333 202.4911 47.183286 202.49095 47.183265 202.49056 47.183246 202.49054 47.183247 202.49021 47.183161 202.49014 47.182984 202.49025 47.182809 202.49005 47.182927 202.48965 47.182926 202.48961 47.182654 202.48968 47.182578 202.4894 47.182457 202.48946 47.182258 202.48954 47.182031 202.48951 47.18199 202.48938 47.181826 202.48925 47.181594 202.48898 47.181663 202.48875 47.181638 202.48869 47.181482 202.48869 47.18136 202.48841 47.181306 202.48834 47.181292 202.48834 47.181259 202.48856 47.181097 202.48854 47.180819 202.48815 47.180782 202.48804 47.180775 202.4877 47.180864 202.48768 47.18113 202.48769 47.181154 202.48777 47.181388 202.48775 47.181492 202.4876 47.181511 202.48725 47.181445 202.48703 47.181342 202.48705 47.181594 202.48727 47.181757 202.48768 47.181745 202.48772 47.181749 202.48773 47.181777 202.48787 47.181965 202.48788 47.182171 202.48754 47.182205 202.48748 47.182217 202.48706 47.182255 202.48702 47.182264 202.48661 47.182276 202.48656 47.182278 202.48622 47.18221 202.4861 47.181971 202.48579 47.181877 202.48573 47.181723 202.48601 47.181715 202.48614 47.18168 202.48634 47.181509 202.48637 47.181446 202.48627 47.181465 202.4859 47.181534 202.48581 47.181536 202.48547 47.181457 202.48531 47.181253 202.48523 47.181114 202.48522 47.180991 202.48502 47.180819 202.48502 47.180683 202.48508 47.18045 202.48507 47.180417 202.48489 47.180258 202.4847 47.180074 202.4847 47.179882 202.48463 47.179803 202.48448 47.179745 202.48433 47.1797 202.48425 47.179603 202.48415 47.179509 202.48392 47.17935 202.48384 47.179348 202.4838 47.17944 202.48381 47.179628 202.48365 47.179826 202.48341 47.179975 202.48308 47.17997 202.48281 47.179848 202.48272 47.179842 202.48244 47.179794 202.48226 47.179603 202.48212 47.179471 202.48208 47.17941 202.48192 47.179342 202.48177 47.179314 202.4815 47.179383 202.48123 47.17939 202.48095 47.179337 202.48086 47.179577 202.48048 47.17964 202.48045 47.179636 202.48016 47.179529 202.47984 47.179539 202.4797 47.179543 202.47936 47.179471 202.4791 47.179336 202.47904 47.179338 202.47867 47.179329 202.47861 47.179067 202.47889 47.178945 202.47886 47.178861 202.47873 47.178844 202.47847 47.178827 202.47813 47.178772 202.478 47.178989 202.4778 47.178995 202.47757 47.179016 202.47726 47.179066 202.47716 47.179059 202.47681 47.179143 202.47659 47.179305 202.47647 47.179526 202.47618 47.179643 202.4759 47.17977 202.47568 47.179932 202.47547 47.1801 202.47524 47.180254 202.4752 47.180263 202.4749 47.180341 202.47467 47.180331 202.47433 47.180282 202.47422 47.180516 202.47393 47.180554 202.47381 47.180557 202.47349 47.180654 202.47338 47.180887 202.47299 47.180941 202.47296 47.180945 202.47254 47.180957 202.47247 47.180981 202.47249 47.18093 202.47248 47.180652 202.47222 47.180514 202.47222 47.18046 202.47218 47.180224 202.47184 47.180145 202.47174 47.180159 202.47145 47.180113 202.47124 47.179941 202.47091 47.179857 202.47073 47.179663 202.47051 47.179504 202.47023 47.179516 202.46993 47.179605 202.46984 47.17957 202.46991 47.17962 202.46986 47.179883 202.46951 47.179965 202.46945 47.179963 202.46943 47.179911 202.46935 47.179712 202.46927 47.179512 202.46965 47.179453 202.46967 47.179163 202.46972 47.179115 202.46962 47.179136 202.4693 47.17923 202.46907 47.179268 202.4691 47.17911 202.46901 47.178983 202.46878 47.178827 202.46862 47.178805 202.46838 47.178958 202.46824 47.179167 202.46825 47.179222 202.46827 47.179484 202.46813 47.179635 202.46811 47.179685 202.46813 47.179963 202.46812 47.179989 202.4679 47.180151 202.46784 47.180177 202.46748 47.180187 202.46738 47.180428 202.46704 47.180511 202.46705 47.180757 202.46706 47.180823 202.46696 47.180825 202.46668 47.180883 202.46649 47.180844 202.46615 47.180771 202.46613 47.18054 202.46616 47.180438 202.46587 47.180332 202.46581 47.180046 202.46625 47.180017 202.46623 47.179739 202.46623 47.179706 202.46611 47.1795 202.46587 47.179483 202.46569 47.179489 202.4657 47.179378 202.46585 47.179171 202.4658 47.17908 202.46578 47.17883 202.46582 47.178737 202.46586 47.178579 202.46582 47.178417 202.46583 47.178262 202.46585 47.178066 202.46582 47.177956 202.46576 47.177809 202.46556 47.177628 202.46535 47.177458 202.46535 47.17736 202.46541 47.1771 202.46558 47.176968 202.46561 47.176923 202.46565 47.176917 202.46595 47.176841 202.4662 47.176834 202.46648 47.17695 202.46673 47.177025 202.4666 47.176865 202.46658 47.176636 202.46692 47.176626 202.46704 47.17686 202.46705 47.176927 202.4668 47.177073 202.46682 47.177351 202.46706 47.1775 202.46706 47.177533 202.46717 47.177739 202.46723 47.177938 202.46721 47.178041 202.46735 47.178017 202.46761 47.177874 202.46755 47.177784 202.46758 47.177556 202.46792 47.177475 202.468 47.177457 202.46821 47.177353 202.46823 47.177287 202.46821 47.177057 202.46824 47.176954 202.46812 47.176998 202.4679 47.17716 202.46753 47.177151 202.46732 47.176978 202.46731 47.176793 202.46751 47.176618 202.46782 47.176609 202.46811 47.176696 202.4683 47.176513 202.46855 47.176372 202.46859 47.176365 202.46862 47.176414 202.46864 47.176659 202.469 47.176649 202.46912 47.176428 202.46929 47.176237 202.46961 47.176134 202.46987 47.176001 202.46986 47.175756 202.46988 47.175706 202.47006 47.175517 202.47025 47.175465 202.4704 47.175431 202.47052 47.17527 202.4703 47.175103 202.47027 47.175054 202.47037 47.175052 202.4706 47.174959 202.47095 47.174949 202.47097 47.175187 202.47085 47.17535 202.47085 47.175416 202.47098 47.175576 202.471 47.175805 202.47097 47.175908 202.47125 47.175962 202.47123 47.175717 202.47123 47.175651 202.47135 47.175632 202.47152 47.175535 202.4718 47.175412 202.4721 47.175403 202.47232 47.175434 202.47255 47.175396 202.47267 47.175358 202.47302 47.175371 202.4733 47.175453 202.47338 47.175434 202.47374 47.175424 202.47386 47.175203 202.47414 47.175195 202.47426 47.175155 202.47431 47.175067 202.4743 47.174879 202.47438 47.174692 202.47417 47.17452 202.47416 47.174493 202.47421 47.174492 202.47447 47.174621 202.47483 47.174611 202.47505 47.174453 202.47513 47.174466 202.47553 47.174454 202.47552 47.174176 202.47511 47.174187 202.47504 47.174204 202.47503 47.17414 202.47502 47.173895 202.47501 47.173829 202.47509 47.173843 202.47537 47.17396 202.47559 47.174124 202.47583 47.174273 202.47619 47.174263 202.47628 47.174262 202.47652 47.174409 202.47653 47.174475 202.47654 47.174721 202.47678 47.17487 202.47676 47.17492 202.47654 47.175082 202.47656 47.17536 202.47697 47.175348 202.47701 47.175347 202.47742 47.175335 202.47746 47.17534 202.4775 47.175383 202.47725 47.175524 202.47738 47.17573 202.47739 47.175911 202.47715 47.176063 202.47694 47.176052 202.47669 47.176071 202.47638 47.176182 202.47633 47.176449 202.47613 47.176624 202.47582 47.176553 202.47561 47.176595 202.47556 47.176745 202.47555 47.176855 202.47564 47.177012 202.47588 47.177066 202.47603 47.177053 202.47637 47.177121 202.47645 47.177119 202.47682 47.177051 202.47706 47.176904 202.4771 47.176909 202.47735 47.177052 202.47769 47.176996 202.47784 47.176791 202.478 47.176591 202.478 47.176567 202.47792 47.176306 202.47791 47.17624 202.47816 47.176094 202.47839 47.175937 202.47845 47.175913 202.47881 47.175903 202.47891 47.1759 202.47923 47.175985 202.47951 47.176039 202.47949 47.175794 202.47926 47.175636 202.47929 47.175603 202.4792 47.175356 202.47921 47.175256 202.47939 47.175067 202.47958 47.175078 202.47965 47.175234 202.47971 47.175304 202.47993 47.175405 202.48002 47.175401 202.48029 47.175332 202.48063 47.175244 202.48068 47.175243 202.48109 47.175231 202.4813 47.175069 202.48129 47.174791 202.48129 47.174758 202.48143 47.174551 202.48149 47.174318 202.48123 47.174186 202.48102 47.174293 202.48067 47.174268 202.48044 47.174119 202.48019 47.173977 202.48029 47.173838 202.48045 47.17378 202.48072 47.173912 202.48092 47.173931 202.4812 47.173808 202.48136 47.173764 202.48168 47.173851 202.48178 47.174104 202.48216 47.174149 202.48238 47.174243 202.48247 47.17424 202.48282 47.174306 202.48307 47.174379 202.48317 47.174376 202.48341 47.174525 202.48377 47.174515 202.48399 47.174353 202.48406 47.174367 202.48447 47.174355 202.48452 47.174354 202.48475 47.174509 202.48476 47.174536 202.48478 47.174814 202.48478 47.174847 202.4848 47.175125 202.48482 47.175174 202.48484 47.175419 202.48481 47.175464 202.48458 47.175622 202.48453 47.17565 202.48429 47.175501 202.48405 47.17559 202.48371 47.175599 202.48356 47.175583 202.48329 47.175591 202.48314 47.175617 202.48277 47.175688 202.48271 47.17569 202.48237 47.175617 202.48213 47.175468 202.48195 47.175473 202.48187 47.17566 202.48211 47.175809 202.48209 47.175859 202.48211 47.176137 202.48251 47.176122 202.48274 47.175963 202.48278 47.175962 202.48312 47.175906 202.48335 47.175868 202.48353 47.175863 202.48375 47.175701 202.48403 47.175693 202.48431 47.17581 202.48446 47.176028 202.48466 47.176204 202.48497 47.176296 202.4849 47.176419 202.48481 47.176659 202.48451 47.176639 202.48435 47.176435 202.48414 47.176263 202.4841 47.17622 202.48396 47.17607 202.48382 47.176044 202.48355 47.176176 202.48325 47.176288 202.48303 47.176447 202.48282 47.176617 202.48283 47.176905 202.48284 47.176928 202.48297 47.177126 202.48317 47.177134 202.48337 47.177159 202.48366 47.177138 202.48389 47.1771 202.48417 47.177217 202.48425 47.177208 202.48448 47.177052 202.48471 47.1769 202.48496 47.176757 202.48528 47.176654 202.48526 47.176409 202.48517 47.17629 202.48535 47.17634 202.48557 47.176506 202.48591 47.17645 202.48608 47.176258 202.48631 47.176283 202.48666 47.176319 202.48683 47.176131 202.48696 47.176128 202.48731 47.176192 202.48755 47.176277 202.48762 47.176292 202.48796 47.176236 202.48819 47.176198 202.48846 47.176251 202.48845 47.176006 202.48823 47.17584 202.48782 47.175815 202.48782 47.175553 202.48823 47.175516 202.48825 47.175519 202.48839 47.175398 202.48845 47.175344 202.48846 47.175343 202.48881 47.175415 202.48907 47.175546 202.48936 47.175658 202.48956 47.175833 202.48957 47.176048 202.48945 47.17624 202.48945 47.176273 202.4894 47.176274 202.489 47.176246 202.48883 47.176181 202.48853 47.176293 202.48834 47.176477 202.48844 47.176662 202.48872 47.176711 202.48878 47.176734 202.48914 47.176797 202.48931 47.176992 202.48966 47.17706 202.48989 47.177146 202.49005 47.176945 202.49031 47.176907 202.49057 47.17697 202.49067 47.176968 202.49093 47.176899 202.49117 47.176923 202.49122 47.177079 202.49127 47.17717 202.49138 47.177415 202.49135 47.177457 202.49129 47.177484 202.49109 47.177593 202.49103 47.177675 202.49099 47.177834 202.49106 47.17798 202.49135 47.178056 202.49142 47.178037 202.49164 47.177939 202.49198 47.177851 202.49217 47.177674 202.4924 47.177636 202.49258 47.177631 202.49266 47.177444 202.49269 47.177399 202.49272 47.177398 202.4931 47.177446 202.49317 47.177397 202.49342 47.177254 202.49382 47.177242 202.49404 47.177405 202.49405 47.17765 202.49385 47.177825 202.49345 47.177836 202.49338 47.177827 202.49299 47.177854 202.49287 47.177811 202.49288 47.177934 202.49307 47.178116 202.49342 47.178152 202.49347 47.178151 202.49349 47.1782 202.4936 47.178381 202.49373 47.178347 202.4941 47.178337 202.49433 47.178422 202.49442 47.178419 202.49478 47.178483 202.49502 47.178557 202.49512 47.178555 202.49548 47.178544 202.49573 47.178403 202.49577 47.178402 202.49601 47.178551 202.49604 47.178595 202.49606 47.17884 202.49639 47.178916 202.49653 47.1789 202.49664 47.178733 202.49664 47.178667 202.49671 47.178682 202.49712 47.17867 202.49716 47.178674 202.49717 47.178702 202.5103 47.187201 202.51027 47.187201 202.50992 47.187139 202.50992 47.186963 202.51016 47.186963 202.5103 47.18718 202.5103 47.187201 202.4979 47.17946 202.49786 47.179461 202.49785 47.179428 202.49789 47.179433 202.4979 47.17946 202.49303 47.176412 202.49273 47.176419 202.49273 47.176228 202.49301 47.176208 202.49303 47.176412 202.47929 47.167824 202.47926 47.167831 202.47927 47.167813 202.47928 47.167813 202.47929 47.167824 202.51627 47.191231 202.51627 47.191232 202.51627 47.191227 202.51627 47.191227 202.51627 47.191231 202.50965 47.187097 202.50949 47.187128 202.50952 47.187017 202.50964 47.187019 202.50965 47.187097 202.5056 47.184563 202.50547 47.184567 202.50542 47.184451 202.50562 47.184462 202.5056 47.184563 202.49752 47.179517 202.49733 47.179523 202.49728 47.179367 202.49751 47.179392 202.49752 47.179517 202.49501 47.17795 202.49462 47.177946 202.49463 47.177712 202.49492 47.17773 202.49501 47.17795 202.51836 47.192834 202.51805 47.192845 202.51803 47.192629 202.51836 47.192616 202.51836 47.192834 202.50924 47.187137 202.50908 47.187109 202.50906 47.187029 202.50919 47.187025 202.50924 47.187137 202.50678 47.185605 202.50669 47.185621 202.5065 47.185436 202.5065 47.18543 202.50652 47.185423 202.5068 47.185539 202.50678 47.185605 202.50344 47.183518 202.50329 47.183722 202.50311 47.18371 202.50311 47.183606 202.50336 47.183464 202.50344 47.183468 202.50344 47.183518 202.4952 47.178368 202.49492 47.178376 202.49496 47.178218 202.49514 47.178212 202.4952 47.178368 202.47925 47.168399 202.47891 47.168417 202.47892 47.168193 202.47923 47.168179 202.47925 47.168399 202.47657 47.166726 202.47635 47.166731 202.47638 47.166605 202.47656 47.166571 202.47657 47.166726 202.50461 47.184544 202.5042 47.184534 202.50415 47.184259 202.50453 47.184292 202.50461 47.184544 202.49574 47.179006 202.49562 47.179164 202.49562 47.17923 202.49572 47.179411 202.49583 47.179361 202.49599 47.179211 202.49599 47.179161 202.49596 47.178908 202.49574 47.179006 202.48953 47.175123 202.4892 47.175125 202.48918 47.174908 202.48954 47.17487 202.48953 47.175123 202.51713 47.192665 202.51698 47.192661 202.51696 47.192557 202.51711 47.192564 202.51713 47.192665 202.51217 47.189567 202.51188 47.189594 202.51188 47.189385 202.51215 47.189393 202.51217 47.189567 202.50943 47.187857 202.50938 47.187859 202.5091 47.187948 202.5091 47.188072 202.50905 47.188217 202.5088 47.188291 202.50852 47.188176 202.50851 47.188175 202.50811 47.188152 202.50802 47.18789 202.50802 47.187873 202.50821 47.187689 202.50834 47.187652 202.50869 47.187725 202.50876 47.187737 202.50907 47.187634 202.50924 47.187643 202.50942 47.187836 202.50943 47.187857 202.50635 47.185935 202.50619 47.185991 202.5059 47.185947 202.50599 47.18614 202.50628 47.186248 202.50622 47.186449 202.50602 47.186622 202.50575 47.186642 202.50554 47.186623 202.50527 47.186754 202.50515 47.186757 202.50519 47.186702 202.50529 47.186465 202.50536 47.186276 202.50508 47.186158 202.50503 47.186003 202.5052 47.185811 202.50516 47.185772 202.50504 47.18554 202.50509 47.185445 202.50516 47.185453 202.50558 47.185462 202.50562 47.185478 202.50591 47.185548 202.50621 47.185653 202.50636 47.185864 202.50635 47.185935 202.50115 47.182681 202.50104 47.182916 202.50063 47.182939 202.50058 47.182656 202.50057 47.182623 202.5006 47.182341 202.50098 47.182355 202.50114 47.182566 202.50115 47.182681 202.49798 47.180705 202.49793 47.180706 202.49793 47.180673 202.49797 47.180677 202.49798 47.180705 202.50397 47.185045 202.50391 47.185071 202.50391 47.185005 202.50397 47.185028 202.50397 47.185045 202.50267 47.184233 202.50244 47.184208 202.50243 47.184082 202.50262 47.184077 202.50267 47.184233 202.50196 47.183786 202.50168 47.183794 202.50167 47.183605 202.5019 47.18363 202.50196 47.183786 202.50124 47.183339 202.50096 47.183347 202.501 47.183188 202.50118 47.183183 202.50124 47.183339 202.4853 47.173378 202.48529 47.173456 202.48529 47.173671 202.48499 47.173679 202.48476 47.173529 202.48479 47.173356 202.48496 47.173167 202.48526 47.173159 202.4853 47.173378 202.47693 47.168146 202.47665 47.168135 202.47648 47.167931 202.47648 47.167864 202.47662 47.167827 202.47689 47.167955 202.47693 47.168146 202.50474 47.185826 202.50465 47.185829 202.50467 47.185779 202.50474 47.18576 202.50474 47.185826 202.48715 47.174834 202.48693 47.17485 202.48664 47.174741 202.48664 47.174514 202.48698 47.174488 202.48714 47.174692 202.48715 47.174834 202.50654 47.187249 202.50624 47.187257 202.50606 47.18706 202.50611 47.186979 202.50617 47.186982 202.50649 47.18707 202.50654 47.187249 202.48232 47.172115 202.48227 47.172114 202.48227 47.172082 202.48232 47.172078 202.48232 47.172115 202.50982 47.189594 202.50965 47.189614 202.50966 47.189493 202.50981 47.1895 202.50982 47.189594 202.50934 47.189292 202.50919 47.189304 202.50917 47.189186 202.50933 47.189201 202.50934 47.189292 202.5044 47.186209 202.50417 47.186185 202.50416 47.186059 202.50439 47.186021 202.5044 47.186209 202.48669 47.175145 202.48651 47.175161 202.48628 47.175004 202.48627 47.174884 202.48645 47.174879 202.48667 47.175043 202.48669 47.175145 202.48542 47.174351 202.4854 47.174351 202.4854 47.174338 202.48543 47.174333 202.48542 47.174351 202.47951 47.170659 202.47939 47.170663 202.47939 47.170582 202.4795 47.170579 202.47951 47.170659 202.51766 47.194788 202.51762 47.194787 202.51761 47.194759 202.51765 47.194763 202.51766 47.194788 202.49025 47.177669 202.49015 47.177672 202.4898 47.177608 202.4897 47.177626 202.48971 47.177672 202.48992 47.177842 202.49008 47.177858 202.49035 47.17785 202.49053 47.177845 202.49048 47.177754 202.49025 47.177669 202.47724 47.169533 202.47692 47.16956 202.47694 47.169351 202.47722 47.169337 202.47724 47.169533 202.47596 47.168738 202.47583 47.168737 202.47581 47.168645 202.47598 47.168627 202.47596 47.168738 202.51889 47.195855 202.5188 47.195867 202.51872 47.195752 202.51889 47.195798 202.51889 47.195855 202.50779 47.188925 202.50749 47.188934 202.50746 47.188718 202.50776 47.188733 202.50779 47.188925 202.50735 47.188652 202.50698 47.188664 202.50699 47.188426 202.50735 47.188388 202.50735 47.188652 202.501 47.184687 202.50093 47.184672 202.50052 47.184684 202.50042 47.184921 202.50046 47.185022 202.50061 47.185038 202.50084 47.184884 202.50113 47.184847 202.50138 47.184922 202.50128 47.18474 202.501 47.184687 202.4858 47.175183 202.48555 47.175219 202.48554 47.175022 202.48579 47.175044 202.4858 47.175183 202.48097 47.172169 202.48084 47.172193 202.48087 47.172104 202.48101 47.172068 202.48097 47.172169 202.50148 47.18528 202.50156 47.18551 202.5019 47.185547 202.50188 47.185268 202.50148 47.18528 202.48752 47.176561 202.48753 47.176684 202.48768 47.176897 202.48788 47.176788 202.48794 47.176705 202.48779 47.176492 202.48752 47.176561 202.48588 47.175535 202.48561 47.175502 202.48557 47.175343 202.48579 47.175366 202.48588 47.175535 202.47943 47.171503 202.47907 47.171551 202.47904 47.171258 202.47946 47.171264 202.47943 47.171503 202.51161 47.191907 202.5115 47.192137 202.5111 47.192124 202.51108 47.191879 202.51141 47.191787 202.51155 47.19179 202.51161 47.191907 202.48599 47.175904 202.48592 47.17616 202.48558 47.17617 202.48561 47.175968 202.48594 47.175872 202.48599 47.175871 202.48599 47.175904 202.48426 47.174824 202.48426 47.174867 202.48448 47.174962 202.48447 47.174717 202.48426 47.174824 202.482 47.173411 202.48183 47.173416 202.48159 47.173264 202.48161 47.173167 202.48176 47.173137 202.482 47.17329 202.482 47.173411 202.48097 47.172764 202.48094 47.172769 202.48093 47.172742 202.48105 47.172689 202.48097 47.172764 202.48051 47.172475 202.48039 47.172705 202.4801 47.172742 202.48008 47.172511 202.48046 47.172449 202.4805 47.172448 202.48051 47.172475 202.48008 47.172207 202.47993 47.172417 202.47965 47.172425 202.47971 47.172275 202.47986 47.172071 202.48015 47.172057 202.48008 47.172207 202.5076 47.189703 202.50732 47.18971 202.50736 47.189552 202.50754 47.189547 202.5076 47.189703 202.50699 47.189321 202.50697 47.189322 202.50695 47.189299 202.50698 47.189309 202.50699 47.189321 202.48209 47.173765 202.48175 47.173798 202.48177 47.173567 202.48208 47.173558 202.48209 47.173765 202.4803 47.172948 202.48043 47.173148 202.48044 47.173332 202.48017 47.17334 202.48 47.173137 202.48 47.173056 202.48026 47.172918 202.48029 47.172925 202.4803 47.172948 202.51348 47.19397 202.51344 47.193973 202.51343 47.193945 202.51348 47.193943 202.51348 47.19397 202.48258 47.17467 202.48228 47.174707 202.48218 47.174716 202.48205 47.174875 202.48241 47.174865 202.48249 47.17488 202.48283 47.174823 202.48288 47.17459 202.48258 47.17467 202.47811 47.171878 202.47772 47.171897 202.47772 47.171629 202.47811 47.171609 202.47811 47.171878 202.51124 47.192871 202.51094 47.192896 202.51095 47.19269 202.51122 47.192682 202.51124 47.192871 202.50778 47.190715 202.50772 47.190716 202.50769 47.190656 202.5078 47.190655 202.50778 47.190715 202.47954 47.173069 202.47943 47.173236 202.47941 47.173286 202.47919 47.173448 202.47921 47.173726 202.47956 47.173794 202.47955 47.173972 202.4794 47.17418 202.4792 47.174349 202.47883 47.174422 202.4787 47.174426 202.47842 47.174308 202.47829 47.174083 202.47862 47.173991 202.47887 47.173975 202.47901 47.173933 202.47916 47.173758 202.47893 47.173603 202.47889 47.173563 202.47879 47.173381 202.47878 47.173193 202.47874 47.173095 202.47848 47.172965 202.47849 47.17271 202.47883 47.1727 202.47904 47.172877 202.47923 47.172876 202.47953 47.172839 202.47954 47.173069 202.48253 47.17524 202.48264 47.175421 202.48278 47.175395 202.48281 47.175293 202.48253 47.17524 202.47988 47.173578 202.47983 47.17359 202.47983 47.173548 202.47992 47.173526 202.47988 47.173578 202.47757 47.172136 202.47746 47.172368 202.47741 47.172455 202.47773 47.172543 202.47766 47.17279 202.4777 47.172891 202.47794 47.172966 202.47804 47.172964 202.47828 47.173113 202.47828 47.173179 202.4783 47.173424 202.47827 47.173474 202.47823 47.173475 202.47799 47.173326 202.47758 47.173338 202.47748 47.173575 202.4774 47.173761 202.47772 47.173846 202.478 47.173964 202.47798 47.174188 202.47763 47.174242 202.47759 47.174243 202.47722 47.174308 202.47705 47.174342 202.47686 47.174161 202.47662 47.17401 202.47664 47.173951 202.47663 47.173677 202.47663 47.173643 202.47668 47.173642 202.47709 47.17363 202.47707 47.173352 202.47666 47.173364 202.47661 47.173365 202.47631 47.173441 202.47599 47.173539 202.47594 47.17354 202.47591 47.173492 202.47601 47.173253 202.47614 47.173066 202.47614 47.173035 202.47609 47.172773 202.47573 47.172783 202.47567 47.172763 202.47567 47.172741 202.47561 47.172478 202.4756 47.172402 202.47582 47.17224 202.47595 47.172229 202.47627 47.172318 202.47655 47.172436 202.4766 47.172428 202.47681 47.172258 202.47704 47.172101 202.47712 47.172014 202.47693 47.171828 202.47694 47.171743 202.47713 47.171681 202.47729 47.171887 202.47756 47.172014 202.47757 47.172136 202.47323 47.169424 202.47314 47.169424 202.47281 47.169344 202.47288 47.169202 202.47313 47.169112 202.47323 47.169364 202.47323 47.169424 202.5065 47.190513 202.50654 47.190615 202.50678 47.190689 202.50677 47.190444 202.5065 47.190513 202.47355 47.169923 202.47334 47.169929 202.47323 47.169723 202.47354 47.16978 202.47355 47.169923 202.51439 47.195736 202.51411 47.195753 202.51398 47.195525 202.51397 47.195477 202.51404 47.19548 202.51437 47.195567 202.51439 47.195736 202.51071 47.19344 202.51064 47.193442 202.51063 47.193392 202.51069 47.193404 202.51071 47.19344 202.47263 47.169645 202.47237 47.16967 202.47244 47.169528 202.47264 47.169472 202.47263 47.169645 202.51254 47.19488 202.5123 47.195029 202.512 47.195037 202.51197 47.194827 202.51215 47.19464 202.51252 47.194652 202.51254 47.19488 202.51153 47.194252 202.51122 47.19431 202.51127 47.194086 202.5115 47.194107 202.51153 47.194252 202.51041 47.193549 202.51002 47.193607 202.50995 47.193626 202.50968 47.193697 202.50944 47.193843 202.50918 47.193867 202.50913 47.19365 202.50939 47.193513 202.50973 47.193427 202.50978 47.193425 202.51006 47.193334 202.51039 47.193299 202.51041 47.193549 202.4735 47.17049 202.47345 47.170498 202.47334 47.170389 202.47351 47.170455 202.4735 47.17049 202.51725 47.198123 202.517 47.198177 202.51701 47.19797 202.51728 47.197967 202.51725 47.198123 202.51172 47.194669 202.51161 47.194672 202.51161 47.1946 202.51173 47.194585 202.51172 47.194669 202.49931 47.186917 202.49919 47.187144 202.49896 47.1873 202.49903 47.187382 202.49915 47.187418 202.4995 47.187339 202.49952 47.187049 202.49955 47.186992 202.49931 47.186917 202.51409 47.196446 202.51403 47.196463 202.51406 47.196428 202.51408 47.196427 202.51409 47.196446 202.49775 47.186244 202.49757 47.186429 202.49722 47.186436 202.49701 47.186272 202.49679 47.18624 202.49673 47.186474 202.49676 47.186523 202.49678 47.186768 202.49677 47.18683 202.49687 47.187021 202.49698 47.186959 202.49739 47.186968 202.49747 47.187232 202.49781 47.187176 202.49786 47.186942 202.49747 47.186906 202.49743 47.186643 202.49765 47.186477 202.49791 47.186342 202.49789 47.186271 202.49775 47.186244 202.48206 47.176436 202.48179 47.176569 202.48148 47.176672 202.48162 47.176822 202.48176 47.176849 202.48198 47.176686 202.48226 47.176678 202.48253 47.176732 202.48251 47.176487 202.48216 47.176421 202.48206 47.176436 202.4738 47.171273 202.47376 47.171548 202.47349 47.171682 202.47327 47.171844 202.47321 47.171976 202.47315 47.172065 202.47297 47.17225 202.47294 47.172502 202.47294 47.172535 202.47296 47.172813 202.47335 47.172852 202.47338 47.173105 202.47296 47.173137 202.47292 47.172841 202.47253 47.172877 202.47243 47.17288 202.47204 47.172866 202.47201 47.172867 202.47162 47.172826 202.47152 47.172575 202.47128 47.17243 202.47097 47.172334 202.47081 47.172128 202.4708 47.172095 202.47093 47.171875 202.47116 47.171869 202.47148 47.17192 202.47146 47.171641 202.47133 47.171523 202.47158 47.171555 202.47173 47.171474 202.47198 47.171335 202.47229 47.171353 202.4726 47.17142 202.47249 47.171207 202.47251 47.171066 202.47269 47.171061 202.47286 47.171258 202.47328 47.171246 202.47323 47.170984 202.47325 47.170934 202.4733 47.170937 202.47352 47.171095 202.4738 47.171215 202.4738 47.171273 202.51279 47.195934 202.51253 47.195951 202.51236 47.19575 202.51234 47.195652 202.51248 47.195657 202.51278 47.195764 202.51279 47.195934 202.50082 47.188462 202.50064 47.188468 202.50042 47.188511 202.50047 47.188594 202.5007 47.188745 202.50079 47.188743 202.50103 47.188592 202.50103 47.188507 202.50082 47.188462 202.49959 47.187689 202.49934 47.187835 202.49947 47.188033 202.49962 47.188009 202.4998 47.187822 202.49979 47.187798 202.49959 47.187689 202.51606 47.198274 202.51599 47.198272 202.51599 47.19823 202.51605 47.198228 202.51606 47.198274 202.51394 47.196953 202.51379 47.196973 202.51379 47.19686 202.51394 47.196855 202.51394 47.196953 202.50961 47.194546 202.50958 47.194547 202.50958 47.194528 202.50962 47.194521 202.50961 47.194546 202.49569 47.185856 202.4954 47.185836 202.49519 47.185841 202.49494 47.185849 202.49473 47.185675 202.49446 47.185554 202.49414 47.185466 202.49411 47.185462 202.49369 47.185503 202.49377 47.185733 202.49399 47.185898 202.494 47.185992 202.49379 47.186046 202.49355 47.185897 202.4934 47.185921 202.49341 47.186003 202.49362 47.186173 202.49363 47.186362 202.49332 47.186465 202.49326 47.186441 202.49301 47.186296 202.49277 47.186147 202.49242 47.186085 202.49225 47.186097 202.49203 47.186045 202.49194 47.185903 202.49203 47.185723 202.49205 47.185673 202.49203 47.185395 202.492 47.185346 202.49186 47.185196 202.49172 47.185168 202.49175 47.185277 202.49172 47.185466 202.4917 47.185642 202.49175 47.185786 202.49157 47.185736 202.49121 47.185677 202.4911 47.185675 202.49075 47.185759 202.49068 47.185745 202.49065 47.185696 202.49052 47.185536 202.49037 47.18552 202.49014 47.185674 202.49005 47.185886 202.49029 47.186035 202.49069 47.186023 202.49077 47.186004 202.49098 47.186171 202.49098 47.186204 202.491 47.186482 202.49135 47.18655 202.49148 47.18678 202.49151 47.186829 202.49152 47.187074 202.49188 47.187064 202.49198 47.186823 202.492 47.18672 202.49206 47.186577 202.49218 47.186589 202.49244 47.186722 202.49277 47.186801 202.49294 47.187004 202.49313 47.187186 202.49349 47.187169 202.49348 47.186926 202.4935 47.186878 202.49357 47.186859 202.49379 47.187025 202.49419 47.187055 202.49429 47.187307 202.4945 47.187473 202.49491 47.187461 202.49483 47.187231 202.49477 47.187075 202.49471 47.186992 202.49449 47.186899 202.49442 47.186885 202.4941 47.18679 202.49403 47.186609 202.49404 47.186513 202.49403 47.186311 202.49426 47.186352 202.49462 47.186384 202.49469 47.18636 202.49505 47.18635 202.49512 47.186364 202.49512 47.186397 202.49521 47.186627 202.49555 47.186664 202.4956 47.186662 202.49584 47.186811 202.49614 47.186733 202.49616 47.18657 202.49611 47.186414 202.49642 47.18631 202.49627 47.186167 202.49604 47.186012 202.49579 47.185872 202.49569 47.185856 202.48623 47.179944 202.48609 47.180154 202.48613 47.180319 202.48619 47.180515 202.48585 47.180525 202.48577 47.180555 202.48571 47.180632 202.48572 47.180821 202.48578 47.180908 202.48588 47.180919 202.48621 47.180909 202.48634 47.180906 202.48667 47.180896 202.48682 47.180909 202.48706 47.180933 202.48729 47.180907 202.48727 47.180783 202.48697 47.180707 202.4869 47.180726 202.48659 47.180629 202.4863 47.180524 202.48632 47.180299 202.48653 47.180131 202.48658 47.179992 202.48623 47.179944 202.51239 47.196585 202.5121 47.196594 202.51208 47.196392 202.51238 47.196383 202.51239 47.196585 202.49186 47.183763 202.49194 47.183834 202.49202 47.183861 202.492 47.18379 202.49186 47.183763 202.48888 47.181899 202.48884 47.181895 202.48883 47.181868 202.4889 47.181849 202.48888 47.181899 202.48855 47.181689 202.48823 47.181698 202.48822 47.181483 202.48856 47.18145 202.48855 47.181689 202.47844 47.175372 202.4783 47.175376 202.47829 47.175278 202.47846 47.175258 202.47844 47.175372 202.47779 47.174964 202.47752 47.174972 202.47722 47.174869 202.4772 47.1746 202.47757 47.174609 202.47778 47.174784 202.47779 47.174964 202.47559 47.173591 202.47542 47.173595 202.47524 47.173404 202.47525 47.173377 202.47529 47.17337 202.47563 47.173445 202.47559 47.173591 202.47414 47.172684 202.47402 47.172678 202.474 47.172595 202.47413 47.172596 202.47414 47.172684 202.4719 47.171284 202.47153 47.171264 202.47154 47.171057 202.47184 47.171038 202.4719 47.171284 202.48993 47.183155 202.48978 47.183157 202.48974 47.183035 202.48999 47.183001 202.48993 47.183155 202.51144 47.196889 202.51128 47.196875 202.51126 47.196773 202.51143 47.196758 202.51144 47.196889 202.49565 47.187022 202.49555 47.187263 202.49521 47.187346 202.49522 47.187592 202.49546 47.187741 202.4957 47.187652 202.49595 47.187509 202.49591 47.187408 202.4959 47.187179 202.49587 47.187114 202.49565 47.187022 202.49084 47.184022 202.49073 47.184248 202.49048 47.184267 202.4905 47.184104 202.49081 47.184 202.49084 47.183997 202.49084 47.184022 202.48455 47.180088 202.48461 47.180147 202.48457 47.1804 202.48426 47.180401 202.48411 47.180413 202.4839 47.180581 202.48354 47.180606 202.48356 47.180368 202.48356 47.180272 202.4835 47.180029 202.48388 47.180035 202.48408 47.180092 202.48431 47.179941 202.48453 47.179877 202.48455 47.180088 202.48314 47.179211 202.4831 47.179304 202.48338 47.179357 202.48323 47.179212 202.48314 47.179211 202.47863 47.17639 202.47849 47.176535 202.47872 47.176447 202.47875 47.176344 202.47863 47.17639 202.47589 47.174677 202.47571 47.174862 202.47539 47.174959 202.47547 47.175189 202.47552 47.175345 202.47556 47.175446 202.47571 47.175462 202.47579 47.175276 202.47581 47.175225 202.47603 47.175063 202.47625 47.174901 202.47623 47.174623 202.47589 47.174677 202.47403 47.173513 202.47381 47.173488 202.47375 47.17334 202.47395 47.173381 202.47403 47.173513 202.51201 47.197543 202.51167 47.197631 202.51157 47.197634 202.51159 47.197579 202.51164 47.197309 202.51198 47.197333 202.51201 47.197543 202.49624 47.18769 202.49627 47.187791 202.49652 47.187866 202.49636 47.187723 202.49624 47.18769 202.48994 47.183756 202.4898 47.183792 202.48979 47.183663 202.48994 47.183684 202.48994 47.183756 202.4748 47.174292 202.4745 47.174274 202.47445 47.174075 202.47479 47.174065 202.4748 47.174292 202.47073 47.171747 202.47043 47.171756 202.47021 47.171722 202.46998 47.171759 202.46983 47.171549 202.46986 47.171502 202.46998 47.171439 202.47014 47.171377 202.47051 47.17137 202.47071 47.171545 202.47073 47.171747 202.49268 47.185766 202.49268 47.185888 202.49286 47.185883 202.49281 47.185793 202.49268 47.185766 202.48792 47.182792 202.48757 47.182873 202.48748 47.182905 202.48752 47.18284 202.48764 47.182616 202.48791 47.182588 202.48792 47.182792 202.47756 47.176316 202.47746 47.176319 202.47748 47.176269 202.47755 47.17625 202.47756 47.176316 202.51208 47.198186 202.51169 47.198198 202.51167 47.197929 202.51204 47.197938 202.51208 47.198186 202.48807 47.183186 202.488 47.183441 202.48774 47.183582 202.48737 47.183648 202.48735 47.183649 202.48735 47.183636 202.48742 47.183376 202.48754 47.183185 202.48751 47.183136 202.48758 47.183156 202.488 47.183144 202.48807 47.18312 202.48807 47.183186 202.47309 47.17382 202.47291 47.173825 202.47292 47.173717 202.47309 47.173692 202.47309 47.17382 202.47243 47.173412 202.47211 47.17344 202.47216 47.173239 202.47242 47.173212 202.47243 47.173412 202.49474 47.187655 202.4949 47.187833 202.49494 47.188078 202.49474 47.188249 202.49471 47.188293 202.49494 47.188379 202.49516 47.188217 202.49515 47.187972 202.49517 47.187921 202.49515 47.187643 202.49474 47.187655 202.47013 47.172268 202.46972 47.172314 202.46965 47.172571 202.46931 47.17258 202.46919 47.172346 202.46923 47.172305 202.46926 47.172294 202.46967 47.172283 202.46967 47.17199 202.46967 47.171987 202.46968 47.171982 202.4701 47.172002 202.47013 47.172268 202.5139 47.199915 202.51377 47.199914 202.51378 47.199844 202.51386 47.199848 202.5139 47.199915 202.50228 47.192661 202.50231 47.192762 202.50243 47.192758 202.50241 47.192694 202.50228 47.192661 202.49359 47.187234 202.49348 47.187463 202.49337 47.187661 202.49367 47.187583 202.49396 47.187546 202.49421 47.187621 202.49419 47.187375 202.49381 47.187337 202.49359 47.187234 202.4709 47.173055 202.47086 47.173061 202.47086 47.173028 202.47093 47.17301 202.4709 47.173055 202.49576 47.188889 202.49591 47.189039 202.4961 47.18922 202.49633 47.189377 202.49649 47.189581 202.4965 47.189647 202.49663 47.189807 202.49687 47.189882 202.49695 47.189897 202.49736 47.189885 202.49724 47.189679 202.4971 47.189458 202.49672 47.189411 202.49648 47.189263 202.49625 47.189113 202.49612 47.188879 202.49576 47.188889 202.48185 47.180198 202.48156 47.180121 202.48145 47.179949 202.48174 47.179985 202.48185 47.180198 202.51319 47.200374 202.51312 47.200393 202.51312 47.200327 202.51319 47.200341 202.51319 47.200374 202.48878 47.185126 202.48866 47.185285 202.48887 47.185452 202.48921 47.185396 202.4892 47.185208 202.48884 47.185149 202.48878 47.185126 202.48797 47.184622 202.48788 47.184863 202.48789 47.184878 202.48786 47.185151 202.48778 47.18528 202.48802 47.185429 202.48837 47.185466 202.48835 47.185188 202.48835 47.185155 202.4884 47.184891 202.48844 47.184796 202.48821 47.184638 202.48797 47.184622 202.47287 47.175182 202.47282 47.175196 202.47283 47.175159 202.47286 47.175162 202.47287 47.175182 202.47119 47.174131 202.47118 47.17413 202.47118 47.174123 202.47119 47.174122 202.47119 47.174131 202.49173 47.187268 202.4918 47.187519 202.4921 47.187619 202.49238 47.187673 202.49223 47.187522 202.49215 47.187256 202.49173 47.187268 202.49081 47.186693 202.49091 47.186874 202.49109 47.186869 202.49108 47.186746 202.49081 47.186693 202.49014 47.186274 202.49009 47.186508 202.49035 47.18664 202.49071 47.18663 202.49069 47.186384 202.49048 47.186218 202.49014 47.186274 202.47498 47.176799 202.47477 47.176966 202.47474 47.177028 202.47486 47.177024 202.47512 47.176887 202.47519 47.176692 202.47498 47.176799 202.50672 47.196928 202.50673 47.196982 202.50682 47.196993 202.5068 47.196932 202.50672 47.196928 202.48658 47.18435 202.48629 47.184467 202.48631 47.184746 202.48661 47.184667 202.48694 47.184572 202.48685 47.184342 202.48658 47.18435 202.47079 47.174482 202.4707 47.174485 202.47072 47.174435 202.47076 47.174442 202.47079 47.174482 202.50984 47.199176 202.50984 47.199242 202.50992 47.199229 202.51006 47.199078 202.50984 47.199176 202.48581 47.184169 202.48583 47.184447 202.48624 47.184436 202.4861 47.184245 202.48581 47.184169 202.47091 47.174854 202.47063 47.174862 202.47062 47.17467 202.4709 47.174662 202.47091 47.174854 202.50643 47.197348 202.5062 47.197504 202.50621 47.197689 202.50638 47.197893 202.50641 47.197936 202.50629 47.198156 202.5063 47.198279 202.50657 47.198333 202.50679 47.19817 202.50688 47.19793 202.50689 47.19784 202.50697 47.197682 202.50693 47.197482 202.50668 47.197345 202.50643 47.197348 202.49096 47.187685 202.49068 47.187693 202.49067 47.187504 202.49095 47.187496 202.49096 47.187685 202.49682 47.191642 202.49663 47.191826 202.49653 47.191828 202.49653 47.191762 202.49677 47.191616 202.49682 47.19162 202.49682 47.191642 202.49135 47.188226 202.4913 47.18821 202.49129 47.188192 202.49135 47.188178 202.49135 47.188226 202.48564 47.184658 202.4858 47.184798 202.48601 47.184893 202.486 47.184648 202.48564 47.184658 202.48382 47.183525 202.48349 47.183612 202.48341 47.183631 202.48305 47.183641 202.48299 47.183621 202.48256 47.183633 202.4825 47.183657 202.48214 47.183667 202.48204 47.18367 202.48169 47.183606 202.48158 47.183619 202.48119 47.183672 202.481 47.183855 202.48091 47.184096 202.4808 47.184263 202.48102 47.184164 202.48128 47.184031 202.48156 47.184024 202.48174 47.184018 202.48193 47.183837 202.48227 47.183827 202.48244 47.184024 202.48279 47.184072 202.483 47.18391 202.48307 47.183886 202.48343 47.183876 202.4835 47.18389 202.48391 47.183879 202.48398 47.18386 202.48425 47.183791 202.48433 47.183605 202.484 47.183519 202.48382 47.183525 202.50713 47.198383 202.50703 47.198385 202.50667 47.198396 202.50666 47.198659 202.50689 47.198813 202.50727 47.198766 202.50751 47.198617 202.50732 47.198497 202.50713 47.198383 202.4972 47.192182 202.49699 47.192141 202.49691 47.192002 202.49715 47.192027 202.4972 47.192182 202.49268 47.189358 202.49239 47.189475 202.49223 47.189479 202.49192 47.189379 202.49191 47.189176 202.49223 47.189153 202.49235 47.189149 202.49267 47.189154 202.49268 47.189358 202.49053 47.188016 202.49023 47.188025 202.49025 47.187838 202.49055 47.187788 202.49053 47.188016 202.48706 47.185848 202.48689 47.18604 202.48673 47.18606 202.48667 47.185904 202.48701 47.185816 202.48693 47.185587 202.48659 47.18555 202.48651 47.185569 202.48654 47.185524 202.48648 47.185272 202.48617 47.185175 202.48599 47.18518 202.486 47.185297 202.48596 47.185458 202.48578 47.185464 202.4855 47.185339 202.4853 47.185345 202.48497 47.18544 202.48475 47.185602 202.48477 47.18588 202.48508 47.185804 202.48527 47.185623 202.48557 47.185615 202.48583 47.185752 202.48584 47.185981 202.48573 47.186148 202.48573 47.186214 202.48549 47.186361 202.48551 47.186639 202.48592 47.186627 202.48599 47.186608 202.48625 47.186539 202.48649 47.186564 202.48683 47.186601 202.48688 47.186599 202.48729 47.186588 202.48752 47.186434 202.48758 47.186407 202.4878 47.186309 202.48781 47.186237 202.48755 47.186105 202.48735 47.185923 202.48706 47.185848 202.48432 47.184134 202.48436 47.184235 202.48446 47.184222 202.4845 47.184129 202.48432 47.184134 202.49474 47.190945 202.49467 47.19093 202.49467 47.190897 202.49474 47.190878 202.49474 47.190945 202.50333 47.196605 202.50328 47.196606 202.50325 47.196557 202.50332 47.196572 202.50333 47.196605 202.49242 47.189794 202.49224 47.189799 202.49223 47.189673 202.49241 47.189668 202.49242 47.189794 202.48622 47.185922 202.48603 47.185928 202.48602 47.185795 202.48622 47.185789 202.48622 47.185922 202.48367 47.184329 202.48365 47.184432 202.4838 47.184407 202.48382 47.184304 202.48367 47.184329 202.4694 47.175405 202.46902 47.175398 202.46903 47.175174 202.46936 47.17515 202.4694 47.175405 202.50083 47.195347 202.50057 47.195354 202.50055 47.195173 202.50078 47.195198 202.50083 47.195347 202.49983 47.194723 202.49965 47.194728 202.49965 47.194607 202.49979 47.194627 202.49983 47.194723 202.49535 47.191924 202.49507 47.191932 202.49489 47.191937 202.49493 47.192038 202.49518 47.192113 202.49527 47.19211 202.49563 47.1921 202.49562 47.191855 202.49535 47.191924 202.4688 47.175332 202.46867 47.175336 202.46866 47.175241 202.46878 47.175252 202.4688 47.175332 202.50464 47.198024 202.50446 47.198012 202.50414 47.19801 202.50401 47.198013 202.50367 47.197946 202.50361 47.197683 202.50404 47.197671 202.50424 47.197776 202.50434 47.197771 202.50461 47.197901 202.50464 47.198024 202.50028 47.195304 202.50021 47.195291 202.50021 47.195258 202.50028 47.19524 202.50028 47.195304 202.49909 47.194561 202.499 47.194563 202.49902 47.194513 202.49909 47.194495 202.49909 47.194561 202.49795 47.193844 202.49776 47.193849 202.49775 47.193724 202.49795 47.193707 202.49795 47.193844 202.48085 47.183162 202.48051 47.183172 202.48036 47.183156 202.48015 47.183114 202.47982 47.183036 202.47966 47.18302 202.47939 47.183028 202.47911 47.182974 202.47913 47.183219 202.47949 47.183209 202.47959 47.183206 202.47956 47.183256 202.47958 47.183534 202.47999 47.183523 202.48003 47.183527 202.48035 47.183446 202.48064 47.183332 202.48074 47.183329 202.48098 47.183244 202.481 47.183137 202.48085 47.183162 202.4754 47.179753 202.47516 47.179905 202.47512 47.179999 202.4754 47.180052 202.47562 47.17989 202.47549 47.17973 202.4754 47.179753 202.47395 47.178849 202.47356 47.178907 202.47335 47.179069 202.47312 47.179226 202.47293 47.179409 202.47283 47.179412 202.47264 47.179527 202.47241 47.179679 202.47231 47.179801 202.47231 47.17992 202.47233 47.180109 202.47255 47.180066 202.47288 47.180032 202.47296 47.180023 202.47328 47.179927 202.47327 47.179741 202.47321 47.179585 202.47351 47.179468 202.4737 47.179291 202.47392 47.179129 202.47409 47.178937 202.47405 47.178836 202.47395 47.178849 202.46919 47.175871 202.46887 47.175832 202.46873 47.175615 202.46873 47.175582 202.46877 47.175581 202.46914 47.175634 202.46919 47.175871 202.50791 47.200364 202.50787 47.200371 202.50784 47.200322 202.50792 47.200337 202.50791 47.200364 202.50028 47.195601 202.50043 47.195779 202.50042 47.19599 202.50009 47.196035 202.49985 47.195882 202.49982 47.195611 202.50023 47.195569 202.5003 47.195553 202.50028 47.195601 202.49975 47.195267 202.49952 47.195423 202.49917 47.19541 202.49916 47.1952 202.49928 47.195006 202.49925 47.194958 202.49932 47.194972 202.49974 47.194987 202.49975 47.195267 202.49386 47.191593 202.49377 47.191596 202.49353 47.191447 202.49353 47.191383 202.49362 47.191378 202.49386 47.191527 202.49386 47.191593 202.4931 47.191118 202.49305 47.191385 202.49272 47.191394 202.49275 47.191196 202.49309 47.191112 202.4931 47.191112 202.4931 47.191118 202.49072 47.189628 202.49083 47.189863 202.49084 47.190001 202.49077 47.190235 202.4908 47.190278 202.4907 47.190281 202.49047 47.190132 202.49023 47.189982 202.49002 47.18981 202.48998 47.189767 202.49008 47.189765 202.49028 47.189652 202.49069 47.189609 202.49073 47.189608 202.49072 47.189628 202.48504 47.186078 202.48505 47.186323 202.48541 47.186313 202.4854 47.186068 202.48504 47.186078 202.50629 47.199654 202.50644 47.199802 202.50653 47.1998 202.50654 47.199728 202.50629 47.199654 202.49768 47.194273 202.49763 47.194269 202.49721 47.194281 202.49718 47.194282 202.49717 47.194254 202.49739 47.194098 202.49743 47.194091 202.49767 47.19424 202.49768 47.194273 202.4967 47.193666 202.49669 47.193669 202.49668 47.193654 202.49671 47.193653 202.4967 47.193666 202.50806 47.201059 202.50779 47.201078 202.50774 47.200857 202.50807 47.200874 202.50806 47.201059 202.50382 47.198412 202.50344 47.198441 202.50345 47.198182 202.50382 47.198158 202.50382 47.198412 202.50127 47.196814 202.50107 47.19699 202.50099 47.196992 202.50075 47.197093 202.5004 47.197103 202.50043 47.196891 202.50069 47.196757 202.50088 47.196751 202.50122 47.196788 202.50127 47.196787 202.50127 47.196814 202.49579 47.193392 202.49574 47.193393 202.49571 47.193344 202.49578 47.193359 202.49579 47.193392 202.50561 47.199829 202.50555 47.199806 202.50554 47.199781 202.50559 47.19978 202.50561 47.199829 202.50237 47.197805 202.5024 47.197903 202.50242 47.198132 202.50207 47.198216 202.50209 47.198461 202.50241 47.198546 202.50265 47.198695 202.50293 47.198749 202.503 47.198763 202.50323 47.198921 202.50324 47.198945 202.50332 47.199175 202.5035 47.199372 202.5035 47.199405 202.50358 47.199635 202.50359 47.199761 202.50363 47.199922 202.50394 47.199983 202.50418 47.199832 202.5042 47.199832 202.50421 47.199851 202.50402 47.20003 202.50404 47.200276 202.50401 47.200326 202.50403 47.200604 202.50403 47.200637 202.50419 47.20081 202.50424 47.201062 202.50409 47.201209 202.5043 47.201381 202.50457 47.201507 202.50488 47.201465 202.50504 47.201488 202.50508 47.201592 202.50492 47.20179 202.50466 47.201767 202.5044 47.201764 202.50435 47.201998 202.50476 47.201986 202.50483 47.201967 202.5048 47.202012 202.50461 47.202195 202.50463 47.202441 202.50461 47.202491 202.50463 47.202769 202.50465 47.202818 202.50453 47.203039 202.50454 47.203161 202.50472 47.203156 202.50499 47.203148 202.505 47.203337 202.50493 47.203523 202.50529 47.203513 202.50538 47.203272 202.5054 47.203169 202.50539 47.202981 202.50547 47.202794 202.5055 47.202749 202.50569 47.202566 202.50567 47.202321 202.50546 47.202149 202.50543 47.202106 202.50532 47.201927 202.50531 47.201734 202.5056 47.201726 202.50574 47.201703 202.50574 47.201622 202.50572 47.201392 202.5057 47.201321 202.50573 47.201095 202.50597 47.200946 202.50606 47.200735 202.50605 47.200702 202.50617 47.200474 202.50642 47.200464 202.50643 47.20064 202.50645 47.200768 202.50669 47.200917 202.5067 47.201106 202.50673 47.20121 202.50665 47.201371 202.50651 47.201583 202.5064 47.201783 202.50643 47.201832 202.50644 47.202077 202.50665 47.202249 202.50665 47.202268 202.50659 47.202295 202.50637 47.202129 202.50609 47.20222 202.50598 47.202418 202.50633 47.202486 202.50648 47.202462 202.50673 47.202512 202.50701 47.202634 202.50728 47.202662 202.50726 47.202445 202.50727 47.20236 202.50722 47.202154 202.50719 47.202011 202.50718 47.201854 202.50687 47.201759 202.50686 47.201507 202.50724 47.201484 202.50749 47.201601 202.50753 47.2016 202.50756 47.201643 202.50758 47.201888 202.50787 47.202 202.50803 47.202204 202.50834 47.202304 202.50834 47.20243 202.50839 47.202591 202.50853 47.202813 202.50876 47.202968 202.50876 47.202987 202.50873 47.203267 202.50873 47.203315 202.50883 47.203568 202.50919 47.203623 202.50931 47.203865 202.50927 47.203904 202.50915 47.204132 202.50903 47.204351 202.50875 47.204479 202.50852 47.204632 202.50828 47.204786 202.50802 47.20492 202.50781 47.205087 202.50763 47.205274 202.50739 47.205422 202.50707 47.205525 202.50685 47.205688 202.50675 47.20592 202.50652 47.206074 202.50625 47.206211 202.50606 47.206391 202.5058 47.206524 202.50554 47.206661 202.50548 47.20669 202.50511 47.206693 202.50504 47.206695 202.50476 47.206773 202.50477 47.206895 202.50478 47.207084 202.50482 47.207185 202.50471 47.207338 202.50444 47.207473 202.50439 47.207501 202.50403 47.207512 202.50404 47.207757 202.504 47.207795 202.50384 47.207994 202.5037 47.208206 202.5034 47.208319 202.50315 47.208462 202.50303 47.208505 202.50302 47.208379 202.50298 47.208218 202.50284 47.207997 202.50243 47.208008 202.50236 47.208027 202.50235 47.207961 202.50225 47.20778 202.50224 47.207591 202.50247 47.207616 202.50274 47.207608 202.5028 47.207374 202.50277 47.207325 202.50276 47.20708 202.50275 47.207014 202.50274 47.206769 202.50277 47.206724 202.50275 47.206435 202.50275 47.206416 202.50284 47.206173 202.5028 47.20607 202.50268 47.205836 202.50267 47.20577 202.50266 47.205525 202.50238 47.205407 202.50237 47.205281 202.50242 47.205047 202.50242 47.205014 202.5024 47.204736 202.50207 47.204794 202.50183 47.204832 202.50157 47.2047 202.50152 47.204449 202.50167 47.204306 202.50169 47.204256 202.5016 47.204026 202.5016 47.2039 202.50158 47.203715 202.50135 47.203566 202.50129 47.20341 202.5016 47.203307 202.50159 47.203061 202.50158 47.202995 202.50157 47.20275 202.50156 47.202684 202.50146 47.202503 202.50131 47.20229 202.50095 47.2023 202.50088 47.202286 202.50061 47.202154 202.50061 47.202088 202.5007 47.201848 202.50108 47.201785 202.50127 47.201602 202.50117 47.20142 202.50089 47.201367 202.50082 47.201353 202.50079 47.201304 202.50101 47.201142 202.5011 47.200901 202.50136 47.200759 202.50143 47.200572 202.50146 47.200522 202.50156 47.200285 202.50155 47.200163 202.50131 47.200014 202.50135 47.199855 202.5014 47.199621 202.50099 47.199633 202.50094 47.199635 202.50068 47.199503 202.50068 47.199437 202.50089 47.199275 202.50088 47.199029 202.50088 47.198963 202.50077 47.198782 202.50059 47.198787 202.5006 47.19891 202.50061 47.199098 202.50034 47.199103 202.5001 47.198957 202.49986 47.198808 202.49971 47.198595 202.49939 47.198502 202.49934 47.198302 202.49968 47.198292 202.49978 47.198544 202.50011 47.198488 202.50017 47.198254 202.49991 47.198122 202.4999 47.198056 202.49989 47.197811 202.49967 47.197645 202.49926 47.197656 202.49904 47.197819 202.49899 47.19782 202.49873 47.197688 202.49849 47.197539 202.49849 47.197473 202.49873 47.197327 202.49895 47.197165 202.49915 47.196987 202.49937 47.196825 202.49946 47.196822 202.49979 47.196907 202.49994 47.19712 202.49994 47.197186 202.49996 47.197431 202.50017 47.197603 202.50044 47.197729 202.50072 47.197847 202.50106 47.197884 202.50113 47.197865 202.5014 47.197796 202.50148 47.19761 202.50124 47.19746 202.50104 47.197286 202.501 47.197245 202.5011 47.197243 202.50133 47.197392 202.50155 47.197558 202.50179 47.197707 202.50212 47.197647 202.50231 47.197649 202.50237 47.197805 202.487 47.188204 202.48702 47.188449 202.48699 47.188496 202.4869 47.188735 202.48659 47.188764 202.48655 47.188521 202.4866 47.188433 202.48664 47.188274 202.48694 47.188162 202.48698 47.188155 202.487 47.188204 202.48355 47.186047 202.48321 47.186056 202.48309 47.18606 202.48298 47.186226 202.48322 47.186376 202.48344 47.186277 202.48377 47.186293 202.48399 47.186324 202.48398 47.186138 202.48367 47.186043 202.48355 47.186047 202.50943 47.202508 202.50939 47.202504 202.50938 47.202477 202.50945 47.202458 202.50943 47.202508 202.50859 47.201987 202.50836 47.201962 202.5083 47.201806 202.50858 47.201798 202.50859 47.201987 202.49585 47.19403 202.49578 47.194016 202.49575 47.193967 202.49582 47.193981 202.49585 47.19403 202.49509 47.193556 202.49524 47.193761 202.49531 47.19399 202.49508 47.194144 202.49471 47.194155 202.49469 47.193905 202.49467 47.193858 202.4946 47.193582 202.49436 47.193433 202.49434 47.193384 202.49446 47.193163 202.49474 47.193155 202.49491 47.193353 202.49509 47.193546 202.49509 47.193556 202.4906 47.190751 202.4907 47.190932 202.49088 47.190927 202.49088 47.190805 202.4906 47.190751 202.48032 47.184326 202.48027 47.184592 202.48023 47.184685 202.48037 47.184655 202.48075 47.184592 202.48073 47.184314 202.48032 47.184326 202.47715 47.182343 202.47702 47.1825 202.47737 47.182564 202.47753 47.18258 202.47752 47.182457 202.47728 47.182308 202.47715 47.182343 202.47662 47.182015 202.47669 47.182095 202.47676 47.182103 202.47677 47.182031 202.47662 47.182015 202.47557 47.18136 202.4755 47.181346 202.47509 47.181357 202.47486 47.181514 202.47488 47.181803 202.47525 47.181757 202.47546 47.181704 202.47573 47.181757 202.47595 47.181595 202.47593 47.18135 202.47557 47.18136 202.47303 47.179771 202.47274 47.179808 202.47272 47.179579 202.47306 47.179569 202.47303 47.179771 202.49957 47.196655 202.49924 47.196665 202.49911 47.19643 202.49875 47.196441 202.49885 47.196622 202.49887 47.196811 202.49863 47.196786 202.49844 47.196606 202.4982 47.196457 202.49822 47.196406 202.4982 47.196128 202.4982 47.196095 202.49827 47.196077 202.49849 47.196243 202.49882 47.196187 202.49901 47.196181 202.49918 47.196379 202.49952 47.196455 202.49957 47.196655 202.49802 47.195682 202.49795 47.195662 202.49795 47.19564 202.49798 47.195639 202.49802 47.195682 202.48721 47.189231 202.48682 47.18925 202.48678 47.188964 202.48722 47.188948 202.48721 47.189231 202.48535 47.188068 202.48533 47.188071 202.48532 47.188047 202.48536 47.188045 202.48535 47.188068 202.46553 47.175679 202.46521 47.175776 202.46498 47.175782 202.46499 47.17564 202.46517 47.175456 202.46543 47.175449 202.46553 47.175679 202.495 47.194396 202.49478 47.194558 202.49455 47.194596 202.49454 47.194408 202.49476 47.194245 202.49504 47.194237 202.495 47.194396 202.47973 47.184857 202.4795 47.184895 202.47937 47.184928 202.479 47.184938 202.47891 47.184942 202.47879 47.185099 202.47902 47.185248 202.47929 47.185179 202.47951 47.185017 202.47974 47.185042 202.4798 47.185198 202.47958 47.18536 202.47939 47.185542 202.47928 47.185708 202.47952 47.185857 202.47979 47.185788 202.47977 47.185675 202.47975 47.185469 202.48006 47.185461 202.48029 47.185617 202.48043 47.185594 202.48046 47.185491 202.48022 47.185337 202.48028 47.185202 202.48027 47.184981 202.48 47.184849 202.47973 47.184857 202.46622 47.176412 202.46592 47.176389 202.46591 47.176215 202.46614 47.176226 202.46622 47.176412 202.50246 47.199357 202.50247 47.19948 202.50265 47.199475 202.50264 47.199352 202.50246 47.199357 202.50165 47.198851 202.50178 47.199011 202.5019 47.199008 202.50201 47.198841 202.50165 47.198851 202.48954 47.191286 202.48934 47.191292 202.48933 47.191152 202.48948 47.191188 202.48954 47.191286 202.48662 47.189462 202.48653 47.189465 202.48655 47.189414 202.4866 47.189413 202.48662 47.189462 202.48626 47.189236 202.48592 47.189265 202.48589 47.189007 202.48625 47.189019 202.48626 47.189236 202.47864 47.184472 202.47864 47.184554 202.47876 47.184551 202.47876 47.184469 202.47864 47.184472 202.50499 47.201233 202.50492 47.201252 202.50494 47.201201 202.50498 47.201209 202.50499 47.201233 202.49878 47.197358 202.4988 47.197637 202.49921 47.197625 202.49919 47.197347 202.49878 47.197358 202.49831 47.19706 202.49824 47.197079 202.49823 47.197013 202.4983 47.197027 202.49831 47.19706 202.49778 47.196732 202.4974 47.196791 202.49726 47.197004 202.49705 47.196978 202.4967 47.196912 202.49652 47.196722 202.49652 47.196545 202.49684 47.196487 202.49709 47.196622 202.4973 47.196728 202.49737 47.196477 202.49776 47.196451 202.49778 47.196732 202.49954 47.198132 202.49945 47.198135 202.49947 47.198085 202.49954 47.198066 202.49954 47.198132 202.49509 47.195649 202.49477 47.195749 202.49475 47.19575 202.49452 47.195891 202.49427 47.196032 202.49389 47.196061 202.49371 47.195867 202.49352 47.195685 202.49351 47.195559 202.49356 47.195326 202.49357 47.195298 202.49361 47.195291 202.49395 47.195235 202.49418 47.195197 202.49437 47.195379 202.49458 47.195329 202.49492 47.195296 202.49506 47.195523 202.49509 47.195649 202.47263 47.181614 202.47252 47.181596 202.47249 47.181524 202.47266 47.181491 202.47263 47.181614 202.47172 47.181046 202.47154 47.18102 202.47156 47.180947 202.47167 47.180922 202.47172 47.181046 202.49915 47.198487 202.49899 47.198476 202.49891 47.198333 202.49919 47.198325 202.49915 47.198487 202.49728 47.197319 202.49706 47.197294 202.49706 47.197177 202.49727 47.197139 202.49728 47.197319 202.485 47.189647 202.48493 47.189666 202.48496 47.189621 202.48503 47.189597 202.485 47.189647 202.47892 47.185846 202.47896 47.185947 202.47911 47.185964 202.47919 47.185777 202.47892 47.185846 202.47654 47.184355 202.47654 47.184478 202.47672 47.184473 202.47672 47.18435 202.47654 47.184355 202.47458 47.183132 202.47443 47.183109 202.47405 47.183101 202.474 47.183368 202.47361 47.183425 202.47351 47.183662 202.47355 47.183763 202.47379 47.183838 202.47389 47.183835 202.47416 47.183767 202.47438 47.183604 202.47473 47.183525 202.47482 47.18328 202.47475 47.183201 202.47458 47.183132 202.47371 47.182586 202.47337 47.182596 202.47325 47.182361 202.47288 47.182372 202.47299 47.182553 202.47322 47.182702 202.47346 47.182851 202.47359 47.183081 202.474 47.18307 202.47409 47.182824 202.47421 47.182621 202.47394 47.182498 202.47371 47.182586 202.50378 47.201676 202.50376 47.201781 202.50394 47.201775 202.50391 47.201674 202.50378 47.201676 202.49173 47.194148 202.49165 47.194133 202.49166 47.194106 202.49172 47.194082 202.49173 47.194148 202.49073 47.193524 202.49052 47.193689 202.49049 47.19369 202.49011 47.193648 202.49012 47.193442 202.49032 47.19327 202.49065 47.193247 202.49073 47.193515 202.49073 47.193524 202.47131 47.181387 202.47123 47.181573 202.47121 47.181623 202.47117 47.181619 202.4709 47.181493 202.47054 47.181503 202.47041 47.181724 202.4701 47.181827 202.46985 47.181974 202.46981 47.181975 202.46947 47.182031 202.4695 47.182198 202.46951 47.182359 202.46924 47.182397 202.46898 47.182327 202.46876 47.182489 202.46869 47.182474 202.46839 47.182373 202.46804 47.182337 202.46784 47.18251 202.46762 47.182672 202.46744 47.18286 202.46726 47.182882 202.467 47.18288 202.46671 47.182998 202.46667 47.182994 202.46663 47.182951 202.46662 47.182705 202.46664 47.182655 202.46654 47.182439 202.46655 47.182303 202.46651 47.18213 202.46651 47.181975 202.4667 47.181995 202.46699 47.182103 202.4673 47.182169 202.46753 47.182015 202.46766 47.181798 202.46793 47.181734 202.46817 47.181816 202.46822 47.181552 202.46861 47.181495 202.46869 47.181498 202.46871 47.181559 202.46862 47.181803 202.4686 47.181894 202.46882 47.181925 202.46912 47.181811 202.46915 47.18181 202.46952 47.181764 202.46971 47.181586 202.47 47.181469 202.47008 47.18145 202.47044 47.18144 202.47069 47.181299 202.47075 47.181275 202.47102 47.181206 202.47125 47.181232 202.47131 47.181387 202.47059 47.180938 202.47031 47.180954 202.47022 47.180708 202.47066 47.180695 202.47059 47.180938 202.46988 47.180495 202.46961 47.180494 202.46954 47.180282 202.4699 47.180277 202.46988 47.180495 202.46504 47.177464 202.4649 47.177468 202.46487 47.177363 202.46503 47.177372 202.46504 47.177464 202.50093 47.200195 202.50083 47.200367 202.50083 47.200433 202.50077 47.200413 202.5005 47.200287 202.50049 47.200221 202.5006 47.199986 202.50088 47.200008 202.50093 47.200195 202.49694 47.197703 202.49668 47.197837 202.49633 47.197836 202.4963 47.1976 202.49648 47.197413 202.49692 47.1974 202.49694 47.197703 202.49589 47.197049 202.49562 47.197057 202.49564 47.196889 202.49588 47.196866 202.49589 47.197049 202.48932 47.192941 202.4893 47.192944 202.4893 47.19293 202.48932 47.192933 202.48932 47.192941 202.48635 47.191089 202.48639 47.191191 202.48654 47.191207 202.48654 47.191084 202.48635 47.191089 202.47901 47.186499 202.47903 47.186549 202.47924 47.186645 202.47914 47.186463 202.47901 47.186499 202.47016 47.180966 202.46983 47.180985 202.46984 47.180766 202.4702 47.180707 202.47016 47.180966 202.50597 47.203641 202.50598 47.203723 202.50613 47.203739 202.50612 47.203616 202.50597 47.203641 202.50374 47.20225 202.50369 47.202484 202.50372 47.202533 202.50385 47.202693 202.504 47.202709 202.50399 47.202586 202.50403 47.202428 202.50408 47.202194 202.50374 47.20225 202.4927 47.19535 202.49266 47.195346 202.49262 47.195303 202.49269 47.195317 202.4927 47.19535 202.48993 47.193622 202.48978 47.193827 202.4894 47.193847 202.48934 47.193567 202.48933 47.193548 202.48936 47.193551 202.48971 47.193487 202.48989 47.193482 202.48993 47.193622 202.487 47.191789 202.48701 47.192034 202.48701 47.1921 202.48717 47.192245 202.48721 47.192225 202.48725 47.192186 202.48723 47.191936 202.48727 47.191843 202.487 47.191789 202.47615 47.18501 202.47604 47.185177 202.4764 47.185167 202.4763 47.184986 202.47615 47.18501 202.4729 47.182978 202.47291 47.183256 202.47325 47.1832 202.47324 47.183015 202.4729 47.182978 202.46974 47.181005 202.46937 47.180999 202.46935 47.180762 202.46971 47.180746 202.46974 47.181005 202.46728 47.179467 202.46699 47.179504 202.46689 47.179523 202.46684 47.17961 202.46709 47.179753 202.46738 47.179829 202.4676 47.179667 202.46752 47.179437 202.46728 47.179467 202.5061 47.204023 202.50621 47.204204 202.50617 47.204363 202.50588 47.204481 202.50583 47.204482 202.50559 47.204333 202.50556 47.204284 202.50543 47.204124 202.50542 47.203895 202.50544 47.203792 202.50517 47.203738 202.5051 47.203718 202.50483 47.203592 202.50465 47.203711 202.50457 47.203784 202.50451 47.203927 202.50456 47.204121 202.50464 47.204303 202.50467 47.204362 202.50479 47.204401 202.50507 47.204393 202.50503 47.204551 202.50498 47.204785 202.50522 47.204934 202.50521 47.204962 202.50503 47.205145 202.50481 47.205307 202.50468 47.205528 202.50473 47.205619 202.50496 47.205704 202.50518 47.205542 202.50526 47.205556 202.50528 47.205605 202.50539 47.205786 202.50566 47.20584 202.50579 47.205619 202.50601 47.205457 202.50628 47.205449 202.50646 47.205444 202.50643 47.205343 202.50641 47.205113 202.50652 47.204946 202.50652 47.20488 202.5066 47.20463 202.50682 47.204468 202.50681 47.204407 202.50661 47.204231 202.50646 47.204013 202.5061 47.204023 202.4999 47.200148 202.4998 47.200151 202.4998 47.200085 202.4999 47.200082 202.4999 47.200148 202.49462 47.196854 202.49458 47.196855 202.49457 47.196822 202.49462 47.196821 202.49462 47.196854 202.49223 47.195358 202.49219 47.195365 202.49216 47.195316 202.49226 47.195313 202.49223 47.195358 202.49179 47.195081 202.49169 47.195084 202.49145 47.194935 202.49109 47.194945 202.49099 47.194948 202.49065 47.194879 202.49052 47.19465 202.49054 47.1946 202.49059 47.194598 202.49099 47.194583 202.49108 47.194561 202.49131 47.194717 202.49154 47.194866 202.49175 47.195038 202.49179 47.195081 202.48786 47.192629 202.48772 47.19281 202.48772 47.192843 202.48783 47.193056 202.48807 47.19306 202.48812 47.192844 202.48811 47.192787 202.48797 47.192627 202.48786 47.192629 202.47166 47.182502 202.47153 47.182656 202.47153 47.182722 202.47129 47.182868 202.47109 47.183046 202.47122 47.183206 202.47134 47.183203 202.47168 47.183193 202.47193 47.183268 202.47179 47.183108 202.47178 47.182878 202.47213 47.182795 202.47211 47.18255 202.47187 47.1824 202.47166 47.182502 202.46399 47.177709 202.46405 47.177768 202.46409 47.178067 202.46368 47.178113 202.46358 47.178116 202.46337 47.17822 202.46299 47.178231 202.463 47.17799 202.46337 47.177922 202.46342 47.177651 202.46371 47.177534 202.46394 47.177528 202.46399 47.177709 202.49011 47.194333 202.49004 47.194352 202.49006 47.194302 202.49011 47.1943 202.49011 47.194333 202.47496 47.184868 202.47469 47.184876 202.47467 47.184687 202.47467 47.184564 202.47444 47.184407 202.47423 47.184413 202.47415 47.184624 202.47417 47.184673 202.47408 47.184676 202.47381 47.184745 202.47354 47.184877 202.47355 47.185062 202.47379 47.185211 202.47406 47.185203 202.47423 47.185215 202.47453 47.185319 202.47449 47.185469 202.47432 47.185474 202.47397 47.185442 202.47374 47.185598 202.47365 47.18584 202.47365 47.185963 202.47362 47.186121 202.4735 47.186348 202.4735 47.186404 202.47363 47.186431 202.4739 47.186299 202.47413 47.186261 202.47441 47.186315 202.47439 47.186069 202.47442 47.186025 202.47446 47.186018 202.47487 47.186006 202.47498 47.185778 202.47511 47.185558 202.47548 47.185491 202.47576 47.185363 202.47569 47.185112 202.47538 47.185012 202.47514 47.184863 202.47496 47.184868 202.50337 47.202916 202.50344 47.202997 202.50366 47.203156 202.50377 47.203163 202.50388 47.202996 202.50352 47.202932 202.50337 47.202916 202.50264 47.202461 202.50265 47.2026 202.50289 47.202616 202.50295 47.202383 202.50264 47.202461 202.50015 47.200904 202.5001 47.200905 202.50008 47.200857 202.50017 47.200854 202.50015 47.200904 202.49979 47.20068 202.49958 47.200639 202.4995 47.2005 202.49978 47.200492 202.49979 47.20068 202.49345 47.19672 202.49324 47.196888 202.49302 47.197051 202.49294 47.197295 202.49258 47.197352 202.49271 47.197154 202.49299 47.197032 202.49317 47.196846 202.49316 47.196601 202.49318 47.19655 202.49323 47.196549 202.49345 47.19671 202.49345 47.19672 202.49285 47.196346 202.49257 47.196384 202.49244 47.196154 202.49216 47.196214 202.49194 47.196372 202.4917 47.196379 202.49169 47.196216 202.49198 47.196102 202.49208 47.19586 202.49235 47.195898 202.49251 47.196102 202.49284 47.196183 202.49285 47.196346 202.48166 47.189353 202.48138 47.189361 202.4812 47.189366 202.48127 47.189446 202.48149 47.189606 202.48163 47.189632 202.48194 47.189529 202.48193 47.189284 202.48166 47.189353 202.47512 47.185266 202.47504 47.185261 202.4748 47.185114 202.4748 47.185065 202.47487 47.185063 202.47518 47.185164 202.47512 47.185266 202.46465 47.17872 202.46454 47.17895 202.46436 47.179138 202.46412 47.179284 202.46411 47.179356 202.46412 47.179585 202.46391 47.179754 202.46365 47.17989 202.4637 47.179978 202.46389 47.180168 202.46385 47.180316 202.46393 47.180463 202.464 47.180706 202.46399 47.180745 202.46406 47.181019 202.46405 47.181039 202.46385 47.181209 202.46362 47.181366 202.4634 47.181528 202.46336 47.181534 202.46296 47.181507 202.46271 47.18136 202.46264 47.181354 202.46224 47.181404 202.46202 47.181562 202.46199 47.181573 202.46158 47.181585 202.46153 47.181586 202.46119 47.181642 202.46092 47.181776 202.46083 47.182016 202.46057 47.182151 202.46059 47.182275 202.46065 47.182499 202.46061 47.182592 202.46079 47.182587 202.46086 47.182401 202.46089 47.182351 202.46108 47.182173 202.46115 47.182193 202.46142 47.182319 202.46165 47.18247 202.46166 47.182534 202.46156 47.182537 202.4612 47.182547 202.4613 47.182728 202.46131 47.182917 202.46136 47.183009 202.4616 47.183093 202.46168 47.182846 202.46205 47.182777 202.4621 47.182792 202.4621 47.182808 202.46206 47.183082 202.46167 47.183141 202.46144 47.183297 202.46138 47.183557 202.46116 47.183483 202.4609 47.183348 202.46071 47.183165 202.46049 47.183004 202.46047 47.182986 202.46038 47.182756 202.46009 47.182645 202.4599 47.182467 202.4598 47.182272 202.45978 47.182229 202.4596 47.182034 202.45935 47.18199 202.45919 47.18201 202.45885 47.181974 202.45882 47.181962 202.45853 47.181849 202.45826 47.181725 202.45804 47.181563 202.4578 47.181413 202.45751 47.181305 202.45748 47.181117 202.45776 47.180997 202.4579 47.180785 202.45789 47.180693 202.45802 47.180557 202.45821 47.180378 202.4584 47.18032 202.45848 47.180544 202.45842 47.180628 202.45854 47.180582 202.45882 47.180461 202.45881 47.18034 202.4589 47.180212 202.45881 47.180016 202.45886 47.179885 202.4591 47.179738 202.45928 47.179552 202.45957 47.179433 202.45974 47.17924 202.45995 47.179072 202.46022 47.178942 202.46038 47.178741 202.46061 47.178585 202.46087 47.178451 202.46109 47.178289 202.46132 47.178134 202.46147 47.178049 202.46148 47.178233 202.46152 47.178341 202.46159 47.178304 202.46167 47.178231 202.46165 47.17804 202.46189 47.177888 202.46208 47.177922 202.46245 47.177978 202.46252 47.178252 202.46287 47.17832 202.46305 47.178315 202.46332 47.178307 202.46345 47.178268 202.46383 47.178258 202.46406 47.178348 202.46412 47.178368 202.46451 47.178409 202.46463 47.178645 202.46465 47.17872 202.46262 47.17745 202.46244 47.177639 202.46201 47.17765 202.46209 47.177417 202.46234 47.177274 202.46264 47.177186 202.46262 47.17745 202.49787 47.19978 202.49764 47.199933 202.49741 47.199968 202.49711 47.19986 202.49697 47.199639 202.49692 47.199486 202.49688 47.19938 202.49694 47.199195 202.49717 47.199171 202.49738 47.199335 202.49744 47.199511 202.49749 47.199583 202.49765 47.199638 202.49779 47.199683 202.49787 47.19978 202.49051 47.195179 202.4903 47.195138 202.49027 47.195029 202.49049 47.194991 202.49051 47.195179 202.47658 47.186475 202.47659 47.18672 202.47686 47.186651 202.47694 47.186465 202.47658 47.186475 202.47014 47.18245 202.47004 47.182452 202.47006 47.182402 202.47011 47.182401 202.47014 47.18245 202.46504 47.179262 202.46466 47.179273 202.46464 47.179012 202.465 47.179024 202.46504 47.179262 202.50201 47.202664 202.50199 47.202767 202.50217 47.202761 202.50213 47.20266 202.50201 47.202664 202.50045 47.201691 202.50036 47.201694 202.50015 47.201522 202.50011 47.201479 202.50021 47.201476 202.50043 47.201642 202.50045 47.201691 202.49782 47.200347 202.49775 47.200366 202.49751 47.200217 202.49751 47.200153 202.49758 47.200165 202.49782 47.200314 202.49782 47.200347 202.49527 47.198752 202.49528 47.198938 202.49529 47.199063 202.49533 47.199227 202.49531 47.199378 202.49536 47.199527 202.49541 47.19974 202.49539 47.199835 202.49534 47.199991 202.49515 47.200007 202.49485 47.199984 202.49468 47.200033 202.49453 47.200085 202.49419 47.20007 202.4942 47.19988 202.4945 47.199769 202.4944 47.199588 202.49444 47.199429 202.49443 47.199244 202.49408 47.199207 202.49389 47.199385 202.49379 47.199388 202.49379 47.199322 202.49368 47.199141 202.49349 47.198959 202.49315 47.198922 202.4931 47.198924 202.49268 47.198931 202.49265 47.198932 202.49263 47.198896 202.49283 47.198726 202.4927 47.198566 202.49247 47.198413 202.49226 47.198371 202.49208 47.198376 202.4919 47.198179 202.4919 47.198145 202.49182 47.197916 202.49162 47.197735 202.49165 47.197685 202.49156 47.197455 202.49122 47.197419 202.49118 47.197414 202.49117 47.197387 202.49116 47.197104 202.49116 47.197084 202.49107 47.196841 202.49108 47.196735 202.49124 47.19672 202.4914 47.196921 202.49141 47.19694 202.49143 47.197229 202.49174 47.197324 202.49201 47.197317 202.49224 47.197162 202.49236 47.197195 202.49252 47.197334 202.49256 47.197365 202.49264 47.197412 202.49285 47.197478 202.49321 47.197468 202.49328 47.197488 202.49329 47.197516 202.49319 47.197752 202.49311 47.197939 202.49311 47.198005 202.49322 47.198186 202.49345 47.198335 202.49373 47.198389 202.49397 47.198242 202.49402 47.198241 202.49426 47.19839 202.49461 47.198456 202.49489 47.198573 202.49503 47.198602 202.4953 47.198597 202.49527 47.198752 202.47444 47.185735 202.47441 47.185732 202.4744 47.185712 202.47443 47.185711 202.47444 47.185735 202.46498 47.179825 202.46467 47.179927 202.46445 47.180088 202.46443 47.180089 202.46442 47.18007 202.46464 47.179907 202.46475 47.179679 202.465 47.179672 202.46498 47.179825 202.50097 47.202612 202.5011 47.202772 202.50107 47.202974 202.50078 47.203011 202.50053 47.202936 202.50031 47.203098 202.50024 47.203084 202.50001 47.202929 202.49997 47.202886 202.50005 47.2029 202.50045 47.202888 202.50044 47.20261 202.50018 47.202478 202.50021 47.202434 202.50027 47.20241 202.50048 47.202576 202.50089 47.202564 202.50097 47.202546 202.50097 47.202612 202.50025 47.202165 202.50019 47.202144 202.50019 47.202122 202.50025 47.202098 202.50025 47.202165 202.49669 47.199936 202.49659 47.199919 202.4966 47.199884 202.49665 47.199876 202.49669 47.199936 202.4671 47.181448 202.46699 47.181451 202.46679 47.181279 202.46677 47.181244 202.46686 47.181222 202.46713 47.18135 202.4671 47.181448 202.46209 47.178314 202.46204 47.178584 202.46188 47.178721 202.46189 47.178787 202.46199 47.178968 202.46214 47.178944 202.46213 47.178862 202.46212 47.178633 202.46237 47.17849 202.46245 47.178304 202.46209 47.178314 202.49667 47.200224 202.49663 47.200215 202.49662 47.200193 202.49669 47.200174 202.49667 47.200224 202.47487 47.186605 202.47485 47.186708 202.47503 47.186703 202.47502 47.186581 202.47487 47.186605 202.5011 47.203293 202.50082 47.203301 202.50081 47.203112 202.50105 47.203137 202.5011 47.203293 202.49072 47.196807 202.49068 47.196805 202.49064 47.196759 202.49071 47.196783 202.49072 47.196807 202.46663 47.181754 202.46656 47.181769 202.46656 47.181707 202.46664 47.181712 202.46663 47.181754 202.46566 47.181149 202.46565 47.181146 202.46564 47.181136 202.46566 47.181136 202.46566 47.181149 202.501 47.203529 202.50081 47.203707 202.50071 47.20371 202.50035 47.20372 202.50028 47.2037 202.50025 47.203657 202.50023 47.203412 202.50025 47.203362 202.50033 47.203343 202.50065 47.203428 202.50093 47.203482 202.50102 47.203479 202.501 47.203529 202.49816 47.201757 202.49807 47.20176 202.49777 47.201653 202.49773 47.201489 202.49803 47.201463 202.49824 47.201633 202.49816 47.201757 202.46119 47.178651 202.46134 47.178794 202.46133 47.179035 202.46097 47.179108 202.46082 47.179315 202.4609 47.179451 202.46094 47.179692 202.46081 47.179843 202.46101 47.180017 202.46142 47.180039 202.4615 47.180042 202.46151 47.179971 202.46143 47.179708 202.4614 47.179678 202.46137 47.179425 202.46139 47.179375 202.46161 47.179213 202.46159 47.178935 202.46157 47.178886 202.46139 47.178763 202.46119 47.178651 202.49675 47.20117 202.49667 47.201166 202.49666 47.201114 202.49674 47.201111 202.49675 47.20117 202.49575 47.200547 202.49574 47.200547 202.49537 47.200498 202.49538 47.20032 202.49562 47.200313 202.49575 47.200544 202.49575 47.200547 202.47752 47.189159 202.47758 47.189243 202.47771 47.189276 202.4777 47.189154 202.47752 47.189159 202.47399 47.186952 202.47395 47.187045 202.47413 47.18704 202.47421 47.186854 202.47399 47.186952 202.49966 47.203287 202.49952 47.203291 202.49953 47.203209 202.49963 47.203206 202.49966 47.203287 202.49343 47.199398 202.49336 47.199384 202.49335 47.199351 202.49343 47.199332 202.49343 47.199398 202.49005 47.197287 202.49003 47.197283 202.49003 47.197277 202.49004 47.197276 202.49005 47.197287 202.47042 47.185017 202.47042 47.185099 202.47057 47.185115 202.47056 47.184993 202.47042 47.185017 202.46532 47.181833 202.46515 47.181838 202.46514 47.18172 202.46528 47.18174 202.46532 47.181833 202.49295 47.199396 202.49275 47.199574 202.49269 47.199553 202.49268 47.199526 202.49267 47.199243 202.49266 47.199219 202.4927 47.199218 202.49294 47.199363 202.49295 47.199396 202.49175 47.19865 202.4917 47.198652 202.4913 47.198663 202.49122 47.198682 202.49124 47.198632 202.49146 47.19847 202.49151 47.198468 202.49175 47.198617 202.49175 47.19865 202.48693 47.195639 202.48678 47.195781 202.48702 47.195693 202.48713 47.195526 202.48693 47.195639 202.46825 47.183961 202.46825 47.184099 202.46845 47.184085 202.46839 47.183998 202.46825 47.183961 202.46586 47.182469 202.46566 47.182438 202.46567 47.182351 202.46577 47.182357 202.46586 47.182469 202.49343 47.2 202.4934 47.200001 202.49339 47.199973 202.49344 47.199972 202.49343 47.2 202.4889 47.197168 202.48884 47.197192 202.48886 47.197141 202.4889 47.197146 202.4889 47.197168 202.46971 47.185173 202.46963 47.185359 202.46985 47.185261 202.46989 47.185168 202.46971 47.185173 202.4689 47.184667 202.46891 47.184912 202.46918 47.184843 202.46917 47.18472 202.4689 47.184667 202.48566 47.195442 202.48567 47.195627 202.48591 47.195776 202.48618 47.195769 202.48617 47.195583 202.48593 47.195434 202.48566 47.195442 202.46192 47.180603 202.46189 47.180665 202.462 47.180652 202.46201 47.18058 202.46192 47.180603 202.50016 47.2048 202.50009 47.204819 202.50012 47.204774 202.50015 47.204773 202.50016 47.2048 202.49341 47.200584 202.49307 47.200569 202.49282 47.200427 202.49283 47.200218 202.49313 47.200198 202.49336 47.200355 202.49341 47.200584 202.48959 47.198197 202.48921 47.198218 202.48912 47.197959 202.48912 47.1979 202.4892 47.197898 202.48959 47.197937 202.48959 47.198197 202.46837 47.184933 202.46835 47.185002 202.46837 47.185231 202.46825 47.185398 202.46849 47.18531 202.46886 47.185242 202.46884 47.184964 202.46858 47.184832 202.46837 47.184933 202.46431 47.182397 202.46395 47.182469 202.46388 47.182449 202.46388 47.18243 202.46387 47.182133 202.46387 47.182122 202.46389 47.182114 202.46426 47.182166 202.46431 47.182397 202.49248 47.200299 202.49209 47.200317 202.49197 47.200086 202.49182 47.199888 202.49214 47.199954 202.49246 47.200045 202.49248 47.200299 202.47778 47.191116 202.47788 47.191298 202.47816 47.191351 202.47801 47.191202 202.47778 47.191116 202.46577 47.183606 202.46538 47.183665 202.46531 47.183667 202.46531 47.183622 202.46541 47.183386 202.46573 47.183359 202.46577 47.183606 202.49451 47.201868 202.49439 47.201871 202.4944 47.2018 202.49451 47.201788 202.49451 47.201868 202.49358 47.201285 202.49337 47.201324 202.49334 47.201134 202.49359 47.201161 202.49358 47.201285 202.46152 47.181252 202.4614 47.181354 202.46174 47.181391 202.46163 47.181185 202.46152 47.181252 202.49823 47.204492 202.49791 47.204476 202.49784 47.204245 202.4982 47.204266 202.49823 47.204492 202.50239 47.207386 202.50232 47.207405 202.5021 47.207503 202.50173 47.207514 202.50162 47.207269 202.50162 47.207203 202.50171 47.2072 202.50207 47.20719 202.50217 47.207187 202.50241 47.207336 202.50239 47.207386 202.49728 47.204194 202.49698 47.204192 202.49693 47.203976 202.49726 47.20398 202.49728 47.204194 202.50078 47.20668 202.50058 47.206732 202.50057 47.206552 202.50077 47.206593 202.50078 47.20668 202.49954 47.205904 202.4995 47.20591 202.4995 47.205883 202.49954 47.205876 202.49954 47.205904 202.49606 47.203735 202.49578 47.203775 202.49556 47.203721 202.49547 47.203961 202.49549 47.20399 202.49544 47.204245 202.49513 47.204254 202.49496 47.204054 202.4949 47.203907 202.49508 47.203719 202.49536 47.203597 202.49553 47.203399 202.49584 47.203405 202.49604 47.203583 202.49606 47.203735 202.48935 47.199844 202.48918 47.199865 202.48883 47.199804 202.48881 47.199506 202.48925 47.199488 202.48935 47.199743 202.48935 47.199844 202.45896 47.180844 202.45881 47.18099 202.45914 47.181074 202.45923 47.181014 202.45939 47.180886 202.45903 47.180832 202.45896 47.180844 202.50154 47.207753 202.5014 47.207757 202.50132 47.207617 202.5016 47.207609 202.50154 47.207753 202.50032 47.206994 202.50025 47.20698 202.50025 47.206947 202.50032 47.206928 202.50032 47.206994 202.49577 47.204152 202.4957 47.204158 202.49558 47.204034 202.49578 47.204103 202.49577 47.204152 202.49178 47.201659 202.49157 47.201682 202.4916 47.201546 202.49175 47.20155 202.49178 47.201659 202.46635 47.185766 202.46631 47.18586 202.46625 47.186003 202.46627 47.186216 202.46664 47.186245 202.46682 47.186062 202.46681 47.185817 202.46657 47.185668 202.46635 47.185766 202.5023 47.208526 202.50214 47.208515 202.50206 47.208376 202.50233 47.208368 202.5023 47.208526 202.50082 47.207603 202.50072 47.207606 202.50072 47.20754 202.50079 47.207555 202.50082 47.207603 202.49946 47.206753 202.49923 47.206758 202.49926 47.20663 202.49945 47.206595 202.49946 47.206753 202.49626 47.205056 202.49607 47.205233 202.49601 47.205231 202.49593 47.20515 202.49625 47.205048 202.49626 47.205046 202.49626 47.205056 202.49586 47.204807 202.4957 47.204812 202.4957 47.204707 202.49584 47.204709 202.49586 47.204807 202.49083 47.201662 202.49071 47.201665 202.4907 47.201585 202.49082 47.201582 202.49083 47.201662 202.50205 47.208971 202.50207 47.209216 202.50207 47.209282 202.50217 47.209463 202.50207 47.209583 202.50183 47.209729 202.50161 47.20989 202.50141 47.210066 202.50117 47.210214 202.501 47.210409 202.50083 47.210454 202.50076 47.210258 202.50111 47.210178 202.5011 47.209933 202.50088 47.209767 202.50051 47.209713 202.50033 47.20969 202.50012 47.209677 202.50013 47.209566 202.50005 47.209403 202.50003 47.209201 202.50038 47.209161 202.50051 47.209204 202.50072 47.209037 202.50103 47.208934 202.50125 47.208772 202.50135 47.208769 202.50171 47.208759 202.50178 47.208779 202.50205 47.208905 202.50205 47.208971 202.46334 47.184784 202.46299 47.184737 202.46287 47.184496 202.46285 47.184479 202.4629 47.184478 202.46331 47.184495 202.46334 47.184784 202.49366 47.204032 202.49342 47.204179 202.49304 47.204176 202.49302 47.203929 202.4932 47.203741 202.49364 47.203729 202.49366 47.204032 202.4894 47.201367 202.48935 47.201369 202.48932 47.20132 202.48938 47.201343 202.4894 47.201367 202.49715 47.206511 202.49694 47.206496 202.49665 47.20639 202.49666 47.206204 202.49691 47.206196 202.49712 47.206368 202.49715 47.206511 202.4902 47.20217 202.49005 47.202149 202.49005 47.202074 202.4902 47.202044 202.4902 47.20217 202.4892 47.201841 202.48916 47.201836 202.48886 47.201732 202.48885 47.201623 202.48901 47.201619 202.4892 47.201807 202.4892 47.201841 202.49675 47.206854 202.49637 47.20692 202.49637 47.206919 202.49637 47.206917 202.4965 47.2067 202.49668 47.206688 202.49675 47.206854 202.49823 47.208081 202.49793 47.208193 202.49764 47.208254 202.49771 47.208055 202.49788 47.207864 202.49818 47.207855 202.49823 47.208081 202.49433 47.205643 202.49426 47.205877 202.49427 47.205904 202.49423 47.2059 202.49394 47.205784 202.4939 47.205672 202.4938 47.205567 202.49381 47.205318 202.49415 47.205309 202.49431 47.205515 202.49433 47.205643 202.50029 47.209961 202.50012 47.210006 202.50017 47.209889 202.5003 47.20987 202.50029 47.209961 202.49316 47.205511 202.49298 47.205516 202.49299 47.205405 202.49315 47.205392 202.49316 47.205511 202.49859 47.209502 202.49829 47.209614 202.49802 47.209605 202.49803 47.209448 202.49809 47.209228 202.49809 47.209186 202.49814 47.209191 202.49857 47.209201 202.49859 47.209502 202.48227 47.19931 202.48204 47.199285 202.48203 47.19916 202.48222 47.199154 202.48227 47.19931 202.49492 47.207509 202.49472 47.207681 202.49443 47.207698 202.49442 47.207497 202.49469 47.207364 202.49491 47.207346 202.49492 47.207509 202.48543 47.201579 202.48546 47.201639 202.48568 47.201735 202.4855 47.201607 202.48543 47.201579 202.49978 47.210841 202.49941 47.210852 202.49942 47.210616 202.49979 47.210573 202.49978 47.210841 202.49299 47.206603 202.49283 47.206607 202.49282 47.206497 202.49298 47.206492 202.49299 47.206603 202.48299 47.200353 202.48285 47.200311 202.48284 47.200264 202.48294 47.200249 202.48299 47.200353 202.49843 47.210297 202.49837 47.210323 202.4984 47.210278 202.49844 47.210272 202.49843 47.210297 202.48818 47.203896 202.48811 47.203914 202.4881 47.203848 202.48817 47.203868 202.48818 47.203896 202.48748 47.20376 202.48743 47.203761 202.48744 47.203733 202.4875 47.20371 202.48748 47.20376 202.49717 47.210109 202.4969 47.210107 202.49689 47.209934 202.49718 47.209899 202.49717 47.210109 202.4887 47.205122 202.48866 47.205129 202.48866 47.205096 202.48871 47.205094 202.4887 47.205122 202.48266 47.201344 202.48266 47.201428 202.48279 47.201662 202.48276 47.201707 202.48269 47.201731 202.48246 47.201819 202.48212 47.201908 202.48186 47.202044 202.48182 47.202051 202.48182 47.202018 202.48192 47.201781 202.48185 47.201701 202.4817 47.201487 202.48169 47.201341 202.48161 47.201233 202.48159 47.200978 202.48192 47.200881 202.48209 47.200876 202.4823 47.201048 202.4826 47.201149 202.48266 47.201344 202.49902 47.211864 202.49876 47.212001 202.4989 47.212205 202.49884 47.212347 202.4986 47.212433 202.49834 47.212335 202.4983 47.212329 202.49824 47.212276 202.49839 47.212069 202.49846 47.211879 202.49849 47.211829 202.49856 47.21181 202.49882 47.211741 202.49906 47.211766 202.49902 47.211864 202.48754 47.204693 202.48747 47.204712 202.48726 47.204819 202.48698 47.204943 202.4869 47.205129 202.48691 47.205195 202.48673 47.205386 202.48662 47.205615 202.48662 47.205666 202.48676 47.205883 202.48675 47.205993 202.48648 47.206126 202.48656 47.206356 202.48662 47.206515 202.48634 47.20652 202.48623 47.20657 202.48597 47.206708 202.48565 47.206804 202.48555 47.207041 202.48551 47.207134 202.48547 47.207292 202.48533 47.207504 202.48522 47.207671 202.48519 47.207716 202.48516 47.207717 202.48493 47.207563 202.48453 47.207599 202.48436 47.207791 202.48413 47.207949 202.48397 47.208146 202.48379 47.208337 202.48366 47.208503 202.48363 47.208533 202.4836 47.208547 202.48337 47.208674 202.48328 47.208782 202.48324 47.208891 202.48311 47.209106 202.48286 47.209094 202.48289 47.20897 202.48283 47.208789 202.48256 47.208762 202.48242 47.208766 202.48215 47.20864 202.48182 47.208555 202.48157 47.208417 202.48136 47.208246 202.48141 47.208047 202.48157 47.207848 202.48181 47.207696 202.48207 47.207561 202.48216 47.207335 202.48215 47.207313 202.48219 47.207306 202.4825 47.207228 202.48283 47.207138 202.48292 47.206896 202.48314 47.206734 202.48332 47.206542 202.48353 47.20638 202.48387 47.206396 202.48416 47.206471 202.48435 47.206293 202.48422 47.206133 202.48421 47.205904 202.48432 47.205737 202.48411 47.205562 202.48411 47.205545 202.48425 47.205331 202.48448 47.205293 202.48475 47.205346 202.48501 47.205205 202.48504 47.205205 202.48546 47.205192 202.4855 47.205186 202.48581 47.205107 202.4859 47.204896 202.4859 47.204868 202.48599 47.204621 202.48615 47.204425 202.48655 47.204414 202.48662 47.204686 202.48688 47.204582 202.48717 47.204462 202.48744 47.204409 202.48756 47.204643 202.48754 47.204693 202.48545 47.203388 202.48557 47.203511 202.4858 47.203666 202.48591 47.203673 202.48589 47.203602 202.48574 47.203388 202.48545 47.203388 202.49687 47.210823 202.49681 47.210824 202.49681 47.21078 202.49687 47.210778 202.49687 47.210823 202.48944 47.206179 202.48913 47.206288 202.48886 47.206284 202.48878 47.206066 202.48902 47.205915 202.48932 47.205949 202.48944 47.206179 202.48281 47.202039 202.48271 47.202042 202.48271 47.201976 202.48278 47.201996 202.48281 47.202039 202.48139 47.201448 202.48133 47.201435 202.48132 47.201408 202.48138 47.201399 202.48139 47.201448 202.49641 47.211133 202.49639 47.211137 202.49638 47.21111 202.49642 47.211114 202.49641 47.211133 202.4881 47.205941 202.48803 47.205926 202.48802 47.205893 202.4881 47.205875 202.4881 47.205941 202.49488 47.210476 202.49461 47.210495 202.4946 47.2103 202.49489 47.210293 202.49488 47.210476 202.48287 47.202974 202.48277 47.203213 202.4828 47.203278 202.48279 47.203519 202.48278 47.203621 202.48293 47.203835 202.48297 47.203935 202.48302 47.204096 202.48322 47.204269 202.48328 47.204425 202.48293 47.204507 202.48275 47.204691 202.48261 47.204903 202.48228 47.204999 202.48209 47.205177 202.48183 47.205318 202.48177 47.205342 202.48141 47.205352 202.48154 47.205512 202.48151 47.205714 202.4813 47.205883 202.48104 47.206016 202.48087 47.206005 202.48069 47.205818 202.48068 47.205791 202.48066 47.205513 202.48063 47.205464 202.48073 47.205461 202.481 47.205392 202.48107 47.205206 202.48107 47.20514 202.48127 47.204964 202.48147 47.204911 202.48175 47.204965 202.48167 47.204762 202.48173 47.204655 202.48186 47.204436 202.4818 47.204342 202.48187 47.204143 202.482 47.203924 202.48202 47.203858 202.48205 47.203656 202.48214 47.203444 202.48173 47.203456 202.48168 47.203458 202.48145 47.2033 202.48145 47.203283 202.48155 47.203049 202.48164 47.202835 202.48165 47.202807 202.48171 47.202784 202.48198 47.202715 202.48232 47.202627 202.48236 47.202631 202.48239 47.202674 202.48249 47.202856 202.48268 47.202855 202.48288 47.202895 202.48287 47.202974 202.49792 47.212673 202.49778 47.212708 202.49773 47.212552 202.49794 47.212593 202.49792 47.212673 202.49585 47.21198 202.49568 47.211985 202.49569 47.211877 202.49583 47.211874 202.49585 47.21198 202.48423 47.205021 202.484 47.204996 202.48402 47.204886 202.48418 47.204865 202.48423 47.205021 202.48342 47.204811 202.48334 47.204829 202.48337 47.204784 202.48341 47.204778 202.48342 47.204811 202.49566 47.212756 202.49545 47.212801 202.4955 47.212659 202.49565 47.212655 202.49566 47.212756 202.4808 47.203474 202.48076 47.203484 202.48077 47.203458 202.4808 47.203458 202.4808 47.203474 202.49592 47.213215 202.49573 47.213245 202.49578 47.213133 202.49594 47.21309 202.49592 47.213215 202.48214 47.204609 202.48215 47.204736 202.4823 47.204711 202.48232 47.204608 202.48214 47.204609 202.48122 47.204637 202.48102 47.204596 202.48099 47.204491 202.48116 47.204488 202.48122 47.204637 202.48063 47.204267 202.48071 47.204496 202.4807 47.204607 202.48049 47.20466 202.48031 47.204665 202.48003 47.204673 202.48007 47.204515 202.48029 47.204353 202.48028 47.204167 202.48029 47.204057 202.48046 47.204036 202.48063 47.204234 202.48063 47.204267 202.48079 47.204964 202.48051 47.204971 202.4805 47.204783 202.48071 47.204824 202.48079 47.204964 202.4943 47.213701 202.4942 47.213725 202.49424 47.213663 202.4943 47.213658 202.4943 47.213701 202.48081 47.205275 202.48053 47.205283 202.48052 47.205094 202.4808 47.205086 202.48081 47.205275 202.48213 47.206398 202.48191 47.20656 202.48177 47.206772 202.48162 47.206752 202.48138 47.206604 202.48134 47.206505 202.48156 47.206343 202.48172 47.206354 202.4821 47.206379 202.48214 47.206373 202.48213 47.206398 202.48035 47.205288 202.48039 47.205388 202.48036 47.205592 202.48011 47.205734 202.47981 47.205846 202.47974 47.206106 202.47947 47.206236 202.47914 47.20633 202.47901 47.206544 202.47889 47.206493 202.47889 47.206471 202.47882 47.206219 202.47883 47.206134 202.47877 47.205931 202.47876 47.205793 202.47895 47.205608 202.47925 47.205574 202.47945 47.205625 202.47967 47.205461 202.47981 47.20525 202.47981 47.205164 202.47984 47.20497 202.48012 47.204933 202.48034 47.205099 202.48035 47.205288 202.49475 47.214878 202.49439 47.214888 202.49433 47.21462 202.49472 47.214647 202.49475 47.214878 202.49209 47.213821 202.49187 47.21382 202.49185 47.213671 202.49208 47.213665 202.49209 47.213821 202.48053 47.206599 202.48059 47.206863 202.48064 47.206963 202.48051 47.207184 202.48027 47.207331 202.48005 47.207493 202.47974 47.207597 202.47945 47.207719 202.47943 47.207724 202.47906 47.207771 202.47879 47.207904 202.47875 47.207899 202.47832 47.207911 202.47828 47.207918 202.47828 47.207885 202.47845 47.207694 202.47866 47.207641 202.47884 47.207635 202.47883 47.207513 202.47891 47.207378 202.47917 47.207245 202.47931 47.20703 202.47936 47.206796 202.47928 47.206716 202.47943 47.206745 202.47967 47.206656 202.47978 47.206489 202.4798 47.206439 202.47985 47.206438 202.48026 47.206426 202.48033 47.206408 202.48053 47.206582 202.48053 47.206599 202.49416 47.215413 202.4941 47.215432 202.49404 47.215337 202.49418 47.215371 202.49416 47.215413 202.48416 47.209465 202.48409 47.209484 202.48411 47.209434 202.48416 47.209432 202.48416 47.209465 202.48457 47.21002 202.48455 47.210123 202.48451 47.210281 202.48429 47.210316 202.48417 47.210366 202.48418 47.210393 202.4844 47.21056 202.48463 47.21071 202.48467 47.210979 202.48435 47.211076 202.48406 47.211199 202.48399 47.211182 202.48364 47.211116 202.48334 47.211047 202.48327 47.211066 202.48306 47.210899 202.48303 47.210851 202.4829 47.210692 202.48265 47.210549 202.4826 47.210283 202.4826 47.210261 202.48254 47.209979 202.48251 47.20993 202.48241 47.209749 202.48226 47.209774 202.48227 47.209855 202.48224 47.210057 202.48221 47.210221 202.48222 47.210346 202.48199 47.210384 202.48181 47.210389 202.48153 47.210397 202.48152 47.210209 202.4816 47.210022 202.48124 47.210033 202.48115 47.210273 202.48117 47.21034 202.48139 47.210504 202.48163 47.210579 202.48173 47.210576 202.48174 47.210642 202.48152 47.210804 202.48153 47.211049 202.48151 47.211099 202.48132 47.211277 202.48122 47.21128 202.48086 47.21129 202.48078 47.211276 202.48037 47.211287 202.48039 47.211566 202.48039 47.211599 202.4802 47.211777 202.47998 47.211939 202.47974 47.212085 202.47992 47.212242 202.48007 47.212296 202.48029 47.212289 202.48029 47.212434 202.48015 47.212641 202.47977 47.212702 202.47973 47.212709 202.47972 47.212676 202.47954 47.212519 202.47948 47.212525 202.47909 47.212528 202.47893 47.21232 202.47887 47.212145 202.47918 47.212136 202.47944 47.2122 202.47943 47.211954 202.47916 47.212023 202.47888 47.212031 202.47887 47.211843 202.47886 47.21172 202.47856 47.21165 202.47853 47.211642 202.47828 47.211499 202.47827 47.21147 202.47832 47.211198 202.47831 47.211149 202.47807 47.211 202.47806 47.210738 202.47804 47.210701 202.47779 47.210559 202.47763 47.210354 202.4774 47.210327 202.47719 47.210495 202.47706 47.210711 202.47686 47.210886 202.47651 47.210858 202.47635 47.210644 202.47601 47.210654 202.47598 47.21092 202.476 47.210949 202.47617 47.211107 202.47615 47.211342 202.47579 47.211383 202.47567 47.211343 202.47544 47.211318 202.47539 47.211162 202.47546 47.210976 202.47511 47.210912 202.47499 47.210916 202.47462 47.210983 202.47447 47.21119 202.47442 47.211424 202.47483 47.211412 202.47488 47.211411 202.47511 47.21156 202.47511 47.211588 202.47518 47.211839 202.4755 47.21183 202.47576 47.211697 202.4758 47.211704 202.47616 47.211764 202.47631 47.211739 202.47668 47.211671 202.47666 47.211393 202.47667 47.211365 202.47689 47.211203 202.47694 47.211191 202.47718 47.211087 202.47743 47.210942 202.47774 47.210839 202.47794 47.210776 202.47795 47.210969 202.47787 47.211153 202.47784 47.211198 202.4777 47.21141 202.47757 47.211631 202.47755 47.211711 202.47777 47.211874 202.47778 47.212063 202.47745 47.21215 202.47741 47.212143 202.47697 47.212155 202.47699 47.21245 202.47703 47.21249 202.47716 47.21265 202.47718 47.21288 202.47684 47.212889 202.47672 47.212893 202.47634 47.212955 202.47625 47.213197 202.47617 47.213384 202.47614 47.213426 202.47608 47.213452 202.47584 47.213542 202.47567 47.213734 202.47542 47.213878 202.47506 47.213881 202.47485 47.213706 202.47482 47.213504 202.47496 47.213303 202.47496 47.213289 202.47511 47.213088 202.47507 47.212893 202.47473 47.212845 202.47469 47.212846 202.47436 47.212914 202.47421 47.21312 202.47399 47.213282 202.47396 47.213385 202.47408 47.213624 202.47408 47.213637 202.47405 47.213648 202.4737 47.213581 202.47352 47.213586 202.47324 47.213594 202.47297 47.213541 202.47289 47.213791 202.47285 47.213884 202.47286 47.214073 202.47278 47.214259 202.47279 47.214325 202.47262 47.214524 202.47235 47.214577 202.47223 47.214341 202.47196 47.21441 202.47165 47.214513 202.47155 47.214516 202.47119 47.214526 202.47094 47.214667 202.47087 47.214691 202.47087 47.214625 202.47112 47.214479 202.4711 47.214201 202.47107 47.214152 202.47092 47.214006 202.47084 47.214005 202.47045 47.214063 202.47035 47.2143 202.47027 47.214486 202.47051 47.214635 202.47051 47.214701 202.47042 47.214704 202.47015 47.214773 202.46994 47.214732 202.46961 47.214648 202.46953 47.214686 202.46919 47.214775 202.46893 47.214828 202.46891 47.214599 202.46886 47.214552 202.46866 47.214442 202.46857 47.214445 202.4683 47.214514 202.46796 47.214601 202.46773 47.214755 202.4677 47.214756 202.46769 47.214732 202.46761 47.214502 202.46737 47.214353 202.46702 47.214316 202.46698 47.214312 202.46667 47.214217 202.46666 47.214091 202.46697 47.213981 202.46703 47.213955 202.46724 47.214121 202.46758 47.214065 202.46786 47.213941 202.46799 47.213893 202.46817 47.213833 202.46821 47.213734 202.46826 47.213594 202.46822 47.2134 202.46818 47.213245 202.46843 47.2131 202.4687 47.212972 202.4686 47.212791 202.46847 47.212828 202.4682 47.212953 202.46803 47.213146 202.46777 47.213288 202.4675 47.213418 202.46728 47.213576 202.46705 47.213614 202.46694 47.213666 202.46652 47.213678 202.46644 47.213652 202.46607 47.21372 202.466 47.213738 202.46576 47.213827 202.46552 47.213766 202.46541 47.213607 202.46539 47.213536 202.46531 47.213544 202.46503 47.213477 202.46478 47.213333 202.46449 47.213224 202.4642 47.213115 202.46396 47.212968 202.46376 47.212786 202.46359 47.212587 202.46337 47.212424 202.46316 47.212257 202.46313 47.212185 202.46328 47.21217 202.46363 47.212232 202.46367 47.212218 202.46368 47.212194 202.4638 47.212005 202.46391 47.211771 202.46403 47.21161 202.46403 47.211546 202.46423 47.211375 202.46435 47.211378 202.46464 47.211492 202.46464 47.211632 202.46434 47.211742 202.46448 47.211934 202.4646 47.21217 202.46484 47.212056 202.46521 47.211985 202.46537 47.211928 202.46564 47.212047 202.46585 47.212088 202.46599 47.212115 202.46627 47.212239 202.46645 47.212163 202.46666 47.211994 202.467 47.212021 202.46725 47.212164 202.46742 47.212168 202.46737 47.212074 202.46742 47.211872 202.46768 47.211848 202.46783 47.212062 202.46779 47.212104 202.46781 47.212399 202.46809 47.212517 202.46848 47.212535 202.46852 47.212526 202.46886 47.21247 202.46903 47.212278 202.46911 47.212092 202.46913 47.212041 202.46918 47.21204 202.46959 47.212028 202.46963 47.212033 202.46964 47.21206 202.4696 47.212332 202.46957 47.2124 202.46952 47.212581 202.46925 47.212635 202.4691 47.212621 202.46902 47.212807 202.46902 47.212873 202.46918 47.213016 202.46926 47.21302 202.46957 47.212917 202.4698 47.212879 202.47008 47.212933 202.47014 47.212953 202.47051 47.212907 202.47064 47.212912 202.47093 47.212869 202.47109 47.212667 202.47111 47.212564 202.47115 47.212405 202.47145 47.212295 202.47151 47.212269 202.47173 47.212171 202.4721 47.212161 202.47233 47.212246 202.4724 47.21226 202.47271 47.212182 202.47273 47.212019 202.47251 47.211853 202.47249 47.211744 202.47254 47.21151 202.4723 47.211361 202.47208 47.211491 202.47168 47.211496 202.47158 47.211477 202.47128 47.211592 202.47101 47.211662 202.47087 47.211635 202.47064 47.21161 202.47059 47.211455 202.47055 47.211353 202.47043 47.211357 202.47021 47.211518 202.46991 47.211497 202.46967 47.211482 202.46951 47.211471 202.46929 47.211307 202.46932 47.211265 202.46955 47.211105 202.4696 47.211076 202.4698 47.210963 202.47021 47.210952 202.47033 47.210994 202.47055 47.210836 202.47083 47.210819 202.47093 47.210775 202.47134 47.210732 202.47156 47.21057 202.47161 47.210568 202.47196 47.210635 202.47202 47.210852 202.47206 47.210889 202.47229 47.211044 202.47249 47.21115 202.47257 47.211165 202.47286 47.211079 202.47317 47.211043 202.47341 47.211124 202.47351 47.210889 202.47373 47.210727 202.47411 47.210662 202.47416 47.210635 202.47417 47.210701 202.47431 47.210856 202.47454 47.210936 202.47464 47.210696 202.47498 47.210612 202.47508 47.210371 202.47542 47.210362 202.47562 47.210532 202.47581 47.210527 202.4758 47.210405 202.47565 47.210192 202.47568 47.210149 202.47584 47.20995 202.47599 47.209743 202.47595 47.209641 202.47594 47.209412 202.47596 47.209309 202.476 47.20915 202.47618 47.209145 202.47653 47.209182 202.47672 47.209004 202.4768 47.208754 202.47679 47.208692 202.47682 47.208467 202.47712 47.208355 202.47738 47.208222 202.47761 47.208065 202.47765 47.208059 202.47796 47.20816 202.47829 47.208238 202.47835 47.20823 202.47862 47.208097 202.47895 47.208074 202.47898 47.208323 202.47876 47.208481 202.47868 47.208597 202.47866 47.208718 202.47854 47.208945 202.47845 47.209099 202.47841 47.209165 202.47819 47.209324 202.47815 47.209316 202.47774 47.209293 202.47762 47.209266 202.4774 47.20943 202.47739 47.209555 202.47744 47.209753 202.47748 47.20981 202.4776 47.210046 202.47787 47.210024 202.47818 47.209915 202.47812 47.209664 202.47815 47.209595 202.47825 47.209573 202.47851 47.209523 202.47874 47.209534 202.47882 47.209716 202.47882 47.209797 202.47899 47.210001 202.4792 47.209954 202.47943 47.209798 202.47977 47.209751 202.47999 47.20991 202.4801 47.209917 202.4803 47.209745 202.48057 47.209612 202.48056 47.20949 202.48055 47.209301 202.48051 47.2092 202.48057 47.209014 202.4808 47.208863 202.48101 47.208829 202.48129 47.208948 202.48131 47.209177 202.48131 47.209259 202.48146 47.209275 202.4817 47.2093 202.48204 47.209337 202.48227 47.209182 202.4823 47.209179 202.48256 47.209317 202.48258 47.209371 202.48268 47.209552 202.48295 47.209606 202.48302 47.209626 202.48344 47.209614 202.48348 47.209613 202.48383 47.209675 202.48402 47.209672 202.48424 47.209697 202.48452 47.20982 202.48457 47.21002 202.48059 47.207533 202.48065 47.207796 202.48074 47.207926 202.48043 47.20803 202.48017 47.208171 202.48011 47.208194 202.48011 47.208128 202.48036 47.207987 202.48034 47.207698 202.48033 47.207671 202.48055 47.207509 202.48059 47.207516 202.48059 47.207533 202.47797 47.205893 202.47775 47.206055 202.47769 47.206081 202.47772 47.206036 202.47794 47.205874 202.47796 47.205876 202.47797 47.205893 202.48635 47.21143 202.48631 47.21142 202.48627 47.211382 202.48637 47.211379 202.48635 47.21143 202.48555 47.210931 202.48526 47.210897 202.48523 47.210727 202.4855 47.210719 202.48555 47.210931 202.48898 47.213369 202.48896 47.213369 202.48896 47.213357 202.48898 47.213358 202.48898 47.213369 202.48164 47.208788 202.48144 47.208841 202.48121 47.208684 202.4812 47.208512 202.48149 47.208475 202.4817 47.208645 202.48164 47.208788 202.47451 47.204329 202.47433 47.204334 202.47412 47.204389 202.4739 47.204551 202.47378 47.20474 202.47378 47.204773 202.47373 47.204774 202.47332 47.204786 202.47315 47.204978 202.47305 47.205214 202.47281 47.205366 202.47256 47.205509 202.47222 47.205597 202.47215 47.205615 202.47179 47.205625 202.47181 47.20587 202.47215 47.205943 202.47216 47.206156 202.47218 47.206245 202.47227 47.206227 202.47226 47.206188 202.47224 47.205906 202.47253 47.205789 202.47275 47.205626 202.47303 47.205619 202.4733 47.205672 202.47338 47.205687 202.47371 47.205631 202.47394 47.205593 202.47422 47.205646 202.47412 47.205465 202.47415 47.205306 202.47438 47.205268 202.4745 47.205226 202.47464 47.205077 202.47464 47.205011 202.47448 47.204872 202.47441 47.204599 202.47441 47.204566 202.47445 47.204565 202.47469 47.204447 202.47472 47.204371 202.47451 47.204329 202.49018 47.214421 202.49018 47.214421 202.49018 47.21442 202.49018 47.21442 202.49018 47.214421 202.48664 47.212207 202.48656 47.212214 202.48635 47.212044 202.48635 47.212028 202.4864 47.212011 202.48665 47.212147 202.48664 47.212207 202.47761 47.206568 202.47733 47.20669 202.47734 47.206985 202.47738 47.207025 202.47716 47.207187 202.47707 47.20719 202.47706 47.207124 202.47696 47.206943 202.47702 47.206799 202.47729 47.206666 202.47744 47.206462 202.47767 47.206422 202.47761 47.206568 202.47823 47.207255 202.47819 47.207335 202.47813 47.207492 202.47795 47.207514 202.47768 47.20739 202.47767 47.207201 202.47774 47.207015 202.47778 47.206973 202.47781 47.206963 202.47818 47.207016 202.47823 47.207255 202.49197 47.216433 202.49186 47.21643 202.49185 47.216362 202.49195 47.216364 202.49197 47.216433 202.48477 47.211936 202.48475 47.212225 202.48451 47.212377 202.48413 47.212381 202.48398 47.21217 202.48399 47.212053 202.48409 47.211815 202.48434 47.211673 202.4847 47.21164 202.48476 47.211914 202.48477 47.211936 202.48411 47.211527 202.48392 47.211562 202.48398 47.211442 202.48414 47.211403 202.48411 47.211527 202.47972 47.208785 202.47944 47.20891 202.4792 47.20887 202.47919 47.208752 202.47932 47.208535 202.47966 47.208528 202.47972 47.208785 202.48943 47.215148 202.48917 47.215169 202.48917 47.214983 202.48942 47.214983 202.48943 47.215148 202.48339 47.211374 202.48329 47.211377 202.48329 47.211311 202.48336 47.211325 202.48339 47.211374 202.48341 47.211685 202.48333 47.211671 202.48331 47.211622 202.4834 47.211619 202.48341 47.211685 202.48293 47.211387 202.48286 47.211373 202.48283 47.211324 202.48293 47.211321 202.48293 47.211387 202.47702 47.207696 202.47677 47.207734 202.47676 47.207532 202.47701 47.207556 202.47702 47.207696 202.4764 47.20731 202.47603 47.207303 202.47602 47.20707 202.47636 47.20706 202.4764 47.20731 202.48292 47.211683 202.48287 47.211684 202.48287 47.211651 202.48294 47.211632 202.48292 47.211683 202.48437 47.212886 202.48432 47.21289 202.48432 47.212856 202.48437 47.212855 202.48437 47.212886 202.48297 47.212008 202.48286 47.212019 202.48283 47.211926 202.48299 47.211921 202.48297 47.212008 202.47625 47.207811 202.47607 47.207998 202.47582 47.208144 202.47577 47.208145 202.47577 47.208112 202.47575 47.207834 202.47575 47.207801 202.47582 47.207783 202.47621 47.207789 202.47626 47.207788 202.47625 47.207811 202.47664 47.208356 202.47638 47.208346 202.47631 47.208147 202.47658 47.208204 202.47664 47.208356 202.48139 47.211919 202.48116 47.211973 202.48115 47.211771 202.48138 47.211812 202.48139 47.211919 202.4852 47.214598 202.48511 47.214588 202.4851 47.214539 202.48519 47.214529 202.4852 47.214598 202.48101 47.211983 202.48078 47.211931 202.48073 47.211808 202.481 47.21177 202.48101 47.211983 202.47619 47.208975 202.47596 47.208982 202.47598 47.208843 202.47618 47.208817 202.47619 47.208975 202.47362 47.207364 202.47349 47.207554 202.4738 47.207651 202.47394 47.207566 202.47397 47.207527 202.47377 47.207344 202.47362 47.207364 202.47127 47.2062 202.47089 47.206258 202.47084 47.206259 202.4705 47.206315 202.47032 47.206321 202.46997 47.206284 202.4699 47.206302 202.46968 47.206401 202.46931 47.206411 202.46923 47.20642 202.4691 47.206571 202.46908 47.206621 202.46916 47.206851 202.4695 47.206888 202.46954 47.206892 202.46958 47.206935 202.46945 47.207156 202.46924 47.207115 202.46892 47.207124 202.46872 47.207177 202.46844 47.207123 202.46846 47.207368 202.46844 47.207418 202.46836 47.207437 202.46801 47.207371 202.46789 47.207376 202.46755 47.207386 202.46731 47.207311 202.46724 47.207291 202.46723 47.207264 202.46745 47.207102 202.46743 47.206823 202.46717 47.206692 202.46681 47.206702 202.46656 47.206843 202.46637 47.207026 202.46627 47.207029 202.46591 47.207039 202.46601 47.20722 202.46603 47.207409 202.46595 47.207595 202.46632 47.207643 202.4664 47.207911 202.46671 47.208011 202.46676 47.208167 202.46677 47.20829 202.46704 47.208343 202.46714 47.208341 202.46736 47.208507 202.46773 47.208558 202.46797 47.208703 202.46822 47.208778 202.46828 47.208798 202.46871 47.208786 202.46874 47.208785 202.46912 47.20883 202.46925 47.208828 202.46957 47.208725 202.46984 47.208598 202.46987 47.2086 202.46989 47.208624 202.46997 47.208854 202.47021 47.208824 202.47053 47.208729 202.47068 47.208522 202.4709 47.20836 202.47089 47.208175 202.47054 47.208138 202.4705 47.208134 202.47014 47.208075 202.46995 47.207896 202.46991 47.207741 202.46993 47.207582 202.46992 47.207449 202.47007 47.20724 202.47043 47.20721 202.47052 47.207228 202.4709 47.207165 202.47097 47.207141 202.4712 47.207053 202.47118 47.206981 202.47117 47.206732 202.47117 47.206669 202.47119 47.206447 202.47154 47.206389 202.47157 47.206382 202.4716 47.206349 202.4714 47.206167 202.47127 47.2062 202.47378 47.208063 202.47388 47.208242 202.47415 47.208298 202.47414 47.208052 202.47378 47.208063 202.47308 47.207629 202.47294 47.20784 202.47283 47.208046 202.47319 47.208102 202.47337 47.208111 202.47368 47.207999 202.47366 47.207754 202.47345 47.207582 202.47308 47.207629 202.4755 47.20944 202.47533 47.209635 202.47503 47.209669 202.47502 47.209437 202.47533 47.209332 202.47552 47.20931 202.4755 47.20944 202.48069 47.212981 202.4806 47.213221 202.4803 47.213258 202.48033 47.213056 202.48068 47.212972 202.48069 47.212973 202.48069 47.212981 202.4882 47.21827 202.48807 47.218259 202.48806 47.21818 202.48818 47.218177 202.4882 47.21827 202.47163 47.207917 202.47139 47.208065 202.47132 47.208184 202.47147 47.208117 202.4717 47.207963 202.47171 47.207891 202.47163 47.207917 202.47 47.206901 202.46994 47.206925 202.46997 47.20688 202.47 47.206879 202.47 47.206901 202.48031 47.213639 202.48021 47.213649 202.48019 47.213564 202.48033 47.21356 202.48031 47.213639 202.4747 47.210436 202.47442 47.210444 202.47446 47.210285 202.47469 47.210247 202.4747 47.210436 202.47291 47.209318 202.47284 47.209336 202.47284 47.20927 202.4729 47.20929 202.47291 47.209318 202.47946 47.214009 202.47923 47.214047 202.47922 47.213859 202.47946 47.213884 202.47946 47.214009 202.47811 47.213162 202.47792 47.213346 202.47752 47.213395 202.47748 47.21339 202.47747 47.213363 202.47749 47.213077 202.47781 47.212973 202.4781 47.212936 202.47811 47.213162 202.48005 47.214675 202.47966 47.214709 202.47944 47.214543 202.47947 47.214309 202.47975 47.214318 202.48005 47.214421 202.48005 47.214675 202.47909 47.214072 202.47898 47.214239 202.47919 47.214405 202.47922 47.214454 202.47915 47.214434 202.47878 47.214477 202.47851 47.214608 202.47847 47.214609 202.47805 47.214621 202.47797 47.21487 202.47765 47.214892 202.47749 47.214686 202.47751 47.214582 202.4777 47.214401 202.47787 47.214208 202.47812 47.21407 202.47834 47.213905 202.47858 47.213881 202.47878 47.21388 202.47907 47.213843 202.47909 47.214072 202.46969 47.208203 202.46957 47.208424 202.46922 47.208434 202.4692 47.208195 202.4695 47.208086 202.46971 47.208067 202.46969 47.208203 202.48084 47.215469 202.481 47.21567 202.48093 47.215821 202.48079 47.215825 202.48059 47.215913 202.48022 47.215919 202.47995 47.215795 202.47994 47.215506 202.48035 47.215499 202.48039 47.215484 202.48084 47.215465 202.48084 47.215465 202.48084 47.215469 202.47704 47.213097 202.47701 47.213088 202.47697 47.213049 202.47707 47.213046 202.47704 47.213097 202.47924 47.215065 202.47917 47.215073 202.47886 47.214975 202.47888 47.214839 202.47907 47.214816 202.47926 47.215005 202.47924 47.215065 202.47556 47.21277 202.47554 47.212873 202.47555 47.213061 202.47561 47.213147 202.47574 47.213179 202.4757 47.213077 202.47569 47.212848 202.47565 47.21279 202.47556 47.21277 202.4653 47.206359 202.46519 47.206526 202.46546 47.206457 202.46545 47.206334 202.4653 47.206359 202.48604 47.21961 202.48581 47.219604 202.48581 47.21947 202.48605 47.219423 202.48604 47.21961 202.4678 47.208218 202.46772 47.208237 202.46773 47.208176 202.46779 47.208184 202.4678 47.208218 202.47106 47.210555 202.47076 47.210549 202.47063 47.210585 202.47034 47.2107 202.47017 47.210894 202.46984 47.210903 202.46974 47.210653 202.46973 47.210623 202.46984 47.210388 202.4701 47.210381 202.47024 47.21034 202.4705 47.210203 202.47073 47.210244 202.47103 47.21035 202.47106 47.210555 202.46713 47.208096 202.46703 47.208098 202.46705 47.208048 202.46709 47.208052 202.46713 47.208096 202.48657 47.220545 202.48625 47.220577 202.48603 47.220415 202.48599 47.220179 202.48632 47.220203 202.48656 47.220347 202.48657 47.220545 202.46457 47.206795 202.46458 47.206981 202.46485 47.206973 202.4649 47.206739 202.46457 47.206795 202.47861 47.215871 202.47853 47.215871 202.47854 47.215823 202.47859 47.215821 202.47861 47.215871 202.47648 47.214837 202.4764 47.214837 202.47642 47.214798 202.47646 47.214794 202.47648 47.214837 202.46465 47.207448 202.4647 47.207538 202.46484 47.207565 202.46492 47.207379 202.46465 47.207448 202.47608 47.214888 202.4759 47.214887 202.4759 47.214776 202.47604 47.214778 202.47608 47.214888 202.47245 47.21262 202.4726 47.212763 202.47267 47.212757 202.47268 47.212705 202.47245 47.21262 202.47603 47.215156 202.47597 47.215158 202.47595 47.215107 202.47605 47.2151 202.47603 47.215156 202.47481 47.214393 202.4748 47.214395 202.4748 47.214387 202.47481 47.214387 202.47481 47.214393 202.47101 47.212021 202.47079 47.212183 202.47074 47.212184 202.4704 47.212116 202.47027 47.211886 202.47024 47.211837 202.47031 47.211852 202.47068 47.211904 202.47094 47.211975 202.47103 47.211972 202.47101 47.212021 202.48576 47.221532 202.48541 47.221523 202.4854 47.221305 202.48572 47.221296 202.48576 47.221532 202.47373 47.214017 202.4735 47.214055 202.47349 47.213866 202.47376 47.213858 202.47373 47.214017 202.48517 47.221466 202.48502 47.221485 202.485 47.221356 202.48517 47.221376 202.48517 47.221466 202.48021 47.218665 202.48001 47.218676 202.48001 47.218538 202.4802 47.218537 202.48021 47.218665 202.47322 47.214296 202.47315 47.214315 202.47314 47.214249 202.47324 47.214246 202.47322 47.214296 202.47946 47.218497 202.47938 47.218493 202.47939 47.218451 202.47944 47.218447 202.47946 47.218497 202.46453 47.209166 202.46456 47.209267 202.46465 47.209243 202.46465 47.209203 202.46453 47.209166 202.4832 47.221129 202.48298 47.221293 202.48265 47.221286 202.48266 47.221089 202.48286 47.220918 202.4832 47.220877 202.4832 47.221129 202.47255 47.214777 202.47251 47.214784 202.47248 47.214735 202.47255 47.214755 202.47255 47.214777 202.47444 47.216257 202.47416 47.21638 202.47387 47.216384 202.47387 47.2162 202.47403 47.215999 202.47439 47.215999 202.47444 47.216257 202.48396 47.2225 202.4836 47.222532 202.48359 47.222273 202.48392 47.222298 202.48396 47.2225 202.48429 47.223009 202.48428 47.223013 202.48426 47.222989 202.4843 47.222996 202.48429 47.223009 202.4712 47.215127 202.47116 47.215134 202.47116 47.215106 202.47119 47.215105 202.4712 47.215127 202.47158 47.215669 202.47133 47.215653 202.47133 47.215508 202.47154 47.215502 202.47158 47.215669 202.46511 47.211623 202.46485 47.211659 202.46484 47.211453 202.46518 47.211417 202.46511 47.211623 202.46594 47.21244 202.46579 47.212587 202.46598 47.212468 202.46605 47.212395 202.46594 47.21244 202.48235 47.222993 202.4821 47.222993 202.48208 47.222823 202.48234 47.222816 202.48235 47.222993 202.47937 47.221431 202.47937 47.221431 202.47937 47.22143 202.47937 47.22143 202.47937 47.221431 202.47798 47.22056 202.47782 47.220762 202.47762 47.220774 202.47762 47.220634 202.47789 47.220508 202.47797 47.220509 202.47798 47.22056 202.47108 47.216254 202.47096 47.216257 202.47084 47.2161 202.4711 47.216153 202.47108 47.216254 202.48958 47.173657 202.48942 47.173661 202.48941 47.173555 202.48957 47.173549 202.48958 47.173657 202.48113 47.168675 202.48092 47.168845 202.4805 47.168865 202.48025 47.168723 202.48023 47.168415 202.4804 47.168287 202.48045 47.16825 202.48046 47.168248 202.4809 47.168244 202.48111 47.168417 202.48113 47.168675 202.49364 47.17769 202.4932 47.177698 202.49319 47.177413 202.49362 47.177389 202.49364 47.17769 202.49357 47.179442 202.4935 47.179431 202.4935 47.179397 202.49354 47.179398 202.49357 47.179442 202.49506 47.181869 202.49494 47.181941 202.49481 47.182016 202.49442 47.182 202.49445 47.181788 202.49462 47.181595 202.49499 47.181579 202.49506 47.181855 202.49506 47.181869 202.49134 47.179544 202.49105 47.17961 202.49107 47.179375 202.49134 47.179396 202.49134 47.179544 202.48955 47.179028 202.48918 47.179091 202.48932 47.179267 202.48949 47.179287 202.4897 47.17931 202.48998 47.179425 202.49025 47.179554 202.49033 47.179812 202.49007 47.179949 202.49009 47.179997 202.49023 47.18022 202.49024 47.180352 202.49003 47.180522 202.48978 47.180665 202.48961 47.180678 202.48926 47.180609 202.48925 47.180332 202.48963 47.18027 202.48957 47.180057 202.48921 47.179994 202.48919 47.179997 202.48918 47.180016 202.48917 47.180282 202.48916 47.180359 202.48918 47.180588 202.48896 47.180507 202.48875 47.18034 202.48866 47.180265 202.48859 47.180132 202.48834 47.180065 202.48828 47.180034 202.48828 47.180027 202.48841 47.179808 202.48857 47.179609 202.48872 47.179407 202.48873 47.179377 202.48871 47.179098 202.4887 47.179074 202.48873 47.178816 202.48911 47.178772 202.48914 47.178767 202.48953 47.178781 202.48955 47.179028 202.4956 47.183106 202.49539 47.183275 202.49518 47.183443 202.49513 47.183429 202.49513 47.183407 202.49527 47.183199 202.4955 47.183043 202.49562 47.183069 202.4956 47.183106 202.49527 47.1829 202.49499 47.183022 202.49486 47.182981 202.49486 47.182943 202.49483 47.182677 202.49482 47.18262 202.49492 47.182609 202.49528 47.182667 202.49527 47.1829 202.49322 47.18162 202.49317 47.181627 202.49304 47.181503 202.49323 47.181582 202.49322 47.18162 202.4911 47.180294 202.49086 47.1804 202.49095 47.180199 202.49114 47.180194 202.4911 47.180294 202.49707 47.184321 202.497 47.184323 202.497 47.18428 202.49705 47.184286 202.49707 47.184321 202.49365 47.182185 202.49332 47.182161 202.49336 47.182003 202.49357 47.181978 202.49365 47.182185 202.49269 47.181586 202.4924 47.181542 202.49242 47.18142 202.49257 47.181416 202.49269 47.181586 202.4878 47.178528 202.48753 47.178658 202.48749 47.178665 202.4875 47.178643 202.48739 47.178414 202.48721 47.17822 202.48721 47.17816 202.48731 47.17815 202.4876 47.178256 202.48775 47.178475 202.4878 47.178528 202.50166 47.187488 202.50147 47.18753 202.50149 47.187382 202.50165 47.187394 202.50166 47.187488 202.49363 47.182475 202.49331 47.182499 202.4933 47.182264 202.49367 47.18223 202.49363 47.182475 202.48617 47.17811 202.48601 47.178132 202.48596 47.177978 202.48623 47.177972 202.48617 47.17811 202.47717 47.172484 202.47689 47.172514 202.47692 47.172328 202.4772 47.172278 202.47717 47.172484 202.50131 47.18787 202.50107 47.187824 202.5007 47.187773 202.50066 47.187763 202.50039 47.187675 202.50037 47.18758 202.5005 47.187364 202.5008 47.187375 202.50101 47.187543 202.50124 47.187696 202.50131 47.18787 202.49533 47.184135 202.49534 47.184252 202.49535 47.184444 202.49516 47.184386 202.49493 47.18423 202.49488 47.184148 202.49513 47.184009 202.49524 47.183996 202.49533 47.184135 202.49114 47.181514 202.49112 47.181516 202.49112 47.181501 202.49114 47.181499 202.49114 47.181514 202.5001 47.18741 202.49991 47.187379 202.4999 47.187286 202.50005 47.187278 202.5001 47.18741 202.49583 47.184747 202.49588 47.184826 202.49583 47.185046 202.49551 47.185144 202.49546 47.185141 202.49506 47.185107 202.49482 47.184964 202.49487 47.184745 202.49516 47.184628 202.49537 47.184557 202.49548 47.184524 202.4958 47.184561 202.49583 47.184747 202.49673 47.185606 202.49661 47.18559 202.49632 47.185481 202.49632 47.185348 202.4965 47.185342 202.49675 47.185488 202.49673 47.185606 202.48697 47.179505 202.48676 47.179527 202.48651 47.179393 202.48652 47.179227 202.48675 47.179212 202.48698 47.179371 202.48697 47.179505 202.49607 47.185493 202.49588 47.18548 202.49585 47.185355 202.49605 47.18535 202.49607 47.185493 202.49104 47.182349 202.49083 47.18238 202.49081 47.182209 202.49107 47.182202 202.49104 47.182349 202.48562 47.179261 202.48529 47.179355 202.48522 47.179371 202.48524 47.179321 202.4854 47.179125 202.48562 47.17907 202.48562 47.179261 202.49721 47.187102 202.4972 47.187103 202.4972 47.187098 202.49721 47.187098 202.49721 47.187102 202.47289 47.1719 202.47287 47.171901 202.47287 47.171893 202.47289 47.171892 202.47289 47.1719 202.4987 47.188333 202.49863 47.188327 202.49863 47.188288 202.49868 47.18829 202.4987 47.188333 202.48569 47.180203 202.48541 47.180329 202.48526 47.180311 202.48521 47.180204 202.48542 47.180032 202.48564 47.18003 202.48569 47.180203 202.50173 47.190521 202.50146 47.190462 202.50144 47.190344 202.50159 47.190365 202.50173 47.190521 202.50085 47.189976 202.5008 47.189978 202.50048 47.189884 202.50029 47.189921 202.50004 47.189885 202.50004 47.189765 202.50033 47.189652 202.50036 47.189647 202.50067 47.189743 202.50086 47.189929 202.50085 47.189976 202.5016 47.191039 202.50155 47.191051 202.50154 47.191002 202.50162 47.191 202.5016 47.191039 202.49854 47.189132 202.49843 47.189124 202.49816 47.189 202.49808 47.188845 202.49843 47.188797 202.49852 47.189057 202.49854 47.189132 202.4771 47.175729 202.47692 47.175739 202.47693 47.175626 202.47708 47.175626 202.4771 47.175729 202.49851 47.189409 202.49846 47.189427 202.49848 47.189394 202.49851 47.18939 202.49851 47.189409 202.49729 47.188647 202.49711 47.188802 202.4971 47.188825 202.49707 47.188826 202.49679 47.188711 202.49678 47.188627 202.49686 47.188381 202.49727 47.188357 202.49729 47.188647 202.50145 47.191544 202.50132 47.191547 202.50133 47.19147 202.50147 47.191432 202.50145 47.191544 202.49878 47.189877 202.49873 47.189882 202.49874 47.189851 202.49877 47.189849 202.49878 47.189877 202.50144 47.191841 202.50129 47.192044 202.50108 47.192046 202.50109 47.191917 202.50135 47.191781 202.50144 47.191778 202.50144 47.191841 202.50473 47.194191 202.5043 47.194219 202.50431 47.193932 202.5047 47.193928 202.50473 47.194191 202.49984 47.191438 202.49955 47.191552 202.49965 47.19132 202.49983 47.191346 202.49984 47.191438 202.49914 47.190997 202.49894 47.191029 202.49899 47.190907 202.49909 47.190918 202.49914 47.190997 202.50493 47.194915 202.50471 47.195078 202.50447 47.19507 202.50415 47.194983 202.50393 47.19482 202.50367 47.194689 202.50345 47.194591 202.5034 47.194563 202.5034 47.194556 202.50343 47.194277 202.50379 47.194272 202.50407 47.194377 202.50419 47.194301 202.50453 47.194378 202.50477 47.194525 202.50499 47.194688 202.50493 47.194915 202.51008 47.198431 202.51003 47.198445 202.51004 47.198408 202.51008 47.198411 202.51008 47.198431 202.50282 47.194194 202.50258 47.194195 202.50251 47.194003 202.50285 47.193995 202.50282 47.194194 202.50235 47.193905 202.50211 47.193887 202.50205 47.193713 202.50237 47.193697 202.50235 47.193905 202.50182 47.193574 202.50166 47.193572 202.50163 47.193455 202.5018 47.193469 202.50182 47.193574 202.50601 47.196488 202.50566 47.196475 202.50563 47.196252 202.50599 47.196224 202.50601 47.196488 202.50824 47.19818 202.50804 47.198354 202.50794 47.198369 202.50772 47.198453 202.50741 47.198431 202.50727 47.19821 202.50726 47.198168 202.50734 47.198159 202.5076 47.198081 202.50792 47.198053 202.50818 47.198144 202.50823 47.198149 202.50824 47.19818 202.49851 47.192701 202.49843 47.192704 202.49843 47.192653 202.49851 47.192646 202.49851 47.192701 202.47353 47.177989 202.47342 47.178001 202.4734 47.177909 202.47354 47.177917 202.47353 47.177989 202.50865 47.200231 202.50851 47.200225 202.5085 47.200134 202.50869 47.200088 202.50865 47.200231 202.47283 47.177851 202.47275 47.177851 202.47275 47.177798 202.47282 47.177796 202.47283 47.177851 202.47208 47.177378 202.47206 47.177379 202.47206 47.177369 202.47208 47.177367 202.47208 47.177378 202.4716 47.177377 202.47122 47.17744 202.47104 47.177487 202.47106 47.177342 202.47127 47.177175 202.47146 47.177172 202.4716 47.177377 202.50575 47.199018 202.50574 47.199019 202.50574 47.199007 202.50575 47.199006 202.50575 47.199018 202.47455 47.179521 202.47438 47.179569 202.47444 47.179455 202.47454 47.17945 202.47455 47.179521 202.47059 47.177049 202.47022 47.177115 202.47028 47.176856 202.47054 47.176878 202.47059 47.177049 202.47261 47.178907 202.47239 47.179071 202.47218 47.179241 202.47218 47.179242 202.47212 47.179497 202.47178 47.179538 202.47156 47.179378 202.47134 47.179313 202.47124 47.179288 202.47123 47.179243 202.47116 47.179025 202.47098 47.178829 202.4706 47.178788 202.47064 47.178574 202.47095 47.178529 202.47104 47.178525 202.47143 47.1785 202.47153 47.178531 202.47173 47.178603 202.47214 47.178614 202.47216 47.17861 202.47258 47.178625 202.47261 47.178907 202.46942 47.176916 202.4692 47.176892 202.46921 47.176785 202.46936 47.176771 202.46942 47.176916 202.47011 47.177646 202.46994 47.177646 202.46988 47.177498 202.47008 47.177543 202.47011 47.177646 202.50708 47.201639 202.50704 47.201636 202.50704 47.201615 202.50707 47.201613 202.50708 47.201639 202.47616 47.182326 202.47592 47.182338 202.47592 47.182175 202.47615 47.182164 202.47616 47.182326 202.47036 47.179 202.47029 47.179014 202.47029 47.178953 202.47044 47.178907 202.47036 47.179 202.46925 47.178603 202.4691 47.178592 202.46906 47.178486 202.46924 47.178488 202.46925 47.178603 202.46993 47.179327 202.46987 47.179328 202.46987 47.179287 202.46994 47.179271 202.46993 47.179327 202.50885 47.203945 202.50875 47.203954 202.50874 47.203876 202.50885 47.203874 202.50885 47.203945 202.47534 47.183007 202.475 47.183019 202.475 47.182794 202.47532 47.182783 202.47534 47.183007 202.50889 47.204269 202.50868 47.204324 202.5087 47.20415 202.50892 47.204152 202.50889 47.204269 202.50818 47.203826 202.50802 47.203836 202.50804 47.203735 202.50818 47.203719 202.50818 47.203826 202.46578 47.177329 202.46556 47.177309 202.46556 47.177191 202.46574 47.177172 202.46578 47.177329 202.49432 47.195764 202.49428 47.195772 202.49429 47.195745 202.49433 47.195736 202.49432 47.195764 202.49687 47.197658 202.49653 47.197687 202.49655 47.197457 202.49686 47.197448 202.49687 47.197658 202.46955 47.180888 202.46952 47.180888 202.46952 47.180864 202.46955 47.180862 202.46955 47.180888 202.46393 47.177971 202.46377 47.177977 202.46373 47.177847 202.46392 47.177866 202.46393 47.177971 202.48123 47.190582 202.48106 47.190574 202.48103 47.190456 202.4812 47.190471 202.48123 47.190582 202.46167 47.178652 202.46153 47.178654 202.46152 47.178557 202.46174 47.178505 202.46167 47.178652 202.48177 47.191518 202.48146 47.191624 202.48159 47.191812 202.48163 47.192024 202.4814 47.192182 202.48118 47.192115 202.48086 47.192027 202.48059 47.191973 202.48043 47.192173 202.48051 47.192284 202.48075 47.192428 202.48099 47.192521 202.48108 47.192514 202.48131 47.192426 202.48168 47.192393 202.48187 47.192578 202.48205 47.192772 202.48232 47.192895 202.48241 47.193111 202.48231 47.193234 202.48249 47.19316 202.48276 47.193224 202.48314 47.193272 202.48307 47.193524 202.48303 47.193673 202.48314 47.19387 202.48288 47.194006 202.48287 47.194117 202.48317 47.194223 202.48315 47.194474 202.48319 47.194533 202.4832 47.194805 202.48286 47.194888 202.48288 47.195086 202.48311 47.195049 202.48342 47.194942 202.48358 47.194742 202.48363 47.194534 202.48326 47.194479 202.48322 47.194216 202.48352 47.194105 202.48375 47.194117 202.48376 47.194255 202.4837 47.194477 202.48397 47.194607 202.48398 47.194689 202.48391 47.194947 202.48351 47.194995 202.48361 47.195196 202.48371 47.19542 202.48331 47.195422 202.48326 47.195438 202.4829 47.195396 202.48263 47.195343 202.48255 47.195329 202.4823 47.195191 202.48221 47.195079 202.48211 47.195003 202.48202 47.194962 202.4818 47.194911 202.48175 47.194793 202.48201 47.194655 202.48225 47.194507 202.48217 47.194308 202.48216 47.194151 202.4822 47.193964 202.48199 47.193795 202.48171 47.193675 202.48142 47.193565 202.48124 47.193368 202.48101 47.193219 202.48067 47.193139 202.48058 47.192881 202.48043 47.192772 202.48035 47.192723 202.48015 47.19255 202.47996 47.19248 202.47986 47.192435 202.47966 47.192292 202.47964 47.192275 202.47965 47.191988 202.48 47.192008 202.48024 47.192056 202.48027 47.191812 202.48019 47.191723 202.48008 47.191628 202.48001 47.191614 202.47974 47.19174 202.47948 47.191742 202.47946 47.19157 202.47944 47.191445 202.47923 47.19128 202.47898 47.191134 202.47897 47.190962 202.47907 47.190746 202.47905 47.190713 202.47911 47.190717 202.47948 47.190769 202.47969 47.190934 202.47998 47.190996 202.48005 47.190994 202.48041 47.191055 202.48046 47.191298 202.48048 47.191332 202.48054 47.191346 202.48091 47.191336 202.48109 47.191391 202.48121 47.19144 202.48159 47.191401 202.48172 47.191389 202.48177 47.191518 202.46266 47.18017 202.46253 47.180197 202.46225 47.180073 202.46208 47.179876 202.46207 47.179802 202.46218 47.179801 202.46247 47.179912 202.46266 47.180096 202.46266 47.18017 202.48169 47.192961 202.48139 47.192935 202.48123 47.192976 202.48122 47.193061 202.4815 47.193182 202.48155 47.193173 202.48183 47.193049 202.48178 47.192969 202.48169 47.192961 202.47709 47.190088 202.4771 47.190247 202.47708 47.190379 202.47682 47.190518 202.47679 47.190795 202.47646 47.190891 202.47619 47.19092 202.47589 47.190818 202.47587 47.190821 202.47552 47.190767 202.4752 47.190702 202.47515 47.190713 202.47475 47.190681 202.47449 47.190553 202.47448 47.190552 202.47404 47.190558 202.47401 47.190557 202.47402 47.190573 202.47408 47.190602 202.47447 47.190564 202.47468 47.190735 202.47486 47.190928 202.47515 47.19104 202.47537 47.1912 202.47549 47.191179 202.47585 47.191175 202.47598 47.191189 202.47617 47.191006 202.47651 47.191013 202.47674 47.191165 202.47696 47.191328 202.47696 47.191504 202.47666 47.191616 202.47682 47.191756 202.47709 47.191885 202.47713 47.19191 202.47743 47.191953 202.47766 47.192114 202.47769 47.192254 202.47743 47.192285 202.47725 47.192282 202.47695 47.192313 202.47684 47.192323 202.47683 47.192399 202.47686 47.192637 202.47647 47.192667 202.47644 47.192674 202.47644 47.192689 202.47663 47.192794 202.47671 47.192814 202.47704 47.192749 202.47718 47.192794 202.47719 47.192841 202.47727 47.193052 202.47752 47.193193 202.47768 47.193395 202.47797 47.193511 202.47804 47.193673 202.47809 47.193746 202.47826 47.19381 202.47842 47.193831 202.47874 47.193918 202.47867 47.194069 202.47874 47.194245 202.47899 47.194381 202.4792 47.194549 202.47945 47.194692 202.47975 47.194799 202.47997 47.194963 202.48019 47.195122 202.4803 47.195366 202.48056 47.1955 202.48095 47.195538 202.48119 47.195638 202.48124 47.19565 202.48151 47.195771 202.4818 47.195883 202.48185 47.196056 202.48181 47.196206 202.48181 47.196326 202.48188 47.196479 202.48199 47.196722 202.48203 47.196764 202.48221 47.196882 202.4823 47.19714 202.48229 47.197227 202.48217 47.197448 202.48188 47.197567 202.48181 47.197825 202.48159 47.197985 202.48154 47.198031 202.48139 47.198161 202.48135 47.198171 202.48096 47.198193 202.48085 47.198212 202.48061 47.198067 202.48022 47.198026 202.48022 47.198025 202.47987 47.197963 202.47971 47.197755 202.47972 47.197712 202.4798 47.197466 202.48018 47.197407 202.48019 47.197407 202.48019 47.197402 202.48027 47.197161 202.48039 47.196933 202.48039 47.19693 202.48038 47.196929 202.47995 47.196924 202.47969 47.196794 202.47945 47.196644 202.47942 47.196629 202.47908 47.196713 202.47879 47.196832 202.47872 47.197088 202.47844 47.197064 202.4782 47.19692 202.4781 47.196703 202.47849 47.196704 202.4787 47.19678 202.47857 47.196643 202.47841 47.196435 202.47846 47.196329 202.47838 47.196132 202.47813 47.196122 202.47802 47.196354 202.47772 47.196298 202.47738 47.196226 202.47732 47.196217 202.47734 47.196252 202.47737 47.196542 202.47735 47.196568 202.47723 47.196755 202.47695 47.196881 202.47716 47.197038 202.47729 47.197093 202.47749 47.197121 202.47752 47.197235 202.47736 47.197436 202.47734 47.197555 202.47746 47.197787 202.47778 47.197878 202.47814 47.197935 202.47816 47.197935 202.47846 47.198031 202.47846 47.198121 202.47842 47.198382 202.47859 47.198503 202.47835 47.198436 202.47816 47.198252 202.47779 47.198301 202.47759 47.19848 202.4776 47.198662 202.47758 47.198769 202.47747 47.199001 202.47743 47.199114 202.47756 47.199342 202.47758 47.199369 202.47776 47.199518 202.47786 47.199772 202.47795 47.199902 202.47801 47.199985 202.47808 47.200259 202.47848 47.20029 202.47875 47.200413 202.47886 47.200663 202.47905 47.200844 202.47908 47.200906 202.479 47.200883 202.47877 47.200727 202.47839 47.200772 202.47822 47.200809 202.47824 47.200681 202.47812 47.200555 202.47799 47.200524 202.47766 47.200618 202.47763 47.200895 202.4776 47.200943 202.47757 47.20116 202.47765 47.201229 202.4777 47.201241 202.4777 47.201194 202.47766 47.200917 202.47804 47.20094 202.4782 47.201151 202.47818 47.201242 202.47816 47.201503 202.47818 47.201536 202.47813 47.201809 202.47812 47.201858 202.47809 47.202084 202.47814 47.202164 202.47818 47.202437 202.47815 47.202489 202.47814 47.202712 202.47806 47.202877 202.47803 47.202943 202.47815 47.203133 202.47811 47.203293 202.47795 47.203488 202.4776 47.203546 202.47746 47.203319 202.47724 47.203347 202.47707 47.203539 202.4769 47.203728 202.47664 47.203866 202.47626 47.203883 202.47622 47.203904 202.47621 47.203917 202.47618 47.204177 202.47587 47.204172 202.4757 47.20397 202.47533 47.20395 202.47529 47.203948 202.47489 47.203919 202.47489 47.203669 202.47525 47.203649 202.47551 47.203763 202.47559 47.203512 202.47589 47.203504 202.47606 47.203504 202.47633 47.203508 202.47649 47.203473 202.47661 47.203297 202.47653 47.203201 202.47663 47.202964 202.47664 47.20295 202.47662 47.202955 202.47633 47.203079 202.4761 47.203229 202.47589 47.203398 202.47558 47.203407 202.47537 47.20324 202.47524 47.20301 202.47524 47.202995 202.47527 47.202987 202.47549 47.202848 202.47557 47.202767 202.4756 47.202617 202.47579 47.202605 202.47608 47.20262 202.47631 47.202464 202.47615 47.202333 202.47595 47.202162 202.47588 47.201896 202.47619 47.201794 202.47631 47.201568 202.47631 47.201565 202.4763 47.201564 202.476 47.201671 202.47568 47.201708 202.47554 47.201488 202.47528 47.201355 202.47493 47.201286 202.47492 47.201294 202.47492 47.201296 202.47491 47.201592 202.47482 47.201692 202.47477 47.201803 202.47465 47.201818 202.4744 47.201681 202.47418 47.201729 202.47393 47.201878 202.47365 47.201905 202.47345 47.201872 202.4733 47.201839 202.47326 47.201759 202.47318 47.201602 202.47318 47.201405 202.4733 47.20119 202.47299 47.201288 202.47271 47.201303 202.47243 47.201178 202.47217 47.201051 202.47213 47.201048 202.47184 47.201169 202.47163 47.201335 202.47152 47.201529 202.4715 47.201556 202.4714 47.201792 202.47124 47.201989 202.47086 47.202015 202.47067 47.20183 202.47054 47.201852 202.47028 47.201794 202.47005 47.201637 202.46983 47.201476 202.46954 47.201365 202.46927 47.201237 202.46904 47.201079 202.46888 47.200877 202.46862 47.200746 202.46838 47.200597 202.46816 47.200433 202.46785 47.200334 202.46762 47.20018 202.46737 47.200039 202.46716 47.199869 202.4669 47.199734 202.46664 47.1996 202.46641 47.19945 202.46614 47.199325 202.46588 47.199186 202.46566 47.199025 202.46541 47.198887 202.46516 47.198743 202.46492 47.198597 202.46467 47.198454 202.46447 47.19828 202.46423 47.198131 202.46396 47.198006 202.46373 47.19785 202.4635 47.197691 202.46327 47.197538 202.46306 47.197364 202.46284 47.197207 202.46262 47.197041 202.46241 47.196871 202.46211 47.196765 202.46195 47.196563 202.46173 47.196397 202.46149 47.196251 202.4612 47.196135 202.46096 47.195994 202.46069 47.195867 202.46038 47.19577 202.46037 47.195493 202.46062 47.195352 202.461 47.195292 202.46112 47.195065 202.46131 47.194886 202.46149 47.1947 202.46147 47.194636 202.46159 47.194459 202.46185 47.194327 202.46195 47.194286 202.46218 47.194231 202.46215 47.194136 202.46223 47.193966 202.46242 47.19378 202.46267 47.19364 202.46294 47.19351 202.46311 47.193428 202.46323 47.193392 202.46327 47.193311 202.46338 47.193185 202.46359 47.193022 202.46384 47.192878 202.46405 47.192705 202.46425 47.192536 202.46446 47.192367 202.46466 47.192192 202.4649 47.192041 202.46508 47.191858 202.46529 47.191685 202.4655 47.191522 202.46574 47.191367 202.466 47.191235 202.46619 47.191056 202.46644 47.190911 202.46669 47.190768 202.4669 47.190596 202.46711 47.190432 202.46732 47.190266 202.46752 47.190088 202.46779 47.189956 202.46801 47.1898 202.46822 47.18963 202.46841 47.189451 202.46863 47.189286 202.46883 47.189113 202.46907 47.188963 202.46931 47.188817 202.46929 47.188537 202.46907 47.188377 202.46902 47.188334 202.46923 47.188254 202.46936 47.18825 202.46965 47.188132 202.46989 47.188094 202.47005 47.188079 202.47029 47.187929 202.47056 47.187921 202.47078 47.187935 202.47102 47.187791 202.47121 47.187767 202.47122 47.187915 202.47117 47.188121 202.47155 47.188167 202.47164 47.18843 202.47202 47.188471 202.47204 47.188723 202.47174 47.188835 202.47145 47.188894 202.47136 47.188898 202.47099 47.188909 202.47091 47.188918 202.4707 47.189085 202.4705 47.189261 202.47021 47.189378 202.4701 47.189565 202.4701 47.189609 202.47002 47.189622 202.4697 47.189534 202.46945 47.189392 202.4693 47.189404 202.469 47.189519 202.46891 47.189763 202.46889 47.189808 202.46912 47.189893 202.4692 47.189902 202.4695 47.189829 202.46978 47.189803 202.46988 47.189768 202.47027 47.189767 202.47044 47.189819 202.4706 47.189621 202.47077 47.189426 202.47117 47.189422 202.47138 47.189597 202.47154 47.189608 202.47186 47.189566 202.47195 47.189567 202.47192 47.189519 202.47184 47.189252 202.47184 47.189198 202.472 47.189139 202.47221 47.189129 202.47248 47.188998 202.47277 47.188894 202.47278 47.18889 202.47315 47.188939 202.47334 47.188939 202.4736 47.188801 202.47391 47.188704 202.47392 47.188702 202.47432 47.188655 202.47447 47.188613 202.47471 47.188759 202.475 47.188875 202.47497 47.18906 202.47478 47.189244 202.47475 47.189385 202.47506 47.189481 202.47517 47.189484 202.47549 47.189386 202.47563 47.189386 202.47583 47.189564 202.47609 47.189459 202.47644 47.189437 202.4765 47.189716 202.47626 47.189867 202.47587 47.189859 202.47578 47.189867 202.47572 47.189965 202.4759 47.189944 202.47624 47.189906 202.47647 47.19006 202.47642 47.190263 202.47624 47.190453 202.47624 47.190562 202.47645 47.190582 202.47674 47.190466 202.47658 47.190306 202.47653 47.190037 202.47679 47.189897 202.47705 47.189957 202.47709 47.190088 202.48222 47.193592 202.48217 47.193656 202.48234 47.193667 202.4823 47.193563 202.48222 47.193592 202.49228 47.200179 202.49228 47.200179 202.49228 47.200176 202.49228 47.200176 202.49228 47.200179 202.4719 47.18744 202.47161 47.187476 202.47136 47.187329 202.47139 47.187125 202.47166 47.187114 202.47187 47.18728 202.4719 47.18744 202.46143 47.181194 202.46112 47.181233 202.46106 47.18096 202.46145 47.180995 202.46143 47.181194 202.47885 47.192383 202.47857 47.192412 202.47836 47.192248 202.47837 47.192082 202.47866 47.192024 202.47884 47.192215 202.47885 47.192383 202.47557 47.190333 202.47519 47.190358 202.47515 47.190373 202.47515 47.19039 202.47521 47.190407 202.47555 47.190415 202.47564 47.190376 202.47566 47.190334 202.47557 47.190333 202.46105 47.181259 202.46067 47.181315 202.46057 47.181318 202.46019 47.181276 202.46017 47.181008 202.46058 47.180986 202.46061 47.18098 202.46105 47.18096 202.46105 47.181259 202.48355 47.195622 202.48341 47.195832 202.48315 47.19586 202.48319 47.195692 202.48334 47.19549 202.48369 47.195464 202.48355 47.195622 202.48127 47.194194 202.48113 47.194404 202.48075 47.194387 202.48063 47.194145 202.48059 47.19407 202.4807 47.194096 202.48104 47.194053 202.4812 47.194052 202.48127 47.194194 202.47904 47.192801 202.47896 47.192776 202.47896 47.192751 202.47905 47.192713 202.47904 47.192801 202.47745 47.191811 202.47712 47.191863 202.4772 47.191649 202.47737 47.191674 202.47745 47.191811 202.47967 47.193497 202.47931 47.193496 202.47918 47.193265 202.47918 47.193186 202.47932 47.193161 202.4796 47.193284 202.47967 47.193497 202.47626 47.191365 202.47623 47.191545 202.47655 47.191543 202.47645 47.191376 202.47626 47.191365 202.48914 47.19971 202.48895 47.19971 202.48895 47.19959 202.48912 47.199582 202.48914 47.19971 202.48432 47.196701 202.48411 47.196864 202.48389 47.19694 202.4837 47.196762 202.48367 47.196592 202.48397 47.196559 202.48416 47.196598 202.4843 47.196639 202.48432 47.196701 202.45965 47.181278 202.4593 47.181279 202.45931 47.181065 202.45961 47.18105 202.45965 47.181278 202.46851 47.187119 202.46809 47.187149 202.4681 47.186861 202.46849 47.186847 202.46851 47.187119 202.46001 47.181805 202.45992 47.181795 202.45992 47.181748 202.45999 47.181743 202.46001 47.181805 202.48472 47.197546 202.48447 47.197493 202.48417 47.197505 202.484 47.19751 202.48401 47.197405 202.48425 47.197252 202.48434 47.197258 202.48462 47.197381 202.48472 47.197546 202.4826 47.196221 202.48221 47.196235 202.48223 47.195993 202.48256 47.195971 202.4826 47.196221 202.47298 47.190213 202.47282 47.190158 202.47248 47.190086 202.47221 47.190031 202.47208 47.190053 202.4719 47.190137 202.4716 47.190249 202.47159 47.190414 202.47195 47.190462 202.47197 47.190457 202.47239 47.190443 202.47244 47.190442 202.47281 47.19049 202.47294 47.190486 202.47311 47.190293 202.47311 47.190269 202.47298 47.190213 202.48561 47.198405 202.48544 47.198402 202.48541 47.198276 202.48562 47.198265 202.48561 47.198405 202.48464 47.198098 202.48462 47.198358 202.48488 47.198491 202.4849 47.198558 202.48477 47.198567 202.48442 47.198555 202.48434 47.198563 202.48394 47.19853 202.48378 47.198326 202.48377 47.19815 202.48396 47.197971 202.48433 47.1979 202.48438 47.19788 202.48463 47.198022 202.48464 47.198098 202.46313 47.184649 202.46311 47.184646 202.4631 47.184634 202.46312 47.184635 202.46313 47.184649 202.49363 47.204008 202.49322 47.204043 202.49324 47.203765 202.49361 47.203754 202.49363 47.204008 202.48545 47.199199 202.48519 47.199339 202.48516 47.199585 202.48515 47.199611 202.48502 47.199827 202.48488 47.200043 202.48466 47.200204 202.4843 47.20022 202.48404 47.200083 202.48403 47.199812 202.48403 47.199766 202.48377 47.199635 202.48369 47.199597 202.4835 47.199506 202.48349 47.199473 202.48334 47.199301 202.48316 47.199108 202.48316 47.198969 202.48325 47.198725 202.4837 47.198711 202.48394 47.198858 202.48396 47.198866 202.48437 47.198866 202.4846 47.199024 202.48484 47.19917 202.48501 47.199227 202.48511 47.198987 202.48541 47.199072 202.48545 47.199199 202.48461 47.199571 202.48463 47.199647 202.48485 47.19972 202.48484 47.199491 202.48461 47.199571 202.49852 47.209458 202.49819 47.209475 202.49819 47.20925 202.4985 47.209248 202.49852 47.209458 202.48747 47.202556 202.48721 47.202694 202.48711 47.202695 202.4871 47.202627 202.48729 47.202444 202.48746 47.202439 202.48747 47.202556 202.48037 47.198716 202.48018 47.198709 202.48012 47.198566 202.48031 47.198615 202.48037 47.198716 202.46713 47.190741 202.46714 47.190778 202.46718 47.190773 202.46718 47.190747 202.46713 47.190741 202.47877 47.198917 202.47874 47.199118 202.47894 47.199301 202.47896 47.199332 202.47889 47.199339 202.47851 47.199293 202.47831 47.199116 202.47832 47.198935 202.47832 47.198781 202.47827 47.198605 202.47863 47.19855 202.47877 47.198772 202.47877 47.198917 202.48454 47.203419 202.48439 47.203626 202.48411 47.203613 202.484 47.203377 202.48433 47.20329 202.48455 47.203292 202.48454 47.203419 202.47679 47.199174 202.47678 47.19927 202.47679 47.199473 202.47683 47.199558 202.47688 47.199832 202.47688 47.199843 202.47693 47.200131 202.47701 47.200211 202.47678 47.200367 202.47661 47.200556 202.47653 47.200756 202.47671 47.200921 202.47632 47.200976 202.4764 47.201177 202.47662 47.201165 202.47673 47.200933 202.47674 47.200928 202.47686 47.200712 202.47708 47.200551 202.47738 47.200452 202.4774 47.200453 202.47739 47.200444 202.47743 47.200172 202.47758 47.199977 202.47725 47.199899 202.47693 47.199806 202.47703 47.199621 202.47705 47.199397 202.47704 47.199332 202.4769 47.199179 202.47679 47.199174 202.47985 47.203182 202.47985 47.203183 202.47985 47.203179 202.47985 47.20318 202.47985 47.203182 202.4781 47.203884 202.47798 47.203916 202.478 47.203822 202.47816 47.203782 202.4781 47.203884 202.48335 47.208058 202.48336 47.20807 202.48335 47.208361 202.48293 47.208393 202.4827 47.208236 202.48265 47.208219 202.48232 47.208314 202.48215 47.208315 202.48193 47.208154 202.48193 47.208072 202.4821 47.207874 202.48229 47.207698 202.48265 47.207621 202.48265 47.207621 202.48298 47.207705 202.4832 47.207863 202.48335 47.208058 202.47821 47.204852 202.47798 47.204886 202.47775 47.204737 202.47774 47.204557 202.47801 47.204544 202.47822 47.204711 202.47821 47.204852 202.47242 47.201532 202.47251 47.201774 202.47254 47.201906 202.47237 47.201875 202.47217 47.2017 202.47216 47.201666 202.4724 47.201517 202.47242 47.201513 202.47242 47.201532 202.47271 47.20231 202.47263 47.202333 202.47266 47.202281 202.4727 47.20228 202.47271 47.20231 202.4724 47.202714 202.47207 47.20281 202.47199 47.202808 202.47199 47.202757 202.47207 47.202507 202.47244 47.202478 202.4724 47.202714 202.48374 47.210096 202.48384 47.210323 202.48389 47.210493 202.48353 47.210566 202.48351 47.210564 202.48326 47.210426 202.4829 47.210363 202.48289 47.210167 202.48321 47.210132 202.48331 47.210132 202.48369 47.210069 202.48373 47.210077 202.48374 47.210096 202.47539 47.204884 202.47533 47.204895 202.47496 47.20491 202.47489 47.204894 202.47488 47.204863 202.47505 47.204668 202.4752 47.204668 202.4754 47.204843 202.47539 47.204884 202.47373 47.204142 202.47351 47.204303 202.47348 47.20431 202.47323 47.204171 202.47321 47.204118 202.4733 47.204115 202.47365 47.204094 202.47373 47.204127 202.47373 47.204142 202.47287 47.203909 202.47277 47.204145 202.47244 47.204104 202.47228 47.203897 202.47194 47.203926 202.47188 47.204184 202.47165 47.204338 202.47121 47.204361 202.47103 47.204168 202.47105 47.203965 202.47122 47.203772 202.47143 47.203606 202.47178 47.203524 202.472 47.203449 202.47211 47.203433 202.47248 47.203421 202.47267 47.203602 202.47295 47.203724 202.47287 47.203909 202.47581 47.206342 202.47554 47.206366 202.47531 47.206212 202.47533 47.206043 202.47561 47.205986 202.47588 47.206116 202.47581 47.206342 202.48457 47.212112 202.48434 47.212228 202.48448 47.212055 202.48457 47.212058 202.48457 47.212112 202.47539 47.206979 202.47526 47.207193 202.47485 47.207202 202.47482 47.206917 202.47492 47.206824 202.47496 47.206706 202.47514 47.206658 202.47539 47.206799 202.47539 47.206979 202.46957 47.203338 202.46952 47.203329 202.46952 47.20331 202.46957 47.203294 202.46957 47.203338 202.47323 47.205929 202.47303 47.205946 202.47304 47.205805 202.47322 47.205803 202.47323 47.205929 202.46896 47.203257 202.46867 47.203308 202.46878 47.203143 202.46897 47.203084 202.46896 47.203257 202.47897 47.21101 202.47882 47.211211 202.47865 47.211223 202.47865 47.211106 202.47893 47.210984 202.47898 47.210981 202.47897 47.21101 202.47693 47.210032 202.47676 47.21002 202.47678 47.209942 202.47687 47.209934 202.47693 47.210032 202.47051 47.207515 202.47046 47.207519 202.47046 47.207489 202.47049 47.20749 202.47051 47.207515 202.48083 47.215759 202.48047 47.215835 202.48033 47.215838 202.48007 47.215707 202.48007 47.215583 202.48024 47.215581 202.48042 47.215504 202.48081 47.215489 202.48083 47.215759 202.47199 47.211133 202.47186 47.211356 202.47143 47.211353 202.47128 47.211139 202.47101 47.211122 202.4709 47.211096 202.47089 47.211048 202.47115 47.210908 202.47115 47.210907 202.47145 47.211014 202.47175 47.210987 202.47192 47.210993 202.47199 47.211133 202.46765 47.21261 202.46776 47.212764 202.46777 47.212988 202.46757 47.213164 202.46718 47.213215 202.46709 47.213457 202.46677 47.21349 202.46662 47.213277 202.46654 47.213113 202.46674 47.21294 202.46679 47.212829 202.46681 47.212685 202.46702 47.212516 202.46723 47.212505 202.4675 47.212518 202.46762 47.212538 202.46765 47.21261 202.46316 47.209804 202.46291 47.209837 202.4629 47.209644 202.46317 47.209645 202.46316 47.209804 202.48108 47.168645 202.48089 47.168828 202.48053 47.168845 202.48026 47.16872 202.48024 47.168418 202.48046 47.168259 202.48089 47.168252 202.48106 47.168449 202.48108 47.168645 202.49361 47.177674 202.49322 47.17768 202.49322 47.177428 202.49359 47.177407 202.49361 47.177674 202.48957 47.179635 202.48927 47.179627 202.48925 47.179439 202.48952 47.179441 202.48957 47.179635 202.47704 47.172405 202.47703 47.172407 202.47703 47.172398 202.47705 47.172396 202.47704 47.172405 202.49564 47.184925 202.49527 47.184993 202.49522 47.18499 202.49519 47.184946 202.49531 47.18472 202.4956 47.184706 202.49564 47.184925 202.49722 47.188605 202.4969 47.188627 202.49692 47.188418 202.49721 47.188402 202.49722 47.188605 202.50459 47.194102 202.50445 47.194111 202.50445 47.194019 202.50458 47.194018 202.50459 47.194102 202.50477 47.194818 202.50439 47.19488 202.50431 47.194865 202.50419 47.19475 202.50413 47.194675 202.50422 47.194472 202.50441 47.19447 202.50471 47.19457 202.50477 47.194818 202.50379 47.194501 202.5035 47.194486 202.50352 47.194333 202.50371 47.19433 202.50379 47.194501 202.50587 47.196402 202.50576 47.196398 202.50575 47.196326 202.50587 47.196318 202.50587 47.196402 202.50778 47.198193 202.50759 47.198372 202.5075 47.198366 202.50746 47.198288 202.50774 47.198166 202.50777 47.198164 202.50778 47.198193 202.47228 47.179004 202.47207 47.179169 202.47179 47.179209 202.47159 47.179028 202.4716 47.178878 202.47192 47.178779 202.47193 47.178779 202.47232 47.178813 202.47228 47.179004 202.47525 47.182954 202.47508 47.18296 202.47508 47.182844 202.47524 47.182838 202.47525 47.182954 202.4968 47.197614 202.49661 47.19763 202.49662 47.197501 202.49679 47.197496 202.4968 47.197614 202.48131 47.192724 202.48122 47.192734 202.48123 47.192673 202.48137 47.192625 202.48131 47.192724 202.48068 47.19263 202.48049 47.192623 202.48045 47.192489 202.48064 47.192511 202.48068 47.19263 202.46134 47.181136 202.46124 47.181149 202.46122 47.181061 202.46134 47.181072 202.46134 47.181136 202.48261 47.194734 202.48247 47.194947 202.48222 47.194926 202.48219 47.194768 202.48247 47.194646 202.4827 47.194569 202.48261 47.194734 202.47504 47.190005 202.47492 47.190225 202.47455 47.190292 202.47443 47.190273 202.47436 47.190178 202.47435 47.190003 202.47439 47.189893 202.47464 47.18975 202.47469 47.18975 202.47507 47.189797 202.47504 47.190005 202.46101 47.181233 202.46065 47.181259 202.46065 47.181007 202.46101 47.180991 202.46101 47.181233 202.47369 47.189456 202.4737 47.189509 202.4737 47.189765 202.47351 47.189946 202.4732 47.190047 202.47299 47.190034 202.47282 47.189829 202.47255 47.189703 202.47232 47.189552 202.4723 47.189485 202.47242 47.189477 202.47273 47.189455 202.47298 47.189389 202.47306 47.189363 202.47339 47.189272 202.47362 47.18924 202.47369 47.189456 202.46055 47.181245 202.46025 47.181231 202.46024 47.181048 202.46051 47.181033 202.46055 47.181245 202.48091 47.19427 202.4809 47.19427 202.4809 47.194264 202.48091 47.194262 202.48091 47.19427 202.47697 47.192106 202.47677 47.19212 202.47648 47.192099 202.47657 47.192264 202.47657 47.192456 202.47625 47.1925 202.47619 47.192515 202.4758 47.192513 202.47566 47.192484 202.47538 47.192496 202.47508 47.19239 202.47502 47.192382 202.47501 47.192441 202.47526 47.192581 202.47554 47.192705 202.47554 47.192705 202.47595 47.192726 202.47619 47.192873 202.47637 47.192929 202.47652 47.192953 202.47681 47.193065 202.47705 47.193215 202.47731 47.193344 202.47752 47.193517 202.47776 47.193663 202.47791 47.193878 202.47819 47.193996 202.47823 47.194091 202.47823 47.194295 202.47828 47.194418 202.47837 47.194513 202.47839 47.194787 202.47813 47.194926 202.47777 47.194961 202.47772 47.194969 202.47751 47.195138 202.47751 47.195153 202.47748 47.195419 202.47725 47.195574 202.47703 47.195504 202.47666 47.195502 202.47675 47.195713 202.47687 47.195932 202.47686 47.195958 202.47673 47.196143 202.47645 47.19626 202.47644 47.196263 202.47611 47.196357 202.47588 47.196513 202.47574 47.196723 202.47574 47.196783 202.47595 47.196953 202.47613 47.196964 202.47641 47.196939 202.47657 47.19694 202.47677 47.197002 202.47701 47.197149 202.47706 47.197251 202.47698 47.197496 202.47698 47.197497 202.47708 47.197747 202.47709 47.197867 202.47679 47.197961 202.47677 47.197965 202.47677 47.197975 202.477 47.198127 202.47716 47.19834 202.47718 47.198524 202.47712 47.198696 202.47726 47.198872 202.477 47.198777 202.47674 47.198846 202.47644 47.198956 202.47647 47.199175 202.47646 47.199269 202.47646 47.199507 202.47649 47.199584 202.47644 47.199846 202.47644 47.199852 202.47632 47.200079 202.47618 47.200286 202.4761 47.200424 202.47604 47.2005 202.47594 47.200739 202.4757 47.200719 202.47557 47.200509 202.47557 47.20049 202.47555 47.200492 202.47523 47.200592 202.47493 47.200706 202.47472 47.200875 202.47455 47.201065 202.47428 47.201114 202.47435 47.200942 202.47433 47.20075 202.47428 47.200595 202.47458 47.200572 202.47474 47.200587 202.47472 47.200463 202.47452 47.200448 202.47432 47.200438 202.47407 47.200294 202.47384 47.20014 202.47375 47.199966 202.47382 47.19983 202.47389 47.199754 202.47384 47.199488 202.47381 47.199406 202.47384 47.199165 202.47348 47.199202 202.47323 47.199346 202.47297 47.199482 202.47297 47.199483 202.47297 47.199478 202.47287 47.199227 202.47265 47.19928 202.47238 47.199411 202.47241 47.199573 202.47248 47.199775 202.47248 47.199842 202.47241 47.200026 202.47218 47.20018 202.472 47.200368 202.47183 47.200561 202.47153 47.200673 202.47132 47.20084 202.47114 47.200833 202.47104 47.200665 202.47099 47.20062 202.47092 47.200345 202.47064 47.200224 202.4704 47.200078 202.47005 47.200008 202.46982 47.199856 202.46976 47.199865 202.46974 47.199916 202.46992 47.200107 202.46986 47.200227 202.46971 47.200433 202.46949 47.200424 202.46924 47.200442 202.46929 47.200575 202.46948 47.200593 202.46973 47.20057 202.47003 47.200635 202.4701 47.200626 202.47047 47.200675 202.47073 47.200809 202.47082 47.201068 202.4708 47.201117 202.47063 47.201306 202.4707 47.201485 202.47071 47.201658 202.47037 47.201744 202.47035 47.20174 202.47028 47.201689 202.47017 47.201551 202.46995 47.201383 202.46979 47.201382 202.4696 47.20132 202.46932 47.201202 202.4691 47.20104 202.46899 47.200884 202.46902 47.200776 202.46881 47.200604 202.46847 47.200529 202.46833 47.200305 202.46814 47.200351 202.46791 47.20029 202.46768 47.200136 202.46743 47.199993 202.46723 47.199814 202.46696 47.199689 202.46669 47.199563 202.46646 47.19941 202.46617 47.199298 202.46591 47.199164 202.4657 47.198998 202.46543 47.198866 202.46519 47.198724 202.46495 47.198572 202.46475 47.198398 202.46452 47.198243 202.46428 47.19809 202.46402 47.197957 202.46378 47.197812 202.46357 47.197642 202.46335 47.197476 202.46315 47.197298 202.46292 47.197143 202.46272 47.19697 202.46269 47.196944 202.46259 47.196737 202.46237 47.196743 202.46221 47.196694 202.46213 47.196597 202.46214 47.196417 202.46195 47.196235 202.46183 47.196109 202.46179 47.196027 202.46189 47.195843 202.46203 47.195636 202.46202 47.195531 202.46194 47.19528 202.46194 47.195267 202.46188 47.195244 202.46162 47.195181 202.46163 47.195083 202.46185 47.194922 202.46183 47.1947 202.46177 47.194577 202.46207 47.194461 202.46219 47.194433 202.46238 47.194355 202.46239 47.194282 202.46232 47.194018 202.46232 47.194013 202.46248 47.193819 202.46275 47.19369 202.46276 47.193686 202.46287 47.193763 202.46298 47.193851 202.46317 47.194034 202.46323 47.194289 202.46324 47.19431 202.46346 47.194473 202.46369 47.194625 202.46372 47.194892 202.46374 47.194916 202.46375 47.194917 202.46399 47.194763 202.46398 47.194737 202.46375 47.194584 202.46364 47.194338 202.46364 47.19425 202.46374 47.194013 202.46389 47.193827 202.46358 47.193732 202.46357 47.193603 202.46371 47.193633 202.46397 47.193555 202.46405 47.193386 202.46406 47.193315 202.46427 47.193145 202.4643 47.192875 202.4643 47.192863 202.46453 47.192706 202.46464 47.192478 202.46494 47.192399 202.46498 47.192392 202.46522 47.192243 202.46523 47.192187 202.46517 47.191911 202.46517 47.191904 202.46536 47.191732 202.46558 47.191568 202.46581 47.191417 202.46586 47.191398 202.46613 47.191522 202.46637 47.191464 202.46657 47.191293 202.4667 47.191104 202.4667 47.191074 202.46674 47.191074 202.46714 47.191098 202.46739 47.191239 202.46763 47.191388 202.46772 47.19141 202.46771 47.191333 202.46758 47.191102 202.4676 47.191037 202.46762 47.19075 202.46762 47.190747 202.46775 47.190529 202.46795 47.190501 202.4681 47.190453 202.46841 47.190485 202.46863 47.190651 202.46869 47.190822 202.46868 47.190938 202.46886 47.19113 202.46911 47.191086 202.46931 47.190906 202.46945 47.190697 202.46945 47.190696 202.46936 47.190439 202.4693 47.190301 202.46949 47.190124 202.4698 47.190017 202.46998 47.18998 202.4702 47.18997 202.47039 47.19 202.47076 47.190051 202.47074 47.190305 202.47077 47.190373 202.47095 47.190563 202.47127 47.19064 202.47129 47.19064 202.47163 47.190563 202.47183 47.190567 202.47216 47.190643 202.47217 47.1909 202.47195 47.191063 202.47197 47.191112 202.47201 47.191102 202.47239 47.191036 202.47251 47.191039 202.47277 47.190976 202.47303 47.19098 202.47332 47.191092 202.47339 47.191064 202.47344 47.191001 202.47353 47.190853 202.47365 47.190849 202.47394 47.190957 202.47416 47.191121 202.47445 47.191231 202.47471 47.191364 202.47496 47.191447 202.47504 47.191448 202.47513 47.191556 202.47522 47.191634 202.4753 47.191661 202.47555 47.191716 202.47588 47.1918 202.47616 47.191916 202.47626 47.191963 202.47646 47.191786 202.47671 47.191839 202.47693 47.191998 202.47697 47.192106 202.45955 47.181214 202.45939 47.181215 202.45939 47.181117 202.45953 47.18111 202.45955 47.181214 202.46844 47.187076 202.46816 47.187096 202.46817 47.186903 202.46843 47.186894 202.46844 47.187076 202.4825 47.19616 202.4823 47.196167 202.48231 47.196043 202.48248 47.196032 202.4825 47.19616 202.47002 47.188661 202.47 47.188663 202.47 47.188649 202.47002 47.188647 202.47002 47.188661 202.48138 47.196057 202.48111 47.196069 202.48115 47.195912 202.48133 47.195909 202.48138 47.196057 202.48087 47.195742 202.48063 47.19577 202.48067 47.195617 202.48083 47.195626 202.48087 47.195742 202.4797 47.195008 202.47945 47.19515 202.47933 47.195106 202.47927 47.195039 202.47951 47.194889 202.47961 47.194903 202.4797 47.195008 202.47107 47.189615 202.47091 47.189619 202.47093 47.18953 202.47103 47.189529 202.47107 47.189615 202.49359 47.203984 202.49326 47.204012 202.49327 47.203788 202.49357 47.20378 202.49359 47.203984 202.48423 47.198136 202.48392 47.198222 202.48408 47.198048 202.48418 47.198031 202.48423 47.198136 202.48135 47.19634 202.48137 47.196526 202.4817 47.196607 202.48192 47.19677 202.4822 47.196892 202.48222 47.197183 202.48201 47.197347 202.48162 47.197407 202.48177 47.197531 202.48178 47.197802 202.48136 47.197837 202.48113 47.197684 202.48099 47.197458 202.48097 47.197297 202.48119 47.197136 202.48126 47.196938 202.48125 47.196874 202.48118 47.196672 202.48104 47.196446 202.48104 47.196445 202.48115 47.196214 202.48136 47.196213 202.48135 47.19634 202.48046 47.195783 202.48016 47.195894 202.48016 47.196119 202.48035 47.196303 202.48035 47.196315 202.48035 47.196615 202.48008 47.196743 202.47976 47.196743 202.4795 47.196606 202.47943 47.196338 202.47967 47.196189 202.4797 47.196135 202.47966 47.195879 202.47968 47.195825 202.47955 47.195814 202.47927 47.195802 202.47932 47.19567 202.47944 47.195443 202.47965 47.195278 202.47998 47.195278 202.4801 47.195515 202.4804 47.195617 202.48046 47.195783 202.47866 47.19466 202.47859 47.194676 202.47858 47.19461 202.47868 47.194614 202.47866 47.19466 202.48422 47.198431 202.48408 47.198429 202.48392 47.198242 202.48426 47.1983 202.48422 47.198431 202.4845 47.199206 202.48431 47.199387 202.48402 47.199449 202.48407 47.199238 202.48437 47.199124 202.48444 47.199138 202.4845 47.199206 202.47873 47.195602 202.47868 47.195585 202.47868 47.19557 202.4787 47.195572 202.47873 47.195602 202.48394 47.199152 202.48391 47.199207 202.48396 47.199468 202.48362 47.199423 202.48344 47.199226 202.48335 47.199086 202.48327 47.199026 202.48328 47.198739 202.48368 47.198726 202.48389 47.198896 202.48394 47.199152 202.47788 47.195368 202.47767 47.19536 202.47757 47.195177 202.47785 47.195228 202.47788 47.195368 202.47913 47.196446 202.47885 47.196438 202.47871 47.196218 202.4787 47.196179 202.47881 47.19614 202.47914 47.196222 202.47913 47.196446 202.47779 47.195612 202.47758 47.195781 202.47745 47.195998 202.47725 47.195992 202.47689 47.195935 202.47695 47.195683 202.47731 47.195626 202.47747 47.195707 202.47775 47.195584 202.47782 47.195575 202.47779 47.195612 202.47099 47.191359 202.47084 47.191569 202.47084 47.191619 202.47089 47.1916 202.47134 47.191578 202.47134 47.191578 202.47134 47.191578 202.47113 47.191404 202.47099 47.191359 202.46853 47.18982 202.46844 47.189818 202.46844 47.189765 202.46864 47.189666 202.46853 47.18982 202.48453 47.200124 202.48442 47.200129 202.48428 47.199965 202.48461 47.199992 202.48453 47.200124 202.49845 47.209413 202.49826 47.209423 202.49826 47.209296 202.49844 47.209294 202.49845 47.209413 202.46782 47.190276 202.46782 47.190276 202.46782 47.190275 202.46782 47.190275 202.46782 47.190276 202.47557 47.197212 202.47514 47.197224 202.47511 47.197227 202.47474 47.197292 202.4748 47.197482 202.47478 47.197618 202.4747 47.197867 202.47467 47.197901 202.47487 47.198077 202.47501 47.198061 202.47501 47.197975 202.47504 47.197783 202.47507 47.197602 202.47504 47.197483 202.47524 47.197481 202.47541 47.19768 202.47542 47.197721 202.47544 47.197983 202.47544 47.198031 202.47549 47.198273 202.4755 47.198367 202.47558 47.198529 202.47576 47.198532 202.47572 47.198427 202.47571 47.198199 202.47603 47.198195 202.47618 47.198194 202.4762 47.198071 202.47598 47.19791 202.47568 47.197807 202.47568 47.197586 202.47601 47.197488 202.47587 47.197338 202.47561 47.197205 202.47557 47.197212 202.48427 47.20355 202.4842 47.203547 202.48417 47.203486 202.48431 47.203465 202.48427 47.20355 202.47626 47.198541 202.4763 47.198648 202.47642 47.198645 202.47654 47.198472 202.47626 47.198541 202.47769 47.199736 202.47746 47.199741 202.47745 47.19959 202.47766 47.199598 202.47769 47.199736 202.47873 47.200686 202.47836 47.2007 202.47823 47.200472 202.47821 47.20036 202.47837 47.20037 202.47871 47.200447 202.47873 47.200686 202.4747 47.199063 202.47476 47.199132 202.47479 47.199123 202.47479 47.199109 202.4747 47.199063 202.47383 47.198823 202.47377 47.198889 202.47387 47.198843 202.47387 47.198819 202.47383 47.198823 202.47433 47.199431 202.47428 47.199486 202.47419 47.199643 202.47429 47.199805 202.47455 47.199939 202.47462 47.199911 202.47461 47.199893 202.47448 47.199665 202.47438 47.199462 202.47437 47.199423 202.47433 47.199431 202.4648 47.193473 202.46479 47.193485 202.46481 47.193481 202.46481 47.193472 202.4648 47.193473 202.47743 47.201666 202.47744 47.201707 202.47765 47.201879 202.47783 47.202072 202.4779 47.202262 202.47795 47.202306 202.47795 47.202593 202.47758 47.202663 202.47739 47.20272 202.47709 47.202621 202.47698 47.202371 202.47696 47.202275 202.47685 47.202142 202.47662 47.201986 202.4764 47.201824 202.4764 47.201625 202.47671 47.201517 202.47687 47.201318 202.47715 47.201271 202.47742 47.2014 202.47743 47.201666 202.4765 47.202282 202.47623 47.202277 202.47612 47.202049 202.47652 47.202061 202.4765 47.202282 202.47782 47.203407 202.47777 47.203414 202.47776 47.203373 202.47784 47.203366 202.47782 47.203407 202.47479 47.201515 202.47459 47.201534 202.47436 47.201384 202.4743 47.201207 202.47455 47.201243 202.47479 47.201388 202.47479 47.201515 202.47405 47.201349 202.47393 47.201375 202.47377 47.201179 202.47408 47.201264 202.47405 47.201349 202.47309 47.200749 202.47295 47.200963 202.47266 47.201014 202.47277 47.200849 202.47298 47.200686 202.47311 47.200682 202.47309 47.200749 202.47368 47.201419 202.47348 47.201378 202.47351 47.201312 202.47376 47.201175 202.47368 47.201419 202.47588 47.203095 202.47556 47.203099 202.47556 47.202895 202.47591 47.202837 202.47588 47.203095 202.48329 47.208324 202.48299 47.208347 202.48274 47.208201 202.48248 47.208118 202.48239 47.20814 202.48236 47.208041 202.48237 47.207824 202.48241 47.207774 202.48245 47.207765 202.48276 47.207863 202.48309 47.207946 202.4833 47.208116 202.48329 47.208324 202.4713 47.201127 202.47116 47.201144 202.47111 47.201009 202.47137 47.200989 202.4713 47.201127 202.47519 47.20386 202.47498 47.203851 202.47498 47.203728 202.47516 47.203718 202.47519 47.20386 202.46816 47.199763 202.4681 47.199828 202.4682 47.199792 202.46818 47.199766 202.46816 47.199763 202.46119 47.195708 202.46108 47.1959 202.46109 47.195947 202.46105 47.195926 202.46078 47.195802 202.46045 47.195716 202.46045 47.195541 202.46078 47.195451 202.46082 47.195445 202.46113 47.195538 202.46119 47.195708 202.48306 47.210271 202.48303 47.210267 202.48303 47.210253 202.48305 47.210251 202.48306 47.210271 202.47174 47.204096 202.47152 47.20426 202.47133 47.20427 202.47123 47.20408 202.47124 47.204009 202.47134 47.203849 202.47161 47.203741 202.47173 47.203972 202.47174 47.204096 202.47529 47.206911 202.4752 47.207157 202.4749 47.207164 202.47488 47.206955 202.47521 47.206866 202.47529 47.206879 202.47529 47.206911 202.48079 47.215737 202.48042 47.215778 202.48045 47.215525 202.48078 47.215512 202.48079 47.215737 202.47182 47.211327 202.47147 47.211324 202.47142 47.211081 202.47182 47.211064 202.47182 47.211327 202.46766 47.21292 202.4675 47.213117 202.46724 47.213145 202.46698 47.213093 202.46685 47.213108 202.46688 47.213028 202.467 47.212807 202.46717 47.212611 202.46753 47.212608 202.46766 47.212838 202.46766 47.21292 202.46698 47.213393 202.46689 47.213403 202.46685 47.213308 202.46701 47.213316 202.46698 47.213393 202.48103 47.168616 202.48087 47.168811 202.48055 47.168826 202.48026 47.168717 202.48024 47.168421 202.48047 47.168266 202.48088 47.168259 202.48102 47.168481 202.48103 47.168616 202.49358 47.177657 202.49325 47.177663 202.49324 47.177443 202.49357 47.177425 202.49358 47.177657 202.49552 47.184852 202.49538 47.184874 202.49541 47.18478 202.49551 47.184776 202.49552 47.184852 202.49716 47.188564 202.49697 47.188576 202.49698 47.188456 202.49715 47.188446 202.49716 47.188564 202.50469 47.194765 202.50442 47.194788 202.50436 47.194559 202.50465 47.194614 202.50469 47.194765 202.50365 47.194412 202.50361 47.19441 202.50361 47.194389 202.50364 47.194388 202.50365 47.194412 202.47218 47.178937 202.47195 47.179097 202.47194 47.1791 202.47191 47.179069 202.47214 47.178917 202.47218 47.17892 202.47218 47.178937 202.47517 47.182901 202.47516 47.182901 202.47516 47.182894 202.47517 47.182894 202.47517 47.182901 202.49673 47.197569 202.49669 47.197573 202.49669 47.197545 202.49673 47.197544 202.49673 47.197569 202.46097 47.181206 202.46069 47.181226 202.4607 47.181035 202.46097 47.181022 202.46097 47.181206 202.47477 47.190132 202.4746 47.190144 202.47459 47.190021 202.47479 47.190001 202.47477 47.190132 202.46047 47.181194 202.46031 47.181186 202.4603 47.181088 202.46045 47.18108 202.46047 47.181194 202.47334 47.18984 202.47319 47.189881 202.47311 47.189694 202.47338 47.189742 202.47334 47.18984 202.46837 47.187033 202.46823 47.187043 202.46823 47.186945 202.46837 47.186941 202.46837 47.187033 202.4824 47.196098 202.48239 47.196099 202.48239 47.196093 202.4824 47.196092 202.4824 47.196098 202.47637 47.192332 202.47606 47.192434 202.4759 47.192434 202.47555 47.192369 202.47544 47.192348 202.47518 47.192316 202.47484 47.192273 202.47476 47.192521 202.47483 47.192578 202.47486 47.192584 202.47517 47.192652 202.47541 47.192797 202.47567 47.19293 202.47586 47.192911 202.47609 47.192946 202.47643 47.19302 202.47665 47.193183 202.47684 47.193368 202.47709 47.193511 202.47728 47.193693 202.47736 47.193846 202.47738 47.193949 202.47739 47.194163 202.4771 47.19428 202.47705 47.194517 202.47731 47.194412 202.47768 47.194373 202.47783 47.194592 202.47782 47.194732 202.47755 47.194797 202.47749 47.194823 202.47708 47.194816 202.477 47.194548 202.47672 47.194432 202.47647 47.194486 202.47645 47.194631 202.47653 47.194821 202.47656 47.194877 202.47669 47.195108 202.47669 47.19522 202.47646 47.195377 202.47643 47.195626 202.47644 47.195667 202.47637 47.195665 202.47595 47.195657 202.4761 47.195869 202.47616 47.19609 202.47578 47.196147 202.47569 47.196174 202.47539 47.196208 202.47546 47.196337 202.47543 47.19653 202.47532 47.19676 202.47532 47.19677 202.47525 47.197016 202.47495 47.197043 202.47486 47.197071 202.47454 47.19717 202.47442 47.197392 202.47439 47.197453 202.47455 47.197665 202.47454 47.197765 202.47428 47.197865 202.47421 47.197863 202.47401 47.198034 202.47399 47.198074 202.47397 47.19831 202.47369 47.198299 202.4735 47.198318 202.47318 47.198416 202.47321 47.198653 202.47318 47.198716 202.47308 47.198951 202.47282 47.198941 202.4726 47.198952 202.47246 47.199162 202.47213 47.199255 202.47206 47.199502 202.47206 47.199511 202.47185 47.199675 202.47173 47.199903 202.47169 47.200098 202.47167 47.200163 202.47157 47.200403 202.47125 47.200426 202.47126 47.200205 202.47137 47.200011 202.4713 47.199933 202.47122 47.199796 202.4711 47.199809 202.47074 47.199828 202.47051 47.199737 202.47044 47.19972 202.47004 47.199695 202.46985 47.199512 202.46964 47.199494 202.46956 47.19972 202.46956 47.199743 202.4695 47.200002 202.4694 47.200166 202.46938 47.200231 202.4693 47.200236 202.46908 47.200079 202.46871 47.200025 202.46872 47.199814 202.46888 47.199618 202.46894 47.19953 202.46879 47.199561 202.46851 47.199686 202.46828 47.199689 202.46798 47.199652 202.46788 47.199662 202.46752 47.199606 202.46727 47.199466 202.46722 47.199474 202.46698 47.199624 202.46674 47.199526 202.46651 47.19937 202.46621 47.199271 202.46594 47.199143 202.46573 47.198972 202.46546 47.198846 202.46521 47.198705 202.46499 47.198547 202.46482 47.198341 202.46457 47.198206 202.46434 47.19805 202.46409 47.197909 202.46383 47.197775 202.46363 47.197594 202.46344 47.197415 202.46343 47.197405 202.46328 47.197208 202.4632 47.196966 202.4632 47.196937 202.46302 47.196854 202.46293 47.196811 202.46293 47.196793 202.46285 47.196545 202.46262 47.196393 202.46241 47.196224 202.46231 47.196109 202.46228 47.19599 202.46235 47.195833 202.46238 47.195591 202.46238 47.195553 202.46249 47.195511 202.46265 47.195426 202.46265 47.195396 202.46258 47.195383 202.46228 47.195345 202.46225 47.19517 202.46229 47.195006 202.46211 47.194816 202.46211 47.194785 202.46215 47.194513 202.4625 47.194432 202.46256 47.194172 202.46295 47.194194 202.46299 47.194442 202.46271 47.194565 202.46271 47.194699 202.46296 47.194717 202.46314 47.194535 202.4633 47.194585 202.46334 47.194657 202.46343 47.194814 202.4636 47.195017 202.46394 47.195031 202.46419 47.194891 202.46412 47.194636 202.46401 47.194479 202.46399 47.194403 202.46399 47.194167 202.46405 47.194035 202.4641 47.193937 202.4642 47.193697 202.46445 47.193737 202.46466 47.193906 202.46469 47.194006 202.46478 47.194142 202.46488 47.194125 202.46512 47.193972 202.46509 47.193917 202.46506 47.193636 202.46519 47.19352 202.46524 47.193449 202.46528 47.193447 202.46565 47.1935 202.46586 47.19354 202.46609 47.1935 202.46628 47.193506 202.46627 47.193371 202.46627 47.1932 202.46623 47.193073 202.46629 47.192908 202.46656 47.192831 202.46662 47.192819 202.46663 47.192776 202.46666 47.192545 202.46663 47.192451 202.46664 47.192232 202.46685 47.192063 202.46693 47.191907 202.46661 47.191821 202.46654 47.191574 202.46675 47.191403 202.46698 47.19125 202.46731 47.191297 202.46752 47.191468 202.46759 47.191629 202.46742 47.191819 202.46741 47.191878 202.4675 47.191874 202.46778 47.191751 202.46806 47.191625 202.46817 47.191641 202.46848 47.19159 202.46872 47.19156 202.46879 47.19178 202.46879 47.191832 202.46886 47.191823 202.46923 47.191837 202.46945 47.191993 202.46956 47.191962 202.46985 47.191845 202.47007 47.191861 202.47032 47.192001 202.47053 47.191972 202.47074 47.191803 202.47106 47.191705 202.47117 47.191699 202.47149 47.191675 202.47149 47.191467 202.47139 47.191314 202.47171 47.191212 202.47182 47.191221 202.4721 47.191158 202.47238 47.191136 202.47251 47.191115 202.4729 47.191077 202.47302 47.191311 202.47322 47.191261 202.4736 47.191205 202.47363 47.191216 202.47393 47.191293 202.47422 47.191285 202.47434 47.191313 202.47463 47.191422 202.47491 47.191542 202.47511 47.19172 202.47542 47.191814 202.47572 47.191921 202.47572 47.191921 202.47606 47.191992 202.47628 47.192159 202.47637 47.192332 202.49355 47.20396 202.4933 47.203982 202.49331 47.203811 202.49354 47.203805 202.49355 47.20396 202.47384 47.191644 202.47382 47.191693 202.47387 47.191667 202.47388 47.191649 202.47384 47.191644 202.48221 47.197173 202.48195 47.197312 202.4816 47.197334 202.48143 47.197136 202.48145 47.196998 202.48157 47.196776 202.48187 47.196811 202.48218 47.196903 202.48221 47.197173 202.47967 47.195589 202.47956 47.195588 202.47958 47.19553 202.47968 47.195503 202.47967 47.195589 202.47827 47.194713 202.47804 47.19476 202.47801 47.194554 202.47826 47.194594 202.47827 47.194713 202.4764 47.193544 202.47611 47.19358 202.47587 47.193516 202.47577 47.193505 202.47539 47.193467 202.4752 47.193395 202.47532 47.193514 202.47532 47.193771 202.47495 47.193788 202.47488 47.193794 202.47488 47.193838 202.47494 47.193832 202.47534 47.193826 202.47558 47.193974 202.47567 47.193984 202.47577 47.193836 202.47581 47.193772 202.47587 47.19376 202.47623 47.193738 202.47632 47.193754 202.47632 47.193794 202.47625 47.194047 202.4763 47.194093 202.47647 47.194187 202.47677 47.194072 202.4769 47.193859 202.47688 47.193664 202.47665 47.19351 202.4764 47.193544 202.47205 47.190829 202.47181 47.190905 202.47182 47.190681 202.47205 47.190724 202.47205 47.190829 202.47165 47.190876 202.47146 47.19084 202.47147 47.190763 202.47161 47.190726 202.47165 47.190876 202.48029 47.196577 202.48 47.196692 202.47983 47.196693 202.47955 47.196569 202.47951 47.196383 202.4798 47.196268 202.47998 47.196251 202.48029 47.196352 202.48029 47.196577 202.4727 47.191833 202.47271 47.191864 202.47277 47.191876 202.47274 47.191844 202.4727 47.191833 202.47096 47.190746 202.47103 47.190829 202.47096 47.191043 202.4707 47.191178 202.47052 47.191363 202.47029 47.191521 202.47006 47.191545 202.47005 47.191374 202.47011 47.191182 202.4698 47.191213 202.46965 47.19142 202.46958 47.191578 202.46959 47.191681 202.46942 47.191697 202.46918 47.191547 202.4692 47.191441 202.46935 47.191231 202.46961 47.191093 202.46959 47.190917 202.46963 47.190808 202.46973 47.190572 202.46999 47.190439 202.47034 47.190354 202.47036 47.19035 202.47063 47.190477 202.47084 47.190647 202.47096 47.190746 202.48387 47.19911 202.48354 47.199155 202.4833 47.199009 202.4833 47.198753 202.48366 47.198742 202.48384 47.198935 202.48387 47.19911 202.48174 47.19778 202.4814 47.197808 202.48123 47.197607 202.48118 47.19743 202.48146 47.197436 202.48174 47.197558 202.48174 47.19778 202.47729 47.195 202.47727 47.195002 202.47725 47.194976 202.47735 47.19494 202.47729 47.195 202.48379 47.199357 202.48372 47.199348 202.48365 47.199275 202.48377 47.199306 202.48379 47.199357 202.47565 47.194571 202.47565 47.194575 202.47563 47.19486 202.47551 47.195005 202.4758 47.195112 202.47598 47.195304 202.47621 47.195221 202.47617 47.195163 202.4761 47.194891 202.47609 47.19485 202.47593 47.194692 202.47565 47.19457 202.47565 47.194571 202.49838 47.209369 202.49833 47.209371 202.49833 47.209341 202.49838 47.209341 202.49838 47.209369 202.46816 47.190791 202.46799 47.190798 202.46803 47.190705 202.46817 47.190667 202.46816 47.190791 202.46842 47.191251 202.46823 47.191269 202.46809 47.191048 202.46809 47.191046 202.4681 47.191046 202.46842 47.19113 202.46842 47.191251 202.47674 47.197349 202.47674 47.19735 202.47673 47.197344 202.47674 47.197344 202.47674 47.197349 202.47608 47.197233 202.47602 47.197227 202.47599 47.197179 202.47608 47.197183 202.47608 47.197233 202.46612 47.192504 202.46612 47.192506 202.46599 47.192725 202.46572 47.192798 202.46546 47.192664 202.46547 47.192395 202.46567 47.192222 202.46597 47.192293 202.46612 47.192504 202.47868 47.200654 202.47841 47.200664 202.47833 47.200438 202.47866 47.200481 202.47868 47.200654 202.47624 47.199133 202.47602 47.199293 202.47587 47.199496 202.47591 47.199586 202.47587 47.199797 202.47563 47.199947 202.47533 47.200013 202.47516 47.199814 202.47509 47.19961 202.47533 47.19946 202.4755 47.199265 202.47571 47.199095 202.47601 47.198989 202.47623 47.199022 202.47624 47.199133 202.47546 47.199242 202.47506 47.199237 202.47517 47.199058 202.47532 47.199044 202.47546 47.199242 202.466 47.19333 202.46591 47.193311 202.46573 47.193157 202.46599 47.193254 202.466 47.19333 202.46569 47.193137 202.46533 47.193086 202.46512 47.19308 202.46495 47.193042 202.46487 47.192922 202.46483 47.192807 202.46487 47.192622 202.46512 47.19259 202.46543 47.192691 202.46563 47.19287 202.46569 47.193137 202.46587 47.193843 202.46592 47.193952 202.46619 47.194077 202.46623 47.194068 202.4663 47.194002 202.46616 47.193774 202.46587 47.193843 202.46442 47.193536 202.46421 47.193589 202.46429 47.193454 202.46443 47.193431 202.46442 47.193536 202.47723 47.201841 202.47719 47.201896 202.47744 47.202032 202.47772 47.202154 202.47792 47.202334 202.47791 47.20257 202.47755 47.202602 202.47728 47.202474 202.4771 47.202285 202.47697 47.202054 202.47676 47.201885 202.4765 47.201756 202.4765 47.201683 202.47664 47.201647 202.47684 47.201597 202.47718 47.201577 202.47723 47.201841 202.47127 47.198121 202.47126 47.198138 202.47129 47.19813 202.47137 47.198058 202.47127 47.198121 202.4764 47.202223 202.47631 47.202221 202.47627 47.20214 202.47641 47.202144 202.4764 47.202223 202.47038 47.199057 202.47034 47.199149 202.47035 47.19934 202.47041 47.19942 202.47066 47.199533 202.47052 47.199336 202.47052 47.199143 202.47046 47.199055 202.47038 47.199057 202.47579 47.20304 202.47564 47.203042 202.47564 47.202942 202.47581 47.202914 202.47579 47.20304 202.47095 47.200011 202.47094 47.200008 202.47089 47.199976 202.47097 47.199981 202.47095 47.200011 202.48323 47.208287 202.48305 47.208301 202.48279 47.208167 202.48271 47.20796 202.48304 47.207985 202.48324 47.208161 202.48323 47.208287 202.46405 47.1963 202.46405 47.19631 202.46407 47.196313 202.46407 47.196293 202.46405 47.1963 202.46374 47.196702 202.46381 47.196811 202.46391 47.196811 202.46392 47.196735 202.46374 47.196702 202.47 47.200916 202.46992 47.20108 202.46996 47.201192 202.46979 47.201181 202.46957 47.201244 202.46937 47.201167 202.46915 47.201001 202.46913 47.20097 202.46922 47.20095 202.46956 47.200936 202.46971 47.200731 202.46994 47.200741 202.47 47.200916 202.46824 47.200113 202.46798 47.200241 202.46815 47.200059 202.46825 47.200037 202.46824 47.200113 202.46071 47.195708 202.46052 47.195662 202.46052 47.195589 202.46067 47.195551 202.46071 47.195708 202.47514 47.207121 202.47495 47.207126 202.47494 47.206992 202.47519 47.206947 202.47514 47.207121 202.48076 47.215715 202.48046 47.215748 202.48049 47.215545 202.48074 47.215535 202.48076 47.215715 202.47177 47.211297 202.47151 47.211295 202.47148 47.211113 202.47177 47.2111 202.47177 47.211297 202.46755 47.212847 202.46717 47.212875 202.46725 47.212661 202.46746 47.212659 202.46755 47.212847 202.46742 47.21307 202.46733 47.213081 202.4672 47.212929 202.46751 47.212947 202.46742 47.21307 green 1 4 block 5 linear 1000 zscale -1 66.151 -1 15.7877 32.5755 49.3632 66.151 ������������������������������������������������������������������������������������./saods9/tests/xpa/smooth.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000016�11232370251�015051� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no gaussian 3 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/grid.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000360�11756512443�014503� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no analysis wcs fk5 sexagesimal yes blue 1 0 yes red 1 0 interior lll yes white 1 0 yes blue 1 0 yes helvetica normal roman 10 green interior 0 yes yes helvetica normal roman 12 black yes yes yes helvetica normal roman 10 black ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/data.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000001373�11232370250�014457� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������178 167 181 170 188 179 170 182 182 903,1043 = 178 901,1041 = 179 899,1041 = 170 903,1039 = 188 903,1041 = 182 901,1043 = 182 899,1043 = 170 901,1039 = 181 899,1039 = 167 178 170 178 155 182 161 181 179 182 168 170 172 172 188 167 183 202.470721097,47.196698184 = 178 202.470790293,47.1968910411 = 170 202.470671024,47.196816497 = 178 202.470556536,47.1968197453 = 155 202.470725878,47.1967759765 = 182 202.47061139,47.1967792249 = 161 202.470840366,47.196772728 = 181 202.470785512,47.1968132486 = 179 202.470730658,47.1968537691 = 182 202.470666243,47.1967387045 = 168 202.470845146,47.1968505206 = 170 202.470735439,47.1969315616 = 172 202.47061617,47.1968570175 = 172 202.470780731,47.196735456 = 188 202.4709,47.19681 = 167 202.470675805,47.1968942895 = 183 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/web.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000006�11236332365�014324� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������hvweb ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/colorbar.xpa���������������������������������������������������������������������0000644�0001750�0001750�00000000073�11755007521�015355� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������yes horizontal yes distance helvetica 9 normal roman 20 11 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/bg.xpa���������������������������������������������������������������������������0000644�0001750�0001750�00000000014�11540446107�014134� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������white white ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/mask.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000010�11242614631�014471� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������red 1 0 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/cd.xpa���������������������������������������������������������������������������0000644�0001750�0001750�00000000031�11240627001�014120� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/Users/joye/saods9/tests �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/nan.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000006�11534242553�014323� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������white ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/blink.xpa������������������������������������������������������������������������0000644�0001750�0001750�00000000007�12113740635�014645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no 0.5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/dsssao.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000076�11241073001�015033� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 30 arcsec no new m51 00:42:44.404 +41:16:08.78 sexagesimal ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/file.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000016�12113731142�014456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������data/img.fits ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/pagesetup.xpa��������������������������������������������������������������������0000644�0001750�0001750�00000000024�11762201375�015544� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������portrait 100 letter ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/orient.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000003�11232370251�015034� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xy �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/crosshair.xpa��������������������������������������������������������������������0000644�0001750�0001750�00000000052�11715044514�015543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 801 801 13:29:55.287 +47:11:37.73 none ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/skyview.xpa����������������������������������������������������������������������0000644�0001750�0001750�00000000104�11241100417�015232� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sdssi 30 30 arcsec no new m51 13:29:55.301 +47:11:37.73 sexagesimal ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/tile.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000010�12113740635�014475� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������no grid ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/view.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000111�11232370251�014506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������horizontal yes yes yes yes yes no no yes yes no no yes yes no no yes yes �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/minmax.xpa�����������������������������������������������������������������������0000644�0001750�0001750�00000000017�11232370251�015032� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������auto auto auto �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/wcs.xpa��������������������������������������������������������������������������0000644�0001750�0001750�00000000033�11232370251�014333� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������wcs wcs fk5 sexagesimal no �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/crop.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000110�11716566011�014506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 978 970 356 308 13:29:52.908 +47:11:38.19 35.279606 30.522805 none ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/magnifier.xpa��������������������������������������������������������������������0000644�0001750�0001750�00000000020�11431034705�015476� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������white 4 yes yes ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/nvss.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000074�11241075603�014540� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������30 30 arcsec no new m51 13:29:52.37 +47:11:40.8 sexagesimal ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa/mode.xpa�������������������������������������������������������������������������0000644�0001750�0001750�00000000010�11232370251�014456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pointer ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/partial.sh���������������������������������������������������������������������������0000755�0001750�0001750�00000002672�12131617434�014251� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # which/where which=$1 shift where=$1 shift what=$1 shift # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** $which ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" for f in $where/* do echo " ${f#$where/}" opt="-$what $f -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi ds9 $opt -exit done echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" for f in $where/* do echo " ${f#$where/}" opt="-$what - -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi cat $f | ds9 $opt -exit done echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 $what $f if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 for f in $where/* do echo " ${f#$where/}" cat $f | xpaset ds9 $what if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi echo "DONE" ����������������������������������������������������������������������./saods9/tests/spartial.sh��������������������������������������������������������������������������0000755�0001750�0001750�00000001725�12131617435�014433� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 $extra & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # which/where/what which=$1 shift where=$1 shift what=$1 shift extra=$1 shift # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** $which ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" for f in $where/*.arr do echo " ${f#$where/}" opt="-$what ${f%.arr}.hdr $f -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi ds9 $opt -exit done echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 for f in $where/*.arr do echo " ${f#$where/}" xpaset -p ds9 $what ${f%.arr}.hdr $f if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi echo "DONE" �������������������������������������������./saods9/tests/regions.sh���������������������������������������������������������������������������0000755�0001750�0001750�00000023662�12131345054�014261� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������testit () { echo "Test $1 $2 $3 $4 $5" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 xpaset -p ds9 regions save ${5}.out if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall o=`diff $5 ${5}.out` if [ "$o" = "" ] then echo "PASSED" else echo "FAILED" echo "$o" fi rm -f ${5}.out } testit2 () { echo "Test $1 $2 $3 $4 $5 $6" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 xpaset -p ds9 regions save ${5}.out if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall o=`diff $6 ${5}.out` if [ "$o" = "" ] then echo "PASSED" else echo "FAILED" echo "$o" fi rm -f ${5}.out } testit3 () { echo "Test $1 $2 $3 $4 $5" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall echo "PASSED" } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** regions.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done fi echo "Loading Data..." xpaset -p ds9 fits data/img.fits if [ "$1" = "ds9" -o -z "$1" ]; then echo echo "Testing DS9 Format..." testit ds9 image fk5 degrees regions/ds9.image.reg testit ds9 physical fk5 degrees regions/ds9.physical.reg testit ds9 wcs fk4 degrees regions/ds9.fk4.reg testit ds9 wcs fk4 sexagesimal regions/ds9.fk4.hms.reg testit ds9 wcs fk5 degrees regions/ds9.fk5.reg testit ds9 wcs fk5 sexagesimal regions/ds9.fk5.hms.reg testit ds9 wcs icrs degrees regions/ds9.icrs.reg testit ds9 wcs icrs sexagesimal regions/ds9.icrs.hms.reg testit ds9 wcs galactic degrees regions/ds9.galactic.reg testit ds9 wcs galactic sexagesimal regions/ds9.galactic.hms.reg testit ds9 wcs ecliptic degrees regions/ds9.ecliptic.reg testit ds9 wcs ecliptic sexagesimal regions/ds9.ecliptic.hms.reg echo echo "Testing XML Format..." testit xml image fk5 degrees regions/xml.image.reg testit xml physical fk5 degrees regions/xml.physical.reg testit xml wcs fk4 degrees regions/xml.fk4.reg testit xml wcs fk4 sexagesimal regions/xml.fk4.hms.reg testit xml wcs fk5 degrees regions/xml.fk5.reg testit xml wcs fk5 sexagesimal regions/xml.fk5.hms.reg testit xml wcs icrs degrees regions/xml.icrs.reg testit xml wcs icrs sexagesimal regions/xml.icrs.hms.reg testit xml wcs galactic degrees regions/xml.galactic.reg testit xml wcs galactic sexagesimal regions/xml.galactic.hms.reg testit xml wcs ecliptic degrees regions/xml.ecliptic.reg testit xml wcs ecliptic sexagesimal regions/xml.ecliptic.hms.reg fi if [ "$1" = "comment" -o -z "$1" ]; then echo echo "Testing DS9 Format Comments..." xpaset -p ds9 regions format ds9 xpaset -p ds9 regions file regions/ds9.comment.reg xpaset -p ds9 regions deleteall echo "PASSED" fi if [ "$1" = "ds9strip" -o -z "$1" ]; then echo xpaset -p ds9 regions strip yes echo "Testing ds9 strip Regions Format..." testit2 ds9 image fk5 degrees regions/ds9.image.reg regions/ds9.image.strip.reg testit2 ds9 physical fk5 degrees regions/ds9.physical.reg regions/ds9.physical.strip.reg testit2 ds9 wcs fk4 degrees regions/ds9.fk4.reg regions/ds9.fk4.strip.reg testit2 ds9 wcs fk4 sexagesimal regions/ds9.fk4.hms.reg regions/ds9.fk4.hms.strip.reg testit2 ds9 wcs fk5 degrees regions/ds9.fk5.reg regions/ds9.fk5.strip.reg testit2 ds9 wcs fk5 sexagesimal regions/ds9.fk5.hms.reg regions/ds9.fk5.hms.strip.reg testit2 ds9 wcs icrs degrees regions/ds9.icrs.reg regions/ds9.icrs.strip.reg testit2 ds9 wcs icrs sexagesimal regions/ds9.icrs.hms.reg regions/ds9.icrs.hms.strip.reg testit2 ds9 wcs galactic degrees regions/ds9.galactic.reg regions/ds9.galactic.strip.reg testit2 ds9 wcs galactic sexagesimal regions/ds9.galactic.hms.reg regions/ds9.galactic.hms.strip.reg testit2 ds9 wcs ecliptic degrees regions/ds9.ecliptic.reg regions/ds9.ecliptic.strip.reg testit2 ds9 wcs ecliptic sexagesimal regions/ds9.ecliptic.hms.reg regions/ds9.ecliptic.hms.strip.reg xpaset -p ds9 regions strip no fi if [ "$1" = "ciao" -o -z "$1" ]; then echo echo "Testing CIAO Format..." testit ciao physical fk5 degrees regions/ciao.physical.reg testit ciao wcs fk5 sexagesimal regions/ciao.fk5.reg fi if [ "$1" = "saotng" -o -z "$1" ]; then echo echo "Testing SAOtng Format..." testit saotng image fk5 degrees regions/saotng.image.reg testit saotng wcs fk4 degrees regions/saotng.fk4.reg testit saotng wcs fk4 sexagesimal regions/saotng.fk4.hms.reg testit saotng wcs fk5 degrees regions/saotng.fk5.reg testit saotng wcs fk5 sexagesimal regions/saotng.fk5.hms.reg testit saotng wcs icrs degrees regions/saotng.icrs.reg testit saotng wcs icrs sexagesimal regions/saotng.icrs.hms.reg testit saotng wcs galactic degrees regions/saotng.galactic.reg testit saotng wcs galactic sexagesimal regions/saotng.galactic.hms.reg testit saotng wcs ecliptic degrees regions/saotng.ecliptic.reg testit saotng wcs ecliptic sexagesimal regions/saotng.ecliptic.hms.reg fi if [ "$1" = "pros" -o -z "$1" ]; then echo echo "Testing IRAF Pros Format..." testit pros image fk5 degrees regions/pros.image.reg testit pros physical fk5 degrees regions/pros.physical.reg testit pros wcs fk4 degrees regions/pros.fk4.reg testit pros wcs fk4 sexagesimal regions/pros.fk4.hms.reg testit pros wcs fk5 degrees regions/pros.fk5.reg testit pros wcs fk5 sexagesimal regions/pros.fk5.hms.reg testit pros wcs galactic degrees regions/pros.galactic.reg testit pros wcs galactic sexagesimal regions/pros.galactic.hms.reg testit pros wcs ecliptic degrees regions/pros.ecliptic.reg testit pros wcs ecliptic sexagesimal regions/pros.ecliptic.hms.reg fi if [ "$1" = "saoimage" -o -z "$1" ]; then echo echo "Testing SAOimage Format..." testit saoimage image fk5 degrees regions/saoimage.reg fi if [ "$1" = "xy" -o -z "$1" ]; then echo echo "Testing X Y Format..." testit xy image fk5 degrees regions/xy.image.reg testit xy physical fk5 degrees regions/xy.physical.reg testit xy wcs fk4 degrees regions/xy.fk4.reg testit xy wcs fk4 sexagesimal regions/xy.fk4.hms.reg testit xy wcs fk5 degrees regions/xy.fk5.reg testit xy wcs fk5 sexagesimal regions/xy.fk5.hms.reg testit xy wcs icrs degrees regions/xy.icrs.reg testit xy wcs icrs sexagesimal regions/xy.icrs.hms.reg testit xy wcs galactic degrees regions/xy.galactic.reg testit xy wcs galactic sexagesimal regions/xy.galactic.hms.reg testit xy wcs ecliptic degrees regions/xy.ecliptic.reg testit xy wcs ecliptic sexagesimal regions/xy.ecliptic.hms.reg fi if [ "$1" = "windows" -o -z "$1" ]; then echo echo "Testing Windows /CR/NL Format..." testit3 ds9 physical fk5 degrees regions/ds9.physical.windows.reg testit3 ciao physical fk5 degrees regions/ciao.physical.windows.reg testit3 saotng image fk5 degrees regions/saotng.image.windows.reg testit3 saoimage image fk5 degrees regions/saoimage.windows.reg testit3 pros physical fk5 degrees regions/pros.physical.windows.reg testit3 xy physical fk5 degrees regions/xy.physical.windows.reg fi if [ "$1" = "composite" -o -z "$1" ]; then echo echo "Loading Composite Data..." testit ds9 wcs fk5 degrees regions/ds9.composite.reg fi if [ "$1" = "fits" -o -z "$1" ]; then echo echo "Testing FITS Regions Format..." testit2 ds9 physical fk5 degrees regions/ds9.reg.fits regions/ds9.fits.reg fi if [ "$1" = "mosaic" -o -z "$1" ]; then echo echo "Loading Mosaic Data..." xpaset -p ds9 frame clear xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 zoom .5 echo echo "Testing DS9 Mosaic Format..." testit ds9 image fk5 degrees regions/ds9.mosaic.image.reg testit ds9 physical fk5 degrees regions/ds9.mosaic.physical.reg testit ds9 wcs fk4 degrees regions/ds9.mosaic.fk4.reg testit ds9 wcs fk4 sexagesimal regions/ds9.mosaic.fk4.hms.reg testit ds9 wcs fk5 degrees regions/ds9.mosaic.fk5.reg testit ds9 wcs fk5 sexagesimal regions/ds9.mosaic.fk5.hms.reg testit ds9 wcs icrs degrees regions/ds9.mosaic.icrs.reg testit ds9 wcs icrs sexagesimal regions/ds9.mosaic.icrs.hms.reg testit ds9 wcs galactic degrees regions/ds9.mosaic.galactic.reg testit ds9 wcs galactic sexagesimal regions/ds9.mosaic.galactic.hms.reg testit ds9 wcs ecliptic degrees regions/ds9.mosaic.ecliptic.reg testit ds9 wcs ecliptic sexagesimal regions/ds9.mosaic.ecliptic.hms.reg echo echo "Testing XML Mosaic Format..." testit xml image fk5 degrees regions/xml.mosaic.image.reg testit xml physical fk5 degrees regions/xml.mosaic.physical.reg testit xml wcs fk4 degrees regions/xml.mosaic.fk4.reg testit xml wcs fk4 sexagesimal regions/xml.mosaic.fk4.hms.reg testit xml wcs fk5 degrees regions/xml.mosaic.fk5.reg testit xml wcs fk5 sexagesimal regions/xml.mosaic.fk5.hms.reg testit xml wcs icrs degrees regions/xml.mosaic.icrs.reg testit xml wcs icrs sexagesimal regions/xml.mosaic.icrs.hms.reg testit xml wcs galactic degrees regions/xml.mosaic.galactic.reg testit xml wcs galactic sexagesimal regions/xml.mosaic.galactic.hms.reg testit xml wcs ecliptic degrees regions/xml.mosaic.ecliptic.reg testit xml wcs ecliptic sexagesimal regions/xml.mosaic.ecliptic.hms.reg fi if [ "$1" = "linear" -o -z "$1" ]; then echo echo "Loading Linear Data..." xpaset -p ds9 scale minmax xpaset -p ds9 frame clear xpaset -p ds9 mosaicimage mosaic/ds9_8amp_2x2.fits xpaset -p ds9 zoom .5 echo echo "Testing DS9 Linear Format..." testit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg testit ds9 wcsa fk5 degrees regions/ds9.linear.wcsa.reg testit ds9 wcsc fk5 degrees regions/ds9.linear.wcsc.reg testit ds9 wcsd fk5 degrees regions/ds9.linear.wcsd.reg testit ds9 wcsi fk5 degrees regions/ds9.linear.wcsi.reg testit ds9 wcsp fk5 degrees regions/ds9.linear.wcsp.reg fi if [ -z "$1" ]; then xpaset -p ds9 quit fi ������������������������������������������������������������������������������./saods9/tests/multiframe.sh������������������������������������������������������������������������0000755�0001750�0001750�00000003125�12131345054�014750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # which/where which=Multiframe where=mecube what=multiframe # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** $which ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" for f in $where/* do echo " ${f#$where/}" ds9 -$what $f & KillIt done echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" for f in $where/* do echo " ${f#$where/}" cat $f | ds9 -$what - & KillIt done echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 xpaset -p ds9 frame delete all for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 $what $f if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete all done xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 xpaset -p ds9 frame delete all for f in $where/* do echo " ${f#$where/}" cat $f | xpaset ds9 $what if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete all done xpaset -p ds9 quit echo "PASSED" fi echo "DONE" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/samp.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000005343�12131601437�013547� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "SAMP Tests" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9 -tcl& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi testit () { echo echo "Testing $1" tclsh ../admin/samp.tcl block < samp/${1}.samp # tclsh85sg ../admin/samp.tcl block < samp/${1}.samp echo "PASSED" } doit () { if [ "$1" = "$2" -o -z "$1" ]; then testit "$2" fi } echo echo "*** samp.sh ***" # must be invoked # imexam # movie # samp # skyview # load default image xpaset -p ds9 scale zscale xpaset -p ds9 fits data/img.fits doit "$1" 2mass doit "$1" 3d doit "$1" about doit "$1" align doit "$1" analysis doit "$1" array doit "$1" bg doit "$1" backup doit "$1" bin doit "$1" blink doit "$1" catalog doit "$1" cd doit "$1" cmap doit "$1" colorbar doit "$1" console doit "$1" contour doit "$1" crop doit "$1" crosshair doit "$1" cube doit "$1" cursor doit "$1" data doit "$1" dsssao doit "$1" dsseso doit "$1" dssstsci doit "$1" export # backward compatibility doit "$1" file doit "$1" first doit "$1" fits doit "$1" frame doit "$1" gif doit "$1" grid doit "$1" header doit "$1" height doit "$1" iconify doit "$1" iis # interactive #doit "$1" imexam doit "$1" jpeg doit "$1" lock doit "$1" lower doit "$1" magnifier doit "$1" mask doit "$1" match doit "$1" mecube doit "$1" minmax doit "$1" mode doit "$1" mosaic doit "$1" mosaicimage # backward compatibility doit "$1" mosaicwcs # backward compatibility doit "$1" mosaiciraf # backward compatibility doit "$1" mosaicimagewcs # backward compatibility doit "$1" mosaicimageiraf # backward compatibility doit "$1" mosaicimagewfpc2 # must be aligned at 0x0 #doit "$1" movie doit "$1" multiframe doit "$1" nameserver doit "$1" nan doit "$1" nrrd doit "$1" nvss doit "$1" orient doit "$1" pagesetup doit "$1" pan doit "$1" pixeltable doit "$1" plot doit "$1" png doit "$1" prefs doit "$1" preserve doit "$1" print doit "$1" raise doit "$1" regions doit "$1" restore doit "$1" rgb doit "$1" rgbarray doit "$1" rgbcube doit "$1" rgbimage doit "$1" rotate # really don't want to do this #doit "$1" samp doit "$1" save doit "$1" saveimage doit "$1" scale # backward compatibility doit "$1" sfits doit "$1" single # no tests #doit "$1" shm # timeout issues #doit "$1" skyview doit "$1" sleep # no tests #doit "$1" smosaic # no tests #doit "$1" smosaicwcs # no tests #doit "$1" smosaiciraf doit "$1" smooth doit "$1" source # backward compatibility doit "$1" srgbcube doit "$1" tcl doit "$1" theme doit "$1" threads doit "$1" tiff doit "$1" tile doit "$1" update # no tests doit "$1" url doit "$1" version doit "$1" view doit "$1" vo doit "$1" wcs doit "$1" web doit "$1" width doit "$1" zscale doit "$1" zoom doit "$1" exit rm -f foo.* ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/sfits.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000000047�12122431011�013720� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������spartial.sh SFits sfits sfits "" $1 $2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/wcs2.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000002405�12132057400�013455� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** wcs2.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi testit () { echo "Testing $1" xpaset -p ds9 fits $1 xpaset -p ds9 wcs sky fk5 xpaset -p ds9 align yes read xpaset -p ds9 wcs sky galactic read xpaset -p ds9 frame clear } # load default image xpaset -p ds9 grid yes xpaset -p ds9 wcs skyformat deg echo "STScI DSS" testit wcs2/wcen.fits.gz echo "Old SCAMP" testit wcs2/ngc6819.fits echo "TAN+ PV" testit wcs2/paucam_0_0_t7_0_science.fits echo "TAN PV2_1=0 PV2_2=0" testit wcs2/a68.fits echo "ZPN+ PV" testit wcs2/UKIDDS_K_3219_606_17_67_3.fits echo "TNX" testit wcs2/30s_01.fits echo "ZPX" testit wcs2/E5.3090.fits echo "TAN-SIP" testit wcs2/sst.fits testit wcs2/mos8.fits echo "SAO Plate" testit wcs2/ac.fits #echo "TAB" #testit wcs2/sparse.fits echo "WCSDEP" testit wcs2/ngc6819.fits echo "HPX" testit wcs2/wmap.fits echo "GLON-ZEA" testit wcs2/South_galactic.fits echo "RA-CAR" testit wcs2/CAR_model.fits testit wcs2/car_01.fits echo "GLON-CAR" testit wcs2/GLM_00350+0115_mosaic_I4_cutout_14706.fits echo "IRAF" testit wcs2/obj011.fits xpaset -p ds9 quit �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/rgbimage.sh��������������������������������������������������������������������������0000755�0001750�0001750�00000000052�12107266155�014363� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fullrgb.sh RGBImage mecube rgbimage $1 $2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/makeregions.sh�����������������������������������������������������������������������0000755�0001750�0001750�00000026661�12131345054�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doit () { echo "Generating $6 $7 $8 $9 in ${10}" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions load $5 xpaset -p ds9 regions format $6 xpaset -p ds9 regions system $7 xpaset -p ds9 regions sky $8 xpaset -p ds9 regions skyformat $9 xpaset -p ds9 regions save ${10} xpaset -p ds9 regions deleteall } echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done fi echo "Loading Data..." xpaset -p ds9 file data/img.fits echo "DONE" if [ "$1" = "ds9" ]; then echo echo "DS9 Format..." doit ds9 image fk5 degrees regions/ds9.image.reg ds9 physical fk5 degrees regions/ds9.physical.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk4 degrees regions/ds9.fk4.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk4 sexagesimal regions/ds9.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk5 degrees regions/ds9.fk5.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk5 sexagesimal regions/ds9.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs icrs degrees regions/ds9.icrs.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs icrs sexagesimal regions/ds9.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs galactic degrees regions/ds9.galactic.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs galactic sexagesimal regions/ds9.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs ecliptic degrees regions/ds9.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs ecliptic sexagesimal regions/ds9.ecliptic.hms.reg echo echo "XML Format..." doit ds9 image fk5 degrees regions/ds9.image.reg xml image fk5 degrees regions/xml.image.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml physical fk5 degrees regions/xml.physical.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs fk4 degrees regions/xml.fk4.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs fk4 sexagesimal regions/xml.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs fk5 degrees regions/xml.fk5.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs fk5 sexagesimal regions/xml.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs icrs degrees regions/xml.icrs.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs icrs sexagesimal regions/xml.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs galactic degrees regions/xml.galactic.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs galactic sexagesimal regions/xml.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs ecliptic degrees regions/xml.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.image.reg xml wcs ecliptic sexagesimal regions/xml.ecliptic.hms.reg fi if [ "$1" = "ds9strip" ]; then echo xpaset -p ds9 regions strip yes echo "DS9 strip Format..." doit ds9 image fk5 degrees regions/ds9.image.reg ds9 image fk5 degrees regions/ds9.image.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 physical fk5 degrees regions/ds9.physical.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk4 degrees regions/ds9.fk4.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk4 sexagesimal regions/ds9.fk4.hms.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk5 degrees regions/ds9.fk5.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs fk5 sexagesimal regions/ds9.fk5.hms.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs icrs degrees regions/ds9.icrs.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs icrs sexagesimal regions/ds9.icrs.hms.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs galactic degrees regions/ds9.galactic.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs galactic sexagesimal regions/ds9.galactic.hms.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs ecliptic degrees regions/ds9.ecliptic.strip.reg doit ds9 image fk5 degrees regions/ds9.image.reg ds9 wcs ecliptic sexagesimal regions/ds9.ecliptic.hms.strip.reg xpaset -p ds9 regions strip yes fi if [ "$1" = "ciao" ]; then echo echo "DS9 Format..." doit ds9 image fk5 degrees regions/ds9.image.reg ciao physical fk5 degrees regions/ciao.physical.reg doit ds9 image fk5 degrees regions/ds9.image.reg ciao wcs fk5 sexagesimal regions/ciao.fk5.reg fi if [ "$1" = "saotng" ]; then echo echo "SAOtng Format..." doit ds9 image fk5 degrees regions/ds9.image.reg saotng image fk5 degrees regions/saotng.image.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs fk4 degrees regions/saotng.fk4.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs fk4 sexagesimal regions/saotng.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs fk5 degrees regions/saotng.fk5.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs fk5 sexagesimal regions/saotng.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs icrs degrees regions/saotng.icrs.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs icrs sexagesimal regions/saotng.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs galactic degrees regions/saotng.galactic.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs galactic sexagesimal regions/saotng.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs ecliptic degrees regions/saotng.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.image.reg saotng wcs ecliptic sexagesimal regions/saotng.ecliptic.hms.reg fi if [ "$1" = "pros" ]; then echo echo "IRAF Pros Format..." doit ds9 image fk5 degrees regions/ds9.image.reg pros image fk5 degrees regions/pros.image.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros physical fk5 degrees regions/pros.physical.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs fk4 degrees regions/pros.fk4.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs fk4 sexagesimal regions/pros.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs fk5 degrees regions/pros.fk5.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs fk5 sexagesimal regions/pros.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs galactic degrees regions/pros.galactic.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs galactic sexagesimal regions/pros.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs ecliptic degrees regions/pros.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.image.reg pros wcs ecliptic sexagesimal regions/pros.ecliptic.hms.reg fi if [ "$1" = "xy" ]; then echo echo "X Y Format..." doit ds9 image fk5 degrees regions/ds9.image.reg xy image fk5 degrees regions/xy.image.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy physical fk5 degrees regions/xy.physical.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs fk4 degrees regions/xy.fk4.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs fk4 sexagesimal regions/xy.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs fk5 degrees regions/xy.fk5.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs fk5 sexagesimal regions/xy.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs icrs degrees regions/xy.icrs.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs icrs sexagesimal regions/xy.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs galactic degrees regions/xy.galactic.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs galactic sexagesimal regions/xy.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs ecliptic degrees regions/xy.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.image.reg xy wcs ecliptic sexagesimal regions/xy.ecliptic.hms.reg fi if [ "$1" = "mosaic" ]; then echo echo "Loading Mosaic Data..." xpaset -p ds9 frame clear xpaset -p ds9 file mosaicimage mosaic/mosaicimage.fits echo "DONE" echo echo "DS9 Mosaic Format..." doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 physical fk5 degrees regions/ds9.mosaic.physical.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs fk4 degrees regions/ds9.mosaic.fk4.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs fk4 sexagesimal regions/ds9.mosaic.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs fk5 degrees regions/ds9.mosaic.fk5.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs fk5 sexagesimal regions/ds9.mosaic.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs icrs degrees regions/ds9.mosaic.icrs.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs icrs sexagesimal regions/ds9.mosaic.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs galactic degrees regions/ds9.mosaic.galactic.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs galactic sexagesimal regions/ds9.mosaic.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs ecliptic degrees regions/ds9.mosaic.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg ds9 wcs ecliptic sexagesimal regions/ds9.mosaic.ecliptic.hms.reg echo echo "XML Mosaic Format..." doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml image fk5 degrees regions/xml.mosaic.image.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml physical fk5 degrees regions/xml.mosaic.physical.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs fk4 degrees regions/xml.mosaic.fk4.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs fk4 sexagesimal regions/xml.mosaic.fk4.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs fk5 degrees regions/xml.mosaic.fk5.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs fk5 sexagesimal regions/xml.mosaic.fk5.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs icrs degrees regions/xml.mosaic.icrs.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs icrs sexagesimal regions/xml.mosaic.icrs.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs galactic degrees regions/xml.mosaic.galactic.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs galactic sexagesimal regions/xml.mosaic.galactic.hms.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs ecliptic degrees regions/xml.mosaic.ecliptic.reg doit ds9 image fk5 degrees regions/ds9.mosaic.image.reg xml wcs ecliptic sexagesimal regions/xml.mosaic.ecliptic.hms.reg fi if [ "$1" = "linear" ]; then echo echo "Loading Linear Data..." xpaset -p ds9 scale minmax xpaset -p ds9 frame clear xpaset -p ds9 file mosaicimage mosaic/ds9_8amp_2x2.fits echo "DONE" echo echo "DS9 Linear Format..." doit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg ds9 wcsa fk5 degrees regions/ds9.linear.wcsa.reg doit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg ds9 wcsc fk5 degrees regions/ds9.linear.wcsc.reg doit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg ds9 wcsd fk5 degrees regions/ds9.linear.wcsd.reg doit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg ds9 wcsi fk5 degrees regions/ds9.linear.wcsi.reg doit ds9 wcs fk5 degrees regions/ds9.linear.wcs.reg ds9 wcsp fk5 degrees regions/ds9.linear.wcsp.reg fi xpaset -p ds9 quit �������������������������������������������������������������������������������./saods9/tests/plio.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000040�12107264737�013552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������partial.sh PLIO plio fits $1 $2 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/align.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000002050�12131345054�013671� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** align.sh ***" ds9 -scale mode 98 data/r.fits data/i.fits data/v.fits -match frames wcs -single ds9 -zscale -mosaicimage iraf mosaic/megacam.fits -mosaicimage wcs mosaic/megacam.fits -single ds9 -zscale -mosaic wcs mosaic/megacam.fits[1] mosaic/megacam.fits[2] mosaic/megacam.fits[3] -rgb -red mosaic/megacam.fits[1] -green mosaic/megacam.fits[2] -blue mosaic/megacam.fits[3] -single ds9 -zscale -mosaic wcs data/m51hst.fits data/img.fits -fits -rgb -red data/m51hst.fits -green data/img.fits -single ds9 -zscale data/ch4.nonan.fits data/mips24.nonan.fits -frame new -mosaic wcs data/ch4.nonan.fits data/mips24.nonan.fits -frame new rgb -fits -red data/ch4.nonan.fits -green data/mips24.nonan.fits -frame 1 -pan to 17:42:56.836 -28:31:53.10 fk5 -match frames wcs -single ds9 -mosaicimage iraf mosaic/ds9_2amp.fits -mosaicimage wcs mosaic/ds9_2amp.fits -fits -rgb -red mosaic/ds9_2amp.fits[1] -green mosaic/ds9_2amp.fits[2] -single ds9 -mosaicimage iraf mosaic/ds9_8amp_2x2.fits -mosaicimage wcs mosaic/ds9_8amp_2x2.fits -single echo "Done" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/matrix.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000000254�12131345054�014107� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** matrix.sh ***" echo "test panner,center,zoom" ds9 data/5x5.fits echo "PASSED" echo "testing DATASEC" ds9 mosaic/ds9_2amp.fits echo "PASSED" echo "Done" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/command.sh���������������������������������������������������������������������������0000755�0001750�0001750�00000126522�12131601437�014230� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "Command Line Options Tests" initit () { echo "Testing $1" unset opt } testit () { echo "$1" opt="$opt $1 -sleep .1" } doit () { eval ds9 -zscale data/img.fits "$opt" -exit echo "PASSED" echo "" } echo echo "*** command.sh ***" # must be invoked # -prefs # -private # -samp # no test # -shm # -smosaic # -smosaicwcs # -smosaiciraf # not tested # -geometry # --help # -visual tt="2mass" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-2mass open" testit "-2mass close" testit "-2mass survey h" testit "-2mass size 30 30 arcsec" testit "-2mass save no" testit "-2mass frame new" testit "-2mass update frame" testit "-2mass m1" testit "-2mass name m51" testit "-2mass name ''" testit "-2mass coord 00:42:44.404 +41:16:08.78 sexagesimal" testit "-2mass update frame" testit "-mode crosshair" testit "-2mass update crosshair" testit "-2mass close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="3d" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-3d open" testit "-3d close" testit "-3d" testit "-3d vp 45 30" testit "-3d vp 45 30" testit "-3d az 45" testit "-3d el 30" testit "-3d scale 5" testit "-3d method mip" testit "-3d border yes" testit "-3d border color red" testit "-3d compass yes" testit "-3d compass color red" testit "-3d highlite yes" testit "-3d highlite color red" testit "-3d close" testit "-frame delete" doit fi tt="about" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-about" doit fi tt="align" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-align" doit fi tt="analysis" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-analysis clear" testit "-analysis analysis/analysis.ans" testit "-analysis 0" testit "-analysis task 1" testit "-analysis task '{Basic Help}'" testit "-analysis clear" testit "-analysis load analysis/analysis.ans" testit "-analysis clear load analysis/analysis.ans" testit "-analysis clear" #testit "-analysis message 'This is a message'" #testit "-analysis message yesno 'This is a message'" testit "-analysis text 'This is text'" doit fi tt="array" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-array array/float_big.arr[dim=256,bitpix=-32,endian=big]" testit "-frame delete" testit "-frame new" testit "-array -mask array/float_big.arr[dim=256,bitpix=-32,endian=big] -nomask" testit "-frame delete" doit fi tt="asinh" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-asinh" doit fi tt="bg" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/background" testit "-background red" testit "-background white" doit fi tt="backup" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-backup foo.bck" doit fi tt="bin" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new -fits fits/table.fits" testit "-single" testit "-bin open" testit "-bin factor 4" testit "-bin factor 8 8" testit "-scale log" testit "-scale minmax" testit "-bin buffersize 1024" testit "-bin filter 'circle(4096,4096,200)'" testit "-bin filter ''" testit "-bin cols rawx rawy" testit "-bin about center" testit "-bin colsz x y pha" testit "-bin depth 10" testit "-bin about 4096 4096" testit "-bin depth 1" testit "-bin function sum" testit "-bin to fit" testit "-bin match" testit "-bin lock yes" testit "-bin lock no" testit "-bin close" testit "-frame delete" doit fi tt="blink" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-blink" testit "-blink yes" testit "-blink interval .5" testit "-single" testit "-frame first" testit "-frame next" doit fi tt="blue" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-blue" doit fi tt="catalog" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/cat" testit "-catalog cds 2mass" testit "-catalog clear" testit "-catalog close" testit "-catalog" testit "-catalog close" testit "-catalog cds 'I/284'" testit "-catalog clear" testit "-catalog close" testit "-catalog import sb aux/ds9.cat" testit "-catalog clear" testit "-catalog close" testit "-catalog cds 2mass" testit "-raise" testit "-catalog plot '\$Jmag' '\$Hmag' '\$e_Jmag' '\$e_Hmag'" testit "-catalog symbol condition '\$Jmag>15'" testit "-catalog symbol shape 'boxcircle point'" testit "-catalog symbol color red" testit "-catalog symbol condition ''" testit "-catalog symbol color red" testit "-catalog symbol shape text" testit "-catalog symbol font times" testit "-catalog symbol fontsize 14" testit "-catalog symbol fontweight bold" testit "-catalog symbol fontslant italic" testit "-catalog symbol add" testit "-catalog symbol remove" testit "-catalog symbol load aux/ds9.sym" testit "-catalog symbol save foo.sym" testit "-catalog name m51" testit "-catalog coordinate 202.48 47.21 fk5" testit "-catalog system wcs" testit "-catalog sky fk5" testit "-catalog skyformat degrees" testit "-catalog size 22 22 arcmin" testit "-catalog retrieve" testit "-catalog save foo.cat" testit "-catalog filter '\$Jmag>15'" testit "-catalog filter load aux/ds9.flt" testit "-catalog retrieve" testit "-catalog cancel" #testit "-catalog print" testit "-catalog server sao" testit "-catalog sort 'Jmag' incr" testit "-catalog maxrows 3000" testit "-catalog allcols" testit "-catalog allrows" testit "-catalog ra 'RAJ2000'" testit "-catalog dec 'DEJ2000'" testit "-catalog psystem wcs" testit "-catalog psky fk5" testit "-catalog hide" testit "-catalog show" testit "-catalog panto no" #testit "-catalog edit yes" testit "-catalog location 400" testit "-catalog header" testit "-catalog clear" testit "-catalog close" testit "-catalog 2mass" testit "-catalog xmm" testit "-catalog match function 1and2" testit "-catalog match error 2 arcsec" testit "-catalog match return 1only" testit "-catalog match unique no" testit "-catalog match 2mass xmm" testit "-catalog clear" testit "-catalog close" testit "-catalog clear" testit "-catalog close" testit "-catalog clear" testit "-catalog close" doit fi tt="cd" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-cd ." doit fi tt="cmap" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-cmap open" testit "-cmap Heat" testit "-cmap load aux/ds9.sao" testit "-cmap save foo.sao" testit "-cmap invert yes" testit "-cmap invert no" testit "-invert" testit "-cmap value 5 .2" testit "-cmap tag load aux/ds9.tag" testit "-cmap tag save foo.tag" testit "-cmap tag delete" testit "-cmap match" testit "-cmap lock yes" testit "-cmap lock no" testit "-cmap Grey" testit "-cmap close" doit fi tt="colorbar" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-colorbar no" testit "-colorbar yes" testit "-colorbar vertical" testit "-colorbar horizontal" testit "-colorbar numerics no" testit "-colorbar numerics yes" testit "-colorbar space value" testit "-colorbar space distance" testit "-colorbar font times" testit "-colorbar fontsize 30" testit "-colorbar fontweight bold" testit "-colorbar fontslant roman" testit "-colorbar font helvetica" testit "-colorbar fontsize 10" testit "-colorbar fontweight normal" testit "-colorbar fontslant roman" testit "-colorbar size 30" testit "-colorbar ticks 9" testit "-colorbar size 20" testit "-colorbar size 11" doit fi tt="console" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-console" doit fi tt="contour" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/contours" testit "-contour open" testit "-contour" testit "-contour yes" testit "-contour clear" testit "-contour yes" testit "-contour load aux/ds9.con wcs fk5 red 2" testit "-contour save foo.con wcs fk5" testit "-contour clear" testit "-contour yes" testit "-contour convert" testit "-regions delete all" testit "-contour loadlevels aux/ds9.lev" testit "-contour savelevels foo.lev" testit "-contour clear" testit "-contour yes" testit "-contour copy" testit "-contour paste wcs red 2" testit "-contour clear" testit "-contour yes" testit "-contour color yellow" testit "-contour width 2" testit "-contour smooth 5" testit "-contour method block" testit "-contour nlevels 10" testit "-contour width 2" testit "-contour scale sqrt" testit "-contour log exp 1000" testit "-contour mode zscale" testit "-contour limits 1 100" testit "-contour levels '1 10 100 1000'" testit "-contour clear" testit "-contour close" doit fi tt="crop" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-mode crop" testit "-crop 978 970 356 308" testit "-crop 13:29:52.908 +47:11:38.19 35.279606 30.522805 wcs fk5 arcsec" testit "-crop reset" testit "-3d" testit "-fits data/3d.fits" testit "-3d vp 45 30" testit "-crop 3d 25 75" testit "-crop reset" testit "-crop match wcs" testit "-crop lock wcs" testit "-crop lock none" testit "-3d close" testit "-frame delete" testit "-mode pointer" doit fi tt="crosshair" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-mode crosshair" testit "-crosshair 13:29:55.287 +47:11:37.73 wcs fk5" testit "-crosshair match wcs" testit "-crosshair lock wcs" testit "-crosshair lock none" testit "-mode pointer" doit fi tt="cube" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/datacube" testit "-cube open" testit "-cube close" testit "-frame new -fits data/3d.fits" testit "-cube 2" testit "-cube interval .5" testit "-cube axis 3" testit "-cube play" testit "-cube stop" testit "-cube match" testit "-cube lock yes" testit "-cube lock no" testit "-cube close" testit "-frame delete" doit fi tt="cursor" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-mode crosshair" testit "-cursor 10 10" testit "-mode pointer" doit fi tt="dsssao" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/dss" testit "-dsssao open" testit "-dsssao close" testit "-dsssao size 30 30 arcsec" testit "-dsssao save no" testit "-dsssao frame new" testit "-dsssao update frame" testit "-dsssao m1" testit "-dsssao name m51" testit "-dsssao name ''" testit "-dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal" testit "-dsssao update frame" testit "-mode crosshair" testit "-dsssao update crosshair" testit "-dsssao close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="dsseso" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-dsseso open" testit "-dsseso close" testit "-dsseso survey DSS2-red" testit "-dsseso size 30 30 arcsec" testit "-dsseso save no" testit "-dsseso frame new" testit "-dsseso update frame" testit "-dsseso m1" testit "-dsseso name m51" testit "-dsseso name ''" testit "-dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal" testit "-dsseso update frame" testit "-mode crosshair" testit "-dsseso update crosshair" testit "-dsseso close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="dssstsci" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-dssstsci open" testit "-dssstsci close" testit "-dssstsci survey all" testit "-dssstsci size 30 30 arcsec" testit "-dssstsci save no" testit "-dssstsci frame new" testit "-dssstsci update frame" testit "-dssstsci m1" testit "-dssstsci name m51" testit "-dssstsci name ''" testit "-dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal" testit "-dssstsci update frame" testit "-mode crosshair" testit "-dssstsci update crosshair" testit "-dssstsci close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="export" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-export array foo.arr little" testit "-export foo.arr little" testit "-export nrrd foo.nrrd big" testit "-export foo.nrrd" testit "-export gif foo.gif" testit "-export foo.gif" testit "-export tiff foo.tiff none" testit "-export foo.tiff" testit "-export jpeg foo.jpeg 10" testit "-export foo.jpeg" testit "-export png foo.png" testit "-export foo.png" testit "-frame new rgb" testit "-rgbcube rgbcube/float.fits" testit "-export rgbarray foo.rgb little" testit "-export foo.rgb little" testit "-frame delete" doit fi tt="fifo" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-fifo /dev/imt1" testit "-fifo_only" doit fi # backward compatibility tt="file" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-file fits/float.fits" testit "-file -slice fits/float.fits -noslice" testit "-file -mask fits/float.fits -nomask" testit "-frame delete" doit fi tt="first" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-first open" testit "-first close" testit "-first size 30 30 arcsec" testit "-first save no" testit "-first frame new" testit "-first update frame" testit "-first m3" testit "-first name m51" testit "-first name ''" testit "-first coord 13:29:52.37 +47:11:40.8 sexagesimal" testit "-first update frame" testit "-mode crosshair" testit "-first update crosshair" testit "-first close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="fits" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-fits fits/float.fits" testit "-fits -slice fits/float.fits -noslice" testit "-fits -mask fits/float.fits -nomask" testit "-frame delete" doit fi tt="frame" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-frame delete" testit "-frame new 3d" testit "-frame delete" testit "-fits data/img.fits" testit "-tile" testit "-frame center" testit "-frame center 1" testit "-frame center all" testit "-frame reset" testit "-frame reset 1" testit "-frame reset all" testit "-frame refresh" testit "-frame refresh 1" testit "-frame refresh all" testit "-frame hide" testit "-frame hide 1" testit "-frame hide all" testit "-frame show" testit "-frame show 1" testit "-frame show all" testit "-frame move first" testit "-frame move back" testit "-frame move forward" testit "-frame move last" testit "-frame first" testit "-frame prev" testit "-frame next" testit "-frame last" testit "-frame frameno 1" testit "-frame 2" testit "-frame match wcs" testit "-frame lock wcs" testit "-frame lock none" testit "-frame clear" testit "-frame clear 1" testit "-frame clear all" testit "-frame delete" testit "-frame delete 1" testit "-frame delete all" testit "-frame new -fits data/img.fits" testit "-rgb close" testit "-3d close" doit fi tt="gif" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-gif photo/rose.gif" testit "-frame delete" testit "-frame new" testit "-gif -slice photo/rose.gif -noslice" testit "-frame delete" doit fi tt="green" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-green" doit fi tt="grid" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-grid open" testit "-grid close" testit "-grid" testit "-grid yes" testit "-grid type analysis" testit "-grid system wcs" testit "-grid sky fk5" testit "-grid skyformat degrees" testit "-grid grid yes" testit "-grid grid color red" testit "-grid grid width 2" testit "-grid grid style 1" testit "-grid grid gap1 .01" testit "-grid grid gap2 .01" testit "-grid axes yes" testit "-grid axes color red" testit "-grid axes width 2" testit "-grid axes style 1" testit "-grid axes type exterior" testit "-grid axes origin lll" testit "-grid format1 d.2" testit "-grid format2 d.2" testit "-grid tickmarks color red" testit "-grid tickmarks width 2" testit "-grid tickmarks style 1" testit "-grid border yes" testit "-grid border color red" testit "-grid border width 2" testit "-grid border style 1" testit "-grid numerics yes" testit "-grid numerics font courier" testit "-grid numerics fontweight bold" testit "-grid numerics fontslant roman" testit "-grid numerics fontsize 12" testit "-grid numerics color red" testit "-grid numerics gap1 10" testit "-grid numerics gap2 10" testit "-grid numerics type exterior" testit "-grid numerics vertical yes" testit "-grid title yes" testit "-grid title text 'Hello World'" testit "-grid title def yes" testit "-grid title gap 10" testit "-grid title font courier" testit "-grid title fontweight bold" testit "-grid title fontslant roman" testit "-grid title fontsize 12" testit "-grid title color red" testit "-grid labels yes" testit "-grid labels text1 'Hello World'" testit "-grid labels def1 yes" testit "-grid labels gap1 10" testit "-grid labels text2 'Hello World'" testit "-grid labels def2 yes" testit "-grid labels gap2 10" testit "-grid labels font courier" testit "-grid labels fontweight bold" testit "-grid labels fontslant roman" testit "-grid labels fontsize 12" testit "-grid labels color red" testit "-grid save foo.grd" testit "-grid load foo.grd" testit "-grid reset" testit "-grid no" testit "-grid close" doit fi tt="header" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-header" testit "-header save foo.txt" testit "-header close" testit "-header 1" testit "-header close 1" doit fi tt="height" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-height 443" doit fi tt="histequ" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-histequ" doit fi tt="iconify" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-iconify" testit "-iconify yes" testit "-iconify no" doit fi tt="invert" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-invert" doit fi tt="iis" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-iis filename foo.fits" testit "-iis filename foo.fits 1" doit fi tt="jpeg" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/jpg" testit "-frame new" testit "-jpeg photo/rose.jpeg" testit "-jpeg -slice photo/rose.jpeg -noslice" testit "-frame delete" doit fi tt="language" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-language fr" doit fi tt="linear" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-linear" doit fi tt="lock" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-fits data/img.fits" testit "-tile" testit "-mode crosshair" testit "-lock frame wcs" testit "-lock frame none" testit "-lock crosshair wcs" testit "-crosshair 13:29:56 +47:11:38 wcs fk5" testit "-lock crosshair none" testit "-lock crop wcs" testit "-lock crop none" testit "-lock slice yes" testit "-lock slice no" testit "-lock bin yes" testit "-lock bin no" testit "-lock scale yes" testit "-lock scale no" testit "-lock colorbar yes" testit "-lock colorbar no" testit "-lock smooth yes" testit "-lock smooth no" testit "-mode pointer" testit "-frame delete" testit "-wcs align no" doit fi tt="log" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-log" doit fi tt="lower" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-lower" testit "-raise" doit fi tt="magnifier" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-magnifier color white" testit "-magnifier zoom 4" testit "-magnifier cursor yes" testit "-magnifier region yes" doit fi tt="mask" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-mask open" testit "-mask color cyan" testit "-mask clear" testit "-mask close" doit fi tt="match" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-fits data/img.fits" testit "-tile" testit "-mode crosshair" testit "-match frame wcs" testit "-match frame image" testit "-match crosshair wcs" testit "-match crop wcs" testit "-match slice" testit "-match bin" testit "-match scale" testit "-match colorbar" testit "-match smooth" testit "-frame delete" testit "-mode pointer" doit fi tt="mecube" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-mecube mecube/float.fits" testit "-frame delete" doit fi tt="minmax" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-minmax scan" testit "-minmax mode scan" testit "-minmax interval 10" doit fi tt="mode" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-mode none" testit "-mode crosshair" testit "-mode colorbar" testit "-mode pan" testit "-mode zoom" testit "-mode rotate" testit "-mode catalog" testit "-mode examine" testit "-mode pointer" doit fi tt="mosaic" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-mosaic mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaic wcs mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaic iraf mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaic mosaic/mosaicimage.fits" testit "-mosaic -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi tt="mosaicimage" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-mosaicimage mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaicimage wcs mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaicimage iraf mosaic/mosaicimage.fits" testit "-frame clear" testit "-mosaicimage wfpc2 mosaic/hst.fits" testit "-frame clear" testit "-mosaicimage mosaic/mosaicimage.fits" testit "-mosaicimage -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi # backward compatibility tt="mosaicwcs" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-mosaicwcs mosaic/mosaicimage.fits" testit "-mosaicwcs -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi # backward compatibility tt="mosaiciraf" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-mosaiciraf mosaic/mosaicimage.fits" testit "-mosaiciraf -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi # backward compatibility tt="mosaicimagewcs" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-mosaicimagewcs mosaic/mosaicimage.fits" testit "-mosaicimagewcs -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi # backward compatibility tt="mosaicimageiraf" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-mosaicimageiraf mosaic/mosaicimage.fits" testit "-mosaicimageiraf -mask mosaic/mosaicimage.fits -nomask" testit "-frame delete" doit fi # backward compatibility tt="mosaicimagewfpc2" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-mosaicimagewfpc2 mosaic/hst.fits" testit "-frame delete" doit fi # movie will fail if moved from corner tt="movie" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/savempeg" testit "-width 715 -height 450" testit "-movie slice foo.mpg" testit "-movie frame foo.mpg" testit "-frame new 3d" testit "-movie 3d foo.mpg number 1 azfrom 0 azto 0 elfrom 0 elto 0 slfrom 1 slto 1 repeat 1" testit "-frame delete" # backward compatibility testit "-savempeg foo.mpg" doit fi tt="msg" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-msg ../msgs" doit fi tt="multiframe" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/memf" testit "-frame delete" testit "-multiframe mecube/float.fits" doit fi tt="nameserver" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-nameserver open" testit "-nameserver close" testit "-nameserver m51" testit "-nameserver name m51" testit "-nameserver server simbad-cds" testit "-nameserver skyformat degrees" testit "-mode crosshair" testit "-nameserver crosshair" testit "-nameserver pan" testit "-nameserver close" testit "-mode pointer" testit "-frame reset" doit fi tt="nan" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-nan blue" testit "-nan white" doit fi tt="nrrd" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-nrrd nrrd/float_big_raw.nrrd" testit "-nrrd -mask nrrd/float_big_raw.nrrd -nomask" doit fi tt="nvss" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-nvss open" testit "-nvss close" testit "-nvss size 30 30 arcsec" testit "-nvss save no" testit "-nvss frame new" testit "-nvss update frame" testit "-nvss m3" testit "-nvss name m51" testit "-nvss name ''" testit "-nvss coord 13:29:52.37 +47:11:40.8 sexagesimal" testit "-nvss update frame" testit "-mode crosshair" testit "-nvss update crosshair" testit "-nvss close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="orient" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-orient open" testit "-orient none" testit "-orient x" testit "-orient y" testit "-orient xy" testit "-orient close" testit "-frame reset" doit fi tt="pagesetup" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-pspagesetup orient portrait" testit "-pspagesetup scale 100" testit "-pspagesetup size letter" doit fi tt="pan" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-pan open" testit "-pan 100 100 image" testit "-pan to 13:29:55.666 +47:12:16.29 wcs fk5" testit "-pan close" testit "-frame reset" doit fi # backward compatibility tt="photo" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-photo photo/rose.tiff" testit "-photo -slice photo/rose.tiff -noslice" testit "-frame delete" doit fi tt="pixeltable" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-pixeltable" testit "-pixeltable yes" testit "-pixeltable no" testit "-pixeltable open" testit "-pixeltable close" doit fi tt="plot" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-plot" testit "-plot close" testit "-plot new" testit "-plot new bar" testit "-plot new scatter" testit "-sleep .5" testit "-plot close" testit "-plot close" testit "-plot close" testit "-plot new name foo" testit "-plot new name foo bar" testit "-plot new name foo scatter" testit "-sleep .5" testit "-plot close" testit "-plot close" testit "-plot close" testit "-plot new name foo 'The Title' 'X Axis' 'Y Axis' xy" testit "-plot new name foo bar 'The Title' 'X Axis' 'Y Axis' xy" testit "-plot new name foo scatter 'The Title' 'X Axis' 'Y Axis' xy" testit "-sleep .5" testit "-plot close" testit "-plot close" testit "-plot close" testit "-plot new" testit "-plot load plot/xy.dat xy" testit "-sleep .5" testit "-plot clear" testit "-plot close" echo "..save/load" testit "-plot new" testit "-plot load plot/xy.dat xy" testit "-plot save foo.dat" testit "-sleep .5" testit "-plot close" echo "..config" testit "-plot new" testit "-plot saveconfig foo.plt" testit "-plot loadconfig foo.plt" testit "-sleep .5" testit "-plot close" echo "..print" testit "-plot new" #testit "-plot print" testit "-plot print destination printer" testit "-plot print command 'lp'" testit "-plot print filename 'foo.ps'" testit "-plot print color rgb" testit "-plot pagesetup orient portrait" testit "-plot pagesetup pagesize letter" testit "-plot close" testit "-plot new" testit "-plot load plot/xy.dat xy" testit "-plot graph grid x no" testit "-plot graph grid y yes" testit "-plot graph log x no" testit "-plot graph log y no" testit "-plot graph flip x no" testit "-plot graph flip y no" testit "-plot graph range x min 1" testit "-plot graph range x max 100" testit "-plot graph range y min 1" testit "-plot graph range y max 100" testit "-plot graph range x auto yes" testit "-plot graph range y auto yes" testit "-plot graph format x ''" testit "-plot graph format y ''" testit "-plot graph labels title 'The Title'" testit "-plot graph labels xaxis 'X Axis'" testit "-plot graph labels yaxis 'Y Axis'" testit "-plot font numbers font times" testit "-plot font numbers size 12" testit "-plot font numbers weight bold" testit "-plot font numbers slant roman" testit "-plot font labels font times" testit "-plot font labels size 12" testit "-plot font labels weight bold" testit "-plot font labels slant roman" testit "-plot font title font times" testit "-plot font title size 12" testit "-plot font title weight bold" testit "-plot font title slant roman" testit "-sleep .5" testit "-plot close" echo "..dataset" testit "-plot new" testit "-plot load plot/xy.dat xy" testit "-plot load plot/xyey.dat xyey" testit "-plot dataset 2" testit "-plot view discrete yes" testit "-plot view line yes" testit "-plot view step yes" testit "-plot view quadratic yes" testit "-plot view errorbar yes" testit "-plot color discrete red" testit "-plot color line green" testit "-plot color step blue" testit "-plot color quadratic cyan" testit "-plot color errorbar yellow" testit "-plot color errorbar magenta" testit "-plot line discrete cross" testit "-plot line line width 2" testit "-plot line line dash yes" testit "-plot line step width 2" testit "-plot line step dash yes" testit "-plot line quadratic width 2" testit "-plot line quadratic dash yes" testit "-plot line errorbar width 2" testit "-plot line errorbar style 2" testit "-sleep .5" testit "-plot close" doit fi tt="png" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-png photo/rose.png" testit "-png -slice photo/rose.png -noslice" testit "-frame delete" doit fi tt="port" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-port 5137" testit "-port_only" testit "-inet_only" doit fi tt="pow" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-pow" doit fi tt="prefs" if [ "$1" = "$tt" ]; then initit "$tt" testit "-prefs clear" # backward compatibility testit "-prefs bgcolor white" testit "-prefs nancolor white" testit "-prefs threads 8" doit fi tt="preserve" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-preserve scale no" testit "-preserve pan no" testit "-preserve regions no" doit fi tt="print" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" #testit "-psprint" testit "-psprint destination printer" testit "-psprint command lp" testit "-psprint filename ds9.ps" testit "-psprint color rgb" testit "-psprint level 2" testit "-psprint resolution 75" doit fi tt="private" if [ "$1" = "$tt" ]; then initit "$tt" testit "-private" doit fi tt="raise" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-lower" testit "-raise" doit fi tt="regions" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/region" testit "-regions regions/ds9.physical.reg" testit "-regions delete all" testit "-regions load regions/ds9.physical.reg" testit "-regions delete all" testit "-regions load 'regions/ds9.fk5*.reg'" testit "-regions delete all" testit "-regions load all regions/ds9.physical.reg" testit "-regions save foo.reg" testit "-regions list" testit "-regions list close" testit "-regions delete all" testit "-regions show yes" testit "-regions showtext yes" testit "-regions centroid auto no" testit "-regions centroid radius 10" testit "-regions centroid iteration 30" #testit "-regions getinfo" testit "-regions move front" testit "-regions move back" testit "-regions select all" testit "-regions select none" testit "-regions delete all" testit "-regions delete select" testit "-regions format ds9" testit "-regions system physical" testit "-regions sky fk5" testit "-regions skyformat degrees" testit "-regions delim nl" testit "-regions strip no" testit "-regions shape circle" testit "-regions color green" testit "-regions width 1" testit "-regions edit yes" testit "-regions include" testit "-regions command 'circle 100 100 20'" testit "-regions group new" testit "-regions group foo new" testit "-regions group foo update" testit "-regions group foo select" testit "-regions group foo color red" testit "-regions group foo copy" testit "-regions group foo delete" testit "-regions group foo cut" testit "-regions group foo font 'time 14 bold'" testit "-regions group foo move 100 100" testit "-regions group foo movefront" testit "-regions group foo moveback" testit "-regions group foo property delete no" testit "-regions delete all" testit "-regions command 'circle 100 100 20'" testit "-regions select all" testit "-regions copy" testit "-regions cut" testit "-regions paste" testit "-regions undo" testit "-regions delete all" testit "-regions load regions/ds9.physical.reg" testit "-regions select all" testit "-regions composite" testit "-regions desolve" testit "-regions delete all" testit "-regions command 'circle 100 100 20'" testit "-regions savetemplate foo.tpl" testit "-regions delete all" testit "-regions template foo.tpl" testit "-regions delete all" testit "-regions template foo.tpl at 202.46963 47.19556 fk5" testit "-regions delete all" doit fi tt="red" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-red" doit fi tt="restore" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-backup foo.bck" testit "-restore foo.bck" doit fi tt="rgb" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-rgb open" testit "-rgb close" testit "-rgb" testit "-rgb green" testit "-rgb channel blue" testit "-red" testit "-green" testit "-blue" testit "-rgb view blue off" testit "-rgb system wcs" testit "-rgb lock wcs yes" testit "-rgb lock crop yes" testit "-rgb lock slice yes" testit "-rgb lock bin yes" testit "-rgb lock scale yes" testit "-rgb lock colorbar yes" testit "-rgb lock smooth yes" testit "-rgb close" testit "-frame delete" doit fi tt="rgbarray" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big]" testit "-frame delete" doit fi tt="rgbcube" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-rgbcube rgbcube/float.fits" testit "-frame delete" doit fi tt="rgbimage" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new rgb" testit "-rgbimage mecube/float.fits" testit "-frame delete" doit fi tt="rotate" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-rotate open" testit "-rotate to 30" testit "-rotate 15" testit "-rotate close" testit "-frame reset" doit fi tt="samp" if [ "$1" = "$tt" ]; then initit "$tt" testit "-samp no" testit "-samp yes" testit "-samp broadcast" testit "-samp broadcast image" testit "-samp send aladin" testit "-samp send image aladin" doit fi tt="save" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/savefits" testit "-save foo.fits" testit "-save fits foo.fits" testit "-save foo.fits image" testit "-save fits foo.fits image" testit "-save foo.fits slice" testit "-save fits foo.fits slice" testit "-frame new" testit "-fits fits/table.fits" testit "-save foo.fits" testit "-save fits foo.fits" testit "-save foo.fits image" testit "-save fits foo.fits image" testit "-save foo.fits table" testit "-save fits foo.fits table" testit "-frame delete" testit "-frame new rgb" testit "-rgbimage mecube/float.fits" testit "-save rgbimage foo.fits" testit "-frame delete" testit "-frame new rgb" testit "-rgbcube rgbcube/float.fits" testit "-save rgbcube foo.fits" testit "-frame delete" testit "-frame new" testit "-mecube mecube/float.fits" testit "-save mecube foo.fits" testit "-frame delete" testit "-frame new" testit "-mosaicimage mosaic/mosaicimage.fits" testit "-save mosaicimage foo.fits" testit "-frame delete" testit "-frame new" testit "-mosaicimage mosaic/mosaicimage.fits" testit "-save mosaic foo.fits" testit "-frame delete" # backward compatibility testit "-savefits foo.fits" doit fi tt="saveimage" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-saveimage fits foo.fits" testit "-saveimage foo.fits" testit "-saveimage eps foo.eps" testit "-saveimage foo.eps" testit "-saveimage foo.gif" testit "-saveimage tiff foo.tiff none" testit "-saveimage foo.tiff" testit "-saveimage jpeg foo.jpeg 100" testit "-saveimage foo.jpeg" testit "-saveimage png foo.png" testit "-saveimage foo.png" # backward compatibility testit "-saveimage tiff none foo.tiff" testit "-saveimage jpeg 100 foo.jpeg" testit "-saveimage mpeg foo.mpeg" doit fi tt="scale" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-scale open" testit "-scale minmax" testit "-scale linear" testit "-scale log" testit "-scale pow" testit "-scale sqrt" testit "-scale squared" testit "-scale histequ" testit "-scale log exp 1000" testit "-scale log exp 10000" testit "-linear" testit "-log" testit "-pow" testit "-sqrt" testit "-squared" testit "-asinh" testit "-sinh" testit "-histequ" testit "-scale linear" testit "-scale minmax" testit "-scale zscale" testit "-scale zmax" testit "-scale user" testit "-scale mode minmax" testit "-scale mode zscale" testit "-scale mode zmax" testit "-scale mode 95" testit "-minmax" testit "-zscale" testit "-zmax" testit "-scale minmax" testit "-scale limits 0 100" testit "-scale global" testit "-scale local" testit "-scale scope global" testit "-scale scope local" testit "-scale mode minmax" testit "-scale linear" testit "-scale zscale" testit "-scale datasec yes" testit "-scale match" testit "-scale lock yes" testit "-scale lock no" testit "-scale close" doit fi # backward compatibility tt="sfits" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new" testit "-sfits sfits/float.hdr sfits/float.arr" testit "-sfits -slice sfits/float.hdr sfits/float.arr -noslice" testit "-sfits -mask sfits/float.hdr sfits/float.arr -nomask" testit "-frame delete" doit fi tt="shm" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" # no test doit fi tt="single" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-tile" doit fi tt="sinh" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-sinh" doit fi tt="skyview" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-skyview open" testit "-skyview close" testit "-skyview survey sdssi" testit "-skyview size 30 30 arcsec" testit "-skyview save no" testit "-skyview frame new" testit "-skyview update frame" testit "-skyview m3" testit "-skyview name m51" testit "-skyview name ''" testit "-skyview coord 13:29:55.301 +47:11:37.73 sexagesimal" testit "-skyview update frame" testit "-mode crosshair" testit "-skyview update crosshair" testit "-skyview close" testit "-mode pointer" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" testit "-frame delete" doit fi tt="sleep" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-sleep" testit "-sleep 2" doit fi tt="slice" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-slice" testit "-noslice" doit fi # backward compatibility tt="smosaic" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" # no test doit fi # backward compatibility tt="smosaicwcs" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" # no test doit fi # backward compatibility tt="smosaiciraf" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" # no test doit fi tt="smooth" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-smooth open" testit "-smooth" testit "-smooth yes" testit "-smooth function tophat" testit "-smooth radius 5" testit "-smooth match" testit "-smooth lock yes" testit "-smooth lock no" testit "-smooth no" testit "-smooth close" doit fi tt="squared" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-squared" doit fi tt="sqrt" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-sqrt" doit fi tt="source" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-source aux/source.tcl" doit fi # backward compatibility tt="srgbcube" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt...backward compatibility" testit "-frame new rgb" testit "-srgbcube srgbcube/float.hdr srgbcube/float.arr" testit "-frame delete" doit fi tt="tcl" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-tcl yes" doit fi tt="theme" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-theme native" doit fi tt="threads" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/tread" testit "-threads 8" doit fi tt="tiff" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt/tif" testit "-frame new" testit "-tiff photo/rose.tiff" testit "-tiff -slice photo/rose.tiff -noslice" testit "-frame delete" doit fi tt="tile" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new -fits data/img.fits" testit "-frame new -fits data/img.fits" testit "-tile" testit "-tile yes" testit "-tile row" testit "-tile column" testit "-tile grid" testit "-frame delete" testit "-frame delete" doit fi tt="title" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-title foobar" doit fi tt="unix" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-unix /tmp/.IMT%d" testit "-unix_only" doit fi tt="update" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-update" testit "-update 1 100 100 300 400" testit "-update now" testit "-update now 1 100 100 300 400" testit "-update off" testit "-update on" doit fi tt="url" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame new" testit "-url http://hea-www.harvard.edu/RD/ds9/data/img.fits" testit "-frame delete" doit fi tt="version" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-version" doit fi tt="view" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-frame delete" testit "-view layout vertical" testit "-sleep .5" testit "-view layout horizontal" testit "-sleep .5" testit "-view info no" testit "-view info yes" testit "-view panner no" testit "-view panner yes" testit "-view magnifier no" testit "-view magnifier yes" testit "-view buttons no" testit "-view buttons yes" testit "-view colorbar no" testit "-view colorbar yes" testit "-view graph horizontal yes" testit "-view graph horizontal no" testit "-view graph vertical yes" testit "-view graph vertical no" testit "-view filename no" testit "-view filename yes" testit "-view object no" testit "-view object yes" testit "-view minmax yes" testit "-view minmax no" testit "-view lowhigh yes" testit "-view lowhigh no" testit "-view frame no" testit "-view frame yes" testit "-view wcs no" testit "-view wcs yes" testit "-view wcsa yes" testit "-view wcsa no" testit "-view detector yes" testit "-view detector no" testit "-view amplifier yes" testit "-view amplifier no" testit "-view physical no" testit "-view physical yes" testit "-view image no" testit "-view image yes" testit "-sleep .5" testit "-frame new rgb" testit "-view red no" testit "-view red yes" testit "-view green no" testit "-view green yes" testit "-view blue no" testit "-view blue yes" testit "-frame delete" testit "-sleep .5" testit "-frame new -fits data/img.fits" testit "-rgb close" doit fi tt="vo" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-vo method open" testit "-vo method xpa" testit "-vo server 'http://cxc.harvard.edu/chandraed/list.txt'" testit "-vo internal yes" testit "-vo delay 10" testit "-vo connect foo" testit "-vo chandra-ed" testit "-vo disconnect chandra-ed" testit "-vo method close" testit "-web close" doit fi tt="wcs" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-wcs open" testit "-wcs wcs" testit "-wcs align yes" testit "-wcs system wcs" testit "-wcs sky galactic" testit "-wcs skyformat sexagesimal" testit "-wcs align no" testit "-wcs sky fk5" testit "-wcs skyformat degrees" testit "-wcs append aux/image.wcs" testit "-wcs replace aux/image.wcs" testit "-wcs reset" testit "-wcs skyformat sexagesimal" testit "-wcs close" doit fi tt="web" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-web hea-www.harvard.edu/RD/ds9/acknowledgment.html" testit "-web hea-www.harvard.edu/RD/ds9/helpdesk.html" testit "-web hvweb click back" testit "-web click forward" testit "-web clear" testit "-web close" doit fi tt="width" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-width 600" doit fi tt="xpa" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-xpa yes" testit "-xpa local" testit "-xpa noxpans" doit fi tt="zscale" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-zscale contrast .25" testit "-zscale sample 600" testit "-zscale line 120" doit fi tt="zoom" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-zoom open" testit "-zoom 2" testit "-zoom 2 4" testit "-zoom to 4" testit "-zoom to 2 4" testit "-zoom to fit" testit "-zoom close" testit "-frame reset" doit fi tt="exit" if [ "$1" = "$tt" -o -z "$1" ]; then initit "$tt" testit "-quit" doit fi rm -f foo.* echo "DONE" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis.sh��������������������������������������������������������������������������0000755�0001750�0001750�00000006715�12131345054�014436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** analysis.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ] then ds9& fi i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done # load default xpaset -p ds9 scale zscale xpaset -p ds9 fits data/img.fits xpaset -p ds9 regions file analysis/analysis.reg xpaset -p ds9 analysis clear xpaset -p ds9 analysis load analysis/analysis.ans # Main if [ "$1" = "help" -o -z "$1" ]; then echo "$j Help" xpaset -p ds9 analysis 0 fi # Web if [ "$1" = "web" -o -z "$1" ]; then echo "$j Web" xpaset -p ds9 analysis 1 echo "..$j web url" xpaset -p ds9 analysis 2 echo "..$j web file" xpaset -p ds9 analysis 3 fi # Basics if [ "$1" = "basics" -o -z "$1" ]; then echo "Basic" xpaset -p ds9 analysis 4 echo "..$j escape macro" xpaset -p ds9 analysis 5 echo "..$j non macro" xpaset -p ds9 analysis 6 echo "..$j \$xpa" xpaset -p ds9 analysis 7 echo "..$j \$xpa_method" xpaset -p ds9 analysis 8 echo "..$j \$vo_method" xpaset -p ds9 analysis 9 echo "..$j \$filename" xpaset -p ds9 analysis 10 echo "..$j \$filename(root)" xpaset -p ds9 analysis 11 echo "..$j \$filename(full)" xpaset -p ds9 analysis 12 echo "..$j \$filename(root,3d)" xpaset -p ds9 analysis 13 echo "..$j \$filename(full,3d)" xpaset -p ds9 analysis 14 echo "..$j \$filedialog(open)" xpaset -p ds9 analysis 15 echo "..$j \$filename(save)" xpaset -p ds9 analysis 16 echo "..$j \$width $height $depth $bitpix" xpaset -p ds9 analysis 17 echo "..$j \$pan" xpaset -p ds9 analysis 18 echo "..$j \$env" xpaset -p ds9 analysis 19 fi # Regions if [ "$1" = "regions" -o -z "$1" ]; then echo "$j Regions" xpaset -p ds9 analysis 20 echo "..$j \$regions" xpaset -p ds9 analysis 21 echo "..$j \$regions wcs" xpaset -p ds9 analysis 22 echo "..$j \$jnclude_regions_pixels" xpaset -p ds9 analysis 23 echo "..$j \$filename $regions" xpaset -p ds9 analysis 24 echo "..$j \$regions()" xpaset -p ds9 analysis 25 fi # Output if [ "$1" = "output" -o -z "$1" ]; then echo "$j Output" xpaset -p ds9 analysis 26 echo "..$j \$null" xpaset -p ds9 analysis 27 echo "..$j \$text" xpaset -p ds9 analysis 28 echo "..$j \$plot" xpaset -p ds9 analysis 29 echo "..$j \$plot(title,x,y,xyey)" xpaset -p ds9 analysis 30 echo "..$j \$plot(title,x,y,xyexey)" xpaset -p ds9 analysis 31 echo "..$j \$plot(title,x,y,4)" xpaset -p ds9 analysis 32 echo "..$j \$plot(title,x,y,5)" xpaset -p ds9 analysis 33 echo "..$j \$plot(stdin)" xpaset -p ds9 analysis 34 echo "..$j \$plot(stdin) text" xpaset -p ds9 analysis 35 echo "..$j \$plot(stdin) error" xpaset -p ds9 analysis 36 echo "..$j \$data" xpaset -p ds9 analysis 37 echo "..$j \$jmage" xpaset -p ds9 analysis 38 echo "..$j \$jmage(3d)" xpaset -p ds9 analysis 39 fi # Dialogs if [ "$1" = "dialogs" -o -z "$1" ]; then echo "$j Dialog" xpaset -p ds9 analysis 40 echo "..$j \$message(message)" xpaset -p ds9 analysis 41 echo "..$j \$message(ok,message)" xpaset -p ds9 analysis 42 echo "..$j \$entry(message)" xpaset -p ds9 analysis 43 fi # Params if [ "$1" = "params" -o -z "$1" ]; then echo "$j Param" xpaset -p ds9 analysis 44 echo "..$j \$param" xpaset -p ds9 analysis 45 echo "..$j \$param @file" xpaset -p ds9 analysis 46 fi # Network if [ "$1" = "network" -o -z "$1" ]; then echo "$j Network" xpaset -p ds9 analysis 47 echo "..$j \$url(http://)" xpaset -p ds9 analysis 48 fi echo "PASSED" # Other if [ "$1" = "other" -o -z "$1" ]; then xpaset -p ds9 analysis message {press 'x','y','z' to test interactive} fi echo "Done" ���������������������������������������������������./saods9/tests/fits.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000042�12113456764�013556� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������full.sh Fits fits fits save $1 $2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/xpa.sh�������������������������������������������������������������������������������0000755�0001750�0001750�00000222546�12131601437�013405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "XPA Tests" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9 -tcl& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi testit () { if [ -f xpa/${1}.xpa ] then o=`diff xpa/${1}.xpa ${1}.out` if [ "$o" = "" ] then echo "PASSED" else echo "FAILED" echo "$o" fi else echo "PASSED" fi rm -f ${1}.out xpaset -p ds9 single xpaset -p ds9 raise } echo echo "*** xpa.sh ***" # must be invoked # imexam # samp # shm # no test # shm # smosaic # smosaicwcs # smosaiciraf rm -f *.out xpaset -p ds9 scale zscale xpaset -p ds9 fits data/img.fits tt="2mass" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 2mass open xpaset -p ds9 2mass close xpaset -p ds9 2mass survey h xpaget ds9 2mass survey >> ${tt}.out xpaset -p ds9 2mass size 30 30 arcsec xpaget ds9 2mass size >> ${tt}.out xpaset -p ds9 2mass save no xpaget ds9 2mass save >> ${tt}.out xpaset -p ds9 2mass frame new xpaget ds9 2mass frame >> ${tt}.out xpaset -p ds9 2mass update frame xpaset -p ds9 2mass m1 xpaset -p ds9 2mass name m51 xpaget ds9 2mass name >> ${tt}.out xpaset -p ds9 2mass name {} xpaset -p ds9 2mass coord 00:42:44.404 +41:16:08.78 sexagesimal xpaget ds9 2mass coord >> ${tt}.out xpaset -p ds9 2mass update frame xpaset -p ds9 mode crosshair xpaset -p ds9 2mass update crosshair xpaset -p ds9 2mass close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="3d" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 3d open xpaset -p ds9 3d close xpaset -p ds9 3d xpaset -p ds9 3d vp 45 30 xpaget ds9 3d vp >> ${tt}.out xpaget ds9 3d az >> ${tt}.out xpaget ds9 3d el >> ${tt}.out xpaget ds9 3d scale >> ${tt}.out xpaget ds9 3d method >> ${tt}.out xpaget ds9 3d border >> ${tt}.out xpaget ds9 3d border color >> ${tt}.out xpaget ds9 3d compass >> ${tt}.out xpaget ds9 3d compass color >> ${tt}.out xpaget ds9 3d highlite >> ${tt}.out xpaget ds9 3d highlite color >> ${tt}.out xpaset -p ds9 3d vp 45 30 xpaset -p ds9 3d az 45 xpaset -p ds9 3d el 30 xpaset -p ds9 3d scale 5 xpaset -p ds9 3d method mip xpaset -p ds9 3d border yes xpaset -p ds9 3d border color red xpaset -p ds9 3d compass yes xpaset -p ds9 3d compass color red xpaset -p ds9 3d highlite yes xpaset -p ds9 3d highlite color red xpaset -p ds9 3d close xpaset -p ds9 frame delete testit $tt fi tt="about" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 about >> /dev/null testit $tt fi tt="align" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 align >> ${tt}.out xpaset -p ds9 align xpaset -p ds9 frame reset testit $tt fi tt="analysis" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 analysis clear xpaset -p ds9 analysis analysis/analysis.ans xpaget ds9 analysis > /dev/null xpaget ds9 analysis task > /dev/null #xpaget ds9 analysis entry 'hello world' xpaset -p ds9 analysis 0 xpaset -p ds9 analysis task 1 xpaset -p ds9 analysis task '{Basic Help}' xpaset -p ds9 analysis clear xpaset -p ds9 analysis load analysis/analysis.ans xpaset -p ds9 analysis clear load analysis/analysis.ans xpaset -p ds9 analysis clear cat analysis/analysis.ans | xpaset ds9 analysis load xpaset -p ds9 analysis clear #xpaset -p ds9 analysis message {This is a message} #xpaset -p ds9 analysis message yesno {This is a message} xpaset -p ds9 analysis text {This is text} cat analysis/analysis.txt | xpaset ds9 analysis text testit $tt fi tt="array" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 array array/float_big.arr[dim=256,bitpix=-32,endian=big] cat array/float_big.arr | xpaset ds9 array -[dim=256,bitpix=-32,endian=big] xpaget ds9 array little > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 array new array/float_big.arr[dim=256,bitpix=-32,endian=big] xpaset -p ds9 array mask array/float_big.arr[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete # backward compatibility xpaset -p ds9 frame new rgb cat rgbarray/float_big.rgb | xpaset ds9 array rgb -[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete cat rgbarray/float_big.rgb | xpaset ds9 array new rgb -[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete testit $tt fi tt="bg" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/background..." xpaget ds9 background >> ${tt}.out xpaget ds9 bg >> ${tt}.out xpaset -p ds9 background red xpaset -p ds9 background white testit $tt fi tt="backup" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 backup foo.bck testit $tt fi tt="bin" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 fits new fits/table.fits xpaset -p ds9 single xpaset -p ds9 bin open xpaset -p ds9 bin factor 4 xpaset -p ds9 bin factor 8 8 xpaset -p ds9 scale log xpaset -p ds9 scale minmax xpaset -p ds9 bin buffersize 1024 xpaset -p ds9 bin filter 'circle(4096,4096,200)' xpaset -p ds9 bin filter '' xpaset -p ds9 bin cols rawx rawy xpaset -p ds9 bin about center xpaset -p ds9 bin colsz x y pha xpaset -p ds9 bin depth 10 xpaset -p ds9 bin about 4096 4096 xpaset -p ds9 bin depth 1 xpaset -p ds9 bin function sum xpaset -p ds9 bin to fit xpaset -p ds9 bin match xpaset -p ds9 bin lock yes xpaset -p ds9 bin lock no xpaset -p ds9 bin close xpaget ds9 bin about >> ${tt}.out xpaget ds9 bin buffersize >> ${tt}.out xpaget ds9 bin cols >> ${tt}.out xpaget ds9 bin factor >> ${tt}.out xpaget ds9 bin filter >> ${tt}.out xpaget ds9 bin function >> ${tt}.out xpaget ds9 bin lock >> ${tt}.out xpaset -p ds9 frame delete testit $tt fi tt="blink" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 blink >> ${tt}.out xpaget ds9 blink interval >> ${tt}.out xpaset -p ds9 frame new xpaset -p ds9 blink xpaset -p ds9 blink yes xpaset -p ds9 blink interval .5 xpaset -p ds9 single xpaset -p ds9 frame first xpaset -p ds9 frame next xpaset -p ds9 frame delete testit $tt fi tt="catalog" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/cat..." xpaset -p ds9 catalog cds 2mass xpaget ds9 catalog >> ${tt}.out xpaget ds9 catalog header > /dev/null xpaget ds9 catalog cat2mass header > /dev/null xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog xpaset -p ds9 catalog close xpaset -p ds9 catalog cds "I/284" xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog import sb aux/ds9.cat xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog cds 2mass xpaset -p ds9 raise xpaset -p ds9 catalog plot '$Jmag' '$Hmag' '$e_Jmag' '$e_Hmag' xpaset -p ds9 catalog symbol condition '$Jmag>15' xpaset -p ds9 catalog symbol shape "{boxcircle point}" xpaset -p ds9 catalog symbol color red xpaset -p ds9 catalog symbol condition "{}" xpaset -p ds9 catalog symbol color red xpaset -p ds9 catalog symbol shape text xpaset -p ds9 catalog symbol font times xpaset -p ds9 catalog symbol fontsize 14 xpaset -p ds9 catalog symbol fontweight bold xpaset -p ds9 catalog symbol fontslant italic xpaset -p ds9 catalog symbol add xpaset -p ds9 catalog symbol remove xpaset -p ds9 catalog symbol load aux/ds9.sym xpaset -p ds9 catalog symbol save foo.sym xpaset -p ds9 catalog name m51 xpaset -p ds9 catalog coordinate 202.48 47.21 fk5 xpaset -p ds9 catalog system wcs xpaset -p ds9 catalog sky fk5 xpaset -p ds9 catalog skyformat degrees xpaset -p ds9 catalog size 22 22 arcmin xpaset -p ds9 catalog retrieve xpaset -p ds9 catalog save foo.cat xpaset -p ds9 catalog filter '$Jmag>15' xpaset -p ds9 catalog filter load aux/ds9.flt xpaset -p ds9 catalog retrieve xpaset -p ds9 catalog cancel #xpaset -p ds9 catalog print xpaset -p ds9 catalog server sao xpaset -p ds9 catalog sort "Jmag" incr xpaset -p ds9 catalog maxrows 3000 xpaset -p ds9 catalog allcols xpaset -p ds9 catalog allrows xpaset -p ds9 catalog ra "RAJ2000" xpaset -p ds9 catalog dec "DEJ2000" xpaset -p ds9 catalog psystem wcs xpaset -p ds9 catalog psky fk5 xpaset -p ds9 catalog hide xpaset -p ds9 catalog show xpaset -p ds9 catalog panto no #xpaset -p ds9 catalog edit yes xpaset -p ds9 catalog location 400 xpaset -p ds9 catalog header xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog 2mass xpaset -p ds9 catalog xmm xpaset -p ds9 catalog match function 1and2 xpaset -p ds9 catalog match error 2 arcsec xpaset -p ds9 catalog match return 1only xpaset -p ds9 catalog match unique no xpaset -p ds9 catalog match 2mass xmm xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog clear xpaset -p ds9 catalog close xpaset -p ds9 catalog clear xpaset -p ds9 catalog close testit $tt fi tt="cd" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 cd >> ${tt}.out xpaset -p ds9 cd . testit $tt fi tt="cmap" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 cmap >> ${tt}.out xpaget ds9 cmap file >> ${tt}.out xpaget ds9 cmap invert >> ${tt}.out xpaget ds9 cmap value >> ${tt}.out xpaget ds9 cmap lock >> ${tt}.out xpaset -p ds9 cmap open xpaset -p ds9 cmap Heat xpaset -p ds9 cmap load aux/ds9.sao xpaset -p ds9 cmap save foo.sao xpaset -p ds9 cmap invert yes xpaset -p ds9 cmap value 5 .2 xpaset -p ds9 cmap match xpaset -p ds9 cmap lock yes xpaset -p ds9 cmap lock no xpaset -p ds9 cmap tag load aux/ds9.tag xpaset -p ds9 cmap tag save foo.tag xpaset -p ds9 cmap tag delete xpaset -p ds9 cmap Grey xpaset -p ds9 cmap close testit $tt fi tt="colorbar" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 colorbar >> ${tt}.out xpaget ds9 colorbar orientation >> ${tt}.out xpaget ds9 colorbar numerics >> ${tt}.out xpaget ds9 colorbar space >> ${tt}.out xpaget ds9 colorbar font >> ${tt}.out xpaget ds9 colorbar fontsize >> ${tt}.out xpaget ds9 colorbar fontweight >> ${tt}.out xpaget ds9 colorbar fontslant >> ${tt}.out xpaget ds9 colorbar size >> ${tt}.out xpaget ds9 colorbar ticks >> ${tt}.out xpaset -p ds9 colorbar no xpaset -p ds9 colorbar yes xpaset -p ds9 colorbar vertical xpaset -p ds9 colorbar horizontal xpaset -p ds9 colorbar numerics no xpaset -p ds9 colorbar numerics yes xpaset -p ds9 colorbar space value xpaset -p ds9 colorbar space distance xpaset -p ds9 colorbar font times xpaset -p ds9 colorbar fontsize 30 xpaset -p ds9 colorbar fontweight bold xpaset -p ds9 colorbar fontslant roman xpaset -p ds9 colorbar font helvetica xpaset -p ds9 colorbar fontsize 10 xpaset -p ds9 colorbar fontweight normal xpaset -p ds9 colorbar fontslant roman xpaset -p ds9 colorbar size 30 xpaset -p ds9 colorbar ticks 9 xpaset -p ds9 colorbar size 20 xpaset -p ds9 colorbar ticks 11 testit $tt fi tt="console" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 console testit $tt fi tt="contour" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/contours..." xpaset -p ds9 contour yes xpaget ds9 contour >> ${tt}.out xpaget ds9 contour wcs fk5 >> ${tt}.out xpaget ds9 contour color >> ${tt}.out xpaget ds9 contour width >> ${tt}.out xpaget ds9 contour smooth >> ${tt}.out xpaget ds9 contour method >> ${tt}.out xpaget ds9 contour nlevels >> ${tt}.out xpaget ds9 contour scale >> ${tt}.out xpaget ds9 contour log exp >> ${tt}.out xpaget ds9 contour mode >> ${tt}.out xpaget ds9 contour limits >> ${tt}.out xpaget ds9 contour levels >> ${tt}.out xpaset -p ds9 contour open xpaset -p ds9 contour xpaset -p ds9 contour yes xpaset -p ds9 contour clear xpaset -p ds9 contour yes xpaset -p ds9 contour load aux/ds9.con wcs fk5 red 2 xpaset -p ds9 contour save foo.con wcs fk5 xpaset -p ds9 contour clear xpaset -p ds9 contour yes xpaset -p ds9 contour convert xpaset -p ds9 regions delete all xpaset -p ds9 contour loadlevels aux/ds9.lev xpaset -p ds9 contour savelevels foo.lev xpaset -p ds9 contour clear xpaset -p ds9 contour yes xpaset -p ds9 contour copy xpaset -p ds9 contour paste wcs red 2 xpaset -p ds9 contour clear xpaset -p ds9 contour yes xpaset -p ds9 contour color yellow xpaset -p ds9 contour width 2 xpaset -p ds9 contour smooth 5 xpaset -p ds9 contour method block xpaset -p ds9 contour nlevels 10 xpaset -p ds9 contour width 2 xpaset -p ds9 contour scale sqrt xpaset -p ds9 contour log exp 1000 xpaset -p ds9 contour mode zscale xpaset -p ds9 contour limits 1 100 xpaset -p ds9 contour levels "{1 10 100 1000}" xpaset -p ds9 contour clear xpaset -p ds9 contour close testit $tt fi tt="crop" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 mode crop xpaset -p ds9 crop 978 970 356 308 xpaget ds9 crop >> ${tt}.out xpaget ds9 crop wcs fk5 sexagesimal arcsec >> ${tt}.out xpaget ds9 crop lock >> ${tt}.out xpaset -p ds9 crop 978 970 356 308 xpaset -p ds9 crop 13:29:52.908 +47:11:38.19 35.279606 30.522805 wcs fk5 arcsec xpaset -p ds9 crop reset xpaset -p ds9 3d xpaset -p ds9 fits data/3d.fits xpaset -p ds9 3d vp 45 30 xpaset -p ds9 crop 3d 25 75 xpaset -p ds9 crop reset xpaset -p ds9 crop match wcs xpaset -p ds9 crop lock wcs xpaset -p ds9 crop lock none xpaset -p ds9 3d close xpaset -p ds9 frame delete xpaset -p ds9 mode pointer testit $tt fi tt="crosshair" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 mode crosshair xpaget ds9 crosshair >> ${tt}.out xpaget ds9 crosshair wcs fk5 sexagesimal >> ${tt}.out xpaget ds9 crosshair lock >> ${tt}.out xpaset -p ds9 crosshair 13:29:55.287 +47:11:37.73 wcs fk5 xpaset -p ds9 crosshair match wcs xpaset -p ds9 crosshair lock wcs xpaset -p ds9 crosshair lock none xpaset -p ds9 mode pointer testit $tt fi tt="cube" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/datacube..." xpaset -p ds9 cube open xpaset -p ds9 cube close xpaset -p ds9 fits new data/3d.fits xpaget ds9 cube >> ${tt}.out xpaget ds9 cube interval >> ${tt}.out xpaget ds9 cube axis >> ${tt}.out xpaget ds9 cube lock >> ${tt}.out xpaset -p ds9 cube 2 xpaset -p ds9 cube interval .5 xpaset -p ds9 cube axis 3 xpaset -p ds9 cube play xpaset -p ds9 cube stop xpaset -p ds9 cube match xpaset -p ds9 cube lock yes xpaset -p ds9 cube lock no xpaset -p ds9 cube close xpaset -p ds9 frame delete testit $tt fi tt="cursor" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 mode crosshair xpaset -p ds9 cursor 10 10 xpaset -p ds9 mode pointer testit $tt fi tt="data" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 data image 450 520 3 3 yes >> ${tt}.out xpaget ds9 data physical 899 1039 6 6 no >> ${tt}.out xpaget ds9 data fk5 202.4709 47.19681 0.00016517 0.00016517 yes >> ${tt}.out xpaget ds9 data wcs fk5 202.4709 47.19681 0.00016517 0.00016517 no >> ${tt}.out testit $tt fi tt="dsssao" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/dss..." xpaset -p ds9 dsssao open xpaset -p ds9 dsssao close xpaset -p ds9 dsssao size 30 30 arcsec xpaget ds9 dsssao size >> ${tt}.out xpaset -p ds9 dsssao save no xpaget ds9 dsssao save >> ${tt}.out xpaset -p ds9 dsssao frame new xpaget ds9 dsssao frame >> ${tt}.out xpaset -p ds9 dsssao update frame xpaset -p ds9 dsssao m1 xpaset -p ds9 dsssao name m51 xpaget ds9 dsssao name >> ${tt}.out xpaset -p ds9 dsssao name {} xpaset -p ds9 dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal xpaget ds9 dsssao coord >> ${tt}.out xpaset -p ds9 dsssao update frame xpaset -p ds9 mode crosshair xpaset -p ds9 dsssao update crosshair xpaset -p ds9 dsssao close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="dsseso" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 dsseso open xpaset -p ds9 dsseso close xpaset -p ds9 dsseso survey DSS2-red xpaget ds9 dsseso survey >> ${tt}.out xpaset -p ds9 dsseso size 30 30 arcsec xpaget ds9 dsseso size >> ${tt}.out xpaset -p ds9 dsseso save no xpaget ds9 dsseso save >> ${tt}.out xpaset -p ds9 dsseso frame new xpaget ds9 dsseso frame >> ${tt}.out xpaset -p ds9 dsseso update frame xpaset -p ds9 dsseso m1 xpaset -p ds9 dsseso name m51 xpaget ds9 dsseso name >> ${tt}.out xpaset -p ds9 dsseso name {} xpaset -p ds9 dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal xpaget ds9 dsseso coord >> ${tt}.out xpaset -p ds9 dsseso update frame xpaset -p ds9 mode crosshair xpaset -p ds9 dsseso update crosshair xpaset -p ds9 dsseso close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="dssstsci" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 dssstsci open xpaset -p ds9 dssstsci close xpaset -p ds9 dssstsci survey all xpaget ds9 dssstsci survey >> ${tt}.out xpaset -p ds9 dssstsci size 30 30 arcsec xpaget ds9 dssstsci size >> ${tt}.out xpaset -p ds9 dssstsci save no xpaget ds9 dssstsci save >> ${tt}.out xpaset -p ds9 dssstsci frame new xpaget ds9 dssstsci frame >> ${tt}.out xpaset -p ds9 dssstsci update frame xpaset -p ds9 dssstsci m1 xpaset -p ds9 dssstsci name m51 xpaget ds9 dssstsci name >> ${tt}.out xpaset -p ds9 dssstsci name {} xpaset -p ds9 dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal xpaget ds9 dssstsci coord >> ${tt}.out xpaset -p ds9 dssstsci update frame xpaset -p ds9 mode crosshair xpaset -p ds9 dssstsci update crosshair xpaset -p ds9 dssstsci close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="export" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 export array foo.arr little xpaset -p ds9 export foo.arr little xpaset -p ds9 export nrrd foo.nrrd big xpaset -p ds9 export foo.nrrd xpaset -p ds9 export gif foo.gif xpaset -p ds9 export foo.gif xpaset -p ds9 export tiff foo.tiff none xpaset -p ds9 export foo.tiff xpaset -p ds9 export jpeg foo.jpeg 10 xpaset -p ds9 export foo.jpeg xpaset -p ds9 export png foo.png xpaset -p ds9 export foo.png xpaset -p ds9 frame new rgb xpaset -p ds9 rgbcube rgbcube/float.fits xpaset -p ds9 export rgbarray foo.rgb little xpaset -p ds9 export foo.rgb little xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="file" if [ "$1" = "$tt" -o -z "$1" ]; then echo "$tt...backward compatibility..." xpaget ds9 file >> ${tt}.out echo -n " default..." xpaset -p ds9 frame new xpaset -p ds9 file fits/float.fits xpaset -p ds9 frame delete xpaset -p ds9 file new fits/float.fits xpaset -p ds9 file slice fits/float.fits xpaset -p ds9 file mask fits/float.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " fits..." xpaset -p ds9 frame new xpaset -p ds9 file fits fits/float.fits xpaset -p ds9 frame delete xpaset -p ds9 file new fits fits/float.fits xpaset -p ds9 file fits slice fits/float.fits xpaset -p ds9 file mask fits fits/float.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " sfits..." xpaset -p ds9 frame new xpaset -p ds9 file sfits sfits/float.hdr sfits/float.arr xpaset -p ds9 frame delete xpaset -p ds9 file new sfits sfits/float.hdr sfits/float.arr xpaset -p ds9 file mask sfits sfits/float.hdr sfits/float.arr xpaset -p ds9 frame delete echo "PASSED" echo -n " url..." xpaset -p ds9 frame new xpaset -p ds9 file url http://hea-www.harvard.edu/RD/ds9/data/img.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " rgbimage..." xpaset -p ds9 frame new rgb xpaset -p ds9 file rgbimage mecube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 file new rgbimage mecube/float.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " rgbcube..." xpaset -p ds9 frame new rgb xpaset -p ds9 file rgbcube rgbcube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 file new rgbcube rgbcube/float.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " srgbcube..." xpaset -p ds9 frame new rgb xpaset -p ds9 file srgbcube srgbcube/float.hdr srgbcube/float.arr xpaset -p ds9 frame delete xpaset -p ds9 file new srgbcube srgbcube/float.hdr srgbcube/float.arr xpaset -p ds9 frame delete echo "PASSED" echo -n " mecube..." xpaset -p ds9 frame new xpaset -p ds9 file mecube mecube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mecube mecube/float.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " multiframe..." xpaset -p ds9 frame new xpaset -p ds9 file multiframe mecube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 file new multiframe mecube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 single echo "PASSED" echo -n " mosaic..." xpaset -p ds9 frame new xpaset -p ds9 file mosaic mosaic/mosaicimage.fits xpaset -p ds9 frame clear xpaset -p ds9 file mosaic wcs mosaic/mosaicimage.fits xpaset -p ds9 frame clear xpaset -p ds9 file mosaic iraf mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaic mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaic mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaic wcs mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaic wcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicimage..." xpaset -p ds9 frame new xpaset -p ds9 file mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 frame clear xpaset -p ds9 file mosaicimage wcs mosaic/mosaicimage.fits xpaset -p ds9 frame clear xpaset -p ds9 file mosaicimage iraf mosaic/mosaicimage.fits xpaset -p ds9 frame clear xpaset -p ds9 file mosaicimage wfpc2 mosaic/hst.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicimage wcs mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaicimage wcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicwcs..." xpaset -p ds9 frame new xpaset -p ds9 file mosaicwcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicwcs mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaicwcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaiciraf..." xpaset -p ds9 frame new xpaset -p ds9 file mosaiciraf mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaiciraf mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaiciraf mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicimagewcs..." xpaset -p ds9 frame new xpaset -p ds9 file mosaicimagewcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicimagewcs mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaicimagewcs mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicimageiraf..." xpaset -p ds9 frame new xpaset -p ds9 file mosaicimageiraf mosaic/mosaicimage.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicimageiraf mosaic/mosaicimage.fits xpaset -p ds9 file mask mosaicimageiraf mosaic/mosaicimage.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicimagewfpc2..." xpaset -p ds9 frame new xpaset -p ds9 file mosaicimagewfpc2 mosaic/hst.fits xpaset -p ds9 frame delete xpaset -p ds9 file new mosaicimagewfpc2 mosaic/hst.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " smosaic...no test..." echo "PASSED" echo -n " smosaiciraf...no test..." echo "PASSED" echo -n " smosaicwcs...no test..." echo "PASSED" echo -n " array..." xpaset -p ds9 frame new xpaset -p ds9 file array array/float_big.arr[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete xpaset -p ds9 file new array array/float_big.arr[dim=256,bitpix=-32,endian=big] xpaset -p ds9 file mask array array/float_big.arr[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete echo "PASSED" echo -n " rgbarray..." xpaset -p ds9 frame new rgb xpaset -p ds9 file rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete xpaset -p ds9 file new rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete echo "PASSED" echo -n " photo..." xpaset -p ds9 frame new xpaset -p ds9 file photo photo/rose.tiff xpaset -p ds9 frame delete xpaset -p ds9 file new photo photo/rose.tiff xpaset -p ds9 file photo slice photo/rose.tiff xpaset -p ds9 frame delete echo "PASSED" echo -n " file save..." xpaset -p ds9 file save foo.fits echo "PASSED" echo -n " file save gz..." xpaset -p ds9 file save gz foo.fits.gz echo "PASSED" echo -n " file save resample..." xpaset -p ds9 file save resample foo.fits echo "PASSED" echo -n " file save resample gz..." xpaset -p ds9 file save resample gz foo.fits.gz echo "PASSED" testit $tt fi tt="first" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 first open xpaset -p ds9 first close xpaset -p ds9 first size 30 30 arcsec xpaget ds9 first size >> ${tt}.out xpaset -p ds9 first save no xpaget ds9 first save >> ${tt}.out xpaset -p ds9 first frame new xpaget ds9 first frame >> ${tt}.out xpaset -p ds9 first update frame xpaset -p ds9 first m3 xpaset -p ds9 first name m51 xpaget ds9 first name >> ${tt}.out xpaset -p ds9 first name {} xpaset -p ds9 first coord 13:29:52.37 +47:11:40.8 sexagesimal xpaget ds9 first coord >> ${tt}.out xpaset -p ds9 first update frame xpaset -p ds9 mode crosshair xpaset -p ds9 first update crosshair xpaset -p ds9 first close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="fits" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 fits > /dev/null xpaget ds9 fits image > /dev/null xpaget ds9 fits slice > /dev/null cat fits/table.fits | xpaset ds9 fits new xpaget ds9 fits table > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 frame new xpaset -p ds9 fits fits/float.fits xpaset -p ds9 frame delete xpaset -p ds9 fits new fits/float.fits xpaset -p ds9 fits slice fits/float.fits xpaset -p ds9 fits mask fits/float.fits xpaset -p ds9 frame delete xpaget ds9 fits size >> ${tt}.out xpaget ds9 fits width >> ${tt}.out xpaget ds9 fits height >> ${tt}.out xpaget ds9 fits depth >> ${tt}.out xpaget ds9 fits bitpix >> ${tt}.out xpaget ds9 fits type >> ${tt}.out xpaget ds9 fits size wcs fk5 arcsec >> ${tt}.out xpaget ds9 fits header >> ${tt}.out xpaget ds9 fits header 1 >> ${tt}.out xpaget ds9 fits header keyword "'BITPIX'" >> ${tt}.out xpaget ds9 fits header 1 keyword "'BITPIX'" >> ${tt}.out xpaset -p ds9 single # backward compatibility xpaget ds9 fits image > /dev/null xpaget ds9 fits image gz > /dev/null xpaget ds9 fits resample > /dev/null xpaget ds9 fits resample gz > /dev/null xpaset -p ds9 frame new xpaset -p ds9 fits fits/table.fits xpaget ds9 fits table > /dev/null xpaget ds9 fits table gz> /dev/null xpaset -p ds9 frame delete xpaset -p ds9 frame new cat mecube/float.fits | xpaset ds9 fits mecube xpaset -p ds9 frame delete cat mecube/float.fits | xpaset ds9 fits new mecube xpaset -p ds9 frame delete xpaset -p ds9 frame new cat mosaic/mosaicimage.fits | xpaset ds9 fits mosaicimage cat mosaic/mosaicimage.fits | xpaset ds9 fits mosaicimage wcs xpaset -p ds9 frame delete cat mosaic/mosaicimage.fits | xpaset ds9 fits new mosaicimage cat mosaic/mosaicimage.fits | xpaset ds9 fits mask mosaicimage xpaset -p ds9 frame delete xpaset -p ds9 frame new cat mosaic/mosaicimage.fits | xpaset ds9 fits mosaicimagewcs xpaset -p ds9 frame delete cat mosaic/mosaicimage.fits | xpaset ds9 fits new mosaicimagewcs cat mosaic/mosaicimage.fits | xpaset ds9 fits mask mosaicimagewcs xpaset -p ds9 frame delete xpaset -p ds9 frame new cat mosaic/mosaicimage.fits | xpaset ds9 fits mosaicimageiraf xpaset -p ds9 frame delete cat mosaic/mosaicimage.fits | xpaset ds9 fits new mosaicimageiraf cat mosaic/mosaicimage.fits | xpaset ds9 fits mask mosaicimageiraf xpaset -p ds9 frame delete xpaset -p ds9 frame new cat mosaic/hst.fits | xpaset ds9 fits mosaicimagewfpc2 xpaset -p ds9 frame delete cat mosaic/hst.fits | xpaset ds9 fits new mosaicimagewfpc2 xpaset -p ds9 frame delete xpaset -p ds9 frame new rgb cat rgbcube/float.fits | xpaset ds9 fits rgbcube xpaset -p ds9 frame delete cat rgbcube/float.fits | xpaset ds9 fits new rgbcube xpaset -p ds9 frame delete xpaset -p ds9 frame new rgb cat mecube/float.fits | xpaset ds9 fits rgbimage xpaset -p ds9 frame delete cat mecube/float.fits | xpaset ds9 fits new rgbimage xpaset -p ds9 frame delete testit $tt fi tt="frame" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 frame lock >> ${tt}.out xpaget ds9 frame has amplifier >> ${tt}.out xpaget ds9 frame has datamin >> ${tt}.out xpaget ds9 frame has datasec >> ${tt}.out xpaget ds9 frame has detector >> ${tt}.out xpaget ds9 frame has grid >> ${tt}.out xpaget ds9 frame has iis >> ${tt}.out xpaget ds9 frame has irafmin >> ${tt}.out xpaget ds9 frame has physical >> ${tt}.out xpaget ds9 frame has smooth >> ${tt}.out xpaget ds9 frame has contour >> ${tt}.out xpaget ds9 frame has contour aux >> ${tt}.out xpaget ds9 frame has fits >> ${tt}.out xpaget ds9 frame has fits bin >> ${tt}.out xpaget ds9 frame has fits cube >> ${tt}.out xpaget ds9 frame has fits mosaic >> ${tt}.out xpaget ds9 frame has marker highlite >> ${tt}.out xpaget ds9 frame has marker paste >> ${tt}.out xpaget ds9 frame has marker select >> ${tt}.out xpaget ds9 frame has marker undo >> ${tt}.out xpaget ds9 frame has system physical >> ${tt}.out xpaget ds9 frame has wcs wcsa >> ${tt}.out xpaget ds9 frame has wcs equatorial wcsa >> ${tt}.out xpaset -p ds9 frame new rgb xpaset -p ds9 frame delete xpaset -p ds9 frame new 3d xpaset -p ds9 frame delete xpaset -p ds9 frame new xpaset -p ds9 fits data/img.fits xpaset -p ds9 tile xpaget ds9 frame > /dev/null xpaget ds9 frame frameno > /dev/null xpaget ds9 frame all > /dev/null xpaget ds9 frame active > /dev/null xpaset -p ds9 frame center xpaset -p ds9 frame center 1 xpaset -p ds9 frame center all xpaset -p ds9 frame reset xpaset -p ds9 frame reset 1 xpaset -p ds9 frame reset all xpaset -p ds9 frame refresh xpaset -p ds9 frame refresh 1 xpaset -p ds9 frame refresh all xpaset -p ds9 frame hide xpaset -p ds9 frame hide 1 xpaset -p ds9 frame hide all xpaset -p ds9 frame show xpaset -p ds9 frame show 1 xpaset -p ds9 frame show all xpaset -p ds9 frame move first xpaset -p ds9 frame move back xpaset -p ds9 frame move forward xpaset -p ds9 frame move last xpaset -p ds9 frame first xpaset -p ds9 frame prev xpaset -p ds9 frame next xpaset -p ds9 frame last xpaset -p ds9 frame frameno 1 xpaset -p ds9 frame 2 xpaset -p ds9 frame match wcs xpaset -p ds9 frame lock wcs xpaset -p ds9 frame lock none xpaset -p ds9 frame clear xpaset -p ds9 frame clear 1 xpaset -p ds9 frame clear all xpaset -p ds9 frame delete xpaset -p ds9 frame delete 1 xpaset -p ds9 frame delete all xpaset -p ds9 fits new data/img.fits xpaset -p ds9 rgb close xpaset -p ds9 3d close testit $tt fi tt="gif" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 gif photo/rose.gif cat photo/rose.gif | xpaset ds9 gif xpaget ds9 gif > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 gif new photo/rose.gif xpaset -p ds9 gif slice photo/rose.gif xpaset -p ds9 frame delete testit $tt fi tt="grid" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 wcs wcs xpaget ds9 grid >> ${tt}.out xpaget ds9 grid type >> ${tt}.out xpaget ds9 grid system >> ${tt}.out xpaget ds9 grid sky >> ${tt}.out xpaget ds9 grid skyformat >> ${tt}.out xpaget ds9 grid grid >> ${tt}.out xpaget ds9 grid grid color >> ${tt}.out xpaget ds9 grid grid width >> ${tt}.out xpaget ds9 grid grid style >> ${tt}.out xpaget ds9 grid grid gap1 >> ${tt}.out xpaget ds9 grid grid gap2 >> ${tt}.out xpaget ds9 grid axes >> ${tt}.out xpaget ds9 grid axes color >> ${tt}.out xpaget ds9 grid axes width >> ${tt}.out xpaget ds9 grid axes style >> ${tt}.out xpaget ds9 grid axes type >> ${tt}.out xpaget ds9 grid axes origin >> ${tt}.out xpaget ds9 grid format1 >> ${tt}.out xpaget ds9 grid format2 >> ${tt}.out xpaget ds9 grid tickmarks >> ${tt}.out xpaget ds9 grid tickmarks color >> ${tt}.out xpaget ds9 grid tickmarks width >> ${tt}.out xpaget ds9 grid tickmarks style >> ${tt}.out xpaget ds9 grid border >> ${tt}.out xpaget ds9 grid border color >> ${tt}.out xpaget ds9 grid border width >> ${tt}.out xpaget ds9 grid border style >> ${tt}.out xpaget ds9 grid numerics >> ${tt}.out xpaget ds9 grid numerics font >> ${tt}.out xpaget ds9 grid numerics fontweight >> ${tt}.out xpaget ds9 grid numerics fontslant >> ${tt}.out xpaget ds9 grid numerics fontsize >> ${tt}.out xpaget ds9 grid numerics color >> ${tt}.out xpaget ds9 grid numerics gap1 >> ${tt}.out xpaget ds9 grid numerics gap2 >> ${tt}.out xpaget ds9 grid numerics type >> ${tt}.out xpaget ds9 grid numerics vertical >> ${tt}.out xpaget ds9 grid title >> ${tt}.out xpaget ds9 grid title text >> ${tt}.out xpaget ds9 grid title def >> ${tt}.out xpaget ds9 grid title gap >> ${tt}.out xpaget ds9 grid title font >> ${tt}.out xpaget ds9 grid title fontweight >> ${tt}.out xpaget ds9 grid title fontslant >> ${tt}.out xpaget ds9 grid title fontsize >> ${tt}.out xpaget ds9 grid title color >> ${tt}.out xpaget ds9 grid labels >> ${tt}.out xpaget ds9 grid labels text1 >> ${tt}.out xpaget ds9 grid labels def1 >> ${tt}.out xpaget ds9 grid labels gap1 >> ${tt}.out xpaget ds9 grid labels text2 >> ${tt}.out xpaget ds9 grid labels def2 >> ${tt}.out xpaget ds9 grid labels gap2 >> ${tt}.out xpaget ds9 grid labels font >> ${tt}.out xpaget ds9 grid labels fontweight >> ${tt}.out xpaget ds9 grid labels fontslant >> ${tt}.out xpaget ds9 grid labels fontsize >> ${tt}.out xpaget ds9 grid labels color >> ${tt}.out xpaset -p ds9 grid open xpaset -p ds9 grid close xpaset -p ds9 grid xpaset -p ds9 grid yes xpaset -p ds9 grid type analysis xpaset -p ds9 grid system wcs xpaset -p ds9 grid sky fk5 xpaset -p ds9 grid skyformat degrees xpaset -p ds9 grid grid yes xpaset -p ds9 grid grid color red xpaset -p ds9 grid grid width 2 xpaset -p ds9 grid grid style 1 xpaset -p ds9 grid grid gap1 .01 xpaset -p ds9 grid grid gap2 .01 xpaset -p ds9 grid axes yes xpaset -p ds9 grid axes color red xpaset -p ds9 grid axes width 2 xpaset -p ds9 grid axes style 1 xpaset -p ds9 grid axes type exterior xpaset -p ds9 grid axes origin lll xpaset -p ds9 grid format1 d.2 xpaset -p ds9 grid format2 d.2 xpaset -p ds9 grid tickmarks yes xpaset -p ds9 grid tickmarks color red xpaset -p ds9 grid tickmarks width 2 xpaset -p ds9 grid tickmarks style 1 xpaset -p ds9 grid border yes xpaset -p ds9 grid border color red xpaset -p ds9 grid border width 2 xpaset -p ds9 grid border style 1 xpaset -p ds9 grid numerics yes xpaset -p ds9 grid numerics font courier xpaset -p ds9 grid numerics fontweight bold xpaset -p ds9 grid numerics fontslant roman xpaset -p ds9 grid numerics fontsize 12 xpaset -p ds9 grid numerics color red xpaset -p ds9 grid numerics gap1 10 xpaset -p ds9 grid numerics gap2 10 xpaset -p ds9 grid numerics type exterior xpaset -p ds9 grid numerics vertical yes xpaset -p ds9 grid title yes xpaset -p ds9 grid title text {Hello World} xpaset -p ds9 grid title def yes xpaset -p ds9 grid title gap 10 xpaset -p ds9 grid title font courier xpaset -p ds9 grid title fontweight bold xpaset -p ds9 grid title fontslant roman xpaset -p ds9 grid title fontsize 12 xpaset -p ds9 grid title color red xpaset -p ds9 grid labels yes xpaset -p ds9 grid labels text1 {Hello World} xpaset -p ds9 grid labels def1 yes xpaset -p ds9 grid labels gap1 10 xpaset -p ds9 grid labels text2 {Hello World} xpaset -p ds9 grid labels def2 yes xpaset -p ds9 grid labels gap2 10 xpaset -p ds9 grid labels font courier xpaset -p ds9 grid labels fontweight bold xpaset -p ds9 grid labels fontslant roman xpaset -p ds9 grid labels fontsize 12 xpaset -p ds9 grid labels color red xpaset -p ds9 grid save foo.grd xpaset -p ds9 grid load foo.grd xpaset -p ds9 grid reset xpaset -p ds9 grid no xpaset -p ds9 grid close testit $tt fi tt="header" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 header xpaset -p ds9 header save foo.txt xpaset -p ds9 header close xpaset -p ds9 header 1 xpaset -p ds9 header close 1 testit $tt fi tt="height" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 height >> /dev/null xpaset -p ds9 height 443 testit $tt fi tt="iconify" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 iconify >> ${tt}.out xpaset -p ds9 iconify xpaset -p ds9 iconify yes xpaset -p ds9 iconify no testit $tt fi tt="iis" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 iis filename >> ${tt}.out xpaget ds9 iis filename 1 >> ${tt}.out xpaset -p ds9 iis filename foo.fits xpaset -p ds9 iis filename foo.fits 1 testit $tt fi tt="imexam" if [ "$1" = "$tt" ]; then echo "$tt..." echo "Select coordinate point:" xpaget ds9 imexam coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Press key:" xpaget ds9 imexam key coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Press either:" xpaget ds9 imexam any coordinate wcs fk5 degrees echo " ok" sleep .5 echo "Select value point:" xpaget ds9 imexam data echo " ok" sleep .5 echo "Press key:" xpaget ds9 imexam key data echo " ok" sleep .5 echo "Press any:" xpaget ds9 imexam any data echo " ok" sleep .5 testit $tt fi tt="jpeg" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/jpg..." xpaset -p ds9 frame new xpaset -p ds9 jpeg photo/rose.jpeg cat photo/rose.jpeg | xpaset ds9 jpeg xpaget ds9 jpeg > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 jpeg new photo/rose.jpeg xpaset -p ds9 jpeg slice photo/rose.jpeg xpaset -p ds9 frame delete testit $tt fi tt="lock" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 lock frame >> ${tt}.out xpaget ds9 lock crosshair >> ${tt}.out xpaget ds9 lock crop >> ${tt}.out xpaget ds9 lock slice >> ${tt}.out xpaget ds9 lock bin >> ${tt}.out xpaget ds9 lock scale >> ${tt}.out xpaget ds9 lock colorbar >> ${tt}.out xpaget ds9 lock smooth >> ${tt}.out xpaset -p ds9 fits new data/img.fits xpaset -p ds9 tile xpaset -p ds9 mode crosshair xpaset -p ds9 lock frame wcs xpaset -p ds9 lock frame none xpaset -p ds9 lock crosshair wcs xpaset -p ds9 crosshair 13:29:56 +47:11:38 wcs fk5 xpaset -p ds9 lock crosshair none xpaset -p ds9 lock crop wcs xpaset -p ds9 lock crop none xpaset -p ds9 lock slice yes xpaset -p ds9 lock slice no xpaset -p ds9 lock bin yes xpaset -p ds9 lock bin no xpaset -p ds9 lock scale yes xpaset -p ds9 lock scale no xpaset -p ds9 lock colorbar yes xpaset -p ds9 lock colorbar no xpaset -p ds9 lock smooth yes xpaset -p ds9 lock smooth no xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 wcs align no testit $tt fi tt="lower" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 lower xpaset -p ds9 raise testit $tt fi tt="magnifier" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 magnifier color >> ${tt}.out xpaget ds9 magnifier zoom >> ${tt}.out xpaget ds9 magnifier cursor >> ${tt}.out xpaget ds9 magnifier region >> ${tt}.out xpaset -p ds9 magnifier color white xpaset -p ds9 magnifier zoom 4 xpaset -p ds9 magnifier cursor yes xpaset -p ds9 magnifier region yes testit $tt fi tt="mask" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 mask color >> ${tt}.out xpaget ds9 mask mark >> ${tt}.out xpaget ds9 mask transparency >> ${tt}.out xpaset -p ds9 mask open xpaset -p ds9 mask color cyan xpaset -p ds9 mask clear xpaset -p ds9 mask close sleep .5 testit $tt fi tt="match" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 fits new data/img.fits xpaset -p ds9 tile xpaset -p ds9 mode crosshair xpaset -p ds9 match frame wcs xpaset -p ds9 match frame image xpaset -p ds9 match crosshair wcs xpaset -p ds9 match crop wcs xpaset -p ds9 match slice xpaset -p ds9 match bin xpaset -p ds9 match scale xpaset -p ds9 match colorbar xpaset -p ds9 match smooth xpaset -p ds9 frame delete xpaset -p ds9 mode pointer testit $tt fi tt="mecube" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 mecube mecube/float.fits cat mecube/float.fits | xpaset ds9 mecube xpaget ds9 mecube > /dev/null xpaset -p ds9 frame delete testit $tt fi tt="minmax" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 minmax >> ${tt}.out xpaget ds9 minmax mode >> ${tt}.out xpaget ds9 minmax sample >> ${tt}.out xpaset -p ds9 minmax scan xpaset -p ds9 minmax mode scan xpaset -p ds9 minmax interval 10 testit $tt fi tt="mode" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 mode >> ${tt}.out xpaset -p ds9 mode none xpaset -p ds9 mode crosshair xpaset -p ds9 mode colorbar xpaset -p ds9 mode pan xpaset -p ds9 mode zoom xpaset -p ds9 mode rotate xpaset -p ds9 mode catalog xpaset -p ds9 mode examine xpaset -p ds9 mode pointer testit $tt fi tt="mosaic" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 mosaic mosaic/mosaicimage.fits xpaget ds9 mosaic > /dev/null xpaset -p ds9 frame clear xpaset -p ds9 mosaic wcs mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaic wcs xpaset -p ds9 frame clear xpaset -p ds9 mosaic iraf mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaic iraf xpaset -p ds9 frame delete xpaset -p ds9 mosaic new mosaic/mosaicimage.fits xpaset -p ds9 mosaic mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi tt="mosaicimage" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits xpaget ds9 mosaicimage > /dev/null xpaset -p ds9 frame clear xpaset -p ds9 mosaicimage wcs mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimage wcs xpaset -p ds9 frame clear xpaset -p ds9 mosaicimage iraf mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimage iraf xpaset -p ds9 frame clear xpaset -p ds9 mosaicimage wfpc2 mosaic/hst.fits xpaset -p ds9 frame clear cat mosaic/hst.fits | xpaset ds9 mosaicimage wfpc2 xpaset -p ds9 frame delete xpaset -p ds9 mosaicimage new mosaic/mosaicimage.fits xpaset -p ds9 mosaicimage mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="mosaicwcs" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 mosaicwcs mosaic/mosaicimage.fits xpaget ds9 mosaicwcs > /dev/null xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaicwcs xpaset -p ds9 frame delete xpaset -p ds9 mosaicwcs new mosaic/mosaicimage.fits xpaset -p ds9 mosaicwcs mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="mosaiciraf" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 mosaiciraf mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaiciraf xpaset -p ds9 frame delete xpaset -p ds9 mosaiciraf new mosaic/mosaicimage.fits xpaset -p ds9 mosaiciraf mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="mosaicimagewcs" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimagewcs mosaic/mosaicimage.fits xpaget ds9 mosaicimagewcs > /dev/null xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimagewcs xpaset -p ds9 frame delete xpaset -p ds9 mosaicimagewcs new mosaic/mosaicimage.fits xpaset -p ds9 mosaicimagewcs mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="mosaicimageiraf" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimageiraf mosaic/mosaicimage.fits xpaset -p ds9 frame clear cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimageiraf xpaset -p ds9 frame delete xpaset -p ds9 mosaicimageiraf new mosaic/mosaicimage.fits xpaset -p ds9 mosaicimageiraf mask mosaic/mosaicimage.fits xpaset -p ds9 frame delete testit $tt fi # backward compatibility tt="mosaicimagewfpc2" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimage wfpc2 mosaic/hst.fits xpaset -p ds9 frame clear cat mosaic/hst.fits | xpaset ds9 mosaicimagewfpc2 xpaset -p ds9 frame delete testit $tt fi # movie will fail if moved from corner tt="movie" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/savempeg..." xpaset -p ds9 width 715 xpaset -p ds9 height 450 xpaset -p ds9 movie foo.mpg xpaset -p ds9 movie frame foo.mpg xpaset -p ds9 movie slice foo.mpg xpaset -p ds9 frame new 3d xpaset -p ds9 movie 3d foo.mpg number 1 azfrom 0 azto 0 elfrom 0 elto 0 slfrom 1 slto 1 repeat 1 xpaset -p ds9 frame delete # backward compatibility xpaset -p ds9 savempeg foo.mpg testit $tt fi tt="multiframe" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/memf..." xpaset -p ds9 frame new xpaset -p ds9 multiframe mecube/float.fits xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="nameserver" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 nameserver open xpaset -p ds9 nameserver close xpaset -p ds9 nameserver m51 xpaget ds9 nameserver >> ${tt}.out xpaget ds9 nameserver server >> ${tt}.out xpaget ds9 nameserver skyformat >> ${tt}.out xpaget ds9 nameserver m51 >> ${tt}.out xpaset -p ds9 nameserver name m51 xpaset -p ds9 nameserver server simbad-cds xpaset -p ds9 nameserver skyformat degrees xpaset -p ds9 mode crosshair xpaset -p ds9 nameserver crosshair xpaset -p ds9 nameserver pan xpaset -p ds9 nameserver close xpaset -p ds9 mode pointer xpaset -p ds9 frame reset testit $tt fi tt="nan" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 nan >> ${tt}.out xpaset -p ds9 nan blue xpaset -p ds9 nan white testit $tt fi tt="nrrd" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 nrrd nrrd/float_big_raw.nrrd cat nrrd/float_big_raw.nrrd | xpaset ds9 nrrd xpaget ds9 nrrd > /dev/null xpaget ds9 nrrd big > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 nrrd new nrrd/float_big_raw.nrrd xpaset -p ds9 nrrd mask nrrd/float_big_raw.nrrd xpaset -p ds9 frame delete testit $tt fi tt="nvss" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 nvss open xpaset -p ds9 nvss close xpaset -p ds9 nvss size 30 30 arcsec xpaget ds9 nvss size >> ${tt}.out xpaset -p ds9 nvss save no xpaget ds9 nvss save >> ${tt}.out xpaset -p ds9 nvss frame new xpaget ds9 nvss frame >> ${tt}.out xpaset -p ds9 nvss update frame xpaset -p ds9 nvss m3 xpaset -p ds9 nvss name m51 xpaget ds9 nvss name >> ${tt}.out xpaset -p ds9 nvss name {} xpaset -p ds9 nvss coord 13:29:52.37 +47:11:40.8 sexagesimal xpaget ds9 nvss coord >> ${tt}.out xpaset -p ds9 nvss update frame xpaset -p ds9 mode crosshair xpaset -p ds9 nvss update crosshair xpaset -p ds9 nvss close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="orient" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 orient open xpaset -p ds9 orient none xpaset -p ds9 orient x xpaset -p ds9 orient y xpaset -p ds9 orient xy xpaset -p ds9 orient close xpaget ds9 orient >> ${tt}.out xpaset -p ds9 frame reset testit $tt fi tt="pagesetup" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 pspagesetup orient >> ${tt}.out xpaget ds9 pspagesetup scale >> ${tt}.out xpaget ds9 pspagesetup size >> ${tt}.out xpaset -p ds9 pspagesetup orient portrait xpaset -p ds9 pspagesetup scale 100 xpaset -p ds9 pspagesetup size letter testit $tt fi tt="pan" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 pan physical >> ${tt}.out xpaget ds9 pan wcs fk5 sexagesimal >> ${tt}.out xpaset -p ds9 pan open xpaset -p ds9 pan 100 100 image xpaset -p ds9 pan to 13:29:55.666 +47:12:16.29 wcs fk5 xpaset -p ds9 pan close xpaset -p ds9 frame reset testit $tt fi tt="pixeltable" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 pixeltable >> ${tt}.out xpaset -p ds9 pixeltable xpaset -p ds9 pixeltable yes xpaset -p ds9 pixeltable no xpaset -p ds9 pixeltable open xpaset -p ds9 pixeltable close testit $tt fi tt="plot" if [ "$1" = "$tt" -o -z "$1" ]; then echo "$tt..." echo -n " empty plot..." xpaset -p ds9 plot xpaget ds9 plot >> ${tt}.out sleep .5 xpaset -p ds9 plot close xpaset -p ds9 plot new xpaset -p ds9 plot new bar xpaset -p ds9 plot new scatter sleep .5 xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot new name foo xpaset -p ds9 plot new name foo bar xpaset -p ds9 plot new name foo scatter sleep .5 xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" xy xpaset -p ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" xy xpaset -p ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" xy sleep .5 xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n " data..." xpaset -p ds9 plot new name foo xpaset -p ds9 plot new cat plot/xy.dat | xpaset ds9 plot foo data xy cat plot/xy.dat | xpaset ds9 plot data xy sleep .5 xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n " clear/close..." cat plot/stdin.xy.dat | xpaset ds9 plot new stdin sleep .5 xpaset -p ds9 plot clear xpaset -p ds9 plot close echo "PASSED" echo -n " save/load..." xpaset -p ds9 plot new xpaset -p ds9 plot load plot/xy.dat xy xpaset -p ds9 plot save foo.dat xpaset -p ds9 plot saveconfig foo.plt xpaset -p ds9 plot loadconfig foo.plt sleep .5 xpaset -p ds9 plot close echo "PASSED" echo -n " config..." xpaset -p ds9 plot new xpaset -p ds9 plot saveconfig foo.cfg xpaset -p ds9 plot loadconfig foo.cfg sleep .5 xpaset -p ds9 plot close echo "PASSED" echo -n " print..." xpaset -p ds9 plot new #xpaset -p ds9 plot print xpaset -p ds9 plot print destination printer xpaset -p ds9 plot print command "lp" xpaset -p ds9 plot print filename "foo.ps" xpaset -p ds9 plot print color rgb xpaset -p ds9 plot pagesetup orient portrait xpaset -p ds9 plot pagesetup size letter sleep .5 xpaset -p ds9 plot close echo "PASSED" echo -n " graph..." xpaset -p ds9 plot new xpaset -p ds9 plot load plot/xy.dat xy xpaset -p ds9 plot graph grid x no xpaset -p ds9 plot graph grid y yes xpaset -p ds9 plot graph log x no xpaset -p ds9 plot graph log y no xpaset -p ds9 plot graph flip x no xpaset -p ds9 plot graph flip y no xpaset -p ds9 plot graph range x min 1 xpaset -p ds9 plot graph range x max 100 xpaset -p ds9 plot graph range y min 1 xpaset -p ds9 plot graph range y max 100 xpaset -p ds9 plot graph range x auto yes xpaset -p ds9 plot graph range y auto yes xpaset -p ds9 plot graph format x {} xpaset -p ds9 plot graph format y {} xpaset -p ds9 plot graph labels title "{The Title}" xpaset -p ds9 plot graph labels xaxis "{X Axis}" xpaset -p ds9 plot graph labels yaxis "{Y Axis}" xpaset -p ds9 plot font numbers font times xpaset -p ds9 plot font numbers size 12 xpaset -p ds9 plot font numbers weight bold xpaset -p ds9 plot font numbers slant roman xpaset -p ds9 plot font labels font times xpaset -p ds9 plot font labels size 12 xpaset -p ds9 plot font labels weight bold xpaset -p ds9 plot font labels slant roman xpaset -p ds9 plot font title font times xpaset -p ds9 plot font title size 12 xpaset -p ds9 plot font title weight bold xpaset -p ds9 plot font title slant roman sleep .5 xpaset -p ds9 plot close echo "PASSED" echo -n " dataset..." xpaset -p ds9 plot new cat plot/xy.dat | xpaset ds9 plot data xy cat plot/xyey.dat | xpaset ds9 plot data xyey xpaset -p ds9 plot dataset 2 xpaset -p ds9 plot view discrete yes xpaset -p ds9 plot view line yes xpaset -p ds9 plot view step yes xpaset -p ds9 plot view quadratic yes xpaset -p ds9 plot view errorbar yes xpaset -p ds9 plot color discrete red xpaset -p ds9 plot color line green xpaset -p ds9 plot color step blue xpaset -p ds9 plot color quadratic cyan xpaset -p ds9 plot color errorbar yellow xpaset -p ds9 plot color errorbar magenta xpaset -p ds9 plot line discrete cross xpaset -p ds9 plot line line width 2 xpaset -p ds9 plot line line dash yes xpaset -p ds9 plot line step width 2 xpaset -p ds9 plot line step dash yes xpaset -p ds9 plot line quadratic width 2 xpaset -p ds9 plot line quadratic dash yes xpaset -p ds9 plot line errorbar width 2 xpaset -p ds9 plot line errorbar style 2 sleep .5 xpaset -p ds9 plot close echo "PASSED" testit $tt fi tt="png" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 png photo/rose.png cat photo/rose.png | xpaset ds9 png xpaget ds9 png > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 png new photo/rose.png xpaset -p ds9 png slice photo/rose.png xpaset -p ds9 frame delete testit $tt fi tt="prefs" if [ "$1" = "$tt" -o -z "$1" ]; then echo "$tt..." xpaset -p ds9 prefs clear # backward compatibility xpaget ds9 prefs bgcolor >> ${tt}.out xpaget ds9 prefs nancolor >> ${tt}.out xpaget ds9 prefs threads >> ${tt}.out xpaset -p ds9 prefs bgcolor white xpaset -p ds9 prefs nancolor white xpaset -p ds9 prefs threads 8 testit $tt fi tt="preserve" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 preserve scale >> ${tt}.out xpaget ds9 preserve pan >> ${tt}.out xpaget ds9 preserve regions >> ${tt}.out xpaset -p ds9 preserve scale no xpaset -p ds9 preserve pan no xpaset -p ds9 preserve regions no testit $tt fi tt="print" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 psprint destination >> ${tt}.out xpaget ds9 psprint command >> ${tt}.out xpaget ds9 psprint color >> ${tt}.out xpaget ds9 psprint level >> ${tt}.out xpaget ds9 psprint resolution >> ${tt}.out #xpaset -p ds9 psprint xpaset -p ds9 psprint destination printer xpaset -p ds9 psprint command lp xpaset -p ds9 psprint filename ds9.ps xpaset -p ds9 psprint color rgb xpaset -p ds9 psprint level 2 xpaset -p ds9 psprint resolution 150 testit $tt fi tt="raise" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 lower xpaset -p ds9 raise testit $tt fi tt="regions" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/region..." xpaset -p ds9 regions delete all xpaset -p ds9 regions system physical xpaset -p ds9 regions sky fk5 xpaset -p ds9 regions skyformat degrees echo "physical;circle(957,1027,40) # tag=foo" | xpaset ds9 regions xpaget ds9 regions >> ${tt}.out xpaget ds9 regions show >> ${tt}.out xpaget ds9 regions showtext >> ${tt}.out xpaget ds9 regions centroid auto >> ${tt}.out xpaget ds9 regions centroid radius >> ${tt}.out xpaget ds9 regions centroid iteration >> ${tt}.out xpaget ds9 regions -format pros -system wcs -sky fk5 -skyformat sexagesimal -delim nl -prop edit 1 -group foo -strip yes >> ${tt}.out xpaget ds9 regions include >> ${tt}.out xpaget ds9 regions exclude >> ${tt}.out xpaget ds9 regions source >> ${tt}.out xpaget ds9 regions background >> ${tt}.out xpaget ds9 regions selected >> ${tt}.out xpaget ds9 regions format >> ${tt}.out xpaget ds9 regions system >> ${tt}.out xpaget ds9 regions sky >> ${tt}.out xpaget ds9 regions skyformat >> ${tt}.out xpaget ds9 regions strip >> ${tt}.out xpaget ds9 regions shape >> ${tt}.out xpaget ds9 regions color >> ${tt}.out xpaget ds9 regions width >> ${tt}.out xpaget ds9 regions delim >> ${tt}.out xpaget ds9 regions groups >> ${tt}.out echo "image; circle 100 100 20" | xpaset ds9 regions echo "fk5; circle 13:29:55 47:11:50 .5'" | xpaset ds9 regions echo "physical; ellipse 100 100 20 40" | xpaset ds9 regions echo "box 100 100 20 40 25" | xpaset ds9 regions echo "image; line 100 100 200 400" | xpaset ds9 regions echo "physical; ruler 200 300 200 400" | xpaset ds9 regions echo "image; text 100 100 # text={Hello, World}" | xpaset ds9 regions echo "fk4; boxcircle point 13:29:55 47:11:50" | xpaset ds9 regions xpaset -p ds9 regions delete all xpaset -p ds9 regions regions/ds9.physical.reg xpaset -p ds9 regions delete all xpaset -p ds9 regions load regions/ds9.physical.reg xpaset -p ds9 regions delete all xpaset -p ds9 regions load 'regions/ds9.fk5*.reg' xpaset -p ds9 regions delete all xpaset -p ds9 regions load all regions/ds9.physical.reg xpaset -p ds9 regions save foo.reg xpaset -p ds9 regions list xpaset -p ds9 regions list close xpaset -p ds9 regions delete all xpaset -p ds9 regions show yes xpaset -p ds9 regions showtext yes xpaset -p ds9 regions centroid xpaset -p ds9 regions centroid auto no xpaset -p ds9 regions centroid radius 10 xpaset -p ds9 regions centroid iteration 30 #xpaset -p ds9 regions getinfo xpaset -p ds9 regions move front xpaset -p ds9 regions move back xpaset -p ds9 regions select all xpaset -p ds9 regions select none xpaset -p ds9 regions delete all xpaset -p ds9 regions delete select xpaset -p ds9 regions format ds9 xpaset -p ds9 regions system physical xpaset -p ds9 regions sky fk5 xpaset -p ds9 regions skyformat degrees xpaset -p ds9 regions delim nl xpaset -p ds9 regions strip no xpaset -p ds9 regions shape circle xpaset -p ds9 regions color green xpaset -p ds9 regions width 1 xpaset -p ds9 regions edit yes xpaset -p ds9 regions include xpaset -p ds9 regions command {circle 100 100 20} xpaset -p ds9 regions group new xpaset -p ds9 regions group foo new xpaset -p ds9 regions group foo update xpaset -p ds9 regions group foo select xpaset -p ds9 regions group foo color red xpaset -p ds9 regions group foo copy xpaset -p ds9 regions group foo delete xpaset -p ds9 regions group foo cut xpaset -p ds9 regions group foo font {time 14 bold} xpaset -p ds9 regions group foo move 100 100 xpaset -p ds9 regions group foo movefront xpaset -p ds9 regions group foo moveback xpaset -p ds9 regions group foo property delete no xpaset -p ds9 regions delete all xpaset -p ds9 regions command {circle 100 100 20} xpaset -p ds9 regions select all xpaset -p ds9 regions copy xpaset -p ds9 regions cut xpaset -p ds9 regions paste xpaset -p ds9 regions undo xpaset -p ds9 regions delete all xpaset -p ds9 regions load regions/ds9.physical.reg xpaset -p ds9 regions select all xpaset -p ds9 regions composite xpaset -p ds9 regions desolve xpaset -p ds9 regions delete all xpaset -p ds9 regions command {circle 100 100 20} xpaset -p ds9 regions savetemplate foo.tpl xpaset -p ds9 regions delete all xpaset -p ds9 regions template foo.tpl xpaset -p ds9 regions delete all xpaset -p ds9 regions template foo.tpl at 202.46963 47.19556 fk5 xpaset -p ds9 regions delete all testit $tt fi tt="restore" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 backup foo.bck xpaset -p ds9 restore foo.bck testit $tt fi tt="rgb" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 rgb open xpaset -p ds9 rgb close xpaset -p ds9 rgb xpaget ds9 rgb channel >> ${tt}.out xpaget ds9 rgb view red >> ${tt}.out xpaget ds9 rgb view green >> ${tt}.out xpaget ds9 rgb view blue >> ${tt}.out xpaget ds9 rgb system >> ${tt}.out xpaget ds9 rgb lock wcs >> ${tt}.out xpaget ds9 rgb lock crop >> ${tt}.out xpaget ds9 rgb lock slice >> ${tt}.out xpaget ds9 rgb lock bin >> ${tt}.out xpaget ds9 rgb lock scale >> ${tt}.out xpaget ds9 rgb lock colorbar >> ${tt}.out xpaget ds9 rgb lock smooth >> ${tt}.out xpaset -p ds9 rgb green xpaset -p ds9 rgb channel blue xpaset -p ds9 rgb view blue off xpaset -p ds9 rgb system wcs xpaset -p ds9 rgb lock crop wcs xpaset -p ds9 rgb lock crop yes xpaset -p ds9 rgb lock slice yes xpaset -p ds9 rgb lock bin yes xpaset -p ds9 rgb lock scale yes xpaset -p ds9 rgb lock colorbar yes xpaset -p ds9 rgb lock smooth yes xpaset -p ds9 rgb close xpaset -p ds9 frame delete testit $tt fi tt="rgbarray" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new rgb xpaset -p ds9 rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] cat rgbarray/float_big.rgb | xpaset ds9 rgbarray -[dim=256,bitpix=-32,endian=big] xpaget ds9 rgbarray big > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 rgbarray new rgbarray/float_big.rgb[dim=256,bitpix=-32,endian=big] xpaset -p ds9 frame delete testit $tt fi tt="rgbcube" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new rgb xpaset -p ds9 rgbcube rgbcube/float.fits cat rgbcube/float.fits | xpaset ds9 rgbcube xpaget ds9 rgbcube > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 rgbcube new rgbcube/float.fits xpaset -p ds9 frame delete testit $tt fi tt="rgbimage" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new rgb xpaset -p ds9 rgbimage mecube/float.fits cat mecube/float.fits | xpaset ds9 rgbimage xpaget ds9 rgbimage > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 rgbimage new mecube/float.fits xpaset -p ds9 frame delete testit $tt fi tt="rotate" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 rotate >> ${tt}.out xpaset -p ds9 rotate open xpaset -p ds9 rotate to 30 xpaset -p ds9 rotate 15 xpaset -p ds9 rotate close xpaset -p ds9 frame reset testit $tt fi tt="samp" if [ "$1" = "$tt" ]; then echo "samp" xpaset -p ds9 samp no xpaset -p ds9 samp yes xpaset -p ds9 samp broadcast xpaset -p ds9 samp broadcast image xpaset -p ds9 samp send aladin xpaset -p ds9 samp send image aladin testit $tt fi tt="save" if [ "$1" = "$tt" -o -z "$1" ]; then echo "$tt/savefits..." echo -n " fits..." xpaset -p ds9 save foo.fits xpaset -p ds9 save fits foo.fits xpaset -p ds9 save foo.fits image xpaset -p ds9 save fits foo.fits image xpaset -p ds9 save foo.fits slice xpaset -p ds9 save fits foo.fits slice xpaset -p ds9 frame new xpaset -p ds9 fits fits/table.fits xpaset -p ds9 save foo.fits xpaset -p ds9 save fits foo.fits xpaset -p ds9 save foo.fits image xpaset -p ds9 save fits foo.fits image xpaset -p ds9 save foo.fits table xpaset -p ds9 save fits foo.fits table xpaset -p ds9 frame delete echo "PASSED" echo -n " rgbimage..." xpaset -p ds9 frame new rgb xpaset -p ds9 rgbimage mecube/float.fits xpaset -p ds9 save rgbimage foo.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " rgbcube..." xpaset -p ds9 frame new rgb xpaset -p ds9 rgbcube rgbcube/float.fits xpaset -p ds9 save rgbcube foo.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mecube..." xpaset -p ds9 frame new xpaset -p ds9 mecube mecube/float.fits xpaset -p ds9 save mecube foo.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaicimage..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 save mosaicimage foo.fits xpaset -p ds9 frame delete echo "PASSED" echo -n " mosaic..." xpaset -p ds9 frame new xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits xpaset -p ds9 save mosaic foo.fits xpaset -p ds9 frame delete echo "PASSED" # backward compatibility echo -n " savefits..." xpaset -p ds9 savefits foo.fits echo "PASSED" testit $tt fi tt="saveimage" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 saveimage fits foo.fits xpaset -p ds9 saveimage foo.fits xpaset -p ds9 saveimage eps foo.eps xpaset -p ds9 saveimage foo.eps xpaset -p ds9 saveimage foo.gif xpaset -p ds9 saveimage tiff foo.tiff none xpaset -p ds9 saveimage foo.tiff xpaset -p ds9 saveimage jpeg foo.jpeg 100 xpaset -p ds9 saveimage foo.jpeg xpaset -p ds9 saveimage png foo.png xpaset -p ds9 saveimage foo.png # backward compatibility (6.2) xpaset -p ds9 saveimage tiff none foo.tiff xpaset -p ds9 saveimage jpeg 100 foo.jpeg xpaset -p ds9 saveimage mpeg foo.mpeg testit $tt fi tt="scale" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 scale >> ${tt}.out xpaget ds9 scale log exp >> ${tt}.out xpaget ds9 scale limits >> ${tt}.out xpaget ds9 scale mode >> ${tt}.out xpaget ds9 scale scope >> ${tt}.out xpaget ds9 scale datasec >> ${tt}.out xpaget ds9 scale lock >> ${tt}.out xpaset -p ds9 scale open xpaset -p ds9 scale minmax xpaset -p ds9 scale linear xpaset -p ds9 scale log xpaset -p ds9 scale pow xpaset -p ds9 scale sqrt xpaset -p ds9 scale squared xpaset -p ds9 scale asinh xpaset -p ds9 scale sinh xpaset -p ds9 scale histequ xpaset -p ds9 scale log exp 1000 xpaset -p ds9 scale log exp 10000 xpaset -p ds9 scale linear xpaset -p ds9 scale minmax xpaset -p ds9 scale zscale xpaset -p ds9 scale zmax xpaset -p ds9 scale user xpaset -p ds9 scale mode zscale xpaset -p ds9 scale mode zmax xpaset -p ds9 scale mode 95 xpaset -p ds9 scale mode minmax xpaset -p ds9 scale limits 0 100 xpaset -p ds9 scale global xpaset -p ds9 scale local xpaset -p ds9 scale scope global xpaset -p ds9 scale scope local xpaset -p ds9 scale mode minmax xpaset -p ds9 scale linear xpaset -p ds9 scale zscale xpaset -p ds9 scale datasec yes xpaset -p ds9 scale match xpaset -p ds9 scale lock yes xpaset -p ds9 scale lock no xpaset -p ds9 scale close testit $tt fi # backward compatibility tt="sfits" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new xpaset -p ds9 sfits sfits/float.hdr sfits/float.arr xpaset -p ds9 frame delete xpaset -p ds9 sfits new sfits/float.hdr sfits/float.arr xpaset -p ds9 sfits slice sfits/float.hdr sfits/float.arr xpaset -p ds9 sfits mask sfits/float.hdr sfits/float.arr xpaset -p ds9 frame delete testit $tt fi tt="single" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 single >> ${tt}.out xpaset -p ds9 tile xpaget ds9 single >> ${tt}.out xpaset -p ds9 single xpaget ds9 single >> ${tt}.out testit $tt fi tt="shm" if [ "$1" = "$tt" ]; then echo -n "$tt...no test..." testit $tt fi tt="skyview" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 skyview open xpaset -p ds9 skyview close xpaset -p ds9 skyview survey sdssi xpaget ds9 skyview survey >> ${tt}.out xpaset -p ds9 skyview size 30 30 arcsec xpaget ds9 skyview size >> ${tt}.out xpaset -p ds9 skyview save no xpaget ds9 skyview save >> ${tt}.out xpaset -p ds9 skyview frame new xpaget ds9 skyview frame >> ${tt}.out xpaset -p ds9 skyview update frame xpaset -p ds9 skyview m3 xpaset -p ds9 skyview name m51 xpaget ds9 skyview name >> ${tt}.out xpaset -p ds9 skyview name {} xpaset -p ds9 skyview coord 13:29:55.301 +47:11:37.73 sexagesimal xpaget ds9 skyview coord >> ${tt}.out xpaset -p ds9 skyview update frame xpaset -p ds9 mode crosshair xpaset -p ds9 skyview update crosshair xpaset -p ds9 skyview close xpaset -p ds9 mode pointer xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="sleep" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 sleep xpaset -p ds9 sleep 2 testit $tt fi # backward compatibility tt="smosaic" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility...no test..." testit $tt fi # backward compatibility tt="smosaicwcs" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility...no test..." testit $tt fi # backward compatibility tt="smosaiciraf" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility...no test..." testit $tt fi tt="smooth" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 smooth >> ${tt}.out xpaget ds9 smooth function >> ${tt}.out xpaget ds9 smooth radius >> ${tt}.out xpaset -p ds9 smooth open xpaset -p ds9 smooth xpaset -p ds9 smooth yes xpaset -p ds9 smooth function tophat xpaset -p ds9 smooth radius 5 xpaset -p ds9 smooth match xpaset -p ds9 smooth lock yes xpaset -p ds9 smooth lock no xpaset -p ds9 smooth no xpaset -p ds9 smooth close testit $tt fi tt="source" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 source aux/source.tcl testit $tt fi # backward compatibility tt="srgbcube" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt...backward compatibility..." xpaset -p ds9 frame new rgb xpaset -p ds9 srgbcube srgbcube/float.hdr srgbcube/float.arr xpaset -p ds9 frame delete xpaset -p ds9 srgbcube new srgbcube/float.hdr srgbcube/float.arr xpaset -p ds9 frame delete testit $tt fi tt="tcl" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." cat aux/hello.tcl | xpaset ds9 tcl xpaset -p ds9 tcl 'puts "Hello Again, World"' testit $tt fi tt="theme" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 theme >> ${tt}.out xpaset -p ds9 theme native testit $tt fi tt="threads" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 threads >> ${tt}.out xpaset -p ds9 threads 8 testit $tt fi tt="tiff" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/tif..." xpaset -p ds9 frame new xpaset -p ds9 tiff photo/rose.tiff cat photo/rose.tiff | xpaset ds9 tiff xpaget ds9 tiff > /dev/null xpaget ds9 tiff jpeg > /dev/null xpaset -p ds9 frame delete xpaset -p ds9 tiff new photo/rose.tiff xpaset -p ds9 tiff slice photo/rose.tiff xpaset -p ds9 frame delete testit $tt fi tt="tile" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 tile >> ${tt}.out xpaget ds9 tile mode >> ${tt}.out xpaset -p ds9 fits new data/img.fits xpaset -p ds9 fits new data/img.fits xpaset -p ds9 tile xpaset -p ds9 tile yes xpaset -p ds9 tile row xpaset -p ds9 tile column xpaset -p ds9 tile grid xpaset -p ds9 frame delete xpaset -p ds9 frame delete testit $tt fi tt="update" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 update xpaset -p ds9 update 1 100 100 300 400 xpaset -p ds9 update now xpaset -p ds9 update now 1 100 100 300 400 xpaset -p ds9 update off xpaset -p ds9 update on testit $tt fi tt="url" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame new xpaset -p ds9 url http://hea-www.harvard.edu/RD/ds9/data/img.fits xpaset -p ds9 frame delete testit $tt fi tt="version" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 version >> /dev/null testit $tt fi tt="view" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 frame delete xpaget ds9 view layout >> ${tt}.out xpaget ds9 view info >> ${tt}.out xpaget ds9 view panner >> ${tt}.out xpaget ds9 view magnifier >> ${tt}.out xpaget ds9 view buttons >> ${tt}.out xpaget ds9 view colorbar >> ${tt}.out xpaget ds9 view graph horizontal >> ${tt}.out xpaget ds9 view graph vertical >> ${tt}.out xpaget ds9 view filename >> ${tt}.out xpaget ds9 view object >> ${tt}.out xpaget ds9 view minmax >> ${tt}.out xpaget ds9 view lowhigh >> ${tt}.out xpaget ds9 view frame >> ${tt}.out xpaget ds9 view wcs >> ${tt}.out xpaget ds9 view detector >> ${tt}.out xpaget ds9 view amplifier >> ${tt}.out xpaget ds9 view physical >> ${tt}.out xpaget ds9 view image >> ${tt}.out xpaset -p ds9 view layout vertical xpaset -p ds9 sleep .5 xpaset -p ds9 view layout horizontal xpaset -p ds9 sleep .5 xpaset -p ds9 view info no xpaset -p ds9 view info yes xpaset -p ds9 view panner no xpaset -p ds9 view panner yes xpaset -p ds9 view magnifier no xpaset -p ds9 view magnifier yes xpaset -p ds9 view buttons no xpaset -p ds9 view buttons yes xpaset -p ds9 view colorbar no xpaset -p ds9 view colorbar yes xpaset -p ds9 view graph horizontal yes xpaset -p ds9 view graph horizontal no xpaset -p ds9 view graph vertical yes xpaset -p ds9 view graph vertical no xpaset -p ds9 view filename no xpaset -p ds9 view filename yes xpaset -p ds9 view object no xpaset -p ds9 view object yes xpaset -p ds9 view minmax yes xpaset -p ds9 view minmax no xpaset -p ds9 view lowhigh yes xpaset -p ds9 view lowhigh no xpaset -p ds9 view frame no xpaset -p ds9 view frame yes xpaset -p ds9 view wcs no xpaset -p ds9 view wcs yes xpaset -p ds9 view wcsa yes xpaset -p ds9 view wcsa no xpaset -p ds9 view detector yes xpaset -p ds9 view detector no xpaset -p ds9 view amplifier yes xpaset -p ds9 view amplifier no xpaset -p ds9 view physical no xpaset -p ds9 view physical yes xpaset -p ds9 view image no xpaset -p ds9 view image yes xpaset -p ds9 sleep .5 xpaset -p ds9 frame new rgb xpaset -p ds9 view red no xpaset -p ds9 view red yes xpaset -p ds9 view green no xpaset -p ds9 view green yes xpaset -p ds9 view blue no xpaset -p ds9 view blue yes xpaset -p ds9 frame delete xpaset -p ds9 sleep .5 xpaset -p ds9 fits new data/img.fits xpaset -p ds9 rgb close testit $tt fi tt="vo" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 vo method >> ${tt}.out xpaget ds9 vo server >> ${tt}.out xpaget ds9 vo internal >> ${tt}.out xpaget ds9 vo delay >> ${tt}.out xpaget ds9 vo connect >> ${tt}.out xpaget ds9 vo >> ${tt}.out xpaset -p ds9 vo open xpaset -p ds9 vo method xpa xpaset -p ds9 vo server "http://cxc.harvard.edu/chandraed/list.txt" xpaset -p ds9 vo internal yes xpaset -p ds9 vo delay 15 xpaset -p ds9 vo connect foo xpaset -p ds9 vo chandra-ed xpaset -p ds9 vo disconnect chandra-ed xpaset -p ds9 vo close xpaset -p ds9 web close testit $tt fi tt="wcs" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 wcs >> ${tt}.out xpaget ds9 wcs system >> ${tt}.out xpaget ds9 wcs sky >> ${tt}.out xpaget ds9 wcs skyformat >> ${tt}.out xpaget ds9 wcs align >> ${tt}.out xpaset -p ds9 wcs open xpaset -p ds9 wcs wcs xpaset -p ds9 wcs align yes xpaset -p ds9 wcs system wcs xpaset -p ds9 wcs sky galactic xpaset -p ds9 wcs skyformat sexagesimal xpaset -p ds9 wcs align no xpaset -p ds9 wcs sky fk5 xpaset -p ds9 wcs skyformat degrees cat aux/image.wcs | xpaset ds9 wcs append cat aux/image.wcs | xpaset ds9 wcs replace xpaset -p ds9 wcs append aux/image.wcs xpaset -p ds9 wcs replace aux/image.wcs xpaset -p ds9 wcs reset xpaset -p ds9 wcs skyformat sexagesimal xpaset -p ds9 wcs close testit $tt fi tt="web" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 web hea-www.harvard.edu/RD/ds9/acknowledgment.html sleep .5 xpaget ds9 web >> ${tt}.out xpaset -p ds9 web hea-www.harvard.edu/RD/ds9/helpdesk.html sleep .5 xpaset -p ds9 web hvweb click back sleep .5 xpaset -p ds9 web click forward xpaset -p ds9 web clear xpaset -p ds9 web close testit $tt fi tt="width" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 width >> /dev/null xpaset -p ds9 width 600 testit $tt fi tt="zscale" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaget ds9 zscale contrast >> ${tt}.out xpaget ds9 zscale sample >> ${tt}.out xpaget ds9 zscale line >> ${tt}.out xpaset -p ds9 zscale contrast .25 xpaset -p ds9 zscale sample 600 xpaset -p ds9 zscale line 120 testit $tt fi tt="zoom" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt..." xpaset -p ds9 zoom open xpaset -p ds9 zoom 2 xpaset -p ds9 zoom 2 4 xpaset -p ds9 zoom to 4 xpaset -p ds9 zoom to 2 4 xpaset -p ds9 zoom to fit xpaset -p ds9 zoom close xpaget ds9 zoom > /dev/null xpaset -p ds9 frame reset testit $tt fi tt="exit" if [ "$1" = "$tt" -o -z "$1" ]; then echo -n "$tt/quit..." xpaset -p ds9 quit fi rm -f foo.* echo "DONE" ����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/vo.sh��������������������������������������������������������������������������������0000755�0001750�0001750�00000004577�12131345054�013243� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** vo.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi doit () { dd=1 ddd=4 xpaset -p ds9 vo chandra-ed #xpaset -p ds9 vo chandra-ed.rutgers xpaset -p ds9 web click 4 sleep $ddd xpaset -p ds9 web click back xpaset -p ds9 raise echo "..Overview of Chandra-Ed Analysis Tools" xpaset -p ds9 analysis 0 sleep $dd echo "..Radial Profile Plot" xpaset -p ds9 regions regions/vo2.reg xpaset -p ds9 analysis 1 sleep $dd echo "..Counts in Regions" xpaset -p ds9 regions deleteall xpaset -p ds9 regions regions/vo1.reg xpaset -p ds9 analysis 2 sleep $dd echo "..Quick Energy Spectrum Plot" xpaset -p ds9 analysis 3 sleep $dd echo "..Quick Light Curve Plot" xpaset -p ds9 analysis 4 sleep $dd echo "..Histogram Plot" xpaset -p ds9 analysis 5 sleep $dd echo "..Column Histogram" xpaset -p ds9 analysis 6 sleep $dd echo "..Refine (Centroid) Position" xpaset -p ds9 analysis 7 sleep $ddd echo "..Imexam" xpaset -p ds9 analysis 8 sleep $ddd echo "..Rebin image" xpaset -p ds9 analysis 9 sleep $ddd sleep $ddd xpaset -p ds9 frame delete echo "..Energy Filter" xpaset -p ds9 analysis 10 sleep $ddd sleep $ddd xpaset -p ds9 frame delete echo "..Time Filter" xpaset -p ds9 analysis 11 sleep $ddd sleep $ddd xpaset -p ds9 frame delete echo "..Column Filter" xpaset -p ds9 analysis 12 sleep $ddd sleep $ddd xpaset -p ds9 frame delete echo "..CIAO/Sherpa Spectral Fit" xpaset -p ds9 analysis 13 sleep $ddd echo "..FTOOLS/Light Curve" xpaset -p ds9 analysis 14 sleep $ddd echo "..FTOOLS/Power Spectrum" xpaset -p ds9 analysis 15 sleep $ddd echo "..FTOOLS/Period Fold" xpaset -p ds9 analysis 16 sleep $ddd xpaset -p ds9 regions deleteall xpaset -p ds9 frame clear xpaset -p ds9 vo disconnect chandra-ed xpaset -p ds9 web close echo "PASSED" } if [ "$1" = "xpa" ]; then echo "Testing xpa" xpaset -p ds9 vo method xpa doit fi if [ "$1" = "mime" ]; then echo "Testing mime" xpaset -p ds9 vo method mime doit fi xpaset -p ds9 exit echo "DONE" ���������������������������������������������������������������������������������������������������������������������������������./saods9/tests/regions3d.sh�������������������������������������������������������������������������0000755�0001750�0001750�00000006162�12131345054�014504� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������testit () { echo "Test $1 $2 $3 $4 $5" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 xpaset -p ds9 regions save ${5}.out if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall o=`diff $5 ${5}.out` if [ "$o" = "" ] then echo "PASSED" else echo "FAILED" echo "$o" fi rm -f ${5}.out } testit2 () { echo "Test $1 $2 $3 $4 $5 $6" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 xpaset -p ds9 regions save ${5}.out if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall o=`diff $6 ${5}.out` if [ "$o" = "" ] then echo "PASSED" else echo "FAILED" echo "$o" fi rm -f ${5}.out } testit3 () { echo "Test $1 $2 $3 $4 $5" xpaset -p ds9 regions format $1 xpaset -p ds9 regions system $2 xpaset -p ds9 regions sky $3 xpaset -p ds9 regions skyformat $4 xpaset -p ds9 regions file $5 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 regions deleteall echo "PASSED" } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** regions.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9 -3d -3d vp 45 30& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done fi echo "Loading Data..." xpaset -p ds9 fits data/img.fits if [ "$1" = "ds9" -o -z "$1" ]; then echo echo "Testing DS9 Format..." testit ds9 image fk5 degrees regions/ds9.image.reg testit ds9 physical fk5 degrees regions/ds9.physical.reg testit ds9 wcs fk4 degrees regions/ds9.fk4.reg testit ds9 wcs fk4 sexagesimal regions/ds9.fk4.hms.reg testit ds9 wcs fk5 degrees regions/ds9.fk5.reg testit ds9 wcs fk5 sexagesimal regions/ds9.fk5.hms.reg testit ds9 wcs icrs degrees regions/ds9.icrs.reg testit ds9 wcs icrs sexagesimal regions/ds9.icrs.hms.reg testit ds9 wcs galactic degrees regions/ds9.galactic.reg testit ds9 wcs galactic sexagesimal regions/ds9.galactic.hms.reg testit ds9 wcs ecliptic degrees regions/ds9.ecliptic.reg testit ds9 wcs ecliptic sexagesimal regions/ds9.ecliptic.hms.reg echo echo "Testing XML Format..." testit xml image fk5 degrees regions/xml.image.reg testit xml physical fk5 degrees regions/xml.physical.reg testit xml wcs fk4 degrees regions/xml.fk4.reg testit xml wcs fk4 sexagesimal regions/xml.fk4.hms.reg testit xml wcs fk5 degrees regions/xml.fk5.reg testit xml wcs fk5 sexagesimal regions/xml.fk5.hms.reg testit xml wcs icrs degrees regions/xml.icrs.reg testit xml wcs icrs sexagesimal regions/xml.icrs.hms.reg testit xml wcs galactic degrees regions/xml.galactic.reg testit xml wcs galactic sexagesimal regions/xml.galactic.hms.reg testit xml wcs ecliptic degrees regions/xml.ecliptic.reg testit xml wcs ecliptic sexagesimal regions/xml.ecliptic.hms.reg fi if [ -z "$1" ]; then xpaset -p ds9 quit fi ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/photo.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000012551�12131345761�013744� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } DoXPA () { echo "$1" xpaset -p ds9 $2 $3 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdin () { echo "$1" cat $3 | xpaset ds9 $2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdout () { echo ".. $2" xpaset -p ds9 tile xpaget ds9 $2 > foo.$2 xpaset -p ds9 frame new $1 xpaset -p ds9 $2 foo.$2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete } initit () { echo "Testing $1" unset opt } testit () { echo "$2" opt="$opt -export $2 foo.$2 $3 -sleep .1" opt="$opt -frame new $1 foo.$2" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" } doit () { eval ds9 -tile $1 -tiff photo/rose.tiff "$opt" -exit echo "PASSED" } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** photo.sh ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" echo ".. base" echo ".. gif" ds9 -gif photo/rose.gif & KillIt echo ".. tiff" ds9 -tiff photo/rose.tiff & KillIt echo ".. jpeg" ds9 -jpeg photo/rose.jpeg & KillIt echo ".. png" ds9 -png photo/rose.png & KillIt echo ".. # backward compatibility" echo ".. -photo" ds9 -photo photo/rose.tiff & KillIt echo ".. rgb" echo ".. gif" ds9 -rgb -gif photo/rose.gif & KillIt echo ".. tiff" ds9 -rgb -tiff photo/rose.tiff & KillIt echo ".. jpeg" ds9 -rgb -jpeg photo/rose.jpeg & KillIt echo ".. png" ds9 -rgb -png photo/rose.png & KillIt echo ".. # backward compatibility" echo ".. -photo" ds9 -rgb -photo photo/rose.tiff & KillIt echo ".. 3d" echo ".. gif" ds9 -3d -gif photo/rose.gif & KillIt echo ".. tiff" ds9 -3d -tiff photo/rose.tiff & KillIt echo ".. jpeg" ds9 -3d -jpeg photo/rose.jpeg & KillIt echo ".. png" ds9 -3d -png photo/rose.png & KillIt echo ".. # backward compatibility" echo ".. -photo" ds9 -3d -photo photo/rose.tiff & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Command Stdin" echo ".. base" echo ".. gif" cat photo/rose.gif | ds9 -gif - & KillIt echo ".. tiff" cat photo/rose.tiff | ds9 -tiff - & KillIt echo ".. jpeg" cat photo/rose.jpeg | ds9 -jpeg - & KillIt echo ".. png" cat photo/rose.png | ds9 -png - & KillIt echo ".. rgb" echo ".. gif" cat photo/rose.gif | ds9 -rgb -gif - & KillIt echo ".. tiff" cat photo/rose.tiff | ds9 -rgb -tiff - & KillIt echo ".. jpeg" cat photo/rose.jpeg | ds9 -rgb -jpeg - & KillIt echo ".. png" cat photo/rose.png | ds9 -rgb -png - & KillIt echo ".. 3d" echo ".. gif" cat photo/rose.gif | ds9 -3d -gif - & KillIt echo ".. tiff" cat photo/rose.tiff | ds9 -3d -tiff - & KillIt echo ".. jpeg" cat photo/rose.jpeg | ds9 -3d -jpeg - & KillIt echo ".. png" cat photo/rose.png | ds9 -3d -png - & KillIt echo "PASSED" fi # export if [ "$1" = "export" -o -z "$1" ]; then echo "Testing Command export" initit ".. base" testit "" gif testit "" tiff testit "" tiff none testit "" jpeg testit "" jpeg 100 testit "" png doit "" initit ".. rgb" #testit rgb gif testit rgb tiff testit rgb tiff none testit rgb jpeg testit rgb jpeg 100 testit rgb png doit "-frame delete -rgb" fi # XPA File if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 echo ".. base" DoXPA ".. gif" gif photo/rose.gif DoXPA ".. jpeg" jpeg photo/rose.jpeg DoXPA ".. tiff" tiff photo/rose.tiff DoXPA ".. png" png photo/rose.png echo ".. rgb" xpaset -p ds9 rgb DoXPA ".. gif" gif photo/rose.gif DoXPA ".. jpeg" jpeg photo/rose.jpeg DoXPA ".. tiff" tiff photo/rose.tiff DoXPA ".. png" png photo/rose.png echo ".. 3d" xpaset -p ds9 3d DoXPA ".. gif" gif photo/rose.gif DoXPA ".. jpeg" jpeg photo/rose.jpeg DoXPA ".. tiff" tiff photo/rose.tiff DoXPA ".. png" png photo/rose.png xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 echo ".. base" DoXPAStdin ".. gif" gif photo/rose.gif DoXPAStdin ".. jpeg" jpeg photo/rose.jpeg DoXPAStdin ".. tiff" tiff photo/rose.tiff DoXPAStdin ".. png" png photo/rose.png echo ".. rgb" xpaset -p ds9 rgb DoXPAStdin ".. gif" gif photo/rose.gif DoXPAStdin ".. jpeg" jpeg photo/rose.jpeg DoXPAStdin ".. tiff" tiff photo/rose.tiff DoXPAStdin ".. png" png photo/rose.png echo ".. 3d" xpaset -p ds9 3d DoXPAStdin ".. gif" gif photo/rose.gif DoXPAStdin ".. jpeg" jpeg photo/rose.jpeg DoXPAStdin ".. tiff" tiff photo/rose.tiff DoXPAStdin ".. png" png photo/rose.png xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 echo ".. base" xpaset -p ds9 tiff photo/rose.tiff DoXPAStdout "" gif DoXPAStdout "" jpeg DoXPAStdout "" tiff DoXPAStdout "" png echo ".. rgb" xpaset -p ds9 frame delete xpaset -p ds9 rgb xpaset -p ds9 tiff photo/rose.tiff # not enough colors #DoXPAStdout rgb gif DoXPAStdout rgb jpeg DoXPAStdout rgb tiff DoXPAStdout rgb png xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" �������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/lock.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000003000�12131345054�013523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** lock.sh ***" if [ "$1" = "frame" -o -z "$1" ]; then echo "Testing frame" ds9 -debug -zscale data/img.fits data/img.fits -tile -lock frame wcs -mode pan fi if [ "$1" = "crosshair" -o -z "$1" ]; then echo "Testing crosshair" ds9 -debug -zscale data/img.fits data/img.fits -tile -lock crosshair wcs -mode crosshair fi if [ "$1" = "crop" -o -z "$1" ]; then echo "Testing crop" ds9 -debug -zscale data/img.fits -rgb data/img.fits -green data/img.fits -blue data/img.fits -tile -lock crop wcs -crop open -mode crop -rgb lock crop yes ds9 -debug -zscale data/3d.fits -3d data/3d.fits -3d vp 45 30 -tile -lock crop wcs -mode crop fi if [ "$1" = "slice" -o -z "$1" ]; then echo "Testing slice" ds9 -debug -zscale data/3d.fits -3d data/3d.fits -3d vp 45 30 -tile -lock slice fi if [ "$1" = "bin" -o -z "$1" ]; then echo "Testing bin" ds9 -debug -zscale fits/table.fits -rgb fits/table.fits -green fits/table.fits -blue fits/table.fits -tile -lock bin -bin open -rgb lock bin yes fi if [ "$1" = "scale" -o -z "$1" ]; then echo "Testing scale" ds9 -debug -zscale data/img.fits -rgb data/img.fits -green data/img.fits -blue data/img.fits -tile -lock scale -scale open -rgb lock scale yes fi if [ "$1" = "color" -o -z "$1" ]; then echo "Testing color" ds9 -debug -zscale data/img.fits data/img.fits -rgb -red data/img.fits -green data/img.fits -blue data/img.fits -rgb lock colorbar yes -rgb -red data/img.fits -green data/img.fits -blue data/img.fits -rgb lock colorbar yes -tile -lock colorbar yes -cmap open fi echo "Done" ./saods9/tests/fullrgb.sh���������������������������������������������������������������������������0000755�0001750�0001750�00000004430�12131617434�014244� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 -frame delete -rgb& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # which/where/what which=$1 shift where=$1 shift what=$1 shift # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** $which ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" for f in $where/* do echo " ${f#$where/}" opt="-$what $f -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi ds9 $opt -exit done echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" for f in $where/* do echo " ${f#$where/}" opt="-$what - -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi cat $f | ds9 $opt -exit done echo "PASSED" fi # Save if [ "$1" = "save" -o -z "$1" ]; then echo "Testing Command save" for f in $where/* do echo " ${f#$where/}" opt="-tile -frame delete -rgb -$what $f" opt="$opt -save $what foo.fits" opt="$opt -frame new rgb -$what foo.fits -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete" ds9 $opt -exit done echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 $what $f if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 for f in $where/* do echo " ${f#$where/}" cat $f | xpaset ds9 $what if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 tile xpaset -p ds9 $what $f xpaget ds9 $what > foo.fits xpaset -p ds9 frame new rgb xpaset -p ds9 $what foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/��������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013210� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.xyey.dat������������������������������������������������������������������0000644�0001750�0001750�00000000141�10111177377�016034� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis xyey 1 5 .5 2 7 .5 3 11 .5 4 2 .5 5 11 .5 6 5 .5 7 7 .5 8 11 .5 9 4 .5 10 4 .5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/5.dat���������������������������������������������������������������������������0000644�0001750�0001750�00000000433�07713776174�014104� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0.00 0.153 0.003 .2 .005 80.00 0.021 0.001 .03 .005 160.00 0.008 0.000 .01 .005 240.00 0.007 0.000 .006 .005 320.00 0.007 0.000 .005 .005 400.00 0.006 0.000 .005 .005 480.00 0.006 0.000 .004 .005 560.00 0.006 0.000 .003 .005 640.00 0.005 0.000 .004 .005 720.00 0.005 0.000 .004 .005 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.xyex.dat������������������������������������������������������������������0000644�0001750�0001750�00000000141�10111177377�016033� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis xyex 1 5 .5 2 7 .5 3 11 .5 4 2 .5 5 11 .5 6 5 .5 7 7 .5 8 11 .5 9 4 .5 10 4 .5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.2.dat���������������������������������������������������������������������0000644�0001750�0001750�00000000223�10111150222�015154� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis 2 0.00 0.153 80.00 0.021 160.00 0.008 240.00 0.007 320.00 0.007 400.00 0.006 480.00 0.006 560.00 0.006 640.00 0.005 720.00 0.005 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/xy.dat��������������������������������������������������������������������������0000644�0001750�0001750�00000000051�07713776172�014372� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 3 2 5 3 9 4 0 5 9 6 3 7 5 8 9 9 2 10 2 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/4.dat���������������������������������������������������������������������������0000644�0001750�0001750�00000000351�07713776174�014102� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0.00 0.153 0.003 .2 80.00 0.021 0.001 .03 160.00 0.008 0.000 .01 240.00 0.007 0.000 .006 320.00 0.007 0.000 .005 400.00 0.006 0.000 .005 480.00 0.006 0.000 .004 560.00 0.006 0.000 .003 640.00 0.005 0.000 .004 720.00 0.005 0.000 .004 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/xyexey.dat����������������������������������������������������������������������0000644�0001750�0001750�00000000150�07713776173�015266� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 5 .5 .5 2 7 .5 .5 3 11 .5 .5 4 2 .5 .5 5 11 .5 .5 6 5 .5 .5 7 7 .5 .5 8 11 .5 .5 9 4 .5 .5 10 4 .5 .5 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/xyex.dat������������������������������������������������������������������������0000644�0001750�0001750�00000000100�10111147331�014671� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 5 1 2 7 2 3 11 1 4 2 3 5 11 2 6 5 3 7 7 1 8 11 1 9 4 3 10 4 3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.4.dat���������������������������������������������������������������������0000644�0001750�0001750�00000000375�10111150404�015170� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis 4 0.00 0.153 0.003 .2 80.00 0.021 0.001 .03 160.00 0.008 0.000 .01 240.00 0.007 0.000 .006 320.00 0.007 0.000 .005 400.00 0.006 0.000 .005 480.00 0.006 0.000 .004 560.00 0.006 0.000 .003 640.00 0.005 0.000 .004 720.00 0.005 0.000 .004 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.text.dat������������������������������������������������������������������0000644�0001750�0001750�00000000553�07713776173�016046� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$BEGINTEXT this is text that is inserted at the beginning of the $plot(stdin) call this text can be of any length and maybe contain multiple lines $ENDTEXT Title XAxis YAxis 3 0.00 0.153 0.003 80.00 0.021 0.001 160.00 0.008 0.000 240.00 0.007 0.000 320.00 0.007 0.000 400.00 0.006 0.000 480.00 0.006 0.000 560.00 0.006 0.000 640.00 0.005 0.000 720.00 0.005 0.000 �����������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.xy.dat��������������������������������������������������������������������0000644�0001750�0001750�00000000102�10111177377�015473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis xy 1 5 2 7 3 11 4 2 5 11 6 5 7 7 8 11 9 4 10 4 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/xyey.dat������������������������������������������������������������������������0000644�0001750�0001750�00000000100�07713776172�014723� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 5 1 2 7 2 3 11 1 4 2 3 5 11 2 6 5 3 7 7 1 8 11 1 9 4 3 10 4 3 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.3.dat���������������������������������������������������������������������0000644�0001750�0001750�00000000317�10111150222�015161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis 3 0.00 0.153 0.003 80.00 0.021 0.001 160.00 0.008 0.000 240.00 0.007 0.000 320.00 0.007 0.000 400.00 0.006 0.000 480.00 0.006 0.000 560.00 0.006 0.000 640.00 0.005 0.000 720.00 0.005 0.000 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.xyexey.dat����������������������������������������������������������������0000644�0001750�0001750�00000000201�10111150530�016344� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis xyexey 1 5 .5 .5 2 7 .5 .5 3 11 .5 .5 4 2 .5 .5 5 11 .5 .5 6 5 .5 .5 7 7 .5 .5 8 11 .5 .5 9 4 .5 .5 10 4 .5 .5 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.error.dat�����������������������������������������������������������������0000644�0001750�0001750�00000000053�07734146323�016175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ERROR: This is a test of plot(stdin) ERROR �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot/stdin.5.dat���������������������������������������������������������������������0000644�0001750�0001750�00000000457�10111150404�015172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Title XAxis YAxis 5 0.00 0.153 0.003 .2 .005 80.00 0.021 0.001 .03 .005 160.00 0.008 0.000 .01 .005 240.00 0.007 0.000 .006 .005 320.00 0.007 0.000 .005 .005 400.00 0.006 0.000 .005 .005 480.00 0.006 0.000 .004 .005 560.00 0.006 0.000 .003 .005 640.00 0.005 0.000 .004 .005 720.00 0.005 0.000 .004 .005 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/print.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000003460�12131316277�013746� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** print.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi doit() { echo $1 xpaset -p ds9 psprint palette $2 xpaset -p ds9 psprint level $3 xpaset -p ds9 psprint filename ps/ds9-$4-$2-$3.ps xpaset -p ds9 psprint } rm -rf ps mkdir ps xpaset -p ds9 scale zscale #xpaset -p ds9 psprint command '{gv -}' xpaset -p ds9 psprint destination file xpaset -p ds9 grid if [ "$1" = "single" -o -z "$1" ]; then echo "Testing Single" xpaset -p ds9 fits data/img.fits xpaset -p ds9 regions load regions/ds9.fk5.hms.reg doit "..RGB Level 3" rgb 3 b doit "..CMYK Level 3" cmyk 3 b doit "..Gray Level 3" gray 3 b doit "..RGB Level 2" rgb 2 b doit "..CMYK Level 2" cmyk 2 b doit "..Gray Level 2" gray 2 b doit "..RGB Level 1" rgb 1 b doit "..Gray Level 1" gray 1 b echo "PASSED" fi if [ "$1" = "mosaic" -o -z "$1" ]; then echo "Testing Mosaic" xpaset -p ds9 mosaicimage iraf mosaic/mosaicimage.fits xpaset -p ds9 regions load regions/ds9.mosaic.fk5.hms.reg doit "..RGB Level 3" rgb 3 m doit "..CMYK Level 3" cmyk 3 m doit "..Gray Level 3" gray 3 m doit "..RGB Level 2" rgb 2 m doit "..CMYK Level 2" cmyk 2 m doit "..Gray Level 2" gray 2 m doit "..RGB Level 1" rgb 1 m doit "..Gray Level 1" gray 1 m echo "PASSED" fi if [ "$1" = "rgb" -o -z "$1" ]; then echo "Testing RGB" xpaset -p ds9 rgb xpaset -p ds9 rgbcube rgbcube/float.fits doit "..RGB Level 3" rgb 3 r doit "..CMYK Level 3" cmyk 3 r doit "..Gray Level 3" gray 3 r doit "..RGB Level 2" rgb 2 r doit "..CMYK Level 2" cmyk 2 r doit "..Gray Level 2" gray 2 r doit "..RGB Level 1" rgb 1 r doit "..Gray Level 1" gray 1 r echo "PASSED" fi echo "DONE" if [ -z "$1" ]; then xpaset -p ds9 quit fi ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/mecube.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000000065�12113456764�014056� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������full.sh "Multiple Ext Cube" mecube mecube save $1 $2 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/rgbarray.sh��������������������������������������������������������������������������0000755�0001750�0001750�00000045426�12131345761�014433� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } DoXPA () { echo "$1" xpaset -p ds9 rgbarray $2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdin () { echo "$1" cat $2 | xpaset ds9 rgbarray $3 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdout () { echo "$1" xpaset -p ds9 tile xpaset -p ds9 rgbarray $2 xpaget ds9 rgbarray $3 > foo.rgb xpaset -p ds9 frame new rgb xpaset -p ds9 rgbarray foo.rgb$4 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear } initit () { echo "Testing $1" unset opt } testit () { opt="$opt -export rgbarray foo.rgb $1 -sleep .1" opt="$opt -frame new rgb -rgbarray foo.rgb$2" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" } doit () { eval ds9 -tile -frame delete -rgb -rgbarray $1 "$opt" -exit echo "PASSED" } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 -frame delete -rgb& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** rgbarray.sh ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command File" echo ".. char" ds9 -rgbarray rgbarray/char.rgb[dim=256,bitpix=8] & KillIt echo ".. char gzip" ds9 -rgbarray rgbarray/char.rgb.gz[dim=256,bitpix=8] & KillIt echo ".. short little" ds9 -rgbarray rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] & KillIt echo ".. short little gzip" ds9 -rgbarray rgbarray/short_little.rgb.gz[dim=256,bitpix=16,arch=little] & KillIt echo ".. short big" ds9 -rgbarray rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] & KillIt echo ".. short big gzip" ds9 -rgbarray rgbarray/short_big.rgb.gz[dim=256,bitpix=16,arch=big] & KillIt echo ".. ushort little" ds9 -rgbarray rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" ds9 -rgbarray rgbarray/ushort_little.rgb.gz[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort big" ds9 -rgbarray rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" ds9 -rgbarray rgbarray/ushort_big.rgb.gz[dim=256,bitpix=-16,arch=big] & KillIt echo ".. int little" ds9 -rgbarray rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] & KillIt echo ".. int little gzip" ds9 -rgbarray rgbarray/int_little.rgb.gz[dim=256,bitpix=32,arch=little] & KillIt echo ".. int big" ds9 -rgbarray rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] & KillIt echo ".. int big gzip" ds9 -rgbarray rgbarray/int_big.rgb.gz[dim=256,bitpix=32,arch=big] & KillIt echo ".. longlong little" ds9 -rgbarray rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" ds9 -rgbarray rgbarray/longlong_little.rgb.gz[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong big" ds9 -rgbarray rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" ds9 -rgbarray rgbarray/longlong_big.rgb.gz[dim=256,bitpix=64,arch=big] & KillIt echo ".. float little" ds9 -rgbarray rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" ds9 -rgbarray rgbarray/float_little.rgb.gz[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float big" ds9 -rgbarray rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" ds9 -rgbarray rgbarray/float_big.rgb.gz[dim=256,bitpix=-32,arch=big] & KillIt echo ".. double little" ds9 -rgbarray rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" ds9 -rgbarray rgbarray/double_little.rgb.gz[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double big" ds9 -rgbarray rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" ds9 -rgbarray rgbarray/double_big.rgb.gz[dim=256,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Command Stdin" echo ".. char" cat rgbarray/char.rgb | ds9 -rgbarray -[dim=256,bitpix=8] & KillIt echo ".. char gzip" cat rgbarray/char.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=8] & KillIt echo ".. short little" cat rgbarray/short_little.rgb | ds9 -rgbarray -[dim=256,bitpix=16,arch=little] & KillIt echo ".. short little gzip" cat rgbarray/short_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=16,arch=little] & KillIt echo ".. short big" cat rgbarray/short_big.rgb | ds9 -rgbarray -[dim=256,bitpix=16,arch=big] & KillIt echo ".. short big gzip" cat rgbarray/short_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=16,arch=big] & KillIt echo ".. ushort little" cat rgbarray/ushort_little.rgb | ds9 -rgbarray -[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" cat rgbarray/ushort_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-16,arch=little] & KillIt echo ".. ushort big" cat rgbarray/ushort_big.rgb | ds9 -rgbarray -[dim=256,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" cat rgbarray/ushort_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-16,arch=big] & KillIt echo ".. int little" cat rgbarray/int_little.rgb | ds9 -rgbarray -[dim=256,bitpix=32,arch=little] & KillIt echo ".. int little gzip" cat rgbarray/int_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=32,arch=little] & KillIt echo ".. int big" cat rgbarray/int_big.rgb | ds9 -rgbarray -[dim=256,bitpix=32,arch=big] & KillIt echo ".. int big gzip" cat rgbarray/int_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=32,arch=big] & KillIt echo ".. longlong little" cat rgbarray/longlong_little.rgb | ds9 -rgbarray -[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" cat rgbarray/longlong_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=64,arch=little] & KillIt echo ".. longlong big" cat rgbarray/longlong_big.rgb | ds9 -rgbarray -[dim=256,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" cat rgbarray/longlong_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=64,arch=big] & KillIt echo ".. float little" cat rgbarray/float_little.rgb | ds9 -rgbarray -[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" cat rgbarray/float_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-32,arch=little] & KillIt echo ".. float big" cat rgbarray/float_big.rgb | ds9 -rgbarray -[dim=256,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" cat rgbarray/float_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-32,arch=big] & KillIt echo ".. double little" cat rgbarray/double_little.rgb | ds9 -rgbarray -[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" cat rgbarray/double_little.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-64,arch=little] & KillIt echo ".. double big" cat rgbarray/double_big.rgb | ds9 -rgbarray -[dim=256,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" cat rgbarray/double_big.rgb.gz | ds9 -rgbarray -[dim=256,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # export if [ "$1" = "export" -o -z "$1" ]; then echo "Testing Command export" initit ".. char" testit little [dim=256,bitpix=8] doit rgbarray/char.rgb[dim=256,bitpix=8] initit ".. short little little" testit little [dim=256,bitpix=16,arch=little] doit rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] initit ".. short little big" testit big [dim=256,bitpix=16,arch=big] doit rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] initit ".. short big little" testit little [dim=256,bitpix=16,arch=little] doit rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] initit ".. short big big" testit big [dim=256,bitpix=16,arch=big] doit rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] initit ".. ushort little little" testit little [dim=256,bitpix=-16,arch=little] doit rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] initit ".. ushort little big" testit big [dim=256,bitpix=-16,arch=big] doit rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] initit ".. ushort big little" testit little [dim=256,bitpix=-16,arch=little] doit rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] initit ".. ushort big big" testit big [dim=256,bitpix=-16,arch=big] doit rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] initit ".. int little little" testit little [dim=256,bitpix=32,arch=little] doit rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] initit ".. int little big" testit big [dim=256,bitpix=32,arch=big] doit rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] initit ".. int big little" testit little [dim=256,bitpix=32,arch=little] doit rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] initit ".. int big big" testit big [dim=256,bitpix=32,arch=big] doit rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] initit ".. longlong little little" testit little [dim=256,bitpix=64,arch=little] doit rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] initit ".. longlong little big" testit big [dim=256,bitpix=64,arch=big] doit rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] initit ".. longlong big little" testit little [dim=256,bitpix=64,arch=little] doit rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] initit ".. longlong big big" testit big [dim=256,bitpix=64,arch=big] doit rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] initit ".. float little little" testit little [dim=256,bitpix=-32,arch=little] doit rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] initit ".. float little big" testit big [dim=256,bitpix=-32,arch=big] doit rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] initit ".. float big little" testit little [dim=256,bitpix=-32,arch=little] doit rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] initit ".. float big big" testit big [dim=256,bitpix=-32,arch=big] doit rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] initit ".. double little little" testit little [dim=256,bitpix=-64,arch=little] doit rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] initit ".. double little big" testit big [dim=256,bitpix=-64,arch=big] doit rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] initit ".. double big little" testit little [dim=256,bitpix=-64,arch=little] doit rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] initit ".. double big big" testit big [dim=256,bitpix=-64,arch=big] doit rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 DoXPA ".. char" rgbarray/char.rgb[dim=256,bitpix=8] DoXPA ".. char gzip" rgbarray/char.rgb.gz[dim=256,bitpix=8] DoXPA ".. short little" rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] DoXPA ".. short little gzip" rgbarray/short_little.rgb.gz[dim=256,bitpix=16,arch=little] DoXPA ".. short big" rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] DoXPA ".. short big gzip" rgbarray/short_big.rgb.gz[dim=256,bitpix=16,arch=big] DoXPA ".. ushort little" rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] DoXPA ".. ushort little gzip" rgbarray/ushort_little.rgb.gz[dim=256,bitpix=-16,arch=little] DoXPA ".. ushort big" rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] DoXPA ".. ushort big gzip" rgbarray/ushort_big.rgb.gz[dim=256,bitpix=-16,arch=big] DoXPA ".. int little" rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] DoXPA ".. int little gzip" rgbarray/int_little.rgb.gz[dim=256,bitpix=32,arch=little] DoXPA ".. int big" rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] DoXPA ".. int big gzip" rgbarray/int_big.rgb.gz[dim=256,bitpix=32,arch=big] DoXPA ".. longlong little" rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] DoXPA ".. longlong little gzip" rgbarray/longlong_little.rgb.gz[dim=256,bitpix=64,arch=little] DoXPA ".. longlong big" rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] DoXPA ".. longlong big gzip" rgbarray/longlong_big.rgb.gz[dim=256,bitpix=64,arch=big] DoXPA ".. float little" rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] DoXPA ".. float little gzip" rgbarray/float_little.rgb.gz[dim=256,bitpix=-32,arch=little] DoXPA ".. float big" rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] DoXPA ".. float big gzip" rgbarray/float_big.rgb.gz[dim=256,bitpix=-32,arch=big] DoXPA ".. double little" rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] DoXPA ".. double little gzip" rgbarray/double_little.rgb.gz[dim=256,bitpix=-64,arch=little] DoXPA ".. double big" rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] DoXPA ".. double big gzip" rgbarray/double_big.rgb.gz[dim=256,bitpix=-64,arch=big] echo ".. backward compatibility" echo ".. array rgb" xpaset -p ds9 frame new rgb xpaset -p ds9 array rgb rgbarray/char.rgb[dim=256,bitpix=8] if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo ".. array new rgb" xpaset -p ds9 array new rgb rgbarray/char.rgb[dim=256,bitpix=8] if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 DoXPAStdin ".. char" rgbarray/char.rgb [dim=256,bitpix=8] DoXPAStdin ".. char gzip" rgbarray/char.rgb.gz [dim=256,bitpix=8] DoXPAStdin ".. short little" rgbarray/short_little.rgb [dim=256,bitpix=16,arch=little] DoXPAStdin ".. short little gzip" rgbarray/short_little.rgb.gz [dim=256,bitpix=16,arch=little] DoXPAStdin ".. short big" rgbarray/short_big.rgb [dim=256,bitpix=16,arch=big] DoXPAStdin ".. short big gzip" rgbarray/short_big.rgb.gz [dim=256,bitpix=16,arch=big] DoXPAStdin ".. ushort little" rgbarray/ushort_little.rgb [dim=256,bitpix=-16,arch=little] DoXPAStdin ".. ushort little gzip" rgbarray/ushort_little.rgb.gz [dim=256,bitpix=-16,arch=little] DoXPAStdin ".. ushort big" rgbarray/ushort_big.rgb [dim=256,bitpix=-16,arch=big] DoXPAStdin ".. ushort big gzip" rgbarray/ushort_big.rgb.gz [dim=256,bitpix=-16,arch=big] DoXPAStdin ".. int little" rgbarray/int_little.rgb [dim=256,bitpix=32,arch=little] DoXPAStdin ".. int little gzip" rgbarray/int_little.rgb.gz [dim=256,bitpix=32,arch=little] DoXPAStdin ".. int big" rgbarray/int_big.rgb [dim=256,bitpix=32,arch=big] DoXPAStdin ".. int big gzip" rgbarray/int_big.rgb.gz [dim=256,bitpix=32,arch=big] DoXPAStdin ".. longlong little" rgbarray/longlong_little.rgb [dim=256,bitpix=64,arch=little] DoXPAStdin ".. longlong little gzip" rgbarray/longlong_little.rgb.gz [dim=256,bitpix=64,arch=little] DoXPAStdin ".. longlong big" rgbarray/longlong_big.rgb [dim=256,bitpix=64,arch=big] DoXPAStdin ".. longlong big gzip" rgbarray/longlong_big.rgb.gz [dim=256,bitpix=64,arch=big] DoXPAStdin ".. float little" rgbarray/float_little.rgb [dim=256,bitpix=-32,arch=little] DoXPAStdin ".. float little gzip" rgbarray/float_little.rgb.gz [dim=256,bitpix=-32,arch=little] DoXPAStdin ".. float big" rgbarray/float_big.rgb [dim=256,bitpix=-32,arch=big] DoXPAStdin ".. float big gzip" rgbarray/float_big.rgb.gz [dim=256,bitpix=-32,arch=big] DoXPAStdin ".. double little" rgbarray/double_little.rgb [dim=256,bitpix=-64,arch=little] DoXPAStdin ".. double little gzip" rgbarray/double_little.rgb.gz [dim=256,bitpix=-64,arch=little] DoXPAStdin ".. double big" rgbarray/double_big.rgb [dim=256,bitpix=-64,arch=big] DoXPAStdin ".. double big gzip" rgbarray/double_big.rgb.gz [dim=256,bitpix=-64,arch=big] echo ".. backward compatibility" echo ".. array rgb" xpaset -p ds9 frame new rgb cat rgbarray/char.rgb | xpaset ds9 array rgb [dim=256,bitpix=8] if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo ".. array new rgb" cat rgbarray/char.rgb | xpaset ds9 array new rgb [dim=256,bitpix=8] if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 DoXPAStdout ".. char" rgbarray/char.rgb[dim=256,bitpix=8] little [dim=256,bitpix=8] DoXPAStdout ".. short little little" rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] little [dim=256,bitpix=16,arch=little] DoXPAStdout ".. short little big" rgbarray/short_little.rgb[dim=256,bitpix=16,arch=little] big [dim=256,bitpix=16,arch=big] DoXPAStdout ".. short big little" rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] little [dim=256,bitpix=16,arch=little] DoXPAStdout ".. short big big" rgbarray/short_big.rgb[dim=256,bitpix=16,arch=big] big [dim=256,bitpix=16,arch=big] DoXPAStdout ".. ushort little little" rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] little [dim=256,bitpix=-16,arch=little] DoXPAStdout ".. ushort little big" rgbarray/ushort_little.rgb[dim=256,bitpix=-16,arch=little] big [dim=256,bitpix=-16,arch=big] DoXPAStdout ".. ushort big little" rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] little [dim=256,bitpix=-16,arch=little] DoXPAStdout ".. ushort big big" rgbarray/ushort_big.rgb[dim=256,bitpix=-16,arch=big] big [dim=256,bitpix=-16,arch=big] DoXPAStdout ".. int little little" rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] little [dim=256,bitpix=32,arch=little] DoXPAStdout ".. int little big" rgbarray/int_little.rgb[dim=256,bitpix=32,arch=little] big [dim=256,bitpix=32,arch=big] DoXPAStdout ".. int big little" rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] little [dim=256,bitpix=32,arch=little] DoXPAStdout ".. int big big" rgbarray/int_big.rgb[dim=256,bitpix=32,arch=big] big [dim=256,bitpix=32,arch=big] DoXPAStdout ".. longlong little little" rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] little [dim=256,bitpix=64,arch=little] DoXPAStdout ".. longlong little big" rgbarray/longlong_little.rgb[dim=256,bitpix=64,arch=little] big [dim=256,bitpix=64,arch=big] DoXPAStdout ".. longlong big little" rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] little [dim=256,bitpix=64,arch=little] DoXPAStdout ".. longlong big big" rgbarray/longlong_big.rgb[dim=256,bitpix=64,arch=big] big [dim=256,bitpix=64,arch=big] DoXPAStdout ".. float little little" rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] little [dim=256,bitpix=-32,arch=little] DoXPAStdout ".. float little big" rgbarray/float_little.rgb[dim=256,bitpix=-32,arch=little] big [dim=256,bitpix=-32,arch=big] DoXPAStdout ".. float big little" rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] little [dim=256,bitpix=-32,arch=little] DoXPAStdout ".. float big big" rgbarray/float_big.rgb[dim=256,bitpix=-32,arch=big] big [dim=256,bitpix=-32,arch=big] DoXPAStdout ".. double little little" rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] little [dim=256,bitpix=-64,arch=little] DoXPAStdout ".. double little big" rgbarray/double_little.rgb[dim=256,bitpix=-64,arch=little] big [dim=256,bitpix=-64,arch=big] DoXPAStdout ".. double big little" rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] little [dim=256,bitpix=-64,arch=little] DoXPAStdout ".. double big big" rgbarray/double_big.rgb[dim=256,bitpix=-64,arch=big] big [dim=256,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013351� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.2.prf��������������������������������������������������������������������0000644�0001750�0001750�00000054624�11004151141�015076� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.2 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum top .bl mb .blmb factor { 1 1 } } array set bin [array get pbin] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 copy {} mb .ctmb width 1 smooth 4 top .ct levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Mask prefs global mask global pmask array set pmask { view 1 color red } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local top .scale mb .scalemb } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian top .sm mb .smmb view 0 } array set smooth [array get psmooth] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 colorbar,numerics 1 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # Buttons prefs global buttons array set buttons { color,he 1 view,lowhigh 0 frame,single 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 frame,newrgb 1 bin,512x 0 file,console 0 scale { .ds9.buttons.scale.linear buttons(scale,linear) .ds9.buttons.scale.log buttons(scale,log) .ds9.buttons.scale.pow buttons(scale,pow) .ds9.buttons.scale.sqrt buttons(scale,sqrt) .ds9.buttons.scale.squared buttons(scale,squared) .ds9.buttons.scale.hist buttons(scale,hist) .ds9.buttons.scale.minmax buttons(scale,minmax) .ds9.buttons.scale.995 buttons(scale,99.5) .ds9.buttons.scale.99 buttons(scale,99) .ds9.buttons.scale.98 buttons(scale,98) .ds9.buttons.scale.97 buttons(scale,97) .ds9.buttons.scale.96 buttons(scale,96) .ds9.buttons.scale.95 buttons(scale,95) .ds9.buttons.scale.925 buttons(scale,92.5) .ds9.buttons.scale.90 buttons(scale,90) .ds9.buttons.scale.zscale buttons(scale,zscale) .ds9.buttons.scale.zmax buttons(scale,zmax) .ds9.buttons.scale.user buttons(scale,user) .ds9.buttons.scale.datasec buttons(scale,datasec) .ds9.buttons.scale.params buttons(scale,params) } bin { .ds9.buttons.bin.average buttons(bin,average) .ds9.buttons.bin.sum buttons(bin,sum) .ds9.buttons.bin.in buttons(bin,in) .ds9.buttons.bin.out buttons(bin,out) .ds9.buttons.bin.fit buttons(bin,fit) .ds9.buttons.bin.1 buttons(bin,1) .ds9.buttons.bin.2 buttons(bin,2) .ds9.buttons.bin.4 buttons(bin,4) .ds9.buttons.bin.8 buttons(bin,8) .ds9.buttons.bin.16 buttons(bin,16) .ds9.buttons.bin.32 buttons(bin,32) .ds9.buttons.bin.64 buttons(bin,64) .ds9.buttons.bin.128 buttons(bin,128) .ds9.buttons.bin.256 buttons(bin,256) .ds9.buttons.bin.128x buttons(bin,128x) .ds9.buttons.bin.256x buttons(bin,256x) .ds9.buttons.bin.512x buttons(bin,512x) .ds9.buttons.bin.1024x buttons(bin,1024x) .ds9.buttons.bin.2048x buttons(bin,2048x) .ds9.buttons.bin.4096x buttons(bin,4096x) .ds9.buttons.bin.8192x buttons(bin,8192x) .ds9.buttons.bin.params buttons(bin,params) } bin,8192x 0 edit,prefs 0 bin,2048x 0 edit,colorbar 1 scale,minmax 1 view,horizontal 0 view,colorbar 1 color,sls 0 majorPrev .ds9.buttons.file frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 file,pspage 0 region,list 1 bin,8 1 scale,zscale 1 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 view { .ds9.buttons.view.horizontal buttons(view,horizontal) .ds9.buttons.view.vertical buttons(view,vertical) .ds9.buttons.view.info buttons(view,info) .ds9.buttons.view.panner buttons(view,panner) .ds9.buttons.view.magnifier buttons(view,magnifier) .ds9.buttons.view.buttons buttons(view,buttons) .ds9.buttons.view.colorbar buttons(view,colorbar) .ds9.buttons.view.graphhorz buttons(view,graphhorz) .ds9.buttons.view.graphvert buttons(view,graphvert) .ds9.buttons.view.filename buttons(view,filename) .ds9.buttons.view.object buttons(view,object) .ds9.buttons.view.minmax buttons(view,minmax) .ds9.buttons.view.lowhigh buttons(view,lowhigh) .ds9.buttons.view.frame buttons(view,frame) .ds9.buttons.view.wcs buttons(view,wcs) .ds9.buttons.view.image buttons(view,image) .ds9.buttons.view.physical buttons(view,physical) .ds9.buttons.view.amplifier buttons(view,amplifier) .ds9.buttons.view.detector buttons(view,detector) .ds9.buttons.view.numerics buttons(view,numerics) } scale,96 0 scale,97 0 scale,98 0 file,exit 1 scale,99 0 region,showtext 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 help { .ds9.buttons.help.ref buttons(help,ref) .ds9.buttons.help.keyboard buttons(help,keyboard) .ds9.buttons.help.faq buttons(help,faq) .ds9.buttons.help.new buttons(help,new) .ds9.buttons.help.issue buttons(help,issue) .ds9.buttons.help.release buttons(help,release) .ds9.buttons.help.desk buttons(help,desk) .ds9.buttons.help.ack buttons(help,ack) .ds9.buttons.help.home buttons(help,home) } file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 edit { .ds9.buttons.edit.undo buttons(edit,undo) .ds9.buttons.edit.cut buttons(edit,cut) .ds9.buttons.edit.copy buttons(edit,copy) .ds9.buttons.edit.paste buttons(edit,paste) .ds9.buttons.edit.none buttons(edit,none) .ds9.buttons.edit.pointer buttons(edit,pointer) .ds9.buttons.edit.crosshair buttons(edit,crosshair) .ds9.buttons.edit.colorbar buttons(edit,colorbar) .ds9.buttons.edit.pan buttons(edit,pan) .ds9.buttons.edit.zoom buttons(edit,zoom) .ds9.buttons.edit.rotate buttons(edit,rotate) .ds9.buttons.edit.catalog buttons(edit,catalog) .ds9.buttons.edit.examine buttons(edit,examine) .ds9.buttons.edit.prefs buttons(edit,prefs) } region,load 1 region,savetemplate 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 wcs { .ds9.buttons.wcs.fk4 buttons(wcs,fk4) .ds9.buttons.wcs.fk5 buttons(wcs,fk5) .ds9.buttons.wcs.icrs buttons(wcs,icrs) .ds9.buttons.wcs.galactic buttons(wcs,galactic) .ds9.buttons.wcs.ecliptic buttons(wcs,ecliptic) .ds9.buttons.wcs.degrees buttons(wcs,degrees) .ds9.buttons.wcs.sexagesimal buttons(wcs,sexagesimal) } edit,catalog 1 frame,tile 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 zoom,1/2 1 color,blue 0 region { .ds9.buttons.region.show buttons(region,show) .ds9.buttons.region.showtext buttons(region,showtext) .ds9.buttons.region.info buttons(region,info) .ds9.buttons.region.front buttons(region,front) .ds9.buttons.region.back buttons(region,back) .ds9.buttons.region.all buttons(region,all) .ds9.buttons.region.none buttons(region,none) .ds9.buttons.region.invert buttons(region,invert) .ds9.buttons.region.delete buttons(region,delete) .ds9.buttons.region.deleteall buttons(region,deleteall) .ds9.buttons.region.newgroup buttons(region,newgroup) .ds9.buttons.region.group buttons(region,group) .ds9.buttons.region.create buttons(region,create) .ds9.buttons.region.dissolve buttons(region,dissolve) .ds9.buttons.region.loadtemplate buttons(region,loadtemplate) .ds9.buttons.region.savetemplate buttons(region,savetemplate) .ds9.buttons.region.list buttons(region,list) .ds9.buttons.region.load buttons(region,load) .ds9.buttons.region.save buttons(region,save) .ds9.buttons.region.circle buttons(region,circle) .ds9.buttons.region.ellipse buttons(region,ellipse) .ds9.buttons.region.box buttons(region,box) .ds9.buttons.region.polygon buttons(region,polygon) .ds9.buttons.region.line buttons(region,line) .ds9.buttons.region.vector buttons(region,vector) .ds9.buttons.region.text buttons(region,text) .ds9.buttons.region.point buttons(region,point) .ds9.buttons.region.ruler buttons(region,ruler) .ds9.buttons.region.compass buttons(region,compass) .ds9.buttons.region.projection buttons(region,projection) .ds9.buttons.region.annulus buttons(region,annulus) .ds9.buttons.region.ellipseannulus buttons(region,ellipseannulus) .ds9.buttons.region.boxannulus buttons(region,boxannulus) .ds9.buttons.region.panda buttons(region,panda) .ds9.buttons.region.epanda buttons(region,epanda) .ds9.buttons.region.bpanda buttons(region,bpanda) } file,psprint 0 zoom,1/4 1 wcs,ecliptic 1 region,newgroup 0 region,save 1 color,aips0 1 major {.ds9.buttons.major.file .ds9.buttons.major.edit .ds9.buttons.major.view .ds9.buttons.major.frame .ds9.buttons.major.bin .ds9.buttons.major.zoom .ds9.buttons.major.scale .ds9.buttons.major.color .ds9.buttons.major.region .ds9.buttons.major.wcs .ds9.buttons.major.help} wcs,galactic 1 zoom,1/8 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,hist 1 view,numerics 0 zoom,4 1 color,reset 0 file,about 1 view,detector 0 view,minmax 0 frame,new 1 zoom,8 1 region,show 0 zoom,center 0 frame { .ds9.buttons.frame.new buttons(frame,new) .ds9.buttons.frame.newrgb buttons(frame,newrgb) .ds9.buttons.frame.delete buttons(frame,delete) .ds9.buttons.frame.deleteall buttons(frame,deleteall) .ds9.buttons.frame.clear buttons(frame,clear) .ds9.buttons.frame.reset buttons(frame,reset) .ds9.buttons.frame.refresh buttons(frame,refresh) .ds9.buttons.frame.single buttons(frame,single) .ds9.buttons.frame.tile buttons(frame,tile) .ds9.buttons.frame.blink buttons(frame,blink) .ds9.buttons.frame.size buttons(frame,size) .ds9.buttons.frame.matchframe buttons(frame,matchframe) .ds9.buttons.frame.matchcolor buttons(frame,matchcolor) .ds9.buttons.frame.matchscale buttons(frame,matchscale) .ds9.buttons.frame.cube buttons(frame,cube) .ds9.buttons.frame.rgb buttons(frame,rgb) .ds9.buttons.frame.movefirst buttons(frame,movefirst) .ds9.buttons.frame.moveprev buttons(frame,moveprev) .ds9.buttons.frame.movenext buttons(frame,movenext) .ds9.buttons.frame.movelast buttons(frame,movelast) .ds9.buttons.frame.first buttons(frame,first) .ds9.buttons.frame.prev buttons(frame,prev) .ds9.buttons.frame.next buttons(frame,next) .ds9.buttons.frame.last buttons(frame,last) } zoom,fit 1 region,ellipseannulus 0 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 scale,92.5 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 majorCurrent .ds9.buttons.file wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 zoom { .ds9.buttons.zoom.center buttons(zoom,center) .ds9.buttons.zoom.align buttons(zoom,align) .ds9.buttons.zoom.in buttons(zoom,in) .ds9.buttons.zoom.out buttons(zoom,out) .ds9.buttons.zoom.fit buttons(zoom,fit) .ds9.buttons.zoom.z132 buttons(zoom,1/32) .ds9.buttons.zoom.z116 buttons(zoom,1/16) .ds9.buttons.zoom.z18 buttons(zoom,1/8) .ds9.buttons.zoom.z14 buttons(zoom,1/4) .ds9.buttons.zoom.z12 buttons(zoom,1/2) .ds9.buttons.zoom.z1 buttons(zoom,1) .ds9.buttons.zoom.z2 buttons(zoom,2) .ds9.buttons.zoom.z4 buttons(zoom,4) .ds9.buttons.zoom.z8 buttons(zoom,8) .ds9.buttons.zoom.z16 buttons(zoom,16) .ds9.buttons.zoom.z32 buttons(zoom,32) .ds9.buttons.zoom.none buttons(zoom,none) .ds9.buttons.zoom.x buttons(zoom,x) .ds9.buttons.zoom.y buttons(zoom,y) .ds9.buttons.zoom.xy buttons(zoom,xy) .ds9.buttons.zoom.0 buttons(zoom,0) .ds9.buttons.zoom.90 buttons(zoom,90) .ds9.buttons.zoom.180 buttons(zoom,180) .ds9.buttons.zoom.270 buttons(zoom,270) .ds9.buttons.zoom.params buttons(zoom,params) } color,heat 1 color {.ds9.buttons.color.grey buttons(color,grey) .ds9.buttons.color.red buttons(color,red) .ds9.buttons.color.green buttons(color,green) .ds9.buttons.color.blue buttons(color,blue) .ds9.buttons.color.a buttons(color,a) .ds9.buttons.color.b buttons(color,b) .ds9.buttons.color.bb buttons(color,bb) .ds9.buttons.color.he buttons(color,he) .ds9.buttons.color.i8 buttons(color,i8) .ds9.buttons.color.aips0 buttons(color,aips0) .ds9.buttons.color.sls buttons(color,sls) .ds9.buttons.color.hsv buttons(color,hsv) .ds9.buttons.color.heat buttons(color,heat) .ds9.buttons.color.cool buttons(color,cool) .ds9.buttons.color.rainbow buttons(color,rainbow) .ds9.buttons.color.standard buttons(color,standard) .ds9.buttons.color.staircase buttons(color,staircase) .ds9.buttons.color.color buttons(color,color) .ds9.buttons.color.invert buttons(color,invert) .ds9.buttons.color.reset buttons(color,reset) .ds9.buttons.color.params buttons(color,params) } edit,zoom 1 file { .ds9.buttons.file.about buttons(file,about) .ds9.buttons.file.open buttons(file,open) .ds9.buttons.file.saveimage buttons(file,saveimage) .ds9.buttons.file.savefits buttons(file,savefits) .ds9.buttons.file.savempeg buttons(file,savempeg) .ds9.buttons.file.header buttons(file,header) .ds9.buttons.file.xpa buttons(file,xpa) .ds9.buttons.file.console buttons(file,console) .ds9.buttons.file.tcl buttons(file,tcl) .ds9.buttons.file.pspage buttons(file,pspage) .ds9.buttons.file.psprint buttons(file,psprint) .ds9.buttons.file.page buttons(file,page) .ds9.buttons.file.print buttons(file,print) .ds9.buttons.file.exit buttons(file,exit) } region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 zoom,1/16 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 zoom,1/32 0 region,line 0 region,epanda 0 zoom,out 1 scale,99.5 0 bin,sum 0 bin,256x 0 region,bpanda 0 bin,64 1 } # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] # Edit prefs set prefs(ds9,mode) pointer set ds9(mode) pointer # Frame prefs global tile set prefs(tile,mode) grid set tile(mode) grid global blink set prefs(blink,interval) 500 set blink(interval) 500 # Zoom prefs global current global wcs set prefs(zoom) { 1 1 } set current(zoom) { 1 1 } set prefs(orient) none set current(orient) none set prefs(rotate) 0 set current(rotate) 0 # Color prefs global colorbar set prefs(colorbar,map) Grey set colorbar(map) Grey set prefs(colorbar,invert) 0 set colorbar(invert) 0 # Region prefs global marker set prefs(marker,shape) {circle} set marker(shape) {circle} set prefs(marker,color) green set marker(color) green set prefs(marker,width) 1 set marker(width) 1 set prefs(marker,edit) 1 set marker(edit) 1 set prefs(marker,move) 1 set marker(move) 1 set prefs(marker,rotate) 1 set marker(rotate) 1 set prefs(marker,delete) 1 set marker(delete) 1 set prefs(marker,fixed) 0 set marker(fixed) 0 set prefs(marker,include) 1 set marker(include) 1 set prefs(marker,source) 1 set marker(source) 1 set prefs(marker,font) helvetica set marker(font) helvetica set prefs(marker,font,size) 10 set marker(font,size) 10 set prefs(marker,font,style) normal set marker(font,style) normal set prefs(marker,format) ds9 set marker(format) ds9 set prefs(marker,strip) 0 set marker(strip) 0 set prefs(marker,wcs) 0 set marker(wcs) 0 set prefs(marker,system) physical set marker(system) physical set prefs(marker,sky) fk5 set marker(sky) fk5 set prefs(marker,skyformat) degrees set marker(skyformat) degrees set marker(dialog,system) physical set marker(dialog,sky) fk5 set marker(dialog,skyformat) degrees set marker(dialog,dist,system) physical set marker(dialog,dist,format) degrees set marker(circle,radius) 20 set marker(ellipse,radius1) 40 set marker(ellipse,radius2) 20 set marker(box,radius1) 80 set marker(box,radius2) 40 set marker(polygon,width) 20 set marker(polygon,height) 20 set marker(projection,thick) 0 set marker(annulus,inner) 15 set marker(annulus,outer) 30 set marker(annulus,annuli) 1 set marker(ellipseannulus,radius1) 40 set marker(ellipseannulus,radius2) 20 set marker(ellipseannulus,radius3) 60 set marker(ellipseannulus,annuli) 1 set marker(boxannulus,radius1) 80 set marker(boxannulus,radius2) 40 set marker(boxannulus,radius3) 120 set marker(boxannulus,annuli) 1 set marker(panda,inner) 15 set marker(panda,outer) 30 set marker(panda,annuli) 1 set marker(panda,ang1) 0 set marker(panda,ang2) 360 set marker(panda,angnum) 4 set marker(epanda,radius1) 40 set marker(epanda,radius2) 20 set marker(epanda,radius3) 60 set marker(epanda,annuli) 1 set marker(epanda,ang1) 0 set marker(epanda,ang2) 360 set marker(epanda,angnum) 4 set marker(bpanda,radius1) 80 set marker(bpanda,radius2) 40 set marker(bpanda,radius3) 120 set marker(bpanda,annuli) 1 set marker(bpanda,ang1) 0 set marker(bpanda,ang2) 360 set marker(bpanda,angnum) 4 set marker(point,size) 11 global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false global nres set nres(server) {simbad-sao} global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green global hv set hv(archive,menu,1) {} set hv(archive,url,1) {} set hv(archive,menu,2) {} set hv(archive,url,2) {} set hv(archive,menu,3) {} set hv(archive,url,3) {} set hv(archive,menu,4) {} set hv(archive,url,4) {} global vo set vo(server) {http://cxc.harvard.edu/chandraed/list.txt} set vo(hv) 1 set vo(method) xpa set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} global analysis set prefs(analysis,log) 0 set analysis(log) 0 # Analysis Plot prefs set prefs(ap,grid) 1 set prefs(ap,grid,log) linearlinear set prefs(ap,discrete) 0 set prefs(ap,discrete,symbol) circle set prefs(ap,discrete,color) red set prefs(ap,linear) 1 set prefs(ap,linear,width) 1 set prefs(ap,linear,color) black set prefs(ap,linear,dash) no set prefs(ap,step) 0 set prefs(ap,step,width) 1 set prefs(ap,step,color) black set prefs(ap,step,dash) no set prefs(ap,quadratic) 0 set prefs(ap,quadratic,width) 1 set prefs(ap,quadratic,color) black set prefs(ap,quadratic,dash) no set prefs(ap,error,width) 1 set prefs(ap,error,color) red set prefs(ap,error,style) 1 set prefs(ap,titleFont) helvetica set prefs(ap,titleSize) 12 set prefs(ap,titleStyle) normal set prefs(ap,textlabFont) helvetica set prefs(ap,textlabSize) 10 set prefs(ap,textlabStyle) normal set prefs(ap,numlabFont) helvetica set prefs(ap,numlabSize) 10 set prefs(ap,numlabStyle) normal # Language set ds9(language) locale set ds9(language,name) English # Background Color prefs set ds9(bg,color) white # Blank/Inf/NaN Color prefs set ds9(nan,color) white # Font prefs set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } # Panner prefs global panner set panner(compass,image) 1 set panner(compass,wcs) 1 set panner(compass,wcs,system) wcs set panner(compass,wcs,sky) fk5 # Magnifier prefs global magnifier set magnifier(region) 1 set magnifier(cursor) 1 set magnifier(zoom) 4 # Truecolor Colorbar prefs global colorbar set colorbar(area) 0 set colorbar(mode) center # Dialog prefs global ds9 set ds9(dialog) native # PanZoom prefs global panzoom set panzoom(mode) click # Print Coordinates prefs global coord set coord(value) 1 set coord(image) 1 set coord(physical) 0 set coord(amplifier) 0 set coord(detector) 0 set coord(wcs) 1 set coord(wcsa) 0 set coord(wcsb) 0 set coord(wcsc) 0 set coord(wcsd) 0 set coord(wcse) 0 set coord(wcsf) 0 set coord(wcsg) 0 set coord(wcsh) 0 set coord(wcsi) 0 set coord(wcsj) 0 set coord(wcsk) 0 set coord(wcsl) 0 set coord(wcsm) 0 set coord(wcsn) 0 set coord(wcso) 0 set coord(wcsp) 0 set coord(wcsq) 0 set coord(wcsr) 0 set coord(wcss) 0 set coord(wcst) 0 set coord(wcsu) 0 set coord(wcsv) 0 set coord(wcsw) 0 set coord(wcsx) 0 set coord(wcsy) 0 set coord(wcsz) 0 set coord(sky) fk5 set coord(skyformat) sexagesimal # Examine prefs global examine set examine(mode) new set examine(zoom) 4 # Misc prefs global ds9 set ds9(tmpdir) {/tmp} set ds9(automarker) 1 set ds9(xpa) 1 set ds9(confirm) 1 # HTTP prefs global http set http(proxy) 0 set http(proxy,host) {} set http(proxy,port) {} set http(auth) 0 set http(auth,user) {} set http(auth,passwd) {} ������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.0.prf��������������������������������������������������������������������0000644�0001750�0001750�00000021275�11004151141�015070� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.0 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) $ds9(version)] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum top .bl mb .blmb factor { 1 1 } } array set bin [array get pbin] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 copy {} mb .ctmb width 1 smooth 4 top .ct levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Mask prefs global mask global pmask array set pmask { view 1 color red } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local top .scale mb .scalemb } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian top .sm mb .smmb view 0 } array set smooth [array get psmooth] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 info,lowhigh 0 magnifier 1 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 colorbar,numerics 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] # Edit prefs set prefs(ds9,mode) pointer set ds9(mode) pointer # Frame prefs global tile set prefs(tile,mode) grid set tile(mode) grid global blink set prefs(blink,interval) 500 set blink(interval) 500 # Zoom prefs global current global wcs set prefs(zoom) { 1 1 } set current(zoom) { 1 1 } set prefs(orient) none set current(orient) none set prefs(rotate) 0 set current(rotate) 0 # Color prefs global colorbar set prefs(colorbar,map) Grey set colorbar(map) Grey set prefs(colorbar,invert) 0 set colorbar(invert) 0 # Region prefs global marker set prefs(marker,shape) {circle} set marker(shape) {circle} set prefs(marker,color) green set marker(color) green set prefs(marker,width) 1 set marker(width) 1 set prefs(marker,edit) 1 set marker(edit) 1 set prefs(marker,move) 1 set marker(move) 1 set prefs(marker,rotate) 1 set marker(rotate) 1 set prefs(marker,delete) 1 set marker(delete) 1 set prefs(marker,fixed) 0 set marker(fixed) 0 set prefs(marker,include) 1 set marker(include) 1 set prefs(marker,source) 1 set marker(source) 1 set prefs(marker,font) helvetica set marker(font) helvetica set prefs(marker,font,size) 10 set marker(font,size) 10 set prefs(marker,font,style) normal set marker(font,style) normal set prefs(marker,format) ds9 set marker(format) ds9 set prefs(marker,strip) 0 set marker(strip) 0 set prefs(marker,wcs) 0 set marker(wcs) 0 set prefs(marker,system) physical set marker(system) physical set prefs(marker,sky) fk5 set marker(sky) fk5 set prefs(marker,skyformat) degrees set marker(skyformat) degrees set marker(dialog,system) physical set marker(dialog,sky) fk5 set marker(dialog,skyformat) degrees set marker(dialog,dist,system) physical set marker(dialog,dist,format) degrees set marker(circle,radius) 20 set marker(ellipse,radius1) 40 set marker(ellipse,radius2) 20 set marker(box,radius1) 80 set marker(box,radius2) 40 set marker(polygon,width) 20 set marker(polygon,height) 20 set marker(projection,thick) 0 set marker(annulus,inner) 15 set marker(annulus,outer) 30 set marker(annulus,annuli) 1 set marker(ellipseannulus,radius1) 40 set marker(ellipseannulus,radius2) 20 set marker(ellipseannulus,radius3) 60 set marker(ellipseannulus,annuli) 1 set marker(boxannulus,radius1) 80 set marker(boxannulus,radius2) 40 set marker(boxannulus,radius3) 120 set marker(boxannulus,annuli) 1 set marker(panda,inner) 15 set marker(panda,outer) 30 set marker(panda,annuli) 1 set marker(panda,ang1) 0 set marker(panda,ang2) 360 set marker(panda,angnum) 4 set marker(epanda,radius1) 40 set marker(epanda,radius2) 20 set marker(epanda,radius3) 60 set marker(epanda,annuli) 1 set marker(epanda,ang1) 0 set marker(epanda,ang2) 360 set marker(epanda,angnum) 4 set marker(bpanda,radius1) 80 set marker(bpanda,radius2) 40 set marker(bpanda,radius3) 120 set marker(bpanda,annuli) 1 set marker(bpanda,ang1) 0 set marker(bpanda,ang2) 360 set marker(bpanda,angnum) 4 set marker(point,size) 11 global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false global nres set nres(server) {simbad-sao} global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green global hv set hv(archive,menu,1) {} set hv(archive,url,1) {} set hv(archive,menu,2) {} set hv(archive,url,2) {} set hv(archive,menu,3) {} set hv(archive,url,3) {} set hv(archive,menu,4) {} set hv(archive,url,4) {} global vo set vo(server) {http://cxc.harvard.edu/chandraed/list.txt} set vo(hv) 1 set vo(method) xpa set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} global analysis set prefs(analysis,log) 0 set analysis(log) 0 # Analysis Plot prefs set prefs(ap,grid) 1 set prefs(ap,grid,log) linearlinear set prefs(ap,discrete) 0 set prefs(ap,discrete,symbol) circle set prefs(ap,discrete,color) red set prefs(ap,linear) 1 set prefs(ap,linear,width) 1 set prefs(ap,linear,color) black set prefs(ap,linear,dash) no set prefs(ap,step) 0 set prefs(ap,step,width) 1 set prefs(ap,step,color) black set prefs(ap,step,dash) no set prefs(ap,quadratic) 0 set prefs(ap,quadratic,width) 1 set prefs(ap,quadratic,color) black set prefs(ap,quadratic,dash) no set prefs(ap,error,width) 1 set prefs(ap,error,color) red set prefs(ap,error,style) 1 set prefs(ap,titleFont) helvetica set prefs(ap,titleSize) 12 set prefs(ap,titleStyle) normal set prefs(ap,textlabFont) helvetica set prefs(ap,textlabSize) 10 set prefs(ap,textlabStyle) normal set prefs(ap,numlabFont) helvetica set prefs(ap,numlabSize) 10 set prefs(ap,numlabStyle) normal # Language set ds9(language) locale set ds9(language,name) Locale # Background Color prefs set ds9(bg,color) white # Blank/Inf/NaN Color prefs set ds9(nan,color) white # Font prefs set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } # Panner prefs global panner set panner(compass,image) 1 set panner(compass,wcs) 1 set panner(compass,wcs,system) wcs set panner(compass,wcs,sky) fk5 # Magnifier prefs global magnifier set magnifier(region) 1 set magnifier(cursor) 1 set magnifier(zoom) 4 # Truecolor Colorbar prefs global colorbar set colorbar(area) 0 set colorbar(mode) center # Dialog prefs global ds9 set ds9(dialog) motif # PanZoom prefs global panzoom set panzoom(mode) click # Print Coordinates prefs global coord set coord(value) 1 set coord(image) 1 set coord(physical) 0 set coord(amplifier) 0 set coord(detector) 0 set coord(wcs) 1 set coord(wcsa) 0 set coord(wcsb) 0 set coord(wcsc) 0 set coord(wcsd) 0 set coord(wcse) 0 set coord(wcsf) 0 set coord(wcsg) 0 set coord(wcsh) 0 set coord(wcsi) 0 set coord(wcsj) 0 set coord(wcsk) 0 set coord(wcsl) 0 set coord(wcsm) 0 set coord(wcsn) 0 set coord(wcso) 0 set coord(wcsp) 0 set coord(wcsq) 0 set coord(wcsr) 0 set coord(wcss) 0 set coord(wcst) 0 set coord(wcsu) 0 set coord(wcsv) 0 set coord(wcsw) 0 set coord(wcsx) 0 set coord(wcsy) 0 set coord(wcsz) 0 set coord(sky) fk5 set coord(skyformat) sexagesimal # Examine prefs global examine set examine(mode) new set examine(zoom) 4 # Misc prefs global ds9 set ds9(tmpdir) {/tmp} set ds9(automarker) 1 set ds9(xpa) 1 set ds9(confirm) 1 # HTTP prefs global http set http(proxy) 0 set http(proxy,host) {} set http(proxy,port) {} set http(auth) 0 set http(auth,user) {} set http(auth,passwd) {} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.7.0.prf��������������������������������������������������������������������0000644�0001750�0001750�00000025723�11765664114�015123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 7.0 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } global pds9 array set pds9 { nan,msg White dialog motif text,font courier samp 1 font,msg Helvetica threads 8 font,weight normal automarker 1 bg,msg White language locale text,font,weight normal dialog,all 0 nan white font,slant roman confirm 1 backup 1 language,dir {} font helvetica language,name English bg white xpa 1 text,font,msg Courier theme native tcl 0 font,size 9 text,font,slant roman text,font,size 9 } global current global pcurrent array set pcurrent { orient none zoom { 1 1 } mode pointer display single rotate 0 } array set current [array get pcurrent] global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] global phttp array set phttp { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 proxy,port {} } global pbuttons array set pbuttons { color,he 1 frame,lock,frame,physical 0 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 frame,lock,scale 0 help,story 0 help,new 0 frame,match,color 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,lock,cube 0 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 scale,asinh 1 color,numerics 0 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,match,crop,wcs 0 frame,clear 1 bin,1 1 bin,2 1 frame,new3d 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 frame,lock,crop,none 0 frame,lock,frame,detector 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 frame,match,crop,image 0 scale,90 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 frame,match,cube 0 color,cool 1 frame,match,frame,amplifier 0 bin,average 0 bin,128x 0 frame,lock,crosshair,image 0 color,staircase 0 view,image 0 frame,reset 0 scale,95 0 file,save 1 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 frame,lock,crop,physical 0 help,ref 1 color,grey 1 frame,lock,crop,amplifier 0 frame,lock,crosshair,none 0 view,filename 0 view,magnifier 1 region,vector 0 frame,lock,crosshair,wcs 0 color,vert 0 color,green 0 file,header 1 edit,crop 1 edit,cut 0 frame,lock,crop,image 0 frame,match,scale 0 region,all 1 scale,user 0 file,samp,image 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 region,deleteall 0 color,standard 0 frame,match,frame,physical 0 help,faq 0 frame,lock,frame,image 0 region,load 1 frame,match,frame,image 0 region,savetemplate 0 region,loadtemplate 0 scale,925 0 color,rainbow 1 zoom,params 0 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 frame,lock,crosshair,amplifier 0 bin,fit 1 region,ruler 0 region,circle 0 frame,match,crosshair,amplifier 0 view,physical 0 color,a 1 color,b 1 frame,lock,crop,detector 0 scale,sqrt 1 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 region,group 0 frame,movenext 0 frame,match,crosshair,physical 0 bin,128 0 file,print 1 frame,lock,crop,wcs 0 frame,delete 1 frame,lock,frame,none 0 frame,match,crop,physical 0 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 frame,match,crosshair,wcs 0 region,back 1 file,samp,table 0 frame,match,frame,detector 0 scale,squared 1 scale,datasec 0 help,desk 1 region,ellipse 0 frame,cube 0 view,graphvert 1 edit,none 1 major,edit 1 frame,lock,crosshair,physical 0 color,blue 0 file,psprint 0 wcs,ecliptic 1 color,horz 0 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 region,front 1 zoom,0 0 zoom,1 1 frame,moveprev 0 zoom,2 1 scale,995 0 frame,match,frame,wcs 0 scale,hist 1 zoom,4 1 color,reset 0 color,numspace 0 file,about 1 region,show 0 view,minmax 0 view,detector 0 frame,new 1 frame,match,crop,amplifier 0 zoom,8 1 zoom,center 0 region,ellipseannulus 0 zoom,fit 1 major,bin 1 frame,next 1 edit,pan 1 view,info 1 frame,match,crosshair,detector 0 frame,lock,frame,amplifier 0 bin,1024x 0 bin,out 1 view,object 0 frame,match,crop,detector 0 color,invert 0 region,create 0 region,info 1 frame,match,crosshair,image 0 scale,sinh 1 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 frame,lock,color 0 bin,16 1 frame,lock,bin 0 frame,3d 0 major,frame 1 frame,lock,crosshair,detector 0 frame,match,bin 0 color,color 0 help,ack 1 color,i8 1 frame,prev 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 zoom,crop 0 help,keyboard 1 scale,log 1 frame,lock,frame,wcs 0 bin,4096x 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 color,hsv 0 view,graphhorz 1 file,export 0 region,line 0 color,numvalue 0 region,epanda 0 zoom,out 1 bin,sum 0 bin,256x 0 help,user 1 file,movie 0 region,bpanda 0 bin,64 1 } global ppanner array set ppanner { compass 1 } global pmagnifier array set pmagnifier { region 1 zoom 4 color,msg White cursor 1 color white } global ps global pps array set pps { scale 100 orient portrait height 11 size letter resolution 150 filename,txt ds9.txt dest printer level 2 width 8.5 filename ds9.ps cmd lp color rgb } array set ps [array get pps] global pr global ppr array set ppr { } array set pr [array get ppr] global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] global tile global ptile array set ptile { grid,col 10 mode grid grid,row 10 grid,gap 4 grid,mode automatic } array set tile [array get ptile] global threed global pthreed array set pthreed { highlite,color,msg Cyan highlite,color cyan method mip highlite 1 } array set threed [array get pthreed] global bin global pbin array set pbin { wheel,factor 1.01 wheel 0 lock 0 depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] global panzoom global ppanzoom array set ppanzoom { wheel,factor 1.01 preserve 0 wheel 1 mode click } array set panzoom [array get ppanzoom] global scale global pscale array set pscale { preserve 0 datasec 1 mode minmax scope local log 1000 type linear } array set scale [array get pscale] global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 bpanda,ang2 360 boxannulus,annuli 1 delete 1 centroid,radius 10 annulus,inner 15 panda,angnum 4 show,text 1 centroid,iteration 30 epanda,angnum 4 plot2d 0 font,size 10 rotate 1 move 1 fixed 0 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 plot3d 1 epanda,radius1 40 panda,outer 30 panda,annuli 1 epanda,radius2 20 epanda,radius3 60 source 1 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 bpanda,radius3 120 color green format ds9 annulus,outer 30 font,weight normal polygon,width 20 font,slant roman edit 1 font helvetica bpanda,angnum 4 dash 0 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 include 1 epanda,ang1 0 centroid,auto 0 epanda,ang2 360 circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] global wcs global pwcs array set pwcs { skyformat sexagesimal system wcs sky fk5 align 0 } array set wcs [array get pwcs] global pgraph array set pgraph { horz,log false horz,grid 1 vert,log false vert,grid 1 } global pcoord array set pcoord { wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 wcsf 0 image 1 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 filename 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 wcsr 0 wcsb 0 } global pexamine array set pexamine { zoom 4 mode new } global pixel global ppixel array set ppixel { size 5 } array set pixel [array get ppixel] global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] global contour global pcontour array set pcontour { numlevel 5 dash 0 width 1 method block color,msg Green smooth 4 color green } array set contour [array get pcontour] global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] global nres global pnres array set nres { server simbad-cds } array set nres [array get pnres] global pcat array set pcat { sym,units physical sym,font,weight normal vot 1 loc 500 server cds sym,color,msg Green sym,font,msg Helvetica sym,font,slant roman sym,font,size 10 sym,font,weight, {} sym,color green sym,font helvetica sym,shape {circle point} } global pvo array set pvo { method xpa hv 1 delay 15 server http://cxc.harvard.edu/chandraed/list.txt } global pap array set pap { step,dash no step,width 1 discrete,color,msg Red numlabFont,msg Helvetica titleFont helvetica quadratic,color black step,color,msg Black numlabSize 9 titleWeight normal error 1 linear 1 textlabFont,msg Helvetica numlabFont helvetica textlabSlant roman error,width 1 quadratic 0 grid 1 discrete,color red numlabWeight normal textlabSize 9 linear,width 1 step,color black error,color,msg Red linear,color,msg Black numlabSlant roman quadratic,dash no quadratic,width 1 textlabFont helvetica discrete 0 quadratic,color,msg Black titleFont,msg Helvetica textlabWeight normal titleSlant roman grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } global panalysis array set panalysis { user2 {} autoload 1 user3 {} log 0 user4 {} user {} } # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { invert 0 lock 0 size 20 font,weight normal space 0 tag red font,slant roman map grey numerics 1 font helvetica orientation horizontal font,size 9 ticks 11 tag,msg Red } array set colorbar [array get pcolorbar] ���������������������������������������������./saods9/tests/prefs/ds9.6.2.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023462�11576454532�015123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 6.2 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } global pds9 array set pds9 { nan,msg White dialog motif samp 1 font,msg Helvetica font,weight normal automarker 1 bg,msg White language locale font,slant roman nan white backup 1 confirm 1 language,dir {} font helvetica language,name English xpa 1 bg white tcl 0 font,size 9 } global current global pcurrent array set pcurrent { orient none zoom { 1 1 } mode pointer display single rotate 0 } array set current [array get pcurrent] global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] global phttp array set phttp { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 proxy,port {} } global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 frame,matchframe,amplifier 0 help,story 0 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 color,numerics 0 major,wcs 1 zoom,i8 1 view,colorbar 1 frame,matchbin 0 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 color,vert 0 file,header 1 edit,cut 0 region,all 1 file,savefits 0 scale,user 0 file,samp,image 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 region,deleteall 0 color,standard 0 help,faq 0 region,load 1 region,savetemplate 0 region,loadtemplate 0 scale,925 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 region,group 0 frame,movenext 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 frame,matchframe,physical 0 region,back 1 file,samp,table 0 scale,squared 1 scale,datasec 0 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 color,horz 0 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 region,front 1 zoom,0 0 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 color,numspace 0 region,show 0 view,minmax 0 view,detector 0 frame,new 1 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 frame,matchframe,image 0 frame,matchframe,wcs 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 graphics 0 region,circle3d 0 wcs,sexagesimal 1 region,panda 0 frame,matchframe,detector 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 color,numvalue 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 help,user 1 region,bpanda 0 bin,64 1 } global ppanner array set ppanner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 } global pmagnifier array set pmagnifier { region 1 zoom 4 color,msg White cursor 1 color white } global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] global tile global ptile array set ptile { grid,col 10 mode grid grid,row 10 grid,gap 4 grid,mode automatic } array set tile [array get ptile] global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] global panzoom global ppanzoom array set ppanzoom { wheel,factor 1.2 preserve 0 wheel 1 mode click } array set panzoom [array get ppanzoom] global scale global pscale array set pscale { preserve 0 datasec 1 mode minmax scope local log 1000 type linear } array set scale [array get pscale] global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 centroid,radius 10 annulus,inner 15 panda,angnum 4 show,text 1 epanda,angnum 4 centroid,iteration 30 circle3d,radius 20 font,size 10 rotate 1 move 1 fixed 0 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 epanda,radius1 40 panda,outer 30 panda,annuli 1 epanda,radius2 20 epanda,radius3 60 source 1 dialog,system physical bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 font,weight normal polygon,width 20 font,slant roman edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 centroid,auto 0 dialog,dist,format degrees circle,radius 20 width 1 bpanda,annuli 1 projection,method 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 circle3d,method 1 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] global pgraph array set pgraph { horz,log false horz,grid 1 vert,log false vert,grid 1 } global pcoord array set pcoord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } global pexamine array set pexamine { zoom 4 mode new } global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] global contour global pcontour array set pcontour { numlevel 5 dash 0 width 1 method block color,msg Green smooth 4 color green } array set contour [array get pcontour] global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] global nres global pnres array set nres { server simbad-cds } array set nres [array get pnres] global pcat array set pcat { sym,units physical sym,font,weight normal vot 1 loc 500 server cds sym,color,msg Green sym,font,msg Helvetica sym,font,slant roman sym,font,size 10 sym,font,weight, {} sym,color green sym,font helvetica sym,shape {circle point} } global pvo array set pvo { method xpa hv 1 delay 15 server http://cxc.harvard.edu/chandraed/list.txt } global pap array set pap { step,dash no step,width 1 discrete,color,msg Red numlabFont,msg Helvetica titleFont helvetica quadratic,color black step,color,msg Black numlabSize 9 titleWeight normal error 1 linear 1 textlabFont,msg Helvetica numlabFont helvetica textlabSlant roman error,width 1 quadratic 0 grid 1 discrete,color red numlabWeight normal textlabSize 9 linear,width 1 step,color black error,color,msg Red linear,color,msg Black numlabSlant roman quadratic,dash no quadratic,width 1 textlabFont helvetica discrete 0 quadratic,color,msg Black titleFont,msg Helvetica textlabWeight normal titleSlant roman grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } global panalysis array set panalysis { user2 {} user3 {} log 0 user4 {} user {} } # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { invert 0 space 0 orientation horizontal font,slant roman ticks 11 map Grey numerics 1 font,size 9 size 20 font helvetica font,weight normal } array set colorbar [array get pcolorbar] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.6.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023664�11322716562�015123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.6.3 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,polygon 0 region,none 1 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 region,show 0 view,detector 0 view,minmax 0 frame,new 1 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 file,samp 1 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green set cat(vot) 1 # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 width 1 dash 0 color,msg Green smooth 4 levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 set ds9(samp,auto) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees paste,sky fk5 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 wcs 0 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees paste,system wcs circle,radius 20 load current width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 ellipseannulus,annuli 1 panda,ang1 0 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-sao} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] ����������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.7.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023710�11322716162�015110� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.7 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,polygon 0 region,none 1 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 region,show 0 view,detector 0 view,minmax 0 frame,new 1 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 help,user 1 file,samp 1 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {cds} set cat(sym,shape) {circle point} set cat(sym,color) green set cat(vot) 1 # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 width 1 dash 0 color,msg Green smooth 4 levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 set ds9(samp,auto) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} xpa {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} unique 0 } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees paste,sky fk5 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees paste,system wcs circle,radius 20 load current width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 ellipseannulus,annuli 1 panda,ang1 0 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-cds} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] ��������������������������������������������������������./saods9/tests/prefs/ds9.7.1.prf��������������������������������������������������������������������0000644�0001750�0001750�00000026257�12131315525�015112� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 7.1 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } global pds9 array set pds9 { nan,msg White dialog motif text,font courier samp 1 font,msg Helvetica threads 8 font,weight normal automarker 1 bg,msg White language locale text,font,weight normal dialog,all 0 nan white font,slant roman confirm 1 backup 1 language,dir {} font helvetica language,name English bg white xpa 1 text,font,msg Courier theme native tcl 0 font,size 9 text,font,slant roman text,font,size 9 } global current global pcurrent array set pcurrent { orient none zoom { 1 1 } mode pointer display single rotate 0 } array set current [array get pcurrent] global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] global phttp array set phttp { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 proxy,port {} } global pbuttons array set pbuttons { color,he 1 frame,lock,frame,physical 0 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 frame,lock,scale 0 help,story 0 help,new 0 frame,match,color 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,lock,cube 0 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 frame,match,smooth 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 scale,asinh 1 color,numerics 0 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,match,crop,wcs 0 frame,clear 1 bin,1 1 bin,2 1 frame,new3d 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 frame,lock,crop,none 0 frame,lock,frame,detector 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 frame,match,crop,image 0 scale,90 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 frame,match,cube 0 color,cool 1 frame,match,frame,amplifier 0 bin,average 0 bin,128x 0 frame,lock,crosshair,image 0 color,staircase 0 view,image 0 frame,reset 0 scale,95 0 file,save 1 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 frame,lock,crop,physical 0 help,ref 1 color,grey 1 frame,lock,crop,amplifier 0 frame,lock,crosshair,none 0 view,filename 0 view,magnifier 1 region,vector 0 frame,lock,crosshair,wcs 0 color,vert 0 color,green 0 file,header 1 edit,crop 1 edit,cut 0 frame,lock,crop,image 0 frame,match,scale 0 region,all 1 scale,user 0 file,samp,image 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 region,deleteall 0 color,standard 0 frame,match,frame,physical 0 help,faq 0 frame,lock,frame,image 0 region,load 1 frame,match,frame,image 0 region,savetemplate 0 region,loadtemplate 0 scale,925 0 color,rainbow 1 zoom,params 0 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 frame,lock,crosshair,amplifier 0 bin,fit 1 region,ruler 0 region,circle 0 frame,match,crosshair,amplifier 0 view,physical 0 color,a 1 color,b 1 frame,lock,crop,detector 0 scale,sqrt 1 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 region,group 0 frame,movenext 0 frame,match,crosshair,physical 0 bin,128 0 file,print 1 frame,lock,crop,wcs 0 frame,delete 1 frame,lock,frame,none 0 frame,match,crop,physical 0 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 frame,match,crosshair,wcs 0 help,about 1 region,back 1 file,samp,table 0 frame,match,frame,detector 0 scale,squared 1 scale,datasec 0 help,desk 1 region,ellipse 0 frame,cube 0 view,graphvert 1 edit,none 1 major,edit 1 frame,lock,crosshair,physical 0 color,blue 0 file,psprint 0 wcs,ecliptic 1 color,horz 0 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 region,front 1 zoom,0 0 zoom,1 1 frame,moveprev 0 zoom,2 1 scale,995 0 frame,match,frame,wcs 0 scale,hist 1 zoom,4 1 color,reset 0 color,numspace 0 region,show 0 view,minmax 0 view,detector 0 frame,new 1 frame,match,crop,amplifier 0 zoom,8 1 zoom,center 0 region,ellipseannulus 0 zoom,fit 1 major,bin 1 frame,next 1 edit,pan 1 view,info 1 frame,match,crosshair,detector 0 frame,lock,frame,amplifier 0 bin,1024x 0 bin,out 1 view,object 0 frame,lock,smooth 0 frame,match,crop,detector 0 color,invert 0 region,create 0 region,info 1 frame,match,crosshair,image 0 scale,sinh 1 color,bb 1 file,tcl 0 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 frame,lock,color 0 bin,16 1 frame,lock,bin 0 frame,3d 0 major,frame 1 frame,lock,crosshair,detector 0 frame,match,bin 0 color,color 0 help,ack 1 color,i8 1 frame,prev 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 zoom,crop 0 help,keyboard 1 scale,log 1 frame,lock,frame,wcs 0 bin,4096x 0 zoom,align 0 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 color,hsv 0 view,graphhorz 1 file,export 0 region,line 0 color,numvalue 0 region,epanda 0 zoom,out 1 bin,sum 0 bin,256x 0 help,user 1 file,movie 0 region,bpanda 0 bin,64 1 } global ppanner array set ppanner { compass 1 } global pmagnifier array set pmagnifier { region 1 zoom 4 color,msg White cursor 1 color white } global ps global pps array set pps { scale 100 orient portrait height 11 size letter resolution 150 filename,txt ds9.txt dest printer level 2 width 8.5 filename ds9.ps cmd lp color rgb } array set ps [array get pps] global pr global ppr array set ppr { } array set pr [array get ppr] global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] global tile global ptile array set ptile { grid,col 10 mode grid grid,row 10 grid,gap 4 grid,mode automatic } array set tile [array get ptile] global threed global pthreed array set pthreed { border,color,msg Blue highlite,color,msg Cyan scale 1 method mip highlite,color cyan border,color blue compass,color green highlite 1 border 1 compass 0 } array set threed [array get pthreed] global bin global pbin array set pbin { wheel,factor 1.2 wheel 0 lock 0 depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] global panzoom global ppanzoom array set ppanzoom { wheel,factor 1.2 preserve 0 wheel 1 mode click } array set panzoom [array get ppanzoom] global scale global pscale array set pscale { preserve 0 datasec 1 mode minmax scope local log 1000 type linear } array set scale [array get pscale] global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 bpanda,ang2 360 boxannulus,annuli 1 delete 1 centroid,radius 10 dformat degrees annulus,inner 15 panda,angnum 4 show,text 1 epanda,angnum 4 centroid,iteration 30 plot2d 0 font,size 10 rotate 1 move 1 fixed 0 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 plot3d 1 epanda,radius1 40 panda,outer 30 panda,annuli 1 epanda,radius2 20 epanda,radius3 60 source 1 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 bpanda,radius3 120 color green format ds9 annulus,outer 30 font,weight normal polygon,width 20 font,slant roman edit 1 font helvetica bpanda,angnum 4 dash 0 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 include 1 epanda,ang1 0 centroid,auto 0 epanda,ang2 360 circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] global wcs global pwcs array set pwcs { skyformat sexagesimal system wcs sky fk5 align 0 } array set wcs [array get pwcs] global pgraph array set pgraph { horz,log false horz,grid 1 vert,log false vert,grid 1 } global pcoord array set pcoord { wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 wcsf 0 image 1 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 filename 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 wcsr 0 wcsb 0 } global pexamine array set pexamine { zoom 4 mode new } global pixel global ppixel array set ppixel { size 5 } array set pixel [array get ppixel] global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] global contour global pcontour array set pcontour { numlevel 5 dash 0 width 1 method block color,msg Green smooth 4 color green } array set contour [array get pcontour] global smooth global psmooth array set psmooth { radius 3 lock 0 function gaussian view 0 } array set smooth [array get psmooth] global nres global pnres array set nres { server simbad-cds } array set nres [array get pnres] global pcat array set pcat { sym,units physical sym,font,weight normal vot 1 loc 500 server cds sym,color,msg Green sym,font,msg Helvetica sym,font,slant roman sym,font,size 10 sym,font,weight, {} sym,color green sym,font helvetica sym,shape {circle point} } global pvo array set pvo { method xpa hv 1 delay 15 server http://cxc.harvard.edu/chandraed/list.txt } global pap array set pap { textlabSlant roman quadratic 0 textlabFont,msg Helvetica numlabWeight normal quadratic,dash no textlabWeight normal graph,y,grid 1 quadratic,color black discrete,color,msg Red error 1 discrete,color red step,color black linear,color,msg Black discrete 0 graph,x,log 0 titleSize 12 error,color red bar 0 graph,y,flip 0 linear,color black step,dash no titleFont helvetica titleWeight normal linear 1 discrete,fill 1 textlabSize 9 graph,x,grid 1 numlabSlant roman quadratic,width 1 textlabFont helvetica quadratic,color,msg Black titleSlant roman step 0 discrete,symbol circle linear,dash no step,width 1 numlabFont,msg Helvetica step,color,msg Black numlabSize 9 graph,x,flip 0 numlabFont helvetica error,width 1 linear,width 1 error,color,msg Red bar,color black titleFont,msg Helvetica graph,y,log 0 } global panalysis array set panalysis { user2 {} autoload 1 user3 {} log 0 user4 {} user {} } # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { invert 0 lock 0 size 20 font,weight normal space 0 tag red font,slant roman map grey numerics 1 font helvetica orientation horizontal font,size 9 ticks 11 tag,msg Red } array set colorbar [array get pcolorbar] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.6.1.prf��������������������������������������������������������������������0000644�0001750�0001750�00000022142�11431323362�015076� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 6.1.2 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } global pds9 array set pds9 { dialog native samp 1 automarker 1 font,style normal language locale nan white backup 1 confirm 1 font default language,dir {} xpa 1 bg white language,name English tcl 0 font,size 10 } if {$pds9(font) != "default"} { option add *font {default 10 normal} } global current global pcurrent array set pcurrent { orient none zoom { 1 1 } mode pointer display single rotate 0 } array set current [array get pcurrent] global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] global phttp array set phttp { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 proxy,port {} } global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 color,numerics 0 major,wcs 1 zoom,i8 1 view,colorbar 1 frame,matchbin 0 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 color,vert 0 file,header 1 edit,cut 0 region,all 1 file,savefits 0 scale,user 0 file,samp,image 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 region,deleteall 0 color,standard 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 region,group 0 frame,movenext 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 file,samp,table 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 color,horz 0 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 color,numspace 0 region,show 0 view,minmax 0 view,detector 0 frame,new 1 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 color,numvalue 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 help,user 1 region,bpanda 0 bin,64 1 } global ppanner array set ppanner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 } global pmagnifier array set pmagnifier { region 1 zoom 4 cursor 1 } global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] global tile global ptile array set ptile { grid,col 10 mode grid grid,row 10 grid,gap 4 grid,mode automatic } array set tile [array get ptile] global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] global panzoom global ppanzoom array set ppanzoom { wheel,factor 1.2 preserve 0 wheel 1 mode click } array set panzoom [array get ppanzoom] global scale global pscale array set pscale { preserve 0 datasec 1 mode minmax scope local log 1000 type linear } array set scale [array get pscale] global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 move 1 rotate 1 fixed 0 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 epanda,radius1 40 panda,outer 30 panda,annuli 1 epanda,radius2 20 epanda,radius3 60 source 1 dialog,system physical bpanda,radius1 80 bpanda,radius2 40 dialog,skyformat degrees epanda,annuli 1 bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 include 1 epanda,ang1 0 dialog,dist,format degrees epanda,ang2 360 circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] global pgraph array set pgraph { horz,log false horz,grid 1 vert,log false vert,grid 1 } global pcoord array set pcoord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } global pexamine array set pexamine { zoom 4 mode new } global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] global contour global pcontour array set pcontour { numlevel 5 dash 0 width 1 method block smooth 4 color green } array set contour [array get pcontour] global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] global nres global pnres array set nres { server simbad-cds } array set nres [array get pnres] global pcat array set pcat { sym,units physical sym,color green vot 1 sym,shape {circle point} loc 500 server cds } global pvo array set pvo { method xpa hv 1 delay 15 server http://cxc.harvard.edu/chandraed/list.txt } global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } global panalysis array set panalysis { user2 {} user3 {} log 0 user4 {} user {} } # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { invert 0 space 0 orientation horizontal font,style normal map Grey numerics 1 font,size 10 size 20 font helvetica } array set colorbar [array get pcolorbar] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.1.prf��������������������������������������������������������������������0000644�0001750�0001750�00000021312�11004151141�015061� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.1 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum top .bl mb .blmb factor { 1 1 } } array set bin [array get pbin] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 copy {} mb .ctmb width 1 smooth 4 top .ct levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Mask prefs global mask global pmask array set pmask { view 1 color red } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local top .scale mb .scalemb } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian top .sm mb .smmb view 0 } array set smooth [array get psmooth] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 info,lowhigh 0 magnifier 1 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 colorbar,numerics 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] # Edit prefs set prefs(ds9,mode) pointer set ds9(mode) pointer # Frame prefs global tile set prefs(tile,mode) grid set tile(mode) grid global blink set prefs(blink,interval) 500 set blink(interval) 500 # Zoom prefs global current global wcs set prefs(zoom) { 1 1 } set current(zoom) { 1 1 } set prefs(orient) none set current(orient) none set prefs(rotate) 0 set current(rotate) 0 # Color prefs global colorbar set prefs(colorbar,map) Grey set colorbar(map) Grey set prefs(colorbar,invert) 0 set colorbar(invert) 0 # Region prefs global marker set prefs(marker,shape) {circle} set marker(shape) {circle} set prefs(marker,color) green set marker(color) green set prefs(marker,width) 1 set marker(width) 1 set prefs(marker,edit) 1 set marker(edit) 1 set prefs(marker,move) 1 set marker(move) 1 set prefs(marker,rotate) 1 set marker(rotate) 1 set prefs(marker,delete) 1 set marker(delete) 1 set prefs(marker,fixed) 0 set marker(fixed) 0 set prefs(marker,include) 1 set marker(include) 1 set prefs(marker,source) 1 set marker(source) 1 set prefs(marker,font) helvetica set marker(font) helvetica set prefs(marker,font,size) 10 set marker(font,size) 10 set prefs(marker,font,style) normal set marker(font,style) normal set prefs(marker,format) ds9 set marker(format) ds9 set prefs(marker,strip) 0 set marker(strip) 0 set prefs(marker,wcs) 0 set marker(wcs) 0 set prefs(marker,system) physical set marker(system) physical set prefs(marker,sky) fk5 set marker(sky) fk5 set prefs(marker,skyformat) degrees set marker(skyformat) degrees set marker(dialog,system) physical set marker(dialog,sky) fk5 set marker(dialog,skyformat) degrees set marker(dialog,dist,system) physical set marker(dialog,dist,format) degrees set marker(circle,radius) 20 set marker(ellipse,radius1) 40 set marker(ellipse,radius2) 20 set marker(box,radius1) 80 set marker(box,radius2) 40 set marker(polygon,width) 20 set marker(polygon,height) 20 set marker(projection,thick) 0 set marker(annulus,inner) 15 set marker(annulus,outer) 30 set marker(annulus,annuli) 1 set marker(ellipseannulus,radius1) 40 set marker(ellipseannulus,radius2) 20 set marker(ellipseannulus,radius3) 60 set marker(ellipseannulus,annuli) 1 set marker(boxannulus,radius1) 80 set marker(boxannulus,radius2) 40 set marker(boxannulus,radius3) 120 set marker(boxannulus,annuli) 1 set marker(panda,inner) 15 set marker(panda,outer) 30 set marker(panda,annuli) 1 set marker(panda,ang1) 0 set marker(panda,ang2) 360 set marker(panda,angnum) 4 set marker(epanda,radius1) 40 set marker(epanda,radius2) 20 set marker(epanda,radius3) 60 set marker(epanda,annuli) 1 set marker(epanda,ang1) 0 set marker(epanda,ang2) 360 set marker(epanda,angnum) 4 set marker(bpanda,radius1) 80 set marker(bpanda,radius2) 40 set marker(bpanda,radius3) 120 set marker(bpanda,annuli) 1 set marker(bpanda,ang1) 0 set marker(bpanda,ang2) 360 set marker(bpanda,angnum) 4 set marker(point,size) 11 global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false global nres set nres(server) {simbad-sao} global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green global hv set hv(archive,menu,1) {} set hv(archive,url,1) {} set hv(archive,menu,2) {} set hv(archive,url,2) {} set hv(archive,menu,3) {} set hv(archive,url,3) {} set hv(archive,menu,4) {} set hv(archive,url,4) {} global vo set vo(server) {http://cxc.harvard.edu/chandraed/list.txt} set vo(hv) 1 set vo(method) xpa set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} global analysis set prefs(analysis,log) 0 set analysis(log) 0 # Analysis Plot prefs set prefs(ap,grid) 1 set prefs(ap,grid,log) linearlinear set prefs(ap,discrete) 0 set prefs(ap,discrete,symbol) circle set prefs(ap,discrete,color) red set prefs(ap,linear) 1 set prefs(ap,linear,width) 1 set prefs(ap,linear,color) black set prefs(ap,linear,dash) no set prefs(ap,step) 0 set prefs(ap,step,width) 1 set prefs(ap,step,color) black set prefs(ap,step,dash) no set prefs(ap,quadratic) 0 set prefs(ap,quadratic,width) 1 set prefs(ap,quadratic,color) black set prefs(ap,quadratic,dash) no set prefs(ap,error,width) 1 set prefs(ap,error,color) red set prefs(ap,error,style) 1 set prefs(ap,titleFont) helvetica set prefs(ap,titleSize) 12 set prefs(ap,titleStyle) normal set prefs(ap,textlabFont) helvetica set prefs(ap,textlabSize) 10 set prefs(ap,textlabStyle) normal set prefs(ap,numlabFont) helvetica set prefs(ap,numlabSize) 10 set prefs(ap,numlabStyle) normal # Language set ds9(language) locale set ds9(language,name) English # Background Color prefs set ds9(bg,color) white # Blank/Inf/NaN Color prefs set ds9(nan,color) white # Font prefs set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } # Panner prefs global panner set panner(compass,image) 1 set panner(compass,wcs) 1 set panner(compass,wcs,system) wcs set panner(compass,wcs,sky) fk5 # Magnifier prefs global magnifier set magnifier(region) 1 set magnifier(cursor) 1 set magnifier(zoom) 4 # Truecolor Colorbar prefs global colorbar set colorbar(area) 0 set colorbar(mode) center # Dialog prefs global ds9 set ds9(dialog) native # PanZoom prefs global panzoom set panzoom(mode) click # Print Coordinates prefs global coord set coord(value) 1 set coord(image) 1 set coord(physical) 0 set coord(amplifier) 0 set coord(detector) 0 set coord(wcs) 1 set coord(wcsa) 0 set coord(wcsb) 0 set coord(wcsc) 0 set coord(wcsd) 0 set coord(wcse) 0 set coord(wcsf) 0 set coord(wcsg) 0 set coord(wcsh) 0 set coord(wcsi) 0 set coord(wcsj) 0 set coord(wcsk) 0 set coord(wcsl) 0 set coord(wcsm) 0 set coord(wcsn) 0 set coord(wcso) 0 set coord(wcsp) 0 set coord(wcsq) 0 set coord(wcsr) 0 set coord(wcss) 0 set coord(wcst) 0 set coord(wcsu) 0 set coord(wcsv) 0 set coord(wcsw) 0 set coord(wcsx) 0 set coord(wcsy) 0 set coord(wcsz) 0 set coord(sky) fk5 set coord(skyformat) sexagesimal # Examine prefs global examine set examine(mode) new set examine(zoom) 4 # Misc prefs global ds9 set ds9(tmpdir) {/tmp} set ds9(automarker) 1 set ds9(xpa) 1 set ds9(confirm) 1 # HTTP prefs global http set http(proxy) 0 set http(proxy,host) {} set http(proxy,port) {} set http(auth) 0 set http(auth,user) {} set http(auth,passwd) {} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.5.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023510�11322716562�015110� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.5.1 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 file,pspage 0 region,list 1 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,polygon 0 region,none 1 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 region,show 0 frame,new 1 view,detector 0 view,minmax 0 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 width 1 dash 0 smooth 4 levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 wcs 0 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-sao} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.6.0.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023623�11355450075�015111� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 6.0 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 region,list 1 file,pspage 0 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 region,showtext 0 file,exit 1 scale,99 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,polygon 0 region,none 1 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,save 1 region,newgroup 0 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 region,show 0 view,detector 0 view,minmax 0 frame,new 1 zoom,8 1 zoom,center 0 zoom,fit 1 region,ellipseannulus 0 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 zoom,out 1 region,epanda 0 bin,sum 0 bin,256x 0 help,user 1 file,samp 1 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {cds} set cat(sym,shape) {circle point} set cat(sym,color) green set cat(vot) 1 # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { numlevel 5 dash 0 width 1 method block color,msg Green smooth 4 color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 set ds9(samp,auto) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} windows {} unique 0 } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees paste,sky fk5 ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees paste,system wcs circle,radius 20 load current width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 ellipseannulus,annuli 1 panda,ang1 0 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-cds} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] �������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.4.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023506�11322716562�015114� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.4 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 file,pspage 0 region,list 1 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 file,exit 1 scale,99 0 region,showtext 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,newgroup 0 region,save 1 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 frame,new 1 view,detector 0 view,minmax 0 zoom,8 1 region,show 0 zoom,center 0 region,ellipseannulus 0 zoom,fit 1 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 region,epanda 0 zoom,out 1 bin,sum 0 bin,256x 0 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 width 1 dash 0 smooth 4 levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 wcs 0 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { transparency 0 color red mark 1 } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-sao} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/prefs/ds9.5.3.prf��������������������������������������������������������������������0000644�0001750�0001750�00000023467�11322716562�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global ds9 global prefs set prefs(version) 5.3 # this is a check for to ensure a match between the # current ds9 version matches the prefs version if {[string compare $prefs(version) [lindex $ds9(version) 0]] == 1} { tk_messageBox -type ok -icon warning -message "[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}]" return } # Analysis prefs global analysis global panalysis array set panalysis { log 0 } array set analysis [array get panalysis] # AP prefs global pap array set pap { step,dash no step,width 1 titleFont helvetica quadratic,color black numlabSize 10 error 1 linear 1 textlabStyle normal numlabFont helvetica error,width 1 quadratic 0 grid 1 discrete,color red textlabSize 10 linear,width 1 step,color black numlabStyle normal quadratic,dash no quadratic,width 1 textlabFont helvetica titleStyle normal discrete 0 grid,log linearlinear step 0 titleSize 12 error,color red discrete,symbol circle linear,color black error,style 1 linear,dash no } # Bin prefs global bin global pbin array set pbin { depth 1 buffersize 1024 function sum factor { 1 1 } } array set bin [array get pbin] # Blink prefs global blink global pblink array set pblink { interval 500 } array set blink [array get pblink] # Buttons prefs global pbuttons array set pbuttons { color,he 1 view,lowhigh 0 frame,single 1 major,color 1 view,wcs 0 bin,in 1 view,buttons 1 help,release 1 file,open 1 edit,crosshair 1 view,panner 1 help,new 0 view,amplifier 0 scale,params 0 region,dissolve 0 major,zoom 1 frame,newrgb 1 major,file 1 bin,512x 0 file,console 0 bin,8192x 0 edit,prefs 0 bin,2048x 0 zoom,i2 1 edit,colorbar 1 zoom,i4 1 scale,minmax 1 view,horizontal 0 major,wcs 1 zoom,i8 1 view,colorbar 1 color,sls 0 frame,clear 1 bin,1 1 bin,2 1 zoom,16 0 edit,rotate 1 file,page 1 bin,4 1 zoom,none 0 file,pspage 0 region,list 1 bin,8 1 scale,zscale 1 region,centroid 0 region,autocentroid 0 frame,size 0 zoom,270 0 scale,pow 1 scale,90 0 help,issue 0 wcs,fk4 1 zoom,32 0 wcs,fk5 1 frame,blink 1 bin,average 0 bin,128x 0 color,cool 1 view,image 0 frame,reset 0 scale,95 0 color,staircase 0 scale,96 0 scale,97 0 major,scale 1 scale,98 0 file,exit 1 scale,99 0 region,showtext 0 frame,first 1 help,ref 1 color,grey 1 view,filename 0 view,magnifier 1 region,vector 0 color,green 0 file,header 1 edit,cut 0 file,savefits 0 region,all 1 scale,user 0 file,saveimage 1 color,params 0 zoom,in 1 frame,movelast 0 edit,pointer 1 color,standard 0 region,deleteall 0 help,faq 0 region,load 1 region,savetemplate 0 scale,925 0 region,loadtemplate 0 zoom,params 0 color,rainbow 1 frame,refresh 0 zoom,i16 0 zoom,90 0 region,delete 1 edit,copy 0 file,xpa 0 region,annulus 0 bin,fit 1 region,circle 0 region,ruler 0 view,physical 0 color,a 1 color,b 1 scale,sqrt 1 frame,matchframe 0 zoom,i32 0 major,view 1 view,vertical 0 region,point 0 frame,movenext 0 region,group 0 bin,128 0 file,print 1 frame,delete 1 frame,movefirst 0 color,red 0 region,none 1 region,polygon 0 bin,params 0 frame,last 1 scale,zmax 0 edit,catalog 1 frame,tile 1 major,help 1 region,compass 0 edit,paste 0 scale,squared 1 scale,datasec 0 region,back 1 help,desk 1 frame,cube 0 region,ellipse 0 view,graphvert 1 edit,none 1 major,edit 1 color,blue 0 file,psprint 0 wcs,ecliptic 1 region,newgroup 0 region,save 1 color,aips0 1 wcs,galactic 1 zoom,0 0 region,front 1 zoom,1 1 frame,matchcolor 0 frame,moveprev 0 zoom,2 1 scale,995 0 scale,hist 1 zoom,4 1 color,reset 0 file,about 1 frame,new 1 view,detector 0 view,minmax 0 zoom,8 1 region,show 0 zoom,center 0 region,ellipseannulus 0 zoom,fit 1 major,bin 1 frame,next 1 edit,pan 1 view,info 1 bin,1024x 0 bin,out 1 view,object 0 color,invert 0 region,info 1 region,create 0 file,tcl 0 color,bb 1 wcs,sexagesimal 1 region,panda 0 region,boxannulus 0 wcs,degrees 1 region,box 0 wcs,icrs 1 view,frame 0 bin,16 1 major,frame 1 color,color 0 help,ack 1 frame,prev 1 color,i8 1 color,heat 1 edit,zoom 1 region,invert 0 edit,examine 1 bin,32 1 frame,deleteall 0 region,text 0 region,projection 0 help,keyboard 1 scale,log 1 bin,4096x 0 file,savempeg 0 frame,matchscale 0 zoom,align 0 help,home 1 scale,linear 1 edit,undo 0 major,region 1 zoom,x 0 frame,rgb 0 bin,256 0 zoom,y 0 zoom,xy 0 zoom,180 0 view,graphhorz 1 color,hsv 0 region,line 0 region,epanda 0 zoom,out 1 bin,sum 0 bin,256x 0 region,bpanda 0 bin,64 1 } # CAT prefs global cat set cat(server) {sao} set cat(sym,shape) {circle point} set cat(sym,color) green # Colorbar prefs global colorbar global pcolorbar array set pcolorbar { font,style normal orientation horizontal invert 0 font,size 10 numerics 1 map Grey font helvetica } array set colorbar [array get pcolorbar] # Contour prefs global contour global pcontour array set pcontour { scale linear method block view 0 width 1 dash 0 smooth 4 levels 5 min {} mode minmax max {} color green } array set contour [array get pcontour] # Coord prefs global coord array set coord { skyformat sexagesimal wcss 0 wcsc 0 wcst 0 wcsd 0 wcsu 0 wcse 0 wcsv 0 image 1 wcsf 0 wcsw 0 wcsg 0 wcsx 0 wcsh 0 physical 0 wcs 1 wcsy 0 wcsi 0 wcsz 0 wcsj 0 wcsk 0 wcsl 0 amplifier 0 wcsm 0 detector 0 wcsn 0 wcso 0 wcsp 0 value 1 wcsq 0 wcsa 0 sky fk5 wcsr 0 wcsb 0 } # Current prefs global current global pcurrent array set pcurrent { orient none zoom { 1 1 } rotate 0 } array set current [array get pcurrent] # DS9 prefs global ds9 global pds9 array set pds9 { mode pointer } array set ds9 [array get pds9] set ds9(analysis,user) {} set ds9(analysis,user2) {} set ds9(analysis,user3) {} set ds9(analysis,user4) {} set ds9(automarker) 1 set ds9(bg,color) white set ds9(confirm) 1 set ds9(dialog) native set ds9(font) default set ds9(font,size) 10 set ds9(font,style) normal if {$ds9(font) != "default"} { option add *font {default 10 normal} } set ds9(language) locale set ds9(language,name) English set ds9(nan,color) white set ds9(tmpdir) {/tmp} set ds9(xpa) 1 # Examine prefs global examine array set examine { zoom 4 mode new } # Graph prefs global graph set graph(horz,grid) 1 set graph(horz,log) false set graph(vert,grid) 1 set graph(vert,log) false # HTTP prefs global http array set http { auth,passwd {} proxy,host {} auth,user {} auth 0 proxy 0 timeout 240000 proxy,port {} } # HV prefs global hv array set hv { archive,url,3 {} archive,menu,1 {} archive,url,4 {} archive,menu,2 {} archive,menu,3 {} archive,url,1 {} archive,menu,4 {} archive,url,2 {} } # Magnifier prefs global magnifier array set magnifier { region 1 zoom 4 cursor 1 size 128 } # Marker prefs global marker global pmarker array set pmarker { panda,ang2 360 bpanda,ang1 0 shape circle show 1 dialog,dist,system physical bpanda,ang2 360 boxannulus,annuli 1 delete 1 annulus,inner 15 panda,angnum 4 autocentroid 0 show,text 1 epanda,angnum 4 font,size 10 rotate 1 move 1 fixed 0 skyformat degrees ellipseannulus,radius1 40 ellipseannulus,radius2 20 ellipseannulus,radius3 60 wcs 0 epanda,radius1 40 epanda,radius2 20 panda,outer 30 panda,annuli 1 epanda,radius3 60 source 1 dialog,system physical strip 0 bpanda,radius1 80 bpanda,radius2 40 epanda,annuli 1 dialog,skyformat degrees bpanda,radius3 120 sky fk5 color green format ds9 annulus,outer 30 polygon,width 20 font,style normal edit 1 font helvetica bpanda,angnum 4 dash 0 dialog,sky fk5 projection,thick 0 boxannulus,radius1 80 dashlist {8 3} polygon,height 20 boxannulus,radius2 40 system physical boxannulus,radius3 120 box,radius1 80 box,radius2 40 point,size 11 annulus,annuli 1 compass,radius 40 epanda,ang1 0 include 1 epanda,ang2 360 dialog,dist,format degrees circle,radius 20 width 1 bpanda,annuli 1 ellipse,radius1 40 preserve 0 panda,inner 15 ellipse,radius2 20 maxdialog 48 panda,ang1 0 ellipseannulus,annuli 1 } array set marker [array get pmarker] # Mask prefs global mask global pmask array set pmask { view 1 color red } array set mask [array get pmask] # MinMax prefs global minmax global pminmax array set pminmax { mode auto sample 25 } array set minmax [array get pminmax] # NRES prefs global nres set nres(server) {simbad-sao} # Panner prefs global panner array set panner { compass,wcs,system wcs compass,image 1 compass,wcs,sky fk5 compass,wcs 1 size 128 } # PanZoom prefs global panzoom global ppanzoom set panzoom(mode) click array set ppanzoom { preserve 0 } array set panzoom [array get ppanzoom] # Postscript prefs global ps global pps array set pps { scale scaled orient portrait height 11 size letter resolution 150 dest printer level 2 width 8.5 filename ds9.ps color2 color cmd lp color rgb } array set ps [array get pps] # Scale prefs global scale global pscale array set pscale { min 1 preserve 0 xaxis full mode minmax datasec 1 max 100 yaxis log type linear scope local } array set scale [array get pscale] # Smooth prefs global smooth global psmooth array set psmooth { radius 3 function gaussian view 0 } array set smooth [array get psmooth] # Tile prefs global tile global ptile array set ptile { mode grid } array set tile [array get ptile] # View prefs global view global pview array set pview { info,wcss 0 info,wcsc 0 info,wcst 0 info,wcsd 0 graph,horz 0 info,wcsu 0 info,wcse 0 magnifier 1 info,lowhigh 0 info,wcsf 0 info,frame 1 info,image 1 info,wcsv 0 colorbar 1 info 1 info,wcsg 0 info,wcsw 0 info,wcs 1 info,wcsh 0 info,wcsx 0 info,physical 1 info,wcsi 0 info,wcsy 0 info,object 1 buttons 1 info,wcsj 0 info,wcsz 0 info,wcsk 0 info,filename 1 info,wcsl 0 info,amplifier 0 info,minmax 0 info,wcsm 0 info,detector 0 info,wcsn 0 panner 1 info,wcso 0 info,wcsp 0 layout horizontal info,wcsa 0 info,wcsq 0 graph,vert 0 info,wcsb 0 info,wcsr 0 } array set view [array get pview] # WCS prefs global wcs global pwcs array set pwcs { skyformat sexagesimal align,system wcs system wcs align,sky fk5 sky fk5 align 0 } array set wcs [array get pwcs] # VO prefs global vo set vo(server) http://cxc.harvard.edu/chandraed/list.txt set vo(hv) 1 set vo(method) xpa # ZScale prefs global zscale global pzscale array set pzscale { line 120 contrast .25 sample 600 } array set zscale [array get pzscale] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/���������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013027� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.sym��������������������������������������������������������������������������0000644�0001750�0001750�00000000207�12131336426�014273� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������condition shape color text size size2 units angle --------- ----- ----- ---- ---- ----- ----- ----- diamond point yellow physical �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.cat��������������������������������������������������������������������������0000644�0001750�0001750�00000030354�12131336426�014240� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # VizieR Astronomical Server: vizier.cfa.harvard.edu 2005-03-18T18:31:38 # Explanations and Statistics of UCDs: See LINK below # In case of problem, please report to: question@simbad.u-strasbg.fr # (link) # #Coosys J2000: eq_FK5 2000 #INFO Ref=Vxml14769 #INFO Target=202.483367+47.234489,bm=22.016000/22.019 #RESOURCE=16010735 #Name: J/ApJ/601/735 #Title: M51 luminous X-ray sources (Terashima+, 2004) #Table J_ApJ_601_735_sources: #Name: J/ApJ/601/735/sources #Title: Sources detected {\em(tables 1--3 of paper)} #Column _RAJ2000 (F9.5) Right ascension (FK5) Equinox=J2000. (computed by VizieR, not part of the original data) [ucd=POS_EQ_RA_MAIN] #Column _DEJ2000 (F9.5) Declination (FK5) Equinox=J2000. (computed by VizieR, not part of the original data) [ucd=POS_EQ_DEC_MAIN] #Column recno (I8) Record number within the original table (starting from 1) (link) [ucd=RECORD] #Column [TW2004] (I2) Sequential number (1) (link) [ucd=ID_NUMBER] #Column RAJ2000 (A11) Right ascension (J2000.0) [ucd=POS_EQ_RA_MAIN] #Column DEJ2000 (A11) Declination (J2000.0) [ucd=POS_EQ_DEC_MAIN] #Column 0.5-8keV (F6.1) 0.5-8keV band counts in observations 1 & 2 [ucd=PHOT_COUNTS_X] #Column e_0.5-8keV (F4.1) rms uncertainty on 0.5-8keV [ucd=ERROR] #Column l_0.5-2keV (A1) Limit flag on 0.5-2keV [ucd=CODE_LIMIT] #Column 0.5-2keV (F6.1) 0.5-2keV band counts in observations 1 & 2 [ucd=PHOT_COUNTS_X] #Column e_0.5-2keV (F4.1) ? rms uncertainty on 0.5-2keV [ucd=ERROR] #Column l_2-8keV (A1) Limit flag on 2-8keV [ucd=CODE_LIMIT] #Column 2-8keV (F6.1) 2-8keV band counts in observations 1 & 2 [ucd=PHOT_COUNTS_X] #Column e_2-8keV (F4.1) ? rms uncertainty on 2-8keV [ucd=ERROR] _RAJ2000 _DEJ2000 recno [TW2004] RAJ2000 DEJ2000 0.5-8keV e_0.5-8keV l_0.5-2keV 0.5-2keV e_0.5-2keV l_2-8keV 2-8keV e_2-8keV -------- -------- ----- -------- ------- ------- -------- ---------- ---------- -------- ---------- -------- ------ -------- 202.39871 +47.20031 1 1 13 29 35.69 +47 12 01.1 15.2 5.4 < 9.4 11.6 4.7 202.40229 +47.18483 2 2 13 29 36.55 +47 11 05.4 8.8 4.6 6.7 2.6 < 7.9 202.41217 +47.22331 3 3 13 29 38.92 +47 13 23.9 54.6 8.8 37.5 7.3 17.4 4.2 202.41242 +47.18433 4 4 13 29 38.98 +47 11 03.6 26.3 5.2 16.6 4.1 9.7 3.2 202.41438 +47.21214 5 5 13 29 39.45 +47 12 43.7 427.0 21.0 308.0 18.0 120.0 11.0 202.41650 +47.21025 6 6 13 29 39.96 +47 12 36.9 276.0 17.0 266.0 16.0 10.4 4.4 202.42354 +47.18119 7 7 13 29 41.65 +47 10 52.3 20.4 4.6 16.6 4.1 < 8.9 202.42712 +47.17853 8 8 13 29 42.51 +47 10 42.7 16.7 5.3 13.1 4.8 < 9.1 202.43042 +47.19297 9 9 13 29 43.30 +47 11 34.7 365.0 19.0 364.0 19.0 < 5.8 202.43354 +47.19900 10 10 13 29 44.05 +47 11 56.4 18.8 5.7 17.3 5.4 < 5.8 202.43412 +47.17231 11 11 13 29 44.19 +47 10 20.3 8.1 4.4 8.7 4.4 < 4.3 202.43562 +47.23242 12 12 13 29 44.55 +47 13 56.7 72.8 8.6 55.4 8.6 18.6 4.4 202.43696 +47.19128 13 13 13 29 44.87 +47 11 28.6 11.8 4.8 7.3 4.1 < 10.3 202.43962 +47.19750 14 14 13 29 45.51 +47 11 51.0 30.0 5.6 14.3 3.9 15.7 4.0 202.43967 +47.19033 15 15 13 29 45.52 +47 11 25.2 11.3 3.5 8.5 3.0 < 7.4 202.44142 +47.18214 16 16 13 29 45.94 +47 10 55.7 9.0 3.2 7.5 2.8 < 5.8 202.44213 +47.17842 17 17 13 29 46.11 +47 10 42.3 28.6 5.5 25.0 5.1 < 8.9 202.44592 +47.18453 18 18 13 29 47.02 +47 11 04.3 11.8 4.8 12.3 4.8 < 4.4 202.44796 +47.21703 19 19 13 29 47.51 +47 13 01.3 17.8 4.4 10.5 3.3 7.5 4.0 202.45329 +47.18928 20 20 13 29 48.79 +47 11 21.4 67.8 9.4 50.3 8.3 17.7 4.2 202.45429 +47.18147 21 21 13 29 49.03 +47 10 53.3 143.0 12.0 105.0 10.0 36.5 6.1 202.45479 +47.21583 22 22 13 29 49.15 +47 12 57.0 14.0 3.9 < 3.9 13.7 3.7 202.45858 +47.23886 23 23 13 29 50.06 +47 14 19.9 17.7 5.7 16.0 5.3 < 6.5 202.45867 +47.19425 24 24 13 29 50.08 +47 11 39.3 32.3 6.2 31.8 6.1 < 4.2 202.45979 +47.22297 25 25 13 29 50.35 +47 13 22.7 22.8 6.1 22.3 6.0 < 4.4 202.46113 +47.19864 26 26 13 29 50.67 +47 11 55.1 377.0 20.0 52.2 9.0 325.0 18.0 202.46175 +47.17536 27 27 13 29 50.82 +47 10 31.3 135.0 13.0 117.0 11.0 17.5 5.3 202.46400 +47.17567 28 28 13 29 51.36 +47 10 32.4 238.0 16.0 155.0 13.0 83.0 10.0 202.46575 +47.19778 29 29 13 29 51.78 +47 11 52.0 36.3 8.1 36.2 8.0 < 4.2 202.46696 +47.19078 30 30 13 29 52.07 +47 11 26.8 24.3 7.1 25.2 7.1 < 4.2 202.46717 +47.20356 31 31 13 29 52.12 +47 12 12.8 22.1 5.3 21.7 5.2 < 5.7 202.46762 +47.19156 32 32 13 29 52.23 +47 11 29.6 25.3 7.2 24.2 7.1 < 5.5 202.46971 +47.18089 33 33 13 29 52.73 +47 10 51.2 34.0 6.0 15.8 4.1 18.5 5.4 202.46971 +47.18928 34 34 13 29 52.73 +47 11 21.4 16.1 4.6 15.0 4.5 < 4.2 202.46979 +47.17850 35 35 13 29 52.75 +47 10 42.6 11.8 4.8 < 15.9 < 8.9 202.46996 +47.21247 36 36 13 29 52.79 +47 12 44.9 42.8 7.8 28.3 6.5 14.5 5.0 202.47213 +47.17842 37 37 13 29 53.31 +47 10 42.3 581.0 24.0 429.0 21.0 151.0 12.0 202.47304 +47.19247 38 38 13 29 53.53 +47 11 32.9 27.3 7.4 19.2 6.6 8.1 4.1 202.47308 +47.19067 39 39 13 29 53.54 +47 11 26.4 36.2 6.6 32.1 6.2 < 11.4 202.47342 +47.22300 40 40 13 29 53.62 +47 13 22.8 12.0 3.6 12.3 3.6 < 4.4 202.47383 +47.24331 41 41 13 29 53.72 +47 14 35.9 629.0 26.0 445.0 22.0 184.0 15.0 202.47412 +47.24214 42 42 13 29 53.79 +47 14 31.7 276.0 18.0 217.0 16.0 58.9 8.9 202.47471 +47.17536 43 43 13 29 53.93 +47 10 31.3 12.7 3.7 13.3 5.0 < 4.4 202.47500 +47.15647 44 44 13 29 54.00 +47 09 23.3 9.6 4.4 8.2 4.1 < 5.8 202.47567 +47.19172 45 45 13 29 54.16 +47 11 30.2 18.3 6.6 16.2 6.4 < 6.9 202.47575 +47.19361 46 46 13 29 54.18 +47 11 37.0 111.0 12.0 68.0 8.9 43.1 7.7 202.47600 +47.21672 47 47 13 29 54.24 +47 13 00.2 47.2 7.0 15.0 4.0 32.5 6.8 202.47654 +47.18931 48 48 13 29 54.37 +47 11 21.5 26.8 5.7 27.5 5.7 < 4.2 202.47721 +47.15600 49 49 13 29 54.53 +47 09 21.6 69.2 8.4 45.7 6.9 23.6 4.9 202.47900 +47.15622 50 50 13 29 54.96 +47 09 22.4 47.6 7.0 38.1 6.2 9.5 4.3 202.47913 +47.18394 51 51 13 29 54.99 +47 11 02.2 12.5 3.7 10.8 3.5 < 5.8 202.47971 +47.17839 52 52 13 29 55.13 +47 10 42.2 29.8 6.7 29.3 6.6 < 4.4 202.48017 +47.17950 53 53 13 29 55.24 +47 10 46.2 8.1 3.0 8.3 3.0 < 4.4 202.48104 +47.19542 54 54 13 29 55.45 +47 11 43.5 49.6 7.5 45.4 7.2 < 10.0 202.48112 +47.23389 55 55 13 29 55.47 +47 14 02.0 16.6 4.2 16.2 5.5 < 4.1 202.48179 +47.15519 56 56 13 29 55.63 +47 09 18.7 7.6 4.1 < 11.4 < 7.4 202.48192 +47.15294 57 57 13 29 55.66 +47 09 10.6 12.8 5.2 12.4 5.0 < 5.0 202.48208 +47.17878 58 58 13 29 55.70 +47 10 43.6 14.8 5.2 14.3 5.1 < 4.4 202.48275 +47.19569 59 59 13 29 55.86 +47 11 44.5 42.5 6.9 41.5 6.9 < 4.2 202.48358 +47.23081 60 60 13 29 56.06 +47 13 50.9 14.8 4.0 15.1 4.0 < 4.2 202.48396 +47.21017 61 61 13 29 56.15 +47 12 36.6 18.8 5.7 18.3 5.6 < 4.4 202.48946 +47.17697 62 62 13 29 57.47 +47 10 37.1 18.8 5.7 18.9 4.5 < 4.4 202.48988 +47.18008 63 63 13 29 57.57 +47 10 48.3 400.0 20.0 318.0 18.0 81.0 10.0 202.49008 +47.20172 64 64 13 29 57.62 +47 12 06.2 95.0 11.0 73.9 8.7 20.6 4.6 202.49317 +47.22236 65 65 13 29 58.36 +47 13 20.5 76.1 8.8 53.6 7.4 22.6 4.8 202.49467 +47.17497 66 66 13 29 58.72 +47 10 29.9 53.8 7.4 27.2 5.3 26.5 5.2 202.49592 +47.24283 67 67 13 29 59.02 +47 14 34.2 12.5 5.2 < 15.0 < 11.7 202.50233 +47.19333 68 68 13 30 00.56 +47 11 36.0 13.2 5.1 < 20.7 < 5.7 202.50425 +47.22889 69 69 13 30 01.02 +47 13 44.0 553.0 24.0 374.0 20.0 180.0 13.0 202.50467 +47.22581 70 70 13 30 01.12 +47 13 32.9 12.4 5.1 12.2 3.7 < 4.4 202.50529 +47.21228 71 71 13 30 01.27 +47 12 44.2 15.2 4.1 < 14.1 < 11.8 202.50783 +47.14547 72 72 13 30 01.88 +47 08 43.7 10.4 4.7 11.6 4.7 < 4.0 202.50875 +47.21058 73 73 13 30 02.10 +47 12 38.1 17.6 4.4 15.0 4.0 < 7.4 202.50887 +47.15017 74 74 13 30 02.13 +47 09 00.6 40.9 6.5 29.6 6.6 10.6 4.6 202.51708 +47.16764 75 75 13 30 04.10 +47 10 03.5 24.2 6.5 24.7 6.4 < 3.9 202.51800 +47.22244 76 76 13 30 04.32 +47 13 20.8 120.0 11.0 78.2 9.0 41.5 7.6 202.51862 +47.17539 77 77 13 30 04.47 +47 10 31.4 31.9 5.7 30.3 5.6 < 5.9 202.51942 +47.23806 78 78 13 30 04.66 +47 14 17.0 64.1 9.4 48.0 7.1 15.9 5.2 202.52425 +47.17553 79 79 13 30 05.82 +47 10 31.9 13.1 3.7 13.4 3.7 < 4.1 202.52517 +47.23444 80 80 13 30 06.04 +47 14 04.0 24.3 6.5 23.7 6.3 < 5.2 202.52613 +47.17122 81 81 13 30 06.27 +47 10 16.4 9.6 4.9 < 11.7 < 10.9 202.53150 +47.18497 82 82 13 30 07.56 +47 11 05.9 1680.0 42.0 1367.0 38.0 312.0 18.0 202.53704 +47.20514 83 83 13 30 08.89 +47 12 18.5 29.0 5.6 24.8 5.1 < 9.9 202.54596 +47.17797 84 84 13 30 11.03 +47 10 40.7 89.3 9.5 65.1 9.2 24.6 6.2 202.47000 +47.27903 85 1 13 29 52.80 +47 16 44.5 157.0 13.0 103.0 11.0 54.7 8.7 202.48138 +47.26539 86 2 13 29 55.53 +47 15 55.4 22.2 5.3 < 8.4 20.8 6.0 202.48775 +47.26569 87 3 13 29 57.06 +47 15 56.5 25.5 8.8 19.6 7.9 < 13.4 202.48950 +47.27003 88 4 13 29 57.48 +47 16 12.1 256.0 17.0 178.0 16.0 74.1 9.9 202.49325 +47.26317 89 5 13 29 58.38 +47 15 47.4 124.0 14.0 120.0 14.0 < 9.3 202.49475 +47.27375 90 6 13 29 58.74 +47 16 25.5 94.0 13.0 88.0 12.0 < 13.6 202.49804 +47.26625 91 7 13 29 59.53 +47 15 58.5 522.0 25.0 390.0 22.0 132.0 13.0 202.49912 +47.26133 92 8 13 29 59.79 +47 15 40.8 89.0 13.0 66.0 11.0 22.1 6.2 202.50258 +47.25847 93 9 13 30 00.62 +47 15 30.5 19.5 5.2 18.8 5.0 < 6.7 202.50842 +47.25175 94 10 13 30 02.02 +47 15 06.3 96.0 11.0 68.0 9.4 28.1 6.6 202.51567 +47.26978 95 11 13 30 03.76 +47 16 11.2 85.0 11.0 75.0 10.0 9.9 4.8 202.52512 +47.26178 96 12 13 30 06.03 +47 15 42.4 547.0 25.0 386.0 21.0 161.0 14.0 202.36096 +47.20958 97 1 13 29 26.63 +47 12 34.5 9.7 4.8 < 14.9 < 7.3 202.38887 +47.24456 98 2 13 29 33.33 +47 14 40.4 18.7 5.8 10.3 4.4 < 16.3 202.40321 +47.24681 99 3 13 29 36.77 +47 14 48.5 22.0 6.3 20.7 5.9 < 6.7 202.40442 +47.22500 100 4 13 29 37.06 +47 13 30.0 33.6 7.2 20.2 5.8 13.5 5.0 202.40838 +47.27039 101 5 13 29 38.01 +47 16 13.4 44.7 8.0 39.9 7.5 < 11.1 202.41096 +47.22672 102 6 13 29 38.63 +47 13 36.2 92.0 11.0 82.0 9.1 < 17.8 202.42575 +47.24669 103 7 13 29 42.18 +47 14 48.1 28.3 6.6 16.2 5.2 12.1 4.7 202.43067 +47.25703 104 8 13 29 43.36 +47 15 25.3 133.0 13.0 110.0 12.0 22.8 6.2 202.43262 +47.24294 105 9 13 29 43.83 +47 14 34.6 7.5 2.8 < 11.1 < 7.9 202.48437 +47.24767 106 10 13 29 56.25 +47 14 51.6 161.0 14.0 119.0 12.0 41.8 7.7 202.52696 +47.14286 107 11 13 30 06.47 +47 08 34.3 265.0 16.0 212.0 16.0 53.8 8.5 202.56325 +47.26083 108 12 13 30 15.18 +47 15 39.0 20.7 6.2 10.3 4.6 < 19.5 202.56558 +47.25458 109 13 13 30 15.74 +47 15 16.5 139.0 12.0 118.0 12.0 19.8 4.8 202.58754 +47.23153 110 14 13 30 21.01 +47 13 53.5 32.9 7.3 29.0 5.6 < 10.1 202.60462 +47.22033 111 15 13 30 25.11 +47 13 13.2 26.3 6.4 18.0 4.4 < 16.8 202.61854 +47.25564 112 16 13 30 28.45 +47 15 20.3 17.7 5.9 14.2 5.2 < 9.3 202.62225 +47.24117 113 17 13 30 29.34 +47 14 28.2 19.1 6.0 13.9 3.9 < 12.1 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.lev��������������������������������������������������������������������������0000644�0001750�0001750�00000000043�12131336426�014247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-1 15.7878 32.5755 49.3633 66.151 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.sao��������������������������������������������������������������������������0000644�0001750�0001750�00000000126�12131336426�014245� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# SAOimage color table PSEUDOCOLOR RED: (0,0)(0,0) GREEN: (0,0)(0,0) BLUE: (0,0)(1,1) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/hello.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000000041�12131336426�014645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������puts stdout "Hello Again, World" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.flt��������������������������������������������������������������������������0000644�0001750�0001750�00000000011�12131336426�014241� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$Jmag>15 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/image.wcs������������������������������������������������������������������������0000644�0001750�0001750�00000001440�12131336426�014642� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CRVAL1 = 47.2097404068078 CRVAL2 = 202.481101229926 CRPIX1 = 198.5 CRPIX2 = 607.75 CD1_1 = -3.7266660000000E-4 CD1_2 = 4.05254400000000E-4 CD2_1 = -4.0525440000000E-4 CD2_2 = -3.7266660000000E-4 CTYPE1 = 'DEC--TAN' CTYPE2 = 'RA---TAN' ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/pds9.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000000037�12131336426�014426� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������global pds9 set pds9(backup) 0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.con��������������������������������������������������������������������������0000644�0001750�0001750�00001224076�12131336426�014257� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 2.02472783e+02 4.72188119e+01 2.02472824e+02 4.72187818e+01 2.02472575e+02 4.72186405e+01 2.02472347e+02 4.72184836e+01 2.02472097e+02 4.72183423e+01 2.02471829e+02 4.72182156e+01 2.02473738e+02 4.72194083e+01 2.02473778e+02 4.72193788e+01 2.02473529e+02 4.72192368e+01 2.02473260e+02 4.72191101e+01 2.02478034e+02 4.72220917e+01 2.02478073e+02 4.72220622e+01 2.02477858e+02 4.72218963e+01 2.02477556e+02 4.72217935e+01 2.02479943e+02 4.72232842e+01 2.02479972e+02 4.72232626e+01 2.02479744e+02 4.72231057e+01 2.02479466e+02 4.72229861e+01 2.02483647e+02 4.72238023e+01 2.02483354e+02 4.72239185e+01 2.02483163e+02 4.72240987e+01 2.02482988e+02 4.72242886e+01 2.02503891e+02 4.71820029e+01 2.02503726e+02 4.71819545e+01 2.02503737e+02 4.71819071e+01 2.02503782e+02 4.71819129e+01 2.02503891e+02 4.71820029e+01 2.02492909e+02 4.71754413e+01 2.02492723e+02 4.71754466e+01 2.02492662e+02 4.71752867e+01 2.02492862e+02 4.71753443e+01 2.02492909e+02 4.71754413e+01 2.02512631e+02 4.71880599e+01 2.02512296e+02 4.71879841e+01 2.02512272e+02 4.71878359e+01 2.02512514e+02 4.71878229e+01 2.02512631e+02 4.71880599e+01 2.02498845e+02 4.71794494e+01 2.02498779e+02 4.71794293e+01 2.02498769e+02 4.71794020e+01 2.02498806e+02 4.71794092e+01 2.02498845e+02 4.71794494e+01 2.02489697e+02 4.71737327e+01 2.02489305e+02 4.71737438e+01 2.02489295e+02 4.71734816e+01 2.02489680e+02 4.71734667e+01 2.02489697e+02 4.71737327e+01 2.02481803e+02 4.71687986e+01 2.02481428e+02 4.71688308e+01 2.02481319e+02 4.71687952e+01 2.02480959e+02 4.71688691e+01 2.02480888e+02 4.71689047e+01 2.02480716e+02 4.71690165e+01 2.02480350e+02 4.71689772e+01 2.02480111e+02 4.71688284e+01 2.02479870e+02 4.71686811e+01 2.02479858e+02 4.71684801e+01 2.02480029e+02 4.71682880e+01 2.02480245e+02 4.71681240e+01 2.02480584e+02 4.71680366e+01 2.02480698e+02 4.71680692e+01 2.02480984e+02 4.71681834e+01 2.02481179e+02 4.71683646e+01 2.02481487e+02 4.71684622e+01 2.02481777e+02 4.71685728e+01 2.02481803e+02 4.71687986e+01 2.02520105e+02 4.71930256e+01 2.02520013e+02 4.71930172e+01 2.02520005e+02 4.71929631e+01 2.02520115e+02 4.71929418e+01 2.02520105e+02 4.71930256e+01 2.02498354e+02 4.71794415e+01 2.02498314e+02 4.71794481e+01 2.02498320e+02 4.71794204e+01 2.02498360e+02 4.71794137e+01 2.02498354e+02 4.71794415e+01 2.02497170e+02 4.71787016e+01 2.02497285e+02 4.71789073e+01 2.02497295e+02 4.71790793e+01 2.02497089e+02 4.71792494e+01 2.02496856e+02 4.71792246e+01 2.02496583e+02 4.71792324e+01 2.02496318e+02 4.71793659e+01 2.02496417e+02 4.71795492e+01 2.02496428e+02 4.71797339e+01 2.02496352e+02 4.71799222e+01 2.02496331e+02 4.71799724e+01 2.02496348e+02 4.71802506e+01 2.02496751e+02 4.71802785e+01 2.02496891e+02 4.71805003e+01 2.02496947e+02 4.71806562e+01 2.02496954e+02 4.71807788e+01 2.02497229e+02 4.71808323e+01 2.02497302e+02 4.71808467e+01 2.02497305e+02 4.71808797e+01 2.02497387e+02 4.71811096e+01 2.02497731e+02 4.71811462e+01 2.02497772e+02 4.71811505e+01 2.02498041e+02 4.71812766e+01 2.02498402e+02 4.71812663e+01 2.02498476e+02 4.71812807e+01 2.02498780e+02 4.71813814e+01 2.02499063e+02 4.71814977e+01 2.02499026e+02 4.71816562e+01 2.02498972e+02 4.71818899e+01 2.02499231e+02 4.71820238e+01 2.02499473e+02 4.71821708e+01 2.02499451e+02 4.71822210e+01 2.02499469e+02 4.71824992e+01 2.02499878e+02 4.71824874e+01 2.02499927e+02 4.71824855e+01 2.02499929e+02 4.71825191e+01 2.02499735e+02 4.71826970e+01 2.02499885e+02 4.71828424e+01 2.02499988e+02 4.71830912e+01 2.02500349e+02 4.71830808e+01 2.02500446e+02 4.71830781e+01 2.02500727e+02 4.71831960e+01 2.02500783e+02 4.71833518e+01 2.02500834e+02 4.71834425e+01 2.02501029e+02 4.71836234e+01 2.02501041e+02 4.71838120e+01 2.02501077e+02 4.71839133e+01 2.02501229e+02 4.71839294e+01 2.02501506e+02 4.71839215e+01 2.02501780e+02 4.71839750e+01 2.02501878e+02 4.71839722e+01 2.02502093e+02 4.71841384e+01 2.02502095e+02 4.71841715e+01 2.02502046e+02 4.71841728e+01 2.02501637e+02 4.71841846e+01 2.02501654e+02 4.71844627e+01 2.02501679e+02 4.71845097e+01 2.02501802e+02 4.71846791e+01 2.02501971e+02 4.71846923e+01 2.02502045e+02 4.71844992e+01 2.02502064e+02 4.71844510e+01 2.02502112e+02 4.71844496e+01 2.02502521e+02 4.71844379e+01 2.02502593e+02 4.71844193e+01 2.02502918e+02 4.71845044e+01 2.02502930e+02 4.71846930e+01 2.02502711e+02 4.71848552e+01 2.02502632e+02 4.71850416e+01 2.02502636e+02 4.71851076e+01 2.02502562e+02 4.71850932e+01 2.02502153e+02 4.71851050e+01 2.02502170e+02 4.71853831e+01 2.02502197e+02 4.71854319e+01 2.02501978e+02 4.71855941e+01 2.02501993e+02 4.71858392e+01 2.02502229e+02 4.71859903e+01 2.02502596e+02 4.71859798e+01 2.02502730e+02 4.71857643e+01 2.02502948e+02 4.71857839e+01 2.02503255e+02 4.71858826e+01 2.02503536e+02 4.71860003e+01 2.02503528e+02 4.71862631e+01 2.02503143e+02 4.71862905e+01 2.02503026e+02 4.71862489e+01 2.02503063e+02 4.71863501e+01 2.02503214e+02 4.71863663e+01 2.02503448e+02 4.71863911e+01 2.02503719e+02 4.71865159e+01 2.02503774e+02 4.71867155e+01 2.02503810e+02 4.71867737e+01 2.02504024e+02 4.71868720e+01 2.02504121e+02 4.71868692e+01 2.02504360e+02 4.71870182e+01 2.02504598e+02 4.71871673e+01 2.02504959e+02 4.71871569e+01 2.02505033e+02 4.71871713e+01 2.02505035e+02 4.71872044e+01 2.02505164e+02 4.71874002e+01 2.02505216e+02 4.71876163e+01 2.02505095e+02 4.71877765e+01 2.02505474e+02 4.71878215e+01 2.02505653e+02 4.71880149e+01 2.02505664e+02 4.71881953e+01 2.02505448e+02 4.71883595e+01 2.02505459e+02 4.71884839e+01 2.02505697e+02 4.71886330e+01 2.02505826e+02 4.71888630e+01 2.02506235e+02 4.71888513e+01 2.02506284e+02 4.71888499e+01 2.02506286e+02 4.71888829e+01 2.02506092e+02 4.71890609e+01 2.02506194e+02 4.71892422e+01 2.02506374e+02 4.71892370e+01 2.02506652e+02 4.71892290e+01 2.02506615e+02 4.71893875e+01 2.02506561e+02 4.71896213e+01 2.02506899e+02 4.71895651e+01 2.02507084e+02 4.71895598e+01 2.02507141e+02 4.71897156e+01 2.02506921e+02 4.71898778e+01 2.02506608e+02 4.71899812e+01 2.02506738e+02 4.71901412e+01 2.02506862e+02 4.71903754e+01 2.02507100e+02 4.71905244e+01 2.02507339e+02 4.71906734e+01 2.02507318e+02 4.71907236e+01 2.02507335e+02 4.71910018e+01 2.02507574e+02 4.71911508e+01 2.02507601e+02 4.71911996e+01 2.02507731e+02 4.71913596e+01 2.02507970e+02 4.71915086e+01 2.02508086e+02 4.71915021e+01 2.02508432e+02 4.71914922e+01 2.02508698e+02 4.71916215e+01 2.02508701e+02 4.71918868e+01 2.02508298e+02 4.71919169e+01 2.02508098e+02 4.71918088e+01 2.02508113e+02 4.71920539e+01 2.02508117e+02 4.71921200e+01 2.02508132e+02 4.71923651e+01 2.02508486e+02 4.71924290e+01 2.02508609e+02 4.71926631e+01 2.02508848e+02 4.71928121e+01 2.02509056e+02 4.71929841e+01 2.02509325e+02 4.71931102e+01 2.02509304e+02 4.71931604e+01 2.02509232e+02 4.71931790e+01 2.02508872e+02 4.71931893e+01 2.02508652e+02 4.71933515e+01 2.02508780e+02 4.71935133e+01 2.02508750e+02 4.71937113e+01 2.02508462e+02 4.71937487e+01 2.02508339e+02 4.71937541e+01 2.02508088e+02 4.71938966e+01 2.02508125e+02 4.71939979e+01 2.02508370e+02 4.71940727e+01 2.02508444e+02 4.71938196e+01 2.02508788e+02 4.71938334e+01 2.02508902e+02 4.71940740e+01 2.02508904e+02 4.71941070e+01 2.02508832e+02 4.71941256e+01 2.02508472e+02 4.71941360e+01 2.02508378e+02 4.71943764e+01 2.02508354e+02 4.71944794e+01 2.02508366e+02 4.71946680e+01 2.02508088e+02 4.71946759e+01 2.02507908e+02 4.71946811e+01 2.02507967e+02 4.71947654e+01 2.02508189e+02 4.71949267e+01 2.02508204e+02 4.71951652e+01 2.02508202e+02 4.71952426e+01 2.02508354e+02 4.71952587e+01 2.02508552e+02 4.71953097e+01 2.02508749e+02 4.71954894e+01 2.02508788e+02 4.71955296e+01 2.02508933e+02 4.71956790e+01 2.02509038e+02 4.71956861e+01 2.02509376e+02 4.71956765e+01 2.02509542e+02 4.71958795e+01 2.02509796e+02 4.71960170e+01 2.02509831e+02 4.71961813e+01 2.02509832e+02 4.71963155e+01 2.02510144e+02 4.71963762e+01 2.02510371e+02 4.71962194e+01 2.02510435e+02 4.71961955e+01 2.02510760e+02 4.71962806e+01 2.02510723e+02 4.71964391e+01 2.02510480e+02 4.71965862e+01 2.02510322e+02 4.71966040e+01 2.02510107e+02 4.71966525e+01 2.02509827e+02 4.71967766e+01 2.02509773e+02 4.71970103e+01 2.02509762e+02 4.71970354e+01 2.02509870e+02 4.71972643e+01 2.02510061e+02 4.71974484e+01 2.02510066e+02 4.71975238e+01 2.02509942e+02 4.71977456e+01 2.02509929e+02 4.71978713e+01 2.02510070e+02 4.71980923e+01 2.02510316e+02 4.71982365e+01 2.02510357e+02 4.71983041e+01 2.02510328e+02 4.71985530e+01 2.02510630e+02 4.71984746e+01 2.02510796e+02 4.71982793e+01 2.02511184e+02 4.71982220e+01 2.02511247e+02 4.71981983e+01 2.02511486e+02 4.71983473e+01 2.02511490e+02 4.71984134e+01 2.02511635e+02 4.71985627e+01 2.02511772e+02 4.71985894e+01 2.02511983e+02 4.71986306e+01 2.02512013e+02 4.71987399e+01 2.02512025e+02 4.71989254e+01 2.02512308e+02 4.71990416e+01 2.02512480e+02 4.71992398e+01 2.02512558e+02 4.71993792e+01 2.02512480e+02 4.71995657e+01 2.02512484e+02 4.71996317e+01 2.02512390e+02 4.71998721e+01 2.02512280e+02 4.72000390e+01 2.02512258e+02 4.72000892e+01 2.02512276e+02 4.72003674e+01 2.02512685e+02 4.72003556e+01 2.02512757e+02 4.72003370e+01 2.02512761e+02 4.72004030e+01 2.02512776e+02 4.72006482e+01 2.02512780e+02 4.72007142e+01 2.02512796e+02 4.72009593e+01 2.02513121e+02 4.72010444e+01 2.02513016e+02 4.72011606e+01 2.02512797e+02 4.72013229e+01 2.02512592e+02 4.72014940e+01 2.02512335e+02 4.72016323e+01 2.02512179e+02 4.72018339e+01 2.02511967e+02 4.72020009e+01 2.02511677e+02 4.72021189e+01 2.02511625e+02 4.72021501e+01 2.02511265e+02 4.72021605e+01 2.02511198e+02 4.72021403e+01 2.02510773e+02 4.72021525e+01 2.02510560e+02 4.72023190e+01 2.02510689e+02 4.72025170e+01 2.02510652e+02 4.72026755e+01 2.02510697e+02 4.72028368e+01 2.02510634e+02 4.72029631e+01 2.02510392e+02 4.72031112e+01 2.02510267e+02 4.72031542e+01 2.02510029e+02 4.72030052e+01 2.02509973e+02 4.72028493e+01 2.02509904e+02 4.72027719e+01 2.02509696e+02 4.72026002e+01 2.02509652e+02 4.72023500e+01 2.02509793e+02 4.72022027e+01 2.02509578e+02 4.72020365e+01 2.02509339e+02 4.72018875e+01 2.02509312e+02 4.72018387e+01 2.02509167e+02 4.72016893e+01 2.02508929e+02 4.72015403e+01 2.02508733e+02 4.72013594e+01 2.02508721e+02 4.72011708e+01 2.02508878e+02 4.72009695e+01 2.02509134e+02 4.72008304e+01 2.02509207e+02 4.72006834e+01 2.02509011e+02 4.72007533e+01 2.02508673e+02 4.72007531e+01 2.02508467e+02 4.72005795e+01 2.02508334e+02 4.72003522e+01 2.02508325e+02 4.72003250e+01 2.02508230e+02 4.72001042e+01 2.02508173e+02 4.71999314e+01 2.02508265e+02 4.71997528e+01 2.02507919e+02 4.71996833e+01 2.02507640e+02 4.71995984e+01 2.02507766e+02 4.71997960e+01 2.02507919e+02 4.72000083e+01 2.02507898e+02 4.72000586e+01 2.02507826e+02 4.72000772e+01 2.02507606e+02 4.72001755e+01 2.02507239e+02 4.72001861e+01 2.02507101e+02 4.72001593e+01 2.02507163e+02 4.72002418e+01 2.02507180e+02 4.72005074e+01 2.02506789e+02 4.72005186e+01 2.02506691e+02 4.72002656e+01 2.02506469e+02 4.72003625e+01 2.02506108e+02 4.72003709e+01 2.02506019e+02 4.72001115e+01 2.02506017e+02 4.72000804e+01 2.02505975e+02 4.71998185e+01 2.02505996e+02 4.71997683e+01 2.02505979e+02 4.71994902e+01 2.02505740e+02 4.71993412e+01 2.02505428e+02 4.71992467e+01 2.02505419e+02 4.71991090e+01 2.02505490e+02 4.71988752e+01 2.02505492e+02 4.71988550e+01 2.02505585e+02 4.71986140e+01 2.02505577e+02 4.71984858e+01 2.02505565e+02 4.71983029e+01 2.02505780e+02 4.71981380e+01 2.02505773e+02 4.71980154e+01 2.02505809e+02 4.71978569e+01 2.02505863e+02 4.71976232e+01 2.02505624e+02 4.71974742e+01 2.02505320e+02 4.71973735e+01 2.02505076e+02 4.71973991e+01 2.02504860e+02 4.71973881e+01 2.02504683e+02 4.71971937e+01 2.02504280e+02 4.71972010e+01 2.02504180e+02 4.71974377e+01 2.02504022e+02 4.71976385e+01 2.02503626e+02 4.71976499e+01 2.02503531e+02 4.71973949e+01 2.02503526e+02 4.71973288e+01 2.02503425e+02 4.71971476e+01 2.02503218e+02 4.71969749e+01 2.02503209e+02 4.71968317e+01 2.02503420e+02 4.71968256e+01 2.02503752e+02 4.71968713e+01 2.02503824e+02 4.71968527e+01 2.02504062e+02 4.71970018e+01 2.02504423e+02 4.71969914e+01 2.02504408e+02 4.71967463e+01 2.02504404e+02 4.71966803e+01 2.02504273e+02 4.71965203e+01 2.02504108e+02 4.71963172e+01 2.02504100e+02 4.71961915e+01 2.02504036e+02 4.71960447e+01 2.02503788e+02 4.71959026e+01 2.02503656e+02 4.71959145e+01 2.02503704e+02 4.71959645e+01 2.02503690e+02 4.71962347e+01 2.02503295e+02 4.71962671e+01 2.02503186e+02 4.71962193e+01 2.02502913e+02 4.71962242e+01 2.02502800e+02 4.71962769e+01 2.02502483e+02 4.71963783e+01 2.02502279e+02 4.71963677e+01 2.02502223e+02 4.71962158e+01 2.02502299e+02 4.71960274e+01 2.02502295e+02 4.71959614e+01 2.02502164e+02 4.71958014e+01 2.02502013e+02 4.71957853e+01 2.02501779e+02 4.71957605e+01 2.02501796e+02 4.71956498e+01 2.02501753e+02 4.71954544e+01 2.02501475e+02 4.71954496e+01 2.02501246e+02 4.71955038e+01 2.02501281e+02 4.71953283e+01 2.02501406e+02 4.71951076e+01 2.02501544e+02 4.71949580e+01 2.02501540e+02 4.71948920e+01 2.02501606e+02 4.71949122e+01 2.02501967e+02 4.71948592e+01 2.02502100e+02 4.71948726e+01 2.02502448e+02 4.71949411e+01 2.02502725e+02 4.71950613e+01 2.02502808e+02 4.71950855e+01 2.02503112e+02 4.71949766e+01 2.02503087e+02 4.71947939e+01 2.02503008e+02 4.71946122e+01 2.02502977e+02 4.71945499e+01 2.02502930e+02 4.71945635e+01 2.02502517e+02 4.71945643e+01 2.02502274e+02 4.71944530e+01 2.02502233e+02 4.71944487e+01 2.02501825e+02 4.71944248e+01 2.02501650e+02 4.71942288e+01 2.02501339e+02 4.71941681e+01 2.02501302e+02 4.71941609e+01 2.02501013e+02 4.71940494e+01 2.02500799e+02 4.71941302e+01 2.02500450e+02 4.71941402e+01 2.02500256e+02 4.71940897e+01 2.02500026e+02 4.71941277e+01 2.02499874e+02 4.71939149e+01 2.02499659e+02 4.71937486e+01 2.02499322e+02 4.71936721e+01 2.02499311e+02 4.71935000e+01 2.02499486e+02 4.71933096e+01 2.02499620e+02 4.71931263e+01 2.02499282e+02 4.71931824e+01 2.02499119e+02 4.71931713e+01 2.02498855e+02 4.71932151e+01 2.02498587e+02 4.71932395e+01 2.02498618e+02 4.71930669e+01 2.02498771e+02 4.71928633e+01 2.02498795e+02 4.71927603e+01 2.02498699e+02 4.71928186e+01 2.02498251e+02 4.71928369e+01 2.02498268e+02 4.71925494e+01 2.02498672e+02 4.71925024e+01 2.02498552e+02 4.71922886e+01 2.02498314e+02 4.71921396e+01 2.02498126e+02 4.71919529e+01 2.02498096e+02 4.71918435e+01 2.02498019e+02 4.71917069e+01 2.02497972e+02 4.71914667e+01 2.02497992e+02 4.71914010e+01 2.02497895e+02 4.71914188e+01 2.02497567e+02 4.71913897e+01 2.02497497e+02 4.71911702e+01 2.02497544e+02 4.71910816e+01 2.02497392e+02 4.71908687e+01 2.02497124e+02 4.71907414e+01 2.02496828e+02 4.71906345e+01 2.02496554e+02 4.71905810e+01 2.02496480e+02 4.71905666e+01 2.02496129e+02 4.71905005e+01 2.02496165e+02 4.71903383e+01 2.02496104e+02 4.71901933e+01 2.02495813e+02 4.71901181e+01 2.02495772e+02 4.71901137e+01 2.02495402e+02 4.71901605e+01 2.02495263e+02 4.71901645e+01 2.02494888e+02 4.71901390e+01 2.02494665e+02 4.71902985e+01 2.02494637e+02 4.71903020e+01 2.02494367e+02 4.71901759e+01 2.02494006e+02 4.71901862e+01 2.02493787e+02 4.71903484e+01 2.02493802e+02 4.71905935e+01 2.02493806e+02 4.71906595e+01 2.02493709e+02 4.71906623e+01 2.02493471e+02 4.71905133e+01 2.02493467e+02 4.71904472e+01 2.02493365e+02 4.71902660e+01 2.02493213e+02 4.71900531e+01 2.02493005e+02 4.71898811e+01 2.02492970e+02 4.71898380e+01 2.02492955e+02 4.71895928e+01 2.02492976e+02 4.71895426e+01 2.02492894e+02 4.71893128e+01 2.02492886e+02 4.71891871e+01 2.02492940e+02 4.71889533e+01 2.02492592e+02 4.71888853e+01 2.02492305e+02 4.71888239e+01 2.02492258e+02 4.71888063e+01 2.02492254e+02 4.71887926e+01 2.02492232e+02 4.71885004e+01 2.02491876e+02 4.71884382e+01 2.02491864e+02 4.71882496e+01 2.02491828e+02 4.71881483e+01 2.02491618e+02 4.71879780e+01 2.02491606e+02 4.71877894e+01 2.02491599e+02 4.71876668e+01 2.02491447e+02 4.71874539e+01 2.02491093e+02 4.71873900e+01 2.02490883e+02 4.71872197e+01 2.02490645e+02 4.71870706e+01 2.02490450e+02 4.71868888e+01 2.02490106e+02 4.71868522e+01 2.02490189e+02 4.71870821e+01 2.02490472e+02 4.71871984e+01 2.02490483e+02 4.71873870e+01 2.02490216e+02 4.71875190e+01 2.02490031e+02 4.71875242e+01 2.02489680e+02 4.71874833e+01 2.02489645e+02 4.71874843e+01 2.02489624e+02 4.71874480e+01 2.02489510e+02 4.71872589e+01 2.02489246e+02 4.71871287e+01 2.02489118e+02 4.71871323e+01 2.02489122e+02 4.71872197e+01 2.02489250e+02 4.71874505e+01 2.02489229e+02 4.71875007e+01 2.02489312e+02 4.71877305e+01 2.02489656e+02 4.71877672e+01 2.02489704e+02 4.71877658e+01 2.02489732e+02 4.71878146e+01 2.02489833e+02 4.71879959e+01 2.02489962e+02 4.71882260e+01 2.02490201e+02 4.71883750e+01 2.02490194e+02 4.71884028e+01 2.02490154e+02 4.71884094e+01 2.02489745e+02 4.71884211e+01 2.02489673e+02 4.71884397e+01 2.02489453e+02 4.71885381e+01 2.02489093e+02 4.71886121e+01 2.02489241e+02 4.71887592e+01 2.02489375e+02 4.71887883e+01 2.02489652e+02 4.71887803e+01 2.02489943e+02 4.71888907e+01 2.02490158e+02 4.71890571e+01 2.02490385e+02 4.71892147e+01 2.02490398e+02 4.71894278e+01 2.02490128e+02 4.71894050e+01 2.02489875e+02 4.71892663e+01 2.02489703e+02 4.71892925e+01 2.02489581e+02 4.71894837e+01 2.02489608e+02 4.71895326e+01 2.02489511e+02 4.71895353e+01 2.02489151e+02 4.71895456e+01 2.02489053e+02 4.71895484e+01 2.02488728e+02 4.71894632e+01 2.02488461e+02 4.71893354e+01 2.02488376e+02 4.71893606e+01 2.02487996e+02 4.71893537e+01 2.02487868e+02 4.71893426e+01 2.02487547e+02 4.71894410e+01 2.02487450e+02 4.71894323e+01 2.02487446e+02 4.71893782e+01 2.02487437e+02 4.71891160e+01 2.02487333e+02 4.71890082e+01 2.02487514e+02 4.71890597e+01 2.02487775e+02 4.71889855e+01 2.02487766e+02 4.71888729e+01 2.02487475e+02 4.71887976e+01 2.02487367e+02 4.71888430e+01 2.02487429e+02 4.71887691e+01 2.02487411e+02 4.71884844e+01 2.02487379e+02 4.71884390e+01 2.02487477e+02 4.71884362e+01 2.02487860e+02 4.71884780e+01 2.02488065e+02 4.71885681e+01 2.02488156e+02 4.71885850e+01 2.02488376e+02 4.71887474e+01 2.02488751e+02 4.71886974e+01 2.02488788e+02 4.71884429e+01 2.02488476e+02 4.71883479e+01 2.02488204e+02 4.71883557e+01 2.02487974e+02 4.71883937e+01 2.02487736e+02 4.71882447e+01 2.02487461e+02 4.71881911e+01 2.02487364e+02 4.71881939e+01 2.02487386e+02 4.71881436e+01 2.02487486e+02 4.71879070e+01 2.02487449e+02 4.71878057e+01 2.02487298e+02 4.71877896e+01 2.02487087e+02 4.71877484e+01 2.02486826e+02 4.71876157e+01 2.02486770e+02 4.71874598e+01 2.02486734e+02 4.71873586e+01 2.02486488e+02 4.71872837e+01 2.02486590e+02 4.71874650e+01 2.02486553e+02 4.71876235e+01 2.02486390e+02 4.71876124e+01 2.02486097e+02 4.71875038e+01 2.02485956e+02 4.71872823e+01 2.02485618e+02 4.71873384e+01 2.02485489e+02 4.71875571e+01 2.02485204e+02 4.71876780e+01 2.02484889e+02 4.71877803e+01 2.02484669e+02 4.71879420e+01 2.02484629e+02 4.71879381e+01 2.02484594e+02 4.71878950e+01 2.02484813e+02 4.71877329e+01 2.02484962e+02 4.71875269e+01 2.02485054e+02 4.71872988e+01 2.02484802e+02 4.71871594e+01 2.02484412e+02 4.71871223e+01 2.02484167e+02 4.71870300e+01 2.02484195e+02 4.71872829e+01 2.02484199e+02 4.71873490e+01 2.02484092e+02 4.71875815e+01 2.02483821e+02 4.71875587e+01 2.02483769e+02 4.71873798e+01 2.02483889e+02 4.71871834e+01 2.02483499e+02 4.71872111e+01 2.02483377e+02 4.71874338e+01 2.02483385e+02 4.71875563e+01 2.02483611e+02 4.71877140e+01 2.02483666e+02 4.71879136e+01 2.02483642e+02 4.71880166e+01 2.02483654e+02 4.71882052e+01 2.02483713e+02 4.71882894e+01 2.02483982e+02 4.71884161e+01 2.02484032e+02 4.71884415e+01 2.02484291e+02 4.71885129e+01 2.02484588e+02 4.71884897e+01 2.02484794e+02 4.71884668e+01 2.02485115e+02 4.71885201e+01 2.02485187e+02 4.71885015e+01 2.02485501e+02 4.71885953e+01 2.02485779e+02 4.71887145e+01 2.02485794e+02 4.71889439e+01 2.02485835e+02 4.71889990e+01 2.02485849e+02 4.71892775e+01 2.02485439e+02 4.71892913e+01 2.02485209e+02 4.71891360e+01 2.02485085e+02 4.71890995e+01 2.02484808e+02 4.71891074e+01 2.02484511e+02 4.71890010e+01 2.02484282e+02 4.71888970e+01 2.02484178e+02 4.71891310e+01 2.02483884e+02 4.71891394e+01 2.02483684e+02 4.71891212e+01 2.02483398e+02 4.71892421e+01 2.02483301e+02 4.71892448e+01 2.02482928e+02 4.71892473e+01 2.02482855e+02 4.71892494e+01 2.02482608e+02 4.71893464e+01 2.02482263e+02 4.71894303e+01 2.02482365e+02 4.71896115e+01 2.02482489e+02 4.71895712e+01 2.02482874e+02 4.71895602e+01 2.02482956e+02 4.71895640e+01 2.02483191e+02 4.71894117e+01 2.02483528e+02 4.71894021e+01 2.02483680e+02 4.71894182e+01 2.02484019e+02 4.71893306e+01 2.02484067e+02 4.71893293e+01 2.02484349e+02 4.71894464e+01 2.02484537e+02 4.71896331e+01 2.02484572e+02 4.71896762e+01 2.02484673e+02 4.71898575e+01 2.02484685e+02 4.71900461e+01 2.02484725e+02 4.71901449e+01 2.02484845e+02 4.71903816e+01 2.02485111e+02 4.71903126e+01 2.02485425e+02 4.71902092e+01 2.02485522e+02 4.71902064e+01 2.02485526e+02 4.71902724e+01 2.02485656e+02 4.71904324e+01 2.02485902e+02 4.71905073e+01 2.02485887e+02 4.71902622e+01 2.02485883e+02 4.71901961e+01 2.02485980e+02 4.71901934e+01 2.02486218e+02 4.71903424e+01 2.02486457e+02 4.71904915e+01 2.02486461e+02 4.71905575e+01 2.02486562e+02 4.71907388e+01 2.02486743e+02 4.71907336e+01 2.02486822e+02 4.71905472e+01 2.02486818e+02 4.71904812e+01 2.02486719e+02 4.71902978e+01 2.02486480e+02 4.71901488e+01 2.02486239e+02 4.71900018e+01 2.02486110e+02 4.71897717e+01 2.02485806e+02 4.71896709e+01 2.02485621e+02 4.71894822e+01 2.02485618e+02 4.71894326e+01 2.02485687e+02 4.71894335e+01 2.02485983e+02 4.71895399e+01 2.02486180e+02 4.71897201e+01 2.02486541e+02 4.71897098e+01 2.02486638e+02 4.71897070e+01 2.02486974e+02 4.71897840e+01 2.02487107e+02 4.71900109e+01 2.02487155e+02 4.71900938e+01 2.02487111e+02 4.71903335e+01 2.02487113e+02 4.71903665e+01 2.02487130e+02 4.71906447e+01 2.02487422e+02 4.71905598e+01 2.02487734e+02 4.71905238e+01 2.02487748e+02 4.71907637e+01 2.02487515e+02 4.71909169e+01 2.02487177e+02 4.71910047e+01 2.02487192e+02 4.71912498e+01 2.02487552e+02 4.71912395e+01 2.02487729e+02 4.71910507e+01 2.02487953e+02 4.71910128e+01 2.02488136e+02 4.71910056e+01 2.02488214e+02 4.71908192e+01 2.02488210e+02 4.71907532e+01 2.02488109e+02 4.71905719e+01 2.02488097e+02 4.71903833e+01 2.02488090e+02 4.71902607e+01 2.02487937e+02 4.71900478e+01 2.02487967e+02 4.71900029e+01 2.02487949e+02 4.71897137e+01 2.02487939e+02 4.71896864e+01 2.02487980e+02 4.71896908e+01 2.02488336e+02 4.71897530e+01 2.02488611e+02 4.71898066e+01 2.02488708e+02 4.71898038e+01 2.02489062e+02 4.71898677e+01 2.02489076e+02 4.71900972e+01 2.02488856e+02 4.71902593e+01 2.02488833e+02 4.71903623e+01 2.02489107e+02 4.71904159e+01 2.02489326e+02 4.71902537e+01 2.02489311e+02 4.71900086e+01 2.02489307e+02 4.71899426e+01 2.02489526e+02 4.71897805e+01 2.02489624e+02 4.71897777e+01 2.02489594e+02 4.71898226e+01 2.02489740e+02 4.71900168e+01 2.02489804e+02 4.71902531e+01 2.02489428e+02 4.71903170e+01 2.02489443e+02 4.71905621e+01 2.02489447e+02 4.71906282e+01 2.02489350e+02 4.71906309e+01 2.02488989e+02 4.71906412e+01 2.02488770e+02 4.71908034e+01 2.02488785e+02 4.71910485e+01 2.02489023e+02 4.71911975e+01 2.02489027e+02 4.71912636e+01 2.02489201e+02 4.71913916e+01 2.02489367e+02 4.71915939e+01 2.02489489e+02 4.71915519e+01 2.02489767e+02 4.71914266e+01 2.02489846e+02 4.71912402e+01 2.02489876e+02 4.71911953e+01 2.02489807e+02 4.71909438e+01 2.02489729e+02 4.71908043e+01 2.02490042e+02 4.71907009e+01 2.02489940e+02 4.71905196e+01 2.02489929e+02 4.71903310e+01 2.02490206e+02 4.71903231e+01 2.02490358e+02 4.71905360e+01 2.02490719e+02 4.71905257e+01 2.02490816e+02 4.71905229e+01 2.02491109e+02 4.71904704e+01 2.02491292e+02 4.71904964e+01 2.02491601e+02 4.71904781e+01 2.02491745e+02 4.71904876e+01 2.02491940e+02 4.71906688e+01 2.02492178e+02 4.71908178e+01 2.02492188e+02 4.71908451e+01 2.02492116e+02 4.71908637e+01 2.02491878e+02 4.71907146e+01 2.02491656e+02 4.71908115e+01 2.02491613e+02 4.71909105e+01 2.02491624e+02 4.71910909e+01 2.02491317e+02 4.71911982e+01 2.02491246e+02 4.71914534e+01 2.02491113e+02 4.71916055e+01 2.02491332e+02 4.71915071e+01 2.02491553e+02 4.71913455e+01 2.02491912e+02 4.71912709e+01 2.02491978e+02 4.71912911e+01 2.02492341e+02 4.71913482e+01 2.02492640e+02 4.71914525e+01 2.02492855e+02 4.71916195e+01 2.02492932e+02 4.71918873e+01 2.02493202e+02 4.71920134e+01 2.02493556e+02 4.71920773e+01 2.02493679e+02 4.71923114e+01 2.02493901e+02 4.71922140e+01 2.02494088e+02 4.71920321e+01 2.02494158e+02 4.71919577e+01 2.02494146e+02 4.71917691e+01 2.02494365e+02 4.71916070e+01 2.02494358e+02 4.71914844e+01 2.02494206e+02 4.71912715e+01 2.02493967e+02 4.71911225e+01 2.02493741e+02 4.71912167e+01 2.02493389e+02 4.71912246e+01 2.02493412e+02 4.71910114e+01 2.02493724e+02 4.71909074e+01 2.02493822e+02 4.71909047e+01 2.02494037e+02 4.71910709e+01 2.02494275e+02 4.71912199e+01 2.02494685e+02 4.71912082e+01 2.02494757e+02 4.71911897e+01 2.02494992e+02 4.71911011e+01 2.02495362e+02 4.71910330e+01 2.02495399e+02 4.71910402e+01 2.02495637e+02 4.71911893e+01 2.02495888e+02 4.71913297e+01 2.02496192e+02 4.71914304e+01 2.02496248e+02 4.71915863e+01 2.02496028e+02 4.71917484e+01 2.02495950e+02 4.71919348e+01 2.02496188e+02 4.71920839e+01 2.02496192e+02 4.71921499e+01 2.02496207e+02 4.71923950e+01 2.02496466e+02 4.71925293e+01 2.02496496e+02 4.71926387e+01 2.02496266e+02 4.71926767e+01 2.02495992e+02 4.71926232e+01 2.02495918e+02 4.71926088e+01 2.02495509e+02 4.71926205e+01 2.02495526e+02 4.71928986e+01 2.02495554e+02 4.71929475e+01 2.02495456e+02 4.71929502e+01 2.02495218e+02 4.71928012e+01 2.02495010e+02 4.71926292e+01 2.02494645e+02 4.71926792e+01 2.02494474e+02 4.71927002e+01 2.02494283e+02 4.71925162e+01 2.02493922e+02 4.71925265e+01 2.02493937e+02 4.71927717e+01 2.02493941e+02 4.71928377e+01 2.02493722e+02 4.71929998e+01 2.02493477e+02 4.71931461e+01 2.02493626e+02 4.71933267e+01 2.02493640e+02 4.71935470e+01 2.02493399e+02 4.71936957e+01 2.02493225e+02 4.71938859e+01 2.02493098e+02 4.71940425e+01 2.02493306e+02 4.71942145e+01 2.02493575e+02 4.71943406e+01 2.02493580e+02 4.71944066e+01 2.02493681e+02 4.71945879e+01 2.02493693e+02 4.71947765e+01 2.02493401e+02 4.71948934e+01 2.02493196e+02 4.71949465e+01 2.02493016e+02 4.71949517e+01 2.02492738e+02 4.71949596e+01 2.02492726e+02 4.71947710e+01 2.02492719e+02 4.71946484e+01 2.02492444e+02 4.71945949e+01 2.02492347e+02 4.71945977e+01 2.02492343e+02 4.71945316e+01 2.02492213e+02 4.71943716e+01 2.02492089e+02 4.71941375e+01 2.02492085e+02 4.71940714e+01 2.02492070e+02 4.71938263e+01 2.02492066e+02 4.71937603e+01 2.02492051e+02 4.71935151e+01 2.02492047e+02 4.71934491e+01 2.02491945e+02 4.71932678e+01 2.02491793e+02 4.71930549e+01 2.02491578e+02 4.71928887e+01 2.02491572e+02 4.71928534e+01 2.02491624e+02 4.71928543e+01 2.02492034e+02 4.71928426e+01 2.02491951e+02 4.71926127e+01 2.02491668e+02 4.71924964e+01 2.02491516e+02 4.71922835e+01 2.02491191e+02 4.71921984e+01 2.02491072e+02 4.71922418e+01 2.02490672e+02 4.71922911e+01 2.02490444e+02 4.71924479e+01 2.02490259e+02 4.71926312e+01 2.02490193e+02 4.71926110e+01 2.02490157e+02 4.71925679e+01 2.02490142e+02 4.71923228e+01 2.02489858e+02 4.71923809e+01 2.02489657e+02 4.71923557e+01 2.02489406e+02 4.71922158e+01 2.02489399e+02 4.71920940e+01 2.02489384e+02 4.71919067e+01 2.02489102e+02 4.71917904e+01 2.02488827e+02 4.71917369e+01 2.02488730e+02 4.71917396e+01 2.02488369e+02 4.71917499e+01 2.02488150e+02 4.71919120e+01 2.02488252e+02 4.71920933e+01 2.02488547e+02 4.71922000e+01 2.02488764e+02 4.71922959e+01 2.02488838e+02 4.71923104e+01 2.02488840e+02 4.71923434e+01 2.02488956e+02 4.71925491e+01 2.02488966e+02 4.71927212e+01 2.02488808e+02 4.71929213e+01 2.02488539e+02 4.71930528e+01 2.02488522e+02 4.71931948e+01 2.02488532e+02 4.71933470e+01 2.02488409e+02 4.71935696e+01 2.02488022e+02 4.71935643e+01 2.02487763e+02 4.71934651e+01 2.02487569e+02 4.71936431e+01 2.02487699e+02 4.71938030e+01 2.02487713e+02 4.71940325e+01 2.02487718e+02 4.71941142e+01 2.02487964e+02 4.71941891e+01 2.02488209e+02 4.71940428e+01 2.02488246e+02 4.71940500e+01 2.02488282e+02 4.71940883e+01 2.02488065e+02 4.71942523e+01 2.02488056e+02 4.71945157e+01 2.02488058e+02 4.71945467e+01 2.02488214e+02 4.71947244e+01 2.02488325e+02 4.71947139e+01 2.02488620e+02 4.71947491e+01 2.02488905e+02 4.71948642e+01 2.02488938e+02 4.71950969e+01 2.02488553e+02 4.71951242e+01 2.02488504e+02 4.71951248e+01 2.02488457e+02 4.71951949e+01 2.02488716e+02 4.71953295e+01 2.02488643e+02 4.71955110e+01 2.02488441e+02 4.71956835e+01 2.02488153e+02 4.71957451e+01 2.02488176e+02 4.71955180e+01 2.02488208e+02 4.71953795e+01 2.02487878e+02 4.71953321e+01 2.02487996e+02 4.71955356e+01 2.02488051e+02 4.71957390e+01 2.02488024e+02 4.71958404e+01 2.02488292e+02 4.71959682e+01 2.02488306e+02 4.71961976e+01 2.02488311e+02 4.71962793e+01 2.02488438e+02 4.71962804e+01 2.02488696e+02 4.71963201e+01 2.02488852e+02 4.71965299e+01 2.02488853e+02 4.71965394e+01 2.02488824e+02 4.71965510e+01 2.02488438e+02 4.71965795e+01 2.02488344e+02 4.71968199e+01 2.02488349e+02 4.71969017e+01 2.02488449e+02 4.71971530e+01 2.02488477e+02 4.71972019e+01 2.02488578e+02 4.71973832e+01 2.02488542e+02 4.71975416e+01 2.02488488e+02 4.71977754e+01 2.02488490e+02 4.71978084e+01 2.02488390e+02 4.71980450e+01 2.02488441e+02 4.71981357e+01 2.02488624e+02 4.71983253e+01 2.02488635e+02 4.71984974e+01 2.02488611e+02 4.71986606e+01 2.02488619e+02 4.71987863e+01 2.02488565e+02 4.71990201e+01 2.02488891e+02 4.71991041e+01 2.02488947e+02 4.71992906e+01 2.02488657e+02 4.71994086e+01 2.02488542e+02 4.71996361e+01 2.02488407e+02 4.71997873e+01 2.02488386e+02 4.71998375e+01 2.02488333e+02 4.72001035e+01 2.02488067e+02 4.72002363e+01 2.02487988e+02 4.72004227e+01 2.02487992e+02 4.72004887e+01 2.02488007e+02 4.72007339e+01 2.02488235e+02 4.72006409e+01 2.02488578e+02 4.72006375e+01 2.02488601e+02 4.72008695e+01 2.02488571e+02 4.72009681e+01 2.02488582e+02 4.72011567e+01 2.02488269e+02 4.72012601e+01 2.02488370e+02 4.72014414e+01 2.02488382e+02 4.72016300e+01 2.02488303e+02 4.72018164e+01 2.02488282e+02 4.72018666e+01 2.02488233e+02 4.72018680e+01 2.02487824e+02 4.72018797e+01 2.02487783e+02 4.72018754e+01 2.02487773e+02 4.72018481e+01 2.02487691e+02 4.72016182e+01 2.02487347e+02 4.72015816e+01 2.02487306e+02 4.72015772e+01 2.02486991e+02 4.72016586e+01 2.02486939e+02 4.72018484e+01 2.02486944e+02 4.72019283e+01 2.02486762e+02 4.72019791e+01 2.02486601e+02 4.72020130e+01 2.02486256e+02 4.72020968e+01 2.02486357e+02 4.72022781e+01 2.02486644e+02 4.72023395e+01 2.02486689e+02 4.72023584e+01 2.02486923e+02 4.72025109e+01 2.02487162e+02 4.72023635e+01 2.02487579e+02 4.72023516e+01 2.02487602e+02 4.72026387e+01 2.02487380e+02 4.72027992e+01 2.02486965e+02 4.72028052e+01 2.02486798e+02 4.72027349e+01 2.02486613e+02 4.72027402e+01 2.02486406e+02 4.72025673e+01 2.02486056e+02 4.72025701e+01 2.02485836e+02 4.72027322e+01 2.02485938e+02 4.72029135e+01 2.02486110e+02 4.72031117e+01 2.02486371e+02 4.72032443e+01 2.02486427e+02 4.72034002e+01 2.02486463e+02 4.72035015e+01 2.02486661e+02 4.72036804e+01 2.02486867e+02 4.72038536e+01 2.02486923e+02 4.72040095e+01 2.02486631e+02 4.72041264e+01 2.02486426e+02 4.72041795e+01 2.02486246e+02 4.72041846e+01 2.02485968e+02 4.72041925e+01 2.02485850e+02 4.72042368e+01 2.02485831e+02 4.72042936e+01 2.02485805e+02 4.72045075e+01 2.02485625e+02 4.72046945e+01 2.02485301e+02 4.72047911e+01 2.02485106e+02 4.72048294e+01 2.02484918e+02 4.72046428e+01 2.02484610e+02 4.72045454e+01 2.02484375e+02 4.72043938e+01 2.02484246e+02 4.72041637e+01 2.02484244e+02 4.72041307e+01 2.02484129e+02 4.72039250e+01 2.02484118e+02 4.72037529e+01 2.02484021e+02 4.72036792e+01 2.02483783e+02 4.72035298e+01 2.02483585e+02 4.72034198e+01 2.02483511e+02 4.72034053e+01 2.02483517e+02 4.72033776e+01 2.02483499e+02 4.72030884e+01 2.02483498e+02 4.72030664e+01 2.02483429e+02 4.72028149e+01 2.02483191e+02 4.72026659e+01 2.02483003e+02 4.72024792e+01 2.02482993e+02 4.72024519e+01 2.02483062e+02 4.72021957e+01 2.02483432e+02 4.72021277e+01 2.02483349e+02 4.72018978e+01 2.02483342e+02 4.72017721e+01 2.02483396e+02 4.72015383e+01 2.02483402e+02 4.72015106e+01 2.02483384e+02 4.72012214e+01 2.02483387e+02 4.72012021e+01 2.02483300e+02 4.72009586e+01 2.02483205e+02 4.72007889e+01 2.02483228e+02 4.72006859e+01 2.02483217e+02 4.72004973e+01 2.02483157e+02 4.72004130e+01 2.02483175e+02 4.72001718e+01 2.02483300e+02 4.71999825e+01 2.02483272e+02 4.71999337e+01 2.02483142e+02 4.71997737e+01 2.02482903e+02 4.71996246e+01 2.02482705e+02 4.71994457e+01 2.02482651e+02 4.71992461e+01 2.02482845e+02 4.71990683e+01 2.02482878e+02 4.71989924e+01 2.02482865e+02 4.71987818e+01 2.02482961e+02 4.71986060e+01 2.02482957e+02 4.71985399e+01 2.02483051e+02 4.71982995e+01 2.02483270e+02 4.71981374e+01 2.02483294e+02 4.71980344e+01 2.02483331e+02 4.71978760e+01 2.02483287e+02 4.71977147e+01 2.02483207e+02 4.71974994e+01 2.02483212e+02 4.71974445e+01 2.02483298e+02 4.71972571e+01 2.02483325e+02 4.71970357e+01 2.02483256e+02 4.71969319e+01 2.02483162e+02 4.71968304e+01 2.02483146e+02 4.71965638e+01 2.02483132e+02 4.71965272e+01 2.02483049e+02 4.71965033e+01 2.02482679e+02 4.71965713e+01 2.02482460e+02 4.71967334e+01 2.02482631e+02 4.71968980e+01 2.02482825e+02 4.71970796e+01 2.02482789e+02 4.71972381e+01 2.02482668e+02 4.71974622e+01 2.02482452e+02 4.71976263e+01 2.02482153e+02 4.71977385e+01 2.02482106e+02 4.71979360e+01 2.02482111e+02 4.71980114e+01 2.02481970e+02 4.71982225e+01 2.02481819e+02 4.71984272e+01 2.02481810e+02 4.71984805e+01 2.02481825e+02 4.71987304e+01 2.02481699e+02 4.71988875e+01 2.02481678e+02 4.71989377e+01 2.02481761e+02 4.71991675e+01 2.02481768e+02 4.71992933e+01 2.02481558e+02 4.71994611e+01 2.02481538e+02 4.71996572e+01 2.02481568e+02 4.71997665e+01 2.02481384e+02 4.71999508e+01 2.02481082e+02 4.72000608e+01 2.02480957e+02 4.72002823e+01 2.02480940e+02 4.72004248e+01 2.02480949e+02 4.72005764e+01 2.02480908e+02 4.72007733e+01 2.02480900e+02 4.72008451e+01 2.02480796e+02 4.72008565e+01 2.02480413e+02 4.72008140e+01 2.02480356e+02 4.72008042e+01 2.02480128e+02 4.72009607e+01 2.02480117e+02 4.72010326e+01 2.02480217e+02 4.72012840e+01 2.02480456e+02 4.72014331e+01 2.02480458e+02 4.72014661e+01 2.02480475e+02 4.72017443e+01 2.02480587e+02 4.72018458e+01 2.02480377e+02 4.72020139e+01 2.02480384e+02 4.72021365e+01 2.02480652e+02 4.72022637e+01 2.02480682e+02 4.72025040e+01 2.02480290e+02 4.72025313e+01 2.02480163e+02 4.72023002e+01 2.02479925e+02 4.72023302e+01 2.02479895e+02 4.72024976e+01 2.02479903e+02 4.72026153e+01 2.02479930e+02 4.72027972e+01 2.02479888e+02 4.72029050e+01 2.02480022e+02 4.72030549e+01 2.02480037e+02 4.72032975e+01 2.02479642e+02 4.72033497e+01 2.02479538e+02 4.72034122e+01 2.02479397e+02 4.72034959e+01 2.02479394e+02 4.72035188e+01 2.02479384e+02 4.72037873e+01 2.02479105e+02 4.72039121e+01 2.02479081e+02 4.72040753e+01 2.02479137e+02 4.72042312e+01 2.02478879e+02 4.72043689e+01 2.02478808e+02 4.72046026e+01 2.02478805e+02 4.72046220e+01 2.02478764e+02 4.72048959e+01 2.02478507e+02 4.72050341e+01 2.02478206e+02 4.72051456e+01 2.02477927e+02 4.72052704e+01 2.02477767e+02 4.72054698e+01 2.02477492e+02 4.72055972e+01 2.02477429e+02 4.72056211e+01 2.02477209e+02 4.72057194e+01 2.02477005e+02 4.72058913e+01 2.02476979e+02 4.72059534e+01 2.02476923e+02 4.72061389e+01 2.02476655e+02 4.72061925e+01 2.02476572e+02 4.72062189e+01 2.02476317e+02 4.72063591e+01 2.02476248e+02 4.72064937e+01 2.02476217e+02 4.72065954e+01 2.02476026e+02 4.72066575e+01 2.02475846e+02 4.72066626e+01 2.02475674e+02 4.72068545e+01 2.02475547e+02 4.72070111e+01 2.02475518e+02 4.72070561e+01 2.02475484e+02 4.72073340e+01 2.02475389e+02 4.72074533e+01 2.02475397e+02 4.72075790e+01 2.02475167e+02 4.72076170e+01 2.02474891e+02 4.72074956e+01 2.02474757e+02 4.72074785e+01 2.02474452e+02 4.72075873e+01 2.02474420e+02 4.72078434e+01 2.02474442e+02 4.72078798e+01 2.02474556e+02 4.72080689e+01 2.02474708e+02 4.72082818e+01 2.02474686e+02 4.72083320e+01 2.02474615e+02 4.72083506e+01 2.02474254e+02 4.72083609e+01 2.02474084e+02 4.72085540e+01 2.02473781e+02 4.72086639e+01 2.02473741e+02 4.72086706e+01 2.02473403e+02 4.72087266e+01 2.02473240e+02 4.72087155e+01 2.02473162e+02 4.72085760e+01 2.02473160e+02 4.72084492e+01 2.02472974e+02 4.72084586e+01 2.02472754e+02 4.72086207e+01 2.02472566e+02 4.72088023e+01 2.02472347e+02 4.72089644e+01 2.02472009e+02 4.72089740e+01 2.02471904e+02 4.72089872e+01 2.02471536e+02 4.72089977e+01 2.02471430e+02 4.72089904e+01 2.02471093e+02 4.72090000e+01 2.02470988e+02 4.72090132e+01 2.02470779e+02 4.72091821e+01 2.02470554e+02 4.72090728e+01 2.02470251e+02 4.72091510e+01 2.02469996e+02 4.72092909e+01 2.02469705e+02 4.72094085e+01 2.02469633e+02 4.72094271e+01 2.02469363e+02 4.72094942e+01 2.02469092e+02 4.72095019e+01 2.02468908e+02 4.72095091e+01 2.02468916e+02 4.72096316e+01 2.02469170e+02 4.72097696e+01 2.02469383e+02 4.72098057e+01 2.02469552e+02 4.72096118e+01 2.02469790e+02 4.72096364e+01 2.02470061e+02 4.72096307e+01 2.02470280e+02 4.72094686e+01 2.02470510e+02 4.72094306e+01 2.02470633e+02 4.72093899e+01 2.02470852e+02 4.72092272e+01 2.02471088e+02 4.72090755e+01 2.02471445e+02 4.72090654e+01 2.02471681e+02 4.72091470e+01 2.02471778e+02 4.72091443e+01 2.02472139e+02 4.72091340e+01 2.02472236e+02 4.72091313e+01 2.02472561e+02 4.72092165e+01 2.02472573e+02 4.72094051e+01 2.02472260e+02 4.72095085e+01 2.02472156e+02 4.72097429e+01 2.02471775e+02 4.72098044e+01 2.02471760e+02 4.72098085e+01 2.02471408e+02 4.72098742e+01 2.02471245e+02 4.72098631e+01 2.02470871e+02 4.72098375e+01 2.02470651e+02 4.72099996e+01 2.02470588e+02 4.72100235e+01 2.02470227e+02 4.72100337e+01 2.02470130e+02 4.72100365e+01 2.02469910e+02 4.72101348e+01 2.02469571e+02 4.72102223e+01 2.02469292e+02 4.72103471e+01 2.02469256e+02 4.72103564e+01 2.02468953e+02 4.72104347e+01 2.02468700e+02 4.72104418e+01 2.02468516e+02 4.72104610e+01 2.02468187e+02 4.72104954e+01 2.02468081e+02 4.72104881e+01 2.02467711e+02 4.72105561e+01 2.02467491e+02 4.72107182e+01 2.02467451e+02 4.72107138e+01 2.02467075e+02 4.72106655e+01 2.02466837e+02 4.72106084e+01 2.02466746e+02 4.72105834e+01 2.02466398e+02 4.72105154e+01 2.02466293e+02 4.72105674e+01 2.02465871e+02 4.72105794e+01 2.02465759e+02 4.72105334e+01 2.02465482e+02 4.72105413e+01 2.02465301e+02 4.72105464e+01 2.02465024e+02 4.72105543e+01 2.02464749e+02 4.72105007e+01 2.02464611e+02 4.72107135e+01 2.02464358e+02 4.72107207e+01 2.02464046e+02 4.72106599e+01 2.02464005e+02 4.72106555e+01 2.02463635e+02 4.72107022e+01 2.02463496e+02 4.72107061e+01 2.02463122e+02 4.72106805e+01 2.02463082e+02 4.72106872e+01 2.02462820e+02 4.72105553e+01 2.02462466e+02 4.72104913e+01 2.02462256e+02 4.72103209e+01 2.02461974e+02 4.72102037e+01 2.02461837e+02 4.72101769e+01 2.02461845e+02 4.72102995e+01 2.02461856e+02 4.72104881e+01 2.02461579e+02 4.72104959e+01 2.02461304e+02 4.72104423e+01 2.02461044e+02 4.72105790e+01 2.02461011e+02 4.72105899e+01 2.02460754e+02 4.72106967e+01 2.02460472e+02 4.72106625e+01 2.02460283e+02 4.72104764e+01 2.02460161e+02 4.72103266e+01 2.02460156e+02 4.72102449e+01 2.02460005e+02 4.72102287e+01 2.02459834e+02 4.72101580e+01 2.02459836e+02 4.72101234e+01 2.02460052e+02 4.72099586e+01 2.02460241e+02 4.72097781e+01 2.02460429e+02 4.72095963e+01 2.02460649e+02 4.72094343e+01 2.02460882e+02 4.72092806e+01 2.02461083e+02 4.72091073e+01 2.02461286e+02 4.72089348e+01 2.02461522e+02 4.72087832e+01 2.02461768e+02 4.72086372e+01 2.02462012e+02 4.72084908e+01 2.02462270e+02 4.72083525e+01 2.02462458e+02 4.72081710e+01 2.02462661e+02 4.72079985e+01 2.02462885e+02 4.72078395e+01 2.02463094e+02 4.72076707e+01 2.02463306e+02 4.72075041e+01 2.02463555e+02 4.72073606e+01 2.02463805e+02 4.72072172e+01 2.02463994e+02 4.72070365e+01 2.02464214e+02 4.72068744e+01 2.02464433e+02 4.72067124e+01 2.02464630e+02 4.72065362e+01 2.02464850e+02 4.72063742e+01 2.02465075e+02 4.72062158e+01 2.02465341e+02 4.72060827e+01 2.02465474e+02 4.72058663e+01 2.02465669e+02 4.72056893e+01 2.02465936e+02 4.72055569e+01 2.02466150e+02 4.72053913e+01 2.02466362e+02 4.72052245e+01 2.02466526e+02 4.72050276e+01 2.02466723e+02 4.72048520e+01 2.02466964e+02 4.72047035e+01 2.02467021e+02 4.72045251e+01 2.02467067e+02 4.72044683e+01 2.02467223e+02 4.72042663e+01 2.02467449e+02 4.72041083e+01 2.02467685e+02 4.72039567e+01 2.02467914e+02 4.72038662e+01 2.02468022e+02 4.72038681e+01 2.02468259e+02 4.72037174e+01 2.02468278e+02 4.72035970e+01 2.02468360e+02 4.72034813e+01 2.02468510e+02 4.72032758e+01 2.02468686e+02 4.72030864e+01 2.02468971e+02 4.72029651e+01 2.02469219e+02 4.72028211e+01 2.02469475e+02 4.72026815e+01 2.02469658e+02 4.72024970e+01 2.02469878e+02 4.72023349e+01 2.02470106e+02 4.72021784e+01 2.02470301e+02 4.72020013e+01 2.02470206e+02 4.72018479e+01 2.02469972e+02 4.72016952e+01 2.02469744e+02 4.72015381e+01 2.02469476e+02 4.72014109e+01 2.02469224e+02 4.72012716e+01 2.02468991e+02 4.72011186e+01 2.02468786e+02 4.72009446e+01 2.02468537e+02 4.72008038e+01 2.02468298e+02 4.72006551e+01 2.02468069e+02 4.72004989e+01 2.02467791e+02 4.72003786e+01 2.02467560e+02 4.72002239e+01 2.02467307e+02 4.72000855e+01 2.02467086e+02 4.71999233e+01 2.02466840e+02 4.71997802e+01 2.02466593e+02 4.71996374e+01 2.02466352e+02 4.71994896e+01 2.02466099e+02 4.71993514e+01 2.02465854e+02 4.71992070e+01 2.02465625e+02 4.71990507e+01 2.02465378e+02 4.71989077e+01 2.02465136e+02 4.71987616e+01 2.02464971e+02 4.71986698e+01 2.02464856e+02 4.71986433e+01 2.02464555e+02 4.71985402e+01 2.02464443e+02 4.71983400e+01 2.02464418e+02 4.71983163e+01 2.02464174e+02 4.71981710e+01 2.02464171e+02 4.71981699e+01 2.02463845e+02 4.71980888e+01 2.02463634e+02 4.71979192e+01 2.02463404e+02 4.71977642e+01 2.02463153e+02 4.71976238e+01 2.02462965e+02 4.71974379e+01 2.02462856e+02 4.71973478e+01 2.02462749e+02 4.71972722e+01 2.02462525e+02 4.71971120e+01 2.02462295e+02 4.71969569e+01 2.02462090e+02 4.71968689e+01 2.02462008e+02 4.71968436e+01 2.02461989e+02 4.71968059e+01 2.02461840e+02 4.71966420e+01 2.02461623e+02 4.71964768e+01 2.02461375e+02 4.71963351e+01 2.02461081e+02 4.71962272e+01 2.02460863e+02 4.71960630e+01 2.02460600e+02 4.71959316e+01 2.02460581e+02 4.71959253e+01 2.02460264e+02 4.71958548e+01 2.02460220e+02 4.71956994e+01 2.02460219e+02 4.71955624e+01 2.02460245e+02 4.71954158e+01 2.02460465e+02 4.71952544e+01 2.02460723e+02 4.71951167e+01 2.02460913e+02 4.71949362e+01 2.02461132e+02 4.71947736e+01 2.02461324e+02 4.71945941e+01 2.02461498e+02 4.71944042e+01 2.02461738e+02 4.71942548e+01 2.02461992e+02 4.71941144e+01 2.02462151e+02 4.71939146e+01 2.02462353e+02 4.71937413e+01 2.02462589e+02 4.71935898e+01 2.02462834e+02 4.71934435e+01 2.02463075e+02 4.71932951e+01 2.02463275e+02 4.71931209e+01 2.02463487e+02 4.71929539e+01 2.02463720e+02 4.71928004e+01 2.02463931e+02 4.71926335e+01 2.02464146e+02 4.71924682e+01 2.02464359e+02 4.71923026e+01 2.02464569e+02 4.71921347e+01 2.02464797e+02 4.71919777e+01 2.02465000e+02 4.71918056e+01 2.02465212e+02 4.71916387e+01 2.02465431e+02 4.71914762e+01 2.02465656e+02 4.71913175e+01 2.02465898e+02 4.71911696e+01 2.02466100e+02 4.71909970e+01 2.02466332e+02 4.71908425e+01 2.02466565e+02 4.71906889e+01 2.02466777e+02 4.71905226e+01 2.02466995e+02 4.71903596e+01 2.02467212e+02 4.71901956e+01 2.02467420e+02 4.71900267e+01 2.02467660e+02 4.71898774e+01 2.02467884e+02 4.71897185e+01 2.02468099e+02 4.71895531e+01 2.02468306e+02 4.71893834e+01 2.02468523e+02 4.71892201e+01 2.02468733e+02 4.71890523e+01 2.02468962e+02 4.71888961e+01 2.02469172e+02 4.71887281e+01 2.02469164e+02 4.71886303e+01 2.02468951e+02 4.71884622e+01 2.02468740e+02 4.71882928e+01 2.02468532e+02 4.71881208e+01 2.02468261e+02 4.71879957e+01 2.02468014e+02 4.71878531e+01 2.02467770e+02 4.71877084e+01 2.02467554e+02 4.71875423e+01 2.02467332e+02 4.71873809e+01 2.02467082e+02 4.71872407e+01 2.02466843e+02 4.71870916e+01 2.02466624e+02 4.71869280e+01 2.02466394e+02 4.71867731e+01 2.02466155e+02 4.71866240e+01 2.02465946e+02 4.71864532e+01 2.02465721e+02 4.71862942e+01 2.02465452e+02 4.71861676e+01 2.02465219e+02 4.71860148e+01 2.02464963e+02 4.71858783e+01 2.02464739e+02 4.71857188e+01 2.02464501e+02 4.71855695e+01 2.02464224e+02 4.71854488e+01 2.02464093e+02 4.71852535e+01 2.02464241e+02 4.71851105e+01 2.02464263e+02 4.71850603e+01 2.02464303e+02 4.71850647e+01 2.02464729e+02 4.71850526e+01 2.02464915e+02 4.71848695e+01 2.02465159e+02 4.71847232e+01 2.02465208e+02 4.71847218e+01 2.02465546e+02 4.71846658e+01 2.02465775e+02 4.71846278e+01 2.02465956e+02 4.71846227e+01 2.02466035e+02 4.71844363e+01 2.02466064e+02 4.71843914e+01 2.02466128e+02 4.71843675e+01 2.02466363e+02 4.71842790e+01 2.02466348e+02 4.71842046e+01 2.02466374e+02 4.71839863e+01 2.02466516e+02 4.71837761e+01 2.02466587e+02 4.71837028e+01 2.02466624e+02 4.71835443e+01 2.02466853e+02 4.71835063e+01 2.02467127e+02 4.71835599e+01 2.02467225e+02 4.71835571e+01 2.02467585e+02 4.71835469e+01 2.02467830e+02 4.71834007e+01 2.02467878e+02 4.71833993e+01 2.02468182e+02 4.71835001e+01 2.02468461e+02 4.71834962e+01 2.02468675e+02 4.71833303e+01 2.02468663e+02 4.71831448e+01 2.02468498e+02 4.71829417e+01 2.02468496e+02 4.71829197e+01 2.02468560e+02 4.71828959e+01 2.02468885e+02 4.71829811e+01 2.02469037e+02 4.71831940e+01 2.02469272e+02 4.71831055e+01 2.02469296e+02 4.71830025e+01 2.02469284e+02 4.71828139e+01 2.02469598e+02 4.71827106e+01 2.02469695e+02 4.71827078e+01 2.02469962e+02 4.71826388e+01 2.02470239e+02 4.71826310e+01 2.02470251e+02 4.71828196e+01 2.02470258e+02 4.71829421e+01 2.02470439e+02 4.71829370e+01 2.02470431e+02 4.71828145e+01 2.02470419e+02 4.71826259e+01 2.02470697e+02 4.71826180e+01 2.02470877e+02 4.71826129e+01 2.02470870e+02 4.71824903e+01 2.02470742e+02 4.71822591e+01 2.02470740e+02 4.71822281e+01 2.02470786e+02 4.71822268e+01 2.02471171e+02 4.71821983e+01 2.02471245e+02 4.71822128e+01 2.02471510e+02 4.71821110e+01 2.02471866e+02 4.71820795e+01 2.02472087e+02 4.71821723e+01 2.02472161e+02 4.71821868e+01 2.02472570e+02 4.71821752e+01 2.02472619e+02 4.71821738e+01 2.02473028e+02 4.71821622e+01 2.02473247e+02 4.71820001e+01 2.02473230e+02 4.71817219e+01 2.02473228e+02 4.71816889e+01 2.02473448e+02 4.71815268e+01 2.02473488e+02 4.71815312e+01 2.02473914e+02 4.71815191e+01 2.02473977e+02 4.71814952e+01 2.02473981e+02 4.71815613e+01 2.02473856e+02 4.71817821e+01 2.02473543e+02 4.71818854e+01 2.02473568e+02 4.71821231e+01 2.02473796e+02 4.71822797e+01 2.02474063e+02 4.71822107e+01 2.02474260e+02 4.71820346e+01 2.02474287e+02 4.71819169e+01 2.02474277e+02 4.71817458e+01 2.02474342e+02 4.71815510e+01 2.02474338e+02 4.71814850e+01 2.02474435e+02 4.71814822e+01 2.02474796e+02 4.71814720e+01 2.02475015e+02 4.71813099e+01 2.02475189e+02 4.71811192e+01 2.02475374e+02 4.71811139e+01 2.02475718e+02 4.71811506e+01 2.02475754e+02 4.71811578e+01 2.02476005e+02 4.71812983e+01 2.02476290e+02 4.71812095e+01 2.02476552e+02 4.71812190e+01 2.02476724e+02 4.71814172e+01 2.02476994e+02 4.71813501e+01 2.02477221e+02 4.71813751e+01 2.02477277e+02 4.71815270e+01 2.02477341e+02 4.71816122e+01 2.02477437e+02 4.71816268e+01 2.02477774e+02 4.71816172e+01 2.02477926e+02 4.71816333e+01 2.02478203e+02 4.71816254e+01 2.02478352e+02 4.71816007e+01 2.02478690e+02 4.71815911e+01 2.02478813e+02 4.71818253e+01 2.02478792e+02 4.71818755e+01 2.02478907e+02 4.71820812e+01 2.02478962e+02 4.71822808e+01 2.02478617e+02 4.71823646e+01 2.02478520e+02 4.71823674e+01 2.02478159e+02 4.71823776e+01 2.02478034e+02 4.71825984e+01 2.02478041e+02 4.71827210e+01 2.02478222e+02 4.71827159e+01 2.02478441e+02 4.71825538e+01 2.02478718e+02 4.71825459e+01 2.02478993e+02 4.71825995e+01 2.02479212e+02 4.71824374e+01 2.02479431e+02 4.71822753e+01 2.02479330e+02 4.71820940e+01 2.02479367e+02 4.71819355e+01 2.02479355e+02 4.71817501e+01 2.02479308e+02 4.71815995e+01 2.02479510e+02 4.71816355e+01 2.02479885e+02 4.71816610e+01 2.02479948e+02 4.71816372e+01 2.02479927e+02 4.71816874e+01 2.02479708e+02 4.71818495e+01 2.02479725e+02 4.71821276e+01 2.02479955e+02 4.71822824e+01 2.02480381e+02 4.71822703e+01 2.02480314e+02 4.71820170e+01 2.02480285e+02 4.71819113e+01 2.02480336e+02 4.71816757e+01 2.02480309e+02 4.71816269e+01 2.02480371e+02 4.71816499e+01 2.02480672e+02 4.71817526e+01 2.02480845e+02 4.71816631e+01 2.02481122e+02 4.71815367e+01 2.02481451e+02 4.71815023e+01 2.02481557e+02 4.71815095e+01 2.02481854e+02 4.71815298e+01 2.02482094e+02 4.71815461e+01 2.02482279e+02 4.71815409e+01 2.02482591e+02 4.71816359e+01 2.02482809e+02 4.71818004e+01 2.02482994e+02 4.71818090e+01 2.02483083e+02 4.71815975e+01 2.02483094e+02 4.71815724e+01 2.02483177e+02 4.71813252e+01 2.02483439e+02 4.71813347e+01 2.02483697e+02 4.71814690e+01 2.02483818e+02 4.71817048e+01 2.02484188e+02 4.71816581e+01 2.02484314e+02 4.71816640e+01 2.02484552e+02 4.71818130e+01 2.02484595e+02 4.71819126e+01 2.02484639e+02 4.71820738e+01 2.02484889e+02 4.71822150e+01 2.02485198e+02 4.71822890e+01 2.02485230e+02 4.71822880e+01 2.02485499e+02 4.71824142e+01 2.02485766e+02 4.71823452e+01 2.02486044e+02 4.71823373e+01 2.02486173e+02 4.71825674e+01 2.02486200e+02 4.71826162e+01 2.02485947e+02 4.71827572e+01 2.02485907e+02 4.71827639e+01 2.02485570e+02 4.71826873e+01 2.02485441e+02 4.71824572e+01 2.02485105e+02 4.71825300e+01 2.02484887e+02 4.71825417e+01 2.02484633e+02 4.71825346e+01 2.02484440e+02 4.71825464e+01 2.02484131e+02 4.71825201e+01 2.02484005e+02 4.71827402e+01 2.02484055e+02 4.71828308e+01 2.02484251e+02 4.71830118e+01 2.02484445e+02 4.71831936e+01 2.02484789e+02 4.71832302e+01 2.02485008e+02 4.71830681e+01 2.02485057e+02 4.71830667e+01 2.02485295e+02 4.71832158e+01 2.02485633e+02 4.71831597e+01 2.02485863e+02 4.71831217e+01 2.02486137e+02 4.71831753e+01 2.02486203e+02 4.71831954e+01 2.02486493e+02 4.71833068e+01 2.02486753e+02 4.71834395e+01 2.02486809e+02 4.71835954e+01 2.02486867e+02 4.71836810e+01 2.02486946e+02 4.71839480e+01 2.02486973e+02 4.71839969e+01 2.02487075e+02 4.71841781e+01 2.02487349e+02 4.71842317e+01 2.02487423e+02 4.71842461e+01 2.02487832e+02 4.71842345e+01 2.02487904e+02 4.71842159e+01 2.02488202e+02 4.71841664e+01 2.02488350e+02 4.71842116e+01 2.02488600e+02 4.71843519e+01 2.02488604e+02 4.71844179e+01 2.02488706e+02 4.71845992e+01 2.02488923e+02 4.71847637e+01 2.02489052e+02 4.71846979e+01 2.02489063e+02 4.71846602e+01 2.02488965e+02 4.71844076e+01 2.02488961e+02 4.71843416e+01 2.02488859e+02 4.71841603e+01 2.02488701e+02 4.71839523e+01 2.02488394e+02 4.71838536e+01 2.02488210e+02 4.71836640e+01 2.02488132e+02 4.71835245e+01 2.02488352e+02 4.71833624e+01 2.02488690e+02 4.71832748e+01 2.02488762e+02 4.71832563e+01 2.02488972e+02 4.71831520e+01 2.02489296e+02 4.71830552e+01 2.02489479e+02 4.71830513e+01 2.02489462e+02 4.71831586e+01 2.02489426e+02 4.71834158e+01 2.02489437e+02 4.71834424e+01 2.02489552e+02 4.71836481e+01 2.02489563e+02 4.71838202e+01 2.02489473e+02 4.71840318e+01 2.02489757e+02 4.71841475e+01 2.02490042e+02 4.71842626e+01 2.02490081e+02 4.71844434e+01 2.02489957e+02 4.71846501e+01 2.02489985e+02 4.71846820e+01 2.02489921e+02 4.71846767e+01 2.02489678e+02 4.71847895e+01 2.02489542e+02 4.71849575e+01 2.02489835e+02 4.71850660e+01 2.02490147e+02 4.71851610e+01 2.02490267e+02 4.71851576e+01 2.02490377e+02 4.71849907e+01 2.02490373e+02 4.71849247e+01 2.02490470e+02 4.71849219e+01 2.02490831e+02 4.71849116e+01 2.02490928e+02 4.71849089e+01 2.02491289e+02 4.71848986e+01 2.02491363e+02 4.71849130e+01 2.02491701e+02 4.71848569e+01 2.02491755e+02 4.71846231e+01 2.02491727e+02 4.71845743e+01 2.02491564e+02 4.71844383e+01 2.02491323e+02 4.71842915e+01 2.02491356e+02 4.71840431e+01 2.02491414e+02 4.71838989e+01 2.02491414e+02 4.71837805e+01 2.02491648e+02 4.71836273e+01 2.02491555e+02 4.71834694e+01 2.02491303e+02 4.71833302e+01 2.02491101e+02 4.71832855e+01 2.02490951e+02 4.71832646e+01 2.02490559e+02 4.71832463e+01 2.02490535e+02 4.71832470e+01 2.02490211e+02 4.71831611e+01 2.02490139e+02 4.71829838e+01 2.02490248e+02 4.71828087e+01 2.02490048e+02 4.71829268e+01 2.02489649e+02 4.71829261e+01 2.02489611e+02 4.71826540e+01 2.02489679e+02 4.71825783e+01 2.02489403e+02 4.71824566e+01 2.02489456e+02 4.71822575e+01 2.02489539e+02 4.71820313e+01 2.02489506e+02 4.71819901e+01 2.02489376e+02 4.71818258e+01 2.02489250e+02 4.71815940e+01 2.02488983e+02 4.71816630e+01 2.02488750e+02 4.71816382e+01 2.02488694e+02 4.71814824e+01 2.02488686e+02 4.71813598e+01 2.02488412e+02 4.71813062e+01 2.02488338e+02 4.71812918e+01 2.02488336e+02 4.71812588e+01 2.02488556e+02 4.71810967e+01 2.02488538e+02 4.71808185e+01 2.02488147e+02 4.71807825e+01 2.02488041e+02 4.71807752e+01 2.02487704e+02 4.71808636e+01 2.02487677e+02 4.71811300e+01 2.02487691e+02 4.71811544e+01 2.02487767e+02 4.71813885e+01 2.02487751e+02 4.71814916e+01 2.02487601e+02 4.71815111e+01 2.02487251e+02 4.71814450e+01 2.02487033e+02 4.71813419e+01 2.02487049e+02 4.71815944e+01 2.02487269e+02 4.71817568e+01 2.02487678e+02 4.71817451e+01 2.02487719e+02 4.71817495e+01 2.02487729e+02 4.71817768e+01 2.02487868e+02 4.71819646e+01 2.02487881e+02 4.71821710e+01 2.02487544e+02 4.71822046e+01 2.02487477e+02 4.71822174e+01 2.02487058e+02 4.71822552e+01 2.02487022e+02 4.71822645e+01 2.02486613e+02 4.71822762e+01 2.02486565e+02 4.71822775e+01 2.02486216e+02 4.71822095e+01 2.02486099e+02 4.71819708e+01 2.02485786e+02 4.71818773e+01 2.02485728e+02 4.71817228e+01 2.02486005e+02 4.71817149e+01 2.02486139e+02 4.71816804e+01 2.02486342e+02 4.71815085e+01 2.02486369e+02 4.71814464e+01 2.02486273e+02 4.71814652e+01 2.02485904e+02 4.71815336e+01 2.02485807e+02 4.71815364e+01 2.02485474e+02 4.71814571e+01 2.02485310e+02 4.71812530e+01 2.02485232e+02 4.71811135e+01 2.02485224e+02 4.71809910e+01 2.02485017e+02 4.71808185e+01 2.02485022e+02 4.71806834e+01 2.02485076e+02 4.71804497e+01 2.02485074e+02 4.71804167e+01 2.02484895e+02 4.71802584e+01 2.02484704e+02 4.71800737e+01 2.02484697e+02 4.71798819e+01 2.02484631e+02 4.71798028e+01 2.02484478e+02 4.71797449e+01 2.02484330e+02 4.71796998e+01 2.02484251e+02 4.71796034e+01 2.02484148e+02 4.71795091e+01 2.02483922e+02 4.71793505e+01 2.02483843e+02 4.71793484e+01 2.02483801e+02 4.71794399e+01 2.02483813e+02 4.71796285e+01 2.02483650e+02 4.71798258e+01 2.02483410e+02 4.71799750e+01 2.02483084e+02 4.71799701e+01 2.02482809e+02 4.71798478e+01 2.02482718e+02 4.71798418e+01 2.02482442e+02 4.71797940e+01 2.02482260e+02 4.71796029e+01 2.02482125e+02 4.71794711e+01 2.02482082e+02 4.71794095e+01 2.02481919e+02 4.71793424e+01 2.02481771e+02 4.71793135e+01 2.02481505e+02 4.71793825e+01 2.02481227e+02 4.71793904e+01 2.02480953e+02 4.71793368e+01 2.02480859e+02 4.71795772e+01 2.02480480e+02 4.71796400e+01 2.02480454e+02 4.71796363e+01 2.02480159e+02 4.71795295e+01 2.02479840e+02 4.71795386e+01 2.02479701e+02 4.71795425e+01 2.02479357e+02 4.71794713e+01 2.02479100e+02 4.71793360e+01 2.02479039e+02 4.71793376e+01 2.02478670e+02 4.71793286e+01 2.02478607e+02 4.71790671e+01 2.02478889e+02 4.71789446e+01 2.02478862e+02 4.71788610e+01 2.02478728e+02 4.71788438e+01 2.02478468e+02 4.71788270e+01 2.02478134e+02 4.71787716e+01 2.02478003e+02 4.71789891e+01 2.02477801e+02 4.71789949e+01 2.02477568e+02 4.71790160e+01 2.02477264e+02 4.71790663e+01 2.02477158e+02 4.71790591e+01 2.02476814e+02 4.71791429e+01 2.02476594e+02 4.71793050e+01 2.02476469e+02 4.71795258e+01 2.02476177e+02 4.71796427e+01 2.02475902e+02 4.71797702e+01 2.02475683e+02 4.71799323e+01 2.02475472e+02 4.71800996e+01 2.02475240e+02 4.71802538e+01 2.02475204e+02 4.71802631e+01 2.02474902e+02 4.71803414e+01 2.02474673e+02 4.71803306e+01 2.02474329e+02 4.71802825e+01 2.02474225e+02 4.71805165e+01 2.02473931e+02 4.71805536e+01 2.02473811e+02 4.71805570e+01 2.02473488e+02 4.71806543e+01 2.02473381e+02 4.71808867e+01 2.02472989e+02 4.71809412e+01 2.02472961e+02 4.71809448e+01 2.02472536e+02 4.71809568e+01 2.02472472e+02 4.71809807e+01 2.02472494e+02 4.71809305e+01 2.02472477e+02 4.71806523e+01 2.02472223e+02 4.71805142e+01 2.02472220e+02 4.71804601e+01 2.02472176e+02 4.71802240e+01 2.02471842e+02 4.71801453e+01 2.02471738e+02 4.71801585e+01 2.02471445e+02 4.71801132e+01 2.02471238e+02 4.71799414e+01 2.02470912e+02 4.71798569e+01 2.02470734e+02 4.71796632e+01 2.02470509e+02 4.71795037e+01 2.02470231e+02 4.71795157e+01 2.02469932e+02 4.71796051e+01 2.02469838e+02 4.71795697e+01 2.02469912e+02 4.71796200e+01 2.02469862e+02 4.71798834e+01 2.02469514e+02 4.71799653e+01 2.02469448e+02 4.71799627e+01 2.02469428e+02 4.71799113e+01 2.02469347e+02 4.71797123e+01 2.02469267e+02 4.71795118e+01 2.02469651e+02 4.71794526e+01 2.02469667e+02 4.71791631e+01 2.02469715e+02 4.71791147e+01 2.02469623e+02 4.71791359e+01 2.02469296e+02 4.71792305e+01 2.02469067e+02 4.71792685e+01 2.02469103e+02 4.71791100e+01 2.02469013e+02 4.71789825e+01 2.02468783e+02 4.71788275e+01 2.02468616e+02 4.71788054e+01 2.02468382e+02 4.71789580e+01 2.02468237e+02 4.71791668e+01 2.02468249e+02 4.71792217e+01 2.02468266e+02 4.71794839e+01 2.02468130e+02 4.71796351e+01 2.02468109e+02 4.71796853e+01 2.02468126e+02 4.71799634e+01 2.02468116e+02 4.71799885e+01 2.02467896e+02 4.71801506e+01 2.02467837e+02 4.71801771e+01 2.02467476e+02 4.71801873e+01 2.02467382e+02 4.71804277e+01 2.02467038e+02 4.71805115e+01 2.02467053e+02 4.71807566e+01 2.02467057e+02 4.71808226e+01 2.02466960e+02 4.71808254e+01 2.02466675e+02 4.71808835e+01 2.02466495e+02 4.71808435e+01 2.02466153e+02 4.71807708e+01 2.02466125e+02 4.71805395e+01 2.02466164e+02 4.71804376e+01 2.02465867e+02 4.71803318e+01 2.02465814e+02 4.71800459e+01 2.02466246e+02 4.71800167e+01 2.02466229e+02 4.71797386e+01 2.02466227e+02 4.71797056e+01 2.02466112e+02 4.71794998e+01 2.02465872e+02 4.71794834e+01 2.02465687e+02 4.71794887e+01 2.02465703e+02 4.71793780e+01 2.02465851e+02 4.71791707e+01 2.02465800e+02 4.71790801e+01 2.02465784e+02 4.71788302e+01 2.02465824e+02 4.71787370e+01 2.02465861e+02 4.71785785e+01 2.02465816e+02 4.71784172e+01 2.02465832e+02 4.71782616e+01 2.02465852e+02 4.71780655e+01 2.02465822e+02 4.71779562e+01 2.02465759e+02 4.71778094e+01 2.02465564e+02 4.71776279e+01 2.02465354e+02 4.71774575e+01 2.02465348e+02 4.71773601e+01 2.02465410e+02 4.71771002e+01 2.02465576e+02 4.71769682e+01 2.02465606e+02 4.71769233e+01 2.02465646e+02 4.71769166e+01 2.02465952e+02 4.71768405e+01 2.02466199e+02 4.71768335e+01 2.02466481e+02 4.71769504e+01 2.02466726e+02 4.71770253e+01 2.02466596e+02 4.71768653e+01 2.02466582e+02 4.71766358e+01 2.02466920e+02 4.71766263e+01 2.02467043e+02 4.71768605e+01 2.02467047e+02 4.71769265e+01 2.02466802e+02 4.71770728e+01 2.02466819e+02 4.71773509e+01 2.02467058e+02 4.71775000e+01 2.02467060e+02 4.71775330e+01 2.02467175e+02 4.71777388e+01 2.02467229e+02 4.71779383e+01 2.02467206e+02 4.71780413e+01 2.02467355e+02 4.71780166e+01 2.02467605e+02 4.71778741e+01 2.02467553e+02 4.71777845e+01 2.02467575e+02 4.71775563e+01 2.02467925e+02 4.71774754e+01 2.02467997e+02 4.71774569e+01 2.02468207e+02 4.71773530e+01 2.02468227e+02 4.71772866e+01 2.02468213e+02 4.71770572e+01 2.02468237e+02 4.71769542e+01 2.02468118e+02 4.71769980e+01 2.02467899e+02 4.71771599e+01 2.02467531e+02 4.71771505e+01 2.02467324e+02 4.71769781e+01 2.02467313e+02 4.71767934e+01 2.02467511e+02 4.71766182e+01 2.02467823e+02 4.71766094e+01 2.02468114e+02 4.71766963e+01 2.02468300e+02 4.71765131e+01 2.02468553e+02 4.71763721e+01 2.02468593e+02 4.71763655e+01 2.02468621e+02 4.71764143e+01 2.02468636e+02 4.71766595e+01 2.02468996e+02 4.71766492e+01 2.02469122e+02 4.71764284e+01 2.02469294e+02 4.71762370e+01 2.02469608e+02 4.71761344e+01 2.02469874e+02 4.71760009e+01 2.02469858e+02 4.71757558e+01 2.02469880e+02 4.71757056e+01 2.02470057e+02 4.71755175e+01 2.02470252e+02 4.71754653e+01 2.02470397e+02 4.71754308e+01 2.02470516e+02 4.71752695e+01 2.02470301e+02 4.71751033e+01 2.02470274e+02 4.71750544e+01 2.02470371e+02 4.71750517e+01 2.02470600e+02 4.71749588e+01 2.02470950e+02 4.71749488e+01 2.02470965e+02 4.71751873e+01 2.02470848e+02 4.71753498e+01 2.02470852e+02 4.71754159e+01 2.02470982e+02 4.71755759e+01 2.02470996e+02 4.71758053e+01 2.02470973e+02 4.71759083e+01 2.02471247e+02 4.71759619e+01 2.02471232e+02 4.71757168e+01 2.02471228e+02 4.71756508e+01 2.02471346e+02 4.71756324e+01 2.02471522e+02 4.71755354e+01 2.02471802e+02 4.71754115e+01 2.02472096e+02 4.71754032e+01 2.02472317e+02 4.71754341e+01 2.02472546e+02 4.71753961e+01 2.02472674e+02 4.71753580e+01 2.02473020e+02 4.71753713e+01 2.02473303e+02 4.71754525e+01 2.02473375e+02 4.71754339e+01 2.02473736e+02 4.71754237e+01 2.02473861e+02 4.71752029e+01 2.02474139e+02 4.71751950e+01 2.02474263e+02 4.71751546e+01 2.02474312e+02 4.71750673e+01 2.02474300e+02 4.71748787e+01 2.02474379e+02 4.71746923e+01 2.02474171e+02 4.71745203e+01 2.02474162e+02 4.71744930e+01 2.02474210e+02 4.71744916e+01 2.02474475e+02 4.71746212e+01 2.02474829e+02 4.71746111e+01 2.02475055e+02 4.71744530e+01 2.02475126e+02 4.71744656e+01 2.02475535e+02 4.71744540e+01 2.02475518e+02 4.71741758e+01 2.02475109e+02 4.71741874e+01 2.02475039e+02 4.71742040e+01 2.02475033e+02 4.71741400e+01 2.02475018e+02 4.71738948e+01 2.02475013e+02 4.71738288e+01 2.02475087e+02 4.71738432e+01 2.02475369e+02 4.71739604e+01 2.02475588e+02 4.71741242e+01 2.02475826e+02 4.71742733e+01 2.02476187e+02 4.71742630e+01 2.02476281e+02 4.71742623e+01 2.02476522e+02 4.71744093e+01 2.02476526e+02 4.71744754e+01 2.02476541e+02 4.71747205e+01 2.02476780e+02 4.71748696e+01 2.02476759e+02 4.71749198e+01 2.02476539e+02 4.71750819e+01 2.02476556e+02 4.71753600e+01 2.02476966e+02 4.71753484e+01 2.02477014e+02 4.71753470e+01 2.02477423e+02 4.71753354e+01 2.02477464e+02 4.71753397e+01 2.02477499e+02 4.71753828e+01 2.02477246e+02 4.71755239e+01 2.02477376e+02 4.71757300e+01 2.02477388e+02 4.71759114e+01 2.02477152e+02 4.71760634e+01 2.02476940e+02 4.71760523e+01 2.02476686e+02 4.71760713e+01 2.02476384e+02 4.71761815e+01 2.02476334e+02 4.71764494e+01 2.02476135e+02 4.71766241e+01 2.02475822e+02 4.71765533e+01 2.02475609e+02 4.71765947e+01 2.02475563e+02 4.71767446e+01 2.02475547e+02 4.71768552e+01 2.02475641e+02 4.71770123e+01 2.02475885e+02 4.71770664e+01 2.02476027e+02 4.71770529e+01 2.02476375e+02 4.71771207e+01 2.02476447e+02 4.71771187e+01 2.02476817e+02 4.71770505e+01 2.02477061e+02 4.71769043e+01 2.02477102e+02 4.71769086e+01 2.02477348e+02 4.71770520e+01 2.02477687e+02 4.71769959e+01 2.02477837e+02 4.71767908e+01 2.02477996e+02 4.71765909e+01 2.02478005e+02 4.71765669e+01 2.02477917e+02 4.71763061e+01 2.02477913e+02 4.71762401e+01 2.02478158e+02 4.71760938e+01 2.02478386e+02 4.71759370e+01 2.02478449e+02 4.71759131e+01 2.02478810e+02 4.71759028e+01 2.02478907e+02 4.71759001e+01 2.02479232e+02 4.71759853e+01 2.02479506e+02 4.71760389e+01 2.02479491e+02 4.71757937e+01 2.02479264e+02 4.71756362e+01 2.02479287e+02 4.71756027e+01 2.02479202e+02 4.71753564e+01 2.02479211e+02 4.71752563e+01 2.02479387e+02 4.71750669e+01 2.02479579e+02 4.71750782e+01 2.02479654e+02 4.71752341e+01 2.02479714e+02 4.71753037e+01 2.02479928e+02 4.71754054e+01 2.02480022e+02 4.71754008e+01 2.02480289e+02 4.71753318e+01 2.02480628e+02 4.71752442e+01 2.02480676e+02 4.71752428e+01 2.02481085e+02 4.71752312e+01 2.02481305e+02 4.71750691e+01 2.02481288e+02 4.71747909e+01 2.02481286e+02 4.71747579e+01 2.02481434e+02 4.71745514e+01 2.02481488e+02 4.71743176e+01 2.02481226e+02 4.71741858e+01 2.02481021e+02 4.71742931e+01 2.02480674e+02 4.71742682e+01 2.02480437e+02 4.71741186e+01 2.02480187e+02 4.71739774e+01 2.02480292e+02 4.71738377e+01 2.02480455e+02 4.71737799e+01 2.02480716e+02 4.71739121e+01 2.02480920e+02 4.71739309e+01 2.02481202e+02 4.71738081e+01 2.02481356e+02 4.71737640e+01 2.02481679e+02 4.71738507e+01 2.02481777e+02 4.71741039e+01 2.02482157e+02 4.71741485e+01 2.02482376e+02 4.71742427e+01 2.02482473e+02 4.71742400e+01 2.02482824e+02 4.71743057e+01 2.02483072e+02 4.71743788e+01 2.02483169e+02 4.71743760e+01 2.02483408e+02 4.71745251e+01 2.02483768e+02 4.71745148e+01 2.02483988e+02 4.71743527e+01 2.02484061e+02 4.71743671e+01 2.02484471e+02 4.71743554e+01 2.02484519e+02 4.71743541e+01 2.02484750e+02 4.71745088e+01 2.02484760e+02 4.71745361e+01 2.02484777e+02 4.71748143e+01 2.02484779e+02 4.71748473e+01 2.02484796e+02 4.71751254e+01 2.02484823e+02 4.71751743e+01 2.02484839e+02 4.71754194e+01 2.02484809e+02 4.71754644e+01 2.02484583e+02 4.71756222e+01 2.02484526e+02 4.71756503e+01 2.02484288e+02 4.71755013e+01 2.02484052e+02 4.71755898e+01 2.02483715e+02 4.71755994e+01 2.02483563e+02 4.71755833e+01 2.02483286e+02 4.71755912e+01 2.02483138e+02 4.71756167e+01 2.02482773e+02 4.71756880e+01 2.02482712e+02 4.71756897e+01 2.02482370e+02 4.71756173e+01 2.02482132e+02 4.71754682e+01 2.02481952e+02 4.71754734e+01 2.02481873e+02 4.71756598e+01 2.02482111e+02 4.71758089e+01 2.02482090e+02 4.71758591e+01 2.02482107e+02 4.71761372e+01 2.02482510e+02 4.71761215e+01 2.02482736e+02 4.71759635e+01 2.02482784e+02 4.71759621e+01 2.02483122e+02 4.71759060e+01 2.02483352e+02 4.71758680e+01 2.02483532e+02 4.71758628e+01 2.02483751e+02 4.71757007e+01 2.02484029e+02 4.71756928e+01 2.02484310e+02 4.71758100e+01 2.02484456e+02 4.71760275e+01 2.02484658e+02 4.71762039e+01 2.02484974e+02 4.71762956e+01 2.02484900e+02 4.71764189e+01 2.02484806e+02 4.71766593e+01 2.02484509e+02 4.71766391e+01 2.02484345e+02 4.71764348e+01 2.02484138e+02 4.71762628e+01 2.02484103e+02 4.71762197e+01 2.02483958e+02 4.71760703e+01 2.02483821e+02 4.71760435e+01 2.02483553e+02 4.71761755e+01 2.02483255e+02 4.71762879e+01 2.02483031e+02 4.71764474e+01 2.02482825e+02 4.71766174e+01 2.02482829e+02 4.71769052e+01 2.02482842e+02 4.71769276e+01 2.02482971e+02 4.71771257e+01 2.02483173e+02 4.71771341e+01 2.02483365e+02 4.71771592e+01 2.02483657e+02 4.71771376e+01 2.02483886e+02 4.71770996e+01 2.02484167e+02 4.71772172e+01 2.02484249e+02 4.71772083e+01 2.02484477e+02 4.71770521e+01 2.02484712e+02 4.71768997e+01 2.02484963e+02 4.71767572e+01 2.02485276e+02 4.71766538e+01 2.02485261e+02 4.71764087e+01 2.02485172e+02 4.71762899e+01 2.02485354e+02 4.71763399e+01 2.02485569e+02 4.71765061e+01 2.02485907e+02 4.71764500e+01 2.02486078e+02 4.71762578e+01 2.02486312e+02 4.71762827e+01 2.02486655e+02 4.71763193e+01 2.02486833e+02 4.71761312e+01 2.02486962e+02 4.71761275e+01 2.02487314e+02 4.71761924e+01 2.02487546e+02 4.71762774e+01 2.02487620e+02 4.71762918e+01 2.02487958e+02 4.71762357e+01 2.02488187e+02 4.71761977e+01 2.02488461e+02 4.71762512e+01 2.02488446e+02 4.71760061e+01 2.02488231e+02 4.71758398e+01 2.02487825e+02 4.71758145e+01 2.02487822e+02 4.71755528e+01 2.02488229e+02 4.71755161e+01 2.02488247e+02 4.71755189e+01 2.02488388e+02 4.71753979e+01 2.02488445e+02 4.71753437e+01 2.02488462e+02 4.71753432e+01 2.02488806e+02 4.71754149e+01 2.02489068e+02 4.71755464e+01 2.02489357e+02 4.71756577e+01 2.02489560e+02 4.71758333e+01 2.02489572e+02 4.71760481e+01 2.02489451e+02 4.71762396e+01 2.02489453e+02 4.71762728e+01 2.02489404e+02 4.71762742e+01 2.02489002e+02 4.71762456e+01 2.02488827e+02 4.71761810e+01 2.02488529e+02 4.71762934e+01 2.02488343e+02 4.71764766e+01 2.02488439e+02 4.71766621e+01 2.02488719e+02 4.71767114e+01 2.02488781e+02 4.71767345e+01 2.02489137e+02 4.71767968e+01 2.02489313e+02 4.71769920e+01 2.02489661e+02 4.71770600e+01 2.02489892e+02 4.71771455e+01 2.02490050e+02 4.71769449e+01 2.02490309e+02 4.71769067e+01 2.02490569e+02 4.71769703e+01 2.02490666e+02 4.71769676e+01 2.02490933e+02 4.71768986e+01 2.02491166e+02 4.71769234e+01 2.02491222e+02 4.71770792e+01 2.02491273e+02 4.71771699e+01 2.02491382e+02 4.71774147e+01 2.02491348e+02 4.71774570e+01 2.02491289e+02 4.71774835e+01 2.02491087e+02 4.71775932e+01 2.02491030e+02 4.71776751e+01 2.02490993e+02 4.71778336e+01 2.02491057e+02 4.71779804e+01 2.02491349e+02 4.71780556e+01 2.02491420e+02 4.71780370e+01 2.02491640e+02 4.71779387e+01 2.02491979e+02 4.71778511e+01 2.02492174e+02 4.71776739e+01 2.02492403e+02 4.71776359e+01 2.02492583e+02 4.71776307e+01 2.02492662e+02 4.71774443e+01 2.02492692e+02 4.71773993e+01 2.02492724e+02 4.71773984e+01 2.02493100e+02 4.71774463e+01 2.02493168e+02 4.71773975e+01 2.02493416e+02 4.71772535e+01 2.02493816e+02 4.71772421e+01 2.02494035e+02 4.71774052e+01 2.02494050e+02 4.71776500e+01 2.02493852e+02 4.71778250e+01 2.02493452e+02 4.71778364e+01 2.02493376e+02 4.71778270e+01 2.02492988e+02 4.71778539e+01 2.02492873e+02 4.71778114e+01 2.02492880e+02 4.71779339e+01 2.02493074e+02 4.71781157e+01 2.02493418e+02 4.71781523e+01 2.02493467e+02 4.71781510e+01 2.02493494e+02 4.71781998e+01 2.02493596e+02 4.71783811e+01 2.02493730e+02 4.71783470e+01 2.02494096e+02 4.71783366e+01 2.02494328e+02 4.71784215e+01 2.02494425e+02 4.71784188e+01 2.02494779e+02 4.71784826e+01 2.02495024e+02 4.71785575e+01 2.02495121e+02 4.71785547e+01 2.02495482e+02 4.71785444e+01 2.02495735e+02 4.71784033e+01 2.02495767e+02 4.71784024e+01 2.02496006e+02 4.71785515e+01 2.02496041e+02 4.71785945e+01 2.02496056e+02 4.71788397e+01 2.02496393e+02 4.71789162e+01 2.02496530e+02 4.71789001e+01 2.02496640e+02 4.71787333e+01 2.02496636e+02 4.71786672e+01 2.02496710e+02 4.71786817e+01 2.02497119e+02 4.71786699e+01 2.02497160e+02 4.71786743e+01 2.02497170e+02 4.71787016e+01 2.02510298e+02 4.71872013e+01 2.02510274e+02 4.71872009e+01 2.02509917e+02 4.71871394e+01 2.02509917e+02 4.71869633e+01 2.02510156e+02 4.71869626e+01 2.02510302e+02 4.71871804e+01 2.02510298e+02 4.71872013e+01 2.02497904e+02 4.71794598e+01 2.02497856e+02 4.71794612e+01 2.02497854e+02 4.71794282e+01 2.02497895e+02 4.71794326e+01 2.02497904e+02 4.71794598e+01 2.02493026e+02 4.71764117e+01 2.02492728e+02 4.71764194e+01 2.02492733e+02 4.71762284e+01 2.02493014e+02 4.71762082e+01 2.02493026e+02 4.71764117e+01 2.02479287e+02 4.71678242e+01 2.02479261e+02 4.71678305e+01 2.02479269e+02 4.71678128e+01 2.02479284e+02 4.71678131e+01 2.02479287e+02 4.71678242e+01 2.02516272e+02 4.71912308e+01 2.02516266e+02 4.71912318e+01 2.02516267e+02 4.71912273e+01 2.02516272e+02 4.71912274e+01 2.02516272e+02 4.71912308e+01 2.02509653e+02 4.71870974e+01 2.02509493e+02 4.71871280e+01 2.02509524e+02 4.71870169e+01 2.02509640e+02 4.71870191e+01 2.02509653e+02 4.71870974e+01 2.02505595e+02 4.71845632e+01 2.02505475e+02 4.71845667e+01 2.02505416e+02 4.71844511e+01 2.02505616e+02 4.71844623e+01 2.02505595e+02 4.71845632e+01 2.02497518e+02 4.71795173e+01 2.02497333e+02 4.71795226e+01 2.02497277e+02 4.71793668e+01 2.02497510e+02 4.71793916e+01 2.02497518e+02 4.71795173e+01 2.02495010e+02 4.71779503e+01 2.02494624e+02 4.71779463e+01 2.02494628e+02 4.71777119e+01 2.02494916e+02 4.71777299e+01 2.02495010e+02 4.71779503e+01 2.02518361e+02 4.71928339e+01 2.02518046e+02 4.71928450e+01 2.02518032e+02 4.71926287e+01 2.02518356e+02 4.71926157e+01 2.02518361e+02 4.71928339e+01 2.02509237e+02 4.71871367e+01 2.02509078e+02 4.71871094e+01 2.02509064e+02 4.71870290e+01 2.02509191e+02 4.71870253e+01 2.02509237e+02 4.71871367e+01 2.02506785e+02 4.71856051e+01 2.02506689e+02 4.71856211e+01 2.02506500e+02 4.71854358e+01 2.02506504e+02 4.71854299e+01 2.02506517e+02 4.71854232e+01 2.02506801e+02 4.71855386e+01 2.02506785e+02 4.71856051e+01 2.02503442e+02 4.71835175e+01 2.02503290e+02 4.71837215e+01 2.02503112e+02 4.71837103e+01 2.02503105e+02 4.71836063e+01 2.02503357e+02 4.71834642e+01 2.02503439e+02 4.71834683e+01 2.02503442e+02 4.71835175e+01 2.02495200e+02 4.71783683e+01 2.02494922e+02 4.71783762e+01 2.02494959e+02 4.71782177e+01 2.02495144e+02 4.71782124e+01 2.02495200e+02 4.71783683e+01 2.02479250e+02 4.71683993e+01 2.02478907e+02 4.71684170e+01 2.02478920e+02 4.71681931e+01 2.02479229e+02 4.71681789e+01 2.02479250e+02 4.71683993e+01 2.02476574e+02 4.71667260e+01 2.02476348e+02 4.71667306e+01 2.02476380e+02 4.71666047e+01 2.02476564e+02 4.71665709e+01 2.02476574e+02 4.71667260e+01 2.02504606e+02 4.71845438e+01 2.02504199e+02 4.71845339e+01 2.02504150e+02 4.71842586e+01 2.02504526e+02 4.71842922e+01 2.02504606e+02 4.71845438e+01 2.02495742e+02 4.71790059e+01 2.02495617e+02 4.71791639e+01 2.02495622e+02 4.71792300e+01 2.02495723e+02 4.71794112e+01 2.02495832e+02 4.71793613e+01 2.02495994e+02 4.71792111e+01 2.02495991e+02 4.71791615e+01 2.02495963e+02 4.71789085e+01 2.02495742e+02 4.71790059e+01 2.02489528e+02 4.71751233e+01 2.02489197e+02 4.71751255e+01 2.02489184e+02 4.71749078e+01 2.02489543e+02 4.71748696e+01 2.02489528e+02 4.71751233e+01 2.02517132e+02 4.71926646e+01 2.02516975e+02 4.71926606e+01 2.02516959e+02 4.71925566e+01 2.02517105e+02 4.71925641e+01 2.02517132e+02 4.71926646e+01 2.02512170e+02 4.71895667e+01 2.02511879e+02 4.71895942e+01 2.02511879e+02 4.71893846e+01 2.02512152e+02 4.71893925e+01 2.02512170e+02 4.71895667e+01 2.02509433e+02 4.71878574e+01 2.02509385e+02 4.71878588e+01 2.02509099e+02 4.71879477e+01 2.02509096e+02 4.71880720e+01 2.02509050e+02 4.71882165e+01 2.02508800e+02 4.71882912e+01 2.02508516e+02 4.71881761e+01 2.02508506e+02 4.71881755e+01 2.02508107e+02 4.71881524e+01 2.02508023e+02 4.71878897e+01 2.02508022e+02 4.71878732e+01 2.02508205e+02 4.71876888e+01 2.02508344e+02 4.71876520e+01 2.02508685e+02 4.71877252e+01 2.02508761e+02 4.71877371e+01 2.02509075e+02 4.71876336e+01 2.02509236e+02 4.71876435e+01 2.02509416e+02 4.71878359e+01 2.02509433e+02 4.71878574e+01 2.02506354e+02 4.71859347e+01 2.02506190e+02 4.71859906e+01 2.02505896e+02 4.71859474e+01 2.02505987e+02 4.71861402e+01 2.02506282e+02 4.71862481e+01 2.02506221e+02 4.71864493e+01 2.02506019e+02 4.71866224e+01 2.02505748e+02 4.71866424e+01 2.02505542e+02 4.71866234e+01 2.02505271e+02 4.71867538e+01 2.02505153e+02 4.71867572e+01 2.02505188e+02 4.71867019e+01 2.02505287e+02 4.71864647e+01 2.02505363e+02 4.71862763e+01 2.02505082e+02 4.71861584e+01 2.02505026e+02 4.71860026e+01 2.02505199e+02 4.71858111e+01 2.02505165e+02 4.71857722e+01 2.02505039e+02 4.71855398e+01 2.02505091e+02 4.71854446e+01 2.02505156e+02 4.71854531e+01 2.02505584e+02 4.71854618e+01 2.02505624e+02 4.71854783e+01 2.02505908e+02 4.71855478e+01 2.02506206e+02 4.71856529e+01 2.02506361e+02 4.71858636e+01 2.02506354e+02 4.71859347e+01 2.02501146e+02 4.71826815e+01 2.02501042e+02 4.71829157e+01 2.02500634e+02 4.71829391e+01 2.02500576e+02 4.71826564e+01 2.02500574e+02 4.71826234e+01 2.02500601e+02 4.71823408e+01 2.02500984e+02 4.71823553e+01 2.02501139e+02 4.71825658e+01 2.02501146e+02 4.71826815e+01 2.02497982e+02 4.71807045e+01 2.02497933e+02 4.71807059e+01 2.02497931e+02 4.71806729e+01 2.02497972e+02 4.71806772e+01 2.02497982e+02 4.71807045e+01 2.02503972e+02 4.71850446e+01 2.02503912e+02 4.71850711e+01 2.02503908e+02 4.71850050e+01 2.02503970e+02 4.71850280e+01 2.02503972e+02 4.71850446e+01 2.02502672e+02 4.71842328e+01 2.02502439e+02 4.71842080e+01 2.02502431e+02 4.71840823e+01 2.02502616e+02 4.71840770e+01 2.02502672e+02 4.71842328e+01 2.02501956e+02 4.71837858e+01 2.02501679e+02 4.71837937e+01 2.02501667e+02 4.71836051e+01 2.02501900e+02 4.71836299e+01 2.02501956e+02 4.71837858e+01 2.02501241e+02 4.71833387e+01 2.02500963e+02 4.71833467e+01 2.02501000e+02 4.71831882e+01 2.02501185e+02 4.71831829e+01 2.02501241e+02 4.71833387e+01 2.02485300e+02 4.71733780e+01 2.02485294e+02 4.71734562e+01 2.02485290e+02 4.71736709e+01 2.02484992e+02 4.71736794e+01 2.02484755e+02 4.71735288e+01 2.02484787e+02 4.71733563e+01 2.02484962e+02 4.71731670e+01 2.02485256e+02 4.71731586e+01 2.02485300e+02 4.71733780e+01 2.02476931e+02 4.71681461e+01 2.02476648e+02 4.71681351e+01 2.02476485e+02 4.71679307e+01 2.02476480e+02 4.71678644e+01 2.02476625e+02 4.71678271e+01 2.02476892e+02 4.71679550e+01 2.02476931e+02 4.71681461e+01 2.02504745e+02 4.71858265e+01 2.02504647e+02 4.71858293e+01 2.02504669e+02 4.71857791e+01 2.02504740e+02 4.71857605e+01 2.02504745e+02 4.71858265e+01 2.02487151e+02 4.71748343e+01 2.02486929e+02 4.71748497e+01 2.02486637e+02 4.71747407e+01 2.02486639e+02 4.71745138e+01 2.02486979e+02 4.71744880e+01 2.02487143e+02 4.71746922e+01 2.02487151e+02 4.71748343e+01 2.02506543e+02 4.71872486e+01 2.02506237e+02 4.71872574e+01 2.02506064e+02 4.71870601e+01 2.02506111e+02 4.71869789e+01 2.02506169e+02 4.71869825e+01 2.02506490e+02 4.71870703e+01 2.02506543e+02 4.71872486e+01 2.02482323e+02 4.71721155e+01 2.02482268e+02 4.71721140e+01 2.02482270e+02 4.71720820e+01 2.02482316e+02 4.71720784e+01 2.02482323e+02 4.71721155e+01 2.02509819e+02 4.71895940e+01 2.02509652e+02 4.71896141e+01 2.02509657e+02 4.71894926e+01 2.02509806e+02 4.71895002e+01 2.02509819e+02 4.71895940e+01 2.02509335e+02 4.71892918e+01 2.02509191e+02 4.71893038e+01 2.02509166e+02 4.71891861e+01 2.02509330e+02 4.71892013e+01 2.02509335e+02 4.71892918e+01 2.02504400e+02 4.71862095e+01 2.02504167e+02 4.71861847e+01 2.02504159e+02 4.71860589e+01 2.02504388e+02 4.71860209e+01 2.02504400e+02 4.71862095e+01 2.02486690e+02 4.71751445e+01 2.02486508e+02 4.71751614e+01 2.02486280e+02 4.71750041e+01 2.02486273e+02 4.71748837e+01 2.02486450e+02 4.71748786e+01 2.02486669e+02 4.71750426e+01 2.02486690e+02 4.71751445e+01 2.02485421e+02 4.71743508e+01 2.02485403e+02 4.71743513e+01 2.02485399e+02 4.71743376e+01 2.02485427e+02 4.71743334e+01 2.02485421e+02 4.71743508e+01 2.02479515e+02 4.71706590e+01 2.02479390e+02 4.71706625e+01 2.02479392e+02 4.71705821e+01 2.02479504e+02 4.71705789e+01 2.02479515e+02 4.71706590e+01 2.02517658e+02 4.71947875e+01 2.02517621e+02 4.71947867e+01 2.02517612e+02 4.71947586e+01 2.02517654e+02 4.71947626e+01 2.02517658e+02 4.71947875e+01 2.02490251e+02 4.71776690e+01 2.02490154e+02 4.71776718e+01 2.02489800e+02 4.71776079e+01 2.02489704e+02 4.71776264e+01 2.02489714e+02 4.71776720e+01 2.02489924e+02 4.71778421e+01 2.02490075e+02 4.71778582e+01 2.02490353e+02 4.71778503e+01 2.02490533e+02 4.71778451e+01 2.02490482e+02 4.71777545e+01 2.02490251e+02 4.71776690e+01 2.02477235e+02 4.71695330e+01 2.02476921e+02 4.71695597e+01 2.02476944e+02 4.71693510e+01 2.02477222e+02 4.71693372e+01 2.02477235e+02 4.71695330e+01 2.02475963e+02 4.71687376e+01 2.02475834e+02 4.71687369e+01 2.02475814e+02 4.71686446e+01 2.02475982e+02 4.71686273e+01 2.02475963e+02 4.71687376e+01 2.02518889e+02 4.71958550e+01 2.02518801e+02 4.71958674e+01 2.02518725e+02 4.71957522e+01 2.02518894e+02 4.71957980e+01 2.02518889e+02 4.71958550e+01 2.02507790e+02 4.71889252e+01 2.02507491e+02 4.71889338e+01 2.02507459e+02 4.71887183e+01 2.02507762e+02 4.71887333e+01 2.02507790e+02 4.71889252e+01 2.02507353e+02 4.71886519e+01 2.02506975e+02 4.71886642e+01 2.02506991e+02 4.71884258e+01 2.02507348e+02 4.71883884e+01 2.02507353e+02 4.71886519e+01 2.02501005e+02 4.71846868e+01 2.02500931e+02 4.71846724e+01 2.02500521e+02 4.71846841e+01 2.02500421e+02 4.71849208e+01 2.02500458e+02 4.71850220e+01 2.02500609e+02 4.71850382e+01 2.02500841e+02 4.71848839e+01 2.02501135e+02 4.71848468e+01 2.02501380e+02 4.71849216e+01 2.02501279e+02 4.71847403e+01 2.02501005e+02 4.71846868e+01 2.02485795e+02 4.71751835e+01 2.02485549e+02 4.71752192e+01 2.02485537e+02 4.71750222e+01 2.02485787e+02 4.71750437e+01 2.02485795e+02 4.71751835e+01 2.02480973e+02 4.71721693e+01 2.02480841e+02 4.71721926e+01 2.02480869e+02 4.71721042e+01 2.02481010e+02 4.71720683e+01 2.02480973e+02 4.71721693e+01 2.02501476e+02 4.71852802e+01 2.02501558e+02 4.71855100e+01 2.02501902e+02 4.71855466e+01 2.02501885e+02 4.71852685e+01 2.02501476e+02 4.71852802e+01 2.02487522e+02 4.71765614e+01 2.02487529e+02 4.71766840e+01 2.02487681e+02 4.71768969e+01 2.02487883e+02 4.71767876e+01 2.02487940e+02 4.71767053e+01 2.02487788e+02 4.71764924e+01 2.02487522e+02 4.71765614e+01 2.02485879e+02 4.71755349e+01 2.02485608e+02 4.71755016e+01 2.02485572e+02 4.71753433e+01 2.02485791e+02 4.71753659e+01 2.02485879e+02 4.71755349e+01 2.02479430e+02 4.71715035e+01 2.02479068e+02 4.71715514e+01 2.02479037e+02 4.71712581e+01 2.02479457e+02 4.71712638e+01 2.02479430e+02 4.71715035e+01 2.02511608e+02 4.71919071e+01 2.02511497e+02 4.71921371e+01 2.02511099e+02 4.71921239e+01 2.02511084e+02 4.71918791e+01 2.02511415e+02 4.71917866e+01 2.02511550e+02 4.71917903e+01 2.02511608e+02 4.71919071e+01 2.02485991e+02 4.71759038e+01 2.02485922e+02 4.71761600e+01 2.02485584e+02 4.71761696e+01 2.02485614e+02 4.71759676e+01 2.02485940e+02 4.71758721e+01 2.02485989e+02 4.71758707e+01 2.02485991e+02 4.71759038e+01 2.02484262e+02 4.71748237e+01 2.02484265e+02 4.71748675e+01 2.02484484e+02 4.71749620e+01 2.02484469e+02 4.71747168e+01 2.02484262e+02 4.71748237e+01 2.02482003e+02 4.71734110e+01 2.02481827e+02 4.71734160e+01 2.02481593e+02 4.71732639e+01 2.02481613e+02 4.71731673e+01 2.02481764e+02 4.71731374e+01 2.02481997e+02 4.71732905e+01 2.02482003e+02 4.71734110e+01 2.02480967e+02 4.71727640e+01 2.02480942e+02 4.71727691e+01 2.02480932e+02 4.71727418e+01 2.02481050e+02 4.71726888e+01 2.02480967e+02 4.71727640e+01 2.02480506e+02 4.71724753e+01 2.02480395e+02 4.71727051e+01 2.02480098e+02 4.71727420e+01 2.02480084e+02 4.71725109e+01 2.02480464e+02 4.71724490e+01 2.02480496e+02 4.71724480e+01 2.02480506e+02 4.71724753e+01 2.02480076e+02 4.71722065e+01 2.02479934e+02 4.71724173e+01 2.02479646e+02 4.71724255e+01 2.02479707e+02 4.71722751e+01 2.02479859e+02 4.71720710e+01 2.02480145e+02 4.71720566e+01 2.02480076e+02 4.71722065e+01 2.02507598e+02 4.71897025e+01 2.02507321e+02 4.71897105e+01 2.02507357e+02 4.71895520e+01 2.02507542e+02 4.71895467e+01 2.02507598e+02 4.71897025e+01 2.02506988e+02 4.71893211e+01 2.02506966e+02 4.71893217e+01 2.02506953e+02 4.71892993e+01 2.02506983e+02 4.71893092e+01 2.02506988e+02 4.71893211e+01 2.02482090e+02 4.71737646e+01 2.02481751e+02 4.71737980e+01 2.02481773e+02 4.71735667e+01 2.02482075e+02 4.71735581e+01 2.02482090e+02 4.71737646e+01 2.02480304e+02 4.71729476e+01 2.02480430e+02 4.71731478e+01 2.02480441e+02 4.71733324e+01 2.02480169e+02 4.71733401e+01 2.02480004e+02 4.71731368e+01 2.02479999e+02 4.71730563e+01 2.02480257e+02 4.71729179e+01 2.02480291e+02 4.71729252e+01 2.02480304e+02 4.71729476e+01 2.02513475e+02 4.71939703e+01 2.02513440e+02 4.71939731e+01 2.02513434e+02 4.71939448e+01 2.02513480e+02 4.71939434e+01 2.02513475e+02 4.71939703e+01 2.02482581e+02 4.71746700e+01 2.02482282e+02 4.71747068e+01 2.02482176e+02 4.71747163e+01 2.02482054e+02 4.71748753e+01 2.02482414e+02 4.71748651e+01 2.02482488e+02 4.71748795e+01 2.02482826e+02 4.71748234e+01 2.02482880e+02 4.71745897e+01 2.02482581e+02 4.71746700e+01 2.02478114e+02 4.71718776e+01 2.02477720e+02 4.71718970e+01 2.02477716e+02 4.71716289e+01 2.02478109e+02 4.71716095e+01 2.02478114e+02 4.71718776e+01 2.02511236e+02 4.71928715e+01 2.02510936e+02 4.71928956e+01 2.02510946e+02 4.71926901e+01 2.02511225e+02 4.71926821e+01 2.02511236e+02 4.71928715e+01 2.02507782e+02 4.71907145e+01 2.02507721e+02 4.71907163e+01 2.02507689e+02 4.71906562e+01 2.02507804e+02 4.71906551e+01 2.02507782e+02 4.71907145e+01 2.02479541e+02 4.71730688e+01 2.02479431e+02 4.71732356e+01 2.02479409e+02 4.71732858e+01 2.02479190e+02 4.71734479e+01 2.02479207e+02 4.71737261e+01 2.02479556e+02 4.71737938e+01 2.02479550e+02 4.71739721e+01 2.02479404e+02 4.71741802e+01 2.02479195e+02 4.71743488e+01 2.02478834e+02 4.71744222e+01 2.02478700e+02 4.71744260e+01 2.02478420e+02 4.71743076e+01 2.02478291e+02 4.71740826e+01 2.02478624e+02 4.71739915e+01 2.02478871e+02 4.71739746e+01 2.02479008e+02 4.71739327e+01 2.02479164e+02 4.71737578e+01 2.02478934e+02 4.71736028e+01 2.02478895e+02 4.71735626e+01 2.02478793e+02 4.71733813e+01 2.02478782e+02 4.71731927e+01 2.02478740e+02 4.71730954e+01 2.02478476e+02 4.71729649e+01 2.02478488e+02 4.71727099e+01 2.02478835e+02 4.71727000e+01 2.02479035e+02 4.71728770e+01 2.02479233e+02 4.71728764e+01 2.02479527e+02 4.71728393e+01 2.02479541e+02 4.71730688e+01 2.02482535e+02 4.71752395e+01 2.02482636e+02 4.71754208e+01 2.02482784e+02 4.71753953e+01 2.02482809e+02 4.71752931e+01 2.02482535e+02 4.71752395e+01 2.02479877e+02 4.71735782e+01 2.02479832e+02 4.71735897e+01 2.02479829e+02 4.71735483e+01 2.02479918e+02 4.71735262e+01 2.02479877e+02 4.71735782e+01 2.02477570e+02 4.71721358e+01 2.02477463e+02 4.71723681e+01 2.02477406e+02 4.71724548e+01 2.02477727e+02 4.71725426e+01 2.02477659e+02 4.71727901e+01 2.02477696e+02 4.71728914e+01 2.02477941e+02 4.71729663e+01 2.02478038e+02 4.71729635e+01 2.02478277e+02 4.71731126e+01 2.02478281e+02 4.71731786e+01 2.02478296e+02 4.71734238e+01 2.02478274e+02 4.71734740e+01 2.02478226e+02 4.71734754e+01 2.02477987e+02 4.71733263e+01 2.02477578e+02 4.71733379e+01 2.02477478e+02 4.71735746e+01 2.02477399e+02 4.71737610e+01 2.02477724e+02 4.71738462e+01 2.02478004e+02 4.71739644e+01 2.02477981e+02 4.71741879e+01 2.02477629e+02 4.71742418e+01 2.02477591e+02 4.71742434e+01 2.02477216e+02 4.71743084e+01 2.02477054e+02 4.71743419e+01 2.02476858e+02 4.71741615e+01 2.02476622e+02 4.71740101e+01 2.02476644e+02 4.71739506e+01 2.02476633e+02 4.71736765e+01 2.02476631e+02 4.71736435e+01 2.02476680e+02 4.71736421e+01 2.02477089e+02 4.71736305e+01 2.02477072e+02 4.71733523e+01 2.02476663e+02 4.71733640e+01 2.02476614e+02 4.71733653e+01 2.02476308e+02 4.71734415e+01 2.02475986e+02 4.71735391e+01 2.02475937e+02 4.71735404e+01 2.02475910e+02 4.71734916e+01 2.02476007e+02 4.71732529e+01 2.02476139e+02 4.71730661e+01 2.02476137e+02 4.71730351e+01 2.02476095e+02 4.71727732e+01 2.02475734e+02 4.71727835e+01 2.02475668e+02 4.71727633e+01 2.02475667e+02 4.71727413e+01 2.02475614e+02 4.71724781e+01 2.02475603e+02 4.71724023e+01 2.02475823e+02 4.71722404e+01 2.02475950e+02 4.71722294e+01 2.02476271e+02 4.71723176e+01 2.02476551e+02 4.71724365e+01 2.02476601e+02 4.71724276e+01 2.02476809e+02 4.71722584e+01 2.02477035e+02 4.71721010e+01 2.02477122e+02 4.71720144e+01 2.02476933e+02 4.71718284e+01 2.02476942e+02 4.71717431e+01 2.02477132e+02 4.71716810e+01 2.02477294e+02 4.71718868e+01 2.02477562e+02 4.71720140e+01 2.02477570e+02 4.71721358e+01 2.02473232e+02 4.71694238e+01 2.02473143e+02 4.71694244e+01 2.02472812e+02 4.71693439e+01 2.02472878e+02 4.71692022e+01 2.02473125e+02 4.71691124e+01 2.02473226e+02 4.71693636e+01 2.02473232e+02 4.71694238e+01 2.02506502e+02 4.71905133e+01 2.02506538e+02 4.71906145e+01 2.02506784e+02 4.71906893e+01 2.02506769e+02 4.71904442e+01 2.02506502e+02 4.71905133e+01 2.02473551e+02 4.71699226e+01 2.02473342e+02 4.71699286e+01 2.02473232e+02 4.71697229e+01 2.02473542e+02 4.71697804e+01 2.02473551e+02 4.71699226e+01 2.02514387e+02 4.71957357e+01 2.02514114e+02 4.71957528e+01 2.02513982e+02 4.71955249e+01 2.02513972e+02 4.71954770e+01 2.02514043e+02 4.71954797e+01 2.02514366e+02 4.71955670e+01 2.02514387e+02 4.71957357e+01 2.02510710e+02 4.71934401e+01 2.02510637e+02 4.71934422e+01 2.02510634e+02 4.71933925e+01 2.02510689e+02 4.71934037e+01 2.02510710e+02 4.71934401e+01 2.02472629e+02 4.71696447e+01 2.02472371e+02 4.71696702e+01 2.02472442e+02 4.71695282e+01 2.02472638e+02 4.71694725e+01 2.02472629e+02 4.71696447e+01 2.02512536e+02 4.71948796e+01 2.02512296e+02 4.71950285e+01 2.02512001e+02 4.71950370e+01 2.02511973e+02 4.71948268e+01 2.02512154e+02 4.71946405e+01 2.02512522e+02 4.71946517e+01 2.02512536e+02 4.71948796e+01 2.02511531e+02 4.71942518e+01 2.02511223e+02 4.71943104e+01 2.02511265e+02 4.71940859e+01 2.02511498e+02 4.71941073e+01 2.02511531e+02 4.71942518e+01 2.02510406e+02 4.71935491e+01 2.02510020e+02 4.71936074e+01 2.02509948e+02 4.71936260e+01 2.02509684e+02 4.71936968e+01 2.02509439e+02 4.71938429e+01 2.02509182e+02 4.71938672e+01 2.02509130e+02 4.71936497e+01 2.02509389e+02 4.71935126e+01 2.02509731e+02 4.71934268e+01 2.02509779e+02 4.71934254e+01 2.02510061e+02 4.71933337e+01 2.02510390e+02 4.71932992e+01 2.02510406e+02 4.71935491e+01 2.02473502e+02 4.71704903e+01 2.02473451e+02 4.71704984e+01 2.02473340e+02 4.71703891e+01 2.02473510e+02 4.71704549e+01 2.02473502e+02 4.71704903e+01 2.02517253e+02 4.71981234e+01 2.02516998e+02 4.71981768e+01 2.02517007e+02 4.71979699e+01 2.02517282e+02 4.71979675e+01 2.02517253e+02 4.71981234e+01 2.02511720e+02 4.71946690e+01 2.02511615e+02 4.71946721e+01 2.02511610e+02 4.71946002e+01 2.02511732e+02 4.71945853e+01 2.02511720e+02 4.71946690e+01 2.02499308e+02 4.71869174e+01 2.02499192e+02 4.71871437e+01 2.02498964e+02 4.71873004e+01 2.02499026e+02 4.71873823e+01 2.02499152e+02 4.71874178e+01 2.02499504e+02 4.71873390e+01 2.02499520e+02 4.71870495e+01 2.02499554e+02 4.71869922e+01 2.02499308e+02 4.71869174e+01 2.02514087e+02 4.71964456e+01 2.02514034e+02 4.71964631e+01 2.02514058e+02 4.71964276e+01 2.02514083e+02 4.71964269e+01 2.02514087e+02 4.71964456e+01 2.02497751e+02 4.71862441e+01 2.02497568e+02 4.71864288e+01 2.02497225e+02 4.71864364e+01 2.02497007e+02 4.71862717e+01 2.02496788e+02 4.71862402e+01 2.02496734e+02 4.71864739e+01 2.02496761e+02 4.71865227e+01 2.02496776e+02 4.71867679e+01 2.02496775e+02 4.71868304e+01 2.02496874e+02 4.71870209e+01 2.02496980e+02 4.71869589e+01 2.02497386e+02 4.71869677e+01 2.02497469e+02 4.71872322e+01 2.02497807e+02 4.71871760e+01 2.02497861e+02 4.71869423e+01 2.02497470e+02 4.71869061e+01 2.02497432e+02 4.71866426e+01 2.02497646e+02 4.71864771e+01 2.02497908e+02 4.71863419e+01 2.02497889e+02 4.71862708e+01 2.02497751e+02 4.71862441e+01 2.02482056e+02 4.71764362e+01 2.02481790e+02 4.71765690e+01 2.02481477e+02 4.71766724e+01 2.02481621e+02 4.71768217e+01 2.02481758e+02 4.71768485e+01 2.02481978e+02 4.71766864e+01 2.02482255e+02 4.71766785e+01 2.02482529e+02 4.71767321e+01 2.02482514e+02 4.71764869e+01 2.02482163e+02 4.71764212e+01 2.02482056e+02 4.71764362e+01 2.02473797e+02 4.71712730e+01 2.02473758e+02 4.71715477e+01 2.02473494e+02 4.71716821e+01 2.02473275e+02 4.71718442e+01 2.02473212e+02 4.71719762e+01 2.02473150e+02 4.71720655e+01 2.02472967e+02 4.71722500e+01 2.02472941e+02 4.71725015e+01 2.02472943e+02 4.71725345e+01 2.02472961e+02 4.71728127e+01 2.02473347e+02 4.71728523e+01 2.02473378e+02 4.71731054e+01 2.02472963e+02 4.71731365e+01 2.02472922e+02 4.71728413e+01 2.02472535e+02 4.71728773e+01 2.02472429e+02 4.71728803e+01 2.02472039e+02 4.71728664e+01 2.02472006e+02 4.71728673e+01 2.02471622e+02 4.71728263e+01 2.02471522e+02 4.71725749e+01 2.02471277e+02 4.71724302e+01 2.02470967e+02 4.71723341e+01 2.02470806e+02 4.71721276e+01 2.02470804e+02 4.71720946e+01 2.02470932e+02 4.71718754e+01 2.02471156e+02 4.71718691e+01 2.02471481e+02 4.71719196e+01 2.02471464e+02 4.71716414e+01 2.02471326e+02 4.71715230e+01 2.02471581e+02 4.71715554e+01 2.02471726e+02 4.71714744e+01 2.02471982e+02 4.71713348e+01 2.02472294e+02 4.71713533e+01 2.02472597e+02 4.71714203e+01 2.02472492e+02 4.71712071e+01 2.02472508e+02 4.71710657e+01 2.02472690e+02 4.71710606e+01 2.02472863e+02 4.71712579e+01 2.02473276e+02 4.71712462e+01 2.02473234e+02 4.71709843e+01 2.02473255e+02 4.71709340e+01 2.02473297e+02 4.71709374e+01 2.02473524e+02 4.71710949e+01 2.02473802e+02 4.71712152e+01 2.02473797e+02 4.71712730e+01 2.02512789e+02 4.71959344e+01 2.02512526e+02 4.71959509e+01 2.02512357e+02 4.71957505e+01 2.02512337e+02 4.71956520e+01 2.02512483e+02 4.71956574e+01 2.02512778e+02 4.71957643e+01 2.02512789e+02 4.71959344e+01 2.02500824e+02 4.71884625e+01 2.02500639e+02 4.71884678e+01 2.02500423e+02 4.71885111e+01 2.02500468e+02 4.71885940e+01 2.02500704e+02 4.71887454e+01 2.02500794e+02 4.71887428e+01 2.02501032e+02 4.71885923e+01 2.02501027e+02 4.71885067e+01 2.02500824e+02 4.71884625e+01 2.02499585e+02 4.71876888e+01 2.02499341e+02 4.71878351e+01 2.02499467e+02 4.71880327e+01 2.02499620e+02 4.71880093e+01 2.02499798e+02 4.71878218e+01 2.02499785e+02 4.71877975e+01 2.02499585e+02 4.71876888e+01 2.02516057e+02 4.71982736e+01 2.02515989e+02 4.71982725e+01 2.02515986e+02 4.71982295e+01 2.02516049e+02 4.71982277e+01 2.02516057e+02 4.71982736e+01 2.02513941e+02 4.71969528e+01 2.02513785e+02 4.71969726e+01 2.02513793e+02 4.71968602e+01 2.02513944e+02 4.71968550e+01 2.02513941e+02 4.71969528e+01 2.02509608e+02 4.71945461e+01 2.02509583e+02 4.71945468e+01 2.02509578e+02 4.71945277e+01 2.02509618e+02 4.71945210e+01 2.02509608e+02 4.71945461e+01 2.02495694e+02 4.71858558e+01 2.02495396e+02 4.71858356e+01 2.02495192e+02 4.71858414e+01 2.02494939e+02 4.71858487e+01 2.02494733e+02 4.71856755e+01 2.02494457e+02 4.71855535e+01 2.02494136e+02 4.71854660e+01 2.02494106e+02 4.71854624e+01 2.02493692e+02 4.71855029e+01 2.02493775e+02 4.71857328e+01 2.02493991e+02 4.71858982e+01 2.02493997e+02 4.71859925e+01 2.02493792e+02 4.71860456e+01 2.02493553e+02 4.71858965e+01 2.02493404e+02 4.71859213e+01 2.02493409e+02 4.71860030e+01 2.02493619e+02 4.71861733e+01 2.02493631e+02 4.71863619e+01 2.02493318e+02 4.71864653e+01 2.02493258e+02 4.71864406e+01 2.02493013e+02 4.71862961e+01 2.02492774e+02 4.71861471e+01 2.02492418e+02 4.71860848e+01 2.02492248e+02 4.71860965e+01 2.02492032e+02 4.71860448e+01 2.02491938e+02 4.71859028e+01 2.02492028e+02 4.71857229e+01 2.02492049e+02 4.71856727e+01 2.02492032e+02 4.71853945e+01 2.02492004e+02 4.71853457e+01 2.02491860e+02 4.71851963e+01 2.02491719e+02 4.71851677e+01 2.02491751e+02 4.71852769e+01 2.02491718e+02 4.71854659e+01 2.02491696e+02 4.71856425e+01 2.02491751e+02 4.71857858e+01 2.02491570e+02 4.71857361e+01 2.02491210e+02 4.71856768e+01 2.02491096e+02 4.71856755e+01 2.02490751e+02 4.71857593e+01 2.02490677e+02 4.71857449e+01 2.02490650e+02 4.71856961e+01 2.02490520e+02 4.71855361e+01 2.02490368e+02 4.71855200e+01 2.02490136e+02 4.71856742e+01 2.02490047e+02 4.71858857e+01 2.02490285e+02 4.71860347e+01 2.02490695e+02 4.71860231e+01 2.02490766e+02 4.71860045e+01 2.02490982e+02 4.71861707e+01 2.02490984e+02 4.71862037e+01 2.02491001e+02 4.71864819e+01 2.02491349e+02 4.71865499e+01 2.02491478e+02 4.71867800e+01 2.02491505e+02 4.71868288e+01 2.02491520e+02 4.71870739e+01 2.02491881e+02 4.71870636e+01 2.02491975e+02 4.71868232e+01 2.02491999e+02 4.71867202e+01 2.02492060e+02 4.71865768e+01 2.02492176e+02 4.71865892e+01 2.02492437e+02 4.71867219e+01 2.02492771e+02 4.71868005e+01 2.02492936e+02 4.71870036e+01 2.02493130e+02 4.71871858e+01 2.02493486e+02 4.71871687e+01 2.02493481e+02 4.71869263e+01 2.02493499e+02 4.71868781e+01 2.02493571e+02 4.71868595e+01 2.02493787e+02 4.71870254e+01 2.02494187e+02 4.71870553e+01 2.02494287e+02 4.71873066e+01 2.02494502e+02 4.71874729e+01 2.02494911e+02 4.71874612e+01 2.02494829e+02 4.71872313e+01 2.02494773e+02 4.71870755e+01 2.02494713e+02 4.71869915e+01 2.02494491e+02 4.71868994e+01 2.02494417e+02 4.71868849e+01 2.02494105e+02 4.71867904e+01 2.02494026e+02 4.71866088e+01 2.02494040e+02 4.71865129e+01 2.02494028e+02 4.71863107e+01 2.02494258e+02 4.71863517e+01 2.02494624e+02 4.71863839e+01 2.02494687e+02 4.71863600e+01 2.02495048e+02 4.71863497e+01 2.02495122e+02 4.71863641e+01 2.02495124e+02 4.71863972e+01 2.02495206e+02 4.71866270e+01 2.02495550e+02 4.71866636e+01 2.02495599e+02 4.71866622e+01 2.02495837e+02 4.71868113e+01 2.02496140e+02 4.71867329e+01 2.02496164e+02 4.71865697e+01 2.02496108e+02 4.71864139e+01 2.02496421e+02 4.71863104e+01 2.02496268e+02 4.71861675e+01 2.02496038e+02 4.71860121e+01 2.02495788e+02 4.71858717e+01 2.02495694e+02 4.71858558e+01 2.02486232e+02 4.71799437e+01 2.02486090e+02 4.71801542e+01 2.02486133e+02 4.71803193e+01 2.02486189e+02 4.71805155e+01 2.02485854e+02 4.71805250e+01 2.02485775e+02 4.71805555e+01 2.02485709e+02 4.71806324e+01 2.02485721e+02 4.71808210e+01 2.02485776e+02 4.71809081e+01 2.02485877e+02 4.71809188e+01 2.02486215e+02 4.71809092e+01 2.02486335e+02 4.71809058e+01 2.02486673e+02 4.71808961e+01 2.02486819e+02 4.71809088e+01 2.02487063e+02 4.71809332e+01 2.02487295e+02 4.71809071e+01 2.02487267e+02 4.71807825e+01 2.02486975e+02 4.71807073e+01 2.02486903e+02 4.71807258e+01 2.02486594e+02 4.71806292e+01 2.02486297e+02 4.71805235e+01 2.02486321e+02 4.71802988e+01 2.02486531e+02 4.71801307e+01 2.02486576e+02 4.71799918e+01 2.02486232e+02 4.71799437e+01 2.02512394e+02 4.71965852e+01 2.02512097e+02 4.71965938e+01 2.02512084e+02 4.71963916e+01 2.02512382e+02 4.71963831e+01 2.02512394e+02 4.71965852e+01 2.02491865e+02 4.71837628e+01 2.02491942e+02 4.71838341e+01 2.02492023e+02 4.71838615e+01 2.02492002e+02 4.71837896e+01 2.02491865e+02 4.71837628e+01 2.02488882e+02 4.71818992e+01 2.02488842e+02 4.71818953e+01 2.02488832e+02 4.71818681e+01 2.02488904e+02 4.71818495e+01 2.02488882e+02 4.71818992e+01 2.02488546e+02 4.71816890e+01 2.02488229e+02 4.71816980e+01 2.02488216e+02 4.71814826e+01 2.02488564e+02 4.71814502e+01 2.02488546e+02 4.71816890e+01 2.02478439e+02 4.71753719e+01 2.02478295e+02 4.71753760e+01 2.02478289e+02 4.71752784e+01 2.02478455e+02 4.71752577e+01 2.02478439e+02 4.71753719e+01 2.02477787e+02 4.71749644e+01 2.02477522e+02 4.71749719e+01 2.02477221e+02 4.71748690e+01 2.02477204e+02 4.71746000e+01 2.02477572e+02 4.71746093e+01 2.02477776e+02 4.71747840e+01 2.02477787e+02 4.71749644e+01 2.02475590e+02 4.71735906e+01 2.02475423e+02 4.71735953e+01 2.02475241e+02 4.71734044e+01 2.02475247e+02 4.71733766e+01 2.02475288e+02 4.71733700e+01 2.02475627e+02 4.71734446e+01 2.02475590e+02 4.71735906e+01 2.02474139e+02 4.71726836e+01 2.02474023e+02 4.71726779e+01 2.02473998e+02 4.71725955e+01 2.02474134e+02 4.71725963e+01 2.02474139e+02 4.71726836e+01 2.02471900e+02 4.71712838e+01 2.02471535e+02 4.71712642e+01 2.02471537e+02 4.71710570e+01 2.02471841e+02 4.71710377e+01 2.02471900e+02 4.71712838e+01 2.02489935e+02 4.71831551e+01 2.02489776e+02 4.71831573e+01 2.02489743e+02 4.71830351e+01 2.02489988e+02 4.71830010e+01 2.02489935e+02 4.71831551e+01 2.02511444e+02 4.71968889e+01 2.02511276e+02 4.71968751e+01 2.02511258e+02 4.71967730e+01 2.02511434e+02 4.71967582e+01 2.02511444e+02 4.71968889e+01 2.02495645e+02 4.71870222e+01 2.02495551e+02 4.71872626e+01 2.02495207e+02 4.71873465e+01 2.02495222e+02 4.71875916e+01 2.02495460e+02 4.71877406e+01 2.02495696e+02 4.71876521e+01 2.02495947e+02 4.71875095e+01 2.02495910e+02 4.71874082e+01 2.02495896e+02 4.71871788e+01 2.02495868e+02 4.71871141e+01 2.02495645e+02 4.71870222e+01 2.02490844e+02 4.71840221e+01 2.02490726e+02 4.71842481e+01 2.02490476e+02 4.71842670e+01 2.02490496e+02 4.71841044e+01 2.02490808e+02 4.71839999e+01 2.02490842e+02 4.71839965e+01 2.02490844e+02 4.71840221e+01 2.02484547e+02 4.71800876e+01 2.02484605e+02 4.71801469e+01 2.02484569e+02 4.71804002e+01 2.02484262e+02 4.71804008e+01 2.02484111e+02 4.71804133e+01 2.02483901e+02 4.71805809e+01 2.02483543e+02 4.71806065e+01 2.02483561e+02 4.71803685e+01 2.02483556e+02 4.71802722e+01 2.02483497e+02 4.71800295e+01 2.02483876e+02 4.71800350e+01 2.02484076e+02 4.71800925e+01 2.02484313e+02 4.71799413e+01 2.02484530e+02 4.71798770e+01 2.02484547e+02 4.71800876e+01 2.02483144e+02 4.71792107e+01 2.02483105e+02 4.71793039e+01 2.02483379e+02 4.71793574e+01 2.02483230e+02 4.71792116e+01 2.02483144e+02 4.71792107e+01 2.02478632e+02 4.71763902e+01 2.02478487e+02 4.71765354e+01 2.02478723e+02 4.71764469e+01 2.02478746e+02 4.71763439e+01 2.02478632e+02 4.71763902e+01 2.02475892e+02 4.71746772e+01 2.02475709e+02 4.71748623e+01 2.02475385e+02 4.71749588e+01 2.02475468e+02 4.71751887e+01 2.02475524e+02 4.71753446e+01 2.02475560e+02 4.71754458e+01 2.02475711e+02 4.71754620e+01 2.02475790e+02 4.71752756e+01 2.02475812e+02 4.71752254e+01 2.02476031e+02 4.71750633e+01 2.02476250e+02 4.71749012e+01 2.02476233e+02 4.71746230e+01 2.02475892e+02 4.71746772e+01 2.02474029e+02 4.71735127e+01 2.02473808e+02 4.71734875e+01 2.02473753e+02 4.71733398e+01 2.02473953e+02 4.71733807e+01 2.02474029e+02 4.71735127e+01 2.02512013e+02 4.71975435e+01 2.02511674e+02 4.71976311e+01 2.02511570e+02 4.71976340e+01 2.02511591e+02 4.71975791e+01 2.02511637e+02 4.71973086e+01 2.02511978e+02 4.71973327e+01 2.02512013e+02 4.71975435e+01 2.02496236e+02 4.71876902e+01 2.02496272e+02 4.71877914e+01 2.02496518e+02 4.71878663e+01 2.02496364e+02 4.71877233e+01 2.02496236e+02 4.71876902e+01 2.02489939e+02 4.71837561e+01 2.02489798e+02 4.71837922e+01 2.02489790e+02 4.71836627e+01 2.02489944e+02 4.71836839e+01 2.02489939e+02 4.71837561e+01 2.02474798e+02 4.71742923e+01 2.02474504e+02 4.71742743e+01 2.02474450e+02 4.71740747e+01 2.02474787e+02 4.71740651e+01 2.02474798e+02 4.71742923e+01 2.02470727e+02 4.71717473e+01 2.02470429e+02 4.71717557e+01 2.02470208e+02 4.71717215e+01 2.02469984e+02 4.71717594e+01 2.02469829e+02 4.71715488e+01 2.02469857e+02 4.71715025e+01 2.02469978e+02 4.71714387e+01 2.02470135e+02 4.71713771e+01 2.02470511e+02 4.71713699e+01 2.02470715e+02 4.71715447e+01 2.02470727e+02 4.71717473e+01 2.02492677e+02 4.71857657e+01 2.02492684e+02 4.71858883e+01 2.02492865e+02 4.71858832e+01 2.02492814e+02 4.71857925e+01 2.02492677e+02 4.71857657e+01 2.02487918e+02 4.71827924e+01 2.02487568e+02 4.71828726e+01 2.02487476e+02 4.71829051e+01 2.02487516e+02 4.71828405e+01 2.02487636e+02 4.71826159e+01 2.02487905e+02 4.71825880e+01 2.02487918e+02 4.71827924e+01 2.02477557e+02 4.71763164e+01 2.02477460e+02 4.71763191e+01 2.02477481e+02 4.71762689e+01 2.02477553e+02 4.71762503e+01 2.02477557e+02 4.71763164e+01 2.02512085e+02 4.71981862e+01 2.02511689e+02 4.71981976e+01 2.02511672e+02 4.71979286e+01 2.02512040e+02 4.71979378e+01 2.02512085e+02 4.71981862e+01 2.02488070e+02 4.71831863e+01 2.02487999e+02 4.71834411e+01 2.02487745e+02 4.71835816e+01 2.02487372e+02 4.71836477e+01 2.02487351e+02 4.71836485e+01 2.02487354e+02 4.71836365e+01 2.02487416e+02 4.71833762e+01 2.02487538e+02 4.71831849e+01 2.02487511e+02 4.71831361e+01 2.02487577e+02 4.71831563e+01 2.02488002e+02 4.71831441e+01 2.02488066e+02 4.71831203e+01 2.02488070e+02 4.71831863e+01 2.02473085e+02 4.71738201e+01 2.02472911e+02 4.71738251e+01 2.02472920e+02 4.71737170e+01 2.02473092e+02 4.71736918e+01 2.02473085e+02 4.71738201e+01 2.02472433e+02 4.71734119e+01 2.02472111e+02 4.71734405e+01 2.02472156e+02 4.71732387e+01 2.02472420e+02 4.71732120e+01 2.02472433e+02 4.71734119e+01 2.02494743e+02 4.71876549e+01 2.02494895e+02 4.71878332e+01 2.02494941e+02 4.71880777e+01 2.02494736e+02 4.71882487e+01 2.02494713e+02 4.71882934e+01 2.02494944e+02 4.71883788e+01 2.02495163e+02 4.71882167e+01 2.02495148e+02 4.71879716e+01 2.02495169e+02 4.71879214e+01 2.02495152e+02 4.71876432e+01 2.02494743e+02 4.71876549e+01 2.02470125e+02 4.71722684e+01 2.02469720e+02 4.71723143e+01 2.02469651e+02 4.71725705e+01 2.02469314e+02 4.71725801e+01 2.02469191e+02 4.71723459e+01 2.02469227e+02 4.71723053e+01 2.02469260e+02 4.71722943e+01 2.02469670e+02 4.71722827e+01 2.02469673e+02 4.71719896e+01 2.02469675e+02 4.71719868e+01 2.02469682e+02 4.71719824e+01 2.02470097e+02 4.71720016e+01 2.02470125e+02 4.71722684e+01 2.02513895e+02 4.71999148e+01 2.02513769e+02 4.71999139e+01 2.02513781e+02 4.71998436e+01 2.02513858e+02 4.71998483e+01 2.02513895e+02 4.71999148e+01 2.02502278e+02 4.71926605e+01 2.02502314e+02 4.71927618e+01 2.02502434e+02 4.71927584e+01 2.02502406e+02 4.71926937e+01 2.02502278e+02 4.71926605e+01 2.02493590e+02 4.71872335e+01 2.02493478e+02 4.71874629e+01 2.02493367e+02 4.71876612e+01 2.02493670e+02 4.71875828e+01 2.02493963e+02 4.71875457e+01 2.02494209e+02 4.71876206e+01 2.02494194e+02 4.71873754e+01 2.02493806e+02 4.71873366e+01 2.02493590e+02 4.71872335e+01 2.02470904e+02 4.71730545e+01 2.02470864e+02 4.71730612e+01 2.02470862e+02 4.71730281e+01 2.02470933e+02 4.71730096e+01 2.02470904e+02 4.71730545e+01 2.02495761e+02 4.71888892e+01 2.02495906e+02 4.71890385e+01 2.02496101e+02 4.71892195e+01 2.02496328e+02 4.71893772e+01 2.02496492e+02 4.71895814e+01 2.02496496e+02 4.71896475e+01 2.02496626e+02 4.71898075e+01 2.02496872e+02 4.71898823e+01 2.02496946e+02 4.71898967e+01 2.02497355e+02 4.71898850e+01 2.02497240e+02 4.71896793e+01 2.02497099e+02 4.71894578e+01 2.02496722e+02 4.71894111e+01 2.02496482e+02 4.71892633e+01 2.02496245e+02 4.71891131e+01 2.02496122e+02 4.71888789e+01 2.02495761e+02 4.71888892e+01 2.02481852e+02 4.71801980e+01 2.02481559e+02 4.71801213e+01 2.02481453e+02 4.71799487e+01 2.02481744e+02 4.71799846e+01 2.02481852e+02 4.71801980e+01 2.02513194e+02 4.72003740e+01 2.02513122e+02 4.72003926e+01 2.02513118e+02 4.72003266e+01 2.02513192e+02 4.72003410e+01 2.02513194e+02 4.72003740e+01 2.02488781e+02 4.71851263e+01 2.02488658e+02 4.71852854e+01 2.02488873e+02 4.71854516e+01 2.02489211e+02 4.71853955e+01 2.02489203e+02 4.71852080e+01 2.02488842e+02 4.71851492e+01 2.02488781e+02 4.71851263e+01 2.02487973e+02 4.71846217e+01 2.02487880e+02 4.71848628e+01 2.02487888e+02 4.71848781e+01 2.02487863e+02 4.71851512e+01 2.02487784e+02 4.71852804e+01 2.02488023e+02 4.71854294e+01 2.02488367e+02 4.71854661e+01 2.02488350e+02 4.71851879e+01 2.02488348e+02 4.71851549e+01 2.02488404e+02 4.71848909e+01 2.02488440e+02 4.71847957e+01 2.02488213e+02 4.71846380e+01 2.02487973e+02 4.71846217e+01 2.02472870e+02 4.71751817e+01 2.02472817e+02 4.71751960e+01 2.02472833e+02 4.71751586e+01 2.02472863e+02 4.71751619e+01 2.02472870e+02 4.71751817e+01 2.02471190e+02 4.71741309e+01 2.02471178e+02 4.71741302e+01 2.02471177e+02 4.71741233e+01 2.02471189e+02 4.71741216e+01 2.02471190e+02 4.71741309e+01 2.02491729e+02 4.71872679e+01 2.02491798e+02 4.71875194e+01 2.02492103e+02 4.71876193e+01 2.02492378e+02 4.71876729e+01 2.02492235e+02 4.71875220e+01 2.02492155e+02 4.71872558e+01 2.02491729e+02 4.71872679e+01 2.02490809e+02 4.71866928e+01 2.02490910e+02 4.71868741e+01 2.02491091e+02 4.71868690e+01 2.02491083e+02 4.71867464e+01 2.02490809e+02 4.71866928e+01 2.02490139e+02 4.71862743e+01 2.02490085e+02 4.71865080e+01 2.02490347e+02 4.71866399e+01 2.02490708e+02 4.71866296e+01 2.02490693e+02 4.71863844e+01 2.02490477e+02 4.71862182e+01 2.02490139e+02 4.71862743e+01 2.02474978e+02 4.71767989e+01 2.02474766e+02 4.71769656e+01 2.02474740e+02 4.71770277e+01 2.02474860e+02 4.71770243e+01 2.02475119e+02 4.71768871e+01 2.02475195e+02 4.71766915e+01 2.02474978e+02 4.71767989e+01 2.02506716e+02 4.71969280e+01 2.02506730e+02 4.71969817e+01 2.02506820e+02 4.71969928e+01 2.02506798e+02 4.71969318e+01 2.02506716e+02 4.71969280e+01 2.02486580e+02 4.71843497e+01 2.02486290e+02 4.71844674e+01 2.02486307e+02 4.71847455e+01 2.02486610e+02 4.71846672e+01 2.02486936e+02 4.71845718e+01 2.02486853e+02 4.71843419e+01 2.02486580e+02 4.71843497e+01 2.02470795e+02 4.71744824e+01 2.02470698e+02 4.71744851e+01 2.02470719e+02 4.71744349e+01 2.02470756e+02 4.71744421e+01 2.02470795e+02 4.71744824e+01 2.02509838e+02 4.71991763e+01 2.02509836e+02 4.71992422e+01 2.02509923e+02 4.71992292e+01 2.02510058e+02 4.71990779e+01 2.02509838e+02 4.71991763e+01 2.02485813e+02 4.71841693e+01 2.02485830e+02 4.71844474e+01 2.02486239e+02 4.71844358e+01 2.02486103e+02 4.71842453e+01 2.02485813e+02 4.71841693e+01 2.02470911e+02 4.71748540e+01 2.02470628e+02 4.71748621e+01 2.02470616e+02 4.71746697e+01 2.02470899e+02 4.71746617e+01 2.02470911e+02 4.71748540e+01 2.02506430e+02 4.71973476e+01 2.02506202e+02 4.71975040e+01 2.02506213e+02 4.71976895e+01 2.02506379e+02 4.71978925e+01 2.02506414e+02 4.71979356e+01 2.02506289e+02 4.71981565e+01 2.02506296e+02 4.71982790e+01 2.02506571e+02 4.71983326e+01 2.02506790e+02 4.71981704e+01 2.02506884e+02 4.71979300e+01 2.02506890e+02 4.71978398e+01 2.02506966e+02 4.71976823e+01 2.02506934e+02 4.71974824e+01 2.02506680e+02 4.71973446e+01 2.02506430e+02 4.71973476e+01 2.02490961e+02 4.71876850e+01 2.02490683e+02 4.71876930e+01 2.02490671e+02 4.71875044e+01 2.02490949e+02 4.71874964e+01 2.02490961e+02 4.71876850e+01 2.02496816e+02 4.71916424e+01 2.02496631e+02 4.71918256e+01 2.02496534e+02 4.71918284e+01 2.02496530e+02 4.71917624e+01 2.02496774e+02 4.71916161e+01 2.02496815e+02 4.71916204e+01 2.02496816e+02 4.71916424e+01 2.02491348e+02 4.71882263e+01 2.02491304e+02 4.71882101e+01 2.02491294e+02 4.71881925e+01 2.02491347e+02 4.71881781e+01 2.02491348e+02 4.71882263e+01 2.02485638e+02 4.71846584e+01 2.02485795e+02 4.71847985e+01 2.02486014e+02 4.71848932e+01 2.02485999e+02 4.71846481e+01 2.02485638e+02 4.71846584e+01 2.02483824e+02 4.71835246e+01 2.02483485e+02 4.71836122e+01 2.02483413e+02 4.71836308e+01 2.02483053e+02 4.71836410e+01 2.02482987e+02 4.71836209e+01 2.02482561e+02 4.71836330e+01 2.02482498e+02 4.71836569e+01 2.02482137e+02 4.71836671e+01 2.02482040e+02 4.71836699e+01 2.02481686e+02 4.71836060e+01 2.02481582e+02 4.71836192e+01 2.02481188e+02 4.71836721e+01 2.02481002e+02 4.71838553e+01 2.02480908e+02 4.71840957e+01 2.02480798e+02 4.71842625e+01 2.02481018e+02 4.71841642e+01 2.02481284e+02 4.71840315e+01 2.02481561e+02 4.71840236e+01 2.02481742e+02 4.71840184e+01 2.02481930e+02 4.71838367e+01 2.02482267e+02 4.71838271e+01 2.02482441e+02 4.71840240e+01 2.02482785e+02 4.71840721e+01 2.02483004e+02 4.71839100e+01 2.02483068e+02 4.71838862e+01 2.02483428e+02 4.71838759e+01 2.02483502e+02 4.71838903e+01 2.02483912e+02 4.71838787e+01 2.02483983e+02 4.71838601e+01 2.02484250e+02 4.71837911e+01 2.02484329e+02 4.71836047e+01 2.02484004e+02 4.71835195e+01 2.02483824e+02 4.71835246e+01 2.02507130e+02 4.71983827e+01 2.02507033e+02 4.71983855e+01 2.02506672e+02 4.71983958e+01 2.02506663e+02 4.71986592e+01 2.02506895e+02 4.71988129e+01 2.02507265e+02 4.71987661e+01 2.02507506e+02 4.71986175e+01 2.02507322e+02 4.71984970e+01 2.02507130e+02 4.71983827e+01 2.02497202e+02 4.71921824e+01 2.02496991e+02 4.71921412e+01 2.02496913e+02 4.71920018e+01 2.02497146e+02 4.71920266e+01 2.02497202e+02 4.71921824e+01 2.02492681e+02 4.71893580e+01 2.02492389e+02 4.71894746e+01 2.02492228e+02 4.71894792e+01 2.02491924e+02 4.71893790e+01 2.02491911e+02 4.71891764e+01 2.02492229e+02 4.71891532e+01 2.02492347e+02 4.71891493e+01 2.02492668e+02 4.71891541e+01 2.02492681e+02 4.71893580e+01 2.02490533e+02 4.71880160e+01 2.02490235e+02 4.71880245e+01 2.02490247e+02 4.71878377e+01 2.02490555e+02 4.71877878e+01 2.02490533e+02 4.71880160e+01 2.02487063e+02 4.71858481e+01 2.02486891e+02 4.71860395e+01 2.02486730e+02 4.71860599e+01 2.02486674e+02 4.71859040e+01 2.02487012e+02 4.71858164e+01 2.02486930e+02 4.71855866e+01 2.02486586e+02 4.71855499e+01 2.02486514e+02 4.71855685e+01 2.02486544e+02 4.71855236e+01 2.02486475e+02 4.71852721e+01 2.02486166e+02 4.71851753e+01 2.02485994e+02 4.71851802e+01 2.02486002e+02 4.71852967e+01 2.02485961e+02 4.71854584e+01 2.02485776e+02 4.71854636e+01 2.02485505e+02 4.71853387e+01 2.02485300e+02 4.71853446e+01 2.02484974e+02 4.71854400e+01 2.02484755e+02 4.71856022e+01 2.02484772e+02 4.71858803e+01 2.02485078e+02 4.71858042e+01 2.02485267e+02 4.71856235e+01 2.02485571e+02 4.71856148e+01 2.02485826e+02 4.71857519e+01 2.02485840e+02 4.71859813e+01 2.02485730e+02 4.71861482e+01 2.02485734e+02 4.71862142e+01 2.02485489e+02 4.71863605e+01 2.02485507e+02 4.71866387e+01 2.02485916e+02 4.71866270e+01 2.02485988e+02 4.71866084e+01 2.02486254e+02 4.71865394e+01 2.02486488e+02 4.71865642e+01 2.02486832e+02 4.71866009e+01 2.02486880e+02 4.71865995e+01 2.02487289e+02 4.71865878e+01 2.02487521e+02 4.71864336e+01 2.02487581e+02 4.71864071e+01 2.02487801e+02 4.71863092e+01 2.02487811e+02 4.71862368e+01 2.02487549e+02 4.71861048e+01 2.02487355e+02 4.71859233e+01 2.02487063e+02 4.71858481e+01 2.02484320e+02 4.71841339e+01 2.02484356e+02 4.71842352e+01 2.02484461e+02 4.71842220e+01 2.02484500e+02 4.71841288e+01 2.02484320e+02 4.71841339e+01 2.02494741e+02 4.71909445e+01 2.02494668e+02 4.71909301e+01 2.02494665e+02 4.71908971e+01 2.02494737e+02 4.71908785e+01 2.02494741e+02 4.71909445e+01 2.02503325e+02 4.71966049e+01 2.02503277e+02 4.71966063e+01 2.02503249e+02 4.71965575e+01 2.02503323e+02 4.71965719e+01 2.02503325e+02 4.71966049e+01 2.02492421e+02 4.71897939e+01 2.02492236e+02 4.71897992e+01 2.02492228e+02 4.71896734e+01 2.02492413e+02 4.71896681e+01 2.02492421e+02 4.71897939e+01 2.02486224e+02 4.71859220e+01 2.02486028e+02 4.71859276e+01 2.02486020e+02 4.71857947e+01 2.02486216e+02 4.71857891e+01 2.02486224e+02 4.71859220e+01 2.02483674e+02 4.71843286e+01 2.02483650e+02 4.71844316e+01 2.02483799e+02 4.71844069e+01 2.02483823e+02 4.71843039e+01 2.02483674e+02 4.71843286e+01 2.02469400e+02 4.71754053e+01 2.02469022e+02 4.71753979e+01 2.02469029e+02 4.71751736e+01 2.02469357e+02 4.71751504e+01 2.02469400e+02 4.71754053e+01 2.02500831e+02 4.71953467e+01 2.02500568e+02 4.71953542e+01 2.02500553e+02 4.71951726e+01 2.02500780e+02 4.71951976e+01 2.02500831e+02 4.71953467e+01 2.02499833e+02 4.71947232e+01 2.02499654e+02 4.71947284e+01 2.02499646e+02 4.71946066e+01 2.02499791e+02 4.71946272e+01 2.02499833e+02 4.71947232e+01 2.02495351e+02 4.71919236e+01 2.02495074e+02 4.71919316e+01 2.02494893e+02 4.71919367e+01 2.02494930e+02 4.71920380e+01 2.02495175e+02 4.71921128e+01 2.02495272e+02 4.71921101e+01 2.02495633e+02 4.71920997e+01 2.02495618e+02 4.71918546e+01 2.02495351e+02 4.71919236e+01 2.02468804e+02 4.71753322e+01 2.02468666e+02 4.71753361e+01 2.02468658e+02 4.71752409e+01 2.02468780e+02 4.71752519e+01 2.02468804e+02 4.71753322e+01 2.02504639e+02 4.71980236e+01 2.02504456e+02 4.71980123e+01 2.02504138e+02 4.71980097e+01 2.02504015e+02 4.71980132e+01 2.02503666e+02 4.71979457e+01 2.02503615e+02 4.71976832e+01 2.02504037e+02 4.71976710e+01 2.02504242e+02 4.71977759e+01 2.02504343e+02 4.71977708e+01 2.02504607e+02 4.71979008e+01 2.02504639e+02 4.71980236e+01 2.02500284e+02 4.71953039e+01 2.02500213e+02 4.71952913e+01 2.02500211e+02 4.71952583e+01 2.02500283e+02 4.71952397e+01 2.02500284e+02 4.71953039e+01 2.02499094e+02 4.71945606e+01 2.02498997e+02 4.71945634e+01 2.02499018e+02 4.71945132e+01 2.02499090e+02 4.71944946e+01 2.02499094e+02 4.71945606e+01 2.02497947e+02 4.71938441e+01 2.02497762e+02 4.71938494e+01 2.02497754e+02 4.71937236e+01 2.02497954e+02 4.71937071e+01 2.02497947e+02 4.71938441e+01 2.02480850e+02 4.71831622e+01 2.02480513e+02 4.71831718e+01 2.02480361e+02 4.71831556e+01 2.02480150e+02 4.71831144e+01 2.02479816e+02 4.71830358e+01 2.02479665e+02 4.71830196e+01 2.02479387e+02 4.71830275e+01 2.02479113e+02 4.71829739e+01 2.02479128e+02 4.71832191e+01 2.02479489e+02 4.71832088e+01 2.02479586e+02 4.71832060e+01 2.02479565e+02 4.71832562e+01 2.02479582e+02 4.71835344e+01 2.02479991e+02 4.71835228e+01 2.02480032e+02 4.71835271e+01 2.02480347e+02 4.71834457e+01 2.02480643e+02 4.71833318e+01 2.02480740e+02 4.71833290e+01 2.02480981e+02 4.71832440e+01 2.02480999e+02 4.71831375e+01 2.02480850e+02 4.71831622e+01 2.02475396e+02 4.71797531e+01 2.02475161e+02 4.71799054e+01 2.02475122e+02 4.71799986e+01 2.02475396e+02 4.71800522e+01 2.02475616e+02 4.71798901e+01 2.02475485e+02 4.71797301e+01 2.02475396e+02 4.71797531e+01 2.02473950e+02 4.71788488e+01 2.02473564e+02 4.71789070e+01 2.02473345e+02 4.71790691e+01 2.02473117e+02 4.71792259e+01 2.02472932e+02 4.71794091e+01 2.02472835e+02 4.71794118e+01 2.02472642e+02 4.71795272e+01 2.02472406e+02 4.71796789e+01 2.02472308e+02 4.71798010e+01 2.02472313e+02 4.71799201e+01 2.02472331e+02 4.71801094e+01 2.02472547e+02 4.71800661e+01 2.02472876e+02 4.71800317e+01 2.02472957e+02 4.71800233e+01 2.02473281e+02 4.71799265e+01 2.02473269e+02 4.71797411e+01 2.02473214e+02 4.71795853e+01 2.02473505e+02 4.71794683e+01 2.02473700e+02 4.71792912e+01 2.02473920e+02 4.71791291e+01 2.02474091e+02 4.71789369e+01 2.02474055e+02 4.71788356e+01 2.02473950e+02 4.71788488e+01 2.02469187e+02 4.71758711e+01 2.02468875e+02 4.71758321e+01 2.02468728e+02 4.71756155e+01 2.02468726e+02 4.71755825e+01 2.02468774e+02 4.71755811e+01 2.02469143e+02 4.71756341e+01 2.02469187e+02 4.71758711e+01 2.02507909e+02 4.72003644e+01 2.02507869e+02 4.72003711e+01 2.02507841e+02 4.72003223e+01 2.02507915e+02 4.72003367e+01 2.02507909e+02 4.72003644e+01 2.02500281e+02 4.71956011e+01 2.02500434e+02 4.71957789e+01 2.02500425e+02 4.71959901e+01 2.02500087e+02 4.71960354e+01 2.02499854e+02 4.71958825e+01 2.02499817e+02 4.71956105e+01 2.02500230e+02 4.71955695e+01 2.02500299e+02 4.71955529e+01 2.02500281e+02 4.71956011e+01 2.02499746e+02 4.71952670e+01 2.02499517e+02 4.71954233e+01 2.02499172e+02 4.71954098e+01 2.02499159e+02 4.71951998e+01 2.02499278e+02 4.71950064e+01 2.02499251e+02 4.71949576e+01 2.02499324e+02 4.71949720e+01 2.02499745e+02 4.71949866e+01 2.02499746e+02 4.71952670e+01 2.02493864e+02 4.71915930e+01 2.02493767e+02 4.71915958e+01 2.02493528e+02 4.71914468e+01 2.02493527e+02 4.71913826e+01 2.02493621e+02 4.71913780e+01 2.02493860e+02 4.71915270e+01 2.02493864e+02 4.71915930e+01 2.02493105e+02 4.71911185e+01 2.02493052e+02 4.71913846e+01 2.02492719e+02 4.71913941e+01 2.02492750e+02 4.71911961e+01 2.02493095e+02 4.71911122e+01 2.02493101e+02 4.71911121e+01 2.02493105e+02 4.71911185e+01 2.02490719e+02 4.71896284e+01 2.02490828e+02 4.71898633e+01 2.02490837e+02 4.71900009e+01 2.02490766e+02 4.71902347e+01 2.02490801e+02 4.71902778e+01 2.02490704e+02 4.71902806e+01 2.02490465e+02 4.71901315e+01 2.02490227e+02 4.71899825e+01 2.02490019e+02 4.71898105e+01 2.02489984e+02 4.71897674e+01 2.02490081e+02 4.71897646e+01 2.02490278e+02 4.71896517e+01 2.02490688e+02 4.71896090e+01 2.02490734e+02 4.71896077e+01 2.02490719e+02 4.71896284e+01 2.02485038e+02 4.71860782e+01 2.02485053e+02 4.71863233e+01 2.02485413e+02 4.71863131e+01 2.02485398e+02 4.71860679e+01 2.02485038e+02 4.71860782e+01 2.02506291e+02 4.71996536e+01 2.02506437e+02 4.71998024e+01 2.02506526e+02 4.71998003e+01 2.02506537e+02 4.71997284e+01 2.02506291e+02 4.71996536e+01 2.02497676e+02 4.71942730e+01 2.02497635e+02 4.71942686e+01 2.02497209e+02 4.71942808e+01 2.02497177e+02 4.71942817e+01 2.02497167e+02 4.71942544e+01 2.02497395e+02 4.71940976e+01 2.02497435e+02 4.71940909e+01 2.02497674e+02 4.71942399e+01 2.02497676e+02 4.71942730e+01 2.02496703e+02 4.71936655e+01 2.02496685e+02 4.71936688e+01 2.02496685e+02 4.71936541e+01 2.02496706e+02 4.71936535e+01 2.02496703e+02 4.71936655e+01 2.02508063e+02 4.72010588e+01 2.02507793e+02 4.72010781e+01 2.02507739e+02 4.72008567e+01 2.02508068e+02 4.72008744e+01 2.02508063e+02 4.72010588e+01 2.02503825e+02 4.71984125e+01 2.02503436e+02 4.71984413e+01 2.02503455e+02 4.71981815e+01 2.02503819e+02 4.71981576e+01 2.02503825e+02 4.71984125e+01 2.02501266e+02 4.71968143e+01 2.02501067e+02 4.71969897e+01 2.02500994e+02 4.71969918e+01 2.02500754e+02 4.71970932e+01 2.02500403e+02 4.71971033e+01 2.02500430e+02 4.71968909e+01 2.02500694e+02 4.71967566e+01 2.02500879e+02 4.71967513e+01 2.02501223e+02 4.71967879e+01 2.02501272e+02 4.71967865e+01 2.02501266e+02 4.71968143e+01 2.02495786e+02 4.71933918e+01 2.02495737e+02 4.71933932e+01 2.02495710e+02 4.71933444e+01 2.02495784e+02 4.71933588e+01 2.02495786e+02 4.71933918e+01 2.02505614e+02 4.71998289e+01 2.02505552e+02 4.71998059e+01 2.02505538e+02 4.71997815e+01 2.02505587e+02 4.71997801e+01 2.02505614e+02 4.71998289e+01 2.02502373e+02 4.71978048e+01 2.02502404e+02 4.71979026e+01 2.02502418e+02 4.71981320e+01 2.02502073e+02 4.71982159e+01 2.02502088e+02 4.71984611e+01 2.02502413e+02 4.71985462e+01 2.02502652e+02 4.71986952e+01 2.02502926e+02 4.71987488e+01 2.02503000e+02 4.71987632e+01 2.02503227e+02 4.71989208e+01 2.02503241e+02 4.71989452e+01 2.02503324e+02 4.71991751e+01 2.02503497e+02 4.71993724e+01 2.02503499e+02 4.71994054e+01 2.02503582e+02 4.71996352e+01 2.02503589e+02 4.71997610e+01 2.02503634e+02 4.71999223e+01 2.02503945e+02 4.71999830e+01 2.02504182e+02 4.71998321e+01 2.02504196e+02 4.71998317e+01 2.02504212e+02 4.71998505e+01 2.02504021e+02 4.72000304e+01 2.02504036e+02 4.72002756e+01 2.02504015e+02 4.72003258e+01 2.02504032e+02 4.72006039e+01 2.02504034e+02 4.72006369e+01 2.02504193e+02 4.72008105e+01 2.02504236e+02 4.72010623e+01 2.02504094e+02 4.72012091e+01 2.02504302e+02 4.72013810e+01 2.02504571e+02 4.72015071e+01 2.02504881e+02 4.72014647e+01 2.02505037e+02 4.72014883e+01 2.02505085e+02 4.72015920e+01 2.02504923e+02 4.72017901e+01 2.02504660e+02 4.72017668e+01 2.02504402e+02 4.72017639e+01 2.02504348e+02 4.72019976e+01 2.02504757e+02 4.72019859e+01 2.02504829e+02 4.72019673e+01 2.02504800e+02 4.72020122e+01 2.02504614e+02 4.72021954e+01 2.02504629e+02 4.72024406e+01 2.02504608e+02 4.72024908e+01 2.02504625e+02 4.72027689e+01 2.02504653e+02 4.72028178e+01 2.02504527e+02 4.72030386e+01 2.02504535e+02 4.72031612e+01 2.02504715e+02 4.72031560e+01 2.02504993e+02 4.72031481e+01 2.02505005e+02 4.72033367e+01 2.02504926e+02 4.72035231e+01 2.02505287e+02 4.72035127e+01 2.02505381e+02 4.72032723e+01 2.02505405e+02 4.72031693e+01 2.02505393e+02 4.72029807e+01 2.02505472e+02 4.72027943e+01 2.02505501e+02 4.72027494e+01 2.02505687e+02 4.72025661e+01 2.02505672e+02 4.72023210e+01 2.02505464e+02 4.72021490e+01 2.02505429e+02 4.72021059e+01 2.02505325e+02 4.72019266e+01 2.02505313e+02 4.72017343e+01 2.02505596e+02 4.72017262e+01 2.02505742e+02 4.72017034e+01 2.02505737e+02 4.72016217e+01 2.02505723e+02 4.72013922e+01 2.02505703e+02 4.72013212e+01 2.02505726e+02 4.72010952e+01 2.02505967e+02 4.72009464e+01 2.02506056e+02 4.72007348e+01 2.02506054e+02 4.72007018e+01 2.02506168e+02 4.72004740e+01 2.02506423e+02 4.72004638e+01 2.02506434e+02 4.72006397e+01 2.02506451e+02 4.72007684e+01 2.02506690e+02 4.72009174e+01 2.02506701e+02 4.72011060e+01 2.02506734e+02 4.72012101e+01 2.02506647e+02 4.72013711e+01 2.02506508e+02 4.72015833e+01 2.02506399e+02 4.72017829e+01 2.02506427e+02 4.72018318e+01 2.02506442e+02 4.72020769e+01 2.02506650e+02 4.72022488e+01 2.02506647e+02 4.72022682e+01 2.02506588e+02 4.72022947e+01 2.02506372e+02 4.72021285e+01 2.02506091e+02 4.72022202e+01 2.02505980e+02 4.72024184e+01 2.02506328e+02 4.72024863e+01 2.02506477e+02 4.72024616e+01 2.02506734e+02 4.72025117e+01 2.02507010e+02 4.72026337e+01 2.02507278e+02 4.72026622e+01 2.02507264e+02 4.72024453e+01 2.02507273e+02 4.72023601e+01 2.02507219e+02 4.72021536e+01 2.02507192e+02 4.72020107e+01 2.02507184e+02 4.72018538e+01 2.02506872e+02 4.72017592e+01 2.02506864e+02 4.72015068e+01 2.02507244e+02 4.72014842e+01 2.02507495e+02 4.72016012e+01 2.02507527e+02 4.72016002e+01 2.02507562e+02 4.72016433e+01 2.02507577e+02 4.72018885e+01 2.02507866e+02 4.72020001e+01 2.02508031e+02 4.72022037e+01 2.02508335e+02 4.72023044e+01 2.02508343e+02 4.72024301e+01 2.02508387e+02 4.72025914e+01 2.02508528e+02 4.72028129e+01 2.02508759e+02 4.72029676e+01 2.02508756e+02 4.72029870e+01 2.02508725e+02 4.72032668e+01 2.02508729e+02 4.72033155e+01 2.02508827e+02 4.72035684e+01 2.02509193e+02 4.72036231e+01 2.02509306e+02 4.72038650e+01 2.02509267e+02 4.72039039e+01 2.02509153e+02 4.72041322e+01 2.02509025e+02 4.72043513e+01 2.02508750e+02 4.72044787e+01 2.02508517e+02 4.72046322e+01 2.02508285e+02 4.72047863e+01 2.02508020e+02 4.72049202e+01 2.02507808e+02 4.72050868e+01 2.02507629e+02 4.72052743e+01 2.02507386e+02 4.72054216e+01 2.02507072e+02 4.72055249e+01 2.02506854e+02 4.72056876e+01 2.02506748e+02 4.72059203e+01 2.02506515e+02 4.72060743e+01 2.02506255e+02 4.72062108e+01 2.02506064e+02 4.72063906e+01 2.02505798e+02 4.72065240e+01 2.02505538e+02 4.72066605e+01 2.02505484e+02 4.72066904e+01 2.02505111e+02 4.72066929e+01 2.02505038e+02 4.72066950e+01 2.02504759e+02 4.72067726e+01 2.02504767e+02 4.72068952e+01 2.02504779e+02 4.72070838e+01 2.02504815e+02 4.72071850e+01 2.02504706e+02 4.72073376e+01 2.02504444e+02 4.72074728e+01 2.02504387e+02 4.72075012e+01 2.02504027e+02 4.72075115e+01 2.02504042e+02 4.72077566e+01 2.02504001e+02 4.72077946e+01 2.02503841e+02 4.72079938e+01 2.02503702e+02 4.72082063e+01 2.02503403e+02 4.72083187e+01 2.02503154e+02 4.72084622e+01 2.02503029e+02 4.72085051e+01 2.02503021e+02 4.72083794e+01 2.02502977e+02 4.72082181e+01 2.02502837e+02 4.72079966e+01 2.02502427e+02 4.72080084e+01 2.02502355e+02 4.72080270e+01 2.02502351e+02 4.72079609e+01 2.02502250e+02 4.72077797e+01 2.02502238e+02 4.72075911e+01 2.02502471e+02 4.72076159e+01 2.02502744e+02 4.72076081e+01 2.02502798e+02 4.72073743e+01 2.02502771e+02 4.72073255e+01 2.02502755e+02 4.72070803e+01 2.02502751e+02 4.72070143e+01 2.02502736e+02 4.72067692e+01 2.02502766e+02 4.72067242e+01 2.02502748e+02 4.72064351e+01 2.02502751e+02 4.72064157e+01 2.02502841e+02 4.72061730e+01 2.02502802e+02 4.72060699e+01 2.02502678e+02 4.72058357e+01 2.02502674e+02 4.72057697e+01 2.02502659e+02 4.72055245e+01 2.02502378e+02 4.72054066e+01 2.02502370e+02 4.72052809e+01 2.02502424e+02 4.72050471e+01 2.02502422e+02 4.72050141e+01 2.02502405e+02 4.72047360e+01 2.02502069e+02 4.72047939e+01 2.02501834e+02 4.72048321e+01 2.02501574e+02 4.72046995e+01 2.02501516e+02 4.72044486e+01 2.02501665e+02 4.72043061e+01 2.02501687e+02 4.72042559e+01 2.02501604e+02 4.72040260e+01 2.02501596e+02 4.72039003e+01 2.02501585e+02 4.72037149e+01 2.02501346e+02 4.72035659e+01 2.02501290e+02 4.72034100e+01 2.02501603e+02 4.72033066e+01 2.02501588e+02 4.72030614e+01 2.02501584e+02 4.72029954e+01 2.02501569e+02 4.72027503e+01 2.02501565e+02 4.72026842e+01 2.02501463e+02 4.72025030e+01 2.02501311e+02 4.72022901e+01 2.02500950e+02 4.72023004e+01 2.02500876e+02 4.72022860e+01 2.02500614e+02 4.72021542e+01 2.02500610e+02 4.72020881e+01 2.02500704e+02 4.72018477e+01 2.02501083e+02 4.72017849e+01 2.02501268e+02 4.72016017e+01 2.02501167e+02 4.72014205e+01 2.02500892e+02 4.72013669e+01 2.02500818e+02 4.72013525e+01 2.02500791e+02 4.72013037e+01 2.02501010e+02 4.72011415e+01 2.02501104e+02 4.72009011e+01 2.02501355e+02 4.72007586e+01 2.02501434e+02 4.72005721e+01 2.02501455e+02 4.72005219e+01 2.02501555e+02 4.72002853e+01 2.02501547e+02 4.72001627e+01 2.02501309e+02 4.72000137e+01 2.02501345e+02 4.71998552e+01 2.02501399e+02 4.71996214e+01 2.02500990e+02 4.71996331e+01 2.02500941e+02 4.71996345e+01 2.02500679e+02 4.71995027e+01 2.02500675e+02 4.71994367e+01 2.02500895e+02 4.71992745e+01 2.02500879e+02 4.71990294e+01 2.02500875e+02 4.71989634e+01 2.02500774e+02 4.71987821e+01 2.02500593e+02 4.71987873e+01 2.02500601e+02 4.71989098e+01 2.02500613e+02 4.71990984e+01 2.02500339e+02 4.71991034e+01 2.02500096e+02 4.71989574e+01 2.02499858e+02 4.71988083e+01 2.02499705e+02 4.71985954e+01 2.02499392e+02 4.71985017e+01 2.02499337e+02 4.71983021e+01 2.02499675e+02 4.71982924e+01 2.02499775e+02 4.71985438e+01 2.02500114e+02 4.71984877e+01 2.02500167e+02 4.71982540e+01 2.02499906e+02 4.71981221e+01 2.02499901e+02 4.71980561e+01 2.02499886e+02 4.71978110e+01 2.02499671e+02 4.71976447e+01 2.02499262e+02 4.71976565e+01 2.02499042e+02 4.71978186e+01 2.02498994e+02 4.71978200e+01 2.02498732e+02 4.71976882e+01 2.02498493e+02 4.71975391e+01 2.02498489e+02 4.71974731e+01 2.02498734e+02 4.71973268e+01 2.02498953e+02 4.71971646e+01 2.02499147e+02 4.71969867e+01 2.02499366e+02 4.71968246e+01 2.02499463e+02 4.71968218e+01 2.02499788e+02 4.71969069e+01 2.02499941e+02 4.71971198e+01 2.02499945e+02 4.71971859e+01 2.02499960e+02 4.71974310e+01 2.02500168e+02 4.71976030e+01 2.02500437e+02 4.71977291e+01 2.02500718e+02 4.71978470e+01 2.02501062e+02 4.71978836e+01 2.02501134e+02 4.71978650e+01 2.02501401e+02 4.71977959e+01 2.02501479e+02 4.71976095e+01 2.02501241e+02 4.71974605e+01 2.02501037e+02 4.71972856e+01 2.02500998e+02 4.71972454e+01 2.02501095e+02 4.71972426e+01 2.02501334e+02 4.71973917e+01 2.02501549e+02 4.71975579e+01 2.02501788e+02 4.71977069e+01 2.02502120e+02 4.71976472e+01 2.02502306e+02 4.71976490e+01 2.02502373e+02 4.71978048e+01 2.02487004e+02 4.71882042e+01 2.02487019e+02 4.71884493e+01 2.02486992e+02 4.71884963e+01 2.02486895e+02 4.71887347e+01 2.02486592e+02 4.71887644e+01 2.02486553e+02 4.71885211e+01 2.02486601e+02 4.71884329e+01 2.02486637e+02 4.71882744e+01 2.02486936e+02 4.71881620e+01 2.02486976e+02 4.71881553e+01 2.02487004e+02 4.71882042e+01 2.02483551e+02 4.71860466e+01 2.02483213e+02 4.71860562e+01 2.02483093e+02 4.71860596e+01 2.02482983e+02 4.71862265e+01 2.02483221e+02 4.71863755e+01 2.02483441e+02 4.71862772e+01 2.02483774e+02 4.71862927e+01 2.02483994e+02 4.71863236e+01 2.02483983e+02 4.71861382e+01 2.02483671e+02 4.71860431e+01 2.02483551e+02 4.71860466e+01 2.02509427e+02 4.72025084e+01 2.02509386e+02 4.72025041e+01 2.02509376e+02 4.72024768e+01 2.02509448e+02 4.72024582e+01 2.02509427e+02 4.72025084e+01 2.02508591e+02 4.72019869e+01 2.02508358e+02 4.72019621e+01 2.02508302e+02 4.72018063e+01 2.02508580e+02 4.72017983e+01 2.02508591e+02 4.72019869e+01 2.02495850e+02 4.71940300e+01 2.02495776e+02 4.71940156e+01 2.02495749e+02 4.71939667e+01 2.02495823e+02 4.71939812e+01 2.02495850e+02 4.71940300e+01 2.02495091e+02 4.71935558e+01 2.02495241e+02 4.71937606e+01 2.02495307e+02 4.71939901e+01 2.02495075e+02 4.71941442e+01 2.02494707e+02 4.71941547e+01 2.02494692e+02 4.71939049e+01 2.02494669e+02 4.71938576e+01 2.02494602e+02 4.71935815e+01 2.02494364e+02 4.71934325e+01 2.02494336e+02 4.71933837e+01 2.02494462e+02 4.71931628e+01 2.02494739e+02 4.71931549e+01 2.02494911e+02 4.71933531e+01 2.02495090e+02 4.71935463e+01 2.02495091e+02 4.71935558e+01 2.02490601e+02 4.71907511e+01 2.02490703e+02 4.71909324e+01 2.02490883e+02 4.71909272e+01 2.02490875e+02 4.71908046e+01 2.02490601e+02 4.71907511e+01 2.02480319e+02 4.71843258e+01 2.02480266e+02 4.71845918e+01 2.02480226e+02 4.71846850e+01 2.02480366e+02 4.71846547e+01 2.02480745e+02 4.71845923e+01 2.02480728e+02 4.71843141e+01 2.02480319e+02 4.71843258e+01 2.02477146e+02 4.71823427e+01 2.02477020e+02 4.71824997e+01 2.02477374e+02 4.71825637e+01 2.02477525e+02 4.71825798e+01 2.02477518e+02 4.71824573e+01 2.02477279e+02 4.71823082e+01 2.02477146e+02 4.71823427e+01 2.02476622e+02 4.71820152e+01 2.02476687e+02 4.71820952e+01 2.02476763e+02 4.71821033e+01 2.02476774e+02 4.71820313e+01 2.02476622e+02 4.71820152e+01 2.02475574e+02 4.71813601e+01 2.02475500e+02 4.71813457e+01 2.02475091e+02 4.71813573e+01 2.02474863e+02 4.71815142e+01 2.02474881e+02 4.71818033e+01 2.02475251e+02 4.71817566e+01 2.02475456e+02 4.71817035e+01 2.02475731e+02 4.71817571e+01 2.02475950e+02 4.71815950e+01 2.02475935e+02 4.71813499e+01 2.02475574e+02 4.71813601e+01 2.02473032e+02 4.71797711e+01 2.02472739e+02 4.71798081e+01 2.02472724e+02 4.71795787e+01 2.02473062e+02 4.71795691e+01 2.02473032e+02 4.71797711e+01 2.02499574e+02 4.71966549e+01 2.02499236e+02 4.71966646e+01 2.02499112e+02 4.71964304e+01 2.02498752e+02 4.71964407e+01 2.02498853e+02 4.71966220e+01 2.02498865e+02 4.71968106e+01 2.02498632e+02 4.71967858e+01 2.02498435e+02 4.71966056e+01 2.02498197e+02 4.71964566e+01 2.02498218e+02 4.71964064e+01 2.02498201e+02 4.71961282e+01 2.02498199e+02 4.71960952e+01 2.02498270e+02 4.71960766e+01 2.02498486e+02 4.71962429e+01 2.02498824e+02 4.71961867e+01 2.02499009e+02 4.71961814e+01 2.02499182e+02 4.71963788e+01 2.02499519e+02 4.71964553e+01 2.02499574e+02 4.71966549e+01 2.02498017e+02 4.71956825e+01 2.02497950e+02 4.71956623e+01 2.02497949e+02 4.71956403e+01 2.02497981e+02 4.71956394e+01 2.02498017e+02 4.71956825e+01 2.02487210e+02 4.71892305e+01 2.02486816e+02 4.71892500e+01 2.02486784e+02 4.71889642e+01 2.02487225e+02 4.71889478e+01 2.02487210e+02 4.71892305e+01 2.02485349e+02 4.71880679e+01 2.02485329e+02 4.71880712e+01 2.02485315e+02 4.71880468e+01 2.02485364e+02 4.71880454e+01 2.02485349e+02 4.71880679e+01 2.02465530e+02 4.71756785e+01 2.02465206e+02 4.71757756e+01 2.02464981e+02 4.71757820e+01 2.02464989e+02 4.71756399e+01 2.02465174e+02 4.71754558e+01 2.02465432e+02 4.71754485e+01 2.02465530e+02 4.71756785e+01 2.02494999e+02 4.71943959e+01 2.02494780e+02 4.71945581e+01 2.02494550e+02 4.71945961e+01 2.02494539e+02 4.71944075e+01 2.02494758e+02 4.71942454e+01 2.02495036e+02 4.71942374e+01 2.02494999e+02 4.71943959e+01 2.02479732e+02 4.71848565e+01 2.02479502e+02 4.71848945e+01 2.02479367e+02 4.71849276e+01 2.02479004e+02 4.71849379e+01 2.02478911e+02 4.71849420e+01 2.02478785e+02 4.71850991e+01 2.02479024e+02 4.71852482e+01 2.02479291e+02 4.71851792e+01 2.02479510e+02 4.71850171e+01 2.02479743e+02 4.71850419e+01 2.02479799e+02 4.71851978e+01 2.02479580e+02 4.71853599e+01 2.02479392e+02 4.71855416e+01 2.02479282e+02 4.71857084e+01 2.02479520e+02 4.71858575e+01 2.02479787e+02 4.71857885e+01 2.02479768e+02 4.71856746e+01 2.02479755e+02 4.71854694e+01 2.02480057e+02 4.71854608e+01 2.02480286e+02 4.71856166e+01 2.02480433e+02 4.71855938e+01 2.02480457e+02 4.71854908e+01 2.02480224e+02 4.71853375e+01 2.02480284e+02 4.71852017e+01 2.02480265e+02 4.71849814e+01 2.02480005e+02 4.71848487e+01 2.02479732e+02 4.71848565e+01 2.02466223e+02 4.71764115e+01 2.02465920e+02 4.71763892e+01 2.02465909e+02 4.71762150e+01 2.02466141e+02 4.71762257e+01 2.02466223e+02 4.71764115e+01 2.02502464e+02 4.71993571e+01 2.02502471e+02 4.71994797e+01 2.02502652e+02 4.71994745e+01 2.02502644e+02 4.71993520e+01 2.02502464e+02 4.71993571e+01 2.02501654e+02 4.71988514e+01 2.02501784e+02 4.71990114e+01 2.02501904e+02 4.71990079e+01 2.02502015e+02 4.71988410e+01 2.02501654e+02 4.71988514e+01 2.02489542e+02 4.71912862e+01 2.02489335e+02 4.71912921e+01 2.02489327e+02 4.71911515e+01 2.02489476e+02 4.71911882e+01 2.02489542e+02 4.71912862e+01 2.02486623e+02 4.71894619e+01 2.02486525e+02 4.71894647e+01 2.02486547e+02 4.71894144e+01 2.02486595e+02 4.71894130e+01 2.02486623e+02 4.71894619e+01 2.02486261e+02 4.71892358e+01 2.02485916e+02 4.71892647e+01 2.02485895e+02 4.71890072e+01 2.02486247e+02 4.71890194e+01 2.02486261e+02 4.71892358e+01 2.02478638e+02 4.71844720e+01 2.02478643e+02 4.71845537e+01 2.02478765e+02 4.71845511e+01 2.02478758e+02 4.71844686e+01 2.02478638e+02 4.71844720e+01 2.02504989e+02 4.72012330e+01 2.02504917e+02 4.72012516e+01 2.02504938e+02 4.72012014e+01 2.02504975e+02 4.72012086e+01 2.02504989e+02 4.72012330e+01 2.02498784e+02 4.71973584e+01 2.02498802e+02 4.71976366e+01 2.02499211e+02 4.71976248e+01 2.02499194e+02 4.71973467e+01 2.02498784e+02 4.71973584e+01 2.02498307e+02 4.71970603e+01 2.02498235e+02 4.71970789e+01 2.02498231e+02 4.71970129e+01 2.02498305e+02 4.71970273e+01 2.02498307e+02 4.71970603e+01 2.02497782e+02 4.71967323e+01 2.02497397e+02 4.71967912e+01 2.02497258e+02 4.71970036e+01 2.02497050e+02 4.71969784e+01 2.02496700e+02 4.71969118e+01 2.02496517e+02 4.71967218e+01 2.02496523e+02 4.71965446e+01 2.02496835e+02 4.71964867e+01 2.02497093e+02 4.71966215e+01 2.02497296e+02 4.71967279e+01 2.02497373e+02 4.71964770e+01 2.02497764e+02 4.71964507e+01 2.02497782e+02 4.71967323e+01 2.02499545e+02 4.71981325e+01 2.02499448e+02 4.71981352e+01 2.02499469e+02 4.71980850e+01 2.02499541e+02 4.71980664e+01 2.02499545e+02 4.71981325e+01 2.02495090e+02 4.71956490e+01 2.02494772e+02 4.71957494e+01 2.02494750e+02 4.71957500e+01 2.02494519e+02 4.71958911e+01 2.02494267e+02 4.71960323e+01 2.02493889e+02 4.71960614e+01 2.02493712e+02 4.71958669e+01 2.02493517e+02 4.71956852e+01 2.02493510e+02 4.71955594e+01 2.02493563e+02 4.71953257e+01 2.02493570e+02 4.71952979e+01 2.02493610e+02 4.71952913e+01 2.02493948e+02 4.71952352e+01 2.02494178e+02 4.71951971e+01 2.02494372e+02 4.71953789e+01 2.02494578e+02 4.71953292e+01 2.02494924e+02 4.71952965e+01 2.02495057e+02 4.71955231e+01 2.02495090e+02 4.71956490e+01 2.02472629e+02 4.71816137e+01 2.02472520e+02 4.71815962e+01 2.02472485e+02 4.71815236e+01 2.02472662e+02 4.71814914e+01 2.02472629e+02 4.71816137e+01 2.02471722e+02 4.71810462e+01 2.02471539e+02 4.71810201e+01 2.02471563e+02 4.71809470e+01 2.02471671e+02 4.71809221e+01 2.02471722e+02 4.71810462e+01 2.02499155e+02 4.71984871e+01 2.02498987e+02 4.71984760e+01 2.02498908e+02 4.71983330e+01 2.02499191e+02 4.71983249e+01 2.02499155e+02 4.71984871e+01 2.02497285e+02 4.71973193e+01 2.02497064e+02 4.71972942e+01 2.02497056e+02 4.71971765e+01 2.02497274e+02 4.71971389e+01 2.02497285e+02 4.71973193e+01 2.02485004e+02 4.71896473e+01 2.02484932e+02 4.71896659e+01 2.02484962e+02 4.71896210e+01 2.02485025e+02 4.71895971e+01 2.02485004e+02 4.71896473e+01 2.02478922e+02 4.71858462e+01 2.02478958e+02 4.71859475e+01 2.02479110e+02 4.71859636e+01 2.02479189e+02 4.71857772e+01 2.02478922e+02 4.71858462e+01 2.02476537e+02 4.71843554e+01 2.02476544e+02 4.71844780e+01 2.02476725e+02 4.71844729e+01 2.02476717e+02 4.71843503e+01 2.02476537e+02 4.71843554e+01 2.02474580e+02 4.71831321e+01 2.02474434e+02 4.71831092e+01 2.02474052e+02 4.71831013e+01 2.02473999e+02 4.71833677e+01 2.02473613e+02 4.71834255e+01 2.02473513e+02 4.71836621e+01 2.02473549e+02 4.71837634e+01 2.02473795e+02 4.71838383e+01 2.02473892e+02 4.71838355e+01 2.02474159e+02 4.71837665e+01 2.02474378e+02 4.71836044e+01 2.02474729e+02 4.71835248e+01 2.02474817e+02 4.71832803e+01 2.02474751e+02 4.71832009e+01 2.02474580e+02 4.71831321e+01 2.02473706e+02 4.71825861e+01 2.02473369e+02 4.71825957e+01 2.02473245e+02 4.71823615e+01 2.02472885e+02 4.71823717e+01 2.02472986e+02 4.71825530e+01 2.02473225e+02 4.71827021e+01 2.02473463e+02 4.71828512e+01 2.02473592e+02 4.71830813e+01 2.02474001e+02 4.71830697e+01 2.02474088e+02 4.71828245e+01 2.02474215e+02 4.71826208e+01 2.02473942e+02 4.71824975e+01 2.02473706e+02 4.71825861e+01 2.02503782e+02 4.72016759e+01 2.02503761e+02 4.72017806e+01 2.02503942e+02 4.72017755e+01 2.02503905e+02 4.72016742e+01 2.02503782e+02 4.72016759e+01 2.02491729e+02 4.71941478e+01 2.02491655e+02 4.71941333e+01 2.02491661e+02 4.71941056e+01 2.02491725e+02 4.71940817e+01 2.02491729e+02 4.71941478e+01 2.02490731e+02 4.71935245e+01 2.02490515e+02 4.71936890e+01 2.02490494e+02 4.71936896e+01 2.02490110e+02 4.71936478e+01 2.02490120e+02 4.71934423e+01 2.02490323e+02 4.71932697e+01 2.02490652e+02 4.71932475e+01 2.02490730e+02 4.71935150e+01 2.02490731e+02 4.71935245e+01 2.02471309e+02 4.71813868e+01 2.02471230e+02 4.71815732e+01 2.02471209e+02 4.71816234e+01 2.02471168e+02 4.71816191e+01 2.02470899e+02 4.71814929e+01 2.02470538e+02 4.71815032e+01 2.02470413e+02 4.71817240e+01 2.02470099e+02 4.71818273e+01 2.02469855e+02 4.71819736e+01 2.02469806e+02 4.71819750e+01 2.02469468e+02 4.71820310e+01 2.02469504e+02 4.71821984e+01 2.02469514e+02 4.71823587e+01 2.02469236e+02 4.71823965e+01 2.02468984e+02 4.71823266e+01 2.02468764e+02 4.71824886e+01 2.02468690e+02 4.71824742e+01 2.02468386e+02 4.71823734e+01 2.02468043e+02 4.71823367e+01 2.02467841e+02 4.71825096e+01 2.02467621e+02 4.71826717e+01 2.02467443e+02 4.71828598e+01 2.02467258e+02 4.71828817e+01 2.02466998e+02 4.71828804e+01 2.02466707e+02 4.71829980e+01 2.02466666e+02 4.71829936e+01 2.02466631e+02 4.71829505e+01 2.02466616e+02 4.71827054e+01 2.02466638e+02 4.71826552e+01 2.02466536e+02 4.71824391e+01 2.02466553e+02 4.71823031e+01 2.02466514e+02 4.71821304e+01 2.02466507e+02 4.71819751e+01 2.02466697e+02 4.71819954e+01 2.02466992e+02 4.71821029e+01 2.02467296e+02 4.71821690e+01 2.02467528e+02 4.71820148e+01 2.02467659e+02 4.71817976e+01 2.02467931e+02 4.71817344e+01 2.02468167e+02 4.71818160e+01 2.02468223e+02 4.71815520e+01 2.02468610e+02 4.71814949e+01 2.02468691e+02 4.71814979e+01 2.02468713e+02 4.71815593e+01 2.02468624e+02 4.71818027e+01 2.02468595e+02 4.71818939e+01 2.02468819e+02 4.71819247e+01 2.02469117e+02 4.71818113e+01 2.02469149e+02 4.71818102e+01 2.02469519e+02 4.71817635e+01 2.02469714e+02 4.71815864e+01 2.02470004e+02 4.71814687e+01 2.02470076e+02 4.71814501e+01 2.02470437e+02 4.71814399e+01 2.02470690e+02 4.71812989e+01 2.02470753e+02 4.71812751e+01 2.02471020e+02 4.71812061e+01 2.02471252e+02 4.71812323e+01 2.02471309e+02 4.71813868e+01 2.02470591e+02 4.71809375e+01 2.02470308e+02 4.71809536e+01 2.02470224e+02 4.71807085e+01 2.02470658e+02 4.71806949e+01 2.02470591e+02 4.71809375e+01 2.02469883e+02 4.71804949e+01 2.02469609e+02 4.71804939e+01 2.02469542e+02 4.71802822e+01 2.02469903e+02 4.71802768e+01 2.02469883e+02 4.71804949e+01 2.02465035e+02 4.71774641e+01 2.02464900e+02 4.71774679e+01 2.02464873e+02 4.71773627e+01 2.02465030e+02 4.71773716e+01 2.02465035e+02 4.71774641e+01 2.02500931e+02 4.72001949e+01 2.02500830e+02 4.72003674e+01 2.02500834e+02 4.72004334e+01 2.02500768e+02 4.72004133e+01 2.02500499e+02 4.72002872e+01 2.02500494e+02 4.72002212e+01 2.02500597e+02 4.71999863e+01 2.02500876e+02 4.72000085e+01 2.02500931e+02 4.72001949e+01 2.02496941e+02 4.71977031e+01 2.02496677e+02 4.71978373e+01 2.02496330e+02 4.71978365e+01 2.02496297e+02 4.71975996e+01 2.02496477e+02 4.71974128e+01 2.02496920e+02 4.71974001e+01 2.02496941e+02 4.71977031e+01 2.02495894e+02 4.71970491e+01 2.02495624e+02 4.71970569e+01 2.02495639e+02 4.71968893e+01 2.02495881e+02 4.71968665e+01 2.02495894e+02 4.71970491e+01 2.02489319e+02 4.71929413e+01 2.02489301e+02 4.71929444e+01 2.02489300e+02 4.71929299e+01 2.02489316e+02 4.71929332e+01 2.02489319e+02 4.71929413e+01 2.02486355e+02 4.71910895e+01 2.02486391e+02 4.71911908e+01 2.02486543e+02 4.71912069e+01 2.02486535e+02 4.71910843e+01 2.02486355e+02 4.71910895e+01 2.02479009e+02 4.71864992e+01 2.02479025e+02 4.71865485e+01 2.02479242e+02 4.71866447e+01 2.02479140e+02 4.71864634e+01 2.02479009e+02 4.71864992e+01 2.02470157e+02 4.71809656e+01 2.02469825e+02 4.71809850e+01 2.02469838e+02 4.71807660e+01 2.02470201e+02 4.71807074e+01 2.02470157e+02 4.71809656e+01 2.02505971e+02 4.72036411e+01 2.02505977e+02 4.72037228e+01 2.02506128e+02 4.72037389e+01 2.02506120e+02 4.72036164e+01 2.02505971e+02 4.72036411e+01 2.02503744e+02 4.72022503e+01 2.02503690e+02 4.72024840e+01 2.02503717e+02 4.72025329e+01 2.02503848e+02 4.72026928e+01 2.02503999e+02 4.72027090e+01 2.02503992e+02 4.72025864e+01 2.02504028e+02 4.72024279e+01 2.02504082e+02 4.72021942e+01 2.02503744e+02 4.72022503e+01 2.02492696e+02 4.71953505e+01 2.02492655e+02 4.71953461e+01 2.02492620e+02 4.71953030e+01 2.02492694e+02 4.71953174e+01 2.02492696e+02 4.71953505e+01 2.02489929e+02 4.71936216e+01 2.02489778e+02 4.71938266e+01 2.02489400e+02 4.71938473e+01 2.02489339e+02 4.71935674e+01 2.02489331e+02 4.71935476e+01 2.02489361e+02 4.71935509e+01 2.02489713e+02 4.71934869e+01 2.02489895e+02 4.71934817e+01 2.02489929e+02 4.71936216e+01 2.02486996e+02 4.71917891e+01 2.02487011e+02 4.71920342e+01 2.02487015e+02 4.71921003e+01 2.02487166e+02 4.71922446e+01 2.02487214e+02 4.71922247e+01 2.02487246e+02 4.71921858e+01 2.02487231e+02 4.71919359e+01 2.02487270e+02 4.71918427e+01 2.02486996e+02 4.71917891e+01 2.02476148e+02 4.71850104e+01 2.02476038e+02 4.71851772e+01 2.02476399e+02 4.71851670e+01 2.02476298e+02 4.71849857e+01 2.02476148e+02 4.71850104e+01 2.02472898e+02 4.71829782e+01 2.02472915e+02 4.71832564e+01 2.02473253e+02 4.71832003e+01 2.02473241e+02 4.71830149e+01 2.02472898e+02 4.71829782e+01 2.02469741e+02 4.71810049e+01 2.02469366e+02 4.71809989e+01 2.02469353e+02 4.71807620e+01 2.02469708e+02 4.71807462e+01 2.02469741e+02 4.71810049e+01 2.02467281e+02 4.71794667e+01 2.02466987e+02 4.71795038e+01 2.02466892e+02 4.71795228e+01 2.02466843e+02 4.71796102e+01 2.02467090e+02 4.71797534e+01 2.02467381e+02 4.71798287e+01 2.02467601e+02 4.71796666e+01 2.02467518e+02 4.71794368e+01 2.02467281e+02 4.71794667e+01 2.02506104e+02 4.72040230e+01 2.02506206e+02 4.72042043e+01 2.02506169e+02 4.72043628e+01 2.02505879e+02 4.72044805e+01 2.02505830e+02 4.72044819e+01 2.02505591e+02 4.72043329e+01 2.02505564e+02 4.72042841e+01 2.02505434e+02 4.72041241e+01 2.02505419e+02 4.72038947e+01 2.02505443e+02 4.72037917e+01 2.02505169e+02 4.72037381e+01 2.02505103e+02 4.72037180e+01 2.02504833e+02 4.72035919e+01 2.02504646e+02 4.72037110e+01 2.02504574e+02 4.72037835e+01 2.02504513e+02 4.72039270e+01 2.02504557e+02 4.72041212e+01 2.02504636e+02 4.72043028e+01 2.02504671e+02 4.72043624e+01 2.02504793e+02 4.72044007e+01 2.02505070e+02 4.72043927e+01 2.02505034e+02 4.72045512e+01 2.02504980e+02 4.72047850e+01 2.02505219e+02 4.72049340e+01 2.02505212e+02 4.72049617e+01 2.02505027e+02 4.72051449e+01 2.02504807e+02 4.72053071e+01 2.02504682e+02 4.72055279e+01 2.02504733e+02 4.72056186e+01 2.02504964e+02 4.72057040e+01 2.02505183e+02 4.72055419e+01 2.02505257e+02 4.72055563e+01 2.02505285e+02 4.72056051e+01 2.02505386e+02 4.72057864e+01 2.02505661e+02 4.72058399e+01 2.02505786e+02 4.72056191e+01 2.02506005e+02 4.72054569e+01 2.02506283e+02 4.72054490e+01 2.02506463e+02 4.72054438e+01 2.02506427e+02 4.72053425e+01 2.02506413e+02 4.72051131e+01 2.02506523e+02 4.72049462e+01 2.02506519e+02 4.72048802e+01 2.02506597e+02 4.72046300e+01 2.02506816e+02 4.72044678e+01 2.02506813e+02 4.72044065e+01 2.02506609e+02 4.72042315e+01 2.02506465e+02 4.72040127e+01 2.02506104e+02 4.72040230e+01 2.02499899e+02 4.72001485e+01 2.02499802e+02 4.72001513e+01 2.02499798e+02 4.72000852e+01 2.02499895e+02 4.72000825e+01 2.02499899e+02 4.72001485e+01 2.02494624e+02 4.71968539e+01 2.02494576e+02 4.71968553e+01 2.02494574e+02 4.71968223e+01 2.02494621e+02 4.71968215e+01 2.02494624e+02 4.71968539e+01 2.02492230e+02 4.71953583e+01 2.02492190e+02 4.71953649e+01 2.02492162e+02 4.71953161e+01 2.02492259e+02 4.71953133e+01 2.02492230e+02 4.71953583e+01 2.02491786e+02 4.71950813e+01 2.02491689e+02 4.71950840e+01 2.02491451e+02 4.71949350e+01 2.02491090e+02 4.71949453e+01 2.02490993e+02 4.71949481e+01 2.02490646e+02 4.71948792e+01 2.02490515e+02 4.71946500e+01 2.02490537e+02 4.71945998e+01 2.02490585e+02 4.71945984e+01 2.02490988e+02 4.71945826e+01 2.02491077e+02 4.71945606e+01 2.02491305e+02 4.71947171e+01 2.02491544e+02 4.71948662e+01 2.02491751e+02 4.71950382e+01 2.02491786e+02 4.71950813e+01 2.02487861e+02 4.71926287e+01 2.02487722e+02 4.71928098e+01 2.02487724e+02 4.71928428e+01 2.02487830e+02 4.71930560e+01 2.02488071e+02 4.71930596e+01 2.02488117e+02 4.71928435e+01 2.02488113e+02 4.71927867e+01 2.02487970e+02 4.71926268e+01 2.02487861e+02 4.71926287e+01 2.02471658e+02 4.71825024e+01 2.02471526e+02 4.71826558e+01 2.02471530e+02 4.71827219e+01 2.02471286e+02 4.71828681e+01 2.02471092e+02 4.71830460e+01 2.02471222e+02 4.71832060e+01 2.02471342e+02 4.71832026e+01 2.02471680e+02 4.71831930e+01 2.02471925e+02 4.71832679e+01 2.02471795e+02 4.71831079e+01 2.02471781e+02 4.71828785e+01 2.02472125e+02 4.71827947e+01 2.02472110e+02 4.71825495e+01 2.02471872e+02 4.71824005e+01 2.02471658e+02 4.71825024e+01 2.02463991e+02 4.71777087e+01 2.02464054e+02 4.71777676e+01 2.02464085e+02 4.71780670e+01 2.02463680e+02 4.71781129e+01 2.02463583e+02 4.71781157e+01 2.02463373e+02 4.71782198e+01 2.02462987e+02 4.71782308e+01 2.02463005e+02 4.71779896e+01 2.02463374e+02 4.71779216e+01 2.02463421e+02 4.71776515e+01 2.02463712e+02 4.71775342e+01 2.02463939e+02 4.71775278e+01 2.02463991e+02 4.71777087e+01 2.02490110e+02 4.71943333e+01 2.02490038e+02 4.71943519e+01 2.02490060e+02 4.71943017e+01 2.02490108e+02 4.71943003e+01 2.02490110e+02 4.71943333e+01 2.02474963e+02 4.71848677e+01 2.02474685e+02 4.71848756e+01 2.02474674e+02 4.71846870e+01 2.02474666e+02 4.71845645e+01 2.02474439e+02 4.71844068e+01 2.02474235e+02 4.71844126e+01 2.02474145e+02 4.71846241e+01 2.02474173e+02 4.71846730e+01 2.02474076e+02 4.71846757e+01 2.02473809e+02 4.71847447e+01 2.02473541e+02 4.71848767e+01 2.02473553e+02 4.71850621e+01 2.02473791e+02 4.71852112e+01 2.02474064e+02 4.71852034e+01 2.02474227e+02 4.71852145e+01 2.02474526e+02 4.71853188e+01 2.02474489e+02 4.71854691e+01 2.02474316e+02 4.71854740e+01 2.02473966e+02 4.71854416e+01 2.02473739e+02 4.71855984e+01 2.02473647e+02 4.71858403e+01 2.02473654e+02 4.71859629e+01 2.02473618e+02 4.71861213e+01 2.02473502e+02 4.71863482e+01 2.02473497e+02 4.71864042e+01 2.02473635e+02 4.71864310e+01 2.02473902e+02 4.71862990e+01 2.02474131e+02 4.71862610e+01 2.02474406e+02 4.71863146e+01 2.02474391e+02 4.71860695e+01 2.02474420e+02 4.71860245e+01 2.02474460e+02 4.71860179e+01 2.02474870e+02 4.71860063e+01 2.02474982e+02 4.71857775e+01 2.02475110e+02 4.71855583e+01 2.02475481e+02 4.71854906e+01 2.02475756e+02 4.71853632e+01 2.02475687e+02 4.71851117e+01 2.02475382e+02 4.71850117e+01 2.02475143e+02 4.71848626e+01 2.02474963e+02 4.71848677e+01 2.02503373e+02 4.72029159e+01 2.02503436e+02 4.72029973e+01 2.02503662e+02 4.72031555e+01 2.02503768e+02 4.72031627e+01 2.02503878e+02 4.72029958e+01 2.02503524e+02 4.72029320e+01 2.02503373e+02 4.72029159e+01 2.02502644e+02 4.72024609e+01 2.02502653e+02 4.72026000e+01 2.02502893e+02 4.72026163e+01 2.02502947e+02 4.72023825e+01 2.02502644e+02 4.72024609e+01 2.02500151e+02 4.72009040e+01 2.02500102e+02 4.72009054e+01 2.02500075e+02 4.72008566e+01 2.02500172e+02 4.72008538e+01 2.02500151e+02 4.72009040e+01 2.02499793e+02 4.72006805e+01 2.02499582e+02 4.72006393e+01 2.02499504e+02 4.72004998e+01 2.02499781e+02 4.72004919e+01 2.02499793e+02 4.72006805e+01 2.02493452e+02 4.71967198e+01 2.02493242e+02 4.71968879e+01 2.02493024e+02 4.71970510e+01 2.02492936e+02 4.71972954e+01 2.02492582e+02 4.71973525e+01 2.02492710e+02 4.71971540e+01 2.02492994e+02 4.71970319e+01 2.02493174e+02 4.71968458e+01 2.02493159e+02 4.71966006e+01 2.02493180e+02 4.71965504e+01 2.02493229e+02 4.71965490e+01 2.02493451e+02 4.71967103e+01 2.02493452e+02 4.71967198e+01 2.02492853e+02 4.71963461e+01 2.02492572e+02 4.71963838e+01 2.02492443e+02 4.71961535e+01 2.02492163e+02 4.71962141e+01 2.02491938e+02 4.71963723e+01 2.02491698e+02 4.71963791e+01 2.02491688e+02 4.71962163e+01 2.02491984e+02 4.71961020e+01 2.02492075e+02 4.71958602e+01 2.02492348e+02 4.71958983e+01 2.02492513e+02 4.71961019e+01 2.02492843e+02 4.71961833e+01 2.02492853e+02 4.71963461e+01 2.02481661e+02 4.71893529e+01 2.02481383e+02 4.71893608e+01 2.02481203e+02 4.71893660e+01 2.02481268e+02 4.71894460e+01 2.02481492e+02 4.71896057e+01 2.02481629e+02 4.71896325e+01 2.02481942e+02 4.71895291e+01 2.02481927e+02 4.71892840e+01 2.02481661e+02 4.71893529e+01 2.02475121e+02 4.71852658e+01 2.02475044e+02 4.71852614e+01 2.02474803e+02 4.71851144e+01 2.02474799e+02 4.71850648e+01 2.02474873e+02 4.71850627e+01 2.02475175e+02 4.71851644e+01 2.02475121e+02 4.71852658e+01 2.02464651e+02 4.71787202e+01 2.02464540e+02 4.71789497e+01 2.02464363e+02 4.71791382e+01 2.02464117e+02 4.71792836e+01 2.02464106e+02 4.71793556e+01 2.02464120e+02 4.71795850e+01 2.02463912e+02 4.71797539e+01 2.02463651e+02 4.71798902e+01 2.02463704e+02 4.71799783e+01 2.02463888e+02 4.71801676e+01 2.02463854e+02 4.71803164e+01 2.02463928e+02 4.71804631e+01 2.02463998e+02 4.71807055e+01 2.02463986e+02 4.71807453e+01 2.02464055e+02 4.71810195e+01 2.02464053e+02 4.71810388e+01 2.02463846e+02 4.71812088e+01 2.02463618e+02 4.71813656e+01 2.02463399e+02 4.71815277e+01 2.02463358e+02 4.71815343e+01 2.02462955e+02 4.71815069e+01 2.02462714e+02 4.71813597e+01 2.02462643e+02 4.71813541e+01 2.02462245e+02 4.71814045e+01 2.02462018e+02 4.71815623e+01 2.02461985e+02 4.71815732e+01 2.02461576e+02 4.71815848e+01 2.02461527e+02 4.71815862e+01 2.02461189e+02 4.71816422e+01 2.02460924e+02 4.71817756e+01 2.02460830e+02 4.71820160e+01 2.02460566e+02 4.71821506e+01 2.02460594e+02 4.71822752e+01 2.02460645e+02 4.71824990e+01 2.02460606e+02 4.71825922e+01 2.02460786e+02 4.71825871e+01 2.02460865e+02 4.71824007e+01 2.02460886e+02 4.71823505e+01 2.02461080e+02 4.71821726e+01 2.02461146e+02 4.71821928e+01 2.02461416e+02 4.71823190e+01 2.02461651e+02 4.71824701e+01 2.02461658e+02 4.71825341e+01 2.02461561e+02 4.71825369e+01 2.02461200e+02 4.71825471e+01 2.02461302e+02 4.71827284e+01 2.02461313e+02 4.71829170e+01 2.02461363e+02 4.71830087e+01 2.02461595e+02 4.71830932e+01 2.02461678e+02 4.71828455e+01 2.02462046e+02 4.71827769e+01 2.02462096e+02 4.71827924e+01 2.02462097e+02 4.71828083e+01 2.02462056e+02 4.71830820e+01 2.02461671e+02 4.71831406e+01 2.02461443e+02 4.71832974e+01 2.02461380e+02 4.71835572e+01 2.02461160e+02 4.71834834e+01 2.02460904e+02 4.71833477e+01 2.02460710e+02 4.71831654e+01 2.02460488e+02 4.71830043e+01 2.02460466e+02 4.71829858e+01 2.02460384e+02 4.71827559e+01 2.02460093e+02 4.71826455e+01 2.02459895e+02 4.71824666e+01 2.02459804e+02 4.71822725e+01 2.02459777e+02 4.71822287e+01 2.02459600e+02 4.71820338e+01 2.02459353e+02 4.71819901e+01 2.02459192e+02 4.71820104e+01 2.02458848e+02 4.71819737e+01 2.02458817e+02 4.71819621e+01 2.02458530e+02 4.71818486e+01 2.02458258e+02 4.71817247e+01 2.02458037e+02 4.71815626e+01 2.02457799e+02 4.71814126e+01 2.02457505e+02 4.71813048e+01 2.02457477e+02 4.71811166e+01 2.02457765e+02 4.71809969e+01 2.02457904e+02 4.71807847e+01 2.02457893e+02 4.71806931e+01 2.02458018e+02 4.71805569e+01 2.02458211e+02 4.71803783e+01 2.02458398e+02 4.71803202e+01 2.02458476e+02 4.71805443e+01 2.02458422e+02 4.71806279e+01 2.02458537e+02 4.71805821e+01 2.02458821e+02 4.71804607e+01 2.02458811e+02 4.71803401e+01 2.02458902e+02 4.71802120e+01 2.02458810e+02 4.71800160e+01 2.02458858e+02 4.71798854e+01 2.02459102e+02 4.71797383e+01 2.02459282e+02 4.71795516e+01 2.02459570e+02 4.71794329e+01 2.02459741e+02 4.71792403e+01 2.02459950e+02 4.71790716e+01 2.02460221e+02 4.71789419e+01 2.02460378e+02 4.71787411e+01 2.02460607e+02 4.71785847e+01 2.02460872e+02 4.71784511e+01 2.02461091e+02 4.71782889e+01 2.02461321e+02 4.71781336e+01 2.02461472e+02 4.71780489e+01 2.02461479e+02 4.71782325e+01 2.02461518e+02 4.71783406e+01 2.02461593e+02 4.71783041e+01 2.02461666e+02 4.71782313e+01 2.02461649e+02 4.71780398e+01 2.02461886e+02 4.71778884e+01 2.02462084e+02 4.71779219e+01 2.02462449e+02 4.71779776e+01 2.02462518e+02 4.71782521e+01 2.02462866e+02 4.71783201e+01 2.02463047e+02 4.71783150e+01 2.02463324e+02 4.71783072e+01 2.02463450e+02 4.71782684e+01 2.02463831e+02 4.71782576e+01 2.02464056e+02 4.71783478e+01 2.02464122e+02 4.71783680e+01 2.02464507e+02 4.71784091e+01 2.02464628e+02 4.71786447e+01 2.02464651e+02 4.71787202e+01 2.02462621e+02 4.71774502e+01 2.02462443e+02 4.71776386e+01 2.02462012e+02 4.71776502e+01 2.02462089e+02 4.71774171e+01 2.02462339e+02 4.71772740e+01 2.02462640e+02 4.71771865e+01 2.02462621e+02 4.71774502e+01 2.02497872e+02 4.71997799e+01 2.02497639e+02 4.71999333e+01 2.02497408e+02 4.71999685e+01 2.02497114e+02 4.71998603e+01 2.02496973e+02 4.71996387e+01 2.02496922e+02 4.71994856e+01 2.02496883e+02 4.71993800e+01 2.02496936e+02 4.71991950e+01 2.02497166e+02 4.71991712e+01 2.02497385e+02 4.71993348e+01 2.02497441e+02 4.71995106e+01 2.02497490e+02 4.71995825e+01 2.02497645e+02 4.71996383e+01 2.02497793e+02 4.71996834e+01 2.02497872e+02 4.71997799e+01 2.02490507e+02 4.71951792e+01 2.02490295e+02 4.71951380e+01 2.02490266e+02 4.71950286e+01 2.02490495e+02 4.71949906e+01 2.02490507e+02 4.71951792e+01 2.02476577e+02 4.71864749e+01 2.02476592e+02 4.71867200e+01 2.02476859e+02 4.71866511e+01 2.02476938e+02 4.71864647e+01 2.02476577e+02 4.71864749e+01 2.02470138e+02 4.71824497e+01 2.02470040e+02 4.71824524e+01 2.02470062e+02 4.71824022e+01 2.02470110e+02 4.71824008e+01 2.02470138e+02 4.71824497e+01 2.02465039e+02 4.71792620e+01 2.02464658e+02 4.71792728e+01 2.02464640e+02 4.71790123e+01 2.02464995e+02 4.71790242e+01 2.02465039e+02 4.71792620e+01 2.02502011e+02 4.72026636e+01 2.02501987e+02 4.72027666e+01 2.02502167e+02 4.72027615e+01 2.02502131e+02 4.72026602e+01 2.02502011e+02 4.72026636e+01 2.02500454e+02 4.72016912e+01 2.02500356e+02 4.72016940e+01 2.02500149e+02 4.72015220e+01 2.02500114e+02 4.72014789e+01 2.02500211e+02 4.72014761e+01 2.02500426e+02 4.72016424e+01 2.02500454e+02 4.72016912e+01 2.02497823e+02 4.72003472e+01 2.02497751e+02 4.72003658e+01 2.02497512e+02 4.72002168e+01 2.02497511e+02 4.72001526e+01 2.02497582e+02 4.72001652e+01 2.02497821e+02 4.72003142e+01 2.02497823e+02 4.72003472e+01 2.02495269e+02 4.71987523e+01 2.02495280e+02 4.71989377e+01 2.02495288e+02 4.71990634e+01 2.02495329e+02 4.71992270e+01 2.02495313e+02 4.71993782e+01 2.02495364e+02 4.71995268e+01 2.02495414e+02 4.71997405e+01 2.02495387e+02 4.71998353e+01 2.02495336e+02 4.71999907e+01 2.02495154e+02 4.72000073e+01 2.02494847e+02 4.71999842e+01 2.02494678e+02 4.72000333e+01 2.02494529e+02 4.72000847e+01 2.02494188e+02 4.72000704e+01 2.02494200e+02 4.71998797e+01 2.02494502e+02 4.71997691e+01 2.02494401e+02 4.71995879e+01 2.02494437e+02 4.71994294e+01 2.02494426e+02 4.71992439e+01 2.02494082e+02 4.71992073e+01 2.02493888e+02 4.71993853e+01 2.02493790e+02 4.71993880e+01 2.02493786e+02 4.71993220e+01 2.02493685e+02 4.71991407e+01 2.02493491e+02 4.71989589e+01 2.02493147e+02 4.71989223e+01 2.02493098e+02 4.71989237e+01 2.02492682e+02 4.71989311e+01 2.02492646e+02 4.71989321e+01 2.02492625e+02 4.71988958e+01 2.02492832e+02 4.71987258e+01 2.02492702e+02 4.71985659e+01 2.02492468e+02 4.71984135e+01 2.02492263e+02 4.71983706e+01 2.02492078e+02 4.71983759e+01 2.02491905e+02 4.71981785e+01 2.02491903e+02 4.71981455e+01 2.02491820e+02 4.71979156e+01 2.02491624e+02 4.71977355e+01 2.02491645e+02 4.71976853e+01 2.02491562e+02 4.71974554e+01 2.02491218e+02 4.71974188e+01 2.02491178e+02 4.71974145e+01 2.02491168e+02 4.71973872e+01 2.02491157e+02 4.71971044e+01 2.02491162e+02 4.71970842e+01 2.02491073e+02 4.71968409e+01 2.02491082e+02 4.71967354e+01 2.02491236e+02 4.71967204e+01 2.02491405e+02 4.71969211e+01 2.02491410e+02 4.71969403e+01 2.02491428e+02 4.71972294e+01 2.02491740e+02 4.71973244e+01 2.02492013e+02 4.71973166e+01 2.02492244e+02 4.71971618e+01 2.02492355e+02 4.71971948e+01 2.02492519e+02 4.71973339e+01 2.02492565e+02 4.71973653e+01 2.02492644e+02 4.71974116e+01 2.02492852e+02 4.71974784e+01 2.02493213e+02 4.71974681e+01 2.02493279e+02 4.71974883e+01 2.02493289e+02 4.71975155e+01 2.02493189e+02 4.71977522e+01 2.02493110e+02 4.71979386e+01 2.02493114e+02 4.71980046e+01 2.02493216e+02 4.71981859e+01 2.02493454e+02 4.71983350e+01 2.02493729e+02 4.71983885e+01 2.02493973e+02 4.71982422e+01 2.02494022e+02 4.71982408e+01 2.02494260e+02 4.71983898e+01 2.02494611e+02 4.71984559e+01 2.02494894e+02 4.71985726e+01 2.02495028e+02 4.71986017e+01 2.02495301e+02 4.71985968e+01 2.02495269e+02 4.71987523e+01 2.02474436e+02 4.71857354e+01 2.02474407e+02 4.71857322e+01 2.02474400e+02 4.71857124e+01 2.02474435e+02 4.71857114e+01 2.02474436e+02 4.71857354e+01 2.02464983e+02 4.71798252e+01 2.02464667e+02 4.71799269e+01 2.02464446e+02 4.71800878e+01 2.02464434e+02 4.71800894e+01 2.02464417e+02 4.71800696e+01 2.02464636e+02 4.71799075e+01 2.02464749e+02 4.71796789e+01 2.02464999e+02 4.71796718e+01 2.02464983e+02 4.71798252e+01 2.02500969e+02 4.72026116e+01 2.02501100e+02 4.72027716e+01 2.02501070e+02 4.72029735e+01 2.02500776e+02 4.72030107e+01 2.02500531e+02 4.72029359e+01 2.02500311e+02 4.72030980e+01 2.02500238e+02 4.72030836e+01 2.02500007e+02 4.72029288e+01 2.02499972e+02 4.72028857e+01 2.02500045e+02 4.72029001e+01 2.02500455e+02 4.72028884e+01 2.02500438e+02 4.72026103e+01 2.02500176e+02 4.72024785e+01 2.02500205e+02 4.72024335e+01 2.02500269e+02 4.72024096e+01 2.02500484e+02 4.72025759e+01 2.02500894e+02 4.72025641e+01 2.02500965e+02 4.72025456e+01 2.02500969e+02 4.72026116e+01 2.02500254e+02 4.72021645e+01 2.02500187e+02 4.72021443e+01 2.02500186e+02 4.72021223e+01 2.02500249e+02 4.72020985e+01 2.02500254e+02 4.72021645e+01 2.02496685e+02 4.71999360e+01 2.02496594e+02 4.71999190e+01 2.02496602e+02 4.71998841e+01 2.02496653e+02 4.71998758e+01 2.02496685e+02 4.71999360e+01 2.02467100e+02 4.71814481e+01 2.02466993e+02 4.71814511e+01 2.02466786e+02 4.71812788e+01 2.02466774e+02 4.71812444e+01 2.02466863e+02 4.71812223e+01 2.02467130e+02 4.71813499e+01 2.02467100e+02 4.71814481e+01 2.02462088e+02 4.71783139e+01 2.02462042e+02 4.71785845e+01 2.02461883e+02 4.71787211e+01 2.02461887e+02 4.71787871e+01 2.02461989e+02 4.71789684e+01 2.02462138e+02 4.71789437e+01 2.02462133e+02 4.71788620e+01 2.02462119e+02 4.71786326e+01 2.02462369e+02 4.71784901e+01 2.02462448e+02 4.71783037e+01 2.02462088e+02 4.71783139e+01 2.02496668e+02 4.72002244e+01 2.02496633e+02 4.72002155e+01 2.02496617e+02 4.72001928e+01 2.02496689e+02 4.72001742e+01 2.02496668e+02 4.72002244e+01 2.02474871e+02 4.71866053e+01 2.02474847e+02 4.71867083e+01 2.02475027e+02 4.71867031e+01 2.02475020e+02 4.71865806e+01 2.02474871e+02 4.71866053e+01 2.02501102e+02 4.72032926e+01 2.02500825e+02 4.72033006e+01 2.02500813e+02 4.72031120e+01 2.02501046e+02 4.72031368e+01 2.02501102e+02 4.72032926e+01 2.02490718e+02 4.71968071e+01 2.02490682e+02 4.71968047e+01 2.02490642e+02 4.71967593e+01 2.02490712e+02 4.71967828e+01 2.02490718e+02 4.71968071e+01 2.02466632e+02 4.71817538e+01 2.02466562e+02 4.71817693e+01 2.02466557e+02 4.71817072e+01 2.02466640e+02 4.71817118e+01 2.02466632e+02 4.71817538e+01 2.02465664e+02 4.71811487e+01 2.02465645e+02 4.71811460e+01 2.02465643e+02 4.71811355e+01 2.02465658e+02 4.71811363e+01 2.02465664e+02 4.71811487e+01 2.02501002e+02 4.72035293e+01 2.02500808e+02 4.72037072e+01 2.02500711e+02 4.72037100e+01 2.02500350e+02 4.72037203e+01 2.02500284e+02 4.72037002e+01 2.02500249e+02 4.72036571e+01 2.02500234e+02 4.72034119e+01 2.02500255e+02 4.72033617e+01 2.02500327e+02 4.72033431e+01 2.02500652e+02 4.72034283e+01 2.02500926e+02 4.72034818e+01 2.02501023e+02 4.72034790e+01 2.02501002e+02 4.72035293e+01 2.02498164e+02 4.72017567e+01 2.02498066e+02 4.72017595e+01 2.02497770e+02 4.72016531e+01 2.02497735e+02 4.72014888e+01 2.02498027e+02 4.72014632e+01 2.02498237e+02 4.72016334e+01 2.02498164e+02 4.72017567e+01 2.02461191e+02 4.71786510e+01 2.02461344e+02 4.71787940e+01 2.02461327e+02 4.71790352e+01 2.02460965e+02 4.71791084e+01 2.02460817e+02 4.71793149e+01 2.02460895e+02 4.71794510e+01 2.02460942e+02 4.71796920e+01 2.02460805e+02 4.71798426e+01 2.02461009e+02 4.71800175e+01 2.02461421e+02 4.71800386e+01 2.02461502e+02 4.71800425e+01 2.02461513e+02 4.71799705e+01 2.02461428e+02 4.71797081e+01 2.02461398e+02 4.71796781e+01 2.02461370e+02 4.71794252e+01 2.02461392e+02 4.71793749e+01 2.02461611e+02 4.71792129e+01 2.02461594e+02 4.71789347e+01 2.02461567e+02 4.71788859e+01 2.02461386e+02 4.71787633e+01 2.02461191e+02 4.71786510e+01 2.02496746e+02 4.72011703e+01 2.02496668e+02 4.72011658e+01 2.02496655e+02 4.72011139e+01 2.02496742e+02 4.72011114e+01 2.02496746e+02 4.72011703e+01 2.02495748e+02 4.72005473e+01 2.02495744e+02 4.72005474e+01 2.02495371e+02 4.72004980e+01 2.02495384e+02 4.72003201e+01 2.02495620e+02 4.72003134e+01 2.02495749e+02 4.72005437e+01 2.02495748e+02 4.72005473e+01 2.02477520e+02 4.71891590e+01 2.02477580e+02 4.71892433e+01 2.02477708e+02 4.71892765e+01 2.02477701e+02 4.71891539e+01 2.02477520e+02 4.71891590e+01 2.02473990e+02 4.71869522e+01 2.02473950e+02 4.71870454e+01 2.02474131e+02 4.71870403e+01 2.02474210e+02 4.71868539e+01 2.02473990e+02 4.71869522e+01 2.02499656e+02 4.72032867e+01 2.02499517e+02 4.72032906e+01 2.02499532e+02 4.72032092e+01 2.02499631e+02 4.72032064e+01 2.02499656e+02 4.72032867e+01 2.02493430e+02 4.71993983e+01 2.02493356e+02 4.71993839e+01 2.02493354e+02 4.71993509e+01 2.02493426e+02 4.71993323e+01 2.02493430e+02 4.71993983e+01 2.02490050e+02 4.71972870e+01 2.02490035e+02 4.71972830e+01 2.02490033e+02 4.71972767e+01 2.02490044e+02 4.71972764e+01 2.02490050e+02 4.71972870e+01 2.02470416e+02 4.71850173e+01 2.02470421e+02 4.71850991e+01 2.02470572e+02 4.71851152e+01 2.02470565e+02 4.71849926e+01 2.02470416e+02 4.71850173e+01 2.02465322e+02 4.71818328e+01 2.02465149e+02 4.71818377e+01 2.02465142e+02 4.71817200e+01 2.02465281e+02 4.71817403e+01 2.02465322e+02 4.71818328e+01 2.02492946e+02 4.71993956e+01 2.02492752e+02 4.71995736e+01 2.02492686e+02 4.71995534e+01 2.02492676e+02 4.71995261e+01 2.02492666e+02 4.71992433e+01 2.02492664e+02 4.71992192e+01 2.02492699e+02 4.71992182e+01 2.02492944e+02 4.71993626e+01 2.02492946e+02 4.71993956e+01 2.02491753e+02 4.71986504e+01 2.02491705e+02 4.71986518e+01 2.02491295e+02 4.71986635e+01 2.02491224e+02 4.71986821e+01 2.02491245e+02 4.71986319e+01 2.02491464e+02 4.71984697e+01 2.02491513e+02 4.71984683e+01 2.02491751e+02 4.71986174e+01 2.02491753e+02 4.71986504e+01 2.02486934e+02 4.71956395e+01 2.02486783e+02 4.71957813e+01 2.02487019e+02 4.71956927e+01 2.02487129e+02 4.71955259e+01 2.02486934e+02 4.71956395e+01 2.02468248e+02 4.71839610e+01 2.02468252e+02 4.71840988e+01 2.02468445e+02 4.71840846e+01 2.02468389e+02 4.71839979e+01 2.02468248e+02 4.71839610e+01 2.02465861e+02 4.71824688e+01 2.02465657e+02 4.71824385e+01 2.02465672e+02 4.71823509e+01 2.02465767e+02 4.71823571e+01 2.02465861e+02 4.71824688e+01 2.02493434e+02 4.71999996e+01 2.02493402e+02 4.72000005e+01 2.02493392e+02 4.71999732e+01 2.02493441e+02 4.71999719e+01 2.02493434e+02 4.71999996e+01 2.02488901e+02 4.71971677e+01 2.02488838e+02 4.71971916e+01 2.02488859e+02 4.71971414e+01 2.02488900e+02 4.71971457e+01 2.02488901e+02 4.71971677e+01 2.02469707e+02 4.71851728e+01 2.02469628e+02 4.71853592e+01 2.02469848e+02 4.71852609e+01 2.02469888e+02 4.71851677e+01 2.02469707e+02 4.71851728e+01 2.02468898e+02 4.71846668e+01 2.02468913e+02 4.71849120e+01 2.02469180e+02 4.71848430e+01 2.02469172e+02 4.71847204e+01 2.02468898e+02 4.71846668e+01 2.02485660e+02 4.71954418e+01 2.02485671e+02 4.71956273e+01 2.02485910e+02 4.71957763e+01 2.02486183e+02 4.71957685e+01 2.02486171e+02 4.71955831e+01 2.02485933e+02 4.71954340e+01 2.02485660e+02 4.71954418e+01 2.02461920e+02 4.71806029e+01 2.02461893e+02 4.71806651e+01 2.02461998e+02 4.71806519e+01 2.02462009e+02 4.71805799e+01 2.02461920e+02 4.71806029e+01 2.02500163e+02 4.72048002e+01 2.02500091e+02 4.72048187e+01 2.02500121e+02 4.72047738e+01 2.02500153e+02 4.72047729e+01 2.02500163e+02 4.72048002e+01 2.02493412e+02 4.72005838e+01 2.02493073e+02 4.72005693e+01 2.02492824e+02 4.72004274e+01 2.02492826e+02 4.72002177e+01 2.02493134e+02 4.72001984e+01 2.02493362e+02 4.72003554e+01 2.02493412e+02 4.72005838e+01 2.02489591e+02 4.71981974e+01 2.02489210e+02 4.71982178e+01 2.02489120e+02 4.71979592e+01 2.02489116e+02 4.71979004e+01 2.02489203e+02 4.71978979e+01 2.02489589e+02 4.71979375e+01 2.02489591e+02 4.71981974e+01 2.02468366e+02 4.71849325e+01 2.02468351e+02 4.71850019e+01 2.02468365e+02 4.71852314e+01 2.02468255e+02 4.71853982e+01 2.02468490e+02 4.71853097e+01 2.02468860e+02 4.71852417e+01 2.02468843e+02 4.71849636e+01 2.02468581e+02 4.71848317e+01 2.02468366e+02 4.71849325e+01 2.02464310e+02 4.71823969e+01 2.02463947e+02 4.71824693e+01 2.02463881e+02 4.71824491e+01 2.02463884e+02 4.71824298e+01 2.02463869e+02 4.71821327e+01 2.02463870e+02 4.71821220e+01 2.02463895e+02 4.71821140e+01 2.02464264e+02 4.71821662e+01 2.02464310e+02 4.71823969e+01 2.02492477e+02 4.72002992e+01 2.02492094e+02 4.72003166e+01 2.02491966e+02 4.72000856e+01 2.02491820e+02 4.71998885e+01 2.02492145e+02 4.71999537e+01 2.02492462e+02 4.72000448e+01 2.02492477e+02 4.72002992e+01 2.02477780e+02 4.71911164e+01 2.02477881e+02 4.71912977e+01 2.02478156e+02 4.71913513e+01 2.02478011e+02 4.71912019e+01 2.02477780e+02 4.71911164e+01 2.02465766e+02 4.71836061e+01 2.02465382e+02 4.71836653e+01 2.02465315e+02 4.71836672e+01 2.02465312e+02 4.71836216e+01 2.02465413e+02 4.71833859e+01 2.02465731e+02 4.71833592e+01 2.02465766e+02 4.71836061e+01 2.02494510e+02 4.72018681e+01 2.02494393e+02 4.72018715e+01 2.02494401e+02 4.72017997e+01 2.02494505e+02 4.72017883e+01 2.02494510e+02 4.72018681e+01 2.02493577e+02 4.72012850e+01 2.02493372e+02 4.72013240e+01 2.02493335e+02 4.72011341e+01 2.02493593e+02 4.72011608e+01 2.02493577e+02 4.72012850e+01 2.02461522e+02 4.71812516e+01 2.02461401e+02 4.71813544e+01 2.02461745e+02 4.71813911e+01 2.02461629e+02 4.71811854e+01 2.02461522e+02 4.71812516e+01 2.02498232e+02 4.72044915e+01 2.02497913e+02 4.72044761e+01 2.02497837e+02 4.72042448e+01 2.02498198e+02 4.72042657e+01 2.02498232e+02 4.72044915e+01 2.02502388e+02 4.72073860e+01 2.02502317e+02 4.72074046e+01 2.02502097e+02 4.72075030e+01 2.02501729e+02 4.72075136e+01 2.02501620e+02 4.72072687e+01 2.02501616e+02 4.72072027e+01 2.02501713e+02 4.72071999e+01 2.02502074e+02 4.72071896e+01 2.02502171e+02 4.72071868e+01 2.02502410e+02 4.72073358e+01 2.02502388e+02 4.72073860e+01 2.02497277e+02 4.72041942e+01 2.02496977e+02 4.72041919e+01 2.02496928e+02 4.72039761e+01 2.02497264e+02 4.72039800e+01 2.02497277e+02 4.72041942e+01 2.02500779e+02 4.72066800e+01 2.02500585e+02 4.72067322e+01 2.02500573e+02 4.72065518e+01 2.02500773e+02 4.72065927e+01 2.02500779e+02 4.72066800e+01 2.02499535e+02 4.72059036e+01 2.02499495e+02 4.72059103e+01 2.02499502e+02 4.72058825e+01 2.02499542e+02 4.72058759e+01 2.02499535e+02 4.72059036e+01 2.02496063e+02 4.72037350e+01 2.02495779e+02 4.72037754e+01 2.02495561e+02 4.72037206e+01 2.02495466e+02 4.72039609e+01 2.02495489e+02 4.72039899e+01 2.02495442e+02 4.72042447e+01 2.02495132e+02 4.72042536e+01 2.02494961e+02 4.72040544e+01 2.02494901e+02 4.72039067e+01 2.02495079e+02 4.72037192e+01 2.02495362e+02 4.72035968e+01 2.02495525e+02 4.72033994e+01 2.02495840e+02 4.72034052e+01 2.02496040e+02 4.72035829e+01 2.02496063e+02 4.72037350e+01 2.02489354e+02 4.71998439e+01 2.02489183e+02 4.71998649e+01 2.02488825e+02 4.71998039e+01 2.02488814e+02 4.71995063e+01 2.02489252e+02 4.71994885e+01 2.02489348e+02 4.71997430e+01 2.02489354e+02 4.71998439e+01 2.02458956e+02 4.71808442e+01 2.02458812e+02 4.71809899e+01 2.02459138e+02 4.71810741e+01 2.02459227e+02 4.71810136e+01 2.02459393e+02 4.71808860e+01 2.02459026e+02 4.71808318e+01 2.02458956e+02 4.71808442e+01 2.02501539e+02 4.72077528e+01 2.02501400e+02 4.72077568e+01 2.02501322e+02 4.72076173e+01 2.02501599e+02 4.72076094e+01 2.02501539e+02 4.72077528e+01 2.02500324e+02 4.72069941e+01 2.02500250e+02 4.72069797e+01 2.02500248e+02 4.72069467e+01 2.02500320e+02 4.72069281e+01 2.02500324e+02 4.72069941e+01 2.02495772e+02 4.72041517e+01 2.02495701e+02 4.72041584e+01 2.02495583e+02 4.72040337e+01 2.02495776e+02 4.72041034e+01 2.02495772e+02 4.72041517e+01 2.02491780e+02 4.72016588e+01 2.02491567e+02 4.72016820e+01 2.02491600e+02 4.72015463e+01 2.02491746e+02 4.72015501e+01 2.02491780e+02 4.72016588e+01 2.02466349e+02 4.71857663e+01 2.02466310e+02 4.71858595e+01 2.02466249e+02 4.71860030e+01 2.02466267e+02 4.71862164e+01 2.02466637e+02 4.71862454e+01 2.02466822e+02 4.71860622e+01 2.02466807e+02 4.71858171e+01 2.02466569e+02 4.71856680e+01 2.02466349e+02 4.71857663e+01 2.02502298e+02 4.72085261e+01 2.02502135e+02 4.72085150e+01 2.02502057e+02 4.72083755e+01 2.02502335e+02 4.72083676e+01 2.02502298e+02 4.72085261e+01 2.02500820e+02 4.72076033e+01 2.02500723e+02 4.72076061e+01 2.02500719e+02 4.72075401e+01 2.02500793e+02 4.72075545e+01 2.02500820e+02 4.72076033e+01 2.02499459e+02 4.72067531e+01 2.02499228e+02 4.72067583e+01 2.02499262e+02 4.72066300e+01 2.02499449e+02 4.72065953e+01 2.02499459e+02 4.72067531e+01 2.02496262e+02 4.72050558e+01 2.02496067e+02 4.72052334e+01 2.02496011e+02 4.72052311e+01 2.02495933e+02 4.72051498e+01 2.02496249e+02 4.72050479e+01 2.02496261e+02 4.72050464e+01 2.02496262e+02 4.72050558e+01 2.02495864e+02 4.72048072e+01 2.02495698e+02 4.72048119e+01 2.02495703e+02 4.72047070e+01 2.02495837e+02 4.72047093e+01 2.02495864e+02 4.72048072e+01 2.02490827e+02 4.72016616e+01 2.02490710e+02 4.72016650e+01 2.02490705e+02 4.72015851e+01 2.02490822e+02 4.72015818e+01 2.02490827e+02 4.72016616e+01 2.02502052e+02 4.72089708e+01 2.02502068e+02 4.72092159e+01 2.02502072e+02 4.72092820e+01 2.02502173e+02 4.72094632e+01 2.02502075e+02 4.72095831e+01 2.02501830e+02 4.72097294e+01 2.02501609e+02 4.72098901e+01 2.02501410e+02 4.72100655e+01 2.02501168e+02 4.72102135e+01 2.02501002e+02 4.72104086e+01 2.02500833e+02 4.72104540e+01 2.02500760e+02 4.72102575e+01 2.02501112e+02 4.72101784e+01 2.02501097e+02 4.72099333e+01 2.02500882e+02 4.72097671e+01 2.02500514e+02 4.72097133e+01 2.02500329e+02 4.72096895e+01 2.02500123e+02 4.72096770e+01 2.02500132e+02 4.72095664e+01 2.02500054e+02 4.72094027e+01 2.02500025e+02 4.72092006e+01 2.02500381e+02 4.72091605e+01 2.02500510e+02 4.72092040e+01 2.02500722e+02 4.72090372e+01 2.02501035e+02 4.72089338e+01 2.02501254e+02 4.72087716e+01 2.02501351e+02 4.72087689e+01 2.02501712e+02 4.72087585e+01 2.02501779e+02 4.72087787e+01 2.02502048e+02 4.72089048e+01 2.02502052e+02 4.72089708e+01 2.02463341e+02 4.71847836e+01 2.02462986e+02 4.71847371e+01 2.02462871e+02 4.71844962e+01 2.02462855e+02 4.71844793e+01 2.02462896e+02 4.71844782e+01 2.02463314e+02 4.71844946e+01 2.02463341e+02 4.71847836e+01 2.02493664e+02 4.72040316e+01 2.02493421e+02 4.72041793e+01 2.02493036e+02 4.72041755e+01 2.02493021e+02 4.72039294e+01 2.02493199e+02 4.72037414e+01 2.02493641e+02 4.72037288e+01 2.02493664e+02 4.72040316e+01 2.02489398e+02 4.72013672e+01 2.02489349e+02 4.72013686e+01 2.02489322e+02 4.72013198e+01 2.02489384e+02 4.72013428e+01 2.02489398e+02 4.72013672e+01 2.02497155e+02 4.72065110e+01 2.02496941e+02 4.72064962e+01 2.02496645e+02 4.72063895e+01 2.02496663e+02 4.72062040e+01 2.02496907e+02 4.72061957e+01 2.02497115e+02 4.72063676e+01 2.02497155e+02 4.72065110e+01 2.02490204e+02 4.72021699e+01 2.02490055e+02 4.72021490e+01 2.02490050e+02 4.72020736e+01 2.02490196e+02 4.72020442e+01 2.02490204e+02 4.72021699e+01 2.02489198e+02 4.72018405e+01 2.02489157e+02 4.72018362e+01 2.02488857e+02 4.72017324e+01 2.02488851e+02 4.72016235e+01 2.02489011e+02 4.72016189e+01 2.02489196e+02 4.72018075e+01 2.02489198e+02 4.72018405e+01 2.02496747e+02 4.72068544e+01 2.02496372e+02 4.72069196e+01 2.02496369e+02 4.72069193e+01 2.02496369e+02 4.72069174e+01 2.02496500e+02 4.72067004e+01 2.02496682e+02 4.72066881e+01 2.02496747e+02 4.72068544e+01 2.02498232e+02 4.72080810e+01 2.02497932e+02 4.72081928e+01 2.02497645e+02 4.72082544e+01 2.02497711e+02 4.72080546e+01 2.02497884e+02 4.72078638e+01 2.02498185e+02 4.72078552e+01 2.02498232e+02 4.72080810e+01 2.02494329e+02 4.72056433e+01 2.02494256e+02 4.72058771e+01 2.02494267e+02 4.72059039e+01 2.02494226e+02 4.72058996e+01 2.02493942e+02 4.72057842e+01 2.02493896e+02 4.72056720e+01 2.02493796e+02 4.72055666e+01 2.02493808e+02 4.72053182e+01 2.02494145e+02 4.72053085e+01 2.02494306e+02 4.72055151e+01 2.02494329e+02 4.72056433e+01 2.02500286e+02 4.72099615e+01 2.02500118e+02 4.72100056e+01 2.02500169e+02 4.72098888e+01 2.02500303e+02 4.72098696e+01 2.02500286e+02 4.72099615e+01 2.02493159e+02 4.72055110e+01 2.02492984e+02 4.72055160e+01 2.02492989e+02 4.72054052e+01 2.02493151e+02 4.72053922e+01 2.02493159e+02 4.72055110e+01 2.02498592e+02 4.72095022e+01 2.02498292e+02 4.72096138e+01 2.02498019e+02 4.72096049e+01 2.02498027e+02 4.72094483e+01 2.02498088e+02 4.72092280e+01 2.02498086e+02 4.72091862e+01 2.02498138e+02 4.72091913e+01 2.02498565e+02 4.72092008e+01 2.02498592e+02 4.72095022e+01 2.02482275e+02 4.71993103e+01 2.02482041e+02 4.71992855e+01 2.02482034e+02 4.71991597e+01 2.02482219e+02 4.71991545e+01 2.02482275e+02 4.71993103e+01 2.02494921e+02 4.72075092e+01 2.02494717e+02 4.72076810e+01 2.02494435e+02 4.72076977e+01 2.02494422e+02 4.72074968e+01 2.02494689e+02 4.72073639e+01 2.02494911e+02 4.72073457e+01 2.02494921e+02 4.72075092e+01 2.02485427e+02 4.72015789e+01 2.02485461e+02 4.72016393e+01 2.02485677e+02 4.72017354e+01 2.02485505e+02 4.72016067e+01 2.02485427e+02 4.72015789e+01 2.02499779e+02 4.72108415e+01 2.02499414e+02 4.72108519e+01 2.02499418e+02 4.72106160e+01 2.02499791e+02 4.72105733e+01 2.02499779e+02 4.72108415e+01 2.02492991e+02 4.72066028e+01 2.02492828e+02 4.72066075e+01 2.02492821e+02 4.72064966e+01 2.02492984e+02 4.72064920e+01 2.02492991e+02 4.72066028e+01 2.02482986e+02 4.72003532e+01 2.02482855e+02 4.72003113e+01 2.02482843e+02 4.72002636e+01 2.02482938e+02 4.72002494e+01 2.02482986e+02 4.72003532e+01 2.02498427e+02 4.72102966e+01 2.02498368e+02 4.72103231e+01 2.02498398e+02 4.72102782e+01 2.02498438e+02 4.72102715e+01 2.02498427e+02 4.72102966e+01 2.02488178e+02 4.72038958e+01 2.02488106e+02 4.72039143e+01 2.02488102e+02 4.72038483e+01 2.02488168e+02 4.72038685e+01 2.02488178e+02 4.72038958e+01 2.02487481e+02 4.72037598e+01 2.02487433e+02 4.72037612e+01 2.02487439e+02 4.72037334e+01 2.02487503e+02 4.72037095e+01 2.02487481e+02 4.72037598e+01 2.02497168e+02 4.72101090e+01 2.02496899e+02 4.72101067e+01 2.02496889e+02 4.72099342e+01 2.02497180e+02 4.72098993e+01 2.02497168e+02 4.72101090e+01 2.02488704e+02 4.72051221e+01 2.02488664e+02 4.72051287e+01 2.02488662e+02 4.72050957e+01 2.02488711e+02 4.72050943e+01 2.02488704e+02 4.72051221e+01 2.02482657e+02 4.72013443e+01 2.02482665e+02 4.72014277e+01 2.02482788e+02 4.72016619e+01 2.02482758e+02 4.72017068e+01 2.02482695e+02 4.72017307e+01 2.02482459e+02 4.72018192e+01 2.02482122e+02 4.72019076e+01 2.02481862e+02 4.72020441e+01 2.02481821e+02 4.72020507e+01 2.02481819e+02 4.72020177e+01 2.02481920e+02 4.72017811e+01 2.02481854e+02 4.72017011e+01 2.02481703e+02 4.72014874e+01 2.02481694e+02 4.72013411e+01 2.02481607e+02 4.72012330e+01 2.02481591e+02 4.72009778e+01 2.02481916e+02 4.72008812e+01 2.02482090e+02 4.72008762e+01 2.02482298e+02 4.72010477e+01 2.02482602e+02 4.72011487e+01 2.02482657e+02 4.72013443e+01 2.02499021e+02 4.72118639e+01 2.02498762e+02 4.72120011e+01 2.02498903e+02 4.72122055e+01 2.02498837e+02 4.72123471e+01 2.02498595e+02 4.72124329e+01 2.02498338e+02 4.72123347e+01 2.02498295e+02 4.72123293e+01 2.02498243e+02 4.72122757e+01 2.02498392e+02 4.72120693e+01 2.02498464e+02 4.72118790e+01 2.02498486e+02 4.72118287e+01 2.02498557e+02 4.72118101e+01 2.02498824e+02 4.72117411e+01 2.02499058e+02 4.72117659e+01 2.02499021e+02 4.72118639e+01 2.02487539e+02 4.72046933e+01 2.02487467e+02 4.72047119e+01 2.02487261e+02 4.72048187e+01 2.02486981e+02 4.72049430e+01 2.02486902e+02 4.72051294e+01 2.02486906e+02 4.72051954e+01 2.02486732e+02 4.72053861e+01 2.02486619e+02 4.72056147e+01 2.02486616e+02 4.72056663e+01 2.02486763e+02 4.72058827e+01 2.02486747e+02 4.72059934e+01 2.02486480e+02 4.72061262e+01 2.02486563e+02 4.72063560e+01 2.02486624e+02 4.72065148e+01 2.02486341e+02 4.72065198e+01 2.02486233e+02 4.72065698e+01 2.02485975e+02 4.72067077e+01 2.02485650e+02 4.72068040e+01 2.02485550e+02 4.72070406e+01 2.02485510e+02 4.72071338e+01 2.02485474e+02 4.72072923e+01 2.02485334e+02 4.72075041e+01 2.02485224e+02 4.72076710e+01 2.02485194e+02 4.72077159e+01 2.02485162e+02 4.72077168e+01 2.02484929e+02 4.72075632e+01 2.02484529e+02 4.72075995e+01 2.02484357e+02 4.72077913e+01 2.02484130e+02 4.72079485e+01 2.02483967e+02 4.72081460e+01 2.02483794e+02 4.72083375e+01 2.02483657e+02 4.72085031e+01 2.02483629e+02 4.72085335e+01 2.02483598e+02 4.72085466e+01 2.02483375e+02 4.72086739e+01 2.02483280e+02 4.72087818e+01 2.02483244e+02 4.72088914e+01 2.02483108e+02 4.72091056e+01 2.02482857e+02 4.72090939e+01 2.02482891e+02 4.72089701e+01 2.02482829e+02 4.72087893e+01 2.02482559e+02 4.72087623e+01 2.02482420e+02 4.72087663e+01 2.02482151e+02 4.72086398e+01 2.02481825e+02 4.72085552e+01 2.02481571e+02 4.72084170e+01 2.02481362e+02 4.72082465e+01 2.02481414e+02 4.72080474e+01 2.02481574e+02 4.72078478e+01 2.02481810e+02 4.72076961e+01 2.02482073e+02 4.72075611e+01 2.02482155e+02 4.72073349e+01 2.02482154e+02 4.72073129e+01 2.02482194e+02 4.72073062e+01 2.02482497e+02 4.72072279e+01 2.02482832e+02 4.72071377e+01 2.02482923e+02 4.72068958e+01 2.02483143e+02 4.72067337e+01 2.02483315e+02 4.72065422e+01 2.02483535e+02 4.72063801e+01 2.02483867e+02 4.72063957e+01 2.02484159e+02 4.72064710e+01 2.02484353e+02 4.72062930e+01 2.02484223e+02 4.72061330e+01 2.02484208e+02 4.72059036e+01 2.02484319e+02 4.72057367e+01 2.02484115e+02 4.72055619e+01 2.02484114e+02 4.72055454e+01 2.02484250e+02 4.72053309e+01 2.02484479e+02 4.72052929e+01 2.02484753e+02 4.72053465e+01 2.02485006e+02 4.72052055e+01 2.02485039e+02 4.72052045e+01 2.02485465e+02 4.72051924e+01 2.02485505e+02 4.72051858e+01 2.02485807e+02 4.72051075e+01 2.02485897e+02 4.72048959e+01 2.02485903e+02 4.72048682e+01 2.02485986e+02 4.72046209e+01 2.02486152e+02 4.72044250e+01 2.02486550e+02 4.72044137e+01 2.02486621e+02 4.72046864e+01 2.02486881e+02 4.72045817e+01 2.02487169e+02 4.72044625e+01 2.02487437e+02 4.72044089e+01 2.02487560e+02 4.72046431e+01 2.02487539e+02 4.72046933e+01 2.02485450e+02 4.72033881e+01 2.02485569e+02 4.72035112e+01 2.02485800e+02 4.72036660e+01 2.02485906e+02 4.72036732e+01 2.02485887e+02 4.72036021e+01 2.02485735e+02 4.72033884e+01 2.02485450e+02 4.72033881e+01 2.02496874e+02 4.72108225e+01 2.02496809e+02 4.72108244e+01 2.02496806e+02 4.72107801e+01 2.02496871e+02 4.72107783e+01 2.02496874e+02 4.72108225e+01 2.02489439e+02 4.72061791e+01 2.02489135e+02 4.72062882e+01 2.02488862e+02 4.72062845e+01 2.02488779e+02 4.72060662e+01 2.02489016e+02 4.72059148e+01 2.02489315e+02 4.72059493e+01 2.02489439e+02 4.72061791e+01 2.02482811e+02 4.72020391e+01 2.02482714e+02 4.72020419e+01 2.02482710e+02 4.72019758e+01 2.02482776e+02 4.72019960e+01 2.02482811e+02 4.72020391e+01 2.02481386e+02 4.72014479e+01 2.02481334e+02 4.72014349e+01 2.02481323e+02 4.72014081e+01 2.02481383e+02 4.72013985e+01 2.02481386e+02 4.72014479e+01 2.02496414e+02 4.72111335e+01 2.02496386e+02 4.72111371e+01 2.02496376e+02 4.72111098e+01 2.02496417e+02 4.72111141e+01 2.02496414e+02 4.72111335e+01 2.02488099e+02 4.72059407e+01 2.02488025e+02 4.72059263e+01 2.02488023e+02 4.72058932e+01 2.02488095e+02 4.72058747e+01 2.02488099e+02 4.72059407e+01 2.02494882e+02 4.72104761e+01 2.02494612e+02 4.72104954e+01 2.02494600e+02 4.72102999e+01 2.02494886e+02 4.72102933e+01 2.02494882e+02 4.72104761e+01 2.02482872e+02 4.72029742e+01 2.02482775e+02 4.72032130e+01 2.02482803e+02 4.72032777e+01 2.02482786e+02 4.72035189e+01 2.02482778e+02 4.72036213e+01 2.02482929e+02 4.72038352e+01 2.02482972e+02 4.72039347e+01 2.02483016e+02 4.72040960e+01 2.02483222e+02 4.72042692e+01 2.02483278e+02 4.72044250e+01 2.02482931e+02 4.72045073e+01 2.02482746e+02 4.72046905e+01 2.02482607e+02 4.72049034e+01 2.02482281e+02 4.72049989e+01 2.02482087e+02 4.72051768e+01 2.02481834e+02 4.72053179e+01 2.02481771e+02 4.72053417e+01 2.02481410e+02 4.72053520e+01 2.02481540e+02 4.72055120e+01 2.02481510e+02 4.72057140e+01 2.02481303e+02 4.72058833e+01 2.02481036e+02 4.72060160e+01 2.02480873e+02 4.72060049e+01 2.02480685e+02 4.72058181e+01 2.02480676e+02 4.72057908e+01 2.02480658e+02 4.72055127e+01 2.02480631e+02 4.72054639e+01 2.02480728e+02 4.72054611e+01 2.02480995e+02 4.72053921e+01 2.02481074e+02 4.72052057e+01 2.02481070e+02 4.72051397e+01 2.02481268e+02 4.72049640e+01 2.02481473e+02 4.72049109e+01 2.02481747e+02 4.72049645e+01 2.02481675e+02 4.72047619e+01 2.02481730e+02 4.72046547e+01 2.02481860e+02 4.72044364e+01 2.02481803e+02 4.72043419e+01 2.02481870e+02 4.72041433e+01 2.02481997e+02 4.72039240e+01 2.02482017e+02 4.72038580e+01 2.02482047e+02 4.72036560e+01 2.02482137e+02 4.72034445e+01 2.02481727e+02 4.72034561e+01 2.02481679e+02 4.72034575e+01 2.02481452e+02 4.72032998e+01 2.02481451e+02 4.72032833e+01 2.02481554e+02 4.72030488e+01 2.02481640e+02 4.72028352e+01 2.02481647e+02 4.72028074e+01 2.02481710e+02 4.72027836e+01 2.02481977e+02 4.72027146e+01 2.02482316e+02 4.72026270e+01 2.02482357e+02 4.72026314e+01 2.02482392e+02 4.72026745e+01 2.02482493e+02 4.72028557e+01 2.02482680e+02 4.72028545e+01 2.02482880e+02 4.72028955e+01 2.02482872e+02 4.72029742e+01 2.02497921e+02 4.72126729e+01 2.02497783e+02 4.72127076e+01 2.02497727e+02 4.72125518e+01 2.02497938e+02 4.72125930e+01 2.02497921e+02 4.72126729e+01 2.02495853e+02 4.72119798e+01 2.02495679e+02 4.72119848e+01 2.02495688e+02 4.72118767e+01 2.02495829e+02 4.72118738e+01 2.02495853e+02 4.72119798e+01 2.02484233e+02 4.72050213e+01 2.02483999e+02 4.72049964e+01 2.02484016e+02 4.72048858e+01 2.02484177e+02 4.72048654e+01 2.02484233e+02 4.72050213e+01 2.02483417e+02 4.72048107e+01 2.02483345e+02 4.72048293e+01 2.02483375e+02 4.72047844e+01 2.02483415e+02 4.72047777e+01 2.02483417e+02 4.72048107e+01 2.02495659e+02 4.72127559e+01 2.02495455e+02 4.72128014e+01 2.02495504e+02 4.72126593e+01 2.02495653e+02 4.72126550e+01 2.02495659e+02 4.72127559e+01 2.02480799e+02 4.72034743e+01 2.02480763e+02 4.72034836e+01 2.02480773e+02 4.72034585e+01 2.02480798e+02 4.72034578e+01 2.02480799e+02 4.72034743e+01 2.02495916e+02 4.72132153e+01 2.02495735e+02 4.72132454e+01 2.02495784e+02 4.72131334e+01 2.02495944e+02 4.72130902e+01 2.02495916e+02 4.72132153e+01 2.02482137e+02 4.72046093e+01 2.02482150e+02 4.72047358e+01 2.02482300e+02 4.72047111e+01 2.02482323e+02 4.72046081e+01 2.02482137e+02 4.72046093e+01 2.02481224e+02 4.72046374e+01 2.02481018e+02 4.72045963e+01 2.02480989e+02 4.72044906e+01 2.02481165e+02 4.72044881e+01 2.02481224e+02 4.72046374e+01 2.02480630e+02 4.72042666e+01 2.02480713e+02 4.72044965e+01 2.02480697e+02 4.72046072e+01 2.02480491e+02 4.72046602e+01 2.02480311e+02 4.72046654e+01 2.02480033e+02 4.72046733e+01 2.02480070e+02 4.72045148e+01 2.02480289e+02 4.72043527e+01 2.02480278e+02 4.72041673e+01 2.02480294e+02 4.72040566e+01 2.02480455e+02 4.72040363e+01 2.02480628e+02 4.72042336e+01 2.02480630e+02 4.72042666e+01 2.02480788e+02 4.72049635e+01 2.02480510e+02 4.72049714e+01 2.02480499e+02 4.72047828e+01 2.02480710e+02 4.72048240e+01 2.02480788e+02 4.72049635e+01 2.02494298e+02 4.72137011e+01 2.02494205e+02 4.72137250e+01 2.02494237e+02 4.72136628e+01 2.02494296e+02 4.72136578e+01 2.02494298e+02 4.72137011e+01 2.02480807e+02 4.72052747e+01 2.02480530e+02 4.72052826e+01 2.02480518e+02 4.72050940e+01 2.02480796e+02 4.72050861e+01 2.02480807e+02 4.72052747e+01 2.02482126e+02 4.72063978e+01 2.02481907e+02 4.72065599e+01 2.02481768e+02 4.72067724e+01 2.02481623e+02 4.72067518e+01 2.02481383e+02 4.72066043e+01 2.02481340e+02 4.72065048e+01 2.02481559e+02 4.72063427e+01 2.02481722e+02 4.72063538e+01 2.02482097e+02 4.72063793e+01 2.02482137e+02 4.72063727e+01 2.02482126e+02 4.72063978e+01 2.02480349e+02 4.72052877e+01 2.02480387e+02 4.72053881e+01 2.02480357e+02 4.72055920e+01 2.02480106e+02 4.72057339e+01 2.02479806e+02 4.72058461e+01 2.02479743e+02 4.72061058e+01 2.02479473e+02 4.72062361e+01 2.02479143e+02 4.72063296e+01 2.02479008e+02 4.72065444e+01 2.02478892e+02 4.72064926e+01 2.02478890e+02 4.72064706e+01 2.02478822e+02 4.72062191e+01 2.02478830e+02 4.72061338e+01 2.02478771e+02 4.72059308e+01 2.02478763e+02 4.72057926e+01 2.02478947e+02 4.72056082e+01 2.02479254e+02 4.72055742e+01 2.02479453e+02 4.72056253e+01 2.02479669e+02 4.72054613e+01 2.02479809e+02 4.72052495e+01 2.02479809e+02 4.72051640e+01 2.02479841e+02 4.72049703e+01 2.02480123e+02 4.72049326e+01 2.02480338e+02 4.72050991e+01 2.02480349e+02 4.72052877e+01 2.02494746e+02 4.72148779e+01 2.02494392e+02 4.72148879e+01 2.02494333e+02 4.72146201e+01 2.02494718e+02 4.72146473e+01 2.02494746e+02 4.72148779e+01 2.02492095e+02 4.72138207e+01 2.02491875e+02 4.72138196e+01 2.02491855e+02 4.72136709e+01 2.02492084e+02 4.72136648e+01 2.02492095e+02 4.72138207e+01 2.02480533e+02 4.72065990e+01 2.02480592e+02 4.72068630e+01 2.02480635e+02 4.72069625e+01 2.02480511e+02 4.72071841e+01 2.02480268e+02 4.72073311e+01 2.02480048e+02 4.72074932e+01 2.02479736e+02 4.72075971e+01 2.02479452e+02 4.72077191e+01 2.02479426e+02 4.72077242e+01 2.02479056e+02 4.72077710e+01 2.02478790e+02 4.72079037e+01 2.02478749e+02 4.72078994e+01 2.02478323e+02 4.72079115e+01 2.02478283e+02 4.72079181e+01 2.02478281e+02 4.72078851e+01 2.02478454e+02 4.72076936e+01 2.02478659e+02 4.72076406e+01 2.02478839e+02 4.72076354e+01 2.02478832e+02 4.72075129e+01 2.02478907e+02 4.72073785e+01 2.02479171e+02 4.72072446e+01 2.02479307e+02 4.72070302e+01 2.02479361e+02 4.72067965e+01 2.02479283e+02 4.72067160e+01 2.02479431e+02 4.72067449e+01 2.02479666e+02 4.72066563e+01 2.02479777e+02 4.72064895e+01 2.02479798e+02 4.72064392e+01 2.02479847e+02 4.72064379e+01 2.02480256e+02 4.72064262e+01 2.02480328e+02 4.72064076e+01 2.02480532e+02 4.72065825e+01 2.02480533e+02 4.72065990e+01 2.02494165e+02 4.72154126e+01 2.02494096e+02 4.72154324e+01 2.02494043e+02 4.72153367e+01 2.02494179e+02 4.72153708e+01 2.02494165e+02 4.72154126e+01 2.02484163e+02 4.72094652e+01 2.02484091e+02 4.72094838e+01 2.02484112e+02 4.72094336e+01 2.02484161e+02 4.72094322e+01 2.02484163e+02 4.72094652e+01 2.02484571e+02 4.72100195e+01 2.02484548e+02 4.72101225e+01 2.02484511e+02 4.72102810e+01 2.02484286e+02 4.72103161e+01 2.02484168e+02 4.72103661e+01 2.02484181e+02 4.72103933e+01 2.02484396e+02 4.72105599e+01 2.02484633e+02 4.72107100e+01 2.02484671e+02 4.72109791e+01 2.02484347e+02 4.72110761e+01 2.02484064e+02 4.72111985e+01 2.02483995e+02 4.72111819e+01 2.02483643e+02 4.72111160e+01 2.02483343e+02 4.72110471e+01 2.02483271e+02 4.72110657e+01 2.02483056e+02 4.72108995e+01 2.02483028e+02 4.72108506e+01 2.02482897e+02 4.72106915e+01 2.02482649e+02 4.72105490e+01 2.02482599e+02 4.72102832e+01 2.02482599e+02 4.72102609e+01 2.02482540e+02 4.72099790e+01 2.02482513e+02 4.72099302e+01 2.02482411e+02 4.72097489e+01 2.02482262e+02 4.72097736e+01 2.02482267e+02 4.72098553e+01 2.02482237e+02 4.72100573e+01 2.02482213e+02 4.72102205e+01 2.02482221e+02 4.72103462e+01 2.02481991e+02 4.72103843e+01 2.02481811e+02 4.72103894e+01 2.02481533e+02 4.72103973e+01 2.02481522e+02 4.72102087e+01 2.02481600e+02 4.72100223e+01 2.02481240e+02 4.72100326e+01 2.02481146e+02 4.72102729e+01 2.02481171e+02 4.72103397e+01 2.02481389e+02 4.72105037e+01 2.02481635e+02 4.72105786e+01 2.02481732e+02 4.72105758e+01 2.02481736e+02 4.72106419e+01 2.02481517e+02 4.72108040e+01 2.02481532e+02 4.72110491e+01 2.02481511e+02 4.72110993e+01 2.02481316e+02 4.72112772e+01 2.02481219e+02 4.72112800e+01 2.02480858e+02 4.72112903e+01 2.02480784e+02 4.72112758e+01 2.02480375e+02 4.72112875e+01 2.02480392e+02 4.72115656e+01 2.02480394e+02 4.72115986e+01 2.02480200e+02 4.72117766e+01 2.02479981e+02 4.72119387e+01 2.02479736e+02 4.72120849e+01 2.02479917e+02 4.72122420e+01 2.02480073e+02 4.72122957e+01 2.02480293e+02 4.72122895e+01 2.02480294e+02 4.72124340e+01 2.02480147e+02 4.72126411e+01 2.02479766e+02 4.72127020e+01 2.02479726e+02 4.72127087e+01 2.02479723e+02 4.72126756e+01 2.02479542e+02 4.72125186e+01 2.02479483e+02 4.72125253e+01 2.02479089e+02 4.72125282e+01 2.02478930e+02 4.72123205e+01 2.02478873e+02 4.72121446e+01 2.02479180e+02 4.72121359e+01 2.02479440e+02 4.72121996e+01 2.02479425e+02 4.72119545e+01 2.02479158e+02 4.72120234e+01 2.02478881e+02 4.72120313e+01 2.02478869e+02 4.72118427e+01 2.02478862e+02 4.72117202e+01 2.02478560e+02 4.72116498e+01 2.02478526e+02 4.72116425e+01 2.02478280e+02 4.72114991e+01 2.02478272e+02 4.72114698e+01 2.02478316e+02 4.72111982e+01 2.02478314e+02 4.72111488e+01 2.02478075e+02 4.72110001e+01 2.02478058e+02 4.72107379e+01 2.02478039e+02 4.72107009e+01 2.02477791e+02 4.72105591e+01 2.02477627e+02 4.72103545e+01 2.02477401e+02 4.72103275e+01 2.02477191e+02 4.72104953e+01 2.02477057e+02 4.72107110e+01 2.02476858e+02 4.72108856e+01 2.02476506e+02 4.72108577e+01 2.02476355e+02 4.72106437e+01 2.02476008e+02 4.72106536e+01 2.02475981e+02 4.72109200e+01 2.02476002e+02 4.72109489e+01 2.02476168e+02 4.72111071e+01 2.02476152e+02 4.72113420e+01 2.02475794e+02 4.72113833e+01 2.02475675e+02 4.72113432e+01 2.02475442e+02 4.72113183e+01 2.02475386e+02 4.72111625e+01 2.02475465e+02 4.72109760e+01 2.02475111e+02 4.72109121e+01 2.02474990e+02 4.72109155e+01 2.02474620e+02 4.72109835e+01 2.02474472e+02 4.72111900e+01 2.02474418e+02 4.72114237e+01 2.02474827e+02 4.72114121e+01 2.02474876e+02 4.72114107e+01 2.02475115e+02 4.72115598e+01 2.02475108e+02 4.72115875e+01 2.02475177e+02 4.72118390e+01 2.02475496e+02 4.72118300e+01 2.02475763e+02 4.72116972e+01 2.02475800e+02 4.72117045e+01 2.02476160e+02 4.72117639e+01 2.02476309e+02 4.72117392e+01 2.02476679e+02 4.72116712e+01 2.02476662e+02 4.72113931e+01 2.02476668e+02 4.72113653e+01 2.02476888e+02 4.72112032e+01 2.02476936e+02 4.72111908e+01 2.02477180e+02 4.72110866e+01 2.02477427e+02 4.72109420e+01 2.02477741e+02 4.72108390e+01 2.02477937e+02 4.72107764e+01 2.02477949e+02 4.72109687e+01 2.02477867e+02 4.72111533e+01 2.02477837e+02 4.72111983e+01 2.02477698e+02 4.72114101e+01 2.02477572e+02 4.72116307e+01 2.02477553e+02 4.72117108e+01 2.02477773e+02 4.72118739e+01 2.02477784e+02 4.72120625e+01 2.02477445e+02 4.72121501e+01 2.02477408e+02 4.72121429e+01 2.02476975e+02 4.72121552e+01 2.02476993e+02 4.72124498e+01 2.02477032e+02 4.72124901e+01 2.02477162e+02 4.72126501e+01 2.02477176e+02 4.72128795e+01 2.02476838e+02 4.72128891e+01 2.02476718e+02 4.72128926e+01 2.02476340e+02 4.72129553e+01 2.02476248e+02 4.72131972e+01 2.02476169e+02 4.72133836e+01 2.02476135e+02 4.72134259e+01 2.02476076e+02 4.72134524e+01 2.02475843e+02 4.72135425e+01 2.02475671e+02 4.72137342e+01 2.02475422e+02 4.72138779e+01 2.02475056e+02 4.72138806e+01 2.02474851e+02 4.72137060e+01 2.02474823e+02 4.72135038e+01 2.02474956e+02 4.72133032e+01 2.02474959e+02 4.72132893e+01 2.02475115e+02 4.72130877e+01 2.02475071e+02 4.72128934e+01 2.02474727e+02 4.72128452e+01 2.02474694e+02 4.72128461e+01 2.02474357e+02 4.72129136e+01 2.02474208e+02 4.72131197e+01 2.02473989e+02 4.72132818e+01 2.02473965e+02 4.72133848e+01 2.02474081e+02 4.72136243e+01 2.02474078e+02 4.72136366e+01 2.02474049e+02 4.72136483e+01 2.02473699e+02 4.72135813e+01 2.02473518e+02 4.72135864e+01 2.02473241e+02 4.72135943e+01 2.02472966e+02 4.72135407e+01 2.02472888e+02 4.72137909e+01 2.02472848e+02 4.72138841e+01 2.02472860e+02 4.72140727e+01 2.02472781e+02 4.72142591e+01 2.02472785e+02 4.72143251e+01 2.02472624e+02 4.72145235e+01 2.02472351e+02 4.72145768e+01 2.02472230e+02 4.72143409e+01 2.02471963e+02 4.72144098e+01 2.02471650e+02 4.72145132e+01 2.02471552e+02 4.72145159e+01 2.02471191e+02 4.72145262e+01 2.02470938e+02 4.72146672e+01 2.02470875e+02 4.72146910e+01 2.02470871e+02 4.72146250e+01 2.02471115e+02 4.72144787e+01 2.02471098e+02 4.72142006e+01 2.02471071e+02 4.72141517e+01 2.02470921e+02 4.72140059e+01 2.02470836e+02 4.72140049e+01 2.02470450e+02 4.72140631e+01 2.02470350e+02 4.72142997e+01 2.02470271e+02 4.72144861e+01 2.02470510e+02 4.72146352e+01 2.02470514e+02 4.72147013e+01 2.02470417e+02 4.72147040e+01 2.02470150e+02 4.72147730e+01 2.02469939e+02 4.72147317e+01 2.02469611e+02 4.72146483e+01 2.02469531e+02 4.72146855e+01 2.02469194e+02 4.72147746e+01 2.02468927e+02 4.72148281e+01 2.02468913e+02 4.72145987e+01 2.02468861e+02 4.72145517e+01 2.02468662e+02 4.72144420e+01 2.02468565e+02 4.72144448e+01 2.02468298e+02 4.72145138e+01 2.02467959e+02 4.72146013e+01 2.02467727e+02 4.72147555e+01 2.02467703e+02 4.72147561e+01 2.02467689e+02 4.72147317e+01 2.02467607e+02 4.72145019e+01 2.02467368e+02 4.72143528e+01 2.02467024e+02 4.72143161e+01 2.02466983e+02 4.72143117e+01 2.02466671e+02 4.72142167e+01 2.02466664e+02 4.72140909e+01 2.02466967e+02 4.72139812e+01 2.02467026e+02 4.72139547e+01 2.02467242e+02 4.72141210e+01 2.02467580e+02 4.72140650e+01 2.02467861e+02 4.72139413e+01 2.02467991e+02 4.72138929e+01 2.02468166e+02 4.72138327e+01 2.02468206e+02 4.72137342e+01 2.02468262e+02 4.72135938e+01 2.02468219e+02 4.72133995e+01 2.02468184e+02 4.72132454e+01 2.02468430e+02 4.72130998e+01 2.02468704e+02 4.72129720e+01 2.02468603e+02 4.72127907e+01 2.02468474e+02 4.72128281e+01 2.02468195e+02 4.72129533e+01 2.02468025e+02 4.72131464e+01 2.02467773e+02 4.72132879e+01 2.02467502e+02 4.72134176e+01 2.02467276e+02 4.72135761e+01 2.02467047e+02 4.72136141e+01 2.02466942e+02 4.72136662e+01 2.02466520e+02 4.72136781e+01 2.02466440e+02 4.72136517e+01 2.02466070e+02 4.72137197e+01 2.02465998e+02 4.72137383e+01 2.02465762e+02 4.72138268e+01 2.02465520e+02 4.72137659e+01 2.02465410e+02 4.72136069e+01 2.02465391e+02 4.72135358e+01 2.02465310e+02 4.72135443e+01 2.02465030e+02 4.72134768e+01 2.02464785e+02 4.72133327e+01 2.02464491e+02 4.72132244e+01 2.02464198e+02 4.72131152e+01 2.02463957e+02 4.72129681e+01 2.02463763e+02 4.72127862e+01 2.02463592e+02 4.72125871e+01 2.02463373e+02 4.72124236e+01 2.02463158e+02 4.72122570e+01 2.02463134e+02 4.72121846e+01 2.02463276e+02 4.72121696e+01 2.02463633e+02 4.72122315e+01 2.02463667e+02 4.72122180e+01 2.02463684e+02 4.72121937e+01 2.02463805e+02 4.72120050e+01 2.02463909e+02 4.72117713e+01 2.02464034e+02 4.72116099e+01 2.02464028e+02 4.72115459e+01 2.02464233e+02 4.72113749e+01 2.02464349e+02 4.72113776e+01 2.02464635e+02 4.72114917e+01 2.02464644e+02 4.72116317e+01 2.02464342e+02 4.72117425e+01 2.02464477e+02 4.72119337e+01 2.02464598e+02 4.72121697e+01 2.02464843e+02 4.72120558e+01 2.02465209e+02 4.72119849e+01 2.02465365e+02 4.72119284e+01 2.02465645e+02 4.72120472e+01 2.02465852e+02 4.72120878e+01 2.02465993e+02 4.72121153e+01 2.02466266e+02 4.72122389e+01 2.02466451e+02 4.72121626e+01 2.02466660e+02 4.72119940e+01 2.02467002e+02 4.72120206e+01 2.02467248e+02 4.72121643e+01 2.02467417e+02 4.72121678e+01 2.02467371e+02 4.72120739e+01 2.02467422e+02 4.72118718e+01 2.02467677e+02 4.72118476e+01 2.02467828e+02 4.72120617e+01 2.02467794e+02 4.72121040e+01 2.02467812e+02 4.72123987e+01 2.02468092e+02 4.72125171e+01 2.02468484e+02 4.72125355e+01 2.02468520e+02 4.72125262e+01 2.02468859e+02 4.72124702e+01 2.02469030e+02 4.72122780e+01 2.02469109e+02 4.72120915e+01 2.02469130e+02 4.72120413e+01 2.02469179e+02 4.72120400e+01 2.02469588e+02 4.72120283e+01 2.02469629e+02 4.72120327e+01 2.02469639e+02 4.72120600e+01 2.02469595e+02 4.72123318e+01 2.02469572e+02 4.72123997e+01 2.02469515e+02 4.72125812e+01 2.02469254e+02 4.72126351e+01 2.02469100e+02 4.72126208e+01 2.02469021e+02 4.72128072e+01 2.02469025e+02 4.72128732e+01 2.02469178e+02 4.72130162e+01 2.02469260e+02 4.72130200e+01 2.02469574e+02 4.72129174e+01 2.02469804e+02 4.72128794e+01 2.02470078e+02 4.72129330e+01 2.02470144e+02 4.72129532e+01 2.02470515e+02 4.72129065e+01 2.02470640e+02 4.72129124e+01 2.02470933e+02 4.72128689e+01 2.02471089e+02 4.72126667e+01 2.02471112e+02 4.72125637e+01 2.02471149e+02 4.72124052e+01 2.02471452e+02 4.72122955e+01 2.02471512e+02 4.72122690e+01 2.02471732e+02 4.72121711e+01 2.02472099e+02 4.72121607e+01 2.02472330e+02 4.72122457e+01 2.02472404e+02 4.72122602e+01 2.02472707e+02 4.72121819e+01 2.02472731e+02 4.72120187e+01 2.02472515e+02 4.72118532e+01 2.02472485e+02 4.72117439e+01 2.02472539e+02 4.72115101e+01 2.02472300e+02 4.72113611e+01 2.02472081e+02 4.72114914e+01 2.02471678e+02 4.72114955e+01 2.02471580e+02 4.72114774e+01 2.02471284e+02 4.72115918e+01 2.02471012e+02 4.72116621e+01 2.02470875e+02 4.72116353e+01 2.02470641e+02 4.72116104e+01 2.02470585e+02 4.72114546e+01 2.02470549e+02 4.72113533e+01 2.02470429e+02 4.72113567e+01 2.02470208e+02 4.72115179e+01 2.02469913e+02 4.72114973e+01 2.02469672e+02 4.72114821e+01 2.02469509e+02 4.72114709e+01 2.02469290e+02 4.72113071e+01 2.02469324e+02 4.72112648e+01 2.02469548e+02 4.72111054e+01 2.02469603e+02 4.72110763e+01 2.02469799e+02 4.72109634e+01 2.02470212e+02 4.72109517e+01 2.02470328e+02 4.72109943e+01 2.02470554e+02 4.72108362e+01 2.02470832e+02 4.72108192e+01 2.02470934e+02 4.72107747e+01 2.02471344e+02 4.72107317e+01 2.02471563e+02 4.72105696e+01 2.02471612e+02 4.72105682e+01 2.02471962e+02 4.72106348e+01 2.02472016e+02 4.72108523e+01 2.02472059e+02 4.72108885e+01 2.02472290e+02 4.72110437e+01 2.02472493e+02 4.72111501e+01 2.02472566e+02 4.72111646e+01 2.02472857e+02 4.72110789e+01 2.02473171e+02 4.72110432e+01 2.02473409e+02 4.72111241e+01 2.02473511e+02 4.72108890e+01 2.02473731e+02 4.72107269e+01 2.02474105e+02 4.72106616e+01 2.02474164e+02 4.72106351e+01 2.02474168e+02 4.72107011e+01 2.02474306e+02 4.72108557e+01 2.02474544e+02 4.72109360e+01 2.02474638e+02 4.72106956e+01 2.02474983e+02 4.72106119e+01 2.02475077e+02 4.72103715e+01 2.02475415e+02 4.72103619e+01 2.02475625e+02 4.72105322e+01 2.02475805e+02 4.72105271e+01 2.02475798e+02 4.72104045e+01 2.02475646e+02 4.72101916e+01 2.02475680e+02 4.72101493e+01 2.02475839e+02 4.72099499e+01 2.02475987e+02 4.72097427e+01 2.02475950e+02 4.72096414e+01 2.02475936e+02 4.72094119e+01 2.02475960e+02 4.72093089e+01 2.02475996e+02 4.72091505e+01 2.02476181e+02 4.72091452e+01 2.02476526e+02 4.72091819e+01 2.02476720e+02 4.72090039e+01 2.02476798e+02 4.72087538e+01 2.02476794e+02 4.72086925e+01 2.02476817e+02 4.72084665e+01 2.02477118e+02 4.72083550e+01 2.02477384e+02 4.72082223e+01 2.02477612e+02 4.72080655e+01 2.02477652e+02 4.72080588e+01 2.02477956e+02 4.72081596e+01 2.02478291e+02 4.72082376e+01 2.02478354e+02 4.72082302e+01 2.02478621e+02 4.72080975e+01 2.02478952e+02 4.72080744e+01 2.02478982e+02 4.72083227e+01 2.02478755e+02 4.72084807e+01 2.02478685e+02 4.72085975e+01 2.02478656e+02 4.72087175e+01 2.02478542e+02 4.72089454e+01 2.02478446e+02 4.72090994e+01 2.02478414e+02 4.72091649e+01 2.02478189e+02 4.72093235e+01 2.02478152e+02 4.72093163e+01 2.02477743e+02 4.72092929e+01 2.02477618e+02 4.72092659e+01 2.02477401e+02 4.72094295e+01 2.02477388e+02 4.72095553e+01 2.02477439e+02 4.72097526e+01 2.02477484e+02 4.72098095e+01 2.02477605e+02 4.72100457e+01 2.02477873e+02 4.72100240e+01 2.02478177e+02 4.72099147e+01 2.02478122e+02 4.72096639e+01 2.02478145e+02 4.72095953e+01 2.02478245e+02 4.72095727e+01 2.02478509e+02 4.72095234e+01 2.02478738e+02 4.72095341e+01 2.02478817e+02 4.72097158e+01 2.02478822e+02 4.72097975e+01 2.02478987e+02 4.72100006e+01 2.02479197e+02 4.72099536e+01 2.02479427e+02 4.72097978e+01 2.02479766e+02 4.72097507e+01 2.02479990e+02 4.72099103e+01 2.02480097e+02 4.72099171e+01 2.02480301e+02 4.72097452e+01 2.02480567e+02 4.72096124e+01 2.02480560e+02 4.72094899e+01 2.02480548e+02 4.72093013e+01 2.02480512e+02 4.72092000e+01 2.02480568e+02 4.72090145e+01 2.02480805e+02 4.72088634e+01 2.02481014e+02 4.72088287e+01 2.02481293e+02 4.72089479e+01 2.02481307e+02 4.72091773e+01 2.02481312e+02 4.72092590e+01 2.02481464e+02 4.72092752e+01 2.02481697e+02 4.72093000e+01 2.02482041e+02 4.72093367e+01 2.02482274e+02 4.72091825e+01 2.02482302e+02 4.72091789e+01 2.02482556e+02 4.72093165e+01 2.02482575e+02 4.72093711e+01 2.02482677e+02 4.72095524e+01 2.02482951e+02 4.72096060e+01 2.02483018e+02 4.72096261e+01 2.02483443e+02 4.72096140e+01 2.02483476e+02 4.72096131e+01 2.02483832e+02 4.72096754e+01 2.02484015e+02 4.72096721e+01 2.02484243e+02 4.72096971e+01 2.02484517e+02 4.72098200e+01 2.02484571e+02 4.72100195e+01 2.02480590e+02 4.72075325e+01 2.02480650e+02 4.72077965e+01 2.02480741e+02 4.72079261e+01 2.02480428e+02 4.72080295e+01 2.02480175e+02 4.72081705e+01 2.02480111e+02 4.72081944e+01 2.02480107e+02 4.72081283e+01 2.02480360e+02 4.72079873e+01 2.02480342e+02 4.72076982e+01 2.02480333e+02 4.72076709e+01 2.02480552e+02 4.72075088e+01 2.02480589e+02 4.72075160e+01 2.02480590e+02 4.72075325e+01 2.02477965e+02 4.72058927e+01 2.02477746e+02 4.72060548e+01 2.02477687e+02 4.72060813e+01 2.02477716e+02 4.72060364e+01 2.02477936e+02 4.72058743e+01 2.02477964e+02 4.72058762e+01 2.02477965e+02 4.72058927e+01 2.02486350e+02 4.72114296e+01 2.02486314e+02 4.72114201e+01 2.02486273e+02 4.72113816e+01 2.02486370e+02 4.72113789e+01 2.02486350e+02 4.72114296e+01 2.02485551e+02 4.72109305e+01 2.02485261e+02 4.72108970e+01 2.02485225e+02 4.72107272e+01 2.02485501e+02 4.72107193e+01 2.02485551e+02 4.72109305e+01 2.02488975e+02 4.72133685e+01 2.02488962e+02 4.72133689e+01 2.02488956e+02 4.72133566e+01 2.02488976e+02 4.72133584e+01 2.02488975e+02 4.72133685e+01 2.02481643e+02 4.72087884e+01 2.02481437e+02 4.72088415e+01 2.02481210e+02 4.72086838e+01 2.02481200e+02 4.72085117e+01 2.02481493e+02 4.72084746e+01 2.02481703e+02 4.72086450e+01 2.02481643e+02 4.72087884e+01 2.02474506e+02 4.72043294e+01 2.02474326e+02 4.72043345e+01 2.02474122e+02 4.72043887e+01 2.02473902e+02 4.72045508e+01 2.02473777e+02 4.72047401e+01 2.02473779e+02 4.72047731e+01 2.02473731e+02 4.72047745e+01 2.02473321e+02 4.72047861e+01 2.02473149e+02 4.72049776e+01 2.02473049e+02 4.72052142e+01 2.02472814e+02 4.72053665e+01 2.02472563e+02 4.72055090e+01 2.02472224e+02 4.72055965e+01 2.02472152e+02 4.72056151e+01 2.02471791e+02 4.72056254e+01 2.02471806e+02 4.72058705e+01 2.02472149e+02 4.72059430e+01 2.02472162e+02 4.72061561e+01 2.02472181e+02 4.72062448e+01 2.02472275e+02 4.72062265e+01 2.02472257e+02 4.72061880e+01 2.02472240e+02 4.72059057e+01 2.02472532e+02 4.72057890e+01 2.02472751e+02 4.72056264e+01 2.02473028e+02 4.72056186e+01 2.02473303e+02 4.72056722e+01 2.02473377e+02 4.72056866e+01 2.02473715e+02 4.72056306e+01 2.02473944e+02 4.72055925e+01 2.02474219e+02 4.72056461e+01 2.02474117e+02 4.72054649e+01 2.02474154e+02 4.72053064e+01 2.02474383e+02 4.72052684e+01 2.02474505e+02 4.72052264e+01 2.02474643e+02 4.72050768e+01 2.02474638e+02 4.72050108e+01 2.02474479e+02 4.72048721e+01 2.02474408e+02 4.72045994e+01 2.02474406e+02 4.72045664e+01 2.02474455e+02 4.72045650e+01 2.02474693e+02 4.72044467e+01 2.02474718e+02 4.72043708e+01 2.02474506e+02 4.72043294e+01 2.02490182e+02 4.72144211e+01 2.02490180e+02 4.72144210e+01 2.02490180e+02 4.72144199e+01 2.02490182e+02 4.72144197e+01 2.02490182e+02 4.72144211e+01 2.02486636e+02 4.72122068e+01 2.02486561e+02 4.72122140e+01 2.02486351e+02 4.72120439e+01 2.02486350e+02 4.72120280e+01 2.02486395e+02 4.72120113e+01 2.02486652e+02 4.72121472e+01 2.02486636e+02 4.72122068e+01 2.02477609e+02 4.72065678e+01 2.02477326e+02 4.72066902e+01 2.02477344e+02 4.72069849e+01 2.02477383e+02 4.72070251e+01 2.02477164e+02 4.72071872e+01 2.02477067e+02 4.72071899e+01 2.02477063e+02 4.72071239e+01 2.02476961e+02 4.72069426e+01 2.02477022e+02 4.72067992e+01 2.02477288e+02 4.72066665e+01 2.02477440e+02 4.72064622e+01 2.02477666e+02 4.72064223e+01 2.02477609e+02 4.72065678e+01 2.02478230e+02 4.72072551e+01 2.02478191e+02 4.72073353e+01 2.02478131e+02 4.72074920e+01 2.02477950e+02 4.72075136e+01 2.02477677e+02 4.72073898e+01 2.02477665e+02 4.72072012e+01 2.02477744e+02 4.72070148e+01 2.02477778e+02 4.72069725e+01 2.02477814e+02 4.72069632e+01 2.02478184e+02 4.72070157e+01 2.02478230e+02 4.72072551e+01 2.02491967e+02 4.72164334e+01 2.02491865e+02 4.72164300e+01 2.02491853e+02 4.72163620e+01 2.02491954e+02 4.72163645e+01 2.02491967e+02 4.72164334e+01 2.02484766e+02 4.72119362e+01 2.02484749e+02 4.72122249e+01 2.02484514e+02 4.72123771e+01 2.02484133e+02 4.72123813e+01 2.02483978e+02 4.72121702e+01 2.02483994e+02 4.72120525e+01 2.02484094e+02 4.72118154e+01 2.02484345e+02 4.72116731e+01 2.02484696e+02 4.72116401e+01 2.02484765e+02 4.72119142e+01 2.02484766e+02 4.72119362e+01 2.02484111e+02 4.72115273e+01 2.02483921e+02 4.72115619e+01 2.02483975e+02 4.72114421e+01 2.02484135e+02 4.72114032e+01 2.02484111e+02 4.72115273e+01 2.02479721e+02 4.72087847e+01 2.02479443e+02 4.72089105e+01 2.02479197e+02 4.72088700e+01 2.02479189e+02 4.72087517e+01 2.02479321e+02 4.72085345e+01 2.02479660e+02 4.72085280e+01 2.02479721e+02 4.72087847e+01 2.02489430e+02 4.72151479e+01 2.02489168e+02 4.72151690e+01 2.02489166e+02 4.72149834e+01 2.02489419e+02 4.72149830e+01 2.02489430e+02 4.72151479e+01 2.02483387e+02 4.72113741e+01 2.02483290e+02 4.72113769e+01 2.02483286e+02 4.72113109e+01 2.02483360e+02 4.72113253e+01 2.02483387e+02 4.72113741e+01 2.02483407e+02 4.72116853e+01 2.02483333e+02 4.72116709e+01 2.02483305e+02 4.72116220e+01 2.02483402e+02 4.72116193e+01 2.02483407e+02 4.72116853e+01 2.02482929e+02 4.72113872e+01 2.02482855e+02 4.72113727e+01 2.02482828e+02 4.72113239e+01 2.02482925e+02 4.72113211e+01 2.02482929e+02 4.72113872e+01 2.02477020e+02 4.72076959e+01 2.02476770e+02 4.72077342e+01 2.02476758e+02 4.72075319e+01 2.02477012e+02 4.72075559e+01 2.02477020e+02 4.72076959e+01 2.02476402e+02 4.72073097e+01 2.02476033e+02 4.72073031e+01 2.02476018e+02 4.72070698e+01 2.02476362e+02 4.72070601e+01 2.02476402e+02 4.72073097e+01 2.02482923e+02 4.72116825e+01 2.02482875e+02 4.72116839e+01 2.02482872e+02 4.72116509e+01 2.02482944e+02 4.72116323e+01 2.02482923e+02 4.72116825e+01 2.02484370e+02 4.72128857e+01 2.02484325e+02 4.72128900e+01 2.02484323e+02 4.72128560e+01 2.02484373e+02 4.72128545e+01 2.02484370e+02 4.72128857e+01 2.02482965e+02 4.72120081e+01 2.02482861e+02 4.72120195e+01 2.02482834e+02 4.72119257e+01 2.02482994e+02 4.72119212e+01 2.02482965e+02 4.72120081e+01 2.02476247e+02 4.72078109e+01 2.02476067e+02 4.72079976e+01 2.02475822e+02 4.72081439e+01 2.02475773e+02 4.72081453e+01 2.02475771e+02 4.72081123e+01 2.02475754e+02 4.72078341e+01 2.02475752e+02 4.72078011e+01 2.02475824e+02 4.72077825e+01 2.02476212e+02 4.72077891e+01 2.02476257e+02 4.72077878e+01 2.02476247e+02 4.72078109e+01 2.02476640e+02 4.72083556e+01 2.02476383e+02 4.72083459e+01 2.02476307e+02 4.72081475e+01 2.02476575e+02 4.72082039e+01 2.02476640e+02 4.72083556e+01 2.02481386e+02 4.72119192e+01 2.02481162e+02 4.72119733e+01 2.02481149e+02 4.72117711e+01 2.02481380e+02 4.72118122e+01 2.02481386e+02 4.72119192e+01 2.02485197e+02 4.72145984e+01 2.02485110e+02 4.72145876e+01 2.02485102e+02 4.72145394e+01 2.02485190e+02 4.72145286e+01 2.02485197e+02 4.72145984e+01 2.02481009e+02 4.72119831e+01 2.02480778e+02 4.72119314e+01 2.02480729e+02 4.72118080e+01 2.02480996e+02 4.72117699e+01 2.02481009e+02 4.72119831e+01 2.02476195e+02 4.72089751e+01 2.02475962e+02 4.72089817e+01 2.02475983e+02 4.72088426e+01 2.02476185e+02 4.72088174e+01 2.02476195e+02 4.72089751e+01 2.02473617e+02 4.72073643e+01 2.02473491e+02 4.72075536e+01 2.02473800e+02 4.72076511e+01 2.02473939e+02 4.72075660e+01 2.02473968e+02 4.72075267e+01 2.02473775e+02 4.72073443e+01 2.02473617e+02 4.72073643e+01 2.02471274e+02 4.72061997e+01 2.02470888e+02 4.72062579e+01 2.02470840e+02 4.72062592e+01 2.02470501e+02 4.72063153e+01 2.02470316e+02 4.72063205e+01 2.02469972e+02 4.72062838e+01 2.02469900e+02 4.72063024e+01 2.02469680e+02 4.72064007e+01 2.02469313e+02 4.72064112e+01 2.02469232e+02 4.72064196e+01 2.02469096e+02 4.72065708e+01 2.02469075e+02 4.72066210e+01 2.02469158e+02 4.72068509e+01 2.02469502e+02 4.72068875e+01 2.02469543e+02 4.72068919e+01 2.02469578e+02 4.72069350e+01 2.02469452e+02 4.72071558e+01 2.02469241e+02 4.72071146e+01 2.02468922e+02 4.72071236e+01 2.02468716e+02 4.72071767e+01 2.02468442e+02 4.72071231e+01 2.02468457e+02 4.72073682e+01 2.02468436e+02 4.72074184e+01 2.02468364e+02 4.72074370e+01 2.02468013e+02 4.72073712e+01 2.02467890e+02 4.72073764e+01 2.02467552e+02 4.72073860e+01 2.02467307e+02 4.72073111e+01 2.02467240e+02 4.72072909e+01 2.02467231e+02 4.72072636e+01 2.02467450e+02 4.72071016e+01 2.02467433e+02 4.72068234e+01 2.02467171e+02 4.72066915e+01 2.02466810e+02 4.72067017e+01 2.02466557e+02 4.72068427e+01 2.02466371e+02 4.72070259e+01 2.02466274e+02 4.72070286e+01 2.02465913e+02 4.72070389e+01 2.02466015e+02 4.72072202e+01 2.02466026e+02 4.72074088e+01 2.02465947e+02 4.72075952e+01 2.02466323e+02 4.72076435e+01 2.02466401e+02 4.72079106e+01 2.02466705e+02 4.72080114e+01 2.02466761e+02 4.72081672e+01 2.02466769e+02 4.72082898e+01 2.02467043e+02 4.72083434e+01 2.02467140e+02 4.72083406e+01 2.02467356e+02 4.72085069e+01 2.02467728e+02 4.72085576e+01 2.02467971e+02 4.72087028e+01 2.02468217e+02 4.72087777e+01 2.02468283e+02 4.72087979e+01 2.02468709e+02 4.72087858e+01 2.02468741e+02 4.72087849e+01 2.02469121e+02 4.72088297e+01 2.02469255e+02 4.72088278e+01 2.02469569e+02 4.72087252e+01 2.02469844e+02 4.72085978e+01 2.02469873e+02 4.72085997e+01 2.02469887e+02 4.72086241e+01 2.02469969e+02 4.72088540e+01 2.02470206e+02 4.72088240e+01 2.02470533e+02 4.72087286e+01 2.02470681e+02 4.72085221e+01 2.02470900e+02 4.72083600e+01 2.02470889e+02 4.72081746e+01 2.02470545e+02 4.72081379e+01 2.02470504e+02 4.72081335e+01 2.02470142e+02 4.72080754e+01 2.02469945e+02 4.72078956e+01 2.02469910e+02 4.72077414e+01 2.02469929e+02 4.72075821e+01 2.02469921e+02 4.72074489e+01 2.02470065e+02 4.72072396e+01 2.02470433e+02 4.72072098e+01 2.02470525e+02 4.72072277e+01 2.02470903e+02 4.72071650e+01 2.02470967e+02 4.72071412e+01 2.02471202e+02 4.72070526e+01 2.02471184e+02 4.72069810e+01 2.02471168e+02 4.72067321e+01 2.02471166e+02 4.72066688e+01 2.02471190e+02 4.72064465e+01 2.02471544e+02 4.72063894e+01 2.02471565e+02 4.72063816e+01 2.02471599e+02 4.72063489e+01 2.02471405e+02 4.72061671e+01 2.02471274e+02 4.72061997e+01 2.02473777e+02 4.72080627e+01 2.02473881e+02 4.72082421e+01 2.02474152e+02 4.72082976e+01 2.02474137e+02 4.72080525e+01 2.02473777e+02 4.72080627e+01 2.02473082e+02 4.72076290e+01 2.02472941e+02 4.72078396e+01 2.02472825e+02 4.72080456e+01 2.02473189e+02 4.72081020e+01 2.02473375e+02 4.72081107e+01 2.02473675e+02 4.72079994e+01 2.02473660e+02 4.72077543e+01 2.02473453e+02 4.72075823e+01 2.02473082e+02 4.72076290e+01 2.02475502e+02 4.72094399e+01 2.02475335e+02 4.72096347e+01 2.02475032e+02 4.72096689e+01 2.02475018e+02 4.72094365e+01 2.02475329e+02 4.72093317e+01 2.02475518e+02 4.72093096e+01 2.02475502e+02 4.72094399e+01 2.02480691e+02 4.72129811e+01 2.02480597e+02 4.72132211e+01 2.02480303e+02 4.72132582e+01 2.02480333e+02 4.72130562e+01 2.02480677e+02 4.72129720e+01 2.02480689e+02 4.72129729e+01 2.02480691e+02 4.72129811e+01 2.02488202e+02 4.72182704e+01 2.02488068e+02 4.72182587e+01 2.02488058e+02 4.72181801e+01 2.02488179e+02 4.72181766e+01 2.02488202e+02 4.72182704e+01 2.02471628e+02 4.72079172e+01 2.02471386e+02 4.72080649e+01 2.02471316e+02 4.72081843e+01 2.02471469e+02 4.72081170e+01 2.02471702e+02 4.72079634e+01 2.02471713e+02 4.72078914e+01 2.02471628e+02 4.72079172e+01 2.02470002e+02 4.72069009e+01 2.02469938e+02 4.72069248e+01 2.02469968e+02 4.72068798e+01 2.02470001e+02 4.72068789e+01 2.02470002e+02 4.72069009e+01 2.02480308e+02 4.72136389e+01 2.02480214e+02 4.72136494e+01 2.02480188e+02 4.72135644e+01 2.02480334e+02 4.72135602e+01 2.02480308e+02 4.72136389e+01 2.02474701e+02 4.72104357e+01 2.02474424e+02 4.72104436e+01 2.02474460e+02 4.72102851e+01 2.02474690e+02 4.72102471e+01 2.02474701e+02 4.72104357e+01 2.02472912e+02 4.72093176e+01 2.02472840e+02 4.72093361e+01 2.02472836e+02 4.72092701e+01 2.02472902e+02 4.72092903e+01 2.02472912e+02 4.72093176e+01 2.02479464e+02 4.72140094e+01 2.02479234e+02 4.72140474e+01 2.02479223e+02 4.72138588e+01 2.02479456e+02 4.72138837e+01 2.02479464e+02 4.72140094e+01 2.02478107e+02 4.72131616e+01 2.02477923e+02 4.72133460e+01 2.02477522e+02 4.72133947e+01 2.02477481e+02 4.72133904e+01 2.02477471e+02 4.72133631e+01 2.02477493e+02 4.72130772e+01 2.02477805e+02 4.72129734e+01 2.02478096e+02 4.72129361e+01 2.02478107e+02 4.72131616e+01 2.02480051e+02 4.72146751e+01 2.02479660e+02 4.72147088e+01 2.02479445e+02 4.72145427e+01 2.02479465e+02 4.72143094e+01 2.02479750e+02 4.72143175e+01 2.02480050e+02 4.72144209e+01 2.02480051e+02 4.72146751e+01 2.02479085e+02 4.72140721e+01 2.02478975e+02 4.72142390e+01 2.02479190e+02 4.72144052e+01 2.02479218e+02 4.72144541e+01 2.02479152e+02 4.72144339e+01 2.02478776e+02 4.72144773e+01 2.02478506e+02 4.72146081e+01 2.02478474e+02 4.72146090e+01 2.02478048e+02 4.72146211e+01 2.02477967e+02 4.72148698e+01 2.02477650e+02 4.72148923e+01 2.02477488e+02 4.72146863e+01 2.02477507e+02 4.72145823e+01 2.02477696e+02 4.72144013e+01 2.02477866e+02 4.72142080e+01 2.02478124e+02 4.72140702e+01 2.02478339e+02 4.72139053e+01 2.02478578e+02 4.72138813e+01 2.02478777e+02 4.72138798e+01 2.02479071e+02 4.72138427e+01 2.02479085e+02 4.72140721e+01 2.02469691e+02 4.72082027e+01 2.02469567e+02 4.72084244e+01 2.02469216e+02 4.72084344e+01 2.02469200e+02 4.72081952e+01 2.02469504e+02 4.72080856e+01 2.02469713e+02 4.72080672e+01 2.02469691e+02 4.72082027e+01 2.02480842e+02 4.72154689e+01 2.02481002e+02 4.72156698e+01 2.02480927e+02 4.72158208e+01 2.02480793e+02 4.72158246e+01 2.02480595e+02 4.72159126e+01 2.02480224e+02 4.72159193e+01 2.02479952e+02 4.72157951e+01 2.02479943e+02 4.72155057e+01 2.02480352e+02 4.72154991e+01 2.02480388e+02 4.72154840e+01 2.02480836e+02 4.72154652e+01 2.02480839e+02 4.72154651e+01 2.02480842e+02 4.72154689e+01 2.02477045e+02 4.72130966e+01 2.02477010e+02 4.72130877e+01 2.02476969e+02 4.72130491e+01 2.02477066e+02 4.72130464e+01 2.02477045e+02 4.72130966e+01 2.02479238e+02 4.72150648e+01 2.02479167e+02 4.72150730e+01 2.02478860e+02 4.72149750e+01 2.02478876e+02 4.72148390e+01 2.02479074e+02 4.72148164e+01 2.02479260e+02 4.72150047e+01 2.02479238e+02 4.72150648e+01 2.02475563e+02 4.72127695e+01 2.02475540e+02 4.72128725e+01 2.02475551e+02 4.72130611e+01 2.02475608e+02 4.72131474e+01 2.02475739e+02 4.72131785e+01 2.02475703e+02 4.72130773e+01 2.02475689e+02 4.72128478e+01 2.02475651e+02 4.72127904e+01 2.02475563e+02 4.72127695e+01 2.02465304e+02 4.72063587e+01 2.02465194e+02 4.72065255e+01 2.02465460e+02 4.72064566e+01 2.02465453e+02 4.72063340e+01 2.02465304e+02 4.72063587e+01 2.02486035e+02 4.72196095e+01 2.02485807e+02 4.72196041e+01 2.02485811e+02 4.72194699e+01 2.02486052e+02 4.72194229e+01 2.02486035e+02 4.72196095e+01 2.02467800e+02 4.72082181e+01 2.02467721e+02 4.72082368e+01 2.02467733e+02 4.72081764e+01 2.02467793e+02 4.72081840e+01 2.02467800e+02 4.72082181e+01 2.02471062e+02 4.72105553e+01 2.02470758e+02 4.72105486e+01 2.02470630e+02 4.72105848e+01 2.02470335e+02 4.72106998e+01 2.02470167e+02 4.72108938e+01 2.02469837e+02 4.72109032e+01 2.02469736e+02 4.72106529e+01 2.02469734e+02 4.72106232e+01 2.02469836e+02 4.72103878e+01 2.02470104e+02 4.72103811e+01 2.02470239e+02 4.72103403e+01 2.02470498e+02 4.72102034e+01 2.02470729e+02 4.72102445e+01 2.02471026e+02 4.72103501e+01 2.02471062e+02 4.72105553e+01 2.02467125e+02 4.72080955e+01 2.02467028e+02 4.72080983e+01 2.02467049e+02 4.72080481e+01 2.02467090e+02 4.72080524e+01 2.02467125e+02 4.72080955e+01 2.02486575e+02 4.72205449e+01 2.02486252e+02 4.72205766e+01 2.02486031e+02 4.72204146e+01 2.02485989e+02 4.72201793e+01 2.02486317e+02 4.72202032e+01 2.02486563e+02 4.72203472e+01 2.02486575e+02 4.72205449e+01 2.02464566e+02 4.72067952e+01 2.02464577e+02 4.72069806e+01 2.02464850e+02 4.72069729e+01 2.02464904e+02 4.72067392e+01 2.02464566e+02 4.72067952e+01 2.02478612e+02 4.72158705e+01 2.02478527e+02 4.72158711e+01 2.02478535e+02 4.72158229e+01 2.02478595e+02 4.72158212e+01 2.02478612e+02 4.72158705e+01 2.02476478e+02 4.72148372e+01 2.02476403e+02 4.72148371e+01 2.02476416e+02 4.72147980e+01 2.02476462e+02 4.72147940e+01 2.02476478e+02 4.72148372e+01 2.02464652e+02 4.72074477e+01 2.02464703e+02 4.72075383e+01 2.02464840e+02 4.72075651e+01 2.02464919e+02 4.72073787e+01 2.02464652e+02 4.72074477e+01 2.02476081e+02 4.72148881e+01 2.02475896e+02 4.72148866e+01 2.02475901e+02 4.72147758e+01 2.02476043e+02 4.72147781e+01 2.02476081e+02 4.72148881e+01 2.02472451e+02 4.72126202e+01 2.02472604e+02 4.72127632e+01 2.02472670e+02 4.72127572e+01 2.02472683e+02 4.72127047e+01 2.02472451e+02 4.72126202e+01 2.02476031e+02 4.72151560e+01 2.02475969e+02 4.72151577e+01 2.02475953e+02 4.72151073e+01 2.02476047e+02 4.72151000e+01 2.02476031e+02 4.72151560e+01 2.02474810e+02 4.72143932e+01 2.02474799e+02 4.72143954e+01 2.02474800e+02 4.72143872e+01 2.02474811e+02 4.72143869e+01 2.02474810e+02 4.72143932e+01 2.02471014e+02 4.72120214e+01 2.02470794e+02 4.72121831e+01 2.02470745e+02 4.72121845e+01 2.02470398e+02 4.72121157e+01 2.02470268e+02 4.72118863e+01 2.02470240e+02 4.72118375e+01 2.02470314e+02 4.72118519e+01 2.02470684e+02 4.72119044e+01 2.02470939e+02 4.72119746e+01 2.02471033e+02 4.72119719e+01 2.02471014e+02 4.72120214e+01 2.02485760e+02 4.72215321e+01 2.02485411e+02 4.72215235e+01 2.02485397e+02 4.72213053e+01 2.02485718e+02 4.72212961e+01 2.02485760e+02 4.72215321e+01 2.02473728e+02 4.72140165e+01 2.02473499e+02 4.72140545e+01 2.02473487e+02 4.72138659e+01 2.02473765e+02 4.72138581e+01 2.02473728e+02 4.72140165e+01 2.02485175e+02 4.72214657e+01 2.02485023e+02 4.72214847e+01 2.02484999e+02 4.72213557e+01 2.02485169e+02 4.72213762e+01 2.02485175e+02 4.72214657e+01 2.02480211e+02 4.72186647e+01 2.02480015e+02 4.72186764e+01 2.02480007e+02 4.72185376e+01 2.02480203e+02 4.72185372e+01 2.02480211e+02 4.72186647e+01 2.02473218e+02 4.72142963e+01 2.02473146e+02 4.72143149e+01 2.02473142e+02 4.72142488e+01 2.02473239e+02 4.72142461e+01 2.02473218e+02 4.72142963e+01 2.02479463e+02 4.72184969e+01 2.02479382e+02 4.72184933e+01 2.02479390e+02 4.72184513e+01 2.02479445e+02 4.72184466e+01 2.02479463e+02 4.72184969e+01 2.02464528e+02 4.72091656e+01 2.02464565e+02 4.72092669e+01 2.02464653e+02 4.72092433e+01 2.02464651e+02 4.72092030e+01 2.02464528e+02 4.72091656e+01 2.02483199e+02 4.72211292e+01 2.02482982e+02 4.72212929e+01 2.02482649e+02 4.72212857e+01 2.02482655e+02 4.72210889e+01 2.02482861e+02 4.72209181e+01 2.02483203e+02 4.72208766e+01 2.02483199e+02 4.72211292e+01 2.02472551e+02 4.72147773e+01 2.02472511e+02 4.72147839e+01 2.02472484e+02 4.72147351e+01 2.02472550e+02 4.72147553e+01 2.02472551e+02 4.72147773e+01 2.02474441e+02 4.72162572e+01 2.02474159e+02 4.72163801e+01 2.02473868e+02 4.72163839e+01 2.02473870e+02 4.72161997e+01 2.02474028e+02 4.72159993e+01 2.02474390e+02 4.72159987e+01 2.02474441e+02 4.72162572e+01 2.02483957e+02 4.72225001e+01 2.02483605e+02 4.72225320e+01 2.02483593e+02 4.72222730e+01 2.02483921e+02 4.72222979e+01 2.02483957e+02 4.72225001e+01 2.02484293e+02 4.72230090e+01 2.02484275e+02 4.72230128e+01 2.02484260e+02 4.72229886e+01 2.02484298e+02 4.72229958e+01 2.02484293e+02 4.72230090e+01 2.02471196e+02 4.72151274e+01 2.02471156e+02 4.72151341e+01 2.02471162e+02 4.72151063e+01 2.02471195e+02 4.72151054e+01 2.02471196e+02 4.72151274e+01 2.02471585e+02 4.72156695e+01 2.02471334e+02 4.72156530e+01 2.02471326e+02 4.72155082e+01 2.02471538e+02 4.72155022e+01 2.02471585e+02 4.72156695e+01 2.02465109e+02 4.72116235e+01 2.02464849e+02 4.72116592e+01 2.02464836e+02 4.72114527e+01 2.02465176e+02 4.72114172e+01 2.02465109e+02 4.72116235e+01 2.02465937e+02 4.72124396e+01 2.02465795e+02 4.72125869e+01 2.02465983e+02 4.72124684e+01 2.02466054e+02 4.72123954e+01 2.02465937e+02 4.72124396e+01 2.02482351e+02 4.72229928e+01 2.02482100e+02 4.72229926e+01 2.02482079e+02 4.72228230e+01 2.02482340e+02 4.72228155e+01 2.02482351e+02 4.72229928e+01 2.02479370e+02 4.72214307e+01 2.02479369e+02 4.72214308e+01 2.02479369e+02 4.72214298e+01 2.02479370e+02 4.72214298e+01 2.02479370e+02 4.72214307e+01 2.02477977e+02 4.72205603e+01 2.02477820e+02 4.72207618e+01 2.02477615e+02 4.72207737e+01 2.02477616e+02 4.72206340e+01 2.02477893e+02 4.72205081e+01 2.02477974e+02 4.72205091e+01 2.02477977e+02 4.72205603e+01 2.02471083e+02 4.72162537e+01 2.02470956e+02 4.72162573e+01 2.02470837e+02 4.72161002e+01 2.02471098e+02 4.72161527e+01 2.02471083e+02 4.72162537e+01 2.02489575e+02 4.71736567e+01 2.02489417e+02 4.71736612e+01 2.02489413e+02 4.71735554e+01 2.02489568e+02 4.71735494e+01 2.02489575e+02 4.71736567e+01 2.02481127e+02 4.71686753e+01 2.02480920e+02 4.71688448e+01 2.02480502e+02 4.71688647e+01 2.02480253e+02 4.71687234e+01 2.02480232e+02 4.71684146e+01 2.02480403e+02 4.71682870e+01 2.02480446e+02 4.71682495e+01 2.02480456e+02 4.71682485e+01 2.02480901e+02 4.71682442e+01 2.02481108e+02 4.71684171e+01 2.02481127e+02 4.71686753e+01 2.02493636e+02 4.71776904e+01 2.02493199e+02 4.71776978e+01 2.02493192e+02 4.71774128e+01 2.02493618e+02 4.71773885e+01 2.02493636e+02 4.71776904e+01 2.02493567e+02 4.71794419e+01 2.02493497e+02 4.71794305e+01 2.02493496e+02 4.71793974e+01 2.02493540e+02 4.71793982e+01 2.02493567e+02 4.71794419e+01 2.02495058e+02 4.71818694e+01 2.02494943e+02 4.71819406e+01 2.02494815e+02 4.71820162e+01 2.02494422e+02 4.71820003e+01 2.02494449e+02 4.71817878e+01 2.02494619e+02 4.71815946e+01 2.02494992e+02 4.71815789e+01 2.02495059e+02 4.71818548e+01 2.02495058e+02 4.71818694e+01 2.02491337e+02 4.71795439e+01 2.02491054e+02 4.71796098e+01 2.02491067e+02 4.71793754e+01 2.02491343e+02 4.71793959e+01 2.02491337e+02 4.71795439e+01 2.02489554e+02 4.71790280e+01 2.02489176e+02 4.71790914e+01 2.02489317e+02 4.71792671e+01 2.02489489e+02 4.71792868e+01 2.02489698e+02 4.71793103e+01 2.02489983e+02 4.71794249e+01 2.02490249e+02 4.71795541e+01 2.02490330e+02 4.71798123e+01 2.02490070e+02 4.71799491e+01 2.02490089e+02 4.71799973e+01 2.02490228e+02 4.71802200e+01 2.02490236e+02 4.71803521e+01 2.02490029e+02 4.71805217e+01 2.02489779e+02 4.71806647e+01 2.02489609e+02 4.71806779e+01 2.02489262e+02 4.71806087e+01 2.02489247e+02 4.71803324e+01 2.02489626e+02 4.71802698e+01 2.02489568e+02 4.71800572e+01 2.02489214e+02 4.71799940e+01 2.02489190e+02 4.71799973e+01 2.02489184e+02 4.71800159e+01 2.02489167e+02 4.71802822e+01 2.02489160e+02 4.71803593e+01 2.02489178e+02 4.71805881e+01 2.02488960e+02 4.71805071e+01 2.02488746e+02 4.71803395e+01 2.02488660e+02 4.71802648e+01 2.02488586e+02 4.71801323e+01 2.02488340e+02 4.71800646e+01 2.02488279e+02 4.71800338e+01 2.02488280e+02 4.71800273e+01 2.02488409e+02 4.71798083e+01 2.02488568e+02 4.71796088e+01 2.02488724e+02 4.71794069e+01 2.02488727e+02 4.71793772e+01 2.02488708e+02 4.71790978e+01 2.02488697e+02 4.71790745e+01 2.02488735e+02 4.71788156e+01 2.02489106e+02 4.71787720e+01 2.02489137e+02 4.71787675e+01 2.02489533e+02 4.71787813e+01 2.02489554e+02 4.71790280e+01 2.02495601e+02 4.71831060e+01 2.02495392e+02 4.71832746e+01 2.02495182e+02 4.71834425e+01 2.02495131e+02 4.71834287e+01 2.02495126e+02 4.71834072e+01 2.02495271e+02 4.71831990e+01 2.02495501e+02 4.71830435e+01 2.02495617e+02 4.71830694e+01 2.02495601e+02 4.71831060e+01 2.02495271e+02 4.71828997e+01 2.02494988e+02 4.71830218e+01 2.02494855e+02 4.71829815e+01 2.02494861e+02 4.71829427e+01 2.02494827e+02 4.71826770e+01 2.02494824e+02 4.71826201e+01 2.02494919e+02 4.71826089e+01 2.02495281e+02 4.71826667e+01 2.02495271e+02 4.71828997e+01 2.02493223e+02 4.71816199e+01 2.02493166e+02 4.71816270e+01 2.02493035e+02 4.71815028e+01 2.02493228e+02 4.71815816e+01 2.02493223e+02 4.71816199e+01 2.02491101e+02 4.71802943e+01 2.02490865e+02 4.71804003e+01 2.02490949e+02 4.71801994e+01 2.02491144e+02 4.71801939e+01 2.02491101e+02 4.71802943e+01 2.02497067e+02 4.71843209e+01 2.02497002e+02 4.71843228e+01 2.02497001e+02 4.71842796e+01 2.02497052e+02 4.71842861e+01 2.02497067e+02 4.71843209e+01 2.02493649e+02 4.71821853e+01 2.02493325e+02 4.71821606e+01 2.02493357e+02 4.71820031e+01 2.02493572e+02 4.71819783e+01 2.02493649e+02 4.71821853e+01 2.02492690e+02 4.71815860e+01 2.02492401e+02 4.71815423e+01 2.02492424e+02 4.71814201e+01 2.02492572e+02 4.71814159e+01 2.02492690e+02 4.71815860e+01 2.02487797e+02 4.71785284e+01 2.02487526e+02 4.71786584e+01 2.02487490e+02 4.71786655e+01 2.02487502e+02 4.71786433e+01 2.02487389e+02 4.71784144e+01 2.02487212e+02 4.71782203e+01 2.02487208e+02 4.71781602e+01 2.02487306e+02 4.71781503e+01 2.02487603e+02 4.71782562e+01 2.02487747e+02 4.71784753e+01 2.02487797e+02 4.71785284e+01 2.02501659e+02 4.71874883e+01 2.02501468e+02 4.71875296e+01 2.02501488e+02 4.71873818e+01 2.02501650e+02 4.71873945e+01 2.02501659e+02 4.71874883e+01 2.02493633e+02 4.71824746e+01 2.02493307e+02 4.71824994e+01 2.02493295e+02 4.71822636e+01 2.02493672e+02 4.71822297e+01 2.02493633e+02 4.71824746e+01 2.02486169e+02 4.71781096e+01 2.02486011e+02 4.71781319e+01 2.02485959e+02 4.71779780e+01 2.02486228e+02 4.71779716e+01 2.02486169e+02 4.71781096e+01 2.02477170e+02 4.71724841e+01 2.02476886e+02 4.71725138e+01 2.02476921e+02 4.71723283e+01 2.02477204e+02 4.71722785e+01 2.02477170e+02 4.71724841e+01 2.02501312e+02 4.71878700e+01 2.02501070e+02 4.71878237e+01 2.02500699e+02 4.71877728e+01 2.02500663e+02 4.71877634e+01 2.02500390e+02 4.71876755e+01 2.02500369e+02 4.71875801e+01 2.02500501e+02 4.71873636e+01 2.02500796e+02 4.71873753e+01 2.02501010e+02 4.71875427e+01 2.02501243e+02 4.71876960e+01 2.02501312e+02 4.71878700e+01 2.02495333e+02 4.71841352e+01 2.02495337e+02 4.71842523e+01 2.02495349e+02 4.71844441e+01 2.02495157e+02 4.71843855e+01 2.02494927e+02 4.71842304e+01 2.02494875e+02 4.71841481e+01 2.02495131e+02 4.71840088e+01 2.02495244e+02 4.71839961e+01 2.02495333e+02 4.71841352e+01 2.02491138e+02 4.71815138e+01 2.02491116e+02 4.71815156e+01 2.02491117e+02 4.71815009e+01 2.02491139e+02 4.71814992e+01 2.02491138e+02 4.71815138e+01 2.02500097e+02 4.71874104e+01 2.02499911e+02 4.71873788e+01 2.02499898e+02 4.71872858e+01 2.02500048e+02 4.71872777e+01 2.02500097e+02 4.71874104e+01 2.02495834e+02 4.71847473e+01 2.02495882e+02 4.71848261e+01 2.02495834e+02 4.71850460e+01 2.02495512e+02 4.71851439e+01 2.02495456e+02 4.71851407e+01 2.02495062e+02 4.71851066e+01 2.02494815e+02 4.71849638e+01 2.02494874e+02 4.71847452e+01 2.02495165e+02 4.71846280e+01 2.02495366e+02 4.71845565e+01 2.02495477e+02 4.71845241e+01 2.02495800e+02 4.71845608e+01 2.02495834e+02 4.71847473e+01 2.02496730e+02 4.71856059e+01 2.02496608e+02 4.71855905e+01 2.02496316e+02 4.71854812e+01 2.02496316e+02 4.71853476e+01 2.02496504e+02 4.71853422e+01 2.02496746e+02 4.71854882e+01 2.02496730e+02 4.71856059e+01 2.02486966e+02 4.71795049e+01 2.02486764e+02 4.71795272e+01 2.02486505e+02 4.71793930e+01 2.02486522e+02 4.71792274e+01 2.02486750e+02 4.71792121e+01 2.02486976e+02 4.71793708e+01 2.02486966e+02 4.71795049e+01 2.02496070e+02 4.71854929e+01 2.02495877e+02 4.71854800e+01 2.02495850e+02 4.71853554e+01 2.02496052e+02 4.71853505e+01 2.02496070e+02 4.71854929e+01 2.02491038e+02 4.71823486e+01 2.02490827e+02 4.71823804e+01 2.02490814e+02 4.71822089e+01 2.02491069e+02 4.71822016e+01 2.02491038e+02 4.71823486e+01 2.02485617e+02 4.71792605e+01 2.02485290e+02 4.71793550e+01 2.02485215e+02 4.71793705e+01 2.02485235e+02 4.71793208e+01 2.02485400e+02 4.71791246e+01 2.02485622e+02 4.71790703e+01 2.02485617e+02 4.71792605e+01 2.02497210e+02 4.71871024e+01 2.02497203e+02 4.71871031e+01 2.02497204e+02 4.71870984e+01 2.02497209e+02 4.71870985e+01 2.02497210e+02 4.71871024e+01 2.02472885e+02 4.71718996e+01 2.02472873e+02 4.71719012e+01 2.02472874e+02 4.71718927e+01 2.02472885e+02 4.71718924e+01 2.02472885e+02 4.71718996e+01 2.02498701e+02 4.71883327e+01 2.02498628e+02 4.71883274e+01 2.02498630e+02 4.71882884e+01 2.02498679e+02 4.71882900e+01 2.02498701e+02 4.71883327e+01 2.02485689e+02 4.71802028e+01 2.02485413e+02 4.71803293e+01 2.02485263e+02 4.71803114e+01 2.02485213e+02 4.71802041e+01 2.02485415e+02 4.71800316e+01 2.02485644e+02 4.71800300e+01 2.02485689e+02 4.71802028e+01 2.02501726e+02 4.71905215e+01 2.02501463e+02 4.71904623e+01 2.02501442e+02 4.71903440e+01 2.02501594e+02 4.71903651e+01 2.02501726e+02 4.71905215e+01 2.02500854e+02 4.71899765e+01 2.02500797e+02 4.71899781e+01 2.02500484e+02 4.71898842e+01 2.02500286e+02 4.71899210e+01 2.02500043e+02 4.71898849e+01 2.02500035e+02 4.71897646e+01 2.02500334e+02 4.71896517e+01 2.02500365e+02 4.71896470e+01 2.02500675e+02 4.71897429e+01 2.02500864e+02 4.71899288e+01 2.02500854e+02 4.71899765e+01 2.02501598e+02 4.71910395e+01 2.02501546e+02 4.71910515e+01 2.02501538e+02 4.71910025e+01 2.02501615e+02 4.71910003e+01 2.02501598e+02 4.71910395e+01 2.02498544e+02 4.71891324e+01 2.02498430e+02 4.71891244e+01 2.02498159e+02 4.71889998e+01 2.02498084e+02 4.71888450e+01 2.02498433e+02 4.71887968e+01 2.02498521e+02 4.71890572e+01 2.02498544e+02 4.71891324e+01 2.02477096e+02 4.71757290e+01 2.02476924e+02 4.71757392e+01 2.02476931e+02 4.71756259e+01 2.02477077e+02 4.71756261e+01 2.02477096e+02 4.71757290e+01 2.02498508e+02 4.71894089e+01 2.02498461e+02 4.71894272e+01 2.02498485e+02 4.71893942e+01 2.02498511e+02 4.71893902e+01 2.02498508e+02 4.71894089e+01 2.02497289e+02 4.71886470e+01 2.02497107e+02 4.71888016e+01 2.02497095e+02 4.71888253e+01 2.02497074e+02 4.71888259e+01 2.02496789e+02 4.71887108e+01 2.02496778e+02 4.71886269e+01 2.02496862e+02 4.71883807e+01 2.02497267e+02 4.71883573e+01 2.02497289e+02 4.71886470e+01 2.02501447e+02 4.71915439e+01 2.02501316e+02 4.71915472e+01 2.02501330e+02 4.71914704e+01 2.02501472e+02 4.71914318e+01 2.02501447e+02 4.71915439e+01 2.02498779e+02 4.71898773e+01 2.02498727e+02 4.71898815e+01 2.02498737e+02 4.71898512e+01 2.02498771e+02 4.71898487e+01 2.02498779e+02 4.71898773e+01 2.02501444e+02 4.71918407e+01 2.02501290e+02 4.71920436e+01 2.02501081e+02 4.71920459e+01 2.02501087e+02 4.71919168e+01 2.02501348e+02 4.71917808e+01 2.02501444e+02 4.71917777e+01 2.02501444e+02 4.71918407e+01 2.02504728e+02 4.71941906e+01 2.02504305e+02 4.71942189e+01 2.02504314e+02 4.71939325e+01 2.02504698e+02 4.71939281e+01 2.02504728e+02 4.71941906e+01 2.02499841e+02 4.71914377e+01 2.02499548e+02 4.71915524e+01 2.02499652e+02 4.71913198e+01 2.02499828e+02 4.71913457e+01 2.02499841e+02 4.71914377e+01 2.02499136e+02 4.71909974e+01 2.02498936e+02 4.71910288e+01 2.02498992e+02 4.71909074e+01 2.02499086e+02 4.71909178e+01 2.02499136e+02 4.71909974e+01 2.02504929e+02 4.71949146e+01 2.02504712e+02 4.71950781e+01 2.02504474e+02 4.71950699e+01 2.02504152e+02 4.71949825e+01 2.02503931e+02 4.71948203e+01 2.02503668e+02 4.71946893e+01 2.02503453e+02 4.71945910e+01 2.02503399e+02 4.71945632e+01 2.02503397e+02 4.71945564e+01 2.02503430e+02 4.71942773e+01 2.02503792e+02 4.71942723e+01 2.02504067e+02 4.71943766e+01 2.02504193e+02 4.71943011e+01 2.02504530e+02 4.71943775e+01 2.02504771e+02 4.71945250e+01 2.02504990e+02 4.71946883e+01 2.02504929e+02 4.71949146e+01 2.02510081e+02 4.71984306e+01 2.02510033e+02 4.71984452e+01 2.02510044e+02 4.71984076e+01 2.02510080e+02 4.71984107e+01 2.02510081e+02 4.71984306e+01 2.02502817e+02 4.71941939e+01 2.02502577e+02 4.71941946e+01 2.02502511e+02 4.71940026e+01 2.02502847e+02 4.71939951e+01 2.02502817e+02 4.71941939e+01 2.02502354e+02 4.71939049e+01 2.02502113e+02 4.71938865e+01 2.02502047e+02 4.71937133e+01 2.02502369e+02 4.71936974e+01 2.02502354e+02 4.71939049e+01 2.02501824e+02 4.71935739e+01 2.02501658e+02 4.71935721e+01 2.02501633e+02 4.71934545e+01 2.02501797e+02 4.71934695e+01 2.02501824e+02 4.71935739e+01 2.02506011e+02 4.71964878e+01 2.02505655e+02 4.71964748e+01 2.02505633e+02 4.71962516e+01 2.02505994e+02 4.71962242e+01 2.02506011e+02 4.71964878e+01 2.02508242e+02 4.71981799e+01 2.02508042e+02 4.71983538e+01 2.02507935e+02 4.71983690e+01 2.02507721e+02 4.71984528e+01 2.02507411e+02 4.71984315e+01 2.02507271e+02 4.71982096e+01 2.02507265e+02 4.71981676e+01 2.02507339e+02 4.71981588e+01 2.02507605e+02 4.71980809e+01 2.02507923e+02 4.71980529e+01 2.02508184e+02 4.71981438e+01 2.02508233e+02 4.71981492e+01 2.02508242e+02 4.71981799e+01 2.02498510e+02 4.71927005e+01 2.02498431e+02 4.71927038e+01 2.02498434e+02 4.71926529e+01 2.02498509e+02 4.71926461e+01 2.02498510e+02 4.71927005e+01 2.02473531e+02 4.71779887e+01 2.02473423e+02 4.71780015e+01 2.02473404e+02 4.71779091e+01 2.02473536e+02 4.71779173e+01 2.02473531e+02 4.71779887e+01 2.02508653e+02 4.72002310e+01 2.02508507e+02 4.72002245e+01 2.02508498e+02 4.72001339e+01 2.02508692e+02 4.72000882e+01 2.02508653e+02 4.72002310e+01 2.02472833e+02 4.71778510e+01 2.02472746e+02 4.71778506e+01 2.02472748e+02 4.71777980e+01 2.02472820e+02 4.71777962e+01 2.02472833e+02 4.71778510e+01 2.02472076e+02 4.71773777e+01 2.02472064e+02 4.71773792e+01 2.02472062e+02 4.71773689e+01 2.02472081e+02 4.71773665e+01 2.02472076e+02 4.71773777e+01 2.02471596e+02 4.71773772e+01 2.02471218e+02 4.71774400e+01 2.02471038e+02 4.71774865e+01 2.02471061e+02 4.71773417e+01 2.02471272e+02 4.71771747e+01 2.02471463e+02 4.71771725e+01 2.02471596e+02 4.71773772e+01 2.02505753e+02 4.71990184e+01 2.02505735e+02 4.71990193e+01 2.02505736e+02 4.71990075e+01 2.02505754e+02 4.71990058e+01 2.02505753e+02 4.71990184e+01 2.02474547e+02 4.71795214e+01 2.02474383e+02 4.71795690e+01 2.02474441e+02 4.71794549e+01 2.02474544e+02 4.71794495e+01 2.02474547e+02 4.71795214e+01 2.02470593e+02 4.71770493e+01 2.02470220e+02 4.71771148e+01 2.02470283e+02 4.71768555e+01 2.02470541e+02 4.71768775e+01 2.02470593e+02 4.71770493e+01 2.02472608e+02 4.71789072e+01 2.02472391e+02 4.71790712e+01 2.02472184e+02 4.71792410e+01 2.02472184e+02 4.71792424e+01 2.02472116e+02 4.71794975e+01 2.02471783e+02 4.71795380e+01 2.02471560e+02 4.71793779e+01 2.02471343e+02 4.71793131e+01 2.02471242e+02 4.71792875e+01 2.02471230e+02 4.71792426e+01 2.02471157e+02 4.71790251e+01 2.02470982e+02 4.71788290e+01 2.02470597e+02 4.71787883e+01 2.02470639e+02 4.71785741e+01 2.02470948e+02 4.71785290e+01 2.02471039e+02 4.71785251e+01 2.02471427e+02 4.71785002e+01 2.02471527e+02 4.71785308e+01 2.02471728e+02 4.71786034e+01 2.02472139e+02 4.71786143e+01 2.02472158e+02 4.71786103e+01 2.02472578e+02 4.71786254e+01 2.02472608e+02 4.71789072e+01 2.02469423e+02 4.71769160e+01 2.02469201e+02 4.71768922e+01 2.02469213e+02 4.71767849e+01 2.02469365e+02 4.71767711e+01 2.02469423e+02 4.71769160e+01 2.02470111e+02 4.71776456e+01 2.02469941e+02 4.71776463e+01 2.02469875e+02 4.71774981e+01 2.02470082e+02 4.71775426e+01 2.02470111e+02 4.71776456e+01 2.02507076e+02 4.72016391e+01 2.02507039e+02 4.72016358e+01 2.02507038e+02 4.72016152e+01 2.02507069e+02 4.72016134e+01 2.02507076e+02 4.72016391e+01 2.02476162e+02 4.71823258e+01 2.02475919e+02 4.71823379e+01 2.02475920e+02 4.71821749e+01 2.02476154e+02 4.71821641e+01 2.02476162e+02 4.71823258e+01 2.02470364e+02 4.71790004e+01 2.02470291e+02 4.71790144e+01 2.02470288e+02 4.71789529e+01 2.02470437e+02 4.71789068e+01 2.02470364e+02 4.71790004e+01 2.02469250e+02 4.71786034e+01 2.02469102e+02 4.71785918e+01 2.02469062e+02 4.71784860e+01 2.02469243e+02 4.71784876e+01 2.02469250e+02 4.71786034e+01 2.02469929e+02 4.71793273e+01 2.02469867e+02 4.71793279e+01 2.02469866e+02 4.71792875e+01 2.02469944e+02 4.71792706e+01 2.02469929e+02 4.71793273e+01 2.02508853e+02 4.72039446e+01 2.02508745e+02 4.72039542e+01 2.02508742e+02 4.72038757e+01 2.02508853e+02 4.72038743e+01 2.02508853e+02 4.72039446e+01 2.02475337e+02 4.71830070e+01 2.02474996e+02 4.71830194e+01 2.02474997e+02 4.71827944e+01 2.02475316e+02 4.71827832e+01 2.02475337e+02 4.71830070e+01 2.02508893e+02 4.72042686e+01 2.02508685e+02 4.72043243e+01 2.02508702e+02 4.72041496e+01 2.02508917e+02 4.72041523e+01 2.02508893e+02 4.72042686e+01 2.02508184e+02 4.72038265e+01 2.02508024e+02 4.72038364e+01 2.02508037e+02 4.72037345e+01 2.02508183e+02 4.72037187e+01 2.02508184e+02 4.72038265e+01 2.02465777e+02 4.71773292e+01 2.02465555e+02 4.71773093e+01 2.02465556e+02 4.71771912e+01 2.02465740e+02 4.71771723e+01 2.02465777e+02 4.71773292e+01 2.02494317e+02 4.71957645e+01 2.02494281e+02 4.71957717e+01 2.02494286e+02 4.71957451e+01 2.02494329e+02 4.71957358e+01 2.02494317e+02 4.71957645e+01 2.02496870e+02 4.71976585e+01 2.02496532e+02 4.71976869e+01 2.02496547e+02 4.71974569e+01 2.02496855e+02 4.71974481e+01 2.02496870e+02 4.71976585e+01 2.02469554e+02 4.71808881e+01 2.02469517e+02 4.71808875e+01 2.02469516e+02 4.71808639e+01 2.02469551e+02 4.71808623e+01 2.02469554e+02 4.71808881e+01 2.02463933e+02 4.71779714e+01 2.02463771e+02 4.71779769e+01 2.02463734e+02 4.71778472e+01 2.02463922e+02 4.71778656e+01 2.02463933e+02 4.71779714e+01 2.02481234e+02 4.71905823e+01 2.02481062e+02 4.71905745e+01 2.02481032e+02 4.71904563e+01 2.02481201e+02 4.71904711e+01 2.02481234e+02 4.71905823e+01 2.02461671e+02 4.71786519e+01 2.02461534e+02 4.71786539e+01 2.02461519e+02 4.71785570e+01 2.02461735e+02 4.71785051e+01 2.02461671e+02 4.71786519e+01 2.02481773e+02 4.71915176e+01 2.02481465e+02 4.71916240e+01 2.02481589e+02 4.71918116e+01 2.02481626e+02 4.71920240e+01 2.02481401e+02 4.71921823e+01 2.02481179e+02 4.71921146e+01 2.02480857e+02 4.71920269e+01 2.02480587e+02 4.71919728e+01 2.02480428e+02 4.71921730e+01 2.02480510e+02 4.71922837e+01 2.02480755e+02 4.71924281e+01 2.02480985e+02 4.71925212e+01 2.02481079e+02 4.71925136e+01 2.02481312e+02 4.71924262e+01 2.02481682e+02 4.71923930e+01 2.02481873e+02 4.71925777e+01 2.02482050e+02 4.71927721e+01 2.02482324e+02 4.71928950e+01 2.02482409e+02 4.71931115e+01 2.02482306e+02 4.71932336e+01 2.02482487e+02 4.71931605e+01 2.02482759e+02 4.71932244e+01 2.02483135e+02 4.71932715e+01 2.02483069e+02 4.71935239e+01 2.02483033e+02 4.71936725e+01 2.02483143e+02 4.71938696e+01 2.02482883e+02 4.71940061e+01 2.02482872e+02 4.71941170e+01 2.02483169e+02 4.71942226e+01 2.02483152e+02 4.71944736e+01 2.02483190e+02 4.71945326e+01 2.02483205e+02 4.71948054e+01 2.02482858e+02 4.71948883e+01 2.02482882e+02 4.71950857e+01 2.02483115e+02 4.71950485e+01 2.02483423e+02 4.71949419e+01 2.02483582e+02 4.71947421e+01 2.02483629e+02 4.71945337e+01 2.02483262e+02 4.71944791e+01 2.02483220e+02 4.71942165e+01 2.02483520e+02 4.71941048e+01 2.02483752e+02 4.71941173e+01 2.02483760e+02 4.71942552e+01 2.02483705e+02 4.71944774e+01 2.02483970e+02 4.71946065e+01 2.02483975e+02 4.71946887e+01 2.02483911e+02 4.71949474e+01 2.02483507e+02 4.71949947e+01 2.02483613e+02 4.71951960e+01 2.02483709e+02 4.71954197e+01 2.02483308e+02 4.71954215e+01 2.02483260e+02 4.71954382e+01 2.02482902e+02 4.71953958e+01 2.02482629e+02 4.71953430e+01 2.02482552e+02 4.71953292e+01 2.02482299e+02 4.71951911e+01 2.02482206e+02 4.71950789e+01 2.02482113e+02 4.71950029e+01 2.02482018e+02 4.71949617e+01 2.02481798e+02 4.71949106e+01 2.02481748e+02 4.71947926e+01 2.02482007e+02 4.71946555e+01 2.02482248e+02 4.71945067e+01 2.02482173e+02 4.71943083e+01 2.02482158e+02 4.71941512e+01 2.02482198e+02 4.71939639e+01 2.02481987e+02 4.71937948e+01 2.02481709e+02 4.71936747e+01 2.02481418e+02 4.71935647e+01 2.02481244e+02 4.71933681e+01 2.02481005e+02 4.71932190e+01 2.02480673e+02 4.71931389e+01 2.02480581e+02 4.71928815e+01 2.02480430e+02 4.71927724e+01 2.02480355e+02 4.71927234e+01 2.02480150e+02 4.71925495e+01 2.02479962e+02 4.71924800e+01 2.02479864e+02 4.71924353e+01 2.02479662e+02 4.71922924e+01 2.02479640e+02 4.71922754e+01 2.02479653e+02 4.71919879e+01 2.02480002e+02 4.71920078e+01 2.02480241e+02 4.71920563e+01 2.02480267e+02 4.71918125e+01 2.02480186e+02 4.71917227e+01 2.02480077e+02 4.71916276e+01 2.02480012e+02 4.71916140e+01 2.02479735e+02 4.71917401e+01 2.02479481e+02 4.71917421e+01 2.02479463e+02 4.71915699e+01 2.02479443e+02 4.71914452e+01 2.02479226e+02 4.71912802e+01 2.02478984e+02 4.71911340e+01 2.02478969e+02 4.71909618e+01 2.02479069e+02 4.71907457e+01 2.02479050e+02 4.71907134e+01 2.02479107e+02 4.71907173e+01 2.02479478e+02 4.71907690e+01 2.02479694e+02 4.71909344e+01 2.02479981e+02 4.71909958e+01 2.02480054e+02 4.71909937e+01 2.02480411e+02 4.71910553e+01 2.02480464e+02 4.71912976e+01 2.02480477e+02 4.71913321e+01 2.02480542e+02 4.71913464e+01 2.02480912e+02 4.71913358e+01 2.02481091e+02 4.71913905e+01 2.02481211e+02 4.71914400e+01 2.02481586e+02 4.71914008e+01 2.02481720e+02 4.71913891e+01 2.02481773e+02 4.71915176e+01 2.02462663e+02 4.71801700e+01 2.02462527e+02 4.71801973e+01 2.02462254e+02 4.71800732e+01 2.02462081e+02 4.71798756e+01 2.02462075e+02 4.71798020e+01 2.02462183e+02 4.71798009e+01 2.02462472e+02 4.71799123e+01 2.02462663e+02 4.71800964e+01 2.02462663e+02 4.71801700e+01 2.02481690e+02 4.71929614e+01 2.02481389e+02 4.71929354e+01 2.02481235e+02 4.71929761e+01 2.02481219e+02 4.71930607e+01 2.02481495e+02 4.71931820e+01 2.02481550e+02 4.71931729e+01 2.02481831e+02 4.71930494e+01 2.02481783e+02 4.71929695e+01 2.02481690e+02 4.71929614e+01 2.02477093e+02 4.71900884e+01 2.02477102e+02 4.71902468e+01 2.02477078e+02 4.71903787e+01 2.02476823e+02 4.71905183e+01 2.02476786e+02 4.71907946e+01 2.02476463e+02 4.71908915e+01 2.02476192e+02 4.71909198e+01 2.02475888e+02 4.71908185e+01 2.02475871e+02 4.71908207e+01 2.02475517e+02 4.71907672e+01 2.02475202e+02 4.71907023e+01 2.02475151e+02 4.71907125e+01 2.02474754e+02 4.71906808e+01 2.02474487e+02 4.71905525e+01 2.02474483e+02 4.71905517e+01 2.02474039e+02 4.71905581e+01 2.02474013e+02 4.71905573e+01 2.02474020e+02 4.71905726e+01 2.02474084e+02 4.71906018e+01 2.02474471e+02 4.71905644e+01 2.02474680e+02 4.71907354e+01 2.02474860e+02 4.71909276e+01 2.02475149e+02 4.71910397e+01 2.02475372e+02 4.71912003e+01 2.02475487e+02 4.71911792e+01 2.02475847e+02 4.71911746e+01 2.02475980e+02 4.71911885e+01 2.02476167e+02 4.71910062e+01 2.02476505e+02 4.71910131e+01 2.02476741e+02 4.71911647e+01 2.02476959e+02 4.71913285e+01 2.02476964e+02 4.71915039e+01 2.02476664e+02 4.71916158e+01 2.02476821e+02 4.71917558e+01 2.02477086e+02 4.71918853e+01 2.02477135e+02 4.71919098e+01 2.02477435e+02 4.71919532e+01 2.02477658e+02 4.71921135e+01 2.02477686e+02 4.71922543e+01 2.02477426e+02 4.71922852e+01 2.02477251e+02 4.71922816e+01 2.02476947e+02 4.71923134e+01 2.02476838e+02 4.71923229e+01 2.02476831e+02 4.71923992e+01 2.02476862e+02 4.71926368e+01 2.02476469e+02 4.71926670e+01 2.02476442e+02 4.71926736e+01 2.02476439e+02 4.71926887e+01 2.02476634e+02 4.71927941e+01 2.02476710e+02 4.71928137e+01 2.02477042e+02 4.71927494e+01 2.02477178e+02 4.71927935e+01 2.02477189e+02 4.71928413e+01 2.02477269e+02 4.71930518e+01 2.02477518e+02 4.71931930e+01 2.02477684e+02 4.71933953e+01 2.02477968e+02 4.71935109e+01 2.02478040e+02 4.71936725e+01 2.02478091e+02 4.71937455e+01 2.02478259e+02 4.71938096e+01 2.02478415e+02 4.71938314e+01 2.02478738e+02 4.71939182e+01 2.02478674e+02 4.71940688e+01 2.02478736e+02 4.71942450e+01 2.02478992e+02 4.71943808e+01 2.02479205e+02 4.71945494e+01 2.02479451e+02 4.71946923e+01 2.02479748e+02 4.71947987e+01 2.02479966e+02 4.71949626e+01 2.02480191e+02 4.71951217e+01 2.02480301e+02 4.71953656e+01 2.02480560e+02 4.71954998e+01 2.02480948e+02 4.71955385e+01 2.02481186e+02 4.71956381e+01 2.02481237e+02 4.71956500e+01 2.02481514e+02 4.71957709e+01 2.02481802e+02 4.71958835e+01 2.02481854e+02 4.71960556e+01 2.02481806e+02 4.71962056e+01 2.02481808e+02 4.71963263e+01 2.02481877e+02 4.71964786e+01 2.02481989e+02 4.71967215e+01 2.02482030e+02 4.71967638e+01 2.02482212e+02 4.71968819e+01 2.02482303e+02 4.71971397e+01 2.02482293e+02 4.71972275e+01 2.02482167e+02 4.71974481e+01 2.02481878e+02 4.71975665e+01 2.02481813e+02 4.71978252e+01 2.02481590e+02 4.71979853e+01 2.02481538e+02 4.71980306e+01 2.02481393e+02 4.71981610e+01 2.02481348e+02 4.71981709e+01 2.02480964e+02 4.71981926e+01 2.02480852e+02 4.71982125e+01 2.02480608e+02 4.71980671e+01 2.02480223e+02 4.71980260e+01 2.02480218e+02 4.71980255e+01 2.02479868e+02 4.71979630e+01 2.02479709e+02 4.71977552e+01 2.02479716e+02 4.71977118e+01 2.02479801e+02 4.71974658e+01 2.02480181e+02 4.71974067e+01 2.02480186e+02 4.71974068e+01 2.02480187e+02 4.71974024e+01 2.02480270e+02 4.71971606e+01 2.02480385e+02 4.71969330e+01 2.02480386e+02 4.71969297e+01 2.02480378e+02 4.71969286e+01 2.02479954e+02 4.71969238e+01 2.02479689e+02 4.71967941e+01 2.02479452e+02 4.71966440e+01 2.02479420e+02 4.71966292e+01 2.02479075e+02 4.71967130e+01 2.02478788e+02 4.71968324e+01 2.02478718e+02 4.71970879e+01 2.02478443e+02 4.71970640e+01 2.02478198e+02 4.71969198e+01 2.02478101e+02 4.71967028e+01 2.02478490e+02 4.71967041e+01 2.02478703e+02 4.71967797e+01 2.02478572e+02 4.71966434e+01 2.02478414e+02 4.71964345e+01 2.02478461e+02 4.71963288e+01 2.02478384e+02 4.71961318e+01 2.02478130e+02 4.71961223e+01 2.02478023e+02 4.71963545e+01 2.02477719e+02 4.71962978e+01 2.02477376e+02 4.71962260e+01 2.02477324e+02 4.71962168e+01 2.02477340e+02 4.71962524e+01 2.02477366e+02 4.71965423e+01 2.02477353e+02 4.71965681e+01 2.02477227e+02 4.71967547e+01 2.02476950e+02 4.71968808e+01 2.02477157e+02 4.71970383e+01 2.02477290e+02 4.71970932e+01 2.02477486e+02 4.71971208e+01 2.02477517e+02 4.71972350e+01 2.02477359e+02 4.71974358e+01 2.02477339e+02 4.71975548e+01 2.02477465e+02 4.71977868e+01 2.02477781e+02 4.71978782e+01 2.02478144e+02 4.71979354e+01 2.02478159e+02 4.71979354e+01 2.02478455e+02 4.71980312e+01 2.02478456e+02 4.71981208e+01 2.02478421e+02 4.71983819e+01 2.02478588e+02 4.71985030e+01 2.02478347e+02 4.71984361e+01 2.02478156e+02 4.71982524e+01 2.02477787e+02 4.71983012e+01 2.02477594e+02 4.71984799e+01 2.02477601e+02 4.71986623e+01 2.02477578e+02 4.71987694e+01 2.02477471e+02 4.71990012e+01 2.02477430e+02 4.71991137e+01 2.02477561e+02 4.71993423e+01 2.02477580e+02 4.71993687e+01 2.02477764e+02 4.71995179e+01 2.02477860e+02 4.71997725e+01 2.02477954e+02 4.71999016e+01 2.02478012e+02 4.71999849e+01 2.02478082e+02 4.72002591e+01 2.02478480e+02 4.72002901e+01 2.02478754e+02 4.72004133e+01 2.02478856e+02 4.72006629e+01 2.02479051e+02 4.72008440e+01 2.02479082e+02 4.72009060e+01 2.02478999e+02 4.72008826e+01 2.02478769e+02 4.72007269e+01 2.02478388e+02 4.72007716e+01 2.02478218e+02 4.72008090e+01 2.02478244e+02 4.72006812e+01 2.02478121e+02 4.72005550e+01 2.02477992e+02 4.72005242e+01 2.02477663e+02 4.72006178e+01 2.02477628e+02 4.72008947e+01 2.02477596e+02 4.72009434e+01 2.02477574e+02 4.72011600e+01 2.02477650e+02 4.72012288e+01 2.02477703e+02 4.72012408e+01 2.02477696e+02 4.72011944e+01 2.02477664e+02 4.72009170e+01 2.02478041e+02 4.72009398e+01 2.02478196e+02 4.72011506e+01 2.02478183e+02 4.72012416e+01 2.02478159e+02 4.72015034e+01 2.02478175e+02 4.72015360e+01 2.02478134e+02 4.72018093e+01 2.02478119e+02 4.72018583e+01 2.02478094e+02 4.72020838e+01 2.02478145e+02 4.72021645e+01 2.02478181e+02 4.72024373e+01 2.02478146e+02 4.72024888e+01 2.02478142e+02 4.72027119e+01 2.02478061e+02 4.72028769e+01 2.02478033e+02 4.72029431e+01 2.02478155e+02 4.72031331e+01 2.02478114e+02 4.72032929e+01 2.02477948e+02 4.72034883e+01 2.02477595e+02 4.72035461e+01 2.02477462e+02 4.72033191e+01 2.02477242e+02 4.72033466e+01 2.02477072e+02 4.72035391e+01 2.02476895e+02 4.72037282e+01 2.02476638e+02 4.72038663e+01 2.02476259e+02 4.72038830e+01 2.02476219e+02 4.72039037e+01 2.02476213e+02 4.72039168e+01 2.02476178e+02 4.72041774e+01 2.02475868e+02 4.72041720e+01 2.02475701e+02 4.72039700e+01 2.02475335e+02 4.72039500e+01 2.02475290e+02 4.72039478e+01 2.02474888e+02 4.72039194e+01 2.02474885e+02 4.72036691e+01 2.02475254e+02 4.72036495e+01 2.02475514e+02 4.72037627e+01 2.02475591e+02 4.72035116e+01 2.02475891e+02 4.72035037e+01 2.02476057e+02 4.72035035e+01 2.02476325e+02 4.72035085e+01 2.02476487e+02 4.72034730e+01 2.02476611e+02 4.72032974e+01 2.02476531e+02 4.72032013e+01 2.02476630e+02 4.72029642e+01 2.02476641e+02 4.72029501e+01 2.02476616e+02 4.72029549e+01 2.02476335e+02 4.72030786e+01 2.02476096e+02 4.72032286e+01 2.02475888e+02 4.72033977e+01 2.02475582e+02 4.72034070e+01 2.02475368e+02 4.72032398e+01 2.02475238e+02 4.72030103e+01 2.02475244e+02 4.72029953e+01 2.02475269e+02 4.72029872e+01 2.02475486e+02 4.72028477e+01 2.02475567e+02 4.72027674e+01 2.02475595e+02 4.72026167e+01 2.02475787e+02 4.72026050e+01 2.02476080e+02 4.72026204e+01 2.02476309e+02 4.72024640e+01 2.02476155e+02 4.72023331e+01 2.02475946e+02 4.72021620e+01 2.02475878e+02 4.72018960e+01 2.02476195e+02 4.72017943e+01 2.02476311e+02 4.72015678e+01 2.02476313e+02 4.72015654e+01 2.02476304e+02 4.72015638e+01 2.02475997e+02 4.72016705e+01 2.02475680e+02 4.72017078e+01 2.02475538e+02 4.72014876e+01 2.02475277e+02 4.72013553e+01 2.02474930e+02 4.72012861e+01 2.02474916e+02 4.72012943e+01 2.02474917e+02 4.72012958e+01 2.02474913e+02 4.72015919e+01 2.02474821e+02 4.72016921e+01 2.02474772e+02 4.72018030e+01 2.02474651e+02 4.72018178e+01 2.02474395e+02 4.72016811e+01 2.02474176e+02 4.72017294e+01 2.02473934e+02 4.72018780e+01 2.02473652e+02 4.72019050e+01 2.02473446e+02 4.72018722e+01 2.02473301e+02 4.72018391e+01 2.02473265e+02 4.72017587e+01 2.02473182e+02 4.72016016e+01 2.02473178e+02 4.72014053e+01 2.02473298e+02 4.72011903e+01 2.02472990e+02 4.72012876e+01 2.02472706e+02 4.72013025e+01 2.02472434e+02 4.72011779e+01 2.02472166e+02 4.72010506e+01 2.02472127e+02 4.72010480e+01 2.02471842e+02 4.72011690e+01 2.02471629e+02 4.72013351e+01 2.02471519e+02 4.72015288e+01 2.02471505e+02 4.72015564e+01 2.02471403e+02 4.72017920e+01 2.02471239e+02 4.72019891e+01 2.02470860e+02 4.72020151e+01 2.02470670e+02 4.72018301e+01 2.02470542e+02 4.72018524e+01 2.02470279e+02 4.72017940e+01 2.02470050e+02 4.72016374e+01 2.02469829e+02 4.72014757e+01 2.02469538e+02 4.72013653e+01 2.02469272e+02 4.72012367e+01 2.02469044e+02 4.72010793e+01 2.02468878e+02 4.72008770e+01 2.02468615e+02 4.72007455e+01 2.02468376e+02 4.72005973e+01 2.02468158e+02 4.72004331e+01 2.02467851e+02 4.72003342e+01 2.02467620e+02 4.72001799e+01 2.02467370e+02 4.72000390e+01 2.02467160e+02 4.71998686e+01 2.02466902e+02 4.71997344e+01 2.02466643e+02 4.71996004e+01 2.02466406e+02 4.71994496e+01 2.02466135e+02 4.71993246e+01 2.02465883e+02 4.71991856e+01 2.02465661e+02 4.71990246e+01 2.02465406e+02 4.71988870e+01 2.02465161e+02 4.71987428e+01 2.02464918e+02 4.71985974e+01 2.02464671e+02 4.71984541e+01 2.02464467e+02 4.71982797e+01 2.02464229e+02 4.71981305e+01 2.02463957e+02 4.71980056e+01 2.02463728e+02 4.71978497e+01 2.02463503e+02 4.71976907e+01 2.02463269e+02 4.71975382e+01 2.02463064e+02 4.71973642e+01 2.02462836e+02 4.71972074e+01 2.02462621e+02 4.71970409e+01 2.02462410e+02 4.71968714e+01 2.02462114e+02 4.71967648e+01 2.02461947e+02 4.71965634e+01 2.02461731e+02 4.71963974e+01 2.02461488e+02 4.71962514e+01 2.02461205e+02 4.71961354e+01 2.02460955e+02 4.71959944e+01 2.02460688e+02 4.71958668e+01 2.02460379e+02 4.71957695e+01 2.02460368e+02 4.71954932e+01 2.02460621e+02 4.71953521e+01 2.02461003e+02 4.71952916e+01 2.02461119e+02 4.71950646e+01 2.02461311e+02 4.71948856e+01 2.02461493e+02 4.71947001e+01 2.02461474e+02 4.71946357e+01 2.02461586e+02 4.71944588e+01 2.02461854e+02 4.71943273e+01 2.02461948e+02 4.71942858e+01 2.02462178e+02 4.71942305e+01 2.02462151e+02 4.71941357e+01 2.02462233e+02 4.71939656e+01 2.02462415e+02 4.71937803e+01 2.02462670e+02 4.71936401e+01 2.02462941e+02 4.71935105e+01 2.02463110e+02 4.71934276e+01 2.02463230e+02 4.71933922e+01 2.02463268e+02 4.71933108e+01 2.02463378e+02 4.71931854e+01 2.02463595e+02 4.71930216e+01 2.02463843e+02 4.71928777e+01 2.02464046e+02 4.71927054e+01 2.02464255e+02 4.71925364e+01 2.02464462e+02 4.71923668e+01 2.02464661e+02 4.71921922e+01 2.02464898e+02 4.71920411e+01 2.02465083e+02 4.71918575e+01 2.02465287e+02 4.71916853e+01 2.02465504e+02 4.71915223e+01 2.02465735e+02 4.71913673e+01 2.02466003e+02 4.71912354e+01 2.02466194e+02 4.71910559e+01 2.02466441e+02 4.71909109e+01 2.02466691e+02 4.71907677e+01 2.02466895e+02 4.71905962e+01 2.02467111e+02 4.71904320e+01 2.02467324e+02 4.71902656e+01 2.02467519e+02 4.71900883e+01 2.02467785e+02 4.71899557e+01 2.02468015e+02 4.71897999e+01 2.02468222e+02 4.71896305e+01 2.02468414e+02 4.71894511e+01 2.02468629e+02 4.71892864e+01 2.02468830e+02 4.71891126e+01 2.02469069e+02 4.71889627e+01 2.02469314e+02 4.71888167e+01 2.02469289e+02 4.71885373e+01 2.02469067e+02 4.71883765e+01 2.02469020e+02 4.71883338e+01 2.02469233e+02 4.71882538e+01 2.02469365e+02 4.71882501e+01 2.02469655e+02 4.71881321e+01 2.02469889e+02 4.71880940e+01 2.02470048e+02 4.71880791e+01 2.02470287e+02 4.71879287e+01 2.02470564e+02 4.71879209e+01 2.02470776e+02 4.71879353e+01 2.02471023e+02 4.71877909e+01 2.02471213e+02 4.71877671e+01 2.02471222e+02 4.71879148e+01 2.02471174e+02 4.71881208e+01 2.02471552e+02 4.71881668e+01 2.02471636e+02 4.71884304e+01 2.02472020e+02 4.71884715e+01 2.02472036e+02 4.71887229e+01 2.02471736e+02 4.71888349e+01 2.02471448e+02 4.71888942e+01 2.02471358e+02 4.71888980e+01 2.02470988e+02 4.71889085e+01 2.02470912e+02 4.71889182e+01 2.02470700e+02 4.71890845e+01 2.02470503e+02 4.71892606e+01 2.02470211e+02 4.71893779e+01 2.02470100e+02 4.71895650e+01 2.02470103e+02 4.71896090e+01 2.02470022e+02 4.71896223e+01 2.02469701e+02 4.71895341e+01 2.02469453e+02 4.71893922e+01 2.02469296e+02 4.71894038e+01 2.02469001e+02 4.71895192e+01 2.02468912e+02 4.71897626e+01 2.02468890e+02 4.71898082e+01 2.02469122e+02 4.71898935e+01 2.02469203e+02 4.71899022e+01 2.02469497e+02 4.71898291e+01 2.02469778e+02 4.71898031e+01 2.02469879e+02 4.71897684e+01 2.02470266e+02 4.71897674e+01 2.02470438e+02 4.71898190e+01 2.02470600e+02 4.71896209e+01 2.02470768e+02 4.71894264e+01 2.02471173e+02 4.71894225e+01 2.02471377e+02 4.71895973e+01 2.02471537e+02 4.71896081e+01 2.02471859e+02 4.71895663e+01 2.02471949e+02 4.71895665e+01 2.02471924e+02 4.71895185e+01 2.02471844e+02 4.71892523e+01 2.02471839e+02 4.71891983e+01 2.02471997e+02 4.71891395e+01 2.02472207e+02 4.71891289e+01 2.02472475e+02 4.71889975e+01 2.02472770e+02 4.71888937e+01 2.02472782e+02 4.71888904e+01 2.02473149e+02 4.71889388e+01 2.02473338e+02 4.71889386e+01 2.02473597e+02 4.71888014e+01 2.02473906e+02 4.71887044e+01 2.02473917e+02 4.71887020e+01 2.02474320e+02 4.71886549e+01 2.02474470e+02 4.71886131e+01 2.02474714e+02 4.71887586e+01 2.02474996e+02 4.71888750e+01 2.02474969e+02 4.71890604e+01 2.02474785e+02 4.71892444e+01 2.02474746e+02 4.71893852e+01 2.02475057e+02 4.71894810e+01 2.02475168e+02 4.71894841e+01 2.02475491e+02 4.71893864e+01 2.02475626e+02 4.71893856e+01 2.02475825e+02 4.71895638e+01 2.02476086e+02 4.71894594e+01 2.02476438e+02 4.71894366e+01 2.02476497e+02 4.71897163e+01 2.02476259e+02 4.71898666e+01 2.02475865e+02 4.71898595e+01 2.02475780e+02 4.71898666e+01 2.02475722e+02 4.71899651e+01 2.02475905e+02 4.71899444e+01 2.02476243e+02 4.71899058e+01 2.02476475e+02 4.71900600e+01 2.02476415e+02 4.71902635e+01 2.02476239e+02 4.71904527e+01 2.02476235e+02 4.71905622e+01 2.02476447e+02 4.71905823e+01 2.02476740e+02 4.71904665e+01 2.02476581e+02 4.71903065e+01 2.02476531e+02 4.71900367e+01 2.02476787e+02 4.71898972e+01 2.02477055e+02 4.71899566e+01 2.02477093e+02 4.71900884e+01 2.02482220e+02 4.71935917e+01 2.02482175e+02 4.71936561e+01 2.02482340e+02 4.71936668e+01 2.02482300e+02 4.71935635e+01 2.02482220e+02 4.71935917e+01 2.02492284e+02 4.72001786e+01 2.02492280e+02 4.72001788e+01 2.02492280e+02 4.72001757e+01 2.02492284e+02 4.72001760e+01 2.02492284e+02 4.72001786e+01 2.02471899e+02 4.71874404e+01 2.02471607e+02 4.71874759e+01 2.02471365e+02 4.71873295e+01 2.02471393e+02 4.71871245e+01 2.02471656e+02 4.71871139e+01 2.02471871e+02 4.71872804e+01 2.02471899e+02 4.71874404e+01 2.02461429e+02 4.71811938e+01 2.02461124e+02 4.71812332e+01 2.02461056e+02 4.71809604e+01 2.02461447e+02 4.71809948e+01 2.02461429e+02 4.71811938e+01 2.02478849e+02 4.71923828e+01 2.02478574e+02 4.71924124e+01 2.02478357e+02 4.71922478e+01 2.02478367e+02 4.71920815e+01 2.02478660e+02 4.71920235e+01 2.02478842e+02 4.71922149e+01 2.02478849e+02 4.71923828e+01 2.02475570e+02 4.71903334e+01 2.02475191e+02 4.71903577e+01 2.02475155e+02 4.71903733e+01 2.02475148e+02 4.71903897e+01 2.02475209e+02 4.71904070e+01 2.02475554e+02 4.71904152e+01 2.02475637e+02 4.71903757e+01 2.02475664e+02 4.71903337e+01 2.02475570e+02 4.71903334e+01 2.02461055e+02 4.71812590e+01 2.02460666e+02 4.71813148e+01 2.02460570e+02 4.71813176e+01 2.02460186e+02 4.71812759e+01 2.02460175e+02 4.71810078e+01 2.02460579e+02 4.71809859e+01 2.02460609e+02 4.71809802e+01 2.02461054e+02 4.71809598e+01 2.02461055e+02 4.71812590e+01 2.02483555e+02 4.71956224e+01 2.02483411e+02 4.71958318e+01 2.02483154e+02 4.71958605e+01 2.02483187e+02 4.71956921e+01 2.02483342e+02 4.71954897e+01 2.02483691e+02 4.71954639e+01 2.02483555e+02 4.71956224e+01 2.02481269e+02 4.71941944e+01 2.02481126e+02 4.71944043e+01 2.02480745e+02 4.71943870e+01 2.02480632e+02 4.71941454e+01 2.02480592e+02 4.71940705e+01 2.02480698e+02 4.71940964e+01 2.02481043e+02 4.71940532e+01 2.02481198e+02 4.71940522e+01 2.02481269e+02 4.71941944e+01 2.02479039e+02 4.71928010e+01 2.02478962e+02 4.71927764e+01 2.02478959e+02 4.71927510e+01 2.02479047e+02 4.71927134e+01 2.02479039e+02 4.71928010e+01 2.02477455e+02 4.71918106e+01 2.02477117e+02 4.71918628e+01 2.02477195e+02 4.71916486e+01 2.02477373e+02 4.71916736e+01 2.02477455e+02 4.71918106e+01 2.02479675e+02 4.71934971e+01 2.02479309e+02 4.71934959e+01 2.02479182e+02 4.71932649e+01 2.02479177e+02 4.71931862e+01 2.02479323e+02 4.71931607e+01 2.02479596e+02 4.71932841e+01 2.02479675e+02 4.71934971e+01 2.02476263e+02 4.71913649e+01 2.02476226e+02 4.71915449e+01 2.02476548e+02 4.71915431e+01 2.02476455e+02 4.71913758e+01 2.02476263e+02 4.71913649e+01 2.02489140e+02 4.71997101e+01 2.02488951e+02 4.71997105e+01 2.02488947e+02 4.71995896e+01 2.02489125e+02 4.71995823e+01 2.02489140e+02 4.71997101e+01 2.02484323e+02 4.71967008e+01 2.02484105e+02 4.71968639e+01 2.02483894e+02 4.71969402e+01 2.02483695e+02 4.71967619e+01 2.02483670e+02 4.71965919e+01 2.02483970e+02 4.71965587e+01 2.02484159e+02 4.71965985e+01 2.02484302e+02 4.71966391e+01 2.02484323e+02 4.71967008e+01 2.02459649e+02 4.71812778e+01 2.02459301e+02 4.71812792e+01 2.02459309e+02 4.71810652e+01 2.02459611e+02 4.71810503e+01 2.02459649e+02 4.71812778e+01 2.02468513e+02 4.71871191e+01 2.02468086e+02 4.71871491e+01 2.02468100e+02 4.71868609e+01 2.02468495e+02 4.71868474e+01 2.02468513e+02 4.71871191e+01 2.02460013e+02 4.71818047e+01 2.02459924e+02 4.71817946e+01 2.02459922e+02 4.71817479e+01 2.02459994e+02 4.71817430e+01 2.02460013e+02 4.71818047e+01 2.02484719e+02 4.71975464e+01 2.02484468e+02 4.71974926e+01 2.02484173e+02 4.71975045e+01 2.02484004e+02 4.71975101e+01 2.02484013e+02 4.71974046e+01 2.02484248e+02 4.71972524e+01 2.02484345e+02 4.71972580e+01 2.02484619e+02 4.71973811e+01 2.02484719e+02 4.71975464e+01 2.02482597e+02 4.71962208e+01 2.02482206e+02 4.71962354e+01 2.02482232e+02 4.71959926e+01 2.02482564e+02 4.71959711e+01 2.02482597e+02 4.71962208e+01 2.02472983e+02 4.71902128e+01 2.02472820e+02 4.71901580e+01 2.02472477e+02 4.71900856e+01 2.02472214e+02 4.71900309e+01 2.02472081e+02 4.71900528e+01 2.02471904e+02 4.71901367e+01 2.02471605e+02 4.71902489e+01 2.02471592e+02 4.71904143e+01 2.02471946e+02 4.71904619e+01 2.02471975e+02 4.71904569e+01 2.02472394e+02 4.71904428e+01 2.02472436e+02 4.71904416e+01 2.02472810e+02 4.71904901e+01 2.02472942e+02 4.71904864e+01 2.02473111e+02 4.71902926e+01 2.02473110e+02 4.71902688e+01 2.02472983e+02 4.71902128e+01 2.02485614e+02 4.71984050e+01 2.02485439e+02 4.71984020e+01 2.02485407e+02 4.71982759e+01 2.02485624e+02 4.71982652e+01 2.02485614e+02 4.71984050e+01 2.02484643e+02 4.71980975e+01 2.02484618e+02 4.71983578e+01 2.02484878e+02 4.71984907e+01 2.02484901e+02 4.71985576e+01 2.02484774e+02 4.71985674e+01 2.02484417e+02 4.71985546e+01 2.02484340e+02 4.71985629e+01 2.02483944e+02 4.71985300e+01 2.02483780e+02 4.71983260e+01 2.02483769e+02 4.71981500e+01 2.02483962e+02 4.71979713e+01 2.02484327e+02 4.71979002e+01 2.02484384e+02 4.71978797e+01 2.02484631e+02 4.71980225e+01 2.02484643e+02 4.71980975e+01 2.02463126e+02 4.71846487e+01 2.02463108e+02 4.71846465e+01 2.02463103e+02 4.71846344e+01 2.02463124e+02 4.71846346e+01 2.02463126e+02 4.71846487e+01 2.02493626e+02 4.72040078e+01 2.02493216e+02 4.72040428e+01 2.02493236e+02 4.72037647e+01 2.02493607e+02 4.72037542e+01 2.02493626e+02 4.72040078e+01 2.02485448e+02 4.71991986e+01 2.02485193e+02 4.71993386e+01 2.02485159e+02 4.71995846e+01 2.02485150e+02 4.71996109e+01 2.02485018e+02 4.71998274e+01 2.02484884e+02 4.72000431e+01 2.02484662e+02 4.72002036e+01 2.02484299e+02 4.72002201e+01 2.02484044e+02 4.72000829e+01 2.02484035e+02 4.71998117e+01 2.02484033e+02 4.71997663e+01 2.02483770e+02 4.71996351e+01 2.02483691e+02 4.71995968e+01 2.02483504e+02 4.71995059e+01 2.02483493e+02 4.71994730e+01 2.02483341e+02 4.71993010e+01 2.02483163e+02 4.71991076e+01 2.02483165e+02 4.71989689e+01 2.02483253e+02 4.71987247e+01 2.02483700e+02 4.71987109e+01 2.02483941e+02 4.71988578e+01 2.02483958e+02 4.71988661e+01 2.02484371e+02 4.71988658e+01 2.02484597e+02 4.71990238e+01 2.02484839e+02 4.71991703e+01 2.02485014e+02 4.71992270e+01 2.02485108e+02 4.71989866e+01 2.02485412e+02 4.71990722e+01 2.02485448e+02 4.71991986e+01 2.02484607e+02 4.71995708e+01 2.02484634e+02 4.71996471e+01 2.02484846e+02 4.71997203e+01 2.02484845e+02 4.71994913e+01 2.02484607e+02 4.71995708e+01 2.02498521e+02 4.72094577e+01 2.02498194e+02 4.72094754e+01 2.02498188e+02 4.72092501e+01 2.02498502e+02 4.72092475e+01 2.02498521e+02 4.72094577e+01 2.02487471e+02 4.72025565e+01 2.02487211e+02 4.72026936e+01 2.02487114e+02 4.72026950e+01 2.02487104e+02 4.72026266e+01 2.02487290e+02 4.72024436e+01 2.02487461e+02 4.72024387e+01 2.02487471e+02 4.72025565e+01 2.02480365e+02 4.71987158e+01 2.02480180e+02 4.71987088e+01 2.02480125e+02 4.71985655e+01 2.02480306e+02 4.71986153e+01 2.02480365e+02 4.71987158e+01 2.02467127e+02 4.71907413e+01 2.02467137e+02 4.71907777e+01 2.02467177e+02 4.71907725e+01 2.02467179e+02 4.71907467e+01 2.02467127e+02 4.71907413e+01 2.02478772e+02 4.71989171e+01 2.02478745e+02 4.71991185e+01 2.02478938e+02 4.71993014e+01 2.02478958e+02 4.71993323e+01 2.02478887e+02 4.71993387e+01 2.02478508e+02 4.71992931e+01 2.02478307e+02 4.71991163e+01 2.02478321e+02 4.71989345e+01 2.02478321e+02 4.71987809e+01 2.02478273e+02 4.71986050e+01 2.02478633e+02 4.71985502e+01 2.02478773e+02 4.71987725e+01 2.02478772e+02 4.71989171e+01 2.02484541e+02 4.72034191e+01 2.02484393e+02 4.72036257e+01 2.02484110e+02 4.72036132e+01 2.02483995e+02 4.72033772e+01 2.02484334e+02 4.72032897e+01 2.02484545e+02 4.72032919e+01 2.02484541e+02 4.72034191e+01 2.02476790e+02 4.71991743e+01 2.02476778e+02 4.71992699e+01 2.02476790e+02 4.71994733e+01 2.02476829e+02 4.71995578e+01 2.02476885e+02 4.71998320e+01 2.02476884e+02 4.71998426e+01 2.02476935e+02 4.72001305e+01 2.02477013e+02 4.72002110e+01 2.02476784e+02 4.72003672e+01 2.02476607e+02 4.72005560e+01 2.02476528e+02 4.72007558e+01 2.02476712e+02 4.72009209e+01 2.02476321e+02 4.72009758e+01 2.02476399e+02 4.72011771e+01 2.02476624e+02 4.72011653e+01 2.02476732e+02 4.72009334e+01 2.02476736e+02 4.72009281e+01 2.02476857e+02 4.72007119e+01 2.02477077e+02 4.72005506e+01 2.02477380e+02 4.72004520e+01 2.02477399e+02 4.72004528e+01 2.02477391e+02 4.72004438e+01 2.02477429e+02 4.72001719e+01 2.02477583e+02 4.71999766e+01 2.02477248e+02 4.71998990e+01 2.02476933e+02 4.71998064e+01 2.02477027e+02 4.71996214e+01 2.02477047e+02 4.71993969e+01 2.02477042e+02 4.71993318e+01 2.02476902e+02 4.71991786e+01 2.02476790e+02 4.71991743e+01 2.02479853e+02 4.72031825e+01 2.02479849e+02 4.72031830e+01 2.02479847e+02 4.72031787e+01 2.02479853e+02 4.72031800e+01 2.02479853e+02 4.72031825e+01 2.02478102e+02 4.72038840e+01 2.02477976e+02 4.72039155e+01 2.02478003e+02 4.72038220e+01 2.02478157e+02 4.72037823e+01 2.02478102e+02 4.72038840e+01 2.02483346e+02 4.72080576e+01 2.02483362e+02 4.72080699e+01 2.02483353e+02 4.72083609e+01 2.02482925e+02 4.72083929e+01 2.02482698e+02 4.72082355e+01 2.02482647e+02 4.72082192e+01 2.02482321e+02 4.72083145e+01 2.02482150e+02 4.72083149e+01 2.02481927e+02 4.72081540e+01 2.02481933e+02 4.72080724e+01 2.02482095e+02 4.72078744e+01 2.02482292e+02 4.72076980e+01 2.02482647e+02 4.72076208e+01 2.02482649e+02 4.72076210e+01 2.02482975e+02 4.72077054e+01 2.02483202e+02 4.72078634e+01 2.02483346e+02 4.72080576e+01 2.02478215e+02 4.72048517e+01 2.02477983e+02 4.72048862e+01 2.02477745e+02 4.72047370e+01 2.02477742e+02 4.72045567e+01 2.02478006e+02 4.72045440e+01 2.02478220e+02 4.72047113e+01 2.02478215e+02 4.72048517e+01 2.02472424e+02 4.72015324e+01 2.02472507e+02 4.72017744e+01 2.02472543e+02 4.72019060e+01 2.02472371e+02 4.72018750e+01 2.02472167e+02 4.72017004e+01 2.02472159e+02 4.72016662e+01 2.02472399e+02 4.72015168e+01 2.02472421e+02 4.72015125e+01 2.02472424e+02 4.72015324e+01 2.02472710e+02 4.72023098e+01 2.02472632e+02 4.72023332e+01 2.02472665e+02 4.72022813e+01 2.02472703e+02 4.72022802e+01 2.02472710e+02 4.72023098e+01 2.02472400e+02 4.72027142e+01 2.02472075e+02 4.72028104e+01 2.02471989e+02 4.72028080e+01 2.02471990e+02 4.72027571e+01 2.02472068e+02 4.72025069e+01 2.02472435e+02 4.72024783e+01 2.02472400e+02 4.72027142e+01 2.02483735e+02 4.72100957e+01 2.02483836e+02 4.72103227e+01 2.02483893e+02 4.72104935e+01 2.02483530e+02 4.72105656e+01 2.02483509e+02 4.72105643e+01 2.02483256e+02 4.72104263e+01 2.02482901e+02 4.72103630e+01 2.02482892e+02 4.72101670e+01 2.02483213e+02 4.72101324e+01 2.02483314e+02 4.72101318e+01 2.02483693e+02 4.72100693e+01 2.02483728e+02 4.72100773e+01 2.02483735e+02 4.72100957e+01 2.02475394e+02 4.72048844e+01 2.02475329e+02 4.72048950e+01 2.02474956e+02 4.72049099e+01 2.02474890e+02 4.72048937e+01 2.02474881e+02 4.72048634e+01 2.02475048e+02 4.72046685e+01 2.02475195e+02 4.72046685e+01 2.02475400e+02 4.72048427e+01 2.02475394e+02 4.72048844e+01 2.02473727e+02 4.72041419e+01 2.02473505e+02 4.72043026e+01 2.02473479e+02 4.72043100e+01 2.02473227e+02 4.72041709e+01 2.02473210e+02 4.72041182e+01 2.02473303e+02 4.72041146e+01 2.02473651e+02 4.72040944e+01 2.02473727e+02 4.72041268e+01 2.02473727e+02 4.72041419e+01 2.02472875e+02 4.72039087e+01 2.02472775e+02 4.72041455e+01 2.02472436e+02 4.72041042e+01 2.02472276e+02 4.72038972e+01 2.02471945e+02 4.72039260e+01 2.02471879e+02 4.72041839e+01 2.02471647e+02 4.72043384e+01 2.02471208e+02 4.72043606e+01 2.02471028e+02 4.72041684e+01 2.02471049e+02 4.72039649e+01 2.02471220e+02 4.72037720e+01 2.02471433e+02 4.72036061e+01 2.02471781e+02 4.72035244e+01 2.02472002e+02 4.72034487e+01 2.02472113e+02 4.72034328e+01 2.02472480e+02 4.72034214e+01 2.02472675e+02 4.72036025e+01 2.02472950e+02 4.72037244e+01 2.02472875e+02 4.72039087e+01 2.02475812e+02 4.72063422e+01 2.02475539e+02 4.72063664e+01 2.02475308e+02 4.72062115e+01 2.02475333e+02 4.72060434e+01 2.02475614e+02 4.72059858e+01 2.02475879e+02 4.72061155e+01 2.02475812e+02 4.72063422e+01 2.02484569e+02 4.72121124e+01 2.02484340e+02 4.72122280e+01 2.02484477e+02 4.72120550e+01 2.02484570e+02 4.72120584e+01 2.02484569e+02 4.72121124e+01 2.02475394e+02 4.72069786e+01 2.02475258e+02 4.72071930e+01 2.02474848e+02 4.72072022e+01 2.02474816e+02 4.72069168e+01 2.02474920e+02 4.72068240e+01 2.02474957e+02 4.72067058e+01 2.02475144e+02 4.72066581e+01 2.02475394e+02 4.72067990e+01 2.02475394e+02 4.72069786e+01 2.02469568e+02 4.72033383e+01 2.02469522e+02 4.72033286e+01 2.02469522e+02 4.72033096e+01 2.02469569e+02 4.72032938e+01 2.02469568e+02 4.72033383e+01 2.02473235e+02 4.72059289e+01 2.02473026e+02 4.72059457e+01 2.02473037e+02 4.72058055e+01 2.02473220e+02 4.72058026e+01 2.02473235e+02 4.72059289e+01 2.02468959e+02 4.72032568e+01 2.02468669e+02 4.72033085e+01 2.02468777e+02 4.72031430e+01 2.02468973e+02 4.72030837e+01 2.02468959e+02 4.72032568e+01 2.02478972e+02 4.72110097e+01 2.02478815e+02 4.72112106e+01 2.02478654e+02 4.72112228e+01 2.02478647e+02 4.72111056e+01 2.02478931e+02 4.72109836e+01 2.02478981e+02 4.72109809e+01 2.02478972e+02 4.72110097e+01 2.02476929e+02 4.72100324e+01 2.02476758e+02 4.72100204e+01 2.02476785e+02 4.72099422e+01 2.02476875e+02 4.72099344e+01 2.02476929e+02 4.72100324e+01 2.02470506e+02 4.72075148e+01 2.02470455e+02 4.72075189e+01 2.02470464e+02 4.72074887e+01 2.02470494e+02 4.72074901e+01 2.02470506e+02 4.72075148e+01 2.02480827e+02 4.72157585e+01 2.02480471e+02 4.72158354e+01 2.02480334e+02 4.72158379e+01 2.02480071e+02 4.72157067e+01 2.02480068e+02 4.72155833e+01 2.02480242e+02 4.72155805e+01 2.02480420e+02 4.72155045e+01 2.02480807e+02 4.72154889e+01 2.02480827e+02 4.72157585e+01 2.02471986e+02 4.72111328e+01 2.02471865e+02 4.72113564e+01 2.02471430e+02 4.72113532e+01 2.02471280e+02 4.72111385e+01 2.02471011e+02 4.72111223e+01 2.02470897e+02 4.72110963e+01 2.02470892e+02 4.72110477e+01 2.02471147e+02 4.72109077e+01 2.02471153e+02 4.72109073e+01 2.02471449e+02 4.72110139e+01 2.02471753e+02 4.72109870e+01 2.02471917e+02 4.72109934e+01 2.02471986e+02 4.72111328e+01 2.02467646e+02 4.72126102e+01 2.02467757e+02 4.72127645e+01 2.02467772e+02 4.72129880e+01 2.02467575e+02 4.72131641e+01 2.02467177e+02 4.72132147e+01 2.02467086e+02 4.72134570e+01 2.02466775e+02 4.72134898e+01 2.02466622e+02 4.72132770e+01 2.02466536e+02 4.72131133e+01 2.02466737e+02 4.72129398e+01 2.02466788e+02 4.72128291e+01 2.02466808e+02 4.72126850e+01 2.02467017e+02 4.72125164e+01 2.02467228e+02 4.72125045e+01 2.02467499e+02 4.72125182e+01 2.02467623e+02 4.72125379e+01 2.02467646e+02 4.72126102e+01 2.02463156e+02 4.72098043e+01 2.02462912e+02 4.72098368e+01 2.02462899e+02 4.72096438e+01 2.02463171e+02 4.72096452e+01 2.02463156e+02 4.72098043e+01 2.02481079e+02 4.71686454e+01 2.02480893e+02 4.71688279e+01 2.02480528e+02 4.71688453e+01 2.02480258e+02 4.71687200e+01 2.02480237e+02 4.71684178e+01 2.02480461e+02 4.71682591e+01 2.02480891e+02 4.71682516e+01 2.02481065e+02 4.71684489e+01 2.02481079e+02 4.71686454e+01 2.02493610e+02 4.71776737e+01 2.02493223e+02 4.71776803e+01 2.02493217e+02 4.71774281e+01 2.02493593e+02 4.71774066e+01 2.02493610e+02 4.71776737e+01 2.02489567e+02 4.71796349e+01 2.02489270e+02 4.71796271e+01 2.02489254e+02 4.71794393e+01 2.02489521e+02 4.71794412e+01 2.02489567e+02 4.71796349e+01 2.02477044e+02 4.71724055e+01 2.02477031e+02 4.71724069e+01 2.02477032e+02 4.71723982e+01 2.02477046e+02 4.71723959e+01 2.02477044e+02 4.71724055e+01 2.02495641e+02 4.71849255e+01 2.02495270e+02 4.71849926e+01 2.02495220e+02 4.71849898e+01 2.02495194e+02 4.71849456e+01 2.02495312e+02 4.71847199e+01 2.02495603e+02 4.71847064e+01 2.02495641e+02 4.71849255e+01 2.02497222e+02 4.71886054e+01 2.02496903e+02 4.71886265e+01 2.02496922e+02 4.71884183e+01 2.02497207e+02 4.71884019e+01 2.02497222e+02 4.71886054e+01 2.02504586e+02 4.71941023e+01 2.02504450e+02 4.71941113e+01 2.02504453e+02 4.71940193e+01 2.02504577e+02 4.71940179e+01 2.02504586e+02 4.71941023e+01 2.02504775e+02 4.71948184e+01 2.02504395e+02 4.71948801e+01 2.02504311e+02 4.71948655e+01 2.02504186e+02 4.71947499e+01 2.02504128e+02 4.71946754e+01 2.02504220e+02 4.71944716e+01 2.02504405e+02 4.71944700e+01 2.02504711e+02 4.71945697e+01 2.02504775e+02 4.71948184e+01 2.02503788e+02 4.71945015e+01 2.02503504e+02 4.71944857e+01 2.02503519e+02 4.71943330e+01 2.02503714e+02 4.71943303e+01 2.02503788e+02 4.71945015e+01 2.02505874e+02 4.71964018e+01 2.02505760e+02 4.71963976e+01 2.02505753e+02 4.71963262e+01 2.02505868e+02 4.71963175e+01 2.02505874e+02 4.71964018e+01 2.02507784e+02 4.71981928e+01 2.02507593e+02 4.71983724e+01 2.02507499e+02 4.71983660e+01 2.02507458e+02 4.71982882e+01 2.02507742e+02 4.71981665e+01 2.02507773e+02 4.71981637e+01 2.02507784e+02 4.71981928e+01 2.02472284e+02 4.71790039e+01 2.02472069e+02 4.71791691e+01 2.02471788e+02 4.71792092e+01 2.02471593e+02 4.71790279e+01 2.02471604e+02 4.71788779e+01 2.02471924e+02 4.71787790e+01 2.02471930e+02 4.71787792e+01 2.02472324e+02 4.71788130e+01 2.02472284e+02 4.71790039e+01 2.02475252e+02 4.71829540e+01 2.02475076e+02 4.71829604e+01 2.02475076e+02 4.71828442e+01 2.02475241e+02 4.71828384e+01 2.02475252e+02 4.71829540e+01 2.02496799e+02 4.71976139e+01 2.02496609e+02 4.71976298e+01 2.02496618e+02 4.71975010e+01 2.02496790e+02 4.71974960e+01 2.02496799e+02 4.71976139e+01 2.02481311e+02 4.71927244e+01 2.02481222e+02 4.71927336e+01 2.02481229e+02 4.71926734e+01 2.02481368e+02 4.71926252e+01 2.02481311e+02 4.71927244e+01 2.02480680e+02 4.71926297e+01 2.02480490e+02 4.71926235e+01 2.02480455e+02 4.71924887e+01 2.02480642e+02 4.71925115e+01 2.02480680e+02 4.71926297e+01 2.02461337e+02 4.71811361e+01 2.02461239e+02 4.71811487e+01 2.02461217e+02 4.71810610e+01 2.02461343e+02 4.71810721e+01 2.02461337e+02 4.71811361e+01 2.02482612e+02 4.71947344e+01 2.02482474e+02 4.71949471e+01 2.02482217e+02 4.71949258e+01 2.02482187e+02 4.71947680e+01 2.02482470e+02 4.71946456e+01 2.02482700e+02 4.71945693e+01 2.02482612e+02 4.71947344e+01 2.02475044e+02 4.71900047e+01 2.02474917e+02 4.71902249e+01 2.02474546e+02 4.71902919e+01 2.02474425e+02 4.71902728e+01 2.02474364e+02 4.71901780e+01 2.02474350e+02 4.71900032e+01 2.02474387e+02 4.71898931e+01 2.02474636e+02 4.71897496e+01 2.02474693e+02 4.71897497e+01 2.02475069e+02 4.71897975e+01 2.02475044e+02 4.71900047e+01 2.02461013e+02 4.71812326e+01 2.02460649e+02 4.71812590e+01 2.02460653e+02 4.71810074e+01 2.02461012e+02 4.71809910e+01 2.02461013e+02 4.71812326e+01 2.02473688e+02 4.71894563e+01 2.02473698e+02 4.71895091e+01 2.02473703e+02 4.71897653e+01 2.02473514e+02 4.71899462e+01 2.02473196e+02 4.71900469e+01 2.02472987e+02 4.71900342e+01 2.02472824e+02 4.71898292e+01 2.02472555e+02 4.71897031e+01 2.02472320e+02 4.71895515e+01 2.02472297e+02 4.71894849e+01 2.02472420e+02 4.71894772e+01 2.02472728e+02 4.71894550e+01 2.02472980e+02 4.71893890e+01 2.02473059e+02 4.71893626e+01 2.02473392e+02 4.71892716e+01 2.02473622e+02 4.71892397e+01 2.02473688e+02 4.71894563e+01 2.02460554e+02 4.71812449e+01 2.02460247e+02 4.71812310e+01 2.02460239e+02 4.71810481e+01 2.02460515e+02 4.71810331e+01 2.02460554e+02 4.71812449e+01 2.02480911e+02 4.71942700e+01 2.02480904e+02 4.71942696e+01 2.02480902e+02 4.71942642e+01 2.02480914e+02 4.71942624e+01 2.02480911e+02 4.71942700e+01 2.02476970e+02 4.71921062e+01 2.02476769e+02 4.71921200e+01 2.02476480e+02 4.71920989e+01 2.02476573e+02 4.71922642e+01 2.02476572e+02 4.71924557e+01 2.02476254e+02 4.71925003e+01 2.02476188e+02 4.71925151e+01 2.02475796e+02 4.71925132e+01 2.02475659e+02 4.71924835e+01 2.02475379e+02 4.71924961e+01 2.02475082e+02 4.71923900e+01 2.02475017e+02 4.71923817e+01 2.02475013e+02 4.71924414e+01 2.02475264e+02 4.71925808e+01 2.02475535e+02 4.71927054e+01 2.02475536e+02 4.71927054e+01 2.02475948e+02 4.71927261e+01 2.02476190e+02 4.71928725e+01 2.02476371e+02 4.71929289e+01 2.02476521e+02 4.71929533e+01 2.02476810e+02 4.71930652e+01 2.02477047e+02 4.71932153e+01 2.02477313e+02 4.71933442e+01 2.02477520e+02 4.71935166e+01 2.02477762e+02 4.71936632e+01 2.02477911e+02 4.71938783e+01 2.02478192e+02 4.71939960e+01 2.02478230e+02 4.71940906e+01 2.02478228e+02 4.71942947e+01 2.02478275e+02 4.71944177e+01 2.02478374e+02 4.71945125e+01 2.02478387e+02 4.71947868e+01 2.02478131e+02 4.71949263e+01 2.02477767e+02 4.71949606e+01 2.02477720e+02 4.71949687e+01 2.02477513e+02 4.71951384e+01 2.02477507e+02 4.71951528e+01 2.02477484e+02 4.71954193e+01 2.02477253e+02 4.71955742e+01 2.02477032e+02 4.71955040e+01 2.02476658e+02 4.71955018e+01 2.02476749e+02 4.71957130e+01 2.02476868e+02 4.71959319e+01 2.02476858e+02 4.71959580e+01 2.02476728e+02 4.71961434e+01 2.02476449e+02 4.71962602e+01 2.02476441e+02 4.71962634e+01 2.02476111e+02 4.71963566e+01 2.02475882e+02 4.71965127e+01 2.02475740e+02 4.71967228e+01 2.02475741e+02 4.71967830e+01 2.02475951e+02 4.71969533e+01 2.02476126e+02 4.71969641e+01 2.02476411e+02 4.71969385e+01 2.02476565e+02 4.71969396e+01 2.02476766e+02 4.71970019e+01 2.02477007e+02 4.71971488e+01 2.02477063e+02 4.71972509e+01 2.02476977e+02 4.71974958e+01 2.02476976e+02 4.71974970e+01 2.02477078e+02 4.71977471e+01 2.02477091e+02 4.71978667e+01 2.02476789e+02 4.71979610e+01 2.02476770e+02 4.71979650e+01 2.02476770e+02 4.71979745e+01 2.02477004e+02 4.71981269e+01 2.02477157e+02 4.71983399e+01 2.02477185e+02 4.71985235e+01 2.02477115e+02 4.71986955e+01 2.02477263e+02 4.71988717e+01 2.02477005e+02 4.71987774e+01 2.02476744e+02 4.71988462e+01 2.02476441e+02 4.71989560e+01 2.02476466e+02 4.71991752e+01 2.02476463e+02 4.71992692e+01 2.02476458e+02 4.71995070e+01 2.02476488e+02 4.71995843e+01 2.02476439e+02 4.71998462e+01 2.02476438e+02 4.71998520e+01 2.02476323e+02 4.72000793e+01 2.02476176e+02 4.72002864e+01 2.02476096e+02 4.72004244e+01 2.02476039e+02 4.72005003e+01 2.02475942e+02 4.72007392e+01 2.02475698e+02 4.72007190e+01 2.02475574e+02 4.72005088e+01 2.02475568e+02 4.72004896e+01 2.02475547e+02 4.72004924e+01 2.02475227e+02 4.72005915e+01 2.02474932e+02 4.72007063e+01 2.02474723e+02 4.72008749e+01 2.02474549e+02 4.72010651e+01 2.02474282e+02 4.72011142e+01 2.02474352e+02 4.72009423e+01 2.02474335e+02 4.72007497e+01 2.02474275e+02 4.72005949e+01 2.02474575e+02 4.72005721e+01 2.02474742e+02 4.72005871e+01 2.02474723e+02 4.72004631e+01 2.02474519e+02 4.72004479e+01 2.02474316e+02 4.72004381e+01 2.02474071e+02 4.72002944e+01 2.02473840e+02 4.72001397e+01 2.02473747e+02 4.71999657e+01 2.02473819e+02 4.71998296e+01 2.02473887e+02 4.71997536e+01 2.02473841e+02 4.71994883e+01 2.02473809e+02 4.71994060e+01 2.02473837e+02 4.71991654e+01 2.02473483e+02 4.71992022e+01 2.02473233e+02 4.71993455e+01 2.02472973e+02 4.71994820e+01 2.02472967e+02 4.71994829e+01 2.02472966e+02 4.71994777e+01 2.02472873e+02 4.71992270e+01 2.02472651e+02 4.71992804e+01 2.02472381e+02 4.71994113e+01 2.02472405e+02 4.71995729e+01 2.02472484e+02 4.71997750e+01 2.02472481e+02 4.71998418e+01 2.02472408e+02 4.72000263e+01 2.02472175e+02 4.72001804e+01 2.02471998e+02 4.72003684e+01 2.02471827e+02 4.72005610e+01 2.02471528e+02 4.72006731e+01 2.02471316e+02 4.72008401e+01 2.02471139e+02 4.72008334e+01 2.02471037e+02 4.72006655e+01 2.02470987e+02 4.72006205e+01 2.02470919e+02 4.72003452e+01 2.02470643e+02 4.72002235e+01 2.02470400e+02 4.72000778e+01 2.02470054e+02 4.72000083e+01 2.02469820e+02 4.71998559e+01 2.02469755e+02 4.71998646e+01 2.02469739e+02 4.71999156e+01 2.02469920e+02 4.72001073e+01 2.02469856e+02 4.72002271e+01 2.02469707e+02 4.72004331e+01 2.02469491e+02 4.72004241e+01 2.02469242e+02 4.72004416e+01 2.02469287e+02 4.72005750e+01 2.02469484e+02 4.72005927e+01 2.02469733e+02 4.72005705e+01 2.02470030e+02 4.72006348e+01 2.02470098e+02 4.72006265e+01 2.02470472e+02 4.72006751e+01 2.02470732e+02 4.72008089e+01 2.02470821e+02 4.72010679e+01 2.02470802e+02 4.72011170e+01 2.02470626e+02 4.72013064e+01 2.02470697e+02 4.72014850e+01 2.02470709e+02 4.72016578e+01 2.02470368e+02 4.72017435e+01 2.02470352e+02 4.72017400e+01 2.02470281e+02 4.72016891e+01 2.02470168e+02 4.72015507e+01 2.02469954e+02 4.72013834e+01 2.02469790e+02 4.72013824e+01 2.02469600e+02 4.72013197e+01 2.02469319e+02 4.72012018e+01 2.02469098e+02 4.72010400e+01 2.02468992e+02 4.72008837e+01 2.02469015e+02 4.72007757e+01 2.02468807e+02 4.72006039e+01 2.02468468e+02 4.72005291e+01 2.02468332e+02 4.72003046e+01 2.02468139e+02 4.72003508e+01 2.02467911e+02 4.72002898e+01 2.02467679e+02 4.72001360e+01 2.02467433e+02 4.71999925e+01 2.02467234e+02 4.71998139e+01 2.02466964e+02 4.71996886e+01 2.02466693e+02 4.71995634e+01 2.02466460e+02 4.71994097e+01 2.02466171e+02 4.71992979e+01 2.02465912e+02 4.71991642e+01 2.02465696e+02 4.71989985e+01 2.02465435e+02 4.71988663e+01 2.02465187e+02 4.71987241e+01 2.02464952e+02 4.71985720e+01 2.02464748e+02 4.71983977e+01 2.02464517e+02 4.71982430e+01 2.02464284e+02 4.71980900e+01 2.02464023e+02 4.71979574e+01 2.02463779e+02 4.71978124e+01 2.02463568e+02 4.71976424e+01 2.02463353e+02 4.71974764e+01 2.02463154e+02 4.71972977e+01 2.02462924e+02 4.71971426e+01 2.02462718e+02 4.71969698e+01 2.02462689e+02 4.71969439e+01 2.02462593e+02 4.71967367e+01 2.02462368e+02 4.71967435e+01 2.02462210e+02 4.71966938e+01 2.02462135e+02 4.71965975e+01 2.02462144e+02 4.71964174e+01 2.02461951e+02 4.71962350e+01 2.02461832e+02 4.71961089e+01 2.02461792e+02 4.71960271e+01 2.02461885e+02 4.71958429e+01 2.02462032e+02 4.71956357e+01 2.02462024e+02 4.71955308e+01 2.02461943e+02 4.71952805e+01 2.02461940e+02 4.71952674e+01 2.02461884e+02 4.71952436e+01 2.02461617e+02 4.71951809e+01 2.02461627e+02 4.71950830e+01 2.02461849e+02 4.71949225e+01 2.02461827e+02 4.71947003e+01 2.02461775e+02 4.71945770e+01 2.02462067e+02 4.71944607e+01 2.02462189e+02 4.71944327e+01 2.02462377e+02 4.71943550e+01 2.02462394e+02 4.71942816e+01 2.02462317e+02 4.71940181e+01 2.02462317e+02 4.71940133e+01 2.02462477e+02 4.71938192e+01 2.02462750e+02 4.71936904e+01 2.02462760e+02 4.71936858e+01 2.02462866e+02 4.71937631e+01 2.02462977e+02 4.71938511e+01 2.02463170e+02 4.71940338e+01 2.02463228e+02 4.71942888e+01 2.02463235e+02 4.71943105e+01 2.02463456e+02 4.71944727e+01 2.02463690e+02 4.71946251e+01 2.02463715e+02 4.71948925e+01 2.02463736e+02 4.71949164e+01 2.02463755e+02 4.71949172e+01 2.02463986e+02 4.71947626e+01 2.02463979e+02 4.71947372e+01 2.02463745e+02 4.71945844e+01 2.02463638e+02 4.71943384e+01 2.02463645e+02 4.71942497e+01 2.02463744e+02 4.71940128e+01 2.02463889e+02 4.71938274e+01 2.02463578e+02 4.71937324e+01 2.02463567e+02 4.71936027e+01 2.02463712e+02 4.71936331e+01 2.02463969e+02 4.71935549e+01 2.02464047e+02 4.71933857e+01 2.02464065e+02 4.71933153e+01 2.02464271e+02 4.71931450e+01 2.02464298e+02 4.71928753e+01 2.02464298e+02 4.71928630e+01 2.02464526e+02 4.71927062e+01 2.02464640e+02 4.71924779e+01 2.02464943e+02 4.71923989e+01 2.02464981e+02 4.71923922e+01 2.02465221e+02 4.71922427e+01 2.02465230e+02 4.71921868e+01 2.02465170e+02 4.71919114e+01 2.02465173e+02 4.71919039e+01 2.02465361e+02 4.71917318e+01 2.02465578e+02 4.71915683e+01 2.02465815e+02 4.71914171e+01 2.02465858e+02 4.71913978e+01 2.02466130e+02 4.71915219e+01 2.02466369e+02 4.71914644e+01 2.02466574e+02 4.71912930e+01 2.02466695e+02 4.71911041e+01 2.02466702e+02 4.71910740e+01 2.02466736e+02 4.71910741e+01 2.02467145e+02 4.71910976e+01 2.02467393e+02 4.71912392e+01 2.02467632e+02 4.71913878e+01 2.02467718e+02 4.71914097e+01 2.02467707e+02 4.71913331e+01 2.02467580e+02 4.71911016e+01 2.02467599e+02 4.71910365e+01 2.02467616e+02 4.71907497e+01 2.02467616e+02 4.71907475e+01 2.02467746e+02 4.71905294e+01 2.02467952e+02 4.71905009e+01 2.02468102e+02 4.71904530e+01 2.02468414e+02 4.71904852e+01 2.02468630e+02 4.71906509e+01 2.02468692e+02 4.71908221e+01 2.02468682e+02 4.71909381e+01 2.02468863e+02 4.71911297e+01 2.02469114e+02 4.71910859e+01 2.02469305e+02 4.71909060e+01 2.02469449e+02 4.71906969e+01 2.02469450e+02 4.71906956e+01 2.02469357e+02 4.71904389e+01 2.02469295e+02 4.71903011e+01 2.02469490e+02 4.71901240e+01 2.02469798e+02 4.71900171e+01 2.02469979e+02 4.71899795e+01 2.02470201e+02 4.71899696e+01 2.02470392e+02 4.71899997e+01 2.02470764e+02 4.71900505e+01 2.02470737e+02 4.71903047e+01 2.02470767e+02 4.71903734e+01 2.02470951e+02 4.71905628e+01 2.02471274e+02 4.71906404e+01 2.02471287e+02 4.71906398e+01 2.02471628e+02 4.71905626e+01 2.02471826e+02 4.71905669e+01 2.02472164e+02 4.71906425e+01 2.02472168e+02 4.71908999e+01 2.02471950e+02 4.71910631e+01 2.02471968e+02 4.71911123e+01 2.02472013e+02 4.71911023e+01 2.02472385e+02 4.71910358e+01 2.02472508e+02 4.71910390e+01 2.02472768e+02 4.71909756e+01 2.02473028e+02 4.71909797e+01 2.02473317e+02 4.71910921e+01 2.02473388e+02 4.71910643e+01 2.02473440e+02 4.71910008e+01 2.02473528e+02 4.71908527e+01 2.02473645e+02 4.71908494e+01 2.02473940e+02 4.71909568e+01 2.02474158e+02 4.71911211e+01 2.02474449e+02 4.71912313e+01 2.02474709e+02 4.71913643e+01 2.02474957e+02 4.71914465e+01 2.02475037e+02 4.71914478e+01 2.02475132e+02 4.71915559e+01 2.02475225e+02 4.71916340e+01 2.02475301e+02 4.71916613e+01 2.02475555e+02 4.71917156e+01 2.02475880e+02 4.71918004e+01 2.02476164e+02 4.71919161e+01 2.02476262e+02 4.71919628e+01 2.02476457e+02 4.71917857e+01 2.02476709e+02 4.71918389e+01 2.02476933e+02 4.71919984e+01 2.02476970e+02 4.71921062e+01 2.02459548e+02 4.71812143e+01 2.02459388e+02 4.71812149e+01 2.02459392e+02 4.71811168e+01 2.02459530e+02 4.71811100e+01 2.02459548e+02 4.71812143e+01 2.02468444e+02 4.71870760e+01 2.02468158e+02 4.71870961e+01 2.02468167e+02 4.71869030e+01 2.02468432e+02 4.71868940e+01 2.02468444e+02 4.71870760e+01 2.02482499e+02 4.71961596e+01 2.02482299e+02 4.71961671e+01 2.02482312e+02 4.71960427e+01 2.02482482e+02 4.71960316e+01 2.02482499e+02 4.71961596e+01 2.02470021e+02 4.71886606e+01 2.02470000e+02 4.71886631e+01 2.02470003e+02 4.71886488e+01 2.02470022e+02 4.71886470e+01 2.02470021e+02 4.71886606e+01 2.02481377e+02 4.71960568e+01 2.02481110e+02 4.71960692e+01 2.02481145e+02 4.71959121e+01 2.02481327e+02 4.71959092e+01 2.02481377e+02 4.71960568e+01 2.02480873e+02 4.71957419e+01 2.02480634e+02 4.71957702e+01 2.02480672e+02 4.71956166e+01 2.02480830e+02 4.71956259e+01 2.02480873e+02 4.71957419e+01 2.02479698e+02 4.71950077e+01 2.02479448e+02 4.71951505e+01 2.02479331e+02 4.71951063e+01 2.02479270e+02 4.71950395e+01 2.02479508e+02 4.71948890e+01 2.02479607e+02 4.71949031e+01 2.02479698e+02 4.71950077e+01 2.02471069e+02 4.71896149e+01 2.02470907e+02 4.71896193e+01 2.02470933e+02 4.71895296e+01 2.02471030e+02 4.71895287e+01 2.02471069e+02 4.71896149e+01 2.02493588e+02 4.72039841e+01 2.02493257e+02 4.72040123e+01 2.02493274e+02 4.72037881e+01 2.02493572e+02 4.72037795e+01 2.02493588e+02 4.72039841e+01 2.02484226e+02 4.71981361e+01 2.02483920e+02 4.71982224e+01 2.02484084e+02 4.71980477e+01 2.02484179e+02 4.71980315e+01 2.02484226e+02 4.71981361e+01 2.02481352e+02 4.71963405e+01 2.02481373e+02 4.71965260e+01 2.02481704e+02 4.71966067e+01 2.02481923e+02 4.71967698e+01 2.02482198e+02 4.71968924e+01 2.02482222e+02 4.71971834e+01 2.02482005e+02 4.71973468e+01 2.02481622e+02 4.71974070e+01 2.02481774e+02 4.71975308e+01 2.02481776e+02 4.71978024e+01 2.02481360e+02 4.71978371e+01 2.02481127e+02 4.71976837e+01 2.02480992e+02 4.71974577e+01 2.02480967e+02 4.71972969e+01 2.02481188e+02 4.71971356e+01 2.02481255e+02 4.71969382e+01 2.02481248e+02 4.71968740e+01 2.02481176e+02 4.71966717e+01 2.02481041e+02 4.71964457e+01 2.02481041e+02 4.71964454e+01 2.02481149e+02 4.71962136e+01 2.02481357e+02 4.71962126e+01 2.02481352e+02 4.71963405e+01 2.02480459e+02 4.71957826e+01 2.02480159e+02 4.71958942e+01 2.02480162e+02 4.71961190e+01 2.02480354e+02 4.71963031e+01 2.02480354e+02 4.71963153e+01 2.02480354e+02 4.71966146e+01 2.02480081e+02 4.71967427e+01 2.02479758e+02 4.71967434e+01 2.02479503e+02 4.71966064e+01 2.02479433e+02 4.71963382e+01 2.02479674e+02 4.71961892e+01 2.02479701e+02 4.71961349e+01 2.02479656e+02 4.71958791e+01 2.02479679e+02 4.71958255e+01 2.02479553e+02 4.71958145e+01 2.02479270e+02 4.71958024e+01 2.02479322e+02 4.71956702e+01 2.02479437e+02 4.71954432e+01 2.02479651e+02 4.71952775e+01 2.02479979e+02 4.71952781e+01 2.02480099e+02 4.71955152e+01 2.02480402e+02 4.71956167e+01 2.02480459e+02 4.71957826e+01 2.02478662e+02 4.71946598e+01 2.02478593e+02 4.71946761e+01 2.02478583e+02 4.71946100e+01 2.02478677e+02 4.71946137e+01 2.02478662e+02 4.71946598e+01 2.02484220e+02 4.71984313e+01 2.02484081e+02 4.71984289e+01 2.02483917e+02 4.71982422e+01 2.02484256e+02 4.71983001e+01 2.02484220e+02 4.71984313e+01 2.02484501e+02 4.71992056e+01 2.02484312e+02 4.71993867e+01 2.02484022e+02 4.71994488e+01 2.02484075e+02 4.71992382e+01 2.02484370e+02 4.71991235e+01 2.02484442e+02 4.71991381e+01 2.02484501e+02 4.71992056e+01 2.02478734e+02 4.71956021e+01 2.02478683e+02 4.71955853e+01 2.02478683e+02 4.71955702e+01 2.02478701e+02 4.71955719e+01 2.02478734e+02 4.71956021e+01 2.02483936e+02 4.71991515e+01 2.02483909e+02 4.71992066e+01 2.02483963e+02 4.71994679e+01 2.02483616e+02 4.71994230e+01 2.02483443e+02 4.71992256e+01 2.02483353e+02 4.71990863e+01 2.02483273e+02 4.71990260e+01 2.02483275e+02 4.71987388e+01 2.02483679e+02 4.71987263e+01 2.02483889e+02 4.71988963e+01 2.02483936e+02 4.71991515e+01 2.02477881e+02 4.71953683e+01 2.02477667e+02 4.71953600e+01 2.02477574e+02 4.71951767e+01 2.02477846e+02 4.71952277e+01 2.02477881e+02 4.71953683e+01 2.02479126e+02 4.71964457e+01 2.02478850e+02 4.71964377e+01 2.02478707e+02 4.71962181e+01 2.02478699e+02 4.71961787e+01 2.02478813e+02 4.71961402e+01 2.02479143e+02 4.71962218e+01 2.02479126e+02 4.71964457e+01 2.02477792e+02 4.71956121e+01 2.02477584e+02 4.71957813e+01 2.02477452e+02 4.71959978e+01 2.02477252e+02 4.71959920e+01 2.02476888e+02 4.71959354e+01 2.02476948e+02 4.71956828e+01 2.02477307e+02 4.71956261e+01 2.02477465e+02 4.71957069e+01 2.02477748e+02 4.71955840e+01 2.02477817e+02 4.71955746e+01 2.02477792e+02 4.71956121e+01 2.02470987e+02 4.71913585e+01 2.02470845e+02 4.71915689e+01 2.02470842e+02 4.71916191e+01 2.02470894e+02 4.71915996e+01 2.02471337e+02 4.71915784e+01 2.02471338e+02 4.71915784e+01 2.02471338e+02 4.71915777e+01 2.02471133e+02 4.71914044e+01 2.02470987e+02 4.71913585e+01 2.02468526e+02 4.71898202e+01 2.02468436e+02 4.71898182e+01 2.02468438e+02 4.71897655e+01 2.02468643e+02 4.71896655e+01 2.02468526e+02 4.71898202e+01 2.02484534e+02 4.72001237e+01 2.02484423e+02 4.72001288e+01 2.02484280e+02 4.71999649e+01 2.02484608e+02 4.71999921e+01 2.02484534e+02 4.72001237e+01 2.02498450e+02 4.72094133e+01 2.02498264e+02 4.72094233e+01 2.02498261e+02 4.72092957e+01 2.02498439e+02 4.72092942e+01 2.02498450e+02 4.72094133e+01 2.02467819e+02 4.71902758e+01 2.02467817e+02 4.71902756e+01 2.02467817e+02 4.71902750e+01 2.02467818e+02 4.71902749e+01 2.02467819e+02 4.71902758e+01 2.02475565e+02 4.71972123e+01 2.02475144e+02 4.71972243e+01 2.02475110e+02 4.71972269e+01 2.02474735e+02 4.71972920e+01 2.02474795e+02 4.71974818e+01 2.02474778e+02 4.71976180e+01 2.02474697e+02 4.71978666e+01 2.02474668e+02 4.71979010e+01 2.02474871e+02 4.71980765e+01 2.02475008e+02 4.71980611e+01 2.02475008e+02 4.71979752e+01 2.02475042e+02 4.71977830e+01 2.02475073e+02 4.71976019e+01 2.02475041e+02 4.71974831e+01 2.02475237e+02 4.71974810e+01 2.02475407e+02 4.71976803e+01 2.02475422e+02 4.71977213e+01 2.02475438e+02 4.71979827e+01 2.02475439e+02 4.71980308e+01 2.02475486e+02 4.71982726e+01 2.02475498e+02 4.71983668e+01 2.02475580e+02 4.71985286e+01 2.02475761e+02 4.71985316e+01 2.02475717e+02 4.71984272e+01 2.02475709e+02 4.71981994e+01 2.02476032e+02 4.71981949e+01 2.02476179e+02 4.71981940e+01 2.02476200e+02 4.71980708e+01 2.02475977e+02 4.71979099e+01 2.02475676e+02 4.71978071e+01 2.02475685e+02 4.71975862e+01 2.02476006e+02 4.71974878e+01 2.02475871e+02 4.71973375e+01 2.02475610e+02 4.71972054e+01 2.02475565e+02 4.71972123e+01 2.02484273e+02 4.72035503e+01 2.02484200e+02 4.72035471e+01 2.02484170e+02 4.72034863e+01 2.02484310e+02 4.72034654e+01 2.02484273e+02 4.72035503e+01 2.02476255e+02 4.71985409e+01 2.02476299e+02 4.71986484e+01 2.02476421e+02 4.71986449e+01 2.02476538e+02 4.71984719e+01 2.02476255e+02 4.71985409e+01 2.02477689e+02 4.71997362e+01 2.02477461e+02 4.71997414e+01 2.02477455e+02 4.71995897e+01 2.02477655e+02 4.71995979e+01 2.02477689e+02 4.71997362e+01 2.02478731e+02 4.72006862e+01 2.02478365e+02 4.72007004e+01 2.02478234e+02 4.72004721e+01 2.02478209e+02 4.72003602e+01 2.02478372e+02 4.72003697e+01 2.02478708e+02 4.72004471e+01 2.02478731e+02 4.72006862e+01 2.02474697e+02 4.71990635e+01 2.02474764e+02 4.71991318e+01 2.02474793e+02 4.71991231e+01 2.02474794e+02 4.71991090e+01 2.02474697e+02 4.71990635e+01 2.02473834e+02 4.71988229e+01 2.02473771e+02 4.71988895e+01 2.02473866e+02 4.71988433e+01 2.02473865e+02 4.71988194e+01 2.02473834e+02 4.71988229e+01 2.02474328e+02 4.71994310e+01 2.02474284e+02 4.71994862e+01 2.02474188e+02 4.71996426e+01 2.02474292e+02 4.71998053e+01 2.02474552e+02 4.71999389e+01 2.02474618e+02 4.71999113e+01 2.02474614e+02 4.71998928e+01 2.02474482e+02 4.71996652e+01 2.02474377e+02 4.71994618e+01 2.02474369e+02 4.71994232e+01 2.02474328e+02 4.71994310e+01 2.02464795e+02 4.71934729e+01 2.02464793e+02 4.71934852e+01 2.02464808e+02 4.71934807e+01 2.02464811e+02 4.71934721e+01 2.02464795e+02 4.71934729e+01 2.02477425e+02 4.72016656e+01 2.02477443e+02 4.72017066e+01 2.02477650e+02 4.72018795e+01 2.02477830e+02 4.72020716e+01 2.02477900e+02 4.72022618e+01 2.02477952e+02 4.72023065e+01 2.02477951e+02 4.72025926e+01 2.02477584e+02 4.72026626e+01 2.02477393e+02 4.72027199e+01 2.02477086e+02 4.72026210e+01 2.02476985e+02 4.72023709e+01 2.02476964e+02 4.72022748e+01 2.02476854e+02 4.72021421e+01 2.02476624e+02 4.72019863e+01 2.02476403e+02 4.72018244e+01 2.02476403e+02 4.72016253e+01 2.02476708e+02 4.72015168e+01 2.02476868e+02 4.72013176e+01 2.02477152e+02 4.72012712e+01 2.02477418e+02 4.72013999e+01 2.02477425e+02 4.72016656e+01 2.02476496e+02 4.72022815e+01 2.02476231e+02 4.72022771e+01 2.02476124e+02 4.72020491e+01 2.02476523e+02 4.72020615e+01 2.02476496e+02 4.72022815e+01 2.02477818e+02 4.72034068e+01 2.02477775e+02 4.72034138e+01 2.02477763e+02 4.72033727e+01 2.02477839e+02 4.72033665e+01 2.02477818e+02 4.72034068e+01 2.02474790e+02 4.72015150e+01 2.02474594e+02 4.72015342e+01 2.02474357e+02 4.72013837e+01 2.02474298e+02 4.72012073e+01 2.02474548e+02 4.72012428e+01 2.02474792e+02 4.72013882e+01 2.02474790e+02 4.72015150e+01 2.02474046e+02 4.72013491e+01 2.02473929e+02 4.72013750e+01 2.02473773e+02 4.72011787e+01 2.02474080e+02 4.72012636e+01 2.02474046e+02 4.72013491e+01 2.02473085e+02 4.72007489e+01 2.02472949e+02 4.72009632e+01 2.02472656e+02 4.72010139e+01 2.02472767e+02 4.72008494e+01 2.02472984e+02 4.72006857e+01 2.02473106e+02 4.72006818e+01 2.02473085e+02 4.72007489e+01 2.02473679e+02 4.72014189e+01 2.02473484e+02 4.72013783e+01 2.02473507e+02 4.72013115e+01 2.02473759e+02 4.72011750e+01 2.02473679e+02 4.72014189e+01 2.02475882e+02 4.72030951e+01 2.02475558e+02 4.72030991e+01 2.02475562e+02 4.72028949e+01 2.02475914e+02 4.72028366e+01 2.02475882e+02 4.72030951e+01 2.02483294e+02 4.72083239e+01 2.02482988e+02 4.72083469e+01 2.02482744e+02 4.72082012e+01 2.02482484e+02 4.72081176e+01 2.02482387e+02 4.72081400e+01 2.02482362e+02 4.72080411e+01 2.02482374e+02 4.72078238e+01 2.02482413e+02 4.72077737e+01 2.02482454e+02 4.72077648e+01 2.02482762e+02 4.72078632e+01 2.02483090e+02 4.72079457e+01 2.02483301e+02 4.72081156e+01 2.02483294e+02 4.72083239e+01 2.02471297e+02 4.72011274e+01 2.02471159e+02 4.72011436e+01 2.02471107e+02 4.72010090e+01 2.02471368e+02 4.72009894e+01 2.02471297e+02 4.72011274e+01 2.02475191e+02 4.72038602e+01 2.02474981e+02 4.72038513e+01 2.02474979e+02 4.72037276e+01 2.02475161e+02 4.72037179e+01 2.02475191e+02 4.72038602e+01 2.02468156e+02 4.71997626e+01 2.02468096e+02 4.71998283e+01 2.02468202e+02 4.71997916e+01 2.02468181e+02 4.71997656e+01 2.02468156e+02 4.71997626e+01 2.02461191e+02 4.71957084e+01 2.02461084e+02 4.71958997e+01 2.02461094e+02 4.71959469e+01 2.02461048e+02 4.71959259e+01 2.02460776e+02 4.71958019e+01 2.02460452e+02 4.71957158e+01 2.02460445e+02 4.71955412e+01 2.02460779e+02 4.71954507e+01 2.02460819e+02 4.71954450e+01 2.02461133e+02 4.71955380e+01 2.02461191e+02 4.71957084e+01 2.02483059e+02 4.72102715e+01 2.02483031e+02 4.72102671e+01 2.02483030e+02 4.72102534e+01 2.02483053e+02 4.72102510e+01 2.02483059e+02 4.72102715e+01 2.02471737e+02 4.72040955e+01 2.02471522e+02 4.72042599e+01 2.02471331e+02 4.72042695e+01 2.02471233e+02 4.72040795e+01 2.02471244e+02 4.72040090e+01 2.02471342e+02 4.72038487e+01 2.02471606e+02 4.72037412e+01 2.02471734e+02 4.72039720e+01 2.02471737e+02 4.72040955e+01 2.02475285e+02 4.72069109e+01 2.02475200e+02 4.72071571e+01 2.02474900e+02 4.72071639e+01 2.02474876e+02 4.72069546e+01 2.02475213e+02 4.72068659e+01 2.02475285e+02 4.72068793e+01 2.02475285e+02 4.72069109e+01 2.02480793e+02 4.72157369e+01 2.02480415e+02 4.72157778e+01 2.02480453e+02 4.72155250e+01 2.02480775e+02 4.72155120e+01 2.02480793e+02 4.72157369e+01 2.02471817e+02 4.72113266e+01 2.02471470e+02 4.72113241e+01 2.02471424e+02 4.72110811e+01 2.02471822e+02 4.72110638e+01 2.02471817e+02 4.72113266e+01 2.02467664e+02 4.72129204e+01 2.02467500e+02 4.72131172e+01 2.02467242e+02 4.72131447e+01 2.02466982e+02 4.72130927e+01 2.02466852e+02 4.72131078e+01 2.02466878e+02 4.72130282e+01 2.02467003e+02 4.72128068e+01 2.02467169e+02 4.72126112e+01 2.02467528e+02 4.72126083e+01 2.02467658e+02 4.72128375e+01 2.02467664e+02 4.72129204e+01 2.02466984e+02 4.72133935e+01 2.02466892e+02 4.72134032e+01 2.02466848e+02 4.72133082e+01 2.02467010e+02 4.72133164e+01 2.02466984e+02 4.72133935e+01 2.02481032e+02 4.71686156e+01 2.02480866e+02 4.71688110e+01 2.02480555e+02 4.71688258e+01 2.02480262e+02 4.71687166e+01 2.02480242e+02 4.71684209e+01 2.02480473e+02 4.71682661e+01 2.02480881e+02 4.71682590e+01 2.02481021e+02 4.71684808e+01 2.02481032e+02 4.71686156e+01 2.02493583e+02 4.71776571e+01 2.02493247e+02 4.71776628e+01 2.02493241e+02 4.71774435e+01 2.02493569e+02 4.71774248e+01 2.02493583e+02 4.71776571e+01 2.02495523e+02 4.71848516e+01 2.02495377e+02 4.71848739e+01 2.02495408e+02 4.71847803e+01 2.02495510e+02 4.71847757e+01 2.02495523e+02 4.71848516e+01 2.02497155e+02 4.71885638e+01 2.02496972e+02 4.71885760e+01 2.02496983e+02 4.71884559e+01 2.02497147e+02 4.71884465e+01 2.02497155e+02 4.71885638e+01 2.02504689e+02 4.71947647e+01 2.02504415e+02 4.71947880e+01 2.02504359e+02 4.71945589e+01 2.02504650e+02 4.71946145e+01 2.02504689e+02 4.71947647e+01 2.02503646e+02 4.71944123e+01 2.02503606e+02 4.71944101e+01 2.02503608e+02 4.71943888e+01 2.02503635e+02 4.71943884e+01 2.02503646e+02 4.71944123e+01 2.02472176e+02 4.71789366e+01 2.02471954e+02 4.71790973e+01 2.02471936e+02 4.71790998e+01 2.02471909e+02 4.71790690e+01 2.02472145e+02 4.71789171e+01 2.02472180e+02 4.71789200e+01 2.02472176e+02 4.71789366e+01 2.02475167e+02 4.71829010e+01 2.02475156e+02 4.71829014e+01 2.02475156e+02 4.71828939e+01 2.02475167e+02 4.71828935e+01 2.02475167e+02 4.71829010e+01 2.02496727e+02 4.71975693e+01 2.02496687e+02 4.71975728e+01 2.02496688e+02 4.71975451e+01 2.02496726e+02 4.71975440e+01 2.02496727e+02 4.71975693e+01 2.02460970e+02 4.71812062e+01 2.02460693e+02 4.71812263e+01 2.02460696e+02 4.71810346e+01 2.02460970e+02 4.71810221e+01 2.02460970e+02 4.71812062e+01 2.02474768e+02 4.71901318e+01 2.02474600e+02 4.71901442e+01 2.02474591e+02 4.71900212e+01 2.02474793e+02 4.71900011e+01 2.02474768e+02 4.71901318e+01 2.02460472e+02 4.71811936e+01 2.02460308e+02 4.71811862e+01 2.02460303e+02 4.71810884e+01 2.02460451e+02 4.71810804e+01 2.02460472e+02 4.71811936e+01 2.02473345e+02 4.71898403e+01 2.02473195e+02 4.71898808e+01 2.02473111e+02 4.71896945e+01 2.02473383e+02 4.71897417e+01 2.02473345e+02 4.71898403e+01 2.02468375e+02 4.71870328e+01 2.02468230e+02 4.71870431e+01 2.02468234e+02 4.71869451e+01 2.02468369e+02 4.71869405e+01 2.02468375e+02 4.71870328e+01 2.02482401e+02 4.71960984e+01 2.02482391e+02 4.71960987e+01 2.02482392e+02 4.71960927e+01 2.02482400e+02 4.71960922e+01 2.02482401e+02 4.71960984e+01 2.02476373e+02 4.71923317e+01 2.02476059e+02 4.71924345e+01 2.02475904e+02 4.71924338e+01 2.02475551e+02 4.71923687e+01 2.02475442e+02 4.71923483e+01 2.02475182e+02 4.71923164e+01 2.02474843e+02 4.71922729e+01 2.02474761e+02 4.71925210e+01 2.02474827e+02 4.71925783e+01 2.02474862e+02 4.71925839e+01 2.02475168e+02 4.71926523e+01 2.02475412e+02 4.71927967e+01 2.02475672e+02 4.71929303e+01 2.02475865e+02 4.71929113e+01 2.02476091e+02 4.71929457e+01 2.02476431e+02 4.71930204e+01 2.02476650e+02 4.71931834e+01 2.02476841e+02 4.71933677e+01 2.02477088e+02 4.71935109e+01 2.02477282e+02 4.71936928e+01 2.02477361e+02 4.71938463e+01 2.02477375e+02 4.71939491e+01 2.02477388e+02 4.71941628e+01 2.02477096e+02 4.71942795e+01 2.02477046e+02 4.71945174e+01 2.02477309e+02 4.71944122e+01 2.02477682e+02 4.71943729e+01 2.02477826e+02 4.71945918e+01 2.02477821e+02 4.71947325e+01 2.02477549e+02 4.71947967e+01 2.02477488e+02 4.71948232e+01 2.02477082e+02 4.71948161e+01 2.02477005e+02 4.71945483e+01 2.02476721e+02 4.71944325e+01 2.02476469e+02 4.71944860e+01 2.02476452e+02 4.71946314e+01 2.02476527e+02 4.71948212e+01 2.02476560e+02 4.71948767e+01 2.02476688e+02 4.71951076e+01 2.02476686e+02 4.71952196e+01 2.02476459e+02 4.71953771e+01 2.02476427e+02 4.71956259e+01 2.02476444e+02 4.71956668e+01 2.02476374e+02 4.71956648e+01 2.02475949e+02 4.71956567e+01 2.02476098e+02 4.71958686e+01 2.02476164e+02 4.71960903e+01 2.02475776e+02 4.71961474e+01 2.02475685e+02 4.71961736e+01 2.02475394e+02 4.71962079e+01 2.02475464e+02 4.71963373e+01 2.02475431e+02 4.71965299e+01 2.02475321e+02 4.71967603e+01 2.02475318e+02 4.71967701e+01 2.02475251e+02 4.71970156e+01 2.02474949e+02 4.71970432e+01 2.02474860e+02 4.71970710e+01 2.02474539e+02 4.71971696e+01 2.02474416e+02 4.71973918e+01 2.02474394e+02 4.71974529e+01 2.02474548e+02 4.71976647e+01 2.02474535e+02 4.71977655e+01 2.02474277e+02 4.71978647e+01 2.02474212e+02 4.71978627e+01 2.02474007e+02 4.71980337e+01 2.02473993e+02 4.71980745e+01 2.02473970e+02 4.71983098e+01 2.02473690e+02 4.71982986e+01 2.02473504e+02 4.71983177e+01 2.02473183e+02 4.71984161e+01 2.02473210e+02 4.71986528e+01 2.02473184e+02 4.71987162e+01 2.02473081e+02 4.71989510e+01 2.02472820e+02 4.71989412e+01 2.02472604e+02 4.71989520e+01 2.02472461e+02 4.71991622e+01 2.02472131e+02 4.71992548e+01 2.02472061e+02 4.71995020e+01 2.02472062e+02 4.71995109e+01 2.02471846e+02 4.71996753e+01 2.02471731e+02 4.71999029e+01 2.02471694e+02 4.72000980e+01 2.02471669e+02 4.72001630e+01 2.02471574e+02 4.72004030e+01 2.02471249e+02 4.72004265e+01 2.02471257e+02 4.72002049e+01 2.02471371e+02 4.72000110e+01 2.02471301e+02 4.71999331e+01 2.02471223e+02 4.71997956e+01 2.02471102e+02 4.71998086e+01 2.02470739e+02 4.71998277e+01 2.02470509e+02 4.71997372e+01 2.02470445e+02 4.71997198e+01 2.02470038e+02 4.71996950e+01 2.02469846e+02 4.71995116e+01 2.02469640e+02 4.71994936e+01 2.02469564e+02 4.71997200e+01 2.02469561e+02 4.71997432e+01 2.02469497e+02 4.72000022e+01 2.02469401e+02 4.72001656e+01 2.02469384e+02 4.72002314e+01 2.02469305e+02 4.72002365e+01 2.02469077e+02 4.72000791e+01 2.02468710e+02 4.72000250e+01 2.02468716e+02 4.71998136e+01 2.02468882e+02 4.71996182e+01 2.02468940e+02 4.71995300e+01 2.02468791e+02 4.71995611e+01 2.02468512e+02 4.71996861e+01 2.02468285e+02 4.71996888e+01 2.02467978e+02 4.71996516e+01 2.02467881e+02 4.71996615e+01 2.02467516e+02 4.71996061e+01 2.02467265e+02 4.71994659e+01 2.02467216e+02 4.71994745e+01 2.02466977e+02 4.71996243e+01 2.02466743e+02 4.71995264e+01 2.02466515e+02 4.71993698e+01 2.02466208e+02 4.71992711e+01 2.02465941e+02 4.71991428e+01 2.02465731e+02 4.71989724e+01 2.02465463e+02 4.71988456e+01 2.02465212e+02 4.71987053e+01 2.02464987e+02 4.71985466e+01 2.02464824e+02 4.71983413e+01 2.02464566e+02 4.71982064e+01 2.02464338e+02 4.71980495e+01 2.02464088e+02 4.71979092e+01 2.02463829e+02 4.71977751e+01 2.02463634e+02 4.71975942e+01 2.02463437e+02 4.71974145e+01 2.02463426e+02 4.71974047e+01 2.02463276e+02 4.71972079e+01 2.02463203e+02 4.71969658e+01 2.02463202e+02 4.71969371e+01 2.02463024e+02 4.71968541e+01 2.02462932e+02 4.71968111e+01 2.02462926e+02 4.71967931e+01 2.02462852e+02 4.71965449e+01 2.02462617e+02 4.71963933e+01 2.02462406e+02 4.71962242e+01 2.02462311e+02 4.71961091e+01 2.02462282e+02 4.71959902e+01 2.02462349e+02 4.71958335e+01 2.02462382e+02 4.71955911e+01 2.02462379e+02 4.71955531e+01 2.02462490e+02 4.71955114e+01 2.02462654e+02 4.71954260e+01 2.02462646e+02 4.71953962e+01 2.02462585e+02 4.71953825e+01 2.02462275e+02 4.71953449e+01 2.02462245e+02 4.71951703e+01 2.02462294e+02 4.71950059e+01 2.02462110e+02 4.71948164e+01 2.02462107e+02 4.71947848e+01 2.02462152e+02 4.71945135e+01 2.02462500e+02 4.71944321e+01 2.02462563e+02 4.71941717e+01 2.02462953e+02 4.71941936e+01 2.02462995e+02 4.71944420e+01 2.02462712e+02 4.71945645e+01 2.02462710e+02 4.71946985e+01 2.02462956e+02 4.71947171e+01 2.02463143e+02 4.71945346e+01 2.02463304e+02 4.71945849e+01 2.02463339e+02 4.71946569e+01 2.02463435e+02 4.71948138e+01 2.02463600e+02 4.71950167e+01 2.02463937e+02 4.71950309e+01 2.02464191e+02 4.71948905e+01 2.02464115e+02 4.71946364e+01 2.02464012e+02 4.71944792e+01 2.02463991e+02 4.71944028e+01 2.02463991e+02 4.71941669e+01 2.02464048e+02 4.71940352e+01 2.02464102e+02 4.71939372e+01 2.02464197e+02 4.71936973e+01 2.02464452e+02 4.71937373e+01 2.02464664e+02 4.71939060e+01 2.02464691e+02 4.71940059e+01 2.02464784e+02 4.71941424e+01 2.02464881e+02 4.71941249e+01 2.02465116e+02 4.71939724e+01 2.02465089e+02 4.71939173e+01 2.02465056e+02 4.71936355e+01 2.02465187e+02 4.71935196e+01 2.02465235e+02 4.71934485e+01 2.02465285e+02 4.71934473e+01 2.02465654e+02 4.71934997e+01 2.02465861e+02 4.71935403e+01 2.02466094e+02 4.71934998e+01 2.02466284e+02 4.71935058e+01 2.02466269e+02 4.71933712e+01 2.02466274e+02 4.71932001e+01 2.02466232e+02 4.71930728e+01 2.02466285e+02 4.71929081e+01 2.02466559e+02 4.71928313e+01 2.02466621e+02 4.71928186e+01 2.02466634e+02 4.71927759e+01 2.02466662e+02 4.71925449e+01 2.02466634e+02 4.71924506e+01 2.02466640e+02 4.71922323e+01 2.02466848e+02 4.71920628e+01 2.02466930e+02 4.71919069e+01 2.02466606e+02 4.71918206e+01 2.02466544e+02 4.71915738e+01 2.02466750e+02 4.71914034e+01 2.02466983e+02 4.71912496e+01 2.02467315e+02 4.71912973e+01 2.02467524e+02 4.71914683e+01 2.02467589e+02 4.71916285e+01 2.02467416e+02 4.71918195e+01 2.02467409e+02 4.71918781e+01 2.02467502e+02 4.71918736e+01 2.02467784e+02 4.71917505e+01 2.02468063e+02 4.71916253e+01 2.02468171e+02 4.71916405e+01 2.02468484e+02 4.71915897e+01 2.02468721e+02 4.71915597e+01 2.02468789e+02 4.71917803e+01 2.02468793e+02 4.71918318e+01 2.02468858e+02 4.71918230e+01 2.02469226e+02 4.71918369e+01 2.02469455e+02 4.71919933e+01 2.02469559e+02 4.71919622e+01 2.02469851e+02 4.71918454e+01 2.02470075e+02 4.71918607e+01 2.02470325e+02 4.71920013e+01 2.02470532e+02 4.71919718e+01 2.02470740e+02 4.71918029e+01 2.02471062e+02 4.71917047e+01 2.02471174e+02 4.71916994e+01 2.02471493e+02 4.71916753e+01 2.02471488e+02 4.71914672e+01 2.02471394e+02 4.71913139e+01 2.02471710e+02 4.71912123e+01 2.02471822e+02 4.71912206e+01 2.02472102e+02 4.71911578e+01 2.02472376e+02 4.71911365e+01 2.02472512e+02 4.71911153e+01 2.02472897e+02 4.71910771e+01 2.02473020e+02 4.71913110e+01 2.02473224e+02 4.71912611e+01 2.02473604e+02 4.71912049e+01 2.02473630e+02 4.71912155e+01 2.02473925e+02 4.71912928e+01 2.02474220e+02 4.71912853e+01 2.02474338e+02 4.71913131e+01 2.02474631e+02 4.71914224e+01 2.02474909e+02 4.71915423e+01 2.02475109e+02 4.71917200e+01 2.02475421e+02 4.71918142e+01 2.02475716e+02 4.71919208e+01 2.02475717e+02 4.71919210e+01 2.02476062e+02 4.71919918e+01 2.02476276e+02 4.71921585e+01 2.02476373e+02 4.71923317e+01 2.02493550e+02 4.72039603e+01 2.02493299e+02 4.72039818e+01 2.02493311e+02 4.72038114e+01 2.02493538e+02 4.72038049e+01 2.02493550e+02 4.72039603e+01 2.02473836e+02 4.71916436e+01 2.02473824e+02 4.71916931e+01 2.02473873e+02 4.71916668e+01 2.02473883e+02 4.71916493e+01 2.02473836e+02 4.71916436e+01 2.02482206e+02 4.71971734e+01 2.02481950e+02 4.71973122e+01 2.02481600e+02 4.71973338e+01 2.02481427e+02 4.71971365e+01 2.02481447e+02 4.71969981e+01 2.02481570e+02 4.71967759e+01 2.02481867e+02 4.71968114e+01 2.02482183e+02 4.71969030e+01 2.02482206e+02 4.71971734e+01 2.02479671e+02 4.71955892e+01 2.02479559e+02 4.71955885e+01 2.02479576e+02 4.71955297e+01 2.02479676e+02 4.71955027e+01 2.02479671e+02 4.71955892e+01 2.02478269e+02 4.71947130e+01 2.02478039e+02 4.71947600e+01 2.02478014e+02 4.71945537e+01 2.02478263e+02 4.71945944e+01 2.02478269e+02 4.71947130e+01 2.02476398e+02 4.71935437e+01 2.02476114e+02 4.71935795e+01 2.02475875e+02 4.71935161e+01 2.02475774e+02 4.71935055e+01 2.02475385e+02 4.71934674e+01 2.02475202e+02 4.71933948e+01 2.02475322e+02 4.71935139e+01 2.02475325e+02 4.71937706e+01 2.02474952e+02 4.71937879e+01 2.02474883e+02 4.71937936e+01 2.02474884e+02 4.71938379e+01 2.02474944e+02 4.71938319e+01 2.02475341e+02 4.71938258e+01 2.02475581e+02 4.71939737e+01 2.02475666e+02 4.71939840e+01 2.02475767e+02 4.71938362e+01 2.02475805e+02 4.71937717e+01 2.02475869e+02 4.71937603e+01 2.02476230e+02 4.71937379e+01 2.02476319e+02 4.71937535e+01 2.02476319e+02 4.71937936e+01 2.02476246e+02 4.71940475e+01 2.02476300e+02 4.71940926e+01 2.02476469e+02 4.71941869e+01 2.02476765e+02 4.71940725e+01 2.02476903e+02 4.71938593e+01 2.02476881e+02 4.71936638e+01 2.02476649e+02 4.71935100e+01 2.02476398e+02 4.71935437e+01 2.02472055e+02 4.71908294e+01 2.02471808e+02 4.71909055e+01 2.02471818e+02 4.71906815e+01 2.02472053e+02 4.71907242e+01 2.02472055e+02 4.71908294e+01 2.02471650e+02 4.71908756e+01 2.02471457e+02 4.71908397e+01 2.02471470e+02 4.71907631e+01 2.02471611e+02 4.71907256e+01 2.02471650e+02 4.71908756e+01 2.02480294e+02 4.71965768e+01 2.02480000e+02 4.71966923e+01 2.02479826e+02 4.71966927e+01 2.02479554e+02 4.71965688e+01 2.02479506e+02 4.71963834e+01 2.02479799e+02 4.71962677e+01 2.02479984e+02 4.71962510e+01 2.02480288e+02 4.71963517e+01 2.02480294e+02 4.71965768e+01 2.02472704e+02 4.71918333e+01 2.02472713e+02 4.71918636e+01 2.02472773e+02 4.71918765e+01 2.02472739e+02 4.71918443e+01 2.02472704e+02 4.71918333e+01 2.02470964e+02 4.71907459e+01 2.02471031e+02 4.71908289e+01 2.02470960e+02 4.71910428e+01 2.02470697e+02 4.71911776e+01 2.02470516e+02 4.71913634e+01 2.02470290e+02 4.71915212e+01 2.02470062e+02 4.71915445e+01 2.02470054e+02 4.71913742e+01 2.02470113e+02 4.71911819e+01 2.02469797e+02 4.71912133e+01 2.02469649e+02 4.71914198e+01 2.02469577e+02 4.71915777e+01 2.02469588e+02 4.71916812e+01 2.02469416e+02 4.71916969e+01 2.02469178e+02 4.71915469e+01 2.02469204e+02 4.71914410e+01 2.02469346e+02 4.71912308e+01 2.02469605e+02 4.71910934e+01 2.02469591e+02 4.71909168e+01 2.02469628e+02 4.71908084e+01 2.02469729e+02 4.71905721e+01 2.02469995e+02 4.71904394e+01 2.02470337e+02 4.71903541e+01 2.02470359e+02 4.71903497e+01 2.02470626e+02 4.71904773e+01 2.02470836e+02 4.71906473e+01 2.02470964e+02 4.71907459e+01 2.02483869e+02 4.71991098e+01 2.02483538e+02 4.71991554e+01 2.02483296e+02 4.71990092e+01 2.02483298e+02 4.71987529e+01 2.02483658e+02 4.71987418e+01 2.02483837e+02 4.71989347e+01 2.02483869e+02 4.71991098e+01 2.02481740e+02 4.71977796e+01 2.02481399e+02 4.71978080e+01 2.02481231e+02 4.71976068e+01 2.02481180e+02 4.71974300e+01 2.02481462e+02 4.71974360e+01 2.02481738e+02 4.71975575e+01 2.02481740e+02 4.71977796e+01 2.02477292e+02 4.71949999e+01 2.02477271e+02 4.71950022e+01 2.02477253e+02 4.71949755e+01 2.02477355e+02 4.71949403e+01 2.02477292e+02 4.71949999e+01 2.02483785e+02 4.71993567e+01 2.02483718e+02 4.71993480e+01 2.02483654e+02 4.71992746e+01 2.02483775e+02 4.71993060e+01 2.02483785e+02 4.71993567e+01 2.02475648e+02 4.71945709e+01 2.02475647e+02 4.71945750e+01 2.02475631e+02 4.71948598e+01 2.02475505e+02 4.71950053e+01 2.02475801e+02 4.71951122e+01 2.02475981e+02 4.71953041e+01 2.02476209e+02 4.71952207e+01 2.02476173e+02 4.71951628e+01 2.02476101e+02 4.71948908e+01 2.02476095e+02 4.71948505e+01 2.02475930e+02 4.71946917e+01 2.02475654e+02 4.71945702e+01 2.02475648e+02 4.71945709e+01 2.02498378e+02 4.72093689e+01 2.02498335e+02 4.72093712e+01 2.02498334e+02 4.72093412e+01 2.02498376e+02 4.72093409e+01 2.02498378e+02 4.72093689e+01 2.02468165e+02 4.71907915e+01 2.02467991e+02 4.71907976e+01 2.02468027e+02 4.71907051e+01 2.02468168e+02 4.71906672e+01 2.02468165e+02 4.71907915e+01 2.02468421e+02 4.71912509e+01 2.02468233e+02 4.71912692e+01 2.02468093e+02 4.71910478e+01 2.02468093e+02 4.71910457e+01 2.02468096e+02 4.71910456e+01 2.02468422e+02 4.71911297e+01 2.02468421e+02 4.71912509e+01 2.02476742e+02 4.71973492e+01 2.02476736e+02 4.71973496e+01 2.02476733e+02 4.71973435e+01 2.02476743e+02 4.71973441e+01 2.02476742e+02 4.71973492e+01 2.02476078e+02 4.71972333e+01 2.02476021e+02 4.71972270e+01 2.02475991e+02 4.71971790e+01 2.02476080e+02 4.71971832e+01 2.02476078e+02 4.71972333e+01 2.02466117e+02 4.71925038e+01 2.02466119e+02 4.71925058e+01 2.02465992e+02 4.71927249e+01 2.02465724e+02 4.71927978e+01 2.02465465e+02 4.71926639e+01 2.02465465e+02 4.71923955e+01 2.02465666e+02 4.71922218e+01 2.02465967e+02 4.71922930e+01 2.02466117e+02 4.71925038e+01 2.02478679e+02 4.72006536e+01 2.02478414e+02 4.72006639e+01 2.02478334e+02 4.72004384e+01 2.02478662e+02 4.72004809e+01 2.02478679e+02 4.72006536e+01 2.02476245e+02 4.71991330e+01 2.02476023e+02 4.71992934e+01 2.02475869e+02 4.71994962e+01 2.02475910e+02 4.71995859e+01 2.02475872e+02 4.71997972e+01 2.02475633e+02 4.71999473e+01 2.02475332e+02 4.72000130e+01 2.02475162e+02 4.71998135e+01 2.02475092e+02 4.71996096e+01 2.02475332e+02 4.71994604e+01 2.02475498e+02 4.71992645e+01 2.02475705e+02 4.71990950e+01 2.02476014e+02 4.71989889e+01 2.02476234e+02 4.71990217e+01 2.02476245e+02 4.71991330e+01 2.02475462e+02 4.71992420e+01 2.02475061e+02 4.71992374e+01 2.02475168e+02 4.71990583e+01 2.02475322e+02 4.71990443e+01 2.02475462e+02 4.71992420e+01 2.02466002e+02 4.71933297e+01 2.02465910e+02 4.71933110e+01 2.02465726e+02 4.71931570e+01 2.02465986e+02 4.71932545e+01 2.02466002e+02 4.71933297e+01 2.02465694e+02 4.71931371e+01 2.02465333e+02 4.71930865e+01 2.02465124e+02 4.71930797e+01 2.02464953e+02 4.71930418e+01 2.02464871e+02 4.71929218e+01 2.02464831e+02 4.71928070e+01 2.02464871e+02 4.71926224e+01 2.02465124e+02 4.71925905e+01 2.02465428e+02 4.71926912e+01 2.02465626e+02 4.71928702e+01 2.02465694e+02 4.71931371e+01 2.02465867e+02 4.71938434e+01 2.02465922e+02 4.71939524e+01 2.02466193e+02 4.71940775e+01 2.02466226e+02 4.71940681e+01 2.02466295e+02 4.71940021e+01 2.02466163e+02 4.71937744e+01 2.02465867e+02 4.71938434e+01 2.02464418e+02 4.71935361e+01 2.02464212e+02 4.71935893e+01 2.02464287e+02 4.71934540e+01 2.02464427e+02 4.71934305e+01 2.02464418e+02 4.71935361e+01 2.02477227e+02 4.72018413e+01 2.02477187e+02 4.72018958e+01 2.02477443e+02 4.72020320e+01 2.02477719e+02 4.72021539e+01 2.02477915e+02 4.72023339e+01 2.02477914e+02 4.72025695e+01 2.02477553e+02 4.72026016e+01 2.02477285e+02 4.72024744e+01 2.02477101e+02 4.72022846e+01 2.02476973e+02 4.72020540e+01 2.02476762e+02 4.72018848e+01 2.02476495e+02 4.72017564e+01 2.02476495e+02 4.72016828e+01 2.02476644e+02 4.72016468e+01 2.02476836e+02 4.72015967e+01 2.02477179e+02 4.72015765e+01 2.02477227e+02 4.72018413e+01 2.02471274e+02 4.71981209e+01 2.02471265e+02 4.71981382e+01 2.02471289e+02 4.71981304e+01 2.02471373e+02 4.71980581e+01 2.02471274e+02 4.71981209e+01 2.02476401e+02 4.72022227e+01 2.02476307e+02 4.72022211e+01 2.02476268e+02 4.72021395e+01 2.02476411e+02 4.72021439e+01 2.02476401e+02 4.72022227e+01 2.02470378e+02 4.71990571e+01 2.02470337e+02 4.71991488e+01 2.02470353e+02 4.71993405e+01 2.02470410e+02 4.71994201e+01 2.02470661e+02 4.71995330e+01 2.02470524e+02 4.71993360e+01 2.02470516e+02 4.71991434e+01 2.02470464e+02 4.71990551e+01 2.02470378e+02 4.71990571e+01 2.02475794e+02 4.72030401e+01 2.02475636e+02 4.72030420e+01 2.02475637e+02 4.72029421e+01 2.02475810e+02 4.72029135e+01 2.02475794e+02 4.72030401e+01 2.02470946e+02 4.72000105e+01 2.02470935e+02 4.72000081e+01 2.02470891e+02 4.71999760e+01 2.02470971e+02 4.71999814e+01 2.02470946e+02 4.72000105e+01 2.02483235e+02 4.72082870e+01 2.02483050e+02 4.72083008e+01 2.02482791e+02 4.72081668e+01 2.02482712e+02 4.72079605e+01 2.02483037e+02 4.72079848e+01 2.02483239e+02 4.72081613e+01 2.02483235e+02 4.72082870e+01 2.02464053e+02 4.71963004e+01 2.02464051e+02 4.71963105e+01 2.02464073e+02 4.71963127e+01 2.02464074e+02 4.71962933e+01 2.02464053e+02 4.71963004e+01 2.02463738e+02 4.71967020e+01 2.02463813e+02 4.71968113e+01 2.02463912e+02 4.71968110e+01 2.02463916e+02 4.71967353e+01 2.02463738e+02 4.71967020e+01 2.02470001e+02 4.72009160e+01 2.02469924e+02 4.72010800e+01 2.02469964e+02 4.72011918e+01 2.02469787e+02 4.72011812e+01 2.02469569e+02 4.72012441e+01 2.02469366e+02 4.72011669e+01 2.02469151e+02 4.72010007e+01 2.02469130e+02 4.72009701e+01 2.02469220e+02 4.72009499e+01 2.02469555e+02 4.72009365e+01 2.02469706e+02 4.72007313e+01 2.02469942e+02 4.72007414e+01 2.02470001e+02 4.72009160e+01 2.02468237e+02 4.72001127e+01 2.02467978e+02 4.72002406e+01 2.02468152e+02 4.72000592e+01 2.02468254e+02 4.72000368e+01 2.02468237e+02 4.72001127e+01 2.02460712e+02 4.71957080e+01 2.02460525e+02 4.71956620e+01 2.02460522e+02 4.71955891e+01 2.02460675e+02 4.71955513e+01 2.02460712e+02 4.71957080e+01 2.02475143e+02 4.72071213e+01 2.02474952e+02 4.72071255e+01 2.02474937e+02 4.72069924e+01 2.02475194e+02 4.72069468e+01 2.02475143e+02 4.72071213e+01 2.02480758e+02 4.72157153e+01 2.02480456e+02 4.72157481e+01 2.02480486e+02 4.72155454e+01 2.02480744e+02 4.72155350e+01 2.02480758e+02 4.72157153e+01 2.02471770e+02 4.72112968e+01 2.02471509e+02 4.72112949e+01 2.02471475e+02 4.72111129e+01 2.02471773e+02 4.72110999e+01 2.02471770e+02 4.72112968e+01 2.02467546e+02 4.72128469e+01 2.02467167e+02 4.72128748e+01 2.02467249e+02 4.72126610e+01 2.02467459e+02 4.72126593e+01 2.02467546e+02 4.72128469e+01 2.02467425e+02 4.72130703e+01 2.02467329e+02 4.72130805e+01 2.02467198e+02 4.72129289e+01 2.02467510e+02 4.72129471e+01 2.02467425e+02 4.72130703e+01 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/ds9.tag��������������������������������������������������������������������������0000644�0001750�0001750�00000000076�12131336426�014242� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������10.8811 14.1631 red 29.2606 32.5427 green 48.953 52.2351 blue ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/aux/source.tcl�����������������������������������������������������������������������0000644�0001750�0001750�00000000027�12131336426�015046� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set foo "Hello, World" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/hcompress.sh�������������������������������������������������������������������������0000755�0001750�0001750�00000000052�12107264737�014615� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������partial.sh HCOMPRESS hcompress fits $1 $2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/nrrd.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000044�12113456764�013560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������full.sh NRRD nrrd nrrd export $1 $2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/plot.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000022445�12115164572�013575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9 -tcl& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi echo echo "*** plot.sh ***" delay=.5 echo -n "stdin 2|3|4|5..." cat plot/stdin.2.dat | xpaset ds9 plot new stdin cat plot/stdin.3.dat | xpaset ds9 plot new stdin cat plot/stdin.4.dat | xpaset ds9 plot new stdin cat plot/stdin.5.dat | xpaset ds9 plot new stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.2.dat | xpaset ds9 plot new bar stdin cat plot/stdin.3.dat | xpaset ds9 plot new bar stdin cat plot/stdin.4.dat | xpaset ds9 plot new bar stdin cat plot/stdin.5.dat | xpaset ds9 plot new bar stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.2.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.3.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.4.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.5.dat | xpaset ds9 plot new scatter stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "named stdin 2|3|4|5..." cat plot/stdin.2.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.3.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.4.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.5.dat | xpaset ds9 plot new name foo stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.2.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.3.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.4.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.5.dat | xpaset ds9 plot new name foo bar stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.2.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.3.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.4.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.5.dat | xpaset ds9 plot new name foo scatter stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "stdin xy|xyex|xyey|xyexey..." cat plot/stdin.xy.dat | xpaset ds9 plot new stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.xy.dat | xpaset ds9 plot new bar stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new bar stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new bar stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new bar stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.xy.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new scatter stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new scatter stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "named stdin xy|xyex|xyey|xyexey..." cat plot/stdin.xy.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new name foo stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.xy.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new name foo bar stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new name foo bar stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/stdin.xy.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.xyex.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.xyey.dat | xpaset ds9 plot new name foo scatter stdin cat plot/stdin.xyexey.dat | xpaset ds9 plot new name foo scatter stdin sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "stdin text|error..." cat plot/stdin.error.dat | xpaset ds9 plot new stdin cat plot/stdin.text.dat | xpaset ds9 plot new stdin sleep "$delay" xpaset -p ds9 plot close echo "PASSED" echo -n "named stdin text|error..." cat plot/stdin.error.dat | xpaset ds9 plot new name foo stdin cat plot/stdin.text.dat | xpaset ds9 plot new name foo stdin sleep "$delay" xpaset -p ds9 plot close echo "PASSED" echo -n "4|5..." cat plot/4.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/4.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/4.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "named 4|5..." cat plot/4.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/4.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/4.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" 4 cat plot/5.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" 5 sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "xy|xyex|xyey|xyexey..." cat plot/xy.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/xy.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new bar "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/xy.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new scatter "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" echo -n "name xy|xyex|xyey|xyexey..." cat plot/xy.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new name foo "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/xy.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new name foo bar "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close cat plot/xy.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" xy cat plot/xyex.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" xyex cat plot/xyey.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" xyey cat plot/xyexey.dat | xpaset ds9 plot new name foo scatter "{The Title}" "{X Axis}" "{Y Axis}" xyexey sleep "$delay" xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close xpaset -p ds9 plot close echo "PASSED" xpaset -p ds9 quit echo "DONE" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/mosaicimage.sh�����������������������������������������������������������������������0000755�0001750�0001750�00000013724�12131345761�015074� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** Mosaic Image ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" echo " -mosaicimage" ds9 -mosaicimage mosaic/mosaicimage.fits & KillIt echo " -mosaicimage wcs" ds9 -mosaicimage wcs mosaic/mosaicimage.fits & KillIt echo " -mosaicimagewcs" ds9 -mosaicimagewcs mosaic/mosaicimage.fits & KillIt echo " -mosaicimage iraf" ds9 -mosaicimage iraf mosaic/mosaicimage.fits & KillIt echo " -mosaicimageiraf" ds9 -mosaicimageiraf mosaic/mosaicimage.fits & KillIt echo " -mosaicimage wfpc2" ds9 -mosaicimage wfpc2 mosaic/hst.fits & KillIt echo " -mosaicimagewfpc2" ds9 -mosaicimagewfpc2 mosaic/hst.fits & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" echo " -mosaicimage" cat mosaic/mosaicimage.fits | ds9 -mosaicimage -& KillIt echo " -mosaicimage wcs" cat mosaic/mosaicimage.fits | ds9 -mosaicimage wcs -& KillIt echo " -mosaicimagewcs" cat mosaic/mosaicimage.fits | ds9 -mosaicimagewcs -& KillIt echo " -mosaicimage iraf" cat mosaic/mosaicimage.fits | ds9 -mosaicimage iraf -& KillIt echo " -mosaicimageiraf" cat mosaic/mosaicimage.fits | ds9 -mosaicimageiraf -& KillIt echo " -mosaicimage wfpc2" cat mosaic/hst.fits | ds9 -mosaicimage wfpc2 -& KillIt echo " -mosaicimagewfpc2" cat mosaic/hst.fits | ds9 -mosaicimagewfpc2 -& KillIt echo "PASSED" fi # Save if [ "$1" = "save" -o -z "$1" ]; then echo "Testing Command Save" echo " -mosaicimage" opt="" opt="$opt -save mosaicimage foo.fits -sleep .1" opt="$opt -frame new -mosaicimage foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaicimage mosaic/mosaicimage.fits "$opt" -exit echo " -mosaicimage wcs" opt="" opt="$opt -save mosaicimage wcs foo.fits -sleep .1" opt="$opt -frame new -mosaicimage wcs foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaicimage wcs mosaic/mosaicimage.fits "$opt" -exit echo " -mosaicimagewcs" opt="" opt="$opt -save mosaicimagewcs foo.fits -sleep .1" opt="$opt -frame new -mosaicimagewcs foo.fits" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" eval ds9 -tile -mosaicimagewcs mosaic/mosaicimage.fits "$opt" -exit echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 echo " -mosaicimage" xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage wcs" xpaset -p ds9 mosaicimage wcs mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimagewcs" xpaset -p ds9 mosaicimagewcs mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage iraf" xpaset -p ds9 mosaicimage iraf mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimageiraf" xpaset -p ds9 mosaicimageiraf mosaic/mosaicimage.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage wfpc2" xpaset -p ds9 mosaicimage wfpc2 mosaic/hst.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimagewfpc2" xpaset -p ds9 mosaicimagewfpc2 mosaic/hst.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 echo " -mosaicimage" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimage if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage wcs" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimage wcs if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimagewcs" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimagewcs if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage iraf" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimage iraf if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimageiraf" cat mosaic/mosaicimage.fits | xpaset ds9 mosaicimageiraf if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimage wfpc2" cat mosaic/hst.fits | xpaset ds9 mosaicimage wfpc2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear echo " -mosaicimagewfpc2" cat mosaic/hst.fits | xpaset ds9 mosaicimagewfpc2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 echo " -mosaicimage" xpaset -p ds9 tile xpaset -p ds9 mosaicimage mosaic/mosaicimage.fits xpaget ds9 mosaicimage > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaicimage foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear echo " -mosaicimage wcs" xpaset -p ds9 tile xpaset -p ds9 mosaicimage wcs mosaic/mosaicimage.fits xpaget ds9 mosaicimage wcs > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaicimage wcs foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear echo " -mosaicimagewcs" xpaset -p ds9 tile xpaset -p ds9 mosaicimagewcs mosaic/mosaicimage.fits xpaget ds9 mosaicimagewcs > foo.fits xpaset -p ds9 frame new xpaset -p ds9 mosaicimagewcs foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" ��������������������������������������������./saods9/tests/full.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000004375�12131617434�013561� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9 & i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # which/where/what which=$1 shift where=$1 shift what=$1 shift save=$1 shift # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** $which ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command Line File" for f in $where/* do echo " ${f#$where/}" opt="-$what $f -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi ds9 $opt -exit done echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Stdin File" for f in $where/* do echo " ${f#$where/}" opt="-$what - -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi cat $f | ds9 $opt -exit done echo "PASSED" fi # Save if [ "$1" = "$save" -o -z "$1" ]; then echo "Testing Command $save" for f in $where/* do echo " ${f#$where/}" opt="-tile -$what $f" opt="$opt -$save $what foo.fits" opt="$opt -frame new -$what foo.fits -sleep .1" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete" ds9 $opt -exit done echo "PASSED" fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 $what $f if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi # XPA stdin if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 for f in $where/* do echo " ${f#$where/}" cat $f | xpaset ds9 $what if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 for f in $where/* do echo " ${f#$where/}" xpaset -p ds9 tile xpaset -p ds9 $what $f xpaget ds9 $what > foo.fits xpaset -p ds9 frame new xpaset -p ds9 $what foo.fits if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear done xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014055� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/hv.html���������������������������������������������������������������������0000644�0001750�0001750�00000001472�12107534544�015404� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Testing Image Formats</title> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> </head> <body> <table cellpadding="2" cellspacing="2" width="100%"> <tbody> <tr> <td valign="top">jpg<br> <img src="../photo/rose.jpeg" alt="jpeg" height="149" width="227"> <br> </td> <td valign="top">gif<br> <img src="../photo/rose.gif" alt="gif" height="149" width="227"> <br> </td> </tr> <tr> <td valign="top">tiff<br> <img src="../photo/rose.tiff" alt="tiff" height="149" width="227"> <br> </td> <td valign="top">png<br> <img src="../photo/rose.png" alt="png" height="149" width="227"> <br> </td> </tr> </tbody> </table> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/analysis.txt����������������������������������������������������������������0000644�0001750�0001750�00000000015�11243053526�016451� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is text �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/font.html�������������������������������������������������������������������0000644�0001750�0001750�00000001627�12131337530�015730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> </head> <body> <font size=-2>font size=-2</font> <br><font size=-1>font size=-1</font> <br>font size=0 <br><font size=+1>font size=1</font> <br><font size=+2>font size=2</font> <br><font size=+3>font size=3</font> <br><font size=+4>font size=4</font> <p>font variable <br><tt>font fixed</tt> <br><font face="Arial,Helvetica">font helvetica</font> <br><font face="Times New Roman,Times">font times</font> <br><font face="Courier New,Courier">font courier</font> <p>font plain <br><i>font italic</i> <br><b>font bold</b> <br><b><i>font bold italic</i></b> <br><u>font underline</u> <br><b><i><u>font bold italic underline</u></i></b> <br>&nbsp; <br>&nbsp; </body> </html> ���������������������������������������������������������������������������������������������������������./saods9/tests/analysis/analysis.par����������������������������������������������������������������0000644�0001750�0001750�00000000232�07253746357�016436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������var1,f,a,"something",,,"this is an entry" var2,b,h,yes,,,"this is a checkbox" var3,s,a,"default",default|other|another,,"this is a menu" mode,s,h,"ql",,, ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/analysis.ans����������������������������������������������������������������0000644�0001750�0001750�00000011113�12107534544�016420� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Analysis command descriptions: # menu label # file templates # menu/bind # analysis command line param foo var1 entry entry 40 {this is a entry} var2 checkbox checkbox 1 {this is a checkbox} var3 menu menu AAA|BBB|CCC {this is a menu} endparam param bar @analysis/analysis.par endparam param ltc bins entry "Enter number of [t1:t2:]bins" 0 "('0' for default number of bins)" endparam # Help Main Help help Main Help These menus contain a test for each possible feature supported by the ds9 (blank line above) endhelp --- hmenu Test Web help Web Help Help for web features endhelp --- Web Test url * web http://hea-www.harvard.edu/RD/ds9/site/Home.html Web Test file * web file:/Users/joye/saods9/tests/analysis/hv.html endhmenu hmenu Test Basics help Basic Help Help for basic features endhelp --- Test escape char # this is a comment * menu echo "this is not a macro $$xpa" | $text Test pass thru # this is a comment * menu echo "this is not a macro $foo" | $text Test $xpa # this is a comment * menu echo $xpa | $text Test $xpa_method # this is also a comment * menu echo $xpa_method | $text Test $vo_method * menu echo $vo_method | $text Test $filename *.fits menu echo $filename | $text Test $filename(root) *.fits menu echo $filename(root) | $text Test $filename(full) *.fits menu echo $filename(full) | $text Test $filename(root,3d) *.fits menu echo $filename(root,3d) | $text Test $filename(full,3d) *.fits menu echo $filename(full,3d) | $text Test $filedialog(open) * menu echo "$filedialog(open)" | $text Test $filedialog(save) * menu echo "$filedialog(save)" | $text Test $width $height $depth $bitpix *.fits menu echo "$width $height $depth $bitpix" | $text Test $pan *.fits menu echo "$pan(fk5,degrees)" | $text Test $env * menu echo $env(PATH) | $text endhmenu hmenu Test Regions help Regions Help Help for regions features endhelp --- Test $regions *.fits menu echo "$regions ds9_s:$regions(ds9,source,image) ciao_b:$regions(ciao,background) saotng_i:$regions(saotng,include,wcs,fk5) pros_e:$regions(pros,exclude,wcs,fk5,sexagesimal) xy_be:$regions(xy,background,exclude,wcs,fk4,hms)" | $text Test $regions wcs *.fits menu echo "$regions(ds9,wcs) $regions(ds9,wcs,fk5,sexagesimal) $regions(ds9,wcsa) " | $text Test $include_regions_pixels *.fits menu echo "ds9_s: $source_regions ds9_b: $background_regions_pixels ds9_i: $include_regions_degrees ds9_e: $exclude_regions_hms" | $text Test $filename $regions *.fits menu echo "$filename[$regions]" | $text Test $filename $regions() *.fits menu echo "$filename[$regions()]" | $text endhmenu hmenu Test Output help Output Help Help for output features endhelp --- Test $null * menu echo "This is Text" > /dev/null | $null Test $text * menu echo "This is Text" | $text Test $plot * menu cat xy.dat | $plot Test $plot(title,x,y,xyey) * menu cat xyey.dat | $plot(Title,X Axis,Y Axis,xyey) Test $plot(title,x,y,xyexey) * menu cat xyexey.dat | $plot(Title,X Axis,Y Axis,xyexey) Test $plot(title,x,y,4) * menu cat 4.dat | $plot(Title,X Axis,Y Axis,4) Test $plot(title,x,y,5) * menu cat 5.dat | $plot(Title,X Axis,Y Axis,5) Test $plot(stdin) * menu cat stdin.xy.dat | $plot(stdin) Test $plot(stdin) text * menu cat stdin.text.dat | $plot(stdin) Test $plot(stdin) error * menu cat stdin.error.dat | $plot(stdin) Test $data *.fits menu $data | $image(new) Test $image * menu cat data/img.fits | $image Test $image(3d) * menu cat data/3d.fits | $image(3d) endhmenu hmenu Test Dialogs help Dialogs Help Help for dialog features endhelp --- Test $message(message) * menu $message(ok,This is a Message) | echo "hello" | $text Test $message(ok,message) * menu $message(ok,This is a Message) | echo "World" | $text Test $entry(message) * menu echo "$entry(Enter Something)" | $text endhmenu hmenu Test Params help Param Help Help for param features endhelp --- Test $param * menu $param(foo); echo "$var1 $var2 $var3" | $text Test $param @file * menu $param(bar); echo "$var1 $var2 $var3" | $text endhmenu hmenu Test Network help Network Help Help for network features endhelp --- Test $url(http://) * menu $url(http://hea-www.harvard.edu/RD/ds9/download/data/img.fits) | $image(new) endhmenu $x $y $z $value *.fits bind x echo "$x $y $z $value" | $text $x(fk5) $y(fk5) $z(wcs) $value *.fits bind y echo "$x(fk5) $y(fk5) $z(wcs) $value" | $text $x(wcs,fk5,hms) $y(wcs,fk5,hms) $z(wcs) $value *.fits bind z echo "$x(wcs,fk5,hms) $y(wcs,fk5,hms) $z(wcs) $value" | $text �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/analysis/analysis.reg����������������������������������������������������������������0000644�0001750�0001750�00000000332�11430330435�016404� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Region file format: DS9 version 3.1 global color=green font="helvetica 10 normal roman" select=1 edit=1 move=1 delete=1 include=1 fixed=0 source physical;circle(759,913,40) physical;-circle(1029,917,40) # background ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/cubearray.sh�������������������������������������������������������������������������0000755�0001750�0001750�00000046353�12131345761�014577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } DoXPA () { echo "$1" xpaset -p ds9 array $2 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdin () { echo "$1" cat $2 | xpaset ds9 array $3 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear } DoXPAStdout () { echo "$1" xpaset -p ds9 tile xpaset -p ds9 array $2 xpaget ds9 array $3 > foo.arr xpaset -p ds9 frame new xpaset -p ds9 array foo.arr$4 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame delete xpaset -p ds9 frame clear } initit () { echo "Testing $1" unset opt } testit () { opt="$opt -export array foo.arr $1 -sleep .1" opt="$opt -frame new -array foo.arr$2" if [ $slow = "1" ]; then opt="$opt -sleep 1" fi opt="$opt -frame delete -sleep .1" } doit () { eval ds9 -tile -array $1 "$opt" -exit echo "PASSED" } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** cubearray.sh ***" # Command Line if [ "$1" = "command" -o -z "$1" ]; then echo "Testing Command File" echo ".. char" ds9 -array rgbarray/char.rgb[dim=256,zdim=3,bitpix=8] & KillIt echo ".. char gzip" ds9 -array rgbarray/char.rgb.gz[dim=256,zdim=3,bitpix=8] & KillIt echo ".. short little" ds9 -array rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] & KillIt echo ".. short little gzip" ds9 -array rgbarray/short_little.rgb.gz[dim=256,zdim=3,bitpix=16,arch=little] & KillIt echo ".. short big" ds9 -array rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] & KillIt echo ".. short big gzip" ds9 -array rgbarray/short_big.rgb.gz[dim=256,zdim=3,bitpix=16,arch=big] & KillIt echo ".. ushort little" ds9 -array rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" ds9 -array rgbarray/ushort_little.rgb.gz[dim=256,zdim=3,bitpix=-16,arch=little] & KillIt echo ".. ushort big" ds9 -array rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" ds9 -array rgbarray/ushort_big.rgb.gz[dim=256,zdim=3,bitpix=-16,arch=big] & KillIt echo ".. int little" ds9 -array rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] & KillIt echo ".. int little gzip" ds9 -array rgbarray/int_little.rgb.gz[dim=256,zdim=3,bitpix=32,arch=little] & KillIt echo ".. int big" ds9 -array rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] & KillIt echo ".. int big gzip" ds9 -array rgbarray/int_big.rgb.gz[dim=256,zdim=3,bitpix=32,arch=big] & KillIt echo ".. longlong little" ds9 -array rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" ds9 -array rgbarray/longlong_little.rgb.gz[dim=256,zdim=3,bitpix=64,arch=little] & KillIt echo ".. longlong big" ds9 -array rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" ds9 -array rgbarray/longlong_big.rgb.gz[dim=256,zdim=3,bitpix=64,arch=big] & KillIt echo ".. float little" ds9 -array rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" ds9 -array rgbarray/float_little.rgb.gz[dim=256,zdim=3,bitpix=-32,arch=little] & KillIt echo ".. float big" ds9 -array rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" ds9 -array rgbarray/float_big.rgb.gz[dim=256,zdim=3,bitpix=-32,arch=big] & KillIt echo ".. double little" ds9 -array rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" ds9 -array rgbarray/double_little.rgb.gz[dim=256,zdim=3,bitpix=-64,arch=little] & KillIt echo ".. double big" ds9 -array rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" ds9 -array rgbarray/double_big.rgb.gz[dim=256,zdim=3,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # Stdin if [ "$1" = "stdin" -o -z "$1" ]; then echo "Testing Command Stdin" echo ".. char" cat rgbarray/char.rgb | ds9 -array -[dim=256,zdim=3,bitpix=8] & KillIt echo ".. char gzip" cat rgbarray/char.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=8] & KillIt echo ".. short little" cat rgbarray/short_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=16,arch=little] & KillIt echo ".. short little gzip" cat rgbarray/short_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=16,arch=little] & KillIt echo ".. short big" cat rgbarray/short_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=16,arch=big] & KillIt echo ".. short big gzip" cat rgbarray/short_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=16,arch=big] & KillIt echo ".. ushort little" cat rgbarray/ushort_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-16,arch=little] & KillIt echo ".. ushort little gzip" cat rgbarray/ushort_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-16,arch=little] & KillIt echo ".. ushort big" cat rgbarray/ushort_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-16,arch=big] & KillIt echo ".. ushort big gzip" cat rgbarray/ushort_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-16,arch=big] & KillIt echo ".. int little" cat rgbarray/int_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=32,arch=little] & KillIt echo ".. int little gzip" cat rgbarray/int_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=32,arch=little] & KillIt echo ".. int big" cat rgbarray/int_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=32,arch=big] & KillIt echo ".. int big gzip" cat rgbarray/int_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=32,arch=big] & KillIt echo ".. longlong little" cat rgbarray/longlong_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=64,arch=little] & KillIt echo ".. longlong little gzip" cat rgbarray/longlong_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=64,arch=little] & KillIt echo ".. longlong big" cat rgbarray/longlong_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=64,arch=big] & KillIt echo ".. longlong big gzip" cat rgbarray/longlong_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=64,arch=big] & KillIt echo ".. float little" cat rgbarray/float_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-32,arch=little] & KillIt echo ".. float little gzip" cat rgbarray/float_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-32,arch=little] & KillIt echo ".. float big" cat rgbarray/float_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-32,arch=big] & KillIt echo ".. float big gzip" cat rgbarray/float_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-32,arch=big] & KillIt echo ".. double little" cat rgbarray/double_little.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-64,arch=little] & KillIt echo ".. double little gzip" cat rgbarray/double_little.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-64,arch=little] & KillIt echo ".. double big" cat rgbarray/double_big.rgb | ds9 -array -[dim=256,zdim=3,bitpix=-64,arch=big] & KillIt echo ".. double big gzip" cat rgbarray/double_big.rgb.gz | ds9 -array -[dim=256,zdim=3,bitpix=-64,arch=big] & KillIt echo "PASSED" fi # export if [ "$1" = "export" -o -z "$1" ]; then echo "Testing Command export" initit ".. char" testit little [dim=256,zdim=3,bitpix=8] doit rgbarray/char.rgb[dim=256,zdim=3,bitpix=8] initit ".. short little little" testit little [dim=256,zdim=3,bitpix=16,arch=little] doit rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] initit ".. short little big" testit big [dim=256,zdim=3,bitpix=16,arch=big] doit rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] initit ".. short big little" testit little [dim=256,zdim=3,bitpix=16,arch=little] doit rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] initit ".. short big big" testit big [dim=256,zdim=3,bitpix=16,arch=big] doit rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] initit ".. ushort little little" testit little [dim=256,zdim=3,bitpix=-16,arch=little] doit rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] initit ".. ushort little big" testit big [dim=256,zdim=3,bitpix=-16,arch=big] doit rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] initit ".. ushort big little" testit little [dim=256,zdim=3,bitpix=-16,arch=little] doit rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] initit ".. ushort big big" testit big [dim=256,zdim=3,bitpix=-16,arch=big] doit rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] initit ".. int little little" testit little [dim=256,zdim=3,bitpix=32,arch=little] doit rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] initit ".. int little big" testit big [dim=256,zdim=3,bitpix=32,arch=big] doit rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] initit ".. int big little" testit little [dim=256,zdim=3,bitpix=32,arch=little] doit rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] initit ".. int big big" testit big [dim=256,zdim=3,bitpix=32,arch=big] doit rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] initit ".. longlong little little" testit little [dim=256,zdim=3,bitpix=64,arch=little] doit rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] initit ".. longlong little big" testit big [dim=256,zdim=3,bitpix=64,arch=big] doit rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] initit ".. longlong big little" testit little [dim=256,zdim=3,bitpix=64,arch=little] doit rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] initit ".. longlong big big" testit big [dim=256,zdim=3,bitpix=64,arch=big] doit rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] initit ".. float little little" testit little [dim=256,zdim=3,bitpix=-32,arch=little] doit rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] initit ".. float little big" testit big [dim=256,zdim=3,bitpix=-32,arch=big] doit rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] initit ".. float big little" testit little [dim=256,zdim=3,bitpix=-32,arch=little] doit rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] initit ".. float big big" testit big [dim=256,zdim=3,bitpix=-32,arch=big] doit rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] initit ".. double little little" testit little [dim=256,zdim=3,bitpix=-64,arch=little] doit rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] initit ".. double little big" testit big [dim=256,zdim=3,bitpix=-64,arch=big] doit rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] initit ".. double big little" testit little [dim=256,zdim=3,bitpix=-64,arch=little] doit rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] initit ".. double big big" testit big [dim=256,zdim=3,bitpix=-64,arch=big] doit rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] fi # XPA if [ "$1" = "xpa" -o -z "$1" ]; then echo "Testing XPA File" StartDS9 DoXPA ".. char" rgbarray/char.rgb[dim=256,zdim=3,bitpix=8] DoXPA ".. char gzip" rgbarray/char.rgb.gz[dim=256,zdim=3,bitpix=8] DoXPA ".. short little" rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] DoXPA ".. short little gzip" rgbarray/short_little.rgb.gz[dim=256,zdim=3,bitpix=16,arch=little] DoXPA ".. short big" rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] DoXPA ".. short big gzip" rgbarray/short_big.rgb.gz[dim=256,zdim=3,bitpix=16,arch=big] DoXPA ".. ushort little" rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] DoXPA ".. ushort little gzip" rgbarray/ushort_little.rgb.gz[dim=256,zdim=3,bitpix=-16,arch=little] DoXPA ".. ushort big" rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] DoXPA ".. ushort big gzip" rgbarray/ushort_big.rgb.gz[dim=256,zdim=3,bitpix=-16,arch=big] DoXPA ".. int little" rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] DoXPA ".. int little gzip" rgbarray/int_little.rgb.gz[dim=256,zdim=3,bitpix=32,arch=little] DoXPA ".. int big" rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] DoXPA ".. int big gzip" rgbarray/int_big.rgb.gz[dim=256,zdim=3,bitpix=32,arch=big] DoXPA ".. longlong little" rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] DoXPA ".. longlong little gzip" rgbarray/longlong_little.rgb.gz[dim=256,zdim=3,bitpix=64,arch=little] DoXPA ".. longlong big" rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] DoXPA ".. longlong big gzip" rgbarray/longlong_big.rgb.gz[dim=256,zdim=3,bitpix=64,arch=big] DoXPA ".. float little" rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] DoXPA ".. float little gzip" rgbarray/float_little.rgb.gz[dim=256,zdim=3,bitpix=-32,arch=little] DoXPA ".. float big" rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] DoXPA ".. float big gzip" rgbarray/float_big.rgb.gz[dim=256,zdim=3,bitpix=-32,arch=big] DoXPA ".. double little" rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] DoXPA ".. double little gzip" rgbarray/double_little.rgb.gz[dim=256,zdim=3,bitpix=-64,arch=little] DoXPA ".. double big" rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] DoXPA ".. double big gzip" rgbarray/double_big.rgb.gz[dim=256,zdim=3,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi # XPA if [ "$1" = "xpastdin" -o -z "$1" ]; then echo "Testing XPA Stdin" StartDS9 DoXPAStdin ".. char" rgbarray/char.rgb [dim=256,zdim=3,bitpix=8] DoXPAStdin ".. char gzip" rgbarray/char.rgb.gz [dim=256,zdim=3,bitpix=8] DoXPAStdin ".. short little" rgbarray/short_little.rgb [dim=256,zdim=3,bitpix=16,arch=little] DoXPAStdin ".. short little gzip" rgbarray/short_little.rgb.gz [dim=256,zdim=3,bitpix=16,arch=little] DoXPAStdin ".. short big" rgbarray/short_big.rgb [dim=256,zdim=3,bitpix=16,arch=big] DoXPAStdin ".. short big gzip" rgbarray/short_big.rgb.gz [dim=256,zdim=3,bitpix=16,arch=big] DoXPAStdin ".. ushort little" rgbarray/ushort_little.rgb [dim=256,zdim=3,bitpix=-16,arch=little] DoXPAStdin ".. ushort little gzip" rgbarray/ushort_little.rgb.gz [dim=256,zdim=3,bitpix=-16,arch=little] DoXPAStdin ".. ushort big" rgbarray/ushort_big.rgb [dim=256,zdim=3,bitpix=-16,arch=big] DoXPAStdin ".. ushort big gzip" rgbarray/ushort_big.rgb.gz [dim=256,zdim=3,bitpix=-16,arch=big] DoXPAStdin ".. int little" rgbarray/int_little.rgb [dim=256,zdim=3,bitpix=32,arch=little] DoXPAStdin ".. int little gzip" rgbarray/int_little.rgb.gz [dim=256,zdim=3,bitpix=32,arch=little] DoXPAStdin ".. int big" rgbarray/int_big.rgb [dim=256,zdim=3,bitpix=32,arch=big] DoXPAStdin ".. int big gzip" rgbarray/int_big.rgb.gz [dim=256,zdim=3,bitpix=32,arch=big] DoXPAStdin ".. longlong little" rgbarray/longlong_little.rgb [dim=256,zdim=3,bitpix=64,arch=little] DoXPAStdin ".. longlong little gzip" rgbarray/longlong_little.rgb.gz [dim=256,zdim=3,bitpix=64,arch=little] DoXPAStdin ".. longlong big" rgbarray/longlong_big.rgb [dim=256,zdim=3,bitpix=64,arch=big] DoXPAStdin ".. longlong big gzip" rgbarray/longlong_big.rgb.gz [dim=256,zdim=3,bitpix=64,arch=big] DoXPAStdin ".. float little" rgbarray/float_little.rgb [dim=256,zdim=3,bitpix=-32,arch=little] DoXPAStdin ".. float little gzip" rgbarray/float_little.rgb.gz [dim=256,zdim=3,bitpix=-32,arch=little] DoXPAStdin ".. float big" rgbarray/float_big.rgb [dim=256,zdim=3,bitpix=-32,arch=big] DoXPAStdin ".. float big gzip" rgbarray/float_big.rgb.gz [dim=256,zdim=3,bitpix=-32,arch=big] DoXPAStdin ".. double little" rgbarray/double_little.rgb [dim=256,zdim=3,bitpix=-64,arch=little] DoXPAStdin ".. double little gzip" rgbarray/double_little.rgb.gz [dim=256,zdim=3,bitpix=-64,arch=little] DoXPAStdin ".. double big" rgbarray/double_big.rgb [dim=256,zdim=3,bitpix=-64,arch=big] DoXPAStdin ".. double big gzip" rgbarray/double_big.rgb.gz [dim=256,zdim=3,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi # XPA stdout if [ "$1" = "xpastdout" -o -z "$1" ]; then echo "Testing XPA Stdout" StartDS9 DoXPAStdout ".. char" rgbarray/char.rgb[dim=256,zdim=3,bitpix=8] little [dim=256,zdim=3,bitpix=8] DoXPAStdout ".. short little little" rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] little [dim=256,zdim=3,bitpix=16,arch=little] DoXPAStdout ".. short little big" rgbarray/short_little.rgb[dim=256,zdim=3,bitpix=16,arch=little] big [dim=256,zdim=3,bitpix=16,arch=big] DoXPAStdout ".. short big little" rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] little [dim=256,zdim=3,bitpix=16,arch=little] DoXPAStdout ".. short big big" rgbarray/short_big.rgb[dim=256,zdim=3,bitpix=16,arch=big] big [dim=256,zdim=3,bitpix=16,arch=big] DoXPAStdout ".. ushort little little" rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] little [dim=256,zdim=3,bitpix=-16,arch=little] DoXPAStdout ".. ushort little big" rgbarray/ushort_little.rgb[dim=256,zdim=3,bitpix=-16,arch=little] big [dim=256,zdim=3,bitpix=-16,arch=big] DoXPAStdout ".. ushort big little" rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] little [dim=256,zdim=3,bitpix=-16,arch=little] DoXPAStdout ".. ushort big big" rgbarray/ushort_big.rgb[dim=256,zdim=3,bitpix=-16,arch=big] big [dim=256,zdim=3,bitpix=-16,arch=big] DoXPAStdout ".. int little little" rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] little [dim=256,zdim=3,bitpix=32,arch=little] DoXPAStdout ".. int little big" rgbarray/int_little.rgb[dim=256,zdim=3,bitpix=32,arch=little] big [dim=256,zdim=3,bitpix=32,arch=big] DoXPAStdout ".. int big little" rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] little [dim=256,zdim=3,bitpix=32,arch=little] DoXPAStdout ".. int big big" rgbarray/int_big.rgb[dim=256,zdim=3,bitpix=32,arch=big] big [dim=256,zdim=3,bitpix=32,arch=big] DoXPAStdout ".. longlong little little" rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] little [dim=256,zdim=3,bitpix=64,arch=little] DoXPAStdout ".. longlong little big" rgbarray/longlong_little.rgb[dim=256,zdim=3,bitpix=64,arch=little] big [dim=256,zdim=3,bitpix=64,arch=big] DoXPAStdout ".. longlong big little" rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] little [dim=256,zdim=3,bitpix=64,arch=little] DoXPAStdout ".. longlong big big" rgbarray/longlong_big.rgb[dim=256,zdim=3,bitpix=64,arch=big] big [dim=256,zdim=3,bitpix=64,arch=big] DoXPAStdout ".. float little little" rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] little [dim=256,zdim=3,bitpix=-32,arch=little] DoXPAStdout ".. float little big" rgbarray/float_little.rgb[dim=256,zdim=3,bitpix=-32,arch=little] big [dim=256,zdim=3,bitpix=-32,arch=big] DoXPAStdout ".. float big little" rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] little [dim=256,zdim=3,bitpix=-32,arch=little] DoXPAStdout ".. float big big" rgbarray/float_big.rgb[dim=256,zdim=3,bitpix=-32,arch=big] big [dim=256,zdim=3,bitpix=-32,arch=big] DoXPAStdout ".. double little little" rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] little [dim=256,zdim=3,bitpix=-64,arch=little] DoXPAStdout ".. double little big" rgbarray/double_little.rgb[dim=256,zdim=3,bitpix=-64,arch=little] big [dim=256,zdim=3,bitpix=-64,arch=big] DoXPAStdout ".. double big little" rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] little [dim=256,zdim=3,bitpix=-64,arch=little] DoXPAStdout ".. double big big" rgbarray/double_big.rgb[dim=256,zdim=3,bitpix=-64,arch=big] big [dim=256,zdim=3,bitpix=-64,arch=big] xpaset -p ds9 quit echo "PASSED" fi rm -f foo.* echo "DONE" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/parse.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000005146�12131345054�013722� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 quit break fi i=`expr $i + 1` done } StartDS9 () { if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** parse.sh ***" echo ".. base" ds9 -log fits/table.fits & KillIt echo ".. [2]" ds9 -log fits/table.fits[2] & KillIt echo ".. [STDEVT]" ds9 -log fits/table.fits[STDEVT] & KillIt echo ".. [xmin:xmax,ymin:ymax]" ds9 -zscale data/img.fits[100:300,100:300] & KillIt echo ".. [xmin:xmax,*]" ds9 -zscale data/img.fits[100:300,*] & KillIt echo ".. [dim@xcen@ycen]" ds9 -zscale data/img.fits[256@400@400] & KillIt echo ".. [bin=rawx,rawy]" ds9 -log fits/table.fits[bin=rawx,rawy] & KillIt echo ".. [STDEVT][xmin:xmax,ymin:ymax]" ds9 -log fits/table.fits[STDEVT][100:300,100:300] & KillIt echo ".. [STDEVT][bin=rawx,rawy]" ds9 -log fits/table.fits[STDEVT][bin=rawx,rawy] & KillIt echo ".. [STDEVT][bin=(rawx,rawy)]" ds9 -log 'fits/table.fits[STDEVT][bin=(rawx,rawy)]' & KillIt echo ".. [STDEVT][xmin:xmax,ymin:ymax][bin=rawx,rawy]" ds9 -log fits/table.fits[STDEVT][100:300,100:300][bin=rawx,rawy] & KillIt echo ".. [2,xmin:xmax,ymin:ymax]" ds9 -log fits/table.fits[2,100:300,100:300] & KillIt echo ".. [STDEVT,xmin:xmax,ymin:ymax]" ds9 -log fits/table.fits[STDEVT,100:300,100:300] & KillIt echo ".. [STDEVT,bin=rawx,rawy]" ds9 -log fits/table.fits[STDEVT,bin=rawx,rawy] & KillIt echo ".. [filter]" ds9 -log 'fits/table.fits[pha<5]' & KillIt echo ".. [STDEVT][filter]" ds9 -log 'fits/table.fits[STDEVT][pha<5]' & KillIt echo ".. array[xdim=256,ydim=256,bitpix=-32,arch=little,skip=0]" ds9 -array array/float_little.arr[xdim=256,ydim=256,bitpix=-32,arch=little,skip=0] & KillIt echo ".. array[dim=256,bitpix=-32,endian=little]" ds9 -array array/float_little.arr[dim=256,bitpix=-32,endian=little] & KillIt echo ".. array[dim=256,bitpix=-32,little]" ds9 -array array/float_little.arr[dim=256,bitpix=-32,little] & KillIt echo ".. array[array(r256l)]" ds9 -array 'array/float_little.arr[array(r256l)]' & KillIt echo ".. array[array(r256.256:0l)]" ds9 -array 'array/float_little.arr[array(r256.256:0l)]' & KillIt echo ".. hpx" ds9 fits/wmap.fits & KillIt echo ".. hpx[system=equatorial,order=north,layout=equatorial,col=1,quad=1]" ds9 fits/wmap.fits[system=equatorial,order=north,layout=equatorial,col=1,quad=1] & KillIt echo "DONE" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/rice.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000040�12107264737�013531� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������partial.sh RICE rice fits $1 $2 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/io.sh��������������������������������������������������������������������������������0000644�0001750�0001750�00000000437�12131617605�013216� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fits.sh cube.sh rice.sh hcompress.sh gzip.sh plio.sh fits64.sh #shm.sh rgbimage.sh rgbcube.sh mecube.sh multiframe.sh mosaic.sh mosaicimage.sh # backward compatibility sfits.sh srgbcube.sh #smosaic.sh #smosaiciraf.sh #smosaicwcs.sh array.sh cubearray.sh rgbarray.sh nrrd.sh photo.sh ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/wcs.sh�������������������������������������������������������������������������������0000755�0001750�0001750�00000000657�12131345054�013406� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������echo echo "*** wcs.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ]; then break fi i=`expr $i + 1` done fi xpaset -p ds9 grid on xpaset -p ds9 grid wcs xpaset -p ds9 scale zscale xpaset -p ds9 wcs skyformat degrees for f in wcs/*.fits do echo $f xpaset -p ds9 fits $f read done xpaset -p ds9 quit echo "DONE" ���������������������������������������������������������������������������������./saods9/tests/gzip.sh������������������������������������������������������������������������������0000755�0001750�0001750�00000000040�12107264737�013560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������partial.sh GZIP gzip fits $1 $2 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/fits64.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000000170�12131617434�013723� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������export XPA_CONNECT_TIMEOUT=0 export XPA_SHORT_TIMEOUT=-1 export XPA_LONG_TIMEOUT=-1 full.sh Fits large fits save $1 $2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/shared.sh����������������������������������������������������������������������������0000755�0001750�0001750�00000013316�12132047764�014064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#linux commands #ipcs -m #ipcs -ml #ipcrm shm <shmid> #echo '67108864' > /proc/sys/kernel/shmmax KillIt () { i=1 while [ "$i" -le 15 ]; do sleep 1 if [ `xpaaccess ds9` = yes ]; then sleep 1 xpaset -p ds9 quit break fi i=`expr $i + 1` done } DoCmd () { echo "$1" shmid=`shmload -q $2` ds9 -scale $5 -scale mode $6 -shm $3 shmid $shmid $4 & KillIt ipcrm -m $shmid } DoSCmd () { echo "$1" shmid1=`shmload -q $2` shmid2=`shmload -q $3` ds9 -scale $6 -scale mode $7 -shm $4 shmid $shmid1 $shmid2 $5 & KillIt ipcrm -m $shmid1 ipcrm -m $shmid2 } DoXPA () { echo "$1" shmid=`shmload -q $2` xpaset -p ds9 scale $5 xpaset -p ds9 scale mode $6 xpaset -p ds9 shm $3 shmid $shmid $4 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear ipcrm -m $shmid } DoSXPA () { echo "$1" shmid1=`shmload -q $2` shmid2=`shmload -q $3` xpaset -p ds9 scale $6 xpaset -p ds9 scale mode $7 xpaset -p ds9 shm $4 shmid $shmid1 $shmid2 $5 if [ $slow = "1" ]; then sleep 1 fi xpaset -p ds9 frame clear ipcrm -m $shmid1 ipcrm -m $shmid2 } # slow down? slow=0 if [ "$1" = "slow" ]; then slow=1 shift fi echo echo "*** shared.sh ***" echo "Current shm limits" #ipcs -lm if [ "$1" = "command" -o -z "$1" ]; then echo "Command Line Shm Tests" # basics DoCmd "..fits" data/img.fits fits foo linear zscale DoSCmd "..sfits" sfits/float.hdr sfits/float.arr sfits foo linear zscale DoCmd "..table" fits/table.fits "" foo log minmax DoCmd "..table filter" fits/table.fits "" 'foo[bin=rawx,rawy]' log minmax # mosaic DoCmd "..mosaic image iraf" mosaic/mosaicimage.fits "mosaicimage iraf" foo linear zscale DoCmd "..mosaic image iraf datacube" mosaic/naxis4.fits "mosaicimage iraf" foo linear zscale DoCmd "..mosaic image wcs" mosaic/mosaicimage.fits "mosaicimage wcs" foo linear zscale DoCmd "..mosaic image wcsp" mosaic/ds9_8amp_2x2.fits "mosaicimage wcsp" foo linear minmax DoCmd "..mosaic image wfpc2" mosaic/hst.fits "mosaicimage wfpc2" foo linear zscale DoCmd "..mosaic iraf" mosaic/mosaicimage.fits "mosaic iraf" foo linear zscale DoCmd "..mosaic iraf datacube" mosaic/naxis4.fits "mosaic iraf" foo linear zscale DoCmd "..mosaic wcs" mosaic/mosaicimage.fits "mosaic wcs" foo linear zscale DoCmd "..mosaic wcsp" mosaic/ds9_8amp_2x2.fits "mosaic wcsp" foo linear minmax #DoSCmd "..mosaic wcs sfits" sfits/float.hdr sfits/float.arr "smosaic wcs" foo linear zscale # backward compatibility DoCmd "..mosaic image iraf(bc)" mosaic/mosaicimage.fits mosaicimageiraf foo linear zscale DoCmd "..mosaic image wcs(bc)" mosaic/mosaicimage.fits mosaicimagewcs foo linear zscale DoCmd "..mosaic image wfpc2(bc)" mosaic/hst.fits mosaicimagewfpc2 foo linear zscale DoCmd "..mosaic iraf(bc)" mosaic/mosaicimage.fits mosaiciraf foo linear zscale DoCmd "..mosaic wcs(bc)" mosaic/mosaicimage.fits mosaicwcs foo linear zscale # array DoCmd "..array" array/float_big.arr array 'foo[dim=256,bitpix=-32,arch=big]' linear minmax DoCmd "..array cube" rgbarray/float_big.rgb array 'foo[dim=256,zdim=3,bitpix=-32,arch=big]' linear minmax # rgb DoCmd "..rgbcube" rgbcube/float.fits rgbcube foo linear minmax DoSCmd "..rgbcube sfits" srgbcube/float.hdr srgbcube/float.arr srgbcube foo linear minmax DoCmd "..rgbimage" mecube/float.fits rgbimage foo linear minmax echo "PASSED" fi if [ "$1" = "xpa" -o -z "$1" ]; then echo "XPA Shm Tests" echo "Starting DS9..." if [ `xpaaccess ds9` = no ] then ds9& fi i=1 while [ "$i" -le 15 ] do sleep 1 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done # basics DoXPA "..fits" data/img.fits fits foo linear zscale DoSXPA "..split fits" sfits/float.hdr sfits/float.arr sfits foo linear zscale DoXPA "..table" fits/table.fits "" foo log minmax DoXPA "..table filter" fits/table.fits "" 'foo[bin=rawx,rawy]' log minmax # mosaics DoXPA "..mosaic image iraf" mosaic/mosaicimage.fits "mosaicimage iraf" foo linear zscale DoXPA "..mosaic image iraf datacube" mosaic/naxis4.fits "mosaicimage iraf" foo linear zscale DoXPA "..mosaic image wcs" mosaic/mosaicimage.fits "mosaicimage wcs" foo linear zscale DoXPA "..mosaic image wcsp" mosaic/ds9_8amp_2x2.fits "mosaicimage wcs" foo linear minmax DoXPA "..mosaic image wfpc2" mosaic/hst.fits "mosaicimage wfpc2" foo linear zscale DoXPA "..mosaic iraf" mosaic/mosaicimage.fits "mosaic iraf" foo linear zscale DoXPA "..mosaic iraf datacube" mosaic/naxis4.fits "mosaic iraf" foo linear zscale DoXPA "..mosaic wcs" mosaic/mosaicimage.fits "mosaic wcs" foo linear zscale DoXPA "..mosaic wcsp" mosaic/ds9_8amp_2x2.fits "mosaicimage wcs" foo linear minmax #DoSXPA "..sfits mosaic wcs" sfits/float.hdr sfits/float.arr "smosaic wcs" foo linear zscale # backward compatibility DoXPA "..mosaic image iraf(bc)" mosaic/mosaicimage.fits mosaicimageiraf foo linear zscale DoXPA "..mosaic image wcs(bc)" mosaic/mosaicimage.fits mosaicimagewcs foo linear zscale DoXPA "..mosaic image wfpc2(bc)" mosaic/hst.fits mosaicimagewfpc2 foo linear zscale DoXPA "..mosaic iraf(bc)" mosaic/mosaicimage.fits mosaiciraf foo linear zscale DoXPA "..mosaic wcs(bc)" mosaic/mosaicimage.fits mosaicwcs foo linear zscale # array DoXPA "..array" array/float_big.arr array 'foo[dim=256,bitpix=-32,arch=big]' linear minmax DoXPA "..array cube" rgbarray/float_big.rgb array 'foo[dim=256,zdim=3,bitpix=-32,arch=big]' linear minmax # rgb xpaset -p ds9 scale linear xpaset -p ds9 scale mode minmax xpaset -p ds9 rgb DoXPA "..rgbcube" rgbcube/float.fits rgbcube foo linear minmax DoSXPA "..rgbcube sfits" srgbcube/float.hdr srgbcube/float.arr srgbcube foo linear minmax DoXPA "..rgbimage" mecube/float.fits rgbimage foo linear minmax xpaset -p ds9 frame delete xpaset -p ds9 quit echo "PASSED" fi echo "DONE" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/tests/scale.sh�����������������������������������������������������������������������������0000755�0001750�0001750�00000003057�12131345054�013676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������testit () { echo "Testing $1..." xpaset -p ds9 scale $1 xpaset -p ds9 contour scale $1 xpaset -p ds9 file $2 xpaset -p ds9 contour yes read xpaset -p ds9 frame clear } echo echo "*** scale.sh ***" echo "Starting DS9..." if [ `xpaaccess ds9` = no ]; then ds9& i=1 while [ "$i" -le 30 ] do sleep 2 if [ `xpaaccess ds9` = yes ] then break fi i=`expr $i + 1` done fi echo "Setup..." xpaset -p ds9 cmap i8 xpaset -p ds9 contour nlevels 9 xpaset -p ds9 contour color black testit linear scale/linear.fits testit log scale/pow.fits testit pow scale/log.fits testit sqrt scale/squ.fits testit squared scale/sqrt.fits testit asinh scale/sinh.fits testit sinh scale/asinh.fits echo "Testing histequ..." xpaset -p ds9 scale histequ xpaset -p ds9 contour scale histequ xpaset -p ds9 fits scale/linear.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/log.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/pow.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/sqrt.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/squ.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/asinh.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 fits scale/sinh.fits xpaset -p ds9 contour generate xpaset -p ds9 contour yes read xpaset -p ds9 frame clear xpaset -p ds9 quit ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.macosxppcleopard����������������������������������������������������������������������0000644�0001750�0001750�00000001052�11773331763�015317� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxppcleopard X11INCLUDE =../include/X11 export MACOSX_DEPLOYMENT_TARGET := 10.5 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch ppc -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 AA = -fPIC -D_MACOSX -DMAC_OSX_TK -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip JOBS = 4 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�012232� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/blt.mak���������������������������������������������������������������������������0000644�0001750�0001750�00000001624�11462120062�013514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for demonstation shell of BLT library # ------------------------------------------------------------------------ !INCLUDE ./win/makedefs # ------------------------------------------------------------------------ # Source and target installation directories # ------------------------------------------------------------------------ srcdir = . # ------------------------------------------------------------------------ # Don't edit anything beyond this point # ------------------------------------------------------------------------ all: cd $(MAKEDIR)\src $(MAKE) -f blt.mak all cd $(MAKEDIR) install: install-all install-all: wish$(v2)d.exe win/install.tcl $(v1) $(srcdir) clean: cd $(MAKEDIR)\src $(MAKE) -f blt.mak clean cd $(MAKEDIR) $(RM) *.bak *\~ "#"* *pure* .pure* distclean: clean ������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/README����������������������������������������������������������������������������0000644�0001750�0001750�00000013200�11462120062�013112� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� This is version 3.0 of the BLT library. It's an extension to the Tcl/Tk toolkit. You simply compile and link with the Tcl/Tk libraries. It does not require the Tcl or Tk source files. BLT is available from www.sourceforge.net/projects/blt/files This release has been built and tested with the following Tcl/Tk versions: Tcl/Tk 8.0 Tcl/Tk 8.1 Tcl/Tk 8.2 Tcl/Tk 8.3 Tcl/Tk 8.4 thru 8.4.0 Tcl 7.6/Tk 4.2 isn't supported any more. If you need Tcl 7.x, use the 2.4z release. Avoid alpha and beta versions of Tcl/Tk. They probably won't work. What is BLT? BLT is an extension to Tcl/Tk. It adds plotting widgets (X-Y graph, barchart, stripchart), a powerful geometry manager, a new canvas item, and several new commands to Tk. Plotting widgets: graph, barchart, stripchart BLT has X-Y graph, barchart, and stripchart widgets that are both easy to use and customize. All the widgets work with BLT vector data objects, which makes it easy to manage data. Tree viewer treeview Displays a general ordered tree which may be built on-the-fly or all at once. tree Tree data object. Tab set: tabset Can be used either as a tab notebook or simple tabset. Multi-tiered and/or scrolled tabsets are available. Notebook pages can be torn-off into separate windows and later put back. Geometry Manager: table A table-based geometry manager. Lets you specify widget layouts by row and column positions in the table. Unlike the packer or grid, you can finely control and constrain window sizes. Vector Data Object: vector Lets you manage a vector of floating point values in a high-level fashion. Vectors inter-operate seamlessly with the plotting widgets. The graphs will automatically redraw themselves when the vector data changes. Vector's components can be managed through a Tcl array variable, a Tcl command, or the using its own C API. Background Program Execution: bgexec Like Tcl's "exec ... &", but collects the output, error, and status of the detached UNIX subprocesses. Sets a Tcl variable upon completion. Busy Command: busy For preventing user-interactions when the application is busy. Manages an invisible "busy" window which prevents further user interactions (keyboard, mouse, button, etc.). Also you can provide a busy cursor that temporarily overrides those of the Tk widgets. New Canvas Item: eps An new item is added to the Tk canvas for handling encapsulated PostScript. It lets you embed an EPS file into the canvas displaying either an EPS preview image found in the file, or a Tk image that you provide. When you print the canvas the EPS item will automatically include the EPS file, translating and scaling the PostScript. For example, you could use "eps" items to tile several PostScript pages into single page. The "eps" item can also be used as a replacement for "image" canvas items. Unlike "image" canvas items, the image of an eps item can be printed and scaled arbitrarily. Drag & Drop Facility: drag&drop Adds drag-n-drop capabilities to Tk. It uses "send"-style communication between drag-drop sources and targets. The result is a much more powerful drag-and-drop mechanism than is available with OpenLook or Motif. Bitmap Command: bitmap Lets you read and write bitmaps from Tcl. You can define bitmaps from ordinary text strings. Bitmaps can also be scaled and rotated. For example, you can create a button with rotated text by defining a bitmap from a text string and rotating it. You can then use the bitmap in the button widget. Miscellaneous Commands: winop Basic window operations. You can raise, lower, map, or, unmap windows. Other operations let you move the pointer or take photo image snapshots of Tk widgets. bltdebug Lets you trace the execution of Tcl commands and procedures. Prints out each Tcl command before it's executed. watch Lets you specify Tcl procedures to be run before and/or after every Tcl command. May be used for logging, tracing, profiling, or debugging or Tcl code. spline Computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. htext A simple hypertext widget. Allows text and Tk widgets to be combined in a scroll-able text window. Any Tk widget can be embedded and used to form hyper-links. Other options allow for selections and text searches. How to compile and test BLT? See the file "INSTALL" for instructions. Does BLT work under Windows? Yes. Windows 95/98/ME/NT/2000/XP. I've compiled it with both MS VC++ 5.0/6.0p4 and EGCS 1.1.1. Self-installing pre-compiled versions are available. What are the differences between the Windows and Unix releases? All commands work: graphs, bgexec, busy, drag&drop etc. except the "container", and "cutbuffer" widgets. The "drag&drop" command still needs to use "send" to transfer information between Tk applications. You can use ./demos/scripts/send.tcl to imitate "send" using DDE. Just source the script and execute SendInit SendVerify to set up the new send command. When will...? In general, I can't answer the "When will" questions, mostly out of embarrassment. My estimates of when new features and releases will occur usually turn out to be way way off. What does BLT stand for? Whatever you want it to. Where to send bugs reports, suggestions, etc. ? ghowlett@grandecom.net Make sure you include BLT and the version number in the subject line. --gah ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/�����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013176� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/container.html���������������������������������������������������������������0000644�0001750�0001750�00000033167�11462120062�016064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>container(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> container - Widget to contain a foreign window. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>container</B> <I>pathName </I>?<I>options</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>container</B> widget lets you embed an X11 window from a foreign application into your Tk application. The foreign window is reparented inside of the widget. You can then place and arrange the container just as you would any Tk widget. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Notebooks are a popular graphical paradigm. They allow you to organize many windows in a single widget. For example, you might have an application the displays several X-Y graphs at the same time. Typically, you can't pack the graphs into the same <B>frame</B> because they are too large. The other alternative is to pack the graphs into several <B>toplevel</B> widgets, allowing them to overlap on the screen. The problem is that all the different toplevel windows clutter the screen and are difficult to manage. <P> The <B>container</B> widget lets organize your application by displaying each graph as a page in a folder of a notebook. Only one page is visible at a time. When you click on a tab, the folder (graph) corresponding to the tab is displayed in the <B>container</B> widget. The container also lets you temporarily tear pages out of the notebook into a separate toplevel widget, and put them back in the container later. For example, you could compare two graphs side-by-side by tearing them out, and then replace them when you are finished. <P> A container may contain an unlimited number of folders. If there are too many tabs to view, you can arrange them as multiple tiers or scroll the tabs. The container uses the conventional Tk scrollbar syntax, so you can attach a scrollbar too. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> You create a container widget with the <B>container</B> command. <BR> <CODE># Create a new container<BR> container .c<BR> </CODE><P>A new Tcl command <I>.c</I> is also created. This command can be used to query and modify the container. For example, to change the default borderwidth, you use the new command and the container's <B>configure</B> operation. <BR> <CODE># Change the default font.<BR> .c configure -borderwidth 2<BR> </CODE><P>You can then add folders using the <B>insert</B> operation. <BR> <CODE># Create a new folder "f1"<BR> .c coinsert 0 "f1"<BR> </CODE><P>This inserts the new tab named "f1" into the container. The index <I>0</I> indicates location to insert the new tab. You can also use the index <I>end</I> to append a tab to the end of the container. By default, the text of the tab is the name of the tab. You can change this by configuring the <B>-text</B> option. <BR> <CODE># Change the label of "f1"<BR> .ts tab configure "f1" -label "Tab #1" <BR> </CODE><P>The <B>insert</B> operation lets you add one or more folders at a time. <BR> <CODE>.ts insert end "f2" -label "Tab #2" "f3" "f4" <BR> </CODE><P>The tab on each folder contains a label. A label may display both an image and a text string. You can reconfigure the tab's attributes (foreground/background colors, font, rotation, etc) using the <B>tab configure</B> operation. <BR> <CODE># Add an image to the label of "f1"<BR> set image [image create photo -file stopsign.gif]<BR> .ts tab configure "f1" -image $image<BR> .ts tab configure "f2" -rotate 90<BR> </CODE><P>Each folder may contain an embedded widget to represent its contents. The widget to be embedded must be a child of the container widget. Using the <B>-window</B> option, you specify the name of widget to be embedded. But don't pack the widget, the container takes care of placing and arranging the widget for you. <BR> <CODE>graph .ts.graph<BR> .ts tab configure "f1" -window ".ts.graph" \<BR> -fill both -padx 0.25i -pady 0.25i<BR> </CODE><P>The size of the folder is determined the sizes of the Tk widgets embedded inside each folder. The folder will be as wide as the widest widget in any folder. The tallest determines the height. You can use the tab's <B>-pagewidth</B> and <B>-pageheight</B> options override this. <P> Other options control how the widget appears in the folder. The <B>-fill</B> option says that you wish to have the widget stretch to fill the available space in the folder. <BR> <CODE>.ts tab configure "f1" -fill both -padx 0.25i -pady 0.25i<BR> <P> </CODE><P>Now when you click the left mouse button on "f1", the graph will be displayed in the folder. It will be automatically hidden when another folder is selected. If you click on the right mouse button, the embedded widget will be moved into a toplevel widget of its own. Clicking again on the right mouse button puts it back into the folder. <P> If you want to share a page between two different folders, the <B>-command</B> option lets you specify a Tcl command to be invoked whenever the folder is selected. You can reset the <B>-window</B> option for the tab whenever it's clicked. <BR> <CODE>.ts tab configure "f2" -command { <BR> .ts tab configure "f2" -window ".ts.graph"<BR> }<BR> .ts tab configure "f1" -command { <BR> .ts tab configure "f1" -window ".ts.graph"<BR> }<BR> </CODE><P>If you have many folders, you may wish to stack tabs in multiple tiers. The container's <B>-tiers</B> option requests a maximum number of tiers. The default is one tier. <BR> <CODE>.ts configure -tiers 2<BR> </CODE><P>If the tabs can fit in less tiers, the widget will use that many. Whenever there are more tabs than can be displayed in the maximum number of tiers, the container will automatically let you scroll the tabs. You can even attach a scrollbar to the container. <BR> <CODE>.ts configure -scrollcommand { .sbar set } -scrollincrement 20<BR> .sbar configure -orient horizontal -command { .ts view }<BR> </CODE><P>By default tabs are along the top of the container from left to right. But tabs can be placed on any side of the container using the <B>-side</B> option. <BR> <CODE># Arrange tabs along the right side of the container. <BR> .ts configure -side right -rotate 270<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Syntax</A></H2> The <B>container</B> command creates a new window using the <I>pathName</I> argument and makes it into a container widget. <BR> <CODE><B>container <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>Additional options may be specified on the command line or in the option database to configure aspects of the container such as its colors, font, text, and relief. The <B>container</B> command returns its <I>pathName</I> argument. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. <P> When first created, a new container contains no tabs. Tabs are added or deleted using widget operations described below. It is not necessary for all the tabs to be displayed in the container window at once; commands described below may be used to change the view in the window. Containers allow scrolling of tabs using the <B>-scrollcommand</B> option. They also support scanning (see the <B>scan</B> operation). Tabs may be arranged along any side of the container window using the <B>-side</B> option. <P> The size of the container window is determined the number of tiers of tabs and the sizes of the Tk widgets embedded inside each folder. The widest widget determines the width of the folder. The tallest determines the height. If no folders contain an embedded widget, the size is detemined solely by the size of the tabs. <P> You can override either dimension with the container's <B>-width</B> and <B>-height</B> options. <H2><A NAME="sect6" HREF="#toc6">Container Operations</A></H2> All <B>container</B> operations are invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: <P> <BR> <CODE><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<I>pathName operation </I>?<I>arg arg ...</I>?<BR> <P> </CODE><P><I>Operation</I> and the <I>arg</I>s determine the exact behavior of the command. The following operations are available for container widgets: <DL> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the border color of the container. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines how the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-command <I>pattern</I></B> </DT> <DD>Specifies to search for a window whose <I>WM_COMMAND</I> property matches the given pattern. If no windows, or more than one window, matches the pattern, an error is generated. If <I>pattern</I> is the empty string, then no command search is performed. The default is <I>""</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. If <I>pixels</I> is 0, then the height is height the embedded window plus the specified borderwidth. The default is <I>0</I>. </DD> <DT><B>-highlightbackground <I>color</I></B> </DT> <DD>Sets the color to display in the traversal highlight region when the container does not have the input focus. </DD> <DT><B>-highlightcolor <I>color</I></B> </DT> <DD>Sets the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus. The default is <I>black</I>. </DD> <DT><B>-highlightthickness <I>pixels</I></B> </DT> <DD>Sets the width of the highlight rectangle to draw around the outside of the widget when it has the input focus. <I>Pixels</I> is a non-negative value and may have any of the forms acceptable to <B>Tk_GetPixels</B>. If the value is zero, no focus highlight is drawn around the widget. The default is <I>2</I>. </DD> <DT><B>-name <I>pattern</I></B> </DT> <DD>Specifies to search for a window whose <I>WM_NAME</I> property matches the given pattern. If no windows, or more than one window, matches the pattern, an error is generated. If <I>pattern</I> is the empty string, then no name search is performed. The default is <I>""</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the container widget. <I>Relief</I> specifies how the container should appear relative to widget that it is packed into; for example, <I>raised</I> means the container should appear to protrude. The default is <I>sunken</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts decide whether to focus on the window. The default is <I>1</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. If <I>pixels</I> is 0, then the width is the width the embedded window and the specified borderwidth. The default is <I>0</I>. </DD> <DT><B>-window <I>id</I></B> </DT> <DD>Specifies the foreign embedded using its X window id. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>find <B>-command</B></B></I>|<B>-name</B> <I>pattern</I> </DT> <DD>Searches for all windows that match the given pattern. If the <B>-command</B> switch is given, all windows whose WWM_COMMAND property match <I>pattern</I> are returned in a list. If the <B>-name</B> switch is given, all windows whose WWM_NAME property match <I>pattern</I> are returned in a list. The list returned will contains pairs of the window id and the matching property. </DD> </DL> <H2><A NAME="sect7" HREF="#toc7">Keywords</A></H2> container, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">Container Operations</A></LI> <LI><A NAME="toc7" HREF="#sect7">Keywords</A></LI> </UL> </BODY></HTML> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/beep.html��������������������������������������������������������������������0000644�0001750�0001750�00000002750�11462120062�015007� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>beep(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> beep - ring the bell <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>beep</B> ?<I>percent</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>beep</B> command rings the keyboard bell. <I>Percent</I> is relative to the base volume of the keyboard bell and can range from -100 to 100 inclusive. <P> If <I>percent</I> is nonnegative then the bell volume is: <BR> <CODE>base - [(base * <I>percent</I>) / 100] + <I>percent</I><BR> </CODE><P>If <I>percent</I> is negative then the bell volume is: <BR> <CODE>base + [(base * <I>percent</I>) / 100]<BR> </CODE><P>The default <I>percent</I> is 50. <H2><A NAME="sect3" HREF="#toc3">Example</A></H2> <BR> <CODE>beep<BR> <H2><A NAME="sect4" HREF="#toc4"></CODE><P>Keywords</A></H2> bell, beep <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Example</A></LI> <LI><A NAME="toc4" HREF="#sect4">Keywords</A></LI> </UL> </BODY></HTML> ������������������������./saods9/blt3.0.1/html/treeview.html����������������������������������������������������������������0000644�0001750�0001750�00000300506�11462120062�015726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>treeview(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> treeview - Create and manipulate hierarchical table widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>treeview</B> <I>pathName </I>?<I>options</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>treeview</B> widget displays a tree of data. It replaces both the <B>hiertable</B> and <B>hierbox</B> widgets. The <B>treeview</B> is 100% syntax compatible with the <B>hiertable</B> widget. The <B>hiertable</B> command is retained for sake of script-level compatibility. This widget obsoletes the <B>hierbox</B> widget. It does everything the old <B>hierbox</B> widget did, but also provides data sharing (via <I>tree data objects</I>) and the ability to tag nodes. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>treeview</B> widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. <P> A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is <I>open</I>, its children are exposed. When it is <I>closed</I>, the children and their descedants are hidden. The button is normally a <I>+</I> or <I>-</I> symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). <P> If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. <H2><A NAME="sect4" HREF="#toc4">Tree Data Object</A></H2> The tree is not stored inside the widget but in a tree data object (see the <B>tree</B> command for a further explanation). Tree data objects can be shared among different clients, such as a <B>treeview</B> widget or the <B>tree</B> command. You can walk the tree and manage its data with the <B>tree</B> command tree, while displaying it with the <B>treeview</B> widget. Whenever the tree is updated, the <B>treeview</B> widget is automatically redrawn. <P> By default, the <B>treeview</B> widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the <B>tree</B> command using the <B>-tree</B> configuration option. <B>Treeview</B> widgets can share the same tree object, possibly displaying different views of the same data. <P> A tree object has both a Tcl and C API. You can insert or delete nodes using <B>treeview</B> widget or <B>tree</B> command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. <H2><A NAME="sect5" HREF="#toc5">Syntax</A></H2> <BR> <P> <CODE><B>treeview <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>treeview</B> command creates a new window <I>pathName</I> and makes it into a <B>treeview</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the <B>configure</B> operation below for the exact details about what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>treeview</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available are described in the <FONT SIZE=-1><B>TREEVIEW OPERATIONS</B></FONT> section. <H2><A NAME="sect6" HREF="#toc6">IDs and Tags</A></H2> Nodes can be inserted into a tree using the <B>treeview</B> widget <BR> <CODE>blt::treeview .t<BR> set node [.t insert end root "one"]<BR> </CODE><P>or <B>tree</B> command. <BR> <CODE>set tree [blt::tree create]<BR> set node [$tree insert root "one"]<BR> </CODE><P>In both cases, a number identifying the node is returned (the value of <I>$node</I>). This serial number or <I>id</I> uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id <I>0</I>. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the <B>treeview</B> widget or the <B>tree</B> command. Ids are recycled when the node deleted. <P> A node may also have any number of <I>tags</I> associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "<I>x123</I>" is valid, but "<I>123</I>" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the <B>treeview</B> widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. <P> The tag <B>all</B> is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. <P> Tags may be shared, just like trees, between clients. For example, you can use the tags created by the <B>tree</B> command with <B>treeview</B> widgets. <H2><A NAME="sect7" HREF="#toc7">Special Node IDs</A></H2> There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the <B>treeview</B> widget. <DL> <DT><B>active</B> </DT> <DD>The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the <B>-activeicon</B> option). The <B>active</B> id is changed automatically by moving the mouse pointer over another node or by using the <B>entry activate</B> operation. Note that there can be only one active node at a time. </DD> <DT><B>anchor</B> </DT> <DD>The node representing the fixed end of the current selection. The anchor is set by the <B>selection anchor</B> operation. </DD> <DT><B>current</B> </DT> <DD>The node where the mouse pointer is currently located. But unlike <B>active</B>, this id changes while the selection is dragged. It is used to determine the current node during button drags. </DD> <DT><B>down</B> </DT> <DD>The next open node from the current focus. The <B>down</B> of the last open node is the same. </DD> <DT><B>end</B> </DT> <DD>The last open node (in depth-first order) on the tree. </DD> <DT><B>focus</B> </DT> <DD>The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the <B>focus</B> operation. </DD> <DT><B>last</B> </DT> <DD>The last open node from the current focus. But unlike <B>up</B>, when the focus is at root, <B>last</B> wraps around to the last open node in the tree. </DD> <DT><B>mark</B> </DT> <DD>The node representing the non-fixed end of the current selection. The mark is set by the <B>selection mark</B> operation. </DD> <DT><B>next</B> </DT> <DD>The next open node from the current focus. But unlike <B>down</B>, when the focus is on last open node, <B>next</B> wraps around to the root node. </DD> <DT><B>nextsibling</B> </DT> <DD>The next sibling from the node with the current focus. If the node is already the last sibling then it is the <B>nextsibling<B>. </DD> <DT><B>parent</B></B></B> </DT> <DD>The parent of the node with the current focus. The <B>parent</B> of the root is also the root. </DD> <DT><B>prevsibling</B> </DT> <DD>The previous sibling from the node with the current focus. If the node is already the first sibling then it is the <B>prevsibling<B>. </DD> <DT><B>root</B></B></B> </DT> <DD>The root node. You can also use id <I>0</I> to indicate the root. </DD> <DT><B>up</B> </DT> <DD>The last open node (in depth-first order) from the current focus. The <B>up</B> of the root node (i.e. the root has focus) is also the root. </DD> <DT><B>view.top</B> </DT> <DD>First node that's current visible in the widget. </DD> <DT><B>view.bottom</B> </DT> <DD>Last node that's current visible in the widget. </DD> <DT><I>path</I> </DT> <DD>Absolute path of a node. Path names refer to the node name, not their entry labels. Paths don't have to start with a separator (see the <B>-separator</B> configuration option), but component names must be separated by the designated separator. </DD> <DT><B>@<I>x<B>,<I>y</I></B></I></B> </DT> <DD>Indicates the node that covers the point in the treeview window specified by <I>x</I> and <I>y</I> (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. </DD> </DL> <P> A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. <H2><A NAME="sect8" HREF="#toc8">Data Fields</A></H2> A node in the tree can have <I>data fields</I>. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the <B>treeview</B> widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. <H2><A NAME="sect9" HREF="#toc9">Entry Bindings</A></H2> You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its <I>bindtags</I>. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag <I>all</I> that all node entries automatically have. <H2><A NAME="sect10" HREF="#toc10">Treeview Operations</A></H2> The <B>treeview</B> operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: <P> <BR> <CODE><I>pathName operation </I>?<I>arg arg ...</I>?<BR> <P> </CODE><P><I>Operation</I> and the <I>arg</I>s determine the exact behavior of the command. The following operation are available for <B>treeview</B> widgets: <DL> <DT><I>pathName <B>bbox</B></I> ?<B>-screen</B>? <I>tagOrId...</I> </DT> <DD>Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more <I>tagOrId</I> arguments. If the <B>-screen</B> flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from <I>0</I> from the root node. The returned list contains the following values. <blockquote></DD> <DT><I>x</I> </DT> <DD>X-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>y</I> </DT> <DD>Y-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>width</I> </DT> <DD>Width of the bounding box. </DD> <DT><I>height</I> </DT> <DD>Height of the bounding box. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a node with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> entries, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This command is used to control the button selectors within a <B>treeview</B> widget. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>button activate</B></I> <I>tagOrId</I> </DT> <DD>Designates the node given by <I>tagOrId</I> as active. When a node is active it's entry is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active entry at a time. The special id <B>active</B> indicates the currently active node. </DD> <DT><I>pathName <B>button bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an button of a node entry with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> buttons, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>button configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>BUTTON OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>close </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Closes the node specified by <I>tagOrId</I>. In addition, if a Tcl script was specified by the <B>-closecommand</B> option, it is invoked. If the node is already closed, this command has no effect. If the <B>-recurse</B> flag is present, each child node is recursively closed. </DD> <DT><I>pathName <B>column <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview columns. <blockquote></DD> <DT><I>pathName <B>column activate</B></I> <I>column</I> </DT> <DD>Sets the active column to <I>column</I>. <I>Column</I> is the name of a column in the widget. When a column is active, it's drawn using its <B>-activetitlebackground</B> and <B>-activetitleforeground</B> options. If <I>column</I> is the <I>""</I>, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. </DD> <DT><I>pathName <B>column cget</B></I> <I>name</I> <I>option</I> </DT> <DD>Returns the current value of the column configuration option given by <I>option</I> for <I>name</I>. <I>Name</I> is the name of column that corresponds to a data field. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>column configure</B></I> <I>name</I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the column designated by <I>name</I>. <I>Name</I> is the name of the column corresponding to a data field. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>COLUMN OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>column delete</B></I> <I>field</I> ?<I>field</I>...? </DT> <DD>Deletes one of more columns designated by <I>field</I>. Note that this does not delete the data fields themselves. </DD> <DT><I>pathName <B>column insert</B></I> <I>position</I> <I>field</I> ?<I>options</I>...? </DT> <DD>Inserts one of more columns designated by <I>field</I>. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. <I>Position</I> indicates where in the list of columns to add the new column. It may be either a number or <I>end</I>. </DD> <DT><I>pathName <B>column invoke</B></I> <I>field</I> </DT> <DD>Invokes the Tcl command associated with the column <I>field</I>, if there is one (using the column's <B>-command</B> option). The command is ignored if the column's <B>-state</B> option set to <I>disabled</I>. </DD> <DT><I>pathName <B>column move <I>name</I></B></I> <I>dest</I> </DT> <DD>Moves the column <I>name</I> to the destination position. <I>Dest</I> is the name of another column or a screen position in the form <I>@<I>x<I>,<I>y</I></I></I></I>. </DD> <DT><I>pathName <B>column names</B></I> </DT> <DD>Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. </DD> <DT><I>pathName <B>column nearest</B></I> <I>x</I> ?<I>y</I>? </DT> <DD>Returns the name of the column closest to the given X-Y screen coordinate. If you provide a <I>y</I> argument (it's optional), a name is returned only when if the point is over a column's title. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TREEVIEW OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>curselection</B></I> </DT> <DD>Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. </DD> <DT><I>pathName <B>delete <I>tagOrId</I></B></I>... </DT> <DD>Deletes one or more entries given by <I>tagOrId</I> and its children. </DD> <DT><I>pathName <B>entry <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview entries. <blockquote></DD> <DT><I>pathName <B>entry activate</B></I> <I>tagOrId</I> </DT> <DD>Sets the active entry to the one specified by <I>tagOrId</I>. When an entry is active it is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active node at a time. The special id of the currently active node is <B>active</B>. </DD> <DT><I>pathName <B>entry cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>entry children</B></I> <I>tagOrId</I> ?<I>first</I>? ?<I>last</I>? </DT> <DD>Returns a list of ids for the given range of children of <I>tagOrId</I>. <I>TagOrId</I> is the id or tag of the node to be examined. If only a <I>first</I> argument is present, then the id of the that child at that numeric position is returned. If both <I>first</I> and <I>last</I> arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. </DD> <DT><I>pathName <B>entry configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: </DD> <DT><I>pathName <B>entry delete</B></I> <I>tagOrId</I> ?<I>first</I> ?<I>last</I>? </DT> <DD>Deletes the one or more children nodes of the parent <I>tagOrId</I>. If <I>first</I> and <I>last</I> arguments are present, they are positions designating a range of children nodes to be deleted. </DD> <DT><I>pathName <B>entry isbefore <I>tagOrId1</I></B></I> <I>tagOrId2</I> </DT> <DD>Returns 1 if <I>tagOrId1</I> is before <I>tagOrId2</I> and 0 otherwise. </DD> <DT><I>pathName <B>entry ishidden <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. </DD> <DT><I>pathName <B>entry isopen <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently open and 0 otherwise. </DD> <DT><I>pathName <B>entry size</B></I> <B>-recurse</B> <I>tagOrId</I> </DT> <DD>Returns the number of children for parent node <I>tagOrId</I>. If the <B>-recurse</B> flag is set, the number of all its descendants is returned. The node itself is not counted. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>find </B></I>?<I>flags</I>? <I>first</I> <I>last</I> </DT> <DD>Finds for all entries matching the criteria given by <I>flags</I>. A list of ids for all matching nodes is returned. <I>First</I> and <I>last</I> are ids designating the range of the search in depth-first order. If <I>last</I> is before <I>first</I>, then nodes are searched in reverse order. The valid flags are: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Patterns must match exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Pick entries that don't match. </DD> <DT><B>-exec<I> string</I></B> </DT> <DD>Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-count<I> number</I></B> </DT> <DD>Stop searching after <I>number</I> matches. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>focus </B></I> <I>tagOrId</I> </DT> <DD>Sets the focus to the node given by <I>tagOrId</I>. When a node has focus, it can receive keyboard events. The special id <B>focus</B> designates the node that currently has focus. </DD> <DT><I>pathName <B>get </B></I>?<B>-full</B>? <I>tagOrId</I> <I>tagOrId</I>... </DT> <DD>Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the <B>-full</B> flag is set, then the full pathnames are returned. </DD> <DT><I>pathName <B>hide </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Hides all nodes matching the criteria given by <I>flags</I>. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Hide nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>index </B></I>?<B>-at</B> <I>tagOrId</I>? <I>string</I> </DT> <DD>Returns the id of the node specified by <I>string</I>. <I>String</I> may be a tag or node id. Some special ids are normally relative to the node that has focus. The <B>-at</B> flag lets you select another node. </DD> <DT><I>pathName <B>insert </B></I>?<B>-at <I>tagOrId</I></B>? <I>position</I> <I>path</I> ?<I>options...</I>? ?<I>path</I>? ?<I>options...</I>? </DT> <DD>Inserts one or more nodes at <I>position</I>. <I>Position</I> is the location (number or <I>end</I>) where the new nodes are added to the parent node. <I>Path</I> is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the <B>-separator</B> option). Pathnames are normally absolute, but the <B>-at</B> switch lets you select a relative starting point. Its value is the id of the starting node. <P> All ancestors of the new node must already exist, unless the <B>-autocreate</B> option is set. It is also an error if a node already exists, unless the <B>-allowduplicates</B> option is set. <P> <I>Option</I> and <I>value</I> may have any of the values accepted by the <B>entry configure</B> operation described in the <FONT SIZE=-1><B>ENTRY OPERATIONS</B></FONT> section below. This command returns a list of the ids of the new entries. </DD> <DT><I>pathName <B>move <I>tagOrId</I></B></I> <I>how</I> <I>destId</I> </DT> <DD>Moves the node given by <I>tagOrId</I> to the destination node. The node can not be an ancestor of the destination. <I>DestId</I> is the id of the destination node and can not be the root of the tree. In conjunction with <I>how</I>, it describes how the move is performed. <blockquote></DD> <DT><I>before</I> </DT> <DD>Moves the node before the destination node. </DD> <DT><I>after</I> </DT> <DD>Moves the node after the destination node. </DD> <DT><I>into</I> </DT> <DD>Moves the node to the end of the destination's list of children. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>nearest <I>x y</I></B></I> ?<I>varName</I>? </DT> <DD>Returns the id of the node entry closest to the given X-Y screen coordinate. The optional argument <I>varName</I> is the name of variable which is set to either <I>button</I> or <I>select</I> to indicate over what part of the node the coordinate lies. If the coordinate is not directly over any node, then <I>varName</I> will contain the empty string. </DD> <DT><I>pathName <B>open </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Opens the one or more nodes specified by <I>tagOrId</I>. If a node is not already open, the Tcl script specified by the <B>-opencommand</B> option is invoked. If the <B>-recurse</B> flag is present, then each descendant is recursively opened. </DD> <DT><I>pathName <B>range</B></I> ?<B>-open</B>? <I>first last</I> </DT> <DD>Returns the ids in depth-first order of the nodes between the <I>first</I> and <I>last</I> ids. If the <B>-open</B> flag is present, it indicates to consider only open nodes. If <I>last</I> is before <I>first</I>, then the ids are returned in reverse order. </DD> <DT><I>pathName <B>scan</B></I> <I>option args</I> </DT> <DD>This command implements scanning. It has two forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>scan mark <I>x y</I></B></I> </DT> <DD>Records <I>x</I> and <I>y</I> and the current view in the treeview window; used in conjunction with later <B>scan dragto</B> commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. </DD> <DT><I>pathName <B>scan dragto <I>x y</I></B></I>. </DT> <DD>Computes the difference between its <I>x</I> and <I>y</I> arguments and the <I>x</I> and <I>y</I> arguments to the last <B>scan mark</B> command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>see</B></I> ?<B>-anchor <I>anchor</I></B>? <I>tagOrId</I> </DT> <DD>Adjusts the view of entries so that the node given by <I>tagOrId</I> is visible in the widget window. It is an error if <B>tagOrId</B> is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the <B>-anchor</B> flag. Its value is a Tk anchor position. </DD> <DT><I>pathName <B>selection <I>option arg</I></B></I> </DT> <DD>This command is used to adjust the selection within a <B>treeview</B> widget. It has several forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>selection anchor <I>tagOrId</I></B></I> </DT> <DD>Sets the selection anchor to the node given by <I>tagOrId</I>. If <I>tagOrId</I> refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>anchor</B> may be used to refer to the anchor node. </DD> <DT><I>pathName <B>selection cancel</B></I> </DT> <DD>Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the <B>selection mark</B> operation. </DD> <DT><I>pathName <B>selection clear <I>first </I></B></I>?<I>last</I>? </DT> <DD>Removes the entries between <I>first</I> and <I>last</I> (inclusive) from the selection. Both <I>first</I> and <I>last</I> are ids representing a range of entries. If <I>last</I> isn't given, then only <I>first</I> is deselected. Entries outside the selection are not affected. </DD> <DT><I>pathName <B>selection clearall</B></I> </DT> <DD>Clears the entire selection. </DD> <DT><I>pathName <B>selection mark <I>tagOrId</I></B></I> </DT> <DD>Sets the selection mark to the node given by <I>tagOrId</I>. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>mark</B> may be used to refer to the current mark node. If <I>tagOrId</I> refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. </DD> <DT><I>pathName <B>selection includes <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node given by <I>tagOrId</I> is currently selected, 0 if it isn't. </DD> <DT><I>pathName <B>selection present</B></I> </DT> <DD>Returns 1 if any nodes are currently selected and 0 otherwise. </DD> <DT><I>pathName <B>selection set <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects all of the nodes in the range between <I>first</I> and <I>last</I>, inclusive, without affecting the selection state of nodes outside that range. </DD> <DT><I>pathName <B>selection toggle <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects/deselects nodes in the range between <I>first</I> and <I>last</I>, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>show </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Exposes all nodes matching the criteria given by <I>flags</I>. This is the inverse of the <B>hide</B> operation. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD><B>-glob</B> Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Expose nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>sort</B></I> ?<I>operation</I>? <I>args...</I> </DT> <DD><blockquote></DD> <DT><I>pathName <B>sort auto</B></I> ?<I>boolean</I> </DT> <DD>Turns on/off automatic sorting of node entries. If <I>boolean</I> is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no <I>boolean</I> argument is provided, the current state is returned. </DD> <DT><I>pathName <B>sort cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>sort configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the sorting configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: <blockquote></DD> <DT><B>-column<I> string</I></B> </DT> <DD>Specifies the column to sort. Entries in the widget are rearranged according to this column. If <I>column</I> is <I>""</I> then no sort is performed. </DD> <DT><B>-command<I> string</I></B> </DT> <DD>Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. </DD> <DT><B>-decreasing<I> boolean</I></B> </DT> <DD>Indicates to sort in ascending/descending order. If <I>boolean</I> is true, then the entries as in descending order. The default is <I>no</I>. </DD> <DT><B>-mode<I> string</I></B> </DT> <DD>Specifies how to compare entries when sorting. <I>String</I> may be one of the following: <blockquote></DD> <DT><I>ascii</I> </DT> <DD>Use string comparison based upon the ASCII collation order. </DD> <DT><I>dictionary</I> </DT> <DD>Use dictionary-style comparison. This is the same as <I>ascii</I> except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". </DD> <DT><I>integer</I> </DT> <DD>Compares fields as integers. </DD> <DT><I>real</I> </DT> <DD>Compares fields as floating point numbers. </DD> <DT><I>command</I> </DT> <DD>Use the Tcl proc specified by the <B>-command</B> option to compare entries when sorting. If no command is specified, the sort reverts to <I>ascii</I> sorting. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>sort once</B></I> ?<I>flags</I>? <I>tagOrId...</I> </DT> <DD>Sorts the children for each entries specified by <I>tagOrId</I>. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. <blockquote></DD> <DT><B>-recurse</B> </DT> <DD>Recursively sort the entire branch, not just the children. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>tag <I>operation args</I></B></I> </DT> <DD>Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. <P> Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for tags are listed below. <blockquote></DD> <DT><I>pathName</I> <B>tag add</B> <I>string</I> <I>id</I>... </DT> <DD>Adds the tag <I>string</I> to one of more entries. </DD> <DT><I>pathName</I> <B>tag delete</B> <I>string</I> <I>id</I>... </DT> <DD>Deletes the tag <I>string</I> from one or more entries. </DD> <DT><I>pathName</I> <B>tag forget</B> <I>string</I> </DT> <DD>Removes the tag <I>string</I> from all entries. It's not an error if no entries are tagged as <I>string</I>. </DD> <DT><I>pathName</I> <B>tag names</B> ?<I>id</I>? </DT> <DD>Returns a list of tags used. If an <I>id</I> argument is present, only those tags used by the node designated by <I>id</I> are returned. </DD> <DT><I>pathName</I> <B>tag nodes</B> <I>string</I> </DT> <DD>Returns a list of ids that have the tag <I>string</I>. If no node is tagged as <I>string</I>, then an empty string is returned. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>text apply</B></I> </DT> <DD>Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. </DD> <DT><I>pathName <B>text cancel</B></I> </DT> <DD>Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. </DD> <DT><I>pathName <B>text cget<I> value</I></B></I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>text configure</B></I> ?<I>option value</I>? </DT> <DD>Query or modify the configuration options of the edit window. If no <I>option</I> is specified, returns a list describing all of the available options (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TEXT EDITING OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text delete<I> first last</I></B></I> </DT> <DD>Deletes the characters in the edit buffer between the two given character positions. </DD> <DT><I>pathName <B>text get</B></I> ?<I>-root</I>? <I>x y</I> </DT> <DD></DD> <DT><I>pathName <B>text icursor<I> index</I></B></I> </DT> <DD></DD> <DT><I>pathName <B>text index<I> index</I></B></I> </DT> <DD>Returns the text index of given <I>index</I>. </DD> <DT><I>pathName <B>text insert<I> index string</I></B></I> </DT> <DD>Insert the text string <I>string</I> into the edit buffer at the index <I>index</I>. For example, the index 0 will prepend the buffer. </DD> <DT><I>pathName <B>text selection<I> args</I></B></I> </DT> <DD>This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: <blockquote></DD> <DT><I>pathName <B>text selection adjust<I> index</I></B></I> </DT> <DD>Adjusts either the first or last index of the selection. </DD> <DT><I>pathName <B>text selection clear</B></I> </DT> <DD>Clears the selection. </DD> <DT><I>pathName <B>text selection from<I> index</I></B></I> </DT> <DD>Sets the anchor of the selection. </DD> <DT><I>pathName <B>text selection present</B></I> </DT> <DD>Indicates if a selection is present. </DD> <DT><I>pathName <B>text selection range<I> start end</I></B></I> </DT> <DD>Sets both the anchor and mark of the selection. </DD> <DT><I>pathName <B>text selection to<I> index</I></B></I> </DT> <DD>Sets the unanchored end (mark) of the selection. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>toggle <I>tagOrId</I></B></I> </DT> <DD>Opens or closes the node given by <I>tagOrId</I>. If the corresponding <B>-opencommand</B> or <B>-closecommand</B> option is set, then that command is also invoked. </DD> <DT><I>pathName <B>xview <I>args</I></B></I> </DT> <DD>This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>xview</B></I> </DT> <DD>Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the <B>treeview</B> widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the <B>-xscrollcommand</B> option. </DD> <DT><I>pathName <B>xview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the character position given by <I>tagOrId</I> is displayed at the left edge of the window. Character positions are defined by the width of the character <B>0</B>. </DD> <DT><I>pathName <B>xview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that <I>fraction</I> of the total width of the <B>treeview</B> widget's text is off-screen to the left. <I>fraction</I> must be a fraction between 0 and 1. </DD> <DT><I>pathName <B>xview scroll <I>number what</I></B></I> </DT> <DD>This command shifts the view in the window left or right according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B> or an abbreviation of one of these. If <I>what</I> is <B>units</B>, the view adjusts left or right by <I>number</I> character units (the width of the <B>0</B> character) on the display; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>yview <I>?args</I></B></I>? </DT> <DD>This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>yview</B></I> </DT> <DD>Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the <B>-yscrollcommand</B> option. </DD> <DT><I>pathName <B>yview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the node given by <I>tagOrId</I> is displayed at the top of the window. </DD> <DT><I>pathName <B>yview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that the node given by <I>fraction</I> appears at the top of the window. <I>Fraction</I> is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the <B>treeview</B> widget, and so on. </DD> <DT><I>pathName <B>yview scroll <I>number what</I></B></I> </DT> <DD>This command adjusts the view in the window up or down according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B>. If <I>what</I> is <B>units</B>, the view adjusts up or down by <I>number</I> lines; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then earlier nodes become visible; if it is positive then later nodes become visible. </DD> </DL> </blockquote> <H2><A NAME="sect11" HREF="#toc11">Treeview Options</A></H2> In addition to the <B>configure</B> operation, widget configuration options may also be set by the Tk <B>option</B> command. The class resource name is <I>TreeView</I>. <BR> <CODE>option add *TreeView.Foreground white<BR> option add *TreeView.Background blue<BR> </CODE><P>The following widget options are available: <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed for an entry's icon when it is active. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-autocreate <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-allowduplicates <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the widget. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's <B>-closecommand</B> option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-dashes <I>number</I></B> </DT> <DD>Sets the dash style of the horizontal and vertical lines drawn connecting entries. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, solid lines will be drawn. The default is <I>1</I> (dotted). </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>; the value of the selection will be the label of the selected nodes, separated by newlines. The default is <I>no</I>. </DD> <DT><B>-flat <I>boolean</I></B> </DT> <DD>Indicates whether to display the tree as a flattened list. If <I>boolean</I> is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the <FONT SIZE=-1><B>SORT OPERATIONS</B></FONT> section for more information. The default is <I>no</I>. </DD> <DT><B>-focusdashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, a solid line will be drawn. The default is <I>1</I>. </DD> <DT><B>-focusforeground <I>color</I></B> </DT> <DD>Sets the color of the focus rectangle. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font for entry labels. You can override this for individual entries with the entry's <B>-font</B> configuration option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of entry labels. You can override this for individual entries with the entry's <B>-foreground</B> configuration option. The default is <I>black</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>400</I>. </DD> <DT><B>-hideroot <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, it indicates that no entry for the root node should be displayed. The default is <I>no</I>. </DD> <DT><B>-highlightbackground <I>color</I></B> </DT> <DD>Specifies the normal color of the traversal highlight region when the widget does not have the input focus. </DD> <DT><B>-highlightcolor <I>color</I></B> </DT> <DD>Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is <I>black</I>. </DD> <DT><B>-highlightthickness <I>pixels</I></B> </DT> <DD>Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to <B>Tk_GetPixels</B>. If the value is zero, no focus highlight will be displayed. The default is <I>2</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images for the entry's icon. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-linecolor <I>color</I></B> </DT> <DD>Sets the color of the connecting lines drawn between entries. The default is <I>black</I>. </DD> <DT><B>-linespacing <I>pixels</I></B> </DT> <DD>Sets the number of pixels spacing between entries. The default is <I>0</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the lines drawn connecting entries. If <I>pixels</I> is <I>0</I>, no vertical or horizontal lines are drawn. The default is <I>1</I>. </DD> <DT><B>-newtags <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, when sharing a tree object (see the <B>-tree</B> option), don't share its tags too. The default is <I>0</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's <B>-opencommand</B> configuration option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the widget. <I>Relief</I> specifies how the <B>treeview</B> widget should appear relative to widget it is packed into; for example, <I>raised</I> means the <B>treeview</B> widget should appear to protrude. The default is <I>sunken</I>. </DD> <DT><B>-scrollmode <I>mode</I></B> </DT> <DD>Specifies the style of scrolling to be used. The following styles are valid. This is the default is <I>hierbox</I>. <blockquote></DD> <DT><I>listbox</I> </DT> <DD>Like the <B>listbox</B> widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. </DD> <DT><I>hierbox</I> </DT> <DD>Like the <B>hierbox</B> widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. </DD> <DT><I>canvas</I> </DT> <DD>Like the <B>canvas</B> widget, the entries are bound within the scrolling area. </DD> </DL> </blockquote> <DL> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background color selected node entries. The default is <I>#ffffea</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is <I>0</I>. <B>-selectcommand <I>string</I></B> Specifies a Tcl script to invoked when the set of selected nodes changes. The default is <I>""</I>. </DD> <DT><B>-selectforeground <I>color<B> </B></I></B></DT> <DD>Sets the color of the labels of selected node entries. The default is <I>black</I>. </DD> <DT><B>-selectmode <I>mode</I></B> </DT> <DD>Specifies the selection mode. If <I>mode</I> is <I>single</I>, only one node can be selected at a time. If <I>multiple</I> more than one node can be selected. The default is <I>single</I>. </DD> <DT><B>-separator <I>string</I></B> </DT> <DD>Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If <I>string</I> is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is <I>""</I>. </DD> <DT><B>-showtitles <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is false, column titles are not be displayed. The default is <I>yes</I>. </DD> <DT><B>-sortselection <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is <I>no</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>"1"</I>. </DD> <DT><B>-trim <I>string</I></B> </DT> <DD>Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the <B>-separator</B> is also set. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the widget. If <I>pixels</I> is 0, then the with is computed from the contents of the <B>treeview</B> widget. The default is <I>200</I>. </DD> <DT><B>-xscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-xscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the horizontal scrolling distance. The default is 20 pixels. </DD> <DT><B>-yscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-yscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the vertical scrolling distance. The default is 20 pixels. </DD> </DL> <H2><A NAME="sect12" HREF="#toc12">Entry Options</A></H2> Many widget configuration options have counterparts in entries. For example, there is a <B>-closecommand</B> configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. <P> There is no resource class or name for entries. <DL> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed as the entry's icon when it is active. This overrides the global <B>-activeicons</B> configuration option for the specific entry. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for nodes. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is <I>all</I>. </DD> <DT><B>-button <I>string</I></B> </DT> <DD>Indicates whether a button should be displayed on the left side of the node entry. <I>String</I> can be <I>yes</I>, <I>no</I>, or <I>auto</I>. If <I>auto</I>, then a button is automatically displayed if the node has children. This is the default. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the node is closed. This overrides the global <B>-closecommand</B> option for this entry. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-data <I>string</I></B> </DT> <DD>Sets data fields for the node. <I>String</I> is a list of name-value pairs to be set. The default is <I>""</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for entry labels. This overrides the widget's <B>-font</B> option for this node. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of the entry label. This overrides the widget's <B>-foreground</B> configuration option. The default is <I>""</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images to be displayed for the entry's icon. This overrides the global <B>-icons</B> configuration option. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-label <I>string</I></B> </DT> <DD>Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is <I>""</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's <B>-opencommand</B> option for this node. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <H2><A NAME="sect13" HREF="#toc13">Button Options</A></H2> Button configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Button</I>. The resource name is always <I>button</I>. <BR> <CODE>option add *TreeView.Button.Foreground white<BR> option add *TreeView.button.Background blue<BR> </CODE><P>The following are the configuration options available for buttons. <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the button. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the button. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-closerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the closed button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Sets the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of buttons. The default is <I>black</I>. </DD> <DT><B>-images <I>images</I></B> </DT> <DD>Specifies images to be displayed for the button. <I>Images</I> is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the <I>images</I> is the empty string, then a plus/minus gadget is drawn. The default is <I>""</I>. </DD> <DT><B>-openrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the open button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-size <I>pixels</I></B> </DT> <DD>Sets the requested size of the button. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect14" HREF="#toc14">Column Options</A></H2> Column configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Column</I>. The resource name is the name of the column. <BR> <CODE>option add *TreeView.Column.Foreground white<BR> option add *TreeView.treeView.Background blue<BR> </CODE><P>The following configuration options are available for columns. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the column. This overrides the widget's <B>-background</B> option. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border of the column. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>0</I>. </DD> <DT><B>-edit <I>boolean</I></B> </DT> <DD>Indicates if the column's data fields can be edited. If <I>boolean</I> is false, the data fields in the column may not be edited. The default is <I>yes</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Specifies the foreground color of the column. You can override this for individual entries with the entry's <B>-foreground</B> option. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for a column. You can override this for individual entries with the entry's <B>-font</B> option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the column is not displayed. The default is <I>yes</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>left</I>. </DD> <DT><B>-pad <I>pad</I></B> </DT> <DD>Specifies how much padding for the left and right sides of the column. <I>Pad</I> is a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the column is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the column. <I>Relief</I> specifies how the column should appear relative to the widget; for example, <I>raised</I> means the column should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-state <I>state</I></B> </DT> <DD>Sets the state of the column. If <I>state</I> is <I>disable</I> then the column title can not be activated nor invoked. The default is <I>normal</I>. </DD> <DT><B>-text <I>string</I></B> </DT> <DD>Sets the title for the column. The default is <I>""</I>. </DD> <DT><B>-titleforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the column title. The default is <I>black</I>. </DD> <DT><B>-titleshadow <I>color</I></B> </DT> <DD>Sets the color of the drop shadow of the column title. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the column. This overrides the computed with of the column. If <I>pixels</I> is 0, the width is computed as from the contents of the column. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect15" HREF="#toc15">Text Editing Options</A></H2> Text edit window configuration options may also be set by the <B>option</B> command. The resource class is <I>TreeViewEditor</I>. The resource name is always <I>edit</I>. <BR> <CODE>option add *TreeViewEditor.Foreground white<BR> option add *edit.Background blue<BR> </CODE><P>The following are the configuration options available for the text editing window. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the text edit window. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the edit window. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the edit window. <I>Relief</I> indicates how the background should appear relative to the edit window; for example, <I>raised</I> means the background should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the selected text in the edit window. The <B>-selectrelief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-selectforeground <I>color</I></B> </DT> <DD>Sets the foreground of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the selected text in the edit window. <I>Relief</I> indicates how the text should appear relative to the edit window; for example, <I>raised</I> means the text should appear to protrude. The default is <I>flat</I>. </DD> </DL> </blockquote> <H2><A NAME="sect16" HREF="#toc16">Default Bindings</A></H2> Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a <B>treeview</B> widget is determined by its <B>-selectmode</B> option, which selects one of two ways of dealing with the selection. <P> If the selection mode is <B>single</B>, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. <P> If the selection mode is <B>multiple</B>, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. <OL> <LI>In <B>extended</B> mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. </LI><LI>In <B>extended</B> mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. </LI><LI>If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. </LI><LI>Mouse button 2 may be used for scanning. If it is pressed and dragged over the <B>treeview</B> widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. </LI><LI>If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is <B>browse</B> or <B>extended</B> then the new active entry is also selected and all other entries are deselected. In <B>extended</B> mode the new active entry becomes the selection anchor. </LI><LI>In <B>extended</B> mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. </LI><LI>The Left and Right keys scroll the <B>treeview</B> widget view left and right by the width of the character <B>0</B>. Control-Left and Control-Right scroll the <B>treeview</B> widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. </LI><LI>The Prior and Next keys scroll the <B>treeview</B> widget view up and down by one page (the height of the window). </LI><LI>The Home and End keys scroll the <B>treeview</B> widget horizontally to the left and right edges, respectively. </LI><LI>Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. </LI><LI>Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. </LI><LI>In <B>extended</B> mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. </LI><LI>In <B>multiple</B> mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. </LI><LI>The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. </LI><LI>In <B>extended</B> mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. </LI><LI>In <B>extended</B> mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. </LI><LI>Control-slash selects everything in the widget, except in <B>single</B> and <B>browse</B> modes, in which case it selects the active entry and deselects everything else. </LI><LI>Control-backslash deselects everything in the widget, except in <B>browse</B> mode where it has no effect. </LI><LI>The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. </LI> </OL> <P> The behavior of <B>treeview</B> widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. <H3><A NAME="sect17" HREF="#toc17">Widget Bindings</A></H3> In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. <DL> <DT><I>&lt;ButtonPress-2&gt;</I></DT> <DD>Starts scanning. </DD> <DT><I>&lt;B2-Motion&gt;</I></DT> <DD>Adjusts the scan. </DD> <DT><I>&lt;ButtonRelease-2&gt;</I></DT> <DD>Stops scanning. </DD> <DT><I>&lt;B1-Leave&gt;</I></DT> <DD>Starts auto-scrolling. </DD> <DT><I>&lt;B1-Enter&gt;</I></DT> <DD>Starts auto-scrolling </DD> <DT><I>&lt;KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous entry. </DD> <DT><I>&lt;KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next entry. </DD> <DT><I>&lt;Shift-KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous sibling. </DD> <DT><I>&lt;Shift-KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next sibling. </DD> <DT><I>&lt;KeyPress-Prior&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Next&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Left&gt;</I></DT> <DD>Closes the entry. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-Right&gt;</I></DT> <DD>Opens the entry, displaying its children. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-space&gt;</I></DT> <DD>In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). </DD> <DT><I>&lt;KeyRelease-space&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress-Return&gt;</I></DT> <DD>Sets the focus to the current entry. </DD> <DT><I>&lt;KeyRelease-Return&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress&gt;</I></DT> <DD>Moves to the next entry whose label starts with the letter typed. </DD> <DT><I>&lt;KeyPress-Home&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-End&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-F1&gt;</I></DT> <DD>Opens all entries. </DD> <DT><I>&lt;KeyPress-F2&gt;</I></DT> <DD>Closes all entries (except root). </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Button Bindings</A></H3> Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the button of the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the button back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the view so that the current entry is visible. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Entry Bindings</A></H3> Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to modify them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the entry back to its normal state. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the selection anchor the current entry. </DD> <DT><I>&lt;Double-ButtonPress-1&gt;</I></DT> <DD>Toggles the selection of the current entry. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>For "multiple" mode only. Sets the selection anchor to the current entry. </DD> <DT><I>&lt;Shift-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Extends the selection. </DD> <DT><I>&lt;Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-ButtonRelease-1&gt;</I></DT> <DD>Stop auto-scrolling. </DD> <DT><I>&lt;Control-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Toggles and extends the selection. </DD> <DT><I>&lt;Control-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-ButtonRelease-1&gt;</I></DT> <DD>Stops auto-scrolling. </DD> <DT><I>&lt;Control-Shift-ButtonPress-1&gt;</I></DT> <DD>??? </DD> <DT><I>&lt;Control-Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Column Bindings</A></H3> Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the <B>column bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current column title. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Invokes the command (see the column's -command option) if one if specified. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Column Rule Bindings</A></H3> <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current and activates the ruler. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. Deactivates the ruler. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the resize anchor for the column. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>Sets the resize mark for the column. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the size of the column, based upon the resize anchor and mark positions. </DD> </DL> <H2><A NAME="sect22" HREF="#toc22">Example</A></H2> The <B>treeview</B> command creates a new widget. <BR> <CODE>treeview .h -bg white<BR> </CODE><P>A new Tcl command <I>.h</I> is also created. This command can be used to query and modify the <B>treeview</B> widget. For example, to change the background color of the table to "green", you use the new command and the widget's <B>configure</B> operation. <BR> <CODE># Change the background color.<BR> .h configure -background "green"<BR> </CODE><P>By default, the <B>treeview</B> widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the <B>-tree</B> option to specify the name of another tree. <BR> <CODE># View the tree "myTree".<BR> .h configure -tree "myTree"<BR> </CODE><P>When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always <I>0</I> (you can use also use the special id <I>root</I>). The <B>insert</B> operation lets you insert one or more new entries into the tree. The last argument is the node's <I>pathname</I>. <BR> <CODE># Create a new entry named "myEntry"<BR> set id [.h insert end "myEntry"]<BR> </CODE><P>This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. <BR> <CODE># Prepend "fred".<BR> set id [.h insert 0 "fred"]<BR> </CODE><P>Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the <B>-label</B> option. <BR> <CODE># Create a new node named "fred"<BR> set id [.h insert end "fred" -label "Fred Flintstone"]<BR> </CODE><P>The <B>insert</B> operation returns the id of the new node. You can also use the <B>index</B> operation to get this information. <BR> <CODE># Get the id of "fred"<BR> .h index "fred"<BR> </CODE><P>To insert a node somewhere other than root, use the <B>-at</B> switch. It takes the id of the node where the new child will be added. <BR> <CODE># Create a new node "barney" in "fred".<BR> .h insert -at $id end "barney" <BR> </CODE><P>A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. <BR> <CODE># Create a new sub-entry of "fred"<BR> .h insert end "fred barney" <BR> </CODE><P>Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the <B>-autocreate</B> configuration option to force the creation of ancestor nodes. <BR> <CODE># Force the creation of ancestors.<BR> .h configure -autocreate yes <BR> .h insert end "fred barney wilma betty" <BR> </CODE><P>Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the <B>-separator</B> option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. <BR> <CODE>.h configure -separator /<BR> .h insert end "/usr/local/tcl/bin" <BR> </CODE><P>If the path is prefixed by extraneous characters, you can automatically trim it off using the <B>-trim</B> option. It removed the string from the path before it is parsed. <BR> <CODE>.h configure -trim C:/windows -separator /<BR> .h insert end "C:/window/system" <BR> </CODE><P>You can insert more than one entry at a time with the <B>insert</B> operation. This can be much faster than looping over a list of names. <BR> <CODE># The slow way<BR> foreach f [glob $dir/*] {<BR> .h insert end $f<BR> }<BR> # The fast way<BR> eval .h insert end [glob $dir/*]<BR> </CODE><P>In this case, the <B>insert</B> operation will return a list of ids of the new entries. <P> You can delete entries with the <B>delete</B> operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. <BR> <CODE>.h delete $id<BR> </CODE><P>Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the <B>-label</B> option that sets the entry's text label. The <B>entry configure</B> operation lets you set or modify an entry's configuration options. <BR> <CODE>.h entry configure $id -color red -font fixed<BR> </CODE><P>You can hide an entry and its children using the <B>-hide</B> option. <BR> <CODE>.h entry configure $id -hide yes<BR> </CODE><P>More that one entry can be configured at once. All entries specified are configured with the same options. <BR> <CODE>.h entry configure $i1 $i2 $i3 $i4 -color brown <BR> </CODE><P>An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's <B>-icons</B> option. It takes a list of two image names: one to represent the open entry, another when it is closed. <BR> <CODE>set im1 [image create photo -file openfolder.gif]<BR> set im2 [image create photo -file closefolder.gif]<BR> .h entry configure $id -icons "$im1 $im2"<BR> </CODE><P>If <B>-icons</B> is set to the empty string, no icons are display. <P> If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a <I>+</I> or <I>-</I> symbol, but can be configured in a variety of ways using the <B>button configure</B> operation. For example, the <I>+</I> and <I>-</I> symbols can be replaced with Tk images. <BR> <CODE>set im1 [image create photo -file closefolder.gif]<BR> set im2 [image create photo -file downarrow.gif]<BR> .h button configure $id -images "$im1 $im2" \<BR> -openrelief raised -closerelief raised<BR> </CODE><P>Entries can contain an arbitrary number of <I>data fields</I>. Data fields are name-value pairs. Both the value and name are strings. The entry's <B>-data</B> option lets you set data fields. <BR> <CODE>.h entry configure $id -data {mode 0666 group users}<BR> </CODE><P>The <B>-data</B> takes a list of name-value pairs. <P> You can display these data fields as <I>columns</I> in the <B>treeview</B> widget. You can create and configure columns with the <B>column</B> operation. For example, to add a new column to the widget, use the <B>column insert</B> operation. The last argument is the name of the data field that you want to display. <BR> <CODE>.h column insert end "mode"<BR> </CODE><P>The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's <B>-text</B> option. <BR> <CODE>.h column insert end "mode" -text "File Permissions"<BR> </CODE><P>Columns have several configuration options. The <B>column configure</B> operation lets you query or modify column options. <BR> <CODE>.h column configure "mode" -justify left<BR> </CODE><P>The <B>-justify</B> option says how the data is justified within in the column. The <B>-hide</B> option indicates whether the column is displayed. <BR> <CODE>.h column configure "mode" -hide yes<BR> </CODE><P>Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the <B>-selectforeground</B> and <B>-selectbackground</B> configuration options. The selection itself is managed by the <B>selection</B> operation. <BR> <CODE># Clear all selections<BR> .h selection clear 0 end<BR> # Select the root node<BR> .h selection set 0 <BR> </CODE><P>The <B>curselection</B> operation returns a list of ids of all the selected entries. <BR> <CODE>set ids [.h curselection]<BR> </CODE><P>You can use the <B>get</B> operation to convert the ids to their pathnames. <BR> <CODE>set names [eval .h get -full $ids]<BR> </CODE><P>If a treeview is exporting its selection (using the <B>-exportselection</B> option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type <B>STRING</B>; the value of the selection will be the pathnames of the selected entries, separated by newlines. <P> The <B>treeview</B> supports two modes of selection: <I>single</I> and <I>multiple</I>. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -selectmode "multiple"<BR> </CODE><P>You can be notified when the list of selected entries changes. The widget's <B>-selectcommand</B> specifies a Tcl procedure that is called whenever the selection changes. <BR> <CODE>proc SelectNotify { widget } {<BR> set ids [$widget curselection]<BR> }<BR> .h configure -selectcommand "SelectNotify .h"<BR> </CODE><P>The widget supports the standard Tk scrolling and scanning operations. The <B>treeview</B> can be both horizontally and vertically. You can attach scrollbars to the <B>treeview</B> the same way as the listbox or canvas widgets. <BR> <CODE>scrollbar .xbar -orient horizontal -command ".h xview"<BR> scrollbar .ybar -orient vertical -command ".h yview"<BR> .h configure -xscrollcommand ".xbar set" \<BR> -yscrollcommand ".ybar set"<BR> </CODE><P>There are three different modes of scrolling: <I>listbox</I>, <I>canvas</I>, and <I>hierbox</I>. In <I>listbox</I> mode, the last entry can always be scrolled to the top of the widget. In <I>hierbox</I> mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -scrollmode "listbox"<BR> </CODE><P>Entries can be programmatically opened or closed using the <B>open</B> and <B>close</B> operations respectively. <BR> <CODE>.h open $id<BR> .h close $id<BR> </CODE><P>When an entry is opened, a Tcl procedure can be automatically invoked. The <B>-opencommand</B> option specifies this procedure. This procedure can lazily insert entries as needed. <BR> <CODE>proc AddEntries { dir } {<BR> eval .h insert end [glob -nocomplain $dir/*] <BR> }<BR> .h configure -opencommand "AddEntries %P"<BR> </CODE><P>Now when an entry is opened, the procedure <I>AddEntries</I> is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like <B>bind</B>) are performed. Above, <I>%P</I> is translated to the pathname of the entry. <P> The same feature exists when an entry is closed. The <B>-closecommand</B> option specifies the procedure. <BR> <CODE>proc DeleteEntries { id } {<BR> .h entry delete $id 0 end<BR> }<BR> .h configure -closecommand "DeleteEntries %#"<BR> </CODE><P>When an entry is closed, the procedure <I>DeleteEntries</I> is called and deletes the entry's children using the <B>entry delete</B> operation (<I>%#</I> is the id of entry). <H2><A NAME="sect23" HREF="#toc23">Keywords</A></H2> treeview, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Tree Data Object</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">IDs and Tags</A></LI> <LI><A NAME="toc7" HREF="#sect7">Special Node IDs</A></LI> <LI><A NAME="toc8" HREF="#sect8">Data Fields</A></LI> <LI><A NAME="toc9" HREF="#sect9">Entry Bindings</A></LI> <LI><A NAME="toc10" HREF="#sect10">Treeview Operations</A></LI> <LI><A NAME="toc11" HREF="#sect11">Treeview Options</A></LI> <LI><A NAME="toc12" HREF="#sect12">Entry Options</A></LI> <LI><A NAME="toc13" HREF="#sect13">Button Options</A></LI> <LI><A NAME="toc14" HREF="#sect14">Column Options</A></LI> <LI><A NAME="toc15" HREF="#sect15">Text Editing Options</A></LI> <LI><A NAME="toc16" HREF="#sect16">Default Bindings</A></LI> <UL> <LI><A NAME="toc17" HREF="#sect17">Widget Bindings</A></LI> <LI><A NAME="toc18" HREF="#sect18">Button Bindings</A></LI> <LI><A NAME="toc19" HREF="#sect19">Entry Bindings</A></LI> <LI><A NAME="toc20" HREF="#sect20">Column Bindings</A></LI> <LI><A NAME="toc21" HREF="#sect21">Column Rule Bindings</A></LI> </UL> <LI><A NAME="toc22" HREF="#sect22">Example</A></LI> <LI><A NAME="toc23" HREF="#sect23">Keywords</A></LI> </UL> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/bltdebug.html����������������������������������������������������������������0000644�0001750�0001750�00000002566�11462120062�015671� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>bltdebug(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> bltdebug - print Tcl commands before execution <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>bltdebug</B> ?<I>level</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>bltdebug</B> command is a simple tracing facility for Tcl commands. Each command line is printed before it is executed on standard error. The output consists of the command line both before and after substitutions have occurred. <I>Level</I> indicates at what level to stop tracing commands. If <I>level</I> is <I>0</I>, no tracing is performed. This is the default. If no <I>level</I> argument is given, the current level is printed. <H2><A NAME="sect3" HREF="#toc3">Keywords</A></H2> debug <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Keywords</A></LI> </UL> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/vector.html������������������������������������������������������������������0000644�0001750�0001750�00000124726�11462120062�015406� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>vector(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> vector - Vector data type for Tcl <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>vector create <I>vecName </I></B>?<I>vecName</I>...? ?<I>switches</I>? <P> <B>vector destroy <I>vecName </I></B>?<I>vecName</I>...? <P> <B>vector expr <I>expression</I></B> <P> <B>vector names </B>?<I>pattern</I>...? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>vector</B> command creates a vector of floating point values. The vector's components can be manipulated in three ways: through a Tcl array variable, a Tcl command, or the C API. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> A vector is simply an ordered set of numbers. The components of a vector are real numbers, indexed by counting numbers. <P> Vectors are common data structures for many applications. For example, a graph may use two vectors to represent the X-Y coordinates of the data plotted. The graph will automatically be redrawn when the vectors are updated or changed. By using vectors, you can separate data analysis from the graph widget. This makes it easier, for example, to add data transformations, such as splines. It's possible to plot the same data to in multiple graphs, where each graph presents a different view or scale of the data. <P> You could try to use Tcl's associative arrays as vectors. Tcl arrays are easy to use. You can access individual elements randomly by specifying the index, or the set the entire array by providing a list of index and value pairs for each element. The disadvantages of associative arrays as vectors lie in the fact they are implemented as hash tables. <UL> &#183;<LI>There's no implied ordering to the associative arrays. If you used vectors for plotting, you would want to insure the second component comes after the first, an so on. This isn't possible since arrays are actually hash tables. For example, you can't get a range of values between two indices. Nor can you sort an array. </LI>&#183;<LI>Arrays consume lots of memory when the number of elements becomes large (tens of thousands). This is because each element's index and value are stored as strings in the hash table. </LI>&#183;<LI>The C programming interface is unwieldy. Normally with vectors, you would like to view the Tcl array as you do a C array, as an array of floats or doubles. But with hash tables, you must convert both the index and value to and from decimal strings, just to access an element in the array. This makes it cumbersome to perform operations on the array as a whole. </LI> </UL> <P> The <B>vector</B> command tries to overcome these disadvantages while still retaining the ease of use of Tcl arrays. The <B>vector</B> command creates both a new Tcl command and associate array which are linked to the vector components. You can randomly access vector components though the elements of array. Not have all indices are generated for the array, so printing the array (using the <B>parray</B> procedure) does not print out all the component values. You can use the Tcl command to access the array as a whole. You can copy, append, or sort vector using its command. If you need greater performance, or customized behavior, you can write your own C code to manage vectors. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> You create vectors using the <B>vector</B> command and its <B>create</B> operation. <BR> <CODE># Create a new vector. <BR> vector create y(50)<BR> </CODE><P>This creates a new vector named <I>y</I>. It has fifty components, by default, initialized to <I>0.0</I>. In addition, both a Tcl command and array variable, both named <I>y</I>, are created. You can use either the command or variable to query or modify components of the vector. <BR> <CODE># Set the first value. <BR> set y(0) 9.25<BR> puts "y has [y length] components"<BR> </CODE><P>The array <I>y</I> can be used to read or set individual components of the vector. Vector components are indexed from zero. The array index must be a number less than the number of components. For example, it's an error if you try to set the 51st element of <I>y</I>. <BR> <CODE># This is an error. The vector only has 50 components.<BR> set y(50) 0.02<BR> </CODE><P>You can also specify a range of indices using a colon (:) to separate the first and last indices of the range. <BR> <CODE># Set the first six components of y <BR> set y(0:5) 25.2<BR> </CODE><P>If you don't include an index, then it will default to the first and/or last component of the vector. <BR> <CODE># Print out all the components of y <BR> puts "y = $y(:)"<BR> </CODE><P>There are special non-numeric indices. The index <I>end</I>, specifies the last component of the vector. It's an error to use this index if the vector is empty (length is zero). The index <I>++end</I> can be used to extend the vector by one component and initialize it to a specific value. You can't read from the array using this index, though. <BR> <CODE># Extend the vector by one component.<BR> set y(++end) 0.02<BR> </CODE><P>The other special indices are <I>min</I> and <I>max</I>. They return the current smallest and largest components of the vector. <BR> <CODE># Print the bounds of the vector<BR> puts "min=$y(min) max=$y(max)"<BR> </CODE><P>To delete components from a vector, simply unset the corresponding array element. In the following example, the first component of <I>y</I> is deleted. All the remaining components of <I>y</I> will be moved down by one index as the length of the vector is reduced by one. <BR> <CODE># Delete the first component<BR> unset y(0)<BR> puts "new first element is $y(0)"<BR> </CODE><P>The vector's Tcl command can also be used to query or set the vector. <BR> <CODE># Create and set the components of a new vector<BR> vector create x<BR> x set { 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 }<BR> </CODE><P>Here we've created a vector <I>x</I> without a initial length specification. In this case, the length is zero. The <B>set</B> operation resets the vector, extending it and setting values for each new component. <P> There are several operations for vectors. The <B>range</B> operation lists the components of a vector between two indices. <BR> <CODE># List the components <BR> puts "x = [x range 0 end]"<BR> </CODE><P>You can search for a particular value using the <B>search</B> operation. It returns a list of indices of the components with the same value. If no component has the same value, it returns <I>""</I>. <BR> <CODE># Find the index of the biggest component<BR> set indices [x search $x(max)]<BR> </CODE><P>Other operations copy, append, or sort vectors. You can append vectors or new values onto an existing vector with the <B>append</B> operation. <BR> <CODE># Append assorted vectors and values to x<BR> x append x2 x3 { 2.3 4.5 } x4<BR> </CODE><P>The <B>sort</B> operation sorts the vector. If any additional vectors are specified, they are rearranged in the same order as the vector. For example, you could use it to sort data points represented by x and y vectors. <BR> <CODE># Sort the data points<BR> x sort y<BR> </CODE><P>The vector <I>x</I> is sorted while the components of <I>y</I> are rearranged so that the original x,y coordinate pairs are retained. <P> The <B>expr</B> operation lets you perform arithmetic on vectors. The result is stored in the vector. <BR> <CODE># Add the two vectors and a scalar<BR> x expr { x + y }<BR> x expr { x * 2 }<BR> </CODE><P>When a vector is modified, resized, or deleted, it may trigger call-backs to notify the clients of the vector. For example, when a vector used in the <B>graph</B> widget is updated, the vector automatically notifies the widget that it has changed. The graph can then redrawn itself at the next idle point. By default, the notification occurs when Tk is next idle. This way you can modify the vector many times without incurring the penalty of the graph redrawing itself for each change. You can change this behavior using the <B>notify</B> operation. <BR> <CODE># Make vector x notify after every change<BR> x notify always<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;...<BR> # Never notify<BR> x notify never<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;...<BR> # Force notification now<BR> x notify now<BR> </CODE><P>To delete a vector, use the <B>vector delete</B> command. Both the vector and its corresponding Tcl command are destroyed. <BR> <CODE># Remove vector x<BR> vector destroy x<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Syntax</A></H2> Vectors are created using the <B>vector create</B> operation. Th <B>create</B> operation can be invoked in one of three forms: <DL> <DT><B>vector create <I>vecName</I></B> </DT> <DD>This creates a new vector <I>vecName</I> which initially has no components. </DD> <DT><B>vector create <I>vecName</I></B>(<I>size</I>) </DT> <DD>This second form creates a new vector which will contain <I>size</I> number of components. The components will be indexed starting from zero (0). The default value for the components is <I>0.0</I>. </DD> <DT><B>vector create <I>vecName</I></B>(<I>first</I>:<I>last</I>) </DT> <DD>The last form creates a new vector of indexed <I>first</I> through <I>last</I>. <I>First</I> and <I>last</I> can be any integer value so long as <I>first</I> is less than <I>last</I>. </DD> </DL> <P> Vector names must start with a letter and consist of letters, digits, or underscores. <BR> <CODE># Error: must start with letter<BR> vector create 1abc<BR> </CODE><P>You can automatically generate vector names using the "<I>#auto</I>" vector name. The <B>create</B> operation will generate a unique vector name. <BR> <CODE>set vec [vector create #auto]<BR> puts "$vec has [$vec length] components"<BR> <H3><A NAME="sect6" HREF="#toc6"></CODE><P>Vector Indices</A></H3> Vectors are indexed by integers. You can access the individual vector components via its array variable or Tcl command. The string representing the index can be an integer, a numeric expression, a range, or a special keyword. <P> The index must lie within the current range of the vector, otherwise an an error message is returned. Normally the indices of a vector are start from 0. But you can use the <B>offset</B> operation to change a vector's indices on-the-fly. <BR> <CODE>puts $vecName(0)<BR> vecName offset -5<BR> puts $vecName(-5)<BR> </CODE><P>You can also use numeric expressions as indices. The result of the expression must be an integer value. <BR> <CODE>set n 21<BR> set vecName($n+3) 50.2<BR> </CODE><P>The following special non-numeric indices are available: <I>min</I>, <I>max</I>, <I>end</I>, and <I>++end</I>. <BR> <CODE>puts "min = $vecName($min)"<BR> set vecName(end) -1.2<BR> </CODE><P>The indices <I>min</I> and <I>max</I> will return the minimum and maximum values of the vector. The index <I>end</I> returns the value of the last component in the vector. The index <I>++end</I> is used to append new value onto the vector. It automatically extends the vector by one component and sets its value. <BR> <CODE># Append an new component to the end<BR> set vecName(++end) 3.2<BR> </CODE><P>A range of indices can be indicated by a colon (:). <BR> <CODE># Set the first six components to 1.0<BR> set vecName(0:5) 1.0<BR> </CODE><P>If no index is supplied the first or last component is assumed. <BR> <CODE># Print the values of all the components<BR> puts $vecName(:)<BR> <H2><A NAME="sect7" HREF="#toc7"></CODE><P>Vector Operations</A></H2> <DL> <DT><B>vector create <I>vecName</I></B>?(<I>size</I>)?... ?<I>switches</I>? </DT> <DD>The <B>create</B> operation creates a new vector <I>vecName</I>. Both a Tcl command and array variable <I>vecName</I> are also created. The name <I>vecName</I> must be unique, so another Tcl command or array variable can not already exist in that scope. You can access the components of the vector using its variable. If you change a value in the array, or unset an array element, the vector is updated to reflect the changes. When the variable <I>vecName</I> is unset, the vector and its Tcl command are also destroyed. <P> The vector has optional switches that affect how the vector is created. They are as follows: <blockquote></DD> <DT><B>-variable <I>varName</I></B> </DT> <DD>Specifies the name of a Tcl variable to be mapped to the vector. If the variable already exists, it is first deleted, then recreated. If <I>varName</I> is the empty string, then no variable will be mapped. You can always map a variable back to the vector using the vector's <B>variable</B> operation. </DD> <DT><B>-command <I>cmdName</I></B> </DT> <DD>Maps a Tcl command to the vector. The vector can be accessed using <I>cmdName</I> and one of the vector instance operations. A Tcl command by that name cannot already exist. If <I>cmdName</I> is the empty string, no command mapping will be made. </DD> <DT><B>-watchunset <I>boolean</I></B> </DT> <DD>Indicates that the vector should automatically delete itself if the variable associated with the vector is unset. By default, the vector will not be deleted. This is different from previous releases. Set <I>boolean</I> to "true" to get the old behavior. </DD> </DL> </blockquote> <DL> <DT><B>vector destroy <I>vecName</I></B> ?<I>vecName...</I>? </DT> <DD></DD> <DT><B>vector expr <I>expression</I></B> </DT> <DD><blockquote>All binary operators take vectors as operands (remember that numbers are treated as one-component vectors). The exact action of binary operators depends upon the length of the second operand. If the second operand has only one component, then each element of the first vector operand is computed by that value. For example, the expression "x * 2" multiples all elements of the vector x by 2. If the second operand has more than one component, both operands must be the same length. Each pair of corresponding elements are computed. So "x + y" adds the the first components of x and y together, the second, and so on. <P> The valid operators are listed below, grouped in decreasing order of precedence: </DD> <DT><B>- !</B> </DT> <DD>Unary minus and logical NOT. The unary minus flips the sign of each component in the vector. The logical not operator returns a vector of whose values are 0.0 or 1.0. For each non-zero component 1.0 is returned, 0.0 otherwise. </DD> <DT><B>^</B> </DT> <DD>Exponentiation. </DD> <DT><B>* / %</B> </DT> <DD>Multiply, divide, remainder. </DD> <DT><B>+ -</B> </DT> <DD>Add and subtract. </DD> <DT><B>&lt;&lt; &gt;&gt;</B> </DT> <DD>Left and right shift. Circularly shifts the values of the vector (not implemented yet). </DD> <DT><B>&lt; &gt; &lt;= &gt;=</B> </DT> <DD>Boolean less, greater, less than or equal, and greater than or equal. Each operator returns a vector of ones and zeros. If the condition is true, 1.0 is the component value, 0.0 otherwise. </DD> <DT><B>== !=</B> </DT> <DD>Boolean equal and not equal. Each operator returns a vector of ones and zeros. If the condition is true, 1.0 is the component value, 0.0 otherwise. </DD> <DT><B>|</B> </DT> <DD>Bit-wise OR. (Not implemented). </DD> <DT><B>&amp;&amp;</B> </DT> <DD>Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. </DD> <DT><B>||</B> </DT> <DD>Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. </DD> <DT><I>x<B>?<I>y<B>:<I>z</I></B></I></B></I> </DT> <DD>If-then-else, as in C. (Not implemented yet). </DD> </DL> <P> See the C manual for more details on the results produced by each operator. All of the binary operators group left-to-right within the same precedence level. <P> Several mathematical functions are supported for vectors. Each of the following functions invokes the math library function of the same name; see the manual entries for the library functions for details on what they do. The operation is applied to all elements of the vector returning the results. <BR> <CODE><P> <B>acos</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>cos</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>hypot</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>sinh</B> <BR> <B>asin</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>cosh</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>log</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>sqrt</B> <BR> <B>atan</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>exp</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>log10</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tan</B> <BR> <B>ceil</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>floor</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>sin</B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tanh</B> <BR> </CODE><P>Additional functions are: <DL> <DT><B>abs</B> </DT> <DD>Returns the absolute value of each component. </DD> <DT><B>random</B> </DT> <DD>Returns a vector of non-negative values uniformly distributed between [0.0, 1.0) using <I>drand48</I>. The seed comes from the internal clock of the machine or may be set manual with the srandom function. </DD> <DT><B>round</B> </DT> <DD>Rounds each component of the vector. </DD> <DT><B>srandom</B> </DT> <DD>Initializes the random number generator using <I>srand48</I>. The high order 32-bits are set using the integral portion of the first vector component. All other components are ignored. The low order 16-bits are set to an arbitrary value. </DD> </DL> <P> The following functions return a single value. <DL> <DT><B>adev</B> </DT> <DD>Returns the average deviation (defined as the sum of the absolute values of the differences between component and the mean, divided by the length of the vector). </DD> <DT><B>kurtosis</B> </DT> <DD>Returns the degree of peakedness (fourth moment) of the vector. </DD> <DT><B>length</B> </DT> <DD>Returns the number of components in the vector. </DD> <DT><B>max</B> </DT> <DD>Returns the vector's maximum value. </DD> <DT><B>mean</B> </DT> <DD>Returns the mean value of the vector. </DD> <DT><B>median</B> </DT> <DD>Returns the median of the vector. </DD> <DT><B>min</B> </DT> <DD>Returns the vector's minimum value. </DD> <DT><B>q1</B> </DT> <DD>Returns the first quartile of the vector. </DD> <DT><B>q3</B> </DT> <DD>Returns the third quartile of the vector. </DD> <DT><B>prod</B> </DT> <DD>Returns the product of the components. </DD> <DT><B>sdev</B> </DT> <DD>Returns the standard deviation (defined as the square root of the variance) of the vector. </DD> <DT><B>skew</B> </DT> <DD>Returns the skewness (or third moment) of the vector. This characterizes the degree of asymmetry of the vector about the mean. </DD> <DT><B>sum</B> </DT> <DD>Returns the sum of the components. </DD> <DT><B>var</B> </DT> <DD>Returns the variance of the vector. The sum of the squared differences between each component and the mean is computed. The variance is the sum divided by the length of the vector minus 1. </DD> </DL> <P> The last set returns a vector of the same length as the argument. <DL> <DT><B>norm</B> </DT> <DD>Scales the values of the vector to lie in the range [0.0..1.0]. </DD> <DT><B>sort</B> </DT> <DD>Returns the vector components sorted in ascending order. </DD> </DL> </blockquote> <DL> <DT><B>vector names </B>?<I>pattern</I>? </DT> <DD></DD> </DL> <H2><A NAME="sect8" HREF="#toc8">Instance Operations</A></H2> You can also use the vector's Tcl command to query or modify it. The general form is <BR> <P> <CODE><I>vecName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for vectors are listed below. <DL> <DT><I>vecName <B>append</B></I> <I>item</I> ?<I>item</I>?... </DT> <DD>Appends the component values from <I>item</I> to <I>vecName</I>. <I>Item</I> can be either the name of a vector or a list of numeric values. </DD> <DT><I>vecName <B>clear</B></I> </DT> <DD>Clears the element indices from the array variable associated with <I>vecName</I>. This doesn't affect the components of the vector. By default, the number of entries in the Tcl array doesn't match the number of components in the vector. This is because its too expensive to maintain decimal strings for both the index and value for each component. Instead, the index and value are saved only when you read or write an element with a new index. This command removes the index and value strings from the array. This is useful when the vector is large. </DD> <DT><I>vecName <B>delete</B></I> <I>index</I> ?<I>index</I>?... </DT> <DD>Deletes the <I>index</I>th component from the vector <I>vecName</I>. <I>Index</I> is the index of the element to be deleted. This is the same as unsetting the array variable element <I>index</I>. The vector is compacted after all the indices have been deleted. </DD> <DT><I>vecName <B>dup</B></I> <I>destName</I> </DT> <DD>Copies <I>vecName</I> to <I>destName</I>. <I>DestName</I> is the name of a destination vector. If a vector <I>destName</I> already exists, it is overwritten with the components of <I>vecName</I>. Otherwise a new vector is created. </DD> <DT><I>vecName <B>expr</B></I> <I>expression</I> </DT> <DD>Computes the expression and resets the values of the vector accordingly. Both scalar and vector math operations are allowed. All values in expressions are either real numbers or names of vectors. All numbers are treated as one component vectors. </DD> <DT><I>vecName <B>length</B></I> ?<I>newSize</I>? </DT> <DD>Queries or resets the number of components in <I>vecName</I>. <I>NewSize</I> is a number specifying the new size of the vector. If <I>newSize</I> is smaller than the current size of <I>vecName</I>, <I>vecName</I> is truncated. If <I>newSize</I> is greater, the vector is extended and the new components are initialized to <I>0.0</I>. If no <I>newSize</I> argument is present, the current length of the vector is returned. </DD> <DT><I>vecName <B>merge</B></I> <I>srcName</I> ?<I>srcName</I>?... </DT> <DD>Merges the named vectors into a single vector. The resulting vector is formed by merging the components of each source vector one index at a time. </DD> <DT><I>vecName <B>notify</B></I> <I>keyword</I> </DT> <DD>Controls how vector clients are notified of changes to the vector. The exact behavior is determined by <I>keyword</I>. <blockquote></DD> <DT><I>always</I> </DT> <DD>Indicates that clients are to be notified immediately whenever the vector is updated. </DD> <DT><I>never</I> </DT> <DD>Indicates that no clients are to be notified. </DD> <DT><I>whenidle</I> </DT> <DD>Indicates that clients are to be notified at the next idle point whenever the vector is updated. </DD> <DT><I>now</I> </DT> <DD>If any client notifications is currently pending, they are notified immediately. </DD> <DT><I>cancel</I> </DT> <DD>Cancels pending notifications of clients using the vector. </DD> <DT><I>pending</I> </DT> <DD>Returns <I>1</I> if a client notification is pending, and <I>0</I> otherwise. </DD> </DL> </blockquote> <DL> <DT><I>vecName <B>offset</B></I> ?<I>value</I>? </DT> <DD>Shifts the indices of the vector by the amount specified by <I>value</I>. <I>Value</I> is an integer number. If no <I>value</I> argument is given, the current offset is returned. </DD> <DT><I>vecName <B>populate</B></I> <I>destName</I> ?<I>density</I>? </DT> <DD>Creates a vector <I>destName</I> which is a superset of <I>vecName</I>. <I>DestName</I> will include all the components of <I>vecName</I>, in addition the interval between each of the original components will contain a <I>density</I> number of new components, whose values are evenly distributed between the original components values. This is useful for generating abscissas to be interpolated along a spline. </DD> <DT><I>vecName <B>range</B></I> <I>firstIndex</I> ?<I>lastIndex</I>?... </DT> <DD>Returns a list of numeric values representing the vector components between two indices. Both <I>firstIndex</I> and <I>lastIndex</I> are indices representing the range of components to be returned. If <I>lastIndex</I> is less than <I>firstIndex</I>, the components are listed in reverse order. </DD> <DT><I>vecName <B>search</B></I> <I>value</I> ?<I>value</I>? </DT> <DD>Searches for a value or range of values among the components of <I>vecName</I>. If one <I>value</I> argument is given, a list of indices of the components which equal <I>value</I> is returned. If a second <I>value</I> is also provided, then the indices of all components which lie within the range of the two values are returned. If no components are found, then <I>""</I> is returned. </DD> <DT><I>vecName <B>set</B></I> <I>item</I> </DT> <DD>Resets the components of the vector to <I>item</I>. <I>Item</I> can be either a list of numeric expressions or another vector. </DD> <DT><I>vecName <B>seq</B></I> <I>start</I> ?<I>finish</I>? ?<I>step</I>? </DT> <DD>Generates a sequence of values starting with the value <I>start</I>. <I>Finish</I> indicates the terminating value of the sequence. The vector is automatically resized to contain just the sequence. If three arguments are present, <I>step</I> designates the interval. <P> With only two arguments (no <I>finish</I> argument), the sequence will continue until the vector is filled. With one argument, the interval defaults to 1.0. </DD> <DT><I>vecName <B>sort</B></I> ?<B>-reverse</B>? ?<I>argName</I>?... </DT> <DD>Sorts the vector <I>vecName</I> in increasing order. If the <B>-reverse</B> flag is present, the vector is sorted in decreasing order. If other arguments <I>argName</I> are present, they are the names of vectors which will be rearranged in the same manner as <I>vecName</I>. Each vector must be the same length as <I>vecName</I>. You could use this to sort the x vector of a graph, while still retaining the same x,y coordinate pairs in a y vector. </DD> <DT><I>vecName <B>variable</B></I> <I>varName</I> </DT> <DD>Maps a Tcl variable to the vector, creating another means for accessing the vector. The variable <I>varName</I> can't already exist. This overrides any current variable mapping the vector may have. </DD> </DL> </blockquote> <H2><A NAME="sect9" HREF="#toc9">C Language API</A></H2> You can create, modify, and destroy vectors from C code, using library routines. You need to include the header file <I>blt.h</I>. It contains the definition of the structure <B>Blt_Vector</B>, which represents the vector. It appears below. <BR> <CODE>typedef struct {<BR> double *<I>valueArr</I>; <BR> int <I>numValues</I>; <BR> int <I>arraySize</I>; <BR> double <I>min</I>, <I>max</I>; <BR> } <B>Blt_Vector</B>;<BR> </CODE><P>The field <I>valueArr</I> points to memory holding the vector components. The components are stored in a double precision array, whose size size is represented by <I>arraySize</I>. <I>NumValues</I> is the length of vector. The size of the array is always equal to or larger than the length of the vector. <I>Min</I> and <I>max</I> are minimum and maximum component values. <H2><A NAME="sect10" HREF="#toc10">Library Routines</A></H2> The following routines are available from C to manage vectors. Vectors are identified by the vector name. <P> <B>Blt_CreateVector</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_CreateVector</B> (<I>interp</I>, <I>vecName</I>, <I>length</I>, <I>vecPtrPtr</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> char *<I>vecName</I>;<BR> int <I>length</I>;<BR> Blt_Vector **<I>vecPtrPtr</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Creates a new vector <I>vecName</I> with a length of <I>length</I>. <B>Blt_CreateVector</B> creates both a new Tcl command and array variable <I>vecName</I>. Neither a command nor variable named <I>vecName</I> can already exist. A pointer to the vector is placed into <I>vecPtrPtr</I>. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully created. If <I>length</I> is negative, a Tcl variable or command <I>vecName</I> already exists, or memory cannot be allocated for the vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_DeleteVectorByName</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_DeleteVectorByName</B> (<I>interp</I>, <I>vecName</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> char *<I>vecName</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Removes the vector <I>vecName</I>. <I>VecName</I> is the name of a vector which must already exist. Both the Tcl command and array variable <I>vecName</I> are destroyed. All clients of the vector will be notified immediately that the vector has been destroyed. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully deleted. If <I>vecName</I> is not the name a vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_DeleteVector</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_DeleteVector</B> (<I>vecPtr</I>)<BR> <blockquote>Blt_Vector *<I>vecPtr</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Removes the vector pointed to by <I>vecPtr</I>. <I>VecPtr</I> is a pointer to a vector, typically set by <B>Blt_GetVector</B> or <B>Blt_CreateVector</B>. Both the Tcl command and array variable of the vector are destroyed. All clients of the vector will be notified immediately that the vector has been destroyed. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully deleted. If <I>vecName</I> is not the name a vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_GetVector</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_GetVector</B> (<I>interp</I>, <I>vecName</I>, <I>vecPtrPtr</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> char *<I>vecName</I>;<BR> Blt_Vector **<I>vecPtrPtr</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Retrieves the vector <I>vecName</I>. <I>VecName</I> is the name of a vector which must already exist. <I>VecPtrPtr</I> will point be set to the address of the vector. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully retrieved. If <I>vecName</I> is not the name of a vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_ResetVector</B> <P> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_ResetVector</B> (<I>vecPtr</I>, <I>dataArr</I>, <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<I>numValues</I>, <I>arraySize</I>, <I>freeProc</I>)<BR> <blockquote>Blt_Vector *<I>vecPtr</I>;<BR> double *<I>dataArr</I>;<BR> int *<I>numValues</I>;<BR> int *<I>arraySize</I>;<BR> Tcl_FreeProc *<I>freeProc</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Resets the components of the vector pointed to by <I>vecPtr</I>. Calling <B>Blt_ResetVector</B> will trigger the vector to dispatch notifications to its clients. <I>DataArr</I> is the array of doubles which represents the vector data. <I>NumValues</I> is the number of elements in the array. <I>ArraySize</I> is the actual size of the array (the array may be bigger than the number of values stored in it). <I>FreeProc</I> indicates how the storage for the vector component array (<I>dataArr</I>) was allocated. It is used to determine how to reallocate memory when the vector is resized or destroyed. It must be <I>TCL_DYNAMIC</I>, <I>TCL_STATIC</I>, <I>TCL_VOLATILE</I>, or a pointer to a function to free the memory allocated for the vector array. If <I>freeProc</I> is <I>TCL_VOLATILE</I>, it indicates that <I>dataArr</I> must be copied and saved. If <I>freeProc</I> is <I>TCL_DYNAMIC</I>, it indicates that <I>dataArr</I> was dynamically allocated and that Tcl should free <I>dataArr</I> if necessary. <I>Static</I> indicates that nothing should be done to release storage for <I>dataArr</I>. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully resized. If <I>newSize</I> is negative, a vector <I>vecName</I> does not exist, or memory cannot be allocated for the vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_ResizeVector</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_ResizeVector</B> (<I>vecPtr</I>, <I>newSize</I>)<BR> <blockquote>Blt_Vector *<I>vecPtr</I>;<BR> int <I>newSize</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Resets the length of the vector pointed to by <I>vecPtr</I> to <I>newSize</I>. If <I>newSize</I> is smaller than the current size of the vector, it is truncated. If <I>newSize</I> is greater, the vector is extended and the new components are initialized to <I>0.0</I>. Calling <B>Blt_ResetVector</B> will trigger the vector to dispatch notifications. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully resized. If <I>newSize</I> is negative or memory can not be allocated for the vector, then <I>TCL_ERROR</I> is returned and <I>interp-&gt;result</I> will contain an error message. <P> </DD> </DL> <P> <B>Blt_VectorExists</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_VectorExists</B> (<I>interp</I>, <I>vecName</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> char *<I>vecName</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Indicates if a vector named <I>vecName</I> exists in <I>interp</I>. </DD> <DT>Results: </DT> <DD>Returns <I>1</I> if a vector <I>vecName</I> exists and <I>0</I> otherwise. </DD> </DL> </blockquote> <P> <P> If your application needs to be notified when a vector changes, it can allocate a unique <I>client identifier</I> for itself. Using this identifier, you can then register a call-back to be made whenever the vector is updated or destroyed. By default, the call-backs are made at the next idle point. This can be changed to occur at the time the vector is modified. An application can allocate more than one identifier for any vector. When the client application is done with the vector, it should free the identifier. <P> The call-back routine must of the following type. <BR> <blockquote><BR> <CODE>typedef void (<B>Blt_VectorChangedProc</B>) (Tcl_Interp *<I>interp</I>, <BR> <blockquote>ClientData <I>clientData</I>, Blt_VectorNotify <I>notify</I>);<BR> </blockquote> <BR> </blockquote> </PRE></CODE><P><I>ClientData</I> is passed to this routine whenever it is called. You can use this to pass information to the call-back. The <I>notify</I> argument indicates whether the vector has been updated of destroyed. It is an enumerated type. <BR> <blockquote><BR> <CODE>typedef enum {<BR> <I>BLT_VECTOR_NOTIFY_UPDATE</I>=1,<BR> <I>BLT_VECTOR_NOTIFY_DESTROY</I>=2<BR> } <B>Blt_VectorNotify</B>;<BR> <BR> </blockquote> <P> </CODE><P><B>Blt_AllocVectorId</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>Blt_VectorId <B>Blt_AllocVectorId</B> (<I>interp</I>, <I>vecName</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> char *<I>vecName</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Allocates an client identifier for with the vector <I>vecName</I>. This identifier can be used to specify a call-back which is triggered when the vector is updated or destroyed. </DD> <DT>Results: </DT> <DD>Returns a client identifier if successful. If <I>vecName</I> is not the name of a vector, then <I>NULL</I> is returned and <I>interp-&gt;result</I> will contain an error message. </DD> </DL> </blockquote> <P> <P> <B>Blt_GetVectorById</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>int <B>Blt_GetVector</B> (<I>interp</I>, <I>clientId</I>, <I>vecPtrPtr</I>)<BR> <blockquote>Tcl_Interp *<I>interp</I>;<BR> Blt_VectorId <I>clientId</I>;<BR> Blt_Vector **<I>vecPtrPtr</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Retrieves the vector used by <I>clientId</I>. <I>ClientId</I> is a valid vector client identifier allocated by <B>Blt_AllocVectorId</B>. <I>VecPtrPtr</I> will point be set to the address of the vector. </DD> <DT>Results: </DT> <DD>Returns <I>TCL_OK</I> if the vector is successfully retrieved. </DD> </DL> </blockquote> <P> <P> <B>Blt_SetVectorChangedProc</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>void <B>Blt_SetVectorChangedProc</B> (<I>clientId</I>, <I>proc</I>, <I>clientData</I>);<BR> <blockquote>Blt_VectorId <I>clientId</I>;<BR> Blt_VectorChangedProc *<I>proc</I>;<BR> ClientData *<I>clientData</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Specifies a call-back routine to be called whenever the vector associated with <I>clientId</I> is updated or deleted. <I>Proc</I> is a pointer to call-back routine and must be of the type <B>Blt_VectorChangedProc</B>. <I>ClientData</I> is a one-word value to be passed to the routine when it is invoked. If <I>proc</I> is <I>NULL</I>, then the client is not notified. </DD> <DT>Results: </DT> <DD>The designated call-back procedure will be invoked when the vector is updated or destroyed. </DD> </DL> </blockquote> <P> <P> <B>Blt_FreeVectorId</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>void <B>Blt_FreeVectorId</B> (<I>clientId</I>);<BR> <blockquote>Blt_VectorId <I>clientId</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Frees the client identifier. Memory allocated for the identifier is released. The client will no longer be notified when the vector is modified. </DD> <DT>Results: </DT> <DD>The designated call-back procedure will be no longer be invoked when the vector is updated or destroyed. </DD> </DL> </blockquote> <P> <P> <B>Blt_NameOfVectorId</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>char *<B>Blt_NameOfVectorId</B> (<I>clientId</I>);<BR> <blockquote>Blt_VectorId <I>clientId</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Retrieves the name of the vector associated with the client identifier <I>clientId</I>. </DD> <DT>Results: </DT> <DD>Returns the name of the vector associated with <I>clientId</I>. If <I>clientId</I> is not an identifier or the vector has been destroyed, <I>NULL</I> is returned. </DD> </DL> </blockquote> <P> <P> <B>Blt_InstallIndexProc</B> <blockquote> <DL> <DT>Synopsis: </DT> <DD><BR> <CODE>void <B>Blt_InstallIndexProc</B> (<I>indexName</I>, <I>procPtr</I>)<BR> <blockquote>char *<I>indexName</I>;<BR> Blt_VectorIndexProc *<I>procPtr</I>;<BR> </DD> </DL> </blockquote> <DL> <DT></CODE><P>Description: </DT> <DD>Registers a function to be called to retrieved the index <I>indexName</I> from the vector's array variable. <P> typedef double Blt_VectorIndexProc(Vector *vecPtr); <P> The function will be passed a pointer to the vector. The function must return a double representing the value at the index. </DD> <DT>Results: </DT> <DD>The new index is installed into the vector. </DD> </DL> </blockquote> </blockquote> <H2><A NAME="sect11" HREF="#toc11">C API Example</A></H2> The following example opens a file of binary data and stores it in an array of doubles. The array size is computed from the size of the file. If the vector "data" exists, calling <B>Blt_VectorExists</B>, <B>Blt_GetVector</B> is called to get the pointer to the vector. Otherwise the routine <B>Blt_CreateVector</B> is called to create a new vector and returns a pointer to it. Just like the Tcl interface, both a new Tcl command and array variable are created when a new vector is created. It doesn't make any difference what the initial size of the vector is since it will be reset shortly. The vector is updated when <B>lt_ResetVector</B> is called. Blt_ResetVector makes the changes visible to the Tcl interface and other vector clients (such as a graph widget). <P> <BR> <CODE>#include &lt;tcl.h&gt;<BR> #include &lt;blt.h&gt;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<BR> <!-- Blt_Vector *vecPtr;<BR> double *newArr;<BR> FILE *f;<BR> struct stat statBuf;<BR> int numBytes, numValues;<BR> <P> f = fopen("binary.dat", "r");<BR> fstat(fileno(f), &amp;statBuf);<BR> numBytes = (int)statBuf.st_size;<BR> <P> /* Allocate an array big enough to hold all the data */<BR> newArr = (double *)m<A HREF="alloc.n.html">alloc(numBytes)</A> ;<BR> numValues = numBytes / sizeof(double);<BR> fread((void *)newArr, numValues, sizeof(double), f);<BR> fclose(f);<BR> <P> if (Blt_VectorExists(interp, "data")) {<BR> if (Blt_GetVector(interp, "data", &amp;vecPtr) != TCL_OK) {<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;return TCL_ERROR;<BR> }<BR> } else {<BR> if (Blt_CreateVector(interp, "data", 0, &amp;vecPtr) != TCL_OK) {<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;return TCL_ERROR;<BR> }<BR> }<BR> /* <BR> * Reset the vector. Clients will be notified when Tk is idle. <BR> * TCL_DYNAMIC tells the vector to free the memory allocated <BR> * if it needs to reallocate or destroy the vector.<BR> */<BR> if (Blt_ResetVector(vecPtr, newArr, numValues, numValues, <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;TCL_DYNAMIC) != TCL_OK) {<BR> return TCL_ERROR;<BR> }<BR> --> <H2><A NAME="sect12" HREF="#toc12"></CODE><P>Incompatibilities</A></H2> In previous versions, if the array variable isn't global (i.e. local to a Tcl procedure), the vector is automatically destroyed when the procedure returns. <BR> <CODE>proc doit {} {<BR> # Temporary vector x<BR> vector x(10)<BR> set <A HREF="x.9.html">x(9)</A> 2.0<BR> ...<BR> }<BR> <P> </CODE><P>This has changed. Variables are not automatically destroyed when their variable is unset. You can restore the old behavior by setting the "-watchunset" switch. <H2><A NAME="sect13" HREF="#toc13"></CODE><P>Keywords</A></H2> vector, graph, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <UL> <LI><A NAME="toc6" HREF="#sect6">Vector Indices</A></LI> </UL> <LI><A NAME="toc7" HREF="#sect7">Vector Operations</A></LI> <LI><A NAME="toc8" HREF="#sect8">Instance Operations</A></LI> <LI><A NAME="toc9" HREF="#sect9">C Language API</A></LI> <LI><A NAME="toc10" HREF="#sect10">Library Routines</A></LI> <LI><A NAME="toc11" HREF="#sect11">C API Example</A></LI> <LI><A NAME="toc12" HREF="#sect12">Incompatibilities</A></LI> <LI><A NAME="toc13" HREF="#sect13">Keywords</A></LI> </UL> </BODY></HTML> ������������������������������������������./saods9/blt3.0.1/html/hiertable.html���������������������������������������������������������������0000644�0001750�0001750�00000300207�11462120062�016031� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>treeview(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> treeview - Create and manipulate hierarchical table widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>treeview</B> <I>pathName </I>?<I>options</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>treeview</B> widget displays a tree of data. It replaces both the <B>hiertable</B> and <B>hierbox</B> widgets. The <B>treeview</B> is 100% syntax compatible with the <B>hiertable</B> widget. The <B>hiertable</B> command is retained for sake of script-level compatibility. This widget obsoletes the <B>hierbox</B> widget. It does everything the old <B>hierbox</B> widget did, but also provides data sharing (via <I>tree data objects</I>) and the ability to tag nodes. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>treeview</B> widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. <P> A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is <I>open</I>, its children are exposed. When it is <I>closed</I>, the children and their descedants are hidden. The button is normally a <I>+</I> or <I>-</I> symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). <P> If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. <H2><A NAME="sect4" HREF="#toc4">Tree Data Object</A></H2> The tree is not stored inside the widget but in a tree data object (see the <B>tree</B> command for a further explanation). Tree data objects can be shared among different clients, such as a <B>treeview</B> widget or the <B>tree</B> command. You can walk the tree and manage its data with the <B>tree</B> command tree, while displaying it with the <B>treeview</B> widget. Whenever the tree is updated, the <B>treeview</B> widget is automatically redrawn. <P> By default, the <B>treeview</B> widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the <B>tree</B> command using the <B>-tree</B> configuration option. <B>Treeview</B> widgets can share the same tree object, possibly displaying different views of the same data. <P> A tree object has both a Tcl and C API. You can insert or delete nodes using <B>treeview</B> widget or <B>tree</B> command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. <H2><A NAME="sect5" HREF="#toc5">Syntax</A></H2> <BR> <P> <CODE><B>treeview <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>treeview</B> command creates a new window <I>pathName</I> and makes it into a <B>treeview</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the <B>configure</B> operation below for the exact details about what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>treeview</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available are described in the <FONT SIZE=-1><B>TREEVIEW OPERATIONS</B></FONT> section. <H2><A NAME="sect6" HREF="#toc6">IDs and Tags</A></H2> Nodes can be inserted into a tree using the <B>treeview</B> widget <BR> <CODE>blt::treeview .t<BR> set node [.t insert end root "one"]<BR> </CODE><P>or <B>tree</B> command. <BR> <CODE>set tree [blt::tree create]<BR> set node [$tree insert root "one"]<BR> </CODE><P>In both cases, a number identifying the node is returned (the value of <I>$node</I>). This serial number or <I>id</I> uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id <I>0</I>. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the <B>treeview</B> widget or the <B>tree</B> command. Ids are recycled when the node deleted. <P> A node may also have any number of <I>tags</I> associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "<I>x123</I>" is valid, but "<I>123</I>" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the <B>treeview</B> widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. <P> The tag <B>all</B> is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. <P> Tags may be shared, just like trees, between clients. For example, you can use the tags created by the <B>tree</B> command with <B>treeview</B> widgets. <H2><A NAME="sect7" HREF="#toc7">Special Node IDs</A></H2> There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the <B>treeview</B> widget. <DL> <DT><B>active</B> </DT> <DD>The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the <B>-activeicon</B> option). The <B>active</B> id is changed automatically by moving the mouse pointer over another node or by using the <B>entry activate</B> operation. Note that there can be only one active node at a time. </DD> <DT><B>anchor</B> </DT> <DD>The node representing the fixed end of the current selection. The anchor is set by the <B>selection anchor</B> operation. </DD> <DT><B>current</B> </DT> <DD>The node where the mouse pointer is currently located. But unlike <B>active</B>, this id changes while the selection is dragged. It is used to determine the current node during button drags. </DD> <DT><B>down</B> </DT> <DD>The next open node from the current focus. The <B>down</B> of the last open node is the same. </DD> <DT><B>end</B> </DT> <DD>The last open node (in depth-first order) on the tree. </DD> <DT><B>focus</B> </DT> <DD>The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the <B>focus</B> operation. </DD> <DT><B>last</B> </DT> <DD>The last open node from the current focus. But unlike <B>up</B>, when the focus is at root, <B>last</B> wraps around to the last open node in the tree. </DD> <DT><B>mark</B> </DT> <DD>The node representing the non-fixed end of the current selection. The mark is set by the <B>selection mark</B> operation. </DD> <DT><B>next</B> </DT> <DD>The next open node from the current focus. But unlike <B>down</B>, when the focus is on last open node, <B>next</B> wraps around to the root node. </DD> <DT><B>nextsibling</B> </DT> <DD>The next sibling from the node with the current focus. If the node is already the last sibling then it is the <B>nextsibling<B>. </DD> <DT><B>parent</B></B></B> </DT> <DD>The parent of the node with the current focus. The <B>parent</B> of the root is also the root. </DD> <DT><B>prevsibling</B> </DT> <DD>The previous sibling from the node with the current focus. If the node is already the first sibling then it is the <B>prevsibling<B>. </DD> <DT><B>root</B></B></B> </DT> <DD>The root node. You can also use id <I>0</I> to indicate the root. </DD> <DT><B>up</B> </DT> <DD>The last open node (in depth-first order) from the current focus. The <B>up</B> of the root node (i.e. the root has focus) is also the root. </DD> <DT><B>view.top</B> </DT> <DD>First node that's current visible in the widget. </DD> <DT><B>view.bottom</B> </DT> <DD>Last node that's current visible in the widget. </DD> <DT><I>path</I> </DT> <DD>Absolute path of a node. Path names refer to the node name, not their entry labels. Paths don't have to start with a separator (see the <B>-separator</B> configuration option), but component names must be separated by the designated separator. </DD> <DT><B>@<I>x<B>,<I>y</I></B></I></B> </DT> <DD>Indicates the node that covers the point in the treeview window specified by <I>x</I> and <I>y</I> (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. </DD> </DL> <P> A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. <H2><A NAME="sect8" HREF="#toc8">Data Fields</A></H2> A node in the tree can have <I>data fields</I>. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the <B>treeview</B> widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. <H2><A NAME="sect9" HREF="#toc9">Entry Bindings</A></H2> You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its <I>bindtags</I>. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag <I>all</I> that all node entries automatically have. <H2><A NAME="sect10" HREF="#toc10">Treeview Operations</A></H2> The <B>treeview</B> operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: <P> <BR> <CODE><I>pathName operation </I>?<I>arg arg ...</I>?<BR> <P> </CODE><P><I>Operation</I> and the <I>arg</I>s determine the exact behavior of the command. The following operation are available for <B>treeview</B> widgets: <DL> <DT><I>pathName <B>bbox</B></I> ?<B>-screen</B>? <I>tagOrId...</I> </DT> <DD>Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more <I>tagOrId</I> arguments. If the <B>-screen</B> flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from <I>0</I> from the root node. The returned list contains the following values. <blockquote></DD> <DT><I>x</I> </DT> <DD>X-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>y</I> </DT> <DD>Y-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>width</I> </DT> <DD>Width of the bounding box. </DD> <DT><I>height</I> </DT> <DD>Height of the bounding box. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a node with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> entries, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This command is used to control the button selectors within a <B>treeview</B> widget. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>button activate</B></I> <I>tagOrId</I> </DT> <DD>Designates the node given by <I>tagOrId</I> as active. When a node is active it's entry is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active entry at a time. The special id <B>active</B> indicates the currently active node. </DD> <DT><I>pathName <B>button bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an button of a node entry with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> buttons, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>button configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>BUTTON OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>close </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Closes the node specified by <I>tagOrId</I>. In addition, if a Tcl script was specified by the <B>-closecommand</B> option, it is invoked. If the node is already closed, this command has no effect. If the <B>-recurse</B> flag is present, each child node is recursively closed. </DD> <DT><I>pathName <B>column <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview columns. <blockquote></DD> <DT><I>pathName <B>column activate</B></I> <I>column</I> </DT> <DD>Sets the active column to <I>column</I>. <I>Column</I> is the name of a column in the widget. When a column is active, it's drawn using its <B>-activetitlebackground</B> and <B>-activetitleforeground</B> options. If <I>column</I> is the <I>""</I>, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. </DD> <DT><I>pathName <B>column cget</B></I> <I>name</I> <I>option</I> </DT> <DD>Returns the current value of the column configuration option given by <I>option</I> for <I>name</I>. <I>Name</I> is the name of column that corresponds to a data field. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>column configure</B></I> <I>name</I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the column designated by <I>name</I>. <I>Name</I> is the name of the column corresponding to a data field. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>COLUMN OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>column delete</B></I> <I>field</I> ?<I>field</I>...? </DT> <DD>Deletes one of more columns designated by <I>field</I>. Note that this does not delete the data fields themselves. </DD> <DT><I>pathName <B>column insert</B></I> <I>position</I> <I>field</I> ?<I>options</I>...? </DT> <DD>Inserts one of more columns designated by <I>field</I>. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. <I>Position</I> indicates where in the list of columns to add the new column. It may be either a number or <I>end</I>. </DD> <DT><I>pathName <B>column invoke</B></I> <I>field</I> </DT> <DD>Invokes the Tcl command associated with the column <I>field</I>, if there is one (using the column's <B>-command</B> option). The command is ignored if the column's <B>-state</B> option set to <I>disabled</I>. </DD> <DT><I>pathName <B>column move <I>name</I></B></I> <I>dest</I> </DT> <DD>Moves the column <I>name</I> to the destination position. <I>Dest</I> is the name of another column or a screen position in the form <I>@<I>x<I>,<I>y</I></I></I></I>. </DD> <DT><I>pathName <B>column names</B></I> </DT> <DD>Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. </DD> <DT><I>pathName <B>column nearest</B></I> <I>x</I> ?<I>y</I>? </DT> <DD>Returns the name of the column closest to the given X-Y screen coordinate. If you provide a <I>y</I> argument (it's optional), a name is returned only when if the point is over a column's title. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TREEVIEW OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>curselection</B></I> </DT> <DD>Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. </DD> <DT><I>pathName <B>delete <I>tagOrId</I></B></I>... </DT> <DD>Deletes one or more entries given by <I>tagOrId</I> and its children. </DD> <DT><I>pathName <B>entry <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview entries. <blockquote></DD> <DT><I>pathName <B>entry activate</B></I> <I>tagOrId</I> </DT> <DD>Sets the active entry to the one specified by <I>tagOrId</I>. When an entry is active it is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active node at a time. The special id of the currently active node is <B>active</B>. </DD> <DT><I>pathName <B>entry cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>entry children</B></I> <I>tagOrId</I> ?<I>first</I>? ?<I>last</I>? </DT> <DD>Returns a list of ids for the given range of children of <I>tagOrId</I>. <I>TagOrId</I> is the id or tag of the node to be examined. If only a <I>first</I> argument is present, then the id of the that child at that numeric position is returned. If both <I>first</I> and <I>last</I> arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. </DD> <DT><I>pathName <B>entry configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: </DD> <DT><I>pathName <B>entry delete</B></I> <I>tagOrId</I> ?<I>first</I> ?<I>last</I>? </DT> <DD>Deletes the one or more children nodes of the parent <I>tagOrId</I>. If <I>first</I> and <I>last</I> arguments are present, they are positions designating a range of children nodes to be deleted. </DD> <DT><I>pathName <B>entry isbefore <I>tagOrId1</I></B></I> <I>tagOrId2</I> </DT> <DD>Returns 1 if <I>tagOrId1</I> is before <I>tagOrId2</I> and 0 otherwise. </DD> <DT><I>pathName <B>entry ishidden <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. </DD> <DT><I>pathName <B>entry isopen <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently open and 0 otherwise. </DD> <DT><I>pathName <B>entry size</B></I> <B>-recurse</B> <I>tagOrId</I> </DT> <DD>Returns the number of children for parent node <I>tagOrId</I>. If the <B>-recurse</B> flag is set, the number of all its descendants is returned. The node itself is not counted. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>find </B></I>?<I>flags</I>? <I>first</I> <I>last</I> </DT> <DD>Finds for all entries matching the criteria given by <I>flags</I>. A list of ids for all matching nodes is returned. <I>First</I> and <I>last</I> are ids designating the range of the search in depth-first order. If <I>last</I> is before <I>first</I>, then nodes are searched in reverse order. The valid flags are: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Patterns must match exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Pick entries that don't match. </DD> <DT><B>-exec<I> string</I></B> </DT> <DD>Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-count<I> number</I></B> </DT> <DD>Stop searching after <I>number</I> matches. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>focus </B></I> <I>tagOrId</I> </DT> <DD>Sets the focus to the node given by <I>tagOrId</I>. When a node has focus, it can receive keyboard events. The special id <B>focus</B> designates the node that currently has focus. </DD> <DT><I>pathName <B>get </B></I>?<B>-full</B>? <I>tagOrId</I> <I>tagOrId</I>... </DT> <DD>Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the <B>-full</B> flag is set, then the full pathnames are returned. </DD> <DT><I>pathName <B>hide </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Hides all nodes matching the criteria given by <I>flags</I>. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Hide nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>index </B></I>?<B>-at</B> <I>tagOrId</I>? <I>string</I> </DT> <DD>Returns the id of the node specified by <I>string</I>. <I>String</I> may be a tag or node id. Some special ids are normally relative to the node that has focus. The <B>-at</B> flag lets you select another node. </DD> <DT><I>pathName <B>insert </B></I>?<B>-at <I>tagOrId</I></B>? <I>position</I> <I>path</I> ?<I>options...</I>? ?<I>path</I>? ?<I>options...</I>? </DT> <DD>Inserts one or more nodes at <I>position</I>. <I>Position</I> is the location (number or <I>end</I>) where the new nodes are added to the parent node. <I>Path</I> is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the <B>-separator</B> option). Pathnames are normally absolute, but the <B>-at</B> switch lets you select a relative starting point. Its value is the id of the starting node. <P> All ancestors of the new node must already exist, unless the <B>-autocreate</B> option is set. It is also an error if a node already exists, unless the <B>-allowduplicates</B> option is set. <P> <I>Option</I> and <I>value</I> may have any of the values accepted by the <B>entry configure</B> operation described in the <FONT SIZE=-1><B>ENTRY OPERATIONS</B></FONT> section below. This command returns a list of the ids of the new entries. </DD> <DT><I>pathName <B>move <I>tagOrId</I></B></I> <I>how</I> <I>destId</I> </DT> <DD>Moves the node given by <I>tagOrId</I> to the destination node. The node can not be an ancestor of the destination. <I>DestId</I> is the id of the destination node and can not be the root of the tree. In conjunction with <I>how</I>, it describes how the move is performed. <blockquote></DD> <DT><I>before</I> </DT> <DD>Moves the node before the destination node. </DD> <DT><I>after</I> </DT> <DD>Moves the node after the destination node. </DD> <DT><I>into</I> </DT> <DD>Moves the node to the end of the destination's list of children. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>nearest <I>x y</I></B></I> ?<I>varName</I>? </DT> <DD>Returns the id of the node entry closest to the given X-Y screen coordinate. The optional argument <I>varName</I> is the name of variable which is set to either <I>button</I> or <I>select</I> to indicate over what part of the node the coordinate lies. If the coordinate is not directly over any node, then <I>varName</I> will contain the empty string. </DD> <DT><I>pathName <B>open </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Opens the one or more nodes specified by <I>tagOrId</I>. If a node is not already open, the Tcl script specified by the <B>-opencommand</B> option is invoked. If the <B>-recurse</B> flag is present, then each descendant is recursively opened. </DD> <DT><I>pathName <B>range</B></I> ?<B>-open</B>? <I>first last</I> </DT> <DD>Returns the ids in depth-first order of the nodes between the <I>first</I> and <I>last</I> ids. If the <B>-open</B> flag is present, it indicates to consider only open nodes. If <I>last</I> is before <I>first</I>, then the ids are returned in reverse order. </DD> <DT><I>pathName <B>scan</B></I> <I>option args</I> </DT> <DD>This command implements scanning. It has two forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>scan mark <I>x y</I></B></I> </DT> <DD>Records <I>x</I> and <I>y</I> and the current view in the treeview window; used in conjunction with later <B>scan dragto</B> commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. </DD> <DT><I>pathName <B>scan dragto <I>x y</I></B></I>. </DT> <DD>Computes the difference between its <I>x</I> and <I>y</I> arguments and the <I>x</I> and <I>y</I> arguments to the last <B>scan mark</B> command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>see</B></I> ?<B>-anchor <I>anchor</I></B>? <I>tagOrId</I> </DT> <DD>Adjusts the view of entries so that the node given by <I>tagOrId</I> is visible in the widget window. It is an error if <B>tagOrId</B> is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the <B>-anchor</B> flag. Its value is a Tk anchor position. </DD> <DT><I>pathName <B>selection <I>option arg</I></B></I> </DT> <DD>This command is used to adjust the selection within a <B>treeview</B> widget. It has several forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>selection anchor <I>tagOrId</I></B></I> </DT> <DD>Sets the selection anchor to the node given by <I>tagOrId</I>. If <I>tagOrId</I> refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>anchor</B> may be used to refer to the anchor node. </DD> <DT><I>pathName <B>selection cancel</B></I> </DT> <DD>Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the <B>selection mark</B> operation. </DD> <DT><I>pathName <B>selection clear <I>first </I></B></I>?<I>last</I>? </DT> <DD>Removes the entries between <I>first</I> and <I>last</I> (inclusive) from the selection. Both <I>first</I> and <I>last</I> are ids representing a range of entries. If <I>last</I> isn't given, then only <I>first</I> is deselected. Entries outside the selection are not affected. </DD> <DT><I>pathName <B>selection clearall</B></I> </DT> <DD>Clears the entire selection. </DD> <DT><I>pathName <B>selection mark <I>tagOrId</I></B></I> </DT> <DD>Sets the selection mark to the node given by <I>tagOrId</I>. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>mark</B> may be used to refer to the current mark node. If <I>tagOrId</I> refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. </DD> <DT><I>pathName <B>selection includes <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node given by <I>tagOrId</I> is currently selected, 0 if it isn't. </DD> <DT><I>pathName <B>selection present</B></I> </DT> <DD>Returns 1 if any nodes are currently selected and 0 otherwise. </DD> <DT><I>pathName <B>selection set <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects all of the nodes in the range between <I>first</I> and <I>last</I>, inclusive, without affecting the selection state of nodes outside that range. </DD> <DT><I>pathName <B>selection toggle <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects/deselects nodes in the range between <I>first</I> and <I>last</I>, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>show </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Exposes all nodes matching the criteria given by <I>flags</I>. This is the inverse of the <B>hide</B> operation. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD><B>-glob</B> Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Expose nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>sort</B></I> ?<I>operation</I>? <I>args...</I> </DT> <DD><blockquote></DD> <DT><I>pathName <B>sort auto</B></I> ?<I>boolean</I> </DT> <DD>Turns on/off automatic sorting of node entries. If <I>boolean</I> is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no <I>boolean</I> argument is provided, the current state is returned. </DD> <DT><I>pathName <B>sort cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>sort configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the sorting configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: <blockquote></DD> <DT><B>-column<I> string</I></B> </DT> <DD>Specifies the column to sort. Entries in the widget are rearranged according to this column. If <I>column</I> is <I>""</I> then no sort is performed. </DD> <DT><B>-command<I> string</I></B> </DT> <DD>Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. </DD> <DT><B>-decreasing<I> boolean</I></B> </DT> <DD>Indicates to sort in ascending/descending order. If <I>boolean</I> is true, then the entries as in descending order. The default is <I>no</I>. </DD> <DT><B>-mode<I> string</I></B> </DT> <DD>Specifies how to compare entries when sorting. <I>String</I> may be one of the following: <blockquote></DD> <DT><I>ascii</I> </DT> <DD>Use string comparison based upon the ASCII collation order. </DD> <DT><I>dictionary</I> </DT> <DD>Use dictionary-style comparison. This is the same as <I>ascii</I> except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". </DD> <DT><I>integer</I> </DT> <DD>Compares fields as integers. </DD> <DT><I>real</I> </DT> <DD>Compares fields as floating point numbers. </DD> <DT><I>command</I> </DT> <DD>Use the Tcl proc specified by the <B>-command</B> option to compare entries when sorting. If no command is specified, the sort reverts to <I>ascii</I> sorting. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>sort once</B></I> ?<I>flags</I>? <I>tagOrId...</I> </DT> <DD>Sorts the children for each entries specified by <I>tagOrId</I>. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. <blockquote></DD> <DT><B>-recurse</B> </DT> <DD>Recursively sort the entire branch, not just the children. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>tag <I>operation args</I></B></I> </DT> <DD>Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. <P> Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for tags are listed below. <blockquote></DD> <DT><I>pathName</I> <B>tag add</B> <I>string</I> <I>id</I>... </DT> <DD>Adds the tag <I>string</I> to one of more entries. </DD> <DT><I>pathName</I> <B>tag delete</B> <I>string</I> <I>id</I>... </DT> <DD>Deletes the tag <I>string</I> from one or more entries. </DD> <DT><I>pathName</I> <B>tag forget</B> <I>string</I> </DT> <DD>Removes the tag <I>string</I> from all entries. It's not an error if no entries are tagged as <I>string</I>. </DD> <DT><I>pathName</I> <B>tag names</B> ?<I>id</I>? </DT> <DD>Returns a list of tags used. If an <I>id</I> argument is present, only those tags used by the node designated by <I>id</I> are returned. </DD> <DT><I>pathName</I> <B>tag nodes</B> <I>string</I> </DT> <DD>Returns a list of ids that have the tag <I>string</I>. If no node is tagged as <I>string</I>, then an empty string is returned. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>text apply</B></I> </DT> <DD>Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. </DD> <DT><I>pathName <B>text cancel</B></I> </DT> <DD>Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. </DD> <DT><I>pathName <B>text cget<I> value</I></B></I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>text configure</B></I> ?<I>option value</I>? </DT> <DD>Query or modify the configuration options of the edit window. If no <I>option</I> is specified, returns a list describing all of the available options (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TEXT EDITING OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text delete<I> first last</I></B></I> </DT> <DD>Deletes the characters in the edit buffer between the two given character positions. </DD> <DT><I>pathName <B>text get</B></I> ?<I>-root</I>? <I>x y</I> </DT> <DD></DD> <DT><I>pathName <B>text icursor<I> index</I></B></I> </DT> <DD></DD> <DT><I>pathName <B>text index<I> index</I></B></I> </DT> <DD>Returns the text index of given <I>index</I>. </DD> <DT><I>pathName <B>text insert<I> index string</I></B></I> </DT> <DD>Insert the text string <I>string</I> into the edit buffer at the index <I>index</I>. For example, the index 0 will prepend the buffer. </DD> <DT><I>pathName <B>text selection<I> args</I></B></I> </DT> <DD>This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: <blockquote></DD> <DT><I>pathName <B>text selection adjust<I> index</I></B></I> </DT> <DD>Adjusts either the first or last index of the selection. </DD> <DT><I>pathName <B>text selection clear</B></I> </DT> <DD>Clears the selection. </DD> <DT><I>pathName <B>text selection from<I> index</I></B></I> </DT> <DD>Sets the anchor of the selection. </DD> <DT><I>pathName <B>text selection present</B></I> </DT> <DD>Indicates if a selection is present. </DD> <DT><I>pathName <B>text selection range<I> start end</I></B></I> </DT> <DD>Sets both the anchor and mark of the selection. </DD> <DT><I>pathName <B>text selection to<I> index</I></B></I> </DT> <DD>Sets the unanchored end (mark) of the selection. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>toggle <I>tagOrId</I></B></I> </DT> <DD>Opens or closes the node given by <I>tagOrId</I>. If the corresponding <B>-opencommand</B> or <B>-closecommand</B> option is set, then that command is also invoked. </DD> <DT><I>pathName <B>xview <I>args</I></B></I> </DT> <DD>This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>xview</B></I> </DT> <DD>Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the <B>treeview</B> widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the <B>-xscrollcommand</B> option. </DD> <DT><I>pathName <B>xview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the character position given by <I>tagOrId</I> is displayed at the left edge of the window. Character positions are defined by the width of the character <B>0</B>. </DD> <DT><I>pathName <B>xview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that <I>fraction</I> of the total width of the <B>treeview</B> widget's text is off-screen to the left. <I>fraction</I> must be a fraction between 0 and 1. </DD> <DT><I>pathName <B>xview scroll <I>number what</I></B></I> </DT> <DD>This command shifts the view in the window left or right according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B> or an abbreviation of one of these. If <I>what</I> is <B>units</B>, the view adjusts left or right by <I>number</I> character units (the width of the <B>0</B> character) on the display; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>yview <I>?args</I></B></I>? </DT> <DD>This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>yview</B></I> </DT> <DD>Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the <B>-yscrollcommand</B> option. </DD> <DT><I>pathName <B>yview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the node given by <I>tagOrId</I> is displayed at the top of the window. </DD> <DT><I>pathName <B>yview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that the node given by <I>fraction</I> appears at the top of the window. <I>Fraction</I> is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the <B>treeview</B> widget, and so on. </DD> <DT><I>pathName <B>yview scroll <I>number what</I></B></I> </DT> <DD>This command adjusts the view in the window up or down according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B>. If <I>what</I> is <B>units</B>, the view adjusts up or down by <I>number</I> lines; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then earlier nodes become visible; if it is positive then later nodes become visible. </DD> </DL> </blockquote> <H2><A NAME="sect11" HREF="#toc11">Treeview Options</A></H2> In addition to the <B>configure</B> operation, widget configuration options may also be set by the Tk <B>option</B> command. The class resource name is <I>TreeView</I>. <BR> <CODE>option add *TreeView.Foreground white<BR> option add *TreeView.Background blue<BR> </CODE><P>The following widget options are available: <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed for an entry's icon when it is active. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-autocreate <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-allowduplicates <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the widget. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's <B>-closecommand</B> option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-dashes <I>number</I></B> </DT> <DD>Sets the dash style of the horizontal and vertical lines drawn connecting entries. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, solid lines will be drawn. The default is <I>1</I> (dotted). </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>; the value of the selection will be the label of the selected nodes, separated by newlines. The default is <I>no</I>. </DD> <DT><B>-flat <I>boolean</I></B> </DT> <DD>Indicates whether to display the tree as a flattened list. If <I>boolean</I> is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the <FONT SIZE=-1><B>SORT OPERATIONS</B></FONT> section for more information. The default is <I>no</I>. </DD> <DT><B>-focusdashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, a solid line will be drawn. The default is <I>1</I>. </DD> <DT><B>-focusforeground <I>color</I></B> </DT> <DD>Sets the color of the focus rectangle. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font for entry labels. You can override this for individual entries with the entry's <B>-font</B> configuration option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of entry labels. You can override this for individual entries with the entry's <B>-foreground</B> configuration option. The default is <I>black</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>400</I>. </DD> <DT><B>-hideroot <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, it indicates that no entry for the root node should be displayed. The default is <I>no</I>. </DD> <DT><B>-highlightbackground <I>color</I></B> </DT> <DD>Specifies the normal color of the traversal highlight region when the widget does not have the input focus. </DD> <DT><B>-highlightcolor <I>color</I></B> </DT> <DD>Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is <I>black</I>. </DD> <DT><B>-highlightthickness <I>pixels</I></B> </DT> <DD>Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to <B>Tk_GetPixels</B>. If the value is zero, no focus highlight will be displayed. The default is <I>2</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images for the entry's icon. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-linecolor <I>color</I></B> </DT> <DD>Sets the color of the connecting lines drawn between entries. The default is <I>black</I>. </DD> <DT><B>-linespacing <I>pixels</I></B> </DT> <DD>Sets the number of pixels spacing between entries. The default is <I>0</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the lines drawn connecting entries. If <I>pixels</I> is <I>0</I>, no vertical or horizontal lines are drawn. The default is <I>1</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's <B>-opencommand</B> configuration option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the widget. <I>Relief</I> specifies how the <B>treeview</B> widget should appear relative to widget it is packed into; for example, <I>raised</I> means the <B>treeview</B> widget should appear to protrude. The default is <I>sunken</I>. </DD> <DT><B>-scrollmode <I>mode</I></B> </DT> <DD>Specifies the style of scrolling to be used. The following styles are valid. This is the default is <I>hierbox</I>. <blockquote></DD> <DT><I>listbox</I> </DT> <DD>Like the <B>listbox</B> widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. </DD> <DT><I>hierbox</I> </DT> <DD>Like the <B>hierbox</B> widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. </DD> <DT><I>canvas</I> </DT> <DD>Like the <B>canvas</B> widget, the entries are bound within the scrolling area. </DD> </DL> </blockquote> <DL> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background color selected node entries. The default is <I>#ffffea</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is <I>0</I>. <B>-selectcommand <I>string</I></B> Specifies a Tcl script to invoked when the set of selected nodes changes. The default is <I>""</I>. </DD> <DT><B>-selectforeground <I>color<B> </B></I></B></DT> <DD>Sets the color of the labels of selected node entries. The default is <I>black</I>. </DD> <DT><B>-selectmode <I>mode</I></B> </DT> <DD>Specifies the selection mode. If <I>mode</I> is <I>single</I>, only one node can be selected at a time. If <I>multiple</I> more than one node can be selected. The default is <I>single</I>. </DD> <DT><B>-separator <I>string</I></B> </DT> <DD>Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If <I>string</I> is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is <I>""</I>. </DD> <DT><B>-showtitles <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is false, column titles are not be displayed. The default is <I>yes</I>. </DD> <DT><B>-sortselection <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is <I>no</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>"1"</I>. </DD> <DT><B>-trim <I>string</I></B> </DT> <DD>Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the <B>-separator</B> is also set. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the widget. If <I>pixels</I> is 0, then the with is computed from the contents of the <B>treeview</B> widget. The default is <I>200</I>. </DD> <DT><B>-xscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-xscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the horizontal scrolling distance. The default is 20 pixels. </DD> <DT><B>-yscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-yscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the vertical scrolling distance. The default is 20 pixels. </DD> </DL> <H2><A NAME="sect12" HREF="#toc12">Entry Options</A></H2> Many widget configuration options have counterparts in entries. For example, there is a <B>-closecommand</B> configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. <P> There is no resource class or name for entries. <DL> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed as the entry's icon when it is active. This overrides the global <B>-activeicons</B> configuration option for the specific entry. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for nodes. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is <I>all</I>. </DD> <DT><B>-button <I>string</I></B> </DT> <DD>Indicates whether a button should be displayed on the left side of the node entry. <I>String</I> can be <I>yes</I>, <I>no</I>, or <I>auto</I>. If <I>auto</I>, then a button is automatically displayed if the node has children. This is the default. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the node is closed. This overrides the global <B>-closecommand</B> option for this entry. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-data <I>string</I></B> </DT> <DD>Sets data fields for the node. <I>String</I> is a list of name-value pairs to be set. The default is <I>""</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for entry labels. This overrides the widget's <B>-font</B> option for this node. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of the entry label. This overrides the widget's <B>-foreground</B> configuration option. The default is <I>""</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images to be displayed for the entry's icon. This overrides the global <B>-icons</B> configuration option. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-label <I>string</I></B> </DT> <DD>Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is <I>""</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's <B>-opencommand</B> option for this node. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <H2><A NAME="sect13" HREF="#toc13">Button Options</A></H2> Button configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Button</I>. The resource name is always <I>button</I>. <BR> <CODE>option add *TreeView.Button.Foreground white<BR> option add *TreeView.button.Background blue<BR> </CODE><P>The following are the configuration options available for buttons. <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the button. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the button. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-closerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the closed button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Sets the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of buttons. The default is <I>black</I>. </DD> <DT><B>-images <I>images</I></B> </DT> <DD>Specifies images to be displayed for the button. <I>Images</I> is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the <I>images</I> is the empty string, then a plus/minus gadget is drawn. The default is <I>""</I>. </DD> <DT><B>-openrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the open button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-size <I>pixels</I></B> </DT> <DD>Sets the requested size of the button. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect14" HREF="#toc14">Column Options</A></H2> Column configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Column</I>. The resource name is the name of the column. <BR> <CODE>option add *TreeView.Column.Foreground white<BR> option add *TreeView.treeView.Background blue<BR> </CODE><P>The following configuration options are available for columns. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the column. This overrides the widget's <B>-background</B> option. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border of the column. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>0</I>. </DD> <DT><B>-edit <I>boolean</I></B> </DT> <DD>Indicates if the column's data fields can be edited. If <I>boolean</I> is false, the data fields in the column may not be edited. The default is <I>yes</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Specifies the foreground color of the column. You can override this for individual entries with the entry's <B>-foreground</B> option. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for a column. You can override this for individual entries with the entry's <B>-font</B> option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the column is not displayed. The default is <I>yes</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>left</I>. </DD> <DT><B>-pad <I>pad</I></B> </DT> <DD>Specifies how much padding for the left and right sides of the column. <I>Pad</I> is a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the column is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the column. <I>Relief</I> specifies how the column should appear relative to the widget; for example, <I>raised</I> means the column should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-state <I>state</I></B> </DT> <DD>Sets the state of the column. If <I>state</I> is <I>disable</I> then the column title can not be activated nor invoked. The default is <I>normal</I>. </DD> <DT><B>-text <I>string</I></B> </DT> <DD>Sets the title for the column. The default is <I>""</I>. </DD> <DT><B>-titleforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the column title. The default is <I>black</I>. </DD> <DT><B>-titleshadow <I>color</I></B> </DT> <DD>Sets the color of the drop shadow of the column title. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the column. This overrides the computed with of the column. If <I>pixels</I> is 0, the width is computed as from the contents of the column. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect15" HREF="#toc15">Text Editing Options</A></H2> Text edit window configuration options may also be set by the <B>option</B> command. The resource class is <I>TreeViewEditor</I>. The resource name is always <I>edit</I>. <BR> <CODE>option add *TreeViewEditor.Foreground white<BR> option add *edit.Background blue<BR> </CODE><P>The following are the configuration options available for the text editing window. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the text edit window. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the edit window. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the edit window. <I>Relief</I> indicates how the background should appear relative to the edit window; for example, <I>raised</I> means the background should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the selected text in the edit window. The <B>-selectrelief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-selectforeground <I>color</I></B> </DT> <DD>Sets the foreground of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the selected text in the edit window. <I>Relief</I> indicates how the text should appear relative to the edit window; for example, <I>raised</I> means the text should appear to protrude. The default is <I>flat</I>. </DD> </DL> </blockquote> <H2><A NAME="sect16" HREF="#toc16">Default Bindings</A></H2> Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a <B>treeview</B> widget is determined by its <B>-selectmode</B> option, which selects one of two ways of dealing with the selection. <P> If the selection mode is <B>single</B>, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. <P> If the selection mode is <B>multiple</B>, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. <OL> <LI>In <B>extended</B> mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. </LI><LI>In <B>extended</B> mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. </LI><LI>If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. </LI><LI>Mouse button 2 may be used for scanning. If it is pressed and dragged over the <B>treeview</B> widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. </LI><LI>If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is <B>browse</B> or <B>extended</B> then the new active entry is also selected and all other entries are deselected. In <B>extended</B> mode the new active entry becomes the selection anchor. </LI><LI>In <B>extended</B> mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. </LI><LI>The Left and Right keys scroll the <B>treeview</B> widget view left and right by the width of the character <B>0</B>. Control-Left and Control-Right scroll the <B>treeview</B> widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. </LI><LI>The Prior and Next keys scroll the <B>treeview</B> widget view up and down by one page (the height of the window). </LI><LI>The Home and End keys scroll the <B>treeview</B> widget horizontally to the left and right edges, respectively. </LI><LI>Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. </LI><LI>Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. </LI><LI>In <B>extended</B> mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. </LI><LI>In <B>multiple</B> mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. </LI><LI>The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. </LI><LI>In <B>extended</B> mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. </LI><LI>In <B>extended</B> mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. </LI><LI>Control-slash selects everything in the widget, except in <B>single</B> and <B>browse</B> modes, in which case it selects the active entry and deselects everything else. </LI><LI>Control-backslash deselects everything in the widget, except in <B>browse</B> mode where it has no effect. </LI><LI>The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. </LI> </OL> <P> The behavior of <B>treeview</B> widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. <H3><A NAME="sect17" HREF="#toc17">Widget Bindings</A></H3> In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. <DL> <DT><I>&lt;ButtonPress-2&gt;</I></DT> <DD>Starts scanning. </DD> <DT><I>&lt;B2-Motion&gt;</I></DT> <DD>Adjusts the scan. </DD> <DT><I>&lt;ButtonRelease-2&gt;</I></DT> <DD>Stops scanning. </DD> <DT><I>&lt;B1-Leave&gt;</I></DT> <DD>Starts auto-scrolling. </DD> <DT><I>&lt;B1-Enter&gt;</I></DT> <DD>Starts auto-scrolling </DD> <DT><I>&lt;KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous entry. </DD> <DT><I>&lt;KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next entry. </DD> <DT><I>&lt;Shift-KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous sibling. </DD> <DT><I>&lt;Shift-KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next sibling. </DD> <DT><I>&lt;KeyPress-Prior&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Next&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Left&gt;</I></DT> <DD>Closes the entry. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-Right&gt;</I></DT> <DD>Opens the entry, displaying its children. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-space&gt;</I></DT> <DD>In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). </DD> <DT><I>&lt;KeyRelease-space&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress-Return&gt;</I></DT> <DD>Sets the focus to the current entry. </DD> <DT><I>&lt;KeyRelease-Return&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress&gt;</I></DT> <DD>Moves to the next entry whose label starts with the letter typed. </DD> <DT><I>&lt;KeyPress-Home&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-End&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-F1&gt;</I></DT> <DD>Opens all entries. </DD> <DT><I>&lt;KeyPress-F2&gt;</I></DT> <DD>Closes all entries (except root). </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Button Bindings</A></H3> Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the button of the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the button back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the view so that the current entry is visible. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Entry Bindings</A></H3> Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to modify them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the entry back to its normal state. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the selection anchor the current entry. </DD> <DT><I>&lt;Double-ButtonPress-1&gt;</I></DT> <DD>Toggles the selection of the current entry. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>For "multiple" mode only. Sets the selection anchor to the current entry. </DD> <DT><I>&lt;Shift-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Extends the selection. </DD> <DT><I>&lt;Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-ButtonRelease-1&gt;</I></DT> <DD>Stop auto-scrolling. </DD> <DT><I>&lt;Control-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Toggles and extends the selection. </DD> <DT><I>&lt;Control-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-ButtonRelease-1&gt;</I></DT> <DD>Stops auto-scrolling. </DD> <DT><I>&lt;Control-Shift-ButtonPress-1&gt;</I></DT> <DD>??? </DD> <DT><I>&lt;Control-Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Column Bindings</A></H3> Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the <B>column bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current column title. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Invokes the command (see the column's -command option) if one if specified. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Column Rule Bindings</A></H3> <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current and activates the ruler. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. Deactivates the ruler. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the resize anchor for the column. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>Sets the resize mark for the column. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the size of the column, based upon the resize anchor and mark positions. </DD> </DL> <H2><A NAME="sect22" HREF="#toc22">Example</A></H2> The <B>treeview</B> command creates a new widget. <BR> <CODE>treeview .h -bg white<BR> </CODE><P>A new Tcl command <I>.h</I> is also created. This command can be used to query and modify the <B>treeview</B> widget. For example, to change the background color of the table to "green", you use the new command and the widget's <B>configure</B> operation. <BR> <CODE># Change the background color.<BR> .h configure -background "green"<BR> </CODE><P>By default, the <B>treeview</B> widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the <B>-tree</B> option to specify the name of another tree. <BR> <CODE># View the tree "myTree".<BR> .h configure -tree "myTree"<BR> </CODE><P>When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always <I>0</I> (you can use also use the special id <I>root</I>). The <B>insert</B> operation lets you insert one or more new entries into the tree. The last argument is the node's <I>pathname</I>. <BR> <CODE># Create a new entry named "myEntry"<BR> set id [.h insert end "myEntry"]<BR> </CODE><P>This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. <BR> <CODE># Prepend "fred".<BR> set id [.h insert 0 "fred"]<BR> </CODE><P>Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the <B>-label</B> option. <BR> <CODE># Create a new node named "fred"<BR> set id [.h insert end "fred" -label "Fred Flintstone"]<BR> </CODE><P>The <B>insert</B> operation returns the id of the new node. You can also use the <B>index</B> operation to get this information. <BR> <CODE># Get the id of "fred"<BR> .h index "fred"<BR> </CODE><P>To insert a node somewhere other than root, use the <B>-at</B> switch. It takes the id of the node where the new child will be added. <BR> <CODE># Create a new node "barney" in "fred".<BR> .h insert -at $id end "barney" <BR> </CODE><P>A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. <BR> <CODE># Create a new sub-entry of "fred"<BR> .h insert end "fred barney" <BR> </CODE><P>Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the <B>-autocreate</B> configuration option to force the creation of ancestor nodes. <BR> <CODE># Force the creation of ancestors.<BR> .h configure -autocreate yes <BR> .h insert end "fred barney wilma betty" <BR> </CODE><P>Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the <B>-separator</B> option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. <BR> <CODE>.h configure -separator /<BR> .h insert end "/usr/local/tcl/bin" <BR> </CODE><P>If the path is prefixed by extraneous characters, you can automatically trim it off using the <B>-trim</B> option. It removed the string from the path before it is parsed. <BR> <CODE>.h configure -trim C:/windows -separator /<BR> .h insert end "C:/window/system" <BR> </CODE><P>You can insert more than one entry at a time with the <B>insert</B> operation. This can be much faster than looping over a list of names. <BR> <CODE># The slow way<BR> foreach f [glob $dir/*] {<BR> .h insert end $f<BR> }<BR> # The fast way<BR> eval .h insert end [glob $dir/*]<BR> </CODE><P>In this case, the <B>insert</B> operation will return a list of ids of the new entries. <P> You can delete entries with the <B>delete</B> operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. <BR> <CODE>.h delete $id<BR> </CODE><P>Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the <B>-label</B> option that sets the entry's text label. The <B>entry configure</B> operation lets you set or modify an entry's configuration options. <BR> <CODE>.h entry configure $id -color red -font fixed<BR> </CODE><P>You can hide an entry and its children using the <B>-hide</B> option. <BR> <CODE>.h entry configure $id -hide yes<BR> </CODE><P>More that one entry can be configured at once. All entries specified are configured with the same options. <BR> <CODE>.h entry configure $i1 $i2 $i3 $i4 -color brown <BR> </CODE><P>An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's <B>-icons</B> option. It takes a list of two image names: one to represent the open entry, another when it is closed. <BR> <CODE>set im1 [image create photo -file openfolder.gif]<BR> set im2 [image create photo -file closefolder.gif]<BR> .h entry configure $id -icons "$im1 $im2"<BR> </CODE><P>If <B>-icons</B> is set to the empty string, no icons are display. <P> If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a <I>+</I> or <I>-</I> symbol, but can be configured in a variety of ways using the <B>button configure</B> operation. For example, the <I>+</I> and <I>-</I> symbols can be replaced with Tk images. <BR> <CODE>set im1 [image create photo -file closefolder.gif]<BR> set im2 [image create photo -file downarrow.gif]<BR> .h button configure $id -images "$im1 $im2" \<BR> -openrelief raised -closerelief raised<BR> </CODE><P>Entries can contain an arbitrary number of <I>data fields</I>. Data fields are name-value pairs. Both the value and name are strings. The entry's <B>-data</B> option lets you set data fields. <BR> <CODE>.h entry configure $id -data {mode 0666 group users}<BR> </CODE><P>The <B>-data</B> takes a list of name-value pairs. <P> You can display these data fields as <I>columns</I> in the <B>treeview</B> widget. You can create and configure columns with the <B>column</B> operation. For example, to add a new column to the widget, use the <B>column insert</B> operation. The last argument is the name of the data field that you want to display. <BR> <CODE>.h column insert end "mode"<BR> </CODE><P>The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's <B>-text</B> option. <BR> <CODE>.h column insert end "mode" -text "File Permissions"<BR> </CODE><P>Columns have several configuration options. The <B>column configure</B> operation lets you query or modify column options. <BR> <CODE>.h column configure "mode" -justify left<BR> </CODE><P>The <B>-justify</B> option says how the data is justified within in the column. The <B>-hide</B> option indicates whether the column is displayed. <BR> <CODE>.h column configure "mode" -hide yes<BR> </CODE><P>Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the <B>-selectforeground</B> and <B>-selectbackground</B> configuration options. The selection itself is managed by the <B>selection</B> operation. <BR> <CODE># Clear all selections<BR> .h selection clear 0 end<BR> # Select the root node<BR> .h selection set 0 <BR> </CODE><P>The <B>curselection</B> operation returns a list of ids of all the selected entries. <BR> <CODE>set ids [.h curselection]<BR> </CODE><P>You can use the <B>get</B> operation to convert the ids to their pathnames. <BR> <CODE>set names [eval .h get -full $ids]<BR> </CODE><P>If a treeview is exporting its selection (using the <B>-exportselection</B> option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type <B>STRING</B>; the value of the selection will be the pathnames of the selected entries, separated by newlines. <P> The <B>treeview</B> supports two modes of selection: <I>single</I> and <I>multiple</I>. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -selectmode "multiple"<BR> </CODE><P>You can be notified when the list of selected entries changes. The widget's <B>-selectcommand</B> specifies a Tcl procedure that is called whenever the selection changes. <BR> <CODE>proc SelectNotify { widget } {<BR> set ids [$widget curselection]<BR> }<BR> .h configure -selectcommand "SelectNotify .h"<BR> </CODE><P>The widget supports the standard Tk scrolling and scanning operations. The <B>treeview</B> can be both horizontally and vertically. You can attach scrollbars to the <B>treeview</B> the same way as the listbox or canvas widgets. <BR> <CODE>scrollbar .xbar -orient horizontal -command ".h xview"<BR> scrollbar .ybar -orient vertical -command ".h yview"<BR> .h configure -xscrollcommand ".xbar set" \<BR> -yscrollcommand ".ybar set"<BR> </CODE><P>There are three different modes of scrolling: <I>listbox</I>, <I>canvas</I>, and <I>hierbox</I>. In <I>listbox</I> mode, the last entry can always be scrolled to the top of the widget. In <I>hierbox</I> mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -scrollmode "listbox"<BR> </CODE><P>Entries can be programmatically opened or closed using the <B>open</B> and <B>close</B> operations respectively. <BR> <CODE>.h open $id<BR> .h close $id<BR> </CODE><P>When an entry is opened, a Tcl procedure can be automatically invoked. The <B>-opencommand</B> option specifies this procedure. This procedure can lazily insert entries as needed. <BR> <CODE>proc AddEntries { dir } {<BR> eval .h insert end [glob -nocomplain $dir/*] <BR> }<BR> .h configure -opencommand "AddEntries %P"<BR> </CODE><P>Now when an entry is opened, the procedure <I>AddEntries</I> is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like <B>bind</B>) are performed. Above, <I>%P</I> is translated to the pathname of the entry. <P> The same feature exists when an entry is closed. The <B>-closecommand</B> option specifies the procedure. <BR> <CODE>proc DeleteEntries { id } {<BR> .h entry delete $id 0 end<BR> }<BR> .h configure -closecommand "DeleteEntries %#"<BR> </CODE><P>When an entry is closed, the procedure <I>DeleteEntries</I> is called and deletes the entry's children using the <B>entry delete</B> operation (<I>%#</I> is the id of entry). <H2><A NAME="sect23" HREF="#toc23">Keywords</A></H2> treeview, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Tree Data Object</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">IDs and Tags</A></LI> <LI><A NAME="toc7" HREF="#sect7">Special Node IDs</A></LI> <LI><A NAME="toc8" HREF="#sect8">Data Fields</A></LI> <LI><A NAME="toc9" HREF="#sect9">Entry Bindings</A></LI> <LI><A NAME="toc10" HREF="#sect10">Treeview Operations</A></LI> <LI><A NAME="toc11" HREF="#sect11">Treeview Options</A></LI> <LI><A NAME="toc12" HREF="#sect12">Entry Options</A></LI> <LI><A NAME="toc13" HREF="#sect13">Button Options</A></LI> <LI><A NAME="toc14" HREF="#sect14">Column Options</A></LI> <LI><A NAME="toc15" HREF="#sect15">Text Editing Options</A></LI> <LI><A NAME="toc16" HREF="#sect16">Default Bindings</A></LI> <UL> <LI><A NAME="toc17" HREF="#sect17">Widget Bindings</A></LI> <LI><A NAME="toc18" HREF="#sect18">Button Bindings</A></LI> <LI><A NAME="toc19" HREF="#sect19">Entry Bindings</A></LI> <LI><A NAME="toc20" HREF="#sect20">Column Bindings</A></LI> <LI><A NAME="toc21" HREF="#sect21">Column Rule Bindings</A></LI> </UL> <LI><A NAME="toc22" HREF="#sect22">Example</A></LI> <LI><A NAME="toc23" HREF="#sect23">Keywords</A></LI> </UL> </BODY></HTML> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/Makefile.vc������������������������������������������������������������������0000644�0001750�0001750�00000001272�11462120062�015253� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for HTML files # ------------------------------------------------------------------------ include ../vc.config srcdir = ../$(TOP)/html instdirs = $(prefix) $(libdir) $(scriptdir) $(scriptdir)/html all: install: install-dirs install-html install-dirs: @for i in $(instdirs) ; do \ if test -d "$$i" ; then : ; else \ echo "mkdir $$i" ; \ mkdir "$$i" ; \ fi ; \ done install-html: install-dirs for i in $(srcdir)/*.html ; do \ $(INSTALL_DATA) $$i $(scriptdir)/html ; \ done clean: $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* distclean: clean $(RM) Makefile ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/hierbox.html�����������������������������������������������������������������0000644�0001750�0001750�00000300207�11462120062�015532� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>treeview(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> treeview - Create and manipulate hierarchical table widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>treeview</B> <I>pathName </I>?<I>options</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>treeview</B> widget displays a tree of data. It replaces both the <B>hiertable</B> and <B>hierbox</B> widgets. The <B>treeview</B> is 100% syntax compatible with the <B>hiertable</B> widget. The <B>hiertable</B> command is retained for sake of script-level compatibility. This widget obsoletes the <B>hierbox</B> widget. It does everything the old <B>hierbox</B> widget did, but also provides data sharing (via <I>tree data objects</I>) and the ability to tag nodes. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>treeview</B> widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. <P> A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is <I>open</I>, its children are exposed. When it is <I>closed</I>, the children and their descedants are hidden. The button is normally a <I>+</I> or <I>-</I> symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). <P> If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. <H2><A NAME="sect4" HREF="#toc4">Tree Data Object</A></H2> The tree is not stored inside the widget but in a tree data object (see the <B>tree</B> command for a further explanation). Tree data objects can be shared among different clients, such as a <B>treeview</B> widget or the <B>tree</B> command. You can walk the tree and manage its data with the <B>tree</B> command tree, while displaying it with the <B>treeview</B> widget. Whenever the tree is updated, the <B>treeview</B> widget is automatically redrawn. <P> By default, the <B>treeview</B> widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the <B>tree</B> command using the <B>-tree</B> configuration option. <B>Treeview</B> widgets can share the same tree object, possibly displaying different views of the same data. <P> A tree object has both a Tcl and C API. You can insert or delete nodes using <B>treeview</B> widget or <B>tree</B> command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. <H2><A NAME="sect5" HREF="#toc5">Syntax</A></H2> <BR> <P> <CODE><B>treeview <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>treeview</B> command creates a new window <I>pathName</I> and makes it into a <B>treeview</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the <B>configure</B> operation below for the exact details about what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>treeview</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available are described in the <FONT SIZE=-1><B>TREEVIEW OPERATIONS</B></FONT> section. <H2><A NAME="sect6" HREF="#toc6">IDs and Tags</A></H2> Nodes can be inserted into a tree using the <B>treeview</B> widget <BR> <CODE>blt::treeview .t<BR> set node [.t insert end root "one"]<BR> </CODE><P>or <B>tree</B> command. <BR> <CODE>set tree [blt::tree create]<BR> set node [$tree insert root "one"]<BR> </CODE><P>In both cases, a number identifying the node is returned (the value of <I>$node</I>). This serial number or <I>id</I> uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id <I>0</I>. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the <B>treeview</B> widget or the <B>tree</B> command. Ids are recycled when the node deleted. <P> A node may also have any number of <I>tags</I> associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "<I>x123</I>" is valid, but "<I>123</I>" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the <B>treeview</B> widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. <P> The tag <B>all</B> is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. <P> Tags may be shared, just like trees, between clients. For example, you can use the tags created by the <B>tree</B> command with <B>treeview</B> widgets. <H2><A NAME="sect7" HREF="#toc7">Special Node IDs</A></H2> There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the <B>treeview</B> widget. <DL> <DT><B>active</B> </DT> <DD>The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the <B>-activeicon</B> option). The <B>active</B> id is changed automatically by moving the mouse pointer over another node or by using the <B>entry activate</B> operation. Note that there can be only one active node at a time. </DD> <DT><B>anchor</B> </DT> <DD>The node representing the fixed end of the current selection. The anchor is set by the <B>selection anchor</B> operation. </DD> <DT><B>current</B> </DT> <DD>The node where the mouse pointer is currently located. But unlike <B>active</B>, this id changes while the selection is dragged. It is used to determine the current node during button drags. </DD> <DT><B>down</B> </DT> <DD>The next open node from the current focus. The <B>down</B> of the last open node is the same. </DD> <DT><B>end</B> </DT> <DD>The last open node (in depth-first order) on the tree. </DD> <DT><B>focus</B> </DT> <DD>The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the <B>focus</B> operation. </DD> <DT><B>last</B> </DT> <DD>The last open node from the current focus. But unlike <B>up</B>, when the focus is at root, <B>last</B> wraps around to the last open node in the tree. </DD> <DT><B>mark</B> </DT> <DD>The node representing the non-fixed end of the current selection. The mark is set by the <B>selection mark</B> operation. </DD> <DT><B>next</B> </DT> <DD>The next open node from the current focus. But unlike <B>down</B>, when the focus is on last open node, <B>next</B> wraps around to the root node. </DD> <DT><B>nextsibling</B> </DT> <DD>The next sibling from the node with the current focus. If the node is already the last sibling then it is the <B>nextsibling<B>. </DD> <DT><B>parent</B></B></B> </DT> <DD>The parent of the node with the current focus. The <B>parent</B> of the root is also the root. </DD> <DT><B>prevsibling</B> </DT> <DD>The previous sibling from the node with the current focus. If the node is already the first sibling then it is the <B>prevsibling<B>. </DD> <DT><B>root</B></B></B> </DT> <DD>The root node. You can also use id <I>0</I> to indicate the root. </DD> <DT><B>up</B> </DT> <DD>The last open node (in depth-first order) from the current focus. The <B>up</B> of the root node (i.e. the root has focus) is also the root. </DD> <DT><B>view.top</B> </DT> <DD>First node that's current visible in the widget. </DD> <DT><B>view.bottom</B> </DT> <DD>Last node that's current visible in the widget. </DD> <DT><I>path</I> </DT> <DD>Absolute path of a node. Path names refer to the node name, not their entry labels. Paths don't have to start with a separator (see the <B>-separator</B> configuration option), but component names must be separated by the designated separator. </DD> <DT><B>@<I>x<B>,<I>y</I></B></I></B> </DT> <DD>Indicates the node that covers the point in the treeview window specified by <I>x</I> and <I>y</I> (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. </DD> </DL> <P> A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. <H2><A NAME="sect8" HREF="#toc8">Data Fields</A></H2> A node in the tree can have <I>data fields</I>. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the <B>treeview</B> widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. <H2><A NAME="sect9" HREF="#toc9">Entry Bindings</A></H2> You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its <I>bindtags</I>. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag <I>all</I> that all node entries automatically have. <H2><A NAME="sect10" HREF="#toc10">Treeview Operations</A></H2> The <B>treeview</B> operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: <P> <BR> <CODE><I>pathName operation </I>?<I>arg arg ...</I>?<BR> <P> </CODE><P><I>Operation</I> and the <I>arg</I>s determine the exact behavior of the command. The following operation are available for <B>treeview</B> widgets: <DL> <DT><I>pathName <B>bbox</B></I> ?<B>-screen</B>? <I>tagOrId...</I> </DT> <DD>Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more <I>tagOrId</I> arguments. If the <B>-screen</B> flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from <I>0</I> from the root node. The returned list contains the following values. <blockquote></DD> <DT><I>x</I> </DT> <DD>X-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>y</I> </DT> <DD>Y-coordinate of the upper-left corner of the bounding box. </DD> <DT><I>width</I> </DT> <DD>Width of the bounding box. </DD> <DT><I>height</I> </DT> <DD>Height of the bounding box. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a node with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> entries, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This command is used to control the button selectors within a <B>treeview</B> widget. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>button activate</B></I> <I>tagOrId</I> </DT> <DD>Designates the node given by <I>tagOrId</I> as active. When a node is active it's entry is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active entry at a time. The special id <B>active</B> indicates the currently active node. </DD> <DT><I>pathName <B>button bind</B></I> <I>tagName</I> ?<I>sequence command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an button of a node entry with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on <B>treeview</B> buttons, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>button cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>button configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>BUTTON OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>close </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Closes the node specified by <I>tagOrId</I>. In addition, if a Tcl script was specified by the <B>-closecommand</B> option, it is invoked. If the node is already closed, this command has no effect. If the <B>-recurse</B> flag is present, each child node is recursively closed. </DD> <DT><I>pathName <B>column <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview columns. <blockquote></DD> <DT><I>pathName <B>column activate</B></I> <I>column</I> </DT> <DD>Sets the active column to <I>column</I>. <I>Column</I> is the name of a column in the widget. When a column is active, it's drawn using its <B>-activetitlebackground</B> and <B>-activetitleforeground</B> options. If <I>column</I> is the <I>""</I>, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. </DD> <DT><I>pathName <B>column cget</B></I> <I>name</I> <I>option</I> </DT> <DD>Returns the current value of the column configuration option given by <I>option</I> for <I>name</I>. <I>Name</I> is the name of column that corresponds to a data field. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>column configure</B></I> <I>name</I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the column designated by <I>name</I>. <I>Name</I> is the name of the column corresponding to a data field. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>COLUMN OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>column delete</B></I> <I>field</I> ?<I>field</I>...? </DT> <DD>Deletes one of more columns designated by <I>field</I>. Note that this does not delete the data fields themselves. </DD> <DT><I>pathName <B>column insert</B></I> <I>position</I> <I>field</I> ?<I>options</I>...? </DT> <DD>Inserts one of more columns designated by <I>field</I>. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. <I>Position</I> indicates where in the list of columns to add the new column. It may be either a number or <I>end</I>. </DD> <DT><I>pathName <B>column invoke</B></I> <I>field</I> </DT> <DD>Invokes the Tcl command associated with the column <I>field</I>, if there is one (using the column's <B>-command</B> option). The command is ignored if the column's <B>-state</B> option set to <I>disabled</I>. </DD> <DT><I>pathName <B>column move <I>name</I></B></I> <I>dest</I> </DT> <DD>Moves the column <I>name</I> to the destination position. <I>Dest</I> is the name of another column or a screen position in the form <I>@<I>x<I>,<I>y</I></I></I></I>. </DD> <DT><I>pathName <B>column names</B></I> </DT> <DD>Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. </DD> <DT><I>pathName <B>column nearest</B></I> <I>x</I> ?<I>y</I>? </DT> <DD>Returns the name of the column closest to the given X-Y screen coordinate. If you provide a <I>y</I> argument (it's optional), a name is returned only when if the point is over a column's title. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TREEVIEW OPTIONS</B></FONT> below. </DD> <DT><I>pathName <B>curselection</B></I> </DT> <DD>Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. </DD> <DT><I>pathName <B>delete <I>tagOrId</I></B></I>... </DT> <DD>Deletes one or more entries given by <I>tagOrId</I> and its children. </DD> <DT><I>pathName <B>entry <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>The following operations are available for treeview entries. <blockquote></DD> <DT><I>pathName <B>entry activate</B></I> <I>tagOrId</I> </DT> <DD>Sets the active entry to the one specified by <I>tagOrId</I>. When an entry is active it is drawn using its active icon (see the <B>-activeicon</B> option). Note that there can be only one active node at a time. The special id of the currently active node is <B>active</B>. </DD> <DT><I>pathName <B>entry cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>entry children</B></I> <I>tagOrId</I> ?<I>first</I>? ?<I>last</I>? </DT> <DD>Returns a list of ids for the given range of children of <I>tagOrId</I>. <I>TagOrId</I> is the id or tag of the node to be examined. If only a <I>first</I> argument is present, then the id of the that child at that numeric position is returned. If both <I>first</I> and <I>last</I> arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. </DD> <DT><I>pathName <B>entry configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: </DD> <DT><I>pathName <B>entry delete</B></I> <I>tagOrId</I> ?<I>first</I> ?<I>last</I>? </DT> <DD>Deletes the one or more children nodes of the parent <I>tagOrId</I>. If <I>first</I> and <I>last</I> arguments are present, they are positions designating a range of children nodes to be deleted. </DD> <DT><I>pathName <B>entry isbefore <I>tagOrId1</I></B></I> <I>tagOrId2</I> </DT> <DD>Returns 1 if <I>tagOrId1</I> is before <I>tagOrId2</I> and 0 otherwise. </DD> <DT><I>pathName <B>entry ishidden <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. </DD> <DT><I>pathName <B>entry isopen <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node is currently open and 0 otherwise. </DD> <DT><I>pathName <B>entry size</B></I> <B>-recurse</B> <I>tagOrId</I> </DT> <DD>Returns the number of children for parent node <I>tagOrId</I>. If the <B>-recurse</B> flag is set, the number of all its descendants is returned. The node itself is not counted. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>find </B></I>?<I>flags</I>? <I>first</I> <I>last</I> </DT> <DD>Finds for all entries matching the criteria given by <I>flags</I>. A list of ids for all matching nodes is returned. <I>First</I> and <I>last</I> are ids designating the range of the search in depth-first order. If <I>last</I> is before <I>first</I>, then nodes are searched in reverse order. The valid flags are: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Patterns must match exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Pick entries that don't match. </DD> <DT><B>-exec<I> string</I></B> </DT> <DD>Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-count<I> number</I></B> </DT> <DD>Stop searching after <I>number</I> matches. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>focus </B></I> <I>tagOrId</I> </DT> <DD>Sets the focus to the node given by <I>tagOrId</I>. When a node has focus, it can receive keyboard events. The special id <B>focus</B> designates the node that currently has focus. </DD> <DT><I>pathName <B>get </B></I>?<B>-full</B>? <I>tagOrId</I> <I>tagOrId</I>... </DT> <DD>Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the <B>-full</B> flag is set, then the full pathnames are returned. </DD> <DT><I>pathName <B>hide </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Hides all nodes matching the criteria given by <I>flags</I>. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the node entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD>Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Hide nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>index </B></I>?<B>-at</B> <I>tagOrId</I>? <I>string</I> </DT> <DD>Returns the id of the node specified by <I>string</I>. <I>String</I> may be a tag or node id. Some special ids are normally relative to the node that has focus. The <B>-at</B> flag lets you select another node. </DD> <DT><I>pathName <B>insert </B></I>?<B>-at <I>tagOrId</I></B>? <I>position</I> <I>path</I> ?<I>options...</I>? ?<I>path</I>? ?<I>options...</I>? </DT> <DD>Inserts one or more nodes at <I>position</I>. <I>Position</I> is the location (number or <I>end</I>) where the new nodes are added to the parent node. <I>Path</I> is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the <B>-separator</B> option). Pathnames are normally absolute, but the <B>-at</B> switch lets you select a relative starting point. Its value is the id of the starting node. <P> All ancestors of the new node must already exist, unless the <B>-autocreate</B> option is set. It is also an error if a node already exists, unless the <B>-allowduplicates</B> option is set. <P> <I>Option</I> and <I>value</I> may have any of the values accepted by the <B>entry configure</B> operation described in the <FONT SIZE=-1><B>ENTRY OPERATIONS</B></FONT> section below. This command returns a list of the ids of the new entries. </DD> <DT><I>pathName <B>move <I>tagOrId</I></B></I> <I>how</I> <I>destId</I> </DT> <DD>Moves the node given by <I>tagOrId</I> to the destination node. The node can not be an ancestor of the destination. <I>DestId</I> is the id of the destination node and can not be the root of the tree. In conjunction with <I>how</I>, it describes how the move is performed. <blockquote></DD> <DT><I>before</I> </DT> <DD>Moves the node before the destination node. </DD> <DT><I>after</I> </DT> <DD>Moves the node after the destination node. </DD> <DT><I>into</I> </DT> <DD>Moves the node to the end of the destination's list of children. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>nearest <I>x y</I></B></I> ?<I>varName</I>? </DT> <DD>Returns the id of the node entry closest to the given X-Y screen coordinate. The optional argument <I>varName</I> is the name of variable which is set to either <I>button</I> or <I>select</I> to indicate over what part of the node the coordinate lies. If the coordinate is not directly over any node, then <I>varName</I> will contain the empty string. </DD> <DT><I>pathName <B>open </B></I>?<B>-recurse</B>? <I>tagOrId...</I> </DT> <DD>Opens the one or more nodes specified by <I>tagOrId</I>. If a node is not already open, the Tcl script specified by the <B>-opencommand</B> option is invoked. If the <B>-recurse</B> flag is present, then each descendant is recursively opened. </DD> <DT><I>pathName <B>range</B></I> ?<B>-open</B>? <I>first last</I> </DT> <DD>Returns the ids in depth-first order of the nodes between the <I>first</I> and <I>last</I> ids. If the <B>-open</B> flag is present, it indicates to consider only open nodes. If <I>last</I> is before <I>first</I>, then the ids are returned in reverse order. </DD> <DT><I>pathName <B>scan</B></I> <I>option args</I> </DT> <DD>This command implements scanning. It has two forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>scan mark <I>x y</I></B></I> </DT> <DD>Records <I>x</I> and <I>y</I> and the current view in the treeview window; used in conjunction with later <B>scan dragto</B> commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. </DD> <DT><I>pathName <B>scan dragto <I>x y</I></B></I>. </DT> <DD>Computes the difference between its <I>x</I> and <I>y</I> arguments and the <I>x</I> and <I>y</I> arguments to the last <B>scan mark</B> command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>see</B></I> ?<B>-anchor <I>anchor</I></B>? <I>tagOrId</I> </DT> <DD>Adjusts the view of entries so that the node given by <I>tagOrId</I> is visible in the widget window. It is an error if <B>tagOrId</B> is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the <B>-anchor</B> flag. Its value is a Tk anchor position. </DD> <DT><I>pathName <B>selection <I>option arg</I></B></I> </DT> <DD>This command is used to adjust the selection within a <B>treeview</B> widget. It has several forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>selection anchor <I>tagOrId</I></B></I> </DT> <DD>Sets the selection anchor to the node given by <I>tagOrId</I>. If <I>tagOrId</I> refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>anchor</B> may be used to refer to the anchor node. </DD> <DT><I>pathName <B>selection cancel</B></I> </DT> <DD>Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the <B>selection mark</B> operation. </DD> <DT><I>pathName <B>selection clear <I>first </I></B></I>?<I>last</I>? </DT> <DD>Removes the entries between <I>first</I> and <I>last</I> (inclusive) from the selection. Both <I>first</I> and <I>last</I> are ids representing a range of entries. If <I>last</I> isn't given, then only <I>first</I> is deselected. Entries outside the selection are not affected. </DD> <DT><I>pathName <B>selection clearall</B></I> </DT> <DD>Clears the entire selection. </DD> <DT><I>pathName <B>selection mark <I>tagOrId</I></B></I> </DT> <DD>Sets the selection mark to the node given by <I>tagOrId</I>. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id <B>mark</B> may be used to refer to the current mark node. If <I>tagOrId</I> refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. </DD> <DT><I>pathName <B>selection includes <I>tagOrId</I></B></I> </DT> <DD>Returns 1 if the node given by <I>tagOrId</I> is currently selected, 0 if it isn't. </DD> <DT><I>pathName <B>selection present</B></I> </DT> <DD>Returns 1 if any nodes are currently selected and 0 otherwise. </DD> <DT><I>pathName <B>selection set <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects all of the nodes in the range between <I>first</I> and <I>last</I>, inclusive, without affecting the selection state of nodes outside that range. </DD> <DT><I>pathName <B>selection toggle <I>first </I></B></I>?<I>last</I>? </DT> <DD>Selects/deselects nodes in the range between <I>first</I> and <I>last</I>, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>show </B></I>?<B>flags</B>? <I>tagOrId</I>... </DT> <DD>Exposes all nodes matching the criteria given by <I>flags</I>. This is the inverse of the <B>hide</B> operation. The search is performed recursively for each node given by <I>tagOrId</I>. The valid flags are described below: <blockquote></DD> <DT><B>-name<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node names. </DD> <DT><B>-full<I> pattern</I></B> </DT> <DD>Specifies pattern to match against node pathnames. </DD> <DT><B>-<I>option<I> pattern</I></I></B> </DT> <DD>Specifies pattern to match against the entry's configuration option. </DD> <DT><B>-exact</B> </DT> <DD>Match patterns exactly. The is the default. </DD> <DT><B>-glob</B> </DT> <DD><B>-glob</B> Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: <blockquote></DD> <DT><I>*</I> </DT> <DD>Matches any sequence of characters in string, including a null string. </DD> <DT><I>?</I> </DT> <DD>Matches any single character in string. </DD> <DT><I>[<I>chars<I>]</I></I></I> </DT> <DD>Matches any character in the set given by <I>chars</I>. If a sequence of the form <I>x</I>-<I>y</I> appears in <I>chars</I>, then any character between <I>x</I> and <I>y</I>, inclusive, will match. </DD> <DT><I>\<I>x</I></I> </DT> <DD>Matches the single character <I>x</I>. This provides a way of avoiding the special interpretation of the characters <I>*?[]\</I> in the pattern. </DD> </DL> </blockquote> <DL> <DT><B>-regexp</B> </DT> <DD>Use regular expression pattern matching (i.e. the same as implemented by the <B>regexp</B> command). </DD> <DT><B>-nonmatching</B> </DT> <DD>Expose nodes that don't match. </DD> <DT><B>--</B> </DT> <DD>Indicates the end of flags. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>sort</B></I> ?<I>operation</I>? <I>args...</I> </DT> <DD><blockquote></DD> <DT><I>pathName <B>sort auto</B></I> ?<I>boolean</I> </DT> <DD>Turns on/off automatic sorting of node entries. If <I>boolean</I> is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no <I>boolean</I> argument is provided, the current state is returned. </DD> <DT><I>pathName <B>sort cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>sort configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the sorting configuration options of the widget. If no <I>option</I> is specified, returns a list describing all of the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: <blockquote></DD> <DT><B>-column<I> string</I></B> </DT> <DD>Specifies the column to sort. Entries in the widget are rearranged according to this column. If <I>column</I> is <I>""</I> then no sort is performed. </DD> <DT><B>-command<I> string</I></B> </DT> <DD>Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. </DD> <DT><B>-decreasing<I> boolean</I></B> </DT> <DD>Indicates to sort in ascending/descending order. If <I>boolean</I> is true, then the entries as in descending order. The default is <I>no</I>. </DD> <DT><B>-mode<I> string</I></B> </DT> <DD>Specifies how to compare entries when sorting. <I>String</I> may be one of the following: <blockquote></DD> <DT><I>ascii</I> </DT> <DD>Use string comparison based upon the ASCII collation order. </DD> <DT><I>dictionary</I> </DT> <DD>Use dictionary-style comparison. This is the same as <I>ascii</I> except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". </DD> <DT><I>integer</I> </DT> <DD>Compares fields as integers. </DD> <DT><I>real</I> </DT> <DD>Compares fields as floating point numbers. </DD> <DT><I>command</I> </DT> <DD>Use the Tcl proc specified by the <B>-command</B> option to compare entries when sorting. If no command is specified, the sort reverts to <I>ascii</I> sorting. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>sort once</B></I> ?<I>flags</I>? <I>tagOrId...</I> </DT> <DD>Sorts the children for each entries specified by <I>tagOrId</I>. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. <blockquote></DD> <DT><B>-recurse</B> </DT> <DD>Recursively sort the entire branch, not just the children. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>tag <I>operation args</I></B></I> </DT> <DD>Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. <P> Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for tags are listed below. <blockquote></DD> <DT><I>pathName</I> <B>tag add</B> <I>string</I> <I>id</I>... </DT> <DD>Adds the tag <I>string</I> to one of more entries. </DD> <DT><I>pathName</I> <B>tag delete</B> <I>string</I> <I>id</I>... </DT> <DD>Deletes the tag <I>string</I> from one or more entries. </DD> <DT><I>pathName</I> <B>tag forget</B> <I>string</I> </DT> <DD>Removes the tag <I>string</I> from all entries. It's not an error if no entries are tagged as <I>string</I>. </DD> <DT><I>pathName</I> <B>tag names</B> ?<I>id</I>? </DT> <DD>Returns a list of tags used. If an <I>id</I> argument is present, only those tags used by the node designated by <I>id</I> are returned. </DD> <DT><I>pathName</I> <B>tag nodes</B> <I>string</I> </DT> <DD>Returns a list of ids that have the tag <I>string</I>. If no node is tagged as <I>string</I>, then an empty string is returned. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on <I>operation</I>: <blockquote></DD> <DT><I>pathName <B>text apply</B></I> </DT> <DD>Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. </DD> <DT><I>pathName <B>text cancel</B></I> </DT> <DD>Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. </DD> <DT><I>pathName <B>text cget<I> value</I></B></I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>text configure</B></I> ?<I>option value</I>? </DT> <DD>Query or modify the configuration options of the edit window. If no <I>option</I> is specified, returns a list describing all of the available options (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described in the section <FONT SIZE=-1><B>TEXT EDITING OPTIONS</B></FONT> below. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>text delete<I> first last</I></B></I> </DT> <DD>Deletes the characters in the edit buffer between the two given character positions. </DD> <DT><I>pathName <B>text get</B></I> ?<I>-root</I>? <I>x y</I> </DT> <DD></DD> <DT><I>pathName <B>text icursor<I> index</I></B></I> </DT> <DD></DD> <DT><I>pathName <B>text index<I> index</I></B></I> </DT> <DD>Returns the text index of given <I>index</I>. </DD> <DT><I>pathName <B>text insert<I> index string</I></B></I> </DT> <DD>Insert the text string <I>string</I> into the edit buffer at the index <I>index</I>. For example, the index 0 will prepend the buffer. </DD> <DT><I>pathName <B>text selection<I> args</I></B></I> </DT> <DD>This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: <blockquote></DD> <DT><I>pathName <B>text selection adjust<I> index</I></B></I> </DT> <DD>Adjusts either the first or last index of the selection. </DD> <DT><I>pathName <B>text selection clear</B></I> </DT> <DD>Clears the selection. </DD> <DT><I>pathName <B>text selection from<I> index</I></B></I> </DT> <DD>Sets the anchor of the selection. </DD> <DT><I>pathName <B>text selection present</B></I> </DT> <DD>Indicates if a selection is present. </DD> <DT><I>pathName <B>text selection range<I> start end</I></B></I> </DT> <DD>Sets both the anchor and mark of the selection. </DD> <DT><I>pathName <B>text selection to<I> index</I></B></I> </DT> <DD>Sets the unanchored end (mark) of the selection. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>toggle <I>tagOrId</I></B></I> </DT> <DD>Opens or closes the node given by <I>tagOrId</I>. If the corresponding <B>-opencommand</B> or <B>-closecommand</B> option is set, then that command is also invoked. </DD> <DT><I>pathName <B>xview <I>args</I></B></I> </DT> <DD>This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>xview</B></I> </DT> <DD>Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the <B>treeview</B> widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the <B>-xscrollcommand</B> option. </DD> <DT><I>pathName <B>xview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the character position given by <I>tagOrId</I> is displayed at the left edge of the window. Character positions are defined by the width of the character <B>0</B>. </DD> <DT><I>pathName <B>xview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that <I>fraction</I> of the total width of the <B>treeview</B> widget's text is off-screen to the left. <I>fraction</I> must be a fraction between 0 and 1. </DD> <DT><I>pathName <B>xview scroll <I>number what</I></B></I> </DT> <DD>This command shifts the view in the window left or right according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B> or an abbreviation of one of these. If <I>what</I> is <B>units</B>, the view adjusts left or right by <I>number</I> character units (the width of the <B>0</B> character) on the display; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>yview <I>?args</I></B></I>? </DT> <DD>This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>yview</B></I> </DT> <DD>Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the <B>-yscrollcommand</B> option. </DD> <DT><I>pathName <B>yview</B></I> <I>tagOrId</I> </DT> <DD>Adjusts the view in the window so that the node given by <I>tagOrId</I> is displayed at the top of the window. </DD> <DT><I>pathName <B>yview moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that the node given by <I>fraction</I> appears at the top of the window. <I>Fraction</I> is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the <B>treeview</B> widget, and so on. </DD> <DT><I>pathName <B>yview scroll <I>number what</I></B></I> </DT> <DD>This command adjusts the view in the window up or down according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B>. If <I>what</I> is <B>units</B>, the view adjusts up or down by <I>number</I> lines; if it is <B>pages</B> then the view adjusts by <I>number</I> screenfuls. If <I>number</I> is negative then earlier nodes become visible; if it is positive then later nodes become visible. </DD> </DL> </blockquote> <H2><A NAME="sect11" HREF="#toc11">Treeview Options</A></H2> In addition to the <B>configure</B> operation, widget configuration options may also be set by the Tk <B>option</B> command. The class resource name is <I>TreeView</I>. <BR> <CODE>option add *TreeView.Foreground white<BR> option add *TreeView.Background blue<BR> </CODE><P>The following widget options are available: <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the <B>activate</B> operation. </DD> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed for an entry's icon when it is active. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-autocreate <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-allowduplicates <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is <I>no</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the widget. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's <B>-closecommand</B> option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-dashes <I>number</I></B> </DT> <DD>Sets the dash style of the horizontal and vertical lines drawn connecting entries. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, solid lines will be drawn. The default is <I>1</I> (dotted). </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>; the value of the selection will be the label of the selected nodes, separated by newlines. The default is <I>no</I>. </DD> <DT><B>-flat <I>boolean</I></B> </DT> <DD>Indicates whether to display the tree as a flattened list. If <I>boolean</I> is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the <FONT SIZE=-1><B>SORT OPERATIONS</B></FONT> section for more information. The default is <I>no</I>. </DD> <DT><B>-focusdashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. <I>Number</I> is the length in pixels of the dashes and gaps in the line. If <I>number</I> is <I>0</I>, a solid line will be drawn. The default is <I>1</I>. </DD> <DT><B>-focusforeground <I>color</I></B> </DT> <DD>Sets the color of the focus rectangle. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font for entry labels. You can override this for individual entries with the entry's <B>-font</B> configuration option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of entry labels. You can override this for individual entries with the entry's <B>-foreground</B> configuration option. The default is <I>black</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>400</I>. </DD> <DT><B>-hideroot <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, it indicates that no entry for the root node should be displayed. The default is <I>no</I>. </DD> <DT><B>-highlightbackground <I>color</I></B> </DT> <DD>Specifies the normal color of the traversal highlight region when the widget does not have the input focus. </DD> <DT><B>-highlightcolor <I>color</I></B> </DT> <DD>Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is <I>black</I>. </DD> <DT><B>-highlightthickness <I>pixels</I></B> </DT> <DD>Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to <B>Tk_GetPixels</B>. If the value is zero, no focus highlight will be displayed. The default is <I>2</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images for the entry's icon. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-linecolor <I>color</I></B> </DT> <DD>Sets the color of the connecting lines drawn between entries. The default is <I>black</I>. </DD> <DT><B>-linespacing <I>pixels</I></B> </DT> <DD>Sets the number of pixels spacing between entries. The default is <I>0</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the lines drawn connecting entries. If <I>pixels</I> is <I>0</I>, no vertical or horizontal lines are drawn. The default is <I>1</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's <B>-opencommand</B> configuration option. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the widget. <I>Relief</I> specifies how the <B>treeview</B> widget should appear relative to widget it is packed into; for example, <I>raised</I> means the <B>treeview</B> widget should appear to protrude. The default is <I>sunken</I>. </DD> <DT><B>-scrollmode <I>mode</I></B> </DT> <DD>Specifies the style of scrolling to be used. The following styles are valid. This is the default is <I>hierbox</I>. <blockquote></DD> <DT><I>listbox</I> </DT> <DD>Like the <B>listbox</B> widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. </DD> <DT><I>hierbox</I> </DT> <DD>Like the <B>hierbox</B> widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. </DD> <DT><I>canvas</I> </DT> <DD>Like the <B>canvas</B> widget, the entries are bound within the scrolling area. </DD> </DL> </blockquote> <DL> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background color selected node entries. The default is <I>#ffffea</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is <I>0</I>. <B>-selectcommand <I>string</I></B> Specifies a Tcl script to invoked when the set of selected nodes changes. The default is <I>""</I>. </DD> <DT><B>-selectforeground <I>color<B> </B></I></B></DT> <DD>Sets the color of the labels of selected node entries. The default is <I>black</I>. </DD> <DT><B>-selectmode <I>mode</I></B> </DT> <DD>Specifies the selection mode. If <I>mode</I> is <I>single</I>, only one node can be selected at a time. If <I>multiple</I> more than one node can be selected. The default is <I>single</I>. </DD> <DT><B>-separator <I>string</I></B> </DT> <DD>Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If <I>string</I> is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is <I>""</I>. </DD> <DT><B>-showtitles <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is false, column titles are not be displayed. The default is <I>yes</I>. </DD> <DT><B>-sortselection <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is <I>no</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>"1"</I>. </DD> <DT><B>-trim <I>string</I></B> </DT> <DD>Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the <B>-separator</B> is also set. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the widget. If <I>pixels</I> is 0, then the with is computed from the contents of the <B>treeview</B> widget. The default is <I>200</I>. </DD> <DT><B>-xscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-xscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the horizontal scrolling distance. The default is 20 pixels. </DD> <DT><B>-yscrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-yscrollincrement</B> <I>pixels</I> </DT> <DD>Sets the vertical scrolling distance. The default is 20 pixels. </DD> </DL> <H2><A NAME="sect12" HREF="#toc12">Entry Options</A></H2> Many widget configuration options have counterparts in entries. For example, there is a <B>-closecommand</B> configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. <P> There is no resource class or name for entries. <DL> <DT><B>-activeicons <I>images</I></B> </DT> <DD>Specifies images to be displayed as the entry's icon when it is active. This overrides the global <B>-activeicons</B> configuration option for the specific entry. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for nodes. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is <I>all</I>. </DD> <DT><B>-button <I>string</I></B> </DT> <DD>Indicates whether a button should be displayed on the left side of the node entry. <I>String</I> can be <I>yes</I>, <I>no</I>, or <I>auto</I>. If <I>auto</I>, then a button is automatically displayed if the node has children. This is the default. </DD> <DT><B>-closecommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the node is closed. This overrides the global <B>-closecommand</B> option for this entry. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <DL> <DT><B>-data <I>string</I></B> </DT> <DD>Sets data fields for the node. <I>String</I> is a list of name-value pairs to be set. The default is <I>""</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for entry labels. This overrides the widget's <B>-font</B> option for this node. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the text color of the entry label. This overrides the widget's <B>-foreground</B> configuration option. The default is <I>""</I>. </DD> <DT><B>-icons <I>images</I></B> </DT> <DD>Specifies images to be displayed for the entry's icon. This overrides the global <B>-icons</B> configuration option. <I>Images</I> is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. </DD> <DT><B>-label <I>string</I></B> </DT> <DD>Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is <I>""</I>. </DD> <DT><B>-opencommand <I>string</I></B> </DT> <DD>Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's <B>-opencommand</B> option for this node. The default is <I>""</I>. Percent substitutions are performed on <I>string</I> before it is executed. The following substitutions are valid: <blockquote></DD> <DT><I>%W</I> </DT> <DD>The pathname of the widget. </DD> <DT><I>%p</I> </DT> <DD>The name of the node. </DD> <DT><I>%P</I> </DT> <DD>The full pathname of the node. </DD> <DT><I>%#</I> </DT> <DD>The id of the node. </DD> <DT><I>%%</I> </DT> <DD>Translates to a single percent. </DD> </DL> </blockquote> <H2><A NAME="sect13" HREF="#toc13">Button Options</A></H2> Button configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Button</I>. The resource name is always <I>button</I>. <BR> <CODE>option add *TreeView.Button.Foreground white<BR> option add *TreeView.button.Background blue<BR> </CODE><P>The following are the configuration options available for buttons. <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the <B>button activate</B> operation. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the button. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the button. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-closerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the closed button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Sets the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of buttons. The default is <I>black</I>. </DD> <DT><B>-images <I>images</I></B> </DT> <DD>Specifies images to be displayed for the button. <I>Images</I> is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the <I>images</I> is the empty string, then a plus/minus gadget is drawn. The default is <I>""</I>. </DD> <DT><B>-openrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the open button. <I>Relief</I> indicates how the button should appear relative to the widget; for example, <I>raised</I> means the button should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-size <I>pixels</I></B> </DT> <DD>Sets the requested size of the button. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect14" HREF="#toc14">Column Options</A></H2> Column configuration options may also be set by the <B>option</B> command. The resource subclass is <I>Column</I>. The resource name is the name of the column. <BR> <CODE>option add *TreeView.Column.Foreground white<BR> option add *TreeView.treeView.Background blue<BR> </CODE><P>The following configuration options are available for columns. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the column. This overrides the widget's <B>-background</B> option. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border of the column. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>0</I>. </DD> <DT><B>-edit <I>boolean</I></B> </DT> <DD>Indicates if the column's data fields can be edited. If <I>boolean</I> is false, the data fields in the column may not be edited. The default is <I>yes</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Specifies the foreground color of the column. You can override this for individual entries with the entry's <B>-foreground</B> option. The default is <I>black</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for a column. You can override this for individual entries with the entry's <B>-font</B> option. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the column is not displayed. The default is <I>yes</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>left</I>. </DD> <DT><B>-pad <I>pad</I></B> </DT> <DD>Specifies how much padding for the left and right sides of the column. <I>Pad</I> is a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the column is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the column. <I>Relief</I> specifies how the column should appear relative to the widget; for example, <I>raised</I> means the column should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-state <I>state</I></B> </DT> <DD>Sets the state of the column. If <I>state</I> is <I>disable</I> then the column title can not be activated nor invoked. The default is <I>normal</I>. </DD> <DT><B>-text <I>string</I></B> </DT> <DD>Sets the title for the column. The default is <I>""</I>. </DD> <DT><B>-titleforeground <I>color</I></B> </DT> <DD>Sets the foreground color of the column title. The default is <I>black</I>. </DD> <DT><B>-titleshadow <I>color</I></B> </DT> <DD>Sets the color of the drop shadow of the column title. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the requested width of the column. This overrides the computed with of the column. If <I>pixels</I> is 0, the width is computed as from the contents of the column. The default is <I>0</I>. </DD> </DL> </blockquote> <H2><A NAME="sect15" HREF="#toc15">Text Editing Options</A></H2> Text edit window configuration options may also be set by the <B>option</B> command. The resource class is <I>TreeViewEditor</I>. The resource name is always <I>edit</I>. <BR> <CODE>option add *TreeViewEditor.Foreground white<BR> option add *edit.Background blue<BR> </CODE><P>The following are the configuration options available for the text editing window. <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background of the text edit window. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the edit window. The <B>-relief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-exportselection <I>boolean</I></B> </DT> <DD>Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type <B>STRING</B>. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the edit window. <I>Relief</I> indicates how the background should appear relative to the edit window; for example, <I>raised</I> means the background should appear to protrude. The default is <I>solid</I>. </DD> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the background of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the selected text in the edit window. The <B>-selectrelief</B> option determines if a border is to be drawn. The default is <I>1</I>. </DD> <DT><B>-selectforeground <I>color</I></B> </DT> <DD>Sets the foreground of the selected text in the edit window. The default is <I>white</I>. </DD> <DT><B>-selectrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect of the selected text in the edit window. <I>Relief</I> indicates how the text should appear relative to the edit window; for example, <I>raised</I> means the text should appear to protrude. The default is <I>flat</I>. </DD> </DL> </blockquote> <H2><A NAME="sect16" HREF="#toc16">Default Bindings</A></H2> Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a <B>treeview</B> widget is determined by its <B>-selectmode</B> option, which selects one of two ways of dealing with the selection. <P> If the selection mode is <B>single</B>, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. <P> If the selection mode is <B>multiple</B>, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. <OL> <LI>In <B>extended</B> mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. </LI><LI>In <B>extended</B> mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. </LI><LI>If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. </LI><LI>Mouse button 2 may be used for scanning. If it is pressed and dragged over the <B>treeview</B> widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. </LI><LI>If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is <B>browse</B> or <B>extended</B> then the new active entry is also selected and all other entries are deselected. In <B>extended</B> mode the new active entry becomes the selection anchor. </LI><LI>In <B>extended</B> mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. </LI><LI>The Left and Right keys scroll the <B>treeview</B> widget view left and right by the width of the character <B>0</B>. Control-Left and Control-Right scroll the <B>treeview</B> widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. </LI><LI>The Prior and Next keys scroll the <B>treeview</B> widget view up and down by one page (the height of the window). </LI><LI>The Home and End keys scroll the <B>treeview</B> widget horizontally to the left and right edges, respectively. </LI><LI>Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. </LI><LI>Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. </LI><LI>In <B>extended</B> mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. </LI><LI>In <B>multiple</B> mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. </LI><LI>The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. </LI><LI>In <B>extended</B> mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. </LI><LI>In <B>extended</B> mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. </LI><LI>Control-slash selects everything in the widget, except in <B>single</B> and <B>browse</B> modes, in which case it selects the active entry and deselects everything else. </LI><LI>Control-backslash deselects everything in the widget, except in <B>browse</B> mode where it has no effect. </LI><LI>The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. </LI> </OL> <P> The behavior of <B>treeview</B> widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. <H3><A NAME="sect17" HREF="#toc17">Widget Bindings</A></H3> In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. <DL> <DT><I>&lt;ButtonPress-2&gt;</I></DT> <DD>Starts scanning. </DD> <DT><I>&lt;B2-Motion&gt;</I></DT> <DD>Adjusts the scan. </DD> <DT><I>&lt;ButtonRelease-2&gt;</I></DT> <DD>Stops scanning. </DD> <DT><I>&lt;B1-Leave&gt;</I></DT> <DD>Starts auto-scrolling. </DD> <DT><I>&lt;B1-Enter&gt;</I></DT> <DD>Starts auto-scrolling </DD> <DT><I>&lt;KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous entry. </DD> <DT><I>&lt;KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next entry. </DD> <DT><I>&lt;Shift-KeyPress-Up&gt;</I></DT> <DD>Moves the focus to the previous sibling. </DD> <DT><I>&lt;Shift-KeyPress-Down&gt;</I></DT> <DD>Moves the focus to the next sibling. </DD> <DT><I>&lt;KeyPress-Prior&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Next&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-Left&gt;</I></DT> <DD>Closes the entry. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-Right&gt;</I></DT> <DD>Opens the entry, displaying its children. It is not an error if the entry has no children. </DD> <DT><I>&lt;KeyPress-space&gt;</I></DT> <DD>In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). </DD> <DT><I>&lt;KeyRelease-space&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress-Return&gt;</I></DT> <DD>Sets the focus to the current entry. </DD> <DT><I>&lt;KeyRelease-Return&gt;</I></DT> <DD>Turns off select mode. </DD> <DT><I>&lt;KeyPress&gt;</I></DT> <DD>Moves to the next entry whose label starts with the letter typed. </DD> <DT><I>&lt;KeyPress-Home&gt;</I></DT> <DD>Moves the focus to first entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-End&gt;</I></DT> <DD>Move the focus to the last entry. Closed or hidden entries are ignored. </DD> <DT><I>&lt;KeyPress-F1&gt;</I></DT> <DD>Opens all entries. </DD> <DT><I>&lt;KeyPress-F2&gt;</I></DT> <DD>Closes all entries (except root). </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Button Bindings</A></H3> Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the button of the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the button back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the view so that the current entry is visible. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Entry Bindings</A></H3> Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the <B>bind</B> operation to modify them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current entry. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the entry back to its normal state. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the selection anchor the current entry. </DD> <DT><I>&lt;Double-ButtonPress-1&gt;</I></DT> <DD>Toggles the selection of the current entry. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>For "multiple" mode only. Sets the selection anchor to the current entry. </DD> <DT><I>&lt;Shift-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Extends the selection. </DD> <DT><I>&lt;Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Shift-ButtonRelease-1&gt;</I></DT> <DD>Stop auto-scrolling. </DD> <DT><I>&lt;Control-ButtonPress-1&gt;</I></DT> <DD>For "multiple" mode only. Toggles and extends the selection. </DD> <DT><I>&lt;Control-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-ButtonRelease-1&gt;</I></DT> <DD>Stops auto-scrolling. </DD> <DT><I>&lt;Control-Shift-ButtonPress-1&gt;</I></DT> <DD>??? </DD> <DT><I>&lt;Control-Shift-Double-ButtonPress-1&gt;</I></DT> <DD>Place holder. Does nothing. </DD> <DT><I>&lt;Control-Shift-B1-Motion&gt;</I></DT> <DD>Place holder. Does nothing. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Column Bindings</A></H3> Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the <B>column bind</B> operation to change them. <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current column title. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Invokes the command (see the column's -command option) if one if specified. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Column Rule Bindings</A></H3> <DL> <DT><I>&lt;Enter&gt;</I></DT> <DD>Highlights the current and activates the ruler. </DD> <DT><I>&lt;Leave&gt;</I></DT> <DD>Returns the column back to its normal state. Deactivates the ruler. </DD> <DT><I>&lt;ButtonPress-1&gt;</I></DT> <DD>Sets the resize anchor for the column. </DD> <DT><I>&lt;B1-Motion&gt;</I></DT> <DD>Sets the resize mark for the column. </DD> <DT><I>&lt;ButtonRelease-1&gt;</I></DT> <DD>Adjust the size of the column, based upon the resize anchor and mark positions. </DD> </DL> <H2><A NAME="sect22" HREF="#toc22">Example</A></H2> The <B>treeview</B> command creates a new widget. <BR> <CODE>treeview .h -bg white<BR> </CODE><P>A new Tcl command <I>.h</I> is also created. This command can be used to query and modify the <B>treeview</B> widget. For example, to change the background color of the table to "green", you use the new command and the widget's <B>configure</B> operation. <BR> <CODE># Change the background color.<BR> .h configure -background "green"<BR> </CODE><P>By default, the <B>treeview</B> widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the <B>-tree</B> option to specify the name of another tree. <BR> <CODE># View the tree "myTree".<BR> .h configure -tree "myTree"<BR> </CODE><P>When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always <I>0</I> (you can use also use the special id <I>root</I>). The <B>insert</B> operation lets you insert one or more new entries into the tree. The last argument is the node's <I>pathname</I>. <BR> <CODE># Create a new entry named "myEntry"<BR> set id [.h insert end "myEntry"]<BR> </CODE><P>This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. <BR> <CODE># Prepend "fred".<BR> set id [.h insert 0 "fred"]<BR> </CODE><P>Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the <B>-label</B> option. <BR> <CODE># Create a new node named "fred"<BR> set id [.h insert end "fred" -label "Fred Flintstone"]<BR> </CODE><P>The <B>insert</B> operation returns the id of the new node. You can also use the <B>index</B> operation to get this information. <BR> <CODE># Get the id of "fred"<BR> .h index "fred"<BR> </CODE><P>To insert a node somewhere other than root, use the <B>-at</B> switch. It takes the id of the node where the new child will be added. <BR> <CODE># Create a new node "barney" in "fred".<BR> .h insert -at $id end "barney" <BR> </CODE><P>A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. <BR> <CODE># Create a new sub-entry of "fred"<BR> .h insert end "fred barney" <BR> </CODE><P>Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the <B>-autocreate</B> configuration option to force the creation of ancestor nodes. <BR> <CODE># Force the creation of ancestors.<BR> .h configure -autocreate yes <BR> .h insert end "fred barney wilma betty" <BR> </CODE><P>Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the <B>-separator</B> option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. <BR> <CODE>.h configure -separator /<BR> .h insert end "/usr/local/tcl/bin" <BR> </CODE><P>If the path is prefixed by extraneous characters, you can automatically trim it off using the <B>-trim</B> option. It removed the string from the path before it is parsed. <BR> <CODE>.h configure -trim C:/windows -separator /<BR> .h insert end "C:/window/system" <BR> </CODE><P>You can insert more than one entry at a time with the <B>insert</B> operation. This can be much faster than looping over a list of names. <BR> <CODE># The slow way<BR> foreach f [glob $dir/*] {<BR> .h insert end $f<BR> }<BR> # The fast way<BR> eval .h insert end [glob $dir/*]<BR> </CODE><P>In this case, the <B>insert</B> operation will return a list of ids of the new entries. <P> You can delete entries with the <B>delete</B> operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. <BR> <CODE>.h delete $id<BR> </CODE><P>Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the <B>-label</B> option that sets the entry's text label. The <B>entry configure</B> operation lets you set or modify an entry's configuration options. <BR> <CODE>.h entry configure $id -color red -font fixed<BR> </CODE><P>You can hide an entry and its children using the <B>-hide</B> option. <BR> <CODE>.h entry configure $id -hide yes<BR> </CODE><P>More that one entry can be configured at once. All entries specified are configured with the same options. <BR> <CODE>.h entry configure $i1 $i2 $i3 $i4 -color brown <BR> </CODE><P>An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's <B>-icons</B> option. It takes a list of two image names: one to represent the open entry, another when it is closed. <BR> <CODE>set im1 [image create photo -file openfolder.gif]<BR> set im2 [image create photo -file closefolder.gif]<BR> .h entry configure $id -icons "$im1 $im2"<BR> </CODE><P>If <B>-icons</B> is set to the empty string, no icons are display. <P> If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a <I>+</I> or <I>-</I> symbol, but can be configured in a variety of ways using the <B>button configure</B> operation. For example, the <I>+</I> and <I>-</I> symbols can be replaced with Tk images. <BR> <CODE>set im1 [image create photo -file closefolder.gif]<BR> set im2 [image create photo -file downarrow.gif]<BR> .h button configure $id -images "$im1 $im2" \<BR> -openrelief raised -closerelief raised<BR> </CODE><P>Entries can contain an arbitrary number of <I>data fields</I>. Data fields are name-value pairs. Both the value and name are strings. The entry's <B>-data</B> option lets you set data fields. <BR> <CODE>.h entry configure $id -data {mode 0666 group users}<BR> </CODE><P>The <B>-data</B> takes a list of name-value pairs. <P> You can display these data fields as <I>columns</I> in the <B>treeview</B> widget. You can create and configure columns with the <B>column</B> operation. For example, to add a new column to the widget, use the <B>column insert</B> operation. The last argument is the name of the data field that you want to display. <BR> <CODE>.h column insert end "mode"<BR> </CODE><P>The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's <B>-text</B> option. <BR> <CODE>.h column insert end "mode" -text "File Permissions"<BR> </CODE><P>Columns have several configuration options. The <B>column configure</B> operation lets you query or modify column options. <BR> <CODE>.h column configure "mode" -justify left<BR> </CODE><P>The <B>-justify</B> option says how the data is justified within in the column. The <B>-hide</B> option indicates whether the column is displayed. <BR> <CODE>.h column configure "mode" -hide yes<BR> </CODE><P>Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the <B>-selectforeground</B> and <B>-selectbackground</B> configuration options. The selection itself is managed by the <B>selection</B> operation. <BR> <CODE># Clear all selections<BR> .h selection clear 0 end<BR> # Select the root node<BR> .h selection set 0 <BR> </CODE><P>The <B>curselection</B> operation returns a list of ids of all the selected entries. <BR> <CODE>set ids [.h curselection]<BR> </CODE><P>You can use the <B>get</B> operation to convert the ids to their pathnames. <BR> <CODE>set names [eval .h get -full $ids]<BR> </CODE><P>If a treeview is exporting its selection (using the <B>-exportselection</B> option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type <B>STRING</B>; the value of the selection will be the pathnames of the selected entries, separated by newlines. <P> The <B>treeview</B> supports two modes of selection: <I>single</I> and <I>multiple</I>. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -selectmode "multiple"<BR> </CODE><P>You can be notified when the list of selected entries changes. The widget's <B>-selectcommand</B> specifies a Tcl procedure that is called whenever the selection changes. <BR> <CODE>proc SelectNotify { widget } {<BR> set ids [$widget curselection]<BR> }<BR> .h configure -selectcommand "SelectNotify .h"<BR> </CODE><P>The widget supports the standard Tk scrolling and scanning operations. The <B>treeview</B> can be both horizontally and vertically. You can attach scrollbars to the <B>treeview</B> the same way as the listbox or canvas widgets. <BR> <CODE>scrollbar .xbar -orient horizontal -command ".h xview"<BR> scrollbar .ybar -orient vertical -command ".h yview"<BR> .h configure -xscrollcommand ".xbar set" \<BR> -yscrollcommand ".ybar set"<BR> </CODE><P>There are three different modes of scrolling: <I>listbox</I>, <I>canvas</I>, and <I>hierbox</I>. In <I>listbox</I> mode, the last entry can always be scrolled to the top of the widget. In <I>hierbox</I> mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's <B>-selectmode</B> option. <BR> <CODE>.h configure -scrollmode "listbox"<BR> </CODE><P>Entries can be programmatically opened or closed using the <B>open</B> and <B>close</B> operations respectively. <BR> <CODE>.h open $id<BR> .h close $id<BR> </CODE><P>When an entry is opened, a Tcl procedure can be automatically invoked. The <B>-opencommand</B> option specifies this procedure. This procedure can lazily insert entries as needed. <BR> <CODE>proc AddEntries { dir } {<BR> eval .h insert end [glob -nocomplain $dir/*] <BR> }<BR> .h configure -opencommand "AddEntries %P"<BR> </CODE><P>Now when an entry is opened, the procedure <I>AddEntries</I> is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like <B>bind</B>) are performed. Above, <I>%P</I> is translated to the pathname of the entry. <P> The same feature exists when an entry is closed. The <B>-closecommand</B> option specifies the procedure. <BR> <CODE>proc DeleteEntries { id } {<BR> .h entry delete $id 0 end<BR> }<BR> .h configure -closecommand "DeleteEntries %#"<BR> </CODE><P>When an entry is closed, the procedure <I>DeleteEntries</I> is called and deletes the entry's children using the <B>entry delete</B> operation (<I>%#</I> is the id of entry). <H2><A NAME="sect23" HREF="#toc23">Keywords</A></H2> treeview, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Tree Data Object</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">IDs and Tags</A></LI> <LI><A NAME="toc7" HREF="#sect7">Special Node IDs</A></LI> <LI><A NAME="toc8" HREF="#sect8">Data Fields</A></LI> <LI><A NAME="toc9" HREF="#sect9">Entry Bindings</A></LI> <LI><A NAME="toc10" HREF="#sect10">Treeview Operations</A></LI> <LI><A NAME="toc11" HREF="#sect11">Treeview Options</A></LI> <LI><A NAME="toc12" HREF="#sect12">Entry Options</A></LI> <LI><A NAME="toc13" HREF="#sect13">Button Options</A></LI> <LI><A NAME="toc14" HREF="#sect14">Column Options</A></LI> <LI><A NAME="toc15" HREF="#sect15">Text Editing Options</A></LI> <LI><A NAME="toc16" HREF="#sect16">Default Bindings</A></LI> <UL> <LI><A NAME="toc17" HREF="#sect17">Widget Bindings</A></LI> <LI><A NAME="toc18" HREF="#sect18">Button Bindings</A></LI> <LI><A NAME="toc19" HREF="#sect19">Entry Bindings</A></LI> <LI><A NAME="toc20" HREF="#sect20">Column Bindings</A></LI> <LI><A NAME="toc21" HREF="#sect21">Column Rule Bindings</A></LI> </UL> <LI><A NAME="toc22" HREF="#sect22">Example</A></LI> <LI><A NAME="toc23" HREF="#sect23">Keywords</A></LI> </UL> </BODY></HTML> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/table.html�������������������������������������������������������������������0000644�0001750�0001750�00000077655�11462120062�015203� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>table(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> table - Arranges widgets in a table <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>table <I>container</I></B> ?<I>widget index option value</I>?... <P> <B>table arrange</B> <I>container</I> <P> <B>table cget <I>container</I></B> ?<I>item</I>? <I>option</I> <P> <B>table configure <I>container</I></B> ?<I>item</I>?... ?<I>option value</I>?... <P> <B>table extents <I>container</I></B> <I>item</I> <P> <B>table forget <I>widget</I></B> ?<I>widget</I>?... <P> <B>table info <I>container</I></B> <I>item</I> <P> <B>table locate <I>container</I></B> <I>x y</I> <P> <B>table containers </B>?<I>switch</I>? ?<I>arg</I>? <P> <B>table save <I>container</I></B> <P> <B>table search <I>container</I></B> ?<I>switch arg</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>table</B> command arranges widgets in a table. The alignment of widgets is detemined by their row and column positions and the number of rows or columns that they span. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Probably the most painstaking aspect of building a graphical application is getting the placement and size of the widgets just right. It usually takes many iterations to align widgets and adjust their spacing. That's because managing the geometry of widgets is simply not a packing problem, but also graphical design problem. Attributes such as alignment, symmetry, and balance are more important than minimizing the amount of space used for packing. <P> The <B>table</B> geometry manager arranges widgets in a table. It's easy to align widgets (horizontally and vertically) or to create empty space to balance the arrangement of the widgets. Widgets (called <I>slaves</I> in the Tk parlance) are arranged inside a containing widget (called the <I>master</I>). Widgets are positioned at row,column locations and may span any number of rows or columns. More than one widget can occupy a single location. <P> The placement of widget windows determines both the size and arrangement of the table. The table queries the requested size of each widget. The <I>requested size</I> of a widget is the natural size of the widget (before the widget is shrunk or expanded). The height of each row and the width of each column is the largest widget spanning that row or column. The size of the table is in turn the sum of the row and column sizes. This is the table's <I>normal size</I>. <P> The total number of rows and columns in a table is determined from the indices specified. The table grows dynamically as windows are added at larger indices. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> The table geometry manager is created by invoking the <B>table</B> command. <BR> <CODE># Create a table in the root window<BR> table .<BR> </CODE><P>The window <I>.</I> is now the <I>container</I> of the table. Widgets are packed into the table and displayed within the confines of the container. <P> You add widgets to the table by row and column location. Row and column indices start from zero. <BR> <CODE>label .title -text "This is a title"<BR> <P> # Add a label to the table<BR> table . .title 0,0 <BR> </CODE><P>The label <I>.title</I> is added to the table. We can add more widgets in the same way. <BR> <CODE>button .ok -text "Ok"<BR> button .cancel -text "Cancel"<BR> <P> # Add two buttons<BR> table . .ok 1,0<BR> table . .cancel 1,1<BR> </CODE><P>Two buttons <I>.ok</I> and <I>.cancel</I> are now packed into the second row of the table. They each occupy one cell of the table. By default, widgets span only a single row and column. <P> The first column contains two widgets, <I>.title</I> and <I>.ok</I>. By default, the widest of the two widgets will define the width of the column. However, we want <I>.title</I> to be centered horizontally along the top of the table. We can make <I>.title</I> span two columns using the <B>configure</B> operation. <BR> <CODE># Make the label span both columns<BR> table configure . .title -cspan 2<BR> </CODE><P>The label <I>.title</I> will now be centered along the top row of the table. <P> In the above example, we've create and arranged the layout for the table invoking the <B>table</B> command several times. Alternately, we could have used a single <B>table</B> command. <BR> <CODE>label .title -text "This is a title"<BR> button .ok -text "Ok"<BR> button .cancel -text "Cancel"<BR> <P> # Create and pack the table<BR> table . \<BR> .title 0,0 -cspan 2 \<BR> .ok 1,0 \<BR> .cancel 1,1<BR> </CODE><P>The table will override the requested width and height of the container so that the window fits the table exactly. This also means that any change to the size of table will be propagated up through the Tk window hierarchy. This feature can be turned off using the <B>configure</B> operation again. <BR> <CODE>table configure . -propagate no<BR> </CODE><P>You can also set the width of height of the table to a specific value. This supersedes the calculated table size. <BR> <CODE># Make the container 4 inches wide, 3 inches high<BR> table configure . -reqwidth 4i -reqheight 3i<BR> </CODE><P>If a widget is smaller than the cell(s) it occupies, the widget will float within the extra space. By default, the widget will be centered within the space, but you can anchor the widget to any side of cell using the <B>-anchor</B> configuration option. <BR> <CODE>table configure . .ok -anchor w<BR> </CODE><P>The <B>-fill</B> option expands the widget to fill the extra space either vertically or horizontally (or both). <BR> <CODE># Make the title label fill the entire top row<BR> table configure . .title -cspan 2 -fill x <BR> <P> # Each button will be as height of the 2nd row.<BR> table configure . .ok .cancel -fill y<BR> </CODE><P>The width of <I>.title</I> will be the combined widths of both columns. Both <I>.ok</I> and <I>.cancel</I> will become as tall as the second row. <P> The <B>-padx</B> and <B>-pady</B> options control the amount of padding around the widget. Both options take a list of one or two values. <BR> <CODE># Pad the title by two pixels above and below.<BR> table configure . .title -pady 2<BR> <P> # Pad each button 2 pixels on the left, and 4 on the right.<BR> table configure . .ok .cancel -padx { 2 4 }<BR> </CODE><P>If the list has only one value, then both exterior sides (top and bottom or left and right) of the widget are padded by that amount. If the list has two elements, the first specifies padding for the top or left side and the second for the bottom or right side. <P> Like the container, you can also override the requested widths and heights of widgets using the <B>-reqwidth</B> and <B>-reqheight</B> options. This is especially useful with character-based widgets (such as buttons, labels, text, listbox, etc) that let you specify their size only in units of characters and lines, instead of pixels. <BR> <CODE># Make all buttons one inch wide<BR> table configure . .ok .cancel -reqwidth 1i<BR> <P> </CODE><P>Each row and column of the table can be configured, again using the <B>configure</B> operation. Rows are and columns are designated by <I>R<I>i</I></I> and <I>C<I>i</I></I> respectively, where <I>i</I> is the index of the row or column. <P> For example, you can set the size of a row or column. <BR> <CODE># Make the 1st column 2 inches wide<BR> table configure . c0 -width 2.0i<BR> <P> # Make the 2nd row 1/2 inch high.<BR> table configure . r1 -height 0.5i<BR> </CODE><P>The new size for the row or column overrides its calculated size. If no widgets span the row or column, its height or width is zero. So you can use the <B>-width</B> and <B>-height</B> options to create empty spaces in the table. <BR> <CODE># Create an empty row and column<BR> table configure . r2 c2 -width 1i<BR> </CODE><P>The <B>-pady</B> option lets you add padding to the top and bottom sides of rows. The <B>-padx</B> option adds padding to the left and right sides of columns. Both options take a list of one or two values. <BR> <CODE># Pad above the title by two pixels <BR> table configure . r0 -pady { 2 0 }<BR> <P> # Pad each column 4 pixels on the left, and 2 on the right.<BR> table configure . c* -padx { 2 4 }<BR> <P> </CODE><P>Notice that you can configure all the rows and columns using either <I>R*</I> or <I>C*</I>. <P> When the container is resized, the rows and columns of the table are also resized. Only the rows or columns that contain widgets (a widget spans the row or column) grow or shrink. The <B>-resize</B> option indicates whether the row or column can be shrunk or stretched. If the value is <I>shrink</I>, the row or column can only be resized smaller. If <I>expand</I>, it can only be resized larger. If <I>none</I>, the row or column is frozen at its requested size. <BR> <CODE># Let the 1st column get smaller, but not bigger<BR> table configure . c0 -resize shrink<BR> <P> # Let the 2nd column get bigger, not smaller<BR> table configure . c1 -resize expand<BR> <P> # Don't resize the first row <BR> table configure . r0 -resize none<BR> </CODE><P>The following example packs a canvas, two scrollbars, and a title. The rows and columns containing the scrollbars are frozen at their requested size, so that even if the frame is resized, the scrollbars will remain the same width. <BR> <CODE>table . \<BR> .title 0,0 -cspan 3 \<BR> .canvas 1,1 -fill both \<BR> .vscroll 1,2 -fill y \<BR> .hscroll 2,1 -fill x<BR> <P> # Don't let the scrollbars resize<BR> table configure . c2 r2 -resize none<BR> <P> # Create an empty space to balance the scrollbar<BR> table configure . c0 -width .vscroll<BR> </CODE><P>Note that the value of the <B>-width</B> option is the name of a widget window. This indicates that the width of the column should be the same as the requested width of <I>.vscroll</I>. <P> Finally, the <B>forget</B> operation removes widgets from the table. <BR> <CODE># Remove the windows from the table<BR> table forget .quit .frame<BR> </CODE><P>It's not necessary to specify the container. The <B>table</B> command determines the container from the widget name. <H2><A NAME="sect5" HREF="#toc5">Operations</A></H2> The following operations are available for the <B>table</B>: <DL> <DT><B>table <I>container</I></B> ?<I>widget index option value</I>?... </DT> <DD>Adds the widget <I>widget</I> to the table at <I>index</I>. <I>Index</I> is a row,column position in the table. It must be in the form <I>row</I>,<I>column</I> where <I>row</I> and <I>column</I> are the respective row and column numbers, starting from zero (0,0 is the upper leftmost position). <I>Row</I> and <I>column</I> may also be numeric expressions that are recursively evaluated. If a table doesn't exist for <I>container</I>, one is created. <I>Widget</I> is the path name of the window, that must already exist, to be arranged inside of <I>container</I>. <I>Option</I> and <I>value</I> are described in the <FONT SIZE=-1><B>WIDGET</B></FONT> section. </DD> <DT><B>table arrange</B> <I>container</I> </DT> <DD>Forces the table to compute its layout immediately. Normally, the table geometry manager will wait until the next idle point, before calculating the size of its rows and columns. This is useful for collecting the <I>normal</I> sizes of rows and columns, that are based upon the requested widget sizes. </DD> <DT><B>table cget</B> <I>container </I>?<I>item</I>?<I> option</I> </DT> <DD>Returns the current value of the configuration option specific to <I>item</I> given by <I>option</I>. <I>Item</I> is either a row or column index, or the path name of a widget. <I>Item</I> can be in any form describe in the <B>configure</B> operation below. If no <I>item</I> argument is provided, then the configuration option is for the table itself. <I>Option</I> may be any one of the options described in the appropiate section for <I>item</I>. </DD> <DT><B>table configure</B> <I>container item</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options specific to <I>item</I>. If no <I>option</I> is specified, this command returns a list describing all of the available options for <I>item</I> If the argument <I>item</I> is omitted, then the specified configuration options are for the table itself. Otherwise <I>item</I> must be either a row or column specification, or the path name of a widget. The following <I>item</I> types are available. <blockquote></DD> <DT><I>C<I>i</I></I> </DT> <DD>Specifies the column of <I>container</I> to be configured. <I>Item</I> must be in the form <I>C<I>n</I></I>, where <I>i</I> is the index of the column. See the <FONT SIZE=-1><B>COLUMN</B></FONT> section. </DD> <DT><I>R<I>i</I></I> </DT> <DD>Specifies the row of <I>container</I> to be configured. <I>Item</I> must be in the form <I>R<I>i</I></I>, where <I>i</I> is the index of the row. See the <FONT SIZE=-1><B>ROW</B></FONT> section. </DD> <DT><I>widget</I> </DT> <DD>Specifies a widget of <I>container</I> to be queried. <I>Widget</I> is the path name of a widget packed in <I>container</I>. See the <FONT SIZE=-1><B>WIDGET</B></FONT> section. </DD> <DT>No argument </DT> <DD>Specifies that the table itself is to be queried. See the <FONT SIZE=-1><B>TABLE</B></FONT> section for a description of the option-value pairs for the table. </DD> </DL> </blockquote> <blockquote><P> The <I>option<I> and <I>value</I></I></I> pairs are specific to <I>item</I>. If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given option(s) to have the given value(s); in this case the command returns the empty string. </blockquote> <DL> <DT><B>table extents <I>container</I></B> <I>index</I> </DT> <DD>Queries the location and dimensions of row and columns in the table. <I>Index</I> can be either a row or column index or a table index. Returns a list of the x,y coordinates (upperleft corner) and dimensions (width and height) of the cell, row, or column. </DD> <DT><B>table forget <I>widget</I></B> ?<I>widget</I>?... </DT> <DD>Requests that <I>widget</I> no longer have its geometry managed. <I>Widget</I> is the pathname of the window currently managed by some table. The window will be unmapped so that it no longer appears on the screen. If <I>widget</I> is not currently managed by any table, an error message is returned, otherwise the empty string. </DD> <DT><B>table info <I>container</I></B> <I>item</I> </DT> <DD>Returns a list of the current configuration options for <I>item</I>. The list returned is exactly in the form that might be specified to the <B>table</B> command. It can be used to save and reset table configurations. <I>Item</I> must be one of the following. <blockquote></DD> <DT><I>C<I>i</I></I> </DT> <DD>Specifies the column of <I>container</I> to be queried. <I>Item</I> must be in the form <I>C<I>n</I></I>, where <I>n</I> is the index of the column. </DD> <DT><I>R<I>i</I></I> </DT> <DD>Specifies the row of <I>container</I> to be queried. <I>Item</I> must be in the form <I>R<I>i</I></I>, where <I>i</I> is the index of the row. </DD> <DT><I>widget</I> </DT> <DD>Specifies a widget of <I>container</I> to be queried. <I>Widget</I> is the path name of a widget packed in <I>container</I>. </DD> <DT>No argument </DT> <DD>Specifies that the table itself is to be queried. </DD> </DL> </blockquote> <DL> <DT><B>table locate <I>container</I></B> <I>x y</I> </DT> <DD>Returns the table index (row,column) of the cell containing the given screen coordinates. The <I>x</I> and <I>y</I> arguments represent the x and y coordinates of the sample point to be tested. </DD> <DT><B>table containers </B>?<I>switch arg</I>? </DT> <DD>Returns a list of all container windows matching a given criteria (using <I>switch</I> and <I>arg</I>). If no <I>switch</I> and <I>arg</I> arguments are given, the names of all container windows (only those using the <B>table</B> command) are returned. The following are valid switches: <blockquote></DD> <DT><B>-pattern</B> <I>pattern</I> </DT> <DD>Returns a list of pathnames of all container windows matching <I>pattern</I>. </DD> <DT><B>-slave</B> <I>window</I> </DT> <DD>Returns the name of the container window of table managing <I>window</I>. <I>Window</I> must be the path name of widget. If <I>window</I> is not managed by any table, the empty string is returned. </DD> </DL> </blockquote> <DL> <DT><B>table search <I>container</I></B> ?<I>switch arg</I>?... </DT> <DD>Returns the names of all the widgets in <I>container</I> matching the criteria given by <I>switch</I> and <I>arg</I>. <I>Container</I> is name of the container window associated with the table to be searched. The name of the widget is returned if any one <I>switch</I>-<I>arg</I> criteria matches. If no <I>switch</I>-<I>arg</I> arguments are given, the names of all widgets managed by <I>container</I> are returned. The following are switches are available: <blockquote></DD> <DT><B>-pattern</B> <I>pattern</I> </DT> <DD>Returns the names of any names of the widgets matching <I>pattern</I>. </DD> <DT><B>-span</B> <I>index</I> </DT> <DD>Returns the names of widgets that span <I>index</I>. A widget does not need to start at <I>index</I> to be included. <I>Index</I> must be in the form <I>row</I>,<I>column</I>, where <I>row</I> and <I>column</I> are valid row and column numbers. </DD> <DT><B>-start</B> <I>index</I> </DT> <DD>Returns the names of widgets that start at <I>index</I>. <I>Index</I> must be in the form <I>row</I>,<I>column</I>, where <I>row</I> and <I>column</I> are valid row and column numbers. </DD> </DL> </blockquote> <H2><A NAME="sect6" HREF="#toc6">Table Options</A></H2> To configure the table itself, you omit the <I>item</I> argument when invoking the <B>configure</B> operation. <BR> <CODE><B>table configure</B> <I>container</I> ?<I>option value</I>?...<BR> </CODE><P>The following options are available for the table: <blockquote> <DL> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets how much padding to add to the left and right exteriors of the table. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the left side of the table is padded by the first value and the right side by the second value. If <I>pad</I> has just one value, both the left and right sides are padded evenly by the value. The default is <I>0</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets how much padding to add to the top and bottom exteriors of the table. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the area above the table is padded by the first value and the area below by the second value. If <I>pad</I> is just one number, both the top and bottom areas are padded by the value. The default is <I>0</I>. </DD> <DT><B>-propagate <I>boolean</I></B> </DT> <DD>Indicates if the table should override the requested width and height of the <I>container</I> window. If <I>boolean</I> is false, <I>container</I> will not be resized. <I>Container</I> will be its requested size. The default is <I>1</I>. </DD> </DL> </blockquote> <H2><A NAME="sect7" HREF="#toc7">Widget Options</A></H2> widgets are configured by specifying the name of the widget when invoking the <B>configure</B> operation. <BR> <P> <CODE><B>table configure</B> <I>container <I>widget</I></I> ?<I>option value</I>?...<BR> </CODE><P><I>Widget</I> must be the path name of a window already packed in the table associated with <I>container</I>. The following options are available for widgets: <blockquote> <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Anchors <I>widget</I> to a particular edge of the cell(s) it resides. This option has effect only if the space of the spans surrounding <I>widget</I> is larger than <I>widget</I>. <I>Anchor</I> specifies how <I>widget</I> will be positioned in the space. For example, if <I>anchor</I> is <I>center</I> then the window is centered in the rows and columns it spans; if <I>anchor</I> is <I>w</I> then the window will be aligned with the leftmost edge of the span. The default is <I>center</I>. </DD> <DT><B>-columnspan <I>number</I></B> </DT> <DD>Sets the number of columns <I>widget</I> will span. The default is <I>1</I>. </DD> <DT><B>-columncontrol <I>control</I></B> </DT> <DD>Specifies how the width of <I>widget</I> should control the width of the columns it spans. <I>Control</I> is either <I>normal</I>, <I>none</I>, or <I>full</I>. The default is <I>normal</I>. <blockquote></DD> <DT><I>none</I> </DT> <DD>The width of <I>widget</I> is not considered. </DD> <DT><I>full</I> </DT> <DD>Only the width of <I>widget</I> will be considered when computing the widths of the columns. </DD> <DT><I>normal</I> </DT> <DD>Indicates that the widest widget spanning the column will determine the width of the span. </DD> </DL> </blockquote> <DL> <DT><B>-fill <I>fill</I></B> </DT> <DD>Specifies if <I>widget</I> should be stretched to fill any free space in the span surrounding <I>widget</I>. <I>Fill</I> is either <I>none</I>, <I>x</I>, <I>y</I>, <I>both</I>. The default is <I>none</I>. <blockquote></DD> <DT><I>x</I> </DT> <DD>The widget can grow horizontally. </DD> <DT><I>y</I> </DT> <DD>The widget can grow vertically. </DD> <DT><I>both</I> </DT> <DD>The widget can grow both vertically and horizontally. </DD> <DT><I>none</I> </DT> <DD>The widget does not grow along with the span. </DD> </DL> </blockquote> <DL> <DT><B>-ipadx <I>pixels</I></B> </DT> <DD>Sets how much horizontal padding to add internally on the left and right sides of <I>widget</I>. <I>Pixels</I> must be a valid screen distance like <I>2</I> or <I>0.3i</I>. The default is <I>0</I>. </DD> <DT><B>-ipady <I>pixels</I></B> </DT> <DD>Sets how much vertical padding to add internally on the top and bottom of <I>widget</I>. <I>Pixels</I> must be a valid screen distance like <I>2</I> or <I>0.3i</I>. The default is <I>0</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets how much padding to add to the left and right exteriors of <I>widget</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the left side of <I>widget</I> is padded by the first value and the right side by the second value. If <I>pad</I> has just one value, both the left and right sides are padded evenly by the value. The default is <I>0</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets how much padding to add to the top and bottom exteriors of <I>widget</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the area above <I>widget</I> is padded by the first value and the area below by the second value. If <I>pad</I> is just one number, both the top and bottom areas are padded by the value. The default is <I>0</I>. </DD> <DT><B>-reqheight <I>height</I></B> </DT> <DD>Specifies the limits of the requested height for <I>widget</I>. <I>Height</I> is a list of bounding values. See the <FONT SIZE=-1><B>BOUNDING</B></FONT> section for a description of this list. By default, the height of <I>widget</I> is its requested height with its internal padding (see the <B>-ipady</B> option). The bounds specified by <I>height</I> either override the height completely, or bound the height between two sizes. The default is <I>""</I>. </DD> <DT><B>-reqwidth <I>width</I></B> </DT> <DD>Specifies the limits of the requested width for <I>widget</I>. <I>Width</I> is a list of bounding values. See the <FONT SIZE=-1><B>BOUNDING</B></FONT> section for a description of this list. By default, the width of <I>widget</I> is its requested width with its internal padding (set the <B>-ipadx</B> option). The bounds specified by <I>width</I> either override the width completely, or bound the height between two sizes. The default is <I>""</I>. </DD> <DT><B>-rowspan <I>number</I></B> </DT> <DD>Sets the number of rows <I>widget</I> will span. The default is <I>1</I>. </DD> <DT><B>-rowcontrol <I>control</I></B> </DT> <DD>Specifies how the height of <I>widget</I> should control the height of the rows it spans. <I>Control</I> is either <I>normal</I>, <I>none</I>, or <I>full</I>. The default is <I>normal</I>. <blockquote></DD> <DT><I>none</I> </DT> <DD>The height of <I>widget</I> is not considered. </DD> <DT><I>full</I> </DT> <DD>Only the height of <I>widget</I> will be considered when computing the heights of the rows. </DD> <DT><I>normal</I> </DT> <DD>Indicates that the tallest widget spanning the row will determine the height of the span. </DD> </DL> </blockquote> </blockquote> <H2><A NAME="sect8" HREF="#toc8">Column Options</A></H2> To configure a column in the table, specify the column index as <I>C<I>i</I></I>, where <I>i</I> is the index of the column to be configured. <BR> <P> <CODE><B>table configure</B> <I>container <I>C<I>i</I></I></I> ?<I>option value</I>?...<BR> </CODE><P>If the index is specified as <I>C*</I>, then all columns of the table will be configured. The following options are available for table columns. <blockquote> <DL> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right of the column. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the left side of the column is padded by the first value and the right side by the second value. If <I>pad</I> has just one value, both the left and right sides are padded evenly by the value. The default is <I>0</I>. </DD> <DT><B>-resize <I>mode</I></B> </DT> <DD>Indicates that the column can expand or shrink from its requested width when the table is resized. <I>Mode</I> must be one of the following: <I>none</I>, <I>expand</I>, <I>shrink</I>, or <I>both</I>. If <I>mode</I> is <I>expand</I> the width of the column is expanded if there is extra space in the container window. If <I>mode</I> is <I>shrink</I> its width may be reduced beyond its requested width if there is not enough space in the container. The default is <I>none</I>. </DD> <DT><B>-width <I>width</I></B> </DT> <DD>Specifies the limits within that the width of the column may expand or shrink. <I>Width</I> is a list of bounding values. See the section <FONT SIZE=-1><B>BOUNDING</B></FONT> for a description of this list. By default there are no constraints. </DD> </DL> </blockquote> <H2><A NAME="sect9" HREF="#toc9">Row Options</A></H2> To configure a row in the table, specify the row index as <I>R<I>i</I></I>, where <I>i</I> is the index of the row to be configured. <BR> <P> <CODE><B>table configure</B> <I>container <I>R<I>i</I></I></I> ?<I>option value</I>?...<BR> </CODE><P>If the index is specified as <I>R*</I>, then all rows of the table will be configured. The following options are available for table rows. <blockquote> <DL> <DT><B>-height <I>height</I></B> </DT> <DD>Specifies the limits of the height that the row may expand or shrink to. <I>Height</I> is a list of bounding values. See the section <FONT SIZE=-1><B>BOUNDING</B></FONT> for a description of this list. By default there are no constraints. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the row. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the area above the row is padded by the first value and the area below by the second value. If <I>pad</I> is just one number, both the top and bottom areas are padded by the value. The default is <I>0</I>. </DD> <DT><B>-resize <I>mode</I></B> </DT> <DD>Indicates that the row can expand or shrink from its requested height when the table is resized. <I>Mode</I> must be one of the following: <I>none</I>, <I>expand</I>, <I>shrink</I>, or <I>both</I>. If <I>mode</I> is <I>expand</I> the height of the row is expanded if there is extra space in the container. If <I>mode</I> is <I>shrink</I> its height may be reduced beyond its requested height if there is not enough space in the container. The default is <I>none</I>. </DD> </DL> </blockquote> <H2><A NAME="sect10" HREF="#toc10">Bounding Sizes</A></H2> Sometimes it's more useful to limit resizes to an acceptable range, than to fix the size to a particular value or disallow resizing altogether. Similar to the way the <B>wm</B> command lets you specify a <B>minsize</B> and <B>maxsize</B> for a toplevel window, you can bound the sizes the container, a widget, row, or column may take. The <B>-width</B>, <B>-height</B>, <B>-reqwidth</B>, and <B>-reqheight</B> options, take a list of one, two, or three values. We can take a previous example and instead preventing resizing, bound the size of the scrollbars between two values. <BR> <CODE>table . \<BR> .title 0,0 -cspan 3 \<BR> .canvas 1,1 -fill both \<BR> .vscroll 1,2 -fill y \<BR> .hscroll 2,1 -fill x<BR> <P> # Bound the scrollbars between 1/8 and 1/2 inch<BR> table configure . c2 -width { 0.125 0.5 }<BR> table configure . r2 -height { 0.125 0.5 }<BR> table configure . vscroll .hscroll -fill both<BR> </CODE><P>The scrollbars will get no smaller than 1/8 of an inch, or bigger than 1/2 inch. The initial size will be their requested size, so long as it is within the specified bounds. <P> How the elements of the list are interpreted is dependent upon the number of elements in the list. <blockquote> <DL> <DT>{<I></I>} </DT> <DD>Empty list. No bounds are set. The default sizing is performed. </DD> <DT>{<I> x </I>} </DT> <DD>Fixes the size to <I>x</I>. The window or partition cannot grow or shrink. </DD> <DT>{<I> min max </I>} </DT> <DD>Sets up minimum and maximum limits for the size of the window or partition. The window or partition can be reduced less than <I>min</I>, nor can it be stretched beyond <I>max</I>. </DD> <DT>{<I> min max nom </I>} </DT> <DD>Specifies minimum and maximum size limits, but also specifies a nominal size <I>nom</I>. This overrides the calculated size of the window or partition. </DD> </DL> </blockquote> <H2><A NAME="sect11" HREF="#toc11">Miscellaneous</A></H2> Another feature is that you can put two widgets in the same cell of the table. This is useful when you want to add decorations around a widget. <BR> <CODE>frame .frame -bd 1 -relief sunken<BR> button .quit -text "Quit"<BR> <P> # Put both the frame and the button in the same cell.<BR> table . \<BR> .quit 1,0 -padx 2 -pady 2 \<BR> .frame 1,0 -fill both<BR> <H2><A NAME="sect12" HREF="#toc12"></CODE><P>Limitations</A></H2> A long standing bug in Tk (circa 1993), there is no way to detect if a window is already a container of a different geometry manager. This is usually done by accident, such as the following where all three widgets are arranged in the same container ".", but using different geometry managers. <BR> <CODE> table .f1<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;...<BR> pack .f2<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;...<BR> grid .f3<BR> </CODE><P>This leads to bizarre window resizing, as each geometry manager applies its own brand of layout policies. When the container is a top level window (such as "."), your window manager may become locked as it responds to the never-ending stream of resize requests. <H2><A NAME="sect13" HREF="#toc13">Keywords</A></H2> frame, geometry manager, location, table, size <P> <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Operations</A></LI> <LI><A NAME="toc6" HREF="#sect6">Table Options</A></LI> <LI><A NAME="toc7" HREF="#sect7">Widget Options</A></LI> <LI><A NAME="toc8" HREF="#sect8">Column Options</A></LI> <LI><A NAME="toc9" HREF="#sect9">Row Options</A></LI> <LI><A NAME="toc10" HREF="#sect10">Bounding Sizes</A></LI> <LI><A NAME="toc11" HREF="#sect11">Miscellaneous</A></LI> <LI><A NAME="toc12" HREF="#sect12">Limitations</A></LI> <LI><A NAME="toc13" HREF="#sect13">Keywords</A></LI> </UL> </BODY></HTML> �����������������������������������������������������������������������������������./saods9/blt3.0.1/html/tile.html��������������������������������������������������������������������0000644�0001750�0001750�00000010740�11462120062�015027� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>tile(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> tile - Tiling versions of Tk widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <P> <B>tile::button <I>pathName</I></B> <I>option value</I>... <P> <B>tile::checkbutton <I>pathName</I></B> <I>option value</I>... <P> <B>tile::frame <I>pathName</I></B> <I>option value</I>... <P> <B>tile::label <I>pathName</I></B> <I>option value</I>... <P> <B>tile::radiobutton <I>pathName</I></B> <I>option value</I>... <P> <B>tile::scrollbar <I>pathName</I></B> <I>option value</I>... <P> <B>tile::toplevel <I>pathName</I></B> <I>option value</I>... <P> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The tile widgets let you create textured backgrounds. The texture is a Tk image which is tiled over the entire background of the widget. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> With the advent of Tk 4.0, images are now easy to create and use in applications. Images add interest to applications and they convey more information. But one area where Tk hasn't taken advantage of images is using images as textures for widgets. Since tiling is a standard feature of windowing systems, it's very easy to use images as textures. <P> The tile widgets take the standard Tk 4.0 widgets and add tiling configuration options to them. Textures are specified by the name of the image you wish to be tiled across the background of the widget. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> To add tiling to a widget, you simply create an image using Tk's <B>image</B> command and use the image name as the value for the <B>-tile</B> configuration option of the widget. <BR> <CODE>image create photo my_texture -file tan_paper.gif<BR> blt::tile::frame .f -tile my_texture<BR> </CODE><P>The image <I>my_texture</I> is added to the frame. If <I>my_texture</I> is updated, so will the widget background. <BR> <CODE>image create photo my_texture -file rain.gif<BR> </CODE><P>The tile widget commands reside in the "blt::tile" namespace, so as not to collide with the normal Tk widgets. An easy way to add tiling to existing programs is to import the tile widget commands into the global namespace. <BR> <CODE>image create photo my_texture -file tan_paper.gif<BR> namespace import -force blt::tile::*<BR> frame .f -tile my_texture<BR> </CODE><P>To use one image for all texturing, you can use the "Tile" option class name to specify the same image for all tile widgets. <BR> <CODE>image create photo my_texture -file tan_paper.gif<BR> option add *Tile my_texture<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Options</A></H2> The following configurations options are added to the widgets. If a <B>-tile<B> or <B>-activetile</B></B></B> option is specified, it overrides the background color of the widget. <DL> <DT><B>-activetile <I>image</I></B> </DT> <DD>Specifies a textured background to display when the widget is active. This option is available for the <B>tilebutton</B>, <B>tilecheckbutton</B>, <B>tileradiobutton</B>, and <B>tilescrollbar</B> widgets. <I>Image</I> is the name an image created using Tk's <B>image</B> command. The background of the widget is tiled with <I>image</I>. If <I>image</I> is <I>""</I>, then the active background color is displayed. The default is <I>""</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a textured background to display for the widget. <I>Image</I> is the name an image created using Tk's <B>image</B> command. The background of the widget is tiled with <I>image</I>. If <I>image</I> is <I>""</I>, then the normal background color is displayed. The default is <I>""</I>. </DD> </DL> <H2><A NAME="sect6" HREF="#toc6">Keywords</A></H2> tile, texture, button, label, radiobutton, checkbutton, scrollbar, frame, toplevel <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Options</A></LI> <LI><A NAME="toc6" HREF="#sect6">Keywords</A></LI> </UL> </BODY></HTML> ��������������������������������./saods9/blt3.0.1/html/spline.html������������������������������������������������������������������0000644�0001750�0001750�00000017755�11462120062�015401� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>spline(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> spline - Fit curves with spline interpolation <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <P> <B>spline natural <I>x y sx sy</I></B> <P> <B>spline quadratic <I>x y sx sy</I></B> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>spline</B> command computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Curve fitting has many applications. In graphs, curve fitting can be useful for displaying curves which are aesthetically pleasing to the eye. Another advantage is that you can quickly generate arbitrary points on the curve from a small set of data points. <P> A spline is a device used in drafting to produce smoothed curves. The points of the curve, known as <I>knots</I>, are fixed and the <I>spline</I>, typically a thin strip of wood or metal, is bent around the knots to create the smoothed curve. Spline interpolation is the mathematical equivalent. The curves between adjacent knots are piecewise functions such that the resulting spline runs exactly through all the knots. The order and coefficients of the polynominal determine the "looseness" or "tightness" of the curve fit from the line segments formed by the knots. <P> The <B>spline</B> command performs spline interpolation using cubic ("natural") or quadratic polynomial functions. It computes the spline based upon the knots, which are given as x and y vectors. The interpolated new points are determined by another vector which represents the abscissas (x-coordinates) or the new points. The ordinates (y-coordinates) are interpolated using the spline and written to another vector. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> Before we can use the <B>spline</B> command, we need to create two BLT vectors which will represent the knots (x and y coordinates) of the data that we're going to fit. Obviously, both vectors must be the same length. <BR> <CODE># Create sample data of ten points. <BR> vector x(10) y(10)<BR> <P> for {set i 10} {$i &gt; 0} {incr i -1} {<BR> set x($i-1) [expr $i*$i]<BR> set y($i-1) [expr sin($i*$i*$i)]<BR> }<BR> </CODE><P>We now have two vectors <I>x</I> and <I>y</I> representing the ten data points we're trying to fit. The order of the values of <I>x</I> must be monotonically increasing. We can use the vector's <B>sort</B> operation to sort the vectors. <BR> <CODE>x sort y<BR> </CODE><P>The components of <I>x</I> are sorted in increasing order. The components of <I>y</I> are rearranged so that the original x,y coordinate pairings are retained. <P> A third vector is needed to indicate the abscissas (x-coordinates) of the new points to be interpolated by the spline. Like the x vector, the vector of abscissas must be monotonically increasing. All the abscissas must lie between the first and last knots (x vector) forming the spline. <P> How the abscissas are picked is arbitrary. But if we are going to plot the spline, we will want to include the knots too. Since both the quadratic and natural splines preserve the knots (an abscissa from the x vector will always produce the corresponding ordinate from the y vector), we can simply make the new vector a superset of <I>x</I>. It will contain the same coordinates as <I>x</I>, but also the abscissas of the new points we want interpolated. A simple way is to use the vector's <B>populate</B> operation. <BR> <CODE>x populate sx 10<BR> </CODE><P>This creates a new vector <I>sx</I>. It contains the abscissas of <I>x</I>, but in addition <I>sx</I> will have ten evenly distributed values between each abscissa. You can interpolate any points you wish, simply by setting the vector values. <P> Finally, we generate the ordinates (the images of the spline) using the <B>spline</B> command. The ordinates are stored in a fourth vector. <BR> <CODE>spline natural x y sx sy<BR> </CODE><P>This creates a new vector <I>sy</I>. It will have the same length as <I>sx</I>. The vectors <I>sx</I> and <I>sy</I> represent the smoothed curve which we can now plot. <BR> <CODE>graph .graph<BR> .graph element create original -x x -y x -color blue<BR> .graph element create spline -x sx -y sy -color red<BR> table . .graph<BR> </CODE><P>The <B>natural</B> operation employs a cubic interpolant when forming the spline. In terms of the draftmen's spline, a <I>natural spline</I> requires the least amount of energy to bend the spline (strip of wood), while still passing through each knot. In mathematical terms, the second derivatives of the first and last points are zero. <P> Alternatively, you can generate a spline using the <B>quadratic</B> operation. Quadratic interpolation produces a spline which follows the line segments of the data points much more closely. <BR> <CODE>spline quadratic x y sx sy <BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Operations</A></H2> <DL> <DT><B>spline natural <I>x y sx sy</I></B> </DT> <DD>Computes a cubic spline from the data points represented by the vectors <I>x</I> and <I>y</I> and interpolates new points using vector <I>sx</I> as the x-coordinates. The resulting y-coordinates are written to a new vector <I>sy</I>. The vectors <I>x</I> and <I>y</I> must be the same length and contain at least three components. The order of the components of <I>x</I> must be monotonically increasing. <I>Sx</I> is the vector containing the x-coordinates of the points to be interpolated. No component of <I>sx</I> can be less than first component of <I>x</I> or greater than the last component. The order of the components of <I>sx</I> must be monotonically increasing. <I>Sy</I> is the name of the vector where the calculated y-coordinates will be stored. If <I>sy</I> does not already exist, a new vector will be created. </DD> <DT><B>spline quadratic <I>x y sx sy</I></B> </DT> <DD>Computes a quadratic spline from the data points represented by the vectors <I>x</I> and <I>y</I> and interpolates new points using vector <I>sx</I> as the x-coordinates. The resulting y-coordinates are written to a new vector <I>sy</I>. The vectors <I>x</I> and <I>y</I> must be the same length and contain at least three components. The order of the components of <I>x</I> must be monotonically increasing. <I>Sx</I> is the vector containing the x-coordinates of the points to be interpolated. No component of <I>sx</I> can be less than first component of <I>x</I> or greater than the last component. The order of the components of <I>sx</I> must be monotonically increasing. <I>Sy</I> is the name of the vector where the calculated y-coordinates are stored. If <I>sy</I> does not already exist, a new vector will be created. </DD> </DL> <H2><A NAME="sect6" HREF="#toc6">References</A></H2> <BR> <PRE> Numerical Analysis by R. Burden, J. Faires and A. Reynolds.<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp; Prindle, Weber &amp; Schmidt, 1981, pp. 112 Shape Preserving Quadratic Splines by D.F.Mcallister &amp; J.A.Roulier Coded by S.L.Dodd &amp; M.Roulier N.C.State University. </PRE>The original code for the quadratric spline can be found in TOMS #574. <H2><A NAME="sect7" HREF="#toc7">Keywords</A></H2> spline, vector, graph <P> <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Operations</A></LI> <LI><A NAME="toc6" HREF="#sect6">References</A></LI> <LI><A NAME="toc7" HREF="#sect7">Keywords</A></LI> </UL> </BODY></HTML> �������������������./saods9/blt3.0.1/html/watch.html�������������������������������������������������������������������0000644�0001750�0001750�00000013151�11462120062�015177� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>watch(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> watch - call Tcl procedures before and after each command <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>watch create</B> <I>watchName</I> ?<I>options</I>? <P> <B>watch activate</B> <I>watchName</I> <P> <B>watch deactivate</B> <I>watchName</I> <P> <B>watch delete</B> <I>watchName</I> <P> <B>watch configure</B> <I>watchName</I> ?<I>options</I> <P> <B>watch info</B> <I>watchName</I> <P> <B>watch names</B> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>watch</B> command arranges for Tcl procedures to be invoked before and after the execution of each Tcl command. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> When an error occurs in Tcl, the global variable <I>errorInfo</I> will contain a stack-trace of the active procedures when the error occured. Sometimes, however, the stack trace is insufficient. You may need to know exactly where in the program's execution the error occured. In cases like this, a more general tracing facility would be useful. <P> The <B>watch</B> command lets you designate Tcl procedures to be invoked before and after the execution of each Tcl command. This means you can display the command line and its results for each command as it executes. Another use is to profile your Tcl commands. You can profile any Tcl command (like <B>if</B> and <B>set</B>), not just Tcl procedures. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> The following example use <B>watch</B> to trace Tcl commands (printing to standard error) both before and after they are executed. <BR> <CODE>proc preCmd { level command argv } {<BR> set name [lindex $argv 0]<BR> puts stderr "$level $name =&gt; $command"<BR> }<BR> <P> proc postCmd { level command argv retcode results } {<BR> set name [lindex $argv 0]<BR> puts stderr "$level $name =&gt; $argv0= ($retcode) $results"<BR> }<BR> watch create trace \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-postcmd postCmd -precmd preCmd<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Operations</A></H2> The following operations are available for the <B>watch</B> command: <DL> <DT><B>watch activate <I>watchName</I></B> </DT> <DD>Activates the watch, causing Tcl commands the be traced to the maximum depth selected. </DD> <DT><B>watch create <I>watchName</I></B> ?<I>options</I>?... </DT> <DD>Creates a new watch <I>watchName</I>. It's an error if another watch <I>watchName</I> already exists and an error message will be returned. <I>Options</I> may have any of the values accepted by the <B>watch configure</B> command. This command returns the empty string. </DD> <DT><B>watch configure <I>watchName</I></B> ?<I>options...</I>? </DT> <DD>Queries or modifies the configuration options of the watch <I>watchName</I>. <I>WatchName</I> is the name of a watch. <I>Options</I> may have any of the following values: <blockquote></DD> <DT><B>-active <I>boolean</I></B> </DT> <DD>Specifies if the watch is active. By default, watches are active when created. </DD> <DT><B>-postcmd <I>string</I></B> </DT> <DD>Specifies a Tcl procedure to be called immediately after each Tcl command. <I>String</I> is name of a Tcl procedure and any extra arguments to be passed to it. Before <I>string</I> is invoked, five more arguments are appended: 1) the current level 2) the current command line 3) a list containing the command after substitutions and split into words 4) the return code of the command, and 5) the results of the command. The return status of the postcmd procedure is always ignored. </DD> <DT><B>-precmd <I>string</I></B> </DT> <DD>Specifies a Tcl procedure to be called immediately before each Tcl command. <I>String</I> is name of a Tcl procedure and any extra arguments to be passed to it. Before <I>string</I> is invoked, three arguments are appended: 1) the current level 2) the current command line, and 3) a list containing the command after substitutions and split into words. The return status of the <B>-precmd</B> procedure is always ignored. </DD> <DT><B>-maxlevel <I>number</I></B> </DT> <DD>Specifies the maximum evaluation depth to watch Tcl commands. The default maximum level is 10000. </DD> </DL> </blockquote> <DL> <DT><B>watch deactivate <I>watchName</I></B> </DT> <DD>Deactivates the watch. The <B>-precmd</B> and <B>-postcmd</B> procedures will no longer be invoked. </DD> <DT><B>watch info <I>watchName</I></B> </DT> <DD>Returns the configuration information associated with the watch <I>watchName</I>. <I>WatchName</I> is the name of a watch. </DD> <DT><B>watch names</B> ?<I>state</I>? </DT> <DD>Lists the names of the watches for a given state. <I>State</I> may be one of the following: <I>active</I>, <I>idle</I>, or <I>ignore</I>. If a <I>state</I> argument isn't specified, all watches are<BR> listed. </DD> </DL> </blockquote> <H2><A NAME="sect6" HREF="#toc6">Keywords</A></H2> debug, profile <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Operations</A></LI> <LI><A NAME="toc6" HREF="#sect6">Keywords</A></LI> </UL> </BODY></HTML> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/tabset.html������������������������������������������������������������������0000644�0001750�0001750�00000123574�11462120062�015366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>tabset(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> tabset - Create and manipulate tabset widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>tabset</B> <I>pathName </I>?<I>options</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>tabset</B> widget displays a series of overlapping folders. Only the contents of one folder at a time is displayed. By clicking on the tab's of a folder, you can view other folders. Each folder may contain any Tk widget that can be automatically positioned and resized in the folder. <P> There's no limit to the number of folders. Tabs can be tiered or scrolled. Pages (i.e. embedded widgets) can be torn off and displayed in another toplevel widget, and also restored. A tabset can also be used as just a set of tabs, without a displaying any pages. You can bind events to individual tabs, so it's easy to add features like "balloon help". <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Notebooks are a popular graphical paradigm. They allow you to organize many windows in a single widget. For example, you might have an application the displays several X-Y graphs at the same time. Typically, you can't pack the graphs into the same <B>frame</B> because they are too large. The other alternative is to pack the graphs into several <B>toplevel</B> widgets, allowing them to overlap on the screen. The problem is that all the different toplevel windows clutter the screen and are difficult to manage. <P> The <B>tabset</B> widget lets organize your application by displaying each graph as a page in a folder of a notebook. Only one page is visible at a time. When you click on a tab, the folder (graph) corresponding to the tab is displayed in the <B>tabset</B> widget. The tabset also lets you temporarily tear pages out of the notebook into a separate toplevel widget, and put them back in the tabset later. For example, you could compare two graphs side-by-side by tearing them out, and then replace them when you are finished. <P> A tabset may contain an unlimited number of folders. If there are too many tabs to view, you can arrange them as multiple tiers or scroll the tabs. The tabset uses the conventional Tk scrollbar syntax, so you can attach a scrollbar too. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> You create a tabset widget with the <B>tabset</B> command. <BR> <CODE># Create a new tabset<BR> tabset .ts -relief sunken -borderwidth 2 <BR> </CODE><P>A new Tcl command <I>.ts</I> is also created. This command can be used to query and modify the tabset. For example, to change the default font used by all the tab labels, you use the new command and the tabset's <B>configure</B> operation. <BR> <CODE># Change the default font.<BR> .ts configure -font "fixed"<BR> </CODE><P>You can then add folders using the <B>insert</B> operation. <BR> <CODE># Create a new folder "f1"<BR> .ts insert 0 "f1"<BR> </CODE><P>This inserts the new tab named "f1" into the tabset. The index <I>0</I> indicates location to insert the new tab. You can also use the index <I>end</I> to append a tab to the end of the tabset. By default, the text of the tab is the name of the tab. You can change this by configuring the <B>-text</B> option. <BR> <CODE># Change the label of "f1"<BR> .ts tab configure "f1" -label "Tab #1" <BR> </CODE><P>The <B>insert</B> operation lets you add one or more folders at a time. <BR> <CODE>.ts insert end "f2" -label "Tab #2" "f3" "f4" <BR> </CODE><P>The tab on each folder contains a label. A label may display both an image and a text string. You can reconfigure the tab's attributes (foreground/background colors, font, rotation, etc) using the <B>tab configure</B> operation. <BR> <CODE># Add an image to the label of "f1"<BR> set image [image create photo -file stopsign.gif]<BR> .ts tab configure "f1" -image $image<BR> .ts tab configure "f2" -rotate 90<BR> </CODE><P>Each folder may contain an embedded widget to represent its contents. The widget to be embedded must be a child of the tabset widget. Using the <B>-window</B> option, you specify the name of widget to be embedded. But don't pack the widget, the tabset takes care of placing and arranging the widget for you. <BR> <CODE>graph .ts.graph<BR> .ts tab configure "f1" -window ".ts.graph" \<BR> -fill both -padx 0.25i -pady 0.25i<BR> </CODE><P>The size of the folder is determined the sizes of the Tk widgets embedded inside each folder. The folder will be as wide as the widest widget in any folder. The tallest determines the height. You can use the tab's <B>-pagewidth</B> and <B>-pageheight</B> options override this. <P> Other options control how the widget appears in the folder. The <B>-fill</B> option says that you wish to have the widget stretch to fill the available space in the folder. <BR> <CODE>.ts tab configure "f1" -fill both -padx 0.25i -pady 0.25i<BR> <P> </CODE><P>Now when you click the left mouse button on "f1", the graph will be displayed in the folder. It will be automatically hidden when another folder is selected. If you click on the right mouse button, the embedded widget will be moved into a toplevel widget of its own. Clicking again on the right mouse button puts it back into the folder. <P> If you want to share a page between two different folders, the <B>-command</B> option lets you specify a Tcl command to be invoked whenever the folder is selected. You can reset the <B>-window</B> option for the tab whenever it's clicked. <BR> <CODE>.ts tab configure "f2" -command { <BR> .ts tab configure "f2" -window ".ts.graph"<BR> }<BR> .ts tab configure "f1" -command { <BR> .ts tab configure "f1" -window ".ts.graph"<BR> }<BR> </CODE><P>If you have many folders, you may wish to stack tabs in multiple tiers. The tabset's <B>-tiers</B> option requests a maximum number of tiers. The default is one tier. <BR> <CODE>.ts configure -tiers 2<BR> </CODE><P>If the tabs can fit in less tiers, the widget will use that many. Whenever there are more tabs than can be displayed in the maximum number of tiers, the tabset will automatically let you scroll the tabs. You can even attach a scrollbar to the tabset. <BR> <CODE>.ts configure -scrollcommand { .sbar set } -scrollincrement 20<BR> .sbar configure -orient horizontal -command { .ts view }<BR> </CODE><P>By default tabs are along the top of the tabset from left to right. But tabs can be placed on any side of the tabset using the <B>-side</B> option. <BR> <CODE># Arrange tabs along the right side of the tabset. <BR> .ts configure -side right -rotate 270<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Syntax</A></H2> The <B>tabset</B> command creates a new window using the <I>pathName</I> argument and makes it into a tabset widget. <BR> <P> <CODE><B>tabset <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>Additional options may be specified on the command line or in the option database to configure aspects of the tabset such as its colors, font, text, and relief. The <B>tabset</B> command returns its <I>pathName</I> argument. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. <P> When first created, a new tabset contains no tabs. Tabs are added or deleted using widget operations described below. It is not necessary for all the tabs to be displayed in the tabset window at once; commands described below may be used to change the view in the window. Tabsets allow scrolling of tabs using the <B>-scrollcommand</B> option. They also support scanning (see the <B>scan</B> operation). Tabs may be arranged along any side of the tabset window using the <B>-side</B> option. <P> The size of the tabset window is determined the number of tiers of tabs and the sizes of the Tk widgets embedded inside each folder. The widest widget determines the width of the folder. The tallest determines the height. If no folders contain an embedded widget, the size is detemined solely by the size of the tabs. <P> You can override either dimension with the tabset's <B>-width</B> and <B>-height</B> options. <H2><A NAME="sect6" HREF="#toc6">Tabset Indices</A></H2> Indices refer to individual tabs/folders in the tabset. Many of the operations for tabset widgets take one or more indices as arguments. An index may take several forms: <DL> <DT><I>number</I> </DT> <DD>Unique node id of the tab. </DD> <DT><B>@<I>x<B>,<I>y</I></B></I></B> </DT> <DD>Tab that covers the point in the tabset window specified by <I>x</I> and <I>y</I> (in screen coordinates). If no tab covers that point, then the index is ignored. </DD> <DT><B>select</B> </DT> <DD>The currently selected tab. The <B>select</B> index is typically changed by either clicking on the tab with the left mouse button or using the widget's <B>invoke</B> operation. </DD> <DT><B>active</B> </DT> <DD>The tab where the mouse pointer is currently located. The label is drawn using its active colors (see the <B>-activebackground</B> and <B>-activeforeground</B> options). The <B>active</B> index is typically changed by moving the mouse pointer over a tab or using the widget's <B>activate</B> operation. There can be only one active tab at a time. If there is no tab located under the mouse pointer, the index is ignored. </DD> <DT><B>focus</B> </DT> <DD>Tab that currently has the widget's focus. This tab is displayed with a dashed line around its label. You can change this using the <B>focus</B> operation. If no tab has focus, then the index is ignored. </DD> <DT><B>down</B> </DT> <DD>Tab immediately below the tab that currently has focus, if there is one. If there is no tab below, the current tab is returned. </DD> <DT><B>left</B> </DT> <DD>Tab immediately to the left the tab that currently has focus, if there is one. If there is no tab to the left, the current tab is returned. </DD> <DT><B>right</B> </DT> <DD>Tab immediately to the right the tab that currently has focus, if there is one. If there is no tab to the right, the current tab is returned. </DD> <DT><B>up</B> </DT> <DD>Tab immediately above, if there is one, to the tab that currently has focus. If there is no tab above, the current tab is returned. </DD> <DT><B>end</B> </DT> <DD>Last tab in the tabset. If there are no tabs in the tabset then the index is ignored. </DD> </DL> <P> Some indices may not always be available. For example, if the mouse is not over any tab, "active" does not have an index. For most tabset operations this is harmless and ignored. <H2><A NAME="sect7" HREF="#toc7">Tabset Operations</A></H2> All <B>tabset</B> operations are invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: <P> <BR> <P> <CODE><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<I>pathName operation </I>?<I>arg arg ...</I>?<BR> <P> </CODE><P><I>Operation</I> and the <I>arg</I>s determine the exact behavior of the command. The following operations are available for tabset widgets: <DL> <DT><I>pathName <B>activate</B></I> <I>index</I> </DT> <DD>Sets the active tab to the one indicated by <I>index</I>. The active tab is drawn with its <I>active</I> colors (see the <B>-activebackground</B> and <B>-activeforeground</B> options) and may be retrieved with the index <B>active</B>. Only one tab may be active at a time. If <I>index</I> is the empty string, then all tabs will be drawn with their normal foreground and background colors. </DD> <DT><I>pathName <B>bind</B></I> <I>tagName</I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a tab with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on tabs, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I>. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>configure</B> operation described below. </DD> <DT><I>pathName <B>configure</B></I> ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of the widget. If no <I>option</I> is specified, returns a list describing all the available options for <I>pathName</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list). If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. <I>Option</I> and <I>value</I> are described below: <blockquote></DD> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the default active background color for tabs. A tab is active when the mouse is positioned over it or set by the <B>activate</B> operation. Individual tabs may override this option by setting the tab's <B>-activebackground</B> option. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the default active foreground color for tabs. A tab is active when the mouse is positioned over it or set by the <B>activate</B> operation. Individual tabs may override this option by setting the tab's <B>-activeforeground</B> option. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the tabset. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines how the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>""</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the focus outline. When a tab has the widget's focus, it is drawn with a dashed outline around its label. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the outline will be a solid line. The default value is <I>5 2</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the default font for the text in tab labels. Individual tabs may override this by setting the tab's <B>-font</B> option. The default value is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the default color of tab labels. Individual tabs may override this option by setting the tab's <B>-foreground</B> option. The default value is <I>black</I>. </DD> <DT><B>-gap <I>size</I></B> </DT> <DD>Sets the gap (in pixels) between tabs. The default value is <I>2</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. If <I>pixels</I> is 0, then the height of the widget will be calculated based on the size the tabs and their pages. The default is <I>0</I>. </DD> <DT><B>-highlightbackground <I>color</I></B> </DT> <DD>Sets the color to display in the traversal highlight region when the tabset does not have the input focus. </DD> <DT><B>-highlightcolor <I>color</I></B> </DT> <DD>Sets the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus. The default is <I>black</I>. </DD> <DT><B>-highlightthickness <I>pixels</I></B> </DT> <DD>Sets the width of the highlight rectangle to draw around the outside of the widget when it has the input focus. <I>Pixels</I> is a non-negative value and may have any of the forms acceptable to <B>Tk_GetPixels</B>. If the value is zero, no focus highlight is drawn around the widget. The default is <I>2</I>. </DD> <DT><B>-pageheight <I>pixels</I></B> </DT> <DD>Sets the requested height of the page. The page is the area under the tab used to display the page contents. If <I>pixels</I> is <I>0</I>, the maximum height of all embedded tab windows is used. The default is <I>0</I>. </DD> <DT><B>-pagewidth <I>pixels</I></B> </DT> <DD>Sets the requested width of the page. The page is the area under the tab used to display the page contents. If <I>pixels</I> is <I>0</I>, the maximum width of all embedded tab windows is used. The default is <I>0</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the tabset widget. <I>Relief</I> specifies how the tabset should appear relative to widget that it is packed into; for example, <I>raised</I> means the tabset should appear to protrude. The default is <I>sunken</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the degrees to rotate text in tab labels. <I>Theta</I> is a real value representing the number of degrees to rotate the tick labels. The default is <I>0.0</I> degrees. </DD> <DT><B>-samewidth <I>boolean</I></B> </DT> <DD>Indicates if each tab should be the same width. If true, each tab will be as wide as the widest tab. The default is <I>no</I>. </DD> <DT><B>-scrollcommand <I>string</I></B> </DT> <DD>Specifies the prefix for a command for communicating with scrollbars. Whenever the view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. </DD> <DT><B>-scrollincrement <I>pixels</I></B> </DT> <DD>Sets the smallest number of pixels to scroll the tabs. If <I>pixels</I> is greater than 0, this sets the units for scrolling (e.g., when you the change the view by clicking on the left and right arrows of a scrollbar). </DD> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the color to use when displaying background of the selected tab. Individual tabs can override this option by setting the tab's <B>-selectbackground</B> option. </DD> <DT><B>-selectborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the raised 3-D border to draw around the label of the selected tab. <I>Pixels</I> must be a non-negative value. The default value is <I>1</I>. </DD> <DT><B>-selectcommand <I>string</I></B> </DT> <DD>Specifies a default Tcl script to be associated with tabs. This command is typically invoked when left mouse button is released over the tab. Individual tabs may override this with the tab's <B>-command</B> option. The default value is <I>""</I>. </DD> <DT><B>-selectforeground <I>color<B> </B></I></B></DT> <DD>Sets the default color of the selected tab's text label. Individual tabs can override this option by setting the tab's <B>-selectforeground</B> option. The default value is <I>black</I>. </DD> <DT><B>-selectpad <I>pixels<B> </B></I></B></DT> <DD>Specifies extra padding to be displayed around the selected tab. The default value is <I>3</I>. </DD> <DT><B>-side <I>side<B> </B></I></B></DT> <DD>Specifies the side of the widget to place tabs. The following values are valid for <I>side</I>. The default value is <I>top</I>. <blockquote></DD> <DT><I>top</I> </DT> <DD>Tabs are drawn along the top. </DD> <DT><I>left</I> </DT> <DD>Tabs are drawn along the left side. </DD> <DT><I>right</I> </DT> <DD>Tabs are drawn along the right side. </DD> <DT><I>both</I> </DT> <DD>Tabs are drawn along the bottom side. </DD> </DL> </blockquote> <DL> <DT><B>-slant <I>slant</I></B> </DT> <DD>Specifies if the tabs should be slanted 45 degrees on the left and/or right sides. The following values are valid for <I>slant</I>. The default is <I>none</I>. <blockquote></DD> <DT><I>none</I> </DT> <DD>Tabs are drawn as a rectangle. </DD> <DT><I>left</I> </DT> <DD>The left side of the tab is slanted. </DD> <DT><I>right</I> </DT> <DD>The right side of the tab is slanted. </DD> <DT><I>both</I> </DT> <DD>Boths sides of the tab are slanted. </DD> </DL> </blockquote> <DL> <DT><B>-tabbackground <I>color</I></B> </DT> <DD>Sets the default background color of tabs. Individual tabs can override this option by setting the tab's <B>-background</B> option. </DD> <DT><B>-tabborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the tab. The <B>-tabrelief</B> option determines how the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-tabforeground <I>color</I></B> </DT> <DD>Specifies the color to use when displaying a tab's label. Individual tabs can override this option by setting the tab's <B>-foreground</B> option. </DD> <DT><B>-tabrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for both tabs and folders. <I>Relief</I> specifies how the tabs should appear relative to background of the widget; for example, <I>raised</I> means the tab should appear to protrude. The default is <I>raised</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts decide whether to focus on the window. The default is <I>1</I>. </DD> <DT><B>-textside <I>side<B> </B></I></B></DT> <DD>If both images and text are specified for a tab, this option determines on which side of the tab the text is to be displayed. The valid sides are <I>left</I>, <I>right</I>, <I>top</I>, and <I>bottom</I>. The default value is <I>left</I>. </DD> <DT><B>-tiers <I>number<B> </B></I></B></DT> <DD>Specifies the maximum number of tiers to use to display the tabs. The default value is <I>1</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a tiled background for the widget. If <I>image</I> isn't <I>""</I>, the background is tiled using <I>image</I>. Otherwise, the normal background color is drawn (see the <B>-background</B> option). <I>Image</I> must be an image created using the Tk <B>image</B> command. The default is <I>""</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. If <I>pixels</I> is 0, then the width of the widget will be calculated based on the size the tabs and their pages. The default is <I>0</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>delete <I>first </I></B></I>?<I>last</I>? </DT> <DD>Deletes one or more tabs from the tabset. <I>First</I> and <I>last</I> are the first and last indices, defining a range of tabs to be deleted. If <I>last</I> isn't specified, then only the tab at <I>first</I> is deleted. </DD> <DT><I>pathName <B>focus <I>index</I></B></I> </DT> <DD>Designates a tab to get the widget's focus. This tab is displayed with a dashed line around its label. </DD> <DT><I>pathName <B>get</B></I> <I>index</I> </DT> <DD>Returns the name of the tab. The value of <I>index</I> may be in any form described in the section <FONT SIZE=-1><B>TABSET INDICES</B></FONT> </DD> <DT><I>pathName <B>index</B></I> ?<I>flag</I>? <I>string</I> </DT> <DD>Returns the node id of the tab specified by <I>string</I>. If <I>flag</I> is <B>-name</B>, then <I>string</I> is the name of a tab. If <I>flag</I> is <B>-index</B>, <I>string</I> is an index such as "active" or "focus". If <I>flag</I> isn't specified, it defaults to <B>-index</B>. </DD> <DT><I>pathName <B>insert</B></I> <I>position <I>name</I></I> ?<I>option value</I>?... </DT> <DD>Inserts new tabs into the tabset. Tabs are inserted just before the tab given by <I>position</I>. <I>Position</I> may be either a number, indicating where in the list the new tab should be added, or <B>end</B>, indicating that the new tab is to be added the end of the list. <I>Name</I> is the symbolic name of the tab. <I>Be careful not to use a number. Otherwise the tabset will confuse it with tab indices</I>. Returns a list of indices for all the new tabs. </DD> <DT><I>pathName <B>invoke <I>index</I></B></I> </DT> <DD>Selects the tab given by <I>index</I>, maps the tab's embedded widget, and invokes the Tcl command associated with the tab, if there is one. The return value is the return value from the Tcl command, or an empty string if there is no command associated with the tab. This command is ignored if the tab's state (see the <B>-state</B> option) is disabled. </DD> <DT><I>pathName <B>move</B></I> <I>index</I> <B>before</B>|<B>after</B> <I>index</I> </DT> <DD>Moves the tab <I>index</I> to a new position in the tabset. </DD> <DT><I>pathName <B>nearest</B></I> <I>x</I> <I>y</I> </DT> <DD>Returns the name of the tab nearest to given X-Y screen coordinate. </DD> <DT><I>pathName <B>scan</B></I> <I>option args</I> </DT> <DD>This command implements scanning on tabsets. It has two forms, depending on <I>option</I>: <blockquote></DD> <DT><I>pathName <B>scan mark <I>x y</I></B></I> </DT> <DD>Records <I>x</I> and <I>y</I> and the current view in the tabset window; used with later <B>scan dragto</B> commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. </DD> <DT><I>pathName <B>scan dragto <I>x y</I></B></I>. </DT> <DD>This command computes the difference between its <I>x</I> and <I>y</I> arguments and the <I>x</I> and <I>y</I> arguments to the last <B>scan mark</B> command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>see <I>index</I></B></I> </DT> <DD>Scrolls the tabset so that the tab <I>index</I> is visible in the widget's window. </DD> <DT><I>pathName <B>size</B></I> </DT> <DD>Returns the number of tabs in the tabset. </DD> <DT><I>pathName <B>tab <I>operation</I></B></I> ?<I>args</I>? </DT> <DD>See the <FONT SIZE=-1><B>TAB OPERATIONS</B></FONT> section below. </DD> <DT><I>pathName <B>view <I>args</I></B></I> </DT> <DD>This command queries or changes the position of the tabset in the widget's window. It can take any of the following forms: <blockquote></DD> <DT><I>pathName <B>view</B></I> </DT> <DD>Returns a list of two numbers between 0.0 and 1.0 that describe the amount and position of the tabset that is visible in the window. For example, if <I>view</I> is "0.2 0.6", 20% of the tabset's text is off-screen to the left, 40% is visible in the window, and 40% of the tabset is off-screen to the right. These are the same values passed to scrollbars via the <B>-scrollcommand</B> option. </DD> <DT><I>pathName <B>view moveto<I> fraction</I></B></I> </DT> <DD>Adjusts the view in the window so that <I>fraction</I> of the total width of the tabset text is off-screen to the left. <I>fraction</I> must be a number between 0.0 and 1.0. </DD> <DT><I>pathName <B>view scroll <I>number what</I></B></I> </DT> <DD>This command shifts the view in the window (left/top or right/bottom) according to <I>number</I> and <I>what</I>. <I>Number</I> must be an integer. <I>What</I> must be either <B>units</B> or <B>pages</B> or an abbreviation of these. If <I>what</I> is <B>units</B>, the view adjusts left or right by <I>number</I> scroll units (see the <B>-scrollincrement</B> option). ; if it is <B>pages</B> then the view adjusts by <I>number</I> widget windows. If <I>number</I> is negative then tabs farther to the left become visible; if it is positive then tabs farther to the right become visible. </DD> </DL> </blockquote> <H2><A NAME="sect8" HREF="#toc8">Tab Operations</A></H2> <DL> <DT><I>pathName <B>tab cget</B></I> <I>nameOrIndex</I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may have any of the values accepted by the <B>tab configure</B> operation described below. </DD> <DT><I>pathName <B>tab configure</B></I> <I>nameOrIndex</I> ?<I>nameOrIndex</I>...? <I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Query or modify the configuration options of one or more tabs. If no <I>option</I> is specified, this operation returns a list describing all the available options for <I>nameOrIndex</I>. <I>NameOrIndex</I> can be either the name of a tab or its index. Names of tabs take precedence over their indices. That means a tab named <I>focus</I> is picked over the "focus" tab. </DD> </DL> <P> If <I>option</I> is specified, but not <I>value</I>, then a list describing the one named option is returned. If one or more <I>option-value</I> pairs are specified, then each named tab (specified by <I>nameOrIndex</I>) will have its configurations option(s) set the given value(s). In this last case, the empty string is returned. <I>Option</I> and <I>value</I> are described below: <blockquote> <DL> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the active background color for <I>nameOrIndex</I>. A tab is active when the mouse is positioned over it or set by the <B>activate</B> operation. This overrides the widget's <B>-activebackground</B> option. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the default active foreground color <I>nameOrIndex</I>. A tab is "active" when the mouse is positioned over it or set by the <B>activate</B> operation. Individual tabs may override this option by setting the tab's <B>-activeforeground</B> option. </DD> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Anchors the tab's embedded widget to a particular edge of the folder. This option has effect only if the space in the folder surrounding the embedded widget is larger than the widget itself. <I>Anchor</I> specifies how the widget will be positioned in the extra space. For example, if <I>anchor</I> is <I>center</I> then the window is centered in the folder ; if <I>anchor</I> is <I>w</I> then the window will be aligned with the leftmost edge of the folder. The default value is <I>center</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color for <I>nameOrIndex</I>. Setting this option overides the widget's <B>-tabbackground</B> option. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for this tab. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how commands for events in tabs are invoked. Each tag in the list matching the event sequence will have its Tcl command executed. Implicitly the name of the tab is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-command <I>string</I></B> </DT> <DD>Specifies a Tcl script to be associated with <I>nameOrIndex</I>. This command is typically invoked when left mouse button is released over the tab. Setting this option overrides the widget's <B>-selectcommand</B> option. </DD> <DT><B>-data <I>string</I></B> </DT> <DD>Specifies a string to be associated with <I>nameOrIndex</I>. This value isn't used in the widget code. It may be used in Tcl bindings to associate extra data (other than the image or text) with the tab. The default value is <I>""</I>. </DD> <DT><B>-fill <I>fill</I></B> </DT> <DD>If the space in the folder surrounding the tab's embedded widget is larger than the widget, then <I>fill</I> indicates if the embedded widget should be stretched to occupy the extra space. <I>Fill</I> is either <I>none</I>, <I>x</I>, <I>y</I>, <I>both</I>. For example, if <I>fill</I> is <I>x</I>, then the widget is stretched horizontally. If <I>fill</I> is <I>y</I>, the widget is stretched vertically. The default is <I>none</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Sets the font for the text in tab labels. If <I>fontName</I> is not the empty string, this overrides the tabset's <B>-font</B> option. The default value is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the color of the label for <I>nameOrIndex</I>. If <I>color</I> is not the empty string, this overrides the widget's <B>-tabforeground</B> option. The default value is <I>""</I>. </DD> <DT><B>-image <I>imageName</I></B> </DT> <DD>Specifies the image to be drawn in label for <I>nameOrIndex</I>. If <I>image</I> is <I>""</I>, no image will be drawn. Both text and images may be displayed at the same time in tab labels. The default value is <I>""</I>. </DD> <DT><B>-ipadx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right of the label. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the label is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default value is <I>0</I>. </DD> <DT><B>-ipady <I>pad</I></B> </DT> <DD>Sets the padding to the top and bottom of the label. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the label is padded by the first distance and the bottom by the second. If <I>pad</I> has just one distance, both the top and bottom sides are padded evenly. The default value is <I>0</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding around the left and right of the embedded widget, if one exists. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the widget is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default value is <I>0</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding around the top and bottom of the embedded widget, if one exists. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the widget is padded by the first distance and the bottom by the second. If <I>pad</I> has just one distance, both the top and bottom sides are padded evenly. The default value is <I>0</I>. </DD> <DT><B>-selectbackground <I>color</I></B> </DT> <DD>Sets the color to use when displaying background of the selected tab. If <I>color</I> is not the empty string, this overrides the widget's <B>-selectbackground</B> option. The default value is <I>""</I>. </DD> <DT><B>-shadow <I>color</I></B> </DT> <DD>Sets the shadow color for the text in the tab's label. Drop shadows are useful when both the foreground and background of the tab have similar color intensities. If <I>color</I> is the empty string, no shadow is drawn. The default value is <I>""</I>. </DD> <DT><B>-state <I>state</I></B> </DT> <DD>Sets the state of the tab. If <I>state</I> is <I>disable</I> the text of the tab is drawn as engraved and operations on the tab (such as <B>invoke</B> and <B>tab tearoff</B>) are ignored. The default is <I>normal</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern to use for the background of the folder when the window is torn off. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. The default is <I>BLT</I>. </DD> <DT><B>-text <I>text</I></B> </DT> <DD>Specifies the text of the tab's label. The exact way the text is drawn may be affected by other options such as <B>-state</B> or <B>-rotate</B>. </DD> <DT><B>-window <I>pathName</I></B> </DT> <DD>Specifies the widget to be embedded into the tab. <I>PathName</I> must be a child of the <B>tabset</B> widget. The tabset will "pack" and manage the size and placement of <I>pathName</I>. The default value is <I>""</I>. </DD> <DT><B>-windowheight <I>pixels</I></B> </DT> <DD>Sets the requested height of the page. The page is the area under the tab used to display the page contents. If <I>pixels</I> is <I>0</I>, the maximum height of all embedded tab windows is used. The default is <I>0</I>. </DD> <DT><B>-windowwidth <I>pixels</I></B> </DT> <DD>Sets the requested width of the page. The page is the area under the tab used to display the page contents. If <I>pixels</I> is <I>0</I>, the maximum width of all embedded tab windows is used. The default is <I>0</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>tab names</B></I> ?<I>pattern</I>? </DT> <DD>Returns the names of all the tabs matching the given pattern. If no <I>pattern</I> argument is provided, then all tab names are returned. </DD> <DT><I>pathName <B>tab tearoff <I>index</I></B></I> ?<I>newName</I>? </DT> <DD>Reparents the widget embedded into <I>index</I>, placing it inside of <I>newName</I>. <I>NewName</I> is either the name of an new widget that will contain the embedded widget or the name of the <B>tabset</B> widget. It the last case, the embedded widget is put back into the folder. <P> If no <I>newName</I> argument is provided, then the name of the current parent of the embedded widget is returned. </DD> </DL> <H2><A NAME="sect9" HREF="#toc9">Default Bindings</A></H2> <P> BLT automatically generates class bindings that supply tabsets their default behaviors. The following event sequences are set by default for tabsets (via the class bind tag <I>Tabset</I>): <DL> <DT><B>&lt;ButtonPress-2&gt;</B></DT> <DD></DD> <DT><B>&lt;B2-Motion&gt;</B></DT> <DD></DD> <DT><B>&lt;ButtonRelease-2&gt;</B></DT> <DD>Mouse button 2 may be used for scanning. If it is pressed and dragged over the tabset, the contents of the tabset drag at high speed in the direction the mouse moves. </DD> <DT><B>&lt;KeyPress-Up&gt;</B></DT> <DD></DD> <DT><B>&lt;KeyPress-Down&gt;</B></DT> <DD>The up and down arrow keys move the focus to the tab immediately above or below the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. </DD> <DT><B>&lt;KeyPress-Left&gt;</B></DT> <DD></DD> <DT><B>&lt;KeyPress-Right&gt;</B></DT> <DD>The left and right arrow keys move the focus to the tab immediately to the left or right of the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. </DD> <DT><B>&lt;KeyPress-space&gt;</B></DT> <DD></DD> <DT><B>&lt;KeyPress-Return&gt;</B></DT> <DD>The space and return keys select the current tab given focus. When a folder is selected, it's command is invoked and the embedded widget is mapped. </DD> </DL> <P> Each tab, by default, also has a set of bindings (via the tag <I>all</I>). These bindings may be reset using the tabset's <B>bind</B> operation. <DL> <DT><B>&lt;Enter&gt;</B></DT> <DD></DD> <DT><B>&lt;Leave&gt;</B></DT> <DD>When the mouse pointer enters a tab, it is activated (i.e. drawn in its active colors) and when the pointer leaves, it is redrawn in its normal colors. </DD> <DT><B>&lt;ButtonRelease-1&gt;</B></DT> <DD>Clicking with the left mouse button on a tab causes the tab to be selected and its Tcl script (see the <B>-command</B> or <B>-selectcommand</B> options) to be invoked. The folder and any embedded widget (if one is specified) is automatically mapped. </DD> <DT><B>&lt;ButtonRelease-3&gt;</B></DT> <DD></DD> <DT><B>&lt;Control-ButtonRelease-1&gt;</B></DT> <DD>Clicking on the right mouse button (or the left mouse button with the Control key held down) tears off the current page into its own toplevel widget. The embedded widget is re-packed into a new toplevel and an outline of the widget is drawn in the folder. Clicking again (toggling) will reverse this operation and replace the page back in the folder. </DD> </DL> <H2><A NAME="sect10" HREF="#toc10">Bind Tags</A></H2> You can bind commands to tabs that are triggered when a particular event sequence occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as <B>Enter</B>, <B>Leave</B>, <B>ButtonPress</B>, <B>Motion</B>, and <B>KeyPress</B>). <P> It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the tab name and another is associated with the tab's tags (see the <B>-bindtags</B> option). When this occurs, all the matching bindings are invoked. A binding associated with the tab name is invoked first, followed by one binding for each of the tab's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. <P> The <B>-bindtags</B> option for tabs controls addition tag names that can be matched. Implicitly the first tag for each tab is its name. Setting the value of the <B>-bindtags</B> option doesn't change this. <H2><A NAME="sect11" HREF="#toc11">Keywords</A></H2> tabset, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">Tabset Indices</A></LI> <LI><A NAME="toc7" HREF="#sect7">Tabset Operations</A></LI> <LI><A NAME="toc8" HREF="#sect8">Tab Operations</A></LI> <LI><A NAME="toc9" HREF="#sect9">Default Bindings</A></LI> <LI><A NAME="toc10" HREF="#sect10">Bind Tags</A></LI> <LI><A NAME="toc11" HREF="#sect11">Keywords</A></LI> </UL> </BODY></HTML> ������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/eps.html���������������������������������������������������������������������0000644�0001750�0001750�00000157724�11462120062�014677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>graph(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> eps - Encapsulated PostScript canvas item. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <I>canvas<B> create eps <I>x y </I></B></I>?<I>option value</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>eps</B> canvas item lets you place encapulated PostScript (EPS) on a canvas, controlling its size and placement. The EPS item is displayed either as a solid rectangle or a preview image. The preview image is designated in one of two ways: 1) the EPS file contains an ASCII hexidecimal preview, or 2) a Tk photo image. When the canvas generates PostScript output, the EPS will be inserted with the proper translation and scaling to match that of the EPS item. So can use the canvas widget as a page layout tool. <H2><A NAME="sect3" HREF="#toc3">Example</A></H2> Let's say you have for PostScript files of four graphs which you want to tile two-by-two on a single page. Maybe you'd like to annotate the graphs by putting a caption at the bottom of each graph. <P> Normally, you would have to resort to an external tool or write your own PostScript program. The <B>eps</B> canvas item lets you do this through Tk's canvas widget. An <B>eps</B> item displays an image (or rectangle) representing the encapsulated PostScript file. It also scales and translates the EPS file when the canvas is printed. <P> <H2><A NAME="sect4" HREF="#toc4">Syntax</A></H2> <BR> <P> <CODE><I>canvas <B>create eps <I>x y </I></B></I>?<I>option value</I>?...<BR> </CODE><P>The <B>eps</B> item creates a new canvas item. <I>Canvas</I> is the name of a <B>canvas</B> widget. You must supply the X-Y coordinate of the new eps item. How the coordinate is exactly interpretered is controlled by the <B>-anchor</B> option (see below). <P> Additional options may be specified on the command line to configure aspects of the eps item such as its color, stipple, and font. The following <I>option</I> and <I>value</I> pairs are valid. <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Tells how to position the EPS item relative to its X-Y coordinate. The default is <I>center</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the EPS rectangle. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the item. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>0</I>. </DD> <DT><B>-file <I>fileName</I></B> </DT> <DD>Specifies the name of the EPS file. The first line of an EPS file must start with "%!PS" and contain a "EPS" version specification. The other requirement is that there be a "%%BoundingBox:" entry which contains four integers representing the lower-left and upper-right coordinates of the area bounding the EPS. The default is <I>""</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the title. The default is <I>*-Helvetica-Bold-R-Normal-*-18-180-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Specifies the foreground color of the EPS rectangle. The option matters only when the <B>-stipple</B> option is set. The default is <I>white</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the height EPS item. If <I>pixels</I> is <I>0</I>, then the height is determined from the PostScript "BoundingBox:" entry in the EPS file. The default is <I>0</I>. </DD> <DT><B>-image <I>photo</I></B> </DT> <DD>Specifies the name of a Tk photo image to be displayed as in the item as a preview image. This option overrides any preview specification found in the EPS file. The default is <I>""</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the title should be justified. This matters only when the title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the EPS item. <I>Relief</I> specifies how the item should appear relative to canvas; for example, <I>raised</I> means the item should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-shadowcolor <I>color</I></B> </DT> <DD>Specifies the color of the drop shadow used for the title. The option with the <B>-shadowoffset</B> option control how the title's drop shadow appears. The default is <I>grey</I>. </DD> <DT><B>-shadowoffset <I>pixels</I></B> </DT> <DD>Specifies the offset of the drop shadow from the title's text. If <I>pixels</I> is <I>0</I>, no shadow will be seen. The default is <I>0</I>. </DD> <DT><B>-showimage <I>boolean</I></B> </DT> <DD>Indicates whether to display the image preview (if one exists), or a simple rectangle. The default is <I>yes</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a bitmap to used to stipple the rectangle representing the EPS item. The default is <I>""</I>. </DD> <DT><B>-title <I>string</I></B> </DT> <DD>Sets the title of the EPS item. If <I>string</I> is <I>""</I>, then the title specified by the PostScript "Title:" entry is used. You can set the string a single space to display no title. The default is <I>""</I>. </DD> <DT><B>-titleanchor <I>anchor</I></B> </DT> <DD>Tells how to position the title within EPS item. The default is <I>n</I>. </DD> <DT><B>-titlecolor <I>color</I></B> </DT> <DD>Specifies the color of the title. The default is <I>white</I>. </DD> <DT><B>-titlerotate <I>degrees</I></B> </DT> <DD>Sets the rotation of the title. <I>Degrees</I> is a real number representing the angle of rotation. The title is first rotated in space and then placed according to the <B>-titleanchor</B> position. The default rotation is <I>0.0</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the width EPS item. If <I>pixels</I> is <I>0</I>, then the width is determined from the PostScript "BoundingBox:" entry in the EPS file. The default is <I>0</I>. <I>5i</I>. </DD> </DL> <H2><A NAME="sect5" HREF="#toc5">Example</A></H2> The <B>graph</B> command creates a new graph. <BR> <CODE># Create a new graph. Plotting area is black.<BR> graph .g -plotbackground black<BR> </CODE><P>A new Tcl command <I>.g</I> is also created. This command can be used to query and modify the graph. For example, to change the title of the graph to "My Plot", you use the new command and the graph's <B>configure</B> operation. <BR> <CODE># Change the title.<BR> .g configure -title "My Plot"<BR> </CODE><P>A graph has several components. To access a particular component you use the component's name. For example, to add data elements, you use the new command and the <B>element</B> component. <BR> <CODE># Create a new element named "line1"<BR> .g element create line1 \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;155.85 166.60 175.38 }<BR> </CODE><P>The element's X and Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X-Y coordinates. <BR> <CODE># Create two vectors and add them to the graph.<BR> vector xVec yVec<BR> xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }<BR> yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;166.60 175.38 }<BR> .g element create line1 -xdata xVec -ydata yVec<BR> </CODE><P>The advantage of using vectors is that when you modify one, the graph is automatically redrawn to display the new values. <BR> <CODE># Change the X-Y coordinates of the first point.<BR> set xVec(0) 0.18<BR> set yVec(0) 25.18<BR> </CODE><P>An element named <I>line1</I> is now created in <I>.g</I>. By default, the element's label in the legend will be also <I>line1</I>. You can change the label, or specify no legend entry, again using the element's <B>configure</B> operation. <BR> <CODE># Don't display "line1" in the legend.<BR> .g element configure line1 -label ""<BR> </CODE><P>You can configure more than just the element's label. An element has many attributes such as symbol type and size, dashed or solid lines, colors, line width, etc. <BR> <CODE>.g element configure line1 -symbol square -color red \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-dashes { 2 4 2 } -linewidth 2 -pixels 2c<BR> </CODE><P>Four coordinate axes are automatically created: <I>x</I>, <I>x2</I>, <I>y</I>, and <I>y2</I>. And by default, elements are mapped onto the axes <I>x</I> and <I>y</I>. This can be changed with the <B>-mapx</B> and <B>-mapy</B> options. <BR> <CODE># Map "line1" on the alternate Y-axis "y2".<BR> .g element configure line1 -mapy y2<BR> </CODE><P>Axes can be configured in many ways too. For example, you change the scale of the Y-axis from linear to log using the <B>axis</B> component. <BR> <CODE># Y-axis is log scale.<BR> .g axis configure y -logscale yes<BR> </CODE><P>One important way axes are used is to zoom in on a particular data region. Zooming is done by simply specifying new axis limits using the <B>-min</B> and <B>-max</B> configuration options. <BR> <CODE>.g axis configure x -min 1.0 -max 1.5<BR> .g axis configure y -min 12.0 -max 55.15<BR> </CODE><P>To zoom interactively, you link the axis <B>configure</B> operations with some user interaction (such as pressing the mouse button), using the <B>bind</B> command. To convert between screen and graph coordinates, use the <B>invtransform</B> operation. <BR> <CODE># Click the button to set a new minimum <BR> bind .g &lt;ButtonPress-1&gt; { <BR> %W axis configure x -min [%W axis invtransform x %x]<BR> %W axis configure x -min [%W axis invtransform x %y]<BR> }<BR> </CODE><P>By default, the limits of the axis are determined from data values. To reset back to the default limits, set the <B>-min</B> and <B>-max</B> options to the empty value. <BR> <CODE># Reset the axes to autoscale again.<BR> .g axis configure x -min {} -max {}<BR> .g axis configure y -min {} -max {}<BR> </CODE><P>By default, the legend is drawn in the right margin. You can change this or any legend configuration options using the <B>legend</B> component. <BR> <CODE># Configure the legend font, color, and relief<BR> .g legend configure -position left -relief raised \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-font fixed -fg blue<BR> </CODE><P>To prevent the legend from being displayed, turn on the <B>-hide</B> option. <BR> <CODE># Don't display the legend.<BR> .g legend configure -hide yes<BR> </CODE><P>The <B>graph</B> widget has simple drawing procedures called markers. They can be used to highlight or annotate data in the graph. The types of markers available are bitmaps, images, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. In this example, is a text marker that labels the data first point. Markers are created using the <B>marker</B> component. <BR> <CODE># Create a label for the first data point of "line1".<BR> .g marker create text -name first_marker -coords { 0.2 26.18 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-text "start" -anchor se -xoffset -10 -yoffset -10<BR> </CODE><P>This creates a text marker named <I>first_marker</I>. It will display the text "start" near the coordinates of the first data point. The <B>-anchor</B>, <B>-xoffset</B>, and <B>-yoffset</B> options are used to display the marker above and to the left of the data point, so that the data point isn't covered by the marker. By default, markers are drawn last, on top of data. You can change this with the <B>-under</B> option. <BR> <CODE># Draw the label before elements are drawn.<BR> .g marker configure first_marker -under yes<BR> </CODE><P>You can add cross hairs or grid lines using the <B>crosshairs</B> and <B>grid</B> components. <BR> <CODE># Display both cross hairs and grid lines.<BR> .g crosshairs configure -hide no -color red<BR> .g grid configure -hide no -dashes { 2 2 }<BR> </CODE><P>Finally, to get hardcopy of the graph, use the <B>postscript</B> component. <BR> <CODE># Print the graph into file "file.ps"<BR> .g postscript output file.ps -maxpect yes -decorations no<BR> </CODE><P>This generates a file <I>file.ps</I> containing the encapsulated PostScript of the graph. The option <B>-maxpect</B> says to scale the plot to the size of the page. Turning off the <B>-decorations</B> option denotes that no borders or color backgrounds should be drawn (i.e. the background of the margins, legend, and plotting area will be white). <H2><A NAME="sect6" HREF="#toc6">Graph Operations</A></H2> <DL> <DT><I>pathName <B>axis <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>bar <I>elemName </I></B></I>?<I>option value</I>?... </DT> <DD>Creates a new barchart element <I>elemName</I>. It's an error if an element <I>elemName</I> already exists. See the manual for <B>barchart</B> for details about what <I>option</I> and <I>value</I> pairs are valid. </DD> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the <B>configure</B> operation. </DD> <DT><I>pathName <B>configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the graph. If <I>option</I> isn't specified, a list describing the current options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the option <I>option</I> is set to <I>value</I>. The following options are valid. <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color. This includes the margins and legend, but not the plotting area. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-bottommargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin below the X-coordinate axis. If <I>pixels</I> is <I>0</I>, the size of the margin is selected automatically. The default is <I>0</I>. </DD> <DT><B>-bufferelements <I>boolean</I></B> </DT> <DD>Indicates whether an internal pixmap to buffer the display of data elements should be used. If <I>boolean</I> is true, data elements are drawn to an internal pixmap. This option is especially useful when the graph is redrawn frequently while the remains data unchanged (for example, moving a marker across the plot). See the <FONT SIZE=-1><B>SPEED TIPS</B></FONT> section. The default is <I>1</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>crosshair</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the graph title. The default is <I>*-Helvetica-Bold-R-Normal-*-18-180-*</I>. </DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a maximum distance to consider when searching for the closest data point (see the element's <B>closest</B> operation below). Data points further than <I>pixels</I> away are ignored. The default is <I>0.5i</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>4i</I>. </DD> <DT><B>-invertxy <I>boolean</I></B> </DT> <DD>Indicates whether the placement X-axis and Y-axis should be inverted. If <I>boolean</I> is true, the X and Y axes are swapped. The default is <I>0</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the title should be justified. This matters only when the title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-leftmargin <I>pixels</I></B> </DT> <DD>Sets the size of the margin from the left edge of the window to the Y-coordinate axis. If <I>pixels</I> is <I>0</I>, the size is calculated automatically. The default is <I>0</I>. </DD> <DT><B>-plotbackground <I>color</I></B> </DT> <DD>Specifies the background color of the plotting area. The default is <I>white</I>. </DD> <DT><B>-plotborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the plotting area. The <B>-plotrelief</B> option determines if a border is drawn. The default is <I>2</I>. </DD> <DT><B>-plotpadx <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the left and right sides of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotpady <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the top and bottom of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the plotting area. <I>Relief</I> specifies how the interior of the plotting area should appear relative to rest of the graph; for example, <I>raised</I> means the plot should appear to protrude from the graph, relative to the surface of the graph. The default is <I>sunken</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the graph widget. <I>Relief</I> specifies how the graph should appear relative to widget it is packed into; for example, <I>raised</I> means the graph should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-rightmargin <I>pixels</I></B> </DT> <DD>Sets the size of margin from the plotting area to the right edge of the window. By default, the legend is drawn in this margin. If <I>pixels</I> is than 1, the margin size is selected automatically. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>""</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a tiled background for the widget. If <I>image</I> isn't <I>""</I>, the background is tiled using <I>image</I>. Otherwise, the normal background color is drawn (see the <B>-background</B> option). <I>Image</I> must be an image created using the Tk <B>image</B> command. The default is <I>""</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title to <I>text</I>. If <I>text</I> is <I>""</I>, no title will be displayed. </DD> <DT><B>-topmargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin above the x2 axis. If <I>pixels</I> is <I>0</I>, the margin size is calculated automatically. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. The default is <I>5i</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>crosshairs <I>operation </I></B></I>?<I>arg</I>? </DT> <DD>See the <FONT SIZE=-1><B>CROSSHAIRS COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>element <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>ELEMENT COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>extents <I>item</I></B></I> </DT> <DD>Reports the size of a particular items in the graph. <I>Item</I> must be either <I>leftmargin</I>, <I>rightmargin</I>, <I>topmargin</I>, <I>bottommargin</I>, <I>plotwidth</I>, or <I>plotheight</I>. </DD> <DT><I>pathName <B>grid <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>GRID COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>invtransform <I>winX winY</I></B></I> </DT> <DD>Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X-axis and Y-axis. Returns a list of containing the X-Y y graph coordinates. </DD> <DT><I>pathName <B>inside <I>x y</I></B></I> </DT> <DD>Returns <I>1</I> is the designated screen coordinate (<I>x</I> and <I>y</I>) is inside the plotting area and <I>0</I> otherwise. </DD> <DT><I>pathName <B>legend <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>LEGEND COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>line<B> operation arg</B></B></I>... </DT> <DD>The operation is the same as <B>element</B>. </DD> <DT><I>pathName <B>marker <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>MARKER COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>postscript <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>POSTSCRIPT COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>snap <I>photoName</I></B></I> </DT> <DD>Takes a snapshot of the graph and stores the contents in the photo image <I>photoName</I>. <I>PhotoName</I> is the name of a Tk photo image that must already exist. </DD> <DT><I>pathName <B>transform <I>x y</I></B></I> </DT> <DD>Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X-axis and Y-axis. Returns a list containing the X-Y screen coordinates. </DD> <DT><I>pathName <B>xaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>x2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>yaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>y2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> </DL> <H2><A NAME="sect7" HREF="#toc7">Graph Components</A></H2> A graph is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the graph is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the graph. <H3><A NAME="sect8" HREF="#toc8">Axis Components</A></H3> Four coordinate axes are automatically created: two X-coordinate axes (<I>x</I> and <I>x2</I>) and two Y-coordinate axes (<I>y</I>, and <I>y2</I>). By default, the axis <I>x</I> is located in the bottom margin, <I>y</I> in the left margin, <I>x2</I> in the top margin, and <I>y2</I> in the right margin. <P> An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. <P> The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. <P> You can create and use several axes. To create an axis, invoke the axis component and its create operation. <BR> <CODE># Create a new axis called "tempAxis"<BR> .g axis create tempAxis<BR> </CODE><P>You map data elements to an axis using the element's -mapy and -mapx configuration options. They specify the coordinate axes an element is mapped onto. <BR> <CODE># Now map the tempAxis data to this axis.<BR> .g element create "e1" -xdata $x -ydata $y -mapy tempAxis<BR> </CODE><P>While you can create many axes, only four can be displayed simultaneously. They are drawn in each of the margins surrounding the plotting area. The axes <I>x</I> and <I>y</I> are drawn in the bottom and left margins. The axes <I>x2</I> and <I>y2</I> are drawn in top and right margins. Only <I>x</I> and <I>y</I> are shown by default. Note that the axes can have different scales. <P> To display a different axis, you invoke one of the following components: <B>xaxis</B>, <B>yaxis</B>, <B>x2axis</B>, and <B>y2axis</B>. The <B>use</B> operation designates the axis to be drawn in the corresponding margin: <B>xaxis</B> in the bottom, <B>yaxis</B> in the left, <B>x2axis</B> in the top, and <B>y2axis</B> in the right. <BR> <CODE># Display the axis tempAxis in the left margin.<BR> .g yaxis use tempAxis<BR> <P> </CODE><P>You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label any way you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. <P> <DL> <DT><I>pathName <B>axis <B>cget <I>axisName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>axisName</I>. <I>Option</I> may be any option described below for the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>configure <I>axisName </I></B></B></I>?<I>axisName</I>?... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>axisName</I>. Several axes can be changed. If <I>option</I> isn't specified, a list describing all the current options for <I>axisName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the axis option <I>option</I> is set to <I>value</I>. The following options are valid for axes. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the axis and tick labels. The default is <I>black</I>. </DD> <DT><B>-command <I>prefix</I></B> </DT> <DD>Specifies a Tcl command to be invoked when formatting the axis tick labels. <I>Prefix</I> is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If <I>""</I> is returned, no label will appear next to the tick. You can get the standard tick labels again by setting <I>prefix</I> to <I>""</I>. The default is <I>""</I>. <P> Please note that this procedure is invoked while the graph is redrawn. You may query configuration options. But do not them, because this can have unexpected results. </DD> <DT><B>-descending <I>boolean</I></B> </DT> <DD>Indicates whether the values along the axis are monotonically increasing or decreasing. If <I>boolean</I> is true, the axis values will be decreasing. The default is <I>0</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the axis is displayed. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-limits <I>formatStr</I></B> </DT> <DD>Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. <I>FormatStr</I> is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If <I>""</I> is given as either description, then the that limit will not be displayed. The default is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the axis and tick lines. The default is <I>1</I> pixel. </DD> <DT><B>-logscale <I>boolean</I></B> </DT> <DD>Indicates whether the scale of the axis is logarithmic or linear. If <I>boolean</I> is true, the axis is logarithmic. The default scale is linear. </DD> <DT><B>-loose <I>boolean</I></B> </DT> <DD>Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. This is relevant only when the axis limit is automatically calculated. If <I>boolean</I> is true, the axis range is "loose". The default is <I>0</I>. </DD> <DT><B>-majorticks <I>majorList</I></B> </DT> <DD>Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. <I>MajorList</I> is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If <I>majorList</I> is <I>""</I>, major ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-max <I>value</I></B> </DT> <DD>Sets the maximum limit of <I>axisName</I>. Any data point greater than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the maximum limit is calculated using the largest data value. The default is <I>""</I>. </DD> <DT><B>-min <I>value</I></B> </DT> <DD>Sets the minimum limit of <I>axisName</I>. Any data point less than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the minimum limit is calculated using the smallest data value. The default is <I>""</I>. </DD> <DT><B>-minorticks <I>minorList</I></B> </DT> <DD>Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. <I>MinorList</I> is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the <B>-majortick</B> option is also set. If <I>minorList</I> is <I>""</I>, minor ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the how many degrees to rotate the axis tick labels. <I>Theta</I> is a real value representing the number of degrees to rotate the tick labels. The default is <I>0.0</I> degrees. </DD> <DT><B>-showticks <I>boolean</I></B> </DT> <DD>Indicates whether axis ticks should be drawn. If <I>boolean</I> is true, ticks are drawn. If false, only the axis line is drawn. The default is <I>1</I>. </DD> <DT><B>-stepsize <I>value</I></B> </DT> <DD>Specifies the interval between major axis ticks. If <I>value</I> isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. </DD> <DT><B>-subdivisions <I>number</I></B> </DT> <DD>Indicates how many minor axis ticks are to be drawn. For example, if <I>number</I> is two, only one minor tick is drawn. If <I>number</I> is one, no minor ticks are displayed. The default is <I>2</I>. </DD> <DT><B>-tickfont <I>fontName</I></B> </DT> <DD>Specifies the font for axis tick labels. The default is <I>*-Courier-Bold-R-Normal-*-100-*</I>. </DD> <DT><B>-ticklength <I>pixels</I></B> </DT> <DD>Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If <I>pixels</I> is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is <I>0.1i</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title of the axis. If <I>text</I> is <I>""</I>, no axis title will be displayed. </DD> <DT><B>-titlecolor <I>color</I></B> </DT> <DD>Sets the color of the axis title. The default is <I>black</I>. </DD> <DT><B>-titlefont <I>fontName</I></B> </DT> <DD>Specifies the font for axis title. The default is <I>*-Helvetica-Bold-R-Normal-*-14-140-*</I>. </DD> </DL> <P> Axis configuration options may be also be set by the <B>option</B> command. The resource class is <I>Axis</I>. The resource names are the names of the axes (such as <I>x</I> or <I>x2</I>). <BR> <CODE>option add *Graph.Axis.Color blue<BR> option add *Graph.x.LogScale true<BR> option add *Graph.x2.LogScale false<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>axis <B>create <I>axisName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new axis by the name <I>axisName</I>. No axis by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>delete </B></B></I>?<I>axisName</I>?... </DT> <DD>Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. </DD> <DT><I>pathName <B>axis invtransform <I>axisName value</I></B></I> </DT> <DD>Performs the inverse transformation, changing the screen coordinate <I>value</I> to a graph coordinate, mapping the value mapped to <I>axisName</I>. Returns the graph coordinate. </DD> <DT><I>pathName <B>axis limits <I>axisName</I></B></I> </DT> <DD>Returns a list of the minimum and maximum limits for <I>axisName</I>. The order of the list is <I>min max</I>. </DD> <DT><I>pathName <B>axis names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of axes matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all axes are returned. </DD> <DT><I>pathName <B>axis transform <I>axisName value</I></B></I> </DT> <DD>Transforms the coordinate <I>value</I> to a screen coordinate by mapping the it to <I>axisName</I>. Returns the transformed screen coordinate. </DD> </DL> <P> Only four axes can be displayed simultaneously. By default, they are <I>x</I>, <I>y</I>, <I>x2</I>, and <I>y2</I>. You can swap in a different axis with <B>use</B> operation of the special axis components: <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B>. <BR> <CODE>.g create axis temp<BR> .g create axis time<BR> ...<BR> .g xaxis use temp<BR> .g yaxis use time<BR> </CODE><P>Only the axes specified for use are displayed on the screen. <P> The <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B> components operate on an axis location rather than a specific axis like the more general <B>axis</B> component does. The <B>xaxis</B> component manages the X-axis located in the bottom margin (whatever axis that happens to be). Likewise, <B>yaxis</B> uses the Y-axis in the left margin, <B>x2axis</B> the top X-axis, and <B>y2axis</B> the right Y-axis. <P> They implicitly control the axis that is currently using to that location. By default, <B>xaxis</B> uses the <I>x</I> axis, <B>yaxis</B> uses <I>y</I>, <B>x2axis</B> uses <I>x2</I>, and <B>y2axis</B> uses <I>y2</I>. These components can be more convenient to use than always determining what axes are current being displayed by the graph. <P> The following operations are available for axes. They mirror exactly the operations of the <B>axis</B> component. The <I>axis</I> argument must be <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, or <B>y2axis</B>. <DL> <DT><I>pathName <I>axis <B>cget <I>option</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>configure </B></I></I>?<I>option value</I>?... </DT> <DD></DD> <DT><I>pathName <I>axis<B> invtransform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>limits</B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> transform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> use </B></I></I>?<I>axisName</I>? </DT> <DD>Designates the axis <I>axisName</I> is to be displayed at this location. <I>AxisName</I> can not be already in use at another location. This command returns the name of the axis currently using this location. </DD> </DL> <H3><A NAME="sect9" HREF="#toc9">Crosshairs Component</A></H3> Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire graph. <P> The following operations are available for cross hairs: <DL> <DT><I>pathName <B>crosshairs cget <I>option</I></B></I> </DT> <DD>Returns the current value of the cross hairs configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the cross hairs <B>configure</B> operation. </DD> <DT><I>pathName <B>crosshairs configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the cross hairs. If <I>option</I> isn't specified, a list describing all the current options for the cross hairs is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the cross hairs option <I>option</I> is set to <I>value</I>. The following options are available for cross hairs. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the cross hairs. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the cross hairs. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the cross hairs will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether cross hairs are drawn. If <I>boolean</I> is true, cross hairs are not drawn. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the cross hair lines. The default is <I>1</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies the screen position where the cross hairs intersect. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates of the intersection. </DD> </DL> <P> Cross hairs configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>crosshairs</I> and <I>Crosshairs</I> respectively. <BR> <CODE>option add *Graph.Crosshairs.LineWidth 2<BR> option add *Graph.Crosshairs.Color red<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>crosshairs off</B></I> </DT> <DD>Turns off the cross hairs. </DD> <DT><I>pathName <B>crosshairs on</B></I> </DT> <DD>Turns on the display of the cross hairs. </DD> <DT><I>pathName <B>crosshairs toggle</B></I> </DT> <DD>Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. </DD> </DL> <H3><A NAME="sect10" HREF="#toc10">Element Components</A></H3> A data element represents a set of data. It contains x and y vectors containing the coordinates of the data points. Elements can be displayed with a symbol at each data point and lines connecting the points. Elements also control the appearance of the data, such as the symbol type, line width, color etc. <P> When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. <P> The following operations are available for elements. <DL> <DT><I>pathName <B>element activate <I>elemName </I></B></I>?<I>index</I>?... </DT> <DD>Specifies the data points of element <I>elemName</I> to be drawn using active foreground and background colors. <I>ElemName</I> is the name of the element and <I>index</I> is a number representing the index of the data point. If no indices are present then all data points become active. </DD> <DT><I>pathName <B>element cget <I>elemName <I>option</I></I></B></I> </DT> <DD>Returns the current value of the element configuration option given by <I>option</I>. <I>Option</I> may be any of the options described below for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element closest <I>x y</I></B></I> <I>varName</I> ?<I>option value</I>?... ?<I>elemName</I>?... </DT> <DD>Finds the data point closest to the window coordinates <I>x</I> and <I>y</I> in the element <I>elemName</I>. <I>ElemName</I> is the name of an element, that must not be hidden. If no elements are specified, then all visible elements are searched. It returns via the array variable <I>varName</I> the name of the closest element, the index of its closest point, and the graph coordinates of the point. Returns <I>0</I>, if no data point within the threshold distance can be found, otherwise <I>1</I> is returned. The following <I>option</I>-<I>value</I> pairs are available. <blockquote></DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a threshold distance where selected data points are ignored. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. If this option isn't specified, then it defaults to the value of the graph's <B>-halo</B> option. </DD> <DT><B>-interpolate <I>boolean</I></B> </DT> <DD>Indicates that both the data points and interpolated points along the line segment formed should be considered. If <I>boolean</I> is true, the closest line segment will be selected instead of the closest point. If this option isn't specified, <I>boolean</I> defaults to <I>0</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>element configure <I>elemName </I></B></I>?<I>elemName</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for elements. Several elements can be modified at the same time. If <I>option</I> isn't specified, a list describing all the current options for <I>elemName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing the option <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the element option <I>option</I> is set to <I>value</I>. The following options are valid for elements. <blockquote></DD> <DT><B>-activepen <I>penName</I></B> </DT> <DD>Specifies pen to use to draw active element. If <I>penName</I> is <I>""</I>, no active elements will be drawn. The default is <I>activeLine</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the traces connecting the data points. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of element line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the lines will be solid. </DD> <DT><B>-data <I>coordList</I></B> </DT> <DD>Specifies the X-Y coordinates of the data. <I>CoordList</I> is a list of numeric expressions representing the X-Y coordinate pairs of each data point. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the interior color of symbols. If <I>color</I> is <I>""</I>, then the interior of the symbol is transparent. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the element is displayed. The default is <I>no</I>. </DD> <DT><B>-label <I>text</I></B> </DT> <DD>Sets the element's label in the legend. If <I>text</I> is <I>""</I>, the element will have no entry in the legend. The default label is the element's name. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the connecting lines between data points. If <I>pixels</I> is <I>0</I>, no connecting lines will be drawn between symbols. The default is <I>0</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Selects the X-axis to map the element's X-coordinates onto. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Selects the Y-axis to map the element's Y-coordinates onto. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-offdash <I>color</I></B> </DT> <DD>Sets the color of the stripes when traces are dashed (see the <B>-dashes</B> option). If <I>color</I> is <I>""</I>, then the "off" pixels will represent gaps instead of stripes. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color or the outline around each symbol. If <I>color</I> is <I>""</I>, then no outline is drawn. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outlinewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline bordering each symbol. If <I>pixels</I> is <I>0</I>, no outline will be drawn. The default is <I>1</I>. </DD> <DT><B>-pixels <I>pixels</I></B> </DT> <DD>Sets the size of symbols. If <I>pixels</I> is <I>0</I>, no symbols will be drawn. The default is <I>0.125i</I>. </DD> <DT><B>-scalesymbols <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the size of the symbols drawn for <I>elemName</I> will change with scale of the X-axis and Y-axis. At the time this option is set, the current ranges of the axes are saved as the normalized scales (i.e scale factor is 1.0) and the element is drawn at its designated size (see the <B>-pixels</B> option). As the scale of the axes change, the symbol will be scaled according to the smaller of the X-axis and Y-axis scales. If <I>boolean</I> is false, the element's symbols are drawn at the designated size, regardless of axis scales. The default is <I>0</I>. </DD> <DT><B>-smooth <I>smooth</I></B> </DT> <DD>Specifies how connecting line segments are drawn between data points. <I>Smooth</I> can be either <I>linear</I>, <I>step</I>, <I>natural</I>, or <I>quadratic</I>. If <I>smooth</I> is <I>linear</I>, a single line segment is drawn, connecting both data points. When <I>smooth</I> is <I>step</I>, two line segments are drawn. The first is a horizontal line segment that steps the next X-coordinate. The second is a vertical line, moving to the next Y-coordinate. Both <I>natural</I> and <I>quadratic</I> generate multiple segments between data points. If <I>natural</I>, the segments are generated using a cubic spline. If <I>quadratic</I>, a quadratic spline is used. The default is <I>linear</I>. </DD> <DT><B>-styles <I>styleList</I></B> </DT> <DD>Specifies what pen to use based on the range of weights given. <I>StyleList</I> is a list of style specifications. Each style specification, in turn, is a list consisting of a pen name, and optionally a minimum and maximum range. Data points whose weight (see the <B>-weight</B> option) falls in this range, are drawn with this pen. If no range is specified it defaults to the index of the pen in the list. Note that this affects only symbol attributes. Line attributes, such as line width, dashes, etc. are ignored. </DD> <DT><B>-symbol <I>symbol</I></B> </DT> <DD>Specifies the symbol for data points. <I>Symbol</I> can be either <I>square</I>, <I>circle</I>, <I>diamond</I>, <I>plus</I>, <I>cross</I>, <I>splus</I>, <I>scross</I>, <I>triangle</I>, <I>""</I> (where no symbol is drawn), or a bitmap. Bitmaps are specified as "<I>source</I> ?<I>mask</I>?", where <I>source</I> is the name of the bitmap, and <I>mask</I> is the bitmap's optional mask. The default is <I>circle</I>. </DD> <DT><B>-trace <I>direction</I></B> </DT> <DD>Indicates whether connecting lines between data points (whose X-coordinate values are either increasing or decreasing) are drawn. <I>Direction</I> must be <I>increasing</I>, <I>decreasing</I>, or <I>both</I>. For example, if <I>direction</I> is <I>increasing</I>, connecting lines will be drawn only between those data points where X-coordinate values are monotonically increasing. If <I>direction</I> is <I>both</I>, connecting lines will be draw between all data points. The default is <I>both</I>. </DD> <DT><B>-weights <I>wVec</I></B> </DT> <DD>Specifies the weights of the individual data points. This, with the list pen styles (see the <B>-styles</B> option), controls how data points are drawn. <I>WVec</I> is the name of a BLT vector or a list of numeric expressions representing the weights for each data point. </DD> <DT><B>-xdata <I>xVec</I></B> </DT> <DD>Specifies the X-coordinates of the data. <I>XVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> <DT><B>-ydata <I>yVec</I></B> </DT> <DD>Specifies the Y-coordinates of the data. <I>YVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> </DL> <P> Element configuration options may also be set by the <B>option</B> command. The resource class is <I>Element</I>. The resource name is the name of the element. <BR> <CODE>option add *Graph.Element.symbol line<BR> option add *Graph.e1.symbol line<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>element create <I>elemName</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a new element <I>elemName</I>. It's an error is an element <I>elemName</I> already exists. If additional arguments are present, they specify options valid for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element deactivate <I>elemName</I></B></I> ?<I>elemName</I>?... </DT> <DD>Deactivates all the elements matching <I>pattern</I>. Elements whose names match any of the patterns given are redrawn using their normal colors. </DD> <DT><I>pathName <B>element delete</B></I> ?<I>elemName</I>?... </DT> <DD>Deletes all the named elements. The graph is automatically redrawn. </DD> <DT><I>pathName <B>element exists <I>elemName</I></B></I> </DT> <DD>Returns <I>1</I> if an element <I>elemName</I> currently exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>element names </B></I>?<I>pattern</I>?... </DT> <DD>Returns the elements matching one or more pattern. If no <I>pattern</I> is given, the names of all elements is returned. </DD> <DT><I>pathName <B>element show</B></I> ?<I>nameList</I>? </DT> <DD>Queries or modifies the element display list. The element display list designates the elements drawn and in what order. <I>NameList</I> is a list of elements to be displayed in the order they are named. If there is no <I>nameList</I> argument, the current display list is returned. </DD> <DT><I>pathName <B>element type</B></I> <I>elemName</I> </DT> <DD>Returns the type of <I>elemName</I>. If the element is a bar element, the commands returns the string <I>"bar"</I>, otherwise it returns <I>"line"</I>. </DD> </DL> <H3><A NAME="sect11" HREF="#toc11"></CODE><P>Grid Component</A></H3> Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. <DL> <DT><I>pathName <B>grid cget <I>option</I></B></I> </DT> <DD>Returns the current value of the grid line configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the grid <B>configure</B> operation. </DD> <DT><I>pathName <B>grid configure</B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for grid lines. If <I>option</I> isn't specified, a list describing all the current grid options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the grid line option <I>option</I> is set to <I>value</I>. The following options are valid for grid lines. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the grid lines. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the grid lines. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the grid will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the grid should be drawn. If <I>boolean</I> is true, grid lines are not shown. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of grid lines. The default width is <I>1</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to display grid lines. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to display grid lines. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-minor <I>boolean</I></B> </DT> <DD>Indicates whether the grid lines should be drawn for minor ticks. If <I>boolean</I> is true, the lines will appear at minor tick intervals. The default is <I>1</I>. </DD> </DL> <P> </blockquote> <H2><A NAME="sect12" HREF="#toc12">Speed Tips</A></H2> There may be cases where the graph needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. <UL> &#183;<LI>Try to minimize the number of data points. The more data points the looked at, the more work the graph must do. </LI>&#183;<LI>If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. </LI>&#183;<LI>Data elements without symbols are drawn faster than with symbols. Set the data element's <B>-symbol</B> option to <I>none</I>. If you need to draw symbols, try using the simple symbols such as <I>splus</I> and <I>scross</I>. </LI>&#183;<LI>Don't stipple or dash the element. Solid lines are much faster. </LI>&#183;<LI>If you update data elements frequently, try turning off the widget's <B>-bufferelements</B> option. When the graph is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the graph needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the graph. But if the graph is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. </LI> </UL> <H2><A NAME="sect13" HREF="#toc13">Limitations</A></H2> Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. <P> The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. <H2><A NAME="sect14" HREF="#toc14">Future Incompatibility</A></H2> The <B>-mapped</B> options are obsoleted and will be removed. You can achieve the same results using the <B>-hide</B> option instead. <BR> <CODE># Works for now.<BR> .g legend configure -mapped no<BR> <P> # Instead use this.<BR> .g legend configure -hide yes <BR> <H2><A NAME="sect15" HREF="#toc15"></CODE><P>Keywords</A></H2> graph, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Example</A></LI> <LI><A NAME="toc4" HREF="#sect4">Syntax</A></LI> <LI><A NAME="toc5" HREF="#sect5">Example</A></LI> <LI><A NAME="toc6" HREF="#sect6">Graph Operations</A></LI> <LI><A NAME="toc7" HREF="#sect7">Graph Components</A></LI> <UL> <LI><A NAME="toc8" HREF="#sect8">Axis Components</A></LI> <LI><A NAME="toc9" HREF="#sect9">Crosshairs Component</A></LI> <LI><A NAME="toc10" HREF="#sect10">Element Components</A></LI> <LI><A NAME="toc11" HREF="#sect11">Grid Component</A></LI> </UL> <LI><A NAME="toc12" HREF="#sect12">Speed Tips</A></LI> <LI><A NAME="toc13" HREF="#sect13">Limitations</A></LI> <LI><A NAME="toc14" HREF="#sect14">Future Incompatibility</A></LI> <LI><A NAME="toc15" HREF="#sect15">Keywords</A></LI> </UL> </BODY></HTML> ��������������������������������������������./saods9/blt3.0.1/html/bgexec.html������������������������������������������������������������������0000644�0001750�0001750�00000033513�11462120062�015332� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>bgexec(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> bgexec - Run programs in the background while handling Tk events. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>blt::bgexec <I>varName</I></B> ?<I>option value</I>?... <I>program</I> ?<I>arg</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> <P> The <B>bgexec</B> command executes programs in the background, allowing Tk to handle events. A global Tcl variable <I>varName</I> is set when the program has completed. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Tcl's <B>exec</B> command is very useful for gathering information from the operating system. It runs a program and returns the output as its result. This works well for Tcl-only applications. But for Tk applications, a problem occurs when the program takes time to process. Let's say we want the get the disk usage of a directory. We'll use the Unix program <I>du</I> to get the summary. <BR> <CODE>set out [exec du -s $dir]<BR> puts "Disk usage for $dir is $out"<BR> </CODE><P>While <I>du</I> is running, scrollbars won't respond. None of the Tk widgets will be redrawn properly. The <B>send</B> command won't work. And the worst part is that the application appears hung up or dead. The problem is that while <B>exec</B> is waiting for <I>du</I> to finish, Tk is not able to handle X events. <P> The <B>bgexec</B> command performs the same functions as <B>exec</B>, but also allows Tk to handle events. You can execute a long-running program and the Tk widgets will behave normally. When the program finishes, its output and the exit status are written to Tcl variables. This makes it easy to monitor and save the output of a program. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> Here is the disk usage example again, this time using <B>bgexec</B>. The syntax to invoke "du" is exactly the same as the previous example, when we used <B>exec</B>. <BR> <CODE>global myStatus myOutput<BR> blt::bgexec myStatus -output myOutput du -s $dir<BR> puts "Disk usage for $dir is $myOutput"<BR> </CODE><P>Two global variables, <I>myStatus</I> and <I>myOutput</I>, will be set by <B>bgexec</B> when <I>du</I> has completed. <I>MyStatus</I> will contain the program's exit status. <I>MyOutput</I>, specified by the <B>-output</B> option, will store the output of the program. <P> You can also terminate the program by setting the variable <I>myStatus</I>. If <I>myStatus</I> is set before <I>du</I> has completed, the process is killed. Under Unix, this is done sending by a configurable signal (by default it's SIGKILL). Under Win32, this is done by calling <B>TerminateProcess</B>. It makes no difference what <I>myStatus</I> is set to. <BR> <CODE>set myStatus {}<BR> </CODE><P>There are several <B>bgexec</B> options to collect different types of information. <BR> <CODE>global myStatus myOutput myErrs<BR> blt::bgexec myStatus -output myOutput -error myErrs du -s $dir<BR> </CODE><P>The <B>-error</B> option is similar to <B>-output</B>. It sets a global variable when the program completes. The variable will contain any data written to stderr by the program. <P> The <B>-output</B> and <B>-error</B> variables are set only after the program completes. But if the program takes a long time, to run you may want to receive its partial output. You can gather data as it becomes available using the <B>-onoutput</B> option. It specifies a Tcl command prefix. Whenever new data is available, this command is executed, with the data appended as an argument to the command. <BR> <CODE>proc GetInfo { data } {<BR> puts $data<BR> }<BR> blt::bgexec myStatus -onoutput GetInfo du -s $dir<BR> </CODE><P>When output is available, the procedure <I>GetInfo</I> is called. The <B>-onerror</B> option performs a similar function for the stderr data stream. <P> Like <B>exec</B>, <B>bgexec</B> returns an error if the exit code of the program is not zero. If you think you may get a non-zero exit code, you might want to invoke <B>bgexec</B> from within a <B>catch</B>. <BR> <CODE>catch { blt::bgexec myStatus -output myOutput du -s $dir }<BR> </CODE><P>By default, <B>bgexec</B> will wait for the program to finish. But you can detach the program making ampersand (&amp;) the last argument on the command line. <BR> <CODE>global myStatus myOutput<BR> blt::bgexec myStatus -output myOutput du -s $dir &amp;<BR> </CODE><P><B>Bgexec</B> will return immediately and its result will be a list of the spawned process ids. If at some point you need to wait for the program to finish up, you can use <B>tkwait</B>. When the program finishes, the variable <I>myStatus</I> will be written to, breaking out the <B>tkwait</B> command. <BR> <CODE>global myStatus myOutput<BR> blt::bgexec myStatus -output myOutput du -s $dir &amp;<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;...<BR> tkwait variable myStatus<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Syntax</A></H2> The <B>bgexec</B> command takes the following form: <P> <B><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;blt::bgexec <I>varName</I></B> ?<I>option value</I>?... <I>program</I> ?<I>arg</I>?... <P> <I>VarName</I> is the name of a global variable which is set when <I>program</I> has finished executing. The exit status of will be stored in <I>varName</I>. The exit status is a list of a status token, the process-id of the program, the exit code, and a status message. You can also prematurely terminate the program by setting <I>varName</I>. Under Unix, the program will be sent a signal to terminate it (by default the signal is a SIGKILL; see the <B>-killsignal</B> option). <P> <I>Program</I> is the name of the program to be executed and <I>args</I> are any extra arguments for <I>program</I>. The syntax of <I>program</I> and <I>args</I> is the same as the <B>exec</B> command. So you can redirect I/O, execute pipelines, etc. (see the <B>exec</B> manual for further information) just like <B>exec</B>. If the last argument is an ampersand (&amp;), the program will be run detached, and <B>bgexec</B> will return immediately. <I>VarName</I> will still be set with the return status when <I>program</I> completes. <H2><A NAME="sect6" HREF="#toc6">Options</A></H2> <I>Option</I> refers to the switch name always beginning with a dash (-). <I>Value</I> is the value of the option. Option-value pairs are terminated either by the program name, or double dashes (--). The following options are available for <B>bgexec</B>: <DL> <DT><B>-decodeerror <I>encodingName</I></B> </DT> <DD><BR> Specifies the encoding of the stderr channel. This affects only data returned to the Tcl interpreter. No translation is done on file redirection. <BR> For example if data is to be converted from Unicode for use in Tcl, you would use the "unicode" encoding. The default is that no tranlation is performed. </DD> <DT><B>-decodeoutput <I>encodingName</I></B> </DT> <DD><BR> Specifies the encoding of the stdout channels. This affects only data returned to the Tcl interpreter. No translation is done on file redirection. <BR> For example if data is to be converted from Unicode for use in Tcl, you would use the "unicode" encoding. The default is that no tranlation is performed. </DD> <DT><B>-error <I>varName</I></B> </DT> <DD><BR> Specifies that a global variable <I>varName</I> is to be set with the contents of stderr after the program has completed. </DD> <DT><B>-keepnewline <I>boolean</I></B> </DT> <DD>Specifies that a trailing newline should be retained in the output. If <I>boolean</I> is true, the trailing newline is truncated from the output of the <B>-onoutput</B> and <B>-output</B> variables. The default value is <I>true</I>. </DD> <DT><B>-killsignal <I>signal</I></B> </DT> <DD>Specifies the signal to be sent to the program when terminating. This is available only under Unix. <I>Signal</I> can either be a number (typically 1-32) or a mnemonic (such as SIGINT). If <I>signal</I> is the empty string, then no signal is sent. The default signal is <I>9</I> (SIGKILL). </DD> <DT><B>-lasterror <I>varName</I></B> </DT> <DD>Specifies a variable <I>varName</I> that is updated whenever data becomes available from standard error of the program. <I>VarName</I> is a global variable. Unlike the <B>-error</B> option, data is available as soon as it arrives. </DD> <DT><B>-lastoutput <I>varName</I></B> </DT> <DD>Specifies a variable <I>varName</I> that is updated whenever data becomes available from standard output of the program. <I>VarName</I> is a global variable. Unlike the <B>-output</B> option, data is available as soon as it arrives. </DD> <DT><B>-linebuffered <I>boolean</I></B> </DT> <DD>Specifies that updates should be made on a line-by-line basis. Normally when new data is available <B>bgexec</B> will set the variable (<B>-lastoutput</B> and <B>-lasterror</B> options) or invoke the command (<B>-onoutput</B> and <B>-onerror</B> options) delivering all the new data currently available. If <I>boolean</I> is true, only one line at a time will be delivered. This can be useful when you want to process the output on a line-by-line basis. The default value is <I>false</I>. </DD> <DT><B>-output <I>varName</I></B> </DT> <DD><BR> Specifies that a global variable <I>varName</I> is to be set with the output of the program, once it has completed. If this option is not set, no output will be accumulated. </DD> <DT><B>-onerror <I>command</I></B> </DT> <DD>Specifies the start of a Tcl command that will be executed whenever new data is available from standard error. The data is appended to the command as an extra argument before it is executed. </DD> <DT><B>-onoutput <I>command</I></B> </DT> <DD>Specifies the start of a Tcl command that will be executed whenever new data is available from standard output. The data is appended to the command as an extra argument before it is executed. </DD> <DT><B>-update <I>varName</I></B> </DT> <DD>Deprecated. This option is replaced by <B>-lasterror</B>. </DD> <DT><B>--</B> </DT> <DD>This marks the end of the options. The following argument will be considered the name of a program even if it starts with a dash (<B>-</B>). </DD> </DL> <H2><A NAME="sect7" HREF="#toc7">Preemption</A></H2> Because <B>bgexec</B> allows Tk to handle events while a program is running, it's possible for an application to preempt itself with further user-interactions. Let's say your application has a button that runs the disk usage example. And while the <I>du</I> program is running, the user accidently presses the button again. A second <B>bgexec</B> program will preempt the first. What this means is that the first program can not finish until the second program has completed. <P> Care must be taken to prevent an application from preempting itself by blocking further user-interactions (such as button clicks). The BLT <B>busy</B> command is very useful for just these situations. See the <B>busy</B> manual for details. <H2><A NAME="sect8" HREF="#toc8">Differences with Fileevent</A></H2> Since Tk 4.0, a subset of <B>bgexec</B> can be also achieved using the <B>fileevent</B> command. The steps for running a program in the background are: <P> Execute the program with the <B>open</B> command (using the "|" syntax) and save the file handle. <BR> <CODE>global fileId <BR> set fileId [open "|du -s $dir" r]<BR> </CODE><P>Next register a Tcl code snippet with <B>fileevent</B> to be run whenever output is available on the file handle. The code snippet will read from the file handle and save the output in a variable. <BR> <CODE>fileevent fileId readable { <BR> if { [gets $fileId line] &lt; 0 } {<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;close $fileId<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;set output $temp<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;unset fileId temp<BR> } else {<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;append temp $line<BR> }<BR> }<BR> <P> </CODE><P>The biggest advantage of <B>bgexec</B> is that, unlike <B>fileevent</B>, it requires no additional Tcl code to run a program. It's simpler and less error prone. You don't have to worry about non-blocking I/O. It's handled tranparently for you. <P> <B>Bgexec</B> runs programs that <B>fileevent</B> can not. <B>Fileevent</B> assumes that the when stdout is closed the program has completed. But some programs, like the Unix <I>compress</I> program, reopen stdout, fooling <B>fileevent</B> into thinking the program has terminated. In the example above, we assume that the program will write and flush its output line-by-line. However running another program, your application may block in the <B>gets</B> command reading a partial line. <P> <B>Bgexec</B> lets you get back the exit status of the program. It also allows you to collect data from both stdout and stderr simultaneously. Finally, since data collection is handled in C code, <B>bgexec</B> is faster. You get back to the Tk event loop more quickly, making your application seem more responsive. <H2><A NAME="sect9" HREF="#toc9">See Also</A></H2> busy, exec, tkwait <H2><A NAME="sect10" HREF="#toc10">Keywords</A></H2> exec, background, busy <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">Options</A></LI> <LI><A NAME="toc7" HREF="#sect7">Preemption</A></LI> <LI><A NAME="toc8" HREF="#sect8">Differences with Fileevent</A></LI> <LI><A NAME="toc9" HREF="#sect9">See Also</A></LI> <LI><A NAME="toc10" HREF="#sect10">Keywords</A></LI> </UL> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/busy.html��������������������������������������������������������������������0000644�0001750�0001750�00000024715�11462120062�015063� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>busy(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> busy - Make Tk widgets busy, temporarily blocking user interactions. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>busy hold <I>window</I></B> ?<I>option value</I>?... <P> <B>busy release <I>window</I></B> ?<I>window</I>?... <P> <B>busy configure <I>window</I></B> ?<I>option value</I>?... <P> <B>busy forget <I>window</I></B> ?<I>window</I>?... <P> <B>busy isbusy </B>?<I>pattern</I>? <P> <B>busy names </B>?<I>pattern</I>? <P> <B>busy status <I>window</I></B> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> <P> The <B>busy</B> command provides a simple means to block keyboard, button, and pointer events from Tk widgets, while overriding the widget's cursor with a configurable busy cursor. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> <P> There are many times in applications where you want to temporarily restrict what actions the user can take. For example, an application could have a "run" button that when pressed causes some processing to occur. But while the application is busy processing, you probably don't want the the user to be able to click the "run" button again. You may also want restrict the user from other tasks such as clicking a "print" button. <P> The <B>busy</B> command lets you make Tk widgets busy. This means that user interactions such as button clicks, moving the mouse, typing at the keyboard, etc. are ignored by the widget. You can set a special cursor (like a watch) that overrides the widget's normal cursor, providing feedback that the application (widget) is temporarily busy. <P> When a widget is made busy, the widget and all of its descendents will ignore events. It's easy to make an entire panel of widgets busy. You can simply make the toplevel widget (such as ".") busy. This is easier and far much more efficient than recursively traversing the widget hierarchy, disabling each widget and re-configuring its cursor. <P> Often, the busy command can be used instead of Tk's <B>grab</B> command. Unlike <B>grab</B> which restricts all user interactions to one widget, with the busy command you can have more than one widget active (for example, a "cancel" dialog and a "help" button). <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> You can make several widgets busy by simply making its ancestor widget busy using the <B>hold</B> operation. <BR> <CODE>frame .top<BR> button .top.button; canvas .top.canvas<BR> pack .top.button .top.canvas<BR> pack .top<BR> . . .<BR> busy hold .top<BR> update<BR> </CODE><P>All the widgets within <I>.top</I> (including <I>.top</I>) are now busy. Using <B>update</B> insures that <B>busy</B> command will take effect before any other user events can occur. <P> When the application is no longer busy processing, you can allow user interactions again by the <B>release</B> operation. <BR> <PRE><I><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;busy release .top </I> </PRE>The busy window has a configurable cursor. You can change the busy cursor using the <B>configure</B> operation. <BR> <PRE><I><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;busy configure .top -cursor "watch"</I> </PRE>Finally, when you no longer need to the busy window, invoke the <B>forget</B> operation to free any resources it allocated. <BR> <PRE><I><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;busy forget .top </I> </PRE>Destroying the widget will also clean up any resources allocated by the busy command. <P> <H2><A NAME="sect5" HREF="#toc5">Operations</A></H2> The following operations are available for the <B>busy</B> command: <DL> <DT><B>busy hold <I>window</I></B> ?<I>option value</I>?... </DT> <DD>Makes the widget <I>window</I> (and its descendants in the Tk window hierarchy) busy. <I>Window</I> must be a valid path name of a Tk widget. The busy window is mapped the next time idle tasks are processed, and the widget and its descendants will be blocked from user interactions. All events in the widget window and its descendants are ignored. Normally <B>update</B> should be called immediately afterward to insure that the <B>hold</B> operation is in effect <I>before</I> the application starts its processing. The following configuration options are valid: <blockquote></DD> <DT><B>-cursor <I>cursorName</I></B> </DT> <DD>Specifies the cursor to be displayed when the widget is made busy. <I>CursorName</I> can be in any form accepted by <B>Tk_GetCursor</B>. The default cursor is <I>watch</I>. </DD> </DL> </blockquote> <DL> <DT><B>busy configure <I>window</I></B> ?<I>option value</I>?... </DT> <DD>Queries or modifies the <B>busy</B> command configuration options for <I>window</I>. <I>Window</I> must be the path name of a widget previously made busy by the <B>hold</B> operation. If no options are specified, a list describing all of the available options for <I>window</I> (see <B>Tk_ConfigureInfo</B> for information on the format of this list) is returned. If <I>option</I> is specified with no <I>value</I>, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no <I>option</I> is specified). If one or more <I>option-value</I> pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns the empty string. <I>Option</I> may have any of the values accepted by the <B>hold</B> operation. <P> Please note that the option database is referenced through <I>window</I>. For example, if the widget <I>.frame</I> is to be made busy, the busy cursor can be specified for it by either <B>option</B> command: <BR> <PRE><tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<I>option add *frame.busyCursor gumby</I> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<I>option add *Frame.BusyCursor gumby</I> </PRE></DD> <DT><B>busy forget <I>window</I></B> ?<I>window</I>?... </DT> <DD>Releases resources allocated by the busy command for <I>window</I>, including the busy window. User events will again be received again by <I>window</I>. Resources are also released when <I>window</I> is destroyed. <I>Window</I> must be the name of a widget specified in the <B>hold</B> operation, otherwise an error is reported. </DD> <DT><B>busy isbusy </B>?<I>pattern</I>? </DT> <DD>Returns the pathnames of all widgets that are currently busy. If a <I>pattern</I> is given, the path names of busy widgets matching <I>pattern</I> are returned. </DD> <DT><B>busy names </B>?<I>pattern</I>? </DT> <DD>Returns the pathnames of all widgets that have previously been made busy (i.e. a busy window is allocated and associated with the widget). It makes no difference if the window is currently busy or not. If a <I>pattern</I> is given, the path names of busy widgets matching <I>pattern</I> are returned. </DD> <DT><B>busy release <I>window</I></B> ?<I>window</I>?... </DT> <DD>Restores user interactions to the widget <I>window</I> again. This differs from the <B>forget</B> operation in that the busy window is not destroyed, but simply unmapped. <I>Window</I> must be the name of a widget specified in a <B>hold</B> operation, otherwise an error is reported. </DD> <DT><B>busy status <I>window</I></B> </DT> <DD>Returns the status of a widget <I>window</I> previously made busy. An error is reported if <I>window</I> was never made busy, or the <B>forget</B> operation was invoked (i.e. does not currently have a busy window associated with it). If <I>window</I> is presently can not receive user interactions, <I>1</I> is returned, otherwise <I>0</I>. <P> </DD> </DL> <H2><A NAME="sect6" HREF="#toc6">Bindings</A></H2> The event blocking feature is implemented by creating and mapping a transparent window that completely covers the widget. When the busy window is mapped, it invisibly shields the widget and its hierarchy from all events that may be sent. Like Tk widgets, busy windows have widget names in the Tk window hierarchy. This means that you can use the <B>bind</B> command, to handle events in the busy window. <BR> <CODE>busy hold .frame.canvas<BR> bind .frame.canvas_Busy &lt;Enter&gt; { ... } <BR> <P> </CODE><P>Normally the busy window is a sibling of the widget. The name of the busy window is "<I>widget<I>_Busy</I></I>" where <I>widget</I> is the name of the widget to be made busy. In the previous example, the pathname of the busy window is "<I>.frame.canvas_Busy</I>" The exception is when the widget is a toplevel widget (such as ".") where the busy window can't be made a sibling. The busy window is then a child of the widget named "<I>widget<I>._Busy</I></I>" where <I>widget</I> is the name of the toplevel widget. In the following example, the pathname of the busy window is "<I>._Busy</I>" <BR> <CODE>busy hold .<BR> bind ._Busy &lt;Enter&gt; { ... } <BR> <H2><A NAME="sect7" HREF="#toc7"></CODE><P>Enter/Leave Events</A></H2> Mapping and unmapping busy windows generates Enter/Leave events for all widgets they cover. Please note this if you are tracking Enter/Leave events in widgets. <H2><A NAME="sect8" HREF="#toc8">Keyboard Events</A></H2> When a widget is made busy, the widget is prevented from gaining the keyboard focus by the busy window. But if the widget already had focus, it still may received keyboard events. To prevent this, you must move focus to another window. <BR> <CODE>busy hold .frame<BR> label .dummy<BR> focus .dummy<BR> update<BR> </CODE><P>The above example moves the focus from .frame immediately after invoking the <B>hold</B> so that no keyboard events will be sent to <I>.frame</I> or any of its descendants. <H2><A NAME="sect9" HREF="#toc9">Keywords</A></H2> busy, keyboard events, pointer events, window, cursor <P> <P> <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Operations</A></LI> <LI><A NAME="toc6" HREF="#sect6">Bindings</A></LI> <LI><A NAME="toc7" HREF="#sect7">Enter/Leave Events</A></LI> <LI><A NAME="toc8" HREF="#sect8">Keyboard Events</A></LI> <LI><A NAME="toc9" HREF="#sect9">Keywords</A></LI> </UL> </BODY></HTML> ���������������������������������������������������./saods9/blt3.0.1/html/BLT.html���������������������������������������������������������������������0000644�0001750�0001750�00000015212�11462120062�014512� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>graph(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> BLT - Introduction to the BLT library <H2><A NAME="sect1" HREF="#toc1">Description</A></H2> BLT is a library of extensions to the Tk library. It adds new commands and variables to the application's interpreter. <P> <H2><A NAME="sect2" HREF="#toc2">Commands</A></H2> The following commands are added to the interpreter from the BLT library: <DL> <DT><B>table</B> </DT> <DD>A table geometry manager for Tk. You specify window placements as table row,column positions and windows can also span multiple rows or columns. It also has many options for setting and/or bounding window sizes. </DD> <DT><B>graph</B> </DT> <DD>A 2D plotting widget. Plots two variable data in a window with an optional legend and annotations. It has of several components; coordinate axes, crosshairs, a legend, and a collection of elements and tags. </DD> <DT><B>barchart</B> </DT> <DD>A barchart widget. Plots two-variable data as rectangular bars in a window. The x-coordinate values designate the position of the bar along the x-axis, while the y-coordinate values designate the magnitude. The <B>barchart</B> widget has of several components; coordinate axes, crosshairs, a legend, and a collection of elements and tags. </DD> <DT><B>vector</B> </DT> <DD>Creates a vector of floating point values. The vector's components can be manipulated in three ways: through a Tcl array variable, a Tcl command, or the C API. </DD> <DT><B>spline</B> </DT> <DD>Computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. </DD> <DT><B>bgexec</B> </DT> <DD>Like Tcl's <B>exec</B> command, <B>bgexec</B> runs a pipeline of Unix commands in the background. Unlike <B>exec</B>, the output of the last process is collected and a global Tcl variable is set upon its completion. <B>bgexec</B> can be used with <B>tkwait</B> to wait for Unix commands to finish while still handling expose events. Intermediate output is also available while the pipeline is active. </DD> <DT><B>busy</B> </DT> <DD>Creates a "busy window" which prevents user-interaction when an application is busy. The busy window also provides an easy way to have temporary busy cursors (such as a watch or hourglass). </DD> <DT><B>bitmap</B> </DT> <DD>Reads and writes bitmaps from Tcl. New X bitmaps can be defined on-the-fly from Tcl, obviating the need to copy around bitmap files. Other options query loaded X bitmap's dimensions and data. </DD> <DT><B>drag&amp;drop</B> </DT> <DD>Provides a drag-and-drop facility for Tk. Information (represented by a token window) can be dragged to and from any Tk window, including those of another Tk application. <B>drag&amp;drop</B> acts as a coordinator, directing Tk <B>send</B> commands between (or within) TCL/Tk applications. </DD> <DT><B>htext</B> </DT> <DD>A simple hypertext widget. Combines text and Tk widgets into a single scroll-able window. Tcl commands can be embedded into text, which are invoked as the text is parsed. In addition, Tk widgets can be appended to the window at the current point in the text. <B>Htext</B> can be also used to create scrolled windows of Tk widgets. </DD> <DT><B>winop</B> </DT> <DD>Raise, lower, map, or, unmap any window. The raise and lower functions are useful for stacking windows above or below "busy windows". </DD> <DT><B>watch</B> </DT> <DD>Arranges for Tcl procedures to be called before and/or after the execution of every Tcl command. This command may be used in the logging, profiling, or tracing of Tcl code. </DD> <DT><B>bltdebug</B> </DT> <DD>A simple Tcl command tracing facility useful for debugging Tcl code. Displays each Tcl command before and after substitution along its level in the interpreter on standard error. </DD> </DL> <H2><A NAME="sect3" HREF="#toc3">Variables</A></H2> <P> The following Tcl variables are either set or used by BLT at various times in its execution: <DL> <DT><B>blt_library</B> </DT> <DD>This variable contains the name of a directory containing a library of Tcl scripts and other files related to BLT. Currently, this directory contains the <B>drag&amp;drop</B> protocol scripts and the PostScript prolog used by <B>graph</B> and <B>barchart</B>. The value of this variable is taken from the BLT_LIBRARY environment variable, if one exists, or else from a default value compiled into the <B>BLT</B> library. </DD> <DT><B>blt_versions</B> </DT> <DD>This variable is set in the interpreter for each application. It is an array of the current version numbers for each of the BLT commands in the form <I>major</I>.<I>minor</I>. <I>Major</I> and <I>minor</I> are integers. The major version number increases in any command that includes changes that are not backward compatible (i.e. whenever existing applications and scripts may have to change to work with the new release). The minor version number increases with each new release of a command, except that it resets to zero whenever the major version number changes. The array is indexed by the individual command name. </DD> </DL> <H2><A NAME="sect4" HREF="#toc4">Adding Blt to Your Applications</A></H2> It's easy to add BLT to an existing Tk application. BLT requires no patches or edits to the Tcl or Tk libraries. To add BLT, simply add the following code snippet to your application's tkAppInit.c file. <BR> <CODE>if (Blt_Init(interp) != TCL_OK) {<BR> return TCL_ERROR;<BR> }<BR> </CODE><P>Recompile and link with the BLT library (libBLT.a) and that's it. <P> Alternately, you can dynamically load BLT, simply by invoking the command <BR> <CODE>package require BLT<BR> </CODE><P>from your Tcl script. <H2><A NAME="sect5" HREF="#toc5">Bugs</A></H2> Send bug reports, requests, suggestions, etc. to gah@siliconmetrics.com or gah@myfirstlink.net <H2><A NAME="sect6" HREF="#toc6">Keywords</A></H2> BLT <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Description</A></LI> <LI><A NAME="toc2" HREF="#sect2">Commands</A></LI> <LI><A NAME="toc3" HREF="#sect3">Variables</A></LI> <LI><A NAME="toc4" HREF="#sect4">Adding Blt to Your Applications</A></LI> <LI><A NAME="toc5" HREF="#sect5">Bugs</A></LI> <LI><A NAME="toc6" HREF="#sect6">Keywords</A></LI> </UL> </BODY></HTML> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/tree.html��������������������������������������������������������������������0000644�0001750�0001750�00000113752�11462120062�015040� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>tree(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> tree - Create and manage tree data objects. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>blt::tree create </B>?<I>treeName</I>? <P> <B>blt::tree destroy</B> <I>treeName</I>... <P> <B>blt::tree names</B> ?<I>pattern</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>tree</B> command creates tree data objects. A <I>tree object</I> is general ordered tree of nodes. Each node has both a label and a key-value list of data. Data can be heterogeneous, since nodes do not have to contain the same data keys. It is associated with a Tcl command that you can use to access and modify the its structure and data. Tree objects can also be managed via a C API. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> <P> <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> <P> <H2><A NAME="sect5" HREF="#toc5">Syntax</A></H2> <DL> <DT><B>tree create</B> ?<I>treeName</I>? </DT> <DD>Creates a new tree object. The name of the new tree is returned. If no <I>treeName</I> argument is present, then the name of the tree is automatically generated in the form "<I>tree0</I>", "<I>tree1</I>", etc. If the substring "<I>#auto</I>" is found in <I>treeName</I>, it is automatically substituted by a generated name. For example, the name <I>.foo.#auto.bar</I> will be translated to <I>.foo.tree0.bar</I>. <P> A new Tcl command (by the same name as the tree) is also created. Another Tcl command or tree object can not already exist as <I>treeName</I>. If the Tcl command is deleted, the tree will also be freed. The new tree will contain just the root node. Trees are by default, created in the current namespace, not the global namespace, unless <I>treeName</I> contains a namespace qualifier, such as "<I>fred::myTree</I>". </DD> <DT><B>tree destroy</B> <I>treeName</I>... </DT> <DD>Releases one of more trees. The Tcl command associated with <I>treeName</I> is also removed. Trees are reference counted. The internal tree data object isn't destroyed until no one else is using the tree. </DD> <DT><B>tree names </B>?<I>pattern</I>? </DT> <DD>Returns the names of all tree objects. if a <I>pattern</I> argument is given, then the only those trees whose name matches pattern will be listed. </DD> </DL> <H2><A NAME="sect6" HREF="#toc6">Node IDs and Tags</A></H2> Nodes in a tree object may be referred in either of two ways: by id or by tag. Each node has a unique serial number or id that is assigned to that node when it's created. The id of an node never changes and id numbers are not re-used. <P> A node may also have any number of tags associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "<I>x123</I>" is valid, but "<I>123</I>" isn't. The same tag may be associated with many different nodes. This is commonly done to group nodes in various interesting ways. <P> There are two built-in tags: The tag <B>all</B> is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. The tag <B>root</B> is managed automatically by the tree object. It applies to the node current set as root. <P> When specifying nodes in tree object commands, if the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, then it is assumed to refer to all of the nodes in the tree that have a tag matching the specifier. The symbol <I>node</I> is used below to indicate that an argument specifies either an id that selects a single node or a tag that selects zero or more nodes. Many tree commands only operate on a single node at a time; if <I>node</I> is specified in a way that names multiple items, then an error "refers to more than one node" is generated. <H2><A NAME="sect7" HREF="#toc7">Node Modifiers</A></H2> You can also specify node in relation to another node by appending one or more modifiers to the node id or tag. A modifier refers to a node in relation to the specified node. For example, "<I>root-&gt;firstchild</I>" selects the first subtree of the root node. <P> The following modifiers are available: <blockquote> <DL> <DT><B>firstchild</B> </DT> <DD>Selects the first child of the node. </DD> <DT><B>lastchild</B> </DT> <DD>Selects the last child of the node. </DD> <DT><B>next</B> </DT> <DD>Selects the next node in preorder to the node. </DD> <DT><B>nextsibling</B> </DT> <DD>Selects the next sibling of the node. </DD> <DT><B>parent</B> </DT> <DD>Selects the parent of the node. </DD> <DT><B>previous</B> </DT> <DD>Selects the previous node in preorder to the node. </DD> <DT><B>prevsibling</B> </DT> <DD>Selects the previous sibling of the node. </DD> <DT>"<I>label</I>" </DT> <DD>Selects the node whose label is <I>label</I>. Enclosing <I>label</I> in quotes indicates to always search for a node by its label (for example, even if the node is labeled "parent"). </DD> </DL> </blockquote> <P> It's an error the node can't be found. For example, <B>lastchild</B> and <B>firstchild</B> will generate errors if the node has no children. The exception to this is the <B>index</B> operation. You can use <B>index</B> to test if a modifier is valid. <H2><A NAME="sect8" HREF="#toc8">Tree Operations</A></H2> Once you create a tree object, you can use its Tcl command to query or modify it. The general form is <BR> <P> <CODE><I>treeName</I> <I>operation</I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for trees are listed below. <DL> <DT><I>treeName</I> <B>ancestor</B> <I>node1</I> <I>node2</I> </DT> <DD>Returns the mutual ancestor of the two nodes <I>node1</I> and <I>node2</I>. The ancestor can be one of the two nodes. For example, if <I>node1</I> and <I>node2</I> are the same nodes, their ancestor is <I>node1</I>. </DD> <DT><I>treeName</I> <B>apply</B> <I>node</I> ?<I>switches</I>? </DT> <DD>Runs commands for all nodes matching the criteria given by <I>switches</I> for the subtree designated by <I>node</I>. By default all nodes match, but you can set switches to narrow the match. This operation differs from <B>find</B> in two ways: 1) Tcl commands can be invoked both pre- and post-traversal of a node and 2) the tree is always traversed in depth first order. <P> The <B>-exact</B>, <B>-glob</B>, and <B>-regexp</B> switches indicate both what kind of pattern matching to perform and the pattern. Pattern matching is done, by default, against each node's label. But if the <B>-path</B> switch is present, it will match the full path of the node (a list containing the labels of the node's ancestors too). If the <B>-key</B> switch is used, it designates the data field to be matched. <P> The valid switches are listed below: <blockquote></DD> <DT><B>-depth</B> <I>number</I> </DT> <DD>Descend at most <I>number</I> (a non-negative integer) levels If <I>number</I> is <I>1</I> this means only apply the tests to the children of <I>node</I>. </DD> <DT><B>-exact</B> <I>string</I> </DT> <DD>Matches each node using <I>string</I>. The node must match <I>string</I> exactly. </DD> <DT><B>-glob</B> <I>string</I> </DT> <DD>Test each node to <I>string</I> using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. </DD> <DT><B>-invert</B> </DT> <DD>Select non-matching nodes. Any node that <I>doesn't</I> match the given criteria will be selected. </DD> <DT><B>-key</B> <I>key</I> </DT> <DD>If pattern matching is selected (using the <B>-exact</B>, <B>-glob</B>, or <B>-regexp</B> switches), compare the values of the data field keyed by <I>key</I> instead of the node's label. If no pattern matching switches are set, then any node with this data key will match. </DD> <DT><B>-leafonly</B> </DT> <DD>Only test nodes with no children. </DD> <DT><B>-nocase</B> </DT> <DD>Ignore case when matching patterns. </DD> <DT><B>-path</B> </DT> <DD>Use the node's full path when comparing nodes. </DD> <DT><B>-precommand</B> <I>command</I> </DT> <DD>Invoke <I>command</I> for each matching node. Before <I>command</I> is invoked, the id of the node is appended. You can control processing by the return value of <I>command</I>. If <I>command</I> generates an error, processing stops and the <B>find</B> operation returns an error. But if <I>command</I> returns <B>break</B>, then processing stops, no error is generated. If <I>command</I> returns <B>continue</B>, then processing stops on that subtree and continues on the next. </DD> <DT><B>-postcommand</B> <I>command</I> </DT> <DD>Invoke <I>command</I> for each matching node. Before <I>command</I> is invoked, the id of the node is appended. You can control processing by the return value of <I>command</I>. If <I>command</I> generates an error, processing stops and the <B>find</B> operation returns an error. But if <I>command</I> returns <B>break</B>, then processing stops, no error is generated. If <I>command</I> returns <B>continue</B>, then processing stops on that subtree and continues on the next. </DD> <DT><B>-regexp</B> <I>string</I> </DT> <DD>Test each node using <I>string</I> as a regular expression pattern. </DD> <DT><B>-tag</B> <I>string</I> </DT> <DD>Only test nodes that have the tag <I>string</I>. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>attach</B> <I>treeObject</I> </DT> <DD>Attaches to an existing tree object <I>treeObject</I>. This is for cases where the tree object was previously created via the C API. The current tree associated with <I>treeName</I> is discarded. In addition, the current set of tags, notifier events, and traces are removed. </DD> <DT><I>treeName</I> <B>children</B> <I>node</I> </DT> <DD>Returns a list of children for <I>node</I>. If <I>node</I> is a leaf, then an empty string is returned. </DD> <DT><I>treeName</I> <B>copy</B> <I>srcNode</I> ?<I>destTree</I>? <I>destNode</I> ?<I>switches</I>? </DT> <DD>Copies <I>srcNode</I> into <I>destNode</I>. Both nodes <I>srcNode</I> and <I>destNode</I> must already exist. If <I>destTree</I> argument is present, it indicates the name of the destination tree. By default both the source and destination trees are the same. The valid <I>switches</I> are listed below: <blockquote></DD> <DT><B>-overwrite</B> </DT> <DD>Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. </DD> <DT><B>-recurse</B> </DT> <DD>Recursively copy all the subtrees of <I>srcNode</I> as well. In this case, <I>srcNode</I> can't be an ancestor of <I>destNode</I> as it would result in a cyclic copy. </DD> <DT><B>-tags</B> </DT> <DD>Copy tag inforation. Normally the following node is copied: its label and data fields. This indicates to copy tags as well. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>degree</B> <I>node</I> </DT> <DD>Returns the number of children of <I>node</I>. </DD> <DT><I>treeName</I> <B>delete</B> <I>node</I>... </DT> <DD>Recursively deletes one or more nodes from the tree. The node and all its descendants are removed. The one exception is the root node. In this case, only its descendants are removed. The root node will remain. Any tags or traces on the nodes are released. </DD> <DT><I>treeName</I> <B>depth</B> <I>node</I> </DT> <DD>Returns the depth of the node. The depth is the number of steps from the node to the root of the tree. The depth of the root node is <I>0</I>. </DD> <DT><I>treeName</I> <B>dump</B> <I>node</I> </DT> <DD>Returns a list of the paths and respective data for <I>node</I> and its descendants. The subtree designated by <I>node</I> is traversed returning the following information for each node: 1) the node's path relative to <I>node</I>, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the tree with the <B>restore</B> operation. </DD> <DT><I>treeName</I> <B>dumpfile</B> <I>node</I> <I>fileName</I> </DT> <DD>Writes a list of the paths and respective data for <I>node</I> and its descendants to the given file <I>fileName</I>. The subtree designated by <I>node</I> is traversed returning the following information for each node: 1) the node's path relative to <I>node</I>, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the tree with the <B>restore</B> operation. </DD> <DT><I>treeName</I> <B>exists</B> <I>node</I> ?<I>key</I>? </DT> <DD>Indicates if <I>node</I> exists in the tree. If a <I>key</I> argument is present then the command also indicates if the named data field exists. </DD> <DT><I>treeName</I> <B>find</B> <I>node</I> ?<I>switches</I>? </DT> <DD>Finds for all nodes matching the criteria given by <I>switches</I> for the subtree designated by <I>node</I>. A list of the selected nodes is returned. By default all nodes match, but you can set switches to narrow the match. <P> The <B>-exact</B>, <B>-glob</B>, and <B>-regexp</B> switches indicate both what kind of pattern matching to perform and the pattern. Pattern matching is done, by default, against each node's label. But if the <B>-path</B> switch is present, it will match the full path of the node. If the <B>-key</B> switch is used, it designates the data field to be matched. <P> The order in which the nodes are traversed is controlled by the <B>-order</B> switch. The possible orderings are <B>preorder</B>, <B>postorder</B>, <B>inorder</B>, and <B>breadthfirst</B>. The default is <B>postorder</B>. <P> The valid switches are listed below: <blockquote></DD> <DT><B>-addtag</B> <I>string</I> </DT> <DD>Add the tag <I>string</I> to each selected node. </DD> <DT><B>-count</B> <I>number</I> </DT> <DD>Stop processing after <I>number</I> (a positive integer) matches. </DD> <DT><B>-depth</B> <I>number</I> </DT> <DD>Descend at most <I>number</I> (a non-negative integer) levels If <I>number</I> is <I>1</I> this means only apply the tests to the children of <I>node</I>. </DD> <DT><B>-exact</B> <I>string</I> </DT> <DD>Matches each node using <I>string</I>. The node must match <I>string</I> exactly. </DD> <DT><B>-exec</B> <I>command</I> </DT> <DD>Invoke <I>command</I> for each matching node. Before <I>command</I> is invoked, the id of the node is appended. You can control processing by the return value of <I>command</I>. If <I>command</I> generates an error, processing stops and the <B>find</B> operation returns an error. But if <I>command</I> returns <B>break</B>, then processing stops, no error is generated. If <I>command</I> returns <B>continue</B>, then processing stops on that subtree and continues on the next. </DD> <DT><B>-glob</B> <I>string</I> </DT> <DD>Test each node to <I>string</I> using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. </DD> <DT><B>-invert</B> </DT> <DD>Select non-matching nodes. Any node that <I>doesn't</I> match the given criteria will be selected. </DD> <DT><B>-key</B> <I>key</I> </DT> <DD>If pattern matching is selected (using the <B>-exact</B>, <B>-glob</B>, or <B>-regexp</B> switches), compare the values of the data field keyed by <I>key</I> instead of the node's label. If no pattern matching switches are set, then any node with this data key will match. </DD> <DT><B>-leafonly</B> </DT> <DD>Only test nodes with no children. </DD> <DT><B>-nocase</B> </DT> <DD>Ignore case when matching patterns. </DD> <DT><B>-order</B> <I>string</I> </DT> <DD>Traverse the tree and process nodes according to <I>string</I>. <I>String</I> can be one of the following: <blockquote></DD> <DT><B>breadthfirst</B> </DT> <DD>Process the node and the subtrees at each sucessive level. Each node on a level is processed before going to the next level. </DD> <DT><B>inorder</B> </DT> <DD>Recursively process the nodes of the first subtree, the node itself, and any the remaining subtrees. </DD> <DT><B>postorder</B> </DT> <DD>Recursively process all subtrees before the node. </DD> <DT><B>preorder</B> </DT> <DD>Recursively process the node first, then any subtrees. </DD> </DL> </blockquote> <DL> <DT><B>-path</B> </DT> <DD>Use the node's full path when comparing nodes. </DD> <DT><B>-regexp</B> <I>string</I> </DT> <DD>Test each node using <I>string</I> as a regular expression pattern. </DD> <DT><B>-tag</B> <I>string</I> </DT> <DD>Only test nodes that have the tag <I>string</I>. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>findchild</B> <I>node</I> <I>label</I> </DT> <DD>Searches for a child node Ilabel in <I>node</I>. The id of the child node is returned if found. Otherwise <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>firstchild</B> <I>node</I> </DT> <DD>Returns the id of the first child in the <I>node</I>'s list of subtrees. If <I>node</I> is a leaf (has no children), then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>get</B> <I>node</I> ?<I>key</I>? ?<I>defaultValue</I>? </DT> <DD>Returns a list of key-value pairs of data for the node. If <I>key</I> is present, then onlyx the value for that particular data field is returned. It's normally an error if <I>node</I> does not contain the data field <I>key</I>. But if you provide a <I>defaultValue</I> argument, this value is returned instead (<I>node</I> will still not contain <I>key</I>). This feature can be used to access a data field of <I>node</I> without first testing if it exists. This operation may trigger <B>read</B> data traces. </DD> <DT><I>treeName</I> <B>index</B> <I>node</I> </DT> <DD>Returns the id of <I>node</I>. If <I>node</I> is a tag, it can only specify one node. If <I>node</I> does not represent a valid node id or tag, or has modifiers that are invalid, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>insert</B> <I>parent</I> ?<I>switches</I>? </DT> <DD>Inserts a new node into parent node <I>parent</I>. The id of the new node is returned. The following switches are available: <blockquote></DD> <DT><B>-at</B> <I>number</I> </DT> <DD>Inserts the node into <I>parent</I>'s list of children at position <I>number</I>. The default is to append <I>node</I>. </DD> <DT><B>-data</B> <I>dataList</I> </DT> <DD>Sets the value for each data field in <I>dataList</I> for the new node. <I>DataList</I> is a list of key-value pairs. </DD> <DT><B>-label</B> <I>string</I> </DT> <DD>Designates the labels of the node as <I>string</I>. By default, nodes are labeled as <I>node0</I>, <I>node1</I>, etc. </DD> <DT><B>-tags</B> <I>tagList</I> </DT> <DD>Adds each tag in <I>tagList</I> to the new node. <I>TagList</I> is a list of tags, so be careful if a tag has embedded space. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>is</B> <I>property</I> <I>args</I> </DT> <DD>Indicates the property of a node. Both <I>property</I> and <I>args</I> determine the property being tested. Returns <I>1</I> if true and <I>0</I> otherwise. The following <I>property</I> and <I>args</I> are valid: <blockquote></DD> <DT><B>ancestor</B> <I>node1</I> <I>node2</I> </DT> <DD>Indicates if <I>node1</I> is an ancestor of <I>node2</I>. </DD> <DT><B>before</B> <I>node1</I> <I>node2</I> </DT> <DD>Indicates if <I>node1</I> is before <I>node2</I> in depth first traversal. </DD> <DT><B>leaf</B> <I>node</I> </DT> <DD>Indicates if <I>node</I> is a leaf (it has no subtrees). </DD> <DT><B>root</B> <I>node</I> </DT> <DD>Indicates if <I>node</I> is the designated root. This can be changed by the <B>root</B> operation. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>label</B> <I>node</I> ?<I>newLabel</I>? </DT> <DD>Returns the label of the node designated by <I>node</I>. If <I>newLabel</I> is present, the node is relabeled using it as the new label. </DD> <DT><I>treeName</I> <B>lastchild</B> <I>node</I> </DT> <DD>Returns the id of the last child in the <I>node</I>'s list of subtrees. If <I>node</I> is a leaf (has no children), then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>move</B> <I>node</I> <I>newParent</I> ?<I>switches</I>? </DT> <DD>Moves <I>node</I> into <I>newParent</I>. <I>Node</I> is appended to the list children of <I>newParent</I>. <I>Node</I> can not be an ancestor of <I>newParent</I>. The valid flags for <I>switches</I> are described below. <blockquote></DD> <DT><B>-after</B> <I>child</I> </DT> <DD>Position <I>node</I> after <I>child</I>. The node <I>child</I> must be a child of <I>newParent</I>. </DD> <DT><B>-at</B> <I>number</I> </DT> <DD>Inserts <I>node</I> into <I>parent</I>'s list of children at position <I>number</I>. The default is to append the node. </DD> <DT><B>-before</B> <I>child</I> </DT> <DD>Position <I>node</I> before <I>child</I>. The node <I>child</I> must be a child of <I>newParent</I>. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>next</B> <I>node</I> </DT> <DD>Returns the next node from <I>node</I> in a preorder traversal. If <I>node</I> is the last node in the tree, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>nextsibling</B> <I>node</I> </DT> <DD>Returns the node representing the next subtree from <I>node</I> in its parent's list of children. If <I>node</I> is the last child, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>notify</B> <I>args</I> </DT> <DD>Manages notification events that indicate that the tree structure has been changed. See the <FONT SIZE=-1><B>NOTIFY OPERATIONS</B></FONT> section below. </DD> <DT><I>treeName</I> <B>parent</B> <I>node</I> </DT> <DD>Returns the parent node of <I>node</I>. If <I>node</I> is the root of the tree, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>path</B> <I>node</I> </DT> <DD>Returns the full path (from root) of <I>node</I>. </DD> <DT><I>treeName</I> <B>position</B> <I>node</I> </DT> <DD>Returns the position of the node in its parent's list of children. Positions are numbered from 0. The position of the root node is always 0. </DD> <DT><I>treeName</I> <B>previous</B> <I>node</I> </DT> <DD>Returns the previous node from <I>node</I> in a preorder traversal. If <I>node</I> is the root of the tree, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>prevsibling</B> <I>node</I> </DT> <DD>Returns the node representing the previous subtree from <I>node</I> in its parent's list of children. If <I>node</I> is the first child, then <I>-1</I> is returned. </DD> <DT><I>treeName</I> <B>restore</B> <I>node</I> <I>dataString</I> <I>switches</I> </DT> <DD>Performs the inverse function of the <B>dump</B> operation, restoring nodes to the tree. The format of <I>dataString</I> is exactly what is returned by the <B>dump</B> operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from <I>node</I>. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid <I>switches</I> are listed below: <blockquote></DD> <DT><B>-overwrite</B> </DT> <DD>Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>restorefile</B> <I>node</I> <I>fileName</I> <I>switches</I> </DT> <DD>Performs the inverse function of the <B>dumpfile</B> operation, restoring nodes to the tree from the file <I>fileName</I>. The format of <I>fileName</I> is exactly what is returned by the <B>dumpfile</B> operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from <I>node</I>. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid <I>switches</I> are listed below: <blockquote></DD> <DT><B>-overwrite</B> </DT> <DD>Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>root</B> ?<I>node</I>? </DT> <DD>Returns the id of the root node. Normally this is node <I>0</I>. If a <I>node</I> argument is provided, it will become the new root of the tree. This lets you temporarily work within a subset of the tree. Changing root affects operations such as <B>next</B>, <B>path</B>, <B>previous</B>, etc. </DD> <DT><I>treeName</I> <B>set</B> <I>node</I> <I>key value</I> ?<I>key value</I>...? </DT> <DD>Sets one or more data fields in <I>node</I>. <I>Node</I> may be a tag that represents several nodes. <I>Key</I> is the name of the data field to be set and <I>value</I> is its respective value. This operation may trigger <B>write</B> and <B>create</B> data traces. </DD> <DT><I>treeName</I> <B>size</B> <I>node</I> </DT> <DD>Returns the number of nodes in the subtree. This includes the node and all its descendants. The size of a leaf node is 1. </DD> <DT><I>treeName</I> <B>sort</B> <I>node</I> ?<I>switches</I>? </DT> <DD><blockquote></DD> <DT><B>-ascii</B> </DT> <DD>Compare strings using the ASCII collation order. </DD> <DT><B>-command</B> <I>string</I> </DT> <DD>Use command <I>string</I> as a comparison command. To compare two elements, evaluate a Tcl script consisting of command with the two elements appended as additional arguments. The script should return an integer less than, equal to, or greater than zero if the first element is to be considered less than, equal to, or greater than the second, respectively. </DD> <DT><B>-decreasing</B> </DT> <DD>Sort in decreasing order (largest items come first). </DD> <DT><B>-dictionary</B> </DT> <DD>Compare strings using a dictionary-style comparison. This is the same as <B>-ascii</B> except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, in <B>-dictionary</B> mode, bigBoy sorts between bigbang and bigboy, and x10y sorts between x9y and x11y. </DD> <DT><B>-integer</B> </DT> <DD>Compare the nodes as integers. </DD> <DT><B>-key</B> <I>string</I> </DT> <DD>Sort based upon the node's data field keyed by <I>string</I>. Normally nodes are sorted according to their label. </DD> <DT><B>-path</B> </DT> <DD>Compare the full path of each node. The default is to compare only its label. </DD> <DT><B>-real</B> </DT> <DD>Compare the nodes as real numbers. </DD> <DT><B>-recurse</B> </DT> <DD>Recursively sort the entire subtree rooted at <I>node</I>. </DD> <DT><B>-reorder</B> </DT> <DD>Recursively sort subtrees for each node. <B>Warning</B>. Unlike the normal flat sort, where a list of nodes is returned, this will reorder the tree. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>tag</B> <I>args</I> </DT> <DD>Manages tags for the tree object. See the <FONT SIZE=-1><B>TAG OPERATIONS</B></FONT> section below. </DD> <DT><I>treeName</I> <B>trace</B> <I>args</I> </DT> <DD>Manages traces for data fields in the tree object. Traces cause Tcl commands to be executed whenever a data field of a node is created, read, written, or unset. Traces can be set for a specific node or a tag, representing possibly many nodes. See the <FONT SIZE=-1><B>TRACE OPERATIONS</B></FONT> section below. </DD> <DT><I>treeName</I> <B>unset</B> <I>node</I> <I>key</I>... </DT> <DD>Removes one or more data fields from <I>node</I>. <I>Node</I> may be a tag that represents several nodes. <I>Key</I> is the name of the data field to be removed. It's not an error is <I>node</I> does not contain <I>key</I>. This operation may trigger <B>unset</B> data traces. </DD> </DL> </blockquote> <H2><A NAME="sect9" HREF="#toc9">Tag Operations</A></H2> Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. <P> There are two built-in tags: The tag <B>all</B> is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. The tag <B>root</B> is managed automatically by the tree object. It specifies the node that is currently set as the root of the tree. <P> Most tree operations use tags. And several operations let you operate on multiple nodes at once. For example, you can use the <B>set</B> operation with the tag <B>all</B> to set a data field in for all nodes in the tree. <P> Tags are invoked by the <B>tag</B> operation. The general form is <BR> <P> <CODE><I>treeName</I> <B>tag</B> <I>operation</I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for tags are listed below. <DL> <DT><I>treeName</I> <B>tag add</B> <I>string</I> <I>node</I>... </DT> <DD>Adds the tag <I>string</I> to one of more nodes. </DD> <DT><I>treeName</I> <B>tag delete</B> <I>string</I> <I>node</I>... </DT> <DD>Deletes the tag <I>string</I> from one or more nodes. </DD> <DT><I>treeName</I> <B>tag forget</B> <I>string</I> </DT> <DD>Removes the tag <I>string</I> from all nodes. It's not an error if no nodes are tagged as <I>string</I>. </DD> <DT><I>treeName</I> <B>tag names</B> ?<I>node</I>? </DT> <DD>Returns a list of tags used by the tree. If a <I>node</I> argument is present, only those tags used by <I>node</I> are returned. </DD> <DT><I>treeName</I> <B>tag nodes</B> <I>string</I> </DT> <DD>Returns a list of nodes that have the tag <I>string</I>. If no node is tagged as <I>string</I>, then an empty string is returned. </DD> </DL> <H2><A NAME="sect10" HREF="#toc10">Trace Operations</A></H2> Data fields can be traced much in the same way that you can trace Tcl variables. Data traces cause Tcl commands to be executed whenever a particular data field of a node is created, read, written, or unset. A trace can apply to one or more nodes. You can trace a specific node by using its id, or a group of nodes by a their tag. <P> The tree's <B>get</B>, <B>set</B>, and <B>unset</B> operations can trigger various traces. The <B>get</B> operation can cause a <I>read</I> trace to fire. The <B>set</B> operation causes a <I>write</I> trace to fire. And if the data field is written for the first time, you will also get a <I>create</I> trace. The <B>unset</B> operation triggers <I>unset</I> traces. <P> Data traces are invoked by the <B>trace</B> operation. The general form is <BR> <P> <CODE><I>treeName</I> <B>trace</B> <I>operation</I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for traces are listed below. <DL> <DT><I>treeName</I> <B>trace create</B> <I>node</I> <I>key</I> <I>ops</I> <I>command</I> </DT> <DD>Creates a trace for <I>node</I> on data field <I>key</I>. <I>Node</I> can refer to more than one node (for example, the tag <B>all</B>). If <I>node</I> is a tag, any node with that tag can possibly trigger a trace, invoking <I>command</I>. <I>Command</I> is command prefix, typically a procedure name. Whenever a trace is triggered, four arguments are appended to <I>command</I> before it is invoked: <I>treeName</I>, id of the node, <I>key</I> and, <I>ops</I>. Note that no nodes need have the field <I>key</I>. A trace identifier in the form "<I>trace0</I>", "<I>trace1</I>", etc. is returned. <P> <I>Ops</I> indicates which operations are of interest, and consists of one or more of the following letters: <blockquote></DD> <DT><B>r</B> </DT> <DD>Invoke <I>command</I> whenever <I>key</I> is read. Both read and write traces are temporarily disabled when <I>command</I> is executed. </DD> <DT><B>w</B> </DT> <DD>Invoke <I>command</I> whenever <I>key</I> is written. Both read and write traces are temporarily disabled when <I>command</I> is executed. </DD> <DT><B>c</B> </DT> <DD>Invoke <I>command</I> whenever <I>key</I> is created. </DD> <DT><B>u</B> </DT> <DD>Invoke <I>command</I> whenever <I>key</I> is unset. Data fields are typically unset with the <B>unset</B> command. Data fields are also unset when the tree is released, but all traces are disabled prior to that. <P> </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>trace delete</B> <I>traceId</I>... </DT> <DD>Deletes one of more traces. <I>TraceId</I> is the trace identifier returned by the <B>trace create</B> operation. </DD> <DT><I>treeName</I> <B>trace info</B> <I>traceId</I> </DT> <DD>Returns information about the trace <I>traceId</I>. <I>TraceId</I> is a trace identifier previously returned by the <B>trace create</B> operation. It's the same information specified for the <B>trace create</B> operation. It consists of the node id or tag, data field key, a string of letters indicating the operations that are traced (it's in the same form as <I>ops</I>) and, the command prefix. </DD> <DT><I>treeName</I> <B>trace names</B> </DT> <DD>Returns a list of identifers for all the current traces. </DD> </DL> <H2><A NAME="sect11" HREF="#toc11">Notify Operations</A></H2> Tree objects can be shared among many clients, such as a <B>hiertable</B> widget. Any client can create or delete nodes, sorting the tree, etc. You can request to be notified whenever these events occur. Notify events cause Tcl commands to be executed whenever the tree structure is changed. <P> Notifications are handled by the <B>notify</B> operation. The general form is <BR> <P> <CODE><I>treeName</I> <B>notify</B> <I>operation</I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for events are listed below. <DL> <DT><I>treeName</I> <B>notify create</B> ?<I>switches</I>? <I>command</I> ?<I>args</I>?... </DT> <DD>Creates a notifier for the tree. A notify identifier in the form "<I>notify0</I>", "<I>notify1</I>", etc. is returned. <P> <I>Command</I> and <I>args</I> are saved and invoked whenever the tree structure is changed (according to <I>switches</I>). Two arguments are appended to <I>command</I> and <I>args</I> before it's invoked: the id of the node and a string representing the type of event that occured. One of more switches can be set to indicate the events that are of interest. The valid switches are as follows: <blockquote></DD> <DT><B>-create</B> </DT> <DD>Invoke <I>command</I> whenever a new node has been added. </DD> <DT><B>-delete</B> </DT> <DD>Invoke <I>command</I> whenever a node has been deleted. </DD> <DT><B>-move</B> </DT> <DD>Invoke <I>command</I> whenever a node has been moved. </DD> <DT><B>-sort</B> </DT> <DD>Invoke <I>command</I> whenever the tree has been sorted and reordered. </DD> <DT><B>-relabel</B> </DT> <DD>Invoke <I>command</I> whenever a node has been relabeled. </DD> <DT><B>-allevents</B> </DT> <DD>Invoke <I>command</I> whenever any of the above events occur. </DD> <DT><B>-whenidle</B> </DT> <DD>When an event occurs don't invoke <I>command</I> immediately, but queue it to be run the next time the event loop is entered and there are no events to process. If subsequent events occur before the event loop is entered, <I>command</I> will still be invoked only once. </DD> </DL> </blockquote> <DL> <DT><I>treeName</I> <B>notify delete</B> <I>notifyId</I> </DT> <DD>Deletes one or more notifiers from the tree. <I>NotifyId</I> is the notifier identifier returned by the <B>notify create</B> operation. </DD> <DT><I>treeName</I> <B>notify info</B> <I>notifyId</I> </DT> <DD>Returns information about the notify event <I>notifyId</I>. <I>NotifyId</I> is a notify identifier previously returned by the <B>notify create</B> operation. It's the same information specified for the <B>notify create</B> operation. It consists of the notify id, a sublist of event flags (it's in the same form as <I>flags</I>) and, the command prefix. </DD> <DT><I>treeName</I> <B>notify names</B> </DT> <DD>Returns a list of identifers for all the current notifiers. </DD> </DL> <H2><A NAME="sect12" HREF="#toc12">C Language API</A></H2> Blt_TreeApply, Blt_TreeApplyBFS, Blt_TreeApplyDFS, Blt_TreeChangeRoot, Blt_TreeCreate, Blt_TreeCreateEventHandler, Blt_TreeCreateNode, Blt_TreeCreateTrace, Blt_TreeDeleteEventHandler, Blt_TreeDeleteNode, Blt_TreeDeleteTrace, Blt_TreeExists, Blt_TreeFindChild, Blt_TreeFirstChild, Blt_TreeFirstKey, Blt_TreeGetNode, Blt_TreeGetToken, Blt_TreeGetValue, Blt_TreeIsAncestor, Blt_TreeIsBefore, Blt_TreeIsLeaf, Blt_TreeLastChild, Blt_TreeMoveNode, Blt_TreeName, Blt_TreeNextKey, Blt_TreeNextNode, Blt_TreeNextSibling, Blt_TreeNodeDegree, Blt_TreeNodeDepth, Blt_TreeNodeId, Blt_TreeNodeLabel, Blt_TreeNodeParent, Blt_TreePrevNode, Blt_TreePrevSibling, Blt_TreeRelabelNode, Blt_TreeReleaseToken, Blt_TreeRootNode, Blt_TreeSetValue, Blt_TreeSize, Blt_TreeSortNode, and Blt_TreeUnsetValue. <H2><A NAME="sect13" HREF="#toc13">Keywords</A></H2> tree, hiertable, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Syntax</A></LI> <LI><A NAME="toc6" HREF="#sect6">Node IDs and Tags</A></LI> <LI><A NAME="toc7" HREF="#sect7">Node Modifiers</A></LI> <LI><A NAME="toc8" HREF="#sect8">Tree Operations</A></LI> <LI><A NAME="toc9" HREF="#sect9">Tag Operations</A></LI> <LI><A NAME="toc10" HREF="#sect10">Trace Operations</A></LI> <LI><A NAME="toc11" HREF="#sect11">Notify Operations</A></LI> <LI><A NAME="toc12" HREF="#sect12">C Language API</A></LI> <LI><A NAME="toc13" HREF="#sect13">Keywords</A></LI> </UL> </BODY></HTML> ����������������������./saods9/blt3.0.1/html/graph.html�������������������������������������������������������������������0000644�0001750�0001750�00000326562�11462120062�015207� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>graph(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> graph - 2D graph for plotting X-Y coordinate data. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>graph<I> <I>pathName </I></I></B>?<I>option value</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>graph</B> command creates a graph for plotting two-dimensional data (X-Y coordinates). It has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the graph. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>graph</B> command creates a new window for plotting two-dimensional data (X-Y coordinates). Data points are plotted in a rectangular area displayed in the center of the new window. This is the <I>plotting area</I>. The coordinate axes are drawn in the margins around the plotting area. By default, the legend is displayed in the right margin. The title is displayed in top margin. <P> The <B>graph</B> widget is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. <DL> <DT><I>axis</I> </DT> <DD>The graph has four standard axes (<I>x</I>, <I>x2</I>, <I>y</I>, and <I>y2</I>), but you can create and display any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value at each major tick. </DD> <DT><I>crosshairs</I> </DT> <DD>Cross hairs are used to position the mouse pointer relative to the X and Y coordinate axes. Two perpendicular lines, intersecting at the current location of the mouse, extend across the plotting area to the coordinate axes. </DD> <DT><I>element</I> </DT> <DD>An element represents a set of data points. Elements can be plotted with a symbol at each data point and lines connecting the points. The appearance of the element, such as its symbol, line width, and color is configurable. </DD> <DT><I>grid</I> </DT> <DD>Extends the major and minor ticks of the X-axis and/or Y-axis across the plotting area. </DD> <DT><I>legend</I> </DT> <DD>The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. </DD> <DT><I>marker</I> </DT> <DD>Markers are used annotate or highlight areas of the graph. For example, you could use a polygon marker to fill an area under a curve, or a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. </DD> <DT><I>pen</I> </DT> <DD>Pens define attributes (both symbol and line style) for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here, the particular pen used for a data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). </DD> <DT><I>postscript</I> </DT> <DD>The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. </DD> </DL> <H2><A NAME="sect4" HREF="#toc4">Syntax</A></H2> <BR> <P> <CODE><B>graph <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>graph</B> command creates a new window <I>pathName</I> and makes it into a <B>graph</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the graph such as its colors and font. See the <B>configure</B> operation below for the exact details about what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>graph</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the graph. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for the graph are described in the <FONT SIZE=-1><B>GRAPH OPERATIONS</B></FONT> section. <P> The command can also be used to access components of the graph. <BR> <P> <CODE><I>pathName component operation</I> ?<I>arg</I>?...<BR> </CODE><P>The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. <H2><A NAME="sect5" HREF="#toc5">Example</A></H2> The <B>graph</B> command creates a new graph. <BR> <CODE># Create a new graph. Plotting area is black.<BR> graph .g -plotbackground black<BR> </CODE><P>A new Tcl command <I>.g</I> is also created. This command can be used to query and modify the graph. For example, to change the title of the graph to "My Plot", you use the new command and the graph's <B>configure</B> operation. <BR> <CODE># Change the title.<BR> .g configure -title "My Plot"<BR> </CODE><P>A graph has several components. To access a particular component you use the component's name. For example, to add data elements, you use the new command and the <B>element</B> component. <BR> <CODE># Create a new element named "line1"<BR> .g element create line1 \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;155.85 166.60 175.38 }<BR> </CODE><P>The element's X-Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X-Y coordinates. <BR> <CODE># Create two vectors and add them to the graph.<BR> vector xVec yVec<BR> xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }<BR> yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;166.60 175.38 }<BR> .g element create line1 -xdata xVec -ydata yVec<BR> </CODE><P>The advantage of using vectors is that when you modify one, the graph is automatically redrawn to reflect the new values. <BR> <CODE># Change the y coordinate of the first point.<BR> set yVector(0) 25.18<BR> </CODE><P>An element named <I>e1</I> is now created in <I>.b</I>. It is automatically added to the display list of elements. You can use this list to control in what order elements are displayed. To query or reset the element display list, you use the element's <B>show</B> operation. <BR> <CODE># Get the current display list <BR> set elemList [.b element show]<BR> # Remove the first element so it won't be displayed.<BR> .b element show [lrange $elemList 0 end]<BR> </CODE><P>The element will be displayed by as many bars as there are data points (in this case there are ten). The bars will be drawn centered at the x-coordinate of the data point. All the bars will have the same attributes (colors, stipple, etc). The width of each bar is by default one unit. You can change this with using the <B>-barwidth</B> option. <BR> <CODE># Change the X-Y coordinates of the first point.<BR> set xVec(0) 0.18<BR> set yVec(0) 25.18<BR> </CODE><P>An element named <I>line1</I> is now created in <I>.g</I>. By default, the element's label in the legend will be also <I>line1</I>. You can change the label, or specify no legend entry, again using the element's <B>configure</B> operation. <BR> <CODE># Don't display "line1" in the legend.<BR> .g element configure line1 -label ""<BR> </CODE><P>You can configure more than just the element's label. An element has many attributes such as symbol type and size, dashed or solid lines, colors, line width, etc. <BR> <CODE>.g element configure line1 -symbol square -color red \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-dashes { 2 4 2 } -linewidth 2 -pixels 2c<BR> </CODE><P>Four coordinate axes are automatically created: <I>x</I>, <I>x2</I>, <I>y</I>, and <I>y2</I>. And by default, elements are mapped onto the axes <I>x</I> and <I>y</I>. This can be changed with the <B>-mapx</B> and <B>-mapy</B> options. <BR> <CODE># Map "line1" on the alternate Y-axis "y2".<BR> .g element configure line1 -mapy y2<BR> </CODE><P>Axes can be configured in many ways too. For example, you change the scale of the Y-axis from linear to log using the <B>axis</B> component. <BR> <CODE># Y-axis is log scale.<BR> .g axis configure y -logscale yes<BR> </CODE><P>One important way axes are used is to zoom in on a particular data region. Zooming is done by simply specifying new axis limits using the <B>-min</B> and <B>-max</B> configuration options. <BR> <CODE>.g axis configure x -min 1.0 -max 1.5<BR> .g axis configure y -min 12.0 -max 55.15<BR> </CODE><P>To zoom interactively, you link the <B>axis configure</B> operations with some user interaction (such as pressing the mouse button), using the <B>bind</B> command. To convert between screen and graph coordinates, use the <B>invtransform</B> operation. <BR> <CODE># Click the button to set a new minimum <BR> bind .g &lt;ButtonPress-1&gt; { <BR> %W axis configure x -min [%W axis invtransform x %x]<BR> %W axis configure x -min [%W axis invtransform x %y]<BR> }<BR> </CODE><P>By default, the limits of the axis are determined from data values. To reset back to the default limits, set the <B>-min</B> and <B>-max</B> options to the empty value. <BR> <CODE># Reset the axes to autoscale again.<BR> .g axis configure x -min {} -max {}<BR> .g axis configure y -min {} -max {}<BR> </CODE><P>By default, the legend is drawn in the right margin. You can change this or any legend configuration options using the <B>legend</B> component. <BR> <CODE># Configure the legend font, color, and relief<BR> .g legend configure -position left -relief raised \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-font fixed -fg blue<BR> </CODE><P>To prevent the legend from being displayed, turn on the <B>-hide</B> option. <BR> <CODE># Don't display the legend.<BR> .g legend configure -hide yes<BR> </CODE><P>The <B>graph</B> widget has simple drawing procedures called markers. They can be used to highlight or annotate data in the graph. The types of markers available are bitmaps, images, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. In this example, is a text marker that labels the data first point. Markers are created using the <B>marker</B> component. <BR> <CODE># Create a label for the first data point of "line1".<BR> .g marker create text -name first_marker -coords { 0.2 26.18 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-text "start" -anchor se -xoffset -10 -yoffset -10<BR> </CODE><P>This creates a text marker named <I>first_marker</I>. It will display the text "start" near the coordinates of the first data point. The <B>-anchor</B>, <B>-xoffset</B>, and <B>-yoffset</B> options are used to display the marker above and to the left of the data point, so that the data point isn't covered by the marker. By default, markers are drawn last, on top of data. You can change this with the <B>-under</B> option. <BR> <CODE># Draw the label before elements are drawn.<BR> .g marker configure first_marker -under yes<BR> </CODE><P>You can add cross hairs or grid lines using the <B>crosshairs</B> and <B>grid</B> components. <BR> <CODE># Display both cross hairs and grid lines.<BR> .g crosshairs configure -hide no -color red<BR> .g grid configure -hide no -dashes { 2 2 }<BR> # Set up a binding to reposition the crosshairs.<BR> bind .g &lt;Motion&gt; {<BR> .g crosshairs configure -position @%x,%y<BR> }<BR> </CODE><P>The crosshairs are repositioned as the mouse pointer is moved in the graph. The pointer X-Y coordinates define the center of the crosshairs. <P> Finally, to get hardcopy of the graph, use the <B>postscript</B> component. <BR> <CODE># Print the graph into file "file.ps"<BR> .g postscript output file.ps -maxpect yes -decorations no<BR> </CODE><P>This generates a file <I>file.ps</I> containing the encapsulated PostScript of the graph. The option <B>-maxpect</B> says to scale the plot to the size of the page. Turning off the <B>-decorations</B> option denotes that no borders or color backgrounds should be drawn (i.e. the background of the margins, legend, and plotting area will be white). <H2><A NAME="sect6" HREF="#toc6">Graph Operations</A></H2> <DL> <DT><I>pathName <B>axis <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>bar <I>elemName </I></B></I>?<I>option value</I>?... </DT> <DD>Creates a new barchart element <I>elemName</I>. It's an error if an element <I>elemName</I> already exists. See the manual for <B>barchart</B> for details about what <I>option</I> and <I>value</I> pairs are valid. </DD> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the <B>configure</B> operation. </DD> <DT><I>pathName <B>configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the graph. If <I>option</I> isn't specified, a list describing the current options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the option <I>option</I> is set to <I>value</I>. The following options are valid. <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color. This includes the margins and legend, but not the plotting area. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-bottommargin <I>pixels</I></B> </DT> <DD>If non-zero, overrides the computed size of the margin extending below the X-coordinate axis. If <I>pixels</I> is <I>0</I>, the automatically computed size is used. The default is <I>0</I>. </DD> <DT><B>-bufferelements <I>boolean</I></B> </DT> <DD>Indicates whether an internal pixmap to buffer the display of data elements should be used. If <I>boolean</I> is true, data elements are drawn to an internal pixmap. This option is especially useful when the graph is redrawn frequently while the remains data unchanged (for example, moving a marker across the plot). See the <FONT SIZE=-1><B>SPEED TIPS</B></FONT> section. The default is <I>1</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>crosshair</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the graph title. The default is <I>*-Helvetica-Bold-R-Normal-*-18-180-*</I>. </DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a maximum distance to consider when searching for the closest data point (see the element's <B>closest</B> operation below). Data points further than <I>pixels</I> away are ignored. The default is <I>0.5i</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>4i</I>. </DD> <DT><B>-invertxy <I>boolean</I></B> </DT> <DD>Indicates whether the placement X-axis and Y-axis should be inverted. If <I>boolean</I> is true, the X and Y axes are swapped. The default is <I>0</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the title should be justified. This matters only when the title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-leftmargin <I>pixels</I></B> </DT> <DD>If non-zero, overrides the computed size of the margin extending from the left edge of the window to the Y-coordinate axis. If <I>pixels</I> is <I>0</I>, the automatically computed size is used. The default is <I>0</I>. </DD> <DT><B>-plotbackground <I>color</I></B> </DT> <DD>Specifies the background color of the plotting area. The default is <I>white</I>. </DD> <DT><B>-plotborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the plotting area. The <B>-plotrelief</B> option determines if a border is drawn. The default is <I>2</I>. </DD> <DT><B>-plotpadx <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the left and right sides of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotpady <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the top and bottom of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the plotting area. <I>Relief</I> specifies how the interior of the plotting area should appear relative to rest of the graph; for example, <I>raised</I> means the plot should appear to protrude from the graph, relative to the surface of the graph. The default is <I>sunken</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the graph widget. <I>Relief</I> specifies how the graph should appear relative to widget it is packed into; for example, <I>raised</I> means the graph should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-rightmargin <I>pixels</I></B> </DT> <DD>If non-zero, overrides the computed size of the margin extending from the plotting area to the right edge of the window. By default, the legend is drawn in this margin. If <I>pixels</I> is <I>0</I>, the automatically computed size is used. The default is <I>0</I>. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>""</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a tiled background for the widget. If <I>image</I> isn't <I>""</I>, the background is tiled using <I>image</I>. Otherwise, the normal background color is drawn (see the <B>-background</B> option). <I>Image</I> must be an image created using the Tk <B>image</B> command. The default is <I>""</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title to <I>text</I>. If <I>text</I> is <I>""</I>, no title will be displayed. </DD> <DT><B>-topmargin <I>pixels</I></B> </DT> <DD>If non-zero, overrides the computed size of the margin above the x2 axis. If <I>pixels</I> is <I>0</I>, the automatically computed size is used. The default is <I>0</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. The default is <I>5i</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>crosshairs <I>operation </I></B></I>?<I>arg</I>? </DT> <DD>See the <FONT SIZE=-1><B>CROSSHAIRS COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>element <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>ELEMENT COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>extents <I>item</I></B></I> </DT> <DD>Returns the size of a particular item in the graph. <I>Item</I> must be either <I>leftmargin</I>, <I>rightmargin</I>, <I>topmargin</I>, <I>bottommargin</I>, <I>plotwidth</I>, or <I>plotheight</I>. </DD> <DT><I>pathName <B>grid <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>GRID COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>invtransform <I>winX winY</I></B></I> </DT> <DD>Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X-axis and Y-axis. Returns a list of containing the X-Y graph coordinates. </DD> <DT><I>pathName <B>inside <I>x y</I></B></I> </DT> <DD>Returns <I>1</I> is the designated screen coordinate (<I>x</I> and <I>y</I>) is inside the plotting area and <I>0</I> otherwise. </DD> <DT><I>pathName <B>legend <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>LEGEND COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>line<B> operation arg</B></B></I>... </DT> <DD>The operation is the same as <B>element</B>. </DD> <DT><I>pathName <B>marker <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>MARKER COMPONENTS</B></FONT> section. </DD> <DT><I>pathName</I> <B>metafile</B> ?<I>fileName</I>? </DT> <DD><I>This operation is for Window platforms only</I>. Creates a Windows enhanced metafile of the graph. If present, <I>fileName</I> is the file name of the new metafile. Otherwise, the metafile is automatically added to the clipboard. </DD> <DT><I>pathName <B>postscript <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>POSTSCRIPT COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>snap <I>photoName</I></B></I> </DT> <DD>Takes a snapshot of the graph and stores the contents in the photo image <I>photoName</I>. <I>PhotoName</I> is the name of a Tk photo image that must already exist. </DD> <DT><I>pathName <B>transform <I>x y</I></B></I> </DT> <DD>Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X-axis and Y-axis. Returns a list containing the X-Y screen coordinates. </DD> <DT><I>pathName <B>xaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>x2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>yaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>y2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> </DL> <H2><A NAME="sect7" HREF="#toc7">Graph Components</A></H2> A graph is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the graph is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the graph. <H3><A NAME="sect8" HREF="#toc8">Axis Components</A></H3> Four coordinate axes are automatically created: two X-coordinate axes (<I>x</I> and <I>x2</I>) and two Y-coordinate axes (<I>y</I>, and <I>y2</I>). By default, the axis <I>x</I> is located in the bottom margin, <I>y</I> in the left margin, <I>x2</I> in the top margin, and <I>y2</I> in the right margin. <P> An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. <P> The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. <P> You can have several axes. To create an axis, invoke the axis component and its create operation. <BR> <CODE># Create a new axis called "tempAxis"<BR> .g axis create tempAxis<BR> </CODE><P>You map data elements to an axis using the element's -mapy and -mapx configuration options. They specify the coordinate axes an element is mapped onto. <BR> <CODE># Now map the tempAxis data to this axis.<BR> .g element create "e1" -xdata $x -ydata $y -mapy tempAxis<BR> </CODE><P>Any number of axes can be displayed simultaneously. They are drawn in the margins surrounding the plotting area. The default axes <I>x</I> and <I>y</I> are drawn in the bottom and left margins. The axes <I>x2</I> and <I>y2</I> are drawn in top and right margins. By default, only <I>x</I> and <I>y</I> are shown. Note that the axes can have different scales. <P> To display a different axis or more than one axis, you invoke one of the following components: <B>xaxis</B>, <B>yaxis</B>, <B>x2axis</B>, and <B>y2axis</B>. Each component has a <B>use</B> operation that designates the axis (or axes) to be drawn in that corresponding margin: <B>xaxis</B> in the bottom, <B>yaxis</B> in the left, <B>x2axis</B> in the top, and <B>y2axis</B> in the right. <BR> <CODE># Display the axis tempAxis in the left margin.<BR> .g yaxis use tempAxis<BR> </CODE><P>The <B>use</B> operation takes a list of axis names as its last argument. This is the list of axes to be drawn in this margin. <P> You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label any way you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. <P> <DL> <DT><I>pathName <B>axis bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an axis with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on graph axes, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>axis <B>cget <I>axisName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>axisName</I>. <I>Option</I> may be any option described below for the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>configure <I>axisName </I></B></B></I>?<I>axisName</I>?... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>axisName</I>. Several axes can be changed. If <I>option</I> isn't specified, a list describing all the current options for <I>axisName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the axis option <I>option</I> is set to <I>value</I>. The following options are valid for axes. <blockquote></DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for the axis. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events for axes are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the axis and tick labels. The default is <I>black</I>. </DD> <DT><B>-command <I>prefix</I></B> </DT> <DD>Specifies a Tcl command to be invoked when formatting the axis tick labels. <I>Prefix</I> is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If <I>""</I> is returned, no label will appear next to the tick. You can get the standard tick labels again by setting <I>prefix</I> to <I>""</I>. The default is <I>""</I>. <P> Please note that this procedure is invoked while the graph is redrawn. You may query configuration options. But do not them, because this can have unexpected results. </DD> <DT><B>-descending <I>boolean</I></B> </DT> <DD>Indicates whether the values along the axis are monotonically increasing or decreasing. If <I>boolean</I> is true, the axis values will be decreasing. The default is <I>0</I>. </DD> <DT><B>-hide <I>string</I></B> </DT> <DD>Indicates if the axis and all the elements mapped to it will be displayed. The valid values for <I>string</I> are shown below. The default value is <I>0</I>. <blockquote></DD> <DT><I>false</I> </DT> <DD>The axis and its data elements are displayed. </DD> <DT><I>true</I> </DT> <DD>The axis is hidden, but the data elements mapped to it are displayed. </DD> <DT><I>all</I> </DT> <DD>The axis and its data elements are hidden. </DD> </DL> </blockquote> <DL> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-limits <I>formatStr</I></B> </DT> <DD>Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. <I>FormatStr</I> is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If <I>""</I> is given as either description, then the that limit will not be displayed. The default is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the axis and tick lines. The default is <I>1</I> pixel. </DD> <DT><B>-logscale <I>boolean</I></B> </DT> <DD>Indicates whether the scale of the axis is logarithmic or linear. If <I>boolean</I> is true, the axis is logarithmic. The default scale is linear. </DD> <DT><B>-loose <I>boolean</I></B> </DT> <DD>Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. If the axis limit is set with the -min or -max option, the axes are displayed tightly. If <I>boolean</I> is true, the axis range is "loose". The default is <I>0</I>. </DD> <DT><B>-majorticks <I>majorList</I></B> </DT> <DD>Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. <I>MajorList</I> is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If <I>majorList</I> is <I>""</I>, major ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-max <I>value</I></B> </DT> <DD>Sets the maximum limit of <I>axisName</I>. Any data point greater than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the maximum limit is calculated using the largest data value. The default is <I>""</I>. </DD> <DT><B>-min <I>value</I></B> </DT> <DD>Sets the minimum limit of <I>axisName</I>. Any data point less than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the minimum limit is calculated using the smallest data value. The default is <I>""</I>. </DD> <DT><B>-minorticks <I>minorList</I></B> </DT> <DD>Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. <I>MinorList</I> is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the <B>-majortick</B> option is also set. If <I>minorList</I> is <I>""</I>, minor ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the how many degrees to rotate the axis tick labels. <I>Theta</I> is a real value representing the number of degrees to rotate the tick labels. The default is <I>0.0</I> degrees. </DD> <DT><B>-showticks <I>boolean</I></B> </DT> <DD>Indicates whether axis ticks should be drawn. If <I>boolean</I> is true, ticks are drawn. If false, only the axis line is drawn. The default is <I>1</I>. </DD> <DT><B>-stepsize <I>value</I></B> </DT> <DD>Specifies the interval between major axis ticks. If <I>value</I> isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. </DD> <DT><B>-subdivisions <I>number</I></B> </DT> <DD>Indicates how many minor axis ticks are to be drawn. For example, if <I>number</I> is two, only one minor tick is drawn. If <I>number</I> is one, no minor ticks are displayed. The default is <I>2</I>. </DD> <DT><B>-tickfont <I>fontName</I></B> </DT> <DD>Specifies the font for axis tick labels. The default is <I>*-Courier-Bold-R-Normal-*-100-*</I>. </DD> <DT><B>-ticklength <I>pixels</I></B> </DT> <DD>Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If <I>pixels</I> is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is <I>0.1i</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title of the axis. If <I>text</I> is <I>""</I>, no axis title will be displayed. </DD> <DT><B>-titlecolor <I>color</I></B> </DT> <DD>Sets the color of the axis title. The default is <I>black</I>. </DD> <DT><B>-titlefont <I>fontName</I></B> </DT> <DD>Specifies the font for axis title. The default is <I>*-Helvetica-Bold-R-Normal-*-14-140-*</I>. </DD> </DL> <P> Axis configuration options may be also be set by the <B>option</B> command. The resource class is <I>Axis</I>. The resource names are the names of the axes (such as <I>x</I> or <I>x2</I>). <BR> <CODE>option add *Graph.Axis.Color blue<BR> option add *Graph.x.LogScale true<BR> option add *Graph.x2.LogScale false<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>axis <B>create <I>axisName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new axis by the name <I>axisName</I>. No axis by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>delete </B></B></I>?<I>axisName</I>?... </DT> <DD>Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. </DD> <DT><I>pathName <B>axis invtransform <I>axisName value</I></B></I> </DT> <DD>Performs the inverse transformation, changing the screen coordinate <I>value</I> to a graph coordinate, mapping the value mapped to <I>axisName</I>. Returns the graph coordinate. </DD> <DT><I>pathName <B>axis limits <I>axisName</I></B></I> </DT> <DD>Returns a list of the minimum and maximum limits for <I>axisName</I>. The order of the list is <I>min max</I>. </DD> <DT><I>pathName <B>axis names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of axes matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all axes are returned. </DD> <DT><I>pathName <B>axis transform <I>axisName value</I></B></I> </DT> <DD>Transforms the coordinate <I>value</I> to a screen coordinate by mapping the it to <I>axisName</I>. Returns the transformed screen coordinate. </DD> </DL> <P> The default axes are <I>x</I>, <I>y</I>, <I>x2</I>, and <I>y2</I>. But you can display more than four axes simultaneously. You can also swap in a different axis with <B>use</B> operation of the special axis components: <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B>. <BR> <CODE>.g create axis temp<BR> .g create axis time<BR> ...<BR> .g xaxis use temp<BR> .g yaxis use time<BR> </CODE><P>Only the axes specified for use are displayed on the screen. <P> The <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B> components operate on an axis location rather than a specific axis like the more general <B>axis</B> component does. They implicitly control the axis that is currently using to that location. By default, <B>xaxis</B> uses the <I>x</I> axis, <B>yaxis</B> uses <I>y</I>, <B>x2axis</B> uses <I>x2</I>, and <B>y2axis</B> uses <I>y2</I>. When more than one axis is displayed in a margin, it represents the first axis displayed. <P> The following operations are available for axes. They mirror exactly the operations of the <B>axis</B> component. The <I>axis</I> argument must be <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, or <B>y2axis</B>. This feature is deprecated since more than one axis can now be used a margin. You should only use the <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B> components with the <B>use</B> operation. For all other operations, use the general <B>axis</B> component instead. <DL> <DT><I>pathName <I>axis <B>cget <I>option</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>configure </B></I></I>?<I>option value</I>?... </DT> <DD></DD> <DT><I>pathName <I>axis<B> invtransform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>limits</B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> transform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> use </B></I></I>?<I>axisName</I>? </DT> <DD>Designates the axis <I>axisName</I> is to be displayed at this location. <I>AxisName</I> can not be already in use at another location. This command returns the name of the axis currently using this location. </DD> </DL> <H3><A NAME="sect9" HREF="#toc9">Crosshairs Component</A></H3> Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire graph. <P> The following operations are available for cross hairs: <DL> <DT><I>pathName <B>crosshairs cget <I>option</I></B></I> </DT> <DD>Returns the current value of the cross hairs configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the cross hairs <B>configure</B> operation. </DD> <DT><I>pathName <B>crosshairs configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the cross hairs. If <I>option</I> isn't specified, a list describing all the current options for the cross hairs is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the cross hairs option <I>option</I> is set to <I>value</I>. The following options are available for cross hairs. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the cross hairs. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the cross hairs. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the cross hairs will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether cross hairs are drawn. If <I>boolean</I> is true, cross hairs are not drawn. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the cross hair lines. The default is <I>1</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies the screen position where the cross hairs intersect. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates of the intersection. </DD> </DL> <P> Cross hairs configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>crosshairs</I> and <I>Crosshairs</I> respectively. <BR> <CODE>option add *Graph.Crosshairs.LineWidth 2<BR> option add *Graph.Crosshairs.Color red<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>crosshairs off</B></I> </DT> <DD>Turns off the cross hairs. </DD> <DT><I>pathName <B>crosshairs on</B></I> </DT> <DD>Turns on the display of the cross hairs. </DD> <DT><I>pathName <B>crosshairs toggle</B></I> </DT> <DD>Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. </DD> </DL> <H3><A NAME="sect10" HREF="#toc10">Element Components</A></H3> A data element represents a set of data. It contains x and y vectors containing the coordinates of the data points. Elements can be displayed with a symbol at each data point and lines connecting the points. Elements also control the appearance of the data, such as the symbol type, line width, color etc. <P> When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. <P> The following operations are available for elements. <DL> <DT><I>pathName <B>element activate <I>elemName </I></B></I>?<I>index</I>?... </DT> <DD>Specifies the data points of element <I>elemName</I> to be drawn using active foreground and background colors. <I>ElemName</I> is the name of the element and <I>index</I> is a number representing the index of the data point. If no indices are present then all data points become active. </DD> <DT><I>pathName <B>element bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an element with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on graph elements, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>element cget <I>elemName <I>option</I></I></B></I> </DT> <DD>Returns the current value of the element configuration option given by <I>option</I>. <I>Option</I> may be any of the options described below for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element closest <I>x y</I></B></I> <I>varName</I> ?<I>option value</I>?... ?<I>elemName</I>?... </DT> <DD>Finds the data point closest to the window coordinates <I>x</I> and <I>y</I> in the element <I>elemName</I>. <I>ElemName</I> is the name of an element, that must not be hidden. If no elements are specified, then all visible elements are searched. It returns via the array variable <I>varName</I> the name of the closest element, the index of its closest point, and the graph coordinates of the point. Returns <I>0</I>, if no data point within the threshold distance can be found, otherwise <I>1</I> is returned. The following <I>option</I>-<I>value</I> pairs are available. <blockquote></DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a threshold distance where selected data points are ignored. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. If this option isn't specified, then it defaults to the value of the graph's <B>-halo</B> option. </DD> <DT><B>-interpolate <I>string</I></B> </DT> <DD>Indicates whether to consider projections that lie along the line segments connecting data points when searching for the closest point. The default value is <I>0</I>. The values for <I>string</I> are described below. <blockquote></DD> <DT><I>no</I> </DT> <DD>Search only for the closest data point. </DD> <DT><I>yes</I> </DT> <DD>Search includes projections that lie along the line segments connecting the data points. </DD> <DT><I>x</I> </DT> <DD>Search includes vertical projections from the given X-coordinate. </DD> <DT><I>y</I> </DT> <DD>Search includes horizontal projections from the given Y-coordinate. </DD> </DL> </blockquote> </blockquote> <DL> <DT><I>pathName <B>element configure <I>elemName </I></B></I>?<I>elemName</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for elements. Several elements can be modified at the same time. If <I>option</I> isn't specified, a list describing all the current options for <I>elemName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing the option <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the element option <I>option</I> is set to <I>value</I>. The following options are valid for elements. <blockquote></DD> <DT><B>-activepen <I>penName</I></B> </DT> <DD>Specifies pen to use to draw active element. If <I>penName</I> is <I>""</I>, no active elements will be drawn. The default is <I>activeLine</I>. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for the element. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events are handled for elements. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the traces connecting the data points. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of element line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the lines will be solid. </DD> <DT><B>-data <I>coordList</I></B> </DT> <DD>Specifies the X-Y coordinates of the data. <I>CoordList</I> is a list of numeric expressions representing the X-Y coordinate pairs of each data point. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the interior color of symbols. If <I>color</I> is <I>""</I>, then the interior of the symbol is transparent. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the element is displayed. The default is <I>no</I>. </DD> <DT><B>-label <I>text</I></B> </DT> <DD>Sets the element's label in the legend. If <I>text</I> is <I>""</I>, the element will have no entry in the legend. The default label is the element's name. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the connecting lines between data points. If <I>pixels</I> is <I>0</I>, no connecting lines will be drawn between symbols. The default is <I>0</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Selects the X-axis to map the element's X-coordinates onto. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Selects the Y-axis to map the element's Y-coordinates onto. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-offdash <I>color</I></B> </DT> <DD>Sets the color of the stripes when traces are dashed (see the <B>-dashes</B> option). If <I>color</I> is <I>""</I>, then the "off" pixels will represent gaps instead of stripes. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color or the outline around each symbol. If <I>color</I> is <I>""</I>, then no outline is drawn. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outlinewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline bordering each symbol. If <I>pixels</I> is <I>0</I>, no outline will be drawn. The default is <I>1</I>. </DD> <DT><B>-pixels <I>pixels</I></B> </DT> <DD>Sets the size of symbols. If <I>pixels</I> is <I>0</I>, no symbols will be drawn. The default is <I>0.125i</I>. </DD> <DT><B>-scalesymbols <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the size of the symbols drawn for <I>elemName</I> will change with scale of the X-axis and Y-axis. At the time this option is set, the current ranges of the axes are saved as the normalized scales (i.e scale factor is 1.0) and the element is drawn at its designated size (see the <B>-pixels</B> option). As the scale of the axes change, the symbol will be scaled according to the smaller of the X-axis and Y-axis scales. If <I>boolean</I> is false, the element's symbols are drawn at the designated size, regardless of axis scales. The default is <I>0</I>. </DD> <DT><B>-smooth <I>smooth</I></B> </DT> <DD>Specifies how connecting line segments are drawn between data points. <I>Smooth</I> can be either <I>linear</I>, <I>step</I>, <I>natural</I>, or <I>quadratic</I>. If <I>smooth</I> is <I>linear</I>, a single line segment is drawn, connecting both data points. When <I>smooth</I> is <I>step</I>, two line segments are drawn. The first is a horizontal line segment that steps the next X-coordinate. The second is a vertical line, moving to the next Y-coordinate. Both <I>natural</I> and <I>quadratic</I> generate multiple segments between data points. If <I>natural</I>, the segments are generated using a cubic spline. If <I>quadratic</I>, a quadratic spline is used. The default is <I>linear</I>. </DD> <DT><B>-styles <I>styleList</I></B> </DT> <DD>Specifies what pen to use based on the range of weights given. <I>StyleList</I> is a list of style specifications. Each style specification, in turn, is a list consisting of a pen name, and optionally a minimum and maximum range. Data points whose weight (see the <B>-weight</B> option) falls in this range, are drawn with this pen. If no range is specified it defaults to the index of the pen in the list. Note that this affects only symbol attributes. Line attributes, such as line width, dashes, etc. are ignored. </DD> <DT><B>-symbol <I>symbol</I></B> </DT> <DD>Specifies the symbol for data points. <I>Symbol</I> can be either <I>square</I>, <I>circle</I>, <I>diamond</I>, <I>plus</I>, <I>cross</I>, <I>splus</I>, <I>scross</I>, <I>triangle</I>, <I>""</I> (where no symbol is drawn), or a bitmap. Bitmaps are specified as "<I>source</I> ?<I>mask</I>?", where <I>source</I> is the name of the bitmap, and <I>mask</I> is the bitmap's optional mask. The default is <I>circle</I>. </DD> <DT><B>-trace <I>direction</I></B> </DT> <DD>Indicates whether connecting lines between data points (whose X-coordinate values are either increasing or decreasing) are drawn. <I>Direction</I> must be <I>increasing</I>, <I>decreasing</I>, or <I>both</I>. For example, if <I>direction</I> is <I>increasing</I>, connecting lines will be drawn only between those data points where X-coordinate values are monotonically increasing. If <I>direction</I> is <I>both</I>, connecting lines will be draw between all data points. The default is <I>both</I>. </DD> <DT><B>-weights <I>wVec</I></B> </DT> <DD>Specifies the weights of the individual data points. This, with the list pen styles (see the <B>-styles</B> option), controls how data points are drawn. <I>WVec</I> is the name of a BLT vector or a list of numeric expressions representing the weights for each data point. </DD> <DT><B>-xdata <I>xVec</I></B> </DT> <DD>Specifies the X-coordinates of the data. <I>XVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> <DT><B>-ydata <I>yVec</I></B> </DT> <DD>Specifies the Y-coordinates of the data. <I>YVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> </DL> <P> Element configuration options may also be set by the <B>option</B> command. The resource class is <I>Element</I>. The resource name is the name of the element. <BR> <CODE>option add *Graph.Element.symbol line<BR> option add *Graph.e1.symbol line<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>element create <I>elemName</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a new element <I>elemName</I>. It's an error is an element <I>elemName</I> already exists. If additional arguments are present, they specify options valid for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element deactivate <I>elemName</I></B></I> ?<I>elemName</I>?... </DT> <DD>Deactivates all the elements matching <I>pattern</I>. Elements whose names match any of the patterns given are redrawn using their normal colors. </DD> <DT><I>pathName <B>element delete</B></I> ?<I>elemName</I>?... </DT> <DD>Deletes all the named elements. The graph is automatically redrawn. </DD> <DT><I>pathName <B>element exists <I>elemName</I></B></I> </DT> <DD>Returns <I>1</I> if an element <I>elemName</I> currently exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>element names </B></I>?<I>pattern</I>?... </DT> <DD>Returns the elements matching one or more pattern. If no <I>pattern</I> is given, the names of all elements is returned. </DD> <DT><I>pathName <B>element show</B></I> ?<I>nameList</I>? </DT> <DD>Queries or modifies the element display list. The element display list designates the elements drawn and in what order. <I>NameList</I> is a list of elements to be displayed in the order they are named. If there is no <I>nameList</I> argument, the current display list is returned. </DD> <DT><I>pathName <B>element type</B></I> <I>elemName</I> </DT> <DD>Returns the type of <I>elemName</I>. If the element is a bar element, the commands returns the string <I>"bar"</I>, otherwise it returns <I>"line"</I>. </DD> </DL> <H3><A NAME="sect11" HREF="#toc11"></CODE><P>Grid Component</A></H3> Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. <DL> <DT><I>pathName <B>grid cget <I>option</I></B></I> </DT> <DD>Returns the current value of the grid line configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the grid <B>configure</B> operation. </DD> <DT><I>pathName <B>grid configure</B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for grid lines. If <I>option</I> isn't specified, a list describing all the current grid options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the grid line option <I>option</I> is set to <I>value</I>. The following options are valid for grid lines. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the grid lines. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the grid lines. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the grid will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the grid should be drawn. If <I>boolean</I> is true, grid lines are not shown. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of grid lines. The default width is <I>1</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to display grid lines. <I>XAxis</I> must be the name of an axis or <I>""</I> for no grid lines. The default is <I>""</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to display grid lines. <I>YAxis</I> must be the name of an axis or <I>""</I> for no grid lines. The default is <I>y</I>. </DD> <DT><B>-minor <I>boolean</I></B> </DT> <DD>Indicates whether the grid lines should be drawn for minor ticks. If <I>boolean</I> is true, the lines will appear at minor tick intervals. The default is <I>1</I>. </DD> </DL> <P> Grid configuration options may also be set by the <B>option</B> command. The resource name and class are <I>grid</I> and <I>Grid</I> respectively. <BR> <CODE>option add *Graph.grid.LineWidth 2<BR> option add *Graph.Grid.Color black<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>grid off</B></I> </DT> <DD>Turns off the display the grid lines. </DD> <DT><I>pathName <B>grid on</B></I> </DT> <DD>Turns on the display the grid lines. </DD> <DT><I>pathName <B>grid toggle</B></I> </DT> <DD>Toggles the display of the grid. </DD> </DL> <H3><A NAME="sect12" HREF="#toc12">Legend Component</A></H3> The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. <P> The following operations are valid for the legend. <DL> <DT><I>pathName <B>legend activate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a legend entry with this tag, <I>command</I> will be invoked. Implicitly the element names in the entry are tags. The syntax is similar to the <B>bind</B> command except that it operates on legend entries, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>legend cget <I>option</I></B></I> </DT> <DD>Returns the current value of a legend configuration option. <I>Option</I> may be any option described below in the legend <B>configure</B> operation. </DD> <DT><I>pathName <B>legend configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for the legend. If <I>option</I> isn't specified, a list describing the current legend options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the legend option <I>option</I> is set to <I>value</I>. The following options are valid for the legend. <blockquote></DD> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active legend entries. All legend entries marked active (see the legend <B>activate</B> operation) are drawn using this background color. </DD> <DT><B>-activeborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the active legend entries. The default is <I>2</I>. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color for active legend entries. All legend entries marked as active (see the legend <B>activate</B> operation) are drawn using this foreground color. </DD> <DT><B>-activerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect desired for active legend entries. <I>Relief</I> denotes how the interior of the entry should appear relative to the legend; for example, <I>raised</I> means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is <I>flat</I>. </DD> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the <B>-position</B> option. The default is <I>center</I>. <blockquote></DD> <DT><I>left</I> or <I>right</I> </DT> <DD>The anchor describes how to position the legend vertically. </DD> <DT><I>top</I> or <I>bottom</I> </DT> <DD>The anchor describes how to position the legend horizontally. </DD> <DT><I>@x,y</I> </DT> <DD>The anchor specifies how to position the legend relative to the positioning point. For example, if <I>anchor</I> is <I>center</I> then the legend is centered on the point; if <I>anchor</I> is <I>n</I> then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. </DD> <DT><I>plotarea</I> </DT> <DD>The anchor specifies how to position the legend relative to the plotting area. For example, if <I>anchor</I> is <I>center</I> then the legend is centered in the plotting area; if <I>anchor</I> is <I>ne</I> then the legend will be drawn such that occupies the upper right corner of the plotting area. </DD> </DL> </blockquote> <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the legend. If <I>color</I> is <I>""</I>, the legend background with be transparent. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for legend entries. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events are handled for legend entries. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is <I>all</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the <B>relief</B> option determines this). The default is <I>2</I> pixels. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD><I>FontName</I> specifies a font to use when drawing the labels of each element into the legend. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of the text drawn for the element's label. The default is <I>black</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the legend should be displayed. If <I>boolean</I> is true, the legend will not be draw. The default is <I>no</I>. </DD> <DT><B>-ipadx <I>pad</I></B> </DT> <DD>Sets the amount of internal padding to be added to the width of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-ipady <I>pad</I></B> </DT> <DD>Sets an amount of internal padding to be added to the height of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the entry is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom of the entry are padded evenly. The default is <I>2</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the legend is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>0</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies where the legend is drawn. The <B>-anchor</B> option also affects where the legend is positioned. If <I>pos</I> is <I>left</I>, <I>left</I>, <I>top</I>, or <I>bottom</I>, the legend is drawn in the specified margin. If <I>pos</I> is <I>plotarea</I>, then the legend is drawn inside the plotting area at a particular anchor. If <I>pos</I> is in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is <I>right</I>. </DD> <DT><B>-raised <I>boolean</I></B> </DT> <DD>Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If <I>boolean</I> is true, the legend will be drawn on top of any elements that may overlap it. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the border around the legend. <I>Relief</I> specifies how the interior of the legend should appear relative to the graph; for example, <I>raised</I> means the legend should appear to protrude from the graph, relative to the surface of the graph. The default is <I>sunken</I>. </DD> </DL> <P> Legend configuration options may also be set by the <B>option</B> command. The resource name and class are <I>legend</I> and <I>Legend</I> respectively. <BR> <CODE>option add *Graph.legend.Foreground blue<BR> option add *Graph.Legend.Relief raised<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>legend deactivate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend get <I>pos</I></B></I> </DT> <DD>Returns the name of the element whose entry is at the screen position <I>pos</I> in the legend. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are window coordinates. If the given coordinates do not lie over a legend entry, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect13" HREF="#toc13">Pen Components</A></H3> Pens define attributes (both symbol and line style) for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). <P> One pen, called <I>activeLine</I>, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. <BR> <CODE>.g pen configure "activeLine" -color green<BR> </CODE><P>You can create and use several pens. To create a pen, invoke the pen component and its create operation. <BR> <CODE>.g pen create myPen<BR> </CODE><P>You map pens to a data element using either the element's <B>-pen</B> or <B>-activepen</B> options. <BR> <CODE>.g element create "line1" -xdata $x -ydata $tempData \<BR> -pen myPen<BR> </CODE><P>An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the <B>-styles</B> option). <BR> <CODE>.g element configure "line1" -styles { myPen 2.0 3.0 }<BR> </CODE><P>This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen <I>myPen</I>. All other points are drawn with the element's default attributes. <P> The following operations are available for pen components. <P> <DL> <DT><I>pathName <B>pen <B>cget <I>penName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>penName</I>. <I>Option</I> may be any option described below for the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>configure <I>penName </I></B></B></I>?<I>penName</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>penName</I>. Several pens can be modified at once. If <I>option</I> isn't specified, a list describing the current options for <I>penName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the pen option <I>option</I> is set to <I>value</I>. The following options are valid for pens. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the traces connecting the data points. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of element line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the lines will be solid. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the interior color of symbols. If <I>color</I> is <I>""</I>, then the interior of the symbol is transparent. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the connecting lines between data points. If <I>pixels</I> is <I>0</I>, no connecting lines will be drawn between symbols. The default is <I>0</I>. </DD> <DT><B>-offdash <I>color</I></B> </DT> <DD>Sets the color of the stripes when traces are dashed (see the <B>-dashes</B> option). If <I>color</I> is <I>""</I>, then the "off" pixels will represent gaps instead of stripes. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color or the outline around each symbol. If <I>color</I> is <I>""</I>, then no outline is drawn. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outlinewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline bordering each symbol. If <I>pixels</I> is <I>0</I>, no outline will be drawn. The default is <I>1</I>. </DD> <DT><B>-pixels <I>pixels</I></B> </DT> <DD>Sets the size of symbols. If <I>pixels</I> is <I>0</I>, no symbols will be drawn. The default is <I>0.125i</I>. </DD> <DT><B>-symbol <I>symbol</I></B> </DT> <DD>Specifies the symbol for data points. <I>Symbol</I> can be either <I>square</I>, <I>circle</I>, <I>diamond</I>, <I>plus</I>, <I>cross</I>, <I>splus</I>, <I>scross</I>, <I>triangle</I>, <I>""</I> (where no symbol is drawn), or a bitmap. Bitmaps are specified as "<I>source</I> ?<I>mask</I>?", where <I>source</I> is the name of the bitmap, and <I>mask</I> is the bitmap's optional mask. The default is <I>circle</I>. </DD> <DT><B>-type <I>elemType</I></B> </DT> <DD>Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "line". </DD> </DL> <P> Pen configuration options may be also be set by the <B>option</B> command. The resource class is <I>Pen</I>. The resource names are the names of the pens. <BR> <CODE>option add *Graph.Pen.Color blue<BR> option add *Graph.activeLine.color green<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>pen <B>create <I>penName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new pen by the name <I>penName</I>. No pen by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>delete </B></B></I>?<I>penName</I>?... </DT> <DD>Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. </DD> <DT><I>pathName <B>pen names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of pens matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all pens are returned. </DD> </DL> <H3><A NAME="sect14" HREF="#toc14">PostScript Component</A></H3> The graph can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot will be generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. <P> The following postscript operations are available. <DL> <DT><I>pathName <B>postscript cget <I>option</I></B></I> </DT> <DD>Returns the current value of the postscript option given by <I>option</I>. <I>Option</I> may be any option described below for the postscript <B>configure</B> operation. </DD> <DT><I>pathName <B>postscript configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for PostScript generation. If <I>option</I> isn't specified, a list describing the current postscript options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the postscript option <I>option</I> is set to <I>value</I>. The following postscript options are available. <blockquote></DD> <DT><B>-center <I>boolean</I></B> </DT> <DD>Indicates whether the plot should be centered on the PostScript page. If <I>boolean</I> is false, the plot will be placed in the upper left corner of the page. The default is <I>1</I>. </DD> <DT><B>-colormap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of <I>varName</I> must consist of PostScript code to set a particular color value (e.g. ``<I>1.0 1.0 0.0 setrgbcolor</I>''). When generating color information in PostScript, the array variable <I>varName</I> is checked if an element of the name as the color exists. If so, it uses its value as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in <I>varName</I> for a given color, then it uses the red, green, and blue intensities from the X color. </DD> <DT><B>-colormode <I>mode</I></B> </DT> <DD>Specifies how to output color information. <I>Mode</I> must be either <I>color</I> (for full color output), <I>gray</I> (convert all colors to their gray-scale equivalents) or <I>mono</I> (convert foreground colors to black and background colors to white). The default mode is <I>color</I>. </DD> <DT><B>-fontmap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of <I>varName</I> must consist of a Tcl list with one or two elements; the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable <I>varName</I> is checked to see if an element by the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is <I>Adobe</I> (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to <I>Helvetica-Bold</I>. </DD> <DT><B>-decorations <I>boolean</I></B> </DT> <DD>Indicates whether PostScript commands to generate color backgrounds and 3-D borders will be output. If <I>boolean</I> is false, the background will be white and no 3-D borders will be generated. The default is <I>1</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Sets the height of the plot. This lets you print the graph with a height different from the one drawn on the screen. If <I>pixels</I> is 0, the height is the same as the widget's height. The default is <I>0</I>. </DD> <DT><B>-landscape <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to <I>0</I>. </DD> <DT><B>-maxpect <I>boolean</I></B> </DT> <DD>Indicates to scale the plot so that it fills the PostScript page. The aspect ratio of the graph is still retained. The default is <I>0</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left border is padded by the first distance and the right border by the second. If <I>pad</I> has just one distance, both the left and right borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top border is padded by the first distance and the bottom border by the second. If <I>pad</I> has just one distance, both the top and bottom borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-paperheight <I>pixels</I></B> </DT> <DD>Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is <I>11.0i</I>. </DD> <DT><B>-paperwidth <I>pixels</I></B> </DT> <DD>Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is <I>8.5i</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the width of the plot. This lets you generate a plot of a width different from that of the widget. If <I>pixels</I> is 0, the width is the same as the widget's width. The default is <I>0</I>. </DD> </DL> <P> Postscript configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>postscript</I> and <I>Postscript</I> respectively. <BR> <CODE>option add *Graph.postscript.Decorations false<BR> option add *Graph.Postscript.Landscape true<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>postscript output </B></I>?<I>fileName</I>? ?<I>option value</I>?... </DT> <DD>Outputs a file of encapsulated PostScript. If a <I>fileName</I> argument isn't present, the command returns the PostScript. If any <I>option-value</I> pairs are present, they set configuration options controlling how the PostScript is generated. <I>Option</I> and <I>value</I> can be anything accepted by the postscript <B>configure</B> operation above. </DD> </DL> <H3><A NAME="sect15" HREF="#toc15">Marker Components</A></H3> Markers are simple drawing procedures used to annotate or highlight areas of the graph. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the <B>-under</B> option. <P> Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have <I>elastic</I> coordinates (specified by <I>-Inf</I> and <I>Inf</I> respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates <I>-Inf</I>,<I>-Inf</I>. <P> The following operations are available for markers. <DL> <DT><I>pathName <B>marker after <I>markerId</I></B></I> ?<I>afterId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker after the second. If no second <I>afterId</I> argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker before <I>markerId</I></B></I> ?<I>beforeId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker before the second. If no second <I>beforeId</I> argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a marker with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on graph markers, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>marker cget <I>option</I></B></I> </DT> <DD>Returns the current value of the marker configuration option given by <I>option</I>. <I>Option</I> may be any option described below in the <B>configure</B> operation. </DD> <DT><I>pathName <B>marker configure <I>markerId</I></B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for markers. If <I>option</I> isn't specified, a list describing the current options for <I>markerId</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the marker option <I>option</I> is set to <I>value</I>. <P> The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. <blockquote></DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for the marker. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events for markers are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the marker is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-coords <I>coordList</I></B> </DT> <DD>Specifies the coordinates of the marker. <I>CoordList</I> is a list of graph coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If <I>coordList</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-element <I>elemName</I></B> </DT> <DD>Links the marker with the element <I>elemName</I>. The marker is drawn only if the element is also currently displayed (see the element's <B>show</B> operation). If <I>elemName</I> is <I>""</I>, the marker is always drawn. The default is <I>""</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn. If <I>boolean</I> is true, the marker is not drawn. The default is <I>no</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to map the marker's X-coordinates onto. <I>XAxis</I> must the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to map the marker's Y-coordinates onto. <I>YAxis</I> must the name of an axis. The default is <I>y</I>. </DD> <DT><B>-name <I>markerId</I></B> </DT> <DD>Changes the identifier for the marker. The identifier <I>markerId</I> can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. </DD> <DT><B>-under <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn below/above data elements. If <I>boolean</I> is true, the marker is be drawn underneath the data element symbols and lines. Otherwise, the marker is drawn on top of the element. The default is <I>0</I>. </DD> <DT><B>-xoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the marker horizontally. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> <DT><B>-yoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the markers vertically. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> </DL> <P> Marker configuration options may also be set by the <B>option</B> command. The resource class is either <I>BitmapMarker</I>, <I>ImageMarker</I>, <I>LineMarker</I>, <I>PolygonMarker</I>, <I>TextMarker</I>, or <I>WindowMarker</I>, depending on the type of marker. The resource name is the name of the marker. <BR> <CODE>option add *Graph.TextMarker.Foreground white<BR> option add *Graph.BitmapMarker.Foreground white<BR> option add *Graph.m1.Background blue<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>marker create <I>type</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a marker of the selected type. <I>Type</I> may be either <I>text</I>, <I>line</I>, <I>bitmap</I>, <I>image</I>, <I>polygon</I>, or <I>window</I>. This command returns the marker identifier, used as the <I>markerId</I> argument in the other marker-related commands. If the <B>-name</B> option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. </DD> <DT><I>pathName <B>marker delete</B></I> ?<I>name</I>?... </DT> <DD>Removes one of more markers. The graph will automatically be redrawn without the marker.. </DD> <DT><I>pathName <B>marker exists <I>markerId</I></B></I> </DT> <DD>Returns <I>1</I> if the marker <I>markerId</I> exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>marker names</B></I> ?<I>pattern</I>? </DT> <DD>Returns the names of all the markers that currently exist. If <I>pattern</I> is supplied, only those markers whose names match it will be returned. </DD> <DT><I>pathName <B>marker type <I>markerId</I></B></I> </DT> <DD>Returns the type of the marker given by <I>markerId</I>, such as <I>line</I> or <I>text</I>. If <I>markerId</I> is not a valid a marker identifier, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect16" HREF="#toc16">Bitmap Markers</A></H3> A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. <P> Bitmap markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create bitmap </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration options for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to bitmap markers: <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Same as the <B>-fill</B> option. </DD> <DT><B>-bitmap <I>bitmap</I></B> </DT> <DD>Specifies the bitmap to be displayed. If <I>bitmap</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the bitmap. If <I>color</I> is the empty string, no background will be transparent. The default background color is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Same as the <B>-outline</B> option. </DD> <DT><B>-mask <I>mask</I></B> </DT> <DD>Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If <I>mask</I> is <I>""</I>, all pixels of the bitmap will be drawn. The default is <I>""</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the foreground color of the bitmap. The default value is <I>black</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Sets the rotation of the bitmap. <I>Theta</I> is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is <I>0.0</I>. </DD> </DL> <H3><A NAME="sect17" HREF="#toc17">Image Markers</A></H3> A image marker displays an image. Image markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create image </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to image markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the image relative to the positioning point for the image. For example, if <I>anchor</I> is <I>center</I> then the image is centered on the point; if <I>anchor</I> is <I>n</I> then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-image <I>image</I></B> </DT> <DD>Specifies the image to be drawn. If <I>image</I> is <I>""</I>, the marker will not be drawn. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Line Markers</A></H3> A line marker displays one or more connected line segments. Line markers are created with marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create line </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to line markers: <DL> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the marker line will be solid. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the line. This color is used with striped lines (see the <B>-fdashes</B> option). If <I>color</I> is the empty string, no background color is drawn (the line will be dashed, not striped). The default background color is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the lines. The default width is <I>0</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the foreground color of the line. The default value is <I>black</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern used to draw the line, rather than a solid line. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the line is drawn in a solid fashion. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Polygon Markers</A></H3> A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create polygon </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the <B>marker configure</B> command to change the marker's configuration. The following options are supported for polygon markers: <DL> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline of the polygon. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the outline will be a solid line. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the fill color of the polygon. If <I>color</I> is <I>""</I>, then the interior of the polygon is transparent. The default is <I>white</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline of the polygon. If <I>pixels</I> is zero, no outline is drawn. The default is <I>0</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color of the outline of the polygon. If the polygon is stippled (see the <B>-stipple</B> option), then this represents the foreground color of the stipple. The default is <I>black</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the polygon is filled with a solid color (if the <B>-fill</B> option is set). The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Text Markers</A></H3> A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the graph. Text markers are created with the <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create text </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the text marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to text markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the text relative to the positioning point for the text. For example, if <I>anchor</I> is <I>center</I> then the text is centered on the point; if <I>anchor</I> is <I>n</I> then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is <I>center</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Same as the <B>-fill</B> option. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the text. The default is <I>*-Helvetica-Bold-R-Normal-*-120-*</I>. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the text. If <I>color</I> is the empty string, no background will be transparent. The default background color is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Same as the <B>-outline</B> option. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the text should be justified. This matters only when the marker contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color of the text. The default value is <I>black</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the text is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the text is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>4</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the number of degrees to rotate the text. <I>Theta</I> is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is <I>0.0</I>. </DD> <DT><B>-text <I>text</I></B> </DT> <DD>Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as <B>-anchor</B> or <B>-rotate</B>. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Window Markers</A></H3> A window marker displays a widget at a given position. Window markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create window </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> command. <P> The following options are specific to window markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the widget relative to the positioning point for the widget. For example, if <I>anchor</I> is <I>center</I> then the widget is centered on the point; if <I>anchor</I> is <I>n</I> then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever height the widget requests internally. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever width the widget requests internally. </DD> <DT><B>-window <I>pathName</I></B> </DT> <DD>Specifies the widget to be managed by the graph. <I>PathName</I> must be a child of the <B>graph</B> widget. </DD> </DL> <H2><A NAME="sect22" HREF="#toc22">Graph Component Bindings</A></H2> Specific graph components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as <B>Enter</B>, <B>Leave</B>, <B>ButtonPress</B>, <B>Motion</B>, and <B>KeyPress</B>). <P> Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. <P> It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the <B>-bindtags</B> option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. <P> The <B>-bindtags</B> option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the <B>-bindtags</B> option doesn't change this. <H2><A NAME="sect23" HREF="#toc23">C Language API</A></H2> You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. <P> Data can manipulated from the C language using BLT vectors. You specify the X-Y data coordinates of an element as vectors and manipulate the vector from C. The graph will be redrawn automatically after the vectors are updated. <P> From Tcl, create the vectors and configure the element to use them. <BR> <CODE>vector X Y<BR> .g element configure line1 -xdata X -ydata Y<BR> </CODE><P>To set data points from C, you pass the values as arrays of doubles using the <B>Blt_ResetVector</B> call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the graph will be redrawn automatically. <BR> <CODE>#include &lt;tcl.h&gt;<BR> #include &lt;blt.h&gt;<BR> <P> register int i;<BR> Blt_Vector *xVec, *yVec;<BR> double x[50], y[50];<BR> <P> /* Get the BLT vectors "X" and "Y" (created above from Tcl) */<BR> if ((Blt_GetVector(interp, "X", &amp;xVec) != TCL_OK) ||<BR> (Blt_GetVector(interp, "Y", &amp;yVec) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> <P> for (i = 0; i &lt; 50; i++) {<BR> x[i] = i * 0.02;<BR> y[i] = sin(x[i]);<BR> }<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<BR> <P> /* Put the data into BLT vectors */<BR> if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) ||<BR> (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> </CODE><P>See the <B>vector</B> manual page for more details. <H2><A NAME="sect24" HREF="#toc24">Speed Tips</A></H2> There may be cases where the graph needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. <UL> &#183;<LI>Try to minimize the number of data points. The more data points the looked at, the more work the graph must do. </LI>&#183;<LI>If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. </LI>&#183;<LI>Data elements without symbols are drawn faster than with symbols. Set the data element's <B>-symbol</B> option to <I>none</I>. If you need to draw symbols, try using the simple symbols such as <I>splus</I> and <I>scross</I>. </LI>&#183;<LI>Don't stipple or dash the element. Solid lines are much faster. </LI>&#183;<LI>If you update data elements frequently, try turning off the widget's <B>-bufferelements</B> option. When the graph is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the graph needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the graph. But if the graph is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. </LI> </UL> <H2><A NAME="sect25" HREF="#toc25">Limitations</A></H2> Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. <P> The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. <H2><A NAME="sect26" HREF="#toc26">Keywords</A></H2> graph, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Syntax</A></LI> <LI><A NAME="toc5" HREF="#sect5">Example</A></LI> <LI><A NAME="toc6" HREF="#sect6">Graph Operations</A></LI> <LI><A NAME="toc7" HREF="#sect7">Graph Components</A></LI> <UL> <LI><A NAME="toc8" HREF="#sect8">Axis Components</A></LI> <LI><A NAME="toc9" HREF="#sect9">Crosshairs Component</A></LI> <LI><A NAME="toc10" HREF="#sect10">Element Components</A></LI> <LI><A NAME="toc11" HREF="#sect11">Grid Component</A></LI> <LI><A NAME="toc12" HREF="#sect12">Legend Component</A></LI> <LI><A NAME="toc13" HREF="#sect13">Pen Components</A></LI> <LI><A NAME="toc14" HREF="#sect14">PostScript Component</A></LI> <LI><A NAME="toc15" HREF="#sect15">Marker Components</A></LI> <LI><A NAME="toc16" HREF="#sect16">Bitmap Markers</A></LI> <LI><A NAME="toc17" HREF="#sect17">Image Markers</A></LI> <LI><A NAME="toc18" HREF="#sect18">Line Markers</A></LI> <LI><A NAME="toc19" HREF="#sect19">Polygon Markers</A></LI> <LI><A NAME="toc20" HREF="#sect20">Text Markers</A></LI> <LI><A NAME="toc21" HREF="#sect21">Window Markers</A></LI> </UL> <LI><A NAME="toc22" HREF="#sect22">Graph Component Bindings</A></LI> <LI><A NAME="toc23" HREF="#sect23">C Language API</A></LI> <LI><A NAME="toc24" HREF="#sect24">Speed Tips</A></LI> <LI><A NAME="toc25" HREF="#sect25">Limitations</A></LI> <LI><A NAME="toc26" HREF="#sect26">Keywords</A></LI> </UL> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/cutbuffer.html���������������������������������������������������������������0000644�0001750�0001750�00000004064�11462120062�016061� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>cutbuffer(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> cutbuffer - Manipulate X cut buffer properties <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>cutbuffer<I> get ?number?</I></B> <BR> <B>cutbuffer<I> rotate ?count?</I></B> <BR> <B>cutbuffer<I> set value ?number?</I></B> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> <P> The <B>cutbuffer</B> command allows you to read or modify the eight X cut buffer properties. You can also rotate the buffers properties. <H2><A NAME="sect3" HREF="#toc3">Operations</A></H2> The following operations are available for the <B>cutbuffer</B> command: <DL> <DT><B>cutbuffer get <I>?number?</I></B> </DT> <DD>Returns the value of a cutbuffer <I>number</I>. <I>Number</I> must be a number between 0 and 7. The default is 0. The cutbuffer is returned exactly, except that NUL bytes are converted to '@' characters. If a cut buffer <I>number</I> does not exist, then <I>""</I> is returned. </DD> <DT><B>cutbuffer rotate <I>?count?</I></B> </DT> <DD>Rotates the cut buffers by <I>count</I>. <I>Count</I> must be a number between -7 and 7. The default is 1. </DD> <DT><B>cutbuffer set <I>value</I></B> ?<I>number</I>? </DT> <DD>Sets the cutbuffer <I>number</I> to <I>value</I>. <I>Number</I> must be a number between 0 and 7. The default is 0. </DD> </DL> <H2><A NAME="sect4" HREF="#toc4">Keywords</A></H2> cut buffer, property <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Operations</A></LI> <LI><A NAME="toc4" HREF="#sect4">Keywords</A></LI> </UL> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/dragdrop.html����������������������������������������������������������������0000644�0001750�0001750�00000047743�11462120062�015711� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>drag&drop(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> drag&amp;drop - facilities for handling drag&amp;drop data transfers <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>drag&amp;drop source </B><BR> <B>drag&amp;drop source <I>window </I></B>?<I>options</I>? <BR> <B>drag&amp;drop source <I>window <B>handler </B></I></B>?<I>dataType</I>? ?<I>command arg arg...</I>? <P> <B>drag&amp;drop target </B><BR> <B>drag&amp;drop target <I>window <B>handler </B></I></B>?<I>dataType command arg arg...</I>? <P> <B>drag&amp;drop target <I>window <B>handle <I>dataType</I></B></I></B> ?<I>value</I>? <P> <B>drag&amp;drop token <I>window </I></B><P> <B>drag&amp;drop drag <I>window x y </I></B><BR> <B>drag&amp;drop drop <I>window x y </I></B><BR> <B>drag&amp;drop active </B><BR> <B>drag&amp;drop errors </B>?<I>proc</I>? <BR> <B>drag&amp;drop location </B>?<I>x y</I>? <P> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> <P> The <B>drag&amp;drop</B> command provides access to a set of facilities for managing drag-and-drop data transfers. Any of the usual Tk widgets can be registered to participate in the drag-and-drop process. Widgets registered as a drag&amp;drop <I>source</I> can export data to other widgets registered as a drag&amp;drop <I>target</I>. Note that a particular widget can be registered as a source, as a target, or as both. <P> The drag-and-drop process begins when the user clicks and holds a mouse button in a source window; a token window appears with an icon or message to represent the data being transferred. As the user moves the mouse pointer, the token window follows along, acting as a movable packet of data. Whenever the mouse pointer falls on a valid target window, the border of the token window is changed to a raised (active) state. When the mouse button is released over the target window, a Tcl routine is invoked to send the data to the desired application, and the target window is asked to "handle" the data. If this communication process fails, a rejection symbol (a circle with a line through it) is displayed on the token window to indicate failure. <P> The details of the communication process are fully configurable by the application developer. In the simplest case, the value that is sent to the target window is a simple string. The target window is simply asked to "handle" that string value. In general, the source window can have a special "handler" procedure to transfer a particular data type by issuing a series of "send" commands. After this, the target window is again asked to "handle" the result. <P> Both sources and targets can have a list of "handlers" for different data types. As a token window is dragged from its source to various targets, each target is checked to see if it recognizes a handler offered by the source. If it does, it is treated as a valid target. Otherwise, it is ignored. This scheme allows the same source to interact with many different kinds of targets. For example, a source for RGB color samples might have "color" and "string" handlers. This would allow it to communicate with "color" targets (sending RGB data) as well as entry widgets (sending strings of the form "#rrggbb"). <P> This introduction was presented as a brief overview of the communication process; further details are presented below: <DL> <DT><B>drag&amp;drop source</B> </DT> <DD>Returns a list of path names for widgets registered as drag&amp;drop sources. Returns an empty string if no widgets have been registered. </DD> <DT><B>drag&amp;drop source <I>window </I></B>?<I>options</I>? </DT> <DD>Registers a new drag&amp;drop source window with the given options, or modifies the options for an existing window: <blockquote></DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>buttonBinding</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>ButtonBinding</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-button</B> <I>n</I> </PRE> <DL> <DT>Specifies the mouse button (integer 1-5) that will invoke the drag&amp;drop </DT> <DD>operation on the source window. This causes the following bindings to be added to the widget: <P> <BR> <PRE><I>bind <I>win</I></I> &lt;ButtonPress-<I>n</I>&gt; {drag&amp;drop drag %W %X %Y} <I>bind <I>win</I></I> &lt;B<I>n</I>-Motion&gt; {drag&amp;drop drag %W %X %Y} <I>bind <I>win</I></I> &lt;ButtonRelease-<I>n</I>&gt; {drag&amp;drop drop %W %X %Y} </PRE><P> The default value is button 3. If the value "0" is specified, then no bindings are added; this enables the user to establish bindings manually. <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>packageCommand</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Command</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-packagecmd <I>command</I></B> </PRE> <DL> <DT>Specifies a Tcl command used to establish the appearance of the token </DT> <DD>window at the start of each drag&amp;drop operation. This command is automatically invoked by the <B>drag&amp;drop drag</B> command whenever the token window is about to be mapped for a drag operation. It should update the appearance of the token window to represent the data that is being moved. </DD> </DL> <P> The following substitutions are made in the <I>command</I> string before it is executed: <blockquote> <DL> <DT><B>%t</B> </DT> <DD>Replaced with the window path name for the token which represents the data being dragged. </DD> <DT><B>%W</B> </DT> <DD>Replaced with the window path name for the drag&amp;drop source. </DD> </DL> </blockquote> <P> The return value from the package command represents the data being transferred. If the package command returns an empty string, the drag operation is quietly aborted. This can be used to disallow drag&amp;drop operations from certain parts of a widget, if the drag position is inappropriate. <P> For example, the following package routine will select an item from a listbox and configure the token window to display the selected string. It uses the <B>drag&amp;drop location</B> command to determine the entry in the listbox that the user has selected and it returns this as the data value: <P> <BR> <PRE><I>proc package_list_item {lbox token} {</I> set xy [drag&amp;drop location] set y [expr [lindex $xy 1]-[winfo rooty $lbox]] set str [$lbox get [$lbox nearest $y]] $token.value configure -text $str return $str } </PRE><P> The return value is available later when the source and target communicate. If the source has a command associated with its data handler, then this value is substituted in place of "%v" in the source handler. Otherwise, it is substituted in place of "%v" in the target handler. <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>rejectBackground</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Background</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-rejectbg <I>color</I></B> </PRE> <DL> <DT>Specifies the color used to draw the background of the rejection symbol </DT> <DD>on the token window. The rejection symbol (a circle with a line through it--the international "no") appears whenever communication fails. </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>rejectForeground</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Foreground</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-rejectfg <I>color</I></B> </PRE> <DL> <DT>Specifies the color used to draw the foreground of the rejection symbol </DT> <DD>on the token window. </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>rejectStipple</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Stipple</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-rejectstipple <I>pattern</I></B> </PRE> <DL> <DT>Specifies a stipple pattern used to draw the foreground of the rejection </DT> <DD>symbol on the token window. Any of the forms acceptable to Tk_GetBitmap can be used. </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>selfTarget</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>SelfTarget</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-selftarget <I>boolean</I></B> </PRE> <DL> <DT>If the <I>boolean</I> value is true, and if a source widget is also </DT> <DD>registered as a compatible target, then the source will be able to transmit to itself during drag&amp;drop operations. This is primarily useful for complex sources such as a canvas widget, where items may be moved from place to place within the same widget. By default, this option is disabled. </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>send</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Send</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-send <I>list</I></B> </PRE> <DL> <DT>Specifies a <I>list</I> of <I>dataTypes</I> enabled for communication. Only </DT> <DD><I>dataTypes</I> defined by commands of the form "<B>drag&amp;drop source <I>window <B>handler </B></I></B>?<I>dataType</I> ?<I>command arg arg...</I>?" are allowed. This list also determines the priority of the various <I>dataTypes</I>. When a token window is over a potential drag&amp;drop target, this list is searched from start to finish for a <I>dataType</I> that is also recognized by the target. The first matching <I>dataType</I> found determines the value that will be sent if the token is dropped. If no matching <I>dataType</I> is found, then the target is incompatible, and is ignored. By default, this option has the value "all", indicating that all <I>dataTypes</I> should be considered in the order that they were defined for the source. </DD> </DL> <P> Note that this option makes it easy to control a drag&amp;drop source. Setting the value to an empty string disables the source; setting the value back to "all" restores communication. <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>siteCommand</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Command</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-sitecmd <I>command</I></B> </PRE> <DL> <DT>Specifies a Tcl command used to update the appearance of the token window. </DT> <DD>If specified, this command is automatically invoked by the <B>drag&amp;drop drag</B> command whenever the token window is over a compatible drag&amp;drop target. </DD> </DL> <P> The following substitutions are made in the <I>command</I> string before it is executed: <blockquote> <DL> <DT><B>%s</B> </DT> <DD>Replaced with "1" if the token window is over a compatible target, and "0" otherwise. </DD> <DT><B>%t</B> </DT> <DD>Replaced with the window path name for the token which represents the data being dragged. </DD> </DL> </blockquote> <P> Regardless of this command, border of the token window will become raised whenever the token is over a valid target. This command can be used to display other visual cues. <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tokenAnchor</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Anchor</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-tokenanchor <I>anchor</I></B> </PRE> <DL> <DT>Specifies how the token window is positioned relative to the mouse </DT> <DD>pointer coordinates passed to the <B>drag&amp;drop drag</B> command. Must be one of the values n, s, e, w, center, nw, ne, sw or se. For example, "nw" means to position the token such that its upper-left corner is at the mouse pointer. The default value is "center". </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tokenBackground</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Background</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-tokenbg <I>color</I></B> </PRE> <DL> <DT>Specifies the color used to draw the background of the token window. </DT> <DD></DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tokenBorderWidth</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>BorderWidth</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-tokenborderwidth <I>size</I></B> </PRE> <DL> <DT>Specifies the width in pixels of the border around the token window. </DT> <DD>This border becomes raised to indicate when the token is over a compatible drag&amp;drop target site. The value may have any of the forms acceptable to Tk_GetPixels. The default value is "3". </DD> </DL> <P> <BR> <PRE>Name:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>tokenCursor</B> Class:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>Cursor</B> Switch:<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<B>-tokencursor <I>cursor</I></B> </PRE> <DL> <DT>Specifies the cursor used when a token window is active. The value </DT> <DD>may have any of the forms acceptable to Tk_GetCursor. The default value is "center_ptr". </DD> </DL> </blockquote> <DL> <DT><B>drag&amp;drop source <I>window <B>handler </B></I></B>?<I>dataType</I>? ?<I>command arg arg...</I>? </DT> <DD>With no extra arguments, this command returns a list of all <I>dataType</I> names that have been registered for the source <I>window</I>. If only the <I>dataType</I> is specified, then the <I>dataType</I> is created if necessary, and the command associated with the <I>dataType</I> is returned. Otherwise, it concatenates the <I>command</I> and any extra <I>arg</I> strings, and registers a new <I>dataType</I> with this command. </DD> </DL> <P> The following substitutions are made in the <I>command</I> string before it is executed: <blockquote> <DL> <DT><B>%i</B> </DT> <DD>Replaced with the name of the interpreter for the target application. </DD> <DT><B>%v</B> </DT> <DD>Replaced with the value returned from the "-packagecmd" command. </DD> <DT><B>%w</B> </DT> <DD>Replaced with the window path name for the target window. </DD> </DL> </blockquote> <P> A typical source handler contains one or more "send" commands which transfer data to the remote application. The target window is then asked to handle the new data. Whatever value is returned by the source <I>command</I> handler is automatically substituted into the "%v" fields of the target handler. <P> This separation between the transfer and the handling of the data is important. It allows the same source handler to transfer data for many different targets, and it allows each of the targets to handle the incoming data differently. If an error is encountered during the communication process, the rejection symbol is posted on the token window to indicate failure. </blockquote> <P> <DL> <DT><B>drag&amp;drop target</B> </DT> <DD>Returns a list of path names for widgets registered as drag&amp;drop targets. Returns an empty string if no widgets have been registered. </DD> <DT><B>drag&amp;drop target <I>window <B>handler </B></I></B>?<I>dataType command arg arg...</I>? </DT> <DD>Registers a new drag&amp;drop target window with a given handler, or modifies the handlers for an existing window. If no <I>dataType</I> is specified, this command returns the current list of recognized <I>dataType</I> strings. Each <I>dataType</I> is a symbolic name representing a form of data, and the corresponding <I>command</I> is a Tcl command that specifies how the target will make use of the data. This command is invoked indirectly after a source has transferred data to a target application. </DD> </DL> <P> The following substitutions are made in the <I>command</I> string before it is executed: <blockquote> <DL> <DT><B>%v</B> </DT> <DD>In the simplest case, the source window does not have a handler command for the selected <I>dataType</I>, and this field is replaced with the result from the "-packagecmd" command. When the source does have a handler command, the result from the "-packagecmd" command is substituted into its "%v" field, and the result from this command is substituted into this field in the target command. </DD> <DT><B>%W</B> </DT> <DD>Replaced with the window path name for the target window. </DD> </DL> </blockquote> <DL> <DT><B>drag&amp;drop target <I>window </I></B>handle <I>dataType</I> ?<I>value</I>? </DT> <DD>Searches for the given <I>dataType</I> name among the handlers registered for the target <I>window</I>, and invokes the appropriate <I>command</I>. If a <I>value</I> is specified, it is substituted into any "%v" fields in the handler command associated with the <I>dataType</I>. If the <I>dataType</I> name is not recognized, this command returns an error. This command is invoked automatically by the drag&amp;drop facility when data is being transferred from a source to a target. </DD> <DT><B>drag&amp;drop token <I>window</I></B> </DT> <DD>Returns the token window associated with a drag&amp;drop source <I>window</I>. The token window is used to represent data as it is being dragged from the source to a target. When a source is first established, its token window must be filled with widgets to display the source data. For example, <P> <BR> <PRE><I>drag&amp;drop source .foo</I> set win [drag&amp;drop token .foo] label $win.label -text "Data" pack $win.label </PRE><P> <DL> <DT><B>drag&amp;drop drag <I>window x y</I></B> </DT> <DD>Marks the start of (or movement during) a drag&amp;drop operation. If the token window is unmapped when this command is invoked, then the <B>-packagecmd</B> for the source <I>window</I> is executed. If this command is successful and returns a non-null string, the token window is mapped. On subsequent calls, the token window is moved to the new <I>x y</I> location. Unless the "<B>-button 0</B>" option is specified for the source, this command is automatically bound to &lt;ButtonPress-<I>n</I>&gt; and &lt;B<I>n</I>-Motion&gt; events for "<B>-button <I>n</I></B>" of the source widget. </DD> <DT><B>drag&amp;drop drop <I>window x y</I></B> </DT> <DD>Marks the end of a drag&amp;drop operation. If the mouse pointer is over a compatible target window, then the appropriate send handler for the first compatible <I>dataType</I> is invoked to handle the data transfer. If the data transfer is successful, then the token window is unmapped; otherwise, a rejection symbol is drawn on the token window, and the window is unmapped after a small delay. Unless the "<B>-button 0</B>" option is specified for the source, this command is automatically bound to the &lt;ButtonRelease-<I>n</I>&gt; event for "<B>-button <I>n</I></B>" of the source widget. </DD> <DT><B>drag&amp;drop active</B> </DT> <DD>Returns "1" if a drag&amp;drop operation is in progress, and "0" otherwise. A drag&amp;drop operation officially starts after the package command has been executed successfully, and ends after the send handler has been executed (successfully or otherwise). </DD> <DT><B>drag&amp;drop errors </B>?<I>proc</I>? </DT> <DD>Specifies a Tcl <I>proc</I> used to handle errors encountered during drag&amp;drop operations. If a <I>proc</I> is not specified, this command returns the current error handler. By default, all errors are sent to the usual <B>tkerror</B> command, and therefore appear in a dialog box to the user. This behavior is quite useful when debugging communication protocols, but may not be desirable in a finished application. Errors can be suppressed entirely (leaving the rejection symbol as the only error indicator) by specifying a null string in place of the <I>proc</I> name. </DD> <DT><B>drag&amp;drop location </B>?<I>x y</I>? </DT> <DD>Used to set or query the pointer location during a drag&amp;drop operation. The <I>x y</I> arguments specify the current location; if these arguments are missing, then the last reported (x,y) location is returned as a list with two elements. This command is issued automatically within the <B>drag&amp;drop drag</B> and <B>drag&amp;drop drop</B> commands, to keep track of pointer movement. <P> </DD> </DL> <H2><A NAME="sect3" HREF="#toc3">Keywords</A></H2> drag&amp;drop, send, bind, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Keywords</A></LI> </UL> </BODY></HTML> �����������������������������./saods9/blt3.0.1/html/barchart.html����������������������������������������������������������������0000644�0001750�0001750�00000317133�11462120062�015666� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>barchat(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> barchart - Bar chart for plotting X-Y coordinate data. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>barchart<I> <I>pathName </I></I></B>?<I>option value</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>barchart</B> command creates a bar chart for plotting two-dimensional data (X-Y coordinates). A bar chart is a graphic means of comparing numbers by displaying bars of lengths proportional to the y-coordinates of the points they represented. The bar chart has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the graph. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>barchart</B> command creates a new window for plotting two-dimensional data (X-Y coordinates), using bars of various lengths to represent the data points. The bars are drawn in a rectangular area displayed in the center of the new window. This is the <I>plotting area</I>. The coordinate axes are drawn in the margins surrounding the plotting area. By default, the legend is drawn in the right margin. The title is displayed in top margin. <P> A <B>barchart</B> widget has several configurable components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. Each component can be queried or modified. <DL> <DT><I>axis</I> </DT> <DD><P> Up to four coordinate axes (two X-coordinate and two Y-coordinate axes) can be displayed, but you can create and use any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value at each major tick. </DD> <DT><I>crosshairs</I> </DT> <DD>Cross hairs are used to position the mouse pointer relative to the X and Y coordinate axes. Two perpendicular lines, intersecting at the current location of the mouse, extend across the plotting area to the coordinate axes. </DD> <DT><I>element</I> </DT> <DD>An element represents a set of data to be plotted. It contains an x and y vector of values representing the data points. Each data point is displayed as a bar where the length of the bar is proportional to the ordinate (Y-coordinate) of the data point. The appearance of the bar, such as its color, stipple, or relief is configurable. <P> A special case exists when two or more data points have the same abscissa (X-coordinate). By default, the bars are overlayed, one on top of the other. The bars are drawn in the order of the element display list. But you can also configure the bars to be displayed in two other ways. They may be displayed as a stack, where each bar (with the same abscissa) is stacked on the previous. Or they can be drawn side-by-side as thin bars. The width of each bar is a function of the number of data points with the same abscissa. </DD> <DT><I>grid</I> </DT> <DD>Extends the major and minor ticks of the X-axis and/or Y-axis across the plotting area. </DD> <DT><I>legend</I> </DT> <DD>The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. </DD> <DT><I>marker</I> </DT> <DD>Markers are used annotate or highlight areas of the graph. For example, you could use a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. </DD> <DT><I>pen</I> </DT> <DD>Pens define attributes for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here the particular pen used for a data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). </DD> <DT><I>postscript</I> </DT> <DD>The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. </DD> </DL> <H2><A NAME="sect4" HREF="#toc4">Syntax</A></H2> <BR> <P> <CODE><B>barchart <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>barchart</B> command creates a new window <I>pathName</I> and makes it into a <B>barchart</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the graph such as its colors and font. See the <B>configure</B> operation below for the exact details about what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>barchart</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the graph. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for the graph are described in the <FONT SIZE=-1><B>BARCHART OPERATIONS</B></FONT> section. <P> The command can also be used to access components of the graph. <BR> <P> <CODE><I>pathName component operation</I> ?<I>arg</I>?...<BR> </CODE><P>The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. <H2><A NAME="sect5" HREF="#toc5">Example</A></H2> The <B>barchart</B> command creates a new bar chart. <BR> <CODE># Create a new bar chart. Plotting area is black.<BR> barchart .b -plotbackground black<BR> </CODE><P>A new Tcl command <I>.b</I> is created. This command can be used to query and modify the bar chart. For example, to change the title of the graph to "My Plot", you use the new command and the <B>configure</B> operation. <BR> <CODE># Change the title.<BR> .b configure -title "My Plot"<BR> </CODE><P>To add data elements, you use the command and the <B>element</B> component. <BR> <CODE># Create a new element named "e1"<BR> .b element create e1 \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-xdata { 1 2 3 4 5 6 7 8 9 10 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;155.85 166.60 175.38 }<BR> </CODE><P>The element's X-Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X-Y coordinates. <BR> <CODE># Create two vectors and add them to the barchart.<BR> vector xVector yVector<BR> xVector set { 1 2 3 4 5 6 7 8 9 10 }<BR> yVector set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;166.60 175.38 }<BR> n.b element create e1 -xdata xVector -ydata yVector<BR> </CODE><P>The advantage of using vectors is that when you modify one, the graph is automatically redrawn to reflect the new values. <BR> <CODE># Change the y coordinate of the first point.<BR> set yVector(0) 25.18<BR> </CODE><P>An element named <I>e1</I> is now created in <I>.b</I>. It is automatically added to the display list of elements. You can use this list to control in what order elements are displayed. To query or reset the element display list, you use the element's <B>show</B> operation. <BR> <CODE># Get the current display list <BR> set elemList [.b element show]<BR> # Remove the first element so it won't be displayed.<BR> .b element show [lrange $elemList 0 end]<BR> </CODE><P>The element will be displayed by as many bars as there are data points (in this case there are ten). The bars will be drawn centered at the x-coordinate of the data point. All the bars will have the same attributes (colors, stipple, etc). The width of each bar is by default one unit. You can change this with using the <B>-barwidth</B> option. <BR> <CODE># Change the scale of the x-coordinate data <BR> xVector set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }<BR> # Make sure we change the bar width too.<BR> .b configure -barwidth 0.2<BR> </CODE><P>The height of each bar is proportional to the ordinate (Y-coordinate) of the data point. <P> If two or more data points have the same abscissa (X-coordinate value), the bars representing those data points may be drawn in various ways. The default is to overlay the bars, one on top of the other. The ordering is determined from the of element display list. If the stacked mode is selected (using the <B>-barmode</B> configuration option), the bars are stacked, each bar above the previous. <BR> <CODE># Display the elements as stacked.<BR> .b configure -barmode stacked<BR> </CODE><P>If the aligned mode is selected, the bars having the same x-coordinates are displayed side by side. The width of each bar is a fraction of its normal width, based upon the number of bars with the same x-coordinate. <BR> <CODE># Display the elements side-by-side.<BR> .b configure -barmode aligned<BR> </CODE><P>By default, the element's label in the legend will be also <I>e1</I>. You can change the label, or specify no legend entry, again using the element's <B>configure</B> operation. <BR> <CODE># Don't display "e1" in the legend.<BR> .b element configure e1 -label ""<BR> </CODE><P>You can configure more than just the element's label. An element has many attributes such as stipple, foreground and background colors, relief, etc. <BR> <CODE>.b element configure e1 -fg red -bg pink \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-stipple gray50<BR> </CODE><P>Four coordinate axes are automatically created: <I>x</I>, <I>x2</I>, <I>y</I>, and <I>y2</I>. And by default, elements are mapped onto the axes <I>x</I> and <I>y</I>. This can be changed with the <B>-mapx</B> and <B>-mapy</B> options. <BR> <CODE># Map "e1" on the alternate y axis "y2".<BR> .b element configure e1 -mapy y2<BR> </CODE><P>Axes can be configured in many ways too. For example, you change the scale of the Y-axis from linear to log using the <B>axis</B> component. <BR> <CODE># Y-axis is log scale.<BR> .b axis configure y -logscale yes<BR> </CODE><P>One important way axes are used is to zoom in on a particular data region. Zooming is done by simply specifying new axis limits using the <B>-min</B> and <B>-max</B> configuration options. <BR> <CODE>.b axis configure x -min 1.0 -max 1.5<BR> .b axis configure y -min 12.0 -max 55.15<BR> </CODE><P>To zoom interactively, you link the<B>axis configure</B> operations with some user interaction (such as pressing the mouse button), using the <B>bind</B> command. To convert between screen and graph coordinates, use the <B>invtransform</B> operation. <BR> <CODE># Click the button to set a new minimum <BR> bind .b &lt;ButtonPress-1&gt; { <BR> %W axis configure x -min [%W axis invtransform x %x]<BR> %W axis configure x -min [%W axis invtransform x %y]<BR> }<BR> </CODE><P>By default, the limits of the axis are determined from data values. To reset back to the default limits, set the <B>-min</B> and <B>-max</B> options to the empty value. <BR> <CODE># Reset the axes to autoscale again.<BR> .b axis configure x -min {} -max {}<BR> .b axis configure y -min {} -max {}<BR> </CODE><P>By default, the legend is drawn in the right margin. You can change this or any legend configuration options using the <B>legend</B> component. <BR> <CODE># Configure the legend font, color, and relief<BR> .b legend configure -position left -relief raised \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-font fixed -fg blue<BR> </CODE><P>To prevent the legend from being displayed, turn on the <B>-hide</B> option. <BR> <CODE># Don't display the legend.<BR> .b legend configure -hide yes<BR> </CODE><P>The <B>barchart</B> has simple drawing procedures called markers. They can be used to highlight or annotate data in the graph. The types of markers available are bitmaps, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. For example there may be a line marker which indicates some low-water value. Markers are created using the <B>marker</B> operation. <BR> <CODE># Create a line represent the low water mark at 10.0<BR> .b marker create line -name "low_water" \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-coords { -Inf 10.0 Inf 10.0 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-dashes { 2 4 2 } -fg red -bg blue <BR> </CODE><P>This creates a line marker named <I>low_water</I>. It will display a horizontal line stretching across the plotting area at the y-coordinate 10.0. The coordinates "-Inf" and "Inf" indicate the relative minimum and maximum of the axis (in this case the x-axis). By default, markers are drawn last, on top of the bars. You can change this with the <B>-under</B> option. <BR> <CODE># Draw the marker before elements are drawn.<BR> .b marker configure low_water -under yes<BR> </CODE><P>You can add cross hairs or grid lines using the <B>crosshairs</B> and <B>grid</B> components. <BR> <CODE># Display both cross hairs and grid lines.<BR> .b crosshairs configure -hide no -color red<BR> .b grid configure -hide no -dashes { 2 2 }<BR> </CODE><P>Finally, to get hardcopy of the graph, use the <B>postscript</B> component. <BR> <CODE># Print the bar chart into file "file.ps"<BR> .b postscript output file.ps -maxpect yes -decorations no<BR> </CODE><P>This generates a file <I>file.ps</I> containing the encapsulated PostScript of the graph. The option <B>-maxpect</B> says to scale the plot to the size of the page. Turning off the <B>-decorations</B> option denotes that no borders or color backgrounds should be drawn (i.e. the background of the margins, legend, and plotting area will be white). <H2><A NAME="sect6" HREF="#toc6">Syntax</A></H2> <BR> <P> <CODE><B>barchart <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>barchart</B> command creates a new window <I>pathName</I> and makes it into a barchart widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may may be specified on the command line or in the option database to configure aspects of the bar chart such as its colors and font. See the <B>configure</B> operation below for the exact details as to what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>barchart</B> returns <I>pathName</I>. It also creates a new Tcl command <I>pathName</I>. This command may be used to invoke various operations to query or modify the bar chart. It has the general form: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for the bar chart are described in the following section. <H2><A NAME="sect7" HREF="#toc7">Barchart Operations</A></H2> <DL> <DT><I>pathName <B>bar <I>elemName </I></B></I>?<I>option value</I>?... </DT> <DD>Creates a new barchart element <I>elemName</I>. It's an error if an element <I>elemName</I> already exists. See the manual for <B>barchart</B> for details about what <I>option</I> and <I>value</I> pairs are valid. </DD> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the <B>configure</B> operation. </DD> <DT><I>pathName <B>configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the graph. If <I>option</I> isn't specified, a list describing the current options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the option <I>option</I> is set to <I>value</I>. The following options are valid. <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color. This includes the margins and legend, but not the plotting area. </DD> <DT><B>-barmode <I>mode</I></B> </DT> <DD>Indicates how related bar elements will be drawn. Related elements have data points with the same abscissas (X-coordinates). <I>Mode</I> indicates how those segments should be drawn. <I>Mode</I> can be <I>infront</I>, <I>aligned</I>, <I>overlap</I>, or <I>stacked</I>. The default mode is <I>infront</I>. <blockquote></DD> <DT><I>infront</I> </DT> <DD>Each successive segment is drawn in front of the previous. </DD> <DT><I>stacked</I> </DT> <DD>Each successive segment is stacked vertically on top of the previous. </DD> <DT><I>aligned</I> </DT> <DD>Segments is displayed aligned from right-to-left. </DD> <DT><I>overlap</I> </DT> <DD>Like <I>aligned</I> but segments slightly overlap each other. </DD> </DL> </blockquote> <DL> <DT><B>-barwidth <I>value</I></B> </DT> <DD>Specifies the width of the bars. This value can be overrided by the individual elements using their <B>-barwidth</B> configuration option. <I>Value</I> is the width in terms of graph coordinates. The default width is <I>1.0</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-bottommargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin below the X-coordinate axis. If <I>pixels</I> is <I>0</I>, the size of the margin is selected automatically. The default is <I>0</I>. </DD> <DT><B>-bufferelements <I>boolean</I></B> </DT> <DD>Indicates whether an internal pixmap to buffer the display of data elements should be used. If <I>boolean</I> is true, data elements are drawn to an internal pixmap. This option is especially useful when the graph is redrawn frequently while the remains data unchanged (for example, moving a marker across the plot). See the <FONT SIZE=-1><B>SPEED TIPS</B></FONT> section. The default is <I>1</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>crosshair</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the graph title. The default is <I>*-Helvetica-Bold-R-Normal-*-18-180-*</I>. </DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a maximum distance to consider when searching for the closest data point (see the element's <B>closest</B> operation below). Data points further than <I>pixels</I> away are ignored. The default is <I>0.5i</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>4i</I>. </DD> <DT><B>-invertxy <I>boolean</I></B> </DT> <DD>Indicates whether the placement X-axis and Y-axis should be inverted. If <I>boolean</I> is true, the X and Y axes are swapped. The default is <I>0</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the title should be justified. This matters only when the title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-leftmargin <I>pixels</I></B> </DT> <DD>Sets the size of the margin from the left edge of the window to the Y-coordinate axis. If <I>pixels</I> is <I>0</I>, the size is calculated automatically. The default is <I>0</I>. </DD> <DT><B>-plotbackground <I>color</I></B> </DT> <DD>Specifies the background color of the plotting area. The default is <I>white</I>. </DD> <DT><B>-plotborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the plotting area. The <B>-plotrelief</B> option determines if a border is drawn. The default is <I>2</I>. </DD> <DT><B>-plotpadx <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the left and right sides of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotpady <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the top and bottom of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the plotting area. <I>Relief</I> specifies how the interior of the plotting area should appear relative to rest of the graph; for example, <I>raised</I> means the plot should appear to protrude from the graph, relative to the surface of the graph. The default is <I>sunken</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the barchart widget. <I>Relief</I> specifies how the graph should appear relative to widget it is packed into; for example, <I>raised</I> means the graph should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-rightmargin <I>pixels</I></B> </DT> <DD>Sets the size of margin from the plotting area to the right edge of the window. By default, the legend is drawn in this margin. If <I>pixels</I> is than 1, the margin size is selected automatically. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>""</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a tiled background for the widget. If <I>image</I> isn't <I>""</I>, the background is tiled using <I>image</I>. Otherwise, the normal background color is drawn (see the <B>-background</B> option). <I>Image</I> must be an image created using the Tk <B>image</B> command. The default is <I>""</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title to <I>text</I>. If <I>text</I> is <I>""</I>, no title will be displayed. </DD> <DT><B>-topmargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin above the x2 axis. If <I>pixels</I> is <I>0</I>, the margin size is calculated automatically. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. The default is <I>5i</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>crosshairs <I>operation </I></B></I>?<I>arg</I>? </DT> <DD>See the <FONT SIZE=-1><B>CROSSHAIRS COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>element <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>ELEMENT COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>extents <I>item</I></B></I> </DT> <DD>Returns the size of a particular item in the graph. <I>Item</I> must be either <I>leftmargin</I>, <I>rightmargin</I>, <I>topmargin</I>, <I>bottommargin</I>, <I>plotwidth</I>, or <I>plotheight</I>. </DD> <DT><I>pathName <B>grid <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>GRID COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>invtransform <I>winX winY</I></B></I> </DT> <DD>Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X-axis and Y-axis. Returns a list of containing the X-Y graph coordinates. </DD> <DT><I>pathName <B>inside <I>x y</I></B></I> </DT> <DD>Returns <I>1</I> is the designated screen coordinate (<I>x</I> and <I>y</I>) is inside the plotting area and <I>0</I> otherwise. </DD> <DT><I>pathName <B>legend <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>LEGEND COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>line<B> operation arg</B></B></I>... </DT> <DD>The operation is the same as <B>element</B>. </DD> <DT><I>pathName <B>marker <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>MARKER COMPONENTS</B></FONT> section. </DD> <DT><I>pathName</I> <B>metafile</B> ?<I>fileName</I>? </DT> <DD><I>This operation is for Window platforms only</I>. Creates a Windows enhanced metafile of the barchart. If present, <I>fileName</I> is the file name of the new metafile. Otherwise, the metafile is automatically added to the clipboard. </DD> <DT><I>pathName <B>postscript <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>POSTSCRIPT COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>snap <I>photoName</I></B></I> </DT> <DD>Takes a snapshot of the graph and stores the contents in the photo image <I>photoName</I>. <I>PhotoName</I> is the name of a Tk photo image that must already exist. </DD> <DT><I>pathName <B>transform <I>x y</I></B></I> </DT> <DD>Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X-axis and Y-axis. Returns a list containing the X-Y screen coordinates. </DD> <DT><I>pathName <B>xaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>x2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>yaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>y2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> </DL> <H2><A NAME="sect8" HREF="#toc8">Barchart Components</A></H2> A graph is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the graph is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the graph. <H3><A NAME="sect9" HREF="#toc9">Axis Components</A></H3> Four coordinate axes are automatically created: two X-coordinate axes (<I>x</I> and <I>x2</I>) and two Y-coordinate axes (<I>y</I>, and <I>y2</I>). By default, the axis <I>x</I> is located in the bottom margin, <I>y</I> in the left margin, <I>x2</I> in the top margin, and <I>y2</I> in the right margin. <P> An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. <P> The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. <P> You can create and use several axes. To create an axis, invoke the axis component and its create operation. <BR> <CODE># Create a new axis called "temperature"<BR> .b axis create temperature<BR> </CODE><P>You map data elements to an axis using the element's -mapy and -mapx configuration options. They specify the coordinate axes an element is mapped onto. <BR> <CODE># Now map the temperature data to this axis.<BR> .b element create "temp" -xdata $x -ydata $tempData \<BR> -mapy temperature<BR> </CODE><P>While you can have many axes, only four axes can be displayed simultaneously. They are drawn in each of the margins surrounding the plotting area. The axes <I>x</I> and <I>y</I> are drawn in the bottom and left margins. The axes <I>x2</I> and <I>y2</I> are drawn in top and right margins. Only <I>x</I> and <I>y</I> are shown by default. Note that the axes can have different scales. <P> To display a different axis, you invoke one of the following components: <B>xaxis</B>, <B>yaxis</B>, <B>x2axis</B>, and <B>y2axis</B>. The <B>use</B> operation designates the axis to be drawn in the corresponding margin: <B>xaxis</B> in the bottom, <B>yaxis</B> in the left, <B>x2axis</B> in the top, and <B>y2axis</B> in the right. <BR> <CODE># Display the axis temperature in the left margin.<BR> .b yaxis use temperature<BR> <P> </CODE><P>You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label any way you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. <P> <DL> <DT><I>pathName <B>axis <B>cget <I>axisName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>axisName</I>. <I>Option</I> may be any option described below for the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>configure <I>axisName </I></B></B></I>?<I>axisName</I>?... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>axisName</I>. Several axes can be changed. If <I>option</I> isn't specified, a list describing all the current options for <I>axisName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the axis option <I>option</I> is set to <I>value</I>. The following options are valid for axes. <blockquote></DD> <DT><B>-autorange <I>range</I></B> </DT> <DD>Sets the range of values for the axis to <I>range</I>. The axis limits are automatically reset to display the most recent data points in this range. If <I>range</I> is 0.0, the range is determined from the limits of the data. If <B>-min</B> or <B>-max</B> are specified, they override this option. The default is <I>0.0</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the axis and tick labels. The default is <I>black</I>. </DD> <DT><B>-command <I>prefix</I></B> </DT> <DD>Specifies a Tcl command to be invoked when formatting the axis tick labels. <I>Prefix</I> is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If <I>""</I> is returned, no label will appear next to the tick. You can get the standard tick labels again by setting <I>prefix</I> to <I>""</I>. The default is <I>""</I>. <P> Please note that this procedure is invoked while the bar chart is redrawn. You may query the widget's configuration options. But do not reset options, because this can have unexpected results. </DD> <DT><B>-descending <I>boolean</I></B> </DT> <DD>Indicates whether the values along the axis are monotonically increasing or decreasing. If <I>boolean</I> is true, the axis values will be decreasing. The default is <I>0</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the axis is displayed. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-limits <I>formatStr</I></B> </DT> <DD>Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. <I>FormatStr</I> is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If <I>""</I> is given as either description, then the that limit will not be displayed. The default is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the axis and tick lines. The default is <I>1</I> pixel. </DD> <DT><B>-logscale <I>boolean</I></B> </DT> <DD>Indicates whether the scale of the axis is logarithmic or linear. If <I>boolean</I> is true, the axis is logarithmic. The default scale is linear. </DD> <DT><B>-loose <I>boolean</I></B> </DT> <DD>Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. This is relevant only when the axis limit is automatically calculated. If <I>boolean</I> is true, the axis range is "loose". The default is <I>0</I>. </DD> <DT><B>-majorticks <I>majorList</I></B> </DT> <DD>Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. <I>MajorList</I> is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If <I>majorList</I> is <I>""</I>, major ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-max <I>value</I></B> </DT> <DD>Sets the maximum limit of <I>axisName</I>. Any data point greater than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the maximum limit is calculated using the largest data value. The default is <I>""</I>. </DD> <DT><B>-min <I>value</I></B> </DT> <DD>Sets the minimum limit of <I>axisName</I>. Any data point less than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the minimum limit is calculated using the smallest data value. The default is <I>""</I>. </DD> <DT><B>-minorticks <I>minorList</I></B> </DT> <DD>Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. <I>MinorList</I> is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the <B>-majortick</B> option is also set. If <I>minorList</I> is <I>""</I>, minor ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the how many degrees to rotate the axis tick labels. <I>Theta</I> is a real value representing the number of degrees to rotate the tick labels. The default is <I>0.0</I> degrees. </DD> <DT><B>-shiftby <I>value</I></B> </DT> <DD>Specifies how much to automatically shift the range of the axis. When the new data exceeds the current axis maximum, the maximum is increased in increments of <I>value</I>. You can use this option to prevent the axis limits from being recomputed at each new time point. If <I>value</I> is 0.0, then no automatic shifting is down. The default is <I>0.0</I>. </DD> <DT><B>-showticks <I>boolean</I></B> </DT> <DD>Indicates whether axis ticks should be drawn. If <I>boolean</I> is true, ticks are drawn. If false, only the axis line is drawn. The default is <I>1</I>. </DD> <DT><B>-stepsize <I>value</I></B> </DT> <DD>Specifies the interval between major axis ticks. If <I>value</I> isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. </DD> <DT><B>-subdivisions <I>number</I></B> </DT> <DD>Indicates how many minor axis ticks are to be drawn. For example, if <I>number</I> is two, only one minor tick is drawn. If <I>number</I> is one, no minor ticks are displayed. The default is <I>2</I>. </DD> <DT><B>-tickfont <I>fontName</I></B> </DT> <DD>Specifies the font for axis tick labels. The default is <I>*-Courier-Bold-R-Normal-*-100-*</I>. </DD> <DT><B>-ticklength <I>pixels</I></B> </DT> <DD>Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If <I>pixels</I> is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is <I>0.1i</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title of the axis. If <I>text</I> is <I>""</I>, no axis title will be displayed. </DD> <DT><B>-titlecolor <I>color</I></B> </DT> <DD>Sets the color of the axis title. The default is <I>black</I>. </DD> <DT><B>-titlefont <I>fontName</I></B> </DT> <DD>Specifies the font for axis title. The default is <I>*-Helvetica-Bold-R-Normal-*-14-140-*</I>. </DD> </DL> <P> Axis configuration options may be also be set by the <B>option</B> command. The resource class is <I>Axis</I>. The resource names are the names of the axes (such as <I>x</I> or <I>x2</I>). <BR> <CODE>option add *Barchart.Axis.Color blue<BR> option add *Barchart.x.LogScale true<BR> option add *Barchart.x2.LogScale false<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>axis <B>create <I>axisName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new axis by the name <I>axisName</I>. No axis by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>delete </B></B></I>?<I>axisName</I>?... </DT> <DD>Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. </DD> <DT><I>pathName <B>axis invtransform <I>axisName value</I></B></I> </DT> <DD>Performs the inverse transformation, changing the screen coordinate <I>value</I> to a graph coordinate, mapping the value mapped to <I>axisName</I>. Returns the graph coordinate. </DD> <DT><I>pathName <B>axis limits <I>axisName</I></B></I> </DT> <DD>Returns a list of the minimum and maximum limits for <I>axisName</I>. The order of the list is <I>min max</I>. </DD> <DT><I>pathName <B>axis names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of axes matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all axes are returned. </DD> <DT><I>pathName <B>axis transform <I>axisName value</I></B></I> </DT> <DD>Transforms the coordinate <I>value</I> to a screen coordinate by mapping the it to <I>axisName</I>. Returns the transformed screen coordinate. </DD> </DL> <P> Only four axes can be displayed simultaneously. By default, they are <I>x</I>, <I>y</I>, <I>x2</I>, and <I>y2</I>. You can swap in a different axis with <B>use</B> operation of the special axis components: <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B>. <BR> <CODE>.g create axis temp<BR> .g create axis time<BR> ...<BR> .g xaxis use temp<BR> .g yaxis use time<BR> </CODE><P>Only the axes specified for use are displayed on the screen. <P> The <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B> components operate on an axis location rather than a specific axis like the more general <B>axis</B> component does. The <B>xaxis</B> component manages the X-axis located in the bottom margin (whatever axis that happens to be). Likewise, <B>yaxis</B> uses the Y-axis in the left margin, <B>x2axis</B> the top X-axis, and <B>y2axis</B> the right Y-axis. <P> They implicitly control the axis that is currently using to that location. By default, <B>xaxis</B> uses the <I>x</I> axis, <B>yaxis</B> uses <I>y</I>, <B>x2axis</B> uses <I>x2</I>, and <B>y2axis</B> uses <I>y2</I>. These components can be more convenient to use than always determining what axes are current being displayed by the graph. <P> The following operations are available for axes. They mirror exactly the operations of the <B>axis</B> component. The <I>axis</I> argument must be <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, or <B>y2axis</B>. <DL> <DT><I>pathName <I>axis <B>cget <I>option</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>configure </B></I></I>?<I>option value</I>?... </DT> <DD></DD> <DT><I>pathName <I>axis<B> invtransform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>limits</B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> transform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> use </B></I></I>?<I>axisName</I>? </DT> <DD>Designates the axis <I>axisName</I> is to be displayed at this location. <I>AxisName</I> can not be already in use at another location. This command returns the name of the axis currently using this location. </DD> </DL> <H3><A NAME="sect10" HREF="#toc10">Crosshairs Component</A></H3> Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire widget. <P> The following operations are available for cross hairs: <DL> <DT><I>pathName <B>crosshairs cget <I>option</I></B></I> </DT> <DD>Returns the current value of the cross hairs configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the cross hairs <B>configure</B> operation. </DD> <DT><I>pathName <B>crosshairs configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the cross hairs. If <I>option</I> isn't specified, a list describing all the current options for the cross hairs is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the cross hairs option <I>option</I> is set to <I>value</I>. The following options are available for cross hairs. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the cross hairs. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the cross hairs. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the cross hairs will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether cross hairs are drawn. If <I>boolean</I> is true, cross hairs are not drawn. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the cross hair lines. The default is <I>1</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies the screen position where the cross hairs intersect. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates of the intersection. </DD> </DL> <P> Cross hairs configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>crosshairs</I> and <I>Crosshairs</I> respectively. <BR> <CODE>option add *Barchart.Crosshairs.LineWidth 2<BR> option add *Barchart.Crosshairs.Color red<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>crosshairs off</B></I> </DT> <DD>Turns off the cross hairs. </DD> <DT><I>pathName <B>crosshairs on</B></I> </DT> <DD>Turns on the display of the cross hairs. </DD> <DT><I>pathName <B>crosshairs toggle</B></I> </DT> <DD>Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. </DD> </DL> <H2><A NAME="sect11" HREF="#toc11">Elements</A></H2> A data element represents a set of data. It contains x and y vectors which are the coordinates of the data points. Elements are displayed as bars where the length of the bar is proportional to the ordinate of the data point. Elements also control the appearance of the data, such as the color, stipple, relief, etc. <P> When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. <P> The following operations are available for elements. <DL> <DT><I>pathName <B>element activate <I>elemName </I></B></I>?<I>index</I>?... </DT> <DD>Specifies the data points of element <I>elemName</I> to be drawn using active foreground and background colors. <I>ElemName</I> is the name of the element and <I>index</I> is a number representing the index of the data point. If no indices are present then all data points become active. </DD> <DT><I>pathName <B>element bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for an element with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on graph elements, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>element cget <I>elemName <I>option</I></I></B></I> </DT> <DD>Returns the current value of the element configuration option given by <I>option</I>. <I>Option</I> may be any of the options described below for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element closest <I>x y</I></B></I> ?<I>option value</I>?... ?<I>elemName</I>?... </DT> <DD>Finds the data point representing the bar closest to the window coordinates <I>x</I> and <I>y</I> in the element <I>elemName</I>. <I>ElemName</I> is the name of an element, which must be displayed. If no elements are specified, then all displayed elements are searched. It returns a list containing the name of the closest element, the index of its closest point, and the graph coordinates of the point. If no data point within the threshold distance can be found, <I>""</I> is returned. The following <I>option</I>-<I>value</I> pairs are available. <blockquote></DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a threshold distance where selected data points are ignored. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. If this option isn't specified, then it defaults to the value of the <B>barchart</B>'s <B>-halo</B> option. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>element configure <I>elemName </I></B></I>?<I>elemName</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for elements. Several elements can be modified at the same time. If <I>option</I> isn't specified, a list describing all the current options for <I>elemName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing the option <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the element option <I>option</I> is set to <I>value</I>. The following options are valid for elements. <blockquote></DD> <DT><B>-activepen <I>penName</I></B> </DT> <DD>Specifies pen to use to draw active element. If <I>penName</I> is <I>""</I>, no active elements will be drawn. The default is <I>activeLine</I>. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for the element. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events for elements. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the the color of the border around each bar. The default is <I>white</I>. </DD> <DT><B>-barwidth <I>value</I></B> </DT> <DD>Specifies the width the bars drawn for the element. <I>Value</I> is the width in X-coordinates. If this option isn't specified, the width of each bar is the value of the widget's <B>-barwidth</B> option. </DD> <DT><B>-baseline <I>value</I></B> </DT> <DD>Specifies the baseline of the bar segments. This affects how bars are drawn since bars are drawn from their respective y-coordinate the baseline. By default the baseline is <I>0.0</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the border width of the 3-D border drawn around the outside of each bar. The <B>-relief</B> option determines if such a border is drawn. <I>Pixels</I> must be a valid screen distance like <I>2</I> or <I>0.25i</I>. The default is <I>2</I>. </DD> <DT><B>-data <I>coordList</I></B> </DT> <DD>Specifies the X-Y coordinates of the data. <I>CoordList</I> is a list of numeric expressions representing the X-Y coordinate pairs of each data point. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the color of the interior of the bars. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the element is displayed. The default is <I>no</I>. </DD> <DT><B>-label <I>text</I></B> </DT> <DD>Sets the element's label in the legend. If <I>text</I> is <I>""</I>, the element will have no entry in the legend. The default label is the element's name. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Selects the X-axis to map the element's X-coordinates onto. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Selects the Y-axis to map the element's Y-coordinates onto. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-relief <I>string</I></B> </DT> <DD>Specifies the 3-D effect desired for bars. <I>Relief</I> indicates how the interior of the bar should appear relative to the surface of the chart; for example, <I>raised</I> means the bar should appear to protrude from the surface of the plotting area. The default is <I>raised</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern with which to draw the bars. If <I>bitmap</I> is <I>""</I>, then the bar is drawn in a solid fashion. </DD> <DT><B>-xdata <I>xVector</I></B> </DT> <DD>Specifies the x-coordinate vector of the data. <I>XVector</I> is the name of a BLT vector or a list of numeric expressions. </DD> <DT><B>-ydata <I>yVector</I></B> </DT> <DD>Specifies the y-coordinate vector of the data. <I>YVector</I> is the name of a BLT vector or a list of numeric expressions. </DD> </DL> <P> Element configuration options may also be set by the <B>option</B> command. The resource names in the option database are prefixed by <I>elem</I>. <BR> <CODE>option add *Barchart.Element.background blue<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>element create <I>elemName</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a new element <I>elemName</I>. Element names must be unique, so an element <I>elemName</I> may not already exist. If additional arguments are present, they specify any of the element options valid for element <B>configure</B> operation. </DD> <DT><I>pathName <B>element deactivate <I>pattern</I></B></I>... </DT> <DD>Deactivates all the elements matching <I>pattern</I> for the graph. Elements whose names match any of the patterns given are redrawn using their normal colors. </DD> <DT><I>pathName <B>element delete</B></I> ?<I>pattern</I>?... </DT> <DD>Deletes all the elements matching <I>pattern</I> for the graph. Elements whose names match any of the patterns given are deleted. The graph will be redrawn without the deleted elements. </DD> <DT><I>pathName <B>element exists <I>elemName</I></B></I> </DT> <DD>Returns <I>1</I> if an element <I>elemName</I> currently exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>element names </B></I>?<I>pattern</I>?... </DT> <DD>Returns the elements matching one or more pattern. If no <I>pattern</I> is given, the names of all elements is returned. </DD> <DT><I>pathName <B>element show</B></I> ?<I>nameList</I>? </DT> <DD>Queries or modifies the element display list. The element display list designates the elements drawn and in what order. <I>NameList</I> is a list of elements to be displayed in the order they are named. If there is no <I>nameList</I> argument, the current display list is returned. </DD> <DT><I>pathName <B>element type</B></I> <I>elemName</I> </DT> <DD>Returns the type of <I>elemName</I>. If the element is a bar element, the commands returns the string <I>"bar"</I>, otherwise it returns <I>"line"</I>. </DD> </DL> <H3><A NAME="sect12" HREF="#toc12"></CODE><P>Grid Component</A></H3> Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. <DL> <DT><I>pathName <B>grid cget <I>option</I></B></I> </DT> <DD>Returns the current value of the grid line configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the grid <B>configure</B> operation. </DD> <DT><I>pathName <B>grid configure</B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for grid lines. If <I>option</I> isn't specified, a list describing all the current grid options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the grid line option <I>option</I> is set to <I>value</I>. The following options are valid for grid lines. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the grid lines. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the grid lines. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the grid will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the grid should be drawn. If <I>boolean</I> is true, grid lines are not shown. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of grid lines. The default width is <I>1</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to display grid lines. <I>XAxis</I> must be the name of an axis or <I>""</I> for no grid lines. The default is <I>""</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to display grid lines. <I>YAxis</I> must be the name of an axis or <I>""</I> for no grid lines. The default is <I>y</I>. </DD> <DT><B>-minor <I>boolean</I></B> </DT> <DD>Indicates whether the grid lines should be drawn for minor ticks. If <I>boolean</I> is true, the lines will appear at minor tick intervals. The default is <I>1</I>. </DD> </DL> <P> Grid configuration options may also be set by the <B>option</B> command. The resource name and class are <I>grid</I> and <I>Grid</I> respectively. <BR> <CODE>option add *Barchart.grid.LineWidth 2<BR> option add *Barchart.Grid.Color black<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>grid off</B></I> </DT> <DD>Turns off the display the grid lines. </DD> <DT><I>pathName <B>grid on</B></I> </DT> <DD>Turns on the display the grid lines. </DD> <DT><I>pathName <B>grid toggle</B></I> </DT> <DD>Toggles the display of the grid. </DD> </DL> <H3><A NAME="sect13" HREF="#toc13">Legend Component</A></H3> The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. <P> The following operations are valid for the legend. <DL> <DT><I>pathName <B>legend activate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a legend entry with this tag, <I>command</I> will be invoked. Implicitly the element names in the entry are tags. The syntax is similar to the <B>bind</B> command except that it operates on legend entries, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>legend cget <I>option</I></B></I> </DT> <DD>Returns the current value of a legend configuration option. <I>Option</I> may be any option described below in the legend <B>configure</B> operation. </DD> <DT><I>pathName <B>legend configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for the legend. If <I>option</I> isn't specified, a list describing the current legend options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the legend option <I>option</I> is set to <I>value</I>. The following options are valid for the legend. <blockquote></DD> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active legend entries. All legend entries marked active (see the legend <B>activate</B> operation) are drawn using this background color. </DD> <DT><B>-activeborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the active legend entries. The default is <I>2</I>. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color for active legend entries. All legend entries marked as active (see the legend <B>activate</B> operation) are drawn using this foreground color. </DD> <DT><B>-activerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect desired for active legend entries. <I>Relief</I> denotes how the interior of the entry should appear relative to the legend; for example, <I>raised</I> means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is <I>flat</I>. </DD> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the <B>-position</B> option. The default is <I>center</I>. <blockquote></DD> <DT><I>left</I> or <I>right</I> </DT> <DD>The anchor describes how to position the legend vertically. </DD> <DT><I>top</I> or <I>bottom</I> </DT> <DD>The anchor describes how to position the legend horizontally. </DD> <DT><I>@x,y</I> </DT> <DD>The anchor specifies how to position the legend relative to the positioning point. For example, if <I>anchor</I> is <I>center</I> then the legend is centered on the point; if <I>anchor</I> is <I>n</I> then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. </DD> <DT><I>plotarea</I> </DT> <DD>The anchor specifies how to position the legend relative to the plotting area. For example, if <I>anchor</I> is <I>center</I> then the legend is centered in the plotting area; if <I>anchor</I> is <I>ne</I> then the legend will be drawn such that occupies the upper right corner of the plotting area. </DD> </DL> </blockquote> <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the legend. If <I>color</I> is <I>""</I>, the legend background with be transparent. </DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for legend entries. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events for legend entries. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is <I>all</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the <B>relief</B> option determines this). The default is <I>2</I> pixels. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD><I>FontName</I> specifies a font to use when drawing the labels of each element into the legend. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of the text drawn for the element's label. The default is <I>black</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the legend should be displayed. If <I>boolean</I> is true, the legend will not be draw. The default is <I>no</I>. </DD> <DT><B>-ipadx <I>pad</I></B> </DT> <DD>Sets the amount of internal padding to be added to the width of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-ipady <I>pad</I></B> </DT> <DD>Sets an amount of internal padding to be added to the height of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the entry is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom of the entry are padded evenly. The default is <I>2</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the legend is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>0</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies where the legend is drawn. The <B>-anchor</B> option also affects where the legend is positioned. If <I>pos</I> is <I>left</I>, <I>left</I>, <I>top</I>, or <I>bottom</I>, the legend is drawn in the specified margin. If <I>pos</I> is <I>plotarea</I>, then the legend is drawn inside the plotting area at a particular anchor. If <I>pos</I> is in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is <I>right</I>. </DD> <DT><B>-raised <I>boolean</I></B> </DT> <DD>Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If <I>boolean</I> is true, the legend will be drawn on top of any elements that may overlap it. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the border around the legend. <I>Relief</I> specifies how the interior of the legend should appear relative to the bar chart; for example, <I>raised</I> means the legend should appear to protrude from the bar chart, relative to the surface of the bar chart. The default is <I>sunken</I>. </DD> </DL> <P> Legend configuration options may also be set by the <B>option</B> command. The resource name and class are <I>legend</I> and <I>Legend</I> respectively. <BR> <CODE>option add *Barchart.legend.Foreground blue<BR> option add *Barchart.Legend.Relief raised<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>legend deactivate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend get <I>pos</I></B></I> </DT> <DD>Returns the name of the element whose entry is at the screen position <I>pos</I> in the legend. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are window coordinates. If the given coordinates do not lie over a legend entry, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect14" HREF="#toc14">Pen Components</A></H3> Pens define attributes for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). <P> One pen, called <I>activeBar</I>, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. <BR> <CODE>.g pen configure "activeBar" -fg green -bg green4<BR> </CODE><P>You can create and use several pens. To create a pen, invoke the pen component and its create operation. <BR> <CODE>.g pen create myPen<BR> </CODE><P>You map pens to a data element using either the element's <B>-pen</B> or <B>-activepen</B> options. <BR> <CODE>.g element create "e1" -xdata $x -ydata $tempData \<BR> -pen myPen<BR> </CODE><P>An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the <B>-styles</B> option). <BR> <CODE>.g element configure "e1" -styles { myPen 2.0 3.0 }<BR> </CODE><P>This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen <I>myPen</I>. All other points are drawn with the element's default attributes. <P> The following operations are available for pen components. <P> <DL> <DT><I>pathName <B>pen <B>cget <I>penName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>penName</I>. <I>Option</I> may be any option described below for the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>configure <I>penName </I></B></B></I>?<I>penName</I>... ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>penName</I>. Several pens can be modified at once. If <I>option</I> isn't specified, a list describing the current options for <I>penName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the pen option <I>option</I> is set to <I>value</I>. The following options are valid for pens. <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the the color of the border around each bar. The default is <I>white</I>. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the border width of the 3-D border drawn around the outside of each bar. The <B>-relief</B> option determines if such a border is drawn. <I>Pixels</I> must be a valid screen distance like <I>2</I> or <I>0.25i</I>. The default is <I>2</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the color of the interior of the bars. </DD> <DT><B>-relief <I>string</I></B> </DT> <DD>Specifies the 3-D effect desired for bars. <I>Relief</I> indicates how the interior of the bar should appear relative to the surface of the chart; for example, <I>raised</I> means the bar should appear to protrude from the bar chart, relative to the surface of the plotting area. The default is <I>raised</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern with which to draw the bars. If <I>bitmap</I> is <I>""</I>, then the bar is drawn in a solid fashion. </DD> <DT><B>-type <I>elemType</I></B> </DT> <DD>Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "bar". </DD> </DL> <P> Pen configuration options may be also be set by the <B>option</B> command. The resource class is <I>Pen</I>. The resource names are the names of the pens. <BR> <CODE>option add *Barchart.Pen.Foreground<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp; blue<BR> option add *Barchart.activeBar.foreground green<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>pen <B>create <I>penName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new pen by the name <I>penName</I>. No pen by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>delete </B></B></I>?<I>penName</I>?... </DT> <DD>Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. </DD> <DT><I>pathName <B>pen names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of pens matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all pens are returned. </DD> </DL> <H3><A NAME="sect15" HREF="#toc15">PostScript Component</A></H3> The barchart can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot will be generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. <P> The following postscript operations are available. <DL> <DT><I>pathName <B>postscript cget <I>option</I></B></I> </DT> <DD>Returns the current value of the postscript option given by <I>option</I>. <I>Option</I> may be any option described below for the postscript <B>configure</B> operation. </DD> <DT><I>pathName <B>postscript configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for PostScript generation. If <I>option</I> isn't specified, a list describing the current postscript options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the postscript option <I>option</I> is set to <I>value</I>. The following postscript options are available. <blockquote></DD> <DT><B>-center <I>boolean</I></B> </DT> <DD>Indicates whether the plot should be centered on the PostScript page. If <I>boolean</I> is false, the plot will be placed in the upper left corner of the page. The default is <I>1</I>. </DD> <DT><B>-colormap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of <I>varName</I> must consist of PostScript code to set a particular color value (e.g. ``<I>1.0 1.0 0.0 setrgbcolor</I>''). When generating color information in PostScript, the array variable <I>varName</I> is checked if an element of the name as the color exists. If so, it uses its value as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in <I>varName</I> for a given color, then it uses the red, green, and blue intensities from the X color. </DD> <DT><B>-colormode <I>mode</I></B> </DT> <DD>Specifies how to output color information. <I>Mode</I> must be either <I>color</I> (for full color output), <I>gray</I> (convert all colors to their gray-scale equivalents) or <I>mono</I> (convert foreground colors to black and background colors to white). The default mode is <I>color</I>. </DD> <DT><B>-fontmap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of <I>varName</I> must consist of a Tcl list with one or two elements; the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable <I>varName</I> is checked to see if an element by the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is <I>Adobe</I> (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to <I>Helvetica-Bold</I>. </DD> <DT><B>-decorations <I>boolean</I></B> </DT> <DD>Indicates whether PostScript commands to generate color backgrounds and 3-D borders will be output. If <I>boolean</I> is false, the graph will background will be white and no 3-D borders will be generated. The default is <I>1</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Sets the height of the plot. This lets you print the bar chart with a height different from the one drawn on the screen. If <I>pixels</I> is 0, the height is the same as the widget's height. The default is <I>0</I>. </DD> <DT><B>-landscape <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to <I>0</I>. </DD> <DT><B>-maxpect <I>boolean</I></B> </DT> <DD>Indicates to scale the plot so that it fills the PostScript page. The aspect ratio of the barchart is still retained. The default is <I>0</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left border is padded by the first distance and the right border by the second. If <I>pad</I> has just one distance, both the left and right borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top border is padded by the first distance and the bottom border by the second. If <I>pad</I> has just one distance, both the top and bottom borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-paperheight <I>pixels</I></B> </DT> <DD>Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is <I>11.0i</I>. </DD> <DT><B>-paperwidth <I>pixels</I></B> </DT> <DD>Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is <I>8.5i</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the width of the plot. This lets you generate a plot of a width different from that of the widget. If <I>pixels</I> is 0, the width is the same as the widget's width. The default is <I>0</I>. </DD> </DL> <P> Postscript configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>postscript</I> and <I>Postscript</I> respectively. <BR> <CODE>option add *Barchart.postscript.Decorations false<BR> option add *Barchart.Postscript.Landscape true<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>postscript output </B></I>?<I>fileName</I>? ?<I>option value</I>?... </DT> <DD>Outputs a file of encapsulated PostScript. If a <I>fileName</I> argument isn't present, the command returns the PostScript. If any <I>option-value</I> pairs are present, they set configuration options controlling how the PostScript is generated. <I>Option</I> and <I>value</I> can be anything accepted by the postscript <B>configure</B> operation above. </DD> </DL> <H3><A NAME="sect16" HREF="#toc16">Marker Components</A></H3> Markers are simple drawing procedures used to annotate or highlight areas of the graph. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the <B>-under</B> option. <P> Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have <I>elastic</I> coordinates (specified by <I>-Inf</I> and <I>Inf</I> respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates <I>-Inf</I>,<I>-Inf</I>. <P> The following operations are available for markers. <DL> <DT><I>pathName <B>marker after <I>markerId</I></B></I> ?<I>afterId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker after the second. If no second <I>afterId</I> argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker before <I>markerId</I></B></I> ?<I>beforeId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker before the second. If no second <I>beforeId</I> argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker bind <I>tagName</I></B></I> ?<I>sequence</I>? ?<I>command</I>? </DT> <DD>Associates <I>command</I> with <I>tagName</I> such that whenever the event sequence given by <I>sequence</I> occurs for a marker with this tag, <I>command</I> will be invoked. The syntax is similar to the <B>bind</B> command except that it operates on graph markers, rather than widgets. See the <B>bind</B> manual entry for complete details on <I>sequence</I> and the substitutions performed on <I>command</I> before invoking it. <P> If all arguments are specified then a new binding is created, replacing any existing binding for the same <I>sequence</I> and <I>tagName</I>. If the first character of <I>command</I> is <I>+</I> then <I>command</I> augments an existing binding rather than replacing it. If no <I>command</I> argument is provided then the command currently associated with <I>tagName</I> and <I>sequence</I> (it's an error occurs if there's no such binding) is returned. If both <I>command</I> and <I>sequence</I> are missing then a list of all the event sequences for which bindings have been defined for <I>tagName</I>. </DD> <DT><I>pathName <B>marker cget <I>option</I></B></I> </DT> <DD>Returns the current value of the marker configuration option given by <I>option</I>. <I>Option</I> may be any option described below in the <B>configure</B> operation. </DD> <DT><I>pathName <B>marker configure <I>markerId</I></B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for markers. If <I>option</I> isn't specified, a list describing the current options for <I>markerId</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the marker option <I>option</I> is set to <I>value</I>. <P> The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. <blockquote></DD> <DT><B>-bindtags <I>tagList</I></B> </DT> <DD>Specifies the binding tags for the marker. <I>TagList</I> is a list of binding tag names. The tags and their order will determine how events for markers are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the marker is always the first tag in the list. The default value is <I>all</I>. </DD> <DT><B>-coords <I>coordList</I></B> </DT> <DD>Specifies the coordinates of the marker. <I>CoordList</I> is a list of graph coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If <I>coordList</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-element <I>elemName</I></B> </DT> <DD>Links the marker with the element <I>elemName</I>. The marker is drawn only if the element is also currently displayed (see the element's <B>show</B> operation). If <I>elemName</I> is <I>""</I>, the marker is always drawn. The default is <I>""</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn. If <I>boolean</I> is true, the marker is not drawn. The default is <I>no</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to map the marker's X-coordinates onto. <I>XAxis</I> must the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to map the marker's Y-coordinates onto. <I>YAxis</I> must the name of an axis. The default is <I>y</I>. </DD> <DT><B>-name <I>markerId</I></B> </DT> <DD>Changes the identifier for the marker. The identifier <I>markerId</I> can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. </DD> <DT><B>-under <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn below/above data elements. If <I>boolean</I> is true, the marker is be drawn underneath the data elements. Otherwise, the marker is drawn on top of the element. The default is <I>0</I>. </DD> <DT><B>-xoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the marker horizontally. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> <DT><B>-yoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the markers vertically. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> </DL> <P> Marker configuration options may also be set by the <B>option</B> command. The resource class is either <I>BitmapMarker</I>, <I>ImageMarker</I>, <I>LineMarker</I>, <I>PolygonMarker</I>, <I>TextMarker</I>, or <I>WindowMarker</I>, depending on the type of marker. The resource name is the name of the marker. <BR> <CODE>option add *Barchart.TextMarker.Foreground white<BR> option add *Barchart.BitmapMarker.Foreground white<BR> option add *Barchart.m1.Background blue<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>marker create <I>type</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a marker of the selected type. <I>Type</I> may be either <I>text</I>, <I>line</I>, <I>bitmap</I>, <I>image</I>, <I>polygon</I>, or <I>window</I>. This command returns the marker identifier, used as the <I>markerId</I> argument in the other marker-related commands. If the <B>-name</B> option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. </DD> <DT><I>pathName <B>marker delete</B></I> ?<I>name</I>?... </DT> <DD>Removes one of more markers. The graph will automatically be redrawn without the marker.. </DD> <DT><I>pathName <B>marker exists <I>markerId</I></B></I> </DT> <DD>Returns <I>1</I> if the marker <I>markerId</I> exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>marker names</B></I> ?<I>pattern</I>? </DT> <DD>Returns the names of all the markers that currently exist. If <I>pattern</I> is supplied, only those markers whose names match it will be returned. </DD> <DT><I>pathName <B>marker type <I>markerId</I></B></I> </DT> <DD>Returns the type of the marker given by <I>markerId</I>, such as <I>line</I> or <I>text</I>. If <I>markerId</I> is not a valid a marker identifier, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect17" HREF="#toc17">Bitmap Markers</A></H3> A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. <P> Bitmap markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create bitmap </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration options for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to bitmap markers: <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Same as the <B>-fill</B> option. </DD> <DT><B>-bitmap <I>bitmap</I></B> </DT> <DD>Specifies the bitmap to be displayed. If <I>bitmap</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the bitmap. If <I>color</I> is the empty string, no background will be transparent. The default background color is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Same as the <B>-outline</B> option. </DD> <DT><B>-mask <I>mask</I></B> </DT> <DD>Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If <I>mask</I> is <I>""</I>, all pixels of the bitmap will be drawn. The default is <I>""</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the foreground color of the bitmap. The default value is <I>black</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Sets the rotation of the bitmap. <I>Theta</I> is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is <I>0.0</I>. </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Image Markers</A></H3> A image marker displays an image. Image markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create image </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to image markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the image relative to the positioning point for the image. For example, if <I>anchor</I> is <I>center</I> then the image is centered on the point; if <I>anchor</I> is <I>n</I> then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-image <I>image</I></B> </DT> <DD>Specifies the image to be drawn. If <I>image</I> is <I>""</I>, the marker will not be drawn. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Line Markers</A></H3> A line marker displays one or more connected line segments. Line markers are created with marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create line </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to line markers: <DL> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the marker line will be solid. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the line. This color is used with striped lines (see the <B>-fdashesR option). If <I>color</I></B> is the empty string, no background color is drawn (the line will be dashed, not striped). The default background color is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the lines. The default width is <I>0</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the foreground color of the line. The default value is <I>black</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern used to draw the line, rather than a solid line. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the line is drawn in a solid fashion. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Polygon Markers</A></H3> A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create polygon </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the <B>marker configure</B> command to change the marker's configuration. The following options are supported for polygon markers: <DL> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline of the polygon. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the outline will be a solid line. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the fill color of the polygon. If <I>color</I> is <I>""</I>, then the interior of the polygon is transparent. The default is <I>white</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline of the polygon. If <I>pixels</I> is zero, no outline is drawn. The default is <I>0</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color of the outline of the polygon. If the polygon is stippled (see the <B>-stipple</B> option), then this represents the foreground color of the stipple. The default is <I>black</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the polygon is filled with a solid color (if the <B>-fill</B> option is set). The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Text Markers</A></H3> A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the graph. Text markers are created with the <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create text </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the text marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to text markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the text relative to the positioning point for the text. For example, if <I>anchor</I> is <I>center</I> then the text is centered on the point; if <I>anchor</I> is <I>n</I> then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is <I>center</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Same as the <B>-fill</B> option. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the text. The default is <I>*-Helvetica-Bold-R-Normal-*-120-*</I>. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the background color of the text. If <I>color</I> is the empty string, no background will be transparent. The default background color is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Same as the <B>-outline</B> option. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the text should be justified. This matters only when the marker contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color of the text. The default value is <I>black</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the text is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the text is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>4</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the number of degrees to rotate the text. <I>Theta</I> is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is <I>0.0</I>. </DD> <DT><B>-text <I>text</I></B> </DT> <DD>Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as <B>-anchor</B> or <B>-rotate</B>. </DD> </DL> <H3><A NAME="sect22" HREF="#toc22">Window Markers</A></H3> A window marker displays a widget at a given position. Window markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create window </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> command. <P> The following options are specific to window markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the widget relative to the positioning point for the widget. For example, if <I>anchor</I> is <I>center</I> then the widget is centered on the point; if <I>anchor</I> is <I>n</I> then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever height the widget requests internally. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever width the widget requests internally. </DD> <DT><B>-window <I>pathName</I></B> </DT> <DD>Specifies the widget to be managed by the barchart. <I>PathName</I> must be a child of the <B>barchart</B> widget. </DD> </DL> <H2><A NAME="sect23" HREF="#toc23">Graph Component Bindings</A></H2> Specific barchart components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as <B>Enter</B>, <B>Leave</B>, <B>ButtonPress</B>, <B>Motion</B>, and <B>KeyPress</B>). <P> Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. <P> It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the <B>-bindtags</B> option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. <P> The <B>-bindtags</B> option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the <B>-bindtags</B> option doesn't change this. <H2><A NAME="sect24" HREF="#toc24">C Language API</A></H2> You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. <P> Data can manipulated from the C language using BLT vectors. You specify the X-Y data coordinates of an element as vectors and manipulate the vector from C. The barchart will be redrawn automatically after the vectors are updated. <P> From Tcl, create the vectors and configure the element to use them. <BR> <CODE>vector X Y<BR> .g element configure line1 -xdata X -ydata Y<BR> </CODE><P>To set data points from C, you pass the values as arrays of doubles using the <B>Blt_ResetVector</B> call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the graph will be redrawn automatically. <BR> <CODE>#include &lt;tcl.h&gt;<BR> #include &lt;blt.h&gt;<BR> <P> register int i;<BR> Blt_Vector *xVec, *yVec;<BR> double x[50], y[50];<BR> <P> /* Get the BLT vectors "X" and "Y" (created above from Tcl) */<BR> if ((Blt_GetVector(interp, "X", 50, &amp;xVec) != TCL_OK) ||<BR> (Blt_GetVector(interp, "Y", 50, &amp;yVec) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> <P> for (i = 0; i &lt; 50; i++) {<BR> x[i] = i * 0.02;<BR> y[i] = sin(x[i]);<BR> }<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<BR> <P> /* Put the data into BLT vectors */<BR> if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) ||<BR> (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> </CODE><P>See the <B>vector</B> manual page for more details. <H2><A NAME="sect25" HREF="#toc25">Speed Tips</A></H2> There may be cases where the bar chart needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. <UL> &#183;<LI>Try to minimize the number of data points. The more data points looked at, the more work the bar chart must do. </LI>&#183;<LI>If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. </LI>&#183;<LI>Don't stipple or dash the element. Solid bars are much faster. </LI>&#183;<LI>If you update data elements frequently, try turning off the widget's <B>-bufferelements</B> option. When the bar chart is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the bar chart needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the bar chart. But if the bar chart is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. </LI> </UL> <H2><A NAME="sect26" HREF="#toc26">Limitations</A></H2> Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. <P> The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. <H2><A NAME="sect27" HREF="#toc27">Keywords</A></H2> bar chart, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Syntax</A></LI> <LI><A NAME="toc5" HREF="#sect5">Example</A></LI> <LI><A NAME="toc6" HREF="#sect6">Syntax</A></LI> <LI><A NAME="toc7" HREF="#sect7">Barchart Operations</A></LI> <LI><A NAME="toc8" HREF="#sect8">Barchart Components</A></LI> <UL> <LI><A NAME="toc9" HREF="#sect9">Axis Components</A></LI> <LI><A NAME="toc10" HREF="#sect10">Crosshairs Component</A></LI> </UL> <LI><A NAME="toc11" HREF="#sect11">Elements</A></LI> <UL> <LI><A NAME="toc12" HREF="#sect12">Grid Component</A></LI> <LI><A NAME="toc13" HREF="#sect13">Legend Component</A></LI> <LI><A NAME="toc14" HREF="#sect14">Pen Components</A></LI> <LI><A NAME="toc15" HREF="#sect15">PostScript Component</A></LI> <LI><A NAME="toc16" HREF="#sect16">Marker Components</A></LI> <LI><A NAME="toc17" HREF="#sect17">Bitmap Markers</A></LI> <LI><A NAME="toc18" HREF="#sect18">Image Markers</A></LI> <LI><A NAME="toc19" HREF="#sect19">Line Markers</A></LI> <LI><A NAME="toc20" HREF="#sect20">Polygon Markers</A></LI> <LI><A NAME="toc21" HREF="#sect21">Text Markers</A></LI> <LI><A NAME="toc22" HREF="#sect22">Window Markers</A></LI> </UL> <LI><A NAME="toc23" HREF="#sect23">Graph Component Bindings</A></LI> <LI><A NAME="toc24" HREF="#sect24">C Language API</A></LI> <LI><A NAME="toc25" HREF="#sect25">Speed Tips</A></LI> <LI><A NAME="toc26" HREF="#sect26">Limitations</A></LI> <LI><A NAME="toc27" HREF="#sect27">Keywords</A></LI> </UL> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/bitmap.html������������������������������������������������������������������0000644�0001750�0001750�00000021715�11462120062�015352� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>bitmap(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> bitmap - Define a new bitmap from a Tcl script <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>bitmap define <I>bitmapName data</I></B> ?<I>option value</I>?... <P> <B>bitmap compose <I>bitmapName text</I></B> ?<I>option value</I>?... <P> <B>bitmap exists <I>bitmapName</I></B> <P> <B>bitmap source <I>bitmapName</I></B> <P> <B>bitmap data <I>bitmapName</I></B> <P> <B>bitmap height <I>bitmapName</I></B> <P> <B>bitmap width <I>bitmapName</I></B> <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>bitmap</B> command lets you create new bitmaps directly from your Tcl script. The bitmap can be specified as a list of data or a text string which is converted into a bitmap. You can arbitrarily scale or rotate the bitmap too. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Bitmaps are commonly used within Tk. In label and button widgets, you display bitmaps them instead of text strings and in the canvas and text widgets, they're used for stippling. But Tk let's you can create new bitmaps only by reading the bitmap data from a file. This makes bitmaps cumbersome to manage, especially in packaging the program as a <B>wish</B> script, since each bitmap must be its own file. It would be nicer if you could create new bitmaps directly from your Tcl script. <P> The <B>bitmap</B> command lets you do just that. You can specify the bitmap as in various formats (such as the X11 bitmap format). You can also compose a bitmap from a text string. The <B>bitmap</B> command also lets you and arbitrarily rotate or scale the bitmap. For example, you could use this to create button widgets with the text label rotated 90 degrees. <H2><A NAME="sect4" HREF="#toc4">Example</A></H2> &lt;&lt;&lt;&lt;&lt;&lt;&lt; bitmap.mann You can define a new bitmap with the <B>define</B> operation. For example, let's say you are using the X11 bitmap "gray1". Normally to use it, you would specify the location of the file. <BR> <CODE>label .l -bitmap @/usr/X11R6/include/X11/bitmaps/gray1<BR> </CODE><P>But you can simply cut and paste the contents of "gray1" into the <B>bitmap</B> command. <BR> <CODE>bitmap define gray1 {<BR> #define gray1_width 2<BR> #define gray1_height 2<BR> static char gray1_bits[] = {<BR> 0x01, 0x02};<BR> }<BR> label .l -bitmap gray1<BR> </CODE><P>Tk will recognize "gray1" as a bitmap which can now be used with any widget that accepts bitmaps. <BR> <CODE></CODE><P>The bitmap data can be specified in a mulitude of forms. The following commands are all equivalent. <BR> <CODE>bitmap define gray1 {<BR> #define gray1_width 2<BR> #define gray1_height 2<BR> static char gray1_bits[] = {<BR> 0x01, 0x02};<BR> }<BR> bitmap define gray1 { { 2 2 } { 0x01, 0x02 } }<BR> bitmap define gray1 { { 2 2 } { 0x01 0x02 } }<BR> bitmap define gray1 { { 2 2 } { 1 2 } }<BR> </CODE><P>Either the data is in the standard X11 bitmap form, or it's a list of two lists. The first list contains the height and width of the bitmap. The second list is the bitmap source data. Each element of that list is an hexadecimal number specifying which pixels are <A HREF="foreground.1.html">foreground (1)</A> and which are background (0) of the bitmap. Note that the format of the source data is exactly that of the XBM format. <P> You can scale or rotate the bitmap as you create it, by using the <B>-scale</B> or<B>-rotate</B> options. <BR> <CODE>bitmap define gray1 {<BR> #define gray1_width 2<BR> #define gray1_height 2<BR> static char gray1_bits[] = {<BR> 0x01, 0x02};<BR> } -scale 2.0 -rotate 90.0<BR> </CODE><P>In addition, you can compose bitmaps from text strings. This makes it easy to create rotated buttons or labels. The text string can have multi-line. <BR> <CODE>bitmap compose rot_text "This is rotated\ntext" \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-rotate 90.0 -font fixed<BR> </CODE><P>There are also a number of ways to query bitmaps. This isn't limited to bitmaps that you create, but any bitmap. <BR> <CODE>bitmap exists rot_text<BR> bitmap width rot_text<BR> bitmap height rot_text<BR> bitmap data rot_text<BR> bitmap source rot_text<BR> </CODE><P>The <B>exists</B> operation indicates if a bitmap by that name is defined. You can query the dimensions of the bitmap using the <B>width</B> and <B>height</B> operations. The <B>data</B> operation returns the list of the data used to create the bitmap. For example, you could query the data of a bitmap and <B>send</B> it across the network to another Tk application. <BR> <CODE>set data [bitmap data @/usr/X11R6/include/X11/bitmaps/ghost.xbm]<BR> send {wish #2} bitmap define ghost $data<BR> <H2><A NAME="sect5" HREF="#toc5"></CODE><P>Operations</A></H2> The following operations are available for <B>bitmap</B>: <DL> <DT><B>bitmap compose <I>bitmapName text </I></B>?<I>option value</I>?... </DT> <DD>Creates a bitmap <I>bitmapName</I> from the text string <I>text</I>. A bitmap <I>bitmapName</I> can not already exist. The following options are available. <blockquote></DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies a font to use when drawing text into the bitmap. If this option isn't specified then <I>fontName</I> defaults to <I>*-Helvetica-Bold-R-Normal-*-140-*</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the angle of rotation of the text in the bitmap. <I>Theta</I> is a real number representing the angle in degrees. It defaults to <I>0.0</I> degrees. </DD> <DT><B>-scale <I>value</I></B> </DT> <DD>Specifies the scale of the bitmap. <I>Value</I> is a real number representing the scale. A scale of 1.0 indicates no scaling is necessary, while 2.0 would double the size of the bitmap. There is no way to specify differents scales for the width and height of the bitmap. The default scale is <I>1.0</I>. </DD> </DL> </blockquote> <DL> <DT><B>bitmap data <I>bitmapName</I></B> </DT> <DD>Returns a list of both the dimensions of the bitmap <I>bitmapName</I> and its source data. </DD> <DT><B>bitmap define <I>bitmapName data</I></B> ?<I>option value</I>?... </DT> <DD>Associates <I>bitmapName</I> with in-memory bitmap data so that <I>bitmapName</I> can be used in later calls to <B>Tk_GetBitmap</B>. The <I>bitmapName</I> argument is the name of the bitmap; it must not previously have been defined in either a call to Tk_DefineBitmap or <B>bitmap</B>. The argument <I>data</I> describes the bitmap to be created. It is either the X11 bitmap format (a C structure) or a list of two lists: the dimensions and source data. The dimensions are a list of two numbers which are the width and height of the bitmap. The source data is a list of hexadecimal values in a format similar to the X11 or X10 bitmap format. The values may be optionally separated by commas and do not need to be prefixed with "0x". The following options are available. <blockquote></DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies how many degrees to rotate the bitmap. <I>Theta</I> is a real number representing the angle. The default is <I>0.0</I> degrees. </DD> <DT><B>-scale <I>value</I></B> </DT> <DD>Specifies how to scale the bitmap. <I>Value</I> is a real number representing the scale. A scale of 1.0 indicates no scaling is necessary, while 2.0 would double the size of the bitmap. There is no way to specify differents scales for the width and height of the bitmap. The default scale is <I>1.0</I>. </DD> </DL> </blockquote> <DL> <DT><B>bitmap exists <I>bitmapName</I></B> </DT> <DD>Returns <I>1</I> if a bitmap <I>bitmapName</I> exists, otherwise <I>0</I>. </DD> <DT><B>bitmap height <I>bitmapName</I></B> </DT> <DD>Returns the height in pixels of the bitmap <I>bitmapName</I>. </DD> <DT><B>bitmap source <I>bitmapName</I></B> </DT> <DD>Returns the source data of the bitmap <I>bitmapName</I>. The source data is a list of the hexadecimal values. </DD> <DT><B>bitmap width <I>bitmapName</I></B> </DT> <DD>Returns the width in pixels of the bitmap <I>bitmapName</I>. </DD> </DL> <H2><A NAME="sect6" HREF="#toc6">Limitations</A></H2> Tk currently offers no way of destroying bitmaps. Once a bitmap is created, it exists until the application terminates. <H2><A NAME="sect7" HREF="#toc7">Keywords</A></H2> bitmap <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Example</A></LI> <LI><A NAME="toc5" HREF="#sect5">Operations</A></LI> <LI><A NAME="toc6" HREF="#sect6">Limitations</A></LI> <LI><A NAME="toc7" HREF="#sect7">Keywords</A></LI> </UL> </BODY></HTML> ���������������������������������������������������./saods9/blt3.0.1/html/htext.html�������������������������������������������������������������������0000644�0001750�0001750�00000044031�11462120062�015226� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>htext(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> htext - Create and manipulate hypertext widgets <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>htext</B> <I>pathName </I>?<I>option value</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> <P> The <B>htext</B> command creates a new window (given by the <I>pathName</I> argument) and makes it into a <B>htext</B> widget. Additional options, described above, may be specified on the command line or in the option database to configure aspects of the widget such as its color and font. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. The <B>htext</B> command returns its <I>pathName</I>. <P> The <B>htext</B> widget is hybrid of a non-editable text widget and a geometry manager (e.g. the packer). It displays text (optionally read from file) in a window. Text can be scrolled either horizontally or vertically using the <B>htext</B> window as a viewport. In addition, Tcl commands can be embedded into the text which are evaluated as the text is parsed. Text between special double characters (percent signs "%%") is immediately passed to the Tcl interpreter for evaluation. <P> Furthermore, any widget or widget hierarchy can be packed in-line and made to appear on the current line of the text. Widgets are packed using the <B>htext append</B> command. All widgets must be children of the <B>htext</B> window and must already exist before packing. Once a widget has been packed it cannot be moved to a different position within the text. Widgets can be resized but they will remain at the same position within the text. <P> Before a file or text string is parsed by the <B>htext</B> widget, all the widget's current children are destroyed. You can reload files or text without worrying about unmapping or destroying each child window beforehand. <P> Setting the either the <B>-filename</B> or <B>-text</B> configuration option will adjust the value of the other. If both options are set, the file takes precedence. When a new file is read using the <B>-filename</B> option, the value of the <B>-text</B> option is reset to the empty string. Likewise, when the <B>-text</B> option is set, the string representing the <B>-filename</B> option is cleared. <H2><A NAME="sect3" HREF="#toc3">File Format</A></H2> The format of <B>htext</B> text file is typically ASCII text. Text enclosed by special double characters (by default, percent signs '%%') is interpreted and executed as Tcl commands. The special character may be specified by the <B>-specialchar</B> option. In the following example of a <B>htext</B> file, a button widget is appended to the text between the words "<I>a</I>" and "<I>which</I>". The <I>pathName</I> of the <B>htext</B> widget is "<I>.ht</I>". <BR> <CODE><I>This will be displayed as normal text. <BR> </I>But this will become a %% <BR> button .ht.button -text "button" -fg red<BR> .ht append .ht.button <BR> %% which can invoke a Tcl command.<BR> <P> <H2><A NAME="sect4" HREF="#toc4"></CODE><P>Indices</A></H2> <P> Some of the widget operations (<B>selection</B>, gotoline, <B>search</B>, etc.) take one or more indices as arguments. An index is a string used to indicate a particular place within the text, such as the first and last characters in a range to be selected. <P> An index must have one of the following forms: <DL> <DT><I>line<B>.<I>char</I></B></I> </DT> <DD>Indicates <I>char</I>'th character on line <I>line</I>. Both lines and characters are number from 0, so "0.0" is the first beginning of the text. <I>Char</I> may be undesignated. In this case a character position of 0 is assumed. </DD> <DT><B>@<I>x<B>,<I>y</I></B></I></B> </DT> <DD>Indicates the character that covers the pixel whose x and y coordinates within the text's window are <I>x</I> and <I>y</I>. </DD> <DT><B>end</B> </DT> <DD>Indicates the end of the text. </DD> <DT><B>anchor</B> </DT> <DD>Indicates the anchor point for the selection, which is set with the <B>selection</B> operation. </DD> <DT><B>sel.first</B> </DT> <DD>Indicates the first character in the selection. It is an error to use this form if the selection isn't in the entry window. </DD> <DT><B>sel.last</B> </DT> <DD>Indicates the character just after the last one in the selection. It is an error to use this form if the selection isn't in the entry window. </DD> </DL> <H2><A NAME="sect5" HREF="#toc5">Variables</A></H2> <P> The following global Tcl variables are maintained when an <B>htext</B> file is parsed. <DL> <DT><B>htext(widget)</B> </DT> <DD>is the pathname of the <B>htext</B> widget. </DD> <DT><B>htext(file)</B> </DT> <DD>is the name of the file the <B>htext</B> widget is currently parsing. It is the empty string when the <B>-text</B> option is used. </DD> <DT><B><A HREF="htext.l.html">htext(line)</B></A> </DT> <DD>is the current line number in the text. </DD> </DL> <P> This information might be used to construct hyper links between different files and/or lines. <P> <H2><A NAME="sect6" HREF="#toc6">Syntax</A></H2> The <B>htext</B> command creates a new Tcl command whose name is <I>pathName</I>. This command may be used to invoke various operations on the widget. It has the following general form: <BR> <P> <CODE><I>pathName oper </I>?<I>args</I>?<BR> </CODE><P><I>Oper</I> and <I>args</I> determine the exact behavior of the command. <P> <H2><A NAME="sect7" HREF="#toc7">Operations</A></H2> The following operations are available for <B>htext</B> widgets: <DL> <DT><I>pathName <B>append <I>window </I></B></I>?<I>option value</I>?... </DT> <DD>Embeds the widget <I>window</I> into the htext widget. <I>Window</I> is the pathname of the widget to be embedded which must be a child of <I>pathName</I>. <I>Window</I> will be positioned in the htext widget at the current location of the text. If <I>option</I> and <I>value</I> pairs are present, they configure various aspects how <I>window</I> appears in <I>pathName</I>. The following options are available. <blockquote></DD> <DT><B>-anchor <I>anchorPos</I></B> </DT> <DD>Specifies how <I>window</I> will be arranged if there is any extra space in the cavity surrounding the window. For example, if <I>anchorPos</I> is <B>center</B> then the window is centered in the cavity; if <I>anchorPos</I> is <B>w</B> then the window will be drawn such it touches the leftmost edge of the cavity. The default is <I>center</I>. </DD> <DT><B>-fill <I>style</I></B> </DT> <DD>Specifies how the <I>window</I> should be stretched to occupy the extra space in the cavity surrounding it (if any exists). <I>Style</I> is <I>none</I>, <I>x</I>, <I>y</I>, <I>both</I>. If <I>style</I> is <I>x</I>, the width of <I>window</I> is expanded to fill the cavity. If <I>style</I> is <B>y</B>, the height is expanded. The default is <I>none</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Sets the height of the cavity surrounding <I>window</I>. If <I>pixels</I> is zero, the height of the cavity will be the same as the requested height of <I>window</I>. If <I>pixels</I> is less than the requested height of <I>window</I>, <I>window</I> will be reduced to fit the cavity. The default is <I>0</I>. </DD> <DT><B>-ipadx <I>pad</I></B> </DT> <DD>Sets the amount of internal padding to be added to the width <I>window</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the left side of <I>window</I> is extended by the first value and the right side by the second value. If <I>pad</I> is just one value, both the left and right sides are padded by evenly by the value. The default is <I>0</I>. </DD> <DT><B>-ipady <I>pad</I></B> </DT> <DD>Sets an amount of internal padding to be added to the height of <I>window</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the top of <I>window</I> is padded by the first value and the bottom by the second value. If <I>pad</I> is just one number, both the top and bottom are padded evenly by the value. The default is <I>0</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Justifies <I>window</I> vertically within the cavity containing it in relation to the line of text. <I>Justify</I> is <B>top</B>, <B>bottom</B>, or <B>center</B>. If <I>justify</I> is <I>center</I> the widget is centered along the baseline of the line of text. The default is <I>center</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding on the left and right sides of <I>window</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the left side of <I>window</I> is padded by the first value and the right side by the second value. If <I>pad</I> has just one value, both the left and right sides are padded evenly by the value. The default is <I>0</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below <I>window</I>. <I>Pad</I> can be a list of one or two numbers. If <I>pad</I> has two elements, the area above <I>window</I> is padded by the first value and the area below by the second value. If <I>pad</I> is just one number, both the top and bottom are padded by the value. The default is <I>0</I>. </DD> <DT><B>-relheight <I>value</I></B> </DT> <DD>Specifies the height of the cavity containing <I>window</I> relative to the height of <I>pathName</I>. <I>Value</I> is real number indicating the ratio of the height of the cavity to the height of <I>pathName</I>. As the height of <I>pathName</I> changes, so will the height of <I>window</I>. If <I>value</I> is 0.0 or less, the height of the cavity is the requested height <I>window</I>. The default is <I>0.0</I>. </DD> <DT><B>-relwidth <I>value</I></B> </DT> <DD>Specifies the width of the cavity containing <I>window</I> relative to the width of <I>pathName</I>. <I>Value</I> is real number indicating the ratio of the width of the cavity to the width of IpathName. As the height of <I>pathName</I> changes, so will the height of <I>window</I>. If <I>value</I> is 0.0 or less, the width of the cavity is the requested width of <I>window</I>. The default is <I>0.0</I>. </DD> <DT><B>-width <I>value</I></B> </DT> <DD>Species the width of the cavity containing the child window. <I>Value</I> must be in a form accepted by <B>Tk_GetPixels</B>. If <I>value</I> is greater than zero, the cavity is resized to that width. If the requested window width is greater than the cavity's width, the window will be reduced to fit the cavity. By default, the cavity is requested width of the child window. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>configure</B></I> ?<I>window</I>? ?<I>option</I>? ?<I>value option value ...</I>? </DT> <DD>Queries or modifies the configuration options of the text widget or one of its embedded widgets. If no <I>window</I> argument is present, the htext widget itself is configured. Otherwise <I>window</I> is the pathname of a widget already embedded into the htext widget. Then this command configure the options for the embedded widget. </DD> </DL> <P> If <I>option</I> isn't specified, a list describing all of the current options for <I>pathName</I> or <I>window</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing the option <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the htext or embedded window option <I>option</I> is set to <I>value</I>. <P> The following options are valid for the htext widget. <blockquote> <DL> <DT><B>-background</B> <I>color<I> </I></I></DT> <DD>Sets the background of the htext widget to <I>color</I>. This default is <I>white</I>. </DD> <DT><B>-cursor</B> <I>cursor</I> </DT> <DD>Specifies the cursor for the htext widget. The default cursor is <I>pencil</I>. </DD> <DT><B>-filename</B> <I>fileName</I> </DT> <DD>Specifies a <B>htext</B> file to be displayed in the window. If the value is the empty string, the <B>-text</B> option is used instead. See the section <FONT SIZE=-1><B>FILE</B></FONT> for a description of the <B>htext</B> file format. </DD> <DT><B>-font</B> <I>fontName</I> </DT> <DD>Sets the font of the text in the htext widget to <I>fontName</I>. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground</B> <I>color</I> </DT> <DD>Sets the foreground of the htext widget to <I>color</I>. This is the color of the text. This default is <I>black</I>. </DD> <DT><B>-height</B> <I>pixels</I> </DT> <DD>Specifies the height of the htext widget window. </DD> <DT><B>-linespacing</B> <I>pixels</I> </DT> <DD>Specifies the spacing between each line of text. The value must be in a form accepted by <B>Tk_GetPixels</B>. The default value is 1 pixel. </DD> <DT><B>-specialchar</B> <I>number</I> </DT> <DD>Specifies the ASCII value of the special double character delimiters. In <B>htext</B> files, the text between these special characters is evaluated as a block of Tcl commands. The default special character is the <I>0x25</I> (percent sign). </DD> <DT><B>-text</B> <I>text</I> </DT> <DD>Specifies the text to be displayed in the htext widget. <I>Text</I> can be any valid string of characters. See <FONT SIZE=-1><B>FILE FORMAT</B></FONT> for a description. </DD> <DT><B>-xscrollcommand</B> <I>string</I> </DT> <DD>Specifies the prefix for a command used to communicate with horizontal scrollbars. When the view in the htext widget's window changes (or whenever anything else occurs that could change the display in a scrollbar, such as a change in the total size of the widget's contents), the widget invoke <I>string</I> concatenated by two numbers. Each of the numbers is a fraction between 0 and 1, which indicates a position in the document. If this option is not specified, then no command will be executed. </DD> <DT><B>-yscrollcommand</B> <I>string</I> </DT> <DD>Specifies the prefix for a command used to communicate with vertical scrollbars. When the view in the htext widget's window changes (or whenever anything else occurs that could change the display in a scrollbar, such as a change in the total size of the widget's contents), the widget invoke <I>string</I> concatenated by two numbers. Each of the numbers is a fraction between 0 and 1, which indicates a position in the document. If this option is not specified, then no command will be executed. </DD> <DT><B>-width</B> <I>pixels</I> </DT> <DD>Specifies the desired width of the viewport window. If the <I>pixels</I> is less than one, the window will grow to accommodate the widest line of text. </DD> <DT><B>-xscrollunits</B> <I>pixels</I> </DT> <DD>Specifies the horizontal scrolling distance. The default is 10 pixels. </DD> <DT><B>-yscrollunits</B> <I>pixels</I> </DT> <DD>Specifies the vertical scrolling distance. The default is 10 pixels. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>gotoline </B></I>?<I>index</I>? </DT> <DD>Sets the top line of the text to <I>index</I>. <I>Index</I> must be a valid text index (the character offset is ignored). If an <I>index</I> isn't provided, the current line number is returned. </DD> <DT><I>pathName <B>scan mark <I>position</I></B></I> </DT> <DD>Records <I>position</I> and the current view in the text window; used in conjunction with later <B>scan dragto</B> commands. <I>Position</I> must be in the form "<I>@x,y</I>, where <I>x</I> and <I>y</I> are window coordinates. Typically this command is associated with a mouse button press in the widget. It returns an empty string. </DD> <DT><I>pathName <B>scan dragto <I>position</I></B></I> </DT> <DD>Computes the difference between <I>position</I> and the position registered in the last <B>scan mark</B> command for the widget. The view is then adjusted up or down by 10 times the difference in coordinates. This command is can be associated with mouse motion events to produce the effect of dragging the text at high speed through the window. <I>Position</I> must be in the form "<I>@x,y</I>, where <I>x</I> and <I>y</I> are window coordinates. The command returns an empty string. </DD> <DT><I>pathName <B>search <I>pattern</I></B></I> ?<I>from</I>? ?<I>to</I>? </DT> <DD>Returns the number of the next line matching <I>pattern</I>. <I>Pattern</I> is a string which obeys the matching rules of <B>Tcl_StringMatch</B>. <I>From</I> and <I>to</I> are text line numbers (inclusive) which bound the search. If no match for <I>pattern</I> can be found, <B>-1</B> is returned. </DD> <DT><I>pathName <B>xview </B></I>?<I>position</I>? </DT> <DD>Moves the viewport horizontally to the new text x-coordinate position. <I>Position</I> is the offset from the left side of the text to the current position and must be in a form accepted by <B>Tk_GetPixels</B>. If <I>position</I> is not present, the current text position is returned. </DD> <DT><I>pathName <B>yview </B></I>?<I>position</I>? </DT> <DD>Moves the viewport vertically to the new text y-coordinate position. <I>Position</I> is the offset from the top of the text to the current position and must be in a form accepted by <B>Tk_GetPixels</B>. If <I>position</I> is not present, the current text position is returned. </DD> </DL> <H2><A NAME="sect8" HREF="#toc8">Bugs</A></H2> Text with embedded tabs can be obscured by child windows when scrolled horizontally. <H2><A NAME="sect9" HREF="#toc9">Keywords</A></H2> hypertext, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">File Format</A></LI> <LI><A NAME="toc4" HREF="#sect4">Indices</A></LI> <LI><A NAME="toc5" HREF="#sect5">Variables</A></LI> <LI><A NAME="toc6" HREF="#sect6">Syntax</A></LI> <LI><A NAME="toc7" HREF="#sect7">Operations</A></LI> <LI><A NAME="toc8" HREF="#sect8">Bugs</A></LI> <LI><A NAME="toc9" HREF="#sect9">Keywords</A></LI> </UL> </BODY></HTML> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/stripchart.html��������������������������������������������������������������0000644�0001750�0001750�00000311106�11462120062�016255� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>stripchart(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> stripchart - 2D strip chart for plotting x and y coordinate data. <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>stripchart<I> <I>pathName </I></I></B>?<I>option value</I>?... <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>stripchart</B> command creates a strip chart for plotting two-dimensional data (x,y coordinates). It has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the strip chart. <P> The <B>stripchart</B> is essentially the same as the <B>graph</B> widget. It works almost exactly the very same way. <P> The use of a strip chart differs in that the X-axis typically refers to time points. Data values are added at intervals. The strip chart lets you automatically maintain a view of the most recent time points. The axis options <B>-shiftby</B> and <B>-autorange</B> control this. You can specify different line styles for data points (see the <B>-styles</B> option). <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> The <B>stripchart</B> command creates a new window for plotting two-dimensional data (x,y coordinates). Data points are plotted in a box displayed in the center of the new window. This is the <I>plotting area</I>. The coordinate axes are displayed in the margins around the plotting area. By default, the legend is displayed in the right margin. The title is displayed in top margin. <P> A strip chart is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. <DL> <DT><I>axis</I> </DT> <DD>The stripchart widget can display up to four coordinate axes (two X-coordinate and two Y-coordinate axes), but you can create and use any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value of each major tick. </DD> <DT><I>crosshairs</I> </DT> <DD>Cross hairs are used to finely position the mouse pointer in relation to the coordinate axes. Two perpendicular lines are drawn across the plotting area, intersecting at the current location of the mouse pointer. </DD> <DT><I>element</I> </DT> <DD>An element represents a set of data points. Elements can be plotted with a symbol at each data point and lines connecting the points. The appearance of the element, such as its symbol, line width, and color is configurable. </DD> <DT><I>grid</I> </DT> <DD>Extends the major and minor ticks of the X-axis and/or Y-axis across the plotting area. </DD> <DT><I>legend</I> </DT> <DD>The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. </DD> <DT><I>marker</I> </DT> <DD>Markers are used annotate or highlight areas of the graph. For example, you could use a polygon marker to fill an area under a curve, or a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. </DD> <DT><I>pen</I> </DT> <DD>Pens define attributes (both symbol and line style) for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here, the particular pen used for a data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). </DD> <DT><I>postscript</I> </DT> <DD>The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. </DD> </DL> <H2><A NAME="sect4" HREF="#toc4">Syntax</A></H2> <BR> <P> <CODE><B>stripchart <I>pathName </I></B>?<I>option value</I>?...<BR> </CODE><P>The <B>stripchart</B> command creates a new window <I>pathName</I> and makes it into a <B>stripchart</B> widget. At the time this command is invoked, there must not exist a window named <I>pathName</I>, but <I>pathName</I>'s parent must exist. Additional options may may be specified on the command line or in the option database to configure aspects of the strip chart such as its colors and font. See the <B>configure</B> operation below for the exact details as to what <I>option</I> and <I>value</I> pairs are valid. <P> If successful, <B>stripchart</B> returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to perform various operations that query or modify the graph. The general form is: <BR> <P> <CODE><I>pathName <I>operation</I></I> ?<I>arg</I>?...<BR> </CODE><P>Both <I>operation</I> and its arguments determine the exact behavior of the command. The operations available for the strip chart are described in the <FONT SIZE=-1><B>STRIPCHART OPERATIONS</B></FONT> section. <P> The command can also be used to access components of the strip chart. <BR> <P> <CODE><I>pathName component operation</I> ?<I>arg</I>?...<BR> </CODE><P>The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. <H2><A NAME="sect5" HREF="#toc5">Example</A></H2> The <B>stripchart</B> command creates a new strip chart. <BR> <CODE># Create a new strip chart. Plotting area is black.<BR> stripchart .s -plotbackground black<BR> </CODE><P>A new Tcl command <I>.s</I> is also created. This command can be used to query and modify the strip chart. For example, to change the title of the strip chart to "My Plot", you use the new command and the widget's <B>configure</B> operation. <BR> <CODE># Change the title.<BR> .s configure -title "My Plot"<BR> </CODE><P>A strip chart has several components. To access a particular component you use the component's name. For example, to add data elements, you use the new command and the <B>element</B> component. <BR> <CODE># Create a new element named "line1"<BR> .s element create line1 \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;155.85 166.60 175.38 }<BR> </CODE><P>The element's X and Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X-Y coordinates. <BR> <CODE># Create two vectors and add them to the strip chart.<BR> vector xVec yVec<BR> xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 }<BR> yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 <BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;166.60 175.38 }<BR> .s element create line1 -xdata xVec -ydata yVec<BR> </CODE><P>The advantage of using vectors is that when you modify one, the graph is automatically redrawn to display the new values. <BR> <CODE># Change the X-Y coordinates of the first point.<BR> set xVec(0) 0.18<BR> set yVec(0) 25.18<BR> </CODE><P>An element named <I>line1</I> is now created in <I>.s</I>. By default, the element's label in the legend will be also <I>line1</I>. You can change the label, or specify no legend entry, again using the element's <B>configure</B> operation. <BR> <CODE># Don't display "line1" in the legend.<BR> .s element configure line1 -label ""<BR> </CODE><P>You can configure more than just the element's label. An element has many attributes such as symbol type and size, dashed or solid lines, colors, line width, etc. <BR> <CODE>.s element configure line1 -symbol square -color red \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-dashes { 2 4 2 } -linewidth 2 -pixels 2c<BR> </CODE><P>Four coordinate axes are automatically created: <I>x</I>, <I>x2</I>, <I>y</I>, and <I>y2</I>. And by default, elements are mapped onto the axes <I>x</I> and <I>y</I>. This can be changed with the <B>-mapx</B> and <B>-mapy</B> options. <BR> <CODE># Map "line1" on the alternate Y-axis "y2".<BR> .s element configure line1 -mapy y2<BR> </CODE><P>Axes can be configured in many ways too. For example, you change the scale of the Y-axis from linear to log using the <B>axis</B> operation. <BR> <CODE># Y-axis is log scale.<BR> .s axis configure y -logscale yes<BR> </CODE><P>Axis limits are reset by simply specifying new axis limits using the <B>-min</B> and <B>-max</B> configuration options. <BR> <CODE>.s axis configure x -min 1.0 -max 1.5<BR> .s axis configure y -min 12.0 -max 55.15<BR> </CODE><P>By default, the limits of the axis are determined from data values. To reset back to the default limits, set the <B>-min</B> and <B>-max</B> options to the empty value. <BR> <CODE># Reset the axes to autoscale again.<BR> .s axis configure x -min {} -max {}<BR> .s axis configure y -min {} -max {}<BR> </CODE><P>It's common with strip charts to automatically maintain a view of the most recent time points. You can do this my setting the <B>-autorange</B> option. <BR> <CODE>.s axis configure x -autorange 20.0<BR> </CODE><P>If the time points are added in X-coordinates 1.0 unit, only the last twenty time points will be displayed. As more data is added, the view will march along. <P> Sometimes the rate of data is so high that changing the axis limits with each additional time point is prohibitive. You can use the <B>-shiftby</B> option to define an increment to shift the view when needed. <BR> <CODE>.s axis configure x -shiftby 15.0<BR> </CODE><P>When the view is shifted, it will allow a range of 15 new time points to be added until the axis limits are recomputed. <P> By default, the legend is displayed in the right margin. You can change this or any other legend configuration options using the <B>legend</B> component. <BR> <CODE># Configure the legend font, color, and relief<BR> .s legend configure -position left -relief raised \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-font fixed -fg blue<BR> </CODE><P>To prevent the legend from being displayed, turn on the <B>-hide</B> option. <BR> <CODE># Don't display the legend.<BR> .s legend configure -hide yes<BR> </CODE><P>The <B>stripchart</B> widget has simple drawing procedures called markers. They can be used to highlight or annotate data in the strip chart. The types of markers available are bitmaps, images, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. Here is a text marker which labels the data first point. Markers are created using the <B>marker</B> operation. <BR> <CODE># Create a label for the first data point of "line1".<BR> .s marker create text -name first_marker -coords { 0.2 26.18 } \<BR> <tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;-text "start" -anchor se -xoffset -10 -yoffset -10<BR> </CODE><P>This creates a text marker named <I>first_marker</I>. It will display the text "start" near the coordinates of the first data point. The <B>-anchor</B>, <B>-xoffset</B>, and <B>-yoffset</B> options are used to display the marker above and to the left of the data point, so that the actual data point isn't covered by the marker. By default, markers are drawn last, on top of data. You can change this with the <B>-under</B> option. <BR> <CODE># Draw the label before elements are drawn.<BR> .s marker configure first_marker -under yes<BR> </CODE><P>You can add cross hairs or grid lines using the <B>crosshairs</B> and <B>grid</B> operations. <BR> <CODE># Display both cross hairs and grid lines.<BR> .s crosshairs configure -hide no -color red<BR> .s grid configure -hide no -dashes { 2 2 }<BR> </CODE><P>Finally, to get hardcopy of the strip chart, use the <B>postscript</B> operation. <BR> <CODE># Print the strip chart into file "file.ps"<BR> .s postscript output file.ps -maxpect yes -decorations no<BR> </CODE><P>This generates a file <I>file.ps</I> containing the encapsulated PostScript of the strip chart. The option <B>-maxpect</B> says to scale the plot to the size of the page. Turning off the <B>-decorations</B> option indicates that no borders or color backgrounds should be displayed (i.e. the background of the margins, legend, and plotting area will be white). <H2><A NAME="sect6" HREF="#toc6">Stripchart Operations</A></H2> <DL> <DT><I>pathName <B>axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>bar <I>elemName </I></B></I>?<I>option value</I>?... </DT> <DD>Creates a new barchart element <I>elemName</I>. It's an error if an element <I>elemName</I> already exists. See the manual for <B>barchart</B> for details about what <I>option</I> and <I>value</I> pairs are valid. </DD> <DT><I>pathName <B>cget</B></I> <I>option</I> </DT> <DD>Returns the current value of the stripchart configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the <B>configure</B> operation. </DD> <DT><I>pathName <B>configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the strip chart. If <I>option</I> isn't specified, a list describing all of the current options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the stripchart option <I>option</I> is set to <I>value</I>. The following options are valid for the stripchart. <blockquote></DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color. This includes the margins and legend, but not the plotting area. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the widget. The <B>-relief</B> option determines if the border is to be drawn. The default is <I>2</I>. </DD> <DT><B>-bottommargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin below the X-coordinate axis. If <I>pixels</I> is <I>0</I>, the size of the margin is selected automatically. The default is <I>0</I>. </DD> <DT><B>-bufferelements <I>boolean</I></B> </DT> <DD>Indicates whether to draw elements into a pixmap before displaying them on the screen. The advantage of buffering elements is when markers are used heavily. Markers can be moved and redrawn without requiring every element to be redrawn again. The disadvantage is that it takes slightly longer to draw the graph. If <I>boolean</I> is true, data elements are drawn to an internal pixmap. The option should be turned off if the plot is updated frequently. See the <FONT SIZE=-1><B>SPEED TIPS</B></FONT> section. The default is <I>1</I>. </DD> <DT><B>-buffergraph <I>boolean</I></B> </DT> <DD>Indicates whether to draw the graph into a pixmap first. If <I>boolean</I> is true, the entire graph is drawn into a pixmap and then copied onto the screen. This reduces flashing. If false, the graph is drawn directly into the window. Especially under Windows, turning off the option can be helpful when the stripchart is updated frequently. Turning off this option also turns <B>-bufferelements</B> off. See the <FONT SIZE=-1><B>SPEED TIPS</B></FONT> section. The default is <I>1</I>. </DD> <DT><B>-cursor <I>cursor</I></B> </DT> <DD>Specifies the widget's cursor. The default cursor is <I>crosshair</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the title font. The default is <I>*-Helvetica-Bold-R-Normal-*-18-180-*</I>. </DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a maximum distance to consider when searching for the closest data point (see the element's <B>closest</B> operation below). Data points further than <I>pixels</I> away are ignored. The default is <I>0.5i</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the requested height of widget. The default is <I>4i</I>. </DD> <DT><B>-invertxy <I>boolean</I></B> </DT> <DD>Indicates whether the placement X-axis and Y-axis should be inverted. If <I>boolean</I> is true, the X and Y axes are swapped. The default is <I>0</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the title should be justified. This matters only when the title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-leftmargin <I>pixels</I></B> </DT> <DD>Sets the size of the margin from the left edge of the window to the Y-coordinate axis. If <I>pixels</I> is <I>0</I>, the size is calculated automatically. The default is <I>0</I>. </DD> <DT><B>-plotbackground <I>color</I></B> </DT> <DD>Specifies the background color of the plotting area. The default is <I>white</I>. </DD> <DT><B>-plotborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the plotting area. The <B>-plotrelief</B> option determines if a border is drawn. The default is <I>2</I>. </DD> <DT><B>-plotpadx <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the left and right sides of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotpady <I>pad</I></B> </DT> <DD>Sets the amount of padding to be added to the top and bottom of the plotting area. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom are padded evenly. The default is <I>8</I>. </DD> <DT><B>-plotrelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the plotting area. <I>Relief</I> indicates how the interior of the plotting area should appear relative to rest of the strip chart; for example, <I>raised</I> means the plot should appear to protrude from the strip chart, relative to the surface of the strip chart. The default is <I>sunken</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the widget. <I>Relief</I> indicates how the strip chart should appear relative to widget it is packed into; for example, <I>raised</I> means the strip chart should appear to protrude. The default is <I>flat</I>. </DD> <DT><B>-rightmargin <I>pixels</I></B> </DT> <DD>Sets the size of margin from the plotting area to the right edge of the window. By default, the legend is displayed in this margin. If <I>pixels</I> is than 1, the margin size is selected automatically. </DD> <DT><B>-takefocus</B> <I>focus</I> </DT> <DD>Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If <I>focus</I> is <I>0</I>, this means that this window should be skipped entirely during keyboard traversal. <I>1</I> means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is <I>""</I>. </DD> <DT><B>-tile <I>image</I></B> </DT> <DD>Specifies a tiled background. If <I>image</I> isn't <I>""</I>, the background is tiled using <I>image</I>. Otherwise, the normal background color is drawn (see the <B>-background</B> option). <I>Image</I> must be an image created using the Tk <B>image</B> command. The default is <I>""</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title to <I>text</I>. If <I>text</I> is <I>""</I>, no title will be displayed. </DD> <DT><B>-topmargin <I>pixels</I></B> </DT> <DD>Specifies the size of the margin above the x2 axis. If <I>pixels</I> is <I>0</I>, the margin size is calculated automatically. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the requested width of the widget. The default is <I>5i</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>crosshairs <I>operation </I></B></I>?<I>arg</I>? </DT> <DD>See the <FONT SIZE=-1><B>CROSSHAIRS COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>element <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>ELEMENT COMPONENTS</B></FONT> section. </DD> <DT><I>pathName <B>extents <I>item</I></B></I> </DT> <DD>Returns the size of a particular item in the strip chart. <I>Item</I> must be either <I>leftmargin</I>, <I>rightmargin</I>, <I>topmargin</I>, <I>bottommargin</I>, <I>plotwidth</I>, or <I>plotheight</I>. </DD> <DT><I>pathName <B>grid <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>GRID COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>invtransform <I>winX winY</I></B></I> </DT> <DD>Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X-axis and Y-axis. Returns a list of containing the graph coordinates. </DD> <DT><I>pathName <B>legend <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>LEGEND COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>line <I>elemName</I></B></I> ?<I>option value</I>?... </DT> <DD>The operation is the same as <B>element</B>. </DD> <DT><I>pathName <B>marker <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>MARKER COMPONENTS</B></FONT> section. </DD> <DT><I>pathName</I> <B>metafile</B> ?<I>fileName</I>? </DT> <DD><I>This operation is for Window platforms only</I>. Creates a Windows enhanced metafile of the stripchart. If present, <I>fileName</I> is the file name of the new metafile. Otherwise, the metafile is automatically added to the clipboard. </DD> <DT><I>pathName <B>postscript <I>operation </I></B></I>?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>POSTSCRIPT COMPONENT</B></FONT> section. </DD> <DT><I>pathName <B>snap <I>photoName</I></B></I> </DT> <DD>Takes a snapshot of the strip chart and stores the contents in the photo image <I>photoName</I>. <I>PhotoName</I> is the name of a Tk photo image that must already exist. </DD> <DT><I>pathName <B>transform <I>x y</I></B></I> </DT> <DD>Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X-axis and Y-axis. Returns a list containing the X-Y screen coordinates. </DD> <DT><I>pathName <B>xaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>x2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>yaxis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD></DD> <DT><I>pathName <B>y2axis <I>operation</I></B></I> ?<I>arg</I>?... </DT> <DD>See the <FONT SIZE=-1><B>AXIS COMPONENTS</B></FONT> section. </DD> </DL> <H2><A NAME="sect7" HREF="#toc7">Stripchart Components</A></H2> A strip chart is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the strip chart is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the strip chart. <H3><A NAME="sect8" HREF="#toc8">Axis Components</A></H3> Four coordinate axes are automatically created: two X-coordinate axes (<I>x</I> and <I>x2</I>) and two Y-coordinate axes (<I>y</I>, and <I>y2</I>). By default, the axis <I>x</I> is located in the bottom margin, <I>y</I> in the left margin, <I>x2</I> in the top margin, and <I>y2</I> in the right margin. <P> An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. <P> The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. <P> You can create and use several axes. To create an axis, invoke the axis component and its create operation. <BR> <CODE># Create a new axis called "temperature"<BR> .s axis create temperature<BR> </CODE><P>You map data elements to an axis using the element's -mapy and -mapx configuration options. They specify the coordinate axes an element is mapped onto. <BR> <CODE># Now map the temperature data to this axis.<BR> .s element create "temp" -xdata $x -ydata $tempData \<BR> -mapy temperature<BR> </CODE><P>While you can have many axes, only four axes can be displayed simultaneously. They are drawn in each of the margins surrounding the plotting area. The axes x and y are drawn in the bottom and left margins. The axes x2 and y2 are drawn in top and right margins. Only x and y are shown by default. Note that the axes can have different scales. <P> To display a different axis, you invoke one of the following components: <B>xaxis</B>, <B>yaxis</B>, <B>x2axis</B>, and <B>y2axis</B>. The <B>use</B> operation designates the axis to be drawn in the corresponding margin: <B>xaxis</B> in the bottom, <B>yaxis</B> in the left, <B>x2axis</B> in the top, and <B>y2axis</B> in the right. <BR> <CODE># Display the axis temperature in the left margin.<BR> .s yaxis use temperature<BR> <P> </CODE><P>You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label as you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. <P> <DL> <DT><I>pathName <B>axis <B>cget <I>axisName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>axisName</I>. <I>Option</I> may be any option described below for the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>configure <I>axisName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>axisName</I>. If <I>option</I> isn't specified, a list describing all the current options for <I>axisName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the axis option <I>option</I> is set to <I>value</I>. The following options are valid for axes. <blockquote></DD> <DT><B>-autorange <I>range</I></B> </DT> <DD>Sets the range of values for the axis to <I>range</I>. The axis limits are automatically reset to display the most recent data points in this range. If <I>range</I> is 0.0, the range is determined from the limits of the data. If <B>-min</B> or <B>-max</B> are specified, they override this option. The default is <I>0.0</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the axis and tick labels. The default is <I>black</I>. </DD> <DT><B>-command <I>prefix</I></B> </DT> <DD>Specifies a Tcl command to be invoked when formatting the axis tick labels. <I>Prefix</I> is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If <I>""</I> is returned, no label will appear next to the tick. You can get the standard tick labels again by setting <I>prefix</I> to <I>""</I>. The default is <I>""</I>. <P> Please note that this procedure is invoked while the strip chart is redrawn. You may query the configuration options. But do not reset them, because this can have unexpected results. </DD> <DT><B>-descending <I>boolean</I></B> </DT> <DD>Indicates whether the values along the axis are monotonically increasing or decreasing. If <I>boolean</I> is true, the axis values will be decreasing. The default is <I>0</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the axis is displayed. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-limits <I>formatStr</I></B> </DT> <DD>Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. <I>FormatStr</I> is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If <I>""</I> is given as either description, then the that limit will not be displayed. The default is <I>""</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the axis and tick lines. The default is <I>1</I> pixel. </DD> <DT><B>-logscale <I>boolean</I></B> </DT> <DD>Indicates whether the scale of the axis is logarithmic or linear. If <I>boolean</I> is true, the axis is logarithmic. The default scale is linear. </DD> <DT><B>-loose <I>boolean</I></B> </DT> <DD>Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. This is relevant only when the axis limit is automatically calculated. If <I>boolean</I> is true, the axis range is "loose". The default is <I>0</I>. </DD> <DT><B>-majorticks <I>majorList</I></B> </DT> <DD>Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. <I>MajorList</I> is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If <I>majorList</I> is <I>""</I>, major ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-max <I>value</I></B> </DT> <DD>Sets the maximum limit of <I>axisName</I>. Any data point greater than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the maximum limit is calculated using the largest data value. The default is <I>""</I>. </DD> <DT><B>-min <I>value</I></B> </DT> <DD>Sets the minimum limit of <I>axisName</I>. Any data point less than <I>value</I> is not displayed. If <I>value</I> is <I>""</I>, the minimum limit is calculated using the smallest data value. The default is <I>""</I>. </DD> <DT><B>-minorticks <I>minorList</I></B> </DT> <DD>Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. <I>MinorList</I> is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the <B>-majortick</B> option is also set. If <I>minorList</I> is <I>""</I>, minor ticks will be automatically computed. The default is <I>""</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the how many degrees to rotate the axis tick labels. <I>Theta</I> is a real value representing the number of degrees to rotate the tick labels. The default is <I>0.0</I> degrees. </DD> <DT><B>-shiftby <I>value</I></B> </DT> <DD>Specifies how much to automatically shift the range of the axis. When the new data exceeds the current axis maximum, the maximum is increased in increments of <I>value</I>. You can use this option to prevent the axis limits from being recomputed at each new time point. If <I>value</I> is 0.0, then no automatic shifting is done. The default is <I>0.0</I>. </DD> <DT><B>-showticks <I>boolean</I></B> </DT> <DD>Indicates whether axis ticks should be drawn. If <I>boolean</I> is true, ticks are drawn. If false, only the axis line is drawn. The default is <I>1</I>. </DD> <DT><B>-stepsize <I>value</I></B> </DT> <DD>Specifies the interval between major axis ticks. If <I>value</I> isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. </DD> <DT><B>-subdivisions <I>number</I></B> </DT> <DD>Indicates how many minor axis ticks are to be drawn. For example, if <I>number</I> is two, only one minor tick is drawn. If <I>number</I> is one, no minor ticks are displayed. The default is <I>2</I>. </DD> <DT><B>-tickfont <I>fontName</I></B> </DT> <DD>Specifies the font for axis tick labels. The default is <I>*-Courier-Bold-R-Normal-*-100-*</I>. </DD> <DT><B>-ticklength <I>pixels</I></B> </DT> <DD>Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If <I>pixels</I> is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is <I>0.1i</I>. </DD> <DT><B>-title <I>text</I></B> </DT> <DD>Sets the title of the axis. If <I>text</I> is <I>""</I>, no axis title will be displayed. </DD> <DT><B>-titlecolor <I>color</I></B> </DT> <DD>Sets the color of the axis title. The default is <I>black</I>. </DD> <DT><B>-titlefont <I>fontName</I></B> </DT> <DD>Specifies the font for axis title. The default is <I>*-Helvetica-Bold-R-Normal-*-14-140-*</I>. </DD> </DL> <P> Axis configuration options may be also be set by the <B>option</B> command. The resource class is <I>Axis</I>. The resource names are the names of the axes (such as <I>x</I> or <I>x2</I>). <BR> <CODE>option add *Stripchart.Axis.Color blue<BR> option add *Stripchart.x.LogScale true<BR> option add *Stripchart.x2.LogScale false<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>axis <B>create <I>axisName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new axis by the name <I>axisName</I>. No axis by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the axis <B>configure</B> operation. </DD> <DT><I>pathName <B>axis <B>delete </B></B></I>?<I>axisName</I>?... </DT> <DD>Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. </DD> <DT><I>pathName <B>axis invtransform <I>axisName value</I></B></I> </DT> <DD>Performs the inverse transformation, changing the screen coordinate <I>value</I> to a graph coordinate, mapping the value mapped to <I>axisName</I>. Returns the graph coordinate. </DD> <DT><I>pathName <B>axis limits <I>axisName</I></B></I> </DT> <DD>Returns a list of the minimum and maximum limits for <I>axisName</I>. The order of the list is <I>min max</I>. </DD> <DT><I>pathName <B>axis names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of axes matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all axes are returned. </DD> <DT><I>pathName <B>axis transform <I>axisName value</I></B></I> </DT> <DD>Transforms the coordinate <I>value</I> to a screen coordinate by mapping the it to <I>axisName</I>. Returns the transformed screen coordinate. </DD> </DL> <P> Only four axes can be displayed simultaneously. By default, they are <I>x</I>, <I>y</I>, <I>x2</I>, and <I>y2</I>. You can swap in a different axis with <B>use</B> operation of the special axis components: <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B>. <BR> <CODE>.g create axis temp<BR> .g create axis time<BR> ...<BR> .g xaxis use temp<BR> .g yaxis use time<BR> </CODE><P>Only the axes specified for use are displayed on the screen. <P> The <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, and <B>y2axis</B> components operate on an axis location rather than a specific axis like the more general <B>axis</B> component does. The <B>xaxis</B> component manages the X-axis located in the bottom margin (whatever axis that happens to be). Likewise, <B>yaxis</B> uses the Y-axis in the left margin, <B>x2axis</B> the top X-axis, and <B>y2axis</B> the right Y-axis. <P> They implicitly control the axis that is currently using to that location. By default, <B>xaxis</B> uses the <I>x</I> axis, <B>yaxis</B> uses <I>y</I>, <B>x2axis</B> uses <I>x2</I>, and <B>y2axis</B> uses <I>y2</I>. These components can be more convenient to use than always determining what axes are current being displayed by the graph. <P> The following operations are available for axes. They mirror exactly the operations of the <B>axis</B> component. The <I>axis</I> argument must be <B>xaxis</B>, <B>x2axis</B>, <B>yaxis</B>, or <B>y2axis</B>. <DL> <DT><I>pathName <I>axis <B>cget <I>option</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>configure </B></I></I>?<I>option value</I>?... </DT> <DD></DD> <DT><I>pathName <I>axis<B> invtransform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis <B>limits</B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> transform <I>value</I></B></I></I> </DT> <DD></DD> <DT><I>pathName <I>axis<B> use </B></I></I>?<I>axisName</I>? </DT> <DD>Designates the axis <I>axisName</I> is to be displayed at this location. <I>AxisName</I> can not be already in use at another location. This command returns the name of the axis currently using this location. </DD> </DL> <H3><A NAME="sect9" HREF="#toc9">Crosshairs Component</A></H3> Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire strip chart. <P> The following operations are available for cross hairs: <DL> <DT><I>pathName <B>crosshairs cget <I>option</I></B></I> </DT> <DD>Returns the current value of the cross hairs configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the cross hairs <B>configure</B> operation. </DD> <DT><I>pathName <B>crosshairs configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of the cross hairs. If <I>option</I> isn't specified, a list describing all the current options for the cross hairs is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the cross hairs option <I>option</I> is set to <I>value</I>. The following options are available for cross hairs. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the cross hairs. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the cross hairs. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the cross hairs will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether cross hairs are drawn. If <I>boolean</I> is true, cross hairs are not drawn. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Set the width of the cross hair lines. The default is <I>1</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies the screen position where the cross hairs intersect. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates of the intersection. </DD> </DL> <P> Cross hairs configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>crosshairs</I> and <I>Crosshairs</I> respectively. <BR> <CODE>option add *Stripchart.Crosshairs.LineWidth 2<BR> option add *Stripchart.Crosshairs.Color red<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>crosshairs off</B></I> </DT> <DD>Turns of the cross hairs. </DD> <DT><I>pathName <B>crosshairs on</B></I> </DT> <DD>Turns on the display of the cross hairs. </DD> <DT><I>pathName <B>crosshairs toggle</B></I> </DT> <DD>Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. </DD> </DL> <H3><A NAME="sect10" HREF="#toc10">Element Components</A></H3> A data element represents a set of data. It contains x and y vectors containing the coordinates of the data points. Elements can be displayed with a symbol at each data point and lines connecting the points. Elements also control the appearance of the data, such as the symbol type, line width, color etc. <P> When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. <P> The following operations are available for elements. <DL> <DT><I>pathName <B>element activate <I>elemName </I></B></I>?<I>index</I>?... </DT> <DD>Specifies the data points of element <I>elemName</I> to be drawn using active foreground and background colors. <I>ElemName</I> is the name of the element and <I>index</I> is a number representing the index of the data point. If no indices are present then all data points become active. </DD> <DT><I>pathName <B>element cget <I>elemName <I>option</I></I></B></I> </DT> <DD>Returns the current value of the element configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the element <B>configure</B> operation. </DD> <DT><I>pathName <B>element closest <I>x y</I></B></I> <I>varName</I> ?<I>option value</I>?... ?<I>elemName</I>?... </DT> <DD>Finds the data point closest to the window coordinates <I>x</I> and <I>y</I> in the element <I>elemName</I>. <I>ElemName</I> is the name of an element, that must not be hidden. If no elements are specified, then all visible elements are searched. It returns via the array variable <I>varName</I> the name of the closest element, the index of its closest point, and the graph coordinates of the point. Returns <I>0</I>, if no data point within the threshold distance can be found, otherwise <I>1</I> is returned. The following <I>option</I>-<I>value</I> pairs are available. <blockquote></DD> <DT><B>-halo <I>pixels</I></B> </DT> <DD>Specifies a threshold distance where selected data points are ignored. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. If this option isn't specified, then it defaults to the value of the stripchart's <B>-halo</B> option. </DD> <DT><B>-interpolate <I>boolean</I></B> </DT> <DD>Indicates that both the data points and interpolated points along the line segment formed should be considered. If <I>boolean</I> is true, the closest line segment will be selected instead of the closest point. If this option isn't specified, <I>boolean</I> defaults to <I>0</I>. </DD> </DL> </blockquote> <DL> <DT><I>pathName <B>element configure <I>elemName </I></B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for elements. If <I>option</I> isn't specified, a list describing all the current options for <I>elemName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing the option <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the element option <I>option</I> is set to <I>value</I>. The following options are valid for elements. <blockquote></DD> <DT><B>-activepen <I>penName</I></B> </DT> <DD>Specifies pen to use to draw active element. If <I>penName</I> is <I>""</I>, no active elements will be drawn. The default is <I>activeLine</I>. </DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the traces connecting the data points. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of element line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the lines will be solid. </DD> <DT><B>-data <I>coordList</I></B> </DT> <DD>Specifies the X-Y coordinates of the data. <I>CoordList</I> is a list of numeric expressions representing the X-Y coordinate pairs of each data point. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the interior color of symbols. If <I>color</I> is <I>""</I>, then the interior of the symbol is transparent. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the element is displayed. The default is <I>no</I>. </DD> <DT><B>-label <I>text</I></B> </DT> <DD>Sets the element's label in the legend. If <I>text</I> is <I>""</I>, the element will have no entry in the legend. The default label is the element's name. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the connecting lines between data points. If <I>pixels</I> is <I>0</I>, no connecting lines will be drawn between symbols. The default is <I>0</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Selects the X-axis to map the element's X-coordinates onto. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Selects the Y-axis to map the element's Y-coordinates onto. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-offdash <I>color</I></B> </DT> <DD>Sets the color of the stripes when traces are dashed (see the <B>-dashes</B> option). If <I>color</I> is <I>""</I>, then the "off" pixels will represent gaps instead of stripes. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color or the outline around each symbol. If <I>color</I> is <I>""</I>, then no outline is drawn. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outlinewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline bordering each symbol. If <I>pixels</I> is <I>0</I>, no outline will be drawn. The default is <I>1</I>. </DD> <DT><B>-pixels <I>pixels</I></B> </DT> <DD>Sets the size of symbols. If <I>pixels</I> is <I>0</I>, no symbols will be drawn. The default is <I>0.125i</I>. </DD> <DT><B>-scalesymbols <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, the size of the symbols drawn for <I>elemName</I> will change with scale of the X-axis and Y-axis. At the time this option is set, the current ranges of the axes are saved as the normalized scales (i.e scale factor is 1.0) and the element is drawn at its designated size (see the <B>-pixels</B> option). As the scale of the axes change, the symbol will be scaled according to the smaller of the X-axis and Y-axis scales. If <I>boolean</I> is false, the element's symbols are drawn at the designated size, regardless of axis scales. The default is <I>0</I>. </DD> <DT><B>-smooth <I>smooth</I></B> </DT> <DD>Specifies how connecting line segments are drawn between data points. <I>Smooth</I> can be either <I>linear</I>, <I>step</I>, <I>natural</I>, or <I>quadratic</I>. If <I>smooth</I> is <I>linear</I>, a single line segment is drawn, connecting both data points. When <I>smooth</I> is <I>step</I>, two line segments are drawn. The first is a horizontal line segment which steps the next x-coordinate. The second is a vertical line, moving to the next y-coordinate. Both <I>natural</I> and <I>quadratic</I> generate multiple segments between data points. If <I>natural</I>, the segments are generated using a cubic spline. If <I>quadratic</I>, a quadratic spline is used. The default is <I>linear</I>. </DD> <DT><B>-styles <I>styleList</I></B> </DT> <DD>Specifies what pen to use based upon the range of weights given. <I>StyleList</I> is a list of style specifications. Each style specification, in turn, is a list consisting of a pen name, and optionally a minimum and maximum range. Data points whose weight (see the <B>-weight</B> option) falls in this range, are drawn with this pen. If no range is specified it defaults to the number of the pen in the list. </DD> <DT><B>-symbol <I>symbol</I></B> </DT> <DD>Specifies the symbol for data points. <I>Symbol</I> can be either <I>square</I>, <I>circle</I>, <I>diamond</I>, <I>plus</I>, <I>cross</I>, <I>splus</I>, <I>scross</I>, <I>triangle</I>, <I>""</I> (where no symbol is drawn), or a bitmap. Bitmaps are specified as "<I>source</I> ?<I>mask</I>?", where <I>source</I> is the name of the bitmap, and <I>mask</I> is the bitmap's optional mask. The default is <I>circle</I>. </DD> <DT><B>-weights <I>wVec</I></B> </DT> <DD>Specifies the weights of the individual data points. This, in conjunction with the list pen styles (see the <B>-styles</B> option) controls how data points are drawn. <I>WVec</I> is the name of a BLT vector or a list of numeric expressions representing the weights for each data point. </DD> <DT><B>-xdata <I>xVec</I></B> </DT> <DD>Specifies the x-coordinates of the data. <I>XVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> <DT><B>-ydata <I>yVec</I></B> </DT> <DD>Specifies the y-coordinates of the data. <I>YVec</I> is the name of a BLT vector or a list of numeric expressions. </DD> </DL> <P> Element configuration options may also be set by the <B>option</B> command. The resource class is <I>Element</I>. The resource name is the name of the element. <BR> <CODE>option add *Stripchart.Element.symbol line<BR> option add *Stripchart.e1.symbol line<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>element create <I>elemName</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a new element <I>elemName</I>. It's an error is an element <I>elemName</I> already exists. If additional arguments are present, they specify options valid for element <B>configure</B> operation. </DD> <DT><I>pathName <B>element deactivate <I>elemName</I></B></I> ?<I>elemName</I>?... </DT> <DD>Deactivates all the elements matching <I>pattern</I>. Elements whose names match any of the patterns given are redrawn using their normal colors. </DD> <DT><I>pathName <B>element delete</B></I> ?<I>elemName</I>?... </DT> <DD>Deletes all the named elements. The graph is automatically redrawn. </DD> <DT><I>pathName <B>element exists <I>elemName</I></B></I> </DT> <DD>Returns <I>1</I> if an element <I>elemName</I> currently exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>element names </B></I>?<I>pattern</I>?... </DT> <DD>Returns the elements matching one or more pattern. If no <I>pattern</I> is given, the names of all elements is returned. </DD> <DT><I>pathName <B>element show</B></I> ?<I>nameList</I>? </DT> <DD>Queries or modifies the element display list. The element display list designates the elements drawn and in what order. <I>NameList</I> is a list of elements to be displayed in the order they are named. If there is no <I>nameList</I> argument, the current display list is returned. </DD> <DT><I>pathName <B>element type</B></I> <I>elemName</I> </DT> <DD>Returns the type of <I>elemName</I>. If the element is a bar element, the commands returns the string <I>"bar"</I>, otherwise it returns <I>"line"</I>. </DD> </DL> <H3><A NAME="sect11" HREF="#toc11"></CODE><P>Grid Component</A></H3> Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. <DL> <DT><I>pathName <B>grid cget <I>option</I></B></I> </DT> <DD>Returns the current value of the grid line configuration option given by <I>option</I>. <I>Option</I> may be any option described below for the grid <B>configure</B> operation. </DD> <DT><I>pathName <B>grid configure</B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for grid lines. If <I>option</I> isn't specified, a list describing all the current grid options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the grid line option <I>option</I> is set to <I>value</I>. The following options are valid for grid lines. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the grid lines. The default is <I>black</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the grid lines. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the grid will be solid lines. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the grid should be drawn. If <I>boolean</I> is true, grid lines are not shown. The default is <I>yes</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of grid lines. The default width is <I>1</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to display grid lines. <I>XAxis</I> must be the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to display grid lines. <I>YAxis</I> must be the name of an axis. The default is <I>y</I>. </DD> <DT><B>-minor <I>boolean</I></B> </DT> <DD>Indicates whether the grid lines should be drawn for minor ticks. If <I>boolean</I> is true, the lines will appear at minor tick intervals. The default is <I>1</I>. </DD> </DL> <P> Grid configuration options may also be set by the <B>option</B> command. The resource name and class are <I>grid</I> and <I>Grid</I> respectively. <BR> <CODE>option add *Stripchart.grid.LineWidth 2<BR> option add *Stripchart.Grid.Color black<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>grid off</B></I> </DT> <DD>Turns off the display the grid lines. </DD> <DT><I>pathName <B>grid on</B></I> </DT> <DD>Turns on the display the grid lines. </DD> <DT><I>pathName <B>grid toggle</B></I> </DT> <DD>Toggles the display of the grid. </DD> </DL> <H3><A NAME="sect12" HREF="#toc12">Legend Component</A></H3> The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. <P> The following operations are valid for the legend. <DL> <DT><I>pathName <B>legend activate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend cget <I>option</I></B></I> </DT> <DD>Returns the current value of a legend configuration option. <I>Option</I> may be any option described below in the legend <B>configure</B> operation. </DD> <DT><I>pathName <B>legend configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for the legend. If <I>option</I> isn't specified, a list describing the current legend options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the legend option <I>option</I> is set to <I>value</I>. The following options are valid for the legend. <blockquote></DD> <DT><B>-activebackground <I>color</I></B> </DT> <DD>Sets the background color for active legend entries. All legend entries marked active (see the legend <B>activate</B> operation) are drawn using this background color. </DD> <DT><B>-activeborderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the active legend entries. The default is <I>2</I>. </DD> <DT><B>-activeforeground <I>color</I></B> </DT> <DD>Sets the foreground color for active legend entries. All legend entries marked as active (see the legend <B>activate</B> operation) are drawn using this foreground color. </DD> <DT><B>-activerelief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect desired for active legend entries. <I>Relief</I> denotes how the interior of the entry should appear relative to the legend; for example, <I>raised</I> means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is <I>flat</I>. </DD> <DT><B>-anchor <I>anchor</I></B> </DT> <DD>Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the <B>-position</B> option. The default is <I>center</I>. <blockquote></DD> <DT><I>left</I> or <I>right</I> </DT> <DD>The anchor describes how to position the legend vertically. </DD> <DT><I>top</I> or <I>bottom</I> </DT> <DD>The anchor describes how to position the legend horizontally. </DD> <DT><I>@x,y</I> </DT> <DD>The anchor specifies how to position the legend relative to the positioning point. For example, if <I>anchor</I> is <I>center</I> then the legend is centered on the point; if <I>anchor</I> is <I>n</I> then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. </DD> <DT><I>plotarea</I> </DT> <DD>The anchor specifies how to position the legend relative to the plotting area. For example, if <I>anchor</I> is <I>center</I> then the legend is centered in the plotting area; if <I>anchor</I> is <I>ne</I> then the legend will be drawn such that occupies the upper right corner of the plotting area. </DD> </DL> </blockquote> <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the legend. If <I>color</I> is <I>""</I>, the legend background with be transparent. </DD> <DT><B>-borderwidth <I>pixels</I></B> </DT> <DD>Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the <B>relief</B> option determines this). The default is <I>2</I> pixels. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD><I>FontName</I> specifies a font to use when drawing the labels of each element into the legend. The default is <I>*-Helvetica-Bold-R-Normal-*-12-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of the text drawn for the element's label. The default is <I>black</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the legend should be displayed. If <I>boolean</I> is true, the legend will not be draw. The default is <I>no</I>. </DD> <DT><B>-ipadx <I>pad</I></B> </DT> <DD>Sets the amount of internal padding to be added to the width of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If <I>pad</I> is just one distance, both the left and right sides are padded evenly. The default is <I>2</I>. </DD> <DT><B>-ipady <I>pad</I></B> </DT> <DD>Sets an amount of internal padding to be added to the height of each legend entry. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top of the entry is padded by the first distance and the bottom by the second. If <I>pad</I> is just one distance, both the top and bottom of the entry are padded evenly. The default is <I>2</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the legend is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the legend. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the legend is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>0</I>. </DD> <DT><B>-position <I>pos</I></B> </DT> <DD>Specifies where the legend is drawn. The <B>-anchor</B> option also affects where the legend is positioned. If <I>pos</I> is <I>left</I>, <I>left</I>, <I>top</I>, or <I>bottom</I>, the legend is drawn in the specified margin. If <I>pos</I> is <I>plotarea</I>, then the legend is drawn inside the plotting area at a particular anchor. If <I>pos</I> is in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is <I>right</I>. </DD> <DT><B>-raised <I>boolean</I></B> </DT> <DD>Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If <I>boolean</I> is true, the legend will be drawn on top of any elements that may overlap it. The default is <I>no</I>. </DD> <DT><B>-relief <I>relief</I></B> </DT> <DD>Specifies the 3-D effect for the border around the legend. <I>Relief</I> specifies how the interior of the legend should appear relative to the strip chart; for example, <I>raised</I> means the legend should appear to protrude from the strip chart, relative to the surface of the strip chart. The default is <I>sunken</I>. </DD> </DL> <P> Legend configuration options may also be set by the <B>option</B> command. The resource name and class are <I>legend</I> and <I>Legend</I> respectively. <BR> <CODE>option add *Stripchart.legend.Foreground blue<BR> option add *Stripchart.Legend.Relief raised<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>legend deactivate <I>pattern</I></B></I>... </DT> <DD>Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match <I>pattern</I> are selected. To be selected, the element name must match only one <I>pattern</I>. </DD> <DT><I>pathName <B>legend get <I>pos</I></B></I> </DT> <DD>Returns the name of the element whose entry is at the screen position <I>pos</I> in the legend. <I>Pos</I> must be in the form "<I>@x,y</I>", where <I>x</I> and <I>y</I> are window coordinates. If the given coordinates do not lie over a legend entry, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect13" HREF="#toc13">Pen Components</A></H3> Pens define attributes (both symbol and line style) for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's <B>-weight</B> and <B>-style</B> options). <P> One pen, called <I>activeLine</I>, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. <BR> <CODE>.s pen configure "activeLine" -color green<BR> </CODE><P>You can create and use any number of pens. To create a pen, invoke the pen component and its create operation. <BR> <CODE>.s pen create myPen<BR> </CODE><P>You map pens to a data element using either the element's <B>-pen</B> or <B>-activepen</B> options. <BR> <CODE>.s element create "line1" -xdata $x -ydata $tempData \<BR> -pen myPen<BR> </CODE><P>An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the <B>-styles</B> option). <BR> <CODE>.s element configure "line1" -styles { myPen 2.0 3.0 }<BR> </CODE><P>This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen <I>myPen</I>. All other points are drawn with the element's default attributes. <P> The following operations are available for pen components. <P> <DL> <DT><I>pathName <B>pen <B>cget <I>penName <I>option</I></I></B></B></I> </DT> <DD>Returns the current value of the option given by <I>option</I> for <I>penName</I>. <I>Option</I> may be any option described below for the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>configure <I>penName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options of <I>penName</I>. If <I>option</I> isn't specified, a list describing the current options for <I>penName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the pen option <I>option</I> is set to <I>value</I>. The following options are valid for pens. <blockquote></DD> <DT><B>-color <I>color</I></B> </DT> <DD>Sets the color of the traces connecting the data points. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of element line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the lines will be solid. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the interior color of symbols. If <I>color</I> is <I>""</I>, then the interior of the symbol is transparent. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the connecting lines between data points. If <I>pixels</I> is <I>0</I>, no connecting lines will be drawn between symbols. The default is <I>0</I>. </DD> <DT><B>-offdash <I>color</I></B> </DT> <DD>Sets the color of the stripes when traces are dashed (see the <B>-dashes</B> option). If <I>color</I> is <I>""</I>, then the "off" pixels will represent gaps instead of stripes. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color or the outline around each symbol. If <I>color</I> is <I>""</I>, then no outline is drawn. If <I>color</I> is <I>defcolor</I>, then the color will be the same as the <B>-color</B> option. The default is <I>defcolor</I>. </DD> <DT><B>-outlinewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline bordering each symbol. If <I>pixels</I> is <I>0</I>, no outline will be drawn. The default is <I>1</I>. </DD> <DT><B>-pixels <I>pixels</I></B> </DT> <DD>Sets the size of symbols. If <I>pixels</I> is <I>0</I>, no symbols will be drawn. The default is <I>0.125i</I>. </DD> <DT><B>-symbol <I>symbol</I></B> </DT> <DD>Specifies the symbol for data points. <I>Symbol</I> can be either <I>square</I>, <I>circle</I>, <I>diamond</I>, <I>plus</I>, <I>cross</I>, <I>splus</I>, <I>scross</I>, <I>triangle</I>, <I>""</I> (where no symbol is drawn), or a bitmap. Bitmaps are specified as "<I>source</I> ?<I>mask</I>?", where <I>source</I> is the name of the bitmap, and <I>mask</I> is the bitmap's optional mask. The default is <I>circle</I>. </DD> <DT><B>-type <I>elemType</I></B> </DT> <DD>Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "line". </DD> </DL> <P> Pen configuration options may be also be set by the <B>option</B> command. The resource class is <I>Pen</I>. The resource names are the names of the pens. <BR> <CODE>option add *Stripchart.Pen.Color blue<BR> option add *Stripchart.activeLine.color green<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>pen <B>create <I>penName </I></B></B></I>?<I>option value</I>?... </DT> <DD>Creates a new pen by the name <I>penName</I>. No pen by the same name can already exist. <I>Option</I> and <I>value</I> are described in above in the pen <B>configure</B> operation. </DD> <DT><I>pathName <B>pen <B>delete </B></B></I>?<I>penName</I>?... </DT> <DD>Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. </DD> <DT><I>pathName <B>pen names </B></I>?<I>pattern</I>?... </DT> <DD>Returns a list of pens matching zero or more patterns. If no <I>pattern</I> argument is give, the names of all pens are returned. </DD> </DL> <H3><A NAME="sect14" HREF="#toc14">PostScript Component</A></H3> The strip chart can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot is generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. <P> The following postscript operations are available. <DL> <DT><I>pathName <B>postscript cget <I>option</I></B></I> </DT> <DD>Returns the current value of the postscript option given by <I>option</I>. <I>Option</I> may be any option described below for the postscript <B>configure</B> operation. </DD> <DT><I>pathName <B>postscript configure </B></I>?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for PostScript generation. If <I>option</I> isn't specified, a list describing the current postscript options for <I>pathName</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the postscript option <I>option</I> is set to <I>value</I>. The following postscript options are available. <blockquote></DD> <DT><B>-center <I>boolean</I></B> </DT> <DD>Indicates whether the plot should be centered on the PostScript page. If <I>boolean</I> is false, the plot will be placed in the upper left corner of the page. The default is <I>1</I>. </DD> <DT><B>-colormap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of <I>varName</I> must consist of PostScript code to set a particular color value (e.g. ``<I>1.0 1.0 0.0 setrgbcolor</I>''). When outputting color information in PostScript, the array variable <I>varName</I> is checked to see if an element of the name of the color exists. If so, it uses the value of the element as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in <I>varName</I> for a given color, then it uses the red, green, and blue intensities from the X color. </DD> <DT><B>-colormode <I>mode</I></B> </DT> <DD>Specifies how to output color information. <I>Mode</I> must be either <I>color</I> (for full color output), <I>gray</I> (convert all colors to their gray-scale equivalents) or <I>mono</I> (convert foreground colors to black and background colors to white). The default mode is <I>color</I>. </DD> <DT><B>-fontmap <I>varName</I></B> </DT> <DD><I>VarName</I> must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of <I>varName</I> must consist of a Tcl list with one or two elements, which are the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable <I>varName</I> is checked to see an element of the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is <I>Adobe</I> (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to <I>Helvetica-Bold</I>. </DD> <DT><B>-decorations <I>boolean</I></B> </DT> <DD>Indicates if PostScript commands to generate color backgrounds and 3-D borders should be output. If <I>boolean</I> is false, the background will be white and no 3-D borders will be generated. The default is <I>1</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Sets the height of the plot. This lets you plot the stripchart with a height different from the one displayed on the screen. If <I>pixels</I> is 0, the height is the same as the displayed height. The default is <I>0</I>. </DD> <DT><B>-landscape <I>boolean</I></B> </DT> <DD>If <I>boolean</I> is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to <I>0</I>. </DD> <DT><B>-maxpect <I>boolean</I></B> </DT> <DD>Indicates to scale the the plot so that it fills the PostScript page. The aspect ratio of the strip chart is still retained. The default is <I>0</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left border is padded by the first distance and the right border by the second. If <I>pad</I> has just one distance, both the left and right borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the top border is padded by the first distance and the bottom border by the second. If <I>pad</I> has just one distance, both the top and bottom borders are padded evenly. The default is <I>1i</I>. </DD> <DT><B>-paperheight <I>pixels</I></B> </DT> <DD>Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is <I>11.0i</I>. </DD> <DT><B>-paperwidth <I>pixels</I></B> </DT> <DD>Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is <I>8.5i</I>. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Sets the width of the plot. This lets you plot the strip chart with a width different from the one drawn on the screen. If <I>pixels</I> is 0, the width is the same as the widget's width. The default is <I>0</I>. </DD> </DL> <P> Postscript configuration options may be also be set by the <B>option</B> command. The resource name and class are <I>postscript</I> and <I>Postscript</I> respectively. <BR> <CODE>option add *Stripchart.postscript.Decorations false<BR> option add *Stripchart.Postscript.Landscape true<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>postscript output </B></I>?<I>fileName</I>? ?<I>option value</I>?... </DT> <DD>Outputs a file of encapsulated PostScript. If a <I>fileName</I> argument isn't present, the command returns the PostScript. If any <I>option-value</I> pairs are present, they set configuration options controlling how the PostScript is generated. <I>Option</I> and <I>value</I> can be anything accepted by the postscript <B>configure</B> operation above. </DD> </DL> <H3><A NAME="sect15" HREF="#toc15">Marker Components</A></H3> Markers are simple drawing procedures used to annotate or highlight areas of the strip chart. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the <B>-under</B> option. <P> Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have <I>elastic</I> coordinates (specified by <I>-Inf</I> and <I>Inf</I> respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates <I>-Inf</I>,<I>-Inf</I>. <P> The following operations are available for markers. <DL> <DT><I>pathName <B>marker after <I>markerId</I></B></I> ?<I>afterId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker after the second. If no second <I>afterId</I> argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker before <I>markerId</I></B></I> ?<I>beforeId</I>? </DT> <DD>Changes the order of the markers, drawing the first marker before the second. If no second <I>beforeId</I> argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. </DD> <DT><I>pathName <B>marker cget <I>option</I></B></I> </DT> <DD>Returns the current value of the marker configuration option given by <I>option</I>. <I>Option</I> may be any option described below in the <B>configure</B> operation. </DD> <DT><I>pathName <B>marker configure <I>markerId</I></B></I> ?<I>option value</I>?... </DT> <DD>Queries or modifies the configuration options for markers. If <I>option</I> isn't specified, a list describing the current options for <I>markerId</I> is returned. If <I>option</I> is specified, but not <I>value</I>, then a list describing <I>option</I> is returned. If one or more <I>option</I> and <I>value</I> pairs are specified, then for each pair, the marker option <I>option</I> is set to <I>value</I>. <P> The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. <blockquote></DD> <DT><B>-coords <I>coordList</I></B> </DT> <DD>Specifies the coordinates of the marker. <I>CoordList</I> is a list of graph coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If <I>coordList</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-element <I>elemName</I></B> </DT> <DD>Links the marker with the element <I>elemName</I>. The marker is drawn only if the element is also currently displayed (see the element's <B>show</B> operation). If <I>elemName</I> is <I>""</I>, the marker is always drawn. The default is <I>""</I>. </DD> <DT><B>-hide <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn. If <I>boolean</I> is true, the marker is not drawn. The default is <I>no</I>. </DD> <DT><B>-mapx <I>xAxis</I></B> </DT> <DD>Specifies the X-axis to map the marker's X-coordinates onto. <I>XAxis</I> must the name of an axis. The default is <I>x</I>. </DD> <DT><B>-mapy <I>yAxis</I></B> </DT> <DD>Specifies the Y-axis to map the marker's Y-coordinates onto. <I>YAxis</I> must the name of an axis. The default is <I>y</I>. </DD> <DT><B>-name <I>markerId</I></B> </DT> <DD>Changes the identifier for the marker. The identifier <I>markerId</I> can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. </DD> <DT><B>-under <I>boolean</I></B> </DT> <DD>Indicates whether the marker is drawn below/above data elements. If <I>boolean</I> is true, the marker is be drawn underneath the data element symbols and lines. Otherwise, the marker is drawn on top of the element. The default is <I>0</I>. </DD> <DT><B>-xoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the marker horizontally. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> <DT><B>-yoffset <I>pixels</I></B> </DT> <DD>Specifies a screen distance to offset the markers vertically. <I>Pixels</I> is a valid screen distance, such as <I>2</I> or <I>1.2i</I>. The default is <I>0</I>. </DD> </DL> <P> Marker configuration options may also be set by the <B>option</B> command. The resource class is either <I>BitmapMarker</I>, <I>ImageMarker</I>, <I>LineMarker</I>, <I>PolygonMarker</I>, <I>TextMarker</I>, or <I>WindowMarker</I>, depending on the type of marker. The resource name is the name of the marker. <BR> <CODE>option add *Stripchart.TextMarker.Foreground white<BR> option add *Stripchart.BitmapMarker.Foreground white<BR> option add *Stripchart.m1.Background blue<BR> </blockquote> <DL> <DT></CODE><P><I>pathName <B>marker create <I>type</I></B></I> ?<I>option value</I>?... </DT> <DD>Creates a marker of the selected type. <I>Type</I> may be either <I>text</I>, <I>line</I>, <I>bitmap</I>, <I>image</I>, <I>polygon</I>, or <I>window</I>. This command returns the marker identifier, used as the <I>markerId</I> argument in the other marker-related commands. If the <B>-name</B> option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. </DD> <DT><I>pathName <B>marker delete</B></I> ?<I>name</I>?... </DT> <DD>Removes one of more markers. The graph will automatically be redrawn without the marker.. </DD> <DT><I>pathName <B>marker exists <I>markerId</I></B></I> </DT> <DD>Returns <I>1</I> if the marker <I>markerId</I> exists and <I>0</I> otherwise. </DD> <DT><I>pathName <B>marker names</B></I> ?<I>pattern</I>? </DT> <DD>Returns the names of all the markers that currently exist. If <I>pattern</I> is supplied, only those markers whose names match it will be returned. </DD> <DT><I>pathName <B>marker type <I>markerId</I></B></I> </DT> <DD>Returns the type of the marker given by <I>markerId</I>, such as <I>line</I> or <I>text</I>. If <I>markerId</I> is not a valid a marker identifier, <I>""</I> is returned. </DD> </DL> <H3><A NAME="sect16" HREF="#toc16">Bitmap Markers</A></H3> A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. <P> Bitmap markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create bitmap </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration options for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to bitmap markers: <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the bitmap. If <I>color</I> is <I>""</I>, the background color will be transparent. The default background color is <I>white</I>. </DD> <DT><B>-bitmap <I>bitmap</I></B> </DT> <DD>Specifies the bitmap to be displayed. If <I>bitmap</I> is <I>""</I>, the marker will not be displayed. The default is <I>""</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of the bitmap. The default foreground color is <I>black</I>. </DD> <DT><B>-mask <I>mask</I></B> </DT> <DD>Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If <I>mask</I> is <I>""</I>, all pixels of the bitmap will be drawn. The default is <I>""</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Sets the rotation of the bitmap. <I>Theta</I> is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is <I>0.0</I>. </DD> </DL> <H3><A NAME="sect17" HREF="#toc17">Image Markers</A></H3> A image marker displays an image. Image markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create image </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to image markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the image relative to the positioning point for the image. For example, if <I>anchor</I> is <I>center</I> then the image is centered on the point; if <I>anchor</I> is <I>n</I> then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-image <I>image</I></B> </DT> <DD>Specifies the image to be drawn. If <I>image</I> is <I>""</I>, the marker will not be drawn. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect18" HREF="#toc18">Line Markers</A></H3> A line marker displays one or more connected line segments. Line markers are created with marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create line </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to line markers: <DL> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the line. The option is affects the line color only when the <B>-stipple</B> option is set. If this option isn't specified then it defaults to <I>white</I>. </DD> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the line. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the marker line will be solid. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color. The default foreground color is <I>black</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the lines. The default width is <I>0</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies a stipple pattern used to draw the line, rather than a solid line. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the line is drawn in a solid fashion. The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect19" HREF="#toc19">Polygon Markers</A></H3> A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create polygon </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the <B>marker configure</B> command to change the marker's configuration. The following options are supported for polygon markers: <DL> <DT><B>-dashes <I>dashList</I></B> </DT> <DD>Sets the dash style of the outline of the polygon. <I>DashList</I> is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If <I>dashList</I> is <I>""</I>, the outline will be a solid line. </DD> <DT><B>-fill <I>color</I></B> </DT> <DD>Sets the fill color of the polygon. If <I>color</I> is <I>""</I>, then the interior of the polygon is transparent. The default is <I>white</I>. </DD> <DT><B>-linewidth <I>pixels</I></B> </DT> <DD>Sets the width of the outline of the polygon. If <I>pixels</I> is zero, no outline is drawn. The default is <I>0</I>. </DD> <DT><B>-outline <I>color</I></B> </DT> <DD>Sets the color of the outline of the polygon. If the polygon is stippled (see the <B>-stipple</B> option), then this represents the foreground color of the stipple. The default is <I>black</I>. </DD> <DT><B>-stipple <I>bitmap</I></B> </DT> <DD>Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. <I>Bitmap</I> specifies a bitmap to use as the stipple pattern. If <I>bitmap</I> is <I>""</I>, then the polygon is filled with a solid color (if the <B>-fill</B> option is set). The default is <I>""</I>. </DD> </DL> <H3><A NAME="sect20" HREF="#toc20">Text Markers</A></H3> A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the strip chart. Text markers are created with the <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create text </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the text marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> operation. <P> The following options are specific to text markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the text relative to the positioning point for the text. For example, if <I>anchor</I> is <I>center</I> then the text is centered on the point; if <I>anchor</I> is <I>n</I> then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is <I>center</I>. </DD> <DT><B>-background <I>color</I></B> </DT> <DD>Sets the background color of the text string. If <I>color</I> is <I>""</I>, the background will be transparent. The default is <I>white</I>. </DD> <DT><B>-font <I>fontName</I></B> </DT> <DD>Specifies the font of the text. The default is <I>*-Helvetica-Bold-R-Normal-*-120-*</I>. </DD> <DT><B>-foreground <I>color</I></B> </DT> <DD>Sets the foreground color of the text. The default is <I>black</I>. </DD> <DT><B>-justify <I>justify</I></B> </DT> <DD>Specifies how the text should be justified. This matters only when the marker contains more than one line of text. <I>Justify</I> must be <I>left</I>, <I>right</I>, or <I>center</I>. The default is <I>center</I>. </DD> <DT><B>-padx <I>pad</I></B> </DT> <DD>Sets the padding to the left and right exteriors of the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the left side of the text is padded by the first distance and the right side by the second. If <I>pad</I> has just one distance, both the left and right sides are padded evenly. The default is <I>4</I>. </DD> <DT><B>-pady <I>pad</I></B> </DT> <DD>Sets the padding above and below the text. <I>Pad</I> can be a list of one or two screen distances. If <I>pad</I> has two elements, the area above the text is padded by the first distance and the area below by the second. If <I>pad</I> is just one distance, both the top and bottom areas are padded evenly. The default is <I>4</I>. </DD> <DT><B>-rotate <I>theta</I></B> </DT> <DD>Specifies the number of degrees to rotate the text. <I>Theta</I> is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is <I>0.0</I>. </DD> <DT><B>-text <I>text</I></B> </DT> <DD>Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as <B>-anchor</B> or <B>-rotate</B>. </DD> </DL> <H3><A NAME="sect21" HREF="#toc21">Window Markers</A></H3> A window marker displays a widget at a given position. Window markers are created with the marker's <B>create</B> operation in the form: <BR> <P> <CODE><I>pathName <B>marker create window </B></I>?<I>option value</I>?...<BR> </CODE><P>There may be many <I>option</I>-<I>value</I> pairs, each sets a configuration option for the marker. These same <I>option</I>-<I>value</I> pairs may be used with the marker's <B>configure</B> command. <P> The following options are specific to window markers: <DL> <DT><B>-anchor <I>anchor</I></B> </DT> <DD><I>Anchor</I> tells how to position the widget relative to the positioning point for the widget. For example, if <I>anchor</I> is <I>center</I> then the widget is centered on the point; if <I>anchor</I> is <I>n</I> then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to <I>center</I>. </DD> <DT><B>-height <I>pixels</I></B> </DT> <DD>Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever height the widget requests internally. </DD> <DT><B>-width <I>pixels</I></B> </DT> <DD>Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as <I>""</I>, then the window is given whatever width the widget requests internally. </DD> <DT><B>-window <I>pathName</I></B> </DT> <DD>Specifies the widget to be managed. <I>PathName</I> must be a child of the <B>stripchart</B> widget. </DD> </DL> <H2><A NAME="sect22" HREF="#toc22">Graph Component Bindings</A></H2> Specific stripchart components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as <B>Enter</B>, <B>Leave</B>, <B>ButtonPress</B>, <B>Motion</B>, and <B>KeyPress</B>). <P> Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. <P> It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the <B>-bindtags</B> option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. <P> The <B>-bindtagsR option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the <B>-bindtags</B></B> option doesn't change this. <H2><A NAME="sect23" HREF="#toc23">C Language API</A></H2> You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. <P> Data can manipulated from the C language using BLT vectors. You specify the x and y data coordinates of an element as vectors and manipulate the vector from C. The strip chart will be redrawn automatically after the vectors are updated. <P> From Tcl, create the vectors and configure the element to use them. <BR> <CODE>vector X Y<BR> .s element configure line1 -xdata X -ydata Y<BR> </CODE><P>To set data points from C, you pass the values as arrays of doubles using the <B>Blt_ResetVector</B> call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the strip chart will be redrawn automatically. <BR> <CODE>#include &lt;tcl.h&gt;<BR> #include &lt;blt.h&gt;<BR> <P> register int i;<BR> Blt_Vector *xVec, *yVec;<BR> double x[50], y[50];<BR> <P> /* Get the BLT vectors "X" and "Y" (created above from Tcl) */<BR> if ((Blt_GetVector(interp, "X", 50, &amp;xVec) != TCL_OK) ||<BR> (Blt_GetVector(interp, "Y", 50, &amp;yVec) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> <P> for (i = 0; i &lt; 50; i++) {<BR> x[i] = i * 0.02;<BR> y[i] = sin(x[i]);<BR> }<tt>&#32;</tt>&nbsp;<tt>&#32;</tt>&nbsp;<BR> <P> /* Put the data into BLT vectors */<BR> if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) ||<BR> (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) {<BR> return TCL_ERROR;<BR> }<BR> </CODE><P>See the <B>vector</B> manual page for more details. <H2><A NAME="sect24" HREF="#toc24">Speed Tips</A></H2> There may be cases where the strip chart needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. <UL> &#183;<LI>Try to minimize the number of data points. The more data points the looked at, the more work the strip chart must do. </LI>&#183;<LI>If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. </LI>&#183;<LI>Data elements without symbols are drawn faster than with symbols. Set the data element's <B>-symbol</B> option to <I>none</I>. If you need to draw symbols, try using the simple symbols such as <I>splus</I> and <I>scross</I>. </LI>&#183;<LI>Don't stipple or dash the element. Solid lines are much faster. </LI>&#183;<LI>If you update data elements frequently, try turning off the widget's <B>-bufferelements</B> option. When the strip chart is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the strip chart needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the strip chart. But if the strip chart is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. </LI> </UL> <H2><A NAME="sect25" HREF="#toc25">Limitations</A></H2> Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. <P> The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. <H2><A NAME="sect26" HREF="#toc26">Future Incompatibility</A></H2> The <B>-mapped</B> options are obsoleted and will be removed. You can achieve the same results using the <B>-hide</B> option instead. <BR> <CODE># Works for now.<BR> .s legend configure -mapped no<BR> <P> # Instead use this.<BR> .s legend configure -hide yes <BR> <H2><A NAME="sect27" HREF="#toc27"></CODE><P>Keywords</A></H2> stripchart, graph, widget <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Syntax</A></LI> <LI><A NAME="toc5" HREF="#sect5">Example</A></LI> <LI><A NAME="toc6" HREF="#sect6">Stripchart Operations</A></LI> <LI><A NAME="toc7" HREF="#sect7">Stripchart Components</A></LI> <UL> <LI><A NAME="toc8" HREF="#sect8">Axis Components</A></LI> <LI><A NAME="toc9" HREF="#sect9">Crosshairs Component</A></LI> <LI><A NAME="toc10" HREF="#sect10">Element Components</A></LI> <LI><A NAME="toc11" HREF="#sect11">Grid Component</A></LI> <LI><A NAME="toc12" HREF="#sect12">Legend Component</A></LI> <LI><A NAME="toc13" HREF="#sect13">Pen Components</A></LI> <LI><A NAME="toc14" HREF="#sect14">PostScript Component</A></LI> <LI><A NAME="toc15" HREF="#sect15">Marker Components</A></LI> <LI><A NAME="toc16" HREF="#sect16">Bitmap Markers</A></LI> <LI><A NAME="toc17" HREF="#sect17">Image Markers</A></LI> <LI><A NAME="toc18" HREF="#sect18">Line Markers</A></LI> <LI><A NAME="toc19" HREF="#sect19">Polygon Markers</A></LI> <LI><A NAME="toc20" HREF="#sect20">Text Markers</A></LI> <LI><A NAME="toc21" HREF="#sect21">Window Markers</A></LI> </UL> <LI><A NAME="toc22" HREF="#sect22">Graph Component Bindings</A></LI> <LI><A NAME="toc23" HREF="#sect23">C Language API</A></LI> <LI><A NAME="toc24" HREF="#sect24">Speed Tips</A></LI> <LI><A NAME="toc25" HREF="#sect25">Limitations</A></LI> <LI><A NAME="toc26" HREF="#sect26">Future Incompatibility</A></LI> <LI><A NAME="toc27" HREF="#sect27">Keywords</A></LI> </UL> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/html/winop.html�������������������������������������������������������������������0000644�0001750�0001750�00000012030�11462120062�015220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, --> <!-- available via anonymous ftp from ftp.cs.berkeley.edu:/ucb/people/phelps/tcltk/rman.tar.Z --> <HTML> <HEAD> <TITLE>winop(n) manual page</TITLE> </HEAD> <BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red"> <A HREF="#toc">Table of Contents</A><P> <H2><A NAME="sect0" HREF="#toc0">Name</A></H2> winop - Perform assorted window operations <H2><A NAME="sect1" HREF="#toc1">Synopsis</A></H2> <B>winop lower</B> ?<I>window</I>?... <P> <B>winop map</B> ?<I>window</I>?... <P> <B>winop move <I>window x y</I></B> <P> <B>winop raise</B> ?<I>window</I>?... <P> <B>winop snap <I>window photoName</I></B> <P> <B>winop unmap</B> ?<I>window</I>?... <P> <B>winop warpto</B> ?<I>window</I>? <H2><A NAME="sect2" HREF="#toc2">Description</A></H2> The <B>winop</B> command performs various window operations on Tk windows using low-level Xlib function calls to work around window manager pecularities. <H2><A NAME="sect3" HREF="#toc3">Introduction</A></H2> Tk has several commands for manipulating its windows: <B>raise</B>, <B>lower</B>, <B>wm</B>, etc. These commands ask the window manager to perform operations on Tk windows. In some cases, a particular window manager won't perform the operation as expected. <P> For example, if you positioned a toplevel window using <B>wm geometry</B>, the window may not actually be at those particular coordinates. The position of the window may be offset by dimensions of the title bar added by the window manager. <P> In situations like these, the <B>winop</B> command can be used to workaround these difficulties. Instead, it makes low-level Xlib (such <B>XRaiseWindow</B> and <B>XMapWindow</B>) calls to perform these operations. <BR> <CODE>toplevel .top<BR> wm withdraw .top<BR> <P> # Set the geometry to make the window manager <BR> # place the window.<BR> wm geometry .top +100+100<BR> <P> # Move the window to the desired location<BR> # and "update" to force the window manager<BR> # to recognize it.<BR> winop move .top 100 100<BR> update <BR> <P> wm deiconify .top<BR> winop move .top 100 100<BR> <H2><A NAME="sect4" HREF="#toc4"></CODE><P>Operations</A></H2> The following operations are available for the <B>winop</B> command: <DL> <DT><B>winop lower</B> ?<I>window</I>?... </DT> <DD>Lowers <I>window</I> to the bottom of the X window stack. <I>Window</I> is the path name of a Tk window. </DD> <DT><B>winop map</B> ?<I>window</I>?... </DT> <DD>Maps <I>window</I> on the screen. <I>Window</I> is the path name of a Tk window. If <I>window</I> is already mapped, this command has no effect. </DD> <DT><B>winop move <I>window x y</I></B> </DT> <DD>Move <I>window</I> to the screen location specified by <I>x</I> and <I>y</I>. <I>Window</I> is the path name of a Tk window, while <I>x</I> and <I>y</I> are screen coordinates. This command returns the empty string. </DD> <DT><B>winop raise</B> ?<I>window</I>?... </DT> <DD>Raises <I>window</I> to the top of the X window stack. <I>Window</I> must be a valid path name of a Tk window. This command returns the empty string. </DD> <DT><B>winop snap <I>window photoName</I></B> </DT> <DD>Takes a snapshot of the <I>window</I> and stores the contents in the photo image <I>photoName</I>. <I>Window</I> is the valid path name of a Tk window which must be totally visible (unobscured). <I>PhotoName</I> is the name of a Tk photo image which must already exist. This command can fail if the window is obscured in any fashion, such as covered by another window or partially offscreen. In that case, an error message is returned. </DD> <DT><B>winop unmap</B> ?<I>window</I>?... </DT> <DD>Unmaps <I>window</I> from the screen. <I>Window</I> is the path name of a Tk window. </DD> <DT><B>winop warpto</B> ?<I>window</I>? </DT> <DD>Warps the pointer to <I>window</I>. <I>Window</I> is the path name of a Tk window which must be mapped. If <I>window</I> is in the form <I>@x,y</I>, where <I>x</I> and <I>y</I> are root screen coordinates, the pointer is warped to that location on the screen. <P> [<I>I've never heard a good case for warping the pointer in an application. It can be useful for testing, but in applications, it's always a bad idea. Simply stated, the user owns the pointer, not the application. If you have an application that needs it, I'd like to hear about it.</I>] <P> If no <I>window</I> argument is present the current location of the pointer is returned. The location is returned as a list in the form "<I>x y</I>", where <I>x</I> and <I>y</I> are the current coordinates of the pointer. </DD> </DL> <H2><A NAME="sect5" HREF="#toc5">Keywords</A></H2> window, map, raise, lower, pointer, warp <P> <HR><P> <A NAME="toc"><B>Table of Contents</B></A><P> <UL> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> <LI><A NAME="toc3" HREF="#sect3">Introduction</A></LI> <LI><A NAME="toc4" HREF="#sect4">Operations</A></LI> <LI><A NAME="toc5" HREF="#sect5">Keywords</A></LI> </UL> </BODY></HTML> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/Makefile.vc�����������������������������������������������������������������������0000644�0001750�0001750�00000003671�11462120062�014314� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for demonstation shell of BLT library # ------------------------------------------------------------------------ include vc.config srcdir = $(TOP) # ------------------------------------------------------------------------ # Source and target installation directories # ------------------------------------------------------------------------ instdirs = $(prefix) $(exec_prefix) $(bindir) $(libdir) $(includedir) # ------------------------------------------------------------------------ # Don't edit anything beyond this point # ------------------------------------------------------------------------ subdirs = src demos library html all: (cd src; $(MAKE) -f Makefile.vc all) (cd demos; $(MAKE) -f Makefile.vc all) (cd library; $(MAKE) -f Makefile.vc all) (cd html; $(MAKE) -f Makefile.vc all) install: install-dirs install-all install-readme install-all: (cd src; $(MAKE) -f Makefile.vc install) (cd demos; $(MAKE) -f Makefile.vc install) (cd library; $(MAKE) -f Makefile.vc install) (cd html; $(MAKE) -f Makefile.vc install) install-dirs: @for i in $(instdirs) ; do \ if test ! -d "$$i" ; then \ echo " mkdir $$i" ; \ mkdir $$i ; \ fi ; \ done install-readme: $(INSTALL_DATA) $(srcdir)/README $(scriptdir) $(INSTALL_DATA) $(srcdir)/PROBLEMS $(scriptdir) $(INSTALL_DATA) $(srcdir)/NEWS $(scriptdir) clean: (cd src; $(MAKE) -f Makefile.vc clean) (cd demos; $(MAKE) -f Makefile.vc clean) (cd library; $(MAKE) -f Makefile.vc clean) (cd html; $(MAKE) -f Makefile.vc clean) $(RM) *.bak *\~ "#"* *pure* .pure* GENERATED_FILES = \ config.status config.cache config.log Makefile distclean: clean (cd src; $(MAKE) -f Makefile.vc distclean) (cd demos; $(MAKE) -f Makefile.vc distclean) (cd library; $(MAKE) -f Makefile.vc distclean) (cd html; $(MAKE) -f Makefile.vc distclean) $(RM) $(GENERATED_FILES) �����������������������������������������������������������������������./saods9/blt3.0.1/cf/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�012622� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/cf/config.guess�������������������������������������������������������������������0000755�0001750�0001750�00000127562�11462120062�015163� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-04-14' # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner <per@bothner.com>. # Please send patches to <config-patches@gnu.org>. Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include <stdlib.h> #include <unistd.h> int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include <features.h> #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` echo ${UNAME_MACHINE}-pc-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says <Richard.M.Bartel@ccMail.Census.GOV> echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <hewes@openmarket.com>. # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include <sys/param.h> printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include <sys/param.h> # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 <<EOF $0: unable to guess system type This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be pertinent to <config-patches@gnu.org> in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ����������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/cf/install-sh���������������������������������������������������������������������0000755�0001750�0001750�00000014253�11462120062�014637� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/#inst.$$# rmtmp=$dstdir/#rm.$$# # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/cf/ldAix��������������������������������������������������������������������������0000644�0001750�0001750�00000005066�11462120062�013621� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # # ldAix ldCmd ldArg ldArg ... # # This shell script provides a wrapper for ld under AIX in order to # create the .exp file required for linking. Its arguments consist # of the name and arguments that would normally be provided to the # ld command. This script extracts the names of the object files # from the argument list, creates a .exp file describing all of the # symbols exported by those files, and then invokes "ldCmd" to # perform the real link. # # SCCS: @(#) ldAix 1.8 97/02/21 14:50:27 # Extract from the arguments the names of all of the object files. args=$* ofiles="" for i do x=`echo $i | grep '[^.].o$'` if test "$x" != ""; then ofiles="$ofiles $i" fi done # Create the export file from all of the object files, using nm followed # by sed editing. Here are some tricky aspects of this: # # 1. Nm produces different output under AIX 4.1 than under AIX 3.2.5; # the following statements handle both versions. # 2. Use the -g switch to nm instead of -e under 4.1 (this shows just # externals, not statics; -g isn't available under 3.2.5, though). # 3. Eliminate lines that end in ":": these are the names of object # files (relevant in 4.1 only). # 4. Eliminate entries with the "U" key letter; these are undefined # symbols (relevant in 4.1 only). # 5. Eliminate lines that contain the string "0|extern" preceded by space; # in 3.2.5, these are undefined symbols (address 0). # 6. Eliminate lines containing the "unamex" symbol. In 3.2.5, these # are also undefined symbols. # 7. If a line starts with ".", delete the leading ".", since this will # just cause confusion later. # 8. Eliminate everything after the first field in a line, so that we're # left with just the symbol name. nmopts="-g -C" osver=`uname -v` if test $osver -eq 3; then nmopts="-e" fi rm -f lib.exp echo "#! " >lib.exp /usr/ccs/bin/nm $nmopts -h $ofiles | sed -e '/:$/d' -e '/ U /d' -e '/[ ]0|extern/d' -e '/unamex/d' -e 's/^\.//' -e 's/[ |].*//' | sort | uniq >>lib.exp # Extract the name of the object file that we're linking. If it's a .a # file, then link all the objects together into a single file "shr.o" # and then put that into the archive. Otherwise link the object files # directly into the .a file. outputFile=`echo $args | sed -e 's/.*-o \([^ ]*\).*/\1/'` noDotA=`echo $outputFile | sed -e '/\.a$/d'` echo "noDotA=\"$noDotA\"" if test "$noDotA" = "" ; then linkArgs=`echo $args | sed -e 's/-o .*\.a /-o shr.o /'` echo $linkArgs eval $linkArgs echo ar cr $outputFile shr.o ar cr $outputFile shr.o rm -f shr.o else eval $args fi ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/cf/config.sub���������������������������������������������������������������������0000755�0001750�0001750�00000101542�11462120062�014614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-04-14' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to <config-patches@gnu.org>. Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/cf/install.sh���������������������������������������������������������������������0000644�0001750�0001750�00000011233�11462120062�014630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057630�013040� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/README������������������������������������������������������������������������0000644�0001750�0001750�00000020052�11462120063�013713� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� This file describes how to build BLT under Windows 95/98/NT/2000/XP. It's not necessary to compile BLT for Windows 95/98/NT/2000/XP. Binary versions are available on ftp.tcltk.com/pub/blt. http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.0.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.1.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.2.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.3.exe They will dynamically load into wish80.exe, wish81.exe, wish82.exe, or wish83.exe by invoking package require BLT from within your script. If you really need to build BLT yourself, then hold onto your hat. It's a lot more difficult to build BLT under Windows than under Unix. Most Windows software is designed to be delivered as a self-installing binary executable, therefore it's rare to find the installation tools necessary to build and install BLT from the source code. 1. What versions of Tcl/Tk can I use? Any stable release. I've built and tested BLT with Tcl/Tk versions 8.0.5, 8.1.1, and 8.2.3, and 8.3.4. Avoid the alpha and beta versions. 2. What compiler can I use? You can use one of the following compilers: 1. Microsoft Visual C++ 5.0/6.0 2. Cygwin's GNU CC 2.95.2 (with or without -mno-cygwin) 3. Borland Free compiler 5.5.1 I normally build with VC++ 6.0. This is also what the binary Tcl/Tk distribution use. Note: Unless it's your only option, I don't recommend using the Borland free compiler right now. 3. What "make" program do I need? I highly recommend installing the Cygwin tool suite. You can pick this up from http://sourceware.cygnus.com/cygwin/setup.exe I normally use GNU make instead of Microsoft's nmake. But you can also nmake. If you have a choice, use the Cygnus tools. For compiling with Borland's C compiler, you can use Borland's make.exe. 4. Do I need to compile the Tcl/Tk libraries? More than likely. Unless you're compiling with Cygwin GCC and the cygwin-version of the Tcl/Tk libraries, you'll need to obtain the Tcl/Tk sources and compile them. 5. Is there anything else I need? By default, JPEG support is enabled. It uses the jpeg-6b libraries from ftp.uu.net. You can pick up the sources from ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz You can also use the Intel JPEG Libraries. JPEG support is optional. You can disable it. 6. Can I mix-and-match DLLs? You can't really mix the Borland and VC++ compiled DLLs. BLT isn't stubbed and the symbol names are incompatible between versions. The various workarounds are difficult. I haven't tested this, but I believe you can load a GNU CC (-mno-cygwin) BLT24.dll into a VC++ compiled wish. In general the best advice is to use the same compiler that that you compiled Tcl/Tk to compile BLT. 7. What compiler should I use? Right now, probably Microsoft VC++. This is what all Tcl/Tk releases 8.0 to present have been built with. So you shouldn't have to work too hard to compile the Tcl and Tk libraries. Having said that, Cygwin's GNU CC works just fine. You can obtain versions from Mumit Khan to build Tcl and Tk. I recommend compiling the Tcl/Tk libraries yourself with the -mno-cygwin option. And if compiling Tcl and Tk is too much of a hassle, you can always built BLT with the cygwin Tcl/Tk libraries (cygtcl80.dll and cygtk80.dll). The downside is that the cygwin libraries are 1) pretty old (version 8.0) and 2) there may be some incompatibilities between the native Win32 calls in BLT and the cygwin emulation layer. I have built BLT with the Borland free compiler. It's not 100% yet. The problems are 1) If you automatically load BLT from a script file, you will generate exception in the DLL. Oddly enough, you can source the script manually. 2) Resampled images are blank (see the graph3.tcl and eps.tcl demos). The same code works with both GCC and VC++. 3) I can't even get wish83.exe to open a console window. Weirdly, bltwish.exe does this properly. 4) The turbo debugger is a pain. Building BLT with Microsoft VC++, nmake, and VC++ compiled Tcl/Tk libraries. ==================================================================== 1. Install the Tcl/Tk sources. They should reside in the same directory tree as the BLT sources. ______________|______________ | | | | blt2.4 tcl8.3.4 tk8.3.4 jpeg-6b 2. Build and install the Tcl and Tk libraries. cd tcl8.3.4\win nmake -f Makefile.vc nmake -f Makefile.vc install cd ..\..\tk8.3.4\win nmake -f Makefile.vc nmake -f Makefile.vc install 3. In the BLT directory, edit .\win\makedefs. Set the following macros. v1 = 8.3 Tcl/Tk version. v2 = 83 Version number without dots. v3 = 8.3.4 Suffix of Tcl/Tk directories prefix = C:/Program\ Files/Tcl Location of installed Tcl/Tk files. TOOLS32 = C:/Program\ Files/Microsoft\ Visual\ Studio/VC90 Location of MS C compiler and tools. HAVE_JPEG = 0 4. Compile BLT. make -f blt.mak 5. Install BLT Since Windows doesn't provide tools to install software, we'll use Tcl/Tk to do it. There's an install script in ./win/install.tcl. Add the location of wish83.exe to your PATH and run wish83.exe. wish83.exe ./win/install.tcl 6. Test BLT cd demos bltwish.exe graph1.tcl Building BLT with Cygwin GCC and mingw (-mno-cygwin) Tcl/Tk libraries. ====================================================================== 1. Install the Tcl/Tk sources. They should reside in the same directory tree as the BLT sources. ______________|______________ | | | | blt2.4 tcl8.3.4 tk8.3.4 jpeg-6b 2. Install the cygwin tool suite. 3. Build and install the Tcl and Tk libraries. cd tcl8.3.4/win ./configure --prefix=/usr/local/tcl8.3.4 make make install cd ../../tk8.3.4/win ./configure --prefix=/usr/local/tcl8.3.4 make make install 3. Compile and install BLT. ./configure --disable-cygwin --prefix=/usr/local/tcl8.3.4 make make install 4. Test BLT Add the location of wish83.exe to your PATH and run bltwish.exe. cd demos bltwish.exe graph1.tcl Building BLT with Cygwin GCC and the cygwin distribution Tcl/Tk libraries. ============================================================= 1. Install the cygwin tool suite. 2. Compile and install BLT. ./configure --with-scriptdir=/usr/share --prefix=/usr make make install 3. Test BLT Add the location of wish83.exe to your PATH and run bltwish.exe. cd demos bltwish.exe graph1.tcl Building BLT with Borland bcc55 and Borland compiled Tcl/Tk libraries. ====================================================================== 1. Install the Tcl/Tk sources. They should reside in the same directory tree as the BLT sources. ______________|______________ | | | | blt2.4 tcl8.3.4 tk8.3.4 jpeg-6b 2. Build and install the Tcl and Tk libraries. cd tcl8.3.4\win make -f Makefile.bc make -f Makefile.bc install cd ..\..\tk8.3.4\win make -f Makefile.bc make -f Makefile.bc install 3. In the BLT directory, edit .\win\makedefs. Set the following macros. v1 = 8.3 Tcl/Tk version. v2 = 83 Version number without dots. v3 = 8.3.4 Suffix of Tcl/Tk directories 4. Edit .\src\Makefile.bc prefix = C:\Program Files\Tcl Location of installed Tcl/Tk files. TOOLS32 = C:\Borland\BCC55\ Location of Borland C compiler and tools. HAVE_JPEG = 0 4. Compile BLT. cd src make -f Makefile.bc 5. Install BLT Since Windows doesn't provide tools to install software, we'll use Tcl/Tk to do it. There's an install script in ./win/install.tcl. Add the location of wish83.exe to your PATH and run wish83.exe. wish83.exe ./win/install.tcl 6. Test BLT cd demos bltwish.exe graph1.tcl ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057630�013411� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/Xutil.h�������������������������������������������������������������������0000644�0001750�0001750�00000047367�11462120063�014704� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: Xutil.h,v 11.73 91/07/30 16:21:37 rws Exp $ */ /*********************************************************** Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ #ifndef _XUTIL_H_ #define _XUTIL_H_ /* You must include <X11/Xlib.h> before including this file */ #ifdef MAC_TCL # define Region XRegion #endif /* * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding * value (x, y, width, height) was found in the parsed string. */ #define NoValue 0x0000 #define XValue 0x0001 #define YValue 0x0002 #define WidthValue 0x0004 #define HeightValue 0x0008 #define AllValues 0x000F #define XNegative 0x0010 #define YNegative 0x0020 /* * new version containing base_width, base_height, and win_gravity fields; * used with WM_NORMAL_HINTS. */ typedef struct { long flags; /* marks which fields in this structure are defined */ int x, y; /* obsolete for new window mgrs, but clients */ int width, height; /* should set so old wm's don't mess up */ int min_width, min_height; int max_width, max_height; int width_inc, height_inc; struct { int x; /* numerator */ int y; /* denominator */ } min_aspect, max_aspect; int base_width, base_height; /* added by ICCCM version 1 */ int win_gravity; /* added by ICCCM version 1 */ } XSizeHints; /* * The next block of definitions are for window manager properties that * clients and applications use for communication. */ /* flags argument in size hints */ #define USPosition (1L << 0) /* user specified x, y */ #define USSize (1L << 1) /* user specified width, height */ #define PPosition (1L << 2) /* program specified position */ #define PSize (1L << 3) /* program specified size */ #define PMinSize (1L << 4) /* program specified minimum size */ #define PMaxSize (1L << 5) /* program specified maximum size */ #define PResizeInc (1L << 6) /* program specified resize increments */ #define PAspect (1L << 7) /* program specified min and max aspect ratios */ #define PBaseSize (1L << 8) /* program specified base for incrementing */ #define PWinGravity (1L << 9) /* program specified window gravity */ /* obsolete */ #define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) typedef struct { long flags; /* marks which fields in this structure are defined */ Bool input; /* does this application rely on the window manager to get keyboard input? */ int initial_state; /* see below */ Pixmap icon_pixmap; /* pixmap to be used as icon */ Window icon_window; /* window to be used as icon */ int icon_x, icon_y; /* initial position of icon */ Pixmap icon_mask; /* icon mask bitmap */ XID window_group; /* id of related window group */ /* this structure may be extended in the future */ } XWMHints; /* definition for flags of XWMHints */ #define InputHint (1L << 0) #define StateHint (1L << 1) #define IconPixmapHint (1L << 2) #define IconWindowHint (1L << 3) #define IconPositionHint (1L << 4) #define IconMaskHint (1L << 5) #define WindowGroupHint (1L << 6) #define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \ IconPositionHint|IconMaskHint|WindowGroupHint) /* definitions for initial window state */ #define WithdrawnState 0 /* for windows that are not mapped */ #define NormalState 1 /* most applications want to start this way */ #define IconicState 3 /* application wants to start as an icon */ /* * Obsolete states no longer defined by ICCCM */ #define DontCareState 0 /* don't know or care */ #define ZoomState 2 /* application wants to start zoomed */ #define InactiveState 4 /* application believes it is seldom used; */ /* some wm's may put it on inactive menu */ /* * new structure for manipulating TEXT properties; used with WM_NAME, * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND. */ typedef struct { unsigned char *value; /* same as Property routines */ Atom encoding; /* prop type */ int format; /* prop data format: 8, 16, or 32 */ unsigned long nitems; /* number of data items in value */ } XTextProperty; #define XNoMemory -1 #define XLocaleNotSupported -2 #define XConverterNotFound -3 typedef enum { XStringStyle, /* STRING */ XCompoundTextStyle, /* COMPOUND_TEXT */ XTextStyle, /* text in owner's encoding (current locale)*/ XStdICCTextStyle /* STRING, else COMPOUND_TEXT */ } XICCEncodingStyle; typedef struct { int min_width, min_height; int max_width, max_height; int width_inc, height_inc; } XIconSize; typedef struct { char *res_name; char *res_class; } XClassHint; /* * These macros are used to give some sugar to the image routines so that * naive people are more comfortable with them. */ #define XDestroyImage(ximage) \ ((*((ximage)->f.destroy_image))((ximage))) #define XGetPixel(ximage, x, y) \ ((*((ximage)->f.get_pixel))((ximage), (x), (y))) #define XPutPixel(ximage, x, y, pixel) \ ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))) #define XSubImage(ximage, x, y, width, height) \ ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height))) #define XAddPixel(ximage, value) \ ((*((ximage)->f.add_pixel))((ximage), (value))) /* * Compose sequence status structure, used in calling XLookupString. */ typedef struct _XComposeStatus { XPointer compose_ptr; /* state table pointer */ int chars_matched; /* match state */ } XComposeStatus; /* * Keysym macros, used on Keysyms to test for classes of symbols */ #define IsKeypadKey(keysym) \ (((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal)) #define IsCursorKey(keysym) \ (((unsigned)(keysym) >= XK_Home) && ((unsigned)(keysym) < XK_Select)) #define IsPFKey(keysym) \ (((unsigned)(keysym) >= XK_KP_F1) && ((unsigned)(keysym) <= XK_KP_F4)) #define IsFunctionKey(keysym) \ (((unsigned)(keysym) >= XK_F1) && ((unsigned)(keysym) <= XK_F35)) #define IsMiscFunctionKey(keysym) \ (((unsigned)(keysym) >= XK_Select) && ((unsigned)(keysym) <= XK_Break)) #define IsModifierKey(keysym) \ ((((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) \ || ((unsigned)(keysym) == XK_Mode_switch) \ || ((unsigned)(keysym) == XK_Num_Lock)) /* * opaque reference to Region data type */ typedef struct _XRegion *Region; /* Return values from XRectInRegion() */ #define RectangleOut 0 #define RectangleIn 1 #define RectanglePart 2 /* * Information used by the visual utility routines to find desired visual * type from the many visuals a display may support. */ typedef struct { Visual *visual; VisualID visualid; int screen; int depth; #if defined(__cplusplus) || defined(c_plusplus) int c_class; /* C++ */ #else int class; #endif unsigned long red_mask; unsigned long green_mask; unsigned long blue_mask; int colormap_size; int bits_per_rgb; } XVisualInfo; #define VisualNoMask 0x0 #define VisualIDMask 0x1 #define VisualScreenMask 0x2 #define VisualDepthMask 0x4 #define VisualClassMask 0x8 #define VisualRedMaskMask 0x10 #define VisualGreenMaskMask 0x20 #define VisualBlueMaskMask 0x40 #define VisualColormapSizeMask 0x80 #define VisualBitsPerRGBMask 0x100 #define VisualAllMask 0x1FF /* * This defines a window manager property that clients may use to * share standard color maps of type RGB_COLOR_MAP: */ typedef struct { Colormap colormap; unsigned long red_max; unsigned long red_mult; unsigned long green_max; unsigned long green_mult; unsigned long blue_max; unsigned long blue_mult; unsigned long base_pixel; VisualID visualid; /* added by ICCCM version 1 */ XID killid; /* added by ICCCM version 1 */ } XStandardColormap; #define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */ /* * return codes for XReadBitmapFile and XWriteBitmapFile */ #define BitmapSuccess 0 #define BitmapOpenFailed 1 #define BitmapFileInvalid 2 #define BitmapNoMemory 3 /**************************************************************** * * Context Management * ****************************************************************/ /* Associative lookup table return codes */ #define XCSUCCESS 0 /* No error. */ #define XCNOMEM 1 /* Out of memory */ #define XCNOENT 2 /* No entry in table */ typedef int XContext; #define XUniqueContext() ((XContext) XrmUniqueQuark()) #define XStringToContext(string) ((XContext) XrmStringToQuark(string)) _XFUNCPROTOBEGIN /* The following declarations are alphabetized. */ extern XClassHint *XAllocClassHint ( #if NeedFunctionPrototypes void #endif ); extern XIconSize *XAllocIconSize ( #if NeedFunctionPrototypes void #endif ); extern XSizeHints *XAllocSizeHints ( #if NeedFunctionPrototypes void #endif ); extern XStandardColormap *XAllocStandardColormap ( #if NeedFunctionPrototypes void #endif ); extern XWMHints *XAllocWMHints ( #if NeedFunctionPrototypes void #endif ); extern void XClipBox( #if NeedFunctionPrototypes Region /* r */, XRectangle* /* rect_return */ #endif ); extern Region XCreateRegion( #if NeedFunctionPrototypes void #endif ); extern char *XDefaultString( #if NeedFunctionPrototypes void #endif ); extern int XDeleteContext( #if NeedFunctionPrototypes Display* /* display */, XID /* rid */, XContext /* context */ #endif ); extern void XDestroyRegion( #if NeedFunctionPrototypes Region /* r */ #endif ); extern void XEmptyRegion( #if NeedFunctionPrototypes Region /* r */ #endif ); extern void XEqualRegion( #if NeedFunctionPrototypes Region /* r1 */, Region /* r2 */ #endif ); extern int XFindContext( #if NeedFunctionPrototypes Display* /* display */, XID /* rid */, XContext /* context */, XPointer* /* data_return */ #endif ); extern Status XGetClassHint( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XClassHint* /* class_hints_return */ #endif ); extern Status XGetIconSizes( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XIconSize** /* size_list_return */, int* /* count_return */ #endif ); extern Status XGetNormalHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints_return */ #endif ); extern Status XGetRGBColormaps( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XStandardColormap** /* stdcmap_return */, int* /* count_return */, Atom /* property */ #endif ); extern Status XGetSizeHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints_return */, Atom /* property */ #endif ); extern Status XGetStandardColormap( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XStandardColormap* /* colormap_return */, Atom /* property */ #endif ); extern Status XGetTextProperty( #if NeedFunctionPrototypes Display* /* display */, Window /* window */, XTextProperty* /* text_prop_return */, Atom /* property */ #endif ); extern Status XGetWMClientMachine( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop_return */ #endif ); extern XWMHints *XGetWMHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */ #endif ); extern Status XGetWMIconName( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop_return */ #endif ); extern Status XGetWMName( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop_return */ #endif ); extern Status XGetWMNormalHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints_return */, long* /* supplied_return */ #endif ); extern Status XGetWMSizeHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints_return */, long* /* supplied_return */, Atom /* property */ #endif ); extern Status XGetZoomHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* zhints_return */ #endif ); extern void XIntersectRegion( #if NeedFunctionPrototypes Region /* sra */, Region /* srb */, Region /* dr_return */ #endif ); extern int XLookupString( #if NeedFunctionPrototypes XKeyEvent* /* event_struct */, char* /* buffer_return */, int /* bytes_buffer */, KeySym* /* keysym_return */, XComposeStatus* /* status_in_out */ #endif ); extern Status XMatchVisualInfo( #if NeedFunctionPrototypes Display* /* display */, int /* screen */, int /* depth */, int /* class */, XVisualInfo* /* vinfo_return */ #endif ); extern void XOffsetRegion( #if NeedFunctionPrototypes Region /* r */, int /* dx */, int /* dy */ #endif ); extern Bool XPointInRegion( #if NeedFunctionPrototypes Region /* r */, int /* x */, int /* y */ #endif ); extern Region XPolygonRegion( #if NeedFunctionPrototypes XPoint* /* points */, int /* n */, int /* fill_rule */ #endif ); extern int XRectInRegion( #if NeedFunctionPrototypes Region /* r */, int /* x */, int /* y */, unsigned int /* width */, unsigned int /* height */ #endif ); extern int XSaveContext( #if NeedFunctionPrototypes Display* /* display */, XID /* rid */, XContext /* context */, _Xconst char* /* data */ #endif ); extern void XSetClassHint( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XClassHint* /* class_hints */ #endif ); extern void XSetIconSizes( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XIconSize* /* size_list */, int /* count */ #endif ); extern void XSetNormalHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints */ #endif ); extern void XSetRGBColormaps( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XStandardColormap* /* stdcmaps */, int /* count */, Atom /* property */ #endif ); extern void XSetSizeHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints */, Atom /* property */ #endif ); extern void XSetStandardProperties( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, _Xconst char* /* window_name */, _Xconst char* /* icon_name */, Pixmap /* icon_pixmap */, char** /* argv */, int /* argc */, XSizeHints* /* hints */ #endif ); extern void XSetTextProperty( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop */, Atom /* property */ #endif ); extern void XSetWMHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XWMHints* /* wm_hints */ #endif ); extern void XSetWMIconName( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop */ #endif ); extern void XSetWMName( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* text_prop */ #endif ); extern void XSetWMNormalHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints */ #endif ); extern void XSetWMProperties( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XTextProperty* /* window_name */, XTextProperty* /* icon_name */, char** /* argv */, int /* argc */, XSizeHints* /* normal_hints */, XWMHints* /* wm_hints */, XClassHint* /* class_hints */ #endif ); extern void XmbSetWMProperties( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, _Xconst char* /* window_name */, _Xconst char* /* icon_name */, char** /* argv */, int /* argc */, XSizeHints* /* normal_hints */, XWMHints* /* wm_hints */, XClassHint* /* class_hints */ #endif ); extern void XSetWMSizeHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* hints */, Atom /* property */ #endif ); extern void XSetRegion( #if NeedFunctionPrototypes Display* /* display */, GC /* gc */, Region /* r */ #endif ); extern void XSetStandardColormap( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XStandardColormap* /* colormap */, Atom /* property */ #endif ); extern void XSetZoomHints( #if NeedFunctionPrototypes Display* /* display */, Window /* w */, XSizeHints* /* zhints */ #endif ); extern void XShrinkRegion( #if NeedFunctionPrototypes Region /* r */, int /* dx */, int /* dy */ #endif ); extern void XSubtractRegion( #if NeedFunctionPrototypes Region /* sra */, Region /* srb */, Region /* dr_return */ #endif ); extern int XmbTextListToTextProperty( #if NeedFunctionPrototypes Display* /* display */, char** /* list */, int /* count */, XICCEncodingStyle /* style */, XTextProperty* /* text_prop_return */ #endif ); extern int XwcTextListToTextProperty( #if NeedFunctionPrototypes Display* /* display */, wchar_t** /* list */, int /* count */, XICCEncodingStyle /* style */, XTextProperty* /* text_prop_return */ #endif ); extern void XwcFreeStringList( #if NeedFunctionPrototypes wchar_t** /* list */ #endif ); extern Status XTextPropertyToStringList( #if NeedFunctionPrototypes XTextProperty* /* text_prop */, char*** /* list_return */, int* /* count_return */ #endif ); extern int XmbTextPropertyToTextList( #if NeedFunctionPrototypes Display* /* display */, XTextProperty* /* text_prop */, char*** /* list_return */, int* /* count_return */ #endif ); extern int XwcTextPropertyToTextList( #if NeedFunctionPrototypes Display* /* display */, XTextProperty* /* text_prop */, wchar_t*** /* list_return */, int* /* count_return */ #endif ); extern void XUnionRectWithRegion( #if NeedFunctionPrototypes XRectangle* /* rectangle */, Region /* src_region */, Region /* dest_region_return */ #endif ); extern void XUnionRegion( #if NeedFunctionPrototypes Region /* sra */, Region /* srb */, Region /* dr_return */ #endif ); extern int XWMGeometry( #if NeedFunctionPrototypes Display* /* display */, int /* screen_number */, _Xconst char* /* user_geometry */, _Xconst char* /* default_geometry */, unsigned int /* border_width */, XSizeHints* /* hints */, int* /* x_return */, int* /* y_return */, int* /* width_return */, int* /* height_return */, int* /* gravity_return */ #endif ); extern void XXorRegion( #if NeedFunctionPrototypes Region /* sra */, Region /* srb */, Region /* dr_return */ #endif ); _XFUNCPROTOEND #ifdef MAC_TCL # undef Region #endif #endif /* _XUTIL_H_ */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/X.h�����������������������������������������������������������������������0000644�0001750�0001750�00000044237�11462120063�013777� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * $XConsortium: X.h,v 1.66 88/09/06 15:55:56 jim Exp $ */ /* Definitions for the X window system likely to be used by applications */ #ifndef X_H #define X_H /*********************************************************** Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ #define X_PROTOCOL 11 /* current protocol version */ #define X_PROTOCOL_REVISION 0 /* current minor version */ #ifdef MAC_TCL # define Cursor XCursor # define Region XRegion #endif /* Resources */ typedef unsigned long XID; typedef XID Window; typedef XID Drawable; typedef XID Font; typedef XID Pixmap; typedef XID Cursor; typedef XID Colormap; typedef XID GContext; typedef XID KeySym; typedef unsigned long Mask; typedef unsigned long Atom; typedef unsigned long VisualID; typedef unsigned long Time; typedef unsigned long KeyCode; /* In order to use IME, the Macintosh needs * to pack 3 bytes into the keyCode field in * the XEvent. In the real X.h, a KeyCode is * defined as a short, which wouldn't be big * enough. */ /***************************************************************** * RESERVED RESOURCE AND CONSTANT DEFINITIONS *****************************************************************/ #define None 0L /* universal null resource or null atom */ #define ParentRelative 1L /* background pixmap in CreateWindow and ChangeWindowAttributes */ #define CopyFromParent 0L /* border pixmap in CreateWindow and ChangeWindowAttributes special VisualID and special window class passed to CreateWindow */ #define PointerWindow 0L /* destination window in SendEvent */ #define InputFocus 1L /* destination window in SendEvent */ #define PointerRoot 1L /* focus window in SetInputFocus */ #define AnyPropertyType 0L /* special Atom, passed to GetProperty */ #define AnyKey 0L /* special Key Code, passed to GrabKey */ #define AnyButton 0L /* special Button Code, passed to GrabButton */ #define AllTemporary 0L /* special Resource ID passed to KillClient */ #define CurrentTime 0L /* special Time */ #define NoSymbol 0L /* special KeySym */ /***************************************************************** * EVENT DEFINITIONS *****************************************************************/ /* Input Event Masks. Used as event-mask window attribute and as arguments to Grab requests. Not to be confused with event names. */ #define NoEventMask 0L #define KeyPressMask (1L<<0) #define KeyReleaseMask (1L<<1) #define ButtonPressMask (1L<<2) #define ButtonReleaseMask (1L<<3) #define EnterWindowMask (1L<<4) #define LeaveWindowMask (1L<<5) #define PointerMotionMask (1L<<6) #define PointerMotionHintMask (1L<<7) #define Button1MotionMask (1L<<8) #define Button2MotionMask (1L<<9) #define Button3MotionMask (1L<<10) #define Button4MotionMask (1L<<11) #define Button5MotionMask (1L<<12) #define ButtonMotionMask (1L<<13) #define KeymapStateMask (1L<<14) #define ExposureMask (1L<<15) #define VisibilityChangeMask (1L<<16) #define StructureNotifyMask (1L<<17) #define ResizeRedirectMask (1L<<18) #define SubstructureNotifyMask (1L<<19) #define SubstructureRedirectMask (1L<<20) #define FocusChangeMask (1L<<21) #define PropertyChangeMask (1L<<22) #define ColormapChangeMask (1L<<23) #define OwnerGrabButtonMask (1L<<24) /* Event names. Used in "type" field in XEvent structures. Not to be confused with event masks above. They start from 2 because 0 and 1 are reserved in the protocol for errors and replies. */ #define KeyPress 2 #define KeyRelease 3 #define ButtonPress 4 #define ButtonRelease 5 #define MotionNotify 6 #define EnterNotify 7 #define LeaveNotify 8 #define FocusIn 9 #define FocusOut 10 #define KeymapNotify 11 #define Expose 12 #define GraphicsExpose 13 #define NoExpose 14 #define VisibilityNotify 15 #define CreateNotify 16 #define DestroyNotify 17 #define UnmapNotify 18 #define MapNotify 19 #define MapRequest 20 #define ReparentNotify 21 #define ConfigureNotify 22 #define ConfigureRequest 23 #define GravityNotify 24 #define ResizeRequest 25 #define CirculateNotify 26 #define CirculateRequest 27 #define PropertyNotify 28 #define SelectionClear 29 #define SelectionRequest 30 #define SelectionNotify 31 #define ColormapNotify 32 #define ClientMessage 33 #define MappingNotify 34 #define LASTEvent 35 /* must be bigger than any event # */ /* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, state in various key-, mouse-, and button-related events. */ #define ShiftMask (1<<0) #define LockMask (1<<1) #define ControlMask (1<<2) #define Mod1Mask (1<<3) #define Mod2Mask (1<<4) #define Mod3Mask (1<<5) #define Mod4Mask (1<<6) #define Mod5Mask (1<<7) /* modifier names. Used to build a SetModifierMapping request or to read a GetModifierMapping request. These correspond to the masks defined above. */ #define ShiftMapIndex 0 #define LockMapIndex 1 #define ControlMapIndex 2 #define Mod1MapIndex 3 #define Mod2MapIndex 4 #define Mod3MapIndex 5 #define Mod4MapIndex 6 #define Mod5MapIndex 7 /* button masks. Used in same manner as Key masks above. Not to be confused with button names below. */ #define Button1Mask (1<<8) #define Button2Mask (1<<9) #define Button3Mask (1<<10) #define Button4Mask (1<<11) #define Button5Mask (1<<12) #define AnyModifier (1<<15) /* used in GrabButton, GrabKey */ /* button names. Used as arguments to GrabButton and as detail in ButtonPress and ButtonRelease events. Not to be confused with button masks above. Note that 0 is already defined above as "AnyButton". */ #define Button1 1 #define Button2 2 #define Button3 3 #define Button4 4 #define Button5 5 /* Notify modes */ #define NotifyNormal 0 #define NotifyGrab 1 #define NotifyUngrab 2 #define NotifyWhileGrabbed 3 #define NotifyHint 1 /* for MotionNotify events */ /* Notify detail */ #define NotifyAncestor 0 #define NotifyVirtual 1 #define NotifyInferior 2 #define NotifyNonlinear 3 #define NotifyNonlinearVirtual 4 #define NotifyPointer 5 #define NotifyPointerRoot 6 #define NotifyDetailNone 7 /* Visibility notify */ #define VisibilityUnobscured 0 #define VisibilityPartiallyObscured 1 #define VisibilityFullyObscured 2 /* Circulation request */ #define PlaceOnTop 0 #define PlaceOnBottom 1 /* protocol families */ #define FamilyInternet 0 #define FamilyDECnet 1 #define FamilyChaos 2 /* Property notification */ #define PropertyNewValue 0 #define PropertyDelete 1 /* Color Map notification */ #define ColormapUninstalled 0 #define ColormapInstalled 1 /* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */ #define GrabModeSync 0 #define GrabModeAsync 1 /* GrabPointer, GrabKeyboard reply status */ #define GrabSuccess 0 #define AlreadyGrabbed 1 #define GrabInvalidTime 2 #define GrabNotViewable 3 #define GrabFrozen 4 /* AllowEvents modes */ #define AsyncPointer 0 #define SyncPointer 1 #define ReplayPointer 2 #define AsyncKeyboard 3 #define SyncKeyboard 4 #define ReplayKeyboard 5 #define AsyncBoth 6 #define SyncBoth 7 /* Used in SetInputFocus, GetInputFocus */ #define RevertToNone (int)None #define RevertToPointerRoot (int)PointerRoot #define RevertToParent 2 /***************************************************************** * ERROR CODES *****************************************************************/ #define Success 0 /* everything's okay */ #define BadRequest 1 /* bad request code */ #define BadValue 2 /* int parameter out of range */ #define BadWindow 3 /* parameter not a Window */ #define BadPixmap 4 /* parameter not a Pixmap */ #define BadAtom 5 /* parameter not an Atom */ #define BadCursor 6 /* parameter not a Cursor */ #define BadFont 7 /* parameter not a Font */ #define BadMatch 8 /* parameter mismatch */ #define BadDrawable 9 /* parameter not a Pixmap or Window */ #define BadAccess 10 /* depending on context: - key/button already grabbed - attempt to free an illegal cmap entry - attempt to store into a read-only color map entry. - attempt to modify the access control list from other than the local host. */ #define BadAlloc 11 /* insufficient resources */ #define BadColor 12 /* no such colormap */ #define BadGC 13 /* parameter not a GC */ #define BadIDChoice 14 /* choice not in range or already used */ #define BadName 15 /* font or color name doesn't exist */ #define BadLength 16 /* Request length incorrect */ #define BadImplementation 17 /* server is defective */ #define FirstExtensionError 128 #define LastExtensionError 255 /***************************************************************** * WINDOW DEFINITIONS *****************************************************************/ /* Window classes used by CreateWindow */ /* Note that CopyFromParent is already defined as 0 above */ #define InputOutput 1 #define InputOnly 2 /* Window attributes for CreateWindow and ChangeWindowAttributes */ #define CWBackPixmap (1L<<0) #define CWBackPixel (1L<<1) #define CWBorderPixmap (1L<<2) #define CWBorderPixel (1L<<3) #define CWBitGravity (1L<<4) #define CWWinGravity (1L<<5) #define CWBackingStore (1L<<6) #define CWBackingPlanes (1L<<7) #define CWBackingPixel (1L<<8) #define CWOverrideRedirect (1L<<9) #define CWSaveUnder (1L<<10) #define CWEventMask (1L<<11) #define CWDontPropagate (1L<<12) #define CWColormap (1L<<13) #define CWCursor (1L<<14) /* ConfigureWindow structure */ #define CWX (1<<0) #define CWY (1<<1) #define CWWidth (1<<2) #define CWHeight (1<<3) #define CWBorderWidth (1<<4) #define CWSibling (1<<5) #define CWStackMode (1<<6) /* Bit Gravity */ #define ForgetGravity 0 #define NorthWestGravity 1 #define NorthGravity 2 #define NorthEastGravity 3 #define WestGravity 4 #define CenterGravity 5 #define EastGravity 6 #define SouthWestGravity 7 #define SouthGravity 8 #define SouthEastGravity 9 #define StaticGravity 10 /* Window gravity + bit gravity above */ #define UnmapGravity 0 /* Used in CreateWindow for backing-store hint */ #define NotUseful 0 #define WhenMapped 1 #define Always 2 /* Used in GetWindowAttributes reply */ #define IsUnmapped 0 #define IsUnviewable 1 #define IsViewable 2 /* Used in ChangeSaveSet */ #define SetModeInsert 0 #define SetModeDelete 1 /* Used in ChangeCloseDownMode */ #define DestroyAll 0 #define RetainPermanent 1 #define RetainTemporary 2 /* Window stacking method (in configureWindow) */ #define Above 0 #define Below 1 #define TopIf 2 #define BottomIf 3 #define Opposite 4 /* Circulation direction */ #define RaiseLowest 0 #define LowerHighest 1 /* Property modes */ #define PropModeReplace 0 #define PropModePrepend 1 #define PropModeAppend 2 /***************************************************************** * GRAPHICS DEFINITIONS *****************************************************************/ /* graphics functions, as in GC.alu */ #define GXclear 0x0 /* 0 */ #define GXand 0x1 /* src AND dst */ #define GXandReverse 0x2 /* src AND NOT dst */ #define GXcopy 0x3 /* src */ #define GXandInverted 0x4 /* NOT src AND dst */ #define GXnoop 0x5 /* dst */ #define GXxor 0x6 /* src XOR dst */ #define GXor 0x7 /* src OR dst */ #define GXnor 0x8 /* NOT src AND NOT dst */ #define GXequiv 0x9 /* NOT src XOR dst */ #define GXinvert 0xa /* NOT dst */ #define GXorReverse 0xb /* src OR NOT dst */ #define GXcopyInverted 0xc /* NOT src */ #define GXorInverted 0xd /* NOT src OR dst */ #define GXnand 0xe /* NOT src OR NOT dst */ #define GXset 0xf /* 1 */ /* LineStyle */ #define LineSolid 0 #define LineOnOffDash 1 #define LineDoubleDash 2 /* capStyle */ #define CapNotLast 0 #define CapButt 1 #define CapRound 2 #define CapProjecting 3 /* joinStyle */ #define JoinMiter 0 #define JoinRound 1 #define JoinBevel 2 /* fillStyle */ #define FillSolid 0 #define FillTiled 1 #define FillStippled 2 #define FillOpaqueStippled 3 /* fillRule */ #define EvenOddRule 0 #define WindingRule 1 /* subwindow mode */ #define ClipByChildren 0 #define IncludeInferiors 1 /* SetClipRectangles ordering */ #define Unsorted 0 #define YSorted 1 #define YXSorted 2 #define YXBanded 3 /* CoordinateMode for drawing routines */ #define CoordModeOrigin 0 /* relative to the origin */ #define CoordModePrevious 1 /* relative to previous point */ /* Polygon shapes */ #define Complex 0 /* paths may intersect */ #define Nonconvex 1 /* no paths intersect, but not convex */ #define Convex 2 /* wholly convex */ /* Arc modes for PolyFillArc */ #define ArcChord 0 /* join endpoints of arc */ #define ArcPieSlice 1 /* join endpoints to center of arc */ /* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into GC.stateChanges */ #define GCFunction (1L<<0) #define GCPlaneMask (1L<<1) #define GCForeground (1L<<2) #define GCBackground (1L<<3) #define GCLineWidth (1L<<4) #define GCLineStyle (1L<<5) #define GCCapStyle (1L<<6) #define GCJoinStyle (1L<<7) #define GCFillStyle (1L<<8) #define GCFillRule (1L<<9) #define GCTile (1L<<10) #define GCStipple (1L<<11) #define GCTileStipXOrigin (1L<<12) #define GCTileStipYOrigin (1L<<13) #define GCFont (1L<<14) #define GCSubwindowMode (1L<<15) #define GCGraphicsExposures (1L<<16) #define GCClipXOrigin (1L<<17) #define GCClipYOrigin (1L<<18) #define GCClipMask (1L<<19) #define GCDashOffset (1L<<20) #define GCDashList (1L<<21) #define GCArcMode (1L<<22) #define GCLastBit 22 /***************************************************************** * FONTS *****************************************************************/ /* used in QueryFont -- draw direction */ #define FontLeftToRight 0 #define FontRightToLeft 1 #define FontChange 255 /***************************************************************** * IMAGING *****************************************************************/ /* ImageFormat -- PutImage, GetImage */ #define XYBitmap 0 /* depth 1, XYFormat */ #define XYPixmap 1 /* depth == drawable depth */ #define ZPixmap 2 /* depth == drawable depth */ /***************************************************************** * COLOR MAP STUFF *****************************************************************/ /* For CreateColormap */ #define AllocNone 0 /* create map with no entries */ #define AllocAll 1 /* allocate entire map writeable */ /* Flags used in StoreNamedColor, StoreColors */ #define DoRed (1<<0) #define DoGreen (1<<1) #define DoBlue (1<<2) /***************************************************************** * CURSOR STUFF *****************************************************************/ /* QueryBestSize Class */ #define CursorShape 0 /* largest size that can be displayed */ #define TileShape 1 /* size tiled fastest */ #define StippleShape 2 /* size stippled fastest */ /***************************************************************** * KEYBOARD/POINTER STUFF *****************************************************************/ #define AutoRepeatModeOff 0 #define AutoRepeatModeOn 1 #define AutoRepeatModeDefault 2 #define LedModeOff 0 #define LedModeOn 1 /* masks for ChangeKeyboardControl */ #define KBKeyClickPercent (1L<<0) #define KBBellPercent (1L<<1) #define KBBellPitch (1L<<2) #define KBBellDuration (1L<<3) #define KBLed (1L<<4) #define KBLedMode (1L<<5) #define KBKey (1L<<6) #define KBAutoRepeatMode (1L<<7) #define MappingSuccess 0 #define MappingBusy 1 #define MappingFailed 2 #define MappingModifier 0 #define MappingKeyboard 1 #define MappingPointer 2 /***************************************************************** * SCREEN SAVER STUFF *****************************************************************/ #define DontPreferBlanking 0 #define PreferBlanking 1 #define DefaultBlanking 2 #define DisableScreenSaver 0 #define DisableScreenInterval 0 #define DontAllowExposures 0 #define AllowExposures 1 #define DefaultExposures 2 /* for ForceScreenSaver */ #define ScreenSaverReset 0 #define ScreenSaverActive 1 /***************************************************************** * HOSTS AND CONNECTIONS *****************************************************************/ /* for ChangeHosts */ #define HostInsert 0 #define HostDelete 1 /* for ChangeAccessControl */ #define EnableAccess 1 #define DisableAccess 0 /* Display classes used in opening the connection * Note that the statically allocated ones are even numbered and the * dynamically changeable ones are odd numbered */ #define StaticGray 0 #define GrayScale 1 #define StaticColor 2 #define PseudoColor 3 #define TrueColor 4 #define DirectColor 5 /* Byte order used in imageByteOrder and bitmapBitOrder */ #define LSBFirst 0 #define MSBFirst 1 #ifdef MAC_TCL # undef Cursor # undef Region #endif #endif /* X_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/Xlib.h��������������������������������������������������������������������0000644�0001750�0001750�00000140435�11462120063�014463� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: Xlib.h,v 11.221 93/07/02 14:13:28 gildea Exp $ */ /* * Copyright 1985, 1986, 1987, 1991 by the Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * X Window System is a Trademark of MIT. * */ /* * Xlib.h - Header definition and support file for the C subroutine * interface library (Xlib) to the X Window System Protocol (V11). * Structures and symbols starting with "_" are private to the library. */ #ifndef _XLIB_H_ #define _XLIB_H_ #define XlibSpecificationRelease 5 #ifdef MAC_TCL # include <X.h> # define Cursor XCursor # define Region XRegion #else # include <X11/X.h> #endif /* applications should not depend on these two headers being included! */ #ifdef MAC_TCL #include <Xfuncproto.h> #else #include <X11/Xfuncproto.h> #endif #ifndef X_WCHAR #ifdef X_NOT_STDC_ENV #define X_WCHAR #endif #endif #ifndef X_WCHAR #include <stddef.h> #else /* replace this with #include or typedef appropriate for your system */ typedef unsigned long wchar_t; #endif typedef char *XPointer; #define Bool int #ifdef MAC_TCL #define Status int #else typedef int Status; #endif #define True 1 #define False 0 #define QueuedAlready 0 #define QueuedAfterReading 1 #define QueuedAfterFlush 2 #define ConnectionNumber(dpy) ((dpy)->fd) #define RootWindow(dpy, scr) (((dpy)->screens[(scr)]).root) #define DefaultScreen(dpy) ((dpy)->default_screen) #define DefaultRootWindow(dpy) (((dpy)->screens[(dpy)->default_screen]).root) #define DefaultVisual(dpy, scr) (((dpy)->screens[(scr)]).root_visual) #define DefaultGC(dpy, scr) (((dpy)->screens[(scr)]).default_gc) #define BlackPixel(dpy, scr) (((dpy)->screens[(scr)]).black_pixel) #define WhitePixel(dpy, scr) (((dpy)->screens[(scr)]).white_pixel) #define AllPlanes ((unsigned long)~0L) #define QLength(dpy) ((dpy)->qlen) #define DisplayWidth(dpy, scr) (((dpy)->screens[(scr)]).width) #define DisplayHeight(dpy, scr) (((dpy)->screens[(scr)]).height) #define DisplayWidthMM(dpy, scr)(((dpy)->screens[(scr)]).mwidth) #define DisplayHeightMM(dpy, scr)(((dpy)->screens[(scr)]).mheight) #define DisplayPlanes(dpy, scr) (((dpy)->screens[(scr)]).root_depth) #define DisplayCells(dpy, scr) (DefaultVisual((dpy), (scr))->map_entries) #define ScreenCount(dpy) ((dpy)->nscreens) #define ServerVendor(dpy) ((dpy)->vendor) #define ProtocolVersion(dpy) ((dpy)->proto_major_version) #define ProtocolRevision(dpy) ((dpy)->proto_minor_version) #define VendorRelease(dpy) ((dpy)->release) #define DisplayString(dpy) ((dpy)->display_name) #define DefaultDepth(dpy, scr) (((dpy)->screens[(scr)]).root_depth) #define DefaultColormap(dpy, scr)(((dpy)->screens[(scr)]).cmap) #define BitmapUnit(dpy) ((dpy)->bitmap_unit) #define BitmapBitOrder(dpy) ((dpy)->bitmap_bit_order) #define BitmapPad(dpy) ((dpy)->bitmap_pad) #define ImageByteOrder(dpy) ((dpy)->byte_order) #define NextRequest(dpy) ((dpy)->request + 1) #define LastKnownRequestProcessed(dpy) ((dpy)->request) /* macros for screen oriented applications (toolkit) */ #define ScreenOfDisplay(dpy, scr)(&((dpy)->screens[(scr)])) #define DefaultScreenOfDisplay(dpy) (&((dpy)->screens[(dpy)->default_screen])) #define DisplayOfScreen(s) ((s)->display) #define RootWindowOfScreen(s) ((s)->root) #define BlackPixelOfScreen(s) ((s)->black_pixel) #define WhitePixelOfScreen(s) ((s)->white_pixel) #define DefaultColormapOfScreen(s)((s)->cmap) #define DefaultDepthOfScreen(s) ((s)->root_depth) #define DefaultGCOfScreen(s) ((s)->default_gc) #define DefaultVisualOfScreen(s)((s)->root_visual) #define WidthOfScreen(s) ((s)->width) #define HeightOfScreen(s) ((s)->height) #define WidthMMOfScreen(s) ((s)->mwidth) #define HeightMMOfScreen(s) ((s)->mheight) #define PlanesOfScreen(s) ((s)->root_depth) #define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries) #define MinCmapsOfScreen(s) ((s)->min_maps) #define MaxCmapsOfScreen(s) ((s)->max_maps) #define DoesSaveUnders(s) ((s)->save_unders) #define DoesBackingStore(s) ((s)->backing_store) #define EventMaskOfScreen(s) ((s)->root_input_mask) /* * Extensions need a way to hang private data on some structures. */ typedef struct _XExtData { int number; /* number returned by XRegisterExtension */ struct _XExtData *next; /* next item on list of data for structure */ int (*free_private)(); /* called to free private storage */ XPointer private_data; /* data private to this extension. */ } XExtData; /* * This file contains structures used by the extension mechanism. */ typedef struct { /* public to extension, cannot be changed */ int extension; /* extension number */ int major_opcode; /* major op-code assigned by server */ int first_event; /* first event number for the extension */ int first_error; /* first error number for the extension */ } XExtCodes; /* * Data structure for retrieving info about pixmap formats. */ typedef struct { int depth; int bits_per_pixel; int scanline_pad; } XPixmapFormatValues; /* * Data structure for setting graphics context. */ typedef struct { int function; /* logical operation */ unsigned long plane_mask;/* plane mask */ unsigned long foreground;/* foreground pixel */ unsigned long background;/* background pixel */ int line_width; /* line width */ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ int join_style; /* JoinMiter, JoinRound, JoinBevel */ int fill_style; /* FillSolid, FillTiled, FillStippled, FillOpaeueStippled */ int fill_rule; /* EvenOddRule, WindingRule */ int arc_mode; /* ArcChord, ArcPieSlice */ Pixmap tile; /* tile pixmap for tiling operations */ Pixmap stipple; /* stipple 1 plane pixmap for stipping */ int ts_x_origin; /* offset for tile or stipple operations */ int ts_y_origin; Font font; /* default text font for text operations */ int subwindow_mode; /* ClipByChildren, IncludeInferiors */ Bool graphics_exposures;/* boolean, should exposures be generated */ int clip_x_origin; /* origin for clipping */ int clip_y_origin; Pixmap clip_mask; /* bitmap clipping; other calls for rects */ int dash_offset; /* patterned/dashed line information */ char dashes; } XGCValues; /* * Graphics context. The contents of this structure are implementation * dependent. A GC should be treated as opaque by application code. */ typedef XGCValues *GC; /* * Visual structure; contains information about colormapping possible. */ typedef struct { XExtData *ext_data; /* hook for extension to hang data */ VisualID visualid; /* visual id of this visual */ #if defined(__cplusplus) || defined(c_plusplus) int c_class; /* C++ class of screen (monochrome, etc.) */ #else int class; /* class of screen (monochrome, etc.) */ #endif unsigned long red_mask, green_mask, blue_mask; /* mask values */ int bits_per_rgb; /* log base 2 of distinct color values */ int map_entries; /* color map entries */ } Visual; /* * Depth structure; contains information for each possible depth. */ typedef struct { int depth; /* this depth (Z) of the depth */ int nvisuals; /* number of Visual types at this depth */ Visual *visuals; /* list of visuals possible at this depth */ } Depth; /* * Information about the screen. The contents of this structure are * implementation dependent. A Screen should be treated as opaque * by application code. */ typedef struct { XExtData *ext_data; /* hook for extension to hang data */ struct _XDisplay *display;/* back pointer to display structure */ Window root; /* Root window id. */ int width, height; /* width and height of screen */ int mwidth, mheight; /* width and height of in millimeters */ int ndepths; /* number of depths possible */ Depth *depths; /* list of allowable depths on the screen */ int root_depth; /* bits per pixel */ Visual *root_visual; /* root visual */ GC default_gc; /* GC for the root root visual */ Colormap cmap; /* default color map */ unsigned long white_pixel; unsigned long black_pixel; /* White and Black pixel values */ int max_maps, min_maps; /* max and min color maps */ int backing_store; /* Never, WhenMapped, Always */ Bool save_unders; long root_input_mask; /* initial root input mask */ } Screen; /* * Format structure; describes ZFormat data the screen will understand. */ typedef struct { XExtData *ext_data; /* hook for extension to hang data */ int depth; /* depth of this image format */ int bits_per_pixel; /* bits/pixel at this depth */ int scanline_pad; /* scanline must padded to this multiple */ } ScreenFormat; /* * Data structure for setting window attributes. */ typedef struct { Pixmap background_pixmap; /* background or None or ParentRelative */ unsigned long background_pixel; /* background pixel */ Pixmap border_pixmap; /* border of the window */ unsigned long border_pixel; /* border pixel value */ int bit_gravity; /* one of bit gravity values */ int win_gravity; /* one of the window gravity values */ int backing_store; /* NotUseful, WhenMapped, Always */ unsigned long backing_planes;/* planes to be preseved if possible */ unsigned long backing_pixel;/* value to use in restoring planes */ Bool save_under; /* should bits under be saved? (popups) */ long event_mask; /* set of events that should be saved */ long do_not_propagate_mask; /* set of events that should not propagate */ Bool override_redirect; /* boolean value for override-redirect */ Colormap colormap; /* color map to be associated with window */ Cursor cursor; /* cursor to be displayed (or None) */ } XSetWindowAttributes; typedef struct { int x, y; /* location of window */ int width, height; /* width and height of window */ int border_width; /* border width of window */ int depth; /* depth of window */ Visual *visual; /* the associated visual structure */ Window root; /* root of screen containing window */ #if defined(__cplusplus) || defined(c_plusplus) int c_class; /* C++ InputOutput, InputOnly*/ #else int class; /* InputOutput, InputOnly*/ #endif int bit_gravity; /* one of bit gravity values */ int win_gravity; /* one of the window gravity values */ int backing_store; /* NotUseful, WhenMapped, Always */ unsigned long backing_planes;/* planes to be preserved if possible */ unsigned long backing_pixel;/* value to be used when restoring planes */ Bool save_under; /* boolean, should bits under be saved? */ Colormap colormap; /* color map to be associated with window */ Bool map_installed; /* boolean, is color map currently installed*/ int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ long all_event_masks; /* set of events all people have interest in*/ long your_event_mask; /* my event mask */ long do_not_propagate_mask; /* set of events that should not propagate */ Bool override_redirect; /* boolean value for override-redirect */ Screen *screen; /* back pointer to correct screen */ } XWindowAttributes; /* * Data structure for host setting; getting routines. * */ typedef struct { int family; /* for example FamilyInternet */ int length; /* length of address, in bytes */ char *address; /* pointer to where to find the bytes */ } XHostAddress; /* * Data structure for "image" data, used by image manipulation routines. */ typedef struct _XImage { int width, height; /* size of image */ int xoffset; /* number of pixels offset in X direction */ int format; /* XYBitmap, XYPixmap, ZPixmap */ char *data; /* pointer to image data */ int byte_order; /* data byte order, LSBFirst, MSBFirst */ int bitmap_unit; /* quant. of scanline 8, 16, 32 */ int bitmap_bit_order; /* LSBFirst, MSBFirst */ int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ int depth; /* depth of image */ int bytes_per_line; /* accelarator to next line */ int bits_per_pixel; /* bits per pixel (ZPixmap) */ unsigned long red_mask; /* bits in z arrangment */ unsigned long green_mask; unsigned long blue_mask; XPointer obdata; /* hook for the object routines to hang on */ struct funcs { /* image manipulation routines */ struct _XImage *(*create_image)(); #if NeedFunctionPrototypes int (*destroy_image) (struct _XImage *); unsigned long (*get_pixel) (struct _XImage *, int, int); int (*put_pixel) (struct _XImage *, int, int, unsigned long); struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); int (*add_pixel) (struct _XImage *, long); #else int (*destroy_image)(); unsigned long (*get_pixel)(); int (*put_pixel)(); struct _XImage *(*sub_image)(); int (*add_pixel)(); #endif } f; } XImage; /* * Data structure for XReconfigureWindow */ typedef struct { int x, y; int width, height; int border_width; Window sibling; int stack_mode; } XWindowChanges; /* * Data structure used by color operations */ typedef struct { unsigned long pixel; unsigned short red, green, blue; char flags; /* do_red, do_green, do_blue */ char pad; } XColor; /* * Data structures for graphics operations. On most machines, these are * congruent with the wire protocol structures, so reformatting the data * can be avoided on these architectures. */ typedef struct { short x1, y1, x2, y2; } XSegment; typedef struct { short x, y; } XPoint; typedef struct { short x, y; unsigned short width, height; } XRectangle; typedef struct { short x, y; unsigned short width, height; short angle1, angle2; } XArc; /* Data structure for XChangeKeyboardControl */ typedef struct { int key_click_percent; int bell_percent; int bell_pitch; int bell_duration; int led; int led_mode; int key; int auto_repeat_mode; /* On, Off, Default */ } XKeyboardControl; /* Data structure for XGetKeyboardControl */ typedef struct { int key_click_percent; int bell_percent; unsigned int bell_pitch, bell_duration; unsigned long led_mask; int global_auto_repeat; char auto_repeats[32]; } XKeyboardState; /* Data structure for XGetMotionEvents. */ typedef struct { Time time; short x, y; } XTimeCoord; /* Data structure for X{Set,Get}ModifierMapping */ typedef struct { int max_keypermod; /* The server's max # of keys per modifier */ KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */ } XModifierKeymap; /* * Display datatype maintaining display specific data. * The contents of this structure are implementation dependent. * A Display should be treated as opaque by application code. */ typedef struct _XDisplay { XExtData *ext_data; /* hook for extension to hang data */ struct _XFreeFuncs *free_funcs; /* internal free functions */ int fd; /* Network socket. */ int conn_checker; /* ugly thing used by _XEventsQueued */ int proto_major_version;/* maj. version of server's X protocol */ int proto_minor_version;/* minor version of servers X protocol */ char *vendor; /* vendor of the server hardware */ XID resource_base; /* resource ID base */ XID resource_mask; /* resource ID mask bits */ XID resource_id; /* allocator current ID */ int resource_shift; /* allocator shift to correct bits */ XID (*resource_alloc)(); /* allocator function */ int byte_order; /* screen byte order, LSBFirst, MSBFirst */ int bitmap_unit; /* padding and data requirements */ int bitmap_pad; /* padding requirements on bitmaps */ int bitmap_bit_order; /* LeastSignificant or MostSignificant */ int nformats; /* number of pixmap formats in list */ ScreenFormat *pixmap_format; /* pixmap format list */ int vnumber; /* Xlib's X protocol version number. */ int release; /* release of the server */ struct _XSQEvent *head, *tail; /* Input event queue. */ int qlen; /* Length of input event queue */ unsigned long request; /* sequence number of last request. */ char *last_req; /* beginning of last request, or dummy */ char *buffer; /* Output buffer starting address. */ char *bufptr; /* Output buffer index pointer. */ char *bufmax; /* Output buffer maximum+1 address. */ unsigned max_request_size; /* maximum number 32 bit words in request*/ struct _XrmHashBucketRec *db; int (*synchandler)(); /* Synchronization handler */ char *display_name; /* "host:display" string used on this connect*/ int default_screen; /* default screen for operations */ int nscreens; /* number of screens on this server*/ Screen *screens; /* pointer to list of screens */ unsigned long motion_buffer; /* size of motion buffer */ unsigned long flags; /* internal connection flags */ int min_keycode; /* minimum defined keycode */ int max_keycode; /* maximum defined keycode */ KeySym *keysyms; /* This server's keysyms */ XModifierKeymap *modifiermap; /* This server's modifier keymap */ int keysyms_per_keycode;/* number of rows */ char *xdefaults; /* contents of defaults from server */ char *scratch_buffer; /* place to hang scratch buffer */ unsigned long scratch_length; /* length of scratch buffer */ int ext_number; /* extension number on this display */ struct _XExten *ext_procs; /* extensions initialized on this display */ /* * the following can be fixed size, as the protocol defines how * much address space is available. * While this could be done using the extension vector, there * may be MANY events processed, so a search through the extension * list to find the right procedure for each event might be * expensive if many extensions are being used. */ Bool (*event_vec[128])(); /* vector for wire to event */ Status (*wire_vec[128])(); /* vector for event to wire */ KeySym lock_meaning; /* for XLookupString */ struct _XLockInfo *lock; /* multi-thread state, display lock */ struct _XInternalAsync *async_handlers; /* for internal async */ unsigned long bigreq_size; /* max size of big requests */ struct _XLockPtrs *lock_fns; /* pointers to threads functions */ /* things above this line should not move, for binary compatibility */ struct _XKeytrans *key_bindings; /* for XLookupString */ Font cursor_font; /* for XCreateFontCursor */ struct _XDisplayAtoms *atoms; /* for XInternAtom */ unsigned int mode_switch; /* keyboard group modifiers */ struct _XContextDB *context_db; /* context database */ Bool (**error_vec)(); /* vector for wire to error */ /* * Xcms information */ struct { XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ XPointer perVisualIntensityMaps; /* linked list of XcmsIntensityMap */ } cms; struct _XIMFilter *im_filters; struct _XSQEvent *qfree; /* unallocated event queue elements */ unsigned long next_event_serial_num; /* inserted into next queue elt */ int (*savedsynchandler)(); /* user synchandler when Xlib usurps */ } Display; #if NeedFunctionPrototypes /* prototypes require event type definitions */ #undef _XEVENT_ #endif #ifndef _XEVENT_ #define XMaxTransChars 4 /* * Definitions of specific events. */ typedef struct { int type; /* of event */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* "event" window it is reported relative to */ Window root; /* root window that the event occured on */ Window subwindow; /* child window */ Time time; /* milliseconds */ int x, y; /* pointer x, y coordinates in event window */ int x_root, y_root; /* coordinates relative to root */ unsigned int state; /* key or button mask */ unsigned int keycode; /* detail */ Bool same_screen; /* same screen flag */ char trans_chars[XMaxTransChars]; /* translated characters */ int nbytes; } XKeyEvent; typedef XKeyEvent XKeyPressedEvent; typedef XKeyEvent XKeyReleasedEvent; typedef struct { int type; /* of event */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* "event" window it is reported relative to */ Window root; /* root window that the event occured on */ Window subwindow; /* child window */ Time time; /* milliseconds */ int x, y; /* pointer x, y coordinates in event window */ int x_root, y_root; /* coordinates relative to root */ unsigned int state; /* key or button mask */ unsigned int button; /* detail */ Bool same_screen; /* same screen flag */ } XButtonEvent; typedef XButtonEvent XButtonPressedEvent; typedef XButtonEvent XButtonReleasedEvent; typedef struct { int type; /* of event */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* "event" window reported relative to */ Window root; /* root window that the event occured on */ Window subwindow; /* child window */ Time time; /* milliseconds */ int x, y; /* pointer x, y coordinates in event window */ int x_root, y_root; /* coordinates relative to root */ unsigned int state; /* key or button mask */ char is_hint; /* detail */ Bool same_screen; /* same screen flag */ } XMotionEvent; typedef XMotionEvent XPointerMovedEvent; typedef struct { int type; /* of event */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* "event" window reported relative to */ Window root; /* root window that the event occured on */ Window subwindow; /* child window */ Time time; /* milliseconds */ int x, y; /* pointer x, y coordinates in event window */ int x_root, y_root; /* coordinates relative to root */ int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ int detail; /* * NotifyAncestor, NotifyVirtual, NotifyInferior, * NotifyNonlinear,NotifyNonlinearVirtual */ Bool same_screen; /* same screen flag */ Bool focus; /* boolean focus */ unsigned int state; /* key or button mask */ } XCrossingEvent; typedef XCrossingEvent XEnterWindowEvent; typedef XCrossingEvent XLeaveWindowEvent; typedef struct { int type; /* FocusIn or FocusOut */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* window of event */ int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ int detail; /* * NotifyAncestor, NotifyVirtual, NotifyInferior, * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, * NotifyPointerRoot, NotifyDetailNone */ } XFocusChangeEvent; typedef XFocusChangeEvent XFocusInEvent; typedef XFocusChangeEvent XFocusOutEvent; /* generated on EnterWindow and FocusIn when KeyMapState selected */ typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; char key_vector[32]; } XKeymapEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; int x, y; int width, height; int count; /* if non-zero, at least this many more */ } XExposeEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Drawable drawable; int x, y; int width, height; int count; /* if non-zero, at least this many more */ int major_code; /* core is CopyArea or CopyPlane */ int minor_code; /* not defined in the core */ } XGraphicsExposeEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Drawable drawable; int major_code; /* core is CopyArea or CopyPlane */ int minor_code; /* not defined in the core */ } XNoExposeEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; int state; /* Visibility state */ } XVisibilityEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window parent; /* parent of the window */ Window window; /* window id of window created */ int x, y; /* window location */ int width, height; /* size of window */ int border_width; /* border width */ Bool override_redirect; /* creation should be overridden */ } XCreateWindowEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; } XDestroyWindowEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; Bool from_configure; } XUnmapEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; Bool override_redirect; /* boolean, is override set... */ } XMapEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window parent; Window window; } XMapRequestEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; Window parent; int x, y; Bool override_redirect; } XReparentEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; int x, y; int width, height; int border_width; Window above; Bool override_redirect; } XConfigureEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; int x, y; } XGravityEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; int width, height; } XResizeRequestEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window parent; Window window; int x, y; int width, height; int border_width; Window above; int detail; /* Above, Below, TopIf, BottomIf, Opposite */ unsigned long value_mask; } XConfigureRequestEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window event; Window window; int place; /* PlaceOnTop, PlaceOnBottom */ } XCirculateEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window parent; Window window; int place; /* PlaceOnTop, PlaceOnBottom */ } XCirculateRequestEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; Atom atom; Time time; int state; /* NewValue, Deleted */ } XPropertyEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; Atom selection; Time time; } XSelectionClearEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window owner; Window requestor; Atom selection; Atom target; Atom property; Time time; } XSelectionRequestEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window requestor; Atom selection; Atom target; Atom property; /* ATOM or None */ Time time; } XSelectionEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; Colormap colormap; /* COLORMAP or None */ #if defined(__cplusplus) || defined(c_plusplus) Bool c_new; /* C++ */ #else Bool new; #endif int state; /* ColormapInstalled, ColormapUninstalled */ } XColormapEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; Atom message_type; int format; union { char b[20]; short s[10]; long l[5]; } data; } XClientMessageEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* unused */ int request; /* one of MappingModifier, MappingKeyboard, MappingPointer */ int first_keycode; /* first keycode */ int count; /* defines range of change w. first_keycode*/ } XMappingEvent; typedef struct { int type; Display *display; /* Display the event was read from */ XID resourceid; /* resource id */ unsigned long serial; /* serial number of failed request */ unsigned char error_code; /* error code of failed request */ unsigned char request_code; /* Major op-code of failed request */ unsigned char minor_code; /* Minor op-code of failed request */ } XErrorEvent; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came from a SendEvent request */ Display *display;/* Display the event was read from */ Window window; /* window on which event was requested in event mask */ } XAnyEvent; /* * this union is defined so Xlib can always use the same sized * event structure internally, to avoid memory fragmentation. */ typedef union _XEvent { int type; /* must not be changed; first element */ XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton; XMotionEvent xmotion; XCrossingEvent xcrossing; XFocusChangeEvent xfocus; XExposeEvent xexpose; XGraphicsExposeEvent xgraphicsexpose; XNoExposeEvent xnoexpose; XVisibilityEvent xvisibility; XCreateWindowEvent xcreatewindow; XDestroyWindowEvent xdestroywindow; XUnmapEvent xunmap; XMapEvent xmap; XMapRequestEvent xmaprequest; XReparentEvent xreparent; XConfigureEvent xconfigure; XGravityEvent xgravity; XResizeRequestEvent xresizerequest; XConfigureRequestEvent xconfigurerequest; XCirculateEvent xcirculate; XCirculateRequestEvent xcirculaterequest; XPropertyEvent xproperty; XSelectionClearEvent xselectionclear; XSelectionRequestEvent xselectionrequest; XSelectionEvent xselection; XColormapEvent xcolormap; XClientMessageEvent xclient; XMappingEvent xmapping; XErrorEvent xerror; XKeymapEvent xkeymap; long pad[24]; } XEvent; #endif #define XAllocID(dpy) ((*(dpy)->resource_alloc)((dpy))) /* * per character font metric information. */ typedef struct { short lbearing; /* origin to left edge of raster */ short rbearing; /* origin to right edge of raster */ short width; /* advance to next char's origin */ short ascent; /* baseline to top edge of raster */ short descent; /* baseline to bottom edge of raster */ unsigned short attributes; /* per char flags (not predefined) */ } XCharStruct; /* * To allow arbitrary information with fonts, there are additional properties * returned. */ typedef struct { Atom name; unsigned long card32; } XFontProp; typedef struct { XExtData *ext_data; /* hook for extension to hang data */ Font fid; /* Font id for this font */ unsigned direction; /* hint about direction the font is painted */ unsigned min_char_or_byte2;/* first character */ unsigned max_char_or_byte2;/* last character */ unsigned min_byte1; /* first row that exists */ unsigned max_byte1; /* last row that exists */ Bool all_chars_exist;/* flag if all characters have non-zero size*/ unsigned default_char; /* char to print for undefined character */ int n_properties; /* how many properties there are */ XFontProp *properties; /* pointer to array of additional properties*/ XCharStruct min_bounds; /* minimum bounds over all existing char*/ XCharStruct max_bounds; /* maximum bounds over all existing char*/ XCharStruct *per_char; /* first_char to last_char information */ int ascent; /* log. extent above baseline for spacing */ int descent; /* log. descent below baseline for spacing */ } XFontStruct; /* * PolyText routines take these as arguments. */ typedef struct { char *chars; /* pointer to string */ int nchars; /* number of characters */ int delta; /* delta between strings */ Font font; /* font to print it in, None don't change */ } XTextItem; typedef struct { /* normal 16 bit characters are two bytes */ unsigned char byte1; unsigned char byte2; } XChar2b; typedef struct { XChar2b *chars; /* two byte characters */ int nchars; /* number of characters */ int delta; /* delta between strings */ Font font; /* font to print it in, None don't change */ } XTextItem16; typedef union { Display *display; GC gc; Visual *visual; Screen *screen; ScreenFormat *pixmap_format; XFontStruct *font; } XEDataObject; typedef struct { XRectangle max_ink_extent; XRectangle max_logical_extent; } XFontSetExtents; typedef struct _XFontSet *XFontSet; typedef struct { char *chars; int nchars; int delta; XFontSet font_set; } XmbTextItem; typedef struct { wchar_t *chars; int nchars; int delta; XFontSet font_set; } XwcTextItem; typedef void (*XIMProc)(); typedef struct _XIM *XIM; typedef struct _XIC *XIC; typedef unsigned long XIMStyle; typedef struct { unsigned short count_styles; XIMStyle *supported_styles; } XIMStyles; #define XIMPreeditArea 0x0001L #define XIMPreeditCallbacks 0x0002L #define XIMPreeditPosition 0x0004L #define XIMPreeditNothing 0x0008L #define XIMPreeditNone 0x0010L #define XIMStatusArea 0x0100L #define XIMStatusCallbacks 0x0200L #define XIMStatusNothing 0x0400L #define XIMStatusNone 0x0800L #define XNVaNestedList "XNVaNestedList" #define XNClientWindow "clientWindow" #define XNInputStyle "inputStyle" #define XNFocusWindow "focusWindow" #define XNResourceName "resourceName" #define XNResourceClass "resourceClass" #define XNGeometryCallback "geometryCallback" #define XNFilterEvents "filterEvents" #define XNPreeditStartCallback "preeditStartCallback" #define XNPreeditDoneCallback "preeditDoneCallback" #define XNPreeditDrawCallback "preeditDrawCallback" #define XNPreeditCaretCallback "preeditCaretCallback" #define XNPreeditAttributes "preeditAttributes" #define XNStatusStartCallback "statusStartCallback" #define XNStatusDoneCallback "statusDoneCallback" #define XNStatusDrawCallback "statusDrawCallback" #define XNStatusAttributes "statusAttributes" #define XNArea "area" #define XNAreaNeeded "areaNeeded" #define XNSpotLocation "spotLocation" #define XNColormap "colorMap" #define XNStdColormap "stdColorMap" #define XNForeground "foreground" #define XNBackground "background" #define XNBackgroundPixmap "backgroundPixmap" #define XNFontSet "fontSet" #define XNLineSpace "lineSpace" #define XNCursor "cursor" #define XBufferOverflow -1 #define XLookupNone 1 #define XLookupChars 2 #define XLookupKeySym 3 #define XLookupBoth 4 #if NeedFunctionPrototypes typedef void *XVaNestedList; #else typedef XPointer XVaNestedList; #endif typedef struct { XPointer client_data; XIMProc callback; } XIMCallback; typedef unsigned long XIMFeedback; #define XIMReverse 1 #define XIMUnderline (1<<1) #define XIMHighlight (1<<2) #define XIMPrimary (1<<5) #define XIMSecondary (1<<6) #define XIMTertiary (1<<7) typedef struct _XIMText { unsigned short length; XIMFeedback *feedback; Bool encoding_is_wchar; union { char *multi_byte; wchar_t *wide_char; } string; } XIMText; typedef struct _XIMPreeditDrawCallbackStruct { int caret; /* Cursor offset within pre-edit string */ int chg_first; /* Starting change position */ int chg_length; /* Length of the change in character count */ XIMText *text; } XIMPreeditDrawCallbackStruct; typedef enum { XIMForwardChar, XIMBackwardChar, XIMForwardWord, XIMBackwardWord, XIMCaretUp, XIMCaretDown, XIMNextLine, XIMPreviousLine, XIMLineStart, XIMLineEnd, XIMAbsolutePosition, XIMDontChange } XIMCaretDirection; typedef enum { XIMIsInvisible, /* Disable caret feedback */ XIMIsPrimary, /* UI defined caret feedback */ XIMIsSecondary /* UI defined caret feedback */ } XIMCaretStyle; typedef struct _XIMPreeditCaretCallbackStruct { int position; /* Caret offset within pre-edit string */ XIMCaretDirection direction; /* Caret moves direction */ XIMCaretStyle style; /* Feedback of the caret */ } XIMPreeditCaretCallbackStruct; typedef enum { XIMTextType, XIMBitmapType } XIMStatusDataType; typedef struct _XIMStatusDrawCallbackStruct { XIMStatusDataType type; union { XIMText *text; Pixmap bitmap; } data; } XIMStatusDrawCallbackStruct; typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */ #if NeedFunctionPrototypes Display* /* display */, XErrorEvent* /* error_event */ #endif ); _XFUNCPROTOBEGIN #include "X11/Xutil.h" extern void XSetDashes(Display * display, GC gc, int dash_offset, _Xconst char* dash_list, int n); extern XModifierKeymap *XGetModifierMapping(Display *display); extern XImage *XCreateImage(Display *display, Visual *visual, unsigned int ui1, int i1, int i2, char* cp, unsigned int ui2, unsigned int ui3, int i3, int i4); extern XImage *XGetImage(Display* display,Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); extern char *XGetAtomName(Display *d, Atom a); extern char *XKeysymToString(KeySym k); extern Colormap XCreateColormap(Display *d, Window w, Visual* v, int i); extern Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2, XColor* x1, XColor* x2, unsigned int ui1, unsigned int ui2); extern Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor* x1, XColor* x2); extern GContext XGContextFromGC(GC g); extern XHostAddress *XListHosts(Display *d, int* i, Bool* b); extern KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i); extern KeySym XStringToKeysym(_Xconst char* c); extern Window XRootWindow(Display *d, int i); extern XErrorHandler XSetErrorHandler(XErrorHandler x); extern Status XIconifyWindow(Display *d, Window w, int i); extern Status XWithdrawWindow(Display *d, Window w, int i); extern Status XGetWMColormapWindows(Display *d, Window w, Window** wpp, int* ip); extern Status XAllocColor(Display *d, Colormap c, XColor* xp); extern void XBell(Display *d, int i); extern void XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char* c, int i3); extern void XChangeWindowAttributes(Display *d, Window w, unsigned long ul, XSetWindowAttributes* x); extern void XClearWindow(Display *d, Window w); extern void XConfigureWindow(Display *d, Window w, unsigned int i, XWindowChanges* x); extern void XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); extern void XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4, unsigned long ul); extern Pixmap XCreateBitmapFromData(Display *display, Drawable d, _Xconst char* data, unsigned int width, unsigned int height); extern void XDefineCursor(Display *d, Window w, Cursor c); extern void XDeleteProperty(Display *d, Window w, Atom a); extern void XDestroyWindow(Display *d, Window w); extern void XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); extern void XDrawLines(Display *d, Drawable dr, GC g, XPoint* x, int i1, int i2); extern void XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); extern void XFillArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); extern void XFillPolygon(Display *d, Drawable dr, GC g, XPoint* x, int i1, int i2, int i3); extern void XFillRectangles(Display *d, Drawable dr, GC g, XRectangle* x, int i); extern void XForceScreenSaver(Display *d, int i); extern void XFreeColormap(Display *d, Colormap c); extern void XFreeColors(Display *d, Colormap c, unsigned long* ulp, int i, unsigned long ul); extern void XFreeCursor(Display *d, Cursor c); extern void XFreeModifiermap(XModifierKeymap* x); extern Status XGetGeometry(Display *d, Drawable dr, Window* w, int* i1, int* i2, unsigned int* ui1, unsigned int* ui2, unsigned int* ui3, unsigned int* ui4); extern void XGetInputFocus(Display *d, Window* w, int* i); extern int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2, Bool b, Atom a2, Atom* ap, int* ip, unsigned long* ulp1, unsigned long* ulp2, unsigned char** cpp); extern Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes* x); extern int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t); extern int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); extern KeyCode XKeysymToKeycode(Display *d, KeySym k); extern Status XLookupColor(Display *d, Colormap c1, _Xconst char* c2, XColor* x1, XColor* x2); extern void XMapWindow(Display *d, Window w); extern void XMoveResizeWindow(Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); extern void XMoveWindow(Display *d, Window w, int i1, int i2); extern void XNextEvent(Display *d, XEvent* x); extern void XPutBackEvent(Display *d, XEvent* x); extern void XQueryColors(Display *d, Colormap c, XColor* x, int i); extern Bool XQueryPointer(Display *d, Window w1, Window* w2, Window* w3, int* i1, int* i2, int* i3, int* i4, unsigned int* ui); extern Status XQueryTree(Display *d, Window w1, Window* w2, Window* w3, Window** w4, unsigned int* ui); extern void XRaiseWindow(Display *d, Window w); extern void XRefreshKeyboardMapping(XMappingEvent* x); extern void XResizeWindow(Display *d, Window w, unsigned int ui1, unsigned int ui2); extern void XSelectInput(Display *d, Window w, long l); extern Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent* x); extern void XSetCommand(Display *d, Window w, CONST char** c, int i); extern void XSetIconName(Display *d, Window w, _Xconst char* c); extern void XSetInputFocus(Display *d, Window w, int i, Time t); extern void XSetSelectionOwner(Display *d, Atom a, Window w, Time t); extern void XSetWindowBackground(Display *d, Window w, unsigned long ul); extern void XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p); extern void XSetWindowBorder(Display *d, Window w, unsigned long ul); extern void XSetWindowBorderPixmap(Display *d, Window w, Pixmap p); extern void XSetWindowBorderWidth(Display *d, Window w, unsigned int ui); extern void XSetWindowColormap(Display *d, Window w, Colormap c); extern Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1, int i2, int* i3, int* i4, Window* w3); extern void XUngrabKeyboard(Display *d, Time t); extern void XUngrabPointer(Display *d, Time t); extern void XUnmapWindow(Display *d, Window w); extern void XWindowEvent(Display *d, Window w, long l, XEvent* x); extern void XDestroyIC(XIC x); extern Bool XFilterEvent(XEvent* x, Window w); extern int XmbLookupString(XIC xi, XKeyPressedEvent* xk, char* c, int i, KeySym* k, Status* s); extern void TkPutImage(unsigned long * colors, int ncolors, Display *display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); extern Status XParseColor(Display * display, Colormap map, _Xconst char* spec, XColor * colorPtr); extern GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues* values); extern void XFreeGC(Display *display, GC gc); extern Atom XInternAtom(Display *display, _Xconst char* atom_name, Bool only_if_exists); extern void XSetBackground(Display *display, GC gc, unsigned long foreground); extern void XSetForeground(Display *display, GC gc, unsigned long foreground); extern void XSetClipMask(Display *display, GC gc, Pixmap pixmap); extern void XSetClipOrigin(Display *display, GC gc, int clip_x_origin, int clip_y_origin); extern void XSetTSOrigin(Display *display, GC gc, int ts_x_origin, int ts_y_origin); extern void XChangeGC(Display *display, GC gc, unsigned long mask, XGCValues * values); extern void XSetFont(Display *display, GC gc, Font font); extern void XSetArcMode(Display *display, GC gc, int arc_mode); extern void XSetStipple(Display * display, GC gc, Pixmap stipple); extern void XSetFillRule(Display *display, GC gc, int fill_rule); extern void XSetFillStyle(Display *display, GC gc, int fill_style); extern void XSetFunction(Display *display, GC gc, int function); extern void XSetLineAttributes(Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); extern int _XInitImageFuncPtrs(XImage * image); extern XIC XCreateIC(void); extern XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask, XVisualInfo* vinfo_template, int* nitems_return); extern void XSetWMClientMachine(Display *display, Window w, XTextProperty* text_prop); extern Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return); extern void XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); extern void XWarpPointer(Display *d, Window s, Window dw, int sx, int sy, unsigned int sw, unsigned int sh, int dx, int dy); extern void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); _XFUNCPROTOEND #ifdef MAC_TCL # undef Cursor # undef Region #endif #endif /* _XLIB_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/keysymdef.h���������������������������������������������������������������0000644�0001750�0001750�00000146315�11462120063�015570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: keysymdef.h,v 1.15 93/04/02 10:57:36 rws Exp $ */ /*********************************************************** Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ #define XK_VoidSymbol 0xFFFFFF /* void symbol */ #ifdef XK_MISCELLANY /* * TTY Functions, cleverly chosen to map to ascii, for convenience of * programming, but could have been arbitrary (at the cost of lookup * tables in client code. */ #define XK_BackSpace 0xFF08 /* back space, back char */ #define XK_Tab 0xFF09 #define XK_Linefeed 0xFF0A /* Linefeed, LF */ #define XK_Clear 0xFF0B #define XK_Return 0xFF0D /* Return, enter */ #define XK_Pause 0xFF13 /* Pause, hold */ #define XK_Scroll_Lock 0xFF14 #define XK_Sys_Req 0xFF15 #define XK_Escape 0xFF1B #define XK_Delete 0xFFFF /* Delete, rubout */ /* International & multi-key character composition */ #define XK_Multi_key 0xFF20 /* Multi-key character compose */ /* Japanese keyboard support */ #define XK_Kanji 0xFF21 /* Kanji, Kanji convert */ #define XK_Muhenkan 0xFF22 /* Cancel Conversion */ #define XK_Henkan_Mode 0xFF23 /* Start/Stop Conversion */ #define XK_Henkan 0xFF23 /* Alias for Henkan_Mode */ #define XK_Romaji 0xFF24 /* to Romaji */ #define XK_Hiragana 0xFF25 /* to Hiragana */ #define XK_Katakana 0xFF26 /* to Katakana */ #define XK_Hiragana_Katakana 0xFF27 /* Hiragana/Katakana toggle */ #define XK_Zenkaku 0xFF28 /* to Zenkaku */ #define XK_Hankaku 0xFF29 /* to Hankaku */ #define XK_Zenkaku_Hankaku 0xFF2A /* Zenkaku/Hankaku toggle */ #define XK_Touroku 0xFF2B /* Add to Dictionary */ #define XK_Massyo 0xFF2C /* Delete from Dictionary */ #define XK_Kana_Lock 0xFF2D /* Kana Lock */ #define XK_Kana_Shift 0xFF2E /* Kana Shift */ #define XK_Eisu_Shift 0xFF2F /* Alphanumeric Shift */ #define XK_Eisu_toggle 0xFF30 /* Alphanumeric toggle */ /* Cursor control & motion */ #define XK_Home 0xFF50 #define XK_Left 0xFF51 /* Move left, left arrow */ #define XK_Up 0xFF52 /* Move up, up arrow */ #define XK_Right 0xFF53 /* Move right, right arrow */ #define XK_Down 0xFF54 /* Move down, down arrow */ #define XK_Prior 0xFF55 /* Prior, previous */ #define XK_Page_Up 0xFF55 #define XK_Next 0xFF56 /* Next */ #define XK_Page_Down 0xFF56 #define XK_End 0xFF57 /* EOL */ #define XK_Begin 0xFF58 /* BOL */ /* Special Windows keyboard keys */ #define XK_Win_L 0xFF5B /* Left-hand Windows */ #define XK_Win_R 0xFF5C /* Right-hand Windows */ #define XK_App 0xFF5D /* Menu key */ /* Misc Functions */ #define XK_Select 0xFF60 /* Select, mark */ #define XK_Print 0xFF61 #define XK_Execute 0xFF62 /* Execute, run, do */ #define XK_Insert 0xFF63 /* Insert, insert here */ #define XK_Undo 0xFF65 /* Undo, oops */ #define XK_Redo 0xFF66 /* redo, again */ #define XK_Menu 0xFF67 #define XK_Find 0xFF68 /* Find, search */ #define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ #define XK_Help 0xFF6A /* Help, ? */ #define XK_Break 0xFF6B #define XK_Mode_switch 0xFF7E /* Character set switch */ #define XK_script_switch 0xFF7E /* Alias for mode_switch */ #define XK_Num_Lock 0xFF7F /* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ #define XK_KP_Space 0xFF80 /* space */ #define XK_KP_Tab 0xFF89 #define XK_KP_Enter 0xFF8D /* enter */ #define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ #define XK_KP_F2 0xFF92 #define XK_KP_F3 0xFF93 #define XK_KP_F4 0xFF94 #define XK_KP_Home 0xFF95 #define XK_KP_Left 0xFF96 #define XK_KP_Up 0xFF97 #define XK_KP_Right 0xFF98 #define XK_KP_Down 0xFF99 #define XK_KP_Prior 0xFF9A #define XK_KP_Page_Up 0xFF9A #define XK_KP_Next 0xFF9B #define XK_KP_Page_Down 0xFF9B #define XK_KP_End 0xFF9C #define XK_KP_Begin 0xFF9D #define XK_KP_Insert 0xFF9E #define XK_KP_Delete 0xFF9F #define XK_KP_Equal 0xFFBD /* equals */ #define XK_KP_Multiply 0xFFAA #define XK_KP_Add 0xFFAB #define XK_KP_Separator 0xFFAC /* separator, often comma */ #define XK_KP_Subtract 0xFFAD #define XK_KP_Decimal 0xFFAE #define XK_KP_Divide 0xFFAF #define XK_KP_0 0xFFB0 #define XK_KP_1 0xFFB1 #define XK_KP_2 0xFFB2 #define XK_KP_3 0xFFB3 #define XK_KP_4 0xFFB4 #define XK_KP_5 0xFFB5 #define XK_KP_6 0xFFB6 #define XK_KP_7 0xFFB7 #define XK_KP_8 0xFFB8 #define XK_KP_9 0xFFB9 /* * Auxilliary Functions; note the duplicate definitions for left and right * function keys; Sun keyboards and a few other manufactures have such * function key groups on the left and/or right sides of the keyboard. * We've not found a keyboard with more than 35 function keys total. */ #define XK_F1 0xFFBE #define XK_F2 0xFFBF #define XK_F3 0xFFC0 #define XK_F4 0xFFC1 #define XK_F5 0xFFC2 #define XK_F6 0xFFC3 #define XK_F7 0xFFC4 #define XK_F8 0xFFC5 #define XK_F9 0xFFC6 #define XK_F10 0xFFC7 #define XK_F11 0xFFC8 #define XK_L1 0xFFC8 #define XK_F12 0xFFC9 #define XK_L2 0xFFC9 #define XK_F13 0xFFCA #define XK_L3 0xFFCA #define XK_F14 0xFFCB #define XK_L4 0xFFCB #define XK_F15 0xFFCC #define XK_L5 0xFFCC #define XK_F16 0xFFCD #define XK_L6 0xFFCD #define XK_F17 0xFFCE #define XK_L7 0xFFCE #define XK_F18 0xFFCF #define XK_L8 0xFFCF #define XK_F19 0xFFD0 #define XK_L9 0xFFD0 #define XK_F20 0xFFD1 #define XK_L10 0xFFD1 #define XK_F21 0xFFD2 #define XK_R1 0xFFD2 #define XK_F22 0xFFD3 #define XK_R2 0xFFD3 #define XK_F23 0xFFD4 #define XK_R3 0xFFD4 #define XK_F24 0xFFD5 #define XK_R4 0xFFD5 #define XK_F25 0xFFD6 #define XK_R5 0xFFD6 #define XK_F26 0xFFD7 #define XK_R6 0xFFD7 #define XK_F27 0xFFD8 #define XK_R7 0xFFD8 #define XK_F28 0xFFD9 #define XK_R8 0xFFD9 #define XK_F29 0xFFDA #define XK_R9 0xFFDA #define XK_F30 0xFFDB #define XK_R10 0xFFDB #define XK_F31 0xFFDC #define XK_R11 0xFFDC #define XK_F32 0xFFDD #define XK_R12 0xFFDD #define XK_F33 0xFFDE #define XK_R13 0xFFDE #define XK_F34 0xFFDF #define XK_R14 0xFFDF #define XK_F35 0xFFE0 #define XK_R15 0xFFE0 /* Modifiers */ #define XK_Shift_L 0xFFE1 /* Left shift */ #define XK_Shift_R 0xFFE2 /* Right shift */ #define XK_Control_L 0xFFE3 /* Left control */ #define XK_Control_R 0xFFE4 /* Right control */ #define XK_Caps_Lock 0xFFE5 /* Caps lock */ #define XK_Shift_Lock 0xFFE6 /* Shift lock */ #define XK_Meta_L 0xFFE7 /* Left meta */ #define XK_Meta_R 0xFFE8 /* Right meta */ #define XK_Alt_L 0xFFE9 /* Left alt */ #define XK_Alt_R 0xFFEA /* Right alt */ #define XK_Super_L 0xFFEB /* Left super */ #define XK_Super_R 0xFFEC /* Right super */ #define XK_Hyper_L 0xFFED /* Left hyper */ #define XK_Hyper_R 0xFFEE /* Right hyper */ #endif /* XK_MISCELLANY */ /* * Latin 1 * Byte 3 = 0 */ #ifdef XK_LATIN1 #define XK_space 0x020 #define XK_exclam 0x021 #define XK_quotedbl 0x022 #define XK_numbersign 0x023 #define XK_dollar 0x024 #define XK_percent 0x025 #define XK_ampersand 0x026 #define XK_apostrophe 0x027 #define XK_quoteright 0x027 /* deprecated */ #define XK_parenleft 0x028 #define XK_parenright 0x029 #define XK_asterisk 0x02a #define XK_plus 0x02b #define XK_comma 0x02c #define XK_minus 0x02d #define XK_period 0x02e #define XK_slash 0x02f #define XK_0 0x030 #define XK_1 0x031 #define XK_2 0x032 #define XK_3 0x033 #define XK_4 0x034 #define XK_5 0x035 #define XK_6 0x036 #define XK_7 0x037 #define XK_8 0x038 #define XK_9 0x039 #define XK_colon 0x03a #define XK_semicolon 0x03b #define XK_less 0x03c #define XK_equal 0x03d #define XK_greater 0x03e #define XK_question 0x03f #define XK_at 0x040 #define XK_A 0x041 #define XK_B 0x042 #define XK_C 0x043 #define XK_D 0x044 #define XK_E 0x045 #define XK_F 0x046 #define XK_G 0x047 #define XK_H 0x048 #define XK_I 0x049 #define XK_J 0x04a #define XK_K 0x04b #define XK_L 0x04c #define XK_M 0x04d #define XK_N 0x04e #define XK_O 0x04f #define XK_P 0x050 #define XK_Q 0x051 #define XK_R 0x052 #define XK_S 0x053 #define XK_T 0x054 #define XK_U 0x055 #define XK_V 0x056 #define XK_W 0x057 #define XK_X 0x058 #define XK_Y 0x059 #define XK_Z 0x05a #define XK_bracketleft 0x05b #define XK_backslash 0x05c #define XK_bracketright 0x05d #define XK_asciicircum 0x05e #define XK_underscore 0x05f #define XK_grave 0x060 #define XK_quoteleft 0x060 /* deprecated */ #define XK_a 0x061 #define XK_b 0x062 #define XK_c 0x063 #define XK_d 0x064 #define XK_e 0x065 #define XK_f 0x066 #define XK_g 0x067 #define XK_h 0x068 #define XK_i 0x069 #define XK_j 0x06a #define XK_k 0x06b #define XK_l 0x06c #define XK_m 0x06d #define XK_n 0x06e #define XK_o 0x06f #define XK_p 0x070 #define XK_q 0x071 #define XK_r 0x072 #define XK_s 0x073 #define XK_t 0x074 #define XK_u 0x075 #define XK_v 0x076 #define XK_w 0x077 #define XK_x 0x078 #define XK_y 0x079 #define XK_z 0x07a #define XK_braceleft 0x07b #define XK_bar 0x07c #define XK_braceright 0x07d #define XK_asciitilde 0x07e #define XK_nobreakspace 0x0a0 #define XK_exclamdown 0x0a1 #define XK_cent 0x0a2 #define XK_sterling 0x0a3 #define XK_currency 0x0a4 #define XK_yen 0x0a5 #define XK_brokenbar 0x0a6 #define XK_section 0x0a7 #define XK_diaeresis 0x0a8 #define XK_copyright 0x0a9 #define XK_ordfeminine 0x0aa #define XK_guillemotleft 0x0ab /* left angle quotation mark */ #define XK_notsign 0x0ac #define XK_hyphen 0x0ad #define XK_registered 0x0ae #define XK_macron 0x0af #define XK_degree 0x0b0 #define XK_plusminus 0x0b1 #define XK_twosuperior 0x0b2 #define XK_threesuperior 0x0b3 #define XK_acute 0x0b4 #define XK_mu 0x0b5 #define XK_paragraph 0x0b6 #define XK_periodcentered 0x0b7 #define XK_cedilla 0x0b8 #define XK_onesuperior 0x0b9 #define XK_masculine 0x0ba #define XK_guillemotright 0x0bb /* right angle quotation mark */ #define XK_onequarter 0x0bc #define XK_onehalf 0x0bd #define XK_threequarters 0x0be #define XK_questiondown 0x0bf #define XK_Agrave 0x0c0 #define XK_Aacute 0x0c1 #define XK_Acircumflex 0x0c2 #define XK_Atilde 0x0c3 #define XK_Adiaeresis 0x0c4 #define XK_Aring 0x0c5 #define XK_AE 0x0c6 #define XK_Ccedilla 0x0c7 #define XK_Egrave 0x0c8 #define XK_Eacute 0x0c9 #define XK_Ecircumflex 0x0ca #define XK_Ediaeresis 0x0cb #define XK_Igrave 0x0cc #define XK_Iacute 0x0cd #define XK_Icircumflex 0x0ce #define XK_Idiaeresis 0x0cf #define XK_ETH 0x0d0 #define XK_Eth 0x0d0 /* deprecated */ #define XK_Ntilde 0x0d1 #define XK_Ograve 0x0d2 #define XK_Oacute 0x0d3 #define XK_Ocircumflex 0x0d4 #define XK_Otilde 0x0d5 #define XK_Odiaeresis 0x0d6 #define XK_multiply 0x0d7 #define XK_Ooblique 0x0d8 #define XK_Ugrave 0x0d9 #define XK_Uacute 0x0da #define XK_Ucircumflex 0x0db #define XK_Udiaeresis 0x0dc #define XK_Yacute 0x0dd #define XK_THORN 0x0de #define XK_Thorn 0x0de /* deprecated */ #define XK_ssharp 0x0df #define XK_agrave 0x0e0 #define XK_aacute 0x0e1 #define XK_acircumflex 0x0e2 #define XK_atilde 0x0e3 #define XK_adiaeresis 0x0e4 #define XK_aring 0x0e5 #define XK_ae 0x0e6 #define XK_ccedilla 0x0e7 #define XK_egrave 0x0e8 #define XK_eacute 0x0e9 #define XK_ecircumflex 0x0ea #define XK_ediaeresis 0x0eb #define XK_igrave 0x0ec #define XK_iacute 0x0ed #define XK_icircumflex 0x0ee #define XK_idiaeresis 0x0ef #define XK_eth 0x0f0 #define XK_ntilde 0x0f1 #define XK_ograve 0x0f2 #define XK_oacute 0x0f3 #define XK_ocircumflex 0x0f4 #define XK_otilde 0x0f5 #define XK_odiaeresis 0x0f6 #define XK_division 0x0f7 #define XK_oslash 0x0f8 #define XK_ugrave 0x0f9 #define XK_uacute 0x0fa #define XK_ucircumflex 0x0fb #define XK_udiaeresis 0x0fc #define XK_yacute 0x0fd #define XK_thorn 0x0fe #define XK_ydiaeresis 0x0ff #endif /* XK_LATIN1 */ /* * Latin 2 * Byte 3 = 1 */ #ifdef XK_LATIN2 #define XK_Aogonek 0x1a1 #define XK_breve 0x1a2 #define XK_Lstroke 0x1a3 #define XK_Lcaron 0x1a5 #define XK_Sacute 0x1a6 #define XK_Scaron 0x1a9 #define XK_Scedilla 0x1aa #define XK_Tcaron 0x1ab #define XK_Zacute 0x1ac #define XK_Zcaron 0x1ae #define XK_Zabovedot 0x1af #define XK_aogonek 0x1b1 #define XK_ogonek 0x1b2 #define XK_lstroke 0x1b3 #define XK_lcaron 0x1b5 #define XK_sacute 0x1b6 #define XK_caron 0x1b7 #define XK_scaron 0x1b9 #define XK_scedilla 0x1ba #define XK_tcaron 0x1bb #define XK_zacute 0x1bc #define XK_doubleacute 0x1bd #define XK_zcaron 0x1be #define XK_zabovedot 0x1bf #define XK_Racute 0x1c0 #define XK_Abreve 0x1c3 #define XK_Lacute 0x1c5 #define XK_Cacute 0x1c6 #define XK_Ccaron 0x1c8 #define XK_Eogonek 0x1ca #define XK_Ecaron 0x1cc #define XK_Dcaron 0x1cf #define XK_Dstroke 0x1d0 #define XK_Nacute 0x1d1 #define XK_Ncaron 0x1d2 #define XK_Odoubleacute 0x1d5 #define XK_Rcaron 0x1d8 #define XK_Uring 0x1d9 #define XK_Udoubleacute 0x1db #define XK_Tcedilla 0x1de #define XK_racute 0x1e0 #define XK_abreve 0x1e3 #define XK_lacute 0x1e5 #define XK_cacute 0x1e6 #define XK_ccaron 0x1e8 #define XK_eogonek 0x1ea #define XK_ecaron 0x1ec #define XK_dcaron 0x1ef #define XK_dstroke 0x1f0 #define XK_nacute 0x1f1 #define XK_ncaron 0x1f2 #define XK_odoubleacute 0x1f5 #define XK_udoubleacute 0x1fb #define XK_rcaron 0x1f8 #define XK_uring 0x1f9 #define XK_tcedilla 0x1fe #define XK_abovedot 0x1ff #endif /* XK_LATIN2 */ /* * Latin 3 * Byte 3 = 2 */ #ifdef XK_LATIN3 #define XK_Hstroke 0x2a1 #define XK_Hcircumflex 0x2a6 #define XK_Iabovedot 0x2a9 #define XK_Gbreve 0x2ab #define XK_Jcircumflex 0x2ac #define XK_hstroke 0x2b1 #define XK_hcircumflex 0x2b6 #define XK_idotless 0x2b9 #define XK_gbreve 0x2bb #define XK_jcircumflex 0x2bc #define XK_Cabovedot 0x2c5 #define XK_Ccircumflex 0x2c6 #define XK_Gabovedot 0x2d5 #define XK_Gcircumflex 0x2d8 #define XK_Ubreve 0x2dd #define XK_Scircumflex 0x2de #define XK_cabovedot 0x2e5 #define XK_ccircumflex 0x2e6 #define XK_gabovedot 0x2f5 #define XK_gcircumflex 0x2f8 #define XK_ubreve 0x2fd #define XK_scircumflex 0x2fe #endif /* XK_LATIN3 */ /* * Latin 4 * Byte 3 = 3 */ #ifdef XK_LATIN4 #define XK_kra 0x3a2 #define XK_kappa 0x3a2 /* deprecated */ #define XK_Rcedilla 0x3a3 #define XK_Itilde 0x3a5 #define XK_Lcedilla 0x3a6 #define XK_Emacron 0x3aa #define XK_Gcedilla 0x3ab #define XK_Tslash 0x3ac #define XK_rcedilla 0x3b3 #define XK_itilde 0x3b5 #define XK_lcedilla 0x3b6 #define XK_emacron 0x3ba #define XK_gcedilla 0x3bb #define XK_tslash 0x3bc #define XK_ENG 0x3bd #define XK_eng 0x3bf #define XK_Amacron 0x3c0 #define XK_Iogonek 0x3c7 #define XK_Eabovedot 0x3cc #define XK_Imacron 0x3cf #define XK_Ncedilla 0x3d1 #define XK_Omacron 0x3d2 #define XK_Kcedilla 0x3d3 #define XK_Uogonek 0x3d9 #define XK_Utilde 0x3dd #define XK_Umacron 0x3de #define XK_amacron 0x3e0 #define XK_iogonek 0x3e7 #define XK_eabovedot 0x3ec #define XK_imacron 0x3ef #define XK_ncedilla 0x3f1 #define XK_omacron 0x3f2 #define XK_kcedilla 0x3f3 #define XK_uogonek 0x3f9 #define XK_utilde 0x3fd #define XK_umacron 0x3fe #endif /* XK_LATIN4 */ /* * Katakana * Byte 3 = 4 */ #ifdef XK_KATAKANA #define XK_overline 0x47e #define XK_kana_fullstop 0x4a1 #define XK_kana_openingbracket 0x4a2 #define XK_kana_closingbracket 0x4a3 #define XK_kana_comma 0x4a4 #define XK_kana_conjunctive 0x4a5 #define XK_kana_middledot 0x4a5 /* deprecated */ #define XK_kana_WO 0x4a6 #define XK_kana_a 0x4a7 #define XK_kana_i 0x4a8 #define XK_kana_u 0x4a9 #define XK_kana_e 0x4aa #define XK_kana_o 0x4ab #define XK_kana_ya 0x4ac #define XK_kana_yu 0x4ad #define XK_kana_yo 0x4ae #define XK_kana_tsu 0x4af #define XK_kana_tu 0x4af /* deprecated */ #define XK_prolongedsound 0x4b0 #define XK_kana_A 0x4b1 #define XK_kana_I 0x4b2 #define XK_kana_U 0x4b3 #define XK_kana_E 0x4b4 #define XK_kana_O 0x4b5 #define XK_kana_KA 0x4b6 #define XK_kana_KI 0x4b7 #define XK_kana_KU 0x4b8 #define XK_kana_KE 0x4b9 #define XK_kana_KO 0x4ba #define XK_kana_SA 0x4bb #define XK_kana_SHI 0x4bc #define XK_kana_SU 0x4bd #define XK_kana_SE 0x4be #define XK_kana_SO 0x4bf #define XK_kana_TA 0x4c0 #define XK_kana_CHI 0x4c1 #define XK_kana_TI 0x4c1 /* deprecated */ #define XK_kana_TSU 0x4c2 #define XK_kana_TU 0x4c2 /* deprecated */ #define XK_kana_TE 0x4c3 #define XK_kana_TO 0x4c4 #define XK_kana_NA 0x4c5 #define XK_kana_NI 0x4c6 #define XK_kana_NU 0x4c7 #define XK_kana_NE 0x4c8 #define XK_kana_NO 0x4c9 #define XK_kana_HA 0x4ca #define XK_kana_HI 0x4cb #define XK_kana_FU 0x4cc #define XK_kana_HU 0x4cc /* deprecated */ #define XK_kana_HE 0x4cd #define XK_kana_HO 0x4ce #define XK_kana_MA 0x4cf #define XK_kana_MI 0x4d0 #define XK_kana_MU 0x4d1 #define XK_kana_ME 0x4d2 #define XK_kana_MO 0x4d3 #define XK_kana_YA 0x4d4 #define XK_kana_YU 0x4d5 #define XK_kana_YO 0x4d6 #define XK_kana_RA 0x4d7 #define XK_kana_RI 0x4d8 #define XK_kana_RU 0x4d9 #define XK_kana_RE 0x4da #define XK_kana_RO 0x4db #define XK_kana_WA 0x4dc #define XK_kana_N 0x4dd #define XK_voicedsound 0x4de #define XK_semivoicedsound 0x4df #define XK_kana_switch 0xFF7E /* Alias for mode_switch */ #endif /* XK_KATAKANA */ /* * Arabic * Byte 3 = 5 */ #ifdef XK_ARABIC #define XK_Arabic_comma 0x5ac #define XK_Arabic_semicolon 0x5bb #define XK_Arabic_question_mark 0x5bf #define XK_Arabic_hamza 0x5c1 #define XK_Arabic_maddaonalef 0x5c2 #define XK_Arabic_hamzaonalef 0x5c3 #define XK_Arabic_hamzaonwaw 0x5c4 #define XK_Arabic_hamzaunderalef 0x5c5 #define XK_Arabic_hamzaonyeh 0x5c6 #define XK_Arabic_alef 0x5c7 #define XK_Arabic_beh 0x5c8 #define XK_Arabic_tehmarbuta 0x5c9 #define XK_Arabic_teh 0x5ca #define XK_Arabic_theh 0x5cb #define XK_Arabic_jeem 0x5cc #define XK_Arabic_hah 0x5cd #define XK_Arabic_khah 0x5ce #define XK_Arabic_dal 0x5cf #define XK_Arabic_thal 0x5d0 #define XK_Arabic_ra 0x5d1 #define XK_Arabic_zain 0x5d2 #define XK_Arabic_seen 0x5d3 #define XK_Arabic_sheen 0x5d4 #define XK_Arabic_sad 0x5d5 #define XK_Arabic_dad 0x5d6 #define XK_Arabic_tah 0x5d7 #define XK_Arabic_zah 0x5d8 #define XK_Arabic_ain 0x5d9 #define XK_Arabic_ghain 0x5da #define XK_Arabic_tatweel 0x5e0 #define XK_Arabic_feh 0x5e1 #define XK_Arabic_qaf 0x5e2 #define XK_Arabic_kaf 0x5e3 #define XK_Arabic_lam 0x5e4 #define XK_Arabic_meem 0x5e5 #define XK_Arabic_noon 0x5e6 #define XK_Arabic_ha 0x5e7 #define XK_Arabic_heh 0x5e7 /* deprecated */ #define XK_Arabic_waw 0x5e8 #define XK_Arabic_alefmaksura 0x5e9 #define XK_Arabic_yeh 0x5ea #define XK_Arabic_fathatan 0x5eb #define XK_Arabic_dammatan 0x5ec #define XK_Arabic_kasratan 0x5ed #define XK_Arabic_fatha 0x5ee #define XK_Arabic_damma 0x5ef #define XK_Arabic_kasra 0x5f0 #define XK_Arabic_shadda 0x5f1 #define XK_Arabic_sukun 0x5f2 #define XK_Arabic_switch 0xFF7E /* Alias for mode_switch */ #endif /* XK_ARABIC */ /* * Cyrillic * Byte 3 = 6 */ #ifdef XK_CYRILLIC #define XK_Serbian_dje 0x6a1 #define XK_Macedonia_gje 0x6a2 #define XK_Cyrillic_io 0x6a3 #define XK_Ukrainian_ie 0x6a4 #define XK_Ukranian_je 0x6a4 /* deprecated */ #define XK_Macedonia_dse 0x6a5 #define XK_Ukrainian_i 0x6a6 #define XK_Ukranian_i 0x6a6 /* deprecated */ #define XK_Ukrainian_yi 0x6a7 #define XK_Ukranian_yi 0x6a7 /* deprecated */ #define XK_Cyrillic_je 0x6a8 #define XK_Serbian_je 0x6a8 /* deprecated */ #define XK_Cyrillic_lje 0x6a9 #define XK_Serbian_lje 0x6a9 /* deprecated */ #define XK_Cyrillic_nje 0x6aa #define XK_Serbian_nje 0x6aa /* deprecated */ #define XK_Serbian_tshe 0x6ab #define XK_Macedonia_kje 0x6ac #define XK_Byelorussian_shortu 0x6ae #define XK_Cyrillic_dzhe 0x6af #define XK_Serbian_dze 0x6af /* deprecated */ #define XK_numerosign 0x6b0 #define XK_Serbian_DJE 0x6b1 #define XK_Macedonia_GJE 0x6b2 #define XK_Cyrillic_IO 0x6b3 #define XK_Ukrainian_IE 0x6b4 #define XK_Ukranian_JE 0x6b4 /* deprecated */ #define XK_Macedonia_DSE 0x6b5 #define XK_Ukrainian_I 0x6b6 #define XK_Ukranian_I 0x6b6 /* deprecated */ #define XK_Ukrainian_YI 0x6b7 #define XK_Ukranian_YI 0x6b7 /* deprecated */ #define XK_Cyrillic_JE 0x6b8 #define XK_Serbian_JE 0x6b8 /* deprecated */ #define XK_Cyrillic_LJE 0x6b9 #define XK_Serbian_LJE 0x6b9 /* deprecated */ #define XK_Cyrillic_NJE 0x6ba #define XK_Serbian_NJE 0x6ba /* deprecated */ #define XK_Serbian_TSHE 0x6bb #define XK_Macedonia_KJE 0x6bc #define XK_Byelorussian_SHORTU 0x6be #define XK_Cyrillic_DZHE 0x6bf #define XK_Serbian_DZE 0x6bf /* deprecated */ #define XK_Cyrillic_yu 0x6c0 #define XK_Cyrillic_a 0x6c1 #define XK_Cyrillic_be 0x6c2 #define XK_Cyrillic_tse 0x6c3 #define XK_Cyrillic_de 0x6c4 #define XK_Cyrillic_ie 0x6c5 #define XK_Cyrillic_ef 0x6c6 #define XK_Cyrillic_ghe 0x6c7 #define XK_Cyrillic_ha 0x6c8 #define XK_Cyrillic_i 0x6c9 #define XK_Cyrillic_shorti 0x6ca #define XK_Cyrillic_ka 0x6cb #define XK_Cyrillic_el 0x6cc #define XK_Cyrillic_em 0x6cd #define XK_Cyrillic_en 0x6ce #define XK_Cyrillic_o 0x6cf #define XK_Cyrillic_pe 0x6d0 #define XK_Cyrillic_ya 0x6d1 #define XK_Cyrillic_er 0x6d2 #define XK_Cyrillic_es 0x6d3 #define XK_Cyrillic_te 0x6d4 #define XK_Cyrillic_u 0x6d5 #define XK_Cyrillic_zhe 0x6d6 #define XK_Cyrillic_ve 0x6d7 #define XK_Cyrillic_softsign 0x6d8 #define XK_Cyrillic_yeru 0x6d9 #define XK_Cyrillic_ze 0x6da #define XK_Cyrillic_sha 0x6db #define XK_Cyrillic_e 0x6dc #define XK_Cyrillic_shcha 0x6dd #define XK_Cyrillic_che 0x6de #define XK_Cyrillic_hardsign 0x6df #define XK_Cyrillic_YU 0x6e0 #define XK_Cyrillic_A 0x6e1 #define XK_Cyrillic_BE 0x6e2 #define XK_Cyrillic_TSE 0x6e3 #define XK_Cyrillic_DE 0x6e4 #define XK_Cyrillic_IE 0x6e5 #define XK_Cyrillic_EF 0x6e6 #define XK_Cyrillic_GHE 0x6e7 #define XK_Cyrillic_HA 0x6e8 #define XK_Cyrillic_I 0x6e9 #define XK_Cyrillic_SHORTI 0x6ea #define XK_Cyrillic_KA 0x6eb #define XK_Cyrillic_EL 0x6ec #define XK_Cyrillic_EM 0x6ed #define XK_Cyrillic_EN 0x6ee #define XK_Cyrillic_O 0x6ef #define XK_Cyrillic_PE 0x6f0 #define XK_Cyrillic_YA 0x6f1 #define XK_Cyrillic_ER 0x6f2 #define XK_Cyrillic_ES 0x6f3 #define XK_Cyrillic_TE 0x6f4 #define XK_Cyrillic_U 0x6f5 #define XK_Cyrillic_ZHE 0x6f6 #define XK_Cyrillic_VE 0x6f7 #define XK_Cyrillic_SOFTSIGN 0x6f8 #define XK_Cyrillic_YERU 0x6f9 #define XK_Cyrillic_ZE 0x6fa #define XK_Cyrillic_SHA 0x6fb #define XK_Cyrillic_E 0x6fc #define XK_Cyrillic_SHCHA 0x6fd #define XK_Cyrillic_CHE 0x6fe #define XK_Cyrillic_HARDSIGN 0x6ff #endif /* XK_CYRILLIC */ /* * Greek * Byte 3 = 7 */ #ifdef XK_GREEK #define XK_Greek_ALPHAaccent 0x7a1 #define XK_Greek_EPSILONaccent 0x7a2 #define XK_Greek_ETAaccent 0x7a3 #define XK_Greek_IOTAaccent 0x7a4 #define XK_Greek_IOTAdiaeresis 0x7a5 #define XK_Greek_OMICRONaccent 0x7a7 #define XK_Greek_UPSILONaccent 0x7a8 #define XK_Greek_UPSILONdieresis 0x7a9 #define XK_Greek_OMEGAaccent 0x7ab #define XK_Greek_accentdieresis 0x7ae #define XK_Greek_horizbar 0x7af #define XK_Greek_alphaaccent 0x7b1 #define XK_Greek_epsilonaccent 0x7b2 #define XK_Greek_etaaccent 0x7b3 #define XK_Greek_iotaaccent 0x7b4 #define XK_Greek_iotadieresis 0x7b5 #define XK_Greek_iotaaccentdieresis 0x7b6 #define XK_Greek_omicronaccent 0x7b7 #define XK_Greek_upsilonaccent 0x7b8 #define XK_Greek_upsilondieresis 0x7b9 #define XK_Greek_upsilonaccentdieresis 0x7ba #define XK_Greek_omegaaccent 0x7bb #define XK_Greek_ALPHA 0x7c1 #define XK_Greek_BETA 0x7c2 #define XK_Greek_GAMMA 0x7c3 #define XK_Greek_DELTA 0x7c4 #define XK_Greek_EPSILON 0x7c5 #define XK_Greek_ZETA 0x7c6 #define XK_Greek_ETA 0x7c7 #define XK_Greek_THETA 0x7c8 #define XK_Greek_IOTA 0x7c9 #define XK_Greek_KAPPA 0x7ca #define XK_Greek_LAMDA 0x7cb #define XK_Greek_LAMBDA 0x7cb #define XK_Greek_MU 0x7cc #define XK_Greek_NU 0x7cd #define XK_Greek_XI 0x7ce #define XK_Greek_OMICRON 0x7cf #define XK_Greek_PI 0x7d0 #define XK_Greek_RHO 0x7d1 #define XK_Greek_SIGMA 0x7d2 #define XK_Greek_TAU 0x7d4 #define XK_Greek_UPSILON 0x7d5 #define XK_Greek_PHI 0x7d6 #define XK_Greek_CHI 0x7d7 #define XK_Greek_PSI 0x7d8 #define XK_Greek_OMEGA 0x7d9 #define XK_Greek_alpha 0x7e1 #define XK_Greek_beta 0x7e2 #define XK_Greek_gamma 0x7e3 #define XK_Greek_delta 0x7e4 #define XK_Greek_epsilon 0x7e5 #define XK_Greek_zeta 0x7e6 #define XK_Greek_eta 0x7e7 #define XK_Greek_theta 0x7e8 #define XK_Greek_iota 0x7e9 #define XK_Greek_kappa 0x7ea #define XK_Greek_lamda 0x7eb #define XK_Greek_lambda 0x7eb #define XK_Greek_mu 0x7ec #define XK_Greek_nu 0x7ed #define XK_Greek_xi 0x7ee #define XK_Greek_omicron 0x7ef #define XK_Greek_pi 0x7f0 #define XK_Greek_rho 0x7f1 #define XK_Greek_sigma 0x7f2 #define XK_Greek_finalsmallsigma 0x7f3 #define XK_Greek_tau 0x7f4 #define XK_Greek_upsilon 0x7f5 #define XK_Greek_phi 0x7f6 #define XK_Greek_chi 0x7f7 #define XK_Greek_psi 0x7f8 #define XK_Greek_omega 0x7f9 #define XK_Greek_switch 0xFF7E /* Alias for mode_switch */ #endif /* XK_GREEK */ /* * Technical * Byte 3 = 8 */ #ifdef XK_TECHNICAL #define XK_leftradical 0x8a1 #define XK_topleftradical 0x8a2 #define XK_horizconnector 0x8a3 #define XK_topintegral 0x8a4 #define XK_botintegral 0x8a5 #define XK_vertconnector 0x8a6 #define XK_topleftsqbracket 0x8a7 #define XK_botleftsqbracket 0x8a8 #define XK_toprightsqbracket 0x8a9 #define XK_botrightsqbracket 0x8aa #define XK_topleftparens 0x8ab #define XK_botleftparens 0x8ac #define XK_toprightparens 0x8ad #define XK_botrightparens 0x8ae #define XK_leftmiddlecurlybrace 0x8af #define XK_rightmiddlecurlybrace 0x8b0 #define XK_topleftsummation 0x8b1 #define XK_botleftsummation 0x8b2 #define XK_topvertsummationconnector 0x8b3 #define XK_botvertsummationconnector 0x8b4 #define XK_toprightsummation 0x8b5 #define XK_botrightsummation 0x8b6 #define XK_rightmiddlesummation 0x8b7 #define XK_lessthanequal 0x8bc #define XK_notequal 0x8bd #define XK_greaterthanequal 0x8be #define XK_integral 0x8bf #define XK_therefore 0x8c0 #define XK_variation 0x8c1 #define XK_infinity 0x8c2 #define XK_nabla 0x8c5 #define XK_approximate 0x8c8 #define XK_similarequal 0x8c9 #define XK_ifonlyif 0x8cd #define XK_implies 0x8ce #define XK_identical 0x8cf #define XK_radical 0x8d6 #define XK_includedin 0x8da #define XK_includes 0x8db #define XK_intersection 0x8dc #define XK_union 0x8dd #define XK_logicaland 0x8de #define XK_logicalor 0x8df #define XK_partialderivative 0x8ef #define XK_function 0x8f6 #define XK_leftarrow 0x8fb #define XK_uparrow 0x8fc #define XK_rightarrow 0x8fd #define XK_downarrow 0x8fe #endif /* XK_TECHNICAL */ /* * Special * Byte 3 = 9 */ #ifdef XK_SPECIAL #define XK_blank 0x9df #define XK_soliddiamond 0x9e0 #define XK_checkerboard 0x9e1 #define XK_ht 0x9e2 #define XK_ff 0x9e3 #define XK_cr 0x9e4 #define XK_lf 0x9e5 #define XK_nl 0x9e8 #define XK_vt 0x9e9 #define XK_lowrightcorner 0x9ea #define XK_uprightcorner 0x9eb #define XK_upleftcorner 0x9ec #define XK_lowleftcorner 0x9ed #define XK_crossinglines 0x9ee #define XK_horizlinescan1 0x9ef #define XK_horizlinescan3 0x9f0 #define XK_horizlinescan5 0x9f1 #define XK_horizlinescan7 0x9f2 #define XK_horizlinescan9 0x9f3 #define XK_leftt 0x9f4 #define XK_rightt 0x9f5 #define XK_bott 0x9f6 #define XK_topt 0x9f7 #define XK_vertbar 0x9f8 #endif /* XK_SPECIAL */ /* * Publishing * Byte 3 = a */ #ifdef XK_PUBLISHING #define XK_emspace 0xaa1 #define XK_enspace 0xaa2 #define XK_em3space 0xaa3 #define XK_em4space 0xaa4 #define XK_digitspace 0xaa5 #define XK_punctspace 0xaa6 #define XK_thinspace 0xaa7 #define XK_hairspace 0xaa8 #define XK_emdash 0xaa9 #define XK_endash 0xaaa #define XK_signifblank 0xaac #define XK_ellipsis 0xaae #define XK_doubbaselinedot 0xaaf #define XK_onethird 0xab0 #define XK_twothirds 0xab1 #define XK_onefifth 0xab2 #define XK_twofifths 0xab3 #define XK_threefifths 0xab4 #define XK_fourfifths 0xab5 #define XK_onesixth 0xab6 #define XK_fivesixths 0xab7 #define XK_careof 0xab8 #define XK_figdash 0xabb #define XK_leftanglebracket 0xabc #define XK_decimalpoint 0xabd #define XK_rightanglebracket 0xabe #define XK_marker 0xabf #define XK_oneeighth 0xac3 #define XK_threeeighths 0xac4 #define XK_fiveeighths 0xac5 #define XK_seveneighths 0xac6 #define XK_trademark 0xac9 #define XK_signaturemark 0xaca #define XK_trademarkincircle 0xacb #define XK_leftopentriangle 0xacc #define XK_rightopentriangle 0xacd #define XK_emopencircle 0xace #define XK_emopenrectangle 0xacf #define XK_leftsinglequotemark 0xad0 #define XK_rightsinglequotemark 0xad1 #define XK_leftdoublequotemark 0xad2 #define XK_rightdoublequotemark 0xad3 #define XK_prescription 0xad4 #define XK_minutes 0xad6 #define XK_seconds 0xad7 #define XK_latincross 0xad9 #define XK_hexagram 0xada #define XK_filledrectbullet 0xadb #define XK_filledlefttribullet 0xadc #define XK_filledrighttribullet 0xadd #define XK_emfilledcircle 0xade #define XK_emfilledrect 0xadf #define XK_enopencircbullet 0xae0 #define XK_enopensquarebullet 0xae1 #define XK_openrectbullet 0xae2 #define XK_opentribulletup 0xae3 #define XK_opentribulletdown 0xae4 #define XK_openstar 0xae5 #define XK_enfilledcircbullet 0xae6 #define XK_enfilledsqbullet 0xae7 #define XK_filledtribulletup 0xae8 #define XK_filledtribulletdown 0xae9 #define XK_leftpointer 0xaea #define XK_rightpointer 0xaeb #define XK_club 0xaec #define XK_diamond 0xaed #define XK_heart 0xaee #define XK_maltesecross 0xaf0 #define XK_dagger 0xaf1 #define XK_doubledagger 0xaf2 #define XK_checkmark 0xaf3 #define XK_ballotcross 0xaf4 #define XK_musicalsharp 0xaf5 #define XK_musicalflat 0xaf6 #define XK_malesymbol 0xaf7 #define XK_femalesymbol 0xaf8 #define XK_telephone 0xaf9 #define XK_telephonerecorder 0xafa #define XK_phonographcopyright 0xafb #define XK_caret 0xafc #define XK_singlelowquotemark 0xafd #define XK_doublelowquotemark 0xafe #define XK_cursor 0xaff #endif /* XK_PUBLISHING */ /* * APL * Byte 3 = b */ #ifdef XK_APL #define XK_leftcaret 0xba3 #define XK_rightcaret 0xba6 #define XK_downcaret 0xba8 #define XK_upcaret 0xba9 #define XK_overbar 0xbc0 #define XK_downtack 0xbc2 #define XK_upshoe 0xbc3 #define XK_downstile 0xbc4 #define XK_underbar 0xbc6 #define XK_jot 0xbca #define XK_quad 0xbcc #define XK_uptack 0xbce #define XK_circle 0xbcf #define XK_upstile 0xbd3 #define XK_downshoe 0xbd6 #define XK_rightshoe 0xbd8 #define XK_leftshoe 0xbda #define XK_lefttack 0xbdc #define XK_righttack 0xbfc #endif /* XK_APL */ /* * Hebrew * Byte 3 = c */ #ifdef XK_HEBREW #define XK_hebrew_doublelowline 0xcdf #define XK_hebrew_aleph 0xce0 #define XK_hebrew_bet 0xce1 #define XK_hebrew_beth 0xce1 /* deprecated */ #define XK_hebrew_gimel 0xce2 #define XK_hebrew_gimmel 0xce2 /* deprecated */ #define XK_hebrew_dalet 0xce3 #define XK_hebrew_daleth 0xce3 /* deprecated */ #define XK_hebrew_he 0xce4 #define XK_hebrew_waw 0xce5 #define XK_hebrew_zain 0xce6 #define XK_hebrew_zayin 0xce6 /* deprecated */ #define XK_hebrew_chet 0xce7 #define XK_hebrew_het 0xce7 /* deprecated */ #define XK_hebrew_tet 0xce8 #define XK_hebrew_teth 0xce8 /* deprecated */ #define XK_hebrew_yod 0xce9 #define XK_hebrew_finalkaph 0xcea #define XK_hebrew_kaph 0xceb #define XK_hebrew_lamed 0xcec #define XK_hebrew_finalmem 0xced #define XK_hebrew_mem 0xcee #define XK_hebrew_finalnun 0xcef #define XK_hebrew_nun 0xcf0 #define XK_hebrew_samech 0xcf1 #define XK_hebrew_samekh 0xcf1 /* deprecated */ #define XK_hebrew_ayin 0xcf2 #define XK_hebrew_finalpe 0xcf3 #define XK_hebrew_pe 0xcf4 #define XK_hebrew_finalzade 0xcf5 #define XK_hebrew_finalzadi 0xcf5 /* deprecated */ #define XK_hebrew_zade 0xcf6 #define XK_hebrew_zadi 0xcf6 /* deprecated */ #define XK_hebrew_qoph 0xcf7 #define XK_hebrew_kuf 0xcf7 /* deprecated */ #define XK_hebrew_resh 0xcf8 #define XK_hebrew_shin 0xcf9 #define XK_hebrew_taw 0xcfa #define XK_hebrew_taf 0xcfa /* deprecated */ #define XK_Hebrew_switch 0xFF7E /* Alias for mode_switch */ #endif /* XK_HEBREW */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/Xfuncproto.h��������������������������������������������������������������0000644�0001750�0001750�00000003270�11462120063�015727� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: Xfuncproto.h,v 1.7 91/05/13 20:49:21 rws Exp $ */ /* * Copyright 1989, 1991 by the Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * */ /* Definitions to make function prototypes manageable */ #ifndef _XFUNCPROTO_H_ #define _XFUNCPROTO_H_ #ifndef NeedFunctionPrototypes #define NeedFunctionPrototypes 1 #endif /* NeedFunctionPrototypes */ #ifndef NeedVarargsPrototypes #define NeedVarargsPrototypes 0 #endif /* NeedVarargsPrototypes */ #if NeedFunctionPrototypes #ifndef NeedNestedPrototypes #define NeedNestedPrototypes 1 #endif /* NeedNestedPrototypes */ #ifndef _Xconst #define _Xconst const #endif /* _Xconst */ #ifndef NeedWidePrototypes #ifdef NARROWPROTO #define NeedWidePrototypes 0 #else #define NeedWidePrototypes 1 /* default to make interropt. easier */ #endif #endif /* NeedWidePrototypes */ #endif /* NeedFunctionPrototypes */ #ifdef __cplusplus #define _XFUNCPROTOBEGIN extern "C" { #define _XFUNCPROTOEND } #endif #ifndef _XFUNCPROTOBEGIN #define _XFUNCPROTOBEGIN #define _XFUNCPROTOEND #endif /* _XFUNCPROTOBEGIN */ #endif /* _XFUNCPROTO_H_ */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/cursorfont.h��������������������������������������������������������������0000644�0001750�0001750�00000003641�11462120063�015766� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: cursorfont.h,v 1.2 88/09/06 16:44:27 jim Exp $ */ #define XC_num_glyphs 154 #define XC_X_cursor 0 #define XC_arrow 2 #define XC_based_arrow_down 4 #define XC_based_arrow_up 6 #define XC_boat 8 #define XC_bogosity 10 #define XC_bottom_left_corner 12 #define XC_bottom_right_corner 14 #define XC_bottom_side 16 #define XC_bottom_tee 18 #define XC_box_spiral 20 #define XC_center_ptr 22 #define XC_circle 24 #define XC_clock 26 #define XC_coffee_mug 28 #define XC_cross 30 #define XC_cross_reverse 32 #define XC_crosshair 34 #define XC_diamond_cross 36 #define XC_dot 38 #define XC_dotbox 40 #define XC_double_arrow 42 #define XC_draft_large 44 #define XC_draft_small 46 #define XC_draped_box 48 #define XC_exchange 50 #define XC_fleur 52 #define XC_gobbler 54 #define XC_gumby 56 #define XC_hand1 58 #define XC_hand2 60 #define XC_heart 62 #define XC_icon 64 #define XC_iron_cross 66 #define XC_left_ptr 68 #define XC_left_side 70 #define XC_left_tee 72 #define XC_leftbutton 74 #define XC_ll_angle 76 #define XC_lr_angle 78 #define XC_man 80 #define XC_middlebutton 82 #define XC_mouse 84 #define XC_pencil 86 #define XC_pirate 88 #define XC_plus 90 #define XC_question_arrow 92 #define XC_right_ptr 94 #define XC_right_side 96 #define XC_right_tee 98 #define XC_rightbutton 100 #define XC_rtl_logo 102 #define XC_sailboat 104 #define XC_sb_down_arrow 106 #define XC_sb_h_double_arrow 108 #define XC_sb_left_arrow 110 #define XC_sb_right_arrow 112 #define XC_sb_up_arrow 114 #define XC_sb_v_double_arrow 116 #define XC_shuttle 118 #define XC_sizing 120 #define XC_spider 122 #define XC_spraycan 124 #define XC_star 126 #define XC_target 128 #define XC_tcross 130 #define XC_top_left_arrow 132 #define XC_top_left_corner 134 #define XC_top_right_corner 136 #define XC_top_side 138 #define XC_top_tee 140 #define XC_trek 142 #define XC_ul_angle 144 #define XC_umbrella 146 #define XC_ur_angle 148 #define XC_watch 150 #define XC_xterm 152 �����������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/X11/keysym.h������������������������������������������������������������������0000644�0001750�0001750�00000002735�11462120063�015106� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $XConsortium: keysym.h,v 1.13 91/03/13 20:09:49 rws Exp $ */ /*********************************************************** Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ /* default keysyms */ #define XK_MISCELLANY #define XK_LATIN1 #define XK_LATIN2 #define XK_LATIN3 #define XK_LATIN4 #define XK_GREEK #ifdef MAC_TCL #include <keysymdef.h> #else #include <X11/keysymdef.h> #endif �����������������������������������./saods9/blt3.0.1/win/X11/Xatom.h�������������������������������������������������������������������0000644�0001750�0001750�00000004726�11462120063�014657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef XATOM_H #define XATOM_H 1 /* THIS IS A GENERATED FILE * * Do not change! Changing this file implies a protocol change! */ #define XA_PRIMARY ((Atom) 1) #define XA_SECONDARY ((Atom) 2) #define XA_ARC ((Atom) 3) #define XA_ATOM ((Atom) 4) #define XA_BITMAP ((Atom) 5) #define XA_CARDINAL ((Atom) 6) #define XA_COLORMAP ((Atom) 7) #define XA_CURSOR ((Atom) 8) #define XA_CUT_BUFFER0 ((Atom) 9) #define XA_CUT_BUFFER1 ((Atom) 10) #define XA_CUT_BUFFER2 ((Atom) 11) #define XA_CUT_BUFFER3 ((Atom) 12) #define XA_CUT_BUFFER4 ((Atom) 13) #define XA_CUT_BUFFER5 ((Atom) 14) #define XA_CUT_BUFFER6 ((Atom) 15) #define XA_CUT_BUFFER7 ((Atom) 16) #define XA_DRAWABLE ((Atom) 17) #define XA_FONT ((Atom) 18) #define XA_INTEGER ((Atom) 19) #define XA_PIXMAP ((Atom) 20) #define XA_POINT ((Atom) 21) #define XA_RECTANGLE ((Atom) 22) #define XA_RESOURCE_MANAGER ((Atom) 23) #define XA_RGB_COLOR_MAP ((Atom) 24) #define XA_RGB_BEST_MAP ((Atom) 25) #define XA_RGB_BLUE_MAP ((Atom) 26) #define XA_RGB_DEFAULT_MAP ((Atom) 27) #define XA_RGB_GRAY_MAP ((Atom) 28) #define XA_RGB_GREEN_MAP ((Atom) 29) #define XA_RGB_RED_MAP ((Atom) 30) #define XA_STRING ((Atom) 31) #define XA_VISUALID ((Atom) 32) #define XA_WINDOW ((Atom) 33) #define XA_WM_COMMAND ((Atom) 34) #define XA_WM_HINTS ((Atom) 35) #define XA_WM_CLIENT_MACHINE ((Atom) 36) #define XA_WM_ICON_NAME ((Atom) 37) #define XA_WM_ICON_SIZE ((Atom) 38) #define XA_WM_NAME ((Atom) 39) #define XA_WM_NORMAL_HINTS ((Atom) 40) #define XA_WM_SIZE_HINTS ((Atom) 41) #define XA_WM_ZOOM_HINTS ((Atom) 42) #define XA_MIN_SPACE ((Atom) 43) #define XA_NORM_SPACE ((Atom) 44) #define XA_MAX_SPACE ((Atom) 45) #define XA_END_SPACE ((Atom) 46) #define XA_SUPERSCRIPT_X ((Atom) 47) #define XA_SUPERSCRIPT_Y ((Atom) 48) #define XA_SUBSCRIPT_X ((Atom) 49) #define XA_SUBSCRIPT_Y ((Atom) 50) #define XA_UNDERLINE_POSITION ((Atom) 51) #define XA_UNDERLINE_THICKNESS ((Atom) 52) #define XA_STRIKEOUT_ASCENT ((Atom) 53) #define XA_STRIKEOUT_DESCENT ((Atom) 54) #define XA_ITALIC_ANGLE ((Atom) 55) #define XA_X_HEIGHT ((Atom) 56) #define XA_QUAD_WIDTH ((Atom) 57) #define XA_WEIGHT ((Atom) 58) #define XA_POINT_SIZE ((Atom) 59) #define XA_RESOLUTION ((Atom) 60) #define XA_COPYRIGHT ((Atom) 61) #define XA_NOTICE ((Atom) 62) #define XA_FONT_NAME ((Atom) 63) #define XA_FAMILY_NAME ((Atom) 64) #define XA_FULL_NAME ((Atom) 65) #define XA_CAP_HEIGHT ((Atom) 66) #define XA_WM_CLASS ((Atom) 67) #define XA_WM_TRANSIENT_FOR ((Atom) 68) #define XA_LAST_PREDEFINED ((Atom) 68) #endif /* XATOM_H */ ������������������������������������������./saods9/blt3.0.1/win/makedefs����������������������������������������������������������������������0000644�0001750�0001750�00000003202�11462120063�014533� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ENABLE_SYMBOLS=1 ENABLE_SHARED=1 ENABLE_STUBS=0 WITH_JPG=0 SRC = H:/src JPG_DIR = $(SRC)/libs/jpeg-6b WITH_PNG=0 PNG_DIR = $(SRC)/libs/libpng-1.2.15 ZLIB_DIR = $(SRC)/libs/zlib-1.2.3 WITH_TIF=0 WITH_EXPAT = 0 WITH_MYSQL = 0 #v1 = 8.4 #v2 = 84 #v3 = 8.4.0 v1 = 8.4 v2 = 84 v3 = 8.4.14 #v1 = 8.2 #v2 = 82 #v3 = 8.2.3 #v1 = 8.1 #v2 = 81 #v3 = 8.1.1 #v1 = 8.0 #v2 = 80 #v3 = 8.0.5 #Use Independent JPEG Group (IJG) library or Intel JPEG Library (IJL) # 0 = None. # 1 = IJG # 2 = IJL TCLDIR = $(SRC)/tcl/tcl$(v3) TKDIR = $(SRC)/tcl/tk$(v3) ifeq ($(WITH_JPG),1) JPG_LIB_SPEC = $(JPG_DIR)/libjpeg.lib JPG_INC_SPEC = -I$(JPG_DIR) JPG_DEFINES = -DHAVE_LIBJPG endif ifeq ($(WITH_PNG),1) PNG_LIB_SPEC = $(PNG_DIR)/libpng.lib $(ZLIB_DIR)/zlib.lib PNG_INC_SPEC = -I$(PNG_DIR) -I$(ZLIB_DIR) PNG_DEFINES = -DHAVE_LIBPNG endif ifeq ($(WITH_EXPAT),1) EXPAT_DIR = C:/Expat-2.0.0 EXPAT_INC_SPEC = -I$(EXPAT_DIR)/Source/lib EXPAT_LIB_SPEC = $(EXPAT_DIR)/Libs/libexpat.lib endif # ------------------------------------------------------------------------ # You shouldn't need to edit anything beyond this point # ------------------------------------------------------------------------ BLT_MAJOR_VERSION = 3 BLT_MINOR_VERSION = 0 BLT_VERSION = 3.0 prefix = C:/Program\ Files/Tcl exec_prefix = $(prefix) includedir = $(prefix)/include bindir = $(prefix)/bin libdir = $(prefix)/lib scriptdir = $(libdir)/blt$(BLT_VERSION) BLT_LIBRARY = $(libdir)/blt$(BLT_VERSION) TCLLIBPATH = $(libdir)/tcl$(v1) AUX_LIBS = SHLIB_SUFFIX = .dll INSTALL = install -m 0755 INSTALL_DATA = install -m 0444 RANLIB = : SHELL = bash.exe RM = rm -f ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/README.vc++�������������������������������������������������������������������0000644�0001750�0001750�00000005541�11462120063�014456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� How to build BLT with Microsoft VC++. This file describes how to build BLT under Windows 95/98/NT/2000/XP with Visual C++. For most, it's not necessary to compile BLT for Windows. If you have downloaded Tcl/Tk from www.tcltk.com or activestate then the precompiled binary versions on www.sourceforge.net should suffice. They are http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.0.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.1.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.2.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.3.exe -or- http://www.sourceforge.net/projects/blt/files/blt2.4z-for-8.4.exe Simply pick the one that matches the version of Tcl/Tk that you are using. Assuming the you need to build BLT from its sources, here is a short description. I. Requirements. ================ Visual C++ 5 or 6 I've tested building BLT with both these compilers Tcl/Tk sources You must have the sources to both Tcl and Tk available. II. Directory structure. ======================== The Tcl/Tk sources must be installed in the same directory and the BLT sources. The following is an example. ______________|______________ | | | | blt2.4 tcl8.3.4 tk8.3.4 jpeg-6b* * The JPEG library is optional. III. Building Tcl/Tk. ===================== You must first build the Tcl and Tk libraries. cd tcl8.3.4/win nmake -f Makefile.vc nmake -f Makefile.vc install cd ../../tk8.3.4/win nmake -f Makefile.vc nmake -f Makefile.vc install This will install Tcl/Tk into C:/Program Files/Tcl IV. Configuring BLT =================== In the BLT directory, edit ./win/makedefs. Set the following macros. v1 = 8.3 Tcl/Tk version. v2 = 83 Version number without dots. v3 = 8.3.4 Suffix of Tcl/Tk directories prefix = C:/Program\ Files/Tcl Location of installed Tcl/Tk files. TOOLS32 = C:/Program\ Files/Microsoft\ Visual\ Studio/VC90 Location of MS C compiler and tools. HAVE_JPEG = 0 Setting HAVE_JPEG to 0 eliminated the need for the JPEG library. V. Compiling BLT ================ If you have the Cygwin distribution, go into a bash shell and run make -f Makefile.vc from the blt2.4z directory. Otherwise (without cygwin) it's nmake -f blt.mak VI. Installing BLT ================== Again, if you have the Cygwin distribution, then run make -f Makefile.vc install Without cygwin, you must use the home-brew installer script with tclsh. tclsh8.3.exe win/install.tcl VII. Testing BLT ================ Add the location of BLT24.dll to your PATH variable. For example from the bash shell export PATH=/cygdrive/c/Program\ Files/Tcl/bin:$PATH cd demos bltwish.exe graph1.tcl ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/win/install.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000053150�11462120063�015212� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Script for installation of BLT under Windows # namespace eval Installer { variable commandList {} variable cmdLog {} variable component array set component { binaries 1 headers 1 html 1 scripts 1 demos 1 } variable totalBytes 0 variable totalFiles 0 variable panel 0 variable panelList { Welcome Directory Components Ready Finish } } proc Installer::DoInstall { package version } { global prefix srcdir regsub {\.} $version {} v2 variable scriptdir set scriptdir $prefix/lib/blt${version} variable component global tcl_platform if { $component(binaries) } { if { $tcl_platform(platform) == "unix" } { Add ${srcdir}/src -perm 0755 \ -file bltwish \ -file bltsh \ -rename "bltwish bltwish${v2}" \ -rename "bltsh bltsh${v2}" \ $prefix/bin set ext [info sharedlibextension] Add ${srcdir}/src -perm 0755 \ -file libBLT${v2}.a \ -file libBLTlite${v2}.a \ -file shared/libBLT${v2}${ext} \ -file shared/libBLTlite${v2}${ext} \ $prefix/lib } else { Add ${srcdir}/src -perm 0755 \ -file bltwish.exe \ -file bltsh.exe \ -file BLT${v2}.dll \ -file BLTlite${v2}.dll \ -rename "bltwish.exe bltwish${v2}.exe" \ -rename "bltsh.exe bltsh${v2}.exe" \ $prefix/bin Add ${srcdir}/src -perm 0755 \ -file BLT${v2}.lib \ -file BLTlite${v2}.lib \ $prefix/lib } } if { $component(headers) } { Add ${srcdir}/src \ -file blt.h \ -file bltChain.h \ -file bltVector.h \ -file bltTree.h \ $prefix/include } if { $component(html) } { Add ${srcdir}/html -pattern *.html $scriptdir/html } if { $component(scripts) } { Add ${srcdir} -file README -file PROBLEMS $scriptdir Add ${srcdir}/library \ -pattern *.cur \ -pattern *.tcl \ -pattern *.pro \ -file tclIndex \ $scriptdir Add ${srcdir}/library/dd_protocols \ -pattern *.tcl \ -file tclIndex \ $scriptdir/dd_protocols } if { $component(demos) } { Add ${srcdir}/demos \ -pattern *.tcl \ -file htext.txt \ $scriptdir/demos Add ${srcdir}/demos/bitmaps -pattern *.xbm $scriptdir/bitmaps Add ${srcdir}/demos/bitmaps/hand -pattern *.xbm $scriptdir/bitmaps/hand Add ${srcdir}/demos/bitmaps/fish -pattern *.xbm $scriptdir/bitmaps/fish Add ${srcdir}/demos/images \ -pattern *.gif \ -file out.ps \ $scriptdir/images Add ${srcdir}/demos/scripts -pattern *.tcl $scriptdir/scripts } Install $package $version } proc Installer::InstallDirectory { dest } { variable commandList lappend commandList [list CheckPath $dest] } proc Installer::Update { src dest size perm } { variable currentBytes variable totalBytes .install.text insert end "file copy -force $src $dest\n" if { [catch {file copy -force $src $dest} results] != 0 } { .install.text insert end "Error: $results\n" fail } else { incr currentBytes $size } global tcl_platform if { $tcl_platform(platform) == "unix" } { .install.text insert end "file attributes $dest -permissions $perm\n" if { [catch {file attributes $dest -permissions $perm} results] != 0 } { .install.text insert end "Error: $results\n" fail } } set percent [expr round(double($currentBytes)/$totalBytes * 100.0)] .install.current configure -text "$percent% complete" update } proc Installer::InstallFile { src dest perm } { variable commandList variable totalBytes variable totalFiles if { [catch { file size $src } size ] != 0 } { set size 0 } lappend commandList [list Update $src $dest $size $perm] incr totalBytes $size incr totalFiles } proc Installer::Add { dir args } { variable commandList variable totalBytes if { ![file exists $dir] } { error "can't find directory \"$dir\"" } set argc [llength $args] set destDir [lindex $args end] incr argc -2 set perm 0644 InstallDirectory $destDir foreach { option value } [lrange $args 0 $argc] { switch -- $option { "-pattern" { foreach f [lsort [glob $dir/$value]] { InstallFile $f $destDir/[file tail $f] $perm } } "-rename" { set src [lindex $value 0] set dest [lindex $value 1] InstallFile $dir/$src $destDir/$dest $perm } "-perm" { set perm $value } "-file" { InstallFile $dir/$value $destDir/$value $perm } default { error "Unknown option \"$option\"" } } } } proc Installer::CheckPath { dest } { set save [pwd] if { [file pathtype $dest] == "absolute" } { if { [string match {[a-zA-Z]:*} $dest] } { cd [string range $dest 0 2] set dest [string range $dest 3 end] } else { cd / set dest [string range $dest 1 end] } } set dirs [file split $dest] foreach d $dirs { if { ![file exists $d] } { .install.text insert end "file mkdir $d\n" if { [catch { file mkdir $d } result] != 0 } { .install.text insert end "Error: $result\n" fail break } } if { ![file isdirectory $d] } { .install.text insert end "Error: Not a directory: \"$d\"" fail break } update cd $d } cd $save } proc Installer::MakePackageIndex { package version file } { global prefix set suffix [info sharedlibextension] regsub {\.} $version {} version_no_dots set libName "${package}${version_no_dots}${suffix}" set libPath [file join ${prefix}/bin $libName] set cmd [list load $libPath $package] if { [file exists $file] } { file delete $file } set cmd { set fid [open $file "w"] puts $fid "# Package Index for $package" puts $fid "# generated on [clock format [clock seconds]]" puts $fid "" puts $fid [list package ifneeded $package $version $cmd] close $fid } if { [catch $cmd result] != 0 } { .install.text insert end "Error: $result\n" fail } } proc Installer::SetRegistryKey { package version valueName } { variable scriptdir global tcl_version package require registry set key HKEY_LOCAL_MACHINE\\Software\\$package\\$version\\$tcl_version registry set $key $valueName $scriptdir } proc Installer::Install { package version } { variable commandList variable totalBytes variable currentBytes 0 variable totalFiles variable scriptdir .install.totals configure -text "Files: $totalFiles Size: $totalBytes" foreach cmd $commandList { if { ![winfo exists .install] } { return } if { [catch $cmd result] != 0 } { .install.text insert end "Error: $result\n" fail } update } global tcl_version tcl_platform prefix set name [string tolower $package] MakePackageIndex $package $version $scriptdir/pkgIndex.tcl MakePackageIndex $package $version \ $prefix/lib/tcl${tcl_version}/${name}${version}/pkgIndex.tcl if { $tcl_platform(platform) == "windows" } { SetRegistryKey $package $version ${package}_LIBRARY } .install.cancel configure -text "Done" } proc Installer::Next {} { variable panel variable continue variable panelList incr panel set max [llength $panelList] if { $panel >= $max } { exit 0 } if { ($panel + 1) == $max } { .next configure -text "Finish" .cancel configure -state disabled } else { .next configure -text "Next" } if { $panel > 0 } { .back configure -state normal } set continue 1 } proc Installer::Back {} { variable panel variable continue incr panel -1 if { $panel <= 0 } { .back configure -state disabled set panel 0 } else { .back configure -state normal } .next configure -text "Next" .cancel configure -state normal set continue 0 } proc Installer::Cancel {} { exit 0 } if { $tcl_platform(platform) == "unix" } { font create textFont -family Helvetica -weight normal -size 11 font create titleFont -family Helvetica -weight normal -size 14 } else { font create titleFont -family Arial -weight bold -size 12 font create textFont -family Arial -weight normal -size 9 } font create hugeFont -family {Times New Roman} -size 18 -slant italic \ -weight bold proc Installer::MakeLink { widget tag command } { $widget tag configure $tag -foreground blue -underline yes $widget tag bind $tag <ButtonRelease-1> \ "$command; $widget tag configure $tag -foreground blue" $widget tag bind $tag <ButtonPress-1> \ [list $widget tag configure $tag -foreground red] } proc Installer::Welcome { package version } { global tcl_version if { [winfo exists .panel] } { destroy .panel } text .panel -wrap word -width 10 -height 18 \ -relief flat -padx 4 -pady 4 -cursor arrow \ -background [. cget -bg] .panel tag configure welcome -font titleFont -justify center \ -foreground navyblue .panel tag configure package -font hugeFont -foreground red \ -justify center MakeLink .panel next "Installer::Next" MakeLink .panel cancel "Installer::Cancel" .panel insert end "Welcome!\n" welcome .panel insert end "\n" .panel insert end \ "This installs the compiled \n" "" \ "${package} ${version}\n" package \ "binaries and components from the source directories to " "" \ "where Tcl/Tk is currently installed.\n\nThe compiled binaries " "" \ "require Tcl/Tk $tcl_version.\n\n" .panel insert end \ "Press the " "" \ "Next" next \ " button to continue. Press the " "" \ "Cancel" cancel \ " button if you do not wish to install $package at this time." .panel configure -state disabled blt::table . \ 0,1 .panel -columnspan 3 -pady 10 -padx { 0 10 } -fill x -anchor n tkwait variable Installer::continue } option add *Hierbox.openCommand {Installer::OpenDir %W "%P" %n} proc Installer::OpenDir { widget path atnode } { puts path=$path set save [pwd] global tcl_platform if { $tcl_platform(platform) == "windows" } { if { $path == "/" } { foreach v [file volumes] { if { ![string match {[A-B]:/} $v] } { .browser.h insert end $v -button yes } } return } set path [string trimleft $path /] } cd $path/ foreach dir [lsort [glob -nocomplain */ ]] { set node [$widget insert -at $atnode end $dir] # Does the directory have subdirectories? set subdirs [glob -nocomplain $dir/*/ ] if { $subdirs != "" } { $widget entry configure $node -button yes } else { $widget entry configure $node -button no } } cd $save } proc Installer::CenterPanel { panel } { update idletasks set x [expr ([winfo width .] - [winfo reqwidth $panel]) / 2] set y [expr ([winfo height .] - [winfo reqheight $panel]) / 2] incr x [winfo rootx .] incr y [winfo rooty .] wm geometry $panel +$x+$y wm deiconify $panel } proc Installer::Browse { } { if { [winfo exists .browser] } { raise .browser wm deiconify .browser return } toplevel .browser entry .browser.entry -bg white -borderwidth 2 -relief sunken \ -textvariable Installer::selection bind .browser.entry <KeyPress-Return> { .browser.ok flash .browser.ok invoke } blt::hierbox .browser.h -hideroot yes -separator / -height 1i -width 3i \ -borderwidth 2 -relief sunken -autocreate yes -trim / \ -yscrollcommand { .browser.sbar set } \ -selectcommand { set index [.browser.h curselection] set path [lindex [.browser.h get -full $index] 0] if { $tcl_platform(platform) == "windows" } { set path [string trimleft $path /] } puts $path set Installer::selection $path } scrollbar .browser.sbar -command { .browser.h yview } wm protocol .browser WM_DELETE_WINDOW { .browser.cancel invoke } wm transient .browser . frame .browser.sep -height 2 -borderwidth 1 -relief sunken button .browser.ok -text "Continue" -command { set prefix $Installer::selection grab release .browser destroy .browser } button .browser.cancel -text "Cancel" -command { grab release .browser destroy .browser } global tcl_platform global prefix if { $tcl_platform(platform) == "windows" } { set root "C:/" .browser.h open "C:/" .browser.h open "C:/Program Files" if { [file exists $prefix] } { .browser.h see $prefix/ } } else { set root /usr/local #.browser.h open $root } set Installer::selection $prefix wm title .browser "Installer: Select Install Directory" blt::table .browser \ 0,0 .browser.entry -fill x -columnspan 2 -padx 4 -pady 4 \ 1,0 .browser.h -fill both -columnspan 2 -padx 4 -pady { 0 4 } \ 1,2 .browser.sbar -fill y \ 2,0 .browser.sep -fill x -padx 10 -cspan 3 -pady { 4 0 } \ 3,0 .browser.ok -width .75i -padx 4 -pady 4 \ 3,1 .browser.cancel -width .75i -padx 4 -pady 4 blt::table configure .browser c2 r0 r2 r3 -resize none wm withdraw .browser after idle { Installer::CenterPanel .browser grab set .browser } } proc Installer::Directory { package version } { global tcl_version if { [winfo exists .panel] } { destroy .panel } frame .panel text .panel.text -wrap word -width 10 \ -height 10 -borderwidth 0 -padx 4 -pady 4 -cursor arrow \ -background [.panel cget -background] .panel.text tag configure title -font titleFont -justify center \ -foreground navyblue .panel.text insert end "Select Destination Directory\n" title .panel.text insert end "\n\n" .panel.text insert end "Please select the directory where Tcl/Tk \ $tcl_version is installed. This is also where $package $version will be \ installed.\n" .panel.text configure -state disabled frame .panel.frame -relief groove -borderwidth 2 label .panel.frame.label -textvariable ::prefix button .panel.frame.button -text "Browse..." -command Installer::Browse blt::table .panel.frame \ 0,0 .panel.frame.label -padx 4 -pady 4 -anchor w \ 0,1 .panel.frame.button -padx 4 -pady 4 -anchor e blt::table .panel \ 0,0 .panel.text -padx 4 -pady 4 -fill both \ 1,0 .panel.frame -padx 4 -fill x blt::table . \ 0,1 .panel -columnspan 3 -pady 10 -padx { 0 10 } -fill both tkwait variable Installer::continue } proc Installer::Components { package version } { global tcl_version if { [winfo exists .panel] } { destroy .panel } regsub {\.} $version {} v2 frame .panel text .panel.text -wrap word -width 10 \ -height 8 -borderwidth 0 -padx 4 -pady 4 -cursor arrow \ -background [.panel cget -background] .panel.text tag configure title -font titleFont -justify center \ -foreground navyblue .panel.text insert end "Select Components\n" title .panel.text insert end "\n\n" .panel.text insert end "Please select the components you wish to install. \ You should install all components.\n" .panel.text configure -state disabled frame .panel.frame -relief groove -borderwidth 2 variable component global tcl_platform if { $tcl_platform(platform) == "unix" } { set ext [info sharedlibextension] set sharedlib lib${package}${v2}${ext} set lib lib${package}${v2}.a set exe "" } else { set sharedlib ${package}${v2}.dll set lib ${package}${v2}.lib set exe ".exe" } checkbutton .panel.frame.binaries \ -text "bltwish${exe} and Shared Library" \ -variable Installer::component(binaries) checkbutton .panel.frame.scripts \ -text "Script Library" \ -variable Installer::component(scripts) checkbutton .panel.frame.headers \ -text "Include Files and Static Library" \ -variable Installer::component(headers) checkbutton .panel.frame.html -text "HTML Manual Pages" \ -variable Installer::component(html) checkbutton .panel.frame.demos -text "Demos" \ -variable Installer::component(demos) blt::table .panel.frame \ 0,0 .panel.frame.binaries -padx 4 -pady 4 -anchor w \ 1,0 .panel.frame.scripts -padx 4 -pady 4 -anchor w \ 2,0 .panel.frame.headers -padx 4 -pady 4 -anchor w \ 3,0 .panel.frame.html -padx 4 -pady 4 -anchor w \ 4,0 .panel.frame.demos -padx 4 -pady 4 -anchor w blt::table .panel \ 0,0 .panel.text -padx 4 -pady 4 -fill both \ 1,0 .panel.frame -padx 4 -fill both blt::table . \ 0,1 .panel -columnspan 3 -pady 10 -padx { 0 10 } -fill both tkwait variable Installer::continue } proc Installer::Ready { package version } { global tcl_version if { [winfo exists .panel] } { destroy .panel } text .panel -wrap word -width 10 -height 18 \ -relief flat -padx 4 -pady 4 -cursor arrow \ -background [. cget -bg] .panel tag configure welcome -font titleFont -justify center \ -foreground navyblue .panel tag configure package -font hugeFont -foreground red \ -justify center MakeLink .panel next "Installer::Next" MakeLink .panel cancel "Installer::Cancel" MakeLink .panel back "Installer::Back" .panel insert end "Ready To Install!\n" welcome .panel insert end "\n" .panel insert end "We're now ready to install ${package} ${version} \ and its components.\n\n" .panel insert end \ "Press the " "" \ "Next" next \ " button to install all selected components.\n\n" "" .panel insert end \ "To reselect components, click on the " "" \ "Back" back \ " button.\n\n" .panel insert end \ "Press the " "" \ "Cancel" cancel \ " button if you do not wish to install $package at this time." .panel configure -state disabled blt::table . \ 0,1 .panel -columnspan 3 -pady 10 -padx { 0 10 } -fill x -anchor n tkwait variable Installer::continue if { $Installer::continue } { Results update DoInstall $package $version } } proc Installer::Results { } { if { [winfo exists .install] } { destroy .install } toplevel .install text .install.text -height 10 -width 50 -wrap none -bg white \ -yscrollcommand { .install.ybar set } \ -xscrollcommand { .install.xbar set } .install.text tag configure fail -foreground red label .install.totals -text "Files: 0 Bytes: 0" -width 50 label .install.current -text "Installing:\n" -height 2 -width 50 scrollbar .install.ybar -command { .install.text yview } scrollbar .install.xbar -command { .install.text xview } -orient horizontal wm protocol .install WM_DELETE_WINDOW { .install.cancel invoke } wm transient .install . button .install.cancel -text "Cancel" -command { grab release .install destroy .install } blt::table .install \ 0,0 .install.totals -anchor w -columnspan 2 \ 1,0 .install.current -anchor w -cspan 2 \ 2,0 .install.text -fill both \ 2,1 .install.ybar -fill y \ 3,0 .install.xbar -fill x \ 4,0 .install.cancel -width .75i -padx 4 -pady 4 -cspan 2 blt::table configure .install c1 r0 r1 r3 -resize none wm withdraw .install after idle { Installer::CenterPanel .install grab set .install } } proc Installer::Finish { package version } { global tcl_version if { [winfo exists .panel] } { destroy .panel } text .panel -wrap word -width 10 -height 18 \ -relief flat -padx 4 -pady 4 -cursor arrow \ -background [. cget -bg] .panel tag configure welcome -font titleFont -justify center \ -foreground navyblue .panel tag configure package -font hugeFont -foreground red \ -justify center .panel insert end "Installation Completed\n" welcome .panel insert end "\n" .panel insert end "${package} ${version} is now installed.\n\n" MakeLink .panel finish "Installer::Next" .panel insert end \ "Press the " "" \ "Finish" finish \ " button to exit this installation" .panel configure -state disabled blt::table . \ 0,1 .panel -columnspan 3 -pady 10 -padx { 0 10 } -fill x -anchor n tkwait variable Installer::continue } set prefix [lindex $argv 2] set srcdir [lindex $argv 1] set version [lindex $argv 0] set version 2.4 set package BLT regsub {\.} $version {} v2 set ext [info sharedlibextension] if { $tcl_platform(platform) == "unix" } { set ext [info sharedlibextension] set sharedlib shared/lib${package}${v2}${ext} set prefix "/usr/local/blt" } else { set sharedlib ${package}${v2}.dll set prefix "C:/Program Files/Tcl" } if { [file exists ./src/$sharedlib] } { load ./src/$sharedlib $package } else { error "Can't find library \"$sharedlib\" to load" } set blt_library $srcdir/library image create photo openFolder -format gif -data { R0lGODlhEAANAPIAAAAAAH9/f7+/v///////AAAAAAAAAAAAACH+JEZpbGUgd3JpdHRlbiBi eSBBZG9iZSBQaG90b3Nob3CoIDUuMAAsAAAAABAADQAAAzk4Gsz6cIQ44xqCZCGbk4MmclAA gNs4ml7rEaxVAkKc3gTAnBO+sbyQT6M7gVQpk9HlAhgHzqhUmgAAOw== } image create photo closeFolder -format gif -data { R0lGODlhEAANAPIAAAAAAH9/f7+/v///AP///wAAAAAAAAAAACH+JEZpbGUgd3JpdHRlbiBi eSBBZG9iZSBQaG90b3Nob3CoIDUuMAAsAAAAABAADQAAAzNIGsz6kAQxqAjxzcpvc1KWBUDY nRQZWmilYi37EmztlrAt43R8mzrO60P8lAiApHK5TAAAOw== } image create photo blt -file ${srcdir}/demos/images/blt98.gif option add *Text.font textFont option add *HighlightThickness 0 option add *Hierbox.icons "closeFolder openFolder" option add *Hierbox.button yes set color \#accaff option add *Frame.background $color option add *Toplevel.background $color #option add *Button.background $color option add *Checkbutton.background $color option add *Label.background $color option add *Text.background $color . configure -bg $color wm title . "$package $version Installer" label .image -image blt -borderwidth 2 -relief groove button .back -text "Back" -state disabled -command Installer::Back -underline 0 button .next -text "Next" -command Installer::Next -underline 0 button .cancel -text "Cancel" -command Installer::Cancel -underline 0 frame .sep -height 2 -borderwidth 1 -relief sunken blt::table . \ 0,0 .image -fill both -padx 10 -pady 10 \ 1,0 .sep -fill x -padx 4 -pady 4 -columnspan 4 -padx 5 \ 2,1 .back -anchor e -padx 4 -pady 4 \ 2,2 .next -anchor w -padx 4 -pady 4 \ 2,3 .cancel -padx 20 -pady 4 blt::table configure . .back .next .cancel -width .75i blt::table configure . r1 r2 -resize none blt::table configure . r3 -height 0.125i while { 1 } { namespace eval Installer { variable panel set cmd [lindex $panelList $panel] eval [list $cmd $package $version] } update } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013676� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/treeview.cur��������������������������������������������������������������0000644�0001750�0001750�00000000506�11462120062�016250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �� ��0�����(��� ���@��������������������������������ÿÿÿ�����������������������������������������������������������������þ��2��2�� 2@�2`�)2P�O3È�€0�€0�O3È�)2P�2`� 2@�2��2��þ��ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿö¿ÿæŸÿÆÿ€�ÿ��ÿ��ÿ€�ÿÆÿæŸÿö¿ÿþÿÿþÿÿþÿÿ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/winButton.tcl�������������������������������������������������������������0000644�0001750�0001750�00000013773�11462120062�016412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������######################### # Windows implementation ######################### bind TkCheckbutton <equal> { blt::Button::CheckRadioInvoke %W select } bind TkCheckbutton <plus> { blt::Button::CheckRadioInvoke %W select } bind TkCheckbutton <minus> { blt::Button::CheckRadioInvoke %W deselect } bind TkCheckbutton <1> { blt::Button::CheckRadioDown %W } bind TkCheckbutton <ButtonRelease-1> { blt::Button::Up %W } bind TkCheckbutton <Enter> { blt::Button::CheckRadioEnter %W } bind TkRadiobutton <1> { blt::Button::CheckRadioDown %W } bind TkRadiobutton <ButtonRelease-1> { blt::Button::Up %W } bind TkRadiobutton <Enter> { blt::Button::CheckRadioEnter %W } bind TkPushbutton <equal> { blt::Button::CheckRadioInvoke %W select } bind TkPushbutton <plus> { blt::Button::CheckRadioInvoke %W select } bind TkPushbutton <minus> { blt::Button::CheckRadioInvoke %W deselect } bind TkPushbutton <1> { blt::Button::CheckRadioDown %W } bind TkPushbutton <ButtonRelease-1> { blt::Button::Up %W } bind TkPushbutton <Enter> { blt::Button::CheckRadioEnter %W } # Enter -- # # The procedure below is invoked when the mouse pointer enters a # button widget. It records the button we're in and changes the # state of the button to active unless the button is disabled. # # Arguments: # w - The name of the widget. proc ::blt::Button::Enter w { variable _private if {[$w cget -state] != "disabled"} { # If the mouse button is down, set the relief to sunken on entry. # Overwise, if there's an -overrelief value, set the relief to that. set _private($w,relief) [$w cget -relief] if { $_private(buttonWindow) == $w } { $w configure -relief sunken -state active set _private($w,prelief) sunken } elseif {[set over [$w cget -overrelief]] ne ""} { $w configure -relief $over set _private($w,prelief) $over } } set _private(window) $w } # Leave -- # The procedure below is invoked when the mouse pointer leaves a # button widget. It changes the state of the button back to inactive. # Restore any modified relief too. # # Arguments: # w - The name of the widget. proc ::blt::Button::Leave w { variable _private if {[$w cget -state] != "disabled"} { $w configure -state normal } # Restore the original button relief if it was changed by Tk. # That is signaled by the existence of _private($w,prelief). if { [info exists _private($w,relief)] } { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } set _private(window) "" } # Down -- # # The procedure below is invoked when the mouse button is pressed in # a button widget. It records the fact that the mouse is in the button, # saves the button's relief so it can be restored later, and changes # the relief to sunken. # # Arguments: # w - The name of the widget. proc ::blt::Button::Down w { variable _private # Only save the button's relief if it does not yet exist. If there # is an overrelief setting, Priv($w,relief) will already have been set, # and the current value of the -relief option will be incorrect. if {![info exists _private($w,relief)]} { set _private($w,relief) [$w cget -relief] } if {[$w cget -state] != "disabled"} { set _private(buttonWindow) $w $w configure -relief sunken -state active set _private($w,prelief) sunken # If this button has a repeatdelay set up, get it going with an after after cancel $_private(afterId) set delay [$w cget -repeatdelay] set _private(repeated) 0 if {$delay > 0} { set cmd [list blt::Button::AutoInvoke $w] set _private(afterId) [after $delay $cmd] } } } # Up -- # # The procedure below is invoked when the mouse button is released in # a button widget. It restores the button's relief and invokes the # command as long as the mouse hasn't left the button. # # Arguments: # w - The name of the widget. proc ::blt::Button::Up { w } { variable _private if { $_private(buttonWindow) == $w } { set _private(buttonWindow) "" # Restore the button's relief if it was cached. if { [info exists _private($w,relief)] } { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } # Clean up the after event from the auto-repeater after cancel $_private(afterId) if {$_private(window) eq $w && [$w cget -state] != "disabled"} { $w configure -state normal # Only invoke the command if it wasn't already invoked by the # auto-repeater functionality if { $_private(repeated) == 0 } { uplevel #0 [list $w invoke] } } } } # CheckRadioEnter -- # # The procedure below is invoked when the mouse pointer enters a # checkbutton or radiobutton widget. It records the button we're in # and changes the state of the button to active unless the button is # disabled. # # Arguments: # w - The name of the widget. proc ::blt::Button::CheckRadioEnter w { variable _private if { [$w cget -state] != "disabled" } { if { $_private(buttonWindow) == $w } { $w configure -state active } if {[set over [$w cget -overrelief]] ne ""} { set _private($w,relief) [$w cget -relief] set _private($w,prelief) $over $w configure -relief $over } } set _private(window) $w } # CheckRadioDown -- # # The procedure below is invoked when the mouse button is pressed in # a button widget. It records the fact that the mouse is in the button, # saves the button's relief so it can be restored later, and changes # the relief to sunken. # # Arguments: # w - The name of the widget. proc ::blt::Button::CheckRadioDown w { variable _private if {![info exists _private($w,relief)]} { set _private($w,relief) [$w cget -relief] } if {[$w cget -state] != "disabled"} { set _private(buttonWindow) $w set _private(repeated) 0 $w configure -state active } } } �����./saods9/blt3.0.1/library/scrollset.tcl�������������������������������������������������������������0000644�0001750�0001750�00000002011�11462120062�016412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� namespace eval blt { namespace eval Scrollset { #empty } } proc blt::Scrollset::ConfigureScrollbars { scrollset } { set xscrollbar [$scrollset cget -xscrollbar] set yscrollbar [$scrollset cget -yscrollbar] set slave [$scrollset cget -window] if { $slave != "" } { set yscrollcmd [$scrollset cget -yscrollcommand] if { $yscrollcmd == "" } { set yscrollcmd [list $slave yview] } if { [catch $yscrollcmd] == 0 } { $slave configure -yscrollcommand [list $scrollset set y] } set xscrollcmd [$scrollset cget -xscrollcommand] if { $xscrollcmd == "" } { set xscrollcmd [list $slave xview] } if { [catch $xscrollcmd] == 0 } { $slave configure -xscrollcommand [list $scrollset set x] } } if { $xscrollbar != "" } { $xscrollbar configure -command [list $scrollset xview] \ -orient horizontal -highlightthickness 0 } if { $yscrollbar != "" } { $yscrollbar configure -command [list $scrollset yview] \ -orient vertical -highlightthickness 0 } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/treeview.tcl��������������������������������������������������������������0000644�0001750�0001750�00000063115�11462120062�016246� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ====================================================================== # # treeview.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT treeview widget # ---------------------------------------------------------------------- # # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@lucent.com # http://www.tcltk.com/blt # # RCS: $Id: treeview.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ---------------------------------------------------------------------- # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== namespace eval ::blt::TreeView { variable _private array set _private { afterId -1 scroll 0 column "" space off x 0 y 0 } } image create picture ::blt::TreeView::openIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } image create picture ::blt::TreeView::closeIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } if { $tcl_platform(platform) == "windows" } { if { $tk_version >= 8.3 } { set cursor "@[file join $blt_library treeview.cur]" } else { set cursor "size_we" } option add *TreeView.ResizeCursor [list $cursor] } else { option add *TreeView.ResizeCursor \ "@$blt_library/treeview.xbm $blt_library/treeview_m.xbm black white" } # ---------------------------------------------------------------------- # # Initialize -- # # Invoked by internally by Treeview_Init routine. Initializes # the default bindings for the treeview widget entries. These # are local to the widget, so they can't be set through the # widget's class bind tags. # # ---------------------------------------------------------------------- proc blt::TreeView::Initialize { w } { variable _private # # Active entry bindings # $w bind Entry <Enter> { %W entry highlight current } $w bind Entry <Leave> { %W entry highlight "" } # # Button bindings # $w button bind all <ButtonRelease-1> { set index [%W nearest %x %y blt::TreeView::_private(who)] if { [%W index current] == $index && $blt::TreeView::_private(who) == "button" } { %W see -anchor nw current %W toggle current } } $w button bind all <Enter> { %W button highlight current } $w button bind all <Leave> { %W button highlight "" } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current entry. # 3. Sets the focus to this entry. # 4. Scrolls the entry into view. # 5. Sets the selection anchor to this entry, just in case # this is "multiple" mode. # $w bind Entry <ButtonPress-1> { blt::TreeView::SetSelectionAnchor %W current set blt::TreeView::_private(scroll) 1 } $w bind Entry <Double-ButtonPress-1> { if { ![%W cget -flat] } { %W toggle current } } # # B1-Motion # # For "multiple" mode only. Saves the current location of the # pointer for auto-scrolling. Resets the selection mark. # $w bind Entry <B1-Motion> { set blt::TreeView::_private(x) %x set blt::TreeView::_private(y) %y set index [%W nearest %x %y] if { [%W cget -selectmode] == "multiple" } { %W selection mark $index } else { blt::TreeView::SetSelectionAnchor %W $index } } # # ButtonRelease-1 # # For "multiple" mode only. # $w bind Entry <ButtonRelease-1> { if { [%W cget -selectmode] == "multiple" } { %W selection anchor current } after cancel $blt::TreeView::_private(afterId) set blt::TreeView::_private(afterId) -1 set blt::TreeView::_private(scroll) 0 } # # Shift-ButtonPress-1 # # For "multiple" mode only. # $w bind Entry <Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == -1 } { %W selection anchor current } set index [%W index anchor] %W selection clearall %W selection set $index current } else { blt::TreeView::SetSelectionAnchor %W current } } $w bind Entry <Shift-Double-ButtonPress-1> { # do nothing } $w bind Entry <Shift-B1-Motion> { # do nothing } $w bind Entry <Shift-ButtonRelease-1> { after cancel $blt::TreeView::_private(afterId) set blt::TreeView::_private(afterId) -1 set blt::TreeView::_private(scroll) 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # $w bind Entry <Control-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" } { set index [%W index current] %W selection toggle $index %W selection anchor $index } else { blt::TreeView::SetSelectionAnchor %W current } } $w bind Entry <Control-Double-ButtonPress-1> { # do nothing } $w bind Entry <Control-B1-Motion> { # do nothing } $w bind Entry <Control-ButtonRelease-1> { after cancel $blt::TreeView::_private(afterId) set blt::TreeView::_private(afterId) -1 set blt::TreeView::_private(scroll) 0 } $w bind Entry <Control-Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == -1 } { %W selection anchor current } if { [%W selection includes anchor] } { %W selection set anchor current } else { %W selection clear anchor current %W selection set current } } else { blt::TreeView::SetSelectionAnchor %W current } } $w bind Entry <Control-Shift-Double-ButtonPress-1> { # do nothing } $w bind Entry <Control-Shift-B1-Motion> { # do nothing } $w bind Entry <ButtonRelease-3> { blt::TreeView::EditColumn %W %X %Y } $w column bind all <Enter> { %W column highlight [%W column current] } $w column bind all <Leave> { %W column highlight "" } $w column bind Rule <Enter> { %W column highlight [%W column current] %W column resize activate [%W column current] } $w column bind Rule <Leave> { %W column highlight "" %W column resize activate "" } $w column bind Rule <ButtonPress-1> { %W column resize anchor %x } $w column bind Rule <B1-Motion> { %W column resize mark %x } $w column bind Rule <ButtonRelease-1> { %W column configure [%W column current] -width [%W column resize set] } $w column bind all <ButtonPress-1> { set blt::TreeView::_private(column) [%W column current] %W column configure $blt::TreeView::_private(column) \ -titlerelief sunken } $w column bind all <ButtonRelease-1> { set column [%W column current] if { $column != "" } { %W column invoke $column } %W column configure $blt::TreeView::_private(column) \ -titlerelief raised } # $w bind TextBoxStyle <ButtonPress-3> { # puts stderr "widget bind buttonpress-3 %W %X %Y" # if { [%W edit -root -test %X %Y] } { # break # } # } # $w bind TextBoxStyle <ButtonRelease-3> { # if { [%W edit -root -test %X %Y] } { # blt::TreeView::EditColumn %W %X %Y # break # } # } $w bind CheckBoxStyle <Enter> { if { [%W column cget [%W column current] -edit] } { %W style activate current [%W column current] } } $w bind CheckBoxStyle <Leave> { %W style activate "" } $w bind CheckBoxStyle <ButtonPress-1> { if { [%W column cget [%W column current] -edit] } { break } } $w bind CheckBoxStyle <B1-Motion> { if { [%W column cget [%W column current] -edit] } { break } } $w bind CheckBoxStyle <ButtonRelease-1> { if { [%W edit -root -test %X %Y] } { %W edit -root %X %Y break } } $w bind ComboBoxStyle <Enter> { if { [%W column cget [%W column current] -edit] } { %W style activate current [%W column current] } } $w bind ComboBoxStyle <Leave> { %W style activate "" } $w bind ComboBoxStyle <ButtonPress-1> { if { [%W column cget [%W column current] -edit] } { break } } $w bind ComboBoxStyle <ButtonRelease-1> { if { [%W edit -root -test %X %Y] } { %W edit -root %X %Y break } } } # ---------------------------------------------------------------------- # # AutoScroll -- # # Invoked when the user is selecting elements in a treeview # widget and drags the mouse pointer outside of the widget. # Scrolls the view in the direction of the pointer. # # ---------------------------------------------------------------------- proc blt::TreeView::AutoScroll { w } { variable _private if { ![winfo exists $w] } { return } set x $_private(x) set y $_private(y) set index [$w nearest $x $y] if {$y >= [winfo height $w]} { $w yview scroll 1 units set neighbor down } elseif {$y < 0} { $w yview scroll -1 units set neighbor up } else { set neighbor $index } if { [$w cget -selectmode] == "single" } { SetSelectionAnchor $w $neighbor } else { $w selection mark $index } set _private(afterId) [after 50 blt::TreeView::AutoScroll $w] } proc blt::TreeView::SetSelectionAnchor { w tagOrId } { set index [$w index $tagOrId] $w selection clearall $w see $index $w focus $index $w selection set $index $w selection anchor $index } # ---------------------------------------------------------------------- # # MoveFocus -- # # Invoked by KeyPress bindings. Moves the active selection to # the entry <where>, which is an index such as "up", "down", # "prevsibling", "nextsibling", etc. # # ---------------------------------------------------------------------- proc blt::TreeView::MoveFocus { w tagOrId } { catch {$w focus $tagOrId} if { [$w cget -selectmode] == "single" } { $w selection clearall $w selection set focus $w selection anchor focus } $w see focus } # ---------------------------------------------------------------------- # # MovePage -- # # Invoked by KeyPress bindings. Pages the current view up or # down. The <where> argument should be either "top" or # "bottom". # # ---------------------------------------------------------------------- proc blt::TreeView::MovePage { w where } { # If the focus is already at the top/bottom of the window, we want # to scroll a page. It's really one page minus an entry because we # want to see the last entry on the next/last page. if { [$w index focus] == [$w index view.$where] } { if {$where == "top"} { $w yview scroll -1 pages $w yview scroll 1 units } else { $w yview scroll 1 pages $w yview scroll -1 units } } update # Adjust the entry focus and the view. Also activate the entry. # just in case the mouse point is not in the widget. $w entry highlight view.$where $w focus view.$where $w see view.$where if { [$w cget -selectmode] == "single" } { $w selection clearall $w selection set focus } } # ---------------------------------------------------------------------- # # NextMatch -- # # Invoked by KeyPress bindings. Searches for an entry that # starts with the letter <char> and makes that entry active. # # ---------------------------------------------------------------------- proc blt::TreeView::NextMatch { w key } { if {[string match {[ -~]} $key]} { set last [$w index focus] if { $last == -1 } { return; # No focus. } set next [$w index next] if { $next == -1 } { set next $last } while { $next != $last } { set label [$w entry cget $next -label] set label [string index $label 0] if { [string tolower $label] == [string tolower $key] } { break } set next [$w index -at $next next] } $w focus $next if {[$w cget -selectmode] == "single"} { $w selection clearall $w selection set focus } $w see focus } } #------------------------------------------------------------------------ # # InsertText -- # # Inserts a text string into an entry at the insertion cursor. # If there is a selection in the entry, and it covers the point # of the insertion cursor, then delete the selection before # inserting. # # Arguments: # w Widget where to insert the text. # text Text string to insert (usually just a single character) # #------------------------------------------------------------------------ proc blt::TreeView::InsertText { w text } { if { [string length $text] > 0 } { set index [$w index insert] if { ($index >= [$w index sel.first]) && ($index <= [$w index sel.last]) } { $w delete sel.first sel.last } $w insert $index $text } } #------------------------------------------------------------------------ # # Transpose - # # This procedure implements the "transpose" function for entry # widgets. It tranposes the characters on either side of the # insertion cursor, unless the cursor is at the end of the line. # In this case it transposes the two characters to the left of # the cursor. In either case, the cursor ends up to the right # of the transposed characters. # # Arguments: # w The entry window. # #------------------------------------------------------------------------ proc blt::TreeView::Transpose { w } { set i [$w index insert] if {$i < [$w index end]} { incr i } set first [expr {$i-2}] if {$first < 0} { return } set new [string index [$w get] [expr {$i-1}]][string index [$w get] $first] $w delete $first $i $w insert insert $new } #------------------------------------------------------------------------ # # GetSelection -- # # Returns the selected text of the entry with respect to the # -show option. # # Arguments: # w Entry window from which the text to get # #------------------------------------------------------------------------ proc blt::TreeView::GetSelection { w } { set text [string range [$w get] [$w index sel.first] \ [expr [$w index sel.last] - 1]] if {[$w cget -show] != ""} { regsub -all . $text [string index [$w cget -show] 0] text } return $text } proc blt::TreeView::EditColumn { w x y } { $w see current if { [winfo exists $w.edit] } { destroy $w.edit return } if { ![$w edit -root -test $x $y] } { return } $w edit -root $x $y update if { [winfo exists $w.edit] } { focus $w.edit $w.edit selection range 0 end grab set $w.edit tkwait window $w.edit grab release $w.edit } } # # ButtonPress assignments # # B1-Enter start auto-scrolling # B1-Leave stop auto-scrolling # ButtonPress-2 start scan # B2-Motion adjust scan # ButtonRelease-2 stop scan # bind TreeView <ButtonPress-2> { set blt::TreeView::_private(cursor) [%W cget -cursor] %W configure -cursor hand1 %W scan mark %x %y } bind TreeView <B2-Motion> { %W scan dragto %x %y } bind TreeView <ButtonRelease-2> { %W configure -cursor $blt::TreeView::_private(cursor) } bind TreeView <B1-Leave> { if { $blt::TreeView::_private(scroll) } { blt::TreeView::AutoScroll %W } } bind TreeView <B1-Enter> { after cancel $blt::TreeView::_private(afterId) set blt::TreeView::_private(afterId) -1 } # # KeyPress assignments # # Up # Down # Shift-Up # Shift-Down # Prior (PageUp) # Next (PageDn) # Left # Right # space Start selection toggle of entry currently with focus. # Return Start selection toggle of entry currently with focus. # Home # End # F1 # F2 # ASCII char Go to next open entry starting with character. # # KeyRelease # # space Stop selection toggle of entry currently with focus. # Return Stop selection toggle of entry currently with focus. bind TreeView <KeyPress-Up> { blt::TreeView::MoveFocus %W up if { $blt::TreeView::_private(space) } { %W selection toggle focus } } bind TreeView <KeyPress-Down> { blt::TreeView::MoveFocus %W down if { $blt::TreeView::_private(space) } { %W selection toggle focus } } bind TreeView <Shift-KeyPress-Up> { blt::TreeView::MoveFocus %W prevsibling } bind TreeView <Shift-KeyPress-Down> { blt::TreeView::MoveFocus %W nextsibling } bind TreeView <KeyPress-Prior> { blt::TreeView::MovePage %W top } bind TreeView <KeyPress-Next> { blt::TreeView::MovePage %W bottom } bind TreeView <KeyPress-Left> { %W close focus } bind TreeView <KeyPress-Right> { %W open focus %W see focus -anchor w } bind TreeView <KeyPress-space> { if { [%W cget -selectmode] == "single" } { if { [%W selection includes focus] } { %W selection clearall } else { %W selection clearall %W selection set focus } } else { %W selection toggle focus } set blt::TreeView::_private(space) on } bind TreeView <KeyRelease-space> { set blt::TreeView::_private(space) off } bind TreeView <KeyPress-Return> { blt::TreeView::MoveFocus %W focus set blt::TreeView::_private(space) on } bind TreeView <KeyRelease-Return> { set blt::TreeView::_private(space) off } bind TreeView <KeyPress> { blt::TreeView::NextMatch %W %A } bind TreeView <KeyPress-Home> { blt::TreeView::MoveFocus %W top } bind TreeView <KeyPress-End> { blt::TreeView::MoveFocus %W bottom } bind TreeView <KeyPress-F1> { %W open -r root } bind TreeView <KeyPress-F2> { eval %W close -r [%W entry children root] } if {[string equal "x11" [tk windowingsystem]]} { bind TreeView <4> { %W yview scroll -5 units } bind TreeView <5> { %W yview scroll 5 units } } else { bind TreeView <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } } # # Differences between id "current" and operation nearest. # # set index [$w index current] # set index [$w nearest $x $y] # # o Nearest gives you the closest entry. # o current is "" if # 1) the pointer isn't over an entry. # 2) the pointer is over a open/close button. # 3) # # # Edit mode assignments # # ButtonPress-3 Enables/disables edit mode on entry. Sets focus to # entry. # # KeyPress # # Left Move insertion position to previous. # Right Move insertion position to next. # Up Move insertion position up one line. # Down Move insertion position down one line. # Return End edit mode. # Shift-Return Line feed. # Home Move to first position. # End Move to last position. # ASCII char Insert character left of insertion point. # Del Delete character right of insertion point. # Delete Delete character left of insertion point. # Ctrl-X Cut # Ctrl-V Copy # Ctrl-P Paste # # KeyRelease # # ButtonPress-1 Start selection if in entry, otherwise clear selection. # B1-Motion Extend/reduce selection. # ButtonRelease-1 End selection if in entry, otherwise use last # selection. # B1-Enter Disabled. # B1-Leave Disabled. # ButtonPress-2 Same as above. # B2-Motion Same as above. # ButtonRelease-2 Same as above. # # # Standard Motif bindings: bind TreeViewEditor <ButtonPress-1> { %W icursor @%x,%y %W selection clear } bind TreeViewEditor <Left> { %W icursor last %W selection clear } bind TreeViewEditor <Right> { %W icursor next %W selection clear } bind TreeViewEditor <Shift-Left> { set new [expr {[%W index insert] - 1}] if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind TreeViewEditor <Shift-Right> { set new [expr {[%W index insert] + 1}] if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind TreeViewEditor <Home> { %W icursor 0 %W selection clear } bind TreeViewEditor <Shift-Home> { set new 0 if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind TreeViewEditor <End> { %W icursor end %W selection clear } bind TreeViewEditor <Shift-End> { set new end if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind TreeViewEditor <Delete> { if { [%W selection present]} { %W delete sel.first sel.last } else { %W delete insert } } bind TreeViewEditor <BackSpace> { if { [%W selection present] } { %W delete sel.first sel.last } else { set index [expr [%W index insert] - 1] if { $index >= 0 } { %W delete $index $index } } } bind TreeViewEditor <Control-space> { %W selection from insert } bind TreeViewEditor <Select> { %W selection from insert } bind TreeViewEditor <Control-Shift-space> { %W selection adjust insert } bind TreeViewEditor <Shift-Select> { %W selection adjust insert } bind TreeViewEditor <Control-slash> { %W selection range 0 end } bind TreeViewEditor <Control-backslash> { %W selection clear } bind TreeViewEditor <KeyPress> { blt::TreeView::InsertText %W %A } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Escape, Return, and Tab. bind TreeViewEditor <Alt-KeyPress> { # nothing } bind TreeViewEditor <Meta-KeyPress> { # nothing } bind TreeViewEditor <Control-KeyPress> { # nothing } bind TreeViewEditor <Escape> { %W cancel } bind TreeViewEditor <Return> { %W apply } bind TreeViewEditor <Shift-Return> { blt::TreeView::InsertText %W "\n" } bind TreeViewEditor <KP_Enter> { # nothing } bind TreeViewEditor <Tab> { # nothing } if {![string compare $tcl_platform(platform) "macintosh"]} { bind TreeViewEditor <Command-KeyPress> { # nothing } } # On Windows, paste is done using Shift-Insert. Shift-Insert already # generates the <<Paste>> event, so we don't need to do anything here. if { [string compare $tcl_platform(platform) "windows"] != 0 } { bind TreeViewEditor <Insert> { catch {blt::TreeView::InsertText %W [selection get -displayof %W]} } } # Additional emacs-like bindings: bind TreeViewEditor <ButtonRelease-3> { set parent [winfo parent %W] %W cancel } bind TreeViewEditor <Control-a> { %W icursor 0 %W selection clear } bind TreeViewEditor <Control-b> { %W icursor [expr {[%W index insert] - 1}] %W selection clear } bind TreeViewEditor <Control-d> { %W delete insert } bind TreeViewEditor <Control-e> { %W icursor end %W selection clear } bind TreeViewEditor <Control-f> { %W icursor [expr {[%W index insert] + 1}] %W selection clear } bind TreeViewEditor <Control-h> { if {[%W selection present]} { %W delete sel.first sel.last } else { set index [expr [%W index insert] - 1] if { $index >= 0 } { %W delete $index $index } } } bind TreeViewEditor <Control-k> { %W delete insert end } if 0 { bind TreeViewEditor <Control-t> { blt::TreeView::Transpose %W } bind TreeViewEditor <Meta-b> { %W icursor [blt::TreeView::PreviousWord %W insert] %W selection clear } bind TreeViewEditor <Meta-d> { %W delete insert [blt::TreeView::NextWord %W insert] } bind TreeViewEditor <Meta-f> { %W icursor [blt::TreeView::NextWord %W insert] %W selection clear } bind TreeViewEditor <Meta-BackSpace> { %W delete [blt::TreeView::PreviousWord %W insert] insert } bind TreeViewEditor <Meta-Delete> { %W delete [blt::TreeView::PreviousWord %W insert] insert } # tkEntryNextWord -- Returns the index of the next word position # after a given position in the entry. The next word is platform # dependent and may be either the next end-of-word position or the # next start-of-word position after the next end-of-word position. # # Arguments: # w - The entry window in which the cursor is to move. # start - Position at which to start search. if {![string compare $tcl_platform(platform) "windows"]} { proc blt::TreeView::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos >= 0} { set pos [tcl_startOfNextWord [$w get] $pos] } if {$pos < 0} { return end } return $pos } } else { proc blt::TreeView::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos < 0} { return end } return $pos } } # PreviousWord -- # # Returns the index of the previous word position before a given # position in the entry. # # Arguments: # w - The entry window in which the cursor is to move. # start - Position at which to start search. proc blt::TreeView::PreviousWord {w start} { set pos [tcl_startOfPreviousWord [$w get] [$w index $start]] if {$pos < 0} { return 0 } return $pos } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/bltCanvEps.pro������������������������������������������������������������0000644�0001750�0001750�00000004345�11462120062�016473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% % PostScript encapulator prolog file of the BLT "eps" canvas item. % % Copyright 1991-1997 Bell Labs Innovations for Lucent Technologies. % % Permission to use, copy, modify, and distribute this software and its % documentation for any purpose and without fee is hereby granted, provided % that the above copyright notice appear in all copies and that both that the % copyright notice and warranty disclaimer appear in supporting documentation, % and that the names of Lucent Technologies any of their entities not be used % in advertising or publicity pertaining to distribution of the software % without specific, written prior permission. % % Lucent Technologies disclaims all warranties with regard to this software, % including all implied warranties of merchantability and fitness. In no event % shall Lucent Technologies be liable for any special, indirect or % consequential damages or any damages whatsoever resulting from loss of use, % data or profits, whether in an action of contract, negligence or other % tortuous action, arising out of or in connection with the use or performance % of this software. % % % The definitions of the next two macros are from Appendix H of % Adobe's "PostScript Language Reference Manual" pp. 709-736. % % Prepare for EPS file /BeginEPSF { /beforeInclusionState save def /dictCount countdictstack def % Save the # objects in the dictionary /opCount count 1 sub def % Count object on operator stack userdict begin % Make "userdict" the current % dictionary /showpage {} def % Redefine showpage to be null 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit [] 0 setdash newpath /languagellevel where { pop languagelevel 1 ne { false setstrokeadjust false setoverprint } if } if % note: no "end" } bind def /EndEPSF { %def count opCount sub { pop } repeat countdictstack dictCount sub { end % Clean up dictionary stack } repeat beforeInclusionState restore } bind def % % Set up a clip region based upon a bounding box (x1, y1, x2, y2). % /SetClipRegion { % Stack: x1 y1 x2 y2 newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath clip newpath } def �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/unixButton.tcl������������������������������������������������������������0000644�0001750�0001750�00000010633�11462120062�016570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ##################### # Unix implementation ##################### bind TkCheckbutton <Return> { if {!$tk_strictMotif} { blt::Button::CheckRadioInvoke %W } } bind TkRadiobutton <Return> { if {!$tk_strictMotif} { blt::Button::CheckRadioInvoke %W } } bind TkPushbutton <Return> { if {!$tk_strictMotif} { blt::Button::CheckRadioInvoke %W } } bind TkCheckbutton <1> { blt::Button::CheckRadioInvoke %W } bind TkRadiobutton <1> { blt::Button::CheckRadioInvoke %W } bind TkPushbutton <1> { blt::Button::CheckRadioInvoke %W } bind TkCheckbutton <Enter> { blt::Button::Enter %W } bind TkRadiobutton <Enter> { blt::Button::Enter %W } bind TkPushbutton <Enter> { blt::Button::Enter %W } # Enter -- # # The procedure below is invoked when the mouse pointer enters a # button widget. It records the button we're in and changes the # state of the button to active unless the button is disabled. # # Arguments: # w - The name of the widget. proc ::blt::Button::Enter {w} { variable _private if { [$w cget -state] != "disabled" } { # On unix the state is active just with mouse-over $w configure -state active # If the mouse button is down, set the relief to sunken on entry. # Overwise, if there's an -overrelief value, set the relief to that. set _private($w,relief) [$w cget -relief] if {$_private(buttonWindow) eq $w} { $w configure -relief sunken set _private($w,prelief) sunken } elseif {[set over [$w cget -overrelief]] ne ""} { $w configure -relief $over set _private($w,prelief) $over } } set _private(window) $w } # Leave -- # # The procedure below is invoked when the mouse pointer leaves a # button widget. It changes the state of the button back to inactive. # Restore any modified relief too. # # Arguments: # w - The name of the widget. proc ::blt::Button::Leave w { variable _private if {[$w cget -state] != "disabled"} { $w configure -state normal } # Restore the original button relief if it was changed by Tk. # That is signaled by the existence of _private($w,prelief). if {[info exists _private($w,relief)]} { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } set _private(window) "" } # Down -- # # The procedure below is invoked when the mouse button is pressed in # a button widget. It records the fact that the mouse is in the button, # saves the button's relief so it can be restored later, and changes # the relief to sunken. # # Arguments: # w - The name of the widget. proc ::blt::Button::Down w { variable _private # Only save the button's relief if it does not yet exist. If there # is an overrelief setting, Priv($w,relief) will already have been set, # and the current value of the -relief option will be incorrect. if {![info exists _private($w,relief)]} { set _private($w,relief) [$w cget -relief] } if {[$w cget -state] != "disabled"} { set _private(buttonWindow) $w $w configure -relief sunken set _private($w,prelief) sunken # If this button has a repeatdelay set up, get it going with an after after cancel $_private(afterId) set delay [$w cget -repeatdelay] set _private(repeated) 0 if {$delay > 0} { set cmd [list blt::Button::AutoInvoke $w] set _private(afterId) [after $delay $cmd] } } } # Up -- # # The procedure below is invoked when the mouse button is released # in a button widget. It restores the button's relief and invokes # the command as long as the mouse hasn't left the button. # # Arguments: # w - The name of the widget. proc ::blt::Button::Up w { variable _private if {$w eq $_private(buttonWindow)} { set _private(buttonWindow) "" # Restore the button's relief if it was cached. if {[info exists _private($w,relief)]} { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } # Clean up the after event from the auto-repeater after cancel $_private(afterId) if {$_private(window) eq $w && [$w cget -state] != "disabled"} { # Only invoke the command if it wasn't already invoked by the # auto-repeater functionality if { $_private(repeated) == 0 } { uplevel #0 [list $w invoke] } } } } �����������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/hierbox.tcl���������������������������������������������������������������0000644�0001750�0001750�00000032447�11462120062�016060� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # hierbox.tcl # ---------------------------------------------------------------------- # Bindings for the BLT hierbox widget # ---------------------------------------------------------------------- # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@lucent.com # http://www.tcltk.com/blt # # RCS: $Id: hierbox.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ====================================================================== # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== array set bltHierbox { afterId "" scroll 0 space off x 0 y 0 } catch { namespace eval blt::Hierbox {} } # # ButtonPress assignments # # B1-Enter start auto-scrolling # B1-Leave stop auto-scrolling # ButtonPress-2 start scan # B2-Motion adjust scan # ButtonRelease-2 stop scan # bind Hierbox <ButtonPress-2> { set bltHierbox(cursor) [%W cget -cursor] %W configure -cursor hand1 %W scan mark %x %y } bind Hierbox <B2-Motion> { %W scan dragto %x %y } bind Hierbox <ButtonRelease-2> { %W configure -cursor $bltHierbox(cursor) } bind Hierbox <B1-Leave> { if { $bltHierbox(scroll) } { blt::Hierbox::AutoScroll %W } } bind Hierbox <B1-Enter> { after cancel $bltHierbox(afterId) } # # KeyPress assignments # # Up # Down # Shift-Up # Shift-Down # Prior (PageUp) # Next (PageDn) # Left # Right # space Start selection toggle of entry currently with focus. # Return Start selection toggle of entry currently with focus. # Home # End # F1 # F2 # ASCII char Go to next open entry starting with character. # # KeyRelease # # space Stop selection toggle of entry currently with focus. # Return Stop selection toggle of entry currently with focus. bind Hierbox <KeyPress-Up> { blt::Hierbox::MoveFocus %W up if { $bltHierbox(space) } { %W selection toggle focus } } bind Hierbox <KeyPress-Down> { blt::Hierbox::MoveFocus %W down if { $bltHierbox(space) } { %W selection toggle focus } } bind Hierbox <Shift-KeyPress-Up> { blt::Hierbox::MoveFocus %W prevsibling } bind Hierbox <Shift-KeyPress-Down> { blt::Hierbox::MoveFocus %W nextsibling } bind Hierbox <KeyPress-Prior> { blt::Hierbox::MovePage %W top } bind Hierbox <KeyPress-Next> { blt::Hierbox::MovePage %W bottom } bind Hierbox <KeyPress-Left> { %W close focus } bind Hierbox <KeyPress-Right> { %W open focus %W see focus -anchor w } bind Hierbox <KeyPress-space> { blt::HierboxToggle %W focus set bltHierbox(space) on } bind Hierbox <KeyRelease-space> { set bltHierbox(space) off } bind Hierbox <KeyPress-Return> { blt::HierboxToggle %W focus set bltHierbox(space) on } bind Hierbox <KeyRelease-Return> { set bltHierbox(space) off } bind Hierbox <KeyPress> { blt::Hierbox::NextMatchingEntry %W %A } bind Hierbox <KeyPress-Home> { blt::Hierbox::MoveFocus %W root } bind Hierbox <KeyPress-End> { blt::Hierbox::MoveFocus %W end } bind Hierbox <KeyPress-F1> { %W open -r root } bind Hierbox <KeyPress-F2> { eval %W close -r [%W entry children root 0 end] } # ---------------------------------------------------------------------- # USAGE: blt::HierboxToggle <hierbox> <index> # Arguments: hierbox hierarchy widget # # Invoked when the user presses the space bar. Toggles the selection # for the entry at <index>. # ---------------------------------------------------------------------- proc blt::HierboxToggle { widget index } { switch -- [$widget cget -selectmode] { single { if { [$widget selection includes $index] } { $widget selection clearall } else { $widget selection set $index } } multiple { $widget selection toggle $index } } } # ---------------------------------------------------------------------- # USAGE: blt::Hierbox::MovePage <hierbox> <where> # Arguments: hierbox hierarchy widget # # Invoked by KeyPress bindings. Pages the current view up or down. # The <where> argument should be either "top" or "bottom". # ---------------------------------------------------------------------- proc blt::Hierbox::MovePage { widget where } { # If the focus is already at the top/bottom of the window, we want # to scroll a page. It's really one page minus an entry because we # want to see the last entry on the next/last page. if { [$widget index focus] == [$widget index view.$where] } { if {$where == "top"} { $widget yview scroll -1 pages $widget yview scroll 1 units } else { $widget yview scroll 1 pages $widget yview scroll -1 units } } update # Adjust the entry focus and the view. Also activate the entry. # just in case the mouse point is not in the widget. $widget entry highlight view.$where $widget focus view.$where $widget see view.$where if { [$widget cget -selectmode] == "single" } { $widget selection clearall $widget selection set focus } } # # Edit mode assignments # # ButtonPress-3 Enables/disables edit mode on entry. Sets focus to # entry. # # KeyPress # # Left Move insertion position to previous. # Right Move insertion position to next. # Up Move insertion position up one line. # Down Move insertion position down one line. # Return End edit mode. # Shift-Return Line feed. # Home Move to first position. # End Move to last position. # ASCII char Insert character left of insertion point. # Del Delete character right of insertion point. # Delete Delete character left of insertion point. # Ctrl-X Cut # Ctrl-V Copy # Ctrl-P Paste # # KeyRelease # # ButtonPress-1 Start selection if in entry, otherwise clear selection. # B1-Motion Extend/reduce selection. # ButtonRelease-1 End selection if in entry, otherwise use last selection. # B1-Enter Disabled. # B1-Leave Disabled. # ButtonPress-2 Same as above. # B2-Motion Same as above. # ButtonRelease-2 Same as above. # # All bindings in editting mode will "break" to override other bindings. # # bind Hierbox <ButtonPress-3> { set node [%W nearest %x %y] %W entry insert $node @%x,%y "" # %W entry insert $node 2 "" } proc blt::Hierbox::Init { widget } { # # Active entry bindings # $widget bind Entry <Enter> { %W entry highlight current } $widget bind Entry <Leave> { %W entry highlight "" } # # Button bindings # $widget button bind all <ButtonRelease-1> { %W see -anchor nw current %W toggle current } $widget button bind all <Enter> { %W button highlight current } $widget button bind all <Leave> { %W button highlight "" } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current entry. # 3. Sets the focus to this entry. # 4. Scrolls the entry into view. # 5. Sets the selection anchor to this entry, just in case # this is "multiple" mode. # $widget bind Entry <ButtonPress-1> { blt::Hierbox::SetSelectionAnchor %W current set bltHierbox(scroll) 1 } $widget bin Entry <Double-ButtonPress-1> { %W toggle current } # # B1-Motion # # For "multiple" mode only. Saves the current location of the # pointer for auto-scrolling. # $widget bind Entry <B1-Motion> { set bltHierbox(x) %x set bltHierbox(y) %y set index [%W nearest %x %y] if { [%W cget -selectmode] == "multiple" } { %W selection mark $index } else { blt::Hierbox::SetSelectionAnchor %W $index } } # # ButtonRelease-1 # # For "multiple" mode only. # $widget bind Entry <ButtonRelease-1> { if { [%W cget -selectmode] == "multiple" } { %W selection anchor current } after cancel $bltHierbox(afterId) set bltHierbox(scroll) 0 } # # Shift-ButtonPress-1 # # For "multiple" mode only. # $widget bind Entry <Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } set index [%W index anchor] %W selection clearall %W selection set $index current } else { blt::Hierbox::SetSelectionAnchor %W current } } $widget bind Entry <Shift-B1-Motion> { # do nothing } $widget bind Entry <Shift-ButtonRelease-1> { after cancel $bltHierbox(afterId) set bltHierbox(scroll) 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # $widget bind Entry <Control-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" } { set index [%W index current] %W selection toggle $index %W selection anchor $index } else { blt::Hierbox::SetSelectionAnchor %W current } } $widget bind Entry <Control-B1-Motion> { # do nothing } $widget bind Entry <Control-ButtonRelease-1> { after cancel $bltHierbox(afterId) set bltHierbox(scroll) 0 } # # Control-Shift-ButtonPress-1 # # For "multiple" mode only. # $widget bind Entry <Control-Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } if { [%W selection includes anchor] } { %W selection set anchor current } else { %W selection clear anchor current %W selection set current } } else { blt::Hierbox::SetSelectionAnchor %W current } } $widget bind Entry <Control-Shift-B1-Motion> { # do nothing } } # ---------------------------------------------------------------------- # USAGE: blt::Hierbox::AutoScroll <hierbox> # # Invoked when the user is selecting elements in a hierbox widget # and drags the mouse pointer outside of the widget. Scrolls the # view in the direction of the pointer. # # Arguments: hierbox hierarchy widget # # ---------------------------------------------------------------------- proc blt::Hierbox::AutoScroll { widget } { global bltHierbox if { ![winfo exists $widget] } { return } set x $bltHierbox(x) set y $bltHierbox(y) set index [$widget nearest $x $y] if { $y >= [winfo height $widget] } { $widget yview scroll 1 units set neighbor down } elseif { $y < 0 } { $widget yview scroll -1 units set neighbor up } else { set neighbor $index } if { [$widget cget -selectmode] == "single" } { blt::Hierbox::SetSelectionAnchor $widget $neighbor } else { $widget selection mark $index } set bltHierbox(afterId) [after 10 blt::Hierbox::AutoScroll $widget] } proc blt::Hierbox::SetSelectionAnchor { widget index } { set index [$widget index $index] $widget selection clearall $widget see $index $widget focus $index $widget selection set $index $widget selection anchor $index } # ---------------------------------------------------------------------- # USAGE: blt::Hierbox::NextMatchingEntry <hierbox> <char> # Arguments: hierbox hierarchy widget # # Invoked by KeyPress bindings. Searches for an entry that starts # with the letter <char> and makes that entry active. # ---------------------------------------------------------------------- proc blt::Hierbox::NextMatchingEntry { widget key } { if {[string match {[ -~]} $key]} { set last [$widget index focus] set next [$widget index next] while { $next != $last } { set label [$widget entry cget $next -label] if { [string index $label 0] == $key } { break } set next [$widget index -at $next next] } $widget focus $next if {[$widget cget -selectmode] == "single"} { $widget selection clearall $widget selection set focus } $widget see focus } } # ---------------------------------------------------------------------- # USAGE: blt::Hierbox::MoveFocus <hierbox> <where> # # Invoked by KeyPress bindings. Moves the active selection to the # entry <where>, which is an index such as "up", "down", "prevsibling", # "nextsibling", etc. # ---------------------------------------------------------------------- proc blt::Hierbox::MoveFocus { widget where } { catch {$widget focus $where} if { [$widget cget -selectmode] == "single" } { $widget selection clearall $widget selection set focus } $widget see focus } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/treeview.xbm��������������������������������������������������������������0000644�0001750�0001750�00000000506�11462120062�016245� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define test_width 16 #define test_height 16 #define test_x_hot 7 #define test_y_hot 7 static unsigned char test_bits[] = { 0x00, 0x00, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x64, 0x26, 0x66, 0x66, 0x7f, 0xfe, 0x66, 0x66, 0x64, 0x26, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x00, 0x00}; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/graph.tcl�����������������������������������������������������������������0000644�0001750�0001750�00000054065�11717273511�015534� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� namespace eval ::blt::legend { variable _private array set _private { afterId "" scroll 0 space off drag 0 x 0 y 0 } } namespace eval ::blt::ZoomStack { variable _private array set _private { afterId "" scroll 0 space off drag 0 x 0 y 0 } } option add *zoomOutline.dashes 4 option add *zoomOutline.lineWidth 2 option add *zoomOutline.xor yes option add *zoomTitle.anchor nw option add *zoomTitle.coords "-Inf Inf" option add *zoomTitle.font "Arial 14" option add *zoomTitle.foreground yellow3 option add *zoomTitle.shadow yellow4 # ---------------------------------------------------------------------- # # Initialize -- # # Invoked by internally by Treeview_Init routine. Initializes # the default bindings for the treeview widget entries. These # are local to the widget, so they can't be set through the # widget's class bind tags. # # ---------------------------------------------------------------------- proc blt::LegendSelections { w } { if 0 { # # Active entry bindings # $w legend bind all <Enter> { %W entry highlight current } $w legend bind all <Leave> { %W entry highlight "" } } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current entry. # 3. Sets the focus to this entry. # 4. Scrolls the entry into view. # 5. Sets the selection anchor to this entry, just in case # this is "multiple" mode. # $w legend bind all <ButtonPress-1> { blt::legend::SetSelectionAnchor %W current set blt::legend::_private(scroll) 1 } # # B1-Motion # # For "multiple" mode only. Saves the current location of the # pointer for auto-scrolling. Resets the selection mark. # $w legend bind all <B1-Motion> { set blt::legend::_private(x) %x set blt::legend::_private(y) %y set elem [%W legend get @%x,%y] if { $elem != "" } { if { [%W legend cget -selectmode] == "multiple" } { %W legend selection mark $elem } else { blt::legend::SetSelectionAnchor %W $elem } } } # # ButtonRelease-1 # # For "multiple" mode only. # $w legend bind all <ButtonRelease-1> { if { [%W legend cget -selectmode] == "multiple" } { %W legend selection anchor current } after cancel $blt::legend::_private(afterId) set blt::legend::_private(scroll) 0 } # # Shift-ButtonPress-1 # # For "multiple" mode only. # $w legend bind all <Shift-ButtonPress-1> { if { [%W legend cget -selectmode] == "multiple" && [%W legend selection present] } { if { [%W legend get anchor] == "" } { %W legend selection anchor current } set elem [%W legend get anchor] %W legend selection clearall %W legend selection set $elem current } else { blt::legend::SetSelectionAnchor %W current } } $w legend bind all <Shift-Double-ButtonPress-1> { # do nothing } $w legend bind all <Shift-B1-Motion> { # do nothing } $w legend bind all <Shift-ButtonRelease-1> { after cancel $blt::legend::_private(afterId) set blt::legend::_private(scroll) 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # $w legend bind all <Control-ButtonPress-1> { if { [%W legend cget -selectmode] == "multiple" } { set elem [%W legend get current] %W legend selection toggle $elem %W legend selection anchor $elem } else { blt::legend::SetSelectionAnchor %W current } } $w legend bind all <Control-Double-ButtonPress-1> { # do nothing } $w legend bind all <Control-B1-Motion> { # do nothing } $w legend bind all <Control-ButtonRelease-1> { after cancel $blt::legend::_private(afterId) set blt::legend::_private(scroll) 0 } $w legend bind all <Control-Shift-ButtonPress-1> { if { [%W legend cget -selectmode] == "multiple" && [%W legend selection present] } { if { [%W legend get anchor] == "" } { %W selection anchor current } if { [%W legend selection includes anchor] } { %W legend selection set anchor current } else { %W legend selection clear anchor current %W legend selection set current } } else { blt::legend::SetSelectionAnchor %W current } } $w legend bind all <Control-Shift-Double-ButtonPress-1> { # do nothing } $w legend bind all <Control-Shift-B1-Motion> { # do nothing } $w legend bind all <KeyPress-Up> { blt::legend::MoveFocus %W previous.row if { $blt::legend::_private(space) } { %W legend selection toggle focus } } $w legend bind all <KeyPress-Down> { blt::legend::MoveFocus %W next.row if { $blt::legend::_private(space) } { %W legend selection toggle focus } } $w legend bind all <KeyPress-Left> { blt::legend::MoveFocus %W previous.column if { $blt::legend::_private(space) } { %W legend selection toggle focus } } $w legend bind all <KeyPress-Right> { blt::legend::MoveFocus %W next.column if { $blt::legend::_private(space) } { %W legend selection toggle focus } } $w legend bind all <KeyPress-space> { if { [%W legend cget -selectmode] == "single" } { if { [%W legend selection includes focus] } { %W legend selection clearall } else { %W legend selection clearall %W legend selection set focus } } else { %W legend selection toggle focus } set blt::legend::_private(space) on } $w legend bind all <KeyRelease-space> { set blt::legend::_private(space) off } $w legend bind all <KeyPress-Return> { blt::legend::MoveFocus %W focus set blt::legend::_private(space) on } $w legend bind all <KeyRelease-Return> { set blt::legend::_private(space) off } $w legend bind all <KeyPress-Home> { blt::legend::MoveFocus %W first } $w legend bind all <KeyPress-End> { blt::tv::MoveFocus %W last } } proc blt::legend::SetSelectionAnchor { w tagOrId } { set elem [$w legend get $tagOrId] # If the anchor hasn't changed, don't do anything if { $elem != [$w legend get anchor] } { $w legend selection clearall $w legend focus $elem $w legend selection set $elem $w legend selection anchor $elem } } # ---------------------------------------------------------------------- # # MoveFocus -- # # Invoked by KeyPress bindings. Moves the active selection to # the entry <where>, which is an index such as "up", "down", # "prevsibling", "nextsibling", etc. # # ---------------------------------------------------------------------- proc blt::legend::MoveFocus { w elem } { catch {$w legend focus $elem} result puts stderr "result=$result elem=$elem" if { [$w legend cget -selectmode] == "single" } { $w legend selection clearall $w legend selection set focus $w legend selection anchor focus } } proc Blt_ActiveLegend { g } { $g legend bind all <Enter> [list blt::ActivateLegend $g ] $g legend bind all <Leave> [list blt::DeactivateLegend $g] $g legend bind all <ButtonPress-1> [list blt::HighlightLegend $g] } proc Blt_Crosshairs { g } { blt::Crosshairs $g } proc Blt_ResetCrosshairs { g state } { blt::Crosshairs $g "Any-Motion" $state } proc Blt_ZoomStack { g args } { array set params { -mode click } array set params $args if { $params(-mode) == "click" } { blt::ZoomStack::ClickClick $g } else { blt::ZoomStack::ClickRelease $g } } proc Blt_PrintKey { g } { blt::PrintKey $g } proc Blt_ClosestPoint { g } { blt::ClosestPoint $g } # # The following procedures that reside in the "blt" namespace are # supposed to be private. # proc blt::ActivateLegend { g } { set elem [$g legend get current] $g legend activate $elem } proc blt::DeactivateLegend { g } { set elem [$g legend get current] $g legend deactivate $elem } proc blt::HighlightLegend { g } { set elem [$g legend get current] if { $elem != "" } { set relief [$g element cget $elem -legendrelief] if { $relief == "flat" } { $g element configure $elem -legendrelief raised $g element activate $elem } else { $g element configure $elem -legendrelief flat $g element deactivate $elem } } } proc blt::Crosshairs { g {event "Any-Motion"} {state "on"}} { $g crosshairs $state bind crosshairs-$g <$event> { %W crosshairs configure -position @%x,%y } bind crosshairs-$g <Leave> { %W crosshairs off } bind crosshairs-$g <Enter> { %W crosshairs on } $g crosshairs configure -color red if { $state == "on" } { blt::AddBindTag $g crosshairs-$g } elseif { $state == "off" } { blt::RemoveBindTag $g crosshairs-$g } } proc blt::PrintKey { g {event "Shift-ButtonRelease-3"} } { bind print-$g <$event> { Blt_PostScriptDialog %W } blt::AddBindTag $g print-$g } proc blt::ClosestPoint { g {event "Control-ButtonPress-2"} } { bind closest-point-$g <$event> { blt::FindElement %W %x %y } blt::AddBindTag $g closest-point-$g } proc blt::AddBindTag { widget tag } { set oldTagList [bindtags $widget] if { [lsearch $oldTagList $tag] < 0 } { bindtags $widget [linsert $oldTagList 0 $tag] } } proc blt::RemoveBindTag { widget tag } { set oldTagList [bindtags $widget] set index [lsearch $oldTagList $tag] if { $index >= 0 } { bindtags $widget [lreplace $oldTagList $index $index] } } proc blt::FindElement { g x y } { array set info [$g element closest $x $y -interpolate yes] if { ![info exists info(name)] } { beep return } # -------------------------------------------------------------- # find(name) - element Id # find(index) - index of closest point # find(x) find(y) - coordinates of closest point # or closest point on line segment. # find(dist) - distance from sample coordinate # -------------------------------------------------------------- set markerName "bltClosest_$info(name)" catch { $g marker delete $markerName } $g marker create text -coords { $info(x) $info(y) } \ -name $markerName \ -text "$info(name): $info(dist)\nindex $info(index)" \ -font "Arial 6" \ -anchor center -justify left \ -yoffset 0 -bg {} set coords [$g invtransform $x $y] set nx [lindex $coords 0] set ny [lindex $coords 1] $g marker create line -coords "$nx $ny $info(x) $info(y)" \ -name line.$markerName blt::FlashPoint $g $info(name) $info(index) 10 blt::FlashPoint $g $info(name) [expr $info(index) + 1] 10 } proc blt::FlashPoint { g name index count } { if { $count & 1 } { $g element deactivate $name } else { $g element activate $name $index } incr count -1 if { $count > 0 } { after 200 blt::FlashPoint $g $name $index $count update } else { eval $g marker delete [$g marker names "bltClosest_*"] } } proc blt::ZoomStack::Init { g } { variable _private set _private($g,interval) 100 set _private($g,afterId) 0 set _private($g,A,x) {} set _private($g,A,y) {} set _private($g,B,x) {} set _private($g,B,y) {} set _private($g,stack) {} set _private($g,corner) A } proc blt::ZoomStack::ClickClick { g {start "ButtonPress-1"} {reset "ButtonPress-3"} } { variable _private Init $g bind zoom-$g <Enter> "focus %W" bind zoom-$g <KeyPress-Escape> { blt::ZoomStack::Reset %W } bind zoom-$g <${start}> { blt::ZoomStack::SetPoint %W %x %y } bind zoom-$g <${reset}> { if { [%W inside %x %y] } { blt::ZoomStack::Reset %W } } blt::AddBindTag $g zoom-$g } proc blt::ZoomStack::ClickRelease { g } { variable _private Init $g bind zoom-$g <Enter> "focus %W" bind zoom-$g <KeyPress-Escape> { blt::ZoomStack::Reset %W } bind zoom-$g <ButtonPress-1> { blt::ZoomStack::DragStart %W %x %y } bind zoom-$g <B1-Motion> { blt::ZoomStack::DragMotion %W %x %y } bind zoom-$g <ButtonRelease-1> { blt::ZoomStack::DragFinish %W %x %y } bind zoom-$g <ButtonPress-3> { if { [%W inside %x %y] } { blt::ZoomStack::Reset %W } } blt::AddBindTag $g zoom-$g } proc blt::ZoomStack::GetCoords { g x y index } { variable _private if { [$g cget -invertxy] } { set _private($g,$index,x) $y set _private($g,$index,y) $x } else { set _private($g,$index,x) $x set _private($g,$index,y) $y } } proc blt::ZoomStack::MarkPoint { g index } { variable _private if { [llength [$g xaxis use]] > 0 } { set x [$g xaxis invtransform $_private($g,$index,x)] } else if { [llength [$g x2axis use]] > 0 } { set x [$g x2axis invtransform $_private($g,$index,x)] } if { [llength [$g yaxis use]] > 0 } { set y [$g yaxis invtransform $_private($g,$index,y)] } else if { [llength [$g y2axis use]] > 0 } { set y [$g y2axis invtransform $_private($g,$index,y)] } set marker "zoomText_$index" set text [format "x=%.4g\ny=%.4g" $x $y] if [$g marker exists $marker] { $g marker configure $marker -coords { $x $y } -text $text } else { $g marker create text -coords { $x $y } -name $marker \ -font "mathmatica1 10" \ -text $text -anchor center -bg {} -justify left } } proc blt::ZoomStack::DestroyTitle { g } { variable _private if { $_private($g,corner) == "A" } { catch { $g marker delete "zoomTitle" } } } proc blt::ZoomStack::Pop { g } { variable _private set zoomStack $_private($g,stack) if { [llength $zoomStack] > 0 } { set cmd [lindex $zoomStack 0] set _private($g,stack) [lrange $zoomStack 1 end] eval $cmd TitleLast $g blt::busy hold $g update blt::busy release $g after 2000 [list blt::ZoomStack::DestroyTitle $g] } else { catch { $g marker delete "zoomTitle" } } } # Push the old axis limits on the stack and set the new ones proc blt::ZoomStack::Push { g } { variable _private eval $g marker delete [$g marker names "zoom*"] if { [info exists _private($g,afterId)] } { after cancel $_private($g,afterId) } set x1 $_private($g,A,x) set y1 $_private($g,A,y) set x2 $_private($g,B,x) set y2 $_private($g,B,y) if { ($x1 == $x2) || ($y1 == $y2) } { # No delta, revert to start return } set cmd {} foreach axis [$g axis names] { if { [$g axis cget $axis -hide] } { continue } set min [$g axis cget $axis -min] set max [$g axis cget $axis -max] set logscale [$g axis cget $axis -logscale] # Save the current scale (log or linear) so that we can restore it. # This is for the case where the user changes to logscale while # zooming. A previously pushed axis limit could be negative. It # seems better for popping the zoom stack to restore a previous view # (not convert the ranges). set c [list $g axis configure $axis] lappend c -min $min -max $max -logscale $logscale append cmd "$c\n" } # This effectively pushes the command to reset the graph to the current # zoom level onto the stack. This is useful if the new axis ranges are # bad and we need to reset the zoom stack. set _private($g,stack) [linsert $_private($g,stack) 0 $cmd] foreach axis [$g axis names] { if { [$g axis cget $axis -hide] } { continue; # Don't set zoom on axes not displayed. } set type [$g axis type $axis] if { $type == "x" } { set min [$g axis invtransform $axis $x1] set max [$g axis invtransform $axis $x2] } elseif { $type == "y" } { set min [$g axis invtransform $axis $y1] set max [$g axis invtransform $axis $y2] } else { continue; # Axis is not bound to any margin. } if { ![SetAxisRanges $g $axis $min $max] } { Pop $g bell return } } blt::busy hold $g update; # This "update" redraws the graph blt::busy release $g } proc blt::ZoomStack::SetAxisRanges { g axis min max } { if { $min > $max } { set tmp $max; set max $min; set min $tmp } if { [catch { $g axis configure $axis -min $min -max $max }] != 0 } { return 0 } return 1 } # # This routine terminates either an existing zoom, or pops back to # the previous zoom level (if no zoom is in progress). # proc blt::ZoomStack::Reset { g } { variable _private if { ![info exists _private($g,corner)] } { Init $g } eval $g marker delete [$g marker names "zoom*"] if { $_private($g,corner) == "A" } { # Reset the whole axis Pop $g } else { set _private($g,corner) A blt::RemoveBindTag $g select-region-$g } } proc blt::ZoomStack::TitleNext { g } { variable _private set level [expr [llength $_private($g,stack)] + 1] if { [$g cget -invertxy] } { set coords "Inf -Inf" } else { set coords "-Inf Inf" } $g marker create text -name "zoomTitle" -text "Zoom #$level" \ -coords $coords -bindtags "" -anchor nw } proc blt::ZoomStack::TitleLast { g } { variable _private set level [llength $_private($g,stack)] if { $level > 0 } { $g marker create text -name "zoomTitle" -anchor nw \ -text "Zoom #$level" } } proc blt::ZoomStack::SetPoint { g x y } { variable _private if { ![info exists _private($g,corner)] } { Init $g } GetCoords $g $x $y $_private($g,corner) bind select-region-$g <Motion> { blt::ZoomStack::GetCoords %W %x %y B #blt::ZoomStack::MarkPoint $g B blt::ZoomStack::Box %W } if { $_private($g,corner) == "A" } { if { ![$g inside $x $y] } { return } # First corner selected, start watching motion events #MarkPoint $g A TitleNext $g blt::AddBindTag $g select-region-$g set _private($g,corner) B } else { # Delete the modal binding blt::RemoveBindTag $g select-region-$g Push $g set _private($g,corner) A } } proc blt::ZoomStack::DragStart { g x y } { variable _private if { ![info exists _private($g,corner)] } { Init $g } GetCoords $g $x $y A if { ![$g inside $x $y] } { return } set _private(drag) 1 TitleNext $g } proc blt::ZoomStack::DragMotion { g x y } { variable _private if { $_private(drag) } { GetCoords $g $x $y B set dx [expr abs($_private($g,B,x) - $_private($g,A,x))] set dy [expr abs($_private($g,B,y) - $_private($g,A,y))] Box $g if { $dy > 10 && $dx > 10 } { return 1 } } return 0 } proc blt::ZoomStack::DragFinish { g x y } { variable _private if { [DragMotion $g $x $y] } { Push $g } else { eval $g marker delete [$g marker names "zoom*"] if { [info exists _private($g,afterId)] } { after cancel $_private($g,afterId) } } set _private(drag) 0 } proc blt::ZoomStack::MarchingAnts { g offset } { variable _private incr offset # wrap the counter after 2^16 set offset [expr $offset & 0xFFFF] if { [$g marker exists zoomOutline] } { $g marker configure zoomOutline -dashoffset $offset set interval $_private($g,interval) set id [after $interval [list blt::ZoomStack::MarchingAnts $g $offset]] set _private($g,afterId) $id } } proc blt::ZoomStack::Box { g } { variable _private if { $_private($g,A,x) > $_private($g,B,x) } { set x1 [$g xaxis invtransform $_private($g,B,x)] set y1 [$g yaxis invtransform $_private($g,B,y)] set x2 [$g xaxis invtransform $_private($g,A,x)] set y2 [$g yaxis invtransform $_private($g,A,y)] } else { set x1 [$g xaxis invtransform $_private($g,A,x)] set y1 [$g yaxis invtransform $_private($g,A,y)] set x2 [$g xaxis invtransform $_private($g,B,x)] set y2 [$g yaxis invtransform $_private($g,B,y)] } set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 } if { [$g marker exists "zoomOutline"] } { $g marker configure "zoomOutline" -coords $coords } else { set X [lindex [$g xaxis use] 0] set Y [lindex [$g yaxis use] 0] $g marker create line -coords $coords -name "zoomOutline" \ -mapx $X -mapy $Y set interval $_private($g,interval) set id [after $interval [list blt::ZoomStack::MarchingAnts $g 0]] set _private($g,afterId) $id } } proc Blt_PostScriptDialog { g } { set top $g.top toplevel $top foreach var { center landscape maxpect preview decorations padx pady paperwidth paperheight width height colormode } { global $g.$var set $g.$var [$g postscript cget -$var] } set row 1 set col 0 label $top.title -text "PostScript Options" blt::table $top $top.title -cspan 7 foreach bool { center landscape maxpect preview decorations } { set w $top.$bool-label label $w -text "-$bool" -font "courier 12" blt::table $top $row,$col $w -anchor e -pady { 2 0 } -padx { 0 4 } set w $top.$bool-yes global $g.$bool radiobutton $w -text "yes" -variable $g.$bool -value 1 blt::table $top $row,$col+1 $w -anchor w set w $top.$bool-no radiobutton $w -text "no" -variable $g.$bool -value 0 blt::table $top $row,$col+2 $w -anchor w incr row } label $top.modes -text "-colormode" -font "courier 12" blt::table $top $row,0 $top.modes -anchor e -pady { 2 0 } -padx { 0 4 } set col 1 foreach m { color greyscale } { set w $top.$m radiobutton $w -text $m -variable $g.colormode -value $m blt::table $top $row,$col $w -anchor w incr col } set row 1 frame $top.sep -width 2 -bd 1 -relief sunken blt::table $top $row,3 $top.sep -fill y -rspan 6 set col 4 foreach value { padx pady paperwidth paperheight width height } { set w $top.$value-label label $w -text "-$value" -font "courier 12" blt::table $top $row,$col $w -anchor e -pady { 2 0 } -padx { 0 4 } set w $top.$value-entry global $g.$value entry $w -textvariable $g.$value -width 8 blt::table $top $row,$col+1 $w -cspan 2 -anchor w -padx 8 incr row } blt::table configure $top c3 -width .125i button $top.cancel -text "Cancel" -command "destroy $top" blt::table $top $row,0 $top.cancel -width 1i -pady 2 -cspan 3 button $top.reset -text "Reset" -command "destroy $top" #blt::table $top $row,1 $top.reset -width 1i button $top.print -text "Print" -command "blt::ResetPostScript $g" blt::table $top $row,4 $top.print -width 1i -pady 2 -cspan 2 } proc blt::ResetPostScript { g } { foreach var { center landscape maxpect preview decorations padx pady paperwidth paperheight width height colormode } { global $g.$var set old [$g postscript cget -$var] if { [catch {$g postscript configure -$var [set $g.$var]}] != 0 } { $g postscript configure -$var $old set $g.$var $old } } $g postscript output "out.ps" puts stdout "wrote file \"out.ps\"." flush stdout } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/Makefile.vc���������������������������������������������������������������0000644�0001750�0001750�00000003222�11462120062�015750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for library files and directories of BLT library # ------------------------------------------------------------------------ include ../vc.config srcdir = ../$(TOP)/library version = $(BLT_MAJOR_VERSION).$(BLT_MINOR_VERSION) pkgdir = $(libdir)/tcl$(v1)/blt$(version) cursors = treeview.cur miscFiles = bltCanvEps.pro \ bltGraph.pro \ dnd.tcl \ dragdrop.tcl \ graph.tcl \ hierbox.tcl \ tabnotebook.tcl \ tabset.tcl \ treeview.tcl \ tclIndex \ $(cursors) ddFiles = dd-color.tcl \ dd-file.tcl \ dd-number.tcl \ dd-text.tcl \ tclIndex instdirs = $(prefix) $(exec_prefix) $(libdir) \ $(scriptdir) $(scriptdir)/dd_protocols $(libdir)/tcl$(v1) \ $(pkgdir) all: pkgIndex.tcl install: install-dirs install-ddfiles install-files install-pkgindex install-dirs: @for i in $(instdirs) ; do \ if test -d "$$i" ; then : ; else mkdir "$$i" ; fi ; \ done install-ddfiles: install-dirs for i in $(ddFiles) ; do \ $(INSTALL_DATA) $(srcdir)/dd_protocols/$$i $(scriptdir)/dd_protocols ; \ done install-files: install-dirs for i in $(miscFiles) ; do \ $(INSTALL_DATA) $(srcdir)/$$i $(scriptdir) ; \ done pkgIndex.tcl: $(srcdir)/pkgIndex.tcl.in rm -f pkgIndex.tcl sed -e 's/%VERSION%/$(version)/' $(srcdir)/pkgIndex.tcl.in | \ sed -e 's/%LIB_PREFIX%//' | \ sed -e 's;%LIB_DIR%;$(libdir);' > pkgIndex.tcl install-pkgindex: pkgIndex.tcl $(INSTALL_DATA) pkgIndex.tcl $(scriptdir) $(INSTALL_DATA) pkgIndex.tcl $(pkgdir) clean: $(RM) pkgIndex.tcl $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* distclean: clean $(RM) Makefile ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/paneset.tcl���������������������������������������������������������������0000644�0001750�0001750�00000001360�11462120062�016045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������namespace eval blt::Paneset { set buttonPressed 0 proc Initialize {} { } } bind PanesetSash <Enter> { if { !$blt::Paneset::buttonPressed } { %W activate } } bind PanesetSash <Leave> { if { !$blt::Paneset::buttonPressed } { %W deactivate } } bind PanesetSash <KeyPress-Left> { %W move -10 0 } bind PanesetSash <KeyPress-Right> { %W move 10 0 } bind PanesetSash <KeyPress-Up> { %W move 0 -10 } bind PanesetSash <KeyPress-Down> { %W move 0 10 } bind PanesetSash <ButtonPress-1> { set blt::Paneset::buttonPressed 1 %W anchor %X %Y } bind PanesetSash <B1-Motion> { %W mark %X %Y } bind PanesetSash <ButtonRelease-1> { set blt::Paneset::buttonPressed 0 %W set %X %Y } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/panes.tcl�����������������������������������������������������������������0000644�0001750�0001750�00000012623�11462120062�015520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # panes.tcl -- # # This file defines the default bindings for Tk panedwindow widgets and # provides procedures that help in implementing those bindings. # # RCS: @(#) $Id: panes.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # bind Panes <Button-1> { ::blt::panes::MarkSash %W %x %y 1 } bind Panes <Button-2> { ::blt::panes::MarkSash %W %x %y 0 } bind Panes <B1-Motion> { ::blt::panes::DragSash %W %x %y 1 } bind Panes <B2-Motion> { ::blt::panes::DragSash %W %x %y 0 } bind Panes <ButtonRelease-1> {::blt::panes::ReleaseSash %W 1} bind Panes <ButtonRelease-2> {::blt::panes::ReleaseSash %W 0} bind Panes <Motion> { %W sash activate %x %y } bind Panes <ButtonPress-1> { if { [%W sash activate] } { %W sash anchor %x %y } } bind Panes <B1-Motion> { %W sash mark %x %y } bind Panes <ButtonRelease-1> { %W sash set %x %y %W sash activate %x %y } bind Panes <Leave> { %W sash activate -1 } bind Panes <B1-Leave> { # do nothing } bind Panes <Enter> { %W sash activate %x %y } bind Panes <Button-2> { ::blt::panes::MarkSash %W %x %y 0 } # Initialize namespace namespace eval ::blt::panes {} # ::blt::panes::MarkSash -- # # Handle marking the correct sash for possible dragging # # Arguments: # w the widget # x widget local x coord # y widget local y coord # proxy whether this should be a proxy sash # Results: # None # proc ::tk::panedwindow::MarkSash {w x y proxy} { if {[$w cget -opaqueresize]} { set proxy 0 } set what [$w identify $x $y] if { [llength $what] == 2 } { foreach {index which} $what break if { !$::tk_strictMotif || $which eq "handle" } { if {!$proxy} { $w sash mark $index $x $y } set ::tk::Priv(sash) $index foreach {sx sy} [$w sash coord $index] break set ::tk::Priv(dx) [expr {$sx-$x}] set ::tk::Priv(dy) [expr {$sy-$y}] # Do this to init the proxy location DragSash $w $x $y $proxy } } } # ::blt::panes::DragSash -- # # Handle dragging of the correct sash # # Arguments: # w the widget # x widget local x coord # y widget local y coord # proxy whether this should be a proxy sash # Results: # Moves sash # proc ::blt::panes::DragSash {w x y proxy} { if {[$w cget -opaqueresize]} { set proxy 0 } if { [info exists ::tk::Priv(sash)] } { if {$proxy} { $w proxy place \ [expr {$x+$::tk::Priv(dx)}] [expr {$y+$::tk::Priv(dy)}] } else { $w sash place $::tk::Priv(sash) \ [expr {$x+$::tk::Priv(dx)}] [expr {$y+$::tk::Priv(dy)}] } } } # ::blt::panes::ReleaseSash -- # # Handle releasing of the sash # # Arguments: # w the widget # proxy whether this should be a proxy sash # Results: # Returns ... # proc ::blt::panes::ReleaseSash {w proxy} { if {[$w cget -opaqueresize]} { set proxy 0 } if { [info exists ::tk::Priv(sash)] } { if {$proxy} { foreach {x y} [$w proxy coord] break $w sash place $::tk::Priv(sash) $x $y $w proxy forget } unset ::tk::Priv(sash) ::tk::Priv(dx) ::tk::Priv(dy) } } # ::blt::panes::Motion -- # # Handle motion on the widget. This is used to change the cursor # when the user moves over the sash area. # # Arguments: # w the widget # x widget local x coord # y widget local y coord # Results: # May change the cursor. Sets up a timer to verify that we are still # over the widget. # proc ::blt::panes::Motion {w x y} { variable ::tk::Priv set id [$w identify $x $y] if {([llength $id] == 2) && \ (!$::tk_strictMotif || [lindex $id 1] eq "handle")} { if { ![info exists Priv($w,panecursor)] } { set Priv($w,panecursor) [$w cget -cursor] if { [$w cget -sashcursor] eq "" } { if { [$w cget -orient] eq "horizontal" } { $w configure -cursor sb_h_double_arrow } else { $w configure -cursor sb_v_double_arrow } } else { $w configure -cursor [$w cget -sashcursor] } if {[info exists Priv($w,pwAfterId)]} { after cancel $Priv($w,pwAfterId) } set Priv($w,pwAfterId) [after 150 \ [list ::tk::panedwindow::Cursor $w]] } return } if { [info exists Priv($w,panecursor)] } { $w configure -cursor $Priv($w,panecursor) unset Priv($w,panecursor) } } # ::blt::panes::Cursor -- # # Handles returning the normal cursor when we are no longer over the # sash area. This needs to be done this way, because the panedwindow # won't see Leave events when the mouse moves from the sash to a # paned child, although the child does receive an Enter event. # # Arguments: # w the widget # Results: # May restore the default cursor, or schedule a timer to do it. # proc ::blt::panes::Cursor {w} { variable ::tk::Priv # Make sure to check window existence in case it is destroyed. if {[info exists Priv($w,panecursor)] && [winfo exists $w]} { if {[winfo containing [winfo pointerx $w] [winfo pointery $w]] eq $w} { set Priv($w,pwAfterId) [after 150 \ [list ::tk::panedwindow::Cursor $w]] } else { $w configure -cursor $Priv($w,panecursor) unset Priv($w,panecursor) if {[info exists Priv($w,pwAfterId)]} { after cancel $Priv($w,pwAfterId) unset Priv($w,pwAfterId) } } } } # ::blt::panes::Leave -- # # Return to default cursor when leaving the pw widget. # # Arguments: # w the widget # Results: # Restores the default cursor # proc ::tk::panedwindow::Leave {w} { if {[info exists ::tk::Priv($w,panecursor)]} { $w configure -cursor $::tk::Priv($w,panecursor) unset ::tk::Priv($w,panecursor) } } �������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014441� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Courier-Bold.afm������������������������������������������������������0000644�0001750�0001750�00000036521�11462120062�017427� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Tue Sep 17 14:02:41 1991 Comment UniqueID 36384 Comment VMusage 31992 40360 FontName Courier-Bold FullName Courier Bold FamilyName Courier Weight Bold ItalicAngle 0 IsFixedPitch true FontBBox -113 -250 749 801 UnderlinePosition -100 UnderlineThickness 50 Version 002.004 Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 439 Ascender 626 Descender -142 StartCharMetrics 260 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ; C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; C 49 ; WX 600 ; N one ; B 81 0 539 616 ; C 50 ; WX 600 ; N two ; B 61 0 499 616 ; C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; C 52 ; WX 600 ; N four ; B 53 0 507 616 ; C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; C 60 ; WX 600 ; N less ; B 66 15 523 501 ; C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; C 65 ; WX 600 ; N A ; B -9 0 609 562 ; C 66 ; WX 600 ; N B ; B 30 0 573 562 ; C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; C 68 ; WX 600 ; N D ; B 30 0 594 562 ; C 69 ; WX 600 ; N E ; B 25 0 560 562 ; C 70 ; WX 600 ; N F ; B 39 0 570 562 ; C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; C 72 ; WX 600 ; N H ; B 20 0 580 562 ; C 73 ; WX 600 ; N I ; B 77 0 523 562 ; C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; C 75 ; WX 600 ; N K ; B 21 0 599 562 ; C 76 ; WX 600 ; N L ; B 39 0 578 562 ; C 77 ; WX 600 ; N M ; B -2 0 602 562 ; C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; C 80 ; WX 600 ; N P ; B 48 0 559 562 ; C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; C 82 ; WX 600 ; N R ; B 24 0 599 562 ; C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; C 84 ; WX 600 ; N T ; B 21 0 579 562 ; C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; C 86 ; WX 600 ; N V ; B -13 0 613 562 ; C 87 ; WX 600 ; N W ; B -18 0 618 562 ; C 88 ; WX 600 ; N X ; B 12 0 588 562 ; C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; C 104 ; WX 600 ; N h ; B 5 0 592 626 ; C 105 ; WX 600 ; N i ; B 77 0 523 658 ; C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; C 107 ; WX 600 ; N k ; B 20 0 585 626 ; C 108 ; WX 600 ; N l ; B 77 0 523 626 ; C 109 ; WX 600 ; N m ; B -22 0 626 454 ; C 110 ; WX 600 ; N n ; B 18 0 592 454 ; C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; C 114 ; WX 600 ; N r ; B 47 0 580 454 ; C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; C 118 ; WX 600 ; N v ; B -1 0 601 439 ; C 119 ; WX 600 ; N w ; B -18 0 618 439 ; C 120 ; WX 600 ; N x ; B 6 0 594 439 ; C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; C 122 ; WX 600 ; N z ; B 81 0 520 439 ; C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ; C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ; C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; C 168 ; WX 600 ; N currency ; B 54 49 546 517 ; C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; C 174 ; WX 600 ; N fi ; B 12 0 593 626 ; C 175 ; WX 600 ; N fl ; B 12 0 593 626 ; C 177 ; WX 600 ; N endash ; B 65 203 535 313 ; C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ; C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ; C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; C 193 ; WX 600 ; N grave ; B 132 508 395 661 ; C 194 ; WX 600 ; N acute ; B 205 508 468 661 ; C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ; C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ; C 197 ; WX 600 ; N macron ; B 88 505 512 585 ; C 198 ; WX 600 ; N breve ; B 83 468 517 631 ; C 199 ; WX 600 ; N dotaccent ; B 230 485 370 625 ; C 200 ; WX 600 ; N dieresis ; B 128 485 472 625 ; C 202 ; WX 600 ; N ring ; B 198 481 402 678 ; C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; C 206 ; WX 600 ; N ogonek ; B 169 -199 367 0 ; C 207 ; WX 600 ; N caron ; B 103 493 497 667 ; C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ; C 225 ; WX 600 ; N AE ; B -29 0 602 562 ; C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ; C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; C 234 ; WX 600 ; N OE ; B -25 0 595 562 ; C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ; C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ; C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ; C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ; C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 748 ; C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; C -1 ; WX 600 ; N merge ; B 137 -15 464 487 ; C -1 ; WX 600 ; N degree ; B 86 243 474 616 ; C -1 ; WX 600 ; N dectab ; B 8 0 592 320 ; C -1 ; WX 600 ; N ll ; B -12 0 600 626 ; C -1 ; WX 600 ; N IJ ; B -8 -18 622 562 ; C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ; C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; C -1 ; WX 600 ; N left ; B 65 44 535 371 ; C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; C -1 ; WX 600 ; N up ; B 136 0 463 447 ; C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ; C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; C -1 ; WX 600 ; N tab ; B 19 0 581 562 ; C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; C -1 ; WX 600 ; N divide ; B 71 16 529 500 ; C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ; C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ; C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ; C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ; C -1 ; WX 600 ; N down ; B 137 -15 464 439 ; C -1 ; WX 600 ; N center ; B 40 14 560 580 ; C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; C -1 ; WX 600 ; N ij ; B 6 -146 574 658 ; C -1 ; WX 600 ; N edieresis ; B 40 -15 563 625 ; C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ; C -1 ; WX 600 ; N odieresis ; B 30 -15 570 625 ; C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ; C -1 ; WX 600 ; N prescription ; B 24 -15 599 562 ; C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ; C -1 ; WX 600 ; N largebullet ; B 248 229 352 333 ; C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ; C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; C -1 ; WX 600 ; N notegraphic ; B 77 -15 523 572 ; C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 748 ; C -1 ; WX 600 ; N Gcaron ; B 22 -18 594 790 ; C -1 ; WX 600 ; N arrowdown ; B 144 -15 456 608 ; C -1 ; WX 600 ; N format ; B 5 -146 115 601 ; C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; C -1 ; WX 600 ; N Idieresis ; B 77 0 523 748 ; C -1 ; WX 600 ; N adieresis ; B 35 -15 570 625 ; C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ; C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; C -1 ; WX 600 ; N LL ; B -45 0 645 562 ; C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ; C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; C -1 ; WX 600 ; N Idot ; B 77 0 523 748 ; C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ; C -1 ; WX 600 ; N indent ; B 65 45 535 372 ; C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ; C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ; C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ; C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ; C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ; C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ; C -1 ; WX 600 ; N lira ; B 72 -28 558 611 ; C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ; C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 748 ; C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 625 ; C -1 ; WX 600 ; N idieresis ; B 77 0 523 625 ; C -1 ; WX 600 ; N Adieresis ; B -9 0 609 748 ; C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ; C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ; C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ; C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ; C -1 ; WX 600 ; N return ; B 19 0 581 562 ; C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ; C -1 ; WX 600 ; N square ; B 19 0 581 562 ; C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; C -1 ; WX 600 ; N stop ; B 19 0 581 562 ; C -1 ; WX 600 ; N udieresis ; B -1 -15 569 625 ; C -1 ; WX 600 ; N arrowup ; B 144 3 456 626 ; C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ; C -1 ; WX 600 ; N Edieresis ; B 25 0 560 748 ; C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ; C -1 ; WX 600 ; N arrowboth ; B -24 143 624 455 ; C -1 ; WX 600 ; N gcaron ; B 30 -146 580 667 ; C -1 ; WX 600 ; N arrowleft ; B -24 143 634 455 ; C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ; C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ; C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ; C -1 ; WX 600 ; N arrowright ; B -34 143 624 455 ; C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ; C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ; C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ; C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ; C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ; C -1 ; WX 600 ; N icircumflex ; B 63 0 523 657 ; EndCharMetrics StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 30 123 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 123 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -20 123 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave -50 123 ; CC Aring 2 ; PCC A 0 0 ; PCC ring -10 123 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde -30 123 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 123 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 123 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 123 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 123 ; CC Gcaron 2 ; PCC G 0 0 ; PCC caron 10 123 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 123 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 123 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 123 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 123 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 123 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 123 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 123 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 123 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 123 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 123 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 123 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 123 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 123 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 123 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 123 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 123 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 123 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 123 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ; EndComposites EndFontMetrics �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Times-BoldItalic.afm��������������������������������������������������0000644�0001750�0001750�00000044437�11462120062�020233� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Mar 20 13:14:55 1990 Comment UniqueID 28425 Comment VMusage 32721 39613 FontName Times-BoldItalic FullName Times Bold Italic FamilyName Times Weight Bold ItalicAngle -15 IsFixedPitch false FontBBox -200 -218 996 921 UnderlinePosition -100 UnderlineThickness 50 Version 001.009 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 669 XHeight 462 Ascender 699 Descender -205 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ; C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ; C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ; C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ; C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ; C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ; C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ; C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ; C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ; C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ; C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ; C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ; C 46 ; WX 250 ; N period ; B -9 -13 139 135 ; C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ; C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ; C 49 ; WX 500 ; N one ; B 5 0 419 683 ; C 50 ; WX 500 ; N two ; B -27 0 446 683 ; C 51 ; WX 500 ; N three ; B -15 -13 450 683 ; C 52 ; WX 500 ; N four ; B -15 0 503 683 ; C 53 ; WX 500 ; N five ; B -11 -13 487 669 ; C 54 ; WX 500 ; N six ; B 23 -15 509 679 ; C 55 ; WX 500 ; N seven ; B 52 0 525 669 ; C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ; C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ; C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ; C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ; C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; C 63 ; WX 500 ; N question ; B 79 -13 470 684 ; C 64 ; WX 832 ; N at ; B 63 -18 770 685 ; C 65 ; WX 667 ; N A ; B -67 0 593 683 ; C 66 ; WX 667 ; N B ; B -24 0 624 669 ; C 67 ; WX 667 ; N C ; B 32 -18 677 685 ; C 68 ; WX 722 ; N D ; B -46 0 685 669 ; C 69 ; WX 667 ; N E ; B -27 0 653 669 ; C 70 ; WX 667 ; N F ; B -13 0 660 669 ; C 71 ; WX 722 ; N G ; B 21 -18 706 685 ; C 72 ; WX 778 ; N H ; B -24 0 799 669 ; C 73 ; WX 389 ; N I ; B -32 0 406 669 ; C 74 ; WX 500 ; N J ; B -46 -99 524 669 ; C 75 ; WX 667 ; N K ; B -21 0 702 669 ; C 76 ; WX 611 ; N L ; B -22 0 590 669 ; C 77 ; WX 889 ; N M ; B -29 -12 917 669 ; C 78 ; WX 722 ; N N ; B -27 -15 748 669 ; C 79 ; WX 722 ; N O ; B 27 -18 691 685 ; C 80 ; WX 611 ; N P ; B -27 0 613 669 ; C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ; C 82 ; WX 667 ; N R ; B -29 0 623 669 ; C 83 ; WX 556 ; N S ; B 2 -18 526 685 ; C 84 ; WX 611 ; N T ; B 50 0 650 669 ; C 85 ; WX 722 ; N U ; B 67 -18 744 669 ; C 86 ; WX 667 ; N V ; B 65 -18 715 669 ; C 87 ; WX 889 ; N W ; B 65 -18 940 669 ; C 88 ; WX 667 ; N X ; B -24 0 694 669 ; C 89 ; WX 611 ; N Y ; B 73 0 659 669 ; C 90 ; WX 611 ; N Z ; B -11 0 590 669 ; C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ; C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ; C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ; C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ; C 97 ; WX 500 ; N a ; B -21 -14 455 462 ; C 98 ; WX 500 ; N b ; B -14 -13 444 699 ; C 99 ; WX 444 ; N c ; B -5 -13 392 462 ; C 100 ; WX 500 ; N d ; B -21 -13 517 699 ; C 101 ; WX 444 ; N e ; B 5 -13 398 462 ; C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B -52 -203 478 462 ; C 104 ; WX 556 ; N h ; B -13 -9 498 699 ; C 105 ; WX 278 ; N i ; B 2 -9 263 684 ; C 106 ; WX 278 ; N j ; B -189 -207 279 684 ; C 107 ; WX 500 ; N k ; B -23 -8 483 699 ; C 108 ; WX 278 ; N l ; B 2 -9 290 699 ; C 109 ; WX 778 ; N m ; B -14 -9 722 462 ; C 110 ; WX 556 ; N n ; B -6 -9 493 462 ; C 111 ; WX 500 ; N o ; B -3 -13 441 462 ; C 112 ; WX 500 ; N p ; B -120 -205 446 462 ; C 113 ; WX 500 ; N q ; B 1 -205 471 462 ; C 114 ; WX 389 ; N r ; B -21 0 389 462 ; C 115 ; WX 389 ; N s ; B -19 -13 333 462 ; C 116 ; WX 278 ; N t ; B -11 -9 281 594 ; C 117 ; WX 556 ; N u ; B 15 -9 492 462 ; C 118 ; WX 444 ; N v ; B 16 -13 401 462 ; C 119 ; WX 667 ; N w ; B 16 -13 614 462 ; C 120 ; WX 500 ; N x ; B -46 -13 469 462 ; C 121 ; WX 444 ; N y ; B -94 -205 392 462 ; C 122 ; WX 389 ; N z ; B -43 -78 368 449 ; C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ; C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ; C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ; C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ; C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ; C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ; C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ; C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ; C 165 ; WX 500 ; N yen ; B 33 0 628 669 ; C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ; C 167 ; WX 500 ; N section ; B 36 -143 459 685 ; C 168 ; WX 500 ; N currency ; B -26 34 526 586 ; C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ; C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ; C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ; C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ; C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ; C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ; C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ; C 177 ; WX 500 ; N endash ; B -40 178 477 269 ; C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ; C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ; C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ; C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ; C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ; C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ; C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ; C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ; C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ; C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ; C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ; C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ; C 193 ; WX 333 ; N grave ; B 85 516 297 697 ; C 194 ; WX 333 ; N acute ; B 139 516 379 697 ; C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ; C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ; C 197 ; WX 333 ; N macron ; B 51 553 393 623 ; C 198 ; WX 333 ; N breve ; B 71 516 387 678 ; C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ; C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ; C 202 ; WX 333 ; N ring ; B 127 516 340 729 ; C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ; C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ; C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ; C 207 ; WX 333 ; N caron ; B 79 516 411 690 ; C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ; C 225 ; WX 944 ; N AE ; B -64 0 918 669 ; C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ; C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ; C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ; C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ; C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ; C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ; C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ; C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ; C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ; C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ; C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ; C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ; C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ; C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ; C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ; C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ; C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ; C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ; C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ; C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ; C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ; C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ; C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ; C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ; C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ; C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ; C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ; C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ; C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ; C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ; C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ; C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ; C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ; C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ; C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ; C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ; C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ; C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ; C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ; C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ; C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ; C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ; C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ; C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ; C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ; C -1 ; WX 389 ; N Iacute ; B -32 0 412 904 ; C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ; C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ; C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ; C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ; C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ; C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ; C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ; C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ; C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ; C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ; C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ; C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ; C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ; C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ; C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ; C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ; C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ; C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ; C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ; C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ; C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ; C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ; C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ; C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ; C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ; C -1 ; WX 606 ; N minus ; B 51 209 555 297 ; C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ; C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ; C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ; C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ; C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ; C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ; C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ; C -1 ; WX 400 ; N degree ; B 83 397 369 683 ; C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ; C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ; C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ; C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ; C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ; C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ; C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ; C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ; EndCharMetrics StartKernData StartKernPairs 283 KPX A y -74 KPX A w -74 KPX A v -74 KPX A u -30 KPX A quoteright -74 KPX A quotedblright 0 KPX A p 0 KPX A Y -70 KPX A W -100 KPX A V -95 KPX A U -50 KPX A T -55 KPX A Q -55 KPX A O -50 KPX A G -60 KPX A C -65 KPX B period 0 KPX B comma 0 KPX B U -10 KPX B A -25 KPX D period 0 KPX D comma 0 KPX D Y -50 KPX D W -40 KPX D V -50 KPX D A -25 KPX F r -50 KPX F period -129 KPX F o -70 KPX F i -40 KPX F e -100 KPX F comma -129 KPX F a -95 KPX F A -100 KPX G period 0 KPX G comma 0 KPX J u -40 KPX J period -10 KPX J o -40 KPX J e -40 KPX J comma -10 KPX J a -40 KPX J A -25 KPX K y -20 KPX K u -20 KPX K o -25 KPX K e -25 KPX K O -30 KPX L y -37 KPX L quoteright -55 KPX L quotedblright 0 KPX L Y -37 KPX L W -37 KPX L V -37 KPX L T -18 KPX N period 0 KPX N comma 0 KPX N A -30 KPX O period 0 KPX O comma 0 KPX O Y -50 KPX O X -40 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -40 KPX P period -129 KPX P o -55 KPX P e -50 KPX P comma -129 KPX P a -40 KPX P A -85 KPX Q period 0 KPX Q comma 0 KPX Q U -10 KPX R Y -18 KPX R W -18 KPX R V -18 KPX R U -40 KPX R T -30 KPX R O -40 KPX S period 0 KPX S comma 0 KPX T y -37 KPX T w -37 KPX T u -37 KPX T semicolon -74 KPX T r -37 KPX T period -92 KPX T o -95 KPX T i -37 KPX T hyphen -92 KPX T h 0 KPX T e -92 KPX T comma -92 KPX T colon -74 KPX T a -92 KPX T O -18 KPX T A -55 KPX U period 0 KPX U comma 0 KPX U A -45 KPX V u -55 KPX V semicolon -74 KPX V period -129 KPX V o -111 KPX V i -55 KPX V hyphen -70 KPX V e -111 KPX V comma -129 KPX V colon -74 KPX V a -111 KPX V O -30 KPX V G -10 KPX V A -85 KPX W y -55 KPX W u -55 KPX W semicolon -55 KPX W period -74 KPX W o -80 KPX W i -37 KPX W hyphen -50 KPX W h 0 KPX W e -90 KPX W comma -74 KPX W colon -55 KPX W a -85 KPX W O -15 KPX W A -74 KPX Y u -92 KPX Y semicolon -92 KPX Y period -74 KPX Y o -111 KPX Y i -55 KPX Y hyphen -92 KPX Y e -111 KPX Y comma -92 KPX Y colon -92 KPX Y a -92 KPX Y O -25 KPX Y A -74 KPX a y 0 KPX a w 0 KPX a v 0 KPX a t 0 KPX a p 0 KPX a g 0 KPX a b 0 KPX b y 0 KPX b v 0 KPX b u -20 KPX b period -40 KPX b l 0 KPX b comma 0 KPX b b -10 KPX c y 0 KPX c period 0 KPX c l 0 KPX c k -10 KPX c h -10 KPX c comma 0 KPX colon space 0 KPX comma space 0 KPX comma quoteright -95 KPX comma quotedblright -95 KPX d y 0 KPX d w 0 KPX d v 0 KPX d period 0 KPX d d 0 KPX d comma 0 KPX e y 0 KPX e x 0 KPX e w 0 KPX e v 0 KPX e period 0 KPX e p 0 KPX e g 0 KPX e comma 0 KPX e b -10 KPX f quoteright 55 KPX f quotedblright 0 KPX f period -10 KPX f o -10 KPX f l 0 KPX f i 0 KPX f f -18 KPX f e -10 KPX f dotlessi -30 KPX f comma -10 KPX f a 0 KPX g y 0 KPX g r 0 KPX g period 0 KPX g o 0 KPX g i 0 KPX g g 0 KPX g e 0 KPX g comma 0 KPX g a 0 KPX h y 0 KPX i v 0 KPX k y 0 KPX k o -10 KPX k e -30 KPX l y 0 KPX l w 0 KPX m y 0 KPX m u 0 KPX n y 0 KPX n v -40 KPX n u 0 KPX o y -10 KPX o x -10 KPX o w -25 KPX o v -15 KPX o g 0 KPX p y 0 KPX period quoteright -95 KPX period quotedblright -95 KPX quotedblleft quoteleft 0 KPX quotedblleft A 0 KPX quotedblright space 0 KPX quoteleft quoteleft -74 KPX quoteleft A 0 KPX quoteright v -15 KPX quoteright t -37 KPX quoteright space -74 KPX quoteright s -74 KPX quoteright r -15 KPX quoteright quoteright -74 KPX quoteright quotedblright 0 KPX quoteright l 0 KPX quoteright d -15 KPX r y 0 KPX r v 0 KPX r u 0 KPX r t 0 KPX r s 0 KPX r r 0 KPX r q 0 KPX r period -65 KPX r p 0 KPX r o 0 KPX r n 0 KPX r m 0 KPX r l 0 KPX r k 0 KPX r i 0 KPX r hyphen 0 KPX r g 0 KPX r e 0 KPX r d 0 KPX r comma -65 KPX r c 0 KPX r a 0 KPX s w 0 KPX space quoteleft 0 KPX space quotedblleft 0 KPX space Y -70 KPX space W -70 KPX space V -70 KPX space T 0 KPX space A -37 KPX v period -37 KPX v o -15 KPX v e -15 KPX v comma -37 KPX v a 0 KPX w period -37 KPX w o -15 KPX w h 0 KPX w e -10 KPX w comma -37 KPX w a -10 KPX x e -10 KPX y period -37 KPX y o 0 KPX y e 0 KPX y comma -37 KPX y a 0 KPX z o 0 KPX z e 0 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 172 207 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 207 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 207 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 172 207 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 157 192 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 207 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 172 207 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 187 207 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 187 207 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 172 207 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 33 207 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 53 207 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 48 207 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 33 207 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 207 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 207 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 207 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 207 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 207 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 207 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 207 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 210 207 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 230 207 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 230 207 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 200 207 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 154 207 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 207 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 207 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 74 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 74 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 46 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -42 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -37 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -37 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 97 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 69 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 74 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 97 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 102 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 41 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 13 0 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Courier-BoldOblique.afm�����������������������������������������������0000644�0001750�0001750�00000036627�11462120062�020757� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Tue Sep 17 14:13:24 1991 Comment UniqueID 36389 Comment VMusage 10055 54684 FontName Courier-BoldOblique FullName Courier Bold Oblique FamilyName Courier Weight Bold ItalicAngle -12 IsFixedPitch true FontBBox -56 -250 868 801 UnderlinePosition -100 UnderlineThickness 50 Version 002.004 Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 439 Ascender 626 Descender -142 StartCharMetrics 260 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 216 -15 495 572 ; C 34 ; WX 600 ; N quotedbl ; B 212 277 584 562 ; C 35 ; WX 600 ; N numbersign ; B 88 -45 640 651 ; C 36 ; WX 600 ; N dollar ; B 87 -126 629 666 ; C 37 ; WX 600 ; N percent ; B 102 -15 624 616 ; C 38 ; WX 600 ; N ampersand ; B 62 -15 594 543 ; C 39 ; WX 600 ; N quoteright ; B 230 277 542 562 ; C 40 ; WX 600 ; N parenleft ; B 266 -102 592 616 ; C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; C 42 ; WX 600 ; N asterisk ; B 179 219 597 601 ; C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; C 46 ; WX 600 ; N period ; B 207 -15 426 171 ; C 47 ; WX 600 ; N slash ; B 91 -77 626 626 ; C 48 ; WX 600 ; N zero ; B 136 -15 592 616 ; C 49 ; WX 600 ; N one ; B 93 0 561 616 ; C 50 ; WX 600 ; N two ; B 61 0 593 616 ; C 51 ; WX 600 ; N three ; B 72 -15 571 616 ; C 52 ; WX 600 ; N four ; B 82 0 558 616 ; C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; C 54 ; WX 600 ; N six ; B 136 -15 652 616 ; C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; C 57 ; WX 600 ; N nine ; B 76 -15 592 616 ; C 58 ; WX 600 ; N colon ; B 206 -15 479 425 ; C 59 ; WX 600 ; N semicolon ; B 99 -111 480 425 ; C 60 ; WX 600 ; N less ; B 121 15 612 501 ; C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; C 63 ; WX 600 ; N question ; B 183 -14 591 580 ; C 64 ; WX 600 ; N at ; B 66 -15 641 616 ; C 65 ; WX 600 ; N A ; B -9 0 631 562 ; C 66 ; WX 600 ; N B ; B 30 0 629 562 ; C 67 ; WX 600 ; N C ; B 75 -18 674 580 ; C 68 ; WX 600 ; N D ; B 30 0 664 562 ; C 69 ; WX 600 ; N E ; B 25 0 669 562 ; C 70 ; WX 600 ; N F ; B 39 0 683 562 ; C 71 ; WX 600 ; N G ; B 75 -18 674 580 ; C 72 ; WX 600 ; N H ; B 20 0 699 562 ; C 73 ; WX 600 ; N I ; B 77 0 642 562 ; C 74 ; WX 600 ; N J ; B 59 -18 720 562 ; C 75 ; WX 600 ; N K ; B 21 0 691 562 ; C 76 ; WX 600 ; N L ; B 39 0 635 562 ; C 77 ; WX 600 ; N M ; B -2 0 721 562 ; C 78 ; WX 600 ; N N ; B 8 -12 729 562 ; C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; C 80 ; WX 600 ; N P ; B 48 0 642 562 ; C 81 ; WX 600 ; N Q ; B 84 -138 636 580 ; C 82 ; WX 600 ; N R ; B 24 0 617 562 ; C 83 ; WX 600 ; N S ; B 54 -22 672 582 ; C 84 ; WX 600 ; N T ; B 86 0 678 562 ; C 85 ; WX 600 ; N U ; B 101 -18 715 562 ; C 86 ; WX 600 ; N V ; B 84 0 732 562 ; C 87 ; WX 600 ; N W ; B 84 0 737 562 ; C 88 ; WX 600 ; N X ; B 12 0 689 562 ; C 89 ; WX 600 ; N Y ; B 109 0 708 562 ; C 90 ; WX 600 ; N Z ; B 62 0 636 562 ; C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; C 92 ; WX 600 ; N backslash ; B 223 -77 496 626 ; C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; C 94 ; WX 600 ; N asciicircum ; B 171 250 555 616 ; C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; C 97 ; WX 600 ; N a ; B 62 -15 592 454 ; C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; C 100 ; WX 600 ; N d ; B 61 -15 644 626 ; C 101 ; WX 600 ; N e ; B 81 -15 604 454 ; C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 41 -146 673 454 ; C 104 ; WX 600 ; N h ; B 18 0 614 626 ; C 105 ; WX 600 ; N i ; B 77 0 545 658 ; C 106 ; WX 600 ; N j ; B 37 -146 580 658 ; C 107 ; WX 600 ; N k ; B 33 0 642 626 ; C 108 ; WX 600 ; N l ; B 77 0 545 626 ; C 109 ; WX 600 ; N m ; B -22 0 648 454 ; C 110 ; WX 600 ; N n ; B 18 0 614 454 ; C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; C 112 ; WX 600 ; N p ; B -31 -142 622 454 ; C 113 ; WX 600 ; N q ; B 61 -142 684 454 ; C 114 ; WX 600 ; N r ; B 47 0 654 454 ; C 115 ; WX 600 ; N s ; B 67 -17 607 459 ; C 116 ; WX 600 ; N t ; B 118 -15 566 562 ; C 117 ; WX 600 ; N u ; B 70 -15 591 439 ; C 118 ; WX 600 ; N v ; B 70 0 694 439 ; C 119 ; WX 600 ; N w ; B 53 0 711 439 ; C 120 ; WX 600 ; N x ; B 6 0 670 439 ; C 121 ; WX 600 ; N y ; B -20 -142 694 439 ; C 122 ; WX 600 ; N z ; B 81 0 613 439 ; C 123 ; WX 600 ; N braceleft ; B 204 -102 595 616 ; C 124 ; WX 600 ; N bar ; B 202 -250 504 750 ; C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; C 126 ; WX 600 ; N asciitilde ; B 120 153 589 356 ; C 161 ; WX 600 ; N exclamdown ; B 197 -146 477 449 ; C 162 ; WX 600 ; N cent ; B 121 -49 604 614 ; C 163 ; WX 600 ; N sterling ; B 107 -28 650 611 ; C 164 ; WX 600 ; N fraction ; B 22 -60 707 661 ; C 165 ; WX 600 ; N yen ; B 98 0 709 562 ; C 166 ; WX 600 ; N florin ; B -56 -131 701 616 ; C 167 ; WX 600 ; N section ; B 74 -70 619 580 ; C 168 ; WX 600 ; N currency ; B 77 49 643 517 ; C 169 ; WX 600 ; N quotesingle ; B 304 277 492 562 ; C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; C 171 ; WX 600 ; N guillemotleft ; B 63 70 638 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 196 70 544 446 ; C 173 ; WX 600 ; N guilsinglright ; B 166 70 514 446 ; C 174 ; WX 600 ; N fi ; B 12 0 643 626 ; C 175 ; WX 600 ; N fl ; B 12 0 643 626 ; C 177 ; WX 600 ; N endash ; B 108 203 602 313 ; C 178 ; WX 600 ; N dagger ; B 176 -70 586 580 ; C 179 ; WX 600 ; N daggerdbl ; B 122 -70 586 580 ; C 180 ; WX 600 ; N periodcentered ; B 249 165 461 351 ; C 182 ; WX 600 ; N paragraph ; B 61 -70 699 580 ; C 183 ; WX 600 ; N bullet ; B 197 132 523 430 ; C 184 ; WX 600 ; N quotesinglbase ; B 145 -142 457 143 ; C 185 ; WX 600 ; N quotedblbase ; B 35 -142 559 143 ; C 186 ; WX 600 ; N quotedblright ; B 120 277 644 562 ; C 187 ; WX 600 ; N guillemotright ; B 72 70 647 446 ; C 188 ; WX 600 ; N ellipsis ; B 35 -15 586 116 ; C 189 ; WX 600 ; N perthousand ; B -44 -15 742 616 ; C 191 ; WX 600 ; N questiondown ; B 101 -146 509 449 ; C 193 ; WX 600 ; N grave ; B 272 508 503 661 ; C 194 ; WX 600 ; N acute ; B 313 508 608 661 ; C 195 ; WX 600 ; N circumflex ; B 212 483 606 657 ; C 196 ; WX 600 ; N tilde ; B 200 493 642 636 ; C 197 ; WX 600 ; N macron ; B 195 505 636 585 ; C 198 ; WX 600 ; N breve ; B 217 468 651 631 ; C 199 ; WX 600 ; N dotaccent ; B 346 485 490 625 ; C 200 ; WX 600 ; N dieresis ; B 244 485 592 625 ; C 202 ; WX 600 ; N ring ; B 319 481 528 678 ; C 203 ; WX 600 ; N cedilla ; B 169 -206 367 0 ; C 205 ; WX 600 ; N hungarumlaut ; B 172 488 728 661 ; C 206 ; WX 600 ; N ogonek ; B 144 -199 350 0 ; C 207 ; WX 600 ; N caron ; B 238 493 632 667 ; C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ; C 225 ; WX 600 ; N AE ; B -29 0 707 562 ; C 227 ; WX 600 ; N ordfeminine ; B 189 196 526 580 ; C 232 ; WX 600 ; N Lslash ; B 39 0 635 562 ; C 233 ; WX 600 ; N Oslash ; B 48 -22 672 584 ; C 234 ; WX 600 ; N OE ; B 26 0 700 562 ; C 235 ; WX 600 ; N ordmasculine ; B 189 196 542 580 ; C 241 ; WX 600 ; N ae ; B 21 -15 651 454 ; C 245 ; WX 600 ; N dotlessi ; B 77 0 545 439 ; C 248 ; WX 600 ; N lslash ; B 77 0 578 626 ; C 249 ; WX 600 ; N oslash ; B 55 -24 637 463 ; C 250 ; WX 600 ; N oe ; B 19 -15 661 454 ; C 251 ; WX 600 ; N germandbls ; B 22 -15 628 626 ; C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 748 ; C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; C -1 ; WX 600 ; N merge ; B 168 -15 533 487 ; C -1 ; WX 600 ; N degree ; B 173 243 569 616 ; C -1 ; WX 600 ; N dectab ; B 8 0 615 320 ; C -1 ; WX 600 ; N ll ; B 1 0 653 626 ; C -1 ; WX 600 ; N IJ ; B -8 -18 741 562 ; C -1 ; WX 600 ; N Eacute ; B 25 0 669 784 ; C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; C -1 ; WX 600 ; N ucircumflex ; B 70 -15 591 657 ; C -1 ; WX 600 ; N left ; B 109 44 589 371 ; C -1 ; WX 600 ; N threesuperior ; B 193 222 525 616 ; C -1 ; WX 600 ; N up ; B 196 0 523 447 ; C -1 ; WX 600 ; N multiply ; B 105 39 606 478 ; C -1 ; WX 600 ; N Scaron ; B 54 -22 672 790 ; C -1 ; WX 600 ; N tab ; B 19 0 641 562 ; C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 715 780 ; C -1 ; WX 600 ; N divide ; B 114 16 596 500 ; C -1 ; WX 600 ; N Acircumflex ; B -9 0 631 780 ; C -1 ; WX 600 ; N eacute ; B 81 -15 608 661 ; C -1 ; WX 600 ; N uacute ; B 70 -15 608 661 ; C -1 ; WX 600 ; N Aacute ; B -9 0 665 784 ; C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; C -1 ; WX 600 ; N twosuperior ; B 192 230 541 616 ; C -1 ; WX 600 ; N Ecircumflex ; B 25 0 669 780 ; C -1 ; WX 600 ; N ntilde ; B 18 0 642 636 ; C -1 ; WX 600 ; N down ; B 168 -15 496 439 ; C -1 ; WX 600 ; N center ; B 103 14 623 580 ; C -1 ; WX 600 ; N onesuperior ; B 213 230 514 616 ; C -1 ; WX 600 ; N ij ; B 6 -146 714 658 ; C -1 ; WX 600 ; N edieresis ; B 81 -15 604 625 ; C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ; C -1 ; WX 600 ; N odieresis ; B 71 -15 622 625 ; C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; C -1 ; WX 600 ; N threequarters ; B 8 -60 698 661 ; C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ; C -1 ; WX 600 ; N prescription ; B 24 -15 632 562 ; C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ; C -1 ; WX 600 ; N largebullet ; B 307 229 413 333 ; C -1 ; WX 600 ; N egrave ; B 81 -15 604 661 ; C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; C -1 ; WX 600 ; N notegraphic ; B 91 -15 619 572 ; C -1 ; WX 600 ; N Udieresis ; B 101 -18 715 748 ; C -1 ; WX 600 ; N Gcaron ; B 75 -18 674 790 ; C -1 ; WX 600 ; N arrowdown ; B 174 -15 486 608 ; C -1 ; WX 600 ; N format ; B -26 -146 243 601 ; C -1 ; WX 600 ; N Otilde ; B 74 -18 668 759 ; C -1 ; WX 600 ; N Idieresis ; B 77 0 642 748 ; C -1 ; WX 600 ; N adieresis ; B 62 -15 592 625 ; C -1 ; WX 600 ; N ecircumflex ; B 81 -15 606 657 ; C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ; C -1 ; WX 600 ; N onequarter ; B 14 -60 706 661 ; C -1 ; WX 600 ; N LL ; B -45 0 694 562 ; C -1 ; WX 600 ; N agrave ; B 62 -15 592 661 ; C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; C -1 ; WX 600 ; N Scedilla ; B 54 -206 672 582 ; C -1 ; WX 600 ; N Idot ; B 77 0 642 748 ; C -1 ; WX 600 ; N Iacute ; B 77 0 642 784 ; C -1 ; WX 600 ; N indent ; B 99 45 579 372 ; C -1 ; WX 600 ; N Ugrave ; B 101 -18 715 784 ; C -1 ; WX 600 ; N scaron ; B 67 -17 632 667 ; C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ; C -1 ; WX 600 ; N Aring ; B -9 0 631 801 ; C -1 ; WX 600 ; N Ccedilla ; B 74 -206 674 580 ; C -1 ; WX 600 ; N Igrave ; B 77 0 642 784 ; C -1 ; WX 600 ; N brokenbar ; B 218 -175 488 675 ; C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; C -1 ; WX 600 ; N otilde ; B 71 -15 642 636 ; C -1 ; WX 600 ; N Yacute ; B 109 0 708 784 ; C -1 ; WX 600 ; N lira ; B 107 -28 650 611 ; C -1 ; WX 600 ; N Icircumflex ; B 77 0 642 780 ; C -1 ; WX 600 ; N Atilde ; B -9 0 638 759 ; C -1 ; WX 600 ; N Uacute ; B 101 -18 715 784 ; C -1 ; WX 600 ; N Ydieresis ; B 109 0 708 748 ; C -1 ; WX 600 ; N ydieresis ; B -20 -142 694 625 ; C -1 ; WX 600 ; N idieresis ; B 77 0 552 625 ; C -1 ; WX 600 ; N Adieresis ; B -9 0 631 748 ; C -1 ; WX 600 ; N mu ; B 50 -142 591 439 ; C -1 ; WX 600 ; N trademark ; B 86 230 868 562 ; C -1 ; WX 600 ; N oacute ; B 71 -15 622 661 ; C -1 ; WX 600 ; N acircumflex ; B 62 -15 592 657 ; C -1 ; WX 600 ; N Agrave ; B -9 0 631 784 ; C -1 ; WX 600 ; N return ; B 79 0 700 562 ; C -1 ; WX 600 ; N atilde ; B 62 -15 642 636 ; C -1 ; WX 600 ; N square ; B 19 0 700 562 ; C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; C -1 ; WX 600 ; N stop ; B 19 0 700 562 ; C -1 ; WX 600 ; N udieresis ; B 70 -15 591 625 ; C -1 ; WX 600 ; N arrowup ; B 244 3 556 626 ; C -1 ; WX 600 ; N igrave ; B 77 0 545 661 ; C -1 ; WX 600 ; N Edieresis ; B 25 0 669 748 ; C -1 ; WX 600 ; N zcaron ; B 81 0 632 667 ; C -1 ; WX 600 ; N arrowboth ; B 40 143 688 455 ; C -1 ; WX 600 ; N gcaron ; B 41 -146 673 667 ; C -1 ; WX 600 ; N arrowleft ; B 40 143 708 455 ; C -1 ; WX 600 ; N aacute ; B 62 -15 608 661 ; C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; C -1 ; WX 600 ; N scedilla ; B 67 -206 607 459 ; C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ; C -1 ; WX 600 ; N onehalf ; B 23 -60 715 661 ; C -1 ; WX 600 ; N ugrave ; B 70 -15 591 661 ; C -1 ; WX 600 ; N Ntilde ; B 8 -12 729 759 ; C -1 ; WX 600 ; N iacute ; B 77 0 608 661 ; C -1 ; WX 600 ; N arrowright ; B 20 143 688 455 ; C -1 ; WX 600 ; N Thorn ; B 48 0 619 562 ; C -1 ; WX 600 ; N Egrave ; B 25 0 669 784 ; C -1 ; WX 600 ; N thorn ; B -31 -142 622 626 ; C -1 ; WX 600 ; N aring ; B 62 -15 592 678 ; C -1 ; WX 600 ; N yacute ; B -20 -142 694 661 ; C -1 ; WX 600 ; N icircumflex ; B 77 0 566 657 ; EndCharMetrics StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 56 123 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 123 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 6 123 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave -24 123 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 16 123 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde -4 123 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 123 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 123 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 26 123 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 123 ; CC Gcaron 2 ; PCC G 0 0 ; PCC caron 36 123 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 123 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 123 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 26 123 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 123 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 26 123 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 123 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 123 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 26 123 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 123 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 26 123 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 26 123 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 123 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 123 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 26 123 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 123 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 123 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 26 123 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 26 123 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Palatino-Italic.afm���������������������������������������������������0000644�0001750�0001750�00000037455�11462120062�020122� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jul 2 22:37:33 1990 Comment UniqueID 31796 Comment VMusage 37415 48307 FontName Palatino-Italic FullName Palatino Italic FamilyName Palatino Weight Medium ItalicAngle -10 IsFixedPitch false FontBBox -170 -276 1010 918 UnderlinePosition -100 UnderlineThickness 50 Version 001.005 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 692 XHeight 482 Ascender 733 Descender -276 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 76 -8 292 733 ; C 34 ; WX 500 ; N quotedbl ; B 140 508 455 733 ; C 35 ; WX 500 ; N numbersign ; B 4 0 495 692 ; C 36 ; WX 500 ; N dollar ; B 15 -113 452 733 ; C 37 ; WX 889 ; N percent ; B 74 -7 809 710 ; C 38 ; WX 778 ; N ampersand ; B 47 -18 766 692 ; C 39 ; WX 278 ; N quoteright ; B 78 488 258 733 ; C 40 ; WX 333 ; N parenleft ; B 54 -106 331 733 ; C 41 ; WX 333 ; N parenright ; B 2 -106 279 733 ; C 42 ; WX 389 ; N asterisk ; B 76 368 400 706 ; C 43 ; WX 606 ; N plus ; B 51 0 555 504 ; C 44 ; WX 250 ; N comma ; B 8 -143 203 123 ; C 45 ; WX 333 ; N hyphen ; B 19 223 304 281 ; C 46 ; WX 250 ; N period ; B 53 -5 158 112 ; C 47 ; WX 296 ; N slash ; B -40 -119 392 733 ; C 48 ; WX 500 ; N zero ; B 36 -11 480 699 ; C 49 ; WX 500 ; N one ; B 54 -3 398 699 ; C 50 ; WX 500 ; N two ; B 12 -3 437 699 ; C 51 ; WX 500 ; N three ; B 22 -11 447 699 ; C 52 ; WX 500 ; N four ; B 15 -3 478 699 ; C 53 ; WX 500 ; N five ; B 14 -11 491 693 ; C 54 ; WX 500 ; N six ; B 49 -11 469 699 ; C 55 ; WX 500 ; N seven ; B 53 -3 502 692 ; C 56 ; WX 500 ; N eight ; B 36 -11 469 699 ; C 57 ; WX 500 ; N nine ; B 32 -11 468 699 ; C 58 ; WX 250 ; N colon ; B 44 -5 207 458 ; C 59 ; WX 250 ; N semicolon ; B -9 -146 219 456 ; C 60 ; WX 606 ; N less ; B 53 -6 554 516 ; C 61 ; WX 606 ; N equal ; B 51 126 555 378 ; C 62 ; WX 606 ; N greater ; B 53 -6 554 516 ; C 63 ; WX 500 ; N question ; B 114 -8 427 706 ; C 64 ; WX 747 ; N at ; B 27 -18 718 706 ; C 65 ; WX 722 ; N A ; B -19 -3 677 705 ; C 66 ; WX 611 ; N B ; B 26 -6 559 692 ; C 67 ; WX 667 ; N C ; B 45 -18 651 706 ; C 68 ; WX 778 ; N D ; B 28 -3 741 692 ; C 69 ; WX 611 ; N E ; B 30 -3 570 692 ; C 70 ; WX 556 ; N F ; B 0 -3 548 692 ; C 71 ; WX 722 ; N G ; B 50 -18 694 706 ; C 72 ; WX 778 ; N H ; B -3 -3 800 692 ; C 73 ; WX 333 ; N I ; B 7 -3 354 692 ; C 74 ; WX 333 ; N J ; B -35 -206 358 692 ; C 75 ; WX 667 ; N K ; B 13 -3 683 692 ; C 76 ; WX 556 ; N L ; B 16 -3 523 692 ; C 77 ; WX 944 ; N M ; B -19 -18 940 692 ; C 78 ; WX 778 ; N N ; B 2 -11 804 692 ; C 79 ; WX 778 ; N O ; B 53 -18 748 706 ; C 80 ; WX 611 ; N P ; B 9 -3 594 692 ; C 81 ; WX 778 ; N Q ; B 53 -201 748 706 ; C 82 ; WX 667 ; N R ; B 9 -3 639 692 ; C 83 ; WX 556 ; N S ; B 42 -18 506 706 ; C 84 ; WX 611 ; N T ; B 53 -3 635 692 ; C 85 ; WX 778 ; N U ; B 88 -18 798 692 ; C 86 ; WX 722 ; N V ; B 75 -8 754 692 ; C 87 ; WX 944 ; N W ; B 71 -8 980 700 ; C 88 ; WX 722 ; N X ; B 20 -3 734 692 ; C 89 ; WX 667 ; N Y ; B 52 -3 675 705 ; C 90 ; WX 667 ; N Z ; B 20 -3 637 692 ; C 91 ; WX 333 ; N bracketleft ; B 18 -100 326 733 ; C 92 ; WX 606 ; N backslash ; B 81 0 513 733 ; C 93 ; WX 333 ; N bracketright ; B 7 -100 315 733 ; C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 278 ; N quoteleft ; B 78 488 258 733 ; C 97 ; WX 444 ; N a ; B 4 -11 406 482 ; C 98 ; WX 463 ; N b ; B 37 -11 433 733 ; C 99 ; WX 407 ; N c ; B 25 -11 389 482 ; C 100 ; WX 500 ; N d ; B 17 -11 483 733 ; C 101 ; WX 389 ; N e ; B 15 -11 374 482 ; C 102 ; WX 278 ; N f ; B -162 -276 413 733 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B -37 -276 498 482 ; C 104 ; WX 500 ; N h ; B 10 -9 471 733 ; C 105 ; WX 278 ; N i ; B 34 -9 264 712 ; C 106 ; WX 278 ; N j ; B -70 -276 265 712 ; C 107 ; WX 444 ; N k ; B 8 -9 449 733 ; C 108 ; WX 278 ; N l ; B 36 -9 251 733 ; C 109 ; WX 778 ; N m ; B 24 -9 740 482 ; C 110 ; WX 556 ; N n ; B 24 -9 514 482 ; C 111 ; WX 444 ; N o ; B 17 -11 411 482 ; C 112 ; WX 500 ; N p ; B -7 -276 465 482 ; C 113 ; WX 463 ; N q ; B 24 -276 432 482 ; C 114 ; WX 389 ; N r ; B 26 -9 384 482 ; C 115 ; WX 389 ; N s ; B 9 -11 345 482 ; C 116 ; WX 333 ; N t ; B 41 -9 310 646 ; C 117 ; WX 556 ; N u ; B 32 -11 512 482 ; C 118 ; WX 500 ; N v ; B 21 -11 477 482 ; C 119 ; WX 722 ; N w ; B 21 -11 699 482 ; C 120 ; WX 500 ; N x ; B 9 -11 484 482 ; C 121 ; WX 500 ; N y ; B -8 -276 490 482 ; C 122 ; WX 444 ; N z ; B -1 -11 416 482 ; C 123 ; WX 333 ; N braceleft ; B 15 -100 319 733 ; C 124 ; WX 606 ; N bar ; B 275 0 331 733 ; C 125 ; WX 333 ; N braceright ; B 14 -100 318 733 ; C 126 ; WX 606 ; N asciitilde ; B 51 168 555 339 ; C 161 ; WX 333 ; N exclamdown ; B 15 -276 233 467 ; C 162 ; WX 500 ; N cent ; B 56 -96 418 551 ; C 163 ; WX 500 ; N sterling ; B 2 -18 479 708 ; C 164 ; WX 167 ; N fraction ; B -170 0 337 699 ; C 165 ; WX 500 ; N yen ; B 35 -3 512 699 ; C 166 ; WX 500 ; N florin ; B 5 -276 470 708 ; C 167 ; WX 500 ; N section ; B 14 -220 463 706 ; C 168 ; WX 500 ; N currency ; B 14 115 486 577 ; C 169 ; WX 333 ; N quotesingle ; B 140 508 288 733 ; C 170 ; WX 500 ; N quotedblleft ; B 98 488 475 733 ; C 171 ; WX 500 ; N guillemotleft ; B 57 70 437 440 ; C 172 ; WX 333 ; N guilsinglleft ; B 57 70 270 440 ; C 173 ; WX 333 ; N guilsinglright ; B 63 70 276 440 ; C 174 ; WX 528 ; N fi ; B -162 -276 502 733 ; C 175 ; WX 545 ; N fl ; B -162 -276 520 733 ; C 177 ; WX 500 ; N endash ; B -10 228 510 278 ; C 178 ; WX 500 ; N dagger ; B 48 0 469 692 ; C 179 ; WX 500 ; N daggerdbl ; B 10 -162 494 692 ; C 180 ; WX 250 ; N periodcentered ; B 53 195 158 312 ; C 182 ; WX 500 ; N paragraph ; B 33 -224 611 692 ; C 183 ; WX 500 ; N bullet ; B 86 182 430 526 ; C 184 ; WX 278 ; N quotesinglbase ; B 27 -122 211 120 ; C 185 ; WX 500 ; N quotedblbase ; B 43 -122 424 120 ; C 186 ; WX 500 ; N quotedblright ; B 98 488 475 733 ; C 187 ; WX 500 ; N guillemotright ; B 63 70 443 440 ; C 188 ; WX 1000 ; N ellipsis ; B 102 -5 873 112 ; C 189 ; WX 1000 ; N perthousand ; B 72 -6 929 717 ; C 191 ; WX 500 ; N questiondown ; B 57 -246 370 467 ; C 193 ; WX 333 ; N grave ; B 86 518 310 687 ; C 194 ; WX 333 ; N acute ; B 122 518 346 687 ; C 195 ; WX 333 ; N circumflex ; B 56 510 350 679 ; C 196 ; WX 333 ; N tilde ; B 63 535 390 638 ; C 197 ; WX 333 ; N macron ; B 74 538 386 589 ; C 198 ; WX 333 ; N breve ; B 92 518 393 677 ; C 199 ; WX 333 ; N dotaccent ; B 175 537 283 645 ; C 200 ; WX 333 ; N dieresis ; B 78 537 378 637 ; C 202 ; WX 333 ; N ring ; B 159 508 359 708 ; C 203 ; WX 333 ; N cedilla ; B -9 -216 202 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 46 518 385 730 ; C 206 ; WX 333 ; N ogonek ; B 38 -207 196 -18 ; C 207 ; WX 333 ; N caron ; B 104 510 409 679 ; C 208 ; WX 1000 ; N emdash ; B -10 228 1010 278 ; C 225 ; WX 941 ; N AE ; B -4 -3 902 692 ; C 227 ; WX 333 ; N ordfeminine ; B 60 404 321 699 ; C 232 ; WX 556 ; N Lslash ; B -16 -3 523 692 ; C 233 ; WX 778 ; N Oslash ; B 32 -39 762 721 ; C 234 ; WX 1028 ; N OE ; B 56 -18 989 706 ; C 235 ; WX 333 ; N ordmasculine ; B 66 404 322 699 ; C 241 ; WX 638 ; N ae ; B 1 -11 623 482 ; C 245 ; WX 278 ; N dotlessi ; B 34 -9 241 482 ; C 248 ; WX 278 ; N lslash ; B -10 -9 302 733 ; C 249 ; WX 444 ; N oslash ; B -18 -24 460 510 ; C 250 ; WX 669 ; N oe ; B 17 -11 654 482 ; C 251 ; WX 500 ; N germandbls ; B -160 -276 488 733 ; C -1 ; WX 667 ; N Zcaron ; B 20 -3 637 907 ; C -1 ; WX 407 ; N ccedilla ; B 25 -216 389 482 ; C -1 ; WX 500 ; N ydieresis ; B -8 -276 490 657 ; C -1 ; WX 444 ; N atilde ; B 4 -11 446 650 ; C -1 ; WX 278 ; N icircumflex ; B 29 -9 323 699 ; C -1 ; WX 300 ; N threesuperior ; B 28 273 304 699 ; C -1 ; WX 389 ; N ecircumflex ; B 15 -11 398 699 ; C -1 ; WX 500 ; N thorn ; B -39 -276 433 733 ; C -1 ; WX 389 ; N egrave ; B 15 -11 374 707 ; C -1 ; WX 300 ; N twosuperior ; B 13 278 290 699 ; C -1 ; WX 389 ; N eacute ; B 15 -11 394 707 ; C -1 ; WX 444 ; N otilde ; B 17 -11 446 650 ; C -1 ; WX 722 ; N Aacute ; B -19 -3 677 897 ; C -1 ; WX 444 ; N ocircumflex ; B 17 -11 411 699 ; C -1 ; WX 500 ; N yacute ; B -8 -276 490 707 ; C -1 ; WX 556 ; N udieresis ; B 32 -11 512 657 ; C -1 ; WX 750 ; N threequarters ; B 35 -2 715 699 ; C -1 ; WX 444 ; N acircumflex ; B 4 -11 406 699 ; C -1 ; WX 778 ; N Eth ; B 19 -3 741 692 ; C -1 ; WX 389 ; N edieresis ; B 15 -11 406 657 ; C -1 ; WX 556 ; N ugrave ; B 32 -11 512 707 ; C -1 ; WX 1000 ; N trademark ; B 52 285 951 689 ; C -1 ; WX 444 ; N ograve ; B 17 -11 411 707 ; C -1 ; WX 389 ; N scaron ; B 9 -11 419 687 ; C -1 ; WX 333 ; N Idieresis ; B 7 -3 418 847 ; C -1 ; WX 556 ; N uacute ; B 32 -11 512 707 ; C -1 ; WX 444 ; N agrave ; B 4 -11 406 707 ; C -1 ; WX 556 ; N ntilde ; B 24 -9 514 650 ; C -1 ; WX 444 ; N aring ; B 4 -11 406 728 ; C -1 ; WX 444 ; N zcaron ; B -1 -11 447 687 ; C -1 ; WX 333 ; N Icircumflex ; B 7 -3 390 889 ; C -1 ; WX 778 ; N Ntilde ; B 2 -11 804 866 ; C -1 ; WX 556 ; N ucircumflex ; B 32 -11 512 699 ; C -1 ; WX 611 ; N Ecircumflex ; B 30 -3 570 889 ; C -1 ; WX 333 ; N Iacute ; B 7 -3 406 897 ; C -1 ; WX 667 ; N Ccedilla ; B 45 -216 651 706 ; C -1 ; WX 778 ; N Odieresis ; B 53 -18 748 847 ; C -1 ; WX 556 ; N Scaron ; B 42 -18 539 907 ; C -1 ; WX 611 ; N Edieresis ; B 30 -3 570 847 ; C -1 ; WX 333 ; N Igrave ; B 7 -3 354 897 ; C -1 ; WX 444 ; N adieresis ; B 4 -11 434 657 ; C -1 ; WX 778 ; N Ograve ; B 53 -18 748 897 ; C -1 ; WX 611 ; N Egrave ; B 30 -3 570 897 ; C -1 ; WX 667 ; N Ydieresis ; B 52 -3 675 847 ; C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ; C -1 ; WX 778 ; N Otilde ; B 53 -18 748 866 ; C -1 ; WX 750 ; N onequarter ; B 31 -2 715 699 ; C -1 ; WX 778 ; N Ugrave ; B 88 -18 798 897 ; C -1 ; WX 778 ; N Ucircumflex ; B 88 -18 798 889 ; C -1 ; WX 611 ; N Thorn ; B 9 -3 570 692 ; C -1 ; WX 606 ; N divide ; B 51 0 555 504 ; C -1 ; WX 722 ; N Atilde ; B -19 -3 677 866 ; C -1 ; WX 778 ; N Uacute ; B 88 -18 798 897 ; C -1 ; WX 778 ; N Ocircumflex ; B 53 -18 748 889 ; C -1 ; WX 606 ; N logicalnot ; B 51 118 555 378 ; C -1 ; WX 722 ; N Aring ; B -19 -3 677 918 ; C -1 ; WX 278 ; N idieresis ; B 34 -9 351 657 ; C -1 ; WX 278 ; N iacute ; B 34 -9 331 707 ; C -1 ; WX 444 ; N aacute ; B 4 -11 414 707 ; C -1 ; WX 606 ; N plusminus ; B 51 0 555 504 ; C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ; C -1 ; WX 778 ; N Udieresis ; B 88 -18 798 847 ; C -1 ; WX 606 ; N minus ; B 51 224 555 280 ; C -1 ; WX 300 ; N onesuperior ; B 61 278 285 699 ; C -1 ; WX 611 ; N Eacute ; B 30 -3 570 897 ; C -1 ; WX 722 ; N Acircumflex ; B -19 -3 677 889 ; C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ; C -1 ; WX 722 ; N Agrave ; B -19 -3 677 897 ; C -1 ; WX 444 ; N odieresis ; B 17 -11 434 657 ; C -1 ; WX 444 ; N oacute ; B 17 -11 414 707 ; C -1 ; WX 400 ; N degree ; B 90 389 390 689 ; C -1 ; WX 278 ; N igrave ; B 34 -9 271 707 ; C -1 ; WX 556 ; N mu ; B 15 -226 512 482 ; C -1 ; WX 778 ; N Oacute ; B 53 -18 748 897 ; C -1 ; WX 444 ; N eth ; B 17 -11 478 733 ; C -1 ; WX 722 ; N Adieresis ; B -19 -3 677 847 ; C -1 ; WX 667 ; N Yacute ; B 52 -3 675 897 ; C -1 ; WX 606 ; N brokenbar ; B 275 0 331 733 ; C -1 ; WX 750 ; N onehalf ; B 31 -2 721 699 ; EndCharMetrics StartKernData StartKernPairs 106 KPX A y -55 KPX A w -37 KPX A v -37 KPX A space -37 KPX A quoteright -55 KPX A Y -55 KPX A W -55 KPX A V -74 KPX A T -55 KPX F period -111 KPX F comma -111 KPX F A -111 KPX L y -37 KPX L space -18 KPX L quoteright -37 KPX L Y -74 KPX L W -74 KPX L V -74 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -129 KPX R y -37 KPX R Y -55 KPX R W -55 KPX R V -74 KPX R T -55 KPX T y -92 KPX T w -92 KPX T u -111 KPX T semicolon -74 KPX T s -111 KPX T r -111 KPX T period -74 KPX T o -111 KPX T i -55 KPX T hyphen -55 KPX T e -111 KPX T comma -74 KPX T colon -74 KPX T c -111 KPX T a -111 KPX T O -18 KPX T A -92 KPX V y -74 KPX V u -74 KPX V semicolon -37 KPX V r -92 KPX V period -129 KPX V o -74 KPX V i -74 KPX V hyphen -55 KPX V e -92 KPX V comma -129 KPX V colon -37 KPX V a -74 KPX V A -210 KPX W y -20 KPX W u -20 KPX W semicolon -18 KPX W r -20 KPX W period -55 KPX W o -20 KPX W i -20 KPX W hyphen -18 KPX W e -20 KPX W comma -55 KPX W colon -18 KPX W a -20 KPX W A -92 KPX Y v -74 KPX Y u -92 KPX Y semicolon -74 KPX Y q -92 KPX Y period -92 KPX Y p -74 KPX Y o -111 KPX Y i -55 KPX Y hyphen -74 KPX Y e -111 KPX Y comma -92 KPX Y colon -74 KPX Y a -92 KPX Y A -92 KPX f quoteright 55 KPX one one -55 KPX quoteleft quoteleft -74 KPX quoteright t -37 KPX quoteright space -55 KPX quoteright s -55 KPX quoteright quoteright -74 KPX r quoteright 37 KPX r q -18 KPX r period -74 KPX r o -18 KPX r h -18 KPX r g -18 KPX r e -18 KPX r comma -74 KPX r c -18 KPX v period -55 KPX v comma -55 KPX w period -55 KPX w comma -55 KPX y period -37 KPX y comma -37 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 271 210 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 261 210 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 255 210 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 210 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 235 210 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 255 228 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 199 210 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 179 210 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 179 210 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 210 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 60 210 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 210 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 40 210 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 263 228 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 210 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 210 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 255 210 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 251 210 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 228 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 130 228 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 277 210 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 255 210 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 210 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 210 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 227 210 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 187 210 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 228 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 68 20 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 20 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 44 20 ; CC aring 2 ; PCC a 0 0 ; PCC ring 36 20 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 12 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 37 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 48 20 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 48 20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 28 20 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 16 20 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -15 20 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 20 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -39 20 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 68 20 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 56 20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 56 20 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 36 20 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 56 12 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 10 8 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 124 20 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 20 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 100 20 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 96 20 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 20 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 38 8 ; EndComposites EndFontMetrics �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/ZapfDingbats.afm������������������������������������������������������0000644�0001750�0001750�00000022732�11462120062�017514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Fri Dec 1 12:57:42 1989 Comment UniqueID 26200 Comment VMusage 39281 49041 FontName ZapfDingbats FullName ITC Zapf Dingbats FamilyName ITC Zapf Dingbats Weight Medium ItalicAngle 0 IsFixedPitch false FontBBox -1 -143 981 820 UnderlinePosition -98 UnderlineThickness 54 Version 001.004 Notice Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation. EncodingScheme FontSpecific StartCharMetrics 202 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ; C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ; C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ; C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ; C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ; C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ; C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ; C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ; C 41 ; WX 690 ; N a117 ; B 35 138 655 553 ; C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ; C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ; C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ; C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ; C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ; C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ; C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ; C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ; C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ; C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ; C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ; C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ; C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ; C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ; C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ; C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ; C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ; C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ; C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ; C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ; C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ; C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ; C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ; C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ; C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ; C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ; C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ; C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ; C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ; C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ; C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ; C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ; C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ; C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ; C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ; C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ; C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ; C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ; C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ; C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ; C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ; C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ; C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ; C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ; C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ; C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ; C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ; C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ; C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ; C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ; C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ; C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ; C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ; C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ; C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ; C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ; C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ; C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ; C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ; C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ; C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ; C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ; C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ; C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ; C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ; C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ; C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ; C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ; C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ; C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ; C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ; C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ; C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ; C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ; C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ; C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ; C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ; C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ; C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ; C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ; C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ; C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ; C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ; C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ; C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ; C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ; C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ; C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ; C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ; C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ; C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ; C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ; C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ; C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ; C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ; C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ; C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ; C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ; C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ; C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ; C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ; C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ; C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ; C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ; C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ; C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ; C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ; C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ; C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ; C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ; C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ; C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ; C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ; C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ; C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ; C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ; C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ; C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ; C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ; C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ; C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ; C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ; C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ; C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ; C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ; C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ; C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ; C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ; C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ; C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ; C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ; C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ; C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ; C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ; C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ; C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ; C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ; C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ; C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ; C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ; C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ; C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ; C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ; C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ; C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ; C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ; C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ; C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ; C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ; C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ; C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ; C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ; C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ; C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ; C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ; C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ; C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ; C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ; C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ; C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ; C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ; C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ; C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ; C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ; C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ; C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ; C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ; C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ; C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ; C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ; C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ; C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ; C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ; C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ; C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ; C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ; C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ; C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ; C -1 ; WX 410 ; N a86 ; B 35 0 375 692 ; C -1 ; WX 509 ; N a85 ; B 35 0 475 692 ; C -1 ; WX 334 ; N a95 ; B 35 0 299 692 ; C -1 ; WX 509 ; N a205 ; B 35 0 475 692 ; C -1 ; WX 390 ; N a89 ; B 35 -14 356 705 ; C -1 ; WX 234 ; N a87 ; B 35 -14 199 705 ; C -1 ; WX 276 ; N a91 ; B 35 0 242 692 ; C -1 ; WX 390 ; N a90 ; B 35 -14 355 705 ; C -1 ; WX 410 ; N a206 ; B 35 0 375 692 ; C -1 ; WX 317 ; N a94 ; B 35 0 283 692 ; C -1 ; WX 317 ; N a93 ; B 35 0 283 692 ; C -1 ; WX 276 ; N a92 ; B 35 0 242 692 ; C -1 ; WX 334 ; N a96 ; B 35 0 299 692 ; C -1 ; WX 234 ; N a88 ; B 35 -14 199 705 ; EndCharMetrics EndFontMetrics ��������������������������������������./saods9/blt3.0.1/library/afm/Times-Bold.afm��������������������������������������������������������0000644�0001750�0001750�00000044310�11462120062�017073� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Mar 20 12:17:14 1990 Comment UniqueID 28417 Comment VMusage 30458 37350 FontName Times-Bold FullName Times Bold FamilyName Times Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -168 -218 1000 935 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 676 XHeight 461 Ascender 676 Descender -205 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ; C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ; C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ; C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ; C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ; C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ; C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ; C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ; C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ; C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ; C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ; C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ; C 46 ; WX 250 ; N period ; B 41 -13 210 156 ; C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ; C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ; C 49 ; WX 500 ; N one ; B 65 0 442 688 ; C 50 ; WX 500 ; N two ; B 17 0 478 688 ; C 51 ; WX 500 ; N three ; B 16 -14 468 688 ; C 52 ; WX 500 ; N four ; B 19 0 475 688 ; C 53 ; WX 500 ; N five ; B 22 -8 470 676 ; C 54 ; WX 500 ; N six ; B 28 -13 475 688 ; C 55 ; WX 500 ; N seven ; B 17 0 477 676 ; C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ; C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ; C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ; C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ; C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; C 63 ; WX 500 ; N question ; B 57 -13 445 689 ; C 64 ; WX 930 ; N at ; B 108 -19 822 691 ; C 65 ; WX 722 ; N A ; B 9 0 689 690 ; C 66 ; WX 667 ; N B ; B 16 0 619 676 ; C 67 ; WX 722 ; N C ; B 49 -19 687 691 ; C 68 ; WX 722 ; N D ; B 14 0 690 676 ; C 69 ; WX 667 ; N E ; B 16 0 641 676 ; C 70 ; WX 611 ; N F ; B 16 0 583 676 ; C 71 ; WX 778 ; N G ; B 37 -19 755 691 ; C 72 ; WX 778 ; N H ; B 21 0 759 676 ; C 73 ; WX 389 ; N I ; B 20 0 370 676 ; C 74 ; WX 500 ; N J ; B 3 -96 479 676 ; C 75 ; WX 778 ; N K ; B 30 0 769 676 ; C 76 ; WX 667 ; N L ; B 19 0 638 676 ; C 77 ; WX 944 ; N M ; B 14 0 921 676 ; C 78 ; WX 722 ; N N ; B 16 -18 701 676 ; C 79 ; WX 778 ; N O ; B 35 -19 743 691 ; C 80 ; WX 611 ; N P ; B 16 0 600 676 ; C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ; C 82 ; WX 722 ; N R ; B 26 0 715 676 ; C 83 ; WX 556 ; N S ; B 35 -19 513 692 ; C 84 ; WX 667 ; N T ; B 31 0 636 676 ; C 85 ; WX 722 ; N U ; B 16 -19 701 676 ; C 86 ; WX 722 ; N V ; B 16 -18 701 676 ; C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ; C 88 ; WX 722 ; N X ; B 16 0 699 676 ; C 89 ; WX 722 ; N Y ; B 15 0 699 676 ; C 90 ; WX 667 ; N Z ; B 28 0 634 676 ; C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ; C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ; C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ; C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ; C 97 ; WX 500 ; N a ; B 25 -14 488 473 ; C 98 ; WX 556 ; N b ; B 17 -14 521 676 ; C 99 ; WX 444 ; N c ; B 25 -14 430 473 ; C 100 ; WX 556 ; N d ; B 25 -14 534 676 ; C 101 ; WX 444 ; N e ; B 25 -14 426 473 ; C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 28 -206 483 473 ; C 104 ; WX 556 ; N h ; B 16 0 534 676 ; C 105 ; WX 278 ; N i ; B 16 0 255 691 ; C 106 ; WX 333 ; N j ; B -57 -203 263 691 ; C 107 ; WX 556 ; N k ; B 22 0 543 676 ; C 108 ; WX 278 ; N l ; B 16 0 255 676 ; C 109 ; WX 833 ; N m ; B 16 0 814 473 ; C 110 ; WX 556 ; N n ; B 21 0 539 473 ; C 111 ; WX 500 ; N o ; B 25 -14 476 473 ; C 112 ; WX 556 ; N p ; B 19 -205 524 473 ; C 113 ; WX 556 ; N q ; B 34 -205 536 473 ; C 114 ; WX 444 ; N r ; B 29 0 434 473 ; C 115 ; WX 389 ; N s ; B 25 -14 361 473 ; C 116 ; WX 333 ; N t ; B 20 -12 332 630 ; C 117 ; WX 556 ; N u ; B 16 -14 537 461 ; C 118 ; WX 500 ; N v ; B 21 -14 485 461 ; C 119 ; WX 722 ; N w ; B 23 -14 707 461 ; C 120 ; WX 500 ; N x ; B 12 0 484 461 ; C 121 ; WX 500 ; N y ; B 16 -205 480 461 ; C 122 ; WX 444 ; N z ; B 21 0 420 461 ; C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ; C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ; C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ; C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ; C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ; C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ; C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ; C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ; C 165 ; WX 500 ; N yen ; B -64 0 547 676 ; C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ; C 167 ; WX 500 ; N section ; B 57 -132 443 691 ; C 168 ; WX 500 ; N currency ; B -26 61 526 613 ; C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ; C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ; C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ; C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ; C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ; C 174 ; WX 556 ; N fi ; B 14 0 536 691 ; C 175 ; WX 556 ; N fl ; B 14 0 536 691 ; C 177 ; WX 500 ; N endash ; B 0 181 500 271 ; C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ; C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ; C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ; C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ; C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ; C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ; C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ; C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ; C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ; C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ; C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ; C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ; C 193 ; WX 333 ; N grave ; B 8 528 246 713 ; C 194 ; WX 333 ; N acute ; B 86 528 324 713 ; C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ; C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ; C 197 ; WX 333 ; N macron ; B 1 565 331 637 ; C 198 ; WX 333 ; N breve ; B 15 528 318 691 ; C 199 ; WX 333 ; N dotaccent ; B 103 537 230 667 ; C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ; C 202 ; WX 333 ; N ring ; B 60 527 273 740 ; C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ; C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ; C 207 ; WX 333 ; N caron ; B -2 528 335 704 ; C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ; C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ; C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ; C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ; C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ; C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ; C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ; C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ; C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ; C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ; C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ; C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ; C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ; C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ; C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ; C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ; C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ; C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ; C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ; C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ; C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ; C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ; C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ; C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ; C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ; C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ; C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ; C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ; C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ; C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ; C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ; C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ; C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ; C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ; C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ; C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ; C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ; C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ; C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ; C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ; C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ; C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ; C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ; C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ; C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ; C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ; C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ; C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ; C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ; C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ; C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ; C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ; C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ; C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ; C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ; C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ; C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ; C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ; C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ; C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ; C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ; C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ; C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ; C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ; C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ; C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ; C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ; C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ; C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ; C -1 ; WX 278 ; N idieresis ; B -36 0 301 667 ; C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ; C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ; C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ; C -1 ; WX 570 ; N minus ; B 33 209 537 297 ; C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ; C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ; C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ; C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ; C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ; C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ; C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ; C -1 ; WX 400 ; N degree ; B 57 402 343 688 ; C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ; C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ; C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ; C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ; C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ; C -1 ; WX 722 ; N Yacute ; B 15 0 699 928 ; C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ; C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ; EndCharMetrics StartKernData StartKernPairs 283 KPX A y -74 KPX A w -90 KPX A v -100 KPX A u -50 KPX A quoteright -74 KPX A quotedblright 0 KPX A p -25 KPX A Y -100 KPX A W -130 KPX A V -145 KPX A U -50 KPX A T -95 KPX A Q -45 KPX A O -45 KPX A G -55 KPX A C -55 KPX B period 0 KPX B comma 0 KPX B U -10 KPX B A -30 KPX D period -20 KPX D comma 0 KPX D Y -40 KPX D W -40 KPX D V -40 KPX D A -35 KPX F r 0 KPX F period -110 KPX F o -25 KPX F i 0 KPX F e -25 KPX F comma -92 KPX F a -25 KPX F A -90 KPX G period 0 KPX G comma 0 KPX J u -15 KPX J period -20 KPX J o -15 KPX J e -15 KPX J comma 0 KPX J a -15 KPX J A -30 KPX K y -45 KPX K u -15 KPX K o -25 KPX K e -25 KPX K O -30 KPX L y -55 KPX L quoteright -110 KPX L quotedblright -20 KPX L Y -92 KPX L W -92 KPX L V -92 KPX L T -92 KPX N period 0 KPX N comma 0 KPX N A -20 KPX O period 0 KPX O comma 0 KPX O Y -50 KPX O X -40 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -40 KPX P period -110 KPX P o -20 KPX P e -20 KPX P comma -92 KPX P a -10 KPX P A -74 KPX Q period -20 KPX Q comma 0 KPX Q U -10 KPX R Y -35 KPX R W -35 KPX R V -55 KPX R U -30 KPX R T -40 KPX R O -30 KPX S period 0 KPX S comma 0 KPX T y -74 KPX T w -74 KPX T u -92 KPX T semicolon -74 KPX T r -74 KPX T period -90 KPX T o -92 KPX T i -18 KPX T hyphen -92 KPX T h 0 KPX T e -92 KPX T comma -74 KPX T colon -74 KPX T a -92 KPX T O -18 KPX T A -90 KPX U period -50 KPX U comma -50 KPX U A -60 KPX V u -92 KPX V semicolon -92 KPX V period -145 KPX V o -100 KPX V i -37 KPX V hyphen -74 KPX V e -100 KPX V comma -129 KPX V colon -92 KPX V a -92 KPX V O -45 KPX V G -30 KPX V A -135 KPX W y -60 KPX W u -50 KPX W semicolon -55 KPX W period -92 KPX W o -75 KPX W i -18 KPX W hyphen -37 KPX W h 0 KPX W e -65 KPX W comma -92 KPX W colon -55 KPX W a -65 KPX W O -10 KPX W A -120 KPX Y u -92 KPX Y semicolon -92 KPX Y period -92 KPX Y o -111 KPX Y i -37 KPX Y hyphen -92 KPX Y e -111 KPX Y comma -92 KPX Y colon -92 KPX Y a -85 KPX Y O -35 KPX Y A -110 KPX a y 0 KPX a w 0 KPX a v -25 KPX a t 0 KPX a p 0 KPX a g 0 KPX a b 0 KPX b y 0 KPX b v -15 KPX b u -20 KPX b period -40 KPX b l 0 KPX b comma 0 KPX b b -10 KPX c y 0 KPX c period 0 KPX c l 0 KPX c k 0 KPX c h 0 KPX c comma 0 KPX colon space 0 KPX comma space 0 KPX comma quoteright -55 KPX comma quotedblright -45 KPX d y 0 KPX d w -15 KPX d v 0 KPX d period 0 KPX d d 0 KPX d comma 0 KPX e y 0 KPX e x 0 KPX e w 0 KPX e v -15 KPX e period 0 KPX e p 0 KPX e g 0 KPX e comma 0 KPX e b 0 KPX f quoteright 55 KPX f quotedblright 50 KPX f period -15 KPX f o -25 KPX f l 0 KPX f i -25 KPX f f 0 KPX f e 0 KPX f dotlessi -35 KPX f comma -15 KPX f a 0 KPX g y 0 KPX g r 0 KPX g period -15 KPX g o 0 KPX g i 0 KPX g g 0 KPX g e 0 KPX g comma 0 KPX g a 0 KPX h y -15 KPX i v -10 KPX k y -15 KPX k o -15 KPX k e -10 KPX l y 0 KPX l w 0 KPX m y 0 KPX m u 0 KPX n y 0 KPX n v -40 KPX n u 0 KPX o y 0 KPX o x 0 KPX o w -10 KPX o v -10 KPX o g 0 KPX p y 0 KPX period quoteright -55 KPX period quotedblright -55 KPX quotedblleft quoteleft 0 KPX quotedblleft A -10 KPX quotedblright space 0 KPX quoteleft quoteleft -63 KPX quoteleft A -10 KPX quoteright v -20 KPX quoteright t 0 KPX quoteright space -74 KPX quoteright s -37 KPX quoteright r -20 KPX quoteright quoteright -63 KPX quoteright quotedblright 0 KPX quoteright l 0 KPX quoteright d -20 KPX r y 0 KPX r v -10 KPX r u 0 KPX r t 0 KPX r s 0 KPX r r 0 KPX r q -18 KPX r period -100 KPX r p -10 KPX r o -18 KPX r n -15 KPX r m 0 KPX r l 0 KPX r k 0 KPX r i 0 KPX r hyphen -37 KPX r g -10 KPX r e -18 KPX r d 0 KPX r comma -92 KPX r c -18 KPX r a 0 KPX s w 0 KPX space quoteleft 0 KPX space quotedblleft 0 KPX space Y -55 KPX space W -30 KPX space V -45 KPX space T -30 KPX space A -55 KPX v period -70 KPX v o -10 KPX v e -10 KPX v comma -55 KPX v a -10 KPX w period -70 KPX w o -10 KPX w h 0 KPX w e 0 KPX w comma -55 KPX w a 0 KPX x e 0 KPX y period -70 KPX y o -25 KPX y e -10 KPX y comma -55 KPX y a 0 KPX z o 0 KPX z e 0 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 188 210 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 188 210 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 188 210 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 188 210 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 180 195 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 188 210 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 208 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 210 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 210 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 210 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 210 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 210 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 210 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 210 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 210 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 210 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 210 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 210 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 210 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 210 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 210 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 222 210 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 222 210 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 222 210 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 222 210 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 210 215 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 215 210 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 210 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 77 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 77 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 77 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 77 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 77 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 77 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 62 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 62 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 62 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 62 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 105 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 105 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 105 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 105 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ; EndComposites EndFontMetrics ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Courier.afm�����������������������������������������������������������0000644�0001750�0001750�00000036504�11462120062�016552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Tue Sep 17 07:47:21 1991 Comment UniqueID 36347 Comment VMusage 31037 39405 FontName Courier FullName Courier FamilyName Courier Weight Medium ItalicAngle 0 IsFixedPitch true FontBBox -28 -250 628 805 UnderlinePosition -100 UnderlineThickness 50 Version 002.004 Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 426 Ascender 629 Descender -157 StartCharMetrics 260 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ; C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; C 49 ; WX 600 ; N one ; B 96 0 505 622 ; C 50 ; WX 600 ; N two ; B 70 0 471 622 ; C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; C 52 ; WX 600 ; N four ; B 78 0 500 622 ; C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; C 60 ; WX 600 ; N less ; B 41 42 519 472 ; C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; C 65 ; WX 600 ; N A ; B 3 0 597 562 ; C 66 ; WX 600 ; N B ; B 43 0 559 562 ; C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; C 68 ; WX 600 ; N D ; B 43 0 574 562 ; C 69 ; WX 600 ; N E ; B 53 0 550 562 ; C 70 ; WX 600 ; N F ; B 53 0 545 562 ; C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; C 72 ; WX 600 ; N H ; B 32 0 568 562 ; C 73 ; WX 600 ; N I ; B 96 0 504 562 ; C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; C 75 ; WX 600 ; N K ; B 38 0 582 562 ; C 76 ; WX 600 ; N L ; B 47 0 554 562 ; C 77 ; WX 600 ; N M ; B 4 0 596 562 ; C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; C 80 ; WX 600 ; N P ; B 79 0 558 562 ; C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; C 82 ; WX 600 ; N R ; B 38 0 588 562 ; C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; C 84 ; WX 600 ; N T ; B 38 0 563 562 ; C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; C 88 ; WX 600 ; N X ; B 23 0 577 562 ; C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; C 104 ; WX 600 ; N h ; B 18 0 582 629 ; C 105 ; WX 600 ; N i ; B 95 0 505 657 ; C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; C 107 ; WX 600 ; N k ; B 43 0 580 629 ; C 108 ; WX 600 ; N l ; B 95 0 505 629 ; C 109 ; WX 600 ; N m ; B -5 0 605 441 ; C 110 ; WX 600 ; N n ; B 26 0 575 441 ; C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; C 114 ; WX 600 ; N r ; B 60 0 559 441 ; C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; C 120 ; WX 600 ; N x ; B 20 0 580 426 ; C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; C 122 ; WX 600 ; N z ; B 99 0 502 426 ; C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ; C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ; C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; C 168 ; WX 600 ; N currency ; B 73 58 527 506 ; C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; C 174 ; WX 600 ; N fi ; B 3 0 597 629 ; C 175 ; WX 600 ; N fl ; B 3 0 597 629 ; C 177 ; WX 600 ; N endash ; B 75 231 525 285 ; C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ; C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ; C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; C 193 ; WX 600 ; N grave ; B 151 497 378 672 ; C 194 ; WX 600 ; N acute ; B 242 497 469 672 ; C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ; C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ; C 197 ; WX 600 ; N macron ; B 120 525 480 565 ; C 198 ; WX 600 ; N breve ; B 153 501 447 609 ; C 199 ; WX 600 ; N dotaccent ; B 249 477 352 580 ; C 200 ; WX 600 ; N dieresis ; B 148 492 453 595 ; C 202 ; WX 600 ; N ring ; B 218 463 382 627 ; C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; C 206 ; WX 600 ; N ogonek ; B 227 -151 370 0 ; C 207 ; WX 600 ; N caron ; B 124 492 476 669 ; C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ; C 225 ; WX 600 ; N AE ; B 3 0 550 562 ; C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ; C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; C 234 ; WX 600 ; N OE ; B 7 0 567 562 ; C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ; C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ; C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ; C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ; C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 731 ; C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; C -1 ; WX 600 ; N merge ; B 160 -15 440 436 ; C -1 ; WX 600 ; N degree ; B 123 269 477 622 ; C -1 ; WX 600 ; N dectab ; B 18 0 582 227 ; C -1 ; WX 600 ; N ll ; B 18 0 567 629 ; C -1 ; WX 600 ; N IJ ; B 32 -18 583 562 ; C -1 ; WX 600 ; N Eacute ; B 53 0 550 793 ; C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 775 ; C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; C -1 ; WX 600 ; N left ; B 70 68 530 348 ; C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; C -1 ; WX 600 ; N up ; B 160 0 440 437 ; C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ; C -1 ; WX 600 ; N Scaron ; B 72 -20 529 805 ; C -1 ; WX 600 ; N tab ; B 19 0 581 562 ; C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 775 ; C -1 ; WX 600 ; N divide ; B 87 48 513 467 ; C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 775 ; C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ; C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ; C -1 ; WX 600 ; N Aacute ; B 3 0 597 793 ; C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 775 ; C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ; C -1 ; WX 600 ; N down ; B 160 -15 440 426 ; C -1 ; WX 600 ; N center ; B 40 14 560 580 ; C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; C -1 ; WX 600 ; N ij ; B 37 -157 490 657 ; C -1 ; WX 600 ; N edieresis ; B 66 -15 548 595 ; C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ; C -1 ; WX 600 ; N odieresis ; B 62 -15 538 595 ; C -1 ; WX 600 ; N Ograve ; B 43 -18 557 793 ; C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ; C -1 ; WX 600 ; N prescription ; B 27 -15 577 562 ; C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ; C -1 ; WX 600 ; N largebullet ; B 261 220 339 297 ; C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ; C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; C -1 ; WX 600 ; N notegraphic ; B 136 -15 464 572 ; C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 731 ; C -1 ; WX 600 ; N Gcaron ; B 31 -18 575 805 ; C -1 ; WX 600 ; N arrowdown ; B 116 -15 484 608 ; C -1 ; WX 600 ; N format ; B 5 -157 56 607 ; C -1 ; WX 600 ; N Otilde ; B 43 -18 557 732 ; C -1 ; WX 600 ; N Idieresis ; B 96 0 504 731 ; C -1 ; WX 600 ; N adieresis ; B 53 -15 559 595 ; C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ; C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; C -1 ; WX 600 ; N LL ; B 8 0 592 562 ; C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ; C -1 ; WX 600 ; N Zcaron ; B 86 0 514 805 ; C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; C -1 ; WX 600 ; N Idot ; B 96 0 504 716 ; C -1 ; WX 600 ; N Iacute ; B 96 0 504 793 ; C -1 ; WX 600 ; N indent ; B 70 68 530 348 ; C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 793 ; C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ; C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ; C -1 ; WX 600 ; N Aring ; B 3 0 597 753 ; C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; C -1 ; WX 600 ; N Igrave ; B 96 0 504 793 ; C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; C -1 ; WX 600 ; N Oacute ; B 43 -18 557 793 ; C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ; C -1 ; WX 600 ; N Yacute ; B 24 0 576 793 ; C -1 ; WX 600 ; N lira ; B 73 -21 521 611 ; C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 775 ; C -1 ; WX 600 ; N Atilde ; B 3 0 597 732 ; C -1 ; WX 600 ; N Uacute ; B 17 -18 583 793 ; C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 731 ; C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 595 ; C -1 ; WX 600 ; N idieresis ; B 95 0 505 595 ; C -1 ; WX 600 ; N Adieresis ; B 3 0 597 731 ; C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ; C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ; C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ; C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; C -1 ; WX 600 ; N Agrave ; B 3 0 597 793 ; C -1 ; WX 600 ; N return ; B 19 0 581 562 ; C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ; C -1 ; WX 600 ; N square ; B 19 0 581 562 ; C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; C -1 ; WX 600 ; N stop ; B 19 0 581 562 ; C -1 ; WX 600 ; N udieresis ; B 21 -15 562 595 ; C -1 ; WX 600 ; N arrowup ; B 116 0 484 623 ; C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ; C -1 ; WX 600 ; N Edieresis ; B 53 0 550 731 ; C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ; C -1 ; WX 600 ; N arrowboth ; B -28 115 628 483 ; C -1 ; WX 600 ; N gcaron ; B 45 -157 566 669 ; C -1 ; WX 600 ; N arrowleft ; B -24 115 624 483 ; C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ; C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ; C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 732 ; C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ; C -1 ; WX 600 ; N arrowright ; B -24 115 624 483 ; C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ; C -1 ; WX 600 ; N Egrave ; B 53 0 550 793 ; C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ; C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ; C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ; C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; EndCharMetrics StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 20 121 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 121 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -30 136 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave -30 121 ; CC Aring 2 ; PCC A 0 0 ; PCC ring -15 126 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 126 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 121 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 121 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 136 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 121 ; CC Gcaron 2 ; PCC G 0 0 ; PCC caron 0 136 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 121 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 121 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 136 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 121 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 126 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 121 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 121 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 136 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 121 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 126 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 30 136 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 121 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 121 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 136 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 121 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 121 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 136 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 136 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Bookman-DemiItalic.afm������������������������������������������������0000644�0001750�0001750�00000036520�11462120062�020530� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Jan 21 16:12:43 1992 Comment UniqueID 37832 Comment VMusage 32139 39031 FontName Bookman-DemiItalic FullName ITC Bookman Demi Italic FamilyName ITC Bookman Weight Demi ItalicAngle -10 IsFixedPitch false FontBBox -231 -250 1333 941 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 515 Ascender 732 Descender -213 StartCharMetrics 228 C 32 ; WX 340 ; N space ; B 0 0 0 0 ; C 33 ; WX 320 ; N exclam ; B 86 -8 366 698 ; C 34 ; WX 380 ; N quotedbl ; B 140 371 507 697 ; C 35 ; WX 680 ; N numbersign ; B 157 0 649 681 ; C 36 ; WX 680 ; N dollar ; B 45 -164 697 790 ; C 37 ; WX 880 ; N percent ; B 106 -17 899 698 ; C 38 ; WX 980 ; N ampersand ; B 48 -17 1016 698 ; C 39 ; WX 320 ; N quoteright ; B 171 420 349 698 ; C 40 ; WX 260 ; N parenleft ; B 31 -134 388 741 ; C 41 ; WX 260 ; N parenright ; B -35 -134 322 741 ; C 42 ; WX 460 ; N asterisk ; B 126 346 508 698 ; C 43 ; WX 600 ; N plus ; B 91 9 595 514 ; C 44 ; WX 340 ; N comma ; B 100 -124 298 185 ; C 45 ; WX 280 ; N hyphen ; B 59 218 319 313 ; C 46 ; WX 340 ; N period ; B 106 -8 296 177 ; C 47 ; WX 360 ; N slash ; B 9 -106 502 742 ; C 48 ; WX 680 ; N zero ; B 87 -17 703 698 ; C 49 ; WX 680 ; N one ; B 123 0 565 681 ; C 50 ; WX 680 ; N two ; B 67 0 674 698 ; C 51 ; WX 680 ; N three ; B 72 -17 683 698 ; C 52 ; WX 680 ; N four ; B 63 0 708 681 ; C 53 ; WX 680 ; N five ; B 78 -17 669 681 ; C 54 ; WX 680 ; N six ; B 88 -17 704 698 ; C 55 ; WX 680 ; N seven ; B 123 0 739 681 ; C 56 ; WX 680 ; N eight ; B 68 -17 686 698 ; C 57 ; WX 680 ; N nine ; B 71 -17 712 698 ; C 58 ; WX 340 ; N colon ; B 106 -8 356 515 ; C 59 ; WX 340 ; N semicolon ; B 100 -124 352 515 ; C 60 ; WX 620 ; N less ; B 79 -9 588 540 ; C 61 ; WX 600 ; N equal ; B 91 109 595 421 ; C 62 ; WX 620 ; N greater ; B 89 -9 598 540 ; C 63 ; WX 620 ; N question ; B 145 -8 668 698 ; C 64 ; WX 780 ; N at ; B 80 -17 790 698 ; C 65 ; WX 720 ; N A ; B -27 0 769 681 ; C 66 ; WX 720 ; N B ; B 14 0 762 681 ; C 67 ; WX 700 ; N C ; B 78 -17 754 698 ; C 68 ; WX 760 ; N D ; B 14 0 805 681 ; C 69 ; WX 720 ; N E ; B 14 0 777 681 ; C 70 ; WX 660 ; N F ; B 14 0 763 681 ; C 71 ; WX 760 ; N G ; B 77 -17 828 698 ; C 72 ; WX 800 ; N H ; B 14 0 910 681 ; C 73 ; WX 380 ; N I ; B 14 0 485 681 ; C 74 ; WX 620 ; N J ; B 8 -17 721 681 ; C 75 ; WX 780 ; N K ; B 14 0 879 681 ; C 76 ; WX 640 ; N L ; B 14 0 725 681 ; C 77 ; WX 860 ; N M ; B 14 0 970 681 ; C 78 ; WX 740 ; N N ; B 14 0 845 681 ; C 79 ; WX 760 ; N O ; B 78 -17 806 698 ; C 80 ; WX 640 ; N P ; B -6 0 724 681 ; C 81 ; WX 760 ; N Q ; B 37 -213 805 698 ; C 82 ; WX 740 ; N R ; B 14 0 765 681 ; C 83 ; WX 700 ; N S ; B 59 -17 731 698 ; C 84 ; WX 700 ; N T ; B 70 0 802 681 ; C 85 ; WX 740 ; N U ; B 112 -17 855 681 ; C 86 ; WX 660 ; N V ; B 72 0 819 681 ; C 87 ; WX 1000 ; N W ; B 72 0 1090 681 ; C 88 ; WX 740 ; N X ; B -7 0 835 681 ; C 89 ; WX 660 ; N Y ; B 72 0 817 681 ; C 90 ; WX 680 ; N Z ; B 23 0 740 681 ; C 91 ; WX 260 ; N bracketleft ; B 9 -118 374 741 ; C 92 ; WX 580 ; N backslash ; B 73 0 575 741 ; C 93 ; WX 260 ; N bracketright ; B -18 -118 347 741 ; C 94 ; WX 620 ; N asciicircum ; B 92 281 594 681 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 320 ; N quoteleft ; B 155 420 333 698 ; C 97 ; WX 680 ; N a ; B 84 -8 735 515 ; C 98 ; WX 600 ; N b ; B 57 -8 633 732 ; C 99 ; WX 560 ; N c ; B 58 -8 597 515 ; C 100 ; WX 680 ; N d ; B 60 -8 714 732 ; C 101 ; WX 560 ; N e ; B 59 -8 596 515 ; C 102 ; WX 420 ; N f ; B -192 -213 641 741 ; L i fi ; L l fl ; C 103 ; WX 620 ; N g ; B 21 -213 669 515 ; C 104 ; WX 700 ; N h ; B 93 -8 736 732 ; C 105 ; WX 380 ; N i ; B 83 -8 420 755 ; C 106 ; WX 320 ; N j ; B -160 -213 392 755 ; C 107 ; WX 700 ; N k ; B 97 -8 732 732 ; C 108 ; WX 380 ; N l ; B 109 -8 410 732 ; C 109 ; WX 960 ; N m ; B 83 -8 996 515 ; C 110 ; WX 680 ; N n ; B 83 -8 715 515 ; C 111 ; WX 600 ; N o ; B 59 -8 627 515 ; C 112 ; WX 660 ; N p ; B -24 -213 682 515 ; C 113 ; WX 620 ; N q ; B 60 -213 640 515 ; C 114 ; WX 500 ; N r ; B 84 0 582 515 ; C 115 ; WX 540 ; N s ; B 32 -8 573 515 ; C 116 ; WX 440 ; N t ; B 106 -8 488 658 ; C 117 ; WX 680 ; N u ; B 83 -8 720 507 ; C 118 ; WX 540 ; N v ; B 56 -8 572 515 ; C 119 ; WX 860 ; N w ; B 56 -8 891 515 ; C 120 ; WX 620 ; N x ; B 10 -8 654 515 ; C 121 ; WX 600 ; N y ; B 25 -213 642 507 ; C 122 ; WX 560 ; N z ; B 36 -8 586 515 ; C 123 ; WX 300 ; N braceleft ; B 49 -123 413 742 ; C 124 ; WX 620 ; N bar ; B 303 -250 422 750 ; C 125 ; WX 300 ; N braceright ; B -8 -114 356 751 ; C 126 ; WX 620 ; N asciitilde ; B 101 162 605 368 ; C 161 ; WX 320 ; N exclamdown ; B 64 -191 344 515 ; C 162 ; WX 680 ; N cent ; B 161 25 616 718 ; C 163 ; WX 680 ; N sterling ; B 0 -17 787 698 ; C 164 ; WX 120 ; N fraction ; B -144 0 382 681 ; C 165 ; WX 680 ; N yen ; B 92 0 782 681 ; C 166 ; WX 680 ; N florin ; B -28 -199 743 741 ; C 167 ; WX 620 ; N section ; B 46 -137 638 698 ; C 168 ; WX 680 ; N currency ; B 148 85 637 571 ; C 169 ; WX 180 ; N quotesingle ; B 126 370 295 696 ; C 170 ; WX 520 ; N quotedblleft ; B 156 420 545 698 ; C 171 ; WX 380 ; N guillemotleft ; B 62 84 406 503 ; C 172 ; WX 220 ; N guilsinglleft ; B 62 84 249 503 ; C 173 ; WX 220 ; N guilsinglright ; B 62 84 249 503 ; C 174 ; WX 820 ; N fi ; B -191 -213 850 741 ; C 175 ; WX 820 ; N fl ; B -191 -213 850 741 ; C 177 ; WX 500 ; N endash ; B 40 219 573 311 ; C 178 ; WX 420 ; N dagger ; B 89 -137 466 698 ; C 179 ; WX 420 ; N daggerdbl ; B 79 -137 486 698 ; C 180 ; WX 340 ; N periodcentered ; B 126 173 316 358 ; C 182 ; WX 680 ; N paragraph ; B 137 0 715 681 ; C 183 ; WX 360 ; N bullet ; B 60 170 404 511 ; C 184 ; WX 300 ; N quotesinglbase ; B 106 -112 284 166 ; C 185 ; WX 520 ; N quotedblbase ; B 106 -112 495 166 ; C 186 ; WX 520 ; N quotedblright ; B 171 420 560 698 ; C 187 ; WX 380 ; N guillemotright ; B 62 84 406 503 ; C 188 ; WX 1000 ; N ellipsis ; B 86 -8 942 177 ; C 189 ; WX 1360 ; N perthousand ; B 106 -17 1333 698 ; C 191 ; WX 620 ; N questiondown ; B 83 -189 606 515 ; C 193 ; WX 380 ; N grave ; B 193 566 424 771 ; C 194 ; WX 340 ; N acute ; B 176 566 407 771 ; C 195 ; WX 480 ; N circumflex ; B 183 582 523 749 ; C 196 ; WX 480 ; N tilde ; B 178 587 533 709 ; C 197 ; WX 480 ; N macron ; B 177 603 531 691 ; C 198 ; WX 460 ; N breve ; B 177 577 516 707 ; C 199 ; WX 380 ; N dotaccent ; B 180 570 345 734 ; C 200 ; WX 520 ; N dieresis ; B 180 570 569 734 ; C 202 ; WX 360 ; N ring ; B 185 558 406 775 ; C 203 ; WX 360 ; N cedilla ; B 68 -220 289 -8 ; C 205 ; WX 560 ; N hungarumlaut ; B 181 560 616 775 ; C 206 ; WX 320 ; N ogonek ; B 68 -182 253 0 ; C 207 ; WX 480 ; N caron ; B 183 582 523 749 ; C 208 ; WX 1000 ; N emdash ; B 40 219 1073 311 ; C 225 ; WX 1140 ; N AE ; B -27 0 1207 681 ; C 227 ; WX 440 ; N ordfeminine ; B 118 400 495 685 ; C 232 ; WX 640 ; N Lslash ; B 14 0 724 681 ; C 233 ; WX 760 ; N Oslash ; B 21 -29 847 725 ; C 234 ; WX 1180 ; N OE ; B 94 -17 1245 698 ; C 235 ; WX 440 ; N ordmasculine ; B 127 400 455 685 ; C 241 ; WX 880 ; N ae ; B 39 -8 913 515 ; C 245 ; WX 380 ; N dotlessi ; B 83 -8 420 507 ; C 248 ; WX 380 ; N lslash ; B 63 -8 412 732 ; C 249 ; WX 600 ; N oslash ; B 17 -54 661 571 ; C 250 ; WX 920 ; N oe ; B 48 -8 961 515 ; C 251 ; WX 660 ; N germandbls ; B -231 -213 702 741 ; C -1 ; WX 560 ; N ecircumflex ; B 59 -8 596 749 ; C -1 ; WX 560 ; N edieresis ; B 59 -8 596 734 ; C -1 ; WX 680 ; N aacute ; B 84 -8 735 771 ; C -1 ; WX 780 ; N registered ; B 83 -17 783 698 ; C -1 ; WX 380 ; N icircumflex ; B 83 -8 433 749 ; C -1 ; WX 680 ; N udieresis ; B 83 -8 720 734 ; C -1 ; WX 600 ; N ograve ; B 59 -8 627 771 ; C -1 ; WX 680 ; N uacute ; B 83 -8 720 771 ; C -1 ; WX 680 ; N ucircumflex ; B 83 -8 720 749 ; C -1 ; WX 720 ; N Aacute ; B -27 0 769 937 ; C -1 ; WX 380 ; N igrave ; B 83 -8 424 771 ; C -1 ; WX 380 ; N Icircumflex ; B 14 0 493 915 ; C -1 ; WX 560 ; N ccedilla ; B 58 -220 597 515 ; C -1 ; WX 680 ; N adieresis ; B 84 -8 735 734 ; C -1 ; WX 720 ; N Ecircumflex ; B 14 0 777 915 ; C -1 ; WX 540 ; N scaron ; B 32 -8 573 749 ; C -1 ; WX 660 ; N thorn ; B -24 -213 682 732 ; C -1 ; WX 940 ; N trademark ; B 42 277 982 681 ; C -1 ; WX 560 ; N egrave ; B 59 -8 596 771 ; C -1 ; WX 408 ; N threesuperior ; B 86 269 483 698 ; C -1 ; WX 560 ; N zcaron ; B 36 -8 586 749 ; C -1 ; WX 680 ; N atilde ; B 84 -8 735 709 ; C -1 ; WX 680 ; N aring ; B 84 -8 735 775 ; C -1 ; WX 600 ; N ocircumflex ; B 59 -8 627 749 ; C -1 ; WX 720 ; N Edieresis ; B 14 0 777 900 ; C -1 ; WX 1020 ; N threequarters ; B 86 0 1054 691 ; C -1 ; WX 600 ; N ydieresis ; B 25 -213 642 734 ; C -1 ; WX 600 ; N yacute ; B 25 -213 642 771 ; C -1 ; WX 380 ; N iacute ; B 83 -8 420 771 ; C -1 ; WX 720 ; N Acircumflex ; B -27 0 769 915 ; C -1 ; WX 740 ; N Uacute ; B 112 -17 855 937 ; C -1 ; WX 560 ; N eacute ; B 59 -8 596 771 ; C -1 ; WX 760 ; N Ograve ; B 78 -17 806 937 ; C -1 ; WX 680 ; N agrave ; B 84 -8 735 771 ; C -1 ; WX 740 ; N Udieresis ; B 112 -17 855 900 ; C -1 ; WX 680 ; N acircumflex ; B 84 -8 735 749 ; C -1 ; WX 380 ; N Igrave ; B 14 0 485 937 ; C -1 ; WX 408 ; N twosuperior ; B 91 279 485 698 ; C -1 ; WX 740 ; N Ugrave ; B 112 -17 855 937 ; C -1 ; WX 1020 ; N onequarter ; B 118 0 1054 681 ; C -1 ; WX 740 ; N Ucircumflex ; B 112 -17 855 915 ; C -1 ; WX 700 ; N Scaron ; B 59 -17 731 915 ; C -1 ; WX 380 ; N Idieresis ; B 14 0 499 900 ; C -1 ; WX 380 ; N idieresis ; B 83 -8 479 734 ; C -1 ; WX 720 ; N Egrave ; B 14 0 777 937 ; C -1 ; WX 760 ; N Oacute ; B 78 -17 806 937 ; C -1 ; WX 600 ; N divide ; B 91 9 595 521 ; C -1 ; WX 720 ; N Atilde ; B -27 0 769 875 ; C -1 ; WX 720 ; N Aring ; B -27 0 769 941 ; C -1 ; WX 760 ; N Odieresis ; B 78 -17 806 900 ; C -1 ; WX 720 ; N Adieresis ; B -27 0 769 900 ; C -1 ; WX 740 ; N Ntilde ; B 14 0 845 875 ; C -1 ; WX 680 ; N Zcaron ; B 23 0 740 915 ; C -1 ; WX 640 ; N Thorn ; B -6 0 701 681 ; C -1 ; WX 380 ; N Iacute ; B 14 0 485 937 ; C -1 ; WX 600 ; N plusminus ; B 91 0 595 514 ; C -1 ; WX 600 ; N multiply ; B 91 10 595 514 ; C -1 ; WX 720 ; N Eacute ; B 14 0 777 937 ; C -1 ; WX 660 ; N Ydieresis ; B 72 0 817 900 ; C -1 ; WX 408 ; N onesuperior ; B 118 279 406 688 ; C -1 ; WX 680 ; N ugrave ; B 83 -8 720 771 ; C -1 ; WX 620 ; N logicalnot ; B 81 129 585 421 ; C -1 ; WX 680 ; N ntilde ; B 83 -8 715 709 ; C -1 ; WX 760 ; N Otilde ; B 78 -17 806 875 ; C -1 ; WX 600 ; N otilde ; B 59 -8 627 709 ; C -1 ; WX 700 ; N Ccedilla ; B 78 -220 754 698 ; C -1 ; WX 720 ; N Agrave ; B -27 0 769 937 ; C -1 ; WX 1020 ; N onehalf ; B 118 0 1036 681 ; C -1 ; WX 760 ; N Eth ; B 14 0 805 681 ; C -1 ; WX 400 ; N degree ; B 130 398 430 698 ; C -1 ; WX 660 ; N Yacute ; B 72 0 817 937 ; C -1 ; WX 760 ; N Ocircumflex ; B 78 -17 806 915 ; C -1 ; WX 600 ; N oacute ; B 59 -8 627 771 ; C -1 ; WX 680 ; N mu ; B 54 -213 720 507 ; C -1 ; WX 600 ; N minus ; B 91 207 595 323 ; C -1 ; WX 600 ; N eth ; B 59 -8 662 741 ; C -1 ; WX 600 ; N odieresis ; B 59 -8 627 734 ; C -1 ; WX 780 ; N copyright ; B 83 -17 783 698 ; C -1 ; WX 620 ; N brokenbar ; B 303 -175 422 675 ; EndCharMetrics StartKernData StartKernPairs 92 KPX A y 20 KPX A w 20 KPX A v 20 KPX A Y -25 KPX A W -35 KPX A V -40 KPX A T -17 KPX F period -105 KPX F comma -98 KPX F A -35 KPX L y 62 KPX L Y -5 KPX L W -15 KPX L V -19 KPX L T -26 KPX P period -105 KPX P comma -98 KPX P A -31 KPX R y 27 KPX R Y 4 KPX R W -4 KPX R V -8 KPX R T -3 KPX T y 56 KPX T w 69 KPX T u 42 KPX T semicolon 31 KPX T s -1 KPX T r 41 KPX T period -107 KPX T o -5 KPX T i 42 KPX T hyphen -20 KPX T e -10 KPX T comma -100 KPX T colon 26 KPX T c -8 KPX T a -8 KPX T A -42 KPX V y 17 KPX V u -1 KPX V semicolon -22 KPX V r 2 KPX V period -115 KPX V o -50 KPX V i 32 KPX V hyphen -20 KPX V e -50 KPX V comma -137 KPX V colon -28 KPX V a -50 KPX V A -50 KPX W y -51 KPX W u -69 KPX W semicolon -81 KPX W r -66 KPX W period -183 KPX W o -100 KPX W i -36 KPX W hyphen -22 KPX W e -100 KPX W comma -201 KPX W colon -86 KPX W a -100 KPX W A -77 KPX Y v 26 KPX Y u -1 KPX Y semicolon -4 KPX Y q -43 KPX Y period -113 KPX Y o -41 KPX Y i 20 KPX Y hyphen -20 KPX Y e -46 KPX Y comma -106 KPX Y colon -9 KPX Y a -45 KPX Y A -30 KPX f f 10 KPX r q -3 KPX r period -120 KPX r o -1 KPX r n 39 KPX r m 39 KPX r hyphen -20 KPX r h -35 KPX r g -23 KPX r f 42 KPX r e -6 KPX r d -3 KPX r comma -113 KPX r c -5 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 190 166 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 120 166 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 100 166 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 170 166 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 200 166 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 166 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 190 166 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 120 166 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 100 166 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 170 166 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 166 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 166 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -70 166 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 166 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 166 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 166 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 140 166 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 140 166 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 190 166 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 140 166 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 110 166 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 200 166 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 130 166 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 130 166 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 166 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 160 166 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 70 166 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 100 166 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 170 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 100 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 150 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 160 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 100 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 60 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 20 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -90 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 130 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 150 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 130 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Oblique.afm�������������������������������������������������0000644�0001750�0001750�00000044144�11462120062�020443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Thu Mar 15 10:24:18 1990 Comment UniqueID 28362 Comment VMusage 7572 42473 FontName Helvetica-Oblique FullName Helvetica Oblique FamilyName Helvetica Weight Medium ItalicAngle -12 IsFixedPitch false FontBBox -170 -225 1116 931 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ; C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ; C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ; C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ; C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ; C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ; C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ; C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ; C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ; C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ; C 43 ; WX 584 ; N plus ; B 85 0 606 505 ; C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ; C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ; C 46 ; WX 278 ; N period ; B 87 0 214 106 ; C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ; C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ; C 49 ; WX 556 ; N one ; B 207 0 508 703 ; C 50 ; WX 556 ; N two ; B 26 0 617 703 ; C 51 ; WX 556 ; N three ; B 75 -19 610 703 ; C 52 ; WX 556 ; N four ; B 61 0 576 703 ; C 53 ; WX 556 ; N five ; B 68 -19 621 688 ; C 54 ; WX 556 ; N six ; B 91 -19 615 703 ; C 55 ; WX 556 ; N seven ; B 137 0 669 688 ; C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ; C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ; C 58 ; WX 278 ; N colon ; B 87 0 301 516 ; C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ; C 60 ; WX 584 ; N less ; B 94 11 641 495 ; C 61 ; WX 584 ; N equal ; B 63 115 628 390 ; C 62 ; WX 584 ; N greater ; B 50 11 597 495 ; C 63 ; WX 556 ; N question ; B 161 0 610 727 ; C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ; C 65 ; WX 667 ; N A ; B 14 0 654 718 ; C 66 ; WX 667 ; N B ; B 74 0 712 718 ; C 67 ; WX 722 ; N C ; B 108 -19 782 737 ; C 68 ; WX 722 ; N D ; B 81 0 764 718 ; C 69 ; WX 667 ; N E ; B 86 0 762 718 ; C 70 ; WX 611 ; N F ; B 86 0 736 718 ; C 71 ; WX 778 ; N G ; B 111 -19 799 737 ; C 72 ; WX 722 ; N H ; B 77 0 799 718 ; C 73 ; WX 278 ; N I ; B 91 0 341 718 ; C 74 ; WX 500 ; N J ; B 47 -19 581 718 ; C 75 ; WX 667 ; N K ; B 76 0 808 718 ; C 76 ; WX 556 ; N L ; B 76 0 555 718 ; C 77 ; WX 833 ; N M ; B 73 0 914 718 ; C 78 ; WX 722 ; N N ; B 76 0 799 718 ; C 79 ; WX 778 ; N O ; B 105 -19 826 737 ; C 80 ; WX 667 ; N P ; B 86 0 737 718 ; C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ; C 82 ; WX 722 ; N R ; B 88 0 773 718 ; C 83 ; WX 667 ; N S ; B 90 -19 713 737 ; C 84 ; WX 611 ; N T ; B 148 0 750 718 ; C 85 ; WX 722 ; N U ; B 123 -19 797 718 ; C 86 ; WX 667 ; N V ; B 173 0 800 718 ; C 87 ; WX 944 ; N W ; B 169 0 1081 718 ; C 88 ; WX 667 ; N X ; B 19 0 790 718 ; C 89 ; WX 667 ; N Y ; B 167 0 806 718 ; C 90 ; WX 611 ; N Z ; B 23 0 741 718 ; C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ; C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ; C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ; C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ; C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ; C 97 ; WX 556 ; N a ; B 61 -15 559 538 ; C 98 ; WX 556 ; N b ; B 58 -15 584 718 ; C 99 ; WX 500 ; N c ; B 74 -15 553 538 ; C 100 ; WX 556 ; N d ; B 84 -15 652 718 ; C 101 ; WX 556 ; N e ; B 84 -15 578 538 ; C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 42 -220 610 538 ; C 104 ; WX 556 ; N h ; B 65 0 573 718 ; C 105 ; WX 222 ; N i ; B 67 0 308 718 ; C 106 ; WX 222 ; N j ; B -60 -210 308 718 ; C 107 ; WX 500 ; N k ; B 67 0 600 718 ; C 108 ; WX 222 ; N l ; B 67 0 308 718 ; C 109 ; WX 833 ; N m ; B 65 0 852 538 ; C 110 ; WX 556 ; N n ; B 65 0 573 538 ; C 111 ; WX 556 ; N o ; B 83 -14 585 538 ; C 112 ; WX 556 ; N p ; B 14 -207 584 538 ; C 113 ; WX 556 ; N q ; B 84 -207 605 538 ; C 114 ; WX 333 ; N r ; B 77 0 446 538 ; C 115 ; WX 500 ; N s ; B 63 -15 529 538 ; C 116 ; WX 278 ; N t ; B 102 -7 368 669 ; C 117 ; WX 556 ; N u ; B 94 -15 600 523 ; C 118 ; WX 500 ; N v ; B 119 0 603 523 ; C 119 ; WX 722 ; N w ; B 125 0 820 523 ; C 120 ; WX 500 ; N x ; B 11 0 594 523 ; C 121 ; WX 500 ; N y ; B 15 -214 600 523 ; C 122 ; WX 500 ; N z ; B 31 0 571 523 ; C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ; C 124 ; WX 260 ; N bar ; B 90 -19 324 737 ; C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ; C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ; C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ; C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ; C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ; C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ; C 165 ; WX 556 ; N yen ; B 81 0 699 688 ; C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ; C 167 ; WX 556 ; N section ; B 76 -191 584 737 ; C 168 ; WX 556 ; N currency ; B 60 99 646 603 ; C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ; C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ; C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ; C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ; C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ; C 174 ; WX 500 ; N fi ; B 86 0 587 728 ; C 175 ; WX 500 ; N fl ; B 86 0 585 728 ; C 177 ; WX 556 ; N endash ; B 51 240 623 313 ; C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ; C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ; C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ; C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ; C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ; C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ; C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ; C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ; C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ; C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ; C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ; C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ; C 193 ; WX 333 ; N grave ; B 170 593 337 734 ; C 194 ; WX 333 ; N acute ; B 248 593 475 734 ; C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ; C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ; C 197 ; WX 333 ; N macron ; B 143 627 468 684 ; C 198 ; WX 333 ; N breve ; B 167 595 476 731 ; C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ; C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ; C 202 ; WX 333 ; N ring ; B 214 572 402 756 ; C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ; C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ; C 207 ; WX 333 ; N caron ; B 177 593 468 734 ; C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ; C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ; C 227 ; WX 370 ; N ordfeminine ; B 100 304 449 737 ; C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ; C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ; C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ; C 235 ; WX 365 ; N ordmasculine ; B 100 304 468 737 ; C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ; C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ; C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ; C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ; C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ; C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ; C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ; C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ; C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ; C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ; C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ; C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ; C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ; C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ; C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ; C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ; C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ; C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ; C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ; C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ; C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ; C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ; C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ; C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ; C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ; C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ; C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ; C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ; C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ; C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ; C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ; C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ; C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ; C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ; C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ; C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ; C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ; C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ; C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ; C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ; C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ; C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ; C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ; C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ; C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ; C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ; C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ; C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ; C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ; C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ; C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ; C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ; C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ; C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ; C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ; C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ; C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ; C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ; C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ; C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ; C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ; C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ; C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ; C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ; C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ; C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ; C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ; C -1 ; WX 584 ; N minus ; B 85 216 606 289 ; C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ; C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ; C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ; C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ; C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ; C -1 ; WX 400 ; N degree ; B 169 411 468 703 ; C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ; C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ; C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ; C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ; C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ; C -1 ; WX 260 ; N brokenbar ; B 90 -19 324 737 ; C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ; EndCharMetrics StartKernData StartKernPairs 250 KPX A y -40 KPX A w -40 KPX A v -40 KPX A u -30 KPX A Y -100 KPX A W -50 KPX A V -70 KPX A U -50 KPX A T -120 KPX A Q -30 KPX A O -30 KPX A G -30 KPX A C -30 KPX B period -20 KPX B comma -20 KPX B U -10 KPX C period -30 KPX C comma -30 KPX D period -70 KPX D comma -70 KPX D Y -90 KPX D W -40 KPX D V -70 KPX D A -40 KPX F r -45 KPX F period -150 KPX F o -30 KPX F e -30 KPX F comma -150 KPX F a -50 KPX F A -80 KPX J u -20 KPX J period -30 KPX J comma -30 KPX J a -20 KPX J A -20 KPX K y -50 KPX K u -30 KPX K o -40 KPX K e -40 KPX K O -50 KPX L y -30 KPX L quoteright -160 KPX L quotedblright -140 KPX L Y -140 KPX L W -70 KPX L V -110 KPX L T -110 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -60 KPX O W -30 KPX O V -50 KPX O T -40 KPX O A -20 KPX P period -180 KPX P o -50 KPX P e -50 KPX P comma -180 KPX P a -40 KPX P A -120 KPX Q U -10 KPX R Y -50 KPX R W -30 KPX R V -50 KPX R U -40 KPX R T -30 KPX R O -20 KPX S period -20 KPX S comma -20 KPX T y -120 KPX T w -120 KPX T u -120 KPX T semicolon -20 KPX T r -120 KPX T period -120 KPX T o -120 KPX T hyphen -140 KPX T e -120 KPX T comma -120 KPX T colon -20 KPX T a -120 KPX T O -40 KPX T A -120 KPX U period -40 KPX U comma -40 KPX U A -40 KPX V u -70 KPX V semicolon -40 KPX V period -125 KPX V o -80 KPX V hyphen -80 KPX V e -80 KPX V comma -125 KPX V colon -40 KPX V a -70 KPX V O -40 KPX V G -40 KPX V A -80 KPX W y -20 KPX W u -30 KPX W period -80 KPX W o -30 KPX W hyphen -40 KPX W e -30 KPX W comma -80 KPX W a -40 KPX W O -20 KPX W A -50 KPX Y u -110 KPX Y semicolon -60 KPX Y period -140 KPX Y o -140 KPX Y i -20 KPX Y hyphen -140 KPX Y e -140 KPX Y comma -140 KPX Y colon -60 KPX Y a -140 KPX Y O -85 KPX Y A -110 KPX a y -30 KPX a w -20 KPX a v -20 KPX b y -20 KPX b v -20 KPX b u -20 KPX b period -40 KPX b l -20 KPX b comma -40 KPX b b -10 KPX c k -20 KPX c comma -15 KPX colon space -50 KPX comma quoteright -100 KPX comma quotedblright -100 KPX e y -20 KPX e x -30 KPX e w -20 KPX e v -30 KPX e period -15 KPX e comma -15 KPX f quoteright 50 KPX f quotedblright 60 KPX f period -30 KPX f o -30 KPX f e -30 KPX f dotlessi -28 KPX f comma -30 KPX f a -30 KPX g r -10 KPX h y -30 KPX k o -20 KPX k e -20 KPX m y -15 KPX m u -10 KPX n y -15 KPX n v -20 KPX n u -10 KPX o y -30 KPX o x -30 KPX o w -15 KPX o v -15 KPX o period -40 KPX o comma -40 KPX oslash z -55 KPX oslash y -70 KPX oslash x -85 KPX oslash w -70 KPX oslash v -70 KPX oslash u -55 KPX oslash t -55 KPX oslash s -55 KPX oslash r -55 KPX oslash q -55 KPX oslash period -95 KPX oslash p -55 KPX oslash o -55 KPX oslash n -55 KPX oslash m -55 KPX oslash l -55 KPX oslash k -55 KPX oslash j -55 KPX oslash i -55 KPX oslash h -55 KPX oslash g -55 KPX oslash f -55 KPX oslash e -55 KPX oslash d -55 KPX oslash comma -95 KPX oslash c -55 KPX oslash b -55 KPX oslash a -55 KPX p y -30 KPX p period -35 KPX p comma -35 KPX period space -60 KPX period quoteright -100 KPX period quotedblright -100 KPX quotedblright space -40 KPX quoteleft quoteleft -57 KPX quoteright space -70 KPX quoteright s -50 KPX quoteright r -50 KPX quoteright quoteright -57 KPX quoteright d -50 KPX r y 30 KPX r v 30 KPX r u 15 KPX r t 40 KPX r semicolon 30 KPX r period -50 KPX r p 30 KPX r n 25 KPX r m 25 KPX r l 15 KPX r k 15 KPX r i 15 KPX r comma -50 KPX r colon 30 KPX r a -10 KPX s w -30 KPX s period -15 KPX s comma -15 KPX semicolon space -50 KPX space quoteleft -60 KPX space quotedblleft -30 KPX space Y -90 KPX space W -40 KPX space V -50 KPX space T -50 KPX v period -80 KPX v o -25 KPX v e -25 KPX v comma -80 KPX v a -25 KPX w period -60 KPX w o -10 KPX w e -10 KPX w comma -60 KPX w a -15 KPX x e -30 KPX y period -100 KPX y o -20 KPX y e -20 KPX y comma -100 KPX y a -20 KPX z o -15 KPX z e -15 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 208 195 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 208 195 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 208 195 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 208 195 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 204 175 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 208 195 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 208 195 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 208 195 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 208 195 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 208 195 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 195 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 195 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 195 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 195 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 246 195 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 264 195 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 264 195 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 264 195 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 264 195 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 264 195 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 208 195 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 236 195 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 236 195 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 236 195 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 236 195 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 208 195 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 208 195 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 180 195 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Times-Italic.afm������������������������������������������������������0000644�0001750�0001750�00000044435�11462120062�017430� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Mar 20 13:14:56 1990 Comment UniqueID 28427 Comment VMusage 32912 39804 FontName Times-Italic FullName Times Italic FamilyName Times Weight Medium ItalicAngle -15.5 IsFixedPitch false FontBBox -169 -217 1010 883 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 653 XHeight 441 Ascender 683 Descender -205 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ; C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ; C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ; C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ; C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ; C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ; C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ; C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ; C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ; C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ; C 43 ; WX 675 ; N plus ; B 86 0 590 506 ; C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ; C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ; C 46 ; WX 250 ; N period ; B 27 -11 138 100 ; C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ; C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ; C 49 ; WX 500 ; N one ; B 49 0 409 676 ; C 50 ; WX 500 ; N two ; B 12 0 452 676 ; C 51 ; WX 500 ; N three ; B 15 -7 465 676 ; C 52 ; WX 500 ; N four ; B 1 0 479 676 ; C 53 ; WX 500 ; N five ; B 15 -7 491 666 ; C 54 ; WX 500 ; N six ; B 30 -7 521 686 ; C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ; C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ; C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ; C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ; C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ; C 60 ; WX 675 ; N less ; B 84 -8 592 514 ; C 61 ; WX 675 ; N equal ; B 86 120 590 386 ; C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ; C 63 ; WX 500 ; N question ; B 132 -12 472 664 ; C 64 ; WX 920 ; N at ; B 118 -18 806 666 ; C 65 ; WX 611 ; N A ; B -51 0 564 668 ; C 66 ; WX 611 ; N B ; B -8 0 588 653 ; C 67 ; WX 667 ; N C ; B 66 -18 689 666 ; C 68 ; WX 722 ; N D ; B -8 0 700 653 ; C 69 ; WX 611 ; N E ; B -1 0 634 653 ; C 70 ; WX 611 ; N F ; B 8 0 645 653 ; C 71 ; WX 722 ; N G ; B 52 -18 722 666 ; C 72 ; WX 722 ; N H ; B -8 0 767 653 ; C 73 ; WX 333 ; N I ; B -8 0 384 653 ; C 74 ; WX 444 ; N J ; B -6 -18 491 653 ; C 75 ; WX 667 ; N K ; B 7 0 722 653 ; C 76 ; WX 556 ; N L ; B -8 0 559 653 ; C 77 ; WX 833 ; N M ; B -18 0 873 653 ; C 78 ; WX 667 ; N N ; B -20 -15 727 653 ; C 79 ; WX 722 ; N O ; B 60 -18 699 666 ; C 80 ; WX 611 ; N P ; B 0 0 605 653 ; C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ; C 82 ; WX 611 ; N R ; B -13 0 588 653 ; C 83 ; WX 500 ; N S ; B 17 -18 508 667 ; C 84 ; WX 556 ; N T ; B 59 0 633 653 ; C 85 ; WX 722 ; N U ; B 102 -18 765 653 ; C 86 ; WX 611 ; N V ; B 76 -18 688 653 ; C 87 ; WX 833 ; N W ; B 71 -18 906 653 ; C 88 ; WX 611 ; N X ; B -29 0 655 653 ; C 89 ; WX 556 ; N Y ; B 78 0 633 653 ; C 90 ; WX 556 ; N Z ; B -6 0 606 653 ; C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ; C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ; C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ; C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ; C 97 ; WX 500 ; N a ; B 17 -11 476 441 ; C 98 ; WX 500 ; N b ; B 23 -11 473 683 ; C 99 ; WX 444 ; N c ; B 30 -11 425 441 ; C 100 ; WX 500 ; N d ; B 15 -13 527 683 ; C 101 ; WX 444 ; N e ; B 31 -11 412 441 ; C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 8 -206 472 441 ; C 104 ; WX 500 ; N h ; B 19 -9 478 683 ; C 105 ; WX 278 ; N i ; B 49 -11 264 654 ; C 106 ; WX 278 ; N j ; B -124 -207 276 654 ; C 107 ; WX 444 ; N k ; B 14 -11 461 683 ; C 108 ; WX 278 ; N l ; B 41 -11 279 683 ; C 109 ; WX 722 ; N m ; B 12 -9 704 441 ; C 110 ; WX 500 ; N n ; B 14 -9 474 441 ; C 111 ; WX 500 ; N o ; B 27 -11 468 441 ; C 112 ; WX 500 ; N p ; B -75 -205 469 441 ; C 113 ; WX 500 ; N q ; B 25 -209 483 441 ; C 114 ; WX 389 ; N r ; B 45 0 412 441 ; C 115 ; WX 389 ; N s ; B 16 -13 366 442 ; C 116 ; WX 278 ; N t ; B 37 -11 296 546 ; C 117 ; WX 500 ; N u ; B 42 -11 475 441 ; C 118 ; WX 444 ; N v ; B 21 -18 426 441 ; C 119 ; WX 667 ; N w ; B 16 -18 648 441 ; C 120 ; WX 444 ; N x ; B -27 -11 447 441 ; C 121 ; WX 444 ; N y ; B -24 -206 426 441 ; C 122 ; WX 389 ; N z ; B -2 -81 380 428 ; C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ; C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ; C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ; C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ; C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ; C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ; C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ; C 165 ; WX 500 ; N yen ; B 27 0 603 653 ; C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ; C 167 ; WX 500 ; N section ; B 53 -162 461 666 ; C 168 ; WX 500 ; N currency ; B -22 53 522 597 ; C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ; C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ; C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ; C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ; C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ; C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ; C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ; C 177 ; WX 500 ; N endash ; B -6 197 505 243 ; C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ; C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ; C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ; C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ; C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ; C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ; C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ; C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ; C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ; C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ; C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ; C 193 ; WX 333 ; N grave ; B 121 492 311 664 ; C 194 ; WX 333 ; N acute ; B 180 494 403 664 ; C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ; C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ; C 197 ; WX 333 ; N macron ; B 99 532 411 583 ; C 198 ; WX 333 ; N breve ; B 117 492 418 650 ; C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ; C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ; C 202 ; WX 333 ; N ring ; B 155 492 355 691 ; C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ; C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ; C 207 ; WX 333 ; N caron ; B 121 492 426 661 ; C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ; C 225 ; WX 889 ; N AE ; B -27 0 911 653 ; C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ; C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ; C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ; C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ; C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ; C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ; C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ; C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ; C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ; C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ; C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ; C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ; C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ; C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ; C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ; C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ; C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ; C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ; C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ; C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ; C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ; C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ; C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ; C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ; C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ; C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ; C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ; C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ; C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ; C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ; C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ; C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ; C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ; C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ; C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ; C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ; C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ; C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ; C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ; C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ; C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ; C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ; C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ; C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ; C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ; C -1 ; WX 333 ; N Iacute ; B -8 0 413 876 ; C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ; C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ; C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ; C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ; C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ; C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ; C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ; C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ; C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ; C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ; C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ; C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ; C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ; C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ; C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ; C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ; C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ; C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ; C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ; C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ; C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ; C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ; C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ; C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ; C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ; C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ; C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ; C -1 ; WX 675 ; N minus ; B 86 220 590 286 ; C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ; C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ; C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ; C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ; C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ; C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ; C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ; C -1 ; WX 400 ; N degree ; B 101 390 387 676 ; C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ; C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ; C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ; C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ; C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ; C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ; C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ; C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ; EndCharMetrics StartKernData StartKernPairs 283 KPX A y -55 KPX A w -55 KPX A v -55 KPX A u -20 KPX A quoteright -37 KPX A quotedblright 0 KPX A p 0 KPX A Y -55 KPX A W -95 KPX A V -105 KPX A U -50 KPX A T -37 KPX A Q -40 KPX A O -40 KPX A G -35 KPX A C -30 KPX B period 0 KPX B comma 0 KPX B U -10 KPX B A -25 KPX D period 0 KPX D comma 0 KPX D Y -40 KPX D W -40 KPX D V -40 KPX D A -35 KPX F r -55 KPX F period -135 KPX F o -105 KPX F i -45 KPX F e -75 KPX F comma -135 KPX F a -75 KPX F A -115 KPX G period 0 KPX G comma 0 KPX J u -35 KPX J period -25 KPX J o -25 KPX J e -25 KPX J comma -25 KPX J a -35 KPX J A -40 KPX K y -40 KPX K u -40 KPX K o -40 KPX K e -35 KPX K O -50 KPX L y -30 KPX L quoteright -37 KPX L quotedblright 0 KPX L Y -20 KPX L W -55 KPX L V -55 KPX L T -20 KPX N period 0 KPX N comma 0 KPX N A -27 KPX O period 0 KPX O comma 0 KPX O Y -50 KPX O X -40 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -55 KPX P period -135 KPX P o -80 KPX P e -80 KPX P comma -135 KPX P a -80 KPX P A -90 KPX Q period 0 KPX Q comma 0 KPX Q U -10 KPX R Y -18 KPX R W -18 KPX R V -18 KPX R U -40 KPX R T 0 KPX R O -40 KPX S period 0 KPX S comma 0 KPX T y -74 KPX T w -74 KPX T u -55 KPX T semicolon -65 KPX T r -55 KPX T period -74 KPX T o -92 KPX T i -55 KPX T hyphen -74 KPX T h 0 KPX T e -92 KPX T comma -74 KPX T colon -55 KPX T a -92 KPX T O -18 KPX T A -50 KPX U period -25 KPX U comma -25 KPX U A -40 KPX V u -74 KPX V semicolon -74 KPX V period -129 KPX V o -111 KPX V i -74 KPX V hyphen -55 KPX V e -111 KPX V comma -129 KPX V colon -65 KPX V a -111 KPX V O -30 KPX V G 0 KPX V A -60 KPX W y -70 KPX W u -55 KPX W semicolon -65 KPX W period -92 KPX W o -92 KPX W i -55 KPX W hyphen -37 KPX W h 0 KPX W e -92 KPX W comma -92 KPX W colon -65 KPX W a -92 KPX W O -25 KPX W A -60 KPX Y u -92 KPX Y semicolon -65 KPX Y period -92 KPX Y o -92 KPX Y i -74 KPX Y hyphen -74 KPX Y e -92 KPX Y comma -92 KPX Y colon -65 KPX Y a -92 KPX Y O -15 KPX Y A -50 KPX a y 0 KPX a w 0 KPX a v 0 KPX a t 0 KPX a p 0 KPX a g -10 KPX a b 0 KPX b y 0 KPX b v 0 KPX b u -20 KPX b period -40 KPX b l 0 KPX b comma 0 KPX b b 0 KPX c y 0 KPX c period 0 KPX c l 0 KPX c k -20 KPX c h -15 KPX c comma 0 KPX colon space 0 KPX comma space 0 KPX comma quoteright -140 KPX comma quotedblright -140 KPX d y 0 KPX d w 0 KPX d v 0 KPX d period 0 KPX d d 0 KPX d comma 0 KPX e y -30 KPX e x -20 KPX e w -15 KPX e v -15 KPX e period -15 KPX e p 0 KPX e g -40 KPX e comma -10 KPX e b 0 KPX f quoteright 92 KPX f quotedblright 0 KPX f period -15 KPX f o 0 KPX f l 0 KPX f i -20 KPX f f -18 KPX f e 0 KPX f dotlessi -60 KPX f comma -10 KPX f a 0 KPX g y 0 KPX g r 0 KPX g period -15 KPX g o 0 KPX g i 0 KPX g g -10 KPX g e -10 KPX g comma -10 KPX g a 0 KPX h y 0 KPX i v 0 KPX k y -10 KPX k o -10 KPX k e -10 KPX l y 0 KPX l w 0 KPX m y 0 KPX m u 0 KPX n y 0 KPX n v -40 KPX n u 0 KPX o y 0 KPX o x 0 KPX o w 0 KPX o v -10 KPX o g -10 KPX p y 0 KPX period quoteright -140 KPX period quotedblright -140 KPX quotedblleft quoteleft 0 KPX quotedblleft A 0 KPX quotedblright space 0 KPX quoteleft quoteleft -111 KPX quoteleft A 0 KPX quoteright v -10 KPX quoteright t -30 KPX quoteright space -111 KPX quoteright s -40 KPX quoteright r -25 KPX quoteright quoteright -111 KPX quoteright quotedblright 0 KPX quoteright l 0 KPX quoteright d -25 KPX r y 0 KPX r v 0 KPX r u 0 KPX r t 0 KPX r s -10 KPX r r 0 KPX r q -37 KPX r period -111 KPX r p 0 KPX r o -45 KPX r n 0 KPX r m 0 KPX r l 0 KPX r k 0 KPX r i 0 KPX r hyphen -20 KPX r g -37 KPX r e -37 KPX r d -37 KPX r comma -111 KPX r c -37 KPX r a -15 KPX s w 0 KPX space quoteleft 0 KPX space quotedblleft 0 KPX space Y -75 KPX space W -40 KPX space V -35 KPX space T -18 KPX space A -18 KPX v period -74 KPX v o 0 KPX v e 0 KPX v comma -74 KPX v a 0 KPX w period -74 KPX w o 0 KPX w h 0 KPX w e 0 KPX w comma -74 KPX w a 0 KPX x e 0 KPX y period -55 KPX y o 0 KPX y e 0 KPX y comma -55 KPX y a 0 KPX z o 0 KPX z e 0 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 139 212 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 144 212 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 139 212 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 149 212 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 129 192 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 139 212 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 149 212 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 212 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 159 212 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 149 212 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 212 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 212 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 30 212 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 212 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 177 212 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 212 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 230 212 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 205 212 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 212 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 94 212 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 215 212 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 225 212 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 215 212 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 132 212 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 212 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 112 212 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -57 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -52 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 49 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 74 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 69 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 74 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 74 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 74 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 36 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 8 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Narrow-BoldOblique.afm��������������������������������������0000644�0001750�0001750�00000042546�11462120062�022516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu Mar 15 12:08:57 1990 Comment UniqueID 28407 Comment VMusage 7614 43068 FontName Helvetica-Narrow-BoldOblique FullName Helvetica Narrow Bold Oblique FamilyName Helvetica Weight Bold ItalicAngle -12 IsFixedPitch false FontBBox -143 -228 913 962 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 228 ; N space ; B 0 0 0 0 ; C 33 ; WX 273 ; N exclam ; B 77 0 325 718 ; C 34 ; WX 389 ; N quotedbl ; B 158 447 433 718 ; C 35 ; WX 456 ; N numbersign ; B 49 0 528 698 ; C 36 ; WX 456 ; N dollar ; B 55 -115 510 775 ; C 37 ; WX 729 ; N percent ; B 112 -19 739 710 ; C 38 ; WX 592 ; N ampersand ; B 73 -19 600 718 ; C 39 ; WX 228 ; N quoteright ; B 137 445 297 718 ; C 40 ; WX 273 ; N parenleft ; B 62 -208 385 734 ; C 41 ; WX 273 ; N parenright ; B -21 -208 302 734 ; C 42 ; WX 319 ; N asterisk ; B 120 387 394 718 ; C 43 ; WX 479 ; N plus ; B 67 0 500 506 ; C 44 ; WX 228 ; N comma ; B 23 -168 201 146 ; C 45 ; WX 273 ; N hyphen ; B 60 215 311 345 ; C 46 ; WX 228 ; N period ; B 52 0 201 146 ; C 47 ; WX 228 ; N slash ; B -30 -19 383 737 ; C 48 ; WX 456 ; N zero ; B 71 -19 506 710 ; C 49 ; WX 456 ; N one ; B 142 0 434 710 ; C 50 ; WX 456 ; N two ; B 21 0 508 710 ; C 51 ; WX 456 ; N three ; B 54 -19 499 710 ; C 52 ; WX 456 ; N four ; B 50 0 490 710 ; C 53 ; WX 456 ; N five ; B 53 -19 522 698 ; C 54 ; WX 456 ; N six ; B 70 -19 507 710 ; C 55 ; WX 456 ; N seven ; B 102 0 555 698 ; C 56 ; WX 456 ; N eight ; B 57 -19 505 710 ; C 57 ; WX 456 ; N nine ; B 64 -19 504 710 ; C 58 ; WX 273 ; N colon ; B 75 0 288 512 ; C 59 ; WX 273 ; N semicolon ; B 46 -168 288 512 ; C 60 ; WX 479 ; N less ; B 67 -8 537 514 ; C 61 ; WX 479 ; N equal ; B 48 87 519 419 ; C 62 ; WX 479 ; N greater ; B 30 -8 500 514 ; C 63 ; WX 501 ; N question ; B 135 0 550 727 ; C 64 ; WX 800 ; N at ; B 152 -19 782 737 ; C 65 ; WX 592 ; N A ; B 16 0 576 718 ; C 66 ; WX 592 ; N B ; B 62 0 626 718 ; C 67 ; WX 592 ; N C ; B 88 -19 647 737 ; C 68 ; WX 592 ; N D ; B 62 0 637 718 ; C 69 ; WX 547 ; N E ; B 62 0 620 718 ; C 70 ; WX 501 ; N F ; B 62 0 606 718 ; C 71 ; WX 638 ; N G ; B 89 -19 670 737 ; C 72 ; WX 592 ; N H ; B 58 0 659 718 ; C 73 ; WX 228 ; N I ; B 52 0 301 718 ; C 74 ; WX 456 ; N J ; B 49 -18 522 718 ; C 75 ; WX 592 ; N K ; B 71 0 703 718 ; C 76 ; WX 501 ; N L ; B 62 0 501 718 ; C 77 ; WX 683 ; N M ; B 57 0 752 718 ; C 78 ; WX 592 ; N N ; B 57 0 661 718 ; C 79 ; WX 638 ; N O ; B 88 -19 675 737 ; C 80 ; WX 547 ; N P ; B 62 0 605 718 ; C 81 ; WX 638 ; N Q ; B 88 -52 675 737 ; C 82 ; WX 592 ; N R ; B 62 0 638 718 ; C 83 ; WX 547 ; N S ; B 66 -19 588 737 ; C 84 ; WX 501 ; N T ; B 114 0 615 718 ; C 85 ; WX 592 ; N U ; B 96 -19 659 718 ; C 86 ; WX 547 ; N V ; B 141 0 656 718 ; C 87 ; WX 774 ; N W ; B 138 0 887 718 ; C 88 ; WX 547 ; N X ; B 11 0 648 718 ; C 89 ; WX 547 ; N Y ; B 137 0 661 718 ; C 90 ; WX 501 ; N Z ; B 20 0 604 718 ; C 91 ; WX 273 ; N bracketleft ; B 17 -196 379 722 ; C 92 ; WX 228 ; N backslash ; B 101 -19 252 737 ; C 93 ; WX 273 ; N bracketright ; B -14 -196 347 722 ; C 94 ; WX 479 ; N asciicircum ; B 107 323 484 698 ; C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ; C 96 ; WX 228 ; N quoteleft ; B 136 454 296 727 ; C 97 ; WX 456 ; N a ; B 45 -14 478 546 ; C 98 ; WX 501 ; N b ; B 50 -14 529 718 ; C 99 ; WX 456 ; N c ; B 65 -14 491 546 ; C 100 ; WX 501 ; N d ; B 67 -14 577 718 ; C 101 ; WX 456 ; N e ; B 58 -14 486 546 ; C 102 ; WX 273 ; N f ; B 71 0 385 727 ; L i fi ; L l fl ; C 103 ; WX 501 ; N g ; B 31 -217 546 546 ; C 104 ; WX 501 ; N h ; B 53 0 516 718 ; C 105 ; WX 228 ; N i ; B 57 0 298 725 ; C 106 ; WX 228 ; N j ; B -35 -214 298 725 ; C 107 ; WX 456 ; N k ; B 57 0 549 718 ; C 108 ; WX 228 ; N l ; B 57 0 297 718 ; C 109 ; WX 729 ; N m ; B 52 0 746 546 ; C 110 ; WX 501 ; N n ; B 53 0 516 546 ; C 111 ; WX 501 ; N o ; B 67 -14 527 546 ; C 112 ; WX 501 ; N p ; B 15 -207 529 546 ; C 113 ; WX 501 ; N q ; B 66 -207 545 546 ; C 114 ; WX 319 ; N r ; B 52 0 401 546 ; C 115 ; WX 456 ; N s ; B 52 -14 479 546 ; C 116 ; WX 273 ; N t ; B 82 -6 346 676 ; C 117 ; WX 501 ; N u ; B 80 -14 540 532 ; C 118 ; WX 456 ; N v ; B 103 0 538 532 ; C 119 ; WX 638 ; N w ; B 101 0 723 532 ; C 120 ; WX 456 ; N x ; B 12 0 531 532 ; C 121 ; WX 456 ; N y ; B 34 -214 535 532 ; C 122 ; WX 410 ; N z ; B 16 0 478 532 ; C 123 ; WX 319 ; N braceleft ; B 77 -196 425 722 ; C 124 ; WX 230 ; N bar ; B 66 -19 289 737 ; C 125 ; WX 319 ; N braceright ; B -14 -196 333 722 ; C 126 ; WX 479 ; N asciitilde ; B 94 163 473 343 ; C 161 ; WX 273 ; N exclamdown ; B 41 -186 290 532 ; C 162 ; WX 456 ; N cent ; B 65 -118 491 628 ; C 163 ; WX 456 ; N sterling ; B 41 -16 520 718 ; C 164 ; WX 137 ; N fraction ; B -143 -19 399 710 ; C 165 ; WX 456 ; N yen ; B 49 0 585 698 ; C 166 ; WX 456 ; N florin ; B -41 -210 548 737 ; C 167 ; WX 456 ; N section ; B 50 -184 491 727 ; C 168 ; WX 456 ; N currency ; B 22 76 558 636 ; C 169 ; WX 195 ; N quotesingle ; B 135 447 263 718 ; C 170 ; WX 410 ; N quotedblleft ; B 132 454 482 727 ; C 171 ; WX 456 ; N guillemotleft ; B 111 76 468 484 ; C 172 ; WX 273 ; N guilsinglleft ; B 106 76 289 484 ; C 173 ; WX 273 ; N guilsinglright ; B 81 76 264 484 ; C 174 ; WX 501 ; N fi ; B 71 0 571 727 ; C 175 ; WX 501 ; N fl ; B 71 0 570 727 ; C 177 ; WX 456 ; N endash ; B 40 227 514 333 ; C 178 ; WX 456 ; N dagger ; B 97 -171 513 718 ; C 179 ; WX 456 ; N daggerdbl ; B 38 -171 515 718 ; C 180 ; WX 228 ; N periodcentered ; B 90 172 226 334 ; C 182 ; WX 456 ; N paragraph ; B 80 -191 564 700 ; C 183 ; WX 287 ; N bullet ; B 68 194 345 524 ; C 184 ; WX 228 ; N quotesinglbase ; B 34 -146 194 127 ; C 185 ; WX 410 ; N quotedblbase ; B 29 -146 380 127 ; C 186 ; WX 410 ; N quotedblright ; B 132 445 483 718 ; C 187 ; WX 456 ; N guillemotright ; B 85 76 443 484 ; C 188 ; WX 820 ; N ellipsis ; B 75 0 770 146 ; C 189 ; WX 820 ; N perthousand ; B 62 -19 851 710 ; C 191 ; WX 501 ; N questiondown ; B 44 -195 459 532 ; C 193 ; WX 273 ; N grave ; B 112 604 290 750 ; C 194 ; WX 273 ; N acute ; B 194 604 423 750 ; C 195 ; WX 273 ; N circumflex ; B 97 604 387 750 ; C 196 ; WX 273 ; N tilde ; B 92 610 415 737 ; C 197 ; WX 273 ; N macron ; B 100 604 396 678 ; C 198 ; WX 273 ; N breve ; B 128 604 405 750 ; C 199 ; WX 273 ; N dotaccent ; B 192 614 316 729 ; C 200 ; WX 273 ; N dieresis ; B 112 614 395 729 ; C 202 ; WX 273 ; N ring ; B 164 568 344 776 ; C 203 ; WX 273 ; N cedilla ; B -30 -228 180 0 ; C 205 ; WX 273 ; N hungarumlaut ; B 113 604 529 750 ; C 206 ; WX 273 ; N ogonek ; B 33 -228 216 0 ; C 207 ; WX 273 ; N caron ; B 123 604 412 750 ; C 208 ; WX 820 ; N emdash ; B 40 227 878 333 ; C 225 ; WX 820 ; N AE ; B 4 0 902 718 ; C 227 ; WX 303 ; N ordfeminine ; B 75 276 381 737 ; C 232 ; WX 501 ; N Lslash ; B 28 0 501 718 ; C 233 ; WX 638 ; N Oslash ; B 29 -27 733 745 ; C 234 ; WX 820 ; N OE ; B 81 -19 913 737 ; C 235 ; WX 299 ; N ordmasculine ; B 75 276 398 737 ; C 241 ; WX 729 ; N ae ; B 46 -14 757 546 ; C 245 ; WX 228 ; N dotlessi ; B 57 0 264 532 ; C 248 ; WX 228 ; N lslash ; B 33 0 334 718 ; C 249 ; WX 501 ; N oslash ; B 18 -29 575 560 ; C 250 ; WX 774 ; N oe ; B 67 -14 801 546 ; C 251 ; WX 501 ; N germandbls ; B 57 -14 539 731 ; C -1 ; WX 501 ; N Zcaron ; B 20 0 604 936 ; C -1 ; WX 456 ; N ccedilla ; B 65 -228 491 546 ; C -1 ; WX 456 ; N ydieresis ; B 34 -214 535 729 ; C -1 ; WX 456 ; N atilde ; B 45 -14 507 737 ; C -1 ; WX 228 ; N icircumflex ; B 57 0 364 750 ; C -1 ; WX 273 ; N threesuperior ; B 75 271 361 710 ; C -1 ; WX 456 ; N ecircumflex ; B 58 -14 486 750 ; C -1 ; WX 501 ; N thorn ; B 15 -208 529 718 ; C -1 ; WX 456 ; N egrave ; B 58 -14 486 750 ; C -1 ; WX 273 ; N twosuperior ; B 57 283 368 710 ; C -1 ; WX 456 ; N eacute ; B 58 -14 514 750 ; C -1 ; WX 501 ; N otilde ; B 67 -14 529 737 ; C -1 ; WX 592 ; N Aacute ; B 16 0 615 936 ; C -1 ; WX 501 ; N ocircumflex ; B 67 -14 527 750 ; C -1 ; WX 456 ; N yacute ; B 34 -214 535 750 ; C -1 ; WX 501 ; N udieresis ; B 80 -14 540 729 ; C -1 ; WX 684 ; N threequarters ; B 82 -19 688 710 ; C -1 ; WX 456 ; N acircumflex ; B 45 -14 478 750 ; C -1 ; WX 592 ; N Eth ; B 51 0 637 718 ; C -1 ; WX 456 ; N edieresis ; B 58 -14 487 729 ; C -1 ; WX 501 ; N ugrave ; B 80 -14 540 750 ; C -1 ; WX 820 ; N trademark ; B 146 306 909 718 ; C -1 ; WX 501 ; N ograve ; B 67 -14 527 750 ; C -1 ; WX 456 ; N scaron ; B 52 -14 504 750 ; C -1 ; WX 228 ; N Idieresis ; B 52 0 405 915 ; C -1 ; WX 501 ; N uacute ; B 80 -14 540 750 ; C -1 ; WX 456 ; N agrave ; B 45 -14 478 750 ; C -1 ; WX 501 ; N ntilde ; B 53 0 529 737 ; C -1 ; WX 456 ; N aring ; B 45 -14 478 776 ; C -1 ; WX 410 ; N zcaron ; B 16 0 481 750 ; C -1 ; WX 228 ; N Icircumflex ; B 52 0 397 936 ; C -1 ; WX 592 ; N Ntilde ; B 57 0 661 923 ; C -1 ; WX 501 ; N ucircumflex ; B 80 -14 540 750 ; C -1 ; WX 547 ; N Ecircumflex ; B 62 0 620 936 ; C -1 ; WX 228 ; N Iacute ; B 52 0 433 936 ; C -1 ; WX 592 ; N Ccedilla ; B 88 -228 647 737 ; C -1 ; WX 638 ; N Odieresis ; B 88 -19 675 915 ; C -1 ; WX 547 ; N Scaron ; B 66 -19 588 936 ; C -1 ; WX 547 ; N Edieresis ; B 62 0 620 915 ; C -1 ; WX 228 ; N Igrave ; B 52 0 301 936 ; C -1 ; WX 456 ; N adieresis ; B 45 -14 487 729 ; C -1 ; WX 638 ; N Ograve ; B 88 -19 675 936 ; C -1 ; WX 547 ; N Egrave ; B 62 0 620 936 ; C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 915 ; C -1 ; WX 604 ; N registered ; B 45 -19 684 737 ; C -1 ; WX 638 ; N Otilde ; B 88 -19 675 923 ; C -1 ; WX 684 ; N onequarter ; B 108 -19 661 710 ; C -1 ; WX 592 ; N Ugrave ; B 96 -19 659 936 ; C -1 ; WX 592 ; N Ucircumflex ; B 96 -19 659 936 ; C -1 ; WX 547 ; N Thorn ; B 62 0 588 718 ; C -1 ; WX 479 ; N divide ; B 67 -42 500 548 ; C -1 ; WX 592 ; N Atilde ; B 16 0 608 923 ; C -1 ; WX 592 ; N Uacute ; B 96 -19 659 936 ; C -1 ; WX 638 ; N Ocircumflex ; B 88 -19 675 936 ; C -1 ; WX 479 ; N logicalnot ; B 86 108 519 419 ; C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ; C -1 ; WX 228 ; N idieresis ; B 57 0 373 729 ; C -1 ; WX 228 ; N iacute ; B 57 0 400 750 ; C -1 ; WX 456 ; N aacute ; B 45 -14 514 750 ; C -1 ; WX 479 ; N plusminus ; B 33 0 512 506 ; C -1 ; WX 479 ; N multiply ; B 47 1 520 505 ; C -1 ; WX 592 ; N Udieresis ; B 96 -19 659 915 ; C -1 ; WX 479 ; N minus ; B 67 197 500 309 ; C -1 ; WX 273 ; N onesuperior ; B 121 283 318 710 ; C -1 ; WX 547 ; N Eacute ; B 62 0 620 936 ; C -1 ; WX 592 ; N Acircumflex ; B 16 0 579 936 ; C -1 ; WX 604 ; N copyright ; B 46 -19 685 737 ; C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ; C -1 ; WX 501 ; N odieresis ; B 67 -14 527 729 ; C -1 ; WX 501 ; N oacute ; B 67 -14 537 750 ; C -1 ; WX 328 ; N degree ; B 143 426 383 712 ; C -1 ; WX 228 ; N igrave ; B 57 0 268 750 ; C -1 ; WX 501 ; N mu ; B 18 -207 540 532 ; C -1 ; WX 638 ; N Oacute ; B 88 -19 675 936 ; C -1 ; WX 501 ; N eth ; B 67 -14 549 737 ; C -1 ; WX 592 ; N Adieresis ; B 16 0 588 915 ; C -1 ; WX 547 ; N Yacute ; B 137 0 661 936 ; C -1 ; WX 230 ; N brokenbar ; B 66 -19 289 737 ; C -1 ; WX 684 ; N onehalf ; B 108 -19 704 710 ; EndCharMetrics StartKernData StartKernPairs 209 KPX A y -30 KPX A w -30 KPX A v -40 KPX A u -30 KPX A Y -110 KPX A W -60 KPX A V -80 KPX A U -50 KPX A T -90 KPX A Q -40 KPX A O -40 KPX A G -50 KPX A C -40 KPX B U -10 KPX B A -30 KPX D period -30 KPX D comma -30 KPX D Y -70 KPX D W -40 KPX D V -40 KPX D A -40 KPX F period -100 KPX F comma -100 KPX F a -20 KPX F A -80 KPX J u -20 KPX J period -20 KPX J comma -20 KPX J A -20 KPX K y -40 KPX K u -30 KPX K o -35 KPX K e -15 KPX K O -30 KPX L y -30 KPX L quoteright -140 KPX L quotedblright -140 KPX L Y -120 KPX L W -80 KPX L V -110 KPX L T -90 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -50 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -50 KPX P period -120 KPX P o -40 KPX P e -30 KPX P comma -120 KPX P a -30 KPX P A -100 KPX Q period 20 KPX Q comma 20 KPX Q U -10 KPX R Y -50 KPX R W -40 KPX R V -50 KPX R U -20 KPX R T -20 KPX R O -20 KPX T y -60 KPX T w -60 KPX T u -90 KPX T semicolon -40 KPX T r -80 KPX T period -80 KPX T o -80 KPX T hyphen -120 KPX T e -60 KPX T comma -80 KPX T colon -40 KPX T a -80 KPX T O -40 KPX T A -90 KPX U period -30 KPX U comma -30 KPX U A -50 KPX V u -60 KPX V semicolon -40 KPX V period -120 KPX V o -90 KPX V hyphen -80 KPX V e -50 KPX V comma -120 KPX V colon -40 KPX V a -60 KPX V O -50 KPX V G -50 KPX V A -80 KPX W y -20 KPX W u -45 KPX W semicolon -10 KPX W period -80 KPX W o -60 KPX W hyphen -40 KPX W e -35 KPX W comma -80 KPX W colon -10 KPX W a -40 KPX W O -20 KPX W A -60 KPX Y u -100 KPX Y semicolon -50 KPX Y period -100 KPX Y o -100 KPX Y e -80 KPX Y comma -100 KPX Y colon -50 KPX Y a -90 KPX Y O -70 KPX Y A -110 KPX a y -20 KPX a w -15 KPX a v -15 KPX a g -10 KPX b y -20 KPX b v -20 KPX b u -20 KPX b l -10 KPX c y -10 KPX c l -20 KPX c k -20 KPX c h -10 KPX colon space -40 KPX comma space -40 KPX comma quoteright -120 KPX comma quotedblright -120 KPX d y -15 KPX d w -15 KPX d v -15 KPX d d -10 KPX e y -15 KPX e x -15 KPX e w -15 KPX e v -15 KPX e period 20 KPX e comma 10 KPX f quoteright 30 KPX f quotedblright 30 KPX f period -10 KPX f o -20 KPX f e -10 KPX f comma -10 KPX g g -10 KPX g e 10 KPX h y -20 KPX k o -15 KPX l y -15 KPX l w -15 KPX m y -30 KPX m u -20 KPX n y -20 KPX n v -40 KPX n u -10 KPX o y -20 KPX o x -30 KPX o w -15 KPX o v -20 KPX p y -15 KPX period space -40 KPX period quoteright -120 KPX period quotedblright -120 KPX quotedblright space -80 KPX quoteleft quoteleft -46 KPX quoteright v -20 KPX quoteright space -80 KPX quoteright s -60 KPX quoteright r -40 KPX quoteright quoteright -46 KPX quoteright l -20 KPX quoteright d -80 KPX r y 10 KPX r v 10 KPX r t 20 KPX r s -15 KPX r q -20 KPX r period -60 KPX r o -20 KPX r hyphen -20 KPX r g -15 KPX r d -20 KPX r comma -60 KPX r c -20 KPX s w -15 KPX semicolon space -40 KPX space quoteleft -60 KPX space quotedblleft -80 KPX space Y -120 KPX space W -80 KPX space V -80 KPX space T -100 KPX v period -80 KPX v o -30 KPX v comma -80 KPX v a -20 KPX w period -40 KPX w o -20 KPX w comma -40 KPX x e -10 KPX y period -80 KPX y o -25 KPX y e -10 KPX y comma -80 KPX y a -30 KPX z e 10 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 192 186 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 192 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 192 186 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 192 186 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 169 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 186 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 169 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 169 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 10 186 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 10 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 192 186 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 215 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 215 186 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 215 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 186 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 169 186 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 192 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 192 186 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 192 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 192 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 169 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 146 186 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica.afm���������������������������������������������������������0000644�0001750�0001750�00000044024�11462120062�017042� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Thu Mar 15 08:58:00 1990 Comment UniqueID 28352 Comment VMusage 26389 33281 FontName Helvetica FullName Helvetica FamilyName Helvetica Weight Medium ItalicAngle 0 IsFixedPitch false FontBBox -166 -225 1000 931 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ; C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ; C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ; C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ; C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ; C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ; C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ; C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ; C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ; C 43 ; WX 584 ; N plus ; B 39 0 545 505 ; C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ; C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ; C 46 ; WX 278 ; N period ; B 87 0 191 106 ; C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ; C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ; C 49 ; WX 556 ; N one ; B 101 0 359 703 ; C 50 ; WX 556 ; N two ; B 26 0 507 703 ; C 51 ; WX 556 ; N three ; B 34 -19 522 703 ; C 52 ; WX 556 ; N four ; B 25 0 523 703 ; C 53 ; WX 556 ; N five ; B 32 -19 514 688 ; C 54 ; WX 556 ; N six ; B 38 -19 518 703 ; C 55 ; WX 556 ; N seven ; B 37 0 523 688 ; C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ; C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ; C 58 ; WX 278 ; N colon ; B 87 0 191 516 ; C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ; C 60 ; WX 584 ; N less ; B 48 11 536 495 ; C 61 ; WX 584 ; N equal ; B 39 115 545 390 ; C 62 ; WX 584 ; N greater ; B 48 11 536 495 ; C 63 ; WX 556 ; N question ; B 56 0 492 727 ; C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ; C 65 ; WX 667 ; N A ; B 14 0 654 718 ; C 66 ; WX 667 ; N B ; B 74 0 627 718 ; C 67 ; WX 722 ; N C ; B 44 -19 681 737 ; C 68 ; WX 722 ; N D ; B 81 0 674 718 ; C 69 ; WX 667 ; N E ; B 86 0 616 718 ; C 70 ; WX 611 ; N F ; B 86 0 583 718 ; C 71 ; WX 778 ; N G ; B 48 -19 704 737 ; C 72 ; WX 722 ; N H ; B 77 0 646 718 ; C 73 ; WX 278 ; N I ; B 91 0 188 718 ; C 74 ; WX 500 ; N J ; B 17 -19 428 718 ; C 75 ; WX 667 ; N K ; B 76 0 663 718 ; C 76 ; WX 556 ; N L ; B 76 0 537 718 ; C 77 ; WX 833 ; N M ; B 73 0 761 718 ; C 78 ; WX 722 ; N N ; B 76 0 646 718 ; C 79 ; WX 778 ; N O ; B 39 -19 739 737 ; C 80 ; WX 667 ; N P ; B 86 0 622 718 ; C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ; C 82 ; WX 722 ; N R ; B 88 0 684 718 ; C 83 ; WX 667 ; N S ; B 49 -19 620 737 ; C 84 ; WX 611 ; N T ; B 14 0 597 718 ; C 85 ; WX 722 ; N U ; B 79 -19 644 718 ; C 86 ; WX 667 ; N V ; B 20 0 647 718 ; C 87 ; WX 944 ; N W ; B 16 0 928 718 ; C 88 ; WX 667 ; N X ; B 19 0 648 718 ; C 89 ; WX 667 ; N Y ; B 14 0 653 718 ; C 90 ; WX 611 ; N Z ; B 23 0 588 718 ; C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ; C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ; C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ; C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ; C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ; C 97 ; WX 556 ; N a ; B 36 -15 530 538 ; C 98 ; WX 556 ; N b ; B 58 -15 517 718 ; C 99 ; WX 500 ; N c ; B 30 -15 477 538 ; C 100 ; WX 556 ; N d ; B 35 -15 499 718 ; C 101 ; WX 556 ; N e ; B 40 -15 516 538 ; C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 40 -220 499 538 ; C 104 ; WX 556 ; N h ; B 65 0 491 718 ; C 105 ; WX 222 ; N i ; B 67 0 155 718 ; C 106 ; WX 222 ; N j ; B -16 -210 155 718 ; C 107 ; WX 500 ; N k ; B 67 0 501 718 ; C 108 ; WX 222 ; N l ; B 67 0 155 718 ; C 109 ; WX 833 ; N m ; B 65 0 769 538 ; C 110 ; WX 556 ; N n ; B 65 0 491 538 ; C 111 ; WX 556 ; N o ; B 35 -14 521 538 ; C 112 ; WX 556 ; N p ; B 58 -207 517 538 ; C 113 ; WX 556 ; N q ; B 35 -207 494 538 ; C 114 ; WX 333 ; N r ; B 77 0 332 538 ; C 115 ; WX 500 ; N s ; B 32 -15 464 538 ; C 116 ; WX 278 ; N t ; B 14 -7 257 669 ; C 117 ; WX 556 ; N u ; B 68 -15 489 523 ; C 118 ; WX 500 ; N v ; B 8 0 492 523 ; C 119 ; WX 722 ; N w ; B 14 0 709 523 ; C 120 ; WX 500 ; N x ; B 11 0 490 523 ; C 121 ; WX 500 ; N y ; B 11 -214 489 523 ; C 122 ; WX 500 ; N z ; B 31 0 469 523 ; C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ; C 124 ; WX 260 ; N bar ; B 94 -19 167 737 ; C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ; C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ; C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ; C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ; C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ; C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ; C 165 ; WX 556 ; N yen ; B 3 0 553 688 ; C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ; C 167 ; WX 556 ; N section ; B 43 -191 512 737 ; C 168 ; WX 556 ; N currency ; B 28 99 528 603 ; C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ; C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ; C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ; C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ; C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ; C 174 ; WX 500 ; N fi ; B 14 0 434 728 ; C 175 ; WX 500 ; N fl ; B 14 0 432 728 ; C 177 ; WX 556 ; N endash ; B 0 240 556 313 ; C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ; C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ; C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ; C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ; C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ; C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ; C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ; C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ; C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ; C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ; C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ; C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ; C 193 ; WX 333 ; N grave ; B 14 593 211 734 ; C 194 ; WX 333 ; N acute ; B 122 593 319 734 ; C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ; C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ; C 197 ; WX 333 ; N macron ; B 10 627 323 684 ; C 198 ; WX 333 ; N breve ; B 13 595 321 731 ; C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ; C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ; C 202 ; WX 333 ; N ring ; B 75 572 259 756 ; C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ; C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ; C 207 ; WX 333 ; N caron ; B 21 593 312 734 ; C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ; C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ; C 227 ; WX 370 ; N ordfeminine ; B 24 304 346 737 ; C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ; C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ; C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ; C 235 ; WX 365 ; N ordmasculine ; B 25 304 341 737 ; C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ; C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ; C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ; C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ; C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ; C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ; C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ; C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ; C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ; C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ; C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ; C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ; C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ; C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ; C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ; C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ; C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ; C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ; C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ; C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ; C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ; C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ; C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ; C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ; C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ; C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ; C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ; C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ; C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ; C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ; C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ; C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ; C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ; C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ; C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ; C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ; C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ; C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ; C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ; C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ; C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ; C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ; C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ; C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ; C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ; C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ; C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ; C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ; C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ; C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ; C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ; C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ; C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ; C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ; C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ; C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ; C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ; C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ; C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ; C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ; C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ; C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ; C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ; C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ; C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ; C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ; C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ; C -1 ; WX 584 ; N minus ; B 39 216 545 289 ; C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ; C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ; C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ; C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ; C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ; C -1 ; WX 400 ; N degree ; B 54 411 346 703 ; C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ; C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ; C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ; C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ; C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ; C -1 ; WX 260 ; N brokenbar ; B 94 -19 167 737 ; C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ; EndCharMetrics StartKernData StartKernPairs 250 KPX A y -40 KPX A w -40 KPX A v -40 KPX A u -30 KPX A Y -100 KPX A W -50 KPX A V -70 KPX A U -50 KPX A T -120 KPX A Q -30 KPX A O -30 KPX A G -30 KPX A C -30 KPX B period -20 KPX B comma -20 KPX B U -10 KPX C period -30 KPX C comma -30 KPX D period -70 KPX D comma -70 KPX D Y -90 KPX D W -40 KPX D V -70 KPX D A -40 KPX F r -45 KPX F period -150 KPX F o -30 KPX F e -30 KPX F comma -150 KPX F a -50 KPX F A -80 KPX J u -20 KPX J period -30 KPX J comma -30 KPX J a -20 KPX J A -20 KPX K y -50 KPX K u -30 KPX K o -40 KPX K e -40 KPX K O -50 KPX L y -30 KPX L quoteright -160 KPX L quotedblright -140 KPX L Y -140 KPX L W -70 KPX L V -110 KPX L T -110 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -60 KPX O W -30 KPX O V -50 KPX O T -40 KPX O A -20 KPX P period -180 KPX P o -50 KPX P e -50 KPX P comma -180 KPX P a -40 KPX P A -120 KPX Q U -10 KPX R Y -50 KPX R W -30 KPX R V -50 KPX R U -40 KPX R T -30 KPX R O -20 KPX S period -20 KPX S comma -20 KPX T y -120 KPX T w -120 KPX T u -120 KPX T semicolon -20 KPX T r -120 KPX T period -120 KPX T o -120 KPX T hyphen -140 KPX T e -120 KPX T comma -120 KPX T colon -20 KPX T a -120 KPX T O -40 KPX T A -120 KPX U period -40 KPX U comma -40 KPX U A -40 KPX V u -70 KPX V semicolon -40 KPX V period -125 KPX V o -80 KPX V hyphen -80 KPX V e -80 KPX V comma -125 KPX V colon -40 KPX V a -70 KPX V O -40 KPX V G -40 KPX V A -80 KPX W y -20 KPX W u -30 KPX W period -80 KPX W o -30 KPX W hyphen -40 KPX W e -30 KPX W comma -80 KPX W a -40 KPX W O -20 KPX W A -50 KPX Y u -110 KPX Y semicolon -60 KPX Y period -140 KPX Y o -140 KPX Y i -20 KPX Y hyphen -140 KPX Y e -140 KPX Y comma -140 KPX Y colon -60 KPX Y a -140 KPX Y O -85 KPX Y A -110 KPX a y -30 KPX a w -20 KPX a v -20 KPX b y -20 KPX b v -20 KPX b u -20 KPX b period -40 KPX b l -20 KPX b comma -40 KPX b b -10 KPX c k -20 KPX c comma -15 KPX colon space -50 KPX comma quoteright -100 KPX comma quotedblright -100 KPX e y -20 KPX e x -30 KPX e w -20 KPX e v -30 KPX e period -15 KPX e comma -15 KPX f quoteright 50 KPX f quotedblright 60 KPX f period -30 KPX f o -30 KPX f e -30 KPX f dotlessi -28 KPX f comma -30 KPX f a -30 KPX g r -10 KPX h y -30 KPX k o -20 KPX k e -20 KPX m y -15 KPX m u -10 KPX n y -15 KPX n v -20 KPX n u -10 KPX o y -30 KPX o x -30 KPX o w -15 KPX o v -15 KPX o period -40 KPX o comma -40 KPX oslash z -55 KPX oslash y -70 KPX oslash x -85 KPX oslash w -70 KPX oslash v -70 KPX oslash u -55 KPX oslash t -55 KPX oslash s -55 KPX oslash r -55 KPX oslash q -55 KPX oslash period -95 KPX oslash p -55 KPX oslash o -55 KPX oslash n -55 KPX oslash m -55 KPX oslash l -55 KPX oslash k -55 KPX oslash j -55 KPX oslash i -55 KPX oslash h -55 KPX oslash g -55 KPX oslash f -55 KPX oslash e -55 KPX oslash d -55 KPX oslash comma -95 KPX oslash c -55 KPX oslash b -55 KPX oslash a -55 KPX p y -30 KPX p period -35 KPX p comma -35 KPX period space -60 KPX period quoteright -100 KPX period quotedblright -100 KPX quotedblright space -40 KPX quoteleft quoteleft -57 KPX quoteright space -70 KPX quoteright s -50 KPX quoteright r -50 KPX quoteright quoteright -57 KPX quoteright d -50 KPX r y 30 KPX r v 30 KPX r u 15 KPX r t 40 KPX r semicolon 30 KPX r period -50 KPX r p 30 KPX r n 25 KPX r m 25 KPX r l 15 KPX r k 15 KPX r i 15 KPX r comma -50 KPX r colon 30 KPX r a -10 KPX s w -30 KPX s period -15 KPX s comma -15 KPX semicolon space -50 KPX space quoteleft -60 KPX space quotedblleft -30 KPX space Y -90 KPX space W -40 KPX space V -50 KPX space T -50 KPX v period -80 KPX v o -25 KPX v e -25 KPX v comma -80 KPX v a -25 KPX w period -60 KPX w o -10 KPX w e -10 KPX w comma -60 KPX w a -15 KPX x e -30 KPX y period -100 KPX y o -20 KPX y e -20 KPX y comma -100 KPX y a -20 KPX z o -15 KPX z e -15 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 195 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 195 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 195 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 195 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 195 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 195 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 195 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 195 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 195 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 195 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 195 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 195 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 195 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 205 195 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 195 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 195 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 195 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 195 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 195 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 195 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 195 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 195 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 195 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 195 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 195 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 195 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 195 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; EndComposites EndFontMetrics ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Courier-Oblique.afm���������������������������������������������������0000644�0001750�0001750�00000036654�11462120062�020156� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Tue Sep 17 09:42:19 1991 Comment UniqueID 36350 Comment VMusage 9174 52297 FontName Courier-Oblique FullName Courier Oblique FamilyName Courier Weight Medium ItalicAngle -12 IsFixedPitch true FontBBox -28 -250 742 805 UnderlinePosition -100 UnderlineThickness 50 Version 002.004 Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 426 Ascender 629 Descender -157 StartCharMetrics 260 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ; C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; C 49 ; WX 600 ; N one ; B 98 0 515 622 ; C 50 ; WX 600 ; N two ; B 70 0 568 622 ; C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; C 52 ; WX 600 ; N four ; B 108 0 541 622 ; C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; C 60 ; WX 600 ; N less ; B 96 42 610 472 ; C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; C 65 ; WX 600 ; N A ; B 3 0 607 562 ; C 66 ; WX 600 ; N B ; B 43 0 616 562 ; C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; C 68 ; WX 600 ; N D ; B 43 0 645 562 ; C 69 ; WX 600 ; N E ; B 53 0 660 562 ; C 70 ; WX 600 ; N F ; B 53 0 660 562 ; C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; C 72 ; WX 600 ; N H ; B 32 0 687 562 ; C 73 ; WX 600 ; N I ; B 96 0 623 562 ; C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; C 75 ; WX 600 ; N K ; B 38 0 671 562 ; C 76 ; WX 600 ; N L ; B 47 0 607 562 ; C 77 ; WX 600 ; N M ; B 4 0 715 562 ; C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; C 80 ; WX 600 ; N P ; B 79 0 644 562 ; C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; C 82 ; WX 600 ; N R ; B 38 0 598 562 ; C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; C 84 ; WX 600 ; N T ; B 108 0 665 562 ; C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; C 88 ; WX 600 ; N X ; B 23 0 675 562 ; C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; C 104 ; WX 600 ; N h ; B 33 0 592 629 ; C 105 ; WX 600 ; N i ; B 95 0 515 657 ; C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; C 107 ; WX 600 ; N k ; B 58 0 633 629 ; C 108 ; WX 600 ; N l ; B 95 0 515 629 ; C 109 ; WX 600 ; N m ; B -5 0 615 441 ; C 110 ; WX 600 ; N n ; B 26 0 585 441 ; C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; C 114 ; WX 600 ; N r ; B 60 0 636 441 ; C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; C 120 ; WX 600 ; N x ; B 20 0 655 426 ; C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; C 122 ; WX 600 ; N z ; B 99 0 593 426 ; C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ; C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ; C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; C 168 ; WX 600 ; N currency ; B 94 58 628 506 ; C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; C 174 ; WX 600 ; N fi ; B 3 0 619 629 ; C 175 ; WX 600 ; N fl ; B 3 0 619 629 ; C 177 ; WX 600 ; N endash ; B 124 231 586 285 ; C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ; C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ; C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; C 193 ; WX 600 ; N grave ; B 294 497 484 672 ; C 194 ; WX 600 ; N acute ; B 348 497 612 672 ; C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ; C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ; C 197 ; WX 600 ; N macron ; B 232 525 600 565 ; C 198 ; WX 600 ; N breve ; B 279 501 576 609 ; C 199 ; WX 600 ; N dotaccent ; B 360 477 466 580 ; C 200 ; WX 600 ; N dieresis ; B 262 492 570 595 ; C 202 ; WX 600 ; N ring ; B 332 463 500 627 ; C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; C 206 ; WX 600 ; N ogonek ; B 207 -151 348 0 ; C 207 ; WX 600 ; N caron ; B 262 492 614 669 ; C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ; C 225 ; WX 600 ; N AE ; B 3 0 655 562 ; C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ; C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; C 234 ; WX 600 ; N OE ; B 59 0 672 562 ; C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ; C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; C 248 ; WX 600 ; N lslash ; B 95 0 583 629 ; C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ; C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ; C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 731 ; C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; C -1 ; WX 600 ; N merge ; B 187 -15 503 436 ; C -1 ; WX 600 ; N degree ; B 214 269 576 622 ; C -1 ; WX 600 ; N dectab ; B 18 0 593 227 ; C -1 ; WX 600 ; N ll ; B 33 0 616 629 ; C -1 ; WX 600 ; N IJ ; B 32 -18 702 562 ; C -1 ; WX 600 ; N Eacute ; B 53 0 668 793 ; C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 775 ; C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; C -1 ; WX 600 ; N left ; B 114 68 580 348 ; C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; C -1 ; WX 600 ; N up ; B 223 0 503 437 ; C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ; C -1 ; WX 600 ; N Scaron ; B 76 -20 673 805 ; C -1 ; WX 600 ; N tab ; B 19 0 641 562 ; C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 775 ; C -1 ; WX 600 ; N divide ; B 136 48 573 467 ; C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 775 ; C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ; C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ; C -1 ; WX 600 ; N Aacute ; B 3 0 658 793 ; C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 775 ; C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ; C -1 ; WX 600 ; N down ; B 187 -15 467 426 ; C -1 ; WX 600 ; N center ; B 103 14 623 580 ; C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; C -1 ; WX 600 ; N ij ; B 37 -157 630 657 ; C -1 ; WX 600 ; N edieresis ; B 106 -15 598 595 ; C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ; C -1 ; WX 600 ; N odieresis ; B 102 -15 588 595 ; C -1 ; WX 600 ; N Ograve ; B 94 -18 625 793 ; C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ; C -1 ; WX 600 ; N prescription ; B 27 -15 617 562 ; C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ; C -1 ; WX 600 ; N largebullet ; B 315 220 395 297 ; C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ; C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; C -1 ; WX 600 ; N notegraphic ; B 143 -15 564 572 ; C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 731 ; C -1 ; WX 600 ; N Gcaron ; B 83 -18 645 805 ; C -1 ; WX 600 ; N arrowdown ; B 152 -15 520 608 ; C -1 ; WX 600 ; N format ; B -28 -157 185 607 ; C -1 ; WX 600 ; N Otilde ; B 94 -18 656 732 ; C -1 ; WX 600 ; N Idieresis ; B 96 0 623 731 ; C -1 ; WX 600 ; N adieresis ; B 76 -15 570 595 ; C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ; C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; C -1 ; WX 600 ; N LL ; B 8 0 647 562 ; C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ; C -1 ; WX 600 ; N Zcaron ; B 86 0 643 805 ; C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; C -1 ; WX 600 ; N Idot ; B 96 0 623 716 ; C -1 ; WX 600 ; N Iacute ; B 96 0 638 793 ; C -1 ; WX 600 ; N indent ; B 108 68 574 348 ; C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 793 ; C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ; C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ; C -1 ; WX 600 ; N Aring ; B 3 0 607 753 ; C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; C -1 ; WX 600 ; N Igrave ; B 96 0 623 793 ; C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; C -1 ; WX 600 ; N Oacute ; B 94 -18 638 793 ; C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ; C -1 ; WX 600 ; N Yacute ; B 133 0 695 793 ; C -1 ; WX 600 ; N lira ; B 118 -21 621 611 ; C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 775 ; C -1 ; WX 600 ; N Atilde ; B 3 0 656 732 ; C -1 ; WX 600 ; N Uacute ; B 125 -18 702 793 ; C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 731 ; C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 595 ; C -1 ; WX 600 ; N idieresis ; B 95 0 540 595 ; C -1 ; WX 600 ; N Adieresis ; B 3 0 607 731 ; C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ; C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ; C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ; C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; C -1 ; WX 600 ; N Agrave ; B 3 0 607 793 ; C -1 ; WX 600 ; N return ; B 79 0 700 562 ; C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ; C -1 ; WX 600 ; N square ; B 19 0 700 562 ; C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; C -1 ; WX 600 ; N stop ; B 19 0 700 562 ; C -1 ; WX 600 ; N udieresis ; B 101 -15 572 595 ; C -1 ; WX 600 ; N arrowup ; B 209 0 577 623 ; C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ; C -1 ; WX 600 ; N Edieresis ; B 53 0 660 731 ; C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ; C -1 ; WX 600 ; N arrowboth ; B 36 115 692 483 ; C -1 ; WX 600 ; N gcaron ; B 61 -157 657 669 ; C -1 ; WX 600 ; N arrowleft ; B 40 115 693 483 ; C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ; C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ; C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 732 ; C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ; C -1 ; WX 600 ; N arrowright ; B 34 115 688 483 ; C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ; C -1 ; WX 600 ; N Egrave ; B 53 0 660 793 ; C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ; C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ; C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ; C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; EndCharMetrics StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 46 121 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 121 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -1 136 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave -4 121 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 12 126 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 27 126 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 121 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 121 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 29 136 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 121 ; CC Gcaron 2 ; PCC G 0 0 ; PCC caron 29 136 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 121 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 121 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 29 136 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 121 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 27 126 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 121 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 121 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 29 136 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 121 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 27 126 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 59 136 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 121 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 121 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 29 136 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 121 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 121 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 29 136 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 29 136 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ; CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ; EndComposites EndFontMetrics ������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/ZapfChancery-MediumItalic.afm�����������������������������������������0000644�0001750�0001750�00000040533�11462120062�022060� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Fri Dec 28 16:35:46 1990 Comment UniqueID 33936 Comment VMusage 34559 41451 FontName ZapfChancery-MediumItalic FullName ITC Zapf Chancery Medium Italic FamilyName ITC Zapf Chancery Weight Medium ItalicAngle -14 IsFixedPitch false FontBBox -181 -314 1065 831 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Chancery is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 708 XHeight 438 Ascender 714 Descender -314 StartCharMetrics 228 C 32 ; WX 220 ; N space ; B 0 0 0 0 ; C 33 ; WX 280 ; N exclam ; B 119 -14 353 610 ; C 34 ; WX 220 ; N quotedbl ; B 120 343 333 610 ; C 35 ; WX 440 ; N numbersign ; B 83 0 521 594 ; C 36 ; WX 440 ; N dollar ; B 60 -144 508 709 ; C 37 ; WX 680 ; N percent ; B 132 -160 710 700 ; C 38 ; WX 780 ; N ampersand ; B 126 -16 915 610 ; C 39 ; WX 240 ; N quoteright ; B 168 343 338 610 ; C 40 ; WX 260 ; N parenleft ; B 96 -216 411 664 ; C 41 ; WX 220 ; N parenright ; B -13 -216 302 664 ; C 42 ; WX 420 ; N asterisk ; B 139 263 479 610 ; C 43 ; WX 520 ; N plus ; B 117 0 543 426 ; C 44 ; WX 220 ; N comma ; B 25 -140 213 148 ; C 45 ; WX 280 ; N hyphen ; B 69 190 334 248 ; C 46 ; WX 220 ; N period ; B 102 -14 228 128 ; C 47 ; WX 340 ; N slash ; B 74 -16 458 610 ; C 48 ; WX 440 ; N zero ; B 79 -16 538 610 ; C 49 ; WX 440 ; N one ; B 41 0 428 610 ; C 50 ; WX 440 ; N two ; B 17 -16 485 610 ; C 51 ; WX 440 ; N three ; B 1 -16 485 610 ; C 52 ; WX 440 ; N four ; B 77 -35 499 610 ; C 53 ; WX 440 ; N five ; B 60 -16 595 679 ; C 54 ; WX 440 ; N six ; B 90 -16 556 610 ; C 55 ; WX 440 ; N seven ; B 157 -33 561 645 ; C 56 ; WX 440 ; N eight ; B 65 -16 529 610 ; C 57 ; WX 440 ; N nine ; B 32 -16 517 610 ; C 58 ; WX 260 ; N colon ; B 98 -14 296 438 ; C 59 ; WX 240 ; N semicolon ; B 29 -140 299 438 ; C 60 ; WX 520 ; N less ; B 139 0 527 468 ; C 61 ; WX 520 ; N equal ; B 117 86 543 340 ; C 62 ; WX 520 ; N greater ; B 139 0 527 468 ; C 63 ; WX 380 ; N question ; B 150 -14 455 610 ; C 64 ; WX 700 ; N at ; B 127 -16 753 610 ; C 65 ; WX 620 ; N A ; B 13 -16 697 632 ; C 66 ; WX 600 ; N B ; B 85 -6 674 640 ; C 67 ; WX 520 ; N C ; B 93 -16 631 610 ; C 68 ; WX 700 ; N D ; B 86 -6 768 640 ; C 69 ; WX 620 ; N E ; B 91 -12 709 618 ; C 70 ; WX 580 ; N F ; B 120 -118 793 629 ; C 71 ; WX 620 ; N G ; B 148 -242 709 610 ; C 72 ; WX 680 ; N H ; B 18 -16 878 708 ; C 73 ; WX 380 ; N I ; B 99 0 504 594 ; C 74 ; WX 400 ; N J ; B -14 -147 538 594 ; C 75 ; WX 660 ; N K ; B 53 -153 844 610 ; C 76 ; WX 580 ; N L ; B 53 -16 657 610 ; C 77 ; WX 840 ; N M ; B 58 -16 1020 722 ; C 78 ; WX 700 ; N N ; B 85 -168 915 708 ; C 79 ; WX 600 ; N O ; B 94 -16 660 610 ; C 80 ; WX 540 ; N P ; B 42 0 658 628 ; C 81 ; WX 600 ; N Q ; B 84 -177 775 610 ; C 82 ; WX 600 ; N R ; B 58 -168 805 640 ; C 83 ; WX 460 ; N S ; B 45 -81 558 610 ; C 84 ; WX 500 ; N T ; B 63 0 744 667 ; C 85 ; WX 740 ; N U ; B 126 -16 792 617 ; C 86 ; WX 640 ; N V ; B 124 -16 810 714 ; C 87 ; WX 880 ; N W ; B 94 -16 1046 723 ; C 88 ; WX 560 ; N X ; B -30 -16 699 610 ; C 89 ; WX 560 ; N Y ; B 41 -168 774 647 ; C 90 ; WX 620 ; N Z ; B 42 -19 669 624 ; C 91 ; WX 240 ; N bracketleft ; B -13 -207 405 655 ; C 92 ; WX 480 ; N backslash ; B 140 -16 524 610 ; C 93 ; WX 320 ; N bracketright ; B -27 -207 391 655 ; C 94 ; WX 520 ; N asciicircum ; B 132 239 532 594 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 240 ; N quoteleft ; B 169 343 339 610 ; C 97 ; WX 420 ; N a ; B 92 -15 485 438 ; C 98 ; WX 420 ; N b ; B 82 -23 492 714 ; C 99 ; WX 340 ; N c ; B 87 -14 406 438 ; C 100 ; WX 440 ; N d ; B 102 -14 651 714 ; C 101 ; WX 340 ; N e ; B 87 -14 403 438 ; C 102 ; WX 320 ; N f ; B -119 -314 547 714 ; L i fi ; L l fl ; C 103 ; WX 400 ; N g ; B -108 -314 503 438 ; C 104 ; WX 440 ; N h ; B 55 -14 524 714 ; C 105 ; WX 240 ; N i ; B 100 -14 341 635 ; C 106 ; WX 220 ; N j ; B -112 -314 332 635 ; C 107 ; WX 440 ; N k ; B 87 -184 628 714 ; C 108 ; WX 240 ; N l ; B 102 -14 480 714 ; C 109 ; WX 620 ; N m ; B 86 -14 704 438 ; C 110 ; WX 460 ; N n ; B 101 -14 544 438 ; C 111 ; WX 400 ; N o ; B 87 -14 449 438 ; C 112 ; WX 440 ; N p ; B -23 -314 484 432 ; C 113 ; WX 400 ; N q ; B 87 -300 490 510 ; C 114 ; WX 300 ; N r ; B 101 -14 424 438 ; C 115 ; WX 320 ; N s ; B 46 -14 403 438 ; C 116 ; WX 320 ; N t ; B 106 -14 426 539 ; C 117 ; WX 460 ; N u ; B 102 -14 528 438 ; C 118 ; WX 440 ; N v ; B 87 -14 533 488 ; C 119 ; WX 680 ; N w ; B 87 -14 782 488 ; C 120 ; WX 420 ; N x ; B 70 -195 589 438 ; C 121 ; WX 400 ; N y ; B -24 -314 483 438 ; C 122 ; WX 440 ; N z ; B 26 -14 508 445 ; C 123 ; WX 240 ; N braceleft ; B 55 -207 383 655 ; C 124 ; WX 520 ; N bar ; B 320 -16 378 714 ; C 125 ; WX 240 ; N braceright ; B -10 -207 318 655 ; C 126 ; WX 520 ; N asciitilde ; B 123 186 539 320 ; C 161 ; WX 280 ; N exclamdown ; B 72 -186 306 438 ; C 162 ; WX 440 ; N cent ; B 122 -134 476 543 ; C 163 ; WX 440 ; N sterling ; B -16 -52 506 610 ; C 164 ; WX 60 ; N fraction ; B -181 -16 320 610 ; C 165 ; WX 440 ; N yen ; B -1 -168 613 647 ; C 166 ; WX 440 ; N florin ; B -64 -314 582 610 ; C 167 ; WX 420 ; N section ; B 53 -215 514 610 ; C 168 ; WX 440 ; N currency ; B 50 85 474 509 ; C 169 ; WX 160 ; N quotesingle ; B 145 343 215 610 ; C 170 ; WX 340 ; N quotedblleft ; B 169 343 464 610 ; C 171 ; WX 340 ; N guillemotleft ; B 98 24 356 414 ; C 172 ; WX 240 ; N guilsinglleft ; B 98 24 258 414 ; C 173 ; WX 260 ; N guilsinglright ; B 106 24 266 414 ; C 174 ; WX 520 ; N fi ; B -124 -314 605 714 ; C 175 ; WX 520 ; N fl ; B -124 -314 670 714 ; C 177 ; WX 500 ; N endash ; B 51 199 565 239 ; C 178 ; WX 460 ; N dagger ; B 138 -37 568 610 ; C 179 ; WX 480 ; N daggerdbl ; B 138 -59 533 610 ; C 180 ; WX 220 ; N periodcentered ; B 139 208 241 310 ; C 182 ; WX 500 ; N paragraph ; B 105 -199 638 594 ; C 183 ; WX 600 ; N bullet ; B 228 149 524 445 ; C 184 ; WX 180 ; N quotesinglbase ; B 21 -121 191 146 ; C 185 ; WX 280 ; N quotedblbase ; B -14 -121 281 146 ; C 186 ; WX 360 ; N quotedblright ; B 158 343 453 610 ; C 187 ; WX 380 ; N guillemotright ; B 117 24 375 414 ; C 188 ; WX 1000 ; N ellipsis ; B 124 -14 916 128 ; C 189 ; WX 960 ; N perthousand ; B 112 -160 1005 700 ; C 191 ; WX 400 ; N questiondown ; B 82 -186 387 438 ; C 193 ; WX 220 ; N grave ; B 193 492 339 659 ; C 194 ; WX 300 ; N acute ; B 265 492 422 659 ; C 195 ; WX 340 ; N circumflex ; B 223 482 443 649 ; C 196 ; WX 440 ; N tilde ; B 243 543 522 619 ; C 197 ; WX 440 ; N macron ; B 222 544 465 578 ; C 198 ; WX 440 ; N breve ; B 253 522 501 631 ; C 199 ; WX 220 ; N dotaccent ; B 236 522 328 610 ; C 200 ; WX 360 ; N dieresis ; B 243 522 469 610 ; C 202 ; WX 300 ; N ring ; B 240 483 416 659 ; C 203 ; WX 300 ; N cedilla ; B 12 -191 184 6 ; C 205 ; WX 400 ; N hungarumlaut ; B 208 492 495 659 ; C 206 ; WX 280 ; N ogonek ; B 38 -191 233 6 ; C 207 ; WX 340 ; N caron ; B 254 492 474 659 ; C 208 ; WX 1000 ; N emdash ; B 51 199 1065 239 ; C 225 ; WX 740 ; N AE ; B -21 -16 799 594 ; C 227 ; WX 260 ; N ordfeminine ; B 111 338 386 610 ; C 232 ; WX 580 ; N Lslash ; B 49 -16 657 610 ; C 233 ; WX 660 ; N Oslash ; B 83 -78 751 672 ; C 234 ; WX 820 ; N OE ; B 63 -16 909 610 ; C 235 ; WX 260 ; N ordmasculine ; B 128 339 373 610 ; C 241 ; WX 540 ; N ae ; B 67 -14 624 468 ; C 245 ; WX 240 ; N dotlessi ; B 100 -14 306 438 ; C 248 ; WX 300 ; N lslash ; B 121 -14 515 714 ; C 249 ; WX 440 ; N oslash ; B 46 -64 540 488 ; C 250 ; WX 560 ; N oe ; B 78 -14 628 438 ; C 251 ; WX 420 ; N germandbls ; B -127 -314 542 714 ; C -1 ; WX 340 ; N ecircumflex ; B 87 -14 433 649 ; C -1 ; WX 340 ; N edieresis ; B 87 -14 449 610 ; C -1 ; WX 420 ; N aacute ; B 92 -15 492 659 ; C -1 ; WX 740 ; N registered ; B 137 -16 763 610 ; C -1 ; WX 240 ; N icircumflex ; B 100 -14 363 649 ; C -1 ; WX 460 ; N udieresis ; B 102 -14 528 610 ; C -1 ; WX 400 ; N ograve ; B 87 -14 449 659 ; C -1 ; WX 460 ; N uacute ; B 102 -14 528 659 ; C -1 ; WX 460 ; N ucircumflex ; B 102 -14 528 649 ; C -1 ; WX 620 ; N Aacute ; B 13 -16 702 821 ; C -1 ; WX 240 ; N igrave ; B 100 -14 306 659 ; C -1 ; WX 380 ; N Icircumflex ; B 99 0 504 821 ; C -1 ; WX 340 ; N ccedilla ; B 62 -191 406 438 ; C -1 ; WX 420 ; N adieresis ; B 92 -15 485 610 ; C -1 ; WX 620 ; N Ecircumflex ; B 91 -12 709 821 ; C -1 ; WX 320 ; N scaron ; B 46 -14 464 659 ; C -1 ; WX 440 ; N thorn ; B -38 -314 505 714 ; C -1 ; WX 1000 ; N trademark ; B 127 187 1046 594 ; C -1 ; WX 340 ; N egrave ; B 87 -14 403 659 ; C -1 ; WX 264 ; N threesuperior ; B 59 234 348 610 ; C -1 ; WX 440 ; N zcaron ; B 26 -14 514 659 ; C -1 ; WX 420 ; N atilde ; B 92 -15 522 619 ; C -1 ; WX 420 ; N aring ; B 92 -15 485 659 ; C -1 ; WX 400 ; N ocircumflex ; B 87 -14 453 649 ; C -1 ; WX 620 ; N Edieresis ; B 91 -12 709 762 ; C -1 ; WX 660 ; N threequarters ; B 39 -16 706 610 ; C -1 ; WX 400 ; N ydieresis ; B -24 -314 483 610 ; C -1 ; WX 400 ; N yacute ; B -24 -314 483 659 ; C -1 ; WX 240 ; N iacute ; B 100 -14 392 659 ; C -1 ; WX 620 ; N Acircumflex ; B 13 -16 697 821 ; C -1 ; WX 740 ; N Uacute ; B 126 -16 792 821 ; C -1 ; WX 340 ; N eacute ; B 87 -14 462 659 ; C -1 ; WX 600 ; N Ograve ; B 94 -16 660 821 ; C -1 ; WX 420 ; N agrave ; B 92 -15 485 659 ; C -1 ; WX 740 ; N Udieresis ; B 126 -16 792 762 ; C -1 ; WX 420 ; N acircumflex ; B 92 -15 485 649 ; C -1 ; WX 380 ; N Igrave ; B 99 0 504 821 ; C -1 ; WX 264 ; N twosuperior ; B 72 234 354 610 ; C -1 ; WX 740 ; N Ugrave ; B 126 -16 792 821 ; C -1 ; WX 660 ; N onequarter ; B 56 -16 702 610 ; C -1 ; WX 740 ; N Ucircumflex ; B 126 -16 792 821 ; C -1 ; WX 460 ; N Scaron ; B 45 -81 594 831 ; C -1 ; WX 380 ; N Idieresis ; B 99 0 519 762 ; C -1 ; WX 240 ; N idieresis ; B 100 -14 369 610 ; C -1 ; WX 620 ; N Egrave ; B 91 -12 709 821 ; C -1 ; WX 600 ; N Oacute ; B 94 -16 660 821 ; C -1 ; WX 520 ; N divide ; B 117 -14 543 440 ; C -1 ; WX 620 ; N Atilde ; B 13 -16 702 771 ; C -1 ; WX 620 ; N Aring ; B 13 -16 697 831 ; C -1 ; WX 600 ; N Odieresis ; B 94 -16 660 762 ; C -1 ; WX 620 ; N Adieresis ; B 13 -16 709 762 ; C -1 ; WX 700 ; N Ntilde ; B 85 -168 915 761 ; C -1 ; WX 620 ; N Zcaron ; B 42 -19 669 831 ; C -1 ; WX 540 ; N Thorn ; B 52 0 647 623 ; C -1 ; WX 380 ; N Iacute ; B 99 0 532 821 ; C -1 ; WX 520 ; N plusminus ; B 117 0 543 436 ; C -1 ; WX 520 ; N multiply ; B 133 16 527 410 ; C -1 ; WX 620 ; N Eacute ; B 91 -12 709 821 ; C -1 ; WX 560 ; N Ydieresis ; B 41 -168 774 762 ; C -1 ; WX 264 ; N onesuperior ; B 83 244 311 610 ; C -1 ; WX 460 ; N ugrave ; B 102 -14 528 659 ; C -1 ; WX 520 ; N logicalnot ; B 117 86 543 340 ; C -1 ; WX 460 ; N ntilde ; B 101 -14 544 619 ; C -1 ; WX 600 ; N Otilde ; B 94 -16 660 761 ; C -1 ; WX 400 ; N otilde ; B 87 -14 502 619 ; C -1 ; WX 520 ; N Ccedilla ; B 93 -191 631 610 ; C -1 ; WX 620 ; N Agrave ; B 13 -16 697 821 ; C -1 ; WX 660 ; N onehalf ; B 56 -16 702 610 ; C -1 ; WX 700 ; N Eth ; B 86 -6 768 640 ; C -1 ; WX 400 ; N degree ; B 171 324 457 610 ; C -1 ; WX 560 ; N Yacute ; B 41 -168 774 821 ; C -1 ; WX 600 ; N Ocircumflex ; B 94 -16 660 821 ; C -1 ; WX 400 ; N oacute ; B 87 -14 482 659 ; C -1 ; WX 460 ; N mu ; B 7 -314 523 438 ; C -1 ; WX 520 ; N minus ; B 117 184 543 242 ; C -1 ; WX 400 ; N eth ; B 87 -14 522 714 ; C -1 ; WX 400 ; N odieresis ; B 87 -14 479 610 ; C -1 ; WX 740 ; N copyright ; B 137 -16 763 610 ; C -1 ; WX 520 ; N brokenbar ; B 320 -16 378 714 ; EndCharMetrics StartKernData StartKernPairs 131 KPX A quoteright -40 KPX A quotedblright -40 KPX A U -10 KPX A T 10 KPX A Q 10 KPX A O 10 KPX A G -30 KPX A C 20 KPX D period -30 KPX D comma -20 KPX D Y 10 KPX D A -10 KPX F period -40 KPX F i 10 KPX F comma -30 KPX G period -20 KPX G comma -10 KPX J period -20 KPX J comma -10 KPX K u -20 KPX K o -20 KPX K e -20 KPX L y -10 KPX L quoteright -25 KPX L quotedblright -25 KPX L W -10 KPX L V -20 KPX O period -20 KPX O comma -10 KPX O Y 10 KPX O T 20 KPX O A -20 KPX P period -50 KPX P o -10 KPX P e -10 KPX P comma -40 KPX P a -20 KPX P A -10 KPX Q U -10 KPX R Y 10 KPX R W 10 KPX R T 20 KPX T o -20 KPX T i 20 KPX T hyphen -20 KPX T h 20 KPX T e -20 KPX T a -20 KPX T O 30 KPX T A 10 KPX V period -100 KPX V o -20 KPX V e -20 KPX V comma -90 KPX V a -20 KPX V O 10 KPX V G -20 KPX W period -50 KPX W o -20 KPX W i 10 KPX W h 10 KPX W e -20 KPX W comma -40 KPX W a -20 KPX W O 10 KPX Y u -20 KPX Y period -50 KPX Y o -50 KPX Y i 10 KPX Y e -40 KPX Y comma -40 KPX Y a -60 KPX b period -30 KPX b l -20 KPX b comma -20 KPX b b -20 KPX c k -10 KPX comma quoteright -70 KPX comma quotedblright -70 KPX d w -20 KPX d v -10 KPX d d -40 KPX e y 10 KPX f quoteright 30 KPX f quotedblright 30 KPX f period -50 KPX f f -50 KPX f e -10 KPX f comma -40 KPX f a -20 KPX g y 10 KPX g period -30 KPX g i 10 KPX g e 10 KPX g comma -20 KPX g a 10 KPX k y 10 KPX k o -10 KPX k e -20 KPX m y 10 KPX m u 10 KPX n y 20 KPX o period -30 KPX o comma -20 KPX p period -30 KPX p p -10 KPX p comma -20 KPX period quoteright -80 KPX period quotedblright -80 KPX quotedblleft quoteleft 20 KPX quotedblleft A 10 KPX quoteleft quoteleft -115 KPX quoteleft A 10 KPX quoteright v 30 KPX quoteright t 20 KPX quoteright s -25 KPX quoteright r 30 KPX quoteright quoteright -115 KPX quoteright quotedblright 20 KPX quoteright l 20 KPX r period -50 KPX r i 10 KPX r comma -40 KPX s period -20 KPX s comma -10 KPX v period -30 KPX v comma -20 KPX w period -30 KPX w o 10 KPX w h 20 KPX w comma -20 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 280 162 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 240 172 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 240 152 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 250 162 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 260 172 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 180 152 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 230 162 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 180 172 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 170 152 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 220 162 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 110 162 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 60 172 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 50 152 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 100 162 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 142 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 160 162 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 130 172 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 120 152 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 150 162 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 90 142 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 172 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 310 162 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 260 172 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 260 152 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 270 162 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 220 162 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 170 152 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 130 172 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 70 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 20 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 10 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 80 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 60 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 40 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex -10 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis -20 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 30 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -30 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -80 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -100 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -40 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 10 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 60 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 10 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 10 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 60 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde -20 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron -10 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 70 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 20 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 50 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 60 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/NewCenturySchlbk-Bold.afm���������������������������������������������0000644�0001750�0001750�00000040165�11462120062�021250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue May 28 16:48:12 1991 Comment UniqueID 35031 Comment VMusage 30773 37665 FontName NewCenturySchlbk-Bold FullName New Century Schoolbook Bold FamilyName New Century Schoolbook Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -165 -250 1000 988 UnderlinePosition -100 UnderlineThickness 50 Version 001.009 Notice Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 722 XHeight 475 Ascender 737 Descender -205 StartCharMetrics 228 C 32 ; WX 287 ; N space ; B 0 0 0 0 ; C 33 ; WX 296 ; N exclam ; B 53 -15 243 737 ; C 34 ; WX 333 ; N quotedbl ; B 0 378 333 737 ; C 35 ; WX 574 ; N numbersign ; B 36 0 538 690 ; C 36 ; WX 574 ; N dollar ; B 25 -141 549 810 ; C 37 ; WX 833 ; N percent ; B 14 -15 819 705 ; C 38 ; WX 852 ; N ampersand ; B 34 -15 818 737 ; C 39 ; WX 241 ; N quoteright ; B 22 378 220 737 ; C 40 ; WX 389 ; N parenleft ; B 77 -117 345 745 ; C 41 ; WX 389 ; N parenright ; B 44 -117 312 745 ; C 42 ; WX 500 ; N asterisk ; B 54 302 446 737 ; C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; C 44 ; WX 278 ; N comma ; B 40 -184 238 175 ; C 45 ; WX 333 ; N hyphen ; B 42 174 291 302 ; C 46 ; WX 278 ; N period ; B 44 -15 234 175 ; C 47 ; WX 278 ; N slash ; B -42 -15 320 737 ; C 48 ; WX 574 ; N zero ; B 27 -15 547 705 ; C 49 ; WX 574 ; N one ; B 83 0 491 705 ; C 50 ; WX 574 ; N two ; B 19 0 531 705 ; C 51 ; WX 574 ; N three ; B 23 -15 531 705 ; C 52 ; WX 574 ; N four ; B 19 0 547 705 ; C 53 ; WX 574 ; N five ; B 32 -15 534 705 ; C 54 ; WX 574 ; N six ; B 27 -15 547 705 ; C 55 ; WX 574 ; N seven ; B 45 -15 547 705 ; C 56 ; WX 574 ; N eight ; B 27 -15 548 705 ; C 57 ; WX 574 ; N nine ; B 27 -15 547 705 ; C 58 ; WX 278 ; N colon ; B 44 -15 234 485 ; C 59 ; WX 278 ; N semicolon ; B 40 -184 238 485 ; C 60 ; WX 606 ; N less ; B 50 -9 556 515 ; C 61 ; WX 606 ; N equal ; B 50 103 556 403 ; C 62 ; WX 606 ; N greater ; B 50 -9 556 515 ; C 63 ; WX 500 ; N question ; B 23 -15 477 737 ; C 64 ; WX 747 ; N at ; B -2 -15 750 737 ; C 65 ; WX 759 ; N A ; B -19 0 778 737 ; C 66 ; WX 778 ; N B ; B 19 0 739 722 ; C 67 ; WX 778 ; N C ; B 39 -15 723 737 ; C 68 ; WX 833 ; N D ; B 19 0 794 722 ; C 69 ; WX 759 ; N E ; B 19 0 708 722 ; C 70 ; WX 722 ; N F ; B 19 0 697 722 ; C 71 ; WX 833 ; N G ; B 39 -15 818 737 ; C 72 ; WX 870 ; N H ; B 19 0 851 722 ; C 73 ; WX 444 ; N I ; B 29 0 415 722 ; C 74 ; WX 648 ; N J ; B 6 -15 642 722 ; C 75 ; WX 815 ; N K ; B 19 0 822 722 ; C 76 ; WX 722 ; N L ; B 19 0 703 722 ; C 77 ; WX 981 ; N M ; B 10 0 971 722 ; C 78 ; WX 833 ; N N ; B 5 -10 828 722 ; C 79 ; WX 833 ; N O ; B 39 -15 794 737 ; C 80 ; WX 759 ; N P ; B 24 0 735 722 ; C 81 ; WX 833 ; N Q ; B 39 -189 808 737 ; C 82 ; WX 815 ; N R ; B 19 -15 815 722 ; C 83 ; WX 667 ; N S ; B 51 -15 634 737 ; C 84 ; WX 722 ; N T ; B 16 0 706 722 ; C 85 ; WX 833 ; N U ; B 14 -15 825 722 ; C 86 ; WX 759 ; N V ; B -19 -10 778 722 ; C 87 ; WX 981 ; N W ; B 7 -10 974 722 ; C 88 ; WX 722 ; N X ; B -12 0 734 722 ; C 89 ; WX 722 ; N Y ; B -12 0 734 722 ; C 90 ; WX 667 ; N Z ; B 28 0 639 722 ; C 91 ; WX 389 ; N bracketleft ; B 84 -109 339 737 ; C 92 ; WX 606 ; N backslash ; B 122 -15 484 737 ; C 93 ; WX 389 ; N bracketright ; B 50 -109 305 737 ; C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 241 ; N quoteleft ; B 22 378 220 737 ; C 97 ; WX 611 ; N a ; B 40 -15 601 485 ; C 98 ; WX 648 ; N b ; B 4 -15 616 737 ; C 99 ; WX 556 ; N c ; B 32 -15 524 485 ; C 100 ; WX 667 ; N d ; B 32 -15 644 737 ; C 101 ; WX 574 ; N e ; B 32 -15 542 485 ; C 102 ; WX 389 ; N f ; B 11 0 461 737 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B 30 -205 623 535 ; C 104 ; WX 685 ; N h ; B 17 0 662 737 ; C 105 ; WX 370 ; N i ; B 26 0 338 737 ; C 106 ; WX 352 ; N j ; B -86 -205 271 737 ; C 107 ; WX 667 ; N k ; B 17 0 662 737 ; C 108 ; WX 352 ; N l ; B 17 0 329 737 ; C 109 ; WX 963 ; N m ; B 17 0 940 485 ; C 110 ; WX 685 ; N n ; B 17 0 662 485 ; C 111 ; WX 611 ; N o ; B 32 -15 579 485 ; C 112 ; WX 667 ; N p ; B 17 -205 629 485 ; C 113 ; WX 648 ; N q ; B 32 -205 638 485 ; C 114 ; WX 519 ; N r ; B 17 0 516 485 ; C 115 ; WX 500 ; N s ; B 48 -15 476 485 ; C 116 ; WX 426 ; N t ; B 21 -15 405 675 ; C 117 ; WX 685 ; N u ; B 17 -15 668 475 ; C 118 ; WX 611 ; N v ; B 12 -10 599 475 ; C 119 ; WX 889 ; N w ; B 16 -10 873 475 ; C 120 ; WX 611 ; N x ; B 12 0 599 475 ; C 121 ; WX 611 ; N y ; B 12 -205 599 475 ; C 122 ; WX 537 ; N z ; B 38 0 499 475 ; C 123 ; WX 389 ; N braceleft ; B 36 -109 313 737 ; C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ; C 125 ; WX 389 ; N braceright ; B 76 -109 353 737 ; C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ; C 161 ; WX 296 ; N exclamdown ; B 53 -205 243 547 ; C 162 ; WX 574 ; N cent ; B 32 -102 528 572 ; C 163 ; WX 574 ; N sterling ; B 16 -15 558 705 ; C 164 ; WX 167 ; N fraction ; B -165 -15 332 705 ; C 165 ; WX 574 ; N yen ; B -10 0 584 690 ; C 166 ; WX 574 ; N florin ; B 14 -205 548 737 ; C 167 ; WX 500 ; N section ; B 62 -86 438 737 ; C 168 ; WX 574 ; N currency ; B 27 84 547 605 ; C 169 ; WX 241 ; N quotesingle ; B 53 378 189 737 ; C 170 ; WX 481 ; N quotedblleft ; B 22 378 459 737 ; C 171 ; WX 500 ; N guillemotleft ; B 46 79 454 397 ; C 172 ; WX 333 ; N guilsinglleft ; B 62 79 271 397 ; C 173 ; WX 333 ; N guilsinglright ; B 62 79 271 397 ; C 174 ; WX 685 ; N fi ; B 11 0 666 737 ; C 175 ; WX 685 ; N fl ; B 11 0 666 737 ; C 177 ; WX 500 ; N endash ; B 0 184 500 292 ; C 178 ; WX 500 ; N dagger ; B 39 -101 461 737 ; C 179 ; WX 500 ; N daggerdbl ; B 39 -89 461 737 ; C 180 ; WX 278 ; N periodcentered ; B 53 200 225 372 ; C 182 ; WX 747 ; N paragraph ; B 96 -71 631 722 ; C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; C 184 ; WX 241 ; N quotesinglbase ; B 22 -184 220 175 ; C 185 ; WX 481 ; N quotedblbase ; B 22 -184 459 175 ; C 186 ; WX 481 ; N quotedblright ; B 22 378 459 737 ; C 187 ; WX 500 ; N guillemotright ; B 46 79 454 397 ; C 188 ; WX 1000 ; N ellipsis ; B 72 -15 928 175 ; C 189 ; WX 1000 ; N perthousand ; B 7 -15 993 705 ; C 191 ; WX 500 ; N questiondown ; B 23 -205 477 547 ; C 193 ; WX 333 ; N grave ; B 2 547 249 737 ; C 194 ; WX 333 ; N acute ; B 84 547 331 737 ; C 195 ; WX 333 ; N circumflex ; B -10 547 344 725 ; C 196 ; WX 333 ; N tilde ; B -24 563 357 705 ; C 197 ; WX 333 ; N macron ; B -6 582 339 664 ; C 198 ; WX 333 ; N breve ; B 9 547 324 714 ; C 199 ; WX 333 ; N dotaccent ; B 95 552 237 694 ; C 200 ; WX 333 ; N dieresis ; B -12 552 345 694 ; C 202 ; WX 333 ; N ring ; B 58 545 274 761 ; C 203 ; WX 333 ; N cedilla ; B 17 -224 248 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -16 547 431 737 ; C 206 ; WX 333 ; N ogonek ; B 168 -163 346 3 ; C 207 ; WX 333 ; N caron ; B -10 547 344 725 ; C 208 ; WX 1000 ; N emdash ; B 0 184 1000 292 ; C 225 ; WX 981 ; N AE ; B -29 0 963 722 ; C 227 ; WX 367 ; N ordfeminine ; B 1 407 393 705 ; C 232 ; WX 722 ; N Lslash ; B 19 0 703 722 ; C 233 ; WX 833 ; N Oslash ; B 39 -53 794 775 ; C 234 ; WX 1000 ; N OE ; B 0 0 982 722 ; C 235 ; WX 367 ; N ordmasculine ; B 1 407 366 705 ; C 241 ; WX 870 ; N ae ; B 32 -15 838 485 ; C 245 ; WX 370 ; N dotlessi ; B 26 0 338 475 ; C 248 ; WX 352 ; N lslash ; B 17 0 329 737 ; C 249 ; WX 611 ; N oslash ; B 32 -103 579 573 ; C 250 ; WX 907 ; N oe ; B 32 -15 875 485 ; C 251 ; WX 611 ; N germandbls ; B -2 -15 580 737 ; C -1 ; WX 574 ; N ecircumflex ; B 32 -15 542 725 ; C -1 ; WX 574 ; N edieresis ; B 32 -15 542 694 ; C -1 ; WX 611 ; N aacute ; B 40 -15 601 737 ; C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; C -1 ; WX 370 ; N icircumflex ; B 9 0 363 725 ; C -1 ; WX 685 ; N udieresis ; B 17 -15 668 694 ; C -1 ; WX 611 ; N ograve ; B 32 -15 579 737 ; C -1 ; WX 685 ; N uacute ; B 17 -15 668 737 ; C -1 ; WX 685 ; N ucircumflex ; B 17 -15 668 725 ; C -1 ; WX 759 ; N Aacute ; B -19 0 778 964 ; C -1 ; WX 370 ; N igrave ; B 21 0 338 737 ; C -1 ; WX 444 ; N Icircumflex ; B 29 0 415 952 ; C -1 ; WX 556 ; N ccedilla ; B 32 -224 524 485 ; C -1 ; WX 611 ; N adieresis ; B 40 -15 601 694 ; C -1 ; WX 759 ; N Ecircumflex ; B 19 0 708 952 ; C -1 ; WX 500 ; N scaron ; B 48 -15 476 725 ; C -1 ; WX 667 ; N thorn ; B 17 -205 629 737 ; C -1 ; WX 1000 ; N trademark ; B 6 317 982 722 ; C -1 ; WX 574 ; N egrave ; B 32 -15 542 737 ; C -1 ; WX 344 ; N threesuperior ; B -3 273 355 705 ; C -1 ; WX 537 ; N zcaron ; B 38 0 499 725 ; C -1 ; WX 611 ; N atilde ; B 40 -15 601 705 ; C -1 ; WX 611 ; N aring ; B 40 -15 601 761 ; C -1 ; WX 611 ; N ocircumflex ; B 32 -15 579 725 ; C -1 ; WX 759 ; N Edieresis ; B 19 0 708 921 ; C -1 ; WX 861 ; N threequarters ; B 15 -15 838 705 ; C -1 ; WX 611 ; N ydieresis ; B 12 -205 599 694 ; C -1 ; WX 611 ; N yacute ; B 12 -205 599 737 ; C -1 ; WX 370 ; N iacute ; B 26 0 350 737 ; C -1 ; WX 759 ; N Acircumflex ; B -19 0 778 952 ; C -1 ; WX 833 ; N Uacute ; B 14 -15 825 964 ; C -1 ; WX 574 ; N eacute ; B 32 -15 542 737 ; C -1 ; WX 833 ; N Ograve ; B 39 -15 794 964 ; C -1 ; WX 611 ; N agrave ; B 40 -15 601 737 ; C -1 ; WX 833 ; N Udieresis ; B 14 -15 825 921 ; C -1 ; WX 611 ; N acircumflex ; B 40 -15 601 725 ; C -1 ; WX 444 ; N Igrave ; B 29 0 415 964 ; C -1 ; WX 344 ; N twosuperior ; B -3 282 350 705 ; C -1 ; WX 833 ; N Ugrave ; B 14 -15 825 964 ; C -1 ; WX 861 ; N onequarter ; B 31 -15 838 705 ; C -1 ; WX 833 ; N Ucircumflex ; B 14 -15 825 952 ; C -1 ; WX 667 ; N Scaron ; B 51 -15 634 952 ; C -1 ; WX 444 ; N Idieresis ; B 29 0 415 921 ; C -1 ; WX 370 ; N idieresis ; B 7 0 364 694 ; C -1 ; WX 759 ; N Egrave ; B 19 0 708 964 ; C -1 ; WX 833 ; N Oacute ; B 39 -15 794 964 ; C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ; C -1 ; WX 759 ; N Atilde ; B -19 0 778 932 ; C -1 ; WX 759 ; N Aring ; B -19 0 778 988 ; C -1 ; WX 833 ; N Odieresis ; B 39 -15 794 921 ; C -1 ; WX 759 ; N Adieresis ; B -19 0 778 921 ; C -1 ; WX 833 ; N Ntilde ; B 5 -10 828 932 ; C -1 ; WX 667 ; N Zcaron ; B 28 0 639 952 ; C -1 ; WX 759 ; N Thorn ; B 24 0 735 722 ; C -1 ; WX 444 ; N Iacute ; B 29 0 415 964 ; C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ; C -1 ; WX 759 ; N Eacute ; B 19 0 708 964 ; C -1 ; WX 722 ; N Ydieresis ; B -12 0 734 921 ; C -1 ; WX 344 ; N onesuperior ; B 31 282 309 705 ; C -1 ; WX 685 ; N ugrave ; B 17 -15 668 737 ; C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ; C -1 ; WX 685 ; N ntilde ; B 17 0 662 705 ; C -1 ; WX 833 ; N Otilde ; B 39 -15 794 932 ; C -1 ; WX 611 ; N otilde ; B 32 -15 579 705 ; C -1 ; WX 778 ; N Ccedilla ; B 39 -224 723 737 ; C -1 ; WX 759 ; N Agrave ; B -19 0 778 964 ; C -1 ; WX 861 ; N onehalf ; B 31 -15 838 705 ; C -1 ; WX 833 ; N Eth ; B 19 0 794 722 ; C -1 ; WX 400 ; N degree ; B 57 419 343 705 ; C -1 ; WX 722 ; N Yacute ; B -12 0 734 964 ; C -1 ; WX 833 ; N Ocircumflex ; B 39 -15 794 952 ; C -1 ; WX 611 ; N oacute ; B 32 -15 579 737 ; C -1 ; WX 685 ; N mu ; B 17 -205 668 475 ; C -1 ; WX 606 ; N minus ; B 50 199 556 307 ; C -1 ; WX 611 ; N eth ; B 32 -15 579 737 ; C -1 ; WX 611 ; N odieresis ; B 32 -15 579 694 ; C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ; EndCharMetrics StartKernData StartKernPairs 128 KPX A y -18 KPX A w -18 KPX A v -18 KPX A quoteright -74 KPX A quotedblright -74 KPX A Y -91 KPX A W -74 KPX A V -74 KPX A U -18 KPX A T -55 KPX C period -18 KPX C comma -18 KPX D period -25 KPX D comma -25 KPX F r -18 KPX F period -125 KPX F o -55 KPX F i -18 KPX F e -55 KPX F comma -125 KPX F a -74 KPX J u -18 KPX J period -55 KPX J o -18 KPX J e -18 KPX J comma -55 KPX J a -18 KPX J A -18 KPX K y -25 KPX K u -18 KPX L y -25 KPX L quoteright -100 KPX L quotedblright -100 KPX L Y -74 KPX L W -74 KPX L V -100 KPX L T -100 KPX N period -18 KPX N comma -18 KPX O period -25 KPX O comma -25 KPX O T 10 KPX P period -150 KPX P o -55 KPX P e -55 KPX P comma -150 KPX P a -55 KPX P A -74 KPX S period -18 KPX S comma -18 KPX T u -18 KPX T r -18 KPX T period -100 KPX T o -74 KPX T i -18 KPX T hyphen -125 KPX T e -74 KPX T comma -100 KPX T a -74 KPX T O 10 KPX T A -55 KPX U period -25 KPX U comma -25 KPX U A -18 KPX V u -55 KPX V semicolon -37 KPX V period -125 KPX V o -74 KPX V i -18 KPX V hyphen -100 KPX V e -74 KPX V comma -125 KPX V colon -37 KPX V a -74 KPX V A -74 KPX W y -25 KPX W u -37 KPX W semicolon -55 KPX W period -100 KPX W o -74 KPX W i -18 KPX W hyphen -100 KPX W e -74 KPX W comma -100 KPX W colon -55 KPX W a -74 KPX W A -74 KPX Y u -55 KPX Y semicolon -25 KPX Y period -100 KPX Y o -100 KPX Y i -18 KPX Y hyphen -125 KPX Y e -100 KPX Y comma -100 KPX Y colon -25 KPX Y a -100 KPX Y A -91 KPX colon space -18 KPX comma space -18 KPX comma quoteright -18 KPX comma quotedblright -18 KPX f quoteright 75 KPX f quotedblright 75 KPX period space -18 KPX period quoteright -18 KPX period quotedblright -18 KPX quotedblleft A -74 KPX quotedblright space -18 KPX quoteleft A -74 KPX quoteright s -25 KPX quoteright d -25 KPX r period -74 KPX r comma -74 KPX semicolon space -18 KPX space quoteleft -18 KPX space quotedblleft -18 KPX space Y -18 KPX space W -18 KPX space V -18 KPX space T -18 KPX space A -18 KPX v period -100 KPX v comma -100 KPX w period -100 KPX w comma -100 KPX y period -100 KPX y comma -100 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 227 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 213 227 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 213 227 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 213 227 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 213 227 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 213 227 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 213 227 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 213 227 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 213 227 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 213 227 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 56 227 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 56 227 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 56 227 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 56 227 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 227 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 227 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 227 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 227 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 227 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 227 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 227 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 227 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 250 227 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 250 227 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 250 227 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 227 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 227 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 227 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 139 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 139 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 139 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 139 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 139 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 139 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 121 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 121 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 121 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 121 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 19 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 19 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 19 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 19 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 139 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 139 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 102 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Symbol.afm������������������������������������������������������������0000644�0001750�0001750�00000023176�11462120062�016410� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Wed Jan 17 21:48:26 1990 Comment UniqueID 27004 Comment VMusage 28489 37622 FontName Symbol FullName Symbol FamilyName Symbol Weight Medium ItalicAngle 0 IsFixedPitch false FontBBox -180 -293 1090 1010 UnderlinePosition -98 UnderlineThickness 54 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. EncodingScheme FontSpecific StartCharMetrics 189 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ; C 34 ; WX 713 ; N universal ; B 31 0 681 705 ; C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ; C 36 ; WX 549 ; N existential ; B 25 0 478 707 ; C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ; C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ; C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ; C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ; C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ; C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ; C 43 ; WX 549 ; N plus ; B 10 0 539 533 ; C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ; C 45 ; WX 549 ; N minus ; B 11 233 535 288 ; C 46 ; WX 250 ; N period ; B 69 -17 181 95 ; C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ; C 48 ; WX 500 ; N zero ; B 23 -17 471 685 ; C 49 ; WX 500 ; N one ; B 117 0 390 673 ; C 50 ; WX 500 ; N two ; B 25 0 475 686 ; C 51 ; WX 500 ; N three ; B 39 -17 435 685 ; C 52 ; WX 500 ; N four ; B 16 0 469 685 ; C 53 ; WX 500 ; N five ; B 29 -17 443 685 ; C 54 ; WX 500 ; N six ; B 36 -17 467 685 ; C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ; C 56 ; WX 500 ; N eight ; B 54 -18 440 685 ; C 57 ; WX 500 ; N nine ; B 31 -18 460 685 ; C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ; C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ; C 60 ; WX 549 ; N less ; B 26 0 523 522 ; C 61 ; WX 549 ; N equal ; B 11 141 537 390 ; C 62 ; WX 549 ; N greater ; B 26 0 523 522 ; C 63 ; WX 444 ; N question ; B 70 -17 412 686 ; C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ; C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ; C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ; C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ; C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ; C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ; C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ; C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ; C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ; C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ; C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ; C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ; C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ; C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ; C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ; C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ; C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ; C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ; C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ; C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ; C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ; C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ; C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ; C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ; C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ; C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ; C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ; C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ; C 92 ; WX 863 ; N therefore ; B 163 0 701 478 ; C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ; C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ; C 95 ; WX 500 ; N underscore ; B -2 -252 502 -206 ; C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ; C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ; C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ; C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ; C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ; C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ; C 102 ; WX 521 ; N phi ; B 27 -224 490 671 ; C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ; C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ; C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ; C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ; C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ; C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ; C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ; C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ; C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ; C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ; C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ; C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ; C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ; C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ; C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ; C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ; C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ; C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ; C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ; C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ; C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ; C 124 ; WX 200 ; N bar ; B 65 -177 135 673 ; C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ; C 126 ; WX 549 ; N similar ; B 17 203 529 307 ; C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ; C 162 ; WX 247 ; N minute ; B 27 459 228 735 ; C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ; C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ; C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ; C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ; C 167 ; WX 753 ; N club ; B 86 -26 660 533 ; C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ; C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ; C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ; C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ; C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ; C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ; C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ; C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ; C 176 ; WX 400 ; N degree ; B 50 385 350 685 ; C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ; C 178 ; WX 411 ; N second ; B 20 459 413 737 ; C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ; C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ; C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ; C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ; C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ; C 184 ; WX 549 ; N divide ; B 10 71 536 456 ; C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ; C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ; C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ; C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ; C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ; C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ; C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ; C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ; C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ; C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ; C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ; C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ; C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ; C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ; C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ; C 200 ; WX 768 ; N union ; B 40 -17 732 492 ; C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ; C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ; C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ; C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ; C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ; C 206 ; WX 713 ; N element ; B 45 0 505 468 ; C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ; C 208 ; WX 768 ; N angle ; B 26 0 738 673 ; C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ; C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ; C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ; C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ; C 213 ; WX 823 ; N product ; B 25 -101 803 751 ; C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ; C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ; C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ; C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ; C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ; C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ; C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ; C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ; C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ; C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ; C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ; C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ; C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ; C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ; C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ; C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ; C 230 ; WX 384 ; N parenlefttp ; B 40 -293 436 926 ; C 231 ; WX 384 ; N parenleftex ; B 40 -85 92 925 ; C 232 ; WX 384 ; N parenleftbt ; B 40 -293 436 926 ; C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 341 926 ; C 234 ; WX 384 ; N bracketleftex ; B 0 -79 55 925 ; C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 340 926 ; C 236 ; WX 494 ; N bracelefttp ; B 201 -75 439 926 ; C 237 ; WX 494 ; N braceleftmid ; B 14 -85 255 935 ; C 238 ; WX 494 ; N braceleftbt ; B 201 -70 439 926 ; C 239 ; WX 494 ; N braceex ; B 201 -80 255 935 ; C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ; C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ; C 243 ; WX 686 ; N integraltp ; B 332 -83 715 921 ; C 244 ; WX 686 ; N integralex ; B 332 -88 415 975 ; C 245 ; WX 686 ; N integralbt ; B 39 -81 415 921 ; C 246 ; WX 384 ; N parenrighttp ; B 54 -293 450 926 ; C 247 ; WX 384 ; N parenrightex ; B 398 -85 450 925 ; C 248 ; WX 384 ; N parenrightbt ; B 54 -293 450 926 ; C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 360 926 ; C 250 ; WX 384 ; N bracketrightex ; B 305 -79 360 925 ; C 251 ; WX 384 ; N bracketrightbt ; B 20 -80 360 926 ; C 252 ; WX 494 ; N bracerighttp ; B 17 -75 255 926 ; C 253 ; WX 494 ; N bracerightmid ; B 201 -85 442 935 ; C 254 ; WX 494 ; N bracerightbt ; B 17 -70 255 926 ; C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ; EndCharMetrics EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Narrow-Bold.afm���������������������������������������������0000644�0001750�0001750�00000042371�11462120062�021171� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu Mar 15 11:47:27 1990 Comment UniqueID 28398 Comment VMusage 7614 43068 FontName Helvetica-Narrow-Bold FullName Helvetica Narrow Bold FamilyName Helvetica Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -139 -228 822 962 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 228 ; N space ; B 0 0 0 0 ; C 33 ; WX 273 ; N exclam ; B 74 0 200 718 ; C 34 ; WX 389 ; N quotedbl ; B 80 447 308 718 ; C 35 ; WX 456 ; N numbersign ; B 15 0 441 698 ; C 36 ; WX 456 ; N dollar ; B 25 -115 429 775 ; C 37 ; WX 729 ; N percent ; B 23 -19 706 710 ; C 38 ; WX 592 ; N ampersand ; B 44 -19 575 718 ; C 39 ; WX 228 ; N quoteright ; B 57 445 171 718 ; C 40 ; WX 273 ; N parenleft ; B 29 -208 257 734 ; C 41 ; WX 273 ; N parenright ; B 16 -208 244 734 ; C 42 ; WX 319 ; N asterisk ; B 22 387 297 718 ; C 43 ; WX 479 ; N plus ; B 33 0 446 506 ; C 44 ; WX 228 ; N comma ; B 52 -168 175 146 ; C 45 ; WX 273 ; N hyphen ; B 22 215 251 345 ; C 46 ; WX 228 ; N period ; B 52 0 175 146 ; C 47 ; WX 228 ; N slash ; B -27 -19 255 737 ; C 48 ; WX 456 ; N zero ; B 26 -19 430 710 ; C 49 ; WX 456 ; N one ; B 57 0 310 710 ; C 50 ; WX 456 ; N two ; B 21 0 419 710 ; C 51 ; WX 456 ; N three ; B 22 -19 423 710 ; C 52 ; WX 456 ; N four ; B 22 0 431 710 ; C 53 ; WX 456 ; N five ; B 22 -19 423 698 ; C 54 ; WX 456 ; N six ; B 25 -19 426 710 ; C 55 ; WX 456 ; N seven ; B 20 0 433 698 ; C 56 ; WX 456 ; N eight ; B 26 -19 430 710 ; C 57 ; WX 456 ; N nine ; B 25 -19 428 710 ; C 58 ; WX 273 ; N colon ; B 75 0 198 512 ; C 59 ; WX 273 ; N semicolon ; B 75 -168 198 512 ; C 60 ; WX 479 ; N less ; B 31 -8 448 514 ; C 61 ; WX 479 ; N equal ; B 33 87 446 419 ; C 62 ; WX 479 ; N greater ; B 31 -8 448 514 ; C 63 ; WX 501 ; N question ; B 49 0 456 727 ; C 64 ; WX 800 ; N at ; B 97 -19 702 737 ; C 65 ; WX 592 ; N A ; B 16 0 576 718 ; C 66 ; WX 592 ; N B ; B 62 0 549 718 ; C 67 ; WX 592 ; N C ; B 36 -19 561 737 ; C 68 ; WX 592 ; N D ; B 62 0 562 718 ; C 69 ; WX 547 ; N E ; B 62 0 509 718 ; C 70 ; WX 501 ; N F ; B 62 0 481 718 ; C 71 ; WX 638 ; N G ; B 36 -19 585 737 ; C 72 ; WX 592 ; N H ; B 58 0 534 718 ; C 73 ; WX 228 ; N I ; B 52 0 175 718 ; C 74 ; WX 456 ; N J ; B 18 -18 397 718 ; C 75 ; WX 592 ; N K ; B 71 0 592 718 ; C 76 ; WX 501 ; N L ; B 62 0 478 718 ; C 77 ; WX 683 ; N M ; B 57 0 627 718 ; C 78 ; WX 592 ; N N ; B 57 0 536 718 ; C 79 ; WX 638 ; N O ; B 36 -19 602 737 ; C 80 ; WX 547 ; N P ; B 62 0 514 718 ; C 81 ; WX 638 ; N Q ; B 36 -52 604 737 ; C 82 ; WX 592 ; N R ; B 62 0 555 718 ; C 83 ; WX 547 ; N S ; B 32 -19 516 737 ; C 84 ; WX 501 ; N T ; B 11 0 490 718 ; C 85 ; WX 592 ; N U ; B 59 -19 534 718 ; C 86 ; WX 547 ; N V ; B 16 0 531 718 ; C 87 ; WX 774 ; N W ; B 13 0 762 718 ; C 88 ; WX 547 ; N X ; B 11 0 535 718 ; C 89 ; WX 547 ; N Y ; B 12 0 535 718 ; C 90 ; WX 501 ; N Z ; B 20 0 481 718 ; C 91 ; WX 273 ; N bracketleft ; B 52 -196 253 722 ; C 92 ; WX 228 ; N backslash ; B -27 -19 255 737 ; C 93 ; WX 273 ; N bracketright ; B 20 -196 221 722 ; C 94 ; WX 479 ; N asciicircum ; B 51 323 428 698 ; C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ; C 96 ; WX 228 ; N quoteleft ; B 57 454 171 727 ; C 97 ; WX 456 ; N a ; B 24 -14 432 546 ; C 98 ; WX 501 ; N b ; B 50 -14 474 718 ; C 99 ; WX 456 ; N c ; B 28 -14 430 546 ; C 100 ; WX 501 ; N d ; B 28 -14 452 718 ; C 101 ; WX 456 ; N e ; B 19 -14 433 546 ; C 102 ; WX 273 ; N f ; B 8 0 261 727 ; L i fi ; L l fl ; C 103 ; WX 501 ; N g ; B 33 -217 453 546 ; C 104 ; WX 501 ; N h ; B 53 0 448 718 ; C 105 ; WX 228 ; N i ; B 57 0 171 725 ; C 106 ; WX 228 ; N j ; B 2 -214 171 725 ; C 107 ; WX 456 ; N k ; B 57 0 461 718 ; C 108 ; WX 228 ; N l ; B 57 0 171 718 ; C 109 ; WX 729 ; N m ; B 52 0 677 546 ; C 110 ; WX 501 ; N n ; B 53 0 448 546 ; C 111 ; WX 501 ; N o ; B 28 -14 474 546 ; C 112 ; WX 501 ; N p ; B 51 -207 474 546 ; C 113 ; WX 501 ; N q ; B 28 -207 453 546 ; C 114 ; WX 319 ; N r ; B 52 0 306 546 ; C 115 ; WX 456 ; N s ; B 25 -14 426 546 ; C 116 ; WX 273 ; N t ; B 8 -6 253 676 ; C 117 ; WX 501 ; N u ; B 54 -14 447 532 ; C 118 ; WX 456 ; N v ; B 11 0 445 532 ; C 119 ; WX 638 ; N w ; B 8 0 631 532 ; C 120 ; WX 456 ; N x ; B 12 0 444 532 ; C 121 ; WX 456 ; N y ; B 8 -214 442 532 ; C 122 ; WX 410 ; N z ; B 16 0 394 532 ; C 123 ; WX 319 ; N braceleft ; B 39 -196 299 722 ; C 124 ; WX 230 ; N bar ; B 69 -19 161 737 ; C 125 ; WX 319 ; N braceright ; B 20 -196 280 722 ; C 126 ; WX 479 ; N asciitilde ; B 50 163 429 343 ; C 161 ; WX 273 ; N exclamdown ; B 74 -186 200 532 ; C 162 ; WX 456 ; N cent ; B 28 -118 430 628 ; C 163 ; WX 456 ; N sterling ; B 23 -16 444 718 ; C 164 ; WX 137 ; N fraction ; B -139 -19 276 710 ; C 165 ; WX 456 ; N yen ; B -7 0 463 698 ; C 166 ; WX 456 ; N florin ; B -8 -210 423 737 ; C 167 ; WX 456 ; N section ; B 28 -184 428 727 ; C 168 ; WX 456 ; N currency ; B -2 76 458 636 ; C 169 ; WX 195 ; N quotesingle ; B 57 447 138 718 ; C 170 ; WX 410 ; N quotedblleft ; B 52 454 358 727 ; C 171 ; WX 456 ; N guillemotleft ; B 72 76 384 484 ; C 172 ; WX 273 ; N guilsinglleft ; B 68 76 205 484 ; C 173 ; WX 273 ; N guilsinglright ; B 68 76 205 484 ; C 174 ; WX 501 ; N fi ; B 8 0 444 727 ; C 175 ; WX 501 ; N fl ; B 8 0 444 727 ; C 177 ; WX 456 ; N endash ; B 0 227 456 333 ; C 178 ; WX 456 ; N dagger ; B 30 -171 426 718 ; C 179 ; WX 456 ; N daggerdbl ; B 30 -171 426 718 ; C 180 ; WX 228 ; N periodcentered ; B 48 172 180 334 ; C 182 ; WX 456 ; N paragraph ; B -7 -191 442 700 ; C 183 ; WX 287 ; N bullet ; B 8 194 279 524 ; C 184 ; WX 228 ; N quotesinglbase ; B 57 -146 171 127 ; C 185 ; WX 410 ; N quotedblbase ; B 52 -146 358 127 ; C 186 ; WX 410 ; N quotedblright ; B 52 445 358 718 ; C 187 ; WX 456 ; N guillemotright ; B 72 76 384 484 ; C 188 ; WX 820 ; N ellipsis ; B 75 0 745 146 ; C 189 ; WX 820 ; N perthousand ; B -2 -19 822 710 ; C 191 ; WX 501 ; N questiondown ; B 45 -195 452 532 ; C 193 ; WX 273 ; N grave ; B -19 604 184 750 ; C 194 ; WX 273 ; N acute ; B 89 604 292 750 ; C 195 ; WX 273 ; N circumflex ; B -8 604 281 750 ; C 196 ; WX 273 ; N tilde ; B -14 610 287 737 ; C 197 ; WX 273 ; N macron ; B -5 604 278 678 ; C 198 ; WX 273 ; N breve ; B -2 604 275 750 ; C 199 ; WX 273 ; N dotaccent ; B 85 614 189 729 ; C 200 ; WX 273 ; N dieresis ; B 5 614 268 729 ; C 202 ; WX 273 ; N ring ; B 48 568 225 776 ; C 203 ; WX 273 ; N cedilla ; B 5 -228 201 0 ; C 205 ; WX 273 ; N hungarumlaut ; B 7 604 399 750 ; C 206 ; WX 273 ; N ogonek ; B 58 -228 249 0 ; C 207 ; WX 273 ; N caron ; B -8 604 281 750 ; C 208 ; WX 820 ; N emdash ; B 0 227 820 333 ; C 225 ; WX 820 ; N AE ; B 4 0 782 718 ; C 227 ; WX 303 ; N ordfeminine ; B 18 276 285 737 ; C 232 ; WX 501 ; N Lslash ; B -16 0 478 718 ; C 233 ; WX 638 ; N Oslash ; B 27 -27 610 745 ; C 234 ; WX 820 ; N OE ; B 30 -19 788 737 ; C 235 ; WX 299 ; N ordmasculine ; B 5 276 295 737 ; C 241 ; WX 729 ; N ae ; B 24 -14 704 546 ; C 245 ; WX 228 ; N dotlessi ; B 57 0 171 532 ; C 248 ; WX 228 ; N lslash ; B -15 0 243 718 ; C 249 ; WX 501 ; N oslash ; B 18 -29 483 560 ; C 250 ; WX 774 ; N oe ; B 28 -14 748 546 ; C 251 ; WX 501 ; N germandbls ; B 57 -14 475 731 ; C -1 ; WX 501 ; N Zcaron ; B 20 0 481 936 ; C -1 ; WX 456 ; N ccedilla ; B 28 -228 430 546 ; C -1 ; WX 456 ; N ydieresis ; B 8 -214 442 729 ; C -1 ; WX 456 ; N atilde ; B 24 -14 432 737 ; C -1 ; WX 228 ; N icircumflex ; B -30 0 259 750 ; C -1 ; WX 273 ; N threesuperior ; B 7 271 267 710 ; C -1 ; WX 456 ; N ecircumflex ; B 19 -14 433 750 ; C -1 ; WX 501 ; N thorn ; B 51 -208 474 718 ; C -1 ; WX 456 ; N egrave ; B 19 -14 433 750 ; C -1 ; WX 273 ; N twosuperior ; B 7 283 266 710 ; C -1 ; WX 456 ; N eacute ; B 19 -14 433 750 ; C -1 ; WX 501 ; N otilde ; B 28 -14 474 737 ; C -1 ; WX 592 ; N Aacute ; B 16 0 576 936 ; C -1 ; WX 501 ; N ocircumflex ; B 28 -14 474 750 ; C -1 ; WX 456 ; N yacute ; B 8 -214 442 750 ; C -1 ; WX 501 ; N udieresis ; B 54 -14 447 729 ; C -1 ; WX 684 ; N threequarters ; B 13 -19 655 710 ; C -1 ; WX 456 ; N acircumflex ; B 24 -14 432 750 ; C -1 ; WX 592 ; N Eth ; B -4 0 562 718 ; C -1 ; WX 456 ; N edieresis ; B 19 -14 433 729 ; C -1 ; WX 501 ; N ugrave ; B 54 -14 447 750 ; C -1 ; WX 820 ; N trademark ; B 36 306 784 718 ; C -1 ; WX 501 ; N ograve ; B 28 -14 474 750 ; C -1 ; WX 456 ; N scaron ; B 25 -14 426 750 ; C -1 ; WX 228 ; N Idieresis ; B -17 0 246 915 ; C -1 ; WX 501 ; N uacute ; B 54 -14 447 750 ; C -1 ; WX 456 ; N agrave ; B 24 -14 432 750 ; C -1 ; WX 501 ; N ntilde ; B 53 0 448 737 ; C -1 ; WX 456 ; N aring ; B 24 -14 432 776 ; C -1 ; WX 410 ; N zcaron ; B 16 0 394 750 ; C -1 ; WX 228 ; N Icircumflex ; B -30 0 259 936 ; C -1 ; WX 592 ; N Ntilde ; B 57 0 536 923 ; C -1 ; WX 501 ; N ucircumflex ; B 54 -14 447 750 ; C -1 ; WX 547 ; N Ecircumflex ; B 62 0 509 936 ; C -1 ; WX 228 ; N Iacute ; B 52 0 270 936 ; C -1 ; WX 592 ; N Ccedilla ; B 36 -228 561 737 ; C -1 ; WX 638 ; N Odieresis ; B 36 -19 602 915 ; C -1 ; WX 547 ; N Scaron ; B 32 -19 516 936 ; C -1 ; WX 547 ; N Edieresis ; B 62 0 509 915 ; C -1 ; WX 228 ; N Igrave ; B -41 0 175 936 ; C -1 ; WX 456 ; N adieresis ; B 24 -14 432 729 ; C -1 ; WX 638 ; N Ograve ; B 36 -19 602 936 ; C -1 ; WX 547 ; N Egrave ; B 62 0 509 936 ; C -1 ; WX 547 ; N Ydieresis ; B 12 0 535 915 ; C -1 ; WX 604 ; N registered ; B -9 -19 613 737 ; C -1 ; WX 638 ; N Otilde ; B 36 -19 602 923 ; C -1 ; WX 684 ; N onequarter ; B 21 -19 628 710 ; C -1 ; WX 592 ; N Ugrave ; B 59 -19 534 936 ; C -1 ; WX 592 ; N Ucircumflex ; B 59 -19 534 936 ; C -1 ; WX 547 ; N Thorn ; B 62 0 514 718 ; C -1 ; WX 479 ; N divide ; B 33 -42 446 548 ; C -1 ; WX 592 ; N Atilde ; B 16 0 576 923 ; C -1 ; WX 592 ; N Uacute ; B 59 -19 534 936 ; C -1 ; WX 638 ; N Ocircumflex ; B 36 -19 602 936 ; C -1 ; WX 479 ; N logicalnot ; B 33 108 446 419 ; C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ; C -1 ; WX 228 ; N idieresis ; B -17 0 246 729 ; C -1 ; WX 228 ; N iacute ; B 57 0 270 750 ; C -1 ; WX 456 ; N aacute ; B 24 -14 432 750 ; C -1 ; WX 479 ; N plusminus ; B 33 0 446 506 ; C -1 ; WX 479 ; N multiply ; B 33 1 447 505 ; C -1 ; WX 592 ; N Udieresis ; B 59 -19 534 915 ; C -1 ; WX 479 ; N minus ; B 33 197 446 309 ; C -1 ; WX 273 ; N onesuperior ; B 21 283 194 710 ; C -1 ; WX 547 ; N Eacute ; B 62 0 509 936 ; C -1 ; WX 592 ; N Acircumflex ; B 16 0 576 936 ; C -1 ; WX 604 ; N copyright ; B -9 -19 614 737 ; C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ; C -1 ; WX 501 ; N odieresis ; B 28 -14 474 729 ; C -1 ; WX 501 ; N oacute ; B 28 -14 474 750 ; C -1 ; WX 328 ; N degree ; B 47 426 281 712 ; C -1 ; WX 228 ; N igrave ; B -41 0 171 750 ; C -1 ; WX 501 ; N mu ; B 54 -207 447 532 ; C -1 ; WX 638 ; N Oacute ; B 36 -19 602 936 ; C -1 ; WX 501 ; N eth ; B 28 -14 474 737 ; C -1 ; WX 592 ; N Adieresis ; B 16 0 576 915 ; C -1 ; WX 547 ; N Yacute ; B 12 0 535 936 ; C -1 ; WX 230 ; N brokenbar ; B 69 -19 161 737 ; C -1 ; WX 684 ; N onehalf ; B 21 -19 651 710 ; EndCharMetrics StartKernData StartKernPairs 209 KPX A y -24 KPX A w -24 KPX A v -32 KPX A u -24 KPX A Y -89 KPX A W -48 KPX A V -65 KPX A U -40 KPX A T -73 KPX A Q -32 KPX A O -32 KPX A G -40 KPX A C -32 KPX B U -7 KPX B A -24 KPX D period -24 KPX D comma -24 KPX D Y -56 KPX D W -32 KPX D V -32 KPX D A -32 KPX F period -81 KPX F comma -81 KPX F a -15 KPX F A -65 KPX J u -15 KPX J period -15 KPX J comma -15 KPX J A -15 KPX K y -32 KPX K u -24 KPX K o -28 KPX K e -11 KPX K O -24 KPX L y -24 KPX L quoteright -114 KPX L quotedblright -114 KPX L Y -97 KPX L W -65 KPX L V -89 KPX L T -73 KPX O period -32 KPX O comma -32 KPX O Y -56 KPX O X -40 KPX O W -40 KPX O V -40 KPX O T -32 KPX O A -40 KPX P period -97 KPX P o -32 KPX P e -24 KPX P comma -97 KPX P a -24 KPX P A -81 KPX Q period 16 KPX Q comma 16 KPX Q U -7 KPX R Y -40 KPX R W -32 KPX R V -40 KPX R U -15 KPX R T -15 KPX R O -15 KPX T y -48 KPX T w -48 KPX T u -73 KPX T semicolon -32 KPX T r -65 KPX T period -65 KPX T o -65 KPX T hyphen -97 KPX T e -48 KPX T comma -65 KPX T colon -32 KPX T a -65 KPX T O -32 KPX T A -73 KPX U period -24 KPX U comma -24 KPX U A -40 KPX V u -48 KPX V semicolon -32 KPX V period -97 KPX V o -73 KPX V hyphen -65 KPX V e -40 KPX V comma -97 KPX V colon -32 KPX V a -48 KPX V O -40 KPX V G -40 KPX V A -65 KPX W y -15 KPX W u -36 KPX W semicolon -7 KPX W period -65 KPX W o -48 KPX W hyphen -32 KPX W e -28 KPX W comma -65 KPX W colon -7 KPX W a -32 KPX W O -15 KPX W A -48 KPX Y u -81 KPX Y semicolon -40 KPX Y period -81 KPX Y o -81 KPX Y e -65 KPX Y comma -81 KPX Y colon -40 KPX Y a -73 KPX Y O -56 KPX Y A -89 KPX a y -15 KPX a w -11 KPX a v -11 KPX a g -7 KPX b y -15 KPX b v -15 KPX b u -15 KPX b l -7 KPX c y -7 KPX c l -15 KPX c k -15 KPX c h -7 KPX colon space -32 KPX comma space -32 KPX comma quoteright -97 KPX comma quotedblright -97 KPX d y -11 KPX d w -11 KPX d v -11 KPX d d -7 KPX e y -11 KPX e x -11 KPX e w -11 KPX e v -11 KPX e period 16 KPX e comma 8 KPX f quoteright 25 KPX f quotedblright 25 KPX f period -7 KPX f o -15 KPX f e -7 KPX f comma -7 KPX g g -7 KPX g e 8 KPX h y -15 KPX k o -11 KPX l y -11 KPX l w -11 KPX m y -24 KPX m u -15 KPX n y -15 KPX n v -32 KPX n u -7 KPX o y -15 KPX o x -24 KPX o w -11 KPX o v -15 KPX p y -11 KPX period space -32 KPX period quoteright -97 KPX period quotedblright -97 KPX quotedblright space -65 KPX quoteleft quoteleft -37 KPX quoteright v -15 KPX quoteright space -65 KPX quoteright s -48 KPX quoteright r -32 KPX quoteright quoteright -37 KPX quoteright l -15 KPX quoteright d -65 KPX r y 8 KPX r v 8 KPX r t 16 KPX r s -11 KPX r q -15 KPX r period -48 KPX r o -15 KPX r hyphen -15 KPX r g -11 KPX r d -15 KPX r comma -48 KPX r c -15 KPX s w -11 KPX semicolon space -32 KPX space quoteleft -48 KPX space quotedblleft -65 KPX space Y -97 KPX space W -65 KPX space V -65 KPX space T -81 KPX v period -65 KPX v o -24 KPX v comma -65 KPX v a -15 KPX w period -32 KPX w o -15 KPX w comma -32 KPX x e -7 KPX y period -65 KPX y o -20 KPX y e -7 KPX y comma -65 KPX y a -24 KPX z e 8 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 160 186 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 160 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 160 186 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 160 186 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 186 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 186 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 160 186 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 186 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 186 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 186 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 186 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 186 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/NewCenturySchlbk-BoldItalic.afm���������������������������������������0000644�0001750�0001750�00000043263�11462120062�022400� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue May 28 16:56:07 1991 Comment UniqueID 35034 Comment VMusage 31030 37922 FontName NewCenturySchlbk-BoldItalic FullName New Century Schoolbook Bold Italic FamilyName New Century Schoolbook Weight Bold ItalicAngle -16 IsFixedPitch false FontBBox -205 -250 1147 991 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 722 XHeight 477 Ascender 737 Descender -205 StartCharMetrics 228 C 32 ; WX 287 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 0 -15 333 737 ; C 34 ; WX 400 ; N quotedbl ; B 66 388 428 737 ; C 35 ; WX 574 ; N numbersign ; B 30 0 544 690 ; C 36 ; WX 574 ; N dollar ; B 9 -120 565 810 ; C 37 ; WX 889 ; N percent ; B 54 -28 835 727 ; C 38 ; WX 889 ; N ampersand ; B 32 -15 823 737 ; C 39 ; WX 259 ; N quoteright ; B 48 388 275 737 ; C 40 ; WX 407 ; N parenleft ; B 72 -117 454 745 ; C 41 ; WX 407 ; N parenright ; B -70 -117 310 745 ; C 42 ; WX 500 ; N asterisk ; B 58 301 498 737 ; C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; C 44 ; WX 287 ; N comma ; B -57 -192 170 157 ; C 45 ; WX 333 ; N hyphen ; B 2 177 263 299 ; C 46 ; WX 287 ; N period ; B -20 -15 152 157 ; C 47 ; WX 278 ; N slash ; B -41 -15 320 737 ; C 48 ; WX 574 ; N zero ; B 21 -15 553 705 ; C 49 ; WX 574 ; N one ; B 25 0 489 705 ; C 50 ; WX 574 ; N two ; B -38 -3 538 705 ; C 51 ; WX 574 ; N three ; B -7 -15 536 705 ; C 52 ; WX 574 ; N four ; B -13 0 544 705 ; C 53 ; WX 574 ; N five ; B 0 -15 574 705 ; C 54 ; WX 574 ; N six ; B 31 -15 574 705 ; C 55 ; WX 574 ; N seven ; B 64 -15 593 705 ; C 56 ; WX 574 ; N eight ; B 0 -15 552 705 ; C 57 ; WX 574 ; N nine ; B 0 -15 543 705 ; C 58 ; WX 287 ; N colon ; B -20 -15 237 477 ; C 59 ; WX 287 ; N semicolon ; B -57 -192 237 477 ; C 60 ; WX 606 ; N less ; B 50 -9 556 515 ; C 61 ; WX 606 ; N equal ; B 50 103 556 403 ; C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ; C 63 ; WX 481 ; N question ; B 79 -15 451 737 ; C 64 ; WX 747 ; N at ; B -4 -15 751 737 ; C 65 ; WX 741 ; N A ; B -75 0 716 737 ; C 66 ; WX 759 ; N B ; B -50 0 721 722 ; C 67 ; WX 759 ; N C ; B 37 -15 759 737 ; C 68 ; WX 833 ; N D ; B -47 0 796 722 ; C 69 ; WX 741 ; N E ; B -41 0 730 722 ; C 70 ; WX 704 ; N F ; B -41 0 730 722 ; C 71 ; WX 815 ; N G ; B 37 -15 805 737 ; C 72 ; WX 870 ; N H ; B -41 0 911 722 ; C 73 ; WX 444 ; N I ; B -41 0 485 722 ; C 74 ; WX 667 ; N J ; B -20 -15 708 722 ; C 75 ; WX 778 ; N K ; B -41 0 832 722 ; C 76 ; WX 704 ; N L ; B -41 0 670 722 ; C 77 ; WX 944 ; N M ; B -44 0 988 722 ; C 78 ; WX 852 ; N N ; B -61 -10 913 722 ; C 79 ; WX 833 ; N O ; B 37 -15 796 737 ; C 80 ; WX 741 ; N P ; B -41 0 730 722 ; C 81 ; WX 833 ; N Q ; B 37 -189 796 737 ; C 82 ; WX 796 ; N R ; B -41 -15 749 722 ; C 83 ; WX 685 ; N S ; B 1 -15 666 737 ; C 84 ; WX 722 ; N T ; B 41 0 759 722 ; C 85 ; WX 833 ; N U ; B 88 -15 900 722 ; C 86 ; WX 741 ; N V ; B 32 -10 802 722 ; C 87 ; WX 944 ; N W ; B 40 -10 1000 722 ; C 88 ; WX 741 ; N X ; B -82 0 801 722 ; C 89 ; WX 704 ; N Y ; B 13 0 775 722 ; C 90 ; WX 704 ; N Z ; B -33 0 711 722 ; C 91 ; WX 407 ; N bracketleft ; B 1 -109 464 737 ; C 92 ; WX 606 ; N backslash ; B 161 -15 445 737 ; C 93 ; WX 407 ; N bracketright ; B -101 -109 362 737 ; C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 259 ; N quoteleft ; B 47 388 274 737 ; C 97 ; WX 667 ; N a ; B 6 -15 636 477 ; C 98 ; WX 611 ; N b ; B 29 -15 557 737 ; C 99 ; WX 537 ; N c ; B 0 -15 482 477 ; C 100 ; WX 667 ; N d ; B 0 -15 660 737 ; C 101 ; WX 519 ; N e ; B 0 -15 479 477 ; C 102 ; WX 389 ; N f ; B -48 -205 550 737 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B -63 -205 604 528 ; C 104 ; WX 685 ; N h ; B 0 -15 639 737 ; C 105 ; WX 389 ; N i ; B 32 -15 345 737 ; C 106 ; WX 370 ; N j ; B -205 -205 347 737 ; C 107 ; WX 648 ; N k ; B -11 -15 578 737 ; C 108 ; WX 389 ; N l ; B 32 -15 375 737 ; C 109 ; WX 944 ; N m ; B 0 -15 909 477 ; C 110 ; WX 685 ; N n ; B 0 -15 639 477 ; C 111 ; WX 574 ; N o ; B 0 -15 530 477 ; C 112 ; WX 648 ; N p ; B -119 -205 590 477 ; C 113 ; WX 630 ; N q ; B 0 -205 587 477 ; C 114 ; WX 519 ; N r ; B 0 0 527 486 ; C 115 ; WX 481 ; N s ; B 0 -15 435 477 ; C 116 ; WX 407 ; N t ; B 24 -15 403 650 ; C 117 ; WX 685 ; N u ; B 30 -15 635 477 ; C 118 ; WX 556 ; N v ; B 30 -15 496 477 ; C 119 ; WX 833 ; N w ; B 30 -15 773 477 ; C 120 ; WX 574 ; N x ; B -46 -15 574 477 ; C 121 ; WX 519 ; N y ; B -66 -205 493 477 ; C 122 ; WX 519 ; N z ; B -19 -15 473 477 ; C 123 ; WX 407 ; N braceleft ; B 52 -109 408 737 ; C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ; C 125 ; WX 407 ; N braceright ; B -25 -109 331 737 ; C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ; C 161 ; WX 333 ; N exclamdown ; B -44 -205 289 547 ; C 162 ; WX 574 ; N cent ; B 30 -144 512 578 ; C 163 ; WX 574 ; N sterling ; B -18 -15 566 705 ; C 164 ; WX 167 ; N fraction ; B -166 -15 333 705 ; C 165 ; WX 574 ; N yen ; B 17 0 629 690 ; C 166 ; WX 574 ; N florin ; B -43 -205 575 737 ; C 167 ; WX 500 ; N section ; B -30 -146 515 737 ; C 168 ; WX 574 ; N currency ; B 27 84 547 605 ; C 169 ; WX 287 ; N quotesingle ; B 112 388 250 737 ; C 170 ; WX 481 ; N quotedblleft ; B 54 388 521 737 ; C 171 ; WX 481 ; N guillemotleft ; B -35 69 449 407 ; C 172 ; WX 278 ; N guilsinglleft ; B -25 69 244 407 ; C 173 ; WX 278 ; N guilsinglright ; B -26 69 243 407 ; C 174 ; WX 685 ; N fi ; B -70 -205 641 737 ; C 175 ; WX 685 ; N fl ; B -70 -205 671 737 ; C 177 ; WX 500 ; N endash ; B -47 189 479 287 ; C 178 ; WX 500 ; N dagger ; B 48 -146 508 737 ; C 179 ; WX 500 ; N daggerdbl ; B -60 -150 508 737 ; C 180 ; WX 287 ; N periodcentered ; B 57 200 229 372 ; C 182 ; WX 650 ; N paragraph ; B 25 -131 681 722 ; C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; C 184 ; WX 259 ; N quotesinglbase ; B -57 -192 170 157 ; C 185 ; WX 481 ; N quotedblbase ; B -57 -192 412 157 ; C 186 ; WX 481 ; N quotedblright ; B 43 388 510 737 ; C 187 ; WX 481 ; N guillemotright ; B -31 69 453 407 ; C 188 ; WX 1000 ; N ellipsis ; B 81 -15 919 157 ; C 189 ; WX 1167 ; N perthousand ; B 20 -28 1147 727 ; C 191 ; WX 481 ; N questiondown ; B 0 -205 372 547 ; C 193 ; WX 333 ; N grave ; B 74 538 294 722 ; C 194 ; WX 333 ; N acute ; B 123 538 372 722 ; C 195 ; WX 333 ; N circumflex ; B 23 533 365 705 ; C 196 ; WX 333 ; N tilde ; B 28 561 398 690 ; C 197 ; WX 333 ; N macron ; B 47 573 404 649 ; C 198 ; WX 333 ; N breve ; B 67 535 390 698 ; C 199 ; WX 333 ; N dotaccent ; B 145 546 289 690 ; C 200 ; WX 333 ; N dieresis ; B 33 546 393 690 ; C 202 ; WX 333 ; N ring ; B 111 522 335 746 ; C 203 ; WX 333 ; N cedilla ; B -21 -220 225 3 ; C 205 ; WX 333 ; N hungarumlaut ; B 15 538 480 722 ; C 206 ; WX 333 ; N ogonek ; B 68 -155 246 -10 ; C 207 ; WX 333 ; N caron ; B 60 531 403 705 ; C 208 ; WX 1000 ; N emdash ; B -47 189 979 287 ; C 225 ; WX 889 ; N AE ; B -86 0 915 722 ; C 227 ; WX 412 ; N ordfeminine ; B 47 407 460 705 ; C 232 ; WX 704 ; N Lslash ; B -41 0 670 722 ; C 233 ; WX 833 ; N Oslash ; B 35 -68 798 790 ; C 234 ; WX 963 ; N OE ; B 29 0 989 722 ; C 235 ; WX 356 ; N ordmasculine ; B 42 407 394 705 ; C 241 ; WX 815 ; N ae ; B -18 -15 775 477 ; C 245 ; WX 389 ; N dotlessi ; B 32 -15 345 477 ; C 248 ; WX 389 ; N lslash ; B 5 -15 390 737 ; C 249 ; WX 574 ; N oslash ; B 0 -121 530 583 ; C 250 ; WX 852 ; N oe ; B -6 -15 812 477 ; C 251 ; WX 574 ; N germandbls ; B -91 -205 540 737 ; C -1 ; WX 519 ; N ecircumflex ; B 0 -15 479 705 ; C -1 ; WX 519 ; N edieresis ; B 0 -15 486 690 ; C -1 ; WX 667 ; N aacute ; B 6 -15 636 722 ; C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; C -1 ; WX 389 ; N icircumflex ; B 21 -15 363 698 ; C -1 ; WX 685 ; N udieresis ; B 30 -15 635 690 ; C -1 ; WX 574 ; N ograve ; B 0 -15 530 722 ; C -1 ; WX 685 ; N uacute ; B 30 -15 635 722 ; C -1 ; WX 685 ; N ucircumflex ; B 30 -15 635 705 ; C -1 ; WX 741 ; N Aacute ; B -75 0 716 947 ; C -1 ; WX 389 ; N igrave ; B 32 -15 345 715 ; C -1 ; WX 444 ; N Icircumflex ; B -41 0 485 930 ; C -1 ; WX 537 ; N ccedilla ; B 0 -220 482 477 ; C -1 ; WX 667 ; N adieresis ; B 6 -15 636 690 ; C -1 ; WX 741 ; N Ecircumflex ; B -41 0 730 930 ; C -1 ; WX 481 ; N scaron ; B 0 -15 477 705 ; C -1 ; WX 648 ; N thorn ; B -119 -205 590 737 ; C -1 ; WX 950 ; N trademark ; B 42 317 1017 722 ; C -1 ; WX 519 ; N egrave ; B 0 -15 479 722 ; C -1 ; WX 344 ; N threesuperior ; B 3 273 361 705 ; C -1 ; WX 519 ; N zcaron ; B -19 -15 473 695 ; C -1 ; WX 667 ; N atilde ; B 6 -15 636 690 ; C -1 ; WX 667 ; N aring ; B 6 -15 636 746 ; C -1 ; WX 574 ; N ocircumflex ; B 0 -15 530 705 ; C -1 ; WX 741 ; N Edieresis ; B -41 0 730 915 ; C -1 ; WX 861 ; N threequarters ; B 35 -15 789 705 ; C -1 ; WX 519 ; N ydieresis ; B -66 -205 493 690 ; C -1 ; WX 519 ; N yacute ; B -66 -205 493 722 ; C -1 ; WX 389 ; N iacute ; B 32 -15 370 715 ; C -1 ; WX 741 ; N Acircumflex ; B -75 0 716 930 ; C -1 ; WX 833 ; N Uacute ; B 88 -15 900 947 ; C -1 ; WX 519 ; N eacute ; B 0 -15 479 722 ; C -1 ; WX 833 ; N Ograve ; B 37 -15 796 947 ; C -1 ; WX 667 ; N agrave ; B 6 -15 636 722 ; C -1 ; WX 833 ; N Udieresis ; B 88 -15 900 915 ; C -1 ; WX 667 ; N acircumflex ; B 6 -15 636 705 ; C -1 ; WX 444 ; N Igrave ; B -41 0 485 947 ; C -1 ; WX 344 ; N twosuperior ; B -17 280 362 705 ; C -1 ; WX 833 ; N Ugrave ; B 88 -15 900 947 ; C -1 ; WX 861 ; N onequarter ; B 17 -15 789 705 ; C -1 ; WX 833 ; N Ucircumflex ; B 88 -15 900 930 ; C -1 ; WX 685 ; N Scaron ; B 1 -15 666 930 ; C -1 ; WX 444 ; N Idieresis ; B -41 0 509 915 ; C -1 ; WX 389 ; N idieresis ; B 31 -15 391 683 ; C -1 ; WX 741 ; N Egrave ; B -41 0 730 947 ; C -1 ; WX 833 ; N Oacute ; B 37 -15 796 947 ; C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ; C -1 ; WX 741 ; N Atilde ; B -75 0 716 915 ; C -1 ; WX 741 ; N Aring ; B -75 0 716 991 ; C -1 ; WX 833 ; N Odieresis ; B 37 -15 796 915 ; C -1 ; WX 741 ; N Adieresis ; B -75 0 716 915 ; C -1 ; WX 852 ; N Ntilde ; B -61 -10 913 915 ; C -1 ; WX 704 ; N Zcaron ; B -33 0 711 930 ; C -1 ; WX 741 ; N Thorn ; B -41 0 690 722 ; C -1 ; WX 444 ; N Iacute ; B -41 0 488 947 ; C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ; C -1 ; WX 741 ; N Eacute ; B -41 0 730 947 ; C -1 ; WX 704 ; N Ydieresis ; B 13 0 775 915 ; C -1 ; WX 344 ; N onesuperior ; B 19 282 326 705 ; C -1 ; WX 685 ; N ugrave ; B 30 -15 635 722 ; C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ; C -1 ; WX 685 ; N ntilde ; B 0 -15 639 690 ; C -1 ; WX 833 ; N Otilde ; B 37 -15 796 915 ; C -1 ; WX 574 ; N otilde ; B 0 -15 530 690 ; C -1 ; WX 759 ; N Ccedilla ; B 37 -220 759 737 ; C -1 ; WX 741 ; N Agrave ; B -75 0 716 947 ; C -1 ; WX 861 ; N onehalf ; B 17 -15 798 705 ; C -1 ; WX 833 ; N Eth ; B -47 0 796 722 ; C -1 ; WX 400 ; N degree ; B 86 419 372 705 ; C -1 ; WX 704 ; N Yacute ; B 13 0 775 947 ; C -1 ; WX 833 ; N Ocircumflex ; B 37 -15 796 930 ; C -1 ; WX 574 ; N oacute ; B 0 -15 530 722 ; C -1 ; WX 685 ; N mu ; B -89 -205 635 477 ; C -1 ; WX 606 ; N minus ; B 50 199 556 307 ; C -1 ; WX 574 ; N eth ; B 0 -15 530 752 ; C -1 ; WX 574 ; N odieresis ; B 0 -15 530 690 ; C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ; EndCharMetrics StartKernData StartKernPairs 239 KPX A y -33 KPX A w -25 KPX A v -10 KPX A u -15 KPX A quoteright -95 KPX A quotedblright -95 KPX A Y -70 KPX A W -84 KPX A V -100 KPX A U -32 KPX A T 5 KPX A Q 5 KPX A O 5 KPX A G 5 KPX A C 5 KPX B period 15 KPX B comma 15 KPX B U 15 KPX B A -11 KPX C A -5 KPX D period -11 KPX D comma -11 KPX D Y 6 KPX D W -11 KPX D V -18 KPX F r -27 KPX F period -91 KPX F o -47 KPX F i -41 KPX F e -41 KPX F comma -91 KPX F a -47 KPX F A -79 KPX J u -39 KPX J period -74 KPX J o -40 KPX J e -33 KPX J comma -74 KPX J a -40 KPX J A -30 KPX K y -48 KPX K u -4 KPX K o -4 KPX K e 18 KPX L y -30 KPX L quoteright -100 KPX L quotedblright -100 KPX L Y -55 KPX L W -69 KPX L V -97 KPX L T -75 KPX N period -49 KPX N comma -49 KPX O period -18 KPX O comma -18 KPX O X -18 KPX O W -15 KPX O V -24 KPX O A -5 KPX P period -100 KPX P o -40 KPX P e -33 KPX P comma -100 KPX P a -40 KPX P A -80 KPX R W -14 KPX R V -24 KPX S period -18 KPX S comma -18 KPX T y -30 KPX T w -30 KPX T u -22 KPX T r -9 KPX T period -55 KPX T o -40 KPX T i -22 KPX T hyphen -75 KPX T h -9 KPX T e -33 KPX T comma -55 KPX T a -40 KPX T O 11 KPX T A -60 KPX U period -25 KPX U comma -25 KPX U A -42 KPX V u -70 KPX V semicolon 6 KPX V period -94 KPX V o -71 KPX V i -35 KPX V hyphen -94 KPX V e -66 KPX V comma -94 KPX V colon -49 KPX V a -55 KPX V O -19 KPX V G -12 KPX V A -100 KPX W y -41 KPX W u -25 KPX W semicolon -22 KPX W period -86 KPX W o -33 KPX W i -27 KPX W hyphen -61 KPX W h 5 KPX W e -39 KPX W comma -86 KPX W colon -22 KPX W a -33 KPX W O -11 KPX W A -66 KPX Y u -58 KPX Y semicolon -55 KPX Y period -91 KPX Y o -77 KPX Y i -22 KPX Y hyphen -91 KPX Y e -71 KPX Y comma -91 KPX Y colon -55 KPX Y a -77 KPX Y A -79 KPX a y -8 KPX a w -8 KPX a v 6 KPX b y -6 KPX b v 8 KPX b period 6 KPX b comma 6 KPX c y -20 KPX c period -8 KPX c l -13 KPX c k -8 KPX c h -18 KPX c comma -8 KPX colon space -18 KPX comma space -18 KPX comma quoteright -18 KPX comma quotedblright -18 KPX d y -15 KPX d w -15 KPX e y -15 KPX e x -5 KPX e w -15 KPX e p -11 KPX e g -4 KPX e b -8 KPX f quoteright 105 KPX f quotedblright 105 KPX f period -28 KPX f o 7 KPX f l 7 KPX f i 7 KPX f e 14 KPX f dotlessi 7 KPX f comma -28 KPX f a 8 KPX g y -11 KPX g r 11 KPX g period -5 KPX g comma -5 KPX h y -20 KPX i v 7 KPX k y -15 KPX k o -22 KPX k e -16 KPX l y -7 KPX l w -7 KPX m y -20 KPX m u -11 KPX n y -20 KPX n v -7 KPX n u -11 KPX o y -11 KPX o w -8 KPX o v 6 KPX p y -4 KPX p period 8 KPX p comma 8 KPX period space -18 KPX period quoteright -18 KPX period quotedblright -18 KPX quotedblleft quoteleft 20 KPX quotedblleft A -60 KPX quotedblright space -18 KPX quoteleft A -80 KPX quoteright v -16 KPX quoteright t -22 KPX quoteright s -46 KPX quoteright r -9 KPX quoteright l -22 KPX quoteright d -41 KPX r y -20 KPX r v -7 KPX r u -11 KPX r t -11 KPX r semicolon 9 KPX r s -20 KPX r quoteright 9 KPX r period -90 KPX r p -17 KPX r o -11 KPX r l -14 KPX r k 9 KPX r i -14 KPX r hyphen -16 KPX r g -11 KPX r e -7 KPX r d -7 KPX r comma -90 KPX r colon 9 KPX r a -11 KPX s period 11 KPX s comma 11 KPX semicolon space -18 KPX space quotedblleft -18 KPX space Y -18 KPX space W -33 KPX space V -24 KPX space T -18 KPX space A -22 KPX v period -11 KPX v o -6 KPX v comma -11 KPX v a -6 KPX w period -17 KPX w o -14 KPX w e -8 KPX w comma -17 KPX w a -14 KPX x e 5 KPX y period -25 KPX y o 8 KPX y e 15 KPX y comma -25 KPX y a 8 KPX z e 4 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 259 225 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 259 225 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 259 225 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 259 225 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 229 245 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 259 225 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 296 225 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 296 225 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 296 225 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 296 225 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 116 225 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 116 225 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 116 225 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 116 225 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 326 225 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 315 225 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 315 225 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 315 225 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 315 225 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 315 225 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 206 225 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 340 225 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 340 225 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 340 225 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 340 225 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 246 225 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 225 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 226 225 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 167 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 167 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 167 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 167 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 167 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 167 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 93 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 93 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 93 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 93 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -2 -7 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -2 -7 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -2 -7 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -2 -7 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 121 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 121 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 121 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 121 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 121 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 74 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 93 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 93 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 63 -10 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/AvantGarde-Demi.afm���������������������������������������������������0000644�0001750�0001750�00000042540�11462120062�020027� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Mar 4 13:46:34 1991 Comment UniqueID 34370 Comment VMusage 24954 31846 FontName AvantGarde-Demi FullName ITC Avant Garde Gothic Demi FamilyName ITC Avant Garde Gothic Weight Demi ItalicAngle 0 IsFixedPitch false FontBBox -123 -251 1222 1021 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 740 XHeight 555 Ascender 740 Descender -185 StartCharMetrics 228 C 32 ; WX 280 ; N space ; B 0 0 0 0 ; C 33 ; WX 280 ; N exclam ; B 73 0 206 740 ; C 34 ; WX 360 ; N quotedbl ; B 19 444 341 740 ; C 35 ; WX 560 ; N numbersign ; B 29 0 525 700 ; C 36 ; WX 560 ; N dollar ; B 58 -86 501 857 ; C 37 ; WX 860 ; N percent ; B 36 -15 822 755 ; C 38 ; WX 680 ; N ampersand ; B 34 -15 665 755 ; C 39 ; WX 280 ; N quoteright ; B 72 466 205 740 ; C 40 ; WX 380 ; N parenleft ; B 74 -157 350 754 ; C 41 ; WX 380 ; N parenright ; B 37 -157 313 754 ; C 42 ; WX 440 ; N asterisk ; B 67 457 374 755 ; C 43 ; WX 600 ; N plus ; B 48 0 552 506 ; C 44 ; WX 280 ; N comma ; B 73 -141 206 133 ; C 45 ; WX 420 ; N hyphen ; B 71 230 349 348 ; C 46 ; WX 280 ; N period ; B 73 0 206 133 ; C 47 ; WX 460 ; N slash ; B 6 -100 454 740 ; C 48 ; WX 560 ; N zero ; B 32 -15 529 755 ; C 49 ; WX 560 ; N one ; B 137 0 363 740 ; C 50 ; WX 560 ; N two ; B 36 0 523 755 ; C 51 ; WX 560 ; N three ; B 28 -15 532 755 ; C 52 ; WX 560 ; N four ; B 15 0 545 740 ; C 53 ; WX 560 ; N five ; B 25 -15 535 740 ; C 54 ; WX 560 ; N six ; B 23 -15 536 739 ; C 55 ; WX 560 ; N seven ; B 62 0 498 740 ; C 56 ; WX 560 ; N eight ; B 33 -15 527 755 ; C 57 ; WX 560 ; N nine ; B 24 0 537 754 ; C 58 ; WX 280 ; N colon ; B 73 0 206 555 ; C 59 ; WX 280 ; N semicolon ; B 73 -141 206 555 ; C 60 ; WX 600 ; N less ; B 46 -8 554 514 ; C 61 ; WX 600 ; N equal ; B 48 81 552 425 ; C 62 ; WX 600 ; N greater ; B 46 -8 554 514 ; C 63 ; WX 560 ; N question ; B 38 0 491 755 ; C 64 ; WX 740 ; N at ; B 50 -12 750 712 ; C 65 ; WX 740 ; N A ; B 7 0 732 740 ; C 66 ; WX 580 ; N B ; B 70 0 551 740 ; C 67 ; WX 780 ; N C ; B 34 -15 766 755 ; C 68 ; WX 700 ; N D ; B 63 0 657 740 ; C 69 ; WX 520 ; N E ; B 61 0 459 740 ; C 70 ; WX 480 ; N F ; B 61 0 438 740 ; C 71 ; WX 840 ; N G ; B 27 -15 817 755 ; C 72 ; WX 680 ; N H ; B 71 0 610 740 ; C 73 ; WX 280 ; N I ; B 72 0 209 740 ; C 74 ; WX 480 ; N J ; B 2 -15 409 740 ; C 75 ; WX 620 ; N K ; B 89 0 620 740 ; C 76 ; WX 440 ; N L ; B 72 0 435 740 ; C 77 ; WX 900 ; N M ; B 63 0 837 740 ; C 78 ; WX 740 ; N N ; B 70 0 671 740 ; C 79 ; WX 840 ; N O ; B 33 -15 807 755 ; C 80 ; WX 560 ; N P ; B 72 0 545 740 ; C 81 ; WX 840 ; N Q ; B 32 -15 824 755 ; C 82 ; WX 580 ; N R ; B 64 0 565 740 ; C 83 ; WX 520 ; N S ; B 12 -15 493 755 ; C 84 ; WX 420 ; N T ; B 6 0 418 740 ; C 85 ; WX 640 ; N U ; B 55 -15 585 740 ; C 86 ; WX 700 ; N V ; B 8 0 695 740 ; C 87 ; WX 900 ; N W ; B 7 0 899 740 ; C 88 ; WX 680 ; N X ; B 4 0 676 740 ; C 89 ; WX 620 ; N Y ; B -2 0 622 740 ; C 90 ; WX 500 ; N Z ; B 19 0 481 740 ; C 91 ; WX 320 ; N bracketleft ; B 66 -157 284 754 ; C 92 ; WX 640 ; N backslash ; B 96 -100 544 740 ; C 93 ; WX 320 ; N bracketright ; B 36 -157 254 754 ; C 94 ; WX 600 ; N asciicircum ; B 73 375 527 740 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 280 ; N quoteleft ; B 72 466 205 740 ; C 97 ; WX 660 ; N a ; B 27 -18 613 574 ; C 98 ; WX 660 ; N b ; B 47 -18 632 740 ; C 99 ; WX 640 ; N c ; B 37 -18 610 574 ; C 100 ; WX 660 ; N d ; B 34 -18 618 740 ; C 101 ; WX 640 ; N e ; B 31 -18 610 577 ; C 102 ; WX 280 ; N f ; B 15 0 280 755 ; L i fi ; L l fl ; C 103 ; WX 660 ; N g ; B 32 -226 623 574 ; C 104 ; WX 600 ; N h ; B 54 0 546 740 ; C 105 ; WX 240 ; N i ; B 53 0 186 740 ; C 106 ; WX 260 ; N j ; B 16 -185 205 740 ; C 107 ; WX 580 ; N k ; B 80 0 571 740 ; C 108 ; WX 240 ; N l ; B 54 0 187 740 ; C 109 ; WX 940 ; N m ; B 54 0 887 574 ; C 110 ; WX 600 ; N n ; B 54 0 547 574 ; C 111 ; WX 640 ; N o ; B 25 -18 615 574 ; C 112 ; WX 660 ; N p ; B 47 -185 629 574 ; C 113 ; WX 660 ; N q ; B 31 -185 613 574 ; C 114 ; WX 320 ; N r ; B 63 0 317 574 ; C 115 ; WX 440 ; N s ; B 19 -18 421 574 ; C 116 ; WX 300 ; N t ; B 21 0 299 740 ; C 117 ; WX 600 ; N u ; B 50 -18 544 555 ; C 118 ; WX 560 ; N v ; B 3 0 556 555 ; C 119 ; WX 800 ; N w ; B 11 0 789 555 ; C 120 ; WX 560 ; N x ; B 3 0 556 555 ; C 121 ; WX 580 ; N y ; B 8 -185 571 555 ; C 122 ; WX 460 ; N z ; B 20 0 442 555 ; C 123 ; WX 340 ; N braceleft ; B -3 -191 317 747 ; C 124 ; WX 600 ; N bar ; B 233 -100 366 740 ; C 125 ; WX 340 ; N braceright ; B 23 -191 343 747 ; C 126 ; WX 600 ; N asciitilde ; B 67 160 533 347 ; C 161 ; WX 280 ; N exclamdown ; B 74 -185 207 555 ; C 162 ; WX 560 ; N cent ; B 43 39 517 715 ; C 163 ; WX 560 ; N sterling ; B -2 0 562 755 ; C 164 ; WX 160 ; N fraction ; B -123 0 282 740 ; C 165 ; WX 560 ; N yen ; B -10 0 570 740 ; C 166 ; WX 560 ; N florin ; B 0 -151 512 824 ; C 167 ; WX 560 ; N section ; B 28 -158 530 755 ; C 168 ; WX 560 ; N currency ; B 27 69 534 577 ; C 169 ; WX 220 ; N quotesingle ; B 44 444 177 740 ; C 170 ; WX 480 ; N quotedblleft ; B 70 466 410 740 ; C 171 ; WX 460 ; N guillemotleft ; B 61 108 400 469 ; C 172 ; WX 240 ; N guilsinglleft ; B 50 108 190 469 ; C 173 ; WX 240 ; N guilsinglright ; B 50 108 190 469 ; C 174 ; WX 520 ; N fi ; B 25 0 461 755 ; C 175 ; WX 520 ; N fl ; B 25 0 461 755 ; C 177 ; WX 500 ; N endash ; B 35 230 465 348 ; C 178 ; WX 560 ; N dagger ; B 51 -142 509 740 ; C 179 ; WX 560 ; N daggerdbl ; B 51 -142 509 740 ; C 180 ; WX 280 ; N periodcentered ; B 73 187 206 320 ; C 182 ; WX 600 ; N paragraph ; B -7 -103 607 740 ; C 183 ; WX 600 ; N bullet ; B 148 222 453 532 ; C 184 ; WX 280 ; N quotesinglbase ; B 72 -141 205 133 ; C 185 ; WX 480 ; N quotedblbase ; B 70 -141 410 133 ; C 186 ; WX 480 ; N quotedblright ; B 70 466 410 740 ; C 187 ; WX 460 ; N guillemotright ; B 61 108 400 469 ; C 188 ; WX 1000 ; N ellipsis ; B 100 0 899 133 ; C 189 ; WX 1280 ; N perthousand ; B 36 -15 1222 755 ; C 191 ; WX 560 ; N questiondown ; B 68 -200 521 555 ; C 193 ; WX 420 ; N grave ; B 50 624 329 851 ; C 194 ; WX 420 ; N acute ; B 91 624 370 849 ; C 195 ; WX 540 ; N circumflex ; B 71 636 470 774 ; C 196 ; WX 480 ; N tilde ; B 44 636 437 767 ; C 197 ; WX 420 ; N macron ; B 72 648 349 759 ; C 198 ; WX 480 ; N breve ; B 42 633 439 770 ; C 199 ; WX 280 ; N dotaccent ; B 74 636 207 769 ; C 200 ; WX 500 ; N dieresis ; B 78 636 422 769 ; C 202 ; WX 360 ; N ring ; B 73 619 288 834 ; C 203 ; WX 340 ; N cedilla ; B 98 -251 298 6 ; C 205 ; WX 700 ; N hungarumlaut ; B 132 610 609 862 ; C 206 ; WX 340 ; N ogonek ; B 79 -195 262 9 ; C 207 ; WX 540 ; N caron ; B 71 636 470 774 ; C 208 ; WX 1000 ; N emdash ; B 35 230 965 348 ; C 225 ; WX 900 ; N AE ; B -5 0 824 740 ; C 227 ; WX 360 ; N ordfeminine ; B 19 438 334 755 ; C 232 ; WX 480 ; N Lslash ; B 26 0 460 740 ; C 233 ; WX 840 ; N Oslash ; B 33 -71 807 814 ; C 234 ; WX 1060 ; N OE ; B 37 -15 1007 755 ; C 235 ; WX 360 ; N ordmasculine ; B 23 438 338 755 ; C 241 ; WX 1080 ; N ae ; B 29 -18 1048 574 ; C 245 ; WX 240 ; N dotlessi ; B 53 0 186 555 ; C 248 ; WX 320 ; N lslash ; B 34 0 305 740 ; C 249 ; WX 660 ; N oslash ; B 35 -50 625 608 ; C 250 ; WX 1080 ; N oe ; B 30 -18 1050 574 ; C 251 ; WX 600 ; N germandbls ; B 51 -18 585 755 ; C -1 ; WX 640 ; N ecircumflex ; B 31 -18 610 774 ; C -1 ; WX 640 ; N edieresis ; B 31 -18 610 769 ; C -1 ; WX 660 ; N aacute ; B 27 -18 613 849 ; C -1 ; WX 740 ; N registered ; B -12 -12 752 752 ; C -1 ; WX 240 ; N icircumflex ; B -79 0 320 774 ; C -1 ; WX 600 ; N udieresis ; B 50 -18 544 769 ; C -1 ; WX 640 ; N ograve ; B 25 -18 615 851 ; C -1 ; WX 600 ; N uacute ; B 50 -18 544 849 ; C -1 ; WX 600 ; N ucircumflex ; B 50 -18 544 774 ; C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ; C -1 ; WX 240 ; N igrave ; B -65 0 214 851 ; C -1 ; WX 280 ; N Icircumflex ; B -59 0 340 944 ; C -1 ; WX 640 ; N ccedilla ; B 37 -251 610 574 ; C -1 ; WX 660 ; N adieresis ; B 27 -18 613 769 ; C -1 ; WX 520 ; N Ecircumflex ; B 61 0 460 944 ; C -1 ; WX 440 ; N scaron ; B 19 -18 421 774 ; C -1 ; WX 660 ; N thorn ; B 47 -185 629 740 ; C -1 ; WX 1000 ; N trademark ; B 9 296 821 740 ; C -1 ; WX 640 ; N egrave ; B 31 -18 610 851 ; C -1 ; WX 336 ; N threesuperior ; B 8 287 328 749 ; C -1 ; WX 460 ; N zcaron ; B 20 0 455 774 ; C -1 ; WX 660 ; N atilde ; B 27 -18 613 767 ; C -1 ; WX 660 ; N aring ; B 27 -18 613 834 ; C -1 ; WX 640 ; N ocircumflex ; B 25 -18 615 774 ; C -1 ; WX 520 ; N Edieresis ; B 61 0 459 939 ; C -1 ; WX 840 ; N threequarters ; B 18 0 803 749 ; C -1 ; WX 580 ; N ydieresis ; B 8 -185 571 769 ; C -1 ; WX 580 ; N yacute ; B 8 -185 571 849 ; C -1 ; WX 240 ; N iacute ; B 26 0 305 849 ; C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ; C -1 ; WX 640 ; N Uacute ; B 55 -15 585 1019 ; C -1 ; WX 640 ; N eacute ; B 31 -18 610 849 ; C -1 ; WX 840 ; N Ograve ; B 33 -15 807 1021 ; C -1 ; WX 660 ; N agrave ; B 27 -18 613 851 ; C -1 ; WX 640 ; N Udieresis ; B 55 -15 585 939 ; C -1 ; WX 660 ; N acircumflex ; B 27 -18 613 774 ; C -1 ; WX 280 ; N Igrave ; B -45 0 234 1021 ; C -1 ; WX 336 ; N twosuperior ; B 13 296 322 749 ; C -1 ; WX 640 ; N Ugrave ; B 55 -15 585 1021 ; C -1 ; WX 840 ; N onequarter ; B 92 0 746 740 ; C -1 ; WX 640 ; N Ucircumflex ; B 55 -15 585 944 ; C -1 ; WX 520 ; N Scaron ; B 12 -15 493 944 ; C -1 ; WX 280 ; N Idieresis ; B -32 0 312 939 ; C -1 ; WX 240 ; N idieresis ; B -52 0 292 769 ; C -1 ; WX 520 ; N Egrave ; B 61 0 459 1021 ; C -1 ; WX 840 ; N Oacute ; B 33 -15 807 1019 ; C -1 ; WX 600 ; N divide ; B 48 -20 552 526 ; C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ; C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ; C -1 ; WX 840 ; N Odieresis ; B 33 -15 807 939 ; C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ; C -1 ; WX 740 ; N Ntilde ; B 70 0 671 937 ; C -1 ; WX 500 ; N Zcaron ; B 19 0 481 944 ; C -1 ; WX 560 ; N Thorn ; B 72 0 545 740 ; C -1 ; WX 280 ; N Iacute ; B 46 0 325 1019 ; C -1 ; WX 600 ; N plusminus ; B 48 -62 552 556 ; C -1 ; WX 600 ; N multiply ; B 59 12 541 494 ; C -1 ; WX 520 ; N Eacute ; B 61 0 459 1019 ; C -1 ; WX 620 ; N Ydieresis ; B -2 0 622 939 ; C -1 ; WX 336 ; N onesuperior ; B 72 296 223 740 ; C -1 ; WX 600 ; N ugrave ; B 50 -18 544 851 ; C -1 ; WX 600 ; N logicalnot ; B 48 108 552 425 ; C -1 ; WX 600 ; N ntilde ; B 54 0 547 767 ; C -1 ; WX 840 ; N Otilde ; B 33 -15 807 937 ; C -1 ; WX 640 ; N otilde ; B 25 -18 615 767 ; C -1 ; WX 780 ; N Ccedilla ; B 34 -251 766 755 ; C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ; C -1 ; WX 840 ; N onehalf ; B 62 0 771 740 ; C -1 ; WX 742 ; N Eth ; B 25 0 691 740 ; C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; C -1 ; WX 620 ; N Yacute ; B -2 0 622 1019 ; C -1 ; WX 840 ; N Ocircumflex ; B 33 -15 807 944 ; C -1 ; WX 640 ; N oacute ; B 25 -18 615 849 ; C -1 ; WX 576 ; N mu ; B 38 -187 539 555 ; C -1 ; WX 600 ; N minus ; B 48 193 552 313 ; C -1 ; WX 640 ; N eth ; B 27 -18 616 754 ; C -1 ; WX 640 ; N odieresis ; B 25 -18 615 769 ; C -1 ; WX 740 ; N copyright ; B -12 -12 752 752 ; C -1 ; WX 600 ; N brokenbar ; B 233 -100 366 740 ; EndCharMetrics StartKernData StartKernPairs 218 KPX A y -50 KPX A w -65 KPX A v -70 KPX A u -20 KPX A quoteright -90 KPX A Y -80 KPX A W -60 KPX A V -102 KPX A U -40 KPX A T -25 KPX A Q -50 KPX A O -50 KPX A G -40 KPX A C -40 KPX B A -10 KPX C A -40 KPX D period -20 KPX D comma -20 KPX D Y -45 KPX D W -25 KPX D V -50 KPX D A -50 KPX F period -129 KPX F e -20 KPX F comma -162 KPX F a -20 KPX F A -75 KPX G period -20 KPX G comma -20 KPX G Y -15 KPX J period -15 KPX J a -20 KPX J A -30 KPX K y -20 KPX K u -15 KPX K o -45 KPX K e -40 KPX K O -30 KPX L y -23 KPX L quoteright -30 KPX L quotedblright -30 KPX L Y -80 KPX L W -55 KPX L V -85 KPX L T -46 KPX O period -30 KPX O comma -30 KPX O Y -30 KPX O X -30 KPX O W -20 KPX O V -45 KPX O T -15 KPX O A -60 KPX P period -200 KPX P o -20 KPX P e -20 KPX P comma -220 KPX P a -20 KPX P A -100 KPX Q comma 20 KPX R W 25 KPX R V -10 KPX R U 25 KPX R T 40 KPX R O 25 KPX S comma 20 KPX T y -10 KPX T w -55 KPX T u -46 KPX T semicolon -29 KPX T r -30 KPX T period -91 KPX T o -49 KPX T hyphen -75 KPX T e -49 KPX T comma -82 KPX T colon -15 KPX T a -70 KPX T O -15 KPX T A -25 KPX U period -20 KPX U comma -20 KPX U A -40 KPX V u -55 KPX V semicolon -33 KPX V period -145 KPX V o -101 KPX V i -15 KPX V hyphen -75 KPX V e -101 KPX V comma -145 KPX V colon -18 KPX V a -95 KPX V O -45 KPX V G -20 KPX V A -102 KPX W y -15 KPX W u -30 KPX W semicolon -33 KPX W period -106 KPX W o -46 KPX W i -10 KPX W hyphen -35 KPX W e -47 KPX W comma -106 KPX W colon -15 KPX W a -50 KPX W O -20 KPX W A -58 KPX Y u -52 KPX Y semicolon -23 KPX Y period -145 KPX Y o -89 KPX Y hyphen -100 KPX Y e -89 KPX Y comma -145 KPX Y colon -10 KPX Y a -93 KPX Y O -30 KPX Y A -80 KPX a t 5 KPX a p 20 KPX a b 5 KPX b y -20 KPX b v -20 KPX c y -20 KPX c l -15 KPX c k -15 KPX comma space -50 KPX comma quoteright -70 KPX comma quotedblright -70 KPX e y -20 KPX e x -20 KPX e w -20 KPX e v -20 KPX f period -40 KPX f o -20 KPX f l -15 KPX f i -15 KPX f f -20 KPX f dotlessi -15 KPX f comma -40 KPX f a -15 KPX g i 25 KPX g a 15 KPX h y -30 KPX k y -5 KPX k o -30 KPX k e -40 KPX m y -20 KPX m u -20 KPX n y -15 KPX n v -30 KPX o y -20 KPX o x -30 KPX o w -20 KPX o v -30 KPX p y -20 KPX period space -50 KPX period quoteright -70 KPX period quotedblright -70 KPX quotedblleft A -50 KPX quotedblright space -50 KPX quoteleft quoteleft -80 KPX quoteleft A -50 KPX quoteright v -10 KPX quoteright t 10 KPX quoteright space -50 KPX quoteright s -15 KPX quoteright r -20 KPX quoteright quoteright -80 KPX quoteright d -50 KPX r y 40 KPX r v 40 KPX r u 20 KPX r t 20 KPX r s 20 KPX r q -8 KPX r period -73 KPX r p 20 KPX r o -15 KPX r n 21 KPX r m 15 KPX r l 20 KPX r k 5 KPX r i 20 KPX r hyphen -60 KPX r g 1 KPX r e -4 KPX r d -6 KPX r comma -75 KPX r c -7 KPX s period 20 KPX s comma 20 KPX space quoteleft -50 KPX space quotedblleft -50 KPX space Y -60 KPX space W -25 KPX space V -80 KPX space T -25 KPX space A -20 KPX v period -90 KPX v o -20 KPX v e -20 KPX v comma -90 KPX v a -30 KPX w period -90 KPX w o -30 KPX w e -20 KPX w comma -90 KPX w a -30 KPX x e -20 KPX y period -100 KPX y o -30 KPX y e -20 KPX y comma -100 KPX y c -35 KPX y a -30 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 100 170 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 120 170 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 170 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 190 135 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 170 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 50 170 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex -10 170 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 10 170 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 50 170 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -45 170 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -130 170 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -110 170 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -95 170 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 170 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 170 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 170 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 170 170 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 170 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 170 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron -10 170 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 145 170 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 50 170 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 70 170 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 75 170 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 135 170 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 60 170 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 5 170 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/NewCenturySchlbk-Italic.afm�������������������������������������������0000644�0001750�0001750�00000042061�11462120062�021572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue May 28 16:40:04 1991 Comment UniqueID 35028 Comment VMusage 31423 38315 FontName NewCenturySchlbk-Italic FullName New Century Schoolbook Italic FamilyName New Century Schoolbook Weight Medium ItalicAngle -16 IsFixedPitch false FontBBox -166 -250 994 958 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 722 XHeight 466 Ascender 737 Descender -205 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 17 -15 303 737 ; C 34 ; WX 400 ; N quotedbl ; B 127 463 363 737 ; C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ; C 36 ; WX 556 ; N dollar ; B 4 -142 536 808 ; C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ; C 38 ; WX 852 ; N ampersand ; B 24 -15 773 737 ; C 39 ; WX 204 ; N quoteright ; B 39 463 229 737 ; C 40 ; WX 333 ; N parenleft ; B 53 -117 411 745 ; C 41 ; WX 333 ; N parenright ; B -93 -117 265 745 ; C 42 ; WX 500 ; N asterisk ; B 80 318 500 737 ; C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; C 44 ; WX 278 ; N comma ; B -39 -165 151 109 ; C 45 ; WX 333 ; N hyphen ; B 32 202 259 274 ; C 46 ; WX 278 ; N period ; B 17 -15 141 109 ; C 47 ; WX 606 ; N slash ; B 132 -15 474 737 ; C 48 ; WX 556 ; N zero ; B 30 -15 526 705 ; C 49 ; WX 556 ; N one ; B 50 0 459 705 ; C 50 ; WX 556 ; N two ; B -37 0 506 705 ; C 51 ; WX 556 ; N three ; B -2 -15 506 705 ; C 52 ; WX 556 ; N four ; B -8 0 512 705 ; C 53 ; WX 556 ; N five ; B 4 -15 540 705 ; C 54 ; WX 556 ; N six ; B 36 -15 548 705 ; C 55 ; WX 556 ; N seven ; B 69 -15 561 705 ; C 56 ; WX 556 ; N eight ; B 6 -15 526 705 ; C 57 ; WX 556 ; N nine ; B 8 -15 520 705 ; C 58 ; WX 278 ; N colon ; B 17 -15 229 466 ; C 59 ; WX 278 ; N semicolon ; B -39 -165 229 466 ; C 60 ; WX 606 ; N less ; B 36 -8 542 514 ; C 61 ; WX 606 ; N equal ; B 50 117 556 389 ; C 62 ; WX 606 ; N greater ; B 64 -8 570 514 ; C 63 ; WX 444 ; N question ; B 102 -15 417 737 ; C 64 ; WX 747 ; N at ; B -2 -15 750 737 ; C 65 ; WX 704 ; N A ; B -87 0 668 737 ; C 66 ; WX 722 ; N B ; B -33 0 670 722 ; C 67 ; WX 722 ; N C ; B 40 -15 712 737 ; C 68 ; WX 778 ; N D ; B -33 0 738 722 ; C 69 ; WX 722 ; N E ; B -33 0 700 722 ; C 70 ; WX 667 ; N F ; B -33 0 700 722 ; C 71 ; WX 778 ; N G ; B 40 -15 763 737 ; C 72 ; WX 833 ; N H ; B -33 0 866 722 ; C 73 ; WX 407 ; N I ; B -33 0 435 722 ; C 74 ; WX 611 ; N J ; B -14 -15 651 722 ; C 75 ; WX 741 ; N K ; B -33 0 816 722 ; C 76 ; WX 667 ; N L ; B -33 0 627 722 ; C 77 ; WX 944 ; N M ; B -33 0 977 722 ; C 78 ; WX 815 ; N N ; B -51 -15 866 722 ; C 79 ; WX 778 ; N O ; B 40 -15 738 737 ; C 80 ; WX 667 ; N P ; B -33 0 667 722 ; C 81 ; WX 778 ; N Q ; B 40 -190 738 737 ; C 82 ; WX 741 ; N R ; B -45 -15 692 722 ; C 83 ; WX 667 ; N S ; B -6 -15 638 737 ; C 84 ; WX 685 ; N T ; B 40 0 725 722 ; C 85 ; WX 815 ; N U ; B 93 -15 867 722 ; C 86 ; WX 704 ; N V ; B 36 -10 779 722 ; C 87 ; WX 926 ; N W ; B 53 -10 978 722 ; C 88 ; WX 704 ; N X ; B -75 0 779 722 ; C 89 ; WX 685 ; N Y ; B 31 0 760 722 ; C 90 ; WX 667 ; N Z ; B -25 0 667 722 ; C 91 ; WX 333 ; N bracketleft ; B -55 -109 388 737 ; C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ; C 93 ; WX 333 ; N bracketright ; B -77 -109 366 737 ; C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 204 ; N quoteleft ; B 39 463 229 737 ; C 97 ; WX 574 ; N a ; B 2 -15 524 466 ; C 98 ; WX 556 ; N b ; B 32 -15 488 737 ; C 99 ; WX 444 ; N c ; B 2 -15 394 466 ; C 100 ; WX 611 ; N d ; B 2 -15 585 737 ; C 101 ; WX 444 ; N e ; B -6 -15 388 466 ; C 102 ; WX 333 ; N f ; B -68 -205 470 737 ; L i fi ; L l fl ; C 103 ; WX 537 ; N g ; B -79 -205 523 497 ; C 104 ; WX 611 ; N h ; B 14 -15 562 737 ; C 105 ; WX 333 ; N i ; B 29 -15 282 715 ; C 106 ; WX 315 ; N j ; B -166 -205 318 715 ; C 107 ; WX 556 ; N k ; B 0 -15 497 737 ; C 108 ; WX 333 ; N l ; B 14 -15 292 737 ; C 109 ; WX 889 ; N m ; B 14 -15 840 466 ; C 110 ; WX 611 ; N n ; B 14 -15 562 466 ; C 111 ; WX 500 ; N o ; B 2 -15 450 466 ; C 112 ; WX 574 ; N p ; B -101 -205 506 466 ; C 113 ; WX 556 ; N q ; B 2 -205 500 466 ; C 114 ; WX 444 ; N r ; B 10 0 434 466 ; C 115 ; WX 444 ; N s ; B 2 -15 394 466 ; C 116 ; WX 352 ; N t ; B 24 -15 328 619 ; C 117 ; WX 611 ; N u ; B 44 -15 556 466 ; C 118 ; WX 519 ; N v ; B 31 -15 447 466 ; C 119 ; WX 778 ; N w ; B 31 -15 706 466 ; C 120 ; WX 500 ; N x ; B -33 -15 471 466 ; C 121 ; WX 500 ; N y ; B -83 -205 450 466 ; C 122 ; WX 463 ; N z ; B -33 -15 416 466 ; C 123 ; WX 333 ; N braceleft ; B 38 -109 394 737 ; C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ; C 125 ; WX 333 ; N braceright ; B -87 -109 269 737 ; C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ; C 161 ; WX 333 ; N exclamdown ; B -22 -205 264 547 ; C 162 ; WX 556 ; N cent ; B 62 -144 486 580 ; C 163 ; WX 556 ; N sterling ; B -13 -15 544 705 ; C 164 ; WX 167 ; N fraction ; B -134 -15 301 705 ; C 165 ; WX 556 ; N yen ; B 40 0 624 690 ; C 166 ; WX 556 ; N florin ; B -58 -205 569 737 ; C 167 ; WX 500 ; N section ; B -10 -147 480 737 ; C 168 ; WX 556 ; N currency ; B 26 93 530 597 ; C 169 ; WX 278 ; N quotesingle ; B 151 463 237 737 ; C 170 ; WX 389 ; N quotedblleft ; B 39 463 406 737 ; C 171 ; WX 426 ; N guillemotleft ; B -15 74 402 402 ; C 172 ; WX 333 ; N guilsinglleft ; B 40 74 259 402 ; C 173 ; WX 333 ; N guilsinglright ; B 40 74 259 402 ; C 174 ; WX 611 ; N fi ; B -68 -205 555 737 ; C 175 ; WX 611 ; N fl ; B -68 -205 587 737 ; C 177 ; WX 500 ; N endash ; B -27 208 487 268 ; C 178 ; WX 500 ; N dagger ; B 51 -147 506 737 ; C 179 ; WX 500 ; N daggerdbl ; B -54 -147 506 737 ; C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ; C 182 ; WX 650 ; N paragraph ; B 48 -132 665 722 ; C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; C 184 ; WX 204 ; N quotesinglbase ; B -78 -165 112 109 ; C 185 ; WX 389 ; N quotedblbase ; B -78 -165 289 109 ; C 186 ; WX 389 ; N quotedblright ; B 39 463 406 737 ; C 187 ; WX 426 ; N guillemotright ; B -15 74 402 402 ; C 188 ; WX 1000 ; N ellipsis ; B 59 -15 849 109 ; C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ; C 191 ; WX 444 ; N questiondown ; B -3 -205 312 547 ; C 193 ; WX 333 ; N grave ; B 71 518 262 690 ; C 194 ; WX 333 ; N acute ; B 132 518 355 690 ; C 195 ; WX 333 ; N circumflex ; B 37 518 331 690 ; C 196 ; WX 333 ; N tilde ; B 52 547 383 649 ; C 197 ; WX 333 ; N macron ; B 52 560 363 610 ; C 198 ; WX 333 ; N breve ; B 69 518 370 677 ; C 199 ; WX 333 ; N dotaccent ; B 146 544 248 646 ; C 200 ; WX 333 ; N dieresis ; B 59 544 359 646 ; C 202 ; WX 333 ; N ring ; B 114 512 314 712 ; C 203 ; WX 333 ; N cedilla ; B 3 -215 215 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 32 518 455 690 ; C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ; C 207 ; WX 333 ; N caron ; B 73 518 378 690 ; C 208 ; WX 1000 ; N emdash ; B -27 208 987 268 ; C 225 ; WX 870 ; N AE ; B -87 0 888 722 ; C 227 ; WX 422 ; N ordfeminine ; B 72 416 420 705 ; C 232 ; WX 667 ; N Lslash ; B -33 0 627 722 ; C 233 ; WX 778 ; N Oslash ; B 16 -68 748 780 ; C 234 ; WX 981 ; N OE ; B 40 0 975 722 ; C 235 ; WX 372 ; N ordmasculine ; B 66 416 370 705 ; C 241 ; WX 722 ; N ae ; B -18 -15 666 466 ; C 245 ; WX 333 ; N dotlessi ; B 29 -15 282 466 ; C 248 ; WX 333 ; N lslash ; B -25 -15 340 737 ; C 249 ; WX 500 ; N oslash ; B 2 -121 450 549 ; C 250 ; WX 778 ; N oe ; B 2 -15 722 466 ; C 251 ; WX 556 ; N germandbls ; B -76 -205 525 737 ; C -1 ; WX 444 ; N ecircumflex ; B -6 -15 388 690 ; C -1 ; WX 444 ; N edieresis ; B -6 -15 415 646 ; C -1 ; WX 574 ; N aacute ; B 2 -15 524 690 ; C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ; C -1 ; WX 333 ; N icircumflex ; B 29 -15 331 690 ; C -1 ; WX 611 ; N udieresis ; B 44 -15 556 646 ; C -1 ; WX 500 ; N ograve ; B 2 -15 450 690 ; C -1 ; WX 611 ; N uacute ; B 44 -15 556 690 ; C -1 ; WX 611 ; N ucircumflex ; B 44 -15 556 690 ; C -1 ; WX 704 ; N Aacute ; B -87 0 668 946 ; C -1 ; WX 333 ; N igrave ; B 29 -15 282 690 ; C -1 ; WX 407 ; N Icircumflex ; B -33 0 435 946 ; C -1 ; WX 444 ; N ccedilla ; B 2 -215 394 466 ; C -1 ; WX 574 ; N adieresis ; B 2 -15 524 646 ; C -1 ; WX 722 ; N Ecircumflex ; B -33 0 700 946 ; C -1 ; WX 444 ; N scaron ; B 2 -15 434 690 ; C -1 ; WX 574 ; N thorn ; B -101 -205 506 737 ; C -1 ; WX 950 ; N trademark ; B 32 318 968 722 ; C -1 ; WX 444 ; N egrave ; B -6 -15 388 690 ; C -1 ; WX 333 ; N threesuperior ; B 22 273 359 705 ; C -1 ; WX 463 ; N zcaron ; B -33 -15 443 690 ; C -1 ; WX 574 ; N atilde ; B 2 -15 524 649 ; C -1 ; WX 574 ; N aring ; B 2 -15 524 712 ; C -1 ; WX 500 ; N ocircumflex ; B 2 -15 450 690 ; C -1 ; WX 722 ; N Edieresis ; B -33 0 700 902 ; C -1 ; WX 834 ; N threequarters ; B 22 -15 782 705 ; C -1 ; WX 500 ; N ydieresis ; B -83 -205 450 646 ; C -1 ; WX 500 ; N yacute ; B -83 -205 450 690 ; C -1 ; WX 333 ; N iacute ; B 29 -15 355 690 ; C -1 ; WX 704 ; N Acircumflex ; B -87 0 668 946 ; C -1 ; WX 815 ; N Uacute ; B 93 -15 867 946 ; C -1 ; WX 444 ; N eacute ; B -6 -15 411 690 ; C -1 ; WX 778 ; N Ograve ; B 40 -15 738 946 ; C -1 ; WX 574 ; N agrave ; B 2 -15 524 690 ; C -1 ; WX 815 ; N Udieresis ; B 93 -15 867 902 ; C -1 ; WX 574 ; N acircumflex ; B 2 -15 524 690 ; C -1 ; WX 407 ; N Igrave ; B -33 0 435 946 ; C -1 ; WX 333 ; N twosuperior ; B 0 282 359 705 ; C -1 ; WX 815 ; N Ugrave ; B 93 -15 867 946 ; C -1 ; WX 834 ; N onequarter ; B 34 -15 782 705 ; C -1 ; WX 815 ; N Ucircumflex ; B 93 -15 867 946 ; C -1 ; WX 667 ; N Scaron ; B -6 -15 638 946 ; C -1 ; WX 407 ; N Idieresis ; B -33 0 456 902 ; C -1 ; WX 333 ; N idieresis ; B 29 -15 359 646 ; C -1 ; WX 722 ; N Egrave ; B -33 0 700 946 ; C -1 ; WX 778 ; N Oacute ; B 40 -15 738 946 ; C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ; C -1 ; WX 704 ; N Atilde ; B -87 0 668 905 ; C -1 ; WX 704 ; N Aring ; B -87 0 668 958 ; C -1 ; WX 778 ; N Odieresis ; B 40 -15 738 902 ; C -1 ; WX 704 ; N Adieresis ; B -87 0 668 902 ; C -1 ; WX 815 ; N Ntilde ; B -51 -15 866 905 ; C -1 ; WX 667 ; N Zcaron ; B -25 0 667 946 ; C -1 ; WX 667 ; N Thorn ; B -33 0 627 722 ; C -1 ; WX 407 ; N Iacute ; B -33 0 452 946 ; C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ; C -1 ; WX 722 ; N Eacute ; B -33 0 700 946 ; C -1 ; WX 685 ; N Ydieresis ; B 31 0 760 902 ; C -1 ; WX 333 ; N onesuperior ; B 34 282 311 705 ; C -1 ; WX 611 ; N ugrave ; B 44 -15 556 690 ; C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ; C -1 ; WX 611 ; N ntilde ; B 14 -15 562 649 ; C -1 ; WX 778 ; N Otilde ; B 40 -15 738 905 ; C -1 ; WX 500 ; N otilde ; B 2 -15 467 649 ; C -1 ; WX 722 ; N Ccedilla ; B 40 -215 712 737 ; C -1 ; WX 704 ; N Agrave ; B -87 0 668 946 ; C -1 ; WX 834 ; N onehalf ; B 34 -15 776 705 ; C -1 ; WX 778 ; N Eth ; B -33 0 738 722 ; C -1 ; WX 400 ; N degree ; B 86 419 372 705 ; C -1 ; WX 685 ; N Yacute ; B 31 0 760 946 ; C -1 ; WX 778 ; N Ocircumflex ; B 40 -15 738 946 ; C -1 ; WX 500 ; N oacute ; B 2 -15 450 690 ; C -1 ; WX 611 ; N mu ; B -60 -205 556 466 ; C -1 ; WX 606 ; N minus ; B 50 217 556 289 ; C -1 ; WX 500 ; N eth ; B 2 -15 450 737 ; C -1 ; WX 500 ; N odieresis ; B 2 -15 450 646 ; C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ; C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ; EndCharMetrics StartKernData StartKernPairs 181 KPX A y -55 KPX A w -18 KPX A v -18 KPX A u -18 KPX A quoteright -125 KPX A quotedblright -125 KPX A Y -55 KPX A W -74 KPX A V -74 KPX A U -37 KPX A T -30 KPX A Q -18 KPX A O -18 KPX A G -18 KPX A C -18 KPX B period -50 KPX B comma -50 KPX C period -50 KPX C comma -50 KPX D period -50 KPX D comma -50 KPX D Y -18 KPX D W -18 KPX D V -18 KPX F r -55 KPX F period -125 KPX F o -55 KPX F i -10 KPX F e -55 KPX F comma -125 KPX F a -55 KPX F A -35 KPX G period -50 KPX G comma -50 KPX J u -18 KPX J period -100 KPX J o -37 KPX J e -37 KPX J comma -100 KPX J a -37 KPX J A -18 KPX L y -50 KPX L quoteright -125 KPX L quotedblright -125 KPX L Y -100 KPX L W -100 KPX L V -100 KPX L T -100 KPX N period -60 KPX N comma -60 KPX O period -50 KPX O comma -50 KPX O Y -18 KPX O X -18 KPX O V -18 KPX O T 18 KPX P period -125 KPX P o -55 KPX P e -55 KPX P comma -125 KPX P a -55 KPX P A -50 KPX Q period -20 KPX Q comma -20 KPX R Y -18 KPX R W -18 KPX R V -18 KPX R U -18 KPX S period -50 KPX S comma -50 KPX T y -50 KPX T w -50 KPX T u -50 KPX T semicolon -50 KPX T r -50 KPX T period -100 KPX T o -74 KPX T i -18 KPX T hyphen -100 KPX T h -25 KPX T e -74 KPX T comma -100 KPX T colon -50 KPX T a -74 KPX T O 18 KPX U period -100 KPX U comma -100 KPX U A -18 KPX V u -75 KPX V semicolon -75 KPX V period -100 KPX V o -75 KPX V i -50 KPX V hyphen -100 KPX V e -75 KPX V comma -100 KPX V colon -75 KPX V a -75 KPX V A -37 KPX W y -55 KPX W u -55 KPX W semicolon -75 KPX W period -100 KPX W o -55 KPX W i -20 KPX W hyphen -75 KPX W h -20 KPX W e -55 KPX W comma -100 KPX W colon -75 KPX W a -55 KPX W A -55 KPX Y u -100 KPX Y semicolon -75 KPX Y period -100 KPX Y o -100 KPX Y i -25 KPX Y hyphen -100 KPX Y e -100 KPX Y comma -100 KPX Y colon -75 KPX Y a -100 KPX Y A -55 KPX b period -50 KPX b comma -50 KPX b b -10 KPX c period -50 KPX c k -18 KPX c h -18 KPX c comma -50 KPX colon space -37 KPX comma space -37 KPX comma quoteright -37 KPX comma quotedblright -37 KPX e period -37 KPX e comma -37 KPX f quoteright 75 KPX f quotedblright 75 KPX f period -75 KPX f o -10 KPX f comma -75 KPX g period -50 KPX g comma -50 KPX l y -10 KPX o period -50 KPX o comma -50 KPX p period -50 KPX p comma -50 KPX period space -37 KPX period quoteright -37 KPX period quotedblright -37 KPX quotedblleft A -75 KPX quotedblright space -37 KPX quoteleft quoteleft -37 KPX quoteleft A -75 KPX quoteright s -25 KPX quoteright quoteright -37 KPX quoteright d -37 KPX r semicolon -25 KPX r s -10 KPX r period -125 KPX r k -18 KPX r hyphen -75 KPX r comma -125 KPX r colon -25 KPX s period -50 KPX s comma -50 KPX semicolon space -37 KPX space quoteleft -37 KPX space quotedblleft -37 KPX space Y -37 KPX space W -37 KPX space V -37 KPX space T -37 KPX space A -37 KPX v period -75 KPX v comma -75 KPX w period -75 KPX w comma -75 KPX y period -75 KPX y comma -75 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 246 256 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 246 256 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 231 256 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 246 256 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 216 246 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 231 256 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 255 256 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 255 256 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 255 256 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 255 256 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 97 256 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 97 256 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 97 256 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 97 256 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 301 256 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 256 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 283 256 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 283 256 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 283 256 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 283 256 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 227 256 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 301 256 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 301 256 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 301 256 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 301 256 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 256 256 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 256 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 227 256 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 121 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 121 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 121 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 121 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 121 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 121 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 65 0 ; EndComposites EndFontMetrics �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Condensed.afm�����������������������������������������������0000644�0001750�0001750�00000036476�11462120062�020756� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Wed Sep 4 17:26:31 1991 Comment UniqueID 36179 Comment VMusage 26415 33307 FontName Helvetica-Condensed FullName Helvetica Condensed Medium FamilyName Helvetica Weight Medium ItalicAngle 0 IsFixedPitch false FontBBox -174 -250 1071 990 UnderlinePosition -100 UnderlineThickness 50 Version 001.003 Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 750 XHeight 556 Ascender 750 Descender -188 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 121 0 212 750 ; C 34 ; WX 250 ; N quotedbl ; B 44 513 207 739 ; C 35 ; WX 500 ; N numbersign ; B 5 0 495 750 ; C 36 ; WX 500 ; N dollar ; B 35 -116 465 815 ; C 37 ; WX 833 ; N percent ; B 55 -15 756 750 ; C 38 ; WX 667 ; N ampersand ; B 75 -18 620 750 ; C 39 ; WX 222 ; N quoteright ; B 64 504 158 750 ; C 40 ; WX 333 ; N parenleft ; B 76 -215 289 750 ; C 41 ; WX 333 ; N parenright ; B 44 -215 257 750 ; C 42 ; WX 500 ; N asterisk ; B 96 455 405 750 ; C 43 ; WX 500 ; N plus ; B 44 0 457 505 ; C 44 ; WX 250 ; N comma ; B 80 -146 171 100 ; C 45 ; WX 333 ; N hyphen ; B 45 275 288 358 ; C 46 ; WX 250 ; N period ; B 80 0 171 100 ; C 47 ; WX 278 ; N slash ; B -13 -27 291 750 ; C 48 ; WX 500 ; N zero ; B 46 -15 455 750 ; C 49 ; WX 500 ; N one ; B 74 0 317 750 ; C 50 ; WX 500 ; N two ; B 44 0 447 750 ; C 51 ; WX 500 ; N three ; B 38 -15 447 750 ; C 52 ; WX 500 ; N four ; B 28 0 451 750 ; C 53 ; WX 500 ; N five ; B 43 -15 446 735 ; C 54 ; WX 500 ; N six ; B 43 -15 458 750 ; C 55 ; WX 500 ; N seven ; B 44 0 456 735 ; C 56 ; WX 500 ; N eight ; B 46 -15 454 750 ; C 57 ; WX 500 ; N nine ; B 43 -15 458 750 ; C 58 ; WX 250 ; N colon ; B 80 0 171 547 ; C 59 ; WX 250 ; N semicolon ; B 80 -146 171 547 ; C 60 ; WX 500 ; N less ; B 42 -10 459 518 ; C 61 ; WX 500 ; N equal ; B 44 124 457 384 ; C 62 ; WX 500 ; N greater ; B 42 -10 459 518 ; C 63 ; WX 500 ; N question ; B 60 0 462 750 ; C 64 ; WX 800 ; N at ; B 36 -15 764 750 ; C 65 ; WX 556 ; N A ; B 11 0 546 750 ; C 66 ; WX 556 ; N B ; B 80 0 503 750 ; C 67 ; WX 556 ; N C ; B 53 -18 503 765 ; C 68 ; WX 611 ; N D ; B 82 0 548 750 ; C 69 ; WX 500 ; N E ; B 74 0 451 750 ; C 70 ; WX 444 ; N F ; B 74 0 426 750 ; C 71 ; WX 611 ; N G ; B 54 -18 532 765 ; C 72 ; WX 611 ; N H ; B 79 0 532 750 ; C 73 ; WX 278 ; N I ; B 98 0 181 750 ; C 74 ; WX 444 ; N J ; B 21 -15 368 750 ; C 75 ; WX 556 ; N K ; B 79 0 546 750 ; C 76 ; WX 500 ; N L ; B 83 0 472 750 ; C 77 ; WX 778 ; N M ; B 76 0 702 750 ; C 78 ; WX 611 ; N N ; B 77 0 534 750 ; C 79 ; WX 611 ; N O ; B 59 -18 553 765 ; C 80 ; WX 556 ; N P ; B 86 0 519 750 ; C 81 ; WX 611 ; N Q ; B 59 -34 582 765 ; C 82 ; WX 611 ; N R ; B 86 0 565 750 ; C 83 ; WX 556 ; N S ; B 51 -18 505 765 ; C 84 ; WX 500 ; N T ; B 15 0 486 750 ; C 85 ; WX 611 ; N U ; B 81 -18 531 750 ; C 86 ; WX 556 ; N V ; B 11 0 545 750 ; C 87 ; WX 833 ; N W ; B 17 0 816 750 ; C 88 ; WX 556 ; N X ; B 17 0 539 750 ; C 89 ; WX 556 ; N Y ; B 11 0 546 750 ; C 90 ; WX 500 ; N Z ; B 28 0 473 750 ; C 91 ; WX 333 ; N bracketleft ; B 100 -209 275 750 ; C 92 ; WX 250 ; N backslash ; B -31 0 281 750 ; C 93 ; WX 333 ; N bracketright ; B 58 -209 233 750 ; C 94 ; WX 500 ; N asciicircum ; B 70 333 431 750 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 222 ; N quoteleft ; B 64 521 158 767 ; C 97 ; WX 444 ; N a ; B 31 -15 417 571 ; C 98 ; WX 500 ; N b ; B 75 -15 447 750 ; C 99 ; WX 444 ; N c ; B 44 -15 405 571 ; C 100 ; WX 500 ; N d ; B 48 -15 424 750 ; C 101 ; WX 444 ; N e ; B 43 -15 395 571 ; C 102 ; WX 278 ; N f ; B 12 0 259 752 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 45 -189 426 571 ; C 104 ; WX 500 ; N h ; B 73 0 428 750 ; C 105 ; WX 222 ; N i ; B 72 0 151 750 ; C 106 ; WX 222 ; N j ; B 13 -190 154 750 ; C 107 ; WX 444 ; N k ; B 69 0 439 750 ; C 108 ; WX 222 ; N l ; B 72 0 151 750 ; C 109 ; WX 778 ; N m ; B 76 0 703 571 ; C 110 ; WX 500 ; N n ; B 73 0 428 571 ; C 111 ; WX 500 ; N o ; B 51 -15 449 571 ; C 112 ; WX 500 ; N p ; B 72 -188 447 571 ; C 113 ; WX 500 ; N q ; B 55 -184 426 571 ; C 114 ; WX 333 ; N r ; B 81 0 322 563 ; C 115 ; WX 444 ; N s ; B 43 -15 400 571 ; C 116 ; WX 278 ; N t ; B 9 0 257 707 ; C 117 ; WX 500 ; N u ; B 77 -15 424 556 ; C 118 ; WX 444 ; N v ; B 13 0 431 556 ; C 119 ; WX 667 ; N w ; B 19 0 649 556 ; C 120 ; WX 444 ; N x ; B 9 0 436 556 ; C 121 ; WX 444 ; N y ; B 5 -190 425 556 ; C 122 ; WX 389 ; N z ; B 24 0 366 556 ; C 123 ; WX 274 ; N braceleft ; B 7 -95 266 750 ; C 124 ; WX 250 ; N bar ; B 93 -250 157 750 ; C 125 ; WX 274 ; N braceright ; B 8 -95 267 750 ; C 126 ; WX 500 ; N asciitilde ; B 44 166 457 345 ; C 161 ; WX 333 ; N exclamdown ; B 121 -179 212 571 ; C 162 ; WX 500 ; N cent ; B 58 -137 418 667 ; C 163 ; WX 500 ; N sterling ; B 30 -15 485 750 ; C 164 ; WX 167 ; N fraction ; B -174 0 341 750 ; C 165 ; WX 500 ; N yen ; B -17 0 518 750 ; C 166 ; WX 500 ; N florin ; B 10 -192 488 750 ; C 167 ; WX 500 ; N section ; B 35 -208 466 750 ; C 168 ; WX 500 ; N currency ; B 24 50 475 553 ; C 169 ; WX 250 ; N quotesingle ; B 99 513 151 739 ; C 170 ; WX 389 ; N quotedblleft ; B 62 521 327 767 ; C 171 ; WX 500 ; N guillemotleft ; B 85 125 415 495 ; C 172 ; WX 278 ; N guilsinglleft ; B 64 125 215 495 ; C 173 ; WX 278 ; N guilsinglright ; B 63 125 214 495 ; C 174 ; WX 500 ; N fi ; B 12 0 427 752 ; C 175 ; WX 500 ; N fl ; B 12 0 425 752 ; C 177 ; WX 500 ; N endash ; B 0 275 500 345 ; C 178 ; WX 500 ; N dagger ; B 40 -176 461 750 ; C 179 ; WX 500 ; N daggerdbl ; B 39 -176 462 750 ; C 180 ; WX 250 ; N periodcentered ; B 80 204 171 304 ; C 182 ; WX 440 ; N paragraph ; B 0 -116 391 750 ; C 183 ; WX 333 ; N bullet ; B 15 222 318 529 ; C 184 ; WX 222 ; N quotesinglbase ; B 64 -146 158 100 ; C 185 ; WX 389 ; N quotedblbase ; B 62 -146 327 100 ; C 186 ; WX 389 ; N quotedblright ; B 62 504 327 750 ; C 187 ; WX 500 ; N guillemotright ; B 85 125 415 495 ; C 188 ; WX 1000 ; N ellipsis ; B 121 0 878 100 ; C 189 ; WX 1111 ; N perthousand ; B 47 -16 1071 750 ; C 191 ; WX 500 ; N questiondown ; B 38 -190 440 559 ; C 193 ; WX 333 ; N grave ; B 35 624 233 765 ; C 194 ; WX 333 ; N acute ; B 100 624 298 765 ; C 195 ; WX 333 ; N circumflex ; B 21 624 313 765 ; C 196 ; WX 333 ; N tilde ; B -3 633 337 749 ; C 197 ; WX 333 ; N macron ; B 10 657 323 715 ; C 198 ; WX 333 ; N breve ; B 12 629 321 765 ; C 199 ; WX 250 ; N dotaccent ; B 86 650 165 750 ; C 200 ; WX 333 ; N dieresis ; B 52 650 281 750 ; C 202 ; WX 250 ; N ring ; B 23 593 227 796 ; C 203 ; WX 333 ; N cedilla ; B 66 -224 281 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 61 624 440 765 ; C 206 ; WX 333 ; N ogonek ; B 0 -191 208 13 ; C 207 ; WX 333 ; N caron ; B 21 624 313 765 ; C 208 ; WX 1000 ; N emdash ; B 0 275 1000 345 ; C 225 ; WX 833 ; N AE ; B 0 0 785 750 ; C 227 ; WX 300 ; N ordfeminine ; B 25 413 276 765 ; C 232 ; WX 500 ; N Lslash ; B -13 0 472 750 ; C 233 ; WX 611 ; N Oslash ; B 29 -43 573 796 ; C 234 ; WX 833 ; N OE ; B 56 -18 787 765 ; C 235 ; WX 300 ; N ordmasculine ; B 20 413 279 765 ; C 241 ; WX 667 ; N ae ; B 26 -15 630 571 ; C 245 ; WX 222 ; N dotlessi ; B 72 0 151 556 ; C 248 ; WX 222 ; N lslash ; B -8 0 231 750 ; C 249 ; WX 500 ; N oslash ; B 25 -46 472 582 ; C 250 ; WX 722 ; N oe ; B 40 -15 676 571 ; C 251 ; WX 500 ; N germandbls ; B 71 -5 445 765 ; C -1 ; WX 444 ; N ecircumflex ; B 43 -15 395 765 ; C -1 ; WX 444 ; N edieresis ; B 43 -15 395 750 ; C -1 ; WX 444 ; N aacute ; B 31 -15 417 765 ; C -1 ; WX 800 ; N registered ; B 8 -18 792 765 ; C -1 ; WX 222 ; N icircumflex ; B -34 0 258 765 ; C -1 ; WX 500 ; N udieresis ; B 77 -15 424 750 ; C -1 ; WX 500 ; N ograve ; B 51 -15 449 765 ; C -1 ; WX 500 ; N uacute ; B 77 -15 424 765 ; C -1 ; WX 500 ; N ucircumflex ; B 77 -15 424 765 ; C -1 ; WX 556 ; N Aacute ; B 11 0 546 959 ; C -1 ; WX 222 ; N igrave ; B -20 0 178 765 ; C -1 ; WX 278 ; N Icircumflex ; B -6 0 286 959 ; C -1 ; WX 444 ; N ccedilla ; B 44 -224 405 571 ; C -1 ; WX 444 ; N adieresis ; B 31 -15 417 750 ; C -1 ; WX 500 ; N Ecircumflex ; B 74 0 451 959 ; C -1 ; WX 444 ; N scaron ; B 43 -15 400 765 ; C -1 ; WX 500 ; N thorn ; B 72 -188 447 750 ; C -1 ; WX 750 ; N trademark ; B 0 329 719 750 ; C -1 ; WX 444 ; N egrave ; B 43 -15 395 765 ; C -1 ; WX 300 ; N threesuperior ; B 17 291 283 750 ; C -1 ; WX 389 ; N zcaron ; B 24 0 366 765 ; C -1 ; WX 444 ; N atilde ; B 31 -15 417 749 ; C -1 ; WX 444 ; N aring ; B 31 -15 417 826 ; C -1 ; WX 500 ; N ocircumflex ; B 51 -15 449 765 ; C -1 ; WX 500 ; N Edieresis ; B 74 0 451 944 ; C -1 ; WX 750 ; N threequarters ; B 21 0 730 750 ; C -1 ; WX 444 ; N ydieresis ; B 5 -190 425 750 ; C -1 ; WX 444 ; N yacute ; B 5 -190 425 765 ; C -1 ; WX 222 ; N iacute ; B 45 0 243 765 ; C -1 ; WX 556 ; N Acircumflex ; B 11 0 546 959 ; C -1 ; WX 611 ; N Uacute ; B 81 -18 531 959 ; C -1 ; WX 444 ; N eacute ; B 43 -15 395 765 ; C -1 ; WX 611 ; N Ograve ; B 59 -18 553 959 ; C -1 ; WX 444 ; N agrave ; B 31 -15 417 765 ; C -1 ; WX 611 ; N Udieresis ; B 81 -18 531 944 ; C -1 ; WX 444 ; N acircumflex ; B 31 -15 417 765 ; C -1 ; WX 278 ; N Igrave ; B 8 0 206 959 ; C -1 ; WX 300 ; N twosuperior ; B 19 300 281 750 ; C -1 ; WX 611 ; N Ugrave ; B 81 -18 531 959 ; C -1 ; WX 750 ; N onequarter ; B 34 0 716 750 ; C -1 ; WX 611 ; N Ucircumflex ; B 81 -18 531 959 ; C -1 ; WX 556 ; N Scaron ; B 51 -18 505 959 ; C -1 ; WX 278 ; N Idieresis ; B 25 0 254 944 ; C -1 ; WX 222 ; N idieresis ; B -3 0 226 750 ; C -1 ; WX 500 ; N Egrave ; B 74 0 451 959 ; C -1 ; WX 611 ; N Oacute ; B 59 -18 553 959 ; C -1 ; WX 500 ; N divide ; B 44 3 457 505 ; C -1 ; WX 556 ; N Atilde ; B 11 0 546 943 ; C -1 ; WX 556 ; N Aring ; B 11 0 546 990 ; C -1 ; WX 611 ; N Odieresis ; B 59 -18 553 944 ; C -1 ; WX 556 ; N Adieresis ; B 11 0 546 944 ; C -1 ; WX 611 ; N Ntilde ; B 77 0 534 943 ; C -1 ; WX 500 ; N Zcaron ; B 28 0 473 959 ; C -1 ; WX 556 ; N Thorn ; B 86 0 519 750 ; C -1 ; WX 278 ; N Iacute ; B 73 0 271 959 ; C -1 ; WX 500 ; N plusminus ; B 44 0 457 505 ; C -1 ; WX 500 ; N multiply ; B 44 48 457 461 ; C -1 ; WX 500 ; N Eacute ; B 74 0 451 959 ; C -1 ; WX 556 ; N Ydieresis ; B 11 0 546 944 ; C -1 ; WX 300 ; N onesuperior ; B 67 300 233 750 ; C -1 ; WX 500 ; N ugrave ; B 77 -15 424 765 ; C -1 ; WX 500 ; N logicalnot ; B 44 117 457 384 ; C -1 ; WX 500 ; N ntilde ; B 73 0 428 749 ; C -1 ; WX 611 ; N Otilde ; B 59 -18 553 943 ; C -1 ; WX 500 ; N otilde ; B 51 -15 449 749 ; C -1 ; WX 556 ; N Ccedilla ; B 53 -224 503 765 ; C -1 ; WX 556 ; N Agrave ; B 11 0 546 959 ; C -1 ; WX 750 ; N onehalf ; B 42 0 709 750 ; C -1 ; WX 611 ; N Eth ; B 9 0 548 750 ; C -1 ; WX 400 ; N degree ; B 50 450 350 750 ; C -1 ; WX 556 ; N Yacute ; B 11 0 546 959 ; C -1 ; WX 611 ; N Ocircumflex ; B 59 -18 553 959 ; C -1 ; WX 500 ; N oacute ; B 51 -15 449 765 ; C -1 ; WX 500 ; N mu ; B 75 -189 422 556 ; C -1 ; WX 500 ; N minus ; B 44 219 457 289 ; C -1 ; WX 500 ; N eth ; B 51 -15 449 831 ; C -1 ; WX 500 ; N odieresis ; B 51 -15 449 750 ; C -1 ; WX 800 ; N copyright ; B 8 -18 792 765 ; C -1 ; WX 250 ; N brokenbar ; B 93 -175 157 675 ; EndCharMetrics StartKernData StartKernPairs 90 KPX A y -18 KPX A w -18 KPX A v -18 KPX A quoteright -55 KPX A Y -55 KPX A W -37 KPX A V -37 KPX A T -55 KPX F period -111 KPX F comma -111 KPX F A -37 KPX L y -37 KPX L quoteright -92 KPX L Y -92 KPX L W -74 KPX L V -74 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -37 KPX R Y -18 KPX R T -18 KPX T y -55 KPX T w -74 KPX T u -74 KPX T semicolon -74 KPX T s -74 KPX T r -74 KPX T period -92 KPX T o -74 KPX T i -18 KPX T hyphen -55 KPX T e -74 KPX T comma -92 KPX T colon -74 KPX T c -74 KPX T a -74 KPX T A -55 KPX V u -18 KPX V semicolon -18 KPX V r -18 KPX V period -92 KPX V o -18 KPX V hyphen -18 KPX V e -18 KPX V comma -92 KPX V colon -18 KPX V a -18 KPX V A -37 KPX W period -74 KPX W o -18 KPX W hyphen -18 KPX W e -18 KPX W comma -74 KPX W a -18 KPX W A -18 KPX Y v -18 KPX Y u -37 KPX Y semicolon -37 KPX Y q -55 KPX Y period -111 KPX Y p -37 KPX Y o -55 KPX Y i -18 KPX Y hyphen -74 KPX Y e -55 KPX Y comma -111 KPX Y colon -37 KPX Y a -55 KPX Y A -55 KPX f quoteright 18 KPX quoteleft quoteleft -18 KPX quoteright s -55 KPX quoteright quoteright -18 KPX r z 20 KPX r y 18 KPX r x 20 KPX r w 18 KPX r v 18 KPX r period -74 KPX r hyphen -37 KPX r f 20 KPX r comma -74 KPX r c -20 KPX v period -55 KPX v comma -55 KPX w period -37 KPX w comma -37 KPX y period -55 KPX y comma -55 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 112 194 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 112 194 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 112 194 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 112 194 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 153 194 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 112 194 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 84 194 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 84 194 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 194 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 84 194 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 194 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 194 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 194 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 194 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 139 194 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 139 194 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 139 194 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 139 194 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 139 194 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 139 194 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 194 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 139 194 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 139 194 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 139 194 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 139 194 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 112 194 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 194 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 84 194 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 82 30 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -55 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -55 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -55 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/NewCenturySchlbk-Roman.afm��������������������������������������������0000644�0001750�0001750�00000041446�11462120062�021447� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue May 28 16:31:51 1991 Comment UniqueID 35025 Comment VMusage 30420 37312 FontName NewCenturySchlbk-Roman FullName New Century Schoolbook Roman FamilyName New Century Schoolbook Weight Roman ItalicAngle 0 IsFixedPitch false FontBBox -195 -250 1000 965 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 722 XHeight 464 Ascender 737 Descender -205 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 296 ; N exclam ; B 86 -15 210 737 ; C 34 ; WX 389 ; N quotedbl ; B 61 443 328 737 ; C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ; C 36 ; WX 556 ; N dollar ; B 45 -138 511 813 ; C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ; C 38 ; WX 815 ; N ampersand ; B 51 -15 775 737 ; C 39 ; WX 204 ; N quoteright ; B 25 443 179 737 ; C 40 ; WX 333 ; N parenleft ; B 40 -117 279 745 ; C 41 ; WX 333 ; N parenright ; B 54 -117 293 745 ; C 42 ; WX 500 ; N asterisk ; B 57 306 443 737 ; C 43 ; WX 606 ; N plus ; B 50 0 556 506 ; C 44 ; WX 278 ; N comma ; B 62 -185 216 109 ; C 45 ; WX 333 ; N hyphen ; B 42 199 291 277 ; C 46 ; WX 278 ; N period ; B 77 -15 201 109 ; C 47 ; WX 278 ; N slash ; B -32 -15 310 737 ; C 48 ; WX 556 ; N zero ; B 42 -15 514 705 ; C 49 ; WX 556 ; N one ; B 100 0 496 705 ; C 50 ; WX 556 ; N two ; B 35 0 505 705 ; C 51 ; WX 556 ; N three ; B 42 -15 498 705 ; C 52 ; WX 556 ; N four ; B 28 0 528 705 ; C 53 ; WX 556 ; N five ; B 46 -15 502 705 ; C 54 ; WX 556 ; N six ; B 41 -15 515 705 ; C 55 ; WX 556 ; N seven ; B 59 -15 508 705 ; C 56 ; WX 556 ; N eight ; B 42 -15 514 705 ; C 57 ; WX 556 ; N nine ; B 41 -15 515 705 ; C 58 ; WX 278 ; N colon ; B 77 -15 201 474 ; C 59 ; WX 278 ; N semicolon ; B 62 -185 216 474 ; C 60 ; WX 606 ; N less ; B 50 -8 556 514 ; C 61 ; WX 606 ; N equal ; B 50 117 556 389 ; C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ; C 63 ; WX 444 ; N question ; B 29 -15 415 737 ; C 64 ; WX 737 ; N at ; B -8 -15 744 737 ; C 65 ; WX 722 ; N A ; B -8 0 730 737 ; C 66 ; WX 722 ; N B ; B 29 0 669 722 ; C 67 ; WX 722 ; N C ; B 45 -15 668 737 ; C 68 ; WX 778 ; N D ; B 29 0 733 722 ; C 69 ; WX 722 ; N E ; B 29 0 663 722 ; C 70 ; WX 667 ; N F ; B 29 0 638 722 ; C 71 ; WX 778 ; N G ; B 45 -15 775 737 ; C 72 ; WX 833 ; N H ; B 29 0 804 722 ; C 73 ; WX 407 ; N I ; B 38 0 369 722 ; C 74 ; WX 556 ; N J ; B 5 -15 540 722 ; C 75 ; WX 778 ; N K ; B 29 0 803 722 ; C 76 ; WX 667 ; N L ; B 29 0 644 722 ; C 77 ; WX 944 ; N M ; B 29 0 915 722 ; C 78 ; WX 815 ; N N ; B 24 -15 791 722 ; C 79 ; WX 778 ; N O ; B 45 -15 733 737 ; C 80 ; WX 667 ; N P ; B 29 0 650 722 ; C 81 ; WX 778 ; N Q ; B 45 -190 748 737 ; C 82 ; WX 722 ; N R ; B 29 -15 713 722 ; C 83 ; WX 630 ; N S ; B 47 -15 583 737 ; C 84 ; WX 667 ; N T ; B 19 0 648 722 ; C 85 ; WX 815 ; N U ; B 16 -15 799 722 ; C 86 ; WX 722 ; N V ; B -8 -10 730 722 ; C 87 ; WX 981 ; N W ; B 5 -10 976 722 ; C 88 ; WX 704 ; N X ; B -8 0 712 722 ; C 89 ; WX 704 ; N Y ; B -11 0 715 722 ; C 90 ; WX 611 ; N Z ; B 24 0 576 722 ; C 91 ; WX 333 ; N bracketleft ; B 126 -109 315 737 ; C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ; C 93 ; WX 333 ; N bracketright ; B 18 -109 207 737 ; C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 204 ; N quoteleft ; B 25 443 179 737 ; C 97 ; WX 556 ; N a ; B 44 -15 542 479 ; C 98 ; WX 556 ; N b ; B 10 -15 522 737 ; C 99 ; WX 444 ; N c ; B 34 -15 426 479 ; C 100 ; WX 574 ; N d ; B 34 -15 552 737 ; C 101 ; WX 500 ; N e ; B 34 -15 466 479 ; C 102 ; WX 333 ; N f ; B 18 0 437 737 ; L i fi ; L l fl ; C 103 ; WX 537 ; N g ; B 23 -205 542 494 ; C 104 ; WX 611 ; N h ; B 7 0 592 737 ; C 105 ; WX 315 ; N i ; B 18 0 286 722 ; C 106 ; WX 296 ; N j ; B -86 -205 216 722 ; C 107 ; WX 593 ; N k ; B 10 0 589 737 ; C 108 ; WX 315 ; N l ; B 18 0 286 737 ; C 109 ; WX 889 ; N m ; B 26 0 863 479 ; C 110 ; WX 611 ; N n ; B 22 0 589 479 ; C 111 ; WX 500 ; N o ; B 34 -15 466 479 ; C 112 ; WX 574 ; N p ; B 22 -205 540 479 ; C 113 ; WX 556 ; N q ; B 34 -205 552 479 ; C 114 ; WX 444 ; N r ; B 18 0 434 479 ; C 115 ; WX 463 ; N s ; B 46 -15 417 479 ; C 116 ; WX 389 ; N t ; B 18 -15 371 666 ; C 117 ; WX 611 ; N u ; B 22 -15 589 464 ; C 118 ; WX 537 ; N v ; B -6 -10 515 464 ; C 119 ; WX 778 ; N w ; B 1 -10 749 464 ; C 120 ; WX 537 ; N x ; B 8 0 529 464 ; C 121 ; WX 537 ; N y ; B 4 -205 533 464 ; C 122 ; WX 481 ; N z ; B 42 0 439 464 ; C 123 ; WX 333 ; N braceleft ; B 54 -109 279 737 ; C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ; C 125 ; WX 333 ; N braceright ; B 54 -109 279 737 ; C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ; C 161 ; WX 296 ; N exclamdown ; B 86 -205 210 547 ; C 162 ; WX 556 ; N cent ; B 74 -141 482 584 ; C 163 ; WX 556 ; N sterling ; B 18 -15 538 705 ; C 164 ; WX 167 ; N fraction ; B -195 -15 362 705 ; C 165 ; WX 556 ; N yen ; B -1 0 557 690 ; C 166 ; WX 556 ; N florin ; B 0 -205 538 737 ; C 167 ; WX 500 ; N section ; B 55 -147 445 737 ; C 168 ; WX 556 ; N currency ; B 26 93 530 597 ; C 169 ; WX 204 ; N quotesingle ; B 59 443 145 737 ; C 170 ; WX 389 ; N quotedblleft ; B 25 443 364 737 ; C 171 ; WX 426 ; N guillemotleft ; B 39 78 387 398 ; C 172 ; WX 259 ; N guilsinglleft ; B 39 78 220 398 ; C 173 ; WX 259 ; N guilsinglright ; B 39 78 220 398 ; C 174 ; WX 611 ; N fi ; B 18 0 582 737 ; C 175 ; WX 611 ; N fl ; B 18 0 582 737 ; C 177 ; WX 556 ; N endash ; B 0 208 556 268 ; C 178 ; WX 500 ; N dagger ; B 42 -147 458 737 ; C 179 ; WX 500 ; N daggerdbl ; B 42 -149 458 737 ; C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ; C 182 ; WX 606 ; N paragraph ; B 60 -132 546 722 ; C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ; C 184 ; WX 204 ; N quotesinglbase ; B 25 -185 179 109 ; C 185 ; WX 389 ; N quotedblbase ; B 25 -185 364 109 ; C 186 ; WX 389 ; N quotedblright ; B 25 443 364 737 ; C 187 ; WX 426 ; N guillemotright ; B 39 78 387 398 ; C 188 ; WX 1000 ; N ellipsis ; B 105 -15 895 109 ; C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ; C 191 ; WX 444 ; N questiondown ; B 29 -205 415 547 ; C 193 ; WX 333 ; N grave ; B 17 528 242 699 ; C 194 ; WX 333 ; N acute ; B 91 528 316 699 ; C 195 ; WX 333 ; N circumflex ; B 10 528 323 695 ; C 196 ; WX 333 ; N tilde ; B 1 553 332 655 ; C 197 ; WX 333 ; N macron ; B 10 568 323 623 ; C 198 ; WX 333 ; N breve ; B 25 528 308 685 ; C 199 ; WX 333 ; N dotaccent ; B 116 543 218 645 ; C 200 ; WX 333 ; N dieresis ; B 16 543 317 645 ; C 202 ; WX 333 ; N ring ; B 66 522 266 722 ; C 203 ; WX 333 ; N cedilla ; B 29 -215 237 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -9 528 416 699 ; C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ; C 207 ; WX 333 ; N caron ; B 10 528 323 695 ; C 208 ; WX 1000 ; N emdash ; B 0 208 1000 268 ; C 225 ; WX 1000 ; N AE ; B 0 0 962 722 ; C 227 ; WX 334 ; N ordfeminine ; B -4 407 338 705 ; C 232 ; WX 667 ; N Lslash ; B 29 0 644 722 ; C 233 ; WX 778 ; N Oslash ; B 45 -56 733 778 ; C 234 ; WX 1000 ; N OE ; B 21 0 979 722 ; C 235 ; WX 300 ; N ordmasculine ; B 4 407 296 705 ; C 241 ; WX 796 ; N ae ; B 34 -15 762 479 ; C 245 ; WX 315 ; N dotlessi ; B 18 0 286 464 ; C 248 ; WX 315 ; N lslash ; B 18 0 286 737 ; C 249 ; WX 500 ; N oslash ; B 34 -97 466 561 ; C 250 ; WX 833 ; N oe ; B 34 -15 799 479 ; C 251 ; WX 574 ; N germandbls ; B 30 -15 537 737 ; C -1 ; WX 500 ; N ecircumflex ; B 34 -15 466 695 ; C -1 ; WX 500 ; N edieresis ; B 34 -15 466 645 ; C -1 ; WX 556 ; N aacute ; B 44 -15 542 699 ; C -1 ; WX 737 ; N registered ; B -8 -15 744 737 ; C -1 ; WX 315 ; N icircumflex ; B 1 0 314 695 ; C -1 ; WX 611 ; N udieresis ; B 22 -15 589 645 ; C -1 ; WX 500 ; N ograve ; B 34 -15 466 699 ; C -1 ; WX 611 ; N uacute ; B 22 -15 589 699 ; C -1 ; WX 611 ; N ucircumflex ; B 22 -15 589 695 ; C -1 ; WX 722 ; N Aacute ; B -8 0 730 937 ; C -1 ; WX 315 ; N igrave ; B 8 0 286 699 ; C -1 ; WX 407 ; N Icircumflex ; B 38 0 369 933 ; C -1 ; WX 444 ; N ccedilla ; B 34 -215 426 479 ; C -1 ; WX 556 ; N adieresis ; B 44 -15 542 645 ; C -1 ; WX 722 ; N Ecircumflex ; B 29 0 663 933 ; C -1 ; WX 463 ; N scaron ; B 46 -15 417 695 ; C -1 ; WX 574 ; N thorn ; B 22 -205 540 737 ; C -1 ; WX 1000 ; N trademark ; B 32 318 968 722 ; C -1 ; WX 500 ; N egrave ; B 34 -15 466 699 ; C -1 ; WX 333 ; N threesuperior ; B 18 273 315 705 ; C -1 ; WX 481 ; N zcaron ; B 42 0 439 695 ; C -1 ; WX 556 ; N atilde ; B 44 -15 542 655 ; C -1 ; WX 556 ; N aring ; B 44 -15 542 732 ; C -1 ; WX 500 ; N ocircumflex ; B 34 -15 466 695 ; C -1 ; WX 722 ; N Edieresis ; B 29 0 663 883 ; C -1 ; WX 834 ; N threequarters ; B 28 -15 795 705 ; C -1 ; WX 537 ; N ydieresis ; B 4 -205 533 645 ; C -1 ; WX 537 ; N yacute ; B 4 -205 533 699 ; C -1 ; WX 315 ; N iacute ; B 18 0 307 699 ; C -1 ; WX 722 ; N Acircumflex ; B -8 0 730 933 ; C -1 ; WX 815 ; N Uacute ; B 16 -15 799 937 ; C -1 ; WX 500 ; N eacute ; B 34 -15 466 699 ; C -1 ; WX 778 ; N Ograve ; B 45 -15 733 937 ; C -1 ; WX 556 ; N agrave ; B 44 -15 542 699 ; C -1 ; WX 815 ; N Udieresis ; B 16 -15 799 883 ; C -1 ; WX 556 ; N acircumflex ; B 44 -15 542 695 ; C -1 ; WX 407 ; N Igrave ; B 38 0 369 937 ; C -1 ; WX 333 ; N twosuperior ; B 14 282 319 705 ; C -1 ; WX 815 ; N Ugrave ; B 16 -15 799 937 ; C -1 ; WX 834 ; N onequarter ; B 39 -15 795 705 ; C -1 ; WX 815 ; N Ucircumflex ; B 16 -15 799 933 ; C -1 ; WX 630 ; N Scaron ; B 47 -15 583 933 ; C -1 ; WX 407 ; N Idieresis ; B 38 0 369 883 ; C -1 ; WX 315 ; N idieresis ; B 7 0 308 645 ; C -1 ; WX 722 ; N Egrave ; B 29 0 663 937 ; C -1 ; WX 778 ; N Oacute ; B 45 -15 733 937 ; C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ; C -1 ; WX 722 ; N Atilde ; B -8 0 730 893 ; C -1 ; WX 722 ; N Aring ; B -8 0 730 965 ; C -1 ; WX 778 ; N Odieresis ; B 45 -15 733 883 ; C -1 ; WX 722 ; N Adieresis ; B -8 0 730 883 ; C -1 ; WX 815 ; N Ntilde ; B 24 -15 791 893 ; C -1 ; WX 611 ; N Zcaron ; B 24 0 576 933 ; C -1 ; WX 667 ; N Thorn ; B 29 0 650 722 ; C -1 ; WX 407 ; N Iacute ; B 38 0 369 937 ; C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ; C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ; C -1 ; WX 722 ; N Eacute ; B 29 0 663 937 ; C -1 ; WX 704 ; N Ydieresis ; B -11 0 715 883 ; C -1 ; WX 333 ; N onesuperior ; B 39 282 294 705 ; C -1 ; WX 611 ; N ugrave ; B 22 -15 589 699 ; C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ; C -1 ; WX 611 ; N ntilde ; B 22 0 589 655 ; C -1 ; WX 778 ; N Otilde ; B 45 -15 733 893 ; C -1 ; WX 500 ; N otilde ; B 34 -15 466 655 ; C -1 ; WX 722 ; N Ccedilla ; B 45 -215 668 737 ; C -1 ; WX 722 ; N Agrave ; B -8 0 730 937 ; C -1 ; WX 834 ; N onehalf ; B 39 -15 820 705 ; C -1 ; WX 778 ; N Eth ; B 29 0 733 722 ; C -1 ; WX 400 ; N degree ; B 57 419 343 705 ; C -1 ; WX 704 ; N Yacute ; B -11 0 715 937 ; C -1 ; WX 778 ; N Ocircumflex ; B 45 -15 733 933 ; C -1 ; WX 500 ; N oacute ; B 34 -15 466 699 ; C -1 ; WX 611 ; N mu ; B 22 -205 589 464 ; C -1 ; WX 606 ; N minus ; B 50 217 556 289 ; C -1 ; WX 500 ; N eth ; B 34 -15 466 752 ; C -1 ; WX 500 ; N odieresis ; B 34 -15 466 645 ; C -1 ; WX 737 ; N copyright ; B -8 -15 744 737 ; C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ; EndCharMetrics StartKernData StartKernPairs 169 KPX A y -37 KPX A w -25 KPX A v -37 KPX A quoteright -74 KPX A quotedblright -74 KPX A Y -75 KPX A W -50 KPX A V -75 KPX A U -30 KPX A T -18 KPX B period -37 KPX B comma -37 KPX B A -18 KPX C period -37 KPX C comma -37 KPX C A -18 KPX D period -37 KPX D comma -37 KPX D Y -18 KPX D V -18 KPX F r -10 KPX F period -125 KPX F o -55 KPX F i -10 KPX F e -55 KPX F comma -125 KPX F a -65 KPX F A -50 KPX G period -37 KPX G comma -37 KPX J u -25 KPX J period -74 KPX J o -25 KPX J e -25 KPX J comma -74 KPX J a -25 KPX J A -18 KPX K y -25 KPX K o 10 KPX K e 10 KPX L y -25 KPX L quoteright -100 KPX L quotedblright -100 KPX L Y -74 KPX L W -74 KPX L V -91 KPX L T -75 KPX N period -55 KPX N comma -55 KPX O period -37 KPX O comma -37 KPX O Y -18 KPX O V -18 KPX O T 10 KPX P period -125 KPX P o -37 KPX P e -37 KPX P comma -125 KPX P a -37 KPX P A -55 KPX Q period -25 KPX Q comma -25 KPX S period -37 KPX S comma -37 KPX T semicolon -37 KPX T period -125 KPX T o -55 KPX T hyphen -100 KPX T e -55 KPX T comma -125 KPX T colon -37 KPX T a -55 KPX T O 10 KPX T A -18 KPX U period -100 KPX U comma -100 KPX U A -30 KPX V u -75 KPX V semicolon -75 KPX V period -125 KPX V o -75 KPX V i -18 KPX V hyphen -100 KPX V e -75 KPX V comma -125 KPX V colon -75 KPX V a -85 KPX V O -18 KPX V A -74 KPX W y -55 KPX W u -55 KPX W semicolon -100 KPX W period -125 KPX W o -60 KPX W i -18 KPX W hyphen -100 KPX W e -60 KPX W comma -125 KPX W colon -100 KPX W a -75 KPX W A -50 KPX Y u -91 KPX Y semicolon -75 KPX Y period -100 KPX Y o -100 KPX Y i -18 KPX Y hyphen -125 KPX Y e -100 KPX Y comma -100 KPX Y colon -75 KPX Y a -100 KPX Y O -18 KPX Y A -75 KPX a y -10 KPX a w -10 KPX a v -10 KPX b period -18 KPX b comma -18 KPX c period -18 KPX c l -7 KPX c k -7 KPX c h -7 KPX c comma -18 KPX colon space -37 KPX comma space -37 KPX comma quoteright -37 KPX comma quotedblright -37 KPX e period -18 KPX e comma -18 KPX f quoteright 100 KPX f quotedblright 100 KPX f period -37 KPX f comma -37 KPX g period -25 KPX g comma -25 KPX o period -18 KPX o comma -18 KPX p period -18 KPX p comma -18 KPX period space -37 KPX period quoteright -37 KPX period quotedblright -37 KPX quotedblleft A -74 KPX quotedblright space -37 KPX quoteleft quoteleft -25 KPX quoteleft A -74 KPX quoteright s -25 KPX quoteright quoteright -25 KPX quoteright d -37 KPX r period -100 KPX r hyphen -37 KPX r comma -100 KPX s period -25 KPX s comma -25 KPX semicolon space -37 KPX space quoteleft -37 KPX space quotedblleft -37 KPX space Y -37 KPX space W -37 KPX space V -37 KPX space T -37 KPX space A -37 KPX v period -125 KPX v comma -125 KPX w period -125 KPX w comma -125 KPX w a -18 KPX y period -125 KPX y comma -125 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 238 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 238 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 238 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 238 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 195 243 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 238 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 195 238 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 195 238 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 195 238 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 195 238 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 37 238 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 37 238 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 37 238 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 37 238 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 241 238 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 238 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 238 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 238 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 238 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 238 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 149 238 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 241 238 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 241 238 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 241 238 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 241 238 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 216 238 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 186 238 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 238 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 112 10 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -9 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -9 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -9 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -9 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 65 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 102 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 102 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 74 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-BoldOblique.afm���������������������������������������������0000644�0001750�0001750�00000042611�11462120062�021241� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu Mar 15 10:44:33 1990 Comment UniqueID 28371 Comment VMusage 7614 43068 FontName Helvetica-BoldOblique FullName Helvetica Bold Oblique FamilyName Helvetica Weight Bold ItalicAngle -12 IsFixedPitch false FontBBox -174 -228 1114 962 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ; C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ; C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ; C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ; C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ; C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ; C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ; C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ; C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ; C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ; C 43 ; WX 584 ; N plus ; B 82 0 610 506 ; C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ; C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ; C 46 ; WX 278 ; N period ; B 64 0 245 146 ; C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ; C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ; C 49 ; WX 556 ; N one ; B 173 0 529 710 ; C 50 ; WX 556 ; N two ; B 26 0 619 710 ; C 51 ; WX 556 ; N three ; B 65 -19 608 710 ; C 52 ; WX 556 ; N four ; B 60 0 598 710 ; C 53 ; WX 556 ; N five ; B 64 -19 636 698 ; C 54 ; WX 556 ; N six ; B 85 -19 619 710 ; C 55 ; WX 556 ; N seven ; B 125 0 676 698 ; C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ; C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ; C 58 ; WX 333 ; N colon ; B 92 0 351 512 ; C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ; C 60 ; WX 584 ; N less ; B 82 -8 655 514 ; C 61 ; WX 584 ; N equal ; B 58 87 633 419 ; C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ; C 63 ; WX 611 ; N question ; B 165 0 671 727 ; C 64 ; WX 975 ; N at ; B 186 -19 954 737 ; C 65 ; WX 722 ; N A ; B 20 0 702 718 ; C 66 ; WX 722 ; N B ; B 76 0 764 718 ; C 67 ; WX 722 ; N C ; B 107 -19 789 737 ; C 68 ; WX 722 ; N D ; B 76 0 777 718 ; C 69 ; WX 667 ; N E ; B 76 0 757 718 ; C 70 ; WX 611 ; N F ; B 76 0 740 718 ; C 71 ; WX 778 ; N G ; B 108 -19 817 737 ; C 72 ; WX 722 ; N H ; B 71 0 804 718 ; C 73 ; WX 278 ; N I ; B 64 0 367 718 ; C 74 ; WX 556 ; N J ; B 60 -18 637 718 ; C 75 ; WX 722 ; N K ; B 87 0 858 718 ; C 76 ; WX 611 ; N L ; B 76 0 611 718 ; C 77 ; WX 833 ; N M ; B 69 0 918 718 ; C 78 ; WX 722 ; N N ; B 69 0 807 718 ; C 79 ; WX 778 ; N O ; B 107 -19 823 737 ; C 80 ; WX 667 ; N P ; B 76 0 738 718 ; C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ; C 82 ; WX 722 ; N R ; B 76 0 778 718 ; C 83 ; WX 667 ; N S ; B 81 -19 718 737 ; C 84 ; WX 611 ; N T ; B 140 0 751 718 ; C 85 ; WX 722 ; N U ; B 116 -19 804 718 ; C 86 ; WX 667 ; N V ; B 172 0 801 718 ; C 87 ; WX 944 ; N W ; B 169 0 1082 718 ; C 88 ; WX 667 ; N X ; B 14 0 791 718 ; C 89 ; WX 667 ; N Y ; B 168 0 806 718 ; C 90 ; WX 611 ; N Z ; B 25 0 737 718 ; C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ; C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ; C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ; C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ; C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ; C 97 ; WX 556 ; N a ; B 55 -14 583 546 ; C 98 ; WX 611 ; N b ; B 61 -14 645 718 ; C 99 ; WX 556 ; N c ; B 79 -14 599 546 ; C 100 ; WX 611 ; N d ; B 82 -14 704 718 ; C 101 ; WX 556 ; N e ; B 70 -14 593 546 ; C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B 38 -217 666 546 ; C 104 ; WX 611 ; N h ; B 65 0 629 718 ; C 105 ; WX 278 ; N i ; B 69 0 363 725 ; C 106 ; WX 278 ; N j ; B -42 -214 363 725 ; C 107 ; WX 556 ; N k ; B 69 0 670 718 ; C 108 ; WX 278 ; N l ; B 69 0 362 718 ; C 109 ; WX 889 ; N m ; B 64 0 909 546 ; C 110 ; WX 611 ; N n ; B 65 0 629 546 ; C 111 ; WX 611 ; N o ; B 82 -14 643 546 ; C 112 ; WX 611 ; N p ; B 18 -207 645 546 ; C 113 ; WX 611 ; N q ; B 80 -207 665 546 ; C 114 ; WX 389 ; N r ; B 64 0 489 546 ; C 115 ; WX 556 ; N s ; B 63 -14 584 546 ; C 116 ; WX 333 ; N t ; B 100 -6 422 676 ; C 117 ; WX 611 ; N u ; B 98 -14 658 532 ; C 118 ; WX 556 ; N v ; B 126 0 656 532 ; C 119 ; WX 778 ; N w ; B 123 0 882 532 ; C 120 ; WX 556 ; N x ; B 15 0 648 532 ; C 121 ; WX 556 ; N y ; B 42 -214 652 532 ; C 122 ; WX 500 ; N z ; B 20 0 583 532 ; C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ; C 124 ; WX 280 ; N bar ; B 80 -19 353 737 ; C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ; C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ; C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ; C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ; C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ; C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ; C 165 ; WX 556 ; N yen ; B 60 0 713 698 ; C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ; C 167 ; WX 556 ; N section ; B 61 -184 598 727 ; C 168 ; WX 556 ; N currency ; B 27 76 680 636 ; C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ; C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ; C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ; C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ; C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ; C 174 ; WX 611 ; N fi ; B 87 0 696 727 ; C 175 ; WX 611 ; N fl ; B 87 0 695 727 ; C 177 ; WX 556 ; N endash ; B 48 227 627 333 ; C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ; C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ; C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ; C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ; C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ; C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ; C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ; C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ; C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ; C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ; C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ; C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ; C 193 ; WX 333 ; N grave ; B 136 604 353 750 ; C 194 ; WX 333 ; N acute ; B 236 604 515 750 ; C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ; C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ; C 197 ; WX 333 ; N macron ; B 122 604 483 678 ; C 198 ; WX 333 ; N breve ; B 156 604 494 750 ; C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ; C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ; C 202 ; WX 333 ; N ring ; B 200 568 420 776 ; C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ; C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ; C 207 ; WX 333 ; N caron ; B 149 604 502 750 ; C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ; C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ; C 227 ; WX 370 ; N ordfeminine ; B 92 276 465 737 ; C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ; C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ; C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ; C 235 ; WX 365 ; N ordmasculine ; B 92 276 485 737 ; C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ; C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ; C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ; C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ; C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ; C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ; C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ; C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ; C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ; C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ; C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ; C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ; C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ; C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ; C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ; C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ; C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ; C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ; C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ; C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ; C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ; C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ; C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ; C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ; C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ; C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ; C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ; C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ; C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ; C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ; C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ; C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ; C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ; C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ; C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ; C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ; C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ; C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ; C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ; C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ; C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ; C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ; C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ; C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ; C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ; C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ; C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ; C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ; C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ; C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ; C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ; C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ; C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ; C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ; C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ; C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ; C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ; C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ; C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ; C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ; C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ; C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ; C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ; C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ; C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ; C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ; C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ; C -1 ; WX 584 ; N minus ; B 82 197 610 309 ; C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ; C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ; C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ; C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ; C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ; C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ; C -1 ; WX 400 ; N degree ; B 175 426 467 712 ; C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ; C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ; C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ; C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ; C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ; C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ; C -1 ; WX 280 ; N brokenbar ; B 80 -19 353 737 ; C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ; EndCharMetrics StartKernData StartKernPairs 209 KPX A y -30 KPX A w -30 KPX A v -40 KPX A u -30 KPX A Y -110 KPX A W -60 KPX A V -80 KPX A U -50 KPX A T -90 KPX A Q -40 KPX A O -40 KPX A G -50 KPX A C -40 KPX B U -10 KPX B A -30 KPX D period -30 KPX D comma -30 KPX D Y -70 KPX D W -40 KPX D V -40 KPX D A -40 KPX F period -100 KPX F comma -100 KPX F a -20 KPX F A -80 KPX J u -20 KPX J period -20 KPX J comma -20 KPX J A -20 KPX K y -40 KPX K u -30 KPX K o -35 KPX K e -15 KPX K O -30 KPX L y -30 KPX L quoteright -140 KPX L quotedblright -140 KPX L Y -120 KPX L W -80 KPX L V -110 KPX L T -90 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -50 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -50 KPX P period -120 KPX P o -40 KPX P e -30 KPX P comma -120 KPX P a -30 KPX P A -100 KPX Q period 20 KPX Q comma 20 KPX Q U -10 KPX R Y -50 KPX R W -40 KPX R V -50 KPX R U -20 KPX R T -20 KPX R O -20 KPX T y -60 KPX T w -60 KPX T u -90 KPX T semicolon -40 KPX T r -80 KPX T period -80 KPX T o -80 KPX T hyphen -120 KPX T e -60 KPX T comma -80 KPX T colon -40 KPX T a -80 KPX T O -40 KPX T A -90 KPX U period -30 KPX U comma -30 KPX U A -50 KPX V u -60 KPX V semicolon -40 KPX V period -120 KPX V o -90 KPX V hyphen -80 KPX V e -50 KPX V comma -120 KPX V colon -40 KPX V a -60 KPX V O -50 KPX V G -50 KPX V A -80 KPX W y -20 KPX W u -45 KPX W semicolon -10 KPX W period -80 KPX W o -60 KPX W hyphen -40 KPX W e -35 KPX W comma -80 KPX W colon -10 KPX W a -40 KPX W O -20 KPX W A -60 KPX Y u -100 KPX Y semicolon -50 KPX Y period -100 KPX Y o -100 KPX Y e -80 KPX Y comma -100 KPX Y colon -50 KPX Y a -90 KPX Y O -70 KPX Y A -110 KPX a y -20 KPX a w -15 KPX a v -15 KPX a g -10 KPX b y -20 KPX b v -20 KPX b u -20 KPX b l -10 KPX c y -10 KPX c l -20 KPX c k -20 KPX c h -10 KPX colon space -40 KPX comma space -40 KPX comma quoteright -120 KPX comma quotedblright -120 KPX d y -15 KPX d w -15 KPX d v -15 KPX d d -10 KPX e y -15 KPX e x -15 KPX e w -15 KPX e v -15 KPX e period 20 KPX e comma 10 KPX f quoteright 30 KPX f quotedblright 30 KPX f period -10 KPX f o -20 KPX f e -10 KPX f comma -10 KPX g g -10 KPX g e 10 KPX h y -20 KPX k o -15 KPX l y -15 KPX l w -15 KPX m y -30 KPX m u -20 KPX n y -20 KPX n v -40 KPX n u -10 KPX o y -20 KPX o x -30 KPX o w -15 KPX o v -20 KPX p y -15 KPX period space -40 KPX period quoteright -120 KPX period quotedblright -120 KPX quotedblright space -80 KPX quoteleft quoteleft -46 KPX quoteright v -20 KPX quoteright space -80 KPX quoteright s -60 KPX quoteright r -40 KPX quoteright quoteright -46 KPX quoteright l -20 KPX quoteright d -80 KPX r y 10 KPX r v 10 KPX r t 20 KPX r s -15 KPX r q -20 KPX r period -60 KPX r o -20 KPX r hyphen -20 KPX r g -15 KPX r d -20 KPX r comma -60 KPX r c -20 KPX s w -15 KPX semicolon space -40 KPX space quoteleft -60 KPX space quotedblleft -80 KPX space Y -120 KPX space W -80 KPX space V -80 KPX space T -100 KPX v period -80 KPX v o -30 KPX v comma -80 KPX v a -20 KPX w period -40 KPX w o -20 KPX w comma -40 KPX x e -10 KPX y period -80 KPX y o -25 KPX y e -10 KPX y comma -80 KPX y a -30 KPX z e 10 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 235 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 235 186 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 235 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 235 186 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 235 186 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 207 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 207 186 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 207 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 207 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 13 186 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 235 186 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 263 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 186 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 263 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 263 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 186 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 207 186 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 186 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 207 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 207 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 186 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Condensed-Oblique.afm���������������������������������������0000644�0001750�0001750�00000036637�11462120062�022353� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Wed Sep 4 17:59:46 1991 Comment UniqueID 36200 Comment VMusage 7672 41967 FontName Helvetica-Condensed-Oblique FullName Helvetica Condensed Oblique FamilyName Helvetica Weight Medium ItalicAngle -12 IsFixedPitch false FontBBox -174 -250 1118 990 UnderlinePosition -100 UnderlineThickness 50 Version 001.003 Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 750 XHeight 556 Ascender 750 Descender -188 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 121 0 371 750 ; C 34 ; WX 250 ; N quotedbl ; B 153 513 364 739 ; C 35 ; WX 500 ; N numbersign ; B 33 0 621 750 ; C 36 ; WX 500 ; N dollar ; B 69 -116 569 815 ; C 37 ; WX 833 ; N percent ; B 164 -15 803 750 ; C 38 ; WX 667 ; N ampersand ; B 111 -18 648 750 ; C 39 ; WX 222 ; N quoteright ; B 171 504 317 750 ; C 40 ; WX 333 ; N parenleft ; B 115 -215 443 750 ; C 41 ; WX 333 ; N parenright ; B 3 -215 331 750 ; C 42 ; WX 500 ; N asterisk ; B 229 455 537 750 ; C 43 ; WX 500 ; N plus ; B 91 0 518 505 ; C 44 ; WX 250 ; N comma ; B 49 -146 192 100 ; C 45 ; WX 333 ; N hyphen ; B 103 275 364 358 ; C 46 ; WX 250 ; N period ; B 80 0 192 100 ; C 47 ; WX 278 ; N slash ; B -19 -27 450 750 ; C 48 ; WX 500 ; N zero ; B 98 -15 563 750 ; C 49 ; WX 500 ; N one ; B 190 0 476 750 ; C 50 ; WX 500 ; N two ; B 44 0 562 750 ; C 51 ; WX 500 ; N three ; B 73 -15 552 750 ; C 52 ; WX 500 ; N four ; B 68 0 543 750 ; C 53 ; WX 500 ; N five ; B 75 -15 575 735 ; C 54 ; WX 500 ; N six ; B 91 -15 566 750 ; C 55 ; WX 500 ; N seven ; B 116 0 612 735 ; C 56 ; WX 500 ; N eight ; B 83 -15 559 750 ; C 57 ; WX 500 ; N nine ; B 91 -15 566 750 ; C 58 ; WX 250 ; N colon ; B 80 0 287 547 ; C 59 ; WX 250 ; N semicolon ; B 49 -146 287 547 ; C 60 ; WX 500 ; N less ; B 89 -10 569 518 ; C 61 ; WX 500 ; N equal ; B 70 124 539 384 ; C 62 ; WX 500 ; N greater ; B 40 -10 520 518 ; C 63 ; WX 500 ; N question ; B 169 0 586 750 ; C 64 ; WX 800 ; N at ; B 106 -15 863 750 ; C 65 ; WX 556 ; N A ; B 11 0 546 750 ; C 66 ; WX 556 ; N B ; B 80 0 610 750 ; C 67 ; WX 556 ; N C ; B 106 -18 624 765 ; C 68 ; WX 611 ; N D ; B 82 0 653 750 ; C 69 ; WX 500 ; N E ; B 74 0 608 750 ; C 70 ; WX 444 ; N F ; B 74 0 585 750 ; C 71 ; WX 611 ; N G ; B 109 -18 646 765 ; C 72 ; WX 611 ; N H ; B 79 0 691 750 ; C 73 ; WX 278 ; N I ; B 98 0 340 750 ; C 74 ; WX 444 ; N J ; B 52 -15 527 750 ; C 75 ; WX 556 ; N K ; B 79 0 698 750 ; C 76 ; WX 500 ; N L ; B 83 0 488 750 ; C 77 ; WX 778 ; N M ; B 76 0 861 750 ; C 78 ; WX 611 ; N N ; B 77 0 693 750 ; C 79 ; WX 611 ; N O ; B 116 -18 658 765 ; C 80 ; WX 556 ; N P ; B 86 0 641 750 ; C 81 ; WX 611 ; N Q ; B 116 -34 659 765 ; C 82 ; WX 611 ; N R ; B 86 0 655 750 ; C 83 ; WX 556 ; N S ; B 86 -18 611 765 ; C 84 ; WX 500 ; N T ; B 158 0 645 750 ; C 85 ; WX 611 ; N U ; B 114 -18 690 750 ; C 86 ; WX 556 ; N V ; B 170 0 704 750 ; C 87 ; WX 833 ; N W ; B 176 0 975 750 ; C 88 ; WX 556 ; N X ; B 17 0 692 750 ; C 89 ; WX 556 ; N Y ; B 170 0 705 750 ; C 90 ; WX 500 ; N Z ; B 28 0 627 750 ; C 91 ; WX 333 ; N bracketleft ; B 56 -209 434 750 ; C 92 ; WX 250 ; N backslash ; B 128 0 281 750 ; C 93 ; WX 333 ; N bracketright ; B 14 -209 392 750 ; C 94 ; WX 500 ; N asciicircum ; B 141 333 502 750 ; C 95 ; WX 500 ; N underscore ; B -27 -125 484 -75 ; C 96 ; WX 222 ; N quoteleft ; B 175 521 321 767 ; C 97 ; WX 444 ; N a ; B 55 -15 465 571 ; C 98 ; WX 500 ; N b ; B 75 -15 525 750 ; C 99 ; WX 444 ; N c ; B 85 -15 488 571 ; C 100 ; WX 500 ; N d ; B 88 -15 583 750 ; C 101 ; WX 444 ; N e ; B 86 -15 476 571 ; C 102 ; WX 278 ; N f ; B 93 0 418 752 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 53 -189 544 571 ; C 104 ; WX 500 ; N h ; B 73 0 524 750 ; C 105 ; WX 222 ; N i ; B 72 0 310 750 ; C 106 ; WX 222 ; N j ; B -27 -190 313 750 ; C 107 ; WX 444 ; N k ; B 69 0 552 750 ; C 108 ; WX 222 ; N l ; B 72 0 310 750 ; C 109 ; WX 778 ; N m ; B 76 0 799 571 ; C 110 ; WX 500 ; N n ; B 73 0 524 571 ; C 111 ; WX 500 ; N o ; B 96 -15 524 571 ; C 112 ; WX 500 ; N p ; B 32 -188 524 571 ; C 113 ; WX 500 ; N q ; B 100 -184 544 571 ; C 114 ; WX 333 ; N r ; B 81 0 441 563 ; C 115 ; WX 444 ; N s ; B 68 -15 473 571 ; C 116 ; WX 278 ; N t ; B 101 0 375 707 ; C 117 ; WX 500 ; N u ; B 99 -15 542 556 ; C 118 ; WX 444 ; N v ; B 131 0 549 556 ; C 119 ; WX 667 ; N w ; B 137 0 767 556 ; C 120 ; WX 444 ; N x ; B 9 0 548 556 ; C 121 ; WX 444 ; N y ; B -13 -190 543 556 ; C 122 ; WX 389 ; N z ; B 24 0 482 556 ; C 123 ; WX 274 ; N braceleft ; B 77 -95 425 750 ; C 124 ; WX 250 ; N bar ; B 40 -250 316 750 ; C 125 ; WX 274 ; N braceright ; B -12 -95 337 750 ; C 126 ; WX 500 ; N asciitilde ; B 89 166 520 345 ; C 161 ; WX 333 ; N exclamdown ; B 83 -179 333 571 ; C 162 ; WX 500 ; N cent ; B 94 -137 499 667 ; C 163 ; WX 500 ; N sterling ; B 40 -15 589 750 ; C 164 ; WX 167 ; N fraction ; B -174 0 500 750 ; C 165 ; WX 500 ; N yen ; B 88 0 677 750 ; C 166 ; WX 500 ; N florin ; B -28 -192 645 750 ; C 167 ; WX 500 ; N section ; B 51 -208 552 750 ; C 168 ; WX 500 ; N currency ; B 51 50 576 553 ; C 169 ; WX 250 ; N quotesingle ; B 208 513 308 739 ; C 170 ; WX 389 ; N quotedblleft ; B 173 521 490 767 ; C 171 ; WX 500 ; N guillemotleft ; B 145 125 520 495 ; C 172 ; WX 278 ; N guilsinglleft ; B 124 125 320 495 ; C 173 ; WX 278 ; N guilsinglright ; B 90 125 286 495 ; C 174 ; WX 500 ; N fi ; B 93 0 584 752 ; C 175 ; WX 500 ; N fl ; B 93 0 584 752 ; C 177 ; WX 500 ; N endash ; B 58 275 573 345 ; C 178 ; WX 500 ; N dagger ; B 137 -176 573 750 ; C 179 ; WX 500 ; N daggerdbl ; B 50 -176 572 750 ; C 180 ; WX 250 ; N periodcentered ; B 123 204 236 304 ; C 182 ; WX 440 ; N paragraph ; B 113 -116 550 750 ; C 183 ; WX 333 ; N bullet ; B 91 222 401 529 ; C 184 ; WX 222 ; N quotesinglbase ; B 33 -146 179 100 ; C 185 ; WX 389 ; N quotedblbase ; B 31 -146 348 100 ; C 186 ; WX 389 ; N quotedblright ; B 169 504 486 750 ; C 187 ; WX 500 ; N guillemotright ; B 112 125 487 495 ; C 188 ; WX 1000 ; N ellipsis ; B 121 0 899 100 ; C 189 ; WX 1111 ; N perthousand ; B 157 -16 1118 750 ; C 191 ; WX 500 ; N questiondown ; B 33 -190 450 559 ; C 193 ; WX 333 ; N grave ; B 198 624 366 765 ; C 194 ; WX 333 ; N acute ; B 233 624 461 765 ; C 195 ; WX 333 ; N circumflex ; B 154 624 446 765 ; C 196 ; WX 333 ; N tilde ; B 132 633 496 749 ; C 197 ; WX 333 ; N macron ; B 150 657 475 715 ; C 198 ; WX 333 ; N breve ; B 172 629 484 765 ; C 199 ; WX 250 ; N dotaccent ; B 224 650 324 750 ; C 200 ; WX 333 ; N dieresis ; B 190 650 440 750 ; C 202 ; WX 250 ; N ring ; B 169 593 377 796 ; C 203 ; WX 333 ; N cedilla ; B 23 -224 255 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 194 624 603 765 ; C 206 ; WX 333 ; N ogonek ; B -23 -191 188 13 ; C 207 ; WX 333 ; N caron ; B 184 624 476 765 ; C 208 ; WX 1000 ; N emdash ; B 58 275 1073 345 ; C 225 ; WX 833 ; N AE ; B 0 0 944 750 ; C 227 ; WX 300 ; N ordfeminine ; B 129 413 392 765 ; C 232 ; WX 500 ; N Lslash ; B 39 0 488 750 ; C 233 ; WX 611 ; N Oslash ; B 25 -43 738 796 ; C 234 ; WX 833 ; N OE ; B 113 -18 946 765 ; C 235 ; WX 300 ; N ordmasculine ; B 138 413 413 765 ; C 241 ; WX 667 ; N ae ; B 50 -15 711 571 ; C 245 ; WX 222 ; N dotlessi ; B 72 0 269 556 ; C 248 ; WX 222 ; N lslash ; B 59 0 347 750 ; C 249 ; WX 500 ; N oslash ; B 19 -46 591 582 ; C 250 ; WX 722 ; N oe ; B 81 -15 758 571 ; C 251 ; WX 500 ; N germandbls ; B 71 -5 548 765 ; C -1 ; WX 444 ; N ecircumflex ; B 86 -15 502 765 ; C -1 ; WX 444 ; N edieresis ; B 86 -15 496 750 ; C -1 ; WX 444 ; N aacute ; B 55 -15 517 765 ; C -1 ; WX 800 ; N registered ; B 79 -18 881 765 ; C -1 ; WX 222 ; N icircumflex ; B 72 0 391 765 ; C -1 ; WX 500 ; N udieresis ; B 99 -15 542 750 ; C -1 ; WX 500 ; N ograve ; B 96 -15 524 765 ; C -1 ; WX 500 ; N uacute ; B 99 -15 545 765 ; C -1 ; WX 500 ; N ucircumflex ; B 99 -15 542 765 ; C -1 ; WX 556 ; N Aacute ; B 11 0 614 959 ; C -1 ; WX 222 ; N igrave ; B 72 0 311 765 ; C -1 ; WX 278 ; N Icircumflex ; B 98 0 460 959 ; C -1 ; WX 444 ; N ccedilla ; B 79 -224 488 571 ; C -1 ; WX 444 ; N adieresis ; B 55 -15 496 750 ; C -1 ; WX 500 ; N Ecircumflex ; B 74 0 608 959 ; C -1 ; WX 444 ; N scaron ; B 68 -15 532 765 ; C -1 ; WX 500 ; N thorn ; B 32 -188 523 750 ; C -1 ; WX 750 ; N trademark ; B 147 329 878 750 ; C -1 ; WX 444 ; N egrave ; B 86 -15 476 765 ; C -1 ; WX 300 ; N threesuperior ; B 102 291 409 750 ; C -1 ; WX 389 ; N zcaron ; B 24 0 504 765 ; C -1 ; WX 444 ; N atilde ; B 55 -15 552 749 ; C -1 ; WX 444 ; N aring ; B 55 -15 465 826 ; C -1 ; WX 500 ; N ocircumflex ; B 96 -15 530 765 ; C -1 ; WX 500 ; N Edieresis ; B 74 0 608 944 ; C -1 ; WX 750 ; N threequarters ; B 106 0 831 750 ; C -1 ; WX 444 ; N ydieresis ; B -13 -190 543 750 ; C -1 ; WX 444 ; N yacute ; B -13 -190 543 765 ; C -1 ; WX 222 ; N iacute ; B 72 0 406 765 ; C -1 ; WX 556 ; N Acircumflex ; B 11 0 599 959 ; C -1 ; WX 611 ; N Uacute ; B 114 -18 690 959 ; C -1 ; WX 444 ; N eacute ; B 86 -15 517 765 ; C -1 ; WX 611 ; N Ograve ; B 116 -18 658 959 ; C -1 ; WX 444 ; N agrave ; B 55 -15 465 765 ; C -1 ; WX 611 ; N Udieresis ; B 114 -18 690 944 ; C -1 ; WX 444 ; N acircumflex ; B 55 -15 502 765 ; C -1 ; WX 278 ; N Igrave ; B 98 0 380 959 ; C -1 ; WX 300 ; N twosuperior ; B 83 300 413 750 ; C -1 ; WX 611 ; N Ugrave ; B 114 -18 690 959 ; C -1 ; WX 750 ; N onequarter ; B 143 0 817 750 ; C -1 ; WX 611 ; N Ucircumflex ; B 114 -18 690 959 ; C -1 ; WX 556 ; N Scaron ; B 86 -18 629 959 ; C -1 ; WX 278 ; N Idieresis ; B 98 0 455 944 ; C -1 ; WX 222 ; N idieresis ; B 72 0 385 750 ; C -1 ; WX 500 ; N Egrave ; B 74 0 608 959 ; C -1 ; WX 611 ; N Oacute ; B 116 -18 658 959 ; C -1 ; WX 500 ; N divide ; B 91 3 518 505 ; C -1 ; WX 556 ; N Atilde ; B 11 0 649 943 ; C -1 ; WX 556 ; N Aring ; B 11 0 571 990 ; C -1 ; WX 611 ; N Odieresis ; B 116 -18 658 944 ; C -1 ; WX 556 ; N Adieresis ; B 11 0 594 944 ; C -1 ; WX 611 ; N Ntilde ; B 77 0 693 943 ; C -1 ; WX 500 ; N Zcaron ; B 28 0 627 959 ; C -1 ; WX 556 ; N Thorn ; B 86 0 618 750 ; C -1 ; WX 278 ; N Iacute ; B 98 0 475 959 ; C -1 ; WX 500 ; N plusminus ; B 44 0 531 505 ; C -1 ; WX 500 ; N multiply ; B 65 48 544 461 ; C -1 ; WX 500 ; N Eacute ; B 74 0 608 959 ; C -1 ; WX 556 ; N Ydieresis ; B 170 0 705 944 ; C -1 ; WX 300 ; N onesuperior ; B 200 300 392 750 ; C -1 ; WX 500 ; N ugrave ; B 99 -15 542 765 ; C -1 ; WX 500 ; N logicalnot ; B 111 117 539 384 ; C -1 ; WX 500 ; N ntilde ; B 73 0 580 749 ; C -1 ; WX 611 ; N Otilde ; B 116 -18 676 943 ; C -1 ; WX 500 ; N otilde ; B 96 -15 580 749 ; C -1 ; WX 556 ; N Ccedilla ; B 106 -224 624 765 ; C -1 ; WX 556 ; N Agrave ; B 11 0 546 959 ; C -1 ; WX 750 ; N onehalf ; B 91 0 777 750 ; C -1 ; WX 611 ; N Eth ; B 82 0 650 750 ; C -1 ; WX 400 ; N degree ; B 174 450 481 750 ; C -1 ; WX 556 ; N Yacute ; B 170 0 705 959 ; C -1 ; WX 611 ; N Ocircumflex ; B 116 -18 658 959 ; C -1 ; WX 500 ; N oacute ; B 96 -15 545 765 ; C -1 ; WX 500 ; N mu ; B 35 -189 540 556 ; C -1 ; WX 500 ; N minus ; B 91 219 518 289 ; C -1 ; WX 500 ; N eth ; B 96 -15 525 831 ; C -1 ; WX 500 ; N odieresis ; B 96 -15 524 750 ; C -1 ; WX 800 ; N copyright ; B 79 -18 880 765 ; C -1 ; WX 250 ; N brokenbar ; B 56 -175 300 675 ; EndCharMetrics StartKernData StartKernPairs 90 KPX A y -18 KPX A w -18 KPX A v -18 KPX A quoteright -55 KPX A Y -55 KPX A W -37 KPX A V -37 KPX A T -55 KPX F period -111 KPX F comma -111 KPX F A -37 KPX L y -37 KPX L quoteright -92 KPX L Y -92 KPX L W -74 KPX L V -74 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -37 KPX R Y -18 KPX R T -18 KPX T y -55 KPX T w -74 KPX T u -74 KPX T semicolon -74 KPX T s -74 KPX T r -74 KPX T period -92 KPX T o -74 KPX T i -18 KPX T hyphen -55 KPX T e -74 KPX T comma -92 KPX T colon -74 KPX T c -74 KPX T a -74 KPX T A -55 KPX V u -18 KPX V semicolon -18 KPX V r -18 KPX V period -92 KPX V o -18 KPX V hyphen -18 KPX V e -18 KPX V comma -92 KPX V colon -18 KPX V a -18 KPX V A -37 KPX W period -74 KPX W o -18 KPX W hyphen -18 KPX W e -18 KPX W comma -74 KPX W a -18 KPX W A -18 KPX Y v -18 KPX Y u -37 KPX Y semicolon -37 KPX Y q -55 KPX Y period -111 KPX Y p -37 KPX Y o -55 KPX Y i -18 KPX Y hyphen -74 KPX Y e -55 KPX Y comma -111 KPX Y colon -37 KPX Y a -55 KPX Y A -55 KPX f quoteright 18 KPX quoteleft quoteleft -18 KPX quoteright s -55 KPX quoteright quoteright -18 KPX r z 20 KPX r y 18 KPX r x 20 KPX r w 18 KPX r v 18 KPX r period -74 KPX r hyphen -37 KPX r f 20 KPX r comma -74 KPX r c -20 KPX v period -55 KPX v comma -55 KPX w period -37 KPX w comma -37 KPX y period -55 KPX y comma -55 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 153 194 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 153 194 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 153 194 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 153 194 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 194 194 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 153 194 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 125 194 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 125 194 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 125 194 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 125 194 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 194 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 194 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 194 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 194 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 180 194 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 180 194 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 180 194 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 180 194 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 180 194 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 194 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 153 194 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 180 194 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 194 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 194 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 194 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 153 194 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 153 194 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 125 194 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 88 30 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -55 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -55 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -55 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ; EndComposites EndFontMetrics �������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Condensed-Bold.afm������������������������������������������0000644�0001750�0001750�00000036476�11462120062�021634� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Wed Sep 4 17:42:59 1991 Comment UniqueID 36188 Comment VMusage 27402 34294 FontName Helvetica-Condensed-Bold FullName Helvetica Condensed Bold FamilyName Helvetica Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -169 -250 1091 991 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 750 XHeight 564 Ascender 750 Descender -189 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 101 0 232 750 ; C 34 ; WX 333 ; N quotedbl ; B 16 468 318 739 ; C 35 ; WX 500 ; N numbersign ; B 31 0 469 738 ; C 36 ; WX 500 ; N dollar ; B 35 -124 466 803 ; C 37 ; WX 833 ; N percent ; B 31 -15 803 750 ; C 38 ; WX 667 ; N ampersand ; B 63 -18 615 768 ; C 39 ; WX 278 ; N quoteright ; B 81 479 202 750 ; C 40 ; WX 333 ; N parenleft ; B 52 -198 281 768 ; C 41 ; WX 333 ; N parenright ; B 52 -198 281 768 ; C 42 ; WX 500 ; N asterisk ; B 79 412 422 738 ; C 43 ; WX 500 ; N plus ; B 26 0 475 492 ; C 44 ; WX 333 ; N comma ; B 101 -145 233 132 ; C 45 ; WX 333 ; N hyphen ; B 48 255 286 370 ; C 46 ; WX 333 ; N period ; B 101 0 233 132 ; C 47 ; WX 278 ; N slash ; B -11 -94 312 750 ; C 48 ; WX 500 ; N zero ; B 48 -15 453 753 ; C 49 ; WX 500 ; N one ; B 44 0 353 750 ; C 50 ; WX 500 ; N two ; B 32 0 453 753 ; C 51 ; WX 500 ; N three ; B 28 -15 453 753 ; C 52 ; WX 500 ; N four ; B 23 0 470 738 ; C 53 ; WX 500 ; N five ; B 37 -15 458 738 ; C 54 ; WX 500 ; N six ; B 42 -15 459 753 ; C 55 ; WX 500 ; N seven ; B 32 0 454 738 ; C 56 ; WX 500 ; N eight ; B 41 -15 460 753 ; C 57 ; WX 500 ; N nine ; B 42 -15 459 753 ; C 58 ; WX 278 ; N colon ; B 73 0 205 556 ; C 59 ; WX 278 ; N semicolon ; B 73 -145 205 556 ; C 60 ; WX 500 ; N less ; B 42 -24 459 527 ; C 61 ; WX 500 ; N equal ; B 26 96 475 401 ; C 62 ; WX 500 ; N greater ; B 42 -24 459 527 ; C 63 ; WX 500 ; N question ; B 51 0 440 768 ; C 64 ; WX 833 ; N at ; B 38 -18 795 768 ; C 65 ; WX 556 ; N A ; B 9 0 547 750 ; C 66 ; WX 556 ; N B ; B 65 0 506 750 ; C 67 ; WX 556 ; N C ; B 55 -18 512 768 ; C 68 ; WX 611 ; N D ; B 72 0 550 750 ; C 69 ; WX 500 ; N E ; B 64 0 458 750 ; C 70 ; WX 500 ; N F ; B 73 0 470 750 ; C 71 ; WX 611 ; N G ; B 55 -18 542 768 ; C 72 ; WX 611 ; N H ; B 68 0 544 750 ; C 73 ; WX 278 ; N I ; B 69 0 209 750 ; C 74 ; WX 444 ; N J ; B 7 -18 384 750 ; C 75 ; WX 556 ; N K ; B 68 0 547 750 ; C 76 ; WX 500 ; N L ; B 68 0 468 750 ; C 77 ; WX 778 ; N M ; B 67 0 712 750 ; C 78 ; WX 611 ; N N ; B 68 0 543 750 ; C 79 ; WX 611 ; N O ; B 61 -18 551 768 ; C 80 ; WX 556 ; N P ; B 68 0 529 750 ; C 81 ; WX 611 ; N Q ; B 61 -71 587 768 ; C 82 ; WX 611 ; N R ; B 66 0 567 750 ; C 83 ; WX 556 ; N S ; B 49 -18 508 768 ; C 84 ; WX 500 ; N T ; B 17 0 484 750 ; C 85 ; WX 611 ; N U ; B 68 -18 544 750 ; C 86 ; WX 556 ; N V ; B 21 0 536 750 ; C 87 ; WX 833 ; N W ; B 24 0 810 750 ; C 88 ; WX 556 ; N X ; B 11 0 545 750 ; C 89 ; WX 556 ; N Y ; B 12 0 545 750 ; C 90 ; WX 500 ; N Z ; B 33 0 468 750 ; C 91 ; WX 333 ; N bracketleft ; B 81 -94 280 750 ; C 92 ; WX 250 ; N backslash ; B -89 0 340 750 ; C 93 ; WX 333 ; N bracketright ; B 53 -94 252 750 ; C 94 ; WX 500 ; N asciicircum ; B 10 326 490 750 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 278 ; N quoteleft ; B 76 495 197 766 ; C 97 ; WX 500 ; N a ; B 42 -15 440 579 ; C 98 ; WX 500 ; N b ; B 64 -15 444 750 ; C 99 ; WX 444 ; N c ; B 49 -15 403 579 ; C 100 ; WX 500 ; N d ; B 53 -15 433 750 ; C 101 ; WX 500 ; N e ; B 53 -15 443 579 ; C 102 ; WX 278 ; N f ; B 21 0 257 750 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 53 -190 433 579 ; C 104 ; WX 500 ; N h ; B 61 0 440 750 ; C 105 ; WX 278 ; N i ; B 74 0 204 750 ; C 106 ; WX 278 ; N j ; B 31 -192 210 750 ; C 107 ; WX 444 ; N k ; B 48 0 443 750 ; C 108 ; WX 278 ; N l ; B 74 0 204 750 ; C 109 ; WX 778 ; N m ; B 66 0 712 579 ; C 110 ; WX 500 ; N n ; B 61 0 440 579 ; C 111 ; WX 500 ; N o ; B 53 -15 447 579 ; C 112 ; WX 500 ; N p ; B 58 -189 438 579 ; C 113 ; WX 500 ; N q ; B 50 -188 430 579 ; C 114 ; WX 333 ; N r ; B 60 0 319 574 ; C 115 ; WX 444 ; N s ; B 28 -15 407 579 ; C 116 ; WX 278 ; N t ; B 14 -7 252 719 ; C 117 ; WX 500 ; N u ; B 58 -15 431 564 ; C 118 ; WX 444 ; N v ; B 10 0 434 564 ; C 119 ; WX 667 ; N w ; B 11 0 645 564 ; C 120 ; WX 444 ; N x ; B 8 0 436 564 ; C 121 ; WX 444 ; N y ; B 5 -195 429 564 ; C 122 ; WX 389 ; N z ; B 23 0 367 564 ; C 123 ; WX 274 ; N braceleft ; B -32 -92 240 750 ; C 124 ; WX 250 ; N bar ; B 75 -250 175 750 ; C 125 ; WX 274 ; N braceright ; B 34 -94 306 750 ; C 126 ; WX 500 ; N asciitilde ; B 26 153 475 359 ; C 161 ; WX 333 ; N exclamdown ; B 102 -170 232 579 ; C 162 ; WX 500 ; N cent ; B 72 -122 428 671 ; C 163 ; WX 500 ; N sterling ; B 35 -15 487 768 ; C 164 ; WX 167 ; N fraction ; B -169 0 331 738 ; C 165 ; WX 500 ; N yen ; B -18 0 518 750 ; C 166 ; WX 500 ; N florin ; B 9 -185 492 763 ; C 167 ; WX 500 ; N section ; B 37 -183 463 768 ; C 168 ; WX 500 ; N currency ; B 9 58 492 560 ; C 169 ; WX 250 ; N quotesingle ; B 66 468 185 739 ; C 170 ; WX 500 ; N quotedblleft ; B 87 495 405 766 ; C 171 ; WX 500 ; N guillemotleft ; B 74 62 419 447 ; C 172 ; WX 278 ; N guilsinglleft ; B 58 62 215 447 ; C 173 ; WX 278 ; N guilsinglright ; B 63 62 220 447 ; C 174 ; WX 500 ; N fi ; B 10 0 446 750 ; C 175 ; WX 500 ; N fl ; B 10 0 443 750 ; C 177 ; WX 500 ; N endash ; B 0 259 500 369 ; C 178 ; WX 500 ; N dagger ; B 37 -155 463 768 ; C 179 ; WX 500 ; N daggerdbl ; B 35 -161 466 768 ; C 180 ; WX 333 ; N periodcentered ; B 101 183 233 315 ; C 182 ; WX 550 ; N paragraph ; B 23 -116 526 750 ; C 183 ; WX 420 ; N bullet ; B 22 186 398 562 ; C 184 ; WX 278 ; N quotesinglbase ; B 87 -138 207 132 ; C 185 ; WX 500 ; N quotedblbase ; B 96 -138 413 132 ; C 186 ; WX 500 ; N quotedblright ; B 95 479 413 750 ; C 187 ; WX 500 ; N guillemotright ; B 81 62 426 447 ; C 188 ; WX 1000 ; N ellipsis ; B 101 0 899 132 ; C 189 ; WX 1111 ; N perthousand ; B 21 -18 1091 748 ; C 191 ; WX 500 ; N questiondown ; B 60 -190 449 579 ; C 193 ; WX 333 ; N grave ; B 1 629 250 775 ; C 194 ; WX 333 ; N acute ; B 83 629 332 775 ; C 195 ; WX 333 ; N circumflex ; B -10 644 343 790 ; C 196 ; WX 333 ; N tilde ; B -16 636 350 764 ; C 197 ; WX 333 ; N macron ; B -6 666 340 740 ; C 198 ; WX 333 ; N breve ; B -1 635 335 780 ; C 199 ; WX 333 ; N dotaccent ; B 103 644 230 759 ; C 200 ; WX 333 ; N dieresis ; B 5 644 328 759 ; C 202 ; WX 333 ; N ring ; B 60 632 273 845 ; C 203 ; WX 333 ; N cedilla ; B 39 -228 275 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -17 634 447 780 ; C 206 ; WX 333 ; N ogonek ; B 88 -205 278 0 ; C 207 ; WX 333 ; N caron ; B -10 634 343 780 ; C 208 ; WX 1000 ; N emdash ; B 0 259 1000 369 ; C 225 ; WX 778 ; N AE ; B -22 0 750 750 ; C 227 ; WX 300 ; N ordfeminine ; B 22 412 281 768 ; C 232 ; WX 500 ; N Lslash ; B 0 0 474 750 ; C 233 ; WX 611 ; N Oslash ; B 36 -38 578 779 ; C 234 ; WX 833 ; N OE ; B 61 -18 792 768 ; C 235 ; WX 300 ; N ordmasculine ; B 22 412 278 768 ; C 241 ; WX 722 ; N ae ; B 44 -15 672 579 ; C 245 ; WX 278 ; N dotlessi ; B 74 0 204 564 ; C 248 ; WX 278 ; N lslash ; B 2 0 272 750 ; C 249 ; WX 500 ; N oslash ; B 7 -58 492 617 ; C 250 ; WX 722 ; N oe ; B 46 -15 678 579 ; C 251 ; WX 500 ; N germandbls ; B 60 -15 445 768 ; C -1 ; WX 500 ; N ecircumflex ; B 53 -15 443 770 ; C -1 ; WX 500 ; N edieresis ; B 53 -15 443 759 ; C -1 ; WX 500 ; N aacute ; B 42 -15 440 775 ; C -1 ; WX 830 ; N registered ; B 22 -18 808 768 ; C -1 ; WX 278 ; N icircumflex ; B -47 0 306 770 ; C -1 ; WX 500 ; N udieresis ; B 58 -15 431 759 ; C -1 ; WX 500 ; N ograve ; B 53 -15 447 775 ; C -1 ; WX 500 ; N uacute ; B 58 -15 431 775 ; C -1 ; WX 500 ; N ucircumflex ; B 58 -15 431 780 ; C -1 ; WX 556 ; N Aacute ; B 9 0 547 961 ; C -1 ; WX 278 ; N igrave ; B -26 0 223 775 ; C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 956 ; C -1 ; WX 444 ; N ccedilla ; B 49 -228 403 579 ; C -1 ; WX 500 ; N adieresis ; B 42 -15 440 759 ; C -1 ; WX 500 ; N Ecircumflex ; B 64 0 458 956 ; C -1 ; WX 444 ; N scaron ; B 28 -15 407 760 ; C -1 ; WX 500 ; N thorn ; B 58 -189 438 750 ; C -1 ; WX 860 ; N trademark ; B 1 346 774 750 ; C -1 ; WX 500 ; N egrave ; B 53 -15 443 775 ; C -1 ; WX 300 ; N threesuperior ; B 12 290 288 751 ; C -1 ; WX 389 ; N zcaron ; B 18 0 371 760 ; C -1 ; WX 500 ; N atilde ; B 42 -15 440 744 ; C -1 ; WX 500 ; N aring ; B 42 -15 440 835 ; C -1 ; WX 500 ; N ocircumflex ; B 53 -15 447 770 ; C -1 ; WX 500 ; N Edieresis ; B 64 0 458 945 ; C -1 ; WX 750 ; N threequarters ; B 12 0 739 751 ; C -1 ; WX 444 ; N ydieresis ; B 5 -195 429 759 ; C -1 ; WX 444 ; N yacute ; B 5 -195 429 775 ; C -1 ; WX 278 ; N iacute ; B 56 0 305 775 ; C -1 ; WX 556 ; N Acircumflex ; B 9 0 547 956 ; C -1 ; WX 611 ; N Uacute ; B 68 -18 544 961 ; C -1 ; WX 500 ; N eacute ; B 53 -15 443 775 ; C -1 ; WX 611 ; N Ograve ; B 61 -18 551 961 ; C -1 ; WX 500 ; N agrave ; B 42 -15 440 775 ; C -1 ; WX 611 ; N Udieresis ; B 68 -18 544 945 ; C -1 ; WX 500 ; N acircumflex ; B 42 -15 440 770 ; C -1 ; WX 278 ; N Igrave ; B -26 0 223 961 ; C -1 ; WX 300 ; N twosuperior ; B 13 300 287 752 ; C -1 ; WX 611 ; N Ugrave ; B 68 -18 544 961 ; C -1 ; WX 750 ; N onequarter ; B 20 0 729 750 ; C -1 ; WX 611 ; N Ucircumflex ; B 68 -18 544 956 ; C -1 ; WX 556 ; N Scaron ; B 49 -18 508 946 ; C -1 ; WX 278 ; N Idieresis ; B -22 0 301 945 ; C -1 ; WX 278 ; N idieresis ; B -22 0 301 759 ; C -1 ; WX 500 ; N Egrave ; B 64 0 458 961 ; C -1 ; WX 611 ; N Oacute ; B 61 -18 551 961 ; C -1 ; WX 500 ; N divide ; B 26 6 475 492 ; C -1 ; WX 556 ; N Atilde ; B 9 0 547 930 ; C -1 ; WX 556 ; N Aring ; B 9 0 547 991 ; C -1 ; WX 611 ; N Odieresis ; B 61 -18 551 945 ; C -1 ; WX 556 ; N Adieresis ; B 9 0 547 945 ; C -1 ; WX 611 ; N Ntilde ; B 68 0 543 930 ; C -1 ; WX 500 ; N Zcaron ; B 33 0 468 946 ; C -1 ; WX 556 ; N Thorn ; B 68 0 529 750 ; C -1 ; WX 278 ; N Iacute ; B 56 0 305 961 ; C -1 ; WX 500 ; N plusminus ; B 26 -15 475 513 ; C -1 ; WX 500 ; N multiply ; B 26 22 475 476 ; C -1 ; WX 500 ; N Eacute ; B 64 0 458 961 ; C -1 ; WX 556 ; N Ydieresis ; B 12 0 545 945 ; C -1 ; WX 300 ; N onesuperior ; B 50 300 251 750 ; C -1 ; WX 500 ; N ugrave ; B 58 -15 431 775 ; C -1 ; WX 500 ; N logicalnot ; B 26 105 475 401 ; C -1 ; WX 500 ; N ntilde ; B 61 0 440 744 ; C -1 ; WX 611 ; N Otilde ; B 61 -18 551 930 ; C -1 ; WX 500 ; N otilde ; B 53 -15 447 744 ; C -1 ; WX 556 ; N Ccedilla ; B 55 -228 512 768 ; C -1 ; WX 556 ; N Agrave ; B 9 0 547 961 ; C -1 ; WX 750 ; N onehalf ; B 12 0 739 750 ; C -1 ; WX 611 ; N Eth ; B 20 0 550 750 ; C -1 ; WX 400 ; N degree ; B 50 450 350 750 ; C -1 ; WX 556 ; N Yacute ; B 12 0 545 961 ; C -1 ; WX 611 ; N Ocircumflex ; B 61 -18 551 956 ; C -1 ; WX 500 ; N oacute ; B 53 -15 447 775 ; C -1 ; WX 500 ; N mu ; B 58 -189 431 564 ; C -1 ; WX 500 ; N minus ; B 26 194 475 304 ; C -1 ; WX 500 ; N eth ; B 53 -15 447 779 ; C -1 ; WX 500 ; N odieresis ; B 53 -15 447 759 ; C -1 ; WX 830 ; N copyright ; B 22 -18 808 768 ; C -1 ; WX 250 ; N brokenbar ; B 75 -175 175 675 ; EndCharMetrics StartKernData StartKernPairs 88 KPX A y -18 KPX A w -18 KPX A v -18 KPX A quoteright -55 KPX A Y -55 KPX A W -37 KPX A V -37 KPX A T -55 KPX F period -111 KPX F comma -111 KPX F A -37 KPX L y -37 KPX L quoteright -92 KPX L Y -92 KPX L W -74 KPX L V -74 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -37 KPX R Y -18 KPX R T -18 KPX T y -55 KPX T w -74 KPX T u -74 KPX T semicolon -74 KPX T s -74 KPX T r -74 KPX T period -92 KPX T o -74 KPX T i -18 KPX T hyphen -55 KPX T e -74 KPX T comma -92 KPX T colon -74 KPX T c -74 KPX T a -74 KPX T A -55 KPX V u -18 KPX V semicolon -18 KPX V r -18 KPX V period -92 KPX V o -18 KPX V hyphen -18 KPX V e -18 KPX V comma -92 KPX V colon -18 KPX V a -18 KPX V A -37 KPX W period -74 KPX W o -18 KPX W hyphen -18 KPX W e -18 KPX W comma -74 KPX W a -18 KPX W A -18 KPX Y v -18 KPX Y u -37 KPX Y semicolon -37 KPX Y q -55 KPX Y period -111 KPX Y p -37 KPX Y o -55 KPX Y i -18 KPX Y hyphen -74 KPX Y e -55 KPX Y comma -111 KPX Y colon -37 KPX Y a -55 KPX Y A -55 KPX f quoteright 18 KPX quoteleft quoteleft -18 KPX quoteright s -55 KPX quoteright quoteright -18 KPX r z 20 KPX r y 18 KPX r x 20 KPX r w 18 KPX r v 18 KPX r period -74 KPX r hyphen -37 KPX r comma -74 KPX v period -55 KPX v comma -55 KPX w period -37 KPX w comma -37 KPX y period -55 KPX y comma -55 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 112 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 102 166 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 112 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 112 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 112 146 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 112 166 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 84 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 84 166 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 84 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 166 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 139 166 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 139 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 139 166 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 139 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 139 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 139 166 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 166 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 139 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 139 166 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 139 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 139 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 112 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 84 166 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 -20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 69 -10 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 -20 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 -20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -37 -20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 -20 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 -20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 -20 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 46 -20 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 -10 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 -20 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/AvantGarde-BookOblique.afm��������������������������������������������0000644�0001750�0001750�00000043000�11462120062�021354� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Mar 4 13:41:11 1991 Comment UniqueID 34367 Comment VMusage 6555 39267 FontName AvantGarde-BookOblique FullName ITC Avant Garde Gothic Book Oblique FamilyName ITC Avant Garde Gothic Weight Book ItalicAngle -10.5 IsFixedPitch false FontBBox -113 -222 1279 955 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 740 XHeight 547 Ascender 740 Descender -192 StartCharMetrics 228 C 32 ; WX 277 ; N space ; B 0 0 0 0 ; C 33 ; WX 295 ; N exclam ; B 111 0 322 740 ; C 34 ; WX 309 ; N quotedbl ; B 130 444 410 740 ; C 35 ; WX 554 ; N numbersign ; B 71 0 620 740 ; C 36 ; WX 554 ; N dollar ; B 107 -70 581 811 ; C 37 ; WX 775 ; N percent ; B 124 -13 787 751 ; C 38 ; WX 757 ; N ampersand ; B 92 -12 775 753 ; C 39 ; WX 351 ; N quoteright ; B 195 546 393 740 ; C 40 ; WX 369 ; N parenleft ; B 89 -205 495 757 ; C 41 ; WX 369 ; N parenright ; B -24 -205 382 757 ; C 42 ; WX 425 ; N asterisk ; B 170 446 479 740 ; C 43 ; WX 606 ; N plus ; B 92 0 608 506 ; C 44 ; WX 277 ; N comma ; B 2 -67 199 126 ; C 45 ; WX 332 ; N hyphen ; B 76 248 360 315 ; C 46 ; WX 277 ; N period ; B 102 0 199 126 ; C 47 ; WX 437 ; N slash ; B 25 -100 540 740 ; C 48 ; WX 554 ; N zero ; B 71 -13 622 753 ; C 49 ; WX 554 ; N one ; B 260 0 473 740 ; C 50 ; WX 554 ; N two ; B 40 0 615 753 ; C 51 ; WX 554 ; N three ; B 73 -13 565 753 ; C 52 ; WX 554 ; N four ; B 39 0 598 740 ; C 53 ; WX 554 ; N five ; B 69 -13 605 740 ; C 54 ; WX 554 ; N six ; B 65 -13 580 739 ; C 55 ; WX 554 ; N seven ; B 110 0 628 740 ; C 56 ; WX 554 ; N eight ; B 77 -13 580 753 ; C 57 ; WX 554 ; N nine ; B 111 0 626 752 ; C 58 ; WX 277 ; N colon ; B 102 0 278 548 ; C 59 ; WX 277 ; N semicolon ; B 2 -67 278 548 ; C 60 ; WX 606 ; N less ; B 87 -8 649 514 ; C 61 ; WX 606 ; N equal ; B 73 118 627 388 ; C 62 ; WX 606 ; N greater ; B 51 -8 613 514 ; C 63 ; WX 591 ; N question ; B 158 0 628 752 ; C 64 ; WX 867 ; N at ; B 126 -13 888 753 ; C 65 ; WX 740 ; N A ; B 12 0 729 740 ; C 66 ; WX 574 ; N B ; B 74 0 606 740 ; C 67 ; WX 813 ; N C ; B 105 -13 870 752 ; C 68 ; WX 744 ; N D ; B 74 0 773 740 ; C 69 ; WX 536 ; N E ; B 70 0 612 740 ; C 70 ; WX 485 ; N F ; B 70 0 581 740 ; C 71 ; WX 872 ; N G ; B 103 -13 891 753 ; C 72 ; WX 683 ; N H ; B 76 0 744 740 ; C 73 ; WX 226 ; N I ; B 76 0 287 740 ; C 74 ; WX 482 ; N J ; B 37 -13 539 740 ; C 75 ; WX 591 ; N K ; B 81 0 728 740 ; C 76 ; WX 462 ; N L ; B 82 0 474 740 ; C 77 ; WX 919 ; N M ; B 76 0 980 740 ; C 78 ; WX 740 ; N N ; B 75 0 801 740 ; C 79 ; WX 869 ; N O ; B 105 -13 901 753 ; C 80 ; WX 592 ; N P ; B 75 0 664 740 ; C 81 ; WX 871 ; N Q ; B 102 -13 912 753 ; C 82 ; WX 607 ; N R ; B 70 0 669 740 ; C 83 ; WX 498 ; N S ; B 57 -13 561 753 ; C 84 ; WX 426 ; N T ; B 131 0 556 740 ; C 85 ; WX 655 ; N U ; B 118 -13 716 740 ; C 86 ; WX 702 ; N V ; B 145 0 830 740 ; C 87 ; WX 960 ; N W ; B 148 0 1087 740 ; C 88 ; WX 609 ; N X ; B 8 0 724 740 ; C 89 ; WX 592 ; N Y ; B 138 0 729 740 ; C 90 ; WX 480 ; N Z ; B 12 0 596 740 ; C 91 ; WX 351 ; N bracketleft ; B 145 -179 477 753 ; C 92 ; WX 605 ; N backslash ; B 255 -100 458 740 ; C 93 ; WX 351 ; N bracketright ; B -19 -179 312 753 ; C 94 ; WX 606 ; N asciicircum ; B 110 307 610 740 ; C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ; C 96 ; WX 351 ; N quoteleft ; B 232 546 358 740 ; C 97 ; WX 683 ; N a ; B 88 -13 722 561 ; C 98 ; WX 682 ; N b ; B 68 -13 703 740 ; C 99 ; WX 647 ; N c ; B 87 -13 678 561 ; C 100 ; WX 685 ; N d ; B 85 -13 755 740 ; C 101 ; WX 650 ; N e ; B 84 -13 664 561 ; C 102 ; WX 314 ; N f ; B 104 0 454 753 ; L i fi ; L l fl ; C 103 ; WX 673 ; N g ; B 56 -215 707 561 ; C 104 ; WX 610 ; N h ; B 62 0 606 740 ; C 105 ; WX 200 ; N i ; B 65 0 272 740 ; C 106 ; WX 203 ; N j ; B -80 -192 274 740 ; C 107 ; WX 502 ; N k ; B 70 0 588 740 ; C 108 ; WX 200 ; N l ; B 65 0 272 740 ; C 109 ; WX 938 ; N m ; B 66 0 938 561 ; C 110 ; WX 610 ; N n ; B 65 0 609 561 ; C 111 ; WX 655 ; N o ; B 88 -13 669 561 ; C 112 ; WX 682 ; N p ; B 28 -192 699 561 ; C 113 ; WX 682 ; N q ; B 83 -192 717 561 ; C 114 ; WX 301 ; N r ; B 65 0 395 561 ; C 115 ; WX 388 ; N s ; B 49 -13 424 561 ; C 116 ; WX 339 ; N t ; B 104 0 431 740 ; C 117 ; WX 608 ; N u ; B 100 -13 642 547 ; C 118 ; WX 554 ; N v ; B 108 0 647 547 ; C 119 ; WX 831 ; N w ; B 114 0 921 547 ; C 120 ; WX 480 ; N x ; B 12 0 569 547 ; C 121 ; WX 536 ; N y ; B 97 -192 624 547 ; C 122 ; WX 425 ; N z ; B 10 0 498 547 ; C 123 ; WX 351 ; N braceleft ; B 115 -189 468 740 ; C 124 ; WX 672 ; N bar ; B 280 -100 510 740 ; C 125 ; WX 351 ; N braceright ; B -15 -189 338 740 ; C 126 ; WX 606 ; N asciitilde ; B 114 179 584 319 ; C 161 ; WX 295 ; N exclamdown ; B 74 -192 286 548 ; C 162 ; WX 554 ; N cent ; B 115 62 596 707 ; C 163 ; WX 554 ; N sterling ; B 29 0 614 753 ; C 164 ; WX 166 ; N fraction ; B -113 0 417 740 ; C 165 ; WX 554 ; N yen ; B 75 0 687 740 ; C 166 ; WX 554 ; N florin ; B -39 -153 669 818 ; C 167 ; WX 615 ; N section ; B 118 -141 597 753 ; C 168 ; WX 554 ; N currency ; B 24 42 645 580 ; C 169 ; WX 198 ; N quotesingle ; B 153 444 277 740 ; C 170 ; WX 502 ; N quotedblleft ; B 234 546 507 740 ; C 171 ; WX 425 ; N guillemotleft ; B 92 81 469 481 ; C 172 ; WX 251 ; N guilsinglleft ; B 92 81 295 481 ; C 173 ; WX 251 ; N guilsinglright ; B 60 81 263 481 ; C 174 ; WX 487 ; N fi ; B 104 0 559 753 ; C 175 ; WX 485 ; N fl ; B 104 0 557 753 ; C 177 ; WX 500 ; N endash ; B 81 248 523 315 ; C 178 ; WX 553 ; N dagger ; B 146 -133 593 740 ; C 179 ; WX 553 ; N daggerdbl ; B 72 -133 593 740 ; C 180 ; WX 277 ; N periodcentered ; B 137 190 235 316 ; C 182 ; WX 564 ; N paragraph ; B 119 -110 688 740 ; C 183 ; WX 606 ; N bullet ; B 217 222 528 532 ; C 184 ; WX 354 ; N quotesinglbase ; B 76 -68 274 126 ; C 185 ; WX 502 ; N quotedblbase ; B 76 -68 422 126 ; C 186 ; WX 484 ; N quotedblright ; B 197 546 542 740 ; C 187 ; WX 425 ; N guillemotright ; B 60 81 437 481 ; C 188 ; WX 1000 ; N ellipsis ; B 130 0 893 126 ; C 189 ; WX 1174 ; N perthousand ; B 128 -13 1182 751 ; C 191 ; WX 591 ; N questiondown ; B 64 -205 534 548 ; C 193 ; WX 378 ; N grave ; B 204 619 425 786 ; C 194 ; WX 375 ; N acute ; B 203 619 444 786 ; C 195 ; WX 502 ; N circumflex ; B 192 639 546 764 ; C 196 ; WX 439 ; N tilde ; B 179 651 520 754 ; C 197 ; WX 485 ; N macron ; B 197 669 547 736 ; C 198 ; WX 453 ; N breve ; B 192 651 541 754 ; C 199 ; WX 222 ; N dotaccent ; B 192 639 290 765 ; C 200 ; WX 369 ; N dieresis ; B 191 639 437 765 ; C 202 ; WX 332 ; N ring ; B 191 600 401 807 ; C 203 ; WX 324 ; N cedilla ; B 52 -222 231 0 ; C 205 ; WX 552 ; N hungarumlaut ; B 239 605 594 800 ; C 206 ; WX 302 ; N ogonek ; B 53 -191 202 0 ; C 207 ; WX 502 ; N caron ; B 210 639 565 764 ; C 208 ; WX 1000 ; N emdash ; B 81 248 1023 315 ; C 225 ; WX 992 ; N AE ; B -20 0 1044 740 ; C 227 ; WX 369 ; N ordfeminine ; B 102 407 494 753 ; C 232 ; WX 517 ; N Lslash ; B 107 0 529 740 ; C 233 ; WX 868 ; N Oslash ; B 76 -83 929 819 ; C 234 ; WX 1194 ; N OE ; B 107 -13 1279 753 ; C 235 ; WX 369 ; N ordmasculine ; B 116 407 466 753 ; C 241 ; WX 1157 ; N ae ; B 80 -13 1169 561 ; C 245 ; WX 200 ; N dotlessi ; B 65 0 236 547 ; C 248 ; WX 300 ; N lslash ; B 95 0 354 740 ; C 249 ; WX 653 ; N oslash ; B 51 -64 703 614 ; C 250 ; WX 1137 ; N oe ; B 80 -13 1160 561 ; C 251 ; WX 554 ; N germandbls ; B 61 -13 578 753 ; C -1 ; WX 650 ; N ecircumflex ; B 84 -13 664 764 ; C -1 ; WX 650 ; N edieresis ; B 84 -13 664 765 ; C -1 ; WX 683 ; N aacute ; B 88 -13 722 786 ; C -1 ; WX 747 ; N registered ; B 53 -12 830 752 ; C -1 ; WX 200 ; N icircumflex ; B 41 0 395 764 ; C -1 ; WX 608 ; N udieresis ; B 100 -13 642 765 ; C -1 ; WX 655 ; N ograve ; B 88 -13 669 786 ; C -1 ; WX 608 ; N uacute ; B 100 -13 642 786 ; C -1 ; WX 608 ; N ucircumflex ; B 100 -13 642 764 ; C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ; C -1 ; WX 200 ; N igrave ; B 65 0 296 786 ; C -1 ; WX 226 ; N Icircumflex ; B 76 0 439 927 ; C -1 ; WX 647 ; N ccedilla ; B 87 -222 678 561 ; C -1 ; WX 683 ; N adieresis ; B 88 -13 722 765 ; C -1 ; WX 536 ; N Ecircumflex ; B 70 0 612 927 ; C -1 ; WX 388 ; N scaron ; B 49 -13 508 764 ; C -1 ; WX 682 ; N thorn ; B 28 -192 699 740 ; C -1 ; WX 1000 ; N trademark ; B 137 296 953 740 ; C -1 ; WX 650 ; N egrave ; B 84 -13 664 786 ; C -1 ; WX 332 ; N threesuperior ; B 98 289 408 747 ; C -1 ; WX 425 ; N zcaron ; B 10 0 527 764 ; C -1 ; WX 683 ; N atilde ; B 88 -13 722 754 ; C -1 ; WX 683 ; N aring ; B 88 -13 722 807 ; C -1 ; WX 655 ; N ocircumflex ; B 88 -13 669 764 ; C -1 ; WX 536 ; N Edieresis ; B 70 0 612 928 ; C -1 ; WX 831 ; N threequarters ; B 126 0 825 747 ; C -1 ; WX 536 ; N ydieresis ; B 97 -192 624 765 ; C -1 ; WX 536 ; N yacute ; B 97 -192 624 786 ; C -1 ; WX 200 ; N iacute ; B 65 0 397 786 ; C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ; C -1 ; WX 655 ; N Uacute ; B 118 -13 716 949 ; C -1 ; WX 650 ; N eacute ; B 84 -13 664 786 ; C -1 ; WX 869 ; N Ograve ; B 105 -13 901 949 ; C -1 ; WX 683 ; N agrave ; B 88 -13 722 786 ; C -1 ; WX 655 ; N Udieresis ; B 118 -13 716 928 ; C -1 ; WX 683 ; N acircumflex ; B 88 -13 722 764 ; C -1 ; WX 226 ; N Igrave ; B 76 0 340 949 ; C -1 ; WX 332 ; N twosuperior ; B 74 296 433 747 ; C -1 ; WX 655 ; N Ugrave ; B 118 -13 716 949 ; C -1 ; WX 831 ; N onequarter ; B 183 0 770 740 ; C -1 ; WX 655 ; N Ucircumflex ; B 118 -13 716 927 ; C -1 ; WX 498 ; N Scaron ; B 57 -13 593 927 ; C -1 ; WX 226 ; N Idieresis ; B 76 0 396 928 ; C -1 ; WX 200 ; N idieresis ; B 65 0 353 765 ; C -1 ; WX 536 ; N Egrave ; B 70 0 612 949 ; C -1 ; WX 869 ; N Oacute ; B 105 -13 901 949 ; C -1 ; WX 606 ; N divide ; B 92 -13 608 519 ; C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ; C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ; C -1 ; WX 869 ; N Odieresis ; B 105 -13 901 928 ; C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ; C -1 ; WX 740 ; N Ntilde ; B 75 0 801 917 ; C -1 ; WX 480 ; N Zcaron ; B 12 0 596 927 ; C -1 ; WX 592 ; N Thorn ; B 60 0 621 740 ; C -1 ; WX 226 ; N Iacute ; B 76 0 440 949 ; C -1 ; WX 606 ; N plusminus ; B 47 -24 618 518 ; C -1 ; WX 606 ; N multiply ; B 87 24 612 482 ; C -1 ; WX 536 ; N Eacute ; B 70 0 612 949 ; C -1 ; WX 592 ; N Ydieresis ; B 138 0 729 928 ; C -1 ; WX 332 ; N onesuperior ; B 190 296 335 740 ; C -1 ; WX 608 ; N ugrave ; B 100 -13 642 786 ; C -1 ; WX 606 ; N logicalnot ; B 110 109 627 388 ; C -1 ; WX 610 ; N ntilde ; B 65 0 609 754 ; C -1 ; WX 869 ; N Otilde ; B 105 -13 901 917 ; C -1 ; WX 655 ; N otilde ; B 88 -13 669 754 ; C -1 ; WX 813 ; N Ccedilla ; B 105 -222 870 752 ; C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ; C -1 ; WX 831 ; N onehalf ; B 164 0 810 740 ; C -1 ; WX 790 ; N Eth ; B 104 0 813 740 ; C -1 ; WX 400 ; N degree ; B 158 421 451 709 ; C -1 ; WX 592 ; N Yacute ; B 138 0 729 949 ; C -1 ; WX 869 ; N Ocircumflex ; B 105 -13 901 927 ; C -1 ; WX 655 ; N oacute ; B 88 -13 669 786 ; C -1 ; WX 608 ; N mu ; B 46 -184 628 547 ; C -1 ; WX 606 ; N minus ; B 92 219 608 287 ; C -1 ; WX 655 ; N eth ; B 88 -12 675 753 ; C -1 ; WX 655 ; N odieresis ; B 88 -13 669 765 ; C -1 ; WX 747 ; N copyright ; B 53 -12 830 752 ; C -1 ; WX 672 ; N brokenbar ; B 280 -100 510 740 ; EndCharMetrics StartKernData StartKernPairs 216 KPX A y -62 KPX A w -65 KPX A v -70 KPX A u -20 KPX A quoteright -100 KPX A quotedblright -100 KPX A Y -92 KPX A W -60 KPX A V -102 KPX A U -40 KPX A T -45 KPX A Q -40 KPX A O -50 KPX A G -40 KPX A C -40 KPX B A -10 KPX C A -40 KPX D period -20 KPX D comma -20 KPX D Y -30 KPX D W -10 KPX D V -50 KPX D A -50 KPX F period -160 KPX F e -20 KPX F comma -180 KPX F a -20 KPX F A -75 KPX G period -20 KPX G comma -20 KPX G Y -20 KPX J period -15 KPX J a -20 KPX J A -30 KPX K o -15 KPX K e -20 KPX K O -20 KPX L y -23 KPX L quoteright -130 KPX L quotedblright -130 KPX L Y -91 KPX L W -67 KPX L V -113 KPX L T -46 KPX O period -30 KPX O comma -30 KPX O Y -30 KPX O X -30 KPX O W -20 KPX O V -60 KPX O T -30 KPX O A -60 KPX P period -300 KPX P o -60 KPX P e -20 KPX P comma -280 KPX P a -20 KPX P A -114 KPX Q comma 20 KPX R Y -10 KPX R W 10 KPX R V -10 KPX R T 6 KPX S comma 20 KPX T y -50 KPX T w -55 KPX T u -46 KPX T semicolon -29 KPX T r -30 KPX T period -91 KPX T o -70 KPX T i 10 KPX T hyphen -75 KPX T e -49 KPX T comma -82 KPX T colon -15 KPX T a -90 KPX T O -30 KPX T A -45 KPX U period -20 KPX U comma -20 KPX U A -40 KPX V u -40 KPX V semicolon -33 KPX V period -165 KPX V o -101 KPX V i -5 KPX V hyphen -75 KPX V e -101 KPX V comma -145 KPX V colon -18 KPX V a -104 KPX V O -60 KPX V G -20 KPX V A -102 KPX W y -2 KPX W u -30 KPX W semicolon -33 KPX W period -106 KPX W o -46 KPX W i 6 KPX W hyphen -35 KPX W e -47 KPX W comma -106 KPX W colon -15 KPX W a -50 KPX W O -20 KPX W A -58 KPX Y u -52 KPX Y semicolon -23 KPX Y period -175 KPX Y o -89 KPX Y hyphen -85 KPX Y e -89 KPX Y comma -145 KPX Y colon -10 KPX Y a -93 KPX Y O -30 KPX Y A -92 KPX a p 20 KPX a b 20 KPX b y -20 KPX b v -20 KPX c y -20 KPX c k -15 KPX comma space -110 KPX comma quoteright -120 KPX comma quotedblright -120 KPX e y -20 KPX e w -20 KPX e v -20 KPX f period -50 KPX f o -40 KPX f l -30 KPX f i -34 KPX f f -60 KPX f e -20 KPX f dotlessi -34 KPX f comma -50 KPX f a -40 KPX g a -15 KPX h y -30 KPX k y -5 KPX k e -15 KPX m y -20 KPX m u -20 KPX m a -20 KPX n y -15 KPX n v -20 KPX o y -20 KPX o x -15 KPX o w -20 KPX o v -30 KPX p y -20 KPX period space -110 KPX period quoteright -120 KPX period quotedblright -120 KPX quotedblleft quoteleft -35 KPX quotedblleft A -100 KPX quotedblright space -110 KPX quoteleft quoteleft -203 KPX quoteleft A -100 KPX quoteright v -30 KPX quoteright t 10 KPX quoteright space -110 KPX quoteright s -15 KPX quoteright r -20 KPX quoteright quoteright -203 KPX quoteright quotedblright -35 KPX quoteright d -110 KPX r y 40 KPX r v 40 KPX r u 20 KPX r t 20 KPX r s 20 KPX r q -8 KPX r period -73 KPX r p 20 KPX r o -20 KPX r n 21 KPX r m 28 KPX r l 20 KPX r k 20 KPX r i 20 KPX r hyphen -60 KPX r g -15 KPX r e -4 KPX r d -6 KPX r comma -75 KPX r c -20 KPX r a -20 KPX s period 20 KPX s comma 20 KPX space quoteleft -110 KPX space quotedblleft -110 KPX space Y -60 KPX space W -25 KPX space V -50 KPX space T -25 KPX space A -20 KPX v period -130 KPX v o -30 KPX v e -20 KPX v comma -100 KPX v a -30 KPX w period -100 KPX w o -30 KPX w h 15 KPX w e -20 KPX w comma -90 KPX w a -30 KPX y period -125 KPX y o -30 KPX y e -20 KPX y comma -110 KPX y a -30 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 163 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 149 163 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 216 163 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 211 163 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 231 148 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 181 163 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 111 163 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 47 163 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 114 163 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 109 163 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -4 163 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -108 163 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -41 163 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -86 163 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 163 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 277 163 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 214 163 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 280 163 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 276 163 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 245 163 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 28 163 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 190 163 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 107 163 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 173 163 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 149 163 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 159 163 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 163 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 19 163 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ; EndComposites EndFontMetrics ./saods9/blt3.0.1/library/afm/Helvetica-Condensed-BoldObl.afm���������������������������������������0000644�0001750�0001750�00000036605�11462120062�022263� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Wed Sep 4 17:46:28 1991 Comment UniqueID 36191 Comment VMusage 8125 43764 FontName Helvetica-Condensed-BoldObl FullName Helvetica Condensed Bold Oblique FamilyName Helvetica Weight Bold ItalicAngle -12 IsFixedPitch false FontBBox -169 -250 1141 991 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1991 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 750 XHeight 564 Ascender 750 Descender -189 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 102 0 390 750 ; C 34 ; WX 333 ; N quotedbl ; B 115 468 475 739 ; C 35 ; WX 500 ; N numbersign ; B 81 0 580 738 ; C 36 ; WX 500 ; N dollar ; B 68 -124 576 803 ; C 37 ; WX 833 ; N percent ; B 138 -15 853 750 ; C 38 ; WX 667 ; N ampersand ; B 101 -18 676 768 ; C 39 ; WX 278 ; N quoteright ; B 183 479 361 750 ; C 40 ; WX 333 ; N parenleft ; B 91 -198 442 768 ; C 41 ; WX 333 ; N parenright ; B 12 -198 363 768 ; C 42 ; WX 500 ; N asterisk ; B 203 412 546 738 ; C 43 ; WX 500 ; N plus ; B 67 0 540 492 ; C 44 ; WX 333 ; N comma ; B 70 -145 261 132 ; C 45 ; WX 333 ; N hyphen ; B 102 255 365 370 ; C 46 ; WX 333 ; N period ; B 101 0 261 132 ; C 47 ; WX 278 ; N slash ; B -31 -94 471 750 ; C 48 ; WX 500 ; N zero ; B 82 -15 576 753 ; C 49 ; WX 500 ; N one ; B 155 0 512 750 ; C 50 ; WX 500 ; N two ; B 32 0 577 753 ; C 51 ; WX 500 ; N three ; B 61 -15 563 753 ; C 52 ; WX 500 ; N four ; B 55 0 563 738 ; C 53 ; WX 500 ; N five ; B 72 -15 581 738 ; C 54 ; WX 500 ; N six ; B 83 -15 575 753 ; C 55 ; WX 500 ; N seven ; B 126 0 611 738 ; C 56 ; WX 500 ; N eight ; B 76 -15 570 753 ; C 57 ; WX 500 ; N nine ; B 84 -15 575 753 ; C 58 ; WX 278 ; N colon ; B 73 0 323 556 ; C 59 ; WX 278 ; N semicolon ; B 42 -145 323 556 ; C 60 ; WX 500 ; N less ; B 85 -24 571 527 ; C 61 ; WX 500 ; N equal ; B 46 96 560 401 ; C 62 ; WX 500 ; N greater ; B 37 -24 523 527 ; C 63 ; WX 500 ; N question ; B 147 0 569 768 ; C 64 ; WX 833 ; N at ; B 109 -18 897 768 ; C 65 ; WX 556 ; N A ; B 9 0 547 750 ; C 66 ; WX 556 ; N B ; B 65 0 615 750 ; C 67 ; WX 556 ; N C ; B 99 -18 630 768 ; C 68 ; WX 611 ; N D ; B 72 0 662 750 ; C 69 ; WX 500 ; N E ; B 64 0 617 750 ; C 70 ; WX 500 ; N F ; B 73 0 629 750 ; C 71 ; WX 611 ; N G ; B 99 -18 664 768 ; C 72 ; WX 611 ; N H ; B 68 0 703 750 ; C 73 ; WX 278 ; N I ; B 69 0 368 750 ; C 74 ; WX 444 ; N J ; B 36 -18 543 750 ; C 75 ; WX 556 ; N K ; B 68 0 697 750 ; C 76 ; WX 500 ; N L ; B 68 0 491 750 ; C 77 ; WX 778 ; N M ; B 67 0 871 750 ; C 78 ; WX 611 ; N N ; B 68 0 702 750 ; C 79 ; WX 611 ; N O ; B 105 -18 664 768 ; C 80 ; WX 556 ; N P ; B 68 0 651 750 ; C 81 ; WX 611 ; N Q ; B 105 -71 664 768 ; C 82 ; WX 611 ; N R ; B 66 0 671 750 ; C 83 ; WX 556 ; N S ; B 85 -18 613 768 ; C 84 ; WX 500 ; N T ; B 153 0 643 750 ; C 85 ; WX 611 ; N U ; B 105 -18 703 750 ; C 86 ; WX 556 ; N V ; B 180 0 695 750 ; C 87 ; WX 833 ; N W ; B 167 0 969 750 ; C 88 ; WX 556 ; N X ; B 11 0 698 750 ; C 89 ; WX 556 ; N Y ; B 171 0 704 750 ; C 90 ; WX 500 ; N Z ; B 33 0 618 750 ; C 91 ; WX 333 ; N bracketleft ; B 61 -94 439 750 ; C 92 ; WX 250 ; N backslash ; B 70 0 340 750 ; C 93 ; WX 333 ; N bracketright ; B 33 -94 411 750 ; C 94 ; WX 500 ; N asciicircum ; B 89 326 569 750 ; C 95 ; WX 500 ; N underscore ; B -27 -125 484 -75 ; C 96 ; WX 278 ; N quoteleft ; B 181 495 360 766 ; C 97 ; WX 500 ; N a ; B 68 -15 525 579 ; C 98 ; WX 500 ; N b ; B 64 -15 534 750 ; C 99 ; WX 444 ; N c ; B 79 -15 496 579 ; C 100 ; WX 500 ; N d ; B 83 -15 592 750 ; C 101 ; WX 500 ; N e ; B 88 -15 530 579 ; C 102 ; WX 278 ; N f ; B 71 0 416 750 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 44 -190 553 579 ; C 104 ; WX 500 ; N h ; B 61 0 539 750 ; C 105 ; WX 278 ; N i ; B 74 0 363 750 ; C 106 ; WX 278 ; N j ; B -9 -192 368 750 ; C 107 ; WX 444 ; N k ; B 48 0 563 750 ; C 108 ; WX 278 ; N l ; B 74 0 363 750 ; C 109 ; WX 778 ; N m ; B 66 0 812 579 ; C 110 ; WX 500 ; N n ; B 61 0 539 579 ; C 111 ; WX 500 ; N o ; B 88 -15 531 579 ; C 112 ; WX 500 ; N p ; B 18 -189 528 579 ; C 113 ; WX 500 ; N q ; B 80 -188 550 579 ; C 114 ; WX 333 ; N r ; B 60 0 441 574 ; C 115 ; WX 444 ; N s ; B 56 -15 498 579 ; C 116 ; WX 278 ; N t ; B 83 -7 372 719 ; C 117 ; WX 500 ; N u ; B 78 -15 551 564 ; C 118 ; WX 444 ; N v ; B 130 0 554 564 ; C 119 ; WX 667 ; N w ; B 127 0 765 564 ; C 120 ; WX 444 ; N x ; B 8 0 553 564 ; C 121 ; WX 444 ; N y ; B 36 -195 549 564 ; C 122 ; WX 389 ; N z ; B 23 0 487 564 ; C 123 ; WX 274 ; N braceleft ; B 37 -92 399 750 ; C 124 ; WX 250 ; N bar ; B 22 -250 334 750 ; C 125 ; WX 274 ; N braceright ; B 14 -94 375 750 ; C 126 ; WX 500 ; N asciitilde ; B 74 153 536 359 ; C 161 ; WX 333 ; N exclamdown ; B 66 -170 355 579 ; C 162 ; WX 500 ; N cent ; B 103 -122 521 671 ; C 163 ; WX 500 ; N sterling ; B 52 -15 603 768 ; C 164 ; WX 167 ; N fraction ; B -169 0 488 738 ; C 165 ; WX 500 ; N yen ; B 89 0 677 750 ; C 166 ; WX 500 ; N florin ; B -28 -185 651 763 ; C 167 ; WX 500 ; N section ; B 48 -183 572 768 ; C 168 ; WX 500 ; N currency ; B 38 58 594 560 ; C 169 ; WX 250 ; N quotesingle ; B 165 468 342 739 ; C 170 ; WX 500 ; N quotedblleft ; B 192 495 568 766 ; C 171 ; WX 500 ; N guillemotleft ; B 117 62 514 447 ; C 172 ; WX 278 ; N guilsinglleft ; B 101 62 310 447 ; C 173 ; WX 278 ; N guilsinglright ; B 76 62 285 447 ; C 174 ; WX 500 ; N fi ; B 60 0 605 750 ; C 175 ; WX 500 ; N fl ; B 60 0 602 750 ; C 177 ; WX 500 ; N endash ; B 55 259 578 369 ; C 178 ; WX 500 ; N dagger ; B 127 -155 577 768 ; C 179 ; WX 500 ; N daggerdbl ; B 51 -161 579 768 ; C 180 ; WX 333 ; N periodcentered ; B 140 183 300 315 ; C 182 ; WX 550 ; N paragraph ; B 139 -116 685 750 ; C 183 ; WX 420 ; N bullet ; B 97 186 482 562 ; C 184 ; WX 278 ; N quotesinglbase ; B 58 -138 235 132 ; C 185 ; WX 500 ; N quotedblbase ; B 67 -138 441 132 ; C 186 ; WX 500 ; N quotedblright ; B 197 479 572 750 ; C 187 ; WX 500 ; N guillemotright ; B 94 62 491 447 ; C 188 ; WX 1000 ; N ellipsis ; B 101 0 927 132 ; C 189 ; WX 1111 ; N perthousand ; B 128 -18 1141 748 ; C 191 ; WX 500 ; N questiondown ; B 54 -190 476 579 ; C 193 ; WX 333 ; N grave ; B 166 629 384 775 ; C 194 ; WX 333 ; N acute ; B 217 629 497 775 ; C 195 ; WX 333 ; N circumflex ; B 127 644 480 790 ; C 196 ; WX 333 ; N tilde ; B 119 636 512 764 ; C 197 ; WX 333 ; N macron ; B 136 666 497 740 ; C 198 ; WX 333 ; N breve ; B 161 635 501 780 ; C 199 ; WX 333 ; N dotaccent ; B 240 644 391 759 ; C 200 ; WX 333 ; N dieresis ; B 142 644 489 759 ; C 202 ; WX 333 ; N ring ; B 215 632 432 845 ; C 203 ; WX 333 ; N cedilla ; B -4 -228 248 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 118 634 613 780 ; C 206 ; WX 333 ; N ogonek ; B 63 -205 256 0 ; C 207 ; WX 333 ; N caron ; B 156 634 509 780 ; C 208 ; WX 1000 ; N emdash ; B 55 259 1078 369 ; C 225 ; WX 778 ; N AE ; B -22 0 909 750 ; C 227 ; WX 300 ; N ordfeminine ; B 127 412 421 768 ; C 232 ; WX 500 ; N Lslash ; B 49 0 497 750 ; C 233 ; WX 611 ; N Oslash ; B 34 -38 736 779 ; C 234 ; WX 833 ; N OE ; B 111 -18 951 768 ; C 235 ; WX 300 ; N ordmasculine ; B 133 412 417 768 ; C 241 ; WX 722 ; N ae ; B 69 -15 762 579 ; C 245 ; WX 278 ; N dotlessi ; B 74 0 324 564 ; C 248 ; WX 278 ; N lslash ; B 68 0 391 750 ; C 249 ; WX 500 ; N oslash ; B 2 -58 616 617 ; C 250 ; WX 722 ; N oe ; B 81 -15 763 579 ; C 251 ; WX 500 ; N germandbls ; B 60 -15 561 768 ; C -1 ; WX 500 ; N ecircumflex ; B 88 -15 560 770 ; C -1 ; WX 500 ; N edieresis ; B 88 -15 573 759 ; C -1 ; WX 500 ; N aacute ; B 68 -15 581 775 ; C -1 ; WX 830 ; N registered ; B 93 -18 897 768 ; C -1 ; WX 278 ; N icircumflex ; B 74 0 439 770 ; C -1 ; WX 500 ; N udieresis ; B 78 -15 573 759 ; C -1 ; WX 500 ; N ograve ; B 88 -15 531 775 ; C -1 ; WX 500 ; N uacute ; B 78 -15 581 775 ; C -1 ; WX 500 ; N ucircumflex ; B 78 -15 562 780 ; C -1 ; WX 556 ; N Aacute ; B 9 0 648 961 ; C -1 ; WX 278 ; N igrave ; B 74 0 357 775 ; C -1 ; WX 278 ; N Icircumflex ; B 69 0 488 956 ; C -1 ; WX 444 ; N ccedilla ; B 66 -228 496 579 ; C -1 ; WX 500 ; N adieresis ; B 68 -15 573 759 ; C -1 ; WX 500 ; N Ecircumflex ; B 64 0 617 956 ; C -1 ; WX 444 ; N scaron ; B 56 -15 551 760 ; C -1 ; WX 500 ; N thorn ; B 18 -189 529 750 ; C -1 ; WX 860 ; N trademark ; B 144 346 933 750 ; C -1 ; WX 500 ; N egrave ; B 88 -15 530 775 ; C -1 ; WX 300 ; N threesuperior ; B 96 290 416 751 ; C -1 ; WX 389 ; N zcaron ; B 23 0 533 760 ; C -1 ; WX 500 ; N atilde ; B 68 -15 592 744 ; C -1 ; WX 500 ; N aring ; B 68 -15 525 835 ; C -1 ; WX 500 ; N ocircumflex ; B 88 -15 560 770 ; C -1 ; WX 500 ; N Edieresis ; B 64 0 617 945 ; C -1 ; WX 750 ; N threequarters ; B 96 0 816 751 ; C -1 ; WX 444 ; N ydieresis ; B 36 -195 549 759 ; C -1 ; WX 444 ; N yacute ; B 36 -195 553 775 ; C -1 ; WX 278 ; N iacute ; B 74 0 470 775 ; C -1 ; WX 556 ; N Acircumflex ; B 9 0 617 956 ; C -1 ; WX 611 ; N Uacute ; B 105 -18 703 961 ; C -1 ; WX 500 ; N eacute ; B 88 -15 581 775 ; C -1 ; WX 611 ; N Ograve ; B 105 -18 664 961 ; C -1 ; WX 500 ; N agrave ; B 68 -15 525 775 ; C -1 ; WX 611 ; N Udieresis ; B 105 -18 703 945 ; C -1 ; WX 500 ; N acircumflex ; B 68 -15 560 770 ; C -1 ; WX 278 ; N Igrave ; B 69 0 396 961 ; C -1 ; WX 300 ; N twosuperior ; B 77 300 425 752 ; C -1 ; WX 611 ; N Ugrave ; B 105 -18 703 961 ; C -1 ; WX 750 ; N onequarter ; B 131 0 788 750 ; C -1 ; WX 611 ; N Ucircumflex ; B 105 -18 703 956 ; C -1 ; WX 556 ; N Scaron ; B 85 -18 656 946 ; C -1 ; WX 278 ; N Idieresis ; B 69 0 502 945 ; C -1 ; WX 278 ; N idieresis ; B 74 0 462 759 ; C -1 ; WX 500 ; N Egrave ; B 64 0 617 961 ; C -1 ; WX 611 ; N Oacute ; B 105 -18 675 961 ; C -1 ; WX 500 ; N divide ; B 67 6 540 492 ; C -1 ; WX 556 ; N Atilde ; B 9 0 660 930 ; C -1 ; WX 556 ; N Aring ; B 9 0 575 991 ; C -1 ; WX 611 ; N Odieresis ; B 105 -18 668 945 ; C -1 ; WX 556 ; N Adieresis ; B 9 0 641 945 ; C -1 ; WX 611 ; N Ntilde ; B 68 0 702 930 ; C -1 ; WX 500 ; N Zcaron ; B 33 0 628 946 ; C -1 ; WX 556 ; N Thorn ; B 68 0 625 750 ; C -1 ; WX 278 ; N Iacute ; B 69 0 509 961 ; C -1 ; WX 500 ; N plusminus ; B 23 -15 556 513 ; C -1 ; WX 500 ; N multiply ; B 48 22 560 476 ; C -1 ; WX 500 ; N Eacute ; B 64 0 620 961 ; C -1 ; WX 556 ; N Ydieresis ; B 171 0 704 945 ; C -1 ; WX 300 ; N onesuperior ; B 180 300 410 750 ; C -1 ; WX 500 ; N ugrave ; B 78 -15 551 775 ; C -1 ; WX 500 ; N logicalnot ; B 88 105 560 401 ; C -1 ; WX 500 ; N ntilde ; B 61 0 592 744 ; C -1 ; WX 611 ; N Otilde ; B 105 -18 687 930 ; C -1 ; WX 500 ; N otilde ; B 88 -15 592 744 ; C -1 ; WX 556 ; N Ccedilla ; B 99 -228 630 768 ; C -1 ; WX 556 ; N Agrave ; B 9 0 547 961 ; C -1 ; WX 750 ; N onehalf ; B 108 0 813 750 ; C -1 ; WX 611 ; N Eth ; B 72 0 662 750 ; C -1 ; WX 400 ; N degree ; B 174 450 481 750 ; C -1 ; WX 556 ; N Yacute ; B 171 0 704 961 ; C -1 ; WX 611 ; N Ocircumflex ; B 105 -18 664 956 ; C -1 ; WX 500 ; N oacute ; B 88 -15 581 775 ; C -1 ; WX 500 ; N mu ; B 18 -189 551 564 ; C -1 ; WX 500 ; N minus ; B 67 194 540 304 ; C -1 ; WX 500 ; N eth ; B 88 -15 540 779 ; C -1 ; WX 500 ; N odieresis ; B 88 -15 573 759 ; C -1 ; WX 830 ; N copyright ; B 93 -18 897 768 ; C -1 ; WX 250 ; N brokenbar ; B 38 -175 318 675 ; EndCharMetrics StartKernData StartKernPairs 88 KPX A y -18 KPX A w -18 KPX A v -18 KPX A quoteright -55 KPX A Y -55 KPX A W -37 KPX A V -37 KPX A T -55 KPX F period -111 KPX F comma -111 KPX F A -37 KPX L y -37 KPX L quoteright -92 KPX L Y -92 KPX L W -74 KPX L V -74 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -37 KPX R Y -18 KPX R T -18 KPX T y -55 KPX T w -74 KPX T u -74 KPX T semicolon -74 KPX T s -74 KPX T r -74 KPX T period -92 KPX T o -74 KPX T i -18 KPX T hyphen -55 KPX T e -74 KPX T comma -92 KPX T colon -74 KPX T c -74 KPX T a -74 KPX T A -55 KPX V u -18 KPX V semicolon -18 KPX V r -18 KPX V period -92 KPX V o -18 KPX V hyphen -18 KPX V e -18 KPX V comma -92 KPX V colon -18 KPX V a -18 KPX V A -37 KPX W period -74 KPX W o -18 KPX W hyphen -18 KPX W e -18 KPX W comma -74 KPX W a -18 KPX W A -18 KPX Y v -18 KPX Y u -37 KPX Y semicolon -37 KPX Y q -55 KPX Y period -111 KPX Y p -37 KPX Y o -55 KPX Y i -18 KPX Y hyphen -74 KPX Y e -55 KPX Y comma -111 KPX Y colon -37 KPX Y a -55 KPX Y A -55 KPX f quoteright 18 KPX quoteleft quoteleft -18 KPX quoteright s -55 KPX quoteright quoteright -18 KPX r z 20 KPX r y 18 KPX r x 20 KPX r w 18 KPX r v 18 KPX r period -74 KPX r hyphen -37 KPX r comma -74 KPX v period -55 KPX v comma -55 KPX w period -37 KPX w comma -37 KPX y period -55 KPX y comma -55 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 152 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 166 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 152 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 143 146 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 147 166 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 124 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 119 166 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 124 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 124 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 8 166 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 174 166 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 179 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 174 166 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 179 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 179 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 174 166 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 147 166 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 179 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 174 166 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 179 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 179 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 152 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 152 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 119 166 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 -20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 67 -10 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 80 -20 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 80 -20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -41 -20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 -20 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 80 -20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 -20 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 42 -20 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 82 -10 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 56 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 24 -20 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Bold.afm����������������������������������������������������0000644�0001750�0001750�00000042476�11462120062�017731� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu Mar 15 09:43:00 1990 Comment UniqueID 28357 Comment VMusage 26878 33770 FontName Helvetica-Bold FullName Helvetica Bold FamilyName Helvetica Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -170 -228 1003 962 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ; C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ; C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ; C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ; C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ; C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ; C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ; C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ; C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ; C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ; C 43 ; WX 584 ; N plus ; B 40 0 544 506 ; C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ; C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ; C 46 ; WX 278 ; N period ; B 64 0 214 146 ; C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ; C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ; C 49 ; WX 556 ; N one ; B 69 0 378 710 ; C 50 ; WX 556 ; N two ; B 26 0 511 710 ; C 51 ; WX 556 ; N three ; B 27 -19 516 710 ; C 52 ; WX 556 ; N four ; B 27 0 526 710 ; C 53 ; WX 556 ; N five ; B 27 -19 516 698 ; C 54 ; WX 556 ; N six ; B 31 -19 520 710 ; C 55 ; WX 556 ; N seven ; B 25 0 528 698 ; C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ; C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ; C 58 ; WX 333 ; N colon ; B 92 0 242 512 ; C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ; C 60 ; WX 584 ; N less ; B 38 -8 546 514 ; C 61 ; WX 584 ; N equal ; B 40 87 544 419 ; C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ; C 63 ; WX 611 ; N question ; B 60 0 556 727 ; C 64 ; WX 975 ; N at ; B 118 -19 856 737 ; C 65 ; WX 722 ; N A ; B 20 0 702 718 ; C 66 ; WX 722 ; N B ; B 76 0 669 718 ; C 67 ; WX 722 ; N C ; B 44 -19 684 737 ; C 68 ; WX 722 ; N D ; B 76 0 685 718 ; C 69 ; WX 667 ; N E ; B 76 0 621 718 ; C 70 ; WX 611 ; N F ; B 76 0 587 718 ; C 71 ; WX 778 ; N G ; B 44 -19 713 737 ; C 72 ; WX 722 ; N H ; B 71 0 651 718 ; C 73 ; WX 278 ; N I ; B 64 0 214 718 ; C 74 ; WX 556 ; N J ; B 22 -18 484 718 ; C 75 ; WX 722 ; N K ; B 87 0 722 718 ; C 76 ; WX 611 ; N L ; B 76 0 583 718 ; C 77 ; WX 833 ; N M ; B 69 0 765 718 ; C 78 ; WX 722 ; N N ; B 69 0 654 718 ; C 79 ; WX 778 ; N O ; B 44 -19 734 737 ; C 80 ; WX 667 ; N P ; B 76 0 627 718 ; C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ; C 82 ; WX 722 ; N R ; B 76 0 677 718 ; C 83 ; WX 667 ; N S ; B 39 -19 629 737 ; C 84 ; WX 611 ; N T ; B 14 0 598 718 ; C 85 ; WX 722 ; N U ; B 72 -19 651 718 ; C 86 ; WX 667 ; N V ; B 19 0 648 718 ; C 87 ; WX 944 ; N W ; B 16 0 929 718 ; C 88 ; WX 667 ; N X ; B 14 0 653 718 ; C 89 ; WX 667 ; N Y ; B 15 0 653 718 ; C 90 ; WX 611 ; N Z ; B 25 0 586 718 ; C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ; C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ; C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ; C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ; C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ; C 97 ; WX 556 ; N a ; B 29 -14 527 546 ; C 98 ; WX 611 ; N b ; B 61 -14 578 718 ; C 99 ; WX 556 ; N c ; B 34 -14 524 546 ; C 100 ; WX 611 ; N d ; B 34 -14 551 718 ; C 101 ; WX 556 ; N e ; B 23 -14 528 546 ; C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B 40 -217 553 546 ; C 104 ; WX 611 ; N h ; B 65 0 546 718 ; C 105 ; WX 278 ; N i ; B 69 0 209 725 ; C 106 ; WX 278 ; N j ; B 3 -214 209 725 ; C 107 ; WX 556 ; N k ; B 69 0 562 718 ; C 108 ; WX 278 ; N l ; B 69 0 209 718 ; C 109 ; WX 889 ; N m ; B 64 0 826 546 ; C 110 ; WX 611 ; N n ; B 65 0 546 546 ; C 111 ; WX 611 ; N o ; B 34 -14 578 546 ; C 112 ; WX 611 ; N p ; B 62 -207 578 546 ; C 113 ; WX 611 ; N q ; B 34 -207 552 546 ; C 114 ; WX 389 ; N r ; B 64 0 373 546 ; C 115 ; WX 556 ; N s ; B 30 -14 519 546 ; C 116 ; WX 333 ; N t ; B 10 -6 309 676 ; C 117 ; WX 611 ; N u ; B 66 -14 545 532 ; C 118 ; WX 556 ; N v ; B 13 0 543 532 ; C 119 ; WX 778 ; N w ; B 10 0 769 532 ; C 120 ; WX 556 ; N x ; B 15 0 541 532 ; C 121 ; WX 556 ; N y ; B 10 -214 539 532 ; C 122 ; WX 500 ; N z ; B 20 0 480 532 ; C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ; C 124 ; WX 280 ; N bar ; B 84 -19 196 737 ; C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ; C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ; C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ; C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ; C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ; C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ; C 165 ; WX 556 ; N yen ; B -9 0 565 698 ; C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ; C 167 ; WX 556 ; N section ; B 34 -184 522 727 ; C 168 ; WX 556 ; N currency ; B -3 76 559 636 ; C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ; C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ; C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ; C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ; C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ; C 174 ; WX 611 ; N fi ; B 10 0 542 727 ; C 175 ; WX 611 ; N fl ; B 10 0 542 727 ; C 177 ; WX 556 ; N endash ; B 0 227 556 333 ; C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ; C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ; C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ; C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ; C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ; C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ; C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ; C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ; C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ; C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ; C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ; C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ; C 193 ; WX 333 ; N grave ; B -23 604 225 750 ; C 194 ; WX 333 ; N acute ; B 108 604 356 750 ; C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ; C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ; C 197 ; WX 333 ; N macron ; B -6 604 339 678 ; C 198 ; WX 333 ; N breve ; B -2 604 335 750 ; C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ; C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ; C 202 ; WX 333 ; N ring ; B 59 568 275 776 ; C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ; C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ; C 207 ; WX 333 ; N caron ; B -10 604 343 750 ; C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ; C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ; C 227 ; WX 370 ; N ordfeminine ; B 22 276 347 737 ; C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ; C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ; C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ; C 235 ; WX 365 ; N ordmasculine ; B 6 276 360 737 ; C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ; C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ; C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ; C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ; C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ; C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ; C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ; C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ; C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ; C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ; C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ; C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ; C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ; C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ; C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ; C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ; C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ; C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ; C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ; C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ; C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ; C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ; C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ; C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ; C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ; C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ; C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ; C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ; C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ; C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ; C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ; C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ; C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ; C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ; C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ; C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ; C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ; C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ; C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ; C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ; C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ; C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ; C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ; C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ; C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ; C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ; C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ; C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ; C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ; C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ; C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ; C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ; C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ; C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ; C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ; C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ; C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ; C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ; C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ; C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ; C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ; C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ; C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ; C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ; C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ; C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ; C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ; C -1 ; WX 584 ; N minus ; B 40 197 544 309 ; C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ; C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ; C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ; C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ; C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ; C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ; C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ; C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ; C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ; C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ; C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ; C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ; C -1 ; WX 280 ; N brokenbar ; B 84 -19 196 737 ; C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ; EndCharMetrics StartKernData StartKernPairs 209 KPX A y -30 KPX A w -30 KPX A v -40 KPX A u -30 KPX A Y -110 KPX A W -60 KPX A V -80 KPX A U -50 KPX A T -90 KPX A Q -40 KPX A O -40 KPX A G -50 KPX A C -40 KPX B U -10 KPX B A -30 KPX D period -30 KPX D comma -30 KPX D Y -70 KPX D W -40 KPX D V -40 KPX D A -40 KPX F period -100 KPX F comma -100 KPX F a -20 KPX F A -80 KPX J u -20 KPX J period -20 KPX J comma -20 KPX J A -20 KPX K y -40 KPX K u -30 KPX K o -35 KPX K e -15 KPX K O -30 KPX L y -30 KPX L quoteright -140 KPX L quotedblright -140 KPX L Y -120 KPX L W -80 KPX L V -110 KPX L T -90 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -50 KPX O W -50 KPX O V -50 KPX O T -40 KPX O A -50 KPX P period -120 KPX P o -40 KPX P e -30 KPX P comma -120 KPX P a -30 KPX P A -100 KPX Q period 20 KPX Q comma 20 KPX Q U -10 KPX R Y -50 KPX R W -40 KPX R V -50 KPX R U -20 KPX R T -20 KPX R O -20 KPX T y -60 KPX T w -60 KPX T u -90 KPX T semicolon -40 KPX T r -80 KPX T period -80 KPX T o -80 KPX T hyphen -120 KPX T e -60 KPX T comma -80 KPX T colon -40 KPX T a -80 KPX T O -40 KPX T A -90 KPX U period -30 KPX U comma -30 KPX U A -50 KPX V u -60 KPX V semicolon -40 KPX V period -120 KPX V o -90 KPX V hyphen -80 KPX V e -50 KPX V comma -120 KPX V colon -40 KPX V a -60 KPX V O -50 KPX V G -50 KPX V A -80 KPX W y -20 KPX W u -45 KPX W semicolon -10 KPX W period -80 KPX W o -60 KPX W hyphen -40 KPX W e -35 KPX W comma -80 KPX W colon -10 KPX W a -40 KPX W O -20 KPX W A -60 KPX Y u -100 KPX Y semicolon -50 KPX Y period -100 KPX Y o -100 KPX Y e -80 KPX Y comma -100 KPX Y colon -50 KPX Y a -90 KPX Y O -70 KPX Y A -110 KPX a y -20 KPX a w -15 KPX a v -15 KPX a g -10 KPX b y -20 KPX b v -20 KPX b u -20 KPX b l -10 KPX c y -10 KPX c l -20 KPX c k -20 KPX c h -10 KPX colon space -40 KPX comma space -40 KPX comma quoteright -120 KPX comma quotedblright -120 KPX d y -15 KPX d w -15 KPX d v -15 KPX d d -10 KPX e y -15 KPX e x -15 KPX e w -15 KPX e v -15 KPX e period 20 KPX e comma 10 KPX f quoteright 30 KPX f quotedblright 30 KPX f period -10 KPX f o -20 KPX f e -10 KPX f comma -10 KPX g g -10 KPX g e 10 KPX h y -20 KPX k o -15 KPX l y -15 KPX l w -15 KPX m y -30 KPX m u -20 KPX n y -20 KPX n v -40 KPX n u -10 KPX o y -20 KPX o x -30 KPX o w -15 KPX o v -20 KPX p y -15 KPX period space -40 KPX period quoteright -120 KPX period quotedblright -120 KPX quotedblright space -80 KPX quoteleft quoteleft -46 KPX quoteright v -20 KPX quoteright space -80 KPX quoteright s -60 KPX quoteright r -40 KPX quoteright quoteright -46 KPX quoteright l -20 KPX quoteright d -80 KPX r y 10 KPX r v 10 KPX r t 20 KPX r s -15 KPX r q -20 KPX r period -60 KPX r o -20 KPX r hyphen -20 KPX r g -15 KPX r d -20 KPX r comma -60 KPX r c -20 KPX s w -15 KPX semicolon space -40 KPX space quoteleft -60 KPX space quotedblleft -80 KPX space Y -120 KPX space W -80 KPX space V -80 KPX space T -100 KPX v period -80 KPX v o -30 KPX v comma -80 KPX v a -20 KPX w period -40 KPX w o -20 KPX w comma -40 KPX x e -10 KPX y period -80 KPX y o -25 KPX y e -10 KPX y comma -80 KPX y a -30 KPX z e 10 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 186 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 186 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 186 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 186 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 195 186 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 186 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 186 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 186 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 186 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 186 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 186 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 186 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 186 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 186 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 186 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 186 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 186 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 186 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 186 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 186 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 186 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 186 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 186 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 186 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 186 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Narrow.afm��������������������������������������������������0000644�0001750�0001750�00000043732�11462120062�020315� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Thu Mar 15 11:04:57 1990 Comment UniqueID 28380 Comment VMusage 7572 42473 FontName Helvetica-Narrow FullName Helvetica Narrow FamilyName Helvetica Weight Medium ItalicAngle 0 IsFixedPitch false FontBBox -136 -225 820 931 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 228 ; N space ; B 0 0 0 0 ; C 33 ; WX 228 ; N exclam ; B 74 0 153 718 ; C 34 ; WX 291 ; N quotedbl ; B 57 463 234 718 ; C 35 ; WX 456 ; N numbersign ; B 23 0 434 688 ; C 36 ; WX 456 ; N dollar ; B 26 -115 426 775 ; C 37 ; WX 729 ; N percent ; B 32 -19 697 703 ; C 38 ; WX 547 ; N ampersand ; B 36 -15 529 718 ; C 39 ; WX 182 ; N quoteright ; B 43 463 129 718 ; C 40 ; WX 273 ; N parenleft ; B 56 -207 245 733 ; C 41 ; WX 273 ; N parenright ; B 28 -207 217 733 ; C 42 ; WX 319 ; N asterisk ; B 32 431 286 718 ; C 43 ; WX 479 ; N plus ; B 32 0 447 505 ; C 44 ; WX 228 ; N comma ; B 71 -147 157 106 ; C 45 ; WX 273 ; N hyphen ; B 36 232 237 322 ; C 46 ; WX 228 ; N period ; B 71 0 157 106 ; C 47 ; WX 228 ; N slash ; B -14 -19 242 737 ; C 48 ; WX 456 ; N zero ; B 30 -19 426 703 ; C 49 ; WX 456 ; N one ; B 83 0 294 703 ; C 50 ; WX 456 ; N two ; B 21 0 416 703 ; C 51 ; WX 456 ; N three ; B 28 -19 428 703 ; C 52 ; WX 456 ; N four ; B 20 0 429 703 ; C 53 ; WX 456 ; N five ; B 26 -19 421 688 ; C 54 ; WX 456 ; N six ; B 31 -19 425 703 ; C 55 ; WX 456 ; N seven ; B 30 0 429 688 ; C 56 ; WX 456 ; N eight ; B 31 -19 424 703 ; C 57 ; WX 456 ; N nine ; B 34 -19 421 703 ; C 58 ; WX 228 ; N colon ; B 71 0 157 516 ; C 59 ; WX 228 ; N semicolon ; B 71 -147 157 516 ; C 60 ; WX 479 ; N less ; B 39 11 440 495 ; C 61 ; WX 479 ; N equal ; B 32 115 447 390 ; C 62 ; WX 479 ; N greater ; B 39 11 440 495 ; C 63 ; WX 456 ; N question ; B 46 0 403 727 ; C 64 ; WX 832 ; N at ; B 121 -19 712 737 ; C 65 ; WX 547 ; N A ; B 11 0 536 718 ; C 66 ; WX 547 ; N B ; B 61 0 514 718 ; C 67 ; WX 592 ; N C ; B 36 -19 558 737 ; C 68 ; WX 592 ; N D ; B 66 0 553 718 ; C 69 ; WX 547 ; N E ; B 71 0 505 718 ; C 70 ; WX 501 ; N F ; B 71 0 478 718 ; C 71 ; WX 638 ; N G ; B 39 -19 577 737 ; C 72 ; WX 592 ; N H ; B 63 0 530 718 ; C 73 ; WX 228 ; N I ; B 75 0 154 718 ; C 74 ; WX 410 ; N J ; B 14 -19 351 718 ; C 75 ; WX 547 ; N K ; B 62 0 544 718 ; C 76 ; WX 456 ; N L ; B 62 0 440 718 ; C 77 ; WX 683 ; N M ; B 60 0 624 718 ; C 78 ; WX 592 ; N N ; B 62 0 530 718 ; C 79 ; WX 638 ; N O ; B 32 -19 606 737 ; C 80 ; WX 547 ; N P ; B 71 0 510 718 ; C 81 ; WX 638 ; N Q ; B 32 -56 606 737 ; C 82 ; WX 592 ; N R ; B 72 0 561 718 ; C 83 ; WX 547 ; N S ; B 40 -19 508 737 ; C 84 ; WX 501 ; N T ; B 11 0 490 718 ; C 85 ; WX 592 ; N U ; B 65 -19 528 718 ; C 86 ; WX 547 ; N V ; B 16 0 531 718 ; C 87 ; WX 774 ; N W ; B 13 0 761 718 ; C 88 ; WX 547 ; N X ; B 16 0 531 718 ; C 89 ; WX 547 ; N Y ; B 11 0 535 718 ; C 90 ; WX 501 ; N Z ; B 19 0 482 718 ; C 91 ; WX 228 ; N bracketleft ; B 52 -196 205 722 ; C 92 ; WX 228 ; N backslash ; B -14 -19 242 737 ; C 93 ; WX 228 ; N bracketright ; B 23 -196 176 722 ; C 94 ; WX 385 ; N asciicircum ; B -11 264 396 688 ; C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ; C 96 ; WX 182 ; N quoteleft ; B 53 470 139 725 ; C 97 ; WX 456 ; N a ; B 30 -15 435 538 ; C 98 ; WX 456 ; N b ; B 48 -15 424 718 ; C 99 ; WX 410 ; N c ; B 25 -15 391 538 ; C 100 ; WX 456 ; N d ; B 29 -15 409 718 ; C 101 ; WX 456 ; N e ; B 33 -15 423 538 ; C 102 ; WX 228 ; N f ; B 11 0 215 728 ; L i fi ; L l fl ; C 103 ; WX 456 ; N g ; B 33 -220 409 538 ; C 104 ; WX 456 ; N h ; B 53 0 403 718 ; C 105 ; WX 182 ; N i ; B 55 0 127 718 ; C 106 ; WX 182 ; N j ; B -13 -210 127 718 ; C 107 ; WX 410 ; N k ; B 55 0 411 718 ; C 108 ; WX 182 ; N l ; B 55 0 127 718 ; C 109 ; WX 683 ; N m ; B 53 0 631 538 ; C 110 ; WX 456 ; N n ; B 53 0 403 538 ; C 111 ; WX 456 ; N o ; B 29 -14 427 538 ; C 112 ; WX 456 ; N p ; B 48 -207 424 538 ; C 113 ; WX 456 ; N q ; B 29 -207 405 538 ; C 114 ; WX 273 ; N r ; B 63 0 272 538 ; C 115 ; WX 410 ; N s ; B 26 -15 380 538 ; C 116 ; WX 228 ; N t ; B 11 -7 211 669 ; C 117 ; WX 456 ; N u ; B 56 -15 401 523 ; C 118 ; WX 410 ; N v ; B 7 0 403 523 ; C 119 ; WX 592 ; N w ; B 11 0 581 523 ; C 120 ; WX 410 ; N x ; B 9 0 402 523 ; C 121 ; WX 410 ; N y ; B 9 -214 401 523 ; C 122 ; WX 410 ; N z ; B 25 0 385 523 ; C 123 ; WX 274 ; N braceleft ; B 34 -196 239 722 ; C 124 ; WX 213 ; N bar ; B 77 -19 137 737 ; C 125 ; WX 274 ; N braceright ; B 34 -196 239 722 ; C 126 ; WX 479 ; N asciitilde ; B 50 180 429 326 ; C 161 ; WX 273 ; N exclamdown ; B 97 -195 176 523 ; C 162 ; WX 456 ; N cent ; B 42 -115 421 623 ; C 163 ; WX 456 ; N sterling ; B 27 -16 442 718 ; C 164 ; WX 137 ; N fraction ; B -136 -19 273 703 ; C 165 ; WX 456 ; N yen ; B 2 0 453 688 ; C 166 ; WX 456 ; N florin ; B -9 -207 411 737 ; C 167 ; WX 456 ; N section ; B 35 -191 420 737 ; C 168 ; WX 456 ; N currency ; B 23 99 433 603 ; C 169 ; WX 157 ; N quotesingle ; B 48 463 108 718 ; C 170 ; WX 273 ; N quotedblleft ; B 31 470 252 725 ; C 171 ; WX 456 ; N guillemotleft ; B 80 108 376 446 ; C 172 ; WX 273 ; N guilsinglleft ; B 72 108 201 446 ; C 173 ; WX 273 ; N guilsinglright ; B 72 108 201 446 ; C 174 ; WX 410 ; N fi ; B 11 0 356 728 ; C 175 ; WX 410 ; N fl ; B 11 0 354 728 ; C 177 ; WX 456 ; N endash ; B 0 240 456 313 ; C 178 ; WX 456 ; N dagger ; B 35 -159 421 718 ; C 179 ; WX 456 ; N daggerdbl ; B 35 -159 421 718 ; C 180 ; WX 228 ; N periodcentered ; B 63 190 166 315 ; C 182 ; WX 440 ; N paragraph ; B 15 -173 408 718 ; C 183 ; WX 287 ; N bullet ; B 15 202 273 517 ; C 184 ; WX 182 ; N quotesinglbase ; B 43 -149 129 106 ; C 185 ; WX 273 ; N quotedblbase ; B 21 -149 242 106 ; C 186 ; WX 273 ; N quotedblright ; B 21 463 242 718 ; C 187 ; WX 456 ; N guillemotright ; B 80 108 376 446 ; C 188 ; WX 820 ; N ellipsis ; B 94 0 726 106 ; C 189 ; WX 820 ; N perthousand ; B 6 -19 815 703 ; C 191 ; WX 501 ; N questiondown ; B 75 -201 432 525 ; C 193 ; WX 273 ; N grave ; B 11 593 173 734 ; C 194 ; WX 273 ; N acute ; B 100 593 262 734 ; C 195 ; WX 273 ; N circumflex ; B 17 593 256 734 ; C 196 ; WX 273 ; N tilde ; B -3 606 276 722 ; C 197 ; WX 273 ; N macron ; B 8 627 265 684 ; C 198 ; WX 273 ; N breve ; B 11 595 263 731 ; C 199 ; WX 273 ; N dotaccent ; B 99 604 174 706 ; C 200 ; WX 273 ; N dieresis ; B 33 604 240 706 ; C 202 ; WX 273 ; N ring ; B 61 572 212 756 ; C 203 ; WX 273 ; N cedilla ; B 37 -225 212 0 ; C 205 ; WX 273 ; N hungarumlaut ; B 25 593 335 734 ; C 206 ; WX 273 ; N ogonek ; B 60 -225 235 0 ; C 207 ; WX 273 ; N caron ; B 17 593 256 734 ; C 208 ; WX 820 ; N emdash ; B 0 240 820 313 ; C 225 ; WX 820 ; N AE ; B 7 0 780 718 ; C 227 ; WX 303 ; N ordfeminine ; B 20 304 284 737 ; C 232 ; WX 456 ; N Lslash ; B -16 0 440 718 ; C 233 ; WX 638 ; N Oslash ; B 32 -19 607 737 ; C 234 ; WX 820 ; N OE ; B 30 -19 791 737 ; C 235 ; WX 299 ; N ordmasculine ; B 20 304 280 737 ; C 241 ; WX 729 ; N ae ; B 30 -15 695 538 ; C 245 ; WX 228 ; N dotlessi ; B 78 0 150 523 ; C 248 ; WX 182 ; N lslash ; B -16 0 198 718 ; C 249 ; WX 501 ; N oslash ; B 23 -22 440 545 ; C 250 ; WX 774 ; N oe ; B 29 -15 740 538 ; C 251 ; WX 501 ; N germandbls ; B 55 -15 468 728 ; C -1 ; WX 501 ; N Zcaron ; B 19 0 482 929 ; C -1 ; WX 410 ; N ccedilla ; B 25 -225 391 538 ; C -1 ; WX 410 ; N ydieresis ; B 9 -214 401 706 ; C -1 ; WX 456 ; N atilde ; B 30 -15 435 722 ; C -1 ; WX 228 ; N icircumflex ; B -5 0 234 734 ; C -1 ; WX 273 ; N threesuperior ; B 4 270 266 703 ; C -1 ; WX 456 ; N ecircumflex ; B 33 -15 423 734 ; C -1 ; WX 456 ; N thorn ; B 48 -207 424 718 ; C -1 ; WX 456 ; N egrave ; B 33 -15 423 734 ; C -1 ; WX 273 ; N twosuperior ; B 3 281 265 703 ; C -1 ; WX 456 ; N eacute ; B 33 -15 423 734 ; C -1 ; WX 456 ; N otilde ; B 29 -14 427 722 ; C -1 ; WX 547 ; N Aacute ; B 11 0 536 929 ; C -1 ; WX 456 ; N ocircumflex ; B 29 -14 427 734 ; C -1 ; WX 410 ; N yacute ; B 9 -214 401 734 ; C -1 ; WX 456 ; N udieresis ; B 56 -15 401 706 ; C -1 ; WX 684 ; N threequarters ; B 37 -19 664 703 ; C -1 ; WX 456 ; N acircumflex ; B 30 -15 435 734 ; C -1 ; WX 592 ; N Eth ; B 0 0 553 718 ; C -1 ; WX 456 ; N edieresis ; B 33 -15 423 706 ; C -1 ; WX 456 ; N ugrave ; B 56 -15 401 734 ; C -1 ; WX 820 ; N trademark ; B 38 306 740 718 ; C -1 ; WX 456 ; N ograve ; B 29 -14 427 734 ; C -1 ; WX 410 ; N scaron ; B 26 -15 380 734 ; C -1 ; WX 228 ; N Idieresis ; B 11 0 218 901 ; C -1 ; WX 456 ; N uacute ; B 56 -15 401 734 ; C -1 ; WX 456 ; N agrave ; B 30 -15 435 734 ; C -1 ; WX 456 ; N ntilde ; B 53 0 403 722 ; C -1 ; WX 456 ; N aring ; B 30 -15 435 756 ; C -1 ; WX 410 ; N zcaron ; B 25 0 385 734 ; C -1 ; WX 228 ; N Icircumflex ; B -5 0 234 929 ; C -1 ; WX 592 ; N Ntilde ; B 62 0 530 917 ; C -1 ; WX 456 ; N ucircumflex ; B 56 -15 401 734 ; C -1 ; WX 547 ; N Ecircumflex ; B 71 0 505 929 ; C -1 ; WX 228 ; N Iacute ; B 75 0 239 929 ; C -1 ; WX 592 ; N Ccedilla ; B 36 -225 558 737 ; C -1 ; WX 638 ; N Odieresis ; B 32 -19 606 901 ; C -1 ; WX 547 ; N Scaron ; B 40 -19 508 929 ; C -1 ; WX 547 ; N Edieresis ; B 71 0 505 901 ; C -1 ; WX 228 ; N Igrave ; B -11 0 154 929 ; C -1 ; WX 456 ; N adieresis ; B 30 -15 435 706 ; C -1 ; WX 638 ; N Ograve ; B 32 -19 606 929 ; C -1 ; WX 547 ; N Egrave ; B 71 0 505 929 ; C -1 ; WX 547 ; N Ydieresis ; B 11 0 535 901 ; C -1 ; WX 604 ; N registered ; B -11 -19 617 737 ; C -1 ; WX 638 ; N Otilde ; B 32 -19 606 917 ; C -1 ; WX 684 ; N onequarter ; B 60 -19 620 703 ; C -1 ; WX 592 ; N Ugrave ; B 65 -19 528 929 ; C -1 ; WX 592 ; N Ucircumflex ; B 65 -19 528 929 ; C -1 ; WX 547 ; N Thorn ; B 71 0 510 718 ; C -1 ; WX 479 ; N divide ; B 32 -19 447 524 ; C -1 ; WX 547 ; N Atilde ; B 11 0 536 917 ; C -1 ; WX 592 ; N Uacute ; B 65 -19 528 929 ; C -1 ; WX 638 ; N Ocircumflex ; B 32 -19 606 929 ; C -1 ; WX 479 ; N logicalnot ; B 32 108 447 390 ; C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ; C -1 ; WX 228 ; N idieresis ; B 11 0 218 706 ; C -1 ; WX 228 ; N iacute ; B 78 0 239 734 ; C -1 ; WX 456 ; N aacute ; B 30 -15 435 734 ; C -1 ; WX 479 ; N plusminus ; B 32 0 447 506 ; C -1 ; WX 479 ; N multiply ; B 32 0 447 506 ; C -1 ; WX 592 ; N Udieresis ; B 65 -19 528 901 ; C -1 ; WX 479 ; N minus ; B 32 216 447 289 ; C -1 ; WX 273 ; N onesuperior ; B 35 281 182 703 ; C -1 ; WX 547 ; N Eacute ; B 71 0 505 929 ; C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ; C -1 ; WX 604 ; N copyright ; B -11 -19 617 737 ; C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ; C -1 ; WX 456 ; N odieresis ; B 29 -14 427 706 ; C -1 ; WX 456 ; N oacute ; B 29 -14 427 734 ; C -1 ; WX 328 ; N degree ; B 44 411 284 703 ; C -1 ; WX 228 ; N igrave ; B -11 0 151 734 ; C -1 ; WX 456 ; N mu ; B 56 -207 401 523 ; C -1 ; WX 638 ; N Oacute ; B 32 -19 606 929 ; C -1 ; WX 456 ; N eth ; B 29 -15 428 737 ; C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ; C -1 ; WX 547 ; N Yacute ; B 11 0 535 929 ; C -1 ; WX 213 ; N brokenbar ; B 77 -19 137 737 ; C -1 ; WX 684 ; N onehalf ; B 35 -19 634 703 ; EndCharMetrics StartKernData StartKernPairs 250 KPX A y -32 KPX A w -32 KPX A v -32 KPX A u -24 KPX A Y -81 KPX A W -40 KPX A V -56 KPX A U -40 KPX A T -97 KPX A Q -24 KPX A O -24 KPX A G -24 KPX A C -24 KPX B period -15 KPX B comma -15 KPX B U -7 KPX C period -24 KPX C comma -24 KPX D period -56 KPX D comma -56 KPX D Y -73 KPX D W -32 KPX D V -56 KPX D A -32 KPX F r -36 KPX F period -122 KPX F o -24 KPX F e -24 KPX F comma -122 KPX F a -40 KPX F A -65 KPX J u -15 KPX J period -24 KPX J comma -24 KPX J a -15 KPX J A -15 KPX K y -40 KPX K u -24 KPX K o -32 KPX K e -32 KPX K O -40 KPX L y -24 KPX L quoteright -130 KPX L quotedblright -114 KPX L Y -114 KPX L W -56 KPX L V -89 KPX L T -89 KPX O period -32 KPX O comma -32 KPX O Y -56 KPX O X -48 KPX O W -24 KPX O V -40 KPX O T -32 KPX O A -15 KPX P period -147 KPX P o -40 KPX P e -40 KPX P comma -147 KPX P a -32 KPX P A -97 KPX Q U -7 KPX R Y -40 KPX R W -24 KPX R V -40 KPX R U -32 KPX R T -24 KPX R O -15 KPX S period -15 KPX S comma -15 KPX T y -97 KPX T w -97 KPX T u -97 KPX T semicolon -15 KPX T r -97 KPX T period -97 KPX T o -97 KPX T hyphen -114 KPX T e -97 KPX T comma -97 KPX T colon -15 KPX T a -97 KPX T O -32 KPX T A -97 KPX U period -32 KPX U comma -32 KPX U A -32 KPX V u -56 KPX V semicolon -32 KPX V period -102 KPX V o -65 KPX V hyphen -65 KPX V e -65 KPX V comma -102 KPX V colon -32 KPX V a -56 KPX V O -32 KPX V G -32 KPX V A -65 KPX W y -15 KPX W u -24 KPX W period -65 KPX W o -24 KPX W hyphen -32 KPX W e -24 KPX W comma -65 KPX W a -32 KPX W O -15 KPX W A -40 KPX Y u -89 KPX Y semicolon -48 KPX Y period -114 KPX Y o -114 KPX Y i -15 KPX Y hyphen -114 KPX Y e -114 KPX Y comma -114 KPX Y colon -48 KPX Y a -114 KPX Y O -69 KPX Y A -89 KPX a y -24 KPX a w -15 KPX a v -15 KPX b y -15 KPX b v -15 KPX b u -15 KPX b period -32 KPX b l -15 KPX b comma -32 KPX b b -7 KPX c k -15 KPX c comma -11 KPX colon space -40 KPX comma quoteright -81 KPX comma quotedblright -81 KPX e y -15 KPX e x -24 KPX e w -15 KPX e v -24 KPX e period -11 KPX e comma -11 KPX f quoteright 41 KPX f quotedblright 49 KPX f period -24 KPX f o -24 KPX f e -24 KPX f dotlessi -22 KPX f comma -24 KPX f a -24 KPX g r -7 KPX h y -24 KPX k o -15 KPX k e -15 KPX m y -11 KPX m u -7 KPX n y -11 KPX n v -15 KPX n u -7 KPX o y -24 KPX o x -24 KPX o w -11 KPX o v -11 KPX o period -32 KPX o comma -32 KPX oslash z -44 KPX oslash y -56 KPX oslash x -69 KPX oslash w -56 KPX oslash v -56 KPX oslash u -44 KPX oslash t -44 KPX oslash s -44 KPX oslash r -44 KPX oslash q -44 KPX oslash period -77 KPX oslash p -44 KPX oslash o -44 KPX oslash n -44 KPX oslash m -44 KPX oslash l -44 KPX oslash k -44 KPX oslash j -44 KPX oslash i -44 KPX oslash h -44 KPX oslash g -44 KPX oslash f -44 KPX oslash e -44 KPX oslash d -44 KPX oslash comma -77 KPX oslash c -44 KPX oslash b -44 KPX oslash a -44 KPX p y -24 KPX p period -28 KPX p comma -28 KPX period space -48 KPX period quoteright -81 KPX period quotedblright -81 KPX quotedblright space -32 KPX quoteleft quoteleft -46 KPX quoteright space -56 KPX quoteright s -40 KPX quoteright r -40 KPX quoteright quoteright -46 KPX quoteright d -40 KPX r y 25 KPX r v 25 KPX r u 12 KPX r t 33 KPX r semicolon 25 KPX r period -40 KPX r p 25 KPX r n 21 KPX r m 21 KPX r l 12 KPX r k 12 KPX r i 12 KPX r comma -40 KPX r colon 25 KPX r a -7 KPX s w -24 KPX s period -11 KPX s comma -11 KPX semicolon space -40 KPX space quoteleft -48 KPX space quotedblleft -24 KPX space Y -73 KPX space W -32 KPX space V -40 KPX space T -40 KPX v period -65 KPX v o -20 KPX v e -20 KPX v comma -65 KPX v a -20 KPX w period -48 KPX w o -7 KPX w e -7 KPX w comma -48 KPX w a -11 KPX x e -24 KPX y period -81 KPX y o -15 KPX y e -15 KPX y comma -81 KPX y a -15 KPX z o -11 KPX z e -11 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 137 195 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 195 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 137 195 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 137 195 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 137 175 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 137 195 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 195 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 195 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 195 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 195 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 195 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 195 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 195 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 195 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 168 195 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 195 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 195 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 195 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 195 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 195 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 195 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 195 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 195 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 195 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 195 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 195 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 195 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 195 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; EndComposites EndFontMetrics ��������������������������������������./saods9/blt3.0.1/library/afm/Bookman-Light.afm�����������������������������������������������������0000644�0001750�0001750�00000036060�11462120062�017572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Jan 21 16:15:53 1992 Comment UniqueID 37833 Comment VMusage 32321 39213 FontName Bookman-Light FullName ITC Bookman Light FamilyName ITC Bookman Weight Light ItalicAngle 0 IsFixedPitch false FontBBox -188 -251 1266 908 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 484 Ascender 717 Descender -228 StartCharMetrics 228 C 32 ; WX 320 ; N space ; B 0 0 0 0 ; C 33 ; WX 300 ; N exclam ; B 75 -8 219 698 ; C 34 ; WX 380 ; N quotedbl ; B 56 458 323 698 ; C 35 ; WX 620 ; N numbersign ; B 65 0 556 681 ; C 36 ; WX 620 ; N dollar ; B 34 -109 593 791 ; C 37 ; WX 900 ; N percent ; B 22 -8 873 698 ; C 38 ; WX 800 ; N ampersand ; B 45 -17 787 698 ; C 39 ; WX 220 ; N quoteright ; B 46 480 178 698 ; C 40 ; WX 300 ; N parenleft ; B 76 -145 278 727 ; C 41 ; WX 300 ; N parenright ; B 17 -146 219 727 ; C 42 ; WX 440 ; N asterisk ; B 54 325 391 698 ; C 43 ; WX 600 ; N plus ; B 51 8 555 513 ; C 44 ; WX 320 ; N comma ; B 90 -114 223 114 ; C 45 ; WX 400 ; N hyphen ; B 50 232 350 292 ; C 46 ; WX 320 ; N period ; B 92 -8 220 123 ; C 47 ; WX 600 ; N slash ; B 74 -149 532 717 ; C 48 ; WX 620 ; N zero ; B 40 -17 586 698 ; C 49 ; WX 620 ; N one ; B 160 0 501 681 ; C 50 ; WX 620 ; N two ; B 42 0 576 698 ; C 51 ; WX 620 ; N three ; B 40 -17 576 698 ; C 52 ; WX 620 ; N four ; B 25 0 600 681 ; C 53 ; WX 620 ; N five ; B 60 -17 584 717 ; C 54 ; WX 620 ; N six ; B 45 -17 590 698 ; C 55 ; WX 620 ; N seven ; B 60 0 586 681 ; C 56 ; WX 620 ; N eight ; B 44 -17 583 698 ; C 57 ; WX 620 ; N nine ; B 37 -17 576 698 ; C 58 ; WX 320 ; N colon ; B 92 -8 220 494 ; C 59 ; WX 320 ; N semicolon ; B 90 -114 223 494 ; C 60 ; WX 600 ; N less ; B 49 -2 558 526 ; C 61 ; WX 600 ; N equal ; B 51 126 555 398 ; C 62 ; WX 600 ; N greater ; B 48 -2 557 526 ; C 63 ; WX 540 ; N question ; B 27 -8 514 698 ; C 64 ; WX 820 ; N at ; B 55 -17 755 698 ; C 65 ; WX 680 ; N A ; B -37 0 714 681 ; C 66 ; WX 740 ; N B ; B 31 0 702 681 ; C 67 ; WX 740 ; N C ; B 44 -17 702 698 ; C 68 ; WX 800 ; N D ; B 31 0 752 681 ; C 69 ; WX 720 ; N E ; B 31 0 705 681 ; C 70 ; WX 640 ; N F ; B 31 0 654 681 ; C 71 ; WX 800 ; N G ; B 44 -17 778 698 ; C 72 ; WX 800 ; N H ; B 31 0 769 681 ; C 73 ; WX 340 ; N I ; B 31 0 301 681 ; C 74 ; WX 600 ; N J ; B -23 -17 567 681 ; C 75 ; WX 720 ; N K ; B 31 0 750 681 ; C 76 ; WX 600 ; N L ; B 31 0 629 681 ; C 77 ; WX 920 ; N M ; B 26 0 894 681 ; C 78 ; WX 740 ; N N ; B 26 0 722 681 ; C 79 ; WX 800 ; N O ; B 44 -17 758 698 ; C 80 ; WX 620 ; N P ; B 31 0 613 681 ; C 81 ; WX 820 ; N Q ; B 44 -189 769 698 ; C 82 ; WX 720 ; N R ; B 31 0 757 681 ; C 83 ; WX 660 ; N S ; B 28 -17 634 698 ; C 84 ; WX 620 ; N T ; B -37 0 656 681 ; C 85 ; WX 780 ; N U ; B 25 -17 754 681 ; C 86 ; WX 700 ; N V ; B -30 0 725 681 ; C 87 ; WX 960 ; N W ; B -30 0 984 681 ; C 88 ; WX 720 ; N X ; B -30 0 755 681 ; C 89 ; WX 640 ; N Y ; B -30 0 666 681 ; C 90 ; WX 640 ; N Z ; B 10 0 656 681 ; C 91 ; WX 300 ; N bracketleft ; B 92 -136 258 717 ; C 92 ; WX 600 ; N backslash ; B 74 0 532 717 ; C 93 ; WX 300 ; N bracketright ; B 41 -136 207 717 ; C 94 ; WX 600 ; N asciicircum ; B 52 276 554 681 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 220 ; N quoteleft ; B 46 479 178 698 ; C 97 ; WX 580 ; N a ; B 35 -8 587 494 ; C 98 ; WX 620 ; N b ; B -2 -8 582 717 ; C 99 ; WX 520 ; N c ; B 37 -8 498 494 ; C 100 ; WX 620 ; N d ; B 37 -8 591 717 ; C 101 ; WX 520 ; N e ; B 37 -8 491 494 ; C 102 ; WX 320 ; N f ; B 20 0 414 734 ; L i fi ; L l fl ; C 103 ; WX 540 ; N g ; B 17 -243 542 567 ; C 104 ; WX 660 ; N h ; B 20 0 643 717 ; C 105 ; WX 300 ; N i ; B 20 0 288 654 ; C 106 ; WX 300 ; N j ; B -109 -251 214 654 ; C 107 ; WX 620 ; N k ; B 20 0 628 717 ; C 108 ; WX 300 ; N l ; B 20 0 286 717 ; C 109 ; WX 940 ; N m ; B 17 0 928 494 ; C 110 ; WX 660 ; N n ; B 20 0 649 494 ; C 111 ; WX 560 ; N o ; B 37 -8 526 494 ; C 112 ; WX 620 ; N p ; B 20 -228 583 494 ; C 113 ; WX 580 ; N q ; B 37 -228 589 494 ; C 114 ; WX 440 ; N r ; B 20 0 447 494 ; C 115 ; WX 520 ; N s ; B 40 -8 487 494 ; C 116 ; WX 380 ; N t ; B 20 -8 388 667 ; C 117 ; WX 680 ; N u ; B 20 -8 653 484 ; C 118 ; WX 520 ; N v ; B -23 0 534 484 ; C 119 ; WX 780 ; N w ; B -19 0 804 484 ; C 120 ; WX 560 ; N x ; B -16 0 576 484 ; C 121 ; WX 540 ; N y ; B -23 -236 549 484 ; C 122 ; WX 480 ; N z ; B 7 0 476 484 ; C 123 ; WX 280 ; N braceleft ; B 21 -136 260 717 ; C 124 ; WX 600 ; N bar ; B 264 -250 342 750 ; C 125 ; WX 280 ; N braceright ; B 21 -136 260 717 ; C 126 ; WX 600 ; N asciitilde ; B 52 173 556 352 ; C 161 ; WX 300 ; N exclamdown ; B 75 -214 219 494 ; C 162 ; WX 620 ; N cent ; B 116 20 511 651 ; C 163 ; WX 620 ; N sterling ; B 8 -17 631 698 ; C 164 ; WX 140 ; N fraction ; B -188 0 335 681 ; C 165 ; WX 620 ; N yen ; B -22 0 647 681 ; C 166 ; WX 620 ; N florin ; B -29 -155 633 749 ; C 167 ; WX 520 ; N section ; B 33 -178 486 698 ; C 168 ; WX 620 ; N currency ; B 58 89 563 591 ; C 169 ; WX 220 ; N quotesingle ; B 67 458 153 698 ; C 170 ; WX 400 ; N quotedblleft ; B 46 479 348 698 ; C 171 ; WX 360 ; N guillemotleft ; B 51 89 312 437 ; C 172 ; WX 240 ; N guilsinglleft ; B 51 89 189 437 ; C 173 ; WX 240 ; N guilsinglright ; B 51 89 189 437 ; C 174 ; WX 620 ; N fi ; B 20 0 608 734 ; C 175 ; WX 620 ; N fl ; B 20 0 606 734 ; C 177 ; WX 500 ; N endash ; B -15 232 515 292 ; C 178 ; WX 540 ; N dagger ; B 79 -156 455 698 ; C 179 ; WX 540 ; N daggerdbl ; B 79 -156 455 698 ; C 180 ; WX 320 ; N periodcentered ; B 92 196 220 327 ; C 182 ; WX 600 ; N paragraph ; B 14 0 577 681 ; C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ; C 184 ; WX 220 ; N quotesinglbase ; B 46 -108 178 110 ; C 185 ; WX 400 ; N quotedblbase ; B 46 -108 348 110 ; C 186 ; WX 400 ; N quotedblright ; B 46 480 348 698 ; C 187 ; WX 360 ; N guillemotright ; B 51 89 312 437 ; C 188 ; WX 1000 ; N ellipsis ; B 101 -8 898 123 ; C 189 ; WX 1280 ; N perthousand ; B 22 -8 1266 698 ; C 191 ; WX 540 ; N questiondown ; B 23 -217 510 494 ; C 193 ; WX 340 ; N grave ; B 68 571 274 689 ; C 194 ; WX 340 ; N acute ; B 68 571 274 689 ; C 195 ; WX 420 ; N circumflex ; B 68 567 352 685 ; C 196 ; WX 440 ; N tilde ; B 68 572 375 661 ; C 197 ; WX 440 ; N macron ; B 68 587 364 635 ; C 198 ; WX 460 ; N breve ; B 68 568 396 687 ; C 199 ; WX 260 ; N dotaccent ; B 68 552 186 672 ; C 200 ; WX 420 ; N dieresis ; B 68 552 349 674 ; C 202 ; WX 320 ; N ring ; B 68 546 252 731 ; C 203 ; WX 320 ; N cedilla ; B 68 -200 257 0 ; C 205 ; WX 380 ; N hungarumlaut ; B 68 538 311 698 ; C 206 ; WX 320 ; N ogonek ; B 68 -145 245 0 ; C 207 ; WX 420 ; N caron ; B 68 554 352 672 ; C 208 ; WX 1000 ; N emdash ; B -15 232 1015 292 ; C 225 ; WX 1260 ; N AE ; B -36 0 1250 681 ; C 227 ; WX 420 ; N ordfeminine ; B 49 395 393 698 ; C 232 ; WX 600 ; N Lslash ; B 31 0 629 681 ; C 233 ; WX 800 ; N Oslash ; B 44 -53 758 733 ; C 234 ; WX 1240 ; N OE ; B 44 -17 1214 698 ; C 235 ; WX 420 ; N ordmasculine ; B 56 394 361 698 ; C 241 ; WX 860 ; N ae ; B 35 -8 832 494 ; C 245 ; WX 300 ; N dotlessi ; B 20 0 288 484 ; C 248 ; WX 320 ; N lslash ; B 20 0 291 717 ; C 249 ; WX 560 ; N oslash ; B 37 -40 526 534 ; C 250 ; WX 900 ; N oe ; B 37 -8 876 494 ; C 251 ; WX 660 ; N germandbls ; B -109 -110 614 698 ; C -1 ; WX 520 ; N ecircumflex ; B 37 -8 491 685 ; C -1 ; WX 520 ; N edieresis ; B 37 -8 491 674 ; C -1 ; WX 580 ; N aacute ; B 35 -8 587 689 ; C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ; C -1 ; WX 300 ; N icircumflex ; B 8 0 292 685 ; C -1 ; WX 680 ; N udieresis ; B 20 -8 653 674 ; C -1 ; WX 560 ; N ograve ; B 37 -8 526 689 ; C -1 ; WX 680 ; N uacute ; B 20 -8 653 689 ; C -1 ; WX 680 ; N ucircumflex ; B 20 -8 653 685 ; C -1 ; WX 680 ; N Aacute ; B -37 0 714 866 ; C -1 ; WX 300 ; N igrave ; B 20 0 288 689 ; C -1 ; WX 340 ; N Icircumflex ; B 28 0 312 862 ; C -1 ; WX 520 ; N ccedilla ; B 37 -200 498 494 ; C -1 ; WX 580 ; N adieresis ; B 35 -8 587 674 ; C -1 ; WX 720 ; N Ecircumflex ; B 31 0 705 862 ; C -1 ; WX 520 ; N scaron ; B 40 -8 487 672 ; C -1 ; WX 620 ; N thorn ; B 20 -228 583 717 ; C -1 ; WX 980 ; N trademark ; B 34 277 930 681 ; C -1 ; WX 520 ; N egrave ; B 37 -8 491 689 ; C -1 ; WX 372 ; N threesuperior ; B 12 269 360 698 ; C -1 ; WX 480 ; N zcaron ; B 7 0 476 672 ; C -1 ; WX 580 ; N atilde ; B 35 -8 587 661 ; C -1 ; WX 580 ; N aring ; B 35 -8 587 731 ; C -1 ; WX 560 ; N ocircumflex ; B 37 -8 526 685 ; C -1 ; WX 720 ; N Edieresis ; B 31 0 705 851 ; C -1 ; WX 930 ; N threequarters ; B 52 0 889 691 ; C -1 ; WX 540 ; N ydieresis ; B -23 -236 549 674 ; C -1 ; WX 540 ; N yacute ; B -23 -236 549 689 ; C -1 ; WX 300 ; N iacute ; B 20 0 288 689 ; C -1 ; WX 680 ; N Acircumflex ; B -37 0 714 862 ; C -1 ; WX 780 ; N Uacute ; B 25 -17 754 866 ; C -1 ; WX 520 ; N eacute ; B 37 -8 491 689 ; C -1 ; WX 800 ; N Ograve ; B 44 -17 758 866 ; C -1 ; WX 580 ; N agrave ; B 35 -8 587 689 ; C -1 ; WX 780 ; N Udieresis ; B 25 -17 754 851 ; C -1 ; WX 580 ; N acircumflex ; B 35 -8 587 685 ; C -1 ; WX 340 ; N Igrave ; B 31 0 301 866 ; C -1 ; WX 372 ; N twosuperior ; B 20 279 367 698 ; C -1 ; WX 780 ; N Ugrave ; B 25 -17 754 866 ; C -1 ; WX 930 ; N onequarter ; B 80 0 869 681 ; C -1 ; WX 780 ; N Ucircumflex ; B 25 -17 754 862 ; C -1 ; WX 660 ; N Scaron ; B 28 -17 634 849 ; C -1 ; WX 340 ; N Idieresis ; B 28 0 309 851 ; C -1 ; WX 300 ; N idieresis ; B 8 0 289 674 ; C -1 ; WX 720 ; N Egrave ; B 31 0 705 866 ; C -1 ; WX 800 ; N Oacute ; B 44 -17 758 866 ; C -1 ; WX 600 ; N divide ; B 51 10 555 514 ; C -1 ; WX 680 ; N Atilde ; B -37 0 714 838 ; C -1 ; WX 680 ; N Aring ; B -37 0 714 908 ; C -1 ; WX 800 ; N Odieresis ; B 44 -17 758 851 ; C -1 ; WX 680 ; N Adieresis ; B -37 0 714 851 ; C -1 ; WX 740 ; N Ntilde ; B 26 0 722 838 ; C -1 ; WX 640 ; N Zcaron ; B 10 0 656 849 ; C -1 ; WX 620 ; N Thorn ; B 31 0 613 681 ; C -1 ; WX 340 ; N Iacute ; B 31 0 301 866 ; C -1 ; WX 600 ; N plusminus ; B 51 0 555 513 ; C -1 ; WX 600 ; N multiply ; B 51 9 555 513 ; C -1 ; WX 720 ; N Eacute ; B 31 0 705 866 ; C -1 ; WX 640 ; N Ydieresis ; B -30 0 666 851 ; C -1 ; WX 372 ; N onesuperior ; B 80 279 302 688 ; C -1 ; WX 680 ; N ugrave ; B 20 -8 653 689 ; C -1 ; WX 600 ; N logicalnot ; B 51 128 555 398 ; C -1 ; WX 660 ; N ntilde ; B 20 0 649 661 ; C -1 ; WX 800 ; N Otilde ; B 44 -17 758 838 ; C -1 ; WX 560 ; N otilde ; B 37 -8 526 661 ; C -1 ; WX 740 ; N Ccedilla ; B 44 -200 702 698 ; C -1 ; WX 680 ; N Agrave ; B -37 0 714 866 ; C -1 ; WX 930 ; N onehalf ; B 80 0 885 681 ; C -1 ; WX 800 ; N Eth ; B 31 0 752 681 ; C -1 ; WX 400 ; N degree ; B 50 398 350 698 ; C -1 ; WX 640 ; N Yacute ; B -30 0 666 866 ; C -1 ; WX 800 ; N Ocircumflex ; B 44 -17 758 862 ; C -1 ; WX 560 ; N oacute ; B 37 -8 526 689 ; C -1 ; WX 680 ; N mu ; B 20 -251 653 484 ; C -1 ; WX 600 ; N minus ; B 51 224 555 300 ; C -1 ; WX 560 ; N eth ; B 37 -8 526 734 ; C -1 ; WX 560 ; N odieresis ; B 37 -8 526 674 ; C -1 ; WX 740 ; N copyright ; B 24 -17 724 698 ; C -1 ; WX 600 ; N brokenbar ; B 264 -175 342 675 ; EndCharMetrics StartKernData StartKernPairs 82 KPX A y 32 KPX A w 4 KPX A v 7 KPX A Y -35 KPX A W -40 KPX A V -56 KPX A T 1 KPX F period -46 KPX F comma -41 KPX F A -21 KPX L y 79 KPX L Y 13 KPX L W 1 KPX L V -4 KPX L T 28 KPX P period -60 KPX P comma -55 KPX P A -8 KPX R y 59 KPX R Y 26 KPX R W 13 KPX R V 8 KPX R T 71 KPX T s 16 KPX T r 38 KPX T period -33 KPX T o 15 KPX T i 42 KPX T hyphen 90 KPX T e 13 KPX T comma -28 KPX T c 14 KPX T a 17 KPX T A 1 KPX V y 15 KPX V u -38 KPX V r -41 KPX V period -40 KPX V o -71 KPX V i -20 KPX V hyphen 11 KPX V e -72 KPX V comma -34 KPX V a -69 KPX V A -66 KPX W y 15 KPX W u -38 KPX W r -41 KPX W period -40 KPX W o -68 KPX W i -20 KPX W hyphen 11 KPX W e -69 KPX W comma -34 KPX W a -66 KPX W A -64 KPX Y v 15 KPX Y u -38 KPX Y q -55 KPX Y period -40 KPX Y p -31 KPX Y o -57 KPX Y i -37 KPX Y hyphen 11 KPX Y e -58 KPX Y comma -34 KPX Y a -54 KPX Y A -53 KPX f f 29 KPX r q 9 KPX r period -64 KPX r o 8 KPX r n 31 KPX r m 31 KPX r hyphen 70 KPX r h -21 KPX r g -4 KPX r f 33 KPX r e 7 KPX r d 7 KPX r comma -58 KPX r c 7 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 130 177 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 140 177 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 180 177 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 177 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 220 177 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 150 177 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 177 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 177 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -40 177 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -40 177 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -20 177 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 150 177 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 260 177 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 190 177 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 177 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 177 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 177 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 177 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 177 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 190 177 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 177 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 110 177 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 110 177 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 130 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 70 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 50 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -60 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -60 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 110 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 70 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 50 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 130 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 130 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 170 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 100 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ; EndComposites EndFontMetrics ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/AvantGarde-DemiOblique.afm��������������������������������������������0000644�0001750�0001750�00000042650�11462120062�021352� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Mar 4 13:49:44 1991 Comment UniqueID 34373 Comment VMusage 6550 39938 FontName AvantGarde-DemiOblique FullName ITC Avant Garde Gothic Demi Oblique FamilyName ITC Avant Garde Gothic Weight Demi ItalicAngle -10.5 IsFixedPitch false FontBBox -123 -251 1256 1021 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 740 XHeight 555 Ascender 740 Descender -185 StartCharMetrics 228 C 32 ; WX 280 ; N space ; B 0 0 0 0 ; C 33 ; WX 280 ; N exclam ; B 73 0 343 740 ; C 34 ; WX 360 ; N quotedbl ; B 127 444 478 740 ; C 35 ; WX 560 ; N numbersign ; B 66 0 618 700 ; C 36 ; WX 560 ; N dollar ; B 99 -86 582 857 ; C 37 ; WX 860 ; N percent ; B 139 -15 856 755 ; C 38 ; WX 680 ; N ampersand ; B 71 -15 742 755 ; C 39 ; WX 280 ; N quoteright ; B 159 466 342 740 ; C 40 ; WX 380 ; N parenleft ; B 120 -157 490 754 ; C 41 ; WX 380 ; N parenright ; B 8 -157 378 754 ; C 42 ; WX 440 ; N asterisk ; B 174 457 492 755 ; C 43 ; WX 600 ; N plus ; B 84 0 610 506 ; C 44 ; WX 280 ; N comma ; B 48 -141 231 133 ; C 45 ; WX 420 ; N hyphen ; B 114 230 413 348 ; C 46 ; WX 280 ; N period ; B 73 0 231 133 ; C 47 ; WX 460 ; N slash ; B -13 -100 591 740 ; C 48 ; WX 560 ; N zero ; B 70 -15 628 755 ; C 49 ; WX 560 ; N one ; B 230 0 500 740 ; C 50 ; WX 560 ; N two ; B 44 0 622 755 ; C 51 ; WX 560 ; N three ; B 67 -15 585 755 ; C 52 ; WX 560 ; N four ; B 36 0 604 740 ; C 53 ; WX 560 ; N five ; B 64 -15 600 740 ; C 54 ; WX 560 ; N six ; B 64 -15 587 739 ; C 55 ; WX 560 ; N seven ; B 83 0 635 740 ; C 56 ; WX 560 ; N eight ; B 71 -15 590 755 ; C 57 ; WX 560 ; N nine ; B 110 0 633 754 ; C 58 ; WX 280 ; N colon ; B 73 0 309 555 ; C 59 ; WX 280 ; N semicolon ; B 48 -141 309 555 ; C 60 ; WX 600 ; N less ; B 84 -8 649 514 ; C 61 ; WX 600 ; N equal ; B 63 81 631 425 ; C 62 ; WX 600 ; N greater ; B 45 -8 610 514 ; C 63 ; WX 560 ; N question ; B 135 0 593 755 ; C 64 ; WX 740 ; N at ; B 109 -12 832 712 ; C 65 ; WX 740 ; N A ; B 7 0 732 740 ; C 66 ; WX 580 ; N B ; B 70 0 610 740 ; C 67 ; WX 780 ; N C ; B 97 -15 864 755 ; C 68 ; WX 700 ; N D ; B 63 0 732 740 ; C 69 ; WX 520 ; N E ; B 61 0 596 740 ; C 70 ; WX 480 ; N F ; B 61 0 575 740 ; C 71 ; WX 840 ; N G ; B 89 -15 887 755 ; C 72 ; WX 680 ; N H ; B 71 0 747 740 ; C 73 ; WX 280 ; N I ; B 72 0 346 740 ; C 74 ; WX 480 ; N J ; B 34 -15 546 740 ; C 75 ; WX 620 ; N K ; B 89 0 757 740 ; C 76 ; WX 440 ; N L ; B 72 0 459 740 ; C 77 ; WX 900 ; N M ; B 63 0 974 740 ; C 78 ; WX 740 ; N N ; B 70 0 808 740 ; C 79 ; WX 840 ; N O ; B 95 -15 882 755 ; C 80 ; WX 560 ; N P ; B 72 0 645 740 ; C 81 ; WX 840 ; N Q ; B 94 -15 882 755 ; C 82 ; WX 580 ; N R ; B 64 0 656 740 ; C 83 ; WX 520 ; N S ; B 49 -15 578 755 ; C 84 ; WX 420 ; N T ; B 119 0 555 740 ; C 85 ; WX 640 ; N U ; B 97 -15 722 740 ; C 86 ; WX 700 ; N V ; B 145 0 832 740 ; C 87 ; WX 900 ; N W ; B 144 0 1036 740 ; C 88 ; WX 680 ; N X ; B 4 0 813 740 ; C 89 ; WX 620 ; N Y ; B 135 0 759 740 ; C 90 ; WX 500 ; N Z ; B 19 0 599 740 ; C 91 ; WX 320 ; N bracketleft ; B 89 -157 424 754 ; C 92 ; WX 640 ; N backslash ; B 233 -100 525 740 ; C 93 ; WX 320 ; N bracketright ; B 7 -157 342 754 ; C 94 ; WX 600 ; N asciicircum ; B 142 375 596 740 ; C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ; C 96 ; WX 280 ; N quoteleft ; B 158 466 341 740 ; C 97 ; WX 660 ; N a ; B 73 -18 716 574 ; C 98 ; WX 660 ; N b ; B 47 -18 689 740 ; C 99 ; WX 640 ; N c ; B 84 -18 679 574 ; C 100 ; WX 660 ; N d ; B 80 -18 755 740 ; C 101 ; WX 640 ; N e ; B 77 -18 667 577 ; C 102 ; WX 280 ; N f ; B 62 0 420 755 ; L i fi ; L l fl ; C 103 ; WX 660 ; N g ; B 33 -226 726 574 ; C 104 ; WX 600 ; N h ; B 54 0 614 740 ; C 105 ; WX 240 ; N i ; B 53 0 323 740 ; C 106 ; WX 260 ; N j ; B -18 -185 342 740 ; C 107 ; WX 580 ; N k ; B 80 0 648 740 ; C 108 ; WX 240 ; N l ; B 54 0 324 740 ; C 109 ; WX 940 ; N m ; B 54 0 954 574 ; C 110 ; WX 600 ; N n ; B 54 0 613 574 ; C 111 ; WX 640 ; N o ; B 71 -18 672 574 ; C 112 ; WX 660 ; N p ; B 13 -185 686 574 ; C 113 ; WX 660 ; N q ; B 78 -185 716 574 ; C 114 ; WX 320 ; N r ; B 63 0 423 574 ; C 115 ; WX 440 ; N s ; B 49 -18 483 574 ; C 116 ; WX 300 ; N t ; B 86 0 402 740 ; C 117 ; WX 600 ; N u ; B 87 -18 647 555 ; C 118 ; WX 560 ; N v ; B 106 0 659 555 ; C 119 ; WX 800 ; N w ; B 114 0 892 555 ; C 120 ; WX 560 ; N x ; B 3 0 632 555 ; C 121 ; WX 580 ; N y ; B 75 -185 674 555 ; C 122 ; WX 460 ; N z ; B 20 0 528 555 ; C 123 ; WX 340 ; N braceleft ; B 40 -191 455 747 ; C 124 ; WX 600 ; N bar ; B 214 -100 503 740 ; C 125 ; WX 340 ; N braceright ; B -12 -191 405 747 ; C 126 ; WX 600 ; N asciitilde ; B 114 160 579 347 ; C 161 ; WX 280 ; N exclamdown ; B 40 -185 310 555 ; C 162 ; WX 560 ; N cent ; B 110 39 599 715 ; C 163 ; WX 560 ; N sterling ; B 38 0 615 755 ; C 164 ; WX 160 ; N fraction ; B -123 0 419 740 ; C 165 ; WX 560 ; N yen ; B 83 0 707 740 ; C 166 ; WX 560 ; N florin ; B -27 -151 664 824 ; C 167 ; WX 560 ; N section ; B 65 -158 602 755 ; C 168 ; WX 560 ; N currency ; B 53 69 628 577 ; C 169 ; WX 220 ; N quotesingle ; B 152 444 314 740 ; C 170 ; WX 480 ; N quotedblleft ; B 156 466 546 740 ; C 171 ; WX 460 ; N guillemotleft ; B 105 108 487 469 ; C 172 ; WX 240 ; N guilsinglleft ; B 94 108 277 469 ; C 173 ; WX 240 ; N guilsinglright ; B 70 108 253 469 ; C 174 ; WX 520 ; N fi ; B 72 0 598 755 ; C 175 ; WX 520 ; N fl ; B 72 0 598 755 ; C 177 ; WX 500 ; N endash ; B 78 230 529 348 ; C 178 ; WX 560 ; N dagger ; B 133 -142 612 740 ; C 179 ; WX 560 ; N daggerdbl ; B 63 -142 618 740 ; C 180 ; WX 280 ; N periodcentered ; B 108 187 265 320 ; C 182 ; WX 600 ; N paragraph ; B 90 -103 744 740 ; C 183 ; WX 600 ; N bullet ; B 215 222 526 532 ; C 184 ; WX 280 ; N quotesinglbase ; B 47 -141 230 133 ; C 185 ; WX 480 ; N quotedblbase ; B 45 -141 435 133 ; C 186 ; WX 480 ; N quotedblright ; B 157 466 547 740 ; C 187 ; WX 460 ; N guillemotright ; B 81 108 463 469 ; C 188 ; WX 1000 ; N ellipsis ; B 100 0 924 133 ; C 189 ; WX 1280 ; N perthousand ; B 139 -15 1256 755 ; C 191 ; WX 560 ; N questiondown ; B 69 -200 527 555 ; C 193 ; WX 420 ; N grave ; B 189 624 462 851 ; C 194 ; WX 420 ; N acute ; B 224 624 508 849 ; C 195 ; WX 540 ; N circumflex ; B 189 636 588 774 ; C 196 ; WX 480 ; N tilde ; B 178 636 564 767 ; C 197 ; WX 420 ; N macron ; B 192 648 490 759 ; C 198 ; WX 480 ; N breve ; B 185 633 582 770 ; C 199 ; WX 280 ; N dotaccent ; B 192 636 350 769 ; C 200 ; WX 500 ; N dieresis ; B 196 636 565 769 ; C 202 ; WX 360 ; N ring ; B 206 619 424 834 ; C 203 ; WX 340 ; N cedilla ; B 67 -251 272 6 ; C 205 ; WX 700 ; N hungarumlaut ; B 258 610 754 862 ; C 206 ; WX 340 ; N ogonek ; B 59 -195 243 9 ; C 207 ; WX 540 ; N caron ; B 214 636 613 774 ; C 208 ; WX 1000 ; N emdash ; B 78 230 1029 348 ; C 225 ; WX 900 ; N AE ; B -5 0 961 740 ; C 227 ; WX 360 ; N ordfeminine ; B 127 438 472 755 ; C 232 ; WX 480 ; N Lslash ; B 68 0 484 740 ; C 233 ; WX 840 ; N Oslash ; B 94 -71 891 814 ; C 234 ; WX 1060 ; N OE ; B 98 -15 1144 755 ; C 235 ; WX 360 ; N ordmasculine ; B 131 438 451 755 ; C 241 ; WX 1080 ; N ae ; B 75 -18 1105 574 ; C 245 ; WX 240 ; N dotlessi ; B 53 0 289 555 ; C 248 ; WX 320 ; N lslash ; B 74 0 404 740 ; C 249 ; WX 660 ; N oslash ; B 81 -50 685 608 ; C 250 ; WX 1080 ; N oe ; B 76 -18 1108 574 ; C 251 ; WX 600 ; N germandbls ; B 51 -18 629 755 ; C -1 ; WX 640 ; N ecircumflex ; B 77 -18 667 774 ; C -1 ; WX 640 ; N edieresis ; B 77 -18 667 769 ; C -1 ; WX 660 ; N aacute ; B 73 -18 716 849 ; C -1 ; WX 740 ; N registered ; B 50 -12 827 752 ; C -1 ; WX 240 ; N icircumflex ; B 39 0 438 774 ; C -1 ; WX 600 ; N udieresis ; B 87 -18 647 769 ; C -1 ; WX 640 ; N ograve ; B 71 -18 672 851 ; C -1 ; WX 600 ; N uacute ; B 87 -18 647 849 ; C -1 ; WX 600 ; N ucircumflex ; B 87 -18 647 774 ; C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ; C -1 ; WX 240 ; N igrave ; B 53 0 347 851 ; C -1 ; WX 280 ; N Icircumflex ; B 72 0 489 944 ; C -1 ; WX 640 ; N ccedilla ; B 83 -251 679 574 ; C -1 ; WX 660 ; N adieresis ; B 73 -18 716 769 ; C -1 ; WX 520 ; N Ecircumflex ; B 61 0 609 944 ; C -1 ; WX 440 ; N scaron ; B 49 -18 563 774 ; C -1 ; WX 660 ; N thorn ; B 13 -185 686 740 ; C -1 ; WX 1000 ; N trademark ; B 131 296 958 740 ; C -1 ; WX 640 ; N egrave ; B 77 -18 667 851 ; C -1 ; WX 336 ; N threesuperior ; B 87 287 413 749 ; C -1 ; WX 460 ; N zcaron ; B 20 0 598 774 ; C -1 ; WX 660 ; N atilde ; B 73 -18 716 767 ; C -1 ; WX 660 ; N aring ; B 73 -18 716 834 ; C -1 ; WX 640 ; N ocircumflex ; B 71 -18 672 774 ; C -1 ; WX 520 ; N Edieresis ; B 61 0 606 939 ; C -1 ; WX 840 ; N threequarters ; B 97 0 836 749 ; C -1 ; WX 580 ; N ydieresis ; B 75 -185 674 769 ; C -1 ; WX 580 ; N yacute ; B 75 -185 674 849 ; C -1 ; WX 240 ; N iacute ; B 53 0 443 849 ; C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ; C -1 ; WX 640 ; N Uacute ; B 97 -15 722 1019 ; C -1 ; WX 640 ; N eacute ; B 77 -18 667 849 ; C -1 ; WX 840 ; N Ograve ; B 95 -15 882 1021 ; C -1 ; WX 660 ; N agrave ; B 73 -18 716 851 ; C -1 ; WX 640 ; N Udieresis ; B 97 -15 722 939 ; C -1 ; WX 660 ; N acircumflex ; B 73 -18 716 774 ; C -1 ; WX 280 ; N Igrave ; B 72 0 398 1021 ; C -1 ; WX 336 ; N twosuperior ; B 73 296 436 749 ; C -1 ; WX 640 ; N Ugrave ; B 97 -15 722 1021 ; C -1 ; WX 840 ; N onequarter ; B 187 0 779 740 ; C -1 ; WX 640 ; N Ucircumflex ; B 97 -15 722 944 ; C -1 ; WX 520 ; N Scaron ; B 49 -15 635 944 ; C -1 ; WX 280 ; N Idieresis ; B 72 0 486 939 ; C -1 ; WX 240 ; N idieresis ; B 53 0 435 769 ; C -1 ; WX 520 ; N Egrave ; B 61 0 596 1021 ; C -1 ; WX 840 ; N Oacute ; B 95 -15 882 1019 ; C -1 ; WX 600 ; N divide ; B 84 -20 610 526 ; C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ; C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ; C -1 ; WX 840 ; N Odieresis ; B 95 -15 882 939 ; C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ; C -1 ; WX 740 ; N Ntilde ; B 70 0 808 937 ; C -1 ; WX 500 ; N Zcaron ; B 19 0 650 944 ; C -1 ; WX 560 ; N Thorn ; B 72 0 619 740 ; C -1 ; WX 280 ; N Iacute ; B 72 0 494 1019 ; C -1 ; WX 600 ; N plusminus ; B 37 -62 626 556 ; C -1 ; WX 600 ; N multiply ; B 76 12 617 494 ; C -1 ; WX 520 ; N Eacute ; B 61 0 596 1019 ; C -1 ; WX 620 ; N Ydieresis ; B 135 0 759 939 ; C -1 ; WX 336 ; N onesuperior ; B 182 296 360 740 ; C -1 ; WX 600 ; N ugrave ; B 87 -18 647 851 ; C -1 ; WX 600 ; N logicalnot ; B 105 108 631 425 ; C -1 ; WX 600 ; N ntilde ; B 54 0 624 767 ; C -1 ; WX 840 ; N Otilde ; B 95 -15 882 937 ; C -1 ; WX 640 ; N otilde ; B 71 -18 672 767 ; C -1 ; WX 780 ; N Ccedilla ; B 97 -251 864 755 ; C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ; C -1 ; WX 840 ; N onehalf ; B 157 0 830 740 ; C -1 ; WX 742 ; N Eth ; B 83 0 766 740 ; C -1 ; WX 400 ; N degree ; B 160 426 451 712 ; C -1 ; WX 620 ; N Yacute ; B 135 0 759 1019 ; C -1 ; WX 840 ; N Ocircumflex ; B 95 -15 882 944 ; C -1 ; WX 640 ; N oacute ; B 71 -18 672 849 ; C -1 ; WX 576 ; N mu ; B 3 -187 642 555 ; C -1 ; WX 600 ; N minus ; B 84 193 610 313 ; C -1 ; WX 640 ; N eth ; B 73 -18 699 754 ; C -1 ; WX 640 ; N odieresis ; B 71 -18 672 769 ; C -1 ; WX 740 ; N copyright ; B 50 -12 827 752 ; C -1 ; WX 600 ; N brokenbar ; B 214 -100 503 740 ; EndCharMetrics StartKernData StartKernPairs 218 KPX A y -50 KPX A w -65 KPX A v -70 KPX A u -20 KPX A quoteright -90 KPX A Y -80 KPX A W -60 KPX A V -102 KPX A U -40 KPX A T -25 KPX A Q -50 KPX A O -50 KPX A G -40 KPX A C -40 KPX B A -10 KPX C A -40 KPX D period -20 KPX D comma -20 KPX D Y -45 KPX D W -25 KPX D V -50 KPX D A -50 KPX F period -129 KPX F e -20 KPX F comma -162 KPX F a -20 KPX F A -75 KPX G period -20 KPX G comma -20 KPX G Y -15 KPX J period -15 KPX J a -20 KPX J A -30 KPX K y -20 KPX K u -15 KPX K o -45 KPX K e -40 KPX K O -30 KPX L y -23 KPX L quoteright -30 KPX L quotedblright -30 KPX L Y -80 KPX L W -55 KPX L V -85 KPX L T -46 KPX O period -30 KPX O comma -30 KPX O Y -30 KPX O X -30 KPX O W -20 KPX O V -45 KPX O T -15 KPX O A -60 KPX P period -200 KPX P o -20 KPX P e -20 KPX P comma -220 KPX P a -20 KPX P A -100 KPX Q comma 20 KPX R W 25 KPX R V -10 KPX R U 25 KPX R T 40 KPX R O 25 KPX S comma 20 KPX T y -10 KPX T w -55 KPX T u -46 KPX T semicolon -29 KPX T r -30 KPX T period -91 KPX T o -49 KPX T hyphen -75 KPX T e -49 KPX T comma -82 KPX T colon -15 KPX T a -70 KPX T O -15 KPX T A -25 KPX U period -20 KPX U comma -20 KPX U A -40 KPX V u -55 KPX V semicolon -33 KPX V period -145 KPX V o -101 KPX V i -15 KPX V hyphen -75 KPX V e -101 KPX V comma -145 KPX V colon -18 KPX V a -95 KPX V O -45 KPX V G -20 KPX V A -102 KPX W y -15 KPX W u -30 KPX W semicolon -33 KPX W period -106 KPX W o -46 KPX W i -10 KPX W hyphen -35 KPX W e -47 KPX W comma -106 KPX W colon -15 KPX W a -50 KPX W O -20 KPX W A -58 KPX Y u -52 KPX Y semicolon -23 KPX Y period -145 KPX Y o -89 KPX Y hyphen -100 KPX Y e -89 KPX Y comma -145 KPX Y colon -10 KPX Y a -93 KPX Y O -30 KPX Y A -80 KPX a t 5 KPX a p 20 KPX a b 5 KPX b y -20 KPX b v -20 KPX c y -20 KPX c l -15 KPX c k -15 KPX comma space -50 KPX comma quoteright -70 KPX comma quotedblright -70 KPX e y -20 KPX e x -20 KPX e w -20 KPX e v -20 KPX f period -40 KPX f o -20 KPX f l -15 KPX f i -15 KPX f f -20 KPX f dotlessi -15 KPX f comma -40 KPX f a -15 KPX g i 25 KPX g a 15 KPX h y -30 KPX k y -5 KPX k o -30 KPX k e -40 KPX m y -20 KPX m u -20 KPX n y -15 KPX n v -30 KPX o y -20 KPX o x -30 KPX o w -20 KPX o v -30 KPX p y -20 KPX period space -50 KPX period quoteright -70 KPX period quotedblright -70 KPX quotedblleft A -50 KPX quotedblright space -50 KPX quoteleft quoteleft -80 KPX quoteleft A -50 KPX quoteright v -10 KPX quoteright t 10 KPX quoteright space -50 KPX quoteright s -15 KPX quoteright r -20 KPX quoteright quoteright -80 KPX quoteright d -50 KPX r y 40 KPX r v 40 KPX r u 20 KPX r t 20 KPX r s 20 KPX r q -8 KPX r period -73 KPX r p 20 KPX r o -15 KPX r n 21 KPX r m 15 KPX r l 20 KPX r k 5 KPX r i 20 KPX r hyphen -60 KPX r g 1 KPX r e -4 KPX r d -6 KPX r comma -75 KPX r c -7 KPX s period 20 KPX s comma 20 KPX space quoteleft -50 KPX space quotedblleft -50 KPX space Y -60 KPX space W -25 KPX space V -80 KPX space T -25 KPX space A -20 KPX v period -90 KPX v o -20 KPX v e -20 KPX v comma -90 KPX v a -30 KPX w period -90 KPX w o -30 KPX w e -20 KPX w comma -90 KPX w a -30 KPX x e -20 KPX y period -100 KPX y o -30 KPX y e -20 KPX y comma -100 KPX y c -35 KPX y a -30 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 170 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 132 170 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 170 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 170 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 215 135 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 162 170 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 82 170 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 22 170 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 42 170 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 82 170 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -13 170 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -98 170 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -78 170 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -63 170 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 162 170 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 242 170 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 182 170 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 202 170 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 242 170 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 212 170 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 22 170 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 177 170 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 82 170 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 102 170 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 107 170 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 170 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 92 170 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 37 170 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Makefile.in�����������������������������������������������������������0000644�0001750�0001750�00000003427�11462120062�016520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for AFM files. # ------------------------------------------------------------------------ datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ libdir = @libdir@ prefix = @prefix@ srcdir = @srcdir@ version = @BLT_VERSION@ so_prefix = @BLT_SO_PREFIX@ so_ext = @BLT_SO_EXT@ lib_suffix = @BLT_LIB_SUFFIX@ pkgdir = @BLT_LIBRARY@ afmdir = $(pkgdir)/afm INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ RM = rm -f SHELL = /bin/sh MKDIR_P = @MKDIR_P@ afmFiles = \ AvantGarde-Book.afm \ AvantGarde-BookOblique.afm \ AvantGarde-Demi.afm \ AvantGarde-DemiOblique.afm \ Bookman-Demi.afm \ Bookman-DemiItalic.afm \ Bookman-Light.afm \ Bookman-LightItalic.afm \ Courier-Bold.afm \ Courier-BoldOblique.afm \ Courier-Oblique.afm \ Courier.afm \ Helvetica-Bold.afm \ Helvetica-BoldOblique.afm \ Helvetica-Condensed-Bold.afm \ Helvetica-Condensed-BoldObl.afm \ Helvetica-Condensed-Oblique.afm \ Helvetica-Condensed.afm \ Helvetica-Narrow-Bold.afm \ Helvetica-Narrow-BoldOblique.afm \ Helvetica-Narrow-Oblique.afm \ Helvetica-Narrow.afm \ Helvetica-Oblique.afm \ Helvetica.afm \ NewCenturySchlbk-Bold.afm \ NewCenturySchlbk-BoldItalic.afm \ NewCenturySchlbk-Italic.afm \ NewCenturySchlbk-Roman.afm \ Palatino-Bold.afm \ Palatino-BoldItalic.afm \ Palatino-Italic.afm \ Palatino-Roman.afm \ Symbol.afm \ Times-Bold.afm \ Times-BoldItalic.afm \ Times-Italic.afm \ Times-Roman.afm \ ZapfChancery-MediumItalic.afm \ ZapfDingbats.afm all: install: mkdirs for i in $(afmFiles) ; do \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(afmdir) ; \ done mkdirs: $(MKDIR_P) $(DESTDIR)$(afmdir) clean: distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Helvetica-Narrow-Oblique.afm������������������������������������������0000644�0001750�0001750�00000044072�11462120062�021711� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Thu Mar 15 11:25:48 1990 Comment UniqueID 28389 Comment VMusage 7572 42473 FontName Helvetica-Narrow-Oblique FullName Helvetica Narrow Oblique FamilyName Helvetica Weight Medium ItalicAngle -12 IsFixedPitch false FontBBox -139 -225 915 931 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StartCharMetrics 228 C 32 ; WX 228 ; N space ; B 0 0 0 0 ; C 33 ; WX 228 ; N exclam ; B 74 0 278 718 ; C 34 ; WX 291 ; N quotedbl ; B 138 463 359 718 ; C 35 ; WX 456 ; N numbersign ; B 60 0 517 688 ; C 36 ; WX 456 ; N dollar ; B 57 -115 506 775 ; C 37 ; WX 729 ; N percent ; B 120 -19 729 703 ; C 38 ; WX 547 ; N ampersand ; B 63 -15 530 718 ; C 39 ; WX 182 ; N quoteright ; B 124 463 254 718 ; C 40 ; WX 273 ; N parenleft ; B 89 -207 372 733 ; C 41 ; WX 273 ; N parenright ; B -7 -207 276 733 ; C 42 ; WX 319 ; N asterisk ; B 135 431 389 718 ; C 43 ; WX 479 ; N plus ; B 70 0 497 505 ; C 44 ; WX 228 ; N comma ; B 46 -147 175 106 ; C 45 ; WX 273 ; N hyphen ; B 77 232 293 322 ; C 46 ; WX 228 ; N period ; B 71 0 175 106 ; C 47 ; WX 228 ; N slash ; B -17 -19 370 737 ; C 48 ; WX 456 ; N zero ; B 77 -19 499 703 ; C 49 ; WX 456 ; N one ; B 170 0 417 703 ; C 50 ; WX 456 ; N two ; B 21 0 506 703 ; C 51 ; WX 456 ; N three ; B 61 -19 500 703 ; C 52 ; WX 456 ; N four ; B 50 0 472 703 ; C 53 ; WX 456 ; N five ; B 55 -19 509 688 ; C 54 ; WX 456 ; N six ; B 74 -19 504 703 ; C 55 ; WX 456 ; N seven ; B 112 0 549 688 ; C 56 ; WX 456 ; N eight ; B 60 -19 497 703 ; C 57 ; WX 456 ; N nine ; B 67 -19 499 703 ; C 58 ; WX 228 ; N colon ; B 71 0 247 516 ; C 59 ; WX 228 ; N semicolon ; B 46 -147 247 516 ; C 60 ; WX 479 ; N less ; B 77 11 526 495 ; C 61 ; WX 479 ; N equal ; B 52 115 515 390 ; C 62 ; WX 479 ; N greater ; B 41 11 490 495 ; C 63 ; WX 456 ; N question ; B 132 0 500 727 ; C 64 ; WX 832 ; N at ; B 176 -19 791 737 ; C 65 ; WX 547 ; N A ; B 11 0 536 718 ; C 66 ; WX 547 ; N B ; B 61 0 583 718 ; C 67 ; WX 592 ; N C ; B 88 -19 640 737 ; C 68 ; WX 592 ; N D ; B 66 0 626 718 ; C 69 ; WX 547 ; N E ; B 71 0 625 718 ; C 70 ; WX 501 ; N F ; B 71 0 603 718 ; C 71 ; WX 638 ; N G ; B 91 -19 655 737 ; C 72 ; WX 592 ; N H ; B 63 0 655 718 ; C 73 ; WX 228 ; N I ; B 75 0 279 718 ; C 74 ; WX 410 ; N J ; B 39 -19 476 718 ; C 75 ; WX 547 ; N K ; B 62 0 662 718 ; C 76 ; WX 456 ; N L ; B 62 0 455 718 ; C 77 ; WX 683 ; N M ; B 60 0 749 718 ; C 78 ; WX 592 ; N N ; B 62 0 655 718 ; C 79 ; WX 638 ; N O ; B 86 -19 677 737 ; C 80 ; WX 547 ; N P ; B 71 0 604 718 ; C 81 ; WX 638 ; N Q ; B 86 -56 677 737 ; C 82 ; WX 592 ; N R ; B 72 0 634 718 ; C 83 ; WX 547 ; N S ; B 74 -19 584 737 ; C 84 ; WX 501 ; N T ; B 122 0 615 718 ; C 85 ; WX 592 ; N U ; B 101 -19 653 718 ; C 86 ; WX 547 ; N V ; B 142 0 656 718 ; C 87 ; WX 774 ; N W ; B 138 0 886 718 ; C 88 ; WX 547 ; N X ; B 16 0 647 718 ; C 89 ; WX 547 ; N Y ; B 137 0 661 718 ; C 90 ; WX 501 ; N Z ; B 19 0 607 718 ; C 91 ; WX 228 ; N bracketleft ; B 17 -196 331 722 ; C 92 ; WX 228 ; N backslash ; B 115 -19 239 737 ; C 93 ; WX 228 ; N bracketright ; B -11 -196 302 722 ; C 94 ; WX 385 ; N asciicircum ; B 35 264 442 688 ; C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ; C 96 ; WX 182 ; N quoteleft ; B 135 470 265 725 ; C 97 ; WX 456 ; N a ; B 50 -15 458 538 ; C 98 ; WX 456 ; N b ; B 48 -15 479 718 ; C 99 ; WX 410 ; N c ; B 61 -15 454 538 ; C 100 ; WX 456 ; N d ; B 69 -15 534 718 ; C 101 ; WX 456 ; N e ; B 69 -15 474 538 ; C 102 ; WX 228 ; N f ; B 71 0 341 728 ; L i fi ; L l fl ; C 103 ; WX 456 ; N g ; B 34 -220 500 538 ; C 104 ; WX 456 ; N h ; B 53 0 470 718 ; C 105 ; WX 182 ; N i ; B 55 0 252 718 ; C 106 ; WX 182 ; N j ; B -49 -210 252 718 ; C 107 ; WX 410 ; N k ; B 55 0 492 718 ; C 108 ; WX 182 ; N l ; B 55 0 252 718 ; C 109 ; WX 683 ; N m ; B 53 0 699 538 ; C 110 ; WX 456 ; N n ; B 53 0 470 538 ; C 111 ; WX 456 ; N o ; B 68 -14 479 538 ; C 112 ; WX 456 ; N p ; B 11 -207 479 538 ; C 113 ; WX 456 ; N q ; B 69 -207 496 538 ; C 114 ; WX 273 ; N r ; B 63 0 365 538 ; C 115 ; WX 410 ; N s ; B 52 -15 434 538 ; C 116 ; WX 228 ; N t ; B 84 -7 302 669 ; C 117 ; WX 456 ; N u ; B 77 -15 492 523 ; C 118 ; WX 410 ; N v ; B 98 0 495 523 ; C 119 ; WX 592 ; N w ; B 103 0 673 523 ; C 120 ; WX 410 ; N x ; B 9 0 487 523 ; C 121 ; WX 410 ; N y ; B 12 -214 492 523 ; C 122 ; WX 410 ; N z ; B 25 0 468 523 ; C 123 ; WX 274 ; N braceleft ; B 75 -196 365 722 ; C 124 ; WX 213 ; N bar ; B 74 -19 265 737 ; C 125 ; WX 274 ; N braceright ; B 0 -196 291 722 ; C 126 ; WX 479 ; N asciitilde ; B 91 180 476 326 ; C 161 ; WX 273 ; N exclamdown ; B 63 -195 267 523 ; C 162 ; WX 456 ; N cent ; B 78 -115 479 623 ; C 163 ; WX 456 ; N sterling ; B 40 -16 520 718 ; C 164 ; WX 137 ; N fraction ; B -139 -19 396 703 ; C 165 ; WX 456 ; N yen ; B 67 0 573 688 ; C 166 ; WX 456 ; N florin ; B -43 -207 537 737 ; C 167 ; WX 456 ; N section ; B 63 -191 479 737 ; C 168 ; WX 456 ; N currency ; B 49 99 530 603 ; C 169 ; WX 157 ; N quotesingle ; B 129 463 233 718 ; C 170 ; WX 273 ; N quotedblleft ; B 113 470 378 725 ; C 171 ; WX 456 ; N guillemotleft ; B 120 108 454 446 ; C 172 ; WX 273 ; N guilsinglleft ; B 112 108 279 446 ; C 173 ; WX 273 ; N guilsinglright ; B 91 108 257 446 ; C 174 ; WX 410 ; N fi ; B 71 0 481 728 ; C 175 ; WX 410 ; N fl ; B 71 0 479 728 ; C 177 ; WX 456 ; N endash ; B 42 240 510 313 ; C 178 ; WX 456 ; N dagger ; B 110 -159 510 718 ; C 179 ; WX 456 ; N daggerdbl ; B 43 -159 511 718 ; C 180 ; WX 228 ; N periodcentered ; B 106 190 211 315 ; C 182 ; WX 440 ; N paragraph ; B 103 -173 533 718 ; C 183 ; WX 287 ; N bullet ; B 74 202 339 517 ; C 184 ; WX 182 ; N quotesinglbase ; B 17 -149 147 106 ; C 185 ; WX 273 ; N quotedblbase ; B -5 -149 260 106 ; C 186 ; WX 273 ; N quotedblright ; B 102 463 367 718 ; C 187 ; WX 456 ; N guillemotright ; B 98 108 433 446 ; C 188 ; WX 820 ; N ellipsis ; B 94 0 744 106 ; C 189 ; WX 820 ; N perthousand ; B 72 -19 844 703 ; C 191 ; WX 501 ; N questiondown ; B 70 -201 438 525 ; C 193 ; WX 273 ; N grave ; B 139 593 276 734 ; C 194 ; WX 273 ; N acute ; B 203 593 390 734 ; C 195 ; WX 273 ; N circumflex ; B 121 593 359 734 ; C 196 ; WX 273 ; N tilde ; B 102 606 402 722 ; C 197 ; WX 273 ; N macron ; B 117 627 384 684 ; C 198 ; WX 273 ; N breve ; B 137 595 391 731 ; C 199 ; WX 273 ; N dotaccent ; B 204 604 297 706 ; C 200 ; WX 273 ; N dieresis ; B 138 604 363 706 ; C 202 ; WX 273 ; N ring ; B 175 572 330 756 ; C 203 ; WX 273 ; N cedilla ; B 2 -225 191 0 ; C 205 ; WX 273 ; N hungarumlaut ; B 129 593 463 734 ; C 206 ; WX 273 ; N ogonek ; B 35 -225 204 0 ; C 207 ; WX 273 ; N caron ; B 145 593 384 734 ; C 208 ; WX 820 ; N emdash ; B 42 240 875 313 ; C 225 ; WX 820 ; N AE ; B 7 0 899 718 ; C 227 ; WX 303 ; N ordfeminine ; B 82 304 368 737 ; C 232 ; WX 456 ; N Lslash ; B 34 0 455 718 ; C 233 ; WX 638 ; N Oslash ; B 35 -19 730 737 ; C 234 ; WX 820 ; N OE ; B 80 -19 915 737 ; C 235 ; WX 299 ; N ordmasculine ; B 82 304 384 737 ; C 241 ; WX 729 ; N ae ; B 50 -15 746 538 ; C 245 ; WX 228 ; N dotlessi ; B 78 0 241 523 ; C 248 ; WX 182 ; N lslash ; B 34 0 284 718 ; C 249 ; WX 501 ; N oslash ; B 24 -22 531 545 ; C 250 ; WX 774 ; N oe ; B 68 -15 791 538 ; C 251 ; WX 501 ; N germandbls ; B 55 -15 539 728 ; C -1 ; WX 501 ; N Zcaron ; B 19 0 607 929 ; C -1 ; WX 410 ; N ccedilla ; B 61 -225 454 538 ; C -1 ; WX 410 ; N ydieresis ; B 12 -214 492 706 ; C -1 ; WX 456 ; N atilde ; B 50 -15 486 722 ; C -1 ; WX 228 ; N icircumflex ; B 78 0 337 734 ; C -1 ; WX 273 ; N threesuperior ; B 74 270 358 703 ; C -1 ; WX 456 ; N ecircumflex ; B 69 -15 474 734 ; C -1 ; WX 456 ; N thorn ; B 11 -207 479 718 ; C -1 ; WX 456 ; N egrave ; B 69 -15 474 734 ; C -1 ; WX 273 ; N twosuperior ; B 52 281 368 703 ; C -1 ; WX 456 ; N eacute ; B 69 -15 481 734 ; C -1 ; WX 456 ; N otilde ; B 68 -14 494 722 ; C -1 ; WX 547 ; N Aacute ; B 11 0 560 929 ; C -1 ; WX 456 ; N ocircumflex ; B 68 -14 479 734 ; C -1 ; WX 410 ; N yacute ; B 12 -214 492 734 ; C -1 ; WX 456 ; N udieresis ; B 77 -15 492 706 ; C -1 ; WX 684 ; N threequarters ; B 106 -19 706 703 ; C -1 ; WX 456 ; N acircumflex ; B 50 -15 458 734 ; C -1 ; WX 592 ; N Eth ; B 57 0 626 718 ; C -1 ; WX 456 ; N edieresis ; B 69 -15 474 706 ; C -1 ; WX 456 ; N ugrave ; B 77 -15 492 734 ; C -1 ; WX 820 ; N trademark ; B 152 306 866 718 ; C -1 ; WX 456 ; N ograve ; B 68 -14 479 734 ; C -1 ; WX 410 ; N scaron ; B 52 -15 453 734 ; C -1 ; WX 228 ; N Idieresis ; B 75 0 375 901 ; C -1 ; WX 456 ; N uacute ; B 77 -15 492 734 ; C -1 ; WX 456 ; N agrave ; B 50 -15 458 734 ; C -1 ; WX 456 ; N ntilde ; B 53 0 486 722 ; C -1 ; WX 456 ; N aring ; B 50 -15 458 756 ; C -1 ; WX 410 ; N zcaron ; B 25 0 468 734 ; C -1 ; WX 228 ; N Icircumflex ; B 75 0 371 929 ; C -1 ; WX 592 ; N Ntilde ; B 62 0 655 917 ; C -1 ; WX 456 ; N ucircumflex ; B 77 -15 492 734 ; C -1 ; WX 547 ; N Ecircumflex ; B 71 0 625 929 ; C -1 ; WX 228 ; N Iacute ; B 75 0 401 929 ; C -1 ; WX 592 ; N Ccedilla ; B 88 -225 640 737 ; C -1 ; WX 638 ; N Odieresis ; B 86 -19 677 901 ; C -1 ; WX 547 ; N Scaron ; B 74 -19 584 929 ; C -1 ; WX 547 ; N Edieresis ; B 71 0 625 901 ; C -1 ; WX 228 ; N Igrave ; B 75 0 288 929 ; C -1 ; WX 456 ; N adieresis ; B 50 -15 458 706 ; C -1 ; WX 638 ; N Ograve ; B 86 -19 677 929 ; C -1 ; WX 547 ; N Egrave ; B 71 0 625 929 ; C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 901 ; C -1 ; WX 604 ; N registered ; B 44 -19 687 737 ; C -1 ; WX 638 ; N Otilde ; B 86 -19 677 917 ; C -1 ; WX 684 ; N onequarter ; B 123 -19 658 703 ; C -1 ; WX 592 ; N Ugrave ; B 101 -19 653 929 ; C -1 ; WX 592 ; N Ucircumflex ; B 101 -19 653 929 ; C -1 ; WX 547 ; N Thorn ; B 71 0 584 718 ; C -1 ; WX 479 ; N divide ; B 70 -19 497 524 ; C -1 ; WX 547 ; N Atilde ; B 11 0 573 917 ; C -1 ; WX 592 ; N Uacute ; B 101 -19 653 929 ; C -1 ; WX 638 ; N Ocircumflex ; B 86 -19 677 929 ; C -1 ; WX 479 ; N logicalnot ; B 87 108 515 390 ; C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ; C -1 ; WX 228 ; N idieresis ; B 78 0 341 706 ; C -1 ; WX 228 ; N iacute ; B 78 0 367 734 ; C -1 ; WX 456 ; N aacute ; B 50 -15 481 734 ; C -1 ; WX 479 ; N plusminus ; B 32 0 507 506 ; C -1 ; WX 479 ; N multiply ; B 41 0 526 506 ; C -1 ; WX 592 ; N Udieresis ; B 101 -19 653 901 ; C -1 ; WX 479 ; N minus ; B 70 216 497 289 ; C -1 ; WX 273 ; N onesuperior ; B 136 281 305 703 ; C -1 ; WX 547 ; N Eacute ; B 71 0 625 929 ; C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ; C -1 ; WX 604 ; N copyright ; B 44 -19 687 737 ; C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ; C -1 ; WX 456 ; N odieresis ; B 68 -14 479 706 ; C -1 ; WX 456 ; N oacute ; B 68 -14 481 734 ; C -1 ; WX 328 ; N degree ; B 138 411 384 703 ; C -1 ; WX 228 ; N igrave ; B 78 0 254 734 ; C -1 ; WX 456 ; N mu ; B 20 -207 492 523 ; C -1 ; WX 638 ; N Oacute ; B 86 -19 677 929 ; C -1 ; WX 456 ; N eth ; B 67 -15 506 737 ; C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ; C -1 ; WX 547 ; N Yacute ; B 137 0 661 929 ; C -1 ; WX 213 ; N brokenbar ; B 74 -19 265 737 ; C -1 ; WX 684 ; N onehalf ; B 93 -19 688 703 ; EndCharMetrics StartKernData StartKernPairs 250 KPX A y -40 KPX A w -40 KPX A v -40 KPX A u -30 KPX A Y -100 KPX A W -50 KPX A V -70 KPX A U -50 KPX A T -120 KPX A Q -30 KPX A O -30 KPX A G -30 KPX A C -30 KPX B period -20 KPX B comma -20 KPX B U -10 KPX C period -30 KPX C comma -30 KPX D period -70 KPX D comma -70 KPX D Y -90 KPX D W -40 KPX D V -70 KPX D A -40 KPX F r -45 KPX F period -150 KPX F o -30 KPX F e -30 KPX F comma -150 KPX F a -50 KPX F A -80 KPX J u -20 KPX J period -30 KPX J comma -30 KPX J a -20 KPX J A -20 KPX K y -50 KPX K u -30 KPX K o -40 KPX K e -40 KPX K O -50 KPX L y -30 KPX L quoteright -160 KPX L quotedblright -140 KPX L Y -140 KPX L W -70 KPX L V -110 KPX L T -110 KPX O period -40 KPX O comma -40 KPX O Y -70 KPX O X -60 KPX O W -30 KPX O V -50 KPX O T -40 KPX O A -20 KPX P period -180 KPX P o -50 KPX P e -50 KPX P comma -180 KPX P a -40 KPX P A -120 KPX Q U -10 KPX R Y -50 KPX R W -30 KPX R V -50 KPX R U -40 KPX R T -30 KPX R O -20 KPX S period -20 KPX S comma -20 KPX T y -120 KPX T w -120 KPX T u -120 KPX T semicolon -20 KPX T r -120 KPX T period -120 KPX T o -120 KPX T hyphen -140 KPX T e -120 KPX T comma -120 KPX T colon -20 KPX T a -120 KPX T O -40 KPX T A -120 KPX U period -40 KPX U comma -40 KPX U A -40 KPX V u -70 KPX V semicolon -40 KPX V period -125 KPX V o -80 KPX V hyphen -80 KPX V e -80 KPX V comma -125 KPX V colon -40 KPX V a -70 KPX V O -40 KPX V G -40 KPX V A -80 KPX W y -20 KPX W u -30 KPX W period -80 KPX W o -30 KPX W hyphen -40 KPX W e -30 KPX W comma -80 KPX W a -40 KPX W O -20 KPX W A -50 KPX Y u -110 KPX Y semicolon -60 KPX Y period -140 KPX Y o -140 KPX Y i -20 KPX Y hyphen -140 KPX Y e -140 KPX Y comma -140 KPX Y colon -60 KPX Y a -140 KPX Y O -85 KPX Y A -110 KPX a y -30 KPX a w -20 KPX a v -20 KPX b y -20 KPX b v -20 KPX b u -20 KPX b period -40 KPX b l -20 KPX b comma -40 KPX b b -10 KPX c k -20 KPX c comma -15 KPX colon space -50 KPX comma quoteright -100 KPX comma quotedblright -100 KPX e y -20 KPX e x -30 KPX e w -20 KPX e v -30 KPX e period -15 KPX e comma -15 KPX f quoteright 50 KPX f quotedblright 60 KPX f period -30 KPX f o -30 KPX f e -30 KPX f dotlessi -28 KPX f comma -30 KPX f a -30 KPX g r -10 KPX h y -30 KPX k o -20 KPX k e -20 KPX m y -15 KPX m u -10 KPX n y -15 KPX n v -20 KPX n u -10 KPX o y -30 KPX o x -30 KPX o w -15 KPX o v -15 KPX o period -40 KPX o comma -40 KPX oslash z -55 KPX oslash y -70 KPX oslash x -85 KPX oslash w -70 KPX oslash v -70 KPX oslash u -55 KPX oslash t -55 KPX oslash s -55 KPX oslash r -55 KPX oslash q -55 KPX oslash period -95 KPX oslash p -55 KPX oslash o -55 KPX oslash n -55 KPX oslash m -55 KPX oslash l -55 KPX oslash k -55 KPX oslash j -55 KPX oslash i -55 KPX oslash h -55 KPX oslash g -55 KPX oslash f -55 KPX oslash e -55 KPX oslash d -55 KPX oslash comma -95 KPX oslash c -55 KPX oslash b -55 KPX oslash a -55 KPX p y -30 KPX p period -35 KPX p comma -35 KPX period space -60 KPX period quoteright -100 KPX period quotedblright -100 KPX quotedblright space -40 KPX quoteleft quoteleft -57 KPX quoteright space -70 KPX quoteright s -50 KPX quoteright r -50 KPX quoteright quoteright -57 KPX quoteright d -50 KPX r y 30 KPX r v 30 KPX r u 15 KPX r t 40 KPX r semicolon 30 KPX r period -50 KPX r p 30 KPX r n 25 KPX r m 25 KPX r l 15 KPX r k 15 KPX r i 15 KPX r comma -50 KPX r colon 30 KPX r a -10 KPX s w -30 KPX s period -15 KPX s comma -15 KPX semicolon space -50 KPX space quoteleft -60 KPX space quotedblleft -30 KPX space Y -90 KPX space W -40 KPX space V -50 KPX space T -50 KPX v period -80 KPX v o -25 KPX v e -25 KPX v comma -80 KPX v a -25 KPX w period -60 KPX w o -10 KPX w e -10 KPX w comma -60 KPX w a -15 KPX x e -30 KPX y period -100 KPX y o -20 KPX y e -20 KPX y comma -100 KPX y a -20 KPX z o -15 KPX z e -15 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 171 195 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 171 195 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 171 195 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 171 195 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 171 195 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 171 195 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 171 195 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 171 195 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 171 195 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 12 195 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 12 195 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 12 195 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 12 195 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 202 195 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 217 195 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 217 195 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 217 195 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 217 195 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 217 195 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 171 195 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 195 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 195 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 195 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 195 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 171 195 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 171 195 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 148 195 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Bookman-LightItalic.afm�����������������������������������������������0000644�0001750�0001750�00000036350�11462120062�020722� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Jan 21 16:12:06 1992 Comment UniqueID 37830 Comment VMusage 33139 40031 FontName Bookman-LightItalic FullName ITC Bookman Light Italic FamilyName ITC Bookman Weight Light ItalicAngle -10 IsFixedPitch false FontBBox -228 -250 1269 883 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 494 Ascender 717 Descender -212 StartCharMetrics 228 C 32 ; WX 300 ; N space ; B 0 0 0 0 ; C 33 ; WX 320 ; N exclam ; B 103 -8 342 698 ; C 34 ; WX 360 ; N quotedbl ; B 107 468 402 698 ; C 35 ; WX 620 ; N numbersign ; B 107 0 598 681 ; C 36 ; WX 620 ; N dollar ; B 78 -85 619 762 ; C 37 ; WX 800 ; N percent ; B 56 -8 811 691 ; C 38 ; WX 820 ; N ampersand ; B 65 -18 848 698 ; C 39 ; WX 280 ; N quoteright ; B 148 470 288 698 ; C 40 ; WX 280 ; N parenleft ; B 96 -146 383 727 ; C 41 ; WX 280 ; N parenright ; B -8 -146 279 727 ; C 42 ; WX 440 ; N asterisk ; B 139 324 505 698 ; C 43 ; WX 600 ; N plus ; B 91 43 595 548 ; C 44 ; WX 300 ; N comma ; B 88 -115 227 112 ; C 45 ; WX 320 ; N hyphen ; B 78 269 336 325 ; C 46 ; WX 300 ; N period ; B 96 -8 231 127 ; C 47 ; WX 600 ; N slash ; B 104 -149 562 717 ; C 48 ; WX 620 ; N zero ; B 86 -17 646 698 ; C 49 ; WX 620 ; N one ; B 154 0 500 681 ; C 50 ; WX 620 ; N two ; B 66 0 636 698 ; C 51 ; WX 620 ; N three ; B 55 -17 622 698 ; C 52 ; WX 620 ; N four ; B 69 0 634 681 ; C 53 ; WX 620 ; N five ; B 70 -17 614 681 ; C 54 ; WX 620 ; N six ; B 89 -17 657 698 ; C 55 ; WX 620 ; N seven ; B 143 0 672 681 ; C 56 ; WX 620 ; N eight ; B 61 -17 655 698 ; C 57 ; WX 620 ; N nine ; B 77 -17 649 698 ; C 58 ; WX 300 ; N colon ; B 96 -8 292 494 ; C 59 ; WX 300 ; N semicolon ; B 88 -114 292 494 ; C 60 ; WX 600 ; N less ; B 79 33 588 561 ; C 61 ; WX 600 ; N equal ; B 91 161 595 433 ; C 62 ; WX 600 ; N greater ; B 93 33 602 561 ; C 63 ; WX 540 ; N question ; B 114 -8 604 698 ; C 64 ; WX 780 ; N at ; B 102 -17 802 698 ; C 65 ; WX 700 ; N A ; B -25 0 720 681 ; C 66 ; WX 720 ; N B ; B 21 0 746 681 ; C 67 ; WX 720 ; N C ; B 88 -17 746 698 ; C 68 ; WX 740 ; N D ; B 21 0 782 681 ; C 69 ; WX 680 ; N E ; B 21 0 736 681 ; C 70 ; WX 620 ; N F ; B 21 0 743 681 ; C 71 ; WX 760 ; N G ; B 88 -17 813 698 ; C 72 ; WX 800 ; N H ; B 21 0 888 681 ; C 73 ; WX 320 ; N I ; B 21 0 412 681 ; C 74 ; WX 560 ; N J ; B -2 -17 666 681 ; C 75 ; WX 720 ; N K ; B 21 0 804 681 ; C 76 ; WX 580 ; N L ; B 21 0 656 681 ; C 77 ; WX 860 ; N M ; B 18 0 956 681 ; C 78 ; WX 720 ; N N ; B 18 0 823 681 ; C 79 ; WX 760 ; N O ; B 88 -17 799 698 ; C 80 ; WX 600 ; N P ; B 21 0 681 681 ; C 81 ; WX 780 ; N Q ; B 61 -191 812 698 ; C 82 ; WX 700 ; N R ; B 21 0 736 681 ; C 83 ; WX 640 ; N S ; B 61 -17 668 698 ; C 84 ; WX 600 ; N T ; B 50 0 725 681 ; C 85 ; WX 720 ; N U ; B 118 -17 842 681 ; C 86 ; WX 680 ; N V ; B 87 0 815 681 ; C 87 ; WX 960 ; N W ; B 87 0 1095 681 ; C 88 ; WX 700 ; N X ; B -25 0 815 681 ; C 89 ; WX 660 ; N Y ; B 87 0 809 681 ; C 90 ; WX 580 ; N Z ; B 8 0 695 681 ; C 91 ; WX 260 ; N bracketleft ; B 56 -136 351 717 ; C 92 ; WX 600 ; N backslash ; B 84 0 542 717 ; C 93 ; WX 260 ; N bracketright ; B 15 -136 309 717 ; C 94 ; WX 600 ; N asciicircum ; B 97 276 599 681 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 280 ; N quoteleft ; B 191 470 330 698 ; C 97 ; WX 620 ; N a ; B 71 -8 686 494 ; C 98 ; WX 600 ; N b ; B 88 -8 621 717 ; C 99 ; WX 480 ; N c ; B 65 -8 522 494 ; C 100 ; WX 640 ; N d ; B 65 -8 695 717 ; C 101 ; WX 540 ; N e ; B 65 -8 575 494 ; C 102 ; WX 340 ; N f ; B -160 -218 557 725 ; L i fi ; L l fl ; C 103 ; WX 560 ; N g ; B 4 -221 581 494 ; C 104 ; WX 620 ; N h ; B 88 -8 689 717 ; C 105 ; WX 280 ; N i ; B 88 -8 351 663 ; C 106 ; WX 280 ; N j ; B -200 -221 308 663 ; C 107 ; WX 600 ; N k ; B 88 -8 657 717 ; C 108 ; WX 280 ; N l ; B 100 -8 342 717 ; C 109 ; WX 880 ; N m ; B 88 -8 952 494 ; C 110 ; WX 620 ; N n ; B 88 -8 673 494 ; C 111 ; WX 540 ; N o ; B 65 -8 572 494 ; C 112 ; WX 600 ; N p ; B -24 -212 620 494 ; C 113 ; WX 560 ; N q ; B 65 -212 584 494 ; C 114 ; WX 400 ; N r ; B 88 0 481 494 ; C 115 ; WX 540 ; N s ; B 65 -8 547 494 ; C 116 ; WX 340 ; N t ; B 88 -8 411 664 ; C 117 ; WX 620 ; N u ; B 88 -8 686 484 ; C 118 ; WX 540 ; N v ; B 88 -8 562 494 ; C 119 ; WX 880 ; N w ; B 88 -8 893 494 ; C 120 ; WX 540 ; N x ; B 9 -8 626 494 ; C 121 ; WX 600 ; N y ; B 60 -221 609 484 ; C 122 ; WX 520 ; N z ; B 38 -8 561 494 ; C 123 ; WX 360 ; N braceleft ; B 122 -191 442 717 ; C 124 ; WX 600 ; N bar ; B 294 -250 372 750 ; C 125 ; WX 380 ; N braceright ; B 13 -191 333 717 ; C 126 ; WX 600 ; N asciitilde ; B 91 207 595 386 ; C 161 ; WX 320 ; N exclamdown ; B 73 -213 301 494 ; C 162 ; WX 620 ; N cent ; B 148 -29 596 715 ; C 163 ; WX 620 ; N sterling ; B 4 -17 702 698 ; C 164 ; WX 20 ; N fraction ; B -228 0 323 681 ; C 165 ; WX 620 ; N yen ; B 71 0 735 681 ; C 166 ; WX 620 ; N florin ; B -26 -218 692 725 ; C 167 ; WX 620 ; N section ; B 38 -178 638 698 ; C 168 ; WX 620 ; N currency ; B 100 89 605 591 ; C 169 ; WX 200 ; N quotesingle ; B 99 473 247 698 ; C 170 ; WX 440 ; N quotedblleft ; B 191 470 493 698 ; C 171 ; WX 300 ; N guillemotleft ; B 70 129 313 434 ; C 172 ; WX 180 ; N guilsinglleft ; B 75 129 208 434 ; C 173 ; WX 180 ; N guilsinglright ; B 70 129 203 434 ; C 174 ; WX 640 ; N fi ; B -159 -222 709 725 ; C 175 ; WX 660 ; N fl ; B -159 -218 713 725 ; C 177 ; WX 500 ; N endash ; B 33 269 561 325 ; C 178 ; WX 620 ; N dagger ; B 192 -130 570 698 ; C 179 ; WX 620 ; N daggerdbl ; B 144 -122 566 698 ; C 180 ; WX 300 ; N periodcentered ; B 137 229 272 364 ; C 182 ; WX 620 ; N paragraph ; B 112 0 718 681 ; C 183 ; WX 460 ; N bullet ; B 100 170 444 511 ; C 184 ; WX 320 ; N quotesinglbase ; B 87 -114 226 113 ; C 185 ; WX 480 ; N quotedblbase ; B 87 -114 390 113 ; C 186 ; WX 440 ; N quotedblright ; B 148 470 451 698 ; C 187 ; WX 300 ; N guillemotright ; B 60 129 303 434 ; C 188 ; WX 1000 ; N ellipsis ; B 99 -8 900 127 ; C 189 ; WX 1180 ; N perthousand ; B 56 -8 1199 691 ; C 191 ; WX 540 ; N questiondown ; B 18 -212 508 494 ; C 193 ; WX 340 ; N grave ; B 182 551 377 706 ; C 194 ; WX 320 ; N acute ; B 178 551 373 706 ; C 195 ; WX 440 ; N circumflex ; B 176 571 479 685 ; C 196 ; WX 440 ; N tilde ; B 180 586 488 671 ; C 197 ; WX 440 ; N macron ; B 178 599 484 658 ; C 198 ; WX 440 ; N breve ; B 191 577 500 680 ; C 199 ; WX 260 ; N dotaccent ; B 169 543 290 664 ; C 200 ; WX 420 ; N dieresis ; B 185 569 467 688 ; C 202 ; WX 300 ; N ring ; B 178 551 334 706 ; C 203 ; WX 320 ; N cedilla ; B 45 -178 240 0 ; C 205 ; WX 340 ; N hungarumlaut ; B 167 547 402 738 ; C 206 ; WX 260 ; N ogonek ; B 51 -173 184 0 ; C 207 ; WX 440 ; N caron ; B 178 571 481 684 ; C 208 ; WX 1000 ; N emdash ; B 33 269 1061 325 ; C 225 ; WX 1220 ; N AE ; B -45 0 1269 681 ; C 227 ; WX 440 ; N ordfeminine ; B 130 396 513 698 ; C 232 ; WX 580 ; N Lslash ; B 21 0 656 681 ; C 233 ; WX 760 ; N Oslash ; B 88 -95 799 777 ; C 234 ; WX 1180 ; N OE ; B 88 -17 1237 698 ; C 235 ; WX 400 ; N ordmasculine ; B 139 396 455 698 ; C 241 ; WX 880 ; N ae ; B 71 -8 918 494 ; C 245 ; WX 280 ; N dotlessi ; B 88 -8 351 484 ; C 248 ; WX 340 ; N lslash ; B 50 -8 398 717 ; C 249 ; WX 540 ; N oslash ; B 65 -49 571 532 ; C 250 ; WX 900 ; N oe ; B 65 -8 948 494 ; C 251 ; WX 620 ; N germandbls ; B -121 -111 653 698 ; C -1 ; WX 540 ; N ecircumflex ; B 65 -8 575 685 ; C -1 ; WX 540 ; N edieresis ; B 65 -8 575 688 ; C -1 ; WX 620 ; N aacute ; B 71 -8 686 706 ; C -1 ; WX 740 ; N registered ; B 84 -17 784 698 ; C -1 ; WX 280 ; N icircumflex ; B 76 -8 379 685 ; C -1 ; WX 620 ; N udieresis ; B 88 -8 686 688 ; C -1 ; WX 540 ; N ograve ; B 65 -8 572 706 ; C -1 ; WX 620 ; N uacute ; B 88 -8 686 706 ; C -1 ; WX 620 ; N ucircumflex ; B 88 -8 686 685 ; C -1 ; WX 700 ; N Aacute ; B -25 0 720 883 ; C -1 ; WX 280 ; N igrave ; B 88 -8 351 706 ; C -1 ; WX 320 ; N Icircumflex ; B 21 0 449 862 ; C -1 ; WX 480 ; N ccedilla ; B 65 -178 522 494 ; C -1 ; WX 620 ; N adieresis ; B 71 -8 686 688 ; C -1 ; WX 680 ; N Ecircumflex ; B 21 0 736 862 ; C -1 ; WX 540 ; N scaron ; B 65 -8 547 684 ; C -1 ; WX 600 ; N thorn ; B -24 -212 620 717 ; C -1 ; WX 980 ; N trademark ; B 69 277 965 681 ; C -1 ; WX 540 ; N egrave ; B 65 -8 575 706 ; C -1 ; WX 372 ; N threesuperior ; B 70 269 439 698 ; C -1 ; WX 520 ; N zcaron ; B 38 -8 561 684 ; C -1 ; WX 620 ; N atilde ; B 71 -8 686 671 ; C -1 ; WX 620 ; N aring ; B 71 -8 686 706 ; C -1 ; WX 540 ; N ocircumflex ; B 65 -8 572 685 ; C -1 ; WX 680 ; N Edieresis ; B 21 0 736 865 ; C -1 ; WX 930 ; N threequarters ; B 99 0 913 691 ; C -1 ; WX 600 ; N ydieresis ; B 60 -221 609 688 ; C -1 ; WX 600 ; N yacute ; B 60 -221 609 706 ; C -1 ; WX 280 ; N iacute ; B 88 -8 351 706 ; C -1 ; WX 700 ; N Acircumflex ; B -25 0 720 862 ; C -1 ; WX 720 ; N Uacute ; B 118 -17 842 883 ; C -1 ; WX 540 ; N eacute ; B 65 -8 575 706 ; C -1 ; WX 760 ; N Ograve ; B 88 -17 799 883 ; C -1 ; WX 620 ; N agrave ; B 71 -8 686 706 ; C -1 ; WX 720 ; N Udieresis ; B 118 -17 842 865 ; C -1 ; WX 620 ; N acircumflex ; B 71 -8 686 685 ; C -1 ; WX 320 ; N Igrave ; B 21 0 412 883 ; C -1 ; WX 372 ; N twosuperior ; B 68 279 439 698 ; C -1 ; WX 720 ; N Ugrave ; B 118 -17 842 883 ; C -1 ; WX 930 ; N onequarter ; B 91 0 913 681 ; C -1 ; WX 720 ; N Ucircumflex ; B 118 -17 842 862 ; C -1 ; WX 640 ; N Scaron ; B 61 -17 668 861 ; C -1 ; WX 320 ; N Idieresis ; B 21 0 447 865 ; C -1 ; WX 280 ; N idieresis ; B 88 -8 377 688 ; C -1 ; WX 680 ; N Egrave ; B 21 0 736 883 ; C -1 ; WX 760 ; N Oacute ; B 88 -17 799 883 ; C -1 ; WX 600 ; N divide ; B 91 46 595 548 ; C -1 ; WX 700 ; N Atilde ; B -25 0 720 848 ; C -1 ; WX 700 ; N Aring ; B -25 0 720 883 ; C -1 ; WX 760 ; N Odieresis ; B 88 -17 799 865 ; C -1 ; WX 700 ; N Adieresis ; B -25 0 720 865 ; C -1 ; WX 720 ; N Ntilde ; B 18 0 823 848 ; C -1 ; WX 580 ; N Zcaron ; B 8 0 695 861 ; C -1 ; WX 600 ; N Thorn ; B 21 0 656 681 ; C -1 ; WX 320 ; N Iacute ; B 21 0 412 883 ; C -1 ; WX 600 ; N plusminus ; B 91 0 595 548 ; C -1 ; WX 600 ; N multiply ; B 91 44 595 548 ; C -1 ; WX 680 ; N Eacute ; B 21 0 736 883 ; C -1 ; WX 660 ; N Ydieresis ; B 87 0 809 865 ; C -1 ; WX 372 ; N onesuperior ; B 114 279 339 688 ; C -1 ; WX 620 ; N ugrave ; B 88 -8 686 706 ; C -1 ; WX 600 ; N logicalnot ; B 91 163 595 433 ; C -1 ; WX 620 ; N ntilde ; B 88 -8 673 671 ; C -1 ; WX 760 ; N Otilde ; B 88 -17 799 848 ; C -1 ; WX 540 ; N otilde ; B 65 -8 572 671 ; C -1 ; WX 720 ; N Ccedilla ; B 88 -178 746 698 ; C -1 ; WX 700 ; N Agrave ; B -25 0 720 883 ; C -1 ; WX 930 ; N onehalf ; B 91 0 925 681 ; C -1 ; WX 740 ; N Eth ; B 21 0 782 681 ; C -1 ; WX 400 ; N degree ; B 120 398 420 698 ; C -1 ; WX 660 ; N Yacute ; B 87 0 809 883 ; C -1 ; WX 760 ; N Ocircumflex ; B 88 -17 799 862 ; C -1 ; WX 540 ; N oacute ; B 65 -8 572 706 ; C -1 ; WX 620 ; N mu ; B 53 -221 686 484 ; C -1 ; WX 600 ; N minus ; B 91 259 595 335 ; C -1 ; WX 540 ; N eth ; B 65 -8 642 725 ; C -1 ; WX 540 ; N odieresis ; B 65 -8 572 688 ; C -1 ; WX 740 ; N copyright ; B 84 -17 784 698 ; C -1 ; WX 600 ; N brokenbar ; B 294 -175 372 675 ; EndCharMetrics StartKernData StartKernPairs 85 KPX A Y -62 KPX A W -73 KPX A V -78 KPX A T -5 KPX F period -97 KPX F comma -98 KPX F A -16 KPX L y 20 KPX L Y 7 KPX L W 9 KPX L V 4 KPX P period -105 KPX P comma -106 KPX P A -30 KPX R Y 11 KPX R W 2 KPX R V 2 KPX R T 65 KPX T semicolon 48 KPX T s -7 KPX T r 67 KPX T period -78 KPX T o 14 KPX T i 71 KPX T hyphen 20 KPX T e 10 KPX T comma -79 KPX T colon 48 KPX T c 16 KPX T a 9 KPX T A -14 KPX V y -14 KPX V u -10 KPX V semicolon -44 KPX V r -20 KPX V period -100 KPX V o -70 KPX V i 3 KPX V hyphen 20 KPX V e -70 KPX V comma -109 KPX V colon -35 KPX V a -70 KPX V A -70 KPX W y -14 KPX W u -20 KPX W semicolon -42 KPX W r -30 KPX W period -100 KPX W o -60 KPX W i 3 KPX W hyphen 20 KPX W e -60 KPX W comma -109 KPX W colon -35 KPX W a -60 KPX W A -60 KPX Y v -19 KPX Y u -31 KPX Y semicolon -40 KPX Y q -72 KPX Y period -100 KPX Y p -37 KPX Y o -75 KPX Y i -11 KPX Y hyphen 20 KPX Y e -78 KPX Y comma -109 KPX Y colon -35 KPX Y a -79 KPX Y A -82 KPX f f -19 KPX r q -14 KPX r period -134 KPX r o -10 KPX r n 38 KPX r m 37 KPX r hyphen 20 KPX r h -20 KPX r g -3 KPX r f -9 KPX r e -15 KPX r d -9 KPX r comma -143 KPX r c -8 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 140 177 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 177 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 220 177 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 177 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 210 177 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 140 177 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 150 177 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 30 177 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 177 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -20 177 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -30 177 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 177 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 177 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 200 177 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 177 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 190 177 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 100 177 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 230 177 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 170 177 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 177 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 200 177 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 140 177 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 177 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 70 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 110 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 140 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 60 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 30 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 80 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -40 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -100 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -60 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 80 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 20 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 80 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 30 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 120 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 60 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 70 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 110 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 140 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 70 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 20 0 ; EndComposites EndFontMetrics ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/AvantGarde-Book.afm���������������������������������������������������0000644�0001750�0001750�00000042627�11462120062�020051� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Mar 4 13:37:31 1991 Comment UniqueID 34364 Comment VMusage 24225 31117 FontName AvantGarde-Book FullName ITC Avant Garde Gothic Book FamilyName ITC Avant Garde Gothic Weight Book ItalicAngle 0 IsFixedPitch false FontBBox -113 -222 1148 955 UnderlinePosition -100 UnderlineThickness 50 Version 001.006 Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 740 XHeight 547 Ascender 740 Descender -192 StartCharMetrics 228 C 32 ; WX 277 ; N space ; B 0 0 0 0 ; C 33 ; WX 295 ; N exclam ; B 111 0 185 740 ; C 34 ; WX 309 ; N quotedbl ; B 36 444 273 740 ; C 35 ; WX 554 ; N numbersign ; B 33 0 521 740 ; C 36 ; WX 554 ; N dollar ; B 70 -70 485 811 ; C 37 ; WX 775 ; N percent ; B 21 -13 753 751 ; C 38 ; WX 757 ; N ampersand ; B 56 -12 736 753 ; C 39 ; WX 351 ; N quoteright ; B 94 546 256 740 ; C 40 ; WX 369 ; N parenleft ; B 47 -205 355 757 ; C 41 ; WX 369 ; N parenright ; B 14 -205 322 757 ; C 42 ; WX 425 ; N asterisk ; B 58 446 367 740 ; C 43 ; WX 606 ; N plus ; B 51 0 555 506 ; C 44 ; WX 277 ; N comma ; B 14 -67 176 126 ; C 45 ; WX 332 ; N hyphen ; B 30 248 302 315 ; C 46 ; WX 277 ; N period ; B 102 0 176 126 ; C 47 ; WX 437 ; N slash ; B 44 -100 403 740 ; C 48 ; WX 554 ; N zero ; B 29 -13 525 753 ; C 49 ; WX 554 ; N one ; B 135 0 336 740 ; C 50 ; WX 554 ; N two ; B 40 0 514 753 ; C 51 ; WX 554 ; N three ; B 34 -13 506 753 ; C 52 ; WX 554 ; N four ; B 14 0 528 740 ; C 53 ; WX 554 ; N five ; B 26 -13 530 740 ; C 54 ; WX 554 ; N six ; B 24 -13 530 739 ; C 55 ; WX 554 ; N seven ; B 63 0 491 740 ; C 56 ; WX 554 ; N eight ; B 41 -13 513 753 ; C 57 ; WX 554 ; N nine ; B 24 0 530 752 ; C 58 ; WX 277 ; N colon ; B 102 0 176 548 ; C 59 ; WX 277 ; N semicolon ; B 14 -67 176 548 ; C 60 ; WX 606 ; N less ; B 46 -8 554 514 ; C 61 ; WX 606 ; N equal ; B 51 118 555 388 ; C 62 ; WX 606 ; N greater ; B 52 -8 560 514 ; C 63 ; WX 591 ; N question ; B 64 0 526 752 ; C 64 ; WX 867 ; N at ; B 65 -13 803 753 ; C 65 ; WX 740 ; N A ; B 12 0 729 740 ; C 66 ; WX 574 ; N B ; B 74 0 544 740 ; C 67 ; WX 813 ; N C ; B 43 -13 771 752 ; C 68 ; WX 744 ; N D ; B 74 0 699 740 ; C 69 ; WX 536 ; N E ; B 70 0 475 740 ; C 70 ; WX 485 ; N F ; B 70 0 444 740 ; C 71 ; WX 872 ; N G ; B 40 -13 828 753 ; C 72 ; WX 683 ; N H ; B 76 0 607 740 ; C 73 ; WX 226 ; N I ; B 76 0 150 740 ; C 74 ; WX 482 ; N J ; B 6 -13 402 740 ; C 75 ; WX 591 ; N K ; B 81 0 591 740 ; C 76 ; WX 462 ; N L ; B 82 0 462 740 ; C 77 ; WX 919 ; N M ; B 76 0 843 740 ; C 78 ; WX 740 ; N N ; B 75 0 664 740 ; C 79 ; WX 869 ; N O ; B 43 -13 826 753 ; C 80 ; WX 592 ; N P ; B 75 0 564 740 ; C 81 ; WX 871 ; N Q ; B 40 -13 837 753 ; C 82 ; WX 607 ; N R ; B 70 0 572 740 ; C 83 ; WX 498 ; N S ; B 22 -13 473 753 ; C 84 ; WX 426 ; N T ; B 6 0 419 740 ; C 85 ; WX 655 ; N U ; B 75 -13 579 740 ; C 86 ; WX 702 ; N V ; B 8 0 693 740 ; C 87 ; WX 960 ; N W ; B 11 0 950 740 ; C 88 ; WX 609 ; N X ; B 8 0 602 740 ; C 89 ; WX 592 ; N Y ; B 1 0 592 740 ; C 90 ; WX 480 ; N Z ; B 12 0 470 740 ; C 91 ; WX 351 ; N bracketleft ; B 133 -179 337 753 ; C 92 ; WX 605 ; N backslash ; B 118 -100 477 740 ; C 93 ; WX 351 ; N bracketright ; B 14 -179 218 753 ; C 94 ; WX 606 ; N asciicircum ; B 53 307 553 740 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 351 ; N quoteleft ; B 95 546 257 740 ; C 97 ; WX 683 ; N a ; B 42 -13 621 561 ; C 98 ; WX 682 ; N b ; B 68 -13 647 740 ; C 99 ; WX 647 ; N c ; B 41 -13 607 561 ; C 100 ; WX 685 ; N d ; B 39 -13 618 740 ; C 101 ; WX 650 ; N e ; B 38 -13 608 561 ; C 102 ; WX 314 ; N f ; B 19 0 314 753 ; L i fi ; L l fl ; C 103 ; WX 673 ; N g ; B 37 -215 606 561 ; C 104 ; WX 610 ; N h ; B 62 0 543 740 ; C 105 ; WX 200 ; N i ; B 65 0 135 740 ; C 106 ; WX 203 ; N j ; B -44 -192 137 740 ; C 107 ; WX 502 ; N k ; B 70 0 498 740 ; C 108 ; WX 200 ; N l ; B 65 0 135 740 ; C 109 ; WX 938 ; N m ; B 66 0 872 561 ; C 110 ; WX 610 ; N n ; B 65 0 546 561 ; C 111 ; WX 655 ; N o ; B 42 -13 614 561 ; C 112 ; WX 682 ; N p ; B 64 -192 643 561 ; C 113 ; WX 682 ; N q ; B 37 -192 616 561 ; C 114 ; WX 301 ; N r ; B 65 0 291 561 ; C 115 ; WX 388 ; N s ; B 24 -13 364 561 ; C 116 ; WX 339 ; N t ; B 14 0 330 740 ; C 117 ; WX 608 ; N u ; B 62 -13 541 547 ; C 118 ; WX 554 ; N v ; B 7 0 546 547 ; C 119 ; WX 831 ; N w ; B 13 0 820 547 ; C 120 ; WX 480 ; N x ; B 12 0 468 547 ; C 121 ; WX 536 ; N y ; B 15 -192 523 547 ; C 122 ; WX 425 ; N z ; B 10 0 415 547 ; C 123 ; WX 351 ; N braceleft ; B 70 -189 331 740 ; C 124 ; WX 672 ; N bar ; B 299 -100 373 740 ; C 125 ; WX 351 ; N braceright ; B 20 -189 281 740 ; C 126 ; WX 606 ; N asciitilde ; B 72 179 534 319 ; C 161 ; WX 295 ; N exclamdown ; B 110 -192 184 548 ; C 162 ; WX 554 ; N cent ; B 48 62 510 707 ; C 163 ; WX 554 ; N sterling ; B 4 0 552 753 ; C 164 ; WX 166 ; N fraction ; B -113 0 280 740 ; C 165 ; WX 554 ; N yen ; B 4 0 550 740 ; C 166 ; WX 554 ; N florin ; B -12 -153 518 818 ; C 167 ; WX 615 ; N section ; B 85 -141 529 753 ; C 168 ; WX 554 ; N currency ; B 8 42 546 580 ; C 169 ; WX 198 ; N quotesingle ; B 59 444 140 740 ; C 170 ; WX 502 ; N quotedblleft ; B 97 546 406 740 ; C 171 ; WX 425 ; N guillemotleft ; B 40 81 386 481 ; C 172 ; WX 251 ; N guilsinglleft ; B 40 81 212 481 ; C 173 ; WX 251 ; N guilsinglright ; B 39 81 211 481 ; C 174 ; WX 487 ; N fi ; B 19 0 422 753 ; C 175 ; WX 485 ; N fl ; B 19 0 420 753 ; C 177 ; WX 500 ; N endash ; B 35 248 465 315 ; C 178 ; WX 553 ; N dagger ; B 59 -133 493 740 ; C 179 ; WX 553 ; N daggerdbl ; B 59 -133 493 740 ; C 180 ; WX 277 ; N periodcentered ; B 102 190 176 316 ; C 182 ; WX 564 ; N paragraph ; B 22 -110 551 740 ; C 183 ; WX 606 ; N bullet ; B 150 222 455 532 ; C 184 ; WX 354 ; N quotesinglbase ; B 89 -68 251 126 ; C 185 ; WX 502 ; N quotedblbase ; B 89 -68 399 126 ; C 186 ; WX 484 ; N quotedblright ; B 96 546 405 740 ; C 187 ; WX 425 ; N guillemotright ; B 39 81 385 481 ; C 188 ; WX 1000 ; N ellipsis ; B 130 0 870 126 ; C 189 ; WX 1174 ; N perthousand ; B 25 -13 1148 751 ; C 191 ; WX 591 ; N questiondown ; B 65 -205 527 548 ; C 193 ; WX 378 ; N grave ; B 69 619 300 786 ; C 194 ; WX 375 ; N acute ; B 78 619 309 786 ; C 195 ; WX 502 ; N circumflex ; B 74 639 428 764 ; C 196 ; WX 439 ; N tilde ; B 47 651 392 754 ; C 197 ; WX 485 ; N macron ; B 73 669 411 736 ; C 198 ; WX 453 ; N breve ; B 52 651 401 754 ; C 199 ; WX 222 ; N dotaccent ; B 74 639 148 765 ; C 200 ; WX 369 ; N dieresis ; B 73 639 295 765 ; C 202 ; WX 332 ; N ring ; B 62 600 269 807 ; C 203 ; WX 324 ; N cedilla ; B 80 -222 254 0 ; C 205 ; WX 552 ; N hungarumlaut ; B 119 605 453 800 ; C 206 ; WX 302 ; N ogonek ; B 73 -191 228 0 ; C 207 ; WX 502 ; N caron ; B 68 639 423 764 ; C 208 ; WX 1000 ; N emdash ; B 35 248 965 315 ; C 225 ; WX 992 ; N AE ; B -20 0 907 740 ; C 227 ; WX 369 ; N ordfeminine ; B -3 407 356 753 ; C 232 ; WX 517 ; N Lslash ; B 59 0 517 740 ; C 233 ; WX 868 ; N Oslash ; B 43 -83 826 819 ; C 234 ; WX 1194 ; N OE ; B 45 -13 1142 753 ; C 235 ; WX 369 ; N ordmasculine ; B 12 407 356 753 ; C 241 ; WX 1157 ; N ae ; B 34 -13 1113 561 ; C 245 ; WX 200 ; N dotlessi ; B 65 0 135 547 ; C 248 ; WX 300 ; N lslash ; B 43 0 259 740 ; C 249 ; WX 653 ; N oslash ; B 41 -64 613 614 ; C 250 ; WX 1137 ; N oe ; B 34 -13 1104 561 ; C 251 ; WX 554 ; N germandbls ; B 61 -13 525 753 ; C -1 ; WX 650 ; N ecircumflex ; B 38 -13 608 764 ; C -1 ; WX 650 ; N edieresis ; B 38 -13 608 765 ; C -1 ; WX 683 ; N aacute ; B 42 -13 621 786 ; C -1 ; WX 747 ; N registered ; B -9 -12 755 752 ; C -1 ; WX 200 ; N icircumflex ; B -77 0 277 764 ; C -1 ; WX 608 ; N udieresis ; B 62 -13 541 765 ; C -1 ; WX 655 ; N ograve ; B 42 -13 614 786 ; C -1 ; WX 608 ; N uacute ; B 62 -13 541 786 ; C -1 ; WX 608 ; N ucircumflex ; B 62 -13 541 764 ; C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ; C -1 ; WX 200 ; N igrave ; B -60 0 171 786 ; C -1 ; WX 226 ; N Icircumflex ; B -64 0 290 927 ; C -1 ; WX 647 ; N ccedilla ; B 41 -222 607 561 ; C -1 ; WX 683 ; N adieresis ; B 42 -13 621 765 ; C -1 ; WX 536 ; N Ecircumflex ; B 70 0 475 927 ; C -1 ; WX 388 ; N scaron ; B 11 -13 366 764 ; C -1 ; WX 682 ; N thorn ; B 64 -192 643 740 ; C -1 ; WX 1000 ; N trademark ; B 9 296 816 740 ; C -1 ; WX 650 ; N egrave ; B 38 -13 608 786 ; C -1 ; WX 332 ; N threesuperior ; B 18 289 318 747 ; C -1 ; WX 425 ; N zcaron ; B 10 0 415 764 ; C -1 ; WX 683 ; N atilde ; B 42 -13 621 754 ; C -1 ; WX 683 ; N aring ; B 42 -13 621 807 ; C -1 ; WX 655 ; N ocircumflex ; B 42 -13 614 764 ; C -1 ; WX 536 ; N Edieresis ; B 70 0 475 928 ; C -1 ; WX 831 ; N threequarters ; B 46 0 784 747 ; C -1 ; WX 536 ; N ydieresis ; B 15 -192 523 765 ; C -1 ; WX 536 ; N yacute ; B 15 -192 523 786 ; C -1 ; WX 200 ; N iacute ; B 31 0 262 786 ; C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ; C -1 ; WX 655 ; N Uacute ; B 75 -13 579 949 ; C -1 ; WX 650 ; N eacute ; B 38 -13 608 786 ; C -1 ; WX 869 ; N Ograve ; B 43 -13 826 949 ; C -1 ; WX 683 ; N agrave ; B 42 -13 621 786 ; C -1 ; WX 655 ; N Udieresis ; B 75 -13 579 928 ; C -1 ; WX 683 ; N acircumflex ; B 42 -13 621 764 ; C -1 ; WX 226 ; N Igrave ; B -47 0 184 949 ; C -1 ; WX 332 ; N twosuperior ; B 19 296 318 747 ; C -1 ; WX 655 ; N Ugrave ; B 75 -13 579 949 ; C -1 ; WX 831 ; N onequarter ; B 100 0 729 740 ; C -1 ; WX 655 ; N Ucircumflex ; B 75 -13 579 927 ; C -1 ; WX 498 ; N Scaron ; B 22 -13 473 927 ; C -1 ; WX 226 ; N Idieresis ; B 2 0 224 928 ; C -1 ; WX 200 ; N idieresis ; B -11 0 211 765 ; C -1 ; WX 536 ; N Egrave ; B 70 0 475 949 ; C -1 ; WX 869 ; N Oacute ; B 43 -13 826 949 ; C -1 ; WX 606 ; N divide ; B 51 -13 555 519 ; C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ; C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ; C -1 ; WX 869 ; N Odieresis ; B 43 -13 826 928 ; C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ; C -1 ; WX 740 ; N Ntilde ; B 75 0 664 917 ; C -1 ; WX 480 ; N Zcaron ; B 12 0 470 927 ; C -1 ; WX 592 ; N Thorn ; B 60 0 549 740 ; C -1 ; WX 226 ; N Iacute ; B 44 0 275 949 ; C -1 ; WX 606 ; N plusminus ; B 51 -24 555 518 ; C -1 ; WX 606 ; N multiply ; B 74 24 533 482 ; C -1 ; WX 536 ; N Eacute ; B 70 0 475 949 ; C -1 ; WX 592 ; N Ydieresis ; B 1 0 592 928 ; C -1 ; WX 332 ; N onesuperior ; B 63 296 198 740 ; C -1 ; WX 608 ; N ugrave ; B 62 -13 541 786 ; C -1 ; WX 606 ; N logicalnot ; B 51 109 555 388 ; C -1 ; WX 610 ; N ntilde ; B 65 0 546 754 ; C -1 ; WX 869 ; N Otilde ; B 43 -13 826 917 ; C -1 ; WX 655 ; N otilde ; B 42 -13 614 754 ; C -1 ; WX 813 ; N Ccedilla ; B 43 -222 771 752 ; C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ; C -1 ; WX 831 ; N onehalf ; B 81 0 750 740 ; C -1 ; WX 790 ; N Eth ; B 40 0 739 740 ; C -1 ; WX 400 ; N degree ; B 56 421 344 709 ; C -1 ; WX 592 ; N Yacute ; B 1 0 592 949 ; C -1 ; WX 869 ; N Ocircumflex ; B 43 -13 826 927 ; C -1 ; WX 655 ; N oacute ; B 42 -13 614 786 ; C -1 ; WX 608 ; N mu ; B 80 -184 527 547 ; C -1 ; WX 606 ; N minus ; B 51 219 555 287 ; C -1 ; WX 655 ; N eth ; B 42 -12 614 753 ; C -1 ; WX 655 ; N odieresis ; B 42 -13 614 765 ; C -1 ; WX 747 ; N copyright ; B -9 -12 755 752 ; C -1 ; WX 672 ; N brokenbar ; B 299 -100 373 740 ; EndCharMetrics StartKernData StartKernPairs 216 KPX A y -62 KPX A w -65 KPX A v -70 KPX A u -20 KPX A quoteright -100 KPX A quotedblright -100 KPX A Y -92 KPX A W -60 KPX A V -102 KPX A U -40 KPX A T -45 KPX A Q -40 KPX A O -50 KPX A G -40 KPX A C -40 KPX B A -10 KPX C A -40 KPX D period -20 KPX D comma -20 KPX D Y -30 KPX D W -10 KPX D V -50 KPX D A -50 KPX F period -160 KPX F e -20 KPX F comma -180 KPX F a -20 KPX F A -75 KPX G period -20 KPX G comma -20 KPX G Y -20 KPX J period -15 KPX J a -20 KPX J A -30 KPX K o -15 KPX K e -20 KPX K O -20 KPX L y -23 KPX L quoteright -130 KPX L quotedblright -130 KPX L Y -91 KPX L W -67 KPX L V -113 KPX L T -46 KPX O period -30 KPX O comma -30 KPX O Y -30 KPX O X -30 KPX O W -20 KPX O V -60 KPX O T -30 KPX O A -60 KPX P period -300 KPX P o -60 KPX P e -20 KPX P comma -280 KPX P a -20 KPX P A -114 KPX Q comma 20 KPX R Y -10 KPX R W 10 KPX R V -10 KPX R T 6 KPX S comma 20 KPX T y -50 KPX T w -55 KPX T u -46 KPX T semicolon -29 KPX T r -30 KPX T period -91 KPX T o -70 KPX T i 10 KPX T hyphen -75 KPX T e -49 KPX T comma -82 KPX T colon -15 KPX T a -90 KPX T O -30 KPX T A -45 KPX U period -20 KPX U comma -20 KPX U A -40 KPX V u -40 KPX V semicolon -33 KPX V period -165 KPX V o -101 KPX V i -5 KPX V hyphen -75 KPX V e -101 KPX V comma -145 KPX V colon -18 KPX V a -104 KPX V O -60 KPX V G -20 KPX V A -102 KPX W y -2 KPX W u -30 KPX W semicolon -33 KPX W period -106 KPX W o -46 KPX W i 6 KPX W hyphen -35 KPX W e -47 KPX W comma -106 KPX W colon -15 KPX W a -50 KPX W O -20 KPX W A -58 KPX Y u -52 KPX Y semicolon -23 KPX Y period -175 KPX Y o -89 KPX Y hyphen -85 KPX Y e -89 KPX Y comma -145 KPX Y colon -10 KPX Y a -93 KPX Y O -30 KPX Y A -92 KPX a p 20 KPX a b 20 KPX b y -20 KPX b v -20 KPX c y -20 KPX c k -15 KPX comma space -110 KPX comma quoteright -120 KPX comma quotedblright -120 KPX e y -20 KPX e w -20 KPX e v -20 KPX f period -50 KPX f o -40 KPX f l -30 KPX f i -34 KPX f f -60 KPX f e -20 KPX f dotlessi -34 KPX f comma -50 KPX f a -40 KPX g a -15 KPX h y -30 KPX k y -5 KPX k e -15 KPX m y -20 KPX m u -20 KPX m a -20 KPX n y -15 KPX n v -20 KPX o y -20 KPX o x -15 KPX o w -20 KPX o v -30 KPX p y -20 KPX period space -110 KPX period quoteright -120 KPX period quotedblright -120 KPX quotedblleft quoteleft -35 KPX quotedblleft A -100 KPX quotedblright space -110 KPX quoteleft quoteleft -203 KPX quoteleft A -100 KPX quoteright v -30 KPX quoteright t 10 KPX quoteright space -110 KPX quoteright s -15 KPX quoteright r -20 KPX quoteright quoteright -203 KPX quoteright quotedblright -35 KPX quoteright d -110 KPX r y 40 KPX r v 40 KPX r u 20 KPX r t 20 KPX r s 20 KPX r q -8 KPX r period -73 KPX r p 20 KPX r o -20 KPX r n 21 KPX r m 28 KPX r l 20 KPX r k 20 KPX r i 20 KPX r hyphen -60 KPX r g -15 KPX r e -4 KPX r d -6 KPX r comma -75 KPX r c -20 KPX r a -20 KPX s period 20 KPX s comma 20 KPX space quoteleft -110 KPX space quotedblleft -110 KPX space Y -60 KPX space W -25 KPX space V -50 KPX space T -25 KPX space A -20 KPX v period -130 KPX v o -30 KPX v e -20 KPX v comma -100 KPX v a -30 KPX w period -100 KPX w o -30 KPX w h 15 KPX w e -20 KPX w comma -90 KPX w a -30 KPX y period -125 KPX y o -30 KPX y e -20 KPX y comma -110 KPX y a -30 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 183 163 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 119 163 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 186 163 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 181 163 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 204 148 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 151 163 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 81 163 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 17 163 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 163 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 79 163 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute -34 163 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -138 163 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -71 163 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave -116 163 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 151 163 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 247 163 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 184 163 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 163 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 246 163 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 163 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron -2 163 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 163 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 77 163 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 143 163 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 119 163 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 129 163 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 163 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron -11 163 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ; EndComposites EndFontMetrics ���������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Palatino-Bold.afm�����������������������������������������������������0000644�0001750�0001750�00000037341�11462120062�017567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jul 2 22:26:30 1990 Comment UniqueID 31793 Comment VMusage 36031 46923 FontName Palatino-Bold FullName Palatino Bold FamilyName Palatino Weight Bold ItalicAngle 0 IsFixedPitch false FontBBox -152 -266 1000 924 UnderlinePosition -100 UnderlineThickness 50 Version 001.005 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 471 Ascender 720 Descender -258 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 63 -12 219 688 ; C 34 ; WX 402 ; N quotedbl ; B 22 376 380 695 ; C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ; C 36 ; WX 500 ; N dollar ; B 28 -114 472 721 ; C 37 ; WX 889 ; N percent ; B 61 -9 828 714 ; C 38 ; WX 833 ; N ampersand ; B 52 -17 813 684 ; C 39 ; WX 278 ; N quoteright ; B 29 405 249 695 ; C 40 ; WX 333 ; N parenleft ; B 65 -104 305 723 ; C 41 ; WX 333 ; N parenright ; B 28 -104 268 723 ; C 42 ; WX 444 ; N asterisk ; B 44 332 399 695 ; C 43 ; WX 606 ; N plus ; B 51 0 555 505 ; C 44 ; WX 250 ; N comma ; B -6 -166 227 141 ; C 45 ; WX 333 ; N hyphen ; B 16 195 317 305 ; C 46 ; WX 250 ; N period ; B 47 -12 203 144 ; C 47 ; WX 296 ; N slash ; B -9 -17 305 720 ; C 48 ; WX 500 ; N zero ; B 33 -17 468 660 ; C 49 ; WX 500 ; N one ; B 35 -3 455 670 ; C 50 ; WX 500 ; N two ; B 25 -3 472 660 ; C 51 ; WX 500 ; N three ; B 22 -17 458 660 ; C 52 ; WX 500 ; N four ; B 12 -3 473 672 ; C 53 ; WX 500 ; N five ; B 42 -17 472 656 ; C 54 ; WX 500 ; N six ; B 37 -17 469 660 ; C 55 ; WX 500 ; N seven ; B 46 -3 493 656 ; C 56 ; WX 500 ; N eight ; B 34 -17 467 660 ; C 57 ; WX 500 ; N nine ; B 31 -17 463 660 ; C 58 ; WX 250 ; N colon ; B 47 -12 203 454 ; C 59 ; WX 250 ; N semicolon ; B -6 -166 227 454 ; C 60 ; WX 606 ; N less ; B 49 -15 558 519 ; C 61 ; WX 606 ; N equal ; B 51 114 555 396 ; C 62 ; WX 606 ; N greater ; B 49 -15 558 519 ; C 63 ; WX 444 ; N question ; B 43 -12 411 687 ; C 64 ; WX 747 ; N at ; B 42 -12 704 681 ; C 65 ; WX 778 ; N A ; B 24 -3 757 686 ; C 66 ; WX 667 ; N B ; B 39 -3 611 681 ; C 67 ; WX 722 ; N C ; B 44 -17 695 695 ; C 68 ; WX 833 ; N D ; B 35 -3 786 681 ; C 69 ; WX 611 ; N E ; B 39 -4 577 681 ; C 70 ; WX 556 ; N F ; B 28 -3 539 681 ; C 71 ; WX 833 ; N G ; B 47 -17 776 695 ; C 72 ; WX 833 ; N H ; B 36 -3 796 681 ; C 73 ; WX 389 ; N I ; B 39 -3 350 681 ; C 74 ; WX 389 ; N J ; B -11 -213 350 681 ; C 75 ; WX 778 ; N K ; B 39 -3 763 681 ; C 76 ; WX 611 ; N L ; B 39 -4 577 681 ; C 77 ; WX 1000 ; N M ; B 32 -10 968 681 ; C 78 ; WX 833 ; N N ; B 35 -16 798 681 ; C 79 ; WX 833 ; N O ; B 47 -17 787 695 ; C 80 ; WX 611 ; N P ; B 39 -3 594 681 ; C 81 ; WX 833 ; N Q ; B 47 -184 787 695 ; C 82 ; WX 722 ; N R ; B 39 -3 708 681 ; C 83 ; WX 611 ; N S ; B 57 -17 559 695 ; C 84 ; WX 667 ; N T ; B 17 -3 650 681 ; C 85 ; WX 778 ; N U ; B 26 -17 760 681 ; C 86 ; WX 778 ; N V ; B 20 -3 763 681 ; C 87 ; WX 1000 ; N W ; B 17 -3 988 686 ; C 88 ; WX 667 ; N X ; B 17 -3 650 695 ; C 89 ; WX 667 ; N Y ; B 15 -3 660 695 ; C 90 ; WX 667 ; N Z ; B 24 -3 627 681 ; C 91 ; WX 333 ; N bracketleft ; B 73 -104 291 720 ; C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ; C 93 ; WX 333 ; N bracketright ; B 42 -104 260 720 ; C 94 ; WX 606 ; N asciicircum ; B 52 275 554 678 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 278 ; N quoteleft ; B 29 405 249 695 ; C 97 ; WX 500 ; N a ; B 40 -17 478 471 ; C 98 ; WX 611 ; N b ; B 10 -17 556 720 ; C 99 ; WX 444 ; N c ; B 37 -17 414 471 ; C 100 ; WX 611 ; N d ; B 42 -17 577 720 ; C 101 ; WX 500 ; N e ; B 42 -17 461 471 ; C 102 ; WX 389 ; N f ; B 34 -3 381 720 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 26 -266 535 471 ; C 104 ; WX 611 ; N h ; B 24 -3 587 720 ; C 105 ; WX 333 ; N i ; B 34 -3 298 706 ; C 106 ; WX 333 ; N j ; B 3 -266 241 706 ; C 107 ; WX 611 ; N k ; B 21 -3 597 720 ; C 108 ; WX 333 ; N l ; B 24 -3 296 720 ; C 109 ; WX 889 ; N m ; B 24 -3 864 471 ; C 110 ; WX 611 ; N n ; B 24 -3 587 471 ; C 111 ; WX 556 ; N o ; B 40 -17 517 471 ; C 112 ; WX 611 ; N p ; B 29 -258 567 471 ; C 113 ; WX 611 ; N q ; B 52 -258 589 471 ; C 114 ; WX 389 ; N r ; B 30 -3 389 471 ; C 115 ; WX 444 ; N s ; B 39 -17 405 471 ; C 116 ; WX 333 ; N t ; B 22 -17 324 632 ; C 117 ; WX 611 ; N u ; B 25 -17 583 471 ; C 118 ; WX 556 ; N v ; B 11 -3 545 459 ; C 119 ; WX 833 ; N w ; B 13 -3 820 471 ; C 120 ; WX 500 ; N x ; B 20 -3 483 471 ; C 121 ; WX 556 ; N y ; B 10 -266 546 459 ; C 122 ; WX 500 ; N z ; B 16 -3 464 459 ; C 123 ; WX 310 ; N braceleft ; B 5 -117 288 725 ; C 124 ; WX 606 ; N bar ; B 260 0 346 720 ; C 125 ; WX 310 ; N braceright ; B 22 -117 305 725 ; C 126 ; WX 606 ; N asciitilde ; B 51 155 555 342 ; C 161 ; WX 278 ; N exclamdown ; B 59 -227 215 471 ; C 162 ; WX 500 ; N cent ; B 73 -106 450 554 ; C 163 ; WX 500 ; N sterling ; B -2 -19 501 676 ; C 164 ; WX 167 ; N fraction ; B -152 0 320 660 ; C 165 ; WX 500 ; N yen ; B 17 -3 483 695 ; C 166 ; WX 500 ; N florin ; B 11 -242 490 703 ; C 167 ; WX 500 ; N section ; B 30 -217 471 695 ; C 168 ; WX 500 ; N currency ; B 32 96 468 533 ; C 169 ; WX 227 ; N quotesingle ; B 45 376 181 695 ; C 170 ; WX 500 ; N quotedblleft ; B 34 405 466 695 ; C 171 ; WX 500 ; N guillemotleft ; B 36 44 463 438 ; C 172 ; WX 389 ; N guilsinglleft ; B 82 44 307 438 ; C 173 ; WX 389 ; N guilsinglright ; B 82 44 307 438 ; C 174 ; WX 611 ; N fi ; B 10 -3 595 720 ; C 175 ; WX 611 ; N fl ; B 17 -3 593 720 ; C 177 ; WX 500 ; N endash ; B 0 208 500 291 ; C 178 ; WX 500 ; N dagger ; B 29 -6 472 682 ; C 179 ; WX 500 ; N daggerdbl ; B 32 -245 468 682 ; C 180 ; WX 250 ; N periodcentered ; B 47 179 203 335 ; C 182 ; WX 641 ; N paragraph ; B 19 -161 599 683 ; C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; C 184 ; WX 333 ; N quotesinglbase ; B 56 -160 276 130 ; C 185 ; WX 500 ; N quotedblbase ; B 34 -160 466 130 ; C 186 ; WX 500 ; N quotedblright ; B 34 405 466 695 ; C 187 ; WX 500 ; N guillemotright ; B 37 44 464 438 ; C 188 ; WX 1000 ; N ellipsis ; B 89 -12 911 144 ; C 189 ; WX 1000 ; N perthousand ; B 33 -9 982 724 ; C 191 ; WX 444 ; N questiondown ; B 33 -231 401 471 ; C 193 ; WX 333 ; N grave ; B 18 506 256 691 ; C 194 ; WX 333 ; N acute ; B 78 506 316 691 ; C 195 ; WX 333 ; N circumflex ; B -2 506 335 681 ; C 196 ; WX 333 ; N tilde ; B -16 535 349 661 ; C 197 ; WX 333 ; N macron ; B 1 538 332 609 ; C 198 ; WX 333 ; N breve ; B 15 506 318 669 ; C 199 ; WX 333 ; N dotaccent ; B 100 537 234 671 ; C 200 ; WX 333 ; N dieresis ; B -8 537 341 671 ; C 202 ; WX 333 ; N ring ; B 67 500 267 700 ; C 203 ; WX 333 ; N cedilla ; B 73 -225 300 -7 ; C 205 ; WX 333 ; N hungarumlaut ; B -56 506 390 691 ; C 206 ; WX 333 ; N ogonek ; B 60 -246 274 -17 ; C 207 ; WX 333 ; N caron ; B -2 510 335 685 ; C 208 ; WX 1000 ; N emdash ; B 0 208 1000 291 ; C 225 ; WX 1000 ; N AE ; B 12 -4 954 681 ; C 227 ; WX 438 ; N ordfeminine ; B 77 367 361 660 ; C 232 ; WX 611 ; N Lslash ; B 16 -4 577 681 ; C 233 ; WX 833 ; N Oslash ; B 32 -20 808 698 ; C 234 ; WX 1000 ; N OE ; B 43 -17 985 695 ; C 235 ; WX 488 ; N ordmasculine ; B 89 367 399 660 ; C 241 ; WX 778 ; N ae ; B 46 -17 731 471 ; C 245 ; WX 333 ; N dotlessi ; B 34 -3 298 471 ; C 248 ; WX 333 ; N lslash ; B -4 -3 334 720 ; C 249 ; WX 556 ; N oslash ; B 23 -18 534 471 ; C 250 ; WX 833 ; N oe ; B 48 -17 799 471 ; C 251 ; WX 611 ; N germandbls ; B 30 -17 565 720 ; C -1 ; WX 667 ; N Zcaron ; B 24 -3 627 909 ; C -1 ; WX 444 ; N ccedilla ; B 37 -225 414 471 ; C -1 ; WX 556 ; N ydieresis ; B 10 -266 546 691 ; C -1 ; WX 500 ; N atilde ; B 40 -17 478 673 ; C -1 ; WX 333 ; N icircumflex ; B -2 -3 335 701 ; C -1 ; WX 300 ; N threesuperior ; B 9 261 292 667 ; C -1 ; WX 500 ; N ecircumflex ; B 42 -17 461 701 ; C -1 ; WX 611 ; N thorn ; B 17 -258 563 720 ; C -1 ; WX 500 ; N egrave ; B 42 -17 461 711 ; C -1 ; WX 300 ; N twosuperior ; B 5 261 295 660 ; C -1 ; WX 500 ; N eacute ; B 42 -17 461 711 ; C -1 ; WX 556 ; N otilde ; B 40 -17 517 673 ; C -1 ; WX 778 ; N Aacute ; B 24 -3 757 915 ; C -1 ; WX 556 ; N ocircumflex ; B 40 -17 517 701 ; C -1 ; WX 556 ; N yacute ; B 10 -266 546 711 ; C -1 ; WX 611 ; N udieresis ; B 25 -17 583 691 ; C -1 ; WX 750 ; N threequarters ; B 15 -2 735 667 ; C -1 ; WX 500 ; N acircumflex ; B 40 -17 478 701 ; C -1 ; WX 833 ; N Eth ; B 10 -3 786 681 ; C -1 ; WX 500 ; N edieresis ; B 42 -17 461 691 ; C -1 ; WX 611 ; N ugrave ; B 25 -17 583 711 ; C -1 ; WX 998 ; N trademark ; B 38 274 961 678 ; C -1 ; WX 556 ; N ograve ; B 40 -17 517 711 ; C -1 ; WX 444 ; N scaron ; B 39 -17 405 693 ; C -1 ; WX 389 ; N Idieresis ; B 20 -3 369 895 ; C -1 ; WX 611 ; N uacute ; B 25 -17 583 711 ; C -1 ; WX 500 ; N agrave ; B 40 -17 478 711 ; C -1 ; WX 611 ; N ntilde ; B 24 -3 587 673 ; C -1 ; WX 500 ; N aring ; B 40 -17 478 700 ; C -1 ; WX 500 ; N zcaron ; B 16 -3 464 693 ; C -1 ; WX 389 ; N Icircumflex ; B 26 -3 363 905 ; C -1 ; WX 833 ; N Ntilde ; B 35 -16 798 885 ; C -1 ; WX 611 ; N ucircumflex ; B 25 -17 583 701 ; C -1 ; WX 611 ; N Ecircumflex ; B 39 -4 577 905 ; C -1 ; WX 389 ; N Iacute ; B 39 -3 350 915 ; C -1 ; WX 722 ; N Ccedilla ; B 44 -225 695 695 ; C -1 ; WX 833 ; N Odieresis ; B 47 -17 787 895 ; C -1 ; WX 611 ; N Scaron ; B 57 -17 559 909 ; C -1 ; WX 611 ; N Edieresis ; B 39 -4 577 895 ; C -1 ; WX 389 ; N Igrave ; B 39 -3 350 915 ; C -1 ; WX 500 ; N adieresis ; B 40 -17 478 691 ; C -1 ; WX 833 ; N Ograve ; B 47 -17 787 915 ; C -1 ; WX 611 ; N Egrave ; B 39 -4 577 915 ; C -1 ; WX 667 ; N Ydieresis ; B 15 -3 660 895 ; C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ; C -1 ; WX 833 ; N Otilde ; B 47 -17 787 885 ; C -1 ; WX 750 ; N onequarter ; B 19 -2 735 665 ; C -1 ; WX 778 ; N Ugrave ; B 26 -17 760 915 ; C -1 ; WX 778 ; N Ucircumflex ; B 26 -17 760 905 ; C -1 ; WX 611 ; N Thorn ; B 39 -3 574 681 ; C -1 ; WX 606 ; N divide ; B 51 0 555 510 ; C -1 ; WX 778 ; N Atilde ; B 24 -3 757 885 ; C -1 ; WX 778 ; N Uacute ; B 26 -17 760 915 ; C -1 ; WX 833 ; N Ocircumflex ; B 47 -17 787 905 ; C -1 ; WX 606 ; N logicalnot ; B 51 114 555 396 ; C -1 ; WX 778 ; N Aring ; B 24 -3 757 924 ; C -1 ; WX 333 ; N idieresis ; B -8 -3 341 691 ; C -1 ; WX 333 ; N iacute ; B 34 -3 316 711 ; C -1 ; WX 500 ; N aacute ; B 40 -17 478 711 ; C -1 ; WX 606 ; N plusminus ; B 51 0 555 505 ; C -1 ; WX 606 ; N multiply ; B 72 21 534 483 ; C -1 ; WX 778 ; N Udieresis ; B 26 -17 760 895 ; C -1 ; WX 606 ; N minus ; B 51 212 555 298 ; C -1 ; WX 300 ; N onesuperior ; B 14 261 287 665 ; C -1 ; WX 611 ; N Eacute ; B 39 -4 577 915 ; C -1 ; WX 778 ; N Acircumflex ; B 24 -3 757 905 ; C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ; C -1 ; WX 778 ; N Agrave ; B 24 -3 757 915 ; C -1 ; WX 556 ; N odieresis ; B 40 -17 517 691 ; C -1 ; WX 556 ; N oacute ; B 40 -17 517 711 ; C -1 ; WX 400 ; N degree ; B 50 360 350 660 ; C -1 ; WX 333 ; N igrave ; B 18 -3 298 711 ; C -1 ; WX 611 ; N mu ; B 25 -225 583 471 ; C -1 ; WX 833 ; N Oacute ; B 47 -17 787 915 ; C -1 ; WX 556 ; N eth ; B 40 -17 517 720 ; C -1 ; WX 778 ; N Adieresis ; B 24 -3 757 895 ; C -1 ; WX 667 ; N Yacute ; B 15 -3 660 915 ; C -1 ; WX 606 ; N brokenbar ; B 260 0 346 720 ; C -1 ; WX 750 ; N onehalf ; B 9 -2 745 665 ; EndCharMetrics StartKernData StartKernPairs 101 KPX A y -70 KPX A w -70 KPX A v -70 KPX A space -18 KPX A quoteright -92 KPX A Y -111 KPX A W -90 KPX A V -129 KPX A T -92 KPX F period -111 KPX F comma -111 KPX F A -55 KPX L y -74 KPX L space -18 KPX L quoteright -74 KPX L Y -92 KPX L W -92 KPX L V -92 KPX L T -74 KPX P period -129 KPX P comma -129 KPX P A -74 KPX R y -30 KPX R Y -55 KPX R W -37 KPX R V -74 KPX R T -55 KPX T y -90 KPX T w -90 KPX T u -129 KPX T semicolon -74 KPX T s -111 KPX T r -111 KPX T period -92 KPX T o -111 KPX T i -55 KPX T hyphen -92 KPX T e -111 KPX T comma -92 KPX T colon -74 KPX T c -129 KPX T a -111 KPX T A -92 KPX V y -90 KPX V u -92 KPX V semicolon -74 KPX V r -111 KPX V period -129 KPX V o -111 KPX V i -55 KPX V hyphen -92 KPX V e -111 KPX V comma -129 KPX V colon -74 KPX V a -111 KPX V A -129 KPX W y -74 KPX W u -74 KPX W semicolon -37 KPX W r -74 KPX W period -37 KPX W o -74 KPX W i -37 KPX W hyphen -37 KPX W e -74 KPX W comma -92 KPX W colon -37 KPX W a -74 KPX W A -90 KPX Y v -74 KPX Y u -74 KPX Y semicolon -55 KPX Y q -92 KPX Y period -74 KPX Y p -74 KPX Y o -74 KPX Y i -55 KPX Y hyphen -74 KPX Y e -74 KPX Y comma -74 KPX Y colon -55 KPX Y a -74 KPX Y A -55 KPX f quoteright 37 KPX f f -18 KPX one one -37 KPX quoteleft quoteleft -55 KPX quoteright t -18 KPX quoteright space -55 KPX quoteright s -55 KPX quoteright quoteright -55 KPX r quoteright 55 KPX r period -55 KPX r hyphen -18 KPX r comma -55 KPX v period -111 KPX v comma -111 KPX w period -92 KPX w comma -92 KPX y period -92 KPX y comma -92 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 223 224 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 211 224 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 224 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 224 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 223 224 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 224 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 224 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 224 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 224 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 224 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 224 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 224 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 224 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 224 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 224 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 224 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 224 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 224 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 224 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 224 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 224 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 224 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 224 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 224 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 224 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 211 224 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 199 224 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 224 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 20 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 84 20 ; CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 12 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 84 20 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 96 20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 20 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 84 20 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 12 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 56 8 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 151 20 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 20 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 20 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 131 20 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 124 20 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Palatino-Roman.afm����������������������������������������������������0000644�0001750�0001750�00000037506�11462120062�017766� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jul 2 22:14:17 1990 Comment UniqueID 31790 Comment VMusage 36445 47337 FontName Palatino-Roman FullName Palatino Roman FamilyName Palatino Weight Roman ItalicAngle 0 IsFixedPitch false FontBBox -166 -283 1021 927 UnderlinePosition -100 UnderlineThickness 50 Version 001.005 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 692 XHeight 469 Ascender 726 Descender -281 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 81 -5 197 694 ; C 34 ; WX 371 ; N quotedbl ; B 52 469 319 709 ; C 35 ; WX 500 ; N numbersign ; B 4 0 495 684 ; C 36 ; WX 500 ; N dollar ; B 30 -116 471 731 ; C 37 ; WX 840 ; N percent ; B 39 -20 802 709 ; C 38 ; WX 778 ; N ampersand ; B 43 -20 753 689 ; C 39 ; WX 278 ; N quoteright ; B 45 446 233 709 ; C 40 ; WX 333 ; N parenleft ; B 60 -215 301 726 ; C 41 ; WX 333 ; N parenright ; B 32 -215 273 726 ; C 42 ; WX 389 ; N asterisk ; B 32 342 359 689 ; C 43 ; WX 606 ; N plus ; B 51 7 555 512 ; C 44 ; WX 250 ; N comma ; B 16 -155 218 123 ; C 45 ; WX 333 ; N hyphen ; B 17 215 312 287 ; C 46 ; WX 250 ; N period ; B 67 -5 183 111 ; C 47 ; WX 606 ; N slash ; B 87 -119 519 726 ; C 48 ; WX 500 ; N zero ; B 29 -20 465 689 ; C 49 ; WX 500 ; N one ; B 60 -3 418 694 ; C 50 ; WX 500 ; N two ; B 16 -3 468 689 ; C 51 ; WX 500 ; N three ; B 15 -20 462 689 ; C 52 ; WX 500 ; N four ; B 2 -3 472 694 ; C 53 ; WX 500 ; N five ; B 13 -20 459 689 ; C 54 ; WX 500 ; N six ; B 32 -20 468 689 ; C 55 ; WX 500 ; N seven ; B 44 -3 497 689 ; C 56 ; WX 500 ; N eight ; B 30 -20 464 689 ; C 57 ; WX 500 ; N nine ; B 20 -20 457 689 ; C 58 ; WX 250 ; N colon ; B 66 -5 182 456 ; C 59 ; WX 250 ; N semicolon ; B 16 -153 218 456 ; C 60 ; WX 606 ; N less ; B 57 0 558 522 ; C 61 ; WX 606 ; N equal ; B 51 136 555 386 ; C 62 ; WX 606 ; N greater ; B 48 0 549 522 ; C 63 ; WX 444 ; N question ; B 43 -5 395 694 ; C 64 ; WX 747 ; N at ; B 24 -20 724 694 ; C 65 ; WX 778 ; N A ; B 15 -3 756 700 ; C 66 ; WX 611 ; N B ; B 26 -3 576 692 ; C 67 ; WX 709 ; N C ; B 22 -20 670 709 ; C 68 ; WX 774 ; N D ; B 22 -3 751 692 ; C 69 ; WX 611 ; N E ; B 22 -3 572 692 ; C 70 ; WX 556 ; N F ; B 22 -3 536 692 ; C 71 ; WX 763 ; N G ; B 22 -20 728 709 ; C 72 ; WX 832 ; N H ; B 22 -3 810 692 ; C 73 ; WX 337 ; N I ; B 22 -3 315 692 ; C 74 ; WX 333 ; N J ; B -15 -194 311 692 ; C 75 ; WX 726 ; N K ; B 22 -3 719 692 ; C 76 ; WX 611 ; N L ; B 22 -3 586 692 ; C 77 ; WX 946 ; N M ; B 16 -13 926 692 ; C 78 ; WX 831 ; N N ; B 17 -20 813 692 ; C 79 ; WX 786 ; N O ; B 22 -20 764 709 ; C 80 ; WX 604 ; N P ; B 22 -3 580 692 ; C 81 ; WX 786 ; N Q ; B 22 -176 764 709 ; C 82 ; WX 668 ; N R ; B 22 -3 669 692 ; C 83 ; WX 525 ; N S ; B 24 -20 503 709 ; C 84 ; WX 613 ; N T ; B 18 -3 595 692 ; C 85 ; WX 778 ; N U ; B 12 -20 759 692 ; C 86 ; WX 722 ; N V ; B 8 -9 706 692 ; C 87 ; WX 1000 ; N W ; B 8 -9 984 700 ; C 88 ; WX 667 ; N X ; B 14 -3 648 700 ; C 89 ; WX 667 ; N Y ; B 9 -3 654 704 ; C 90 ; WX 667 ; N Z ; B 15 -3 638 692 ; C 91 ; WX 333 ; N bracketleft ; B 79 -184 288 726 ; C 92 ; WX 606 ; N backslash ; B 81 0 512 726 ; C 93 ; WX 333 ; N bracketright ; B 45 -184 254 726 ; C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 278 ; N quoteleft ; B 45 446 233 709 ; C 97 ; WX 500 ; N a ; B 32 -12 471 469 ; C 98 ; WX 553 ; N b ; B -15 -12 508 726 ; C 99 ; WX 444 ; N c ; B 26 -20 413 469 ; C 100 ; WX 611 ; N d ; B 35 -12 579 726 ; C 101 ; WX 479 ; N e ; B 26 -20 448 469 ; C 102 ; WX 333 ; N f ; B 23 -3 341 728 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 32 -283 544 469 ; C 104 ; WX 582 ; N h ; B 6 -3 572 726 ; C 105 ; WX 291 ; N i ; B 21 -3 271 687 ; C 106 ; WX 234 ; N j ; B -40 -283 167 688 ; C 107 ; WX 556 ; N k ; B 21 -12 549 726 ; C 108 ; WX 291 ; N l ; B 21 -3 271 726 ; C 109 ; WX 883 ; N m ; B 16 -3 869 469 ; C 110 ; WX 582 ; N n ; B 6 -3 572 469 ; C 111 ; WX 546 ; N o ; B 32 -20 514 469 ; C 112 ; WX 601 ; N p ; B 8 -281 554 469 ; C 113 ; WX 560 ; N q ; B 35 -281 560 469 ; C 114 ; WX 395 ; N r ; B 21 -3 374 469 ; C 115 ; WX 424 ; N s ; B 30 -20 391 469 ; C 116 ; WX 326 ; N t ; B 22 -12 319 621 ; C 117 ; WX 603 ; N u ; B 18 -12 581 469 ; C 118 ; WX 565 ; N v ; B 6 -7 539 459 ; C 119 ; WX 834 ; N w ; B 6 -7 808 469 ; C 120 ; WX 516 ; N x ; B 20 -3 496 469 ; C 121 ; WX 556 ; N y ; B 12 -283 544 459 ; C 122 ; WX 500 ; N z ; B 16 -3 466 462 ; C 123 ; WX 333 ; N braceleft ; B 58 -175 289 726 ; C 124 ; WX 606 ; N bar ; B 275 0 331 726 ; C 125 ; WX 333 ; N braceright ; B 44 -175 275 726 ; C 126 ; WX 606 ; N asciitilde ; B 51 176 555 347 ; C 161 ; WX 278 ; N exclamdown ; B 81 -225 197 469 ; C 162 ; WX 500 ; N cent ; B 61 -101 448 562 ; C 163 ; WX 500 ; N sterling ; B 12 -13 478 694 ; C 164 ; WX 167 ; N fraction ; B -166 0 337 689 ; C 165 ; WX 500 ; N yen ; B 5 -3 496 701 ; C 166 ; WX 500 ; N florin ; B 0 -262 473 706 ; C 167 ; WX 500 ; N section ; B 26 -219 465 709 ; C 168 ; WX 500 ; N currency ; B 30 96 470 531 ; C 169 ; WX 208 ; N quotesingle ; B 61 469 147 709 ; C 170 ; WX 500 ; N quotedblleft ; B 51 446 449 709 ; C 171 ; WX 500 ; N guillemotleft ; B 50 71 450 428 ; C 172 ; WX 331 ; N guilsinglleft ; B 66 71 265 428 ; C 173 ; WX 331 ; N guilsinglright ; B 66 71 265 428 ; C 174 ; WX 605 ; N fi ; B 23 -3 587 728 ; C 175 ; WX 608 ; N fl ; B 23 -3 590 728 ; C 177 ; WX 500 ; N endash ; B 0 219 500 277 ; C 178 ; WX 500 ; N dagger ; B 34 -5 466 694 ; C 179 ; WX 500 ; N daggerdbl ; B 34 -249 466 694 ; C 180 ; WX 250 ; N periodcentered ; B 67 203 183 319 ; C 182 ; WX 628 ; N paragraph ; B 39 -150 589 694 ; C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; C 184 ; WX 278 ; N quotesinglbase ; B 22 -153 210 110 ; C 185 ; WX 500 ; N quotedblbase ; B 51 -153 449 110 ; C 186 ; WX 500 ; N quotedblright ; B 51 446 449 709 ; C 187 ; WX 500 ; N guillemotright ; B 50 71 450 428 ; C 188 ; WX 1000 ; N ellipsis ; B 109 -5 891 111 ; C 189 ; WX 1144 ; N perthousand ; B 123 -20 1021 709 ; C 191 ; WX 444 ; N questiondown ; B 43 -231 395 469 ; C 193 ; WX 333 ; N grave ; B 31 506 255 677 ; C 194 ; WX 333 ; N acute ; B 78 506 302 677 ; C 195 ; WX 333 ; N circumflex ; B 11 510 323 677 ; C 196 ; WX 333 ; N tilde ; B 2 535 332 640 ; C 197 ; WX 333 ; N macron ; B 11 538 323 591 ; C 198 ; WX 333 ; N breve ; B 26 506 308 664 ; C 199 ; WX 250 ; N dotaccent ; B 75 537 175 637 ; C 200 ; WX 333 ; N dieresis ; B 17 537 316 637 ; C 202 ; WX 333 ; N ring ; B 67 496 267 696 ; C 203 ; WX 333 ; N cedilla ; B 96 -225 304 -10 ; C 205 ; WX 380 ; N hungarumlaut ; B 3 506 377 687 ; C 206 ; WX 313 ; N ogonek ; B 68 -165 245 -20 ; C 207 ; WX 333 ; N caron ; B 11 510 323 677 ; C 208 ; WX 1000 ; N emdash ; B 0 219 1000 277 ; C 225 ; WX 944 ; N AE ; B -10 -3 908 692 ; C 227 ; WX 333 ; N ordfeminine ; B 24 422 310 709 ; C 232 ; WX 611 ; N Lslash ; B 6 -3 586 692 ; C 233 ; WX 833 ; N Oslash ; B 30 -20 797 709 ; C 234 ; WX 998 ; N OE ; B 22 -20 962 709 ; C 235 ; WX 333 ; N ordmasculine ; B 10 416 323 709 ; C 241 ; WX 758 ; N ae ; B 30 -20 732 469 ; C 245 ; WX 287 ; N dotlessi ; B 21 -3 271 469 ; C 248 ; WX 291 ; N lslash ; B -14 -3 306 726 ; C 249 ; WX 556 ; N oslash ; B 16 -23 530 474 ; C 250 ; WX 827 ; N oe ; B 32 -20 800 469 ; C 251 ; WX 556 ; N germandbls ; B 23 -9 519 731 ; C -1 ; WX 667 ; N Zcaron ; B 15 -3 638 908 ; C -1 ; WX 444 ; N ccedilla ; B 26 -225 413 469 ; C -1 ; WX 556 ; N ydieresis ; B 12 -283 544 657 ; C -1 ; WX 500 ; N atilde ; B 32 -12 471 652 ; C -1 ; WX 287 ; N icircumflex ; B -12 -3 300 697 ; C -1 ; WX 300 ; N threesuperior ; B 1 266 299 689 ; C -1 ; WX 479 ; N ecircumflex ; B 26 -20 448 697 ; C -1 ; WX 601 ; N thorn ; B -2 -281 544 726 ; C -1 ; WX 479 ; N egrave ; B 26 -20 448 697 ; C -1 ; WX 300 ; N twosuperior ; B 0 273 301 689 ; C -1 ; WX 479 ; N eacute ; B 26 -20 448 697 ; C -1 ; WX 546 ; N otilde ; B 32 -20 514 652 ; C -1 ; WX 778 ; N Aacute ; B 15 -3 756 908 ; C -1 ; WX 546 ; N ocircumflex ; B 32 -20 514 697 ; C -1 ; WX 556 ; N yacute ; B 12 -283 544 697 ; C -1 ; WX 603 ; N udieresis ; B 18 -12 581 657 ; C -1 ; WX 750 ; N threequarters ; B 15 -3 735 689 ; C -1 ; WX 500 ; N acircumflex ; B 32 -12 471 697 ; C -1 ; WX 774 ; N Eth ; B 14 -3 751 692 ; C -1 ; WX 479 ; N edieresis ; B 26 -20 448 657 ; C -1 ; WX 603 ; N ugrave ; B 18 -12 581 697 ; C -1 ; WX 979 ; N trademark ; B 40 285 939 689 ; C -1 ; WX 546 ; N ograve ; B 32 -20 514 697 ; C -1 ; WX 424 ; N scaron ; B 30 -20 391 685 ; C -1 ; WX 337 ; N Idieresis ; B 19 -3 318 868 ; C -1 ; WX 603 ; N uacute ; B 18 -12 581 697 ; C -1 ; WX 500 ; N agrave ; B 32 -12 471 697 ; C -1 ; WX 582 ; N ntilde ; B 6 -3 572 652 ; C -1 ; WX 500 ; N aring ; B 32 -12 471 716 ; C -1 ; WX 500 ; N zcaron ; B 16 -3 466 685 ; C -1 ; WX 337 ; N Icircumflex ; B 13 -3 325 908 ; C -1 ; WX 831 ; N Ntilde ; B 17 -20 813 871 ; C -1 ; WX 603 ; N ucircumflex ; B 18 -12 581 697 ; C -1 ; WX 611 ; N Ecircumflex ; B 22 -3 572 908 ; C -1 ; WX 337 ; N Iacute ; B 22 -3 315 908 ; C -1 ; WX 709 ; N Ccedilla ; B 22 -225 670 709 ; C -1 ; WX 786 ; N Odieresis ; B 22 -20 764 868 ; C -1 ; WX 525 ; N Scaron ; B 24 -20 503 908 ; C -1 ; WX 611 ; N Edieresis ; B 22 -3 572 868 ; C -1 ; WX 337 ; N Igrave ; B 22 -3 315 908 ; C -1 ; WX 500 ; N adieresis ; B 32 -12 471 657 ; C -1 ; WX 786 ; N Ograve ; B 22 -20 764 908 ; C -1 ; WX 611 ; N Egrave ; B 22 -3 572 908 ; C -1 ; WX 667 ; N Ydieresis ; B 9 -3 654 868 ; C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ; C -1 ; WX 786 ; N Otilde ; B 22 -20 764 883 ; C -1 ; WX 750 ; N onequarter ; B 30 -3 727 692 ; C -1 ; WX 778 ; N Ugrave ; B 12 -20 759 908 ; C -1 ; WX 778 ; N Ucircumflex ; B 12 -20 759 908 ; C -1 ; WX 604 ; N Thorn ; B 32 -3 574 692 ; C -1 ; WX 606 ; N divide ; B 51 10 555 512 ; C -1 ; WX 778 ; N Atilde ; B 15 -3 756 871 ; C -1 ; WX 778 ; N Uacute ; B 12 -20 759 908 ; C -1 ; WX 786 ; N Ocircumflex ; B 22 -20 764 908 ; C -1 ; WX 606 ; N logicalnot ; B 51 120 551 386 ; C -1 ; WX 778 ; N Aring ; B 15 -3 756 927 ; C -1 ; WX 287 ; N idieresis ; B -6 -3 293 657 ; C -1 ; WX 287 ; N iacute ; B 21 -3 279 697 ; C -1 ; WX 500 ; N aacute ; B 32 -12 471 697 ; C -1 ; WX 606 ; N plusminus ; B 51 0 555 512 ; C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ; C -1 ; WX 778 ; N Udieresis ; B 12 -20 759 868 ; C -1 ; WX 606 ; N minus ; B 51 233 555 289 ; C -1 ; WX 300 ; N onesuperior ; B 31 273 269 692 ; C -1 ; WX 611 ; N Eacute ; B 22 -3 572 908 ; C -1 ; WX 778 ; N Acircumflex ; B 15 -3 756 908 ; C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ; C -1 ; WX 778 ; N Agrave ; B 15 -3 756 908 ; C -1 ; WX 546 ; N odieresis ; B 32 -20 514 657 ; C -1 ; WX 546 ; N oacute ; B 32 -20 514 697 ; C -1 ; WX 400 ; N degree ; B 50 389 350 689 ; C -1 ; WX 287 ; N igrave ; B 8 -3 271 697 ; C -1 ; WX 603 ; N mu ; B 18 -236 581 469 ; C -1 ; WX 786 ; N Oacute ; B 22 -20 764 908 ; C -1 ; WX 546 ; N eth ; B 32 -20 504 728 ; C -1 ; WX 778 ; N Adieresis ; B 15 -3 756 868 ; C -1 ; WX 667 ; N Yacute ; B 9 -3 654 908 ; C -1 ; WX 606 ; N brokenbar ; B 275 0 331 726 ; C -1 ; WX 750 ; N onehalf ; B 15 -3 735 692 ; EndCharMetrics StartKernData StartKernPairs 111 KPX A y -74 KPX A w -74 KPX A v -92 KPX A space -55 KPX A quoteright -74 KPX A Y -111 KPX A W -74 KPX A V -111 KPX A T -74 KPX F period -92 KPX F comma -92 KPX F A -74 KPX L y -55 KPX L space -37 KPX L quoteright -74 KPX L Y -92 KPX L W -74 KPX L V -92 KPX L T -74 KPX P space -18 KPX P period -129 KPX P comma -129 KPX P A -92 KPX R y -37 KPX R Y -37 KPX R W -37 KPX R V -55 KPX R T -37 KPX T y -90 KPX T w -90 KPX T u -90 KPX T semicolon -55 KPX T s -90 KPX T r -90 KPX T period -74 KPX T o -92 KPX T i -55 KPX T hyphen -55 KPX T e -92 KPX T comma -74 KPX T colon -55 KPX T c -111 KPX T a -92 KPX T O -18 KPX T A -74 KPX V y -92 KPX V u -92 KPX V semicolon -55 KPX V r -92 KPX V period -129 KPX V o -111 KPX V i -55 KPX V hyphen -74 KPX V e -111 KPX V comma -129 KPX V colon -55 KPX V a -92 KPX V A -111 KPX W y -50 KPX W u -50 KPX W semicolon -18 KPX W r -74 KPX W period -92 KPX W o -92 KPX W i -55 KPX W hyphen -55 KPX W e -92 KPX W comma -92 KPX W colon -18 KPX W a -92 KPX W A -92 KPX Y v -90 KPX Y u -90 KPX Y space -18 KPX Y semicolon -74 KPX Y q -90 KPX Y period -111 KPX Y p -111 KPX Y o -92 KPX Y i -55 KPX Y hyphen -92 KPX Y e -92 KPX Y comma -111 KPX Y colon -74 KPX Y a -92 KPX Y A -92 KPX f quoteright 55 KPX f f -18 KPX one one -55 KPX quoteleft quoteleft -37 KPX quoteright quoteright -37 KPX r u -8 KPX r quoteright 74 KPX r q -18 KPX r period -74 KPX r o -18 KPX r hyphen -18 KPX r h -18 KPX r g -18 KPX r e -18 KPX r d -18 KPX r comma -74 KPX r c -18 KPX space Y -18 KPX space A -37 KPX v period -111 KPX v comma -111 KPX w period -92 KPX w comma -92 KPX y period -111 KPX y comma -111 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 229 231 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 223 231 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 231 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 231 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 223 231 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 231 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 231 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 231 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 231 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 231 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 2 231 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 2 231 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 2 231 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 2 231 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 249 231 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 227 231 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 227 231 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 227 231 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 227 231 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 227 243 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 96 231 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 255 231 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 247 231 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 231 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 231 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 203 231 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 191 231 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 231 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 72 20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 72 20 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 60 20 ; CC aring 2 ; PCC a 0 0 ; PCC ring 72 20 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 72 12 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 97 20 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 85 20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 73 20 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 73 20 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -23 20 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -23 20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -23 20 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -23 20 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 113 12 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 107 20 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 107 20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 107 20 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 95 20 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 107 12 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 46 8 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 159 20 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 135 20 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 135 20 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 20 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ; EndComposites EndFontMetrics ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Times-Roman.afm�������������������������������������������������������0000644�0001750�0001750�00000044237�11462120062�017277� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Mar 20 12:15:44 1990 Comment UniqueID 28416 Comment VMusage 30487 37379 FontName Times-Roman FullName Times Roman FamilyName Times Weight Roman ItalicAngle 0 IsFixedPitch false FontBBox -168 -218 1000 898 UnderlinePosition -100 UnderlineThickness 50 Version 001.007 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 662 XHeight 450 Ascender 683 Descender -217 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ; C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ; C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ; C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ; C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ; C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ; C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ; C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ; C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ; C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ; C 43 ; WX 564 ; N plus ; B 30 0 534 506 ; C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ; C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ; C 46 ; WX 250 ; N period ; B 70 -11 181 100 ; C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ; C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ; C 49 ; WX 500 ; N one ; B 111 0 394 676 ; C 50 ; WX 500 ; N two ; B 30 0 475 676 ; C 51 ; WX 500 ; N three ; B 43 -14 431 676 ; C 52 ; WX 500 ; N four ; B 12 0 472 676 ; C 53 ; WX 500 ; N five ; B 32 -14 438 688 ; C 54 ; WX 500 ; N six ; B 34 -14 468 684 ; C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ; C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ; C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ; C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ; C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ; C 60 ; WX 564 ; N less ; B 28 -8 536 514 ; C 61 ; WX 564 ; N equal ; B 30 120 534 386 ; C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ; C 63 ; WX 444 ; N question ; B 68 -8 414 676 ; C 64 ; WX 921 ; N at ; B 116 -14 809 676 ; C 65 ; WX 722 ; N A ; B 15 0 706 674 ; C 66 ; WX 667 ; N B ; B 17 0 593 662 ; C 67 ; WX 667 ; N C ; B 28 -14 633 676 ; C 68 ; WX 722 ; N D ; B 16 0 685 662 ; C 69 ; WX 611 ; N E ; B 12 0 597 662 ; C 70 ; WX 556 ; N F ; B 12 0 546 662 ; C 71 ; WX 722 ; N G ; B 32 -14 709 676 ; C 72 ; WX 722 ; N H ; B 19 0 702 662 ; C 73 ; WX 333 ; N I ; B 18 0 315 662 ; C 74 ; WX 389 ; N J ; B 10 -14 370 662 ; C 75 ; WX 722 ; N K ; B 34 0 723 662 ; C 76 ; WX 611 ; N L ; B 12 0 598 662 ; C 77 ; WX 889 ; N M ; B 12 0 863 662 ; C 78 ; WX 722 ; N N ; B 12 -11 707 662 ; C 79 ; WX 722 ; N O ; B 34 -14 688 676 ; C 80 ; WX 556 ; N P ; B 16 0 542 662 ; C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ; C 82 ; WX 667 ; N R ; B 17 0 659 662 ; C 83 ; WX 556 ; N S ; B 42 -14 491 676 ; C 84 ; WX 611 ; N T ; B 17 0 593 662 ; C 85 ; WX 722 ; N U ; B 14 -14 705 662 ; C 86 ; WX 722 ; N V ; B 16 -11 697 662 ; C 87 ; WX 944 ; N W ; B 5 -11 932 662 ; C 88 ; WX 722 ; N X ; B 10 0 704 662 ; C 89 ; WX 722 ; N Y ; B 22 0 703 662 ; C 90 ; WX 611 ; N Z ; B 9 0 597 662 ; C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ; C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ; C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ; C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ; C 97 ; WX 444 ; N a ; B 37 -10 442 460 ; C 98 ; WX 500 ; N b ; B 3 -10 468 683 ; C 99 ; WX 444 ; N c ; B 25 -10 412 460 ; C 100 ; WX 500 ; N d ; B 27 -10 491 683 ; C 101 ; WX 444 ; N e ; B 25 -10 424 460 ; C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 28 -218 470 460 ; C 104 ; WX 500 ; N h ; B 9 0 487 683 ; C 105 ; WX 278 ; N i ; B 16 0 253 683 ; C 106 ; WX 278 ; N j ; B -70 -218 194 683 ; C 107 ; WX 500 ; N k ; B 7 0 505 683 ; C 108 ; WX 278 ; N l ; B 19 0 257 683 ; C 109 ; WX 778 ; N m ; B 16 0 775 460 ; C 110 ; WX 500 ; N n ; B 16 0 485 460 ; C 111 ; WX 500 ; N o ; B 29 -10 470 460 ; C 112 ; WX 500 ; N p ; B 5 -217 470 460 ; C 113 ; WX 500 ; N q ; B 24 -217 488 460 ; C 114 ; WX 333 ; N r ; B 5 0 335 460 ; C 115 ; WX 389 ; N s ; B 51 -10 348 460 ; C 116 ; WX 278 ; N t ; B 13 -10 279 579 ; C 117 ; WX 500 ; N u ; B 9 -10 479 450 ; C 118 ; WX 500 ; N v ; B 19 -14 477 450 ; C 119 ; WX 722 ; N w ; B 21 -14 694 450 ; C 120 ; WX 500 ; N x ; B 17 0 479 450 ; C 121 ; WX 500 ; N y ; B 14 -218 475 450 ; C 122 ; WX 444 ; N z ; B 27 0 418 450 ; C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ; C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ; C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ; C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ; C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ; C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ; C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ; C 165 ; WX 500 ; N yen ; B -53 0 512 662 ; C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ; C 167 ; WX 500 ; N section ; B 70 -148 426 676 ; C 168 ; WX 500 ; N currency ; B -22 58 522 602 ; C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ; C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ; C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ; C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ; C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ; C 174 ; WX 556 ; N fi ; B 31 0 521 683 ; C 175 ; WX 556 ; N fl ; B 32 0 521 683 ; C 177 ; WX 500 ; N endash ; B 0 201 500 250 ; C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ; C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ; C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ; C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ; C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ; C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ; C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ; C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ; C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ; C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ; C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ; C 193 ; WX 333 ; N grave ; B 19 507 242 678 ; C 194 ; WX 333 ; N acute ; B 93 507 317 678 ; C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ; C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ; C 197 ; WX 333 ; N macron ; B 11 547 322 601 ; C 198 ; WX 333 ; N breve ; B 26 507 307 664 ; C 199 ; WX 333 ; N dotaccent ; B 118 523 216 623 ; C 200 ; WX 333 ; N dieresis ; B 18 523 315 623 ; C 202 ; WX 333 ; N ring ; B 67 512 266 711 ; C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ; C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ; C 207 ; WX 333 ; N caron ; B 11 507 322 674 ; C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ; C 225 ; WX 889 ; N AE ; B 0 0 863 662 ; C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ; C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ; C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ; C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ; C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ; C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ; C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ; C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ; C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ; C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ; C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ; C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ; C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ; C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ; C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ; C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ; C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ; C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ; C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ; C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ; C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ; C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ; C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ; C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ; C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ; C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ; C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ; C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ; C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ; C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ; C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ; C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ; C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ; C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ; C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ; C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ; C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ; C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ; C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ; C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ; C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ; C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ; C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ; C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ; C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ; C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ; C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ; C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ; C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ; C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ; C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ; C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ; C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ; C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ; C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ; C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ; C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ; C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ; C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ; C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ; C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ; C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ; C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ; C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ; C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ; C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ; C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ; C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ; C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ; C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ; C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ; C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ; C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ; C -1 ; WX 564 ; N minus ; B 30 220 534 286 ; C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ; C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ; C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ; C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ; C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ; C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ; C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ; C -1 ; WX 400 ; N degree ; B 57 390 343 676 ; C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ; C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ; C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ; C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ; C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ; C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ; C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ; C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ; EndCharMetrics StartKernData StartKernPairs 283 KPX A y -92 KPX A w -92 KPX A v -74 KPX A u 0 KPX A quoteright -111 KPX A quotedblright 0 KPX A p 0 KPX A Y -105 KPX A W -90 KPX A V -135 KPX A U -55 KPX A T -111 KPX A Q -55 KPX A O -55 KPX A G -40 KPX A C -40 KPX B period 0 KPX B comma 0 KPX B U -10 KPX B A -35 KPX D period 0 KPX D comma 0 KPX D Y -55 KPX D W -30 KPX D V -40 KPX D A -40 KPX F r 0 KPX F period -80 KPX F o -15 KPX F i 0 KPX F e 0 KPX F comma -80 KPX F a -15 KPX F A -74 KPX G period 0 KPX G comma 0 KPX J u 0 KPX J period 0 KPX J o 0 KPX J e 0 KPX J comma 0 KPX J a 0 KPX J A -60 KPX K y -25 KPX K u -15 KPX K o -35 KPX K e -25 KPX K O -30 KPX L y -55 KPX L quoteright -92 KPX L quotedblright 0 KPX L Y -100 KPX L W -74 KPX L V -100 KPX L T -92 KPX N period 0 KPX N comma 0 KPX N A -35 KPX O period 0 KPX O comma 0 KPX O Y -50 KPX O X -40 KPX O W -35 KPX O V -50 KPX O T -40 KPX O A -35 KPX P period -111 KPX P o 0 KPX P e 0 KPX P comma -111 KPX P a -15 KPX P A -92 KPX Q period 0 KPX Q comma 0 KPX Q U -10 KPX R Y -65 KPX R W -55 KPX R V -80 KPX R U -40 KPX R T -60 KPX R O -40 KPX S period 0 KPX S comma 0 KPX T y -80 KPX T w -80 KPX T u -45 KPX T semicolon -55 KPX T r -35 KPX T period -74 KPX T o -80 KPX T i -35 KPX T hyphen -92 KPX T h 0 KPX T e -70 KPX T comma -74 KPX T colon -50 KPX T a -80 KPX T O -18 KPX T A -93 KPX U period 0 KPX U comma 0 KPX U A -40 KPX V u -75 KPX V semicolon -74 KPX V period -129 KPX V o -129 KPX V i -60 KPX V hyphen -100 KPX V e -111 KPX V comma -129 KPX V colon -74 KPX V a -111 KPX V O -40 KPX V G -15 KPX V A -135 KPX W y -73 KPX W u -50 KPX W semicolon -37 KPX W period -92 KPX W o -80 KPX W i -40 KPX W hyphen -65 KPX W h 0 KPX W e -80 KPX W comma -92 KPX W colon -37 KPX W a -80 KPX W O -10 KPX W A -120 KPX Y u -111 KPX Y semicolon -92 KPX Y period -129 KPX Y o -110 KPX Y i -55 KPX Y hyphen -111 KPX Y e -100 KPX Y comma -129 KPX Y colon -92 KPX Y a -100 KPX Y O -30 KPX Y A -120 KPX a y 0 KPX a w -15 KPX a v -20 KPX a t 0 KPX a p 0 KPX a g 0 KPX a b 0 KPX b y 0 KPX b v -15 KPX b u -20 KPX b period -40 KPX b l 0 KPX b comma 0 KPX b b 0 KPX c y -15 KPX c period 0 KPX c l 0 KPX c k 0 KPX c h 0 KPX c comma 0 KPX colon space 0 KPX comma space 0 KPX comma quoteright -70 KPX comma quotedblright -70 KPX d y 0 KPX d w 0 KPX d v 0 KPX d period 0 KPX d d 0 KPX d comma 0 KPX e y -15 KPX e x -15 KPX e w -25 KPX e v -25 KPX e period 0 KPX e p 0 KPX e g -15 KPX e comma 0 KPX e b 0 KPX f quoteright 55 KPX f quotedblright 0 KPX f period 0 KPX f o 0 KPX f l 0 KPX f i -20 KPX f f -25 KPX f e 0 KPX f dotlessi -50 KPX f comma 0 KPX f a -10 KPX g y 0 KPX g r 0 KPX g period 0 KPX g o 0 KPX g i 0 KPX g g 0 KPX g e 0 KPX g comma 0 KPX g a -5 KPX h y -5 KPX i v -25 KPX k y -15 KPX k o -10 KPX k e -10 KPX l y 0 KPX l w -10 KPX m y 0 KPX m u 0 KPX n y -15 KPX n v -40 KPX n u 0 KPX o y -10 KPX o x 0 KPX o w -25 KPX o v -15 KPX o g 0 KPX p y -10 KPX period quoteright -70 KPX period quotedblright -70 KPX quotedblleft quoteleft 0 KPX quotedblleft A -80 KPX quotedblright space 0 KPX quoteleft quoteleft -74 KPX quoteleft A -80 KPX quoteright v -50 KPX quoteright t -18 KPX quoteright space -74 KPX quoteright s -55 KPX quoteright r -50 KPX quoteright quoteright -74 KPX quoteright quotedblright 0 KPX quoteright l -10 KPX quoteright d -50 KPX r y 0 KPX r v 0 KPX r u 0 KPX r t 0 KPX r s 0 KPX r r 0 KPX r q 0 KPX r period -55 KPX r p 0 KPX r o 0 KPX r n 0 KPX r m 0 KPX r l 0 KPX r k 0 KPX r i 0 KPX r hyphen -20 KPX r g -18 KPX r e 0 KPX r d 0 KPX r comma -40 KPX r c 0 KPX r a 0 KPX s w 0 KPX space quoteleft 0 KPX space quotedblleft 0 KPX space Y -90 KPX space W -30 KPX space V -50 KPX space T -18 KPX space A -55 KPX v period -65 KPX v o -20 KPX v e -15 KPX v comma -65 KPX v a -25 KPX w period -65 KPX w o -10 KPX w h 0 KPX w e 0 KPX w comma -65 KPX w a -10 KPX x e -15 KPX y period -65 KPX y o 0 KPX y e 0 KPX y comma -65 KPX y a 0 KPX z o 0 KPX z e 0 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 185 187 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 212 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 212 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 212 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 212 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 212 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 195 212 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 195 212 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 195 212 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 195 212 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 212 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 212 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 212 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 212 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 212 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 212 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 56 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Bookman-Demi.afm������������������������������������������������������0000644�0001750�0001750�00000036325�11462120062�017405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Tue Jan 21 16:13:29 1992 Comment UniqueID 37831 Comment VMusage 31983 38875 FontName Bookman-Demi FullName ITC Bookman Demi FamilyName ITC Bookman Weight Demi ItalicAngle 0 IsFixedPitch false FontBBox -194 -250 1346 934 UnderlinePosition -100 UnderlineThickness 50 Version 001.004 Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 502 Ascender 725 Descender -212 StartCharMetrics 228 C 32 ; WX 340 ; N space ; B 0 0 0 0 ; C 33 ; WX 360 ; N exclam ; B 82 -8 282 698 ; C 34 ; WX 420 ; N quotedbl ; B 11 379 369 698 ; C 35 ; WX 660 ; N numbersign ; B 84 0 576 681 ; C 36 ; WX 660 ; N dollar ; B 48 -119 620 805 ; C 37 ; WX 940 ; N percent ; B 12 -8 924 698 ; C 38 ; WX 800 ; N ampersand ; B 21 -17 772 698 ; C 39 ; WX 320 ; N quoteright ; B 82 440 242 698 ; C 40 ; WX 320 ; N parenleft ; B 48 -150 289 749 ; C 41 ; WX 320 ; N parenright ; B 20 -150 262 749 ; C 42 ; WX 460 ; N asterisk ; B 62 317 405 697 ; C 43 ; WX 600 ; N plus ; B 51 9 555 514 ; C 44 ; WX 340 ; N comma ; B 78 -124 257 162 ; C 45 ; WX 360 ; N hyphen ; B 20 210 340 318 ; C 46 ; WX 340 ; N period ; B 76 -8 258 172 ; C 47 ; WX 600 ; N slash ; B 50 -149 555 725 ; C 48 ; WX 660 ; N zero ; B 30 -17 639 698 ; C 49 ; WX 660 ; N one ; B 137 0 568 681 ; C 50 ; WX 660 ; N two ; B 41 0 628 698 ; C 51 ; WX 660 ; N three ; B 37 -17 631 698 ; C 52 ; WX 660 ; N four ; B 19 0 649 681 ; C 53 ; WX 660 ; N five ; B 44 -17 623 723 ; C 54 ; WX 660 ; N six ; B 34 -17 634 698 ; C 55 ; WX 660 ; N seven ; B 36 0 632 681 ; C 56 ; WX 660 ; N eight ; B 36 -17 633 698 ; C 57 ; WX 660 ; N nine ; B 33 -17 636 698 ; C 58 ; WX 340 ; N colon ; B 76 -8 258 515 ; C 59 ; WX 340 ; N semicolon ; B 75 -124 259 515 ; C 60 ; WX 600 ; N less ; B 49 -9 558 542 ; C 61 ; WX 600 ; N equal ; B 51 109 555 421 ; C 62 ; WX 600 ; N greater ; B 48 -9 557 542 ; C 63 ; WX 660 ; N question ; B 61 -8 608 698 ; C 64 ; WX 820 ; N at ; B 60 -17 758 698 ; C 65 ; WX 720 ; N A ; B -34 0 763 681 ; C 66 ; WX 720 ; N B ; B 20 0 693 681 ; C 67 ; WX 740 ; N C ; B 35 -17 724 698 ; C 68 ; WX 780 ; N D ; B 20 0 748 681 ; C 69 ; WX 720 ; N E ; B 20 0 724 681 ; C 70 ; WX 680 ; N F ; B 20 0 686 681 ; C 71 ; WX 780 ; N G ; B 35 -17 773 698 ; C 72 ; WX 820 ; N H ; B 20 0 800 681 ; C 73 ; WX 400 ; N I ; B 20 0 379 681 ; C 74 ; WX 640 ; N J ; B -12 -17 622 681 ; C 75 ; WX 800 ; N K ; B 20 0 796 681 ; C 76 ; WX 640 ; N L ; B 20 0 668 681 ; C 77 ; WX 940 ; N M ; B 20 0 924 681 ; C 78 ; WX 740 ; N N ; B 20 0 724 681 ; C 79 ; WX 800 ; N O ; B 35 -17 769 698 ; C 80 ; WX 660 ; N P ; B 20 0 658 681 ; C 81 ; WX 800 ; N Q ; B 35 -226 775 698 ; C 82 ; WX 780 ; N R ; B 20 0 783 681 ; C 83 ; WX 660 ; N S ; B 21 -17 639 698 ; C 84 ; WX 700 ; N T ; B -4 0 703 681 ; C 85 ; WX 740 ; N U ; B 15 -17 724 681 ; C 86 ; WX 720 ; N V ; B -20 0 730 681 ; C 87 ; WX 940 ; N W ; B -20 0 963 681 ; C 88 ; WX 780 ; N X ; B 1 0 770 681 ; C 89 ; WX 700 ; N Y ; B -20 0 718 681 ; C 90 ; WX 640 ; N Z ; B 6 0 635 681 ; C 91 ; WX 300 ; N bracketleft ; B 75 -138 285 725 ; C 92 ; WX 600 ; N backslash ; B 50 0 555 725 ; C 93 ; WX 300 ; N bracketright ; B 21 -138 231 725 ; C 94 ; WX 600 ; N asciicircum ; B 52 281 554 681 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 320 ; N quoteleft ; B 82 440 242 698 ; C 97 ; WX 580 ; N a ; B 28 -8 588 515 ; C 98 ; WX 600 ; N b ; B -20 -8 568 725 ; C 99 ; WX 580 ; N c ; B 31 -8 550 515 ; C 100 ; WX 640 ; N d ; B 31 -8 622 725 ; C 101 ; WX 580 ; N e ; B 31 -8 548 515 ; C 102 ; WX 380 ; N f ; B 22 0 461 741 ; L i fi ; L l fl ; C 103 ; WX 580 ; N g ; B 9 -243 583 595 ; C 104 ; WX 680 ; N h ; B 22 0 654 725 ; C 105 ; WX 360 ; N i ; B 22 0 335 729 ; C 106 ; WX 340 ; N j ; B -94 -221 278 729 ; C 107 ; WX 660 ; N k ; B 22 0 643 725 ; C 108 ; WX 340 ; N l ; B 9 0 322 725 ; C 109 ; WX 1000 ; N m ; B 22 0 980 515 ; C 110 ; WX 680 ; N n ; B 22 0 652 515 ; C 111 ; WX 620 ; N o ; B 31 -8 585 515 ; C 112 ; WX 640 ; N p ; B 22 -212 611 515 ; C 113 ; WX 620 ; N q ; B 31 -212 633 515 ; C 114 ; WX 460 ; N r ; B 22 0 462 502 ; C 115 ; WX 520 ; N s ; B 22 -8 492 515 ; C 116 ; WX 460 ; N t ; B 22 -8 445 660 ; C 117 ; WX 660 ; N u ; B 22 -8 653 502 ; C 118 ; WX 600 ; N v ; B -6 0 593 502 ; C 119 ; WX 800 ; N w ; B -6 0 810 502 ; C 120 ; WX 600 ; N x ; B 8 0 591 502 ; C 121 ; WX 620 ; N y ; B 6 -221 613 502 ; C 122 ; WX 560 ; N z ; B 22 0 547 502 ; C 123 ; WX 320 ; N braceleft ; B 14 -139 301 726 ; C 124 ; WX 600 ; N bar ; B 243 -250 362 750 ; C 125 ; WX 320 ; N braceright ; B 15 -140 302 725 ; C 126 ; WX 600 ; N asciitilde ; B 51 162 555 368 ; C 161 ; WX 360 ; N exclamdown ; B 84 -191 284 515 ; C 162 ; WX 660 ; N cent ; B 133 17 535 674 ; C 163 ; WX 660 ; N sterling ; B 10 -17 659 698 ; C 164 ; WX 120 ; N fraction ; B -194 0 312 681 ; C 165 ; WX 660 ; N yen ; B -28 0 696 681 ; C 166 ; WX 660 ; N florin ; B -46 -209 674 749 ; C 167 ; WX 600 ; N section ; B 36 -153 560 698 ; C 168 ; WX 660 ; N currency ; B 77 88 584 593 ; C 169 ; WX 240 ; N quotesingle ; B 42 379 178 698 ; C 170 ; WX 540 ; N quotedblleft ; B 82 439 449 698 ; C 171 ; WX 400 ; N guillemotleft ; B 34 101 360 457 ; C 172 ; WX 220 ; N guilsinglleft ; B 34 101 188 457 ; C 173 ; WX 220 ; N guilsinglright ; B 34 101 188 457 ; C 174 ; WX 740 ; N fi ; B 22 0 710 741 ; C 175 ; WX 740 ; N fl ; B 22 0 710 741 ; C 177 ; WX 500 ; N endash ; B -25 212 525 318 ; C 178 ; WX 440 ; N dagger ; B 33 -156 398 698 ; C 179 ; WX 380 ; N daggerdbl ; B 8 -156 380 698 ; C 180 ; WX 340 ; N periodcentered ; B 76 175 258 355 ; C 182 ; WX 800 ; N paragraph ; B 51 0 698 681 ; C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ; C 184 ; WX 320 ; N quotesinglbase ; B 82 -114 242 144 ; C 185 ; WX 540 ; N quotedblbase ; B 82 -114 450 144 ; C 186 ; WX 540 ; N quotedblright ; B 82 440 449 698 ; C 187 ; WX 400 ; N guillemotright ; B 34 101 360 457 ; C 188 ; WX 1000 ; N ellipsis ; B 76 -8 924 172 ; C 189 ; WX 1360 ; N perthousand ; B 12 -8 1346 698 ; C 191 ; WX 660 ; N questiondown ; B 62 -191 609 515 ; C 193 ; WX 400 ; N grave ; B 68 547 327 730 ; C 194 ; WX 400 ; N acute ; B 68 547 327 731 ; C 195 ; WX 500 ; N circumflex ; B 68 555 430 731 ; C 196 ; WX 480 ; N tilde ; B 69 556 421 691 ; C 197 ; WX 460 ; N macron ; B 68 577 383 663 ; C 198 ; WX 500 ; N breve ; B 68 553 429 722 ; C 199 ; WX 320 ; N dotaccent ; B 68 536 259 730 ; C 200 ; WX 500 ; N dieresis ; B 68 560 441 698 ; C 202 ; WX 340 ; N ring ; B 68 552 275 755 ; C 203 ; WX 360 ; N cedilla ; B 68 -213 284 0 ; C 205 ; WX 440 ; N hungarumlaut ; B 68 554 365 741 ; C 206 ; WX 320 ; N ogonek ; B 68 -163 246 0 ; C 207 ; WX 500 ; N caron ; B 68 541 430 717 ; C 208 ; WX 1000 ; N emdash ; B -25 212 1025 318 ; C 225 ; WX 1140 ; N AE ; B -34 0 1149 681 ; C 227 ; WX 400 ; N ordfeminine ; B 27 383 396 698 ; C 232 ; WX 640 ; N Lslash ; B 20 0 668 681 ; C 233 ; WX 800 ; N Oslash ; B 35 -110 771 781 ; C 234 ; WX 1220 ; N OE ; B 35 -17 1219 698 ; C 235 ; WX 400 ; N ordmasculine ; B 17 383 383 698 ; C 241 ; WX 880 ; N ae ; B 28 -8 852 515 ; C 245 ; WX 360 ; N dotlessi ; B 22 0 335 502 ; C 248 ; WX 340 ; N lslash ; B 9 0 322 725 ; C 249 ; WX 620 ; N oslash ; B 31 -40 586 551 ; C 250 ; WX 940 ; N oe ; B 31 -8 908 515 ; C 251 ; WX 660 ; N germandbls ; B -61 -91 644 699 ; C -1 ; WX 580 ; N ecircumflex ; B 31 -8 548 731 ; C -1 ; WX 580 ; N edieresis ; B 31 -8 548 698 ; C -1 ; WX 580 ; N aacute ; B 28 -8 588 731 ; C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ; C -1 ; WX 360 ; N icircumflex ; B -2 0 360 731 ; C -1 ; WX 660 ; N udieresis ; B 22 -8 653 698 ; C -1 ; WX 620 ; N ograve ; B 31 -8 585 730 ; C -1 ; WX 660 ; N uacute ; B 22 -8 653 731 ; C -1 ; WX 660 ; N ucircumflex ; B 22 -8 653 731 ; C -1 ; WX 720 ; N Aacute ; B -34 0 763 910 ; C -1 ; WX 360 ; N igrave ; B 22 0 335 730 ; C -1 ; WX 400 ; N Icircumflex ; B 18 0 380 910 ; C -1 ; WX 580 ; N ccedilla ; B 31 -213 550 515 ; C -1 ; WX 580 ; N adieresis ; B 28 -8 588 698 ; C -1 ; WX 720 ; N Ecircumflex ; B 20 0 724 910 ; C -1 ; WX 520 ; N scaron ; B 22 -8 492 717 ; C -1 ; WX 640 ; N thorn ; B 22 -212 611 725 ; C -1 ; WX 980 ; N trademark ; B 42 277 982 681 ; C -1 ; WX 580 ; N egrave ; B 31 -8 548 730 ; C -1 ; WX 396 ; N threesuperior ; B 5 269 391 698 ; C -1 ; WX 560 ; N zcaron ; B 22 0 547 717 ; C -1 ; WX 580 ; N atilde ; B 28 -8 588 691 ; C -1 ; WX 580 ; N aring ; B 28 -8 588 755 ; C -1 ; WX 620 ; N ocircumflex ; B 31 -8 585 731 ; C -1 ; WX 720 ; N Edieresis ; B 20 0 724 877 ; C -1 ; WX 990 ; N threequarters ; B 15 0 967 692 ; C -1 ; WX 620 ; N ydieresis ; B 6 -221 613 698 ; C -1 ; WX 620 ; N yacute ; B 6 -221 613 731 ; C -1 ; WX 360 ; N iacute ; B 22 0 335 731 ; C -1 ; WX 720 ; N Acircumflex ; B -34 0 763 910 ; C -1 ; WX 740 ; N Uacute ; B 15 -17 724 910 ; C -1 ; WX 580 ; N eacute ; B 31 -8 548 731 ; C -1 ; WX 800 ; N Ograve ; B 35 -17 769 909 ; C -1 ; WX 580 ; N agrave ; B 28 -8 588 730 ; C -1 ; WX 740 ; N Udieresis ; B 15 -17 724 877 ; C -1 ; WX 580 ; N acircumflex ; B 28 -8 588 731 ; C -1 ; WX 400 ; N Igrave ; B 20 0 379 909 ; C -1 ; WX 396 ; N twosuperior ; B 14 279 396 698 ; C -1 ; WX 740 ; N Ugrave ; B 15 -17 724 909 ; C -1 ; WX 990 ; N onequarter ; B 65 0 967 681 ; C -1 ; WX 740 ; N Ucircumflex ; B 15 -17 724 910 ; C -1 ; WX 660 ; N Scaron ; B 21 -17 639 896 ; C -1 ; WX 400 ; N Idieresis ; B 18 0 391 877 ; C -1 ; WX 360 ; N idieresis ; B -2 0 371 698 ; C -1 ; WX 720 ; N Egrave ; B 20 0 724 909 ; C -1 ; WX 800 ; N Oacute ; B 35 -17 769 910 ; C -1 ; WX 600 ; N divide ; B 51 9 555 521 ; C -1 ; WX 720 ; N Atilde ; B -34 0 763 870 ; C -1 ; WX 720 ; N Aring ; B -34 0 763 934 ; C -1 ; WX 800 ; N Odieresis ; B 35 -17 769 877 ; C -1 ; WX 720 ; N Adieresis ; B -34 0 763 877 ; C -1 ; WX 740 ; N Ntilde ; B 20 0 724 870 ; C -1 ; WX 640 ; N Zcaron ; B 6 0 635 896 ; C -1 ; WX 660 ; N Thorn ; B 20 0 658 681 ; C -1 ; WX 400 ; N Iacute ; B 20 0 379 910 ; C -1 ; WX 600 ; N plusminus ; B 51 0 555 514 ; C -1 ; WX 600 ; N multiply ; B 48 10 552 514 ; C -1 ; WX 720 ; N Eacute ; B 20 0 724 910 ; C -1 ; WX 700 ; N Ydieresis ; B -20 0 718 877 ; C -1 ; WX 396 ; N onesuperior ; B 65 279 345 687 ; C -1 ; WX 660 ; N ugrave ; B 22 -8 653 730 ; C -1 ; WX 600 ; N logicalnot ; B 51 129 555 421 ; C -1 ; WX 680 ; N ntilde ; B 22 0 652 691 ; C -1 ; WX 800 ; N Otilde ; B 35 -17 769 870 ; C -1 ; WX 620 ; N otilde ; B 31 -8 585 691 ; C -1 ; WX 740 ; N Ccedilla ; B 35 -213 724 698 ; C -1 ; WX 720 ; N Agrave ; B -34 0 763 909 ; C -1 ; WX 990 ; N onehalf ; B 65 0 980 681 ; C -1 ; WX 780 ; N Eth ; B 20 0 748 681 ; C -1 ; WX 400 ; N degree ; B 50 398 350 698 ; C -1 ; WX 700 ; N Yacute ; B -20 0 718 910 ; C -1 ; WX 800 ; N Ocircumflex ; B 35 -17 769 910 ; C -1 ; WX 620 ; N oacute ; B 31 -8 585 731 ; C -1 ; WX 660 ; N mu ; B 22 -221 653 502 ; C -1 ; WX 600 ; N minus ; B 51 207 555 323 ; C -1 ; WX 620 ; N eth ; B 31 -8 585 741 ; C -1 ; WX 620 ; N odieresis ; B 31 -8 585 698 ; C -1 ; WX 740 ; N copyright ; B 23 -17 723 698 ; C -1 ; WX 600 ; N brokenbar ; B 243 -175 362 675 ; EndCharMetrics StartKernData StartKernPairs 90 KPX A y -1 KPX A w -9 KPX A v -8 KPX A Y -52 KPX A W -20 KPX A V -68 KPX A T -40 KPX F period -132 KPX F comma -130 KPX F A -59 KPX L y 19 KPX L Y -35 KPX L W -41 KPX L V -50 KPX L T -4 KPX P period -128 KPX P comma -129 KPX P A -46 KPX R y -8 KPX R Y -20 KPX R W -24 KPX R V -29 KPX R T -4 KPX T semicolon 5 KPX T s -10 KPX T r 27 KPX T period -122 KPX T o -28 KPX T i 27 KPX T hyphen -10 KPX T e -29 KPX T comma -122 KPX T colon 7 KPX T c -29 KPX T a -24 KPX T A -42 KPX V y 12 KPX V u -11 KPX V semicolon -38 KPX V r -15 KPX V period -105 KPX V o -79 KPX V i 15 KPX V hyphen -10 KPX V e -80 KPX V comma -103 KPX V colon -37 KPX V a -74 KPX V A -88 KPX W y 12 KPX W u -11 KPX W semicolon -38 KPX W r -15 KPX W period -105 KPX W o -78 KPX W i 15 KPX W hyphen -10 KPX W e -79 KPX W comma -103 KPX W colon -37 KPX W a -73 KPX W A -60 KPX Y v 24 KPX Y u -13 KPX Y semicolon -34 KPX Y q -66 KPX Y period -105 KPX Y p -23 KPX Y o -66 KPX Y i 2 KPX Y hyphen -10 KPX Y e -67 KPX Y comma -103 KPX Y colon -32 KPX Y a -60 KPX Y A -56 KPX f f 21 KPX r q -9 KPX r period -102 KPX r o -9 KPX r n 20 KPX r m 20 KPX r hyphen -10 KPX r h -23 KPX r g -9 KPX r f 20 KPX r e -10 KPX r d -10 KPX r comma -101 KPX r c -9 EndKernPairs EndKernData StartComposites 56 CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 179 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 110 179 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 110 179 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 179 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 190 179 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 179 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 179 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 110 179 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 110 179 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 179 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 179 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -50 179 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -50 179 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 179 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 179 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 179 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 179 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 150 179 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 179 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 160 179 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 80 179 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 170 179 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 120 179 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 120 179 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 179 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 179 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 100 179 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 179 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 90 0 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 40 0 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 40 0 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 90 0 ; CC aring 2 ; PCC a 0 0 ; PCC ring 100 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 30 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 40 0 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -70 0 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -70 0 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 0 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 60 0 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 50 0 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 10 0 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 130 0 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 80 0 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 130 0 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 110 0 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ; EndComposites EndFontMetrics �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/afm/Palatino-BoldItalic.afm�����������������������������������������������0000644�0001750�0001750�00000037574�11462120062�020725� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������StartFontMetrics 2.0 Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jul 2 22:48:39 1990 Comment UniqueID 31799 Comment VMusage 37656 48548 FontName Palatino-BoldItalic FullName Palatino Bold Italic FamilyName Palatino Weight Bold ItalicAngle -10 IsFixedPitch false FontBBox -170 -271 1073 926 UnderlinePosition -100 UnderlineThickness 50 Version 001.005 Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 681 XHeight 469 Ascender 726 Descender -271 StartCharMetrics 228 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 58 -17 322 695 ; C 34 ; WX 500 ; N quotedbl ; B 137 467 493 720 ; C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ; C 36 ; WX 500 ; N dollar ; B 20 -108 477 737 ; C 37 ; WX 889 ; N percent ; B 56 -17 790 697 ; C 38 ; WX 833 ; N ampersand ; B 74 -17 811 695 ; C 39 ; WX 278 ; N quoteright ; B 76 431 302 720 ; C 40 ; WX 333 ; N parenleft ; B 58 -129 368 723 ; C 41 ; WX 333 ; N parenright ; B -12 -129 298 723 ; C 42 ; WX 444 ; N asterisk ; B 84 332 439 695 ; C 43 ; WX 606 ; N plus ; B 50 -5 556 501 ; C 44 ; WX 250 ; N comma ; B -33 -164 208 147 ; C 45 ; WX 389 ; N hyphen ; B 37 198 362 300 ; C 46 ; WX 250 ; N period ; B 48 -17 187 135 ; C 47 ; WX 315 ; N slash ; B 1 -17 315 720 ; C 48 ; WX 500 ; N zero ; B 42 -17 490 683 ; C 49 ; WX 500 ; N one ; B 41 -3 434 678 ; C 50 ; WX 500 ; N two ; B 1 -3 454 683 ; C 51 ; WX 500 ; N three ; B 8 -17 450 683 ; C 52 ; WX 500 ; N four ; B 3 -3 487 683 ; C 53 ; WX 500 ; N five ; B 14 -17 481 675 ; C 54 ; WX 500 ; N six ; B 39 -17 488 683 ; C 55 ; WX 500 ; N seven ; B 69 -3 544 674 ; C 56 ; WX 500 ; N eight ; B 26 -17 484 683 ; C 57 ; WX 500 ; N nine ; B 27 -17 491 683 ; C 58 ; WX 250 ; N colon ; B 38 -17 236 452 ; C 59 ; WX 250 ; N semicolon ; B -33 -164 247 452 ; C 60 ; WX 606 ; N less ; B 49 -21 558 517 ; C 61 ; WX 606 ; N equal ; B 51 106 555 390 ; C 62 ; WX 606 ; N greater ; B 48 -21 557 517 ; C 63 ; WX 444 ; N question ; B 91 -17 450 695 ; C 64 ; WX 833 ; N at ; B 82 -12 744 681 ; C 65 ; WX 722 ; N A ; B -35 -3 685 683 ; C 66 ; WX 667 ; N B ; B 8 -3 629 681 ; C 67 ; WX 685 ; N C ; B 69 -17 695 695 ; C 68 ; WX 778 ; N D ; B 0 -3 747 682 ; C 69 ; WX 611 ; N E ; B 11 -3 606 681 ; C 70 ; WX 556 ; N F ; B -6 -3 593 681 ; C 71 ; WX 778 ; N G ; B 72 -17 750 695 ; C 72 ; WX 778 ; N H ; B -12 -3 826 681 ; C 73 ; WX 389 ; N I ; B -1 -3 412 681 ; C 74 ; WX 389 ; N J ; B -29 -207 417 681 ; C 75 ; WX 722 ; N K ; B -10 -3 746 681 ; C 76 ; WX 611 ; N L ; B 26 -3 578 681 ; C 77 ; WX 944 ; N M ; B -23 -17 985 681 ; C 78 ; WX 778 ; N N ; B -2 -3 829 681 ; C 79 ; WX 833 ; N O ; B 76 -17 794 695 ; C 80 ; WX 667 ; N P ; B 11 -3 673 681 ; C 81 ; WX 833 ; N Q ; B 76 -222 794 695 ; C 82 ; WX 722 ; N R ; B 4 -3 697 681 ; C 83 ; WX 556 ; N S ; B 50 -17 517 695 ; C 84 ; WX 611 ; N T ; B 56 -3 674 681 ; C 85 ; WX 778 ; N U ; B 83 -17 825 681 ; C 86 ; WX 667 ; N V ; B 67 -3 745 681 ; C 87 ; WX 1000 ; N W ; B 67 -3 1073 689 ; C 88 ; WX 722 ; N X ; B -9 -3 772 681 ; C 89 ; WX 611 ; N Y ; B 54 -3 675 695 ; C 90 ; WX 667 ; N Z ; B 1 -3 676 681 ; C 91 ; WX 333 ; N bracketleft ; B 45 -102 381 723 ; C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ; C 93 ; WX 333 ; N bracketright ; B -21 -102 315 723 ; C 94 ; WX 606 ; N asciicircum ; B 63 275 543 678 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 278 ; N quoteleft ; B 65 431 291 720 ; C 97 ; WX 556 ; N a ; B 44 -17 519 470 ; C 98 ; WX 537 ; N b ; B 44 -17 494 726 ; C 99 ; WX 444 ; N c ; B 32 -17 436 469 ; C 100 ; WX 556 ; N d ; B 38 -17 550 726 ; C 101 ; WX 444 ; N e ; B 28 -17 418 469 ; C 102 ; WX 333 ; N f ; B -130 -271 449 726 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B -50 -271 529 469 ; C 104 ; WX 556 ; N h ; B 22 -17 522 726 ; C 105 ; WX 333 ; N i ; B 26 -17 312 695 ; C 106 ; WX 333 ; N j ; B -64 -271 323 695 ; C 107 ; WX 556 ; N k ; B 34 -17 528 726 ; C 108 ; WX 333 ; N l ; B 64 -17 318 726 ; C 109 ; WX 833 ; N m ; B 19 -17 803 469 ; C 110 ; WX 556 ; N n ; B 17 -17 521 469 ; C 111 ; WX 556 ; N o ; B 48 -17 502 469 ; C 112 ; WX 556 ; N p ; B -21 -271 516 469 ; C 113 ; WX 537 ; N q ; B 32 -271 513 469 ; C 114 ; WX 389 ; N r ; B 20 -17 411 469 ; C 115 ; WX 444 ; N s ; B 25 -17 406 469 ; C 116 ; WX 389 ; N t ; B 42 -17 409 636 ; C 117 ; WX 556 ; N u ; B 22 -17 521 469 ; C 118 ; WX 556 ; N v ; B 19 -17 513 469 ; C 119 ; WX 833 ; N w ; B 27 -17 802 469 ; C 120 ; WX 500 ; N x ; B -8 -17 500 469 ; C 121 ; WX 556 ; N y ; B 13 -271 541 469 ; C 122 ; WX 500 ; N z ; B 31 -17 470 469 ; C 123 ; WX 333 ; N braceleft ; B 18 -105 334 720 ; C 124 ; WX 606 ; N bar ; B 259 0 347 720 ; C 125 ; WX 333 ; N braceright ; B -1 -105 315 720 ; C 126 ; WX 606 ; N asciitilde ; B 51 151 555 346 ; C 161 ; WX 333 ; N exclamdown ; B 2 -225 259 479 ; C 162 ; WX 500 ; N cent ; B 52 -105 456 547 ; C 163 ; WX 500 ; N sterling ; B 21 -5 501 683 ; C 164 ; WX 167 ; N fraction ; B -170 0 338 683 ; C 165 ; WX 500 ; N yen ; B 11 -3 538 695 ; C 166 ; WX 500 ; N florin ; B 8 -242 479 690 ; C 167 ; WX 556 ; N section ; B 47 -151 497 695 ; C 168 ; WX 500 ; N currency ; B 32 96 468 533 ; C 169 ; WX 250 ; N quotesingle ; B 127 467 293 720 ; C 170 ; WX 500 ; N quotedblleft ; B 65 431 511 720 ; C 171 ; WX 500 ; N guillemotleft ; B 35 43 458 446 ; C 172 ; WX 333 ; N guilsinglleft ; B 60 43 292 446 ; C 173 ; WX 333 ; N guilsinglright ; B 35 40 267 443 ; C 174 ; WX 611 ; N fi ; B -130 -271 588 726 ; C 175 ; WX 611 ; N fl ; B -130 -271 631 726 ; C 177 ; WX 500 ; N endash ; B -12 214 512 282 ; C 178 ; WX 556 ; N dagger ; B 67 -3 499 685 ; C 179 ; WX 556 ; N daggerdbl ; B 33 -153 537 693 ; C 180 ; WX 250 ; N periodcentered ; B 67 172 206 324 ; C 182 ; WX 556 ; N paragraph ; B 14 -204 629 681 ; C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ; C 184 ; WX 250 ; N quotesinglbase ; B -3 -144 220 145 ; C 185 ; WX 500 ; N quotedblbase ; B -18 -144 424 145 ; C 186 ; WX 500 ; N quotedblright ; B 73 431 519 720 ; C 187 ; WX 500 ; N guillemotright ; B 35 40 458 443 ; C 188 ; WX 1000 ; N ellipsis ; B 91 -17 896 135 ; C 189 ; WX 1000 ; N perthousand ; B 65 -17 912 691 ; C 191 ; WX 444 ; N questiondown ; B -12 -226 347 479 ; C 193 ; WX 333 ; N grave ; B 110 518 322 699 ; C 194 ; WX 333 ; N acute ; B 153 518 392 699 ; C 195 ; WX 333 ; N circumflex ; B 88 510 415 684 ; C 196 ; WX 333 ; N tilde ; B 82 535 441 654 ; C 197 ; WX 333 ; N macron ; B 76 538 418 608 ; C 198 ; WX 333 ; N breve ; B 96 518 412 680 ; C 199 ; WX 333 ; N dotaccent ; B 202 537 325 668 ; C 200 ; WX 333 ; N dieresis ; B 90 537 426 668 ; C 202 ; WX 556 ; N ring ; B 277 514 477 714 ; C 203 ; WX 333 ; N cedilla ; B 12 -218 248 5 ; C 205 ; WX 333 ; N hungarumlaut ; B -28 518 409 699 ; C 206 ; WX 333 ; N ogonek ; B 32 -206 238 -17 ; C 207 ; WX 333 ; N caron ; B 113 510 445 684 ; C 208 ; WX 1000 ; N emdash ; B -12 214 1012 282 ; C 225 ; WX 944 ; N AE ; B -29 -3 927 681 ; C 227 ; WX 333 ; N ordfeminine ; B 47 391 355 684 ; C 232 ; WX 611 ; N Lslash ; B 6 -3 578 681 ; C 233 ; WX 833 ; N Oslash ; B 57 -54 797 730 ; C 234 ; WX 944 ; N OE ; B 39 -17 961 695 ; C 235 ; WX 333 ; N ordmasculine ; B 51 391 346 683 ; C 241 ; WX 738 ; N ae ; B 44 -17 711 469 ; C 245 ; WX 333 ; N dotlessi ; B 26 -17 293 469 ; C 248 ; WX 333 ; N lslash ; B 13 -17 365 726 ; C 249 ; WX 556 ; N oslash ; B 14 -50 522 506 ; C 250 ; WX 778 ; N oe ; B 48 -17 755 469 ; C 251 ; WX 556 ; N germandbls ; B -131 -271 549 726 ; C -1 ; WX 667 ; N Zcaron ; B 1 -3 676 896 ; C -1 ; WX 444 ; N ccedilla ; B 32 -218 436 469 ; C -1 ; WX 556 ; N ydieresis ; B 13 -271 541 688 ; C -1 ; WX 556 ; N atilde ; B 44 -17 553 666 ; C -1 ; WX 333 ; N icircumflex ; B 26 -17 403 704 ; C -1 ; WX 300 ; N threesuperior ; B 23 263 310 683 ; C -1 ; WX 444 ; N ecircumflex ; B 28 -17 471 704 ; C -1 ; WX 556 ; N thorn ; B -21 -271 516 726 ; C -1 ; WX 444 ; N egrave ; B 28 -17 418 719 ; C -1 ; WX 300 ; N twosuperior ; B 26 271 321 683 ; C -1 ; WX 444 ; N eacute ; B 28 -17 448 719 ; C -1 ; WX 556 ; N otilde ; B 48 -17 553 666 ; C -1 ; WX 722 ; N Aacute ; B -35 -3 685 911 ; C -1 ; WX 556 ; N ocircumflex ; B 48 -17 515 704 ; C -1 ; WX 556 ; N yacute ; B 13 -271 541 719 ; C -1 ; WX 556 ; N udieresis ; B 22 -17 538 688 ; C -1 ; WX 750 ; N threequarters ; B 18 -2 732 683 ; C -1 ; WX 556 ; N acircumflex ; B 44 -17 527 704 ; C -1 ; WX 778 ; N Eth ; B 0 -3 747 682 ; C -1 ; WX 444 ; N edieresis ; B 28 -17 482 688 ; C -1 ; WX 556 ; N ugrave ; B 22 -17 521 719 ; C -1 ; WX 1000 ; N trademark ; B 38 274 961 678 ; C -1 ; WX 556 ; N ograve ; B 48 -17 502 719 ; C -1 ; WX 444 ; N scaron ; B 25 -17 489 692 ; C -1 ; WX 389 ; N Idieresis ; B -1 -3 454 880 ; C -1 ; WX 556 ; N uacute ; B 22 -17 521 719 ; C -1 ; WX 556 ; N agrave ; B 44 -17 519 719 ; C -1 ; WX 556 ; N ntilde ; B 17 -17 553 666 ; C -1 ; WX 556 ; N aring ; B 44 -17 519 714 ; C -1 ; WX 500 ; N zcaron ; B 31 -17 517 692 ; C -1 ; WX 389 ; N Icircumflex ; B -1 -3 443 896 ; C -1 ; WX 778 ; N Ntilde ; B -2 -3 829 866 ; C -1 ; WX 556 ; N ucircumflex ; B 22 -17 521 704 ; C -1 ; WX 611 ; N Ecircumflex ; B 11 -3 606 896 ; C -1 ; WX 389 ; N Iacute ; B -1 -3 420 911 ; C -1 ; WX 685 ; N Ccedilla ; B 69 -218 695 695 ; C -1 ; WX 833 ; N Odieresis ; B 76 -17 794 880 ; C -1 ; WX 556 ; N Scaron ; B 50 -17 557 896 ; C -1 ; WX 611 ; N Edieresis ; B 11 -3 606 880 ; C -1 ; WX 389 ; N Igrave ; B -1 -3 412 911 ; C -1 ; WX 556 ; N adieresis ; B 44 -17 538 688 ; C -1 ; WX 833 ; N Ograve ; B 76 -17 794 911 ; C -1 ; WX 611 ; N Egrave ; B 11 -3 606 911 ; C -1 ; WX 611 ; N Ydieresis ; B 54 -3 675 880 ; C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ; C -1 ; WX 833 ; N Otilde ; B 76 -17 794 866 ; C -1 ; WX 750 ; N onequarter ; B 18 -2 732 683 ; C -1 ; WX 778 ; N Ugrave ; B 83 -17 825 911 ; C -1 ; WX 778 ; N Ucircumflex ; B 83 -17 825 896 ; C -1 ; WX 667 ; N Thorn ; B 11 -3 644 681 ; C -1 ; WX 606 ; N divide ; B 50 -5 556 501 ; C -1 ; WX 722 ; N Atilde ; B -35 -3 685 866 ; C -1 ; WX 778 ; N Uacute ; B 83 -17 825 911 ; C -1 ; WX 833 ; N Ocircumflex ; B 76 -17 794 896 ; C -1 ; WX 606 ; N logicalnot ; B 51 107 555 390 ; C -1 ; WX 722 ; N Aring ; B -35 -3 685 926 ; C -1 ; WX 333 ; N idieresis ; B 26 -17 426 688 ; C -1 ; WX 333 ; N iacute ; B 26 -17 392 719 ; C -1 ; WX 556 ; N aacute ; B 44 -17 519 719 ; C -1 ; WX 606 ; N plusminus ; B 50 0 556 501 ; C -1 ; WX 606 ; N multiply ; B 72 17 534 479 ; C -1 ; WX 778 ; N Udieresis ; B 83 -17 825 880 ; C -1 ; WX 606 ; N minus ; B 51 204 555 292 ; C -1 ; WX 300 ; N onesuperior ; B 41 271 298 680 ; C -1 ; WX 611 ; N Eacute ; B 11 -3 606 911 ; C -1 ; WX 722 ; N Acircumflex ; B -35 -3 685 896 ; C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ; C -1 ; WX 722 ; N Agrave ; B -35 -3 685 911 ; C -1 ; WX 556 ; N odieresis ; B 48 -17 538 688 ; C -1 ; WX 556 ; N oacute ; B 48 -17 504 719 ; C -1 ; WX 400 ; N degree ; B 50 383 350 683 ; C -1 ; WX 333 ; N igrave ; B 26 -17 322 719 ; C -1 ; WX 556 ; N mu ; B -15 -232 521 469 ; C -1 ; WX 833 ; N Oacute ; B 76 -17 794 911 ; C -1 ; WX 556 ; N eth ; B 48 -17 546 726 ; C -1 ; WX 722 ; N Adieresis ; B -35 -3 685 880 ; C -1 ; WX 611 ; N Yacute ; B 54 -3 675 911 ; C -1 ; WX 606 ; N brokenbar ; B 259 0 347 720 ; C -1 ; WX 750 ; N onehalf ; B 14 -2 736 683 ; EndCharMetrics StartKernData StartKernPairs 108 KPX A y -55 KPX A w -37 KPX A v -55 KPX A space -55 KPX A quoteright -55 KPX A Y -74 KPX A W -74 KPX A V -74 KPX A T -55 KPX F space -18 KPX F period -111 KPX F comma -111 KPX F A -74 KPX L y -37 KPX L space -18 KPX L quoteright -55 KPX L Y -74 KPX L W -74 KPX L V -74 KPX L T -74 KPX P space -55 KPX P period -129 KPX P comma -129 KPX P A -92 KPX R y -20 KPX R Y -37 KPX R W -55 KPX R V -55 KPX R T -37 KPX T y -80 KPX T w -50 KPX T u -92 KPX T semicolon -55 KPX T s -92 KPX T r -92 KPX T period -55 KPX T o -111 KPX T i -74 KPX T hyphen -92 KPX T e -111 KPX T comma -55 KPX T colon -55 KPX T c -92 KPX T a -111 KPX T O -18 KPX T A -55 KPX V y -50 KPX V u -50 KPX V semicolon -37 KPX V r -74 KPX V period -111 KPX V o -74 KPX V i -50 KPX V hyphen -37 KPX V e -74 KPX V comma -111 KPX V colon -37 KPX V a -92 KPX V A -74 KPX W y -30 KPX W u -30 KPX W semicolon -18 KPX W r -30 KPX W period -55 KPX W o -55 KPX W i -30 KPX W e -55 KPX W comma -55 KPX W colon -28 KPX W a -74 KPX W A -74 KPX Y v -30 KPX Y u -50 KPX Y semicolon -55 KPX Y q -92 KPX Y period -55 KPX Y p -74 KPX Y o -111 KPX Y i -54 KPX Y hyphen -55 KPX Y e -92 KPX Y comma -55 KPX Y colon -55 KPX Y a -111 KPX Y A -55 KPX f quoteright 37 KPX f f -37 KPX one one -55 KPX quoteleft quoteleft -55 KPX quoteright t -18 KPX quoteright space -37 KPX quoteright s -37 KPX quoteright quoteright -55 KPX r quoteright 55 KPX r q -18 KPX r period -55 KPX r o -18 KPX r h -18 KPX r g -18 KPX r e -18 KPX r comma -55 KPX r c -18 KPX v period -55 KPX v comma -55 KPX w period -55 KPX w comma -55 KPX y period -37 KPX y comma -37 EndKernPairs EndKernData StartComposites 58 CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ; CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ; CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ; CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ; CC Aring 2 ; PCC A 0 0 ; PCC ring 83 212 ; CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ; CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ; CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ; CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ; CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ; CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ; CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 212 ; CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 212 ; CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 212 ; CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 212 ; CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 223 212 ; CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 212 ; CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 212 ; CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 212 ; CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 212 ; CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 212 ; CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ; CC Uacute 2 ; PCC U 0 0 ; PCC acute 223 212 ; CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 223 212 ; CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 212 ; CC Ugrave 2 ; PCC U 0 0 ; PCC grave 211 212 ; CC Yacute 2 ; PCC Y 0 0 ; PCC acute 151 212 ; CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 212 ; CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 212 ; CC aacute 2 ; PCC a 0 0 ; PCC acute 112 20 ; CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 20 ; CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 20 ; CC agrave 2 ; PCC a 0 0 ; PCC grave 112 20 ; CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ; CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 12 ; CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ; CC eacute 2 ; PCC e 0 0 ; PCC acute 56 20 ; CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 20 ; CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 20 ; CC egrave 2 ; PCC e 0 0 ; PCC grave 56 20 ; CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ; CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -12 20 ; CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ; CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ; CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ; CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ; CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 100 20 ; CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ; CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ; CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ; CC scaron 2 ; PCC s 0 0 ; PCC caron 44 8 ; CC uacute 2 ; PCC u 0 0 ; PCC acute 112 20 ; CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 20 ; CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ; CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 20 ; CC yacute 2 ; PCC y 0 0 ; PCC acute 112 20 ; CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ; CC zcaron 2 ; PCC z 0 0 ; PCC caron 72 8 ; EndComposites EndFontMetrics ������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/bltGraph.pro��������������������������������������������������������������0000644�0001750�0001750�00000031310�11462120062�016165� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� %%BeginProlog % % PostScript prolog file of the BLT graph widget. % % Copyright 1989-1992 Regents of the University of California. % Permission to use, copy, modify, and distribute this % software and its documentation for any purpose and without % fee is hereby granted, provided that the above copyright % notice appear in all copies. The University of California % makes no representations about the suitability of this % software for any purpose. It is provided "as is" without % express or implied warranty. % % Copyright 1991-1997 Bell Labs Innovations for Lucent Technologies. % % Permission to use, copy, modify, and distribute this software and its % documentation for any purpose and without fee is hereby granted, provided % that the above copyright notice appear in all copies and that both that the % copyright notice and warranty disclaimer appear in supporting documentation, % and that the names of Lucent Technologies any of their entities not be used % in advertising or publicity pertaining to distribution of the software % without specific, written prior permission. % % Lucent Technologies disclaims all warranties with regard to this software, % including all implied warranties of merchantability and fitness. In no event % shall Lucent Technologies be liable for any special, indirect or % consequential damages or any damages whatsoever resulting from loss of use, % data or profits, whether in an action of contract, negligence or other % tortuous action, arising out of or in connection with the use or performance % of this software. % 200 dict begin /BaseRatio 1.3467736870885982 def % Ratio triangle base / symbol size /BgColorProc 0 def % Background color routine (symbols) /DrawSymbolProc 0 def % Routine to draw symbol outline/fill /StippleProc 0 def % Stipple routine (bar segments) /DashesProc 0 def % Dashes routine (line segments) % Define the array ISOLatin1Encoding (which specifies how characters are % encoded for ISO-8859-1 fonts), if it isn't already present (Postscript % level 2 is supposed to define it, but level 1 doesn't). systemdict /ISOLatin1Encoding known not { /ISOLatin1Encoding [ /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /minus /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedillar /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def } if % font ISOEncode font % This procedure changes the encoding of a font from the default % Postscript encoding to ISOLatin1. It is typically invoked just % before invoking "setfont". The body of this procedure comes from % Section 5.6.1 of the Postscript book. /ISOEncode { dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def currentdict end % I'm not sure why it's necessary to use "definefont" on this new % font, but it seems to be important; just use the name "Temporary" % for the font. /Temporary exch definefont } bind def /Stroke { gsave stroke grestore } def /Fill { gsave fill grestore } def /SetFont { % Stack: pointSize fontName findfont exch scalefont ISOEncode setfont } def /Box { % Stack: x y width height newpath exch 4 2 roll moveto dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath } def % The next two definitions are taken from "$tk_library/prolog.ps" % desiredSize EvenPixels closestSize % % The procedure below is used for stippling. Given the optimal size % of a dot in a stipple pattern in the current user coordinate system, % compute the closest size that is an exact multiple of the device's % pixel size. This allows stipple patterns to be displayed without % aliasing effects. /EvenPixels { % Compute exact number of device pixels per stipple dot. dup 0 matrix currentmatrix dtransform dup mul exch dup mul add sqrt % Round to an integer, make sure the number is at least 1, and compute % user coord distance corresponding to this. dup round dup 1 lt {pop 1} if exch div mul } bind def % width height string filled StippleFill -- % % Given a path and other graphics information already set up, this % procedure will fill the current path in a stippled fashion. "String" % contains a proper image description of the stipple pattern and % "width" and "height" give its dimensions. If "filled" is true then % it means that the area to be stippled is gotten by filling the % current path (e.g. the interior of a polygon); if it's false, the % area is gotten by stroking the current path (e.g. a wide line). % Each stipple dot is assumed to be about one unit across in the % current user coordinate system. % width height string StippleFill -- % % Given a path already set up and a clipping region generated from % it, this procedure will fill the clipping region with a stipple % pattern. "String" contains a proper image description of the % stipple pattern and "width" and "height" give its dimensions. Each % stipple dot is assumed to be about one unit across in the current % user coordinate system. This procedure trashes the graphics state. /StippleFill { % The following code is needed to work around a NeWSprint bug. /tmpstip 1 index def % Change the scaling so that one user unit in user coordinates % corresponds to the size of one stipple dot. 1 EvenPixels dup scale % Compute the bounding box occupied by the path (which is now % the clipping region), and round the lower coordinates down % to the nearest starting point for the stipple pattern. Be % careful about negative numbers, since the rounding works % differently on them. pathbbox 4 2 roll 5 index div dup 0 lt {1 sub} if cvi 5 index mul 4 1 roll 6 index div dup 0 lt {1 sub} if cvi 6 index mul 3 2 roll % Stack now: width height string y1 y2 x1 x2 % Below is a doubly-nested for loop to iterate across this area % in units of the stipple pattern size, going up columns then % across rows, blasting out a stipple-pattern-sized rectangle at % each position 6 index exch { 2 index 5 index 3 index { % Stack now: width height string y1 y2 x y gsave 1 index exch translate 5 index 5 index true matrix tmpstip imagemask grestore } for pop } for pop pop pop pop pop } bind def /LS { % Stack: x1 y1 x2 y2 newpath 4 2 roll moveto lineto closepath stroke } def /EndText { %Stack : grestore } def /BeginText { %Stack : w h theta centerX centerY gsave % Translate the origin to the center of bounding box and rotate translate neg rotate % Translate back to the origin of the text region -0.5 mul exch -0.5 mul exch translate } def /DrawAdjText { %Stack : str strWidth x y moveto % Go to the text position exch dup dup 4 2 roll % Adjust character widths to get desired overall string width % adjust X = (desired width - real width)/#chars stringwidth pop sub exch length div 0 3 -1 roll % Flip back the scale so that the string is not drawn in reverse gsave 1 -1 scale ashow grestore } def /DrawBitmap { % Stack: ?bgColorProc? boolean centerX centerY width height theta imageStr gsave 6 -2 roll translate % Translate to center of bounding box 4 1 roll neg rotate % Rotate by theta % Find upperleft corner of bounding box 2 copy -.5 mul exch -.5 mul exch translate 2 copy scale % Make pixel unit scale newpath 0 0 moveto 0 1 lineto 1 1 lineto 1 0 lineto closepath % Fill rectangle with background color 4 -1 roll { gsave 4 -1 roll exec fill grestore } if % Paint the image string into the unit rectangle 2 copy true 3 -1 roll 0 0 5 -1 roll 0 0 6 array astore 5 -1 roll imagemask grestore } def % Symbols: % Skinny-cross /Sc { % Stack: x y symbolSize gsave 3 -2 roll translate 45 rotate 0 0 3 -1 roll Sp grestore } def % Skinny-plus /Sp { % Stack: x y symbolSize gsave 3 -2 roll translate 2 idiv dup 2 copy newpath neg 0 moveto 0 lineto DrawSymbolProc newpath neg 0 exch moveto 0 exch lineto DrawSymbolProc grestore } def % Cross /Cr { % Stack: x y symbolSize gsave 3 -2 roll translate 45 rotate 0 0 3 -1 roll Pl grestore } def % Plus /Pl { % Stack: x y symbolSize gsave 3 -2 roll translate dup 2 idiv exch 6 idiv % % 2 3 The plus/cross symbol is a % closed polygon of 12 points. % 0 1 4 5 The diagram to the left % x,y represents the positions of % 11 10 7 6 the points which are computed % below. % 9 8 % newpath 2 copy exch neg exch neg moveto dup neg dup lineto 2 copy neg exch neg lineto 2 copy exch neg lineto dup dup neg lineto 2 copy neg lineto 2 copy lineto dup dup lineto 2 copy exch lineto 2 copy neg exch lineto dup dup neg exch lineto exch neg exch lineto closepath DrawSymbolProc grestore } def % Circle /Ci { % Stack: x y symbolSize gsave 3 copy pop moveto newpath 2 div 0 360 arc closepath DrawSymbolProc grestore } def % Square /Sq { % Stack: x y symbolSize gsave dup dup 2 div dup 6 -1 roll exch sub exch 5 -1 roll exch sub 4 -2 roll Box DrawSymbolProc grestore } def % Line /Li { % Stack: x y symbolSize gsave 3 1 roll exch 3 -1 roll 2 div 3 copy newpath sub exch moveto add exch lineto closepath stroke grestore } def % Diamond /Di { % Stack: x y symbolSize gsave 3 1 roll translate 45 rotate 0 0 3 -1 roll Sq grestore } def % Triangle /Tr { % Stack: x y symbolSize gsave 3 -2 roll translate BaseRatio mul 0.5 mul % Calculate 1/2 base dup 0 exch 30 cos mul % h1 = height above center point neg % b2 0 -h1 newpath moveto % point 1; b2 dup 30 sin 30 cos div mul % h2 = height below center point 2 copy lineto % point 2; b2 h2 exch neg exch lineto % closepath DrawSymbolProc grestore } def % Arrow /Ar { % Stack: x y symbolSize gsave 3 -2 roll translate BaseRatio mul 0.5 mul % Calculate 1/2 base dup 0 exch 30 cos mul % h1 = height above center point % b2 0 h1 newpath moveto % point 1; b2 dup 30 sin 30 cos div mul % h2 = height below center point neg % -h2 b2 2 copy lineto % point 2; b2 h2 exch neg exch lineto % closepath DrawSymbolProc grestore } def % Bitmap /Bm { % Stack: x y symbolSize gsave 3 1 roll translate pop DrawSymbolProc grestore } def %%EndProlog %%BeginSetup gsave % Save the graphics state % Default line/text style parameters 1 setlinewidth % width 1 setlinejoin % join 0 setlinecap % cap [] 0 setdash % dashes 0 0 0 setrgbcolor % color ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/combotree.tcl�������������������������������������������������������������0000644�0001750�0001750�00000032147�11462120062�016374� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ====================================================================== # # combotree.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT combotree widget # ---------------------------------------------------------------------- # # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@lucent.com # http://www.tcltk.com/blt # # RCS: $Id: combotree.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ---------------------------------------------------------------------- # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== namespace eval blt::ComboTree { array set _private { afterId -1 scroll 0 column "" space off x 0 y 0 } } image create picture ::blt::ComboTree::openIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } image create picture ::blt::ComboTree::closeIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } # ---------------------------------------------------------------------- # # Initialize -- # # Invoked by internally by Combotree_Init routine. Initializes # the default bindings for the combotree widget entries. These # are local to the widget, so they can't be set through the # widget's class bind tags. # # ---------------------------------------------------------------------- proc blt::ComboTree::Initialize { w } { # # Active entry bindings # $w bind Entry <Enter> { puts stderr "Entry <Enter> [%W index current]" %W activate current %W entry highlight current } $w bind Entry <Leave> { puts stderr "Entry <Leave> [%W index current]" %W activate none %W entry highlight "" } # # Button bindings # $w button bind all <ButtonRelease-1> { set index [%W nearest %x %y blt::ComboTree::_private(who)] if { [%W index current] == $index && $blt::ComboTree::_private(who) == "button" } { %W see -anchor nw current %W toggle current } } $w button bind all <Enter> { %W button highlight current } $w button bind all <B1-Enter> { %W button highlight current } $w button bind all <Leave> { %W button highlight "" } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current entry. # 3. Sets the focus to this entry. # 4. Scrolls the entry into view. # 5. Sets the selection anchor to this entry, just in case # this is "multiple" mode. # # # ButtonRelease-1 # # For "multiple" mode only. # $w bind Entry <ButtonRelease-3> { puts stderr "Entry <ButtonRelease> [%W index current]" %W invoke active event generate [grab current] <ButtonRelease-1> after cancel $blt::ComboTree::_private(afterId) set blt::ComboTree::_private(afterId) -1 set blt::ComboTree::_private(scroll) 0 } $w bind Entry <ButtonRelease-1> { puts stderr "Entry <ButtonRelease-1> [%W index current]" %W invoke active event generate [grab current] <ButtonRelease-1> after cancel $blt::ComboTree::_private(afterId) set blt::ComboTree::_private(afterId) -1 set blt::ComboTree::_private(scroll) 0 } $w bind Entry <Double-ButtonPress-1> { %W see -anchor nw active %W toggle active } # # Shift-ButtonPress-1 # # For "multiple" mode only. # $w bind Entry <Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } set index [%W index anchor] %W selection clearall %W selection set $index current } else { blt::ComboTree::SetSelectionAnchor %W current } } $w bind Entry <Shift-Double-ButtonPress-1> { # do nothing } $w bind Entry <Shift-B1-Motion> { # do nothing } $w bind Entry <Shift-ButtonRelease-1> { after cancel $blt::ComboTree::_private(afterId) set blt::ComboTree::_private(afterId) -1 set blt::ComboTree::_private(scroll) 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # $w bind Entry <Control-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" } { set index [%W index current] %W selection toggle $index %W selection anchor $index } else { blt::ComboTree::SetSelectionAnchor %W current } } $w bind Entry <Control-Double-ButtonPress-1> { # do nothing } $w bind Entry <Control-B1-Motion> { # do nothing } $w bind Entry <Control-ButtonRelease-1> { after cancel $blt::ComboTree::_private(afterId) set blt::ComboTree::_private(afterId) -1 set blt::ComboTree::_private(scroll) 0 } $w bind Entry <Control-Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } if { [%W selection includes anchor] } { %W selection set anchor current } else { %W selection clear anchor current %W selection set current } } else { blt::ComboTree::SetSelectionAnchor %W current } } $w bind Entry <Control-Shift-Double-ButtonPress-1> { # do nothing } $w bind Entry <Control-Shift-B1-Motion> { # do nothing } $w bind Entry <Shift-ButtonPress-3> { puts stderr "entry bind buttonpress-3 %W %X %Y" blt::ComboTree::EditColumn %W %X %Y } } # ---------------------------------------------------------------------- # # AutoScroll -- # # Invoked when the user is selecting elements in a combotree # widget and drags the mouse pointer outside of the widget. # Scrolls the view in the direction of the pointer. # # ---------------------------------------------------------------------- proc blt::ComboTree::AutoScroll { w } { variable _private if { ![winfo exists $w] } { return } set x $_private(x) set y $_private(y) set index [$w nearest $x $y] if {$y >= [winfo height $w]} { $w yview scroll 1 units set neighbor down } elseif {$y < 0} { $w yview scroll -1 units set neighbor up } else { set neighbor $index } SetSelectionAnchor $w $neighbor set _private(afterId) [after 50 blt::ComboTree::AutoScroll $w] } proc blt::ComboTree::SetSelectionAnchor { w tagOrId } { set index [$w index $tagOrId] # If the anchor hasn't changed, don't do anything if { $index != [$w index anchor] } { #$w selection clearall $w see $index #$w focus $index #$w selection set $index #$w selection anchor $index } } # ---------------------------------------------------------------------- # # MoveFocus -- # # Invoked by KeyPress bindings. Moves the active selection to # the entry <where>, which is an index such as "up", "down", # "prevsibling", "nextsibling", etc. # # ---------------------------------------------------------------------- proc blt::ComboTree::MoveFocus { w index } { $w activate $index $w see active } # ---------------------------------------------------------------------- # # MovePage -- # # Invoked by KeyPress bindings. Pages the current view up or # down. The <where> argument should be either "top" or # "bottom". # # ---------------------------------------------------------------------- proc blt::ComboTree::MovePage { w where } { # If the focus is already at the top/bottom of the window, we want # to scroll a page. It's really one page minus an entry because we # want to see the last entry on the next/last page. if { [$w index focus] == [$w index view.$where] } { if {$where == "top"} { $w yview scroll -1 pages $w yview scroll 1 units } else { $w yview scroll 1 pages $w yview scroll -1 units } } update # Adjust the entry focus and the view. Also activate the entry. # just in case the mouse point is not in the widget. $w entry highlight view.$where $w focus view.$where $w see view.$where if { [$w cget -selectmode] == "single" } { $w selection clearall $w selection set focus } } # ---------------------------------------------------------------------- # # NextMatch -- # # Invoked by KeyPress bindings. Searches for an entry that # starts with the letter <char> and makes that entry active. # # ---------------------------------------------------------------------- proc blt::ComboTree::NextMatch { w key } { if {[string match {[ -~]} $key]} { set last [$w index focus] set next [$w index next] while { $next != $last } { set label [$w entry cget $next -label] set label [string index $label 0] if { [string tolower $label] == [string tolower $key] } { break } set next [$w index -at $next next] } $w focus $next if {[$w cget -selectmode] == "single"} { $w selection clearall $w selection set focus } $w see focus } } # # ButtonPress assignments # # B1-Enter start auto-scrolling # B1-Leave stop auto-scrolling # ButtonPress-2 start scan # B2-Motion adjust scan # ButtonRelease-2 stop scan # bind ComboTree <ButtonPress-2> { set blt::ComboTree::_private(cursor) [%W cget -cursor] %W configure -cursor hand1 %W scan mark %x %y } bind ComboTree <B2-Motion> { %W scan dragto %x %y } bind ComboTree <ButtonRelease-2> { %W configure -cursor $blt::ComboTree::_private(cursor) } bind ComboTree <B1-Leave> { if { $blt::ComboTree::_private(scroll) } { blt::ComboTree::AutoScroll %W } } bind ComboTree <B1-Enter> { after cancel $blt::ComboTree::_private(afterId) set blt::ComboTree::_private(afterId) -1 } # # KeyPress assignments # # Up # Down # Shift-Up # Shift-Down # Prior (PageUp) # Next (PageDn) # Left # Right # space Start selection toggle of entry currently with focus. # Return Start selection toggle of entry currently with focus. # Home # End # F1 # F2 # ASCII char Go to next open entry starting with character. # # KeyRelease # # space Stop selection toggle of entry currently with focus. # Return Stop selection toggle of entry currently with focus. bind ComboTree <KeyPress-Up> { %W activate up %W see active } bind ComboTree <KeyPress-Down> { %W activate down %W see active } bind ComboTree <Shift-KeyPress-Up> { %W activate prevsibling %W see active } bind ComboTree <Shift-KeyPress-Down> { %W activate nextsibling %W see active } bind ComboTree <KeyPress-Prior> { %W activate top %W see active } bind ComboTree <KeyPress-Next> { %W activate bottom %W see active } bind ComboTree <KeyPress-Left> { %W close active } bind ComboTree <KeyPress-Right> { %W open active %W see active } bind ComboTree <KeyPress-space> { %W invoke active } bind ComboTree <KeyPress-Return> { %W invoke active } bind ComboTree <KeyPress> { blt::ComboTree::NextMatch %W %A } bind ComboTree <KeyPress-Home> { %W open top %W see active -anchor w } bind ComboTree <KeyPress-End> { blt::ComboTree::MoveFocus %W bottom } bind ComboTree <KeyPress-F1> { %W open -recurse root } bind ComboTree <KeyPress-F2> { eval %W close -r [%W entry children root] } if {[string equal "x11" [tk windowingsystem]]} { bind ComboTree <4> { %W yview scroll -5 units } bind ComboTree <5> { %W yview scroll 5 units } } else { bind ComboTree <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } } proc blt::ComboTree::ConfigureScrollbars { menu } { set ys [$menu cget -yscrollbar] if { $ys != "" } { if { [$menu cget -yscrollcommand] == "" } { $menu configure -yscrollcommand [list $ys set] } if { [$ys cget -command] == "" } { $ys configure -command [list $menu yview] -orient vertical \ -highlightthickness 0 } } set xs [$menu cget -xscrollbar] if { $xs != "" } { if { [$menu cget -xscrollcommand] == "" } { $menu configure -xscrollcommand [list $xs set] } if { [$xs cget -command] == "" } { $xs configure -command [list $menu xview] -orient horizontal \ -highlightthickness 0 } } }�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/macButton.tcl�������������������������������������������������������������0000644�0001750�0001750�00000007561�11462120062�016353� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #################### # Mac implementation #################### bind TkRadiobutton <Enter> { blt::Button::Enter %W } bind TkRadiobutton <1> { blt::Button::Down %W } bind TkRadiobutton <ButtonRelease-1> { blt::Button::Up %W } bind TkCheckbutton <Enter> { blt::Button::Enter %W } bind TkCheckbutton <1> { blt::Button::Down %W } bind TkCheckbutton <ButtonRelease-1> { blt::Button::Up %W } bind TkPushbutton <Enter> { blt::Button::Enter %W } bind TkPushbutton <1> { blt::Button::Down %W } bind TkPushbutton <ButtonRelease-1> { blt::Button::Up %W } # # Enter -- # # The procedure below is invoked when the mouse pointer enters a # button widget. It records the button we're in and changes the # state of the button to active unless the button is disabled. # # Arguments: # w - The name of the widget. proc ::blt::Button::Enter {w} { variable _private if {[$w cget -state] != "disabled"} { # If there's an -overrelief value, set the relief to that. if {$_private(buttonWindow) eq $w} { $w configure -state active } elseif {[set over [$w cget -overrelief]] ne ""} { set _private($w,relief) [$w cget -relief] set _private($w,prelief) $over $w configure -relief $over } } set _private(window) $w } # Leave -- # # The procedure below is invoked when the mouse pointer leaves a # button widget. It changes the state of the button back to # inactive. If we're leaving the button window with a mouse button # pressed (_private(buttonWindow) == $w), restore the relief of the # button too. # # Arguments: # w - The name of the widget. proc ::blt::Button::Leave w { variable _private if {$w eq $_private(buttonWindow)} { $w configure -state normal } # Restore the original button relief if it was changed by Tk. # That is signaled by the existence of _private($w,prelief). if {[info exists _private($w,relief)]} { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } set _private(window) "" } # Down -- # # The procedure below is invoked when the mouse button is pressed in # a button widget. It records the fact that the mouse is in the button, # saves the button's relief so it can be restored later, and changes # the relief to sunken. # # Arguments: # w - The name of the widget. proc ::blt::Button::Down w { variable _private if {[$w cget -state] != "disabled"} { set _private(buttonWindow) $w $w configure -state active # If this button has a repeatdelay set up, get it going with an after after cancel $_private(afterId) set _private(repeated) 0 if { ![catch {$w cget -repeatdelay} delay] } { if {$delay > 0} { set _private(afterId) [after $delay [list blt::Button::AutoInvoke $w]] } } } } # Up -- # # The procedure below is invoked when the mouse button is released # in a button widget. It restores the button's relief and invokes # the command as long as the mouse hasn't left the button. # # Arguments: # w - The name of the widget. proc ::blt::Button::Up w { variable _private if {$_private(buttonWindow) eq $w} { set _private(buttonWindow) "" $w configure -state normal # Restore the button's relief if it was cached. if {[info exists _private($w,relief)]} { if {[info exists _private($w,prelief)] && \ $_private($w,prelief) eq [$w cget -relief]} { $w configure -relief $_private($w,relief) } unset -nocomplain _private($w,relief) _private($w,prelief) } # Clean up the after event from the auto-repeater after cancel $_private(afterId) if {$_private(window) eq $w && [$w cget -state] != "disabled"} { # Only invoke the command if it wasn't already invoked by the # auto-repeater functionality if { $_private(repeated) == 0 } { uplevel #0 [list $w invoke] } } } } } �����������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/comboentry.tcl������������������������������������������������������������0000644�0001750�0001750�00000035502�11462120062�016574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� namespace eval ::blt::ComboEntry { variable _private array set _private { activeItem {} afterId -1 b1 "" lastFocus {} mouseMoved 0 oldGrab {} postingButton {} arrowRelief raised trace 0 lastX -1 } proc trace { mesg } { variable _private if { $_private(trace) } { puts stderr $mesg } } } bind ComboEntry <Enter> { # Do nothing } bind ComboEntry <Leave> { %W activate off } # Standard Motif bindings: bind ComboEntry <Motion> { %W activate [%W identify %x %y] } bind ComboEntry <ButtonPress-1> { ::blt::ComboEntry::ButtonPress %W %x %y } bind ComboEntry <ButtonRelease-1> { blt::ComboEntry::trace "ComboEntry %W at %X,%Y <ButtonRelease-1> state=[%W cget -state], grab=[grab current]" after cancel $blt::ComboEntry::_private(afterId) switch -- [%W identify -root %X %Y] { "arrow" { blt::ComboEntry::trace "invoke" %W invoke } "close" { blt::ComboEntry::trace "button invoke" %W button invoke } default { blt::ComboEntry::trace "unpost" blt::ComboEntry::UnpostMenu %W } } if { [info exists blt::ComboEntry::_private(arrowRelief)] } { %W configure -arrowrelief $blt::ComboEntry::_private(arrowRelief) } } bind ComboEntry <B1-Motion> { if { $blt::ComboEntry::_private(b1) != "arrow" } { %W selection to [%W closest %x] } } bind ComboEntry <B1-Enter> { after cancel $blt::ComboEntry::_private(afterId) set blt::ComboEntry::_private(afterId) -1 } bind ComboEntry <B1-Leave> { blt::ComboEntry::trace "ComboEntry B1-Leave" if { $blt::ComboEntry::_private(b1) == "text" } { set blt::ComboEntry::_private(lastX) %x blt::ComboEntry::AutoScan %W } } bind ComboEntry <KeyPress-Down> { if { [%W cget -state] != "disabled" } { grab %W ::blt::ComboEntry::PostMenu %W } } bind ComboEntry <Double-1> { blt::ComboEntry::trace "Double-1" if { [%W identify %x %y] == "arrow" } { ::blt::ComboEntry::ButtonPress %W %x %y } else { %W icursor [%W closest %x] %W selection range \ [string wordstart [%W get] [%W index previous]] \ [string wordend [%W get] [%W index insert]] %W icursor sel.last %W see insert } } bind ComboEntry <Triple-1> { blt::ComboEntry::trace "Triple-1" if { [%W identify %x %y] != "arrow" } { %W selection range 0 end %W icursor sel.last } } bind ComboEntry <Shift-1> { %W selection adjust @%x } bind ComboEntry <ButtonPress-2> { %W scan mark %x } bind ComboEntry <ButtonRelease-2> { if { abs([%W scan mark] - %x) <= 3 } { catch { %W insert insert [selection get] %W see insert } } } bind ComboEntry <B2-Motion> { %W scan dragto %x } bind ComboEntry <Control-1> { %W icursor @%x } bind ComboEntry <KeyPress-Left> { if { [%W selection present] } { %W icursor sel.last %W selection clear } %W icursor previous %W see insert } bind ComboEntry <KeyPress-Right> { if { [%W selection present] } { %W icursor sel.last %W selection clear } %W icursor next %W see insert } bind ComboEntry <Shift-Left> { if {![%W selection present]} { %W selection range previous insert } else { %W selection adjust previous } %W icursor previous %W see insert } bind ComboEntry <Shift-Right> { if {![%W selection present]} { %W selection range insert next } else { %W selection adjust next } %W icursor next %W see insert } bind ComboEntry <Shift-Control-Left> { set previous [string wordstart [%W get] [%W index previous]] if {![%W selection present]} { %W selection range $previous insert } else { %W selection adjust $previous } %W icursor $previous %W see insert } bind ComboEntry <Shift-Control-Right> { set next [string wordend [%W get] [%W index insert]] if {![%W selection present]} { %W selection range insert $next } else { %W selection adjust $next } %W icursor $next %W see insert } bind ComboEntry <Home> { %W icursor 0 %W see insert } bind ComboEntry <Shift-Home> { if {![%W selection present]} { %W selection range 0 insert } else { %W selection adjust 0 } %W icursor 0 %W see insert } bind ComboEntry <End> { %W icursor end %W see insert } bind ComboEntry <Shift-End> { if {![%W selection present]} { %W selection range insert end } else { %W selection adjust end } %W icursor end %W see insert } bind ComboEntry <Delete> { if {[%W selection present]} { %W delete sel.first sel.last } else { %W delete insert next } } bind ComboEntry <BackSpace> { if {[%W selection present]} { %W delete sel.first sel.last } else { %W delete previous insert %W see insert } } bind ComboEntry <Control-space> { %W selection from insert } bind ComboEntry <Select> { %W selection from insert } bind ComboEntry <Control-Shift-space> { %W selection adjust insert } bind ComboEntry <Shift-Select> { %W selection adjust insert } bind ComboEntry <Control-slash> { %W selection range 0 end } bind ComboEntry <Control-backslash> { %W selection clear } bind ComboEntry <Control-z> { %W undo %W see insert } bind ComboEntry <Control-Z> { %W redo %W see insert } bind ComboEntry <Control-y> { %W redo %W see insert } bind ComboEntry <<Cut>> { if { [%W selection present] } { clipboard clear -displayof %W clipboard append -displayof %W [selection get] %W delete sel.first sel.last } } bind ComboEntry <<Copy>> { if { [%W selection present] } { clipboard clear -displayof %W clipboard append -displayof %W [selection get] } } bind ComboEntry <<Paste>> { %W insert insert [selection get] %W see insert } bind ComboEntry <<Clear>> { %W delete sel.first sel.last } bind Entry <<PasteSelection>> { if { $tk_strictMotif || ![info exists tk::ComboEntry::_private(mouseMoved)] || !$tk::ComboEntry::_private(mouseMoved)} { tk::EntryPaste %W %x } } # Paste bind ComboEntry <Control-v> { %W insert insert [selection get] } # Cut bind ComboEntry <Control-x> { if { [%W selection present] } { clipboard clear -displayof %W clipboard append -displayof %W [selection get] %W delete sel.first sel.last } } # Copy bind ComboEntry <Control-c> { if { [%W selection present] } { clipboard clear -displayof %W clipboard append -displayof %W [selection get] } } bind ComboEntry <Return> { %W invoke } bind ComboEntry <KeyPress> { if { [string compare %A {}] == 0 } { continue } if { [%W selection present] } { %W delete sel.first sel.last } %W insert insert %A %W see insert } # Additional emacs-like bindings: bind ComboEntry <Control-a> { %W icursor 0 %W see insert } bind ComboEntry <Control-b> { %W icursor previous %W see insert } bind ComboEntry <Control-d> { if { [%W selection present] } { %W delete sel.first sel.last } else { %W delete insert next } } bind ComboEntry <Control-e> { %W icursor end %W see insert } bind ComboEntry <Control-f> { %W icursor next %W see insert } bind ComboEntry <Control-h> { if { [%W selection present] } { %W delete sel.first sel.last } else { %W delete previous insert %W see insert } } bind ComboEntry <Control-k> { %W delete insert end } bind ComboEntry <Control-t> { set index [%W index insert] if { $index != 0 && $index != [%W index end] } { set a [string index [%W get] [%W index previous]] set b [string index [%W get] [%W index insert]] %W delete previous next %W insert insert "$b$a" } } bind ComboEntry <Alt-b> { %W icursor [string wordstart [%W get] [%W index previous]] %W see insert } bind ComboEntry <Alt-d> { %W delete insert [string wordend [%W get] [%W index insert]] %W see insert } bind ComboEntry <Alt-f> { %W icursor [string wordend [%W get] [%W index insert]] %W see insert } bind ComboEntry <Alt-BackSpace> { %W delete [string wordstart [%W get] [%W index previous]] insert %W see insert } bind ComboEntry <Alt-Delete> { %W delete insert [string wordend [%W get] [%W index insert]] %W see insert } #### bind ComboEntry <Meta-b> { %W icursor [string wordstart [%W get] [%W index previous]] %W see insert } bind ComboEntry <Meta-d> { %W delete insert [string wordend [%W get] [%W index insert]] %W see insert } bind ComboEntry <Meta-f> { %W icursor [string wordend [%W get] [%W index insert]] %W see insert } bind ComboEntry <Meta-BackSpace> { %W delete [string wordstart [%W get] [%W index previous]] insert %W see insert } bind ComboEntry <Meta-Delete> { %W delete insert [string wordend [%W get] [%W index insert]] %W see insert } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Escape, Return, and Tab. bind ComboEntry <Alt-KeyPress> { # Do nothing. } bind ComboEntry <Meta-KeyPress> { blt::ComboEntry::trace %K } bind ComboEntry <Control-KeyPress> { # Do nothing. } bind ComboEntry <Escape> { # Do nothing. } bind ComboEntry <KP_Enter> { # Do nothing. } bind ComboEntry <Tab> { # Do nothing. } switch -- [tk windowingsystem] { "classic" - "aqua" { bind ComboEntry <Command-KeyPress> { # Do nothing. } } } proc ::blt::ComboEntry::AutoScan {w} { variable _private set x $_private(lastX) if { ![winfo exists $w] } { return } if { $x >= [winfo width $w] } { $w xview scroll 2 units } elseif { $x < 0 } { $w xview scroll -2 units } set _private(afterId) [after 50 [list blt::ComboEntry::AutoScan $w]] } proc ::blt::ComboEntry::SaveGrab { w } { variable _private set grab [grab current $w] set _private(oldGrab) "" if { $grab != "" } { set type [grab status $grab] if { $type == "global" } { #set _private(oldGrab) [list grab set -global $grab] } else { #set _private(oldGrab) [list grab set $grab] } } } # ::blt::ComboEntry::RestoreOldGrab -- # Restores the grab to what it was before TkSaveGrabInfo was called. proc ::blt::ComboEntry::RestoreOldGrab {} { variable _private if { $_private(oldGrab) != "" } { # Be careful restoring the old grab, since it's window may not # be visible anymore. catch $_private(oldGrab) set _private(oldGrab) "" } } # ::blt::ComboEntry::PostMenu -- # # Given a menubutton, this procedure does all the work of posting # its associated menu and unposting any other menu that is currently # posted. # # Arguments: # w - The name of the menubutton widget whose menu # is to be posted. # x, y - Root coordinates of cursor, used for positioning # option menus. If not specified, then the center # of the menubutton is used for an option menu. proc ::blt::ComboEntry::PostMenu { w } { variable _private trace "proc PostMenu $w, state=[$w cget -state]" if { [$w cget -state] == "disabled" } { return } if { [$w cget -state] == "posted" } { UnpostMenu $w return } set menu [$w cget -menu] if { $menu == "" } { return } set cur $_private(postingButton) if { $cur != "" } { # UnpostMenu $cur } set _private(cursor) [$w cget -cursor] $w configure -cursor arrow set _private(postingButton) $w set _private(lastFocus) [focus] $menu activate none #blt::ComboEntry::GenerateMenuSelect $menu # If this looks like an option menubutton then post the menu so # that the current entry is on top of the mouse. Otherwise post # the menu just below the menubutton, as for a pull-down. update idletasks if { [catch { $w post } msg] != 0 } { # Error posting menu (e.g. bogus -postcommand). Unpost it and # reflect the error. global errorInfo set savedInfo $errorInfo # UnpostMenu $w error $msg $savedInfo } focus $menu set value [$w get] set index [$menu index $value] if { $index != -1 } { $menu see $index $menu activate $index } if { [winfo viewable $menu] } { SaveGrab $menu trace "setting global grab on $menu" #grab -global $menu } } # ::blt::ComboEntry::UnpostMenu -- # # This procedure unposts a given menu, plus all of its ancestors up # to (and including) a menubutton, if any. It also restores various # values to what they were before the menu was posted, and releases # a grab if there's a menubutton involved. Special notes: # 1. It's important to unpost all menus before releasing the grab, so # that any Enter-Leave events (e.g. from menu back to main # application) have mode NotifyGrab. # 2. Be sure to enclose various groups of commands in "catch" so that # the procedure will complete even if the menubutton or the menu # or the grab window has been deleted. # # Arguments: # menu - Name of a menu to unpost. Ignored if there # is a posted menubutton. proc ::blt::ComboEntry::UnpostMenu { w } { variable _private trace "proc UnpostMenu $w" catch { # Restore focus right away (otherwise X will take focus away when the # menu is unmapped and under some window managers (e.g. olvwm) we'll # lose the focus completely). focus $_private(lastFocus) } set _private(lastFocus) "" # Unpost menu(s) and restore some stuff that's dependent on what was # posted. $w unpost set _private(postingButton) {} if { [info exists _private(cursor)] } { $w configure -cursor $_private(cursor) } if { [$w cget -state] != "disabled" } { #$w configure -state normal } set menu [$w cget -menu] if { $menu == "" } { return } trace MENU=$menu trace GRAB=[grab current $menu] # Release grab, if any, and restore the previous grab, if there # was one. if { $menu != "" } { set grab [grab current $menu] if { $grab != "" } { grab release $grab } } RestoreOldGrab } proc ::blt::ComboEntry::GenerateMenuSelect {menu} { if 0 { variable _private if { $_private(activeComboMenu) != $menu || $_private(activeItem) != [$menu index active] } { set _private(activeComboMenu) $menu set _private(activeItem) [$menu index active] event generate $menu <<MenuSelect>> } } } proc ::blt::ComboEntry::ButtonPress { w x y } { variable _private trace "blt::ComboEntry::ButtonPress $w state=[$w cget -state]" set _private(b1) [$w identify $x $y] trace "_private(b1) = \"$_private(b1)\"" if { [$w cget -state] == "posted" } { trace "state = [$w cget -state]" $w unpost UnpostMenu $w } elseif { $_private(b1) == "arrow" } { set _private(arrowRelief) [$w cget -arrowrelief] trace "relief=$_private(arrowRelief)" if { [$w cget -state] != "disabled" } { $w configure -arrowrelief sunken } grab -global $w PostMenu $w } else { trace "else: priv(v1)=$_private(b1) state=[$w cget -state]" focus $w $w icursor [$w closest $x] $w selection clear $w selection from insert $w configure -arrowrelief $_private(arrowRelief) } }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/listview.tcl��������������������������������������������������������������0000644�0001750�0001750�00000053442�11462120062�016264� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ====================================================================== # # listview.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT listview widget # ---------------------------------------------------------------------- # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== namespace eval ::blt::ListView { variable _private array set _private { afterId -1 scroll 0 column "" space off x 0 y 0 } } image create picture ::blt::ListView::openIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } image create picture ::blt::ListView::closeIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } if { $tcl_platform(platform) == "windows" } { if { $tk_version >= 8.3 } { set cursor "@[file join $blt_library treeview.cur]" } else { set cursor "size_we" } option add *ListView.ResizeCursor [list $cursor] } else { option add *ListView.ResizeCursor \ "@$blt_library/treeview.xbm $blt_library/treeview_m.xbm black white" } bind ListView <Motion> { %W activate @%x,%y } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current item. # 3. Sets the focus to this item. # 4. Scrolls the item into view. # 5. Sets the selection anchor to this item, just in case # this is "multiple" mode. # bind ListView <ButtonPress-1> { blt::ListView::SetSelectionAnchor %W @%x,%y set blt::ListView::_private(scroll) 1 } bind ListView <Double-ButtonPress-1> { if { [%W index @%x,@%y] >= 0 } { blt::ListView::EditItem %W %X %Y } } # # B1-Motion # # For "multiple" mode only. Saves the current location of the # pointer for auto-scrolling. Resets the selection mark. # bind ListView <B1-Motion> { set blt::ListView::_private(x) %x set blt::ListView::_private(y) %y if { [%W cget -selectmode] == "multiple" } { %W selection mark @%x,%y %W activate @%x,%y } else { blt::ListView::SetSelectionAnchor %W @%x,%y } } # # ButtonRelease-1 # # For "multiple" mode only. # bind ListView <ButtonRelease-1> { if { [%W cget -selectmode] == "multiple" } { %W selection anchor @%x,%y } after cancel $blt::ListView::_private(afterId) set blt::ListView::_private(afterId) -1 set blt::ListView::_private(scroll) 0 } # # Shift-ButtonPress-1 # # For "multiple" mode only. # bind ListView <Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W selection anchor] == -1 } { %W selection anchor @%x,%y } set index [%W selection anchor] if { $index >= 0 } { %W selection clearall %W selection set $index @%x,%y } } else { blt::ListView::SetSelectionAnchor %W @%x,%y } } bind ListView <Shift-Double-ButtonPress-1> { # do nothing } bind ListView <Shift-B1-Motion> { # do nothing } bind ListView <Shift-ButtonRelease-1> { after cancel $blt::ListView::_private(afterId) set blt::ListView::_private(afterId) -1 set blt::ListView::_private(scroll) 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # bind ListView <Control-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" } { %W selection toggle @%x,%y %W selection anchor @%x,%y } else { blt::ListView::SetSelectionAnchor %W @%x,%y } } bind ListView <Control-Double-ButtonPress-1> { # do nothing } bind ListView <Control-B1-Motion> { # do nothing } bind ListView <Control-ButtonRelease-1> { after cancel $blt::ListView::_private(afterId) set blt::ListView::_private(afterId) -1 set blt::ListView::_private(scroll) 0 } bind ListView <Control-Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == -1 } { %W selection anchor @%x,%y } if { [%W selection includes anchor] } { %W selection set anchor @%x,%y } else { %W selection clear anchor @%x,%y %W selection set @%x,%y } } else { blt::ListView::SetSelectionAnchor %W @%x,%y } } bind ListView <Control-Shift-Double-ButtonPress-1> { # do nothing } bind ListView <Control-Shift-B1-Motion> { # do nothing } bind ListView <ButtonRelease-3> { blt::ListView::EditItem %W %X %Y } bind ListView <KeyPress> { if { [string compare %A {}] == 0 } { continue } set index [%W find "%A*" -from next -count 1 -wrap] if { $index >= 0 } { %W see $index %W focus $index } } # ---------------------------------------------------------------------- # # AutoScroll -- # # Invoked when the user is selecting elements in a treeview # widget and drags the mouse pointer outside of the widget. # Scrolls the view in the direction of the pointer. # # ---------------------------------------------------------------------- proc blt::ListView::AutoScroll { w } { variable _private if { ![winfo exists $w] } { return } set x $_private(x) set y $_private(y) if { [$w cget -layoutmode] == "column" } { set index [$w nearest $x $y] if { $x >= [winfo width $w] } { $w xview scroll 1 units set neighbor down } elseif { $x < 0 } { $w xview scroll -1 units set neighbor up } else { set neighbor $index } } else { # This covers both row and icons layouts. set index [$w nearest $x $y] if {$y >= [winfo height $w]} { $w yview scroll 1 units set neighbor down } elseif {$y < 0} { $w yview scroll -1 units set neighbor up } else { set neighbor $index } } puts stderr "layout mode= [$w cget -layoutmode]" if { [$w cget -selectmode] == "single" } { if { [$w exists $neighbor] } { SetSelectionAnchor $w $neighbor } } else { catch { $w selection mark $index } } set _private(afterId) [after 50 blt::ListView::AutoScroll $w] } proc blt::ListView::SetSelectionAnchor { w item } { $w selection clearall set index [$w index $item] if { $index >= 0 } { $w see $index $w focus $index $w selection set $index $w selection anchor $index } } # ---------------------------------------------------------------------- # # MoveFocus -- # # Invoked by KeyPress bindings. Moves the active selection to # the item <where>, which is an index such as "up", "down", # "prevsibling", "nextsibling", etc. # # ---------------------------------------------------------------------- proc blt::ListView::MoveFocus { w item } { catch {$w focus $item} if { [$w cget -selectmode] == "single" } { $w selection clearall $w selection set focus $w selection anchor focus } $w see focus } # ---------------------------------------------------------------------- # # MovePage -- # # Invoked by KeyPress bindings. Pages the current view up or # down. The <where> argument should be either "top" or # "bottom". # # ---------------------------------------------------------------------- proc blt::ListView::MovePage { w where } { # If the focus is already at the top/bottom of the window, we want # to scroll a page. It's really one page minus an item because we # want to see the last item on the next/last page. if { [$w index focus] == [$w index view.$where] } { if {$where == "top"} { $w yview scroll -1 pages $w yview scroll 1 units } else { $w yview scroll 1 pages $w yview scroll -1 units } } update # Adjust the item focus and the view. Also activate the item. # just in case the mouse point is not in the widget. $w activate view.$where $w focus view.$where $w see view.$where if { [$w cget -selectmode] == "single" } { $w selection clearall $w selection set focus } } # ---------------------------------------------------------------------- # # NextMatch -- # # Invoked by KeyPress bindings. Searches for an item that # starts with the letter <char> and makes that item active. # # ---------------------------------------------------------------------- proc blt::ListView::NextMatch { w key } { if {[string match {[ -~]} $key]} { set last [$w index focus] if { $last == -1 } { return; # No focus. } set next [$w index next] if { $next == -1 } { set next $last } while { $next != $last } { set label [$w item cget $next -label] set label [string index $label 0] if { [string tolower $label] == [string tolower $key] } { break } set next [$w index -at $next next] } $w focus $next if {[$w cget -selectmode] == "single"} { $w selection clearall $w selection set focus } $w see focus } } #------------------------------------------------------------------------ # # InsertText -- # # Inserts a text string into an item at the insertion cursor. # If there is a selection in the item, and it covers the point # of the insertion cursor, then delete the selection before # inserting. # # Arguments: # w Widget where to insert the text. # text Text string to insert (usually just a single character) # #------------------------------------------------------------------------ proc blt::ListView::InsertText { w text } { if { [string length $text] > 0 } { set index [$w index insert] if { ($index >= [$w index sel.first]) && ($index <= [$w index sel.last]) } { $w delete sel.first sel.last } $w insert $index $text } } #------------------------------------------------------------------------ # # Transpose - # # This procedure implements the "transpose" function for item # widgets. It tranposes the characters on either side of the # insertion cursor, unless the cursor is at the end of the line. # In this case it transposes the two characters to the left of # the cursor. In either case, the cursor ends up to the right # of the transposed characters. # # Arguments: # w The item window. # #------------------------------------------------------------------------ proc blt::ListView::Transpose { w } { set i [$w index insert] if {$i < [$w index end]} { incr i } set first [expr {$i-2}] if {$first < 0} { return } set new [string index [$w get] [expr {$i-1}]][string index [$w get] $first] $w delete $first $i $w insert insert $new } #------------------------------------------------------------------------ # # GetSelection -- # # Returns the selected text of the item with respect to the # -show option. # # Arguments: # w Item window from which the text to get # #------------------------------------------------------------------------ proc blt::ListView::GetSelection { w } { set text [string range [$w get] [$w index sel.first] \ [expr [$w index sel.last] - 1]] if {[$w cget -show] != ""} { regsub -all . $text [string index [$w cget -show] 0] text } return $text } proc blt::ListView::EditItem { w x y } { $w see active if { [winfo exists $w.edit] } { destroy $w.edit return } if { ![$w edit -root -test $x $y] } { return } $w edit -root $x $y update if { [winfo exists $w.edit] } { focus $w.edit $w.edit selection range 0 end grab set $w.edit tkwait window $w.edit grab release $w.edit } } # # ButtonPress assignments # # B1-Enter start auto-scrolling # B1-Leave stop auto-scrolling # ButtonPress-2 start scan # B2-Motion adjust scan # ButtonRelease-2 stop scan # bind ListView <ButtonPress-2> { set blt::ListView::_private(cursor) [%W cget -cursor] %W configure -cursor hand1 %W scan mark %x %y } bind ListView <B2-Motion> { %W scan dragto %x %y } bind ListView <ButtonRelease-2> { %W configure -cursor $blt::ListView::_private(cursor) } bind ListView <B1-Leave> { if { $blt::ListView::_private(scroll) } { blt::ListView::AutoScroll %W } } bind ListView <B1-Enter> { after cancel $blt::ListView::_private(afterId) set blt::ListView::_private(afterId) -1 } # # KeyPress assignments # # Up # Down # Shift-Up # Shift-Down # Prior (PageUp) # Next (PageDn) # Left # Right # space Start selection toggle of item currently with focus. # Return Start selection toggle of item currently with focus. # Home # End # ASCII char Go to next open item starting with character. # # KeyRelease # # space Stop selection toggle of item currently with focus. # Return Stop selection toggle of item currently with focus. bind ListView <KeyPress-Up> { blt::ListView::MoveFocus %W previous if { $blt::ListView::_private(space) } { %W selection toggle focus } } bind ListView <KeyPress-Down> { blt::ListView::MoveFocus %W next if { $blt::ListView::_private(space) } { %W selection toggle focus } } bind ListView <KeyPress-Home> { blt::ListView::MoveFocus %W 0 } bind ListView <KeyPress-End> { blt::ListView::MoveFocus %W end } bind ListView <KeyPress-space> { if { [%W cget -selectmode] == "single" } { if { [%W selection includes focus] } { %W selection clearall } else { %W selection clearall %W selection set focus } } else { %W selection toggle focus } set blt::ListView::_private(space) on } bind ListView <KeyRelease-space> { set blt::ListView::_private(space) off } bind ListView <KeyPress-Return> { blt::ListView::MoveFocus %W focus set blt::ListView::_private(space) on } bind ListView <KeyRelease-Return> { set blt::ListView::_private(space) off } if 0 { bind ListView <KeyPress> { blt::ListView::NextMatch %W %A } } if {[string equal "x11" [tk windowingsystem]]} { bind ListView <4> { %W yview scroll -5 units } bind ListView <5> { %W yview scroll 5 units } } else { bind ListView <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } } # # Differences between id "current" and operation nearest. # # set index [$w index current] # set index [$w nearest $x $y] # # o Nearest gives you the closest item. # o current is "" if # 1) the pointer isn't over an item. # 2) the pointer is over a open/close button. # 3) # # # Edit mode assignments # # ButtonPress-3 Enables/disables edit mode on item. Sets focus to # item. # # KeyPress # # Left Move insertion position to previous. # Right Move insertion position to next. # Up Move insertion position up one line. # Down Move insertion position down one line. # Prior Move insertion position up one line. # Next Move insertion position down one line. # Return End edit mode. # Shift-Return Line feed. # Home Move to first position. # End Move to last position. # ASCII char Insert character left of insertion point. # Del Delete character right of insertion point. # Delete Delete character left of insertion point. # Ctrl-X Cut # Ctrl-V Copy # Ctrl-P Paste # # KeyRelease # # ButtonPress-1 Start selection if in item, otherwise clear selection. # B1-Motion Extend/reduce selection. # ButtonRelease-1 End selection if in item, otherwise use last # selection. # B1-Enter Disabled. # B1-Leave Disabled. # ButtonPress-2 Same as above. # B2-Motion Same as above. # ButtonRelease-2 Same as above. # # # Standard Motif bindings: bind ListViewEditor <ButtonPress-1> { %W icursor @%x,%y %W selection clear } bind ListViewEditor <Left> { %W icursor last %W selection clear } bind ListViewEditor <Right> { %W icursor next %W selection clear } bind ListViewEditor <Shift-Left> { set new [expr {[%W index insert] - 1}] if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind ListViewEditor <Shift-Right> { set new [expr {[%W index insert] + 1}] if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind ListViewEditor <Home> { %W icursor 0 %W selection clear } bind ListViewEditor <Shift-Home> { set new 0 if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind ListViewEditor <End> { %W icursor end %W selection clear } bind ListViewEditor <Shift-End> { set new end if {![%W selection present]} { %W selection from insert %W selection to $new } else { %W selection adjust $new } %W icursor $new } bind ListViewEditor <Delete> { if { [%W selection present]} { %W delete sel.first sel.last } else { %W delete insert } } bind ListViewEditor <BackSpace> { if { [%W selection present] } { %W delete sel.first sel.last } else { set index [expr [%W index insert] - 1] if { $index >= 0 } { %W delete $index $index } } } bind ListViewEditor <Control-space> { %W selection from insert } bind ListViewEditor <Select> { %W selection from insert } bind ListViewEditor <Control-Shift-space> { %W selection adjust insert } bind ListViewEditor <Shift-Select> { %W selection adjust insert } bind ListViewEditor <Control-slash> { %W selection range 0 end } bind ListViewEditor <Control-backslash> { %W selection clear } bind ListViewEditor <KeyPress> { blt::ListView::InsertText %W %A } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Escape, Return, and Tab. bind ListViewEditor <Alt-KeyPress> { # nothing } bind ListViewEditor <Meta-KeyPress> { # nothing } bind ListViewEditor <Control-KeyPress> { # nothing } bind ListViewEditor <Escape> { %W cancel } bind ListViewEditor <Return> { %W apply } bind ListViewEditor <Shift-Return> { blt::ListView::InsertText %W "\n" } bind ListViewEditor <KP_Enter> { # nothing } bind ListViewEditor <Tab> { # nothing } if {![string compare $tcl_platform(platform) "macintosh"]} { bind ListViewEditor <Command-KeyPress> { # nothing } } # On Windows, paste is done using Shift-Insert. Shift-Insert already # generates the <<Paste>> event, so we don't need to do anything here. if { [string compare $tcl_platform(platform) "windows"] != 0 } { bind ListViewEditor <Insert> { catch {blt::ListView::InsertText %W [selection get -displayof %W]} } } # Additional emacs-like bindings: bind ListViewEditor <ButtonRelease-3> { set parent [winfo parent %W] %W cancel } bind ListViewEditor <Control-a> { %W icursor 0 %W selection clear } bind ListViewEditor <Control-b> { %W icursor [expr {[%W index insert] - 1}] %W selection clear } bind ListViewEditor <Control-d> { %W delete insert } bind ListViewEditor <Control-e> { %W icursor end %W selection clear } bind ListViewEditor <Control-f> { %W icursor [expr {[%W index insert] + 1}] %W selection clear } bind ListViewEditor <Control-h> { if {[%W selection present]} { %W delete sel.first sel.last } else { set index [expr [%W index insert] - 1] if { $index >= 0 } { %W delete $index $index } } } bind ListViewEditor <Control-k> { %W delete insert end } if 0 { bind ListViewEditor <Control-t> { blt::ListView::Transpose %W } bind ListViewEditor <Meta-b> { %W icursor [blt::ListView::PreviousWord %W insert] %W selection clear } bind ListViewEditor <Meta-d> { %W delete insert [blt::ListView::NextWord %W insert] } bind ListViewEditor <Meta-f> { %W icursor [blt::ListView::NextWord %W insert] %W selection clear } bind ListViewEditor <Meta-BackSpace> { %W delete [blt::ListView::PreviousWord %W insert] insert } bind ListViewEditor <Meta-Delete> { %W delete [blt::ListView::PreviousWord %W insert] insert } # tkEntryNextWord -- Returns the index of the next word position # after a given position in the entry. The next word is platform # dependent and may be either the next end-of-word position or the # next start-of-word position after the next end-of-word position. # # Arguments: # w - The item window in which the cursor is to move. # start - Position at which to start search. if {![string compare $tcl_platform(platform) "windows"]} { proc blt::ListView::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos >= 0} { set pos [tcl_startOfNextWord [$w get] $pos] } if {$pos < 0} { return end } return $pos } } else { proc blt::ListView::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos < 0} { return end } return $pos } } # PreviousWord -- # # Returns the index of the previous word position before a given # position in the item. # # Arguments: # w - The item window in which the cursor is to move. # start - Position at which to start search. proc blt::ListView::PreviousWord {w start} { set pos [tcl_startOfPreviousWord [$w get] [$w index $start]] if {$pos < 0} { return 0 } return $pos } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dragdrop.tcl��������������������������������������������������������������0000644�0001750�0001750�00000005346�11462120062�016220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # dragdrop.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT drag&drop command # ---------------------------------------------------------------------- # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@bell-labs.com # http://www.tcltk.com/blt # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ====================================================================== # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== if { $tcl_version >= 8.0 } { set cmd blt::drag&drop } else { set cmd drag&drop } for { set i 1 } { $i <= 5 } { incr i } { bind BltDrag&DropButton$i <ButtonPress-$i> [list $cmd drag %W %X %Y] bind BltDrag&DropButton$i <B$i-Motion> [list $cmd drag %W %X %Y] bind BltDrag&DropButton$i <ButtonRelease-$i> [list $cmd drop %W %X %Y] } # ---------------------------------------------------------------------- # # Drag&DropInit -- # # Invoked from C whenever a new drag&drop source is created. # Sets up the default bindings for the drag&drop source. # # <ButtonPress-?> Starts the drag operation. # <B?-Motion> Updates the drag. # <ButtonRelease-?> Drop the data on the target. # # Arguments: # widget source widget # button Mouse button used to activate drag. # cmd "dragdrop" or "blt::dragdrop" # # ---------------------------------------------------------------------- proc blt::Drag&DropInit { widget button } { set tagList {} if { $button > 0 } { lappend tagList BltDrag&DropButton$button } foreach tag [bindtags $widget] { if { ![string match BltDrag&DropButton* $tag] } { lappend tagList $tag } } bindtags $widget $tagList } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/pkgIndex.tcl.in�����������������������������������������������������������0000644�0001750�0001750�00000005531�11462120062�016570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tcl package index file, version 1.0 set version "%VERSION%" namespace eval blt${version} {} proc blt${version}::load_library { name version dir package } { set prefix "%SO_PREFIX%" set suffix "%LIB_SUFFIX%" set so [info sharedlibextension] regsub {\.} $version {} version_no_dots set fullname ${prefix}${name}${version_no_dots}${suffix}${so} global tcl_platform if { $tcl_platform(platform) == "unix" } { set library [file join $dir $fullname] if { ![file exists $library] } { # Try the parent directory. set library [file join [file dirname $dir] $fullname] } if { ![file exists $library] } { # Default to the path generated at compilation. set library [file join "%LIB_DIR%" $fullname] } } else { set library $fullname } load $library $package } package ifneeded BLT $version [subst -nocommands { package require blt_core $version if { [info commands tk] == "tk" } { package require blt_extra $version } package provide BLT $version }] # Core (tcl-only) and extra (Tk) packages package ifneeded blt_core $version \ [list blt${version}::load_library "BLTCore" $version $dir "blt_core"] package ifneeded blt_extra $version [subst { package require blt_core blt${version}::load_library "BLTX" $version $dir "blt_x" }] # Data table data format packages package ifneeded blt_datatable_xml $version [subst { package require blt_core blt::datatable load xml $dir }] package ifneeded blt_datatable_mysql $version \ [list blt::datatable load mysql $dir] package ifneeded blt_datatable_tree $version \ [list blt::datatable load tree $dir] package ifneeded blt_datatable_vector $version \ [list blt::datatable load vector $dir] package ifneeded blt_datatable_csv $version \ [list blt::datatable load csv $dir] # Picture image format packages package ifneeded blt_picture_bmp $version [subst { package require BLT blt::picture load bmp $dir }] package ifneeded blt_picture_gif $version \ [list blt::picture load gif $dir] package ifneeded blt_picture_jpg $version \ [list blt::picture load jpg $dir] package ifneeded blt_picture_pbm $version \ [list blt::picture load pbm $dir] package ifneeded blt_picture_pdf $version \ [list blt::picture load pdf $dir] package ifneeded blt_picture_png $version \ [list blt::picture load png $dir] package ifneeded blt_picture_ps $version \ [list blt::picture load ps $dir] package ifneeded blt_picture_tif $version \ [list blt::picture load tif $dir] package ifneeded blt_picture_xbm $version \ [list blt::picture load xbm $dir] package ifneeded blt_picture_xpm $version \ [list blt::picture load xpm $dir] package ifneeded blt_picture_photo $version \ [list blt::picture load photo $dir] # Tree data format packages package ifneeded blt_tree_xml $version \ [list blt::tree load xml $dir] # End of package index file �����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dnd.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000006262�11462120062�015161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # dnd.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT drag&drop command # ---------------------------------------------------------------------- # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@bell-labs.com # http://www.tcltk.com/blt # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ====================================================================== # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== if { $tcl_version >= 8.0 } { set cmd blt::dnd } else { set cmd dnd } for { set i 1 } { $i <= 5 } { incr i } { bind BltDndButton$i <ButtonPress-$i> [list $cmd select %W %X %Y %t] bind BltDndButton$i <B$i-Motion> [list $cmd drag %W %X %Y] bind BltDndButton$i <ButtonRelease-$i> [list $cmd drop %W %X %Y] } # ---------------------------------------------------------------------- # # DndInit -- # # Invoked from C whenever a new drag&drop source is created. # Sets up the default bindings for the drag&drop source. # # <ButtonPress-?> Starts the drag operation. # <B?-Motion> Updates the drag. # <ButtonRelease-?> Drop the data on the target. # # Arguments: # widget source widget # button Mouse button used to activate drag. # cmd "dragdrop" or "blt::dragdrop" # # ---------------------------------------------------------------------- proc blt::DndInit { widget button } { set tagList {} if { $button > 0 } { lappend tagList BltDndButton$button } foreach tag [bindtags $widget] { if { ![string match BltDndButton* $tag] } { lappend tagList $tag } } bindtags $widget $tagList } proc blt::DndStdDrop { widget args } { array set info $args set fmt [lindex $info(formats) 0] dnd pull $widget $fmt return 0 } proc blt::PrintInfo { array } { upvar $array state parray state if { $info(state) & 0x01 } { puts "Shift-Drop" } if { $info(state) & 0x02 } { puts "CapsLock-Drop" } if { $info(state) & 0x04 } { puts "Control-Drop" } if { $info(state) & 0x08 } { puts "Alt-Drop" } if { $info(state) & 0x10 } { puts "NumLock-Drop" } }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/hiertable.tcl�������������������������������������������������������������0000644�0001750�0001750�00000060162�11462120062�016352� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# hiertable.tcl # ---------------------------------------------------------------------- # Bindings for the BLT hiertable widget # ---------------------------------------------------------------------- # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@lucent.com # http://www.tcltk.com/blt # # RCS: $Id: hiertable.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ====================================================================== # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== namespace eval blt::Hiertable { set afterId "" set scroll 0 set column "" set space off set x 0 set y 0 } # # ButtonPress assignments # # B1-Enter start auto-scrolling # B1-Leave stop auto-scrolling # ButtonPress-2 start scan # B2-Motion adjust scan # ButtonRelease-2 stop scan # bind Hiertable <ButtonPress-2> { set blt::Hiertable::cursor [%W cget -cursor] %W configure -cursor hand1 %W scan mark %x %y } bind Hiertable <B2-Motion> { %W scan dragto %x %y } bind Hiertable <ButtonRelease-2> { %W configure -cursor $blt::Hiertable::cursor } bind Hiertable <B1-Leave> { if { $blt::Hiertable::scroll } { blt::Hiertable::AutoScroll %W } } bind Hiertable <B1-Enter> { after cancel $blt::Hiertable::afterId } # # KeyPress assignments # # Up # Down # Shift-Up # Shift-Down # Prior (PageUp) # Next (PageDn) # Left # Right # space Start selection toggle of entry currently with focus. # Return Start selection toggle of entry currently with focus. # Home # End # F1 # F2 # ASCII char Go to next open entry starting with character. # # KeyRelease # # space Stop selection toggle of entry currently with focus. # Return Stop selection toggle of entry currently with focus. bind Hiertable <KeyPress-Up> { blt::Hiertable::MoveFocus %W up if { $blt::Hiertable::space } { %W selection toggle focus } } bind Hiertable <KeyPress-Down> { blt::Hiertable::MoveFocus %W down if { $blt::Hiertable::space } { %W selection toggle focus } } bind Hiertable <Shift-KeyPress-Up> { blt::Hiertable::MoveFocus %W prevsibling } bind Hiertable <Shift-KeyPress-Down> { blt::Hiertable::MoveFocus %W nextsibling } bind Hiertable <KeyPress-Prior> { blt::Hiertable::MovePage %W top } bind Hiertable <KeyPress-Next> { blt::Hiertable::MovePage %W bottom } bind Hiertable <KeyPress-Left> { %W close focus } bind Hiertable <KeyPress-Right> { %W open focus %W see focus -anchor w } bind Hiertable <KeyPress-space> { if { [%W cget -selectmode] == "single" } { if { [%W selection includes focus] } { %W selection clearall } else { %W selection clearall %W selection set focus } } else { %W selection toggle focus } set blt::Hiertable::space on } bind Hiertable <KeyRelease-space> { set blt::Hiertable::space off } bind Hiertable <KeyPress-Return> { blt::Hiertable::MoveFocus %W focus set blt::Hiertable::space on } bind Hiertable <KeyRelease-Return> { set blt::Hiertable::space off } bind Hiertable <KeyPress> { blt::Hiertable::NextMatchingEntry %W %A } bind Hiertable <KeyPress-Home> { blt::Hiertable::MoveFocus %W top } bind Hiertable <KeyPress-End> { blt::Hiertable::MoveFocus %W bottom } bind Hiertable <KeyPress-F1> { %W open -r root } bind Hiertable <KeyPress-F2> { eval %W close -r [%W entry children root] } # # Differences between "current" and nearest. # # set index [$widget index current] # set index [$widget nearest $x $y] # # o Nearest gives you the closest entry. # o current is "" if # 1) the pointer isn't over an entry. # 2) the pointer is over a open/close button. # 3) # # # ---------------------------------------------------------------------- # # USAGE: blt::Hiertable::Init <hiertable> # # Invoked by internally by Hiertable_Init routine. Initializes the # default bindings for the hiertable widget entries. These are local # to the widget, so they can't be set through the widget's class # bind tags. # # Arguments: hiertable hierarchy widget # # ---------------------------------------------------------------------- proc blt::Hiertable::Init { widget } { # # Active entry bindings # $widget bind Entry <Enter> { %W entry highlight current } $widget bind Entry <Leave> { %W entry highlight "" } # # Button bindings # $widget button bind all <ButtonRelease-1> { %W see -anchor nw current %W toggle current } $widget button bind all <Enter> { %W button highlight current } $widget button bind all <Leave> { %W button highlight "" } # # ButtonPress-1 # # Performs the following operations: # # 1. Clears the previous selection. # 2. Selects the current entry. # 3. Sets the focus to this entry. # 4. Scrolls the entry into view. # 5. Sets the selection anchor to this entry, just in case # this is "multiple" mode. # $widget bind Entry <ButtonPress-1> { blt::Hiertable::SetSelectionAnchor %W current set blt::Hiertable::scroll 1 } $widget bind Entry <Double-ButtonPress-1> { %W toggle current } # # B1-Motion # # For "multiple" mode only. Saves the current location of the # pointer for auto-scrolling. Resets the selection mark. # $widget bind Entry <B1-Motion> { set blt::Hiertable::x %x set blt::Hiertable::y %y set index [%W nearest %x %y] if { [%W cget -selectmode] == "multiple" } { %W selection mark $index } else { blt::Hiertable::SetSelectionAnchor %W $index } } # # ButtonRelease-1 # # For "multiple" mode only. # $widget bind Entry <ButtonRelease-1> { if { [%W cget -selectmode] == "multiple" } { %W selection anchor current } after cancel $blt::Hiertable::afterId set blt::Hiertable::scroll 0 } # # Shift-ButtonPress-1 # # For "multiple" mode only. # $widget bind Entry <Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } set index [%W index anchor] %W selection clearall %W selection set $index current } else { blt::Hiertable::SetSelectionAnchor %W current } } $widget bind Entry <Shift-Double-ButtonPress-1> { puts <Shift-Double-ButtonPress-1> # do nothing } $widget bind Entry <Shift-B1-Motion> { # do nothing } $widget bind Entry <Shift-ButtonRelease-1> { after cancel $blt::Hiertable::afterId set blt::Hiertable::scroll 0 } # # Control-ButtonPress-1 # # For "multiple" mode only. # $widget bind Entry <Control-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" } { set index [%W index current] %W selection toggle $index %W selection anchor $index } else { blt::Hiertable::SetSelectionAnchor %W current } } $widget bind Entry <Control-Double-ButtonPress-1> { puts <Control-Double-ButtonPress-1> # do nothing } $widget bind Entry <Control-B1-Motion> { # do nothing } $widget bind Entry <Control-ButtonRelease-1> { after cancel $blt::Hiertable::afterId set blt::Hiertable::scroll 0 } $widget bind Entry <Control-Shift-ButtonPress-1> { if { [%W cget -selectmode] == "multiple" && [%W selection present] } { if { [%W index anchor] == "" } { %W selection anchor current } if { [%W selection includes anchor] } { %W selection set anchor current } else { %W selection clear anchor current %W selection set current } } else { blt::Hiertable::SetSelectionAnchor %W current } } $widget bind Entry <Control-Shift-Double-ButtonPress-1> { puts <Control-Shift-Double-ButtonPress-1> # do nothing } $widget bind Entry <Control-Shift-B1-Motion> { # do nothing } $widget column bind all <Enter> { %W column highlight [%W column current] } $widget column bind all <Leave> { %W column highlight "" } $widget column bind Rule <Enter> { %W column highlight [%W column current] %W column resize activate [%W column current] } $widget column bind Rule <Leave> { %W column highlight "" %W column resize activate "" } $widget column bind Rule <ButtonPress-1> { %W column resize anchor %x } $widget column bind Rule <B1-Motion> { %W column resize mark %x } $widget column bind Rule <ButtonRelease-1> { %W column configure [%W column current] -width [%W column resize set] } $widget column bind all <ButtonRelease-1> { set column [%W column nearest %x %y] if { $column != "" } { %W column invoke $column } } } # ---------------------------------------------------------------------- # USAGE: blt::Hiertable::AutoScroll <hiertable> # # Invoked when the user is selecting elements in a hiertable widget # and drags the mouse pointer outside of the widget. Scrolls the # view in the direction of the pointer. # # Arguments: hiertable hierarchy widget # # ---------------------------------------------------------------------- proc blt::Hiertable::AutoScroll { widget } { if { ![winfo exists $widget] } { return } set x $blt::Hiertable::x set y $blt::Hiertable::y set index [$widget nearest $x $y] if {$y >= [winfo height $widget]} { $widget yview scroll 1 units set neighbor down } elseif {$y < 0} { $widget yview scroll -1 units set neighbor up } else { set neighbor $index } if { [$widget cget -selectmode] == "single" } { blt::Hiertable::SetSelectionAnchor $widget $neighbor } else { $widget selection mark $index } set ::blt::Hiertable::afterId [after 10 blt::Hiertable::AutoScroll $widget] } proc blt::Hiertable::SetSelectionAnchor { widget index } { set index [$widget index $index] # If the anchor hasn't changed, don't do anything if { $index != [$widget index anchor] } { $widget selection clearall $widget see $index $widget focus $index $widget selection set $index $widget selection anchor $index } } # ---------------------------------------------------------------------- # USAGE: blt::Hiertable::MoveFocus <hiertable> <where> # # Invoked by KeyPress bindings. Moves the active selection to the # entry <where>, which is an index such as "up", "down", "prevsibling", # "nextsibling", etc. # ---------------------------------------------------------------------- proc blt::Hiertable::MoveFocus { widget where } { catch {$widget focus $where} if { [$widget cget -selectmode] == "single" } { $widget selection clearall $widget selection set focus } $widget see focus } # ---------------------------------------------------------------------- # USAGE: blt::Hiertable::MovePage <hiertable> <where> # Arguments: hiertable hierarchy widget # # Invoked by KeyPress bindings. Pages the current view up or down. # The <where> argument should be either "top" or "bottom". # ---------------------------------------------------------------------- proc blt::Hiertable::MovePage { widget where } { # If the focus is already at the top/bottom of the window, we want # to scroll a page. It's really one page minus an entry because we # want to see the last entry on the next/last page. if { [$widget index focus] == [$widget index view.$where] } { if {$where == "top"} { $widget yview scroll -1 pages $widget yview scroll 1 units } else { $widget yview scroll 1 pages $widget yview scroll -1 units } } update # Adjust the entry focus and the view. Also activate the entry. # just in case the mouse point is not in the widget. $widget entry highlight view.$where $widget focus view.$where $widget see view.$where if { [$widget cget -selectmode] == "single" } { $widget selection clearall $widget selection set focus } } # ---------------------------------------------------------------------- # USAGE: blt::Hiertable::NextMatchingEntry <hiertable> <char> # Arguments: hiertable hierarchy widget # # Invoked by KeyPress bindings. Searches for an entry that starts # with the letter <char> and makes that entry active. # ---------------------------------------------------------------------- proc blt::Hiertable::NextMatchingEntry { widget key } { if {[string match {[ -~]} $key]} { set last [$widget index focus] set next [$widget index next] while { $next != $last } { set label [$widget entry cget $next -label] if { [string index $label 0] == $key } { break } set next [$widget index -at $next next] } $widget focus $next if {[$widget cget -selectmode] == "single"} { $widget selection clearall $widget selection set focus } $widget see focus } } # # Edit mode assignments # # ButtonPress-3 Enables/disables edit mode on entry. Sets focus to # entry. # # KeyPress # # Left Move insertion position to previous. # Right Move insertion position to next. # Up Move insertion position up one line. # Down Move insertion position down one line. # Return End edit mode. # Shift-Return Line feed. # Home Move to first position. # End Move to last position. # ASCII char Insert character left of insertion point. # Del Delete character right of insertion point. # Delete Delete character left of insertion point. # Ctrl-X Cut # Ctrl-V Copy # Ctrl-P Paste # # KeyRelease # # ButtonPress-1 Start selection if in entry, otherwise clear selection. # B1-Motion Extend/reduce selection. # ButtonRelease-1 End selection if in entry, otherwise use last selection. # B1-Enter Disabled. # B1-Leave Disabled. # ButtonPress-2 Same as above. # B2-Motion Same as above. # ButtonRelease-2 Same as above. # # All bindings in editting mode will "break" to override other bindings. # # bind xEditor <ButtonPress-3> { set node [%W nearest %x %y] %W entry insert $node @%x,%y "" # %W entry insert $node 2 "" } image create photo blt::Hiertable::CloseNormalFolder -format gif -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } image create photo blt::Hiertable::OpenNormalFolder -format gif -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } image create photo blt::Hiertable::CloseActiveFolder -format gif -data { R0lGODlhEAANAMIAAAAAAH9/f/////+/AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } image create photo blt::Hiertable::OpenActiveFolder -format gif -data { R0lGODlhEAANAMIAAAAAAH9/f/////+/AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } if { $tcl_platform(platform) == "windows" } { if { $tk_version >= 8.3 } { set cursor "@[file join $blt_library treeview.cur]" } else { set cursor "size_we" } option add *Hiertable.ResizeCursor [list $cursor] } else { option add *Hiertable.ResizeCursor \ "@$blt_library/treeview.xbm $blt_library/treeview_m.xbm black white" } # Standard Motif bindings: bind HiertableEditor <ButtonPress-1> { %W text icursor @%x,%y } bind HiertableEditor <Left> { %W text icursor last } bind HiertableEditor <Right> { %W text icursor next } bind HiertableEditor <Shift-Left> { set new [expr {[%W text index insert] - 1}] if {![%W text selection present]} { %W text selection from insert %W text selection to $new } else { %W text selection adjust $new } %W text icursor $new } bind HiertableEditor <Shift-Right> { set new [expr {[%W text index insert] + 1}] if {![%W text selection present]} { %W text selection from insert %W text selection to $new } else { %W text selection adjust $new } %W text icursor $new } bind HiertableEditor <Home> { %W text icursor 0 } bind HiertableEditor <Shift-Home> { set new 0 if {![%W text selection present]} { %W text selection from insert %W text selection to $new } else { %W text selection adjust $new } %W text icursor $new } bind HiertableEditor <End> { %W text icursor end } bind HiertableEditor <Shift-End> { set new end if {![%W text selection present]} { %W text selection from insert %W text selection to $new } else { %W text selection adjust $new } %W text icursor $new } bind HiertableEditor <Delete> { if { [%W text selection present]} { %W text delete sel.first sel.last } else { %W text delete insert } } bind HiertableEditor <BackSpace> { if { [%W text selection present] } { %W text delete sel.first sel.last } else { set index [expr [%W text index insert] - 1] if { $index >= 0 } { %W text delete $index $index } } } bind HiertableEditor <Control-space> { %W text selection from insert } bind HiertableEditor <Select> { %W text selection from insert } bind HiertableEditor <Control-Shift-space> { %W text selection adjust insert } bind HiertableEditor <Shift-Select> { %W text selection adjust insert } bind HiertableEditor <Control-slash> { %W text selection range 0 end } bind HiertableEditor <Control-backslash> { %W text selection clear } bind HiertableEditor <KeyPress> { blt::Hiertable::Insert %W %A } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Escape, Return, and Tab. bind HiertableEditor <Alt-KeyPress> { # nothing } bind HiertableEditor <Meta-KeyPress> { # nothing } bind HiertableEditor <Control-KeyPress> { # nothing } bind HiertableEditor <Escape> { %W text cancel grab release %W } bind HiertableEditor <Return> { %W text apply grab release %W } bind HiertableEditor <Shift-Return> { blt::Hiertable::Insert %W "\n" } bind HiertableEditor <KP_Enter> { # nothing } bind HiertableEditor <Tab> { # nothing } if {![string compare $tcl_platform(platform) "macintosh"]} { bind HiertableEditor <Command-KeyPress> { # nothing } } # On Windows, paste is done using Shift-Insert. Shift-Insert already # generates the <<Paste>> event, so we don't need to do anything here. if { [string compare $tcl_platform(platform) "windows"] != 0 } { bind HiertableEditor <Insert> { catch {blt::Hiertable::Insert %W [selection get -displayof %W]} } } # Additional emacs-like bindings: bind HiertableEditor <ButtonPress-3> { if { [winfo viewable %W] } { grab release %W %W text cancel } } bind HiertableEditor <Control-a> { %W text icursor 0 %W text selection clear } bind HiertableEditor <Control-b> { %W text icursor [expr {[%W index insert] - 1}] %W text selection clear } bind HiertableEditor <Control-d> { %W text delete insert } bind HiertableEditor <Control-e> { %W text icursor end %W text selection clear } bind HiertableEditor <Control-f> { %W text icursor [expr {[%W index insert] + 1}] %W text selection clear } bind HiertableEditor <Control-h> { if {[%W text selection present]} { %W text delete sel.first sel.last } else { set index [expr [%W text index insert] - 1] if { $index >= 0 } { %W text delete $index $index } } } bind HiertableEditor <Control-k> { %W text delete insert end } # blt::Hiertable::Insert -- # Insert a string into an entry at the point of the insertion cursor. # If there is a selection in the entry, and it covers the point of the # insertion cursor, then delete the selection before inserting. # # Arguments: # w - The entry window in which to insert the string # s - The string to insert (usually just a single character) proc blt::Hiertable::Insert {w s} { if {![string compare $s ""]} { return } catch { set insert [$w text index insert] if {([$w text index sel.first] <= $insert) && ([$w text index sel.last] >= $insert)} { $w delete sel.first sel.last } } $w text insert insert $s } # tkEntryTranspose - # This procedure implements the "transpose" function for entry widgets. # It tranposes the characters on either side of the insertion cursor, # unless the cursor is at the end of the line. In this case it # transposes the two characters to the left of the cursor. In either # case, the cursor ends up to the right of the transposed characters. # # Arguments: # w - The entry window. proc HiertableTranspose w { set i [$w text index insert] if {$i < [$w text index end]} { incr i } set first [expr {$i-2}] if {$first < 0} { return } set new [string index [$w get] [expr {$i-1}]][string index [$w get] $first] $w delete $first $i $w insert insert $new } # Hiertable::GetSelection -- # # Returns the selected text of the entry with respect to the -show option. # # Arguments: # w - The entry window from which the text to get proc blt::Hiertable::GetSelection {w} { set entryString [string range [$w get] [$w index sel.first] \ [expr [$w index sel.last] - 1]] if {[$w cget -show] != ""} { regsub -all . $entryString [string index [$w cget -show] 0] entryString } return $entryString } if 0 { bind HiertableEditor <Control-t> { tkEntryTranspose %W } bind HiertableEditor <Meta-b> { %W text icursor [blt::Hiertable::PreviousWord %W insert] %W text selection clear } bind HiertableEditor <Meta-d> { %W delete insert [blt::Hiertable::NextWord %W insert] } bind HiertableEditor <Meta-f> { %W text icursor [blt::Hiertable::NextWord %W insert] %W text selection clear } bind HiertableEditor <Meta-BackSpace> { %W delete [blt::Hiertable::PreviousWord %W insert] insert } bind HiertableEditor <Meta-Delete> { %W delete [blt::Hiertable::PreviousWord %W insert] insert } # tkEntryNextWord -- Returns the index of the next word position # after a given position in the entry. The next word is platform # dependent and may be either the next end-of-word position or the # next start-of-word position after the next end-of-word position. # # Arguments: # w - The entry window in which the cursor is to move. # start - Position at which to start search. if {![string compare $tcl_platform(platform) "windows"]} { proc blt::Hiertable::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos >= 0} { set pos [tcl_startOfNextWord [$w get] $pos] } if {$pos < 0} { return end } return $pos } } else { proc blt::Hiertable::NextWord {w start} { set pos [tcl_endOfWord [$w get] [$w index $start]] if {$pos < 0} { return end } return $pos } } # blt::Hiertable::PreviousWord -- # # Returns the index of the previous word position before a given # position in the entry. # # Arguments: # w - The entry window in which the cursor is to move. # start - Position at which to start search. proc blt::Hiertable::PreviousWord {w start} { set pos [tcl_startOfPreviousWord [$w get] [$w index $start]] if {$pos < 0} { return 0 } return $pos } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/combomenu.tcl�������������������������������������������������������������0000644�0001750�0001750�00000035250�11462120062�016377� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� namespace eval ::blt::ComboMenu { variable _private array set _private { activeComboMenu "" activeItem "" afterId -1 b1 "" lastFocus "" menuBar "" oldGrab "" popup "" postingMenu "" trace 0 } proc trace { mesg } { variable _private if { $_private(trace) } { puts stderr $mesg } } } # ----------------------------------------------------------------------------- # Must set focus when mouse enters a menu, in order to allow # mixed-mode processing using both the mouse and the keyboard. # Don't set the focus if the event comes from a grab release, # though: such an event can happen after as part of unposting # a cascaded chain of menus, after the focus has already been # restored to wherever it was before menu selection started. bind ComboMenu <FocusIn> {} bind ComboMenu <Enter> { blt::ComboMenu::trace "blt::ComboMenu %W <Enter>" focus %W } bind ComboMenu <Leave> { blt::ComboMenu::trace "blt::ComboMenu %W <Leave> %s" if { %s == 0 } { #%W activate none } } bind ComboMenu <Motion> { #blt::ComboMenu::trace "blt::ComboMenu Motion %x,%y" %W activate @%x,%y %W postcascade active } bind ComboMenu <ButtonRelease-1> { blt::ComboMenu::trace "blt::ComboMenu %W at %x,%y ButtonRelease-1" set index [%W index @%x,%y] if { $index == -1 } { blt::ComboMenu::trace "ButtonRelease-1: failed to find item in %W" blt::ComboMenu::SimulateButtonRelease %W } else { %W activate $index blt::ComboMenu::trace "ButtonRelease-1: activated $index" if { [%W type active] == "cascade" } { blt::ComboMenu::trace "ButtonRelease-1: posting cascade for $index" %W postcascade active blt::ComboMenu::PostMenu %W active } else { blt::ComboMenu::trace "ButtonRelease-1: %W invoke active ($index)" blt::ComboMenu::SimulateButtonRelease %W update %W invoke active } } } bind ComboMenu <ButtonPress-1> { blt::ComboMenu::trace "blt::ComboMenu ButtonPress-1" } bind ComboMenu <ButtonPress-2> { blt::ComboMenu::trace "blt::ComboMenu %W ButtonPress-2" set w [grab current] $w configure -cursor diamond_cross update %W scan mark %x %y } bind ComboMenu <B2-Motion> { %W scan dragto %x %y } bind ComboMenu <ButtonRelease-2> { blt::ComboMenu::trace "blt::ComboMenu %W ButtonRelease-2" set w [grab current] $w configure -cursor arrow } bind ComboMenu <ButtonPress-3> { blt::ComboMenu::trace "blt::ComboMenu ButtonPress-3" blt::ComboMenu::UnpostMenu %W } bind xComboMenu <ButtonRelease-3> { blt::ComboMenu::trace "blt::ComboMenu ButtonRelease-3" if { $blt::ComboMenu::_private(popup) != "" } { blt::ComboMenu::popup %W %X %Y } } bind ComboMenu <KeyPress-space> { if { [%W type active] == "cascade" } { %W postcascade active blt::ComboMenu::PostMenu %W active } else { blt::ComboMenu::SimulateButtonRelease %W %W invoke active } } bind ComboMenu <KeyRelease> { if { [string compare %A {}] == 0 } { continue } set index [%W find "%A" -underline] if { $index >= 0 } { %W activate $index %W see $index } } # KeyPress-Return -- # # If the menu item selected is a cascade menu, then post the cascade. # Otherwise tell the combobutton or comboentry that we've selected # something by simulating a button release. This will unpost all the # posted menus. Set the root coordinates of the event to be offscreen # so that we don't inadvertantly lie over the arrow of the button. # bind ComboMenu <KeyPress-Return> { if { [%W type active] == "cascade" } { %W postcascade active blt::ComboMenu::PostMenu %W active } else { %W invoke active blt::ComboMenu::SimulateButtonRelease %W } } bind ComboMenu <Escape> { blt::ComboMenu::SimulateButtonRelease %W } bind ComboMenu <Left> { set menu [winfo parent %W] if { [winfo class $menu] == "ComboMenu" } { $menu postcascade none focus $menu } } bind ComboMenu <Right> { if { [%W type active] == "cascade" } { %W postcascade active set menu [%W item cget active -menu] focus $menu } } bind ComboMenu <KeyPress-Up> { %W activate previous %W see active } bind ComboMenu <KeyPress-Down> { %W activate next %W see active } bind ComboMenu <KeyPress-Home> { %W activate first %W see active } bind ComboMenu <KeyPress-End> { %W activate end %W see active } bind ComboMenu <KeyPress-Prior> { %W yview scroll -1 page %W activate view.top %W see active } bind ComboMenu <KeyPress-Next> { %W yview scroll 1 page %W activate view.bottom %W see active } # The following bindings apply to all windows, and are used to implement # keyboard menu traversal. if { [tk windowingsystem] == "x11" } { bind all <Alt-KeyPress> { blt::ComboMenu::Traverse %W %A } bind all <F10> { blt::ComboMenu::FirstItem %W } } else { bind ComboMenubutton <Alt-KeyPress> { blt::ComboMenu::Traverse %W %A } bind ComboMenubutton <F10> { blt::ComboMenu::First %W } } if { [tk windowingsystem] == "x11" } { bind ComboMenu <4> { %W yview scroll -5 units } bind ComboMenu <5> { %W yview scroll 5 units } } else { bind ComboMenu <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } } # ::blt::ComboMenu::UnpostMenu -- # # This procedure unposts a given menu, plus all of its ancestors up # to (and including) a menubutton, if any. It also restores various # values to what they were before the menu was posted, and releases # a grab if there's a menubutton involved. Special notes: # 1. It's important to unpost all menus before releasing the grab, so # that any Enter-Leave events (e.g. from menu back to main # application) have mode NotifyGrab. # 2. Be sure to enclose various groups of commands in "catch" so that # the procedure will complete even if the menubutton or the menu # or the grab window has been deleted. # # Arguments: # menu - Name of a menu to unpost. Ignored if there # is a posted menubutton. proc ::blt::ComboMenu::UnpostMenu { menu } { variable _private trace "proc ComboMenu::UnpostMenu $menu" set mb $_private(postingMenu) set mb "" # Restore focus right away (otherwise X will take focus away when the menu # is unmapped and under some window managers (e.g. olvwm) we'll lose the # focus completely). catch {focus $_private(lastFocus)} set _private(lastFocus) "" # Unpost menu(s) and restore some stuff that's dependent on what was # posted. catch { if { $mb != "" } { set menu [$mb cget -menu] $menu unpost set _private(postingMenu) {} $mb configure -cursor $_private(cursor) if { [$mb cget -arrowrelief] == "sunken" } { $mb configure -arrowrelief $_private(relief) } } elseif { $_private(popup) != "" } { $_private(popup) unpost set _private(popup) {} } else { # We're in a cascaded sub-menu from a tearoff menu or popup. # Unpost all the menus up to the toplevel one (but not including # the top-level torn-off one) and deactivate the top-level torn # off menu if there is one. while {1} { set parent [winfo parent $menu] if { [winfo class $parent] != "ComboMenu" || ![winfo ismapped $parent]} { break } $parent activate none $parent postcascade none ComboMenu::GenerateSelect $parent set menu $parent } $menu unpost } } if { $mb != "" && [$mb cget -state] != "disabled" } { $mb configure -state normal } trace menuBar=$_private(menuBar) trace menu=$menu trace grab=[grab current $menu] # Release grab, if any, and restore the previous grab, if there # was one. if { $menu != "" } { set grab [grab current $menu] if { $grab != "" } { grab release $grab } } RestoreOldGrab if { $_private(menuBar) != "" } { $_private(menuBar) configure -cursor $_private(cursor) set _private(menuBar) {} } } proc ::blt::ComboMenu::SimulateButtonRelease { w } { set grab [grab current] if { $grab != "$w" } { event generate $grab <ButtonRelease-1> -rootx -1000 -rooty -1000 } else { $w unpost RestoreOldGrab } } proc ::blt::ComboMenu::PostMenu { w item } { variable _private trace "proc ComboMenu::PostMenu $w, item=$item" if { [$w item cget $item -state] == "disabled" } { return } set menu [$w item cget $item -menu] if { $menu == "" } { return } #$menu activate none set _private(lastFocus) [focus] GenerateSelect $menu # If this looks like an option menubutton then post the menu so # that the current entry is on top of the mouse. Otherwise post # the menu just below the menubutton, as for a pull-down. update idletasks if { [catch { $w postcascade $item } msg] != 0 } { # Error posting menu (e.g. bogus -postcommand). Unpost it and # reflect the error. global errorInfo set savedInfo $errorInfo # #MbUnpost $w error $msg $savedInfo } focus $menu $menu activate first if { [winfo viewable $menu] } { SaveGrab $menu trace "setting global grab on $menu" grab -global $menu } } # ::blt::xxxComboMenuUnpost -- # This procedure unposts a given menu, plus all of its ancestors up # to (and including) a menubutton, if any. It also restores various # values to what they were before the menu was posted, and releases # a grab if there's a menubutton involved. Special notes: # 1. It's important to unpost all menus before releasing the grab, so # that any Enter-Leave events (e.g. from menu back to main # application) have mode NotifyGrab. # 2. Be sure to enclose various groups of commands in "catch" so that # the procedure will complete even if the menubutton or the menu # or the grab window has been deleted. # # Arguments: # menu - Name of a menu to unpost. Ignored if there # is a posted menubutton. proc ::blt::xxxComboMenuUnpost { w } { variable _private trace "proc ComboMenuUnpost $w" catch { # Restore focus right away (otherwise X will take focus away when the # menu is unmapped and under some window managers (e.g. olvwm) we'll # lose the focus completely). focus $_private(lastFocus) } set _private(lastFocus) "" # Unpost menu(s) and restore some stuff that's dependent on what was # posted. $w unpost #set _private(postingMenu) {} $w configure -cursor $_private(cursor) if { [$w cget -state] != "disabled" } { #$w configure -state normal } set menu [$w cget -menu] trace MENU=$menu trace GRAB=[grab current $menu] # Release grab, if any, and restore the previous grab, if there # was one. if { $menu != "" } { set grab [grab current $menu] if { $grab != "" } { #grab release $grab } } RestoreOldGrab } # ::blt::SaveGrab -- # Sets the variable blt::_private(oldGrab) to record # the state of any existing grab on the w's display. # # Arguments: # w - Name of a window; used to select the display # whose grab information is to be recorded. proc blt::ComboMenu::SaveGrab { w } { variable _private set grab [grab current $w] set _private(oldGrab) "" if { $grab != "" } { set type [grab status $grab] if { $type == "global" } { #set _private(oldGrab) [list grab set -global $grab] } else { #set _private(oldGrab) [list grab set $grab] } } } # ::blt::RestoreOldGrab -- # Restores the grab to what it was before TkSaveGrabInfo was called. # proc ::blt::ComboMenu::RestoreOldGrab {} { variable _private trace "RestoreOldGrab: current=[grab current] old=$_private(oldGrab)" if { $_private(oldGrab) != "" } { # Be careful restoring the old grab, since it's window may not # be visible anymore. catch $_private(oldGrab) set _private(oldGrab) "" } else { grab release [grab current] } } proc ::blt::xxxComboMenuSetFocus {menu} { variable _private if { $_private(lastFocus) == "" } { set _private(lastFocus) [focus] } focus $menu } proc ::blt::ComboMenu::GenerateSelect {menu} { variable _private if { $_private(activeComboMenu) == $menu && $_private(activeItem) == [$menu index active] } { return } set _private(activeComboMenu) $menu set _private(activeItem) [$menu index active] event generate $menu <<MenuSelect>> } bind ComboMenu <B1-Enter> { after cancel $blt::ComboMenu::_private(afterId) set blt::ComboMenu::_private(afterId) -1 } bind ComboMenu <B1-Leave> { blt::ComboMenu::trace "ComboMenu B1-Leave" blt::ComboMenu::AutoScroll %W %x %y } bind ComboMenu <Unmap> { after cancel $blt::ComboMenu::_private(afterId) set blt::ComboMenu::_private(afterId) -1 } proc ::blt::ComboMenu::AutoScroll {w x y} { variable _private trace "autoscan $w $y" if { ![winfo exists $w] } { return } set i -1 if { $y >= [winfo height $w] } { set i [$w next view.bottom] } elseif { $y < 0 } { set i [$w previous view.top] } if { $i > 0 } { trace $i $w activate $i $w see $i } set cmd [list blt::ComboMenu::AutoScroll $w $x $y] set _private(afterId) [after 50 $cmd] } proc blt::ComboMenu::ConfigureScrollbars { menu } { set ys [$menu cget -yscrollbar] if { $ys != "" } { if { [$menu cget -yscrollcommand] == "" } { $menu configure -yscrollcommand [list $ys set] } if { [$ys cget -command] == "" } { $ys configure -command [list $menu yview] -orient vertical \ -highlightthickness 0 } } set xs [$menu cget -xscrollbar] if { $xs != "" } { if { [$menu cget -xscrollcommand] == "" } { $menu configure -xscrollcommand [list $xs set] } if { [$xs cget -command] == "" } { $xs configure -command [list $menu xview] -orient horizontal \ -highlightthickness 0 } } } # ::tk_popup -- # This procedure pops up a menu and sets things up for traversing # the menu and its submenus. # # Arguments: # menu - Name of the menu to be popped up. # x, y - Root coordinates at which to pop up the # menu. # entry - Index of a menu entry to center over (x,y). # If omitted or specified as {}, then menu's # upper-left corner goes at (x,y). proc ::blt::ComboMenu::popup { menu x y } { variable _private blt::ComboMenu::trace "blt::ComboMenu::popup $menu $x $y" blt::ComboMenu::trace "blt::ComboMenu::popup popup=$_private(popup)" if { [grab current] == $menu } { blt::ComboMenu::trace "blt::ComboMenu::popup unposting $menu" UnpostMenu $menu } else { blt::ComboMenu::trace "blt::ComboMenu::popup posting $menu" $menu post $x $y popup if { [tk windowingsystem] == "x11" && [winfo viewable $menu] } { set _private(activeComboMenu) $menu set _private(popup) $menu SaveGrab $menu trace "popup: setting global grab on $menu" grab -global $menu focus $menu } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/Makefile.in���������������������������������������������������������������0000644�0001750�0001750�00000003672�11462120062�015757� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for library files and directories of BLT library # ------------------------------------------------------------------------ datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ libdir = @libdir@ prefix = @prefix@ srcdir = @srcdir@ version = @BLT_VERSION@ so_prefix = @BLT_SO_PREFIX@ so_ext = @BLT_SO_EXT@ lib_suffix = @BLT_LIB_SUFFIX@ pkgdir = @BLT_LIBRARY@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ RM = rm -f SHELL = /bin/sh MKDIR_P = @MKDIR_P@ cursors = treeview.xbm \ treeview_m.xbm WIN32 = @WIN32@ ifneq ("$(WIN32)", "") cursors += treeview.cur endif libraryFiles = \ bltCanvEps.pro \ bltGraph.pro \ combobutton.tcl \ comboentry.tcl \ combomenu.tcl \ combotree.tcl \ dnd.tcl \ dragdrop.tcl \ drawer.tcl \ filmstrip.tcl \ graph.tcl \ listview.tcl \ paneset.tcl \ pushbutton.tcl \ unixButton.tcl \ macButton.tcl \ winButton.tcl \ scrollbar.tcl \ scrollset.tcl \ tabset.tcl \ treeview.tcl \ tclIndex \ $(cursors) ddFiles = dd-color.tcl \ dd-file.tcl \ dd-number.tcl \ dd-text.tcl \ tclIndex all: pkgIndex pkgIndex: rm -f pkgIndex.tcl sed -e 's/%VERSION%/$(version)/' $(srcdir)/pkgIndex.tcl.in | \ sed -e 's/%SO_PREFIX%/$(so_prefix)/' | \ sed -e 's/%LIB_SUFFIX%/$(lib_suffix)/' | \ sed -e 's/%SO_EXT%/$(so_ext)/' | \ sed -e 's;%LIB_DIR%;$(libdir);' > pkgIndex.tcl install: mkdirs pkgIndex for i in $(ddFiles) ; do \ $(INSTALL_DATA) $(srcdir)/dd_protocols/$$i \ $(DESTDIR)$(pkgdir)/dd_protocols ; \ done for i in $(libraryFiles) ; do \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(pkgdir) ; \ done $(INSTALL_DATA) pkgIndex.tcl $(pkgdir) $(MAKE) -C afm install mkdirs: $(MKDIR_P) $(DESTDIR)/$(pkgdir) $(MKDIR_P) $(DESTDIR)/$(pkgdir)/dd_protocols clean: $(RM) pkgIndex.tcl distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile ����������������������������������������������������������������������./saods9/blt3.0.1/library/pushbutton.tcl������������������������������������������������������������0000644�0001750�0001750�00000007117�11462120062�016627� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # button.tcl -- # # This file defines the default bindings for Tk label, button, # checkbutton, and radiobutton widgets and provides procedures # that help in implementing those bindings. # # RCS: @(#) $Id: pushbutton.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 2002 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # namespace eval blt::Button { array set _private { afterId -1 repeated "" window "" trace 0 buttonWindow "" } proc trace { mesg } { variable _private if { $_private(trace) } { puts stderr $mesg } } } #------------------------------------------------------------------------- # The code below creates the default class bindings for buttons. #------------------------------------------------------------------------- switch -glob -- [tk windowingsystem] { "classic" - "aqua" { source [file join $blt_library macButton.tcl] } "x11" { source [file join $blt_library unixButton.tcl] } "win*" { source [file join $blt_library winButton.tcl] } } ################## # Shared routines ################## # Invoke -- # # The procedure below is called when a button is invoked through # the keyboard. It simulates a press of the button via the mouse. # # Arguments: # w - The name of the widget. proc ::blt::Button::Invoke w { if {[$w cget -state] != "disabled"} { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken update idletasks after 100 $w configure -state $oldState -relief $oldRelief uplevel #0 [list $w invoke] } } # ::blt::Button::AutoInvoke -- # # Invoke an auto-repeating button, and set it up to continue to repeat. # # Arguments: # w button to invoke. # # Results: # None. # # Side effects: # May create an after event to call ::blt::Button::AutoInvoke. proc ::blt::Button::AutoInvoke {w} { variable _private after cancel $_private(afterId) set delay [$w cget -repeatinterval] if {$_private(window) eq $w} { incr _private(repeated) uplevel #0 [list $w invoke] } if {$delay > 0} { set _private(afterId) [after $delay [list blt::Button::AutoInvoke $w]] } } # ::blt::Button::CheckRadioInvoke -- # The procedure below is invoked when the mouse button is pressed in # a checkbutton or radiobutton widget, or when the widget is invoked # through the keyboard. It invokes the widget if it # isn't disabled. # # Arguments: # w - The name of the widget. # cmd - The subcommand to invoke (one of invoke, select, or deselect). proc ::blt::Button::CheckRadioInvoke {w {cmd invoke}} { if {[$w cget -state] != "disabled"} { uplevel #0 [list $w $cmd] } } bind TkButton <space> { blt::Button::Invoke %W } bind TkCheckbutton <space> { blt::Button::CheckRadioInvoke %W } bind TkRadiobutton <space> { blt::Button::CheckRadioInvoke %W } bind TkPushbutton <space> { blt::Button::CheckRadioInvoke %W } bind TkButton <FocusIn> { } bind TkButton <Enter> { blt::Button::Enter %W } bind TkButton <Leave> { blt::Button::Leave %W } bind TkButton <1> { blt::Button::Down %W } bind TkButton <ButtonRelease-1> { blt::Button::Up %W } bind TkCheckbutton <FocusIn> { } bind TkCheckbutton <Leave> { blt::Button::Leave %W } bind TkRadiobutton <FocusIn> {} bind TkRadiobutton <Leave> { blt::Button::Leave %W } bind TkPushbutton <FocusIn> {} bind TkPushbutton <Leave> { blt::Button::Leave %W } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/tabset.tcl����������������������������������������������������������������0000644�0001750�0001750�00000026734�11462120062�015704� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # # tabset.tcl # # ---------------------------------------------------------------------- # Bindings for the BLT tabset widget # ---------------------------------------------------------------------- # AUTHOR: George Howlett # Bell Labs Innovations for Lucent Technologies # gah@bell-labs.com # http://www.tcltk.com/blt # ---------------------------------------------------------------------- # Copyright (c) 1998 Lucent Technologies, Inc. # ====================================================================== # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that the copyright notice and warranty disclaimer appear in # supporting documentation, and that the names of Lucent Technologies # any of their entities not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # Lucent Technologies disclaims all warranties with regard to this # software, including all implied warranties of merchantability and # fitness. In no event shall Lucent be liable for any special, indirect # or consequential damages or any damages whatsoever resulting from loss # of use, data or profits, whether in an action of contract, negligence # or other tortuous action, arising out of or in connection with the use # or performance of this software. # # ====================================================================== # # Indicates whether to activate (highlight) tabs when the mouse passes # over them. This is turned off during scan operations. # namespace eval blt { namespace eval Tabset { variable privateData set privateData(activate) yes } } # ---------------------------------------------------------------------- # # ButtonPress assignments # # <ButtonPress-2> Starts scan mechanism (pushes the tabs) # <B2-Motion> Adjust scan # <ButtonRelease-2> Stops scan # <ButtonPress-3> Starts scan mechanism (pushes the tabs) # <B3-Motion> Adjust scan # <ButtonRelease-3> Stops scan # # ---------------------------------------------------------------------- bind Tabset <B2-Motion> { %W scan dragto %x %y } bind Tabset <ButtonPress-2> { set blt::Tabset::privateData(cursor) [%W cget -cursor] set blt::Tabset::privateData(activate) no %W configure -cursor hand1 %W scan mark %x %y } bind Tabset <ButtonRelease-2> { %W configure -cursor $::blt::Tabset::privateData(cursor) set blt::Tabset::privateData(activate) yes %W activate @%x,%y } bind Tabset <B3-Motion> { %W scan dragto %x %y } bind Tabset <ButtonPress-3> { set blt::Tabset::privateData(cursor) [%W cget -cursor] set blt::Tabset::privateData(activate) no %W configure -cursor hand1 %W scan mark %x %y } bind Tabset <ButtonRelease-3> { %W configure -cursor $blt::Tabset::privateData(cursor) set blt::Tabset::privateData(activate) yes %W activate @%x,%y } # ---------------------------------------------------------------------- # # KeyPress assignments # # <KeyPress-Up> Moves focus to the tab immediately above the # current. # <KeyPress-Down> Moves focus to the tab immediately below the # current. # <KeyPress-Left> Moves focus to the tab immediately left of the # currently focused tab. # <KeyPress-Right> Moves focus to the tab immediately right of the # currently focused tab. # <KeyPress-space> Invokes the commands associated with the current # tab. # <KeyPress-Return> Same as above. # <KeyPress> Go to next tab starting with the ASCII character. # <KeyPress-End> Moves focus to the last tab. # <KeyPress-Home> Moves focus to the last tab. # # ---------------------------------------------------------------------- bind Tabset <KeyPress-Up> { blt::Tabset::MoveFocus %W "up" } bind Tabset <KeyPress-Down> { blt::Tabset::MoveFocus %W "down" } bind Tabset <KeyPress-Right> { blt::Tabset::MoveFocus %W "right" } bind Tabset <KeyPress-Left> { blt::Tabset::MoveFocus %W "left" } bind Tabset <KeyPress-Home> { blt::Tabset::MoveFocus %W "first" } bind Tabset <KeyPress-End> { blt::Tabset::MoveFocus %W "last" } bind Tabset <KeyPress-space> { blt::Tabset::Select %W "focus" } bind Tabset <KeyPress-Return> { %W invoke focus } bind Tabset <KeyPress> { if { [string match {[A-Za-z0-9]*} "%A"] } { blt::Tabset::FindMatch %W %A } } # ---------------------------------------------------------------------- # # FindMatch -- # # Find the first tab (from the tab that currently has focus) # starting with the same first letter as the tab. It searches # in order of the tab positions and wraps around. If no tab # matches, it stops back at the current tab. # # Arguments: # widget Tabset widget. # key ASCII character of key pressed # # ---------------------------------------------------------------------- proc blt::Tabset::FindMatch { w key } { set key [string tolower $key] set itab [$w index focus] set numTabs [$w size] for { set i 0 } { $i < $numTabs } { incr i } { if { [incr itab] >= $numTabs } { set itab 0 } set label [string tolower [$w tab cget $itab -text]] if { [string index $label 0] == $key } { break } } $w focus $itab $w see focus } # ---------------------------------------------------------------------- # # Select -- # # Invokes the command for the tab. If the widget associated tab # is currently torn off, the tearoff is raised. # # Arguments: # widget Tabset widget. # x y Unused. # # ---------------------------------------------------------------------- proc blt::Tabset::Select { w tab } { set index [$w index $tab] if { $index != "" } { $w select $index $w focus $index $w see $index set tearoff [$w tearoff $index] if { ($tearoff != "") && ($tearoff != "$w") } { raise [winfo toplevel $tearoff] } $w invoke $index } } # ---------------------------------------------------------------------- # # MoveFocus -- # # Invokes the command for the tab. If the widget associated tab # is currently torn off, the tearoff is raised. # # Arguments: # widget Tabset widget. # x y Unused. # # ---------------------------------------------------------------------- proc blt::Tabset::MoveFocus { w tab } { set index [$w index $tab] if { $index != "" } { $w focus $index $w see $index } } # ---------------------------------------------------------------------- # # DestroyTearoff -- # # Destroys the toplevel window and the container tearoff # window holding the embedded widget. The widget is placed # back inside the tab. # # Arguments: # widget Tabset widget. # tab Tab selected. # # ---------------------------------------------------------------------- proc blt::Tabset::DestroyTearoff { w tab } { set id [$w id $tab] set top "$w.toplevel-$id" if { [winfo exists $top] } { wm withdraw $top update $w tearoff $tab $w destroy $top } } # ---------------------------------------------------------------------- # # CreateTearoff -- # # Creates a new toplevel window and moves the embedded widget # into it. The toplevel is placed just below the tab. The # DELETE WINDOW property is set so that if the toplevel window # is requested to be deleted by the window manager, the embedded # widget is placed back inside of the tab. Note also that # if the tabset container is ever destroyed, the toplevel is # also destroyed. # # Arguments: # widget Tabset widget. # tab Tab selected. # x y The coordinates of the mouse pointer. # # ---------------------------------------------------------------------- proc blt::Tabset::CreateTearoff { w tab rootX rootY } { # ------------------------------------------------------------------ # When reparenting the window contained in the tab, check if the # window or any window in its hierarchy currently has focus. # Since we're reparenting windows behind its back, Tk can # mistakenly activate the keyboard focus when the mouse enters the # old toplevel. The simplest way to deal with this problem is to # take the focus off the window and set it to the tabset widget # itself. # ------------------------------------------------------------------ set focus [focus] set win [$w tab cget $tab -window] set index [$w index $tab] if { ($focus == $w) || ([string match ${win}.* $focus]) } { focus -force $w } set id [$w id $index] set top "$w.toplevel-$id" toplevel $top $w tearoff $tab $top.container blt::table $top 0,0 $top.container -fill both incr rootX 10 ; incr rootY 10 wm geometry $top +$rootX+$rootY set parent [winfo toplevel $w] wm title $top "[wm title $parent]: [$w tab cget $index -text]" #wm transient $top $parent # If the user tries to delete the toplevel, put the window back # into the tab folder. wm protocol $top WM_DELETE_WINDOW \ [list blt::Tabset::DestroyTearoff $w $tab] # If the container is ever destroyed, automatically destroy the # toplevel too. bind $top.container <Destroy> [list destroy $top] } # ---------------------------------------------------------------------- # # ToggleTearoff -- # # Toggles the tab tearoff. If the tab contains a embedded widget, # it is placed inside of a toplevel window. If the widget has # already been torn off, the widget is replaced back in the tab. # # Arguments: # widget tabset widget. # x y The coordinates of the mouse pointer. # # ---------------------------------------------------------------------- proc blt::Tabset::ToggleTearoff { w index } { set tab [$w index $index] if { $tab == "" } { return } $w invoke $tab set win [$w tearoff $index] if { $win == "$w" } { foreach { x1 y1 x2 y2 } [$w extents $tab] break CreateTearoff $w $tab $x1 $y1 } elseif { $win != "" } { DestroyTearoff $w $tab } } # ---------------------------------------------------------------------- # # Init # # Invoked from C whenever a new tabset widget is created. # Sets up the default bindings for the all tab entries. # These bindings are local to the widget, so they can't be # set through the usual widget class bind tags mechanism. # # <Enter> Activates the tab. # <Leave> Deactivates all tabs. # <ButtonPress-1> Selects the tab and invokes its command. # <Control-ButtonPress-1> # Toggles the tab tearoff. If the tab contains # a embedded widget, it is placed inside of a # toplevel window. If the widget has already # been torn off, the widget is replaced back # in the tab. # # Arguments: # widget tabset widget # # ---------------------------------------------------------------------- proc blt::Tabset::Init { w } { $w bind all <Enter> { if { $::blt::Tabset::privateData(activate) } { %W activate current } } $w bind all <Leave> { %W activate "" } $w bind all <ButtonPress-1> { blt::Tabset::Select %W "current" } $w bind all <Control-ButtonPress-1> { blt::Tabset::ToggleTearoff %W active } $w configure -perforationcommand [list blt::Tabset::ToggleTearoff $w] $w bind Perforation <Enter> { %W perforation activate on } $w bind Perforation <Leave> { %W perforation activate off } $w bind Perforation <ButtonRelease-1> { %W perforation invoke } $w bind Button <Enter> { %W button activate current } $w bind Button <Leave> { %W button activate "" } $w bind Button <ButtonRelease-1> { if { [catch {%W close current}] == 0 } { %W delete current } } } ������������������������������������./saods9/blt3.0.1/library/treeview_m.xbm������������������������������������������������������������0000644�0001750�0001750�00000000513�11462120062�016557� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define testm_width 16 #define testm_height 16 #define testm_x_hot 7 #define testm_y_hot 7 static unsigned char testm_bits[] = { 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfc, 0x3f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f}; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/filmstrip.tcl�������������������������������������������������������������0000644�0001750�0001750�00000002054�11462120062�016420� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������namespace eval blt::Filmstrip { set buttonPressed 0 proc Initialize {} { } } bind FilmstripHandle <Enter> { if { !$blt::Filmstrip::buttonPressed } { %W activate } } bind FilmstripHandle <Leave> { if { !$blt::Filmstrip::buttonPressed } { %W deactivate } } bind FilmstripHandle <KeyPress-Left> { %W move -10 0 } bind FilmstripHandle <KeyPress-Right> { %W move 10 0 } bind FilmstripHandle <KeyPress-Up> { %W move 0 -10 } bind FilmstripHandle <KeyPress-Down> { %W move 0 10 } bind FilmstripHandle <Shift-KeyPress-Left> { %W move -100 0 } bind FilmstripHandle <Shift-KeyPress-Right> { %W move 100 0 } bind FilmstripHandle <Shift-KeyPress-Up> { %W move 0 -100 } bind FilmstripHandle <Shift-KeyPress-Down> { %W move 0 100 } bind FilmstripHandle <ButtonPress-1> { set blt::Filmstrip::buttonPressed 1 %W anchor %X %Y } bind FilmstripHandle <B1-Motion> { %W mark %X %Y } bind FilmstripHandle <ButtonRelease-1> { set blt::Filmstrip::buttonPressed 0 %W set %X %Y } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/drawer.tcl����������������������������������������������������������������0000644�0001750�0001750�00000001365�11462120062�015677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������namespace eval blt::Drawer { set buttonPressed 0 proc Initialize {} { } } bind DrawerHandle <Enter> { if { !$blt::Drawer::buttonPressed } { %W activate } } bind DrawerHandle <Leave> { if { !$blt::Drawer::buttonPressed } { %W deactivate } } bind DrawerHandle <KeyPress-Left> { %W move -10 0 } bind DrawerHandle <KeyPress-Right> { %W move 10 0 } bind DrawerHandle <KeyPress-Up> { %W move 0 -10 } bind DrawerHandle <KeyPress-Down> { %W move 0 10 } bind DrawerHandle <ButtonPress-1> { set blt::Drawer::buttonPressed 1 %W anchor %X %Y } bind DrawerHandle <B1-Motion> { %W mark %X %Y } bind DrawerHandle <ButtonRelease-1> { set blt::Drawer::buttonPressed 0 %W set %X %Y } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/ZoomStack.itcl������������������������������������������������������������0000644�0001750�0001750�00000023160�11462120062�016473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import add itcl class ZoomStackGraph { # The name of graph (nee the namespace path) variable graph "" # Indicates which corner of the rectangular zoom region # is currently being choosen. variable corner "first" # Coordinates of the current zoom region. They represent the # two corners of a rectangular area. The two points are order # independent. variable x1 variable y1 variable x2 variable y2 # A list of axis configuration commmands. Acts as a stack to # unzoom the graph back to previous axis limits. variable stack {} constructor { args } { # This will need to change when we start using inheritance. set graph [info namespace tail $this] # What about collisions between the blt::graph instance # command and the ZoomStackGraph instance command? blt::graph $graph if { [llength $args] > 0 } { $graph configure $args } # Set up the bindings to select/deselect the zoom region bind $graph <1> [code $this SelectPoint %x %y] bind $graph <3> [code $this ClearZoom] # The particular mouse buttons should be configurable. } destructor { if { [winfo exists $graph] } { destroy $graph } } # These methods are used internally, within this class, to manage the # zoom stack. private method SaveCoords { x y } private method Zoom {} private method Unzoom {} private method Push { cmd } private method Pop {} private method MarkPoint { x y } private method SetTitle { title } private method DrawBox { } # These methods are called by "bind" and "after" from the Tk # event loop. Is there any way of hiding them, so that it # doesn't look to the user as part of the public interface? method ClearZoom {} method ClearTitle {} method UpdateOutline { x y } method SelectPoint { x y } } # ---------------------------------------------------------------------- # # SaveCoords -- # # Given a point on the screen, transforms the point into graph # coordinates and saves it as one of the points representing a # corner of the zoom region. # # ---------------------------------------------------------------------- body ZoomStackGraph::SaveCoords { x y } { set coords [$graph invtransform $x $y] set x [lindex $coords 0] set y [lindex $coords 1] scan [$graph xaxis limits] "%s %s" min max if { $x > $max } { set x $max } elseif { $x < $min } { set x $min } scan [$graph yaxis limits] "%s %s" min max if { $y > $max } { set y $max } elseif { $y < $min } { set y $min } if { $corner == "first" } { set x1 $x ; set y1 $y } else { set x2 $x ; set y2 $y } } # ---------------------------------------------------------------------- # # MarkPoint -- # # Adds text around one of the corners of the zoom region. # The text consists of the x,y graph coordinates of the # corner. # # ---------------------------------------------------------------------- body ZoomStackGraph::MarkPoint { x y } { set marker "bltZoom_text_$corner" set text [format "x=%.4g\ny=%.4g" $x $y] if [$graph marker exists $marker] { $graph marker configure $marker -coords { $x $y } -text $text } else { $graph marker create text -coords { $x $y } -name $marker \ -font *lucida*-r-*-10-* \ -text $text -anchor center -bg {} -justify left } } # ---------------------------------------------------------------------- # # Empty -- # # Indicates if the stack of axis configuration commands is # empty. # # ---------------------------------------------------------------------- body ZoomStackGraph::Empty { } { return [llength $stack] } # ---------------------------------------------------------------------- # # Push -- # # Appends a command on the list "stack" which can be used # to return to previous graph x and y axis ranges. # # ---------------------------------------------------------------------- body ZoomStackGraph::Push { cmd } { lappend stack $cmd } # ---------------------------------------------------------------------- # # Pop -- # # Remove the last item pushed onto the stack and returns it. # # ---------------------------------------------------------------------- body ZoomStackGraph::Pop { } { set cmd [lindex $stack end] set stack [lreplace $stack end end] return $cmd } # ---------------------------------------------------------------------- # # ClearTitle -- # # Clears the zoom title (displayed in the upper left corner # of the graph). This routine is called from the event queue # using "after". # # ---------------------------------------------------------------------- body ZoomStackGraph::ClearTitle {} { $graph marker delete "bltZoom_title" } # ---------------------------------------------------------------------- # # Unzoom -- # # Reverts to a previous zoom. Resets the x and y axis limits # back to a previous setting. First checks if there's anything # to pop back to. In addition, displays a title in the upper # left corner showing the current zoom level. # # ---------------------------------------------------------------------- body ZoomStackGraph::Unzoom { } { if ![Empty] { # Reset the x and y axis limits, by invoking the saved graph # command. eval [Pop] # Cheat: Using "Empty" to get the number of entries on the stack. set level [Empty] if { $level > 0 } { SetTitle "Zoom #$level" } blt::busy hold $graph update if { $corner == "first" } { # Remember to remove the zoom title in a couple of seconds after 2000 [code $this ClearTitle] } blt::busy release $graph } else { $graph marker delete "bltZoom_title" } } # ---------------------------------------------------------------------- # # Zoom -- # # Push the old axis limits on the stack and set them to the # zoom region. # # ---------------------------------------------------------------------- body ZoomStackGraph::Zoom { } { $graph marker delete "bltZoom_*" if { ($x1 == $x2) && ($y1 == $y2) } { # The first and last points of the zoom region are the same. # Revert back to the start. return } # Put a command on the stack that lets us revert back to the current # axis limits. set cmd [format { %s xaxis configure -min "%s" -max "%s" %s yaxis configure -min "%s" -max "%s" } $graph [$graph xaxis cget -min] [$graph xaxis cget -max] \ $graph [$graph yaxis cget -min] [$graph yaxis cget -max] ] Push $cmd # The first and last corners of the zoom region don't have to be # selected in ascending order. So consider their relative positions # when setting min and max axis limits. if { $x1 > $x2 } { $graph xaxis configure -min $x2 -max $x1 } elseif { $x1 < $x2 } { $graph xaxis configure -min $x1 -max $x2 } if { $y1 > $y2 } { $graph yaxis configure -min $y2 -max $y1 } elseif { $y1 < $y2 } { $graph yaxis configure -min $y1 -max $y2 } # Call "update" explicitly here after the graph is made busy. # This prevents the user from inadvertantly selecting another zoom # region when the graph is recalculating and redrawing itself. blt::busy hold $graph update blt::busy release $graph } # ---------------------------------------------------------------------- # # ClearZoom -- # # ---------------------------------------------------------------------- body ZoomStackGraph::ClearZoom { } { $graph marker delete "bltZoom_*" if { $corner == "first" } { # We're haven't started to select a zoom region, so assume # that we want to revert back to a previous zoom level. Unzoom } else { # Let the user re-pick the first corner again. So reset the # indicator "corner" and turn off the <Motion> binding. set corner "first" bind $graph <Motion> {} } } # ---------------------------------------------------------------------- # # SetTitle -- # # ---------------------------------------------------------------------- body ZoomStackGraph::SetTitle { title } { $graph marker create text -name "bltZoom_title" -text $title \ -coords {-Inf Inf} -anchor nw -bg {} } # ---------------------------------------------------------------------- # # UpdateOutline -- # # ---------------------------------------------------------------------- body ZoomStackGraph::UpdateOutline { x y } { SaveCoords $x $y MarkPoint $x2 $y2 DrawBox } # ---------------------------------------------------------------------- # # SelectPoint -- # # Invoked from the binding to ButtonPress-1 events. Saves # a corner of zoom region. # # # ---------------------------------------------------------------------- body ZoomStackGraph::SelectPoint { x y } { SaveCoords $x $y if { $corner == "first" } { MarkPoint $x1 $y1 # Display a new title indicating zoom pick is active set level [expr [llength $stack] + 1] SetTitle "Zoom #$level" # Start watching now for motion events, drawing an outline bind $graph <Any-Motion> [code $this UpdateOutline %x %y] # Indicate the next corner is the last set corner last } else { # Stop watching motion events bind $graph <Any-Motion> {} # Zoom into the new region defined by the outline Zoom # Reset to select the first corner, again set corner first } } # ---------------------------------------------------------------------- # # DrawBox -- # # ---------------------------------------------------------------------- body ZoomStackGraph::DrawBox { } { set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 } if [$graph marker exists "bltZoom_outline"] { $graph marker configure "bltZoom_outline" -coords $coords } else { $graph marker create line -coords $coords -name "bltZoom_outline" \ -dashes { 4 2 } } $graph marker before "bltZoom_outline" } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/tclIndex������������������������������������������������������������������0000644�0001750�0001750�00000001215�11462120062�015376� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tcl autoload index file, version 2.0 # This file is generated by the "auto_mkindex" command # and sourced to set up indexing information for one or # more commands. Typically each line is a command that # sets an element in the auto_index array, where the # element name is the name of a command and the value is # a script that loads the command. set auto_index(Blt_ActiveLegend) [list source $dir/graph.tcl] set auto_index(Blt_Crosshairs) [list source $dir/graph.tcl] set auto_index(Blt_ZoomStack) [list source $dir/graph.tcl] set auto_index(Blt_PrintKey) [list source $dir/graph.tcl] set auto_index(Blt_ClosestPoint) [list source $dir/graph.tcl] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/�������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�016371� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/dd-text.tcl��������������������������������������������������0000644�0001750�0001750�00000003053�11462120062�020453� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------------- # PURPOSE: drag&drop send routine for "text" data # # Widgets that are to participate in drag&drop operations for # "text" data should be registered as follows: # # drag&drop .win source handler text dd_send_text # drag&drop .win target handler text my_text_handler # # proc my_text_handler {} { # global DragDrop # # set data $DragDrop(text) # . # . do something with $data # . # } # # AUTHOR: Michael J. McLennan Phone: (215)770-2842 # AT&T Bell Laboratories E-mail: aluxpo!mmc@att.com # # SCCS: %W% (%G%) # ---------------------------------------------------------------------- # Copyright (c) 1993 AT&T All Rights Reserved # ====================================================================== # ---------------------------------------------------------------------- # COMMAND: dd_send_text <interp> <ddwin> <data> # # INPUTS # <interp> = interpreter for target application # <ddwin> = pathname for target drag&drop window # <data> = data returned from -tokencmd # # RETURNS # "" # # SIDE-EFFECTS # Sends data to remote application DragDrop(text), and then # invokes the "text" handler for the drag&drop target. # ---------------------------------------------------------------------- proc dd_send_text {interp ddwin data} { send $interp " global DragDrop set DragDrop(text) [list $data] " send $interp "drag&drop target $ddwin handle text" } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/dd-file.tcl��������������������������������������������������0000644�0001750�0001750�00000003225�11462120062�020407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------------- # PURPOSE: drag&drop send routine for "file" data # # Widgets that are to participate in drag&drop operations for # "file" data should be registered as follows: # # drag&drop .win source handler text dd_send_file # drag&drop .win target handler text my_file_handler # # proc my_file_handler {} { # global DragDrop # # set data $DragDrop(file) # . # . do something with $data # . # } # # AUTHOR: Michael J. McLennan Phone: (215)770-2842 # AT&T Bell Laboratories E-mail: aluxpo!mmc@att.com # # SCCS: %W% (%G%) # ---------------------------------------------------------------------- # Copyright (c) 1993 AT&T All Rights Reserved # ====================================================================== # ---------------------------------------------------------------------- # COMMAND: dd_send_file <interp> <ddwin> <data> # # INPUTS # <interp> = interpreter for target application # <ddwin> = pathname for target drag&drop window # <data> = data returned from -tokencmd # # RETURNS # "" # # SIDE-EFFECTS # Sends data to remote application DragDrop(file), and then # invokes the "file" handler for the drag&drop target. # ---------------------------------------------------------------------- proc dd_send_file {interp ddwin data} { send $interp " foreach file [list $data] { if {!\[file exists \$file\]} { error \"not a file: \$file\" } } global DragDrop set DragDrop(file) [list $data] " send $interp "drag&drop target $ddwin handle file" } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/dd-color.tcl�������������������������������������������������0000644�0001750�0001750�00000003163�11462120062�020607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------------- # PURPOSE: drag&drop send routine for "color" data # # Widgets that are to participate in drag&drop operations for # "color" data should be registered as follows: # # drag&drop .win source handler color dd_send_color # drag&drop .win target handler color my_color_handler # # proc my_color_handler {} { # global DragDrop # # set data $DragDrop(color) # . # . do something with $data # . # } # # AUTHOR: Michael J. McLennan Phone: (215)770-2842 # AT&T Bell Laboratories E-mail: aluxpo!mmc@att.com # # SCCS: %W% (%G%) # ---------------------------------------------------------------------- # Copyright (c) 1993 AT&T All Rights Reserved # ====================================================================== # ---------------------------------------------------------------------- # COMMAND: dd_send_color <interp> <ddwin> <data> # # INPUTS # <interp> = interpreter for target application # <ddwin> = pathname for target drag&drop window # <data> = data returned from -tokencmd # # RETURNS # "" # # SIDE-EFFECTS # Sends data to remote application DragDrop(color), and then # invokes the "color" handler for the drag&drop target. # ---------------------------------------------------------------------- proc dd_send_color {interp ddwin data} { send $interp " foreach color [list $data] { winfo rgb . \$color } global DragDrop set DragDrop(color) [list $data] " send $interp "drag&drop target $ddwin handle color" } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/dd-number.tcl������������������������������������������������0000644�0001750�0001750�00000003173�11462120062�020762� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------------- # PURPOSE: drag&drop send routine for "number" data # # Widgets that are to participate in drag&drop operations for # "number" data should be registered as follows: # # drag&drop .win source handler number dd_send_number # drag&drop .win target handler number my_number_handler # # proc my_number_handler {} { # global DragDrop # # set data $DragDrop(number) # . # . do something with $data # . # } # # AUTHOR: Michael J. McLennan Phone: (215)770-2842 # AT&T Bell Laboratories E-mail: aluxpo!mmc@att.com # # SCCS: %W% (%G%) # ---------------------------------------------------------------------- # Copyright (c) 1993 AT&T All Rights Reserved # ====================================================================== # ---------------------------------------------------------------------- # COMMAND: dd_send_number <interp> <ddwin> <data> # # INPUTS # <interp> = interpreter for target application # <ddwin> = pathname for target drag&drop window # <data> = data returned from -tokencmd # # RETURNS # "" # # SIDE-EFFECTS # Sends data to remote application DragDrop(number), and then # invokes the "number" handler for the drag&drop target. # ---------------------------------------------------------------------- proc dd_send_number {interp ddwin data} { send $interp " foreach num [list $data] { expr \$num*1 } global DragDrop set DragDrop(number) [list $data] " send $interp "drag&drop target $ddwin handle number" } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/dd_protocols/tclIndex�����������������������������������������������������0000644�0001750�0001750�00000001102�11462120062�020064� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tcl autoload index file, version 2.0 # This file is generated by the "auto_mkindex" command # and sourced to set up indexing information for one or # more commands. Typically each line is a command that # sets an element in the auto_index array, where the # element name is the name of a command and the value is # a script that loads the command. set auto_index(dd_send_file) "source $dir/dd-file.tcl" set auto_index(dd_send_text) "source $dir/dd-text.tcl" set auto_index(dd_send_number) "source $dir/dd-number.tcl" set auto_index(dd_send_color) "source $dir/dd-color.tcl" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/scrollbar.tcl�������������������������������������������������������������0000644�0001750�0001750�00000031565�11462120062�016403� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # scrollbar.tcl -- # # This file defines the default bindings for Tk scrollbar widgets. # It also provides procedures that help in implementing the bindings. # # RCS: @(#) $Id: scrollbar.tcl,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ # # Copyright (c) 1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # #------------------------------------------------------------------------- # The code below creates the default class bindings for scrollbars. #------------------------------------------------------------------------- # Standard Motif bindings: namespace eval ::blt::TkScrollbar { variable _private array set _private { activeBg "" afterId -1 border 1 initPos 0 initValues "" x 0 y 0 relief flat } } bind TkScrollbar <Enter> { if {$tk_strictMotif} { set blt::TkScrollbar::_private(activeBg) [%W cget -activebackground] %W configure -activebackground [%W cget -background] } %W activate [%W identify %x %y] } bind TkScrollbar <Motion> { %W activate [%W identify %x %y] } # The "info exists" command in the following binding handles the # situation where a Leave event occurs for a scrollbar without the Enter # event. This seems to happen on some systems (such as Solaris 2.4) for # unknown reasons. bind TkScrollbar <Leave> { if {$tk_strictMotif && [info exists blt::TkScrollbar::_private(activeBg)]} { %W configure -activebackground $blt::TkScrollbar::_private(activeBg) } %W activate {} } bind TkScrollbar <1> { blt::TkScrollbar::ScrollButtonDown %W %x %y } bind TkScrollbar <B1-Motion> { blt::TkScrollbar::ScrollDrag %W %x %y } bind TkScrollbar <B1-B2-Motion> { blt::TkScrollbar::ScrollDrag %W %x %y } bind TkScrollbar <ButtonRelease-1> { blt::TkScrollbar::ScrollButtonUp %W %x %y } bind TkScrollbar <B1-Leave> { # Prevents <Leave> binding from being invoked. } bind TkScrollbar <B1-Enter> { # Prevents <Enter> binding from being invoked. } bind TkScrollbar <2> { blt::TkScrollbar::ScrollButton2Down %W %x %y } bind TkScrollbar <B1-2> { # Do nothing, since button 1 is already down. } bind TkScrollbar <B2-1> { # Do nothing, since button 2 is already down. } bind TkScrollbar <B2-Motion> { blt::TkScrollbar::ScrollDrag %W %x %y } bind TkScrollbar <ButtonRelease-2> { blt::TkScrollbar::ScrollButtonUp %W %x %y } bind TkScrollbar <B1-ButtonRelease-2> { # Do nothing: B1 release will handle it. } bind TkScrollbar <B2-ButtonRelease-1> { # Do nothing: B2 release will handle it. } bind TkScrollbar <B2-Leave> { # Prevents <Leave> binding from being invoked. } bind TkScrollbar <B2-Enter> { # Prevents <Enter> binding from being invoked. } bind TkScrollbar <Control-1> { blt::TkScrollbar::ScrollTopBottom %W %x %y } bind TkScrollbar <Control-2> { blt::TkScrollbar::ScrollTopBottom %W %x %y } bind TkScrollbar <Up> { blt::TkScrollbar::ScrollByUnits %W v -1 } bind TkScrollbar <Down> { blt::TkScrollbar::ScrollByUnits %W v 1 } bind TkScrollbar <Control-Up> { blt::TkScrollbar::ScrollByPages %W v -1 } bind TkScrollbar <Control-Down> { blt::TkScrollbar::ScrollByPages %W v 1 } bind TkScrollbar <Left> { blt::TkScrollbar::ScrollByUnits %W h -1 } bind TkScrollbar <Right> { blt::TkScrollbar::ScrollByUnits %W h 1 } bind TkScrollbar <Control-Left> { blt::TkScrollbar::ScrollByPages %W h -1 } bind TkScrollbar <Control-Right> { blt::TkScrollbar::ScrollByPages %W h 1 } bind TkScrollbar <Prior> { blt::TkScrollbar::ScrollByPages %W hv -1 } bind TkScrollbar <Next> { blt::TkScrollbar::ScrollByPages %W hv 1 } bind TkScrollbar <Home> { blt::TkScrollbar::ScrollToPos %W 0 } bind TkScrollbar <End> { blt::TkScrollbar::ScrollToPos %W 1 } if {[tk windowingsystem] eq "classic" || [tk windowingsystem] eq "aqua"} { bind TkScrollbar <MouseWheel> { blt::TkScrollbar::ScrollByUnits %W v [expr {- (%D)}] } bind TkScrollbar <Option-MouseWheel> { blt::TkScrollbar::ScrollByUnits %W v [expr {-10 * (%D)}] } bind TkScrollbar <Shift-MouseWheel> { blt::TkScrollbar::ScrollByUnits %W h [expr {- (%D)}] } bind TkScrollbar <Shift-Option-MouseWheel> { blt::TkScrollbar::ScrollByUnits %W h [expr {-10 * (%D)}] } } # blt::TkScrollbar::ScrollButtonDown -- # This procedure is invoked when a button is pressed in a scrollbar. # It changes the way the scrollbar is displayed and takes actions # depending on where the mouse is. # # Arguments: # w - The scrollbar widget. # x, y - Mouse coordinates. proc blt::TkScrollbar::ScrollButtonDown {w x y} { variable _private set _private(relief) [$w cget -activerelief] set _private(border) [$w cget -activebackground] $w configure -activerelief sunken set element [$w identify $x $y] $w select $element if {$element eq "slider"} { ScrollStartDrag $w $x $y } else { ScrollSelect $w $element initial } } # ScrollButtonUp -- # This procedure is invoked when a button is released in a scrollbar. # It cancels scans and auto-repeats that were in progress, and restores # the way the active element is displayed. # # Arguments: # w - The scrollbar widget. # x, y - Mouse coordinates. proc ::blt::TkScrollbar::ScrollButtonUp {w x y} { variable _private CancelRepeat if {[info exists _private(relief)]} { # Avoid error due to spurious release events $w configure -activerelief $_private(relief) ScrollEndDrag $w $x $y set element [$w identify $x $y] $w activate [$w identify $x $y] $w select {} } } # ScrollSelect -- # This procedure is invoked when a button is pressed over the scrollbar. # It invokes one of several scrolling actions depending on where in # the scrollbar the button was pressed. # # Arguments: # w - The scrollbar widget. # element - The element of the scrollbar that was selected, such # as "arrow1" or "trough2". Shouldn't be "slider". # repeat - Whether and how to auto-repeat the action: "noRepeat" # means don't auto-repeat, "initial" means this is the # first action in an auto-repeat sequence, and "again" # means this is the second repetition or later. proc ::blt::TkScrollbar::ScrollSelect {w element repeat} { variable _private if {![winfo exists $w]} { return } switch -- $element { "arrow1" {ScrollByUnits $w hv -1} "trough1" {ScrollByPages $w hv -1} "trough2" {ScrollByPages $w hv 1} "arrow2" {ScrollByUnits $w hv 1} default {return} } set cmd [list blt::TkScrollbar::ScrollSelect $w $element again] if {$repeat eq "again"} { set _private(afterId) [after [$w cget -repeatinterval] $cmd] } elseif {$repeat eq "initial"} { set delay [$w cget -repeatdelay] if {$delay > 0} { set _private(afterId) [after $delay $cmd] } } } # ScrollStartDrag -- # This procedure is called to initiate a drag of the slider. It just # remembers the starting position of the mouse and slider. # # Arguments: # w - The scrollbar widget. # x, y - The mouse position at the start of the drag operation. proc ::blt::TkScrollbar::ScrollStartDrag {w x y} { variable _private if {[$w cget -command] eq ""} { return } set _private(x) $x set _private(y) $y set _private(initValues) [$w get] set iv0 [lindex $_private(initValues) 0] if {[llength $_private(initValues)] == 2} { set _private(initPos) $iv0 } elseif {$iv0 == 0} { set _private(initPos) 0.0 } else { set _private(initPos) [expr {(double([lindex $_private(initValues) 2])) \ / [lindex $_private(initValues) 0]}] } } # ScrollDrag -- # This procedure is called for each mouse motion even when the slider # is being dragged. It notifies the associated widget if we're not # jump scrolling, and it just updates the scrollbar if we are jump # scrolling. # # Arguments: # w - The scrollbar widget. # x, y - The current mouse position. proc ::blt::TkScrollbar::ScrollDrag {w x y} { variable _private if {$_private(initPos) eq ""} { return } set delta \ [$w delta [expr {$x - $_private(x)}] [expr {$y - $_private(y)}]] if {[$w cget -jump]} { if {[llength $_private(initValues)] == 2} { $w set [expr {[lindex $_private(initValues) 0] + $delta}] \ [expr {[lindex $_private(initValues) 1] + $delta}] } else { set delta [expr {round($delta * [lindex $_private(initValues) 0])}] eval [list $w] set [lreplace $_private(initValues) 2 3 \ [expr {[lindex $_private(initValues) 2] + $delta}] \ [expr {[lindex $_private(initValues) 3] + $delta}]] } } else { ScrollToPos $w [expr {$_private(initPos) + $delta}] } } # ScrollEndDrag -- # This procedure is called to end an interactive drag of the slider. # It scrolls the window if we're in jump mode, otherwise it does nothing. # # Arguments: # w - The scrollbar widget. # x, y - The mouse position at the end of the drag operation. proc ::blt::TkScrollbar::ScrollEndDrag {w x y} { variable _private if {$_private(initPos) eq ""} { return } if {[$w cget -jump]} { set delta [$w delta [expr {$x-$_private(x)}] [expr {$y-$_private(y)}]] ScrollToPos $w [expr {$_private(initPos) + $delta}] } set _private(initPos) "" } # ScrollByUnits -- # This procedure tells the scrollbar's associated widget to scroll up # or down by a given number of units. It notifies the associated widget # in different ways for old and new command syntaxes. # # Arguments: # w - The scrollbar widget. # orient - Which kinds of scrollbars this applies to: "h" for # horizontal, "v" for vertical, "hv" for both. # amount - How many units to scroll: typically 1 or -1. proc ::blt::TkScrollbar::ScrollByUnits {w orient amount} { set cmd [$w cget -command] if {$cmd eq "" || ([string first [string index [$w cget -orient] 0] $orient] < 0)} { return } set info [$w get] if {[llength $info] == 2} { uplevel #0 $cmd scroll $amount units } else { uplevel #0 $cmd [expr {[lindex $info 2] + $amount}] } } # ScrollByPages -- # This procedure tells the scrollbar's associated widget to scroll up # or down by a given number of screenfuls. It notifies the associated # widget in different ways for old and new command syntaxes. # # Arguments: # w - The scrollbar widget. # orient - Which kinds of scrollbars this applies to: "h" for # horizontal, "v" for vertical, "hv" for both. # amount - How many screens to scroll: typically 1 or -1. proc ::blt::TkScrollbar::ScrollByPages {w orient amount} { set cmd [$w cget -command] if {$cmd eq "" || ([string first [string index [$w cget -orient] 0] $orient] < 0)} { return } set info [$w get] if {[llength $info] == 2} { uplevel #0 $cmd scroll $amount pages } else { uplevel #0 $cmd [expr {[lindex $info 2] + $amount*([lindex $info 1] - 1)}] } } # ScrollToPos -- # This procedure tells the scrollbar's associated widget to scroll to # a particular location, given by a fraction between 0 and 1. It notifies # the associated widget in different ways for old and new command syntaxes. # # Arguments: # w - The scrollbar widget. # pos - A fraction between 0 and 1 indicating a desired position # in the document. proc ::blt::TkScrollbar::ScrollToPos {w pos} { set cmd [$w cget -command] if {$cmd eq ""} { return } set info [$w get] if {[llength $info] == 2} { uplevel #0 $cmd moveto $pos } else { uplevel #0 $cmd [expr {round([lindex $info 0]*$pos)}] } } # # ScrollTopBottom -- # # Scroll to the top or bottom of the document, depending on the mouse # position. # # Arguments: # w The scrollbar widget. # x, y Mouse coordinates within the widget. # proc ::blt::TkScrollbar::ScrollTopBottom {w x y} { variable _private set element [$w identify $x $y] if {[string match *1 $element]} { ScrollToPos $w 0 } elseif {[string match *2 $element]} { ScrollToPos $w 1 } # Set _private(relief), since it's needed by ScrollButtonUp. set _private(relief) [$w cget -activerelief] } # # ScrollButton2Down -- # # This procedure is invoked when button 2 is pressed over a scrollbar. # If the button is over the trough or slider, it sets the scrollbar to # the mouse position and starts a slider drag. Otherwise it just # behaves the same as button 1. # # Arguments: # w The scrollbar widget. # x, y Mouse coordinates within the widget. proc ::blt::TkScrollbar::ScrollButton2Down {w x y} { variable _private set element [$w identify $x $y] if {[string match {arrow[12]} $element]} { ScrollButtonDown $w $x $y return } ScrollToPos $w [$w fraction $x $y] set _private(relief) [$w cget -activerelief] # Need the "update idletasks" below so that the widget calls us # back to reset the actual scrollbar position before we start the # slider drag. update idletasks $w configure -activerelief sunken $w activate slider ScrollStartDrag $w $x $y } proc ::blt::TkScrollbar::CancelRepeat {} { variable _private after cancel $_private(afterId) set _private(afterId) -1 } �������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/library/combobutton.tcl�����������������������������������������������������������0000644�0001750�0001750�00000015626�11462120062�016753� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� namespace eval blt::ComboButton { variable _private array set _private { activeMenu {} posted {} activeItem {} cursor {} focus {} oldGrab {} trace 0 } proc trace { mesg } { variable _private if { $_private(trace) } { puts stderr $mesg } } } bind ComboButton <Enter> { %W activate yes } bind ComboButton <Leave> { %W activate no } bind ComboButton <B1-Motion> { blt::ComboButton::trace "ComboButton <B1-Motion> %W state=[%W cget -state]" blt::ComboButton::NextButton %W %X %Y } bind ComboButton <B1-Leave> { blt::ComboButton::trace "ComboButton <B1-Leave> state=[%W cget -state]" } # Standard Motif bindings: bind ComboButton <ButtonPress-1> { blt::ComboButton::trace "ComboButton <ButtonPress-1> state=[%W cget -state]" if { [%W cget -state] == "posted" } { %W unpost blt::ComboButton::UnpostMenu %W } else { grab -global %W blt::ComboButton::PostMenu %W } } bind ComboButton <ButtonRelease-1> { blt::ComboButton::trace \ "ComboButton <ButtonRelease-1> state=[%W cget -state]" if { [winfo containing -display %W %X %Y] == "%W" } { blt::ComboButton::trace "invoke" %W invoke } else { %W activate off blt::ComboButton::trace "unpost" blt::ComboButton::UnpostMenu %W } } bind ComboButton <KeyPress-Down> { if { [%W cget -state] != "disabled" } { blt::ComboButton::PostMenu %W } } # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for Escape, Return, and Tab. bind ComboButton <Alt-KeyPress> {# nothing} bind ComboButton <Meta-KeyPress> { puts %K } bind ComboButton <Control-KeyPress> {# nothing} bind ComboButton <Escape> {# nothing} #bind ComboButton <KP_Enter> {# nothing} bind ComboButton <Tab> {# nothing} if {[string equal [tk windowingsystem] "classic"] || [string equal [tk windowingsystem] "aqua"]} { bind ComboButton <Command-KeyPress> {# nothing} } proc blt::ComboButton::SaveGrab { w } { variable _private set grab [grab current $w] set _private(oldGrab) "" if { $grab != "" } { set type [grab status $grab] if { $type == "global" } { #set _private(oldGrab) [list grab set -global $grab] } else { #set _private(oldGrab) [list grab set $grab] } } } # ::blt::ComboButton::RestoreOldGrab -- # Restores the grab to what it was before TkSaveGrabInfo was called. # proc ::blt::ComboButton::RestoreOldGrab {} { variable _private if { $_private(oldGrab) != "" } { # Be careful restoring the old grab, since it's window may not be # visible anymore. catch $_private(oldGrab) set _private(oldGrab) "" } } # ::blt::ComboButton::PostMenu -- # Given a menubutton, this procedure does all the work of posting # its associated menu and unposting any other menu that is currently # posted. # # Arguments: # w - The name of the menubutton widget whose menu # is to be posted. # x, y - Root coordinates of cursor, used for positioning # option menus. If not specified, then the center # of the menubutton is used for an option menu. proc ::blt::ComboButton::PostMenu { cbutton } { variable _private trace "proc ComboButton::PostMenu $cbutton, state=[$cbutton cget -state]" if { [$cbutton cget -state] == "disabled" } { return } if { [$cbutton cget -state] == "posted" } { UnpostMenu $cbutton return } set menu [$cbutton cget -menu] if { $menu == "" } { return } set last $_private(posted) if { $last != "" } { UnpostMenu $last } set _private(cursor) [$cbutton cget -cursor] $cbutton configure -cursor arrow set _private(posted) $cbutton set _private(focus) [focus] $menu activate none GenerateMenuSelect $menu # If this looks like an option menubutton then post the menu so # that the current entry is on top of the mouse. Otherwise post # the menu just below the menubutton, as for a pull-down. update idletasks if { [catch { $cbutton post } msg] != 0 } { # Error posting menu (e.g. bogus -postcommand). Unpost it and # reflect the error. global errorInfo set savedInfo $errorInfo # UnpostMenu $cbutton error $msg $savedInfo } focus $menu if { [winfo viewable $menu] } { SaveGrab $menu trace "setting global grab on $menu" #grab -global $menu } } # ::blt::ComboButton::UnpostMenu -- # This procedure unposts a given menu, plus all of its ancestors up # to (and including) a menubutton, if any. It also restores various # values to what they were before the menu was posted, and releases # a grab if there's a menubutton involved. Special notes: # 1. It's important to unpost all menus before releasing the grab, so # that any Enter-Leave events (e.g. from menu back to main # application) have mode NotifyGrab. # 2. Be sure to enclose various groups of commands in "catch" so that # the procedure will complete even if the menubutton or the menu # or the grab window has been deleted. # # Arguments: # menu - Name of a menu to unpost. Ignored if there # is a posted menubutton. proc ::blt::ComboButton::UnpostMenu { cbutton } { variable _private trace "proc ComboButton::UnpostMenu $cbutton" # Restore focus right away (otherwise X will take focus away when the # menu is unmapped and under some window managers (e.g. olvwm) we'll # lose the focus completely). catch { focus $_private(focus) } set _private(focus) "" # Unpost menu(s) and restore some stuff that's dependent on what was # posted. $cbutton unpost set _private(posted) {} if { [info exists _private(cursor)] } { $cbutton configure -cursor $_private(cursor) } if { [$cbutton cget -state] != "disabled" } { #$cbutton configure -state normal } set menu [$cbutton cget -menu] trace MENU=$menu trace GRAB=[grab current $menu] # Release grab, if any, and restore the previous grab, if there # was one. if { $menu != "" } { set grab [grab current $menu] if { $grab != "" } { grab release $grab } } RestoreOldGrab } proc blt::ComboButton::GenerateMenuSelect {menu} { variable _private set item [$menu index active] if { $_private(activeMenu) != $menu || $_private(activeItem) != $item } { set _private(activeMenu) $menu set _private(activeItem) $item event generate $menu <<MenuSelect>> } } proc blt::ComboButton::NextButton { cbutton rootx rooty } { variable _private set next [winfo containing -display $cbutton $rootx $rooty] if { $next == "" || $next == $_private(posted) || [winfo class $next] != "ComboButton" } { return } # Release the current combobutton, including removing the grab. event generate $cbutton <ButtonRelease-1> grab -global $next # Simulate pressing the new combobutton widget. event generate $next <ButtonPress-1> } ����������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/tests/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013374� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/tests/defs������������������������������������������������������������������������0000644�0001750�0001750�00000005516�11462120063�014254� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file contains support code for the Tcl test suite. It is # normally sourced by the individual files in the test suite before # they run their tests. This improved approach to testing was designed # and initially implemented by Mary Ann May-Pumphrey of Sun Microsystems. if ![info exists VERBOSE] { set VERBOSE 0 } if ![info exists TESTS] { set TESTS {} } # Some of the tests don't work on some system configurations due to # configuration quirks, not due to Tk problems; in order to prevent # false alarms, these tests are only run in the master source directory # at Berkeley. The presence of a file "Berkeley" in this directory is # used to indicate that these tests should be run. set atBerkeley [file exists Berkeley] proc print_verbose {test_name test_description contents_of_test code answer} { puts stdout "\n" puts stdout "==== $test_name $test_description" puts stdout "==== Contents of test case:" puts stdout "$contents_of_test" if {$code != 0} { if {$code == 1} { puts stdout "==== Test generated error:" puts stdout $answer } elseif {$code == 2} { puts stdout "==== Test generated return exception; result was:" puts stdout $answer } elseif {$code == 3} { puts stdout "==== Test generated break exception" } elseif {$code == 4} { puts stdout "==== Test generated continue exception" } else { puts stdout "==== Test generated exception $code; message was:" puts stdout $answer } } else { puts stdout "==== Result was:" puts stdout "$answer" } } proc test {test_name test_description contents_of_test passing_results} { global VERBOSE global TESTS if {[string compare $TESTS ""] != 0} then { set ok 0 foreach test $TESTS { if [string match $test $test_name] then { set ok 1 break } } if !$ok then return } set code [catch {uplevel $contents_of_test} answer] if {$code != 0} { print_verbose $test_name $test_description $contents_of_test \ $code $answer } elseif {[string compare $answer $passing_results] == 0} then { if $VERBOSE then { print_verbose $test_name $test_description $contents_of_test \ $code $answer puts stdout "++++ $test_name PASSED" } } else { print_verbose $test_name $test_description $contents_of_test \ $code $answer puts stdout "---- Result should have been:" puts stdout "$passing_results" puts stdout "---- $test_name FAILED" } } proc dotests {file args} { global TESTS set savedTests $TESTS set TESTS $args source $file set TESTS $savedTests } # If the main window isn't already mapped (e.g. because the tests are # being run automatically) , specify a precise size for it so that the # user won't have to position it manually. if { [llength [info commands tk]] > 0 } { if {![winfo ismapped .]} { wm geometry . +0+0 update } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/tests/datatable.tcl���������������������������������������������������������������0000644�0001750�0001750�00000412553�11462120063�016040� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT if {[info procs test] != "test"} { source defs } if [file exists ../library] { set blt_library ../library } #set VERBOSE 1 test datatable.1 {datatable no args} { list [catch {blt::datatable} msg] $msg } {1 {wrong # args: should be one of... blt::datatable create ?name? blt::datatable destroy name... blt::datatable load name libpath blt::datatable names ?pattern?...}} test datatable.2 {datatable create #auto} { list [catch {blt::datatable create #auto} msg] $msg } {0 ::datatable0} test datatable.3 {datatable create #auto.suffix} { list [catch { blt::datatable create #auto.suffix } msg] $msg } {0 ::datatable0.suffix} test datatable.4 {datatable create prefix.#auto} { list [catch { blt::datatable create prefix.#auto } msg] $msg } {0 ::prefix.datatable0} test datatable.5 {datatable create prefix.#auto.suffix} { list [catch { blt::datatable create prefix.#auto.suffix } msg] $msg } {0 ::prefix.datatable0.suffix} test datatable.6 {datatable create prefix.#auto.suffix.#auto} { list [catch { blt::datatable create prefix.#auto.suffix.#auto } msg] $msg } {0 ::prefix.datatable0.suffix.#auto} test datatable.7 {blt::datatable destroy [blt::datatable names *datatable0*]} { list [catch { eval blt::datatable destroy [blt::datatable names *datatable0*] } msg] $msg } {0 {}} test datatable.8 {blt::datatable create} { list [catch { blt::datatable create } msg] $msg } {0 ::datatable0} test datatable.9 {blt::datatable create} { list [catch { blt::datatable create } msg] $msg } {0 ::datatable1} test datatable.10 {blt::datatable create fred} { list [catch { blt::datatable create fred } msg] $msg } {0 ::fred} test datatable.11 {blt::datatable create fred} { list [catch { blt::datatable create fred } msg] $msg } {1 {a command "::fred" already exists}} test datatable.12 {blt::datatable create if} { list [catch { blt::datatable create if } msg] $msg } {1 {a command "::if" already exists}} test datatable.13 {blt::datatable create (bad namespace)} { list [catch { blt::datatable create badNs::fred } msg] $msg } {1 {unknown namespace "badNs"}} test datatable.14 {blt::datatable create (wrong # args)} { list [catch { blt::datatable create a b } msg] $msg } {1 {wrong # args: should be "blt::datatable create ?name?"}} test datatable.15 {names} { list [catch { blt::datatable names } msg] [lsort $msg] } {0 {::datatable0 ::datatable1 ::fred}} test datatable.16 {names pattern)} { list [catch { blt::datatable names ::datatable* } msg] [lsort $msg] } {0 {::datatable0 ::datatable1}} test datatable.17 {names badPattern)} { list [catch { blt::datatable names badPattern* } msg] $msg } {0 {}} test datatable.18 {names pattern arg (wrong # args)} { list [catch { blt::datatable names pattern arg } msg] $msg } {1 {wrong # args: should be "blt::datatable names ?pattern?..."}} test datatable.19 {destroy (wrong # args)} { list [catch { blt::datatable destroy } msg] $msg } {1 {wrong # args: should be "blt::datatable destroy name..."}} test datatable.20 {destroy badName} { list [catch { blt::datatable destroy badName } msg] $msg } {1 {can't find table "badName"}} test datatable.21 {destroy fred} { list [catch { blt::datatable destroy fred } msg] $msg } {0 {}} test datatable.22 {destroy datatable0 datatable1} { list [catch { blt::datatable destroy datatable0 datatable1 } msg] $msg } {0 {}} test datatable.23 {create} { list [catch { blt::datatable create } msg] $msg } {0 ::datatable0} test datatable.24 {datatable0} { list [catch { datatable0 } msg] $msg } {1 {wrong # args: should be one of... datatable0 add table ?switches? datatable0 append row column value ?value...? datatable0 attach args... datatable0 column op args... datatable0 dump ?switches? datatable0 emptyvalue ?newValue? datatable0 exists row column datatable0 export format args... datatable0 find expr ?switches? datatable0 get row column ?defValue? datatable0 import format args... datatable0 keys ?column...? datatable0 lappend row column value ?value...? datatable0 lookup ?value...? datatable0 notify op args... datatable0 restore ?switches? datatable0 row op args... datatable0 set ?row column value?... datatable0 sort ?flags...? datatable0 trace op args... datatable0 unset row column ?row column?}} test datatable.25 {datatable0 badOp} { list [catch { datatable0 badOp } msg] $msg } {1 {bad operation "badOp": should be one of... datatable0 add table ?switches? datatable0 append row column value ?value...? datatable0 attach args... datatable0 column op args... datatable0 dump ?switches? datatable0 emptyvalue ?newValue? datatable0 exists row column datatable0 export format args... datatable0 find expr ?switches? datatable0 get row column ?defValue? datatable0 import format args... datatable0 keys ?column...? datatable0 lappend row column value ?value...? datatable0 lookup ?value...? datatable0 notify op args... datatable0 restore ?switches? datatable0 row op args... datatable0 set ?row column value?... datatable0 sort ?flags...? datatable0 trace op args... datatable0 unset row column ?row column?}} test datatable.26 {datatable0 column (wrong \# args)} { list [catch { datatable0 column } msg] $msg } {1 {wrong # args: should be "datatable0 column op args..."}} test datatable.27 {datatable0 column badOp} { list [catch { datatable0 column badOp } msg] $msg } {1 {bad operation "badOp": should be one of... datatable0 column copy src dest ?switches...? datatable0 column create ?switches? datatable0 column delete column... datatable0 column dup column... datatable0 column exists column datatable0 column extend label ?label...? datatable0 column get column ?switches? datatable0 column index column datatable0 column indices column ?column...? datatable0 column label column ?label? datatable0 column labels ?labelList? datatable0 column length datatable0 column move from to ?count? datatable0 column names ?pattern...? datatable0 column notify column ?flags? command datatable0 column set column row value... datatable0 column tag op args... datatable0 column trace column how command datatable0 column type column ?type? datatable0 column unique column ?switches? datatable0 column unset column... datatable0 column values column ?valueList?}} test datatable.28 {datatable0 row (wrong \# args)} { list [catch { datatable0 row } msg] $msg } {1 {wrong # args: should be "datatable0 row op args..."}} test datatable.29 {datatable0 row badOp} { list [catch { datatable0 row badOp } msg] $msg } {1 {bad operation "badOp": should be one of... datatable0 row copy src dest ?switches...? datatable0 row create ?switches...? datatable0 row delete row... datatable0 row dup row... datatable0 row exists row datatable0 row extend label ?label...? datatable0 row get row ?switches? datatable0 row index row datatable0 row indices row ?row...? datatable0 row label row ?label? datatable0 row labels ?labelList? datatable0 row length datatable0 row move from to ?count? datatable0 row names ?pattern...? datatable0 row notify row ?flags? command datatable0 row set row column value... datatable0 row tag op args... datatable0 row trace row how command datatable0 row unique row datatable0 row unset row... datatable0 row values row ?valueList?}} test datatable.30 {datatable0 column length} { list [catch {datatable0 column length} msg] $msg } {0 0} test datatable.31 {datatable0 column length badArg} { list [catch {datatable0 column length badArg} msg] $msg } {1 {wrong # args: should be "datatable0 column length "}} test datatable.32 {datatable0 column -label xyz insert} { list [catch {datatable0 column -label xyz insert} msg] $msg } {1 {bad operation "-label": should be one of... datatable0 column copy src dest ?switches...? datatable0 column create ?switches? datatable0 column delete column... datatable0 column dup column... datatable0 column exists column datatable0 column extend label ?label...? datatable0 column get column ?switches? datatable0 column index column datatable0 column indices column ?column...? datatable0 column label column ?label? datatable0 column labels ?labelList? datatable0 column length datatable0 column move from to ?count? datatable0 column names ?pattern...? datatable0 column notify column ?flags? command datatable0 column set column row value... datatable0 column tag op args... datatable0 column trace column how command datatable0 column type column ?type? datatable0 column unique column ?switches? datatable0 column unset column... datatable0 column values column ?valueList?}} test datatable.33 {column extend 5} { list [catch {datatable0 column extend 5} msg] $msg } {0 {1 2 3 4 5}} test datatable.34 {column length} { list [catch {datatable0 column length} msg] $msg } {0 5} test datatable.35 {column index end} { list [catch {datatable0 column index end} msg] $msg } {0 5} test datatable.36 {row extend 5} { list [catch {datatable0 row extend 5} msg] $msg } {0 {1 2 3 4 5}} test datatable.37 {row length} { list [catch {datatable0 row length} msg] $msg } {0 5} test datatable.38 {column index end} { list [catch {datatable0 row index end} msg] $msg } {0 5} test datatable.39 {column index all} { list [catch {datatable0 column index all} msg] $msg } {0 -1} test datatable.40 {column indices all} { list [catch {datatable0 column indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.41 {column indices 1-end} { list [catch {datatable0 column indices 1-end} msg] $msg } {0 {1 2 3 4 5}} test datatable.42 {column indices range=1-end} { list [catch {datatable0 column indices range=1-end} msg] $msg } {0 {1 2 3 4 5}} test datatable.43 {column indices 1-all} { list [catch {datatable0 column indices 1-all} msg] $msg } {1 {unknown column specification "1-all" in ::datatable0}} test datatable.44 {column indices range=1-all} { list [catch {datatable0 column indices range=1-all} msg] $msg } {1 {multiple columns specified by "all"}} test datatable.45 {column indices 2-5} { list [catch {datatable0 column indices 2-5} msg] $msg } {0 {2 3 4 5}} test datatable.46 {column indices 5-2} { list [catch {datatable0 column indices 5-2} msg] $msg } {0 {}} test datatable.47 {column index end} { list [catch {datatable0 column index end} msg] $msg } {0 5} test datatable.48 {column index end badArg} { list [catch {datatable0 column index end badArg} msg] $msg } {1 {wrong # args: should be "datatable0 column index column"}} test datatable.49 {column label 1} { list [catch {datatable0 column label 1} msg] $msg } {0 c1} test datatable.50 {column label 1 myLabel} { list [catch {datatable0 column label 1 myLabel} msg] $msg } {0 {}} test datatable.51 {column label 1 myLabel} { list [catch {datatable0 column label 1 myLabel} msg] $msg } {0 {}} test datatable.52 {column label 2 myLabel} { list [catch {datatable0 column label 2 myLabel} msg] $msg } {0 {}} package require blt_datatable_csv puts stderr [datatable0 export csv -columnlabels] test datatable.53 {column index myLabel} { list [catch {datatable0 column index myLabel} msg] $msg } {0 1} test datatable.54 {column label 1 newLabel} { list [catch {datatable0 column label 1 newLabel} msg] $msg } {0 {}} test datatable.55 {column index myLabel} { list [catch {datatable0 column index myLabel} msg] $msg } {0 2} test datatable.56 {column label 1} { list [catch {datatable0 column label 1} msg] $msg } {0 newLabel} test datatable.57 {column label end end} { list [catch {datatable0 column label end end} msg] $msg } {0 {}} test datatable.58 {column label end endLabel} { list [catch {datatable0 column label end endLabel} msg] $msg } {0 {}} test datatable.59 {column label end label-with-minus} { list [catch {datatable0 column label end label-with-minus} msg] $msg } {0 {}} test datatable.60 {column label end 1abc} { list [catch {datatable0 column label end 1abc} msg] $msg } {0 {}} test datatable.61 {column label end -abc} { list [catch {datatable0 column label end -abc} msg] $msg } {1 {column label "-abc" can't start with a '-'.}} test datatable.62 {column indices 1-5} { list [catch {datatable0 column indices 1-5} msg] $msg } {0 {1 2 3 4 5}} test datatable.63 {column indices range=1-5} { list [catch {datatable0 column indices range=1-5} msg] $msg } {0 {1 2 3 4 5}} test datatable.64 {column label 1-5 c1 } { list [catch {datatable0 column label 1-5 c1} msg] $msg } {1 {multiple columns specified by "1-5"}} test datatable.65 {column label 1 c1 2 c2 3 c3 4 c4 5 c5 } { list [catch {datatable0 column label 1 c1 2 c2 3 c3 4 c4 5 c5} msg] $msg } {0 {}} test datatable.66 {column label 1} { list [catch {datatable0 column label 1} msg] $msg } {0 c1} test datatable.67 {column label 2} { list [catch {datatable0 column label 2} msg] $msg } {0 c2} test datatable.68 {column label 3} { list [catch {datatable0 column label 3} msg] $msg } {0 c3} test datatable.69 {column label 4} { list [catch {datatable0 column label 4} msg] $msg } {0 c4} test datatable.70 {column label 5} { list [catch {datatable0 column label 5} msg] $msg } {0 c5} test datatable.71 {column label 6} { list [catch {datatable0 column label 6} msg] $msg } {1 {bad column index "6"}} test datatable.72 {column names} { list [catch {datatable0 column names} msg] $msg } {0 {c1 c2 c3 c4 c5}} test datatable.73 {column names c*} { list [catch {datatable0 column names c*} msg] $msg } {0 {c1 c2 c3 c4 c5}} test datatable.74 {column names {*[1-2]}} { list [catch {datatable0 column names {*[1-2]}} msg] $msg } {0 {c1 c2}} test datatable.75 {column names noMatch} { list [catch {datatable0 column names noMatch} msg] $msg } {0 {}} test datatable.76 {row label 1-5 r1} { list [catch {datatable0 row label 1-5 r1} msg] $msg } {1 {multiple rows specified by "1-5"}} test datatable.77 {row label 1 r1 2 r2 3 r3 4 r4 5 r5} { list [catch {datatable0 row label 1 r1 2 r2 3 r3 4 r4 5 r5} msg] $msg } {0 {}} test datatable.78 {row names} { list [catch {datatable0 row names} msg] $msg } {0 {r1 r2 r3 r4 r5}} test datatable.79 {row names r*} { list [catch {datatable0 row names r*} msg] $msg } {0 {r1 r2 r3 r4 r5}} test datatable.80 {row names noMatch} { list [catch {datatable0 row names noMatch} msg] $msg } {0 {}} test datatable.81 {column get} { list [catch {datatable0 column get} msg] $msg } {1 {wrong # args: should be "datatable0 column get column ?switches?"}} test datatable.82 {column get c1} { list [catch {datatable0 column get c1} msg] $msg } {0 {1 {} 2 {} 3 {} 4 {} 5 {}}} test datatable.83 {column get badColumn} { list [catch {datatable0 column get badColumn} msg] $msg } {1 {unknown column specification "badColumn" in ::datatable0}} test datatable.84 {column values} { list [catch {datatable0 column values} msg] $msg } {1 {wrong # args: should be "datatable0 column values column ?valueList?"}} test datatable.85 {column values c1} { list [catch { datatable0 column values c1 } msg] $msg } {0 {{} {} {} {} {}}} test datatable.86 {column values c1 {1.01 2.01 3.01 4.01 5.01}} { list [catch { datatable0 column values c1 {1.01 2.01 3.01 4.01 5.01} } msg] $msg } {0 {}} test datatable.87 {column get 1} { list [catch {datatable0 column get 1} msg] $msg } {0 {1 1.01 2 2.01 3 3.01 4 4.01 5 5.01}} test datatable.88 {column set all 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0} { list [catch { datatable0 column set all 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 } msg] $msg } {0 {}} test datatable.89 {column get all} { list [catch {datatable0 column get all} msg] $msg } {1 {multiple columns specified by "all"}} test datatable.90 {column get 1-2} { list [catch {datatable0 column get 1-2} msg] $msg } {1 {multiple columns specified by "1-2"}} test datatable.91 {datatable0 column get 2} { list [catch {datatable0 column get 2} msg] $msg } {0 {1 1.0 2 2.0 3 3.0 4 4.0 5 5.0}} test datatable.92 {datatable0 column get 3} { list [catch {datatable0 column get 3} msg] $msg } {0 {1 1.0 2 2.0 3 3.0 4 4.0 5 5.0}} test datatable.93 {datatable0 column get end} { list [catch {datatable0 column get end} msg] $msg } {0 {1 1.0 2 2.0 3 3.0 4 4.0 5 5.0}} test datatable.94 {datatable0 column set 1 3 a 2 b 1 c} { list [catch {datatable0 column set 1 3 a 2 b 1 c} msg] $msg } {0 {}} test datatable.95 {column values 1} { list [catch {datatable0 column values 1} msg] $msg } {0 {c b a 4.0 5.0}} test datatable.96 {column set end 1 x 2 y} { list [catch {datatable0 column set end 1 x 2 y} msg] $msg } {0 {}} test datatable.97 {column values end} { list [catch {datatable0 column values end} msg] $msg } {0 {x y 3.0 4.0 5.0}} test datatable.98 {column index c5} { list [catch {datatable0 column index c5} msg] $msg } {0 5} test datatable.99 {column indices all} { list [catch {datatable0 column indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.100 {column index -1} { list [catch {datatable0 column index -1} msg] $msg } {0 -1} test datatable.101 {column index 1000} { list [catch {datatable0 column index 1000} msg] $msg } {0 -1} test datatable.102 {column type 1} { list [catch {datatable0 column type 1} msg] $msg } {0 string} test datatable.103 {column type 2 integer} { list [catch {datatable0 column type 2 integer} msg] $msg } {1 {expected integer but got "1.0"}} test datatable.104 {column type 4 double} { list [catch {datatable0 column type 4 double} msg] $msg } {0 double} test datatable.106 {column type 1 string} { list [catch {datatable0 column type 1 string} msg] $msg } {0 string} test datatable.107 {column type 1 string badArg} { list [catch {datatable0 column type 1 string badArg} msg] $msg } {1 {wrong # args: should be "datatable0 column type column ?type?"}} test datatable.108 {column type badTag string} { list [catch {datatable0 column type badTag string} msg] $msg } {1 {unknown column specification "badTag" in ::datatable0}} test datatable.109 {column type all string} { list [catch {datatable0 column type all string} msg] $msg } {0 {string string string string string}} test datatable.110 {column tag badOp} { list [catch {datatable0 column tag badOp} msg] $msg } {1 {bad tag operation "badOp": should be one of... datatable0 column tag add tag ?column...? datatable0 column tag delete tag ?column...? datatable0 column tag exists tag ?column? datatable0 column tag forget ?tag...? datatable0 column tag get column ?pattern...? datatable0 column tag indices ?tag...? datatable0 column tag labels ?tag...? datatable0 column tag range from to ?tag...? datatable0 column tag search column ?pattern? datatable0 column tag set column tag... datatable0 column tag unset column tag...}} test datatable.111 {column tag (missing args)} { list [catch {datatable0 column tag} msg] $msg } {1 {wrong # args: should be one of... datatable0 column tag add tag ?column...? datatable0 column tag delete tag ?column...? datatable0 column tag exists tag ?column? datatable0 column tag forget ?tag...? datatable0 column tag get column ?pattern...? datatable0 column tag indices ?tag...? datatable0 column tag labels ?tag...? datatable0 column tag range from to ?tag...? datatable0 column tag search column ?pattern? datatable0 column tag set column tag... datatable0 column tag unset column tag...}} test datatable.112 {datatable0 column tag badOp} { list [catch {datatable0 column tag badOp} msg] $msg } {1 {bad tag operation "badOp": should be one of... datatable0 column tag add tag ?column...? datatable0 column tag delete tag ?column...? datatable0 column tag exists tag ?column? datatable0 column tag forget ?tag...? datatable0 column tag get column ?pattern...? datatable0 column tag indices ?tag...? datatable0 column tag labels ?tag...? datatable0 column tag range from to ?tag...? datatable0 column tag search column ?pattern? datatable0 column tag set column tag... datatable0 column tag unset column tag...}} test datatable.113 {datatable0 column tag add} { list [catch {datatable0 column tag add} msg] $msg } {1 {wrong # args: should be "datatable0 column tag add tag ?column...?"}} test datatable.114 {datatable0 column tag add newTag (no columns)} { list [catch {datatable0 column tag add newTag} msg] $msg } {0 {}} test datatable.115 {datatable0 column tag add newTag badIndex} { list [catch {datatable0 column tag add newTag badIndex} msg] $msg } {1 {unknown column specification "badIndex" in ::datatable0}} test datatable.116 {datatable0 column tag add newTag 1} { list [catch {datatable0 column tag add newTag 1} msg] $msg } {0 {}} test datatable.117 {datatable0 column tag add newTag1 1 2 3} { list [catch {datatable0 column tag add newTag1 1 2 3} msg] $msg } {0 {}} test datatable.117 {datatable0 column tag add newTag2 all} { list [catch {datatable0 column tag add newTag2 1} msg] $msg } {0 {}} test datatable.118 {datatable0 column tag search} { list [catch {datatable0 column tag search} msg] $msg } {1 {wrong # args: should be "datatable0 column tag search column ?pattern?"}} test datatable.119 {datatable0 column tag search 1} { list [catch {datatable0 column tag search 1} msg] [lsort $msg] } {0 {all newTag newTag1 newTag2}} test datatable.120 {datatable0 column tag search 1*Tag*} { list [catch {datatable0 column tag search 1 *Tag*} msg] [lsort $msg] } {0 {newTag newTag1 newTag2}} test datatable.121 {datatable0 column tag search all} { list [catch {datatable0 column tag search all} msg] $msg } {0 {newTag2 newTag newTag1 all end}} test datatable.122 {datatable0 column tag search end} { list [catch {datatable0 column tag search end} msg] $msg } {0 {all end}} test datatable.123 {datatable0 column tag search end end} { list [catch {datatable0 column tag search end end} msg] $msg } {0 end} test datatable.124 {datatable0 column tag search end e*} { list [catch {datatable0 column tag search end e*} msg] $msg } {0 end} test datatable.125 {datatable0 column tag delete} { list [catch {datatable0 column tag delete} msg] $msg } {1 {wrong # args: should be "datatable0 column tag delete tag ?column...?"}} test datatable.126 {datatable0 column tag delete badTag} { list [catch {datatable0 column tag delete badTag} msg] $msg } {0 {}} test datatable.127 {datatable0 column tag delete newTag1} { list [catch {datatable0 column tag delete newTag1} msg] $msg } {0 {}} test datatable.128 {datatable0 column tag delete newTags1 1} { list [catch {datatable0 column tag delete newTag1 1} msg] $msg } {0 {}} test datatable.129 {column tag delete newTag2 1} { list [catch {datatable0 column tag delete newTag2 1} msg] $msg } {0 {}} test datatable.130 {column tag delete badTag 1} { list [catch {datatable0 column tag delete badTag 1} msg] $msg } {1 {unknown column tag "badTag"}} test datatable.131 {column tag delete someTag 1000} { list [catch {datatable0 column tag delete someTag 1000} msg] $msg } {1 {bad column index "1000"}} test datatable.132 {column tag delete end 1} { list [catch {datatable0 column tag delete end 1} msg] $msg } {0 {}} test datatable.133 {column tag delete all 1} { list [catch {datatable0 column tag delete all 1} msg] $msg } {0 {}} test datatable.134 {column tag forget} { list [catch {datatable0 column tag forget} msg] $msg } {0 {}} test datatable.135 {column tag forget all} { list [catch {datatable0 column tag forget all} msg] $msg } {0 {}} test datatable.136 {column tag forget newTag1} { list [catch {datatable0 column tag forget newTag1} msg] $msg } {0 {}} test datatable.137 {column tag forget newTag1} { list [catch {datatable0 column tag forget newTag1} msg] $msg } {1 {unknown column tag "newTag1"}} test datatable.138 {column tag indices} { list [catch {datatable0 column tag indices} msg] $msg } {0 {}} test datatable.139 {column tag indices all} { list [catch {datatable0 column tag indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.140 {column tag indices end} { list [catch {datatable0 column tag indices end} msg] $msg } {0 5} test datatable.141 {column tag indices newTag} { list [catch {datatable0 column tag indices newTag} msg] $msg } {0 1} test datatable.142 {column tag range 1 3 midTag} { list [catch {datatable0 column tag range 1 3 midTag} msg] $msg } {0 {}} test datatable.143 {column tag indices midTag} { list [catch {datatable0 column tag indices midTag} msg] $msg } {0 {1 2 3}} test datatable.144 {column tag range end 1 myTag} { list [catch {datatable0 column tag range end 1 myTag} msg] $msg } {0 {}} test datatable.145 {column tag indices myTag} { list [catch {datatable0 column tag indices myTag} msg] $msg } {0 {1 2 3 4 5}} test datatable.146 {column tag range -1 1 myTag} { list [catch {datatable0 column tag range -1 1 myTag} msg] $msg } {1 {unknown column specification "-1" in ::datatable0}} test datatable.147 {column tag range 1 -1 myTag} { list [catch {datatable0 column tag range 1 -1 myTag} msg] $msg } {1 {unknown column specification "-1" in ::datatable0}} test datatable.148 {column tag range 1 1000 myTag} { list [catch {datatable0 column tag range 1 1000 myTag} msg] $msg } {1 {bad column index "1000"}} test datatable.149 {column unset} { list [catch {datatable0 column unset} msg] $msg } {1 {wrong # args: should be "datatable0 column unset column..."}} test datatable.150 {column unset 1} { list [catch {datatable0 column unset 1} msg] $msg } {0 {}} test datatable.151 {column unset 1 end} { list [catch {datatable0 column unset 1 end} msg] $msg } {0 {}} test datatable.152 {column extend 5 badArg } { list [catch {datatable0 column extend 5 badArg} msg] $msg } {1 {column label "5" can't be a number.}} test datatable.153 {column extend} { list [catch {datatable0 column extend} msg] $msg } {1 {wrong # args: should be "datatable0 column extend label ?label...?"}} test datatable.154 {column extend -1} { list [catch {datatable0 column extend -1} msg] $msg } {1 {bad count "-1": # columns can't be negative.}} if 0 { test datatable.155 {column extend 10000000000 } { list [catch {datatable0 column extend 10000000000} msg] $msg } {1 {can't extend table by 10000000000 columns: out of memory.}} } test datatable.156 {column extend -10 } { list [catch {datatable0 column extend -10} msg] $msg } {1 {bad count "-10": # columns can't be negative.}} test datatable.157 {column extend 10 } { list [catch {datatable0 column extend 10} msg] $msg } {0 {8 9 10 11 12 13 14 15 16 17}} test datatable.158 {column label 6 c6 7 c7 8 c8...} { list [catch { datatable0 column label \ 6 c6 7 c7 8 c8 9 c9 10 c10 11 c11 12 c12 13 c13 14 c14 15 c15 } msg] $msg } {0 {}} test datatable.159 {column names} { list [catch {datatable0 column names} msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17}} test datatable.160 {column delete 10 } { list [catch {datatable0 column delete 10} msg] $msg } {0 {}} test datatable.161 {column names} { list [catch {datatable0 column names} msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c11 c12 c13 c14 c15 c16 c17}} test datatable.162 {column delete 10 } { list [catch {datatable0 column delete 10} msg] $msg } {0 {}} test datatable.163 {column names} { list [catch {datatable0 column names} msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c12 c13 c14 c15 c16 c17}} test datatable.164 {column length} { list [catch {datatable0 column length} msg] $msg } {0 15} test datatable.165 {column create} { list [catch {datatable0 column create} msg] $msg } {0 16} test datatable.166 {column names} { list [catch {datatable0 column names} msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c12 c13 c14 c15 c16 c17 c18}} test datatable.167 {column label end fred} { list [catch { datatable0 column label end fred datatable0 column names } msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c12 c13 c14 c15 c16 c17 fred}} test datatable.168 {column label end c18} { list [catch { datatable0 column label end c18 datatable0 column names } msg] $msg } {0 {c1 c2 c3 c4 c5 c6 c7 c8 c9 c12 c13 c14 c15 c16 c17 c18}} test datatable.169 {column create -before 1 -badSwitch} { list [catch {datatable0 column create -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.170 {datatable0 column create -badSwitch -before 1} { list [catch {datatable0 column create -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.171 {datatable0 column create -before 1 -badSwitch arg} { list [catch {datatable0 column create -badSwitch arg} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.172 {datatable0 column create -before 1 -label nc1} { list [catch {datatable0 column create -before 1 -label nc1} msg] $msg } {0 1} test datatable.173 {datatable0 column create -before 2 -label nc2} { list [catch {datatable0 column create -before 2 -label nc2} msg] $msg } {0 2} test datatable.174 {datatable0 column create -after 3 -label nc3} { list [catch {datatable0 column create -after 3 -label nc3} msg] $msg } {0 4} test datatable.175 {datatable0 column length} { list [catch {datatable0 column length} msg] $msg } {0 19} test datatable.176 {datatable0 column index end} { list [catch {datatable0 column index end} msg] $msg } {0 19} test datatable.177 {datatable0 column names} { list [catch {datatable0 column names} msg] $msg } {0 {nc1 nc2 c1 nc3 c2 c3 c4 c5 c6 c7 c8 c9 c12 c13 c14 c15 c16 c17 c18}} test datatable.178 {datatable0 column create -after end} { list [catch {datatable0 column create -after end} msg] $msg } {0 20} test datatable.179 {datatable0 column create -after 1} { list [catch {datatable0 column create -after 1} msg] $msg } {0 2} test datatable.180 {datatable0 column create -label -one} { list [catch {datatable0 column create -label -one} msg] $msg } {1 {column label "-one" can't start with a '-'.}} test datatable.181 {datatable0 column create -label abc-one} { list [catch {datatable0 column create -label abc-one} msg] $msg } {0 22} test datatable.182 {datatable0 column create -label} { list [catch {datatable0 column create -label} msg] $msg } {1 {value for "-label" missing}} test datatable.183 {datatable0 column create -before 0} { list [catch {datatable0 column create -before 0} msg] $msg } {1 {bad column index "0"}} test datatable.184 {datatable0 column length} { list [catch {datatable0 column length} msg] $msg } {0 22} test datatable.185 {datatable0 column index fred} { list [catch {datatable0 column index fred} msg] $msg } {0 -1} test datatable.186 {datatable0 column index one} { list [catch {datatable0 column index one} msg] $msg } {0 -1} test datatable.187 {datatable0 column index end} { list [catch {datatable0 column index end} msg] $msg } {0 22} test datatable.188 {datatable0 column create -after 40} { list [catch {datatable0 column create -after 40} msg] $msg } {1 {bad column index "40"}} test datatable.189 {datatable0 column create -tags {myTag1 myTag2}} { list [catch { datatable0 column create -tags {myTag1 myTag2} } msg] $msg } {0 23} test datatable.190 {datatable0 column create -after end -tags {myTag1 myTag2}} { list [catch { datatable0 column create -after end -tags {myTag1 myTag2} } msg] $msg } {0 24} test datatable.191 {datatable0 column tag indices myTag1 myTag2} { list [catch { datatable0 column tag indices myTag1 myTag2 } msg] $msg } {0 {23 24}} test datatable.192 {datatable0 column tag indices myTag1 myTag2} { list [catch { datatable0 column tag indices myTag1 myTag2 } msg] $msg } {0 {23 24}} test datatable.193 {datatable0 column move} { list [catch {datatable0 column move} msg] $msg } {1 {wrong # args: should be "datatable0 column move from to ?count?"}} test datatable.194 {datatable0 column move 0} { list [catch {datatable0 column move 0} msg] $msg } {1 {wrong # args: should be "datatable0 column move from to ?count?"}} test datatable.195 {datatable0 column move 0 0} { list [catch {datatable0 column move 0 0} msg] $msg } {1 {bad column index "0"}} test datatable.196 {datatable0 column move 10 0} { list [catch {datatable0 column move 10 0} msg] $msg } {1 {bad column index "0"}} test datatable.197 {datatable0 column move all 10} { list [catch {datatable0 column move all 10} msg] $msg } {1 {multiple columns specified by "all"}} test datatable.198 {column label} { list [catch { set nCols [datatable0 column length] for { set i 1} { $i <= $nCols } { incr i } { lappend labels $i c$i } eval datatable0 column label $labels } msg] $msg } {0 {}} test datatable.199 {datatable0 column move 1 10 0} { list [catch { # This should be a no-op. set before [datatable0 column names] datatable0 column move 1 10 0 set after [datatable0 column names] expr {$before == $after} } msg] $msg } {0 1} test datatable.200 {datatable0 column move 1 1} { list [catch { # This should be a no-op. set before [datatable0 column names] datatable0 column move 1 1 set after [datatable0 column names] expr {$before == $after} } msg] $msg } {0 1} test datatable.201 {datatable0 column move 1 10} { list [catch { datatable0 column move 1 10 datatable0 column names } msg] $msg } {0 {c2 c3 c4 c5 c6 c7 c8 c9 c10 c1 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24}} test datatable.202 {datatable0 column move 1 2} { list [catch { datatable0 column move 1 2 datatable0 column names } msg] $msg } {0 {c3 c2 c4 c5 c6 c7 c8 c9 c10 c1 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24}} test datatable.203 {datatable0 column move 0 2} { list [catch {datatable0 column move 0 2} msg] $msg } {1 {bad column index "0"}} test datatable.204 {datatable0 column move 1 17} { list [catch {datatable0 column move 1 17} msg] $msg } {0 {}} test datatable.205 {find expr} { list [catch { datatable0 column tag set 4 testTag datatable0 find { $testTag > 3.0 } } msg] $msg } {0 {4 5}} #exit 0 test datatable.206 {datatable0 column trace} { list [catch {datatable0 column trace} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} test datatable.207 {column trace all} { list [catch {datatable0 column trace all} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} test datatable.208 {column trace end} { list [catch {datatable0 column trace end} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} test datatable.209 {column trace 1} { list [catch {datatable0 column trace 1} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} test datatable.210 {column trace 1 rwuc} { list [catch {datatable0 column trace 1 rwuc} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} test datatable.211 {column trace all rwuc} { list [catch {datatable0 column trace all rwuc} msg] $msg } {1 {wrong # args: should be "datatable0 column trace column how command"}} proc Doit { args } { global mylist; lappend mylist $args } test datatable.212 {column trace all rwuc Doit} { list [catch {datatable0 column trace all rwuc Doit} msg] $msg } {0 trace0} test datatable.213 {trace info trace0} { list [catch {datatable0 trace info trace0} msg] $msg } {0 {id trace0 column all flags rwuc command Doit}} test datatable.214 {test create trace} { list [catch { set mylist {} datatable0 set all 1 20 set mylist } msg] $msg } {0 {{::datatable0 1 1 wc} {::datatable0 2 1 wc} {::datatable0 3 1 wc} {::datatable0 4 1 wc} {::datatable0 5 1 wc}}} test datatable.215 {test read trace} { list [catch { set mylist {} datatable0 column get 1 set mylist } msg] $msg } {0 {{::datatable0 1 1 r} {::datatable0 2 1 r} {::datatable0 3 1 r} {::datatable0 4 1 r} {::datatable0 5 1 r}}} test datatable.216 {test write trace} { list [catch { set mylist {} datatable0 column set 1 1 a 2 b 3 c 4 d 5 e set mylist } msg] $msg } {0 {{::datatable0 1 1 w} {::datatable0 2 1 w} {::datatable0 3 1 w} {::datatable0 4 1 w} {::datatable0 5 1 w}}} test datatable.217 {test unset trace} { list [catch { set mylist {} datatable0 column unset 1 set mylist } msg] $msg } {0 {{::datatable0 1 1 u} {::datatable0 2 1 u} {::datatable0 3 1 u} {::datatable0 4 1 u} {::datatable0 5 1 u}}} test datatable.218 {trace delete} { list [catch {datatable0 trace delete} msg] $msg } {0 {}} if 0 { puts stderr [datatable0 column type all double] datatable0 column set 4 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 datatable0 column set 5 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 datatable0 column set 6 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 puts stderr [datatable0 export csv] puts stderr [datatable0 export xml] puts stderr 1,1=[datatable0 get 1 1] } test datatable.219 {trace delete badId} { list [catch {datatable0 trace delete badId} msg] $msg } {1 {unknown trace "badId"}} test datatable.220 {trace delete trace0} { list [catch {datatable0 trace delete trace0} msg] $msg } {0 {}} test datatable.221 {export -file} { list [catch {datatable0 export -file} msg] $msg } {1 {can't export "-file": format not registered}} test datatable.222 {export csv -file} { list [catch {datatable0 export csv -file} msg] $msg } {1 {value for "-file" missing}} test datatable.223 {exportfile csv -file /badDir/badFile } { list [catch {datatable0 export csv -file /badDir/badFile} msg] $msg } {1 {couldn't open "/badDir/badFile": no such file or directory}} test datatable.224 {exportfile csv -file @badChannel } { list [catch {datatable0 export csv -file @badChannel} msg] $msg } {1 {can not find channel named "badChannel"}} test datatable.225 {export csv -file table.csv} { list [catch {datatable0 export csv -file table.csv} msg] $msg } {0 {}} test datatable.109 {column type all double} { list [catch {datatable0 column type all double} msg] $msg } {0 {double double double double double double double double double double double double double double double double double double double double double double double double}} test datatable.226 {export csv -rowlabels -columnlabels} { list [catch {datatable0 export csv -rowlabels -columnlabels} msg] $msg } {0 {"*BLT*","c2","c4","c5","c6","c7","c8","c9","c10","c1","c11","c12","c13","c14","c15","c16","c17","c3","c18","c19","c20","c21","c22","c23","c24" "r1",,,,1.0,1.0,1.0,,,,,,,,,,,,,,,,,, "r2",,,,2.0,2.0,2.0,,,,,,,,,,,,,,,,,, "r3",,,,3.0,3.0,3.0,,,,,,,,,,,,,,,,,, "r4",,,,4.0,4.0,4.0,,,,,,,,,,,,,,,,,, "r5",,,,5.0,5.0,5.0,,,,,,,,,,,,,,,,,, }} test datatable.109 {column type all string} { list [catch {datatable0 column type all string} msg] $msg } {0 {string string string string string string string string string string string string string string string string string string string string string string string string}} #---------------------- test datatable.227 {dump -file table.dump} { list [catch {datatable0 dump -file table.dump} msg] $msg } {0 {}} test datatable.228 {datatable0 set (no args)} { list [catch { datatable0 set } msg] $msg } {1 {wrong # args: should be "datatable0 set ?row column value?..."}} test datatable.229 {datatable0 set 1 (no column)} { list [catch { datatable0 set 1 } msg] $msg } {1 {wrong # args: should be "datatable0 set ?row column value?..."}} test datatable.230 {datatable0 set 1 1 (no value)} { list [catch { datatable0 set 1 1 } msg] $msg } {1 {wrong # args: should be "datatable0 set ?row column value?..."}} test datatable.231 {datatable0 set 1 1 1.0 3.0 (too many args)} { list [catch { datatable0 set 1 1 1.0 3.0} msg] $msg } {1 {wrong # args: should be "datatable0 set ?row column value?..."}} test datatable.232 {datatable0 set 1 1 1.0} { list [catch { datatable0 set 1 1 1.0 } msg] $msg } {0 {}} test datatable.233 {datatable0 get 1 1} { list [catch { datatable0 get 1 1 } msg] $msg } {0 1.0} test datatable.234 {datatable0 row exists newRow} { list [catch { datatable0 row exists newRow } msg] $msg } {0 0} test datatable.235 {datatable0 set newRow 1 abc} { list [catch { datatable0 set newRow 1 abc } msg] $msg } {0 {}} test datatable.236 {datatable0 get newRow 1} { list [catch { datatable0 get newRow 1 } msg] $msg } {0 abc} test datatable.237 {datatable0 row exists newRow} { list [catch { datatable0 row exists newRow } msg] $msg } {0 1} test datatable.238 {datatable0 column exists newColumn} { list [catch { datatable0 column exists newColumn } msg] $msg } {0 0} test datatable.239 {datatable0 set 1 newColumn def} { list [catch { datatable0 set 1 newColumn def } msg] $msg } {0 {}} test datatable.240 {datatable0 get 1 newColumn} { list [catch { datatable0 get 1 newColumn } msg] $msg } {0 def} test datatable.241 {datatable0 row delete newRow} { list [catch { datatable0 row delete newRow } msg] $msg } {0 {}} test datatable.242 {datatable0 row exists newRow} { list [catch { datatable0 row exists newRow } msg] $msg } {0 0} test datatable.243 {datatable0 column delete newColumn} { list [catch { datatable0 column delete newColumn } msg] $msg } {0 {}} test datatable.244 {datatable0 column exists newColumn} { list [catch { datatable0 row exists newRow } msg] $msg } {0 0} test datatable.245 {datatable0 set newRow newColumn abc} { list [catch { datatable0 set newRow newColumn abc } msg] $msg } {0 {}} test datatable.246 {datatable0 row delete newRow} { list [catch { datatable0 row delete newRow } msg] $msg } {0 {}} test datatable.247 {datatable0 column delete newColumn} { list [catch { datatable0 column delete newColumn } msg] $msg } {0 {}} test datatable.248 {datatable0 column type 1 double} { list [catch { datatable0 column type 1 double } msg] $msg } {0 double} test datatable.249 {datatable0 set 1 1 1.0} { list [catch { datatable0 set 1 1 1.0 datatable0 get 1 1 } msg] $msg } {0 1.0} test datatable.249 {datatable0 set end 1 1.0 end 2 2.0 end 3 3.0 end 4 4.0 } { list [catch { datatable0 set end 1 1.0 end 2 2.0 end 3 3.0 end 4 4.0 } msg] $msg } {0 {}} test datatable.249 {datatable0 set 6 1 1.0 6 } { list [catch { datatable0 set 6 1 1.0 6 } msg] $msg } {1 {wrong # args: should be "datatable0 set ?row column value?..."}} test datatable.250 {datatable0 set 1 1 abc} { list [catch { datatable0 set 1 1 abc } msg] $msg } {1 {expected floating-point number but got "abc"}} test datatable.248 {datatable0 column type 1 string} { list [catch { datatable0 column type 1 string } msg] $msg } {0 string} test datatable.250 {datatable0 unset 1 1} { list [catch { datatable0 unset 1 1} msg] $msg } {0 {}} test datatable.250 {datatable0 append 1 1 abc (from empty)} { list [catch { datatable0 append 1 1 abc} msg] $msg } {0 {}} test datatable.236 {datatable0 get 1 1} { list [catch { datatable0 get 1 1 } msg] $msg } {0 abc} test datatable.250 {datatable0 append 1 1 def (from empty)} { list [catch { datatable0 append 1 1 def} msg] $msg } {0 {}} test datatable.236 {datatable0 get 1 1} { list [catch { datatable0 get 1 1 } msg] $msg } {0 abcdef} test datatable.236 {datatable0 get 1 2 defValue } { list [catch { datatable0 get 2 1 defValue } msg] $msg } {0 defValue} test datatable.236 {datatable0 get 1 2 defValue (too many args) } { list [catch { datatable0 get 2 1 defValue extraArg } msg] $msg } {1 {wrong # args: should be "datatable0 get row column ?defValue?"}} test datatable.250 {datatable0 append 1 1 123 456 789 (from empty)} { list [catch { datatable0 append 1 1 123 456 789 } msg] $msg } {0 {}} test datatable.236 {datatable0 get 1 1} { list [catch { datatable0 get 1 1 } msg] $msg } {0 abcdef123456789} test datatable.250 {datatable0 unset 1 1} { list [catch { datatable0 unset 1 1} msg] $msg } {0 {}} test datatable.250 {datatable0 unset 1 1} { list [catch { datatable0 unset 1 1} msg] $msg } {0 {}} test datatable.249 {datatable0 unset 1 1 1 } { list [catch { datatable0 unset 1 1 1 } msg] $msg } {1 {wrong # args: should be "datatable0 unset ?row column?...}} test datatable.249 {datatable0 unset end 1 end 2 end 3 end 4 } { list [catch { datatable0 unset end 1 end 2 end 3 end 4 } msg] $msg } {0 {}} test datatable.249 {datatable0 unset 0 0 } { list [catch { datatable0 unset 0 0 } msg] $msg } {0 {}} test datatable.249 {datatable0 unset 10000 10000 } { list [catch { datatable0 unset 10000 10000 } msg] $msg } {0 {}} test datatable.249 {datatable0 unset 10000 10000 } { list [catch { datatable0 unset 10000 10000 } msg] $msg } {0 {}} #--------------------- test datatable.251 {blt::datatable create} { list [catch {blt::datatable create} msg] $msg } {0 ::datatable1} test datatable.252 {column extend 5} { list [catch {datatable1 column extend 5} msg] $msg } {0 {1 2 3 4 5}} test datatable.253 {row length} { list [catch {datatable1 row length} msg] $msg } {0 0} test datatable.254 {row length} { list [catch {datatable1 row length} msg] $msg } {0 0} test datatable.255 {row length badArg} { list [catch {datatable1 row length badArg} msg] $msg } {1 {wrong # args: should be "datatable1 row length "}} test datatable.256 {row -label xyz create} { list [catch {datatable1 row -label xyz create} msg] $msg } {1 {bad operation "-label": should be one of... datatable1 row copy src dest ?switches...? datatable1 row create ?switches...? datatable1 row delete row... datatable1 row dup row... datatable1 row exists row datatable1 row extend label ?label...? datatable1 row get row ?switches? datatable1 row index row datatable1 row indices row ?row...? datatable1 row label row ?label? datatable1 row labels ?labelList? datatable1 row length datatable1 row move from to ?count? datatable1 row names ?pattern...? datatable1 row notify row ?flags? command datatable1 row set row column value... datatable1 row tag op args... datatable1 row trace row how command datatable1 row unique row datatable1 row unset row... datatable1 row values row ?valueList?}} test datatable.257 {row extend 5} { list [catch {datatable1 row extend 5} msg] $msg } {0 {1 2 3 4 5}} test datatable.258 {row length} { list [catch {datatable1 row length} msg] $msg } {0 5} test datatable.259 {row index end} { list [catch {datatable1 row index end} msg] $msg } {0 5} test datatable.260 {row indices all} { list [catch {datatable1 row indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.261 {row indices 1-end} { list [catch {datatable1 row indices "1-end" } msg] $msg } {0 {1 2 3 4 5}} test datatable.262 {row indices 1-all} { list [catch {datatable1 row indices "1-all" } msg] $msg } {1 {unknown row specification "1-all" in ::datatable1}} test datatable.263 {row indices 2-5} { list [catch {datatable1 row indices 2-5} msg] $msg } {0 {2 3 4 5}} test datatable.264 {row indices 5-2} { list [catch {datatable1 row indices 5-2} msg] $msg } {0 {}} test datatable.265 {row index end} { list [catch {datatable1 row index end} msg] $msg } {0 5} test datatable.266 {row index end badArg} { list [catch {datatable1 row index end badArg} msg] $msg } {1 {wrong # args: should be "datatable1 row index row"}} test datatable.267 {row label 1} { list [catch {datatable1 row label 1} msg] $msg } {0 r1} test datatable.268 {row label 1 myLabel} { list [catch {datatable1 row label 1 myLabel} msg] $msg } {0 {}} test datatable.269 {row label 1} { list [catch {datatable1 row label 1} msg] $msg } {0 myLabel} test datatable.270 {row label 2 myLabel} { list [catch {datatable1 row label 2 myLabel} msg] $msg } {0 {}} test datatable.271 {row label 1} { list [catch {datatable1 row label 1} msg] $msg } {0 myLabel} test datatable.272 {row label end end} { list [catch {datatable1 row label end end} msg] $msg } {0 {}} test datatable.273 {row label end endLabel} { list [catch {datatable1 row label end endLabel} msg] $msg } {0 {}} test datatable.274 {row label end 1abc} { list [catch {datatable1 row label end 1abc} msg] $msg } {0 {}} test datatable.275 {row label end label-with-minus} { list [catch {datatable1 row label end label-with-minus} msg] $msg } {0 {}} test datatable.276 {row label end -abc} { list [catch {datatable1 row label end -abc} msg] $msg } {1 {row label "-abc" can't start with a '-'.}} test datatable.277 {row names *Label} { list [catch {datatable1 row names *Label} msg] $msg } {0 {myLabel myLabel}} test datatable.278 {row names} { list [catch {datatable1 row names} msg] $msg } {0 {myLabel myLabel r3 r4 label-with-minus}} test datatable.279 {row names r*} { list [catch {datatable1 row names r*} msg] $msg } {0 {r3 r4}} test datatable.280 {row names *-with-*} { list [catch {datatable1 row names *-with-*} msg] $msg } {0 label-with-minus} test datatable.281 {datatable1 row names badPattern} { list [catch {datatable1 row names badPattern} msg] $msg } {0 {}} test datatable.282 {datatable1 row get myLabel} { list [catch {datatable1 row get myLabel} msg] $msg } {0 {1 {} 2 {} 3 {} 4 {} 5 {}}} test datatable.283 {datatable1 row get} { list [catch {datatable1 row get} msg] $msg } {1 {wrong # args: should be "datatable1 row get row ?switches?"}} test datatable.284 {datatable1 row set myLabel} { list [catch {datatable1 row set myLabel} msg] $msg } {1 {wrong # args: should be "datatable1 row set row column value..."}} test datatable.285 {row set all 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0} { list [catch { datatable1 row set all 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 } msg] $msg } {0 {}} test datatable.286 {datatable1 row values 1} { list [catch {datatable1 row values 1} msg] $msg } {0 {1.0 2.0 3.0 4.0 5.0}} test datatable.287 {datatable1 row values all} { list [catch {datatable1 row values all} msg] $msg } {1 {multiple rows specified by "all"}} test datatable.288 {datatable1 row values 1-2} { list [catch {datatable1 row values 1-2} msg] $msg } {1 {multiple rows specified by "1-2"}} test datatable.289 {datatable1 row values 2} { list [catch {datatable1 row values 2} msg] $msg } {0 {1.0 2.0 3.0 4.0 5.0}} test datatable.290 {datatable1 row values 3} { list [catch {datatable1 row values 3} msg] $msg } {0 {1.0 2.0 3.0 4.0 5.0}} test datatable.291 {datatable1 row values end} { list [catch {datatable1 row values end} msg] $msg } {0 {1.0 2.0 3.0 4.0 5.0}} test datatable.292 {datatable1 row values 1 { a b c }} { list [catch {datatable1 row values 1 { a b c }} msg] $msg } {0 {}} test datatable.293 {datatable1 row values 1} { list [catch {datatable1 row values 1} msg] $msg } {0 {a b c 4.0 5.0}} test datatable.294 {datatable1 row values end { x y }} { list [catch {datatable1 row values end { x y }} msg] $msg } {0 {}} test datatable.295 {datatable1 row values end} { list [catch {datatable1 row values end} msg] $msg } {0 {x y 3.0 4.0 5.0}} test datatable.296 {datatable1 row index label-with-minus} { list [catch {datatable1 row index label-with-minus} msg] $msg } {0 5} test datatable.297 {datatable1 row indices all} { list [catch {datatable1 row indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.298 {datatable1 row index -1} { list [catch {datatable1 row index -1} msg] $msg } {0 -1} test datatable.299 {datatable1 row index 1000} { list [catch {datatable1 row index 1000} msg] $msg } {0 -1} test datatable.300 {datatable1 row tag badOp} { list [catch {datatable1 row tag badOp} msg] $msg } {1 {bad tag operation "badOp": should be one of... datatable1 row tag add tag ?row...? datatable1 row tag delete tag ?row...? datatable1 row tag exists tag ?row? datatable1 row tag forget ?tag...? datatable1 row tag get row ?pattern...? datatable1 row tag indices ?tag...? datatable1 row tag labels ?tag...? datatable1 row tag range from to ?tag...? datatable1 row tag search row ?pattern? datatable1 row tag set row tag... datatable1 row tag unset row tag...}} test datatable.301 {datatable1 row tag (missing args)} { list [catch {datatable1 row tag} msg] $msg } {1 {wrong # args: should be one of... datatable1 row tag add tag ?row...? datatable1 row tag delete tag ?row...? datatable1 row tag exists tag ?row? datatable1 row tag forget ?tag...? datatable1 row tag get row ?pattern...? datatable1 row tag indices ?tag...? datatable1 row tag labels ?tag...? datatable1 row tag range from to ?tag...? datatable1 row tag search row ?pattern? datatable1 row tag set row tag... datatable1 row tag unset row tag...}} test datatable.302 {datatable1 row tag badOp} { list [catch {datatable1 row tag badOp} msg] $msg } {1 {bad tag operation "badOp": should be one of... datatable1 row tag add tag ?row...? datatable1 row tag delete tag ?row...? datatable1 row tag exists tag ?row? datatable1 row tag forget ?tag...? datatable1 row tag get row ?pattern...? datatable1 row tag indices ?tag...? datatable1 row tag labels ?tag...? datatable1 row tag range from to ?tag...? datatable1 row tag search row ?pattern? datatable1 row tag set row tag... datatable1 row tag unset row tag...}} test datatable.303 {datatable1 row tag add} { list [catch {datatable1 row tag add} msg] $msg } {1 {wrong # args: should be "datatable1 row tag add tag ?row...?"}} test datatable.304 {datatable1 row tag add 1} { list [catch {datatable1 row tag add 1} msg] $msg } {1 {tag "1" can't be a number.}} test datatable.305 {datatable1 row tag add tag badIndex} { list [catch {datatable1 row tag add tag badIndex} msg] $msg } {1 {unknown row specification "badIndex" in ::datatable1}} test datatable.306 {datatable1 row tag add newTag 1} { list [catch {datatable1 row tag add newTag 1} msg] $msg } {0 {}} test datatable.307 {datatable1 row tag add newTag1 1} { list [catch {datatable1 row tag add newTag1 1} msg] $msg } {0 {}} test datatable.307 {datatable1 row tag add newTag2 1} { list [catch {datatable1 row tag add newTag2 1} msg] $msg } {0 {}} test datatable.308 {datatable1 row tag search} { list [catch {datatable1 row tag search} msg] $msg } {1 {wrong # args: should be "datatable1 row tag search row ?pattern?"}} test datatable.309 {datatable1 row tag search 1} { list [catch {datatable1 row tag search 1} msg] [lsort $msg] } {0 {all newTag newTag1 newTag2}} test datatable.310 {datatable1 row tag search 1*Tag*} { list [catch {datatable1 row tag search 1 *Tag*} msg] [lsort $msg] } {0 {newTag newTag1 newTag2}} test datatable.311 {datatable1 row tag search all} { list [catch {datatable1 row tag search all} msg] $msg } {0 {newTag2 newTag newTag1 all end}} test datatable.312 {datatable1 row tag search end} { list [catch {datatable1 row tag search end} msg] $msg } {0 {all end}} test datatable.313 {datatable1 row tag search end end} { list [catch {datatable1 row tag search end end} msg] $msg } {0 end} test datatable.314 {datatable1 row tag search end e*} { list [catch {datatable1 row tag search end e*} msg] $msg } {0 end} test datatable.315 {datatable1 row tag delete} { list [catch {datatable1 row tag delete} msg] $msg } {1 {wrong # args: should be "datatable1 row tag delete tag ?row...?"}} test datatable.316 {datatable1 row tag delete someTag} { list [catch {datatable1 row tag delete someTag} msg] $msg } {0 {}} test datatable.317 {datatable1 row tag delete newTag1 1} { list [catch {datatable1 row tag delete newTag1 1} msg] $msg } {0 {}} test datatable.318 {datatable1 row tag delete newTag1 1} { list [catch {datatable1 row tag delete newTag1 1} msg] $msg } {0 {}} test datatable.319 {datatable1 row tag delete newTag2 1} { list [catch {datatable1 row tag delete newTag2 1} msg] $msg } {0 {}} test datatable.320 {datatable1 row tag delete badTag 1} { list [catch {datatable1 row tag delete badTag 1} msg] $msg } {1 {unknown row tag "badTag"}} test datatable.321 {datatable1 row tag delete someTag 1000} { list [catch {datatable1 row tag delete someTag 1000} msg] $msg } {1 {bad row index "1000"}} test datatable.322 {datatable1 row tag delete end 1} { list [catch {datatable1 row tag delete end 1} msg] $msg } {0 {}} test datatable.323 {datatable1 row tag delete all 1} { list [catch {datatable1 row tag delete all 1} msg] $msg } {0 {}} test datatable.324 {datatable1 row tag forget} { list [catch {datatable1 row tag forget} msg] $msg } {0 {}} test datatable.325 {row tag forget all} { list [catch {datatable1 row tag forget all} msg] $msg } {0 {}} test datatable.326 {row tag forget newTag1} { list [catch {datatable1 row tag forget newTag1} msg] $msg } {0 {}} test datatable.327 {row tag forget newTag1} { list [catch {datatable1 row tag forget newTag1} msg] $msg } {1 {unknown row tag "newTag1"}} test datatable.328 {row tag indices} { list [catch {datatable1 row tag indices} msg] $msg } {0 {}} test datatable.329 {row tag indices all} { list [catch {datatable1 row tag indices all} msg] $msg } {0 {1 2 3 4 5}} test datatable.330 {row tag indices end} { list [catch {datatable1 row tag indices end} msg] $msg } {0 5} test datatable.331 {row tag indices newTag} { list [catch {datatable1 row tag indices newTag} msg] $msg } {0 1} test datatable.332 {row tag range 1 3 midTag} { list [catch {datatable1 row tag range 1 3 midTag} msg] $msg } {0 {}} test datatable.333 {row tag indices midTag} { list [catch {datatable1 row tag indices midTag} msg] $msg } {0 {1 2 3}} test datatable.334 {row tag range end 1 myTag} { list [catch {datatable1 row tag range end 1 myTag} msg] $msg } {0 {}} test datatable.335 {row tag indices myTag} { list [catch {datatable1 row tag indices myTag} msg] $msg } {0 {1 2 3 4 5}} test datatable.336 {row tag range -1 1 myTag} { list [catch {datatable1 row tag range -1 1 myTag} msg] $msg } {1 {unknown row specification "-1" in ::datatable1}} test datatable.337 {row tag range 1 -1 myTag} { list [catch {datatable1 row tag range 1 -1 myTag} msg] $msg } {1 {unknown row specification "-1" in ::datatable1}} test datatable.338 {row tag range 1 1000 myTag} { list [catch {datatable1 row tag range 1 1000 myTag} msg] $msg } {1 {bad row index "1000"}} test datatable.339 {row unset} { list [catch {datatable1 row unset} msg] $msg } {1 {wrong # args: should be "datatable1 row unset row..."}} test datatable.340 {row unset 1} { list [catch {datatable1 row unset 1} msg] $msg } {0 {}} test datatable.341 {dump} { list [catch {datatable1 dump} msg] $msg } {0 {i 5 5 0 0 c 1 c1 string {} c 2 c2 string {} c 3 c3 string {} c 4 c4 string {} c 5 c5 string {} r 1 myLabel {myTag midTag newTag} r 2 myLabel {myTag midTag} r 3 r3 {myTag midTag} r 4 r4 {myTag} r 5 label-with-minus {myTag} d 2 1 1.0 d 3 1 1.0 d 4 1 1.0 d 5 1 x d 2 2 2.0 d 3 2 2.0 d 4 2 2.0 d 5 2 y d 2 3 3.0 d 3 3 3.0 d 4 3 3.0 d 5 3 3.0 d 2 4 4.0 d 3 4 4.0 d 4 4 4.0 d 5 4 4.0 d 2 5 5.0 d 3 5 5.0 d 4 5 5.0 d 5 5 5.0 }} test datatable.342 {datatable1 row get 1 defValue} { list [catch { datatable1 emptyvalue defValue set out [datatable1 row get 1] datatable1 emptyvalue "" eval list $out } msg] $msg } {0 {1 defValue 2 defValue 3 defValue 4 defValue 5 defValue}} test datatable.343 {datatable1 row unset 1 end} { list [catch {datatable1 row unset 1 end} msg] $msg } {0 {}} test datatable.344 {datatable1 row extend 5 badArg } { list [catch {datatable1 row extend 5 badArg} msg] $msg } {1 {row label "5" can't be a number.}} test datatable.345 {datatable1 row extend} { list [catch {datatable1 row extend} msg] $msg } {1 {wrong # args: should be "datatable1 row extend label ?label...?"}} test datatable.346 {datatable1 row extend myRow} { list [catch {datatable1 row extend myRow} msg] $msg } {0 8} if 0 { test datatable.347 {datatable1 row extend 10000000000 } { list [catch {datatable1 row extend 10000000000} msg] $msg } {1 {can't extend table by 10000000000 rows: out of memory.}} } test datatable.348 {datatable1 row extend -10 } { list [catch {datatable1 row extend -10} msg] $msg } {1 {bad count "-10": # rows can't be negative.}} test datatable.349 {datatable1 row extend 10 } { list [catch {datatable1 row extend 10} msg] $msg } {0 {9 10 11 12 13 14 15 16 17 18}} test datatable.350 {datatable1 row names} { list [catch {datatable1 row names} msg] $msg } {0 {myLabel myLabel r3 r4 label-with-minus r6 r7 myRow r9 r10 r11 r12 r13 r14 r15 r16 r17 r18}} test datatable.351 {datatable1 row delete 10 } { list [catch {datatable1 row delete 10} msg] $msg } {0 {}} test datatable.352 {datatable1 row names} { list [catch {datatable1 row names} msg] $msg } {0 {myLabel myLabel r3 r4 label-with-minus r6 r7 myRow r9 r11 r12 r13 r14 r15 r16 r17 r18}} test datatable.353 {datatable1 row delete 10 } { list [catch {datatable1 row delete 10} msg] $msg } {0 {}} test datatable.354 {datatable1 row length} { list [catch {datatable1 row length} msg] $msg } {0 16} test datatable.355 {datatable1 row create} { list [catch {datatable1 row create} msg] $msg } {0 17} test datatable.356 {datatable1 row create -before 1 -badSwitch} { list [catch {datatable1 row create -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.357 {datatable1 row create -badSwitch -before 1} { list [catch {datatable1 row create -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.358 {datatable1 row create -before 1 -badSwitch arg} { list [catch {datatable1 row create -badSwitch arg} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -after column -after row -before column -before row -label string -tags tags -type type}} test datatable.359 {datatable1 row create -before 1 -label one} { list [catch {datatable1 row create -before 1 -label one} msg] $msg } {0 1} test datatable.360 {datatable1 row create -before 2 -label two} { list [catch {datatable1 row create -before 2 -label two} msg] $msg } {0 2} test datatable.361 {datatable1 row create -after 3 -label three} { list [catch {datatable1 row create -after 3 -label three} msg] $msg } {0 4} test datatable.362 {datatable1 row length} { list [catch {datatable1 row length} msg] $msg } {0 20} test datatable.363 {datatable1 row names} { list [catch {datatable1 row names} msg] $msg } {0 {one two myLabel three myLabel r3 r4 label-with-minus r6 r7 myRow r9 r12 r13 r14 r15 r16 r17 r18 r19}} test datatable.364 {datatable1 row index end} { list [catch {datatable1 row index end} msg] $msg } {0 20} test datatable.365 {datatable1 row names} { list [catch {datatable1 row names} msg] $msg } {0 {one two myLabel three myLabel r3 r4 label-with-minus r6 r7 myRow r9 r12 r13 r14 r15 r16 r17 r18 r19}} test datatable.366 {datatable1 row create -after end} { list [catch {datatable1 row create -after end} msg] $msg } {0 21} test datatable.367 {datatable1 row create -after 1} { list [catch {datatable1 row create -after 1} msg] $msg } {0 2} test datatable.368 {datatable1 row create -label one} { list [catch {datatable1 row create -label one} msg] $msg } {0 23} test datatable.369 {datatable1 row create -label} { list [catch {datatable1 row create -label} msg] $msg } {1 {value for "-label" missing}} test datatable.370 {datatable1 row create -before 0} { list [catch {datatable1 row create -before 0} msg] $msg } {1 {bad row index "0"}} test datatable.371 {datatable1 row length} { list [catch {datatable1 row length} msg] $msg } {0 23} test datatable.372 {datatable1 row index fred} { list [catch {datatable1 row index fred} msg] $msg } {0 -1} test datatable.373 {datatable1 row index one} { list [catch {datatable1 row index one} msg] $msg } {0 23} test datatable.374 {datatable1 row index end} { list [catch {datatable1 row index end} msg] $msg } {0 23} test datatable.375 {datatable1 row create -after 40} { list [catch {datatable1 row create -after 40} msg] $msg } {1 {bad row index "40"}} test datatable.376 {datatable1 row create -tags {myTag1 myTag2}} { list [catch { datatable1 row create -tags {myTag1 myTag2} } msg] $msg } {0 24} test datatable.377 {datatable1 row create -after end -tags {myTag1 myTag2}} { list [catch { datatable1 row create -after end -tags {myTag1 myTag2} } msg] $msg } {0 25} test datatable.378 {datatable1 row tag indices myTag1 myTag2} { list [catch { datatable1 row tag indices myTag1 myTag2 } msg] $msg } {0 {24 25}} test datatable.379 {datatable1 row tag indices myTag1 myTag2} { list [catch { datatable1 row tag indices myTag1 myTag2 } msg] $msg } {0 {24 25}} test datatable.380 {datatable1 row move} { list [catch {datatable1 row move} msg] $msg } {1 {wrong # args: should be "datatable1 row move from to ?count?"}} test datatable.381 {datatable1 row move 0} { list [catch {datatable1 row move 0} msg] $msg } {1 {wrong # args: should be "datatable1 row move from to ?count?"}} test datatable.382 {datatable1 row move 0 0} { list [catch {datatable1 row move 0 0} msg] $msg } {1 {bad row index "0"}} test datatable.383 {datatable1 row move 10 0} { list [catch {datatable1 row move 10 0} msg] $msg } {1 {bad row index "0"}} test datatable.384 {datatable1 row move all 10} { list [catch {datatable1 row move all 10} msg] $msg } {1 {multiple rows specified by "all"}} test datatable.385 {datatable1 row move 1 10 0} { list [catch { datatable1 row move 1 10 0 datatable1 row names } msg] $msg } {0 {one r24 two myLabel three myLabel r3 r4 label-with-minus r6 r7 end r9 r12 r13 r14 r15 r16 r17 r18 r19 r23 one r26 r27}} test datatable.386 {datatable1 row move 1 1} { list [catch { datatable1 row move 1 1 datatable1 row names } msg] $msg } {0 {one r24 two myLabel three myLabel r3 r4 label-with-minus r6 r7 end r9 r12 r13 r14 r15 r16 r17 r18 r19 r23 one r26 r27}} test datatable.387 {datatable1 row move 1 10} { list [catch { datatable1 row move 1 10 datatable1 row names } msg] $msg } {0 {r24 two myLabel three myLabel r3 r4 label-with-minus r6 one r7 end r9 r12 r13 r14 r15 r16 r17 r18 r19 r23 one r26 r27}} test datatable.388 {datatable1 row move 1 2} { list [catch { datatable1 row move 1 2 datatable1 row names } msg] $msg } {0 {two r24 myLabel three myLabel r3 r4 label-with-minus r6 one r7 end r9 r12 r13 r14 r15 r16 r17 r18 r19 r23 one r26 r27}} test datatable.389 {export csv} { list [catch {datatable1 export csv} msg] $msg } {0 {"*BLT*","c1","c2","c3","c4","c5" "two",,,,, "r24",,,,, "myLabel",,,,, "three",,,,, "myLabel","1.0","2.0","3.0","4.0","5.0" "r3","1.0","2.0","3.0","4.0","5.0" "r4","1.0","2.0","3.0","4.0","5.0" "label-with-minus",,,,, "r6",,,,, "one",,,,, "r7",,,,, "end",,,,, "r9",,,,, "r12",,,,, "r13",,,,, "r14",,,,, "r15",,,,, "r16",,,,, "r17",,,,, "r18",,,,, "r19",,,,, "r23",,,,, "one",,,,, "r26",,,,, "r27",,,,, }} test datatable.390 {datatable1 row move 0 2} { list [catch {datatable1 row move 0 2} msg] $msg } {1 {bad row index "0"}} test datatable.391 {datatable1 row move 1 17} { list [catch {datatable1 row move 1 17} msg] $msg } {0 {}} #exit 0 test datatable.392 {datatable1 row trace} { list [catch {datatable1 row trace} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} test datatable.393 {datatable1 row trace all} { list [catch {datatable1 row trace all} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} test datatable.394 {datatable1 row trace end} { list [catch {datatable1 row trace end} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} test datatable.395 {datatable1 row trace 1} { list [catch {datatable1 row trace 1} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} test datatable.396 {datatable1 row trace 1 rwuc} { list [catch {datatable1 row trace 1 rwuc} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} test datatable.397 {datatable1 row trace all rwuc} { list [catch {datatable1 row trace all rwuc} msg] $msg } {1 {wrong # args: should be "datatable1 row trace row how command"}} proc Doit { args } { global mylist; lappend mylist $args } test datatable.398 {datatable1 row trace all rwuc Doit} { list [catch {datatable1 row trace all rwuc Doit} msg] $msg } {0 trace0} test datatable.399 {datatable1 trace info trace0} { list [catch {datatable1 trace info trace0} msg] $msg } {0 {id trace0 row all flags rwuc command Doit}} test datatable.400 {test create trace} { list [catch { set mylist {} datatable1 set all 1 20 set mylist } msg] $msg } {0 {{::datatable1 1 1 wc} {::datatable1 2 1 wc} {::datatable1 3 1 wc} {::datatable1 4 1 w} {::datatable1 5 1 w} {::datatable1 6 1 w} {::datatable1 7 1 wc} {::datatable1 8 1 wc} {::datatable1 9 1 wc} {::datatable1 10 1 wc} {::datatable1 11 1 wc} {::datatable1 12 1 wc} {::datatable1 13 1 wc} {::datatable1 14 1 wc} {::datatable1 15 1 wc} {::datatable1 16 1 wc} {::datatable1 17 1 wc} {::datatable1 18 1 wc} {::datatable1 19 1 wc} {::datatable1 20 1 wc} {::datatable1 21 1 wc} {::datatable1 22 1 wc} {::datatable1 23 1 wc} {::datatable1 24 1 wc} {::datatable1 25 1 wc}}} test datatable.401 {test read trace} { list [catch { set mylist {} datatable1 row get 1 -valuesonly set mylist } msg] $msg } {0 {{::datatable1 1 1 r} {::datatable1 1 2 r} {::datatable1 1 3 r} {::datatable1 1 4 r} {::datatable1 1 5 r}}} test datatable.402 {test write trace} { list [catch { set mylist {} datatable1 row values 1 {a b c d e} set mylist } msg] $msg } {0 {{::datatable1 1 1 w} {::datatable1 1 2 wc} {::datatable1 1 3 wc} {::datatable1 1 4 wc} {::datatable1 1 5 wc}}} test datatable.403 {test unset trace} { list [catch { set mylist {} datatable1 row unset 1 set mylist } msg] $msg } {0 {{::datatable1 1 1 u} {::datatable1 1 2 u} {::datatable1 1 3 u} {::datatable1 1 4 u} {::datatable1 1 5 u}}} test datatable.404 {datatable1 trace delete} { list [catch {datatable1 trace delete} msg] $msg } {0 {}} #--------------------- test datatable.405 {datatable1 trace} { list [catch {datatable1 trace} msg] $msg } {1 {wrong # args: should be one of... datatable1 trace create row column how command datatable1 trace delete traceId... datatable1 trace info traceId datatable1 trace names }} test datatable.406 {datatable1 trace create} { list [catch {datatable1 trace create} msg] $msg } {1 {wrong # args: should be "datatable1 trace create row column how command"}} test datatable.407 {datatable1 trace create 1} { list [catch {datatable1 trace create 1} msg] $msg } {1 {wrong # args: should be "datatable1 trace create row column how command"}} test datatable.408 {datatable1 trace create 1 1 } { list [catch {datatable1 trace create 1 1 } msg] $msg } {1 {wrong # args: should be "datatable1 trace create row column how command"}} test datatable.409 {datatable1 trace create 1 1 rwuc} { list [catch {datatable1 trace create 1 1 rwuc} msg] $msg } {1 {wrong # args: should be "datatable1 trace create row column how command"}} proc Doit args { global mylist; lappend mylist $args } test datatable.410 {datatable1 trace names} { list [catch {datatable1 trace names} msg] $msg } {0 trace0} test datatable.411 {datatable1 trace create 1 1 rwuc Doit} { list [catch {datatable1 trace create 1 1 rwuc Doit} msg] $msg } {0 trace1} test datatable.412 {datatable1 trace names} { list [catch {datatable1 trace names} msg] $msg } {0 {trace1 trace0}} test datatable.413 {datatable1 trace info trace1} { list [catch {datatable1 trace info trace1} msg] $msg } {0 {id trace1 row 1 column 1 flags rwuc command Doit}} test datatable.414 {test create trace} { list [catch { set mylist {} datatable1 set 1 1 "newValue" set mylist } msg] $msg } {0 {{::datatable1 1 1 wc} {::datatable1 1 1 wc}}} test datatable.415 {test read trace} { list [catch { set mylist {} datatable1 get 1 1 set mylist } msg] $msg } {0 {{::datatable1 1 1 r} {::datatable1 1 1 r}}} test datatable.416 {test write trace} { list [catch { set mylist {} datatable1 column values 1 { a b c e d } set mylist } msg] $msg } {0 {{::datatable1 1 1 w} {::datatable1 1 1 w} {::datatable1 2 1 w} {::datatable1 3 1 w} {::datatable1 4 1 w} {::datatable1 5 1 w}}} test datatable.417 {trace delete trace0} { list [catch {datatable1 trace delete trace0} msg] $msg } {0 {}} test datatable.418 {test write trace} { list [catch { set mylist {} datatable1 row values 1 { a b c e d } set mylist } msg] $msg } {0 {{::datatable1 1 1 w}}} test datatable.419 {test write trace} { list [catch { set mylist {} datatable1 set 1 1 "nextValue" set mylist } msg] $msg } {0 {{::datatable1 1 1 w}}} test datatable.420 {test unset trace} { list [catch { set mylist {} datatable1 unset 1 1 set mylist } msg] $msg } {0 {{::datatable1 1 1 u}}} test datatable.421 {datatable1 trace delete} { list [catch {datatable1 trace delete} msg] $msg } {0 {}} test datatable.422 {datatable1 trace delete badId} { list [catch {datatable1 trace delete badId} msg] $msg } {1 {unknown trace "badId"}} test datatable.423 {datatable1 trace names} { list [catch {datatable1 trace names} msg] $msg } {0 trace1} test datatable.424 {datatable1 trace names badArg} { list [catch {datatable1 trace names badArg} msg] $msg } {1 {wrong # args: should be "datatable1 trace names "}} test datatable.425 {datatable1 trace delete trace1} { list [catch {datatable1 trace delete trace1} msg] $msg } {0 {}} test datatable.426 {test create trace} { list [catch { set mylist {} datatable0 set all newKey 20 set mylist } msg] $msg } {0 {}} test datatable.427 {test unset trace} { list [catch { set mylist {} datatable0 unset all newKey set mylist } msg] $msg } {0 {}} test datatable.428 {datatable0 dump -badSwitch} { list [catch {datatable0 dump -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch"}} test datatable.429 {datatable0 dump -rows 1} { list [catch {datatable0 dump -rows 1} msg] $msg } {0 {i 1 22 0 0 c 1 one string c 2 c14 string c 3 two string c 4 myLabel image {myTag midTag newTag} c 5 three string c 6 c2 image {myTag midTag} c 7 c3 image {myTag midTag} c 8 c4 image myTag c 9 endLabel image myTag c 10 c1 string c 11 c5 string c 12 c6 string c 13 c7 string c 14 c10 string c 15 c11 string c 16 c12 string c 17 c13 string c 18 c8 string c 19 c9 string c 20 c15 string c 21 c16 string {myTag2 myTag1} c 22 c17 string {myTag2 myTag1} r 1 r1 d 1 6 1.0 d 1 7 1.0 d 1 8 1.0 }} test datatable.430 {datatable0 dump -columns 1} { list [catch {datatable0 dump -columns 1} msg] $msg } {0 {i 5 1 0 0 c 1 one string r 1 r1 r 2 r2 r 3 r3 r 4 r4 r 5 r5 }} test datatable.431 {dump -rows badTag} { list [catch {datatable0 dump -rows badTag} msg] $msg } {1 {can't find row tag "badTag" in ::datatable0}} test datatable.432 {dump -columns badTag} { list [catch {datatable0 dump -columns badTag} msg] $msg } {1 {can't find column tag "badTag" in ::datatable0}} test datatable.433 {dump -rows 1 -columns 1} { list [catch {datatable0 dump -rows 1 -columns 1} msg] $msg } {0 {i 1 1 0 0 c 1 one string r 1 r1 }} test datatable.434 {dump -file myout.dump} { list [catch {datatable0 dump -file myout.dump} msg] $msg } {0 {}} test datatable.435 {blt::datatable destroy datatable0} { list [catch {blt::datatable destroy datatable0} msg] $msg } {0 {}} test datatable.436 {blt::datatable create} { list [catch {blt::datatable create} msg] $msg } {0 ::datatable0} test datatable.437 {datatable0 column names} { list [catch {datatable0 column names} msg] $msg } {0 {}} test datatable.438 {datatable0 dump} { list [catch {datatable0 dump} msg] $msg } {0 {i 0 0 0 0 }} test datatable.439 {datatable0 restore} { list [catch {datatable0 restore} msg] $msg } {0 {}} test datatable.440 {datatable0 dump} { list [catch {datatable0 dump} msg] $msg } {0 {i 5 22 0 0 c 1 one string c 2 c14 string c 3 two string c 4 myLabel image {myTag midTag newTag} c 5 three string c 6 c2 image {myTag midTag} c 7 c3 image {myTag midTag} c 8 c4 image myTag c 9 endLabel image myTag c 10 c1 string c 11 c5 string c 12 c6 string c 13 c7 string c 14 c10 string c 15 c11 string c 16 c12 string c 17 c13 string c 18 c8 string c 19 c9 string c 20 c15 string c 21 c16 string {myTag2 myTag1} c 22 c17 string {myTag2 myTag1} r 1 r1 r 2 r2 r 3 r3 r 4 r4 r 5 r5 d 1 6 1.0 d 1 7 1.0 d 1 8 1.0 d 2 6 2.0 d 2 7 2.0 d 2 8 2.0 d 3 6 3.0 d 3 7 3.0 d 3 8 3.0 d 4 6 4.0 d 4 7 4.0 d 4 8 4.0 d 5 6 5.0 d 5 7 5.0 d 5 8 5.0 }} exit 0 #---------------------- test datatable.441 {datatable0 column tag names badNode} { list [catch {datatable0 column tag names badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::datatable0}} test datatable.442 {datatable0 column tag names all} { list [catch {datatable0 column tag names all} msg] $msg } {1 {multiple columns specified by "all"}} test datatable.443 {datatable0 column tag names root} { list [catch {datatable0 column tag names root} msg] $msg } {0 {all hi newTag root tag2}} test datatable.444 {datatable0 column tag names 0 1} { list [catch {datatable0 column tag names 0 1} msg] $msg } {0 {all hi newTag root tag2}} test datatable.445 {datatable0 column tag nodes (missing arg)} { list [catch {datatable0 column tag nodes} msg] $msg } {1 {wrong # args: should be "datatable0 column tag nodes tag ?tag...?"}} test datatable.446 {datatable0 column tag nodes root badTag} { list [catch {datatable0 column tag nodes root badTag} msg] $msg } {1 {can't find a tag "badTag"}} test datatable.447 {datatable0 column tag nodes root tag2} { list [catch {datatable0 column tag nodes root tag2} msg] $msg } {0 {0 1 2 3 4}} test datatable.448 {datatable0 create 0} { list [catch {datatable0 create 0} msg] $msg } {0 2} test datatable.449 {datatable0 create root} { list [catch {datatable0 create root} msg] $msg } {0 3} test datatable.450 {datatable0 create all} { list [catch {datatable0 create all} msg] $msg } {1 {multiple columns specified by "all"}} test datatable.451 {datatable0 create 0 -at badPosition} { list [catch {datatable0 create 0 -at badPosition} msg] $msg } {1 {expected integer but got "badPosition"}} test datatable.452 {datatable0 create 0 -at -1} { list [catch {datatable0 create 0 -at -1} msg] $msg } {1 {bad value "-1": can't be negative}} test datatable.453 {datatable0 create 0 -at 1000} { list [catch {datatable0 create 0 -at 1000} msg] $msg } {0 4} test datatable.454 {datatable0 create 0 -at (no arg)} { list [catch {datatable0 create 0 -at} msg] $msg } {1 {value for "-at" missing}} test datatable.455 {datatable0 create 0 -tags myTag} { list [catch {datatable0 create 0 -tags myTag} msg] $msg } {0 5} test datatable.456 {datatable0 insert 0 -tags {myTag1 myTag2} } { list [catch {datatable0 insert 0 -tags {myTag1 myTag2}} msg] $msg } {0 6} test datatable.457 {datatable0 insert 0 -tags root} { list [catch {datatable0 insert 0 -tags root} msg] $msg } {1 {can't add reserved tag "root"}} test datatable.458 {datatable0 insert 0 -tags (missing arg)} { list [catch {datatable0 insert 0 -tags} msg] $msg } {1 {value for "-tags" missing}} test datatable.459 {datatable0 insert 0 -label myLabel -tags thisTag} { list [catch {datatable0 insert 0 -label myLabel -tags thisTag} msg] $msg } {0 8} test datatable.460 {datatable0 insert 0 -label (missing arg)} { list [catch {datatable0 insert 0 -label} msg] $msg } {1 {value for "-label" missing}} test datatable.461 {datatable0 insert 1 -tags thisTag} { list [catch {datatable0 insert 1 -tags thisTag} msg] $msg } {0 9} test datatable.462 {datatable0 insert 1 -data key (missing value)} { list [catch {datatable0 insert 1 -data key} msg] $msg } {1 {missing value for "key"}} test datatable.463 {datatable0 insert 1 -data {key value}} { list [catch {datatable0 insert 1 -data {key value}} msg] $msg } {0 11} test datatable.464 {datatable0 insert 1 -data {key1 value1 key2 value2}} { list [catch {datatable0 insert 1 -data {key1 value1 key2 value2}} msg] $msg } {0 12} test datatable.465 {get} { list [catch { datatable0 get 12 } msg] $msg } {0 {key1 value1 key2 value2}} test datatable.466 {datatable0 children} { list [catch {datatable0 children} msg] $msg } {1 {wrong # args: should be "datatable0 children node ?first? ?last?"}} test datatable.467 {datatable0 children 0} { list [catch {datatable0 children 0} msg] $msg } {0 {1 2 3 4 5 6 8}} test datatable.468 {datatable0 children root} { list [catch {datatable0 children root} msg] $msg } {0 {1 2 3 4 5 6 8}} test datatable.469 {datatable0 children 1} { list [catch {datatable0 children 1} msg] $msg } {0 {9 11 12}} test datatable.470 {datatable0 insert myTag} { list [catch {datatable0 insert myTag} msg] $msg } {0 13} test datatable.471 {datatable0 children myTag} { list [catch {datatable0 children myTag} msg] $msg } {0 13} test datatable.472 {datatable0 children root 0 end} { list [catch {datatable0 children root 0 end} msg] $msg } {0 {1 2 3 4 5 6 8}} test datatable.473 {datatable0 children root 2} { list [catch {datatable0 children root 2} msg] $msg } {0 3} test datatable.474 {datatable0 children root 2 end} { list [catch {datatable0 children root 2 end} msg] $msg } {0 {3 4 5 6 8}} test datatable.475 {datatable0 children root end end} { list [catch {datatable0 children root end end} msg] $msg } {0 8} test datatable.476 {datatable0 children root 0 2} { list [catch {datatable0 children root 0 2} msg] $msg } {0 {1 2 3}} test datatable.477 {datatable0 children root -1 -20} { list [catch {datatable0 children root -1 -20} msg] $msg } {0 {}} test datatable.478 {datatable0 firstchild (missing arg)} { list [catch {datatable0 firstchild} msg] $msg } {1 {wrong # args: should be "datatable0 firstchild node"}} test datatable.479 {datatable0 firstchild root} { list [catch {datatable0 firstchild root} msg] $msg } {0 1} test datatable.480 {datatable0 lastchild (missing arg)} { list [catch {datatable0 lastchild} msg] $msg } {1 {wrong # args: should be "datatable0 lastchild node"}} test datatable.481 {datatable0 lastchild root} { list [catch {datatable0 lastchild root} msg] $msg } {0 8} test datatable.482 {datatable0 nextsibling (missing arg)} { list [catch {datatable0 nextsibling} msg] $msg } {1 {wrong # args: should be "datatable0 nextsibling node"}} test datatable.483 {datatable0 nextsibling 1)} { list [catch {datatable0 nextsibling 1} msg] $msg } {0 2} test datatable.484 {datatable0 nextsibling 2)} { list [catch {datatable0 nextsibling 2} msg] $msg } {0 3} test datatable.485 {datatable0 nextsibling 3)} { list [catch {datatable0 nextsibling 3} msg] $msg } {0 4} test datatable.486 {datatable0 nextsibling 4)} { list [catch {datatable0 nextsibling 4} msg] $msg } {0 5} test datatable.487 {datatable0 nextsibling 5)} { list [catch {datatable0 nextsibling 5} msg] $msg } {0 6} test datatable.488 {datatable0 nextsibling 6)} { list [catch {datatable0 nextsibling 6} msg] $msg } {0 8} test datatable.489 {datatable0 nextsibling 8)} { list [catch {datatable0 nextsibling 8} msg] $msg } {0 -1} test datatable.490 {datatable0 nextsibling all)} { list [catch {datatable0 nextsibling all} msg] $msg } {1 { than one node tagged as "all"}} test datatable.491 {datatable0 nextsibling badTag)} { list [catch {datatable0 nextsibling badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::datatable0}} test datatable.492 {datatable0 nextsibling -1)} { list [catch {datatable0 nextsibling -1} msg] $msg } {1 {can't find tag or id "-1" in ::datatable0}} test datatable.493 {datatable0 prevsibling 2)} { list [catch {datatable0 prevsibling 2} msg] $msg } {0 1} test datatable.494 {datatable0 prevsibling 1)} { list [catch {datatable0 prevsibling 1} msg] $msg } {0 -1} test datatable.495 {datatable0 prevsibling -1)} { list [catch {datatable0 prevsibling -1} msg] $msg } {1 {can't find tag or id "-1" in ::datatable0}} test datatable.496 {datatable0 root)} { list [catch {datatable0 root} msg] $msg } {0 0} test datatable.497 {datatable0 root badArg)} { list [catch {datatable0 root badArgs} msg] $msg } {1 {wrong # args: should be "datatable0 root "}} test datatable.498 {datatable0 parent (missing arg))} { list [catch {datatable0 parent} msg] $msg } {1 {wrong # args: should be "datatable0 parent node"}} test datatable.499 {datatable0 parent root)} { list [catch {datatable0 parent root} msg] $msg } {0 -1} test datatable.500 {datatable0 parent 1)} { list [catch {datatable0 parent 1} msg] $msg } {0 0} test datatable.501 {datatable0 parent myTag)} { list [catch {datatable0 parent myTag} msg] $msg } {0 0} test datatable.502 {datatable0 next (missing arg))} { list [catch {datatable0 next} msg] $msg } {1 {wrong # args: should be "datatable0 next node"}} test datatable.503 {datatable0 next (extra arg))} { list [catch {datatable0 next root root} msg] $msg } {1 {wrong # args: should be "datatable0 next node"}} test datatable.504 {datatable0 next root} { list [catch {datatable0 next root} msg] $msg } {0 1} test datatable.505 {datatable0 next 1)} { list [catch {datatable0 next 1} msg] $msg } {0 9} test datatable.506 {datatable0 next 2)} { list [catch {datatable0 next 2} msg] $msg } {0 3} test datatable.507 {datatable0 next 3)} { list [catch {datatable0 next 3} msg] $msg } {0 4} test datatable.508 {datatable0 next 4)} { list [catch {datatable0 next 4} msg] $msg } {0 5} test datatable.509 {datatable0 next 5)} { list [catch {datatable0 next 5} msg] $msg } {0 13} test datatable.510 {datatable0 next 6)} { list [catch {datatable0 next 6} msg] $msg } {0 8} test datatable.511 {datatable0 next 8)} { list [catch {datatable0 next 8} msg] $msg } {0 -1} test datatable.512 {datatable0 previous 1)} { list [catch {datatable0 previous 1} msg] $msg } {0 0} test datatable.513 {datatable0 previous 0)} { list [catch {datatable0 previous 0} msg] $msg } {0 -1} test datatable.514 {datatable0 previous 8)} { list [catch {datatable0 previous 8} msg] $msg } {0 6} test datatable.515 {datatable0 depth (no arg))} { list [catch {datatable0 depth} msg] $msg } {1 {wrong # args: should be "datatable0 depth node"}} test datatable.516 {datatable0 depth root))} { list [catch {datatable0 depth root} msg] $msg } {0 0} test datatable.517 {datatable0 depth myTag))} { list [catch {datatable0 depth myTag} msg] $msg } {0 1} test datatable.518 {datatable0 depth myTag))} { list [catch {datatable0 depth myTag} msg] $msg } {0 1} test datatable.519 {datatable0 dumpdata 1} { list [catch {datatable0 dumpdata 1} msg] $msg } {0 {-1 1 {node1} {} {} 1 9 {node1 node9} {} {thisTag} 1 11 {node1 node11} {key value} {} 1 12 {node1 node12} {key1 value1 key2 value2} {} }} test datatable.520 {datatable0 dumpdata this} { list [catch {datatable0 dumpdata myTag} msg] $msg } {0 {-1 5 {node5} {} {myTag} 5 13 {node5 node13} {} {} }} test datatable.521 {datatable0 dumpdata 1 badArg (too many args)} { list [catch {datatable0 dumpdata 1 badArg} msg] $msg } {1 {wrong # args: should be "datatable0 dumpdata node"}} test datatable.522 {datatable0 dumpdata 11} { list [catch {datatable0 dumpdata 11} msg] $msg } {0 {-1 11 {node11} {key value} {} }} test datatable.523 {datatable0 dumpdata all} { list [catch {datatable0 dumpdata all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.524 {datatable0 dumpdata all} { list [catch {datatable0 dumpdata all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.525 {datatable0 dumpfile 0 test.dump} { list [catch {datatable0 dumpfile 0 test.dump} msg] $msg } {0 {}} test datatable.526 {datatable0 get 9} { list [catch {datatable0 get 9} msg] $msg } {0 {}} test datatable.527 {datatable0 get all} { list [catch {datatable0 get all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.528 {datatable0 get root} { list [catch {datatable0 get root} msg] $msg } {0 {}} test datatable.529 {datatable0 get 9 key} { list [catch {datatable0 get root} msg] $msg } {0 {}} test datatable.530 {datatable0 get 12} { list [catch {datatable0 get 12} msg] $msg } {0 {key1 value1 key2 value2}} test datatable.531 {datatable0 get 12 key1} { list [catch {datatable0 get 12 key1} msg] $msg } {0 value1} test datatable.532 {datatable0 get 12 key2} { list [catch {datatable0 get 12 key2} msg] $msg } {0 value2} test datatable.533 {datatable0 get 12 key1 defValue } { list [catch {datatable0 get 12 key1 defValue} msg] $msg } {0 value1} test datatable.534 {datatable0 get 12 key100 defValue } { list [catch {datatable0 get 12 key100 defValue} msg] $msg } {0 defValue} test datatable.535 {datatable0 index (missing arg) } { list [catch {datatable0 index} msg] $msg } {1 {wrong # args: should be "datatable0 index name"}} test datatable.536 {datatable0 index 0 10 (extra arg) } { list [catch {datatable0 index 0 10} msg] $msg } {1 {wrong # args: should be "datatable0 index name"}} test datatable.537 {datatable0 index 0} { list [catch {datatable0 index 0} msg] $msg } {0 0} test datatable.538 {datatable0 index root} { list [catch {datatable0 index root} msg] $msg } {0 0} test datatable.539 {datatable0 index all} { list [catch {datatable0 index all} msg] $msg } {0 -1} test datatable.540 {datatable0 index myTag} { list [catch {datatable0 index myTag} msg] $msg } {0 5} test datatable.541 {datatable0 index thisTag} { list [catch {datatable0 index thisTag} msg] $msg } {0 -1} test datatable.542 {datatable0 is (no args)} { list [catch {datatable0 is} msg] $msg } {1 {wrong # args: should be one of... datatable0 is ancestor node1 node2 datatable0 is before node1 node2 datatable0 is leaf node datatable0 is link node datatable0 is root node}} test datatable.543 {datatable0 is badOp} { list [catch {datatable0 is badOp} msg] $msg } {1 {bad operation "badOp": should be one of... datatable0 is ancestor node1 node2 datatable0 is before node1 node2 datatable0 is leaf node datatable0 is link node datatable0 is root node}} test datatable.544 {datatable0 is before} { list [catch {datatable0 is before} msg] $msg } {1 {wrong # args: should be "datatable0 is before node1 node2"}} test datatable.545 {datatable0 is before 0 10 20} { list [catch {datatable0 is before 0 10 20} msg] $msg } {1 {wrong # args: should be "datatable0 is before node1 node2"}} test datatable.546 {datatable0 is before 0 12} { list [catch {datatable0 is before 0 12} msg] $msg } {0 1} test datatable.547 {datatable0 is before 12 0} { list [catch {datatable0 is before 12 0} msg] $msg } {0 0} test datatable.548 {datatable0 is before 0 0} { list [catch {datatable0 is before 0 0} msg] $msg } {0 0} test datatable.549 {datatable0 is before root 0} { list [catch {datatable0 is before root 0} msg] $msg } {0 0} test datatable.550 {datatable0 is before 0 all} { list [catch {datatable0 is before 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.551 {datatable0 is ancestor} { list [catch {datatable0 is ancestor} msg] $msg } {1 {wrong # args: should be "datatable0 is ancestor node1 node2"}} test datatable.552 {datatable0 is ancestor 0 12 20} { list [catch {datatable0 is ancestor 0 12 20} msg] $msg } {1 {wrong # args: should be "datatable0 is ancestor node1 node2"}} test datatable.553 {datatable0 is ancestor 0 12} { list [catch {datatable0 is ancestor 0 12} msg] $msg } {0 1} test datatable.554 {datatable0 is ancestor 12 0} { list [catch {datatable0 is ancestor 12 0} msg] $msg } {0 0} test datatable.555 {datatable0 is ancestor 1 2} { list [catch {datatable0 is ancestor 1 2} msg] $msg } {0 0} test datatable.556 {datatable0 is ancestor root 0} { list [catch {datatable0 is ancestor root 0} msg] $msg } {0 0} test datatable.557 {datatable0 is ancestor 0 all} { list [catch {datatable0 is ancestor 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.558 {datatable0 is root (missing arg)} { list [catch {datatable0 is root} msg] $msg } {1 {wrong # args: should be "datatable0 is root node"}} test datatable.559 {datatable0 is root 0 20 (extra arg)} { list [catch {datatable0 is root 0 20} msg] $msg } {1 {wrong # args: should be "datatable0 is root node"}} test datatable.560 {datatable0 is root 0} { list [catch {datatable0 is root 0} msg] $msg } {0 1} test datatable.561 {datatable0 is root 12} { list [catch {datatable0 is root 12} msg] $msg } {0 0} test datatable.562 {datatable0 is root 1} { list [catch {datatable0 is root 1} msg] $msg } {0 0} test datatable.563 {datatable0 is root root} { list [catch {datatable0 is root root} msg] $msg } {0 1} test datatable.564 {datatable0 is root all} { list [catch {datatable0 is root all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.565 {datatable0 is leaf (missing arg)} { list [catch {datatable0 is leaf} msg] $msg } {1 {wrong # args: should be "datatable0 is leaf node"}} test datatable.566 {datatable0 is leaf 0 20 (extra arg)} { list [catch {datatable0 is leaf 0 20} msg] $msg } {1 {wrong # args: should be "datatable0 is leaf node"}} test datatable.567 {datatable0 is leaf 0} { list [catch {datatable0 is leaf 0} msg] $msg } {0 0} test datatable.568 {datatable0 is leaf 12} { list [catch {datatable0 is leaf 12} msg] $msg } {0 1} test datatable.569 {datatable0 is leaf 1} { list [catch {datatable0 is leaf 1} msg] $msg } {0 0} test datatable.570 {datatable0 is leaf root} { list [catch {datatable0 is leaf root} msg] $msg } {0 0} test datatable.571 {datatable0 is leaf all} { list [catch {datatable0 is leaf all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.572 {datatable0 is leaf 1000} { list [catch {datatable0 is leaf 1000} msg] $msg } {1 {can't find tag or id "1000" in ::datatable0}} test datatable.573 {datatable0 is leaf badTag} { list [catch {datatable0 is leaf badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::datatable0}} test datatable.574 {datatable0 set (missing arg)} { list [catch {datatable0 set} msg] $msg } {1 {wrong # args: should be "datatable0 set node ?key value...?"}} test datatable.575 {datatable0 set 0 (missing arg)} { list [catch {datatable0 set 0} msg] $msg } {0 {}} test datatable.576 {datatable0 set 0 key (missing arg)} { list [catch {datatable0 set 0 key} msg] $msg } {1 {missing value for field "key"}} test datatable.577 {datatable0 set 0 key value} { list [catch {datatable0 set 0 key value} msg] $msg } {0 {}} test datatable.578 {datatable0 set 0 key1 value1 key2 value2 key3 value3} { list [catch {datatable0 set 0 key1 value1 key2 value2 key3 value3} msg] $msg } {0 {}} test datatable.579 {datatable0 set 0 key1 value1 key2 (missing arg)} { list [catch {datatable0 set 0 key1 value1 key2} msg] $msg } {1 {missing value for field "key2"}} test datatable.580 {datatable0 set 0 key value} { list [catch {datatable0 set 0 key value} msg] $msg } {0 {}} test datatable.581 {datatable0 set 0 key1 value1 key2 (missing arg)} { list [catch {datatable0 set 0 key1 value1 key2} msg] $msg } {1 {missing value for field "key2"}} test datatable.582 {datatable0 set all} { list [catch {datatable0 set all} msg] $msg } {0 {}} test datatable.583 {datatable0 set all abc 123} { list [catch {datatable0 set all abc 123} msg] $msg } {0 {}} test datatable.584 {datatable0 set root} { list [catch {datatable0 set root} msg] $msg } {0 {}} test datatable.585 {datatable0 restore stuff} { list [catch { set data [datatable0 dumpdata root] blt::datatable create datatable1 restore root $data set data [datatable1 dumpdata root] blt::datatable destroy datatable1 set data } msg] $msg } {0 {-1 0 {::datatable0} {key value key1 value1 key2 value2 key3 value3 abc 123} {} 0 1 {::datatable0 node1} {abc 123} {} 1 9 {::datatable0 node1 node9} {abc 123} {thisTag} 1 11 {::datatable0 node1 node11} {key value abc 123} {} 1 12 {::datatable0 node1 node12} {key1 value1 key2 value2 abc 123} {} 0 2 {::datatable0 node2} {abc 123} {} 0 3 {::datatable0 node3} {abc 123} {} 0 4 {::datatable0 node4} {abc 123} {} 0 5 {::datatable0 node5} {abc 123} {myTag} 5 13 {::datatable0 node5 node13} {abc 123} {} 0 6 {::datatable0 node6} {abc 123} {myTag2 myTag1} 0 8 {::datatable0 myLabel} {abc 123} {thisTag} }} test datatable.586 {datatable0 restorefile 0 test.dump} { list [catch { blt::datatable create datatable1 restorefile root test.dump set data [datatable1 dumpdata root] blt::datatable destroy datatable1 set data } msg] $msg } {0 {-1 0 {::datatable0} {} {} 0 1 {::datatable0 node1} {} {} 1 9 {::datatable0 node1 node9} {} {thisTag} 1 11 {::datatable0 node1 node11} {key value} {} 1 12 {::datatable0 node1 node12} {key1 value1 key2 value2} {} 0 2 {::datatable0 node2} {} {} 0 3 {::datatable0 node3} {} {} 0 4 {::datatable0 node4} {} {} 0 5 {::datatable0 node5} {} {myTag} 5 13 {::datatable0 node5 node13} {} {} 0 6 {::datatable0 node6} {} {myTag2 myTag1} 0 8 {::datatable0 myLabel} {} {thisTag} }} test datatable.587 {datatable0 unset 0 key1} { list [catch {datatable0 unset 0 key1} msg] $msg } {0 {}} test datatable.588 {datatable0 get 0} { list [catch {datatable0 get 0} msg] $msg } {0 {key value key2 value2 key3 value3 abc 123}} test datatable.589 {datatable0 unset 0 key2 key3} { list [catch {datatable0 unset 0 key2 key3} msg] $msg } {0 {}} test datatable.590 {datatable0 get 0} { list [catch {datatable0 get 0} msg] $msg } {0 {key value abc 123}} test datatable.591 {datatable0 unset 0} { list [catch {datatable0 unset 0} msg] $msg } {0 {}} test datatable.592 {datatable0 get 0} { list [catch {datatable0 get 0} msg] $msg } {0 {}} test datatable.593 {datatable0 unset all abc} { list [catch {datatable0 unset all abc} msg] $msg } {0 {}} test datatable.594 {datatable0 restore stuff} { list [catch { set data [datatable0 dumpdata root] blt::datatable create datatable1 datatable1 restore root $data set data [datatable1 dumpdata root] blt::datatable destroy datatable1 set data } msg] $msg } {0 {-1 0 {::datatable0} {} {} 0 1 {::datatable0 node1} {} {} 1 9 {::datatable0 node1 node9} {} {thisTag} 1 11 {::datatable0 node1 node11} {key value} {} 1 12 {::datatable0 node1 node12} {key1 value1 key2 value2} {} 0 2 {::datatable0 node2} {} {} 0 3 {::datatable0 node3} {} {} 0 4 {::datatable0 node4} {} {} 0 5 {::datatable0 node5} {} {myTag} 5 13 {::datatable0 node5 node13} {} {} 0 6 {::datatable0 node6} {} {myTag2 myTag1} 0 8 {::datatable0 myLabel} {} {thisTag} }} test datatable.595 {datatable0 restore (missing arg)} { list [catch {datatable0 restore} msg] $msg } {1 {wrong # args: should be "datatable0 restore node dataString ?switches?"}} test datatable.596 {datatable0 restore 0 badString} { list [catch {datatable0 restore 0 badString} msg] $msg } {1 {line #1: wrong # elements in restore entry}} test datatable.597 {datatable0 restore 0 {} arg (extra arg)} { list [catch {datatable0 restore 0 {} arg} msg] $msg } {1 {unknown option "arg"}} test datatable.598 {datatable0 size (missing arg)} { list [catch {datatable0 size} msg] $msg } {1 {wrong # args: should be "datatable0 size node"}} test datatable.599 {datatable0 size 0} { list [catch {datatable0 size 0} msg] $msg } {0 12} test datatable.600 {datatable0 size all} { list [catch {datatable0 size all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.601 {datatable0 size 0 10 (extra arg)} { list [catch {datatable0 size 0 10} msg] $msg } {1 {wrong # args: should be "datatable0 size node"}} test datatable.602 {datatable0 delete (missing arg)} { list [catch {datatable0 delete} msg] $msg } {1 {wrong # args: should be "datatable0 delete node ?node...?"}} test datatable.603 {datatable0 delete 11} { list [catch {datatable0 delete 11} msg] $msg } {0 {}} test datatable.604 {datatable0 delete 11} { list [catch {datatable0 delete 11} msg] $msg } {1 {can't find tag or id "11" in ::datatable0}} test datatable.605 {datatable0 delete 9 12} { list [catch {datatable0 delete 9 12} msg] $msg } {0 {}} test datatable.606 {datatable0 dumpdata 0} { list [catch {datatable0 dump 0} msg] $msg } {0 {-1 0 {::datatable0} {} {} 0 1 {::datatable0 node1} {} {} 0 2 {::datatable0 node2} {} {} 0 3 {::datatable0 node3} {} {} 0 4 {::datatable0 node4} {} {} 0 5 {::datatable0 node5} {} {myTag} 5 13 {::datatable0 node5 node13} {} {} 0 6 {::datatable0 node6} {} {myTag2 myTag1} 0 8 {::datatable0 myLabel} {} {thisTag} }} test datatable.607 {delete all} { list [catch { set data [datatable0 dump root] blt::datatable create datatable1 restore root $data datatable1 delete all set data [datatable1 dump root] blt::datatable destroy datatable1 set data } msg] $msg } {0 {-1 0 {::datatable0} {} {} }} test datatable.608 {delete all all} { list [catch { set data [datatable0 dump root] blt::datatable create datatable1 restore root $data datatable1 delete all all set data [datatable1 dump root] blt::datatable destroy datatable1 set data } msg] $msg } {0 {-1 0 {::datatable0} {} {} }} test datatable.609 {datatable0 apply (missing arg)} { list [catch {datatable0 apply} msg] $msg } {1 {wrong # args: should be "datatable0 apply node ?switches?"}} test datatable.610 {datatable0 apply 0} { list [catch {datatable0 apply 0} msg] $msg } {0 {}} test datatable.611 {datatable0 apply 0 -badOption} { list [catch {datatable0 apply 0 -badOption} msg] $msg } {1 {unknown option "-badOption"}} test datatable.612 {datatable0 apply badTag} { list [catch {datatable0 apply badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::datatable0}} test datatable.613 {datatable0 apply all} { list [catch {datatable0 apply all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.614 {datatable0 apply myTag -precommand lappend} { list [catch { set mylist {} datatable0 apply myTag -precommand {lappend mylist} set mylist } msg] $msg } {0 {5 13}} test datatable.615 {datatable0 apply root -precommand lappend} { list [catch { set mylist {} datatable0 apply root -precommand {lappend mylist} set mylist } msg] $msg } {0 {0 1 2 3 4 5 13 6 8}} test datatable.616 {datatable0 apply -precommand -postcommand} { list [catch { set mylist {} datatable0 apply root -precommand {lappend mylist} \ -postcommand {lappend mylist} set mylist } msg] $msg } {0 {0 1 1 2 2 3 3 4 4 5 13 13 5 6 6 8 8 0}} test datatable.617 {datatable0 apply root -precommand lappend -depth 1} { list [catch { set mylist {} datatable0 apply root -precommand {lappend mylist} -depth 1 set mylist } msg] $msg } {0 {0 1 2 3 4 5 6 8}} test datatable.618 {datatable0 apply root -precommand -depth 0} { list [catch { set mylist {} datatable0 apply root -precommand {lappend mylist} -depth 0 set mylist } msg] $msg } {0 0} test datatable.619 {datatable0 apply root -precommand -tag myTag} { list [catch { set mylist {} datatable0 apply root -precommand {lappend mylist} -tag myTag set mylist } msg] $msg } {0 5} test datatable.620 {datatable0 apply root -precommand -key key1} { list [catch { set mylist {} datatable0 set myTag key1 0.0 datatable0 apply root -precommand {lappend mylist} -key key1 datatable0 unset myTag key1 set mylist } msg] $msg } {0 5} test datatable.621 {datatable0 apply root -postcommand -regexp node.*} { list [catch { set mylist {} datatable0 set myTag key1 0.0 datatable0 apply root -precommand {lappend mylist} -regexp {node5} datatable0 unset myTag key1 set mylist } msg] $msg } {0 5} test datatable.622 {datatable0 find (missing arg)} { list [catch {datatable0 find} msg] $msg } {1 {wrong # args: should be "datatable0 find node ?switches?"}} test datatable.623 {datatable0 find 0} { list [catch {datatable0 find 0} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.624 {datatable0 find root} { list [catch {datatable0 find root} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.625 {datatable0 find 0 -glob node*} { list [catch {datatable0 find root -glob node*} msg] $msg } {0 {1 2 3 4 13 5 6}} test datatable.626 {datatable0 find 0 -glob nobody} { list [catch {datatable0 find root -glob nobody} msg] $msg } {0 {}} test datatable.627 {datatable0 find 0 -regexp {node[0-3]}} { list [catch {datatable0 find root -regexp {node[0-3]}} msg] $msg } {0 {1 2 3 13}} test datatable.628 {datatable0 find 0 -regexp {.*[A-Z].*}} { list [catch {datatable0 find root -regexp {.*[A-Z].*}} msg] $msg } {0 8} test datatable.629 {datatable0 find 0 -exact myLabel} { list [catch {datatable0 find root -exact myLabel} msg] $msg } {0 8} test datatable.630 {datatable0 find 0 -exact myLabel -invert} { list [catch {datatable0 find root -exact myLabel -invert} msg] $msg } {0 {1 2 3 4 13 5 6 0}} test datatable.631 {datatable0 find 3 -exact node3} { list [catch {datatable0 find 3 -exact node3} msg] $msg } {0 3} test datatable.632 {datatable0 find 0 -nocase -exact mylabel} { list [catch {datatable0 find 0 -nocase -exact mylabel} msg] $msg } {0 8} test datatable.633 {datatable0 find 0 -nocase} { list [catch {datatable0 find 0 -nocase} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.634 {datatable0 find 0 -path -nocase -glob *node1* } { list [catch {datatable0 find 0 -path -nocase -glob *node1*} msg] $msg } {0 {1 13}} test datatable.635 {datatable0 find 0 -count 5 } { list [catch {datatable0 find 0 -count 5} msg] $msg } {0 {1 2 3 4 13}} test datatable.636 {datatable0 find 0 -count -5 } { list [catch {datatable0 find 0 -count -5} msg] $msg } {1 {bad value "-5": can't be negative}} test datatable.637 {datatable0 find 0 -count badValue } { list [catch {datatable0 find 0 -count badValue} msg] $msg } {1 {expected integer but got "badValue"}} test datatable.638 {datatable0 find 0 -count badValue } { list [catch {datatable0 find 0 -count badValue} msg] $msg } {1 {expected integer but got "badValue"}} test datatable.639 {datatable0 find 0 -leafonly} { list [catch {datatable0 find 0 -leafonly} msg] $msg } {0 {1 2 3 4 13 6 8}} test datatable.640 {datatable0 find 0 -leafonly -glob {node[18]}} { list [catch {datatable0 find 0 -glob {node[18]} -leafonly} msg] $msg } {0 1} test datatable.641 {datatable0 find 0 -depth 0} { list [catch {datatable0 find 0 -depth 0} msg] $msg } {0 0} test datatable.642 {datatable0 find 0 -depth 1} { list [catch {datatable0 find 0 -depth 1} msg] $msg } {0 {1 2 3 4 5 6 8 0}} test datatable.643 {datatable0 find 0 -depth 2} { list [catch {datatable0 find 0 -depth 2} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.644 {datatable0 find 0 -depth 20} { list [catch {datatable0 find 0 -depth 20} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.645 {datatable0 find 1 -depth 0} { list [catch {datatable0 find 1 -depth 0} msg] $msg } {0 1} test datatable.646 {datatable0 find 1 -depth 1} { list [catch {datatable0 find 1 -depth 1} msg] $msg } {0 1} test datatable.647 {datatable0 find 1 -depth 2} { list [catch {datatable0 find 1 -depth 2} msg] $msg } {0 1} test datatable.648 {datatable0 find all} { list [catch {datatable0 find all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.649 {datatable0 find badTag} { list [catch {datatable0 find badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::datatable0}} test datatable.650 {datatable0 find 0 -addtag hi} { list [catch {datatable0 find 0 -addtag hi} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.651 {datatable0 find 0 -addtag all} { list [catch {datatable0 find 0 -addtag all} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test datatable.652 {datatable0 find 0 -addtag root} { list [catch {datatable0 find 0 -addtag root} msg] $msg } {1 {can't add reserved tag "root"}} test datatable.653 {datatable0 find 0 -exec {lappend list} -leafonly} { list [catch { set list {} datatable0 find 0 -exec {lappend list} -leafonly set list } msg] $msg } {0 {1 2 3 4 13 6 8}} test datatable.654 {datatable0 find 0 -tag root} { list [catch {datatable0 find 0 -tag root} msg] $msg } {0 0} test datatable.655 {datatable0 find 0 -tag myTag} { list [catch {datatable0 find 0 -tag myTag} msg] $msg } {0 5} test datatable.656 {datatable0 find 0 -tag badTag} { list [catch {datatable0 find 0 -tag badTag} msg] $msg } {0 {}} test datatable.657 {datatable0 tag (missing args)} { list [catch {datatable0 tag} msg] $msg } {1 {wrong # args: should be "datatable0 tag args"}} test datatable.658 {datatable0 tag badOp} { list [catch {datatable0 tag badOp} msg] $msg } {1 {bad operation "badOp": should be one of... datatable0 tag add tag node... datatable0 tag delete tag node... datatable0 tag dump tag... datatable0 tag exists node tag... datatable0 tag forget tag... datatable0 tag get node ?pattern...? datatable0 tag names ?node...? datatable0 tag nodes tag ?tag...? datatable0 tag set node tag... datatable0 tag unset node tag...}} test datatable.659 {datatable0 tag add} { list [catch {datatable0 tag add} msg] $msg } {1 {wrong # args: should be "datatable0 tag add tag node..."}} test datatable.660 {datatable0 tag add tag} { list [catch {datatable0 tag add tag} msg] $msg } {1 {wrong # args: should be "datatable0 tag add tag node..."}} test datatable.661 {datatable0 tag add tag badNode} { list [catch {datatable0 tag add tag badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::datatable0}} test datatable.662 {datatable0 tag add newTag root} { list [catch {datatable0 tag add newTag root} msg] $msg } {0 {}} test datatable.663 {datatable0 tag add newTag all} { list [catch {datatable0 tag add newTag all} msg] $msg } {0 {}} test datatable.664 {datatable0 tag add tag2 0 1 2 3 4} { list [catch {datatable0 tag add tag2 0 1 2 3 4} msg] $msg } {0 {}} test datatable.665 {datatable0 tag add tag2 0 1 2 3 4 1000} { list [catch {datatable0 tag add tag2 0 1 2 3 4 1000} msg] $msg } {1 {can't find tag or id "1000" in ::datatable0}} test datatable.666 {datatable0 tag names} { list [catch {datatable0 tag names} msg] $msg } {0 {all hi myTag myTag1 myTag2 newTag root tag2 thisTag}} test datatable.667 {datatable0 tag names badNode} { list [catch {datatable0 tag names badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::datatable0}} test datatable.668 {datatable0 tag names all} { list [catch {datatable0 tag names all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.669 {datatable0 tag names root} { list [catch {datatable0 tag names root} msg] $msg } {0 {all hi newTag root tag2}} test datatable.670 {datatable0 tag names 0 1} { list [catch {datatable0 tag names 0 1} msg] $msg } {0 {all hi newTag root tag2}} test datatable.671 {datatable0 tag nodes (missing arg)} { list [catch {datatable0 tag nodes} msg] $msg } {1 {wrong # args: should be "datatable0 tag nodes tag ?tag...?"}} test datatable.672 {datatable0 tag nodes root badTag} { list [catch {datatable0 tag nodes root badTag} msg] $msg } {1 {can't find a tag "badTag"}} test datatable.673 {datatable0 tag nodes root tag2} { list [catch {datatable0 tag nodes root tag2} msg] $msg } {0 {0 1 2 3 4}} test datatable.674 {datatable0 ancestor (missing arg)} { list [catch {datatable0 ancestor} msg] $msg } {1 {wrong # args: should be "datatable0 ancestor node1 node2"}} test datatable.675 {datatable0 ancestor 0 (missing arg)} { list [catch {datatable0 ancestor 0} msg] $msg } {1 {wrong # args: should be "datatable0 ancestor node1 node2"}} test datatable.676 {datatable0 ancestor 0 10} { list [catch {datatable0 ancestor 0 10} msg] $msg } {1 {can't find tag or id "10" in ::datatable0}} test datatable.677 {datatable0 ancestor 0 4} { list [catch {datatable0 ancestor 0 4} msg] $msg } {0 0} test datatable.678 {datatable0 ancestor 1 8} { list [catch {datatable0 ancestor 1 8} msg] $msg } {0 0} test datatable.679 {datatable0 ancestor root 0} { list [catch {datatable0 ancestor root 0} msg] $msg } {0 0} test datatable.680 {datatable0 ancestor 8 8} { list [catch {datatable0 ancestor 8 8} msg] $msg } {0 8} test datatable.681 {datatable0 ancestor 0 all} { list [catch {datatable0 ancestor 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.682 {datatable0 ancestor 7 9} { list [catch { set n1 1; set n2 1; for { set i 0 } { $i < 4 } { incr i } { set n1 [datatable0 insert $n1] set n2 [datatable0 insert $n2] } datatable0 ancestor $n1 $n2 } msg] $msg } {0 1} test datatable.683 {datatable0 path (missing arg)} { list [catch {datatable0 path} msg] $msg } {1 {wrong # args: should be "datatable0 path node"}} test datatable.684 {datatable0 path root} { list [catch {datatable0 path root} msg] $msg } {0 {}} test datatable.685 {datatable0 path 0} { list [catch {datatable0 path 0} msg] $msg } {0 {}} test datatable.686 {datatable0 path 15} { list [catch {datatable0 path 15} msg] $msg } {0 {node1 node15}} test datatable.687 {datatable0 path all} { list [catch {datatable0 path all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.688 {datatable0 path 0 1 2 4 (extra args)} { list [catch {datatable0 path 0 1 2 4} msg] $msg } {1 {wrong # args: should be "datatable0 path node"}} test datatable.689 {datatable0 tag forget} { list [catch {datatable0 tag forget} msg] $msg } {1 {wrong # args: should be "datatable0 tag forget tag..."}} test datatable.690 {datatable0 tag forget badTag} { list [catch { datatable0 tag forget badTag lsort [datatable0 tag names] } msg] $msg } {0 {all hi myTag myTag1 myTag2 newTag root tag2 thisTag}} test datatable.691 {datatable0 tag forget hi} { list [catch { datatable0 tag forget hi lsort [datatable0 tag names] } msg] $msg } {0 {all myTag myTag1 myTag2 newTag root tag2 thisTag}} test datatable.692 {datatable0 tag forget tag1 tag2} { list [catch { datatable0 tag forget myTag1 myTag2 lsort [datatable0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test datatable.693 {datatable0 tag forget all} { list [catch { datatable0 tag forget all lsort [datatable0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test datatable.694 {datatable0 tag forget root} { list [catch { datatable0 tag forget root lsort [datatable0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test datatable.695 {datatable0 tag delete} { list [catch {datatable0 tag delete} msg] $msg } {1 {wrong # args: should be "datatable0 tag delete tag node..."}} test datatable.696 {datatable0 tag delete tag} { list [catch {datatable0 tag delete tag} msg] $msg } {1 {wrong # args: should be "datatable0 tag delete tag node..."}} test datatable.697 {datatable0 tag delete tag 0} { list [catch {datatable0 tag delete tag 0} msg] $msg } {0 {}} test datatable.698 {datatable0 tag delete root 0} { list [catch {datatable0 tag delete root 0} msg] $msg } {1 {can't delete reserved tag "root"}} test datatable.699 {datatable0 attach} { list [catch {datatable0 attach} msg] $msg } {0 ::datatable0} test datatable.700 {datatable0 attach datatable2 datatable3} { list [catch {datatable0 attach datatable2 datatable3} msg] $msg } {1 {wrong # args: should be "datatable0 attach ?datatable?"}} test datatable.701 {datatable1 attach datatable0} { list [catch { blt::datatable create datatable1 attach datatable0 datatable1 dump 0 } msg] $msg } {0 {-1 0 {::datatable0} {} {} 0 2 {::datatable0 node2} {} {} 2 1 {::datatable0 node2 node1} {} {} 1 14 {::datatable0 node2 node1 node14} {} {} 14 16 {::datatable0 node2 node1 node14 node16} {} {} 16 18 {::datatable0 node2 node1 node14 node16 node18} {} {} 18 20 {::datatable0 node2 node1 node14 node16 node18 node20} {} {} 1 15 {::datatable0 node2 node1 node15} {} {} 15 17 {::datatable0 node2 node1 node15 node17} {} {} 17 19 {::datatable0 node2 node1 node15 node17 node19} {} {} 19 21 {::datatable0 node2 node1 node15 node17 node19 node21} {} {} 0 3 {::datatable0 node3} {} {} 0 4 {::datatable0 node4} {} {} 0 5 {::datatable0 node5} {} {} 5 13 {::datatable0 node5 node13} {} {} 0 6 {::datatable0 node6} {} {} 0 8 {::datatable0 myLabel} {} {} }} test datatable.702 {datatable1 attach} { list [catch {datatable1 attach} msg] $msg } {0 ::datatable0} test datatable.703 {blt::datatable destroy datatable1} { list [catch {blt::datatable destroy datatable1} msg] $msg } {0 {}} test datatable.704 {datatable0 find root -badFlag} { list [catch {datatable0 find root -badFlag} msg] $msg } {1 {unknown option "-badFlag"}} test datatable.705 {datatable0 find root -order} { list [catch {datatable0 find root -order} msg] $msg } {1 {value for "-order" missing}} test datatable.706 {datatable0 find root ...} { list [catch {datatable0 find root -order preorder -order postorder -order inorder} msg] $msg } {0 {20 18 16 14 1 21 19 17 15 2 0 3 4 13 5 6 8}} test datatable.707 {datatable0 find root -order preorder} { list [catch {datatable0 find root -order preorder} msg] $msg } {0 {0 2 1 14 16 18 20 15 17 19 21 3 4 5 13 6 8}} test datatable.708 {datatable0 find root -order postorder} { list [catch {datatable0 find root -order postorder} msg] $msg } {0 {20 18 16 14 21 19 17 15 1 2 3 4 13 5 6 8 0}} test datatable.709 {datatable0 find root -order inorder} { list [catch {datatable0 find root -order inorder} msg] $msg } {0 {20 18 16 14 1 21 19 17 15 2 0 3 4 13 5 6 8}} test datatable.710 {datatable0 find root -order breadthfirst} { list [catch {datatable0 find root -order breadthfirst} msg] $msg } {0 {0 2 3 4 5 6 8 1 13 14 15 16 17 18 19 20 21}} test datatable.711 {datatable0 set all key1 myValue} { list [catch {datatable0 set all key1 myValue} msg] $msg } {0 {}} test datatable.712 {datatable0 set 15 key1 123} { list [catch {datatable0 set 15 key1 123} msg] $msg } {0 {}} test datatable.713 {datatable0 set 16 key1 1234 key2 abc} { list [catch {datatable0 set 16 key1 123 key2 abc} msg] $msg } {0 {}} test datatable.714 {datatable0 find root -key } { list [catch {datatable0 find root -key} msg] $msg } {1 {value for "-key" missing}} test datatable.715 {datatable0 find root -key noKey} { list [catch {datatable0 find root -key noKey} msg] $msg } {0 {}} test datatable.716 {datatable0 find root -key key1} { list [catch {datatable0 find root -key key1} msg] $msg } {0 {20 18 16 14 21 19 17 15 1 2 3 4 13 5 6 8 0}} test datatable.717 {datatable0 find root -key key2} { list [catch {datatable0 find root -key key2} msg] $msg } {0 16} test datatable.718 {datatable0 find root -key key2 -exact notThere } { list [catch {datatable0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test datatable.719 {datatable0 find root -key key1 -glob notThere } { list [catch {datatable0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test datatable.720 {datatable0 find root -key badKey -regexp notThere } { list [catch {datatable0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test datatable.721 {datatable0 find root -key key1 -glob 12*} { list [catch {datatable0 find root -key key1 -glob 12*} msg] $msg } {0 {16 15}} test datatable.722 {datatable0 sort} { list [catch {datatable0 sort} msg] $msg } {1 {wrong # args: should be "datatable0 sort node ?flags...?"}} test datatable.723 {datatable0 sort all} { list [catch {datatable0 sort all} msg] $msg } {1 {more than one node tagged as "all"}} test datatable.724 {datatable0 sort -recurse} { list [catch {datatable0 sort -recurse} msg] $msg } {1 {can't find tag or id "-recurse" in ::datatable0}} test datatable.725 {datatable0 sort 0} { list [catch {datatable0 sort 0} msg] $msg } {0 {8 2 3 4 5 6}} test datatable.726 {datatable0 sort 0 -recurse} { list [catch {datatable0 sort 0 -recurse} msg] $msg } {0 {0 8 1 2 3 4 5 6 13 14 15 16 17 18 19 20 21}} test datatable.727 {datatable0 sort 0 -decreasing -key} { list [catch {datatable0 sort 0 -decreasing -key} msg] $msg } {1 {value for "-key" missing}} test datatable.728 {datatable0 sort 0 -re} { list [catch {datatable0 sort 0 -re} msg] $msg } {1 {ambiguous option "-re"}} test datatable.729 {datatable0 sort 0 -decreasing} { list [catch {datatable0 sort 0 -decreasing} msg] $msg } {0 {6 5 4 3 2 8}} test datatable.730 {datatable0 sort 0} { list [catch { set list {} foreach n [datatable0 sort 0] { lappend list [datatable0 label $n] } set list } msg] $msg } {0 {myLabel node2 node3 node4 node5 node6}} test datatable.731 {datatable0 sort 0 -decreasing} { list [catch {datatable0 sort 0 -decreasing} msg] $msg } {0 {6 5 4 3 2 8}} test datatable.732 {datatable0 sort 0 -decreasing -key} { list [catch {datatable0 sort 0 -decreasing -key} msg] $msg } {1 {value for "-key" missing}} test datatable.733 {datatable0 sort 0 -decreasing -key key1} { list [catch {datatable0 sort 0 -decreasing -key key1} msg] $msg } {0 {8 6 5 4 3 2}} test datatable.734 {datatable0 sort 0 -decreasing -recurse -key key1} { list [catch {datatable0 sort 0 -decreasing -recurse -key key1} msg] $msg } {0 {15 16 0 1 2 3 4 5 6 8 13 14 17 18 19 20 21}} test datatable.735 {datatable0 sort 0 -decreasing -key key1} { list [catch { set list {} foreach n [datatable0 sort 0 -decreasing -key key1] { lappend list [datatable0 get $n key1] } set list } msg] $msg } {0 {myValue myValue myValue myValue myValue myValue}} test datatable.736 {datatable0 index 1-firstchild} { list [catch {datatable0 index 1-firstchild} msg] $msg } {0 14} test datatable.737 {datatable0 index root-to-firstchild} { list [catch {datatable0 index root-to-firstchild} msg] $msg } {0 2} test datatable.738 {datatable0 label root-to-parent} { list [catch {datatable0 label root-to-parent} msg] $msg } {1 {can't find tag or id "root-to-parent" in ::datatable0}} test datatable.739 {datatable0 index root-to-parent} { list [catch {datatable0 index root-to-parent} msg] $msg } {0 -1} test datatable.740 {datatable0 index root-to-lastchild} { list [catch {datatable0 index root-to-lastchild} msg] $msg } {0 8} test datatable.741 {datatable0 index root-to-next} { list [catch {datatable0 index root-to-next} msg] $msg } {0 2} test datatable.742 {datatable0 index root-to-previous} { list [catch {datatable0 index root-to-previous} msg] $msg } {0 -1} test datatable.743 {datatable0 label root-to-previous} { list [catch {datatable0 label root-to-previous} msg] $msg } {1 {can't find tag or id "root-to-previous" in ::datatable0}} test datatable.744 {datatable0 index 1-previous} { list [catch {datatable0 index 1-previous} msg] $msg } {0 2} test datatable.745 {datatable0 label root-to-badModifier} { list [catch {datatable0 label root-to-badModifier} msg] $msg } {1 {can't find tag or id "root-to-badModifier" in ::datatable0}} test datatable.746 {datatable0 index root-to-badModifier} { list [catch {datatable0 index root-to-badModifier} msg] $msg } {0 -1} test datatable.747 {datatable0 index root-to-firstchild-to-parent} { list [catch {datatable0 index root-to-firstchild-to-parent} msg] $msg } {0 0} test datatable.748 {datatable0 trace} { list [catch {datatable0 trace} msg] $msg } {1 {wrong # args: should be one of... datatable0 trace create node key how command datatable0 trace delete id... datatable0 trace info id datatable0 trace names }} test datatable.749 {datatable0 trace create} { list [catch {datatable0 trace create} msg] $msg } {1 {wrong # args: should be "datatable0 trace create node key how command"}} test datatable.750 {datatable0 trace create root} { list [catch {datatable0 trace create root} msg] $msg } {1 {wrong # args: should be "datatable0 trace create node key how command"}} test datatable.751 {datatable0 trace create root * } { list [catch {datatable0 trace create root * } msg] $msg } {1 {wrong # args: should be "datatable0 trace create node key how command"}} test datatable.752 {datatable0 trace create root * rwuc} { list [catch {datatable0 trace create root * rwuc} msg] $msg } {1 {wrong # args: should be "datatable0 trace create node key how command"}} proc Doit args { global mylist; lappend mylist $args } test datatable.753 {datatable0 trace create all newKey rwuc Doit} { list [catch {datatable0 trace create all newKey rwuc Doit} msg] $msg } {0 trace0} test datatable.754 {datatable0 trace info trace0} { list [catch {datatable0 trace info trace0} msg] $msg } {0 {all newKey {} Doit}} test datatable.755 {test create trace} { list [catch { set mylist {} datatable0 set all newKey 20 set mylist } msg] $msg } {0 {{::datatable0 0 newKey wc} {::datatable0 2 newKey wc} {::datatable0 1 newKey wc} {::datatable0 14 newKey wc} {::datatable0 16 newKey wc} {::datatable0 18 newKey wc} {::datatable0 20 newKey wc} {::datatable0 15 newKey wc} {::datatable0 17 newKey wc} {::datatable0 19 newKey wc} {::datatable0 21 newKey wc} {::datatable0 3 newKey wc} {::datatable0 4 newKey wc} {::datatable0 5 newKey wc} {::datatable0 13 newKey wc} {::datatable0 6 newKey wc} {::datatable0 8 newKey wc}}} test datatable.756 {test read trace} { list [catch { set mylist {} datatable0 get root newKey set mylist } msg] $msg } {0 {{::datatable0 0 newKey r}}} test datatable.757 {test write trace} { list [catch { set mylist {} datatable0 set all newKey 21 set mylist } msg] $msg } {0 {{::datatable0 0 newKey w} {::datatable0 2 newKey w} {::datatable0 1 newKey w} {::datatable0 14 newKey w} {::datatable0 16 newKey w} {::datatable0 18 newKey w} {::datatable0 20 newKey w} {::datatable0 15 newKey w} {::datatable0 17 newKey w} {::datatable0 19 newKey w} {::datatable0 21 newKey w} {::datatable0 3 newKey w} {::datatable0 4 newKey w} {::datatable0 5 newKey w} {::datatable0 13 newKey w} {::datatable0 6 newKey w} {::datatable0 8 newKey w}}} test datatable.758 {test unset trace} { list [catch { set mylist {} datatable0 set all newKey 21 set mylist } msg] $msg } {0 {{::datatable0 0 newKey w} {::datatable0 2 newKey w} {::datatable0 1 newKey w} {::datatable0 14 newKey w} {::datatable0 16 newKey w} {::datatable0 18 newKey w} {::datatable0 20 newKey w} {::datatable0 15 newKey w} {::datatable0 17 newKey w} {::datatable0 19 newKey w} {::datatable0 21 newKey w} {::datatable0 3 newKey w} {::datatable0 4 newKey w} {::datatable0 5 newKey w} {::datatable0 13 newKey w} {::datatable0 6 newKey w} {::datatable0 8 newKey w}}} test datatable.759 {datatable0 trace delete} { list [catch {datatable0 trace delete} msg] $msg } {0 {}} test datatable.760 {datatable0 trace delete badId} { list [catch {datatable0 trace delete badId} msg] $msg } {1 {unknown trace "badId"}} test datatable.761 {datatable0 trace delete trace0} { list [catch {datatable0 trace delete trace0} msg] $msg } {0 {}} test datatable.762 {test create trace} { list [catch { set mylist {} datatable0 set all newKey 20 set mylist } msg] $msg } {0 {}} test datatable.763 {test unset trace} { list [catch { set mylist {} datatable0 unset all newKey set mylist } msg] $msg } {0 {}} test datatable.764 {datatable0 notify} { list [catch {datatable0 notify} msg] $msg } {1 {wrong # args: should be one of... datatable0 notify create ?flags? command datatable0 notify delete notifyId... datatable0 notify info notifyId datatable0 notify names }} test datatable.765 {datatable0 notify create} { list [catch {datatable0 notify create} msg] $msg } {1 {wrong # args: should be "datatable0 notify create ?flags? command"}} test datatable.766 {datatable0 notify create -allevents} { list [catch {datatable0 notify create -allevents Doit} msg] $msg } {0 notify0} test datatable.767 {datatable0 notify info notify0} { list [catch {datatable0 notify info notify0} msg] $msg } {0 {notify0 {-create -delete -move -sort -relabel} {Doit}}} test datatable.768 {datatable0 notify info badId} { list [catch {datatable0 notify info badId} msg] $msg } {1 {unknown notify name "badId"}} test datatable.769 {datatable0 notify info} { list [catch {datatable0 notify info} msg] $msg } {1 {wrong # args: should be "datatable0 notify info notifyId"}} test datatable.770 {datatable0 notify names} { list [catch {datatable0 notify names} msg] $msg } {0 notify0} test datatable.771 {test create notify} { list [catch { set mylist {} datatable0 insert 1 -tags test set mylist } msg] $msg } {0 {{-create 22}}} test datatable.772 {test move notify} { list [catch { set mylist {} datatable0 move 8 test set mylist } msg] $msg } {0 {{-move 8}}} test datatable.773 {test sort notify} { list [catch { set mylist {} datatable0 sort 0 -reorder set mylist } msg] $msg } {0 {{-sort 0}}} test datatable.774 {test relabel notify} { list [catch { set mylist {} datatable0 label test "newLabel" set mylist } msg] $msg } {0 {{-relabel 22}}} test datatable.775 {test delete notify} { list [catch { set mylist {} datatable0 delete test set mylist } msg] $msg } {0 {{-delete 8} {-delete 22}}} test datatable.776 {datatable0 notify delete badId} { list [catch {datatable0 notify delete badId} msg] $msg } {1 {unknown notify name "badId"}} test datatable.777 {test create notify} { list [catch { set mylist {} datatable0 set all newKey 20 set mylist } msg] $msg } {0 {}} test datatable.778 {test delete notify} { list [catch { set mylist {} datatable0 unset all newKey set mylist } msg] $msg } {0 {}} test datatable.779 {test delete notify} { list [catch { set mylist {} datatable0 unset all newKey set mylist } msg] $msg } {0 {}} test datatable.780 {datatable0 copy} { list [catch {datatable0 copy} msg] $msg } {1 {wrong # args: should be "datatable0 copy srcNode ?destDatatable? destNode ?switches?"}} test datatable.781 {datatable0 copy root} { list [catch {datatable0 copy root} msg] $msg } {1 {wrong # args: should be "datatable0 copy srcNode ?destDatatable? destNode ?switches?"}} test datatable.782 {datatable0 copy root 14} { list [catch {datatable0 copy root 14} msg] $msg } {0 23} test datatable.783 {datatable0 copy 14 root} { list [catch {datatable0 copy 14 root} msg] $msg } {0 24} test datatable.784 {datatable0 copy root 14 -recurse} { list [catch {datatable0 copy root 14 -recurse} msg] $msg } {1 {can't make cyclic copy: source node is an ancestor of the destination}} test datatable.785 {datatable0 copy 2 3 -recurse -tags} { list [catch {datatable0 copy 2 3 -recurse -tags} msg] $msg } {0 25} test datatable.786 {datatable0 copy 2 3 -recurse -overwrite} { list [catch { blt::datatable create datatable1 foreach node [datatable0 children root] { datatable0 copy $node datatable1 root -recurse } foreach node [datatable0 children root] { datatable0 copy $node datatable1 root -recurse } datatable1 dump root } msg] $msg } {0 {-1 0 {::datatable1} {} {} 0 1 {::datatable1 node2} {key1 myValue} {} 1 2 {::datatable1 node2 node1} {key1 myValue} {} 2 3 {::datatable1 node2 node1 node14} {key1 myValue} {} 3 4 {::datatable1 node2 node1 node14 node16} {key1 123 key2 abc} {} 4 5 {::datatable1 node2 node1 node14 node16 node18} {key1 myValue} {} 5 6 {::datatable1 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 3 7 {::datatable1 node2 node1 node14 ::datatable0} {key1 myValue} {} 2 8 {::datatable1 node2 node1 node15} {key1 123} {} 8 9 {::datatable1 node2 node1 node15 node17} {key1 myValue} {} 9 10 {::datatable1 node2 node1 node15 node17 node19} {key1 myValue} {} 10 11 {::datatable1 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 12 {::datatable1 node3} {key1 myValue} {} 12 13 {::datatable1 node3 node2} {key1 myValue} {} 13 14 {::datatable1 node3 node2 node1} {key1 myValue} {} 14 15 {::datatable1 node3 node2 node1 node14} {key1 myValue} {} 15 16 {::datatable1 node3 node2 node1 node14 node16} {key1 123 key2 abc} {} 16 17 {::datatable1 node3 node2 node1 node14 node16 node18} {key1 myValue} {} 17 18 {::datatable1 node3 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 15 19 {::datatable1 node3 node2 node1 node14 ::datatable0} {key1 myValue} {} 14 20 {::datatable1 node3 node2 node1 node15} {key1 123} {} 20 21 {::datatable1 node3 node2 node1 node15 node17} {key1 myValue} {} 21 22 {::datatable1 node3 node2 node1 node15 node17 node19} {key1 myValue} {} 22 23 {::datatable1 node3 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 24 {::datatable1 node4} {key1 myValue} {} 0 25 {::datatable1 node5} {key1 myValue} {} 25 26 {::datatable1 node5 node13} {key1 myValue} {} 0 27 {::datatable1 node6} {key1 myValue} {} 0 28 {::datatable1 node14} {key1 myValue} {} 0 29 {::datatable1 node2} {key1 myValue} {} 29 30 {::datatable1 node2 node1} {key1 myValue} {} 30 31 {::datatable1 node2 node1 node14} {key1 myValue} {} 31 32 {::datatable1 node2 node1 node14 node16} {key1 123 key2 abc} {} 32 33 {::datatable1 node2 node1 node14 node16 node18} {key1 myValue} {} 33 34 {::datatable1 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 31 35 {::datatable1 node2 node1 node14 ::datatable0} {key1 myValue} {} 30 36 {::datatable1 node2 node1 node15} {key1 123} {} 36 37 {::datatable1 node2 node1 node15 node17} {key1 myValue} {} 37 38 {::datatable1 node2 node1 node15 node17 node19} {key1 myValue} {} 38 39 {::datatable1 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 40 {::datatable1 node3} {key1 myValue} {} 40 41 {::datatable1 node3 node2} {key1 myValue} {} 41 42 {::datatable1 node3 node2 node1} {key1 myValue} {} 42 43 {::datatable1 node3 node2 node1 node14} {key1 myValue} {} 43 44 {::datatable1 node3 node2 node1 node14 node16} {key1 123 key2 abc} {} 44 45 {::datatable1 node3 node2 node1 node14 node16 node18} {key1 myValue} {} 45 46 {::datatable1 node3 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 43 47 {::datatable1 node3 node2 node1 node14 ::datatable0} {key1 myValue} {} 42 48 {::datatable1 node3 node2 node1 node15} {key1 123} {} 48 49 {::datatable1 node3 node2 node1 node15 node17} {key1 myValue} {} 49 50 {::datatable1 node3 node2 node1 node15 node17 node19} {key1 myValue} {} 50 51 {::datatable1 node3 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 52 {::datatable1 node4} {key1 myValue} {} 0 53 {::datatable1 node5} {key1 myValue} {} 53 54 {::datatable1 node5 node13} {key1 myValue} {} 0 55 {::datatable1 node6} {key1 myValue} {} 0 56 {::datatable1 node14} {key1 myValue} {} }} puts stderr "done testing datatablecmd.tcl" exit 0 �����������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/tests/tree.tcl��������������������������������������������������������������������0000644�0001750�0001750�00000165474�11462120063�015065� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # Test switches # # -before, -after, -node for "insert" operation # if {[info procs test] != "test"} { source defs } if [file exists ../library] { set blt_library ../library } #set VERBOSE 1 test tree.1 {tree no args} { list [catch {blt::tree} msg] $msg } {1 {wrong # args: should be one of... blt::tree create ?name? blt::tree destroy name... blt::tree load name libpath blt::tree names ?pattern?...}} test tree.2 {tree create #auto} { list [catch {blt::tree create #auto} msg] $msg } {0 ::tree0} test tree.3 {tree create #auto.suffix} { list [catch {blt::tree create #auto.suffix} msg] $msg } {0 ::tree0.suffix} test tree.4 {tree create prefix.#auto} { list [catch {blt::tree create prefix.#auto} msg] $msg } {0 ::prefix.tree0} test tree.5 {tree create prefix.#auto.suffix} { list [catch {blt::tree create prefix.#auto.suffix} msg] $msg } {0 ::prefix.tree0.suffix} test tree.6 {tree create prefix.#auto.suffix.#auto} { list [catch {blt::tree create prefix.#auto.suffix.#auto} msg] $msg } {0 ::prefix.tree0.suffix.#auto} test tree.7 {tree destroy [tree names *tree0*]} { list [catch {eval blt::tree destroy [blt::tree names *tree0*]} msg] $msg } {0 {}} test tree.8 {create} { list [catch {blt::tree create} msg] $msg } {0 ::tree0} test tree.9 {create} { list [catch {blt::tree create} msg] $msg } {0 ::tree1} test tree.10 {create fred} { list [catch {blt::tree create fred} msg] $msg } {0 ::fred} test tree.11 {create fred} { list [catch {blt::tree create fred} msg] $msg } {1 {a command "::fred" already exists}} test tree.12 {create if} { list [catch {blt::tree create if} msg] $msg } {1 {a command "::if" already exists}} test tree.13 {tree create (bad namespace)} { list [catch {blt::tree create badName::fred} msg] $msg } {1 {unknown namespace "badName"}} test tree.14 {tree create (wrong # args)} { list [catch {blt::tree create a b} msg] $msg } {1 {wrong # args: should be "blt::tree create ?name?"}} test tree.15 {tree names} { list [catch {blt::tree names} msg] [lsort $msg] } {0 {::fred ::tree0 ::tree1}} test tree.16 {tree names pattern)} { list [catch {blt::tree names ::tree*} msg] [lsort $msg] } {0 {::tree0 ::tree1}} test tree.17 {tree names badPattern)} { list [catch {blt::tree names badPattern*} msg] $msg } {0 {}} test tree.18 {tree names pattern arg (wrong # args)} { list [catch {blt::tree names pattern arg} msg] $msg } {1 {wrong # args: should be "blt::tree names ?pattern?..."}} test tree.19 {tree destroy (wrong # args)} { list [catch {blt::tree destroy} msg] $msg } {1 {wrong # args: should be "blt::tree destroy name..."}} test tree.20 {tree destroy badTree} { list [catch {blt::tree destroy badTree} msg] $msg } {1 {can't find a tree named "badTree"}} test tree.21 {tree destroy fred} { list [catch {blt::tree destroy fred} msg] $msg } {0 {}} test tree.22 {tree destroy tree0 tree1} { list [catch {blt::tree destroy tree0 tree1} msg] $msg } {0 {}} test tree.23 {create} { list [catch {blt::tree create} msg] $msg } {0 ::tree0} test tree.24 {tree0} { list [catch {tree0} msg] $msg } {1 {wrong # args: should be one of... tree0 ancestor node1 node2 tree0 apply node ?switches? tree0 attach tree ?switches? tree0 children node ?first? ?last? tree0 copy parent ?tree? node ?switches? tree0 degree node tree0 delete node ?node...? tree0 depth node tree0 dump node tree0 dumpfile node fileName tree0 exists node ?key? tree0 export format ?switches? tree0 find node ?switches? tree0 findchild node label tree0 firstchild node tree0 get node ?key? ?defaultValue? tree0 import format ?switches? tree0 index label|list tree0 insert parent ?switches? tree0 is oper args... tree0 keys node ?node...? tree0 label node ?newLabel? tree0 lastchild node tree0 move node newParent ?switches? tree0 next node tree0 nextsibling node tree0 notify args... tree0 parent node tree0 parsepath node string ?separator? tree0 path node tree0 position ?switches? node... tree0 previous node tree0 prevsibling node tree0 restore node data ?switches? tree0 restorefile node fileName ?switches? tree0 root tree0 set node ?key value...? tree0 size node tree0 sort node ?flags...? tree0 tag args... tree0 trace args... tree0 type node key tree0 unset node ?key...? tree0 values node ?key?}} test tree.25 {tree0 badOp} { list [catch {tree0 badOp} msg] $msg } {1 {bad operation "badOp": should be one of... tree0 ancestor node1 node2 tree0 apply node ?switches? tree0 attach tree ?switches? tree0 children node ?first? ?last? tree0 copy parent ?tree? node ?switches? tree0 degree node tree0 delete node ?node...? tree0 depth node tree0 dump node tree0 dumpfile node fileName tree0 exists node ?key? tree0 export format ?switches? tree0 find node ?switches? tree0 findchild node label tree0 firstchild node tree0 get node ?key? ?defaultValue? tree0 import format ?switches? tree0 index label|list tree0 insert parent ?switches? tree0 is oper args... tree0 keys node ?node...? tree0 label node ?newLabel? tree0 lastchild node tree0 move node newParent ?switches? tree0 next node tree0 nextsibling node tree0 notify args... tree0 parent node tree0 parsepath node string ?separator? tree0 path node tree0 position ?switches? node... tree0 previous node tree0 prevsibling node tree0 restore node data ?switches? tree0 restorefile node fileName ?switches? tree0 root tree0 set node ?key value...? tree0 size node tree0 sort node ?flags...? tree0 tag args... tree0 trace args... tree0 type node key tree0 unset node ?key...? tree0 values node ?key?}} test tree.26 {tree0 insert (wrong # args)} { list [catch {tree0 insert} msg] $msg } {1 {wrong # args: should be "tree0 insert parent ?switches?"}} test tree.27 {tree0 insert badParent} { list [catch {tree0 insert badParent} msg] $msg } {1 {can't find tag or id "badParent" in ::tree0}} test tree.28 {tree0 insert 1000} { list [catch {tree0 insert 1000} msg] $msg } {1 {can't find tag or id "1000" in ::tree0}} test tree.29 {tree0 insert 0} { list [catch {tree0 insert 0} msg] $msg } {0 1} test tree.30 {tree0 insert 0} { list [catch {tree0 insert 0} msg] $msg } {0 2} test tree.31 {tree0 insert root} { list [catch {tree0 insert root} msg] $msg } {0 3} test tree.32 {tree0 insert all} { list [catch {tree0 insert all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.33 {tree0 insert 0 -at badPosition} { list [catch {tree0 insert 0 -at badPosition} msg] $msg } {1 {expected integer but got "badPosition"}} test tree.34 {tree0 insert 0 -at -1} { list [catch {tree0 insert 0 -at -1} msg] $msg } {1 {bad value "-1": can't be negative}} test tree.35 {tree0 insert 0 -at 1000} { list [catch {tree0 insert 0 -at 1000} msg] $msg } {0 4} test tree.36 {tree0 insert 0 -at (no arg)} { list [catch {tree0 insert 0 -at} msg] $msg } {1 {value for "-at" missing}} test tree.37 {tree0 insert 0 -tags myTag} { list [catch {tree0 insert 0 -tags myTag} msg] $msg } {0 5} test tree.38 {tree0 insert 0 -tags {myTag1 myTag2} } { list [catch {tree0 insert 0 -tags {myTag1 myTag2}} msg] $msg } {0 6} test tree.39 {tree0 insert 0 -tags root} { list [catch {tree0 insert 0 -tags root} msg] $msg } {1 {can't add reserved tag "root"}} test tree.40 {tree0 insert 0 -tags (missing arg)} { list [catch {tree0 insert 0 -tags} msg] $msg } {1 {value for "-tags" missing}} test tree.41 {tree0 insert 0 -label myLabel -tags thisTag} { list [catch {tree0 insert 0 -label myLabel -tags thisTag} msg] $msg } {0 8} test tree.42 {tree0 insert 0 -label (missing arg)} { list [catch {tree0 insert 0 -label} msg] $msg } {1 {value for "-label" missing}} test tree.43 {tree0 insert 1 -tags thisTag} { list [catch {tree0 insert 1 -tags thisTag} msg] $msg } {0 9} test tree.44 {tree0 insert 1 -data key (missing value)} { list [catch {tree0 insert 1 -data key} msg] $msg } {1 {missing value for "key"}} test tree.45 {tree0 insert 1 -data {key value}} { list [catch {tree0 insert 1 -data {key value}} msg] $msg } {0 11} test tree.46 {tree0 insert 1 -data {key1 value1 key2 value2}} { list [catch {tree0 insert 1 -data {key1 value1 key2 value2}} msg] $msg } {0 12} test tree.47 {get} { list [catch { tree0 get 12 } msg] $msg } {0 {key1 value1 key2 value2}} test tree.48 {tree0 children} { list [catch {tree0 children} msg] $msg } {1 {wrong # args: should be "tree0 children node ?first? ?last?"}} test tree.49 {tree0 children 0} { list [catch {tree0 children 0} msg] $msg } {0 {1 2 3 4 5 6 8}} test tree.50 {tree0 children root} { list [catch {tree0 children root} msg] $msg } {0 {1 2 3 4 5 6 8}} test tree.51 {tree0 children 1} { list [catch {tree0 children 1} msg] $msg } {0 {9 11 12}} test tree.52 {tree0 insert myTag} { list [catch {tree0 insert myTag} msg] $msg } {0 13} test tree.53 {tree0 children myTag} { list [catch {tree0 children myTag} msg] $msg } {0 13} test tree.54 {tree0 children root 0 end} { list [catch {tree0 children root 0 end} msg] $msg } {0 {1 2 3 4 5 6 8}} test tree.55 {tree0 children root 2} { list [catch {tree0 children root 2} msg] $msg } {0 3} test tree.56 {tree0 children root 2 end} { list [catch {tree0 children root 2 end} msg] $msg } {0 {3 4 5 6 8}} test tree.57 {tree0 children root end end} { list [catch {tree0 children root end end} msg] $msg } {0 8} test tree.58 {tree0 children root 0 2} { list [catch {tree0 children root 0 2} msg] $msg } {0 {1 2 3}} test tree.59 {tree0 children root -1 -20} { list [catch {tree0 children root -1 -20} msg] $msg } {0 {}} test tree.60 {tree0 firstchild (missing arg)} { list [catch {tree0 firstchild} msg] $msg } {1 {wrong # args: should be "tree0 firstchild node"}} test tree.61 {tree0 firstchild root} { list [catch {tree0 firstchild root} msg] $msg } {0 1} test tree.62 {tree0 lastchild (missing arg)} { list [catch {tree0 lastchild} msg] $msg } {1 {wrong # args: should be "tree0 lastchild node"}} test tree.63 {tree0 lastchild root} { list [catch {tree0 lastchild root} msg] $msg } {0 8} test tree.64 {tree0 nextsibling (missing arg)} { list [catch {tree0 nextsibling} msg] $msg } {1 {wrong # args: should be "tree0 nextsibling node"}} test tree.65 {tree0 nextsibling 1)} { list [catch {tree0 nextsibling 1} msg] $msg } {0 2} test tree.66 {tree0 nextsibling 2)} { list [catch {tree0 nextsibling 2} msg] $msg } {0 3} test tree.67 {tree0 nextsibling 3)} { list [catch {tree0 nextsibling 3} msg] $msg } {0 4} test tree.68 {tree0 nextsibling 4)} { list [catch {tree0 nextsibling 4} msg] $msg } {0 5} test tree.69 {tree0 nextsibling 5)} { list [catch {tree0 nextsibling 5} msg] $msg } {0 6} test tree.70 {tree0 nextsibling 6)} { list [catch {tree0 nextsibling 6} msg] $msg } {0 8} test tree.71 {tree0 nextsibling 8)} { list [catch {tree0 nextsibling 8} msg] $msg } {0 -1} test tree.72 {tree0 nextsibling all)} { list [catch {tree0 nextsibling all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.73 {tree0 nextsibling badTag)} { list [catch {tree0 nextsibling badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::tree0}} test tree.74 {tree0 nextsibling -1)} { list [catch {tree0 nextsibling -1} msg] $msg } {1 {can't find tag or id "-1" in ::tree0}} test tree.75 {tree0 prevsibling 2)} { list [catch {tree0 prevsibling 2} msg] $msg } {0 1} test tree.76 {tree0 prevsibling 1)} { list [catch {tree0 prevsibling 1} msg] $msg } {0 -1} test tree.77 {tree0 prevsibling -1)} { list [catch {tree0 prevsibling -1} msg] $msg } {1 {can't find tag or id "-1" in ::tree0}} test tree.78 {tree0 root)} { list [catch {tree0 root} msg] $msg } {0 0} test tree.79 {tree0 root badArg)} { list [catch {tree0 root badArgs} msg] $msg } {1 {wrong # args: should be "tree0 root "}} test tree.80 {tree0 parent (missing arg))} { list [catch {tree0 parent} msg] $msg } {1 {wrong # args: should be "tree0 parent node"}} test tree.81 {tree0 parent root)} { list [catch {tree0 parent root} msg] $msg } {0 -1} test tree.82 {tree0 parent 1)} { list [catch {tree0 parent 1} msg] $msg } {0 0} test tree.83 {tree0 parent myTag)} { list [catch {tree0 parent myTag} msg] $msg } {0 0} test tree.84 {tree0 next (missing arg))} { list [catch {tree0 next} msg] $msg } {1 {wrong # args: should be "tree0 next node"}} test tree.85 {tree0 next (extra arg))} { list [catch {tree0 next root root} msg] $msg } {1 {wrong # args: should be "tree0 next node"}} test tree.86 {tree0 next root} { list [catch {tree0 next root} msg] $msg } {0 1} test tree.87 {tree0 next 1)} { list [catch {tree0 next 1} msg] $msg } {0 9} test tree.88 {tree0 next 2)} { list [catch {tree0 next 2} msg] $msg } {0 3} test tree.89 {tree0 next 3)} { list [catch {tree0 next 3} msg] $msg } {0 4} test tree.90 {tree0 next 4)} { list [catch {tree0 next 4} msg] $msg } {0 5} test tree.91 {tree0 next 5)} { list [catch {tree0 next 5} msg] $msg } {0 13} test tree.92 {tree0 next 6)} { list [catch {tree0 next 6} msg] $msg } {0 8} test tree.93 {tree0 next 8)} { list [catch {tree0 next 8} msg] $msg } {0 -1} test tree.94 {tree0 previous 1)} { list [catch {tree0 previous 1} msg] $msg } {0 0} test tree.95 {tree0 previous 0)} { list [catch {tree0 previous 0} msg] $msg } {0 -1} test tree.96 {tree0 previous 8)} { list [catch {tree0 previous 8} msg] $msg } {0 6} test tree.97 {tree0 depth (no arg))} { list [catch {tree0 depth} msg] $msg } {1 {wrong # args: should be "tree0 depth node"}} test tree.98 {tree0 depth root))} { list [catch {tree0 depth root} msg] $msg } {0 0} test tree.99 {tree0 depth myTag))} { list [catch {tree0 depth myTag} msg] $msg } {0 1} test tree.100 {tree0 depth myTag))} { list [catch {tree0 depth myTag} msg] $msg } {0 1} test tree.101 {tree0 dump (missing arg)))} { list [catch {tree0 dump} msg] $msg } {1 {wrong # args: should be "tree0 dump node"}} test tree.102 {tree0 dump root} { list [catch {tree0 dump root} msg] $msg } {0 {-1 0 {{}} {} {} 0 1 {{} node1} {} {} 1 9 {{} node1 node9} {} {thisTag} 1 11 {{} node1 node11} {key value} {} 1 12 {{} node1 node12} {key1 value1 key2 value2} {} 0 2 {{} node2} {} {} 0 3 {{} node3} {} {} 0 4 {{} node4} {} {} 0 5 {{} node5} {} {myTag} 5 13 {{} node5 node13} {} {} 0 6 {{} node6} {} {myTag2 myTag1} 0 8 {{} myLabel} {} {thisTag} }} test tree.103 {tree0 dump 1} { list [catch {tree0 dump 1} msg] $msg } {0 {-1 1 {node1} {} {} 1 9 {node1 node9} {} {thisTag} 1 11 {node1 node11} {key value} {} 1 12 {node1 node12} {key1 value1 key2 value2} {} }} test tree.104 {tree0 dump this} { list [catch {tree0 dump myTag} msg] $msg } {0 {-1 5 {node5} {} {myTag} 5 13 {node5 node13} {} {} }} test tree.105 {tree0 dump 1 badArg (too many args)} { list [catch {tree0 dump 1 badArg} msg] $msg } {1 {wrong # args: should be "tree0 dump node"}} test tree.106 {tree0 dump 11} { list [catch {tree0 dump 11} msg] $msg } {0 {-1 11 {node11} {key value} {} }} test tree.107 {tree0 dump all} { list [catch {tree0 dump all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.108 {tree0 dump all} { list [catch {tree0 dump all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.109 {tree0 dumpfile 0 test.dump} { list [catch {tree0 dumpfile 0 test.dump} msg] $msg } {0 {}} test tree.110 {tree0 get 9} { list [catch {tree0 get 9} msg] $msg } {0 {}} test tree.111 {tree0 get all} { list [catch {tree0 get all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.112 {tree0 get root} { list [catch {tree0 get root} msg] $msg } {0 {}} test tree.113 {tree0 get 9 key} { list [catch {tree0 get root} msg] $msg } {0 {}} test tree.114 {tree0 get 12} { list [catch {tree0 get 12} msg] $msg } {0 {key1 value1 key2 value2}} test tree.115 {tree0 get 12 key1} { list [catch {tree0 get 12 key1} msg] $msg } {0 value1} test tree.116 {tree0 get 12 key2} { list [catch {tree0 get 12 key2} msg] $msg } {0 value2} test tree.117 {tree0 get 12 key1 defValue } { list [catch {tree0 get 12 key1 defValue} msg] $msg } {0 value1} test tree.118 {tree0 get 12 key100 defValue } { list [catch {tree0 get 12 key100 defValue} msg] $msg } {0 defValue} test tree.119 {tree0 index (missing arg) } { list [catch {tree0 index} msg] $msg } {1 {wrong # args: should be "tree0 index label|list"}} test tree.120 {tree0 index 0 10 (extra arg) } { list [catch {tree0 index 0 10} msg] $msg } {1 {wrong # args: should be "tree0 index label|list"}} test tree.121 {tree0 index 0} { list [catch {tree0 index 0} msg] $msg } {0 0} test tree.122 {tree0 index root} { list [catch {tree0 index root} msg] $msg } {0 0} test tree.123 {tree0 index all} { list [catch {tree0 index all} msg] $msg } {0 -1} test tree.124 {tree0 index myTag} { list [catch {tree0 index myTag} msg] $msg } {0 5} test tree.125 {tree0 index thisTag} { list [catch {tree0 index thisTag} msg] $msg } {0 -1} test tree.126 {tree0 is (no args)} { list [catch {tree0 is} msg] $msg } {1 {wrong # args: should be one of... tree0 is ancestor node1 node2 tree0 is before node1 node2 tree0 is leaf node tree0 is root node}} test tree.127 {tree0 is badOp} { list [catch {tree0 is badOp} msg] $msg } {1 {bad operation "badOp": should be one of... tree0 is ancestor node1 node2 tree0 is before node1 node2 tree0 is leaf node tree0 is root node}} test tree.128 {tree0 is before} { list [catch {tree0 is before} msg] $msg } {1 {wrong # args: should be "tree0 is before node1 node2"}} test tree.129 {tree0 is before 0 10 20} { list [catch {tree0 is before 0 10 20} msg] $msg } {1 {wrong # args: should be "tree0 is before node1 node2"}} test tree.130 {tree0 is before 0 12} { list [catch {tree0 is before 0 12} msg] $msg } {0 1} test tree.131 {tree0 is before 12 0} { list [catch {tree0 is before 12 0} msg] $msg } {0 0} test tree.132 {tree0 is before 0 0} { list [catch {tree0 is before 0 0} msg] $msg } {0 0} test tree.133 {tree0 is before root 0} { list [catch {tree0 is before root 0} msg] $msg } {0 0} test tree.134 {tree0 is before 0 all} { list [catch {tree0 is before 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.135 {tree0 is ancestor} { list [catch {tree0 is ancestor} msg] $msg } {1 {wrong # args: should be "tree0 is ancestor node1 node2"}} test tree.136 {tree0 is ancestor 0 12 20} { list [catch {tree0 is ancestor 0 12 20} msg] $msg } {1 {wrong # args: should be "tree0 is ancestor node1 node2"}} test tree.137 {tree0 is ancestor 0 12} { list [catch {tree0 is ancestor 0 12} msg] $msg } {0 1} test tree.138 {tree0 is ancestor 12 0} { list [catch {tree0 is ancestor 12 0} msg] $msg } {0 0} test tree.139 {tree0 is ancestor 1 2} { list [catch {tree0 is ancestor 1 2} msg] $msg } {0 0} test tree.140 {tree0 is ancestor root 0} { list [catch {tree0 is ancestor root 0} msg] $msg } {0 0} test tree.141 {tree0 is ancestor 0 all} { list [catch {tree0 is ancestor 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.142 {tree0 is root (missing arg)} { list [catch {tree0 is root} msg] $msg } {1 {wrong # args: should be "tree0 is root node"}} test tree.143 {tree0 is root 0 20 (extra arg)} { list [catch {tree0 is root 0 20} msg] $msg } {1 {wrong # args: should be "tree0 is root node"}} test tree.144 {tree0 is root 0} { list [catch {tree0 is root 0} msg] $msg } {0 1} test tree.145 {tree0 is root 12} { list [catch {tree0 is root 12} msg] $msg } {0 0} test tree.146 {tree0 is root 1} { list [catch {tree0 is root 1} msg] $msg } {0 0} test tree.147 {tree0 is root root} { list [catch {tree0 is root root} msg] $msg } {0 1} test tree.148 {tree0 is root all} { list [catch {tree0 is root all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.149 {tree0 is leaf (missing arg)} { list [catch {tree0 is leaf} msg] $msg } {1 {wrong # args: should be "tree0 is leaf node"}} test tree.150 {tree0 is leaf 0 20 (extra arg)} { list [catch {tree0 is leaf 0 20} msg] $msg } {1 {wrong # args: should be "tree0 is leaf node"}} test tree.151 {tree0 is leaf 0} { list [catch {tree0 is leaf 0} msg] $msg } {0 0} test tree.152 {tree0 is leaf 12} { list [catch {tree0 is leaf 12} msg] $msg } {0 1} test tree.153 {tree0 is leaf 1} { list [catch {tree0 is leaf 1} msg] $msg } {0 0} test tree.154 {tree0 is leaf root} { list [catch {tree0 is leaf root} msg] $msg } {0 0} test tree.155 {tree0 is leaf all} { list [catch {tree0 is leaf all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.156 {tree0 is leaf 1000} { list [catch {tree0 is leaf 1000} msg] $msg } {1 {can't find tag or id "1000" in ::tree0}} test tree.157 {tree0 is leaf badTag} { list [catch {tree0 is leaf badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::tree0}} test tree.158 {tree0 set (missing arg)} { list [catch {tree0 set} msg] $msg } {1 {wrong # args: should be "tree0 set node ?key value...?"}} test tree.159 {tree0 set 0 (missing arg)} { list [catch {tree0 set 0} msg] $msg } {0 {}} test tree.160 {tree0 set 0 key (missing arg)} { list [catch {tree0 set 0 key} msg] $msg } {1 {missing value for field "key"}} test tree.161 {tree0 set 0 key value} { list [catch {tree0 set 0 key value} msg] $msg } {0 {}} test tree.162 {tree0 set 0 key1 value1 key2 value2 key3 value3} { list [catch {tree0 set 0 key1 value1 key2 value2 key3 value3} msg] $msg } {0 {}} test tree.163 {tree0 set 0 key1 value1 key2 (missing arg)} { list [catch {tree0 set 0 key1 value1 key2} msg] $msg } {1 {missing value for field "key2"}} test tree.164 {tree0 set 0 key value} { list [catch {tree0 set 0 key value} msg] $msg } {0 {}} test tree.165 {tree0 set 0 key1 value1 key2 (missing arg)} { list [catch {tree0 set 0 key1 value1 key2} msg] $msg } {1 {missing value for field "key2"}} test tree.166 {tree0 set all} { list [catch {tree0 set all} msg] $msg } {0 {}} test tree.167 {tree0 set all abc 123} { list [catch {tree0 set all abc 123} msg] $msg } {0 {}} test tree.168 {tree0 set root} { list [catch {tree0 set root} msg] $msg } {0 {}} test tree.169 {tree0 restore stuff} { list [catch { set data [tree0 dump root] blt::tree create tree1 restore root $data set data [tree1 dump root] blt::tree destroy tree1 set data } msg] $msg } {0 {-1 0 {{}} {key value key1 value1 key2 value2 key3 value3 abc 123} {} 0 1 {{} node1} {abc 123} {} 1 9 {{} node1 node9} {abc 123} {thisTag} 1 11 {{} node1 node11} {key value abc 123} {} 1 12 {{} node1 node12} {key1 value1 key2 value2 abc 123} {} 0 2 {{} node2} {abc 123} {} 0 3 {{} node3} {abc 123} {} 0 4 {{} node4} {abc 123} {} 0 5 {{} node5} {abc 123} {myTag} 5 13 {{} node5 node13} {abc 123} {} 0 6 {{} node6} {abc 123} {myTag2 myTag1} 0 8 {{} myLabel} {abc 123} {thisTag} }} test tree.170 {tree0 restorefile 0 test.dump} { list [catch { blt::tree create tree1 restorefile root test.dump set data [tree1 dump root] blt::tree destroy tree1 file delete test.dump set data } msg] $msg } {0 {-1 0 {{}} {} {} 0 1 {{} node1} {} {} 1 9 {{} node1 node9} {} {thisTag} 1 11 {{} node1 node11} {key value} {} 1 12 {{} node1 node12} {key1 value1 key2 value2} {} 0 2 {{} node2} {} {} 0 3 {{} node3} {} {} 0 4 {{} node4} {} {} 0 5 {{} node5} {} {myTag} 5 13 {{} node5 node13} {} {} 0 6 {{} node6} {} {myTag2 myTag1} 0 8 {{} myLabel} {} {thisTag} }} test tree.171 {tree0 unset 0 key1} { list [catch {tree0 unset 0 key1} msg] $msg } {0 {}} test tree.172 {tree0 get 0} { list [catch {tree0 get 0} msg] $msg } {0 {key value key2 value2 key3 value3 abc 123}} test tree.173 {tree0 unset 0 key2 key3} { list [catch {tree0 unset 0 key2 key3} msg] $msg } {0 {}} test tree.174 {tree0 get 0} { list [catch {tree0 get 0} msg] $msg } {0 {key value abc 123}} test tree.175 {tree0 unset 0} { list [catch {tree0 unset 0} msg] $msg } {0 {}} test tree.176 {tree0 get 0} { list [catch {tree0 get 0} msg] $msg } {0 {}} test tree.177 {tree0 unset all abc} { list [catch {tree0 unset all abc} msg] $msg } {0 {}} test tree.178 {tree0 restore stuff} { list [catch { set data [tree0 dump root] blt::tree create tree1 tree1 restore root $data set data [tree1 dump root] blt::tree destroy tree1 set data } msg] $msg } {0 {-1 0 {{}} {} {} 0 1 {{} node1} {} {} 1 9 {{} node1 node9} {} {thisTag} 1 11 {{} node1 node11} {key value} {} 1 12 {{} node1 node12} {key1 value1 key2 value2} {} 0 2 {{} node2} {} {} 0 3 {{} node3} {} {} 0 4 {{} node4} {} {} 0 5 {{} node5} {} {myTag} 5 13 {{} node5 node13} {} {} 0 6 {{} node6} {} {myTag2 myTag1} 0 8 {{} myLabel} {} {thisTag} }} test tree.179 {tree0 restore (missing arg)} { list [catch {tree0 restore} msg] $msg } {1 {wrong # args: should be "tree0 restore node data ?switches?"}} test tree.180 {tree0 restore 0 badString} { list [catch {tree0 restore 0 badString} msg] $msg } {1 {line #1: wrong # elements in restore entry}} test tree.181 {tree0 restore 0 {} arg (extra arg)} { list [catch {tree0 restore 0 {} arg} msg] $msg } {1 {unknown switch "arg" following switches are available: -notags -overwrite }} test tree.182 {tree0 size (missing arg)} { list [catch {tree0 size} msg] $msg } {1 {wrong # args: should be "tree0 size node"}} test tree.183 {tree0 size 0} { list [catch {tree0 size 0} msg] $msg } {0 12} test tree.184 {tree0 size all} { list [catch {tree0 size all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.185 {tree0 size 0 10 (extra arg)} { list [catch {tree0 size 0 10} msg] $msg } {1 {wrong # args: should be "tree0 size node"}} test tree.186 {tree0 delete (no args)} { list [catch {tree0 delete} msg] $msg } {0 {}} test tree.187 {tree0 delete 11} { list [catch {tree0 delete 11} msg] $msg } {0 {}} test tree.188 {tree0 delete 11} { list [catch {tree0 delete 11} msg] $msg } {1 {can't find tag or id "11" in ::tree0}} test tree.189 {tree0 delete 9 12} { list [catch {tree0 delete 9 12} msg] $msg } {0 {}} test tree.190 {tree0 dump 0} { list [catch {tree0 dump 0} msg] $msg } {0 {-1 0 {{}} {} {} 0 1 {{} node1} {} {} 0 2 {{} node2} {} {} 0 3 {{} node3} {} {} 0 4 {{} node4} {} {} 0 5 {{} node5} {} {myTag} 5 13 {{} node5 node13} {} {} 0 6 {{} node6} {} {myTag2 myTag1} 0 8 {{} myLabel} {} {thisTag} }} test tree.191 {delete all} { list [catch { set data [tree0 dump root] blt::tree create tree1 restore root $data tree1 delete all set data [tree1 dump root] blt::tree destroy tree1 set data } msg] $msg } {0 {-1 0 {{}} {} {} }} test tree.192 {delete all all} { list [catch { set data [tree0 dump root] blt::tree create tree1 restore root $data tree1 delete all all set data [tree1 dump root] blt::tree destroy tree1 set data } msg] $msg } {0 {-1 0 {{}} {} {} }} test tree.193 {tree0 apply (missing arg)} { list [catch {tree0 apply} msg] $msg } {1 {wrong # args: should be "tree0 apply node ?switches?"}} test tree.194 {tree0 apply 0} { list [catch {tree0 apply 0} msg] $msg } {0 {}} test tree.195 {tree0 apply 0 -badSwitch} { list [catch {tree0 apply 0 -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -precommand command -postcommand command -depth number -exact string -glob pattern -invert -key pattern -keyexact string -keyglob pattern -keyregexp pattern -leafonly -nocase -path -regexp pattern -tag {?tag?...}}} test tree.196 {tree0 apply badTag} { list [catch {tree0 apply badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::tree0}} test tree.197 {tree0 apply all} { list [catch {tree0 apply all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.198 {tree0 apply myTag -precommand lappend} { list [catch { set mylist {} tree0 apply myTag -precommand {lappend mylist} set mylist } msg] $msg } {0 {5 13}} test tree.199 {tree0 apply root -precommand lappend} { list [catch { set mylist {} tree0 apply root -precommand {lappend mylist} set mylist } msg] $msg } {0 {0 1 2 3 4 5 13 6 8}} test tree.200 {tree0 apply -precommand -postcommand} { list [catch { set mylist {} tree0 apply root -precommand {lappend mylist} \ -postcommand {lappend mylist} set mylist } msg] $msg } {0 {0 1 1 2 2 3 3 4 4 5 13 13 5 6 6 8 8 0}} test tree.201 {tree0 apply root -precommand lappend -depth 1} { list [catch { set mylist {} tree0 apply root -precommand {lappend mylist} -depth 1 set mylist } msg] $msg } {0 {0 1 2 3 4 5 6 8}} test tree.202 {tree0 apply root -precommand -depth 0} { list [catch { set mylist {} tree0 apply root -precommand {lappend mylist} -depth 0 set mylist } msg] $msg } {0 0} test tree.203 {tree0 apply root -precommand -tag myTag} { list [catch { set mylist {} tree0 apply root -precommand {lappend mylist} -tag myTag set mylist } msg] $msg } {0 5} test tree.204 {tree0 apply root -precommand -key key1} { list [catch { set mylist {} tree0 set myTag key1 0.0 tree0 apply root -precommand {lappend mylist} -key key1 tree0 unset myTag key1 set mylist } msg] $msg } {0 5} test tree.205 {tree0 apply root -postcommand -regexp node.*} { list [catch { set mylist {} tree0 set myTag key1 0.0 tree0 apply root -precommand {lappend mylist} -regexp {node5} tree0 unset myTag key1 set mylist } msg] $msg } {0 5} test tree.206 {tree0 find (missing arg)} { list [catch {tree0 find} msg] $msg } {1 {wrong # args: should be "tree0 find node ?switches?"}} test tree.207 {tree0 find 0} { list [catch {tree0 find 0} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.208 {tree0 find root} { list [catch {tree0 find root} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.209 {tree0 find 0 -glob node*} { list [catch {tree0 find root -glob node*} msg] $msg } {0 {1 2 3 4 13 5 6}} test tree.210 {tree0 find 0 -glob nobody} { list [catch {tree0 find root -glob nobody} msg] $msg } {0 {}} test tree.211 {tree0 find 0 -regexp {node[0-3]}} { list [catch {tree0 find root -regexp {node[0-3]}} msg] $msg } {0 {1 2 3 13}} test tree.212 {tree0 find 0 -regexp {.*[A-Z].*}} { list [catch {tree0 find root -regexp {.*[A-Z].*}} msg] $msg } {0 8} test tree.213 {tree0 find 0 -exact myLabel} { list [catch {tree0 find root -exact myLabel} msg] $msg } {0 8} test tree.214 {tree0 find 0 -exact myLabel -invert} { list [catch {tree0 find root -exact myLabel -invert} msg] $msg } {0 {1 2 3 4 13 5 6 0}} test tree.215 {tree0 find 3 -exact node3} { list [catch {tree0 find 3 -exact node3} msg] $msg } {0 3} test tree.216 {tree0 find 0 -nocase -exact mylabel} { list [catch {tree0 find 0 -nocase -exact mylabel} msg] $msg } {0 8} test tree.217 {tree0 find 0 -nocase} { list [catch {tree0 find 0 -nocase} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.218 {tree0 find 0 -path -nocase -glob *node1* } { list [catch {tree0 find 0 -path -nocase -glob *node1*} msg] $msg } {0 {1 13}} test tree.219 {tree0 find 0 -count 5 } { list [catch {tree0 find 0 -count 5} msg] $msg } {0 {1 2 3 4 13}} test tree.220 {tree0 find 0 -count -5 } { list [catch {tree0 find 0 -count -5} msg] $msg } {1 {bad value "-5": can't be negative}} test tree.221 {tree0 find 0 -count badValue } { list [catch {tree0 find 0 -count badValue} msg] $msg } {1 {expected integer but got "badValue"}} test tree.222 {tree0 find 0 -count badValue } { list [catch {tree0 find 0 -count badValue} msg] $msg } {1 {expected integer but got "badValue"}} test tree.223 {tree0 find 0 -leafonly} { list [catch {tree0 find 0 -leafonly} msg] $msg } {0 {1 2 3 4 13 6 8}} test tree.224 {tree0 find 0 -leafonly -glob {node[18]}} { list [catch {tree0 find 0 -glob {node[18]} -leafonly} msg] $msg } {0 1} test tree.225 {tree0 find 0 -depth 0} { list [catch {tree0 find 0 -depth 0} msg] $msg } {0 0} test tree.226 {tree0 find 0 -depth 1} { list [catch {tree0 find 0 -depth 1} msg] $msg } {0 {1 2 3 4 5 6 8 0}} test tree.227 {tree0 find 0 -depth 2} { list [catch {tree0 find 0 -depth 2} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.228 {tree0 find 0 -depth 20} { list [catch {tree0 find 0 -depth 20} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.229 {tree0 find 1 -depth 0} { list [catch {tree0 find 1 -depth 0} msg] $msg } {0 1} test tree.230 {tree0 find 1 -depth 1} { list [catch {tree0 find 1 -depth 1} msg] $msg } {0 1} test tree.231 {tree0 find 1 -depth 2} { list [catch {tree0 find 1 -depth 2} msg] $msg } {0 1} test tree.232 {tree0 find all} { list [catch {tree0 find all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.233 {tree0 find badTag} { list [catch {tree0 find badTag} msg] $msg } {1 {can't find tag or id "badTag" in ::tree0}} test tree.234 {tree0 find 0 -addtag hi} { list [catch {tree0 find 0 -addtag hi} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.235 {tree0 find 0 -addtag all} { list [catch {tree0 find 0 -addtag all} msg] $msg } {0 {1 2 3 4 13 5 6 8 0}} test tree.236 {tree0 find 0 -addtag root} { list [catch {tree0 find 0 -addtag root} msg] $msg } {1 {can't add reserved tag "root"}} test tree.237 {tree0 find 0 -exec {lappend list} -leafonly} { list [catch { set list {} tree0 find 0 -exec {lappend list} -leafonly set list } msg] $msg } {0 {1 2 3 4 13 6 8}} test tree.238 {tree0 find 0 -tag root} { list [catch {tree0 find 0 -tag root} msg] $msg } {0 0} test tree.239 {tree0 find 0 -tag myTag} { list [catch {tree0 find 0 -tag myTag} msg] $msg } {0 5} test tree.240 {tree0 find 0 -tag badTag} { list [catch {tree0 find 0 -tag badTag} msg] $msg } {0 {}} test tree.241 {tree0 tag (missing args)} { list [catch {tree0 tag} msg] $msg } {1 {wrong # args: should be "tree0 tag args..."}} test tree.242 {tree0 tag badOp} { list [catch {tree0 tag badOp} msg] $msg } {1 {bad operation "badOp": should be one of... tree0 tag add tag ?node...? tree0 tag delete tag node... tree0 tag dump tag... tree0 tag exists tag ?node? tree0 tag forget tag... tree0 tag get node ?pattern...? tree0 tag names ?node...? tree0 tag nodes tag ?tag...? tree0 tag set node tag... tree0 tag unset node tag...}} test tree.243 {tree0 tag add} { list [catch {tree0 tag add} msg] $msg } {1 {wrong # args: should be "tree0 tag add tag ?node...?"}} test tree.244 {tree0 tag add newTag} { list [catch {tree0 tag add newTag} msg] $msg } {0 {}} test tree.245 {tree0 tag add tag badNode} { list [catch {tree0 tag add tag badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::tree0}} test tree.246 {tree0 tag add newTag root} { list [catch {tree0 tag add newTag root} msg] $msg } {0 {}} test tree.247 {tree0 tag add newTag all} { list [catch {tree0 tag add newTag all} msg] $msg } {0 {}} test tree.248 {tree0 tag add tag2 0 1 2 3 4} { list [catch {tree0 tag add tag2 0 1 2 3 4} msg] $msg } {0 {}} test tree.248 {tree0 tag exists tag2} { list [catch {tree0 tag exists tag2} msg] $msg } {0 1} test tree.248 {tree0 tag exists tag2 0} { list [catch {tree0 tag exists tag2 0} msg] $msg } {0 1} test tree.248 {tree0 tag exists tag2 5} { list [catch {tree0 tag exists tag2 5} msg] $msg } {0 0} test tree.248 {tree0 tag exists badTag} { list [catch {tree0 tag exists badTag} msg] $msg } {0 0} test tree.248 {tree0 tag exists badTag 1000} { list [catch {tree0 tag exists badTag 1000} msg] $msg } {1 {can't find tag or id "1000" in ::tree0}} test tree.249 {tree0 tag add tag2 0 1 2 3 4 1000} { list [catch {tree0 tag add tag2 0 1 2 3 4 1000} msg] $msg } {1 {can't find tag or id "1000" in ::tree0}} test tree.250 {tree0 tag names} { list [catch {tree0 tag names} msg] [lsort $msg] } {0 {all hi myTag myTag1 myTag2 newTag root tag2 thisTag}} test tree.251 {tree0 tag names badNode} { list [catch {tree0 tag names badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::tree0}} test tree.252 {tree0 tag names all} { list [catch {tree0 tag names all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.253 {tree0 tag names root} { list [catch {tree0 tag names root} msg] [lsort $msg] } {0 {all hi newTag root tag2}} test tree.254 {tree0 tag names 0 1} { list [catch {tree0 tag names 0 1} msg] [lsort $msg] } {0 {all hi newTag root tag2}} test tree.255 {tree0 tag nodes (missing arg)} { list [catch {tree0 tag nodes} msg] $msg } {1 {wrong # args: should be "tree0 tag nodes tag ?tag...?"}} test tree.256 {tree0 tag nodes root badTag} { # It's not an error to use bad tag. list [catch {tree0 tag nodes root badTag} msg] $msg } {0 {}} test tree.257 {tree0 tag nodes root tag2} { list [catch {tree0 tag nodes root tag2} msg] [lsort $msg] } {0 {0 1 2 3 4}} test tree.258 {tree0 ancestor (missing arg)} { list [catch {tree0 ancestor} msg] $msg } {1 {wrong # args: should be "tree0 ancestor node1 node2"}} test tree.259 {tree0 ancestor 0 (missing arg)} { list [catch {tree0 ancestor 0} msg] $msg } {1 {wrong # args: should be "tree0 ancestor node1 node2"}} test tree.260 {tree0 ancestor 0 10} { list [catch {tree0 ancestor 0 10} msg] $msg } {1 {can't find tag or id "10" in ::tree0}} test tree.261 {tree0 ancestor 0 4} { list [catch {tree0 ancestor 0 4} msg] $msg } {0 0} test tree.262 {tree0 ancestor 1 8} { list [catch {tree0 ancestor 1 8} msg] $msg } {0 0} test tree.263 {tree0 ancestor root 0} { list [catch {tree0 ancestor root 0} msg] $msg } {0 0} test tree.264 {tree0 ancestor 8 8} { list [catch {tree0 ancestor 8 8} msg] $msg } {0 8} test tree.265 {tree0 ancestor 0 all} { list [catch {tree0 ancestor 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.266 {tree0 ancestor 7 9} { list [catch { set n1 1; set n2 1; for { set i 0 } { $i < 4 } { incr i } { set n1 [tree0 insert $n1] set n2 [tree0 insert $n2] } tree0 ancestor $n1 $n2 } msg] $msg } {0 1} test tree.267 {tree0 path (missing arg)} { list [catch {tree0 path} msg] $msg } {1 {wrong # args: should be "tree0 path node"}} test tree.268 {tree0 path root} { list [catch {tree0 path root} msg] $msg } {0 {}} test tree.269 {tree0 path 0} { list [catch {tree0 path 0} msg] $msg } {0 {}} test tree.270 {tree0 path 15} { list [catch {tree0 path 15} msg] $msg } {0 {node1 node15}} test tree.271 {tree0 path all} { list [catch {tree0 path all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.272 {tree0 path 0 1 2 4 (extra args)} { list [catch {tree0 path 0 1 2 4} msg] $msg } {1 {wrong # args: should be "tree0 path node"}} test tree.273 {tree0 tag forget} { list [catch {tree0 tag forget} msg] $msg } {1 {wrong # args: should be "tree0 tag forget tag..."}} test tree.274 {tree0 tag forget badTag} { list [catch { tree0 tag forget badTag lsort [tree0 tag names] } msg] $msg } {0 {all hi myTag myTag1 myTag2 newTag root tag2 thisTag}} test tree.275 {tree0 tag forget hi} { list [catch { tree0 tag forget hi lsort [tree0 tag names] } msg] $msg } {0 {all myTag myTag1 myTag2 newTag root tag2 thisTag}} test tree.276 {tree0 tag forget tag1 tag2} { list [catch { tree0 tag forget myTag1 myTag2 lsort [tree0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test tree.277 {tree0 tag forget all} { list [catch { tree0 tag forget all lsort [tree0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test tree.278 {tree0 tag forget root} { list [catch { tree0 tag forget root lsort [tree0 tag names] } msg] $msg } {0 {all myTag newTag root tag2 thisTag}} test tree.279 {tree0 tag delete} { list [catch {tree0 tag delete} msg] $msg } {1 {wrong # args: should be "tree0 tag delete tag node..."}} test tree.280 {tree0 tag delete tag} { list [catch {tree0 tag delete tag} msg] $msg } {1 {wrong # args: should be "tree0 tag delete tag node..."}} test tree.281 {tree0 tag delete tag 0} { list [catch {tree0 tag delete tag 0} msg] $msg } {0 {}} test tree.282 {tree0 tag delete root 0} { list [catch {tree0 tag delete root 0} msg] $msg } {1 {can't delete reserved tag "root"}} test tree.283 {tree0 move} { list [catch {tree0 move} msg] $msg } {1 {wrong # args: should be "tree0 move node newParent ?switches?"}} test tree.284 {tree0 move 0} { list [catch {tree0 move 0} msg] $msg } {1 {wrong # args: should be "tree0 move node newParent ?switches?"}} test tree.285 {tree0 move 0 0} { list [catch {tree0 move 0 0} msg] $msg } {1 {can't move root node}} test tree.286 {tree0 move 0 badNode} { list [catch {tree0 move 0 badNode} msg] $msg } {1 {can't find tag or id "badNode" in ::tree0}} test tree.287 {tree0 move 0 all} { list [catch {tree0 move 0 all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.288 {tree0 move 1 0 -before 2} { list [catch { tree0 move 1 0 -before 2 tree0 children 0 } msg] $msg } {0 {1 2 3 4 5 6 8}} test tree.289 {tree0 move 1 0 -after 2} { list [catch { tree0 move 1 0 -after 2 tree0 children 0 } msg] $msg } {0 {2 1 3 4 5 6 8}} test tree.290 {tree0 move 1 2} { list [catch { tree0 move 1 2 tree0 children 0 } msg] $msg } {0 {2 3 4 5 6 8}} test tree.291 {tree0 move 0 2} { list [catch {tree0 move 0 2} msg] $msg } {1 {can't move root node}} test tree.292 {tree0 move 1 17} { list [catch {tree0 move 1 17} msg] $msg } {1 {can't move node: "1" is an ancestor of "17"}} test tree.293 {tree0 attach} { list [catch {tree0 attach} msg] $msg } {1 {wrong # args: should be "tree0 attach tree ?switches?"}} test tree.294 {tree0 attach tree2 badArg} { list [catch {tree0 attach tree2 badArg} msg] $msg } {1 {unknown switch "badArg" following switches are available: -newtags }} test tree.295 {tree1 attach tree0 -newtags} { list [catch { blt::tree create tree1 attach tree0 -newtags tree1 dump 0 } msg] $msg } {0 {-1 0 {{}} {} {} 0 2 {{} node2} {} {} 2 1 {{} node2 node1} {} {} 1 14 {{} node2 node1 node14} {} {} 14 16 {{} node2 node1 node14 node16} {} {} 16 18 {{} node2 node1 node14 node16 node18} {} {} 18 20 {{} node2 node1 node14 node16 node18 node20} {} {} 1 15 {{} node2 node1 node15} {} {} 15 17 {{} node2 node1 node15 node17} {} {} 17 19 {{} node2 node1 node15 node17 node19} {} {} 19 21 {{} node2 node1 node15 node17 node19 node21} {} {} 0 3 {{} node3} {} {} 0 4 {{} node4} {} {} 0 5 {{} node5} {} {} 5 13 {{} node5 node13} {} {} 0 6 {{} node6} {} {} 0 8 {{} myLabel} {} {} }} test tree.296 {tree1 attach tree0} { list [catch { blt::tree create tree1 attach tree0 tree1 dump 0 } msg] $msg } {0 {-1 0 {{}} {} {tag2 newTag} 0 2 {{} node2} {} {tag2 newTag} 2 1 {{} node2 node1} {} {tag2 newTag} 1 14 {{} node2 node1 node14} {} {} 14 16 {{} node2 node1 node14 node16} {} {} 16 18 {{} node2 node1 node14 node16 node18} {} {} 18 20 {{} node2 node1 node14 node16 node18 node20} {} {} 1 15 {{} node2 node1 node15} {} {} 15 17 {{} node2 node1 node15 node17} {} {} 17 19 {{} node2 node1 node15 node17 node19} {} {} 19 21 {{} node2 node1 node15 node17 node19 node21} {} {} 0 3 {{} node3} {} {tag2 newTag} 0 4 {{} node4} {} {tag2 newTag} 0 5 {{} node5} {} {newTag myTag} 5 13 {{} node5 node13} {} {newTag} 0 6 {{} node6} {} {newTag} 0 8 {{} myLabel} {} {thisTag newTag} }} test tree.297 {tree1 attach ""} { list [catch {tree1 attach ""} msg] $msg } {0 {}} test tree.298 {blt::tree destroy tree1} { list [catch {blt::tree destroy tree1} msg] $msg } {0 {}} test tree.299 {tree0 find root -badSwitch} { list [catch {tree0 find root -badSwitch} msg] $msg } {1 {unknown switch "-badSwitch" following switches are available: -addtag tagName -count number -depth number -exact string -excludes nodes -exec command -glob pattern -invert -key string -keyexact string -keyglob pattern -keyregexp pattern -leafonly -nocase -order order -path -regexp pattern -tag {?tag?...}}} test tree.300 {tree0 find root -order} { list [catch {tree0 find root -order} msg] $msg } {1 {value for "-order" missing}} test tree.301 {tree0 find root ...} { list [catch {tree0 find root -order preorder -order postorder -order inorder} msg] $msg } {0 {20 18 16 14 1 21 19 17 15 2 0 3 4 13 5 6 8}} test tree.302 {tree0 find root -order preorder} { list [catch {tree0 find root -order preorder} msg] $msg } {0 {0 2 1 14 16 18 20 15 17 19 21 3 4 5 13 6 8}} test tree.303 {tree0 find root -order postorder} { list [catch {tree0 find root -order postorder} msg] $msg } {0 {20 18 16 14 21 19 17 15 1 2 3 4 13 5 6 8 0}} test tree.304 {tree0 find root -order inorder} { list [catch {tree0 find root -order inorder} msg] $msg } {0 {20 18 16 14 1 21 19 17 15 2 0 3 4 13 5 6 8}} test tree.305 {tree0 find root -order breadthfirst} { list [catch {tree0 find root -order breadthfirst} msg] $msg } {0 {0 2 3 4 5 6 8 1 13 14 15 16 17 18 19 20 21}} test tree.306 {tree0 set all key1 myValue} { list [catch {tree0 set all key1 myValue} msg] $msg } {0 {}} test tree.307 {tree0 set 15 key1 123} { list [catch {tree0 set 15 key1 123} msg] $msg } {0 {}} test tree.308 {tree0 set 16 key1 1234 key2 abc} { list [catch {tree0 set 16 key1 123 key2 abc} msg] $msg } {0 {}} test tree.309 {tree0 find root -key } { list [catch {tree0 find root -key} msg] $msg } {1 {value for "-key" missing}} test tree.310 {tree0 find root -key noKey} { list [catch {tree0 find root -key noKey} msg] $msg } {0 {}} test tree.311 {tree0 find root -key key1} { list [catch {tree0 find root -key key1} msg] $msg } {0 {20 18 16 14 21 19 17 15 1 2 3 4 13 5 6 8 0}} test tree.312 {tree0 find root -key key2} { list [catch {tree0 find root -key key2} msg] $msg } {0 16} test tree.313 {tree0 find root -key key2 -exact notThere } { list [catch {tree0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test tree.314 {tree0 find root -key key1 -glob notThere } { list [catch {tree0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test tree.315 {tree0 find root -key badKey -regexp notThere } { list [catch {tree0 find root -key key2 -exact notThere } msg] $msg } {0 {}} test tree.316 {tree0 find root -key key1 -glob 12*} { list [catch {tree0 find root -key key1 -glob 12*} msg] $msg } {0 {16 15}} test tree.317 {tree0 sort} { list [catch {tree0 sort} msg] $msg } {1 {wrong # args: should be "tree0 sort node ?flags...?"}} test tree.318 {tree0 sort all} { list [catch {tree0 sort all} msg] $msg } {1 {more than one node tagged as "all"}} test tree.319 {tree0 sort -recurse} { list [catch {tree0 sort -recurse} msg] $msg } {1 {can't find tag or id "-recurse" in ::tree0}} test tree.320 {tree0 sort 0} { list [catch {tree0 sort 0} msg] $msg } {0 {8 2 3 4 5 6}} test tree.321 {tree0 sort 0 -recurse} { list [catch {tree0 sort 0 -recurse} msg] $msg } {0 {0 8 1 2 3 4 5 6 13 14 15 16 17 18 19 20 21}} test tree.322 {tree0 sort 0 -decreasing -key} { list [catch {tree0 sort 0 -decreasing -key} msg] $msg } {1 {value for "-key" missing}} test tree.323 {tree0 sort 0 -re} { list [catch {tree0 sort 0 -re} msg] $msg } {1 {ambiguous switch "-re" following switches are available: -ascii -command command -decreasing -dictionary -integer -key string -path -real -recurse -reorder }} test tree.324 {tree0 sort 0 -decreasing} { list [catch {tree0 sort 0 -decreasing} msg] $msg } {0 {6 5 4 3 2 8}} test tree.325 {tree0 sort 0} { list [catch { set list {} foreach n [tree0 sort 0] { lappend list [tree0 label $n] } set list } msg] $msg } {0 {myLabel node2 node3 node4 node5 node6}} test tree.326 {tree0 sort 0 -decreasing} { list [catch {tree0 sort 0 -decreasing} msg] $msg } {0 {6 5 4 3 2 8}} test tree.327 {tree0 sort 0 -decreasing -key} { list [catch {tree0 sort 0 -decreasing -key} msg] $msg } {1 {value for "-key" missing}} test tree.328 {tree0 sort 0 -decreasing -key key1} { list [catch {tree0 sort 0 -decreasing -key key1} msg] $msg } {0 {8 6 5 4 3 2}} test tree.329 {tree0 sort 0 -decreasing -recurse -key key1} { list [catch {tree0 sort 0 -decreasing -recurse -key key1} msg] $msg } {0 {15 16 0 1 2 3 4 5 6 8 13 14 17 18 19 20 21}} test tree.330 {tree0 sort 0 -decreasing -key key1} { list [catch { set list {} foreach n [tree0 sort 0 -decreasing -key key1] { lappend list [tree0 get $n key1] } set list } msg] $msg } {0 {myValue myValue myValue myValue myValue myValue}} test tree.331 {tree0 index 1->firstchild} { list [catch {tree0 index 1->firstchild} msg] $msg } {0 14} test tree.332 {tree0 index root->firstchild} { list [catch {tree0 index root->firstchild} msg] $msg } {0 2} test tree.333 {tree0 label root->parent} { list [catch {tree0 label root->parent} msg] $msg } {1 {can't find tag or id "root->parent" in ::tree0}} test tree.334 {tree0 index root->parent} { list [catch {tree0 index root->parent} msg] $msg } {0 -1} test tree.335 {tree0 index root->lastchild} { list [catch {tree0 index root->lastchild} msg] $msg } {0 8} test tree.336 {tree0 index root->next} { list [catch {tree0 index root->next} msg] $msg } {0 2} test tree.337 {tree0 index root->previous} { list [catch {tree0 index root->previous} msg] $msg } {0 -1} test tree.338 {tree0 label root->previous} { list [catch {tree0 label root->previous} msg] $msg } {1 {can't find tag or id "root->previous" in ::tree0}} test tree.339 {tree0 index 1->previous} { list [catch {tree0 index 1->previous} msg] $msg } {0 2} test tree.340 {tree0 label root->badModifier} { list [catch {tree0 label root->badModifier} msg] $msg } {1 {can't find tag or id "root->badModifier" in ::tree0}} test tree.341 {tree0 index root->badModifier} { list [catch {tree0 index root->badModifier} msg] $msg } {0 -1} test tree.342 {tree0 index root->firstchild->parent} { list [catch {tree0 index root->firstchild->parent} msg] $msg } {0 0} test tree.343 {tree0 trace} { list [catch {tree0 trace} msg] $msg } {1 {wrong # args: should be one of... tree0 trace create node key how command ?-whenidle? tree0 trace delete id... tree0 trace info id tree0 trace names }} test tree.344 {tree0 trace create} { list [catch {tree0 trace create} msg] $msg } {1 {wrong # args: should be "tree0 trace create node key how command ?-whenidle?"}} test tree.345 {tree0 trace create root} { list [catch {tree0 trace create root} msg] $msg } {1 {wrong # args: should be "tree0 trace create node key how command ?-whenidle?"}} test tree.346 {tree0 trace create root * } { list [catch {tree0 trace create root * } msg] $msg } {1 {wrong # args: should be "tree0 trace create node key how command ?-whenidle?"}} test tree.347 {tree0 trace create root * rwuc} { list [catch {tree0 trace create root * rwuc} msg] $msg } {1 {wrong # args: should be "tree0 trace create node key how command ?-whenidle?"}} proc Doit args { global mylist; lappend mylist $args } test tree.348 {tree0 trace create all newKey rwuc Doit} { list [catch {tree0 trace create all newKey rwuc Doit} msg] $msg } {0 trace0} test tree.349 {tree0 trace info trace0} { list [catch {tree0 trace info trace0} msg] $msg } {0 {all newKey rwuc Doit}} test tree.350 {test create trace} { list [catch { set mylist {} tree0 set all newKey 20 set mylist } msg] $msg } {0 {{::tree0 0 newKey wc} {::tree0 2 newKey wc} {::tree0 1 newKey wc} {::tree0 14 newKey wc} {::tree0 16 newKey wc} {::tree0 18 newKey wc} {::tree0 20 newKey wc} {::tree0 15 newKey wc} {::tree0 17 newKey wc} {::tree0 19 newKey wc} {::tree0 21 newKey wc} {::tree0 3 newKey wc} {::tree0 4 newKey wc} {::tree0 5 newKey wc} {::tree0 13 newKey wc} {::tree0 6 newKey wc} {::tree0 8 newKey wc}}} test tree.351 {test read trace} { list [catch { set mylist {} tree0 get root newKey set mylist } msg] $msg } {0 {{::tree0 0 newKey r}}} test tree.352 {test write trace} { list [catch { set mylist {} tree0 set all newKey 21 set mylist } msg] $msg } {0 {{::tree0 0 newKey w} {::tree0 2 newKey w} {::tree0 1 newKey w} {::tree0 14 newKey w} {::tree0 16 newKey w} {::tree0 18 newKey w} {::tree0 20 newKey w} {::tree0 15 newKey w} {::tree0 17 newKey w} {::tree0 19 newKey w} {::tree0 21 newKey w} {::tree0 3 newKey w} {::tree0 4 newKey w} {::tree0 5 newKey w} {::tree0 13 newKey w} {::tree0 6 newKey w} {::tree0 8 newKey w}}} test tree.353 {test unset trace} { list [catch { set mylist {} tree0 set all newKey 21 set mylist } msg] $msg } {0 {{::tree0 0 newKey w} {::tree0 2 newKey w} {::tree0 1 newKey w} {::tree0 14 newKey w} {::tree0 16 newKey w} {::tree0 18 newKey w} {::tree0 20 newKey w} {::tree0 15 newKey w} {::tree0 17 newKey w} {::tree0 19 newKey w} {::tree0 21 newKey w} {::tree0 3 newKey w} {::tree0 4 newKey w} {::tree0 5 newKey w} {::tree0 13 newKey w} {::tree0 6 newKey w} {::tree0 8 newKey w}}} test tree.354 {tree0 trace delete} { list [catch {tree0 trace delete} msg] $msg } {0 {}} test tree.355 {tree0 trace delete badId} { list [catch {tree0 trace delete badId} msg] $msg } {1 {unknown trace "badId"}} test tree.356 {tree0 trace delete trace0} { list [catch {tree0 trace delete trace0} msg] $msg } {0 {}} test tree.357 {test create trace} { list [catch { set mylist {} tree0 set all newKey 20 set mylist } msg] $msg } {0 {}} test tree.358 {test unset trace} { list [catch { set mylist {} tree0 unset all newKey set mylist } msg] $msg } {0 {}} test tree.359 {tree0 notify} { list [catch {tree0 notify} msg] $msg } {1 {wrong # args: should be one of... tree0 notify create ?flags? command tree0 notify delete notifyId... tree0 notify info notifyId tree0 notify names }} test tree.360 {tree0 notify create} { list [catch {tree0 notify create} msg] $msg } {1 {wrong # args: should be "tree0 notify create ?flags? command"}} test tree.361 {tree0 notify create -allevents} { list [catch {tree0 notify create -allevents Doit} msg] $msg } {0 notify0} test tree.362 {tree0 notify info notify0} { list [catch {tree0 notify info notify0} msg] $msg } {0 {notify0 {-create -delete -move -sort -relabel} {Doit}}} test tree.363 {tree0 notify info badId} { list [catch {tree0 notify info badId} msg] $msg } {1 {unknown notify name "badId"}} test tree.364 {tree0 notify info} { list [catch {tree0 notify info} msg] $msg } {1 {wrong # args: should be "tree0 notify info notifyId"}} test tree.365 {tree0 notify names} { list [catch {tree0 notify names} msg] $msg } {0 notify0} test tree.366 {test create notify} { list [catch { set mylist {} tree0 insert 1 -tags test set mylist } msg] $msg } {0 {{-create 22}}} test tree.367 {test move notify} { list [catch { set mylist {} tree0 move 8 test set mylist } msg] $msg } {0 {{-move 8}}} test tree.368 {test sort notify} { list [catch { set mylist {} tree0 sort 0 -reorder set mylist } msg] $msg } {0 {{-sort 0}}} test tree.369 {test relabel notify} { list [catch { set mylist {} tree0 label test "newLabel" set mylist } msg] $msg } {0 {{-relabel 22}}} test tree.370 {test delete notify} { list [catch { set mylist {} tree0 delete test set mylist } msg] $msg } {0 {{-delete 8} {-delete 22}}} test tree.371 {tree0 notify delete badId} { list [catch {tree0 notify delete badId} msg] $msg } {1 {unknown notify name "badId"}} test tree.372 {test create notify} { list [catch { set mylist {} tree0 set all newKey 20 set mylist } msg] $msg } {0 {}} test tree.373 {test delete notify} { list [catch { set mylist {} tree0 unset all newKey set mylist } msg] $msg } {0 {}} test tree.374 {test delete notify} { list [catch { set mylist {} tree0 unset all newKey set mylist } msg] $msg } {0 {}} test tree.375 {tree0 copy} { list [catch {tree0 copy} msg] $msg } {1 {wrong # args: should be "tree0 copy parent ?tree? node ?switches?"}} test tree.376 {tree0 copy root} { list [catch {tree0 copy root} msg] $msg } {1 {wrong # args: should be "tree0 copy parent ?tree? node ?switches?"}} test tree.377 {tree0 copy root 14} { list [catch {tree0 copy root 14} msg] $msg } {0 23} test tree.378 {tree0 copy 14 root} { list [catch {tree0 copy 14 root} msg] $msg } {0 24} test tree.379 {tree0 copy 14 root -recurse} { list [catch {tree0 copy 14 root -recurse} msg] $msg } {1 {can't make cyclic copy: source node is an ancestor of the destination}} test tree.380 {tree0 copy 3 2 -recurse -tags} { list [catch {tree0 copy 3 2 -recurse -tags} msg] $msg } {0 25} test tree.381 {copy tree to tree -recurse} { list [catch { blt::tree create tree1 foreach node [tree0 children root] { tree1 copy root tree0 $node -recurse } foreach node [tree0 children root] { tree1 copy root tree0 $node -recurse } tree1 dump root } msg] $msg } {0 {-1 0 {{}} {} {} 0 1 {{} node2} {key1 myValue} {} 1 2 {{} node2 node1} {key1 myValue} {} 2 3 {{} node2 node1 node14} {key1 myValue} {} 3 4 {{} node2 node1 node14 node16} {key1 123 key2 abc} {} 4 5 {{} node2 node1 node14 node16 node18} {key1 myValue} {} 5 6 {{} node2 node1 node14 node16 node18 node20} {key1 myValue} {} 3 7 {{} node2 node1 node14 {}} {key1 myValue} {} 2 8 {{} node2 node1 node15} {key1 123} {} 8 9 {{} node2 node1 node15 node17} {key1 myValue} {} 9 10 {{} node2 node1 node15 node17 node19} {key1 myValue} {} 10 11 {{} node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 12 {{} node3} {key1 myValue} {} 12 13 {{} node3 node2} {key1 myValue} {} 13 14 {{} node3 node2 node1} {key1 myValue} {} 14 15 {{} node3 node2 node1 node14} {key1 myValue} {} 15 16 {{} node3 node2 node1 node14 node16} {key1 123 key2 abc} {} 16 17 {{} node3 node2 node1 node14 node16 node18} {key1 myValue} {} 17 18 {{} node3 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 15 19 {{} node3 node2 node1 node14 {}} {key1 myValue} {} 14 20 {{} node3 node2 node1 node15} {key1 123} {} 20 21 {{} node3 node2 node1 node15 node17} {key1 myValue} {} 21 22 {{} node3 node2 node1 node15 node17 node19} {key1 myValue} {} 22 23 {{} node3 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 24 {{} node4} {key1 myValue} {} 0 25 {{} node5} {key1 myValue} {} 25 26 {{} node5 node13} {key1 myValue} {} 0 27 {{} node6} {key1 myValue} {} 0 28 {{} node14} {key1 myValue} {} 0 29 {{} node2} {key1 myValue} {} 29 30 {{} node2 node1} {key1 myValue} {} 30 31 {{} node2 node1 node14} {key1 myValue} {} 31 32 {{} node2 node1 node14 node16} {key1 123 key2 abc} {} 32 33 {{} node2 node1 node14 node16 node18} {key1 myValue} {} 33 34 {{} node2 node1 node14 node16 node18 node20} {key1 myValue} {} 31 35 {{} node2 node1 node14 {}} {key1 myValue} {} 30 36 {{} node2 node1 node15} {key1 123} {} 36 37 {{} node2 node1 node15 node17} {key1 myValue} {} 37 38 {{} node2 node1 node15 node17 node19} {key1 myValue} {} 38 39 {{} node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 40 {{} node3} {key1 myValue} {} 40 41 {{} node3 node2} {key1 myValue} {} 41 42 {{} node3 node2 node1} {key1 myValue} {} 42 43 {{} node3 node2 node1 node14} {key1 myValue} {} 43 44 {{} node3 node2 node1 node14 node16} {key1 123 key2 abc} {} 44 45 {{} node3 node2 node1 node14 node16 node18} {key1 myValue} {} 45 46 {{} node3 node2 node1 node14 node16 node18 node20} {key1 myValue} {} 43 47 {{} node3 node2 node1 node14 {}} {key1 myValue} {} 42 48 {{} node3 node2 node1 node15} {key1 123} {} 48 49 {{} node3 node2 node1 node15 node17} {key1 myValue} {} 49 50 {{} node3 node2 node1 node15 node17 node19} {key1 myValue} {} 50 51 {{} node3 node2 node1 node15 node17 node19 node21} {key1 myValue} {} 0 52 {{} node4} {key1 myValue} {} 0 53 {{} node5} {key1 myValue} {} 53 54 {{} node5 node13} {key1 myValue} {} 0 55 {{} node6} {key1 myValue} {} 0 56 {{} node14} {key1 myValue} {} }} puts stderr "done testing treecmd.tcl" exit 0 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/tests/renumber.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000613�11462120063�015724� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set infile [lindex $argv 0] set outfile [lindex $argv 1] set f [open $infile "r"] set data [read $f] close $f set test [file root [file tail $infile]] set f [open $outfile "w"] set count 1 set pattern [subst -nocommands {^test ${test}\.[a-z0-9]+ }] foreach line [split $data \n] { if { [regsub $pattern $line "test ${test}.${count} " line] } { incr count } puts $f $line } close $f���������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013005� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/BLT.mann����������������������������������������������������������������������0000644�0001750�0001750�00000014713�11462120062�014313� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" .so man.macros .TH intro n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME BLT \- Introduction to the BLT library .BE .SH DESCRIPTION BLT is a library of extensions to the Tk library. It adds new commands and variables to the application's interpreter. .LP .SH COMMANDS The following commands are added to the interpreter from the BLT library: .TP 15 \fBtable\fR A table geometry manager for Tk. You specify window placements as table row,column positions and windows can also span multiple rows or columns. It also has many options for setting and/or bounding window sizes. .TP 15 \fBgraph\fR A 2D plotting widget. Plots two variable data in a window with an optional legend and annotations. It has of several components; coordinate axes, crosshairs, a legend, and a collection of elements and tags. .TP 15 \fBbarchart\fR A barchart widget. Plots two-variable data as rectangular bars in a window. The x-coordinate values designate the position of the bar along the x-axis, while the y-coordinate values designate the magnitude. The \fBbarchart\fR widget has of several components; coordinate axes, crosshairs, a legend, and a collection of elements and tags. .TP 15 \fBvector\fR Creates a vector of floating point values. The vector's components can be manipulated in three ways: through a Tcl array variable, a Tcl command, or the C API. .TP \fBspline\fR Computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. .TP 15 \fBbgexec\fR Like Tcl's \fBexec\fR command, \fBbgexec\fR runs a pipeline of Unix commands in the background. Unlike \fBexec\fR, the output of the last process is collected and a global Tcl variable is set upon its completion. \fBbgexec\fR can be used with \fBtkwait\fR to wait for Unix commands to finish while still handling expose events. Intermediate output is also available while the pipeline is active. .TP 15 \fBbusy\fR Creates a "busy window" which prevents user-interaction when an application is busy. The busy window also provides an easy way to have temporary busy cursors (such as a watch or hourglass). .TP 15 \fBbitmap\fR Reads and writes bitmaps from Tcl. New X bitmaps can be defined on-the-fly from Tcl, obviating the need to copy around bitmap files. Other options query loaded X bitmap's dimensions and data. .TP 15 \fBdrag&drop\fR Provides a drag-and-drop facility for Tk. Information (represented by a token window) can be dragged to and from any Tk window, including those of another Tk application. \fBdrag&drop\fR acts as a coordinator, directing Tk \fBsend\fR commands between (or within) TCL/Tk applications. .TP 15 \fBhtext\fR A simple hypertext widget. Combines text and Tk widgets into a single scroll-able window. Tcl commands can be embedded into text, which are invoked as the text is parsed. In addition, Tk widgets can be appended to the window at the current point in the text. \fBHtext\fR can be also used to create scrolled windows of Tk widgets. .TP 15 \fBwinop\fR Raise, lower, map, or, unmap any window. The raise and lower functions are useful for stacking windows above or below "busy windows". .TP 15 \fBwatch\fR Arranges for Tcl procedures to be called before and/or after the execution of every Tcl command. This command may be used in the logging, profiling, or tracing of Tcl code. .TP 15 \fBbltdebug\fR A simple Tcl command tracing facility useful for debugging Tcl code. Displays each Tcl command before and after substitution along its level in the interpreter on standard error. .SH VARIABLES .PP The following Tcl variables are either set or used by BLT at various times in its execution: .TP 15 \fBblt_library\fR This variable contains the name of a directory containing a library of Tcl scripts and other files related to BLT. Currently, this directory contains the \fBdrag&drop\fR protocol scripts and the PostScript prolog used by \fBgraph\fR and \fBbarchart\fR. The value of this variable is taken from the BLT_LIBRARY environment variable, if one exists, or else from a default value compiled into the \fBBLT\fR library. .TP 15 \fBblt_versions\fR This variable is set in the interpreter for each application. It is an array of the current version numbers for each of the BLT commands in the form \fImajor\fR.\fIminor\fR. \fIMajor\fR and \fIminor\fR are integers. The major version number increases in any command that includes changes that are not backward compatible (i.e. whenever existing applications and scripts may have to change to work with the new release). The minor version number increases with each new release of a command, except that it resets to zero whenever the major version number changes. The array is indexed by the individual command name. .SH ADDING BLT TO YOUR APPLICATIONS It's easy to add BLT to an existing Tk application. BLT requires no patches or edits to the Tcl or Tk libraries. To add BLT, simply add the following code snippet to your application's tkAppInit.c file. .CS if (Blt_Init(interp) != TCL_OK) { return TCL_ERROR; } .CE Recompile and link with the BLT library (libBLT.a) and that's it. .PP Alternately, you can dynamically load BLT, simply by invoking the command .CS package require BLT .CE from your Tcl script. .SH BUGS Send bug reports, requests, suggestions, etc. to gah@siliconmetrics.com or ghowlett@grandecom.net .SH KEYWORDS BLT �����������������������������������������������������./saods9/blt3.0.1/man/eps.mann����������������������������������������������������������������������0000644�0001750�0001750�00000014776�11462120062�014472� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Graph widget created by Sani Nassif and George Howlett. '\" .so man.macros .TH eps n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME eps \- Encapsulated PostScript canvas item. .SH SYNOPSIS \fIcanvas\fB create eps \fIx y \fR?\fIoption value\fR?... .BE .SH DESCRIPTION The \fBeps\fR canvas item lets you place encapulated PostScript (EPS) on a canvas, controlling its size and placement. The EPS item is displayed either as a solid rectangle or a preview image. The preview image is designated in one of two ways: 1) the EPS file contains an ASCII hexidecimal preview, or 2) a Tk photo image. When the canvas generates PostScript output, the EPS will be inserted with the proper translation and scaling to match that of the EPS item. So can use the canvas widget as a page layout tool. .SH EXAMPLE Let's say you have for PostScript files of four graphs which you want to tile two-by-two on a single page. Maybe you'd like to annotate the graphs by putting a caption at the bottom of each graph. .PP Normally, you would have to resort to an external tool or write your own PostScript program. The \fBeps\fR canvas item lets you do this through Tk's canvas widget. An \fBeps\fR item displays an image (or rectangle) representing the encapsulated PostScript file. It also scales and translates the EPS file when the canvas is printed. .SH SYNTAX .DS \fIcanvas \fBcreate eps \fIx y \fR?\fIoption value\fR?... .DE The \fBeps\fR item creates a new canvas item. \fICanvas\fR is the name of a \fBcanvas\fR widget. You must supply the X-Y coordinate of the new eps item. How the coordinate is exactly interpretered is controlled by the \fB\-anchor\fR option (see below). .PP Additional options may be specified on the command line to configure aspects of the eps item such as its color, stipple, and font. The following \fIoption\fR and \fIvalue\fR pairs are valid. .TP \fB\-anchor \fIanchor\fR Tells how to position the EPS item relative to its X-Y coordinate. The default is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Sets the background color of the EPS rectangle. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the item. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW0\fR. .TP \fB\-file \fIfileName\fR Specifies the name of the EPS file. The first line of an EPS file must start with "%!PS" and contain a "EPS" version specification. The other requirement is that there be a "%%BoundingBox:" entry which contains four integers representing the lower-left and upper-right coordinates of the area bounding the EPS. The default is \f(CW""\fR. .TP \fB\-font \fIfontName\fR Specifies the font of the title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR. .TP \fB\-foreground \fIcolor\fR Specifies the foreground color of the EPS rectangle. The option matters only when the \fB\-stipple\fR option is set. The default is \f(CWwhite\fR. .TP \fB\-height \fIpixels\fR Specifies the height EPS item. If \fIpixels\fR is \f(CW0\fR, then the height is determined from the PostScript "BoundingBox:" entry in the EPS file. The default is \f(CW0\fR. .TP \fB\-image \fIphoto\fR Specifies the name of a Tk photo image to be displayed as in the item as a preview image. This option overrides any preview specification found in the EPS file. The default is \f(CW""\fR. .TP \fB\-justify \fIjustify\fR Specifies how the title should be justified. This matters only when the title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the EPS item. \fIRelief\fR specifies how the item should appear relative to canvas; for example, \f(CWraised\fR means the item should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-shadowcolor \fIcolor\fR Specifies the color of the drop shadow used for the title. The option with the \fB\-shadowoffset\fR option control how the title's drop shadow appears. The default is \f(CWgrey\fR. .TP \fB\-shadowoffset \fIpixels\fR Specifies the offset of the drop shadow from the title's text. If \fIpixels\fR is \f(CW0\fR, no shadow will be seen. The default is \f(CW0\fR. .TP \fB\-showimage \fIboolean\fR Indicates whether to display the image preview (if one exists), or a simple rectangle. The default is \f(CWyes\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a bitmap to used to stipple the rectangle representing the EPS item. The default is \f(CW""\fR. .TP \fB\-title \fIstring\fR Sets the title of the EPS item. If \fIstring\fR is \f(CW""\fR, then the title specified by the PostScript "Title:" entry is used. You can set the string a single space to display no title. The default is \f(CW""\fR. .TP \fB\-titleanchor \fIanchor\fR Tells how to position the title within EPS item. The default is \f(CWn\fR. .TP \fB\-titlecolor \fIcolor\fR Specifies the color of the title. The default is \f(CWwhite\fR. .TP \fB\-titlerotate \fIdegrees\fR Sets the rotation of the title. \fIDegrees\fR is a real number representing the angle of rotation. The title is first rotated in space and then placed according to the \fB\-titleanchor\fR position. The default rotation is \f(CW0.0\fR. .TP \fB\-width \fIpixels\fR Specifies the width EPS item. If \fIpixels\fR is \f(CW0\fR, then the width is determined from the PostScript "BoundingBox:" entry in the EPS file. The default is \f(CW0\fR. \f(CW5i\fR. ��./saods9/blt3.0.1/man/man.macros��������������������������������������������������������������������0000644�0001750�0001750�00000011557�11462120062�015003� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" The definitions below are for supplemental macros used in Tcl/Tk '\" manual entries. '\" '\" .AP type name in/out ?indent? '\" Start paragraph describing an argument to a library procedure. '\" type is type of argument (int, etc.), in/out is either "in", "out", '\" or "in/out" to describe whether procedure reads or modifies arg, '\" and indent is equivalent to second arg of .IP (shouldn't ever be '\" needed; use .AS below instead) '\" '\" .AS ?type? ?name? '\" Give maximum sizes of arguments for setting tab stops. Type and '\" name are examples of largest possible arguments that will be passed '\" to .AP later. If args are omitted, default tab stops are used. '\" '\" .BS '\" Start box enclosure. From here until next .BE, everything will be '\" enclosed in one large box. '\" '\" .BE '\" End of box enclosure. '\" '\" .CS '\" Begin code excerpt. '\" '\" .CE '\" End code excerpt. '\" '\" .VS ?version? ?br? '\" Begin vertical sidebar, for use in marking newly-changed parts '\" of man pages. The first argument is ignored and used for recording '\" the version when the .VS was added, so that the sidebars can be '\" found and removed when they reach a certain age. If another argument '\" is present, then a line break is forced before starting the sidebar. '\" '\" .VE '\" End of vertical sidebar. '\" '\" .DS '\" Begin an indented unfilled display. '\" '\" .DE '\" End of indented unfilled display. '\" '\" .SO '\" Start of list of standard options for a Tk widget. The '\" options follow on successive lines, in four columns separated '\" by tabs. '\" '\" .SE '\" End of list of standard options for a Tk widget. '\" '\" .OP cmdName dbName dbClass '\" Start of description of a specific option. cmdName gives the '\" option's name as specified in the class command, dbName gives '\" the option's name in the option database, and dbClass gives '\" the option's class in the option database. '\" '\" .UL arg1 arg2 '\" Print arg1 underlined, then print arg2 normally. '\" '\" RCS: @(#) $Id: man.macros,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ '\" '\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. .if t .wh -1.3i ^B .nr ^l \n(.l .ad b '\" # Start an argument description .de AP .ie !"\\$4"" .TP \\$4 .el \{\ . ie !"\\$2"" .TP \\n()Cu . el .TP 15 .\} .ta \\n()Au \\n()Bu .ie !"\\$3"" \{\ \&\\$1 \\fI\\$2\\fP (\\$3) .\".b .\} .el \{\ .br .ie !"\\$2"" \{\ \&\\$1 \\fI\\$2\\fP .\} .el \{\ \&\\fI\\$1\\fP .\} .\} .. '\" # define tabbing values for .AP .de AS .nr )A 10n .if !"\\$1"" .nr )A \\w'\\$1'u+3n .nr )B \\n()Au+15n .\" .if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n .nr )C \\n()Bu+\\w'(in/out)'u+2n .. .AS Tcl_Interp Tcl_CreateInterp in/out '\" # BS - start boxed text '\" # ^y = starting y location '\" # ^b = 1 .de BS .br .mk ^y .nr ^b 1u .if n .nf .if n .ti 0 .if n \l'\\n(.lu\(ul' .if n .fi .. '\" # BE - end boxed text (draw box now) .de BE .nf .ti 0 .mk ^t .ie n \l'\\n(^lu\(ul' .el \{\ .\" Draw four-sided box normally, but don't draw top of .\" box if the box started on an earlier page. .ie !\\n(^b-1 \{\ \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .el \}\ \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .\} .fi .br .nr ^b 0 .. '\" # VS - start vertical sidebar '\" # ^Y = starting y location '\" # ^v = 1 (for troff; for nroff this doesn't matter) .de VS .if !"\\$2"" .br .mk ^Y .ie n 'mc \s12\(br\s0 .el .nr ^v 1u .. '\" # VE - end of vertical sidebar .de VE .ie n 'mc .el \{\ .ev 2 .nf .ti 0 .mk ^t \h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' .sp -1 .fi .ev .\} .nr ^v 0 .. '\" # Special macro to handle page bottom: finish off current '\" # box/sidebar if in box/sidebar mode, then invoked standard '\" # page bottom macro. .de ^B .ev 2 'ti 0 'nf .mk ^t .if \\n(^b \{\ .\" Draw three-sided box if this is the box's first page, .\" draw two sides but no top otherwise. .ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .\} .if \\n(^v \{\ .nr ^x \\n(^tu+1v-\\n(^Yu \kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c .\} .bp 'fi .ev .if \\n(^b \{\ .mk ^y .nr ^b 2 .\} .if \\n(^v \{\ .mk ^Y .\} .. '\" # DS - begin display .de DS .RS .nf .sp .. '\" # DE - end display .de DE .fi .RE .sp .. '\" # SO - start of list of standard options .de SO .SH "STANDARD OPTIONS" .LP .nf .ta 4c 8c 12c .ft B .. '\" # SE - end of list of standard options .de SE .fi .ft R .LP See the \\fBoptions\\fR manual entry for details on the standard options. .. '\" # OP - start of full description for a single option .de OP .LP .nf .ta 4c Command-Line Name: \\fB\\$1\\fR Database Name: \\fB\\$2\\fR Database Class: \\fB\\$3\\fR .fi .IP .. '\" # CS - begin code excerpt .de CS .RS .nf .ta .25i .5i .75i 1i .ft CW .sp .. '\" # CE - end code excerpt .de CE .fi .RE .ft R .sp .. .de UL \\$1\l'|0\(ul'\\$2 .. �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/htext.mann��������������������������������������������������������������������0000644�0001750�0001750�00000041447�11462120062�015032� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Hypertext widget created by George Howlett. '\" .so man.macros .TH htext n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME htext \- Create and manipulate hypertext widgets .SH SYNOPSIS \fBhtext\fP \fIpathName \fR?\fIoption value\fR?... .BE .SH DESCRIPTION .PP The \fBhtext\fR command creates a new window (given by the \fIpathName\fR argument) and makes it into a \fBhtext\fP widget. Additional options, described above, may be specified on the command line or in the option database to configure aspects of the widget such as its color and font. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. The \fBhtext\fR command returns its \fIpathName\fR. .PP The \fBhtext\fP widget is hybrid of a non-editable text widget and a geometry manager (e.g. the packer). It displays text (optionally read from file) in a window. Text can be scrolled either horizontally or vertically using the \fBhtext\fR window as a viewport. In addition, Tcl commands can be embedded into the text which are evaluated as the text is parsed. Text between special double characters (percent signs "%%") is immediately passed to the Tcl interpreter for evaluation. .PP Furthermore, any widget or widget hierarchy can be packed in-line and made to appear on the current line of the text. Widgets are packed using the \fBhtext append\fP command. All widgets must be children of the \fBhtext\fP window and must already exist before packing. Once a widget has been packed it cannot be moved to a different position within the text. Widgets can be resized but they will remain at the same position within the text. .PP Before a file or text string is parsed by the \fBhtext\fR widget, all the widget's current children are destroyed. You can reload files or text without worrying about unmapping or destroying each child window beforehand. .PP Setting the either the \fB\-filename\fR or \fB\-text\fR configuration option will adjust the value of the other. If both options are set, the file takes precedence. When a new file is read using the \fB\-filename\fR option, the value of the \fB\-text\fR option is reset to the empty string. Likewise, when the \fB\-text\fR option is set, the string representing the \fB\-filename\fR option is cleared. .SH FILE FORMAT The format of \fBhtext\fP text file is typically ASCII text. Text enclosed by special double characters (by default, percent signs '%%') is interpreted and executed as Tcl commands. The special character may be specified by the \fB\-specialchar\fP option. In the following example of a \fBhtext\fP file, a button widget is appended to the text between the words "\f(CWa\fP" and "\f(CWwhich\fP". The \fIpathName\fR of the \fBhtext\fP widget is "\f(CW.ht\fP". .CS \f(CWThis will be displayed as normal text. But this will become a %% button .ht.button -text "button" -fg red .ht append .ht.button %% which can invoke a Tcl command.\fR .CE .LP .SH INDICES .PP Some of the widget operations (\fBselection\fR, \fRgotoline\fR, \fBsearch\fR, etc.) take one or more indices as arguments. An index is a string used to indicate a particular place within the text, such as the first and last characters in a range to be selected. .LP An index must have one of the following forms: .TP 12 \fIline\fB.\fIchar\fR Indicates \fIchar\fR'th character on line \fIline\fR. Both lines and characters are number from 0, so "0.0" is the first beginning of the text. \fIChar\fR may be undesignated. In this case a character position of 0 is assumed. .TP 12 \fB@\fIx\fB,\fIy\fR Indicates the character that covers the pixel whose x and y coordinates within the text's window are \fIx\fR and \fIy\fR. .TP 12 \fBend\fR Indicates the end of the text. .TP 12 \fBanchor\fR Indicates the anchor point for the selection, which is set with the \fBselection\fR operation. .TP 12 \fBsel.first\fR Indicates the first character in the selection. It is an error to use this form if the selection isn't in the entry window. .TP 12 \fBsel.last\fR .VS Indicates the character just after the last one in the selection. .VE It is an error to use this form if the selection isn't in the entry window. .SH "VARIABLES" .PP The following global Tcl variables are maintained when an \fBhtext\fR file is parsed. .TP \fBhtext(widget)\fR is the pathname of the \fBhtext\fP widget. .TP \fBhtext(file)\fR is the name of the file the \fBhtext\fP widget is currently parsing. It is the empty string when the \fB\-text\fP option is used. .TP \fBhtext(line)\fR is the current line number in the text. .PP This information might be used to construct hyper links between different files and/or lines. .LP .SH "SYNTAX" The \fBhtext\fP command creates a new Tcl command whose name is \fIpathName\fR. This command may be used to invoke various operations on the widget. It has the following general form: .DS \fIpathName oper \fR?\fIargs\fR? .DE \fIOper\fR and \fIargs\fR determine the exact behavior of the command. .PP .SH "OPERATIONS" The following operations are available for \fBhtext\fP widgets: .TP \fIpathName \fBappend \fIwindow \fR?\fIoption value\fR?... Embeds the widget \fIwindow\fP into the htext widget. \fIWindow\fP is the pathname of the widget to be embedded which must be a child of \fIpathName\fR. \fIWindow\fR will be positioned in the htext widget at the current location of the text. If \fIoption\fR and \fIvalue\fR pairs are present, they configure various aspects how \fIwindow\fR appears in \fIpathName\fR. The following options are available. .RS .TP \fB\-anchor \fIanchorPos\fR Specifies how \fIwindow\fR will be arranged if there is any extra space in the cavity surrounding the window. For example, if \fIanchorPos\fR is \fBcenter\fR then the window is centered in the cavity; if \fIanchorPos\fR is \fBw\fR then the window will be drawn such it touches the leftmost edge of the cavity. The default is \f(CWcenter\fR. .TP \fB\-fill \fIstyle\fR Specifies how the \fIwindow\fR should be stretched to occupy the extra space in the cavity surrounding it (if any exists). \fIStyle\fR is \f(CWnone\fR, \f(CWx\fR, \f(CWy\fR, \f(CWboth\fR. If \fIstyle\fR is \f(CWx\fR, the width of \fIwindow\fR is expanded to fill the cavity. If \fIstyle\fR is \fBy\fR, the height is expanded. The default is \f(CWnone\fR. .TP \fB\-height \fIpixels\fR Sets the height of the cavity surrounding \fIwindow\fR. If \fIpixels\fP is zero, the height of the cavity will be the same as the requested height of \fIwindow\fR. If \fIpixels\fR is less than the requested height of \fIwindow\fR, \fIwindow\fR will be reduced to fit the cavity. The default is \f(CW0\fR. .TP \fB\-ipadx \fIpad\fR Sets the amount of internal padding to be added to the width \fIwindow\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the left side of \fIwindow\fR is extended by the first value and the right side by the second value. If \fIpad\fR is just one value, both the left and right sides are padded by evenly by the value. The default is \f(CW0\fR. .TP \fB\-ipady \fIpad\fR Sets an amount of internal padding to be added to the height of \fIwindow\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the top of \fIwindow\fR is padded by the first value and the bottom by the second value. If \fIpad\fR is just one number, both the top and bottom are padded evenly by the value. The default is \f(CW0\fR. .TP \fB\-justify \fIjustify\fR Justifies \fIwindow\fR vertically within the cavity containing it in relation to the line of text. \fIJustify\fR is \fBtop\fP, \fBbottom\fR, or \fBcenter\fR. If \fIjustify\fR is \f(CWcenter\fR the widget is centered along the baseline of the line of text. The default is \f(CWcenter\fR. .TP \fB\-padx \fIpad\fR Sets the padding on the left and right sides of \fIwindow\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the left side of \fIwindow\fR is padded by the first value and the right side by the second value. If \fIpad\fR has just one value, both the left and right sides are padded evenly by the value. The default is \f(CW0\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below \fIwindow\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the area above \fIwindow\fR is padded by the first value and the area below by the second value. If \fIpad\fR is just one number, both the top and bottom are padded by the value. The default is \f(CW0\fR. .TP \fB\-relheight \fIvalue\fR Specifies the height of the cavity containing \fIwindow\fR relative to the height of \fIpathName\fR. \fIValue\fP is real number indicating the ratio of the height of the cavity to the height of \fIpathName\fR. As the height of \fIpathName\fR changes, so will the height of \fIwindow\fR. If \fIvalue\fR is 0.0 or less, the height of the cavity is the requested height \fIwindow\fR. The default is \f(CW0.0\fR. .TP \fB\-relwidth \fIvalue\fR Specifies the width of the cavity containing \fIwindow\fR relative to the width of \fIpathName\fR. \fIValue\fP is real number indicating the ratio of the width of the cavity to the width of \IpathName\fR. As the height of \fIpathName\fR changes, so will the height of \fIwindow\fR. If \fIvalue\fR is 0.0 or less, the width of the cavity is the requested width of \fIwindow\fR. The default is \f(CW0.0\fR. .TP \fB\-width \fIvalue\fR Species the width of the cavity containing the child window. \fIValue\fP must be in a form accepted by \fBTk_GetPixels\fR. If \fIvalue\fP is greater than zero, the cavity is resized to that width. If the requested window width is greater than the cavity's width, the window will be reduced to fit the cavity. By default, the cavity is requested width of the child window. .RE .TP \fIpathName \fBconfigure\fR ?\fIwindow\fR? ?\fIoption\fR? ?\fIvalue option value ...\fR? Queries or modifies the configuration options of the text widget or one of its embedded widgets. If no \fIwindow\fR argument is present, the htext widget itself is configured. Otherwise \fIwindow\fR is the pathname of a widget already embedded into the htext widget. Then this command configure the options for the embedded widget. .PP If \fIoption\fR isn't specified, a list describing all of the current options for \fIpathName\fR or \fIwindow\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the option \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the htext or embedded window option \fIoption\fR is set to \fIvalue\fR. .PP The following options are valid for the htext widget. .RS .TP \fB\-background\fR \fIcolor\fI Sets the background of the htext widget to \fIcolor\fR. This default is \f(CWwhite\fR. .TP \fB\-cursor\fR \fIcursor\fR Specifies the cursor for the htext widget. The default cursor is \f(CWpencil\fR. .TP \fB\-filename\fR \fIfileName\fR Specifies a \fBhtext\fP file to be displayed in the window. If the value is the empty string, the \fB\-text\fR option is used instead. See the section .SB FILE FORMAT for a description of the \fBhtext\fP file format. .TP \fB\-font\fR \fIfontName\fR Sets the font of the text in the htext widget to \fIfontName\fR. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground\fR \fIcolor\fR Sets the foreground of the htext widget to \fIcolor\fR. This is the color of the text. This default is \f(CWblack\fR. .TP \fB\-height\fR \fIpixels\fR Specifies the height of the htext widget window. .TP \fB\-linespacing\fR \fIpixels\fR Specifies the spacing between each line of text. The value must be in a form accepted by \fBTk_GetPixels\fR. The default value is 1 pixel. .TP \fB\-specialchar\fR \fInumber\fR Specifies the ASCII value of the special double character delimiters. In \fBhtext\fP files, the text between these special characters is evaluated as a block of Tcl commands. The default special character is the \f(CW0x25\fR (percent sign). .TP \fB\-text\fR \fItext\fR Specifies the text to be displayed in the htext widget. \fIText\fR can be any valid string of characters. See .SB "FILE FORMAT" for a description. .TP \fB\-xscrollcommand\fR \fIstring\fR Specifies the prefix for a command used to communicate with horizontal scrollbars. When the view in the htext widget's window changes (or whenever anything else occurs that could change the display in a scrollbar, such as a change in the total size of the widget's contents), the widget invoke \fIstring\fR concatenated by two numbers. Each of the numbers is a fraction between 0 and 1, which indicates a position in the document. If this option is not specified, then no command will be executed. .TP \fB\-yscrollcommand\fR \fIstring\fR Specifies the prefix for a command used to communicate with vertical scrollbars. When the view in the htext widget's window changes (or whenever anything else occurs that could change the display in a scrollbar, such as a change in the total size of the widget's contents), the widget invoke \fIstring\fR concatenated by two numbers. Each of the numbers is a fraction between 0 and 1, which indicates a position in the document. If this option is not specified, then no command will be executed. .TP \fB\-width\fR \fIpixels\fR Specifies the desired width of the viewport window. If the \fIpixels\fR is less than one, the window will grow to accommodate the widest line of text. .TP \fB\-xscrollunits\fR \fIpixels\fR Specifies the horizontal scrolling distance. The default is 10 pixels. .TP \fB\-yscrollunits\fR \fIpixels\fR Specifies the vertical scrolling distance. The default is 10 pixels. .RE .TP \fIpathName \fBgotoline \fR?\fIindex\fR? Sets the top line of the text to \fIindex\fP. \fIIndex\fP must be a valid text index (the character offset is ignored). If an \fIindex\fP isn't provided, the current line number is returned. .TP \fIpathName \fBscan mark \fIposition\fR Records \fIposition\fR and the current view in the text window; used in conjunction with later \fBscan dragto\fR commands. \fIPosition\fR must be in the form "\fI@x,y\fR, where \fIx\fR and \fIy\fR are window coordinates. Typically this command is associated with a mouse button press in the widget. It returns an empty string. .TP \fIpathName \fBscan dragto \fIposition\fR Computes the difference between \fIposition\fR and the position registered in the last \fBscan mark\fR command for the widget. The view is then adjusted up or down by 10 times the difference in coordinates. This command is can be associated with mouse motion events to produce the effect of dragging the text at high speed through the window. \fIPosition\fR must be in the form "\fI@x,y\fR, where \fIx\fR and \fIy\fR are window coordinates. The command returns an empty string. .TP \fIpathName \fBsearch \fIpattern\fR ?\fIfrom\fR? ?\fIto\fR? Returns the number of the next line matching \fIpattern\fR. \fIPattern\fR is a string which obeys the matching rules of \fBTcl_StringMatch\fR. \fIFrom\fR and \fIto\fR are text line numbers (inclusive) which bound the search. If no match for \fIpattern\fR can be found, \fB-1\fR is returned. .TP \fIpathName \fBxview \fR?\fIposition\fR? Moves the viewport horizontally to the new text x-coordinate position. \fIPosition\fR is the offset from the left side of the text to the current position and must be in a form accepted by \fBTk_GetPixels\fR. If \fIposition\fR is not present, the current text position is returned. .TP \fIpathName \fByview \fR?\fIposition\fR? Moves the viewport vertically to the new text y-coordinate position. \fIPosition\fR is the offset from the top of the text to the current position and must be in a form accepted by \fBTk_GetPixels\fR. If \fIposition\fR is not present, the current text position is returned. .SH BUGS Text with embedded tabs can be obscured by child windows when scrolled horizontally. .SH KEYWORDS hypertext, widget �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/watch.mann��������������������������������������������������������������������0000644�0001750�0001750�00000012456�11462120062�015002� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH watch n BLT_VERSION BLT "BLT Built-In Commands" .BS .SH NAME watch \- call Tcl procedures before and after each command .SH SYNOPSIS \fBwatch create\fR \fIwatchName\fR ?\fIoptions\fR? .sp \fBwatch activate\fR \fIwatchName\fR .sp \fBwatch deactivate\fR \fIwatchName\fR .sp \fBwatch delete\fR \fIwatchName\fR .sp \fBwatch configure\fR \fIwatchName\fR ?\fIoptions\fR .sp \fBwatch info\fR \fIwatchName\fR .sp \fBwatch names\fR .BE .SH DESCRIPTION The \fBwatch\fR command arranges for Tcl procedures to be invoked before and after the execution of each Tcl command. .SH INTRODUCTION When an error occurs in Tcl, the global variable \fIerrorInfo\fR will contain a stack-trace of the active procedures when the error occured. Sometimes, however, the stack trace is insufficient. You may need to know exactly where in the program's execution the error occured. In cases like this, a more general tracing facility would be useful. .PP The \fBwatch\fR command lets you designate Tcl procedures to be invoked before and after the execution of each Tcl command. This means you can display the command line and its results for each command as it executes. Another use is to profile your Tcl commands. You can profile any Tcl command (like \fBif\fR and \fBset\fR), not just Tcl procedures. .SH EXAMPLE The following example use \fBwatch\fR to trace Tcl commands (printing to standard error) both before and after they are executed. .CS proc preCmd { level command argv } { set name [lindex $argv 0] puts stderr "$level $name => $command" } proc postCmd { level command argv retcode results } { set name [lindex $argv 0] puts stderr "$level $name => $argv\n<= ($retcode) $results" } watch create trace \\ -postcmd postCmd -precmd preCmd .CE .SH "OPERATIONS" The following operations are available for the \fBwatch\fR command: .TP \fBwatch activate \fIwatchName\fR Activates the watch, causing Tcl commands the be traced to the maximum depth selected. .TP \fBwatch create \fIwatchName\fR ?\fIoptions\fR?... Creates a new watch \fIwatchName\fR. It's an error if another watch \fIwatchName\fR already exists and an error message will be returned. \fIOptions\fR may have any of the values accepted by the \fBwatch configure\fR command. This command returns the empty string. .TP \fBwatch configure \fIwatchName\fR ?\fIoptions...\fR? Queries or modifies the configuration options of the watch \fIwatchName\fR. \fIWatchName\fR is the name of a watch. \fIOptions\fR may have any of the following values: .RS .TP \fB\-active \fIboolean\fR Specifies if the watch is active. By default, watches are active when created. .TP \fB\-postcmd \fIstring\fR Specifies a Tcl procedure to be called immediately after each Tcl command. \fIString\fR is name of a Tcl procedure and any extra arguments to be passed to it. Before \fIstring\fR is invoked, five more arguments are appended: 1) the current level 2) the current command line 3) a list containing the command after substitutions and split into words 4) the return code of the command, and 5) the results of the command. The return status of the postcmd procedure is always ignored. .TP \fB\-precmd \fIstring\fR Specifies a Tcl procedure to be called immediately before each Tcl command. \fIString\fR is name of a Tcl procedure and any extra arguments to be passed to it. Before \fIstring\fR is invoked, three arguments are appended: 1) the current level 2) the current command line, and 3) a list containing the command after substitutions and split into words. The return status of the \fB\-precmd\fR procedure is always ignored. .TP \fB\-maxlevel \fInumber\fR Specifies the maximum evaluation depth to watch Tcl commands. The default maximum level is 10000. .RE .TP \fBwatch deactivate \fIwatchName\fR Deactivates the watch. The \fB\-precmd\fR and \fB\-postcmd\fR procedures will no longer be invoked. .TP \fBwatch info \fIwatchName\fR Returns the configuration information associated with the watch \fIwatchName\fR. \fIWatchName\fR is the name of a watch. .TP \fBwatch names\fR ?\fIstate\fR? Lists the names of the watches for a given state. \fIState\fR may be one of the following: \f(CWactive\fR, \f(CWidle\fR, or \f(CWignore\fR. If a \fIstate\fR argument isn't specified, all watches are listed. .RE .SH KEYWORDS debug, profile ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeGetToken.man3���������������������������������������������������������0000644�0001750�0001750�00000006411�11462120062�016734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeGetToken 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeGetToken \- Grabs a token associated with existing tree data object. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp int \fBBlt_TreeGetToken\fR(\fIinterp\fR, \fIname\fR, \fItokenPtr\fR) .SH ARGUMENTS .AS Tcl_Interp *interp .AP Tcl_Interp *interp in Interpreter to report results back to. .AP "const char" *name in Name of an existing tree data object. Can be qualified by a namespace. .AP Blt_Tree *tokenPtr out Points to location to store the client tree token. .BE .SH DESCRIPTION .PP This procedure obtains a token to a C-based tree data object. The arguments are as follows: .TP 1i \fIinterp\fR Interpreter to report results back to. If an error occurs, then interp->result will contain an error message. .TP 1i \fIname\fR Name of an existing tree data object. It's an error if a tree \fIname\fR doesn't already exist. \fIName\fR can be qualified by a namespace such as \f(CWfred::myTree\fR. If no namespace qualifier is used, the tree the current namespace is searched, then the global namespace. .TP 1i \fItokenPtr\fR Points to the location where the returned token is stored. A tree token is used to work with the tree object. .PP A token for the tree data object is returned. Tree data objects can be shared. For example, the \fBtree\fR and \fBhiertable\fR commands may be accessing the same tree data object. Each client grabs a token that is associated with the tree. When all tokens are released (see \fBBlt_TreeReleaseToken\fR) the tree data object is automatically destroyed. .PP .SH RETURNS A standard Tcl result is returned. If TCL_ERROR is returned, then \fIinterp->result\fR will contain an error message. The following errors may occur: .IP \(bu 3 No tree exists as \fIname\fR. You can use \fBTcl_TreeExists\fR to determine if a tree exists beforehand. .IP \(bu Memory can't be allocated for the token. .SH EXAMPLE The following example allocated a token for an existing tree. .CS Blt_Tree token; if (Blt_TreeGetToken(interp, "myTree", &token) != TCL_OK) { return TCL_ERROR; } printf("tree is %s\\n", Blt_TreeName(token)); .CE .SH SEE ALSO Tcl_TreeCreate, Tcl_TreeExists, Tcl_TreeReleaseToken �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_Tree.man3�����������������������������������������������������������������0000644�0001750�0001750�00000015032�11462120062�015272� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: Blt_Tree.man3,v 1.1.1.1 2010/10/27 21:57:06 joye Exp $ '\" .so man.macros .TH Blt_Tree 3 BLT_VERSION BLT "Blt Library Procedures" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Blt_Tree \- Tree data object. .SH SYNOPSIS .nf #include <bltTree.h> .sp struct Blt_Tree { \fBTcl_Alloc\fR(\fIsize\fR) .sp \fBTcl_Free\fR(\fIptr\fR) .sp char * \fBTcl_Realloc\fR(\fIptr, size\fR) .SH ARGUMENTS .AS char *size .AP int size in Size in bytes of the memory block to allocate. .AP char *ptr in Pointer to memory block to free or realloc. .BE .SH DESCRIPTION .PP These procedures provide a platform and compiler independent interface for memory allocation. Programs that need to transfer ownership of memory blocks between Tcl and other modules should use these routines rather than the native \fBmalloc()\fR and \fBfree()\fR routines provided by the C run-time library. .PP \fBTcl_Alloc\fR returns a pointer to a block of at least \fIsize\fR bytes suitably aligned for any use. .PP \fBTcl_Free\fR makes the space referred to by \fIptr\fR available for further allocation. .PP \fBTcl_Realloc\fR changes the size of the block pointed to by \fIptr\fR to \fIsize\fR bytes and returns a pointer to the new block. The contents will be unchanged up to the lesser of the new and old sizes. The returned location may be different from \fIptr\fR. .SH TREE OBJECT ROUTINES The following library routines allow you to create and destroy tree objects. Each tree object has a name that uniquely identifies it. Tree objects can also be shared. For example, the \fBtree\fR and \fBhiertable\fR commands may access the same tree data object. Each client grabs a token associated with the tree. When all tokens are released the tree data object is automatically destroyed. .TP 2.0i \fBBlt_TreeCreate\fR Create a tree data object and optionally obtains a token associated with it. .TP \fBBlt_TreeExists\fR Indicates if a tree by a given name exists. .TP \fBBlt_TreeGetToken\fR Obtains a token for an existing tree data object. .TP \fBBlt_TreeReleaseToken\fR Releases a token for a tree data object. The tree object is deleted when all outstanding tokens have been released. .TP \fBBlt_TreeName\fR Returns the name of the tree object. .TP \fBBlt_TreeChangeRoot\fR Specifies a node as the new root to a tree. .SH TREENODE ROUTINES Tree objects initially contain only a root node. You can add or delete nodes with the following routines. .TP 2i \fBBlt_TreeCreateNode\fR Creates a new child node for a given parent in the tree. .TP \fBBlt_TreeDeleteNode\fR Deletes a node and its children. .TP \fBBlt_TreeNodeId\fR Returns the unique node identifier for a node. .TP \fBBlt_TreeGetNode\fR Gets a node based upon its identifier. .TP \fBBlt_TreeFindChild\fR Searches for a child node given by its label in a parent node. .TP \fBBlt_TreeNodeLabel\fR Returns the current label for a node. .TP \fBBlt_TreeRelabelNode\fR Resets a node's label. .TP \fBBlt_TreeNodePath\fR Returns the fullpath to a node. .TP \fBBlt_TreeNodeDepth\fR Returns the depth of the node. .TP \fBBlt_TreeNodeDegree\fR Returns the number of children for a node. .TP \fBBlt_TreeIsLeaf\fR Indicates if a node has no children. .TP \fBBlt_TreeIsBefore\fR Indicates if a node is before another node in depth-first search order. .TP \fBBlt_TreeIsAncestor\fR Indicates if a node is an ancestor or another. .TP \fBBlt_TreeSortNode\fR Sorts the children of a node. .TP \fBBlt_TreeSize\fR Returns the number of nodes in a node and its descendants. .TP \fBBlt_TreeMoveNode\fR .SH NODE NAVIGATION Each node can have zero or more children nodes. These routines let you navigate the tree hierarchy. .TP 2i \fBBlt_TreeNodeParent\fR Returns the parent node. .TP \fBBlt_TreeFirstChild\fR Returns the first child of a parent node. .TP \fBBlt_TreeLastChild\fR Returns the last child of a parent node. .TP \fBBlt_TreeNextSibling\fR Returns the next sibling node in the parent's list of children. .TP \fBBlt_TreePrevSibling\fR Returns the previous sibling node in the parent's list of children. .TP \fBBlt_TreeRootNode\fR Returns the root node of the tree. .TP \fBBlt_TreeNextNode\fR Returns the next node in depth-first order. .TP \fBBlt_TreePrevNode\fR Returns the previous node in depth-first order. .TP \fBBlt_TreeEndNode\fR Returns the last node in the tree as determined by depth-first order. .TP \fBBlt_TreeApply\fR Walks through a node and all it descendants, applying a given callback procedure. .TP \fBBlt_TreeApplyDFS\fR Walks through a node and all it descendants in depth-first search order, applying a given callback procedure. .TP \fBBlt_TreeApplyBFS\fR Walks through a node and all it descendants in breadth-first search order, applying a given callback procedure. .SH NODE DATA VALUES Data values can be stored at any node. Values have by both a string key and a Tcl_Obj value. Data value keys do not have to be homogenous across all nodes (i.e. nodes do not have to contain the same keys). There is also a special node array data type. .TP 2i \fBBlt_TreeGetValue\fR Gets the node data value given by a key. .TP \fBBlt_TreeValueExists\fR Indicates if a node data value given by a key exists. .TP \fBBlt_TreeSetValue\fR Sets a node's value of a key. .TP \fBBlt_TreeUnsetValue\fR Remove the node data value and key. .TP \fBBlt_TreeGetArrayValue\fR Gets the node data array value given by a key and an array index. .TP \fBBlt_TreeSetArrayValue\fR Sets the node data array value given by a key and an array index. .TP \fBBlt_TreeUnsetArrayValue\fR Remove the node data array value. .TP \fBBlt_TreeArrayValueExists\fR Determines if an array element by a given index exists. .TP \fBBlt_TreeFirstKey\fR Returns the key of the first value in the node. .TP \fBBlt_TreeNextKey\fR Returns the key of the next value in the node. .TP \fBBlt_TreePrivateValue\fR Lock the value to current client, making it private. .TP \fBBlt_TreePublicValue\fR Unlock the value so that all clients can access it. .TP \fBBlt_TreeGetKey\fR .SH NODE TRACES .TP 2i \fBBlt_TreeCreateTrace\fR Sets up a trace callback to be invoked when the node value is read, set, or unset. .TP \fBBlt_TreeDeleteTrace\fR Deletes an existing trace. .SH NODE EVENTS .TP 2i \fBBlt_TreeCreateEventHandler\fR Sets up a callback to be invoked when events (create, delete, relabel, etc) take place on a node. .TP \fBBlt_TreeDeleteEventHandler\fR Deletes an existing node callback. .SH KEYWORDS alloc, allocation, free, malloc, memory, realloc ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/bitmap.mann�������������������������������������������������������������������0000644�0001750�0001750�00000021022�11462120062�015135� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-2001 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Bitmap command created by George Howlett. '\" .so man.macros .TH bitmap n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBbitmap\fR \- Define a new bitmap from a Tcl script .SH SYNOPSIS \fBblt::bitmap define \fIbitmapName data\fR ?\fIoption value\fR?... .sp \fBblt::bitmap compose \fIbitmapName text\fR ?\fIoption value\fR?... .sp \fBblt::bitmap exists \fIbitmapName\fR .sp \fBblt::bitmap source \fIbitmapName\fR .sp \fBblt::bitmap data \fIbitmapName\fR .sp \fBblt::bitmap height \fIbitmapName\fR .sp \fBblt::bitmap width \fIbitmapName\fR .BE .SH DESCRIPTION The \fBbitmap\fR command lets you create new bitmaps directly from your Tcl script. The bitmap can be specified as a list of data or a text string which is converted into a bitmap. You can arbitrarily scale or rotate the bitmap too. .SH INTRODUCTION Bitmaps are commonly used within Tk. In label and button widgets, you display bitmaps them instead of text strings and in the canvas and text widgets, they're used for stippling. But Tk let's you can create new bitmaps only by reading the bitmap data from a file. This makes bitmaps cumbersome to manage, especially in packaging the program as a \fBwish\fR script, since each bitmap must be its own file. It would be nicer if you could create new bitmaps directly from your Tcl script. .PP The \fBbitmap\fR command lets you do just that. You can specify the bitmap as in various formats (such as the X11 bitmap format). You can also compose a bitmap from a text string. The \fBbitmap\fR command also lets you and arbitrarily rotate or scale the bitmap. For example, you could use this to create button widgets with the text label rotated 90 degrees. .SH EXAMPLE You can define a new bitmap with the \fBdefine\fR operation. For example, let's say you are using the X11 bitmap "gray1". Normally to use it, you would specify the location of the file. .CS label .l -bitmap @/usr/X11R6/include/X11/bitmaps/gray1 .CE But you can simply cut and paste the contents of "gray1" into the \fBbitmap\fR command. .CS blt::bitmap define gray1 { #define gray1_width 2 #define gray1_height 2 static char gray1_bits[] = { 0x01, 0x02}; } label .l -bitmap gray1 .CE Tk will recognize "gray1" as a bitmap which can now be used with any widget that accepts bitmaps. .CS .barchart element configure elem1 -stipple gray1 .CE The bitmap data can be specified in a mulitude of forms. The following commands are all equivalent. .CS blt::bitmap define gray1 { #define gray1_width 2 #define gray1_height 2 static char gray1_bits[] = { 0x01, 0x02}; } blt::bitmap define gray1 { { 2 2 } { 0x01, 0x02 } } blt::bitmap define gray1 { { 2 2 } { 0x01 0x02 } } blt::bitmap define gray1 { { 2 2 } { 1 2 } } .CE Either the data is in the standard X11 bitmap form, or it's a list of two lists. The first list contains the height and width of the bitmap. The second list is the bitmap source data. Each element of that list is an hexadecimal number specifying which pixels are foreground (1) and which are background (0) of the bitmap. Note that the format of the source data is exactly that of the XBM format. .P You can scale or rotate the bitmap as you create it, by using the \fB-scale\fR or\fB-rotate\fR options. .CS blt::bitmap define gray1 { #define gray1_width 2 #define gray1_height 2 static char gray1_bits[] = { 0x01, 0x02}; } -scale 2.0 -rotate 90.0 .CE In addition, you can compose bitmaps from text strings. This makes it easy to create rotated buttons or labels. The text string can have multi-line. .CS blt::bitmap compose rot_text "This is rotated\\ntext" \\ -rotate 90.0 -font fixed .CE There are also a number of ways to query bitmaps. This isn't limited to bitmaps that you create, but any bitmap. .CS blt::bitmap exists rot_text blt::bitmap width rot_text blt::bitmap height rot_text blt::bitmap data rot_text blt::bitmap source rot_text .CE The \fBexists\fR operation indicates if a bitmap by that name is defined. You can query the dimensions of the bitmap using the \fBwidth\fR and \fBheight\fR operations. The \fBdata\fR operation returns the list of the data used to create the bitmap. For example, you could query the data of a bitmap and \fBsend\fR it across the network to another Tk application. .CS set data [blt::bitmap data @/usr/X11R6/include/X11/bitmaps/ghost.xbm] send {wish #2} blt::bitmap define ghost $data .CE .SH OPERATIONS The following operations are available for \fBbitmap\fR: .TP \fBblt::bitmap compose \fIbitmapName text \fR?\fIoption value\fR?... Creates a bitmap \fIbitmapName\fR from the text string \fItext\fR. A bitmap \fIbitmapName\fR can not already exist. The following options are available. .RS .TP \fB\-font \fIfontName\fR Specifies a font to use when drawing text into the bitmap. If this option isn't specified then \fIfontName\fR defaults to \f(CW*-Helvetica-Bold-R-Normal-*-140-*\fR. .TP \fB\-rotate \fItheta\fR Specifies the angle of rotation of the text in the bitmap. \fITheta\fR is a real number representing the angle in degrees. It defaults to \f(CW0.0\fR degrees. .TP \fB\-scale \fIvalue\fR Specifies the scale of the bitmap. \fIValue\fR is a real number representing the scale. A scale of 1.0 indicates no scaling is necessary, while 2.0 would double the size of the bitmap. There is no way to specify differents scales for the width and height of the bitmap. The default scale is \f(CW1.0\fR. .RE .TP \fBblt::bitmap data \fIbitmapName\fR Returns a list of both the dimensions of the bitmap \fIbitmapName\fR and its source data. .TP \fBblt::bitmap define \fIbitmapName data\fR \fR?\fIoption value\fR?... Associates \fIbitmapName\fR with in-memory bitmap data so that \fIbitmapName\fR can be used in later calls to \fBTk_GetBitmap\fR. The \fIbitmapName\fR argument is the name of the bitmap; it must not previously have been defined in either a call to Tk_DefineBitmap or \fBbitmap\fR. The argument \fIdata\fP describes the bitmap to be created. It is either the X11 bitmap format (a C structure) or a list of two lists: the dimensions and source data. The dimensions are a list of two numbers which are the width and height of the bitmap. The source data is a list of hexadecimal values in a format similar to the X11 or X10 bitmap format. The values may be optionally separated by commas and do not need to be prefixed with "0x". The following options are available. .RS .TP \fB\-rotate \fItheta\fR Specifies how many degrees to rotate the bitmap. \fITheta\fR is a real number representing the angle. The default is \f(CW0.0\fR degrees. .TP \fB\-scale \fIvalue\fR Specifies how to scale the bitmap. \fIValue\fR is a real number representing the scale. A scale of 1.0 indicates no scaling is necessary, while 2.0 would double the size of the bitmap. There is no way to specify differents scales for the width and height of the bitmap. The default scale is \f(CW1.0\fR. .RE .TP \fBblt::bitmap exists \fIbitmapName\fR Returns \f(CW1\fR if a bitmap \fIbitmapName\fR exists, otherwise \f(CW0\fR. .TP \fBblt::bitmap height \fIbitmapName\fR Returns the height in pixels of the bitmap \fIbitmapName\fR. .TP \fBblt::bitmap source \fIbitmapName\fR Returns the source data of the bitmap \fIbitmapName\fR. The source data is a list of the hexadecimal values. .TP \fBblt::bitmap width \fIbitmapName\fR Returns the width in pixels of the bitmap \fIbitmapName\fR. .SH LIMITATIONS Tk currently offers no way of destroying bitmaps. Once a bitmap is created, it exists until the application terminates. .SH KEYWORDS bitmap ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/spline.mann�������������������������������������������������������������������0000644�0001750�0001750�00000017556�11462120062�015174� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Spline command created by George Howlett. '\" .so man.macros .TH spline n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBspline\fR \- Fit curves with spline interpolation .SH SYNOPSIS .sp \fBblt::spline natural \fIx y sx sy\fR .sp \fBblt::spline quadratic \fIx y sx sy\fR .BE .SH DESCRIPTION The \fBspline\fR command computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. .SH INTRODUCTION Curve fitting has many applications. In graphs, curve fitting can be useful for displaying curves which are aesthetically pleasing to the eye. Another advantage is that you can quickly generate arbitrary points on the curve from a small set of data points. .PP A spline is a device used in drafting to produce smoothed curves. The points of the curve, known as \fIknots\fR, are fixed and the \fIspline\fR, typically a thin strip of wood or metal, is bent around the knots to create the smoothed curve. Spline interpolation is the mathematical equivalent. The curves between adjacent knots are piecewise functions such that the resulting spline runs exactly through all the knots. The order and coefficients of the polynominal determine the "looseness" or "tightness" of the curve fit from the line segments formed by the knots. .PP The \fBspline\fR command performs spline interpolation using cubic ("natural") or quadratic polynomial functions. It computes the spline based upon the knots, which are given as x and y vectors. The interpolated new points are determined by another vector which represents the abscissas (x-coordinates) or the new points. The ordinates (y-coordinates) are interpolated using the spline and written to another vector. .SH EXAMPLE Before we can use the \fBspline\fR command, we need to create two BLT vectors which will represent the knots (x and y coordinates) of the data that we're going to fit. Obviously, both vectors must be the same length. .CS # Create sample data of ten points. blt::vector x(10) y(10) for {set i 10} {$i > 0} {incr i -1} { set x($i-1) [expr $i*$i] set y($i-1) [expr sin($i*$i*$i)] } .CE We now have two vectors \f(CWx\fR and \f(CWy\fR representing the ten data points we're trying to fit. The order of the values of \f(CWx\fR must be monotonically increasing. We can use the vector's \fBsort\fR operation to sort the vectors. .CS x sort y .CE The components of \f(CWx\fR are sorted in increasing order. The components of \f(CWy\fR are rearranged so that the original x,y coordinate pairings are retained. .PP A third vector is needed to indicate the abscissas (x-coordinates) of the new points to be interpolated by the spline. Like the x vector, the vector of abscissas must be monotonically increasing. All the abscissas must lie between the first and last knots (x vector) forming the spline. .PP How the abscissas are picked is arbitrary. But if we are going to plot the spline, we will want to include the knots too. Since both the quadratic and natural splines preserve the knots (an abscissa from the x vector will always produce the corresponding ordinate from the y vector), we can simply make the new vector a superset of \f(CWx\fR. It will contain the same coordinates as \f(CWx\fR, but also the abscissas of the new points we want interpolated. A simple way is to use the vector's \fBpopulate\fR operation. .CS x populate sx 10 .CE This creates a new vector \f(CWsx\fR. It contains the abscissas of \f(CWx\fR, but in addition \f(CWsx\fR will have ten evenly distributed values between each abscissa. You can interpolate any points you wish, simply by setting the vector values. .PP Finally, we generate the ordinates (the images of the spline) using the \fBspline\fR command. The ordinates are stored in a fourth vector. .CS blt::spline natural x y sx sy .CE This creates a new vector \f(CWsy\fR. It will have the same length as \f(CWsx\fR. The vectors \f(CWsx\fR and \f(CWsy\fR represent the smoothed curve which we can now plot. .CS blt::graph .graph \&.graph element create original -x x -y x -color blue \&.graph element create spline -x sx -y sy -color red blt::table . .graph .CE The \fBnatural\fR operation employs a cubic interpolant when forming the spline. In terms of the draftmen's spline, a \fInatural spline\fR requires the least amount of energy to bend the spline (strip of wood), while still passing through each knot. In mathematical terms, the second derivatives of the first and last points are zero. .PP Alternatively, you can generate a spline using the \fBquadratic\fR operation. Quadratic interpolation produces a spline which follows the line segments of the data points much more closely. .CS blt::spline quadratic x y sx sy .CE .SH OPERATIONS .TP \fBblt::spline natural \fIx y sx sy\fR Computes a cubic spline from the data points represented by the vectors \fIx\fR and \fIy\fR and interpolates new points using vector \fIsx\fR as the x-coordinates. The resulting y-coordinates are written to a new vector \fIsy\fR. The vectors \fIx\fR and \fIy\fR must be the same length and contain at least three components. The order of the components of \fIx\fR must be monotonically increasing. \fISx\fR is the vector containing the x-coordinates of the points to be interpolated. No component of \fIsx\fR can be less than first component of \fIx\fR or greater than the last component. The order of the components of \fIsx\fR must be monotonically increasing. \fISy\fR is the name of the vector where the calculated y-coordinates will be stored. If \fIsy\fR does not already exist, a new vector will be created. .TP \fBblt::spline quadratic \fIx y sx sy\fR Computes a quadratic spline from the data points represented by the vectors \fIx\fR and \fIy\fR and interpolates new points using vector \fIsx\fR as the x-coordinates. The resulting y-coordinates are written to a new vector \fIsy\fR. The vectors \fIx\fR and \fIy\fR must be the same length and contain at least three components. The order of the components of \fIx\fR must be monotonically increasing. \fISx\fR is the vector containing the x-coordinates of the points to be interpolated. No component of \fIsx\fR can be less than first component of \fIx\fR or greater than the last component. The order of the components of \fIsx\fR must be monotonically increasing. \fISy\fR is the name of the vector where the calculated y-coordinates are stored. If \fIsy\fR does not already exist, a new vector will be created. .SH REFERENCES .nf .sp Numerical Analysis by R. Burden, J. Faires and A. Reynolds. Prindle, Weber & Schmidt, 1981, pp. 112 .sp Shape Preserving Quadratic Splines by D.F.Mcallister & J.A.Roulier Coded by S.L.Dodd & M.Roulier N.C.State University. .sp .fi The original code for the quadratric spline can be found in TOMS #574. .SH KEYWORDS spline, vector, graph ��������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/cutbuffer.mann����������������������������������������������������������������0000644�0001750�0001750�00000004422�11462120062�015653� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" .so man.macros .TH cutbuffer n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME cutbuffer \- Manipulate X cut buffer properties .SH SYNOPSIS \fBcutbuffer\fI get ?number?\fR .br \fBcutbuffer\fI rotate ?count?\fR .br \fBcutbuffer\fI set value ?number?\fR .BE .SH DESCRIPTION .PP The \fBcutbuffer\fR command allows you to read or modify the eight X cut buffer properties. You can also rotate the buffers properties. .SH OPERATIONS The following operations are available for the \fBcutbuffer\fR command: .TP \fBcutbuffer get \fI?number?\fR Returns the value of a cutbuffer \fInumber\fR. \fINumber\fR must be a number between 0 and 7. The default is 0. The cutbuffer is returned exactly, except that NUL bytes are converted to '@' characters. If a cut buffer \fInumber\fR does not exist, then \f(CW""\fR is returned. .TP \fBcutbuffer rotate \fI?count?\fR Rotates the cut buffers by \fIcount\fR. \fICount\fR must be a number between -7 and 7. The default is 1. .TP \fBcutbuffer set \fIvalue\fR ?\fInumber\fR? Sets the cutbuffer \fInumber\fR to \fIvalue\fR. \fINumber\fR must be a number between 0 and 7. The default is 0. .SH KEYWORDS cut buffer, property ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/busy.mann���������������������������������������������������������������������0000644�0001750�0001750�00000024603�11462120062�014653� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Busy command created by George Howlett. '\" .so man.macros .TH busy n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBbusy\fR \- Make Tk widgets busy, temporarily blocking user interactions. .SH SYNOPSIS \fBblt::busy hold \fIwindow\fR ?\fIoption value\fR?... .sp \fBblt::busy release \fIwindow\fR ?\fIwindow\fR?... .sp \fBblt::busy configure \fIwindow\fR ?\fIoption value\fR?... .sp \fBblt::busy forget \fIwindow\fR ?\fIwindow\fR?... .sp \fBblt::busy isbusy \fR?\fIpattern\fR? .sp \fBblt::busy names \fR?\fIpattern\fR? .sp \fBblt::busy status \fIwindow\fR .BE .SH DESCRIPTION .PP The \fBbusy\fR command provides a simple means to block keyboard, button, and pointer events from Tk widgets, while overriding the widget's cursor with a configurable busy cursor. .SH INTRODUCTION .PP There are many times in applications where you want to temporarily restrict what actions the user can take. For example, an application could have a "run" button that when pressed causes some processing to occur. But while the application is busy processing, you probably don't want the the user to be able to click the "run" button again. You may also want restrict the user from other tasks such as clicking a "print" button. .PP The \fBbusy\fR command lets you make Tk widgets busy. This means that user interactions such as button clicks, moving the mouse, typing at the keyboard, etc. are ignored by the widget. You can set a special cursor (like a watch) that overrides the widget's normal cursor, providing feedback that the application (widget) is temporarily busy. .PP When a widget is made busy, the widget and all of its descendents will ignore events. It's easy to make an entire panel of widgets busy. You can simply make the toplevel widget (such as ".") busy. This is easier and far much more efficient than recursively traversing the widget hierarchy, disabling each widget and re-configuring its cursor. .PP Often, the busy command can be used instead of Tk's \fBgrab\fR command. Unlike \fBgrab\fR which restricts all user interactions to one widget, with the busy command you can have more than one widget active (for example, a "cancel" dialog and a "help" button). .SH EXAMPLE You can make several widgets busy by simply making its ancestor widget busy using the \fBhold\fR operation. .CS frame .top button .top.button; canvas .top.canvas pack .top.button .top.canvas pack .top . . . blt::busy hold .top update .CE All the widgets within \f(CW.top\fR (including \f(CW.top\fR) are now busy. Using \fBupdate\fR insures that \fBbusy\fR command will take effect before any other user events can occur. .PP When the application is no longer busy processing, you can allow user interactions again by the \fBrelease\fR operation. .nf \f(CW blt::busy release .top \fR .fi The busy window has a configurable cursor. You can change the busy cursor using the \fBconfigure\fR operation. .nf \f(CW blt::busy configure .top -cursor "watch"\fR .fi Finally, when you no longer need to the busy window, invoke the \fBforget\fR operation to free any resources it allocated. .nf \f(CW blt::busy forget .top \fR .fi Destroying the widget will also clean up any resources allocated by the busy command. .PP .SH OPERATIONS The following operations are available for the \fBbusy\fR command: .TP \fBblt::busy hold \fIwindow\fR ?\fIoption value\fR?... Makes the widget \fIwindow\fR (and its descendants in the Tk window hierarchy) busy. \fIWindow\fR must be a valid path name of a Tk widget. The busy window is mapped the next time idle tasks are processed, and the widget and its descendants will be blocked from user interactions. All events in the widget window and its descendants are ignored. Normally \fBupdate\fR should be called immediately afterward to insure that the \fBhold\fR operation is in effect \fIbefore\fR the application starts its processing. The following configuration options are valid: .RS .TP \fB\-cursor \fIcursorName\fR Specifies the cursor to be displayed when the widget is made busy. \fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The default cursor is \f(CWwatch\fR. .RE .TP \fBblt::busy configure \fIwindow\fR ?\fIoption value\fR?... Queries or modifies the \fBbusy\fR command configuration options for \fIwindow\fR. \fIWindow\fR must be the path name of a widget previously made busy by the \fBhold\fR operation. If no options are specified, a list describing all of the available options for \fIwindow\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list) is returned. If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns the empty string. \fIOption\fR may have any of the values accepted by the \fBhold\fR operation. .sp Please note that the option database is referenced through \fIwindow\fR. For example, if the widget \f(CW.frame\fR is to be made busy, the busy cursor can be specified for it by either \fBoption\fR command: .nf \f(CWoption add *frame.busyCursor gumby\fR \f(CWoption add *Frame.BusyCursor gumby\fR .fi .TP \fBblt::busy forget \fIwindow\fR ?\fIwindow\fR?... Releases resources allocated by the busy command for \fIwindow\fR, including the busy window. User events will again be received again by \fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed. \fIWindow\fR must be the name of a widget specified in the \fBhold\fR operation, otherwise an error is reported. .TP \fBblt::busy check \fIwindow\fR Checks if \fIwindow\fR or any of its ancestors are currently busy. If \fIwindow\fR is presently busy (it can not receive user interactions) \f(CW1\fR is returned, otherwise \f(CW0\fR. .TP \fBblt::busy isbusy \fR?\fIpattern\fR? Returns the pathnames of all widgets that are currently busy. If a \fIpattern\fR is given, the path names of busy widgets matching \fIpattern\fR are returned. .TP \fBblt::busy names \fR?\fIpattern\fR? Returns the pathnames of all widgets that have previously been made busy (i.e. a busy window is allocated and associated with the widget). It makes no difference if the window is currently busy or not. If a \fIpattern\fR is given, the path names of busy widgets matching \fIpattern\fR are returned. .TP \fBblt::busy release \fIwindow\fR ?\fIwindow\fR?... Restores user interactions to the widget \fIwindow\fR again. This differs from the \fBforget\fR operation in that the busy window is not destroyed, but simply unmapped. \fIWindow\fR must be the name of a widget specified in a \fBhold\fR operation, otherwise an error is reported. .TP \fBblt::busy status \fIwindow\fR Returns the status of a widget \fIwindow\fR previously made busy. An error is reported if \fIwindow\fR does not was never made busy, or the \fBforget\fR operation was invoked (i.e. does not currently have a busy window associated with it). If \fIwindow\fR is presently can not receive user interactions, \f(CW1\fR is returned, otherwise \f(CW0\fR. .sp 1 .SH BINDINGS The event blocking feature is implemented by creating and mapping a transparent window that completely covers the widget. When the busy window is mapped, it invisibly shields the widget and its hierarchy from all events that may be sent. Like Tk widgets, busy windows have widget names in the Tk window hierarchy. This means that you can use the \fBbind\fR command, to handle events in the busy window. .CS blt::busy hold .frame.canvas bind .frame.canvas_Busy <Enter> { ... } .CE .PP Normally the busy window is a sibling of the widget. The name of the busy window is "\fIwidget\f(CW_Busy\fR" where \fIwidget\fR is the name of the widget to be made busy. In the previous example, the pathname of the busy window is "\f(CW.frame.canvas_Busy\fR" The exception is when the widget is a toplevel widget (such as ".") where the busy window can't be made a sibling. The busy window is then a child of the widget named "\fIwidget\f(CW._Busy\fR" where \fIwidget\fR is the name of the toplevel widget. In the following example, the pathname of the busy window is "\f(CW._Busy\fR" .CS blt::busy hold . bind ._Busy <Enter> { ... } .CE .SH ENTER/LEAVE EVENTS Mapping and unmapping busy windows generates Enter/Leave events for all widgets they cover. Please note this if you are tracking Enter/Leave events in widgets. .SH KEYBOARD EVENTS When a widget is made busy, the widget is prevented from gaining the keyboard focus by the busy window. But if the widget already had focus, it still may received keyboard events. To prevent this, you must move focus to another window. .CS blt::busy hold .frame label .dummy focus .dummy update .CE The above example moves the focus from .frame immediately after invoking the \fBhold\fR so that no keyboard events will be sent to \f(CW.frame\fR or any of its descendants. .PP Tk's tab traversal mechanism should be also modified to check for busy windows. You can do this by adding a simple test to "tkFocusOK". Here's an example. .CS tk_focusNext . rename tkFocusOK tkFocusOK.orig proc tkFocusOK { w } { if { [blt::busy check $w] } { return 0 } return [tkFocusOK.orig $w] } .CE .SH KEYWORDS busy, keyboard events, pointer events, window, cursor �����������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeExists.man3�����������������������������������������������������������0000644�0001750�0001750�00000004433�11462120062�016475� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeExists 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeExists \- Indicates if a tree exists. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp int \fBBlt_TreeExists\fR(\fIinterp\fR, \fIname\fR) .SH ARGUMENTS .AS Tcl_Interp *interp .AP Tcl_Interp *interp in Interpreter to determine current namespace context. .AP "const char" *name in Name of an existing tree data object. Can be qualified by a namespace. .BE .SH DESCRIPTION .PP This procedure determines if a C-based tree data object exists by a given name. The arguments are as follows: .TP 1i interp Used the determine the current namespace context. .TP 1i name Name of an existing tree data object. \fIName\fR can be qualified by a namespace such as \f(CWfred::myTree\fR. If no namespace qualifier is used, the current namespace is searched, then the global namespace. .PP .SH RETURNS A boolean result is returned. If the tree exists 1 is returned, 0 otherwise. .SH EXAMPLE The following example checks if a tree "myTree" exists. .CS .ft CW if (!Blt_TreeExists(interp, "myTree")) { fprintf(stderr, "can't find tree \\"myTree\\\\n"); } .ft R .CE .SH KEYWORDS tree, token Tcl_TreeCreate, Tcl_TreeGetToken, Tcl_TreeReleaseToken�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeNodeId.man3�����������������������������������������������������������0000644�0001750�0001750�00000004265�11462120062�016363� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeNodeId 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeNodeId \- Returns the node serial number. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp unsigned int \fBBlt_TreeNodeId\fR(\fInode\fR) .SH ARGUMENTS .AS Blt_TreeNode node .AP Blt_TreeNode node in Node whose ID is to be returned. .BE .SH DESCRIPTION This procedure returns the node serial number. The node serial number is useful for programs that export the tree data object to the Tcl programming level. Since node labels (and therefore pathnames) are not unique, the ID can be used to uniquely identify a node. .PP The arguments are as follows: .TP 1i \fInode\fR The node whose serial number is returned. The serial number of the root node for example is always 0. .SH RETURNS The serial number of the node. Nodes are given a unique serial number when they are created. You can use the ID to later retrieve the node using \fBBlt_TreeGetNode\fR. .SH EXAMPLE The following example prints the ID of a node. .CS printf("root ID is %s\\n", Blt_TreeNodeId(node)); .CE .SH KEYWORDS Tcl_TreeCreateNode, Tcl_TreeDeleteNode �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/stripchart.mann���������������������������������������������������������������0000644�0001750�0001750�00000265637�11462120062�016072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Stripchart widget created by Sani Nassif and George Howlett. '\" .so man.macros .TH stripchart n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME stripchart \- 2D strip chart for plotting x and y coordinate data. .SH SYNOPSIS \fBstripchart\fI \fIpathName \fR?\fIoption value\fR?... .BE .SH DESCRIPTION The \fBstripchart\fR command creates a strip chart for plotting two-dimensional data (x,y coordinates). It has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the strip chart. .PP The \fBstripchart\fR is essentially the same as the \fBgraph\fR widget. It works almost exactly the very same way. .PP The use of a strip chart differs in that the X-axis typically refers to time points. Data values are added at intervals. The strip chart lets you automatically maintain a view of the most recent time points. The axis options \fB\-shiftby\fR and \fB\-autorange\fR control this. You can specify different line styles for data points (see the \fB\-styles\fR option). .SH INTRODUCTION The \fBstripchart\fR command creates a new window for plotting two-dimensional data (x,y coordinates). Data points are plotted in a box displayed in the center of the new window. This is the \fIplotting area\fR. The coordinate axes are displayed in the margins around the plotting area. By default, the legend is displayed in the right margin. The title is displayed in top margin. .PP A strip chart is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. .TP 1i \f(CWaxis\fR The stripchart widget can display up to four coordinate axes (two X-coordinate and two Y-coordinate axes), but you can create and use any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value of each major tick. .TP 1i \f(CWcrosshairs\fR Cross hairs are used to finely position the mouse pointer in relation to the coordinate axes. Two perpendicular lines are drawn across the plotting area, intersecting at the current location of the mouse pointer. .TP 1i \f(CWelement\fR An element represents a set of data points. Elements can be plotted with a symbol at each data point and lines connecting the points. The appearance of the element, such as its symbol, line width, and color is configurable. .TP 1i \f(CWgrid\fR Extends the major and minor ticks of the X\-axis and/or Y\-axis across the plotting area. .TP 1i \f(CWlegend\fR The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. .TP 1i \f(CWmarker\fR Markers are used annotate or highlight areas of the graph. For example, you could use a polygon marker to fill an area under a curve, or a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. .TP 1i \f(CWpen\fR Pens define attributes (both symbol and line style) for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here, the particular pen used for a data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .TP 1i \f(CWpostscript\fR The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. .SH SYNTAX .DS \fBstripchart \fIpathName \fR?\fIoption value\fR?... .DE The \fBstripchart\fR command creates a new window \fIpathName\fR and makes it into a \fBstripchart\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may may be specified on the command line or in the option database to configure aspects of the strip chart such as its colors and font. See the \fBconfigure\fR operation below for the exact details as to what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBstripchart\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to perform various operations that query or modify the graph. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for the strip chart are described in the .SB "STRIPCHART OPERATIONS" section. .PP The command can also be used to access components of the strip chart. .DS \fIpathName component operation\fR ?\fIarg\fR?... .DE The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. .SH EXAMPLE The \fBstripchart\fR command creates a new strip chart. .CS # Create a new strip chart. Plotting area is black. stripchart .s -plotbackground black .CE A new Tcl command \f(CW.s\fR is also created. This command can be used to query and modify the strip chart. For example, to change the title of the strip chart to "My Plot", you use the new command and the widget's \fBconfigure\fR operation. .CS # Change the title. \&.s configure \-title "My Plot" .CE A strip chart has several components. To access a particular component you use the component's name. For example, to add data elements, you use the new command and the \fBelement\fR component. .CS # Create a new element named "line1" \&.s element create line1 \\ \-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \\ \-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } .CE The element's X and Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X\-Y coordinates. .CS # Create two vectors and add them to the strip chart. vector xVec yVec xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } \&.s element create line1 \-xdata xVec \-ydata yVec .CE The advantage of using vectors is that when you modify one, the graph is automatically redrawn to display the new values. .CS # Change the X\-Y coordinates of the first point. set xVec(0) 0.18 set yVec(0) 25.18 .CE An element named \f(CWline1\fR is now created in \f(CW.s\fR. By default, the element's label in the legend will be also \f(CWline1\fR. You can change the label, or specify no legend entry, again using the element's \fBconfigure\fR operation. .CS # Don't display "line1" in the legend. \&.s element configure line1 -label "" .CE You can configure more than just the element's label. An element has many attributes such as symbol type and size, dashed or solid lines, colors, line width, etc. .CS \&.s element configure line1 -symbol square -color red \\ -dashes { 2 4 2 } -linewidth 2 -pixels 2c .CE Four coordinate axes are automatically created: \f(CWx\fR, \f(CWx2\fR, \f(CWy\fR, and \f(CWy2\fR. And by default, elements are mapped onto the axes \f(CWx\fR and \f(CWy\fR. This can be changed with the \fB\-mapx\fR and \fB\-mapy\fR options. .CS # Map "line1" on the alternate Y-axis "y2". \&.s element configure line1 -mapy y2 .CE Axes can be configured in many ways too. For example, you change the scale of the Y-axis from linear to log using the \fBaxis\fR operation. .CS # Y-axis is log scale. \&.s axis configure y -logscale yes .CE Axis limits are reset by simply specifying new axis limits using the \fB\-min\fR and \fB\-max\fR configuration options. .CS \&.s axis configure x -min 1.0 -max 1.5 \&.s axis configure y -min 12.0 -max 55.15 .CE By default, the limits of the axis are determined from data values. To reset back to the default limits, set the \fB\-min\fR and \fB\-max\fR options to the empty value. .CS # Reset the axes to autoscale again. \&.s axis configure x -min {} -max {} \&.s axis configure y -min {} -max {} .CE It's common with strip charts to automatically maintain a view of the most recent time points. You can do this my setting the \fB\-autorange\fR option. .CS \&.s axis configure x -autorange 20.0 .CE If the time points are added in X-coordinates 1.0 unit, only the last twenty time points will be displayed. As more data is added, the view will march along. .PP Sometimes the rate of data is so high that changing the axis limits with each additional time point is prohibitive. You can use the \fB\-shiftby\fR option to define an increment to shift the view when needed. .CS \&.s axis configure x -shiftby 15.0 .CE When the view is shifted, it will allow a range of 15 new time points to be added until the axis limits are recomputed. .PP By default, the legend is displayed in the right margin. You can change this or any other legend configuration options using the \fBlegend\fR component. .CS # Configure the legend font, color, and relief \&.s legend configure -position left -relief raised \\ -font fixed -fg blue .CE To prevent the legend from being displayed, turn on the \fB\-hide\fR option. .CS # Don't display the legend. \&.s legend configure -hide yes\fR .CE The \fBstripchart\fR widget has simple drawing procedures called markers. They can be used to highlight or annotate data in the strip chart. The types of markers available are bitmaps, images, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. Here is a text marker which labels the data first point. Markers are created using the \fBmarker\fR operation. .CS # Create a label for the first data point of "line1". \&.s marker create text \-name first_marker \-coords { 0.2 26.18 } \\ \-text "start" \-anchor se \-xoffset -10 \-yoffset -10 .CE This creates a text marker named \f(CWfirst_marker\fR. It will display the text "start" near the coordinates of the first data point. The \fB\-anchor\fR, \fB\-xoffset\fR, and \fB\-yoffset\fR options are used to display the marker above and to the left of the data point, so that the actual data point isn't covered by the marker. By default, markers are drawn last, on top of data. You can change this with the \fB\-under\fR option. .CS # Draw the label before elements are drawn. \&.s marker configure first_marker -under yes .CE You can add cross hairs or grid lines using the \fBcrosshairs\fR and \fBgrid\fR operations. .CS # Display both cross hairs and grid lines. \&.s crosshairs configure \-hide no \-color red \&.s grid configure \-hide no \-dashes { 2 2 } .CE Finally, to get hardcopy of the strip chart, use the \fBpostscript\fR operation. .CS # Print the strip chart into file "file.ps" \&.s postscript output file.ps \-maxpect yes \-decorations no .CE This generates a file \f(CWfile.ps\fR containing the encapsulated PostScript of the strip chart. The option \fB\-maxpect\fR says to scale the plot to the size of the page. Turning off the \fB\-decorations\fR option indicates that no borders or color backgrounds should be displayed (i.e. the background of the margins, legend, and plotting area will be white). .SH "STRIPCHART OPERATIONS" .TP \fIpathName \fBaxis \fIoperation\fR ?\fIarg\fR?... See the .SB "AXIS COMPONENTS" section. .TP \fIpathName \fBbar \fIelemName \fR?\fIoption value\fR?... Creates a new barchart element \fIelemName\fR. It's an error if an element \fIelemName\fR already exists. See the manual for \fBbarchart\fR for details about what \fIoption\fR and \fIvalue\fR pairs are valid. .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the stripchart configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the \fBconfigure\fR operation. .TP \fIpathName \fBconfigure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the strip chart. If \fIoption\fR isn't specified, a list describing all of the current options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the stripchart option \fIoption\fR is set to \fIvalue\fR. The following options are valid for the stripchart. .RS .TP \fB\-background \fIcolor\fR Sets the background color. This includes the margins and legend, but not the plotting area. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-bottommargin \fIpixels\fR Specifies the size of the margin below the X\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the size of the margin is selected automatically. The default is \f(CW0\fR. .TP \fB\-bufferelements \fIboolean\fR Indicates whether to draw elements into a pixmap before displaying them on the screen. The advantage of buffering elements is when markers are used heavily. Markers can be moved and redrawn without requiring every element to be redrawn again. The disadvantage is that it takes slightly longer to draw the graph. If \fIboolean\fR is true, data elements are drawn to an internal pixmap. The option should be turned off if the plot is updated frequently. See the .SB "SPEED TIPS" section. The default is \f(CW1\fR. .TP \fB\-buffergraph \fIboolean\fR Indicates whether to draw the graph into a pixmap first. If \fIboolean\fR is true, the entire graph is drawn into a pixmap and then copied onto the screen. This reduces flashing. If false, the graph is drawn directly into the window. Especially under Windows, turning off the option can be helpful when the stripchart is updated frequently. Turning off this option also turns \fB\-bufferelements\fR off. See the .SB "SPEED TIPS" section. The default is \f(CW1\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CWcrosshair\fR. .TP \fB\-font \fIfontName\fR Specifies the title font. The default is \f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR. .TP \fB\-halo \fIpixels\fR Specifies a maximum distance to consider when searching for the closest data point (see the element's \fBclosest\fR operation below). Data points further than \fIpixels\fR away are ignored. The default is \f(CW0.5i\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW4i\fR. .TP \fB\-invertxy \fIboolean\fR Indicates whether the placement X\-axis and Y\-axis should be inverted. If \fIboolean\fR is true, the X and Y axes are swapped. The default is \f(CW0\fR. .TP \fB\-justify \fIjustify\fR Specifies how the title should be justified. This matters only when the title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-leftmargin \fIpixels\fR Sets the size of the margin from the left edge of the window to the Y\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the size is calculated automatically. The default is \f(CW0\fR. .TP \fB\-plotbackground \fIcolor\fR Specifies the background color of the plotting area. The default is \f(CWwhite\fR. .TP \fB\-plotborderwidth \fIpixels\fR Sets the width of the 3-D border around the plotting area. The \fB\-plotrelief\fR option determines if a border is drawn. The default is \f(CW2\fR. .TP \fB\-plotpadx \fIpad\fR Sets the amount of padding to be added to the left and right sides of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotpady \fIpad\fR Sets the amount of padding to be added to the top and bottom of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotrelief \fIrelief\fR Specifies the 3-D effect for the plotting area. \fIRelief\fR indicates how the interior of the plotting area should appear relative to rest of the strip chart; for example, \f(CWraised\fR means the plot should appear to protrude from the strip chart, relative to the surface of the strip chart. The default is \f(CWsunken\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the widget. \fIRelief\fR indicates how the strip chart should appear relative to widget it is packed into; for example, \f(CWraised\fR means the strip chart should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-rightmargin \fIpixels\fR Sets the size of margin from the plotting area to the right edge of the window. By default, the legend is displayed in this margin. If \fIpixels\fR is than 1, the margin size is selected automatically. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW""\fR. .TP \fB\-tile \fIimage\fR Specifies a tiled background. If \fIimage\fR isn't \f(CW""\fR, the background is tiled using \fIimage\fR. Otherwise, the normal background color is drawn (see the \fB\-background\fR option). \fIImage\fR must be an image created using the Tk \fBimage\fR command. The default is \f(CW""\fR. .TP \fB\-title \fItext\fR Sets the title to \fItext\fR. If \fItext\fR is \f(CW""\fR, no title will be displayed. .TP \fB\-topmargin \fIpixels\fR Specifies the size of the margin above the x2 axis. If \fIpixels\fR is \f(CW0\fR, the margin size is calculated automatically. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. The default is \f(CW5i\fR. .RE .TP \fIpathName \fBcrosshairs \fIoperation \fR?\fIarg\fR? See the .SB "CROSSHAIRS COMPONENT" section. .TP \fIpathName \fBelement \fIoperation \fR?\fIarg\fR?... See the .SB "ELEMENT COMPONENTS" section. .TP \fIpathName \fBextents \fIitem\fR Returns the size of a particular item in the strip chart. \fIItem\fR must be either \f(CWleftmargin\fR, \f(CWrightmargin\fR, \f(CWtopmargin\fR, \f(CWbottommargin\fR, \f(CWplotwidth\fR, or \f(CWplotheight\fR. .TP \fIpathName \fBgrid \fIoperation \fR?\fIarg\fR?... See the .SB "GRID COMPONENT" section. .TP \fIpathName \fBinvtransform \fIwinX winY\fR Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X\-axis and Y\-axis. Returns a list of containing the graph coordinates. .TP \fIpathName \fBlegend \fIoperation \fR?\fIarg\fR?... See the .SB "LEGEND COMPONENT" section. .TP \fIpathName \fBline \fIelemName\fR ?\fIoption value\fR?... The operation is the same as \fBelement\fR. .TP \fIpathName \fBmarker \fIoperation \fR?\fIarg\fR?... See the .SB "MARKER COMPONENTS" section. .TP \fIpathName\fR \fBmetafile\fR ?\fIfileName\fR? \fIThis operation is for Window platforms only\fR. Creates a Windows enhanced metafile of the stripchart. If present, \fIfileName\fR is the file name of the new metafile. Otherwise, the metafile is automatically added to the clipboard. .TP \fIpathName \fBpostscript \fIoperation \fR?\fIarg\fR?... See the .SB "POSTSCRIPT COMPONENT" section. .TP \fIpathName \fBsnap \fIphotoName\fR Takes a snapshot of the strip chart and stores the contents in the photo image \fIphotoName\fR. \fIPhotoName\fR is the name of a Tk photo image that must already exist. .TP \fIpathName \fBtransform \fIx y\fR Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X\-axis and Y\-axis. Returns a list containing the X\-Y screen coordinates. .TP \fIpathName \fBxaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBx2axis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fByaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBy2axis \fIoperation\fR ?\fIarg\fR?... See the .SB "AXIS COMPONENTS" section. .SH "STRIPCHART COMPONENTS" A strip chart is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the strip chart is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the strip chart. .SS "AXIS COMPONENTS" Four coordinate axes are automatically created: two X\-coordinate axes (\f(CWx\fR and \f(CWx2\fR) and two Y\-coordinate axes (\f(CWy\fR, and \f(CWy2\fR). By default, the axis \f(CWx\fR is located in the bottom margin, \f(CWy\fR in the left margin, \f(CWx2\fR in the top margin, and \f(CWy2\fR in the right margin. .PP An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. .PP The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. .PP You can create and use several axes. To create an axis, invoke the axis component and its create operation. .CS # Create a new axis called "temperature" \&.s axis create temperature .CE You map data elements to an axis using the element's \-mapy and \-mapx configuration options. They specify the coordinate axes an element is mapped onto. .CS # Now map the temperature data to this axis. \&.s element create "temp" \-xdata $x \-ydata $tempData \\ \-mapy temperature .CE While you can have many axes, only four axes can be displayed simultaneously. They are drawn in each of the margins surrounding the plotting area. The axes x and y are drawn in the bottom and left margins. The axes x2 and y2 are drawn in top and right margins. Only x and y are shown by default. Note that the axes can have different scales. .PP To display a different axis, you invoke one of the following components: \fBxaxis\fR, \fByaxis\fR, \fBx2axis\fR, and \fBy2axis\fR. The \fBuse\fR operation designates the axis to be drawn in the corresponding margin: \fBxaxis\fR in the bottom, \fByaxis\fR in the left, \fBx2axis\fR in the top, and \fBy2axis\fR in the right. .CS # Display the axis temperature in the left margin. \&.s yaxis use temperature .CE .PP You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label as you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. .PP .TP \fIpathName \fBaxis \fBcget \fIaxisName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIaxisName\fR. \fIOption\fR may be any option described below for the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBconfigure \fIaxisName \fR?\fIoption value\fR?... Queries or modifies the configuration options of \fIaxisName\fR. If \fIoption\fR isn't specified, a list describing all the current options for \fIaxisName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the axis option \fIoption\fR is set to \fIvalue\fR. The following options are valid for axes. .RS .TP \fB\-autorange \fIrange\fR Sets the range of values for the axis to \fIrange\fR. The axis limits are automatically reset to display the most recent data points in this range. If \fIrange\fR is 0.0, the range is determined from the limits of the data. If \fB\-min\fR or \fB-max\fR are specified, they override this option. The default is \f(CW0.0\fR. .TP \fB\-color \fIcolor\fR Sets the color of the axis and tick labels. The default is \f(CWblack\fR. .TP \fB\-command \fIprefix\fR Specifies a Tcl command to be invoked when formatting the axis tick labels. \fIPrefix\fR is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If \f(CW""\fR is returned, no label will appear next to the tick. You can get the standard tick labels again by setting \fIprefix\fR to \f(CW""\fR. The default is \f(CW""\fR. .sp 1 Please note that this procedure is invoked while the strip chart is redrawn. You may query the configuration options. But do not reset them, because this can have unexpected results. .TP \fB\-descending \fIboolean\fR Indicates whether the values along the axis are monotonically increasing or decreasing. If \fIboolean\fR is true, the axis values will be decreasing. The default is \f(CW0\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the axis is displayed. .TP \fB\-justify \fIjustify\fR Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-limits \fIformatStr\fR Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. \fIFormatStr\fR is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If \f(CW""\fR is given as either description, then the that limit will not be displayed. The default is \f(CW""\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the axis and tick lines. The default is \f(CW1\fR pixel. .TP \fB\-logscale \fIboolean\fR Indicates whether the scale of the axis is logarithmic or linear. If \fIboolean\fR is true, the axis is logarithmic. The default scale is linear. .TP \fB\-loose \fIboolean\fR Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. This is relevant only when the axis limit is automatically calculated. If \fIboolean\fR is true, the axis range is "loose". The default is \f(CW0\fR. .TP \fB\-majorticks \fImajorList\fR Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. \fIMajorList\fR is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If \fImajorList\fR is \f(CW""\fR, major ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-max \fIvalue\fR Sets the maximum limit of \fIaxisName\fR. Any data point greater than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the maximum limit is calculated using the largest data value. The default is \f(CW""\fR. .TP \fB\-min \fIvalue\fR Sets the minimum limit of \fIaxisName\fR. Any data point less than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the minimum limit is calculated using the smallest data value. The default is \f(CW""\fR. .TP \fB\-minorticks \fIminorList\fR Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. \fIMinorList\fR is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the \fB\-majortick\fR option is also set. If \fIminorList\fR is \f(CW""\fR, minor ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-rotate \fItheta\fR Specifies the how many degrees to rotate the axis tick labels. \fITheta\fR is a real value representing the number of degrees to rotate the tick labels. The default is \f(CW0.0\fR degrees. .TP \fB\-shiftby \fIvalue\fR Specifies how much to automatically shift the range of the axis. When the new data exceeds the current axis maximum, the maximum is increased in increments of \fIvalue\fR. You can use this option to prevent the axis limits from being recomputed at each new time point. If \fIvalue\fR is 0.0, then no automatic shifting is done. The default is \f(CW0.0\fR. .TP \fB\-showticks \fIboolean\fR Indicates whether axis ticks should be drawn. If \fIboolean\fR is true, ticks are drawn. If false, only the axis line is drawn. The default is \f(CW1\fR. .TP \fB\-stepsize \fIvalue\fR Specifies the interval between major axis ticks. If \fIvalue\fR isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. .TP \fB\-subdivisions \fInumber\fR Indicates how many minor axis ticks are to be drawn. For example, if \fInumber\fR is two, only one minor tick is drawn. If \fInumber\fR is one, no minor ticks are displayed. The default is \f(CW2\fR. .TP \fB\-tickfont \fIfontName\fR Specifies the font for axis tick labels. The default is \f(CW*-Courier-Bold-R-Normal-*-100-*\fR. .TP \fB\-ticklength \fIpixels\fR Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If \fIpixels\fR is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is \f(CW0.1i\fR. .TP \fB\-title \fItext\fR Sets the title of the axis. If \fItext\fR is \f(CW""\fR, no axis title will be displayed. .TP \fB\-titlecolor \fIcolor\fR Sets the color of the axis title. The default is \f(CWblack\fR. .TP \fB\-titlefont \fIfontName\fR Specifies the font for axis title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-14-140-*\fR. .PP Axis configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWAxis\fR. The resource names are the names of the axes (such as \f(CWx\fR or \f(CWx2\fR). .CS option add *Stripchart.Axis.Color blue option add *Stripchart.x.LogScale true option add *Stripchart.x2.LogScale false .CE .RE .TP \fIpathName \fBaxis \fBcreate \fIaxisName \fR?\fIoption value\fR?... Creates a new axis by the name \fIaxisName\fR. No axis by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBdelete \fR?\fIaxisName\fR?... Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. .TP \fIpathName \fBaxis invtransform \fIaxisName value\fR Performs the inverse transformation, changing the screen coordinate \fIvalue\fR to a graph coordinate, mapping the value mapped to \fIaxisName\fR. Returns the graph coordinate. .TP \fIpathName \fBaxis limits \fIaxisName\fR Returns a list of the minimum and maximum limits for \fIaxisName\fR. The order of the list is \f(CWmin max\fR. .TP \fIpathName \fBaxis names \fR?\fIpattern\fR?... Returns a list of axes matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all axes are returned. .TP \fIpathName \fBaxis transform \fIaxisName value\fR Transforms the coordinate \fIvalue\fR to a screen coordinate by mapping the it to \fIaxisName\fR. Returns the transformed screen coordinate. .PP Only four axes can be displayed simultaneously. By default, they are \f(CWx\fR, \f(CWy\fR, \f(CWx2\fR, and \f(CWy2\fR. You can swap in a different axis with \fBuse\fR operation of the special axis components: \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR. .CS \&.g create axis temp \&.g create axis time \&... \&.g xaxis use temp \&.g yaxis use time .CE Only the axes specified for use are displayed on the screen. .PP The \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR components operate on an axis location rather than a specific axis like the more general \fBaxis\fR component does. The \fBxaxis\fR component manages the X-axis located in the bottom margin (whatever axis that happens to be). Likewise, \fByaxis\fR uses the Y-axis in the left margin, \fBx2axis\fR the top X-axis, and \fBy2axis\fR the right Y-axis. .PP They implicitly control the axis that is currently using to that location. By default, \fBxaxis\fR uses the \f(CWx\fR axis, \fByaxis\fR uses \f(CWy\fR, \fBx2axis\fR uses \f(CWx2\fR, and \fBy2axis\fR uses \f(CWy2\fR. These components can be more convenient to use than always determining what axes are current being displayed by the graph. .PP The following operations are available for axes. They mirror exactly the operations of the \fBaxis\fR component. The \fIaxis\fR argument must be \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, or \fBy2axis\fR. .TP \fIpathName \fIaxis \fBcget \fIoption\fR .TP \fIpathName \fIaxis \fBconfigure \fR?\fIoption value\fR?... .TP \fIpathName \fIaxis\fB invtransform \fIvalue\fR .TP \fIpathName \fIaxis \fBlimits\fR .TP \fIpathName \fIaxis\fB transform \fIvalue\fR .TP \fIpathName \fIaxis\fB use \fR?\fIaxisName\fR? Designates the axis \fIaxisName\fR is to be displayed at this location. \fIAxisName\fR can not be already in use at another location. This command returns the name of the axis currently using this location. .SS "CROSSHAIRS COMPONENT" Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire strip chart. .PP The following operations are available for cross hairs: .TP \fIpathName \fBcrosshairs cget \fIoption\fR Returns the current value of the cross hairs configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the cross hairs \fBconfigure\fR operation. .TP \fIpathName \fBcrosshairs configure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the cross hairs. If \fIoption\fR isn't specified, a list describing all the current options for the cross hairs is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the cross hairs option \fIoption\fR is set to \fIvalue\fR. The following options are available for cross hairs. .RS .TP \fB\-color \fIcolor\fR Sets the color of the cross hairs. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the cross hairs. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the cross hairs will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether cross hairs are drawn. If \fIboolean\fR is true, cross hairs are not drawn. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the cross hair lines. The default is \f(CW1\fR. .TP \fB\-position \fIpos\fR Specifies the screen position where the cross hairs intersect. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates of the intersection. .PP Cross hairs configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWcrosshairs\fR and \f(CWCrosshairs\fR respectively. .CS option add *Stripchart.Crosshairs.LineWidth 2 option add *Stripchart.Crosshairs.Color red .CE .RE .TP \fIpathName \fBcrosshairs off\fR Turns of the cross hairs. .TP \fIpathName \fBcrosshairs on\fR Turns on the display of the cross hairs. .TP \fIpathName \fBcrosshairs toggle\fR Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. .SS "ELEMENT COMPONENTS" A data element represents a set of data. It contains x and y vectors containing the coordinates of the data points. Elements can be displayed with a symbol at each data point and lines connecting the points. Elements also control the appearance of the data, such as the symbol type, line width, color etc. .PP When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. .PP The following operations are available for elements. .TP \fIpathName \fBelement activate \fIelemName \fR?\fIindex\fR?... Specifies the data points of element \fIelemName\fR to be drawn using active foreground and background colors. \fIElemName\fR is the name of the element and \fIindex\fR is a number representing the index of the data point. If no indices are present then all data points become active. .TP \fIpathName \fBelement cget \fIelemName \fIoption\fR Returns the current value of the element configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the element \fBconfigure\fR operation. .TP \fIpathName \fBelement closest \fIx y\fR \fIvarName\fR ?\fIoption value\fR?... ?\fIelemName\fR?... Finds the data point closest to the window coordinates \fIx\fR and \fIy\fR in the element \fIelemName\fR. \fIElemName\fR is the name of an element, that must not be hidden. If no elements are specified, then all visible elements are searched. It returns via the array variable \fIvarName\fR the name of the closest element, the index of its closest point, and the graph coordinates of the point. Returns \f(CW0\fR, if no data point within the threshold distance can be found, otherwise \f(CW1\fR is returned. The following \fIoption\fR\-\fIvalue\fR pairs are available. .RS .TP \fB\-halo \fIpixels\fR Specifies a threshold distance where selected data points are ignored. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. If this option isn't specified, then it defaults to the value of the stripchart's \fB\-halo\fR option. .TP \fB\-interpolate \fIboolean\fR Indicates that both the data points and interpolated points along the line segment formed should be considered. If \fIboolean\fR is true, the closest line segment will be selected instead of the closest point. If this option isn't specified, \fIboolean\fR defaults to \f(CW0\fR. .RE .TP \fIpathName \fBelement configure \fIelemName \fR?\fIoption value\fR?... Queries or modifies the configuration options for elements. If \fIoption\fR isn't specified, a list describing all the current options for \fIelemName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the option \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the element option \fIoption\fR is set to \fIvalue\fR. The following options are valid for elements. .RS .TP \fB\-activepen \fIpenName\fR Specifies pen to use to draw active element. If \fIpenName\fR is \f(CW""\fR, no active elements will be drawn. The default is \f(CWactiveLine\fR. .TP \fB\-color \fIcolor\fR Sets the color of the traces connecting the data points. .TP \fB\-dashes \fIdashList\fR Sets the dash style of element line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the lines will be solid. .TP \fB\-data \fIcoordList\fR Specifies the X\-Y coordinates of the data. \fICoordList\fR is a list of numeric expressions representing the X\-Y coordinate pairs of each data point. .TP \fB\-fill \fIcolor\fR Sets the interior color of symbols. If \fIcolor\fR is \f(CW""\fR, then the interior of the symbol is transparent. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the element is displayed. The default is \f(CWno\fR. .TP \fB\-label \fItext\fR Sets the element's label in the legend. If \fItext\fR is \f(CW""\fR, the element will have no entry in the legend. The default label is the element's name. .TP \fB\-linewidth \fIpixels\fR Sets the width of the connecting lines between data points. If \fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between symbols. The default is \f(CW0\fR. .TP \fB\-mapx \fIxAxis\fR Selects the X\-axis to map the element's X\-coordinates onto. \fIXAxis\fR must be the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Selects the Y\-axis to map the element's Y\-coordinates onto. \fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR. .TP \fB\-offdash \fIcolor\fR Sets the color of the stripes when traces are dashed (see the \fB\-dashes\fR option). If \fIcolor\fR is \f(CW""\fR, then the "off" pixels will represent gaps instead of stripes. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outline \fIcolor\fR Sets the color or the outline around each symbol. If \fIcolor\fR is \f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outlinewidth \fIpixels\fR Sets the width of the outline bordering each symbol. If \fIpixels\fR is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR. .TP \fB\-pixels \fIpixels\fR Sets the size of symbols. If \fIpixels\fR is \f(CW0\fR, no symbols will be drawn. The default is \f(CW0.125i\fR. .TP \fB\-scalesymbols \fIboolean\fR If \fIboolean\fR is true, the size of the symbols drawn for \fIelemName\fR will change with scale of the X\-axis and Y\-axis. At the time this option is set, the current ranges of the axes are saved as the normalized scales (i.e scale factor is 1.0) and the element is drawn at its designated size (see the \fB\-pixels\fR option). As the scale of the axes change, the symbol will be scaled according to the smaller of the X\-axis and Y\-axis scales. If \fIboolean\fR is false, the element's symbols are drawn at the designated size, regardless of axis scales. The default is \f(CW0\fR. .TP \fB\-smooth \fIsmooth\fR Specifies how connecting line segments are drawn between data points. \fISmooth\fR can be either \f(CWlinear\fR, \f(CWstep\fR, \f(CWnatural\fR, or \f(CWquadratic\fR. If \fIsmooth\fR is \f(CWlinear\fR, a single line segment is drawn, connecting both data points. When \fIsmooth\fR is \f(CWstep\fR, two line segments are drawn. The first is a horizontal line segment which steps the next x-coordinate. The second is a vertical line, moving to the next y-coordinate. Both \fInatural\fR and \fIquadratic\fR generate multiple segments between data points. If \fInatural\fR, the segments are generated using a cubic spline. If \fIquadratic\fR, a quadratic spline is used. The default is \fIlinear\fR. .TP \fB\-styles \fIstyleList\fR Specifies what pen to use based upon the range of weights given. \fIStyleList\fR is a list of style specifications. Each style specification, in turn, is a list consisting of a pen name, and optionally a minimum and maximum range. Data points whose weight (see the \fB\-weight\fR option) falls in this range, are drawn with this pen. If no range is specified it defaults to the number of the pen in the list. .TP \fB\-symbol \fIsymbol\fR Specifies the symbol for data points. \fISymbol\fR can be either \f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR, \f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol is drawn), or a bitmap. Bitmaps are specified as "\fIsource\fR ?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and \fImask\fR is the bitmap's optional mask. The default is \f(CWcircle\fR. .TP \fB\-weights \fIwVec\fR Specifies the weights of the individual data points. This, in conjunction with the list pen styles (see the \fB\-styles\fR option) controls how data points are drawn. \fIWVec\fR is the name of a BLT vector or a list of numeric expressions representing the weights for each data point. .TP \fB\-xdata \fIxVec\fR Specifies the x-coordinates of the data. \fIXVec\fR is the name of a BLT vector or a list of numeric expressions. .TP \fB\-ydata \fIyVec\fR Specifies the y-coordinates of the data. \fIYVec\fR is the name of a BLT vector or a list of numeric expressions. .PP Element configuration options may also be set by the \fBoption\fR command. The resource class is \f(CWElement\fR. The resource name is the name of the element. .CS option add *Stripchart.Element.symbol line option add *Stripchart.e1.symbol line .CE .RE .TP \fIpathName \fBelement create \fIelemName\fR ?\fIoption value\fR?... Creates a new element \fIelemName\fR. It's an error is an element \fIelemName\fR already exists. If additional arguments are present, they specify options valid for element \fBconfigure\fR operation. .TP \fIpathName \fBelement deactivate \fIelemName\fR ?\fIelemName\fR?... Deactivates all the elements matching \fIpattern\fR. Elements whose names match any of the patterns given are redrawn using their normal colors. .TP \fIpathName \fBelement delete\fR ?\fIelemName\fR?... Deletes all the named elements. The graph is automatically redrawn. .TP \fIpathName \fBelement exists \fIelemName\fR Returns \f(CW1\fR if an element \fIelemName\fR currently exists and \f(CW0\fR otherwise. .TP \fIpathName \fBelement names \fR?\fIpattern\fR?... Returns the elements matching one or more pattern. If no \fIpattern\fR is given, the names of all elements is returned. .TP \fIpathName \fBelement show\fR ?\fInameList\fR? Queries or modifies the element display list. The element display list designates the elements drawn and in what order. \fINameList\fR is a list of elements to be displayed in the order they are named. If there is no \fInameList\fR argument, the current display list is returned. .TP \fIpathName \fBelement type\fR \fIelemName\fR Returns the type of \fIelemName\fR. If the element is a bar element, the commands returns the string \f(CW"bar"\fR, otherwise it returns \f(CW"line"\fR. .CE .SS "GRID COMPONENT" Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. .TP \fIpathName \fBgrid cget \fIoption\fR Returns the current value of the grid line configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the grid \fBconfigure\fR operation. .TP \fIpathName \fBgrid configure\fR ?\fIoption value\fR?... Queries or modifies the configuration options for grid lines. If \fIoption\fR isn't specified, a list describing all the current grid options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the grid line option \fIoption\fR is set to \fIvalue\fR. The following options are valid for grid lines. .RS .TP \fB\-color \fIcolor\fR Sets the color of the grid lines. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the grid lines. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the grid will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether the grid should be drawn. If \fIboolean\fR is true, grid lines are not shown. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of grid lines. The default width is \f(CW1\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to display grid lines. \fIXAxis\fR must be the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to display grid lines. \fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR. .TP \fB\-minor \fIboolean\fR Indicates whether the grid lines should be drawn for minor ticks. If \fIboolean\fR is true, the lines will appear at minor tick intervals. The default is \f(CW1\fR. .PP Grid configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWgrid\fR and \f(CWGrid\fR respectively. .CS option add *Stripchart.grid.LineWidth 2 option add *Stripchart.Grid.Color black .CE .RE .TP \fIpathName \fBgrid off\fR Turns off the display the grid lines. .TP \fIpathName \fBgrid on\fR Turns on the display the grid lines. .TP \fIpathName \fBgrid toggle\fR Toggles the display of the grid. .SS "LEGEND COMPONENT" The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. .PP The following operations are valid for the legend. .TP \fIpathName \fBlegend activate \fIpattern\fR... Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend cget \fIoption\fR Returns the current value of a legend configuration option. \fIOption\fR may be any option described below in the legend \fBconfigure\fR operation. .TP \fIpathName \fBlegend configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for the legend. If \fIoption\fR isn't specified, a list describing the current legend options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the legend option \fIoption\fR is set to \fIvalue\fR. The following options are valid for the legend. .RS .TP \fB\-activebackground \fIcolor\fR Sets the background color for active legend entries. All legend entries marked active (see the legend \fBactivate\fR operation) are drawn using this background color. .TP \fB\-activeborderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the active legend entries. The default is \f(CW2\fR. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color for active legend entries. All legend entries marked as active (see the legend \fBactivate\fR operation) are drawn using this foreground color. .TP \fB\-activerelief \fIrelief\fR Specifies the 3-D effect desired for active legend entries. \fIRelief\fR denotes how the interior of the entry should appear relative to the legend; for example, \f(CWraised\fR means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is \f(CWflat\fR. .TP \fB\-anchor \fIanchor\fR Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the \fB\-position\fR option. The default is \f(CWcenter\fR. .RS .TP 1.25i \f(CWleft\fR or \f(CWright\fR The anchor describes how to position the legend vertically. .TP \f(CWtop\fR or \f(CWbottom\fR The anchor describes how to position the legend horizontally. .TP \f(CW@x,y\fR The anchor specifies how to position the legend relative to the positioning point. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered on the point; if \fIanchor\fR is \f(CWn\fR then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. .TP \f(CWplotarea\fR The anchor specifies how to position the legend relative to the plotting area. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered in the plotting area; if \fIanchor\fR is \f(CWne\fR then the legend will be drawn such that occupies the upper right corner of the plotting area. .RE .TP \fB\-background \fIcolor\fR Sets the background color of the legend. If \fIcolor\fR is \f(CW""\fR, the legend background with be transparent. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the \fBrelief\fR option determines this). The default is \f(CW2\fR pixels. .TP \fB\-font \fIfontName\fR \fIFontName\fR specifies a font to use when drawing the labels of each element into the legend. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of the text drawn for the element's label. The default is \f(CWblack\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the legend should be displayed. If \fIboolean\fR is true, the legend will not be draw. The default is \f(CWno\fR. .TP \fB\-ipadx \fIpad\fR Sets the amount of internal padding to be added to the width of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-ipady \fIpad\fR Sets an amount of internal padding to be added to the height of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the entry is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom of the entry are padded evenly. The default is \f(CW2\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the legend is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW0\fR. .TP \fB\-position \fIpos\fR Specifies where the legend is drawn. The \fB\-anchor\fR option also affects where the legend is positioned. If \fIpos\fR is \f(CWleft\fR, \f(CWleft\fR, \f(CWtop\fR, or \f(CWbottom\fR, the legend is drawn in the specified margin. If \fIpos\fR is \f(CWplotarea\fR, then the legend is drawn inside the plotting area at a particular anchor. If \fIpos\fR is in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is \f(CWright\fR. .TP \fB\-raised \fIboolean\fR Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If \fIboolean\fR is true, the legend will be drawn on top of any elements that may overlap it. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the border around the legend. \fIRelief\fR specifies how the interior of the legend should appear relative to the strip chart; for example, \f(CWraised\fR means the legend should appear to protrude from the strip chart, relative to the surface of the strip chart. The default is \f(CWsunken\fR. .PP Legend configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWlegend\fR and \f(CWLegend\fR respectively. .CS option add *Stripchart.legend.Foreground blue option add *Stripchart.Legend.Relief raised .CE .RE .TP \fIpathName \fBlegend deactivate \fIpattern\fR... Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend get \fIpos\fR Returns the name of the element whose entry is at the screen position \fIpos\fR in the legend. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are window coordinates. If the given coordinates do not lie over a legend entry, \f(CW""\fR is returned. .SS "PEN COMPONENTS" Pens define attributes (both symbol and line style) for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .PP One pen, called \f(CWactiveLine\fR, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. .CS \&.s pen configure "activeLine" -color green .CE You can create and use any number of pens. To create a pen, invoke the pen component and its create operation. .CS \&.s pen create myPen .CE You map pens to a data element using either the element's \fB\-pen\fR or \fB\-activepen\fR options. .CS \&.s element create "line1" -xdata $x -ydata $tempData \\ -pen myPen .CE An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the \fB\-styles\fR option). .CS \&.s element configure "line1" -styles { myPen 2.0 3.0 } .CE This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen \f(CWmyPen\fR. All other points are drawn with the element's default attributes. .PP The following operations are available for pen components. .PP .TP \fIpathName \fBpen \fBcget \fIpenName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIpenName\fR. \fIOption\fR may be any option described below for the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBconfigure \fIpenName \fR?\fIoption value\fR?... Queries or modifies the configuration options of \fIpenName\fR. If \fIoption\fR isn't specified, a list describing the current options for \fIpenName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the pen option \fIoption\fR is set to \fIvalue\fR. The following options are valid for pens. .RS .TP \fB\-color \fIcolor\fR Sets the color of the traces connecting the data points. .TP \fB\-dashes \fIdashList\fR Sets the dash style of element line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the lines will be solid. .TP \fB\-fill \fIcolor\fR Sets the interior color of symbols. If \fIcolor\fR is \f(CW""\fR, then the interior of the symbol is transparent. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the connecting lines between data points. If \fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between symbols. The default is \f(CW0\fR. .TP \fB\-offdash \fIcolor\fR Sets the color of the stripes when traces are dashed (see the \fB\-dashes\fR option). If \fIcolor\fR is \f(CW""\fR, then the "off" pixels will represent gaps instead of stripes. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outline \fIcolor\fR Sets the color or the outline around each symbol. If \fIcolor\fR is \f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outlinewidth \fIpixels\fR Sets the width of the outline bordering each symbol. If \fIpixels\fR is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR. .TP \fB\-pixels \fIpixels\fR Sets the size of symbols. If \fIpixels\fR is \f(CW0\fR, no symbols will be drawn. The default is \f(CW0.125i\fR. .TP \fB\-symbol \fIsymbol\fR Specifies the symbol for data points. \fISymbol\fR can be either \f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR, \f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol is drawn), or a bitmap. Bitmaps are specified as "\fIsource\fR ?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and \fImask\fR is the bitmap's optional mask. The default is \f(CWcircle\fR. .TP \fB\-type \fIelemType\fR Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "line". .PP Pen configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWPen\fR. The resource names are the names of the pens. .CS option add *Stripchart.Pen.Color blue option add *Stripchart.activeLine.color green .CE .RE .TP \fIpathName \fBpen \fBcreate \fIpenName \fR?\fIoption value\fR?... Creates a new pen by the name \fIpenName\fR. No pen by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBdelete \fR?\fIpenName\fR?... Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. .TP \fIpathName \fBpen names \fR?\fIpattern\fR?... Returns a list of pens matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all pens are returned. .SS "POSTSCRIPT COMPONENT" The strip chart can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot is generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. .PP The following postscript operations are available. .TP \fIpathName \fBpostscript cget \fIoption\fR Returns the current value of the postscript option given by \fIoption\fR. \fIOption\fR may be any option described below for the postscript \fBconfigure\fR operation. .TP \fIpathName \fBpostscript configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for PostScript generation. If \fIoption\fR isn't specified, a list describing the current postscript options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the postscript option \fIoption\fR is set to \fIvalue\fR. The following postscript options are available. .RS .TP \fB\-center \fIboolean\fR Indicates whether the plot should be centered on the PostScript page. If \fIboolean\fR is false, the plot will be placed in the upper left corner of the page. The default is \f(CW1\fR. .TP \fB\-colormap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of \fIvarName\fR must consist of PostScript code to set a particular color value (e.g. ``\f(CW1.0 1.0 0.0 setrgbcolor\fR''). When outputting color information in PostScript, the array variable \fIvarName\fR is checked to see if an element of the name of the color exists. If so, it uses the value of the element as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in \fIvarName\fR for a given color, then it uses the red, green, and blue intensities from the X color. .TP \fB\-colormode \fImode\fR Specifies how to output color information. \fIMode\fR must be either \f(CWcolor\fR (for full color output), \f(CWgray\fR (convert all colors to their gray-scale equivalents) or \f(CWmono\fR (convert foreground colors to black and background colors to white). The default mode is \f(CWcolor\fR. .TP \fB\-fontmap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of \fIvarName\fR must consist of a Tcl list with one or two elements, which are the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable \fIvarName\fR is checked to see an element of the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is \fIAdobe\fR (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to \f(CWHelvetica-Bold\fR. .TP \fB\-decorations \fIboolean\fR Indicates if PostScript commands to generate color backgrounds and 3-D borders should be output. If \fIboolean\fR is false, the background will be white and no 3-D borders will be generated. The default is \f(CW1\fR. .TP \fB\-height \fIpixels\fR Sets the height of the plot. This lets you plot the stripchart with a height different from the one displayed on the screen. If \fIpixels\fR is 0, the height is the same as the displayed height. The default is \f(CW0\fR. .TP \fB\-landscape \fIboolean\fR If \fIboolean\fR is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to \f(CW0\fR. .TP \fB\-maxpect \fIboolean\fR Indicates to scale the the plot so that it fills the PostScript page. The aspect ratio of the strip chart is still retained. The default is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left border is padded by the first distance and the right border by the second. If \fIpad\fR has just one distance, both the left and right borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-pady \fIpad\fR Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top border is padded by the first distance and the bottom border by the second. If \fIpad\fR has just one distance, both the top and bottom borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-paperheight \fIpixels\fR Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is \f(CW11.0i\fR. .TP \fB\-paperwidth \fIpixels\fR Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is \f(CW8.5i\fR. .TP \fB\-width \fIpixels\fR Sets the width of the plot. This lets you plot the strip chart with a width different from the one drawn on the screen. If \fIpixels\fR is 0, the width is the same as the widget's width. The default is \f(CW0\fR. .PP Postscript configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWpostscript\fR and \f(CWPostscript\fR respectively. .CS option add *Stripchart.postscript.Decorations false option add *Stripchart.Postscript.Landscape true .CE .RE .TP \fIpathName \fBpostscript output \fR?\fIfileName\fR? ?\fIoption value\fR?... Outputs a file of encapsulated PostScript. If a \fIfileName\fR argument isn't present, the command returns the PostScript. If any \fIoption-value\fR pairs are present, they set configuration options controlling how the PostScript is generated. \fIOption\fR and \fIvalue\fR can be anything accepted by the postscript \fBconfigure\fR operation above. .SS "MARKER COMPONENTS" Markers are simple drawing procedures used to annotate or highlight areas of the strip chart. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the \fB\-under\fR option. .PP Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have \fIelastic\fR coordinates (specified by \f(CW-Inf\fR and \f(CWInf\fR respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates \f(CW-Inf\fR,\f(CW-Inf\fR. .PP The following operations are available for markers. .TP \fIpathName \fBmarker after \fImarkerId\fR ?\fIafterId\fR? Changes the order of the markers, drawing the first marker after the second. If no second \fIafterId\fR argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker before \fImarkerId\fR ?\fIbeforeId\fR? Changes the order of the markers, drawing the first marker before the second. If no second \fIbeforeId\fR argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker cget \fIoption\fR Returns the current value of the marker configuration option given by \fIoption\fR. \fIOption\fR may be any option described below in the \fBconfigure\fR operation. .TP \fIpathName \fBmarker configure \fImarkerId\fR ?\fIoption value\fR?... Queries or modifies the configuration options for markers. If \fIoption\fR isn't specified, a list describing the current options for \fImarkerId\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the marker option \fIoption\fR is set to \fIvalue\fR. .sp The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. .RS .TP \fB\-coords \fIcoordList\fR Specifies the coordinates of the marker. \fICoordList\fR is a list of graph coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X\-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If \fIcoordList\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-element \fIelemName\fR Links the marker with the element \fIelemName\fR. The marker is drawn only if the element is also currently displayed (see the element's \fBshow\fR operation). If \fIelemName\fR is \f(CW""\fR, the marker is always drawn. The default is \f(CW""\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the marker is drawn. If \fIboolean\fR is true, the marker is not drawn. The default is \f(CWno\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to map the marker's X\-coordinates onto. \fIXAxis\fR must the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to map the marker's Y\-coordinates onto. \fIYAxis\fR must the name of an axis. The default is \f(CWy\fR. .TP \fB\-name \fImarkerId\fR Changes the identifier for the marker. The identifier \fImarkerId\fR can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. .TP \fB\-under \fIboolean\fR Indicates whether the marker is drawn below/above data elements. If \fIboolean\fR is true, the marker is be drawn underneath the data element symbols and lines. Otherwise, the marker is drawn on top of the element. The default is \f(CW0\fR. .TP \fB\-xoffset \fIpixels\fR Specifies a screen distance to offset the marker horizontally. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .TP \fB\-yoffset \fIpixels\fR Specifies a screen distance to offset the markers vertically. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .PP Marker configuration options may also be set by the \fBoption\fR command. The resource class is either \f(CWBitmapMarker\fR, \f(CWImageMarker\fR, \f(CWLineMarker\fR, \f(CWPolygonMarker\fR, \f(CWTextMarker\fR, or \f(CWWindowMarker\fR, depending on the type of marker. The resource name is the name of the marker. .CS option add *Stripchart.TextMarker.Foreground white option add *Stripchart.BitmapMarker.Foreground white option add *Stripchart.m1.Background blue .CE .RE .TP \fIpathName \fBmarker create \fItype\fR ?\fIoption value\fR?... Creates a marker of the selected type. \fIType\fR may be either \f(CWtext\fR, \f(CWline\fR, \f(CWbitmap\fR, \f(CWimage\fR, \f(CWpolygon\fR, or \f(CWwindow\fR. This command returns the marker identifier, used as the \fImarkerId\fR argument in the other marker-related commands. If the \fB\-name\fR option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. .TP \fIpathName \fBmarker delete\fR ?\fIname\fR?... Removes one of more markers. The graph will automatically be redrawn without the marker.\fR. .TP \fIpathName \fBmarker exists \fImarkerId\fR Returns \f(CW1\fR if the marker \fImarkerId\fR exists and \f(CW0\fR otherwise. .TP \fIpathName \fBmarker names\fR ?\fIpattern\fR? Returns the names of all the markers that currently exist. If \fIpattern\fR is supplied, only those markers whose names match it will be returned. .TP \fIpathName \fBmarker type \fImarkerId\fR Returns the type of the marker given by \fImarkerId\fR, such as \f(CWline\fR or \f(CWtext\fR. If \fImarkerId\fR is not a valid a marker identifier, \f(CW""\fR is returned. .SS "BITMAP MARKERS" A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. .PP Bitmap markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create bitmap \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration options for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to bitmap markers: .TP \fB\-background \fIcolor\fR Sets the background color of the bitmap. If \fIcolor\fR is \f(CW""\fR, the background color will be transparent. The default background color is \f(CWwhite\fR. .TP \fB\-bitmap \fIbitmap\fR Specifies the bitmap to be displayed. If \fIbitmap\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of the bitmap. The default foreground color is \f(CWblack\fR. .TP \fB\-mask \fImask\fR Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If \fImask\fR is \f(CW""\fR, all pixels of the bitmap will be drawn. The default is \f(CW""\fR. .TP \fB\-rotate \fItheta\fR Sets the rotation of the bitmap. \fITheta\fR is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is \f(CW0.0\fR. .SS "IMAGE MARKERS" A image marker displays an image. Image markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create image \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to image markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the image relative to the positioning point for the image. For example, if \fIanchor\fR is \f(CWcenter\fR then the image is centered on the point; if \fIanchor\fR is \f(CWn\fR then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-image \fIimage\fR Specifies the image to be drawn. If \fIimage\fR is \f(CW""\fR, the marker will not be drawn. The default is \f(CW""\fR. .SS "LINE MARKERS" A line marker displays one or more connected line segments. Line markers are created with marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create line \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to line markers: .TP \fB\-background \fIcolor\fR Sets the background color of the line. The option is affects the line color only when the \fB\-stipple\fR option is set. If this option isn't specified then it defaults to \f(CWwhite\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the marker line will be solid. .TP \fB\-foreground \fIcolor\fR Sets the foreground color. The default foreground color is \f(CWblack\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the lines. The default width is \f(CW0\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern used to draw the line, rather than a solid line. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the line is drawn in a solid fashion. The default is \f(CW""\fR. .SS "POLYGON MARKERS" A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create polygon \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the \fBmarker configure\fR command to change the marker's configuration. The following options are supported for polygon markers: .TP \fB\-dashes \fIdashList\fR Sets the dash style of the outline of the polygon. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line. .TP \fB\-fill \fIcolor\fR Sets the fill color of the polygon. If \fIcolor\fR is \f(CW""\fR, then the interior of the polygon is transparent. The default is \f(CWwhite\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the outline of the polygon. If \fIpixels\fR is zero, no outline is drawn. The default is \f(CW0\fR. .TP \fB\-outline \fIcolor\fR Sets the color of the outline of the polygon. If the polygon is stippled (see the \fB\-stipple\fR option), then this represents the foreground color of the stipple. The default is \f(CWblack\fR. .TP \fB\-stipple \fIbitmap\fR Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the polygon is filled with a solid color (if the \fB\-fill\fR option is set). The default is \f(CW""\fR. .SS "TEXT MARKERS" A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the strip chart. Text markers are created with the \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create text \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the text marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to text markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the text relative to the positioning point for the text. For example, if \fIanchor\fR is \f(CWcenter\fR then the text is centered on the point; if \fIanchor\fR is \f(CWn\fR then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Sets the background color of the text string. If \fIcolor\fR is \f(CW""\fR, the background will be transparent. The default is \f(CWwhite\fR. .TP \fB\-font \fIfontName\fR Specifies the font of the text. The default is \f(CW*-Helvetica-Bold-R-Normal-*-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of the text. The default is \f(CWblack\fR. .TP \fB\-justify \fIjustify\fR Specifies how the text should be justified. This matters only when the marker contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the text is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the text is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW4\fR. .TP \fB\-rotate \fItheta\fR Specifies the number of degrees to rotate the text. \fITheta\fR is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is \f(CW0.0\fR. .TP \fB\-text \fItext\fR Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as \fB\-anchor\fR or \fB\-rotate\fR. .SS "WINDOW MARKERS" A window marker displays a widget at a given position. Window markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create window \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR command. .PP The following options are specific to window markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the widget relative to the positioning point for the widget. For example, if \fIanchor\fR is \f(CWcenter\fR then the widget is centered on the point; if \fIanchor\fR is \f(CWn\fR then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-height \fIpixels\fR Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever height the widget requests internally. .TP \fB\-width \fIpixels\fR Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever width the widget requests internally. .TP \fB\-window \fIpathName\fR Specifies the widget to be managed. \fIPathName\fR must be a child of the \fBstripchart\fR widget. .SH "GRAPH COMPONENT BINDINGS" Specific stripchart components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR). .sp Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. .sp It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the \fB\-bindtags\fR option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. .sp The \fB\-bindtags\R option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the \fB\-bindtags\fR option doesn't change this. .SH "C LANGUAGE API" You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. .PP Data can manipulated from the C language using BLT vectors. You specify the x and y data coordinates of an element as vectors and manipulate the vector from C. The strip chart will be redrawn automatically after the vectors are updated. .PP From Tcl, create the vectors and configure the element to use them. .CS vector X Y \&.s element configure line1 -xdata X -ydata Y .CE To set data points from C, you pass the values as arrays of doubles using the \fBBlt_ResetVector\fR call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the strip chart will be redrawn automatically. .CS #include <tcl.h> #include <blt.h> register int i; Blt_Vector *xVec, *yVec; double x[50], y[50]; /* Get the BLT vectors "X" and "Y" (created above from Tcl) */ if ((Blt_GetVector(interp, "X", 50, &xVec) != TCL_OK) || (Blt_GetVector(interp, "Y", 50, &yVec) != TCL_OK)) { return TCL_ERROR; } for (i = 0; i < 50; i++) { x[i] = i * 0.02; y[i] = sin(x[i]); } /* Put the data into BLT vectors */ if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) || (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) { return TCL_ERROR; } .CE See the \fBvector\fR manual page for more details. .SH SPEED TIPS There may be cases where the strip chart needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. .TP 2 \(bu Try to minimize the number of data points. The more data points the looked at, the more work the strip chart must do. .TP 2 \(bu If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. .TP 2 \(bu Data elements without symbols are drawn faster than with symbols. Set the data element's \fB\-symbol\fR option to \f(CWnone\fR. If you need to draw symbols, try using the simple symbols such as \f(CWsplus\fR and \f(CWscross\fR. .TP 2 \(bu Don't stipple or dash the element. Solid lines are much faster. .TP 2 \(bu If you update data elements frequently, try turning off the widget's \fB\-bufferelements\fR option. When the strip chart is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the strip chart needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the strip chart. But if the strip chart is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. .SH LIMITATIONS Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. .PP The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. .SH "FUTURE INCOMPATIBILITY" The \fB\-mapped\fR options are obsoleted and will be removed. You can achieve the same results using the \fB\-hide\fR option instead. .CS # Works for now. \&.s legend configure -mapped no # Instead use this. \&.s legend configure -hide yes .CE .SH KEYWORDS stripchart, graph, widget �������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/barchart.mann�����������������������������������������������������������������0000644�0001750�0001750�00000273227�11462120062�015467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Barchart widget created by Sani Nassif and George Howlett. '\" .so man.macros .TH barchart n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME barchart \- Bar chart for plotting X-Y coordinate data. .SH SYNOPSIS \fBbarchart\fI \fIpathName \fR?\fIoption value\fR?... .BE .SH DESCRIPTION The \fBbarchart\fR command creates a bar chart for plotting two-dimensional data (X-Y coordinates). A bar chart is a graphic means of comparing numbers by displaying bars of lengths proportional to the y-coordinates of the points they represented. The bar chart has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the graph. .SH INTRODUCTION The \fBbarchart\fR command creates a new window for plotting two-dimensional data (X-Y coordinates), using bars of various lengths to represent the data points. The bars are drawn in a rectangular area displayed in the center of the new window. This is the \fIplotting area\fR. The coordinate axes are drawn in the margins surrounding the plotting area. By default, the legend is drawn in the right margin. The title is displayed in top margin. .PP A \fBbarchart\fR widget has several configurable components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. Each component can be queried or modified. .TP 1i \f(CWaxis\fR Up to four coordinate axes (two X\-coordinate and two Y\-coordinate axes) can be displayed, but you can create and use any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value at each major tick. .TP 1i \f(CWcrosshairs\fR Cross hairs are used to position the mouse pointer relative to the X and Y coordinate axes. Two perpendicular lines, intersecting at the current location of the mouse, extend across the plotting area to the coordinate axes. .TP 1i \f(CWelement\fR An element represents a set of data to be plotted. It contains an x and y vector of values representing the data points. Each data point is displayed as a bar where the length of the bar is proportional to the ordinate (Y-coordinate) of the data point. The appearance of the bar, such as its color, stipple, or relief is configurable. .sp A special case exists when two or more data points have the same abscissa (X-coordinate). By default, the bars are overlayed, one on top of the other. The bars are drawn in the order of the element display list. But you can also configure the bars to be displayed in two other ways. They may be displayed as a stack, where each bar (with the same abscissa) is stacked on the previous. Or they can be drawn side-by-side as thin bars. The width of each bar is a function of the number of data points with the same abscissa. .TP 1i \f(CWgrid\fR Extends the major and minor ticks of the X\-axis and/or Y\-axis across the plotting area. .TP 1i \f(CWlegend\fR The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. .TP 1i \f(CWmarker\fR Markers are used annotate or highlight areas of the graph. For example, you could use a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. .TP 1i \f(CWpen\fR Pens define attributes for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here the particular pen used for a data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .TP 1i \f(CWpostscript\fR The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. .SH SYNTAX .DS \fBbarchart \fIpathName \fR?\fIoption value\fR?... .DE The \fBbarchart\fR command creates a new window \fIpathName\fR and makes it into a \fBbarchart\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the graph such as its colors and font. See the \fBconfigure\fR operation below for the exact details about what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBbarchart\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the graph. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for the graph are described in the .SB "BARCHART OPERATIONS" section. .PP The command can also be used to access components of the graph. .DS \fIpathName component operation\fR ?\fIarg\fR?... .DE The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. .SH EXAMPLE The \fBbarchart\fR command creates a new bar chart. .CS # Create a new bar chart. Plotting area is black. barchart .b -plotbackground black .CE A new Tcl command \f(CW.b\fR is created. This command can be used to query and modify the bar chart. For example, to change the title of the graph to "My Plot", you use the new command and the \fBconfigure\fR operation. .CS # Change the title. \&.b configure -title "My Plot" .CE To add data elements, you use the command and the \fBelement\fR component. .CS # Create a new element named "e1" \&.b element create e1 \\ -xdata { 1 2 3 4 5 6 7 8 9 10 } \\ -ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } .CE The element's X-Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X-Y coordinates. .CS # Create two vectors and add them to the barchart. vector xVector yVector xVector set { 1 2 3 4 5 6 7 8 9 10 } yVector set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } \&n.b element create e1 -xdata xVector -ydata yVector .CE The advantage of using vectors is that when you modify one, the graph is automatically redrawn to reflect the new values. .CS # Change the y coordinate of the first point. set yVector(0) 25.18 .CE An element named \f(CWe1\fR is now created in \f(CW.b\fR. It is automatically added to the display list of elements. You can use this list to control in what order elements are displayed. To query or reset the element display list, you use the element's \fBshow\fR operation. .CS # Get the current display list set elemList [.b element show] # Remove the first element so it won't be displayed. \&.b element show [lrange $elemList 0 end] .CE The element will be displayed by as many bars as there are data points (in this case there are ten). The bars will be drawn centered at the x-coordinate of the data point. All the bars will have the same attributes (colors, stipple, etc). The width of each bar is by default one unit. You can change this with using the \fB\-barwidth\fR option. .CS # Change the scale of the x-coordinate data xVector set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } # Make sure we change the bar width too. \&.b configure -barwidth 0.2 .CE The height of each bar is proportional to the ordinate (Y-coordinate) of the data point. .PP If two or more data points have the same abscissa (X-coordinate value), the bars representing those data points may be drawn in various ways. The default is to overlay the bars, one on top of the other. The ordering is determined from the of element display list. If the stacked mode is selected (using the \fB\-barmode\fR configuration option), the bars are stacked, each bar above the previous. .CS # Display the elements as stacked. \&.b configure -barmode stacked .CE If the aligned mode is selected, the bars having the same x-coordinates are displayed side by side. The width of each bar is a fraction of its normal width, based upon the number of bars with the same x-coordinate. .CS # Display the elements side-by-side. \&.b configure -barmode aligned .CE By default, the element's label in the legend will be also \f(CWe1\fR. You can change the label, or specify no legend entry, again using the element's \fBconfigure\fR operation. .CS # Don't display "e1" in the legend. \&.b element configure e1 -label "" .CE You can configure more than just the element's label. An element has many attributes such as stipple, foreground and background colors, relief, etc. .CS \&.b element configure e1 -fg red -bg pink \\ -stipple gray50 .CE Four coordinate axes are automatically created: \f(CWx\fR, \f(CWx2\fR, \f(CWy\fR, and \f(CWy2\fR. And by default, elements are mapped onto the axes \f(CWx\fR and \f(CWy\fR. This can be changed with the \fB\-mapx\fR and \fB\-mapy\fR options. .CS # Map "e1" on the alternate y axis "y2". \&.b element configure e1 -mapy y2 .CE Axes can be configured in many ways too. For example, you change the scale of the Y\-axis from linear to log using the \fBaxis\fR component. .CS # Y-axis is log scale. \&.b axis configure y -logscale yes .CE One important way axes are used is to zoom in on a particular data region. Zooming is done by simply specifying new axis limits using the \fB\-min\fR and \fB\-max\fR configuration options. .CS \&.b axis configure x \-min 1.0 \-max 1.5 \&.b axis configure y \-min 12.0 \-max 55.15 .CE To zoom interactively, you link the\fBaxis configure\fR operations with some user interaction (such as pressing the mouse button), using the \fBbind\fR command. To convert between screen and graph coordinates, use the \fBinvtransform\fR operation. .CS # Click the button to set a new minimum bind .b <ButtonPress-1> { %W axis configure x \-min [%W axis invtransform x %x] %W axis configure x \-min [%W axis invtransform x %y] } .CE By default, the limits of the axis are determined from data values. To reset back to the default limits, set the \fB\-min\fR and \fB\-max\fR options to the empty value. .CS # Reset the axes to autoscale again. \&.b axis configure x \-min {} \-max {} \&.b axis configure y \-min {} \-max {} .CE By default, the legend is drawn in the right margin. You can change this or any legend configuration options using the \fBlegend\fR component. .CS # Configure the legend font, color, and relief \&.b legend configure -position left -relief raised \\ -font fixed -fg blue .CE To prevent the legend from being displayed, turn on the \fB\-hide\fR option. .CS # Don't display the legend. \&.b legend configure \-hide yes\fR .CE The \fBbarchart\fR has simple drawing procedures called markers. They can be used to highlight or annotate data in the graph. The types of markers available are bitmaps, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. For example there may be a line marker which indicates some low-water value. Markers are created using the \fBmarker\fR operation. .CS # Create a line represent the low water mark at 10.0 \&.b marker create line -name "low_water" \\ -coords { -Inf 10.0 Inf 10.0 } \\ -dashes { 2 4 2 } -fg red -bg blue .CE This creates a line marker named \f(CWlow_water\fR. It will display a horizontal line stretching across the plotting area at the y-coordinate 10.0. The coordinates "-Inf" and "Inf" indicate the relative minimum and maximum of the axis (in this case the x-axis). By default, markers are drawn last, on top of the bars. You can change this with the \fB\-under\fR option. .CS # Draw the marker before elements are drawn. \&.b marker configure low_water -under yes .CE You can add cross hairs or grid lines using the \fBcrosshairs\fR and \fBgrid\fR components. .CS # Display both cross hairs and grid lines. \&.b crosshairs configure -hide no -color red \&.b grid configure -hide no -dashes { 2 2 } .CE Finally, to get hardcopy of the graph, use the \fBpostscript\fR component. .CS # Print the bar chart into file "file.ps" \&.b postscript output file.ps -maxpect yes -decorations no .CE This generates a file \f(CWfile.ps\fR containing the encapsulated PostScript of the graph. The option \fB\-maxpect\fR says to scale the plot to the size of the page. Turning off the \fB\-decorations\fR option denotes that no borders or color backgrounds should be drawn (i.e. the background of the margins, legend, and plotting area will be white). .SH SYNTAX .DS \fBbarchart \fIpathName \fR?\fIoption value\fR?... .DE The \fBbarchart\fR command creates a new window \fIpathName\fR and makes it into a barchart widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may may be specified on the command line or in the option database to configure aspects of the bar chart such as its colors and font. See the \fBconfigure\fR operation below for the exact details as to what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBbarchart\fR returns \fIpathName\fR. It also creates a new Tcl command \fIpathName\fR. This command may be used to invoke various operations to query or modify the bar chart. It has the general form: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for the bar chart are described in the following section. .SH "BARCHART OPERATIONS" .TP \fIpathName \fBbar \fIelemName \fR?\fIoption value\fR?... Creates a new barchart element \fIelemName\fR. It's an error if an element \fIelemName\fR already exists. See the manual for \fBbarchart\fR for details about what \fIoption\fR and \fIvalue\fR pairs are valid. .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the \fBconfigure\fR operation. .TP \fIpathName \fBconfigure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the graph. If \fIoption\fR isn't specified, a list describing the current options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the option \fIoption\fR is set to \fIvalue\fR. The following options are valid. .RS .TP \fB\-background \fIcolor\fR Sets the background color. This includes the margins and legend, but not the plotting area. .TP \fB\-barmode \fImode\fR Indicates how related bar elements will be drawn. Related elements have data points with the same abscissas (X-coordinates). \fIMode\fR indicates how those segments should be drawn. \fIMode\fR can be \f(CWinfront\fR, \f(CWaligned\fR, \f(CWoverlap\fR, or \f(CWstacked\fR. The default mode is \f(CWinfront\fR. .RS .TP 1i \f(CWinfront\fR Each successive segment is drawn in front of the previous. .TP 1i \f(CWstacked\fR Each successive segment is stacked vertically on top of the previous. .TP 1i \f(CWaligned\fR Segments is displayed aligned from right-to-left. .TP 1i \f(CWoverlap\fR Like \f(CWaligned\fR but segments slightly overlap each other. .RE .TP \fB\-barwidth \fIvalue\fR Specifies the width of the bars. This value can be overrided by the individual elements using their \fB\-barwidth\fR configuration option. \fIValue\fR is the width in terms of graph-coordinates. The default width is \f(CW1.0\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-bottommargin \fIpixels\fR Specifies the size of the margin below the X\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the size of the margin is selected automatically. The default is \f(CW0\fR. .TP \fB\-bufferelements \fIboolean\fR Indicates whether an internal pixmap to buffer the display of data elements should be used. If \fIboolean\fR is true, data elements are drawn to an internal pixmap. This option is especially useful when the graph is redrawn frequently while the remains data unchanged (for example, moving a marker across the plot). See the .SB "SPEED TIPS" section. The default is \f(CW1\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CWcrosshair\fR. .TP \fB\-font \fIfontName\fR Specifies the font of the graph title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR. .TP \fB\-halo \fIpixels\fR Specifies a maximum distance to consider when searching for the closest data point (see the element's \fBclosest\fR operation below). Data points further than \fIpixels\fR away are ignored. The default is \f(CW0.5i\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW4i\fR. .TP \fB\-invertxy \fIboolean\fR Indicates whether the placement X\-axis and Y\-axis should be inverted. If \fIboolean\fR is true, the X and Y axes are swapped. The default is \f(CW0\fR. .TP \fB\-justify \fIjustify\fR Specifies how the title should be justified. This matters only when the title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-leftmargin \fIpixels\fR Sets the size of the margin from the left edge of the window to the Y\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the size is calculated automatically. The default is \f(CW0\fR. .TP \fB\-plotbackground \fIcolor\fR Specifies the background color of the plotting area. The default is \f(CWwhite\fR. .TP \fB\-plotborderwidth \fIpixels\fR Sets the width of the 3-D border around the plotting area. The \fB\-plotrelief\fR option determines if a border is drawn. The default is \f(CW2\fR. .TP \fB\-plotpadx \fIpad\fR Sets the amount of padding to be added to the left and right sides of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotpady \fIpad\fR Sets the amount of padding to be added to the top and bottom of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotrelief \fIrelief\fR Specifies the 3-D effect for the plotting area. \fIRelief\fR specifies how the interior of the plotting area should appear relative to rest of the graph; for example, \f(CWraised\fR means the plot should appear to protrude from the graph, relative to the surface of the graph. The default is \f(CWsunken\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the barchart widget. \fIRelief\fR specifies how the graph should appear relative to widget it is packed into; for example, \f(CWraised\fR means the graph should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-rightmargin \fIpixels\fR Sets the size of margin from the plotting area to the right edge of the window. By default, the legend is drawn in this margin. If \fIpixels\fR is than 1, the margin size is selected automatically. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW""\fR. .TP \fB\-tile \fIimage\fR Specifies a tiled background for the widget. If \fIimage\fR isn't \f(CW""\fR, the background is tiled using \fIimage\fR. Otherwise, the normal background color is drawn (see the \fB\-background\fR option). \fIImage\fR must be an image created using the Tk \fBimage\fR command. The default is \f(CW""\fR. .TP \fB\-title \fItext\fR Sets the title to \fItext\fR. If \fItext\fR is \f(CW""\fR, no title will be displayed. .TP \fB\-topmargin \fIpixels\fR Specifies the size of the margin above the x2 axis. If \fIpixels\fR is \f(CW0\fR, the margin size is calculated automatically. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. The default is \f(CW5i\fR. .RE .TP \fIpathName \fBcrosshairs \fIoperation \fR?\fIarg\fR? See the .SB "CROSSHAIRS COMPONENT" section. .TP \fIpathName \fBelement \fIoperation \fR?\fIarg\fR?... See the .SB "ELEMENT COMPONENTS" section. .TP \fIpathName \fBextents \fIitem\fR Returns the size of a particular item in the graph. \fIItem\fR must be either \f(CWleftmargin\fR, \f(CWrightmargin\fR, \f(CWtopmargin\fR, \f(CWbottommargin\fR, \f(CWplotwidth\fR, or \f(CWplotheight\fR. .TP \fIpathName \fBgrid \fIoperation \fR?\fIarg\fR?... See the .SB "GRID COMPONENT" section. .TP \fIpathName \fBinvtransform \fIwinX winY\fR Performs an inverse coordinate transformation, mapping window coordinates back to graph-coordinates, using the standard X\-axis and Y\-axis. Returns a list of containing the X-Y graph-coordinates. .TP \fIpathName \fBinside \fIx y\fR Returns \f(CW1\fR is the designated screen-coordinate (\fIx\fR and \fIy\fR) is inside the plotting area and \f(CW0\fR otherwise. .TP \fIpathName \fBlegend \fIoperation \fR?\fIarg\fR?... See the .SB "LEGEND COMPONENT" section. .TP \fIpathName \fBline\fB operation arg\fR... The operation is the same as \fBelement\fR. .TP \fIpathName \fBmarker \fIoperation \fR?\fIarg\fR?... See the .SB "MARKER COMPONENTS" section. .TP \fIpathName\fR \fBmetafile\fR ?\fIfileName\fR? \fIThis operation is for Window platforms only\fR. Creates a Windows enhanced metafile of the barchart. If present, \fIfileName\fR is the file name of the new metafile. Otherwise, the metafile is automatically added to the clipboard. .TP \fIpathName \fBpostscript \fIoperation \fR?\fIarg\fR?... See the .SB "POSTSCRIPT COMPONENT" section. .TP \fIpathName \fBsnap \fIphotoName\fR Takes a snapshot of the graph and stores the contents in the photo image \fIphotoName\fR. \fIPhotoName\fR is the name of a Tk photo image that must already exist. .TP \fIpathName \fBtransform \fIx y\fR Performs a coordinate transformation, mapping graph-coordinates to window coordinates, using the standard X\-axis and Y\-axis. Returns a list containing the X\-Y screen-coordinates. .TP \fIpathName \fBxaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBx2axis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fByaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBy2axis \fIoperation\fR ?\fIarg\fR?... See the .SB "AXIS COMPONENTS" section. .SH "BARCHART COMPONENTS" A graph is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the graph is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the graph. .SS "AXIS COMPONENTS" Four coordinate axes are automatically created: two X\-coordinate axes (\f(CWx\fR and \f(CWx2\fR) and two Y\-coordinate axes (\f(CWy\fR, and \f(CWy2\fR). By default, the axis \f(CWx\fR is located in the bottom margin, \f(CWy\fR in the left margin, \f(CWx2\fR in the top margin, and \f(CWy2\fR in the right margin. .PP An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. .PP The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. .PP You can create and use several axes. To create an axis, invoke the axis component and its create operation. .CS # Create a new axis called "temperature" \&.b axis create temperature .CE You map data elements to an axis using the element's \-mapy and \-mapx configuration options. They specify the coordinate axes an element is mapped onto. .CS # Now map the temperature data to this axis. \&.b element create "temp" \-xdata $x \-ydata $tempData \\ \-mapy temperature .CE While you can have many axes, only four axes can be displayed simultaneously. They are drawn in each of the margins surrounding the plotting area. The axes \f(CWx\fR and \f(CWy\fR are drawn in the bottom and left margins. The axes \f(CWx2\fR and \f(CWy2\fR are drawn in top and right margins. Only \f(CWx\fR and \f(CWy\fR are shown by default. Note that the axes can have different scales. .PP To display a different axis, you invoke one of the following components: \fBxaxis\fR, \fByaxis\fR, \fBx2axis\fR, and \fBy2axis\fR. The \fBuse\fR operation designates the axis to be drawn in the corresponding margin: \fBxaxis\fR in the bottom, \fByaxis\fR in the left, \fBx2axis\fR in the top, and \fBy2axis\fR in the right. .CS # Display the axis temperature in the left margin. \&.b yaxis use temperature .CE .PP You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label any way you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. .PP .TP \fIpathName \fBaxis \fBcget \fIaxisName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIaxisName\fR. \fIOption\fR may be any option described below for the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBconfigure \fIaxisName \fR?\fIaxisName\fR?... ?\fIoption value\fR?... Queries or modifies the configuration options of \fIaxisName\fR. Several axes can be changed. If \fIoption\fR isn't specified, a list describing all the current options for \fIaxisName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the axis option \fIoption\fR is set to \fIvalue\fR. The following options are valid for axes. .RS .TP \fB\-autorange \fIrange\fR Sets the range of values for the axis to \fIrange\fR. The axis limits are automatically reset to display the most recent data points in this range. If \fIrange\fR is 0.0, the range is determined from the limits of the data. If \fB\-min\fR or \fB-max\fR are specified, they override this option. The default is \f(CW0.0\fR. .TP \fB\-color \fIcolor\fR Sets the color of the axis and tick labels. The default is \f(CWblack\fR. .TP \fB\-command \fIprefix\fR Specifies a Tcl command to be invoked when formatting the axis tick labels. \fIPrefix\fR is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If \f(CW""\fR is returned, no label will appear next to the tick. You can get the standard tick labels again by setting \fIprefix\fR to \f(CW""\fR. The default is \f(CW""\fR. .sp 1 Please note that this procedure is invoked while the bar chart is redrawn. You may query the widget's configuration options. But do not reset options, because this can have unexpected results. .TP \fB\-descending \fIboolean\fR Indicates whether the values along the axis are monotonically increasing or decreasing. If \fIboolean\fR is true, the axis values will be decreasing. The default is \f(CW0\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the axis is displayed. .TP \fB\-justify \fIjustify\fR Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-limits \fIformatStr\fR Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. \fIFormatStr\fR is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If \f(CW""\fR is given as either description, then the that limit will not be displayed. The default is \f(CW""\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the axis and tick lines. The default is \f(CW1\fR pixel. .TP \fB\-logscale \fIboolean\fR Indicates whether the scale of the axis is logarithmic or linear. If \fIboolean\fR is true, the axis is logarithmic. The default scale is linear. .TP \fB\-loose \fIboolean\fR Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. This is relevant only when the axis limit is automatically calculated. If \fIboolean\fR is true, the axis range is "loose". The default is \f(CW0\fR. .TP \fB\-majorticks \fImajorList\fR Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. \fIMajorList\fR is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If \fImajorList\fR is \f(CW""\fR, major ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-max \fIvalue\fR Sets the maximum limit of \fIaxisName\fR. Any data point greater than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the maximum limit is calculated using the largest data value. The default is \f(CW""\fR. .TP \fB\-min \fIvalue\fR Sets the minimum limit of \fIaxisName\fR. Any data point less than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the minimum limit is calculated using the smallest data value. The default is \f(CW""\fR. .TP \fB\-minorticks \fIminorList\fR Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. \fIMinorList\fR is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the \fB\-majortick\fR option is also set. If \fIminorList\fR is \f(CW""\fR, minor ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-rotate \fItheta\fR Specifies the how many degrees to rotate the axis tick labels. \fITheta\fR is a real value representing the number of degrees to rotate the tick labels. The default is \f(CW0.0\fR degrees. .TP \fB\-shiftby \fIvalue\fR Specifies how much to automatically shift the range of the axis. When the new data exceeds the current axis maximum, the maximum is increased in increments of \fIvalue\fR. You can use this option to prevent the axis limits from being recomputed at each new time point. If \fIvalue\fR is 0.0, then no automatic shifting is down. The default is \f(CW0.0\fR. .TP \fB\-showticks \fIboolean\fR Indicates whether axis ticks should be drawn. If \fIboolean\fR is true, ticks are drawn. If false, only the axis line is drawn. The default is \f(CW1\fR. .TP \fB\-stepsize \fIvalue\fR Specifies the interval between major axis ticks. If \fIvalue\fR isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. .TP \fB\-subdivisions \fInumber\fR Indicates how many minor axis ticks are to be drawn. For example, if \fInumber\fR is two, only one minor tick is drawn. If \fInumber\fR is one, no minor ticks are displayed. The default is \f(CW2\fR. .TP \fB\-tickfont \fIfontName\fR Specifies the font for axis tick labels. The default is \f(CW*-Courier-Bold-R-Normal-*-100-*\fR. .TP \fB\-ticklength \fIpixels\fR Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If \fIpixels\fR is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is \f(CW0.1i\fR. .TP \fB\-title \fItext\fR Sets the title of the axis. If \fItext\fR is \f(CW""\fR, no axis title will be displayed. .TP \fB\-titlecolor \fIcolor\fR Sets the color of the axis title. The default is \f(CWblack\fR. .TP \fB\-titlefont \fIfontName\fR Specifies the font for axis title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-14-140-*\fR. .PP Axis configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWAxis\fR. The resource names are the names of the axes (such as \f(CWx\fR or \f(CWx2\fR). .CS option add *Barchart.Axis.Color blue option add *Barchart.x.LogScale true option add *Barchart.x2.LogScale false .CE .RE .TP \fIpathName \fBaxis \fBcreate \fIaxisName \fR?\fIoption value\fR?... Creates a new axis by the name \fIaxisName\fR. No axis by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBdelete \fR?\fIaxisName\fR?... Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. .TP \fIpathName \fBaxis invtransform \fIaxisName value\fR Performs the inverse transformation, changing the screen-coordinate \fIvalue\fR to a graph-coordinate, mapping the value mapped to \fIaxisName\fR. Returns the graph-coordinate. .TP \fIpathName \fBaxis limits \fIaxisName\fR Returns a list of the minimum and maximum limits for \fIaxisName\fR. The order of the list is \f(CWmin max\fR. .TP \fIpathName \fBaxis names \fR?\fIpattern\fR?... Returns a list of axes matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all axes are returned. .TP \fIpathName \fBaxis transform \fIaxisName value\fR Transforms the coordinate \fIvalue\fR to a screen-coordinate by mapping the it to \fIaxisName\fR. Returns the transformed screen-coordinate. .PP Only four axes can be displayed simultaneously. By default, they are \f(CWx\fR, \f(CWy\fR, \f(CWx2\fR, and \f(CWy2\fR. You can swap in a different axis with \fBuse\fR operation of the special axis components: \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR. .CS \&.g create axis temp \&.g create axis time \&... \&.g xaxis use temp \&.g yaxis use time .CE Only the axes specified for use are displayed on the screen. .PP The \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR components operate on an axis location rather than a specific axis like the more general \fBaxis\fR component does. The \fBxaxis\fR component manages the X-axis located in the bottom margin (whatever axis that happens to be). Likewise, \fByaxis\fR uses the Y-axis in the left margin, \fBx2axis\fR the top X-axis, and \fBy2axis\fR the right Y-axis. .PP They implicitly control the axis that is currently using to that location. By default, \fBxaxis\fR uses the \f(CWx\fR axis, \fByaxis\fR uses \f(CWy\fR, \fBx2axis\fR uses \f(CWx2\fR, and \fBy2axis\fR uses \f(CWy2\fR. These components can be more convenient to use than always determining what axes are current being displayed by the graph. .PP The following operations are available for axes. They mirror exactly the operations of the \fBaxis\fR component. The \fIaxis\fR argument must be \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, or \fBy2axis\fR. .TP \fIpathName \fIaxis \fBcget \fIoption\fR .TP \fIpathName \fIaxis \fBconfigure \fR?\fIoption value\fR?... .TP \fIpathName \fIaxis\fB invtransform \fIvalue\fR .TP \fIpathName \fIaxis \fBlimits\fR .TP \fIpathName \fIaxis\fB transform \fIvalue\fR .TP \fIpathName \fIaxis\fB use \fR?\fIaxisName\fR? Designates the axis \fIaxisName\fR is to be displayed at this location. \fIAxisName\fR can not be already in use at another location. This command returns the name of the axis currently using this location. .SS "CROSSHAIRS COMPONENT" Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire widget. .PP The following operations are available for cross hairs: .TP \fIpathName \fBcrosshairs cget \fIoption\fR Returns the current value of the cross hairs configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the cross hairs \fBconfigure\fR operation. .TP \fIpathName \fBcrosshairs configure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the cross hairs. If \fIoption\fR isn't specified, a list describing all the current options for the cross hairs is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the cross hairs option \fIoption\fR is set to \fIvalue\fR. The following options are available for cross hairs. .RS .TP \fB\-color \fIcolor\fR Sets the color of the cross hairs. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the cross hairs. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the cross hairs will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether cross hairs are drawn. If \fIboolean\fR is true, cross hairs are not drawn. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the cross hair lines. The default is \f(CW1\fR. .TP \fB\-position \fIpos\fR Specifies the screen position where the cross hairs intersect. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates of the intersection. .PP Cross hairs configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWcrosshairs\fR and \f(CWCrosshairs\fR respectively. .CS option add *Barchart.Crosshairs.LineWidth 2 option add *Barchart.Crosshairs.Color red .CE .RE .TP \fIpathName \fBcrosshairs off\fR Turns off the cross hairs. .TP \fIpathName \fBcrosshairs on\fR Turns on the display of the cross hairs. .TP \fIpathName \fBcrosshairs toggle\fR Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. .SH "ELEMENTS" A data element represents a set of data. It contains x and y vectors which are the coordinates of the data points. Elements are displayed as bars where the length of the bar is proportional to the ordinate of the data point. Elements also control the appearance of the data, such as the color, stipple, relief, etc. .PP When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. .PP The following operations are available for elements. .TP \fIpathName \fBelement activate \fIelemName \fR?\fIindex\fR?... Specifies the data points of element \fIelemName\fR to be drawn using active foreground and background colors. \fIElemName\fR is the name of the element and \fIindex\fR is a number representing the index of the data point. If no indices are present then all data points become active. .TP \fIpathName \fBelement bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an element with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on graph elements, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBelement cget \fIelemName \fIoption\fR Returns the current value of the element configuration option given by \fIoption\fR. \fIOption\fR may be any of the options described below for the element \fBconfigure\fR operation. .TP \fIpathName \fBelement closest \fIx y\fR ?\fIoption value\fR?... ?\fIelemName\fR?... Finds the data point representing the bar closest to the window coordinates \fIx\fR and \fIy\fR in the element \fIelemName\fR. \fIElemName\fR is the name of an element, which must be currently displayed. If no elements are specified, then all displayed elements are searched. It returns a key-value list containing the name of the closest element, the index of its closest point, and the graph-coordinates of the point. If no data point within the threshold distance can be found, \f(CW""\fR is returned. The following \fIoption\fR-\fIvalue\fR pairs are available. .RS .TP \fB\-halo \fIpixels\fR Specifies a threshold distance where selected data points are ignored. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. If this option isn't specified, then it defaults to the value of the \fBbarchart\fR's \fB\-halo\fR option. .RE .TP \fIpathName \fBelement configure \fIelemName \fR?\fIelemName\fR... ?\fIoption value\fR?... Queries or modifies the configuration options for elements. Several elements can be modified at the same time. If \fIoption\fR isn't specified, a list describing all the current options for \fIelemName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the option \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the element option \fIoption\fR is set to \fIvalue\fR. The following options are valid for elements. .RS .TP \fB\-activepen \fIpenName\fR Specifies pen to use to draw active element. If \fIpenName\fR is \f(CW""\fR, no active elements will be drawn. The default is \f(CWactiveLine\fR. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for the element. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events for elements. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-background \fIcolor\fR Sets the the color of the border around each bar. The default is \f(CWwhite\fR. .TP \fB\-barwidth \fIvalue\fR Specifies the width the bars drawn for the element. \fIValue\fR is the width in X-coordinates. If this option isn't specified, the width of each bar is the value of the widget's \fB\-barwidth\fR option. .TP \fB\-baseline \fIvalue\fR Specifies the baseline of the bar segments. This affects how bars are drawn since bars are drawn from their respective y-coordinate the baseline. By default the baseline is \f(CW0.0\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the border width of the 3-D border drawn around the outside of each bar. The \fB\-relief\fR option determines if such a border is drawn. \fIPixels\fR must be a valid screen distance like \f(CW2\fR or \f(CW0.25i\fR. The default is \f(CW2\fR. .TP \fB\-data \fIcoordList\fR Specifies the X\-Y coordinates of the data. \fICoordList\fR is a list of numeric expressions representing the X\-Y coordinate pairs of each data point. .TP \fB\-foreground \fIcolor\fR Sets the color of the interior of the bars. .TP \fB\-hide \fIboolean\fR Indicates whether the element is displayed. The default is \f(CWno\fR. .TP \fB\-label \fItext\fR Sets the element's label in the legend. If \fItext\fR is \f(CW""\fR, the element will have no entry in the legend. The default label is the element's name. .TP \fB\-mapx \fIxAxis\fR Selects the X\-axis to map the element's X\-coordinates onto. \fIXAxis\fR must be the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Selects the Y\-axis to map the element's Y\-coordinates onto. \fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR. .TP \fB\-relief \fIstring\fR Specifies the 3-D effect desired for bars. \fIRelief\fR indicates how the interior of the bar should appear relative to the surface of the chart; for example, \f(CWraised\fR means the bar should appear to protrude from the surface of the plotting area. The default is \f(CWraised\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern with which to draw the bars. If \fIbitmap\fR is \f(CW""\fR, then the bar is drawn in a solid fashion. .TP \fB\-xdata \fIxVector\fR Specifies the x-coordinate vector of the data. \fIXVector\fR is the name of a BLT vector or a list of numeric expressions. .TP \fB\-ydata \fIyVector\fR Specifies the y-coordinate vector of the data. \fIYVector\fR is the name of a BLT vector or a list of numeric expressions. .PP Element configuration options may also be set by the \fBoption\fR command. The resource names in the option database are prefixed by \f(CWelem\fR. .CS option add *Barchart.Element.background blue .CE .RE .TP \fIpathName \fBelement create \fIelemName\fR ?\fIoption value\fR?... Creates a new element \fIelemName\fR. Element names must be unique, so an element \fIelemName\fR may not already exist. If additional arguments are present, they specify any of the element options valid for element \fBconfigure\fR operation. .TP \fIpathName \fBelement deactivate \fIpattern\fR... Deactivates all the elements matching \fIpattern\fR for the graph. Elements whose names match any of the patterns given are redrawn using their normal colors. .TP \fIpathName \fBelement delete\fR ?\fIpattern\fR?... Deletes all the elements matching \fIpattern\fR for the graph. Elements whose names match any of the patterns given are deleted. The graph will be redrawn without the deleted elements. .TP \fIpathName \fBelement exists \fIelemName\fR Returns \f(CW1\fR if an element \fIelemName\fR currently exists and \f(CW0\fR otherwise. .TP \fIpathName \fBelement names \fR?\fIpattern\fR?... Returns the elements matching one or more pattern. If no \fIpattern\fR is given, the names of all elements is returned. .TP \fIpathName \fBelement show\fR ?\fInameList\fR? Queries or modifies the element display list. The element display list designates the elements drawn and in what order. \fINameList\fR is a list of elements to be displayed in the order they are named. If there is no \fInameList\fR argument, the current display list is returned. .TP \fIpathName \fBelement type\fR \fIelemName\fR Returns the type of \fIelemName\fR. If the element is a bar element, the commands returns the string \f(CW"bar"\fR, otherwise it returns \f(CW"line"\fR. .CE .SS "GRID COMPONENT" Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. .TP \fIpathName \fBgrid cget \fIoption\fR Returns the current value of the grid line configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the grid \fBconfigure\fR operation. .TP \fIpathName \fBgrid configure\fR ?\fIoption value\fR?... Queries or modifies the configuration options for grid lines. If \fIoption\fR isn't specified, a list describing all the current grid options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the grid line option \fIoption\fR is set to \fIvalue\fR. The following options are valid for grid lines. .RS .TP \fB\-color \fIcolor\fR Sets the color of the grid lines. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the grid lines. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the grid will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether the grid should be drawn. If \fIboolean\fR is true, grid lines are not shown. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of grid lines. The default width is \f(CW1\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to display grid lines. \fIXAxis\fR must be the name of an axis or \f(CW""\fR for no grid lines. The default is \f(CW""\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to display grid lines. \fIYAxis\fR must be the name of an axis or \f(CW""\fR for no grid lines. The default is \f(CWy\fR. .TP \fB\-minor \fIboolean\fR Indicates whether the grid lines should be drawn for minor ticks. If \fIboolean\fR is true, the lines will appear at minor tick intervals. The default is \f(CW1\fR. .PP Grid configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWgrid\fR and \f(CWGrid\fR respectively. .CS option add *Barchart.grid.LineWidth 2 option add *Barchart.Grid.Color black .CE .RE .TP \fIpathName \fBgrid off\fR Turns off the display the grid lines. .TP \fIpathName \fBgrid on\fR Turns on the display the grid lines. .TP \fIpathName \fBgrid toggle\fR Toggles the display of the grid. .SS "LEGEND COMPONENT" The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. .PP The following operations are valid for the legend. .TP \fIpathName \fBlegend activate \fIpattern\fR... Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a legend entry with this tag, \fIcommand\fR will be invoked. Implicitly the element names in the entry are tags. The syntax is similar to the \fBbind\fR command except that it operates on legend entries, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBlegend cget \fIoption\fR Returns the current value of a legend configuration option. \fIOption\fR may be any option described below in the legend \fBconfigure\fR operation. .TP \fIpathName \fBlegend configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for the legend. If \fIoption\fR isn't specified, a list describing the current legend options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the legend option \fIoption\fR is set to \fIvalue\fR. The following options are valid for the legend. .RS .TP \fB\-activebackground \fIcolor\fR Sets the background color for active legend entries. All legend entries marked active (see the legend \fBactivate\fR operation) are drawn using this background color. .TP \fB\-activeborderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the active legend entries. The default is \f(CW2\fR. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color for active legend entries. All legend entries marked as active (see the legend \fBactivate\fR operation) are drawn using this foreground color. .TP \fB\-activerelief \fIrelief\fR Specifies the 3-D effect desired for active legend entries. \fIRelief\fR denotes how the interior of the entry should appear relative to the legend; for example, \f(CWraised\fR means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is \f(CWflat\fR. .TP \fB\-anchor \fIanchor\fR Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the \fB\-position\fR option. The default is \f(CWcenter\fR. .RS .TP 1.25i \f(CWleft\fR or \f(CWright\fR The anchor describes how to position the legend vertically. .TP \f(CWtop\fR or \f(CWbottom\fR The anchor describes how to position the legend horizontally. .TP \f(CW@x,y\fR The anchor specifies how to position the legend relative to the positioning point. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered on the point; if \fIanchor\fR is \f(CWn\fR then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. .TP \f(CWplotarea\fR The anchor specifies how to position the legend relative to the plotting area. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered in the plotting area; if \fIanchor\fR is \f(CWne\fR then the legend will be drawn such that occupies the upper right corner of the plotting area. .RE .TP \fB\-background \fIcolor\fR Sets the background color of the legend. If \fIcolor\fR is \f(CW""\fR, the legend background with be transparent. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for legend entries. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events for legend entries. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is \f(CWall\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the \fBrelief\fR option determines this). The default is \f(CW2\fR pixels. .TP \fB\-font \fIfontName\fR \fIFontName\fR specifies a font to use when drawing the labels of each element into the legend. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of the text drawn for the element's label. The default is \f(CWblack\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the legend should be displayed. If \fIboolean\fR is true, the legend will not be draw. The default is \f(CWno\fR. .TP \fB\-ipadx \fIpad\fR Sets the amount of internal padding to be added to the width of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-ipady \fIpad\fR Sets an amount of internal padding to be added to the height of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the entry is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom of the entry are padded evenly. The default is \f(CW2\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the legend is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW0\fR. .TP \fB\-position \fIpos\fR Specifies where the legend is drawn. The \fB\-anchor\fR option also affects where the legend is positioned. If \fIpos\fR is \f(CWleft\fR, \f(CWleft\fR, \f(CWtop\fR, or \f(CWbottom\fR, the legend is drawn in the specified margin. If \fIpos\fR is \f(CWplotarea\fR, then the legend is drawn inside the plotting area at a particular anchor. If \fIpos\fR is in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is \f(CWright\fR. .TP \fB\-raised \fIboolean\fR Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If \fIboolean\fR is true, the legend will be drawn on top of any elements that may overlap it. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the border around the legend. \fIRelief\fR specifies how the interior of the legend should appear relative to the bar chart; for example, \f(CWraised\fR means the legend should appear to protrude from the bar chart, relative to the surface of the bar chart. The default is \f(CWsunken\fR. .PP Legend configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWlegend\fR and \f(CWLegend\fR respectively. .CS option add *Barchart.legend.Foreground blue option add *Barchart.Legend.Relief raised .CE .RE .TP \fIpathName \fBlegend deactivate \fIpattern\fR... Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend get \fIpos\fR Returns the name of the element whose entry is at the screen position \fIpos\fR in the legend. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are window coordinates. If the given coordinates do not lie over a legend entry, \f(CW""\fR is returned. .SS "PEN COMPONENTS" Pens define attributes for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .PP One pen, called \f(CWactiveBar\fR, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. .CS \&.g pen configure "activeBar" -fg green -bg green4 .CE You can create and use several pens. To create a pen, invoke the pen component and its create operation. .CS \&.g pen create myPen .CE You map pens to a data element using either the element's \fB\-pen\fR or \fB\-activepen\fR options. .CS \&.g element create "e1" -xdata $x -ydata $tempData \\ -pen myPen .CE An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the \fB\-styles\fR option). .CS \&.g element configure "e1" -styles { myPen 2.0 3.0 } .CE This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen \f(CWmyPen\fR. All other points are drawn with the element's default attributes. .PP The following operations are available for pen components. .PP .TP \fIpathName \fBpen \fBcget \fIpenName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIpenName\fR. \fIOption\fR may be any option described below for the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBconfigure \fIpenName \fR?\fIpenName\fR... ?\fIoption value\fR?... Queries or modifies the configuration options of \fIpenName\fR. Several pens can be modified at once. If \fIoption\fR isn't specified, a list describing the current options for \fIpenName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the pen option \fIoption\fR is set to \fIvalue\fR. The following options are valid for pens. .RS .TP \fB\-background \fIcolor\fR Sets the the color of the border around each bar. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the border width of the 3-D border drawn around the outside of each bar. The \fB\-relief\fR option determines if such a border is drawn. \fIPixels\fR must be a valid screen distance like \f(CW2\fR or \f(CW0.25i\fR. The default is \f(CW2\fR. .TP \fB\-foreground \fIcolor\fR Sets the color of the interior of the bars. .TP \fB\-relief \fIstring\fR Specifies the 3-D effect desired for bars. \fIRelief\fR indicates how the interior of the bar should appear relative to the surface of the chart; for example, \f(CWraised\fR means the bar should appear to protrude from the bar chart, relative to the surface of the plotting area. The default is \f(CWraised\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern with which to draw the bars. If \fIbitmap\fR is \f(CW""\fR, then the bar is drawn in a solid fashion. .TP \fB\-type \fIelemType\fR Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "bar". .PP Pen configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWPen\fR. The resource names are the names of the pens. .CS option add *Barchart.Pen.Foreground blue option add *Barchart.activeBar.foreground green .CE .RE .TP \fIpathName \fBpen \fBcreate \fIpenName \fR?\fIoption value\fR?... Creates a new pen by the name \fIpenName\fR. No pen by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBdelete \fR?\fIpenName\fR?... Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. .TP \fIpathName \fBpen names \fR?\fIpattern\fR?... Returns a list of pens matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all pens are returned. .SS "POSTSCRIPT COMPONENT" The barchart can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot will be generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. .PP The following postscript operations are available. .TP \fIpathName \fBpostscript cget \fIoption\fR Returns the current value of the postscript option given by \fIoption\fR. \fIOption\fR may be any option described below for the postscript \fBconfigure\fR operation. .TP \fIpathName \fBpostscript configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for PostScript generation. If \fIoption\fR isn't specified, a list describing the current postscript options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the postscript option \fIoption\fR is set to \fIvalue\fR. The following postscript options are available. .RS .TP \fB\-center \fIboolean\fR Indicates whether the plot should be centered on the PostScript page. If \fIboolean\fR is false, the plot will be placed in the upper left corner of the page. The default is \f(CW1\fR. .TP \fB\-colormap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of \fIvarName\fR must consist of PostScript code to set a particular color value (e.g. ``\f(CW1.0 1.0 0.0 setrgbcolor\fR''). When generating color information in PostScript, the array variable \fIvarName\fR is checked if an element of the name as the color exists. If so, it uses its value as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in \fIvarName\fR for a given color, then it uses the red, green, and blue intensities from the X color. .TP \fB\-colormode \fImode\fR Specifies how to output color information. \fIMode\fR must be either \f(CWcolor\fR (for full color output), \f(CWgray\fR (convert all colors to their gray-scale equivalents) or \f(CWmono\fR (convert foreground colors to black and background colors to white). The default mode is \f(CWcolor\fR. .TP \fB\-fontmap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of \fIvarName\fR must consist of a Tcl list with one or two elements; the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable \fIvarName\fR is checked to see if an element by the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is \fIAdobe\fR (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to \f(CWHelvetica-Bold\fR. .TP \fB\-decorations \fIboolean\fR Indicates whether PostScript commands to generate color backgrounds and 3-D borders will be output. If \fIboolean\fR is false, the graph will background will be white and no 3-D borders will be generated. The default is \f(CW1\fR. .TP \fB\-height \fIpixels\fR Sets the height of the plot. This lets you print the bar chart with a height different from the one drawn on the screen. If \fIpixels\fR is 0, the height is the same as the widget's height. The default is \f(CW0\fR. .TP \fB\-landscape \fIboolean\fR If \fIboolean\fR is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X\-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X\-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to \f(CW0\fR. .TP \fB\-maxpect \fIboolean\fR Indicates to scale the plot so that it fills the PostScript page. The aspect ratio of the barchart is still retained. The default is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left border is padded by the first distance and the right border by the second. If \fIpad\fR has just one distance, both the left and right borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-pady \fIpad\fR Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top border is padded by the first distance and the bottom border by the second. If \fIpad\fR has just one distance, both the top and bottom borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-paperheight \fIpixels\fR Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is \f(CW11.0i\fR. .TP \fB\-paperwidth \fIpixels\fR Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is \f(CW8.5i\fR. .TP \fB\-width \fIpixels\fR Sets the width of the plot. This lets you generate a plot of a width different from that of the widget. If \fIpixels\fR is 0, the width is the same as the widget's width. The default is \f(CW0\fR. .PP Postscript configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWpostscript\fR and \f(CWPostscript\fR respectively. .CS option add *Barchart.postscript.Decorations false option add *Barchart.Postscript.Landscape true .CE .RE .TP \fIpathName \fBpostscript output \fR?\fIfileName\fR? ?\fIoption value\fR?... Outputs a file of encapsulated PostScript. If a \fIfileName\fR argument isn't present, the command returns the PostScript. If any \fIoption-value\fR pairs are present, they set configuration options controlling how the PostScript is generated. \fIOption\fR and \fIvalue\fR can be anything accepted by the postscript \fBconfigure\fR operation above. .SS "MARKER COMPONENTS" Markers are simple drawing procedures used to annotate or highlight areas of the graph. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the \fB\-under\fR option. .PP Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have \fIelastic\fR coordinates (specified by \f(CW-Inf\fR and \f(CWInf\fR respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates \f(CW-Inf\fR,\f(CW-Inf\fR. .PP The following operations are available for markers. .TP \fIpathName \fBmarker after \fImarkerId\fR ?\fIafterId\fR? Changes the order of the markers, drawing the first marker after the second. If no second \fIafterId\fR argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker before \fImarkerId\fR ?\fIbeforeId\fR? Changes the order of the markers, drawing the first marker before the second. If no second \fIbeforeId\fR argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a marker with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on graph markers, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBmarker cget \fIoption\fR Returns the current value of the marker configuration option given by \fIoption\fR. \fIOption\fR may be any option described below in the \fBconfigure\fR operation. .TP \fIpathName \fBmarker configure \fImarkerId\fR ?\fIoption value\fR?... Queries or modifies the configuration options for markers. If \fIoption\fR isn't specified, a list describing the current options for \fImarkerId\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the marker option \fIoption\fR is set to \fIvalue\fR. .sp The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. .RS .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for the marker. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events for markers are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the marker is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-coords \fIcoordList\fR Specifies the coordinates of the marker. \fICoordList\fR is a list of graph-coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X\-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If \fIcoordList\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-element \fIelemName\fR Links the marker with the element \fIelemName\fR. The marker is drawn only if the element is also currently displayed (see the element's \fBshow\fR operation). If \fIelemName\fR is \f(CW""\fR, the marker is always drawn. The default is \f(CW""\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the marker is drawn. If \fIboolean\fR is true, the marker is not drawn. The default is \f(CWno\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to map the marker's X\-coordinates onto. \fIXAxis\fR must the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to map the marker's Y\-coordinates onto. \fIYAxis\fR must the name of an axis. The default is \f(CWy\fR. .TP \fB\-name \fImarkerId\fR Changes the identifier for the marker. The identifier \fImarkerId\fR can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. .TP \fB\-under \fIboolean\fR Indicates whether the marker is drawn below/above data elements. If \fIboolean\fR is true, the marker is be drawn underneath the data elements. Otherwise, the marker is drawn on top of the element. The default is \f(CW0\fR. .TP \fB\-xoffset \fIpixels\fR Specifies a screen distance to offset the marker horizontally. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .TP \fB\-yoffset \fIpixels\fR Specifies a screen distance to offset the markers vertically. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .PP Marker configuration options may also be set by the \fBoption\fR command. The resource class is either \f(CWBitmapMarker\fR, \f(CWImageMarker\fR, \f(CWLineMarker\fR, \f(CWPolygonMarker\fR, \f(CWTextMarker\fR, or \f(CWWindowMarker\fR, depending on the type of marker. The resource name is the name of the marker. .CS option add *Barchart.TextMarker.Foreground white option add *Barchart.BitmapMarker.Foreground white option add *Barchart.m1.Background blue .CE .RE .TP \fIpathName \fBmarker create \fItype\fR ?\fIoption value\fR?... Creates a marker of the selected type. \fIType\fR may be either \f(CWtext\fR, \f(CWline\fR, \f(CWbitmap\fR, \f(CWimage\fR, \f(CWpolygon\fR, or \f(CWwindow\fR. This command returns the marker identifier, used as the \fImarkerId\fR argument in the other marker-related commands. If the \fB\-name\fR option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. .TP \fIpathName \fBmarker delete\fR ?\fIname\fR?... Removes one of more markers. The graph will automatically be redrawn without the marker.\fR. .TP \fIpathName \fBmarker exists \fImarkerId\fR Returns \f(CW1\fR if the marker \fImarkerId\fR exists and \f(CW0\fR otherwise. .TP \fIpathName \fBmarker names\fR ?\fIpattern\fR? Returns the names of all the markers that currently exist. If \fIpattern\fR is supplied, only those markers whose names match it will be returned. .TP \fIpathName \fBmarker type \fImarkerId\fR Returns the type of the marker given by \fImarkerId\fR, such as \f(CWline\fR or \f(CWtext\fR. If \fImarkerId\fR is not a valid a marker identifier, \f(CW""\fR is returned. .SS "BITMAP MARKERS" A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. .PP Bitmap markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create bitmap \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration options for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to bitmap markers: .TP \fB\-background \fIcolor\fR Same as the \fB\-fill\fR option. .TP \fB\-bitmap \fIbitmap\fR Specifies the bitmap to be displayed. If \fIbitmap\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-fill \fIcolor\fR Sets the background color of the bitmap. If \fIcolor\fR is the empty string, no background will be transparent. The default background color is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Same as the \fB\-outline\fR option. .TP \fB\-mask \fImask\fR Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If \fImask\fR is \f(CW""\fR, all pixels of the bitmap will be drawn. The default is \f(CW""\fR. .TP \fB\-outline \fIcolor\fR Sets the foreground color of the bitmap. The default value is \f(CWblack\fR. .TP \fB\-rotate \fItheta\fR Sets the rotation of the bitmap. \fITheta\fR is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is \f(CW0.0\fR. .SS "IMAGE MARKERS" A image marker displays an image. Image markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create image \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to image markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the image relative to the positioning point for the image. For example, if \fIanchor\fR is \f(CWcenter\fR then the image is centered on the point; if \fIanchor\fR is \f(CWn\fR then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-image \fIimage\fR Specifies the image to be drawn. If \fIimage\fR is \f(CW""\fR, the marker will not be drawn. The default is \f(CW""\fR. .SS "LINE MARKERS" A line marker displays one or more connected line segments. Line markers are created with marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create line \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to line markers: .TP \fB\-dashes \fIdashList\fR Sets the dash style of the line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the marker line will be solid. .TP \fB\-fill \fIcolor\fR Sets the background color of the line. This color is used with striped lines (see the \fB\-fdashes\R option). If \fIcolor\fR is the empty string, no background color is drawn (the line will be dashed, not striped). The default background color is \f(CW""\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the lines. The default width is \f(CW0\fR. .TP \fB\-outline \fIcolor\fR Sets the foreground color of the line. The default value is \f(CWblack\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern used to draw the line, rather than a solid line. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the line is drawn in a solid fashion. The default is \f(CW""\fR. .SS "POLYGON MARKERS" A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create polygon \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the \fBmarker configure\fR command to change the marker's configuration. The following options are supported for polygon markers: .TP \fB\-dashes \fIdashList\fR Sets the dash style of the outline of the polygon. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line. .TP \fB\-fill \fIcolor\fR Sets the fill color of the polygon. If \fIcolor\fR is \f(CW""\fR, then the interior of the polygon is transparent. The default is \f(CWwhite\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the outline of the polygon. If \fIpixels\fR is zero, no outline is drawn. The default is \f(CW0\fR. .TP \fB\-outline \fIcolor\fR Sets the color of the outline of the polygon. If the polygon is stippled (see the \fB\-stipple\fR option), then this represents the foreground color of the stipple. The default is \f(CWblack\fR. .TP \fB\-stipple \fIbitmap\fR Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the polygon is filled with a solid color (if the \fB\-fill\fR option is set). The default is \f(CW""\fR. .SS "TEXT MARKERS" A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the graph. Text markers are created with the \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create text \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the text marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to text markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the text relative to the positioning point for the text. For example, if \fIanchor\fR is \f(CWcenter\fR then the text is centered on the point; if \fIanchor\fR is \f(CWn\fR then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Same as the \fB\-fill\fR option. .TP \fB\-font \fIfontName\fR Specifies the font of the text. The default is \f(CW*-Helvetica-Bold-R-Normal-*-120-*\fR. .TP \fB\-fill \fIcolor\fR Sets the background color of the text. If \fIcolor\fR is the empty string, no background will be transparent. The default background color is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Same as the \fB\-outline\fR option. .TP \fB\-justify \fIjustify\fR Specifies how the text should be justified. This matters only when the marker contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-outline \fIcolor\fR Sets the color of the text. The default value is \f(CWblack\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the text is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the text is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW4\fR. .TP \fB\-rotate \fItheta\fR Specifies the number of degrees to rotate the text. \fITheta\fR is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is \f(CW0.0\fR. .TP \fB\-text \fItext\fR Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as \fB\-anchor\fR or \fB\-rotate\fR. .SS "WINDOW MARKERS" A window marker displays a widget at a given position. Window markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create window \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR command. .PP The following options are specific to window markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the widget relative to the positioning point for the widget. For example, if \fIanchor\fR is \f(CWcenter\fR then the widget is centered on the point; if \fIanchor\fR is \f(CWn\fR then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-height \fIpixels\fR Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever height the widget requests internally. .TP \fB\-width \fIpixels\fR Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever width the widget requests internally. .TP \fB\-window \fIpathName\fR Specifies the widget to be managed by the barchart. \fIPathName\fR must be a child of the \fBbarchart\fR widget. .SH "GRAPH COMPONENT BINDINGS" Specific barchart components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR). .PP Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. .PP It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the \fB\-bindtags\fR option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. .PP The \fB\-bindtags\fR option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the \fB\-bindtags\fR option doesn't change this. .SH "C LANGUAGE API" You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. .PP Data can manipulated from the C language using BLT vectors. You specify the X-Y data coordinates of an element as vectors and manipulate the vector from C. The barchart will be redrawn automatically after the vectors are updated. .PP From Tcl, create the vectors and configure the element to use them. .CS vector X Y \&.g element configure line1 -xdata X -ydata Y .CE To set data points from C, you pass the values as arrays of doubles using the \fBBlt_ResetVector\fR call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the graph will be redrawn automatically. .CS #include <tcl.h> #include <blt.h> register int i; Blt_Vector *xVec, *yVec; double x[50], y[50]; /* Get the BLT vectors "X" and "Y" (created above from Tcl) */ if ((Blt_GetVector(interp, "X", 50, &xVec) != TCL_OK) || (Blt_GetVector(interp, "Y", 50, &yVec) != TCL_OK)) { return TCL_ERROR; } for (i = 0; i < 50; i++) { x[i] = i * 0.02; y[i] = sin(x[i]); } /* Put the data into BLT vectors */ if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) || (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) { return TCL_ERROR; } .CE See the \fBvector\fR manual page for more details. .SH SPEED TIPS There may be cases where the bar chart needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. .TP 2 \(bu Try to minimize the number of data points. The more data points looked at, the more work the bar chart must do. .TP 2 \(bu If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. .TP 2 \(bu Don't stipple or dash the element. Solid bars are much faster. .TP 2 \(bu If you update data elements frequently, try turning off the widget's \fB\-bufferelements\fR option. When the bar chart is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the bar chart needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the bar chart. But if the bar chart is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. .SH LIMITATIONS Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. .PP The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. .SH KEYWORDS bar chart, widget �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/tile.mann���������������������������������������������������������������������0000644�0001750�0001750�00000010737�11462120062�014631� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Tile command created by George Howlett. '\" .so man.macros .TH tile n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME tile \- Tiling versions of Tk widgets .SH SYNOPSIS .sp \fBtile::button \fIpathName\fR \fIoption value\fR... .sp \fBtile::checkbutton \fIpathName\fR \fIoption value\fR... .sp \fBtile::frame \fIpathName\fR \fIoption value\fR... .sp \fBtile::label \fIpathName\fR \fIoption value\fR... .sp \fBtile::radiobutton \fIpathName\fR \fIoption value\fR... .sp \fBtile::scrollbar \fIpathName\fR \fIoption value\fR... .sp \fBtile::toplevel \fIpathName\fR \fIoption value\fR... .sp .BE .SH DESCRIPTION The tile widgets let you create textured backgrounds. The texture is a Tk image which is tiled over the entire background of the widget. .SH INTRODUCTION With the advent of Tk 4.0, images are now easy to create and use in applications. Images add interest to applications and they convey more information. But one area where Tk hasn't taken advantage of images is using images as textures for widgets. Since tiling is a standard feature of windowing systems, it's very easy to use images as textures. .PP The tile widgets take the standard Tk 4.0 widgets and add tiling configuration options to them. Textures are specified by the name of the image you wish to be tiled across the background of the widget. .SH EXAMPLE To add tiling to a widget, you simply create an image using Tk's \fBimage\fR command and use the image name as the value for the \fB\-tile\fR configuration option of the widget. .CS image create photo my_texture -file tan_paper.gif blt::tile::frame .f -tile my_texture .CE The image \f(CWmy_texture\fR is added to the frame. If \f(CWmy_texture\fR is updated, so will the widget background. .CS image create photo my_texture -file rain.gif .CE The tile widget commands reside in the "blt::tile" namespace, so as not to collide with the normal Tk widgets. An easy way to add tiling to existing programs is to import the tile widget commands into the global namespace. .CS image create photo my_texture -file tan_paper.gif namespace import -force blt::tile::* frame .f -tile my_texture .CE To use one image for all texturing, you can use the "Tile" option class name to specify the same image for all tile widgets. .CS image create photo my_texture -file tan_paper.gif option add *Tile my_texture .CE .SH OPTIONS The following configurations options are added to the widgets. If a \fB\-tile\fB or \fB\-activetile\fR option is specified, it overrides the background color of the widget. .TP \fB\-activetile \fIimage\fR Specifies a textured background to display when the widget is active. This option is available for the \fBtilebutton\fR, \fBtilecheckbutton\fR, \fBtileradiobutton\fR, and \fBtilescrollbar\fR widgets. \fIImage\fR is the name an image created using Tk's \fBimage\fR command. The background of the widget is tiled with \fIimage\fR. If \fIimage\fR is \f(CW""\fR, then the active background color is displayed. The default is \f(CW""\fR. .TP \fB\-tile \fIimage\fR Specifies a textured background to display for the widget. \fIImage\fR is the name an image created using Tk's \fBimage\fR command. The background of the widget is tiled with \fIimage\fR. If \fIimage\fR is \f(CW""\fR, then the normal background color is displayed. The default is \f(CW""\fR. .SH KEYWORDS tile, texture, button, label, radiobutton, checkbutton, scrollbar, frame, toplevel ���������������������������������./saods9/blt3.0.1/man/bgexec.mann�������������������������������������������������������������������0000644�0001750�0001750�00000031521�11462120062�015123� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Bgexec command created by George Howlett. '\" .so man.macros .TH bgexec n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBbgexec\fR \- Run programs in the background while handling Tk events. .SH SYNOPSIS \fBblt::bgexec \fIvarName\fR ?\fIoption value\fR?... \fIprogram\fR ?\fIarg\fR?... .BE .SH DESCRIPTION .PP The \fBbgexec\fR command executes programs in the background, allowing Tk to handle events. A global Tcl variable \fIvarName\fR is set when the program has completed. .SH INTRODUCTION Tcl's \fBexec\fR command is very useful for gathering information from the operating system. It runs a program and returns the output as its result. This works well for Tcl-only applications. But for Tk applications, a problem occurs when the program takes time to process. Let's say we want the get the disk usage of a directory. We'll use the Unix program \f(CWdu\fR to get the summary. .CS set out [exec du -s $dir] puts "Disk usage for $dir is $out" .CE While \f(CWdu\fR is running, scrollbars won't respond. None of the Tk widgets will be redrawn properly. The \fBsend\fR command won't work. And the worst part is that the application appears hung up or dead. The problem is that while \fBexec\fR is waiting for \fIdu\fR to finish, Tk is not able to handle X events. .PP The \fBbgexec\fR command performs the same functions as \fBexec\fR, but also allows Tk to handle events. You can execute a long-running program and the Tk widgets will behave normally. When the program finishes, its output and the exit status are written to Tcl variables. This makes it easy to monitor and save the output of a program. .SH EXAMPLE Here is the disk usage example again, this time using \fBbgexec\fR. The syntax to invoke "du" is exactly the same as the previous example, when we used \fBexec\fR. .CS global myStatus myOutput blt::bgexec myStatus -output myOutput du -s $dir puts "Disk usage for $dir is $myOutput" .CE Two global variables, \f(CWmyStatus\fR and \f(CWmyOutput\fR, will be set by \fBbgexec\fR when \f(CWdu\fR has completed. \f(CWMyStatus\fR will contain the program's exit status. \f(CWMyOutput\fR, specified by the \fB\-output\fR option, will store the output of the program. .PP You can also terminate the program by setting the variable \f(CWmyStatus\fR. If \f(CWmyStatus\fR is set before \f(CWdu\fR has completed, the process is killed. Under Unix, this is done sending by a configurable signal (by default it's SIGKILL). Under Win32, this is done by calling \fBTerminateProcess\fR. It makes no difference what \f(CWmyStatus\fR is set to. .CS set myStatus {} .CE There are several \fBbgexec\fR options to collect different types of information. .CS global myStatus myOutput myErrs blt::bgexec myStatus -output myOutput -error myErrs du -s $dir .CE The \fB\-error\fR option is similar to \fB\-output\fR. It sets a global variable when the program completes. The variable will contain any data written to stderr by the program. .PP The \fB\-output\fR and \fB\-error\fR variables are set only after the program completes. But if the program takes a long time, to run you may want to receive its partial output. You can gather data as it becomes available using the \fB\-onoutput\fR option. It specifies a Tcl command prefix. Whenever new data is available, this command is executed, with the data appended as an argument to the command. .CS proc GetInfo { data } { puts $data } blt::bgexec myStatus -onoutput GetInfo du -s $dir .CE When output is available, the procedure \f(CWGetInfo\fR is called. The \fB\-onerror\fR option performs a similar function for the stderr data stream. .PP Like \fBexec\fR, \fBbgexec\fR returns an error if the exit code of the program is not zero. If you think you may get a non-zero exit code, you might want to invoke \fBbgexec\fR from within a \fBcatch\fR. .CS catch { blt::bgexec myStatus -output myOutput du -s $dir } .CE By default, \fBbgexec\fR will wait for the program to finish. But you can detach the program making ampersand (&) the last argument on the command line. .CS global myStatus myOutput blt::bgexec myStatus -output myOutput du -s $dir & .CE \fBBgexec\fR will return immediately and its result will be a list of the spawned process ids. If at some point you need to wait for the program to finish up, you can use \fBtkwait\fR. When the program finishes, the variable \f(CWmyStatus\fR will be written to, breaking out the \fBtkwait\fR command. .CS global myStatus myOutput blt::bgexec myStatus -output myOutput du -s $dir & ... tkwait variable myStatus .CE .SH SYNTAX The \fBbgexec\fR command takes the following form: .sp \fB blt::bgexec \fIvarName\fR ?\fIoption value\fR?... \fIprogram\fR ?\fIarg\fR?... .sp \fIVarName\fR is the name of a global variable which is set when \fIprogram\fR has finished executing. The exit status of will be stored in \fIvarName\fR. The exit status is a list of a status token, the process-id of the program, the exit code, and a status message. You can also prematurely terminate the program by setting \fIvarName\fR. Under Unix, the program will be sent a signal to terminate it (by default the signal is a SIGKILL; see the \fB\-killsignal\fR option). .PP \fIProgram\fR is the name of the program to be executed and \fIargs\fR are any extra arguments for \fIprogram\fR. The syntax of \fIprogram\fR and \fIargs\fR is the same as the \fBexec\fR command. So you can redirect I/O, execute pipelines, etc. (see the \fBexec\fR manual for further information) just like \fBexec\fR. If the last argument is an ampersand (&), the program will be run detached, and \fBbgexec\fR will return immediately. \fIVarName\fR will still be set with the return status when \fIprogram\fR completes. .SH OPTIONS \fIOption\fR refers to the switch name always beginning with a dash (\-). \fIValue\fR is the value of the option. Option-value pairs are terminated either by the program name, or double dashes (\-\-). The following options are available for \fBbgexec\fR: .TP \fB\-decodeerror \fIencodingName\fR .br Specifies the encoding of the stderr channel. This affects only data returned to the Tcl interpreter. No translation is done on file redirection. .br For example if data is to be converted from Unicode for use in Tcl, you would use the "unicode" encoding. The default is that no tranlation is performed. .TP \fB\-decodeoutput \fIencodingName\fR .br Specifies the encoding of the stdout channels. This affects only data returned to the Tcl interpreter. No translation is done on file redirection. .br For example if data is to be converted from Unicode for use in Tcl, you would use the "unicode" encoding. The default is that no tranlation is performed. .TP \fB\-error \fIvarName\fR .br Specifies that a global variable \fIvarName\fR is to be set with the contents of stderr after the program has completed. .TP \fB\-keepnewline \fIboolean\fR Specifies that a trailing newline should be retained in the output. If \fIboolean\fR is true, the trailing newline is truncated from the output of the \fB\-onoutput\fR and \fB\-output\fR variables. The default value is \f(CWtrue\fR. .TP \fB\-killsignal \fIsignal\fR Specifies the signal to be sent to the program when terminating. This is available only under Unix. \fISignal\fR can either be a number (typically 1-32) or a mnemonic (such as SIGINT). If \fIsignal\fR is the empty string, then no signal is sent. The default signal is \f(CW9\fR (SIGKILL). .TP \fB\-lasterror \fIvarName\fR Specifies a variable \fIvarName\fR that is updated whenever data becomes available from standard error of the program. \fIVarName\fR is a global variable. Unlike the \fB\-error\fR option, data is available as soon as it arrives. .TP \fB\-lastoutput \fIvarName\fR Specifies a variable \fIvarName\fR that is updated whenever data becomes available from standard output of the program. \fIVarName\fR is a global variable. Unlike the \fB\-output\fR option, data is available as soon as it arrives. .TP \fB\-linebuffered \fIboolean\fR Specifies that updates should be made on a line-by-line basis. Normally when new data is available \fBbgexec\fR will set the variable (\fB\-lastoutput\fR and \fB\-lasterror\fR options) or invoke the command (\fB\-onoutput\fR and \fB\-onerror\fR options) delivering all the new data currently available. If \fIboolean\fR is true, only one line at a time will be delivered. This can be useful when you want to process the output on a line-by-line basis. The default value is \f(CWfalse\fR. .TP \fB\-output \fIvarName\fR .br Specifies that a global variable \fIvarName\fR is to be set with the output of the program, once it has completed. If this option is not set, no output will be accumulated. .TP \fB\-onerror \fIcommand\fR Specifies the start of a Tcl command that will be executed whenever new data is available from standard error. The data is appended to the command as an extra argument before it is executed. .TP \fB\-onoutput \fIcommand\fR Specifies the start of a Tcl command that will be executed whenever new data is available from standard output. The data is appended to the command as an extra argument before it is executed. .TP \fB\-update \fIvarName\fR Deprecated. This option is replaced by \fB\-lasterror\fR. .TP \fB\-\|\-\fR This marks the end of the options. The following argument will be considered the name of a program even if it starts with a dash (\fB\-\fR). .SH PREEMPTION Because \fBbgexec\fR allows Tk to handle events while a program is running, it's possible for an application to preempt itself with further user-interactions. Let's say your application has a button that runs the disk usage example. And while the \f(CWdu\fR program is running, the user accidently presses the button again. A second \fBbgexec\fR program will preempt the first. What this means is that the first program can not finish until the second program has completed. .PP Care must be taken to prevent an application from preempting itself by blocking further user-interactions (such as button clicks). The BLT \fBbusy\fR command is very useful for just these situations. See the \fBbusy\fR manual for details. .SH DIFFERENCES WITH FILEEVENT Since Tk 4.0, a subset of \fBbgexec\fR can be also achieved using the \fBfileevent\fR command. The steps for running a program in the background are: .PP Execute the program with the \fBopen\fR command (using the "|" syntax) and save the file handle. .CS global fileId set fileId [open "|du -s $dir" r] .CE Next register a Tcl code snippet with \fBfileevent\fR to be run whenever output is available on the file handle. The code snippet will read from the file handle and save the output in a variable. .CS fileevent fileId readable { if { [gets $fileId line] < 0 } { close $fileId set output $temp unset fileId temp } else { append temp $line } } .CE .PP The biggest advantage of \fBbgexec\fR is that, unlike \fBfileevent\fR, it requires no additional Tcl code to run a program. It's simpler and less error prone. You don't have to worry about non-blocking I/O. It's handled tranparently for you. .PP \fBBgexec\fR runs programs that \fBfileevent\fR can not. \fBFileevent\fR assumes that the when stdout is closed the program has completed. But some programs, like the Unix \f(CWcompress\fR program, reopen stdout, fooling \fBfileevent\fR into thinking the program has terminated. In the example above, we assume that the program will write and flush its output line-by-line. However running another program, your application may block in the \fBgets\fR command reading a partial line. .PP \fBBgexec\fR lets you get back the exit status of the program. It also allows you to collect data from both stdout and stderr simultaneously. Finally, since data collection is handled in C code, \fBbgexec\fR is faster. You get back to the Tk event loop more quickly, making your application seem more responsive. .SH SEE ALSO busy, exec, tkwait .SH KEYWORDS exec, background, busy �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/dragdrop.mann�����������������������������������������������������������������0000644�0001750�0001750�00000044112�11462120062�015470� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH drag&drop n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME drag&drop \- facilities for handling drag&drop data transfers .SH SYNOPSIS \fBdrag&drop source .br \fBdrag&drop source \fIwindow \fR?\fIoptions\fR? .br \fBdrag&drop source \fIwindow \fBhandler \fR?\fIdataType\fR? ?\fIcommand arg arg...\fR? .sp \fBdrag&drop target .br \fBdrag&drop target \fIwindow \fBhandler \fR?\fIdataType command arg arg...\fR? .sp \fBdrag&drop target \fIwindow \fBhandle \fIdataType\fR ?\fIvalue\fR? .sp \fBdrag&drop token \fIwindow .sp \fBdrag&drop drag \fIwindow x y .br \fBdrag&drop drop \fIwindow x y .br \fBdrag&drop active .br \fBdrag&drop location \fR?\fIx y\fR? .BE .SH DESCRIPTION .PP The \fBdrag&drop\fR command provides access to a set of facilities for managing drag-and-drop data transfers. Any of the usual Tk widgets can be registered to participate in the drag-and-drop process. Widgets registered as a drag&drop \fIsource\fP can export data to other widgets registered as a drag&drop \fItarget\fP. Note that a particular widget can be registered as a source, as a target, or as both. .PP The drag-and-drop process begins when the user clicks and holds a mouse button in a source window; a token window appears with an icon or message to represent the data being transferred. As the user moves the mouse pointer, the token window follows along, acting as a movable packet of data. Whenever the mouse pointer falls on a valid target window, the border of the token window is changed to a raised (active) state. When the mouse button is released over the target window, a Tcl routine is invoked to send the data to the desired application, and the target window is asked to "handle" the data. If this communication process fails, a rejection symbol (a circle with a line through it) is displayed on the token window to indicate failure. .PP The details of the communication process are fully configurable by the application developer. In the simplest case, the value that is sent to the target window is a simple string. The target window is simply asked to "handle" that string value. In general, the source window can have a special "handler" procedure to transfer a particular data type by issuing a series of "send" commands. After this, the target window is again asked to "handle" the result. .PP Both sources and targets can have a list of "handlers" for different data types. As a token window is dragged from its source to various targets, each target is checked to see if it recognizes a handler offered by the source. If it does, it is treated as a valid target. Otherwise, it is ignored. This scheme allows the same source to interact with many different kinds of targets. For example, a source for RGB color samples might have "color" and "string" handlers. This would allow it to communicate with "color" targets (sending RGB data) as well as entry widgets (sending strings of the form "#rrggbb"). .PP This introduction was presented as a brief overview of the communication process; further details are presented below: .TP \fBdrag&drop source\fR Returns a list of path names for widgets registered as drag&drop sources. Returns an empty string if no widgets have been registered. .TP \fBdrag&drop source \fIwindow \fR?\fIoptions\fR? Registers a new drag&drop source window with the given options, or modifies the options for an existing window: .RS .LP .nf Name: \fBbuttonBinding\fR Class: \fBButtonBinding\fR Switch: \fB\-button\fR \fIn\fR .fi .IP Specifies the mouse button (integer 1-5) that will invoke the drag&drop operation on the source window. This causes the following bindings to be added to the widget: .sp .nf .RS \f(CWbind \fIwin\fP <ButtonPress-\fIn\fP> {drag&drop drag %W %X %Y} \f(CWbind \fIwin\fP <B\fIn\fP-Motion> {drag&drop drag %W %X %Y} \f(CWbind \fIwin\fP <ButtonRelease-\fIn\fP> {drag&drop drop %W %X %Y}\fR .RE .fi .sp The default value is button 3. If the value "0" is specified, then no bindings are added; this enables the user to establish bindings manually. .LP .nf Name: \fBpackageCommand\fR Class: \fBCommand\fR Switch: \fB\-packagecmd \fIcommand\fR .fi .IP Specifies a Tcl command used to establish the appearance of the token window at the start of each drag&drop operation. This command is automatically invoked by the \fBdrag&drop drag\fP command whenever the token window is about to be mapped for a drag operation. It should update the appearance of the token window to represent the data that is being moved. .PP The following substitutions are made in the \fIcommand\fR string before it is executed: .RS .TP \fB%t\fR Replaced with the window path name for the token which represents the data being dragged. .TP \fB%W\fR Replaced with the window path name for the drag&drop source. .RE .LP The return value from the package command represents the data being transferred. If the package command returns an empty string, the drag operation is quietly aborted. This can be used to disallow drag&drop operations from certain parts of a widget, if the drag position is inappropriate. .LP For example, the following package routine will select an item from a listbox and configure the token window to display the selected string. It uses the \fBdrag&drop location\fR command to determine the entry in the listbox that the user has selected and it returns this as the data value: .sp .nf .RS \f(CWproc package_list_item {lbox token} { set xy [drag&drop location] set y [expr [lindex $xy 1]-[winfo rooty $lbox]] set str [$lbox get [$lbox nearest $y]] $token.value configure -text $str return $str }\fR .RE .fi .sp The return value is available later when the source and target communicate. If the source has a command associated with its data handler, then this value is substituted in place of "%v" in the source handler. Otherwise, it is substituted in place of "%v" in the target handler. .LP .nf Name: \fBerrorCmd\fR Class: \fBErrorCmd\fR Switch: \fB\-errorcmd \fIproc\fR .fi .IP Specifies a Tcl \fIproc\fR used to handle errors encountered during drag&drop operations. If a \fIproc\fR is not specified, this command returns the current error handler. By default, all errors are sent to the usual \fBtkerror\fR command, and therefore appear in a dialog box to the user. This behavior is quite useful when debugging communication protocols, but may not be desirable in a finished application. Errors can be suppressed entirely (leaving the rejection symbol as the only error indicator) by specifying a null string in place of the \fIproc\fR name. .LP .nf Name: \fBrejectBackground\fR Class: \fBBackground\fR Switch: \fB\-rejectbg \fIcolor\fR .fi .IP Specifies the color used to draw the background of the rejection symbol on the token window. The rejection symbol (a circle with a line through it--the international "no") appears whenever communication fails. .LP .nf Name: \fBrejectForeground\fR Class: \fBForeground\fR Switch: \fB\-rejectfg \fIcolor\fR .fi .IP Specifies the color used to draw the foreground of the rejection symbol on the token window. .LP .nf Name: \fBrejectStipple\fR Class: \fBStipple\fR Switch: \fB\-rejectstipple \fIpattern\fR .fi .IP Specifies a stipple pattern used to draw the foreground of the rejection symbol on the token window. Any of the forms acceptable to Tk_GetBitmap can be used. .LP .nf Name: \fBselfTarget\fR Class: \fBSelfTarget\fR Switch: \fB\-selftarget \fIboolean\fR .fi .IP If the \fIboolean\fR value is true, and if a source widget is also registered as a compatible target, then the source will be able to transmit to itself during drag&drop operations. This is primarily useful for complex sources such as a canvas widget, where items may be moved from place to place within the same widget. By default, this option is disabled. .LP .nf Name: \fBsend\fR Class: \fBSend\fR Switch: \fB\-send \fIlist\fR .fi .IP Specifies a \fIlist\fR of \fIdataTypes\fR enabled for communication. Only \fIdataTypes\fR defined by commands of the form "\fBdrag&drop source \fIwindow \fBhandler \fR?\fIdataType\fR ?\fIcommand arg arg...\fR?" are allowed. This list also determines the priority of the various \fIdataTypes\fR. When a token window is over a potential drag&drop target, this list is searched from start to finish for a \fIdataType\fR that is also recognized by the target. The first matching \fIdataType\fR found determines the value that will be sent if the token is dropped. If no matching \fIdataType\fR is found, then the target is incompatible, and is ignored. By default, this option has the value "all", indicating that all \fIdataTypes\fR should be considered in the order that they were defined for the source. .LP Note that this option makes it easy to control a drag&drop source. Setting the value to an empty string disables the source; setting the value back to "all" restores communication. .LP .nf Name: \fBsiteCommand\fR Class: \fBCommand\fR Switch: \fB\-sitecmd \fIcommand\fR .fi .IP Specifies a Tcl command used to update the appearance of the token window. If specified, this command is automatically invoked by the \fBdrag&drop drag\fP command whenever the token window is over a compatible drag&drop target. .PP The following substitutions are made in the \fIcommand\fR string before it is executed: .RS .TP \fB%s\fR Replaced with "1" if the token window is over a compatible target, and "0" otherwise. .TP \fB%t\fR Replaced with the window path name for the token which represents the data being dragged. .RE .LP Regardless of this command, border of the token window will become raised whenever the token is over a valid target. This command can be used to display other visual cues. .LP .nf Name: \fBtokenAnchor\fR Class: \fBAnchor\fR Switch: \fB\-tokenanchor \fIanchor\fR .fi .IP Specifies how the token window is positioned relative to the mouse pointer coordinates passed to the \fBdrag&drop drag\fP command. Must be one of the values n, s, e, w, center, nw, ne, sw or se. For example, "nw" means to position the token such that its upper-left corner is at the mouse pointer. The default value is "center". .LP .nf Name: \fBtokenBackground\fR Class: \fBBackground\fR Switch: \fB\-tokenbg \fIcolor\fR .fi .IP Specifies the color used to draw the background of the token window. .LP .nf Name: \fBtokenBorderWidth\fR Class: \fBBorderWidth\fR Switch: \fB\-tokenborderwidth \fIsize\fR .fi .IP Specifies the width in pixels of the border around the token window. This border becomes raised to indicate when the token is over a compatible drag&drop target site. The value may have any of the forms acceptable to Tk_GetPixels. The default value is "3". .LP .nf Name: \fBtokenCursor\fR Class: \fBCursor\fR Switch: \fB\-tokencursor \fIcursor\fR .fi .IP Specifies the cursor used when a token window is active. The value may have any of the forms acceptable to Tk_GetCursor. The default value is "center_ptr". .RE .TP \fBdrag&drop source \fIwindow \fBhandler \fR?\fIdataType\fR? ?\fIcommand arg arg...\fR? With no extra arguments, this command returns a list of all \fIdataType\fR names that have been registered for the source \fIwindow\fR. If only the \fIdataType\fR is specified, then the \fIdataType\fR is created if necessary, and the command associated with the \fIdataType\fR is returned. Otherwise, it concatenates the \fIcommand\fR and any extra \fIarg\fR strings, and registers a new \fIdataType\fR with this command. .PP The following substitutions are made in the \fIcommand\fR string before it is executed: .RS .TP \fB%i\fR Replaced with the name of the interpreter for the target application. .TP \fB%v\fR Replaced with the value returned from the "-packagecmd" command. .TP \fB%w\fR Replaced with the window path name for the target window. .RE .LP A typical source handler contains one or more "send" commands which transfer data to the remote application. The target window is then asked to handle the new data. Whatever value is returned by the source \fIcommand\fR handler is automatically substituted into the "%v" fields of the target handler. .LP This separation between the transfer and the handling of the data is important. It allows the same source handler to transfer data for many different targets, and it allows each of the targets to handle the incoming data differently. If an error is encountered during the communication process, the rejection symbol is posted on the token window to indicate failure. .RE .sp .TP \fBdrag&drop target\fR Returns a list of path names for widgets registered as drag&drop targets. Returns an empty string if no widgets have been registered. .TP \fBdrag&drop target \fIwindow \fBhandler \fR?\fIdataType command arg arg...\fR? Registers a new drag&drop target window with a given handler, or modifies the handlers for an existing window. If no \fIdataType\fR is specified, this command returns the current list of recognized \fIdataType\fR strings. Each \fIdataType\fR is a symbolic name representing a form of data, and the corresponding \fIcommand\fR is a Tcl command that specifies how the target will make use of the data. This command is invoked indirectly after a source has transferred data to a target application. .PP The following substitutions are made in the \fIcommand\fR string before it is executed: .RS .TP \fB%v\fR In the simplest case, the source window does not have a handler command for the selected \fIdataType\fR, and this field is replaced with the result from the "-packagecmd" command. When the source does have a handler command, the result from the "-packagecmd" command is substituted into its "%v" field, and the result from this command is substituted into this field in the target command. .TP \fB%W\fR Replaced with the window path name for the target window. .RE .TP \fBdrag&drop target \fIwindow \fRhandle \fIdataType\fR ?\fIvalue\fR? Searches for the given \fIdataType\fR name among the handlers registered for the target \fIwindow\fR, and invokes the appropriate \fIcommand\fR. If a \fIvalue\fR is specified, it is substituted into any "%v" fields in the handler command associated with the \fIdataType\fR. If the \fIdataType\fR name is not recognized, this command returns an error. This command is invoked automatically by the drag&drop facility when data is being transferred from a source to a target. .TP \fBdrag&drop token \fIwindow\fR Returns the token window associated with a drag&drop source \fIwindow\fR. The token window is used to represent data as it is being dragged from the source to a target. When a source is first established, its token window must be filled with widgets to display the source data. For example, .sp .nf .RS \f(CWdrag&drop source .foo set win [drag&drop token .foo] label $win.label -text "Data" pack $win.label\fR .RE .fi .sp .TP \fBdrag&drop drag \fIwindow x y\fR Marks the start of (or movement during) a drag&drop operation. If the token window is unmapped when this command is invoked, then the \fB\-packagecmd\fR for the source \fIwindow\fR is executed. If this command is successful and returns a non-null string, the token window is mapped. On subsequent calls, the token window is moved to the new \fIx y\fR location. Unless the "\fB\-button 0\fR" option is specified for the source, this command is automatically bound to <ButtonPress-\fIn\fR> and <B\fIn\fR-Motion> events for "\fB\-button \fIn\fR" of the source widget. .TP \fBdrag&drop drop \fIwindow x y\fR Marks the end of a drag&drop operation. If the mouse pointer is over a compatible target window, then the appropriate send handler for the first compatible \fIdataType\fR is invoked to handle the data transfer. If the data transfer is successful, then the token window is unmapped; otherwise, a rejection symbol is drawn on the token window, and the window is unmapped after a small delay. Unless the "\fB\-button 0\fR" option is specified for the source, this command is automatically bound to the <ButtonRelease-\fIn\fR> event for "\fB\-button \fIn\fR" of the source widget. .TP \fBdrag&drop active\fR Returns "1" if a drag&drop operation is in progress, and "0" otherwise. A drag&drop operation officially starts after the package command has been executed successfully, and ends after the send handler has been executed (successfully or otherwise). .TP \fBdrag&drop errors \fR?\fIproc\fR? Specifies a Tcl \fIproc\fR used to handle errors encountered during drag&drop operations. If a \fIproc\fR is not specified, this command returns the current error handler. By default, all errors are sent to the usual \fBtkerror\fR command, and therefore appear in a dialog box to the user. This behavior is quite useful when debugging communication protocols, but may not be desirable in a finished application. Errors can be suppressed entirely (leaving the rejection symbol as the only error indicator) by specifying a null string in place of the \fIproc\fR name. .TP \fBdrag&drop location \fR?\fIx y\fR? Used to set or query the pointer location during a drag&drop operation. The \fIx y\fR arguments specify the current location; if these arguments are missing, then the last reported (x,y) location is returned as a list with two elements. This command is issued automatically within the \fBdrag&drop drag\fR and \fBdrag&drop drop\fR commands, to keep track of pointer movement. .SH KEYWORDS drag&drop, send, bind, widget ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeReleaseToken.man3�����������������������������������������������������0000644�0001750�0001750�00000004236�11462120062�017600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeReleaseToken 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeReleaseToken \- Releases token associated with tree object. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp int \fBBlt_TreeReleaseToken\fR(\fItoken\fR) .SH ARGUMENTS .AS Blt_Tree token .AP Blt_Tree *token in Token of tree to be released. .BE .SH DESCRIPTION .PP This procedure releases the token associated with a C-based tree data object. When all outstanding tokens for a tree data object have been released, then the data object itself will be freed. The arguments are as follows: .TP 1i token Token of the tree data object to be released. This token was initialized either by \fBTcl_TreeGetToken\fI or \fIBlt_TreeCreate\fR earlier. .SH RETURNS Nothing. .SH EXAMPLE The following example creates and then releases a new token. .CS Blt_Tree token; if (Blt_TreeCreate(interp, "myTree", &token) != TCL_OK) { return TCL_ERROR; } printf("tree is %s\\n", Blt_TreeName(token)); /* Tree will be destroyed when the token is released. */ Blt_TreeReleaseToken(token); .CE .SH KEYWORDS tree, token ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeName.man3�������������������������������������������������������������0000644�0001750�0001750�00000004033�11462120062�016072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeName 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeName \- Returns the name of the tree data object. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp char * \fBBlt_TreeName\fR(\fItree\fR) .SH ARGUMENTS .AS Blt_Tree tree .AP Blt_Tree tree in Token for the tree object. .BE .SH DESCRIPTION .PP This procedure returns the name of the C-based tree data object. The arguments are as follows: .TP 1i \fItree\fR Token for the tree object. The token must have been previously obtained via \fBBlt_TreeGetToken\fR or \fBBlt_TreeCreate\fR. .SH RETURNS The name of the tree object is returned. The name will be fully qualified with a namespace context. .SH EXAMPLE The following example prints the name of the new tree. .CS Blt_Tree token; if (Blt_TreeCreate(interp, NULL, &token) != TCL_OK) { return TCL_ERROR; } printf("tree is %s\\n", Blt_TreeName(token)); .CE .SH KEYWORDS Tcl_TreeGetToken, Tcl_TreeExists, Tcl_TreeReleaseToken �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/hierbox.mann������������������������������������������������������������������0000644�0001750�0001750�00000253721�11462120062�015336� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 2001-2 by Silicon Metrics Corporation. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Silicon Metrics or any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Silicon Metrics disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Silicon Metrics be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" The hierarchical table widget created by George Howlett. '\" .so man.macros .TH treeview n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME treeview \- Create and manipulate hierarchical table widgets .BE .SH SYNOPSIS \fBtreeview\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBtreeview\fR widget displays a tree of data. It replaces both the \fBhiertable\fR and \fBhierbox\fR widgets. The \fBtreeview\fR is 100% syntax compatible with the \fBhiertable\fR widget. The \fBhiertable\fR command is retained for sake of script-level compatibility. This widget obsoletes the \fBhierbox\fR widget. It does everything the old \fBhierbox\fR widget did, but also provides data sharing (via \fItree data objects\fR) and the ability to tag nodes. .SH INTRODUCTION The \fBtreeview\fR widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. .PP A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is \fIopen\fR, its children are exposed. When it is \fIclosed\fR, the children and their descedants are hidden. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). .PP If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. .SH "TREE DATA OBJECT" The tree is not stored inside the widget but in a tree data object (see the \fBtree\fR command for a further explanation). Tree data objects can be shared among different clients, such as a \fBtreeview\fR widget or the \fBtree\fR command. You can walk the tree and manage its data with the \fBtree\fR command tree, while displaying it with the \fBtreeview\fR widget. Whenever the tree is updated, the \fBtreeview\fR widget is automatically redrawn. .PP By default, the \fBtreeview\fR widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the \fBtree\fR command using the \fB\-tree\fR configuration option. \fBTreeview\fR widgets can share the same tree object, possibly displaying different views of the same data. .PP A tree object has both a Tcl and C API. You can insert or delete nodes using \fBtreeview\fR widget or \fBtree\fR command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. .SH SYNTAX .DS \fBtreeview \fIpathName \fR?\fIoption value\fR?... .DE The \fBtreeview\fR command creates a new window \fIpathName\fR and makes it into a \fBtreeview\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the \fBconfigure\fR operation below for the exact details about what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBtreeview\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available are described in the .SB "TREEVIEW OPERATIONS" section. .SH "IDS AND TAGS" Nodes can be inserted into a tree using the \fBtreeview\fR widget .CS blt::treeview .t set node [.t insert end root "one"] .CE or \fBtree\fR command. .CS set tree [blt::tree create] set node [$tree insert root "one"] .CE In both cases, a number identifying the node is returned (the value of \f(CW$node\fR). This serial number or \fIid\fR uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id \f(CW0\fR. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the \fBtreeview\fR widget or the \fBtree\fR command. Ids are recycled when the node deleted. .PP A node may also have any number of \fItags\fR associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "\f(CWx123\fR" is valid, but "\f(CW123\fR" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the \fBtreeview\fR widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. .PP The tag \fBall\fR is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. .PP Tags may be shared, just like trees, between clients. For example, you can use the tags created by the \fBtree\fR command with \fBtreeview\fR widgets. .SH SPECIAL NODE IDS There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the \fBtreeview\fR widget. .TP 15 \fBactive\fR The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the \fB\-activeicon\fR option). The \fBactive\fR id is changed automatically by moving the mouse pointer over another node or by using the \fBentry activate\fR operation. Note that there can be only one active node at a time. .TP 15 \fBanchor\fR The node representing the fixed end of the current selection. The anchor is set by the \fBselection anchor\fR operation. .TP 15 \fBcurrent\fR The node where the mouse pointer is currently located. But unlike \fBactive\fR, this id changes while the selection is dragged. It is used to determine the current node during button drags. .TP 15 \fBdown\fR The next open node from the current focus. The \fBdown\fR of the last open node is the same. .TP 15 \fBend\fR The last open node (in depth-first order) on the tree. .TP 15 \fBfocus\fR The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the \fBfocus\fR operation. .TP 15 \fBlast\fR The last open node from the current focus. But unlike \fBup\fR, when the focus is at root, \fBlast\fR wraps around to the last open node in the tree. .TP 15 \fBmark\fR The node representing the non-fixed end of the current selection. The mark is set by the \fBselection mark\fR operation. .TP 15 \fBnext\fR The next open node from the current focus. But unlike \fBdown\fR, when the focus is on last open node, \fBnext\fR wraps around to the root node. .TP 15 \fBnextsibling\fR The next sibling from the node with the current focus. If the node is already the last sibling then it is the \fBnextsibling\fB. .TP 15 \fBparent\fR The parent of the node with the current focus. The \fBparent\fR of the root is also the root. .TP 15 \fBprevsibling\fR The previous sibling from the node with the current focus. If the node is already the first sibling then it is the \fBprevsibling\fB. .TP 15 \fBroot\fR The root node. You can also use id \f(CW0\fR to indicate the root. .TP 15 \fBup\fR The last open node (in depth-first order) from the current focus. The \fBup\fR of the root node (i.e. the root has focus) is also the root. .TP 15 \fBview.top\fR First node that's current visible in the widget. .TP 15 \fBview.bottom\fR Last node that's current visible in the widget. .TP 15 \fIpath\fR Absolute path of a node. Path names refer to the node name, not their entry labels. Paths don't have to start with a separator (see the \fB\-separator\fR configuration option), but component names must be separated by the designated separator. .TP 15 \fB@\fIx\fB,\fIy\fR Indicates the node that covers the point in the treeview window specified by \fIx\fR and \fIy\fR (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. .PP A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. .SH DATA FIELDS A node in the tree can have \fIdata fields\fR. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the \fBtreeview\fR widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. .SH ENTRY BINDINGS You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its \fIbindtags\fR. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag \f(CWall\fR that all node entries automatically have. .SH "TREEVIEW OPERATIONS" The \fBtreeview\fR operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .CS \fIpathName operation \fR?\fIarg arg ...\fR? .CE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operation are available for \fBtreeview\fR widgets: .TP \fIpathName \fBbbox\fR ?\fB-screen\fR? \fItagOrId...\fR Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more \fItagOrId\fR arguments. If the \fB\-screen\fR flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from \f(CW0\fR from the root node. The returned list contains the following values. .RS .TP 1.25i \fIx\fR X-coordinate of the upper-left corner of the bounding box. .TP \fIy\fR Y-coordinate of the upper-left corner of the bounding box. .TP \fIwidth\fR Width of the bounding box. .TP \fIheight\fR Height of the bounding box. .RE .TP \fIpathName \fBbind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a node with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR entries, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton \fIoperation\fR ?\fIargs\fR? This command is used to control the button selectors within a \fBtreeview\fR widget. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBbutton activate\fR \fItagOrId\fR Designates the node given by \fItagOrId\fR as active. When a node is active it's entry is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active entry at a time. The special id \fBactive\fR indicates the currently active node. .TP \fIpathName \fBbutton bind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an button of a node entry with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR buttons, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBbutton configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "BUTTON OPTIONS" below. .RE .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBclose \fR?\fB\-recurse\fR? \fItagOrId...\fR Closes the node specified by \fItagOrId\fR. In addition, if a Tcl script was specified by the \fB\-closecommand\fR option, it is invoked. If the node is already closed, this command has no effect. If the \fB\-recurse\fR flag is present, each child node is recursively closed. .TP \fIpathName \fBcolumn \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview columns. .RS .TP \fIpathName \fBcolumn activate\fR \fIcolumn\fR Sets the active column to \fIcolumn\fR. \fIColumn\fR is the name of a column in the widget. When a column is active, it's drawn using its \fB\-activetitlebackground\fR and \fB\-activetitleforeground\fR options. If \fIcolumn\fR is the \f(CW""\fR, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. .TP \fIpathName \fBcolumn cget\fR \fIname\fR \fIoption\fR Returns the current value of the column configuration option given by \fIoption\fR for \fIname\fR. \fIName\fR is the name of column that corresponds to a data field. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBcolumn configure\fR \fIname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the column designated by \fIname\fR. \fIName\fR is the name of the column corresponding to a data field. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "COLUMN OPTIONS" below. .TP \fIpathName \fBcolumn delete\fR \fIfield\fR ?\fIfield\fR...? Deletes one of more columns designated by \fIfield\fR. Note that this does not delete the data fields themselves. .TP \fIpathName \fBcolumn insert\fR \fIposition\fR \fIfield\fR ?\fIoptions\fR...? Inserts one of more columns designated by \fIfield\fR. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. \fIPosition\fR indicates where in the list of columns to add the new column. It may be either a number or \f(CWend\fR. .TP \fIpathName \fBcolumn invoke\fR \fIfield\fR Invokes the Tcl command associated with the column \fIfield\fR, if there is one (using the column's \fB\-command\fR option). The command is ignored if the column's \fB\-state\fR option set to \f(CWdisabled\fR. .TP \fIpathName \fBcolumn move \fIname\fR \fIdest\fR Moves the column \fIname\fR to the destination position. \fIDest\fR is the name of another column or a screen position in the form \f(CW@\fIx\f(CW,\fIy\fR. .TP \fIpathName \fBcolumn names\fR Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. .TP \fIpathName \fBcolumn nearest\fR \fIx\fR ?\fIy\fR? Returns the name of the column closest to the given X-Y screen coordinate. If you provide a \fIy\fR argument (it's optional), a name is returned only when if the point is over a column's title. .RE .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TREEVIEW OPTIONS" below. .TP \fIpathName \fBcurselection\fR Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. .TP \fIpathName \fBdelete \fItagOrId\fR... Deletes one or more entries given by \fItagOrId\fR and its children. .TP \fIpathName \fBentry \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview entries. .RS .TP \fIpathName \fBentry activate\fR \fItagOrId\fR Sets the active entry to the one specified by \fItagOrId\fR. When an entry is active it is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active node at a time. The special id of the currently active node is \fBactive\fR. .TP \fIpathName \fBentry cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBentry children\fR \fItagOrId\fR ?\fIfirst\fR? ?\fIlast\fR? Returns a list of ids for the given range of children of \fItagOrId\fR. \fITagOrId\fR is the id or tag of the node to be examined. If only a \fIfirst\fR argument is present, then the id of the that child at that numeric position is returned. If both \fIfirst\fR and \fIlast\fR arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. .TP \fIpathName \fBentry configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .TP \fIpathName \fBentry delete\fR \fItagOrId\fR ?\fIfirst\fR ?\fIlast\fR? Deletes the one or more children nodes of the parent \fItagOrId\fR. If \fIfirst\fR and \fIlast\fR arguments are present, they are positions designating a range of children nodes to be deleted. .TP \fIpathName \fBentry isbefore \fItagOrId1\fR \fItagOrId2\fR Returns 1 if \fItagOrId1\fR is before \fItagOrId2\fR and 0 otherwise. .TP \fIpathName \fBentry ishidden \fItagOrId\fR Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. .TP \fIpathName \fBentry isopen \fItagOrId\fR Returns 1 if the node is currently open and 0 otherwise. .TP \fIpathName \fBentry size\fR \fB\-recurse\fR \fItagOrId\fR Returns the number of children for parent node \fItagOrId\fR. If the \fB\-recurse\fR flag is set, the number of all its descendants is returned. The node itself is not counted. .RE .TP \fIpathName \fBfind \fR?\fIflags\fR? \fIfirst\fR \fIlast\fR Finds for all entries matching the criteria given by \fIflags\fR. A list of ids for all matching nodes is returned. \fIFirst\fR and \fIlast\fR are ids designating the range of the search in depth-first order. If \fIlast\fR is before \fIfirst\fR, then nodes are searched in reverse order. The valid flags are: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Patterns must match exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Pick entries that don't match. .TP 1.25i \fB\-exec\fI string\fR Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP 1.25i \fB\-count\fI number\fR Stop searching after \fInumber\fR matches. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBfocus \fR \fItagOrId\fR Sets the focus to the node given by \fItagOrId\fR. When a node has focus, it can receive keyboard events. The special id \fBfocus\fR designates the node that currently has focus. .TP \fIpathName \fBget \fR?\fB\-full\fR? \fItagOrId\fR \fItagOrId\fR... Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the \fB\-full\fR flag is set, then the full pathnames are returned. .TP \fIpathName \fBhide \fR?\fBflags\fR? \fItagOrId\fR... Hides all nodes matching the criteria given by \fIflags\fR. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Hide nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBindex \fR?\fB\-at\fR \fItagOrId\fR? \fIstring\fR Returns the id of the node specified by \fIstring\fR. \fIString\fR may be a tag or node id. Some special ids are normally relative to the node that has focus. The \fB\-at\fR flag lets you select another node. .TP \fIpathName \fBinsert \fR?\fB\-at \fItagOrId\fR? \fIposition\fR \fIpath\fR ?\fIoptions...\fR? ?\fIpath\fR? ?\fIoptions...\fR? Inserts one or more nodes at \fIposition\fR. \fIPosition\fR is the location (number or \f(CWend\fR) where the new nodes are added to the parent node. \fIPath\fR is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the \fB\-separator\fR option). Pathnames are normally absolute, but the \fB\-at\fR switch lets you select a relative starting point. Its value is the id of the starting node. .sp All ancestors of the new node must already exist, unless the \fB\-autocreate\fR option is set. It is also an error if a node already exists, unless the \fB\-allowduplicates\fR option is set. .sp \fIOption\fR and \fIvalue\fR may have any of the values accepted by the \fBentry configure\fR operation described in the .SB "ENTRY OPERATIONS" section below. This command returns a list of the ids of the new entries. .TP \fIpathName \fBmove \fItagOrId\fR \fIhow\fR \fIdestId\fR Moves the node given by \fItagOrId\fR to the destination node. The node can not be an ancestor of the destination. \fIDestId\fR is the id of the destination node and can not be the root of the tree. In conjunction with \fIhow\fR, it describes how the move is performed. .RS .TP 8 \f(CWbefore\fR Moves the node before the destination node. .TP 8 \f(CWafter\fR Moves the node after the destination node. .TP 8 \f(CWinto\fR Moves the node to the end of the destination's list of children. .RE .TP \fIpathName \fBnearest \fIx y\fR ?\fIvarName\fR? Returns the id of the node entry closest to the given X-Y screen coordinate. The optional argument \fIvarName\fR is the name of variable which is set to either \f(CWbutton\fR or \f(CWselect\fR to indicate over what part of the node the coordinate lies. If the coordinate is not directly over any node, then \fIvarName\fR will contain the empty string. .TP \fIpathName \fBopen \fR?\fB\-recurse\fR? \fItagOrId...\fR Opens the one or more nodes specified by \fItagOrId\fR. If a node is not already open, the Tcl script specified by the \fB\-opencommand\fR option is invoked. If the \fB\-recurse\fR flag is present, then each descendant is recursively opened. .TP \fIpathName \fBrange\fR ?\fB-open\fR? \fIfirst last\fR Returns the ids in depth-first order of the nodes between the \fIfirst\fR and \fIlast\fR ids. If the \fB\-open\fR flag is present, it indicates to consider only open nodes. If \fIlast\fR is before \fIfirst\fR, then the ids are returned in reverse order. .TP \fIpathName \fBscan\fR \fIoption args\fR This command implements scanning. It has two forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBscan mark \fIx y\fR Records \fIx\fR and \fIy\fR and the current view in the treeview window; used in conjunction with later \fBscan dragto\fR commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. .TP \fIpathName \fBscan dragto \fIx y\fR. Computes the difference between its \fIx\fR and \fIy\fR arguments and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. .RE .TP \fIpathName \fBsee\fR ?\fB\-anchor \fIanchor\fR? \fItagOrId\fR Adjusts the view of entries so that the node given by \fItagOrId\fR is visible in the widget window. It is an error if \fBtagOrId\fR is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the \fB\-anchor\fR flag. Its value is a Tk anchor position. .TP \fIpathName \fBselection \fIoption arg\fR This command is used to adjust the selection within a \fBtreeview\fR widget. It has several forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBselection anchor \fItagOrId\fR Sets the selection anchor to the node given by \fItagOrId\fR. If \fItagOrId\fR refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBanchor\fR may be used to refer to the anchor node. .TP \fIpathName \fBselection cancel\fR Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the \fBselection mark\fR operation. .TP \fIpathName \fBselection clear \fIfirst \fR?\fIlast\fR? Removes the entries between \fIfirst\fR and \fIlast\fR (inclusive) from the selection. Both \fIfirst\fR and \fIlast\fR are ids representing a range of entries. If \fIlast\fR isn't given, then only \fIfirst\fR is deselected. Entries outside the selection are not affected. .TP \fIpathName \fBselection clearall\fR Clears the entire selection. .TP \fIpathName \fBselection mark \fItagOrId\fR Sets the selection mark to the node given by \fItagOrId\fR. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBmark\fR may be used to refer to the current mark node. If \fItagOrId\fR refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. .TP \fIpathName \fBselection includes \fItagOrId\fR Returns 1 if the node given by \fItagOrId\fR is currently selected, 0 if it isn't. .TP \fIpathName \fBselection present\fR Returns 1 if any nodes are currently selected and 0 otherwise. .TP \fIpathName \fBselection set \fIfirst \fR?\fIlast\fR? Selects all of the nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, without affecting the selection state of nodes outside that range. .TP \fIpathName \fBselection toggle \fIfirst \fR?\fIlast\fR? Selects/deselects nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. .RE .TP \fIpathName \fBshow \fR?\fBflags\fR? \fItagOrId\fR... Exposes all nodes matching the criteria given by \fIflags\fR. This is the inverse of the \fBhide\fR operation. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Expose nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBsort\fR ?\fIoperation\fR? \fIargs...\fR .RS .TP \fIpathName \fBsort auto\fR ?\fIboolean\fR Turns on/off automatic sorting of node entries. If \fIboolean\fR is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no \fIboolean\fR argument is provided, the current state is returned. .TP \fIpathName \fBsort cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBsort configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the sorting configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .RS .TP \fB\-column\fI string\fR Specifies the column to sort. Entries in the widget are rearranged according to this column. If \fIcolumn\fR is \f(CW""\fR then no sort is performed. .TP \fB\-command\fI string\fR Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. .TP \fB\-decreasing\fI boolean\fR Indicates to sort in ascending/descending order. If \fIboolean\fR is true, then the entries as in descending order. The default is \f(CWno\fR. .TP \fB\-mode\fI string\fR Specifies how to compare entries when sorting. \fIString\fR may be one of the following: .RS .TP 1.5i \f(CWascii\fR Use string comparison based upon the ASCII collation order. .TP 1.5i \f(CWdictionary\fR Use dictionary-style comparison. This is the same as \f(CWascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". .TP 1.5i \f(CWinteger\fR Compares fields as integers. .TP 1.5i \f(CWreal\fR Compares fields as floating point numbers. .TP 1.5i \f(CWcommand\fR Use the Tcl proc specified by the \fB\-command\fR option to compare entries when sorting. If no command is specified, the sort reverts to \f(CWascii\fR sorting. .RE .RE .TP \fIpathName \fBsort once\fR ?\fIflags\fR? \fItagOrId...\fR Sorts the children for each entries specified by \fItagOrId\fR. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. .RS .TP 1.5i \fB\-recurse\fR Recursively sort the entire branch, not just the children. .RE .RE .TP \fIpathName \fBtag \fIoperation args\fR Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. .sp Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tags are listed below. .RS .TP \fIpathName\fR \fBtag add\fR \fIstring\fR \fIid\fR... Adds the tag \fIstring\fR to one of more entries. .TP \fIpathName\fR \fBtag delete\fR \fIstring\fR \fIid\fR... Deletes the tag \fIstring\fR from one or more entries. .TP \fIpathName\fR \fBtag forget\fR \fIstring\fR Removes the tag \fIstring\fR from all entries. It's not an error if no entries are tagged as \fIstring\fR. .TP \fIpathName\fR \fBtag names\fR ?\fIid\fR? Returns a list of tags used. If an \fIid\fR argument is present, only those tags used by the node designated by \fIid\fR are returned. .TP \fIpathName\fR \fBtag nodes\fR \fIstring\fR Returns a list of ids that have the tag \fIstring\fR. If no node is tagged as \fIstring\fR, then an empty string is returned. .RE .TP \fIpathName \fBtext \fIoperation\fR ?\fIargs\fR? This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBtext apply\fR Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. .TP \fIpathName \fBtext cancel\fR Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. .TP \fIpathName \fBtext cget\fI value\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBtext configure\fR ?\fIoption value\fR? Query or modify the configuration options of the edit window. If no \fIoption\fR is specified, returns a list describing all of the available options (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TEXT EDITING OPTIONS" below. .RE .TP \fIpathName \fBtext delete\fI first last\fR Deletes the characters in the edit buffer between the two given character positions. .TP \fIpathName \fBtext get\fR ?\fI\-root\fR? \fIx y\fR .TP \fIpathName \fBtext icursor\fI index\fR .TP \fIpathName \fBtext index\fI index\fR Returns the text index of given \fIindex\fR. .TP \fIpathName \fBtext insert\fI index string\fR Insert the text string \fIstring\fR into the edit buffer at the index \fIindex\fR. For example, the index 0 will prepend the buffer. .TP \fIpathName \fBtext selection\fI args\fR This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: .RS .TP \fIpathName \fBtext selection adjust\fI index\fR Adjusts either the first or last index of the selection. .TP \fIpathName \fBtext selection clear\fR Clears the selection. .TP \fIpathName \fBtext selection from\fI index\fR Sets the anchor of the selection. .TP \fIpathName \fBtext selection present\fR Indicates if a selection is present. .TP \fIpathName \fBtext selection range\fI start end\fR Sets both the anchor and mark of the selection. .TP \fIpathName \fBtext selection to\fI index\fR Sets the unanchored end (mark) of the selection. .RE .TP \fIpathName \fBtoggle \fItagOrId\fR Opens or closes the node given by \fItagOrId\fR. If the corresponding \fB\-opencommand\fR or \fB\-closecommand\fR option is set, then that command is also invoked. .TP \fIpathName \fBxview \fIargs\fR This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fBxview\fR Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the \fBtreeview\fR widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR option. .TP \fIpathName \fBxview\fR \fItagOrId\fR Adjusts the view in the window so that the character position given by \fItagOrId\fR is displayed at the left edge of the window. Character positions are defined by the width of the character \fB0\fR. .TP \fIpathName \fBxview moveto\fI fraction\fR Adjusts the view in the window so that \fIfraction\fR of the total width of the \fBtreeview\fR widget's text is off-screen to the left. \fIfraction\fR must be a fraction between 0 and 1. .TP \fIpathName \fBxview scroll \fInumber what\fR This command shifts the view in the window left or right according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation of one of these. If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by \fInumber\fR character units (the width of the \fB0\fR character) on the display; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. .RE .TP \fIpathName \fByview \fI?args\fR? This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fByview\fR Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR option. .TP \fIpathName \fByview\fR \fItagOrId\fR Adjusts the view in the window so that the node given by \fItagOrId\fR is displayed at the top of the window. .TP \fIpathName \fByview moveto\fI fraction\fR Adjusts the view in the window so that the node given by \fIfraction\fR appears at the top of the window. \fIFraction\fR is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the \fBtreeview\fR widget, and so on. .TP \fIpathName \fByview scroll \fInumber what\fR This command adjusts the view in the window up or down according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR. If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by \fInumber\fR lines; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then earlier nodes become visible; if it is positive then later nodes become visible. .RE .SH "TREEVIEW OPTIONS" In addition to the \fBconfigure\fR operation, widget configuration options may also be set by the Tk \fBoption\fR command. The class resource name is \f(CWTreeView\fR. .CS option add *TreeView.Foreground white option add *TreeView.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed for an entry's icon when it is active. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-autocreate \fIboolean\fR If \fIboolean\fR is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-allowduplicates \fIboolean\fR If \fIboolean\fR is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-background \fIcolor\fR Sets the background color of the widget. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's \fB\-closecommand\fR option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-dashes \fInumber\fR Sets the dash style of the horizontal and vertical lines drawn connecting entries. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, solid lines will be drawn. The default is \f(CW1\fR (dotted). .TP \fB\-exportselection \fIboolean\fR Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR; the value of the selection will be the label of the selected nodes, separated by newlines. The default is \f(CWno\fR. .TP \fB\-flat \fIboolean\fR Indicates whether to display the tree as a flattened list. If \fIboolean\fR is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the .SB "SORT OPERATIONS" section for more information. The default is \f(CWno\fR. .TP \fB\-focusdashes \fIdashList\fR Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, a solid line will be drawn. The default is \f(CW1\fR. .TP \fB\-focusforeground \fIcolor\fR Sets the color of the focus rectangle. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Specifies the font for entry labels. You can override this for individual entries with the entry's \fB\-font\fR configuration option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of entry labels. You can override this for individual entries with the entry's \fB\-foreground\fR configuration option. The default is \f(CWblack\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW400\fR. .TP \fB\-hideroot \fIboolean\fR If \fIboolean\fR is true, it indicates that no entry for the root node should be displayed. The default is \f(CWno\fR. .TP \fB\-highlightbackground \fIcolor\fR Specifies the normal color of the traversal highlight region when the widget does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight will be displayed. The default is \f(CW2\fR. .TP \fB\-icons \fIimages\fR Specifies images for the entry's icon. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-linecolor \fIcolor\fR Sets the color of the connecting lines drawn between entries. The default is \f(CWblack\fR. .TP \fB\-linespacing \fIpixels\fR Sets the number of pixels spacing between entries. The default is \f(CW0\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the lines drawn connecting entries. If \fIpixels\fR is \f(CW0\fR, no vertical or horizontal lines are drawn. The default is \f(CW1\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's \fB\-opencommand\fR configuration option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the widget. \fIRelief\fR specifies how the \fBtreeview\fR widget should appear relative to widget it is packed into; for example, \f(CWraised\fR means the \fBtreeview\fR widget should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-scrollmode \fImode\fR Specifies the style of scrolling to be used. The following styles are valid. This is the default is \f(CWhierbox\fR. .RS .TP 1.25i \f(CWlistbox\fR Like the \fBlistbox\fR widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. .TP 1.25i \f(CWhierbox\fR Like the \fBhierbox\fR widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. .TP 1.25i \f(CWcanvas\fR Like the \fBcanvas\fR widget, the entries are bound within the scrolling area. .RE .TP \fB\-selectbackground \fIcolor\fR Sets the background color selected node entries. The default is \f(CW#ffffea\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is \f(CW0\fR. \fB\-selectcommand \fIstring\fR Specifies a Tcl script to invoked when the set of selected nodes changes. The default is \f(CW""\fR. .TP \fB\-selectforeground \fIcolor\fB Sets the color of the labels of selected node entries. The default is \f(CWblack\fR. .TP \fB\-selectmode \fImode\fR Specifies the selection mode. If \fImode\fR is \f(CWsingle\fR, only one node can be selected at a time. If \f(CWmultiple\fR more than one node can be selected. The default is \f(CWsingle\fR. .TP \fB\-separator \fIstring\fR Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If \fIstring\fR is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is \f(CW""\fR. .TP \fB\-showtitles \fIboolean\fR If \fIboolean\fR is false, column titles are not be displayed. The default is \f(CWyes\fR. .TP \fB\-sortselection \fIboolean\fR If \fIboolean\fR is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is \f(CWno\fR. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW"1"\fR. .TP \fB\-trim \fIstring\fR Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the \fB\-separator\fR is also set. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the widget. If \fIpixels\fR is 0, then the with is computed from the contents of the \fBtreeview\fR widget. The default is \f(CW200\fR. .TP \fB\-xscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-xscrollincrement\fR \fIpixels\fR Sets the horizontal scrolling distance. The default is 20 pixels. .TP \fB\-yscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-yscrollincrement\fR \fIpixels\fR Sets the vertical scrolling distance. The default is 20 pixels. .SH "ENTRY OPTIONS" Many widget configuration options have counterparts in entries. For example, there is a \fB\-closecommand\fR configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. .PP There is no resource class or name for entries. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed as the entry's icon when it is active. This overrides the global \fB\-activeicons\fR configuration option for the specific entry. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for nodes. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is \f(CWall\fR. .TP \fB\-button \fIstring\fR Indicates whether a button should be displayed on the left side of the node entry. \fIString\fR can be \f(CWyes\fR, \f(CWno\fR, or \f(CWauto\fR. If \f(CWauto\fR, then a button is automatically displayed if the node has children. This is the default. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when the node is closed. This overrides the global \fB\-closecommand\fR option for this entry. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-data \fIstring\fR Sets data fields for the node. \fIString\fR is a list of name-value pairs to be set. The default is \f(CW""\fR. .TP \fB\-font \fIfontName\fR Sets the font for entry labels. This overrides the widget's \fB\-font\fR option for this node. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of the entry label. This overrides the widget's \fB\-foreground\fR configuration option. The default is \f(CW""\fR. .TP \fB\-icons \fIimages\fR Specifies images to be displayed for the entry's icon. This overrides the global \fB\-icons\fR configuration option. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-label \fIstring\fR Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is \f(CW""\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's \fB\-opencommand\fR option for this node. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .SH "BUTTON OPTIONS" Button configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWButton\fR. The resource name is always \f(CWbutton\fR. .CS option add *TreeView.Button.Foreground white option add *TreeView.button.Background blue .CE The following are the configuration options available for buttons. .TP \fB\-activebackground \fIcolor\fR Sets the background color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-background \fIcolor\fR Sets the background of the button. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the button. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-closerelief \fIrelief\fR Specifies the 3-D effect for the closed button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-cursor \fIcursor\fR Sets the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of buttons. The default is \f(CWblack\fR. .TP \fB\-images \fIimages\fR Specifies images to be displayed for the button. \fIImages\fR is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the \fIimages\fR is the empty string, then a plus/minus gadget is drawn. The default is \f(CW""\fR. .TP \fB\-openrelief \fIrelief\fR Specifies the 3-D effect of the open button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-size \fIpixels\fR Sets the requested size of the button. The default is \f(CW0\fR. .RE .SH "COLUMN OPTIONS" Column configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWColumn\fR. The resource name is the name of the column. .CS option add *TreeView.Column.Foreground white option add *TreeView.treeView.Background blue .CE The following configuration options are available for columns. .TP \fB\-background \fIcolor\fR Sets the background color of the column. This overrides the widget's \fB\-background\fR option. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border of the column. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW0\fR. .TP \fB\-edit \fIboolean\fR Indicates if the column's data fields can be edited. If \fIboolean\fR is false, the data fields in the column may not be edited. The default is \f(CWyes\fR. .TP \fB\-foreground \fIcolor\fR Specifies the foreground color of the column. You can override this for individual entries with the entry's \fB\-foreground\fR option. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Sets the font for a column. You can override this for individual entries with the entry's \fB\-font\fR option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-hide \fIboolean\fR If \fIboolean\fR is true, the column is not displayed. The default is \f(CWyes\fR. .TP \fB\-justify \fIjustify\fR Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWleft\fR. .TP \fB\-pad \fIpad\fR Specifies how much padding for the left and right sides of the column. \fIPad\fR is a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the column is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the column. \fIRelief\fR specifies how the column should appear relative to the widget; for example, \f(CWraised\fR means the column should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-state \fIstate\fR Sets the state of the column. If \fIstate\fR is \f(CWdisable\fR then the column title can not be activated nor invoked. The default is \f(CWnormal\fR. .TP \fB\-text \fIstring\fR Sets the title for the column. The default is \f(CW""\fR. .TP \fB\-titleforeground \fIcolor\fR Sets the foreground color of the column title. The default is \f(CWblack\fR. .TP \fB\-titleshadow \fIcolor\fR Sets the color of the drop shadow of the column title. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the column. This overrides the computed with of the column. If \fIpixels\fR is 0, the width is computed as from the contents of the column. The default is \f(CW0\fR. .RE .SH "TEXT EDITING OPTIONS" Text edit window configuration options may also be set by the \fBoption\fR command. The resource class is \f(CWTreeViewEditor\fR. The resource name is always \f(CWedit\fR. .CS option add *TreeViewEditor.Foreground white option add *edit.Background blue .CE The following are the configuration options available for the text editing window. .TP \fB\-background \fIcolor\fR Sets the background of the text edit window. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the edit window. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-exportselection \fIboolean\fR Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the edit window. \fIRelief\fR indicates how the background should appear relative to the edit window; for example, \f(CWraised\fR means the background should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-selectbackground \fIcolor\fR Sets the background of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the 3\-D border around the selected text in the edit window. The \fB\-selectrelief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-selectforeground \fIcolor\fR Sets the foreground of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectrelief \fIrelief\fR Specifies the 3-D effect of the selected text in the edit window. \fIRelief\fR indicates how the text should appear relative to the edit window; for example, \f(CWraised\fR means the text should appear to protrude. The default is \f(CWflat\fR. .RE .SH "DEFAULT BINDINGS" Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a \fBtreeview\fR widget is determined by its \fB\-selectmode\fR option, which selects one of two ways of dealing with the selection. .PP If the selection mode is \fBsingle\fR, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. .PP If the selection mode is \fBmultiple\fR, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. .IP [1] In \fBextended\fR mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. .IP [2] In \fBextended\fR mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. .IP [3] If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. .IP [4] Mouse button 2 may be used for scanning. If it is pressed and dragged over the \fBtreeview\fR widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. .IP [5] If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is \fBbrowse\fR or \fBextended\fR then the new active entry is also selected and all other entries are deselected. In \fBextended\fR mode the new active entry becomes the selection anchor. .IP [6] In \fBextended\fR mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. .IP [7] The Left and Right keys scroll the \fBtreeview\fR widget view left and right by the width of the character \fB0\fR. Control-Left and Control-Right scroll the \fBtreeview\fR widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. .IP [8] The Prior and Next keys scroll the \fBtreeview\fR widget view up and down by one page (the height of the window). .IP [9] The Home and End keys scroll the \fBtreeview\fR widget horizontally to the left and right edges, respectively. .IP [10] Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. .IP [11] Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. .IP [12] In \fBextended\fR mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. .IP [13] In \fBmultiple\fR mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. .IP [14] The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. .IP [15] In \fBextended\fR mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. .IP [16] In \fBextended\fR mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. .IP [17] Control-slash selects everything in the widget, except in \fBsingle\fR and \fBbrowse\fR modes, in which case it selects the active entry and deselects everything else. .IP [18] Control-backslash deselects everything in the widget, except in \fBbrowse\fR mode where it has no effect. .IP [19] The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. .PP The behavior of \fBtreeview\fR widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. .SS WIDGET BINDINGS In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. .IP \f(CW<ButtonPress-2>\fR Starts scanning. .IP \f(CW<B2-Motion>\fR Adjusts the scan. .IP \f(CW<ButtonRelease-2>\fR Stops scanning. .IP \f(CW<B1-Leave>\fR Starts auto-scrolling. .IP \f(CW<B1-Enter>\fR Starts auto-scrolling .IP \f(CW<KeyPress-Up>\fR Moves the focus to the previous entry. .IP \f(CW<KeyPress-Down>\fR Moves the focus to the next entry. .IP \f(CW<Shift-KeyPress-Up>\fR Moves the focus to the previous sibling. .IP \f(CW<Shift-KeyPress-Down>\fR Moves the focus to the next sibling. .IP \f(CW<KeyPress-Prior>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Next>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Left>\fR Closes the entry. It is not an error if the entry has no children. .IP \f(CW<KeyPress-Right>\fR Opens the entry, displaying its children. It is not an error if the entry has no children. .IP \f(CW<KeyPress-space>\fR In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). .IP \f(CW<KeyRelease-space>\fR Turns off select mode. .IP \f(CW<KeyPress-Return>\fR Sets the focus to the current entry. .IP \f(CW<KeyRelease-Return>\fR Turns off select mode. .IP \f(CW<KeyPress>\fR Moves to the next entry whose label starts with the letter typed. .IP \f(CW<KeyPress-Home>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-End>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-F1>\fR Opens all entries. .IP \f(CW<KeyPress-F2>\fR Closes all entries (except root). .SS BUTTON BINDINGS Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the button of the current entry. .IP \f(CW<Leave>\fR Returns the button back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Adjust the view so that the current entry is visible. .SS ENTRY BINDINGS Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to modify them. .IP \f(CW<Enter>\fR Highlights the current entry. .IP \f(CW<Leave>\fR Returns the entry back to its normal state. .IP \f(CW<ButtonPress-1>\fR Sets the selection anchor the current entry. .IP \f(CW<Double-ButtonPress-1>\fR Toggles the selection of the current entry. .IP \f(CW<B1-Motion>\fR For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. .IP \f(CW<ButtonRelease-1>\fR For "multiple" mode only. Sets the selection anchor to the current entry. .IP \f(CW<Shift-ButtonPress-1>\fR For "multiple" mode only. Extends the selection. .IP \f(CW<Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Shift-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Shift-ButtonRelease-1>\fR Stop auto-scrolling. .IP \f(CW<Control-ButtonPress-1>\fR For "multiple" mode only. Toggles and extends the selection. .IP \f(CW<Control-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Control-ButtonRelease-1>\fR Stops auto-scrolling. .IP \f(CW<Control-Shift-ButtonPress-1>\fR ??? .IP \f(CW<Control-Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-Shift-B1-Motion>\fR Place holder. Does nothing. .SS COLUMN BINDINGS Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the \fBcolumn bind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the current column title. .IP \f(CW<Leave>\fR Returns the column back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Invokes the command (see the column's -command option) if one if specified. .SS COLUMN RULE BINDINGS .IP \f(CW<Enter>\fR Highlights the current and activates the ruler. .IP \f(CW<Leave>\fR Returns the column back to its normal state. Deactivates the ruler. .IP \f(CW<ButtonPress-1>\fR Sets the resize anchor for the column. .IP \f(CW<B1-Motion>\fR Sets the resize mark for the column. .IP \f(CW<ButtonRelease-1>\fR Adjust the size of the column, based upon the resize anchor and mark positions. .SH EXAMPLE The \fBtreeview\fR command creates a new widget. .CS treeview .h \-bg white .CE A new Tcl command \f(CW.h\fR is also created. This command can be used to query and modify the \fBtreeview\fR widget. For example, to change the background color of the table to "green", you use the new command and the widget's \fBconfigure\fR operation. .CS # Change the background color. \&.h configure \-background "green" .CE By default, the \fBtreeview\fR widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the \fB\-tree\fR option to specify the name of another tree. .CS # View the tree "myTree". \&.h configure \-tree "myTree" .CE When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always \f(CW0\fR (you can use also use the special id \f(CWroot\fR). The \fBinsert\fR operation lets you insert one or more new entries into the tree. The last argument is the node's \fIpathname\fR. .CS # Create a new entry named "myEntry" set id [\&.h insert end "myEntry"] .CE This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. .CS # Prepend "fred". set id [\&.h insert 0 "fred"] .CE Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the \fB\-label\fR option. .CS # Create a new node named "fred" set id [\&.h insert end "fred" -label "Fred Flintstone"] .CE The \fBinsert\fR operation returns the id of the new node. You can also use the \fBindex\fR operation to get this information. .CS # Get the id of "fred" \&.h index "fred" .CE To insert a node somewhere other than root, use the \fB\-at\fR switch. It takes the id of the node where the new child will be added. .CS # Create a new node "barney" in "fred". \&.h insert -at $id end "barney" .CE A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. .CS # Create a new sub-entry of "fred" \&.h insert end "fred barney" .CE Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the \fB\-autocreate\fR configuration option to force the creation of ancestor nodes. .CS # Force the creation of ancestors. \&.h configure -autocreate yes \&.h insert end "fred barney wilma betty" .CE Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the \fB\-separator\fR option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. .CS \&.h configure -separator / \&.h insert end "/usr/local/tcl/bin" .CE If the path is prefixed by extraneous characters, you can automatically trim it off using the \fB\-trim\fR option. It removed the string from the path before it is parsed. .CS \&.h configure -trim C:/windows -separator / \&.h insert end "C:/window/system" .CE You can insert more than one entry at a time with the \fBinsert\fR operation. This can be much faster than looping over a list of names. .CS # The slow way foreach f [glob $dir/*] { \&.h insert end $f } # The fast way eval .h insert end [glob $dir/*] .CE In this case, the \fBinsert\fR operation will return a list of ids of the new entries. .PP You can delete entries with the \fBdelete\fR operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. .CS \&.h delete $id .CE Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the \fB\-label\fR option that sets the entry's text label. The \fBentry configure\fR operation lets you set or modify an entry's configuration options. .CS \&.h entry configure $id -color red -font fixed .CE You can hide an entry and its children using the \fB\-hide\fR option. .CS \&.h entry configure $id -hide yes .CE More that one entry can be configured at once. All entries specified are configured with the same options. .CS \&.h entry configure $i1 $i2 $i3 $i4 -color brown .CE An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's \fB\-icons\fR option. It takes a list of two image names: one to represent the open entry, another when it is closed. .CS set im1 [image create photo -file openfolder.gif] set im2 [image create photo -file closefolder.gif] \&.h entry configure $id -icons "$im1 $im2" .CE If \fB\-icons\fR is set to the empty string, no icons are display. .PP If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol, but can be configured in a variety of ways using the \fBbutton configure\fR operation. For example, the \f(CW+\fR and \f(CW\-\fR symbols can be replaced with Tk images. .CS set im1 [image create photo -file closefolder.gif] set im2 [image create photo -file downarrow.gif] \&.h button configure $id -images "$im1 $im2" \\ -openrelief raised -closerelief raised .CE Entries can contain an arbitrary number of \fIdata fields\fR. Data fields are name-value pairs. Both the value and name are strings. The entry's \fB\-data\fR option lets you set data fields. .CS \&.h entry configure $id -data {mode 0666 group users} .CE The \fB\-data\fR takes a list of name-value pairs. .PP You can display these data fields as \fIcolumns\fR in the \fBtreeview\fR widget. You can create and configure columns with the \fBcolumn\fR operation. For example, to add a new column to the widget, use the \fBcolumn insert\fR operation. The last argument is the name of the data field that you want to display. .CS \&.h column insert end "mode" .CE The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's \fB\-text\fR option. .CS \&.h column insert end "mode" -text "File Permissions" .CE Columns have several configuration options. The \fBcolumn configure\fR operation lets you query or modify column options. .CS \&.h column configure "mode" -justify left .CE The \fB\-justify\fR option says how the data is justified within in the column. The \fB\-hide\fR option indicates whether the column is displayed. .CS \&.h column configure "mode" -hide yes .CE Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the \fB\-selectforeground\fR and \fB\-selectbackground\fR configuration options. The selection itself is managed by the \fBselection\fR operation. .CS # Clear all selections \&.h selection clear 0 end # Select the root node \&.h selection set 0 .CE The \fBcurselection\fR operation returns a list of ids of all the selected entries. .CS set ids [\&.h curselection] .CE You can use the \fBget\fR operation to convert the ids to their pathnames. .CS set names [eval .h get -full $ids] .CE If a treeview is exporting its selection (using the \fB\-exportselection\fR option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type \fBSTRING\fR; the value of the selection will be the pathnames of the selected entries, separated by newlines. .PP The \fBtreeview\fR supports two modes of selection: \f(CWsingle\fR and \f(CWmultiple\fR. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -selectmode "multiple" .CE You can be notified when the list of selected entries changes. The widget's \fB\-selectcommand\fR specifies a Tcl procedure that is called whenever the selection changes. .CS proc SelectNotify { widget } { set ids [\&$widget curselection] } \&.h configure -selectcommand "SelectNotify .h" .CE The widget supports the standard Tk scrolling and scanning operations. The \fBtreeview\fR can be both horizontally and vertically. You can attach scrollbars to the \fBtreeview\fR the same way as the listbox or canvas widgets. .CS scrollbar .xbar -orient horizontal -command ".h xview" scrollbar .ybar -orient vertical -command ".h yview" \&.h configure -xscrollcommand ".xbar set" \\ -yscrollcommand ".ybar set" .CE There are three different modes of scrolling: \f(CWlistbox\fR, \f(CWcanvas\fR, and \f(CWhierbox\fR. In \f(CWlistbox\fR mode, the last entry can always be scrolled to the top of the widget. In \f(CWhierbox\fR mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -scrollmode "listbox" .CE Entries can be programmatically opened or closed using the \fBopen\fR and \fBclose\fR operations respectively. .CS \&.h open $id \&.h close $id .CE When an entry is opened, a Tcl procedure can be automatically invoked. The \fB\-opencommand\fR option specifies this procedure. This procedure can lazily insert entries as needed. .CS proc AddEntries { dir } { eval .h insert end [glob -nocomplain $dir/*] } \&.h configure -opencommand "AddEntries %P" .CE Now when an entry is opened, the procedure \f(CWAddEntries\fR is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like \fBbind\fR) are performed. Above, \f(CW%P\fR is translated to the pathname of the entry. .PP The same feature exists when an entry is closed. The \fB\-closecommand\fR option specifies the procedure. .CS proc DeleteEntries { id } { .h entry delete $id 0 end } \&.h configure -closecommand "DeleteEntries %#" .CE When an entry is closed, the procedure \f(CWDeleteEntries\fR is called and deletes the entry's children using the \fBentry delete\fR operation (\f(CW%#\fR is the id of entry). .SH KEYWORDS treeview, widget �����������������������������������������������./saods9/blt3.0.1/man/Blt_TreeDeleteNode.man3�������������������������������������������������������0000644�0001750�0001750�00000005260�11462120062�017225� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeDeleteNode 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeDeleteNode \- Deletes a node and its descendants. .SH SYNOPSIS .nf #include <bltTree.h> .sp Blt_TreeNode \fBBlt_TreeDeleteNode\fR(\fItree\fR, \fInode\fR) .SH ARGUMENTS .AS Blt_TreeNode node .AP Blt_Tree tree in Tree containing the node. .AP Blt_TreeNode node in Node to be deleted. .BE .SH DESCRIPTION This procedure deletes a given node and all it descendants from a tree data object. .PP The arguments are as follows: .TP 1i \fItree\fR The tree containing the parent node. .TP \fInode\fR Node to be deleted. The node and its descendant nodes are deleted. Each node's data values are deleted also. The reference count of the Tcl_Obj is decremented. .PP Since all tree objects must contain at least a root node, the root node itself can't be deleted unless the tree is released and destroyed. Therefore you can clear a tree by deleting its root, but the root node will remain until the tree is destroyed. .SH RETURNS Always returns TCL_OK. Errors generated in a notification callbacks are backgrounded (see \fBTcl_TreeCreateNotifyHandler\fR). .SH EXAMPLE The following example deletes the root node. .CS Blt_TreeNode root; root = Blt_TreeRootNode(token); Blt_TreeDeleteNode(token, root); .CE .SH NOTIFICATIONS \fBBlt_TreeDeleteNode\fR can trigger tree notify events. You can be notified whenever a node is deleted by using the \fBBlt_TreeCreateNotifyHandler\fR. A callback routine is registered that will be automatically invoked whenever a node is deleted via \fBBlt_TreeDeleteNode\fR to the tree. .SH KEYWORDS tree, token ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Makefile.in�������������������������������������������������������������������0000644�0001750�0001750�00000003512�11462120062�015057� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for manual page files # ------------------------------------------------------------------------ prefix = @prefix@ mandir = @mandir@ manndir = $(mandir)/mann man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 srcdir = @srcdir@ datadir = @datadir@ datarootdir = @datarootdir@ version = @BLT_VERSION@ instdirs = $(man1dir) $(manndir) $(man3dir) MAN_N = BLT.n barchart.n beep.n bgexec.n bitmap.n \ bltdebug.n busy.n container.n cutbuffer.n \ dragdrop.n eps.n graph.n hierbox.n \ hiertable.n htext.n spline.n stripchart.n \ table.n tabset.n tile.n tree.n treeview.n vector.n \ watch.n winop.n MAN_3 = Blt_Tree.3 Blt_TreeGetNode.3 \ Blt_TreeCreate.3 Blt_TreeGetToken.3 \ Blt_TreeCreateNode.3 Blt_TreeName.3 \ Blt_TreeDeleteNode.3 Blt_TreeNodeId.3 \ Blt_TreeExists.3 Blt_TreeReleaseToken.3 MANPAGES = $(MAN_N) $(MAN_3) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ SHELL = /bin/sh RM = rm -rf MKDIR_P = @MKDIR_P@ VPATH = $(srcdir) all: man.macros $(MANPAGES) install: mkdirs install-mann install-man3 install-mann: $(MAN_N) for i in *.n ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(manndir); \ done install-man3: $(MAN_3) for i in *.3 ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(man3dir); \ done mkdirs: @for i in $(instdirs) ; do \ echo "$(MKDIR_P) $(DESTDIR)$$i" ; \ $(MKDIR_P) $(DESTDIR)$$i ; \ done .SUFFIXES: .n .mann .3 .man3 .man3.3: $(srcdir)/man.macros $(RM) $@ sed -e "/man\.macros/r $(srcdir)/man.macros" -e '/man\.macros/d' -e 's/BLT_VERSION/$(version)/' $< > $@ .mann.n: $(srcdir)/man.macros $(RM) $@ sed -e "/man\.macros/r $(srcdir)/man.macros" -e '/man\.macros/d' -e 's/BLT_VERSION/$(version)/' $< > $@ clean: $(RM) *.3 *.n distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeCreateNode.man3�������������������������������������������������������0000644�0001750�0001750�00000007030�11462120062�017223� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeCreateNode 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeCreateNode \- Creates a node in a tree data object. .SH SYNOPSIS .nf #include <bltTree.h> .sp Blt_TreeNode \fBBlt_TreeCreateNode\fR(\fItree\fR, \fIparent\fR, \fIname\fR, \fIposition\fR) .SH ARGUMENTS .AS Blt_TreeNode parent .AP Blt_Tree tree in Tree containing the parent node. .AP Blt_TreeNode parent in Node in which to insert the new child. .AP "const char" *name in Node label. If NULL, a label will automatically be generated. .AP int position in Position in the parent's list of children to insert the new node. .BE .SH DESCRIPTION .PP This procedure creates a new node is a tree data object. The node is initially empty, but data values can be added with \fBBlt_TreeSetValue\fR. Each node has a serial number that identifies it within the tree. No two nodes in the same tree will ever have the same ID. You can find a node's ID with \fBBlt_TreeNodeId\fR. .PP The arguments are as follows: .TP 1i \fItree\fR The tree containing the parent node. .TP \fIparent\fR Node in which the new child will be inserted. .TP \fIname\fR Label of the new node. If \fIname\fR is NULL, a label in the form "\f(CWnode0\fR", "\f(CWnode1\fR", etc. will automatically be generated. \fIName\fR can be any string. Labels are non-unique. A parent can contain two nodes with the same label. Nodes can be relabeled using \fBBlt_TreeRelabelNode\fR. .TP \fIposition\fR Position the parent's list of children to insert the new node. For example, if \fIposition\fR is 0, then the new node is prepended to the beginning of the list. If \fIposition\fR is -1, then the node is appended onto the end of the parent's list. .PP .SH RETURNS The new node returned is of type \fBBlt_TreeNode\fR. It's a token that can be used with other routines to add/delete data values or children nodes. .SH EXAMPLE The following example creates a new node from the root node. .CS Blt_Tree token; Blt_TreeNode root, node; if (Blt_TreeGetToken(interp, "myTree", &token) != TCL_OK) { return TCL_ERROR; } root = Blt_TreeRootNode(token); node = Blt_TreeCreateNode(token, root, "myNode", -1); .CE .SH NOTIFICATIONS \fBBlt_TreeCreateNode\fR can trigger tree notify events. You can be notified whenever a node is created by using the \fBBlt_TreeCreateNotifyHandler\fR. A callback routine is registered that will be automatically invoked whenever a new node is added via \fBBlt_TreeCreateNode\fR to the tree. .SH KEYWORDS tree, token ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/beep.mann���������������������������������������������������������������������0000644�0001750�0001750�00000003367�11462120062�014610� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" .so man.macros .TH beep n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME beep \- ring the bell .SH SYNOPSIS \fBbeep\fR ?\fIpercent\fR? .BE .SH DESCRIPTION The \fBbeep\fR command rings the keyboard bell. \fIPercent\fR is relative to the base volume of the keyboard bell and can range from -100 to 100 inclusive. .PP If \fIpercent\fR is nonnegative then the bell volume is: .CS base - [(base * \fIpercent\fR) / 100] + \fIpercent\fR .CE If \fIpercent\fR is negative then the bell volume is: .CS C base + [(base * \fIpercent\fR) / 100] .CE The default \fIpercent\fR is 50. .SH EXAMPLE .CS beep .CE .SH KEYWORDS bell, beep �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/winop.mann��������������������������������������������������������������������0000644�0001750�0001750�00000012031�11462120062�015015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Window command created by George Howlett. '\" .so man.macros .TH winop n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME winop \- Perform assorted window operations .SH SYNOPSIS \fBwinop lower\fR ?\fIwindow\fR?... .sp \fBwinop map\fR ?\fIwindow\fR?... .sp \fBwinop move \fIwindow x y\fR .sp \fBwinop raise\fR ?\fIwindow\fR?... .sp \fBwinop snap \fIwindow photoName\fR .sp \fBwinop unmap\fR ?\fIwindow\fR?... .sp \fBwinop warpto\fR ?\fIwindow\fR? .BE .SH DESCRIPTION The \fBwinop\fR command performs various window operations on Tk windows using low-level Xlib function calls to work around window manager pecularities. .SH INTRODUCTION Tk has several commands for manipulating its windows: \fBraise\fR, \fBlower\fR, \fBwm\fR, etc. These commands ask the window manager to perform operations on Tk windows. In some cases, a particular window manager won't perform the operation as expected. .PP For example, if you positioned a toplevel window using \fBwm geometry\fR, the window may not actually be at those particular coordinates. The position of the window may be offset by dimensions of the title bar added by the window manager. .PP In situations like these, the \fBwinop\fR command can be used to workaround these difficulties. Instead, it makes low-level Xlib (such \fBXRaiseWindow\fR and \fBXMapWindow\fR) calls to perform these operations. .CS toplevel .top wm withdraw .top # Set the geometry to make the window manager # place the window. wm geometry .top +100+100 # Move the window to the desired location # and "update" to force the window manager # to recognize it. winop move .top 100 100 update wm deiconify .top winop move .top 100 100 .CE .SH OPERATIONS The following operations are available for the \fBwinop\fR command: .TP \fBwinop lower\fR ?\fIwindow\fR?... Lowers \fIwindow\fR to the bottom of the X window stack. \fIWindow\fR is the path name of a Tk window. .TP \fBwinop map\fR ?\fIwindow\fR?... Maps \fIwindow\fR on the screen. \fIWindow\fR is the path name of a Tk window. If \fIwindow\fR is already mapped, this command has no effect. .TP \fBwinop move \fIwindow x y\fR Move \fIwindow\fR to the screen location specified by \fIx\fR and \fIy\fR. \fIWindow\fR is the path name of a Tk window, while \fIx\fR and \fIy\fR are screen coordinates. This command returns the empty string. .TP \fBwinop raise\fR ?\fIwindow\fR?... Raises \fIwindow\fR to the top of the X window stack. \fIWindow\fR must be a valid path name of a Tk window. This command returns the empty string. .TP \fBwinop snap \fIwindow photoName\fR Takes a snapshot of the \fIwindow\fR and stores the contents in the photo image \fIphotoName\fR. \fIWindow\fR is the valid path name of a Tk window which must be totally visible (unobscured). \fIPhotoName\fR is the name of a Tk photo image which must already exist. This command can fail if the window is obscured in any fashion, such as covered by another window or partially offscreen. In that case, an error message is returned. .TP \fBwinop unmap\fR ?\fIwindow\fR?... Unmaps \fIwindow\fR from the screen. \fIWindow\fR is the path name of a Tk window. .TP \fBwinop warpto\fR ?\fIwindow\fR? Warps the pointer to \fIwindow\fR. \fIWindow\fR is the path name of a Tk window which must be mapped. If \fIwindow\fR is in the form \fI@x,y\fR, where \fIx\fR and \fIy\fR are root screen coordinates, the pointer is warped to that location on the screen. .sp [\fII've never heard a good case for warping the pointer in an application. It can be useful for testing, but in applications, it's always a bad idea. Simply stated, the user owns the pointer, not the application. If you have an application that needs it, I'd like to hear about it.\fR] .sp If no \fIwindow\fR argument is present the current location of the pointer is returned. The location is returned as a list in the form "\fIx y\fR", where \fIx\fR and \fIy\fR are the current coordinates of the pointer. .SH KEYWORDS window, map, raise, lower, pointer, warp �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/bltdebug.mann�����������������������������������������������������������������0000644�0001750�0001750�00000003424�11462120062�015457� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" .so man.macros .TH bltdebug n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME bltdebug \- print Tcl commands before execution .SH SYNOPSIS \fBbltdebug\fR ?\fIlevel\fR? .BE .SH DESCRIPTION The \fBbltdebug\fR command is a simple tracing facility for Tcl commands. Each command line is printed before it is executed on standard error. The output consists of the command line both before and after substitutions have occurred. \fILevel\fR indicates at what level to stop tracing commands. If \fIlevel\fR is \f(CW0\fR, no tracing is performed. This is the default. If no \fIlevel\fR argument is given, the current level is printed. .SH KEYWORDS debug ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/table.mann��������������������������������������������������������������������0000644�0001750�0001750�00000071617�11462120062�014767� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" The table geometry manager created by George Howlett. '\" .so man.macros .TH table n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME table \- Arranges widgets in a table .SH SYNOPSIS \fBtable \fIcontainer\fR ?\fIwidget index option value\fR?... .sp \fBtable arrange\fR \fIcontainer\fR .sp \fBtable cget \fIcontainer\fR ?\fIitem\fR? \fIoption\fR .sp \fBtable configure \fIcontainer\fR ?\fIitem\fR?... ?\fIoption value\fR?... .sp \fBtable extents \fIcontainer\fR \fIitem\fR .sp \fBtable forget \fIwidget\fR ?\fIwidget\fR?... .sp \fBtable info \fIcontainer\fR \fIitem\fR .sp \fBtable locate \fIcontainer\fR \fIx y\fR .sp \fBtable containers \fR?\fIswitch\fR? ?\fIarg\fR? .sp \fBtable save \fIcontainer\fR .sp \fBtable search \fIcontainer\fR ?\fIswitch arg\fR?... .BE .SH DESCRIPTION The \fBtable\fR command arranges widgets in a table. The alignment of widgets is detemined by their row and column positions and the number of rows or columns that they span. .SH INTRODUCTION Probably the most painstaking aspect of building a graphical application is getting the placement and size of the widgets just right. It usually takes many iterations to align widgets and adjust their spacing. That's because managing the geometry of widgets is simply not a packing problem, but also graphical design problem. Attributes such as alignment, symmetry, and balance are more important than minimizing the amount of space used for packing. .PP The \fBtable\fR geometry manager arranges widgets in a table. It's easy to align widgets (horizontally and vertically) or to create empty space to balance the arrangement of the widgets. Widgets (called \fIslaves\fR in the Tk parlance) are arranged inside a containing widget (called the \fImaster\fR). Widgets are positioned at row,column locations and may span any number of rows or columns. More than one widget can occupy a single location. .PP The placement of widget windows determines both the size and arrangement of the table. The table queries the requested size of each widget. The \fIrequested size\fR of a widget is the natural size of the widget (before the widget is shrunk or expanded). The height of each row and the width of each column is the largest widget spanning that row or column. The size of the table is in turn the sum of the row and column sizes. This is the table's \fInormal size\fR. .PP The total number of rows and columns in a table is determined from the indices specified. The table grows dynamically as windows are added at larger indices. .SH EXAMPLE The table geometry manager is created by invoking the \fBtable\fR command. .CS # Create a table in the root window table . .CE The window \f(CW.\fR is now the \fIcontainer\fR of the table. Widgets are packed into the table and displayed within the confines of the container. .PP You add widgets to the table by row and column location. Row and column indices start from zero. .CS label .title -text "This is a title" # Add a label to the table table . .title 0,0 .CE The label \f(CW.title\fR is added to the table. We can add more widgets in the same way. .CS button .ok -text "Ok" button .cancel -text "Cancel" # Add two buttons table . .ok 1,0 table . .cancel 1,1 .CE Two buttons \f(CW.ok\fR and \f(CW.cancel\fR are now packed into the second row of the table. They each occupy one cell of the table. By default, widgets span only a single row and column. .PP The first column contains two widgets, \f(CW.title\fR and \f(CW.ok\fR. By default, the widest of the two widgets will define the width of the column. However, we want \f(CW.title\fR to be centered horizontally along the top of the table. We can make \f(CW.title\fR span two columns using the \fBconfigure\fR operation. .CS # Make the label span both columns table configure . .title -cspan 2 .CE The label \f(CW.title\fR will now be centered along the top row of the table. .PP In the above example, we've create and arranged the layout for the table invoking the \fBtable\fR command several times. Alternately, we could have used a single \fBtable\fR command. .CS label .title -text "This is a title" button .ok -text "Ok" button .cancel -text "Cancel" # Create and pack the table table . \\ .title 0,0 -cspan 2 \\ .ok 1,0 \\ .cancel 1,1 .CE The table will override the requested width and height of the container so that the window fits the table exactly. This also means that any change to the size of table will be propagated up through the Tk window hierarchy. This feature can be turned off using the \fBconfigure\fR operation again. .CS table configure . -propagate no .CE You can also set the width of height of the table to a specific value. This supersedes the calculated table size. .CS # Make the container 4 inches wide, 3 inches high table configure . -reqwidth 4i -reqheight 3i .CE If a widget is smaller than the cell(s) it occupies, the widget will float within the extra space. By default, the widget will be centered within the space, but you can anchor the widget to any side of cell using the \fB\-anchor\fR configuration option. .CS table configure . .ok -anchor w .CE The \fB\-fill\fR option expands the widget to fill the extra space either vertically or horizontally (or both). .CS # Make the title label fill the entire top row table configure . .title -cspan 2 -fill x # Each button will be as height of the 2nd row. table configure . .ok .cancel -fill y .CE The width of \f(CW.title\fR will be the combined widths of both columns. Both \f(CW.ok\fR and \f(CW.cancel\fR will become as tall as the second row. .PP The \fB\-padx\fR and \fB\-pady\fR options control the amount of padding around the widget. Both options take a list of one or two values. .CS # Pad the title by two pixels above and below. table configure . .title -pady 2 # Pad each button 2 pixels on the left, and 4 on the right. table configure . .ok .cancel -padx { 2 4 } .CE If the list has only one value, then both exterior sides (top and bottom or left and right) of the widget are padded by that amount. If the list has two elements, the first specifies padding for the top or left side and the second for the bottom or right side. .PP Like the container, you can also override the requested widths and heights of widgets using the \fB\-reqwidth\fR and \fB\-reqheight\fR options. This is especially useful with character-based widgets (such as buttons, labels, text, listbox, etc) that let you specify their size only in units of characters and lines, instead of pixels. .CS # Make all buttons one inch wide table configure . .ok .cancel -reqwidth 1i .CE .PP Each row and column of the table can be configured, again using the \fBconfigure\fR operation. Rows are and columns are designated by \f(CWR\fIi\fR and \f(CWC\fIi\fR respectively, where \fIi\fR is the index of the row or column. .PP For example, you can set the size of a row or column. .CS # Make the 1st column 2 inches wide table configure . c0 -width 2.0i # Make the 2nd row 1/2 inch high. table configure . r1 -height 0.5i .CE The new size for the row or column overrides its calculated size. If no widgets span the row or column, its height or width is zero. So you can use the \fB\-width\fR and \fB\-height\fR options to create empty spaces in the table. .CS # Create an empty row and column table configure . r2 c2 -width 1i .CE The \fB\-pady\fR option lets you add padding to the top and bottom sides of rows. The \fB\-padx\fR option adds padding to the left and right sides of columns. Both options take a list of one or two values. .CS # Pad above the title by two pixels table configure . r0 -pady { 2 0 } # Pad each column 4 pixels on the left, and 2 on the right. table configure . c* -padx { 2 4 } .CE .PP Notice that you can configure all the rows and columns using either \f(CWR*\fR or \f(CWC*\fR. .PP When the container is resized, the rows and columns of the table are also resized. Only the rows or columns that contain widgets (a widget spans the row or column) grow or shrink. The \fB\-resize\fR option indicates whether the row or column can be shrunk or stretched. If the value is \f(CWshrink\fR, the row or column can only be resized smaller. If \f(CWexpand\fR, it can only be resized larger. If \f(CWnone\fR, the row or column is frozen at its requested size. .CS # Let the 1st column get smaller, but not bigger table configure . c0 -resize shrink # Let the 2nd column get bigger, not smaller table configure . c1 -resize expand # Don't resize the first row table configure . r0 -resize none .CE The following example packs a canvas, two scrollbars, and a title. The rows and columns containing the scrollbars are frozen at their requested size, so that even if the frame is resized, the scrollbars will remain the same width. .CS table . \\ .title 0,0 -cspan 3 \\ .canvas 1,1 -fill both \\ .vscroll 1,2 -fill y \\ .hscroll 2,1 -fill x # Don't let the scrollbars resize table configure . c2 r2 -resize none # Create an empty space to balance the scrollbar table configure . c0 -width .vscroll .CE Note that the value of the \fB\-width\fR option is the name of a widget window. This indicates that the width of the column should be the same as the requested width of \f(CW.vscroll\fR. .PP Finally, the \fBforget\fR operation removes widgets from the table. .CS # Remove the windows from the table table forget .quit .frame .CE It's not necessary to specify the container. The \fBtable\fR command determines the container from the widget name. .SH OPERATIONS The following operations are available for the \fBtable\fR: .TP \fBtable \fIcontainer\fR ?\fIwidget index option value\fR?... Adds the widget \fIwidget\fR to the table at \fIindex\fR. \fIIndex\fR is a row,column position in the table. It must be in the form \fIrow\fR,\fIcolumn\fR where \fIrow\fR and \fIcolumn\fR are the respective row and column numbers, starting from zero (0,0 is the upper leftmost position). \fIRow\fR and \fIcolumn\fR may also be numeric expressions that are recursively evaluated. If a table doesn't exist for \fIcontainer\fR, one is created. \fIWidget\fR is the path name of the window, that must already exist, to be arranged inside of \fIcontainer\fR. \fIOption\fR and \fIvalue\fR are described in the .SB WIDGET OPTIONS section. .TP \fBtable arrange\fR \fIcontainer\fR Forces the table to compute its layout immediately. Normally, the table geometry manager will wait until the next idle point, before calculating the size of its rows and columns. This is useful for collecting the \fInormal\fR sizes of rows and columns, that are based upon the requested widget sizes. .TP \fBtable cget\fR \fIcontainer \fR?\fIitem\fR?\fI option\fR Returns the current value of the configuration option specific to \fIitem\fR given by \fIoption\fR. \fIItem\fR is either a row or column index, or the path name of a widget. \fIItem\fR can be in any form describe in the \fBconfigure\fR operation below. If no \fIitem\fR argument is provided, then the configuration option is for the table itself. \fIOption\fR may be any one of the options described in the appropiate section for \fIitem\fR. .TP \fBtable configure\fR \fIcontainer item\fR... ?\fIoption value\fR?... Queries or modifies the configuration options specific to \fIitem\fR. If no \fIoption\fR is specified, this command returns a list describing all of the available options for \fIitem\fR If the argument \fIitem\fR is omitted, then the specified configuration options are for the table itself. Otherwise \fIitem\fR must be either a row or column specification, or the path name of a widget. The following \fIitem\fR types are available. .RS .TP \f(CWC\fIi\fR Specifies the column of \fIcontainer\fR to be configured. \fIItem\fR must be in the form \f(CWC\fIn\fR, where \fIi\fR is the index of the column. See the .SB COLUMN OPTIONS section. .TP \f(CWR\fIi\fR Specifies the row of \fIcontainer\fR to be configured. \fIItem\fR must be in the form \f(CWR\fIi\fR, where \fIi\fR is the index of the row. See the .SB ROW OPTIONS section. .TP \fIwidget\fR Specifies a widget of \fIcontainer\fR to be queried. \fIWidget\fR is the path name of a widget packed in \fIcontainer\fR. See the .SB WIDGET OPTIONS section. .TP No argument Specifies that the table itself is to be queried. See the .SB TABLE OPTIONS section for a description of the option-value pairs for the table. .RE .RS .sp The \fIoption\fI and \fIvalue\fR pairs are specific to \fIitem\fR. If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given option(s) to have the given value(s); in this case the command returns the empty string. .RE .TP \fBtable extents \fIcontainer\fR \fIindex\fR Queries the location and dimensions of row and columns in the table. \fIIndex\fR can be either a row or column index or a table index. Returns a list of the x,y coordinates (upperleft corner) and dimensions (width and height) of the cell, row, or column. .TP \fBtable forget \fIwidget\fR ?\fIwidget\fR?... Requests that \fIwidget\fR no longer have its geometry managed. \fIWidget\fR is the pathname of the window currently managed by some table. The window will be unmapped so that it no longer appears on the screen. If \fIwidget\fR is not currently managed by any table, an error message is returned, otherwise the empty string. .TP \fBtable info \fIcontainer\fR \fIitem\fR Returns a list of the current configuration options for \fIitem\fR. The list returned is exactly in the form that might be specified to the \fBtable\fR command. It can be used to save and reset table configurations. \fIItem\fR must be one of the following. .RS .TP .75i \f(CWC\fIi\fR Specifies the column of \fIcontainer\fR to be queried. \fIItem\fR must be in the form \f(CWC\fIn\fR, where \fIn\fR is the index of the column. .TP \f(CWR\fIi\fR Specifies the row of \fIcontainer\fR to be queried. \fIItem\fR must be in the form \f(CWR\fIi\fR, where \fIi\fR is the index of the row. .TP \fIwidget\fR Specifies a widget of \fIcontainer\fR to be queried. \fIWidget\fR is the path name of a widget packed in \fIcontainer\fR. .TP No argument Specifies that the table itself is to be queried. .RE .TP \fBtable locate \fIcontainer\fR \fIx y\fR Returns the table index (row,column) of the cell containing the given screen coordinates. The \fIx\fR and \fIy\fR arguments represent the x and y coordinates of the sample point to be tested. .TP \fBtable containers \fR?\fIswitch arg\fR? Returns a list of all container windows matching a given criteria (using \fIswitch\fR and \fIarg\fR). If no \fIswitch\fR and \fIarg\fR arguments are given, the names of all container windows (only those using the \fBtable\fR command) are returned. The following are valid switches: .RS .TP \fB\-pattern\fR \fIpattern\fR Returns a list of pathnames of all container windows matching \fIpattern\fR. .TP \fB\-slave\fR \fIwindow\fR Returns the name of the container window of table managing \fIwindow\fR. \fIWindow\fR must be the path name of widget. If \fIwindow\fR is not managed by any table, the empty string is returned. .RE .TP \fBtable search \fIcontainer\fR ?\fIswitch arg\fR?... Returns the names of all the widgets in \fIcontainer\fR matching the criteria given by \fIswitch\fR and \fIarg\fR. \fIContainer\fR is name of the container window associated with the table to be searched. The name of the widget is returned if any one \fIswitch\fR-\fIarg\fR criteria matches. If no \fIswitch\fR-\fIarg\fR arguments are given, the names of all widgets managed by \fIcontainer\fR are returned. The following are switches are available: .RS .TP \fB\-pattern\fR \fIpattern\fR Returns the names of any names of the widgets matching \fIpattern\fR. .TP \fB\-span\fR \fIindex\fR Returns the names of widgets that span \fIindex\fR. A widget does not need to start at \fIindex\fR to be included. \fIIndex\fR must be in the form \fIrow\fR,\fIcolumn\fR, where \fIrow\fR and \fIcolumn\fR are valid row and column numbers. .TP \fB\-start\fR \fIindex\fR Returns the names of widgets that start at \fIindex\fR. \fIIndex\fR must be in the form \fIrow\fR,\fIcolumn\fR, where \fIrow\fR and \fIcolumn\fR are valid row and column numbers. .RE .SH TABLE OPTIONS To configure the table itself, you omit the \fIitem\fR argument when invoking the \fBconfigure\fR operation. .CS \fBtable configure\fR \fIcontainer\fR ?\fIoption value\fR?... .CE The following options are available for the table: .RS .TP \fB\-padx \fIpad\fR Sets how much padding to add to the left and right exteriors of the table. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the left side of the table is padded by the first value and the right side by the second value. If \fIpad\fR has just one value, both the left and right sides are padded evenly by the value. The default is \f(CW0\fR. .TP \fB\-pady \fIpad\fR Sets how much padding to add to the top and bottom exteriors of the table. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the area above the table is padded by the first value and the area below by the second value. If \fIpad\fR is just one number, both the top and bottom areas are padded by the value. The default is \f(CW0\fR. .TP \fB\-propagate \fIboolean\fR Indicates if the table should override the requested width and height of the \fIcontainer\fR window. If \fIboolean\fR is false, \fIcontainer\fR will not be resized. \fIContainer\fR will be its requested size. The default is \f(CW1\fR. .RE .SH WIDGET OPTIONS widgets are configured by specifying the name of the widget when invoking the \fBconfigure\fR operation. .DS \fBtable configure\fR \fIcontainer \fIwidget\fR ?\fIoption value\fR?... .DE \fIWidget\fR must be the path name of a window already packed in the table associated with \fIcontainer\fR. The following options are available for widgets: .RS .TP \fB\-anchor \fIanchor\fR Anchors \fIwidget\fR to a particular edge of the cell(s) it resides. This option has effect only if the space of the spans surrounding \fIwidget\fR is larger than \fIwidget\fR. \fIAnchor\fR specifies how \fIwidget\fR will be positioned in the space. For example, if \fIanchor\fR is \f(CWcenter\fR then the window is centered in the rows and columns it spans; if \fIanchor\fR is \f(CWw\fR then the window will be aligned with the leftmost edge of the span. The default is \f(CWcenter\fR. .TP \fB\-columnspan \fInumber\fR Sets the number of columns \fIwidget\fR will span. The default is \f(CW1\fR. .TP \fB\-columncontrol \fIcontrol\fR Specifies how the width of \fIwidget\fR should control the width of the columns it spans. \fIControl\fR is either \f(CWnormal\fR, \f(CWnone\fR, or \f(CWfull\fR. The default is \f(CWnormal\fR. .RS .TP 1i \f(CWnone\fR The width of \fIwidget\fR is not considered. .TP 1i \f(CWfull\fR Only the width of \fIwidget\fR will be considered when computing the widths of the columns. .TP 1i \f(CWnormal\fR Indicates that the widest widget spanning the column will determine the width of the span. .RE .TP \fB\-fill \fIfill\fR Specifies if \fIwidget\fR should be stretched to fill any free space in the span surrounding \fIwidget\fR. \fIFill\fR is either \f(CWnone\fR, \f(CWx\fR, \f(CWy\fR, \f(CWboth\fR. The default is \f(CWnone\fR. .RS .TP 1i \f(CWx\fR The widget can grow horizontally. .TP 1i \f(CWy\fR The widget can grow vertically. .TP 1i \f(CWboth\fR The widget can grow both vertically and horizontally. .TP 1i \f(CWnone\fR The widget does not grow along with the span. .RE .TP \fB\-ipadx \fIpixels\fR Sets how much horizontal padding to add internally on the left and right sides of \fIwidget\fR. \fIPixels\fR must be a valid screen distance like \f(CW2\fR or \f(CW0.3i\fR. The default is \f(CW0\fR. .TP \fB\-ipady \fIpixels\fR Sets how much vertical padding to add internally on the top and bottom of \fIwidget\fR. \fIPixels\fR must be a valid screen distance like \f(CW2\fR or \f(CW0.3i\fR. The default is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets how much padding to add to the left and right exteriors of \fIwidget\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the left side of \fIwidget\fR is padded by the first value and the right side by the second value. If \fIpad\fR has just one value, both the left and right sides are padded evenly by the value. The default is \f(CW0\fR. .TP \fB\-pady \fIpad\fR Sets how much padding to add to the top and bottom exteriors of \fIwidget\fR. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the area above \fIwidget\fR is padded by the first value and the area below by the second value. If \fIpad\fR is just one number, both the top and bottom areas are padded by the value. The default is \f(CW0\fR. .TP \fB\-reqheight \fIheight\fR Specifies the limits of the requested height for \fIwidget\fR. \fIHeight\fR is a list of bounding values. See the .SB BOUNDING SIZES section for a description of this list. By default, the height of \fIwidget\fR is its requested height with its internal padding (see the \fB\-ipady\fR option). The bounds specified by \fIheight\fR either override the height completely, or bound the height between two sizes. The default is \f(CW""\fR. .TP \fB\-reqwidth \fIwidth\fR Specifies the limits of the requested width for \fIwidget\fR. \fIWidth\fR is a list of bounding values. See the .SB BOUNDING SIZES section for a description of this list. By default, the width of \fIwidget\fR is its requested width with its internal padding (set the \fB\-ipadx\fR option). The bounds specified by \fIwidth\fR either override the width completely, or bound the height between two sizes. The default is \f(CW""\fR. .TP \fB\-rowspan \fInumber\fR Sets the number of rows \fIwidget\fR will span. The default is \f(CW1\fR. .TP \fB\-rowcontrol \fIcontrol\fR Specifies how the height of \fIwidget\fR should control the height of the rows it spans. \fIControl\fR is either \f(CWnormal\fR, \f(CWnone\fR, or \f(CWfull\fR. The default is \f(CWnormal\fR. .RS .TP 1i \f(CWnone\fR The height of \fIwidget\fR is not considered. .TP 1i \f(CWfull\fR Only the height of \fIwidget\fR will be considered when computing the heights of the rows. .TP 1i \f(CWnormal\fR Indicates that the tallest widget spanning the row will determine the height of the span. .RE .RE .SH COLUMN OPTIONS To configure a column in the table, specify the column index as \f(CWC\fIi\fR, where \fIi\fR is the index of the column to be configured. .DS \fBtable configure\fR \fIcontainer \f(CWC\fIi\fR ?\fIoption value\fR?... .DE If the index is specified as \f(CWC*\fR, then all columns of the table will be configured. The following options are available for table columns. .RS .TP \fB\-padx \fIpad\fR Sets the padding to the left and right of the column. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the left side of the column is padded by the first value and the right side by the second value. If \fIpad\fR has just one value, both the left and right sides are padded evenly by the value. The default is \f(CW0\fR. .TP \fB\-resize \fImode\fR Indicates that the column can expand or shrink from its requested width when the table is resized. \fIMode\fR must be one of the following: \f(CWnone\fR, \f(CWexpand\fR, \f(CWshrink\fR, or \f(CWboth\fR. If \fImode\fR is \f(CWexpand\fR the width of the column is expanded if there is extra space in the container window. If \fImode\fR is \f(CWshrink\fR its width may be reduced beyond its requested width if there is not enough space in the container. The default is \f(CWnone\fR. .TP \fB\-width \fIwidth\fR Specifies the limits within that the width of the column may expand or shrink. \fIWidth\fR is a list of bounding values. See the section .SB BOUNDING SIZES for a description of this list. By default there are no constraints. .RE .SH ROW OPTIONS To configure a row in the table, specify the row index as \f(CWR\fIi\fR, where \fIi\fR is the index of the row to be configured. .DS \fBtable configure\fR \fIcontainer \f(CWR\fIi\fR ?\fIoption value\fR?... .DE If the index is specified as \f(CWR*\fR, then all rows of the table will be configured. The following options are available for table rows. .RS .TP \fB\-height \fIheight\fR Specifies the limits of the height that the row may expand or shrink to. \fIHeight\fR is a list of bounding values. See the section .SB BOUNDING SIZES for a description of this list. By default there are no constraints. .TP \fB\-pady \fIpad\fR Sets the padding above and below the row. \fIPad\fR can be a list of one or two numbers. If \fIpad\fR has two elements, the area above the row is padded by the first value and the area below by the second value. If \fIpad\fR is just one number, both the top and bottom areas are padded by the value. The default is \f(CW0\fR. .TP \fB\-resize \fImode\fR Indicates that the row can expand or shrink from its requested height when the table is resized. \fIMode\fR must be one of the following: \f(CWnone\fR, \f(CWexpand\fR, \f(CWshrink\fR, or \f(CWboth\fR. If \fImode\fR is \f(CWexpand\fR the height of the row is expanded if there is extra space in the container. If \fImode\fR is \f(CWshrink\fR its height may be reduced beyond its requested height if there is not enough space in the container. The default is \f(CWnone\fR. .RE .SH BOUNDING SIZES Sometimes it's more useful to limit resizes to an acceptable range, than to fix the size to a particular value or disallow resizing altogether. Similar to the way the \fBwm\fR command lets you specify a \fBminsize\fR and \fBmaxsize\fR for a toplevel window, you can bound the sizes the container, a widget, row, or column may take. The \fB\-width\fR, \fB\-height\fR, \fB\-reqwidth\fR, and \fB\-reqheight\fR options, take a list of one, two, or three values. We can take a previous example and instead preventing resizing, bound the size of the scrollbars between two values. .CS table . \\ .title 0,0 -cspan 3 \\ .canvas 1,1 -fill both \\ .vscroll 1,2 -fill y \\ .hscroll 2,1 -fill x # Bound the scrollbars between 1/8 and 1/2 inch table configure . c2 -width { 0.125 0.5 } table configure . r2 -height { 0.125 0.5 } table configure . vscroll .hscroll -fill both .CE The scrollbars will get no smaller than 1/8 of an inch, or bigger than 1/2 inch. The initial size will be their requested size, so long as it is within the specified bounds. .PP How the elements of the list are interpreted is dependent upon the number of elements in the list. .RS .TP 1i {\fI\fR} Empty list. No bounds are set. The default sizing is performed. .TP {\fI x \fR} Fixes the size to \fIx\fR. The window or partition cannot grow or shrink. .TP {\fI min max \fR} Sets up minimum and maximum limits for the size of the window or partition. The window or partition can be reduced less than \fImin\fR, nor can it be stretched beyond \fImax\fR. .TP {\fI min max nom \fR} Specifies minimum and maximum size limits, but also specifies a nominal size \fInom\fR. This overrides the calculated size of the window or partition. .RE .SH MISCELLANEOUS Another feature is that you can put two widgets in the same cell of the table. This is useful when you want to add decorations around a widget. .CS frame .frame -bd 1 -relief sunken button .quit -text "Quit" # Put both the frame and the button in the same cell. table . \\ .quit 1,0 -padx 2 -pady 2 \\ .frame 1,0 -fill both .CE .SH LIMITATIONS A long standing bug in Tk (circa 1993), there is no way to detect if a window is already a container of a different geometry manager. This is usually done by accident, such as the following where all three widgets are arranged in the same container ".", but using different geometry managers. .CS table .f1 ... pack .f2 ... grid .f3 .CE This leads to bizarre window resizing, as each geometry manager applies its own brand of layout policies. When the container is a top level window (such as "."), your window manager may become locked as it responds to the never-ending stream of resize requests. .SH KEYWORDS frame, geometry manager, location, table, size �����������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/graph.mann��������������������������������������������������������������������0000644�0001750�0001750�00000311201�11462120062�014763� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Graph widget created by Sani Nassif and George Howlett. '\" .so man.macros .TH graph n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME graph \- 2D graph for plotting X\-Y coordinate data. .SH SYNOPSIS \fBgraph\fI \fIpathName \fR?\fIoption value\fR?... .BE .SH DESCRIPTION The \fBgraph\fR command creates a graph for plotting two-dimensional data (X\-Y coordinates). It has many configurable components: coordinate axes, elements, legend, grid lines, cross hairs, etc. They allow you to customize the look and feel of the graph. .SH INTRODUCTION The \fBgraph\fR command creates a new window for plotting two-dimensional data (X\-Y coordinates). Data points are plotted in a rectangular area displayed in the center of the new window. This is the \fIplotting area\fR. The coordinate axes are drawn in the margins around the plotting area. By default, the legend is displayed in the right margin. The title is displayed in top margin. .PP The \fBgraph\fR widget is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, pens, postscript, and annotation markers. .TP 1i \f(CWaxis\fR The graph has four standard axes (\f(CWx\fR, \f(CWx2\fR, \f(CWy\fR, and \f(CWy2\fR), but you can create and display any number of axes. Axes control what region of data is displayed and how the data is scaled. Each axis consists of the axis line, title, major and minor ticks, and tick labels. Tick labels display the value at each major tick. .TP 1i \f(CWcrosshairs\fR Cross hairs are used to position the mouse pointer relative to the X and Y coordinate axes. Two perpendicular lines, intersecting at the current location of the mouse, extend across the plotting area to the coordinate axes. .TP 1i \f(CWelement\fR An element represents a set of data points. Elements can be plotted with a symbol at each data point and lines connecting the points. The appearance of the element, such as its symbol, line width, and color is configurable. .TP 1i \f(CWgrid\fR Extends the major and minor ticks of the X\-axis and/or Y\-axis across the plotting area. .TP 1i \f(CWlegend\fR The legend displays the name and symbol of each data element. The legend can be drawn in any margin or in the plotting area. .TP 1i \f(CWmarker\fR Markers are used annotate or highlight areas of the graph. For example, you could use a polygon marker to fill an area under a curve, or a text marker to label a particular data point. Markers come in various forms: text strings, bitmaps, connected line segments, images, polygons, or embedded widgets. .TP 1i \f(CWpen\fR Pens define attributes (both symbol and line style) for elements. Data elements use pens to specify how they should be drawn. A data element may use many pens at once. Here, the particular pen used for a data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .TP 1i \f(CWpostscript\fR The widget can generate encapsulated PostScript output. This component has several options to configure how the PostScript is generated. .SH SYNTAX .DS \fBgraph \fIpathName \fR?\fIoption value\fR?... .DE The \fBgraph\fR command creates a new window \fIpathName\fR and makes it into a \fBgraph\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the graph such as its colors and font. See the \fBconfigure\fR operation below for the exact details about what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBgraph\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the graph. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for the graph are described in the .SB "GRAPH OPERATIONS" section. .PP The command can also be used to access components of the graph. .DS \fIpathName component operation\fR ?\fIarg\fR?... .DE The operation, now located after the name of the component, is the function to be performed on that component. Each component has its own set of operations that manipulate that component. They will be described below in their own sections. .SH EXAMPLE The \fBgraph\fR command creates a new graph. .CS # Create a new graph. Plotting area is black. graph .g \-plotbackground black .CE A new Tcl command \f(CW.g\fR is also created. This command can be used to query and modify the graph. For example, to change the title of the graph to "My Plot", you use the new command and the graph's \fBconfigure\fR operation. .CS # Change the title. \&.g configure \-title "My Plot" .CE A graph has several components. To access a particular component you use the component's name. For example, to add data elements, you use the new command and the \fBelement\fR component. .CS # Create a new element named "line1" \&.g element create line1 \\ \-xdata { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } \\ \-ydata { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } .CE The element's X-Y coordinates are specified using lists of numbers. Alternately, BLT vectors could be used to hold the X\-Y coordinates. .CS # Create two vectors and add them to the graph. vector xVec yVec xVec set { 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 } yVec set { 26.18 50.46 72.85 93.31 111.86 128.47 143.14 155.85 166.60 175.38 } \&.g element create line1 \-xdata xVec \-ydata yVec .CE The advantage of using vectors is that when you modify one, the graph is automatically redrawn to reflect the new values. .CS # Change the y coordinate of the first point. set yVector(0) 25.18 .CE An element named \f(CWe1\fR is now created in \f(CW.b\fR. It is automatically added to the display list of elements. You can use this list to control in what order elements are displayed. To query or reset the element display list, you use the element's \fBshow\fR operation. .CS # Get the current display list set elemList [.b element show] # Remove the first element so it won't be displayed. \&.b element show [lrange $elemList 0 end] .CE The element will be displayed by as many bars as there are data points (in this case there are ten). The bars will be drawn centered at the x-coordinate of the data point. All the bars will have the same attributes (colors, stipple, etc). The width of each bar is by default one unit. You can change this with using the \fB\-barwidth\fR option. .CS # Change the X\-Y coordinates of the first point. set xVec(0) 0.18 set yVec(0) 25.18 .CE An element named \f(CWline1\fR is now created in \f(CW.g\fR. By default, the element's label in the legend will be also \f(CWline1\fR. You can change the label, or specify no legend entry, again using the element's \fBconfigure\fR operation. .CS # Don't display "line1" in the legend. \&.g element configure line1 \-label "" .CE You can configure more than just the element's label. An element has many attributes such as symbol type and size, dashed or solid lines, colors, line width, etc. .CS \&.g element configure line1 \-symbol square \-color red \\ \-dashes { 2 4 2 } \-linewidth 2 \-pixels 2c .CE Four coordinate axes are automatically created: \f(CWx\fR, \f(CWx2\fR, \f(CWy\fR, and \f(CWy2\fR. And by default, elements are mapped onto the axes \f(CWx\fR and \f(CWy\fR. This can be changed with the \fB\-mapx\fR and \fB\-mapy\fR options. .CS # Map "line1" on the alternate Y\-axis "y2". \&.g element configure line1 \-mapy y2 .CE Axes can be configured in many ways too. For example, you change the scale of the Y\-axis from linear to log using the \fBaxis\fR component. .CS # Y\-axis is log scale. \&.g axis configure y \-logscale yes .CE One important way axes are used is to zoom in on a particular data region. Zooming is done by simply specifying new axis limits using the \fB\-min\fR and \fB\-max\fR configuration options. .CS \&.g axis configure x \-min 1.0 \-max 1.5 \&.g axis configure y \-min 12.0 \-max 55.15 .CE To zoom interactively, you link the \fBaxis configure\fR operations with some user interaction (such as pressing the mouse button), using the \fBbind\fR command. To convert between screen and graph coordinates, use the \fBinvtransform\fR operation. .CS # Click the button to set a new minimum bind .g <ButtonPress-1> { %W axis configure x \-min [%W axis invtransform x %x] %W axis configure x \-min [%W axis invtransform x %y] } .CE By default, the limits of the axis are determined from data values. To reset back to the default limits, set the \fB\-min\fR and \fB\-max\fR options to the empty value. .CS # Reset the axes to autoscale again. \&.g axis configure x \-min {} \-max {} \&.g axis configure y \-min {} \-max {} .CE By default, the legend is drawn in the right margin. You can change this or any legend configuration options using the \fBlegend\fR component. .CS # Configure the legend font, color, and relief \&.g legend configure \-position left \-relief raised \\ \-font fixed \-fg blue .CE To prevent the legend from being displayed, turn on the \fB\-hide\fR option. .CS # Don't display the legend. \&.g legend configure \-hide yes\fR .CE The \fBgraph\fR widget has simple drawing procedures called markers. They can be used to highlight or annotate data in the graph. The types of markers available are bitmaps, images, polygons, lines, or windows. Markers can be used, for example, to mark or brush points. In this example, is a text marker that labels the data first point. Markers are created using the \fBmarker\fR component. .CS # Create a label for the first data point of "line1". \&.g marker create text \-name first_marker \-coords { 0.2 26.18 } \\ \-text "start" \-anchor se \-xoffset -10 \-yoffset -10 .CE This creates a text marker named \f(CWfirst_marker\fR. It will display the text "start" near the coordinates of the first data point. The \fB\-anchor\fR, \fB\-xoffset\fR, and \fB\-yoffset\fR options are used to display the marker above and to the left of the data point, so that the data point isn't covered by the marker. By default, markers are drawn last, on top of data. You can change this with the \fB\-under\fR option. .CS # Draw the label before elements are drawn. \&.g marker configure first_marker \-under yes .CE You can add cross hairs or grid lines using the \fBcrosshairs\fR and \fBgrid\fR components. .CS # Display both cross hairs and grid lines. \&.g crosshairs configure \-hide no \-color red \&.g grid configure \-hide no \-dashes { 2 2 } # Set up a binding to reposition the crosshairs. bind .g <Motion> { .g crosshairs configure -position @%x,%y } .CE The crosshairs are repositioned as the mouse pointer is moved in the graph. The pointer X-Y coordinates define the center of the crosshairs. .PP Finally, to get hardcopy of the graph, use the \fBpostscript\fR component. .CS # Print the graph into file "file.ps" \&.g postscript output file.ps \-maxpect yes \-decorations no .CE This generates a file \f(CWfile.ps\fR containing the encapsulated PostScript of the graph. The option \fB\-maxpect\fR says to scale the plot to the size of the page. Turning off the \fB\-decorations\fR option denotes that no borders or color backgrounds should be drawn (i.e. the background of the margins, legend, and plotting area will be white). .SH "GRAPH OPERATIONS" .TP \fIpathName \fBaxis \fIoperation \fR?\fIarg\fR?... See the .SB "AXIS COMPONENTS" section. .TP \fIpathName \fBbar \fIelemName \fR?\fIoption value\fR?... Creates a new barchart element \fIelemName\fR. It's an error if an element \fIelemName\fR already exists. See the manual for \fBbarchart\fR for details about what \fIoption\fR and \fIvalue\fR pairs are valid. .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the \fBconfigure\fR operation. .TP \fIpathName \fBconfigure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the graph. If \fIoption\fR isn't specified, a list describing the current options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the option \fIoption\fR is set to \fIvalue\fR. The following options are valid. .RS .TP \fB\-aspect \fIwidth/height\fR Force a fixed aspect ratio of \fIwidth/height\fR, a floating point number. .TP \fB\-background \fIcolor\fR Sets the background color. This includes the margins and legend, but not the plotting area. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-bottommargin \fIpixels\fR If non-zero, overrides the computed size of the margin extending below the X\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used. The default is \f(CW0\fR. .TP \fB\-bufferelements \fIboolean\fR Indicates whether an internal pixmap to buffer the display of data elements should be used. If \fIboolean\fR is true, data elements are drawn to an internal pixmap. This option is especially useful when the graph is redrawn frequently while the remains data unchanged (for example, moving a marker across the plot). See the .SB "SPEED TIPS" section. The default is \f(CW1\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CWcrosshair\fR. .TP \fB\-font \fIfontName\fR Specifies the font of the graph title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-18-180-*\fR. .TP \fB\-halo \fIpixels\fR Specifies a maximum distance to consider when searching for the closest data point (see the element's \fBclosest\fR operation below). Data points further than \fIpixels\fR away are ignored. The default is \f(CW0.5i\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW4i\fR. .TP \fB\-invertxy \fIboolean\fR Indicates whether the placement X\-axis and Y\-axis should be inverted. If \fIboolean\fR is true, the X and Y axes are swapped. The default is \f(CW0\fR. .TP \fB\-justify \fIjustify\fR Specifies how the title should be justified. This matters only when the title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-leftmargin \fIpixels\fR If non-zero, overrides the computed size of the margin extending from the left edge of the window to the Y\-coordinate axis. If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used. The default is \f(CW0\fR. .TP \fB\-plotbackground \fIcolor\fR Specifies the background color of the plotting area. The default is \f(CWwhite\fR. .TP \fB\-plotborderwidth \fIpixels\fR Sets the width of the 3-D border around the plotting area. The \fB\-plotrelief\fR option determines if a border is drawn. The default is \f(CW2\fR. .TP \fB\-plotpadx \fIpad\fR Sets the amount of padding to be added to the left and right sides of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the plotting area entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotpady \fIpad\fR Sets the amount of padding to be added to the top and bottom of the plotting area. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the plotting area is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom are padded evenly. The default is \f(CW8\fR. .TP \fB\-plotrelief \fIrelief\fR Specifies the 3-D effect for the plotting area. \fIRelief\fR specifies how the interior of the plotting area should appear relative to rest of the graph; for example, \f(CWraised\fR means the plot should appear to protrude from the graph, relative to the surface of the graph. The default is \f(CWsunken\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the graph widget. \fIRelief\fR specifies how the graph should appear relative to widget it is packed into; for example, \f(CWraised\fR means the graph should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-rightmargin \fIpixels\fR If non-zero, overrides the computed size of the margin extending from the plotting area to the right edge of the window. By default, the legend is drawn in this margin. If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used. The default is \f(CW0\fR. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW""\fR. .TP \fB\-tile \fIimage\fR Specifies a tiled background for the widget. If \fIimage\fR isn't \f(CW""\fR, the background is tiled using \fIimage\fR. Otherwise, the normal background color is drawn (see the \fB\-background\fR option). \fIImage\fR must be an image created using the Tk \fBimage\fR command. The default is \f(CW""\fR. .TP \fB\-title \fItext\fR Sets the title to \fItext\fR. If \fItext\fR is \f(CW""\fR, no title will be displayed. .TP \fB\-topmargin \fIpixels\fR If non-zero, overrides the computed size of the margin above the x2 axis. If \fIpixels\fR is \f(CW0\fR, the automatically computed size is used. The default is \f(CW0\fR. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. The default is \f(CW5i\fR. .RE .TP \fIpathName \fBcrosshairs \fIoperation \fR?\fIarg\fR? See the .SB "CROSSHAIRS COMPONENT" section. .TP \fIpathName \fBelement \fIoperation \fR?\fIarg\fR?... See the .SB "ELEMENT COMPONENTS" section. .TP \fIpathName \fBextents \fIitem\fR Returns the size of a particular item in the graph. \fIItem\fR must be either \f(CWleftmargin\fR, \f(CWrightmargin\fR, \f(CWtopmargin\fR, \f(CWbottommargin\fR, \f(CWplotwidth\fR, or \f(CWplotheight\fR. .TP \fIpathName \fBgrid \fIoperation \fR?\fIarg\fR?... See the .SB "GRID COMPONENT" section. .TP \fIpathName \fBinvtransform \fIwinX winY\fR Performs an inverse coordinate transformation, mapping window coordinates back to graph coordinates, using the standard X\-axis and Y\-axis. Returns a list of containing the X-Y graph coordinates. .TP \fIpathName \fBinside \fIx y\fR Returns \f(CW1\fR is the designated screen coordinate (\fIx\fR and \fIy\fR) is inside the plotting area and \f(CW0\fR otherwise. .TP \fIpathName \fBlegend \fIoperation \fR?\fIarg\fR?... See the .SB "LEGEND COMPONENT" section. .TP \fIpathName \fBline\fB operation arg\fR... The operation is the same as \fBelement\fR. .TP \fIpathName \fBmarker \fIoperation \fR?\fIarg\fR?... See the .SB "MARKER COMPONENTS" section. .TP \fIpathName \fBpostscript \fIoperation \fR?\fIarg\fR?... See the .SB "POSTSCRIPT COMPONENT" section. .TP \fIpathName \fBsnap \fR?\fIswitches\fR? \fIoutputName\fR Takes a snapshot of the graph, saving the output in \fIoutputName\fR. The following switches are available. .RS .TP 1i \fB\-format\fR \fIformat\fR Specifies how the snapshot is output. \fIFormat\fR may be one of the following listed below. The default is \f(CWphoto\fR. .RS .TP \f(CWphoto\fR Saves a Tk photo image. \fIOutputName\fR represents the name of a Tk photo image that must already have been created. .TP \f(CWwmf\fR Saves an Aldus Placeable Metafile. \fIOutputName\fR represents the filename where the metafile is written. If \fIoutputName\fR is \f(CWCLIPBOARD\fR, then output is written directly to the Windows clipboard. This format is available only under Microsoft Windows. .TP \f(CWemf\fR Saves an Enhanced Metafile. \fIOutputName\fR represents the filename where the metafile is written. If \fIoutputName\fR is \f(CWCLIPBOARD\fR, then output is written directly to the Windows clipboard. This format is available only under Microsoft Windows. .RE .TP 1i \fB\-height\fR \fIsize\fR Specifies the height of the graph. \fISize\fR is a screen distance. The graph will be redrawn using this dimension, rather than its current window height. .TP 1i \fB\-width\fR \fIsize\fR Specifies the width of the graph. \fISize\fR is a screen distance. The graph will be redrawn using this dimension, rather than its current window width. .RE .TP \fIpathName \fBtransform \fIx y\fR Performs a coordinate transformation, mapping graph coordinates to window coordinates, using the standard X\-axis and Y\-axis. Returns a list containing the X\-Y screen coordinates. .TP \fIpathName \fBxaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBx2axis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fByaxis \fIoperation\fR ?\fIarg\fR?... .TP \fIpathName \fBy2axis \fIoperation\fR ?\fIarg\fR?... See the .SB "AXIS COMPONENTS" section. .SH "GRAPH COMPONENTS" A graph is composed of several components: coordinate axes, data elements, legend, grid, cross hairs, postscript, and annotation markers. Instead of one big set of configuration options and operations, the graph is partitioned, where each component has its own configuration options and operations that specifically control that aspect or part of the graph. .SS "AXIS COMPONENTS" Four coordinate axes are automatically created: two X\-coordinate axes (\f(CWx\fR and \f(CWx2\fR) and two Y\-coordinate axes (\f(CWy\fR, and \f(CWy2\fR). By default, the axis \f(CWx\fR is located in the bottom margin, \f(CWy\fR in the left margin, \f(CWx2\fR in the top margin, and \f(CWy2\fR in the right margin. .PP An axis consists of the axis line, title, major and minor ticks, and tick labels. Major ticks are drawn at uniform intervals along the axis. Each tick is labeled with its coordinate value. Minor ticks are drawn at uniform intervals within major ticks. .PP The range of the axis controls what region of data is plotted. Data points outside the minimum and maximum limits of the axis are not plotted. By default, the minimum and maximum limits are determined from the data, but you can reset either limit. .PP You can have several axes. To create an axis, invoke the axis component and its create operation. .CS # Create a new axis called "tempAxis" \&.g axis create tempAxis .CE You map data elements to an axis using the element's \-mapy and \-mapx configuration options. They specify the coordinate axes an element is mapped onto. .CS # Now map the tempAxis data to this axis. \&.g element create "e1" \-xdata $x \-ydata $y \-mapy tempAxis .CE Any number of axes can be displayed simultaneously. They are drawn in the margins surrounding the plotting area. The default axes \f(CWx\fR and \f(CWy\fR are drawn in the bottom and left margins. The axes \f(CWx2\fR and \f(CWy2\fR are drawn in top and right margins. By default, only \f(CWx\fR and \f(CWy\fR are shown. Note that the axes can have different scales. .PP To display a different axis or more than one axis, you invoke one of the following components: \fBxaxis\fR, \fByaxis\fR, \fBx2axis\fR, and \fBy2axis\fR. Each component has a \fBuse\fR operation that designates the axis (or axes) to be drawn in that corresponding margin: \fBxaxis\fR in the bottom, \fByaxis\fR in the left, \fBx2axis\fR in the top, and \fBy2axis\fR in the right. .CS # Display the axis tempAxis in the left margin. \&.g yaxis use tempAxis .CE The \fBuse\fR operation takes a list of axis names as its last argument. This is the list of axes to be drawn in this margin. .PP You can configure axes in many ways. The axis scale can be linear or logarithmic. The values along the axis can either monotonically increase or decrease. If you need custom tick labels, you can specify a Tcl procedure to format the label any way you wish. You can control how ticks are drawn, by changing the major tick interval or the number of minor ticks. You can define non-uniform tick intervals, such as for time-series plots. .PP .TP \fIpathName \fBaxis bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an axis with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on graph axes, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBaxis \fBcget \fIaxisName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIaxisName\fR. \fIOption\fR may be any option described below for the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBconfigure \fIaxisName \fR?\fIaxisName\fR?... ?\fIoption value\fR?... Queries or modifies the configuration options of \fIaxisName\fR. Several axes can be changed. If \fIoption\fR isn't specified, a list describing all the current options for \fIaxisName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the axis option \fIoption\fR is set to \fIvalue\fR. The following options are valid for axes. .RS .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for the axis. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events for axes are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-color \fIcolor\fR Sets the color of the axis and tick labels. The default is \f(CWblack\fR. .TP \fB\-command \fIprefix\fR Specifies a Tcl command to be invoked when formatting the axis tick labels. \fIPrefix\fR is a string containing the name of a Tcl proc and any extra arguments for the procedure. This command is invoked for each major tick on the axis. Two additional arguments are passed to the procedure: the pathname of the widget and the current the numeric value of the tick. The procedure returns the formatted tick label. If \f(CW""\fR is returned, no label will appear next to the tick. You can get the standard tick labels again by setting \fIprefix\fR to \f(CW""\fR. The default is \f(CW""\fR. .sp 1 Please note that this procedure is invoked while the graph is redrawn. You may query configuration options. But do not them, because this can have unexpected results. .TP \fB\-descending \fIboolean\fR Indicates whether the values along the axis are monotonically increasing or decreasing. If \fIboolean\fR is true, the axis values will be decreasing. The default is \f(CW0\fR. .TP \fB\-hide \fIboolean\fR Indicates if the axis is displayed. If \fIboolean\fR is false the axis will be displayed. Any element mapped to the axis is displayed regardless. The default value is \f(CW0\fR. .TP \fB\-justify \fIjustify\fR Specifies how the axis title should be justified. This matters only when the axis title contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-limits \fIformatStr\fR Specifies a printf-like description to format the minimum and maximum limits of the axis. The limits are displayed at the top/bottom or left/right sides of the plotting area. \fIFormatStr\fR is a list of one or two format descriptions. If one description is supplied, both the minimum and maximum limits are formatted in the same way. If two, the first designates the format for the minimum limit, the second for the maximum. If \f(CW""\fR is given as either description, then the that limit will not be displayed. The default is \f(CW""\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the axis and tick lines. The default is \f(CW1\fR pixel. .TP \fB\-logscale \fIboolean\fR Indicates whether the scale of the axis is logarithmic or linear. If \fIboolean\fR is true, the axis is logarithmic. The default scale is linear. .TP \fB\-loose \fIboolean\fR Indicates whether the limits of the axis should fit the data points tightly, at the outermost data points, or loosely, at the outer tick intervals. If the axis limit is set with the -min or -max option, the axes are displayed tightly. If \fIboolean\fR is true, the axis range is "loose". The default is \f(CW0\fR. .TP \fB\-majorticks \fImajorList\fR Specifies where to display major axis ticks. You can use this option to display ticks at non-uniform intervals. \fIMajorList\fR is a list of axis coordinates designating the location of major ticks. No minor ticks are drawn. If \fImajorList\fR is \f(CW""\fR, major ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-max \fIvalue\fR Sets the maximum limit of \fIaxisName\fR. Any data point greater than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the maximum limit is calculated using the largest data value. The default is \f(CW""\fR. .TP \fB\-min \fIvalue\fR Sets the minimum limit of \fIaxisName\fR. Any data point less than \fIvalue\fR is not displayed. If \fIvalue\fR is \f(CW""\fR, the minimum limit is calculated using the smallest data value. The default is \f(CW""\fR. .TP \fB\-minorticks \fIminorList\fR Specifies where to display minor axis ticks. You can use this option to display minor ticks at non-uniform intervals. \fIMinorList\fR is a list of real values, ranging from 0.0 to 1.0, designating the placement of a minor tick. No minor ticks are drawn if the \fB\-majortick\fR option is also set. If \fIminorList\fR is \f(CW""\fR, minor ticks will be automatically computed. The default is \f(CW""\fR. .TP \fB\-rotate \fItheta\fR Specifies the how many degrees to rotate the axis tick labels. \fITheta\fR is a real value representing the number of degrees to rotate the tick labels. The default is \f(CW0.0\fR degrees. .TP \fB\-scrollcommand \fIcommand\fR Specify the prefix for a command used to communicate with scrollbars for this axis, such as \fI.sbar set\fP. .TP \fB\-scrollmax \fIvalue\fR Sets the maximum limit of the axis scroll region. If \fIvalue\fR is \f(CW""\fR, the maximum limit is calculated using the largest data value. The default is \f(CW""\fR. .TP \fB\-scrollmin \fIvalue\fR Sets the minimum limit of axis scroll region. If \fIvalue\fR is \f(CW""\fR, the minimum limit is calculated using the smallest data value. The default is \f(CW""\fR. .TP \fB\-showticks \fIboolean\fR Indicates whether axis ticks should be drawn. If \fIboolean\fR is true, ticks are drawn. If false, only the axis line is drawn. The default is \f(CW1\fR. .TP \fB\-stepsize \fIvalue\fR Specifies the interval between major axis ticks. If \fIvalue\fR isn't a valid interval (must be less than the axis range), the request is ignored and the step size is automatically calculated. .TP \fB\-subdivisions \fInumber\fR Indicates how many minor axis ticks are to be drawn. For example, if \fInumber\fR is two, only one minor tick is drawn. If \fInumber\fR is one, no minor ticks are displayed. The default is \f(CW2\fR. .TP \fB\-tickfont \fIfontName\fR Specifies the font for axis tick labels. The default is \f(CW*-Courier-Bold-R-Normal-*-100-*\fR. .TP \fB\-ticklength \fIpixels\fR Sets the length of major and minor ticks (minor ticks are half the length of major ticks). If \fIpixels\fR is less than zero, the axis will be inverted with ticks drawn pointing towards the plot. The default is \f(CW0.1i\fR. .TP \fB\-title \fItext\fR Sets the title of the axis. If \fItext\fR is \f(CW""\fR, no axis title will be displayed. .TP \fB\-titlealternate \fIboolean\fR Indicates to display the axis title in its alternate location. Normally the axis title is centered along the axis. This option places the axis either to the right (horizontal axes) or above (vertical axes) the axis. The default is \f(CW0\fR. .TP \fB\-titlecolor \fIcolor\fR Sets the color of the axis title. The default is \f(CWblack\fR. .TP \fB\-titlefont \fIfontName\fR Specifies the font for axis title. The default is \f(CW*-Helvetica-Bold-R-Normal-*-14-140-*\fR. .PP Axis configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWAxis\fR. The resource names are the names of the axes (such as \f(CWx\fR or \f(CWx2\fR). .CS option add *Graph.Axis.Color blue option add *Graph.x.LogScale true option add *Graph.x2.LogScale false .CE .RE .TP \fIpathName \fBaxis \fBcreate \fIaxisName \fR?\fIoption value\fR?... Creates a new axis by the name \fIaxisName\fR. No axis by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the axis \fBconfigure\fR operation. .TP \fIpathName \fBaxis \fBdelete \fR?\fIaxisName\fR?... Deletes the named axes. An axis is not really deleted until it is not longer in use, so it's safe to delete axes mapped to elements. .TP \fIpathName \fBaxis invtransform \fIaxisName value\fR Performs the inverse transformation, changing the screen coordinate \fIvalue\fR to a graph coordinate, mapping the value mapped to \fIaxisName\fR. Returns the graph coordinate. .TP \fIpathName \fBaxis limits \fIaxisName\fR Returns a list of the minimum and maximum limits for \fIaxisName\fR. The order of the list is \f(CWmin max\fR. .TP \fIpathName \fBaxis names \fR?\fIpattern\fR?... Returns a list of axes matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all axes are returned. .TP \fIpathName \fBaxis transform \fIaxisName value\fR Transforms the coordinate \fIvalue\fR to a screen coordinate by mapping the it to \fIaxisName\fR. Returns the transformed screen coordinate. .TP \fIpathName \fBaxis view \fIaxisName\fR Change the viewable area of this axis. Use as an argument to a scrollbar's "\fI\-command\fR". .PP The default axes are \f(CWx\fR, \f(CWy\fR, \f(CWx2\fR, and \f(CWy2\fR. But you can display more than four axes simultaneously. You can also swap in a different axis with \fBuse\fR operation of the special axis components: \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR. .CS \&.g create axis temp \&.g create axis time \&... \&.g xaxis use temp \&.g yaxis use time .CE Only the axes specified for use are displayed on the screen. .PP The \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR components operate on an axis location rather than a specific axis like the more general \fBaxis\fR component does. They implicitly control the axis that is currently using to that location. By default, \fBxaxis\fR uses the \f(CWx\fR axis, \fByaxis\fR uses \f(CWy\fR, \fBx2axis\fR uses \f(CWx2\fR, and \fBy2axis\fR uses \f(CWy2\fR. When more than one axis is displayed in a margin, it represents the first axis displayed. .PP The following operations are available for axes. They mirror exactly the operations of the \fBaxis\fR component. The \fIaxis\fR argument must be \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, or \fBy2axis\fR. This feature is deprecated since more than one axis can now be used a margin. You should only use the \fBxaxis\fR, \fBx2axis\fR, \fByaxis\fR, and \fBy2axis\fR components with the \fBuse\fR operation. For all other operations, use the general \fBaxis\fR component instead. .TP \fIpathName \fIaxis \fBcget \fIoption\fR .TP \fIpathName \fIaxis \fBconfigure \fR?\fIoption value\fR?... .TP \fIpathName \fIaxis\fB invtransform \fIvalue\fR .TP \fIpathName \fIaxis \fBlimits\fR .TP \fIpathName \fIaxis\fB transform \fIvalue\fR .TP \fIpathName \fIaxis\fB use \fR?\fIaxisName\fR? Designates the axis \fIaxisName\fR is to be displayed at this location. \fIAxisName\fR can not be already in use at another location. This command returns the name of the axis currently using this location. .SS "CROSSHAIRS COMPONENT" Cross hairs consist of two intersecting lines (one vertical and one horizontal) drawn completely across the plotting area. They are used to position the mouse in relation to the coordinate axes. Cross hairs differ from line markers in that they are implemented using XOR drawing primitives. This means that they can be quickly drawn and erased without redrawing the entire graph. .PP The following operations are available for cross hairs: .TP \fIpathName \fBcrosshairs cget \fIoption\fR Returns the current value of the cross hairs configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the cross hairs \fBconfigure\fR operation. .TP \fIpathName \fBcrosshairs configure \fR?\fIoption value\fR?... Queries or modifies the configuration options of the cross hairs. If \fIoption\fR isn't specified, a list describing all the current options for the cross hairs is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the cross hairs option \fIoption\fR is set to \fIvalue\fR. The following options are available for cross hairs. .RS .TP \fB\-color \fIcolor\fR Sets the color of the cross hairs. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the cross hairs. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the cross hairs will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether cross hairs are drawn. If \fIboolean\fR is true, cross hairs are not drawn. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the cross hair lines. The default is \f(CW1\fR. .TP \fB\-position \fIpos\fR Specifies the screen position where the cross hairs intersect. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates of the intersection. .PP Cross hairs configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWcrosshairs\fR and \f(CWCrosshairs\fR respectively. .CS option add *Graph.Crosshairs.LineWidth 2 option add *Graph.Crosshairs.Color red .CE .RE .TP \fIpathName \fBcrosshairs off\fR Turns off the cross hairs. .TP \fIpathName \fBcrosshairs on\fR Turns on the display of the cross hairs. .TP \fIpathName \fBcrosshairs toggle\fR Toggles the current state of the cross hairs, alternately mapping and unmapping the cross hairs. .SS "ELEMENT COMPONENTS" A data element represents a set of data. It contains x and y vectors containing the coordinates of the data points. Elements can be displayed with a symbol at each data point and lines connecting the points. Elements also control the appearance of the data, such as the symbol type, line width, color etc. .PP When new data elements are created, they are automatically added to a list of displayed elements. The display list controls what elements are drawn and in what order. .PP The following operations are available for elements. .TP \fIpathName \fBelement activate \fIelemName \fR?\fIindex\fR?... Specifies the data points of element \fIelemName\fR to be drawn using active foreground and background colors. \fIElemName\fR is the name of the element and \fIindex\fR is a number representing the index of the data point. If no indices are present then all data points become active. .TP \fIpathName \fBelement bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an element with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on graph elements, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBelement cget \fIelemName \fIoption\fR Returns the current value of the element configuration option given by \fIoption\fR. \fIOption\fR may be any of the options described below for the element \fBconfigure\fR operation. .TP \fIpathName \fBelement closest \fIx y\fR ?\fIoption value\fR?... ?\fIelemName\fR?... Searches for the data point closest to the window coordinates \fIx\fR and \fIy\fR. By default, all elements are searched. Hidden elements (see the \fB\-hide\fR option is false) are ignored. You can limit the search by specifying only the elements you want to be considered. \fIElemName\fR must be the name of an element that can not be hidden. It returns a key-value list containing the name of the closest element, the index of the closest data point, and the graph-coordinates of the point. Returns \f(CW""\fR, if no data point within the threshold distance can be found. The following \fIoption\fR\-\fIvalue\fR pairs are available. .RS .TP \fB\-along \fIdirection\fR Search for the closest element using the following criteria: .RS .TP \f(CWx\fR Find closest element vertically from the given X-coordinate. .TP \f(CWy\fR Find the closest element horizontally from the given Y-coordinate. .TP \f(CWboth\fR Find the closest element for the given point (using both the X and Y coordinates). .RE .TP \fB\-halo \fIpixels\fR Specifies a threshold distance where selected data points are ignored. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. If this option isn't specified, then it defaults to the value of the graph's \fB\-halo\fR option. .TP \fB\-interpolate \fIstring\fR Indicates whether to consider projections that lie along the line segments connecting data points when searching for the closest point. The default value is \f(CW0\fR. The values for \fIstring\fR are described below. .RS .TP 1.25i \f(CWno\fR Search only for the closest data point. .TP \f(CWyes\fR Search includes projections that lie along the line segments connecting the data points. .RE .RE .TP \fIpathName \fBelement configure \fIelemName \fR?\fIelemName\fR... ?\fIoption value\fR?... Queries or modifies the configuration options for elements. Several elements can be modified at the same time. If \fIoption\fR isn't specified, a list describing all the current options for \fIelemName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the option \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the element option \fIoption\fR is set to \fIvalue\fR. The following options are valid for elements. .RS .TP \fB\-activepen \fIpenName\fR Specifies pen to use to draw active element. If \fIpenName\fR is \f(CW""\fR, no active elements will be drawn. The default is \f(CWactiveLine\fR. .TP \fB\-areabackground \fIcolor\fR Specifies the background color of the area under the curve. The background area color is drawn only for bitmaps (see the \fB\-areapattern\fR option). If \fIcolor\fR is \f(CW""\fR, the background is transparent. The default is \f(CWblack\fR. .TP \fB\-areaforeground \fIcolor\fR Specifies the foreground color of the area under the curve. The default is \f(CWblack\fR. .TP \fB\-areapattern \fIpattern\fR Specifies how to fill the area under the curve. \fIPattern\fR may be the name of a Tk bitmap, \f(CWsolid\fR, or \f(CW""\fR. If "solid", then the area under the curve is drawn with the color designated by the \fB\-areaforeground\fR option. If a bitmap, then the bitmap is stippled across the area. Here the bitmap colors are controlled by the \fB\-areaforeground\fR and \fB\-areabackground\fR options. If \fIpattern\fR is \f(CW""\fR, no filled area is drawn. The default is \f(CW""\fR. .TP \fB\-areatile \fIimage\fR Specifies the name of a Tk image to be used to tile the area under the curve. This option supersedes the \fB\-areapattern\fR option. \fIImage\fR must be a photo image. If \fIimage\fR is \f(CW""\fR, no tiling is performed. The default is \f(CW""\fR. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for the element. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events are handled for elements. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the element is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-color \fIcolor\fR Sets the color of the traces connecting the data points. .TP \fB\-dashes \fIdashList\fR Sets the dash style of element line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the lines will be solid. .TP \fB\-data \fIcoordList\fR Specifies the X\-Y coordinates of the data. \fICoordList\fR is a list of numeric expressions representing the X\-Y coordinate pairs of each data point. .TP \fB\-fill \fIcolor\fR Sets the interior color of symbols. If \fIcolor\fR is \f(CW""\fR, then the interior of the symbol is transparent. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the element is displayed. The default is \f(CWno\fR. .TP \fB\-label \fItext\fR Sets the element's label in the legend. If \fItext\fR is \f(CW""\fR, the element will have no entry in the legend. The default label is the element's name. .TP \fB\-linewidth \fIpixels\fR Sets the width of the connecting lines between data points. If \fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between symbols. The default is \f(CW0\fR. .TP \fB\-mapx \fIxAxis\fR Selects the X\-axis to map the element's X\-coordinates onto. \fIXAxis\fR must be the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Selects the Y\-axis to map the element's Y\-coordinates onto. \fIYAxis\fR must be the name of an axis. The default is \f(CWy\fR. .TP \fB\-offdash \fIcolor\fR Sets the color of the stripes when traces are dashed (see the \fB\-dashes\fR option). If \fIcolor\fR is \f(CW""\fR, then the "off" pixels will represent gaps instead of stripes. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outline \fIcolor\fR Sets the color or the outline around each symbol. If \fIcolor\fR is \f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-pen \fIpenname\fR Set the pen to use for this element. .TP \fB\-outlinewidth \fIpixels\fR Sets the width of the outline bordering each symbol. If \fIpixels\fR is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR. .TP \fB\-pixels \fIpixels\fR Sets the size of symbols. If \fIpixels\fR is \f(CW0\fR, no symbols will be drawn. The default is \f(CW0.125i\fR. .TP \fB\-scalesymbols \fIboolean\fR If \fIboolean\fR is true, the size of the symbols drawn for \fIelemName\fR will change with scale of the X\-axis and Y\-axis. At the time this option is set, the current ranges of the axes are saved as the normalized scales (i.e scale factor is 1.0) and the element is drawn at its designated size (see the \fB\-pixels\fR option). As the scale of the axes change, the symbol will be scaled according to the smaller of the X\-axis and Y\-axis scales. If \fIboolean\fR is false, the element's symbols are drawn at the designated size, regardless of axis scales. The default is \f(CW0\fR. .TP \fB\-smooth \fIsmooth\fR Specifies how connecting line segments are drawn between data points. \fISmooth\fR can be either \f(CWlinear\fR, \f(CWstep\fR, \f(CWnatural\fR, or \f(CWquadratic\fR. If \fIsmooth\fR is \f(CWlinear\fR, a single line segment is drawn, connecting both data points. When \fIsmooth\fR is \f(CWstep\fR, two line segments are drawn. The first is a horizontal line segment that steps the next X\-coordinate. The second is a vertical line, moving to the next Y\-coordinate. Both \fInatural\fR and \fIquadratic\fR generate multiple segments between data points. If \fInatural\fR, the segments are generated using a cubic spline. If \fIquadratic\fR, a quadratic spline is used. The default is \fIlinear\fR. .TP \fB\-styles \fIstyleList\fR Specifies what pen to use based on the range of weights given. \fIStyleList\fR is a list of style specifications. Each style specification, in turn, is a list consisting of a pen name, and optionally a minimum and maximum range. Data points whose weight (see the \fB\-weight\fR option) falls in this range, are drawn with this pen. If no range is specified it defaults to the index of the pen in the list. Note that this affects only symbol attributes. Line attributes, such as line width, dashes, etc. are ignored. .TP \fB\-symbol \fIsymbol\fR Specifies the symbol for data points. \fISymbol\fR can be either \f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR, \f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol is drawn), or a bitmap. Bitmaps are specified as "\fIsource\fR ?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and \fImask\fR is the bitmap's optional mask. The default is \f(CWcircle\fR. .TP \fB\-trace \fIdirection\fR Indicates whether connecting lines between data points (whose X\-coordinate values are either increasing or decreasing) are drawn. \fIDirection\fR must be \f(CWincreasing\fR, \f(CWdecreasing\fR, or \f(CWboth\fR. For example, if \fIdirection\fR is \f(CWincreasing\fR, connecting lines will be drawn only between those data points where X\-coordinate values are monotonically increasing. If \fIdirection\fR is \f(CWboth\fR, connecting lines will be draw between all data points. The default is \f(CWboth\fR. .TP \fB\-weights \fIwVec\fR Specifies the weights of the individual data points. This, with the list pen styles (see the \fB\-styles\fR option), controls how data points are drawn. \fIWVec\fR is the name of a BLT vector or a list of numeric expressions representing the weights for each data point. .TP \fB\-xdata \fIxVec\fR Specifies the X\-coordinates of the data. \fIXVec\fR is the name of a BLT vector or a list of numeric expressions. .TP \fB\-ydata \fIyVec\fR Specifies the Y\-coordinates of the data. \fIYVec\fR is the name of a BLT vector or a list of numeric expressions. .PP Element configuration options may also be set by the \fBoption\fR command. The resource class is \f(CWElement\fR. The resource name is the name of the element. .CS option add *Graph.Element.symbol line option add *Graph.e1.symbol line .CE .RE .TP \fIpathName \fBelement create \fIelemName\fR ?\fIoption value\fR?... Creates a new element \fIelemName\fR. It's an error is an element \fIelemName\fR already exists. If additional arguments are present, they specify options valid for the element \fBconfigure\fR operation. .TP \fIpathName \fBelement deactivate \fIelemName\fR ?\fIelemName\fR?... Deactivates all the elements matching \fIpattern\fR. Elements whose names match any of the patterns given are redrawn using their normal colors. .TP \fIpathName \fBelement delete\fR ?\fIelemName\fR?... Deletes all the named elements. The graph is automatically redrawn. .TP \fIpathName \fBelement exists \fIelemName\fR Returns \f(CW1\fR if an element \fIelemName\fR currently exists and \f(CW0\fR otherwise. .TP \fIpathName \fBelement names \fR?\fIpattern\fR?... Returns the elements matching one or more pattern. If no \fIpattern\fR is given, the names of all elements is returned. .TP \fIpathName \fBelement show\fR ?\fInameList\fR? Queries or modifies the element display list. The element display list designates the elements drawn and in what order. \fINameList\fR is a list of elements to be displayed in the order they are named. If there is no \fInameList\fR argument, the current display list is returned. .TP \fIpathName \fBelement type\fR \fIelemName\fR Returns the type of \fIelemName\fR. If the element is a bar element, the commands returns the string \f(CW"bar"\fR, otherwise it returns \f(CW"line"\fR. .CE .SS "GRID COMPONENT" Grid lines extend from the major and minor ticks of each axis horizontally or vertically across the plotting area. The following operations are available for grid lines. .TP \fIpathName \fBgrid cget \fIoption\fR Returns the current value of the grid line configuration option given by \fIoption\fR. \fIOption\fR may be any option described below for the grid \fBconfigure\fR operation. .TP \fIpathName \fBgrid configure\fR ?\fIoption value\fR?... Queries or modifies the configuration options for grid lines. If \fIoption\fR isn't specified, a list describing all the current grid options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the grid line option \fIoption\fR is set to \fIvalue\fR. The following options are valid for grid lines. .RS .TP \fB\-color \fIcolor\fR Sets the color of the grid lines. The default is \f(CWblack\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the grid lines. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the grid lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the grid will be solid lines. .TP \fB\-hide \fIboolean\fR Indicates whether the grid should be drawn. If \fIboolean\fR is true, grid lines are not shown. The default is \f(CWyes\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of grid lines. The default width is \f(CW1\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to display grid lines. \fIXAxis\fR must be the name of an axis or \f(CW""\fR for no grid lines. The default is \f(CW""\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to display grid lines. \fIYAxis\fR must be the name of an axis or \f(CW""\fR for no grid lines. The default is \f(CWy\fR. .TP \fB\-minor \fIboolean\fR Indicates whether the grid lines should be drawn for minor ticks. If \fIboolean\fR is true, the lines will appear at minor tick intervals. The default is \f(CW1\fR. .PP Grid configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWgrid\fR and \f(CWGrid\fR respectively. .CS option add *Graph.grid.LineWidth 2 option add *Graph.Grid.Color black .CE .RE .TP \fIpathName \fBgrid off\fR Turns off the display the grid lines. .TP \fIpathName \fBgrid on\fR Turns on the display the grid lines. .TP \fIpathName \fBgrid toggle\fR Toggles the display of the grid. .SS "LEGEND COMPONENT" The legend displays a list of the data elements. Each entry consists of the element's symbol and label. The legend can appear in any margin (the default location is in the right margin). It can also be positioned anywhere within the plotting area. .PP The following operations are valid for the legend. .TP \fIpathName \fBlegend activate \fIpattern\fR... Selects legend entries to be drawn using the active legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a legend entry with this tag, \fIcommand\fR will be invoked. Implicitly the element names in the entry are tags. The syntax is similar to the \fBbind\fR command except that it operates on legend entries, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBlegend cget \fIoption\fR Returns the current value of a legend configuration option. \fIOption\fR may be any option described below in the legend \fBconfigure\fR operation. .TP \fIpathName \fBlegend configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for the legend. If \fIoption\fR isn't specified, a list describing the current legend options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the legend option \fIoption\fR is set to \fIvalue\fR. The following options are valid for the legend. .RS .TP \fB\-activebackground \fIcolor\fR Sets the background color for active legend entries. All legend entries marked active (see the legend \fBactivate\fR operation) are drawn using this background color. .TP \fB\-activeborderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the active legend entries. The default is \f(CW2\fR. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color for active legend entries. All legend entries marked as active (see the legend \fBactivate\fR operation) are drawn using this foreground color. .TP \fB\-activerelief \fIrelief\fR Specifies the 3-D effect desired for active legend entries. \fIRelief\fR denotes how the interior of the entry should appear relative to the legend; for example, \f(CWraised\fR means the entry should appear to protrude from the legend, relative to the surface of the legend. The default is \f(CWflat\fR. .TP \fB\-anchor \fIanchor\fR Tells how to position the legend relative to the positioning point for the legend. This is dependent on the value of the \fB\-position\fR option. The default is \f(CWcenter\fR. .RS .TP 1.25i \f(CWleft\fR or \f(CWright\fR The anchor describes how to position the legend vertically. .TP \f(CWtop\fR or \f(CWbottom\fR The anchor describes how to position the legend horizontally. .TP \f(CW@x,y\fR The anchor specifies how to position the legend relative to the positioning point. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered on the point; if \fIanchor\fR is \f(CWn\fR then the legend will be drawn such that the top center point of the rectangular region occupied by the legend will be at the positioning point. .TP \f(CWplotarea\fR The anchor specifies how to position the legend relative to the plotting area. For example, if \fIanchor\fR is \f(CWcenter\fR then the legend is centered in the plotting area; if \fIanchor\fR is \f(CWne\fR then the legend will be drawn such that occupies the upper right corner of the plotting area. .RE .TP \fB\-background \fIcolor\fR Sets the background color of the legend. If \fIcolor\fR is \f(CW""\fR, the legend background with be transparent. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for legend entries. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events are handled for legend entries. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is \f(CWall\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3-D border around the outside edge of the legend (if such border is being drawn; the \fBrelief\fR option determines this). The default is \f(CW2\fR pixels. .TP \fB\-font \fIfontName\fR \fIFontName\fR specifies a font to use when drawing the labels of each element into the legend. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of the text drawn for the element's label. The default is \f(CWblack\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the legend should be displayed. If \fIboolean\fR is true, the legend will not be draw. The default is \f(CWno\fR. .TP \fB\-ipadx \fIpad\fR Sets the amount of internal padding to be added to the width of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend entry is padded by the first distance and the right side by the second. If \fIpad\fR is just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-ipady \fIpad\fR Sets an amount of internal padding to be added to the height of each legend entry. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the entry is padded by the first distance and the bottom by the second. If \fIpad\fR is just one distance, both the top and bottom of the entry are padded evenly. The default is \f(CW2\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the legend is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the legend. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the legend is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW0\fR. .TP \fB\-position \fIpos\fR Specifies where the legend is drawn. The \fB\-anchor\fR option also affects where the legend is positioned. If \fIpos\fR is \f(CWleft\fR, \f(CWleft\fR, \f(CWtop\fR, or \f(CWbottom\fR, the legend is drawn in the specified margin. If \fIpos\fR is \f(CWplotarea\fR, then the legend is drawn inside the plotting area at a particular anchor. If \fIpos\fR is in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are the window coordinates, the legend is drawn in the plotting area at the specified coordinates. The default is \f(CWright\fR. .TP \fB\-raised \fIboolean\fR Indicates whether the legend is above or below the data elements. This matters only if the legend is in the plotting area. If \fIboolean\fR is true, the legend will be drawn on top of any elements that may overlap it. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the border around the legend. \fIRelief\fR specifies how the interior of the legend should appear relative to the graph; for example, \f(CWraised\fR means the legend should appear to protrude from the graph, relative to the surface of the graph. The default is \f(CWsunken\fR. .PP Legend configuration options may also be set by the \fBoption\fR command. The resource name and class are \f(CWlegend\fR and \f(CWLegend\fR respectively. .CS option add *Graph.legend.Foreground blue option add *Graph.Legend.Relief raised .CE .RE .TP \fIpathName \fBlegend deactivate \fIpattern\fR... Selects legend entries to be drawn using the normal legend colors and relief. All entries whose element names match \fIpattern\fR are selected. To be selected, the element name must match only one \fIpattern\fR. .TP \fIpathName \fBlegend get \fIpos\fR Returns the name of the element whose entry is at the screen position \fIpos\fR in the legend. \fIPos\fR must be in the form "\fI@x,y\fR", where \fIx\fR and \fIy\fR are window coordinates. If the given coordinates do not lie over a legend entry, \f(CW""\fR is returned. .SS "PEN COMPONENTS" Pens define attributes (both symbol and line style) for elements. Pens mirror the configuration options of data elements that pertain to how symbols and lines are drawn. Data elements use pens to determine how they are drawn. A data element may use several pens at once. In this case, the pen used for a particular data point is determined from each element's weight vector (see the element's \fB\-weight\fR and \fB\-style\fR options). .PP One pen, called \f(CWactiveLine\fR, is automatically created. It's used as the default active pen for elements. So you can change the active attributes for all elements by simply reconfiguring this pen. .CS \&.g pen configure "activeLine" -color green .CE You can create and use several pens. To create a pen, invoke the pen component and its create operation. .CS \&.g pen create myPen .CE You map pens to a data element using either the element's \fB\-pen\fR or \fB\-activepen\fR options. .CS \&.g element create "line1" -xdata $x -ydata $tempData \\ -pen myPen .CE An element can use several pens at once. This is done by specifying the name of the pen in the element's style list (see the \fB\-styles\fR option). .CS \&.g element configure "line1" -styles { myPen 2.0 3.0 } .CE This says that any data point with a weight between 2.0 and 3.0 is to be drawn using the pen \f(CWmyPen\fR. All other points are drawn with the element's default attributes. .PP The following operations are available for pen components. .PP .TP \fIpathName \fBpen \fBcget \fIpenName \fIoption\fR Returns the current value of the option given by \fIoption\fR for \fIpenName\fR. \fIOption\fR may be any option described below for the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBconfigure \fIpenName \fR?\fIpenName\fR... ?\fIoption value\fR?... Queries or modifies the configuration options of \fIpenName\fR. Several pens can be modified at once. If \fIoption\fR isn't specified, a list describing the current options for \fIpenName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the pen option \fIoption\fR is set to \fIvalue\fR. The following options are valid for pens. .RS .TP \fB\-color \fIcolor\fR Sets the color of the traces connecting the data points. .TP \fB\-dashes \fIdashList\fR Sets the dash style of element line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the element line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the lines will be solid. .TP \fB\-fill \fIcolor\fR Sets the interior color of symbols. If \fIcolor\fR is \f(CW""\fR, then the interior of the symbol is transparent. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the connecting lines between data points. If \fIpixels\fR is \f(CW0\fR, no connecting lines will be drawn between symbols. The default is \f(CW0\fR. .TP \fB\-offdash \fIcolor\fR Sets the color of the stripes when traces are dashed (see the \fB\-dashes\fR option). If \fIcolor\fR is \f(CW""\fR, then the "off" pixels will represent gaps instead of stripes. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outline \fIcolor\fR Sets the color or the outline around each symbol. If \fIcolor\fR is \f(CW""\fR, then no outline is drawn. If \fIcolor\fR is \f(CWdefcolor\fR, then the color will be the same as the \fB\-color\fR option. The default is \f(CWdefcolor\fR. .TP \fB\-outlinewidth \fIpixels\fR Sets the width of the outline bordering each symbol. If \fIpixels\fR is \f(CW0\fR, no outline will be drawn. The default is \f(CW1\fR. .TP \fB\-pixels \fIpixels\fR Sets the size of symbols. If \fIpixels\fR is \f(CW0\fR, no symbols will be drawn. The default is \f(CW0.125i\fR. .TP \fB\-symbol \fIsymbol\fR Specifies the symbol for data points. \fISymbol\fR can be either \f(CWsquare\fR, \f(CWcircle\fR, \f(CWdiamond\fR, \f(CWplus\fR, \f(CWcross\fR, \f(CWsplus\fR, \f(CWscross\fR, \f(CWtriangle\fR, \f(CW""\fR (where no symbol is drawn), or a bitmap. Bitmaps are specified as "\fIsource\fR ?\fImask\fR?", where \fIsource\fR is the name of the bitmap, and \fImask\fR is the bitmap's optional mask. The default is \f(CWcircle\fR. .TP \fB\-type \fIelemType\fR Specifies the type of element the pen is to be used with. This option should only be employed when creating the pen. This is for those that wish to mix different types of elements (bars and lines) on the same graph. The default type is "line". .PP Pen configuration options may be also be set by the \fBoption\fR command. The resource class is \f(CWPen\fR. The resource names are the names of the pens. .CS option add *Graph.Pen.Color blue option add *Graph.activeLine.color green .CE .RE .TP \fIpathName \fBpen \fBcreate \fIpenName \fR?\fIoption value\fR?... Creates a new pen by the name \fIpenName\fR. No pen by the same name can already exist. \fIOption\fR and \fIvalue\fR are described in above in the pen \fBconfigure\fR operation. .TP \fIpathName \fBpen \fBdelete \fR?\fIpenName\fR?... Deletes the named pens. A pen is not really deleted until it is not longer in use, so it's safe to delete pens mapped to elements. .TP \fIpathName \fBpen names \fR?\fIpattern\fR?... Returns a list of pens matching zero or more patterns. If no \fIpattern\fR argument is give, the names of all pens are returned. .SS "POSTSCRIPT COMPONENT" The graph can generate encapsulated PostScript output. There are several configuration options you can specify to control how the plot will be generated. You can change the page dimensions and borders. The plot itself can be scaled, centered, or rotated to landscape. The PostScript output can be written directly to a file or returned through the interpreter. .PP The following postscript operations are available. .TP \fIpathName \fBpostscript cget \fIoption\fR Returns the current value of the postscript option given by \fIoption\fR. \fIOption\fR may be any option described below for the postscript \fBconfigure\fR operation. .TP \fIpathName \fBpostscript configure \fR?\fIoption value\fR?... Queries or modifies the configuration options for PostScript generation. If \fIoption\fR isn't specified, a list describing the current postscript options for \fIpathName\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the postscript option \fIoption\fR is set to \fIvalue\fR. The following postscript options are available. .RS .TP \fB\-center \fIboolean\fR Indicates whether the plot should be centered on the PostScript page. If \fIboolean\fR is false, the plot will be placed in the upper left corner of the page. The default is \f(CW1\fR. .TP \fB\-colormap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a color mapping from the X color name to PostScript. Each element of \fIvarName\fR must consist of PostScript code to set a particular color value (e.g. ``\f(CW1.0 1.0 0.0 setrgbcolor\fR''). When generating color information in PostScript, the array variable \fIvarName\fR is checked if an element of the name as the color exists. If so, it uses its value as the PostScript command to set the color. If this option hasn't been specified, or if there isn't an entry in \fIvarName\fR for a given color, then it uses the red, green, and blue intensities from the X color. .TP \fB\-colormode \fImode\fR Specifies how to output color information. \fIMode\fR must be either \f(CWcolor\fR (for full color output), \f(CWgray\fR (convert all colors to their gray-scale equivalents) or \f(CWmono\fR (convert foreground colors to black and background colors to white). The default mode is \f(CWcolor\fR. .TP \fB\-fontmap \fIvarName\fR \fIVarName\fR must be the name of a global array variable that specifies a font mapping from the X font name to PostScript. Each element of \fIvarName\fR must consist of a Tcl list with one or two elements; the name and point size of a PostScript font. When outputting PostScript commands for a particular font, the array variable \fIvarName\fR is checked to see if an element by the specified font exists. If there is such an element, then the font information contained in that element is used in the PostScript output. (If the point size is omitted from the list, the point size of the X font is used). Otherwise the X font is examined in an attempt to guess what PostScript font to use. This works only for fonts whose foundry property is \fIAdobe\fR (such as Times, Helvetica, Courier, etc.). If all of this fails then the font defaults to \f(CWHelvetica-Bold\fR. .TP \fB\-decorations \fIboolean\fR Indicates whether PostScript commands to generate color backgrounds and 3-D borders will be output. If \fIboolean\fR is false, the background will be white and no 3-D borders will be generated. The default is \f(CW1\fR. .TP \fB\-height \fIpixels\fR Sets the height of the plot. This lets you print the graph with a height different from the one drawn on the screen. If \fIpixels\fR is 0, the height is the same as the widget's height. The default is \f(CW0\fR. .TP \fB\-landscape \fIboolean\fR If \fIboolean\fR is true, this specifies the printed area is to be rotated 90 degrees. In non-rotated output the X\-axis of the printed area runs along the short dimension of the page (``portrait'' orientation); in rotated output the X\-axis runs along the long dimension of the page (``landscape'' orientation). Defaults to \f(CW0\fR. .TP \fB\-maxpect \fIboolean\fR Indicates to scale the plot so that it fills the PostScript page. The aspect ratio of the graph is still retained. The default is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets the horizontal padding for the left and right page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left border is padded by the first distance and the right border by the second. If \fIpad\fR has just one distance, both the left and right borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-pady \fIpad\fR Sets the vertical padding for the top and bottom page borders. The borders are exterior to the plot. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top border is padded by the first distance and the bottom border by the second. If \fIpad\fR has just one distance, both the top and bottom borders are padded evenly. The default is \f(CW1i\fR. .TP \fB\-paperheight \fIpixels\fR Sets the height of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default height is \f(CW11.0i\fR. .TP \fB\-paperwidth \fIpixels\fR Sets the width of the postscript page. This can be used to select between different page sizes (letter, A4, etc). The default width is \f(CW8.5i\fR. .TP \fB\-width \fIpixels\fR Sets the width of the plot. This lets you generate a plot of a width different from that of the widget. If \fIpixels\fR is 0, the width is the same as the widget's width. The default is \f(CW0\fR. .PP Postscript configuration options may be also be set by the \fBoption\fR command. The resource name and class are \f(CWpostscript\fR and \f(CWPostscript\fR respectively. .CS option add *Graph.postscript.Decorations false option add *Graph.Postscript.Landscape true .CE .RE .TP \fIpathName \fBpostscript output \fR?\fIfileName\fR? ?\fIoption value\fR?... Outputs a file of encapsulated PostScript. If a \fIfileName\fR argument isn't present, the command returns the PostScript. If any \fIoption-value\fR pairs are present, they set configuration options controlling how the PostScript is generated. \fIOption\fR and \fIvalue\fR can be anything accepted by the postscript \fBconfigure\fR operation above. .SS "MARKER COMPONENTS" Markers are simple drawing procedures used to annotate or highlight areas of the graph. Markers have various types: text strings, bitmaps, images, connected lines, windows, or polygons. They can be associated with a particular element, so that when the element is hidden or un-hidden, so is the marker. By default, markers are the last items drawn, so that data elements will appear in behind them. You can change this by configuring the \fB\-under\fR option. .PP Markers, in contrast to elements, don't affect the scaling of the coordinate axes. They can also have \fIelastic\fR coordinates (specified by \f(CW-Inf\fR and \f(CWInf\fR respectively) that translate into the minimum or maximum limit of the axis. For example, you can place a marker so it always remains in the lower left corner of the plotting area, by using the coordinates \f(CW-Inf\fR,\f(CW-Inf\fR. .PP The following operations are available for markers. .TP \fIpathName \fBmarker after \fImarkerId\fR ?\fIafterId\fR? Changes the order of the markers, drawing the first marker after the second. If no second \fIafterId\fR argument is specified, the marker is placed at the end of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker before \fImarkerId\fR ?\fIbeforeId\fR? Changes the order of the markers, drawing the first marker before the second. If no second \fIbeforeId\fR argument is specified, the marker is placed at the beginning of the display list. This command can be used to control how markers are displayed since markers are drawn in the order of this display list. .TP \fIpathName \fBmarker bind \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a marker with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on graph markers, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBmarker cget \fIoption\fR Returns the current value of the marker configuration option given by \fIoption\fR. \fIOption\fR may be any option described below in the \fBconfigure\fR operation. .TP \fIpathName \fBmarker configure \fImarkerId\fR ?\fIoption value\fR?... Queries or modifies the configuration options for markers. If \fIoption\fR isn't specified, a list describing the current options for \fImarkerId\fR is returned. If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing \fIoption\fR is returned. If one or more \fIoption\fR and \fIvalue\fR pairs are specified, then for each pair, the marker option \fIoption\fR is set to \fIvalue\fR. .sp The following options are valid for all markers. Each type of marker also has its own type-specific options. They are described in the sections below. .RS .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for the marker. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events for markers are handled. Each tag in the list matching the current event sequence will have its Tcl command executed. Implicitly the name of the marker is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-coords \fIcoordList\fR Specifies the coordinates of the marker. \fICoordList\fR is a list of graph coordinates. The number of coordinates required is dependent on the type of marker. Text, image, and window markers need only two coordinates (an X\-Y coordinate). Bitmap markers can take either two or four coordinates (if four, they represent the corners of the bitmap). Line markers need at least four coordinates, polygons at least six. If \fIcoordList\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-element \fIelemName\fR Links the marker with the element \fIelemName\fR. The marker is drawn only if the element is also currently displayed (see the element's \fBshow\fR operation). If \fIelemName\fR is \f(CW""\fR, the marker is always drawn. The default is \f(CW""\fR. .TP \fB\-hide \fIboolean\fR Indicates whether the marker is drawn. If \fIboolean\fR is true, the marker is not drawn. The default is \f(CWno\fR. .TP \fB\-mapx \fIxAxis\fR Specifies the X\-axis to map the marker's X\-coordinates onto. \fIXAxis\fR must the name of an axis. The default is \f(CWx\fR. .TP \fB\-mapy \fIyAxis\fR Specifies the Y\-axis to map the marker's Y\-coordinates onto. \fIYAxis\fR must the name of an axis. The default is \f(CWy\fR. .TP \fB\-name \fImarkerId\fR Changes the identifier for the marker. The identifier \fImarkerId\fR can not already be used by another marker. If this option isn't specified, the marker's name is uniquely generated. .TP \fB\-under \fIboolean\fR Indicates whether the marker is drawn below/above data elements. If \fIboolean\fR is true, the marker is be drawn underneath the data element symbols and lines. Otherwise, the marker is drawn on top of the element. The default is \f(CW0\fR. .TP \fB\-xoffset \fIpixels\fR Specifies a screen distance to offset the marker horizontally. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .TP \fB\-yoffset \fIpixels\fR Specifies a screen distance to offset the markers vertically. \fIPixels\fR is a valid screen distance, such as \f(CW2\fR or \f(CW1.2i\fR. The default is \f(CW0\fR. .PP Marker configuration options may also be set by the \fBoption\fR command. The resource class is either \f(CWBitmapMarker\fR, \f(CWImageMarker\fR, \f(CWLineMarker\fR, \f(CWPolygonMarker\fR, \f(CWTextMarker\fR, or \f(CWWindowMarker\fR, depending on the type of marker. The resource name is the name of the marker. .CS option add *Graph.TextMarker.Foreground white option add *Graph.BitmapMarker.Foreground white option add *Graph.m1.Background blue .CE .RE .TP \fIpathName \fBmarker create \fItype\fR ?\fIoption value\fR?... Creates a marker of the selected type. \fIType\fR may be either \f(CWtext\fR, \f(CWline\fR, \f(CWbitmap\fR, \f(CWimage\fR, \f(CWpolygon\fR, or \f(CWwindow\fR. This command returns the marker identifier, used as the \fImarkerId\fR argument in the other marker-related commands. If the \fB\-name\fR option is used, this overrides the normal marker identifier. If the name provided is already used for another marker, the new marker will replace the old. .TP \fIpathName \fBmarker delete\fR ?\fIname\fR?... Removes one of more markers. The graph will automatically be redrawn without the marker.\fR. .TP \fIpathName \fBmarker exists \fImarkerId\fR Returns \f(CW1\fR if the marker \fImarkerId\fR exists and \f(CW0\fR otherwise. .TP \fIpathName \fBmarker names\fR ?\fIpattern\fR? Returns the names of all the markers that currently exist. If \fIpattern\fR is supplied, only those markers whose names match it will be returned. .TP \fIpathName \fBmarker type \fImarkerId\fR Returns the type of the marker given by \fImarkerId\fR, such as \f(CWline\fR or \f(CWtext\fR. If \fImarkerId\fR is not a valid a marker identifier, \f(CW""\fR is returned. .SS "BITMAP MARKERS" A bitmap marker displays a bitmap. The size of the bitmap is controlled by the number of coordinates specified. If two coordinates, they specify the position of the top-left corner of the bitmap. The bitmap retains its normal width and height. If four coordinates, the first and second pairs of coordinates represent the corners of the bitmap. The bitmap will be stretched or reduced as necessary to fit into the bounding rectangle. .PP Bitmap markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create bitmap \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration options for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to bitmap markers: .TP \fB\-background \fIcolor\fR Same as the \fB\-fill\fR option. .TP \fB\-bitmap \fIbitmap\fR Specifies the bitmap to be displayed. If \fIbitmap\fR is \f(CW""\fR, the marker will not be displayed. The default is \f(CW""\fR. .TP \fB\-fill \fIcolor\fR Sets the background color of the bitmap. If \fIcolor\fR is the empty string, no background will be transparent. The default background color is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Same as the \fB\-outline\fR option. .TP \fB\-mask \fImask\fR Specifies a mask for the bitmap to be displayed. This mask is a bitmap itself, denoting the pixels that are transparent. If \fImask\fR is \f(CW""\fR, all pixels of the bitmap will be drawn. The default is \f(CW""\fR. .TP \fB\-outline \fIcolor\fR Sets the foreground color of the bitmap. The default value is \f(CWblack\fR. .TP \fB\-rotate \fItheta\fR Sets the rotation of the bitmap. \fITheta\fR is a real number representing the angle of rotation in degrees. The marker is first rotated and then placed according to its anchor position. The default rotation is \f(CW0.0\fR. .SS "IMAGE MARKERS" A image marker displays an image. Image markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create image \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to image markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the image relative to the positioning point for the image. For example, if \fIanchor\fR is \f(CWcenter\fR then the image is centered on the point; if \fIanchor\fR is \f(CWn\fR then the image will be drawn such that the top center point of the rectangular region occupied by the image will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-image \fIimage\fR Specifies the image to be drawn. If \fIimage\fR is \f(CW""\fR, the marker will not be drawn. The default is \f(CW""\fR. .SS "LINE MARKERS" A line marker displays one or more connected line segments. Line markers are created with marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create line \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to line markers: .TP \fB\-dashes \fIdashList\fR Sets the dash style of the line. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the line. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the marker line will be solid. .TP \fB\-fill \fIcolor\fR Sets the background color of the line. This color is used with striped lines (see the \fB\-fdashes\fR option). If \fIcolor\fR is the empty string, no background color is drawn (the line will be dashed, not striped). The default background color is \f(CW""\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the lines. The default width is \f(CW0\fR. .TP \fB\-outline \fIcolor\fR Sets the foreground color of the line. The default value is \f(CWblack\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern used to draw the line, rather than a solid line. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the line is drawn in a solid fashion. The default is \f(CW""\fR. .SS "POLYGON MARKERS" A polygon marker displays a closed region described as two or more connected line segments. It is assumed the first and last points are connected. Polygon markers are created using the marker \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create polygon \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the \fBmarker configure\fR command to change the marker's configuration. The following options are supported for polygon markers: .TP \fB\-dashes \fIdashList\fR Sets the dash style of the outline of the polygon. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the outline. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line. .TP \fB\-fill \fIcolor\fR Sets the fill color of the polygon. If \fIcolor\fR is \f(CW""\fR, then the interior of the polygon is transparent. The default is \f(CWwhite\fR. .TP \fB\-linewidth \fIpixels\fR Sets the width of the outline of the polygon. If \fIpixels\fR is zero, no outline is drawn. The default is \f(CW0\fR. .TP \fB\-outline \fIcolor\fR Sets the color of the outline of the polygon. If the polygon is stippled (see the \fB\-stipple\fR option), then this represents the foreground color of the stipple. The default is \f(CWblack\fR. .TP \fB\-stipple \fIbitmap\fR Specifies that the polygon should be drawn with a stippled pattern rather than a solid color. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. If \fIbitmap\fR is \f(CW""\fR, then the polygon is filled with a solid color (if the \fB\-fill\fR option is set). The default is \f(CW""\fR. .SS "TEXT MARKERS" A text marker displays a string of characters on one or more lines of text. Embedded newlines cause line breaks. They may be used to annotate regions of the graph. Text markers are created with the \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create text \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the text marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR operation. .PP The following options are specific to text markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the text relative to the positioning point for the text. For example, if \fIanchor\fR is \f(CWcenter\fR then the text is centered on the point; if \fIanchor\fR is \f(CWn\fR then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This default is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Same as the \fB\-fill\fR option. .TP \fB\-font \fIfontName\fR Specifies the font of the text. The default is \f(CW*-Helvetica-Bold-R-Normal-*-120-*\fR. .TP \fB\-fill \fIcolor\fR Sets the background color of the text. If \fIcolor\fR is the empty string, no background will be transparent. The default background color is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Same as the \fB\-outline\fR option. .TP \fB\-justify \fIjustify\fR Specifies how the text should be justified. This matters only when the marker contains more than one line of text. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWcenter\fR. .TP \fB\-outline \fIcolor\fR Sets the color of the text. The default value is \f(CWblack\fR. .TP \fB\-padx \fIpad\fR Sets the padding to the left and right exteriors of the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the text is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW4\fR. .TP \fB\-pady \fIpad\fR Sets the padding above and below the text. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the area above the text is padded by the first distance and the area below by the second. If \fIpad\fR is just one distance, both the top and bottom areas are padded evenly. The default is \f(CW4\fR. .TP \fB\-rotate \fItheta\fR Specifies the number of degrees to rotate the text. \fITheta\fR is a real number representing the angle of rotation. The marker is first rotated along its center and is then drawn according to its anchor position. The default is \f(CW0.0\fR. .TP \fB\-text \fItext\fR Specifies the text of the marker. The exact way the text is displayed may be affected by other options such as \fB\-anchor\fR or \fB\-rotate\fR. .SS "WINDOW MARKERS" A window marker displays a widget at a given position. Window markers are created with the marker's \fBcreate\fR operation in the form: .DS \fIpathName \fBmarker create window \fR?\fIoption value\fR?... .DE There may be many \fIoption\fR-\fIvalue\fR pairs, each sets a configuration option for the marker. These same \fIoption\fR\-\fIvalue\fR pairs may be used with the marker's \fBconfigure\fR command. .PP The following options are specific to window markers: .TP \fB\-anchor \fIanchor\fR \fIAnchor\fR tells how to position the widget relative to the positioning point for the widget. For example, if \fIanchor\fR is \f(CWcenter\fR then the widget is centered on the point; if \fIanchor\fR is \f(CWn\fR then the widget will be displayed such that the top center point of the rectangular region occupied by the widget will be at the positioning point. This option defaults to \f(CWcenter\fR. .TP \fB\-height \fIpixels\fR Specifies the height to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever height the widget requests internally. .TP \fB\-width \fIpixels\fR Specifies the width to assign to the marker's window. If this option isn't specified, or if it is specified as \f(CW""\fR, then the window is given whatever width the widget requests internally. .TP \fB\-window \fIpathName\fR Specifies the widget to be managed by the graph. \fIPathName\fR must be a child of the \fBgraph\fR widget. .SH "GRAPH COMPONENT BINDINGS" Specific graph components, such as elements, markers and legend entries, can have a command trigger when event occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR). .PP Only one element or marker can be picked during an event. This means, that if the mouse is directly over both an element and a marker, only the uppermost component is selected. This isn't true for legend entries. Both a legend entry and an element (or marker) binding commands will be invoked if both items are picked. .PP It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the element name and another is associated with one of the element's tags (see the \fB\-bindtags\fR option). When this occurs, all of the matching bindings are invoked. A binding associated with the element name is invoked first, followed by one binding for each of the element's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. .PP The \fB\-bindtags\fR option for these components controls addition tag names which can be matched. Implicitly elements and markers always have tags matching their names. Setting the value of the \fB\-bindtags\fR option doesn't change this. .SH "C LANGUAGE API" You can manipulate data elements from the C language. There may be situations where it is too expensive to translate the data values from ASCII strings. Or you might want to read data in a special file format. .PP Data can manipulated from the C language using BLT vectors. You specify the X-Y data coordinates of an element as vectors and manipulate the vector from C. The graph will be redrawn automatically after the vectors are updated. .PP From Tcl, create the vectors and configure the element to use them. .CS vector X Y \&.g element configure line1 -xdata X -ydata Y .CE To set data points from C, you pass the values as arrays of doubles using the \fBBlt_ResetVector\fR call. The vector is reset with the new data and at the next idle point (when Tk re-enters its event loop), the graph will be redrawn automatically. .CS #include <tcl.h> #include <blt.h> register int i; Blt_Vector *xVec, *yVec; double x[50], y[50]; /* Get the BLT vectors "X" and "Y" (created above from Tcl) */ if ((Blt_GetVector(interp, "X", &xVec) != TCL_OK) || (Blt_GetVector(interp, "Y", &yVec) != TCL_OK)) { return TCL_ERROR; } for (i = 0; i < 50; i++) { x[i] = i * 0.02; y[i] = sin(x[i]); } /* Put the data into BLT vectors */ if ((Blt_ResetVector(xVec, x, 50, 50, TCL_VOLATILE) != TCL_OK) || (Blt_ResetVector(yVec, y, 50, 50, TCL_VOLATILE) != TCL_OK)) { return TCL_ERROR; } .CE See the \fBvector\fR manual page for more details. .SH SPEED TIPS There may be cases where the graph needs to be drawn and updated as quickly as possible. If drawing speed becomes a big problem, here are a few tips to speed up displays. .TP 2 \(bu Try to minimize the number of data points. The more data points the looked at, the more work the graph must do. .TP 2 \(bu If your data is generated as floating point values, the time required to convert the data values to and from ASCII strings can be significant, especially when there any many data points. You can avoid the redundant string-to-decimal conversions using the C API to BLT vectors. .TP 2 \(bu Data elements without symbols are drawn faster than with symbols. Set the data element's \fB\-symbol\fR option to \f(CWnone\fR. If you need to draw symbols, try using the simple symbols such as \f(CWsplus\fR and \f(CWscross\fR. .TP 2 \(bu Don't stipple or dash the element. Solid lines are much faster. .TP 2 \(bu If you update data elements frequently, try turning off the widget's \fB\-bufferelements\fR option. When the graph is first displayed, it draws data elements into an internal pixmap. The pixmap acts as a cache, so that when the graph needs to be redrawn again, and the data elements or coordinate axes haven't changed, the pixmap is simply copied to the screen. This is especially useful when you are using markers to highlight points and regions on the graph. But if the graph is updated frequently, changing either the element data or coordinate axes, the buffering becomes redundant. .SH LIMITATIONS Auto-scale routines do not use requested min/max limits as boundaries when the axis is logarithmically scaled. .PP The PostScript output generated for polygons with more than 1500 points may exceed the limits of some printers (See PostScript Language Reference Manual, page 568). The work-around is to break the polygon into separate pieces. .SH KEYWORDS graph, widget �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/tree.mann���������������������������������������������������������������������0000644�0001750�0001750�00000107715�11462120062�014636� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Lucent Technologies, Inc. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Tree command created by George Howlett. '\" .so man.macros .TH tree n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBtree\fR \- Create and manage tree data objects. .SH SYNOPSIS \fBblt::tree create \fR?\fItreeName\fR? .sp \fBblt::tree destroy\fR \fItreeName\fR... .sp \fBblt::tree names\fR \fR?\fIpattern\fR? .BE .SH DESCRIPTION The \fBtree\fR command creates tree data objects. A \fItree object\fR is general ordered tree of nodes. Each node has both a label and a key-value list of data. Data can be heterogeneous, since nodes do not have to contain the same data keys. It is associated with a Tcl command that you can use to access and modify the its structure and data. Tree objects can also be managed via a C API. .SH INTRODUCTION .SH EXAMPLE .SH SYNTAX .TP \fBblt::tree create\fR ?\fItreeName\fR? Creates a new tree object. The name of the new tree is returned. If no \fItreeName\fR argument is present, then the name of the tree is automatically generated in the form "\f(CWtree0\fR", "\f(CWtree1\fR", etc. If the substring "\f(CW#auto\fR" is found in \fItreeName\fR, it is automatically substituted by a generated name. For example, the name \f(CW.foo.#auto.bar\fR will be translated to \f(CW.foo.tree0.bar\fR. .sp A new Tcl command (by the same name as the tree) is also created. Another Tcl command or tree object can not already exist as \fItreeName\fR. If the Tcl command is deleted, the tree will also be freed. The new tree will contain just the root node. Trees are by default, created in the current namespace, not the global namespace, unless \fItreeName\fR contains a namespace qualifier, such as "\f(CWfred::myTree\fR". .TP \fBblt::tree destroy\fR \fItreeName\fR... Releases one of more trees. The Tcl command associated with \fItreeName\fR is also removed. Trees are reference counted. The internal tree data object isn't destroyed until no one else is using the tree. .TP \fBblt::tree names \fR?\fIpattern\fR? Returns the names of all tree objects. if a \fIpattern\fR argument is given, then the only those trees whose name matches pattern will be listed. .SH NODE IDS AND TAGS Nodes in a tree object may be referred in either of two ways: by id or by tag. Each node has a unique serial number or id that is assigned to that node when it's created. The id of an node never changes and id numbers are not re-used. .PP A node may also have any number of tags associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "\f(CWx123\fR" is valid, but "\f(CW123\fR" isn't. The same tag may be associated with many different nodes. This is commonly done to group nodes in various interesting ways. .sp There are two built-in tags: The tag \fBall\fR is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. The tag \fBroot\fR is managed automatically by the tree object. It applies to the node currently set as root. .sp When specifying nodes in tree object commands, if the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, then it is assumed to refer to all of the nodes in the tree that have a tag matching the specifier. The symbol \fInode\fR is used below to indicate that an argument specifies either an id that selects a single node or a tag that selects zero or more nodes. Many tree commands only operate on a single node at a time; if \fInode\fR is specified in a way that names multiple items, then an error "refers to more than one node" is generated. .SH NODE MODIFIERS You can also specify node in relation to another node by appending one or more modifiers to the node id or tag. A modifier refers to a node in relation to the specified node. For example, "\f(CWroot->firstchild\fR" selects the first subtree of the root node. .PP The following modifiers are available: .RS .TP 1i \fBfirstchild\fR Selects the first child of the node. .TP 1i \fBlastchild\fR Selects the last child of the node. .TP 1i \fBnext\fR Selects the next node in preorder to the node. .TP 1i \fBnextsibling\fR Selects the next sibling of the node. .TP 1i \fBparent\fR Selects the parent of the node. .TP 1i \fBprevious\fR Selects the previous node in preorder to the node. .TP 1i \fBprevsibling\fR Selects the previous sibling of the node. .TP 1i "\fIlabel\fR" Selects the node whose label is \fIlabel\fR. Enclosing \fIlabel\fR in quotes indicates to always search for a node by its label (for example, even if the node is labeled "parent"). .RE .sp It's an error the node can't be found. For example, \fBlastchild\fR and \fBfirstchild\fR will generate errors if the node has no children. The exception to this is the \fBindex\fR operation. You can use \fBindex\fR to test if a modifier is valid. .SH TREE OPERATIONS Once you create a tree object, you can use its Tcl command to query or modify it. The general form is .DS \fItreeName\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for trees are listed below. .TP \fItreeName\fR \fBancestor\fR \fInode1\fR \fInode2\fR Returns the mutual ancestor of the two nodes \fInode1\fR and \fInode2\fR. The ancestor can be one of the two nodes. For example, if \fInode1\fR and \fInode2\fR are the same nodes, their ancestor is \fInode1\fR. .TP \fItreeName\fR \fBapply\fR \fInode\fR ?\fIswitches\fR? Runs commands for all nodes matching the criteria given by \fIswitches\fR for the subtree designated by \fInode\fR. By default all nodes match, but you can set switches to narrow the match. This operation differs from \fBfind\fR in two ways: 1) Tcl commands can be invoked both pre- and post-traversal of a node and 2) the tree is always traversed in depth first order. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The valid switches are listed below: .RS .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR If pattern matching is selected (using the \fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern matching switches are set, then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP 1i \fB\-path\fR Use the node's full path when comparing nodes. The node's full path is a list of labels, starting from the root of each ancestor and the node itself. .TP 1i \fB\-precommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-postcommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP 1i \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItreeName\fR \fBattach\fR \fItreeObject\fR ?\fIswitches\fR? Attaches to an existing tree object \fItreeObject\fR. The current tree associated with \fItreeName\fR is discarded. In addition, the current set of tags, notifier events, and traces are removed. The valid \fIswitches\fR are listed below: .RS .TP \fB\-newtags\fR By default, the tree will share the tags of the attached tree. If this flag is present, the tree will start with an empty tag table. .RE .TP \fItreeName\fR \fBchildren\fR \fInode\fR Returns a list of children for \fInode\fR. If \fInode\fR is a leaf, then an empty string is returned. .TP \fItreeName\fR \fBcopy\fR \fIparent\fR ?\fItree\fR? \fInode\fR ?\fIswitches\fR? Copies \fInode\fR into \fIparent\fR. Both nodes \fInode\fR and \fIparent\fR must already exist. The id of the new node is returned. You can also copy nodes from another tree. If a \fItree\fR argument is present, it indicates the name of the source tree. The valid \fIswitches\fR are listed below: .RS .TP \fB\-label\fR \fIstring\fR Label \fIdestNode\fR as \fIstring\fR. By default, \fIdestNode\fR has the same label as \fIsrcNode\fR. .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .TP \fB\-recurse\fR Recursively copy all the subtrees of \fIsrcNode\fR as well. In this case, \fIsrcNode\fR can't be an ancestor of \fIdestNode\fR as it would result in a cyclic copy. .TP \fB\-tags\fR Copy tag inforation. Normally the following node is copied: its label and data fields. This indicates to copy tags as well. .RE .TP \fItreeName\fR \fBdegree\fR \fInode\fR Returns the number of children of \fInode\fR. .TP \fItreeName\fR \fBdelete\fR \fInode\fR... Recursively deletes one or more nodes from the tree. The node and all its descendants are removed. The one exception is the root node. In this case, only its descendants are removed. The root node will remain. Any tags or traces on the nodes are released. .TP \fItreeName\fR \fBdepth\fR \fInode\fR Returns the depth of the node. The depth is the number of steps from the node to the root of the tree. The depth of the root node is \f(CW0\fR. .TP \fItreeName\fR \fBdump\fR \fInode\fR Returns a list of the paths and respective data for \fInode\fR and its descendants. The subtree designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the tree with the \fBrestore\fR operation. .TP \fItreeName\fR \fBdumpfile\fR \fInode\fR \fIfileName\fR Writes a list of the paths and respective data for \fInode\fR and its descendants to the given file \fIfileName\fR. The subtree designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the tree with the \fBrestore\fR operation. .TP \fItreeName\fR \fBexists\fR \fInode\fR ?\fIkey\fR? Indicates if \fInode\fR exists in the tree. If a \fIkey\fR argument is present then the command also indicates if the named data field exists. .TP \fItreeName\fR \fBfind\fR \fInode\fR ?\fIswitches\fR? Finds for all nodes matching the criteria given by \fIswitches\fR for the subtree designated by \fInode\fR. A list of the selected nodes is returned. By default all nodes match, but you can set switches to narrow the match. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The order in which the nodes are traversed is controlled by the \fB\-order\fR switch. The possible orderings are \fBpreorder\fR, \fBpostorder\fR, \fBinorder\fR, and \fBbreadthfirst\fR. The default is \fBpostorder\fR. .sp The valid switches are listed below: .RS .TP 1i \fB\-addtag\fR \fIstring\fR Add the tag \fIstring\fR to each selected node. .TP 1i \fB\-count\fR \fInumber\fR Stop processing after \fInumber\fR (a positive integer) matches. .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-excludes\fR \fInodeList\fR Excludes any node in the list \fInodeList\fR from the search. The subnodes of an excluded node are still examined. .TP 1i \fB\-exec\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR Compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern is given (\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP \fB\-order\fR \fIstring\fR Traverse the tree and process nodes according to \fIstring\fR. \fIString\fR can be one of the following: .RS .TP 1i \fBbreadthfirst\fR Process the node and the subtrees at each sucessive level. Each node on a level is processed before going to the next level. .TP 1i \fBinorder\fR Recursively process the nodes of the first subtree, the node itself, and any the remaining subtrees. .TP 1i \fBpostorder\fR Recursively process all subtrees before the node. .TP 1i \fBpreorder\fR Recursively process the node first, then any subtrees. .RE .TP \fB\-path\fR Use the node's full path when comparing nodes. .TP \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItreeName\fR \fBfindchild\fR \fInode\fR \fIlabel\fR Searches for a child node \Ilabel\fR in \fInode\fR. The id of the child node is returned if found. Otherwise \f(CW-1\fR is returned. .TP \fItreeName\fR \fBfirstchild\fR \fInode\fR Returns the id of the first child in the \fInode\fR's list of subtrees. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBget\fR \fInode\fR ?\fIkey\fR? ?\fIdefaultValue\fR? Returns a list of key-value pairs of data for the node. If \fIkey\fR is present, then onlyx the value for that particular data field is returned. It's normally an error if \fInode\fR does not contain the data field \fIkey\fR. But if you provide a \fIdefaultValue\fR argument, this value is returned instead (\fInode\fR will still not contain \fIkey\fR). This feature can be used to access a data field of \fInode\fR without first testing if it exists. This operation may trigger \fBread\fR data traces. .TP \fItreeName\fR \fBindex\fR \fInode\fR Returns the id of \fInode\fR. If \fInode\fR is a tag, it can only specify one node. If \fInode\fR does not represent a valid node id or tag, or has modifiers that are invalid, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBinsert\fR \fIparent\fR ?\fIswitches\fR? Inserts a new node into parent node \fIparent\fR. The id of the new node is returned. The following switches are available: .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts the node into \fIparent\fR's list of children at position \fInumber\fR. The default is to append \fInode\fR. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-data\fR \fIdataList\fR Sets the value for each data field in \fIdataList\fR for the new node. \fIDataList\fR is a list of key-value pairs. .TP 1i \fB\-label\fR \fIstring\fR Designates the labels of the node as \fIstring\fR. By default, nodes are labeled as \f(CWnode0\fR, \f(CWnode1\fR, etc. .TP 1i \fB\-node\fR \fIid\fR Designates the id for the node. Normally new ids are automatically generated. This allows you to create a node with a specific id. It is an error if the id is already used by another node in the tree. .TP 1i \fB\-tags\fR \fItagList\fR Adds each tag in \fItagList\fR to the new node. \fITagList\fR is a list of tags, so be careful if a tag has embedded spaces. .RE .TP \fItreeName\fR \fBis\fR \fIproperty\fR \fIargs\fR Indicates the property of a node. Both \fIproperty\fR and \fIargs\fR determine the property being tested. Returns \f(CW1\fR if true and \f(CW0\fR otherwise. The following \fIproperty\fR and \fIargs\fR are valid: .RS .TP 1i \fBancestor\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is an ancestor of \fInode2\fR. .TP 1i \fBbefore\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is before \fInode2\fR in depth first traversal. .TP 1i \fBleaf\fR \fInode\fR Indicates if \fInode\fR is a leaf (it has no subtrees). .TP 1i \fBroot\fR \fInode\fR Indicates if \fInode\fR is the designated root. This can be changed by the \fBroot\fR operation. .RE .TP \fItreeName\fR \fBlabel\fR \fInode\fR ?\fInewLabel\fR? Returns the label of the node designated by \fInode\fR. If \fInewLabel\fR is present, the node is relabeled using it as the new label. .TP \fItreeName\fR \fBlastchild\fR \fInode\fR Returns the id of the last child in the \fInode\fR's list of subtrees. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBmove\fR \fInode\fR \fInewParent\fR ?\fIswitches\fR? Moves \fInode\fR into \fInewParent\fR. \fINode\fR is appended to the list children of \fInewParent\fR. \fINode\fR can not be an ancestor of \fInewParent\fR. The valid flags for \fIswitches\fR are described below. .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts \fInode\fR into \fIparent\fR's list of children at position \fInumber\fR. The default is to append the node. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .RE .TP \fItreeName\fR \fBnext\fR \fInode\fR Returns the next node from \fInode\fR in a preorder traversal. If \fInode\fR is the last node in the tree, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBnextsibling\fR \fInode\fR Returns the node representing the next subtree from \fInode\fR in its parent's list of children. If \fInode\fR is the last child, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBnotify\fR \fIargs\fR Manages notification events that indicate that the tree structure has been changed. See the .SB "NOTIFY OPERATIONS" section below. .TP \fItreeName\fR \fBparent\fR \fInode\fR Returns the parent node of \fInode\fR. If \fInode\fR is the root of the tree, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBpath\fR \fInode\fR Returns the full path (from root) of \fInode\fR. .TP \fItreeName\fR \fBposition\fR \fInode\fR Returns the position of the node in its parent's list of children. Positions are numbered from 0. The position of the root node is always 0. .TP \fItreeName\fR \fBprevious\fR \fInode\fR Returns the previous node from \fInode\fR in a preorder traversal. If \fInode\fR is the root of the tree, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBprevsibling\fR \fInode\fR Returns the node representing the previous subtree from \fInode\fR in its parent's list of children. If \fInode\fR is the first child, then \f(CW-1\fR is returned. .TP \fItreeName\fR \fBrestore\fR \fInode\fR \fIdataString\fR \fIswitches\fR Performs the inverse function of the \fBdump\fR operation, restoring nodes to the tree. The format of \fIdataString\fR is exactly what is returned by the \fBdump\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItreeName\fR \fBrestorefile\fR \fInode\fR \fIfileName\fR \fIswitches\fR Performs the inverse function of the \fBdumpfile\fR operation, restoring nodes to the tree from the file \fIfileName\fR. The format of \fIfileName\fR is exactly what is returned by the \fBdumpfile\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItreeName\fR \fBroot\fR ?\fInode\fR? Returns the id of the root node. Normally this is node \f(CW0\fR. If a \fInode\fR argument is provided, it will become the new root of the tree. This lets you temporarily work within a subset of the tree. Changing root affects operations such as \fBnext\fR, \fBpath\fR, \fBprevious\fR, etc. .TP \fItreeName\fR \fBset\fR \fInode\fR \fIkey value\fR ?\fIkey value\fR...? Sets one or more data fields in \fInode\fR. \fINode\fR may be a tag that represents several nodes. \fIKey\fR is the name of the data field to be set and \fIvalue\fR is its respective value. This operation may trigger \fBwrite\fR and \fBcreate\fR data traces. .TP \fItreeName\fR \fBsize\fR \fInode\fR Returns the number of nodes in the subtree. This includes the node and all its descendants. The size of a leaf node is 1. .TP \fItreeName\fR \fBsort\fR \fInode\fR ?\fIswitches\fR? .RS .TP 1i \fB\-ascii\fR Compare strings using the ASCII collation order. .TP 1i \fB\-command\fR \fIstring\fR Use command \fIstring\fR as a comparison command. To compare two elements, evaluate a Tcl script consisting of command with the two elements appended as additional arguments. The script should return an integer less than, equal to, or greater than zero if the first element is to be considered less than, equal to, or greater than the second, respectively. .TP 1i \fB\-decreasing\fR Sort in decreasing order (largest items come first). .TP 1i \fB\-dictionary\fR Compare strings using a dictionary-style comparison. This is the same as \fB\-ascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, in \fB\-dictionary\fR mode, bigBoy sorts between bigbang and bigboy, and x10y sorts between x9y and x11y. .TP 1i \fB\-integer\fR Compare the nodes as integers. .TP 1i \fB\-key\fR \fIstring\fR Sort based upon the node's data field keyed by \fIstring\fR. Normally nodes are sorted according to their label. .TP 1i \fB\-path\fR Compare the full path of each node. The default is to compare only its label. .TP 1i \fB\-real\fR Compare the nodes as real numbers. .TP 1i \fB\-recurse\fR Recursively sort the entire subtree rooted at \fInode\fR. .TP 1i \fB\-reorder\fR Recursively sort subtrees for each node. \fBWarning\fR. Unlike the normal flat sort, where a list of nodes is returned, this will reorder the tree. .RE .TP \fItreeName\fR \fBtag\fR \fIargs\fR Manages tags for the tree object. See the .SB "TAG OPERATIONS" section below. .TP \fItreeName\fR \fBtrace\fR \fIargs\fR Manages traces for data fields in the tree object. Traces cause Tcl commands to be executed whenever a data field of a node is created, read, written, or unset. Traces can be set for a specific node or a tag, representing possibly many nodes. See the .SB "TRACE OPERATIONS" section below. .TP \fItreeName\fR \fBunset\fR \fInode\fR \fIkey\fR... Removes one or more data fields from \fInode\fR. \fINode\fR may be a tag that represents several nodes. \fIKey\fR is the name of the data field to be removed. It's not an error is \fInode\fR does not contain \fIkey\fR. This operation may trigger \fBunset\fR data traces. .RE .SH TAG OPERATIONS Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. .sp There are two built-in tags: The tag \fBall\fR is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. The tag \fBroot\fR is managed automatically by the tree object. It specifies the node that is currently set as the root of the tree. .sp Most tree operations use tags. And several operations let you operate on multiple nodes at once. For example, you can use the \fBset\fR operation with the tag \fBall\fR to set a data field in for all nodes in the tree. .PP Tags are invoked by the \fBtag\fR operation. The general form is .DS \fItreeName\fR \fBtag\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tags are listed below. .TP \fItreeName\fR \fBtag add\fR \fIstring\fR \fInode\fR... Adds the tag \fIstring\fR to one of more nodes. .TP \fItreeName\fR \fBtag delete\fR \fIstring\fR \fInode\fR... Deletes the tag \fIstring\fR from one or more nodes. .TP \fItreeName\fR \fBtag forget\fR \fIstring\fR Removes the tag \fIstring\fR from all nodes. It's not an error if no nodes are tagged as \fIstring\fR. .TP \fItreeName\fR \fBtag get\fR \fInode\fR \fIpattern\fR... Returns the tag names for a given node. If one of more pattern arguments are provided, then only those matching tags are returned. .TP \fItreeName\fR \fBtag names\fR ?\fInode\fR? Returns a list of tags used by the tree. If a \fInode\fR argument is present, only those tags used by \fInode\fR are returned. .TP \fItreeName\fR \fBtag nodes\fR \fIstring\fR Returns a list of nodes that have the tag \fIstring\fR. If no node is tagged as \fIstring\fR, then an empty string is returned. .TP \fItreeName\fR \fBtag set\fR \fInode\fR \fIstring\fR... Sets one or more tags for a given node. Tag names can't start with a digit (to distinquish them from node ids) and can't be a reserved tag ("root" or "all"). .TP \fItreeName\fR \fBtag unset\fR \fInode\fR \fIstring\fR... Removes one or more tags from a given node. Tag names that don't exist or are reserved ("root" or "all") are silently ignored. .SH TRACE OPERATIONS Data fields can be traced much in the same way that you can trace Tcl variables. Data traces cause Tcl commands to be executed whenever a particular data field of a node is created, read, written, or unset. A trace can apply to one or more nodes. You can trace a specific node by using its id, or a group of nodes by a their tag. .PP The tree's \fBget\fR, \fBset\fR, and \fBunset\fR operations can trigger various traces. The \fBget\fR operation can cause a \fIread\fR trace to fire. The \fBset\fR operation causes a \fIwrite\fR trace to fire. And if the data field is written for the first time, you will also get a \fIcreate\fR trace. The \fBunset\fR operation triggers \fIunset\fR traces. .PP Data traces are invoked by the \fBtrace\fR operation. The general form is .DS \fItreeName\fR \fBtrace\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for traces are listed below. .TP \fItreeName\fR \fBtrace create\fR \fInode\fR \fIkey\fR \fIops\fR \fIcommand\fR Creates a trace for \fInode\fR on data field \fIkey\fR. \fINode\fR can refer to more than one node (for example, the tag \fBall\fR). If \fInode\fR is a tag, any node with that tag can possibly trigger a trace, invoking \fIcommand\fR. \fICommand\fR is command prefix, typically a procedure name. Whenever a trace is triggered, four arguments are appended to \fIcommand\fR before it is invoked: \fItreeName\fR, id of the node, \fIkey\fR and, \fIops\fR. Note that no nodes need have the field \fIkey\fR. A trace identifier in the form "\f(CWtrace0\fR", "\f(CWtrace1\fR", etc. is returned. .sp \fIOps\fR indicates which operations are of interest, and consists of one or more of the following letters: .RS .TP \fBr\fR Invoke \fIcommand\fR whenever \fIkey\fR is read. Both read and write traces are temporarily disabled when \fIcommand\fR is executed. .TP \fBw\fR Invoke \fIcommand\fR whenever \fIkey\fR is written. Both read and write traces are temporarily disabled when \fIcommand\fR is executed. .TP \fBc\fR Invoke \fIcommand\fR whenever \fIkey\fR is created. .TP \fBu\fR Invoke \fIcommand\fR whenever \fIkey\fR is unset. Data fields are typically unset with the \fBunset\fR command. Data fields are also unset when the tree is released, but all traces are disabled prior to that. .sp .RE .TP \fItreeName\fR \fBtrace delete\fR \fItraceId\fR... Deletes one of more traces. \fITraceId\fR is the trace identifier returned by the \fBtrace create\fR operation. .TP \fItreeName\fR \fBtrace info\fR \fItraceId\fR Returns information about the trace \fItraceId\fR. \fITraceId\fR is a trace identifier previously returned by the \fBtrace create\fR operation. It's the same information specified for the \fBtrace create\fR operation. It consists of the node id or tag, data field key, a string of letters indicating the operations that are traced (it's in the same form as \fIops\fR) and, the command prefix. .TP \fItreeName\fR \fBtrace names\fR Returns a list of identifers for all the current traces. .SH NOTIFY OPERATIONS Tree objects can be shared among many clients, such as a \fBhiertable\fR widget. Any client can create or delete nodes, sorting the tree, etc. You can request to be notified whenever these events occur. Notify events cause Tcl commands to be executed whenever the tree structure is changed. .PP Notifications are handled by the \fBnotify\fR operation. The general form is .DS \fItreeName\fR \fBnotify\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for events are listed below. .TP \fItreeName\fR \fBnotify create\fR ?\fIswitches\fR? \fIcommand\fR \fR?\fIargs\fR?... Creates a notifier for the tree. A notify identifier in the form "\f(CWnotify0\fR", "\f(CWnotify1\fR", etc. is returned. .sp \fICommand\fR and \fIargs\fR are saved and invoked whenever the tree structure is changed (according to \fIswitches\fR). Two arguments are appended to \fIcommand\fR and \fIargs\fR before it's invoked: the id of the node and a string representing the type of event that occured. One of more switches can be set to indicate the events that are of interest. The valid switches are as follows: .RS .TP 1i \fB\-create\fR Invoke \fIcommand\fR whenever a new node has been added. .TP 1i \fB\-delete\fR Invoke \fIcommand\fR whenever a node has been deleted. .TP 1i \fB\-move\fR Invoke \fIcommand\fR whenever a node has been moved. .TP 1i \fB\-sort\fR Invoke \fIcommand\fR whenever the tree has been sorted and reordered. .TP 1i \fB\-relabel\fR Invoke \fIcommand\fR whenever a node has been relabeled. .TP 1i \fB\-allevents\fR Invoke \fIcommand\fR whenever any of the above events occur. .TP 1i \fB\-whenidle\fR When an event occurs don't invoke \fIcommand\fR immediately, but queue it to be run the next time the event loop is entered and there are no events to process. If subsequent events occur before the event loop is entered, \fIcommand\fR will still be invoked only once. .RE .TP \fItreeName\fR \fBnotify delete\fR \fInotifyId\fR Deletes one or more notifiers from the tree. \fINotifyId\fR is the notifier identifier returned by the \fBnotify create\fR operation. .TP \fItreeName\fR \fBnotify info\fR \fInotifyId\fR Returns information about the notify event \fInotifyId\fR. \fINotifyId\fR is a notify identifier previously returned by the \fBnotify create\fR operation. It's the same information specified for the \fBnotify create\fR operation. It consists of the notify id, a sublist of event flags (it's in the same form as \fIflags\fR) and, the command prefix. .TP \fItreeName\fR \fBnotify names\fR Returns a list of identifers for all the current notifiers. .SH C LANGUAGE API Blt_TreeApply, Blt_TreeApplyBFS, Blt_TreeApplyDFS, Blt_TreeChangeRoot, Blt_TreeCreate, Blt_TreeCreateEventHandler, Blt_TreeCreateNode, Blt_TreeCreateTrace, Blt_TreeDeleteEventHandler, Blt_TreeDeleteNode, Blt_TreeDeleteTrace, Blt_TreeExists, Blt_TreeFindChild, Blt_TreeFirstChild, Blt_TreeFirstKey, Blt_TreeGetNode, Blt_TreeGetToken, Blt_TreeGetValue, Blt_TreeIsAncestor, Blt_TreeIsBefore, Blt_TreeIsLeaf, Blt_TreeLastChild, Blt_TreeMoveNode, Blt_TreeName, Blt_TreeNextKey, Blt_TreeNextNode, Blt_TreeNextSibling, Blt_TreeNodeDegree, Blt_TreeNodeDepth, Blt_TreeNodeId, Blt_TreeNodeLabel, Blt_TreeNodeParent, Blt_TreePrevNode, Blt_TreePrevSibling, Blt_TreeRelabelNode, Blt_TreeReleaseToken, Blt_TreeRootNode, Blt_TreeSetValue, Blt_TreeSize, Blt_TreeSortNode, and Blt_TreeUnsetValue. .SH KEYWORDS tree, hiertable, widget ���������������������������������������������������./saods9/blt3.0.1/man/datatable.mann����������������������������������������������������������������0000644�0001750�0001750�00000165564�11462120062�015626� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� '\" '\" Copyright 1991-1997 by Lucent Technologies, Inc. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Datatable command created by George Howlett. '\" .so man.macros .TH datatable n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBdatatable\fR \- Create and manage table data objects. .SH SYNOPSIS \fBblt::datatable create \fR?\fItableName\fR? .sp \fBblt::datatable destroy\fR \fItableName\fR... .sp \fBblt::datatable names\fR \fR?\fIpattern\fR? .BE .SH DESCRIPTION The \fBdatatable\fR command creates table data objects. A \fItable object\fR is general ordered tree of nodes. Each node has both a label and a key-value list of data. Data can be heterogeneous, since nodes do not have to contain the same data keys. It is associated with a Tcl command that you can use to access and modify the its structure and data. Table objects can also be managed via a C API. .SH INTRODUCTION .SH EXAMPLE .SH SYNTAX .TP \fBblt::datatable create\fR ?\fItableName\fR? Creates a new table object. The name of the new table is returned. If no \fItableName\fR argument is present, then the name of the table is automatically generated in the form "\f(CWdatatable0\fR", "\f(CWdatatable1\fR", etc. If the substring "\f(CW#auto\fR" is found in \fItableName\fR, it is automatically substituted by a generated name. For example, the name \f(CW.foo.#auto.bar\fR will be translated to \f(CW.foo.datatable0.bar\fR. .sp A new Tcl command (by the same name as the table) is also created. Another Tcl command or table object can not already exist as \fItableName\fR. If the Tcl command is deleted, the table will also be freed. The new table will contain no rows or columns. Tables are by default, created in the current namespace, not the global namespace, unless \fItableName\fR contains a namespace qualifier, such as "\f(CWfred::myTable\fR". .TP \fBblt::datatable destroy\fR \fItableName\fR... Deletes one of more tables. The Tcl command associated with \fItableName\fR is also removed. If the table is currently shared (another client is using it), the table data isn't destroyed until no one else is using it. .TP \fBblt::datatable names \fR?\fIpattern\fR? Returns the names of all table objects. if a \fIpattern\fR argument is given, then the only those tables whose name matches pattern will be listed. .SH ROW/COLUMN IDENTIFIERS Rows and columns in a table object may be identified by either an index, label, or tag. .SS INDEX An index is the position of the row/column. Row/column indices start from one (not zero). Indices may change if rows/columns are inserted, deleted, or sorted. .SS LABEL A label is a string of characters that identifies a row or column. A label may reference more than one row or column. It is up to the programmer to maintain unique labels. For example, if two columns have the same label, only the first column may be accessed using that label. Row and column labels are distinct. Labels do not change if other rows/columns are inserted, deleted, or sorted. Labels can not start with a "-". .SS TAG A row/column may also have any number of tags associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "\f(CWx123\fR" is valid, but "\f(CW123\fR" isn't. The same tag may be associated with many different rows/columns. This is commonly done to group rows/columns in various interesting ways. .sp There are two built-in tags: The tag \fBall\fR is implicitly associated with every row/column in the table. It may be used to invoke operations on all the rows/columns in the table. The tag \fBend\fR is managed automatically by the table object. It applies to the last row/column. .sp When specifying nodes in table object commands, if the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, then it is assumed to refer to all of the nodes in the table that have a tag matching the specifier. The symbol \fInode\fR is used below to indicate that an argument specifies either an id that selects a single node or a tag that selects zero or more nodes. Many table commands only operate on a single node at a time; if \fInode\fR is specified in a way that names multiple items, then an error "refers to more than one node" is generated. .SH NODE MODIFIERS You can also specify node in relation to another node by appending one or more modifiers to the node id or tag. A modifier refers to a node in relation to the specified node. For example, "\f(CWroot->firstchild\fR" selects the first subtree of the root node. .PP The following modifiers are available: .RS .TP 1i \fBfirstchild\fR Selects the first child of the node. .TP 1i \fBlastchild\fR Selects the last child of the node. .TP 1i \fBnext\fR Selects the next node in preorder to the node. .TP 1i \fBnextsibling\fR Selects the next sibling of the node. .TP 1i \fBparent\fR Selects the parent of the node. .TP 1i \fBprevious\fR Selects the previous node in preorder to the node. .TP 1i \fBprevsibling\fR Selects the previous sibling of the node. .TP 1i "\fIlabel\fR" Selects the node whose label is \fIlabel\fR. Enclosing \fIlabel\fR in quotes indicates to always search for a node by its label (for example, even if the node is labeled "parent"). .RE .sp It's an error the node can't be found. For example, \fBlastchild\fR and \fBfirstchild\fR will generate errors if the node has no children. The exception to this is the \fBindex\fR operation. You can use \fBindex\fR to test if a modifier is valid. .SH TABLE OPERATIONS Once you create a table object, you can use its Tcl command to query or modify it. The general form is .DS \fItableName\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tables are listed below. .TP \fItableName\fR \fBarray\fR \fBexists\fR \fIrow\fR \fIcol\fR \fIkey\fR Indicates if \fIkey\fR exists in the array element located at the given row and column position in the table. If \fIrow\fR is not a valid row identifier, \fIcol\fR is not a valid column identifier, or \fIkey\fR is not a valid key for the array, then \f(CW0\fR is returned, otherwise \f(CW1\fR. .TP \fItableName\fR \fBarray\fR \fBget\fR \fIrow\fR \fIcol\fR \fIkey\fR ?\fIdefValue\fR? Returns the value associated with \fIkey\fR in the array located at the given row and column position in the table. It's normally an error if \fIrow\fR is not a valid row identifier, \fIcol\fR is not a valid column identifier, or \fIkey\fR is not a valid key for the array. But if you provide a \fIdefValue\fR argument, this value is will be returned instead. This operation may trigger \fBread\fR traces. .TP \fItableName\fR \fBarray\fR \fBnames\fR \fIrow\fR \fIcol\fR Returns a list of the current keys in the array located at the given row and column position in the table. It is an error \fIrow\fR is not a valid row identifier or \fIcol\fR is not a valid column identifier. .TP \fItableName\fR \fBarray\fR \fBset\fR \fIrow\fR \fIcol\fR \fIkey\fR \fIvalue\fR Sets the value to the array element associated with \fIkey\fR located at the given row and column position in the table. If either \fIrow\fR or \fIcolumn\fR do not exist, they will be automatically created (they must be a label or index). If \fIkey\fR doesn't exist, a new entry in the array be created. This operation may trigger \fBwrite\fR traces. .TP \fItableName\fR \fBarray\fR \fBunset\fR \fIrow\fR \fIcol\fR \fIkey\fR... Unsets the value to the array element associated with \fIkey\fR located at the given row and column position in the table. It's an error if either \fIrow\fR or \fIcolumn\fR do not exist. This operation may trigger \fBunset\fR traces. .TP \fItableName\fR \fBapply\fR \fInode\fR ?\fIswitches\fR? Runs commands for all nodes matching the criteria given by \fIswitches\fR for the subtree designated by \fInode\fR. By default all nodes match, but you can set switches to narrow the match. This operation differs from \fBfind\fR in two ways: 1) Tcl commands can be invoked both pre- and post-traversal of a node and 2) the table is always traversed in depth first order. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The valid switches are listed below: .RS .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR If pattern matching is selected (using the \fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern matching switches are set, then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP 1i \fB\-path\fR Use the node's full path when comparing nodes. The node's full path is a list of labels, starting from the root of each ancestor and the node itself. .TP 1i \fB\-precommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-postcommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP 1i \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItableName\fR \fBattach\fR \fItableObject\fR ?\fIswitches\fR? Attaches to an existing table object \fItableObject\fR. The current table associated with \fItableName\fR is discarded. In addition, the current set of tags, notifier events, and traces are removed. The valid \fIswitches\fR are listed below: .RS .TP \fB\-newtags\fR By default, the table will share the tags of the attached table. If this flag is present, the table will start with an empty tag table. .RE .TP \fItableName\fR \fBchildren\fR \fInode\fR Returns a list of children for \fInode\fR. If \fInode\fR is a leaf, then an empty string is returned. .TP \fItableName\fR \fBcopy\fR \fIparent\fR ?\fItable\fR? \fInode\fR ?\fIswitches\fR? Copies \fInode\fR into \fIparent\fR. Both nodes \fInode\fR and \fIparent\fR must already exist. The id of the new node is returned. You can also copy nodes from another table. If a \fItable\fR argument is present, it indicates the name of the source table. The valid \fIswitches\fR are listed below: .RS .TP \fB\-label\fR \fIstring\fR Label \fIdestNode\fR as \fIstring\fR. By default, \fIdestNode\fR has the same label as \fIsrcNode\fR. .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .TP \fB\-recurse\fR Recursively copy all the subtables of \fIsrcNode\fR as well. In this case, \fIsrcNode\fR can't be an ancestor of \fIdestNode\fR as it would result in a cyclic copy. .TP \fB\-tags\fR Copy tag inforation. Normally the following node is copied: its label and data fields. This indicates to copy tags as well. .RE .TP \fItableName\fR \fBdegree\fR \fInode\fR Returns the number of children of \fInode\fR. .TP \fItableName\fR \fBdelete\fR \fInode\fR... Recursively deletes one or more nodes from the table. The node and all its descendants are removed. The one exception is the root node. In this case, only its descendants are removed. The root node will remain. Any tags or traces on the nodes are released. .TP \fItableName\fR \fBdepth\fR \fInode\fR Returns the depth of the node. The depth is the number of steps from the node to the root of the table. The depth of the root node is \f(CW0\fR. .TP \fItableName\fR \fBdump\fR \fInode\fR Returns a list of the paths and respective data for \fInode\fR and its descendants. The subtable designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the table with the \fBrestore\fR operation. .TP \fItableName\fR \fBdumpfile\fR \fInode\fR \fIfileName\fR Writes a list of the paths and respective data for \fInode\fR and its descendants to the given file \fIfileName\fR. The subtable designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the table with the \fBrestore\fR operation. .TP \fItableName\fR \fBexists\fR \fInode\fR ?\fIkey\fR? Indicates if \fInode\fR exists in the table. If a \fIkey\fR argument is present then the command also indicates if the named data field exists. .TP \fItableName\fR \fBfind\fR \fInode\fR ?\fIswitches\fR? Finds for all nodes matching the criteria given by \fIswitches\fR for the subtable designated by \fInode\fR. A list of the selected nodes is returned. By default all nodes match, but you can set switches to narrow the match. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The order in which the nodes are traversed is controlled by the \fB\-order\fR switch. The possible orderings are \fBpreorder\fR, \fBpostorder\fR, \fBinorder\fR, and \fBbreadthfirst\fR. The default is \fBpostorder\fR. .sp The valid switches are listed below: .RS .TP 1i \fB\-addtag\fR \fIstring\fR Add the tag \fIstring\fR to each selected node. .TP 1i \fB\-count\fR \fInumber\fR Stop processing after \fInumber\fR (a positive integer) matches. .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-excludes\fR \fInodeList\fR Excludes any node in the list \fInodeList\fR from the search. The subnodes of an excluded node are still examined. .TP 1i \fB\-exec\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtable and continues on the next. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR Compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern is given (\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP \fB\-order\fR \fIstring\fR Traverse the table and process nodes according to \fIstring\fR. \fIString\fR can be one of the following: .RS .TP 1i \fBbreadthfirst\fR Process the node and the subtables at each sucessive level. Each node on a level is processed before going to the next level. .TP 1i \fBinorder\fR Recursively process the nodes of the first subtable, the node itself, and any the remaining subtables. .TP 1i \fBpostorder\fR Recursively process all subtables before the node. .TP 1i \fBpreorder\fR Recursively process the node first, then any subtables. .RE .TP \fB\-path\fR Use the node's full path when comparing nodes. .TP \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItableName\fR \fBfindchild\fR \fInode\fR \fIlabel\fR Searches for a child node \Ilabel\fR in \fInode\fR. The id of the child node is returned if found. Otherwise \f(CW-1\fR is returned. .TP \fItableName\fR \fBfirstchild\fR \fInode\fR Returns the id of the first child in the \fInode\fR's list of subtables. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItableName\fR \fBget\fR \fInode\fR ?\fIkey\fR? ?\fIdefaultValue\fR? Returns a list of key-value pairs of data for the node. If \fIkey\fR is present, then only the value for that particular data field is returned. It's normally an error if \fInode\fR does not contain the data field \fIkey\fR. But if you provide a \fIdefaultValue\fR argument, this value is returned instead (\fInode\fR will still not contain \fIkey\fR). This feature can be used to access a data field of \fInode\fR without first testing if it exists. This operation may trigger \fBread\fR data traces. .TP \fItableName\fR \fBindex\fR \fInode\fR Returns the id of \fInode\fR. If \fInode\fR is a tag, it can only specify one node. If \fInode\fR does not represent a valid node id or tag, or has modifiers that are invalid, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBinsert\fR \fIparent\fR ?\fIswitches\fR? Inserts a new node into parent node \fIparent\fR. The id of the new node is returned. The following switches are available: .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts the node into \fIparent\fR's list of children at position \fInumber\fR. The default is to append \fInode\fR. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-data\fR \fIdataList\fR Sets the value for each data field in \fIdataList\fR for the new node. \fIDataList\fR is a list of key-value pairs. .TP 1i \fB\-label\fR \fIstring\fR Designates the labels of the node as \fIstring\fR. By default, nodes are labeled as \f(CWnode0\fR, \f(CWnode1\fR, etc. .TP 1i \fB\-node\fR \fIid\fR Designates the id for the node. Normally new ids are automatically generated. This allows you to create a node with a specific id. It is an error if the id is already used by another node in the table. .TP 1i \fB\-tags\fR \fItagList\fR Adds each tag in \fItagList\fR to the new node. \fITagList\fR is a list of tags, so be careful if a tag has embedded spaces. .RE .TP \fItableName\fR \fBis\fR \fIproperty\fR \fIargs\fR Indicates the property of a node. Both \fIproperty\fR and \fIargs\fR determine the property being tested. Returns \f(CW1\fR if true and \f(CW0\fR otherwise. The following \fIproperty\fR and \fIargs\fR are valid: .RS .TP 1i \fBancestor\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is an ancestor of \fInode2\fR. .TP 1i \fBbefore\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is before \fInode2\fR in depth first traversal. .TP 1i \fBleaf\fR \fInode\fR Indicates if \fInode\fR is a leaf (it has no subtables). .TP 1i \fBroot\fR \fInode\fR Indicates if \fInode\fR is the designated root. This can be changed by the \fBroot\fR operation. .RE .TP \fItableName\fR \fBlabel\fR \fInode\fR ?\fInewLabel\fR? Returns the label of the node designated by \fInode\fR. If \fInewLabel\fR is present, the node is relabeled using it as the new label. .TP \fItableName\fR \fBlastchild\fR \fInode\fR Returns the id of the last child in the \fInode\fR's list of subtables. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItableName\fR \fBmove\fR \fInode\fR \fInewParent\fR ?\fIswitches\fR? Moves \fInode\fR into \fInewParent\fR. \fINode\fR is appended to the list children of \fInewParent\fR. \fINode\fR can not be an ancestor of \fInewParent\fR. The valid flags for \fIswitches\fR are described below. .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts \fInode\fR into \fIparent\fR's list of children at position \fInumber\fR. The default is to append the node. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .RE .TP \fItableName\fR \fBnext\fR \fInode\fR Returns the next node from \fInode\fR in a preorder traversal. If \fInode\fR is the last node in the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBnextsibling\fR \fInode\fR Returns the node representing the next subtable from \fInode\fR in its parent's list of children. If \fInode\fR is the last child, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBnotify\fR \fIargs\fR Manages notification events that indicate that the table structure has been changed. See the .SB "NOTIFY OPERATIONS" section below. .TP \fItableName\fR \fBparent\fR \fInode\fR Returns the parent node of \fInode\fR. If \fInode\fR is the root of the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBpath\fR \fInode\fR Returns the full path (from root) of \fInode\fR. .TP \fItableName\fR \fBposition\fR \fInode\fR Returns the position of the node in its parent's list of children. Positions are numbered from 0. The position of the root node is always 0. .TP \fItableName\fR \fBprevious\fR \fInode\fR Returns the previous node from \fInode\fR in a preorder traversal. If \fInode\fR is the root of the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBprevsibling\fR \fInode\fR Returns the node representing the previous subtable from \fInode\fR in its parent's list of children. If \fInode\fR is the first child, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBrestore\fR \fInode\fR \fIdataString\fR \fIswitches\fR Performs the inverse function of the \fBdump\fR operation, restoring nodes to the table. The format of \fIdataString\fR is exactly what is returned by the \fBdump\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItableName\fR \fBrestorefile\fR \fInode\fR \fIfileName\fR \fIswitches\fR Performs the inverse function of the \fBdumpfile\fR operation, restoring nodes to the table from the file \fIfileName\fR. The format of \fIfileName\fR is exactly what is returned by the \fBdumpfile\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItableName\fR \fBroot\fR ?\fInode\fR? Returns the id of the root node. Normally this is node \f(CW0\fR. If a \fInode\fR argument is provided, it will become the new root of the table. This lets you temporarily work within a subset of the table. Changing root affects operations such as \fBnext\fR, \fBpath\fR, \fBprevious\fR, etc. .TP \fItableName\fR \fBset\fR \fInode\fR \fIkey value\fR ?\fIkey value\fR...? Sets one or more data fields in \fInode\fR. \fINode\fR may be a tag that represents several nodes. \fIKey\fR is the name of the data field to be set and \fIvalue\fR is its respective value. This operation may trigger \fBwrite\fR and \fBcreate\fR data traces. .TP \fItableName\fR \fBsize\fR \fInode\fR Returns the number of nodes in the subtable. This includes the node and all its descendants. The size of a leaf node is 1. .TP \fItableName\fR \fBsort\fR \fInode\fR ?\fIswitches\fR? .RS .TP 1i \fB\-ascii\fR Compare strings using the ASCII collation order. .TP 1i \fB\-command\fR \fIstring\fR Use command \fIstring\fR as a comparison command. To compare two elements, evaluate a Tcl script consisting of command with the two elements appended as additional arguments. The script should return an integer less than, equal to, or greater than zero if the first element is to be considered less than, equal to, or greater than the second, respectively. .TP 1i \fB\-decreasing\fR Sort in decreasing order (largest items come first). .TP 1i \fB\-dictionary\fR Compare strings using a dictionary-style comparison. This is the same as \fB\-ascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, in \fB\-dictionary\fR mode, bigBoy sorts between bigbang and bigboy, and x10y sorts between x9y and x11y. .TP 1i \fB\-integer\fR Compare the nodes as integers. .TP 1i \fB\-key\fR \fIstring\fR Sort based upon the node's data field keyed by \fIstring\fR. Normally nodes are sorted according to their label. .TP 1i \fB\-path\fR Compare the full path of each node. The default is to compare only its label. .TP 1i \fB\-real\fR Compare the nodes as real numbers. .TP 1i \fB\-recurse\fR Recursively sort the entire subtable rooted at \fInode\fR. .TP 1i \fB\-reorder\fR Recursively sort subtables for each node. \fBWarning\fR. Unlike the normal flat sort, where a list of nodes is returned, this will reorder the table. .RE .TP \fItableName\fR \fBtag\fR \fIargs\fR Manages tags for the table object. See the .SH TABLE OPERATIONS Once you create a table object, you can use its Tcl command to query or modify it. The general form is .DS \fItableName\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tables are listed below. .TP \fItableName\fR \fBancestor\fR \fInode1\fR \fInode2\fR Returns the mutual ancestor of the two nodes \fInode1\fR and \fInode2\fR. The ancestor can be one of the two nodes. For example, if \fInode1\fR and \fInode2\fR are the same nodes, their ancestor is \fInode1\fR. .TP \fItableName\fR \fBapply\fR \fInode\fR ?\fIswitches\fR? Runs commands for all nodes matching the criteria given by \fIswitches\fR for the subtree designated by \fInode\fR. By default all nodes match, but you can set switches to narrow the match. This operation differs from \fBfind\fR in two ways: 1) Tcl commands can be invoked both pre- and post-traversal of a node and 2) the table is always traversed in depth first order. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The valid switches are listed below: .RS .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR If pattern matching is selected (using the \fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern matching switches are set, then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP 1i \fB\-path\fR Use the node's full path when comparing nodes. The node's full path is a list of labels, starting from the root of each ancestor and the node itself. .TP 1i \fB\-precommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-postcommand\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtree and continues on the next. .TP 1i \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP 1i \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItableName\fR \fBattach\fR \fItableObject\fR ?\fIswitches\fR? Attaches to an existing table object \fItableObject\fR. The current table associated with \fItableName\fR is discarded. In addition, the current set of tags, notifier events, and traces are removed. The valid \fIswitches\fR are listed below: .RS .TP \fB\-newtags\fR By default, the table will share the tags of the attached table. If this flag is present, the table will start with an empty tag table. .RE .TP \fItableName\fR \fBchildren\fR \fInode\fR Returns a list of children for \fInode\fR. If \fInode\fR is a leaf, then an empty string is returned. .TP \fItableName\fR \fBcopy\fR \fIparent\fR ?\fItable\fR? \fInode\fR ?\fIswitches\fR? Copies \fInode\fR into \fIparent\fR. Both nodes \fInode\fR and \fIparent\fR must already exist. The id of the new node is returned. You can also copy nodes from another table. If a \fItable\fR argument is present, it indicates the name of the source table. The valid \fIswitches\fR are listed below: .RS .TP \fB\-label\fR \fIstring\fR Label \fIdestNode\fR as \fIstring\fR. By default, \fIdestNode\fR has the same label as \fIsrcNode\fR. .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .TP \fB\-recurse\fR Recursively copy all the subtables of \fIsrcNode\fR as well. In this case, \fIsrcNode\fR can't be an ancestor of \fIdestNode\fR as it would result in a cyclic copy. .TP \fB\-tags\fR Copy tag inforation. Normally the following node is copied: its label and data fields. This indicates to copy tags as well. .RE .TP \fItableName\fR \fBdegree\fR \fInode\fR Returns the number of children of \fInode\fR. .TP \fItableName\fR \fBdelete\fR \fInode\fR... Recursively deletes one or more nodes from the table. The node and all its descendants are removed. The one exception is the root node. In this case, only its descendants are removed. The root node will remain. Any tags or traces on the nodes are released. .TP \fItableName\fR \fBdepth\fR \fInode\fR Returns the depth of the node. The depth is the number of steps from the node to the root of the table. The depth of the root node is \f(CW0\fR. .TP \fItableName\fR \fBdump\fR \fInode\fR Returns a list of the paths and respective data for \fInode\fR and its descendants. The subtable designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the table with the \fBrestore\fR operation. .TP \fItableName\fR \fBdumpfile\fR \fInode\fR \fIfileName\fR Writes a list of the paths and respective data for \fInode\fR and its descendants to the given file \fIfileName\fR. The subtable designated by \fInode\fR is traversed returning the following information for each node: 1) the node's path relative to \fInode\fR, 2) a sublist key value pairs representing the node's data fields, and 3) a sublist of tags. This list returned can be used later to copy or restore the table with the \fBrestore\fR operation. .TP \fItableName\fR \fBexists\fR \fInode\fR ?\fIkey\fR? Indicates if \fInode\fR exists in the table. If a \fIkey\fR argument is present then the command also indicates if the named data field exists. .TP \fItableName\fR \fBfind\fR \fInode\fR ?\fIswitches\fR? Finds for all nodes matching the criteria given by \fIswitches\fR for the subtable designated by \fInode\fR. A list of the selected nodes is returned. By default all nodes match, but you can set switches to narrow the match. .sp The \fB\-exact\fR, \fB\-glob\fR, and \fB\-regexp\fR switches indicate both what kind of pattern matching to perform and the pattern. By default each pattern will be compared with the node label. You can set more than one of these switches. If any of the patterns match (logical or), the node matches. If the \fB\-key\fR switch is used, it designates the data field to be matched. .sp The order in which the nodes are traversed is controlled by the \fB\-order\fR switch. The possible orderings are \fBpreorder\fR, \fBpostorder\fR, \fBinorder\fR, and \fBbreadthfirst\fR. The default is \fBpostorder\fR. .sp The valid switches are listed below: .RS .TP 1i \fB\-addtag\fR \fIstring\fR Add the tag \fIstring\fR to each selected node. .TP 1i \fB\-count\fR \fInumber\fR Stop processing after \fInumber\fR (a positive integer) matches. .TP 1i \fB\-depth\fR \fInumber\fR Descend at most \fInumber\fR (a non-negative integer) levels If \fInumber\fR is \f(CW1\fR this means only apply the tests to the children of \fInode\fR. .TP 1i \fB\-exact\fR \fIstring\fR Matches each node using \fIstring\fR. The node must match \fIstring\fR exactly. .TP 1i \fB\-excludes\fR \fInodeList\fR Excludes any node in the list \fInodeList\fR from the search. The subnodes of an excluded node are still examined. .TP 1i \fB\-exec\fR \fIcommand\fR Invoke \fIcommand\fR for each matching node. Before \fIcommand\fR is invoked, the id of the node is appended. You can control processing by the return value of \fIcommand\fR. If \fIcommand\fR generates an error, processing stops and the \fBfind\fR operation returns an error. But if \fIcommand\fR returns \fBbreak\fR, then processing stops, no error is generated. If \fIcommand\fR returns \fBcontinue\fR, then processing stops on that subtable and continues on the next. .TP 1i \fB\-glob\fR \fIstring\fR Test each node to \fIstring\fR using global pattern matching. Matching is done in a fashion similar to that used by the C-shell. .TP 1i \fB\-invert\fR Select non-matching nodes. Any node that \fIdoesn't\fR match the given criteria will be selected. .TP 1i \fB\-key\fR \fIkey\fR Compare the values of the data field keyed by \fIkey\fR instead of the node's label. If no pattern is given (\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR switches), then any node with this data key will match. .TP 1i \fB\-leafonly\fR Only test nodes with no children. .TP 1i \fB\-nocase\fR Ignore case when matching patterns. .TP \fB\-order\fR \fIstring\fR Traverse the table and process nodes according to \fIstring\fR. \fIString\fR can be one of the following: .RS .TP 1i \fBbreadthfirst\fR Process the node and the subtables at each sucessive level. Each node on a level is processed before going to the next level. .TP 1i \fBinorder\fR Recursively process the nodes of the first subtable, the node itself, and any the remaining subtables. .TP 1i \fBpostorder\fR Recursively process all subtables before the node. .TP 1i \fBpreorder\fR Recursively process the node first, then any subtables. .RE .TP \fB\-path\fR Use the node's full path when comparing nodes. .TP \fB\-regexp\fR \fIstring\fR Test each node using \fIstring\fR as a regular expression pattern. .TP \fB\-tag\fR \fIstring\fR Only test nodes that have the tag \fIstring\fR. .RE .TP \fItableName\fR \fBfindchild\fR \fInode\fR \fIlabel\fR Searches for a child node \Ilabel\fR in \fInode\fR. The id of the child node is returned if found. Otherwise \f(CW-1\fR is returned. .TP \fItableName\fR \fBfirstchild\fR \fInode\fR Returns the id of the first child in the \fInode\fR's list of subtables. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItableName\fR \fBget\fR \fInode\fR ?\fIkey\fR? ?\fIdefaultValue\fR? Returns a list of key-value pairs of data for the node. If \fIkey\fR is present, then onlyx the value for that particular data field is returned. It's normally an error if \fInode\fR does not contain the data field \fIkey\fR. But if you provide a \fIdefaultValue\fR argument, this value is returned instead (\fInode\fR will still not contain \fIkey\fR). This feature can be used to access a data field of \fInode\fR without first testing if it exists. This operation may trigger \fBread\fR data traces. .TP \fItableName\fR \fBindex\fR \fInode\fR Returns the id of \fInode\fR. If \fInode\fR is a tag, it can only specify one node. If \fInode\fR does not represent a valid node id or tag, or has modifiers that are invalid, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBinsert\fR \fIparent\fR ?\fIswitches\fR? Inserts a new node into parent node \fIparent\fR. The id of the new node is returned. The following switches are available: .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts the node into \fIparent\fR's list of children at position \fInumber\fR. The default is to append \fInode\fR. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fIparent\fR. .TP 1i \fB\-data\fR \fIdataList\fR Sets the value for each data field in \fIdataList\fR for the new node. \fIDataList\fR is a list of key-value pairs. .TP 1i \fB\-label\fR \fIstring\fR Designates the labels of the node as \fIstring\fR. By default, nodes are labeled as \f(CWnode0\fR, \f(CWnode1\fR, etc. .TP 1i \fB\-node\fR \fIid\fR Designates the id for the node. Normally new ids are automatically generated. This allows you to create a node with a specific id. It is an error if the id is already used by another node in the table. .TP 1i \fB\-tags\fR \fItagList\fR Adds each tag in \fItagList\fR to the new node. \fITagList\fR is a list of tags, so be careful if a tag has embedded spaces. .RE .TP \fItableName\fR \fBis\fR \fIproperty\fR \fIargs\fR Indicates the property of a node. Both \fIproperty\fR and \fIargs\fR determine the property being tested. Returns \f(CW1\fR if true and \f(CW0\fR otherwise. The following \fIproperty\fR and \fIargs\fR are valid: .RS .TP 1i \fBancestor\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is an ancestor of \fInode2\fR. .TP 1i \fBbefore\fR \fInode1\fR \fInode2\fR Indicates if \fInode1\fR is before \fInode2\fR in depth first traversal. .TP 1i \fBleaf\fR \fInode\fR Indicates if \fInode\fR is a leaf (it has no subtables). .TP 1i \fBroot\fR \fInode\fR Indicates if \fInode\fR is the designated root. This can be changed by the \fBroot\fR operation. .RE .TP \fItableName\fR \fBlabel\fR \fInode\fR ?\fInewLabel\fR? Returns the label of the node designated by \fInode\fR. If \fInewLabel\fR is present, the node is relabeled using it as the new label. .TP \fItableName\fR \fBlastchild\fR \fInode\fR Returns the id of the last child in the \fInode\fR's list of subtables. If \fInode\fR is a leaf (has no children), then \f(CW-1\fR is returned. .TP \fItableName\fR \fBmove\fR \fInode\fR \fInewParent\fR ?\fIswitches\fR? Moves \fInode\fR into \fInewParent\fR. \fINode\fR is appended to the list children of \fInewParent\fR. \fINode\fR can not be an ancestor of \fInewParent\fR. The valid flags for \fIswitches\fR are described below. .RS .TP 1i \fB\-after\fR \fIchild\fR Position \fInode\fR after \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .TP 1i \fB\-at\fR \fInumber\fR Inserts \fInode\fR into \fIparent\fR's list of children at position \fInumber\fR. The default is to append the node. .TP 1i \fB\-before\fR \fIchild\fR Position \fInode\fR before \fIchild\fR. The node \fIchild\fR must be a child of \fInewParent\fR. .RE .TP \fItableName\fR \fBnext\fR \fInode\fR Returns the next node from \fInode\fR in a preorder traversal. If \fInode\fR is the last node in the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBnextsibling\fR \fInode\fR Returns the node representing the next subtable from \fInode\fR in its parent's list of children. If \fInode\fR is the last child, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBnotify\fR \fIargs\fR Manages notification events that indicate that the table structure has been changed. See the .SB "NOTIFY OPERATIONS" section below. .TP \fItableName\fR \fBparent\fR \fInode\fR Returns the parent node of \fInode\fR. If \fInode\fR is the root of the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBpath\fR \fInode\fR Returns the full path (from root) of \fInode\fR. .TP \fItableName\fR \fBposition\fR \fInode\fR Returns the position of the node in its parent's list of children. Positions are numbered from 0. The position of the root node is always 0. .TP \fItableName\fR \fBprevious\fR \fInode\fR Returns the previous node from \fInode\fR in a preorder traversal. If \fInode\fR is the root of the table, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBprevsibling\fR \fInode\fR Returns the node representing the previous subtable from \fInode\fR in its parent's list of children. If \fInode\fR is the first child, then \f(CW-1\fR is returned. .TP \fItableName\fR \fBrestore\fR \fInode\fR \fIdataString\fR \fIswitches\fR Performs the inverse function of the \fBdump\fR operation, restoring nodes to the table. The format of \fIdataString\fR is exactly what is returned by the \fBdump\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItableName\fR \fBrestorefile\fR \fInode\fR \fIfileName\fR \fIswitches\fR Performs the inverse function of the \fBdumpfile\fR operation, restoring nodes to the table from the file \fIfileName\fR. The format of \fIfileName\fR is exactly what is returned by the \fBdumpfile\fR operation. It's a list containing information for each node to be restored. The information consists of 1) the relative path of the node, 2) a sublist of key value pairs representing the node's data, and 3) a list of tags for the node. Nodes are created starting from \fInode\fR. Nodes can be listed in any order. If a node's path describes ancestor nodes that do not already exist, they are automatically created. The valid \fIswitches\fR are listed below: .RS .TP \fB\-overwrite\fR Overwrite nodes that already exist. Normally nodes are always created, even if there already exists a node by the same name. This switch indicates to add or overwrite the node's data fields. .RE .TP \fItableName\fR \fBroot\fR ?\fInode\fR? Returns the id of the root node. Normally this is node \f(CW0\fR. If a \fInode\fR argument is provided, it will become the new root of the table. This lets you temporarily work within a subset of the table. Changing root affects operations such as \fBnext\fR, \fBpath\fR, \fBprevious\fR, etc. .TP \fItableName\fR \fBset\fR \fInode\fR \fIkey value\fR ?\fIkey value\fR...? Sets one or more data fields in \fInode\fR. \fINode\fR may be a tag that represents several nodes. \fIKey\fR is the name of the data field to be set and \fIvalue\fR is its respective value. This operation may trigger \fBwrite\fR and \fBcreate\fR data traces. .TP \fItableName\fR \fBsize\fR \fInode\fR Returns the number of nodes in the subtable. This includes the node and all its descendants. The size of a leaf node is 1. .TP \fItableName\fR \fBsort\fR \fInode\fR ?\fIswitches\fR? .RS .TP 1i \fB\-ascii\fR Compare strings using the ASCII collation order. .TP 1i \fB\-command\fR \fIstring\fR Use command \fIstring\fR as a comparison command. To compare two elements, evaluate a Tcl script consisting of command with the two elements appended as additional arguments. The script should return an integer less than, equal to, or greater than zero if the first element is to be considered less than, equal to, or greater than the second, respectively. .TP 1i \fB\-decreasing\fR Sort in decreasing order (largest items come first). .TP 1i \fB\-dictionary\fR Compare strings using a dictionary-style comparison. This is the same as \fB\-ascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, in \fB\-dictionary\fR mode, bigBoy sorts between bigbang and bigboy, and x10y sorts between x9y and x11y. .TP 1i \fB\-integer\fR Compare the nodes as integers. .TP 1i \fB\-key\fR \fIstring\fR Sort based upon the node's data field keyed by \fIstring\fR. Normally nodes are sorted according to their label. .TP 1i \fB\-path\fR Compare the full path of each node. The default is to compare only its label. .TP 1i \fB\-real\fR Compare the nodes as real numbers. .TP 1i \fB\-recurse\fR Recursively sort the entire subtable rooted at \fInode\fR. .TP 1i \fB\-reorder\fR Recursively sort subtables for each node. \fBWarning\fR. Unlike the normal flat sort, where a list of nodes is returned, this will reorder the table. .RE .TP \fItableName\fR \fBtag\fR \fIargs\fR Manages tags for the table object. See the .SB "TAG OPERATIONS" section below. .TP \fItableName\fR \fBtrace\fR \fIargs\fR Manages traces for data fields in the table object. Traces cause Tcl commands to be executed whenever a data field of a node is created, read, written, or unset. Traces can be set for a specific node or a tag, representing possibly many nodes. See the .SB "TRACE OPERATIONS" section below. .TP \fItableName\fR \fBunset\fR \fInode\fR \fIkey\fR... Removes one or more data fields from \fInode\fR. \fINode\fR may be a tag that represents several nodes. \fIKey\fR is the name of the data field to be removed. It's not an error is \fInode\fR does not contain \fIkey\fR. This operation may trigger \fBunset\fR data traces. .RE .SH TAG OPERATIONS Tags are a general means of selecting and marking nodes in the table. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. .sp There are two built-in tags: The tag \fBall\fR is implicitly associated with every node in the table. It may be used to invoke operations on all the nodes in the table. The tag \fBroot\fR is managed automatically by the table object. It specifies the node that is currently set as the root of the table. .sp Most table operations use tags. And several operations let you operate on multiple nodes at once. For example, you can use the \fBset\fR operation with the tag \fBall\fR to set a data field in for all nodes in the table. .PP Tags are invoked by the \fBtag\fR operation. The general form is .DS \fItableName\fR \fBtag\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tags are listed below. .TP \fItableName\fR \fBtag add\fR \fIstring\fR \fInode\fR... Adds the tag \fIstring\fR to one of more nodes. .TP \fItableName\fR \fBtag delete\fR \fIstring\fR \fInode\fR... Deletes the tag \fIstring\fR from one or more nodes. .TP \fItableName\fR \fBtag forget\fR \fIstring\fR Removes the tag \fIstring\fR from all nodes. It's not an error if no nodes are tagged as \fIstring\fR. .TP \fItableName\fR \fBtag get\fR \fInode\fR \fIpattern\fR... Returns the tag names for a given node. If one of more pattern arguments are provided, then only those matching tags are returned. .TP \fItableName\fR \fBtag names\fR ?\fInode\fR? Returns a list of tags used by the table. If a \fInode\fR argument is present, only those tags used by \fInode\fR are returned. .TP \fItableName\fR \fBtag nodes\fR \fIstring\fR Returns a list of nodes that have the tag \fIstring\fR. If no node is tagged as \fIstring\fR, then an empty string is returned. .TP \fItableName\fR \fBtag set\fR \fInode\fR \fIstring\fR... Sets one or more tags for a given node. Tag names can't start with a digit (to distinquish them from node ids) and can't be a reserved tag ("root" or "all"). .TP \fItableName\fR \fBtag unset\fR \fInode\fR \fIstring\fR... Removes one or more tags from a given node. Tag names that don't exist or are reserved ("root" or "all") are silently ignored. .SH TRACE OPERATIONS Data fields can be traced much in the same way that you can trace Tcl variables. Data traces cause Tcl commands to be executed whenever a particular data field of a node is created, read, written, or unset. A trace can apply to one or more nodes. You can trace a specific node by using its id, or a group of nodes by a their tag. .PP The table's \fBget\fR, \fBset\fR, and \fBunset\fR operations can trigger various traces. The \fBget\fR operation can cause a \fIread\fR trace to fire. The \fBset\fR operation causes a \fIwrite\fR trace to fire. And if the data field is written for the first time, you will also get a \fIcreate\fR trace. The \fBunset\fR operation triggers \fIunset\fR traces. .PP Data traces are invoked by the \fBtrace\fR operation. The general form is .DS \fItableName\fR \fBtrace\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for traces are listed below. .TP \fItableName\fR \fBtrace create\fR \fInode\fR \fIkey\fR \fIops\fR \fIcommand\fR Creates a trace for \fInode\fR on data field \fIkey\fR. \fINode\fR can refer to more than one node (for example, the tag \fBall\fR). If \fInode\fR is a tag, any node with that tag can possibly trigger a trace, invoking \fIcommand\fR. \fICommand\fR is command prefix, typically a procedure name. Whenever a trace is triggered, four arguments are appended to \fIcommand\fR before it is invoked: \fItableName\fR, id of the node, \fIkey\fR and, \fIops\fR. Note that no nodes need have the field \fIkey\fR. A trace identifier in the form "\f(CWtrace0\fR", "\f(CWtrace1\fR", etc. is returned. .sp \fIOps\fR indicates which operations are of interest, and consists of one or more of the following letters: .RS .TP \fBr\fR Invoke \fIcommand\fR whenever \fIkey\fR is read. Both read and write traces are temporarily disabled when \fIcommand\fR is executed. .TP \fBw\fR Invoke \fIcommand\fR whenever \fIkey\fR is written. Both read and write traces are temporarily disabled when \fIcommand\fR is executed. .TP \fBc\fR Invoke \fIcommand\fR whenever \fIkey\fR is created. .TP \fBu\fR Invoke \fIcommand\fR whenever \fIkey\fR is unset. Data fields are typically unset with the \fBunset\fR command. Data fields are also unset when the table is released, but all traces are disabled prior to that. .sp .RE .TP \fItableName\fR \fBtrace delete\fR \fItraceId\fR... Deletes one of more traces. \fITraceId\fR is the trace identifier returned by the \fBtrace create\fR operation. .TP \fItableName\fR \fBtrace info\fR \fItraceId\fR Returns information about the trace \fItraceId\fR. \fITraceId\fR is a trace identifier previously returned by the \fBtrace create\fR operation. It's the same information specified for the \fBtrace create\fR operation. It consists of the node id or tag, data field key, a string of letters indicating the operations that are traced (it's in the same form as \fIops\fR) and, the command prefix. .TP \fItableName\fR \fBtrace names\fR Returns a list of identifers for all the current traces. .SH NOTIFY OPERATIONS Table objects can be shared among many clients, such as a \fBhiertable\fR widget. Any client can create or delete nodes, sorting the table, etc. You can request to be notified whenever these events occur. Notify events cause Tcl commands to be executed whenever the table structure is changed. .PP Notifications are handled by the \fBnotify\fR operation. The general form is .DS \fItableName\fR \fBnotify\fR \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for events are listed below. .TP \fItableName\fR \fBnotify create\fR ?\fIswitches\fR? \fIcommand\fR \fR?\fIargs\fR?... Creates a notifier for the table. A notify identifier in the form "\f(CWnotify0\fR", "\f(CWnotify1\fR", etc. is returned. .sp \fICommand\fR and \fIargs\fR are saved and invoked whenever the table structure is changed (according to \fIswitches\fR). Two arguments are appended to \fIcommand\fR and \fIargs\fR before it's invoked: the id of the node and a string representing the type of event that occured. One of more switches can be set to indicate the events that are of interest. The valid switches are as follows: .RS .TP 1i \fB\-create\fR Invoke \fIcommand\fR whenever a new node has been added. .TP 1i \fB\-delete\fR Invoke \fIcommand\fR whenever a node has been deleted. .TP 1i \fB\-move\fR Invoke \fIcommand\fR whenever a node has been moved. .TP 1i \fB\-sort\fR Invoke \fIcommand\fR whenever the table has been sorted and reordered. .TP 1i \fB\-relabel\fR Invoke \fIcommand\fR whenever a node has been relabeled. .TP 1i \fB\-allevents\fR Invoke \fIcommand\fR whenever any of the above events occur. .TP 1i \fB\-whenidle\fR When an event occurs don't invoke \fIcommand\fR immediately, but queue it to be run the next time the event loop is entered and there are no events to process. If subsequent events occur before the event loop is entered, \fIcommand\fR will still be invoked only once. .RE .TP \fItableName\fR \fBnotify delete\fR \fInotifyId\fR Deletes one or more notifiers from the table. \fINotifyId\fR is the notifier identifier returned by the \fBnotify create\fR operation. .TP \fItableName\fR \fBnotify info\fR \fInotifyId\fR Returns information about the notify event \fInotifyId\fR. \fINotifyId\fR is a notify identifier previously returned by the \fBnotify create\fR operation. It's the same information specified for the \fBnotify create\fR operation. It consists of the notify id, a sublist of event flags (it's in the same form as \fIflags\fR) and, the command prefix. .TP \fItableName\fR \fBnotify names\fR Returns a list of identifers for all the current notifiers. .SH C LANGUAGE API Blt_Dt_Apply, Blt_Dt_ApplyBFS, Blt_Dt_ApplyDFS, Blt_Dt_ChangeRoot, Blt_Dt_Create, Blt_Dt_CreateEventHandler, Blt_Dt_CreateNode, Blt_Dt_CreateTrace, Blt_Dt_DeleteEventHandler, Blt_Dt_DeleteNode, Blt_Dt_DeleteTrace, Blt_Dt_Exists, Blt_Dt_FindChild, Blt_Dt_FirstChild, Blt_Dt_FirstKey, Blt_Dt_GetNode, Blt_Dt_GetToken, Blt_Dt_GetValue, Blt_Dt_IsAncestor, Blt_Dt_IsBefore, Blt_Dt_IsLeaf, Blt_Dt_LastChild, Blt_Dt_MoveNode, Blt_Dt_Name, Blt_Dt_NextKey, Blt_Dt_NextNode, Blt_Dt_NextSibling, Blt_Dt_NodeDegree, Blt_Dt_NodeDepth, Blt_Dt_NodeId, Blt_Dt_NodeLabel, Blt_Dt_NodeParent, Blt_Dt_PrevNode, Blt_Dt_PrevSibling, Blt_Dt_RelabelNode, Blt_Dt_ReleaseToken, Blt_Dt_RootNode, Blt_Dt_SetValue, Blt_Dt_Size, Blt_Dt_SortNode, and Blt_Dt_UnsetValue. .SH KEYWORDS table, hiertable, widget ��������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/container.mann����������������������������������������������������������������0000644�0001750�0001750�00000032021�11462120062�015644� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Container widget created by George Howlett. '\" .so man.macros.in .TH container n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME container \- Widget to contain a foreign window. .BE .SH SYNOPSIS \fBcontainer\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBcontainer\fR widget lets you embed an X11 window from a foreign application into your Tk application. The foreign window is reparented inside of the widget. You can then place and arrange the container just as you would any Tk widget. .SH INTRODUCTION Notebooks are a popular graphical paradigm. They allow you to organize many windows in a single widget. For example, you might have an application the displays several X-Y graphs at the same time. Typically, you can't pack the graphs into the same \fBframe\fR because they are too large. The other alternative is to pack the graphs into several \fBtoplevel\fR widgets, allowing them to overlap on the screen. The problem is that all the different toplevel windows clutter the screen and are difficult to manage. .PP The \fBcontainer\fR widget lets organize your application by displaying each graph as a page in a folder of a notebook. Only one page is visible at a time. When you click on a tab, the folder (graph) corresponding to the tab is displayed in the \fBcontainer\fR widget. The container also lets you temporarily tear pages out of the notebook into a separate toplevel widget, and put them back in the container later. For example, you could compare two graphs side-by-side by tearing them out, and then replace them when you are finished. .PP A container may contain an unlimited number of folders. If there are too many tabs to view, you can arrange them as multiple tiers or scroll the tabs. The container uses the conventional Tk scrollbar syntax, so you can attach a scrollbar too. .SH EXAMPLE You create a container widget with the \fBcontainer\fR command. .CS # Create a new container container .c .CE A new Tcl command \f(CW.c\fR is also created. This command can be used to query and modify the container. For example, to change the default borderwidth, you use the new command and the container's \fBconfigure\fR operation. .CS # Change the default font. \&.c configure \-borderwidth 2 .CE You can then add folders using the \fBinsert\fR operation. .CS # Create a new folder "f1" \&.c coinsert 0 "f1" .CE This inserts the new tab named "f1" into the container. The index \f(CW0\fR indicates location to insert the new tab. You can also use the index \f(CWend\fR to append a tab to the end of the container. By default, the text of the tab is the name of the tab. You can change this by configuring the \fB\-text\fR option. .CS # Change the label of "f1" \&.ts tab configure "f1" -label "Tab #1" .CE The \fBinsert\fR operation lets you add one or more folders at a time. .CS \&.ts insert end "f2" -label "Tab #2" "f3" "f4" .CE The tab on each folder contains a label. A label may display both an image and a text string. You can reconfigure the tab's attributes (foreground/background colors, font, rotation, etc) using the \fBtab configure\fR operation. .CS # Add an image to the label of "f1" set image [image create photo -file stopsign.gif] \&.ts tab configure "f1" -image $image \&.ts tab configure "f2" -rotate 90 .CE Each folder may contain an embedded widget to represent its contents. The widget to be embedded must be a child of the container widget. Using the \fB\-window\fR option, you specify the name of widget to be embedded. But don't pack the widget, the container takes care of placing and arranging the widget for you. .CS graph .ts.graph \&.ts tab configure "f1" -window ".ts.graph" \\ -fill both -padx 0.25i -pady 0.25i .CE The size of the folder is determined the sizes of the Tk widgets embedded inside each folder. The folder will be as wide as the widest widget in any folder. The tallest determines the height. You can use the tab's \fB\-pagewidth\fR and \fB\-pageheight\fR options override this. .PP Other options control how the widget appears in the folder. The \fB\-fill\fR option says that you wish to have the widget stretch to fill the available space in the folder. .CS \&.ts tab configure "f1" -fill both -padx 0.25i -pady 0.25i .CE .PP Now when you click the left mouse button on "f1", the graph will be displayed in the folder. It will be automatically hidden when another folder is selected. If you click on the right mouse button, the embedded widget will be moved into a toplevel widget of its own. Clicking again on the right mouse button puts it back into the folder. .PP If you want to share a page between two different folders, the \fB\-command\fR option lets you specify a Tcl command to be invoked whenever the folder is selected. You can reset the \fB\-window\fR option for the tab whenever it's clicked. .CS \&.ts tab configure "f2" -command { \&.ts tab configure "f2" -window ".ts.graph" } \&.ts tab configure "f1" -command { \&.ts tab configure "f1" -window ".ts.graph" } .CE If you have many folders, you may wish to stack tabs in multiple tiers. The container's \fB\-tiers\fR option requests a maximum number of tiers. The default is one tier. .CS \&.ts configure -tiers 2 .CE If the tabs can fit in less tiers, the widget will use that many. Whenever there are more tabs than can be displayed in the maximum number of tiers, the container will automatically let you scroll the tabs. You can even attach a scrollbar to the container. .CS \&.ts configure -scrollcommand { .sbar set } -scrollincrement 20 \&.sbar configure -orient horizontal -command { .ts view } .CE By default tabs are along the top of the container from left to right. But tabs can be placed on any side of the container using the \fB\-side\fR option. .CS # Arrange tabs along the right side of the container. \&.ts configure -side right -rotate 270 .CE .SH SYNTAX The \fBcontainer\fR command creates a new window using the \fIpathName\fR argument and makes it into a container widget. .CS \fBcontainer \fIpathName \fR?\fIoption value\fR?... .CE Additional options may be specified on the command line or in the option database to configure aspects of the container such as its colors, font, text, and relief. The \fBcontainer\fR command returns its \fIpathName\fR argument. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. .PP When first created, a new container contains no tabs. Tabs are added or deleted using widget operations described below. It is not necessary for all the tabs to be displayed in the container window at once; commands described below may be used to change the view in the window. Containers allow scrolling of tabs using the \fB\-scrollcommand\fR option. They also support scanning (see the \fBscan\fR operation). Tabs may be arranged along any side of the container window using the \fB\-side\fR option. .PP The size of the container window is determined the number of tiers of tabs and the sizes of the Tk widgets embedded inside each folder. The widest widget determines the width of the folder. The tallest determines the height. If no folders contain an embedded widget, the size is detemined solely by the size of the tabs. .PP You can override either dimension with the container's \fB\-width\fR and \fB\-height\fR options. .SH "CONTAINER OPERATIONS" All \fBcontainer\fR operations are invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .CS \fIpathName operation \fR?\fIarg arg ...\fR? .CE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operations are available for container widgets: .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .RS .TP \fB\-background \fIcolor\fR Sets the border color of the container. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines how the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-command \fIpattern\fR Specifies to search for a window whose \f(CWWM_COMMAND\fR property matches the given pattern. If no windows, or more than one window, matches the pattern, an error is generated. If \fIpattern\fR is the empty string, then no command search is performed. The default is \f(CW""\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. If \fIpixels\fR is 0, then the height is height the embedded window plus the specified borderwidth. The default is \f(CW0\fR. .TP \fB\-highlightbackground \fIcolor\fR Sets the color to display in the traversal highlight region when the container does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Sets the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Sets the width of the highlight rectangle to draw around the outside of the widget when it has the input focus. \fIPixels\fR is a non-negative value and may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight is drawn around the widget. The default is \f(CW2\fR. .TP \fB\-name \fIpattern\fR Specifies to search for a window whose \f(CWWM_NAME\fR property matches the given pattern. If no windows, or more than one window, matches the pattern, an error is generated. If \fIpattern\fR is the empty string, then no name search is performed. The default is \f(CW""\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the container widget. \fIRelief\fR specifies how the container should appear relative to widget that it is packed into; for example, \f(CWraised\fR means the container should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts decide whether to focus on the window. The default is \f(CW1\fR. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. If \fIpixels\fR is 0, then the width is the width the embedded window and the specified borderwidth. The default is \f(CW0\fR. .TP \fB\-window \fIid\fR Specifies the foreign embedded using its X window id. .RE .TP \fIpathName \fBfind \fB\-command\fR|\fB\-name\fR \fIpattern\fR Searches for all windows that match the given pattern. If the \fB\-command\fR switch is given, all windows whose \fCWWM_COMMAND\fR property match \fIpattern\fR are returned in a list. If the \fB\-name\fR switch is given, all windows whose \fCWWM_NAME\fR property match \fIpattern\fR are returned in a list. The list returned will contains pairs of the window id and the matching property. .SH KEYWORDS container, widget ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/Blt_TreeCreate.man3�����������������������������������������������������������0000644�0001750�0001750�00000007622�11462120062�016424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeCreate 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeCreate \- Create tree data object. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp int \fBBlt_TreeCreate\fR(\fIinterp\fR, \fIname\fR, \fItokenPtr\fR) .SH ARGUMENTS .AS Tcl_Interp *interp .AP Tcl_Interp *interp in Interpreter to report results back to. .AP "const char" *name in Name of the new tree. Can be qualified by a namespace. .AP Blt_Tree *tokenPtr out If not NULL, points to location to store the client tree token. .BE .SH DESCRIPTION .PP This procedure creates a C-based tree data object and optionally returns a token to it. The arguments are as follows: .TP 1i \fIinterp\fR Interpreter to report results back to. If an error occurs, then interp->result will contain an error message. .TP 1i \fIname\fR Name of the new tree object. You can think of \fIname\fR as the memory address of the object. It's a unique name that identifies the tree object. No tree object \fIname\fR can already exist. \fIName\fR can be qualified by a namespace such as \f(CWfred::myTree\fR. If no namespace qualifier is used, the tree will be created in the current namespace, not the global namespace. If a qualifier is present, the namespace must already exist. .TP 1i \fItokenPtr\fR Holds the returned token. \fITokenPtr\fR points to a location where it is stored. Tree tokens are used to work with the tree object. If NULL, no token is allocated. You can later use \fBTcl_TreeGetToken\fR to obtain a token. .PP The new tree data object created will initially contain only a root node. You can add new nodes with \fBBlt_TreeCreateNode\fR. .PP Optionally a token for the tree data object is returned. Tree data objects can be shared. For example, the \fBtree\fR and \fBhiertable\fR commands may be accessing the same tree data object. Each client grabs a token that is associated with the tree. When all tokens are released (see \fBBlt_TreeReleaseToken\fR) the tree data object is automatically destroyed. .PP .SH RETURNS A standard Tcl result is returned. If TCL_ERROR is returned, then \fIinterp->result\fR will contain an error message. The following errors may occur: .IP \(bu 3 There already exists a tree by the same name as \fIname\fR. You can use \fBTcl_TreeExists\fR to determine if a tree exists beforehand. .IP \(bu The tree name is prefixed by a namespace that doesn't exist. If you qualified the tree name with a namespace, the namespace must exist. Unlike Tcl procs and variables, the namespace is not automatically created for you. .IP \(bu Memory can't be allocated for the tree or token. .SH EXAMPLE The following example creates a new .CS Blt_Tree token; if (Blt_TreeCreate(interp, "myTree", &token) != TCL_OK) { return TCL_ERROR; } printf("tree is %s\\n", Blt_TreeName(token)); .CE .SH KEYWORDS Tcl_TreeGetToken, Tcl_TreeExists, Tcl_TreeReleaseToken ��������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/vector.mann�������������������������������������������������������������������0000644�0001750�0001750�00000114150�11462120062�015170� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1997 by Lucent Technologies, Inc. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Vector command created by George Howlett. '\" .so man.macros .TH blt::vector n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBvector\fR \- Vector data type for Tcl .SH SYNOPSIS \fBblt::vector create \fIvecName \fR?\fIvecName\fR...? ?\fIswitches\fR? .sp \fBblt::vector destroy \fIvecName \fR?\fIvecName\fR...? .sp \fBblt::vector expr \fIexpression\fR .sp \fBblt::vector names \fR?\fIpattern\fR...? .BE .SH DESCRIPTION The \fBvector\fR command creates an array of floating point values. The vector's components can be manipulated in three ways: through a Tcl array variable, a Tcl command, or the C API. .SH INTRODUCTION A vector is an ordered set of real numbers. The components of a vector are indexed by integers. .PP Vectors are common data structures for many applications. For example, a graph may use two vectors to represent the X-Y coordinates of the data plotted. The graph will automatically be redrawn when the vectors are updated or changed. By using vectors, you can separate data analysis from the graph widget. This makes it easier, for example, to add data transformations, such as splines. It's possible to plot the same data to in multiple graphs, where each graph presents a different view or scale of the data. .PP You could try to use Tcl's associative arrays as vectors. Tcl arrays are easy to use. You can access individual elements randomly by specifying the index, or the set the entire array by providing a list of index and value pairs for each element. The disadvantages of associative arrays as vectors lie in the fact they are implemented as hash tables. .TP 2 \(bu There's no implied ordering to the associative arrays. If you used vectors for plotting, you would want to insure the second component comes after the first, an so on. This isn't possible since arrays are actually hash tables. For example, you can't get a range of values between two indices. Nor can you sort an array. .TP 2 \(bu Arrays consume lots of memory when the number of elements becomes large (tens of thousands). This is because each element's index and value are stored as strings in the hash table. .TP 2 \(bu The C programming interface is unwieldy. Normally with vectors, you would like to view the Tcl array as you do a C array, as an array of floats or doubles. But with hash tables, you must convert both the index and value to and from decimal strings, just to access an element in the array. This makes it cumbersome to perform operations on the array as a whole. .PP The \fBvector\fR command tries to overcome these disadvantages while still retaining the ease of use of Tcl arrays. The \fBvector\fR command creates both a new Tcl command and associate array which are linked to the vector components. You can randomly access vector components though the elements of array. Not have all indices are generated for the array, so printing the array (using the \fBparray\fR procedure) does not print out all the component values. You can use the Tcl command to access the array as a whole. You can copy, append, or sort vector using its command. If you need greater performance, or customized behavior, you can write your own C code to manage vectors. .SH EXAMPLE You create vectors using the \fBvector\fR command and its \fBcreate\fR operation. .CS # Create a new vector. blt::vector create y(50) .CE This creates a new vector named \f(CWy\fR. It has fifty components, by default, initialized to \f(CW0.0\fR. In addition, both a Tcl command and array variable, both named \f(CWy\fR, are created. You can use either the command or variable to query or modify components of the vector. .CS # Set the first value. set y(0) 9.25 puts "y has [y length] components" .CE The array \f(CWy\fR can be used to read or set individual components of the vector. Vector components are indexed from zero. The array index must be a number less than the number of components. For example, it's an error if you try to set the 51st element of \f(CWy\fR. .CS # This is an error. The vector only has 50 components. set y(50) 0.02 .CE You can also specify a range of indices using a colon (:) to separate the first and last indices of the range. .CS # Set the first six components of y set y(0:5) 25.2 .CE If you don't include an index, then it will default to the first and/or last component of the vector. .CS # Print out all the components of y puts "y = $y(:)" .CE There are special non-numeric indices. The index \f(CWend\fR, specifies the last component of the vector. It's an error to use this index if the vector is empty (length is zero). The index \f(CW++end\fR can be used to extend the vector by one component and initialize it to a specific value. You can't read from the array using this index, though. .CS # Extend the vector by one component. set y(++end) 0.02 .CE The other special indices are \f(CWmin\fR and \f(CWmax\fR. They return the current smallest and largest components of the vector. .CS # Print the bounds of the vector puts "min=$y(min) max=$y(max)" .CE To delete components from a vector, simply unset the corresponding array element. In the following example, the first component of \f(CWy\fR is deleted. All the remaining components of \f(CWy\fR will be moved down by one index as the length of the vector is reduced by one. .CS # Delete the first component unset y(0) puts "new first element is $y(0)" .CE The vector's Tcl command can also be used to query or set the vector. .CS # Create and set the components of a new vector blt::vector create x x set { 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 } .CE Here we've created a vector \f(CWx\fR without a initial length specification. In this case, the length is zero. The \fBset\fR operation resets the vector, extending it and setting values for each new component. .PP There are several operations for vectors. The \fBrange\fR operation lists the components of a vector between two indices. .CS # List the components puts "x = [x range 0 end]" .CE You can search for a particular value using the \fBsearch\fR operation. It returns a list of indices of the components with the same value. If no component has the same value, it returns \f(CW""\fR. .CS # Find the index of the biggest component set indices [x search $x(max)] .CE Other operations copy, append, or sort vectors. You can append vectors or new values onto an existing vector with the \fBappend\fR operation. .CS # Append assorted vectors and values to x x append x2 x3 { 2.3 4.5 } x4 .CE The \fBsort\fR operation sorts the vector. If any additional vectors are specified, they are rearranged in the same order as the vector. For example, you could use it to sort data points represented by x and y vectors. .CS # Sort the data points x sort y .CE The vector \f(CWx\fR is sorted while the components of \f(CWy\fR are rearranged so that the original x,y coordinate pairs are retained. .PP The \fBexpr\fR operation lets you perform arithmetic on vectors. The result is stored in the vector. .CS # Add the two vectors and a scalar x expr { x + y } x expr { x * 2 } .CE When a vector is modified, resized, or deleted, it may trigger call-backs to notify the clients of the vector. For example, when a vector used in the \fBgraph\fR widget is updated, the vector automatically notifies the widget that it has changed. The graph can then redrawn itself at the next idle point. By default, the notification occurs when Tk is next idle. This way you can modify the vector many times without incurring the penalty of the graph redrawing itself for each change. You can change this behavior using the \fBnotify\fR operation. .CS # Make vector x notify after every change x notify always ... # Never notify x notify never ... # Force notification now x notify now .CE To delete a vector, use the \fBvector delete\fR command. Both the vector and its corresponding Tcl command are destroyed. .CS # Remove vector x blt::vector destroy x .CE .SH SYNTAX Vectors are created using the \fBvector create\fR operation. Th \fBcreate\fR operation can be invoked in one of three forms: .TP \fBblt::vector create \fIvecName\fR This creates a new vector \fIvecName\fR which initially has no components. .TP \fBblt::vector create \fIvecName\fR(\fIsize\fR) This second form creates a new vector which will contain \fIsize\fR number of components. The components will be indexed starting from zero (0). The default value for the components is \f(CW0.0\fR. .TP \fBblt::vector create \fIvecName\fR(\fIfirst\fR:\fIlast\fR) The last form creates a new vector of indexed \fIfirst\fR through \fIlast\fR. \fIFirst\fR and \fIlast\fR can be any integer value so long as \fIfirst\fR is less than \fIlast\fR. .PP Vector names must start with a letter and consist of letters, digits, or underscores. .CS # Error: must start with letter blt::vector create 1abc .CE You can automatically generate vector names using the "\f(CW#auto\fR" vector name. The \fBcreate\fR operation will generate a unique vector name. .CS set vec [blt::vector create #auto] puts "$vec has [$vec length] components" .CE .SS VECTOR INDICES Vectors are indexed by integers. You can access the individual vector components via its array variable or Tcl command. The string representing the index can be an integer, a numeric expression, a range, or a special keyword. .PP The index must lie within the current range of the vector, otherwise an an error message is returned. Normally the indices of a vector are start from 0. But you can use the \fBoffset\fR operation to change a vector's indices on-the-fly. .CS puts $vecName(0) vecName offset -5 puts $vecName(-5) .CE You can also use numeric expressions as indices. The result of the expression must be an integer value. .CS set n 21 set vecName($n+3) 50.2 .CE The following special non-numeric indices are available: \f(CWmin\fR, \f(CWmax\fR, \f(CWend\fR, and \f(CW++end\fR. .CS puts "min = $vecName($min)" set vecName(end) -1.2 .CE The indices \f(CWmin\fR and \f(CWmax\fR will return the minimum and maximum values of the vector. The index \f(CWend\fR returns the value of the last component in the vector. The index \f(CW++end\fR is used to append new value onto the vector. It automatically extends the vector by one component and sets its value. .CS # Append an new component to the end set vecName(++end) 3.2 .CE A range of indices can be indicated by a colon (:). .CS # Set the first six components to 1.0 set vecName(0:5) 1.0 .CE If no index is supplied the first or last component is assumed. .CS # Print the values of all the components puts $vecName(:) .CE .SH VECTOR OPERATIONS .TP \fBblt::vector create \fIvecName\fR?(\fIsize\fR)?... \fR?\fIswitches\fR? The \fBcreate\fR operation creates a new vector \fIvecName\fR. Both a Tcl command and array variable \fIvecName\fR are also created. The name \fIvecName\fR must be unique, so another Tcl command or array variable can not already exist in that scope. You can access the components of the vector using its variable. If you change a value in the array, or unset an array element, the vector is updated to reflect the changes. When the variable \fIvecName\fR is unset, the vector and its Tcl command are also destroyed. .sp The vector has optional switches that affect how the vector is created. They are as follows: .RS .TP \fB\-variable \fIvarName\fR Specifies the name of a Tcl variable to be mapped to the vector. If the variable already exists, it is first deleted, then recreated. If \fIvarName\fR is the empty string, then no variable will be mapped. You can always map a variable back to the vector using the vector's \fBvariable\fR operation. .TP \fB\-command \fIcmdName\fR Maps a Tcl command to the vector. The vector can be accessed using \fIcmdName\fR and one of the vector instance operations. A Tcl command by that name cannot already exist. If \fIcmdName\fR is the empty string, no command mapping will be made. .TP \fB\-watchunset \fIboolean\fR Indicates that the vector should automatically delete itself if the variable associated with the vector is unset. By default, the vector will not be deleted. This is different from previous releases. Set \fIboolean\fR to "true" to get the old behavior. .RE .TP \fBblt::vector destroy \fIvecName\fR \fR?\fIvecName...\fR? Deletes one or more vectors. Both the Tcl command and array variable are removed also. .TP \fBblt::vector expr \fIexpression\fR .RS All binary operators take vectors as operands (remember that numbers are treated as one-component vectors). The exact action of binary operators depends upon the length of the second operand. If the second operand has only one component, then each element of the first vector operand is computed by that value. For example, the expression "x * 2" multiples all elements of the vector x by 2. If the second operand has more than one component, both operands must be the same length. Each pair of corresponding elements are computed. So "x + y" adds the the first components of x and y together, the second, and so on. .sp The valid operators are listed below, grouped in decreasing order of precedence: .TP 20 \fB\-\0\0!\fR Unary minus and logical NOT. The unary minus flips the sign of each component in the vector. The logical not operator returns a vector of whose values are 0.0 or 1.0. For each non-zero component 1.0 is returned, 0.0 otherwise. .TP 20 \fB^\fR Exponentiation. .TP 20 \fB*\0\0/\0\0%\fR Multiply, divide, remainder. .TP 20 \fB+\0\0\-\fR Add and subtract. .TP 20 \fB<<\0\0>>\fR Left and right shift. Circularly shifts the values of the vector (not implemented yet). .TP 20 \fB<\0\0>\0\0<=\0\0>=\fR Boolean less, greater, less than or equal, and greater than or equal. Each operator returns a vector of ones and zeros. If the condition is true, 1.0 is the component value, 0.0 otherwise. .TP 20 \fB==\0\0!=\fR Boolean equal and not equal. Each operator returns a vector of ones and zeros. If the condition is true, 1.0 is the component value, 0.0 otherwise. .TP 20 \fB|\fR Bit-wise OR. (Not implemented). .TP 20 \fB&&\fR Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. .TP 20 \fB||\fR Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. .TP 20 \fIx\fB?\fIy\fB:\fIz\fR If-then-else, as in C. (Not implemented yet). .LP See the C manual for more details on the results produced by each operator. All of the binary operators group left-to-right within the same precedence level. .sp Several mathematical functions are supported for vectors. Each of the following functions invokes the math library function of the same name; see the manual entries for the library functions for details on what they do. The operation is applied to all elements of the vector returning the results. .CS .ta 3c 6c 9c \fBacos\fR \fBcos\fR \fBhypot\fR \fBsinh\fR \fBasin\fR \fBcosh\fR \fBlog\fR \fBsqrt\fR \fBatan\fR \fBexp\fR \fBlog10\fR \fBtan\fR \fBceil\fR \fBfloor\fR \fBsin\fR \fBtanh\fR .CE Additional functions are: .TP 1i \fBabs\fR Returns the absolute value of each component. .TP 1i \fBrandom\fR Returns a vector of non-negative values uniformly distributed between [0.0, 1.0) using \fIdrand48\fR. The seed comes from the internal clock of the machine or may be set manual with the srandom function. .TP 1i \fBround\fR Rounds each component of the vector. .TP 1i \fBsrandom\fR Initializes the random number generator using \fIsrand48\fR. The high order 32-bits are set using the integral portion of the first vector component. All other components are ignored. The low order 16-bits are set to an arbitrary value. .PP The following functions return a single value. .TP 1i \fBadev\fR Returns the average deviation (defined as the sum of the absolute values of the differences between component and the mean, divided by the length of the vector). .TP 1i \fBkurtosis\fR Returns the degree of peakedness (fourth moment) of the vector. .TP 1i \fBlength\fR Returns the number of components in the vector. .TP 1i \fBmax\fR Returns the vector's maximum value. .TP 1i \fBmean\fR Returns the mean value of the vector. .TP 1i \fBmedian\fR Returns the median of the vector. .TP 1i \fBmin\fR Returns the vector's minimum value. .TP 1i \fBq1\fR Returns the first quartile of the vector. .TP 1i \fBq3\fR Returns the third quartile of the vector. .TP 1i \fBprod\fR Returns the product of the components. .TP 1i \fBsdev\fR Returns the standard deviation (defined as the square root of the variance) of the vector. .TP 1i \fBskew\fR Returns the skewness (or third moment) of the vector. This characterizes the degree of asymmetry of the vector about the mean. .TP 1i \fBsum\fR Returns the sum of the components. .TP 1i \fBvar\fR Returns the variance of the vector. The sum of the squared differences between each component and the mean is computed. The variance is the sum divided by the length of the vector minus 1. .PP The last set returns a vector of the same length as the argument. .TP 1i \fBnorm\fR Scales the values of the vector to lie in the range [0.0..1.0]. .TP 1i \fBsort\fR Returns the vector components sorted in ascending order. .RE .TP \fBvector names \fR?\fIpattern\fR? .SH INSTANCE OPERATIONS You can also use the vector's Tcl command to query or modify it. The general form is .DS \fIvecName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for vectors are listed below. .TP \fIvecName \fBappend\fR \fIitem\fR ?\fIitem\fR?... Appends the component values from \fIitem\fR to \fIvecName\fR. \fIItem\fR can be either the name of a vector or a list of numeric values. .TP \fIvecName \fBbinread\fR \fIchannel\fR ?\fIlength\fR? ?\fIswitches\fR? Reads binary values from a Tcl channel. Values are either appended to the end of the vector or placed at a given index (using the \fB\-at\fR option), overwriting existing values. Data is read until EOF is found on the channel or a specified number of values \fIlength\fR are read (note that this is not necessarily the same as the number of bytes). The following switches are supported: .RS .TP \fB\-swap\fR Swap bytes and words. The default endian is the host machine. .TP \fB\-at \fIindex\fR New values will start at vector index \fIindex\fR. This will overwrite any current values. .TP \fB\-format\fR \fIformat\fR Specifies the format of the data. \fIFormat\fR can be one of the following: "i1", "i2", "i4", "i8", "u1, "u2", "u4", "u8", "r4", "r8", or "r16". The number indicates the number of bytes required for each value. The letter indicates the type: "i" for signed, "u" for unsigned, "r" or real. The default format is "r16". .RE .TP \fIvecName \fBclear\fR Clears the element indices from the array variable associated with \fIvecName\fR. This doesn't affect the components of the vector. By default, the number of entries in the Tcl array doesn't match the number of components in the vector. This is because its too expensive to maintain decimal strings for both the index and value for each component. Instead, the index and value are saved only when you read or write an element with a new index. This command removes the index and value strings from the array. This is useful when the vector is large. .TP \fIvecName \fBdelete\fR \fIindex\fR ?\fIindex\fR?... Deletes the \fIindex\fRth component from the vector \fIvecName\fR. \fIIndex\fR is the index of the element to be deleted. This is the same as unsetting the array variable element \fIindex\fR. The vector is compacted after all the indices have been deleted. .TP \fIvecName \fBdup\fR \fIdestName\fR Copies \fIvecName\fR to \fIdestName\fR. \fIDestName\fR is the name of a destination vector. If a vector \fIdestName\fR already exists, it is overwritten with the components of \fIvecName\fR. Otherwise a new vector is created. .TP \fIvecName \fBexpr\fR \fIexpression\fR Computes the expression and resets the values of the vector accordingly. Both scalar and vector math operations are allowed. All values in expressions are either real numbers or names of vectors. All numbers are treated as one component vectors. .TP \fIvecName \fBlength\fR ?\fInewSize\fR? Queries or resets the number of components in \fIvecName\fR. \fINewSize\fR is a number specifying the new size of the vector. If \fInewSize\fR is smaller than the current size of \fIvecName\fR, \fIvecName\fR is truncated. If \fInewSize\fR is greater, the vector is extended and the new components are initialized to \f(CW0.0\fR. If no \fInewSize\fR argument is present, the current length of the vector is returned. .TP \fIvecName \fBmerge\fR \fIsrcName\fR ?\fIsrcName\fR?... Merges the named vectors into a single vector. The resulting vector is formed by merging the components of each source vector one index at a time. .TP \fIvecName \fBnotify\fR \fIkeyword\fR Controls how vector clients are notified of changes to the vector. The exact behavior is determined by \fIkeyword\fR. .RS .TP 0.75i \f(CWalways\fR Indicates that clients are to be notified immediately whenever the vector is updated. .TP \f(CWnever\fR Indicates that no clients are to be notified. .TP \f(CWwhenidle\fR Indicates that clients are to be notified at the next idle point whenever the vector is updated. .TP \f(CWnow\fR If any client notifications is currently pending, they are notified immediately. .TP \f(CWcancel\fR Cancels pending notifications of clients using the vector. .TP \f(CWpending\fR Returns \f(CW1\fR if a client notification is pending, and \f(CW0\fR otherwise. .RE .TP \fIvecName \fBoffset\fR ?\fIvalue\fR? Shifts the indices of the vector by the amount specified by \fIvalue\fR. \fIValue\fR is an integer number. If no \fIvalue\fR argument is given, the current offset is returned. .TP \fIvecName \fBpopulate\fR \fIdestName\fR ?\fIdensity\fR? Creates a vector \fIdestName\fR which is a superset of \fIvecName\fR. \fIDestName\fR will include all the components of \fIvecName\fR, in addition the interval between each of the original components will contain a \fIdensity\fR number of new components, whose values are evenly distributed between the original components values. This is useful for generating abscissas to be interpolated along a spline. .TP \fIvecName \fBrange\fR \fIfirstIndex\fR ?\fIlastIndex\fR?... Returns a list of numeric values representing the vector components between two indices. Both \fIfirstIndex\fR and \fIlastIndex\fR are indices representing the range of components to be returned. If \fIlastIndex\fR is less than \fIfirstIndex\fR, the components are listed in reverse order. .TP \fIvecName \fBsearch\fR \fIvalue\fR ?\fIvalue\fR? Searches for a value or range of values among the components of \fIvecName\fR. If one \fIvalue\fR argument is given, a list of indices of the components which equal \fIvalue\fR is returned. If a second \fIvalue\fR is also provided, then the indices of all components which lie within the range of the two values are returned. If no components are found, then \f(CW""\fR is returned. .TP \fIvecName \fBset\fR \fIitem\fR Resets the components of the vector to \fIitem\fR. \fIItem\fR can be either a list of numeric expressions or another vector. .TP \fIvecName \fBseq\fR \fIstart\fR ?\fIfinish\fR? ?\fIstep\fR? Generates a sequence of values starting with the value \fIstart\fR. \fIFinish\fR indicates the terminating value of the sequence. The vector is automatically resized to contain just the sequence. If three arguments are present, \fIstep\fR designates the interval. .sp With only two arguments (no \fIfinish\fR argument), the sequence will continue until the vector is filled. With one argument, the interval defaults to 1.0. .TP \fIvecName \fBsort\fR ?\fB-reverse\fR? ?\fIargName\fR?... Sorts the vector \fIvecName\fR in increasing order. If the \fB-reverse\fR flag is present, the vector is sorted in decreasing order. If other arguments \fIargName\fR are present, they are the names of vectors which will be rearranged in the same manner as \fIvecName\fR. Each vector must be the same length as \fIvecName\fR. You could use this to sort the x vector of a graph, while still retaining the same x,y coordinate pairs in a y vector. .TP \fIvecName \fBvariable\fR \fIvarName\fR Maps a Tcl variable to the vector, creating another means for accessing the vector. The variable \fIvarName\fR can't already exist. This overrides any current variable mapping the vector may have. .RE .SH C LANGUAGE API You can create, modify, and destroy vectors from C code, using library routines. You need to include the header file \f(CWblt.h\fR. It contains the definition of the structure \fBBlt_Vector\fR, which represents the vector. It appears below. .CS \fRtypedef struct { double *\fIvalueArr\fR; int \fInumValues\fR; int \fIarraySize\fR; double \fImin\fR, \fImax\fR; } \fBBlt_Vector\fR; .CE The field \fIvalueArr\fR points to memory holding the vector components. The components are stored in a double precision array, whose size size is represented by \fIarraySize\fR. \fINumValues\fR is the length of vector. The size of the array is always equal to or larger than the length of the vector. \fIMin\fR and \fImax\fR are minimum and maximum component values. .SH LIBRARY ROUTINES The following routines are available from C to manage vectors. Vectors are identified by the vector name. .PP \fBBlt_CreateVector\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_CreateVector\fR (\fIinterp\fR, \fIvecName\fR, \fIlength\fR, \fIvecPtrPtr\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; char *\fIvecName\fR; int \fIlength\fR; Blt_Vector **\fIvecPtrPtr\fR; .RE .CE .TP Description: Creates a new vector \fIvecName\fR\fR with a length of \fIlength\fR. \fBBlt_CreateVector\fR creates both a new Tcl command and array variable \fIvecName\fR. Neither a command nor variable named \fIvecName\fR can already exist. A pointer to the vector is placed into \fIvecPtrPtr\fR. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully created. If \fIlength\fR is negative, a Tcl variable or command \fIvecName\fR already exists, or memory cannot be allocated for the vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_DeleteVectorByName\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_DeleteVectorByName\fR (\fIinterp\fR, \fIvecName\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; char *\fIvecName\fR; .RE .CE .TP 1i Description: Removes the vector \fIvecName\fR. \fIVecName\fR is the name of a vector which must already exist. Both the Tcl command and array variable \fIvecName\fR are destroyed. All clients of the vector will be notified immediately that the vector has been destroyed. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully deleted. If \fIvecName\fR is not the name a vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_DeleteVector\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_DeleteVector\fR (\fIvecPtr\fR) .RS 1.25i Blt_Vector *\fIvecPtr\fR; .RE .CE .TP 1i Description: Removes the vector pointed to by \fIvecPtr\fR. \fIVecPtr\fR is a pointer to a vector, typically set by \fBBlt_GetVector\fR or \fBBlt_CreateVector\fR. Both the Tcl command and array variable of the vector are destroyed. All clients of the vector will be notified immediately that the vector has been destroyed. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully deleted. If \fIvecName\fR is not the name a vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_GetVector\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_GetVector\fR (\fIinterp\fR, \fIvecName\fR, \fIvecPtrPtr\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; char *\fIvecName\fR; Blt_Vector **\fIvecPtrPtr\fR; .RE .CE .TP 1i Description: Retrieves the vector \fIvecName\fR. \fIVecName\fR is the name of a vector which must already exist. \fIVecPtrPtr\fR will point be set to the address of the vector. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully retrieved. If \fIvecName\fR is not the name of a vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_ResetVector\fR .PP .RS .25i .TP 1i Synopsis: .CS int \fBBlt_ResetVector\fR (\fIvecPtr\fR, \fIdataArr\fR, \fInumValues\fR, \fIarraySize\fR, \fIfreeProc\fR) .RS 1.25i Blt_Vector *\fIvecPtr\fR; double *\fIdataArr\fR; int *\fInumValues\fR; int *\fIarraySize\fR; Tcl_FreeProc *\fIfreeProc\fR; .RE .CE .TP Description: Resets the components of the vector pointed to by \fIvecPtr\fR. Calling \fBBlt_ResetVector\fR will trigger the vector to dispatch notifications to its clients. \fIDataArr\fR is the array of doubles which represents the vector data. \fINumValues\fR is the number of elements in the array. \fIArraySize\fR is the actual size of the array (the array may be bigger than the number of values stored in it). \fIFreeProc\fP indicates how the storage for the vector component array (\fIdataArr\fR) was allocated. It is used to determine how to reallocate memory when the vector is resized or destroyed. It must be \f(CWTCL_DYNAMIC\fR, \f(CWTCL_STATIC\fR, \f(CWTCL_VOLATILE\fR, or a pointer to a function to free the memory allocated for the vector array. If \fIfreeProc\fR is \f(CWTCL_VOLATILE\fR, it indicates that \fIdataArr\fR must be copied and saved. If \fIfreeProc\fR is \f(CWTCL_DYNAMIC\fR, it indicates that \fIdataArr\fR was dynamically allocated and that Tcl should free \fIdataArr\fR if necessary. \f(CWStatic\fR indicates that nothing should be done to release storage for \fIdataArr\fR. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully resized. If \fInewSize\fR is negative, a vector \fIvecName\fR does not exist, or memory cannot be allocated for the vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_ResizeVector\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_ResizeVector\fR (\fIvecPtr\fR, \fInewSize\fR) .RS 1.25i Blt_Vector *\fIvecPtr\fR; int \fInewSize\fR; .RE .CE .TP Description: Resets the length of the vector pointed to by \fIvecPtr\fR to \fInewSize\fR. If \fInewSize\fR is smaller than the current size of the vector, it is truncated. If \fInewSize\fR is greater, the vector is extended and the new components are initialized to \f(CW0.0\fR. Calling \fBBlt_ResetVector\fR will trigger the vector to dispatch notifications. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully resized. If \fInewSize\fR is negative or memory can not be allocated for the vector, then \f(CWTCL_ERROR\fR is returned and \fIinterp->result\fR will contain an error message. .sp .PP \fBBlt_VectorExists\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_VectorExists\fR (\fIinterp\fR, \fIvecName\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; char *\fIvecName\fR; .RE .CE .TP Description: Indicates if a vector named \fIvecName\fR exists in \fIinterp\fR. .TP Results: Returns \f(CW1\fR if a vector \fIvecName\fR exists and \f(CW0\fR otherwise. .RE .sp .PP If your application needs to be notified when a vector changes, it can allocate a unique \fIclient identifier\fR for itself. Using this identifier, you can then register a call-back to be made whenever the vector is updated or destroyed. By default, the call-backs are made at the next idle point. This can be changed to occur at the time the vector is modified. An application can allocate more than one identifier for any vector. When the client application is done with the vector, it should free the identifier. .PP The call-back routine must of the following type. .CS .RS .sp typedef void (\fBBlt_VectorChangedProc\fR) (Tcl_Interp *\fIinterp\fR, .RS .25i ClientData \fIclientData\fR, Blt_VectorNotify \fInotify\fR); .RE .sp .RE .CE .fi \fIClientData\fR is passed to this routine whenever it is called. You can use this to pass information to the call-back. The \fInotify\fR argument indicates whether the vector has been updated of destroyed. It is an enumerated type. .CS .RS .sp typedef enum { \f(CWBLT_VECTOR_NOTIFY_UPDATE\fR=1, \f(CWBLT_VECTOR_NOTIFY_DESTROY\fR=2 } \fBBlt_VectorNotify\fR; .sp .RE .CE .PP \fBBlt_AllocVectorId\fR .RS .25i .TP 1i Synopsis: .CS Blt_VectorId \fBBlt_AllocVectorId\fR (\fIinterp\fR, \fIvecName\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; char *\fIvecName\fR; .RE .CE .TP Description: Allocates an client identifier for with the vector \fIvecName\fR. This identifier can be used to specify a call-back which is triggered when the vector is updated or destroyed. .TP Results: Returns a client identifier if successful. If \fIvecName\fR is not the name of a vector, then \f(CWNULL\fR is returned and \fIinterp->result\fR will contain an error message. .RE .sp .PP \fBBlt_GetVectorById\fR .RS .25i .TP 1i Synopsis: .CS int \fBBlt_GetVector\fR (\fIinterp\fR, \fIclientId\fR, \fIvecPtrPtr\fR) .RS 1.25i Tcl_Interp *\fIinterp\fR; Blt_VectorId \fIclientId\fR; Blt_Vector **\fIvecPtrPtr\fR; .RE .CE .TP 1i Description: Retrieves the vector used by \fIclientId\fR. \fIClientId\fR is a valid vector client identifier allocated by \fBBlt_AllocVectorId\fR. \fIVecPtrPtr\fR will point be set to the address of the vector. .TP Results: Returns \f(CWTCL_OK\fR if the vector is successfully retrieved. .RE .sp .PP \fBBlt_SetVectorChangedProc\fR .RS .25i .TP 1i Synopsis: .CS void \fBBlt_SetVectorChangedProc\fR (\fIclientId\fR, \fIproc\fR, \fIclientData\fR); .RS 1.25i Blt_VectorId \fIclientId\fR; Blt_VectorChangedProc *\fIproc\fR; ClientData *\fIclientData\fR; .RE .CE .TP Description: Specifies a call-back routine to be called whenever the vector associated with \fIclientId\fR is updated or deleted. \fIProc\fR is a pointer to call-back routine and must be of the type \fBBlt_VectorChangedProc\fR. \fIClientData\fR is a one-word value to be passed to the routine when it is invoked. If \fIproc\fR is \f(CWNULL\fR, then the client is not notified. .TP Results: The designated call-back procedure will be invoked when the vector is updated or destroyed. .RE .sp .PP \fBBlt_FreeVectorId\fR .RS .25i .TP 1i Synopsis: .CS void \fBBlt_FreeVectorId\fR (\fIclientId\fR); .RS 1.25i Blt_VectorId \fIclientId\fR; .RE .CE .TP Description: Frees the client identifier. Memory allocated for the identifier is released. The client will no longer be notified when the vector is modified. .TP Results: The designated call-back procedure will be no longer be invoked when the vector is updated or destroyed. .RE .sp .PP \fBBlt_NameOfVectorId\fR .RS .25i .TP 1i Synopsis: .CS char *\fBBlt_NameOfVectorId\fR (\fIclientId\fR); .RS 1.25i Blt_VectorId \fIclientId\fR; .RE .CE .TP Description: Retrieves the name of the vector associated with the client identifier \fIclientId\fR. .TP Results: Returns the name of the vector associated with \fIclientId\fR. If \fIclientId\fR is not an identifier or the vector has been destroyed, \f(CWNULL\fR is returned. .RE .sp .PP \fBBlt_InstallIndexProc\fR .RS .25i .TP 1i Synopsis: .CS void \fBBlt_InstallIndexProc\fR (\fIindexName\fR, \fIprocPtr\fR) .RS 1.25i char *\fIindexName\fR; Blt_VectorIndexProc *\fIprocPtr\fR; .RE .CE .TP Description: Registers a function to be called to retrieved the index \fIindexName\fR from the vector's array variable. .sp typedef double Blt_VectorIndexProc(Vector *vecPtr); .sp The function will be passed a pointer to the vector. The function must return a double representing the value at the index. .TP Results: The new index is installed into the vector. .RE .RE .SH C API EXAMPLE The following example opens a file of binary data and stores it in an array of doubles. The array size is computed from the size of the file. If the vector "data" exists, calling \fBBlt_VectorExists\fR, \fBBlt_GetVector\fR is called to get the pointer to the vector. Otherwise the routine \fBBlt_CreateVector\fR is called to create a new vector and returns a pointer to it. Just like the Tcl interface, both a new Tcl command and array variable are created when a new vector is created. It doesn't make any difference what the initial size of the vector is since it will be reset shortly. The vector is updated when \fBlt_ResetVector\fR is called. Blt_ResetVector makes the changes visible to the Tcl interface and other vector clients (such as a graph widget). .sp .CS #include <tcl.h> #include <blt.h> ... Blt_Vector *vecPtr; double *newArr; FILE *f; struct stat statBuf; int numBytes, numValues; f = fopen("binary.dat", "r"); fstat(fileno(f), &statBuf); numBytes = (int)statBuf.st_size; /* Allocate an array big enough to hold all the data */ newArr = (double *)malloc(numBytes); numValues = numBytes / sizeof(double); fread((void *)newArr, numValues, sizeof(double), f); fclose(f); if (Blt_VectorExists(interp, "data")) { if (Blt_GetVector(interp, "data", &vecPtr) != TCL_OK) { return TCL_ERROR; } } else { if (Blt_CreateVector(interp, "data", 0, &vecPtr) != TCL_OK) { return TCL_ERROR; } } /* * Reset the vector. Clients will be notified when Tk is idle. * TCL_DYNAMIC tells the vector to free the memory allocated * if it needs to reallocate or destroy the vector. */ if (Blt_ResetVector(vecPtr, newArr, numValues, numValues, TCL_DYNAMIC) != TCL_OK) { return TCL_ERROR; } .CE .SH "INCOMPATIBILITIES" In previous versions, if the array variable isn't global (i.e. local to a Tcl procedure), the vector is automatically destroyed when the procedure returns. .CS proc doit {} { # Temporary vector x vector x(10) set x(9) 2.0 ... } .CE .PP This has changed. Variables are not automatically destroyed when their variable is unset. You can restore the old behavior by setting the "-watchunset" switch. .CE .SH KEYWORDS vector, graph, widget ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/hiertable.mann����������������������������������������������������������������0000644�0001750�0001750�00000253721�11462120062�015635� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 2001-2 by Silicon Metrics Corporation. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Silicon Metrics or any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Silicon Metrics disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Silicon Metrics be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" The hierarchical table widget created by George Howlett. '\" .so man.macros .TH treeview n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME treeview \- Create and manipulate hierarchical table widgets .BE .SH SYNOPSIS \fBtreeview\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBtreeview\fR widget displays a tree of data. It replaces both the \fBhiertable\fR and \fBhierbox\fR widgets. The \fBtreeview\fR is 100% syntax compatible with the \fBhiertable\fR widget. The \fBhiertable\fR command is retained for sake of script-level compatibility. This widget obsoletes the \fBhierbox\fR widget. It does everything the old \fBhierbox\fR widget did, but also provides data sharing (via \fItree data objects\fR) and the ability to tag nodes. .SH INTRODUCTION The \fBtreeview\fR widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. .PP A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is \fIopen\fR, its children are exposed. When it is \fIclosed\fR, the children and their descedants are hidden. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). .PP If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. .SH "TREE DATA OBJECT" The tree is not stored inside the widget but in a tree data object (see the \fBtree\fR command for a further explanation). Tree data objects can be shared among different clients, such as a \fBtreeview\fR widget or the \fBtree\fR command. You can walk the tree and manage its data with the \fBtree\fR command tree, while displaying it with the \fBtreeview\fR widget. Whenever the tree is updated, the \fBtreeview\fR widget is automatically redrawn. .PP By default, the \fBtreeview\fR widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the \fBtree\fR command using the \fB\-tree\fR configuration option. \fBTreeview\fR widgets can share the same tree object, possibly displaying different views of the same data. .PP A tree object has both a Tcl and C API. You can insert or delete nodes using \fBtreeview\fR widget or \fBtree\fR command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. .SH SYNTAX .DS \fBtreeview \fIpathName \fR?\fIoption value\fR?... .DE The \fBtreeview\fR command creates a new window \fIpathName\fR and makes it into a \fBtreeview\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the \fBconfigure\fR operation below for the exact details about what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBtreeview\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available are described in the .SB "TREEVIEW OPERATIONS" section. .SH "IDS AND TAGS" Nodes can be inserted into a tree using the \fBtreeview\fR widget .CS blt::treeview .t set node [.t insert end root "one"] .CE or \fBtree\fR command. .CS set tree [blt::tree create] set node [$tree insert root "one"] .CE In both cases, a number identifying the node is returned (the value of \f(CW$node\fR). This serial number or \fIid\fR uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id \f(CW0\fR. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the \fBtreeview\fR widget or the \fBtree\fR command. Ids are recycled when the node deleted. .PP A node may also have any number of \fItags\fR associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "\f(CWx123\fR" is valid, but "\f(CW123\fR" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the \fBtreeview\fR widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. .PP The tag \fBall\fR is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. .PP Tags may be shared, just like trees, between clients. For example, you can use the tags created by the \fBtree\fR command with \fBtreeview\fR widgets. .SH SPECIAL NODE IDS There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the \fBtreeview\fR widget. .TP 15 \fBactive\fR The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the \fB\-activeicon\fR option). The \fBactive\fR id is changed automatically by moving the mouse pointer over another node or by using the \fBentry activate\fR operation. Note that there can be only one active node at a time. .TP 15 \fBanchor\fR The node representing the fixed end of the current selection. The anchor is set by the \fBselection anchor\fR operation. .TP 15 \fBcurrent\fR The node where the mouse pointer is currently located. But unlike \fBactive\fR, this id changes while the selection is dragged. It is used to determine the current node during button drags. .TP 15 \fBdown\fR The next open node from the current focus. The \fBdown\fR of the last open node is the same. .TP 15 \fBend\fR The last open node (in depth-first order) on the tree. .TP 15 \fBfocus\fR The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the \fBfocus\fR operation. .TP 15 \fBlast\fR The last open node from the current focus. But unlike \fBup\fR, when the focus is at root, \fBlast\fR wraps around to the last open node in the tree. .TP 15 \fBmark\fR The node representing the non-fixed end of the current selection. The mark is set by the \fBselection mark\fR operation. .TP 15 \fBnext\fR The next open node from the current focus. But unlike \fBdown\fR, when the focus is on last open node, \fBnext\fR wraps around to the root node. .TP 15 \fBnextsibling\fR The next sibling from the node with the current focus. If the node is already the last sibling then it is the \fBnextsibling\fB. .TP 15 \fBparent\fR The parent of the node with the current focus. The \fBparent\fR of the root is also the root. .TP 15 \fBprevsibling\fR The previous sibling from the node with the current focus. If the node is already the first sibling then it is the \fBprevsibling\fB. .TP 15 \fBroot\fR The root node. You can also use id \f(CW0\fR to indicate the root. .TP 15 \fBup\fR The last open node (in depth-first order) from the current focus. The \fBup\fR of the root node (i.e. the root has focus) is also the root. .TP 15 \fBview.top\fR First node that's current visible in the widget. .TP 15 \fBview.bottom\fR Last node that's current visible in the widget. .TP 15 \fIpath\fR Absolute path of a node. Path names refer to the node name, not their entry labels. Paths don't have to start with a separator (see the \fB\-separator\fR configuration option), but component names must be separated by the designated separator. .TP 15 \fB@\fIx\fB,\fIy\fR Indicates the node that covers the point in the treeview window specified by \fIx\fR and \fIy\fR (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. .PP A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. .SH DATA FIELDS A node in the tree can have \fIdata fields\fR. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the \fBtreeview\fR widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. .SH ENTRY BINDINGS You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its \fIbindtags\fR. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag \f(CWall\fR that all node entries automatically have. .SH "TREEVIEW OPERATIONS" The \fBtreeview\fR operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .CS \fIpathName operation \fR?\fIarg arg ...\fR? .CE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operation are available for \fBtreeview\fR widgets: .TP \fIpathName \fBbbox\fR ?\fB-screen\fR? \fItagOrId...\fR Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more \fItagOrId\fR arguments. If the \fB\-screen\fR flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from \f(CW0\fR from the root node. The returned list contains the following values. .RS .TP 1.25i \fIx\fR X-coordinate of the upper-left corner of the bounding box. .TP \fIy\fR Y-coordinate of the upper-left corner of the bounding box. .TP \fIwidth\fR Width of the bounding box. .TP \fIheight\fR Height of the bounding box. .RE .TP \fIpathName \fBbind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a node with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR entries, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton \fIoperation\fR ?\fIargs\fR? This command is used to control the button selectors within a \fBtreeview\fR widget. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBbutton activate\fR \fItagOrId\fR Designates the node given by \fItagOrId\fR as active. When a node is active it's entry is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active entry at a time. The special id \fBactive\fR indicates the currently active node. .TP \fIpathName \fBbutton bind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an button of a node entry with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR buttons, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBbutton configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "BUTTON OPTIONS" below. .RE .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBclose \fR?\fB\-recurse\fR? \fItagOrId...\fR Closes the node specified by \fItagOrId\fR. In addition, if a Tcl script was specified by the \fB\-closecommand\fR option, it is invoked. If the node is already closed, this command has no effect. If the \fB\-recurse\fR flag is present, each child node is recursively closed. .TP \fIpathName \fBcolumn \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview columns. .RS .TP \fIpathName \fBcolumn activate\fR \fIcolumn\fR Sets the active column to \fIcolumn\fR. \fIColumn\fR is the name of a column in the widget. When a column is active, it's drawn using its \fB\-activetitlebackground\fR and \fB\-activetitleforeground\fR options. If \fIcolumn\fR is the \f(CW""\fR, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. .TP \fIpathName \fBcolumn cget\fR \fIname\fR \fIoption\fR Returns the current value of the column configuration option given by \fIoption\fR for \fIname\fR. \fIName\fR is the name of column that corresponds to a data field. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBcolumn configure\fR \fIname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the column designated by \fIname\fR. \fIName\fR is the name of the column corresponding to a data field. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "COLUMN OPTIONS" below. .TP \fIpathName \fBcolumn delete\fR \fIfield\fR ?\fIfield\fR...? Deletes one of more columns designated by \fIfield\fR. Note that this does not delete the data fields themselves. .TP \fIpathName \fBcolumn insert\fR \fIposition\fR \fIfield\fR ?\fIoptions\fR...? Inserts one of more columns designated by \fIfield\fR. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. \fIPosition\fR indicates where in the list of columns to add the new column. It may be either a number or \f(CWend\fR. .TP \fIpathName \fBcolumn invoke\fR \fIfield\fR Invokes the Tcl command associated with the column \fIfield\fR, if there is one (using the column's \fB\-command\fR option). The command is ignored if the column's \fB\-state\fR option set to \f(CWdisabled\fR. .TP \fIpathName \fBcolumn move \fIname\fR \fIdest\fR Moves the column \fIname\fR to the destination position. \fIDest\fR is the name of another column or a screen position in the form \f(CW@\fIx\f(CW,\fIy\fR. .TP \fIpathName \fBcolumn names\fR Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. .TP \fIpathName \fBcolumn nearest\fR \fIx\fR ?\fIy\fR? Returns the name of the column closest to the given X-Y screen coordinate. If you provide a \fIy\fR argument (it's optional), a name is returned only when if the point is over a column's title. .RE .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TREEVIEW OPTIONS" below. .TP \fIpathName \fBcurselection\fR Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. .TP \fIpathName \fBdelete \fItagOrId\fR... Deletes one or more entries given by \fItagOrId\fR and its children. .TP \fIpathName \fBentry \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview entries. .RS .TP \fIpathName \fBentry activate\fR \fItagOrId\fR Sets the active entry to the one specified by \fItagOrId\fR. When an entry is active it is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active node at a time. The special id of the currently active node is \fBactive\fR. .TP \fIpathName \fBentry cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBentry children\fR \fItagOrId\fR ?\fIfirst\fR? ?\fIlast\fR? Returns a list of ids for the given range of children of \fItagOrId\fR. \fITagOrId\fR is the id or tag of the node to be examined. If only a \fIfirst\fR argument is present, then the id of the that child at that numeric position is returned. If both \fIfirst\fR and \fIlast\fR arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. .TP \fIpathName \fBentry configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .TP \fIpathName \fBentry delete\fR \fItagOrId\fR ?\fIfirst\fR ?\fIlast\fR? Deletes the one or more children nodes of the parent \fItagOrId\fR. If \fIfirst\fR and \fIlast\fR arguments are present, they are positions designating a range of children nodes to be deleted. .TP \fIpathName \fBentry isbefore \fItagOrId1\fR \fItagOrId2\fR Returns 1 if \fItagOrId1\fR is before \fItagOrId2\fR and 0 otherwise. .TP \fIpathName \fBentry ishidden \fItagOrId\fR Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. .TP \fIpathName \fBentry isopen \fItagOrId\fR Returns 1 if the node is currently open and 0 otherwise. .TP \fIpathName \fBentry size\fR \fB\-recurse\fR \fItagOrId\fR Returns the number of children for parent node \fItagOrId\fR. If the \fB\-recurse\fR flag is set, the number of all its descendants is returned. The node itself is not counted. .RE .TP \fIpathName \fBfind \fR?\fIflags\fR? \fIfirst\fR \fIlast\fR Finds for all entries matching the criteria given by \fIflags\fR. A list of ids for all matching nodes is returned. \fIFirst\fR and \fIlast\fR are ids designating the range of the search in depth-first order. If \fIlast\fR is before \fIfirst\fR, then nodes are searched in reverse order. The valid flags are: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Patterns must match exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Pick entries that don't match. .TP 1.25i \fB\-exec\fI string\fR Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP 1.25i \fB\-count\fI number\fR Stop searching after \fInumber\fR matches. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBfocus \fR \fItagOrId\fR Sets the focus to the node given by \fItagOrId\fR. When a node has focus, it can receive keyboard events. The special id \fBfocus\fR designates the node that currently has focus. .TP \fIpathName \fBget \fR?\fB\-full\fR? \fItagOrId\fR \fItagOrId\fR... Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the \fB\-full\fR flag is set, then the full pathnames are returned. .TP \fIpathName \fBhide \fR?\fBflags\fR? \fItagOrId\fR... Hides all nodes matching the criteria given by \fIflags\fR. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Hide nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBindex \fR?\fB\-at\fR \fItagOrId\fR? \fIstring\fR Returns the id of the node specified by \fIstring\fR. \fIString\fR may be a tag or node id. Some special ids are normally relative to the node that has focus. The \fB\-at\fR flag lets you select another node. .TP \fIpathName \fBinsert \fR?\fB\-at \fItagOrId\fR? \fIposition\fR \fIpath\fR ?\fIoptions...\fR? ?\fIpath\fR? ?\fIoptions...\fR? Inserts one or more nodes at \fIposition\fR. \fIPosition\fR is the location (number or \f(CWend\fR) where the new nodes are added to the parent node. \fIPath\fR is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the \fB\-separator\fR option). Pathnames are normally absolute, but the \fB\-at\fR switch lets you select a relative starting point. Its value is the id of the starting node. .sp All ancestors of the new node must already exist, unless the \fB\-autocreate\fR option is set. It is also an error if a node already exists, unless the \fB\-allowduplicates\fR option is set. .sp \fIOption\fR and \fIvalue\fR may have any of the values accepted by the \fBentry configure\fR operation described in the .SB "ENTRY OPERATIONS" section below. This command returns a list of the ids of the new entries. .TP \fIpathName \fBmove \fItagOrId\fR \fIhow\fR \fIdestId\fR Moves the node given by \fItagOrId\fR to the destination node. The node can not be an ancestor of the destination. \fIDestId\fR is the id of the destination node and can not be the root of the tree. In conjunction with \fIhow\fR, it describes how the move is performed. .RS .TP 8 \f(CWbefore\fR Moves the node before the destination node. .TP 8 \f(CWafter\fR Moves the node after the destination node. .TP 8 \f(CWinto\fR Moves the node to the end of the destination's list of children. .RE .TP \fIpathName \fBnearest \fIx y\fR ?\fIvarName\fR? Returns the id of the node entry closest to the given X-Y screen coordinate. The optional argument \fIvarName\fR is the name of variable which is set to either \f(CWbutton\fR or \f(CWselect\fR to indicate over what part of the node the coordinate lies. If the coordinate is not directly over any node, then \fIvarName\fR will contain the empty string. .TP \fIpathName \fBopen \fR?\fB\-recurse\fR? \fItagOrId...\fR Opens the one or more nodes specified by \fItagOrId\fR. If a node is not already open, the Tcl script specified by the \fB\-opencommand\fR option is invoked. If the \fB\-recurse\fR flag is present, then each descendant is recursively opened. .TP \fIpathName \fBrange\fR ?\fB-open\fR? \fIfirst last\fR Returns the ids in depth-first order of the nodes between the \fIfirst\fR and \fIlast\fR ids. If the \fB\-open\fR flag is present, it indicates to consider only open nodes. If \fIlast\fR is before \fIfirst\fR, then the ids are returned in reverse order. .TP \fIpathName \fBscan\fR \fIoption args\fR This command implements scanning. It has two forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBscan mark \fIx y\fR Records \fIx\fR and \fIy\fR and the current view in the treeview window; used in conjunction with later \fBscan dragto\fR commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. .TP \fIpathName \fBscan dragto \fIx y\fR. Computes the difference between its \fIx\fR and \fIy\fR arguments and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. .RE .TP \fIpathName \fBsee\fR ?\fB\-anchor \fIanchor\fR? \fItagOrId\fR Adjusts the view of entries so that the node given by \fItagOrId\fR is visible in the widget window. It is an error if \fBtagOrId\fR is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the \fB\-anchor\fR flag. Its value is a Tk anchor position. .TP \fIpathName \fBselection \fIoption arg\fR This command is used to adjust the selection within a \fBtreeview\fR widget. It has several forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBselection anchor \fItagOrId\fR Sets the selection anchor to the node given by \fItagOrId\fR. If \fItagOrId\fR refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBanchor\fR may be used to refer to the anchor node. .TP \fIpathName \fBselection cancel\fR Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the \fBselection mark\fR operation. .TP \fIpathName \fBselection clear \fIfirst \fR?\fIlast\fR? Removes the entries between \fIfirst\fR and \fIlast\fR (inclusive) from the selection. Both \fIfirst\fR and \fIlast\fR are ids representing a range of entries. If \fIlast\fR isn't given, then only \fIfirst\fR is deselected. Entries outside the selection are not affected. .TP \fIpathName \fBselection clearall\fR Clears the entire selection. .TP \fIpathName \fBselection mark \fItagOrId\fR Sets the selection mark to the node given by \fItagOrId\fR. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBmark\fR may be used to refer to the current mark node. If \fItagOrId\fR refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. .TP \fIpathName \fBselection includes \fItagOrId\fR Returns 1 if the node given by \fItagOrId\fR is currently selected, 0 if it isn't. .TP \fIpathName \fBselection present\fR Returns 1 if any nodes are currently selected and 0 otherwise. .TP \fIpathName \fBselection set \fIfirst \fR?\fIlast\fR? Selects all of the nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, without affecting the selection state of nodes outside that range. .TP \fIpathName \fBselection toggle \fIfirst \fR?\fIlast\fR? Selects/deselects nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. .RE .TP \fIpathName \fBshow \fR?\fBflags\fR? \fItagOrId\fR... Exposes all nodes matching the criteria given by \fIflags\fR. This is the inverse of the \fBhide\fR operation. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Expose nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBsort\fR ?\fIoperation\fR? \fIargs...\fR .RS .TP \fIpathName \fBsort auto\fR ?\fIboolean\fR Turns on/off automatic sorting of node entries. If \fIboolean\fR is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no \fIboolean\fR argument is provided, the current state is returned. .TP \fIpathName \fBsort cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBsort configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the sorting configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .RS .TP \fB\-column\fI string\fR Specifies the column to sort. Entries in the widget are rearranged according to this column. If \fIcolumn\fR is \f(CW""\fR then no sort is performed. .TP \fB\-command\fI string\fR Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. .TP \fB\-decreasing\fI boolean\fR Indicates to sort in ascending/descending order. If \fIboolean\fR is true, then the entries as in descending order. The default is \f(CWno\fR. .TP \fB\-mode\fI string\fR Specifies how to compare entries when sorting. \fIString\fR may be one of the following: .RS .TP 1.5i \f(CWascii\fR Use string comparison based upon the ASCII collation order. .TP 1.5i \f(CWdictionary\fR Use dictionary-style comparison. This is the same as \f(CWascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". .TP 1.5i \f(CWinteger\fR Compares fields as integers. .TP 1.5i \f(CWreal\fR Compares fields as floating point numbers. .TP 1.5i \f(CWcommand\fR Use the Tcl proc specified by the \fB\-command\fR option to compare entries when sorting. If no command is specified, the sort reverts to \f(CWascii\fR sorting. .RE .RE .TP \fIpathName \fBsort once\fR ?\fIflags\fR? \fItagOrId...\fR Sorts the children for each entries specified by \fItagOrId\fR. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. .RS .TP 1.5i \fB\-recurse\fR Recursively sort the entire branch, not just the children. .RE .RE .TP \fIpathName \fBtag \fIoperation args\fR Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. .sp Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tags are listed below. .RS .TP \fIpathName\fR \fBtag add\fR \fIstring\fR \fIid\fR... Adds the tag \fIstring\fR to one of more entries. .TP \fIpathName\fR \fBtag delete\fR \fIstring\fR \fIid\fR... Deletes the tag \fIstring\fR from one or more entries. .TP \fIpathName\fR \fBtag forget\fR \fIstring\fR Removes the tag \fIstring\fR from all entries. It's not an error if no entries are tagged as \fIstring\fR. .TP \fIpathName\fR \fBtag names\fR ?\fIid\fR? Returns a list of tags used. If an \fIid\fR argument is present, only those tags used by the node designated by \fIid\fR are returned. .TP \fIpathName\fR \fBtag nodes\fR \fIstring\fR Returns a list of ids that have the tag \fIstring\fR. If no node is tagged as \fIstring\fR, then an empty string is returned. .RE .TP \fIpathName \fBtext \fIoperation\fR ?\fIargs\fR? This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBtext apply\fR Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. .TP \fIpathName \fBtext cancel\fR Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. .TP \fIpathName \fBtext cget\fI value\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBtext configure\fR ?\fIoption value\fR? Query or modify the configuration options of the edit window. If no \fIoption\fR is specified, returns a list describing all of the available options (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TEXT EDITING OPTIONS" below. .RE .TP \fIpathName \fBtext delete\fI first last\fR Deletes the characters in the edit buffer between the two given character positions. .TP \fIpathName \fBtext get\fR ?\fI\-root\fR? \fIx y\fR .TP \fIpathName \fBtext icursor\fI index\fR .TP \fIpathName \fBtext index\fI index\fR Returns the text index of given \fIindex\fR. .TP \fIpathName \fBtext insert\fI index string\fR Insert the text string \fIstring\fR into the edit buffer at the index \fIindex\fR. For example, the index 0 will prepend the buffer. .TP \fIpathName \fBtext selection\fI args\fR This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: .RS .TP \fIpathName \fBtext selection adjust\fI index\fR Adjusts either the first or last index of the selection. .TP \fIpathName \fBtext selection clear\fR Clears the selection. .TP \fIpathName \fBtext selection from\fI index\fR Sets the anchor of the selection. .TP \fIpathName \fBtext selection present\fR Indicates if a selection is present. .TP \fIpathName \fBtext selection range\fI start end\fR Sets both the anchor and mark of the selection. .TP \fIpathName \fBtext selection to\fI index\fR Sets the unanchored end (mark) of the selection. .RE .TP \fIpathName \fBtoggle \fItagOrId\fR Opens or closes the node given by \fItagOrId\fR. If the corresponding \fB\-opencommand\fR or \fB\-closecommand\fR option is set, then that command is also invoked. .TP \fIpathName \fBxview \fIargs\fR This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fBxview\fR Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the \fBtreeview\fR widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR option. .TP \fIpathName \fBxview\fR \fItagOrId\fR Adjusts the view in the window so that the character position given by \fItagOrId\fR is displayed at the left edge of the window. Character positions are defined by the width of the character \fB0\fR. .TP \fIpathName \fBxview moveto\fI fraction\fR Adjusts the view in the window so that \fIfraction\fR of the total width of the \fBtreeview\fR widget's text is off-screen to the left. \fIfraction\fR must be a fraction between 0 and 1. .TP \fIpathName \fBxview scroll \fInumber what\fR This command shifts the view in the window left or right according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation of one of these. If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by \fInumber\fR character units (the width of the \fB0\fR character) on the display; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. .RE .TP \fIpathName \fByview \fI?args\fR? This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fByview\fR Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR option. .TP \fIpathName \fByview\fR \fItagOrId\fR Adjusts the view in the window so that the node given by \fItagOrId\fR is displayed at the top of the window. .TP \fIpathName \fByview moveto\fI fraction\fR Adjusts the view in the window so that the node given by \fIfraction\fR appears at the top of the window. \fIFraction\fR is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the \fBtreeview\fR widget, and so on. .TP \fIpathName \fByview scroll \fInumber what\fR This command adjusts the view in the window up or down according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR. If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by \fInumber\fR lines; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then earlier nodes become visible; if it is positive then later nodes become visible. .RE .SH "TREEVIEW OPTIONS" In addition to the \fBconfigure\fR operation, widget configuration options may also be set by the Tk \fBoption\fR command. The class resource name is \f(CWTreeView\fR. .CS option add *TreeView.Foreground white option add *TreeView.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed for an entry's icon when it is active. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-autocreate \fIboolean\fR If \fIboolean\fR is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-allowduplicates \fIboolean\fR If \fIboolean\fR is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-background \fIcolor\fR Sets the background color of the widget. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's \fB\-closecommand\fR option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-dashes \fInumber\fR Sets the dash style of the horizontal and vertical lines drawn connecting entries. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, solid lines will be drawn. The default is \f(CW1\fR (dotted). .TP \fB\-exportselection \fIboolean\fR Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR; the value of the selection will be the label of the selected nodes, separated by newlines. The default is \f(CWno\fR. .TP \fB\-flat \fIboolean\fR Indicates whether to display the tree as a flattened list. If \fIboolean\fR is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the .SB "SORT OPERATIONS" section for more information. The default is \f(CWno\fR. .TP \fB\-focusdashes \fIdashList\fR Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, a solid line will be drawn. The default is \f(CW1\fR. .TP \fB\-focusforeground \fIcolor\fR Sets the color of the focus rectangle. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Specifies the font for entry labels. You can override this for individual entries with the entry's \fB\-font\fR configuration option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of entry labels. You can override this for individual entries with the entry's \fB\-foreground\fR configuration option. The default is \f(CWblack\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW400\fR. .TP \fB\-hideroot \fIboolean\fR If \fIboolean\fR is true, it indicates that no entry for the root node should be displayed. The default is \f(CWno\fR. .TP \fB\-highlightbackground \fIcolor\fR Specifies the normal color of the traversal highlight region when the widget does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight will be displayed. The default is \f(CW2\fR. .TP \fB\-icons \fIimages\fR Specifies images for the entry's icon. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-linecolor \fIcolor\fR Sets the color of the connecting lines drawn between entries. The default is \f(CWblack\fR. .TP \fB\-linespacing \fIpixels\fR Sets the number of pixels spacing between entries. The default is \f(CW0\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the lines drawn connecting entries. If \fIpixels\fR is \f(CW0\fR, no vertical or horizontal lines are drawn. The default is \f(CW1\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's \fB\-opencommand\fR configuration option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the widget. \fIRelief\fR specifies how the \fBtreeview\fR widget should appear relative to widget it is packed into; for example, \f(CWraised\fR means the \fBtreeview\fR widget should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-scrollmode \fImode\fR Specifies the style of scrolling to be used. The following styles are valid. This is the default is \f(CWhierbox\fR. .RS .TP 1.25i \f(CWlistbox\fR Like the \fBlistbox\fR widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. .TP 1.25i \f(CWhierbox\fR Like the \fBhierbox\fR widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. .TP 1.25i \f(CWcanvas\fR Like the \fBcanvas\fR widget, the entries are bound within the scrolling area. .RE .TP \fB\-selectbackground \fIcolor\fR Sets the background color selected node entries. The default is \f(CW#ffffea\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is \f(CW0\fR. \fB\-selectcommand \fIstring\fR Specifies a Tcl script to invoked when the set of selected nodes changes. The default is \f(CW""\fR. .TP \fB\-selectforeground \fIcolor\fB Sets the color of the labels of selected node entries. The default is \f(CWblack\fR. .TP \fB\-selectmode \fImode\fR Specifies the selection mode. If \fImode\fR is \f(CWsingle\fR, only one node can be selected at a time. If \f(CWmultiple\fR more than one node can be selected. The default is \f(CWsingle\fR. .TP \fB\-separator \fIstring\fR Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If \fIstring\fR is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is \f(CW""\fR. .TP \fB\-showtitles \fIboolean\fR If \fIboolean\fR is false, column titles are not be displayed. The default is \f(CWyes\fR. .TP \fB\-sortselection \fIboolean\fR If \fIboolean\fR is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is \f(CWno\fR. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW"1"\fR. .TP \fB\-trim \fIstring\fR Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the \fB\-separator\fR is also set. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the widget. If \fIpixels\fR is 0, then the with is computed from the contents of the \fBtreeview\fR widget. The default is \f(CW200\fR. .TP \fB\-xscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-xscrollincrement\fR \fIpixels\fR Sets the horizontal scrolling distance. The default is 20 pixels. .TP \fB\-yscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-yscrollincrement\fR \fIpixels\fR Sets the vertical scrolling distance. The default is 20 pixels. .SH "ENTRY OPTIONS" Many widget configuration options have counterparts in entries. For example, there is a \fB\-closecommand\fR configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. .PP There is no resource class or name for entries. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed as the entry's icon when it is active. This overrides the global \fB\-activeicons\fR configuration option for the specific entry. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for nodes. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is \f(CWall\fR. .TP \fB\-button \fIstring\fR Indicates whether a button should be displayed on the left side of the node entry. \fIString\fR can be \f(CWyes\fR, \f(CWno\fR, or \f(CWauto\fR. If \f(CWauto\fR, then a button is automatically displayed if the node has children. This is the default. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when the node is closed. This overrides the global \fB\-closecommand\fR option for this entry. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-data \fIstring\fR Sets data fields for the node. \fIString\fR is a list of name-value pairs to be set. The default is \f(CW""\fR. .TP \fB\-font \fIfontName\fR Sets the font for entry labels. This overrides the widget's \fB\-font\fR option for this node. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of the entry label. This overrides the widget's \fB\-foreground\fR configuration option. The default is \f(CW""\fR. .TP \fB\-icons \fIimages\fR Specifies images to be displayed for the entry's icon. This overrides the global \fB\-icons\fR configuration option. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-label \fIstring\fR Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is \f(CW""\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's \fB\-opencommand\fR option for this node. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .SH "BUTTON OPTIONS" Button configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWButton\fR. The resource name is always \f(CWbutton\fR. .CS option add *TreeView.Button.Foreground white option add *TreeView.button.Background blue .CE The following are the configuration options available for buttons. .TP \fB\-activebackground \fIcolor\fR Sets the background color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-background \fIcolor\fR Sets the background of the button. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the button. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-closerelief \fIrelief\fR Specifies the 3-D effect for the closed button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-cursor \fIcursor\fR Sets the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of buttons. The default is \f(CWblack\fR. .TP \fB\-images \fIimages\fR Specifies images to be displayed for the button. \fIImages\fR is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the \fIimages\fR is the empty string, then a plus/minus gadget is drawn. The default is \f(CW""\fR. .TP \fB\-openrelief \fIrelief\fR Specifies the 3-D effect of the open button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-size \fIpixels\fR Sets the requested size of the button. The default is \f(CW0\fR. .RE .SH "COLUMN OPTIONS" Column configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWColumn\fR. The resource name is the name of the column. .CS option add *TreeView.Column.Foreground white option add *TreeView.treeView.Background blue .CE The following configuration options are available for columns. .TP \fB\-background \fIcolor\fR Sets the background color of the column. This overrides the widget's \fB\-background\fR option. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border of the column. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW0\fR. .TP \fB\-edit \fIboolean\fR Indicates if the column's data fields can be edited. If \fIboolean\fR is false, the data fields in the column may not be edited. The default is \f(CWyes\fR. .TP \fB\-foreground \fIcolor\fR Specifies the foreground color of the column. You can override this for individual entries with the entry's \fB\-foreground\fR option. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Sets the font for a column. You can override this for individual entries with the entry's \fB\-font\fR option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-hide \fIboolean\fR If \fIboolean\fR is true, the column is not displayed. The default is \f(CWyes\fR. .TP \fB\-justify \fIjustify\fR Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWleft\fR. .TP \fB\-pad \fIpad\fR Specifies how much padding for the left and right sides of the column. \fIPad\fR is a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the column is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the column. \fIRelief\fR specifies how the column should appear relative to the widget; for example, \f(CWraised\fR means the column should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-state \fIstate\fR Sets the state of the column. If \fIstate\fR is \f(CWdisable\fR then the column title can not be activated nor invoked. The default is \f(CWnormal\fR. .TP \fB\-text \fIstring\fR Sets the title for the column. The default is \f(CW""\fR. .TP \fB\-titleforeground \fIcolor\fR Sets the foreground color of the column title. The default is \f(CWblack\fR. .TP \fB\-titleshadow \fIcolor\fR Sets the color of the drop shadow of the column title. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the column. This overrides the computed with of the column. If \fIpixels\fR is 0, the width is computed as from the contents of the column. The default is \f(CW0\fR. .RE .SH "TEXT EDITING OPTIONS" Text edit window configuration options may also be set by the \fBoption\fR command. The resource class is \f(CWTreeViewEditor\fR. The resource name is always \f(CWedit\fR. .CS option add *TreeViewEditor.Foreground white option add *edit.Background blue .CE The following are the configuration options available for the text editing window. .TP \fB\-background \fIcolor\fR Sets the background of the text edit window. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the edit window. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-exportselection \fIboolean\fR Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the edit window. \fIRelief\fR indicates how the background should appear relative to the edit window; for example, \f(CWraised\fR means the background should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-selectbackground \fIcolor\fR Sets the background of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the 3\-D border around the selected text in the edit window. The \fB\-selectrelief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-selectforeground \fIcolor\fR Sets the foreground of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectrelief \fIrelief\fR Specifies the 3-D effect of the selected text in the edit window. \fIRelief\fR indicates how the text should appear relative to the edit window; for example, \f(CWraised\fR means the text should appear to protrude. The default is \f(CWflat\fR. .RE .SH "DEFAULT BINDINGS" Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a \fBtreeview\fR widget is determined by its \fB\-selectmode\fR option, which selects one of two ways of dealing with the selection. .PP If the selection mode is \fBsingle\fR, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. .PP If the selection mode is \fBmultiple\fR, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. .IP [1] In \fBextended\fR mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. .IP [2] In \fBextended\fR mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. .IP [3] If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. .IP [4] Mouse button 2 may be used for scanning. If it is pressed and dragged over the \fBtreeview\fR widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. .IP [5] If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is \fBbrowse\fR or \fBextended\fR then the new active entry is also selected and all other entries are deselected. In \fBextended\fR mode the new active entry becomes the selection anchor. .IP [6] In \fBextended\fR mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. .IP [7] The Left and Right keys scroll the \fBtreeview\fR widget view left and right by the width of the character \fB0\fR. Control-Left and Control-Right scroll the \fBtreeview\fR widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. .IP [8] The Prior and Next keys scroll the \fBtreeview\fR widget view up and down by one page (the height of the window). .IP [9] The Home and End keys scroll the \fBtreeview\fR widget horizontally to the left and right edges, respectively. .IP [10] Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. .IP [11] Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. .IP [12] In \fBextended\fR mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. .IP [13] In \fBmultiple\fR mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. .IP [14] The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. .IP [15] In \fBextended\fR mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. .IP [16] In \fBextended\fR mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. .IP [17] Control-slash selects everything in the widget, except in \fBsingle\fR and \fBbrowse\fR modes, in which case it selects the active entry and deselects everything else. .IP [18] Control-backslash deselects everything in the widget, except in \fBbrowse\fR mode where it has no effect. .IP [19] The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. .PP The behavior of \fBtreeview\fR widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. .SS WIDGET BINDINGS In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. .IP \f(CW<ButtonPress-2>\fR Starts scanning. .IP \f(CW<B2-Motion>\fR Adjusts the scan. .IP \f(CW<ButtonRelease-2>\fR Stops scanning. .IP \f(CW<B1-Leave>\fR Starts auto-scrolling. .IP \f(CW<B1-Enter>\fR Starts auto-scrolling .IP \f(CW<KeyPress-Up>\fR Moves the focus to the previous entry. .IP \f(CW<KeyPress-Down>\fR Moves the focus to the next entry. .IP \f(CW<Shift-KeyPress-Up>\fR Moves the focus to the previous sibling. .IP \f(CW<Shift-KeyPress-Down>\fR Moves the focus to the next sibling. .IP \f(CW<KeyPress-Prior>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Next>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Left>\fR Closes the entry. It is not an error if the entry has no children. .IP \f(CW<KeyPress-Right>\fR Opens the entry, displaying its children. It is not an error if the entry has no children. .IP \f(CW<KeyPress-space>\fR In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). .IP \f(CW<KeyRelease-space>\fR Turns off select mode. .IP \f(CW<KeyPress-Return>\fR Sets the focus to the current entry. .IP \f(CW<KeyRelease-Return>\fR Turns off select mode. .IP \f(CW<KeyPress>\fR Moves to the next entry whose label starts with the letter typed. .IP \f(CW<KeyPress-Home>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-End>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-F1>\fR Opens all entries. .IP \f(CW<KeyPress-F2>\fR Closes all entries (except root). .SS BUTTON BINDINGS Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the button of the current entry. .IP \f(CW<Leave>\fR Returns the button back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Adjust the view so that the current entry is visible. .SS ENTRY BINDINGS Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to modify them. .IP \f(CW<Enter>\fR Highlights the current entry. .IP \f(CW<Leave>\fR Returns the entry back to its normal state. .IP \f(CW<ButtonPress-1>\fR Sets the selection anchor the current entry. .IP \f(CW<Double-ButtonPress-1>\fR Toggles the selection of the current entry. .IP \f(CW<B1-Motion>\fR For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. .IP \f(CW<ButtonRelease-1>\fR For "multiple" mode only. Sets the selection anchor to the current entry. .IP \f(CW<Shift-ButtonPress-1>\fR For "multiple" mode only. Extends the selection. .IP \f(CW<Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Shift-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Shift-ButtonRelease-1>\fR Stop auto-scrolling. .IP \f(CW<Control-ButtonPress-1>\fR For "multiple" mode only. Toggles and extends the selection. .IP \f(CW<Control-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Control-ButtonRelease-1>\fR Stops auto-scrolling. .IP \f(CW<Control-Shift-ButtonPress-1>\fR ??? .IP \f(CW<Control-Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-Shift-B1-Motion>\fR Place holder. Does nothing. .SS COLUMN BINDINGS Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the \fBcolumn bind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the current column title. .IP \f(CW<Leave>\fR Returns the column back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Invokes the command (see the column's -command option) if one if specified. .SS COLUMN RULE BINDINGS .IP \f(CW<Enter>\fR Highlights the current and activates the ruler. .IP \f(CW<Leave>\fR Returns the column back to its normal state. Deactivates the ruler. .IP \f(CW<ButtonPress-1>\fR Sets the resize anchor for the column. .IP \f(CW<B1-Motion>\fR Sets the resize mark for the column. .IP \f(CW<ButtonRelease-1>\fR Adjust the size of the column, based upon the resize anchor and mark positions. .SH EXAMPLE The \fBtreeview\fR command creates a new widget. .CS treeview .h \-bg white .CE A new Tcl command \f(CW.h\fR is also created. This command can be used to query and modify the \fBtreeview\fR widget. For example, to change the background color of the table to "green", you use the new command and the widget's \fBconfigure\fR operation. .CS # Change the background color. \&.h configure \-background "green" .CE By default, the \fBtreeview\fR widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the \fB\-tree\fR option to specify the name of another tree. .CS # View the tree "myTree". \&.h configure \-tree "myTree" .CE When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always \f(CW0\fR (you can use also use the special id \f(CWroot\fR). The \fBinsert\fR operation lets you insert one or more new entries into the tree. The last argument is the node's \fIpathname\fR. .CS # Create a new entry named "myEntry" set id [\&.h insert end "myEntry"] .CE This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. .CS # Prepend "fred". set id [\&.h insert 0 "fred"] .CE Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the \fB\-label\fR option. .CS # Create a new node named "fred" set id [\&.h insert end "fred" -label "Fred Flintstone"] .CE The \fBinsert\fR operation returns the id of the new node. You can also use the \fBindex\fR operation to get this information. .CS # Get the id of "fred" \&.h index "fred" .CE To insert a node somewhere other than root, use the \fB\-at\fR switch. It takes the id of the node where the new child will be added. .CS # Create a new node "barney" in "fred". \&.h insert -at $id end "barney" .CE A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. .CS # Create a new sub-entry of "fred" \&.h insert end "fred barney" .CE Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the \fB\-autocreate\fR configuration option to force the creation of ancestor nodes. .CS # Force the creation of ancestors. \&.h configure -autocreate yes \&.h insert end "fred barney wilma betty" .CE Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the \fB\-separator\fR option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. .CS \&.h configure -separator / \&.h insert end "/usr/local/tcl/bin" .CE If the path is prefixed by extraneous characters, you can automatically trim it off using the \fB\-trim\fR option. It removed the string from the path before it is parsed. .CS \&.h configure -trim C:/windows -separator / \&.h insert end "C:/window/system" .CE You can insert more than one entry at a time with the \fBinsert\fR operation. This can be much faster than looping over a list of names. .CS # The slow way foreach f [glob $dir/*] { \&.h insert end $f } # The fast way eval .h insert end [glob $dir/*] .CE In this case, the \fBinsert\fR operation will return a list of ids of the new entries. .PP You can delete entries with the \fBdelete\fR operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. .CS \&.h delete $id .CE Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the \fB\-label\fR option that sets the entry's text label. The \fBentry configure\fR operation lets you set or modify an entry's configuration options. .CS \&.h entry configure $id -color red -font fixed .CE You can hide an entry and its children using the \fB\-hide\fR option. .CS \&.h entry configure $id -hide yes .CE More that one entry can be configured at once. All entries specified are configured with the same options. .CS \&.h entry configure $i1 $i2 $i3 $i4 -color brown .CE An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's \fB\-icons\fR option. It takes a list of two image names: one to represent the open entry, another when it is closed. .CS set im1 [image create photo -file openfolder.gif] set im2 [image create photo -file closefolder.gif] \&.h entry configure $id -icons "$im1 $im2" .CE If \fB\-icons\fR is set to the empty string, no icons are display. .PP If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol, but can be configured in a variety of ways using the \fBbutton configure\fR operation. For example, the \f(CW+\fR and \f(CW\-\fR symbols can be replaced with Tk images. .CS set im1 [image create photo -file closefolder.gif] set im2 [image create photo -file downarrow.gif] \&.h button configure $id -images "$im1 $im2" \\ -openrelief raised -closerelief raised .CE Entries can contain an arbitrary number of \fIdata fields\fR. Data fields are name-value pairs. Both the value and name are strings. The entry's \fB\-data\fR option lets you set data fields. .CS \&.h entry configure $id -data {mode 0666 group users} .CE The \fB\-data\fR takes a list of name-value pairs. .PP You can display these data fields as \fIcolumns\fR in the \fBtreeview\fR widget. You can create and configure columns with the \fBcolumn\fR operation. For example, to add a new column to the widget, use the \fBcolumn insert\fR operation. The last argument is the name of the data field that you want to display. .CS \&.h column insert end "mode" .CE The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's \fB\-text\fR option. .CS \&.h column insert end "mode" -text "File Permissions" .CE Columns have several configuration options. The \fBcolumn configure\fR operation lets you query or modify column options. .CS \&.h column configure "mode" -justify left .CE The \fB\-justify\fR option says how the data is justified within in the column. The \fB\-hide\fR option indicates whether the column is displayed. .CS \&.h column configure "mode" -hide yes .CE Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the \fB\-selectforeground\fR and \fB\-selectbackground\fR configuration options. The selection itself is managed by the \fBselection\fR operation. .CS # Clear all selections \&.h selection clear 0 end # Select the root node \&.h selection set 0 .CE The \fBcurselection\fR operation returns a list of ids of all the selected entries. .CS set ids [\&.h curselection] .CE You can use the \fBget\fR operation to convert the ids to their pathnames. .CS set names [eval .h get -full $ids] .CE If a treeview is exporting its selection (using the \fB\-exportselection\fR option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type \fBSTRING\fR; the value of the selection will be the pathnames of the selected entries, separated by newlines. .PP The \fBtreeview\fR supports two modes of selection: \f(CWsingle\fR and \f(CWmultiple\fR. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -selectmode "multiple" .CE You can be notified when the list of selected entries changes. The widget's \fB\-selectcommand\fR specifies a Tcl procedure that is called whenever the selection changes. .CS proc SelectNotify { widget } { set ids [\&$widget curselection] } \&.h configure -selectcommand "SelectNotify .h" .CE The widget supports the standard Tk scrolling and scanning operations. The \fBtreeview\fR can be both horizontally and vertically. You can attach scrollbars to the \fBtreeview\fR the same way as the listbox or canvas widgets. .CS scrollbar .xbar -orient horizontal -command ".h xview" scrollbar .ybar -orient vertical -command ".h yview" \&.h configure -xscrollcommand ".xbar set" \\ -yscrollcommand ".ybar set" .CE There are three different modes of scrolling: \f(CWlistbox\fR, \f(CWcanvas\fR, and \f(CWhierbox\fR. In \f(CWlistbox\fR mode, the last entry can always be scrolled to the top of the widget. In \f(CWhierbox\fR mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -scrollmode "listbox" .CE Entries can be programmatically opened or closed using the \fBopen\fR and \fBclose\fR operations respectively. .CS \&.h open $id \&.h close $id .CE When an entry is opened, a Tcl procedure can be automatically invoked. The \fB\-opencommand\fR option specifies this procedure. This procedure can lazily insert entries as needed. .CS proc AddEntries { dir } { eval .h insert end [glob -nocomplain $dir/*] } \&.h configure -opencommand "AddEntries %P" .CE Now when an entry is opened, the procedure \f(CWAddEntries\fR is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like \fBbind\fR) are performed. Above, \f(CW%P\fR is translated to the pathname of the entry. .PP The same feature exists when an entry is closed. The \fB\-closecommand\fR option specifies the procedure. .CS proc DeleteEntries { id } { .h entry delete $id 0 end } \&.h configure -closecommand "DeleteEntries %#" .CE When an entry is closed, the procedure \f(CWDeleteEntries\fR is called and deletes the entry's children using the \fBentry delete\fR operation (\f(CW%#\fR is the id of entry). .SH KEYWORDS treeview, widget �����������������������������������������������./saods9/blt3.0.1/man/Blt_TreeGetNode.man3����������������������������������������������������������0000644�0001750�0001750�00000004446�11462120062�016547� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 1991-1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" .so man.macros .TH Blt_TreeGetNode 3 BLT_VERSION BLT "BLT Library Procedures" .BS .SH NAME Blt_TreeGetNode \- Finds the node from the ID. .SH SYNOPSIS .nf \fB#include <bltTree.h>\fR .sp Blt_TreeNode \fBBlt_TreeGetNode\fR(\fItree\fR, \fInumber\fR) .SH ARGUMENTS .AS "unsigned int" number .AP Blt_Tree tree in Tree containing the requested node. .AP "unsigned int" number in Serial number of the requested node. .BE .SH DESCRIPTION This procedure returns a node in a tree object based upon a give serial number. The node is searched using the serial number. .PP The arguments are as follows: .TP 1i \fItree\fR The tree containing the requested node. .TP 1i \fInumber\fR The serial number of the requested node. .SH RETURNS The node represented by the given serial number is returned. If no node with that ID exists in \fItree\fR then NULL is returned. .SH EXAMPLE The following example gets the node from a serial number. .CS unsigned int number; Blt_TreeNode node; Blt_TreeToken token; ... node = Blt_TreeGetNode(token, number); if (node == NULL) { printf("no node with ID %d exists\\n", number); } else { printf("node found: label is %s\\n", Blt_TreeNodeLabel(node)); } .CE .SH KEYWORDS Tcl_TreeCreateNode, Tcl_TreeDeleteNode ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/scrollset.mann����������������������������������������������������������������0000644�0001750�0001750�00000076516�11462120062�015715� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� '\" '\" Copyright 1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Scrollset widget created by George Howlett. '\" .so man.macros .TH scrollset n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME scrollset \- Create and manipulate scrollset widgets .BE .SH SYNOPSIS \fBscrollset\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBscrollset\fR manages a widget and two scrollbars, displaying the scrollbars only when they are needed to scroll the widget. The embedded widget may be any type of widget. If the widget doesn't have native scrolling capabilities (i.e. a "xview" or "yview" operation) the widget is by changing the scrollset viewport over the widget. .PP There's no limit to the number of folders. Tabs can be tiered (more than one row). If there are more tabs than can be displayed, tabs can also be scrolled. Any folder can also be torn off, when the contents (the Tk widget contained by it) is temporarily moved into another toplevel widget. A scrollset may used as just a set of tabs, without a displaying any pages. You can bind events to individual tabs, so it's easy to add features like "balloon help". .SH SYNTAX The \fBscrollset\fR command creates a new window using the \fIpathName\fR argument and makes it into a scrollset widget. .DS \fBscrollset \fIpathName \fR?\fIoption value\fR?... .DE Additional options may be specified on the command line or in the option database to configure aspects of the scrollset such as its background color, scrollbars, or embedded widget. The \fBscrollset\fR command returns its \fIpathName\fR argument. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. .PP The scrollbars and embedded widget must be children of the scrollset widget. The scrollbars and embedded widget may be designated in the \fBscrollset\fR widget before they exist. The normal size of of \fBscrollset\fR is the requested width and height of the embedded widget (where no scrollbars are necessary). You can override the embedded widget's requested size by setting the scrollset's \fB\-reqwidth\fR and \fB\-reqheight\fR options respectively. .SH "OPERATIONS" All \fBscrollset\fR operations are invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .DS \fIpathName operation \fR?\fIarg arg ...\fR? .DE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operations are available for scrollset widgets: .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described in the section .SB "WIDGET OPTIONS" below. .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "WIDGET OPTIONS" below. .TP \fIpathName \fBset \fBx\fR|\fBy\fIfirst\fR \fIlast\fR Scrolls the scrollset so that the tab \fItab\fR is visible in the widget's window. .TP \fIpathName \fBsize\fR Returns the number of tabs in the scrollset. .TP \fIpathName \fBtab \fIoperation\fR ?\fIargs\fR? .RS .TP \fIpathName \fBtab cget\fR \fItab\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR for tab \fItab\fR. \fIOption\fR may have any of the values accepted by the \fBtab configure\fR operation described in the section .SB "TAB OPTIONS" below. .TP \fIpathName \fBtab configure\fR \fItab\fR \fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of one or more tabs. More than one tab can be configured if \fItab\fR refers to multiple tabs. If no \fIoption\fR is specified, this operation returns a list describing all the available options for \fItab\fR. .sp If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the one named option is returned. If one or more \fIoption\-value\fR pairs are specified, then each named tab (specified by \fInameOrIndex\fR) will have its configurations option(s) set the given value(s). In this last case, the empty string is returned. \fIOption\fR and \fIvalue\fR are described in the section .SB "TAB OPTIONS" below. .TP \fIpathName \fBtab names\fR ?\fIpattern\fR? Returns the names of all the tabs matching the given pattern. If no \fIpattern\fR argument is provided, then all tab names are returned. .TP \fIpathName \fBtab tearoff \fItab\fR ?\fIwindow\fR? Moves the widget embedded the folder \fItab\fR (see the \fB-window\fR option), placing it inside of \fIwindow\fR. \fIWindow\fR is either the name of an new widget that will contain the embedded widget or the name of the \fBscrollset\fR widget. It the last case, the embedded widget is put back into the folder. .sp If no \fIwindow\fR argument is provided, then the name of the current parent of the embedded widget is returned. .RE .TP \fIpathName \fBview \fIargs\fR This command queries or changes the position of the scrollset in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fBview\fR Returns a list of two numbers between 0.0 and 1.0 that describe the amount and position of the scrollset that is visible in the window. For example, if \fIview\fR is "0.2 0.6", 20% of the scrollset's text is off-screen to the left, 40% is visible in the window, and 40% of the scrollset is off-screen to the right. These are the same values passed to scrollbars via the \fB\-scrollcommand\fR option. .TP \fIpathName \fBview moveto\fI fraction\fR Adjusts the view in the window so that \fIfraction\fR of the total width of the scrollset text is off-screen to the left. \fIfraction\fR must be a number between 0.0 and 1.0. .TP \fIpathName \fBview scroll \fInumber what\fR This command shifts the view in the window (left/top or right/bottom) according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation of these. If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by \fInumber\fR scroll units (see the \fB\-scrollincrement\fR option). ; if it is \fBpages\fR then the view adjusts by \fInumber\fR widget windows. If \fInumber\fR is negative then tabs farther to the left become visible; if it is positive then tabs farther to the right become visible. .RE .SH "WIDGET OPTIONS" Widget configuration options may be set either by the \fBconfigure\fR operation or the Tk \fBoption\fR command. The resource class is \f(CWScrollset\fR. The resource name is the name of the widget. .CS option add *Scrollset.Foreground white option add *Scrollset.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the default active background color for tabs. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB\-activebackground\fR option. .TP \fB\-activeforeground \fIcolor\fR Sets the default active foreground color for tabs. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB\-activeforeground\fR option. .TP \fB\-background \fIcolor\fR Sets the default background color of folders. Individual tabs can override this with their own \fBR-background\fR option. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around tabs and folders. The \fB\-relief\fR option determines how the border is to be drawn. The default is \f(CW1\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for both tabs and folders. \fIRelief\fR specifies how the tabs should appear relative to background of the widget; for example, \f(CWraised\fR means the tab should appear to protrude. The default is \f(CWraised\fR. .TP \fB\-troughbackground \fIcolor\fR Sets the background color of the trough under the tabs. .TP \fB\-outerborderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines how the border is to be drawn. The default is \f(CW0\fR. .TP \fB\-outerpad \fIpixels\fR Sets the amount of padding between the highlight ring on the outer edge of the scrollset and the folder. The default is \f(CW0\fR. .TP \fB\-outerrelief \fIrelief\fR Specifies the 3-D effect for the scrollset widget. \fIRelief\fR specifies how the scrollset should appear relative to widget that it is packed into; for example, \f(CWraised\fR means the scrollset should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the focus outline. When a tab has the widget's focus, it is drawn with a dashed outline around its label. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line. The default value is \f(CW5 2\fR. .TP \fB\-font \fIfontName\fR Sets the default font for the text in tab labels. Individual tabs may override this by setting the tab's \fB\-font\fR option. The default value is \f(CW*Arial 9\fR. .TP \fB\-foreground \fIcolor\fR Sets the default color of tab labels. Individual tabs may override this option by setting the tab's \fB\-foreground\fR option. The default value is \f(CWblack\fR. .TP \fB\-gap \fIsize\fR Sets the gap (in pixels) between tabs. The default value is \f(CW2\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. If \fIpixels\fR is 0, then the height of the widget will be calculated based on the size the tabs and their pages. The default is \f(CW0\fR. .TP \fB\-highlightbackground \fIcolor\fR Sets the color to display in the traversal highlight region when the scrollset does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Sets the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Sets the width of the highlight rectangle to draw around the outside of the widget when it has the input focus. \fIPixels\fR is a non-negative value and may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight is drawn around the widget. The default is \f(CW2\fR. .TP \fB\-pageheight \fIpixels\fR Sets the requested height of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum height of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-pagewidth \fIpixels\fR Sets the requested width of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum width of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-perforationcommand\fR \fIstring\fR Specifies a Tcl script to be invoked to tear off the current page in the scrollset. This command is typically invoked when left mouse button is released over the tab perforation. The default action is to tear-off the page and place it into a new toplevel window. .TP \fB\-rotate \fIangle\fR Specifies the degrees to rotate text in tab labels. \fIAngle\fR is a real value representing the number of degrees to rotate the text labels. The default is \f(CW0.0\fR degrees. .TP \fB\-tabwidth \fIwidth\fR Indicates the width of each tab. \fIWidth\fR can be one of the following: .RS .TP 1i \f(CWvariable\fR The width of the tab is determined by its text and image. .TP 1i \f(CWsame\fR The width of every tab is the maximum size. .TP 1i \f(CWpixels\fR The width of the tab is set to \fIpixels\R. \fIPixels\fR is a positive screen distance. .RE The default is \f(CWsame\fR. .TP \fB\-scrollcommand \fIstring\fR Specifies the prefix for a command for communicating with scrollbars. Whenever the view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-scrollincrement \fIpixels\fR Sets the smallest number of pixels to scroll the tabs. If \fIpixels\fR is greater than 0, this sets the units for scrolling (e.g., when you the change the view by clicking on the left and right arrows of a scrollbar). .TP \fB\-selectbackground \fIcolor\fR Sets the color to use when displaying background of the selected tab. Individual tabs can override this option by setting the tab's \fB\-selectbackground\fR option. '\".TP '\" \fB\-selectborderwidth \fIpixels\fR '\" Sets the width of the raised 3-D border to draw around the label of '\" the selected tab. \fIPixels\fR must be a non-negative value. '\" The default value is \f(CW1\fR. .TP \fB\-selectcommand \fIstring\fR Specifies a default Tcl script to be associated with tabs. This command is typically invoked when left mouse button is released over the tab. Individual tabs may override this with the tab's \fB\-command\fR option. The default value is \f(CW""\fR. .TP \fB\-selectforeground \fIcolor\fB Sets the default color of the selected tab's text label. Individual tabs can override this option by setting the tab's \fB\-selectforeground\fR option. The default value is \f(CWblack\fR. .TP \fB\-selectpad \fIpixels\fB Specifies extra padding to be displayed around the selected tab. The default value is \f(CW3\fR. .TP \fB\-side \fIside\fB Specifies the side of the widget to place tabs. The following values are valid for \fIside\fR. The default value is \f(CWtop\fR. .RS .TP 1i \f(CWtop\fR Tabs are drawn along the top. .TP 1i \f(CWleft\fR Tabs are drawn along the left side. .TP 1i \f(CWright\fR Tabs are drawn along the right side. .TP 1i \f(CWboth\fR Tabs are drawn along the bottom side. .RE .TP \fB\-slant \fIslant\fR Specifies if the tabs should be slanted 45 degrees on the left and/or right sides. The following values are valid for \fIslant\fR. The default is \f(CWnone\fR. .RS .TP 1i \f(CWnone\fR Tabs are drawn as a rectangle. .TP 1i \f(CWleft\fR The left side of the tab is slanted. .TP 1i \f(CWright\fR The right side of the tab is slanted. .TP 1i \f(CWboth\fR Boths sides of the tab are slanted. .RE .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts decide whether to focus on the window. The default is \f(CW1\fR. .TP \fB\-tearoff \fIboolean\fR .TP \fB\-textside \fIside\fB If both images and text are specified for a tab, this option determines on which side of the tab the text is to be displayed. The valid sides are \f(CWleft\fR, \f(CWright\fR, \f(CWtop\fR, and \f(CWbottom\fR. The default value is \f(CWleft\fR. .TP \fB\-tiers \fInumber\fB Specifies the maximum number of tiers to use to display the tabs. The default value is \f(CW1\fR. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. If \fIpixels\fR is 0, then the width of the widget will be calculated based on the size the tabs and their pages. The default is \f(CW0\fR. .SH "TAB OPTIONS" In addition to the \fBconfigure\fR operation, widget configuration options may also be set by the Tk \fBoption\fR command. The class resource name is \f(CWTab\fR. .CS option add *Scrollset.Tab.Foreground white option add *Scrollset.name.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the active background color for \fInameOrIndex\fR. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. This overrides the widget's \fB-activebackground\fR option. .TP \fB\-activeforeground \fIcolor\fR Sets the default active foreground color \fInameOrIndex\fR. A tab is "active" when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB-activeforeground\fR option. .TP \fB\-anchor \fIanchor\fR Anchors the tab's embedded widget to a particular edge of the folder. This option has effect only if the space in the folder surrounding the embedded widget is larger than the widget itself. \fIAnchor\fR specifies how the widget will be positioned in the extra space. For example, if \fIanchor\fR is \f(CWcenter\fR then the window is centered in the folder ; if \fIanchor\fR is \f(CWw\fR then the window will be aligned with the leftmost edge of the folder. The default value is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Sets the background color for \fInameOrIndex\fR. Setting this option overides the widget's \fB\-tabbackground\fR option. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for this tab. \fITagList\fR is a list of binding tag names. The tags and their order will determine how commands for events in tabs are invoked. Each tag in the list matching the event sequence will have its Tcl command executed. Implicitly the name of the tab is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-command \fIstring\fR Specifies a Tcl script to be associated with \fInameOrIndex\fR. This command is typically invoked when left mouse button is released over the tab. Setting this option overrides the widget's \fB\-selectcommand\fR option. .TP \fB\-data \fIstring\fR Specifies a string to be associated with \fInameOrIndex\fR. This value isn't used in the widget code. It may be used in Tcl bindings to associate extra data (other than the image or text) with the tab. The default value is \f(CW""\fR. .TP \fB\-fill \fIfill\fR If the space in the folder surrounding the tab's embedded widget is larger than the widget, then \fIfill\fR indicates if the embedded widget should be stretched to occupy the extra space. \fIFill\fR is either \f(CWnone\fR, \f(CWx\fR, \f(CWy\fR, \f(CWboth\fR. For example, if \fIfill\fR is \f(CWx\fR, then the widget is stretched horizontally. If \fIfill\fR is \f(CWy\fR, the widget is stretched vertically. The default is \f(CWnone\fR. .TP \fB\-font \fIfontName\fR Sets the font for the text in tab labels. If \fIfontName\fR is not the empty string, this overrides the scrollset's \fB\-font\fR option. The default value is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the color of the label for \fInameOrIndex\fR. If \fIcolor\fR is not the empty string, this overrides the widget's \fB\-tabforeground\fR option. The default value is \f(CW""\fR. .TP \fB\-image \fIimageName\fR Specifies the image to be drawn in label for \fInameOrIndex\fR. If \fIimage\fR is \f(CW""\fR, no image will be drawn. Both text and images may be displayed at the same time in tab labels. The default value is \f(CW""\fR. .TP \fB\-ipadx \fIpad\fR Sets the padding to the left and right of the label. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the label is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-ipady \fIpad\fR Sets the padding to the top and bottom of the label. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the label is padded by the first distance and the bottom by the second. If \fIpad\fR has just one distance, both the top and bottom sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets the padding around the left and right of the embedded widget, if one exists. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the widget is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-pady \fIpad\fR Sets the padding around the top and bottom of the embedded widget, if one exists. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the widget is padded by the first distance and the bottom by the second. If \fIpad\fR has just one distance, both the top and bottom sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-selectbackground \fIcolor\fR Sets the color to use when displaying background of the selected tab. If \fIcolor\fR is not the empty string, this overrides the widget's \fB\-selectbackground\fR option. The default value is \f(CW""\fR. .TP \fB\-shadow \fIcolor\fR Sets the shadow color for the text in the tab's label. Drop shadows are useful when both the foreground and background of the tab have similar color intensities. If \fIcolor\fR is the empty string, no shadow is drawn. The default value is \f(CW""\fR. .TP \fB\-state \fIstate\fR Sets the state of the tab. If \fIstate\fR is \f(CWdisable\fR the text of the tab is drawn as engraved and operations on the tab (such as \fBinvoke\fR and \fBtab tearoff\fR) are ignored. The default is \f(CWnormal\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern to use for the background of the folder when the window is torn off. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. The default is \f(CWBLT\fR. .TP \fB\-text \fItext\fR Specifies the text of the tab's label. The exact way the text is drawn may be affected by other options such as \fB\-state\fR or \fB\-rotate\fR. .TP \fB\-window \fIpathName\fR Specifies the widget to be embedded into the tab. \fIPathName\fR must be a child of the \fBscrollset\fR widget. The scrollset will "pack" and manage the size and placement of \fIpathName\fR. The default value is \f(CW""\fR. .TP \fB\-windowheight \fIpixels\fR Sets the requested height of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum height of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-windowwidth \fIpixels\fR Sets the requested width of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum width of all embedded tab windows is used. The default is \f(CW0\fR. .SH "DEFAULT BINDINGS" .PP BLT automatically generates class bindings that supply scrollsets their default behaviors. The following event sequences are set by default for scrollsets (via the class bind tag \f(CWScrollset\fR): .IP \fB<ButtonPress-2>\fR .IP \fB<B2-Motion>\fR .IP \fB<ButtonRelease-2>\fR Mouse button 2 may be used for scanning. If it is pressed and dragged over the scrollset, the contents of the scrollset drag at high speed in the direction the mouse moves. .IP \fB<KeyPress-Up>\fR .IP \fB<KeyPress-Down>\fR The up and down arrow keys move the focus to the tab immediately above or below the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. .IP \fB<KeyPress-Left>\fR .IP \fB<KeyPress-Right>\fR The left and right arrow keys move the focus to the tab immediately to the left or right of the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. .IP \fB<KeyPress-space>\fR .IP \fB<KeyPress-Return>\fR The space and return keys select the current tab given focus. When a folder is selected, it's command is invoked and the embedded widget is mapped. .PP Each tab, by default, also has a set of bindings (via the tag \f(CWall\fR). These bindings may be reset using the scrollset's \fBbind\fR operation. .IP \fB<Enter>\fR .IP \fB<Leave>\fR When the mouse pointer enters a tab, it is activated (i.e. drawn in its active colors) and when the pointer leaves, it is redrawn in its normal colors. .IP \fB<ButtonRelease-1>\fR Clicking with the left mouse button on a tab causes the tab to be selected and its Tcl script (see the \fB\-command\fR or \fB\-selectcommand\fR options) to be invoked. The folder and any embedded widget (if one is specified) is automatically mapped. .IP \fB<ButtonRelease-3>\fR .IP \fB<Control-ButtonRelease-1>\fR Clicking on the right mouse button (or the left mouse button with the Control key held down) tears off the current page into its own toplevel widget. The embedded widget is re-packed into a new toplevel and an outline of the widget is drawn in the folder. Clicking again (toggling) will reverse this operation and replace the page back in the folder. .SH "BIND TAGS" You can bind commands to tabs that are triggered when a particular event sequence occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR). .PP It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the tab name and another is associated with the tab's tags (see the \fB\-bindtags\fR option). When this occurs, all the matching bindings are invoked. A binding associated with the tab name is invoked first, followed by one binding for each of the tab's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. .PP The \fB\-bindtags\fR option for tabs controls addition tag names that can be matched. Implicitly the first tag for each tab is its name. Setting the value of the \fB\-bindtags\fR option doesn't change this. .SH EXAMPLE You create a scrollset widget with the \fBscrollset\fR command. .CS # Create a new scrollset scrollset .ts -relief sunken -borderwidth 2 .CE A new Tcl command \f(CW.ts\fR is also created. This command can be used to query and modify the scrollset. For example, to change the default font used by all the tab labels, you use the new command and the scrollset's \fBconfigure\fR operation. .CS # Change the default font. \&.ts configure \-font "fixed" .CE You can then add folders using the \fBinsert\fR operation. .CS # Create a new folder "f1" \&.ts insert 0 "f1" .CE This inserts the new tab named "f1" into the scrollset. The index \f(CW0\fR indicates location to insert the new tab. You can also use the index \f(CWend\fR to append a tab to the end of the scrollset. By default, the text of the tab is the name of the tab. You can change this by configuring the \fB\-text\fR option. .CS # Change the label of "f1" \&.ts tab configure "f1" -text "Tab #1" .CE The \fBinsert\fR operation lets you add one or more folders at a time. .CS \&.ts insert end "f2" -text "Tab #2" "f3" "f4" .CE The tab on each folder contains a label. A label may display both an image and a text string. You can reconfigure the tab's attributes (foreground/background colors, font, rotation, etc) using the \fBtab configure\fR operation. .CS # Add an image to the label of "f1" set image [image create photo -file stopsign.gif] \&.ts tab configure "f1" -image $image \&.ts tab configure "f2" -rotate 90 .CE Each folder may contain an embedded widget to represent its contents. The widget to be embedded must be a child of the scrollset widget. Using the \fB\-window\fR option, you specify the name of widget to be embedded. But don't pack the widget, the scrollset takes care of placing and arranging the widget for you. .CS graph .ts.graph \&.ts tab configure "f1" -window ".ts.graph" \\ -fill both -padx 0.25i -pady 0.25i .CE The size of the folder is determined the sizes of the Tk widgets embedded inside each folder. The folder will be as wide as the widest widget in any folder. The tallest determines the height. You can use the tab's \fB\-pagewidth\fR and \fB\-pageheight\fR options override this. .PP Other options control how the widget appears in the folder. The \fB\-fill\fR option says that you wish to have the widget stretch to fill the available space in the folder. .CS \&.ts tab configure "f1" -fill both -padx 0.25i -pady 0.25i .CE .PP Now when you click the left mouse button on "f1", the graph will be displayed in the folder. It will be automatically hidden when another folder is selected. If you click on the right mouse button, the embedded widget will be moved into a toplevel widget of its own. Clicking again on the right mouse button puts it back into the folder. .PP If you want to share a page between two different folders, the \fB\-command\fR option lets you specify a Tcl command to be invoked whenever the folder is selected. You can reset the \fB\-window\fR option for the tab whenever it's clicked. .CS \&.ts tab configure "f2" -command { \&.ts tab configure "f2" -window ".ts.graph" } \&.ts tab configure "f1" -command { \&.ts tab configure "f1" -window ".ts.graph" } .CE If you have many folders, you may wish to stack tabs in multiple tiers. The scrollset's \fB\-tiers\fR option requests a maximum number of tiers. The default is one tier. .CS \&.ts configure -tiers 2 .CE If the tabs can fit in less tiers, the widget will use that many. Whenever there are more tabs than can be displayed in the maximum number of tiers, the scrollset will automatically let you scroll the tabs. You can even attach a scrollbar to the scrollset. .CS \&.ts configure -scrollcommand { .sbar set } -scrollincrement 20 \&.sbar configure -orient horizontal -command { .ts view } .CE By default tabs are along the top of the scrollset from left to right. But tabs can be placed on any side of the scrollset using the \fB\-side\fR option. .CS # Arrange tabs along the right side of the scrollset. \&.ts configure -side right -rotate 270 .CE .SH KEYWORDS scrollset, widget ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/treeview.mann�����������������������������������������������������������������0000644�0001750�0001750�00000254076�11462120062�015534� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" '\" Copyright 2001-2 by Silicon Metrics Corporation. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Silicon Metrics or any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Silicon Metrics disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Silicon Metrics be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" The hierarchical table widget created by George Howlett. '\" .so man.macros .TH treeview n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME \fBtreeview\fR \- Create and manipulate hierarchical table widgets .BE .SH SYNOPSIS \fBblt::treeview\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBtreeview\fR widget displays a tree of data. It replaces both the \fBhiertable\fR and \fBhierbox\fR widgets. The \fBtreeview\fR is 100% syntax compatible with the \fBhiertable\fR widget. The \fBhiertable\fR command is retained for sake of script-level compatibility. This widget obsoletes the \fBhierbox\fR widget. It does everything the old \fBhierbox\fR widget did, but also provides data sharing (via \fItree data objects\fR) and the ability to tag nodes. .SH INTRODUCTION The \fBtreeview\fR widget displays hierarchical data. Data is represented as nodes in a general-ordered tree. Each node may have sub-nodes and these nodes can in turn has their own children. .PP A node is displayed as a row entry in the widget. Each entry has a text label and icon. When a node has children, its entry is drawn with a small button to the left of the label. Clicking the mouse over this button opens or closes the node. When a node is \fIopen\fR, its children are exposed. When it is \fIclosed\fR, the children and their descedants are hidden. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol (ala Windows Explorer), but can be replaced with a pair of Tk images (open and closed images). .PP If the node has data associated with it, they can be displayed in columns running vertically on either side the tree. You can control the color, font, etc of each entry. Any entry label or data field can be edited in-place. .SH "TREE DATA OBJECT" The tree is not stored inside the widget but in a tree data object (see the \fBtree\fR command for a further explanation). Tree data objects can be shared among different clients, such as a \fBtreeview\fR widget or the \fBtree\fR command. You can walk the tree and manage its data with the \fBtree\fR command tree, while displaying it with the \fBtreeview\fR widget. Whenever the tree is updated, the \fBtreeview\fR widget is automatically redrawn. .PP By default, the \fBtreeview\fR widget creates its own tree object. The tree initially contains just a root node. But you can also display trees created by the \fBtree\fR command using the \fB\-tree\fR configuration option. \fBTreeview\fR widgets can share the same tree object, possibly displaying different views of the same data. .PP A tree object has both a Tcl and C API. You can insert or delete nodes using \fBtreeview\fR widget or \fBtree\fR command operations, but also from C code. For example, you can load the tree from your C code while still managing and displaying the tree from Tcl. The widget is automatically notified whenever the tree is modified via C or Tcl. .SH SYNTAX .DS \fBblt::treeview \fIpathName \fR?\fIoption value\fR?... .DE The \fBtreeview\fR command creates a new window \fIpathName\fR and makes it into a \fBtreeview\fR widget. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. Additional options may be specified on the command line or in the option database to configure aspects of the widget such as its colors and font. See the \fBconfigure\fR operation below for the exact details about what \fIoption\fR and \fIvalue\fR pairs are valid. .PP If successful, \fBtreeview\fR returns the path name of the widget. It also creates a new Tcl command by the same name. You can use this command to invoke various operations that query or modify the widget. The general form is: .DS \fIpathName \fIoperation\fR \fR?\fIarg\fR?... .DE Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available are described in the .SB "TREEVIEW OPERATIONS" section. .SH "IDS AND TAGS" Nodes can be inserted into a tree using the \fBtreeview\fR widget .CS blt::treeview .t set node [.t insert end root "one"] .CE or \fBtree\fR command. .CS set tree [blt::tree create] set node [$tree insert root "one"] .CE In both cases, a number identifying the node is returned (the value of \f(CW$node\fR). This serial number or \fIid\fR uniquely identifies the node. Please note that you can't infer a location or position of a node from its id. The only exception is that the root node is always id \f(CW0\fR. Since nodes may have the same labels or be moved within the tree, ids provide an convenient way to identify nodes. If a tree is shared, the ids will be the same regardless if you are using by the \fBtreeview\fR widget or the \fBtree\fR command. Ids are recycled when the node deleted. .PP A node may also have any number of \fItags\fR associated with it. A tag is just a string of characters, and it may take any form except that of an integer. For example, "\f(CWx123\fR" is valid, but "\f(CW123\fR" isn't. The same tag may be associated with many different nodes. This is typically done to associate a group of nodes. Many operations in the \fBtreeview\fR widget take either node ids or tag names as arguments. Using a tag says to apply the operation to all nodes with that tag. .PP The tag \fBall\fR is implicitly associated with every node in the tree. It may be used to invoke operations on all the nodes in the tree. .PP Tags may be shared, just like trees, between clients. For example, you can use the tags created by the \fBtree\fR command with \fBtreeview\fR widgets. .SH SPECIAL NODE IDS There are also several special non-numeric ids. Special ids differ from tags in that they are always translated to their numeric equivalent. They also take precedence over tags. For example, you can't use a tag name that is a special id. These ids are specific to the \fBtreeview\fR widget. .TP 15 \fBactive\fR The node where the mouse pointer is currently located. When a node is active, it is drawn using its active icon (see the \fB\-activeicon\fR option). The \fBactive\fR id is changed automatically by moving the mouse pointer over another node or by using the \fBentry activate\fR operation. Note that there can be only one active node at a time. .TP 15 \fBanchor\fR The node representing the fixed end of the current selection. The anchor is set by the \fBselection anchor\fR operation. .TP 15 \fBcurrent\fR The node where the mouse pointer is currently located. But unlike \fBactive\fR, this id changes while the selection is dragged. It is used to determine the current node during button drags. .TP 15 \fBdown\fR The next open node from the current focus. The \fBdown\fR of the last open node is the same. .TP 15 \fBend\fR The last open node (in depth-first order) on the tree. .TP 15 \fBfocus\fR The node that currently has focus. When a node has focus, it receives key events. To indicate focus, the node is drawn with a dotted line around its label. You can change the focus using the \fBfocus\fR operation. .TP 15 \fBlast\fR The last open node from the current focus. But unlike \fBup\fR, when the focus is at root, \fBlast\fR wraps around to the last open node in the tree. .TP 15 \fBmark\fR The node representing the non-fixed end of the current selection. The mark is set by the \fBselection mark\fR operation. .TP 15 \fBnext\fR The next open node from the current focus. But unlike \fBdown\fR, when the focus is on last open node, \fBnext\fR wraps around to the root node. .TP 15 \fBnextsibling\fR The next sibling from the node with the current focus. If the node is already the last sibling then it is the \fBnextsibling\fB. .TP 15 \fBparent\fR The parent of the node with the current focus. The \fBparent\fR of the root is also the root. .TP 15 \fBprevsibling\fR The previous sibling from the node with the current focus. If the node is already the first sibling then it is the \fBprevsibling\fB. .TP 15 \fBroot\fR The root node. You can also use id \f(CW0\fR to indicate the root. .TP 15 \fBup\fR The last open node (in depth-first order) from the current focus. The \fBup\fR of the root node (i.e. the root has focus) is also the root. .TP 15 \fBview.top\fR First node that's current visible in the widget. .TP 15 \fBview.bottom\fR Last node that's current visible in the widget. .TP 15 \fB@\fIx\fB,\fIy\fR Indicates the node that covers the point in the treeview window specified by \fIx\fR and \fIy\fR (in pixel coordinates). If no part of the entryd covers that point, then the closest node to that point is used. .PP A node may be specified as an id or tag. If the specifier is an integer then it is assumed to refer to the single node with that id. If the specifier is not an integer, it's checked to see if it's a special id (such as focus). Otherwise, it's assumed to be tag. Some operations only operate on a single node at a time; if a tag refers to more than one node, then an error is generated. .SH DATA FIELDS A node in the tree can have \fIdata fields\fR. A data field is a name-value pair, used to represent arbitrary data in the node. Nodes can contain different fields (they aren't required to contain the same fields). You can optionally display these fields in the \fBtreeview\fR widget in columns running on either side of the displayed tree. A node's value for the field is drawn in the column along side its node in the hierarchy. Any node that doesn't have a specific field is left blank. Columns can be interactively resized, hidden, or, moved. .SH ENTRY BINDINGS You can bind Tcl commands to be invoked when events occur on nodes (much like Tk canvas items). You can bind a node using its id or its \fIbindtags\fR. Bindtags are simply names that associate a binding with one or more nodes. There is a built-in tag \f(CWall\fR that all node entries automatically have. .SH "TREEVIEW OPERATIONS" The \fBtreeview\fR operations are the invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .CS \fIpathName operation \fR?\fIarg arg ...\fR? .CE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operation are available for \fBtreeview\fR widgets: .TP \fIpathName \fBbbox\fR ?\fB-screen\fR? \fItagOrId...\fR Returns a list of 4 numbers, representing a bounding box of around the specified entries. The entries is given by one or more \fItagOrId\fR arguments. If the \fB\-screen\fR flag is given, then the x-y coordinates of the bounding box are returned as screen coordinates, not virtual coordinates. Virtual coordinates start from \f(CW0\fR from the root node. The returned list contains the following values. .RS .TP 1.25i \fIx\fR X-coordinate of the upper-left corner of the bounding box. .TP \fIy\fR Y-coordinate of the upper-left corner of the bounding box. .TP \fIwidth\fR Width of the bounding box. .TP \fIheight\fR Height of the bounding box. .RE .TP \fIpathName \fBbind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a node with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR entries, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton \fIoperation\fR ?\fIargs\fR? This command is used to control the button selectors within a \fBtreeview\fR widget. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBbutton activate\fR \fItagOrId\fR Designates the node given by \fItagOrId\fR as active. When a node is active it's entry is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active entry at a time. The special id \fBactive\fR indicates the currently active node. .TP \fIpathName \fBbutton bind\fR \fItagName\fR ?\fIsequence command\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for an button of a node entry with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on \fBtreeview\fR buttons, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR before invoking it. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBbutton cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBbutton configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "BUTTON OPTIONS" below. .RE .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBclose \fR?\fB\-recurse\fR? \fItagOrId...\fR Closes the node specified by \fItagOrId\fR. In addition, if a Tcl script was specified by the \fB\-closecommand\fR option, it is invoked. If the node is already closed, this command has no effect. If the \fB\-recurse\fR flag is present, each child node is recursively closed. .TP \fIpathName \fBcolumn \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview columns. .RS .TP \fIpathName \fBcolumn activate\fR \fIcolumn\fR Sets the active column to \fIcolumn\fR. \fIColumn\fR is the name of a column in the widget. When a column is active, it's drawn using its \fB\-activetitlebackground\fR and \fB\-activetitleforeground\fR options. If \fIcolumn\fR is the \f(CW""\fR, then no column will be active. If no column argument is provided, then the name of the currently active column is returned. .TP \fIpathName \fBcolumn cget\fR \fIname\fR \fIoption\fR Returns the current value of the column configuration option given by \fIoption\fR for \fIname\fR. \fIName\fR is the name of column that corresponds to a data field. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBcolumn configure\fR \fIname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the column designated by \fIname\fR. \fIName\fR is the name of the column corresponding to a data field. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "COLUMN OPTIONS" below. .TP \fIpathName \fBcolumn delete\fR \fIfield\fR ?\fIfield\fR...? Deletes one of more columns designated by \fIfield\fR. Note that this does not delete the data fields themselves. .TP \fIpathName \fBcolumn insert\fR \fIposition\fR \fIfield\fR ?\fIoptions\fR...? Inserts one of more columns designated by \fIfield\fR. A column displays each node's data field by the same name. If the node doesn't have the given field, the cell is left blank. \fIPosition\fR indicates where in the list of columns to add the new column. It may be either a number or \f(CWend\fR. .TP \fIpathName \fBcolumn invoke\fR \fIfield\fR Invokes the Tcl command associated with the column \fIfield\fR, if there is one (using the column's \fB\-command\fR option). The command is ignored if the column's \fB\-state\fR option set to \f(CWdisabled\fR. .TP \fIpathName \fBcolumn move \fIname\fR \fIdest\fR Moves the column \fIname\fR to the destination position. \fIDest\fR is the name of another column or a screen position in the form \f(CW@\fIx\f(CW,\fIy\fR. .TP \fIpathName \fBcolumn names\fR Returns a list of the names of all columns in the widget. The list is ordered as the columns are drawn from left-to-right. .TP \fIpathName \fBcolumn nearest\fR \fIx\fR ?\fIy\fR? Returns the name of the column closest to the given X-Y screen coordinate. If you provide a \fIy\fR argument (it's optional), a name is returned only when if the point is over a column's title. .RE .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TREEVIEW OPTIONS" below. .TP \fIpathName \fBcurselection\fR Returns a list containing the ids of all of the entries that are currently selected. If there are no entries selected, then the empty string is returned. .TP \fIpathName \fBdelete \fItagOrId\fR... Deletes one or more entries given by \fItagOrId\fR and its children. .TP \fIpathName \fBentry \fIoperation\fR ?\fIargs\fR? The following operations are available for treeview entries. .RS .TP \fIpathName \fBentry activate\fR \fItagOrId\fR Sets the active entry to the one specified by \fItagOrId\fR. When an entry is active it is drawn using its active icon (see the \fB\-activeicon\fR option). Note that there can be only one active node at a time. The special id of the currently active node is \fBactive\fR. .TP \fIpathName \fBentry cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBentry children\fR \fItagOrId\fR ?\fIfirst\fR? ?\fIlast\fR? Returns a list of ids for the given range of children of \fItagOrId\fR. \fITagOrId\fR is the id or tag of the node to be examined. If only a \fIfirst\fR argument is present, then the id of the that child at that numeric position is returned. If both \fIfirst\fR and \fIlast\fR arguments are given, then the ids of all the children in that range are returned. Otherwise the ids of all children are returned. .TP \fIpathName \fBentry configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .TP \fIpathName \fBentry delete\fR \fItagOrId\fR ?\fIfirst\fR ?\fIlast\fR? Deletes the one or more children nodes of the parent \fItagOrId\fR. If \fIfirst\fR and \fIlast\fR arguments are present, they are positions designating a range of children nodes to be deleted. .TP \fIpathName \fBentry isbefore \fItagOrId1\fR \fItagOrId2\fR Returns 1 if \fItagOrId1\fR is before \fItagOrId2\fR and 0 otherwise. .TP \fIpathName \fBentry ishidden \fItagOrId\fR Returns 1 if the node is currently hidden and 0 otherwise. A node is also hidden if any of its ancestor nodes are closed or hidden. .TP \fIpathName \fBentry isopen \fItagOrId\fR Returns 1 if the node is currently open and 0 otherwise. .TP \fIpathName \fBentry size\fR \fB\-recurse\fR \fItagOrId\fR Returns the number of children for parent node \fItagOrId\fR. If the \fB\-recurse\fR flag is set, the number of all its descendants is returned. The node itself is not counted. .RE .TP \fIpathName \fBfind \fR?\fIflags\fR? \fIfirst\fR \fIlast\fR Finds for all entries matching the criteria given by \fIflags\fR. A list of ids for all matching nodes is returned. \fIFirst\fR and \fIlast\fR are ids designating the range of the search in depth-first order. If \fIlast\fR is before \fIfirst\fR, then nodes are searched in reverse order. The valid flags are: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Patterns must match exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Pick entries that don't match. .TP 1.25i \fB\-exec\fI string\fR Specifies a Tcl script to be invoked for each matching node. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP 1.25i \fB\-count\fI number\fR Stop searching after \fInumber\fR matches. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBfocus \fR \fItagOrId\fR Sets the focus to the node given by \fItagOrId\fR. When a node has focus, it can receive keyboard events. The special id \fBfocus\fR designates the node that currently has focus. .TP \fIpathName \fBget \fR?\fB\-full\fR? \fItagOrId\fR \fItagOrId\fR... Translates one or more ids to their node entry names. It returns a list of names for all the ids specified. If the \fB\-full\fR flag is set, then the full pathnames are returned. .sp Note: If the \fB\-separator\fR option is the empty string (the default), the result is always a list of lists, even if there is only one node specified. .TP \fIpathName \fBhide \fR?\fBflags\fR? \fItagOrId\fR... Hides all nodes matching the criteria given by \fIflags\fR. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the node entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Hide nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBindex \fR?\fB\-at\fR ?\fB\-path\fR? \fItagOrId\fR? \fIstring\fR Returns the id of the node specified by \fIstring\fR. \fIString\fR may be a tag or node id. Some special ids are normally relative to the node that has focus. The \fB\-at\fR flag lets you select another node. .TP \fIpathName \fBinsert \fR?\fB\-at \fItagOrId\fR? \fIposition\fR \fIpath\fR ?\fIoptions...\fR? ?\fIpath\fR? ?\fIoptions...\fR? Inserts one or more nodes at \fIposition\fR. \fIPosition\fR is the location (number or \f(CWend\fR) where the new nodes are added to the parent node. \fIPath\fR is the pathname of the new node. Pathnames can be formated either as a Tcl list (each element is a path component) or as a string separated by a special character sequence (using the \fB\-separator\fR option). Pathnames are normally absolute, but the \fB\-at\fR switch lets you select a relative starting point. Its value is the id of the starting node. .sp All ancestors of the new node must already exist, unless the \fB\-autocreate\fR option is set. It is also an error if a node already exists, unless the \fB\-allowduplicates\fR option is set. .sp \fIOption\fR and \fIvalue\fR may have any of the values accepted by the \fBentry configure\fR operation described in the .SB "ENTRY OPERATIONS" section below. This command returns a list of the ids of the new entries. .TP \fIpathName \fBmove \fItagOrId\fR \fIhow\fR \fIdestId\fR Moves the node given by \fItagOrId\fR to the destination node. The node can not be an ancestor of the destination. \fIDestId\fR is the id of the destination node and can not be the root of the tree. In conjunction with \fIhow\fR, it describes how the move is performed. .RS .TP 8 \f(CWbefore\fR Moves the node before the destination node. .TP 8 \f(CWafter\fR Moves the node after the destination node. .TP 8 \f(CWinto\fR Moves the node to the end of the destination's list of children. .RE .TP \fIpathName \fBnearest \fIx y\fR ?\fIvarName\fR? Returns the id of the node entry closest to the given X-Y screen coordinate. If the coordinate is not directly over any node, then the empty string is returned. If the argument \fIvarName\fR is present, this is a Tcl variable that is set to either \f(CWbutton\fR, \f(CWlabel\fR, \f(CWlabel\fR, or \f(CW""\fR depending what part of the entry the coordinate lies. .TP \fIpathName \fBopen \fR?\fB\-recurse\fR? \fItagOrId...\fR Opens the one or more nodes specified by \fItagOrId\fR. If a node is not already open, the Tcl script specified by the \fB\-opencommand\fR option is invoked. If the \fB\-recurse\fR flag is present, then each descendant is recursively opened. .TP \fIpathName \fBrange\fR ?\fB-open\fR? \fIfirst last\fR Returns the ids in depth-first order of the nodes between the \fIfirst\fR and \fIlast\fR ids. If the \fB\-open\fR flag is present, it indicates to consider only open nodes. If \fIlast\fR is before \fIfirst\fR, then the ids are returned in reverse order. .TP \fIpathName \fBscan\fR \fIoption args\fR This command implements scanning. It has two forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBscan mark \fIx y\fR Records \fIx\fR and \fIy\fR and the current view in the treeview window; used in conjunction with later \fBscan dragto\fR commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. .TP \fIpathName \fBscan dragto \fIx y\fR. Computes the difference between its \fIx\fR and \fIy\fR arguments and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. .RE .TP \fIpathName \fBsee\fR ?\fB\-anchor \fIanchor\fR? \fItagOrId\fR Adjusts the view of entries so that the node given by \fItagOrId\fR is visible in the widget window. It is an error if \fBtagOrId\fR is a tag that refers to more than one node. By default the node's entry is displayed in the middle of the window. This can changed using the \fB\-anchor\fR flag. Its value is a Tk anchor position. .TP \fIpathName \fBselection \fIoption arg\fR This command is used to adjust the selection within a \fBtreeview\fR widget. It has several forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBselection anchor \fItagOrId\fR Sets the selection anchor to the node given by \fItagOrId\fR. If \fItagOrId\fR refers to a non-existent node, then the closest node is used. The selection anchor is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBanchor\fR may be used to refer to the anchor node. .TP \fIpathName \fBselection cancel\fR Clears the temporary selection of entries back to the current anchor. Temporary selections are created by the \fBselection mark\fR operation. .TP \fIpathName \fBselection clear \fIfirst \fR?\fIlast\fR? Removes the entries between \fIfirst\fR and \fIlast\fR (inclusive) from the selection. Both \fIfirst\fR and \fIlast\fR are ids representing a range of entries. If \fIlast\fR isn't given, then only \fIfirst\fR is deselected. Entries outside the selection are not affected. .TP \fIpathName \fBselection clearall\fR Clears the entire selection. .TP \fIpathName \fBselection mark \fItagOrId\fR Sets the selection mark to the node given by \fItagOrId\fR. This causes the range of entries between the anchor and the mark to be temporarily added to the selection. The selection mark is the end of the selection that is fixed while dragging out a selection with the mouse. The special id \fBmark\fR may be used to refer to the current mark node. If \fItagOrId\fR refers to a non-existent node, then the mark is ignored. Resetting the mark will unselect the previous range. Setting the anchor finalizes the range. .TP \fIpathName \fBselection includes \fItagOrId\fR Returns 1 if the node given by \fItagOrId\fR is currently selected, 0 if it isn't. .TP \fIpathName \fBselection present\fR Returns 1 if any nodes are currently selected and 0 otherwise. .TP \fIpathName \fBselection set \fIfirst \fR?\fIlast\fR? Selects all of the nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, without affecting the selection state of nodes outside that range. .TP \fIpathName \fBselection toggle \fIfirst \fR?\fIlast\fR? Selects/deselects nodes in the range between \fIfirst\fR and \fIlast\fR, inclusive, from the selection. If a node is currently selected, it becomes deselected, and visa versa. .RE .TP \fIpathName \fBshow \fR?\fBflags\fR? \fItagOrId\fR... Exposes all nodes matching the criteria given by \fIflags\fR. This is the inverse of the \fBhide\fR operation. The search is performed recursively for each node given by \fItagOrId\fR. The valid flags are described below: .RS .TP 1.25i \fB\-name\fI pattern\fR Specifies pattern to match against node names. .TP 1.25i \fB\-full\fI pattern\fR Specifies pattern to match against node pathnames. .TP 1.25i \fB\-\fIoption\fI pattern\fR Specifies pattern to match against the entry's configuration option. .TP 1.25i \fB\-exact\fR Match patterns exactly. The is the default. .TP 1.25i \fB\-glob\fR \fB\-glob\fR Use global pattern matching. Matching is done in a fashion similar to that used by the C-shell. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern: .RS .TP 5 \f(CW*\fR Matches any sequence of characters in string, including a null string. .TP 5 \f(CW?\fR Matches any single character in string. .TP 5 \f(CW[\fIchars\f(CW]\fR Matches any character in the set given by \fIchars\fR. If a sequence of the form \fIx\fR-\fIy\fR appears in \fIchars\fR, then any character between \fIx\fR and \fIy\fR, inclusive, will match. .TP 5 \f(CW\\\fIx\fR Matches the single character \fIx\fR. This provides a way of avoiding the special interpretation of the characters \f(CW*?[]\\\fR in the pattern. .RE .TP 1.25i \fB\-regexp\fR Use regular expression pattern matching (i.e. the same as implemented by the \fBregexp\fR command). .TP 1.25i \fB\-nonmatching\fR Expose nodes that don't match. .TP 1.25i \fB\-\-\fR Indicates the end of flags. .RE .TP \fIpathName \fBsort\fR ?\fIoperation\fR? \fIargs...\fR .RS .TP \fIpathName \fBsort auto\fR ?\fIboolean\fR Turns on/off automatic sorting of node entries. If \fIboolean\fR is true, entries will be automatically sorted as they are opened, closed, inserted, or deleted. If no \fIboolean\fR argument is provided, the current state is returned. .TP \fIpathName \fBsort cget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBsort configure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the sorting configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all of the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given sorting option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described below: .RS .TP \fB\-column\fI string\fR Specifies the column to sort. Entries in the widget are rearranged according to this column. If \fIcolumn\fR is \f(CW""\fR then no sort is performed. .TP \fB\-command\fI string\fR Specifies a Tcl procedure to be called when sorting nodes. The procedure is called with three arguments: the pathname of the widget and the fields of two entries. The procedure returns 1 if the first node is greater than the second, -1 is the second is greater, and 0 if equal. .TP \fB\-decreasing\fI boolean\fR Indicates to sort in ascending/descending order. If \fIboolean\fR is true, then the entries as in descending order. The default is \f(CWno\fR. .TP \fB\-mode\fI string\fR Specifies how to compare entries when sorting. \fIString\fR may be one of the following: .RS .TP 1.5i \f(CWascii\fR Use string comparison based upon the ASCII collation order. .TP 1.5i \f(CWdictionary\fR Use dictionary-style comparison. This is the same as \f(CWascii\fR except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, "bigBoy" sorts between "bigbang" and "bigboy", and "x10y" sorts between "x9y" and "x11y". .TP 1.5i \f(CWinteger\fR Compares fields as integers. .TP 1.5i \f(CWreal\fR Compares fields as floating point numbers. .TP 1.5i \f(CWcommand\fR Use the Tcl proc specified by the \fB\-command\fR option to compare entries when sorting. If no command is specified, the sort reverts to \f(CWascii\fR sorting. .RE .RE .TP \fIpathName \fBsort once\fR ?\fIflags\fR? \fItagOrId...\fR Sorts the children for each entries specified by \fItagOrId\fR. By default, entries are sorted by name, but you can specify a Tcl proc to do your own comparisons. .RS .TP 1.5i \fB\-recurse\fR Recursively sort the entire branch, not just the children. .RE .RE .TP \fIpathName \fBtag \fIoperation args\fR Tags are a general means of selecting and marking nodes in the tree. A tag is just a string of characters, and it may take any form except that of an integer. The same tag may be associated with many different nodes. .sp Both \fIoperation\fR and its arguments determine the exact behavior of the command. The operations available for tags are listed below. .RS .TP \fIpathName\fR \fBtag add\fR \fIstring\fR \fIid\fR... Adds the tag \fIstring\fR to one of more entries. .TP \fIpathName\fR \fBtag delete\fR \fIstring\fR \fIid\fR... Deletes the tag \fIstring\fR from one or more entries. .TP \fIpathName\fR \fBtag forget\fR \fIstring\fR Removes the tag \fIstring\fR from all entries. It's not an error if no entries are tagged as \fIstring\fR. .TP \fIpathName\fR \fBtag names\fR ?\fIid\fR? Returns a list of tags used. If an \fIid\fR argument is present, only those tags used by the node designated by \fIid\fR are returned. .TP \fIpathName\fR \fBtag nodes\fR \fIstring\fR Returns a list of ids that have the tag \fIstring\fR. If no node is tagged as \fIstring\fR, then an empty string is returned. .RE .TP \fIpathName \fBtext \fIoperation\fR ?\fIargs\fR? This operation is used to provide text editing for cells (data fields in a column) or entry labels. It has several forms, depending on \fIoperation\fR: .RS .TP \fIpathName \fBtext apply\fR Applies the edited buffer, replacing the entry label or data field. The edit window is hidden. .TP \fIpathName \fBtext cancel\fR Cancels the editing operation, reverting the entry label or data value back to the previous value. The edit window is hidden. .TP \fIpathName \fBtext cget\fI value\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described below. .TP \fIpathName \fBtext configure\fR ?\fIoption value\fR? Query or modify the configuration options of the edit window. If no \fIoption\fR is specified, returns a list describing all of the available options (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "TEXT EDITING OPTIONS" below. .RE .TP \fIpathName \fBtext delete\fI first last\fR Deletes the characters in the edit buffer between the two given character positions. .TP \fIpathName \fBtext get\fR ?\fI\-root\fR? \fIx y\fR .TP \fIpathName \fBtext icursor\fI index\fR .TP \fIpathName \fBtext index\fI index\fR Returns the text index of given \fIindex\fR. .TP \fIpathName \fBtext insert\fI index string\fR Insert the text string \fIstring\fR into the edit buffer at the index \fIindex\fR. For example, the index 0 will prepend the buffer. .TP \fIpathName \fBtext selection\fI args\fR This operation controls the selection of the editing window. Note that this differs from the selection of entries. It has the following forms: .RS .TP \fIpathName \fBtext selection adjust\fI index\fR Adjusts either the first or last index of the selection. .TP \fIpathName \fBtext selection clear\fR Clears the selection. .TP \fIpathName \fBtext selection from\fI index\fR Sets the anchor of the selection. .TP \fIpathName \fBtext selection present\fR Indicates if a selection is present. .TP \fIpathName \fBtext selection range\fI start end\fR Sets both the anchor and mark of the selection. .TP \fIpathName \fBtext selection to\fI index\fR Sets the unanchored end (mark) of the selection. .RE .TP \fIpathName \fBtoggle \fItagOrId\fR Opens or closes the node given by \fItagOrId\fR. If the corresponding \fB\-opencommand\fR or \fB\-closecommand\fR option is set, then that command is also invoked. .TP \fIpathName \fBxview \fIargs\fR This command is used to query and change the horizontal position of the information in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fBxview\fR Returns a list containing two elements. Each element is a real fraction between 0 and 1; together they describe the horizontal span that is visible in the window. For example, if the first element is .2 and the second element is .6, 20% of the \fBtreeview\fR widget's text is off-screen to the left, the middle 40% is visible in the window, and 40% of the text is off-screen to the right. These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR option. .TP \fIpathName \fBxview\fR \fItagOrId\fR Adjusts the view in the window so that the character position given by \fItagOrId\fR is displayed at the left edge of the window. Character positions are defined by the width of the character \fB0\fR. .TP \fIpathName \fBxview moveto\fI fraction\fR Adjusts the view in the window so that \fIfraction\fR of the total width of the \fBtreeview\fR widget's text is off-screen to the left. \fIfraction\fR must be a fraction between 0 and 1. .TP \fIpathName \fBxview scroll \fInumber what\fR This command shifts the view in the window left or right according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation of one of these. If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by \fInumber\fR character units (the width of the \fB0\fR character) on the display; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then characters farther to the left become visible; if it is positive then characters farther to the right become visible. .RE .TP \fIpathName \fByview \fI?args\fR? This command is used to query and change the vertical position of the text in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fByview\fR Returns a list containing two elements, both of which are real fractions between 0 and 1. The first element gives the position of the node at the top of the window, relative to the widget as a whole (0.5 means it is halfway through the treeview window, for example). The second element gives the position of the node just after the last one in the window, relative to the widget as a whole. These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR option. .TP \fIpathName \fByview\fR \fItagOrId\fR Adjusts the view in the window so that the node given by \fItagOrId\fR is displayed at the top of the window. .TP \fIpathName \fByview moveto\fI fraction\fR Adjusts the view in the window so that the node given by \fIfraction\fR appears at the top of the window. \fIFraction\fR is a fraction between 0 and 1; 0 indicates the first node, 0.33 indicates the node one-third the way through the \fBtreeview\fR widget, and so on. .TP \fIpathName \fByview scroll \fInumber what\fR This command adjusts the view in the window up or down according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR. If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by \fInumber\fR lines; if it is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls. If \fInumber\fR is negative then earlier nodes become visible; if it is positive then later nodes become visible. .RE .SH "TREEVIEW OPTIONS" In addition to the \fBconfigure\fR operation, widget configuration options may also be set by the Tk \fBoption\fR command. The class resource name is \f(CWTreeView\fR. .CS option add *TreeView.Foreground white option add *TreeView.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the background color for active entries. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of the active node. A node is active when the mouse passes over it's entry or using the \fBactivate\fR operation. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed for an entry's icon when it is active. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-autocreate \fIboolean\fR If \fIboolean\fR is true, automatically create missing ancestor nodes when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-allowduplicates \fIboolean\fR If \fIboolean\fR is true, allow nodes with duplicate pathnames when inserting new nodes. Otherwise flag an error. The default is \f(CWno\fR. .TP \fB\-background \fIcolor\fR Sets the background color of the widget. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines if the border is to be drawn. The default is \f(CW2\fR. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when a node is closed. You can overrider this for individual entries using the entry's \fB\-closecommand\fR option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-dashes \fInumber\fR Sets the dash style of the horizontal and vertical lines drawn connecting entries. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, solid lines will be drawn. The default is \f(CW1\fR (dotted). .TP \fB\-exportselection \fIboolean\fR Indicates if the selection is exported. If the widget is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR; the value of the selection will be the label of the selected nodes, separated by newlines. The default is \f(CWno\fR. .TP \fB\-flat \fIboolean\fR Indicates whether to display the tree as a flattened list. If \fIboolean\fR is true, then the hierarchy will be a list of full paths for the nodes. This option also has affect on sorting. See the .SB "SORT OPERATIONS" section for more information. The default is \f(CWno\fR. .TP \fB\-focusdashes \fIdashList\fR Sets the dash style of the outline rectangle drawn around the entry label of the node that current has focus. \fINumber\fR is the length in pixels of the dashes and gaps in the line. If \fInumber\fR is \f(CW0\fR, a solid line will be drawn. The default is \f(CW1\fR. .TP \fB\-focusforeground \fIcolor\fR Sets the color of the focus rectangle. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Specifies the font for entry labels. You can override this for individual entries with the entry's \fB\-font\fR configuration option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of entry labels. You can override this for individual entries with the entry's \fB\-foreground\fR configuration option. The default is \f(CWblack\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. The default is \f(CW400\fR. .TP \fB\-hideroot \fIboolean\fR If \fIboolean\fR is true, it indicates that no entry for the root node should be displayed. The default is \f(CWno\fR. .TP \fB\-highlightbackground \fIcolor\fR Specifies the normal color of the traversal highlight region when the widget does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Specifies the color of the traversal highlight rectangle when the widget has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Specifies the width of the highlight rectangle indicating when the widget has input focus. The value may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight will be displayed. The default is \f(CW2\fR. .TP \fB\-icons \fIimages\fR Specifies images for the entry's icon. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-linecolor \fIcolor\fR Sets the color of the connecting lines drawn between entries. The default is \f(CWblack\fR. .TP \fB\-linespacing \fIpixels\fR Sets the number of pixels spacing between entries. The default is \f(CW0\fR. .TP \fB\-linewidth \fIpixels\fR Set the width of the lines drawn connecting entries. If \fIpixels\fR is \f(CW0\fR, no vertical or horizontal lines are drawn. The default is \f(CW1\fR. .TP \fB\-newtags \fIboolean\fR If \fIboolean\fR is true, when sharing a tree object (see the \fB\-tree\fR option), don't share its tags too. The default is \f(CW0\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when a node is open. You can override this for individual entries with the entry's \fB\-opencommand\fR configuration option. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for the widget. \fIRelief\fR specifies how the \fBtreeview\fR widget should appear relative to widget it is packed into; for example, \f(CWraised\fR means the \fBtreeview\fR widget should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-scrollmode \fImode\fR Specifies the style of scrolling to be used. The following styles are valid. This is the default is \f(CWhierbox\fR. .RS .TP 1.25i \f(CWlistbox\fR Like the \fBlistbox\fR widget, the last entry can always be scrolled to the top of the widget window. This allows the scrollbar thumb to shrink as the last entry is scrolled upward. .TP 1.25i \f(CWhierbox\fR Like the \fBhierbox\fR widget, the last entry can only be viewed at the bottom of the widget window. The scrollbar stays a constant size. .TP 1.25i \f(CWcanvas\fR Like the \fBcanvas\fR widget, the entries are bound within the scrolling area. .RE .TP \fB\-selectbackground \fIcolor\fR Sets the background color selected node entries. The default is \f(CW#ffffea\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the raised 3-D border drawn around the labels of selected entries. The default is \f(CW0\fR. \fB\-selectcommand \fIstring\fR Specifies a Tcl script to invoked when the set of selected nodes changes. The default is \f(CW""\fR. .TP \fB\-selectforeground \fIcolor\fB Sets the color of the labels of selected node entries. The default is \f(CWblack\fR. .TP \fB\-selectmode \fImode\fR Specifies the selection mode. If \fImode\fR is \f(CWsingle\fR, only one node can be selected at a time. If \f(CWmultiple\fR more than one node can be selected. The default is \f(CWsingle\fR. .TP \fB\-separator \fIstring\fR Specifies the character sequence to use when spliting the path components. The separator may be several characters wide (such as "::") Consecutive separators in a pathname are treated as one. If \fIstring\fR is the empty string, the pathnames are Tcl lists. Each element is a path component. The default is \f(CW""\fR. .TP \fB\-showtitles \fIboolean\fR If \fIboolean\fR is false, column titles are not be displayed. The default is \f(CWyes\fR. .TP \fB\-sortselection \fIboolean\fR If \fIboolean\fR is true, nodes in the selection are ordered as they are currently displayed (depth-first or sorted), not in the order they were selected. The default is \f(CWno\fR. .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts make the decision whether to focus on the window. The default is \f(CW"1"\fR. .TP \fB\-trim \fIstring\fR Specifies a string leading characters to trim from entry pathnames before parsing. This only makes sense if the \fB\-separator\fR is also set. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the widget. If \fIpixels\fR is 0, then the with is computed from the contents of the \fBtreeview\fR widget. The default is \f(CW200\fR. .TP \fB\-xscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with horizontal scrollbars. Whenever the horizontal view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-xscrollincrement\fR \fIpixels\fR Sets the horizontal scrolling distance. The default is 20 pixels. .TP \fB\-yscrollcommand \fIstring\fR Specifies the prefix for a command used to communicate with vertical scrollbars. Whenever the vertical view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-yscrollincrement\fR \fIpixels\fR Sets the vertical scrolling distance. The default is 20 pixels. .SH "ENTRY OPTIONS" Many widget configuration options have counterparts in entries. For example, there is a \fB\-closecommand\fR configuration option for both widget itself and for individual entries. Options set at the widget level are global for all entries. If the entry configuration option is set, then it overrides the widget option. This is done to avoid wasting memory by replicated options. Most entries will have redundant options. .PP There is no resource class or name for entries. .TP \fB\-activeicons \fIimages\fR Specifies images to be displayed as the entry's icon when it is active. This overrides the global \fB\-activeicons\fR configuration option for the specific entry. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for nodes. \fITagList\fR is a list of binding tag names. The tags and their order will determine how events are handled for nodes. Each tag in the list matching the current event sequence will have its Tcl command executed. The default value is \f(CWall\fR. .TP \fB\-button \fIstring\fR Indicates whether a button should be displayed on the left side of the node entry. \fIString\fR can be \f(CWyes\fR, \f(CWno\fR, or \f(CWauto\fR. If \f(CWauto\fR, then a button is automatically displayed if the node has children. This is the default. .TP \fB\-closecommand \fIstring\fR Specifies a Tcl script to be invoked when the node is closed. This overrides the global \fB\-closecommand\fR option for this entry. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .TP \fB\-data \fIstring\fR Sets data fields for the node. \fIString\fR is a list of name-value pairs to be set. The default is \f(CW""\fR. .TP \fB\-font \fIfontName\fR Sets the font for entry labels. This overrides the widget's \fB\-font\fR option for this node. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-foreground \fIcolor\fR Sets the text color of the entry label. This overrides the widget's \fB\-foreground\fR configuration option. The default is \f(CW""\fR. .TP \fB\-icons \fIimages\fR Specifies images to be displayed for the entry's icon. This overrides the global \fB\-icons\fR configuration option. \fIImages\fR is a list of two Tk images: the first image is displayed when the node is open, the second when it is closed. .TP \fB\-label \fIstring\fR Sets the text for the entry's label. If not set, this defaults to the name of the node. The default is \f(CW""\fR. .TP \fB\-opencommand \fIstring\fR Specifies a Tcl script to be invoked when the entry is opened. This overrides the widget's \fB\-opencommand\fR option for this node. The default is \f(CW""\fR. Percent substitutions are performed on \fIstring\fR before it is executed. The following substitutions are valid: .RS .TP 5 \f(CW%W\fR The pathname of the widget. .TP 5 \f(CW%p\fR The name of the node. .TP 5 \f(CW%P\fR The full pathname of the node. .TP 5 \f(CW%#\fR The id of the node. .TP 5 \f(CW%%\fR Translates to a single percent. .RE .SH "BUTTON OPTIONS" Button configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWButton\fR. The resource name is always \f(CWbutton\fR. .CS option add *TreeView.Button.Foreground white option add *TreeView.button.Background blue .CE The following are the configuration options available for buttons. .TP \fB\-activebackground \fIcolor\fR Sets the background color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-activeforeground \fIcolor\fR Sets the foreground color of active buttons. A button is made active when the mouse passes over it or by the \fBbutton activate\fR operation. .TP \fB\-background \fIcolor\fR Sets the background of the button. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the button. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-closerelief \fIrelief\fR Specifies the 3-D effect for the closed button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-cursor \fIcursor\fR Sets the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the foreground color of buttons. The default is \f(CWblack\fR. .TP \fB\-images \fIimages\fR Specifies images to be displayed for the button. \fIImages\fR is a list of two Tk images: the first image is displayed when the button is open, the second when it is closed. If the \fIimages\fR is the empty string, then a plus/minus gadget is drawn. The default is \f(CW""\fR. .TP \fB\-openrelief \fIrelief\fR Specifies the 3-D effect of the open button. \fIRelief\fR indicates how the button should appear relative to the widget; for example, \f(CWraised\fR means the button should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-size \fIpixels\fR Sets the requested size of the button. The default is \f(CW0\fR. .RE .SH "COLUMN OPTIONS" Column configuration options may also be set by the \fBoption\fR command. The resource subclass is \f(CWColumn\fR. The resource name is the name of the column. .CS option add *TreeView.Column.Foreground white option add *TreeView.treeView.Background blue .CE The following configuration options are available for columns. .TP \fB\-background \fIcolor\fR Sets the background color of the column. This overrides the widget's \fB\-background\fR option. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border of the column. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW0\fR. .TP \fB\-edit \fIboolean\fR Indicates if the column's data fields can be edited. If \fIboolean\fR is false, the data fields in the column may not be edited. The default is \f(CWyes\fR. .TP \fB\-foreground \fIcolor\fR Specifies the foreground color of the column. You can override this for individual entries with the entry's \fB\-foreground\fR option. The default is \f(CWblack\fR. .TP \fB\-font \fIfontName\fR Sets the font for a column. You can override this for individual entries with the entry's \fB\-font\fR option. The default is \f(CW*-Helvetica-Bold-R-Normal-*-12-120-*\fR. .TP \fB\-hide \fIboolean\fR If \fIboolean\fR is true, the column is not displayed. The default is \f(CWyes\fR. .TP \fB\-justify \fIjustify\fR Specifies how the column data fields title should be justified within the column. This matters only when the column is wider than the data field to be display. \fIJustify\fR must be \f(CWleft\fR, \f(CWright\fR, or \f(CWcenter\fR. The default is \f(CWleft\fR. .TP \fB\-pad \fIpad\fR Specifies how much padding for the left and right sides of the column. \fIPad\fR is a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the column is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default is \f(CW2\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the column. \fIRelief\fR specifies how the column should appear relative to the widget; for example, \f(CWraised\fR means the column should appear to protrude. The default is \f(CWflat\fR. .TP \fB\-state \fIstate\fR Sets the state of the column. If \fIstate\fR is \f(CWdisable\fR then the column title can not be activated nor invoked. The default is \f(CWnormal\fR. .TP \fB\-title \fIstring\fR Sets the title for the column. The default is \f(CW""\fR. .TP \fB\-titleforeground \fIcolor\fR Sets the foreground color of the column title. The default is \f(CWblack\fR. .TP \fB\-titleshadow \fIcolor\fR Sets the color of the drop shadow of the column title. The default is \f(CW""\fR. .TP \fB\-width \fIpixels\fR Sets the requested width of the column. This overrides the computed with of the column. If \fIpixels\fR is 0, the width is computed as from the contents of the column. The default is \f(CW0\fR. .RE .SH "TEXT EDITING OPTIONS" Text edit window configuration options may also be set by the \fBoption\fR command. The resource class is \f(CWTreeViewEditor\fR. The resource name is always \f(CWedit\fR. .CS option add *TreeViewEditor.Foreground white option add *edit.Background blue .CE The following are the configuration options available for the text editing window. .TP \fB\-background \fIcolor\fR Sets the background of the text edit window. The default is \f(CWwhite\fR. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around the edit window. The \fB\-relief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-exportselection \fIboolean\fR Indicates if the text selection is exported. If the edit window is exporting its selection then it will observe the standard X11 protocols for handling the selection. Selections are available as type \fBSTRING\fR. The default is \f(CWno\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect of the edit window. \fIRelief\fR indicates how the background should appear relative to the edit window; for example, \f(CWraised\fR means the background should appear to protrude. The default is \f(CWsolid\fR. .TP \fB\-selectbackground \fIcolor\fR Sets the background of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectborderwidth \fIpixels\fR Sets the width of the 3\-D border around the selected text in the edit window. The \fB\-selectrelief\fR option determines if a border is to be drawn. The default is \f(CW1\fR. .TP \fB\-selectforeground \fIcolor\fR Sets the foreground of the selected text in the edit window. The default is \f(CWwhite\fR. .TP \fB\-selectrelief \fIrelief\fR Specifies the 3-D effect of the selected text in the edit window. \fIRelief\fR indicates how the text should appear relative to the edit window; for example, \f(CWraised\fR means the text should appear to protrude. The default is \f(CWflat\fR. .RE .SH "DEFAULT BINDINGS" Tk automatically creates class bindings for treeviews that give them Motif-like behavior. Much of the behavior of a \fBtreeview\fR widget is determined by its \fB\-selectmode\fR option, which selects one of two ways of dealing with the selection. .PP If the selection mode is \fBsingle\fR, only one node can be selected at a time. Clicking button 1 on an node selects it and deselects any other selected item. .PP If the selection mode is \fBmultiple\fR, any number of entries may be selected at once, including discontiguous ranges. Clicking Control-Button-1 on a node entry toggles its selection state without affecting any other entries. Pressing Shift-Button-1 on a node entry selects it, extends the selection. .IP [1] In \fBextended\fR mode, the selected range can be adjusted by pressing button 1 with the Shift key down: this modifies the selection to consist of the entries between the anchor and the entry under the mouse, inclusive. The un-anchored end of this new selection can also be dragged with the button down. .IP [2] In \fBextended\fR mode, pressing button 1 with the Control key down starts a toggle operation: the anchor is set to the entry under the mouse, and its selection state is reversed. The selection state of other entries isn't changed. If the mouse is dragged with button 1 down, then the selection state of all entries between the anchor and the entry under the mouse is set to match that of the anchor entry; the selection state of all other entries remains what it was before the toggle operation began. .IP [3] If the mouse leaves the treeview window with button 1 down, the window scrolls away from the mouse, making information visible that used to be off-screen on the side of the mouse. The scrolling continues until the mouse re-enters the window, the button is released, or the end of the hierarchy is reached. .IP [4] Mouse button 2 may be used for scanning. If it is pressed and dragged over the \fBtreeview\fR widget, the contents of the hierarchy drag at high speed in the direction the mouse moves. .IP [5] If the Up or Down key is pressed, the location cursor (active entry) moves up or down one entry. If the selection mode is \fBbrowse\fR or \fBextended\fR then the new active entry is also selected and all other entries are deselected. In \fBextended\fR mode the new active entry becomes the selection anchor. .IP [6] In \fBextended\fR mode, Shift-Up and Shift-Down move the location cursor (active entry) up or down one entry and also extend the selection to that entry in a fashion similar to dragging with mouse button 1. .IP [7] The Left and Right keys scroll the \fBtreeview\fR widget view left and right by the width of the character \fB0\fR. Control-Left and Control-Right scroll the \fBtreeview\fR widget view left and right by the width of the window. Control-Prior and Control-Next also scroll left and right by the width of the window. .IP [8] The Prior and Next keys scroll the \fBtreeview\fR widget view up and down by one page (the height of the window). .IP [9] The Home and End keys scroll the \fBtreeview\fR widget horizontally to the left and right edges, respectively. .IP [10] Control-Home sets the location cursor to the the first entry, selects that entry, and deselects everything else in the widget. .IP [11] Control-End sets the location cursor to the the last entry, selects that entry, and deselects everything else in the widget. .IP [12] In \fBextended\fR mode, Control-Shift-Home extends the selection to the first entry and Control-Shift-End extends the selection to the last entry. .IP [13] In \fBmultiple\fR mode, Control-Shift-Home moves the location cursor to the first entry and Control-Shift-End moves the location cursor to the last entry. .IP [14] The space and Select keys make a selection at the location cursor (active entry) just as if mouse button 1 had been pressed over this entry. .IP [15] In \fBextended\fR mode, Control-Shift-space and Shift-Select extend the selection to the active entry just as if button 1 had been pressed with the Shift key down. .IP [16] In \fBextended\fR mode, the Escape key cancels the most recent selection and restores all the entries in the selected range to their previous selection state. .IP [17] Control-slash selects everything in the widget, except in \fBsingle\fR and \fBbrowse\fR modes, in which case it selects the active entry and deselects everything else. .IP [18] Control-backslash deselects everything in the widget, except in \fBbrowse\fR mode where it has no effect. .IP [19] The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the selection in the widget to the clipboard, if there is a selection. .PP The behavior of \fBtreeview\fR widgets can be changed by defining new bindings for individual widgets or by redefining the class bindings. .SS WIDGET BINDINGS In addition to the above behavior, the following additional behavior is defined by the default widget class (TreeView) bindings. .IP \f(CW<ButtonPress-2>\fR Starts scanning. .IP \f(CW<B2-Motion>\fR Adjusts the scan. .IP \f(CW<ButtonRelease-2>\fR Stops scanning. .IP \f(CW<B1-Leave>\fR Starts auto-scrolling. .IP \f(CW<B1-Enter>\fR Starts auto-scrolling .IP \f(CW<KeyPress-Up>\fR Moves the focus to the previous entry. .IP \f(CW<KeyPress-Down>\fR Moves the focus to the next entry. .IP \f(CW<Shift-KeyPress-Up>\fR Moves the focus to the previous sibling. .IP \f(CW<Shift-KeyPress-Down>\fR Moves the focus to the next sibling. .IP \f(CW<KeyPress-Prior>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Next>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-Left>\fR Closes the entry. It is not an error if the entry has no children. .IP \f(CW<KeyPress-Right>\fR Opens the entry, displaying its children. It is not an error if the entry has no children. .IP \f(CW<KeyPress-space>\fR In "single" select mode this selects the entry. In "multiple" mode, it toggles the entry (if it was previous selected, it is not deselected). .IP \f(CW<KeyRelease-space>\fR Turns off select mode. .IP \f(CW<KeyPress-Return>\fR Sets the focus to the current entry. .IP \f(CW<KeyRelease-Return>\fR Turns off select mode. .IP \f(CW<KeyPress>\fR Moves to the next entry whose label starts with the letter typed. .IP \f(CW<KeyPress-Home>\fR Moves the focus to first entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-End>\fR Move the focus to the last entry. Closed or hidden entries are ignored. .IP \f(CW<KeyPress-F1>\fR Opens all entries. .IP \f(CW<KeyPress-F2>\fR Closes all entries (except root). .SS BUTTON BINDINGS Buttons have bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the button of the current entry. .IP \f(CW<Leave>\fR Returns the button back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Adjust the view so that the current entry is visible. .SS ENTRY BINDINGS Entries have default bindings. There are associated with the "all" bindtag (see the entry's -bindtag option). You can use the \fBbind\fR operation to modify them. .IP \f(CW<Enter>\fR Highlights the current entry. .IP \f(CW<Leave>\fR Returns the entry back to its normal state. .IP \f(CW<ButtonPress-1>\fR Sets the selection anchor the current entry. .IP \f(CW<Double-ButtonPress-1>\fR Toggles the selection of the current entry. .IP \f(CW<B1-Motion>\fR For "multiple" mode only. Saves the current location of the pointer for auto-scrolling. Resets the selection mark. .IP \f(CW<ButtonRelease-1>\fR For "multiple" mode only. Sets the selection anchor to the current entry. .IP \f(CW<Shift-ButtonPress-1>\fR For "multiple" mode only. Extends the selection. .IP \f(CW<Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Shift-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Shift-ButtonRelease-1>\fR Stop auto-scrolling. .IP \f(CW<Control-ButtonPress-1>\fR For "multiple" mode only. Toggles and extends the selection. .IP \f(CW<Control-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-B1-Motion>\fR Place holder. Does nothing. .IP \f(CW<Control-ButtonRelease-1>\fR Stops auto-scrolling. .IP \f(CW<Control-Shift-ButtonPress-1>\fR ??? .IP \f(CW<Control-Shift-Double-ButtonPress-1>\fR Place holder. Does nothing. .IP \f(CW<Control-Shift-B1-Motion>\fR Place holder. Does nothing. .SS COLUMN BINDINGS Columns have bindings too. They are associated with the column's "all" bindtag (see the column -bindtag option). You can use the \fBcolumn bind\fR operation to change them. .IP \f(CW<Enter>\fR Highlights the current column title. .IP \f(CW<Leave>\fR Returns the column back to its normal state. .IP \f(CW<ButtonRelease-1>\fR Invokes the command (see the column's -command option) if one if specified. .SS COLUMN RULE BINDINGS .IP \f(CW<Enter>\fR Highlights the current and activates the ruler. .IP \f(CW<Leave>\fR Returns the column back to its normal state. Deactivates the ruler. .IP \f(CW<ButtonPress-1>\fR Sets the resize anchor for the column. .IP \f(CW<B1-Motion>\fR Sets the resize mark for the column. .IP \f(CW<ButtonRelease-1>\fR Adjust the size of the column, based upon the resize anchor and mark positions. .SH EXAMPLE The \fBtreeview\fR command creates a new widget. .CS treeview .h \-bg white .CE A new Tcl command \f(CW.h\fR is also created. This command can be used to query and modify the \fBtreeview\fR widget. For example, to change the background color of the table to "green", you use the new command and the widget's \fBconfigure\fR operation. .CS # Change the background color. \&.h configure \-background "green" .CE By default, the \fBtreeview\fR widget will automatically create a new tree object to contain the data. The name of the new tree is the pathname of the widget. Above, the new tree object name is ".h". But you can use the \fB\-tree\fR option to specify the name of another tree. .CS # View the tree "myTree". \&.h configure \-tree "myTree" .CE When a new tree is created, it contains only a root node. The node is automatically opened. The id of the root node is always \f(CW0\fR (you can use also use the special id \f(CWroot\fR). The \fBinsert\fR operation lets you insert one or more new entries into the tree. The last argument is the node's \fIpathname\fR. .CS # Create a new entry named "myEntry" set id [\&.h insert end "myEntry"] .CE This appends a new node named "myEntry". It will positioned as the last child of the root of the tree (using the position "end"). You can supply another position to order the node within its siblings. .CS # Prepend "fred". set id [\&.h insert 0 "fred"] .CE Entry names do not need to be unique. By default, the node's label is its name. To supply a different text label, add the \fB\-label\fR option. .CS # Create a new node named "fred" set id [\&.h insert end "fred" -label "Fred Flintstone"] .CE The \fBinsert\fR operation returns the id of the new node. You can also use the \fBindex\fR operation to get this information. .CS # Get the id of "fred" \&.h index "fred" .CE To insert a node somewhere other than root, use the \fB\-at\fR switch. It takes the id of the node where the new child will be added. .CS # Create a new node "barney" in "fred". \&.h insert -at $id end "barney" .CE A pathname describes the path to an entry in the hierarchy. It's a list of entry names that compose the path in the tree. Therefore, you can also add "barney" to "fred" as follows. .CS # Create a new sub-entry of "fred" \&.h insert end "fred barney" .CE Every name in the list is ancestor of the next. All ancestors must already exist. That means that an entry "fred" is an ancestor of "barney" and must already exist. But you can use the \fB\-autocreate\fR configuration option to force the creation of ancestor nodes. .CS # Force the creation of ancestors. \&.h configure -autocreate yes \&.h insert end "fred barney wilma betty" .CE Sometimes the pathname is already separated by a character sequence rather than formed as a list. A file name is a good example of this. You can use the \fB\-separator\fR option to specify a separator string to split the path into its components. Each pathname inserted is automatically split using the separator string as a separator. Multiple separators are treated as one. .CS \&.h configure -separator / \&.h insert end "/usr/local/tcl/bin" .CE If the path is prefixed by extraneous characters, you can automatically trim it off using the \fB\-trim\fR option. It removed the string from the path before it is parsed. .CS \&.h configure -trim C:/windows -separator / \&.h insert end "C:/window/system" .CE You can insert more than one entry at a time with the \fBinsert\fR operation. This can be much faster than looping over a list of names. .CS # The slow way foreach f [glob $dir/*] { \&.h insert end $f } # The fast way eval .h insert end [glob $dir/*] .CE In this case, the \fBinsert\fR operation will return a list of ids of the new entries. .PP You can delete entries with the \fBdelete\fR operation. It takes one or more tags of ids as its argument. It deletes the entry and all its children. .CS \&.h delete $id .CE Entries have several configuration options. They control the appearance of the entry's icon and label. We have already seen the \fB\-label\fR option that sets the entry's text label. The \fBentry configure\fR operation lets you set or modify an entry's configuration options. .CS \&.h entry configure $id -color red -font fixed .CE You can hide an entry and its children using the \fB\-hide\fR option. .CS \&.h entry configure $id -hide yes .CE More that one entry can be configured at once. All entries specified are configured with the same options. .CS \&.h entry configure $i1 $i2 $i3 $i4 -color brown .CE An icon is displayed for each entry. It's a Tk image drawn to the left of the label. You can set the icon with the entry's \fB\-icons\fR option. It takes a list of two image names: one to represent the open entry, another when it is closed. .CS set im1 [image create photo -file openfolder.gif] set im2 [image create photo -file closefolder.gif] \&.h entry configure $id -icons "$im1 $im2" .CE If \fB\-icons\fR is set to the empty string, no icons are display. .PP If an entry has children, a button is displayed to the left of the icon. Clicking the mouse on this button opens or closes the sub-hierarchy. The button is normally a \f(CW+\fR or \f(CW\-\fR symbol, but can be configured in a variety of ways using the \fBbutton configure\fR operation. For example, the \f(CW+\fR and \f(CW\-\fR symbols can be replaced with Tk images. .CS set im1 [image create photo -file closefolder.gif] set im2 [image create photo -file downarrow.gif] \&.h button configure $id -images "$im1 $im2" \\ -openrelief raised -closerelief raised .CE Entries can contain an arbitrary number of \fIdata fields\fR. Data fields are name-value pairs. Both the value and name are strings. The entry's \fB\-data\fR option lets you set data fields. .CS \&.h entry configure $id -data {mode 0666 group users} .CE The \fB\-data\fR takes a list of name-value pairs. .PP You can display these data fields as \fIcolumns\fR in the \fBtreeview\fR widget. You can create and configure columns with the \fBcolumn\fR operation. For example, to add a new column to the widget, use the \fBcolumn insert\fR operation. The last argument is the name of the data field that you want to display. .CS \&.h column insert end "mode" .CE The column title is displayed at the top of the column. By default, it's is the field name. You can override this using the column's \fB\-title\fR option. .CS \&.h column insert end "mode" -title "File Permissions" .CE Columns have several configuration options. The \fBcolumn configure\fR operation lets you query or modify column options. .CS \&.h column configure "mode" -justify left .CE The \fB\-justify\fR option says how the data is justified within in the column. The \fB\-hide\fR option indicates whether the column is displayed. .CS \&.h column configure "mode" -hide yes .CE Entries can be selected by clicking on the mouse. Selected entries are drawn using the colors specified by the \fB\-selectforeground\fR and \fB\-selectbackground\fR configuration options. The selection itself is managed by the \fBselection\fR operation. .CS # Clear all selections \&.h selection clear 0 end # Select the root node \&.h selection set 0 .CE The \fBcurselection\fR operation returns a list of ids of all the selected entries. .CS set ids [\&.h curselection] .CE You can use the \fBget\fR operation to convert the ids to their pathnames. .CS set names [eval .h get -full $ids] .CE If a treeview is exporting its selection (using the \fB\-exportselection\fR option), then it will observe the standard X11 protocols for handling the selection. Treeview selections are available as type \fBSTRING\fR; the value of the selection will be the pathnames of the selected entries, separated by newlines. .PP The \fBtreeview\fR supports two modes of selection: \f(CWsingle\fR and \f(CWmultiple\fR. In single select mode, only one entry can be selected at a time, while multiple select mode allows several entries to be selected. The mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -selectmode "multiple" .CE You can be notified when the list of selected entries changes. The widget's \fB\-selectcommand\fR specifies a Tcl procedure that is called whenever the selection changes. .CS proc SelectNotify { widget } { set ids [\&$widget curselection] } \&.h configure -selectcommand "SelectNotify .h" .CE The widget supports the standard Tk scrolling and scanning operations. The \fBtreeview\fR can be both horizontally and vertically. You can attach scrollbars to the \fBtreeview\fR the same way as the listbox or canvas widgets. .CS scrollbar .xbar -orient horizontal -command ".h xview" scrollbar .ybar -orient vertical -command ".h yview" \&.h configure -xscrollcommand ".xbar set" \\ -yscrollcommand ".ybar set" .CE There are three different modes of scrolling: \f(CWlistbox\fR, \f(CWcanvas\fR, and \f(CWhierbox\fR. In \f(CWlistbox\fR mode, the last entry can always be scrolled to the top of the widget. In \f(CWhierbox\fR mode, the last entry is always drawn at the bottom of the widget. The scroll mode is set by the widget's \fB\-selectmode\fR option. .CS \&.h configure -scrollmode "listbox" .CE Entries can be programmatically opened or closed using the \fBopen\fR and \fBclose\fR operations respectively. .CS \&.h open $id \&.h close $id .CE When an entry is opened, a Tcl procedure can be automatically invoked. The \fB\-opencommand\fR option specifies this procedure. This procedure can lazily insert entries as needed. .CS proc AddEntries { dir } { eval .h insert end [glob -nocomplain $dir/*] } \&.h configure -opencommand "AddEntries %P" .CE Now when an entry is opened, the procedure \f(CWAddEntries\fR is called and adds children to the entry. Before the command is invoked, special "%" substitutions (like \fBbind\fR) are performed. Above, \f(CW%P\fR is translated to the pathname of the entry. .PP The same feature exists when an entry is closed. The \fB\-closecommand\fR option specifies the procedure. .CS proc DeleteEntries { id } { .h entry delete $id 0 end } \&.h configure -closecommand "DeleteEntries %#" .CE When an entry is closed, the procedure \f(CWDeleteEntries\fR is called and deletes the entry's children using the \fBentry delete\fR operation (\f(CW%#\fR is the id of entry). .SH KEYWORDS treeview, widget ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/man/tabset.mann�������������������������������������������������������������������0000644�0001750�0001750�00000115056�11462120062�015156� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� '\" '\" Copyright 1998 by Bell Labs Innovations for Lucent Technologies. '\" '\" Permission to use, copy, modify, and distribute this software and its '\" documentation for any purpose and without fee is hereby granted, provided '\" that the above copyright notice appear in all copies and that both that the '\" copyright notice and warranty disclaimer appear in supporting documentation, '\" and that the names of Lucent Technologies any of their entities not be used '\" in advertising or publicity pertaining to distribution of the software '\" without specific, written prior permission. '\" '\" Lucent Technologies disclaims all warranties with regard to this software, '\" including all implied warranties of merchantability and fitness. In no event '\" shall Lucent Technologies be liable for any special, indirect or '\" consequential damages or any damages whatsoever resulting from loss of use, '\" data or profits, whether in an action of contract, negligence or other '\" tortuous action, arising out of or in connection with the use or performance '\" of this software. '\" '\" Tabset widget created by George Howlett. '\" .so man.macros .TH tabset n BLT_VERSION BLT "BLT Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME tabset \- Create and manipulate tabset widgets .BE .SH SYNOPSIS \fBtabset\fR \fIpathName \fR?\fIoptions\fR? .SH DESCRIPTION The \fBtabset\fR widget displays a series of tabbed folders where only one folder at a time is displayed. A folder can contain a Tk widget that is displayed when the folder is displayed. .PP There's no limit to the number of folders. Tabs can be tiered (more than one row). If there are more tabs than can be displayed, tabs can also be scrolled. Any folder can also be torn off, when the contents (the Tk widget contained by it) is temporarily moved into another toplevel widget. A tabset may used as just a set of tabs, without a displaying any pages. You can bind events to individual tabs, so it's easy to add features like "balloon help". .SH SYNTAX The \fBtabset\fR command creates a new window using the \fIpathName\fR argument and makes it into a tabset widget. .DS \fBtabset \fIpathName \fR?\fIoption value\fR?... .DE Additional options may be specified on the command line or in the option database to configure aspects of the tabset such as its colors, font, text, and relief. The \fBtabset\fR command returns its \fIpathName\fR argument. At the time this command is invoked, there must not exist a window named \fIpathName\fR, but \fIpathName\fR's parent must exist. .PP When first created the new tabset widget contains no tabs. Tabs are added using the \fBinsert\fR operation described below. The size of the tabset window is determined the number of tiers of tabs requested and the sizes of the Tk widgets embedded inside each folder. The widest embedded widget determines the width of all folders. The tallest determines the height. If no folders contain an embedded widget, the size is detemined solely by the size of the tabs. You can override either dimension with the tabset's \fB\-width\fR and \fB\-height\fR options. .PP Tabs may be scrolled using the \fB\-scrollcommand\fR option. They also support scanning (see the \fBscan\fR operation). Tabs also may be arranged along any side of the tabset window using the \fB\-side\fR option. .PP An individual tabs/folders in the tabset may be described by its index, name, tag or text label. .SS "INDICES" An index is the order of the tab in the tabset. Indices start from zero. In addition to numeric indices, there are additional special indices. They are described below: .TP 12 \fInumber\fR Unique node id of the tab. .TP 12 \fB@\fIx\fB,\fIy\fR Tab that covers the point in the tabset window specified by \fIx\fR and \fIy\fR (in screen coordinates). If no tab covers that point, then the index is ignored. .TP 12 \fBselected\fR The currently selected tab. The \fBselected\fR index is typically changed by either clicking on the tab with the left mouse button or using the widget's \fBinvoke\fR operation. .TP 12 \fBactive\fR The tab where the mouse pointer is currently located. The label is drawn using its active colors (see the \fB\-activebackground\fR and \fB\-activeforeground\fR options). The \fBactive\fR index is typically changed by moving the mouse pointer over a tab or using the widget's \fBactivate\fR operation. There can be only one active tab at a time. If there is no tab located under the mouse pointer, the index is ignored. .TP 12 \fBfocus\fR Tab that currently has the widget's focus. This tab is displayed with a dashed line around its label. You can change this using the \fBfocus\fR operation. If no tab has focus, then the index is ignored. .TP 12 \fBdown\fR Tab immediately below the tab that currently has focus, if there is one. If there is no tab below, the current tab is returned. .TP 12 \fBleft\fR Tab immediately to the left the tab that currently has focus, if there is one. If there is no tab to the left, the current tab is returned. .TP 12 \fBright\fR Tab immediately to the right the tab that currently has focus, if there is one. If there is no tab to the right, the current tab is returned. .TP 12 \fBup\fR Tab immediately above, if there is one, to the tab that currently has focus. If there is no tab above, the current tab is returned. .TP 12 \fBend\fR Last tab in the tabset. If there are no tabs in the tabset then the index is ignored. .LP Some indices may not always be available. For example, if the mouse is not over any tab, "active" does not have an index. For most tabset operations this is harmless and ignored. .SH "NAMES" .SH "OPERATIONS" All \fBtabset\fR operations are invoked by specifying the widget's pathname, the operation, and any arguments that pertain to that operation. The general form is: .sp .DS \fIpathName operation \fR?\fIarg arg ...\fR? .DE .sp \fIOperation\fR and the \fIarg\fRs determine the exact behavior of the command. The following operations are available for tabset widgets: .TP \fIpathName \fBactivate\fR \fItab\fR Sets the active tab to the one indicated by \fIindex\fR. The active tab is drawn with its \fIactive\fR colors (see the \fB\-activebackground\fR and \fB\-activeforeground\fR options) and may be retrieved with the index \fBactive\fR. Only one tab may be active at a time. If \fIindex\fR is the empty string, then all tabs will be drawn with their normal foreground and background colors. .TP \fIpathName \fBbind\fR \fItagName\fR ?\fIsequence\fR? ?\fIcommand\fR? Associates \fIcommand\fR with \fItagName\fR such that whenever the event sequence given by \fIsequence\fR occurs for a tab with this tag, \fIcommand\fR will be invoked. The syntax is similar to the \fBbind\fR command except that it operates on tabs, rather than widgets. See the \fBbind\fR manual entry for complete details on \fIsequence\fR and the substitutions performed on \fIcommand\fR. .sp If all arguments are specified then a new binding is created, replacing any existing binding for the same \fIsequence\fR and \fItagName\fR. If the first character of \fIcommand\fR is \f(CW+\fR then \fIcommand\fR augments an existing binding rather than replacing it. If no \fIcommand\fR argument is provided then the command currently associated with \fItagName\fR and \fIsequence\fR (it's an error occurs if there's no such binding) is returned. If both \fIcommand\fR and \fIsequence\fR are missing then a list of all the event sequences for which bindings have been defined for \fItagName\fR. .TP \fIpathName \fBcget\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBconfigure\fR operation described in the section .SB "WIDGET OPTIONS" below. .TP \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of the widget. If no \fIoption\fR is specified, returns a list describing all the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for information on the format of this list). If \fIoption\fR is specified with no \fIvalue\fR, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no \fIoption\fR is specified). If one or more \fIoption\-value\fR pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. \fIOption\fR and \fIvalue\fR are described in the section .SB "WIDGET OPTIONS" below. .TP \fIpathName \fBdelete \fItab...\fR? Deletes one or more tabs from the tabset. \fITab\fR may be an index, tag, name, or label referring to one or more tabs. .TP \fIpathName \fBfocus \fItab\fR Specifies the tab to get the widget's focus. The tab is displayed with a dashed line around its label. .TP \fIpathName \fBget\fR \fItab\fR Returns the name of the tab. The value of \fIindex\fR may be in any form described in the section .SB "INDICES". .TP \fIpathName \fBindex\fR ?\fIflag\fR? \fIstring\fR Returns the node id of the tab specified by \fIstring\fR. If \fIflag\fR is \fB\-name\fR, then \fIstring\fR is the name of a tab. If \fIflag\fR is \fB\-index\fR, \fIstring\fR is an index such as "active" or "focus". If \fIflag\fR isn't specified, it defaults to \fB\-index\fR. .TP \fIpathName \fBinsert\fR \fIposition\fR ?\fIname\fR? ?\fIoption value\fR?... Inserts a new tab into the tabset. The new tab is inserted before the tab given by \fIposition\fR. \fIPosition\fR may be either a number, indicating where in the list the new tab should be added, or \fBend\fR, indicating that the new tab is to be added the end of the list. \fIName\fR is the name of the tab. If \fIname\fR isn't given, then a name is generated in the form "tabN". Returns the name of the new tab. .TP \fIpathName \fBinvoke \fItab\fR Selects the folder given by \fItab\fR, displaying it in the tabset. It also invokes the Tcl command associated with the tab \ (see the tabset's \fB\-selectcommand\fR option or the tab's \fB\-command\fR option), if there is one. It returns the return value from the Tcl command, or an empty string if there is no command associated with the tab. This command is ignored if the tab's state (see the \fB\-state\fR option) is disabled. .TP \fIpathName \fBmove\fR \fItab\fR \fBbefore\fR|\fBafter\fR \fItab\fR Moves the tab \fItab\fR to a new position in the tabset. .TP \fIpathName \fBnearest\fR \fIx\fR \fIy\fR Returns the name of the tab nearest to given X-Y screen coordinate. .TP \fIpathName \fBperforation \fIoperation\fR ?\fIargs\fR? This operation controls the perforation on the tab label. .RS .TP \fIpathName \fBperforation highlight\fR \fItab\fR \fIboolean\fR .TP \fIpathName \fBperforation invoke\fR \fItab\fR Invokes the command specified for perforations (see the \fB\-perforationcommand\fR widget option). Typically this command places the page into a top level widget. The name of the toplevel is the concatonation of the \fIpathName\fR, "-", and the \fItabName\fR. The return value is the return value from the Tcl command, or an empty string if there is no command associated with the tab. This command is ignored if the tab's state (see the \fB\-state\fR option) is disabled. .RE .TP \fIpathName \fBscan\fR \fIoption args\fR This command implements scanning on tabsets. It has two forms, depending on \fIoption\fR: .RS .TP \fIpathName \fBscan mark \fIx y\fR Records \fIx\fR and \fIy\fR and the current view in the tabset window; used with later \fBscan dragto\fR commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. .TP \fIpathName \fBscan dragto \fIx y\fR. This command computes the difference between its \fIx\fR and \fIy\fR arguments and the \fIx\fR and \fIy\fR arguments to the last \fBscan mark\fR command for the widget. It then adjusts the view by 10 times the difference in coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the list at high speed through the window. The return value is an empty string. .RE .TP \fIpathName \fBsee \fItab\fR Scrolls the tabset so that the tab \fItab\fR is visible in the widget's window. .TP \fIpathName \fBsize\fR Returns the number of tabs in the tabset. .TP \fIpathName \fBtab \fIoperation\fR ?\fIargs\fR? .RS .TP \fIpathName \fBtab cget\fR \fItab\fR \fIoption\fR Returns the current value of the configuration option given by \fIoption\fR for tab \fItab\fR. \fIOption\fR may have any of the values accepted by the \fBtab configure\fR operation described in the section .SB "TAB OPTIONS" below. .TP \fIpathName \fBtab configure\fR \fItab\fR \fIoption\fR? ?\fIvalue option value ...\fR? Query or modify the configuration options of one or more tabs. More than one tab can be configured if \fItab\fR refers to multiple tabs. If no \fIoption\fR is specified, this operation returns a list describing all the available options for \fItab\fR. .sp If \fIoption\fR is specified, but not \fIvalue\fR, then a list describing the one named option is returned. If one or more \fIoption\-value\fR pairs are specified, then each named tab (specified by \fInameOrIndex\fR) will have its configurations option(s) set the given value(s). In this last case, the empty string is returned. \fIOption\fR and \fIvalue\fR are described in the section .SB "TAB OPTIONS" below. .TP \fIpathName \fBtab names\fR ?\fIpattern\fR? Returns the names of all the tabs matching the given pattern. If no \fIpattern\fR argument is provided, then all tab names are returned. .TP \fIpathName \fBtab tearoff \fItab\fR ?\fIwindow\fR? Moves the widget embedded the folder \fItab\fR (see the \fB-window\fR option), placing it inside of \fIwindow\fR. \fIWindow\fR is either the name of an new widget that will contain the embedded widget or the name of the \fBtabset\fR widget. It the last case, the embedded widget is put back into the folder. .sp If no \fIwindow\fR argument is provided, then the name of the current parent of the embedded widget is returned. .RE .TP \fIpathName \fBview \fIargs\fR This command queries or changes the position of the tabset in the widget's window. It can take any of the following forms: .RS .TP \fIpathName \fBview\fR Returns a list of two numbers between 0.0 and 1.0 that describe the amount and position of the tabset that is visible in the window. For example, if \fIview\fR is "0.2 0.6", 20% of the tabset's text is off-screen to the left, 40% is visible in the window, and 40% of the tabset is off-screen to the right. These are the same values passed to scrollbars via the \fB\-scrollcommand\fR option. .TP \fIpathName \fBview moveto\fI fraction\fR Adjusts the view in the window so that \fIfraction\fR of the total width of the tabset text is off-screen to the left. \fIfraction\fR must be a number between 0.0 and 1.0. .TP \fIpathName \fBview scroll \fInumber what\fR This command shifts the view in the window (left/top or right/bottom) according to \fInumber\fR and \fIwhat\fR. \fINumber\fR must be an integer. \fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation of these. If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by \fInumber\fR scroll units (see the \fB\-scrollincrement\fR option). ; if it is \fBpages\fR then the view adjusts by \fInumber\fR widget windows. If \fInumber\fR is negative then tabs farther to the left become visible; if it is positive then tabs farther to the right become visible. .RE .SH "WIDGET OPTIONS" Widget configuration options may be set either by the \fBconfigure\fR operation or the Tk \fBoption\fR command. The resource class is \f(CWTabset\fR. The resource name is the name of the widget. .CS option add *Tabset.Foreground white option add *Tabset.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the default active background color for tabs. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB\-activebackground\fR option. .TP \fB\-activeforeground \fIcolor\fR Sets the default active foreground color for tabs. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB\-activeforeground\fR option. .TP \fB\-background \fIcolor\fR Sets the default background color of folders. Individual tabs can override this with their own \fBR-background\fR option. .TP \fB\-borderwidth \fIpixels\fR Sets the width of the 3\-D border around tabs and folders. The \fB\-relief\fR option determines how the border is to be drawn. The default is \f(CW1\fR. .TP \fB\-relief \fIrelief\fR Specifies the 3-D effect for both tabs and folders. \fIRelief\fR specifies how the tabs should appear relative to background of the widget; for example, \f(CWraised\fR means the tab should appear to protrude. The default is \f(CWraised\fR. .TP \fB\-troughbackground \fIcolor\fR Sets the background color of the trough under the tabs. .TP \fB\-outerborderwidth \fIpixels\fR Sets the width of the 3\-D border around the outside edge of the widget. The \fB\-relief\fR option determines how the border is to be drawn. The default is \f(CW0\fR. .TP \fB\-outerpad \fIpixels\fR Sets the amount of padding between the highlight ring on the outer edge of the tabset and the folder. The default is \f(CW0\fR. .TP \fB\-outerrelief \fIrelief\fR Specifies the 3-D effect for the tabset widget. \fIRelief\fR specifies how the tabset should appear relative to widget that it is packed into; for example, \f(CWraised\fR means the tabset should appear to protrude. The default is \f(CWsunken\fR. .TP \fB\-cursor \fIcursor\fR Specifies the widget's cursor. The default cursor is \f(CW""\fR. .TP \fB\-dashes \fIdashList\fR Sets the dash style of the focus outline. When a tab has the widget's focus, it is drawn with a dashed outline around its label. \fIDashList\fR is a list of up to 11 numbers that alternately represent the lengths of the dashes and gaps on the cross hair lines. Each number must be between 1 and 255. If \fIdashList\fR is \f(CW""\fR, the outline will be a solid line. The default value is \f(CW5 2\fR. .TP \fB\-font \fIfontName\fR Sets the default font for the text in tab labels. Individual tabs may override this by setting the tab's \fB\-font\fR option. The default value is \f(CW*Arial 9\fR. .TP \fB\-foreground \fIcolor\fR Sets the default color of tab labels. Individual tabs may override this option by setting the tab's \fB\-foreground\fR option. The default value is \f(CWblack\fR. .TP \fB\-gap \fIsize\fR Sets the gap (in pixels) between tabs. The default value is \f(CW2\fR. .TP \fB\-height \fIpixels\fR Specifies the requested height of widget. If \fIpixels\fR is 0, then the height of the widget will be calculated based on the size the tabs and their pages. The default is \f(CW0\fR. .TP \fB\-highlightbackground \fIcolor\fR Sets the color to display in the traversal highlight region when the tabset does not have the input focus. .TP \fB\-highlightcolor \fIcolor\fR Sets the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus. The default is \f(CWblack\fR. .TP \fB\-highlightthickness \fIpixels\fR Sets the width of the highlight rectangle to draw around the outside of the widget when it has the input focus. \fIPixels\fR is a non-negative value and may have any of the forms acceptable to \fBTk_GetPixels\fR. If the value is zero, no focus highlight is drawn around the widget. The default is \f(CW2\fR. .TP \fB\-pageheight \fIpixels\fR Sets the requested height of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum height of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-pagewidth \fIpixels\fR Sets the requested width of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum width of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-perforationcommand\fR \fIstring\fR Specifies a Tcl script to be invoked to tear off the current page in the tabset. This command is typically invoked when left mouse button is released over the tab perforation. The default action is to tear-off the page and place it into a new toplevel window. .TP \fB\-rotate \fIangle\fR Specifies the degrees to rotate text in tab labels. \fIAngle\fR is a real value representing the number of degrees to rotate the text labels. The default is \f(CW0.0\fR degrees. .TP \fB\-tabwidth \fIwidth\fR Indicates the width of each tab. \fIWidth\fR can be one of the following: .RS .TP 1i \f(CWvariable\fR The width of the tab is determined by its text and image. .TP 1i \f(CWsame\fR The width of every tab is the maximum size. .TP 1i \f(CWpixels\fR The width of the tab is set to \fIpixels\R. \fIPixels\fR is a positive screen distance. .RE The default is \f(CWsame\fR. .TP \fB\-scrollcommand \fIstring\fR Specifies the prefix for a command for communicating with scrollbars. Whenever the view in the widget's window changes, the widget will generate a Tcl command by concatenating the scroll command and two numbers. If this option is not specified, then no command will be executed. .TP \fB\-scrollincrement \fIpixels\fR Sets the smallest number of pixels to scroll the tabs. If \fIpixels\fR is greater than 0, this sets the units for scrolling (e.g., when you the change the view by clicking on the left and right arrows of a scrollbar). .TP \fB\-selectbackground \fIcolor\fR Sets the color to use when displaying background of the selected tab. Individual tabs can override this option by setting the tab's \fB\-selectbackground\fR option. '\".TP '\" \fB\-selectborderwidth \fIpixels\fR '\" Sets the width of the raised 3-D border to draw around the label of '\" the selected tab. \fIPixels\fR must be a non-negative value. '\" The default value is \f(CW1\fR. .TP \fB\-selectcommand \fIstring\fR Specifies a default Tcl script to be associated with tabs. This command is typically invoked when left mouse button is released over the tab. Individual tabs may override this with the tab's \fB\-command\fR option. The default value is \f(CW""\fR. .TP \fB\-selectforeground \fIcolor\fB Sets the default color of the selected tab's text label. Individual tabs can override this option by setting the tab's \fB\-selectforeground\fR option. The default value is \f(CWblack\fR. .TP \fB\-selectpad \fIpixels\fB Specifies extra padding to be displayed around the selected tab. The default value is \f(CW3\fR. .TP \fB\-side \fIside\fB Specifies the side of the widget to place tabs. The following values are valid for \fIside\fR. The default value is \f(CWtop\fR. .RS .TP 1i \f(CWtop\fR Tabs are drawn along the top. .TP 1i \f(CWleft\fR Tabs are drawn along the left side. .TP 1i \f(CWright\fR Tabs are drawn along the right side. .TP 1i \f(CWboth\fR Tabs are drawn along the bottom side. .RE .TP \fB\-slant \fIslant\fR Specifies if the tabs should be slanted 45 degrees on the left and/or right sides. The following values are valid for \fIslant\fR. The default is \f(CWnone\fR. .RS .TP 1i \f(CWnone\fR Tabs are drawn as a rectangle. .TP 1i \f(CWleft\fR The left side of the tab is slanted. .TP 1i \f(CWright\fR The right side of the tab is slanted. .TP 1i \f(CWboth\fR Boths sides of the tab are slanted. .RE .TP \fB\-takefocus\fR \fIfocus\fR Provides information used when moving the focus from window to window via keyboard traversal (e.g., Tab and Shift-Tab). If \fIfocus\fR is \f(CW0\fR, this means that this window should be skipped entirely during keyboard traversal. \f(CW1\fR means that the this window should always receive the input focus. An empty value means that the traversal scripts decide whether to focus on the window. The default is \f(CW1\fR. .TP \fB\-tearoff \fIboolean\fR .TP \fB\-textside \fIside\fB If both images and text are specified for a tab, this option determines on which side of the tab the text is to be displayed. The valid sides are \f(CWleft\fR, \f(CWright\fR, \f(CWtop\fR, and \f(CWbottom\fR. The default value is \f(CWleft\fR. .TP \fB\-tiers \fInumber\fB Specifies the maximum number of tiers to use to display the tabs. The default value is \f(CW1\fR. .TP \fB\-width \fIpixels\fR Specifies the requested width of the widget. If \fIpixels\fR is 0, then the width of the widget will be calculated based on the size the tabs and their pages. The default is \f(CW0\fR. .SH "TAB OPTIONS" In addition to the \fBconfigure\fR operation, widget configuration options may also be set by the Tk \fBoption\fR command. The class resource name is \f(CWTab\fR. .CS option add *Tabset.Tab.Foreground white option add *Tabset.name.Background blue .CE The following widget options are available: .TP \fB\-activebackground \fIcolor\fR Sets the active background color for \fInameOrIndex\fR. A tab is active when the mouse is positioned over it or set by the \fBactivate\fR operation. This overrides the widget's \fB-activebackground\fR option. .TP \fB\-activeforeground \fIcolor\fR Sets the default active foreground color \fInameOrIndex\fR. A tab is "active" when the mouse is positioned over it or set by the \fBactivate\fR operation. Individual tabs may override this option by setting the tab's \fB-activeforeground\fR option. .TP \fB\-anchor \fIanchor\fR Anchors the tab's embedded widget to a particular edge of the folder. This option has effect only if the space in the folder surrounding the embedded widget is larger than the widget itself. \fIAnchor\fR specifies how the widget will be positioned in the extra space. For example, if \fIanchor\fR is \f(CWcenter\fR then the window is centered in the folder ; if \fIanchor\fR is \f(CWw\fR then the window will be aligned with the leftmost edge of the folder. The default value is \f(CWcenter\fR. .TP \fB\-background \fIcolor\fR Sets the background color for \fInameOrIndex\fR. Setting this option overides the widget's \fB\-tabbackground\fR option. .TP \fB\-bindtags \fItagList\fR Specifies the binding tags for this tab. \fITagList\fR is a list of binding tag names. The tags and their order will determine how commands for events in tabs are invoked. Each tag in the list matching the event sequence will have its Tcl command executed. Implicitly the name of the tab is always the first tag in the list. The default value is \f(CWall\fR. .TP \fB\-command \fIstring\fR Specifies a Tcl script to be associated with \fInameOrIndex\fR. This command is typically invoked when left mouse button is released over the tab. Setting this option overrides the widget's \fB\-selectcommand\fR option. .TP \fB\-data \fIstring\fR Specifies a string to be associated with \fInameOrIndex\fR. This value isn't used in the widget code. It may be used in Tcl bindings to associate extra data (other than the image or text) with the tab. The default value is \f(CW""\fR. .TP \fB\-fill \fIfill\fR If the space in the folder surrounding the tab's embedded widget is larger than the widget, then \fIfill\fR indicates if the embedded widget should be stretched to occupy the extra space. \fIFill\fR is either \f(CWnone\fR, \f(CWx\fR, \f(CWy\fR, \f(CWboth\fR. For example, if \fIfill\fR is \f(CWx\fR, then the widget is stretched horizontally. If \fIfill\fR is \f(CWy\fR, the widget is stretched vertically. The default is \f(CWnone\fR. .TP \fB\-font \fIfontName\fR Sets the font for the text in tab labels. If \fIfontName\fR is not the empty string, this overrides the tabset's \fB\-font\fR option. The default value is \f(CW""\fR. .TP \fB\-foreground \fIcolor\fR Sets the color of the label for \fInameOrIndex\fR. If \fIcolor\fR is not the empty string, this overrides the widget's \fB\-tabforeground\fR option. The default value is \f(CW""\fR. .TP \fB\-image \fIimageName\fR Specifies the image to be drawn in label for \fInameOrIndex\fR. If \fIimage\fR is \f(CW""\fR, no image will be drawn. Both text and images may be displayed at the same time in tab labels. The default value is \f(CW""\fR. .TP \fB\-ipadx \fIpad\fR Sets the padding to the left and right of the label. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the label is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-ipady \fIpad\fR Sets the padding to the top and bottom of the label. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the label is padded by the first distance and the bottom by the second. If \fIpad\fR has just one distance, both the top and bottom sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-padx \fIpad\fR Sets the padding around the left and right of the embedded widget, if one exists. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the left side of the widget is padded by the first distance and the right side by the second. If \fIpad\fR has just one distance, both the left and right sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-pady \fIpad\fR Sets the padding around the top and bottom of the embedded widget, if one exists. \fIPad\fR can be a list of one or two screen distances. If \fIpad\fR has two elements, the top of the widget is padded by the first distance and the bottom by the second. If \fIpad\fR has just one distance, both the top and bottom sides are padded evenly. The default value is \f(CW0\fR. .TP \fB\-selectbackground \fIcolor\fR Sets the color to use when displaying background of the selected tab. If \fIcolor\fR is not the empty string, this overrides the widget's \fB\-selectbackground\fR option. The default value is \f(CW""\fR. .TP \fB\-shadow \fIcolor\fR Sets the shadow color for the text in the tab's label. Drop shadows are useful when both the foreground and background of the tab have similar color intensities. If \fIcolor\fR is the empty string, no shadow is drawn. The default value is \f(CW""\fR. .TP \fB\-state \fIstate\fR Sets the state of the tab. If \fIstate\fR is \f(CWdisable\fR the text of the tab is drawn as engraved and operations on the tab (such as \fBinvoke\fR and \fBtab tearoff\fR) are ignored. The default is \f(CWnormal\fR. .TP \fB\-stipple \fIbitmap\fR Specifies a stipple pattern to use for the background of the folder when the window is torn off. \fIBitmap\fR specifies a bitmap to use as the stipple pattern. The default is \f(CWBLT\fR. .TP \fB\-text \fItext\fR Specifies the text of the tab's label. The exact way the text is drawn may be affected by other options such as \fB\-state\fR or \fB\-rotate\fR. .TP \fB\-window \fIpathName\fR Specifies the widget to be embedded into the tab. \fIPathName\fR must be a child of the \fBtabset\fR widget. The tabset will "pack" and manage the size and placement of \fIpathName\fR. The default value is \f(CW""\fR. .TP \fB\-windowheight \fIpixels\fR Sets the requested height of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum height of all embedded tab windows is used. The default is \f(CW0\fR. .TP \fB\-windowwidth \fIpixels\fR Sets the requested width of the page. The page is the area under the tab used to display the page contents. If \fIpixels\fR is \f(CW0\fR, the maximum width of all embedded tab windows is used. The default is \f(CW0\fR. .SH "DEFAULT BINDINGS" .PP BLT automatically generates class bindings that supply tabsets their default behaviors. The following event sequences are set by default for tabsets (via the class bind tag \f(CWTabset\fR): .IP \fB<ButtonPress-2>\fR .IP \fB<B2-Motion>\fR .IP \fB<ButtonRelease-2>\fR Mouse button 2 may be used for scanning. If it is pressed and dragged over the tabset, the contents of the tabset drag at high speed in the direction the mouse moves. .IP \fB<KeyPress-Up>\fR .IP \fB<KeyPress-Down>\fR The up and down arrow keys move the focus to the tab immediately above or below the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. .IP \fB<KeyPress-Left>\fR .IP \fB<KeyPress-Right>\fR The left and right arrow keys move the focus to the tab immediately to the left or right of the current focus tab. The tab with focus is drawn with the a dashed outline around the tab label. .IP \fB<KeyPress-space>\fR .IP \fB<KeyPress-Return>\fR The space and return keys select the current tab given focus. When a folder is selected, it's command is invoked and the embedded widget is mapped. .PP Each tab, by default, also has a set of bindings (via the tag \f(CWall\fR). These bindings may be reset using the tabset's \fBbind\fR operation. .IP \fB<Enter>\fR .IP \fB<Leave>\fR When the mouse pointer enters a tab, it is activated (i.e. drawn in its active colors) and when the pointer leaves, it is redrawn in its normal colors. .IP \fB<ButtonRelease-1>\fR Clicking with the left mouse button on a tab causes the tab to be selected and its Tcl script (see the \fB\-command\fR or \fB\-selectcommand\fR options) to be invoked. The folder and any embedded widget (if one is specified) is automatically mapped. .IP \fB<ButtonRelease-3>\fR .IP \fB<Control-ButtonRelease-1>\fR Clicking on the right mouse button (or the left mouse button with the Control key held down) tears off the current page into its own toplevel widget. The embedded widget is re-packed into a new toplevel and an outline of the widget is drawn in the folder. Clicking again (toggling) will reverse this operation and replace the page back in the folder. .SH "BIND TAGS" You can bind commands to tabs that are triggered when a particular event sequence occurs in them, much like canvas items in Tk's canvas widget. Not all event sequences are valid. The only binding events that may be specified are those related to the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR). .PP It is possible for multiple bindings to match a particular event. This could occur, for example, if one binding is associated with the tab name and another is associated with the tab's tags (see the \fB\-bindtags\fR option). When this occurs, all the matching bindings are invoked. A binding associated with the tab name is invoked first, followed by one binding for each of the tab's bindtags. If there are multiple matching bindings for a single tag, then only the most specific binding is invoked. A continue command in a binding script terminates that script, and a break command terminates that script and skips any remaining scripts for the event, just as for the bind command. .PP The \fB\-bindtags\fR option for tabs controls addition tag names that can be matched. Implicitly the first tag for each tab is its name. Setting the value of the \fB\-bindtags\fR option doesn't change this. .SH EXAMPLE You create a tabset widget with the \fBtabset\fR command. .CS # Create a new tabset tabset .ts -relief sunken -borderwidth 2 .CE A new Tcl command \f(CW.ts\fR is also created. This command can be used to query and modify the tabset. For example, to change the default font used by all the tab labels, you use the new command and the tabset's \fBconfigure\fR operation. .CS # Change the default font. \&.ts configure \-font "fixed" .CE You can then add folders using the \fBinsert\fR operation. .CS # Create a new folder "f1" \&.ts insert 0 "f1" .CE This inserts the new tab named "f1" into the tabset. The index \f(CW0\fR indicates location to insert the new tab. You can also use the index \f(CWend\fR to append a tab to the end of the tabset. By default, the text of the tab is the name of the tab. You can change this by configuring the \fB\-text\fR option. .CS # Change the label of "f1" \&.ts tab configure "f1" -text "Tab #1" .CE The \fBinsert\fR operation lets you add one or more folders at a time. .CS \&.ts insert end "f2" -text "Tab #2" "f3" "f4" .CE The tab on each folder contains a label. A label may display both an image and a text string. You can reconfigure the tab's attributes (foreground/background colors, font, rotation, etc) using the \fBtab configure\fR operation. .CS # Add an image to the label of "f1" set image [image create photo -file stopsign.gif] \&.ts tab configure "f1" -image $image \&.ts tab configure "f2" -rotate 90 .CE Each folder may contain an embedded widget to represent its contents. The widget to be embedded must be a child of the tabset widget. Using the \fB\-window\fR option, you specify the name of widget to be embedded. But don't pack the widget, the tabset takes care of placing and arranging the widget for you. .CS graph .ts.graph \&.ts tab configure "f1" -window ".ts.graph" \\ -fill both -padx 0.25i -pady 0.25i .CE The size of the folder is determined the sizes of the Tk widgets embedded inside each folder. The folder will be as wide as the widest widget in any folder. The tallest determines the height. You can use the tab's \fB\-pagewidth\fR and \fB\-pageheight\fR options override this. .PP Other options control how the widget appears in the folder. The \fB\-fill\fR option says that you wish to have the widget stretch to fill the available space in the folder. .CS \&.ts tab configure "f1" -fill both -padx 0.25i -pady 0.25i .CE .PP Now when you click the left mouse button on "f1", the graph will be displayed in the folder. It will be automatically hidden when another folder is selected. If you click on the right mouse button, the embedded widget will be moved into a toplevel widget of its own. Clicking again on the right mouse button puts it back into the folder. .PP If you want to share a page between two different folders, the \fB\-command\fR option lets you specify a Tcl command to be invoked whenever the folder is selected. You can reset the \fB\-window\fR option for the tab whenever it's clicked. .CS \&.ts tab configure "f2" -command { \&.ts tab configure "f2" -window ".ts.graph" } \&.ts tab configure "f1" -command { \&.ts tab configure "f1" -window ".ts.graph" } .CE If you have many folders, you may wish to stack tabs in multiple tiers. The tabset's \fB\-tiers\fR option requests a maximum number of tiers. The default is one tier. .CS \&.ts configure -tiers 2 .CE If the tabs can fit in less tiers, the widget will use that many. Whenever there are more tabs than can be displayed in the maximum number of tiers, the tabset will automatically let you scroll the tabs. You can even attach a scrollbar to the tabset. .CS \&.ts configure -scrollcommand { .sbar set } -scrollincrement 20 \&.sbar configure -orient horizontal -command { .ts view } .CE By default tabs are along the top of the tabset from left to right. But tabs can be placed on any side of the tabset using the \fB\-side\fR option. .CS # Arrange tabs along the right side of the tabset. \&.ts configure -side right -rotate 270 .CE .SH KEYWORDS tabset, widget ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/examples/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014050� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/examples/calendar.tcl�������������������������������������������������������������0000755�0001750�0001750�00000010013�11462120062�016327� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tile::* } #source scripts/demo.tcl set file ../demos/images/chalk.gif set active ../demos/images/rain.gif image create photo calendar.texture.1 -file $file image create photo calendar.texture.2 -file $active option add *Tile calendar.texture.1 option add *HighlightThickness 0 option add *calendar.weekframe*Tile calendar.texture.2 option add *Calendar.Label.borderWidth 0 option add *Calendar.Label.relief sunken option add *Calendar.Frame.borderWidth 2 option add *Calendar.Frame.relief raised option add *Calendar.Label.font { Helvetica 11 } option add *Calendar.Label.foreground navyblue option add *button.foreground navyblue option add *background grey85 #option add *button.activeForeground red #option add *button.activeBackground blue4 option add *Label.ipadX 200 array set monthInfo { Jan { January 31 } Feb { February 28 } Mar { March 31 } Apr { April 30 } May { May 31 } Jun { June 30 } Jul { July 31 } Aug { August 31 } Sep { September 30 } Oct { October 31 } Nov { November 30 } Dec { December 31 } } option add *tile calendar.texture.2 set abbrDays { Sun Mon Tue Wed Thu Fri Sat } proc Calendar { weekday day month year } { global monthInfo abbrDays set wkdayOffset [lsearch $abbrDays $weekday] if { $wkdayOffset < 0 } { error "Invalid week day \"$weekday\"" } set dayOffset [expr ($day-1)%7] if { $wkdayOffset < $dayOffset } { set wkdayOffset [expr $wkdayOffset+7] } set wkday [expr $wkdayOffset-$dayOffset-1] if { [info commands .calendar] == ".calendar" } { destroy .calendar } frame .calendar -class Calendar -width 3i -height 3i if ![info exists monthInfo($month)] { error "Invalid month \"$month\"" } set info $monthInfo($month) label .calendar.month \ -text "[lindex $info 0] $year" \ -font { Courier 14 bold } table .calendar .calendar.month 1,0 -cspan 7 -pady 10 set cnt 0 frame .calendar.weekframe -relief sunken -bd 1 table .calendar .calendar.weekframe 2,0 -columnspan 7 -fill both foreach dayName $abbrDays { set name [string tolower $dayName] label .calendar.$name \ -text $dayName \ -font { Helvetica 12 } table .calendar .calendar.$name 2,$cnt -pady 2 -padx 2 incr cnt } table configure .calendar c* r2 -pad 4 set week 0 set numDays [lindex $info 1] for { set cnt 1 } { $cnt <= $numDays } { incr cnt } { label .calendar.day${cnt} -text $cnt if { $cnt == $day } { .calendar.day${cnt} configure -relief sunken -bd 1 } incr wkday if { $wkday == 7 } { incr week set wkday 0 } table .calendar .calendar.day${cnt} $week+3,$wkday \ -fill both -ipadx 10 -ipady 4 } frame .calendar.quit -bd 1 -relief sunken button .calendar.quit.button -command { exit } -text {Quit} -bd 2 table .calendar.quit \ .calendar.quit.button -padx 4 -pady 4 table .calendar \ .calendar.quit $week+4,5 -cspan 2 -pady 4 table . \ .calendar -fill both table configure .calendar r0 -resize none table configure .calendar c0 c6 } set date [clock format [clock seconds] -format {%a %b %d %Y}] scan $date { %s %s %d %d } weekday month day year Calendar $weekday $day $month $year ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/examples/pareto.tcl���������������������������������������������������������������0000755�0001750�0001750�00000007156�11462120062�016066� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- # Example of a pareto chart. # # The pareto chart mixes line and bar elements in the same graph. # Each processing operating is represented by a bar element. The # total accumulated defects is displayed with a single line element. blt::barchart .b \ -title "Defects Found During Inspection" \ -font {{Sans Serif} 12 Bold} \ -width 6i \ -height 5i \ -bg white \ -plotborderwidth 1 \ -plotrelief solid blt::table . .b -fill both set data { "Spot Weld" 82 yellow "Lathe" 49 orange "Gear Cut" 38 green "Drill" 24 blue "Grind" 17 red "Lapping" 12 brown "Press" 8 purple "De-burr" 4 pink "Packaging" 3 cyan "Other" 12 magenta } # Create an X-Y graph line element to trace the accumulated defects. .b line create accum -label "" -symbol none -color red # Define a bitmap to be used to stipple the background of each bar. blt::bitmap define pattern1 { {4 4} {01 02 04 08} } # For each process, create a bar element to display the magnitude. set count 0 set sum 0 set ydata 0 set xdata 0 set bg [blt::bgpattern create solid -color orange -opacity 70] set areabg [blt::bgpattern create solid -color blue -opacity 20] foreach { label value color } $data { incr count .b element create $label \ -xdata $count \ -ydata $value \ -fg $color \ -relief raised \ -borderwidth 1 \ -bg $bg set labels($count) $label # Get the total number of defects. set sum [expr $value + $sum] lappend ydata $sum lappend xdata $count } # Configure the coordinates of the accumulated defects, # now that we know what they are. .b line configure accum -xdata $xdata -ydata $ydata \ -areabackground $areabg .b element lower accum # Add text markers to label the percentage of total at each point. foreach x $xdata y $ydata { set percent [expr ($y * 100.0) / $sum] if { $x == 0 } { set text " 0%" } else { set text [format %.1f $percent] } .b marker create text \ -coords "$x $y" \ -text $text \ -font {Math 9} \ -fg red4 \ -anchor c \ -yoffset -5 } # Display an auxillary y-axis for percentages. .b axis configure y2 \ -hide no \ -min 0.0 \ -max 100.0 \ -tickinterior yes \ -title "Percentage" -grid no # Title the y-axis .b axis configure y -title "Defects" -grid no \ -tickinterior yes \ # Configure the x-axis to display the process names, instead of numbers. .b axis configure x \ -title "Process" \ -command FormatLabels \ -rotate 290 \ -tickanchor nw \ -tickfont {{Sans Serif} 9} \ -tickinterior yes \ -ticklength 5 \ -subdivisions 0 proc FormatLabels { widget value } { global labels set value [expr round($value)] if {[info exists labels($value)] } { return $labels($value) } return "" } # No legend needed. .b legend configure -hide yes # Configure the grid lines. .b axis configure x -gridcolor lightblue -grid yes ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/examples/form.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000107775�11462120062�015547� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- #source scripts/demo.tcl option add *takeFocus 0 set file1 ../demos/images/chalk.gif #set file1 /home/gah/titanium.jpg set file2 ../demos/images/tan_paper.gif image create picture texture1 -file $file1 image create photo texture2 -file $file2 option add *Frame.Tile texture1 option add *Toplevel.Tile texture1 option add *Label.Tile texture1 #option add *Scrollbar.tile texture1 #option add *Scrollbar.activeTile texture2 #option add *Button.tile texture1 #option add *Button.activeTile texture2 option add *HighlightThickness 0 option add *Entry.highlightThickness 2 # # Initialization of global variables and Tk resource database # # # Resources available # # Tk.normalBgColor: # Tk.normalFgColor: # Tk.focusHighlightColor: # Tk.statusFont: # Tk.titleFont: # Tk.headingFont: # Tk.subheadingFont: # Tk.entryFont: # Tk.textFont: # #debug 50 blt::bitmap define attlogo { { 60 30 } { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x83, 0xf9, 0x87, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf9, 0x87, 0x7f, 0x00, 0x40, 0x00, 0xf0, 0xc7, 0xc3, 0x38, 0x0c, 0x00, 0xc0, 0xff, 0xff, 0xc7, 0xc3, 0x7c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc2, 0x6c, 0x0c, 0x00, 0x40, 0x00, 0xf8, 0x67, 0xc6, 0x9c, 0x0d, 0x00, 0xc0, 0xff, 0xff, 0xe7, 0xc7, 0xf8, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc7, 0xec, 0x0c, 0x00, 0x80, 0x01, 0xfe, 0x33, 0xcc, 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x33, 0xcc, 0xb8, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } blt::bitmap define globe_00 { { 32 32 } { 00 40 02 00 00 1c 3c 00 00 01 fe 00 80 80 fe 03 60 00 ff 07 10 c0 f1 0f 00 80 c0 1f 00 c0 07 3f 00 c0 ff 3f 00 f0 ff 4f 02 f0 ff 5d 00 f0 ff 1b 00 f0 ff 8f 02 f0 ff 0f 06 e0 fc 0f 0e 00 f8 0f 0f 00 f8 07 3f 00 f8 03 7e 00 f0 03 7e 00 f0 03 3e 00 f0 0b 3c 00 f0 09 3c 00 f0 01 18 00 f0 00 18 00 70 00 10 00 00 00 10 00 00 00 20 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 1f 00 } } blt::bitmap define globe_01 { { 32 32 } { 00 c0 00 00 00 34 38 00 00 02 e8 00 80 01 fa 03 e0 00 fc 07 30 00 e6 0f 10 00 86 1f 08 00 3e 3c 04 00 ff 3f 04 80 ff 5f 02 80 ff 3f 00 80 ff 2f 00 80 ff 3f 0c 00 ff 3f 1c 00 ee 3f 3c 00 c0 3f 7e 00 c0 1f fe 01 80 1f fc 03 80 1f fc 01 80 1f fc 01 80 2f f8 01 80 0f f0 00 80 17 f0 00 80 03 f0 00 80 03 60 00 00 00 60 00 00 00 40 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 1e 00 } } blt::bitmap define globe_02 { { 32 32 } { 00 c0 01 00 00 60 30 00 00 04 f0 00 80 07 e0 03 e0 01 f0 07 f0 00 38 0f 30 00 10 1e 18 00 f0 30 04 00 f8 3f 10 00 f8 7f 12 00 fc 7f 02 00 fc 7f 04 00 fc 7f 74 00 f8 7f f0 00 70 7f f8 01 00 7e f8 03 00 7e f8 0f 00 7c f8 1f 00 3c f0 1f 00 3c f0 0f 00 3e e0 0f 00 5e c0 07 00 1c c0 03 00 0e c0 03 00 04 80 01 00 00 80 01 00 00 80 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 10 1c 00 } } blt::bitmap define globe_03 { { 32 32 } { 00 c0 01 00 00 dc 20 00 00 09 c0 00 80 1f a0 03 e0 07 c0 07 f0 01 c0 0c f8 00 40 18 78 00 c0 23 08 00 c0 3f 04 00 e0 7f 54 00 e0 7f 0c 00 c0 7f 10 00 c0 ff d0 01 c0 ff c0 03 80 fb e0 0f 00 f0 e0 1f 00 f0 e0 ff 00 f0 e0 ff 00 70 c0 ff 00 70 c0 7f 00 70 00 7f 00 70 00 3f 00 30 00 1f 00 38 00 1f 00 18 00 0e 00 00 00 06 00 00 00 02 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 20 18 00 } } blt::bitmap define globe_04 { { 32 32 } { 00 c0 03 00 00 7c 03 00 00 13 00 00 80 7f c0 03 c0 1f 00 07 e0 0f 00 0d f0 03 00 10 f0 01 00 0e 38 01 00 3e 10 00 00 7f 50 00 00 7f 30 00 00 7f 40 00 00 ff 00 1e 00 fe 00 3f 00 ec 00 7f 00 c0 00 ff 00 c0 00 ff 07 c0 00 ff 0f c0 00 fe 07 c0 00 fe 07 c0 00 f8 03 40 00 f8 01 60 00 f8 00 20 00 f8 00 20 00 38 00 00 00 18 00 00 00 18 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 40 10 00 } } blt::bitmap define globe_05 { { 32 32 } { 00 c0 03 00 00 bc 06 00 00 cf 00 00 80 ff 01 02 c0 7f 00 06 c0 3f 00 0e e0 1f 00 14 e0 0f 00 18 e0 00 00 38 60 00 00 78 40 08 00 78 c0 01 00 78 00 02 00 f8 00 f0 00 f0 00 f0 01 b0 00 f8 07 80 00 f8 0f 80 00 f8 3f 00 00 f8 7f 00 00 f0 3f 80 00 f0 3f 80 00 c0 1f 00 00 c0 0f 00 00 c0 07 40 00 c0 07 00 00 c0 01 00 00 e0 00 00 00 60 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 80 10 00 } } blt::bitmap define globe_06 { { 32 32 } { 00 80 07 00 00 7c 0d 00 00 9f 03 00 00 ff 07 02 00 ff 03 04 80 ff 00 08 c0 7f 00 00 80 3f 00 30 80 07 00 20 00 03 00 60 00 03 00 60 00 0e 00 60 00 10 00 e0 00 80 07 c0 00 80 0f c0 00 80 3f 00 00 c0 7f 00 00 c0 ff 01 00 c0 ff 03 00 80 ff 01 00 80 ff 01 00 00 fe 00 00 00 7e 00 00 00 3e 00 00 00 1f 00 00 00 0f 00 00 00 03 00 00 00 03 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 } } blt::bitmap define globe_07 { { 32 32 } { 00 80 07 00 00 fc 1a 00 00 7d 02 00 00 fe 1f 00 00 fe 0f 00 00 fe 07 00 00 ff 03 00 00 fe 01 20 00 1c 01 00 00 1c 00 40 00 18 00 40 00 70 00 00 00 80 00 80 00 00 39 80 00 00 7c 00 00 00 fc 01 00 00 fe 03 00 00 fe 0f 00 00 fc 0f 00 00 fc 0f 00 00 f8 07 00 00 f0 07 00 00 f0 03 00 00 f0 01 00 00 f8 00 00 00 38 00 00 00 18 00 00 00 0c 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 02 00 } } blt::bitmap define globe_08 { { 32 32 } { 00 00 07 00 00 fc 25 00 00 f8 19 00 00 f8 7f 00 00 f8 3f 00 00 f8 1f 00 00 f8 1f 00 00 f8 0f 00 00 f0 08 00 00 f0 00 00 00 c0 04 00 00 80 03 00 00 00 0c 00 00 00 c8 01 00 00 e0 03 00 00 e0 0f 00 00 e0 0f 00 00 f0 3f 00 00 e0 3f 00 00 e0 3f 00 00 c0 1f 00 00 80 1f 00 00 80 0f 00 00 c0 07 00 00 c0 03 00 00 c0 01 00 00 60 00 00 00 30 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 04 00 } } blt::bitmap define globe_09 { { 32 32 } { 00 00 03 00 00 fc 27 00 00 f0 13 00 00 e0 ff 00 00 e0 ff 01 00 e0 7f 00 00 e0 7f 00 00 c0 7f 00 00 80 47 00 00 80 07 00 00 00 26 00 00 00 1c 00 00 00 60 00 00 00 40 0e 00 00 00 1f 00 00 00 3f 00 00 00 3f 00 00 00 7f 00 00 00 7f 00 00 00 7f 00 00 00 7e 00 00 00 3c 00 00 00 3e 00 00 00 1e 00 00 00 0f 00 00 00 07 00 00 80 01 00 00 80 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 08 00 } } blt::bitmap define globe_10 { { 32 32 } { 00 00 06 00 00 f4 2f 00 00 c8 4f 00 00 80 ff 01 00 80 ff 01 00 80 ff 01 00 00 ff 01 00 00 fe 01 00 00 3c 00 00 00 3c 00 00 00 30 04 00 00 e0 00 00 00 00 01 00 00 00 3a 00 00 00 38 00 00 00 78 00 00 00 f8 00 00 00 fc 00 00 00 f8 00 00 00 f8 00 00 00 f8 00 00 00 70 00 00 00 70 00 00 00 38 00 00 00 18 00 00 00 0c 00 00 00 06 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 } } blt::bitmap define globe_11 { { 32 32 } { 00 00 06 00 00 ec 1f 00 00 91 9f 00 00 00 fe 03 00 00 fc 07 00 00 fc 07 00 00 fc 07 00 00 f0 07 00 00 f0 01 00 00 e0 00 00 00 80 05 00 00 00 07 00 00 00 08 00 00 00 60 00 00 00 e0 00 00 00 e0 00 00 00 e0 00 00 00 e0 01 00 00 e0 00 00 00 e0 00 00 00 e0 00 00 00 40 00 00 00 60 00 00 00 60 00 00 00 30 00 00 00 10 40 00 00 08 40 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 } } blt::bitmap define globe_12 { { 32 32 } { 00 00 04 00 00 dc 3f 00 00 42 7e 00 00 00 f8 03 20 00 f0 07 10 00 f0 0f 00 00 e0 0f 00 00 c0 0f 00 00 00 07 00 00 00 06 00 00 00 14 00 00 00 18 00 00 00 20 00 00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 01 00 00 80 00 00 00 80 00 00 00 80 02 00 00 80 02 00 00 00 04 00 00 40 04 00 00 40 08 00 00 20 08 00 00 00 00 00 00 10 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 } } blt::bitmap define globe_13 { { 32 32 } { 00 00 04 00 00 bc 3f 00 00 01 79 00 80 00 e0 03 60 00 c0 07 10 00 80 0f 00 00 80 1f 08 00 00 1e 00 00 00 1c 00 00 00 58 00 00 00 10 00 00 00 20 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 06 00 00 00 04 00 00 00 00 00 00 00 02 00 00 00 0e 00 00 00 0c 00 00 00 1c 00 00 00 18 00 00 00 30 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 } } blt::bitmap define globe_14 { { 32 32 } { 00 00 00 00 00 fc 3f 00 00 03 e6 00 80 01 c0 03 60 00 00 07 30 00 00 0f 00 00 00 1e 00 00 00 38 04 00 00 30 00 00 00 30 02 00 00 00 00 00 00 40 00 00 00 80 00 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 3c 00 00 00 3c 00 00 00 7c 00 00 00 78 00 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 } } blt::bitmap define globe_15 { { 32 32 } { 00 00 00 00 00 fc 3d 00 00 27 c8 00 80 13 00 03 e0 01 00 06 70 00 00 0c 10 00 00 18 18 00 00 30 0c 00 00 20 0c 00 00 40 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 13 00 00 00 64 00 00 00 c0 00 00 00 00 00 00 00 30 00 00 00 f8 00 00 00 f8 01 00 00 f8 03 00 00 f0 03 00 00 80 03 00 00 00 80 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 00 00 } } blt::bitmap define globe_16 { { 32 32 } { 00 00 00 00 00 fc 3b 00 00 9f a0 00 80 4f 00 02 e0 0f 00 04 f0 01 00 08 70 00 00 10 38 00 00 20 3c 00 00 00 1c 00 00 00 06 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 20 00 00 00 0a 00 00 00 0a 00 00 00 00 03 00 00 28 06 00 00 00 00 00 00 c0 02 00 00 e0 07 00 00 f0 0f 00 00 e0 1f 00 00 e0 1f 00 00 00 0c 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 00 00 } } blt::bitmap define globe_17 { { 32 32 } { 00 00 00 00 00 fc 37 00 00 3f 42 00 80 3f 01 02 e0 1f 00 00 f0 07 00 00 f0 11 00 00 f8 04 00 00 fc 00 00 00 7c 00 00 00 1a 00 00 00 9a 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 28 00 00 00 08 18 00 00 00 30 00 00 00 10 00 00 00 17 00 00 00 3f 00 00 c0 7f 00 00 80 7f 00 00 80 7f 00 00 00 70 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 01 00 } } blt::bitmap define globe_18 { { 32 32 } { 00 00 00 00 00 fc 2f 00 00 ff 84 00 80 ff 04 00 e0 7f 00 00 f0 9f 00 00 f0 97 00 00 f8 27 00 00 fc 07 00 00 fc 03 00 00 6c 00 00 00 64 00 00 00 60 04 00 00 40 00 00 00 20 00 00 00 20 01 00 00 a0 01 00 00 00 c0 05 00 00 88 00 00 00 00 00 00 00 38 01 00 00 fc 01 00 00 fe 03 00 00 fe 03 00 00 fc 03 00 00 80 03 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 03 00 } } blt::bitmap define globe_19 { { 32 32 } { 00 40 00 00 00 fc 3f 00 00 ff 13 00 80 ff 13 00 e0 ff 03 00 f0 ff 00 00 f0 9f 00 00 f8 3f 00 00 fc 3f 00 00 f8 1f 00 00 ba 07 00 00 98 23 00 00 08 03 00 00 08 00 00 00 00 00 00 00 80 09 00 00 00 0d 01 00 00 21 0e 00 00 00 1c 00 00 00 00 00 00 c0 09 00 00 e0 0f 00 00 f0 1f 00 00 f0 1f 00 00 f0 1f 00 00 00 0e 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 07 00 } } blt::bitmap define globe_20 { { 32 32 } { 00 00 00 00 00 fc 3f 00 00 ff 07 00 80 ff 0f 00 e0 ff 0f 00 f0 ff 13 00 f0 ff 10 00 f8 ff 00 00 fc ff 01 00 f4 ff 00 00 e6 1e 00 00 62 1c 01 00 20 18 00 00 20 10 00 00 01 80 00 00 01 cc 00 00 01 68 08 00 00 00 60 00 00 00 c0 00 00 00 00 00 00 00 5c 00 00 00 7e 00 00 80 ff 00 00 80 ff 00 00 80 ff 00 00 00 70 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 0f 00 } } blt::bitmap define globe_21 { { 32 32 } { 00 80 00 00 00 fc 3f 00 00 ff 1f 00 80 ff bf 00 e0 ff 3f 00 f0 ff 1f 00 f8 ff 17 00 f8 ff 27 00 ec ff 0f 00 8c ff 07 00 9e f7 00 00 0e e3 00 00 06 c1 00 00 06 81 10 00 03 40 04 00 03 20 06 00 03 40 06 00 01 80 00 03 01 00 00 02 02 00 00 00 02 00 e0 02 02 00 f0 03 00 00 fc 03 00 00 fc 03 00 00 fc 03 00 00 c0 01 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_22 { { 32 32 } { 00 00 01 00 00 fc 3f 00 00 ff 3f 00 80 ff 7f 00 e0 ff ff 00 f0 ff 7f 00 f0 ff 1f 00 e0 ff 3f 00 fc ff 3f 00 34 fe 3f 00 76 bc 07 00 36 1c 07 00 0e 08 0e 00 1e 08 80 00 0f 00 02 00 0f 00 20 00 07 00 36 00 07 00 04 08 07 00 00 18 06 00 00 00 16 00 00 0b 16 00 80 0f 04 00 e0 0f 04 00 e0 0f 08 00 e0 0f 00 00 00 06 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_23 { { 32 32 } { 00 00 00 00 00 fc 3f 00 00 ff 7f 00 80 ff ff 01 e0 ff ff 01 e0 ff ff 01 e8 ff ff 00 c0 ff ff 00 fc fe ff 01 dc f2 ff 01 de e3 3d 00 de e1 38 02 7e 40 70 00 fe 40 00 04 7f 00 00 00 3e 00 30 01 3e 00 a0 01 1e 00 20 20 1e 00 00 20 1c 00 00 00 9c 00 00 3c 1c 00 00 3e 1c 00 00 3f 18 00 80 3f 10 00 00 1f 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_24 { { 32 32 } { 00 00 02 00 00 fc 3f 00 00 fe ff 00 80 ff ff 01 c0 ff ff 03 80 ff ff 03 e0 ff ff 03 18 ff ff 03 fc ff ff 07 7c 87 ff 07 fe 1f ef 01 fe 0e c6 01 fe 01 82 03 fe 03 02 00 ff 03 00 08 fc 01 80 09 fc 00 00 0d fc 00 00 00 f8 00 00 80 f8 00 00 00 f8 00 00 20 78 02 00 70 70 02 00 7c 70 00 00 3c 60 00 00 3c 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_25 { { 32 32 } { 00 00 00 00 00 f0 3f 00 00 fc ff 00 80 ff ff 03 80 ff ff 07 a0 ff ff 07 10 ff ff 07 30 f8 ff 0f f8 df ff 1f fc 3b fc 1f fc fb 78 07 fe 77 30 0e fe 1f 30 0c fe 3f 00 48 fe 1f 00 00 f0 0f 00 24 f0 07 00 a0 f0 07 00 08 e0 07 00 00 e0 07 00 00 e0 27 00 c0 e0 13 00 40 c0 13 00 70 c0 03 00 70 80 01 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_26 { { 32 32 } { 00 40 00 00 00 e0 3f 00 00 e8 ff 00 00 fc ff 03 00 ff ff 07 c0 fe ff 0f 40 f0 ff 1f e0 e0 ff 1f f0 ff fe 3f f8 df e1 3f f8 df c7 1b fc bf 83 19 fc ff 80 30 fc ff 01 20 f8 ff 00 00 c0 ff 00 00 c0 7f 00 e0 80 3f 00 20 80 3f 00 00 80 3f 00 00 80 3f 01 80 80 9f 00 00 00 9f 00 40 00 0f 00 60 00 0e 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 1f 00 } } blt::bitmap define globe_27 { { 32 32 } { 00 80 00 00 00 c4 3f 00 00 f0 ff 00 00 fe ff 03 00 fe ff 07 00 eb ff 0f 80 c9 ff 1f 80 07 ff 3f c0 ff f7 3f e0 ff 0e 7f f0 ff 3e 6e f0 ff 1d 64 f0 ff 07 44 f0 ff 0f 00 60 ff 0f 00 00 fe 07 40 00 fe 03 00 01 fc 01 00 01 fc 01 00 00 fc 01 00 00 fc 09 00 02 fc 08 00 00 f8 04 00 00 78 00 40 00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 1f 00 } } blt::bitmap define globe_28 { { 32 32 } { 00 00 00 00 00 88 3f 00 00 40 ff 00 00 e8 ff 03 00 f8 ff 07 00 8c ff 0f 00 06 fe 1f 00 1e f8 3f 00 ff bf 3f 80 ff 77 7c 80 ff ff 79 c0 ff ef 10 c0 ff 3f 90 c0 ff 7f 00 81 fb 7f 00 01 f0 3f 00 01 f0 1f 00 03 e0 1f 00 07 e0 0f 00 02 c0 1f 00 02 e0 5f 00 06 e0 47 00 04 c0 27 00 04 c0 03 00 00 80 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 1f 00 } } blt::bitmap define globe_29 { { 32 32 } { 00 40 01 00 00 0c 3f 00 00 80 fd 00 00 a0 ff 03 20 e0 ff 07 00 30 fd 0f 00 10 f4 1f 00 f8 c0 3f 00 f8 ff 3f 00 fc bf 73 00 fe ff 67 00 fe 7f 47 00 fe ff 41 00 fe ff 03 01 dc ff 03 03 00 ff 01 07 80 ff 00 0f 00 ff 00 1f 00 7e 00 0e 00 fe 00 0e 00 ff 02 0e 00 3f 01 0c 00 3e 01 0c 00 1e 00 08 00 1c 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 1f 00 } } # ---------------------------------------------------------------- # # SetOption -- # # Sets the option array associated with the resource. It # first check to see if the resource exists in the option # data base, otherwise it uses the default value given. # # # Arguments # name -- Name of the resource. Used as index into # the option array. # value -- default value given. # Globals # pq_dict -- Associative array where the option resources # are stored. # # ---------------------------------------------------------------- proc SetOption { name value } { global pq_dict set widgetOption [option get . $name Tk] if { $widgetOption != "" } { set value $widgetOption } set pq_dict($name) $value } set pq_dict(textIndex) {} set pq_dict(entryNames) { last first middle area exch ext com org tl room oldloc loc street city state zip ema } set pq_dict(numEntries) [llength $pq_dict(entryNames)] set pq_dict(index) 0 set pq_dict(defaults) {} set cnt 0 foreach name $pq_dict(entryNames) { if { $cnt > 0 } { set pq_dict(format) $pq_dict(format):%$name } else { set pq_dict(format) %$name } incr cnt } set visual [winfo screenvisual .] if { ($visual == "staticgray") || ($visual == "grayscale") } { option add *Entry.background white option add *Text.background white set pq_dict(visual) mono } else { set depth [winfo screendepth .] if { $depth < 8 } { SetOption normalBgColor grey SetOption normalFgColor black SetOption focusHighlightColor white } else { #fff4de SetOption normalBgColor grey90 SetOption normalFgColor #da5f5f SetOption normalFgColor black #navyblue SetOption focusHighlightColor #fffdf8 } option add *Entry.background $pq_dict(normalBgColor) widgetDefault option add *Text.background $pq_dict(normalBgColor) widgetDefault option add *Label.foreground $pq_dict(normalFgColor) widgetDefault option add *Button.foreground $pq_dict(normalFgColor) widgetDefault option add *Scrollbar.background $pq_dict(normalBgColor) set pq_dict(visual) color } SetOption statusFont -*-Helvetica-Medium-R-*-*-14-*-*-*-*-*-*-* SetOption titleFont -*-Helvetica-Bold-R-*-*-14-*-*-*-*-*-*-* SetOption headingFont -*-Helvetica-Medium-R-*-*-14-*-*-*-*-*-*-* SetOption subheadingFont -*-Helvetica-Medium-R-*-*-12-*-*-*-*-*-*-* SetOption entryFont -*-Courier-Medium-R-*-*-18-*-*-*-*-*-*-* SetOption textFont -*-Courier-Bold-R-*-*-18-*-*-*-*-*-*-* #SetOption entryFont fixed #SetOption textFont fixed option add *Label.borderWidth 0 widgetDefault option add *Entry.relief sunken widgetDefault option add *Entry.width 11 widgetDefault option add *Entry.borderWidth 2 widgetDefault option add *Entry.font $pq_dict(entryFont) widgetDefault option add *Text.font $pq_dict(textFont) widgetDefault option add *Text.width 35 widgetDefault option add *Text.height 10 widgetDefault option add *Scrollbar.relief flat widgetDefault option add *Scrollbar.minSlider 10 widgetDefault option add *Button.padY 4 option add *Text.relief sunken widgetDefault option add *Text.borderWidth 2 widgetDefault foreach name $pq_dict(entryNames) { option add *${name}_label.font $pq_dict(subheadingFont) widgetDefault } option add *Label.Font $pq_dict(subheadingFont) option add *status_label.font $pq_dict(statusFont) widgetDefault option add *name_label.font $pq_dict(headingFont) widgetDefault option add *tel_label.font $pq_dict(headingFont) widgetDefault option add *office_label.font $pq_dict(headingFont) widgetDefault option add *addr_label.font $pq_dict(headingFont) widgetDefault option add *loc_title.font $pq_dict(headingFont) widgetDefault option add *org_title.font $pq_dict(headingFont) widgetDefault option add *overall_label.text "Customer Database" option add *name_label.text "Name" option add *tel_label.text "Telephone" option add *addr_label.text "Address" option add *last_label.text "last" option add *first_label.text "first" option add *middle_label.text "middle" option add *com_label.text "company" option add *org_label.text "organization" option add *tl_label.text "title" option add *ext_label.text "extension" option add *exch_label.text "exchange" option add *area_label.text "area code" option add *loc_label.text "extension" option add *oldloc_label.text "exchange" option add *room_label.text "area code" option add *street_label.text "street address" option add *ema_label.text "e-mail" option add *city_label.text "city" option add *state_label.text "state" option add *zip_label.text "zip code" option add *org_title.text "Organization" option add *loc_title.text "Fax" option add *clear_button.text "Clear" option add *quit_button.text "Quit" option add *cancel_button.text "Cancel" # -------------------------------------------------------------------------- # # Procedures to perform post queries # # ---------------------------------------------------------------- # # StopQuery -- # # Stops any current "pq" request by setting the variable # associated with the background subprocesses. # # Arguments # None. # # Globals # postOutput -- variable where collected output from # pq command will be stored # # ---------------------------------------------------------------- proc StopQuery {} { global postOutput set postOutput {} } # ---------------------------------------------------------------- # # PostQuery -- # # Collects the data from the entry widget fields and # executes a "pq" request. The "pq" command is executed # in the background and a "wait" is setup to wait for the # command to finish. This allows the animation routine # to operate and exposure events to be handled properly. # # Arguments # None. # # Globals # postOutput -- variable where collected output from # pq command will be stored # pq_dict(entryNames) -- list of entry widget names # pq_dict(textIndex) -- starting index of highlighted information # (a line in the text widget) # # ---------------------------------------------------------------- proc PostQuery {} { global pq_dict .status_label configure -text {} set cnt 0 foreach name $pq_dict(entryNames) { set value [.${name}_entry get] if { $value != "" } { set value [split $value "|"] foreach i $value { if { $cnt > 0 } { set query $query/$name=[list $i] } else { set query $name=[list $i] } incr cnt } } } if { $cnt == 0 } { return } set fmt {%^24pn\t%10org\t%6loc\t%area-%exch-%ext\t%ema} global postOutput postError set postOutput {} set postError {} bgexec postStatus -error postError -output postOutput \ pq -o $fmt $query & Animate on tkwait variable postStatus if { $postOutput != "" } { .text configure -state normal .text delete 0.0 end .text insert 0.0 $postOutput .text configure -state disabled .status_label configure -text "Post query successful" } else { .status_label configure -text "Post query failed" } set pq_dict(textIndex) {} Animate off if { $postError != "" } { tkerror $postError } } # ---------------------------------------------------------------- # # ClearFields -- # # Clears the all the entry fields. # # Arguments # None. # # Globals # pq_dict(entryNames) -- list of entry widget names # pq_dict(textIndex) -- starting index of highlighted information # (a line in the text widget) # # ---------------------------------------------------------------- proc ClearFields {} { global pq_dict blt::busy hold . ; update foreach name $pq_dict(entryNames) { .${name}_entry delete 0 end } set pq_dict(textIndex) {} .status_label configure -text "Cleared query fields" blt::busy release . } # ---------------------------------------------------------------- # # FillFields -- # # Makes a post query based upon the highlighted line in # the text widget to fill in all post entry fields. # # Arguments # x x screen coordinate # y y screen coordinate # # Globals # postOutput variable where collected output from pq # command will be stored # pq_dict(format) standard query format to collect data for # all entry fields # pq_dict(entryNames) list of entry widget names # # ---------------------------------------------------------------- proc FillFields { x y } { global pq_dict set info [.text get [list @$x,$y linestart] [list @$x,$y lineend]] set info [split $info \t] if { [llength $info] == 0 } { return } set name [string trim [lindex $info 0]] set name [split $name ,] set last [lindex $name 0] set name [split [lindex $name 1]] set first [lindex $name 0] set middle [lindex $name 1] set org [string trim [lindex $info 1]] set loc [string trim [lindex $info 2]] set tel [string trim [lindex $info 3]] set query last=$last/first=$first/middle=$middle/org=$org/loc=$loc/tel=[list $tel] global postOutput set postOutput {} bgexec postStatus -output postOutput \ pq -o $pq_dict(format) $query & Animate on tkwait variable postStatus if { $postOutput == "" } { # Try again with out the telephone number set query last=$last/first=$first/middle=$middle/org=$org/loc=$loc set postStatus {} bgexec postStatus -output postOutput \ pq -o $pq_dict(format) $query & tkwait variable postStatus } Animate off if { $postOutput == "" } { .status_label configure -text "Post query failed" } else { .status_label configure -text "Post database fields found" set postOutput [split $postOutput : ] set cnt 0 foreach name $pq_dict(entryNames) { .${name}_entry delete 0 end .${name}_entry insert 0 [lindex $postOutput $cnt] incr cnt } } } # ---------------------------------------------------------------- # # HighlightText -- # # Highlight the text under the current line (as based upon # the given screen coordinates. Only highlight the line if # pointer has been moved to the another line. # # Arguments # x x screen coordinate # y y screen coordinate # # Globals # pq_dict(visual) either "mono" or "color"; indicates if # color screen features can be used # pq_dict(textIndex) starting index of highlighted information # pq_dict(normalFgColor) color to use for highlighted region # # ---------------------------------------------------------------- proc HighlightText { x y } { global pq_dict set newIndex [.text index [list @$x,$y linestart]] if { $newIndex != $pq_dict(textIndex) } { catch { .text tag delete highlight } .text tag add highlight $newIndex [list $newIndex lineend] if { $pq_dict(visual) == "color" } { .text tag configure highlight \ -foreground $pq_dict(normalFgColor) -underline on } else { .text tag configure highlight -underline on } set pq_dict(textIndex) $newIndex } } # ---------------------------------------------------------------- # # ChangeFocus -- # # Change the keyboard focus to the next/last entry widget. # # Arguments # direction either "next" or "last"; indicates in # which direction to change focus # # Globals # pq_dict(entryNames) list of entry widget names # pq_dict(index) current index in list of entry widget # names of the keyboard focus. An index # of -1 indicates there is no focus. # pq_dict(numEntries) number of names in entry widget list # # ---------------------------------------------------------------- proc ChangeFocus direction { global pq_dict case $direction { next { incr pq_dict(index) if { $pq_dict(index) == $pq_dict(numEntries) } { set pq_dict(index) 0 } } last { set pq_dict(index) [expr $pq_dict(index)-1] if { $pq_dict(index) < 0 } { set pq_dict(index) [expr $pq_dict(numEntries)-1] } } } focus .[lindex $pq_dict(entryNames) $pq_dict(index)]_entry update idletasks update } # ---------------------------------------------------------------- # # ColorFocus -- # # Change background color of entry widget with active # keyboard focus # # Arguments # w name of entry widget to change # bool either "on" or "off"; indicates if # the focus highlight should turned on # or off. # # Globals # pq_dict(entryNames) list of entry widget names # pq_dict(index) current index in list of entry widget # names of the keyboard focus. An index # of -1 indicates there is no focus. # pq_dict(visual) either "mono" or "color"; indicates if # color screen features can be used # # ---------------------------------------------------------------- proc ColorFocus { w bool } { global pq_dict regexp {\.([a-z]+)_entry} $w dummy name if { $pq_dict(visual) == "color" && [info commands $w] == $w } { if { $bool == "on" } { set pq_dict(index) [lsearch $pq_dict(entryNames) $name] $w configure -background $pq_dict(focusHighlightColor) } else { $w configure -background $pq_dict(normalBgColor) } } } # ---------------------------------------------------------------- # # Animate -- # # Activates/deactivates an animated bitmap and busy window. # A cancel button is mapped and raised so that it is unaffected # by the busy window. # # Arguments # option either "on", "off", or "continue"; # indicates whether animation should # be started, stoped or continued. # # Globals # pq_dict(entryNames) list of entry widget names # pq_dict(index) current index in list of entry widget # names of the keyboard focus. An index # of -1 indicates there is no focus. # pq_dict(visual) either "mono" or "color"; indicates if # color screen features can be used # # ---------------------------------------------------------------- set pq_dict(curBitmap) 0 set pq_dict(lastBitmap) 0 proc Animate option { global pq_dict case $option { on { blt::busy hold . .status_label configure -text "Searching..." global topLevel blt::table $topLevel .cancel_button 18,8 -anchor e -reqwidth .70i winop raise .cancel_button .quit_button configure -state disabled .clear_button configure -state disabled winop raise .cancel_button set pq_dict(lastFocus) [focus] focus -force . set pq_dict(curBitmap) $pq_dict(lastBitmap) update } off { blt::table forget .cancel_button .quit_button configure -state normal .clear_button configure -state normal .trademark configure -bitmap attlogo set pq_dict(lastBitmap) $pq_dict(curBitmap) set pq_dict(curBitmap) -1 focus $pq_dict(lastFocus) blt::busy release . } } # # Continue with next bitmap # if { $pq_dict(curBitmap) >= 0 } { set bmap [format globe_%0.2d $pq_dict(curBitmap)] .trademark configure -bitmap $bmap incr pq_dict(curBitmap) if { $pq_dict(curBitmap) >= 29 } { set pq_dict(curBitmap) 0 } after 100 Animate continue } } # -------------------------------------------------------------------------- # # main body of program # blt::tile::frame .frame set topLevel .frame blt::tile::label .overall_label -font -*-Helvetica-Bold-R-*-*-18-*-*-*-*-*-*-* blt::tile::label .name_label -font $pq_dict(titleFont) blt::tile::label .tel_label -font $pq_dict(titleFont) blt::tile::label .addr_label -font $pq_dict(titleFont) blt::tile::label .org_title -font $pq_dict(titleFont) blt::tile::label .loc_title -font $pq_dict(titleFont) foreach name $pq_dict(entryNames) { blt::tile::label .${name}_label entry .${name}_entry } if [info exists env(POST_DEFAULTS)] { set pq_dict(defaults) [split $env(POST_DEFAULTS) ":"] } foreach i $pq_dict(defaults) { set i [split $i "="] if { [llength $i] == 2 } { set name [lindex $i 0] if { [lsearch $pq_dict(entryNames) $name] >= 0 } { .${name}_entry insert 0 [lindex $i 1] } } } blt::tile::label .orders_title -text "Current Orders" \ -font -*-Helvetica-Bold-R-*-*-16-*-*-*-*-*-*-* set font -*-Helvetica-Bold-R-*-*-12-*-*-*-*-*-*-* button .clear_button -command ClearFields -font $font button .quit_button -command { exit } -font $font button .search_button -text "Search" -font $font blt::tile::label .status_label button .cancel_button -command StopQuery #-relief raised blt::tile::label .trademark -bitmap attlogo text .text -yscrollcommand { .vscroll set } -state disabled scrollbar .vscroll -command { .text yview } blt::table $topLevel \ .overall_label 0,1 -cspan 10 -pady 5 \ .name_label 1,2 \ .last_entry 2,2 -cspan 2 \ .first_entry 2,4 \ .middle_entry 2,5 \ .last_label 3,2 \ .first_label 3,4 \ .middle_label 3,5 \ .tel_label 1,7 \ .area_entry 2,7 \ .exch_entry 2,8 \ .ext_entry 2,9 \ .area_label 3,7 \ .exch_label 3,8 \ .ext_label 3,9 \ .org_title 4,2 \ .com_entry 5,2 \ .org_entry 5,3 \ .tl_entry 5,4 \ .com_label 6,2 \ .org_label 6,3 \ .tl_label 6,4 \ .loc_title 4,7 \ .room_entry 5,7 \ .oldloc_entry 5,8 \ .loc_entry 5,9 \ .room_label 6,7 \ .oldloc_label 6,8 \ .loc_label 6,9 \ .addr_label 8,2 \ .street_entry 9,2 \ .ema_entry 9,7 -cspan 2 \ .street_label 10,2 \ .city_entry 11,2 -cspan 2 \ .state_entry 11,4 \ .zip_entry 11,5 \ .ema_label 10,7 -cspan 2 \ .city_label 12,2 -cspan 2 \ .state_label 12,4 \ .zip_label 12,5 \ .orders_title 16,2 -pady { 4 0 } \ .text 17,2 -cspan 8 -fill both -padx 2 \ .vscroll 17,10 -anchor center -fill both \ .status_label 18,4 -cspan 6 -reqwidth {0 4i} \ .search_button 18,3 -reqwidth .6i -anchor center -pady 8\ .clear_button 18,5 -reqwidth .6i -anchor center \ .quit_button 18,8 -reqwidth .6i -anchor center eval blt::table configure $topLevel \ [info command .*_label] [info commands .*_title] \ -anchor w -padx 2 -ipadx 2 eval blt::table configure $topLevel [info command .*_entry] \ -fill both -padx 2 eval blt::table configure $topLevel .name_label .tel_label .org_title \ .com_label .addr_label .street_entry .street_label \ -cspan 3 eval blt::table configure $topLevel .last_entry .ema_entry .city_entry \ .ema_label .city_label -cspan 2 blt::table configure $topLevel .overall_label -anchor center blt::table configure $topLevel r16 -pady { 5 5 } -resize both blt::table configure $topLevel c0 -width .vscroll blt::table configure $topLevel c0 c10 -resize none blt::table configure $topLevel r3 r6 r10 r12 -resize none blt::table configure $topLevel r17 -height { 40 {} } blt::table configure $topLevel r16 r18 -resize none blt::table configure $topLevel c6 -pad { 5 5 } if { $topLevel == ".frame" } { blt::table . \ $topLevel 0,0 -fill both } bind .text <Button-2> { FillFields %x %y continue } bind .text <Motion> { HighlightText %x %y continue } bind .text <Enter> { set pq_dict(textIndex) {} HighlightText %x %y set info [.text get [list 0.0 linestart] [list 0.0 lineend]] if { $info != "" } { .status_label configure -text "Query individual with button-2" } continue } bind .text <Leave> { if { [blt::busy isbusy .] != "." } { .text tag delete highlight .status_label configure -text "" } continue } bind EntryFocus <Tab> { ChangeFocus next break } bind EntryFocus <Shift-Tab> { ChangeFocus last break } if { $pq_dict(visual) == "color" } { bind EntryFocus <FocusIn> { ColorFocus %W on } bind EntryFocus <FocusOut> { ColorFocus %W off } } bind Entry <Return> PostQuery foreach name $pq_dict(entryNames) { set w .${name}_entry bindtags $w [list EntryFocus $w Entry all] } focus .last_entry ���./saods9/blt3.0.1/src/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013021� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkFrame.c���������������������������������������������������������������������0000644�0001750�0001750�00000075122�11462120063�014572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkFrame.c -- * * This module implements "frame" and "toplevel" widgets for * the Tk toolkit. Frames are windows with a background color * and possibly a 3-D effect, but not much else in the way of * attributes. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkFrame.c 1.68 96/02/15 18:53:30 */ #include "bltInt.h" #include "bltBgStyle.h" #ifndef NO_TKFRAME /* * Defaults for frames: */ #define DEF_FRAME_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_FRAME_BG_MONO STD_NORMAL_BG_MONO #define DEF_FRAME_BORDERWIDTH "0" #define DEF_FRAME_CLASS "Frame" #define DEF_FRAME_COLORMAP "" #define DEF_FRAME_CONTAINER "0" #define DEF_FRAME_CURSOR "" #define DEF_FRAME_HEIGHT "0" #define DEF_FRAME_HIGHLIGHT_BG STD_NORMAL_BACKGROUND #define DEF_FRAME_HIGHLIGHT RGB_BLACK #define DEF_FRAME_HIGHLIGHT_WIDTH "0" #define DEF_FRAME_RELIEF "flat" #define DEF_FRAME_TAKE_FOCUS "0" #define DEF_FRAME_USE "" #define DEF_FRAME_VISUAL "" #define DEF_FRAME_WIDTH "0" /* * Defaults for toplevels (most of the defaults for frames also apply * to toplevels): */ #define DEF_TOPLEVEL_CLASS "Toplevel" #define DEF_TOPLEVEL_SCREEN "" #define DEF_TOPLEVEL_MENU "" /* * A data structure of the following type is kept for each * frame that currently exists for this process: */ typedef struct { Tk_Window tkwin; /* Window that embodies the frame. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up. */ Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tcl_Command widgetCmd; /* Token for frame's widget command. */ char *className; /* Class name for widget (from configuration * option). Malloc-ed. */ int mask; /* Either FRAME or TOPLEVEL; used to select * which configuration options are valid for * widget. */ char *screenName; /* Screen on which widget is created. Non-null * only for top-levels. Malloc-ed, may be * NULL. */ char *visualName; /* Textual description of visual for window, * from -visual option. Malloc-ed, may be * NULL. */ char *colormapName; /* Textual description of colormap for window, * from -colormap option. Malloc-ed, may be * NULL. */ char *menuName; /* Textual description of menu to use for * menubar. Malloc-ed, may be NULL. */ Colormap colormap; /* If not None, identifies a colormap * allocated for this window, which must be * freed when the window is deleted. */ Blt_Background normalBg; /* Structure used to draw 3-D border and * background. NULL means no background * or border. */ int borderWidth; /* Width of 3-D border (if any). */ int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int width; /* Width to request for window. <= 0 means * don't request any size. */ int height; /* Height to request for window. <= 0 means * don't request any size. */ Tk_Cursor cursor; /* Current cursor for window, or None. */ char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ int isContainer; /* 1 means this window is a container, 0 means * that it isn't. */ char *useThis; /* If the window is embedded, this points to * the name of the window in which it is * embedded (malloc'ed). For non-embedded * windows this is NULL. */ int flags; /* Various flags; see below for * definitions. */ } Frame; /* * Flag bits for frames: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler * has already been queued to redraw * this window. * GOT_FOCUS: Non-zero means this widget currently * has the input focus. */ #define REDRAW_PENDING 1 #define GOT_FOCUS 4 /* * The following flag bits are used so that there can be separate * defaults for some configuration options for frames and toplevels. */ #define FRAME BLT_CONFIG_USER_BIT #define TOPLEVEL (BLT_CONFIG_USER_BIT << 1) #define BOTH (FRAME | TOPLEVEL) static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_FRAME_BACKGROUND, Blt_Offset(Frame, normalBg), BOTH | BLT_CONFIG_COLOR_ONLY | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_FRAME_BG_MONO, Blt_Offset(Frame, normalBg), BOTH | BLT_CONFIG_MONO_ONLY | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, BOTH}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, BOTH}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_FRAME_BORDERWIDTH, Blt_Offset(Frame, borderWidth), BOTH}, {BLT_CONFIG_STRING, "-class", "class", "Class", DEF_FRAME_CLASS, Blt_Offset(Frame, className), FRAME}, {BLT_CONFIG_STRING, "-class", "class", "Class", DEF_TOPLEVEL_CLASS, Blt_Offset(Frame, className), TOPLEVEL}, {BLT_CONFIG_STRING, "-colormap", "colormap", "Colormap", DEF_FRAME_COLORMAP, Blt_Offset(Frame, colormapName), BOTH | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-container", "container", "Container", DEF_FRAME_CONTAINER, Blt_Offset(Frame, isContainer), BOTH}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_FRAME_CURSOR, Blt_Offset(Frame, cursor), BOTH | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_FRAME_HEIGHT, Blt_Offset(Frame, height), BOTH}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, Blt_Offset(Frame, highlightBgColorPtr), BOTH}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_FRAME_HIGHLIGHT, Blt_Offset(Frame, highlightColorPtr), BOTH}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, Blt_Offset(Frame, highlightWidth), BOTH}, {BLT_CONFIG_STRING, "-menu", "menu", "Menu", DEF_TOPLEVEL_MENU, Blt_Offset(Frame, menuName), TOPLEVEL | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_FRAME_RELIEF, Blt_Offset(Frame, relief), BOTH}, {BLT_CONFIG_STRING, "-screen", "screen", "Screen", DEF_TOPLEVEL_SCREEN, Blt_Offset(Frame, screenName), TOPLEVEL | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_FRAME_TAKE_FOCUS, Blt_Offset(Frame, takeFocus), BOTH | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-use", "use", "Use", DEF_FRAME_USE, Blt_Offset(Frame, useThis), TOPLEVEL|BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-visual", "visual", "Visual", DEF_FRAME_VISUAL, Blt_Offset(Frame, visualName), BOTH | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_FRAME_WIDTH, Blt_Offset(Frame, width), BOTH}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * Forward declarations for procedures defined later in this file: */ static int ConfigureFrame (Tcl_Interp *interp, Frame * framePtr, int objc, Tcl_Obj *const *objv, int flags); static Tcl_FreeProc DestroyFrame; static Tcl_IdleProc DisplayFrame; static Tcl_CmdDeleteProc FrameCmdDeletedProc; static Tk_EventProc FrameEventProc; static Tcl_ObjCmdProc FrameWidgetCmd; static Tcl_IdleProc MapFrame; static Tcl_ObjCmdProc FrameCmd, ToplevelCmd; #ifdef TK_MAINWINDOW BLT_EXTERN #else static #endif int TkCreateFrame (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int toplevel, char *appName); #ifndef USE_TK_STUBS BLT_EXTERN void TkSetWindowMenuBar (Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName); BLT_EXTERN Tk_Window TkCreateMainWindow (Tcl_Interp * interp, char *screenName, char *baseName); #if (_TK_VERSION >= _VERSION(8,4,0)) #define TkSetClassProcs Tk_SetClassProcs #else BLT_EXTERN void TkSetClassProcs (Tk_Window tkwin, void *procs, ClientData instanceData); #endif /* TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION > 3 */ BLT_EXTERN void TkpSetMainMenubar (Tcl_Interp * interp, Tk_Window tkwin, char *menuName); BLT_EXTERN int TkpUseWindow (Tcl_Interp * interp, Tk_Window tkwin, char * string); BLT_EXTERN void TkpMakeContainer (Tk_Window tkwin); #endif /* *--------------------------------------------------------------------------- * * FrameCmd, ToplevelCmd -- * * These procedures are invoked to process the "frame" and * "toplevel" TCL commands. See the user documentation for * details on what they do. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. These procedures are just wrappers; * they call ButtonCreate to do all of the real work. * *--------------------------------------------------------------------------- */ static int FrameCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { return TkCreateFrame(clientData, interp, objc, objv, 0, (char *)NULL); } static int ToplevelCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { return TkCreateFrame(clientData, interp, objc, objv, 1, (char *)NULL); } /* *--------------------------------------------------------------------------- * * TkFrameCreate -- * * This procedure is invoked to process the "frame" and "toplevel" * Tcl commands; it is also invoked directly by Tk_Init to create * a new main window. See the user documentation for the "frame" * and "toplevel" commands for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ #ifndef TK_MAINWINDOW static #endif /* TK_MAINWINDOW */ int TkCreateFrame( ClientData clientData, /* Main window associated with interpreter. * If we're called by Tk_Init to create a * new application, then this is NULL. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv, /* Argument strings. */ int toplevel, /* Non-zero means create a toplevel window, * zero means create a frame. */ char *appName) /* Should only be non-NULL if clientData is * NULL: gives the base name to use for the * new application. */ { Frame *framePtr; Tk_Window new; const char *className, *screenName, *visualName, *colormapName, *arg, *useOption; int i, c, depth; unsigned int mask; Colormap colormap; Visual *visual; Tk_Window tkwin; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", objv[0], " pathName ?options?\"", (char *)NULL); return TCL_ERROR; } /* * Pre-process the argument list. Scan through it to find any * "-class", "-screen", "-visual", and "-colormap" options. These * arguments need to be processed specially, before the window * is configured using the usual Tk mechanisms. */ className = colormapName = screenName = visualName = useOption = NULL; colormap = None; for (i = 2; i < objc; i += 2) { int length; arg = Tcl_GetStringFromObj(objv[i], &length); if (length < 2) { continue; } c = arg[1]; if ((c == 'c') && (strncmp(arg, "-class", length) == 0) && (length >= 3)) { className = Tcl_GetString(objv[i + 1]); } else if ((c == 'c') && (strncmp(arg, "-colormap", length) == 0)) { colormapName = Tcl_GetString(objv[i + 1]); } else if ((c == 's') && (toplevel) && (strncmp(arg, "-screen", length) == 0)) { screenName = Tcl_GetString(objv[i + 1]); } else if ((c == 'u') && (toplevel) && (strncmp(arg, "-use", length) == 0)) { useOption = Tcl_GetString(objv[i + 1]); } else if ((c == 'v') && (strncmp(arg, "-visual", length) == 0)) { visualName = Tcl_GetString(objv[i + 1]); } } /* * Create the window, and deal with the special options -use, * -classname, -colormap, -screenname, and -visual. These options * must be handle before calling ConfigureFrame below, and they must * also be processed in a particular order, for the following * reasons: * 1. Must set the window's class before calling ConfigureFrame, * so that unspecified options are looked up in the option * database using the correct class. * 2. Must set visual information before calling ConfigureFrame * so that colors are allocated in a proper colormap. * 3. Must call TkpUseWindow before setting non-default visual * information, since TkpUseWindow changes the defaults. */ if (screenName == NULL) { screenName = (toplevel) ? "" : NULL; } tkwin = Tk_MainWindow(interp); if (tkwin != NULL) { new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), screenName); } else { /* * We were called from Tk_Init; create a new application. */ if (appName == NULL) { panic("TkCreateFrame didn't get application name"); } new = (Tk_Window)TkCreateMainWindow(interp, (char *)screenName,appName); } if (new == NULL) { goto error; } if (className == NULL) { className = (char *)Tk_GetOption(new, "class", "Class"); if (className == NULL) { className = (toplevel) ? "Toplevel" : "Frame"; } } Tk_SetClass(new, className); if (useOption == NULL) { useOption = Tk_GetOption(new, "use", "Use"); } if (useOption != NULL) { if (TkpUseWindow(interp, new, (char *)useOption) != TCL_OK) { goto error; } } if (visualName == NULL) { visualName = (char *)Tk_GetOption(new, "visual", "Visual"); } if (colormapName == NULL) { colormapName = (char *)Tk_GetOption(new, "colormap", "Colormap"); } if (visualName != NULL) { visual = Tk_GetVisual(interp, new, visualName, &depth, (colormapName == NULL) ? &colormap : (Colormap *) NULL); if (visual == NULL) { goto error; } Tk_SetWindowVisual(new, visual, depth, colormap); } if (colormapName != NULL) { colormap = Tk_GetColormap(interp, new, colormapName); if (colormap == None) { goto error; } Tk_SetWindowColormap(new, colormap); } /* * For top-level windows, provide an initial geometry request of * 200x200, just so the window looks nicer on the screen if it * doesn't request a size for itself. */ if (toplevel) { Tk_GeometryRequest(new, 200, 200); } /* * Create the widget record, process configuration options, and * create event handlers. Then fill in a few additional fields * in the widget record from the special options. */ framePtr = Blt_AssertCalloc(1, sizeof(Frame)); framePtr->tkwin = new; framePtr->display = Tk_Display(new); framePtr->interp = interp; framePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(new), FrameWidgetCmd, (ClientData)framePtr, FrameCmdDeletedProc); framePtr->mask = (toplevel) ? TOPLEVEL : FRAME; framePtr->colormap = colormap; framePtr->borderWidth = 0; framePtr->relief = TK_RELIEF_FLAT; /* * Store backreference to frame widget in window structure. */ TkSetClassProcs(new, NULL, (ClientData)framePtr); mask = ExposureMask | StructureNotifyMask | FocusChangeMask; if (toplevel) { mask |= ActivateMask; } Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData)framePtr); if (ConfigureFrame(interp, framePtr, objc - 2, objv + 2, 0) != TCL_OK) { goto error; } if ((framePtr->isContainer)) { if (framePtr->useThis == NULL) { TkpMakeContainer(framePtr->tkwin); } else { Tcl_AppendResult(interp, "A window cannot have both the -use ", "and the -container option set.", (char *)NULL); return TCL_ERROR; } } if (toplevel) { Tcl_DoWhenIdle(MapFrame, (ClientData)framePtr); } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(new), -1); return TCL_OK; error: if (new != NULL) { Tk_DestroyWindow(new); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * FrameWidgetCmd -- * * This procedure is invoked to process the TCL command * that corresponds to a frame widget. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int FrameWidgetCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { register Frame *framePtr = (Frame *) clientData; int result; int length; int c, i; char *string; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } Tcl_Preserve((ClientData)framePtr); string = Tcl_GetStringFromObj(objv[1], &length); c = string[0]; if ((c == 'c') && (length >= 2) && (strncmp(string, "cget", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " cget option\"", (char *)NULL); result = TCL_ERROR; goto done; } result = Blt_ConfigureValueFromObj(interp, framePtr->tkwin, configSpecs, (char *)framePtr, objv[2], framePtr->mask); } else if ((c == 'c') && (length >= 2) && (strncmp(string, "configure", length) == 0)) { if (objc == 2) { result = Blt_ConfigureInfoFromObj(interp, framePtr->tkwin, configSpecs, (char *)framePtr, (Tcl_Obj *)NULL, framePtr->mask); } else if (objc == 3) { result = Blt_ConfigureInfoFromObj(interp, framePtr->tkwin, configSpecs, (char *)framePtr, objv[2], framePtr->mask); } else { /* * Don't allow the options -class, -colormap, -container, * -newcmap, -screen, -use, or -visual to be changed. */ for (i = 2; i < objc; i++) { string = Tcl_GetStringFromObj(objv[i], &length); if (length < 2) { continue; } c = string[1]; if (((c == 'c') && (strncmp(string, "-class", length) == 0)) || ((c == 'c') && (framePtr->mask == TOPLEVEL) && (length >= 3) && (strncmp(string, "-colormap", length) == 0)) || ((c == 'c') && (strncmp(string, "-container", length) == 0) && (length >= 3)) || ((c == 's') && (framePtr->mask == TOPLEVEL) && (strncmp(string, "-screen", length) == 0)) || ((c == 'u') && (framePtr->mask == TOPLEVEL) && (strncmp(string, "-use", length) == 0)) || ((c == 'v') && (framePtr->mask == TOPLEVEL) && (strncmp(string, "-visual", length) == 0))) { Tcl_AppendResult(interp, "can't modify ", string, " option after widget is created", (char *)NULL); result = TCL_ERROR; goto done; } } result = ConfigureFrame(interp, framePtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); } } else { Tcl_AppendResult(interp, "bad option \"", string, "\": must be cget or configure", (char *)NULL); result = TCL_ERROR; } done: Tcl_Release((ClientData)framePtr); return result; } /* *--------------------------------------------------------------------------- * * DestroyFrame -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a frame at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the frame is freed up. * *--------------------------------------------------------------------------- */ static void DestroyFrame(DestroyData memPtr) /* Info about frame widget. */ { register Frame *framePtr = (Frame *) memPtr; Blt_FreeOptions(configSpecs, (char *)framePtr, framePtr->display, framePtr->mask); if (framePtr->colormap != None) { Tk_FreeColormap(framePtr->display, framePtr->colormap); } Blt_Free(framePtr); } /* *--------------------------------------------------------------------------- * * ConfigureFrame -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or * reconfigure) a frame widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for framePtr; old resources get freed, if there * were any. * *--------------------------------------------------------------------------- */ static int ConfigureFrame( Tcl_Interp *interp, /* Used for error reporting. */ register Frame *framePtr, /* Information about widget; may or may * not already have values for some fields. */ int objc, /* Number of valid entries in objv. */ Tcl_Obj *const *objv, /* Arguments. */ int flags) /* Flags to pass to Blt_ConfigureWidget. */ { char *oldMenuName; /* * Need the old menubar name for the menu code to delete it. */ if (framePtr->menuName == NULL) { oldMenuName = NULL; } else { oldMenuName = Blt_AssertStrdup(framePtr->menuName); } if (Blt_ConfigureWidgetFromObj(interp, framePtr->tkwin, configSpecs, objc, objv, (char *)framePtr, flags | framePtr->mask) != TCL_OK) { return TCL_ERROR; } if (((oldMenuName == NULL) && (framePtr->menuName != NULL)) || ((oldMenuName != NULL) && (framePtr->menuName == NULL)) || ((oldMenuName != NULL) && (framePtr->menuName != NULL) && strcmp(oldMenuName, framePtr->menuName) != 0)) { TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName, framePtr->menuName); } #ifdef notdef if (framePtr->normalBg != NULL) { Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->normalBg); } else { Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None); } #endif Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None); if (framePtr->highlightWidth < 0) { framePtr->highlightWidth = 0; } Tk_SetInternalBorder(framePtr->tkwin, framePtr->borderWidth + framePtr->highlightWidth); if ((framePtr->width > 0) || (framePtr->height > 0)) { Tk_GeometryRequest(framePtr->tkwin, framePtr->width, framePtr->height); } if (oldMenuName != NULL) { Blt_Free(oldMenuName); } if (Tk_IsMapped(framePtr->tkwin)) { if (!(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData)framePtr); } framePtr->flags |= REDRAW_PENDING; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DisplayFrame -- * * This procedure is invoked to display a frame widget. * * Results: * None. * * Side effects: * Commands are output to X to display the frame in its * current mode. * *--------------------------------------------------------------------------- */ static void DisplayFrame(ClientData clientData) /* Information about widget. */ { register Frame *framePtr = (Frame *) clientData; register Tk_Window tkwin = framePtr->tkwin; GC gc; framePtr->flags &= ~REDRAW_PENDING; if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin) || framePtr->isContainer) { return; } Blt_FillBackgroundRectangle(tkwin, Tk_WindowId(tkwin), framePtr->normalBg, framePtr->highlightWidth, framePtr->highlightWidth, Tk_Width(tkwin) - 2 * framePtr->highlightWidth, Tk_Height(tkwin) - 2 * framePtr->highlightWidth, framePtr->borderWidth, framePtr->relief); if (framePtr->highlightWidth != 0) { if (framePtr->flags & GOT_FOCUS) { gc = Tk_GCForColor(framePtr->highlightColorPtr, Tk_WindowId(tkwin)); } else { gc = Tk_GCForColor(framePtr->highlightBgColorPtr, Tk_WindowId(tkwin)); } Tk_DrawFocusHighlight(tkwin, gc, framePtr->highlightWidth, Tk_WindowId(tkwin)); } } /* *--------------------------------------------------------------------------- * * FrameEventProc -- * * This procedure is invoked by the Tk dispatcher on * structure changes to a frame. For frames with 3D * borders, this procedure is also invoked for exposures. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void FrameEventProc( ClientData clientData, /* Information about window. */ register XEvent *eventPtr) /* Information about event. */ { register Frame *framePtr = (Frame *) clientData; if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) || (eventPtr->type == ConfigureNotify)) { goto redraw; } else if (eventPtr->type == DestroyNotify) { if (framePtr->menuName != NULL) { TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, framePtr->menuName, NULL); Blt_Free(framePtr->menuName); framePtr->menuName = NULL; } if (framePtr->tkwin != NULL) { /* * If this window is a container, then this event could be * coming from the embedded application, in which case * Tk_DestroyWindow hasn't been called yet. When Tk_DestroyWindow * is called later, then another destroy event will be generated. * We need to be sure we ignore the second event, since the frame * could be gone by then. To do so, delete the event handler * explicitly (normally it's done implicitly by Tk_DestroyWindow). */ Tk_DeleteEventHandler(framePtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, FrameEventProc, (ClientData)framePtr); framePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); } if (framePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayFrame, (ClientData)framePtr); } Tcl_CancelIdleCall(MapFrame, (ClientData)framePtr); Tcl_EventuallyFree((ClientData)framePtr, (Tcl_FreeProc *)DestroyFrame); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { framePtr->flags |= GOT_FOCUS; if (framePtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == FocusOut) { if (eventPtr->xfocus.detail != NotifyInferior) { framePtr->flags &= ~GOT_FOCUS; if (framePtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == ActivateNotify) { TkpSetMainMenubar(framePtr->interp, framePtr->tkwin, framePtr->menuName); } return; redraw: if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData)framePtr); framePtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * FrameCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void FrameCmdDeletedProc(ClientData clientData) /* Pointer to widget record for widget. */ { Frame *framePtr = (Frame *) clientData; Tk_Window tkwin = framePtr->tkwin; if (framePtr->menuName != NULL) { TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, framePtr->menuName, NULL); Blt_Free(framePtr->menuName); framePtr->menuName = NULL; } /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tkwin != NULL) { framePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * MapFrame -- * * This procedure is invoked as a when-idle handler to map a * newly-created top-level frame. * * Results: * None. * * Side effects: * The frame given by the clientData argument is mapped. * *--------------------------------------------------------------------------- */ static void MapFrame(ClientData clientData) /* Pointer to frame structure. */ { Frame *framePtr = (Frame *) clientData; /* * Wait for all other background events to be processed before * mapping window. This ensures that the window's correct geometry * will have been determined before it is first mapped, so that the * window manager doesn't get a false idea of its desired geometry. */ Tcl_Preserve((ClientData)framePtr); for(;;) { if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) { break; } /* * After each event, make sure that the window still exists * and quit if the window has been destroyed. */ if (framePtr->tkwin == NULL) { Tcl_Release((ClientData)framePtr); return; } } Tk_MapWindow(framePtr->tkwin); Tcl_Release((ClientData)framePtr); } /* *--------------------------------------------------------------------------- * * TkInstallFrameMenu -- * * This function is needed when a Windows HWND is created * and a menubar has been set to the window with a system * menu. It notifies the menu package so that the system * menu can be rebuilt. * * Results: * None. * * Side effects: * The system menu (if any) is created for the menubar * associated with this frame. * *--------------------------------------------------------------------------- */ #ifdef notdef void TkInstallFrameMenu(Tk_Window tkwin) /* The window that was just created. */ { #define Tk_InstanceData(tkwin) (((Tk_FakeWin *)(tkwin))->dummy18) #define Tk_MainPtr(tkwin) (((Tk_FakeWin *)(tkwin))->dummy5) if (Tk_MainPtr(tkwin) != NULL) { Frame *framePtr; framePtr = (Frame *) Tk_InstanceData(tkwin); TkpMenuNotifyToplevelCreate(framePtr->interp, framePtr->menuName); } } #endif int Blt_FrameCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[2] = { {"frame", FrameCmd,}, {"toplevel", ToplevelCmd,}, }; return Blt_InitCmds(interp, "::blt::tk", cmdSpecs, 2); } #endif /* NO_TKFRAME */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkPlatDecls.h�����������������������������������������������������������������0000644�0001750�0001750�00000015755�11462120063�015426� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkPlatDecls.h -- * * Declarations of functions in the platform-specific public TCL API. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from tkPlatDecls.h of the Tk library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TKPLATDECLS #define _TKPLATDECLS #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tk.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ #ifdef __WIN32__ /* 0 */ EXTERN Window Tk_AttachHWND(Tk_Window tkwin, HWND hwnd); /* 1 */ EXTERN HINSTANCE Tk_GetHINSTANCE(void); /* 2 */ EXTERN HWND Tk_GetHWND(Window window); /* 3 */ EXTERN Tk_Window Tk_HWNDToWindow(HWND hwnd); /* 4 */ EXTERN void Tk_PointerEvent(HWND hwnd, int x, int y); /* 5 */ EXTERN int Tk_TranslateWinEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * result); #endif /* __WIN32__ */ #ifdef MAC_TCL /* 0 */ EXTERN void Tk_MacSetEmbedHandler( Tk_MacEmbedRegisterWinProc * registerWinProcPtr, Tk_MacEmbedGetGrafPortProc * getPortProcPtr, Tk_MacEmbedMakeContainerExistProc * containerExistProcPtr, Tk_MacEmbedGetClipProc * getClipProc, Tk_MacEmbedGetOffsetInParentProc * getOffsetProc); /* 1 */ EXTERN void Tk_MacTurnOffMenus(void); /* 2 */ EXTERN void Tk_MacTkOwnsCursor(int tkOwnsIt); /* 3 */ EXTERN void TkMacInitMenus(Tcl_Interp * interp); /* 4 */ EXTERN void TkMacInitAppleEvents(Tcl_Interp * interp); /* 5 */ EXTERN int TkMacConvertEvent(EventRecord * eventPtr); /* 6 */ EXTERN int TkMacConvertTkEvent( EventRecord * eventPtr, Window window); /* 7 */ EXTERN void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 8 */ EXTERN void TkMacInvalClipRgns(TkWindow * winPtr); /* 9 */ EXTERN int TkMacHaveAppearance(void); /* 10 */ EXTERN GWorldPtr TkMacGetDrawablePort(Drawable drawable); #endif /* MAC_TCL */ typedef struct TkPlatStubs { int magic; struct TkPlatStubHooks *hooks; #ifdef __WIN32__ Window (*tk_AttachHWND)(Tk_Window tkwin, HWND hwnd); /* 0 */ HINSTANCE (*tk_GetHINSTANCE)(void); /* 1 */ HWND (*tk_GetHWND)(Window window); /* 2 */ Tk_Window (*tk_HWNDToWindow)(HWND hwnd); /* 3 */ void (*tk_PointerEvent)(HWND hwnd, int x, int y); /* 4 */ int (*tk_TranslateWinEvent)(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * result); /* 5 */ #endif /* __WIN32__ */ #ifdef MAC_TCL void (*tk_MacSetEmbedHandler)(Tk_MacEmbedRegisterWinProc * registerWinProcPtr, Tk_MacEmbedGetGrafPortProc * getPortProcPtr, Tk_MacEmbedMakeContainerExistProc * containerExistProcPtr, Tk_MacEmbedGetClipProc * getClipProc, Tk_MacEmbedGetOffsetInParentProc * getOffsetProc); /* 0 */ void (*tk_MacTurnOffMenus)(void); /* 1 */ void (*tk_MacTkOwnsCursor)(int tkOwnsIt); /* 2 */ void (*tkMacInitMenus)(Tcl_Interp * interp); /* 3 */ void (*tkMacInitAppleEvents)(Tcl_Interp * interp); /* 4 */ int (*tkMacConvertEvent)(EventRecord * eventPtr); /* 5 */ int (*tkMacConvertTkEvent)(EventRecord * eventPtr, Window window); /* 6 */ void (*tkGenWMConfigureEvent)(Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 7 */ void (*tkMacInvalClipRgns)(TkWindow * winPtr); /* 8 */ int (*tkMacHaveAppearance)(void); /* 9 */ GWorldPtr (*tkMacGetDrawablePort)(Drawable drawable); /* 10 */ #endif /* MAC_TCL */ } TkPlatStubs; #ifdef __cplusplus extern "C" { #endif extern TkPlatStubs *tkPlatStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) /* * Inline function declarations: */ #ifdef __WIN32__ #ifndef Tk_AttachHWND #define Tk_AttachHWND \ (tkPlatStubsPtr->tk_AttachHWND) /* 0 */ #endif #ifndef Tk_GetHINSTANCE #define Tk_GetHINSTANCE \ (tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */ #endif #ifndef Tk_GetHWND #define Tk_GetHWND \ (tkPlatStubsPtr->tk_GetHWND) /* 2 */ #endif #ifndef Tk_HWNDToWindow #define Tk_HWNDToWindow \ (tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */ #endif #ifndef Tk_PointerEvent #define Tk_PointerEvent \ (tkPlatStubsPtr->tk_PointerEvent) /* 4 */ #endif #ifndef Tk_TranslateWinEvent #define Tk_TranslateWinEvent \ (tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */ #endif #endif /* __WIN32__ */ #ifdef MAC_TCL #ifndef Tk_MacSetEmbedHandler #define Tk_MacSetEmbedHandler \ (tkPlatStubsPtr->tk_MacSetEmbedHandler) /* 0 */ #endif #ifndef Tk_MacTurnOffMenus #define Tk_MacTurnOffMenus \ (tkPlatStubsPtr->tk_MacTurnOffMenus) /* 1 */ #endif #ifndef Tk_MacTkOwnsCursor #define Tk_MacTkOwnsCursor \ (tkPlatStubsPtr->tk_MacTkOwnsCursor) /* 2 */ #endif #ifndef TkMacInitMenus #define TkMacInitMenus \ (tkPlatStubsPtr->tkMacInitMenus) /* 3 */ #endif #ifndef TkMacInitAppleEvents #define TkMacInitAppleEvents \ (tkPlatStubsPtr->tkMacInitAppleEvents) /* 4 */ #endif #ifndef TkMacConvertEvent #define TkMacConvertEvent \ (tkPlatStubsPtr->tkMacConvertEvent) /* 5 */ #endif #ifndef TkMacConvertTkEvent #define TkMacConvertTkEvent \ (tkPlatStubsPtr->tkMacConvertTkEvent) /* 6 */ #endif #ifndef TkGenWMConfigureEvent #define TkGenWMConfigureEvent \ (tkPlatStubsPtr->tkGenWMConfigureEvent) /* 7 */ #endif #ifndef TkMacInvalClipRgns #define TkMacInvalClipRgns \ (tkPlatStubsPtr->tkMacInvalClipRgns) /* 8 */ #endif #ifndef TkMacHaveAppearance #define TkMacHaveAppearance \ (tkPlatStubsPtr->tkMacHaveAppearance) /* 9 */ #endif #ifndef TkMacGetDrawablePort #define TkMacGetDrawablePort \ (tkPlatStubsPtr->tkMacGetDrawablePort) /* 10 */ #endif #endif /* MAC_TCL */ #endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKPLATDECLS */ �������������������./saods9/blt3.0.1/src/bltUnixMain.c�����������������������������������������������������������������0000644�0001750�0001750�00000022727�11462120063�015436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixMain.c -- * * Provides a default version of the Tcl_AppInit procedure for * use in wish and similar Tk-based applications. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from the Tk distribution. * * Copyright (c) 1993 The Regents of the University of * California. All rights reserved. * * Permission is hereby granted, without written agreement and * without license or royalty fees, to use, copy, modify, and * distribute this software and its documentation for any * purpose, provided that the above copyright notice and the * following two paragraphs appear in all copies of this * software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR * MODIFICATIONS. * */ #include <blt.h> #include <tcl.h> #ifndef TCL_ONLY #include <tk.h> #endif #include "config.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef NEED_MATHERR BLT_EXTERN int matherr(); int *tclDummyMathPtr = (int *)matherr; #endif BLT_EXTERN Tcl_AppInitProc Blt_core_Init; BLT_EXTERN Tcl_AppInitProc Blt_core_SafeInit; #ifndef TCL_ONLY BLT_EXTERN Tcl_AppInitProc Blt_x_Init; BLT_EXTERN Tcl_AppInitProc Blt_x_SafeInit; #endif #ifdef STATIC_PKGS /* Picture format packages. */ #ifndef TCL_ONLY BLT_EXTERN Tcl_AppInitProc Blt_PictureBmpInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureGifInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureJpgInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePbmInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePhotoInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePdfInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePngInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePsInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureTifInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureXbmInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureXpmInit; #endif /* TCL_ONLY */ /* Data table format packages. */ BLT_EXTERN Tcl_AppInitProc Blt_Table_CsvInit; #ifdef HAVE_LIBMYSQL BLT_EXTERN Tcl_AppInitProc Blt_Table_MysqlInit; #endif /* HAVE_LIBMYSQL */ BLT_EXTERN Tcl_AppInitProc Blt_Table_TreeInit; BLT_EXTERN Tcl_AppInitProc Blt_Table_VectorInit; #ifdef HAVE_LIBEXPAT BLT_EXTERN Tcl_AppInitProc Blt_Table_XmlInit; #endif /* Tree format packages. */ #ifdef HAVE_LIBEXPAT BLT_EXTERN Tcl_AppInitProc Blt_TreeXmlInit; #endif #endif /* STATIC_PKGS */ static int Initialize(Tcl_Interp *interp) /* Interpreter for application. */ { #ifdef TCLLIBPATH /* * It seems that some distributions of TCL don't compile-in a * default location of the library. This causes Tcl_Init to fail * if bltwish and bltsh are moved to another directory. The * workaround is to set the magic variable "tclDefaultLibrary". */ Tcl_SetVar(interp, "tclDefaultLibrary", TCLLIBPATH, TCL_GLOBAL_ONLY); #endif /* TCLLIBPATH */ if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (Blt_core_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, Blt_core_SafeInit); #ifdef STATIC_PKGS /* Tcl-only static packages */ if (Blt_Table_CsvInit(interp) != TCL_OK) { return TCL_ERROR; } /* Data table packages. */ Tcl_StaticPackage(interp, "blt_datatable_csv", Blt_Table_CsvInit, Blt_Table_CsvInit); #ifdef HAVE_LIBMYSQL if (Blt_Table_MysqlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_mysql", Blt_Table_MysqlInit, Blt_Table_MysqlInit); #endif /* HAVE_LIBMYSQL */ if (Blt_Table_TreeInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_tree", Blt_Table_TreeInit, Blt_Table_TreeInit); if (Blt_Table_VectorInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_vector", Blt_Table_VectorInit, Blt_Table_VectorInit); #ifdef HAVE_LIBEXPAT if (Blt_Table_XmlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_xml", Blt_Table_XmlInit, Blt_Table_XmlInit); #endif /* HAVE_LIBEXPAT */ /* Tree packages. */ #ifdef HAVE_LIBEXPAT if (Blt_TreeXmlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_tree_xml", Blt_TreeXmlInit, Blt_TreeXmlInit); #endif /* HAVE_LIBEXPAT */ #endif /* STATIC_PKGS */ #ifndef TCL_ONLY if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Blt_x_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init, Blt_x_SafeInit); #ifdef STATIC_PKGS /* Picture packages. */ if (Blt_PictureBmpInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_bmp", Blt_PictureBmpInit, Blt_PictureBmpInit); if (Blt_PictureGifInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_gif", Blt_PictureGifInit, Blt_PictureGifInit); #ifdef HAVE_LIBJPG if (Blt_PictureJpgInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_jpg", Blt_PictureJpgInit, Blt_PictureJpgInit); #endif /*HAVE_LIBJPG*/ if (Blt_PicturePbmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_pbm", Blt_PicturePbmInit, Blt_PicturePbmInit); if (Blt_PicturePhotoInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_photo", Blt_PicturePhotoInit, Blt_PicturePhotoInit); #ifdef HAVE_LIBPNG if (Blt_PicturePngInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_png", Blt_PicturePngInit, Blt_PicturePngInit); #endif /*HAVE_LIBPNG*/ if (Blt_PicturePsInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_ps", Blt_PicturePsInit, Blt_PicturePsInit); if (Blt_PicturePdfInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_pdf", Blt_PicturePdfInit, Blt_PicturePdfInit); #ifdef HAVE_LIBTIF if (Blt_PictureTifInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_tif", Blt_PictureTifInit, Blt_PictureTifInit); #endif /*HAVE_LIBTIF*/ if (Blt_PictureXbmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_xbm", Blt_PictureXbmInit, Blt_PictureXbmInit); #ifdef HAVE_LIBXPM if (Blt_PictureXpmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_xpm", Blt_PictureXpmInit, Blt_PictureXpmInit); #endif /*HAVE_LIBXPM*/ #endif /* STATIC_PKGS */ #endif /*TCL_ONLY*/ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ #ifdef TCL_ONLY Tcl_SetVar(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY); #else Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY); #endif return TCL_OK; } /* *--------------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tk_Main never returns here, so this procedure never * returns either. * * Side effects: * Whatever the application does. * *--------------------------------------------------------------------------- */ int main(int argc, char **argv) { #ifdef TCL_ONLY Tcl_Main(argc, argv, Initialize); #else Tk_Main(argc, argv, Initialize); #endif return 0; /* Needed only to prevent compiler warning. */ } �����������������������������������������./saods9/blt3.0.1/src/bltPictFmts.h�����������������������������������������������������������������0000644�0001750�0001750�00000010273�11462120062�015434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictFmts.h -- * * This module implements the various image format conversion routines for * picture in the BLT toolkit. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The JPEG reader/writer is adapted from jdatasrc.c and jdatadst.c * in the Independent JPEG Group (version 6b) library distribution. * * The authors make NO WARRANTY or representation, either express * or implied, with respect to this software, its quality, * accuracy, merchantability, or fitness for a particular * purpose. This software is provided "AS IS", and you, its * user, assume the entire risk as to its quality and accuracy. * * This software is copyright (C) 1991-1998, Thomas G. Lane. All * Rights Reserved except as specified below. * * Permission is hereby granted to use, copy, modify, and * distribute this software (or portions thereof) for any * purpose, without fee, subject to these conditions: (1) If any * part of the source code for this software is distributed, then * this README file must be included, with this copyright and * no-warranty notice unaltered; and any additions, deletions, or * changes to the original files must be clearly indicated in * accompanying documentation. (2) If only executable code is * distributed, then the accompanying documentation must state * that "this software is based in part on the work of the * Independent JPEG Group". (3) Permission for use of this * software is granted only if the user accepts full * responsibility for any undesirable consequences; the authors * accept NO LIABILITY for damages of any kind. * * The GIF reader is from converters/other/giftopnm.c in the netpbm * (version 10.19) distribution. * * Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) * Permission to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is * hereby granted, provided that the above copyright notice * appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation. * This software is provided "as is" without express or implied * warranty. * */ #ifndef _BLT_PIC_FMTS_H #define _BLT_PIC_FMTS_H #include <bltChain.h> #define PIC_PROGRESSIVE (1<<0) #define PIC_NOQUANTIZE (1<<1) #define PIC_FMT_ISASCII (1<<3) typedef int (Blt_PictureIsFmtProc)(Blt_DBuffer buffer); typedef Blt_Chain (Blt_PictureReadDataProc)(Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer); typedef Tcl_Obj *(Blt_PictureWriteDataProc)(Tcl_Interp *interp, Blt_Picture picture); typedef Blt_Chain (Blt_PictureImportProc)(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr); typedef int (Blt_PictureExportProc)(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_PictureRegisterFormat(Tcl_Interp *interp, const char *name, Blt_PictureIsFmtProc *isFmtProc, Blt_PictureReadDataProc *readProc, Blt_PictureWriteDataProc *writeProc, Blt_PictureImportProc *importProc, Blt_PictureExportProc *exportProc); BLT_EXTERN Blt_Picture Blt_GetNthPicture(Blt_Chain chain, size_t index); #endif /* _BLT_PIC_FMTS_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrMisc.c�������������������������������������������������������������������0000644�0001750�0001750�00000154436�11462120062�015074� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrMisc.c -- * * This module implements miscellaneous routines for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include <X11/Xutil.h> #include <bltAlloc.h> #include <bltOp.h> #include <stdarg.h> static Blt_OptionParseProc ObjToPoint; static Blt_OptionPrintProc PointToObj; Blt_CustomOption bltPointOption = { ObjToPoint, PointToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToLimitsProc; static Blt_OptionPrintProc LimitsToObjProc; Blt_CustomOption bltLimitsOption = { ObjToLimitsProc, LimitsToObjProc, NULL, (ClientData)0 }; /* *--------------------------------------------------------------------------- * Custom option parse and print procedures *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * Blt_GetXY -- * * Converts a string in the form "@x,y" into an XPoint structure of the x * and y coordinates. * * Results: * A standard TCL result. If the string represents a valid position * *pointPtr* will contain the converted x and y coordinates and TCL_OK * is returned. Otherwise, TCL_ERROR is returned and interp->result will * contain an error message. * *--------------------------------------------------------------------------- */ int Blt_GetXY(Tcl_Interp *interp, Tk_Window tkwin, const char *string, int *xPtr, int *yPtr) { char *comma; int result; int x, y; if ((string == NULL) || (*string == '\0')) { *xPtr = *yPtr = -SHRT_MAX; return TCL_OK; } if (*string != '@') { goto badFormat; } comma = strchr(string + 1, ','); if (comma == NULL) { goto badFormat; } *comma = '\0'; result = ((Tk_GetPixels(interp, tkwin, string + 1, &x) == TCL_OK) && (Tk_GetPixels(interp, tkwin, comma + 1, &y) == TCL_OK)); *comma = ','; if (!result) { Tcl_AppendResult(interp, ": can't parse position \"", string, "\"", (char *)NULL); return TCL_ERROR; } *xPtr = x, *yPtr = y; return TCL_OK; badFormat: Tcl_AppendResult(interp, "bad position \"", string, "\": should be \"@x,y\"", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ObjToPoint -- * * Convert the string representation of a legend XY position into window * coordinates. The form of the string must be "@x,y" or none. * * Results: * A standard TCL result. The symbol type is written into the * widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPoint( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New legend position string */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { XPoint *pointPtr = (XPoint *)(widgRec + offset); int x, y; if (Blt_GetXY(interp, tkwin, Tcl_GetString(objPtr), &x, &y) != TCL_OK) { return TCL_ERROR; } pointPtr->x = x, pointPtr->y = y; return TCL_OK; } /* *--------------------------------------------------------------------------- * * PointToObj -- * * Convert the window coordinates into a string. * * Results: * The string representing the coordinate position is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PointToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { XPoint *pointPtr = (XPoint *)(widgRec + offset); Tcl_Obj *objPtr; if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) { char string[200]; sprintf_s(string, 200, "@%d,%d", pointPtr->x, pointPtr->y); objPtr = Tcl_NewStringObj(string, -1); } else { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToLimitsProc -- * * Converts the list of elements into zero or more pixel values which * determine the range of pixel values possible. An element can be in any * form accepted by Tk_GetPixels. The list has a different meaning based * upon the number of elements. * * # of elements: * * 0 - the limits are reset to the defaults. * 1 - the minimum and maximum values are set to this * value, freezing the range at a single value. * 2 - first element is the minimum, the second is the * maximum. * 3 - first element is the minimum, the second is the * maximum, and the third is the nominal value. * * Any element may be the empty string which indicates the default. * * Results: * The return value is a standard TCL result. The min and max fields * of the range are set. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLimitsProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Widget of paneset */ Tcl_Obj *objPtr, /* New width list */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Blt_Limits *limitsPtr = (Blt_Limits *)(widgRec + offset); if (Blt_GetLimitsFromObj(interp, tkwin, objPtr, limitsPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LimitsToObjProc -- * * Convert the limits of the pixel values allowed into a list. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LimitsToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { Blt_Limits *limitsPtr = (Blt_Limits *)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (limitsPtr->flags & LIMITS_MIN_SET) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->min)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (limitsPtr->flags & LIMITS_MAX_SET) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->max)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (limitsPtr->flags & LIMITS_NOM_SET) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->nom)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } return listObjPtr; } int Blt_PointInSegments( Point2d *samplePtr, Segment2d *segments, int nSegments, double halo) { Segment2d *sp, *send; double minDist; minDist = DBL_MAX; for (sp = segments, send = sp + nSegments; sp < send; sp++) { double dist; double left, right, top, bottom; Point2d p, t; t = Blt_GetProjection((int)samplePtr->x, (int)samplePtr->y, &sp->p, &sp->q); if (sp->p.x > sp->q.x) { right = sp->p.x, left = sp->q.x; } else { right = sp->q.x, left = sp->p.x; } if (sp->p.y > sp->q.y) { bottom = sp->p.y, top = sp->q.y; } else { bottom = sp->q.y, top = sp->p.y; } p.x = BOUND(t.x, left, right); p.y = BOUND(t.y, top, bottom); dist = hypot(p.x - samplePtr->x, p.y - samplePtr->y); if (dist < minDist) { minDist = dist; } } return (minDist < halo); } int Blt_PointInPolygon( Point2d *s, /* Sample point. */ Point2d *points, /* Points representing the polygon. */ int nPoints) /* # of points in above array. */ { Point2d *p, *q, *qend; int count; count = 0; for (p = points, q = p + 1, qend = p + nPoints; q < qend; p++, q++) { if (((p->y <= s->y) && (s->y < q->y)) || ((q->y <= s->y) && (s->y < p->y))) { double b; b = (q->x - p->x) * (s->y - p->y) / (q->y - p->y) + p->x; if (s->x < b) { count++; /* Count the number of intersections. */ } } } return (count & 0x01); } int Blt_RegionInPolygon( Region2d *regionPtr, Point2d *points, int nPoints, int enclosed) { Point2d *pp, *pend; if (enclosed) { /* * All points of the polygon must be inside the rectangle. */ for (pp = points, pend = pp + nPoints; pp < pend; pp++) { if ((pp->x < regionPtr->left) || (pp->x > regionPtr->right) || (pp->y < regionPtr->top) || (pp->y > regionPtr->bottom)) { return FALSE; /* One point is exterior. */ } } return TRUE; } else { Point2d r; /* * If any segment of the polygon clips the bounding region, the * polygon overlaps the rectangle. */ points[nPoints] = points[0]; for (pp = points, pend = pp + nPoints; pp < pend; pp++) { Point2d p, q; p = *pp; q = *(pp + 1); if (Blt_LineRectClip(regionPtr, &p, &q)) { return TRUE; } } /* * Otherwise the polygon and rectangle are either disjoint or * enclosed. Check if one corner of the rectangle is inside the * polygon. */ r.x = regionPtr->left; r.y = regionPtr->top; return Blt_PointInPolygon(&r, points, nPoints); } } /* *--------------------------------------------------------------------------- * * Blt_GraphExtents -- * * Generates a bounding box representing the plotting area of the * graph. This data structure is used to clip the points and line * segments of the line element. * * The clip region is the plotting area plus such arbitrary extra space. * The reason we clip with a bounding box larger than the plot area is so * that symbols will be drawn even if their center point isn't in the * plotting area. * * Results: * None. * * Side Effects: * The bounding box is filled with the dimensions of the plotting area. * *--------------------------------------------------------------------------- */ void Blt_GraphExtents(Graph *graphPtr, Region2d *regionPtr) { regionPtr->left = (double)(graphPtr->hOffset - graphPtr->xPad.side1); regionPtr->top = (double)(graphPtr->vOffset - graphPtr->yPad.side1); regionPtr->right = (double)(graphPtr->hOffset + graphPtr->hRange + graphPtr->xPad.side2); regionPtr->bottom = (double)(graphPtr->vOffset + graphPtr->vRange + graphPtr->yPad.side2); } static int ClipTest (double ds, double dr, double *t1, double *t2) { double t; if (ds < 0.0) { t = dr / ds; if (t > *t2) { return FALSE; } if (t > *t1) { *t1 = t; } } else if (ds > 0.0) { t = dr / ds; if (t < *t1) { return FALSE; } if (t < *t2) { *t2 = t; } } else { /* d = 0, so line is parallel to this clipping edge */ if (dr < 0.0) { /* Line is outside clipping edge */ return FALSE; } } return TRUE; } /* *--------------------------------------------------------------------------- * * Blt_LineRectClip -- * * Clips the given line segment to a rectangular region. The coordinates * of the clipped line segment are returned. The original coordinates * are overwritten. * * Reference: * Liang, Y-D., and B. Barsky, A new concept and method for * Line Clipping, ACM, TOG,3(1), 1984, pp.1-22. * * Results: * Returns if line segment is visible within the region. The coordinates * of the original line segment are overwritten by the clipped * coordinates. * *--------------------------------------------------------------------------- */ int Blt_LineRectClip( Region2d *regionPtr, /* Rectangular region to clip. */ Point2d *p, Point2d *q) /* (in/out) Coordinates of original and * clipped line segment. */ { double t1, t2; double dx, dy; t1 = 0.0, t2 = 1.0; dx = q->x - p->x; if ((ClipTest (-dx, p->x - regionPtr->left, &t1, &t2)) && (ClipTest (dx, regionPtr->right - p->x, &t1, &t2))) { dy = q->y - p->y; if ((ClipTest (-dy, p->y - regionPtr->top, &t1, &t2)) && (ClipTest (dy, regionPtr->bottom - p->y, &t1, &t2))) { if (t2 < 1.0) { q->x = p->x + t2 * dx; q->y = p->y + t2 * dy; } if (t1 > 0.0) { p->x += t1 * dx; p->y += t1 * dy; } return TRUE; } } return FALSE; } /* *--------------------------------------------------------------------------- * * Blt_PolyRectClip -- * * Clips the given polygon to a rectangular region. The resulting * polygon is returned. Note that the resulting polyon may be complex, * connected by zero width/height segments. The drawing routine (such as * XFillPolygon) will not draw a connecting segment. * * Reference: * Liang Y. D. and Brian A. Barsky, "Analysis and Algorithm for * Polygon Clipping", Communications of ACM, Vol. 26, * p.868-877, 1983 * * Results: * Returns the number of points in the clipped polygon. The points of the * clipped polygon are stored in *outputPts*. * *--------------------------------------------------------------------------- */ #define EPSILON FLT_EPSILON #define AddVertex(vx, vy) r->x=(vx), r->y=(vy), r++, count++ #define LastVertex(vx, vy) r->x=(vx), r->y=(vy), count++ int Blt_PolyRectClip( Region2d *regionPtr, /* Rectangular region clipping the polygon. */ Point2d *points, /* Points of polygon to be clipped. */ int nPoints, /* # of points in polygon. */ Point2d *clipPts) /* (out) Points of clipped polygon. */ { Point2d *p; /* First vertex of input polygon edge. */ Point2d *pend; Point2d *q; /* Last vertex of input polygon edge. */ Point2d *r; int count; r = clipPts; count = 0; /* Counts # of vertices in output polygon. */ points[nPoints] = points[0]; for (p = points, q = p + 1, pend = p + nPoints; p < pend; p++, q++) { double dx, dy; double tin1, tin2, tinx, tiny; double xin, yin, xout, yout; dx = q->x - p->x; /* X-direction */ dy = q->y - p->y; /* Y-direction */ if (FABS(dx) < EPSILON) { dx = (p->x > regionPtr->left) ? -EPSILON : EPSILON ; } if (FABS(dy) < EPSILON) { dy = (p->y > regionPtr->top) ? -EPSILON : EPSILON ; } if (dx > 0.0) { /* Left */ xin = regionPtr->left; xout = regionPtr->right + 1.0; } else { /* Right */ xin = regionPtr->right + 1.0; xout = regionPtr->left; } if (dy > 0.0) { /* Top */ yin = regionPtr->top; yout = regionPtr->bottom + 1.0; } else { /* Bottom */ yin = regionPtr->bottom + 1.0; yout = regionPtr->top; } tinx = (xin - p->x) / dx; tiny = (yin - p->y) / dy; if (tinx < tiny) { /* Hits x first */ tin1 = tinx; tin2 = tiny; } else { /* Hits y first */ tin1 = tiny; tin2 = tinx; } if (tin1 <= 1.0) { if (tin1 > 0.0) { AddVertex(xin, yin); } if (tin2 <= 1.0) { double toutx, touty, tout1; toutx = (xout - p->x) / dx; touty = (yout - p->y) / dy; tout1 = MIN(toutx, touty); if ((tin2 > 0.0) || (tout1 > 0.0)) { if (tin2 <= tout1) { if (tin2 > 0.0) { if (tinx > tiny) { AddVertex(xin, p->y + tinx * dy); } else { AddVertex(p->x + tiny * dx, yin); } } if (tout1 < 1.0) { if (toutx < touty) { AddVertex(xout, p->y + toutx * dy); } else { AddVertex(p->x + touty * dx, yout); } } else { AddVertex(q->x, q->y); } } else { if (tinx > tiny) { AddVertex(xin, yout); } else { AddVertex(xout, yin); } } } } } } if (count > 0) { LastVertex(clipPts[0].x, clipPts[0].y); } return count; } /* *--------------------------------------------------------------------------- * * Blt_GetProjection -- * * Computes the projection of a point on a line. The line (given by two * points), is assumed the be infinite. * * Compute the slope (angle) of the line and rotate it 90 degrees. Using * the slope-intercept method (we know the second line from the sample * test point and the computed slope), then find the intersection of both * lines. This will be the projection of the sample point on the first * line. * * Results: * Returns the coordinates of the projection on the line. * *--------------------------------------------------------------------------- */ Point2d Blt_GetProjection( int x, int y, /* Screen coordinates of the sample point. */ Point2d *p, Point2d *q) /* Line segment to project point onto */ { double dx, dy; Point2d t; dx = p->x - q->x; dy = p->y - q->y; /* Test for horizontal and vertical lines */ if (FABS(dx) < DBL_EPSILON) { t.x = p->x, t.y = (double)y; } else if (FABS(dy) < DBL_EPSILON) { t.x = (double)x, t.y = p->y; } else { double m1, m2; /* Slope of both lines */ double b1, b2; /* y-intercepts */ double midX, midY; /* Midpoint of line segment. */ double ax, ay, bx, by; /* Compute the slope and intercept of PQ. */ m1 = (dy / dx); b1 = p->y - (p->x * m1); /* * Compute the slope and intercept of a second line segment: one that * intersects through sample X-Y coordinate with a slope perpendicular * to original line. */ /* Find midpoint of PQ. */ midX = (p->x + q->x) * 0.5; midY = (p->y + q->y) * 0.5; /* Rotate the line 90 degrees */ ax = midX - (0.5 * dy); ay = midY - (0.5 * -dx); bx = midX + (0.5 * dy); by = midY + (0.5 * -dx); m2 = (ay - by) / (ax - bx); b2 = y - (x * m2); /* * Given the equations of two lines which contain the same point, * * y = m1 * x + b1 * y = m2 * x + b2 * * solve for the intersection. * * x = (b2 - b1) / (m1 - m2) * y = m1 * x + b1 * */ t.x = (b2 - b1) / (m1 - m2); t.y = m1 * t.x + b1; } return t; } typedef struct { double hue, sat, val; } HSV; #define SetColor(c,r,g,b) ((c)->red = (int)((r) * 65535.0), \ (c)->green = (int)((g) * 65535.0), \ (c)->blue = (int)((b) * 65535.0)) #ifdef notdef void Blt_XColorToHSV(XColor *colorPtr, HSV *hsvPtr) { unsigned short max, min; double range; unsigned short *colorValues; /* Find the minimum and maximum RGB intensities */ colorValues = (unsigned short *)&colorPtr->red; max = MAX3(colorValues[0], colorValues[1], colorValues[2]); min = MIN3(colorValues[0], colorValues[1], colorValues[2]); hsvPtr->val = (double)max / 65535.0; hsvPtr->hue = hsvPtr->sat = 0.0; range = (double)(max - min); if (max != min) { hsvPtr->sat = range / (double)max; } if (hsvPtr->sat > 0.0) { double red, green, blue; /* Normalize the RGB values */ red = (double)(max - colorPtr->red) / range; green = (double)(max - colorPtr->green) / range; blue = (double)(max - colorPtr->blue) / range; if (colorPtr->red == max) { hsvPtr->hue = (blue - green); } else if (colorPtr->green == max) { hsvPtr->hue = 2 + (red - blue); } else if (colorPtr->blue == max) { hsvPtr->hue = 4 + (green - red); } hsvPtr->hue *= 60.0; } else { hsvPtr->sat = 0.5; } if (hsvPtr->hue < 0.0) { hsvPtr->hue += 360.0; } } void Blt_HSVToXColor(HSV *hsvPtr, XColor *colorPtr) { double hue, p, q, t; double frac; int quadrant; if (hsvPtr->val < 0.0) { hsvPtr->val = 0.0; } else if (hsvPtr->val > 1.0) { hsvPtr->val = 1.0; } if (hsvPtr->sat == 0.0) { SetColor(colorPtr, hsvPtr->val, hsvPtr->val, hsvPtr->val); return; } hue = FMOD(hsvPtr->hue, 360.0) / 60.0; quadrant = (int)floor(hue); frac = hsvPtr->hue - quadrant; p = hsvPtr->val * (1 - (hsvPtr->sat)); q = hsvPtr->val * (1 - (hsvPtr->sat * frac)); t = hsvPtr->val * (1 - (hsvPtr->sat * (1 - frac))); switch (quadrant) { case 0: SetColor(colorPtr, hsvPtr->val, t, p); break; case 1: SetColor(colorPtr, q, hsvPtr->val, p); break; case 2: SetColor(colorPtr, p, hsvPtr->val, t); break; case 3: SetColor(colorPtr, p, q, hsvPtr->val); break; case 4: SetColor(colorPtr, t, p, hsvPtr->val); break; case 5: SetColor(colorPtr, hsvPtr->val, p, q); break; } } #endif /* *--------------------------------------------------------------------------- * * Blt_AdjustViewport -- * * Adjusts the offsets of the viewport according to the scroll mode. * This is to accommodate both "listbox" and "canvas" style scrolling. * * "canvas" The viewport scrolls within the range of world * coordinates. This way the viewport always displays * a full page of the world. If the world is smaller * than the viewport, then (bizarrely) the world and * viewport are inverted so that the world moves up * and down within the viewport. * * "listbox" The viewport can scroll beyond the range of world * coordinates. Every entry can be displayed at the * top of the viewport. This also means that the * scrollbar thumb weirdly shrinks as the last entry * is scrolled upward. * * Results: * The corrected offset is returned. * *--------------------------------------------------------------------------- */ int Blt_AdjustViewport(int offset, int worldSize, int windowSize, int scrollUnits, int scrollMode) { switch (scrollMode) { case BLT_SCROLL_MODE_CANVAS: /* * Canvas-style scrolling allows the world to be scrolled within the * window. */ if (worldSize < windowSize) { if ((worldSize - offset) > windowSize) { offset = worldSize - windowSize; } if (offset > 0) { offset = 0; } } else { if ((offset + windowSize) > worldSize) { offset = worldSize - windowSize; } if (offset < 0) { offset = 0; } } break; case BLT_SCROLL_MODE_LISTBOX: if (offset < 0) { offset = 0; } if (offset >= worldSize) { offset = worldSize - scrollUnits; } break; case BLT_SCROLL_MODE_HIERBOX: /* * Hierbox-style scrolling allows the world to be scrolled within the * window. */ if ((offset + windowSize) > worldSize) { offset = worldSize - windowSize; } if (offset < 0) { offset = 0; } break; } return offset; } int Blt_GetScrollInfoFromObj(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int *offsetPtr, int worldSize, int windowSize, int scrollUnits, int scrollMode) { char c; const char *string; int length; int offset; offset = *offsetPtr; string = Tcl_GetStringFromObj(objv[0], &length); c = string[0]; if ((c == 's') && (strncmp(string, "scroll", length) == 0)) { double fract; int count; if (objc != 3) { return TCL_ERROR; } /* Scroll number unit/page */ if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'u') && (strncmp(string, "units", length) == 0)) { fract = (double)count *scrollUnits; } else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) { /* A page is 90% of the view-able window. */ fract = (double)count * windowSize * 0.9; } else { Tcl_AppendResult(interp, "unknown \"scroll\" units \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } offset += (int)fract; } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) { double fract; if (objc != 2) { return TCL_ERROR; } /* moveto fraction */ if (Tcl_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) { return TCL_ERROR; } offset = (int)(worldSize * fract); } else { double fract; int count; /* Treat like "scroll units" */ if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) { return TCL_ERROR; } fract = (double)count *scrollUnits; offset += (int)fract; } *offsetPtr = Blt_AdjustViewport(offset, worldSize, windowSize, scrollUnits, scrollMode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_UpdateScrollbar -- * * Invoke a TCL command to the scrollbar, defining the new position and * length of the scroll. See the Tk documentation for further information * on the scrollbar. It is assumed the scrollbar command prefix is * valid. * * Results: * None. * * Side Effects: * Scrollbar is commanded to change position and/or size. * *--------------------------------------------------------------------------- */ void Blt_UpdateScrollbar( Tcl_Interp *interp, Tcl_Obj *scrollCmdObjPtr, /* Scrollbar command prefix. May be * several words */ int first, int last, int width) { Tcl_Obj *cmdObjPtr; double firstFract, lastFract; firstFract = 0.0, lastFract = 1.0; if (width > 0) { firstFract = (double)first / (double)width; lastFract = (double)last / (double)width; } cmdObjPtr = Tcl_DuplicateObj(scrollCmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewDoubleObj(firstFract)); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewDoubleObj(lastFract)); Tcl_IncrRefCount(cmdObjPtr); if (Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL) != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DecrRefCount(cmdObjPtr); } /* -------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * Blt_GetPrivateGCFromDrawable -- * * Like Tk_GetGC, but doesn't share the GC with any other widget. This * is needed because the certain GC parameters (like dashes) can not be * set via XCreateGC, therefore there is no way for Tk's hashing * mechanism to recognize that two such GCs differ. * * Results: * A new GC is returned. * *--------------------------------------------------------------------------- */ GC Blt_GetPrivateGCFromDrawable( Display *display, Drawable drawable, unsigned long gcMask, XGCValues *valuePtr) { GC newGC; #ifdef WIN32 newGC = Blt_EmulateXCreateGC(display, drawable, gcMask, valuePtr); #else newGC = XCreateGC(display, drawable, gcMask, valuePtr); #endif return newGC; } /* *--------------------------------------------------------------------------- * * Blt_GetPrivateGC -- * * Like Tk_GetGC, but doesn't share the GC with any other widget. This * is needed because the certain GC parameters (like dashes) can not be * set via XCreateGC, therefore there is no way for Tk's hashing * mechanism to recognize that two such GCs differ. * * Results: * A new GC is returned. * *--------------------------------------------------------------------------- */ GC Blt_GetPrivateGC( Tk_Window tkwin, unsigned long gcMask, XGCValues *valuePtr) { GC gc; Pixmap pixmap; Drawable drawable; Display *display; pixmap = None; drawable = Tk_WindowId(tkwin); display = Tk_Display(tkwin); if (drawable == None) { Drawable root; int depth; root = Tk_RootWindow(tkwin); depth = Tk_Depth(tkwin); if (depth == DefaultDepth(display, Tk_ScreenNumber(tkwin))) { drawable = root; } else { pixmap = Tk_GetPixmap(display, root, 1, 1, depth); drawable = pixmap; Blt_SetDrawableAttribs(display, drawable, 1, 1, depth, Tk_Colormap(tkwin), Tk_Visual(tkwin)); } } gc = Blt_GetPrivateGCFromDrawable(display, drawable, gcMask, valuePtr); if (pixmap != None) { Tk_FreePixmap(display, pixmap); } return gc; } void Blt_FreePrivateGC(Display *display, GC gc) { Tk_FreeXId(display, (XID) XGContextFromGC(gc)); XFreeGC(display, gc); } #ifndef WIN32 void Blt_SetDashes(Display *display, GC gc, Blt_Dashes *dashesPtr) { XSetDashes(display, gc, dashesPtr->offset, (const char *)dashesPtr->values, (int)strlen((char *)dashesPtr->values)); } #endif void Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, unsigned int *yPtr) { Screen *screen; #define MM_INCH 25.4 screen = Tk_Screen(tkwin); *xPtr = (unsigned int)((WidthOfScreen(screen) * MM_INCH) / WidthMMOfScreen(screen)); *yPtr = (unsigned int)((HeightOfScreen(screen) * MM_INCH) / HeightMMOfScreen(screen)); } void Blt_Draw2DSegments( Display *display, Drawable drawable, GC gc, Segment2d *segments, int nSegments) { XSegment *dp, *xsegments; Segment2d *sp, *send; xsegments = Blt_Malloc(nSegments * sizeof(XSegment)); if (xsegments == NULL) { return; } dp = xsegments; for (sp = segments, send = sp + nSegments; sp < send; sp++) { dp->x1 = (short int)sp->p.x; dp->y1 = (short int)sp->p.y; dp->x2 = (short int)sp->q.x; dp->y2 = (short int)sp->q.y; dp++; } XDrawSegments(display, drawable, gc, xsegments, nSegments); Blt_Free(xsegments); } void Blt_DrawArrowOld(Display *display, Drawable drawable, GC gc, int x, int y, int w, int h, int borderWidth, int orientation) { XPoint arrow[4]; int s2, s; int ax, ay; #define ARROW_IPAD 1 w -= 2 * (ARROW_IPAD + borderWidth); h -= 2 * (ARROW_IPAD + borderWidth); x += ARROW_IPAD + borderWidth; y += ARROW_IPAD + borderWidth; w |= 0x01; h |= 0x01; s = MIN(w, h); s2 = s / 2; ax = x + w / 2; ay = y + h / 2; switch (orientation) { case ARROW_UP: ay -= s2/2 + 1; arrow[2].x = arrow[0].x = ax; arrow[2].y = arrow[0].y = ay; arrow[0].x = ax + s2 + 1; arrow[1].x = ax - s2; arrow[0].y = arrow[1].y = ay + s2 + 1; fprintf(stderr, "up arrow %d,%d %d,%d %d,%d\n", arrow[0].x, arrow[0].y, arrow[1].x, arrow[1].y, arrow[2].x, arrow[2].y); break; case ARROW_DOWN: ay -= s2/2; arrow[3].x = arrow[0].x = ax; arrow[3].y = arrow[0].y = ay + s2 + 1; arrow[1].x = ax + s2 + 1; arrow[2].x = ax - s2; arrow[2].y = arrow[1].y = ay; fprintf(stderr, "down arrow %d,%d %d,%d %d,%d\n", arrow[0].x, arrow[0].y, arrow[1].x, arrow[1].y, arrow[2].x, arrow[2].y); break; case ARROW_LEFT: ax -= s2 / 2; arrow[3].x = arrow[0].x = ax; arrow[3].y = arrow[0].y = ay; arrow[1].y = ay - s2; arrow[2].y = ay + s2 + 1; arrow[2].x = arrow[1].x = ax + s2 + 1; break; case ARROW_RIGHT: ax -= s2 / 2; arrow[3].x = arrow[0].x = ax + s2 + 1; arrow[3].y = arrow[0].y = ay; arrow[1].y = ay - s2; arrow[2].y = ay + s2; arrow[2].x = arrow[1].x = ax; break; } XFillPolygon(display, drawable, gc, arrow, 3, Convex, CoordModeOrigin); } void Blt_DrawArrow(Display *display, Drawable drawable, XColor *color, int x, int y, int w, int h, int borderWidth, int orientation) { int s; int s2; int ax, ay; int dx, dy; GC gc; #define ARROW_IPAD 1 w -= 2 * (ARROW_IPAD + borderWidth); h -= 2 * (ARROW_IPAD + borderWidth); x += ARROW_IPAD + borderWidth; y += ARROW_IPAD + borderWidth; s = MIN(w, h); s2 = (s / 2) + 1; ax = x + w / 2; ay = y + h / 2; gc = Tk_GCForColor(color, drawable); switch (orientation) { case ARROW_UP: ay -= s2 / 2; for (dx = 0; dx < s2; dx++, ay++) { XDrawLine(display, drawable, gc, ax - dx, ay, ax + dx, ay); } break; case ARROW_DOWN: ay += s2 / 2; for (dx = 0; dx < s2; dx++, ay--) { XDrawLine(display, drawable, gc, ax - dx, ay, ax + dx, ay); } break; case ARROW_LEFT: ax -= s2 / 2; for (dy = 0; dy < s2; dy++, ax++) { XDrawLine(display, drawable, gc, ax, ay - dy, ax, ay + dy); } break; case ARROW_RIGHT: ax += s2 / 2; for (dy = 0; dy < s2; dy++, ax--) { XDrawLine(display, drawable, gc, ax, ay - dy, ax, ay + dy); } break; } } long Blt_MaxRequestSize(Display *display, size_t elemSize) { static long maxSizeBytes = 0L; if (maxSizeBytes == 0L) { long size; #ifndef WIN32 size = XExtendedMaxRequestSize(display); if (size == 0) { size = XMaxRequestSize(display); } #else size = XMaxRequestSize(display); #endif size -= (4 * elemSize); /* maxSizeBytes = (size * 4); */ maxSizeBytes = size; } return (maxSizeBytes / elemSize); } void Blt_GetLineExtents(size_t nPoints, Point2d *points, Region2d *r) { Point2d *p, *pend; r->top = r->left = DBL_MAX; r->bottom = r->right = -DBL_MAX; for (p = points, pend = p + nPoints; p < pend; p++) { if (r->top > p->y) { r->top = p->y; } if (r->bottom < p->y) { r->bottom = p->y; } if (r->left > p->x) { r->left = p->x; } if (r->right < p->x) { r->right = p->x; } } } #undef Blt_Fill3DRectangle void Blt_Fill3DRectangle( Tk_Window tkwin, /* Window for which border was allocated. */ Drawable drawable, /* X window or pixmap in which to draw. */ Tk_3DBorder border, /* Token for border to draw. */ int x, int y, int width, int height, /* Outside area of rectangular region. */ int borderWidth, /* Desired width for border, in pixels. Border * will be *inside* region. */ int relief) /* Indicates 3D effect: TK_RELIEF_FLAT, * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */ { #ifndef notdef if ((borderWidth > 1) && (width > 2) && (height > 2) && ((relief == TK_RELIEF_SUNKEN) || (relief == TK_RELIEF_RAISED))) { GC lightGC, darkGC; int x2, y2; x2 = x + width - 1; y2 = y + height - 1; #define TK_3D_LIGHT2_GC TK_3D_DARK_GC+1 #define TK_3D_DARK2_GC TK_3D_DARK_GC+2 if (relief == TK_RELIEF_RAISED) { lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC); #ifdef notdef darkGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); #endif } else { lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC); #ifdef notdef lightGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); #endif darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); } XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x2, y); XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x2, y); XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x, y2); XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x, y2); x++, y++, width -= 2, height -= 2, borderWidth--; } #endif Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief); } #undef Blt_Draw3DRectangle void Blt_Draw3DRectangle( Tk_Window tkwin, /* Window for which border was allocated. */ Drawable drawable, /* X window or pixmap in which to draw. */ Tk_3DBorder border, /* Token for border to draw. */ int x, int y, int width, int height, /* Outside area of rectangular region. */ int borderWidth, /* Desired width for border, in pixels. Border * will be *inside* region. */ int relief) /* Indicates 3D effect: TK_RELIEF_FLAT, * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */ { #ifndef notdef if ((borderWidth > 1) && (width > 2) && (height > 2) && ((relief == TK_RELIEF_SUNKEN) || (relief == TK_RELIEF_RAISED))) { GC lightGC, darkGC; int x2, y2; x2 = x + width - 1; y2 = y + height - 1; if (relief == TK_RELIEF_RAISED) { lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC); #ifdef notdef darkGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); #endif } else { lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC); #ifdef notdef lightGC = DefaultGC(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); #endif darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); } XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x2, y); XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x2, y); XDrawLine(Tk_Display(tkwin), drawable, darkGC, x2, y2, x, y2); XDrawLine(Tk_Display(tkwin), drawable, lightGC, x, y, x, y2); x++, y++, width -= 2, height -= 2, borderWidth--; } #endif Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief); } #ifdef notdef typedef struct { Screen *screen; Visual *visual; Colormap colormap; Tk_Uid nameUid; } BorderKey; typedef struct { Screen *screen; /* Screen on which the border will be used. */ Visual *visual; /* Visual for all windows and pixmaps using * the border. */ int depth; /* Number of bits per pixel of drawables where * the border will be used. */ Colormap colormap; /* Colormap out of which pixels are * allocated. */ int refCount; /* Number of active uses of this color (each * active use corresponds to a call to * Blt_Get3DBorder). If this count is 0, then * this structure is no longer valid and it * isn't present in borderTable: it is being * kept around only because there are objects * referring to it. The structure is freed * when refCount is 0. */ XColor *bgColorPtr; /* Color of face. */ XColor *shadows[4]; Pixmap darkStipple; /* Stipple pattern to use for drawing shadows * areas. Used for displays with <= 64 colors * or where colormap has filled up. */ Pixmap lightStipple; /* Stipple pattern to use for drawing shadows * areas. Used for displays with <= 64 colors * or where colormap has filled up. */ GC bgGC; /* Used (if necessary) to draw areas in the * background color. */ GC lightGC, darkGC; Tcl_HashEntry *hashPtr; /* Entry in borderTable (needed in order to * delete structure). */ struct _Blt_3DBorder *nextPtr; } Border, *Blt_3DBorder; void Blt_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) Tk_Window tkwin; /* Window for which border was allocated. */ Drawable drawable; /* X window or pixmap in which to draw. */ Blt_3DBorder *borderPtr; /* Border to draw. */ int x, y, width, height; /* Outside area of rectangular region. */ int borderWidth; /* Desired width for border, in * pixels. Border will be *inside* region. */ int relief; /* Indicates 3D effect: TK_RELIEF_FLAT, * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */ { if ((width > (2 * borderWidth)) && (height > (2 * borderWidth))) { int x2, y2; int i; x2 = x + width - 1; y2 = y + height - 1; XSetForeground(borderPtr->lightGC, borderPtr->shadows[0]); XSetForeground(borderPtr->darkGC, borderPtr->shadows[3]); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, x, y, x2, y); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, x, y, x, y2); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, x2, y, x2, y2); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, x2, y2, x, y2); XSetForeground(borderPtr->lightGC, borderPtr->shadows[1]); XSetForeground(borderPtr->darkGC, borderPtr->shadows[2]); for (i = 1; i < (borderWidth - 1); i++) { /* * +---------- * |+------- * ||+----- * ||| * ||| * || * | */ x++, y++, x2--, y2--; XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, x, y, x2, y); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->lightGC, x, y, x, y2); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, x2, y, x2, y2); XDrawLine(Tk_Display(tkwin), drawable, borderPtr->darkGC, x2, y2, x, y2); } } } void Blt_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) Tk_Window tkwin; /* Window for which border was allocated. */ Drawable drawable; /* X window or pixmap in which to draw. */ Tk_3DBorder border; /* Token for border to draw. */ int x, y, width, height; /* Outside area of rectangular region. */ int borderWidth; /* Desired width for border, in * pixels. Border will be *inside* region. */ int relief; /* Indicates 3D effect: TK_RELIEF_FLAT, * TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */ { Blt_3DBorder *borderPtr; XFillRectangle(Tk_Display(tkwin), drawable, borderPtr->bgGC, x, y, width, height); if ((borderWidth > 0) && (relief != BLT_RELIEF_FLAT)) { Blt_Draw3DRectangle(tkwin, drawable, borderPtr, x, y, width, height, borderWidth, relief); } } void FreeBorder(display, borderPtr) Display *display; Border *borderPtr; { int i; if (borderPtr->bgColorPtr != NULL) { Tk_FreeColor(display, borderPtr->bgColorPtr); } for (i = 0; i < 4; i++) { Tk_FreeColor(display, borderPtr->shadows[i]); } if (borderPtr->darkGC != NULL) { Blt_FreePrivateGC(display, borderPtr->darkGC); } if (borderPtr->lightGC != NULL) { Blt_FreePrivateGC(tkwin, borderPtr->lightGC); } if (borderPtr->bgGC != NULL) { Blt_FreePrivateGC(tkwin, borderPtr->bgGC); } Blt_Free(borderPtr); } void Blt_Free3DBorder(display, border) Display *display; Blt_3DBorder border; { Border *borderPtr = (Border *)border; borderPtr->refCount--; if (borderPtr->refCount >= 0) { /* Search for the border in the bucket. Start at the head. */ headPtr = Blt_GetHashValue(borderPtr->hashPtr); lastPtr = NULL; while ((headPtr != borderPtr) && (headPtr != NULL)) { lastPtr = headPtr; headPtr = headPtr->next; } if (headPtr == NULL) { return; /* This can't happen. It means that we could * not find the border. */ } if (lastPtr != NULL) { lastPtr->next = borderPtr->next; } else { Tcl_DeleteHashEntry(borderPtr->hashPtr); } FreeBorder(display, borderPtr); } } Blt_3DBorder * Blt_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin, const char *borderName) { Blt_3DBorder *borderPtr, *lastBorderPtr; Blt_HashEntry *hPtr; XColor *bgColorPtr; char **argv; const char *colorName; int argc; int isNew; lastBorderPtr = NULL; hPtr = Tcl_CreateHashEntry(&dataPtr->borderTable, borderName, &isNew); if (!isNew) { borderPtr = lastBorderPtr = Blt_GetHashValue(hPtr); while (borderPtr != NULL) { if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->refCount++; return borderPtr; } borderPtr = borderPtr->nextPtr; } } /* Create a new border. */ argv = NULL; bgColorPtr = NULL; if (Tcl_SplitList(interp, borderName, &argc, &argv) != TCL_OK) { goto error; } colorName = borderName; bgColorPtr = Tk_GetColor(interp, tkwin, colorName); if (bgColorPtr == NULL) { goto error; } /* Create a new border */ borderPtr = Blt_AssertCalloc(1, sizeof(Blt_3DBorder)); borderPtr->screen = Tk_Screen(tkwin); borderPtr->visual = Tk_Visual(tkwin); borderPtr->depth = Tk_Depth(tkwin); borderPtr->colormap = Tk_Colormap(tkwin); borderPtr->refCount = 1; borderPtr->bgColorPtr = bgColorPtr; borderPtr->darkGC = Blt_GetPrivateGC(tkwin, 0, NULL); borderPtr->lightGC = Blt_GetPrivateGC(tkwin, 0, NULL); borderPtr->hashPtr = lastBorderPtr->hashPtr; lastBorderPtr->nextPtr = lastBorderPtr; { HSV hsv; XColor color; double sat, sat0, diff, step, hstep; int count; /* Convert the face (background) color to HSV */ Blt_XColorToHSV(borderPtr->bgColorPtr, &hsv); /* Using the color as the baseline intensity, pick a set of colors * around the intensity. */ #define UFLOOR(x,u) (floor((x)*(u))/(u)) diff = hsv.sat - UFLOOR(hsv.sat, 0.2); sat = 0.1 + (diff - 0.1); sat0 = hsv.sat; count = 0; for (sat = 0.1 + (diff - 0.1); sat <= 1.0; sat += 0.2) { if (FABS(sat0 - sat) >= 0.1) { hsv.sat = sat; Blt_HSVToXColor(&hsv, &color); borderPtr->shadows[count] = Tk_GetColorByValue(tkwin, &color); count++; } } } Blt_SetHashValue(hPtr, borderPtr); if (argv != NULL) { Blt_Free(argv); } return TCL_OK; error: if (argv != NULL) { Blt_Free(argv); } if (bgColorPtr != NULL) { Tk_FreeColor(bgColorPtr); } if (isNew) { Blt_DeleteHashEntry(&borderTable, hPtr); } return NULL; } #endif typedef struct { float x, y, z; } Vector3f; typedef struct { float x, y, z, w; } Vector4f; typedef Vector4f Quaternion; typedef float Matrix3x3f[3][3]; typedef struct _ArcBall { Vector3f click; Vector3f drag; float xScale; float yScale; } ArcBall; /* * Arcball sphere constants: * Diameter is 2.0f * Radius is 1.0f * Radius squared is 1.0f */ /* assuming IEEE-754 (float), which i believe has max precision of 7 bits */ #define EPSILON FLT_EPSILON static INLINE float LengthVector3f(Vector3f *a) { return sqrtf((a->x * a->x) + (a->y * a->y) + (a->z * a->z)); } static INLINE float DotProductVector3f(Vector3f *a, Vector3f *b) { return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); } /** * Calculate the cross product of two 3D vectors: c = a x b. * "c" must not refer to the same memory location as "a" or "b". */ static INLINE void CrossProductVector3f(Vector3f *a, Vector3f *b, Vector3f *c) { c->x = (a->y * b->z) - (b->y * a->z); c->y = (a->z * b->x) - (b->z * a->x); c->z = (a->x * b->y) - (b->x * a->y); } static void PointOnSphere (ArcBall *arcPtr, float x, float y, Vector3f *outPtr) { float sx, sy; float d; /* Adjust point coords and scale down to range of [-1 ... 1] */ sx = (x * arcPtr->xScale) - 1.0f; sy = 1.0f - (y * arcPtr->yScale); /* Compute the square of the length of the vector to the point from the * center. */ d = (sx * sx) + (sy * sy); /* If the point is mapped outside of the sphere ... * (length > radius squared) */ if (d > 1.0f) { float scale; /* Compute a normalizing factor (radius / sqrt(length)) */ scale = 1.0f / sqrt (d); /* Return the "normalized" vector, a point on the sphere */ outPtr->x = sx * scale; outPtr->y = sy * scale; outPtr->z = 0.0f; } else { /* else it's on the inside */ /* Return a vector to a point mapped inside the sphere * sqrt(radius squared - length) */ outPtr->x = sx; outPtr->y = sy; outPtr->z = sqrtf(1.0f - d); } } static void SetArcBallBounds(ArcBall *arcPtr, float w, float h) { if (w <= 1.0f ) { w = 2.0f; } if (h <= 1.0f ) { h = 2.0f; } /* Set adjustment factor for width/height */ arcPtr->xScale = 1.0f / ((w - 1.0f) * 0.5f); arcPtr->yScale = 1.0f / ((h - 1.0f) * 0.5f); } static ArcBall * CreateArcBall (float w, float h) { ArcBall *arcPtr; arcPtr = Blt_AssertCalloc(1, sizeof(ArcBall)); SetArcBallBounds (arcPtr, w, h); return arcPtr; } static void DestroyArcBall(ArcBall *arcPtr) { if (arcPtr != NULL) { Blt_Free(arcPtr); } } /* Mouse down: Supply mouse position in x and y */ static void ArcBallOnClick(ArcBall *arcPtr, float x, float y) { PointOnSphere (arcPtr, x, y, &arcPtr->click); } /* Mouse drag, calculate rotation: Supply mouse position in x and y */ static void ArcBallOnDrag(ArcBall *arcPtr, float x, float y, Quaternion *outPtr) { /* Map the point to the sphere */ PointOnSphere(arcPtr, x, y, &arcPtr->drag); /* Return the quaternion equivalent to the rotation */ if (outPtr != NULL) { Vector3f perp; /* Compute the vector perpendicular to the begin and end vectors */ CrossProductVector3f(&arcPtr->drag, &arcPtr->click, &perp); /* Compute the length of the perpendicular vector */ if (LengthVector3f(&perp) > FLT_EPSILON) { /* If its non-zero, we're ok, so return the perpendicular * vector as the transform after all */ outPtr->x = perp.x; outPtr->y = perp.y; outPtr->z = perp.z; /* In the quaternion values, w is cosine (theta / 2), * where theta is rotation angle */ outPtr->w = DotProductVector3f(&arcPtr->click, &arcPtr->drag); } else { /* If it is zero, the begin and end vectors coincide, * so return an identity transform */ outPtr->x = outPtr->y = outPtr->z = outPtr->z = 0.0f; } } } static INLINE void SetRotationMatrix(const Quaternion* q, Matrix3x3f mat) { float n, s; float xs, ys, zs; float wx, wy, wz; float xx, xy, xz; float yy, yz, zz; assert(mat && q); n = (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); s = (n > 0.0f) ? (2.0f / n) : 0.0f; xs = q->x * s; ys = q->y * s; zs = q->z * s; wx = q->w * xs; wy = q->w * ys; wz = q->w * zs; xx = q->x * xs; xy = q->x * ys; xz = q->x * zs; yy = q->y * ys; yz = q->y * zs; zz = q->z * zs; mat[0][0] = 1.0f - (yy + zz); mat[0][1] = xy - wz; mat[0][2] = xz + wy; mat[1][0] = xy + wz; mat[1][1] = 1.0f - (xx + zz); mat[1][2] = yz - wx; mat[2][0] = xz - wy; mat[2][1] = yz + wx; mat[2][2] = 1.0f - (xx + yy); } /* Return quaternion product qL * qR. Note: order is important! * To combine rotations, use the product Mul(Second, First), * which gives the effect of rotating by First then Second. */ static INLINE void CombineRotations(Quaternion *a, Quaternion *b, Quaternion *result) { result->w = (a->w * b->w) - (a->x * b->x) - (a->y * b->y) - (a->z * b->z); result->x = (a->w * b->x) + (a->x * b->w) + (a->y * b->z) - (a->z * b->y); result->y = (a->w * b->y) + (a->y * b->w) + (a->z * b->x) - (a->x * b->z); result->z = (a->w * b->z) + (a->z * b->w) + (a->x * b->y) - (a->y * b->x); } static int GetQuaternionFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Quaternion *q) { Tcl_Obj **objv; int objc; double x, y, z, w; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc != 4) { Tcl_AppendResult(interp, "wrong number of elements in quaternion \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetDoubleFromObj(interp, objv[0], &x) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[1], &y) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[2], &z) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[3], &w) != TCL_OK)) { return TCL_ERROR; } q->x = x, q->y = y, q->z = z, q->w = w; return TCL_OK; } static int ArcBallCombineOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Quaternion q1, q2, r; if (GetQuaternionFromObj(interp, objv[2], &q1) != TCL_OK) { return TCL_ERROR; } if (GetQuaternionFromObj(interp, objv[3], &q2) != TCL_OK) { return TCL_ERROR; } CombineRotations(&q2, &q1, &r); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(r.x)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(r.y)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(r.w)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(r.z)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static int ArcBallRotateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ArcBall *arcPtr; Tcl_Obj *listObjPtr; Quaternion q; double x1, y1, x2, y2; int w, h; if ((Tcl_GetIntFromObj(interp, objv[2], &w) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &h) != TCL_OK)) { return TCL_ERROR; } if ((Tcl_GetDoubleFromObj(interp, objv[4], &x1) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[5], &y1) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[6], &x2) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[7], &y2) != TCL_OK)) { return TCL_ERROR; } arcPtr = CreateArcBall((float)w, (float)h); ArcBallOnClick(arcPtr, x1, y1); ArcBallOnDrag(arcPtr, x2, y2, &q); DestroyArcBall(arcPtr); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(q.x)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(q.y)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(q.w)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(q.z)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static int ArcBallMatrixOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Matrix3x3f rot; Tcl_Obj *listObjPtr; Quaternion q; if (GetQuaternionFromObj(interp, objv[2], &q) != TCL_OK) { return TCL_ERROR; } SetRotationMatrix(&q, rot); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[0][0])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[0][1])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[0][2])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[1][0])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[1][1])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[1][2])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[2][0])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[2][1])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(rot[2][2])); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static Blt_OpSpec arcBallOps[] = { {"combine", 1, ArcBallCombineOp, 4, 4, "quat1 quat2",}, {"matrix", 1, ArcBallMatrixOp, 3, 3, "quat",}, {"rotate", 1, ArcBallRotateOp, 8, 8, "w h x1 y1 x2 y2",}, }; static int nArcBallOps = sizeof(arcBallOps) / sizeof(Blt_OpSpec); static int ArcBallCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nArcBallOps, arcBallOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } #undef Tk_GetPixmap Pixmap Blt_GetPixmap(Display *display, Drawable drawable, int w, int h, int depth, int lineNum, const char *fileName) { if (w <= 0) { fprintf(stderr, "line %d of %s: width is %d\n", lineNum, fileName, w); abort(); } if (h <= 0) { fprintf(stderr, "line %d of %s: height is %d\n", lineNum, fileName, h); abort(); } return Tk_GetPixmap(display, drawable, w, h, depth); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrElem.c�������������������������������������������������������������������0000644�0001750�0001750�00000203774�11462120062�015063� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrElem.c -- * * This module implements generic elements for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" #include "bltChain.h" #include <X11/Xutil.h> #include <bltDataTable.h> #define GRAPH_KEY "BLT Graph Data" /* Ignore elements that aren't in the display list or have been deleted. */ #define IGNORE_ELEMENT(e) (((e)->link == NULL) || ((e)->flags & DELETE_PENDING)) typedef struct { Blt_Table table; int refCount; } TableClient; static Blt_OptionParseProc ObjToAlong; static Blt_OptionPrintProc AlongToObj; static Blt_CustomOption alongOption = { ObjToAlong, AlongToObj, NULL, (ClientData)0 }; static Blt_OptionFreeProc FreeValues; static Blt_OptionParseProc ObjToValues; static Blt_OptionPrintProc ValuesToObj; Blt_CustomOption bltValuesOption = { ObjToValues, ValuesToObj, FreeValues, (ClientData)0 }; static Blt_OptionFreeProc FreeValuePairs; static Blt_OptionParseProc ObjToValuePairs; static Blt_OptionPrintProc ValuePairsToObj; Blt_CustomOption bltValuePairsOption = { ObjToValuePairs, ValuePairsToObj, FreeValuePairs, (ClientData)0 }; static Blt_OptionFreeProc FreeStyles; static Blt_OptionParseProc ObjToStyles; static Blt_OptionPrintProc StylesToObj; Blt_CustomOption bltLineStylesOption = { ObjToStyles, StylesToObj, FreeStyles, (ClientData)0, }; Blt_CustomOption bltBarStylesOption = { ObjToStyles, StylesToObj, FreeStyles, (ClientData)0, }; #include "bltGrElem.h" static Blt_VectorChangedProc VectorChangedProc; static void FindRange(ElemValues *valuesPtr); static void FreeDataValues(ElemValues *valuesPtr); static Tcl_FreeProc FreeElement; typedef int (GraphElementProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * Blt_DestroyTableClients -- * *--------------------------------------------------------------------------- */ /* ARGSUSED */ void Blt_DestroyTableClients(Graph *graphPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->dataTables, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { TableClient *clientPtr; clientPtr = Blt_GetHashValue(hPtr); if (clientPtr->table != NULL) { Blt_Table_Close(clientPtr->table); } Blt_Free(clientPtr); } Blt_DeleteHashTable(&graphPtr->dataTables); } /* *--------------------------------------------------------------------------- * Custom option parse and print procedures *--------------------------------------------------------------------------- */ static int GetPenStyleFromObj( Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, PenStyle *stylePtr) { Pen *penPtr; Tcl_Obj **objv; int objc; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if ((objc != 1) && (objc != 3)) { if (interp != NULL) { Tcl_AppendResult(interp, "bad style entry \"", Tcl_GetString(objPtr), "\": should be \"penName\" or \"penName min max\"", (char *)NULL); } return TCL_ERROR; } if (Blt_GetPenFromObj(interp, graphPtr, objv[0], classId, &penPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { double min, max; if ((Tcl_GetDoubleFromObj(interp, objv[1], &min) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[2], &max) != TCL_OK)) { return TCL_ERROR; } SetWeight(stylePtr->weight, min, max); } stylePtr->penPtr = penPtr; return TCL_OK; } static void FreeVectorSource(ElemValues *valuesPtr) { if (valuesPtr->vectorSource.vector != NULL) { Blt_SetVectorChangedProc(valuesPtr->vectorSource.vector, NULL, NULL); Blt_FreeVectorId(valuesPtr->vectorSource.vector); valuesPtr->vectorSource.vector = NULL; } } static int FetchVectorValues(Tcl_Interp *interp, ElemValues *valuesPtr, Blt_Vector *vector) { double *array; if (valuesPtr->values == NULL) { array = Blt_Malloc(Blt_VecLength(vector) * sizeof(double)); } else { array = Blt_Realloc(valuesPtr->values, Blt_VecLength(vector) * sizeof(double)); } if (array == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); } return TCL_ERROR; } memcpy(array, Blt_VecData(vector), sizeof(double) * Blt_VecLength(vector)); valuesPtr->min = Blt_VecMin(vector); valuesPtr->max = Blt_VecMax(vector); valuesPtr->values = array; valuesPtr->nValues = Blt_VecLength(vector); /* FindRange(valuesPtr); */ return TCL_OK; } /* *--------------------------------------------------------------------------- * * VectorChangedProc -- * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static void VectorChangedProc( Tcl_Interp *interp, ClientData clientData, Blt_VectorNotify notify) { ElemValues *valuesPtr = clientData; if (notify == BLT_VECTOR_NOTIFY_DESTROY) { FreeDataValues(valuesPtr); } else { Blt_Vector *vector; Blt_GetVectorById(interp, valuesPtr->vectorSource.vector, &vector); if (FetchVectorValues(NULL, valuesPtr, vector) != TCL_OK) { return; } } { Element *elemPtr = valuesPtr->elemPtr; Graph *graphPtr; graphPtr = elemPtr->obj.graphPtr; graphPtr->flags |= RESET_AXES; elemPtr->flags |= MAP_ITEM; if (!IGNORE_ELEMENT(elemPtr)) { graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } } } static int GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr, const char *vecName) { Blt_Vector *vecPtr; VectorDataSource *srcPtr; srcPtr = &valuesPtr->vectorSource; srcPtr->vector = Blt_AllocVectorId(interp, vecName); if (Blt_GetVectorById(interp, srcPtr->vector, &vecPtr) != TCL_OK) { return TCL_ERROR; } if (FetchVectorValues(interp, valuesPtr, vecPtr) != TCL_OK) { FreeVectorSource(valuesPtr); return TCL_ERROR; } Blt_SetVectorChangedProc(srcPtr->vector, VectorChangedProc, valuesPtr); valuesPtr->type = ELEM_SOURCE_VECTOR; return TCL_OK; } static int FetchTableValues(Tcl_Interp *interp, ElemValues *valuesPtr, Blt_TableColumn col) { long i, j; double *array; Blt_Table table; table = valuesPtr->tableSource.table; array = Blt_Malloc(sizeof(double) * Blt_Table_NumRows(table)); if (array == NULL) { return TCL_ERROR; } for (j = 0, i = 1; i <= Blt_Table_NumRows(table); i++) { Blt_TableRow row; double value; row = Blt_Table_FindRowByIndex(table, i); value = Blt_Table_GetDouble(table, row, col); if (FINITE(value)) { array[j] = value; j++; } } if (valuesPtr->values != NULL) { Blt_Free(valuesPtr->values); } valuesPtr->nValues = j; valuesPtr->values = array; FindRange(valuesPtr); return TCL_OK; } static void FreeTableSource(ElemValues *valuesPtr) { TableDataSource *srcPtr; srcPtr = &valuesPtr->tableSource; if (srcPtr->trace != NULL) { Blt_Table_DeleteTrace(srcPtr->trace); } if (srcPtr->notifier != NULL) { Blt_Table_DeleteNotifier(srcPtr->notifier); } if (srcPtr->hashPtr != NULL) { TableClient *clientPtr; clientPtr = Blt_GetHashValue(srcPtr->hashPtr); clientPtr->refCount--; if (clientPtr->refCount == 0) { Graph *graphPtr; graphPtr = valuesPtr->elemPtr->obj.graphPtr; if (srcPtr->table != NULL) { Blt_Table_Close(srcPtr->table); } Blt_Free(clientPtr); Blt_DeleteHashEntry(&graphPtr->dataTables, srcPtr->hashPtr); srcPtr->hashPtr = NULL; } } } /* *--------------------------------------------------------------------------- * * TableNotifyProc -- * * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static int TableNotifyProc(ClientData clientData, Blt_TableNotifyEvent *eventPtr) { ElemValues *valuesPtr = clientData; Element *elemPtr; Graph *graphPtr; elemPtr = valuesPtr->elemPtr; graphPtr = elemPtr->obj.graphPtr; if ((eventPtr->type == TABLE_NOTIFY_COLUMN_DELETED) || (FetchTableValues(graphPtr->interp, valuesPtr, (Blt_TableColumn)eventPtr->header)) != TCL_OK) { FreeTableSource(valuesPtr); return TCL_ERROR; } /* Always redraw the element. */ graphPtr->flags |= RESET_AXES; elemPtr->flags |= MAP_ITEM; if (!IGNORE_ELEMENT(elemPtr)) { graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TableTraceProc -- * * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static int TableTraceProc(ClientData clientData, Blt_TableTraceEvent *eventPtr) { ElemValues *valuesPtr = clientData; Element *elemPtr; Graph *graphPtr; elemPtr = valuesPtr->elemPtr; graphPtr = elemPtr->obj.graphPtr; assert((Blt_TableColumn)eventPtr->column == valuesPtr->tableSource.column); if (FetchTableValues(eventPtr->interp, valuesPtr, eventPtr->column) != TCL_OK) { FreeTableSource(valuesPtr); return TCL_ERROR; } graphPtr->flags |= RESET_AXES; elemPtr->flags |= MAP_ITEM; if (!IGNORE_ELEMENT(elemPtr)) { graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } return TCL_OK; } static int GetTableData(Tcl_Interp *interp, ElemValues *valuesPtr, const char *tableName, Tcl_Obj *colObjPtr) { TableDataSource *srcPtr; TableClient *clientPtr; int isNew; Graph *graphPtr; memset(&valuesPtr->tableSource, 0, sizeof(TableDataSource)); srcPtr = &valuesPtr->tableSource; graphPtr = valuesPtr->elemPtr->obj.graphPtr; /* See if the graph is already using this table. */ srcPtr->hashPtr = Blt_CreateHashEntry(&graphPtr->dataTables, tableName, &isNew); if (isNew) { if (Blt_Table_Open(interp, tableName, &srcPtr->table) != TCL_OK) { return TCL_ERROR; } clientPtr = Blt_AssertMalloc(sizeof(TableClient)); clientPtr->table = srcPtr->table; clientPtr->refCount = 1; Blt_SetHashValue(srcPtr->hashPtr, clientPtr); } else { clientPtr = Blt_GetHashValue(srcPtr->hashPtr); srcPtr->table = clientPtr->table; clientPtr->refCount++; } srcPtr->column = Blt_Table_FindColumn(interp, srcPtr->table, colObjPtr); if (srcPtr->column == NULL) { goto error; } if (FetchTableValues(interp, valuesPtr, srcPtr->column) != TCL_OK) { goto error; } srcPtr->notifier = Blt_Table_CreateColumnNotifier(interp, srcPtr->table, srcPtr->column, TABLE_NOTIFY_COLUMN_CHANGED, TableNotifyProc, (Blt_TableNotifierDeleteProc *)NULL, valuesPtr); srcPtr->trace = Blt_Table_CreateColumnTrace(srcPtr->table, srcPtr->column, (TABLE_TRACE_WRITES | TABLE_TRACE_UNSETS | TABLE_TRACE_CREATES), TableTraceProc, (Blt_TableTraceDeleteProc *)NULL, valuesPtr); valuesPtr->type = ELEM_SOURCE_TABLE; return TCL_OK; error: FreeTableSource(valuesPtr); return TCL_ERROR; } static int ParseValues(Tcl_Interp *interp, Tcl_Obj *objPtr, int *nValuesPtr, double **arrayPtr) { int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } *arrayPtr = NULL; *nValuesPtr = 0; if (objc > 0) { double *array; double *p; int i; array = Blt_Malloc(sizeof(double) * objc); if (array == NULL) { Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); return TCL_ERROR; } for (p = array, i = 0; i < objc; i++, p++) { if (Blt_ExprDoubleFromObj(interp, objv[i], p) != TCL_OK) { Blt_Free(array); return TCL_ERROR; } } *arrayPtr = array; *nValuesPtr = objc; } return TCL_OK; } static void FreeDataValues(ElemValues *valuesPtr) { switch (valuesPtr->type) { case ELEM_SOURCE_VECTOR: FreeVectorSource(valuesPtr); break; case ELEM_SOURCE_TABLE: FreeTableSource(valuesPtr); break; case ELEM_SOURCE_VALUES: break; } if (valuesPtr->values != NULL) { Blt_Free(valuesPtr->values); } valuesPtr->values = NULL; valuesPtr->nValues = 0; valuesPtr->type = ELEM_SOURCE_VALUES; } /* *--------------------------------------------------------------------------- * * FindRange -- * * Find the minimum, positive minimum, and maximum values in a given * vector and store the results in the vector structure. * * Results: * None. * * Side Effects: * Minimum, positive minimum, and maximum values are stored in the * vector. * *--------------------------------------------------------------------------- */ static void FindRange(ElemValues *valuesPtr) { int i; double *x; double min, max; if ((valuesPtr->nValues < 1) || (valuesPtr->values == NULL)) { return; /* This shouldn't ever happen. */ } x = valuesPtr->values; min = DBL_MAX, max = -DBL_MAX; for(i = 0; i < valuesPtr->nValues; i++) { if (FINITE(x[i])) { min = max = x[i]; break; } } /* Initialize values to track the vector range */ for (/* empty */; i < valuesPtr->nValues; i++) { if (FINITE(x[i])) { if (x[i] < min) { min = x[i]; } else if (x[i] > max) { max = x[i]; } } } valuesPtr->min = min, valuesPtr->max = max; } /* *--------------------------------------------------------------------------- * * Blt_FindElemValuesMinimum -- * * Find the minimum, positive minimum, and maximum values in a given * vector and store the results in the vector structure. * * Results: * None. * * Side Effects: * Minimum, positive minimum, and maximum values are stored in the * vector. * *--------------------------------------------------------------------------- */ double Blt_FindElemValuesMinimum(ElemValues *valuesPtr, double minLimit) { int i; double min; min = DBL_MAX; for (i = 0; i < valuesPtr->nValues; i++) { double x; x = valuesPtr->values[i]; if (x < 0.0) { /* What do you do about negative values when using log * scale values seems like a grey area. Mirror. */ x = -x; } if ((x > minLimit) && (min > x)) { min = x; } } if (min == DBL_MAX) { min = minLimit; } return min; } /*ARGSUSED*/ static void FreeValues( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { ElemValues *valuesPtr = (ElemValues *)(widgRec + offset); FreeDataValues(valuesPtr); } /* *--------------------------------------------------------------------------- * * ObjToValues -- * * Given a TCL list of numeric expression representing the element * values, convert into an array of double precision values. In addition, * the minimum and maximum values are saved. Since elastic values are * allow (values which translate to the min/max of the graph), we must * try to get the non-elastic minimum and maximum. * * Results: * The return value is a standard TCL result. The vector is passed * back via the valuesPtr. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToValues( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* TCL list of expressions */ char *widgRec, /* Element record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { ElemValues *valuesPtr = (ElemValues *)(widgRec + offset); Element *elemPtr = (Element *)widgRec; Tcl_Obj **objv; int objc; int result; const char *string; valuesPtr->elemPtr = elemPtr; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } elemPtr->flags |= MAP_ITEM; /* Release the current data sources. */ FreeDataValues(valuesPtr); if (objc == 0) { return TCL_OK; /* Empty list of values. */ } string = Tcl_GetString(objv[0]); if ((objc == 1) && (Blt_VectorExists2(interp, string))) { result = GetVectorData(interp, valuesPtr, string); } else if ((objc == 2) && (Blt_Table_TableExists(interp, string))) { result = GetTableData(interp, valuesPtr, string, objv[1]); } else { double *values; int nValues; result = ParseValues(interp, objPtr, &nValues, &values); if (result != TCL_OK) { return TCL_ERROR; /* Can't parse the values as numbers. */ } FreeDataValues(valuesPtr); if (nValues > 0) { valuesPtr->values = values; } valuesPtr->nValues = nValues; FindRange(valuesPtr); valuesPtr->type = ELEM_SOURCE_VALUES; } return result; } /* *--------------------------------------------------------------------------- * * ValuesToObj -- * * Convert the vector of floating point values into a TCL list. * * Results: * The string representation of the vector is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ValuesToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { ElemValues *valuesPtr = (ElemValues *)(widgRec + offset); switch (valuesPtr->type) { case ELEM_SOURCE_VECTOR: { const char *vecName; vecName = Blt_NameOfVectorId(valuesPtr->vectorSource.vector); return Tcl_NewStringObj(vecName, -1); } case ELEM_SOURCE_TABLE: { Tcl_Obj *listObjPtr; const char *tableName; long i; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); tableName = Blt_Table_TableName(valuesPtr->tableSource.table); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tableName, -1)); i = Blt_Table_ColumnIndex(valuesPtr->tableSource.column); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(i)); return listObjPtr; } case ELEM_SOURCE_VALUES: { Tcl_Obj *listObjPtr; double *vp, *vend; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (vp = valuesPtr->values, vend = vp + valuesPtr->nValues; vp < vend; vp++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(*vp)); } return listObjPtr; } default: abort(); } return Tcl_NewStringObj("", 0); } /*ARGSUSED*/ static void FreeValuePairs( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) /* Not used. */ { Element *elemPtr = (Element *)widgRec; FreeDataValues(&elemPtr->x); FreeDataValues(&elemPtr->y); } /* *--------------------------------------------------------------------------- * * ObjToValuePairs -- * * This procedure is like ObjToValues except that it interprets * the list of numeric expressions as X Y coordinate pairs. The * minimum and maximum for both the X and Y vectors are * determined. * * Results: * The return value is a standard TCL result. The vectors are * passed back via the widget record (elemPtr). * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToValuePairs( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* TCL list of numeric expressions */ char *widgRec, /* Element record */ int offset, /* Not used. */ int flags) /* Not used. */ { Element *elemPtr = (Element *)widgRec; double *values; int nValues; size_t newSize; if (ParseValues(interp, objPtr, &nValues, &values) != TCL_OK) { return TCL_ERROR; } if (nValues & 1) { Tcl_AppendResult(interp, "odd number of data points", (char *)NULL); Blt_Free(values); return TCL_ERROR; } nValues /= 2; newSize = nValues * sizeof(double); FreeDataValues(&elemPtr->x); /* Release the current data sources. */ FreeDataValues(&elemPtr->y); if (newSize > 0) { double *p; int i; elemPtr->x.values = Blt_AssertMalloc(newSize); elemPtr->y.values = Blt_AssertMalloc(newSize); elemPtr->x.nValues = elemPtr->y.nValues = nValues; for (p = values, i = 0; i < nValues; i++) { elemPtr->x.values[i] = *p++; elemPtr->y.values[i] = *p++; } Blt_Free(values); FindRange(&elemPtr->x); FindRange(&elemPtr->y); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ValuePairsToObj -- * * Convert pairs of floating point values in the X and Y arrays * into a TCL list. * * Results: * The return value is a string (Tcl list). * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ValuePairsToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element information record */ int offset, /* Not used. */ int flags) /* Not used. */ { Element *elemPtr = (Element *)widgRec; Tcl_Obj *listObjPtr; int i; int length; length = NUMBEROFPOINTS(elemPtr); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 0; i < length; i++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(elemPtr->x.values[i])); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(elemPtr->y.values[i])); } return listObjPtr; } /* *--------------------------------------------------------------------------- * * ObjToAlong -- * * Given a TCL list of numeric expression representing the element * values, convert into an array of double precision values. In * addition, the minimum and maximum values are saved. Since * elastic values are allow (values which translate to the * min/max of the graph), we must try to get the non-elastic * minimum and maximum. * * Results: * The return value is a standard TCL result. The vector is passed * back via the valuesPtr. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToAlong( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *intPtr = (int *)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if ((string[0] == 'x') && (string[1] == '\0')) { *intPtr = SEARCH_X; } else if ((string[0] == 'y') && (string[1] == '\0')) { *intPtr = SEARCH_Y; } else if ((string[0] == 'b') && (strcmp(string, "both") == 0)) { *intPtr = SEARCH_BOTH; } else { Tcl_AppendResult(interp, "bad along value \"", string, "\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AlongToObj -- * * Convert the vector of floating point values into a TCL list. * * Results: * The string representation of the vector is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * AlongToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int along = *(int *)(widgRec + offset); Tcl_Obj *objPtr; switch (along) { case SEARCH_X: objPtr = Tcl_NewStringObj("x", 1); break; case SEARCH_Y: objPtr = Tcl_NewStringObj("y", 1); break; case SEARCH_BOTH: objPtr = Tcl_NewStringObj("both", 4); break; default: objPtr = Tcl_NewStringObj("unknown along value", 4); break; } return objPtr; } void Blt_FreeStylePalette(Blt_Chain stylePalette) { Blt_ChainLink link; /* Skip the first slot. It contains the built-in "normal" pen of * the element. */ link = Blt_Chain_FirstLink(stylePalette); if (link != NULL) { Blt_ChainLink next; for (link = Blt_Chain_NextLink(link); link != NULL; link = next) { PenStyle *stylePtr; next = Blt_Chain_NextLink(link); stylePtr = Blt_Chain_GetValue(link); Blt_FreePen(stylePtr->penPtr); Blt_Chain_DeleteLink(stylePalette, link); } } } /*ARGSUSED*/ static void FreeStyles( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset); Blt_FreeStylePalette(stylePalette); } /* *--------------------------------------------------------------------------- * * Blt_ObjToStyles -- * * Parse the list of style names. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyles( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style list */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset); Blt_ChainLink link; Element *elemPtr = (Element *)(widgRec); PenStyle *stylePtr; Tcl_Obj **objv; int objc; int i; size_t size = (size_t)clientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } /* Reserve the first entry for the "normal" pen. We'll set the * style later */ Blt_FreeStylePalette(stylePalette); link = Blt_Chain_FirstLink(stylePalette); if (link == NULL) { link = Blt_Chain_AllocLink(size); Blt_Chain_LinkAfter(stylePalette, link, NULL); } stylePtr = Blt_Chain_GetValue(link); stylePtr->penPtr = elemPtr->normalPenPtr; for (i = 0; i < objc; i++) { link = Blt_Chain_AllocLink(size); stylePtr = Blt_Chain_GetValue(link); stylePtr->weight.min = (double)i; stylePtr->weight.max = (double)i + 1.0; stylePtr->weight.range = 1.0; if (GetPenStyleFromObj(interp, elemPtr->obj.graphPtr, objv[i], elemPtr->obj.classId, (PenStyle *)stylePtr) != TCL_OK) { Blt_FreeStylePalette(stylePalette); return TCL_ERROR; } Blt_Chain_LinkAfter(stylePalette, link, NULL); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * StylesToObj -- * * Convert the style information into a Tcl_Obj. * * Results: * The string representing the style information is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StylesToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Chain stylePalette = *(Blt_Chain *)(widgRec + offset); Blt_ChainLink link; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); link = Blt_Chain_FirstLink(stylePalette); if (link != NULL) { /* Skip the first style (it's the default) */ for (link = Blt_Chain_NextLink(link); link != NULL; link = Blt_Chain_NextLink(link)) { PenStyle *stylePtr; Tcl_Obj *subListObjPtr; stylePtr = Blt_Chain_GetValue(link); subListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, subListObjPtr, Tcl_NewStringObj(stylePtr->penPtr->name, -1)); Tcl_ListObjAppendElement(interp, subListObjPtr, Tcl_NewDoubleObj(stylePtr->weight.min)); Tcl_ListObjAppendElement(interp, subListObjPtr, Tcl_NewDoubleObj(stylePtr->weight.max)); Tcl_ListObjAppendElement(interp, listObjPtr, subListObjPtr); } } return listObjPtr; } /* *--------------------------------------------------------------------------- * * Blt_StyleMap -- * * Creates an array of style indices and fills it based on the weight * of each data point. * * Results: * None. * * Side effects: * Memory is freed and allocated for the index array. * *--------------------------------------------------------------------------- */ PenStyle ** Blt_StyleMap(Element *elemPtr) { int i; int nWeights; /* Number of weights to be examined. * If there are more data points than * weights, they will default to the * normal pen. */ PenStyle **dataToStyle; /* Directory of styles. Each array * element represents the style for * the data point at that index */ Blt_ChainLink link; PenStyle *stylePtr; double *w; /* Weight vector */ int nPoints; nPoints = NUMBEROFPOINTS(elemPtr); nWeights = MIN(elemPtr->w.nValues, nPoints); w = elemPtr->w.values; link = Blt_Chain_FirstLink(elemPtr->stylePalette); stylePtr = Blt_Chain_GetValue(link); /* * Create a style mapping array (data point index to style), * initialized to the default style. */ dataToStyle = Blt_AssertMalloc(nPoints * sizeof(PenStyle *)); for (i = 0; i < nPoints; i++) { dataToStyle[i] = stylePtr; } for (i = 0; i < nWeights; i++) { for (link = Blt_Chain_LastLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_PrevLink(link)) { stylePtr = Blt_Chain_GetValue(link); if (stylePtr->weight.range > 0.0) { double norm; norm = (w[i] - stylePtr->weight.min) / stylePtr->weight.range; if (((norm - 1.0) <= DBL_EPSILON) && (((1.0 - norm) - 1.0) <= DBL_EPSILON)) { dataToStyle[i] = stylePtr; break; /* Done: found range that matches. */ } } } } return dataToStyle; } /* *--------------------------------------------------------------------------- * * GetIndex -- * * Given a string representing the index of a pair of x,y * coordinates, return the numeric index. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int GetIndex(Tcl_Interp *interp, Element *elemPtr, Tcl_Obj *objPtr, int *indexPtr) { char *string; string = Tcl_GetString(objPtr); if ((*string == 'e') && (strcmp("end", string) == 0)) { *indexPtr = NUMBEROFPOINTS(elemPtr) - 1; } else if (Blt_ExprIntFromObj(interp, objPtr, indexPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetElement -- * * Find the element represented the given name, returning a pointer to * its data structure via elemPtrPtr. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Element **elemPtrPtr) { Blt_HashEntry *hPtr; char *name; name = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->elements.table, name); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find element \"", name, "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *elemPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyElement -- * * Add a new element to the graph. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static void DestroyElement(Element *elemPtr) { Graph *graphPtr = elemPtr->obj.graphPtr; Blt_DeleteBindings(graphPtr->bindTable, elemPtr); Blt_Legend_RemoveElement(graphPtr, elemPtr); Blt_FreeOptions(elemPtr->configSpecs, (char *)elemPtr,graphPtr->display, 0); /* * Call the element's own destructor to release the memory and * resources allocated for it. */ (*elemPtr->procsPtr->destroyProc) (graphPtr, elemPtr); /* Remove it also from the element display list */ if (elemPtr->link != NULL) { Blt_Chain_DeleteLink(graphPtr->elements.displayList, elemPtr->link); if (!IGNORE_ELEMENT(elemPtr)) { graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); } } /* Remove the element for the graph's hash table of elements */ if (elemPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&graphPtr->elements.table, elemPtr->hashPtr); } if (elemPtr->obj.name != NULL) { Blt_Free(elemPtr->obj.name); } if (elemPtr->label != NULL) { Blt_Free(elemPtr->label); } Blt_Free(elemPtr); } static void FreeElement(DestroyData data) { Element *elemPtr = (Element *)data; DestroyElement(elemPtr); } /* *--------------------------------------------------------------------------- * * CreateElement -- * * Add a new element to the graph. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static int CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId) { Element *elemPtr; Blt_HashEntry *hPtr; int isNew; char *string; string = Tcl_GetString(objv[3]); if (string[0] == '-') { Tcl_AppendResult(graphPtr->interp, "name of element \"", string, "\" can't start with a '-'", (char *)NULL); return TCL_ERROR; } hPtr = Blt_CreateHashEntry(&graphPtr->elements.table, string, &isNew); if (!isNew) { Tcl_AppendResult(interp, "element \"", string, "\" already exists in \"", Tcl_GetString(objv[0]), "\"", (char *)NULL); return TCL_ERROR; } if (classId == CID_ELEM_BAR) { elemPtr = Blt_BarElement(graphPtr, string, classId); } else { /* Stripcharts are line graphs with some options enabled. */ elemPtr = Blt_LineElement(graphPtr, string, classId); } assert(elemPtr->configSpecs != NULL); elemPtr->hashPtr = hPtr; Blt_SetHashValue(hPtr, elemPtr); if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, elemPtr->obj.name, "Element", elemPtr->configSpecs, objc - 4, objv + 4, (char *)elemPtr, 0) != TCL_OK) { DestroyElement(elemPtr); return TCL_ERROR; } (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr); elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr); graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); elemPtr->flags |= MAP_ITEM; graphPtr->flags |= RESET_AXES; Tcl_SetObjResult(interp, objv[3]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_DestroyElements -- * * Removes all the graph's elements. This routine is called when * the graph is destroyed. * * Results: * None. * * Side effects: * Memory allocated for the graph's elements is freed. * *--------------------------------------------------------------------------- */ void Blt_DestroyElements(Graph *graphPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Element *elemPtr; for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { elemPtr = Blt_GetHashValue(hPtr); elemPtr->hashPtr = NULL; DestroyElement(elemPtr); } Blt_DeleteHashTable(&graphPtr->elements.table); Blt_DeleteHashTable(&graphPtr->elements.tagTable); Blt_Chain_Destroy(graphPtr->elements.displayList); } void Blt_ConfigureElements(Graph *graphPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr); } } void Blt_MapElements(Graph *graphPtr) { Blt_ChainLink link; if (graphPtr->mode != BARS_INFRONT) { Blt_ResetBarGroups(graphPtr); } for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (IGNORE_ELEMENT(elemPtr)) { continue; } if ((graphPtr->flags & MAP_ALL) || (elemPtr->flags & MAP_ITEM)) { (*elemPtr->procsPtr->mapProc) (graphPtr, elemPtr); elemPtr->flags &= ~MAP_ITEM; } } } /* *--------------------------------------------------------------------------- * * Blt_DrawElements -- * * Calls the individual element drawing routines for each * element. * * Results: * None * * Side Effects: * Elements are drawn into the drawable (pixmap) which will * eventually be displayed in the graph window. * *--------------------------------------------------------------------------- */ void Blt_DrawElements(Graph *graphPtr, Drawable drawable) { Blt_ChainLink link; /* Draw with respect to the stacking order. */ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & (HIDE|DELETE_PENDING)) == 0) { (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr); } } } /* *--------------------------------------------------------------------------- * * Blt_DrawActiveElements -- * * Calls the individual element drawing routines to display * the active colors for each element. * * Results: * None * * Side Effects: * Elements are drawn into the drawable (pixmap) which will * eventually be displayed in the graph window. * *--------------------------------------------------------------------------- */ void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & (HIDE|ACTIVE|DELETE_PENDING)) == ACTIVE) { (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr); } } } /* *--------------------------------------------------------------------------- * * Blt_ElementsToPostScript -- * * Generates PostScript output for each graph element in the * element display list. * *--------------------------------------------------------------------------- */ void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->flags & (HIDE|DELETE_PENDING)) { continue; } /* Comment the PostScript to indicate the start of the element */ Blt_Ps_Format(ps, "\n%% Element \"%s\"\n\n", elemPtr->obj.name); (*elemPtr->procsPtr->printNormalProc) (graphPtr, ps, elemPtr); } } /* *--------------------------------------------------------------------------- * * Blt_ActiveElementsToPostScript -- * *--------------------------------------------------------------------------- */ void Blt_ActiveElementsToPostScript( Graph *graphPtr, Blt_Ps ps) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & (DELETE_PENDING|HIDE|ACTIVE)) == ACTIVE) { Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n", elemPtr->obj.name); (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr); } } } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Marks data points of elements (given by their index) as active. * * Results: * Returns TCL_OK if no errors occurred. * *--------------------------------------------------------------------------- */ static int ActivateOp( Graph *graphPtr, /* Graph widget */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, /* Number of element names */ Tcl_Obj *const *objv) /* List of element names */ { Element *elemPtr; int i; int *indices; int nIndices; if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* List all the currently active elements */ for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { elemPtr = Blt_GetHashValue(hPtr); if (elemPtr->flags & ACTIVE) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(elemPtr->obj.name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } elemPtr->flags |= ACTIVE | ACTIVE_PENDING; indices = NULL; nIndices = -1; if (objc > 4) { int *activePtr; nIndices = objc - 4; activePtr = indices = Blt_AssertMalloc(sizeof(int) * nIndices); for (i = 4; i < objc; i++) { if (GetIndex(interp, elemPtr, objv[i], activePtr) != TCL_OK) { return TCL_ERROR; } activePtr++; } } if (elemPtr->activeIndices != NULL) { Blt_Free(elemPtr->activeIndices); } elemPtr->nActiveIndices = nIndices; elemPtr->activeIndices = indices; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } ClientData Blt_MakeElementTag(Graph *graphPtr, const char *tagName) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&graphPtr->elements.tagTable, tagName, &isNew); return Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr); } /* *--------------------------------------------------------------------------- * * BindOp -- * * .g element bind elemName sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; char *tagName; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { tagName = Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tagName, -1)); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * CreateOp -- * * Add a new element to the graph (using the default type of the * graph). * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static int CreateOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId) { return CreateElement(graphPtr, interp, objc, objv, classId); } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp( Graph *graphPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Element *elemPtr; if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, elemPtr->configSpecs, (char *)elemPtr, objv[4], 0) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ClosestOp -- * * Find the element closest to the specified screen coordinates. * Options: * -halo Consider points only with this maximum distance * from the picked coordinate. * -interpolate Find closest point along element traces, not just * data points. * -along * * Results: * A standard TCL result. If an element could be found within * the halo distance, the interpreter result is "1", otherwise * "0". If a closest element exists, the designated TCL array * variable will be set with the following information: * * 1) the element name, * 2) the index of the closest point, * 3) the distance (in screen coordinates) from the picked X-Y * coordinate and the closest point, * 4) the X coordinate (graph coordinate) of the closest point, * 5) and the Y-coordinate. * *--------------------------------------------------------------------------- */ static Blt_ConfigSpec closestSpecs[] = { {BLT_CONFIG_PIXELS_NNEG, "-halo", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(ClosestSearch, halo), 0}, {BLT_CONFIG_BOOLEAN, "-interpolate", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(ClosestSearch, mode), 0 }, {BLT_CONFIG_CUSTOM, "-along", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(ClosestSearch, along), 0, &alongOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static int ClosestOp( Graph *graphPtr, /* Graph widget */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Number of element names */ Tcl_Obj *const *objv) /* List of element names */ { Element *elemPtr; ClosestSearch search; int i, x, y; char *string; if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { Tcl_AppendResult(interp, ": bad window x-coordinate", (char *)NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { Tcl_AppendResult(interp, ": bad window y-coordinate", (char *)NULL); return TCL_ERROR; } for (i = 5; i < objc; i += 2) { /* Count switches-value pairs */ string = Tcl_GetString(objv[i]); if ((string[0] != '-') || ((string[1] == '-') && (string[2] == '\0'))) { break; } } if (i > objc) { i = objc; } search.mode = SEARCH_POINTS; search.halo = graphPtr->halo; search.index = -1; search.along = SEARCH_BOTH; search.x = x; search.y = y; if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, closestSpecs, i - 5, objv + 5, (char *)&search, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; /* Error occurred processing an option. */ } if (i < objc) { string = Tcl_GetString(objv[i]); if (string[0] == '-') { i++; /* Skip "--" */ } } search.dist = (double)(search.halo + 1); if (i < objc) { for ( /* empty */ ; i < objc; i++) { if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } if (IGNORE_ELEMENT(elemPtr)) { continue; } if (elemPtr->flags & (HIDE|MAP_ITEM)) { continue; } (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search); } } else { Blt_ChainLink link; /* * Find the closest point from the set of displayed elements, * searching the display list from back to front. That way if * the points from two different elements overlay each other * exactly, the last one picked will be the topmost. */ for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { elemPtr = Blt_Chain_GetValue(link); if (elemPtr->flags & (HIDE|MAP_ITEM|DELETE_PENDING)) { continue; } (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search); } } if (search.dist < (double)search.halo) { Tcl_Obj *listObjPtr; /* * Return a list of name value pairs. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("name", -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(search.elemPtr->obj.name, -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("index", -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(search.index)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("x", -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(search.point.x)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("y", -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(search.point.y)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("dist", -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(search.dist)); Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Sets the element specifications by the given the command line * arguments and calls the element specification configuration * routine. If zero or one command line options are given, only * information about the option(s) is returned in interp->result. * If the element configuration has changed and the element is * currently displayed, the axis limits are updated and * recomputed. * * Results: * The return value is a standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new display list. * *--------------------------------------------------------------------------- */ static int ConfigureOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int nNames, nOpts; Tcl_Obj *const *options; int i; /* Figure out where the option value pairs begin */ objc -= 3; objv += 3; for (i = 0; i < objc; i++) { Element *elemPtr; char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } } nNames = i; /* Number of element names specified */ nOpts = objc - i; /* Number of options specified */ options = objv + nNames; /* Start of options in objv */ for (i = 0; i < nNames; i++) { Element *elemPtr; int flags; if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; } flags = BLT_CONFIG_OBJV_ONLY; if (nOpts == 0) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, elemPtr->configSpecs, (char *)elemPtr, (Tcl_Obj *)NULL, flags); } else if (nOpts == 1) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, elemPtr->configSpecs, (char *)elemPtr, options[0], flags); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, elemPtr->configSpecs, nOpts, options, (char *)elemPtr, flags) != TCL_OK) { return TCL_ERROR; } if ((*elemPtr->procsPtr->configProc) (graphPtr, elemPtr) != TCL_OK) { return TCL_ERROR; /* Failed to configure element */ } if (Blt_ConfigModified(elemPtr->configSpecs, "-hide", (char *)NULL)) { graphPtr->flags |= RESET_AXES; elemPtr->flags |= MAP_ITEM; } /* If data points or axes have changed, reset the axes (may * affect autoscaling) and recalculate the screen points of * the element. */ if (Blt_ConfigModified(elemPtr->configSpecs, "-*data", "-map*", "-x", "-y", (char *)NULL)) { graphPtr->flags |= RESET_WORLD; elemPtr->flags |= MAP_ITEM; } /* The new label may change the size of the legend */ if (Blt_ConfigModified(elemPtr->configSpecs, "-label", (char *)NULL)) { graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); } } /* Update the pixmap if any configuration option changed */ graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeactivateOp -- * * Clears the active bit for the named elements. * * Results: * Returns TCL_OK if no errors occurred. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeactivateOp( Graph *graphPtr, /* Graph widget */ Tcl_Interp *interp, /* Not used. */ int objc, /* Number of element names */ Tcl_Obj *const *objv) /* List of element names */ { int i; for (i = 3; i < objc; i++) { Element *elemPtr; if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } elemPtr->flags &= ~(ACTIVE | ACTIVE_PENDING); if (elemPtr->activeIndices != NULL) { Blt_Free(elemPtr->activeIndices); elemPtr->activeIndices = NULL; } elemPtr->nActiveIndices = 0; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Delete the named elements from the graph. * * Results: * TCL_ERROR is returned if any of the named elements can not be * found. Otherwise TCL_OK is returned; * * Side Effects: * If the element is currently displayed, the plotting area of * the graph is redrawn. Memory and resources allocated by the * elements are released. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp( Graph *graphPtr, /* Graph widget */ Tcl_Interp *interp, /* Not used. */ int objc, /* Number of element names */ Tcl_Obj *const *objv) /* List of element names */ { int i; for (i = 3; i < objc; i++) { Element *elemPtr; if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } elemPtr->flags |= DELETE_PENDING; Tcl_EventuallyFree(elemPtr, FreeElement); } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExistsOp -- * * Indicates if the named element exists in the graph. * * Results: * The return value is a standard TCL result. The interpreter * result will contain "1" or "0". * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ExistsOp( Graph *graphPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&graphPtr->elements.table, Tcl_GetString(objv[3])); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr != NULL)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Returns the name of the picked element (using the element * bind operation). Right now, the only name accepted is * "current". * * Results: * A standard TCL result. The interpreter result will contain * the name of the element. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GetOp( Graph *graphPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { char *string; string = Tcl_GetString(objv[3]); if ((string[0] == 'c') && (strcmp(string, "current") == 0)) { Element *elemPtr; elemPtr = Blt_GetCurrentItem(graphPtr->bindTable); /* Report only on elements. */ if ((elemPtr != NULL) && ((elemPtr->flags & DELETE_PENDING) == 0) && (elemPtr->obj.classId >= CID_ELEM_BAR) && (elemPtr->obj.classId <= CID_ELEM_STRIP)) { Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name,-1); } } return TCL_OK; } static Tcl_Obj * DisplayListObj(Graph *graphPtr) { Tcl_Obj *listObjPtr; Blt_ChainLink link; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; Tcl_Obj *objPtr; elemPtr = Blt_Chain_GetValue(link); objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(graphPtr->interp, listObjPtr, objPtr); } return listObjPtr; } /* *--------------------------------------------------------------------------- * * LowerOp -- * * Lowers the named elements to the bottom of the display list. * * Results: * A standard TCL result. The interpreter result will contain the new * display list of element names. * * .g element lower elem ?elem...? * *--------------------------------------------------------------------------- */ static int LowerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Chain chain; Blt_ChainLink link, next; int i; /* Move the links of lowered elements out of the display list into * a temporary list. */ chain = Blt_Chain_Create(); for (i = 3; i < objc; i++) { Element *elemPtr; if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } Blt_Chain_UnlinkLink(graphPtr->elements.displayList, elemPtr->link); Blt_Chain_LinkAfter(chain, elemPtr->link, NULL); } /* Append the links to end of the display list. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = next) { next = Blt_Chain_NextLink(link); Blt_Chain_UnlinkLink(chain, link); Blt_Chain_LinkAfter(graphPtr->elements.displayList, link, NULL); } Blt_Chain_Destroy(chain); Tcl_SetObjResult(interp, DisplayListObj(graphPtr)); graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns the names of the elements is the graph matching * one of more patterns provided. If no pattern arguments * are given, then all element names will be returned. * * Results: * The return value is a standard TCL result. The interpreter * result will contain a TCL list of the element names. * *--------------------------------------------------------------------------- */ static int NamesOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Element *elemPtr; Tcl_Obj *objPtr; elemPtr = Blt_GetHashValue(hPtr); objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.table, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Element *elemPtr; int i; elemPtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { if (Tcl_StringMatch(elemPtr->obj.name,Tcl_GetString(objv[i]))) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RaiseOp -- * * Reset the element within the display list. * * Results: * The return value is a standard TCL result. The interpreter * result will contain the new display list of element names. * * .g element raise ?elem...? * *--------------------------------------------------------------------------- */ static int RaiseOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Chain chain; Blt_ChainLink link, prev; int i; /* Move the links of lowered elements out of the display list into * a temporary list. */ chain = Blt_Chain_Create(); for (i = 3; i < objc; i++) { Element *elemPtr; if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } Blt_Chain_UnlinkLink(graphPtr->elements.displayList, elemPtr->link); Blt_Chain_LinkAfter(chain, elemPtr->link, NULL); } /* Prepend the links to beginning of the display list in reverse order. */ for (link = Blt_Chain_LastLink(chain); link != NULL; link = prev) { prev = Blt_Chain_PrevLink(link); Blt_Chain_UnlinkLink(chain, link); Blt_Chain_LinkBefore(graphPtr->elements.displayList, link, NULL); } Blt_Chain_Destroy(chain); Tcl_SetObjResult(interp, DisplayListObj(graphPtr)); graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShowOp -- * * Queries or resets the element display list. * * Results: * The return value is a standard TCL result. The interpreter * result will contain the new display list of element names. * *--------------------------------------------------------------------------- */ static int ShowOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 4) { Blt_Chain chain; Blt_ChainLink link; Tcl_Obj **elem; int i, n; if (Tcl_ListObjGetElements(interp, objv[3], &n, &elem) != TCL_OK) { return TCL_ERROR; } /* Collect the named elements into a list. */ chain = Blt_Chain_Create(); for (i = 0; i < n; i++) { Element *elemPtr; /* Element information record */ if (Blt_GetElement(interp, graphPtr, elem[i], &elemPtr) != TCL_OK) { Blt_Chain_Destroy(chain); return TCL_ERROR; } Blt_Chain_Append(chain, elemPtr); } /* Clear the links from the currently displayed elements. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); elemPtr->link = NULL; } Blt_Chain_Destroy(graphPtr->elements.displayList); graphPtr->elements.displayList = chain; /* Set links on all the displayed elements. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); elemPtr->link = link; } graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); } Tcl_SetObjResult(interp, DisplayListObj(graphPtr)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeOp -- * * Returns the name of the type of the element given by some * element name. * * Results: * A standard TCL result. Returns the type of the element in * interp->result. If the identifier given doesn't represent an * element, then an error message is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeOp( Graph *graphPtr, /* Graph widget */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) /* Element name */ { Element *elemPtr; const char *string; if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; /* Can't find named element */ } switch (elemPtr->obj.classId) { case CID_ELEM_BAR: string = "bar"; break; case CID_ELEM_CONTOUR: string = "contour"; break; case CID_ELEM_LINE: string = "line"; break; case CID_ELEM_STRIP: string = "strip"; break; default: string = "???"; break; } Tcl_SetStringObj(Tcl_GetObjResult(interp), string, -1); return TCL_OK; } /* * Global routines: */ static Blt_OpSpec elemOps[] = { {"activate", 1, ActivateOp, 3, 0, "?elemName? ?index...?",}, {"bind", 1, BindOp, 3, 6, "elemName sequence command",}, {"cget", 2, CgetOp, 5, 5, "elemName option",}, {"closest", 2, ClosestOp, 5, 0, "x y ?option value?... ?elemName?...",}, {"configure", 2, ConfigureOp, 4, 0, "elemName ?elemName?... ?option value?...",}, {"create", 2, CreateOp, 4, 0, "elemName ?option value?...",}, {"deactivate", 3, DeactivateOp, 3, 0, "?elemName?...",}, {"delete", 3, DeleteOp, 3, 0, "?elemName?...",}, {"exists", 1, ExistsOp, 4, 4, "elemName",}, {"get", 1, GetOp, 4, 4, "name",}, {"lower", 1, LowerOp, 3, 0, "?elemName?...",}, {"names", 1, NamesOp, 3, 0, "?pattern?...",}, {"raise", 1, RaiseOp, 3, 0, "?elemName?...",}, {"show", 1, ShowOp, 3, 4, "?elemList?",}, {"type", 1, TypeOp, 4, 4, "elemName",}, }; static int numElemOps = sizeof(elemOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * Blt_ElementOp -- * * This procedure is invoked to process the TCL command that * corresponds to a widget managed by this module. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int Blt_ElementOp( Graph *graphPtr, /* Graph widget record */ Tcl_Interp *interp, int objc, /* # arguments */ Tcl_Obj *const *objv, /* Argument list */ ClassId classId) { void *ptr; int result; ptr = Blt_GetOpFromObj(interp, numElemOps, elemOps, BLT_OP_ARG2, objc, objv, 0); if (ptr == NULL) { return TCL_ERROR; } if (ptr == CreateOp) { result = CreateOp(graphPtr, interp, objc, objv, classId); } else { GraphElementProc *proc; proc = ptr; result = (*proc) (graphPtr, interp, objc, objv); } return result; } ����./saods9/blt3.0.1/src/bltWinConfig.h����������������������������������������������������������������0000644�0001750�0001750�00000007313�11462120063�015570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _BLT_WIN_CONFIG_H #define _BLT_WIN_CONFIG_H /* src/bltConfig.h. Generated automatically by configure. */ /* src/bltConfig.h.in. Generated automatically from configure.in by autoheader. */ /* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to `int' if <sys/types.h> doesn't define. */ #if defined(_MSC_VER) || defined(__BORLANDC__) #define pid_t int #endif /* _MSC_VER || __BORLANDC__ */ /* Define to `unsigned' if <sys/types.h> doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both <sys/time.h> and <time.h>. */ #undef TIME_WITH_SYS_TIME /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* Define if DBL_EPSILON is not defined in float.h */ #undef BLT_DBL_EPSILON /* Define if drand48 is declared in math.h. */ #define HAVE_DECL_DRAND48 0 /* Define if srand48 is declared in math.h. */ #define HAVE_DECL_SRAND48 0 /* Define if j1 is declared in a standard header file. */ #define HAVE_DECL_J1 0 /* Define if union wait type is defined incorrectly. */ #undef HAVE_UNION_WAIT /* Define if isfinite is found in libm. */ #undef HAVE_ISFINITE /* The number of bytes in a long. */ #define SIZEOF_LONG 4 /* The number of bytes in a long long. */ #define SIZEOF_LONG_LONG 8 /* The number of bytes in a void *. */ #define SIZEOF_VOID_P 4 /* Define if you have the XExtendedMaxRequestSize function. */ #undef HAVE_XEXTENDEDMAXREQUESTSIZE /* Define if you have the drand48 function. */ #define HAVE_DRAND48 1 /* Define if you have the finite function. */ #undef HAVE_FINITE /* Define if you have the srand48 function. */ #define HAVE_SRAND48 1 /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 #ifndef __BORLANDC__ /* Define if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 #endif /* Define if you have the <ctype.h> header file. */ #define HAVE_CTYPE_H 1 /* Define if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 /* Define if you have the <float.h> header file. */ #define HAVE_FLOAT_H 1 /* Define if you have the <ieeefp.h> header file. */ #undef HAVE_IEEEFP_H /* Define if you have the <jpeglib.h> header file. */ /* Defined in Makefile */ /* #undef HAVE_JPEGLIB_H */ /* Define if you have the <limits.h> header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the <malloc.h> header file. */ #define HAVE_MALLOC_H 1 /* Define if you have the <math.h> header file. */ #define HAVE_MATH_H 1 /* Define if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 /* Define if you have the <setjmp.h> header file. */ #define HAVE_SETJMP_H 1 /* Define if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 /* Define if you have the <string.h> header file. */ #define HAVE_STRING_H 1 /* Define if you have the <sys/param.h> header file. */ #undef HAVE_SYS_PARAM_H /* Define if you have the <sys/time.h> header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the <sys/wait.h> header file. */ #undef HAVE_SYS_WAIT_H /* Define if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H /* Define if you have the <waitflags.h> header file. */ #undef HAVE_WAITFLAGS_H /* Define if you have the m library (-lm). */ #define HAVE_LIBM 1 /* Define if you have the nsl library (-lnsl). */ #undef HAVE_LIBNSL /* Define if you have the socket library (-lsocket). */ #undef HAVE_LIBSOCKET #if (_MSC_VER == 1400) #define HAVE_SPRINTF_S #endif #define WIN32 1 #endif _BLT_WIN_CONFIG_H ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/blt.mak�����������������������������������������������������������������������0000644�0001750�0001750�00000017643�11462120062�014313� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # # Nmakefile for BLT library using VC++. # # Please note this file may or may not be up-to-date. # # You can compare it with "Makefile.vc" in this directory. That's # what I use to build BLT (so it should be current). It builds BLT # with VC++ 6.0 and the cygwin32 tool suite from # # http://sourceware.cygnus.com # # ------------------------------------------------------------------------ !INCLUDE ../win/makedefs TOOLS32 = C:/Program Files/Microsoft Visual Studio/Vc98 prefix = C:/Program Files/Tcl AR = lib.exe LD = link.exe CC = cl.exe rc32 = rc.exe RM = -del # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ DEFINES = -D_X86_=1 -D__STDC__ -DWIN32 -DCONSOLE -D_MT \ $(DEBUG_DEFINES) $(SHLIB_DEFINES) EXTRA_CFLAGS = -nologo -W3 !IF "$(SHARED)" == "1" SHLIB_DEFINES = -D_DLL SHLIB_TARGET = build-dll LIBS = $(COMMON_LIBS) !ELSE SHLIB_DEFINES = -D_CTYPE_DISABLE_MACROS LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) !ENDIF !IF "$(DEBUG)" == "1" CFLAGS = -Z7 -Od DEBUG_LDFLAGS = -debug:full -debugtype:cv D = d builddir = .\Debug !ELSE CFLAGS = -Ox -GB -GD DEBUG_LDFLAGS = -debug:full -debugtype:cv D = builddir = .\Release !ENDIF MSVCRT = msvcrt$(DBG).lib TK_LIB = $(TKDIR)/win/$(builddir)/tk$(v2)$(D).lib TCL_LIB = $(TCLDIR)/win/$(builddir)/tcl$(v2)$(D).lib # ------------------------------------------------------------------------ # Linker flags and options # ------------------------------------------------------------------------ JPEGLIB = $(JPEGDIR)/libjpeg.lib COMMON_LDFLAGS = -nodefaultlib -release -nologo -warn:3 \ -machine:IX86 -align:0x1000 \ $(DEBUG_LDFLAGS) DLLENTRY = @12 SHLIB_LDFLAGS = $(COMMON_LDFLAGS) \ -subsystem:console -entry:mainCRTStartup \ -subsystem:windows -entry:WinMainCRTStartup \ -entry:_DllMainCRTStartup$(DLLENTRY) -dll LDFLAGS = $(COMMON_LDFLAGS) \ -fixed:NO -stack:2300000 COMMON_LIBS = $(TK_LIB) $(TCL_LIB) \ $(MSVCRT) \ kernel32.lib user32.lib EXTRA_LIBS = $(OLELIB) \ $(JPEGLIB) \ gdi32.lib \ oldnames.lib \ advapi32.lib \ winspool.lib TCL_ONLY_LIBS = $(TCL_LIB) $(MSVCRT) kernel32.lib user32.lib advapi32.lib # ------------------------------------------------------------------------ # Source and target directories # ------------------------------------------------------------------------ srcdir = . instdirs = $(prefix) $(exec_prefix) $(bindir) $(libdir) \ $(includedir) instdirs = $(exec_prefix) $(prefix) $(libdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ JPEGDIR = $(srcdir)/../../jpeg-6b TCLDIR = $(srcdir)/../../tcl$(v3) TKDIR = $(srcdir)/../../tk$(v3) INCLUDES = -I. -I$(srcdir) \ -I"$(TOOLS32)/include" \ -I$(TCLDIR)/win \ -I$(TCLDIR)/generic \ -I$(TKDIR)/win \ -I$(TKDIR)/generic \ -I$(TKDIR)/xlib \ -I$(JPEGDIR) SHLIB_LD_LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ N_OBJS = bltTed.o V3_OBJS = bltTri.o bltGrMt.o TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o TCL_ONLY_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBgexec.o \ bltChain.o \ bltDebug.o \ bltHash.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltSpline.o \ bltSwitch.o \ bltTree.o \ bltTreeCmd.o \ bltUtil.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltWatch.o bltWinPipe.o \ OBJS = $(GRAPH_OBJS) \ $(TCL_ONLY_OBJS) \ bltBeep.o \ bltBind.o \ bltBitmap.o \ bltBusy.o \ bltCanvEps.o \ bltConfig.o \ bltContainer.o \ bltDragdrop.o \ bltHtext.o \ bltImage.o \ bltOldConfig.o \ bltPainter.o \ bltPicture.o \ bltPictureFormats.o \ bltPictureImage.o \ bltPictureMMX.o \ bltPs.o \ bltTable.o \ bltTabnotebook.o \ bltTabset.o \ bltText.o \ bltTile.o \ bltTreeView.o \ bltTreeViewCmd.o \ bltTreeViewColumn.o \ bltTreeViewEdit.o \ bltTreeViewStyle.o \ bltWinBitmap.o \ bltWinDraw.o \ bltWinPainter.o \ bltWinPrnt.o \ bltWinWindow.o \ bltWindow.o \ bltWinop.o \ $(TK_OBJS) $(N_OBJS) bltwish = bltwish.exe bltsh = bltsh.exe headers = $(srcdir)/blt.h \ $(srcdir)/bltBind.h \ $(srcdir)/bltChain.h \ bltHash.h \ $(srcdir)/bltList.h \ $(srcdir)/bltPool.h \ $(srcdir)/bltTree.h \ $(srcdir)/bltVector.h version = $(BLT_MAJOR_VERSION)$(BLT_MINOR_VERSION) bltwish2 = bltwish$(version).exe bltsh2 = bltsh$(version).exe lib_name = BLT$(version) lib_a = BLT$(version).lib lib_so = BLT$(version).dll tcl_only_lib_a = BLTlite$(version).lib tcl_only_lib_so = BLTlite$(version).dll CC_SWITCHES = $(CFLAGS) $(EXTRA_CFLAGS) $(DEFINES) $(INCLUDES) VPATH = $(srcdir) all: build-library $(SHLIB_TARGET) build-demos build-demos: $(SHLIB_TARGET) $(bltwish) $(bltsh) build-library: $(BLT_LIB) build-library: $(lib_a) $(tcl_only_lib_a) build-dll: build-library $(lib_so) $(tcl_only_lib_so) $(bltwish): $(lib_a) tkConsole.o bltWinMain.c $(RM) $(bltwish) $(CC) -c $(CC_SWITCHES) -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ -FobltWinMain.o $(srcdir)/bltWinMain.c LIB=$(TOOLS32)/lib \ $(LD) $(LDFLAGS) tkConsole.o bltWinMain.o -out:$(bltwish) \ $(lib_a) $(LIBS) $(bltsh): $(tcl_only_lib_a) bltWinMain.c $(RM) $(bltsh) $(CC) -c $(CC_SWITCHES) -DTCL_ONLY \ -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ -FobltWinMain.o $(srcdir)/bltWinMain.c LIB=$(TOOLS32)/lib \ $(LD) $(LDFLAGS) bltWinMain.o -out:$(bltsh) \ $(tcl_only_lib_a) $(TCL_ONLY_LIBS) $(lib_a): bltHash.h $(OBJS) bltInit.c $(RM) bltInit.o $(CC) -c $(CC_SWITCHES) -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltInit.o $(srcdir)/bltInit.c $(RM) $@ $(AR) -out:$@ bltInit.o $(OBJS) $(lib_so): $(lib_a) $(OBJS) bltInit.c $(RM) bltInit.o $(CC) -c $(CC_SWITCHES) -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltInit.o $(srcdir)/bltInit.c $(RM) $@ LIB=$(TOOLS32)/lib \ $(LD) $(SHLIB_LDFLAGS) -out:$@ bltInit.o $(OBJS) $(SHLIB_LD_LIBS) $(tcl_only_lib_a): bltHash.h $(TCL_ONLY_OBJS) bltInit.c $(RM) bltInit.o $(CC) -c $(CC_SWITCHES) -DTCL_ONLY -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltInit.o $(srcdir)/bltInit.c $(RM) $@ $(AR) -out:$@ bltInit.o $(TCL_ONLY_OBJS) $(tcl_only_lib_so): $(tcl_only_lib_a) $(TCL_ONLY_OBJS) bltInit.c $(RM) bltInit.o $(CC) -c $(CC_SWITCHES) -DTCL_ONLY -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltInit.o $(srcdir)/bltInit.c $(RM) $@ LIB=$(TOOLS32)/lib \ $(LD) $(SHLIB_LDFLAGS) -out:$@ bltInit.o $(TCL_ONLY_OBJS) \ $(TCL_ONLY_LIBS) bltHash.h: bltHash.h.in sed -e 's/@SIZEOF_VOID_P@/4/' \ -e 's/@SIZEOF_INT@/4/' \ -e 's/@SIZEOF_LONG@/4/' \ -e 's/@SIZEOF_LONG_LONG@/8/' \ -e 's/@HAVE_INTTYPES_H@/0/' \ bltHash.h.in > bltHash.h clean: -del *.o 2>nul -del *.pdb 2>nul -del *.exp 2>nul -del $(lib_name).* 2>nul -del $(bltwish) 2>nul -del $(bltsh) 2>nul -del $(srcdir)\*.bak 2>nul -del $(srcdir)\*~ 2>nul -del $(srcdir)\"#"* 2>nul bltPictureDraw.o: $(srcdir)/bltPictureDraw.c $(CC) -c $(CC_OPTS) $(FT_INC_SPEC) \ -FobltPictureDraw.o $(srcdir)/bltPictureDraw.c bltPictureFormats.o: $(srcdir)/bltPictureFormats.c $(CC) -c $(CC_OPTS) \ $(FT_INC_SPEC) \ $(JPEG_INC_SPEC) $(TIFF_INC_SPEC) $(PNG_INC_SPEC) \ $(XPM_INC_SPEC)$(PICTURE_INCLUDES) \ -FobltPictureFormats.o $(srcdir)/bltPictureFormats.c {$(srcdir)}.c.o: $(CC) -c $(CC_SWITCHES) -Fo$*.o $< ���������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tclInterp.h�������������������������������������������������������������������0000644�0001750�0001750�00000017710�11462120063�015151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tclInterp.h -- * * Excerpts from tclInt.h. Used to examine interpreter internals. * Needed by the former parsing (bltParse.c) functions. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file contains excerpts from tclInt.h of the TCL library distribution. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 1994-1998 Sun Microsystems, Inc. * */ /* *--------------------------------------------------------------------------- * Data structures related to command parsing. These are used in * tclParse.c and its clients. *--------------------------------------------------------------------------- */ /* * The following data structure is used by various parsing procedures to hold * information about where to store the results of parsing (e.g. the * substituted contents of a quoted argument, or the result of a nested * command). At any given time, the space available for output is fixed, but * a procedure may be called to expand the space available if the current * space runs out. */ typedef struct _ParseValue ParseValue; struct _ParseValue { char *buffer; char *next; char *end; void (*expandProc)(ParseValue *pvPtr, int needed); ClientData clientData; }; /* * The definitions for the LiteralTable and LiteralEntry structures. Each * interpreter contains a LiteralTable. It is used to reduce the storage * needed for all the TCL objects that hold the literals of scripts compiled * by the interpreter. A literal's object is shared by all the ByteCodes that * refer to the literal. Each distinct literal has one LiteralEntry entry in * the LiteralTable. A literal table is a specialized hash table that is * indexed by the literal's string representation, which may contain null * characters. * * Note that we reduce the space needed for literals by sharing literal * objects both within a ByteCode (each ByteCode contains a local * LiteralTable) and across all an interpreter's ByteCodes (with the * interpreter's global LiteralTable). */ typedef struct _LiteralEntry LiteralEntry; struct _LiteralEntry { LiteralEntry *nextPtr; Tcl_Obj *objPtr; int refCount; }; typedef struct { LiteralEntry **buckets; LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; int numBuckets; int numEntries; int rebuildSize; int mask; } LiteralTable; /* * The following structure defines for each TCL interpreter various * statistics-related information about the bytecode compiler and * interpreter's operation in that interpreter. */ #ifdef TCL_COMPILE_STATS typedef struct { long numExecutions; long numCompilations; long numByteCodesFreed; long instructionCount[256]; double totalSrcBytes; double totalByteCodeBytes; double currentSrcBytes; double currentByteCodeBytes; long srcCount[32]; long byteCodeCount[32]; long lifetimeCount[32]; double currentInstBytes; double currentLitBytes; double currentExceptBytes; double currentAuxBytes; double currentCmdMapBytes; long numLiteralsCreated; double totalLitStringBytes; double currentLitStringBytes; long literalCount[32]; } ByteCodeStats; #endif /* TCL_COMPILE_STATS */ /* *--------------------------------------------------------------------------- * * Data structures and procedures related to TclHandles, which are a very * lightweight method of preserving enough information to determine if an * arbitrary malloc'd block has been deleted. * *--------------------------------------------------------------------------- */ typedef VOID **TclHandle; /* * The following fills in dummy types for structure refered to internally by * the TCL interpreter. Since we don't need the actual size of the * structures (they are only pointer references), we'll simply provide empty * opaque types. * */ typedef struct ActiveCommandTrace ActiveCommandTrace; typedef struct ActiveInterpTrace ActiveInterpTrace; typedef struct _ActiveVarTrace ActiveVarTrace; typedef struct _CallFrame CallFrame; typedef struct _ExecEnv ExecEnv; typedef struct _Namespace Namespace; typedef struct _Proc Proc; typedef struct ResolverScheme ResolverScheme; typedef struct _TclRegexp TclRegexp; typedef struct _Trace Trace; /* *--------------------------------------------------------------------------- * * This structure defines an interpreter, which is a collection of commands * plus other state information related to interpreting commands, such as * variable storage. Primary responsibility for this data structure is in * tclBasic.c, but almost every TCL source file uses something in here. * *--------------------------------------------------------------------------- */ typedef struct Interp { char *result; Tcl_FreeProc *freeProc; int errorLine; #if (_TCL_VERSION >= _VERSION(8,1,0)) struct TclStubs *stubTable; TclHandle handle; #else Tcl_Obj *objResultPtr; #endif /* >= 8.1.0 */ Namespace *globalNsPtr; #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_HashTable *hiddenCmdTablePtr; ClientData interpInfo; #endif /* >= 8.1.0 */ Tcl_HashTable mathFuncTable; int numLevels; int maxNestingDepth; CallFrame *framePtr; CallFrame *varFramePtr; ActiveVarTrace *activeTracePtr; int returnCode; char *errorInfo; char *errorCode; char *appendResult; int appendAvl; int appendUsed; #if (_TCL_VERSION < _VERSION(8,1,0)) char *patterns[5]; int patLengths[5]; regexp *regexps[5]; #endif /* < 8.1.0 */ Tcl_HashTable packageTable; char *packageUnknown; int cmdCount; int evalFlags; int termOffset; #if (_TCL_VERSION >= _VERSION(8,1,0)) LiteralTable literalTable; #endif int compileEpoch; Proc *compiledProcPtr; ResolverScheme *resolverPtr; #if (_TCL_VERSION >= _VERSION(8,4,0)) Tcl_Obj *scriptFile; #else char *scriptFile; #endif /* >= 8.4.0 */ int flags; long randSeed; Trace *tracePtr; Tcl_HashTable *assocData; struct ExecEnv *execEnvPtr; Tcl_Obj *emptyObjPtr; char resultSpace[TCL_RESULT_SIZE+1]; #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_Obj *objResultPtr; Tcl_ThreadId threadId; #endif /* >= 8.1.0 */ #if (_TCL_VERSION >= _VERSION(8,4,0)) ActiveCommandTrace *activeCmdTracePtr; ActiveInterpTrace *activeInterpTracePtr; int tracesForbiddingInline; #endif /* >= 8.4.0 */ #if (_TCL_VERSION >= _VERSION(8,4,1)) #ifdef TCL_COMPILE_STATS ByteCodeStats stats; #endif /* TCL_COMPILE_STATS */ #endif /* >= 8.4.1 */ } Interp; /* * EvalFlag bits for Interp structures: * * TCL_BRACKET_TERM 1 means that the current script is terminated by * a close bracket rather than the end of the string. * TCL_ALLOW_EXCEPTIONS 1 means it's OK for the script to terminate with * a code other than TCL_OK or TCL_ERROR; 0 means * codes other than these should be turned into errors. */ #define TCL_BRACKET_TERM 1 #define TCL_ALLOW_EXCEPTIONS 4 ��������������������������������������������������������./saods9/blt3.0.1/src/bltPictJpg.c������������������������������������������������������������������0000644�0001750�0001750�00000064167�11462120062�015251� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictJpg.c -- * * This module implements JPEG file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The JPEG reader/writer is adapted from jdatasrc.c and jdatadst.c in the * Independent JPEG Group (version 6b) library distribution. * * The authors make NO WARRANTY or representation, either express or * implied, with respect to this software, its quality, accuracy, * merchantability, or fitness for a particular purpose. This software * is provided "AS IS", and you, its user, assume the entire risk as to * its quality and accuracy. * * This software is copyright (C) 1991-1998, Thomas G. Lane. All Rights * Reserved except as specified below. * * Permission is hereby granted to use, copy, modify, and distribute this * software (or portions thereof) for any purpose, without fee, subject * to these conditions: (1) If any part of the source code for this * software is distributed, then this README file must be included, with * this copyright and no-warranty notice unaltered; and any additions, * deletions, or changes to the original files must be clearly indicated * in accompanying documentation. (2) If only executable code is * distributed, then the accompanying documentation must state that "this * software is based in part on the work of the Independent JPEG Group". * (3) Permission for use of this software is granted only if the user * accepts full responsibility for any undesirable consequences; the * authors accept NO LIABILITY for damages of any kind. * */ #include "blt.h" #include "config.h" #ifdef HAVE_LIBJPG #include <tcl.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include <bltAlloc.h> #include "bltPicture.h" #include "bltPictFmts.h" #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ typedef struct _Blt_Picture Picture; #undef HAVE_STDLIB_H #ifdef WIN32 #define XMD_H 1 #endif #undef EXTERN #undef FAR #include "jpeglib.h" #include "jerror.h" #include <setjmp.h> #define PIC_PROGRESSIVE (1<<0) #define PIC_NOQUANTIZE (1<<1) #define PIC_FMT_ISASCII (1<<3) typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int quality; /* Value 0..100 */ int smoothing; /* Value 0..100 */ int compress; /* Value 0..N */ int flags; /* Flag. */ Blt_Pixel bg; int index; } JpgExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int fast; } JpgImportSwitches; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(JpgExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(JpgExportSwitches, dataObjPtr),0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(JpgExportSwitches, fileObjPtr),0}, {BLT_SWITCH_INT_NNEG, "-quality", "int", Blt_Offset(JpgExportSwitches, quality), 0}, {BLT_SWITCH_INT_NNEG, "-smooth", "int", Blt_Offset(JpgExportSwitches, smoothing),0}, {BLT_SWITCH_BITMASK, "-progressive", "", Blt_Offset(JpgExportSwitches, flags), 0, PIC_PROGRESSIVE}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(JpgExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(JpgImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_INT, "-fast", "int", Blt_Offset(JpgImportSwitches, fast), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(JpgImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; #define JPG_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ typedef struct { struct jpeg_source_mgr pub; /* public fields */ Blt_DBuffer dBuffer; /* Collects the converted data. */ } JpgReader; typedef struct { struct jpeg_destination_mgr pub; /* public fields */ Blt_DBuffer dBuffer; /* Target stream */ JOCTET *bytes; /* start of buffer */ } JpgWriter; typedef struct { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf jmpbuf; Tcl_DString dString; } JpgErrorHandler; DLLEXPORT extern Tcl_AppInitProc Blt_PictureJpgInit; extern const char *Blt_Itoa(int); static void JpgErrorProc(j_common_ptr commPtr) { JpgErrorHandler *errorPtr = (JpgErrorHandler *)commPtr->err; (*errorPtr->pub.output_message) (commPtr); longjmp(errorPtr->jmpbuf, 1); } static void JpgMessageProc(j_common_ptr commPtr) { JpgErrorHandler *errorPtr = (JpgErrorHandler *)commPtr->err; char mesg[JMSG_LENGTH_MAX]; /* Create the message and append it into the dynamic string. */ (*errorPtr->pub.format_message) (commPtr, mesg); Tcl_DStringAppend(&errorPtr->dString, " ", -1); Tcl_DStringAppend(&errorPtr->dString, mesg, -1); } static void JpgInitSource(j_decompress_ptr commPtr) { JpgReader *readerPtr = (JpgReader *)commPtr->src; readerPtr->pub.next_input_byte = Blt_DBuffer_Bytes(readerPtr->dBuffer); readerPtr->pub.bytes_in_buffer = Blt_DBuffer_Length(readerPtr->dBuffer); } static boolean JpgFillInputBuffer(j_decompress_ptr commPtr) { JpgReader *readerPtr = (JpgReader *)commPtr->src; static unsigned char eoi[2] = { 0xFF, JPEG_EOI }; /* Insert a fake EOI marker */ readerPtr->pub.next_input_byte = eoi; readerPtr->pub.bytes_in_buffer = 2; return TRUE; } static void JpgSkipInputData(j_decompress_ptr commPtr, long nBytes) { if (nBytes > 0) { JpgReader *readerPtr = (JpgReader *)commPtr->src; assert((readerPtr->pub.next_input_byte + nBytes) < (Blt_DBuffer_Bytes(readerPtr->dBuffer) + Blt_DBuffer_Length(readerPtr->dBuffer))); readerPtr->pub.next_input_byte += (size_t)nBytes; readerPtr->pub.bytes_in_buffer -= (size_t)nBytes; } } static void JpgTermSource (j_decompress_ptr commPtr) { /* Nothing to do. */ } static void JpgSetSourceFromBuffer(j_decompress_ptr commPtr, Blt_DBuffer buffer) { JpgReader *readerPtr; /* The source object is made permanent so that a series of JPEG images can * be read from the same file by calling jpeg_stdio_src only before the * first one. (If we discarded the buffer at the end of one image, we'd * likely lose the start of the next one.) This makes it unsafe to use * this manager and a different source manager serially with the same JPEG * object. Caveat programmer. */ if (commPtr->src == NULL) { /* first time for this JPEG object? */ commPtr->src = (struct jpeg_source_mgr *) (*commPtr->mem->alloc_small) ((j_common_ptr)commPtr, JPOOL_PERMANENT, sizeof(JpgReader)); readerPtr = (JpgReader *)commPtr->src; } readerPtr = (JpgReader *)commPtr->src; readerPtr->dBuffer = buffer; readerPtr->pub.init_source = JpgInitSource; readerPtr->pub.fill_input_buffer = JpgFillInputBuffer; readerPtr->pub.skip_input_data = JpgSkipInputData; /* use default method */ readerPtr->pub.resync_to_restart = jpeg_resync_to_restart; readerPtr->pub.term_source = JpgTermSource; } static void JpgInitDestination (j_compress_ptr commPtr) { JpgWriter *writerPtr = (JpgWriter *)commPtr->dest; writerPtr->bytes = (JOCTET *)(*commPtr->mem->alloc_small) ((j_common_ptr) commPtr, JPOOL_IMAGE, JPG_BUF_SIZE * sizeof(JOCTET)); writerPtr->pub.next_output_byte = writerPtr->bytes; writerPtr->pub.free_in_buffer = JPG_BUF_SIZE; } static boolean JpgEmptyOutputBuffer(j_compress_ptr commPtr) { JpgWriter *writerPtr = (JpgWriter *)commPtr->dest; if (!Blt_DBuffer_AppendData(writerPtr->dBuffer, writerPtr->bytes, JPG_BUF_SIZE)) { ERREXIT(commPtr, 10); } writerPtr->pub.next_output_byte = writerPtr->bytes; writerPtr->pub.free_in_buffer = JPG_BUF_SIZE; return TRUE; } static void JpgTermDestination (j_compress_ptr commPtr) { JpgWriter *writerPtr = (JpgWriter *)commPtr->dest; size_t nBytes = JPG_BUF_SIZE - writerPtr->pub.free_in_buffer; /* Write any data remaining in the buffer */ if (nBytes > 0) { if (!Blt_DBuffer_AppendData(writerPtr->dBuffer, writerPtr->bytes, nBytes)) { ERREXIT(commPtr, 10); } } } static void JpgSetDestinationToBuffer(j_compress_ptr commPtr, Blt_DBuffer buffer) { JpgWriter *writerPtr; /* The destination object is made permanent so that multiple JPEG images * can be written to the same file without re-executing jpeg_stdio_dest. * This makes it dangerous to use this manager and a different destination * manager serially with the same JPEG object, because their private * object sizes may be different. Caveat programmer. */ if (commPtr->dest == NULL) { /* first time for this JPEG object? */ commPtr->dest = (struct jpeg_destination_mgr *) (*commPtr->mem->alloc_small) ((j_common_ptr)commPtr, JPOOL_PERMANENT, sizeof(JpgWriter)); } writerPtr = (JpgWriter *)commPtr->dest; writerPtr->pub.init_destination = JpgInitDestination; writerPtr->pub.empty_output_buffer = JpgEmptyOutputBuffer; writerPtr->pub.term_destination = JpgTermDestination; writerPtr->dBuffer = buffer; } /* *--------------------------------------------------------------------------- * * IsJpg -- * * Attempts to parse a JPG file header. * * Results: * Returns 1 is the header is JPG and 0 otherwise. Note that the * validity of the header contents is not checked here. That's done in * Blt_JpgToPicture. * *--------------------------------------------------------------------------- */ static int IsJpg(Blt_DBuffer buffer) { JpgErrorHandler error; struct jpeg_decompress_struct cinfo; int bool; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.dct_method = JDCT_IFAST; cinfo.err = jpeg_std_error(&error.pub); error.pub.error_exit = JpgErrorProc; error.pub.output_message = JpgMessageProc; /* Initialize possible error message */ bool = FALSE; Tcl_DStringInit(&error.dString); if (setjmp(error.jmpbuf)) { goto done; } jpeg_create_decompress(&cinfo); JpgSetSourceFromBuffer(&cinfo, buffer); bool = (jpeg_read_header(&cinfo, TRUE) == JPEG_HEADER_OK); done: jpeg_destroy_decompress(&cinfo); Tcl_DStringFree(&error.dString); return bool; } /* *--------------------------------------------------------------------------- * * JpgToPicture -- * * Reads a JPEG data buffer and converts it into a picture. * * Results: * The picture is returned. If an error occured, such as the * designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain JpgToPicture( Tcl_Interp *interp, /* Interpreter to report errors back to. */ const char *fileName, /* Name of file used to fill the dynamic * buffer. */ Blt_DBuffer buffer, /* Contents of the above file. */ JpgImportSwitches *switchesPtr) { Blt_Chain chain; JSAMPLE **rows; JpgErrorHandler error; Picture *destPtr; int samplesPerRow; struct jpeg_decompress_struct cinfo; unsigned int width, height; destPtr = NULL; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.dct_method = (switchesPtr->fast) ? JDCT_IFAST : JDCT_ISLOW; cinfo.err = jpeg_std_error(&error.pub); error.pub.error_exit = JpgErrorProc; error.pub.output_message = JpgMessageProc; /* Initialize possible error message */ Tcl_DStringInit(&error.dString); Tcl_DStringAppend(&error.dString, "error reading \"", -1); Tcl_DStringAppend(&error.dString, fileName, -1); Tcl_DStringAppend(&error.dString, "\": ", -1); if (setjmp(error.jmpbuf)) { jpeg_destroy_decompress(&cinfo); Tcl_DStringResult(interp, &error.dString); return NULL; } jpeg_create_decompress(&cinfo); JpgSetSourceFromBuffer(&cinfo, buffer); jpeg_read_header(&cinfo, TRUE); /* Step 3: read file parameters */ jpeg_start_decompress(&cinfo); /* Step 5: Start decompressor */ width = cinfo.output_width; height = cinfo.output_height; if ((width < 1) || (height < 1)) { Tcl_AppendResult(interp, "error reading \"", fileName, "\": bad JPEG image size", (char *)NULL); return NULL; } /* JSAMPLEs per row in output buffer */ samplesPerRow = width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with * image */ rows = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, samplesPerRow, 1); destPtr = Blt_CreatePicture(width, height); if (cinfo.output_components == 1) { Blt_Pixel *destRowPtr; destRowPtr = destPtr->bits; while (cinfo.output_scanline < height) { JSAMPLE *bp; Blt_Pixel *dp; int i; dp = destRowPtr; jpeg_read_scanlines(&cinfo, rows, 1); bp = rows[0]; for (i = 0; i < (int)width; i++) { dp->Red = dp->Green = dp->Blue = *bp++; dp->Alpha = ALPHA_OPAQUE; dp++; } destRowPtr += destPtr->pixelsPerRow; } } else { Blt_Pixel *destRowPtr; destRowPtr = destPtr->bits; while (cinfo.output_scanline < height) { JSAMPLE *bp; Blt_Pixel *dp; int i; dp = destRowPtr; jpeg_read_scanlines(&cinfo, rows, 1); bp = rows[0]; for (i = 0; i < (int)width; i++) { dp->Red = *bp++; dp->Green = *bp++; dp->Blue = *bp++; dp->Alpha = ALPHA_OPAQUE; dp++; } destRowPtr += destPtr->pixelsPerRow; } destPtr->flags |= BLT_PIC_COLOR; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); if (error.pub.num_warnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "JPG_READ_WARNINGS", Tcl_DStringValue(&error.dString), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&error.dString); chain = Blt_Chain_Create(); Blt_Chain_Append(chain, destPtr); return chain; } /* *--------------------------------------------------------------------------- * * PictureToJpg -- * * Writes a JPEG format image to the provided dynamic buffer. * * Results: * A standard TCL result. If an error occured, TCL_ERROR is returned and * an error message will be place in the interpreter result. Otherwise, * the dynamic buffer will contain the binary output of the image. * * Side Effects: * Memory is allocated for the dynamic buffer. * *--------------------------------------------------------------------------- */ static int PictureToJpg( Tcl_Interp *interp, /* Interpreter to report errors back to. */ Blt_Picture original, /* Picture source. */ Blt_DBuffer buffer, /* Destination buffer to contain the JPEG * image. */ JpgExportSwitches *switchesPtr) { JpgErrorHandler error; int result, nColors; struct jpeg_compress_struct cinfo; Picture *srcPtr; result = TCL_ERROR; srcPtr = original; /* Step 1: allocate and initialize JPEG compression object */ cinfo.err = jpeg_std_error(&error.pub); error.pub.error_exit = JpgErrorProc; error.pub.output_message = JpgMessageProc; /* Initialize possible error message */ Tcl_DStringInit(&error.dString); Tcl_DStringAppend(&error.dString, "error writing jpg: ", -1); if (setjmp(error.jmpbuf)) { /* Transfer the error message to the interpreter result. */ Tcl_DStringResult(interp, &error.dString); goto bad; } /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&cinfo); /* Step 2: specify data destination (eg, a file) */ JpgSetDestinationToBuffer(&cinfo, buffer); /* Step 3: set parameters for compression */ /* First we supply a description of the input image. Four fields of the * cinfo struct must be filled in: */ cinfo.image_width = srcPtr->width; cinfo.image_height = srcPtr->height; if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_Picture unassoc; /* * The picture has an alpha burned into the components. * Create a temporary copy removing pre-multiplied alphas. */ unassoc = Blt_ClonePicture(srcPtr); Blt_UnassociateColors(unassoc); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = unassoc; } nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); if (Blt_PictureIsColor(srcPtr)) { cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ } else { cinfo.input_components = 1; /* # of color components per pixel */ cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */ } jpeg_set_defaults(&cinfo); /* * Now you can set any non-default parameters you wish to. Here we just * illustrate the use of quality (quantization table) scaling: */ /* limit to baseline-JPEG values */ jpeg_set_quality(&cinfo, switchesPtr->quality, TRUE); if (switchesPtr->flags & PIC_PROGRESSIVE) { jpeg_simple_progression(&cinfo); } if (switchesPtr->smoothing > 0) { cinfo.smoothing_factor = switchesPtr->smoothing; } /* Step 4: Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Step 5: while (scan lines remain to be written) */ /* jpeg_write_scanlines(...); */ { int y; int row_stride; JSAMPLE *destRow; Blt_Pixel *srcRowPtr; JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ /* JSAMPLEs per row in image_buffer */ row_stride = srcPtr->width * cinfo.input_components; destRow = Blt_AssertMalloc(sizeof(JSAMPLE) * row_stride); srcRowPtr = srcPtr->bits; if (cinfo.input_components == 3) { for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; JSAMPLE *dp; dp = destRow; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp += 3; } row_pointer[0] = destRow; jpeg_write_scanlines(&cinfo, row_pointer, 1); srcRowPtr += srcPtr->pixelsPerRow; } } else { for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; JSAMPLE *dp; dp = destRow; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { *dp++ = sp->Red; } row_pointer[0] = destRow; jpeg_write_scanlines(&cinfo, row_pointer, 1); srcRowPtr += srcPtr->pixelsPerRow; } } Blt_Free(destRow); } /* Step 6: Finish compression */ jpeg_finish_compress(&cinfo); result = TCL_OK; bad: /* Step 7: release JPEG compression object */ jpeg_destroy_compress(&cinfo); if (error.pub.num_warnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "JPG_WRITE_WARNINGS", Tcl_DStringValue(&error.dString), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&error.dString); if (srcPtr != original) { Blt_FreePicture(srcPtr); } return result; } static Blt_Chain ReadJpg(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { JpgImportSwitches switches; memset(&switches, 0, sizeof(switches)); return JpgToPicture(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WriteJpg(Tcl_Interp *interp, Blt_Picture picture) { Tcl_Obj *objPtr; Blt_DBuffer dbuffer; JpgExportSwitches switches; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.quality = 100; switches.smoothing = 0; switches.flags = 0; /* No progressive or compression. */ switches.bg.u32 = 0xFFFFFFFF; /* white */ objPtr = NULL; dbuffer = Blt_DBuffer_Create(); if (PictureToJpg(interp, picture, dbuffer, &switches) == TCL_OK) { char *bytes; bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } } Blt_DBuffer_Destroy(dbuffer); return objPtr; } static Blt_Chain ImportJpg(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_DBuffer dbuffer; Blt_Chain chain; const char *string; JpgImportSwitches switches; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_SaveFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = JpgToPicture(interp, string, dbuffer, &switches); error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportJpg(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer dbuffer; Blt_Picture picture; JpgExportSwitches switches; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.quality = 100; switches.smoothing = 0; switches.flags = 0; /* No progressive or compression. */ switches.bg.u32 = 0xFFFFFFFF; /* white */ switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if (switches.quality == 0) { switches.quality = 100; /* Default quality setting. */ } else if (switches.quality > 100) { switches.quality = 100; /* Maximum quality setting. */ } if (switches.smoothing > 100) { switches.smoothing = 100; /* Maximum smoothing setting. */ } dbuffer = Blt_DBuffer_Create(); result = PictureToJpg(interp, picture, dbuffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { const char *fileName; /* Write the image into the designated file. */ fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; /* Write the image into the designated TCL variable. */ objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; /* Return the image as a base64 string in the interpreter result. */ result = TCL_ERROR; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); result = TCL_OK; } } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PictureJpgInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_jpg", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "jpg", /* Name of format. */ IsJpg, /* Format discovery procedure. */ ReadJpg, /* Read format procedure. */ WriteJpg, /* Write format procedure. */ ImportJpg, /* Import format procedure. */ ExportJpg); /* Export format procedure. */ } #endif /* HAVE_LIBJPG */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrAxis.c�������������������������������������������������������������������0000644�0001750�0001750�00000514047�11462120062�015103� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrAxis.c -- * * This module implements coordinate axes for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" #include "bltGrElem.h" #include <X11/Xutil.h> #define MAXTICKS 10001 #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) /* * Round x in terms of units */ #define UROUND(x,u) (Round((x)/(u))*(u)) #define UCEIL(x,u) (ceil((x)/(u))*(u)) #define UFLOOR(x,u) (floor((x)/(u))*(u)) #define NUMDIGITS 15 /* Specifies the number of digits of * accuracy used when outputting axis * tick labels. */ enum TickRange { AXIS_TIGHT, AXIS_LOOSE, AXIS_ALWAYS_LOOSE }; #define AXIS_PAD_TITLE 2 /* Padding for axis title. */ /* Axis flags: */ #define AXIS_AUTO_MAJOR (1<<16) /* Auto-generate major ticks. */ #define AXIS_AUTO_MINOR (1<<17) /* Auto-generate minor ticks. */ #define AXIS_USE (1<<18) /* Axis is displayed on the screen via * the "use" operation */ #define AXIS_GRID (1<<19) /* Display grid lines. */ #define AXIS_GRIDMINOR (1<<20) /* Display grid lines for minor * ticks. */ #define AXIS_SHOWTICKS (1<<21) /* Display axis ticks. */ #define AXIS_EXTERIOR (1<<22) /* Axis is exterior to the plot. */ #define AXIS_CHECK_LIMITS (1<<23) /* Validate user-defined axis limits. */ #define HORIZMARGIN(m) (!((m)->site & 0x1)) /* Even sites are horizontal */ typedef struct { int axis; /* Length of the axis. */ int t1; /* Length of a major tick (in * pixels). */ int t2; /* Length of a minor tick (in * pixels). */ int label; /* Distance from axis to tick label. */ } AxisInfo; typedef struct { const char *name; ClassId classId; int margin, invertMargin; } AxisName; static AxisName axisNames[] = { { "x", CID_AXIS_X, MARGIN_BOTTOM, MARGIN_LEFT }, { "y", CID_AXIS_Y, MARGIN_LEFT, MARGIN_BOTTOM }, { "x2", CID_AXIS_X, MARGIN_TOP, MARGIN_RIGHT }, { "y2", CID_AXIS_Y, MARGIN_RIGHT, MARGIN_TOP } } ; static int nAxisNames = sizeof(axisNames) / sizeof(AxisName); static Blt_OptionParseProc ObjToLimitProc; static Blt_OptionPrintProc LimitToObjProc; static Blt_CustomOption limitOption = { ObjToLimitProc, LimitToObjProc, NULL, (ClientData)0 }; static Blt_OptionFreeProc FreeTicksProc; static Blt_OptionParseProc ObjToTicksProc; static Blt_OptionPrintProc TicksToObjProc; static Blt_CustomOption majorTicksOption = { ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MAJOR, }; static Blt_CustomOption minorTicksOption = { ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MINOR, }; static Blt_OptionFreeProc FreeAxisProc; static Blt_OptionPrintProc AxisToObjProc; static Blt_OptionParseProc ObjToAxisProc; Blt_CustomOption bltXAxisOption = { ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_X }; Blt_CustomOption bltYAxisOption = { ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_Y }; static Blt_OptionFreeProc FreeFormatProc; static Blt_OptionParseProc ObjToFormatProc; static Blt_OptionPrintProc FormatToObjProc; static Blt_CustomOption formatOption = { ObjToFormatProc, FormatToObjProc, FreeFormatProc, (ClientData)0, }; static Blt_OptionParseProc ObjToLooseProc; static Blt_OptionPrintProc LooseToObjProc; static Blt_CustomOption looseOption = { ObjToLooseProc, LooseToObjProc, NULL, (ClientData)0, }; static Blt_OptionParseProc ObjToUseProc; static Blt_OptionPrintProc UseToObjProc; static Blt_CustomOption useOption = { ObjToUseProc, UseToObjProc, NULL, (ClientData)0 }; #define DEF_AXIS_ACTIVEBACKGROUND STD_ACTIVE_BACKGROUND #define DEF_AXIS_ACTIVEFOREGROUND STD_ACTIVE_FOREGROUND #define DEF_AXIS_ACTIVERELIEF "flat" #define DEF_AXIS_ANGLE "0.0" #define DEF_AXIS_BACKGROUND (char *)NULL #define DEF_AXIS_BORDERWIDTH "0" #define DEF_AXIS_CHECKLIMITS "0" #define DEF_AXIS_COMMAND (char *)NULL #define DEF_AXIS_DESCENDING "0" #define DEF_AXIS_FOREGROUND RGB_BLACK #define DEF_AXIS_GRID_BARCHART "1" #define DEF_AXIS_GRIDCOLOR RGB_GREY64 #define DEF_AXIS_GRIDDASHES "dot" #define DEF_AXIS_GRID_GRAPH "0" #define DEF_AXIS_GRIDLINEWIDTH "0" #define DEF_AXIS_GRIDMINOR "1" #define DEF_AXIS_GRIDMINOR_COLOR RGB_GREY64 #define DEF_AXIS_HIDE "0" #define DEF_AXIS_JUSTIFY "c" #define DEF_AXIS_LIMITS_FORMAT (char *)NULL #define DEF_AXIS_LINEWIDTH "1" #define DEF_AXIS_LOGSCALE "0" #define DEF_AXIS_LOOSE "0" #define DEF_AXIS_RANGE "0.0" #define DEF_AXIS_RELIEF "flat" #define DEF_AXIS_SCROLL_INCREMENT "10" #define DEF_AXIS_SHIFTBY "0.0" #define DEF_AXIS_SHOWTICKS "1" #define DEF_AXIS_STEP "0.0" #define DEF_AXIS_STEP "0.0" #define DEF_AXIS_SUBDIVISIONS "2" #define DEF_AXIS_TAGS "all" #define DEF_AXIS_EXTERIOR "1" #define DEF_AXIS_TICK_ANCHOR "c" #define DEF_AXIS_LIMITS_FONT STD_FONT_NUMBERS #define DEF_AXIS_TICKFONT_GRAPH STD_FONT_NUMBERS #define DEF_AXIS_TICKFONT_BARCHART STD_FONT_SMALL #define DEF_AXIS_TICKLENGTH "4" #define DEF_AXIS_DIVISIONS "10" #define DEF_AXIS_TITLE_ALTERNATE "0" #define DEF_AXIS_TITLE_FG RGB_BLACK #define DEF_AXIS_TITLE_FONT "{Sans Serif} 10" #define DEF_AXIS_X_STEP_BARCHART "1.0" #define DEF_AXIS_X_SUBDIVISIONS_BARCHART "0" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_AXIS_ACTIVEBACKGROUND, Blt_Offset(Axis, activeBg), ALL_GRAPHS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_AXIS_ACTIVEFOREGROUND, Blt_Offset(Axis, activeFgColor), ALL_GRAPHS}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_AXIS_ACTIVERELIEF, Blt_Offset(Axis, activeRelief), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-autorange", "autoRange", "AutoRange", DEF_AXIS_RANGE, Blt_Offset(Axis, windowSize), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_AXIS_BACKGROUND, Blt_Offset(Axis, normalBg), ALL_GRAPHS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_AXIS_TAGS, Blt_Offset(Axis, obj.tags), ALL_GRAPHS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, ALL_GRAPHS}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_AXIS_BORDERWIDTH, Blt_Offset(Axis, borderWidth), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-checklimits", "checkLimits", "CheckLimits", DEF_AXIS_CHECKLIMITS, Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)AXIS_CHECK_LIMITS}, {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_AXIS_FOREGROUND, Blt_Offset(Axis, tickColor), ALL_GRAPHS}, {BLT_CONFIG_STRING, "-command", "command", "Command", DEF_AXIS_COMMAND, Blt_Offset(Axis, formatCmd), BLT_CONFIG_NULL_OK | ALL_GRAPHS}, {BLT_CONFIG_BOOLEAN, "-descending", "descending", "Descending", DEF_AXIS_DESCENDING, Blt_Offset(Axis, descending), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-exterior", "exterior", "exterior", DEF_AXIS_EXTERIOR, Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)AXIS_EXTERIOR}, {BLT_CONFIG_SYNONYM, "-fg", "color", (char *)NULL, (char *)NULL, 0, ALL_GRAPHS}, {BLT_CONFIG_SYNONYM, "-foreground", "color", (char *)NULL, (char *)NULL, 0, ALL_GRAPHS}, {BLT_CONFIG_BITMASK, "-grid", "grid", "Grid", DEF_AXIS_GRID_BARCHART, Blt_Offset(Axis, flags), BARCHART, (Blt_CustomOption *)AXIS_GRID}, {BLT_CONFIG_BITMASK, "-grid", "grid", "Grid", DEF_AXIS_GRID_GRAPH, Blt_Offset(Axis, flags), GRAPH | STRIPCHART, (Blt_CustomOption *)AXIS_GRID}, {BLT_CONFIG_COLOR, "-gridcolor", "gridColor", "GridColor", DEF_AXIS_GRIDCOLOR, Blt_Offset(Axis, major.color), ALL_GRAPHS}, {BLT_CONFIG_DASHES, "-griddashes", "gridDashes", "GridDashes", DEF_AXIS_GRIDDASHES, Blt_Offset(Axis, major.dashes), BLT_CONFIG_NULL_OK | ALL_GRAPHS}, {BLT_CONFIG_PIXELS_NNEG, "-gridlinewidth", "gridLineWidth", "GridLineWidth", DEF_AXIS_GRIDLINEWIDTH, Blt_Offset(Axis, major.lineWidth), BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS}, {BLT_CONFIG_BITMASK, "-gridminor", "gridMinor", "GridMinor", DEF_AXIS_GRIDMINOR, Blt_Offset(Axis, flags), BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS, (Blt_CustomOption *)AXIS_GRIDMINOR}, {BLT_CONFIG_COLOR, "-gridminorcolor", "gridMinorColor", "GridColor", DEF_AXIS_GRIDMINOR_COLOR, Blt_Offset(Axis, minor.color), ALL_GRAPHS}, {BLT_CONFIG_DASHES, "-gridminordashes", "gridMinorDashes", "GridDashes", DEF_AXIS_GRIDDASHES, Blt_Offset(Axis, minor.dashes), BLT_CONFIG_NULL_OK | ALL_GRAPHS}, {BLT_CONFIG_PIXELS_NNEG, "-gridminorlinewidth", "gridMinorLineWidth", "GridLineWidth", DEF_AXIS_GRIDLINEWIDTH, Blt_Offset(Axis, minor.lineWidth), BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_AXIS_HIDE, Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_AXIS_JUSTIFY, Blt_Offset(Axis, titleJustify), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-labeloffset", "labelOffset", "LabelOffset", (char *)NULL, Blt_Offset(Axis, labelOffset), ALL_GRAPHS}, {BLT_CONFIG_COLOR, "-limitscolor", "limitsColor", "Color", DEF_AXIS_FOREGROUND, Blt_Offset(Axis, limitsTextStyle.color), ALL_GRAPHS}, {BLT_CONFIG_FONT, "-limitsfont", "limitsFont", "Font", DEF_AXIS_LIMITS_FONT, Blt_Offset(Axis, limitsTextStyle.font), ALL_GRAPHS}, {BLT_CONFIG_CUSTOM, "-limitsformat", "limitsFormat", "LimitsFormat", (char *)NULL, Blt_Offset(Axis, limitsFormats), BLT_CONFIG_NULL_OK | ALL_GRAPHS, &formatOption}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_AXIS_LINEWIDTH, Blt_Offset(Axis, lineWidth), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-logscale", "logScale", "LogScale", DEF_AXIS_LOGSCALE, Blt_Offset(Axis, logScale), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-loose", "loose", "Loose", DEF_AXIS_LOOSE, 0, ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, &looseOption}, {BLT_CONFIG_CUSTOM, "-majorticks", "majorTicks", "MajorTicks", (char *)NULL, Blt_Offset(Axis, t1Ptr), BLT_CONFIG_NULL_OK | ALL_GRAPHS, &majorTicksOption}, {BLT_CONFIG_CUSTOM, "-max", "max", "Max", (char *)NULL, Blt_Offset(Axis, reqMax), ALL_GRAPHS, &limitOption}, {BLT_CONFIG_CUSTOM, "-min", "min", "Min", (char *)NULL, Blt_Offset(Axis, reqMin), ALL_GRAPHS, &limitOption}, {BLT_CONFIG_CUSTOM, "-minorticks", "minorTicks", "MinorTicks", (char *)NULL, Blt_Offset(Axis, t2Ptr), BLT_CONFIG_NULL_OK | ALL_GRAPHS, &minorTicksOption}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_AXIS_RELIEF, Blt_Offset(Axis, relief), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_AXIS_ANGLE, Blt_Offset(Axis, tickAngle), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-scrollcommand", "scrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(Axis, scrollCmdObjPtr), ALL_GRAPHS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-scrollincrement", "scrollIncrement", "ScrollIncrement", DEF_AXIS_SCROLL_INCREMENT, Blt_Offset(Axis, scrollUnits), ALL_GRAPHS|BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-scrollmax", "scrollMax", "ScrollMax", (char *)NULL, Blt_Offset(Axis, reqScrollMax), ALL_GRAPHS, &limitOption}, {BLT_CONFIG_CUSTOM, "-scrollmin", "scrollMin", "ScrollMin", (char *)NULL, Blt_Offset(Axis, reqScrollMin), ALL_GRAPHS, &limitOption}, {BLT_CONFIG_DOUBLE, "-shiftby", "shiftBy", "ShiftBy", DEF_AXIS_SHIFTBY, Blt_Offset(Axis, shiftBy), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-showticks", "showTicks", "ShowTicks", DEF_AXIS_SHOWTICKS, Blt_Offset(Axis, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)AXIS_SHOWTICKS}, {BLT_CONFIG_DOUBLE, "-stepsize", "stepSize", "StepSize", DEF_AXIS_STEP, Blt_Offset(Axis, reqStep), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT, "-subdivisions", "subdivisions", "Subdivisions", DEF_AXIS_SUBDIVISIONS, Blt_Offset(Axis, reqNumMinorTicks), ALL_GRAPHS}, {BLT_CONFIG_ANCHOR, "-tickanchor", "tickAnchor", "Anchor", DEF_AXIS_TICK_ANCHOR, Blt_Offset(Axis, reqTickAnchor), ALL_GRAPHS}, {BLT_CONFIG_FONT, "-tickfont", "tickFont", "Font", DEF_AXIS_TICKFONT_GRAPH, Blt_Offset(Axis, tickFont), GRAPH | STRIPCHART}, {BLT_CONFIG_FONT, "-tickfont", "tickFont", "Font", DEF_AXIS_TICKFONT_BARCHART, Blt_Offset(Axis, tickFont), BARCHART}, {BLT_CONFIG_PIXELS_NNEG, "-ticklength", "tickLength", "TickLength", DEF_AXIS_TICKLENGTH, Blt_Offset(Axis, tickLength), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT, "-tickdefault", "tickDefault", "TickDefault", DEF_AXIS_DIVISIONS, Blt_Offset(Axis, reqNumMajorTicks), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-title", "title", "Title", (char *)NULL, Blt_Offset(Axis, title), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | ALL_GRAPHS}, {BLT_CONFIG_BOOLEAN, "-titlealternate", "titleAlternate", "TitleAlternate", DEF_AXIS_TITLE_ALTERNATE, Blt_Offset(Axis, titleAlternate), BLT_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS}, {BLT_CONFIG_COLOR, "-titlecolor", "titleColor", "Color", DEF_AXIS_FOREGROUND, Blt_Offset(Axis, titleColor), ALL_GRAPHS}, {BLT_CONFIG_FONT, "-titlefont", "titleFont", "Font", DEF_AXIS_TITLE_FONT, Blt_Offset(Axis, titleFont), ALL_GRAPHS}, {BLT_CONFIG_CUSTOM, "-use", "use", "Use", (char *)NULL, 0, ALL_GRAPHS, &useOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* Forward declarations */ static void DestroyAxis(Axis *axisPtr); static Tcl_FreeProc FreeAxis; static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, Axis **axisPtrPtr); static void TimeScaleAxis(Axis *axisPtr, double min, double max); static int lastMargin; typedef int (GraphAxisProc)(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv); typedef int (GraphVirtualAxisProc)(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv); INLINE static double Clamp(double x) { return (x < 0.0) ? 0.0 : (x > 1.0) ? 1.0 : x; } INLINE static int Round(double x) { return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); } static void SetAxisRange(AxisRange *rangePtr, double min, double max) { rangePtr->min = min; rangePtr->max = max; rangePtr->range = max - min; if (FABS(rangePtr->range) < DBL_EPSILON) { rangePtr->range = 1.0; } rangePtr->scale = 1.0 / rangePtr->range; } /* *--------------------------------------------------------------------------- * * InRange -- * * Determines if a value lies within a given range. * * The value is normalized and compared against the interval [0..1], * where 0.0 is the minimum and 1.0 is the maximum. DBL_EPSILON is the * smallest number that can be represented on the host machine, such that * (1.0 + epsilon) != 1.0. * * Please note, *max* can't equal *min*. * * Results: * If the value is within the interval [min..max], 1 is returned; 0 * otherwise. * *--------------------------------------------------------------------------- */ INLINE static int InRange(double x, AxisRange *rangePtr) { if (rangePtr->range < DBL_EPSILON) { return (FABS(rangePtr->max - x) >= DBL_EPSILON); } else { double norm; norm = (x - rangePtr->min) * rangePtr->scale; return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON)); } } INLINE static int AxisIsHorizontal(Axis *axisPtr) { Graph *graphPtr = axisPtr->obj.graphPtr; return ((axisPtr->obj.classId == CID_AXIS_Y) == graphPtr->inverted); } static void ReleaseAxis(Axis *axisPtr) { if (axisPtr != NULL) { axisPtr->refCount--; assert(axisPtr->refCount >= 0); if (axisPtr->refCount == 0) { axisPtr->flags |= DELETE_PENDING; Tcl_EventuallyFree(axisPtr, FreeAxis); } } } /* *----------------------------------------------------------------------------- * Custom option parse and print procedures *----------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeAxisProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { Axis **axisPtrPtr = (Axis **)(widgRec + offset); if (*axisPtrPtr != NULL) { ReleaseAxis(*axisPtrPtr); *axisPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToAxisProc -- * * Converts the name of an axis to a pointer to its axis structure. * * Results: * The return value is a standard TCL result. The axis flags are written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToAxisProc( ClientData clientData, /* Class identifier of the type of * axis we are looking for. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Used to look up pointer to graph. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Offset to field in structure */ int flags) { ClassId classId = (ClassId)clientData; Axis **axisPtrPtr = (Axis **)(widgRec + offset); Axis *axisPtr; Graph *graphPtr; if (flags & BLT_CONFIG_NULL_OK) { const char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { ReleaseAxis(*axisPtrPtr); *axisPtrPtr = NULL; return TCL_OK; } } graphPtr = Blt_GetGraphFromWindowData(tkwin); assert(graphPtr); if (GetAxisByClass(interp, graphPtr, objPtr, classId, &axisPtr) != TCL_OK) { return TCL_ERROR; } ReleaseAxis(*axisPtrPtr); *axisPtrPtr = axisPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisToObjProc -- * * Convert the window coordinates into a string. * * Results: * The string representing the coordinate position is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * AxisToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Pointer to structure record .*/ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Axis *axisPtr = *(Axis **)(widgRec + offset); const char *name; name = (axisPtr == NULL) ? "" : axisPtr->obj.name; return Tcl_NewStringObj(name, -1); } /*ARGSUSED*/ static void FreeFormatProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); if (axisPtr->limitsFormats != NULL) { Blt_Free(axisPtr->limitsFormats); axisPtr->limitsFormats = NULL; } axisPtr->nFormats = 0; } /* *--------------------------------------------------------------------------- * * ObjToFormatProc -- * * Convert the name of virtual axis to an pointer. * * Results: * The return value is a standard TCL result. The axis flags are written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToFormatProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Not used. */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); const char **argv; int argc; if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) != TCL_OK) { return TCL_ERROR; } if (argc > 2) { Tcl_AppendResult(interp, "too many elements in limits format list \"", Tcl_GetString(objPtr), "\"", (char *)NULL); Blt_Free(argv); return TCL_ERROR; } if (axisPtr->limitsFormats != NULL) { Blt_Free(axisPtr->limitsFormats); } axisPtr->limitsFormats = argv; axisPtr->nFormats = argc; return TCL_OK; } /* *--------------------------------------------------------------------------- * * FormatToObjProc -- * * Convert the window coordinates into a string. * * Results: * The string representing the coordinate position is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * FormatToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); Tcl_Obj *objPtr; if (axisPtr->nFormats == 0) { objPtr = Tcl_NewStringObj("", -1); } else { const char *string; string = Tcl_Merge(axisPtr->nFormats, axisPtr->limitsFormats); objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToLimitProc -- * * Convert the string representation of an axis limit into its numeric * form. * * Results: * The return value is a standard TCL result. The symbol type is written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLimitProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { double *limitPtr = (double *)(widgRec + offset); const char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *limitPtr = Blt_NaN(); } else if (Blt_ExprDoubleFromObj(interp, objPtr, limitPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LimitToObjProc -- * * Convert the floating point axis limits into a string. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LimitToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { double limit = *(double *)(widgRec + offset); Tcl_Obj *objPtr; if (DEFINED(limit)) { objPtr = Tcl_NewDoubleObj(limit); } else { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToUseProc -- * * Convert the string representation of the margin to use into its * numeric form. * * Results: * The return value is a standard TCL result. The use type is written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToUseProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); AxisName *p, *pend; Blt_Chain chain; Graph *graphPtr; const char *string; int margin; graphPtr = axisPtr->obj.graphPtr; if (axisPtr->refCount == 0) { /* Clear the axis class if it's not currently used by an element.*/ Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); } /* Remove the axis from the margin's use list and clear its use flag. */ if (axisPtr->link != NULL) { Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); } axisPtr->flags &= ~AXIS_USE; string = Tcl_GetString(objPtr); if ((string == NULL) || (string[0] == '\0')) { goto done; } for (p = axisNames, pend = axisNames + nAxisNames; p < pend; p++) { if (strcmp(p->name, string) == 0) { break; /* Found the axis name. */ } } if (p == pend) { Tcl_AppendResult(interp, "unknown axis type \"", string, "\": " "should be x, y, x1, y2, or \"\".", (char *)NULL); return TCL_ERROR; } /* Check the axis class. Can't use the axis if it's already being used as * another type. */ if (axisPtr->obj.classId == CID_NONE) { Blt_GraphSetObjectClass(&axisPtr->obj, p->classId); } else if (axisPtr->obj.classId != p->classId) { Tcl_AppendResult(interp, "wrong type for axis \"", axisPtr->obj.name, "\": can't use ", axisPtr->obj.className, " type axis.", (char *)NULL); return TCL_ERROR; } margin = (graphPtr->inverted) ? p->invertMargin : p->margin; chain = graphPtr->margins[margin].axes; if (axisPtr->link != NULL) { /* Move the axis from the old margin's "use" list to the new. */ Blt_Chain_AppendLink(chain, axisPtr->link); } else { axisPtr->link = Blt_Chain_Append(chain, axisPtr); } axisPtr->chain = chain; axisPtr->flags |= AXIS_USE; axisPtr->margin = margin; done: graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); /* When any axis changes, we need to layout the entire graph. */ graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * UseToObjProc -- * * Convert the floating point axis limits into a string. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * UseToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); if (axisPtr->margin == MARGIN_NONE) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(axisNames[axisPtr->margin].name, -1); } /*ARGSUSED*/ static void FreeTicksProc( ClientData clientData, /* Either AXIS_AUTO_MAJOR or * AXIS_AUTO_MINOR. */ Display *display, /* Not used. */ char *widgRec, int offset) { Axis *axisPtr = (Axis *)widgRec; Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); unsigned long mask = (unsigned long)clientData; axisPtr->flags |= mask; if (*ticksPtrPtr != NULL) { Blt_Free(*ticksPtrPtr); } *ticksPtrPtr = NULL; } /* *--------------------------------------------------------------------------- * * ObjToTicksProc -- * * * Results: * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTicksProc( ClientData clientData, /* Either AXIS_AUTO_MAJOR or * AXIS_AUTO_MINOR. */ Tcl_Interp *interp, /* Interpreter to send results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)widgRec; Tcl_Obj **objv; Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); Ticks *ticksPtr; int objc; unsigned long mask = (unsigned long)clientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } axisPtr->flags |= mask; ticksPtr = NULL; if (objc > 0) { int i; ticksPtr = Blt_AssertMalloc(sizeof(Ticks) + (objc*sizeof(double))); for (i = 0; i < objc; i++) { double value; if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { Blt_Free(ticksPtr); return TCL_ERROR; } ticksPtr->values[i] = value; } ticksPtr->nTicks = objc; axisPtr->flags &= ~mask; } FreeTicksProc(clientData, Tk_Display(tkwin), widgRec, offset); *ticksPtrPtr = ticksPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * TicksToObjProc -- * * Convert array of tick coordinates to a list. * * Results: * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TicksToObjProc( ClientData clientData, /* Either AXIS_AUTO_MAJOR or * AXIS_AUTO_MINOR. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Axis *axisPtr; Tcl_Obj *listObjPtr; Ticks *ticksPtr; unsigned long mask; axisPtr = (Axis *)widgRec; ticksPtr = *(Ticks **) (widgRec + offset); mask = (unsigned long)clientData; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if ((ticksPtr != NULL) && ((axisPtr->flags & mask) == 0)) { unsigned int i; for (i = 0; i < ticksPtr->nTicks; i++) { Tcl_Obj *objPtr; objPtr = Tcl_NewDoubleObj(ticksPtr->values[i]); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } /* *--------------------------------------------------------------------------- * * ObjToLooseProc -- * * Convert a string to one of three values. * 0 - false, no, off * 1 - true, yes, on * 2 - always * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLooseProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing new value. */ char *widgRec, /* Pointer to structure record. */ int offset, /* Not used. */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)(widgRec); Tcl_Obj **objv; int i; int objc; int values[2]; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if ((objc < 1) || (objc > 2)) { Tcl_AppendResult(interp, "wrong # elements in loose value \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i++) { const char *string; string = Tcl_GetString(objv[i]); if ((string[0] == 'a') && (strcmp(string, "always") == 0)) { values[i] = AXIS_ALWAYS_LOOSE; } else { int bool; if (Tcl_GetBooleanFromObj(interp, objv[i], &bool) != TCL_OK) { return TCL_ERROR; } values[i] = bool; } } axisPtr->looseMin = axisPtr->looseMax = values[0]; if (objc > 1) { axisPtr->looseMax = values[1]; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LooseToObjProc -- * * Results: * The string representation of the auto boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LooseToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { Axis *axisPtr = (Axis *)widgRec; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (axisPtr->looseMin == AXIS_TIGHT) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(FALSE)); } else if (axisPtr->looseMin == AXIS_LOOSE) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(TRUE)); } else if (axisPtr->looseMin == AXIS_ALWAYS_LOOSE) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("always", 6)); } if (axisPtr->looseMin != axisPtr->looseMax) { if (axisPtr->looseMax == AXIS_TIGHT) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(FALSE)); } else if (axisPtr->looseMax == AXIS_LOOSE) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(TRUE)); } else if (axisPtr->looseMax == AXIS_ALWAYS_LOOSE) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("always", 6)); } } return listObjPtr; } static void FreeTickLabels(Blt_Chain chain) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { TickLabel *labelPtr; labelPtr = Blt_Chain_GetValue(link); Blt_Free(labelPtr); } Blt_Chain_Reset(chain); } /* *--------------------------------------------------------------------------- * * MakeLabel -- * * Converts a floating point tick value to a string to be used as its * label. * * Results: * None. * * Side Effects: * Returns a new label in the string character buffer. The formatted * tick label will be displayed on the graph. * * -------------------------------------------------------------------------- */ static TickLabel * MakeLabel(Axis *axisPtr, double value) { #define TICK_LABEL_SIZE 200 char string[TICK_LABEL_SIZE + 1]; TickLabel *labelPtr; /* Generate a default tick label based upon the tick value. */ if (axisPtr->logScale) { sprintf_s(string, TICK_LABEL_SIZE, "1E%d", ROUND(value)); } else { sprintf_s(string, TICK_LABEL_SIZE, "%.*G", NUMDIGITS, value); } if (axisPtr->formatCmd != NULL) { Graph *graphPtr; Tcl_Interp *interp; Tk_Window tkwin; graphPtr = axisPtr->obj.graphPtr; interp = graphPtr->interp; tkwin = graphPtr->tkwin; /* * A TCL proc was designated to format tick labels. Append the path * name of the widget and the default tick label as arguments when * invoking it. Copy and save the new label from interp->result. */ Tcl_ResetResult(interp); if (Tcl_VarEval(interp, axisPtr->formatCmd, " ", Tk_PathName(tkwin), " ", string, (char *)NULL) != TCL_OK) { Tcl_BackgroundError(interp); } else { /* * The proc could return a string of any length, so arbitrarily * limit it to what will fit in the return string. */ strncpy(string, Tcl_GetStringResult(interp), TICK_LABEL_SIZE); string[TICK_LABEL_SIZE] = '\0'; Tcl_ResetResult(interp); /* Clear the interpreter's result. */ } } labelPtr = Blt_AssertMalloc(sizeof(TickLabel) + strlen(string)); strcpy(labelPtr->string, string); labelPtr->anchorPos.x = labelPtr->anchorPos.y = DBL_MAX; return labelPtr; } /* *--------------------------------------------------------------------------- * * Blt_InvHMap -- * * Maps the given screen coordinate back to a graph coordinate. Called * by the graph locater routine. * * Results: * Returns the graph coordinate value at the given window * y-coordinate. * *--------------------------------------------------------------------------- */ double Blt_InvHMap(Axis *axisPtr, double x) { double value; x = (double)(x - axisPtr->screenMin) * axisPtr->screenScale; if (axisPtr->descending) { x = 1.0 - x; } value = (x * axisPtr->axisRange.range) + axisPtr->axisRange.min; if (axisPtr->logScale) { value = EXP10(value); } return value; } /* *--------------------------------------------------------------------------- * * Blt_InvVMap -- * * Maps the given screen y-coordinate back to the graph coordinate * value. Called by the graph locater routine. * * Results: * Returns the graph coordinate value for the given screen * coordinate. * *--------------------------------------------------------------------------- */ double Blt_InvVMap(Axis *axisPtr, double y) /* Screen coordinate */ { double value; y = (double)(y - axisPtr->screenMin) * axisPtr->screenScale; if (axisPtr->descending) { y = 1.0 - y; } value = ((1.0 - y) * axisPtr->axisRange.range) + axisPtr->axisRange.min; if (axisPtr->logScale) { value = EXP10(value); } return value; } /* *--------------------------------------------------------------------------- * * Blt_HMap -- * * Map the given graph coordinate value to its axis, returning a window * position. * * Results: * Returns a double precision number representing the window coordinate * position on the given axis. * *--------------------------------------------------------------------------- */ double Blt_HMap(Axis *axisPtr, double x) { if ((axisPtr->logScale) && (x != 0.0)) { x = log10(FABS(x)); } /* Map graph coordinate to normalized coordinates [0..1] */ x = (x - axisPtr->axisRange.min) * axisPtr->axisRange.scale; if (axisPtr->descending) { x = 1.0 - x; } return (x * axisPtr->screenRange + axisPtr->screenMin); } /* *--------------------------------------------------------------------------- * * Blt_VMap -- * * Map the given graph coordinate value to its axis, returning a window * position. * * Results: * Returns a double precision number representing the window coordinate * position on the given axis. * *--------------------------------------------------------------------------- */ double Blt_VMap(Axis *axisPtr, double y) { if ((axisPtr->logScale) && (y != 0.0)) { y = log10(FABS(y)); } /* Map graph coordinate to normalized coordinates [0..1] */ y = (y - axisPtr->axisRange.min) * axisPtr->axisRange.scale; if (axisPtr->descending) { y = 1.0 - y; } return ((1.0 - y) * axisPtr->screenRange + axisPtr->screenMin); } /* *--------------------------------------------------------------------------- * * Blt_Map2D -- * * Maps the given graph x,y coordinate values to a window position. * * Results: * Returns a XPoint structure containing the window coordinates of * the given graph x,y coordinate. * *--------------------------------------------------------------------------- */ Point2d Blt_Map2D( Graph *graphPtr, double x, double y, /* Graph x and y coordinates */ Axis2d *axesPtr) /* Specifies which axes to use */ { Point2d point; if (graphPtr->inverted) { point.x = Blt_HMap(axesPtr->y, y); point.y = Blt_VMap(axesPtr->x, x); } else { point.x = Blt_HMap(axesPtr->x, x); point.y = Blt_VMap(axesPtr->y, y); } return point; } /* *--------------------------------------------------------------------------- * * Blt_InvMap2D -- * * Maps the given window x,y coordinates to graph values. * * Results: * Returns a structure containing the graph coordinates of the given * window x,y coordinate. * *--------------------------------------------------------------------------- */ Point2d Blt_InvMap2D( Graph *graphPtr, double x, double y, /* Window x and y coordinates */ Axis2d *axesPtr) /* Specifies which axes to use */ { Point2d point; if (graphPtr->inverted) { point.x = Blt_InvVMap(axesPtr->x, y); point.y = Blt_InvHMap(axesPtr->y, x); } else { point.x = Blt_InvHMap(axesPtr->x, x); point.y = Blt_InvVMap(axesPtr->y, y); } return point; } static void GetDataLimits(Axis *axisPtr, double min, double max) { if (axisPtr->valueRange.min > min) { axisPtr->valueRange.min = min; } if (axisPtr->valueRange.max < max) { axisPtr->valueRange.max = max; } } static void FixAxisRange(Axis *axisPtr) { double min, max; /* * When auto-scaling, the axis limits are the bounds of the element data. * If no data exists, set arbitrary limits (wrt to log/linear scale). */ min = axisPtr->valueRange.min; max = axisPtr->valueRange.max; /* Check the requested axis limits. Can't allow -min to be greater * than -max, or have undefined log scale limits. */ if (((DEFINED(axisPtr->reqMin)) && (DEFINED(axisPtr->reqMax))) && (axisPtr->reqMin >= axisPtr->reqMax)) { axisPtr->reqMin = axisPtr->reqMax = Blt_NaN(); } if (axisPtr->logScale) { if ((DEFINED(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { axisPtr->reqMin = Blt_NaN(); } if ((DEFINED(axisPtr->reqMax)) && (axisPtr->reqMax <= 0.0)) { axisPtr->reqMax = Blt_NaN(); } } if (min == DBL_MAX) { if (DEFINED(axisPtr->reqMin)) { min = axisPtr->reqMin; } else { min = (axisPtr->logScale) ? 0.001 : 0.0; } } if (max == -DBL_MAX) { if (DEFINED(axisPtr->reqMax)) { max = axisPtr->reqMax; } else { max = 1.0; } } if (min >= max) { /* * There is no range of data (i.e. min is not less than max), so * manufacture one. */ if (min == 0.0) { min = 0.0, max = 1.0; } else { max = min + (FABS(min) * 0.1); } } SetAxisRange(&axisPtr->valueRange, min, max); /* * The axis limits are either the current data range or overridden by the * values selected by the user with the -min or -max options. */ axisPtr->min = min; axisPtr->max = max; if (DEFINED(axisPtr->reqMin)) { axisPtr->min = axisPtr->reqMin; } if (DEFINED(axisPtr->reqMax)) { axisPtr->max = axisPtr->reqMax; } if (axisPtr->max < axisPtr->min) { /* * If the limits still don't make sense, it's because one limit * configuration option (-min or -max) was set and the other default * (based upon the data) is too small or large. Remedy this by making * up a new min or max from the user-defined limit. */ if (!DEFINED(axisPtr->reqMin)) { axisPtr->min = axisPtr->max - (FABS(axisPtr->max) * 0.1); } if (!DEFINED(axisPtr->reqMax)) { axisPtr->max = axisPtr->min + (FABS(axisPtr->max) * 0.1); } } /* * If a window size is defined, handle auto ranging by shifting the axis * limits. */ if ((axisPtr->windowSize > 0.0) && (!DEFINED(axisPtr->reqMin)) && (!DEFINED(axisPtr->reqMax))) { if (axisPtr->shiftBy < 0.0) { axisPtr->shiftBy = 0.0; } max = axisPtr->min + axisPtr->windowSize; if (axisPtr->max >= max) { if (axisPtr->shiftBy > 0.0) { max = UCEIL(axisPtr->max, axisPtr->shiftBy); } axisPtr->min = max - axisPtr->windowSize; } axisPtr->max = max; } if ((axisPtr->max != axisPtr->prevMax) || (axisPtr->min != axisPtr->prevMin)) { /* Indicate if the axis limits have changed */ axisPtr->flags |= DIRTY; /* and save the previous minimum and maximum values */ axisPtr->prevMin = axisPtr->min; axisPtr->prevMax = axisPtr->max; } } /* *--------------------------------------------------------------------------- * * NiceNum -- * * Reference: Paul Heckbert, "Nice Numbers for Graph Labels", * Graphics Gems, pp 61-63. * * Finds a "nice" number approximately equal to x. * *--------------------------------------------------------------------------- */ static double NiceNum(double x, int round) /* If non-zero, round. Otherwise take * ceiling of value. */ { double expt; /* Exponent of x */ double frac; /* Fractional part of x */ double nice; /* Nice, rounded fraction */ expt = floor(log10(x)); frac = x / EXP10(expt); /* between 1 and 10 */ if (round) { if (frac < 1.5) { nice = 1.0; } else if (frac < 3.0) { nice = 2.0; } else if (frac < 7.0) { nice = 5.0; } else { nice = 10.0; } } else { if (frac <= 1.0) { nice = 1.0; } else if (frac <= 2.0) { nice = 2.0; } else if (frac <= 5.0) { nice = 5.0; } else { nice = 10.0; } } return nice * EXP10(expt); } static Ticks * GenerateTicks(TickSweep *sweepPtr) { Ticks *ticksPtr; ticksPtr = Blt_AssertMalloc(sizeof(Ticks) + (sweepPtr->nSteps * sizeof(double))); ticksPtr->nTicks = 0; if (sweepPtr->step == 0.0) { /* Hack: A zero step indicates to use log values. */ int i; /* Precomputed log10 values [1..10] */ static double logTable[] = { 0.0, 0.301029995663981, 0.477121254719662, 0.602059991327962, 0.698970004336019, 0.778151250383644, 0.845098040014257, 0.903089986991944, 0.954242509439325, 1.0 }; for (i = 0; i < sweepPtr->nSteps; i++) { ticksPtr->values[i] = logTable[i]; } } else { double value; int i; value = sweepPtr->initial; /* Start from smallest axis tick */ for (i = 0; i < sweepPtr->nSteps; i++) { value = UROUND(value, sweepPtr->step); ticksPtr->values[i] = value; value += sweepPtr->step; } } ticksPtr->nTicks = sweepPtr->nSteps; return ticksPtr; } /* *--------------------------------------------------------------------------- * * LogScaleAxis -- * * Determine the range and units of a log scaled axis. * * Unless the axis limits are specified, the axis is scaled * automatically, where the smallest and largest major ticks encompass * the range of actual data values. When an axis limit is specified, * that value represents the smallest(min)/largest(max) value in the * displayed range of values. * * Both manual and automatic scaling are affected by the step used. By * default, the step is the largest power of ten to divide the range in * more than one piece. * * Automatic scaling: * Find the smallest number of units which contain the range of values. * The minimum and maximum major tick values will be represent the * range of values for the axis. This greatest number of major ticks * possible is 10. * * Manual scaling: * Make the minimum and maximum data values the represent the range of * the values for the axis. The minimum and maximum major ticks will be * inclusive of this range. This provides the largest area for plotting * and the expected results when the axis min and max values have be set * by the user (.e.g zooming). The maximum number of major ticks is 20. * * For log scale, there's the possibility that the minimum and * maximum data values are the same magnitude. To represent the * points properly, at least one full decade should be shown. * However, if you zoom a log scale plot, the results should be * predictable. Therefore, in that case, show only minor ticks. * Lastly, there should be an appropriate way to handle numbers * <=0. * * maxY * | units = magnitude (of least significant digit) * | high = largest unit tick < max axis value * high _| low = smallest unit tick > min axis value * | * | range = high - low * | # ticks = greatest factor of range/units * _| * U | * n | * i | * t _| * | * | * | * low _| * | * |_minX________________maxX__ * | | | | | * minY low high * minY * * * numTicks = Number of ticks * min = Minimum value of axis * max = Maximum value of axis * range = Range of values (max - min) * * If the number of decades is greater than ten, it is assumed * that the full set of log-style ticks can't be drawn properly. * * Results: * None * * -------------------------------------------------------------------------- */ static void LogScaleAxis(Axis *axisPtr, double min, double max) { double range; double tickMin, tickMax; double majorStep, minorStep; int nMajor, nMinor; nMajor = nMinor = 0; /* Suppress compiler warnings. */ majorStep = minorStep = 0.0; tickMin = tickMax = Blt_NaN(); if (min < max) { min = (min != 0.0) ? log10(FABS(min)) : 0.0; max = (max != 0.0) ? log10(FABS(max)) : 1.0; tickMin = floor(min); tickMax = ceil(max); range = tickMax - tickMin; if (range > 10) { /* There are too many decades to display a major tick at every * decade. Instead, treat the axis as a linear scale. */ range = NiceNum(range, 0); majorStep = NiceNum(range / axisPtr->reqNumMajorTicks, 1); tickMin = UFLOOR(tickMin, majorStep); tickMax = UCEIL(tickMax, majorStep); nMajor = (int)((tickMax - tickMin) / majorStep) + 1; minorStep = EXP10(floor(log10(majorStep))); if (minorStep == majorStep) { nMinor = 4, minorStep = 0.2; } else { nMinor = Round(majorStep / minorStep) - 1; } } else { if (tickMin == tickMax) { tickMax++; } majorStep = 1.0; nMajor = (int)(tickMax - tickMin + 1); /* FIXME: Check this. */ minorStep = 0.0; /* This is a special hack to pass * information to the GenerateTicks * routine. An interval of 0.0 tells 1) * this is a minor sweep and 2) the axis * is log scale. */ nMinor = 10; } if ((axisPtr->looseMin == AXIS_TIGHT) || ((axisPtr->looseMin == AXIS_LOOSE) && (DEFINED(axisPtr->reqMin)))) { tickMin = min; nMajor++; } if ((axisPtr->looseMax == AXIS_TIGHT) || ((axisPtr->looseMax == AXIS_LOOSE) && (DEFINED(axisPtr->reqMax)))) { tickMax = max; } } axisPtr->majorSweep.step = majorStep; axisPtr->majorSweep.initial = floor(tickMin); axisPtr->majorSweep.nSteps = nMajor; axisPtr->minorSweep.initial = axisPtr->minorSweep.step = minorStep; axisPtr->minorSweep.nSteps = nMinor; SetAxisRange(&axisPtr->axisRange, tickMin, tickMax); } /* *--------------------------------------------------------------------------- * * LinearScaleAxis -- * * Determine the units of a linear scaled axis. * * The axis limits are either the range of the data values mapped * to the axis (autoscaled), or the values specified by the -min * and -max options (manual). * * If autoscaled, the smallest and largest major ticks will * encompass the range of data values. If the -loose option is * selected, the next outer ticks are choosen. If tight, the * ticks are at or inside of the data limits are used. * * If manually set, the ticks are at or inside the data limits * are used. This makes sense for zooming. You want the * selected range to represent the next limit, not something a * bit bigger. * * Note: I added an "always" value to the -loose option to force * the manually selected axes to be loose. It's probably * not a good idea. * * maxY * | units = magnitude (of least significant digit) * | high = largest unit tick < max axis value * high _| low = smallest unit tick > min axis value * | * | range = high - low * | # ticks = greatest factor of range/units * _| * U | * n | * i | * t _| * | * | * | * low _| * | * |_minX________________maxX__ * | | | | | * minY low high * minY * * numTicks = Number of ticks * min = Minimum value of axis * max = Maximum value of axis * range = Range of values (max - min) * * Results: * None. * * Side Effects: * The axis tick information is set. The actual tick values will * be generated later. * *--------------------------------------------------------------------------- */ static void LinearScaleAxis(Axis *axisPtr, double min, double max) { double step; double tickMin, tickMax; double axisMin, axisMax; unsigned int nTicks; nTicks = 0; step = 1.0; /* Suppress compiler warning. */ axisMin = axisMax = tickMin = tickMax = Blt_NaN(); if (min < max) { double range; range = max - min; /* Calculate the major tick stepping. */ if (axisPtr->reqStep > 0.0) { /* An interval was designated by the user. Keep scaling it until * it fits comfortably within the current range of the axis. */ step = axisPtr->reqStep; while ((2 * step) >= range) { step *= 0.5; } } else { range = NiceNum(range, 0); step = NiceNum(range / axisPtr->reqNumMajorTicks, 1); } /* Find the outer tick values. Add 0.0 to prevent getting -0.0. */ axisMin = tickMin = floor(min / step) * step + 0.0; axisMax = tickMax = ceil(max / step) * step + 0.0; nTicks = Round((tickMax - tickMin) / step) + 1; } axisPtr->majorSweep.step = step; axisPtr->majorSweep.initial = tickMin; axisPtr->majorSweep.nSteps = nTicks; /* * The limits of the axis are either the range of the data ("tight") or at * the next outer tick interval ("loose"). The looseness or tightness has * to do with how the axis fits the range of data values. This option is * overridden when the user sets an axis limit (by either -min or -max * option). The axis limit is always at the selected limit (otherwise we * assume that user would have picked a different number). */ if ((axisPtr->looseMin == AXIS_TIGHT) || ((axisPtr->looseMin == AXIS_LOOSE) && (DEFINED(axisPtr->reqMin)))) { axisMin = min; } if ((axisPtr->looseMax == AXIS_TIGHT) || ((axisPtr->looseMax == AXIS_LOOSE) && (DEFINED(axisPtr->reqMax)))) { axisMax = max; } SetAxisRange(&axisPtr->axisRange, axisMin, axisMax); /* Now calculate the minor tick step and number. */ if ((axisPtr->reqNumMinorTicks > 0) && (axisPtr->flags & AXIS_AUTO_MAJOR)) { nTicks = axisPtr->reqNumMinorTicks - 1; step = 1.0 / (nTicks + 1); } else { nTicks = 0; /* No minor ticks. */ step = 0.5; /* Don't set the minor tick interval to * 0.0. It makes the GenerateTicks * routine * create minor log-scale tick * marks. */ } axisPtr->minorSweep.initial = axisPtr->minorSweep.step = step; axisPtr->minorSweep.nSteps = nTicks; } static void SweepTicks(Axis *axisPtr) { if (axisPtr->flags & AXIS_AUTO_MAJOR) { if (axisPtr->t1Ptr != NULL) { Blt_Free(axisPtr->t1Ptr); } axisPtr->t1Ptr = GenerateTicks(&axisPtr->majorSweep); } if (axisPtr->flags & AXIS_AUTO_MINOR) { if (axisPtr->t2Ptr != NULL) { Blt_Free(axisPtr->t2Ptr); } axisPtr->t2Ptr = GenerateTicks(&axisPtr->minorSweep); } } /* *--------------------------------------------------------------------------- * * Blt_ResetAxes -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_ResetAxes(Graph *graphPtr) { Blt_ChainLink link; Blt_HashEntry *hPtr; Blt_HashSearch cursor; /* FIXME: This should be called whenever the display list of * elements change. Maybe yet another flag INIT_STACKS to * indicate that the element display list has changed. * Needs to be done before the axis limits are set. */ Blt_InitBarSetTable(graphPtr); if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) { Blt_ComputeBarStacks(graphPtr); } /* * Step 1: Reset all axes. Initialize the data limits of the axis to * impossible values. */ for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); axisPtr->min = axisPtr->valueRange.min = DBL_MAX; axisPtr->max = axisPtr->valueRange.max = -DBL_MAX; } /* * Step 2: For each element that's to be displayed, get the smallest * and largest data values mapped to each X and Y-axis. This * will be the axis limits if the user doesn't override them * with -min and -max options. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; Region2d exts; elemPtr = Blt_Chain_GetValue(link); if ((graphPtr->flags & UNMAP_HIDDEN) && (elemPtr->flags & HIDE)) { continue; } (*elemPtr->procsPtr->extentsProc) (elemPtr, &exts); GetDataLimits(elemPtr->axes.x, exts.left, exts.right); GetDataLimits(elemPtr->axes.y, exts.top, exts.bottom); } /* * Step 3: Now that we know the range of data values for each axis, * set axis limits and compute a sweep to generate tick values. */ for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; double min, max; axisPtr = Blt_GetHashValue(hPtr); FixAxisRange(axisPtr); /* Calculate min/max tick (major/minor) layouts */ min = axisPtr->min; max = axisPtr->max; if ((DEFINED(axisPtr->scrollMin)) && (min < axisPtr->scrollMin)) { min = axisPtr->scrollMin; } if ((DEFINED(axisPtr->scrollMax)) && (max > axisPtr->scrollMax)) { max = axisPtr->scrollMax; } if (axisPtr->logScale) { LogScaleAxis(axisPtr, min, max); } else if (axisPtr->timeScale) { TimeScaleAxis(axisPtr, min, max); } else { LinearScaleAxis(axisPtr, min, max); } if ((axisPtr->flags & (DIRTY|AXIS_USE)) == (DIRTY|AXIS_USE)) { graphPtr->flags |= CACHE_DIRTY; } } graphPtr->flags &= ~RESET_AXES; /* * When any axis changes, we need to layout the entire graph. */ graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | MAP_ALL | REDRAW_WORLD); } /* *--------------------------------------------------------------------------- * * ResetTextStyles -- * * Configures axis attributes (font, line width, label, etc) and * allocates a new (possibly shared) graphics context. Line cap style is * projecting. This is for the problem of when a tick sits directly at * the end point of the axis. * * Results: * The return value is a standard TCL result. * * Side Effects: * Axis resources are allocated (GC, font). Axis layout is deferred until * the height and width of the window are known. * *--------------------------------------------------------------------------- */ static void ResetTextStyles(Axis *axisPtr) { Graph *graphPtr = axisPtr->obj.graphPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; Blt_Ts_ResetStyle(graphPtr->tkwin, &axisPtr->limitsTextStyle); gcMask = (GCForeground | GCLineWidth | GCCapStyle); gcValues.foreground = axisPtr->tickColor->pixel; gcValues.font = Blt_FontId(axisPtr->tickFont); gcValues.line_width = LineWidth(axisPtr->lineWidth); gcValues.cap_style = CapProjecting; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (axisPtr->tickGC != NULL) { Tk_FreeGC(graphPtr->display, axisPtr->tickGC); } axisPtr->tickGC = newGC; /* Assuming settings from above GC */ gcValues.foreground = axisPtr->activeFgColor->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (axisPtr->activeTickGC != NULL) { Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); } axisPtr->activeTickGC = newGC; gcValues.background = gcValues.foreground = axisPtr->major.color->pixel; gcValues.line_width = LineWidth(axisPtr->major.lineWidth); gcMask = (GCForeground | GCBackground | GCLineWidth); if (LineIsDashed(axisPtr->major.dashes)) { gcValues.line_style = LineOnOffDash; gcMask |= GCLineStyle; } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(axisPtr->major.dashes)) { Blt_SetDashes(graphPtr->display, newGC, &axisPtr->major.dashes); } if (axisPtr->major.gc != NULL) { Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); } axisPtr->major.gc = newGC; gcValues.background = gcValues.foreground = axisPtr->minor.color->pixel; gcValues.line_width = LineWidth(axisPtr->minor.lineWidth); gcMask = (GCForeground | GCBackground | GCLineWidth); if (LineIsDashed(axisPtr->minor.dashes)) { gcValues.line_style = LineOnOffDash; gcMask |= GCLineStyle; } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(axisPtr->minor.dashes)) { Blt_SetDashes(graphPtr->display, newGC, &axisPtr->minor.dashes); } if (axisPtr->minor.gc != NULL) { Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); } axisPtr->minor.gc = newGC; } /* *--------------------------------------------------------------------------- * * DestroyAxis -- * * Results: * None. * * Side effects: * Resources (font, color, gc, labels, etc.) associated with the axis are * deallocated. * *--------------------------------------------------------------------------- */ static void DestroyAxis(Axis *axisPtr) { Graph *graphPtr = axisPtr->obj.graphPtr; int flags; flags = Blt_GraphType(graphPtr); Blt_FreeOptions(configSpecs, (char *)axisPtr, graphPtr->display, flags); if (graphPtr->bindTable != NULL) { Blt_DeleteBindings(graphPtr->bindTable, axisPtr); } if (axisPtr->link != NULL) { Blt_Chain_DeleteLink(axisPtr->chain, axisPtr->link); } if (axisPtr->obj.name != NULL) { Blt_Free(axisPtr->obj.name); } if (axisPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&graphPtr->axes.table, axisPtr->hashPtr); } Blt_Ts_FreeStyle(graphPtr->display, &axisPtr->limitsTextStyle); if (axisPtr->tickGC != NULL) { Tk_FreeGC(graphPtr->display, axisPtr->tickGC); } if (axisPtr->activeTickGC != NULL) { Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); } if (axisPtr->major.gc != NULL) { Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); } if (axisPtr->minor.gc != NULL) { Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); } FreeTickLabels(axisPtr->tickLabels); Blt_Chain_Destroy(axisPtr->tickLabels); if (axisPtr->segments != NULL) { Blt_Free(axisPtr->segments); } Blt_Free(axisPtr); } static void FreeAxis(DestroyData data) { Axis *axisPtr = (Axis *)data; DestroyAxis(axisPtr); } static float titleAngle[4] = /* Rotation for each axis title */ { 0.0, 90.0, 0.0, 270.0 }; /* *--------------------------------------------------------------------------- * * AxisOffsets -- * * Determines the sites of the axis, major and minor ticks, and title of * the axis. * * Results: * None. * *--------------------------------------------------------------------------- */ static void AxisOffsets( Axis *axisPtr, int margin, int offset, AxisInfo *infoPtr) { Graph *graphPtr = axisPtr->obj.graphPtr; Margin *marginPtr; int pad; /* Offset of axis from interior * region. This includes a possible * border and the axis line width. */ int axisLine; int t1, t2, labelOffset; int tickLabel, axisPad; int inset, mark; int x, y; float fangle; axisPtr->titleAngle = titleAngle[margin]; marginPtr = graphPtr->margins + margin; tickLabel = axisLine = t1 = t2 = 0; labelOffset = AXIS_PAD_TITLE; if (axisPtr->lineWidth > 0) { if (axisPtr->flags & AXIS_SHOWTICKS) { t1 = axisPtr->tickLength; t2 = (t1 * 10) / 15; } labelOffset = t1 + AXIS_PAD_TITLE; if (axisPtr->flags & AXIS_EXTERIOR) { labelOffset += axisPtr->lineWidth; } } axisPad = 0; if (graphPtr->plotRelief != TK_RELIEF_SOLID) { axisPad = 0; } /* Adjust offset for the interior border width and the line width */ pad = 1; if (graphPtr->plotBW > 0) { pad += graphPtr->plotBW + 1; } pad = 0; /* FIXME: test */ /* * Pre-calculate the x-coordinate positions of the axis, tick labels, and * the individual major and minor ticks. */ inset = pad + axisPtr->lineWidth / 2; switch (margin) { case MARGIN_TOP: axisLine = graphPtr->top; if (axisPtr->flags & AXIS_EXTERIOR) { axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; tickLabel = axisLine - 2; if (axisPtr->lineWidth > 0) { tickLabel -= axisPtr->tickLength; } #ifdef notdef fprintf(stderr, "axisLine=%d, axisPad=%d plotBW=%d axisPtr->lineWidth/2=%d\n", axisLine, axisPad, graphPtr->plotBW, axisPtr->lineWidth /2 ); #endif } else { if (graphPtr->plotRelief == TK_RELIEF_SOLID) { axisLine--; } axisLine -= axisPad + axisPtr->lineWidth / 2; tickLabel = graphPtr->top - graphPtr->plotBW - 2; #ifdef notdef fprintf(stderr, "axisLine=%d, axisPad=%d plotBW=%d axisPtr->lineWidth/2=%d\n", axisLine, axisPad, graphPtr->plotBW, axisPtr->lineWidth /2 ); #endif } mark = graphPtr->top - offset - pad; axisPtr->tickAnchor = TK_ANCHOR_S; axisPtr->left = axisPtr->screenMin - inset - 2; axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; if (graphPtr->stackAxes) { axisPtr->top = mark - marginPtr->axesOffset; } else { axisPtr->top = mark - axisPtr->height; } axisPtr->bottom = mark; if (axisPtr->titleAlternate) { x = graphPtr->right + AXIS_PAD_TITLE; y = mark - (axisPtr->height / 2); axisPtr->titleAnchor = TK_ANCHOR_W; } else { x = (axisPtr->right + axisPtr->left) / 2; if (graphPtr->stackAxes) { y = mark - marginPtr->axesOffset + AXIS_PAD_TITLE; } else { y = mark - axisPtr->height + AXIS_PAD_TITLE; } axisPtr->titleAnchor = TK_ANCHOR_N; } axisPtr->titlePos.x = x; axisPtr->titlePos.y = y; break; case MARGIN_BOTTOM: /* * ----------- bottom + plot borderwidth * mark -------------------------------------------- * ===================== axisLine (linewidth) * tick * title * * ===================== axisLine (linewidth) * ----------- bottom + plot borderwidth * mark -------------------------------------------- * tick * title */ axisLine = graphPtr->bottom; if (graphPtr->plotRelief == TK_RELIEF_SOLID) { axisLine++; } if (axisPtr->flags & AXIS_EXTERIOR) { axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; tickLabel = axisLine + 2; if (axisPtr->lineWidth > 0) { tickLabel += axisPtr->tickLength; } } else { axisLine -= axisPad + axisPtr->lineWidth / 2; tickLabel = graphPtr->bottom + graphPtr->plotBW + 2; } mark = graphPtr->bottom + offset; fangle = FMOD(axisPtr->tickAngle, 90.0); if (fangle == 0.0) { axisPtr->tickAnchor = TK_ANCHOR_N; } else { int quadrant; quadrant = (int)(axisPtr->tickAngle / 90.0); if ((quadrant == 0) || (quadrant == 2)) { axisPtr->tickAnchor = TK_ANCHOR_NE; } else { axisPtr->tickAnchor = TK_ANCHOR_NW; } } axisPtr->left = axisPtr->screenMin - inset - 2; axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; axisPtr->top = graphPtr->bottom + labelOffset - t1; if (graphPtr->stackAxes) { axisPtr->bottom = mark + marginPtr->axesOffset - 1; } else { axisPtr->bottom = mark + axisPtr->height - 1; } if (axisPtr->titleAlternate) { x = graphPtr->right + AXIS_PAD_TITLE; y = mark + (axisPtr->height / 2); axisPtr->titleAnchor = TK_ANCHOR_W; } else { x = (axisPtr->right + axisPtr->left) / 2; if (graphPtr->stackAxes) { y = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; } else { y = mark + axisPtr->height - AXIS_PAD_TITLE; } axisPtr->titleAnchor = TK_ANCHOR_S; } axisPtr->titlePos.x = x; axisPtr->titlePos.y = y; break; case MARGIN_LEFT: /* * mark * | : * | : * | : * | : * | : * axisLine */ /* * Exterior axis * + plotarea right * |A|B|C|D|E|F|G|H * |right * A = plot pad * B = plot border width * C = axis pad * D = axis line * E = tick length * F = tick label * G = graph border width * H = highlight thickness */ /* * Interior axis * + plotarea right * |A|B|C|D|E|F|G|H * |right * A = plot pad * B = tick length * C = axis line width * D = axis pad * E = plot border width * F = tick label * G = graph border width * H = highlight thickness */ axisLine = graphPtr->left; if (axisPtr->flags & AXIS_EXTERIOR) { axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; tickLabel = axisLine - 2; if (axisPtr->lineWidth > 0) { tickLabel -= axisPtr->tickLength; } } else { if (graphPtr->plotRelief == TK_RELIEF_SOLID) { axisLine--; } axisLine += axisPad + axisPtr->lineWidth / 2; tickLabel = graphPtr->left - graphPtr->plotBW - 2; } mark = graphPtr->left - offset; axisPtr->tickAnchor = TK_ANCHOR_E; if (graphPtr->stackAxes) { axisPtr->left = mark - marginPtr->axesOffset; } else { axisPtr->left = mark - axisPtr->width; } axisPtr->right = mark - 3; axisPtr->top = axisPtr->screenMin - inset - 2; axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset - 1; if (axisPtr->titleAlternate) { x = mark - (axisPtr->width / 2); y = graphPtr->top - AXIS_PAD_TITLE; axisPtr->titleAnchor = TK_ANCHOR_SW; } else { if (graphPtr->stackAxes) { x = mark - marginPtr->axesOffset; } else { x = mark - axisPtr->width + AXIS_PAD_TITLE; } y = (axisPtr->bottom + axisPtr->top) / 2; axisPtr->titleAnchor = TK_ANCHOR_W; } axisPtr->titlePos.x = x; axisPtr->titlePos.y = y; break; case MARGIN_RIGHT: axisLine = graphPtr->right; if (graphPtr->plotRelief == TK_RELIEF_SOLID) { axisLine++; /* Draw axis line within solid plot * border. */ } if (axisPtr->flags & AXIS_EXTERIOR) { axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; tickLabel = axisLine + 2; if (axisPtr->lineWidth > 0) { tickLabel += axisPtr->tickLength; } } else { axisLine -= axisPad + axisPtr->lineWidth / 2; tickLabel = graphPtr->right + graphPtr->plotBW + 2; } mark = graphPtr->right + offset + pad; axisPtr->tickAnchor = TK_ANCHOR_W; axisPtr->left = mark; if (graphPtr->stackAxes) { axisPtr->right = mark + marginPtr->axesOffset - 1; } else { axisPtr->right = mark + axisPtr->width - 1; } axisPtr->top = axisPtr->screenMin - inset - 2; axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset -1; if (axisPtr->titleAlternate) { x = mark + (axisPtr->width / 2); y = graphPtr->top - AXIS_PAD_TITLE; axisPtr->titleAnchor = TK_ANCHOR_SE; } else { if (graphPtr->stackAxes) { x = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; } else { x = mark + axisPtr->width - AXIS_PAD_TITLE; } y = (axisPtr->bottom + axisPtr->top) / 2; axisPtr->titleAnchor = TK_ANCHOR_E; } axisPtr->titlePos.x = x; axisPtr->titlePos.y = y; break; case MARGIN_NONE: axisLine = 0; break; } if ((margin == MARGIN_LEFT) || (margin == MARGIN_TOP)) { t1 = -t1, t2 = -t2; labelOffset = -labelOffset; } infoPtr->axis = axisLine; infoPtr->t1 = axisLine + t1; infoPtr->t2 = axisLine + t2; if (tickLabel > 0) { infoPtr->label = tickLabel; } else { infoPtr->label = axisLine + labelOffset; } if ((axisPtr->flags & AXIS_EXTERIOR) == 0) { /*infoPtr->label = axisLine + labelOffset - t1; */ infoPtr->t1 = axisLine - t1; infoPtr->t2 = axisLine - t2; } } static void MakeAxisLine(Axis *axisPtr, int line, Segment2d *sp) { double min, max; min = axisPtr->axisRange.min; max = axisPtr->axisRange.max; if (axisPtr->logScale) { min = EXP10(min); max = EXP10(max); } if (AxisIsHorizontal(axisPtr)) { sp->p.x = Blt_HMap(axisPtr, min); sp->q.x = Blt_HMap(axisPtr, max); sp->p.y = sp->q.y = line; } else { sp->q.x = sp->p.x = line; sp->p.y = Blt_VMap(axisPtr, min); sp->q.y = Blt_VMap(axisPtr, max); } } static void MakeTick(Axis *axisPtr, double value, int tick, int line, Segment2d *sp) { if (axisPtr->logScale) { value = EXP10(value); } if (AxisIsHorizontal(axisPtr)) { sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); sp->p.y = line; sp->q.y = tick; } else { sp->p.x = line; sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); sp->q.x = tick; } } static void MakeSegments(Axis *axisPtr, AxisInfo *infoPtr) { int arraySize; int nMajorTicks, nMinorTicks; Segment2d *segments; Segment2d *sp; if (axisPtr->segments != NULL) { Blt_Free(axisPtr->segments); } nMajorTicks = nMinorTicks = 0; if (axisPtr->t1Ptr != NULL) { nMajorTicks = axisPtr->t1Ptr->nTicks; } if (axisPtr->t2Ptr != NULL) { nMinorTicks = axisPtr->t2Ptr->nTicks; } arraySize = 1 + (nMajorTicks * (nMinorTicks + 1)); segments = Blt_AssertMalloc(arraySize * sizeof(Segment2d)); sp = segments; if (axisPtr->lineWidth > 0) { /* Axis baseline */ MakeAxisLine(axisPtr, infoPtr->axis, sp); sp++; } if (axisPtr->flags & AXIS_SHOWTICKS) { Blt_ChainLink link; double labelPos; int i; int isHoriz; isHoriz = AxisIsHorizontal(axisPtr); for (i = 0; i < nMajorTicks; i++) { double t1, t2; int j; t1 = axisPtr->t1Ptr->values[i]; /* Minor ticks */ for (j = 0; j < nMinorTicks; j++) { t2 = t1 + (axisPtr->majorSweep.step * axisPtr->t2Ptr->values[j]); if (InRange(t2, &axisPtr->axisRange)) { MakeTick(axisPtr, t2, infoPtr->t2, infoPtr->axis, sp); sp++; } } if (!InRange(t1, &axisPtr->axisRange)) { continue; } /* Major tick */ MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, sp); sp++; } link = Blt_Chain_FirstLink(axisPtr->tickLabels); labelPos = (double)infoPtr->label; for (i = 0; i < nMajorTicks; i++) { double t1; TickLabel *labelPtr; Segment2d seg; t1 = axisPtr->t1Ptr->values[i]; if (axisPtr->labelOffset) { t1 += axisPtr->majorSweep.step * 0.5; } if (!InRange(t1, &axisPtr->axisRange)) { continue; } labelPtr = Blt_Chain_GetValue(link); link = Blt_Chain_NextLink(link); MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, &seg); /* Save tick label X-Y position. */ if (isHoriz) { labelPtr->anchorPos.x = seg.p.x; labelPtr->anchorPos.y = labelPos; } else { labelPtr->anchorPos.x = labelPos; labelPtr->anchorPos.y = seg.p.y; } } } axisPtr->segments = segments; axisPtr->nSegments = sp - segments; assert(axisPtr->nSegments <= arraySize); } /* *--------------------------------------------------------------------------- * * MapAxis -- * * Pre-calculates positions of the axis, ticks, and labels (to be used * later when displaying the axis). Calculates the values for each major * and minor tick and checks to see if they are in range (the outer ticks * may be outside of the range of plotted values). * * Line segments for the minor and major ticks are saved into one * XSegment array so that they can be drawn by a single XDrawSegments * call. The positions of the tick labels are also computed and saved. * * Results: * None. * * Side Effects: * Line segments and tick labels are saved and used later to draw the * axis. * *--------------------------------------------------------------------------- */ static void MapAxis(Axis *axisPtr, int offset, int margin) { AxisInfo info; Graph *graphPtr = axisPtr->obj.graphPtr; if (AxisIsHorizontal(axisPtr)) { axisPtr->screenMin = graphPtr->hOffset; axisPtr->width = graphPtr->right - graphPtr->left; axisPtr->screenRange = graphPtr->hRange; } else { axisPtr->screenMin = graphPtr->vOffset; axisPtr->height = graphPtr->bottom - graphPtr->top; axisPtr->screenRange = graphPtr->vRange; } axisPtr->screenScale = 1.0 / axisPtr->screenRange; AxisOffsets(axisPtr, margin, offset, &info); MakeSegments(axisPtr, &info); } /* *--------------------------------------------------------------------------- * * MapStackedAxis -- * * Pre-calculates positions of the axis, ticks, and labels (to be used * later when displaying the axis). Calculates the values for each major * and minor tick and checks to see if they are in range (the outer ticks * may be outside of the range of plotted values). * * Line segments for the minor and major ticks are saved into one XSegment * array so that they can be drawn by a single XDrawSegments call. The * positions of the tick labels are also computed and saved. * * Results: * None. * * Side Effects: * Line segments and tick labels are saved and used later to draw the * axis. * *--------------------------------------------------------------------------- */ static void MapStackedAxis(Axis *axisPtr, int count, int margin) { AxisInfo info; Graph *graphPtr = axisPtr->obj.graphPtr; unsigned int slice, w, h; if ((graphPtr->margins[axisPtr->margin].axes->nLinks > 1) || (axisPtr->reqNumMajorTicks <= 0)) { axisPtr->reqNumMajorTicks = 4; } if (AxisIsHorizontal(axisPtr)) { slice = graphPtr->hRange / graphPtr->margins[margin].axes->nLinks; axisPtr->screenMin = graphPtr->hOffset; axisPtr->width = slice; } else { slice = graphPtr->vRange / graphPtr->margins[margin].axes->nLinks; axisPtr->screenMin = graphPtr->vOffset; axisPtr->height = slice; } #define AXIS_PAD 2 Blt_GetTextExtents(axisPtr->tickFont, 0, "0", 1, &w, &h); axisPtr->screenMin += (slice * count) + AXIS_PAD + h / 2; axisPtr->screenRange = slice - 2 * AXIS_PAD - h; axisPtr->screenScale = 1.0f / axisPtr->screenRange; AxisOffsets(axisPtr, margin, 0, &info); MakeSegments(axisPtr, &info); } /* *--------------------------------------------------------------------------- * * AdjustViewport -- * * Adjusts the offsets of the viewport according to the scroll mode. This * is to accommodate both "listbox" and "canvas" style scrolling. * * "canvas" The viewport scrolls within the range of world * coordinates. This way the viewport always displays * a full page of the world. If the world is smaller * than the viewport, then (bizarrely) the world and * viewport are inverted so that the world moves up * and down within the viewport. * * "listbox" The viewport can scroll beyond the range of world * coordinates. Every entry can be displayed at the * top of the viewport. This also means that the * scrollbar thumb weirdly shrinks as the last entry * is scrolled upward. * * Results: * The corrected offset is returned. * *--------------------------------------------------------------------------- */ static double AdjustViewport(double offset, double windowSize) { /* * Canvas-style scrolling allows the world to be scrolled within the window. */ if (windowSize > 1.0) { if (windowSize < (1.0 - offset)) { offset = 1.0 - windowSize; } if (offset > 0.0) { offset = 0.0; } } else { if ((offset + windowSize) > 1.0) { offset = 1.0 - windowSize; } if (offset < 0.0) { offset = 0.0; } } return offset; } static int GetAxisScrollInfo( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, double *offsetPtr, double windowSize, double scrollUnits, double scale) { const char *string; char c; double offset; int length; offset = *offsetPtr; string = Tcl_GetStringFromObj(objv[0], &length); c = string[0]; scrollUnits *= scale; if ((c == 's') && (strncmp(string, "scroll", length) == 0)) { int count; double fract; assert(objc == 3); /* Scroll number unit/page */ if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'u') && (strncmp(string, "units", length) == 0)) { fract = count * scrollUnits; } else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) { /* A page is 90% of the view-able window. */ fract = (int)(count * windowSize * 0.9 + 0.5); } else if ((c == 'p') && (strncmp(string, "pixels", length) == 0)) { fract = count * scale; } else { Tcl_AppendResult(interp, "unknown \"scroll\" units \"", string, "\"", (char *)NULL); return TCL_ERROR; } offset += fract; } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) { double fract; assert(objc == 2); /* moveto fraction */ if (Blt_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) { return TCL_ERROR; } offset = fract; } else { int count; double fract; /* Treat like "scroll units" */ if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) { return TCL_ERROR; } fract = (double)count * scrollUnits; offset += fract; /* CHECK THIS: return TCL_OK; */ } *offsetPtr = AdjustViewport(offset, windowSize); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DrawAxis -- * * Draws the axis, ticks, and labels onto the canvas. * * Initializes and passes text attribute information through TextStyle * structure. * * Results: * None. * * Side Effects: * Axis gets drawn on window. * *--------------------------------------------------------------------------- */ static void DrawAxis(Axis *axisPtr, Drawable drawable) { Graph *graphPtr = axisPtr->obj.graphPtr; if (axisPtr->normalBg != NULL) { Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, axisPtr->normalBg, axisPtr->left, axisPtr->top, axisPtr->right - axisPtr->left, axisPtr->bottom - axisPtr->top, axisPtr->borderWidth, axisPtr->relief); } if (axisPtr->title != NULL) { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetAngle(ts, axisPtr->titleAngle); Blt_Ts_SetFont(ts, axisPtr->titleFont); Blt_Ts_SetPadding(ts, 1, 2, 0, 0); Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); Blt_Ts_SetJustify(ts, axisPtr->titleJustify); if (axisPtr->flags & ACTIVE) { Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); } else { Blt_Ts_SetForeground(ts, axisPtr->titleColor); } Blt_Ts_SetForeground(ts, axisPtr->titleColor); if ((axisPtr->titleAngle == 90.0) || (axisPtr->titleAngle == 270.0)) { Blt_Ts_SetMaxLength(ts, axisPtr->height); } else { Blt_Ts_SetMaxLength(ts, axisPtr->width); } Blt_Ts_DrawText(graphPtr->tkwin, drawable, axisPtr->title, -1, &ts, (int)axisPtr->titlePos.x, (int)axisPtr->titlePos.y); } if (axisPtr->scrollCmdObjPtr != NULL) { double viewWidth, viewMin, viewMax; double worldWidth, worldMin, worldMax; double fract; int isHoriz; worldMin = axisPtr->valueRange.min; worldMax = axisPtr->valueRange.max; if (DEFINED(axisPtr->scrollMin)) { worldMin = axisPtr->scrollMin; } if (DEFINED(axisPtr->scrollMax)) { worldMax = axisPtr->scrollMax; } viewMin = axisPtr->min; viewMax = axisPtr->max; if (viewMin < worldMin) { viewMin = worldMin; } if (viewMax > worldMax) { viewMax = worldMax; } if (axisPtr->logScale) { worldMin = log10(worldMin); worldMax = log10(worldMax); viewMin = log10(viewMin); viewMax = log10(viewMax); } worldWidth = worldMax - worldMin; viewWidth = viewMax - viewMin; isHoriz = AxisIsHorizontal(axisPtr); if (isHoriz != axisPtr->descending) { fract = (viewMin - worldMin) / worldWidth; } else { fract = (worldMax - viewMax) / worldWidth; } fract = AdjustViewport(fract, viewWidth / worldWidth); if (isHoriz != axisPtr->descending) { viewMin = (fract * worldWidth); axisPtr->min = viewMin + worldMin; axisPtr->max = axisPtr->min + viewWidth; viewMax = viewMin + viewWidth; if (axisPtr->logScale) { axisPtr->min = EXP10(axisPtr->min); axisPtr->max = EXP10(axisPtr->max); } Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, viewMin, viewMax, worldWidth); } else { viewMax = (fract * worldWidth); axisPtr->max = worldMax - viewMax; axisPtr->min = axisPtr->max - viewWidth; viewMin = viewMax + viewWidth; if (axisPtr->logScale) { axisPtr->min = EXP10(axisPtr->min); axisPtr->max = EXP10(axisPtr->max); } Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, viewMax, viewMin, worldWidth); } } if (axisPtr->flags & AXIS_SHOWTICKS) { Blt_ChainLink link; TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetAngle(ts, axisPtr->tickAngle); Blt_Ts_SetFont(ts, axisPtr->tickFont); Blt_Ts_SetPadding(ts, 2, 0, 0, 0); Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); if (axisPtr->flags & ACTIVE) { Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); } else { Blt_Ts_SetForeground(ts, axisPtr->tickColor); } for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; link = Blt_Chain_NextLink(link)) { TickLabel *labelPtr; labelPtr = Blt_Chain_GetValue(link); /* Draw major tick labels */ Blt_DrawText(graphPtr->tkwin, drawable, labelPtr->string, &ts, (int)labelPtr->anchorPos.x, (int)labelPtr->anchorPos.y); } } if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { GC gc; if (axisPtr->flags & ACTIVE) { gc = axisPtr->activeTickGC; } else { gc = axisPtr->tickGC; } /* Draw the tick marks and axis line. */ Blt_Draw2DSegments(graphPtr->display, drawable, gc, axisPtr->segments, axisPtr->nSegments); } } /* *--------------------------------------------------------------------------- * * AxisToPostScript -- * * Generates PostScript output to draw the axis, ticks, and labels. * * Initializes and passes text attribute information through TextStyle * structure. * * Results: * None. * * Side Effects: * PostScript output is left in graphPtr->interp->result; * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void AxisToPostScript(Blt_Ps ps, Axis *axisPtr) { Blt_Ps_Format(ps, "%% Axis \"%s\"\n", axisPtr->obj.name); if (axisPtr->normalBg != NULL) { Tk_3DBorder border; border = Blt_BackgroundBorder(axisPtr->normalBg); Blt_Ps_Fill3DRectangle(ps, border, (double)axisPtr->left, (double)axisPtr->top, axisPtr->right - axisPtr->left, axisPtr->bottom - axisPtr->top, axisPtr->borderWidth, axisPtr->relief); } if (axisPtr->title != NULL) { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetAngle(ts, axisPtr->titleAngle); Blt_Ts_SetFont(ts, axisPtr->titleFont); Blt_Ts_SetPadding(ts, 1, 2, 0, 0); Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); Blt_Ts_SetJustify(ts, axisPtr->titleJustify); Blt_Ts_SetForeground(ts, axisPtr->titleColor); Blt_Ps_DrawText(ps, axisPtr->title, &ts, axisPtr->titlePos.x, axisPtr->titlePos.y); } if (axisPtr->flags & AXIS_SHOWTICKS) { Blt_ChainLink link; TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetAngle(ts, axisPtr->tickAngle); Blt_Ts_SetFont(ts, axisPtr->tickFont); Blt_Ts_SetPadding(ts, 2, 0, 0, 0); Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); Blt_Ts_SetForeground(ts, axisPtr->tickColor); for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; link = Blt_Chain_NextLink(link)) { TickLabel *labelPtr; labelPtr = Blt_Chain_GetValue(link); Blt_Ps_DrawText(ps, labelPtr->string, &ts, labelPtr->anchorPos.x, labelPtr->anchorPos.y); } } if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { Blt_Ps_XSetLineAttributes(ps, axisPtr->tickColor, axisPtr->lineWidth, (Blt_Dashes *)NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, axisPtr->segments, axisPtr->nSegments); } } static void MakeGridLine(Axis *axisPtr, double value, Segment2d *sp) { Graph *graphPtr = axisPtr->obj.graphPtr; if (axisPtr->logScale) { value = EXP10(value); } /* Grid lines run orthogonally to the axis */ if (AxisIsHorizontal(axisPtr)) { sp->p.y = graphPtr->top; sp->q.y = graphPtr->bottom; sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); } else { sp->p.x = graphPtr->left; sp->q.x = graphPtr->right; sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); } } /* *--------------------------------------------------------------------------- * * MapGridlines -- * * Assembles the grid lines associated with an axis. Generates tick * positions if necessary (this happens when the axis is not a logical axis * too). * * Results: * None. * *--------------------------------------------------------------------------- */ static void MapGridlines(Axis *axisPtr) { Segment2d *s1, *s2; Ticks *t1Ptr, *t2Ptr; int needed; int i; if (axisPtr == NULL) { return; } t1Ptr = axisPtr->t1Ptr; if (t1Ptr == NULL) { t1Ptr = GenerateTicks(&axisPtr->majorSweep); } t2Ptr = axisPtr->t2Ptr; if (t2Ptr == NULL) { t2Ptr = GenerateTicks(&axisPtr->minorSweep); } needed = t1Ptr->nTicks; if (axisPtr->flags & AXIS_GRIDMINOR) { needed += (t1Ptr->nTicks * t2Ptr->nTicks); } if (needed == 0) { return; } needed = t1Ptr->nTicks; if (needed != axisPtr->major.nAllocated) { if (axisPtr->major.segments != NULL) { Blt_Free(axisPtr->major.segments); } axisPtr->major.segments = Blt_AssertMalloc(sizeof(Segment2d) * needed); axisPtr->major.nAllocated = needed; } needed = (t1Ptr->nTicks * t2Ptr->nTicks); if (needed != axisPtr->minor.nAllocated) { if (axisPtr->minor.segments != NULL) { Blt_Free(axisPtr->minor.segments); } axisPtr->minor.segments = Blt_AssertMalloc(sizeof(Segment2d) * needed); axisPtr->minor.nAllocated = needed; } s1 = axisPtr->major.segments, s2 = axisPtr->minor.segments; for (i = 0; i < t1Ptr->nTicks; i++) { double value; value = t1Ptr->values[i]; if (axisPtr->flags & AXIS_GRIDMINOR) { int j; for (j = 0; j < t2Ptr->nTicks; j++) { double subValue; subValue = value + (axisPtr->majorSweep.step * t2Ptr->values[j]); if (InRange(subValue, &axisPtr->axisRange)) { MakeGridLine(axisPtr, subValue, s2); s2++; } } } if (InRange(value, &axisPtr->axisRange)) { MakeGridLine(axisPtr, value, s1); s1++; } } if (t1Ptr != axisPtr->t1Ptr) { Blt_Free(t1Ptr); /* Free generated ticks. */ } if (t2Ptr != axisPtr->t2Ptr) { Blt_Free(t2Ptr); /* Free generated ticks. */ } axisPtr->major.nUsed = s1 - axisPtr->major.segments; axisPtr->minor.nUsed = s2 - axisPtr->minor.segments; } /* *--------------------------------------------------------------------------- * * GetAxisGeometry -- * * Results: * None. * * Exterior axis: * l r * |a|b|c|d|e|f|g|h|i| j |i|h|g|f|e|d|c|d|a| * * Interior axis: * l r * |a|b|c|d|h|g|f|e| j |e|f|g|h|d|c|b|a| * i.. ..i * a = highlight thickness * b = graph borderwidth * c = axis title * d = tick label * e = tick * f = axis line * g = 1 pixel pad * h = plot borderwidth * i = plot pad * j = plot area *--------------------------------------------------------------------------- */ static void GetAxisGeometry(Graph *graphPtr, Axis *axisPtr) { unsigned int y; FreeTickLabels(axisPtr->tickLabels); y = 0; if ((axisPtr->flags & AXIS_EXTERIOR) && (graphPtr->plotRelief != TK_RELIEF_SOLID)) { /* Leave room for axis baseline and padding */ y += axisPtr->lineWidth + 2; } axisPtr->maxTickHeight = axisPtr->maxTickWidth = 0; if (axisPtr->flags & AXIS_SHOWTICKS) { unsigned int pad; unsigned int i, nLabels, nTicks; SweepTicks(axisPtr); nTicks = 0; if (axisPtr->t1Ptr != NULL) { nTicks = axisPtr->t1Ptr->nTicks; } assert(nTicks <= MAXTICKS); nLabels = 0; for (i = 0; i < nTicks; i++) { TickLabel *labelPtr; double x, x2; unsigned int lw, lh; /* Label width and height. */ x2 = x = axisPtr->t1Ptr->values[i]; if (axisPtr->labelOffset) { x2 += axisPtr->majorSweep.step * 0.5; } if (!InRange(x2, &axisPtr->axisRange)) { continue; } labelPtr = MakeLabel(axisPtr, x); Blt_Chain_Append(axisPtr->tickLabels, labelPtr); nLabels++; /* * Get the dimensions of each tick label. Remember tick labels * can be multi-lined and/or rotated. */ Blt_GetTextExtents(axisPtr->tickFont, 0, labelPtr->string, -1, &lw, &lh); labelPtr->width = lw; labelPtr->height = lh; if (axisPtr->tickAngle != 0.0f) { double rlw, rlh; /* Rotated label width and height. */ Blt_GetBoundingBox(lw, lh, axisPtr->tickAngle, &rlw, &rlh,NULL); lw = ROUND(rlw), lh = ROUND(rlh); } if (axisPtr->maxTickWidth < lw) { axisPtr->maxTickWidth = lw; } if (axisPtr->maxTickHeight < lh) { axisPtr->maxTickHeight = lh; } } assert(nLabels <= nTicks); pad = 0; if (axisPtr->flags & AXIS_EXTERIOR) { /* Because the axis cap style is "CapProjecting", we need to * account for an extra 1.5 linewidth at the end of each line. */ pad = ((axisPtr->lineWidth * 12) / 8); } if (AxisIsHorizontal(axisPtr)) { y += axisPtr->maxTickHeight + pad; } else { y += axisPtr->maxTickWidth + pad; if (axisPtr->maxTickWidth > 0) { y += 5; /* Pad either size of label. */ } } y += 2 * AXIS_PAD_TITLE; if ((axisPtr->lineWidth > 0) && (axisPtr->flags & AXIS_EXTERIOR)) { /* Distance from axis line to tick label. */ y += axisPtr->tickLength; } } if (axisPtr->title != NULL) { if (axisPtr->titleAlternate) { if (y < axisPtr->titleHeight) { y = axisPtr->titleHeight; } } else { y += axisPtr->titleHeight + AXIS_PAD_TITLE; } } /* Correct for orientation of the axis. */ if (AxisIsHorizontal(axisPtr)) { axisPtr->height = y; } else { axisPtr->width = y; } } /* *--------------------------------------------------------------------------- * * GetMarginGeometry -- * * Examines all the axes in the given margin and determines the area * required to display them. * * Note: For multiple axes, the titles are displayed in another * margin. So we must keep track of the widest title. * * Results: * Returns the width or height of the margin, depending if it runs * horizontally along the graph or vertically. * * Side Effects: * The area width and height set in the margin. Note again that this may * be corrected later (mulitple axes) to adjust for the longest title in * another margin. * *--------------------------------------------------------------------------- */ static int GetMarginGeometry(Graph *graphPtr, Margin *marginPtr) { Blt_ChainLink link; unsigned int l, w, h; /* Length, width, and height. */ int isHoriz; unsigned int nVisible; isHoriz = HORIZMARGIN(marginPtr); /* Count the visible axes. */ nVisible = 0; l = w = h = 0; marginPtr->maxTickWidth = marginPtr->maxTickHeight = 0; if (graphPtr->stackAxes) { for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { nVisible++; if (graphPtr->flags & GET_AXIS_GEOMETRY) { GetAxisGeometry(graphPtr, axisPtr); } if (isHoriz) { if (h < axisPtr->height) { h = axisPtr->height; } } else { if (w < axisPtr->width) { w = axisPtr->width; } } if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { marginPtr->maxTickWidth = axisPtr->maxTickWidth; } if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { marginPtr->maxTickHeight = axisPtr->maxTickHeight; } } } } else { for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { nVisible++; if (graphPtr->flags & GET_AXIS_GEOMETRY) { GetAxisGeometry(graphPtr, axisPtr); } if ((axisPtr->titleAlternate) && (l < axisPtr->titleWidth)) { l = axisPtr->titleWidth; } if (isHoriz) { h += axisPtr->height; } else { w += axisPtr->width; } if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { marginPtr->maxTickWidth = axisPtr->maxTickWidth; } if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { marginPtr->maxTickHeight = axisPtr->maxTickHeight; } } } } /* Enforce a minimum size for margins. */ if (w < 3) { w = 3; } if (h < 3) { h = 3; } marginPtr->nAxes = nVisible; marginPtr->axesTitleLength = l; marginPtr->width = w; marginPtr->height = h; marginPtr->axesOffset = (isHoriz) ? h : w; return marginPtr->axesOffset; } /* *--------------------------------------------------------------------------- * * Blt_LayoutGraph -- * * Calculate the layout of the graph. Based upon the data, axis limits, * X and Y titles, and title height, determine the cavity left which is * the plotting surface. The first step get the data and axis limits for * calculating the space needed for the top, bottom, left, and right * margins. * * 1) The LEFT margin is the area from the left border to the Y axis * (not including ticks). It composes the border width, the width an * optional Y axis label and its padding, and the tick numeric labels. * The Y axis label is rotated 90 degrees so that the width is the * font height. * * 2) The RIGHT margin is the area from the end of the graph * to the right window border. It composes the border width, * some padding, the font height (this may be dubious. It * appears to provide a more even border), the max of the * legend width and 1/2 max X tick number. This last part is * so that the last tick label is not clipped. * * Window Width * ___________________________________________________________ * | | | | * | | TOP height of title | | * | | | | * | | x2 title | | * | | | | * | | height of x2-axis | | * |__________|_______________________________|_______________| W * | | -plotpady | | i * |__________|_______________________________|_______________| n * | | top right | | d * | | | | o * | LEFT | | RIGHT | w * | | | | * | y | Free area = 104% | y2 | H * | | Plotting surface = 100% | | e * | t | Tick length = 2 + 2% | t | i * | i | | i | g * | t | | t legend| h * | l | | l width| t * | e | | e | * | height| |height | * | of | | of | * | y-axis| |y2-axis | * | | | | * | |origin 0,0 | | * |__________|_left_________________bottom___|_______________| * | |-plotpady | | * |__________|_______________________________|_______________| * | | (xoffset, yoffset) | | * | | | | * | | height of x-axis | | * | | | | * | | BOTTOM x title | | * |__________|_______________________________|_______________| * * 3) The TOP margin is the area from the top window border to the top * of the graph. It composes the border width, twice the height of * the title font (if one is given) and some padding between the * title. * * 4) The BOTTOM margin is area from the bottom window border to the * X axis (not including ticks). It composes the border width, the height * an optional X axis label and its padding, the height of the font * of the tick labels. * * The plotting area is between the margins which includes the X and Y axes * including the ticks but not the tick numeric labels. The length of the * ticks and its padding is 5% of the entire plotting area. Hence the entire * plotting area is scaled as 105% of the width and height of the area. * * The axis labels, ticks labels, title, and legend may or may not be * displayed which must be taken into account. * * if reqWidth > 0 : set outer size * if reqPlotWidth > 0 : set plot size *--------------------------------------------------------------------------- */ void Blt_LayoutGraph(Graph *graphPtr) { unsigned int titleY; unsigned int left, right, top, bottom; unsigned int plotWidth, plotHeight; unsigned int inset, inset2; int width, height; int pad; width = graphPtr->width; height = graphPtr->height; /* * Step 1: Compute the amount of space needed to display the axes * associated with each margin. They can be overridden by * -leftmargin, -rightmargin, -bottommargin, and -topmargin * graph options, respectively. */ left = GetMarginGeometry(graphPtr, &graphPtr->leftMargin); right = GetMarginGeometry(graphPtr, &graphPtr->rightMargin); top = GetMarginGeometry(graphPtr, &graphPtr->topMargin); bottom = GetMarginGeometry(graphPtr, &graphPtr->bottomMargin); pad = graphPtr->bottomMargin.maxTickWidth; if (pad < graphPtr->topMargin.maxTickWidth) { pad = graphPtr->topMargin.maxTickWidth; } pad = pad / 2 + 3; if (right < pad) { right = pad; } if (left < pad) { left = pad; } pad = graphPtr->leftMargin.maxTickHeight; if (pad < graphPtr->rightMargin.maxTickHeight) { pad = graphPtr->rightMargin.maxTickHeight; } pad = pad / 2; if (top < pad) { top = pad; } if (bottom < pad) { bottom = pad; } if (graphPtr->leftMargin.reqSize > 0) { left = graphPtr->leftMargin.reqSize; } if (graphPtr->rightMargin.reqSize > 0) { right = graphPtr->rightMargin.reqSize; } if (graphPtr->topMargin.reqSize > 0) { top = graphPtr->topMargin.reqSize; } if (graphPtr->bottomMargin.reqSize > 0) { bottom = graphPtr->bottomMargin.reqSize; } /* * Step 2: Add the graph title height to the top margin. */ if (graphPtr->title != NULL) { top += graphPtr->titleHeight + 6; } inset = (graphPtr->inset + graphPtr->plotBW); inset2 = 2 * inset; /* * Step 3: Estimate the size of the plot area from the remaining * space. This may be overridden by the -plotwidth and * -plotheight graph options. We use this to compute the * size of the legend. */ if (width == 0) { width = 400; } if (height == 0) { height = 400; } plotWidth = (graphPtr->reqPlotWidth > 0) ? graphPtr->reqPlotWidth : width - (inset2 + left + right); /* Plot width. */ plotHeight = (graphPtr->reqPlotHeight > 0) ? graphPtr->reqPlotHeight : height - (inset2 + top + bottom); /* Plot height. */ Blt_MapLegend(graphPtr, plotWidth, plotHeight); /* * Step 2: Add the legend to the appropiate margin. */ if (!Blt_Legend_IsHidden(graphPtr)) { switch (Blt_Legend_Site(graphPtr)) { case LEGEND_RIGHT: right += Blt_Legend_Width(graphPtr) + 2; break; case LEGEND_LEFT: left += Blt_Legend_Width(graphPtr) + 2; break; case LEGEND_TOP: top += Blt_Legend_Height(graphPtr) + 2; break; case LEGEND_BOTTOM: bottom += Blt_Legend_Height(graphPtr) + 2; break; case LEGEND_XY: case LEGEND_PLOT: case LEGEND_WINDOW: /* Do nothing. */ break; } } /* * Recompute the plotarea or graph size, now accounting for the legend. */ if (graphPtr->reqPlotWidth == 0) { plotWidth = width - (inset2 + left + right); if (plotWidth < 1) { plotWidth = 1; } } if (graphPtr->reqPlotHeight == 0) { plotHeight = height - (inset2 + top + bottom); if (plotHeight < 1) { plotHeight = 1; } } /* * Step 5: If necessary, correct for the requested plot area aspect * ratio. */ if ((graphPtr->reqPlotWidth == 0) && (graphPtr->reqPlotHeight == 0) && (graphPtr->aspect > 0.0f)) { float ratio; /* * Shrink one dimension of the plotarea to fit the requested * width/height aspect ratio. */ ratio = (float)plotWidth / (float)plotHeight; if (ratio > graphPtr->aspect) { int scaledWidth; /* Shrink the width. */ scaledWidth = (int)(plotHeight * graphPtr->aspect); if (scaledWidth < 1) { scaledWidth = 1; } /* Add the difference to the right margin. */ /* CHECK THIS: w = scaledWidth; */ right += (plotWidth - scaledWidth); } else { int scaledHeight; /* Shrink the height. */ scaledHeight = (int)(plotWidth / graphPtr->aspect); if (scaledHeight < 1) { scaledHeight = 1; } /* Add the difference to the top margin. */ /* CHECK THIS: h = scaledHeight; */ top += (plotHeight - scaledHeight); } } /* * Step 6: If there's multiple axes in a margin, the axis titles will be * displayed in the adjoining margins. Make sure there's room * for the longest axis titles. */ if (top < graphPtr->leftMargin.axesTitleLength) { top = graphPtr->leftMargin.axesTitleLength; } if (right < graphPtr->bottomMargin.axesTitleLength) { right = graphPtr->bottomMargin.axesTitleLength; } if (top < graphPtr->rightMargin.axesTitleLength) { top = graphPtr->rightMargin.axesTitleLength; } if (right < graphPtr->topMargin.axesTitleLength) { right = graphPtr->topMargin.axesTitleLength; } /* * Step 7: Override calculated values with requested margin sizes. */ if (graphPtr->leftMargin.reqSize > 0) { left = graphPtr->leftMargin.reqSize; } if (graphPtr->rightMargin.reqSize > 0) { right = graphPtr->rightMargin.reqSize; } if (graphPtr->topMargin.reqSize > 0) { top = graphPtr->topMargin.reqSize; } if (graphPtr->bottomMargin.reqSize > 0) { bottom = graphPtr->bottomMargin.reqSize; } if (graphPtr->reqPlotWidth > 0) { int w; /* * Width of plotarea is constained. If there's extra space, add it to * th left and/or right margins. If there's too little, grow the * graph width to accomodate it. */ w = plotWidth + inset2 + left + right; if (width > w) { /* Extra space in window. */ int extra; extra = (width - w) / 2; if (graphPtr->leftMargin.reqSize == 0) { left += extra; if (graphPtr->rightMargin.reqSize == 0) { right += extra; } else { left += extra; } } else if (graphPtr->rightMargin.reqSize == 0) { right += extra + extra; } } else if (width < w) { width = w; } } if (graphPtr->reqPlotHeight > 0) { /* Constrain the plotarea height. */ int h; /* * Height of plotarea is constained. If there's extra space, * add it to th top and/or bottom margins. If there's too little, * grow the graph height to accomodate it. */ h = plotHeight + inset2 + top + bottom; if (height > h) { /* Extra space in window. */ int extra; extra = (height - h) / 2; if (graphPtr->topMargin.reqSize == 0) { top += extra; if (graphPtr->bottomMargin.reqSize == 0) { bottom += extra; } else { top += extra; } } else if (graphPtr->bottomMargin.reqSize == 0) { bottom += extra + extra; } } else if (height < h) { height = h; } } graphPtr->width = width; graphPtr->height = height; graphPtr->left = left + inset; graphPtr->top = top + inset; graphPtr->right = width - right - inset; graphPtr->bottom = height - bottom - inset; graphPtr->leftMargin.width = left + graphPtr->inset; graphPtr->rightMargin.width = right + graphPtr->inset; graphPtr->topMargin.height = top + graphPtr->inset; graphPtr->bottomMargin.height = bottom + graphPtr->inset; graphPtr->vOffset = graphPtr->top + graphPtr->padTop; graphPtr->vRange = plotHeight - PADDING(graphPtr->yPad); graphPtr->hOffset = graphPtr->left + graphPtr->padLeft; graphPtr->hRange = plotWidth - PADDING(graphPtr->xPad); if (graphPtr->vRange < 1) { graphPtr->vRange = 1; } if (graphPtr->hRange < 1) { graphPtr->hRange = 1; } graphPtr->hScale = 1.0f / (float)graphPtr->hRange; graphPtr->vScale = 1.0f / (float)graphPtr->vRange; /* * Calculate the placement of the graph title so it is centered within the * space provided for it in the top margin */ titleY = graphPtr->titleHeight; graphPtr->titleY = 3 + graphPtr->inset; graphPtr->titleX = (graphPtr->right + graphPtr->left) / 2; } /* *--------------------------------------------------------------------------- * * ConfigureAxis -- * * Configures axis attributes (font, line width, label, etc). * * Results: * The return value is a standard TCL result. * * Side Effects: * Axis layout is deferred until the height and width of the window are * known. * *--------------------------------------------------------------------------- */ static int ConfigureAxis(Axis *axisPtr) { Graph *graphPtr = axisPtr->obj.graphPtr; float angle; /* Check the requested axis limits. Can't allow -min to be greater than * -max. Do this regardless of -checklimits option. We want to always * detect when the user has zoomed in beyond the precision of the data.*/ if (((DEFINED(axisPtr->reqMin)) && (DEFINED(axisPtr->reqMax))) && (axisPtr->reqMin >= axisPtr->reqMax)) { char msg[200]; sprintf_s(msg, 200, "impossible axis limits (-min %g >= -max %g) for \"%s\"", axisPtr->reqMin, axisPtr->reqMax, axisPtr->obj.name); Tcl_AppendResult(graphPtr->interp, msg, (char *)NULL); return TCL_ERROR; } axisPtr->scrollMin = axisPtr->reqScrollMin; axisPtr->scrollMax = axisPtr->reqScrollMax; if (axisPtr->logScale) { if (axisPtr->flags & AXIS_CHECK_LIMITS) { /* Check that the logscale limits are positive. */ if ((DEFINED(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { Tcl_AppendResult(graphPtr->interp,"bad logscale -min limit \"", Blt_Dtoa(graphPtr->interp, axisPtr->reqMin), "\" for axis \"", axisPtr->obj.name, "\"", (char *)NULL); return TCL_ERROR; } } if ((DEFINED(axisPtr->scrollMin)) && (axisPtr->scrollMin <= 0.0)) { axisPtr->scrollMin = Blt_NaN(); } if ((DEFINED(axisPtr->scrollMax)) && (axisPtr->scrollMax <= 0.0)) { axisPtr->scrollMax = Blt_NaN(); } } angle = FMOD(axisPtr->tickAngle, 360.0); if (angle < 0.0f) { angle += 360.0f; } if (axisPtr->normalBg != NULL) { Blt_SetBackgroundChangedProc(axisPtr->normalBg, Blt_UpdateGraph, graphPtr); } if (axisPtr->activeBg != NULL) { Blt_SetBackgroundChangedProc(axisPtr->activeBg, Blt_UpdateGraph, graphPtr); } axisPtr->tickAngle = angle; ResetTextStyles(axisPtr); axisPtr->titleWidth = axisPtr->titleHeight = 0; if (axisPtr->title != NULL) { unsigned int w, h; Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title, -1, &w, &h); axisPtr->titleWidth = (unsigned short int)w; axisPtr->titleHeight = (unsigned short int)h; } /* * Don't bother to check what configuration options have changed. Almost * every option changes the size of the plotting area (except for -color * and -titlecolor), requiring the graph and its contents to be completely * redrawn. * * Recompute the scale and offset of the axis in case -min, -max options * have changed. */ graphPtr->flags |= REDRAW_WORLD; graphPtr->flags |= MAP_WORLD | RESET_AXES | CACHE_DIRTY; axisPtr->flags |= DIRTY; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NewAxis -- * * Create and initialize a structure containing information to display * a graph axis. * * Results: * The return value is a pointer to an Axis structure. * *--------------------------------------------------------------------------- */ static Axis * NewAxis(Graph *graphPtr, const char *name, int margin) { Axis *axisPtr; Blt_HashEntry *hPtr; int isNew; if (name[0] == '-') { Tcl_AppendResult(graphPtr->interp, "name of axis \"", name, "\" can't start with a '-'", (char *)NULL); return NULL; } hPtr = Blt_CreateHashEntry(&graphPtr->axes.table, name, &isNew); if (!isNew) { axisPtr = Blt_GetHashValue(hPtr); if ((axisPtr->flags & DELETE_PENDING) == 0) { Tcl_AppendResult(graphPtr->interp, "axis \"", name, "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return NULL; } axisPtr->flags &= ~DELETE_PENDING; } else { axisPtr = Blt_Calloc(1, sizeof(Axis)); if (axisPtr == NULL) { Tcl_AppendResult(graphPtr->interp, "can't allocate memory for axis \"", name, "\"", (char *)NULL); return NULL; } axisPtr->obj.name = Blt_AssertStrdup(name); axisPtr->hashPtr = hPtr; Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); axisPtr->obj.graphPtr = graphPtr; axisPtr->looseMin = axisPtr->looseMax = AXIS_TIGHT; axisPtr->reqNumMinorTicks = 2; axisPtr->reqNumMajorTicks = 4 /*10*/; axisPtr->margin = MARGIN_NONE; axisPtr->tickLength = 8; axisPtr->scrollUnits = 10; axisPtr->reqMin = axisPtr->reqMax = Blt_NaN(); axisPtr->reqScrollMin = axisPtr->reqScrollMax = Blt_NaN(); axisPtr->flags = (AXIS_SHOWTICKS|AXIS_GRIDMINOR|AXIS_AUTO_MAJOR| AXIS_AUTO_MINOR | AXIS_EXTERIOR); if (graphPtr->classId == CID_ELEM_BAR) { axisPtr->flags |= AXIS_GRID; } if ((graphPtr->classId == CID_ELEM_BAR) && ((margin == MARGIN_TOP) || (margin == MARGIN_BOTTOM))) { axisPtr->reqStep = 1.0; axisPtr->reqNumMinorTicks = 0; } if ((margin == MARGIN_RIGHT) || (margin == MARGIN_TOP)) { axisPtr->flags |= HIDE; } Blt_Ts_InitStyle(axisPtr->limitsTextStyle); axisPtr->tickLabels = Blt_Chain_Create(); axisPtr->lineWidth = 1; Blt_SetHashValue(hPtr, axisPtr); } return axisPtr; } static int GetAxisFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Axis **axisPtrPtr) { Blt_HashEntry *hPtr; const char *name; *axisPtrPtr = NULL; name = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->axes.table, name); if (hPtr != NULL) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); if ((axisPtr->flags & DELETE_PENDING) == 0) { *axisPtrPtr = axisPtr; return TCL_OK; } } if (interp != NULL) { Tcl_AppendResult(interp, "can't find axis \"", name, "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, Axis **axisPtrPtr) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objPtr, &axisPtr) != TCL_OK) { return TCL_ERROR; } if (classId != CID_NONE) { if ((axisPtr->refCount == 0) || (axisPtr->obj.classId == CID_NONE)) { /* Set the axis type on the first use of it. */ Blt_GraphSetObjectClass(&axisPtr->obj, classId); } else if (axisPtr->obj.classId != classId) { if (interp != NULL) { Tcl_AppendResult(interp, "axis \"", Tcl_GetString(objPtr), "\" is already in use on an opposite ", axisPtr->obj.className, "-axis", (char *)NULL); } return TCL_ERROR; } axisPtr->refCount++; } *axisPtrPtr = axisPtr; return TCL_OK; } void Blt_DestroyAxes(Graph *graphPtr) { { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); axisPtr->hashPtr = NULL; DestroyAxis(axisPtr); } } Blt_DeleteHashTable(&graphPtr->axes.table); { int i; for (i = 0; i < 4; i++) { Blt_Chain_Destroy(graphPtr->axisChain[i]); } } Blt_DeleteHashTable(&graphPtr->axes.tagTable); Blt_Chain_Destroy(graphPtr->axes.displayList); } void Blt_ConfigureAxes(Graph *graphPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); ConfigureAxis(axisPtr); } } int Blt_DefaultAxes(Graph *graphPtr) { int i; int flags; flags = Blt_GraphType(graphPtr); for (i = 0; i < 4; i++) { Blt_Chain chain; Axis *axisPtr; chain = Blt_Chain_Create(); graphPtr->axisChain[i] = chain; /* Create a default axis for each chain. */ axisPtr = NewAxis(graphPtr, axisNames[i].name, i); if (axisPtr == NULL) { return TCL_ERROR; } axisPtr->refCount = 1; /* Default axes are assumed in use. */ axisPtr->margin = i; axisPtr->flags |= AXIS_USE; Blt_GraphSetObjectClass(&axisPtr->obj, axisNames[i].classId); /* * Blt_ConfigureComponentFromObj creates a temporary child window * by the name of the axis. It's used so that the Tk routines * that access the X resource database can describe a single * component and not the entire graph. */ if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, axisPtr->obj.name, "Axis", configSpecs, 0, (Tcl_Obj **)NULL, (char *)axisPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureAxis(axisPtr) != TCL_OK) { return TCL_ERROR; } axisPtr->link = Blt_Chain_Append(chain, axisPtr); axisPtr->chain = chain; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activates the axis, drawing the axis with its -activeforeground, * -activebackgound, -activerelief attributes. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new axis attributes. * *--------------------------------------------------------------------------- */ static int ActivateOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; const char *string; string = Tcl_GetString(objv[2]); if (string[0] == 'a') { axisPtr->flags |= ACTIVE; } else { axisPtr->flags &= ~ACTIVE; } if ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE) { graphPtr->flags |= DRAW_MARGINS | CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } return TCL_OK; } /*------------------------------------------------------------------------------- * * BindOp -- * * .g axis bind axisName sequence command * *--------------------------------------------------------------------------- */ static int BindOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeAxisTag(graphPtr, axisPtr->obj.name), objc, objv); } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Queries axis attributes (font, line width, label, etc). * * Results: * Return value is a standard TCL result. If querying configuration * values, interp->result will contain the results. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CgetOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, (char *)axisPtr, objv[0], Blt_GraphType(graphPtr)); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Queries or resets axis attributes (font, line width, label, etc). * * Results: * Return value is a standard TCL result. If querying configuration * values, interp->result will contain the results. * * Side Effects: * Axis resources are possibly allocated (GC, font). Axis layout is * deferred until the height and width of the window are known. * *--------------------------------------------------------------------------- */ static int ConfigureOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; int flags; flags = BLT_CONFIG_OBJV_ONLY | Blt_GraphType(graphPtr); if (objc == 0) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)axisPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)axisPtr, objv[0], flags); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc, objv, (char *)axisPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureAxis(axisPtr) != TCL_OK) { return TCL_ERROR; } if (axisPtr->flags & AXIS_USE) { if (!Blt_ConfigModified(configSpecs, "-*color", "-background", "-bg", (char *)NULL)) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LimitsOp -- * * This procedure returns a string representing the axis limits * of the graph. The format of the string is { left top right bottom}. * * Results: * Always returns TCL_OK. The interp->result field is * a list of the graph axis limits. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int LimitsOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; Tcl_Obj *listObjPtr; double min, max; if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } if (axisPtr->logScale) { min = EXP10(axisPtr->axisRange.min); max = EXP10(axisPtr->axisRange.max); } else { min = axisPtr->axisRange.min; max = axisPtr->axisRange.max; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(min)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(max)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvTransformOp -- * * Maps the given window coordinate into an axis-value. * * Results: * Returns a standard TCL result. interp->result contains * the axis value. If an error occurred, TCL_ERROR is returned * and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InvTransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; double y; /* Real graph coordinate */ int sy; /* Integer window coordinate*/ if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } if (Tcl_GetIntFromObj(interp, objv[0], &sy) != TCL_OK) { return TCL_ERROR; } /* * Is the axis vertical or horizontal? * * Check the site where the axis was positioned. If the axis is * virtual, all we have to go on is how it was mapped to an * element (using either -mapx or -mapy options). */ if (AxisIsHorizontal(axisPtr)) { y = Blt_InvHMap(axisPtr, (double)sy); } else { y = Blt_InvVMap(axisPtr, (double)sy); } Tcl_SetDoubleObj(Tcl_GetObjResult(interp), y); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MarginOp -- * * This procedure returns a string representing the margin the axis * resides. The format of the string is { left top right bottom}. * * Results: * Always returns TCL_OK. The interp->result field is * a list of the graph axis limits. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MarginOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { const char *marginName; marginName = ""; if (axisPtr->flags & AXIS_USE) { marginName = axisNames[axisPtr->margin].name; } Tcl_SetStringObj(Tcl_GetObjResult(interp), marginName, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TransformOp -- * * Maps the given axis-value to a window coordinate. * * Results: * Returns a standard TCL result. interp->result contains * the window coordinate. If an error occurred, TCL_ERROR * is returned and interp->result will contain an error * message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = axisPtr->obj.graphPtr; double x; if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } if (Blt_ExprDoubleFromObj(interp, objv[0], &x) != TCL_OK) { return TCL_ERROR; } if (AxisIsHorizontal(axisPtr)) { x = Blt_HMap(axisPtr, x); } else { x = Blt_VMap(axisPtr, x); } Tcl_SetIntObj(Tcl_GetObjResult(interp), (int)x); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeOp -- * * This procedure returns a string representing the margin the axis * resides. The format of the string is "x", "y", or "". * * Results: * Always returns TCL_OK. The interp->result field is the type of * axis. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { const char *typeName; typeName = ""; if (axisPtr->flags & AXIS_USE) { if (axisNames[axisPtr->margin].classId == CID_AXIS_X) { typeName = "x"; } else if (axisNames[axisPtr->margin].classId == CID_AXIS_Y) { typeName = "y"; } } Tcl_SetStringObj(Tcl_GetObjResult(interp), typeName, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * UseOp -- * * Sets the default axis for a margin. * * Results: * A standard TCL result. If the named axis doesn't exist * an error message is put in interp->result. * * .g xaxis use "abc def gah" * .g xaxis use [lappend abc [.g axis use]] * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int UseOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr = (Graph *)axisPtr; Blt_Chain chain; Blt_ChainLink link; Tcl_Obj **axisObjv; ClassId classId; int axisObjc; int i; chain = graphPtr->margins[lastMargin].axes; if (objc == 0) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(axisPtr->obj.name, -1)); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if ((lastMargin == MARGIN_BOTTOM) || (lastMargin == MARGIN_TOP)) { classId = (graphPtr->inverted) ? CID_AXIS_Y : CID_AXIS_X; } else { classId = (graphPtr->inverted) ? CID_AXIS_X : CID_AXIS_Y; } if (Tcl_ListObjGetElements(interp, objv[0], &axisObjc, &axisObjv) != TCL_OK) { return TCL_ERROR; } for (link = Blt_Chain_FirstLink(chain); link!= NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); axisPtr->link = NULL; axisPtr->flags &= ~AXIS_USE; /* Clear the axis type if it's not currently used.*/ if (axisPtr->refCount == 0) { Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); } } Blt_Chain_Reset(chain); for (i = 0; i < axisObjc; i++) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, axisObjv[i], &axisPtr) != TCL_OK){ return TCL_ERROR; } if (axisPtr->obj.classId == CID_NONE) { Blt_GraphSetObjectClass(&axisPtr->obj, classId); } else if (axisPtr->obj.classId != classId) { Tcl_AppendResult(interp, "wrong type axis \"", axisPtr->obj.name, "\": can't use ", axisPtr->obj.className, " type axis.", (char *)NULL); return TCL_ERROR; } if (axisPtr->link != NULL) { /* Move the axis from the old margin's "use" list to the new. */ Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); Blt_Chain_AppendLink(chain, axisPtr->link); } else { axisPtr->link = Blt_Chain_Append(chain, axisPtr); } axisPtr->chain = chain; axisPtr->flags |= AXIS_USE; } graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); /* When any axis changes, we need to layout the entire graph. */ graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } static int ViewOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { Graph *graphPtr; double axisOffset, axisScale; double fract; double viewMin, viewMax, worldMin, worldMax; double viewWidth, worldWidth; graphPtr = axisPtr->obj.graphPtr; worldMin = axisPtr->valueRange.min; worldMax = axisPtr->valueRange.max; /* Override data dimensions with user-selected limits. */ if (DEFINED(axisPtr->scrollMin)) { worldMin = axisPtr->scrollMin; } if (DEFINED(axisPtr->scrollMax)) { worldMax = axisPtr->scrollMax; } viewMin = axisPtr->min; viewMax = axisPtr->max; /* Bound the view within scroll region. */ if (viewMin < worldMin) { viewMin = worldMin; } if (viewMax > worldMax) { viewMax = worldMax; } if (axisPtr->logScale) { worldMin = log10(worldMin); worldMax = log10(worldMax); viewMin = log10(viewMin); viewMax = log10(viewMax); } worldWidth = worldMax - worldMin; viewWidth = viewMax - viewMin; /* Unlike horizontal axes, vertical axis values run opposite of the * scrollbar first/last values. So instead of pushing the axis minimum * around, we move the maximum instead. */ if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { axisOffset = viewMin - worldMin; axisScale = graphPtr->hScale; } else { axisOffset = worldMax - viewMax; axisScale = graphPtr->vScale; } if (objc == 4) { Tcl_Obj *listObjPtr; double first, last; first = Clamp(axisOffset / worldWidth); last = Clamp((axisOffset + viewWidth) / worldWidth); listObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(first)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(last)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } fract = axisOffset / worldWidth; if (GetAxisScrollInfo(interp, objc, objv, &fract, viewWidth / worldWidth, axisPtr->scrollUnits, axisScale) != TCL_OK) { return TCL_ERROR; } if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { axisPtr->reqMin = (fract * worldWidth) + worldMin; axisPtr->reqMax = axisPtr->reqMin + viewWidth; } else { axisPtr->reqMax = worldMax - (fract * worldWidth); axisPtr->reqMin = axisPtr->reqMax - viewWidth; } if (axisPtr->logScale) { axisPtr->reqMin = EXP10(axisPtr->reqMin); axisPtr->reqMax = EXP10(axisPtr->reqMax); } graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisCreateOp -- * * Creates a new axis. * * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AxisCreateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; int flags; axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE); if (axisPtr == NULL) { return TCL_ERROR; } flags = Blt_GraphType(graphPtr); if ((Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, axisPtr->obj.name, "Axis", configSpecs, objc - 4, objv + 4, (char *)axisPtr, flags) != TCL_OK) || (ConfigureAxis(axisPtr) != TCL_OK)) { DestroyAxis(axisPtr); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisActivateOp -- * * Activates the axis, drawing the axis with its -activeforeground, * -activebackgound, -activerelief attributes. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new axis attributes. * *--------------------------------------------------------------------------- */ static int AxisActivateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return ActivateOp(interp, axisPtr, objc, objv); } /*------------------------------------------------------------------------------- * * AxisBindOp -- * * .g axis bind axisName sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AxisBindOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.tagTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { const char *tagName; Tcl_Obj *objPtr; tagName = Blt_GetHashKey(&graphPtr->axes.tagTable, hPtr); objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeAxisTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisCgetOp -- * * Queries axis attributes (font, line width, label, etc). * * Results: * Return value is a standard TCL result. If querying configuration * values, interp->result will contain the results. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int AxisCgetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return CgetOp(interp, axisPtr, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisConfigureOp -- * * Queries or resets axis attributes (font, line width, label, etc). * * Results: * Return value is a standard TCL result. If querying configuration * values, interp->result will contain the results. * * Side Effects: * Axis resources are possibly allocated (GC, font). Axis layout is * deferred until the height and width of the window are known. * *--------------------------------------------------------------------------- */ static int AxisConfigureOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Tcl_Obj *const *options; int i; int nNames, nOpts; /* Figure out where the option value pairs begin */ objc -= 3; objv += 3; for (i = 0; i < objc; i++) { Axis *axisPtr; const char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { return TCL_ERROR; } } nNames = i; /* Number of pen names specified */ nOpts = objc - i; /* Number of options specified */ options = objv + i; /* Start of options in objv */ for (i = 0; i < nNames; i++) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { return TCL_ERROR; } if (ConfigureOp(interp, axisPtr, nOpts, options) != TCL_OK) { break; } } if (i < nNames) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisDeleteOp -- * * Deletes one or more axes. The actual removal may be deferred until the * axis is no longer used by any element. The axis can't be referenced by * its name any longer and it may be recreated. * * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AxisDeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { return TCL_ERROR; } axisPtr->flags |= DELETE_PENDING; if (axisPtr->refCount == 0) { Tcl_EventuallyFree(axisPtr, FreeAxis); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisFocusOp -- * * Activates the axis, drawing the axis with its -activeforeground, * -activebackgound, -activerelief attributes. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new axis attributes. * *--------------------------------------------------------------------------- */ static int AxisFocusOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { if (objc > 3) { Axis *axisPtr; const char *string; axisPtr = NULL; string = Tcl_GetString(objv[3]); if ((string[0] != '\0') && (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK)) { return TCL_ERROR; } graphPtr->focusPtr = NULL; if ((axisPtr != NULL) && ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE)) { graphPtr->focusPtr = axisPtr; } Blt_SetFocusItem(graphPtr->bindTable, graphPtr->focusPtr, NULL); } /* Return the name of the axis that has focus. */ if (graphPtr->focusPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), graphPtr->focusPtr->obj.name, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisGetOp -- * * Returns the name of the picked axis (using the axis bind operation). * Right now, the only name accepted is "current". * * Results: * A standard TCL result. The interpreter result will contain the name of * the axis. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AxisGetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; axisPtr = Blt_GetCurrentItem(graphPtr->bindTable); /* Report only on axes. */ if ((axisPtr != NULL) && ((axisPtr->obj.classId == CID_AXIS_X) || (axisPtr->obj.classId == CID_AXIS_Y) || (axisPtr->obj.classId == CID_NONE))) { char c; char *string; string = Tcl_GetString(objv[3]); c = string[0]; if ((c == 'c') && (strcmp(string, "current") == 0)) { Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name,-1); } else if ((c == 'd') && (strcmp(string, "detail") == 0)) { Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->detail, -1); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisInvTransformOp -- * * Maps the given window coordinate into an axis-value. * * Results: * Returns a standard TCL result. interp->result contains * the axis value. If an error occurred, TCL_ERROR is returned * and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ static int AxisInvTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return InvTransformOp(interp, axisPtr, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisLimitsOp -- * * This procedure returns a string representing the axis limits of the * graph. The format of the string is { left top right bottom}. * * Results: * Always returns TCL_OK. The interp->result field is * a list of the graph axis limits. * *--------------------------------------------------------------------------- */ static int AxisLimitsOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return LimitsOp(interp, axisPtr, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisMarginOp -- * * This procedure returns a string representing the axis limits of the * graph. The format of the string is { left top right bottom}. * * Results: * Always returns TCL_OK. The interp->result field is * a list of the graph axis limits. * *--------------------------------------------------------------------------- */ static int AxisMarginOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return MarginOp(interp, axisPtr, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisNamesOp -- * * Return a list of the names of all the axes. * * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AxisNamesOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); if (axisPtr->flags & DELETE_PENDING) { continue; } Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(axisPtr->obj.name, -1)); } } else { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; int i; axisPtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(axisPtr->obj.name, pattern)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(axisPtr->obj.name, -1)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AxisTransformOp -- * * Maps the given axis-value to a window coordinate. * * Results: * Returns the window coordinate via interp->result. If an error occurred, * TCL_ERROR is returned and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ static int AxisTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return TransformOp(interp, axisPtr, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * AxisMarginOp -- * * This procedure returns a string representing the axis limits of the * graph. The format of the string is { left top right bottom}. * * Results: * Always returns TCL_OK. The interp->result field is * a list of the graph axis limits. * *--------------------------------------------------------------------------- */ static int AxisTypeOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return TypeOp(interp, axisPtr, objc - 4, objv + 4); } static int AxisViewOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Axis *axisPtr; if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { return TCL_ERROR; } return ViewOp(interp, axisPtr, objc - 4, objv + 4); } static Blt_OpSpec virtAxisOps[] = { {"activate", 1, AxisActivateOp, 4, 4, "axisName"}, {"bind", 1, AxisBindOp, 3, 6, "axisName sequence command"}, {"cget", 2, AxisCgetOp, 5, 5, "axisName option"}, {"configure", 2, AxisConfigureOp, 4, 0, "axisName ?axisName?... " "?option value?..."}, {"create", 2, AxisCreateOp, 4, 0, "axisName ?option value?..."}, {"deactivate", 3, AxisActivateOp, 4, 4, "axisName"}, {"delete", 3, AxisDeleteOp, 3, 0, "?axisName?..."}, {"focus", 1, AxisFocusOp, 3, 4, "?axisName?"}, {"get", 1, AxisGetOp, 4, 4, "name"}, {"invtransform", 1, AxisInvTransformOp, 5, 5, "axisName value"}, {"limits", 1, AxisLimitsOp, 4, 4, "axisName"}, {"margin", 1, AxisMarginOp, 4, 4, "axisName"}, {"names", 1, AxisNamesOp, 3, 0, "?pattern?..."}, {"transform", 2, AxisTransformOp, 5, 5, "axisName value"}, {"type", 2, AxisTypeOp, 4, 4, "axisName"}, {"view", 1, AxisViewOp, 4, 7, "axisName ?moveto fract? " "?scroll number what?"}, }; static int nVirtAxisOps = sizeof(virtAxisOps) / sizeof(Blt_OpSpec); int Blt_VirtualAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphVirtualAxisProc *proc; int result; proc = Blt_GetOpFromObj(interp, nVirtAxisOps, virtAxisOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (interp, graphPtr, objc, objv); return result; } static Blt_OpSpec axisOps[] = { {"activate", 1, ActivateOp, 3, 3, "",}, {"bind", 1, BindOp, 2, 5, "sequence command",}, {"cget", 2, CgetOp, 4, 4, "option",}, {"configure", 2, ConfigureOp, 3, 0, "?option value?...",}, {"deactivate", 1, ActivateOp, 3, 3, "",}, {"invtransform", 1, InvTransformOp, 4, 4, "value",}, {"limits", 1, LimitsOp, 3, 3, "",}, {"transform", 1, TransformOp, 4, 4, "value",}, {"use", 1, UseOp, 3, 4, "?axisName?",}, {"view", 1, ViewOp, 3, 6, "?moveto fract? ",}, }; static int nAxisOps = sizeof(axisOps) / sizeof(Blt_OpSpec); int Blt_AxisOp(Tcl_Interp *interp, Graph *graphPtr, int margin, int objc, Tcl_Obj *const *objv) { int result; GraphAxisProc *proc; proc = Blt_GetOpFromObj(interp, nAxisOps, axisOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } if (proc == UseOp) { lastMargin = margin; /* Set global variable to the margin * in the argument list. Needed only * for UseOp. */ result = (*proc)(interp, (Axis *)graphPtr, objc - 3, objv + 3); } else { Axis *axisPtr; axisPtr = Blt_GetFirstAxis(graphPtr->margins[margin].axes); if (axisPtr == NULL) { return TCL_OK; } result = (*proc)(interp, axisPtr, objc - 3, objv + 3); } return result; } void Blt_MapAxes(Graph *graphPtr) { int margin; for (margin = 0; margin < 4; margin++) { Blt_Chain chain; Blt_ChainLink link; int count, offset; chain = graphPtr->margins[margin].axes; count = offset = 0; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (AXIS_USE|DELETE_PENDING)) != AXIS_USE) { continue; } if (graphPtr->stackAxes) { if (axisPtr->reqNumMajorTicks <= 0) { axisPtr->reqNumMajorTicks = 4; } MapStackedAxis(axisPtr, count, margin); } else { if (axisPtr->reqNumMajorTicks <= 0) { axisPtr->reqNumMajorTicks = 4; } MapAxis(axisPtr, offset, margin); } if (axisPtr->flags & AXIS_GRID) { MapGridlines(axisPtr); } offset += (AxisIsHorizontal(axisPtr)) ? axisPtr->height : axisPtr->width; count++; } } } void Blt_DrawAxes(Graph *graphPtr, Drawable drawable) { int i; for (i = 0; i < 4; i++) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->margins[i].axes); link != NULL; link = Blt_Chain_PrevLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { DrawAxis(axisPtr, drawable); } } } } /* *--------------------------------------------------------------------------- * * Blt_DrawGrids -- * * Draws the grid lines associated with each axis. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_DrawGrids(Graph *graphPtr, Drawable drawable) { int i; for (i = 0; i < 4; i++) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if (axisPtr->flags & (DELETE_PENDING|HIDE)) { continue; } if ((axisPtr->flags & AXIS_USE) && (axisPtr->flags & AXIS_GRID)) { Blt_Draw2DSegments(graphPtr->display, drawable, axisPtr->major.gc, axisPtr->major.segments, axisPtr->major.nUsed); if (axisPtr->flags & AXIS_GRIDMINOR) { Blt_Draw2DSegments(graphPtr->display, drawable, axisPtr->minor.gc, axisPtr->minor.segments, axisPtr->minor.nUsed); } } } } } /* *--------------------------------------------------------------------------- * * Blt_GridsToPostScript -- * * Draws the grid lines associated with each axis. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_GridsToPostScript(Graph *graphPtr, Blt_Ps ps) { int i; for (i = 0; i < 4; i++) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE|AXIS_GRID)) != (AXIS_GRID|AXIS_USE)) { continue; } Blt_Ps_Format(ps, "%% Axis %s: grid line attributes\n", axisPtr->obj.name); Blt_Ps_XSetLineAttributes(ps, axisPtr->major.color, axisPtr->major.lineWidth, &axisPtr->major.dashes, CapButt, JoinMiter); Blt_Ps_Format(ps, "%% Axis %s: major grid line segments\n", axisPtr->obj.name); Blt_Ps_Draw2DSegments(ps, axisPtr->major.segments, axisPtr->major.nUsed); if (axisPtr->flags & AXIS_GRIDMINOR) { Blt_Ps_XSetLineAttributes(ps, axisPtr->minor.color, axisPtr->minor.lineWidth, &axisPtr->minor.dashes, CapButt, JoinMiter); Blt_Ps_Format(ps, "%% Axis %s: minor grid line segments\n", axisPtr->obj.name); Blt_Ps_Draw2DSegments(ps, axisPtr->minor.segments, axisPtr->minor.nUsed); } } } } void Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps) { Margin *mp, *mend; for (mp = graphPtr->margins, mend = mp + 4; mp < mend; mp++) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(mp->axes); link != NULL; link = Blt_Chain_NextLink(link)) { Axis *axisPtr; axisPtr = Blt_Chain_GetValue(link); if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { AxisToPostScript(ps, axisPtr); } } } } /* *--------------------------------------------------------------------------- * * Blt_DrawAxisLimits -- * * Draws the min/max values of the axis in the plotting area. The text * strings are formatted according to the "sprintf" format descriptors in * the limitsFormats array. * * Results: * None. * * Side Effects: * Draws the numeric values of the axis limits into the outer regions of * the plotting area. * *--------------------------------------------------------------------------- */ void Blt_DrawAxisLimits(Graph *graphPtr, Drawable drawable) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; char minString[200], maxString[200]; int vMin, hMin, vMax, hMax; #define SPACING 8 vMin = vMax = graphPtr->left + graphPtr->padLeft + 2; hMin = hMax = graphPtr->bottom - graphPtr->padBottom - 2; /* Offsets */ for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; Dim2D textDim; const char *minFmt, *maxFmt; char *minPtr, *maxPtr; int isHoriz; axisPtr = Blt_GetHashValue(hPtr); if (axisPtr->flags & DELETE_PENDING) { continue; } if (axisPtr->nFormats == 0) { continue; } isHoriz = AxisIsHorizontal(axisPtr); minPtr = maxPtr = NULL; minFmt = maxFmt = axisPtr->limitsFormats[0]; if (axisPtr->nFormats > 1) { maxFmt = axisPtr->limitsFormats[1]; } if (minFmt[0] != '\0') { minPtr = minString; sprintf_s(minString, 200, minFmt, axisPtr->axisRange.min); } if (maxFmt[0] != '\0') { maxPtr = maxString; sprintf_s(maxString, 200, maxFmt, axisPtr->axisRange.max); } if (axisPtr->descending) { char *tmp; tmp = minPtr, minPtr = maxPtr, maxPtr = tmp; } if (maxPtr != NULL) { if (isHoriz) { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, &axisPtr->limitsTextStyle, graphPtr->right, hMax, &textDim); hMax -= (textDim.height + SPACING); } else { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, &axisPtr->limitsTextStyle, vMax, graphPtr->top, &textDim); vMax += (textDim.width + SPACING); } } if (minPtr != NULL) { Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); if (isHoriz) { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, &axisPtr->limitsTextStyle, graphPtr->left, hMin, &textDim); hMin -= (textDim.height + SPACING); } else { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, &axisPtr->limitsTextStyle, vMin, graphPtr->bottom, &textDim); vMin += (textDim.width + SPACING); } } } /* Loop on axes */ } void Blt_AxisLimitsToPostScript(Graph *graphPtr, Blt_Ps ps) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; double vMin, hMin, vMax, hMax; char string[200]; #define SPACING 8 vMin = vMax = graphPtr->left + graphPtr->padLeft + 2; hMin = hMax = graphPtr->bottom - graphPtr->padBottom - 2; /* Offsets */ for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; const char *minFmt, *maxFmt; unsigned int textWidth, textHeight; axisPtr = Blt_GetHashValue(hPtr); if (axisPtr->flags & DELETE_PENDING) { continue; } if (axisPtr->nFormats == 0) { continue; } minFmt = maxFmt = axisPtr->limitsFormats[0]; if (axisPtr->nFormats > 1) { maxFmt = axisPtr->limitsFormats[1]; } if (*maxFmt != '\0') { sprintf_s(string, 200, maxFmt, axisPtr->axisRange.max); Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, &textHeight); if ((textWidth > 0) && (textHeight > 0)) { if (axisPtr->obj.classId == CID_AXIS_X) { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, (double)graphPtr->right, hMax); hMax -= (textWidth + SPACING); } else { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, vMax, (double)graphPtr->top); vMax += (textWidth + SPACING); } } } if (*minFmt != '\0') { sprintf_s(string, 200, minFmt, axisPtr->axisRange.min); Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, &textHeight); if ((textWidth > 0) && (textHeight > 0)) { Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); if (axisPtr->obj.classId == CID_AXIS_X) { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, (double)graphPtr->left, hMin); hMin -= (textWidth + SPACING); } else { Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, vMin, (double)graphPtr->bottom); vMin += (textWidth + SPACING); } } } } } Axis * Blt_GetFirstAxis(Blt_Chain chain) { Blt_ChainLink link; link = Blt_Chain_FirstLink(chain); if (link == NULL) { return NULL; } return Blt_Chain_GetValue(link); } Axis * Blt_NearestAxis(Graph *graphPtr, int x, int y) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&graphPtr->axes.table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Axis *axisPtr; axisPtr = Blt_GetHashValue(hPtr); if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) != AXIS_USE) { continue; } if (axisPtr->flags & AXIS_SHOWTICKS) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; link = Blt_Chain_NextLink(link)) { TickLabel *labelPtr; Point2d t; double rw, rh; Point2d bbox[5]; labelPtr = Blt_Chain_GetValue(link); Blt_GetBoundingBox(labelPtr->width, labelPtr->height, axisPtr->tickAngle, &rw, &rh, bbox); t = Blt_AnchorPoint(labelPtr->anchorPos.x, labelPtr->anchorPos.y, rw, rh, axisPtr->tickAnchor); t.x = x - t.x - (rw * 0.5); t.y = y - t.y - (rh * 0.5); bbox[4] = bbox[0]; if (Blt_PointInPolygon(&t, bbox, 5)) { axisPtr->detail = "label"; return axisPtr; } } } if (axisPtr->title != NULL) { /* and then the title string. */ Point2d bbox[5]; Point2d t; double rw, rh; unsigned int w, h; Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title,-1,&w,&h); Blt_GetBoundingBox(w, h, axisPtr->titleAngle, &rw, &rh, bbox); t = Blt_AnchorPoint(axisPtr->titlePos.x, axisPtr->titlePos.y, rw, rh, axisPtr->titleAnchor); /* Translate the point so that the 0,0 is the upper left * corner of the bounding box. */ t.x = x - t.x - (rw * 0.5); t.y = y - t.y - (rh * 0.5); bbox[4] = bbox[0]; if (Blt_PointInPolygon(&t, bbox, 5)) { axisPtr->detail = "title"; return axisPtr; } } if (axisPtr->lineWidth > 0) { /* Check for the axis region */ if ((x <= axisPtr->right) && (x >= axisPtr->left) && (y <= axisPtr->bottom) && (y >= axisPtr->top)) { axisPtr->detail = "line"; return axisPtr; } } } return NULL; } ClientData Blt_MakeAxisTag(Graph *graphPtr, const char *tagName) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&graphPtr->axes.tagTable, tagName, &isNew); return Blt_GetHashKey(&graphPtr->axes.tagTable, hPtr); } /* *--------------------------------------------------------------------------- * * TimeScaleAxis -- * * Determine the units of a linear scaled axis. * * The axis limits are either the range of the data values mapped * to the axis (autoscaled), or the values specified by the -min * and -max options (manual). * * If autoscaled, the smallest and largest major ticks will * encompass the range of data values. If the -loose option is * selected, the next outer ticks are choosen. If tight, the * ticks are at or inside of the data limits are used. * * If manually set, the ticks are at or inside the data limits * are used. This makes sense for zooming. You want the * selected range to represent the next limit, not something a * bit bigger. * * Note: I added an "always" value to the -loose option to force * the manually selected axes to be loose. It's probably * not a good idea. * * maxY * | units = magnitude (of least significant digit) * | high = largest unit tick < max axis value * high _| low = smallest unit tick > min axis value * | * | range = high - low * | # ticks = greatest factor of range/units * _| * U | * n | * i | * t _| * | * | * | * low _| * | * |_minX________________maxX__ * | | | | | * minY low high * minY * * numTicks = Number of ticks * min = Minimum value of axis * max = Maximum value of axis * range = Range of values (max - min) * * Results: * None. * * Side Effects: * The axis tick information is set. The actual tick values will * be generated later. * *--------------------------------------------------------------------------- */ static void TimeScaleAxis(Axis *axisPtr, double min, double max) { #ifdef notdef double step; double tickMin, tickMax; double axisMin, axisMax; unsigned int nTicks; range = max - min; #define SECONDS_MIN (60) #define SECONDS_HOUR (SECONDS_MIN * 60) #define SECONDS_DAY (SECONDS_HOUR * 24) #define SECONDS_MONTH (SECONDS_DAY * 30) #define SECONDS_YEAR (SECONDS_MONTH * 12) div = nTicks - 1; if (range > (SECONDS_MONTH * 6 * div)) { unit = TICK_YEAR; } else if (range > (SECONDS_MONTH * 3 * div)) { unit = TICKS_6MONTH; first = timefloor(min, unit); last = timeceil(max, unit); } else if (range > (SECONDS_MONTH * 2 * div)) { unit = TICKS_3MONTH; first = timefloor(min, unit); last = timeceil(max, unit); } else if (range > (SECONDS_MONTH * div)) { unit = TICKS_2MONTH; first = timefloor(min, unit); last = timeceil(max, unit); } else if (range > (SECONDS_DAY * 15 * div)) { unit = TICKS_1MONTH; } else if (range > (SECONDS_DAY * 10 * div)) { unit = TICKS_15DAY; } else if (range > (SECONDS_DAY * div)) { unit = TICKS_10DAY; } else if (range > (SECONDS_HOUR * 12 * div)) { unit = TICKS_1DAY; } else if (range > (SECONDS_HOUR * 6 * div)) { unit = TICKS_12HOUR; } else if (range > (SECONDS_HOUR * 3 * div)) { unit = TICKS_6HOUR; } else if (range > (SECONDS_HOUR * div)) { unit = TICKS_3HOUR; } else if (range > (SECONDS_MIN * 30 * div)) { unit = TICKS_HOUR; } else if (range > (SECONDS_MIN * 20 * div)) { unit = TICKS_30MIN; } else if (range > (SECONDS_MIN * 15 * div)) { unit = TICKS_20MIN; } else if (range > (SECONDS_MIN * 10 * div)) { unit = TICKS_15MIN; } else if (range > (SECONDS_MIN * div)) { unit = TICKS_10MIN; } else if (range > (SECONDS_SEC * 30 * div)) { unit = TICKS_1MIN; } else if (range > (SECONDS_SEC * 20 * div)) { unit = TICKS_30SEC; } else if (range > (SECONDS_SEC * 15 * div)) { unit = TICKS_20SEC; } else if (range > (SECONDS_SEC * 10 * div)) { unit = TICKS_15SEC; } else if (range > (SECONDS_SEC * div)) { unit = TICKS_10SEC; } else { unit = TICKS_1SEC; } } else { unit = TICKS_SECS; } nTicks = 0; step = 1.0; /* Suppress compiler warning. */ axisMin = axisMax = tickMin = tickMax = Blt_NaN(); if (min < max) { double range; range = max - min; /* Calculate the major tick stepping. */ if (axisPtr->reqStep > 0.0) { /* An interval was designated by the user. Keep scaling it until * it fits comfortably within the current range of the axis. */ step = axisPtr->reqStep; while ((2 * step) >= range) { step *= 0.5; } } else { range = NiceNum(range, 0); step = NiceNum(range / axisPtr->reqNumMajorTicks, 1); } /* Find the outer tick values. Add 0.0 to prevent getting -0.0. */ axisMin = tickMin = floor(min / step) * step + 0.0; axisMax = tickMax = ceil(max / step) * step + 0.0; nTicks = Round((tickMax - tickMin) / step) + 1; } axisPtr->majorSweep.step = step; axisPtr->majorSweep.initial = tickMin; axisPtr->majorSweep.nSteps = nTicks; /* * The limits of the axis are either the range of the data ("tight") or at * the next outer tick interval ("loose"). The looseness or tightness has * to do with how the axis fits the range of data values. This option is * overridden when the user sets an axis limit (by either -min or -max * option). The axis limit is always at the selected limit (otherwise we * assume that user would have picked a different number). */ if ((axisPtr->looseMin == AXIS_TIGHT) || ((axisPtr->looseMin == AXIS_LOOSE) && (DEFINED(axisPtr->reqMin)))) { axisMin = min; } if ((axisPtr->looseMax == AXIS_TIGHT) || ((axisPtr->looseMax == AXIS_LOOSE) && (DEFINED(axisPtr->reqMax)))) { axisMax = max; } SetAxisRange(&axisPtr->axisRange, axisMin, axisMax); /* Now calculate the minor tick step and number. */ if ((axisPtr->reqNumMinorTicks > 0) && (axisPtr->flags & AXIS_AUTO_MAJOR)) { nTicks = axisPtr->reqNumMinorTicks - 1; step = 1.0 / (nTicks + 1); } else { nTicks = 0; /* No minor ticks. */ step = 0.5; /* Don't set the minor tick interval to * 0.0. It makes the GenerateTicks * routine * create minor log-scale tick * marks. */ } axisPtr->minorSweep.initial = axisPtr->minorSweep.step = step; axisPtr->minorSweep.nSteps = nTicks; #endif } #ifdef notdef static Ticks * TimeGenerateTicks(TickSweep *sweepPtr) { Ticks *ticksPtr; ticksPtr = Blt_AssertMalloc(sizeof(Ticks) + (sweepPtr->nSteps * sizeof(double))); ticksPtr->nTicks = 0; if (sweepPtr->step == 0.0) { /* Hack: A zero step indicates to use log values. */ int i; /* Precomputed log10 values [1..10] */ static double logTable[] = { 0.0, 0.301029995663981, 0.477121254719662, 0.602059991327962, 0.698970004336019, 0.778151250383644, 0.845098040014257, 0.903089986991944, 0.954242509439325, 1.0 }; for (i = 0; i < sweepPtr->nSteps; i++) { ticksPtr->values[i] = logTable[i]; } } else { double value; int i; value = sweepPtr->initial; /* Start from smallest axis tick */ for (i = 0; i < sweepPtr->nSteps; i++) { value = UROUND(value, sweepPtr->step); ticksPtr->values[i] = value; value += sweepPtr->step; } } ticksPtr->nTicks = sweepPtr->nSteps; return ticksPtr; } static double TimeFloor(double min, int unit) { unsigned long ticks; ticks = (long)floor(min); localtime_r(&ticks, &tm); switch(unit) { case TICK_6MONTHS: tm.sec = 0; tm.min = 0; tm.day = 0; tm. } } static double TimeCeil(double max, int unit) { } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkIntBorder.h�����������������������������������������������������������������0000644�0001750�0001750�00000004523�11462120063�015432� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkIntBorder.h -- * * * The Border structure used internally by the Tk_3D* routines. * The following is a copy of it from tk3d.c. * * Contains copies of internal Tk structures. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _TK_BORDER_INT_H #define _TK_BORDER_INT_H typedef struct _TkBorder { Screen *screen; /* Screen on which the border will be used. */ Visual *visual; /* Visual for all windows and pixmaps using * the border. */ int depth; /* Number of bits per pixel of drawables where * the border will be used. */ Colormap colormap; /* Colormap out of which pixels are * allocated. */ int refCount; /* Number of different users of * this border. */ #if (_TK_VERSION >= _VERSION(8,1,0)) int objRefCount; /* The number of TCL objects that reference * this structure. */ #endif /* _TK_VERSION >= 8.1.0 */ XColor *bgColor; /* Background color (intensity between * lightColorPtr and darkColorPtr). */ XColor *darkColor; /* Color for darker areas (must free when * deleting structure). NULL means shadows * haven't been allocated yet.*/ XColor *lightColor; /* Color used for lighter areas of border * (must free this when deleting structure). * NULL means shadows haven't been allocated * yet. */ Pixmap shadow; /* Stipple pattern to use for drawing * shadows areas. Used for displays with * <= 64 colors or where colormap has filled * up. */ GC bgGC; /* Used (if necessary) to draw areas in * the background color. */ GC darkGC; /* Used to draw darker parts of the * border. None means the shadow colors * haven't been allocated yet.*/ GC lightGC; /* Used to draw lighter parts of * the border. None means the shadow colors * haven't been allocated yet. */ Tcl_HashEntry *hashPtr; /* Entry in borderTable (needed in * order to delete structure). */ struct _TkBorder *nextPtr; /* Points to the next TkBorder structure with * the same color name. Borders with the * same name but different screens or * colormaps are chained together off a * single entry in borderTable. */ } TkBorder; #endif /* _TK_BORDER_INT_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVecCmd.c�������������������������������������������������������������������0000644�0001750�0001750�00000175003�11462120063�015043� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVecCmd.c -- * * This module implements vector data objects. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Code for binary data read operation was donated by Harold Kirsch. * */ /* * TODO: * o Add H. Kirsch's vector binary read operation * x binread file0 * x binread -file file0 * * o Add ASCII/binary file reader * x read fileName * * o Allow Tcl-based client notifications. * vector x * x notify call Display * x notify delete Display * x notify reorder #1 #2 */ #include "bltVecInt.h" #include "bltOp.h" #include "bltNsUtil.h" #include "bltSwitch.h" typedef int (VectorCmdProc)(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static Blt_SwitchParseProc ObjToFFTVector; static Blt_SwitchCustom fftVectorSwitch = { ObjToFFTVector, NULL, (ClientData)0, }; static Blt_SwitchParseProc ObjToIndex; static Blt_SwitchCustom indexSwitch = { ObjToIndex, NULL, (ClientData)0, }; typedef struct { Tcl_Obj *formatObjPtr; int from, to; } PrintSwitches; static Blt_SwitchSpec printSwitches[] = { {BLT_SWITCH_OBJ, "-format", "string", Blt_Offset(PrintSwitches, formatObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-from", "index", Blt_Offset(PrintSwitches, from), 0, 0, &indexSwitch}, {BLT_SWITCH_CUSTOM, "-to", "index", Blt_Offset(PrintSwitches, to), 0, 0, &indexSwitch}, {BLT_SWITCH_END} }; typedef struct { int flags; } SortSwitches; #define SORT_DECREASING (1<<0) #define SORT_UNIQUE (1<<1) static Blt_SwitchSpec sortSwitches[] = { {BLT_SWITCH_BITMASK, "-decreasing", "", Blt_Offset(SortSwitches, flags), 0, SORT_DECREASING}, {BLT_SWITCH_BITMASK, "-reverse", "", Blt_Offset(SortSwitches, flags), 0, SORT_DECREASING}, {BLT_SWITCH_BITMASK, "-uniq", "", Blt_Offset(SortSwitches, flags), 0, SORT_UNIQUE}, {BLT_SWITCH_END} }; typedef struct { double delta; Vector *imagPtr; /* Vector containing imaginary part. */ Vector *freqPtr; /* Vector containing frequencies. */ VectorInterpData *dataPtr; int mask; /* Flags controlling FFT. */ } FFTData; static Blt_SwitchSpec fftSwitches[] = { {BLT_SWITCH_CUSTOM, "-imagpart", "vector", Blt_Offset(FFTData, imagPtr), 0, 0, &fftVectorSwitch}, {BLT_SWITCH_BITMASK, "-noconstant", "", Blt_Offset(FFTData, mask), 0, FFT_NO_CONSTANT}, {BLT_SWITCH_BITMASK, "-spectrum", "", Blt_Offset(FFTData, mask), 0, FFT_SPECTRUM}, {BLT_SWITCH_BITMASK, "-bartlett", "", Blt_Offset(FFTData, mask), 0, FFT_BARTLETT}, {BLT_SWITCH_DOUBLE, "-delta", "float", Blt_Offset(FFTData, mask), 0, 0, }, {BLT_SWITCH_CUSTOM, "-frequencies", "vector", Blt_Offset(FFTData, freqPtr), 0, 0, &fftVectorSwitch}, {BLT_SWITCH_END} }; /* *--------------------------------------------------------------------------- * * ObjToFFTVector -- * * Convert a string representing a vector into its vector structure. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToFFTVector( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Name of vector. */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { FFTData *dataPtr = (FFTData *)record; Vector *vPtr; Vector **vPtrPtr = (Vector **)(record + offset); int isNew; /* Not used. */ char *string; string = Tcl_GetString(objPtr); vPtr = Blt_Vec_Create(dataPtr->dataPtr, string, string, string, &isNew); if (vPtr == NULL) { return TCL_ERROR; } *vPtrPtr = vPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToIndex -- * * Convert a string representing a vector into its vector structure. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIndex( ClientData clientData, /* Contains the vector in question to verify * its length. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Name of vector. */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Vector *vPtr = clientData; int *indexPtr = (int *)(record + offset); int index; if (Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objPtr), &index, INDEX_CHECK, (Blt_VectorIndexProc **)NULL) != TCL_OK) { return TCL_ERROR; } *indexPtr = index; return TCL_OK; } static Tcl_Obj * GetValues(Vector *vPtr, int first, int last) { Tcl_Obj *listObjPtr; double *vp, *vend; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (vp = vPtr->valueArr + first, vend = vPtr->valueArr + last; vp <= vend; vp++) { Tcl_ListObjAppendElement(vPtr->interp, listObjPtr, Tcl_NewDoubleObj(*vp)); } return listObjPtr; } static void ReplicateValue(Vector *vPtr, int first, int last, double value) { double *vp, *vend; for (vp = vPtr->valueArr + first, vend = vPtr->valueArr + last; vp <= vend; vp++) { *vp = value; } vPtr->notifyFlags |= UPDATE_RANGE; } static int CopyList(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; if (Blt_Vec_SetLength(interp, vPtr, objc) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < objc; i++) { double value; if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { Blt_Vec_SetLength(interp, vPtr, i); return TCL_ERROR; } vPtr->valueArr[i] = value; } return TCL_OK; } static int AppendVector(Vector *destPtr, Vector *srcPtr) { size_t nBytes; size_t oldSize, newSize; oldSize = destPtr->length; newSize = oldSize + srcPtr->last - srcPtr->first + 1; if (Blt_Vec_ChangeLength(destPtr->interp, destPtr, newSize) != TCL_OK) { return TCL_ERROR; } nBytes = (newSize - oldSize) * sizeof(double); memcpy((char *)(destPtr->valueArr + oldSize), (srcPtr->valueArr + srcPtr->first), nBytes); destPtr->notifyFlags |= UPDATE_RANGE; return TCL_OK; } static int AppendList(Vector *vPtr, int objc, Tcl_Obj *const *objv) { Tcl_Interp *interp = vPtr->interp; int count; int i; double value; int oldSize; oldSize = vPtr->length; if (Blt_Vec_ChangeLength(interp, vPtr, vPtr->length + objc) != TCL_OK) { return TCL_ERROR; } count = oldSize; for (i = 0; i < objc; i++) { if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { Blt_Vec_ChangeLength(interp, vPtr, count); return TCL_ERROR; } vPtr->valueArr[count++] = value; } vPtr->notifyFlags |= UPDATE_RANGE; return TCL_OK; } /* Vector instance option commands */ /* *--------------------------------------------------------------------------- * * AppendOp -- * * Appends one of more TCL lists of values, or vector objects onto the * end of the current vector object. * * Results: * A standard TCL result. If a current vector can't be created, * resized, any of the named vectors can't be found, or one of lists of * values is invalid, TCL_ERROR is returned. * * Side Effects: * Clients of current vector will be notified of the change. * *--------------------------------------------------------------------------- */ static int AppendOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; int result; Vector *v2Ptr; for (i = 2; i < objc; i++) { v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, Tcl_GetString(objv[i]), (const char **)NULL, NS_SEARCH_BOTH); if (v2Ptr != NULL) { result = AppendVector(vPtr, v2Ptr); } else { int nElem; Tcl_Obj **elemObjArr; if (Tcl_ListObjGetElements(interp, objv[i], &nElem, &elemObjArr) != TCL_OK) { return TCL_ERROR; } result = AppendList(vPtr, nElem, elemObjArr); } if (result != TCL_OK) { return TCL_ERROR; } } if (objc > 2) { if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ClearOp -- * * Deletes all the accumulated array indices for the TCL array associated * will the vector. This routine can be used to free excess memory from * a large vector. * * Results: * Always returns TCL_OK. * * Side Effects: * Memory used for the entries of the TCL array variable is freed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ClearOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Vec_FlushCache(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the given indices from the vector. If no indices are provided * the entire vector is deleted. * * Results: * A standard TCL result. If any of the given indices is invalid, * interp->result will an error message and TCL_ERROR is returned. * * Side Effects: * The clients of the vector will be notified of the vector * deletions. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { unsigned char *unsetArr; int i, j; int count; char *string; /* FIXME: Don't delete vector with no indices. */ if (objc == 2) { Blt_Vec_Free(vPtr); return TCL_OK; } /* Allocate an "unset" bitmap the size of the vector. */ unsetArr = Blt_AssertCalloc(sizeof(unsigned char), (vPtr->length + 7) / 8); #define SetBit(i) \ unsetArr[(i) >> 3] |= (1 << ((i) & 0x07)) #define GetBit(i) \ (unsetArr[(i) >> 3] & (1 << ((i) & 0x07))) for (i = 2; i < objc; i++) { string = Tcl_GetString(objv[i]); if (Blt_Vec_GetIndexRange(interp, vPtr, string, (INDEX_COLON | INDEX_CHECK), (Blt_VectorIndexProc **) NULL) != TCL_OK) { Blt_Free(unsetArr); return TCL_ERROR; } for (j = vPtr->first; j <= vPtr->last; j++) { SetBit(j); /* Mark the range of elements for deletion. */ } } count = 0; for (i = 0; i < vPtr->length; i++) { if (GetBit(i)) { continue; /* Skip elements marked for deletion. */ } if (count < i) { vPtr->valueArr[count] = vPtr->valueArr[i]; } count++; } Blt_Free(unsetArr); vPtr->length = count; if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DupOp -- * * Creates one or more duplicates of the vector object. * * Results: * A standard TCL result. If a new vector can't be created, * or and existing vector resized, TCL_ERROR is returned. * * Side Effects: * Clients of existing vectors will be notified of the change. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DupOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { Vector *v2Ptr; char *name; int isNew; name = Tcl_GetString(objv[i]); v2Ptr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew); if (v2Ptr == NULL) { return TCL_ERROR; } if (v2Ptr == vPtr) { continue; } if (Blt_Vec_Duplicate(v2Ptr, vPtr) != TCL_OK) { return TCL_ERROR; } if (!isNew) { if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } Blt_Vec_UpdateClients(v2Ptr); } } return TCL_OK; } /* spinellia@acm.org START */ /* fft implementation */ /*ARGSUSED*/ static int FFTOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Vector *v2Ptr = NULL; int isNew; FFTData data; char *realVecName; memset(&data, 0, sizeof(data)); data.delta = 1.0; realVecName = Tcl_GetString(objv[2]); v2Ptr = Blt_Vec_Create(vPtr->dataPtr, realVecName, realVecName, realVecName, &isNew); if (v2Ptr == NULL) { return TCL_ERROR; } if (v2Ptr == vPtr) { Tcl_AppendResult(interp, "real vector \"", realVecName, "\"", " can't be the same as the source", (char *)NULL); return TCL_ERROR; } if (Blt_ParseSwitches(interp, fftSwitches, objc - 3, objv + 3, &data, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (Blt_Vec_FFT(interp, v2Ptr, data.imagPtr, data.freqPtr, data.delta, data.mask, vPtr) != TCL_OK) { return TCL_ERROR; } /* Update bookkeeping. */ if (!isNew) { if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } Blt_Vec_UpdateClients(v2Ptr); } if (data.imagPtr != NULL) { if (data.imagPtr->flush) { Blt_Vec_FlushCache(data.imagPtr); } Blt_Vec_UpdateClients(data.imagPtr); } if (data.freqPtr != NULL) { if (data.freqPtr->flush) { Blt_Vec_FlushCache(data.freqPtr); } Blt_Vec_UpdateClients(data.freqPtr); } return TCL_OK; } /*ARGSUSED*/ static int InverseFFTOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int isNew; char *name; Vector *srcImagPtr; Vector *destRealPtr; Vector *destImagPtr; name = Tcl_GetString(objv[2]); if (Blt_Vec_LookupName(vPtr->dataPtr, name, &srcImagPtr) != TCL_OK ) { return TCL_ERROR; } name = Tcl_GetString(objv[3]); destRealPtr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew); name = Tcl_GetString(objv[4]); destImagPtr = Blt_Vec_Create(vPtr->dataPtr, name, name, name, &isNew); if (Blt_Vec_InverseFFT(interp, srcImagPtr, destRealPtr, destImagPtr, vPtr) != TCL_OK ){ return TCL_ERROR; } if (destRealPtr->flush) { Blt_Vec_FlushCache(destRealPtr); } Blt_Vec_UpdateClients(destRealPtr); if (destImagPtr->flush) { Blt_Vec_FlushCache(destImagPtr); } Blt_Vec_UpdateClients(destImagPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Sets or reads the value of the index. This simulates what the * vector's variable does. * * Results: * A standard TCL result. If the index is invalid, * interp->result will an error message and TCL_ERROR is returned. * Otherwise interp->result will contain the values. * *--------------------------------------------------------------------------- */ static int IndexOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int first, last; char *string; string = Tcl_GetString(objv[2]); if (Blt_Vec_GetIndexRange(interp, vPtr, string, INDEX_ALL_FLAGS, (Blt_VectorIndexProc **) NULL) != TCL_OK) { return TCL_ERROR; } first = vPtr->first, last = vPtr->last; if (objc == 3) { Tcl_Obj *listObjPtr; if (first == vPtr->length) { Tcl_AppendResult(interp, "can't get index \"", string, "\"", (char *)NULL); return TCL_ERROR; /* Can't read from index "++end" */ } listObjPtr = GetValues(vPtr, first, last); Tcl_SetObjResult(interp, listObjPtr); } else { double value; /* FIXME: huh? Why set values here?. */ if (first == SPECIAL_INDEX) { Tcl_AppendResult(interp, "can't set index \"", string, "\"", (char *)NULL); return TCL_ERROR; /* Tried to set "min" or "max" */ } if (Blt_ExprDoubleFromObj(interp, objv[3], &value) != TCL_OK) { return TCL_ERROR; } if (first == vPtr->length) { if (Blt_Vec_ChangeLength(interp, vPtr, vPtr->length + 1) != TCL_OK) { return TCL_ERROR; } } ReplicateValue(vPtr, first, last, value); Tcl_SetObjResult(interp, objv[3]); if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LengthOp -- * * Returns the length of the vector. If a new size is given, the * vector is resized to the new vector. * * Results: * A standard TCL result. If the new length is invalid, * interp->result will an error message and TCL_ERROR is returned. * Otherwise interp->result will contain the length of the vector. * *--------------------------------------------------------------------------- */ static int LengthOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { int nElem; if (Tcl_GetIntFromObj(interp, objv[2], &nElem) != TCL_OK) { return TCL_ERROR; } if (nElem < 0) { Tcl_AppendResult(interp, "bad vector size \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } if ((Blt_Vec_SetSize(interp, vPtr, nElem) != TCL_OK) || (Blt_Vec_SetLength(interp, vPtr, nElem) != TCL_OK)) { return TCL_ERROR; } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } Tcl_SetIntObj(Tcl_GetObjResult(interp), vPtr->length); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MapOp -- * * Queries or sets the offset of the array index from the base * address of the data array of values. * * Results: * A standard TCL result. If the source vector doesn't exist * or the source list is not a valid list of numbers, TCL_ERROR * returned. Otherwise TCL_OK is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MapOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc > 2) { if (Blt_Vec_MapVariable(interp, vPtr, Tcl_GetString(objv[2])) != TCL_OK) { return TCL_ERROR; } } if (vPtr->arrayName != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), vPtr->arrayName, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * MaxOp -- * * Returns the maximum value of the vector. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MaxOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetDoubleObj(Tcl_GetObjResult(interp), Blt_Vec_Max(vPtr)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MergeOp -- * * Merges the values from the given vectors to the current vector. * * Results: * A standard TCL result. If any of the given vectors differ in size, * TCL_ERROR is returned. Otherwise TCL_OK is returned and the * vector data will contain merged values of the given vectors. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MergeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Vector **vecArr; int refSize, nElem; int i; double *valuePtr, *valueArr; Vector **vPtrPtr; /* Allocate an array of vector pointers of each vector to be * merged in the current vector. */ vecArr = Blt_AssertMalloc(sizeof(Vector *) * objc); vPtrPtr = vecArr; refSize = -1; nElem = 0; for (i = 2; i < objc; i++) { Vector *v2Ptr; int length; if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), &v2Ptr) != TCL_OK) { Blt_Free(vecArr); return TCL_ERROR; } /* Check that all the vectors are the same length */ length = v2Ptr->last - v2Ptr->first + 1; if (refSize < 0) { refSize = length; } else if (length != refSize) { Tcl_AppendResult(vPtr->interp, "vectors \"", vPtr->name, "\" and \"", v2Ptr->name, "\" differ in length", (char *)NULL); Blt_Free(vecArr); return TCL_ERROR; } *vPtrPtr++ = v2Ptr; nElem += refSize; } *vPtrPtr = NULL; valueArr = Blt_Malloc(sizeof(double) * nElem); if (valueArr == NULL) { Tcl_AppendResult(vPtr->interp, "not enough memory to allocate ", Blt_Itoa(nElem), " vector elements", (char *)NULL); return TCL_ERROR; } /* Merge the values from each of the vectors into the current vector */ valuePtr = valueArr; for (i = 0; i < refSize; i++) { Vector **vpp; for (vpp = vecArr; *vpp != NULL; vpp++) { *valuePtr++ = (*vpp)->valueArr[i + (*vpp)->first]; } } Blt_Free(vecArr); Blt_Vec_Reset(vPtr, valueArr, nElem, nElem, TCL_DYNAMIC); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MinOp -- * * Returns the minimum value of the vector. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MinOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetDoubleObj(Tcl_GetObjResult(interp), Blt_Vec_Min(vPtr)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NormalizeOp -- * * Normalizes the vector. * * Results: * A standard TCL result. If the density is invalid, TCL_ERROR * is returned. Otherwise TCL_OK is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NormalizeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; double range; Blt_Vec_UpdateRange(vPtr); range = vPtr->max - vPtr->min; if (objc > 2) { Vector *v2Ptr; int isNew; char *string; string = Tcl_GetString(objv[2]); v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string, &isNew); if (v2Ptr == NULL) { return TCL_ERROR; } if (Blt_Vec_SetLength(interp, v2Ptr, vPtr->length) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < vPtr->length; i++) { v2Ptr->valueArr[i] = (vPtr->valueArr[i] - vPtr->min) / range; } Blt_Vec_UpdateRange(v2Ptr); if (!isNew) { if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } Blt_Vec_UpdateClients(v2Ptr); } } else { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 0; i < vPtr->length; i++) { double norm; norm = (vPtr->valueArr[i] - vPtr->min) / range; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(norm)); } Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyOp -- * * Notify clients of vector. * * Results: * A standard TCL result. If any of the given vectors differ in size, * TCL_ERROR is returned. Otherwise TCL_OK is returned and the * vector data will contain merged values of the given vectors. * * x vector notify now * x vector notify always * x vector notify whenidle * x vector notify update {} * x vector notify delete {} * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NotifyOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int option; int bool; enum optionIndices { OPTION_ALWAYS, OPTION_NEVER, OPTION_WHENIDLE, OPTION_NOW, OPTION_CANCEL, OPTION_PENDING }; static const char *optionArr[] = { "always", "never", "whenidle", "now", "cancel", "pending", NULL }; if (Tcl_GetIndexFromObj(interp, objv[2], optionArr, "qualifier", TCL_EXACT, &option) != TCL_OK) { return TCL_OK; } switch (option) { case OPTION_ALWAYS: vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK; vPtr->notifyFlags |= NOTIFY_ALWAYS; break; case OPTION_NEVER: vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK; vPtr->notifyFlags |= NOTIFY_NEVER; break; case OPTION_WHENIDLE: vPtr->notifyFlags &= ~NOTIFY_WHEN_MASK; vPtr->notifyFlags |= NOTIFY_WHENIDLE; break; case OPTION_NOW: /* FIXME: How does this play when an update is pending? */ Blt_Vec_NotifyClients(vPtr); break; case OPTION_CANCEL: if (vPtr->notifyFlags & NOTIFY_PENDING) { vPtr->notifyFlags &= ~NOTIFY_PENDING; Tcl_CancelIdleCall(Blt_Vec_NotifyClients, (ClientData)vPtr); } break; case OPTION_PENDING: bool = (vPtr->notifyFlags & NOTIFY_PENDING); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); break; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PopulateOp -- * * Creates or resizes a new vector based upon the density specified. * * Results: * A standard TCL result. If the density is invalid, TCL_ERROR * is returned. Otherwise TCL_OK is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PopulateOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Vector *v2Ptr; int size, density; int isNew; int i, j; double *valuePtr; int count; char *string; string = Tcl_GetString(objv[2]); v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string, &isNew); if (v2Ptr == NULL) { return TCL_ERROR; } if (vPtr->length == 0) { return TCL_OK; /* Source vector is empty. */ } if (Tcl_GetIntFromObj(interp, objv[3], &density) != TCL_OK) { return TCL_ERROR; } if (density < 1) { Tcl_AppendResult(interp, "bad density \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } size = (vPtr->length - 1) * (density + 1) + 1; if (Blt_Vec_SetLength(interp, v2Ptr, size) != TCL_OK) { return TCL_ERROR; } count = 0; valuePtr = v2Ptr->valueArr; for (i = 0; i < (vPtr->length - 1); i++) { double slice, range; range = vPtr->valueArr[i + 1] - vPtr->valueArr[i]; slice = range / (double)(density + 1); for (j = 0; j <= density; j++) { *valuePtr = vPtr->valueArr[i] + (slice * (double)j); valuePtr++; count++; } } count++; *valuePtr = vPtr->valueArr[i]; assert(count == v2Ptr->length); if (!isNew) { if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } Blt_Vec_UpdateClients(v2Ptr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ValuesOp -- * * Print the values vector. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ValuesOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PrintSwitches switches; switches.formatObjPtr = NULL; switches.from = 0; switches.to = vPtr->length - 1; indexSwitch.clientData = vPtr; if (Blt_ParseSwitches(interp, printSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.from > switches.to) { int tmp; /* swap positions. */ tmp = switches.to; switches.to = switches.from; switches.from = tmp; } if (switches.formatObjPtr == NULL) { Tcl_Obj *listObjPtr; int i; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = switches.from; i <= switches.to; i++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(vPtr->valueArr[i])); } Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_DString ds; char buffer[200]; const char *fmt; int i; Tcl_DStringInit(&ds); fmt = Tcl_GetString(switches.formatObjPtr); for (i = switches.from; i <= switches.to; i++) { sprintf(buffer, fmt, vPtr->valueArr[i]); Tcl_DStringAppend(&ds, buffer, -1); } Tcl_DStringResult(interp, &ds); Tcl_DStringFree(&ds); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RangeOp -- * * Returns a TCL list of the range of vector values specified. * * Results: * A standard TCL result. If the given range is invalid, TCL_ERROR * is returned. Otherwise TCL_OK is returned and interp->result * will contain the list of values. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RangeOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; int first, last; int i; if (objc == 2) { first = 0; last = vPtr->length - 1; } else if (objc == 4) { if ((Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objv[2]), &first, INDEX_CHECK, (Blt_VectorIndexProc **) NULL) != TCL_OK) || (Blt_Vec_GetIndex(interp, vPtr, Tcl_GetString(objv[3]), &last, INDEX_CHECK, (Blt_VectorIndexProc **) NULL) != TCL_OK)) { return TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " range ?first last?", (char *)NULL); return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (first > last) { /* Return the list reversed */ for (i = last; i <= first; i++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(vPtr->valueArr[i])); } } else { for (i = first; i <= last; i++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(vPtr->valueArr[i])); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InRange -- * * Determines if a value lies within a given range. * * The value is normalized and compared against the interval * [0..1], where 0.0 is the minimum and 1.0 is the maximum. * DBL_EPSILON is the smallest number that can be represented * on the host machine, such that (1.0 + epsilon) != 1.0. * * Please note, min cannot be greater than max. * * Results: * If the value is within of the interval [min..max], 1 is * returned; 0 otherwise. * *--------------------------------------------------------------------------- */ INLINE static int InRange(double value, double min, double max) { double range; range = max - min; if (range < DBL_EPSILON) { return (FABS(max - value) < DBL_EPSILON); } else { double norm; norm = (value - min) / range; return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON)); } } enum NativeFormats { FMT_UNKNOWN = -1, FMT_UCHAR, FMT_CHAR, FMT_USHORT, FMT_SHORT, FMT_UINT, FMT_INT, FMT_ULONG, FMT_LONG, FMT_FLOAT, FMT_DOUBLE }; /* *--------------------------------------------------------------------------- * * GetBinaryFormat * * Translates a format string into a native type. Valid formats are * * signed i1, i2, i4, i8 * unsigned u1, u2, u4, u8 * real r4, r8, r16 * * There must be a corresponding native type. For example, this for * reading 2-byte binary integers from an instrument and converting them * to unsigned shorts or ints. * *--------------------------------------------------------------------------- */ static enum NativeFormats GetBinaryFormat(Tcl_Interp *interp, char *string, int *sizePtr) { char c; c = tolower(string[0]); if (Tcl_GetInt(interp, string + 1, sizePtr) != TCL_OK) { Tcl_AppendResult(interp, "unknown binary format \"", string, "\": incorrect byte size", (char *)NULL); return FMT_UNKNOWN; } switch (c) { case 'r': if (*sizePtr == sizeof(double)) { return FMT_DOUBLE; } else if (*sizePtr == sizeof(float)) { return FMT_FLOAT; } break; case 'i': if (*sizePtr == sizeof(char)) { return FMT_CHAR; } else if (*sizePtr == sizeof(int)) { return FMT_INT; } else if (*sizePtr == sizeof(long)) { return FMT_LONG; } else if (*sizePtr == sizeof(short)) { return FMT_SHORT; } break; case 'u': if (*sizePtr == sizeof(unsigned char)) { return FMT_UCHAR; } else if (*sizePtr == sizeof(unsigned int)) { return FMT_UINT; } else if (*sizePtr == sizeof(unsigned long)) { return FMT_ULONG; } else if (*sizePtr == sizeof(unsigned short)) { return FMT_USHORT; } break; default: Tcl_AppendResult(interp, "unknown binary format \"", string, "\": should be either i#, r#, u# (where # is size in bytes)", (char *)NULL); return FMT_UNKNOWN; } Tcl_AppendResult(interp, "can't handle format \"", string, "\"", (char *)NULL); return FMT_UNKNOWN; } static int CopyValues(Vector *vPtr, char *byteArr, enum NativeFormats fmt, int size, int length, int swap, int *indexPtr) { int i, n; int newSize; if ((swap) && (size > 1)) { int nBytes = size * length; unsigned char *p; int left, right; for (i = 0; i < nBytes; i += size) { p = (unsigned char *)(byteArr + i); for (left = 0, right = size - 1; left < right; left++, right--) { p[left] ^= p[right]; p[right] ^= p[left]; p[left] ^= p[right]; } } } newSize = *indexPtr + length; if (newSize > vPtr->length) { if (Blt_Vec_ChangeLength(vPtr->interp, vPtr, newSize) != TCL_OK) { return TCL_ERROR; } } #define CopyArrayToVector(vPtr, arr) \ for (i = 0, n = *indexPtr; i < length; i++, n++) { \ (vPtr)->valueArr[n] = (double)(arr)[i]; \ } switch (fmt) { case FMT_CHAR: CopyArrayToVector(vPtr, (char *)byteArr); break; case FMT_UCHAR: CopyArrayToVector(vPtr, (unsigned char *)byteArr); break; case FMT_INT: CopyArrayToVector(vPtr, (int *)byteArr); break; case FMT_UINT: CopyArrayToVector(vPtr, (unsigned int *)byteArr); break; case FMT_LONG: CopyArrayToVector(vPtr, (long *)byteArr); break; case FMT_ULONG: CopyArrayToVector(vPtr, (unsigned long *)byteArr); break; case FMT_SHORT: CopyArrayToVector(vPtr, (short int *)byteArr); break; case FMT_USHORT: CopyArrayToVector(vPtr, (unsigned short int *)byteArr); break; case FMT_FLOAT: CopyArrayToVector(vPtr, (float *)byteArr); break; case FMT_DOUBLE: CopyArrayToVector(vPtr, (double *)byteArr); break; case FMT_UNKNOWN: break; } *indexPtr += length; return TCL_OK; } /* *--------------------------------------------------------------------------- * * BinreadOp -- * * Reads binary values from a TCL channel. Values are either appended to * the end of the vector or placed at a given index (using the "-at" * option), overwriting existing values. Data is read until EOF is found * on the channel or a specified number of values are read. (note that * this is not necessarily the same as the number of bytes). * * The following flags are supported: * -swap Swap bytes * -at index Start writing data at the index. * -format fmt Specifies the format of the data. * * This binary reader was created and graciously donated by Harald Kirsch * (kir@iitb.fhg.de). Anything that's wrong is due to my (gah) munging * of the code. * * Results: * Returns a standard TCL result. The interpreter result will contain the * number of values (not the number of bytes) read. * * Caveats: * Channel reads must end on an element boundary. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BinreadOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Channel channel; char *byteArr; char *string; enum NativeFormats fmt; int arraySize, bytesRead; int count, total; int first; int size, length, mode; int swap; int i; string = Tcl_GetString(objv[2]); channel = Tcl_GetChannel(interp, string, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", string, "\" wasn't opened for reading", (char *)NULL); return TCL_ERROR; } first = vPtr->length; fmt = FMT_DOUBLE; size = sizeof(double); swap = FALSE; count = 0; if (objc > 3) { string = Tcl_GetString(objv[3]); if (string[0] != '-') { long int value; /* Get the number of values to read. */ if (Tcl_GetLongFromObj(interp, objv[3], &value) != TCL_OK) { return TCL_ERROR; } if (value < 0) { Tcl_AppendResult(interp, "count can't be negative", (char *)NULL); return TCL_ERROR; } count = (size_t)value; objc--, objv++; } } /* Process any option-value pairs that remain. */ for (i = 3; i < objc; i++) { string = Tcl_GetString(objv[i]); if (strcmp(string, "-swap") == 0) { swap = TRUE; } else if (strcmp(string, "-format") == 0) { i++; if (i >= objc) { Tcl_AppendResult(interp, "missing arg after \"", string, "\"", (char *)NULL); return TCL_ERROR; } string = Tcl_GetString(objv[i]); fmt = GetBinaryFormat(interp, string, &size); if (fmt == FMT_UNKNOWN) { return TCL_ERROR; } } else if (strcmp(string, "-at") == 0) { i++; if (i >= objc) { Tcl_AppendResult(interp, "missing arg after \"", string, "\"", (char *)NULL); return TCL_ERROR; } string = Tcl_GetString(objv[i]); if (Blt_Vec_GetIndex(interp, vPtr, string, &first, 0, (Blt_VectorIndexProc **)NULL) != TCL_OK) { return TCL_ERROR; } if (first > vPtr->length) { Tcl_AppendResult(interp, "index \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } } } #define BUFFER_SIZE 1024 if (count == 0) { arraySize = BUFFER_SIZE * size; } else { arraySize = count * size; } byteArr = Blt_AssertMalloc(arraySize); /* FIXME: restore old channel translation later? */ if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") != TCL_OK) { return TCL_ERROR; } total = 0; while (!Tcl_Eof(channel)) { bytesRead = Tcl_Read(channel, byteArr, arraySize); if (bytesRead < 0) { Tcl_AppendResult(interp, "error reading channel: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } if ((bytesRead % size) != 0) { Tcl_AppendResult(interp, "error reading channel: short read", (char *)NULL); return TCL_ERROR; } length = bytesRead / size; if (CopyValues(vPtr, byteArr, fmt, size, length, swap, &first) != TCL_OK) { return TCL_ERROR; } total += length; if (count > 0) { break; } } Blt_Free(byteArr); if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); /* Set the result as the number of values read. */ Tcl_SetIntObj(Tcl_GetObjResult(interp), total); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SearchOp -- * * Searches for a value in the vector. Returns the indices of all vector * elements matching a particular value. * * Results: * Always returns TCL_OK. interp->result will contain a list of the * indices of array elements matching value. If no elements match, * interp->result will contain the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SearchOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { double min, max; int i; int wantValue; char *string; Tcl_Obj *listObjPtr; wantValue = FALSE; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-value") == 0)) { wantValue = TRUE; objv++, objc--; } if (Blt_ExprDoubleFromObj(interp, objv[2], &min) != TCL_OK) { return TCL_ERROR; } max = min; if (objc > 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", Tcl_GetString(objv[0]), " search ?-value? min ?max?", (char *)NULL); return TCL_ERROR; } if ((objc > 3) && (Blt_ExprDoubleFromObj(interp, objv[3], &max) != TCL_OK)) { return TCL_ERROR; } if ((min - max) >= DBL_EPSILON) { return TCL_OK; /* Bogus range. Don't bother looking. */ } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (wantValue) { for (i = 0; i < vPtr->length; i++) { if (InRange(vPtr->valueArr[i], min, max)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(vPtr->valueArr[i])); } } } else { for (i = 0; i < vPtr->length; i++) { if (InRange(vPtr->valueArr[i], min, max)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(i + vPtr->offset)); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * OffsetOp -- * * Queries or sets the offset of the array index from the base address of * the data array of values. * * Results: * A standard TCL result. If the source vector doesn't exist or the * source list is not a valid list of numbers, TCL_ERROR returned. * Otherwise TCL_OK is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OffsetOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { int newOffset; if (Tcl_GetIntFromObj(interp, objv[2], &newOffset) != TCL_OK) { return TCL_ERROR; } vPtr->offset = newOffset; } Tcl_SetIntObj(Tcl_GetObjResult(interp), vPtr->offset); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RandomOp -- * * Generates random values for the length of the vector. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RandomOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 0; i < vPtr->length; i++) { vPtr->valueArr[i] = drand48(); } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SeqOp -- * * Generates a sequence of values in the vector. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SeqOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int n; double start, stop; if (Blt_ExprDoubleFromObj(interp, objv[2], &start) != TCL_OK) { return TCL_ERROR; } if (Blt_ExprDoubleFromObj(interp, objv[3], &stop) != TCL_OK) { return TCL_ERROR; } n = vPtr->length; if ((objc > 4) && (Blt_ExprIntFromObj(interp, objv[4], &n) != TCL_OK)) { return TCL_ERROR; } if (n > 1) { int i; double step; if (Blt_Vec_SetLength(interp, vPtr, n) != TCL_OK) { return TCL_ERROR; } step = (stop - start) / (double)(n - 1); for (i = 0; i < n; i++) { vPtr->valueArr[i] = start + (step * i); } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetOp -- * * Sets the data of the vector object from a list of values. * * Results: * A standard TCL result. If the source vector doesn't exist or the * source list is not a valid list of numbers, TCL_ERROR returned. * Otherwise TCL_OK is returned. * * Side Effects: * The vector data is reset. Clients of the vector are notified. Any * cached array indices are flushed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SetOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Vector *v2Ptr; int nElem; Tcl_Obj **elemObjArr; /* The source can be either a list of numbers or another vector. */ v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, Tcl_GetString(objv[2]), NULL, NS_SEARCH_BOTH); if (v2Ptr != NULL) { if (vPtr == v2Ptr) { Vector *tmpPtr; /* * Source and destination vectors are the same. Copy the source * first into a temporary vector to avoid memory overlaps. */ tmpPtr = Blt_Vec_New(vPtr->dataPtr); result = Blt_Vec_Duplicate(tmpPtr, v2Ptr); if (result == TCL_OK) { result = Blt_Vec_Duplicate(vPtr, tmpPtr); } Blt_Vec_Free(tmpPtr); } else { result = Blt_Vec_Duplicate(vPtr, v2Ptr); } } else if (Tcl_ListObjGetElements(interp, objv[2], &nElem, &elemObjArr) == TCL_OK) { result = CopyList(vPtr, interp, nElem, elemObjArr); } else { return TCL_ERROR; } if (result == TCL_OK) { /* * The vector has changed; so flush the array indices (they're wrong * now), find the new range of the data, and notify the vector's * clients that it's been modified. */ if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } return result; } /* *--------------------------------------------------------------------------- * * SimplifyOp -- * * Sets the data of the vector object from a list of values. * * Results: * A standard TCL result. If the source vector doesn't exist or the * source list is not a valid list of numbers, TCL_ERROR returned. * Otherwise TCL_OK is returned. * * Side Effects: * The vector data is reset. Clients of the vector are notified. Any * cached array indices are flushed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SimplifyOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { size_t i, n; int length, nPoints; int *simple; double tolerance = 10.0; Point2d *orig, *reduced; length = vPtr->length; nPoints = vPtr->length / 2; simple = Blt_AssertMalloc(nPoints * sizeof(int)); reduced = Blt_AssertMalloc(nPoints * sizeof(Point2d)); orig = (Point2d *)vPtr->valueArr; n = Blt_SimplifyLine(orig, 0, nPoints - 1, tolerance, simple); for (i = 0; i < n; i++) { reduced[i] = orig[simple[i]]; } Blt_Free(simple); Blt_Vec_Reset(vPtr, (double *)reduced, n * 2, vPtr->length, TCL_DYNAMIC); /* * The vector has changed; so flush the array indices (they're wrong * now), find the new range of the data, and notify the vector's * clients that it's been modified. */ if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SplitOp -- * * Copies the values from the vector evenly into one of more vectors. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SplitOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int nVectors; nVectors = objc - 2; if ((vPtr->length % nVectors) != 0) { Tcl_AppendResult(interp, "can't split vector \"", vPtr->name, "\" into ", Blt_Itoa(nVectors), " even parts.", (char *)NULL); return TCL_ERROR; } if (nVectors > 0) { Vector *v2Ptr; char *string; /* Name of vector. */ int i, j, k; int oldSize, newSize, extra, isNew; extra = vPtr->length / nVectors; for (i = 0; i < nVectors; i++) { string = Tcl_GetString(objv[i+2]); v2Ptr = Blt_Vec_Create(vPtr->dataPtr, string, string, string, &isNew); oldSize = v2Ptr->length; newSize = oldSize + extra; if (Blt_Vec_SetLength(interp, v2Ptr, newSize) != TCL_OK) { return TCL_ERROR; } for (j = i, k = oldSize; j < vPtr->length; j += nVectors, k++) { v2Ptr->valueArr[k] = vPtr->valueArr[j]; } Blt_Vec_UpdateClients(v2Ptr); if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } } } return TCL_OK; } static Vector **sortVectors; /* Pointer to the array of values currently * being sorted. */ static int nSortVectors; static int sortDecreasing; /* Indicates the ordering of the sort. If * non-zero, the vectors are sorted in * decreasing order */ static int CompareVectors(void *a, void *b) { double delta; int i; int sign; Vector *vPtr; sign = (sortDecreasing) ? -1 : 1; for (i = 0; i < nSortVectors; i++) { vPtr = sortVectors[i]; delta = vPtr->valueArr[*(int *)a] - vPtr->valueArr[*(int *)b]; if (delta < 0.0) { return (-1 * sign); } else if (delta > 0.0) { return (1 * sign); } } return 0; } /* *--------------------------------------------------------------------------- * * Blt_Vec_SortMap -- * * Returns an array of indices that represents the sorted mapping of the * original vector. * * Results: * A standard TCL result. If any of the auxiliary vectors are a * different size than the sorted vector object, TCL_ERROR is returned. * Otherwise TCL_OK is returned. * * Side Effects: * The vectors are sorted. * * vecName sort ?switches? vecName vecName... *--------------------------------------------------------------------------- */ size_t * Blt_Vec_SortMap(Vector **vectors, int nVectors) { size_t *map; int i; Vector *vPtr = *vectors; int length; length = vPtr->last - vPtr->first + 1; map = Blt_AssertMalloc(sizeof(size_t) * length); for (i = vPtr->first; i <= vPtr->last; i++) { map[i] = i; } /* Set global variables for sorting routine. */ sortVectors = vectors; nSortVectors = nVectors; qsort((char *)map, length, sizeof(size_t), (QSortCompareProc *)CompareVectors); return map; } static size_t * SortVectors(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Vector **vectors, *v2Ptr; size_t *map; int i; vectors = Blt_AssertMalloc(sizeof(Vector *) * (objc + 1)); vectors[0] = vPtr; map = NULL; for (i = 0; i < objc; i++) { if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), &v2Ptr) != TCL_OK) { goto error; } if (v2Ptr->length != vPtr->length) { Tcl_AppendResult(interp, "vector \"", v2Ptr->name, "\" is not the same size as \"", vPtr->name, "\"", (char *)NULL); goto error; } vectors[i + 1] = v2Ptr; } map = Blt_Vec_SortMap(vectors, objc + 1); error: Blt_Free(vectors); return map; } /* *--------------------------------------------------------------------------- * * SortOp -- * * Sorts the vector object and any other vectors according to sorting * order of the vector object. * * Results: * A standard TCL result. If any of the auxiliary vectors are a * different size than the sorted vector object, TCL_ERROR is returned. * Otherwise TCL_OK is returned. * * Side Effects: * The vectors are sorted. * * vecName sort ?switches? vecName vecName... *--------------------------------------------------------------------------- */ static int SortOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Vector *v2Ptr; double *copy; size_t *map; size_t sortLength, nBytes; int result; int i; unsigned int n; SortSwitches switches; sortDecreasing = FALSE; switches.flags = 0; i = Blt_ParseSwitches(interp, sortSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { return TCL_ERROR; } objc -= i, objv += i; sortDecreasing = (switches.flags & SORT_DECREASING); if (objc > 2) { map = SortVectors(vPtr, interp, objc - 2, objv + 2); } else { map = Blt_Vec_SortMap(&vPtr, 1); } if (map == NULL) { return TCL_ERROR; } sortLength = vPtr->length; /* * Create an array to store a copy of the current values of the * vector. We'll merge the values back into the vector based upon the * indices found in the index array. */ nBytes = sizeof(double) * sortLength; copy = Blt_AssertMalloc(nBytes); memcpy((char *)copy, (char *)vPtr->valueArr, nBytes); if (switches.flags & SORT_UNIQUE) { int count; for (count = n = 1; n < sortLength; n++) { size_t next, prev; next = map[n]; prev = map[n - 1]; if (copy[next] != copy[prev]) { map[count] = next; count++; } } sortLength = count; nBytes = sortLength * sizeof(double); } if (sortLength != vPtr->length) { Blt_Vec_SetLength(interp, vPtr, sortLength); } for (n = 0; n < sortLength; n++) { vPtr->valueArr[n] = copy[map[n]]; } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); /* Now sort any other vectors in the same fashion. The vectors must be * the same size as the map though. */ result = TCL_ERROR; for (i = 2; i < objc; i++) { if (Blt_Vec_LookupName(vPtr->dataPtr, Tcl_GetString(objv[i]), &v2Ptr) != TCL_OK) { goto error; } if (sortLength != v2Ptr->length) { Blt_Vec_SetLength(interp, v2Ptr, sortLength); } memcpy((char *)copy, (char *)v2Ptr->valueArr, nBytes); for (n = 0; n < sortLength; n++) { v2Ptr->valueArr[n] = copy[map[n]]; } Blt_Vec_UpdateClients(v2Ptr); if (v2Ptr->flush) { Blt_Vec_FlushCache(v2Ptr); } } result = TCL_OK; error: Blt_Free(copy); Blt_Free(map); return result; } /* *--------------------------------------------------------------------------- * * InstExprOp -- * * Computes the result of the expression which may be either a scalar * (single value) or vector (list of values). * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InstExprOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (Blt_ExprVector(interp, Tcl_GetString(objv[2]), (Blt_Vector *)vPtr) != TCL_OK) { return TCL_ERROR; } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ArithOp -- * * Results: * A standard TCL result. If the source vector doesn't exist or the * source list is not a valid list of numbers, TCL_ERROR returned. * Otherwise TCL_OK is returned. * * Side Effects: * The vector data is reset. Clients of the vector are notified. * Any cached array indices are flushed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ArithOp(Vector *vPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { double value; int i; Vector *v2Ptr; double scalar; Tcl_Obj *listObjPtr; char *string; v2Ptr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, vPtr->dataPtr, Tcl_GetString(objv[2]), NULL, NS_SEARCH_BOTH); if (v2Ptr != NULL) { int j; int length; length = v2Ptr->last - v2Ptr->first + 1; if (length != vPtr->length) { Tcl_AppendResult(interp, "vectors \"", Tcl_GetString(objv[0]), "\" and \"", Tcl_GetString(objv[2]), "\" are not the same length", (char *)NULL); return TCL_ERROR; } string = Tcl_GetString(objv[1]); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); switch (string[0]) { case '*': for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) { value = vPtr->valueArr[i] * v2Ptr->valueArr[j]; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '/': for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) { value = vPtr->valueArr[i] / v2Ptr->valueArr[j]; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '-': for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) { value = vPtr->valueArr[i] - v2Ptr->valueArr[j]; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '+': for (i = 0, j = v2Ptr->first; i < vPtr->length; i++, j++) { value = vPtr->valueArr[i] + v2Ptr->valueArr[j]; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; } Tcl_SetObjResult(interp, listObjPtr); } else if (Blt_ExprDoubleFromObj(interp, objv[2], &scalar) == TCL_OK) { listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); string = Tcl_GetString(objv[1]); switch (string[0]) { case '*': for (i = 0; i < vPtr->length; i++) { value = vPtr->valueArr[i] * scalar; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '/': for (i = 0; i < vPtr->length; i++) { value = vPtr->valueArr[i] / scalar; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '-': for (i = 0; i < vPtr->length; i++) { value = vPtr->valueArr[i] - scalar; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; case '+': for (i = 0; i < vPtr->length; i++) { value = vPtr->valueArr[i] + scalar; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(value)); } break; } Tcl_SetObjResult(interp, listObjPtr); } else { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * VectorInstCmd -- * * Parses and invokes the appropriate vector instance command option. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec vectorInstOps[] = { {"*", 1, ArithOp, 3, 3, "item",}, /*Deprecated*/ {"+", 1, ArithOp, 3, 3, "item",}, /*Deprecated*/ {"-", 1, ArithOp, 3, 3, "item",}, /*Deprecated*/ {"/", 1, ArithOp, 3, 3, "item",}, /*Deprecated*/ {"append", 1, AppendOp, 3, 0, "item ?item...?",}, {"binread", 1, BinreadOp, 3, 0, "channel ?numValues? ?flags?",}, {"clear", 1, ClearOp, 2, 2, "",}, {"delete", 2, DeleteOp, 2, 0, "index ?index...?",}, {"dup", 2, DupOp, 3, 0, "vecName",}, {"expr", 1, InstExprOp, 3, 3, "expression",}, {"fft", 1, FFTOp, 3, 0, "vecName ?switches?",}, {"index", 3, IndexOp, 3, 4, "index ?value?",}, {"inversefft",3, InverseFFTOp,4, 4, "vecName vecName",}, {"length", 1, LengthOp, 2, 3, "?newSize?",}, {"max", 2, MaxOp, 2, 2, "",}, {"merge", 2, MergeOp, 3, 0, "vecName ?vecName...?",}, {"min", 2, MinOp, 2, 2, "",}, {"normalize", 3, NormalizeOp, 2, 3, "?vecName?",}, /*Deprecated*/ {"notify", 3, NotifyOp, 3, 3, "keyword",}, {"offset", 1, OffsetOp, 2, 3, "?offset?",}, {"populate", 1, PopulateOp, 4, 4, "vecName density",}, {"random", 4, RandomOp, 2, 2, "",}, /*Deprecated*/ {"range", 4, RangeOp, 2, 4, "first last",}, {"search", 3, SearchOp, 3, 5, "?-value? value ?value?",}, {"seq", 3, SeqOp, 4, 5, "begin end ?num?",}, {"set", 3, SetOp, 3, 3, "list",}, {"simplify", 2, SimplifyOp, 2, 2, }, {"sort", 2, SortOp, 2, 0, "?switches? ?vecName...?",}, {"split", 2, SplitOp, 2, 0, "?vecName...?",}, {"values", 3, ValuesOp, 2, 0, "?switches?",}, {"variable", 3, MapOp, 2, 3, "?varName?",}, }; static int nInstOps = sizeof(vectorInstOps) / sizeof(Blt_OpSpec); int Blt_Vec_InstCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { VectorCmdProc *proc; Vector *vPtr = clientData; vPtr->first = 0; vPtr->last = vPtr->length - 1; proc = Blt_GetOpFromObj(interp, nInstOps, vectorInstOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (vPtr, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * Blt_Vec_VarTrace -- * * Results: * Returns NULL on success. Only called from a variable trace. * * Side effects: * *--------------------------------------------------------------------------- */ char * Blt_Vec_VarTrace(ClientData clientData, Tcl_Interp *interp, const char *part1, const char *part2, int flags) { Blt_VectorIndexProc *indexProc; Vector *vPtr = clientData; int first, last; int varFlags; #define MAX_ERR_MSG 1023 static char message[MAX_ERR_MSG + 1]; if (part2 == NULL) { if (flags & TCL_TRACE_UNSETS) { Blt_Free(vPtr->arrayName); vPtr->arrayName = NULL; if (vPtr->freeOnUnset) { Blt_Vec_Free(vPtr); } } return NULL; } if (Blt_Vec_GetIndexRange(interp, vPtr, part2, INDEX_ALL_FLAGS, &indexProc) != TCL_OK) { goto error; } first = vPtr->first, last = vPtr->last; varFlags = TCL_LEAVE_ERR_MSG | (TCL_GLOBAL_ONLY & flags); if (flags & TCL_TRACE_WRITES) { double value; Tcl_Obj *objPtr; if (first == SPECIAL_INDEX) { /* Tried to set "min" or "max" */ return (char *)"read-only index"; } objPtr = Tcl_GetVar2Ex(interp, part1, part2, varFlags); if (objPtr == NULL) { goto error; } if (Blt_ExprDoubleFromObj(interp, objPtr, &value) != TCL_OK) { if ((last == first) && (first >= 0)) { /* Single numeric index. Reset the array element to * its old value on errors */ Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags); } goto error; } if (first == vPtr->length) { if (Blt_Vec_ChangeLength((Tcl_Interp *)NULL, vPtr, vPtr->length + 1) != TCL_OK) { return (char *)"error resizing vector"; } } /* Set possibly an entire range of values */ ReplicateValue(vPtr, first, last, value); } else if (flags & TCL_TRACE_READS) { double value; Tcl_Obj *objPtr; if (vPtr->length == 0) { if (Tcl_SetVar2(interp, part1, part2, "", varFlags) == NULL) { goto error; } return NULL; } if (first == vPtr->length) { return (char *)"write-only index"; } if (first == last) { if (first >= 0) { value = vPtr->valueArr[first]; } else { vPtr->first = 0, vPtr->last = vPtr->length - 1; value = (*indexProc) ((Blt_Vector *) vPtr); } objPtr = Tcl_NewDoubleObj(value); if (Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags) == NULL) { Tcl_DecrRefCount(objPtr); goto error; } } else { objPtr = GetValues(vPtr, first, last); if (Tcl_SetVar2Ex(interp, part1, part2, objPtr, varFlags) == NULL) { Tcl_DecrRefCount(objPtr); goto error; } } } else if (flags & TCL_TRACE_UNSETS) { int i, j; if ((first == vPtr->length) || (first == SPECIAL_INDEX)) { return (char *)"special vector index"; } /* * Collapse the vector from the point of the first unset element. * Also flush any array variable entries so that the shift is * reflected when the array variable is read. */ for (i = first, j = last + 1; j < vPtr->length; i++, j++) { vPtr->valueArr[i] = vPtr->valueArr[j]; } vPtr->length -= ((last - first) + 1); if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } } else { return (char *)"unknown variable trace flag"; } if (flags & (TCL_TRACE_UNSETS | TCL_TRACE_WRITES)) { Blt_Vec_UpdateClients(vPtr); } Tcl_ResetResult(interp); return NULL; error: strncpy(message, Tcl_GetStringResult(interp), MAX_ERR_MSG); message[MAX_ERR_MSG] = '\0'; return message; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPicture.h������������������������������������������������������������������0000644�0001750�0001750�00000034432�11462120062�015321� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPicture.h -- * * Copyright 2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_PICTURE_H #define _BLT_PICTURE_H #include <bltHash.h> /* *--------------------------------------------------------------------------- * * Blt_Pixel -- * * A union representing either a pixel as a RGBA quartet or a single * word value. * *--------------------------------------------------------------------------- */ typedef union { unsigned int u32; struct { #ifdef WORDS_BIGENDIAN unsigned char a, r, g, b; #else unsigned char b, g, r, a; #endif } u8; } Blt_Pixel; #define Red u8.r #define Blue u8.b #define Green u8.g #define Alpha u8.a #define ALPHA_OPAQUE (0xFF) #define ALPHA_TRANSPARENT (0) #define MAXINTENSITY (0xFF) #define GAMMA (1.0f) struct _Blt_Ps; /* *--------------------------------------------------------------------------- * * Blt_Picture -- * * The structure below represents a picture. Each pixel occupies a * 32-bit word of memory: one byte for each of the red, green, and blue * color intensities, and another for alpha-channel image compositing * (e.g. transparency). * *--------------------------------------------------------------------------- */ struct _Blt_Picture { void *buffer; /* Unaligned (malloc'ed) memory for pixels. */ Blt_Pixel *bits; /* Array of pixels containing the RGBA * values. */ short int delay; short int flags; /* Flags describing the picture. */ short int width, height; /* Dimensions of the image in pixels. */ short int pixelsPerRow; /* Stride of the image. */ short int reserved; }; #define BLT_PIC_COLOR (1<<0) /* Indicates if color or greyscale. */ #define BLT_PIC_BLEND (1<<1) /* Picture has partial opaque pixels. */ #define BLT_PIC_MASK (1<<2) /* Pixels are either 100% opaque or * transparent. The separate BLEND and MASK * flags are so that don't premultiply alphas * for masks. */ #define BLT_PIC_ASSOCIATED_COLORS (1<<3) /* Indicates if RGB components have been * premultiplied by their alphas. */ #define BLT_PIC_DIRTY (1<<4) /* Indicates that the picture contents have * changed. Cached items may need to be * refreshed. For example, may need to * premultiply alphas again. */ #define BLT_PIC_FMT_ASCII (1<<0) #define BLT_PIC_FMT_LOADED (1<<1) #define BLT_PAINTER_DITHER (1<<0) #define BLT_PAINTER_BLEND_MASK (0x0F) #define BLT_PAINTER_BLEND_NONE (0) #define BLT_PAINTER_BLEND_MIN_ALPHAS (1<<1) #define BLT_PAINTER_BLEND_MAX_ALPHAS (1<<2) #define BLT_PAINTER_BLEND_DIFF (1<<3) #define BLT_PAINTER_BLEND_MULTIPLY (1<<4) #define BLT_PAINTER_BLEND_UNDER (1<<6) typedef enum GradientShapes { BLT_GRADIENT_SHAPE_LINEAR, BLT_GRADIENT_SHAPE_BILINEAR, BLT_GRADIENT_SHAPE_RADIAL, BLT_GRADIENT_SHAPE_RECTANGULAR } Blt_GradientShape; typedef enum GradientPaths { BLT_GRADIENT_PATH_X, BLT_GRADIENT_PATH_Y, BLT_GRADIENT_PATH_XY, BLT_GRADIENT_PATH_YX, } Blt_GradientPath; typedef struct { Blt_GradientShape shape; /* Determines the shape of gradient. */ Blt_GradientPath path; /* Determines the direction of a linear or * bilinear gradient. */ int logScale; /* If non-zero, use a logarithmic scale to * ramp colors. */ int jitter; /* If non-zero, add jitter error to * gradient. */ } Blt_Gradient; typedef struct _Blt_PictureImage *Blt_PictureImage; typedef struct _Blt_ResampleFilter *Blt_ResampleFilter; typedef struct _Blt_ConvolveFilter *Blt_ConvolveFilter; typedef struct _Blt_Picture *Blt_Picture; struct _Blt_Chain; /* * Blt_Picture is supposed to be an opaque type. Use the macros below to * access its members. */ #define Blt_PictureBits(p) ((p)->bits) #define Blt_PictureFlags(p) ((p)->flags) #define Blt_PictureHeight(p) ((p)->height) #define Blt_PicturePixel(p,x,y) ((p)->bits + ((p)->pixelsPerRow * (y)) + (x)) #define Blt_PictureWidth(p) ((p)->width) #define Blt_PictureStride(p) ((p)->pixelsPerRow) #define Blt_PictureDelay(p) ((p)->delay) #define Blt_PictureIsDirty(p) ((p)->flags & BLT_PIC_DIRTY) #define Blt_PictureIsOpaque(p) \ (((p)->flags & (BLT_PIC_BLEND | BLT_PIC_MASK)) == 0) #define Blt_PictureIsMasked(p) ((p)->flags & BLT_PIC_MASK) #define Blt_PictureIsBlended(p) ((p)->flags & BLT_PIC_BLEND) #define Blt_PictureIsColor(p) ((p)->flags & BLT_PIC_COLOR) #define Blt_PictureIsGreyscale(p) (!Blt_IsColorPicture(p)) typedef enum PictureArithOps { PIC_ARITH_ADD, PIC_ARITH_AND, PIC_ARITH_NAND, PIC_ARITH_NOR, PIC_ARITH_OR, PIC_ARITH_RSUB, PIC_ARITH_SUB, PIC_ARITH_XOR, PIC_ARITH_MIN, PIC_ARITH_MAX, } Blt_PictureArithOps; typedef struct { unsigned int x, y; } PictureCoordinate; typedef enum BlendingModes { BLT_BLEND_NORMAL, /* C = F */ BLT_BLEND_MULTIPLY, /* C = F * B */ BLT_BLEND_SCREEN, /* C = 1 - (1 - F * B */ BLT_BLEND_DARKEN, /* C = min(F,B) */ BLT_BLEND_LIGHTEN, /* C = max(F,B) */ BLT_BLEND_DIFFERENCE, /* C = |F - B| */ BLT_BLEND_HARDLIGHT, BLT_BLEND_SOFTLIGHT, BLT_BLEND_COLORDODGE, /* C = B / (1 - F) */ BLT_BLEND_COLORBURN, /* C = (1 - B) / F */ BLT_BLEND_OVERLAY, /* C = B * (F + (2 * F) * (1 - B)) */ } Blt_BlendingMode; BLT_EXTERN Blt_ResampleFilter bltBoxFilter; /* The ubiquitous box filter */ BLT_EXTERN Blt_ResampleFilter bltMitchellFilter; BLT_EXTERN Blt_ResampleFilter bltBellFilter; BLT_EXTERN Blt_ResampleFilter bltTentFilter; BLT_EXTERN Blt_ResampleFilter bltTableFilter; typedef struct { int x, y, w, h; } PictRegion; #define Blt_AddPictures(dest, src) \ Blt_ApplyPictureToPicture(dest, src, 0, 0, (src)->width, (src)->height, \ 0, 0, PIC_ARITH_ADD) #define Blt_SubtractPictures(dest, src) \ Blt_ApplyPictureToPicture(dest, src, 0, 0, (src)->width, (src)->height, \ 0, 0, PIC_ARITH_SUB) #define Blt_AndPictures(dest, src) \ Blt_ApplyPictureToPicture(dest, src, 0, 0, (src)->width, (src)->height, \ 0, 0, PIC_ARITH_AND) #define Blt_OrPictures(dest, src) \ Blt_ApplyPictureToPicture(dest, src, 0, 0, (src)->width, (src)->height, \ 0, 0, PIC_ARITH_OR) #define Blt_XorPictures(dest, src) \ Blt_ApplyPictureToPicture(dest, src, 0, 0, (src)->width, (src)->height, \ 0, 0, PIC_ARITH_XOR) typedef unsigned int (*Blt_ColorLookupTable)[33][33]; /* Prototypes of picture routines */ BLT_EXTERN void Blt_ApplyPictureToPicture(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy, Blt_PictureArithOps op); BLT_EXTERN void Blt_ApplyScalarToPicture(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_PictureArithOps op); BLT_EXTERN void Blt_ApplyPictureToPictureWithMask(Blt_Picture dest, Blt_Picture src, Blt_Picture mask, int x, int y, int w, int h, int dx, int dy, int invert, Blt_PictureArithOps op); BLT_EXTERN void Blt_ApplyScalarToPictureWithMask(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_Picture mask, int invert, Blt_PictureArithOps op); BLT_EXTERN void Blt_MaskPicture(Blt_Picture dest, Blt_Picture mask, int x, int y, int w, int h, int dx, int dy, Blt_Pixel *colorPtr); BLT_EXTERN void Blt_BlankPicture(Blt_Picture picture, Blt_Pixel *colorPtr); BLT_EXTERN void Blt_BlankRegion(Blt_Picture picture, int x, int y, int w, int h, Blt_Pixel *colorPtr); BLT_EXTERN void Blt_BlurPicture(Blt_Picture dest, Blt_Picture src, unsigned int r); BLT_EXTERN void Blt_ResizePicture(Blt_Picture picture, int w, int h); BLT_EXTERN void Blt_AdjustPicture(Blt_Picture picture, int w, int h); BLT_EXTERN Blt_Picture Blt_ClonePicture(Blt_Picture picture); BLT_EXTERN void Blt_ConvolvePicture(Blt_Picture dest, Blt_Picture src, Blt_ConvolveFilter vFilter, Blt_ConvolveFilter hFilter); BLT_EXTERN Blt_Picture Blt_CreatePicture(int w, int h); BLT_EXTERN Blt_Picture Blt_DitherPicture(Blt_Picture picture, Blt_Pixel *palette); BLT_EXTERN void Blt_FlipPicture(Blt_Picture picture, int vertically); BLT_EXTERN void Blt_FreePicture(Blt_Picture picture); BLT_EXTERN void Blt_GradientPicture(Blt_Picture picture, Blt_Pixel *highPtr, Blt_Pixel *lowPtr, Blt_Gradient *gradientPtr); BLT_EXTERN Blt_Picture Blt_GreyscalePicture(Blt_Picture picture); BLT_EXTERN Blt_Picture Blt_QuantizePicture (Blt_Picture picture, int nColors); BLT_EXTERN void Blt_ResamplePicture (Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter hFilter, Blt_ResampleFilter vFilter); BLT_EXTERN Blt_Picture Blt_ScalePicture(Blt_Picture picture, int x, int y, int w, int h, int dw, int dh); BLT_EXTERN Blt_Picture Blt_ScalePictureArea(Blt_Picture picture, int x, int y, int w, int h, int dw, int dh); BLT_EXTERN Blt_Picture Blt_RotatePicture (Blt_Picture picture, float angle); BLT_EXTERN void Blt_TilePicture(Blt_Picture dest, Blt_Picture src, int xOrigin, int yOrigin, int x, int y, int w, int h); BLT_EXTERN int Blt_PictureToPsData(Blt_Picture picture, int nComponents, Tcl_DString *resultPtr, const char *prefix); BLT_EXTERN void Blt_SelectPixels(Blt_Picture dest, Blt_Picture src, Blt_Pixel *lowerPtr, Blt_Pixel *upperPtr); BLT_EXTERN int Blt_GetPicture(Tcl_Interp *interp, const char *string, Blt_Picture *picturePtr); BLT_EXTERN int Blt_GetPictureFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Picture *picturePtr); BLT_EXTERN int Blt_GetResampleFilterFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_ResampleFilter *filterPtr); BLT_EXTERN const char *Blt_NameOfResampleFilter(Blt_ResampleFilter filter); BLT_EXTERN void Blt_AssociateColors(Blt_Picture picture); BLT_EXTERN void Blt_UnassociateColors(Blt_Picture picture); BLT_EXTERN void Blt_MultiplyPixels(Blt_Picture picture, float value); BLT_EXTERN int Blt_GetBBoxFromObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, PictRegion *regionPtr); BLT_EXTERN int Blt_AdjustRegionToPicture(Blt_Picture picture, PictRegion *regionPtr); BLT_EXTERN int Blt_GetPixelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Pixel *pixelPtr); BLT_EXTERN int Blt_GetPixel(Tcl_Interp *interp, const char *string, Blt_Pixel *pixelPtr); BLT_EXTERN const char *Blt_NameOfPixel(Blt_Pixel *pixelPtr); BLT_EXTERN Blt_Picture Blt_PictureFromPictImage(Blt_PictureImage image); BLT_EXTERN void Blt_NotifyImageChanged(Blt_PictureImage image); BLT_EXTERN int Blt_QueryColors(Blt_Picture picture, Blt_HashTable *tablePtr); BLT_EXTERN void Blt_ClassifyPicture(Blt_Picture picture); BLT_EXTERN void Blt_TentHorizontally(Blt_Picture dest, Blt_Picture src); BLT_EXTERN void Blt_TentVertically(Blt_Picture dest, Blt_Picture src); BLT_EXTERN void Blt_ZoomHorizontally(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter); BLT_EXTERN void Blt_ZoomVertically(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter); BLT_EXTERN void Blt_BlendPictures(Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy); BLT_EXTERN void Blt_BlendPicturesByMode(Blt_Picture dest, Blt_Picture src, Blt_BlendingMode mode); BLT_EXTERN void Blt_SelectPixelsP(Blt_Picture dest, Blt_Picture src, Blt_Pixel *lowPtr , Blt_Pixel *highPtr); BLT_EXTERN void Blt_FadePicture(Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy, int alpha); BLT_EXTERN void Blt_CopyPictureBits(Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy); BLT_EXTERN void Blt_GammaCorrectPicture(Blt_Picture dest, Blt_Picture src, float gamma); BLT_EXTERN void Blt_SharpenPicture(Blt_Picture dest, Blt_Picture src); BLT_EXTERN void Blt_TexturePicture(Blt_Picture picture, Blt_Pixel *lowPtr, Blt_Pixel *highPtr, int type); BLT_EXTERN void Blt_ApplyColorToPicture(Blt_Picture pict, Blt_Pixel *colorPtr); BLT_EXTERN void Blt_SizeOfPicture(Blt_Picture pict, int *wPtr, int *hPtr); #ifdef _BLT_DBUFFER_H BLT_EXTERN Blt_DBuffer Blt_PictureToDBuffer(Blt_Picture picture, int nComp); #endif /* _BLT_DBUFFER_H */ BLT_EXTERN int Blt_ResetPicture(Tcl_Interp *interp, const char *imageName, Blt_Picture picture); BLT_EXTERN void Blt_MapColors(Blt_Picture dest, Blt_Picture src, Blt_ColorLookupTable clut); BLT_EXTERN Blt_ColorLookupTable Blt_GetColorLookupTable(struct _Blt_Chain *chain, int nReqColors); #ifdef _TK BLT_EXTERN Blt_Picture Blt_PhotoToPicture (Tk_PhotoHandle photo); BLT_EXTERN Blt_Picture Blt_PhotoAreaToPicture (Tk_PhotoHandle photo, int x, int y, int w, int h); BLT_EXTERN Blt_Picture Blt_DrawableToPicture(Tk_Window tkwin, Drawable drawable, int x, int y, int w, int h, float gamma); BLT_EXTERN Blt_Picture Blt_WindowToPicture(Display *display, Drawable drawable, int x, int y, int w, int h, float gamma); BLT_EXTERN void Blt_PictureToPhoto(Blt_Picture picture, Tk_PhotoHandle photo); BLT_EXTERN int Blt_SnapPhoto(Tcl_Interp *interp, Tk_Window tkwin, Drawable drawable, int sx, int sy, int w, int h, int dw, int dh, const char *photoName, float gamma); BLT_EXTERN int Blt_SnapPicture(Tcl_Interp *interp, Tk_Window tkwin, Drawable drawable, int sx, int sy, int w, int h, int dw, int dh, const char *imageName, float gamma); BLT_EXTERN Blt_Picture Blt_BitmapToPicture(Display *display, Pixmap bitmap, int w, int h, Blt_Pixel *fg, Blt_Pixel *bg); BLT_EXTERN Blt_Pixel Blt_XColorToPixel(XColor *colorPtr); BLT_EXTERN int Blt_IsPicture(Tk_Image tkImage); BLT_EXTERN Blt_Picture Blt_GetPictureFromImage(Tcl_Interp *interp, Tk_Image tkImage, int *isPhotoPtr); BLT_EXTERN Blt_Picture Blt_GetPictureFromPictureImage(Tcl_Interp *interp, Tk_Image tkImage); BLT_EXTERN Blt_Picture Blt_GetPictureFromPhotoImage(Tcl_Interp *interp, Tk_Image tkImage); #endif /* _TK */ #endif /*_BLT_PICTURE_H*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinPainter.h���������������������������������������������������������������0000644�0001750�0001750�00000006653�11462120063�015773� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinPainter.h -- * * This header contains the private definitions for a painter in * the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the * Tk library distrubution. The photo image type was designed and * implemented by Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #ifndef _BLT_WIN_PAINTER_H #define _BLT_WIN_PAINTER_H #ifdef notdef #define PAINTER_COLOR_WINDOW (1<<0) #define PAINTER_BW (1<<1) #define PAINTER_MAP_COLORS (1<<2) #endif /* * Painter -- * * This structure represents a painter used to display picture images. A * painter is specified by a combination of display, colormap, depth, and * monitor gamma value. Painters contain information necessary to display a * picture. This includes both an RGB to pixel map, and a RGB to allocated * color map. * * Painters may be shared by more than one client and are reference counted. * When no clients are using the painter, it is freed. */ struct _Blt_Painter { Display *display; /* Display of painter. Used to free colors * allocated. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value of monitor. */ Colormap colormap; unsigned int flags; /* Flags listed below. */ int refCount; /* # of clients using this painter. If zero, * # the painter is freed. */ Blt_HashEntry *hashPtr; /* Used to delete the painter entry from the * hash table of painters. */ GC gc; /* GC used to draw the image. */ unsigned char gammaTable[256]; /* Input gamma lookup table. Used to map * non-linear monitor values back to RGB * values. This is used whenever we take a * snapshot of the screen (e.g. alpha * blending). Computes the power mapping. D * = I^gamma. */ unsigned char igammaTable[256]; /* Output gamma lookup table. Used to map * RGB values to non-linear monitor * values. Computes the inverse power mapping. * I~ = D^1/gamma. */ Blt_Pixel palette[256]; /* Maps the picture's 8-bit RGB values to the * RGB values of the colors actually * allocated. This is used for dithering the * picture. */ }; typedef struct _Blt_Painter Painter; #endif /* _BLT_WIN_PAINTER_H */ �������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictXpm.c������������������������������������������������������������������0000644�0001750�0001750�00000043153�11462120062�015265� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictXpm.c -- * * This module implements XPM file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #ifdef HAVE_LIBXPM #include <tcl.h> #include <bltAlloc.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include "bltPicture.h" #include "bltPictFmts.h" #include <ctype.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifndef HAVE_SPRINTF_S BLT_EXTERN int sprintf_s(char *s, size_t size, const char *fmt, /*args*/ ...); #endif /* HAVE_SPRINTF_S */ #define TRUE 1 #define FALSE 0 typedef struct _Blt_Picture Picture; #include <X11/xpm.h> typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int flags; /* Flag. */ Blt_Pixel bg; int index; } XpmExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; } XpmImportSwitches; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(XpmExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(XpmExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(XpmExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_BITMASK, "-noquantize", "", Blt_Offset(XpmExportSwitches, flags), 0, PIC_NOQUANTIZE}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(XpmExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(XpmImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(XpmImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_PictureXpmInit; extern char *Blt_Itoa(int); static int XpmHeader(Blt_DBuffer buffer) { unsigned char *line, *next; unsigned char *bp; Blt_DBuffer_ResetCursor(buffer); bp = Blt_DBuffer_End(buffer); bp[0] = '\0'; /* Guaranteed to have 1 extra byte in the * buffer to create an ASCIZ string. */ for (line = Blt_DBuffer_Pointer(buffer); *line != '\0'; line = next) { #define XPM_MAX_LINE 4097 char substring[XPM_MAX_LINE+1]; int value; char *s; /* Find the start of the next line */ if ((*line == '\n') || (*line == '\r')) { line++; } next = line; while ((*next != '\r') && (*next != '\n') && (*next != '\0')) { if (!isascii(*next)) { return FALSE; } next++; } /* Verify that we won't overrun the buffer with "sscanf". */ if ((next - line) > XPM_MAX_LINE) { return FALSE; } s = (char *)line; if (sscanf(s, "#define %s %d", substring, &value) == 2) { char *p; char c; char *name; p = strrchr(substring, '_'); if (p == NULL) { name = substring; } else { name = p + 1; } c = name[0]; if ((c == 'f') && (strcmp("format", name) == 0)) { return TRUE; } else { return FALSE; } } else if (sscanf(s, "/* %s */", substring) == 1) { if ((strcmp("XPM", substring) == 0) || (strcmp("XPM2", substring) == 0)) { return TRUE; } } } return FALSE; } /* *--------------------------------------------------------------------------- * * IsXpm -- * * Attempts to parse an XBM file header. * * Results: * Returns 1 is the header is XBM and 0 otherwise. Note that * the validity of the header values is not checked here. That's * done in XpmToPicture. * *--------------------------------------------------------------------------- */ static int IsXpm(Blt_DBuffer buffer) { int bool; bool = XpmHeader(buffer); return bool; } /* *--------------------------------------------------------------------------- * * XpmToPicture -- * * Reads an XBM file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain XpmToPicture( Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer, XpmImportSwitches *switchesPtr) { Picture *destPtr; Blt_Pixel *palette; XpmImage xpm; int i, result; int maskColorIndex; Blt_DBuffer_ResetCursor(buffer); result = XpmCreateXpmImageFromBuffer((char *)Blt_DBuffer_Bytes(buffer), &xpm, (XpmInfo *)NULL); if (result != XpmSuccess) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" can't read XPM image. ", (char *)NULL); return NULL; } destPtr = NULL; palette = NULL; if ((xpm.height < 1) || (xpm.width < 1)) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" invalid XPM dimensions \"", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(xpm.width), " x ", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(xpm.height), "\"", (char *)NULL); goto bad; } if (xpm.colorTable == NULL) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" no XPM color table available. ", (char *)NULL); goto bad; } destPtr = Blt_CreatePicture(xpm.width, xpm.height); palette = Blt_Malloc(xpm.ncolors * sizeof(Blt_Pixel)); if (palette == NULL) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" can't allocate a ", Blt_Itoa(xpm.ncolors), " color XPM palette.", (char *)NULL); goto bad; } maskColorIndex = -1; for (i = 0; i < xpm.ncolors; i++) { char *colorName; if (xpm.colorTable[i].c_color) { colorName = xpm.colorTable[i].c_color; } else if (xpm.colorTable[i].g_color) { colorName = xpm.colorTable[i].g_color; } else if (xpm.colorTable[i].g4_color) { colorName = xpm.colorTable[i].g4_color; } else if (xpm.colorTable[i].m_color) { colorName = xpm.colorTable[i].m_color; } else if (xpm.colorTable[i].symbolic) { colorName = xpm.colorTable[i].symbolic; } else { palette[i].u32 = 0xFFBEBEBE; continue; } if (strncmp(colorName, "None", 4) == 0) { maskColorIndex = i; palette[i].u32 = 0x00000000; continue; } if (Blt_GetPixel(interp, colorName, palette + i) != TCL_OK) { palette[i].u32 = 0xFFBEBEBE; } } { int y; unsigned int *pixelPtr; /* Pointer */ Blt_Pixel *destRowPtr; destRowPtr = destPtr->bits; pixelPtr = (unsigned int *)xpm.data; for (y = 0; y < xpm.height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + xpm.width; dp < dend; dp++) { if (*pixelPtr >= xpm.ncolors) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" bad color index ", Blt_Itoa(*pixelPtr), " in XPM image.", (char *)NULL); goto bad; } if (*pixelPtr == maskColorIndex) { destPtr->flags |= BLT_PIC_MASK; } *dp = palette[*pixelPtr]; pixelPtr++; } destRowPtr += destPtr->pixelsPerRow; } } Blt_Free(palette); XpmFreeXpmImage(&xpm); if (destPtr != NULL) { Blt_Chain chain; chain = Blt_Chain_Create(); Blt_Chain_Append(chain, destPtr); return chain; } bad: if (destPtr != NULL) { Blt_FreePicture(destPtr); } if (palette != NULL) { Blt_Free(palette); } XpmFreeXpmImage(&xpm); return NULL; } /* *--------------------------------------------------------------------------- * * PictureToXpm -- * * Reads an XBM file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static int PictureToXpm(Tcl_Interp *interp, Blt_Picture original, Blt_DBuffer buffer, XpmExportSwitches *switchesPtr) { Picture *srcPtr; int nColors; Blt_HashTable colorTable; char fmt[20]; int quantize; Blt_Pixel *bgColorPtr; quantize = ((switchesPtr->flags & PIC_NOQUANTIZE) == 0); bgColorPtr = &switchesPtr->bg; srcPtr = original; if (Blt_PictureIsBlended(srcPtr)) { Blt_Picture background, mask; Blt_Pixel black, white; background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, bgColorPtr); mask = Blt_CreatePicture(srcPtr->width, srcPtr->height); /* Don't select 100% transparent pixels */ white.u32 = 0xFFFFFFFF; black.u32 = 0x01000000; Blt_SelectPixels(mask, srcPtr, &black, &white); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); /* Put back the mask by and-ing the pictures together */ Blt_AndPictures(background, mask); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; } if (Blt_PictureFlags(srcPtr) & BLT_PIC_ASSOCIATED_COLORS) { Blt_Picture unassoc; /* * The picture has an alpha burned into the components. Create a * temporary copy removing pre-multiplied alphas. */ unassoc = Blt_ClonePicture(srcPtr); Blt_UnassociateColors(unassoc); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = unassoc; } nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); if ((quantize) && (nColors > 256)) { Blt_Picture quant; quant = Blt_QuantizePicture(srcPtr, 256); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = quant; } Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); nColors = Blt_QueryColors(srcPtr, &colorTable); if (Blt_PictureIsMasked(srcPtr)) { nColors++; } /* Header. */ { unsigned int size; int cpp; cpp = 1; size = 16; while (size < nColors) { size *= 16; cpp++; } sprintf_s(fmt, 20, "%%0%dx", cpp); /* Write the header line */ Blt_DBuffer_Print(buffer, "/* XPM */\n"); Blt_DBuffer_Print(buffer, "static char * image_name[] = {\n"); Blt_DBuffer_Print(buffer, " /* Creator: BLT %s */\n", BLT_VERSION); Blt_DBuffer_Print(buffer, " \"%d %d %d %d\",\n", srcPtr->width, srcPtr->height, nColors, cpp); Blt_DBuffer_Print(buffer, " /* Colors used: %d */\n", nColors); } /* Color table. */ { unsigned long i; const char *colorkey; Blt_HashEntry *hPtr; Blt_HashSearch cursor; colorkey = (Blt_PictureIsColor(srcPtr)) ? "c" : "m"; i = 0; Blt_DBuffer_Print(buffer, " "); for (hPtr = Blt_FirstHashEntry(&colorTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_Pixel pixel; unsigned long key; Blt_SetHashValue(hPtr, i); key = (unsigned long)Blt_GetHashKey(&colorTable, hPtr); pixel.u32 = (unsigned int)key; Blt_DBuffer_Print(buffer, "\""); Blt_DBuffer_Print(buffer, fmt, i); Blt_DBuffer_Print(buffer, " %s #%02x%02x%02x\", ", colorkey, pixel.Red, pixel.Green, pixel.Blue); i++; if ((i % 4) == 0) { Blt_DBuffer_Print(buffer, "\n "); } } if (Blt_PictureIsMasked(srcPtr)) { i++; Blt_DBuffer_Print(buffer, "\""); Blt_DBuffer_Print(buffer, fmt, i); Blt_DBuffer_Print(buffer, " %s None\",\n", colorkey, i); } if ((i % 4) != 0) { Blt_DBuffer_Print(buffer, "\n"); } } /* Image data. */ { Blt_Pixel *srcRowPtr; int y; int count; srcRowPtr = srcPtr->bits; count = 0; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; Blt_DBuffer_Print(buffer, "\""); for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { Blt_HashEntry *hPtr; unsigned long i; unsigned long key; Blt_Pixel pixel; pixel.u32 = sp->u32; pixel.Alpha = 0xFF; key = (unsigned long)pixel.u32; hPtr = Blt_FindHashEntry(&colorTable, (char *)key); if (hPtr == NULL) { fprintf(stderr, "can't find %x\n", sp->u32); Blt_DBuffer_Print(buffer, fmt, nColors); continue; } if (sp->Alpha == 0x00) { i = (unsigned long)nColors; } else { i = (unsigned long)Blt_GetHashValue(hPtr); } Blt_DBuffer_Print(buffer, fmt, i); } Blt_DBuffer_Print(buffer, "\",\n"); srcRowPtr += srcPtr->pixelsPerRow; } } Blt_DBuffer_Print(buffer, "};\n"); if (srcPtr != original) { Blt_FreePicture(srcPtr); } Blt_DeleteHashTable(&colorTable); return TCL_OK; } static Blt_Chain ReadXpm(Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer) { XpmImportSwitches switches; memset(&switches, 0, sizeof(switches)); return XpmToPicture(interp, fileName, buffer, &switches); } static Tcl_Obj * WriteXpm(Tcl_Interp *interp, Blt_Picture picture) { Tcl_Obj *objPtr; Blt_DBuffer buffer; XpmExportSwitches switches; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* white */ buffer = Blt_DBuffer_Create(); result = PictureToXpm(interp, picture, buffer, &switches); objPtr = NULL; if (result == TCL_OK) { objPtr = Tcl_NewStringObj((char *)Blt_DBuffer_Bytes(buffer), Blt_DBuffer_Length(buffer)); } Blt_DBuffer_Destroy(buffer); return objPtr; } static Blt_Chain ImportXpm( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer buffer; XpmImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); return NULL; } chain = NULL; buffer = Blt_DBuffer_Create(); if (switches.dataObjPtr != NULL) { int nBytes; string = Tcl_GetStringFromObj(switches.dataObjPtr, &nBytes); Blt_DBuffer_AppendData(buffer, (unsigned char *)string, nBytes); string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); if (Blt_DBuffer_LoadFile(interp, string, buffer) != TCL_OK) { Blt_DBuffer_Destroy(buffer); return NULL; } *fileNamePtr = string; } chain = XpmToPicture(interp, string, buffer, &switches); Blt_DBuffer_Destroy(buffer); return chain; } static int ExportXpm(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer buffer; Blt_Picture picture; XpmExportSwitches switches; int result; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data switch.", (char *)NULL); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } buffer = Blt_DBuffer_Create(); result = PictureToXpm(interp, picture, buffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, buffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = Blt_DBuffer_StringObj(buffer); objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, objPtr, 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { Tcl_SetObjResult(interp, Blt_DBuffer_StringObj(buffer)); } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(buffer); return result; } int Blt_PictureXpmInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_xpm", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "xpm", /* Name of format. */ IsXpm, /* Discovery routine. */ ReadXpm, /* Read format procedure. */ WriteXpm, /* Write format procedure. */ ImportXpm, /* Import format procedure. */ ExportXpm); /* Export format procedure. */ } #endif /* HAVE_LIBXPM */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltCoreInit.c�����������������������������������������������������������������0000644�0001750�0001750�00000022655�11500220661�015420� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltCoreInit.c -- * * This module initials the non-Tk command of the BLT toolkit, registering the * commands with the TCL interpreter. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltNsUtil.h" #include "bltArrayObj.h" #include "bltMath.h" #ifndef BLT_LIBRARY # ifdef WIN32 # define BLT_LIBRARY "c:/Program Files/Tcl/lib/blt"##BLT_VERSION # else # define BLT_LIBRARY "unknown" # endif #endif #if (_TCL_VERSION >= _VERSION(8,5,0)) #define TCL_VERSION_LOADED TCL_PATCH_LEVEL #else #define TCL_VERSION_LOADED TCL_VERSION #endif static double bltNaN; BLT_EXTERN Tcl_AppInitProc Blt_core_Init; BLT_EXTERN Tcl_AppInitProc Blt_core_SafeInit; static Tcl_MathProc MinMathProc, MaxMathProc; static char libPath[1024] = { BLT_LIBRARY }; /* * Script to set the BLT library path in the variable global "blt_library" * * Checks the usual locations for a file (bltGraph.pro) from the BLT library. * The places searched in order are * * $BLT_LIBRARY * $BLT_LIBRARY/blt2.4 * $BLT_LIBRARY/.. * $BLT_LIBRARY/../blt2.4 * $blt_libPath * $blt_libPath/blt2.4 * $blt_libPath/.. * $blt_libPath/../blt2.4 * $tcl_library * $tcl_library/blt2.4 * $tcl_library/.. * $tcl_library/../blt2.4 * $env(TCL_LIBRARY) * $env(TCL_LIBRARY)/blt2.4 * $env(TCL_LIBRARY)/.. * $env(TCL_LIBRARY)/../blt2.4 * * The TCL variable "blt_library" is set to the discovered path. If the file * wasn't found, no error is returned. The actual usage of $blt_library is * purposely deferred so that it can be set from within a script. */ /* FIXME: Change this to a namespace procedure in 3.0 */ static char initScript[] = {"\n\ global blt_library blt_libPath blt_version tcl_library env\n\ set blt_library {}\n\ set path {}\n\ foreach var { env(BLT_LIBRARY) blt_libPath tcl_library env(TCL_LIBRARY) } { \n\ if { ![info exists $var] } { \n\ continue \n\ } \n\ set path [set $var] \n\ if { [file readable [file join $path bltGraph.pro]] } { \n\ set blt_library $path\n\ break \n\ } \n\ set path [file join $path blt$blt_version ] \n\ if { [file readable [file join $path bltGraph.pro]] } { \n\ set blt_library $path\n\ break \n\ } \n\ set path [file dirname [set $var]] \n\ if { [file readable [file join $path bltGraph.pro]] } { \n\ set blt_library $path\n\ break \n\ } \n\ set path [file join $path blt$blt_version ] \n\ if { [file readable [file join $path bltGraph.pro]] } { \n\ set blt_library $path\n\ break \n\ } \n\ } \n\ if { $blt_library != \"\" } { \n\ global auto_path \n\ lappend auto_path $blt_library \n\ }\n\ unset var path\n\ \n" }; static Tcl_AppInitProc *cmdProcs[] = { #ifndef NO_BASE64 Blt_Base64CmdInitProc, #endif #ifndef NO_BGEXEC Blt_BgexecCmdInitProc, #endif #ifndef NO_PTYEXEC Blt_PtyExecCmdInitProc, #endif #ifndef NO_CRC32 Blt_Crc32CmdInitProc, #endif #ifndef NO_CSV Blt_CsvCmdInitProc, #endif #ifndef NO_DATATABLE Blt_TableCmdInitProc, #endif #ifndef NO_DDE Blt_DdeCmdInitProc, #endif #ifndef NO_DEBUG Blt_DebugCmdInitProc, #endif #ifndef NO_SPLINE Blt_SplineCmdInitProc, #endif #ifndef NO_TREE Blt_TreeCmdInitProc, #endif #ifndef NO_VECTOR Blt_VectorCmdInitProc, #endif #ifndef NO_WATCH Blt_WatchCmdInitProc, #endif (Tcl_AppInitProc *) NULL }; double Blt_NaN(void) { return bltNaN; } static double MakeNaN(void) { union DoubleValue { unsigned int words[2]; double value; } result; #ifdef WORDS_BIGENDIAN result.words[0] = 0x7ff80000; result.words[1] = 0x00000000; #else result.words[0] = 0x00000000; result.words[1] = 0x7ff80000; #endif return result.value; } /* ARGSUSED */ static int MinMathProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tcl_Value *argsPtr, Tcl_Value *resultPtr) { Tcl_Value *op1Ptr, *op2Ptr; op1Ptr = argsPtr, op2Ptr = argsPtr + 1; if ((op1Ptr->type == TCL_INT) && (op2Ptr->type == TCL_INT)) { resultPtr->intValue = MIN(op1Ptr->intValue, op2Ptr->intValue); resultPtr->type = TCL_INT; } else { double a, b; a = (op1Ptr->type == TCL_INT) ? (double)op1Ptr->intValue : op1Ptr->doubleValue; b = (op2Ptr->type == TCL_INT) ? (double)op2Ptr->intValue : op2Ptr->doubleValue; resultPtr->doubleValue = MIN(a, b); resultPtr->type = TCL_DOUBLE; } return TCL_OK; } /*ARGSUSED*/ static int MaxMathProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tcl_Value *argsPtr, Tcl_Value *resultPtr) { Tcl_Value *op1Ptr, *op2Ptr; op1Ptr = argsPtr, op2Ptr = argsPtr + 1; if ((op1Ptr->type == TCL_INT) && (op2Ptr->type == TCL_INT)) { resultPtr->intValue = MAX(op1Ptr->intValue, op2Ptr->intValue); resultPtr->type = TCL_INT; } else { double a, b; a = (op1Ptr->type == TCL_INT) ? (double)op1Ptr->intValue : op1Ptr->doubleValue; b = (op2Ptr->type == TCL_INT) ? (double)op2Ptr->intValue : op2Ptr->doubleValue; resultPtr->doubleValue = MAX(a, b); resultPtr->type = TCL_DOUBLE; } return TCL_OK; } static int SetLibraryPath(Tcl_Interp *interp) { Tcl_DString dString; const char *value; Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, libPath, -1); #ifdef WIN32 { HKEY key; DWORD result; # ifndef BLT_REGISTRY_KEY # define BLT_REGISTRY_KEY "Software\\BLT\\" BLT_VERSION "\\" TCL_VERSION # endif result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, /* Parent key. */ BLT_REGISTRY_KEY, /* Path to sub-key. */ 0, /* Reserved. */ KEY_READ, /* Security access mask. */ &key); /* Resulting key.*/ if (result == ERROR_SUCCESS) { DWORD size; /* Query once to get the size of the string needed */ result = RegQueryValueEx(key, "BLT_LIBRARY", NULL, NULL, NULL, &size); if (result == ERROR_SUCCESS) { Tcl_DStringSetLength(&dString, size); /* And again to collect the string. */ RegQueryValueEx(key, "BLT_LIBRARY", NULL, NULL, (LPBYTE)Tcl_DStringValue(&dString), &size); RegCloseKey(key); } } } #endif /* WIN32 */ value = Tcl_SetVar(interp, "blt_libPath", Tcl_DStringValue(&dString), TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); Tcl_DStringFree(&dString); if (value == NULL) { return TCL_ERROR; } return TCL_OK; } /*LINTLIBRARY*/ int Blt_core_Init(Tcl_Interp *interp) /* Interpreter to add extra commands */ { Tcl_AppInitProc **p; Tcl_Namespace *nsPtr; Tcl_ValueType args[2]; const char *result; const int isExact = 1; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION_LOADED, isExact) == NULL) { return TCL_ERROR; }; #endif Blt_AllocInit(NULL, NULL, NULL); /* * Check that the versions of TCL that have been loaded are the same ones * that BLT was compiled against. */ if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION_LOADED, isExact) == NULL) { return TCL_ERROR; } /* Set the "blt_version", "blt_patchLevel", and "blt_libPath" Tcl * variables. We'll use them in the following script. */ result = Tcl_SetVar(interp, "blt_version", BLT_VERSION, TCL_GLOBAL_ONLY); if (result == NULL) { return TCL_ERROR; } result = Tcl_SetVar(interp, "blt_patchLevel", BLT_PATCH_LEVEL, TCL_GLOBAL_ONLY); if (result == NULL) { return TCL_ERROR; } if (SetLibraryPath(interp) != TCL_OK) { return TCL_ERROR; } if (Tcl_Eval(interp, initScript) != TCL_OK) { return TCL_ERROR; } nsPtr = Tcl_FindNamespace(interp, "::blt", (Tcl_Namespace *)NULL, 0); if (nsPtr == NULL) { nsPtr = Tcl_CreateNamespace(interp, "::blt", NULL, NULL); if (nsPtr == NULL) { return TCL_ERROR; } } /* Initialize the BLT commands that only require Tcl. */ for (p = cmdProcs; *p != NULL; p++) { if ((**p) (interp) != TCL_OK) { Tcl_DeleteNamespace(nsPtr); return TCL_ERROR; } } args[0] = args[1] = TCL_EITHER; Tcl_CreateMathFunc(interp, "min", 2, args, MinMathProc, (ClientData)0); Tcl_CreateMathFunc(interp, "max", 2, args, MaxMathProc, (ClientData)0); Blt_RegisterArrayObj(); bltNaN = MakeNaN(); if (Tcl_PkgProvide(interp, "blt_core", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /*LINTLIBRARY*/ int Blt_core_SafeInit(Tcl_Interp *interp) /* Interpreter to add extra commands */ { return Blt_core_Init(interp); } #ifdef USE_DLL # include "bltWinDll.c" #endif �����������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDtCsv.c��������������������������������������������������������������������0000644�0001750�0001750�00000047125�11462120062�014727� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtCsv.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #ifndef NO_DATATABLE #include "config.h" #include <tcl.h> #include <bltSwitch.h> #include <bltHash.h> #include <bltDataTable.h> #include <bltAlloc.h> #ifdef HAVE_CTYPE_H # include <ctype.h> #endif /* HAVE_CTYPE_H */ #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ DLLEXPORT extern Tcl_AppInitProc Blt_Table_CsvInit; #define TRUE 1 #define FALSE 0 #define EXPORT_ROWLABELS (1<<0) #define EXPORT_COLUMNLABELS (1<<1) /* * Format Import Export * csv file/data file/data * tree data data * vector data data * xml file/data file/data * sql data data * * $table import csv -file fileName -data dataString * $table export csv -file defaultFileName * $table import tree $treeName $node ?switches? * $table export tree $treeName $node "label" "label" "label" * $table import vector $vecName label $vecName label... * $table export vector label $vecName label $vecName.. * $table import xml -file fileName -data dataString ?switches? * $table export xml -file fileName -data dataString ?switches? * $table import sql -host $host -password $pw -db $db -port $port */ /* * ImportSwitches -- */ typedef struct { unsigned int flags; Tcl_Channel channel; /* If non-NULL, channel to read * from. */ char *buffer; /* Buffer to read data into. */ int nBytes; /* # of bytes in the buffer. */ Tcl_DString ds; /* Dynamic string used to read the * file line by line. */ Tcl_Interp *interp; Blt_HashTable dataTable; Tcl_Obj *fileObjPtr; /* Name of file representing the * channel used as the input * source. */ Tcl_Obj *dataObjPtr; /* If non-NULL, data object to use as * input source. */ const char *quote; /* Quoted string delimiter. */ const char *separators; /* Separator characters. */ const char *comment; /* Comment character. */ int maxRows; /* Stop processing after this many * rows have been found. */ } ImportSwitches; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_STRING, "-comment", "char", Blt_Offset(ImportSwitches, comment), 0}, {BLT_SWITCH_OBJ, "-data", "string", Blt_Offset(ImportSwitches, dataObjPtr), 0, 0, NULL}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_INT_NNEG, "-maxrows", "integer", Blt_Offset(ImportSwitches, maxRows), 0}, {BLT_SWITCH_STRING, "-quote", "char", Blt_Offset(ImportSwitches, quote), 0}, {BLT_SWITCH_STRING, "-separators", "characters", Blt_Offset(ImportSwitches, separators), 0}, {BLT_SWITCH_END} }; /* * ExportSwitches -- */ typedef struct { Blt_TableIterator ri, ci; unsigned int flags; Tcl_Obj *fileObjPtr; Tcl_Channel channel; /* If non-NULL, channel to write * output to. */ Tcl_DString *dsPtr; int length; /* Length of dynamic string. */ int count; /* # of fields in current record. */ Tcl_Interp *interp; char *quote; /* Quoted string delimiter. */ char *separator; /* Separator character. */ } ExportSwitches; extern Blt_SwitchFreeProc Blt_Table_ColumnIterFreeProc; extern Blt_SwitchFreeProc Blt_Table_RowIterFreeProc; extern Blt_SwitchParseProc Blt_Table_ColumnIterSwitchProc; extern Blt_SwitchParseProc Blt_Table_RowIterSwitchProc; static Blt_SwitchCustom columnIterSwitch = { Blt_Table_ColumnIterSwitchProc, Blt_Table_ColumnIterFreeProc, 0, }; static Blt_SwitchCustom rowIterSwitch = { Blt_Table_RowIterSwitchProc, Blt_Table_RowIterFreeProc, 0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-columns", "columns", Blt_Offset(ExportSwitches, ci), 0, 0, &columnIterSwitch}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_BITMASK, "-rowlabels", "", Blt_Offset(ExportSwitches, flags), 0, EXPORT_ROWLABELS}, {BLT_SWITCH_BITMASK, "-columnlabels", "", Blt_Offset(ExportSwitches, flags), 0, EXPORT_COLUMNLABELS}, {BLT_SWITCH_STRING, "-quote", "char", Blt_Offset(ExportSwitches, quote), 0}, {BLT_SWITCH_CUSTOM, "-rows", "rows", Blt_Offset(ExportSwitches, ri), 0, 0, &rowIterSwitch}, {BLT_SWITCH_STRING, "-separator", "char", Blt_Offset(ExportSwitches, separator), 0}, {BLT_SWITCH_END} }; static Blt_TableImportProc ImportCsvProc; static Blt_TableExportProc ExportCsvProc; static void StartCsvRecord(ExportSwitches *exportPtr) { if (exportPtr->channel != NULL) { Tcl_DStringSetLength(exportPtr->dsPtr, 0); exportPtr->length = 0; } exportPtr->count = 0; } static int EndCsvRecord(ExportSwitches *exportPtr) { int nWritten; char *line; Tcl_DStringAppend(exportPtr->dsPtr, "\n", 1); exportPtr->length++; line = Tcl_DStringValue(exportPtr->dsPtr); if (exportPtr->channel != NULL) { nWritten = Tcl_Write(exportPtr->channel, line, exportPtr->length); if (nWritten != exportPtr->length) { Tcl_AppendResult(exportPtr->interp, "can't write csv record: ", Tcl_PosixError(exportPtr->interp), (char *)NULL); return TCL_ERROR; } } return TCL_OK; } static void AppendCsvRecord(ExportSwitches *exportPtr, const char *field, int length, Blt_TableColumnType type) { const char *fp; char *p; int extra, doQuote; doQuote = (type == TABLE_COLUMN_TYPE_STRING); extra = 0; if (field == NULL) { length = 0; } else { for (fp = field; *fp != '\0'; fp++) { if ((*fp == '\n') || (*fp == exportPtr->separator[0]) || (*fp == ' ') || (*fp == '\t')) { doQuote = TRUE; } else if (*fp == exportPtr->quote[0]) { doQuote = TRUE; extra++; } } if (doQuote) { extra += 2; } if (length < 0) { length = fp - field; } } if (exportPtr->count > 0) { Tcl_DStringAppend(exportPtr->dsPtr, exportPtr->separator, 1); exportPtr->length++; } length = length + extra + exportPtr->length; Tcl_DStringSetLength(exportPtr->dsPtr, length); p = Tcl_DStringValue(exportPtr->dsPtr) + exportPtr->length; exportPtr->length = length; if (field != NULL) { if (doQuote) { *p++ = exportPtr->quote[0]; } for (fp = field; *fp != '\0'; fp++) { if (*fp == exportPtr->quote[0]) { *p++ = exportPtr->quote[0]; } *p++ = *fp; } if (doQuote) { *p++ = exportPtr->quote[0]; } } exportPtr->count++; } static int ExportCsvRows(Blt_Table table, ExportSwitches *exportPtr) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&exportPtr->ri); row != NULL; row = Blt_Table_NextTaggedRow(&exportPtr->ri)) { Blt_TableColumn col; StartCsvRecord(exportPtr); if (exportPtr->flags & EXPORT_ROWLABELS) { const char *field; field = Blt_Table_RowLabel(row); AppendCsvRecord(exportPtr, field, -1, TABLE_COLUMN_TYPE_STRING); } for (col = Blt_Table_FirstTaggedColumn(&exportPtr->ci); col != NULL; col = Blt_Table_NextTaggedColumn(&exportPtr->ci)) { const char *string; Blt_TableColumnType type; type = Blt_Table_ColumnType(col); string = Blt_Table_GetString(table, row, col); AppendCsvRecord(exportPtr, string, -1, type); } if (EndCsvRecord(exportPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int ExportCsvColumns(ExportSwitches *exportPtr) { if (exportPtr->flags & EXPORT_COLUMNLABELS) { Blt_TableColumn col; StartCsvRecord(exportPtr); if (exportPtr->flags & EXPORT_ROWLABELS) { AppendCsvRecord(exportPtr, "*BLT*", 5, TABLE_COLUMN_TYPE_STRING); } for (col = Blt_Table_FirstTaggedColumn(&exportPtr->ci); col != NULL; col = Blt_Table_NextTaggedColumn(&exportPtr->ci)) { AppendCsvRecord(exportPtr, Blt_Table_ColumnLabel(col), -1, TABLE_COLUMN_TYPE_STRING); } return EndCsvRecord(exportPtr); } return TCL_OK; } /* * $table exportfile fileName ?switches...? * $table exportdata ?switches...? */ static int ExportCsvProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ExportSwitches switches; Tcl_Channel channel; Tcl_DString ds; int closeChannel; int result; closeChannel = FALSE; channel = NULL; Tcl_DStringInit(&ds); memset(&switches, 0, sizeof(switches)); switches.separator = Blt_AssertStrdup(","); switches.quote = Blt_AssertStrdup("\""); rowIterSwitch.clientData = table; columnIterSwitch.clientData = table; Blt_Table_IterateAllRows(table, &switches.ri); Blt_Table_IterateAllColumns(table, &switches.ci); if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if (switches.fileObjPtr != NULL) { const char *fileName; closeChannel = TRUE; fileName = Tcl_GetString(switches.fileObjPtr); if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { goto error; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for writing", (char *)NULL); goto error; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { goto error; /* Can't open export file. */ } } } switches.interp = interp; switches.dsPtr = &ds; switches.channel = channel; result = ExportCsvColumns(&switches); if (result == TCL_OK) { result = ExportCsvRows(table, &switches); } if ((switches.channel == NULL) && (result == TCL_OK)) { Tcl_DStringResult(interp, &ds); } error: Tcl_DStringFree(&ds); if (closeChannel) { Tcl_Close(interp, channel); } Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return result; } /* * ImportGetLine -- * * Get a single line from the input buffer or file. The resulting buffer * always contains a new line unless an error occurs or we hit EOF. * */ static int ImportGetLine(Tcl_Interp *interp, ImportSwitches *importPtr, char **bufferPtr, int *nBytesPtr) { if (importPtr->channel != NULL) { int nBytes; if (Tcl_Eof(importPtr->channel)) { *nBytesPtr = 0; return TCL_OK; } Tcl_DStringSetLength(&importPtr->ds, 0); nBytes = Tcl_Gets(importPtr->channel, &importPtr->ds); if (nBytes < 0) { if (Tcl_Eof(importPtr->channel)) { *nBytesPtr = 0; return TCL_OK; } *nBytesPtr = nBytes; Tcl_AppendResult(interp, "error reading file: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } Tcl_DStringAppend(&importPtr->ds, "\n", 1); *nBytesPtr = nBytes + 1; *bufferPtr = Tcl_DStringValue(&importPtr->ds); } else { const char *bp, *bend; int nBytes; for (bp = importPtr->buffer, bend = bp + importPtr->nBytes; bp < bend; bp++) { if (*bp == '\n') { bp++; break; } } nBytes = bp - importPtr->buffer; *nBytesPtr = nBytes; *bufferPtr = importPtr->buffer; importPtr->nBytes -= nBytes; importPtr->buffer += nBytes; } return TCL_OK; } static INLINE int IsSeparator(ImportSwitches *importPtr, const char c) { const char *p; for (p = importPtr->separators; *p != '\0'; p++) { if (*p == c) { return TRUE; } } return FALSE; } static int ImportCsv(Tcl_Interp *interp, Blt_Table table, ImportSwitches *importPtr) { Tcl_DString dString; char *fp, *field; int fieldSize; int inQuotes, isQuoted, isPath; int result; size_t i; Blt_TableRow row; Blt_TableColumn col; int tabIsSeparator; const char quote = importPtr->quote[0]; const char comment = importPtr->comment[0]; result = TCL_ERROR; isPath = isQuoted = inQuotes = FALSE; row = NULL; i = 1; Tcl_DStringInit(&dString); fieldSize = 128; Tcl_DStringSetLength(&dString, fieldSize + 1); fp = field = Tcl_DStringValue(&dString); tabIsSeparator = IsSeparator(importPtr, '\t'); for (;;) { char *bp, *bend; int nBytes; result = ImportGetLine(interp, importPtr, &bp, &nBytes); if (result != TCL_OK) { goto error; /* I/O Error. */ } if (nBytes == 0) { break; /* EOF */ } bend = bp + nBytes; while ((bp < bend) && (isspace(*bp))) { bp++; /* Skip leading spaces. */ } if ((*bp == '\0') || (*bp == comment)) { continue; /* Ignore blank or comment lines */ } for (/*empty*/; bp < bend; bp++) { if ((*bp == ' ') || ((*bp == '\t') && (!tabIsSeparator))) { /* * Include whitespace in the field only if it's not leading or * we're inside of quotes or a path. */ if ((fp != field) || (inQuotes) || (isPath)) { *fp++ = *bp; } } else if (*bp == '\\') { /* * Handle special case CSV files that allow unquoted paths. * Example: ...,\this\path " should\have been\quoted\,... */ if (fp == field) { isPath = TRUE; } *fp++ = *bp; } else if (*bp == quote) { if (inQuotes) { if (*(bp+1) == quote) { *fp++ = quote; bp++; } else { inQuotes = FALSE; } } else { /* * If the quote doesn't start a field, then treat all * quotes in the field as ordinary characters. */ if (fp == field) { isQuoted = inQuotes = TRUE; } else { *fp++ = *bp; } } } else if ((IsSeparator(importPtr, *bp)) || (*bp == '\n')) { if (inQuotes) { *fp++ = *bp; /* Copy the comma or newline. */ } else { Blt_TableColumn col; char *last; if ((isPath) && (IsSeparator(importPtr, *bp)) && (fp != field) && (*(fp - 1) != '\\')) { *fp++ = *bp; /* Copy the comma or newline. */ goto done; } /* "last" points to the character after the last character * in the field. */ last = fp; /* Remove trailing spaces only if the field wasn't * quoted. */ if ((!isQuoted) && (!isPath)) { while ((last > field) && (isspace(*(last - 1)))) { last--; } } if (row == NULL) { if ((*bp == '\n') && (fp == field)) { goto done; /* Ignore empty lines. */ } if (Blt_Table_ExtendRows(interp, table, 1, &row) != TCL_OK) { goto error; } if ((importPtr->maxRows > 0) && (Blt_Table_NumRows(table) > importPtr->maxRows)) { bp = bend; goto done; } } /* End of field. Append field to row. */ if (i > Blt_Table_NumColumns(table)) { if (Blt_Table_ExtendColumns(interp, table, 1, &col) != TCL_OK) { goto error; } } else { col = Blt_Table_Column(table, i); } if ((last > field) || (isQuoted)) { if (Blt_Table_SetString(table, row, col, field, last - field) != TCL_OK) { goto error; } } i++; if (*bp == '\n') { row = NULL; i = 1; } fp = field; isPath = isQuoted = FALSE; } done: ; } else { *fp++ = *bp; /* Copy the character. */ } if ((fp - field) >= fieldSize) { int offset; /* * We've exceeded the current maximum size of the field. * Double the size of the field, but make sure to reset the * pointers to the (possibly) new memory location. */ offset = fp - field; fieldSize += fieldSize; Tcl_DStringSetLength(&dString, fieldSize + 1); field = Tcl_DStringValue(&dString); fp = field + offset; } } if (nBytes < 1) { /* * We're reached the end of input. But there may not have been a * final newline to trigger the final append. So check if a last * field is still needs appending the the last row. */ if (fp != field) { char *last; last = fp; /* Remove trailing spaces */ while (isspace(*(last - 1))) { last--; } if (row == NULL) { if (Blt_Table_ExtendRows(interp, table, 1, &row) != TCL_OK) { goto error; } } col = Blt_Table_FindColumnByIndex(table, i); if (col == NULL) { if (Blt_Table_ExtendColumns(interp, table, 1, &col) != TCL_OK) { goto error; } } if ((last > field) || (isQuoted)) { if (Blt_Table_SetString(table, row, col, field, last - field) != TCL_OK) { goto error; } } } break; } } result = TCL_OK; error: Tcl_DStringFree(&dString); return result; } static int ImportCsvProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; ImportSwitches switches; memset(&switches, 0, sizeof(switches)); switches.separators = Blt_AssertStrdup(",\t"); switches.quote = Blt_AssertStrdup("\""); switches.comment = Blt_AssertStrdup(""); Blt_InitHashTable(&switches.dataTable, BLT_STRING_KEYS); if (Blt_ParseSwitches(interp, importSwitches, objc - 3 , objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "can't set both -file and -data switches.", (char *)NULL); goto error; } if (switches.dataObjPtr != NULL) { int nBytes; switches.channel = NULL; switches.buffer = Tcl_GetStringFromObj(switches.dataObjPtr, &nBytes); switches.nBytes = nBytes; switches.fileObjPtr = NULL; result = ImportCsv(interp, table, &switches); } else { int closeChannel; Tcl_Channel channel; const char *fileName; closeChannel = TRUE; if (switches.fileObjPtr == NULL) { fileName = "out.csv"; } else { fileName = Tcl_GetString(switches.fileObjPtr); } if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { goto error; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); goto error; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { goto error; } } switches.channel = channel; Tcl_DStringInit(&switches.ds); result = ImportCsv(interp, table, &switches); Tcl_DStringFree(&switches.ds); if (closeChannel) { Tcl_Close(interp, channel); } } error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DeleteHashTable(&switches.dataTable); return result; } int Blt_Table_CsvInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_datatable_csv", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_Table_RegisterFormat(interp, "csv", /* Name of format. */ ImportCsvProc, /* Import procedure. */ ExportCsvProc); /* Export procedure. */ } #endif /* NO_DATATABLE */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacPainter.c���������������������������������������������������������������0000644�0001750�0001750�00000111677�11462120062�015733� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSXPainter.c -- * * This module implements MacOSX-specific image processing procedures * for the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltPicture.h" #include "bltPainter.h" #include <X11/Xutil.h> #include "tkDisplay.h" typedef struct _Blt_Picture Picture; #include <Carbon/Carbon.h> struct TkWindow; struct _MacDrawable { TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */ CGrafPtr grafPtr; ControlRef rootControl; int xOffset; /* X offset from toplevel window. */ int yOffset; /* Y offset from toplevel window. */ RgnHandle clipRgn; /* Visable region of window. */ RgnHandle aboveClipRgn; /* Visable region of window and its * children. */ int referenceCount; /* Don't delete toplevel until * children are gone. */ /* Pointer to the toplevel datastruct. */ struct _MacDrawable *toplevel; int flags; /* Various state see defines below. */ }; typedef struct _MacDrawable *MacDrawable; /* *--------------------------------------------------------------------------- * * DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Picture DrawableToPicture( Painter *painterPtr, Drawable drawable, int x, int y, int width, int height) /* Dimension of the drawable. */ { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr srcPort; Picture *destPtr; srcPort = TkMacOSXGetDrawablePort(drawable); destPtr = Blt_CreatePicture(width, height); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, x, y, x + width, y + height); SetRect(&destRect, 0, 0, width, height); GetGWorld(&saveWorld, &saveDevice); SetGWorld(srcPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)destPtr->bits; pm.rowBytes = destPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, * not a BitMap. */ CopyBits(GetPortBitMapForCopyBits(destPort), (BitMap *)&pm, &srcRect, &destRect, srcCopy, NULL); } SetGWorld(saveWorld, saveDevice); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_WindowToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * This routine is used to snap foreign (non-Tk) windows. For * pixmaps and Tk windows, Blt_DrawableToPicture is preferred. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_WindowToPicture( Display *display, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainterFromDrawable(display, drawable, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } /* *--------------------------------------------------------------------------- * * Blt_DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_DrawableToPicture( Tk_Window tkwin, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainter(tkwin, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } Pixmap Blt_PhotoImageMask( Tk_Window tkwin, Tk_PhotoImageBlock src) { TkWinBitmap *twdPtr; int offset, count; int x, y; unsigned char *srcPtr; int destBytesPerRow; int destHeight; unsigned char *destBits; destBytesPerRow = ((src.width + 31) & ~31) / 8; destBits = Blt_AssertCalloc(src.height, destBytesPerRow); destHeight = src.height; offset = count = 0; /* FIXME: figure out why this is so! */ for (y = src.height - 1; y >= 0; y--) { srcPtr = src.pixelPtr + offset; for (x = 0; x < src.width; x++) { if (srcPtr[src.offset[3]] == 0x00) { SetBit(x, y); count++; } srcPtr += src.pixelSize; } offset += src.pitch; } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = src.width; bm.bmHeight = src.height; bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } Pixmap Blt_PictureMask( Tk_Window tkwin, Blt_Picture pict) { TkWinBitmap *twdPtr; int count; int x, y; Blt_Pixel *sp; int destBytesPerRow; int destWidth, destHeight; unsigned char *destBits; destWidth = Blt_PictureWidth(pict); destHeight = Blt_PictureHeight(pict); destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); count = 0; sp = Blt_PictureBits(pict); for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { if (sp->Alpha == 0x00) { SetBit(x, y); count++; } sp++; } } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = Blt_PictureWidth(pict); bm.bmHeight = Blt_PictureHeight(pict); bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given * bitmap. We also need a special GC of depth 1, so that we do * not need to rotate more than one plane of the bitmap. * * Note that under Windows, monochrome bitmaps are stored * bottom-to-top. This is why the right angle rotations 0/180 * and 90/270 look reversed. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* Right angle rotation to perform */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; double rotWidth, rotHeight; HDC hDC; TkWinDCState state; int x, y; /* Destination bitmap coordinates */ int sx, sy; /* Source bitmap coordinates */ unsigned long pixel; HBITMAP hBitmap; int result; struct MonoBitmap { BITMAPINFOHEADER bi; RGBQUAD colors[2]; } mb; int srcBytesPerRow, destBytesPerRow; int destWidth, destHeight; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = (int)ceil(rotWidth); destHeight = (int)ceil(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; /* Handle right-angle rotations specially. */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { sx = y; for (x = 0; x < destWidth; x++) { sy = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sx = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sy = x; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { pixel = GetBit(x, y); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double srcCX, srcCY; /* Center of source rectangle */ double destCX, destCY; /* Center of destination rectangle */ double tx, ty; double rx, ry; /* Angle of rotation for x and y coordinates */ radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ srcCX = srcWidth * 0.5; srcCY = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* Rotate each pixel of dest image, placing results in source image */ for (y = 0; y < destHeight; y++) { ty = y - destCY; for (x = 0; x < destWidth; x++) { /* Translate origin to center of destination image */ tx = x - destCX; /* Rotate the coordinates about the origin */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image */ rx += srcCX; ry += srcCY; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bi.biSize = sizeof(BITMAPINFOHEADER); mb.bi.biPlanes = 1; mb.bi.biBitCount = 1; mb.bi.biCompression = BI_RGB; mb.bi.biWidth = destWidth; mb.bi.biHeight = destHeight; mb.bi.biSizeImage = destBytesPerRow * destHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, destHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } *destWidthPtr = destWidth; *destHeightPtr = destHeight; return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { TkWinDCState srcState, destState; HDC src, dest; Pixmap destBitmap; Window root; Display *display; /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; } src = TkWinGetDrawableDC(display, srcBitmap, &srcState); dest = TkWinGetDrawableDC(display, destBitmap, &destState); StretchBlt(dest, 0, 0, destWidth, destHeight, src, 0, 0, srcWidth, srcHeight, SRCCOPY); TkWinReleaseDrawableDC(srcBitmap, src, &srcState); TkWinReleaseDrawableDC(destBitmap, dest, &destState); return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleRotateBitmapArea -- * * Creates a scaled and rotated bitmap from a given bitmap. The * caller also provides (offsets and dimensions) the region of * interest in the destination bitmap. This saves having to * process the entire destination bitmap is only part of it is * showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the * destination image. For each pixel, the corresponding * pixel in the source bitmap is used. This means that * destination coordinates are first scaled to the size of * the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapArea( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual * destination bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int virtWidth, unsigned int virtHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Pixmap destBitmap; Window root; /* Root window drawable */ double rWidth, rHeight; double xScale, yScale; int srcBytesPerRow, destBytesPerRow; int destHeight; int result; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((regionWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(regionHeight, destBytesPerRow); destHeight = regionHeight; angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rWidth, &rHeight, (Point2d *)NULL); xScale = rWidth / (double)virtWidth; yScale = rHeight / (double)virtHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(y+regionY)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sy; sy = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sx; sx = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < (int)regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double scx, scy; /* Offset from the center of the * source rectangle. */ double rcx, rcy; /* Offset to the center of the * rotated rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ scx = srcWidth * 0.5; scy = srcHeight * 0.5; rcx = rWidth * 0.5; rcy = rHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < (int)regionHeight; y++) { int x; double ty; /* Translated coordinates from center */ ty = (yScale * (double)(y + regionY)) - rcy; for (x = 0; x < (int)regionWidth; x++) { double rx, ry; /* Angle of rotation for x and y coordinates */ double tx; /* Translated coordinates from center */ int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rcx; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += scx; ry += scy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= (int)srcWidth) || (sx < 0) || (sy >= (int)srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } { HBITMAP hBitmap; HDC hDC; TkWinDCState state; struct MonoBitmap { BITMAPINFOHEADER bmiHeader; RGBQUAD colors[2]; } mb; /* Write the rotated image into the destination bitmap. */ hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mb.bmiHeader.biPlanes = 1; mb.bmiHeader.biBitCount = 1; mb.bmiHeader.biCompression = BI_RGB; mb.bmiHeader.biWidth = regionWidth; mb.bmiHeader.biHeight = regionHeight; mb.bmiHeader.biSizeImage = destBytesPerRow * regionHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, regionHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); } if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } return destBitmap; } #ifdef HAVE_IJL_H #include <ijl.h> Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { JPEG_CORE_PROPERTIES jpgProps; Blt_Picture pict; ZeroMemory(&jpgProps, sizeof(JPEG_CORE_PROPERTIES)); if(ijlInit(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't initialize Intel JPEG library", (char *)NULL); return NULL; } jpgProps.JPGFile = fileName; if (ijlRead(&jpgProps, IJL_JFILE_READPARAMS) != IJL_OK) { Tcl_AppendResult(interp, "can't read JPEG file header from \"", fileName, "\" file.", (char *)NULL); goto error; } // !dudnik: to fix bug case 584680, [OT:287A305B] // Set the JPG color space ... this will always be // somewhat of an educated guess at best because JPEG // is "color blind" (i.e., nothing in the bit stream // tells you what color space the data was encoded from). // However, in this example we assume that we are // reading JFIF files which means that 3 channel images // are in the YCbCr color space and 1 channel images are // in the Y color space. switch(jpgProps.JPGChannels) { case 1: jpgProps.JPGColor = IJL_G; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 3: jpgProps.JPGColor = IJL_YCBCR; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 4: jpgProps.JPGColor = IJL_YCBCRA_FPX; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; default: /* This catches everything else, but no color twist will be performed by the IJL. */ jpgProps.DIBColor = (IJL_COLOR)IJL_OTHER; jpgProps.JPGColor = (IJL_COLOR)IJL_OTHER; jpgProps.DIBChannels = jpgProps.JPGChannels; break; } jpgProps.DIBWidth = jpgProps.JPGWidth; jpgProps.DIBHeight = jpgProps.JPGHeight; jpgProps.DIBPadBytes = IJL_DIB_PAD_BYTES(jpgProps.DIBWidth, jpgProps.DIBChannels); pict = Blt_CreatePicture(jpgProps.JPGWidth, jpgProps.JPGHeight); jpgProps.DIBBytes = (BYTE *)Blt_PictureBits(pict); if (ijlRead(&jpgProps, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { Tcl_AppendResult(interp, "can't read image data from \"", fileName, "\"", (char *)NULL); goto error; } if (ijlFree(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't free Intel(R) JPEG library.", (char *)NULL); } return pict; error: ijlFree(&jpgProps); if (pict != NULL) { Blt_FreePicture(pict); } ijlFree(&jpgProps); return NULL; } #else #ifdef HAVE_JPEGLIB_H #undef HAVE_STDLIB_H #ifdef WIN32 #define XMD_H 1 #endif #include "jpeglib.h" #include <setjmp.h> typedef struct { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf jmpBuf; Tcl_DString dString; } ReaderHandler; static void ErrorProc(j_common_ptr jpegInfo); static void MessageProc(j_common_ptr jpegInfo); /* * Here's the routine that will replace the standard error_exit method: */ static void ErrorProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; (*handlerPtr->pub.output_message) (jpgPtr); longjmp(handlerPtr->jmpBuf, 1); } static void MessageProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; char buffer[JMSG_LENGTH_MAX]; /* Create the message and append it into the dynamic string. */ (*handlerPtr->pub.format_message) (jpgPtr, buffer); Tcl_DStringAppend(&handlerPtr->dString, " ", -1); Tcl_DStringAppend(&handlerPtr->dString, buffer, -1); } /* *--------------------------------------------------------------------------- * * Blt_JPEGToPicture -- * * Reads a JPEG file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { struct jpeg_decompress_struct jpg; Blt_Picture pict; unsigned int pictWidth, pictHeight; Blt_Pixel *dp; ReaderHandler handler; FILE *f; JSAMPLE **readBuffer; int row_stride; int i; JSAMPLE *bufPtr; f = Blt_OpenFile(interp, fileName, "rb"); if (f == NULL) { return NULL; } pict = NULL; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ jpg.dct_method = JDCT_IFAST; jpg.err = jpeg_std_error(&handler.pub); handler.pub.error_exit = ErrorProc; handler.pub.output_message = MessageProc; Tcl_DStringInit(&handler.dString); Tcl_DStringAppend(&handler.dString, "error reading \"", -1); Tcl_DStringAppend(&handler.dString, fileName, -1); Tcl_DStringAppend(&handler.dString, "\": ", -1); if (setjmp(handler.jmpBuf)) { jpeg_destroy_decompress(&jpg); fclose(f); Tcl_DStringResult(interp, &handler.dString); return NULL; } jpeg_create_decompress(&jpg); jpeg_stdio_src(&jpg, f); jpeg_read_header(&jpg, TRUE); /* Step 3: read file parameters */ jpeg_start_decompress(&jpg); /* Step 5: Start decompressor */ pictWidth = jpg.output_width; pictHeight = jpg.output_height; if ((pictWidth < 1) || (pictHeight < 1)) { Tcl_AppendResult(interp, "bad JPEG image size", (char *)NULL); fclose(f); return NULL; } /* JSAMPLEs per row in output buffer */ row_stride = pictWidth * jpg.output_components; /* Make a one-row-high sample array that will go away when done * with image */ readBuffer = (*jpg.mem->alloc_sarray) ((j_common_ptr)&jpg, JPOOL_IMAGE, row_stride, 1); pict = Blt_CreatePicture(pictWidth, pictHeight); dp = Blt_PictureBits(pict); if (jpg.output_components == 1) { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = dp->Green = dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } else { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = *bufPtr++; dp->Green = *bufPtr++; dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } jpeg_finish_decompress(&jpg); /* We can ignore the return value * since suspension is not * possible with the stdio data * source. */ jpeg_destroy_decompress(&jpg); /* * After finish_decompress, we can close the input file. Here we * postpone it until after no more JPEG errors are possible, so as * to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume * anything...) */ fclose(f); /* * At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ if (handler.pub.num_warnings > 0) { Tcl_SetErrorCode(interp, "IMAGE", "JPEG", Tcl_DStringValue(&handler.dString), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } /* * We're ready to call the Tk_Photo routines. They'll take the RGB * array we've processed to build the Tk image of the JPEG. */ Tcl_DStringFree(&handler.dString); return pict; } #endif /* HAVE_JPEGLIB_H */ #endif /* HAVE_IJL_H */ /* *--------------------------------------------------------------------------- * * PaintPicture -- * * Paints the picture to the given drawable. The region of * the picture is specified and the coordinates where in the * destination drawable is the image to be displayed. * * The image may be dithered depending upon the bit set in * the flags parameter: 0 no dithering, 1 for dithering. * * Results: * Returns TRUE if the picture was successfully display, * Otherwise FALSE is returned if the particular combination * visual and image depth is not handled. * *--------------------------------------------------------------------------- */ static int PaintPicture( Painter *painterPtr, Drawable drawable, Picture *srcPtr, int srcX, int srcY, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; Picture *ditherPtr; ditherPtr = NULL; if (flags & BLT_PAINTER_DITHER) { ditherPtr = Blt_DitherPicture(srcPtr, painterPtr->palette); if (ditherPtr != NULL) { srcPtr = ditherPtr; } } destPort = TkMacOSXGetDrawablePort(drawable); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, srcX, srcY, srcX + width, srcY + height); SetRect(&destRect, destX + dstDraw->xOffset, destY + dstDraw->yOffset, destX + width + dstDraw->xOffset, destY + height + dstDraw->yOffset); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)srcPtr->bits; pm.rowBytes = srcPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, * not a BitMap. */ CopyBits((BitMap *)&pm, GetPortBitMapForCopyBits(destPort), &srcRect, &destRect, srcCopy, NULL); } if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } SetGWorld(saveWorld, saveDevice); return TRUE; } /* *--------------------------------------------------------------------------- * * PaintPictureWithBlend -- * * Blends and paints the picture with the given drawable. The * region of the picture is specified and the coordinates where * in the destination drawable is the image to be displayed. * * The background is snapped from the drawable and converted into * a picture. This picture is then blended with the current * picture (the background always assumed to be 100% opaque). * * Results: * Returns TRUE is the picture was successfully display, * Otherwise FALSE is returned. This may happen if the * background can not be obtained from the drawable. * *--------------------------------------------------------------------------- */ static int PaintPictureWithBlend( Painter *painterPtr, Drawable drawable, Blt_Picture fg, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, int alpha) { Blt_Picture bg; if (destX < 0) { width += destX; destX = 0; } if (destY < 0) { height += destY; destY = 0; } if ((width < 0) || (height < 0)) { return FALSE; } bg = DrawableToPicture(painterPtr, drawable, destX, destY, width, height); if (bg == NULL) { return FALSE; } #ifdef notdef Blt_FadePicture(bg, fg, x, y, width, height, 0, 0, alpha); #else Blt_BlendPictures(bg, fg, x, y, bg->width, bg->height, 0, 0); #endif PaintPicture(painterPtr, drawable, bg, 0, 0, bg->width, bg->height, destX, destY, flags); Blt_FreePicture(bg); return TRUE; } int Blt_PaintPicture( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { if ((picture == NULL) || (x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))) { /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } if ((width <= 0) || (height <= 0)) { return TRUE; } if (Blt_PictureIsOpaque(picture)) { return PaintPicture(painter, drawable, picture, x, y, width, height, destX, destY, flags); } else { int alpha = 128; return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } } int Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, /* Indicates whether to dither the * picture before displaying. */ double falpha) { int alpha; alpha = (int)(falpha * 255.0 + 0.5); assert((x >= 0) && (y >= 0)); /* assert((destX >= 0) && (destY >= 0)); */ assert((width >= 0) && (height >= 0)); if ((x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))){ /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } /* * Check that the region defined does not extend beyond the end of * the picture. * * Clip the end of the region if it is too big. */ if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } GC Blt_PainterGC(Painter *painterPtr) { return painterPtr->gc; } int Blt_PainterDepth(Painter *painterPtr) { return painterPtr->depth; } �����������������������������������������������������������������./saods9/blt3.0.1/src/bltScrollset.c����������������������������������������������������������������0000644�0001750�0001750�00000171731�11462120062�015657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltScrollset.c -- * * This module implements a scrollset widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltBind.h" #include "bltImage.h" #include "bltPicture.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltHash.h" #include "bltBgStyle.h" #include "bltPainter.h" #define VPORTWIDTH(s) (Tk_Width((s)->tkwin) - (s)->yScrollbarWidth) #define VPORTHEIGHT(s) (Tk_Height((s)->tkwin) - (s)->xScrollbarHeight) #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define REDRAW_PENDING (1<<0) /* A redraw request is pending. */ #define LAYOUT_PENDING (1<<1) /* A request to recompute the layout of * the scrollbars and slave widget is * pending. */ #define UPDATE_PENDING (1<<2) /* A request to call the widget update * procedure because scrollbars or * slave widget has been configured. */ #define SCROLLX (1<<3) /* A request to set the X scrollbar is * pending. */ #define SCROLLY (1<<4) /* A request to set the Y scrollbar is * pending. */ #define SCROLL_PENDING (SCROLLX|SCROLLY) #define XSCROLLBAR_PENDING (1<<5) /* A request to install a new * x-scrollbar widget is pending. */ #define YSCROLLBAR_PENDING (1<<6) /* A request to install a new * y-scrollbar widget is pending. */ #define SLAVE_PENDING (1<<7) /* A request to install a new slave * widget is pending. */ #define DISPLAY_X (1<<8) /* Display the x-scrollbar. */ #define DISPLAY_Y (1<<9) /* Display the y-scrollbar. */ #define SLAVE_XVIEW (1<<10) /* The slave widget has a "xview" * operation */ #define SLAVE_YVIEW (1<<11) /* The slave widget has a "yview" * operation. */ #define DEF_ANCHOR "center" #define DEF_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_CURSOR ((char *)NULL) #define DEF_FILL "both" #define DEF_HEIGHT "0" #define DEF_IPADX "0" #define DEF_IPADY "0" #define DEF_PADX "0" #define DEF_PADY "0" #define DEF_WIDTH "0" #define DEF_WINDOW ((char *)NULL) #define DEF_XSCROLLBAR ((char *)NULL) #define DEF_XSCROLLCOMMAND ((char *)NULL) #define DEF_XSCROLLINCREMENT "2" #define DEF_XVIEWCOMMAND ((char *)NULL) #define DEF_YSCROLLBAR ((char *)NULL) #define DEF_YSCROLLCOMMAND ((char *)NULL) #define DEF_YSCROLLINCREMENT "2" #define DEF_YVIEWCOMMAND ((char *)NULL) /* * Limits -- * * Defines the bounding of a size (width or height) in the table. It may * be related to the partition, entry, or table size. The widget pointers * are used to associate sizes with the requested size of other widgets. */ typedef struct { int flags; /* Flags indicate whether using * default values for limits or * not. See flags below. */ int max, min; /* Values for respective limits. */ int nom; /* Nominal starting value. */ } Limits; typedef struct { /* * This works around a bug in the Tk API. Under under Win32, Tk tries to * read the widget record of toplevel windows (TopLevel or Frame widget), to * get its menu name field. What this means is that we must carefully * arrange the fields of this widget so that the menuName field is at the * same offset in the structure. */ Tk_Window tkwin; /* Window that embodies the frame. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up. */ Display *display; /* Display containing widget. Used, * among other things, so that * resources can * be freed even after * tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. * Used to delete widget command. */ Tcl_Command cmdToken; /* Token for widget's command. */ Tcl_Obj *slaveObjPtr; /* Name of the slave widget to be * embed into the widget window. */ Tk_Window slave; /* Slave window to be managed by this * widget. */ Tk_Window shangle; Limits reqSlaveWidth, reqSlaveHeight; /* Requested sizes for slave. */ int reqWidth, reqHeight; Tk_Anchor anchor; /* Anchor type: indicates how the * slave is positioned if extra space * is available in the widget */ Blt_Pad xPad; /* Extra padding placed left and right * of the slave. */ Blt_Pad yPad; /* Extra padding placed above and * below the slave */ Blt_Background bg; int ixPad, iyPad; /* Extra padding added to the interior * of the widget (i.e. adds to the * requested size of the widget) */ int fill; /* Indicates how the widget should * fill the span of cells it * occupies. */ int slaveX, slaveY; /* Origin of widget wrt container. */ int slaveWidth, slaveHeight; /* Dimension of slave widget. */ unsigned int flags; Tk_Cursor cursor; /* Current cursor for window or * None. */ int xScrollUnits, yScrollUnits; /* Unit of distance to move when * clicking on the scrollbar * button. */ /* Names of scrollbars to embed into the widget window. */ Tcl_Obj *xScrollbarObjPtr, *yScrollbarObjPtr; /* Commands to control horizontal and vertical scrollbars. */ Tcl_Obj *xReqScrollCmdObjPtr, *yReqScrollCmdObjPtr; Tcl_Obj *xScrollCmdObjPtr, *yScrollCmdObjPtr; /* Commands to control slave's horizontal and vertical views. */ Tcl_Obj *xViewCmdObjPtr, *yViewCmdObjPtr; int xOffset, yOffset; /* Scroll offsets of viewport in * world. */ int worldWidth, worldHeight; /* Dimension of entire menu. */ int cavityWidth, cavityHeight; /* Dimension of entire menu. */ Tk_Window xScrollbar; /* Horizontal scrollbar to be used if * necessary. If NULL, no x-scrollbar * is used. */ Tk_Window yScrollbar; /* Vertical scrollbar to be used if * necessary. If NULL, no y-scrollbar * is used. */ short int xScrollbarWidth, xScrollbarHeight; short int yScrollbarWidth, yScrollbarHeight; short int shangleWidth, shangleHeight; /* * Scanning Information: */ int scanAnchorX; /* Horizontal scan anchor in screen * x-coordinates. */ int scanX; /* x-offset of the start of the * horizontal scan in world * coordinates.*/ int scanAnchorY; /* Vertical scan anchor in screen * y-coordinates. */ int scanY; /* y-offset of the start of the * vertical scan in world * coordinates.*/ short int width, height; } Scrollset; static Blt_OptionParseProc ObjToLimits; static Blt_OptionPrintProc LimitsToObj; static Blt_CustomOption limitsOption = { ObjToLimits, LimitsToObj, NULL, (ClientData)0 }; static Blt_ConfigSpec scrollsetSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_ANCHOR, Blt_Offset(Scrollset, anchor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BACKGROUND, Blt_Offset(Scrollset, bg), 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(Scrollset, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FILL, "-fill", "fill", "Fill", DEF_FILL, Blt_Offset(Scrollset, fill), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(Scrollset, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-ipadx", "iPadX", "IPadX", DEF_IPADX, Blt_Offset(Scrollset, ixPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-ipady", "iPadY", "IPadY", DEF_IPADY, Blt_Offset(Scrollset, iyPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-padx", "padX", "PadX", DEF_PADX, Blt_Offset(Scrollset, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", "padY", "PadY", DEF_PADY, Blt_Offset(Scrollset, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-reqheight", "reqHeight", "ReqHeight", (char *)NULL, Blt_Offset(Scrollset, reqSlaveHeight), 0, &limitsOption}, {BLT_CONFIG_CUSTOM, "-reqwidth", "reqSlaveWidth", "ReqWidth", (char *)NULL, Blt_Offset(Scrollset, reqSlaveWidth), 0, &limitsOption}, {BLT_CONFIG_OBJ, "-xscrollbar", "xScrollbar", "Scrollbar", DEF_XSCROLLBAR, Blt_Offset(Scrollset, xScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_XSCROLLCOMMAND, Blt_Offset(Scrollset, xReqScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_XSCROLLINCREMENT, Blt_Offset(Scrollset, xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-xviewcommand", "xViewCommand", "ViewCommand", DEF_XVIEWCOMMAND, Blt_Offset(Scrollset, xViewCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-yscrollbar", "yScrollbar", "Scrollbar", DEF_YSCROLLBAR, Blt_Offset(Scrollset, yScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", DEF_YSCROLLCOMMAND, Blt_Offset(Scrollset, yReqScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_YSCROLLINCREMENT, Blt_Offset(Scrollset, yScrollUnits),BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yviewcommand", "yViewCommand", "ViewCommand", DEF_YVIEWCOMMAND, Blt_Offset(Scrollset, yViewCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Scrollset, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-window", "window", "Window", DEF_WINDOW, Blt_Offset(Scrollset, slaveObjPtr), BLT_CONFIG_NULL_OK | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Tk_GeomRequestProc ScrollsetGeometryProc; static Tk_GeomLostSlaveProc ScrollsetCustodyProc; static Tk_GeomMgr scrollsetMgrInfo = { (char *)"scrollset", /* Name of geometry manager used by * winfo. */ ScrollsetGeometryProc, /* Procedure to for new geometry * requests. */ ScrollsetCustodyProc, /* Procedure when scrollbar is taken * away. */ }; static Tcl_IdleProc DisplayScrollset; static Tcl_FreeProc DestroyScrollset; static Tk_EventProc WindowEventProc; static Tk_EventProc ScrollsetEventProc; static Tcl_ObjCmdProc ScrollsetInstCmdProc; static Tcl_CmdDeleteProc ScrollsetInstCmdDeletedProc; typedef int (ScrollsetCmdProc)(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the scrollset display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Scrollset *setPtr) { if ((setPtr->tkwin != NULL) && !(setPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayScrollset, setPtr); setPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * ObjToLimits -- * * Converts the list of elements into zero or more pixel values which * determine the range of pixel values possible. An element can be in any * form accepted by Tk_GetPixels. The list has a different meaning based * upon the number of elements. * * # of elements: * * 0 - the limits are reset to the defaults. * 1 - the minimum and maximum values are set to this * value, freezing the range at a single value. * 2 - first element is the minimum, the second is the * maximum. * 3 - first element is the minimum, the second is the * maximum, and the third is the nominal value. * * Any element may be the empty string which indicates the default. * * Results: * The return value is a standard TCL result. The min and max fields * of the range are set. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLimits( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Widget of table */ Tcl_Obj *objPtr, /* New width list */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Limits *limitsPtr = (Limits *)(widgRec + offset); int objc; int limits[3]; int limitsFlags; /* Initialize limits to default values */ limits[2] = LIMITS_NOM; limits[1] = LIMITS_MAX; limits[0] = LIMITS_MIN; limitsFlags = 0; objc = 0; if (objPtr != NULL) { Tcl_Obj **objv; int size; int i; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 3) { Tcl_AppendResult(interp, "wrong # limits \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i++) { const char *string; string = Tcl_GetString(objv[i]); if (string[0] == '\0') { continue; /* Empty string: use default value */ } limitsFlags |= (1 << i); if (Blt_GetPixelsFromObj(interp, tkwin, objv[i], PIXELS_ANY, &size) != TCL_OK) { return TCL_ERROR; } if ((size < LIMITS_MIN) || (size > LIMITS_MAX)) { Tcl_AppendResult(interp, "bad limits \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } limits[i] = size; } } /* * Check the limits specified. */ switch (objc) { case 1: limitsFlags |= (LIMITS_MIN | LIMITS_MAX); limits[1] = limits[0]; /* Set minimum and maximum to value */ break; case 2: if (limits[1] < limits[0]) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } break; case 3: if (limits[1] < limits[0]) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } if ((limits[2] < limits[0]) || (limits[2] > limits[1])) { Tcl_AppendResult(interp, "nominal value \"", Tcl_GetString(objPtr), "\" out of range", (char *)NULL); return TCL_ERROR; /* Nominal is outside of range defined * by minimum and maximum */ } break; } limitsPtr->min = limits[0]; limitsPtr->max = limits[1]; limitsPtr->nom = limits[2]; limitsPtr->flags = limitsFlags; return TCL_OK; } /* *--------------------------------------------------------------------------- * * LimitsToObj -- * * Convert the limits of the pixel values allowed into a list. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LimitsToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { Limits *limitsPtr = (Limits *)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (limitsPtr->flags & LIMITS_MIN) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->min)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (limitsPtr->flags & LIMITS_MAX) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->max)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (limitsPtr->flags & LIMITS_NOM) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(limitsPtr->nom)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } return listObjPtr; } /* *--------------------------------------------------------------------------- * * ResetLimits -- * * Resets the limits to their default values. * * Results: * None. * *--------------------------------------------------------------------------- */ INLINE static void ResetLimits(Limits *limitsPtr) /* Limits to be imposed on the value */ { limitsPtr->flags = 0; limitsPtr->min = LIMITS_MIN; limitsPtr->max = LIMITS_MAX; limitsPtr->nom = LIMITS_NOM; } /* *--------------------------------------------------------------------------- * * TranslateAnchor -- * * Translate the coordinates of a given bounding box based upon the * anchor specified. The anchor indicates where the given xy position is * in relation to the bounding box. * * nw --- n --- ne * | | x,y ---+ * w center e | | * | | +-----+ * sw --- s --- se * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ static void TranslateAnchor( int dx, int dy, /* Difference between outer and inner * regions */ Tk_Anchor anchor, /* Direction of the anchor */ int *xPtr, int *yPtr) { int x, y; x = y = 0; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y = (dy / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ y = dy; break; case TK_ANCHOR_N: /* Top center */ x = (dx / 2); break; case TK_ANCHOR_CENTER: /* Centered */ x = (dx / 2); y = (dy / 2); break; case TK_ANCHOR_S: /* Bottom center */ x = (dx / 2); y = dy; break; case TK_ANCHOR_NE: /* Upper right corner */ x = dx; break; case TK_ANCHOR_E: /* Right center */ x = dx; y = (dy / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ x = dx; y = dy; break; } *xPtr = (*xPtr) + x; *yPtr = (*yPtr) + y; } /* *--------------------------------------------------------------------------- * * GetBoundedWidth -- * * Bounds a given width value to the limits described in the limit * structure. The initial starting value may be overridden by the nominal * value in the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static INLINE int GetBoundedWidth( int width, /* Initial value to be constrained */ Limits *limitsPtr) /* Limits to be imposed on the * value. */ { if (limitsPtr->flags & LIMITS_NOM) { width = limitsPtr->nom; /* Override initial value */ } if (width < limitsPtr->min) { width = limitsPtr->min; /* Bounded by minimum value */ } if (width > limitsPtr->max) { width = limitsPtr->max; /* Bounded by maximum value */ } return width; } /* *--------------------------------------------------------------------------- * * GetBoundedHeight -- * * Bounds a given value to the limits described in the limit structure. * The initial starting value may be overridden by the nominal value in * the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static INLINE int GetBoundedHeight( int height, /* Initial value to be constrained */ Limits *limitsPtr) /* Limits to be imposed on the * value. */ { if (limitsPtr->flags & LIMITS_NOM) { height = limitsPtr->nom; /* Override initial value */ } if (height < limitsPtr->min) { height = limitsPtr->min; /* Bounded by minimum value */ } if (height > limitsPtr->max) { height = limitsPtr->max; /* Bounded by maximum value */ } return height; } /* *--------------------------------------------------------------------------- * * GetSlaveReqWidth -- * * Returns the width requested by the widget starting in the given entry. * The requested space also includes any internal padding which has been * designated for this widget. * * The requested width of the widget is always bounded by the limits set * in tePtr->reqWidth. * * Results: * Returns the requested width of the widget. * *--------------------------------------------------------------------------- */ static INLINE int GetSlaveReqWidth(Scrollset *setPtr) { int width; width = 2 * setPtr->ixPad; if (setPtr->slave != NULL) { width += Tk_ReqWidth(setPtr->slave); } width = GetBoundedWidth(width, &setPtr->reqSlaveWidth); return width; } /* *--------------------------------------------------------------------------- * * GetSlaveReqHeight -- * * Returns the height requested by the widget starting in the given entry. * The requested space also includes any internal padding which has been * designated for this widget. * * The requested height of the widget is always bounded by the limits set * in setPtr->reqSlaveHeight. * * Results: * Returns the requested height of the widget. * *--------------------------------------------------------------------------- */ static INLINE int GetSlaveReqHeight(Scrollset *setPtr) { int height; height = 2 * setPtr->iyPad; if (setPtr->slave != NULL) { height += Tk_ReqHeight(setPtr->slave); } height = GetBoundedHeight(height, &setPtr->reqSlaveHeight); return height; } static void UnmanageWindow(Scrollset *setPtr, Tk_Window tkwin) { Tk_DeleteEventHandler(tkwin, StructureNotifyMask, WindowEventProc, setPtr); Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL, setPtr); if (Tk_IsMapped(tkwin)) { Tk_UnmapWindow(tkwin); } } static void ManageWindow(Scrollset *setPtr, Tk_Window tkwin) { Tk_CreateEventHandler(tkwin, StructureNotifyMask, WindowEventProc, setPtr); Tk_ManageGeometry(tkwin, &scrollsetMgrInfo, setPtr); } /* *--------------------------------------------------------------------------- * * InstallWindow -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InstallWindow( Tcl_Interp *interp, /* Interpreter to send results back * to */ Scrollset *setPtr, Tcl_Obj *objPtr, /* String representing scrollbar * window. */ Tk_Window *tkwinPtr) { Tk_Window tkwin; if (objPtr == NULL) { Tcl_AppendResult(interp, "window name is NULL", (char *)NULL); *tkwinPtr = NULL; return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objPtr), setPtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_Parent(tkwin) != setPtr->tkwin) { Tcl_AppendResult(interp, "window \"", Tk_PathName(tkwin), "\" must be a slave of scrollset.", (char *)NULL); return TCL_ERROR; } ManageWindow(setPtr, tkwin); *tkwinPtr = tkwin; return TCL_OK; } static void InstallXScrollbar(ClientData clientData) { Scrollset *setPtr = clientData; Tcl_Interp *interp; interp = setPtr->interp; setPtr->flags &= ~XSCROLLBAR_PENDING; if (setPtr->tkwin == NULL) { return; /* Widget has been destroyed. */ } if (InstallWindow(interp, setPtr, setPtr->xScrollbarObjPtr, &setPtr->xScrollbar) != TCL_OK) { Tcl_BackgroundError(setPtr->interp); return; } if (setPtr->xScrollCmdObjPtr != NULL) { Tcl_DecrRefCount(setPtr->xScrollCmdObjPtr); setPtr->xScrollCmdObjPtr = NULL; } if (setPtr->xReqScrollCmdObjPtr != NULL) { Tcl_IncrRefCount(setPtr->xReqScrollCmdObjPtr); setPtr->xScrollCmdObjPtr = setPtr->xReqScrollCmdObjPtr; } else { Tcl_Obj *listObjPtr; /* Defaults to "scrollbar set". */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, setPtr->xScrollbarObjPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("set",3)); Tcl_IncrRefCount(listObjPtr); setPtr->xScrollCmdObjPtr = listObjPtr; } } static void InstallYScrollbar(ClientData clientData) { Scrollset *setPtr = clientData; Tcl_Interp *interp; interp = setPtr->interp; setPtr->flags &= ~YSCROLLBAR_PENDING; if (setPtr->tkwin == NULL) { return; /* Widget has been destroyed. */ } if (InstallWindow(interp, setPtr, setPtr->yScrollbarObjPtr, &setPtr->yScrollbar) != TCL_OK) { Tcl_BackgroundError(setPtr->interp); return; } if (setPtr->yScrollCmdObjPtr != NULL) { Tcl_DecrRefCount(setPtr->yScrollCmdObjPtr); setPtr->yScrollCmdObjPtr = NULL; } if (setPtr->yReqScrollCmdObjPtr != NULL) { Tcl_IncrRefCount(setPtr->yReqScrollCmdObjPtr); setPtr->yScrollCmdObjPtr = setPtr->yReqScrollCmdObjPtr; } else { Tcl_Obj *listObjPtr; /* Defaults to "scrollbar set". */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, setPtr->yScrollbarObjPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("set",3)); Tcl_IncrRefCount(listObjPtr); setPtr->yScrollCmdObjPtr = listObjPtr; } } static void InstallSlave(ClientData clientData) { Scrollset *setPtr = clientData; Tcl_Interp *interp; Tcl_Obj *cmdObjPtr; int result; interp = setPtr->interp; setPtr->flags &= ~(SLAVE_PENDING | SLAVE_XVIEW | SLAVE_YVIEW); if (setPtr->tkwin == NULL) { return; /* Widget has been destroyed. */ } if (InstallWindow(interp, setPtr, setPtr->slaveObjPtr, &setPtr->slave) != TCL_OK) { Tcl_BackgroundError(interp); return; } /* Check if the slave widget has a "yview" operation. */ if (setPtr->yViewCmdObjPtr != NULL) { cmdObjPtr = Tcl_DuplicateObj(setPtr->yViewCmdObjPtr); } else { cmdObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, cmdObjPtr, setPtr->slaveObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr,Tcl_NewStringObj("yview",5)); } Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); Tcl_ResetResult(interp); if (result == TCL_OK) { setPtr->flags |= SLAVE_YVIEW; } /* Check if the slave widget has a "xview" operation. */ if (setPtr->xViewCmdObjPtr != NULL) { cmdObjPtr = Tcl_DuplicateObj(setPtr->xViewCmdObjPtr); } else { cmdObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, cmdObjPtr, setPtr->slaveObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr,Tcl_NewStringObj("xview",5)); } Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); Tcl_ResetResult(interp); if (result == TCL_OK) { setPtr->flags |= SLAVE_XVIEW; } } static void UpdateScrollset(ClientData clientData) { Scrollset *setPtr = clientData; Tcl_Interp *interp; interp = setPtr->interp; /* * Execute the initialization procedure on this widget. */ setPtr->flags &= ~UPDATE_PENDING; if (setPtr->tkwin == NULL) { return; /* Widget has been destroyed. */ } if (Tcl_VarEval(interp, "::blt::Scrollset::ConfigureScrollbars ", Tk_PathName(setPtr->tkwin), (char *)NULL) != TCL_OK) { Tcl_BackgroundError(interp); } } static void ComputeSlaveGeometry(Scrollset *setPtr) { int cavityWidth, cavityHeight; int dx, dy; int slaveWidth, slaveHeight; int x, y; cavityWidth = Tk_Width(setPtr->tkwin); cavityHeight = Tk_Height(setPtr->tkwin); #ifdef notdef fprintf(stderr, "ComputeSlaveGeometry: container=%s rw=%d rh=%d w=%d h=%d, slave=%s rw=%d rh=%d w=%d, h=%d\n", Tk_PathName(setPtr->tkwin), Tk_ReqWidth(setPtr->tkwin), Tk_ReqHeight(setPtr->tkwin), Tk_Width(setPtr->tkwin), Tk_Height(setPtr->tkwin), Tk_PathName(setPtr->slave), Tk_ReqWidth(setPtr->slave), Tk_ReqHeight(setPtr->slave), Tk_Width(setPtr->slave), Tk_Height(setPtr->slave)); #endif slaveWidth = GetSlaveReqWidth(setPtr); slaveHeight = GetSlaveReqHeight(setPtr); #ifdef notdef fprintf(stderr, "ComputeSlaveGeometry: slaveWidth=%d slaveHeight=%d, cavityWidth=%d cavityHeight=%d\n", slaveWidth, slaveHeight, cavityWidth, cavityHeight); #endif setPtr->flags &= ~(DISPLAY_X | DISPLAY_Y); if ((setPtr->flags & SLAVE_XVIEW) == 0) { setPtr->worldWidth = slaveWidth; } if ((setPtr->flags & SLAVE_YVIEW) == 0) { setPtr->worldHeight = slaveHeight; } setPtr->xScrollbarHeight = setPtr->yScrollbarWidth = 0; if ((setPtr->xScrollbar != NULL) && (setPtr->worldWidth > cavityWidth)) { setPtr->xScrollbarHeight = Tk_ReqHeight(setPtr->xScrollbar); cavityHeight -= setPtr->xScrollbarHeight; setPtr->flags |= DISPLAY_X; } if ((setPtr->yScrollbar != NULL) && (setPtr->worldHeight > cavityHeight)) { setPtr->yScrollbarWidth = Tk_ReqWidth(setPtr->yScrollbar); cavityWidth -= setPtr->yScrollbarWidth; setPtr->flags |= DISPLAY_Y; } if ((setPtr->xScrollbar != NULL) && (setPtr->xScrollbarHeight == 0) && (setPtr->worldWidth > cavityWidth)) { setPtr->xScrollbarHeight = Tk_ReqHeight(setPtr->xScrollbar); cavityHeight -= setPtr->xScrollbarHeight; setPtr->flags |= DISPLAY_X; } if ((setPtr->yScrollbar != NULL) && (setPtr->yScrollbarWidth == 0) && (setPtr->worldHeight > cavityHeight)) { setPtr->yScrollbarWidth = Tk_ReqWidth(setPtr->yScrollbar); cavityWidth -= setPtr->yScrollbarWidth; setPtr->flags |= DISPLAY_Y; } #ifdef notdef fprintf(stderr, "ComputeSlaveGeometry: 2 cavityWidth=%d, cavityHeight=%d slaveWidth=%d, slaveHeight=%d\n", cavityWidth, cavityHeight, slaveWidth, slaveHeight); #endif dx = dy = 0; if ((cavityWidth - PADDING(setPtr->xPad)) > slaveWidth) { cavityWidth -= PADDING(setPtr->xPad); if (setPtr->fill & FILL_X) { slaveWidth = cavityWidth; if (slaveWidth > setPtr->reqSlaveWidth.max) { slaveWidth = setPtr->reqSlaveWidth.max; } } else { dx = (cavityWidth - slaveWidth); } setPtr->xOffset = 0; } else if (setPtr->flags & SLAVE_XVIEW) { slaveWidth = cavityWidth; } if ((cavityHeight - PADDING(setPtr->yPad)) > slaveHeight) { cavityHeight -= PADDING(setPtr->yPad); if (setPtr->fill & FILL_Y) { slaveHeight = cavityHeight; if (slaveHeight > setPtr->reqSlaveHeight.max) { slaveHeight = setPtr->reqSlaveHeight.max; } } else { dy = (cavityHeight - slaveHeight); } setPtr->yOffset = 0; } else if (setPtr->flags & SLAVE_YVIEW) { slaveHeight = cavityHeight; } x = y = 0; if ((dx > 0) || (dy > 0)) { TranslateAnchor(dx, dy, setPtr->anchor, &x, &y); } #ifdef notdef fprintf(stderr, "ComputeSlaveGeometry: 3 cavityWidth=%d, cavityHeight=%d slaveWidth=%d, slaveHeight=%d\n", cavityWidth, cavityHeight, slaveWidth, slaveHeight); #endif setPtr->shangleHeight = setPtr->xScrollbarHeight; setPtr->shangleWidth = setPtr->yScrollbarWidth; setPtr->yScrollbarHeight = cavityHeight - setPtr->xScrollbarHeight; setPtr->xScrollbarWidth = cavityWidth - setPtr->yScrollbarWidth; if (setPtr->slave != NULL) { if ((setPtr->xScrollbar == NULL) && (slaveWidth > cavityWidth)) { slaveWidth = cavityWidth; if (slaveWidth < setPtr->reqSlaveWidth.min) { slaveWidth = setPtr->reqSlaveWidth.min; } } if ((setPtr->yScrollbar == NULL) && (slaveHeight > cavityHeight)) { slaveHeight = cavityHeight; if (slaveHeight < setPtr->reqSlaveHeight.min) { slaveHeight = setPtr->reqSlaveHeight.min; } } if (cavityWidth > slaveWidth) { x += Tk_Changes(setPtr->slave)->border_width; } else { x = Tk_Changes(setPtr->slave)->border_width; } if (cavityHeight > slaveHeight) { y += Tk_Changes(setPtr->slave)->border_width; } else { y = Tk_Changes(setPtr->slave)->border_width; } } #ifdef notdef fprintf(stderr, "ComputeSlaveGeometry: final cavityWidth=%d, cavityHeight=%d slaveWidth=%d, slaveHeight=%d\n", cavityWidth, cavityHeight, slaveWidth, slaveHeight); #endif setPtr->slaveX = x; setPtr->slaveY = y; setPtr->slaveWidth = slaveWidth; setPtr->slaveHeight = slaveHeight; setPtr->cavityWidth = cavityWidth; setPtr->cavityHeight = cavityHeight; /* Adjust the scroll offsets to put as much of the slave widget in view as * possible. */ if ((setPtr->flags & SLAVE_YVIEW) == 0) { if ((slaveHeight - setPtr->yOffset) < cavityHeight) { setPtr->yOffset = slaveHeight - cavityHeight; } setPtr->flags |= SCROLLY; } if ((setPtr->flags & SLAVE_XVIEW) == 0) { if ((slaveWidth - setPtr->xOffset) < cavityWidth) { setPtr->xOffset = slaveWidth - cavityWidth; } setPtr->flags |= SCROLLX; } setPtr->flags &= ~LAYOUT_PENDING; } static int ConfigureScrollset(Tcl_Interp *interp, Scrollset *setPtr, int objc, Tcl_Obj *const *objv, int flags) { int updateNeeded; if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, scrollsetSpecs, objc, objv, (char *)setPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Install the scrollbars and slave widget at a later time after the * scrollset window has been created. We defer installing the slave and * scrollbars so the scrollbar widgets don't have to exist when they are * specified by the -xscrollbar, -yscrollbar, and -window options * respectively. The down-side is that errors messages will be backgrounded. */ updateNeeded = FALSE; if (Blt_ConfigModified(scrollsetSpecs, "-xscrollbar", (char *)NULL)) { if (setPtr->xScrollbar != NULL) { UnmanageWindow(setPtr, setPtr->xScrollbar); setPtr->xScrollbar = NULL; } if ((setPtr->flags & XSCROLLBAR_PENDING) == 0) { Tcl_DoWhenIdle(InstallXScrollbar, setPtr); setPtr->flags |= XSCROLLBAR_PENDING; } updateNeeded = TRUE; } if (Blt_ConfigModified(scrollsetSpecs, "-yscrollbar", (char *)NULL)) { if (setPtr->yScrollbar != NULL) { UnmanageWindow(setPtr, setPtr->yScrollbar); setPtr->yScrollbar = NULL; } if ((setPtr->flags & YSCROLLBAR_PENDING) == 0) { Tcl_DoWhenIdle(InstallYScrollbar, setPtr); setPtr->flags |= YSCROLLBAR_PENDING; } updateNeeded = TRUE; } if (Blt_ConfigModified(scrollsetSpecs, "-window", (char *)NULL)) { if (setPtr->slave != NULL) { UnmanageWindow(setPtr, setPtr->slave); setPtr->slave = NULL; } if ((setPtr->flags & SLAVE_PENDING) == 0) { Tcl_DoWhenIdle(InstallSlave, setPtr); setPtr->flags |= SLAVE_PENDING; } updateNeeded = TRUE; } if (updateNeeded) { if ((setPtr->flags & UPDATE_PENDING) == 0) { Tcl_DoWhenIdle(UpdateScrollset, setPtr); setPtr->flags |= UPDATE_PENDING; } } return TCL_OK; } /* Widget Callbacks */ /* *--------------------------------------------------------------------------- * * ScrollsetEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * comboentry widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ScrollsetEventProc(ClientData clientData, XEvent *eventPtr) { Scrollset *setPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(setPtr); } } else if (eventPtr->type == ConfigureNotify) { setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } else if (eventPtr->type == DestroyNotify) { if (setPtr->tkwin != NULL) { setPtr->tkwin = NULL; } if (setPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayScrollset, setPtr); } if (setPtr->flags & XSCROLLBAR_PENDING) { Tcl_CancelIdleCall(InstallXScrollbar, setPtr); } if (setPtr->flags & YSCROLLBAR_PENDING) { Tcl_CancelIdleCall(InstallYScrollbar, setPtr); } if (setPtr->flags & SLAVE_PENDING) { Tcl_CancelIdleCall(InstallSlave, setPtr); } if (setPtr->flags & UPDATE_PENDING) { Tcl_CancelIdleCall(UpdateScrollset, setPtr); } Tcl_EventuallyFree(setPtr, DestroyScrollset); } } /* *--------------------------------------------------------------------------- * * WindowEventProc -- * * This procedure is invoked by the Tk event handler when StructureNotify * events occur in a scrollbar managed by the widget. * * Results: * None. * *--------------------------------------------------------------------------- */ static void WindowEventProc( ClientData clientData, /* Pointer to Entry structure for widget * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { Scrollset *setPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(setPtr); } } else if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(setPtr); } else if (eventPtr->type == DestroyNotify) { if ((setPtr->yScrollbar != NULL) && (eventPtr->xany.window == Tk_WindowId(setPtr->yScrollbar))) { setPtr->yScrollbar = NULL; } else if ((setPtr->xScrollbar != NULL) && (eventPtr->xany.window == Tk_WindowId(setPtr->xScrollbar))) { setPtr->xScrollbar = NULL; } else if ((setPtr->slave != NULL) && (eventPtr->xany.window == Tk_WindowId(setPtr->slave))) { setPtr->slave = NULL; } else if ((setPtr->shangle != NULL) && (eventPtr->xany.window == Tk_WindowId(setPtr->shangle))) { setPtr->shangle = NULL; } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } } /* *--------------------------------------------------------------------------- * * ScrollsetCustodyProc -- * * This procedure is invoked when a scrollbar has been stolen by another * geometry manager. * * Results: * None. * * Side effects: * Arranges for the scrollset to have its layout re-arranged at the next * idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollsetCustodyProc(ClientData clientData, Tk_Window tkwin) { Scrollset *setPtr = (Scrollset *)clientData; if (tkwin == setPtr->yScrollbar) { setPtr->yScrollbar = NULL; setPtr->yScrollbarWidth = 0; setPtr->flags &= ~DISPLAY_Y; } else if (tkwin == setPtr->xScrollbar) { setPtr->xScrollbar = NULL; setPtr->xScrollbarHeight = 0; setPtr->flags &= ~DISPLAY_X; } else if (tkwin == setPtr->slave) { setPtr->slave = NULL; setPtr->slaveWidth = setPtr->slaveHeight = 0; setPtr->flags &= ~(DISPLAY_X|DISPLAY_Y); } Tk_UnmaintainGeometry(tkwin, setPtr->tkwin); setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * ScrollsetGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for scrollbars managed * by the scrollset. * * Results: * None. * * Side effects: * Arranges for the scrollset to have its layout re-computed and * re-arranged at the next idle point. * * -------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollsetGeometryProc(ClientData clientData, Tk_Window tkwin) { Scrollset *setPtr = (Scrollset *)clientData; setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } /* Widget Operations */ /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, scrollsetSpecs, (char *)setPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, scrollsetSpecs, (char *)setPtr, objv[2], 0); } Tcl_Preserve(setPtr); result = ConfigureScrollset(interp, setPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(setPtr); if (result == TCL_ERROR) { return TCL_ERROR; } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm cget option * *--------------------------------------------------------------------------- */ static int CgetOp(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, scrollsetSpecs, (char *)setPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * SetOp -- * * Relays the "set" operation from the slave widget to scrollbar. This * routine checks to see if the first/last values are 0 and 1 respectively, * indicating no scrollbar is necessary. This is used for slave widgets * with scrolling capabilities to determine when scrollbars are needed. * * .ss set x first last * .ss set y first last * *--------------------------------------------------------------------------- */ static int SetOp(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *scrollObjPtr; const char *string; unsigned int flag; int useX; string = Tcl_GetString(objv[2]); flag = 0; if ((string[0] == 'x') && (string[1] == '\0')) { scrollObjPtr = setPtr->xScrollbarObjPtr; useX = TRUE; if (setPtr->flags & SLAVE_XVIEW) { flag = DISPLAY_X; } } else if ((string[0] == 'y') && (string[1] == '\0')) { scrollObjPtr = setPtr->yScrollbarObjPtr; useX = FALSE; if (setPtr->flags & SLAVE_YVIEW) { flag = DISPLAY_Y; } } else { Tcl_AppendResult(interp, "bad scrollbar argument: should be x or y", (char *)NULL); return TCL_ERROR; } if (flag != 0) { double first, last; /* Examine the set values from the slave. */ if (Tcl_GetDoubleFromObj(interp, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if ((first <= 0.0) && (last >= 1.0)) { setPtr->flags &= ~flag; /* Hide scrollbar. */ if (useX) { setPtr->worldWidth = 0; } else { setPtr->worldHeight = 0; } } else if (useX) { setPtr->worldWidth = 0; if ((last > first) && (Tk_Width(setPtr->slave) > 1)) { setPtr->worldWidth = (int)((double)Tk_Width(setPtr->slave) / (last - first)); } setPtr->flags |= DISPLAY_X; /* Display y-scrollbar. */ } else { setPtr->worldHeight = 0; if ((last > first) && (Tk_Height(setPtr->slave) > 1)) { setPtr->worldHeight = (int)((double)Tk_Height(setPtr->slave) / (last - first)); } setPtr->flags |= DISPLAY_Y; /* Display y-scrollbar. */ } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } if (scrollObjPtr != NULL) { Tcl_Obj *cmdv[4]; /* Now relay the "set" command to the appropiate scrollbar. */ cmdv[0] = scrollObjPtr; cmdv[1] = Tcl_NewStringObj("set", 3); cmdv[2] = objv[3]; cmdv[3] = objv[4]; if (Blt_GlobalEvalObjv(interp, 4, cmdv) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int XviewOp(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int w; if (setPtr->flags & SLAVE_XVIEW) { Tcl_Obj *cmdObjPtr; int i; int result; /* The slave widget has a "xview" operation. Simply relay the * information on to the slave widget by calling its "xview" * operation. */ if (setPtr->xViewCmdObjPtr != NULL) { cmdObjPtr = Tcl_DuplicateObj(setPtr->xViewCmdObjPtr); } else { cmdObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, cmdObjPtr, setPtr->slaveObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj("xview", 5)); } for (i = 2; i < objc; i++) { Tcl_ListObjAppendElement(interp, cmdObjPtr, objv[i]); } Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); return result; } w = VPORTWIDTH(setPtr); if (objc == 2) { double first, last; Tcl_Obj *listObjPtr; /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ if (setPtr->worldWidth < 1) { first = 0.0, last = 1.0; } else { first = (double)setPtr->xOffset / setPtr->worldHeight; last = (double)(setPtr->xOffset + w) / setPtr->worldWidth; first = FCLAMP(first); last = FCLAMP(last); } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(first)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(last)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &setPtr->xOffset, setPtr->worldWidth, w, setPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } static int YviewOp(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int height; if (setPtr->flags & SLAVE_YVIEW) { Tcl_Obj *cmdObjPtr; int i; int result; /* The slave widget has a "yview" operation. Simply relay the * information on to the slave widget by calling its "yview" * operation. */ if (setPtr->yViewCmdObjPtr != NULL) { cmdObjPtr = Tcl_DuplicateObj(setPtr->yViewCmdObjPtr); } else { cmdObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, cmdObjPtr, setPtr->slaveObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj("yview", 5)); } for (i = 2; i < objc; i++) { Tcl_ListObjAppendElement(interp, cmdObjPtr, objv[i]); } Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); return result; } height = VPORTHEIGHT(setPtr); if (objc == 2) { double fract; /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)setPtr->yOffset / setPtr->worldHeight; Tcl_AppendElement(interp, Blt_Dtoa(interp, FCLAMP(fract))); fract = (double)(setPtr->yOffset + height) / setPtr->worldHeight; Tcl_AppendElement(interp, Blt_Dtoa(interp, FCLAMP(fract))); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &setPtr->yOffset, setPtr->worldHeight, height, setPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyScrollset -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyScrollset(DestroyData dataPtr) /* Pointer to the widget * record. */ { Scrollset *setPtr = (Scrollset *)dataPtr; if (setPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayScrollset, setPtr); } if (setPtr->flags & XSCROLLBAR_PENDING) { Tcl_CancelIdleCall(InstallXScrollbar, setPtr); } if (setPtr->flags & YSCROLLBAR_PENDING) { Tcl_CancelIdleCall(InstallYScrollbar, setPtr); } if (setPtr->flags & SLAVE_PENDING) { Tcl_CancelIdleCall(InstallSlave, setPtr); } if (setPtr->flags & UPDATE_PENDING) { Tcl_CancelIdleCall(UpdateScrollset, setPtr); } Blt_FreeOptions(scrollsetSpecs, (char *)setPtr, setPtr->display, 0); Tcl_DeleteCommandFromToken(setPtr->interp, setPtr->cmdToken); Blt_Free(setPtr); } /* *--------------------------------------------------------------------------- * * NewScrollset -- * *--------------------------------------------------------------------------- */ static Scrollset * NewScrollset(Tcl_Interp *interp, Tk_Window tkwin) { Scrollset *setPtr; setPtr = Blt_AssertCalloc(1, sizeof(Scrollset)); Tk_SetClass(tkwin, "Scrollset"); setPtr->tkwin = tkwin; setPtr->display = Tk_Display(tkwin); setPtr->interp = interp; setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); setPtr->xScrollUnits = 2; setPtr->yScrollUnits = 2; setPtr->anchor = TK_ANCHOR_CENTER; setPtr->fill = FILL_BOTH; ResetLimits(&setPtr->reqSlaveWidth); ResetLimits(&setPtr->reqSlaveHeight); Blt_SetWindowInstanceData(tkwin, setPtr); return setPtr; } /* *--------------------------------------------------------------------------- * * ScrollsetCmd -- * * This procedure is invoked to process the "scrollset" command. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec scrollsetOps[] = { {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"set", 1, SetOp, 5, 5, "x|y first last",}, {"xview", 1, XviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yview", 1, YviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nScrollsetOps = sizeof(scrollsetOps) / sizeof(Blt_OpSpec); typedef int (ScrollsetInstOp)(Scrollset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int ScrollsetInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { ScrollsetInstOp *proc; Scrollset *setPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nScrollsetOps, scrollsetOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(setPtr); result = (*proc) (setPtr, interp, objc, objv); Tcl_Release(setPtr); return result; } /* *--------------------------------------------------------------------------- * * ScrollsetInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ScrollsetInstCmdDeletedProc(ClientData clientData) { Scrollset *setPtr = clientData; /* Pointer to widget record. */ if (setPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = setPtr->tkwin; setPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ScrollsetCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ScrollsetCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Scrollset *setPtr; Tk_Window tkwin; unsigned int mask; Tcl_CmdInfo cmdInfo; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } setPtr = NewScrollset(interp, tkwin); if (ConfigureScrollset(interp, setPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(setPtr->tkwin); return TCL_ERROR; } mask = (ExposureMask | StructureNotifyMask); Tk_CreateEventHandler(tkwin, mask, ScrollsetEventProc, setPtr); setPtr->cmdToken = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), ScrollsetInstCmdProc, setPtr, ScrollsetInstCmdDeletedProc); /* * The shangle is a small window covering the lower-right corner of the * widget that is unobscurred by both the horizontal of vertical * scrollbar. You can pack a widget into it or use "bind" to add * shangle-like resize behaviors. */ setPtr->shangle = Tk_CreateWindow(interp, tkwin, "shangle", (char *)NULL); Tk_CreateEventHandler(setPtr->shangle, mask, WindowEventProc, setPtr); /* * First time in this interpreter, load in a procedure to initialize various * bindings on the scrollset widget. We deferred sourcing the file until * now so that the variable $blt_library can be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Scrollset::ConfigureScrollbars", &cmdInfo)) { if (Tcl_GlobalEval(interp, "source [file join $blt_library scrollset.tcl]") != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_ScrollsetCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "scrollset", ScrollsetCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } static void DrawScrollset(Scrollset *setPtr) { if (setPtr->slave != NULL) { /* * If the widget is too small (i.e. it has only an external border) * then unmap it. */ if ((setPtr->slaveWidth < 1) || (setPtr->slaveHeight < 1)) { if (Tk_IsMapped(setPtr->slave)) { if (setPtr->tkwin != Tk_Parent(setPtr->slave)) { Tk_UnmaintainGeometry(setPtr->slave, setPtr->tkwin); } Tk_UnmapWindow(setPtr->slave); } } else { int x, y; x = setPtr->slaveX; y = setPtr->slaveY; if (setPtr->xOffset > 0) { x -= setPtr->xOffset; } if (setPtr->yOffset > 0) { y -= setPtr->yOffset; } if (setPtr->tkwin != Tk_Parent(setPtr->slave)) { Tk_MaintainGeometry(setPtr->slave, setPtr->tkwin, x, y, setPtr->slaveWidth, setPtr->slaveHeight); } else { if ((x != Tk_X(setPtr->slave)) || (y != Tk_Y(setPtr->slave)) || (setPtr->slaveWidth != Tk_Width(setPtr->slave)) || (setPtr->slaveHeight != Tk_Height(setPtr->slave))) { #ifdef notdef fprintf(stderr, "Slave Resize %s %d,%d %dx%d\n", Tk_PathName(setPtr->slave), x, y, setPtr->slaveWidth, setPtr->slaveHeight); #endif Tk_MoveResizeWindow(setPtr->slave, x, y, setPtr->slaveWidth, setPtr->slaveHeight); } if (!Tk_IsMapped(setPtr->slave)) { Tk_MapWindow(setPtr->slave); } } } } /* Manage the geometry of the scrollbars. */ if (setPtr->yScrollbarWidth > 0) { int x, y; int yScrollbarHeight; x = VPORTWIDTH(setPtr); y = 0; yScrollbarHeight = VPORTHEIGHT(setPtr); if ((Tk_Width(setPtr->yScrollbar) != setPtr->yScrollbarWidth) || (Tk_Height(setPtr->yScrollbar) != yScrollbarHeight) || (x != Tk_X(setPtr->yScrollbar)) || (y != Tk_Y(setPtr->yScrollbar))) { Tk_MoveResizeWindow(setPtr->yScrollbar, x, y, setPtr->yScrollbarWidth, yScrollbarHeight); } if (!Tk_IsMapped(setPtr->yScrollbar)) { Tk_MapWindow(setPtr->yScrollbar); XRaiseWindow(setPtr->display, Tk_WindowId(setPtr->yScrollbar)); } } else if ((setPtr->yScrollbar != NULL) && (Tk_IsMapped(setPtr->yScrollbar))) { Tk_UnmapWindow(setPtr->yScrollbar); } if (setPtr->xScrollbarHeight > 0) { int x, y; int xScrollbarWidth; x = 0; y = VPORTHEIGHT(setPtr); xScrollbarWidth = VPORTWIDTH(setPtr); if ((Tk_Width(setPtr->xScrollbar) != xScrollbarWidth) || (Tk_Height(setPtr->xScrollbar) != setPtr->xScrollbarHeight) || (x != Tk_X(setPtr->xScrollbar)) || (y != Tk_Y(setPtr->xScrollbar))) { Tk_MoveResizeWindow(setPtr->xScrollbar, x, y, xScrollbarWidth, setPtr->xScrollbarHeight); } if (!Tk_IsMapped(setPtr->xScrollbar)) { Tk_MapWindow(setPtr->xScrollbar); XRaiseWindow(setPtr->display, Tk_WindowId(setPtr->xScrollbar)); } } else if ((setPtr->xScrollbar != NULL) && (Tk_IsMapped(setPtr->xScrollbar))) { Tk_UnmapWindow(setPtr->xScrollbar); } if ((setPtr->yScrollbarWidth > 0) && (setPtr->xScrollbarHeight > 0)) { int shangleX, shangleY; int shangleWidth, shangleHeight; shangleX = VPORTWIDTH(setPtr); shangleY = VPORTHEIGHT(setPtr); shangleWidth = setPtr->yScrollbarWidth; shangleHeight = setPtr->xScrollbarHeight; if ((shangleX != Tk_X(setPtr->shangle)) || (shangleY != Tk_Y(setPtr->shangle)) || (shangleWidth != Tk_Width(setPtr->shangle)) || (shangleHeight != Tk_Height(setPtr->shangle))) { Tk_MoveResizeWindow(setPtr->shangle, shangleX, shangleY, shangleWidth, shangleHeight); } if (!Tk_IsMapped(setPtr->shangle)) { Tk_MapWindow(setPtr->shangle); XRaiseWindow(setPtr->display, Tk_WindowId(setPtr->shangle)); } Blt_FillBackgroundRectangle(setPtr->shangle, Tk_WindowId(setPtr->shangle), setPtr->bg, 0, 0, shangleWidth, shangleHeight, 0, TK_RELIEF_FLAT); } else { Tk_UnmapWindow(setPtr->shangle); } } /* *--------------------------------------------------------------------------- * * DisplayScrollset -- * * This procedure is invoked to display a scrollset widget. * * Results: * None. * * Side effects: * Commands are output to X to display the menu. * *--------------------------------------------------------------------------- */ static void DisplayScrollset(ClientData clientData) { Scrollset *setPtr = clientData; int reqWidth, reqHeight; setPtr->flags &= ~REDRAW_PENDING; if (setPtr->tkwin == NULL) { return; /* Window destroyed (should not get * here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayScrollset(%s)\n", Tk_PathName(setPtr->tkwin)); #endif /* * The request size of the host container is always the requested * size of the slave widget without scrollbars. Only when the size * of the window is less than the requested size to we add scrollbars * (non-scrolling widgets). */ reqWidth = (setPtr->reqWidth > 0) ? setPtr->reqWidth : GetSlaveReqWidth(setPtr); reqHeight = (setPtr->reqHeight > 0) ? setPtr->reqHeight : GetSlaveReqHeight(setPtr); if ((reqWidth != Tk_ReqWidth(setPtr->tkwin)) || (reqHeight != Tk_ReqHeight(setPtr->tkwin))) { #ifdef notdef fprintf(stderr, "DisplayScrollset: %s geometry request = %dx%d\n", Tk_PathName(setPtr->tkwin), reqWidth, reqHeight); #endif Tk_GeometryRequest(setPtr->tkwin, reqWidth, reqHeight); } if ((Tk_Width(setPtr->tkwin) <= 1) || (Tk_Height(setPtr->tkwin) <= 1)){ /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (setPtr->flags & LAYOUT_PENDING) { ComputeSlaveGeometry(setPtr); } if (!Tk_IsMapped(setPtr->tkwin)) { /* The scrollset's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the scrollset's new layout. */ return; } if (setPtr->flags & SCROLL_PENDING) { int w, h; /* * The view port has changed. The scrollbars need to be updated. */ w = VPORTWIDTH(setPtr); h = VPORTHEIGHT(setPtr); if ((setPtr->xScrollCmdObjPtr != NULL) && (setPtr->flags & SCROLLX)) { Blt_UpdateScrollbar(setPtr->interp, setPtr->xScrollCmdObjPtr, setPtr->xOffset, setPtr->xOffset + w, setPtr->worldWidth); } if ((setPtr->yScrollCmdObjPtr != NULL) && (setPtr->flags & SCROLLY)) { Blt_UpdateScrollbar(setPtr->interp, setPtr->yScrollCmdObjPtr, setPtr->yOffset, setPtr->yOffset + h, setPtr->worldHeight); } setPtr->flags &= ~SCROLL_PENDING; } if ((setPtr->slaveWidth < VPORTWIDTH(setPtr)) || (setPtr->slaveHeight < VPORTHEIGHT(setPtr))) { Blt_FillBackgroundRectangle(setPtr->tkwin, Tk_WindowId(setPtr->tkwin), setPtr->bg, 0, 0, VPORTWIDTH(setPtr), VPORTHEIGHT(setPtr), 0, TK_RELIEF_FLAT); } DrawScrollset(setPtr); } ���������������������������������������./saods9/blt3.0.1/src/bltTable.c��������������������������������������������������������������������0000644�0001750�0001750�00000443142�11462120062�014732� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTable.c -- * * This module implements a table-based geometry manager for the BLT toolkit. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * To do: * * 3) No way to detect if widget is already a container of another geometry * manager. This one is especially bad with toplevel widgets, causing the * window manager to lock-up trying to handle the myriads of resize requests. * * Note: This problem continues in Tk 8.x. It's possible for a widget * to be a container for two different geometry managers. Each manager * will set its own requested geometry for the container widget. The * winner sets the geometry last (sometimes ad infinitum). * * 7) Relative sizing of partitions? * */ #include "bltInt.h" #include "bltOp.h" #include "bltSwitch.h" #include "bltTable.h" #define TABLE_THREAD_KEY "BLT Table Data" #define TABLE_DEF_PAD 0 /* * Default values for widget attributes. */ #define DEF_TABLE_ANCHOR "center" #define DEF_TABLE_COLUMNS "0" #define DEF_TABLE_FILL "none" #define DEF_TABLE_PAD "0" #define DEF_TABLE_PROPAGATE "1" #define DEF_TABLE_RESIZE "both" #define DEF_TABLE_ROWS "0" #define DEF_TABLE_SPAN "1" #define DEF_TABLE_CONTROL "normal" #define DEF_TABLE_WEIGHT "1.0" #define ENTRY_DEF_PAD 0 #define ENTRY_DEF_ANCHOR TK_ANCHOR_CENTER #define ENTRY_DEF_FILL FILL_NONE #define ENTRY_DEF_SPAN 1 #define ENTRY_DEF_CONTROL CONTROL_NORMAL #define ENTRY_DEF_IPAD 0 #define ROWCOL_DEF_RESIZE (RESIZE_BOTH | RESIZE_VIRGIN) #define ROWCOL_DEF_PAD 0 #define ROWCOL_DEF_WEIGHT 1.0 #define MATCH_PATTERN (1<<0) /* Find widgets whose path names * match a given pattern */ #define MATCH_SPAN (1<<1) /* Find widgets that span index */ #define MATCH_START (1<<2) /* Find widgets that start at index */ static Blt_Uid rowUid, columnUid; static Tk_GeomRequestProc WidgetGeometryProc; static Tk_GeomLostSlaveProc WidgetCustodyProc; static Tk_GeomMgr tableMgrInfo = { (char *)"table", /* Name of geometry manager used by winfo */ WidgetGeometryProc, /* Procedure to for new geometry requests */ WidgetCustodyProc, /* Procedure when widget is taken away */ }; static Blt_OptionParseProc ObjToLimits; static Blt_OptionPrintProc LimitsToObj; static Blt_CustomOption limitsOption = { ObjToLimits, LimitsToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToControl; static Blt_OptionPrintProc ControlToObj; static Blt_CustomOption controlOption = { ObjToControl, ControlToObj, NULL, (ClientData)0 }; static Blt_ConfigSpec rowConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-height", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(RowColumn, reqSize), 0, &limitsOption}, {BLT_CONFIG_PAD, "-pady", (char *)NULL, (char *)NULL, DEF_TABLE_PAD, Blt_Offset(RowColumn, pad), BLT_CONFIG_DONT_SET_DEFAULT, }, {BLT_CONFIG_RESIZE, "-resize", (char *)NULL, (char *)NULL, DEF_TABLE_RESIZE, Blt_Offset(RowColumn, resize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-weight", (char *)NULL, (char *)NULL, DEF_TABLE_WEIGHT, Blt_Offset(RowColumn, weight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec columnConfigSpecs[] = { {BLT_CONFIG_PAD, "-padx", (char *)NULL, (char *)NULL, DEF_TABLE_PAD, Blt_Offset(RowColumn, pad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RESIZE, "-resize", (char *)NULL, (char *)NULL, DEF_TABLE_RESIZE, Blt_Offset(RowColumn, resize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-weight", (char *)NULL, (char *)NULL, DEF_TABLE_WEIGHT, Blt_Offset(RowColumn, weight), BLT_CONFIG_DONT_SET_DEFAULT, &limitsOption}, {BLT_CONFIG_CUSTOM, "-width", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(RowColumn, reqSize), 0, &limitsOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec entryConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", (char *)NULL, (char *)NULL, DEF_TABLE_ANCHOR, Blt_Offset(TableEntry, anchor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT, "-columnspan", "columnSpan", (char *)NULL, DEF_TABLE_SPAN, Blt_Offset(TableEntry, column.span), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-columncontrol", "columnControl", (char *)NULL, DEF_TABLE_CONTROL, Blt_Offset(TableEntry, column.control), BLT_CONFIG_DONT_SET_DEFAULT, &controlOption}, {BLT_CONFIG_SYNONYM, "-cspan", "columnSpan", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, column.span), 0}, {BLT_CONFIG_SYNONYM, "-ccontrol", "columnControl", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, column.control), 0}, {BLT_CONFIG_FILL, "-fill", (char *)NULL, (char *)NULL, DEF_TABLE_FILL, Blt_Offset(TableEntry, fill), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-height", "reqHeight", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, reqHeight), 0}, {BLT_CONFIG_PAD, "-padx", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, xPad), 0}, {BLT_CONFIG_PAD, "-pady", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, yPad), 0}, {BLT_CONFIG_PIXELS_NNEG, "-ipadx", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, ixPad), 0}, {BLT_CONFIG_PIXELS_NNEG, "-ipady", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, iyPad), 0}, {BLT_CONFIG_CUSTOM, "-reqheight", "reqHeight", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, reqHeight), 0, &limitsOption}, {BLT_CONFIG_CUSTOM, "-reqwidth", "reqWidth", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, reqWidth), 0, &limitsOption}, {BLT_CONFIG_INT, "-rowspan", "rowSpan", (char *)NULL, DEF_TABLE_SPAN, Blt_Offset(TableEntry, row.span), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-rowcontrol", "rowControl", (char *)NULL, DEF_TABLE_CONTROL, Blt_Offset(TableEntry, row.control), BLT_CONFIG_DONT_SET_DEFAULT, &controlOption}, {BLT_CONFIG_SYNONYM, "-rspan", "rowSpan", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, row.span), 0}, {BLT_CONFIG_SYNONYM, "-rcontrol", "rowControl", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, row.control), 0}, {BLT_CONFIG_SYNONYM, "-width", "reqWidth", (char *)NULL, (char *)NULL, Blt_Offset(TableEntry, reqWidth), 0}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec tableConfigSpecs[] = { {BLT_CONFIG_PAD, "-padx", (char *)NULL, (char *)NULL, DEF_TABLE_PAD, Blt_Offset(Table, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", (char *)NULL, (char *)NULL, DEF_TABLE_PAD, Blt_Offset(Table, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-propagate", (char *)NULL, (char *)NULL, DEF_TABLE_PROPAGATE, Blt_Offset(Table, propagate), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-reqheight", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Table, reqHeight), 0, &limitsOption}, {BLT_CONFIG_CUSTOM, "-reqwidth", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Table, reqWidth), 0, &limitsOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_SwitchParseProc ObjToPosition; static Blt_SwitchCustom positionSwitch = { ObjToPosition, NULL, 0, }; typedef struct { int rspan, cspan; int rstart, cstart; int flags; const char *pattern; Table *tablePtr; } SearchSwitches; static Blt_SwitchSpec searchSwitches[] = { {BLT_SWITCH_STRING, "-pattern", "pattern", Blt_Offset(SearchSwitches, pattern), 0, 0,}, {BLT_SWITCH_CUSTOM, "-span", "int", 0, 0, 0, &positionSwitch}, {BLT_SWITCH_CUSTOM, "-start", "position", 0, 0, 0, &positionSwitch}, {BLT_SWITCH_END} }; typedef struct { const char *pattern; const char *slave; } NamesSwitches; static Blt_SwitchSpec namesSwitches[] = { {BLT_SWITCH_STRING, "-pattern", "pattern", Blt_Offset(NamesSwitches, pattern), 0, 0,}, {BLT_SWITCH_STRING, "-slave", "widget", Blt_Offset(NamesSwitches, slave), 0, 0}, {BLT_SWITCH_END} }; /* * Forward declarations */ static Tcl_FreeProc DestroyTable; static Tcl_IdleProc ArrangeTable; static Tcl_InterpDeleteProc TableInterpDeleteProc; static Tcl_ObjCmdProc TableCmd; static Tk_EventProc TableEventProc; static Tk_EventProc WidgetEventProc; static void DestroyEntry(TableEntry * tePtr); static void BinEntry(Table *tablePtr, TableEntry * tePtr); static RowColumn *InitSpan(PartitionInfo * piPtr, int start, int span); static int ParseItem(Table *tablePtr, const char *string, int *rowPtr, int *colPtr); static EntrySearchProc FindEntry; typedef int (TableCmdProc)(TableInterpData *dataPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * ObjToLimits -- * * Converts the list of elements into zero or more pixel values which * determine the range of pixel values possible. An element can be in * any form accepted by Tk_GetPixels. The list has a different meaning * based upon the number of elements. * * # of elements: * * 0 - the limits are reset to the defaults. * 1 - the minimum and maximum values are set to this * value, freezing the range at a single value. * 2 - first element is the minimum, the second is the * maximum. * 3 - first element is the minimum, the second is the * maximum, and the third is the nominal value. * * Any element may be the empty string which indicates the default. * * Results: * The return value is a standard TCL result. The min and max fields * of the range are set. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLimits( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Widget of table */ Tcl_Obj *objPtr, /* New width list */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Limits *limitsPtr = (Limits *)(widgRec + offset); const char **argv; int argc; int limArr[3]; Tk_Window winArr[3]; int limitsFlags; argv = NULL; argc = 0; /* Initialize limits to default values */ limArr[2] = LIMITS_NOM; limArr[1] = LIMITS_MAX; limArr[0] = LIMITS_MIN; winArr[0] = winArr[1] = winArr[2] = NULL; limitsFlags = 0; if (objPtr != NULL) { int size; int i; const char *string; string = Tcl_GetString(objPtr); if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { return TCL_ERROR; } if (argc > 3) { Tcl_AppendResult(interp, "wrong # limits \"", string, "\"", (char *)NULL); goto error; } for (i = 0; i < argc; i++) { if (argv[i][0] == '\0') { continue; /* Empty string: use default value */ } limitsFlags |= (LIMITS_SET_BIT << i); if ((argv[i][0] == '.') && ((argv[i][1] == '\0') || isalpha(UCHAR(argv[i][1])))) { Tk_Window tkwin2; /* Widget specified: save pointer to widget */ tkwin2 = Tk_NameToWindow(interp, argv[i], tkwin); if (tkwin2 == NULL) { goto error; } winArr[i] = tkwin2; } else { if (Tk_GetPixels(interp, tkwin, argv[i], &size) != TCL_OK) { goto error; } if ((size < LIMITS_MIN) || (size > LIMITS_MAX)) { Tcl_AppendResult(interp, "bad limits \"", string, "\"", (char *)NULL); goto error; } limArr[i] = size; } } Blt_Free(argv); } /* * Check the limits specified. We can't check the requested * size of widgets. */ switch (argc) { case 1: limitsFlags |= (LIMITS_SET_MIN | LIMITS_SET_MAX); if (winArr[0] == NULL) { limArr[1] = limArr[0]; /* Set minimum and maximum to value */ } else { winArr[1] = winArr[0]; } break; case 2: if ((winArr[0] == NULL) && (winArr[1] == NULL) && (limArr[1] < limArr[0])) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } break; case 3: if ((winArr[0] == NULL) && (winArr[1] == NULL)) { if (limArr[1] < limArr[0]) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } if ((winArr[2] == NULL) && ((limArr[2] < limArr[0]) || (limArr[2] > limArr[1]))) { Tcl_AppendResult(interp, "nominal value \"", Tcl_GetString(objPtr), "\" out of range", (char *)NULL); return TCL_ERROR; /* Nominal is outside of range defined * by minimum and maximum */ } } break; } limitsPtr->min = limArr[0]; limitsPtr->max = limArr[1]; limitsPtr->nom = limArr[2]; limitsPtr->wMin = winArr[0]; limitsPtr->wMax = winArr[1]; limitsPtr->wNom = winArr[2]; limitsPtr->flags = limitsFlags; return TCL_OK; error: Blt_Free(argv); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ResetLimits -- * * Resets the limits to their default values. * * Results: * None. * *--------------------------------------------------------------------------- */ INLINE static void ResetLimits(Limits *limitsPtr) /* Limits to be imposed on the value */ { limitsPtr->flags = 0; limitsPtr->min = LIMITS_MIN; limitsPtr->max = LIMITS_MAX; limitsPtr->nom = LIMITS_NOM; limitsPtr->wNom = limitsPtr->wMax = limitsPtr->wMin = NULL; } /* *--------------------------------------------------------------------------- * * GetBoundedWidth -- * * Bounds a given width value to the limits described in the limit * structure. The initial starting value may be overridden by the * nominal value in the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedWidth( int width, /* Initial value to be constrained */ Limits *limitsPtr) /* Limits to be imposed on the value */ { /* * Check widgets for requested width values; */ if (limitsPtr->wMin != NULL) { limitsPtr->min = Tk_ReqWidth(limitsPtr->wMin); } if (limitsPtr->wMax != NULL) { limitsPtr->max = Tk_ReqWidth(limitsPtr->wMax); } if (limitsPtr->wNom != NULL) { limitsPtr->nom = Tk_ReqWidth(limitsPtr->wNom); } if (limitsPtr->flags & LIMITS_SET_NOM) { width = limitsPtr->nom; /* Override initial value */ } if (width < limitsPtr->min) { width = limitsPtr->min; /* Bounded by minimum value */ } else if (width > limitsPtr->max) { width = limitsPtr->max; /* Bounded by maximum value */ } return width; } /* *--------------------------------------------------------------------------- * * GetBoundedHeight -- * * Bounds a given value to the limits described in the limit structure. * The initial starting value may be overridden by the nominal value in * the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedHeight( int height, /* Initial value to be constrained */ Limits *limitsPtr) /* Limits to be imposed on the value */ { /* * Check widgets for requested height values; */ if (limitsPtr->wMin != NULL) { limitsPtr->min = Tk_ReqHeight(limitsPtr->wMin); } if (limitsPtr->wMax != NULL) { limitsPtr->max = Tk_ReqHeight(limitsPtr->wMax); } if (limitsPtr->wNom != NULL) { limitsPtr->nom = Tk_ReqHeight(limitsPtr->wNom); } if (limitsPtr->flags & LIMITS_SET_NOM) { height = limitsPtr->nom;/* Override initial value */ } if (height < limitsPtr->min) { height = limitsPtr->min;/* Bounded by minimum value */ } else if (height > limitsPtr->max) { height = limitsPtr->max;/* Bounded by maximum value */ } return height; } /* *--------------------------------------------------------------------------- * * NameOfLimits -- * * Convert the values into a list representing the limits. * * Results: * The static string representation of the limits is returned. * *--------------------------------------------------------------------------- */ static const char * NameOfLimits(Limits *limitsPtr) { Tcl_DString buffer; #define STRING_SPACE 200 static char string[STRING_SPACE + 1]; Tcl_DStringInit(&buffer); if (limitsPtr->wMin != NULL) { Tcl_DStringAppendElement(&buffer, Tk_PathName(limitsPtr->wMin)); } else if (limitsPtr->flags & LIMITS_SET_MIN) { Tcl_DStringAppendElement(&buffer, Blt_Itoa(limitsPtr->min)); } else { Tcl_DStringAppendElement(&buffer, ""); } if (limitsPtr->wMax != NULL) { Tcl_DStringAppendElement(&buffer, Tk_PathName(limitsPtr->wMax)); } else if (limitsPtr->flags & LIMITS_SET_MAX) { Tcl_DStringAppendElement(&buffer, Blt_Itoa(limitsPtr->max)); } else { Tcl_DStringAppendElement(&buffer, ""); } if (limitsPtr->wNom != NULL) { Tcl_DStringAppendElement(&buffer, Tk_PathName(limitsPtr->wNom)); } else if (limitsPtr->flags & LIMITS_SET_NOM) { Tcl_DStringAppendElement(&buffer, Blt_Itoa(limitsPtr->nom)); } else { Tcl_DStringAppendElement(&buffer, ""); } strncpy(string, Tcl_DStringValue(&buffer), STRING_SPACE); string[STRING_SPACE] = '\0'; return string; } /* *--------------------------------------------------------------------------- * * LimitsToObj -- * * Convert the limits of the pixel values allowed into a list. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LimitsToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { Limits *limitsPtr = (Limits *)(widgRec + offset); return Tcl_NewStringObj(NameOfLimits(limitsPtr), -1); } /* *--------------------------------------------------------------------------- * * ObjToControl -- * * Converts the control string into its numeric representation. Valid * control strings are "none", "normal", and "full". * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToControl( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Control style string */ char *widgRec, /* Entry structure record */ int offset, /* Offset to field in structure */ int flags) { const char *string; char c; float *controlPtr = (float *)(widgRec + offset); int bool; int length; if (Tcl_GetBooleanFromObj(NULL, objPtr, &bool) == TCL_OK) { *controlPtr = bool; return TCL_OK; } string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (length > 1) && (strncmp(string, "normal", length) == 0)) { *controlPtr = CONTROL_NORMAL; } else if ((c == 'n') && (length > 1) && (strncmp(string, "none", length) == 0)) { *controlPtr = CONTROL_NONE; } else if ((c == 'f') && (strncmp(string, "full", length) == 0)) { *controlPtr = CONTROL_FULL; } else { double control; if ((Tcl_GetDoubleFromObj(interp, objPtr, &control) != TCL_OK) || (control < 0.0)) { Tcl_AppendResult(interp, "bad control argument \"", string, "\": should be \"normal\", \"none\", or \"full\"", (char *)NULL); return TCL_ERROR; } *controlPtr = (float)control; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NameOfControl -- * * Converts the control value into its string representation. * * Results: * Returns a pointer to the static name string. * *--------------------------------------------------------------------------- */ static const char * NameOfControl(float control) { if (control == CONTROL_NORMAL) { return "normal"; } else if (control == CONTROL_NONE) { return "none"; } else if (control == CONTROL_FULL) { return "full"; } else { static char string[TCL_DOUBLE_SPACE]; sprintf_s(string, TCL_DOUBLE_SPACE, "%g", (double)control); return string; } } /* *--------------------------------------------------------------------------- * * ControlToObj -- * * Returns control mode string based upon the control flags. * * Results: * The control mode string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ControlToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { float control = *(float *)(widgRec + offset); return Tcl_NewStringObj(NameOfControl(control), -1); } /* *--------------------------------------------------------------------------- * * ObjToPosition -- * * Converts the position mode into its numeric representation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPosition( ClientData clientData, /* Flag indicating if the node is considered * before or after the insertion position. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { SearchSwitches *searchPtr = (SearchSwitches *)record; int row, column; if (ParseItem(searchPtr->tablePtr, Tcl_GetString(objPtr), &row, &column) != TCL_OK) { return TCL_ERROR; } if (strcmp(switchName, "-span") == 0) { searchPtr->flags |= MATCH_SPAN; searchPtr->rspan = row; searchPtr->cspan = column; } else if (strcmp(switchName, "-start") == 0) { searchPtr->flags |= MATCH_START; searchPtr->rstart = row; searchPtr->cstart = column; } return TCL_OK; } static void EventuallyArrangeTable(Table *tablePtr) { if (!(tablePtr->flags & ARRANGE_PENDING)) { tablePtr->flags |= ARRANGE_PENDING; Tcl_DoWhenIdle(ArrangeTable, tablePtr); } } /* *--------------------------------------------------------------------------- * * TableEventProc -- * * This procedure is invoked by the Tk event handler when the container * widget is reconfigured or destroyed. * * The table will be rearranged at the next idle point if the container * widget has been resized or moved. There's a distinction made between * parent and non-parent container arrangements. When the container is * the parent of the embedded widgets, the widgets will automatically * keep their positions relative to the container, even when the * container is moved. But if the container is not the parent, those * widgets have to be moved manually. This can be a performance hit in * rare cases where we're scrolling the container (by moving the window) * and there are lots of non-child widgets arranged inside. * * Results: * None. * * Side effects: * Arranges for the table associated with tkwin to have its layout * re-computed and drawn at the next idle point. * *--------------------------------------------------------------------------- */ static void TableEventProc( ClientData clientData, /* Information about widget */ XEvent *eventPtr) /* Information about event */ { Table *tablePtr = clientData; if (eventPtr->type == ConfigureNotify) { if ((tablePtr->container.width != Tk_Width(tablePtr->tkwin)) || (tablePtr->container.height != Tk_Height(tablePtr->tkwin)) || (tablePtr->flags & NON_PARENT)) { EventuallyArrangeTable(tablePtr); } } else if (eventPtr->type == DestroyNotify) { if (tablePtr->flags & ARRANGE_PENDING) { Tcl_CancelIdleCall(ArrangeTable, tablePtr); } tablePtr->tkwin = NULL; Tcl_EventuallyFree(tablePtr, DestroyTable); } } /* *--------------------------------------------------------------------------- * * WidgetEventProc -- * * This procedure is invoked by the Tk event handler when StructureNotify * events occur in a widget managed by the table. * * For example, when a managed widget is destroyed, it frees the * corresponding entry structure and arranges for the table layout to be * re-computed at the next idle point. * * Results: * None. * * Side effects: * If the managed widget was deleted, the Entry structure gets cleaned up * and the table is rearranged. * *--------------------------------------------------------------------------- */ static void WidgetEventProc( ClientData clientData, /* Pointer to Entry structure for widget * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { TableEntry *tePtr = (TableEntry *) clientData; Table *tablePtr = tePtr->tablePtr; if (eventPtr->type == ConfigureNotify) { int borderWidth; tablePtr->flags |= REQUEST_LAYOUT; borderWidth = Tk_Changes(tePtr->tkwin)->border_width; if (tePtr->borderWidth != borderWidth) { tePtr->borderWidth = borderWidth; EventuallyArrangeTable(tablePtr); } } else if (eventPtr->type == DestroyNotify) { tePtr->tkwin = NULL; DestroyEntry(tePtr); tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); } } /* *--------------------------------------------------------------------------- * * WidgetCustodyProc -- * * This procedure is invoked when a widget has been stolen by another * geometry manager. The information and memory associated with the * widget is released. * * Results: * None. * * Side effects: * Arranges for the table to have its layout re-arranged at the next idle * point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void WidgetCustodyProc( ClientData clientData, /* Information about the widget */ Tk_Window tkwin) /* Not used. */ { TableEntry *tePtr = (TableEntry *) clientData; Table *tablePtr = tePtr->tablePtr; if (Tk_IsMapped(tePtr->tkwin)) { Tk_UnmapWindow(tePtr->tkwin); } Tk_UnmaintainGeometry(tePtr->tkwin, tablePtr->tkwin); tePtr->tkwin = NULL; DestroyEntry(tePtr); tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); } /* *--------------------------------------------------------------------------- * * WidgetGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for widgets managed by * the table geometry manager. * * Results: * None. * * Side effects: * Arranges for the table to have its layout re-computed and re-arranged * at the next idle point. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ static void WidgetGeometryProc( ClientData clientData, /* Information about widget that got new * preferred geometry. */ Tk_Window tkwin) /* Other Tk-related information about the * widget. */ { TableEntry *tePtr = (TableEntry *) clientData; tePtr->tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tePtr->tablePtr); } /* *--------------------------------------------------------------------------- * * FindEntry -- * * Searches for the table entry corresponding to the given widget. * * Results: * If a structure associated with the widget exists, a pointer to that * structure is returned. Otherwise NULL. * *--------------------------------------------------------------------------- */ static TableEntry * FindEntry( Table *tablePtr, Tk_Window tkwin) /* Widget associated with table entry */ { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&tablePtr->entryTable, (char *)tkwin); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } static int GetEntry(Tcl_Interp *interp, Table *tablePtr, const char *string, TableEntry **tePtrPtr) { Tk_Window tkwin; TableEntry *tePtr; tkwin = Tk_NameToWindow(interp, string, tablePtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } tePtr = FindEntry(tablePtr, tkwin); if (tePtr == NULL) { Tcl_AppendResult(interp, "\"", Tk_PathName(tkwin), "\" is not managed by any table", (char *)NULL); return TCL_ERROR; } *tePtrPtr = tePtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateEntry -- * * This procedure creates and initializes a new Entry structure to hold a * widget. A valid widget has a parent widget that is either a) the * container widget itself or b) a mutual ancestor of the container * widget. * * Results: * Returns a pointer to the new structure describing the new widget * entry. If an error occurred, then the return value is NULL and an * error message is left in interp->result. * * Side effects: * Memory is allocated and initialized for the Entry structure. * * ---------------------------------------------------------------------------- */ static TableEntry * CreateEntry( Table *tablePtr, Tk_Window tkwin) { TableEntry *tePtr; int dummy; Tk_Window parent, ancestor; /* * Check that this widget can be managed by this table. A valid widget * has a parent widget that either * * 1) is the container widget, or * 2) is a mutual ancestor of the container widget. */ ancestor = Tk_Parent(tkwin); for (parent = tablePtr->tkwin; (parent != ancestor) && (!Tk_IsTopLevel(parent)); parent = Tk_Parent(parent)) { /* empty */ } if (ancestor != parent) { Tcl_AppendResult(tablePtr->interp, "can't manage \"", Tk_PathName(tkwin), "\" in table \"", Tk_PathName(tablePtr->tkwin), "\"", (char *)NULL); return NULL; } tePtr = Blt_AssertCalloc(1, sizeof(TableEntry)); /* Initialize the entry structure */ tePtr->tkwin = tkwin; tePtr->tablePtr = tablePtr; tePtr->borderWidth = Tk_Changes(tkwin)->border_width; tePtr->fill = ENTRY_DEF_FILL; tePtr->row.control = tePtr->column.control = ENTRY_DEF_CONTROL; tePtr->anchor = ENTRY_DEF_ANCHOR; tePtr->row.span = tePtr->column.span = ENTRY_DEF_SPAN; ResetLimits(&tePtr->reqWidth); ResetLimits(&tePtr->reqHeight); /* * Add the entry to the following data structures. * * 1) A chain of widgets managed by the table. * 2) A hash table of widgets managed by the table. */ tePtr->link = Blt_Chain_Append(tablePtr->chain, tePtr); tePtr->hashPtr = Blt_CreateHashEntry(&tablePtr->entryTable, (char *)tkwin, &dummy); Blt_SetHashValue(tePtr->hashPtr, tePtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, WidgetEventProc, tePtr); Tk_ManageGeometry(tkwin, &tableMgrInfo, (ClientData)tePtr); return tePtr; } /* *--------------------------------------------------------------------------- * * DestroyEntry -- * * Removes the Entry structure from the hash table and frees the memory * allocated by it. If the table is still in use (i.e. was not called * from DestoryTable), remove its entries from the lists of row and * column sorted partitions. * * Results: * None. * * Side effects: * Everything associated with the entry is freed up. * *--------------------------------------------------------------------------- */ static void DestroyEntry(TableEntry *tePtr) { Table *tablePtr = tePtr->tablePtr; if (tePtr->row.link != NULL) { Blt_Chain_DeleteLink(tePtr->row.chain, tePtr->row.link); } if (tePtr->column.link != NULL) { Blt_Chain_DeleteLink(tePtr->column.chain, tePtr->column.link); } if (tePtr->link != NULL) { Blt_Chain_DeleteLink(tablePtr->chain, tePtr->link); } if (tePtr->tkwin != NULL) { Tk_DeleteEventHandler(tePtr->tkwin, StructureNotifyMask, WidgetEventProc, (ClientData)tePtr); Tk_ManageGeometry(tePtr->tkwin, (Tk_GeomMgr *)NULL, (ClientData)tePtr); if ((tablePtr->tkwin != NULL) && (Tk_Parent(tePtr->tkwin) != tablePtr->tkwin)) { Tk_UnmaintainGeometry(tePtr->tkwin, tablePtr->tkwin); } if (Tk_IsMapped(tePtr->tkwin)) { Tk_UnmapWindow(tePtr->tkwin); } } if (tePtr->hashPtr != NULL) { Blt_DeleteHashEntry(&tablePtr->entryTable, tePtr->hashPtr); } Blt_Free(tePtr); } /* *--------------------------------------------------------------------------- * * ConfigureEntry -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) one or more * entries. Entries hold information about widgets managed by the table * geometry manager. * * Note: You can query only one widget at a time. But several can be * reconfigured at once. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * The table layout is recomputed and rearranged at the next idle point. * *--------------------------------------------------------------------------- */ static int ConfigureEntry(Table *tablePtr, Tcl_Interp *interp, TableEntry *tePtr, int objc, Tcl_Obj *const *objv) { int oldRowSpan, oldColSpan; if (tePtr->tablePtr != tablePtr) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(tePtr->tkwin), "\" does not belong to table \"", Tk_PathName(tablePtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (objc == 0) { return Blt_ConfigureInfoFromObj(interp, tePtr->tkwin, entryConfigSpecs, (char *)tePtr, (Tcl_Obj *)NULL, 0); } else if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, tePtr->tkwin, entryConfigSpecs, (char *)tePtr, objv[0], 0); } oldRowSpan = tePtr->row.span; oldColSpan = tePtr->column.span; if (Blt_ConfigureWidgetFromObj(interp, tePtr->tkwin, entryConfigSpecs, objc, objv, (char *)tePtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if ((tePtr->column.span < 1) || (tePtr->column.span > USHRT_MAX)) { Tcl_AppendResult(interp, "bad column span specified for \"", Tk_PathName(tePtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if ((tePtr->row.span < 1) || (tePtr->row.span > USHRT_MAX)) { Tcl_AppendResult(interp, "bad row span specified for \"", Tk_PathName(tePtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if ((oldColSpan != tePtr->column.span) || (oldRowSpan != tePtr->row.span)) { BinEntry(tablePtr, tePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PrintEntry -- * * Returns the name, position and options of a widget in the table. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void PrintEntry(TableEntry *tePtr, Tcl_DString *resultPtr) { char string[200]; sprintf_s(string, 200, " %d,%d ", tePtr->row.rcPtr->index, tePtr->column.rcPtr->index); Tcl_DStringAppend(resultPtr, string, -1); Tcl_DStringAppend(resultPtr, Tk_PathName(tePtr->tkwin), -1); if (tePtr->ixPad != ENTRY_DEF_PAD) { Tcl_DStringAppend(resultPtr, " -ipadx ", -1); Tcl_DStringAppend(resultPtr, Blt_Itoa(tePtr->ixPad), -1); } if (tePtr->iyPad != ENTRY_DEF_PAD) { Tcl_DStringAppend(resultPtr, " -ipady ", -1); Tcl_DStringAppend(resultPtr, Blt_Itoa(tePtr->iyPad), -1); } if (tePtr->row.span != ENTRY_DEF_SPAN) { Tcl_DStringAppend(resultPtr, " -rowspan ", -1); Tcl_DStringAppend(resultPtr, Blt_Itoa(tePtr->row.span), -1); } if (tePtr->column.span != ENTRY_DEF_SPAN) { Tcl_DStringAppend(resultPtr, " -columnspan ", -1); Tcl_DStringAppend(resultPtr, Blt_Itoa(tePtr->column.span), -1); } if (tePtr->anchor != ENTRY_DEF_ANCHOR) { Tcl_DStringAppend(resultPtr, " -anchor ", -1); Tcl_DStringAppend(resultPtr, Tk_NameOfAnchor(tePtr->anchor), -1); } if ((tePtr->padLeft != ENTRY_DEF_PAD) || (tePtr->padRight != ENTRY_DEF_PAD)) { Tcl_DStringAppend(resultPtr, " -padx ", -1); sprintf_s(string, 200, "{%d %d}", tePtr->padLeft, tePtr->padRight); Tcl_DStringAppend(resultPtr, string, -1); } if ((tePtr->padTop != ENTRY_DEF_PAD) || (tePtr->padBottom != ENTRY_DEF_PAD)) { Tcl_DStringAppend(resultPtr, " -pady ", -1); sprintf_s(string, 200, "{%d %d}", tePtr->padTop, tePtr->padBottom); Tcl_DStringAppend(resultPtr, string, -1); } if (tePtr->fill != ENTRY_DEF_FILL) { Tcl_DStringAppend(resultPtr, " -fill ", -1); Tcl_DStringAppend(resultPtr, Blt_NameOfFill(tePtr->fill), -1); } if (tePtr->column.control != ENTRY_DEF_CONTROL) { Tcl_DStringAppend(resultPtr, " -columncontrol ", -1); Tcl_DStringAppend(resultPtr, NameOfControl(tePtr->column.control), -1); } if (tePtr->row.control != ENTRY_DEF_CONTROL) { Tcl_DStringAppend(resultPtr, " -rowcontrol ", -1); Tcl_DStringAppend(resultPtr, NameOfControl(tePtr->row.control), -1); } if ((tePtr->reqWidth.nom != LIMITS_NOM) || (tePtr->reqWidth.min != LIMITS_MIN) || (tePtr->reqWidth.max != LIMITS_MAX)) { Tcl_DStringAppend(resultPtr, " -reqwidth {", -1); Tcl_DStringAppend(resultPtr, NameOfLimits(&tePtr->reqWidth), -1); Tcl_DStringAppend(resultPtr, "}", -1); } if ((tePtr->reqHeight.nom != LIMITS_NOM) || (tePtr->reqHeight.min != LIMITS_MIN) || (tePtr->reqHeight.max != LIMITS_MAX)) { Tcl_DStringAppend(resultPtr, " -reqheight {", -1); Tcl_DStringAppend(resultPtr, NameOfLimits(&tePtr->reqHeight), -1); Tcl_DStringAppend(resultPtr, "}", -1); } } /* *--------------------------------------------------------------------------- * * InfoEntry -- * * Returns the name, position and options of a widget in the table. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InfoEntry(Tcl_Interp *interp, Table *tablePtr, TableEntry *tePtr) { Tcl_DString dString; if (tePtr->tablePtr != tablePtr) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(tePtr->tkwin), "\" does not belong to table \"", Tk_PathName(tablePtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } Tcl_DStringInit(&dString); PrintEntry(tePtr, &dString); Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateRowColumn -- * * Creates and initializes a structure that manages the size of a row or * column in the table. There will be one of these structures allocated * for each row and column in the table, regardless if a widget is * contained in it or not. * * Results: * Returns a pointer to the newly allocated row or column structure. * *--------------------------------------------------------------------------- */ static RowColumn * CreateRowColumn(void) { RowColumn *rcPtr; rcPtr = Blt_AssertMalloc(sizeof(RowColumn)); rcPtr->resize = ROWCOL_DEF_RESIZE; ResetLimits(&rcPtr->reqSize); rcPtr->nom = LIMITS_NOM; rcPtr->pad.side1 = rcPtr->pad.side2 = ROWCOL_DEF_PAD; rcPtr->size = rcPtr->index = rcPtr->minSpan = 0; rcPtr->weight = ROWCOL_DEF_WEIGHT; return rcPtr; } static PartitionInfo * ParseRowColumn2(Table *tablePtr, const char *string, int *numberPtr) { char c; int n; PartitionInfo *piPtr; c = tolower(string[0]); if (c == 'c') { piPtr = &tablePtr->cols; } else if (c == 'r') { piPtr = &tablePtr->rows; } else { Tcl_AppendResult(tablePtr->interp, "bad index \"", string, "\": must start with \"r\" or \"c\"", (char *)NULL); return NULL; } /* Handle row or column configuration queries */ if (Tcl_GetInt(tablePtr->interp, string + 1, &n) != TCL_OK) { return NULL; } *numberPtr = (int)n; return piPtr; } static PartitionInfo * ParseRowColumn(Table *tablePtr, Tcl_Obj *objPtr, int *numberPtr) { int n; PartitionInfo *piPtr; const char *string; string = Tcl_GetString(objPtr); piPtr = ParseRowColumn2(tablePtr, string, &n); if (piPtr == NULL) { return NULL; } if ((n < 0) || (n >= Blt_Chain_GetLength(piPtr->chain))) { Tcl_AppendResult(tablePtr->interp, "bad ", piPtr->type, " index \"", string, "\"", (char *)NULL); return NULL; } *numberPtr = (int)n; return piPtr; } /* *--------------------------------------------------------------------------- * * GetRowColumn -- * * Gets the designated row or column from the table. If the row or * column index is greater than the size of the table, new rows/columns * will be automatically allocated. * * Results: * Returns a pointer to the row or column structure. * *--------------------------------------------------------------------------- */ static RowColumn * GetRowColumn(PartitionInfo *piPtr, int n) { Blt_ChainLink link; int i; for (i = Blt_Chain_GetLength(piPtr->chain); i <= n; i++) { RowColumn *rcPtr; rcPtr = CreateRowColumn(); rcPtr->index = i; rcPtr->link = Blt_Chain_Append(piPtr->chain, (ClientData)rcPtr); } link = Blt_Chain_GetNthLink(piPtr->chain, n); if (link == NULL) { return NULL; } return Blt_Chain_GetValue(link); } /* *--------------------------------------------------------------------------- * * DeleteRowColumn -- * * Deletes a span of rows/columns from the table. The number of * rows/columns to be deleted is given by span. * * Results: * None. * * Side effects: * The size of the column partition array may be extended and * initialized. * *--------------------------------------------------------------------------- */ static void DeleteRowColumn( Table *tablePtr, PartitionInfo *piPtr, RowColumn *rcPtr) { /* * Remove any entries that start in the row/column to be deleted. They * point to memory that will be freed. */ if (piPtr->type == rowUid) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = next) { TableEntry *tePtr; next = Blt_Chain_NextLink(link); tePtr = Blt_Chain_GetValue(link); if (tePtr->row.rcPtr->index == rcPtr->index) { DestroyEntry(tePtr); } } } else { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = next) { TableEntry *tePtr; next = Blt_Chain_NextLink(link); tePtr = Blt_Chain_GetValue(link); if (tePtr->column.rcPtr->index == rcPtr->index) { DestroyEntry(tePtr); } } } } /* *--------------------------------------------------------------------------- * * ConfigureRowColumn -- * * This procedure is called to process an objv/objc list in order to * configure a row or column in the table geometry manager. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result holds an error message. * * Side effects: * Partition configuration options (bounds, resize flags, etc) get set. * New partitions may be created as necessary. The table is recalculated * and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int ConfigureRowColumn(Table *tablePtr, PartitionInfo *piPtr, const char *pattern, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link; int nMatches; nMatches = 0; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; char string[200]; rcPtr = Blt_Chain_GetValue(link); sprintf_s(string, 200, "%c%d", pattern[0], rcPtr->index); if (Tcl_StringMatch(string, pattern)) { if (objc == 0) { return Blt_ConfigureInfoFromObj(tablePtr->interp, tablePtr->tkwin, piPtr->configSpecs, (char *)rcPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 1) { return Blt_ConfigureInfoFromObj(tablePtr->interp, tablePtr->tkwin, piPtr->configSpecs, (char *)rcPtr, objv[0], 0); } else { if (Blt_ConfigureWidgetFromObj(tablePtr->interp, tablePtr->tkwin, piPtr->configSpecs, objc, objv, (char *)rcPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } } nMatches++; } } if (nMatches == 0) { int n; RowColumn *rcPtr; /* * We found no existing partitions matching this pattern, so see if * this designates an new partition (one beyond the current range). */ if ((Tcl_GetInt(NULL, pattern + 1, &n) != TCL_OK) || (n < 0)) { Tcl_AppendResult(tablePtr->interp, "pattern \"", pattern, "\" matches no ", piPtr->type, " in table \"", Tk_PathName(tablePtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } rcPtr = GetRowColumn(piPtr, n); assert(rcPtr); if (Blt_ConfigureWidgetFromObj(tablePtr->interp, tablePtr->tkwin, piPtr->configSpecs, objc, objv, (char *)rcPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } } EventuallyArrangeTable(tablePtr); return TCL_OK; } static void PrintRowColumn( Tcl_Interp *interp, PartitionInfo *piPtr, RowColumn *rcPtr, Tcl_DString *resultPtr) { char string[200]; const char *padFmt, *sizeFmt; if (piPtr->type == rowUid) { padFmt = " -pady {%d %d}"; sizeFmt = " -height {%s}"; } else { padFmt = " -padx {%d %d}"; sizeFmt = " -width {%s}"; } if (rcPtr->resize != ROWCOL_DEF_RESIZE) { Tcl_DStringAppend(resultPtr, " -resize ", -1); Tcl_DStringAppend(resultPtr, Blt_NameOfResize(rcPtr->resize), -1); } if ((rcPtr->pad.side1 != ROWCOL_DEF_PAD) || (rcPtr->pad.side2 != ROWCOL_DEF_PAD)) { sprintf_s(string, 200, padFmt, rcPtr->pad.side1, rcPtr->pad.side2); Tcl_DStringAppend(resultPtr, string, -1); } if (rcPtr->weight != ROWCOL_DEF_WEIGHT) { Tcl_DStringAppend(resultPtr, " -weight ", -1); Tcl_DStringAppend(resultPtr, Blt_Dtoa(interp, rcPtr->weight), -1); } if ((rcPtr->reqSize.min != LIMITS_MIN) || (rcPtr->reqSize.nom != LIMITS_NOM) || (rcPtr->reqSize.max != LIMITS_MAX)) { sprintf_s(string, 200, sizeFmt, NameOfLimits(&rcPtr->reqSize)); Tcl_DStringAppend(resultPtr, string, -1); } } /* *--------------------------------------------------------------------------- * * InfoRowColumn -- * * Returns the options of a partition in the table. * * Results: * Returns a standard TCL result. A list of the partition * attributes is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InfoRowColumn(Table *tablePtr, Tcl_Interp *interp, const char *pattern) { PartitionInfo *piPtr; char c; Blt_ChainLink link, last; Tcl_DString dString; c = pattern[0]; if ((c == 'r') || (c == 'R')) { piPtr = &tablePtr->rows; } else { piPtr = &tablePtr->cols; } Tcl_DStringInit(&dString); last = Blt_Chain_LastLink(piPtr->chain); for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; char string[200]; rcPtr = Blt_Chain_GetValue(link); sprintf_s(string, 200, "%c%d", piPtr->type[0], rcPtr->index); if (Tcl_StringMatch(string, pattern)) { Tcl_DStringAppend(&dString, string, -1); PrintRowColumn(interp, piPtr, rcPtr, &dString); if (link != last) { Tcl_DStringAppend(&dString, " \\\n", -1); } else { Tcl_DStringAppend(&dString, "\n", -1); } } } Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InitSpan -- * * Checks the size of the column partitions and extends the size if a * larger array is needed. * * Results: * Always return a RowColumn pointer. * * Side effects: * The size of the column partition array may be extended and * initialized. * *--------------------------------------------------------------------------- */ static RowColumn * InitSpan(PartitionInfo *piPtr, int start, int span) { int length; int i; Blt_ChainLink link; length = Blt_Chain_GetLength(piPtr->chain); for (i = length; i < (start + span); i++) { RowColumn *rcPtr; rcPtr = CreateRowColumn(); rcPtr->index = i; rcPtr->link = Blt_Chain_Append(piPtr->chain, (ClientData)rcPtr); } link = Blt_Chain_GetNthLink(piPtr->chain, start); return Blt_Chain_GetValue(link); } /* *--------------------------------------------------------------------------- * * Blt_GetTableFromObj -- * * Searches for a table associated by the path name of the widget * container. * * Errors may occur because * 1) pathName isn't a valid for any Tk widget, or * 2) there's no table associated with that widget as a container. * * Results: * If a table entry exists, a pointer to the Table structure is * returned. Otherwise NULL is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_GetTableFromObj( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ Tcl_Obj *objPtr, /* Path name of the container widget. */ Table **tablePtrPtr) { Blt_HashEntry *hPtr; Tk_Window tkwin; const char *pathName; pathName = Tcl_GetString(objPtr); tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(&dataPtr->tableTable, (char *)tkwin); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "no table associated with widget \"", pathName, "\"", (char *)NULL); } return TCL_ERROR; } *tablePtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateTable -- * * This procedure creates and initializes a new Table structure with * tkwin as its container widget. The internal structures associated with * the table are initialized. * * Results: * Returns the pointer to the new Table structure describing the new * table geometry manager. If an error occurred, the return value will * be NULL and an error message is left in interp->result. * * Side effects: * Memory is allocated and initialized, an event handler is set up to * watch tkwin, etc. * *--------------------------------------------------------------------------- */ static Table * CreateTable( TableInterpData *dataPtr, Tcl_Interp *interp, /* Interpreter associated with table. */ const char *pathName) /* Path name of the container widget to be * associated with the new table. */ { Table *tablePtr; Tk_Window tkwin; int dummy; Blt_HashEntry *hPtr; tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return NULL; } tablePtr = Blt_AssertCalloc(1, sizeof(Table)); tablePtr->tkwin = tkwin; tablePtr->interp = interp; tablePtr->rows.type = rowUid; tablePtr->rows.configSpecs = rowConfigSpecs; tablePtr->rows.chain = Blt_Chain_Create(); tablePtr->cols.type = columnUid; tablePtr->cols.configSpecs = columnConfigSpecs; tablePtr->cols.chain = Blt_Chain_Create(); tablePtr->propagate = TRUE; tablePtr->arrangeProc = ArrangeTable; Blt_InitHashTable(&tablePtr->entryTable, BLT_ONE_WORD_KEYS); tablePtr->findEntryProc = FindEntry; ResetLimits(&tablePtr->reqWidth); ResetLimits(&tablePtr->reqHeight); tablePtr->chain = Blt_Chain_Create(); tablePtr->rows.list = Blt_List_Create(BLT_ONE_WORD_KEYS); tablePtr->cols.list = Blt_List_Create(BLT_ONE_WORD_KEYS); Tk_CreateEventHandler(tablePtr->tkwin, StructureNotifyMask, TableEventProc, (ClientData)tablePtr); hPtr = Blt_CreateHashEntry(&dataPtr->tableTable, (char *)tkwin, &dummy); tablePtr->hashPtr = hPtr; tablePtr->tablePtr = &dataPtr->tableTable; Blt_SetHashValue(hPtr, (ClientData)tablePtr); return tablePtr; } /* *--------------------------------------------------------------------------- * * ConfigureTable -- * * This procedure is called to process an objv/objc list in order to * configure the table geometry manager. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Table configuration options (-padx, -pady, etc.) get set. The table * is recalculated and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int ConfigureTable( Table *tablePtr, /* Table to be configured */ Tcl_Interp *interp, /* Interpreter to report results back to */ int objc, Tcl_Obj *const *objv) /* Option-value pairs */ { if (objc == 0) { return Blt_ConfigureInfoFromObj(interp, tablePtr->tkwin, tableConfigSpecs, (char *)tablePtr, (Tcl_Obj *)NULL, 0); } else if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, tablePtr->tkwin, tableConfigSpecs, (char *)tablePtr, objv[0], 0); } if (Blt_ConfigureWidgetFromObj(interp, tablePtr->tkwin, tableConfigSpecs, objc, objv, (char *)tablePtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } /* Arrange for the table layout to be computed at the next idle point. */ tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); return TCL_OK; } static void PrintTable( Table *tablePtr, Tcl_DString *resultPtr) { char string[200]; if ((tablePtr->padLeft != TABLE_DEF_PAD) || (tablePtr->padRight != TABLE_DEF_PAD)) { sprintf_s(string, 200, " -padx {%d %d}", tablePtr->padLeft, tablePtr->padRight); Tcl_DStringAppend(resultPtr, string, -1); } if ((tablePtr->padTop != TABLE_DEF_PAD) || (tablePtr->padBottom != TABLE_DEF_PAD)) { sprintf_s(string, 200, " -pady {%d %d}", tablePtr->padTop, tablePtr->padBottom); Tcl_DStringAppend(resultPtr, string, -1); } if (!tablePtr->propagate) { Tcl_DStringAppend(resultPtr, " -propagate no", -1); } if ((tablePtr->reqWidth.min != LIMITS_MIN) || (tablePtr->reqWidth.nom != LIMITS_NOM) || (tablePtr->reqWidth.max != LIMITS_MAX)) { Tcl_DStringAppend(resultPtr, " -reqwidth {%s}", -1); Tcl_DStringAppend(resultPtr, NameOfLimits(&tablePtr->reqWidth), -1); } if ((tablePtr->reqHeight.min != LIMITS_MIN) || (tablePtr->reqHeight.nom != LIMITS_NOM) || (tablePtr->reqHeight.max != LIMITS_MAX)) { Tcl_DStringAppend(resultPtr, " -reqheight {%s}", -1); Tcl_DStringAppend(resultPtr, NameOfLimits(&tablePtr->reqHeight), -1); } } /* *--------------------------------------------------------------------------- * * DestroyPartitions -- * * Clear each of the lists managing the entries. The entries in the * lists of row and column spans are themselves lists which need to be * cleared. * *--------------------------------------------------------------------------- */ static void DestroyPartitions(PartitionInfo *piPtr) { if (piPtr->list != NULL) { Blt_ListNode node; for (node = Blt_List_FirstNode(piPtr->list); node != NULL; node = Blt_List_NextNode(node)) { Blt_Chain chain; chain = Blt_List_GetValue(node); if (chain != NULL) { Blt_Chain_Destroy(chain); } } Blt_List_Destroy(piPtr->list); } if (piPtr->chain != NULL) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); Blt_Free(rcPtr); } Blt_Chain_Destroy(piPtr->chain); } } /* *--------------------------------------------------------------------------- * * DestroyTable -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the Table structure at a safe time (when no-one is using it * anymore). * * Results: * None. * * Side effects: * Everything associated with the table geometry manager is freed up. * *--------------------------------------------------------------------------- */ static void DestroyTable(DestroyData dataPtr) /* Table structure */ { Blt_ChainLink link; Table *tablePtr = (Table *)dataPtr; /* Release the chain of entries. */ for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; tePtr = Blt_Chain_GetValue(link); tePtr->link = NULL; /* Don't disrupt this chain of entries */ DestroyEntry(tePtr); } Blt_Chain_Destroy(tablePtr->chain); DestroyPartitions(&tablePtr->rows); DestroyPartitions(&tablePtr->cols); Blt_DeleteHashTable(&tablePtr->entryTable); if (tablePtr->hashPtr != NULL) { Blt_DeleteHashEntry(tablePtr->tablePtr, tablePtr->hashPtr); } Blt_Free(tablePtr); } /* *--------------------------------------------------------------------------- * * BinEntry -- * * Adds the entry to the lists of both row and column spans. The layout * of the table is done in order of partition spans, from shorted to * longest. The widgets spanning a particular number of partitions are * stored in a linked list. Each list is in turn, contained within a * master list. * * Results: * None. * * Side effects: * The entry is added to both the lists of row and columns spans. This * will effect the layout of the widgets. * *--------------------------------------------------------------------------- */ static void BinEntry(Table *tablePtr, TableEntry *tePtr) { Blt_ListNode node; Blt_List list; Blt_Chain chain; long key; /* * Remove the entry from both row and column lists. It will be * re-inserted into the table at the new position. */ if (tePtr->column.link != NULL) { Blt_Chain_UnlinkLink(tePtr->column.chain, tePtr->column.link); } if (tePtr->row.link != NULL) { Blt_Chain_UnlinkLink(tePtr->row.chain, tePtr->row.link); } list = tablePtr->rows.list; key = 0; /* Initialize key to bogus span */ for (node = Blt_List_FirstNode(list); node != NULL; node = Blt_List_NextNode(node)) { key = (long)Blt_List_GetKey(node); if (tePtr->row.span <= key) { break; } } if (key != tePtr->row.span) { Blt_ListNode newNode; /* * Create a new list (bucket) to hold entries of that size span and * and link it into the list of buckets. */ newNode = Blt_List_CreateNode(list, (char *)tePtr->row.span); Blt_List_SetValue(newNode, (char *)Blt_Chain_Create()); Blt_List_LinkBefore(list, newNode, node); node = newNode; } chain = Blt_List_GetValue(node); if (tePtr->row.link == NULL) { tePtr->row.link = Blt_Chain_Append(chain, tePtr); } else { Blt_Chain_LinkAfter(chain, tePtr->row.link, NULL); } tePtr->row.chain = chain; list = tablePtr->cols.list; key = 0; for (node = Blt_List_FirstNode(list); node != NULL; node = Blt_List_NextNode(node)) { key = (long)Blt_List_GetKey(node); if (tePtr->column.span <= key) { break; } } if (key != tePtr->column.span) { Blt_ListNode newNode; /* * Create a new list (bucket) to hold entries of that size span and * and link it into the list of buckets. */ newNode = Blt_List_CreateNode(list, (char *)tePtr->column.span); Blt_List_SetValue(newNode, (char *)Blt_Chain_Create()); Blt_List_LinkBefore(list, newNode, node); node = newNode; } chain = Blt_List_GetValue(node); /* Add the new entry to the span bucket */ if (tePtr->column.link == NULL) { tePtr->column.link = Blt_Chain_Append(chain, tePtr); } else { Blt_Chain_LinkAfter(chain, tePtr->column.link, NULL); } tePtr->column.chain = chain; } /* *--------------------------------------------------------------------------- * * ParseIndex -- * * Parse the entry index string and return the row and column numbers in * their respective parameters. The format of a table entry index is * row,column where row is the row number and column is the column * number. Rows and columns are numbered starting from zero. * * Results: * Returns a standard TCL result. If TCL_OK is returned, the row and * column numbers are returned via rowPtr and columnPtr respectively. * *--------------------------------------------------------------------------- */ static int ParseIndex(Tcl_Interp *interp, const char *string, int *rowPtr, int *columnPtr) { char *comma; long row, column; int result; comma = (char *)strchr(string, ','); if (comma == NULL) { Tcl_AppendResult(interp, "bad index \"", string, "\": should be \"row,column\"", (char *)NULL); return TCL_ERROR; } *comma = '\0'; result = ((Tcl_ExprLong(interp, string, &row) != TCL_OK) || (Tcl_ExprLong(interp, comma + 1, &column) != TCL_OK)); *comma = ','; /* Repair the argument */ if (result) { return TCL_ERROR; } if ((row < 0) || (row > (long)USHRT_MAX)) { Tcl_AppendResult(interp, "bad index \"", string, "\": row is out of range", (char *)NULL); return TCL_ERROR; } if ((column < 0) || (column > (long)USHRT_MAX)) { Tcl_AppendResult(interp, "bad index \"", string, "\": column is out of range", (char *)NULL); return TCL_ERROR; } *rowPtr = (int)row; *columnPtr = (int)column; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ManageEntry -- * * Inserts the given widget into the table at a given row and column * position. The widget can already be managed by this or another table. * The widget will be simply moved to the new location in this table. * * The new widget is inserted into both a hash table (this is used to * locate the information associated with the widget) and a list (used to * indicate relative ordering of widgets). * * Results: * Returns a standard TCL result. If an error occurred, TCL_ERROR is * returned and an error message is left in interp->result. * * Side Effects: * The table is re-computed and arranged at the next idle point. * * ---------------------------------------------------------------------------- */ static int ManageEntry( Tcl_Interp *interp, Table *tablePtr, Tk_Window tkwin, int row, int column, int objc, Tcl_Obj *const *objv) { TableEntry *tePtr; int result = TCL_OK; tePtr = FindEntry(tablePtr, tkwin); if ((tePtr != NULL) && (tePtr->tablePtr != tablePtr)) { /* The entry for the widget already exists. If it's managed by another * table, delete it. */ DestroyEntry(tePtr); tePtr = NULL; } if (tePtr == NULL) { tePtr = CreateEntry(tablePtr, tkwin); if (tePtr == NULL) { return TCL_ERROR; } } if (objc > 0) { result = Blt_ConfigureWidgetFromObj(tablePtr->interp, tePtr->tkwin, entryConfigSpecs, objc, objv, (char *)tePtr, BLT_CONFIG_OBJV_ONLY); } if ((tePtr->column.span < 1) || (tePtr->row.span < 1)) { Tcl_AppendResult(tablePtr->interp, "bad span specified for \"", Tk_PathName(tkwin), "\"", (char *)NULL); DestroyEntry(tePtr); return TCL_ERROR; } tePtr->column.rcPtr = InitSpan(&tablePtr->cols, column, tePtr->column.span); tePtr->row.rcPtr = InitSpan(&tablePtr->rows, row, tePtr->row.span); /* Insert the entry into both the row and column layout lists */ BinEntry(tablePtr, tePtr); return result; } /* *--------------------------------------------------------------------------- * * BuildTable -- * * Processes an objv/objc list of table entries to add and configure new * widgets into the table. A table entry consists of the widget path * name, table index, and optional configuration options. The first * argument in the objv list is the name of the table. If no table * exists for the given widget, a new one is created. * * Results: * Returns a standard TCL result. If an error occurred, * TCL_ERROR is returned and an error message is left in * interp->result. * * Side Effects: * Memory is allocated, a new table is possibly created, etc. * The table is re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int BuildTable( Table *tablePtr, /* Table to manage new widgets */ Tcl_Interp *interp, /* Interpreter to report errors back to */ int objc, /* */ Tcl_Obj *const *objv) /* List of widgets, indices, and options */ { Tk_Window tkwin; int row, column; int nextRow, nextColumn; int i; /* Process any options specific to the table */ for (i = 2; i < objc; i += 2) { const char *string; string = Tcl_GetString(objv[i]); if (string[0] != '-') { break; } } if (i > objc) { i = objc; } if (i > 2) { if (ConfigureTable(tablePtr, interp, i - 2, objv + 2) != TCL_OK) { return TCL_ERROR; } } nextRow = tablePtr->nRows; nextColumn = 0; objc -= i, objv += i; while (objc > 0) { const char *string; /* * Allow the name of the widget and row/column index to be specified * in any order. */ string = Tcl_GetString(objv[0]); if (string[0] == '.') { tkwin = Tk_NameToWindow(interp, string, tablePtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (objc == 1) { /* No row,column index, use defaults instead */ row = nextRow, column = nextColumn; objc--, objv++; } else { string = Tcl_GetString(objv[1]); if (string[0] == '-') { /* No row,column index, use defaults instead */ row = nextRow, column = nextColumn; objc--, objv++; } else { if (ParseIndex(interp, string, &row, &column) != TCL_OK) { return TCL_ERROR; /* Invalid row,column index */ } /* Skip over the widget pathname and table index. */ objc -= 2, objv += 2; } } } else { if (ParseIndex(interp, Tcl_GetString(objv[0]), &row, &column) != TCL_OK) { return TCL_ERROR; } if (objc == 1) { Tcl_AppendResult(interp, "missing widget pathname after \"", Tcl_GetString(objv[0]), "\"", (char *)NULL); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tablePtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } /* Skip over the widget pathname and table index. */ objc -= 2, objv += 2; } /* Find the end of the widget's option-value pairs */ for (i = 0; i < objc; i += 2) { string = Tcl_GetString(objv[i]); if (string[0] != '-') { break; } } if (i > objc) { i = objc; } if (ManageEntry(interp, tablePtr, tkwin, row, column, i, objv) != TCL_OK) { return TCL_ERROR; } nextColumn = column + 1; objc -= i, objv += i; } /* Arrange for the new table layout to be calculated. */ tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tablePtr->tkwin),-1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ParseItem -- * * Parses a string representing an item in the table. An item may be one * of the following: * Rn - Row index, where n is the index of row * Cn - Column index, where n is the index of column * r,c - Cell index, where r is the row index and c * is the column index. * * Results: * Returns a standard TCL result. If no error occurred, TCL_OK is * returned. *RowPtr* will return the row index. *ColumnPtr* will * return the column index. If the row or column index is not * applicable, -1 is returned via *rowPtr* or *columnPtr*. * *--------------------------------------------------------------------------- */ static int ParseItem(Table *tablePtr, const char *string, int *rowPtr, int *columnPtr) { char c; long partNum; c = tolower(string[0]); *rowPtr = *columnPtr = -1; if (c == 'r') { if (Tcl_ExprLong(tablePtr->interp, string + 1, &partNum) != TCL_OK) { return TCL_ERROR; } if ((partNum < 0) || (partNum >= tablePtr->nRows)) { Tcl_AppendResult(tablePtr->interp, "row index \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } *rowPtr = (int)partNum; } else if (c == 'c') { if (Tcl_ExprLong(tablePtr->interp, string + 1, &partNum) != TCL_OK) { return TCL_ERROR; } if ((partNum < 0) || (partNum >= tablePtr->nColumns)) { Tcl_AppendResult(tablePtr->interp, "column index \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } *columnPtr = (int)partNum; } else { if (ParseIndex(tablePtr->interp, string, rowPtr, columnPtr) != TCL_OK) { return TCL_ERROR; /* Invalid row,column index */ } if ((*rowPtr < 0) || (*rowPtr >= tablePtr->nRows) || (*columnPtr < 0) || (*columnPtr >= tablePtr->nColumns)) { Tcl_AppendResult(tablePtr->interp, "index \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TranslateAnchor -- * * Translate the coordinates of a given bounding box based upon the * anchor specified. The anchor indicates where the given xy position is * in relation to the bounding box. * * nw --- n --- ne * | | x,y ---+ * w center e | | * | | +-----+ * sw --- s --- se * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ static void TranslateAnchor( int dx, int dy, /* Difference between outer and inner * regions */ Tk_Anchor anchor, /* Direction of the anchor */ int *xPtr, int *yPtr) { int x, y; x = y = 0; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y = (dy / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ y = dy; break; case TK_ANCHOR_N: /* Top center */ x = (dx / 2); break; case TK_ANCHOR_CENTER: /* Centered */ x = (dx / 2); y = (dy / 2); break; case TK_ANCHOR_S: /* Bottom center */ x = (dx / 2); y = dy; break; case TK_ANCHOR_NE: /* Upper right corner */ x = dx; break; case TK_ANCHOR_E: /* Right center */ x = dx; y = (dy / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ x = dx; y = dy; break; } *xPtr = (*xPtr) + x; *yPtr = (*yPtr) + y; } /* *--------------------------------------------------------------------------- * * GetReqWidth -- * * Returns the width requested by the widget starting in the given entry. * The requested space also includes any internal padding which has been * designated for this widget. * * The requested width of the widget is always bounded by the limits set * in tePtr->reqWidth. * * Results: * Returns the requested width of the widget. * *--------------------------------------------------------------------------- */ static int GetReqWidth(TableEntry *tePtr) { int width; width = Tk_ReqWidth(tePtr->tkwin) + (2 * tePtr->ixPad); width = GetBoundedWidth(width, &tePtr->reqWidth); return width; } /* *--------------------------------------------------------------------------- * * GetReqHeight -- * * Returns the height requested by the widget starting in the given * entry. The requested space also includes any internal padding which * has been designated for this widget. * * The requested height of the widget is always bounded by the limits set * in tePtr->reqHeight. * * Results: * Returns the requested height of the widget. * *--------------------------------------------------------------------------- */ static int GetReqHeight(TableEntry *tePtr) { int height; height = Tk_ReqHeight(tePtr->tkwin) + (2 * tePtr->iyPad); height = GetBoundedHeight(height, &tePtr->reqHeight); return height; } /* *--------------------------------------------------------------------------- * * GetTotalSpan -- * * Sums the row/column space requirements for the entire table. * * Results: * Returns the space currently used in the span of partitions. * *--------------------------------------------------------------------------- */ static int GetTotalSpan(PartitionInfo *piPtr) { int spaceUsed; Blt_ChainLink link; spaceUsed = 0; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; /* Start of partitions */ rcPtr = Blt_Chain_GetValue(link); spaceUsed += rcPtr->size; } return spaceUsed; } /* *--------------------------------------------------------------------------- * * GetSpan -- * * Determines the space used by rows/columns for an entry. * * Results: * Returns the space currently used in the span of partitions. * *--------------------------------------------------------------------------- */ static int GetSpan(PartitionInfo *piPtr, TableEntry *tePtr) { RowColumn *startPtr; int spaceUsed; int count; Blt_ChainLink link; RowColumn *rcPtr; /* Start of partitions */ int span; /* Number of partitions spanned */ if (piPtr->type == rowUid) { rcPtr = tePtr->row.rcPtr; span = tePtr->row.span; } else { rcPtr = tePtr->column.rcPtr; span = tePtr->column.span; } count = spaceUsed = 0; link = rcPtr->link; startPtr = Blt_Chain_GetValue(link); for ( /*empty*/ ; (link != NULL) && (count < span); link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); spaceUsed += rcPtr->size; count++; } /* * Subtract off the padding on either side of the span, since the * widget can't grow into it. */ rcPtr->pad.side2 = 0; spaceUsed -= (startPtr->pad.side1 + rcPtr->pad.side2 + piPtr->ePad); #ifdef notdef if (strcmp(Tk_Name(tePtr->tkwin), "ss") == 0) { fprintf(stderr, "index=%d spaceUsed=%d\n", rcPtr->index, spaceUsed); } #endif return spaceUsed; } /* *--------------------------------------------------------------------------- * * GrowSpan -- * * Expand the span by the amount of the extra space needed. This * procedure is used in LayoutPartitions to grow the partitions to their * minimum nominal size, starting from a zero width and height space. * * This looks more complicated than it really is. The idea is to make * the size of the partitions correspond to the smallest entry spans. * For example, if widget A is in column 1 and widget B spans both * columns 0 and 1, any extra space needed to fit widget B should come * from column 0. * * On the first pass we try to add space to partitions which have not * been touched yet (i.e. have no nominal size). Since the row and * column lists are sorted in ascending order of the number of rows or * columns spanned, the space is distributed amongst the smallest spans * first. * * The second pass handles the case of widgets which have the same span. * For example, if A and B, which span the same number of partitions are * the only widgets to span column 1, column 1 would grow to contain the * bigger of the two slices of space. * * If there is still extra space after the first two passes, this means * that there were no partitions of with no widget spans or the same * order span that could be expanded. The third pass will try to remedy * this by parcelling out the left over space evenly among the rest of * the partitions. * * On each pass, we have to keep iterating over the span, evenly doling * out slices of extra space, because we may hit partition limits as * space is donated. In addition, if there are left over pixels because * of round-off, this will distribute them as evenly as possible. For * the worst case, it will take *span* passes to expand the span. * * Results: * None. * * Side Effects: * The partitions in the span may be expanded. * *--------------------------------------------------------------------------- */ static void GrowSpan( Table *tablePtr, PartitionInfo *piPtr, TableEntry *tePtr, int growth) /* The amount of extra space needed to grow * the span. */ { Blt_ChainLink link; int nOpen; /* # of partitions with space available */ int n; RowColumn *startPtr; /* Starting (column/row) partition */ int span; /* Number of partitions in the span */ #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "GrowSpan %s %s growth=%d\n", Tk_Name(tablePtr->tkwin), Tk_Name(tePtr->tkwin), growth); } #endif if (piPtr->type == rowUid) { startPtr = tePtr->row.rcPtr; span = tePtr->row.span; } else { startPtr = tePtr->column.rcPtr; span = tePtr->column.span; } /* * Pass 1: First add space to rows/columns that haven't determined * their nominal sizes yet. */ nOpen = 0; /* Find out how many partitions have no size yet */ for (n = 0, link = startPtr->link; (link != NULL) && (n < span); n++, link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->nom == LIMITS_NOM) && (rcPtr->max > rcPtr->size)) { nOpen++; } } while ((nOpen > 0) && (growth > 0)) { int ration; ration = growth / nOpen; if (ration == 0) { ration = 1; } link = startPtr->link; for (n = 0; (n < span) && (growth > 0); n++) { RowColumn *rcPtr; int avail; rcPtr = Blt_Chain_GetValue(link); avail = rcPtr->max - rcPtr->size; if ((rcPtr->nom == LIMITS_NOM) && (avail > 0)) { if (ration < avail) { growth -= ration; rcPtr->size += ration; } else { growth -= avail; rcPtr->size += avail; nOpen--; } rcPtr->minSpan = span; rcPtr->control = tePtr; } #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "GrowSpan pass1 %s %s size=%d\n", Tk_Name(tablePtr->tkwin), Tk_Name(tePtr->tkwin), rcPtr->size); } #endif link = Blt_Chain_NextLink(link); } } /* * Pass 2: Add space to partitions which have the same minimum span */ nOpen = 0; link = startPtr->link; for (n = 0; n < span; n++) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->minSpan == span) && (rcPtr->max > rcPtr->size)) { nOpen++; } link = Blt_Chain_NextLink(link); } while ((nOpen > 0) && (growth > 0)) { int ration; ration = growth / nOpen; if (ration == 0) { ration = 1; } link = startPtr->link; for (n = 0; (n < span) && (growth > 0); n++) { RowColumn *rcPtr; int avail; rcPtr = Blt_Chain_GetValue(link); avail = rcPtr->max - rcPtr->size; if ((rcPtr->minSpan == span) && (avail > 0)) { if (ration < avail) { growth -= ration; rcPtr->size += ration; } else { growth -= avail; rcPtr->size += avail; nOpen--; } rcPtr->control = tePtr; } #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "GrowSpan pass2 %s %s size=%d\n", Tk_Name(tablePtr->tkwin), Tk_Name(tePtr->tkwin), rcPtr->size); } #endif link = Blt_Chain_NextLink(link); } } /* * Pass 3: Try to expand all the partitions with space still available */ /* Find out how many partitions still have space available */ nOpen = 0; link = startPtr->link; for (n = 0; n < span; n++) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->resize & RESIZE_EXPAND) && (rcPtr->max > rcPtr->size)) { nOpen++; } /* Set the nominal size of the row/column. */ rcPtr->nom = rcPtr->size; link = Blt_Chain_NextLink(link); } while ((nOpen > 0) && (growth > 0)) { int ration; ration = growth / nOpen; if (ration == 0) { ration = 1; } link = startPtr->link; for (n = 0; (n < span) && (growth > 0); n++) { RowColumn *rcPtr; int avail; rcPtr = Blt_Chain_GetValue(link); link = Blt_Chain_NextLink(link); if (!(rcPtr->resize & RESIZE_EXPAND)) { continue; } avail = rcPtr->max - rcPtr->size; if (avail > 0) { if (ration < avail) { growth -= ration; rcPtr->size += ration; } else { growth -= avail; rcPtr->size += avail; nOpen--; } rcPtr->nom = rcPtr->size; rcPtr->control = tePtr; } #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "GrowSpan pass3 %s %s size=%d\n", Tk_Name(tablePtr->tkwin), Tk_Name(tePtr->tkwin), rcPtr->size); } #endif } } } /* *--------------------------------------------------------------------------- * * GrowPartitions -- * * Grow the span by the designated amount. Size constraints on the * partitions may prevent any or all of the spacing adjustments. * * This is very much like the GrowSpan procedure, but in this case we are * expanding all the (row or column) partitions. It uses a two pass * approach, first giving space to partitions which are smaller than * their nominal sizes. This is because constraints on the partitions may * cause resizing to be non-linear. * * If there is still extra space, this means that all partitions are at * least to their nominal sizes. The second pass will try to add the * left over space evenly among all the partitions which still have space * available (i.e. haven't reached their specified max sizes). * * Results: * None. * * Side Effects: * The size of the partitions may be increased. * *--------------------------------------------------------------------------- */ static void GrowPartitions( PartitionInfo *piPtr, /* Array of (column/row) partitions */ int adjustment) /* The amount of extra space to grow the * span. If negative, it represents the amount * of space to add. */ { int delta; /* Amount of space needed */ int nAdjust; /* Number of rows/columns that still can be * adjusted. */ Blt_Chain chain; Blt_ChainLink link; float totalWeight; chain = piPtr->chain; /* * Pass 1: First adjust the size of rows/columns that still haven't * reached their nominal size. */ delta = adjustment; nAdjust = 0; totalWeight = 0.0; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->weight > 0.0) && (rcPtr->nom > rcPtr->size)) { nAdjust++; totalWeight += rcPtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0) && (delta > 0)) { Blt_ChainLink link; int ration; /* Amount of space to add to each * row/column. */ ration = (int)(delta / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (delta > 0); link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if (rcPtr->weight > 0.0) { int avail; /* Amount of space still available. */ avail = rcPtr->nom - rcPtr->size; if (avail > 0) { int size; /* Amount of space requested for a particular * row/column. */ size = (int)(ration * rcPtr->weight); if (size > delta) { size = delta; } if (size < avail) { delta -= size; rcPtr->size += size; } else { delta -= avail; rcPtr->size += avail; nAdjust--; totalWeight -= rcPtr->weight; } } } } } /* * Pass 2: Adjust the partitions with space still available */ nAdjust = 0; totalWeight = 0.0; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->weight > 0.0) && (rcPtr->max > rcPtr->size)) { nAdjust++; totalWeight += rcPtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0) && (delta > 0)) { Blt_ChainLink link; int ration; /* Amount of space to add to each * row/column. */ ration = (int)(delta / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (delta > 0); link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if (rcPtr->weight > 0.0) { int avail; /* Amount of space still available */ avail = (rcPtr->max - rcPtr->size); if (avail > 0) { int size; /* Amount of space requested for a particular * row/column. */ size = (int)(ration * rcPtr->weight); if (size > delta) { size = delta; } if (size < avail) { delta -= size; rcPtr->size += size; } else { delta -= avail; rcPtr->size += avail; nAdjust--; totalWeight -= rcPtr->weight; } } } } } } /* *--------------------------------------------------------------------------- * * ShrinkPartitions -- * * Shrink the span by the amount specified. Size constraints on the * partitions may prevent any or all of the spacing adjustments. * * This is very much like the GrowSpan procedure, but in this case we are * shrinking or expanding all the (row or column) partitions. It uses a * two pass approach, first subtracting space to partitions which are * larger than their nominal sizes. This is because constraints on the * partitions may cause resizing to be non-linear. * * After pass 1, if there is still extra to be removed, this means that * all partitions are at least to their nominal sizes. The second pass * will try to remove the extra space evenly among all the partitions * which still have space available (i.e haven't reached their respective * min sizes). * * Results: * None. * * Side Effects: * The size of the partitions may be decreased. * *--------------------------------------------------------------------------- */ static void ShrinkPartitions( PartitionInfo *piPtr, /* Array of (column/row) partitions */ int adjustment) /* The amount of extra space to shrink the * span. It represents the amount of space to * remove. */ { Blt_ChainLink link; int extra; /* Amount of space needed */ int nAdjust; /* Number of rows/columns that still can be * adjusted. */ Blt_Chain chain; float totalWeight; chain = piPtr->chain; /* * Pass 1: First adjust the size of rows/columns that still aren't * at their nominal size. */ extra = -adjustment; nAdjust = 0; totalWeight = 0.0; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->weight > 0.0) && (rcPtr->nom < rcPtr->size)) { nAdjust++; totalWeight += rcPtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0) && (extra > 0)) { Blt_ChainLink link; int ration; /* Amount of space to subtract from each * row/column. */ ration = (int)(extra / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (extra > 0); link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if (rcPtr->weight > 0.0) { int avail; /* Amount of space still available */ avail = rcPtr->size - rcPtr->nom; if (avail > 0) { int slice; /* Amount of space requested for a particular * row/column. */ slice = (int)(ration * rcPtr->weight); if (slice > extra) { slice = extra; } if (avail > slice) { extra -= slice; rcPtr->size -= slice; } else { extra -= avail; rcPtr->size -= avail; nAdjust--; /* Goes to zero (nominal). */ totalWeight -= rcPtr->weight; } } } } } /* * Pass 2: Now adjust the partitions with space still available (i.e. * are bigger than their minimum size). */ nAdjust = 0; totalWeight = 0.0; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if ((rcPtr->weight > 0.0) && (rcPtr->size > rcPtr->min)) { nAdjust++; totalWeight += rcPtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0) && (extra > 0)) { Blt_ChainLink link; int ration; /* Amount of space to subtract from each * row/column. */ ration = (int)(extra / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (extra > 0); link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if (rcPtr->weight > 0.0) { int avail; /* Amount of space still available */ avail = rcPtr->size - rcPtr->min; if (avail > 0) { int slice; /* Amount of space requested for a particular * row/column. */ slice = (int)(ration * rcPtr->weight); if (slice > extra) { slice = extra; } if (avail > slice) { extra -= slice; rcPtr->size -= slice; } else { extra -= avail; rcPtr->size -= avail; nAdjust--; totalWeight -= rcPtr->weight; } } } } } } /* *--------------------------------------------------------------------------- * * ResetPartitions -- * * Sets/resets the size of each row and column partition to the minimum * limit of the partition (this is usually zero). This routine gets * called when new widgets are added, deleted, or resized. * * Results: * None. * * Side Effects: * The size of each partition is re-initialized to its minimum size. * *--------------------------------------------------------------------------- */ static void ResetPartitions(Table *tablePtr, PartitionInfo *piPtr, LimitsProc *limitsProc) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; int pad, size; rcPtr = Blt_Chain_GetValue(link); /* * The constraint procedure below also has the desired side-effect of * setting the minimum, maximum, and nominal values to the requested * size of its associated widget (if one exists). */ size = (*limitsProc)(0, &rcPtr->reqSize); pad = PADDING(rcPtr->pad) + piPtr->ePad; if (rcPtr->reqSize.flags & LIMITS_SET_NOM) { /* * This could be done more cleanly. We want to ensure that the * requested nominal size is not overridden when determining the * normal sizes. So temporarily fix min and max to the nominal * size and reset them back later. */ rcPtr->min = rcPtr->max = rcPtr->size = rcPtr->nom = size + pad; } else { /* The range defaults to 0..MAXINT */ rcPtr->min = rcPtr->reqSize.min + pad; rcPtr->max = rcPtr->reqSize.max + pad; rcPtr->nom = LIMITS_NOM; rcPtr->size = pad; } rcPtr->minSpan = 0; rcPtr->control = NULL; rcPtr->count = 0; } } /* *--------------------------------------------------------------------------- * * SetNominalSizes * * Sets the normal sizes for each partition. The partition size is the * requested widget size plus an amount of padding. In addition, adjust * the min/max bounds of the partition depending upon the resize flags * (whether the partition can be expanded or shrunk from its normal * size). * * Results: * Returns the total space needed for the all the partitions. * * Side Effects: * The nominal size of each partition is set. This is later used to * determine how to shrink or grow the table if the container can't be * resized to accommodate the exact size requirements of all the * partitions. * *--------------------------------------------------------------------------- */ static int SetNominalSizes(Table *tablePtr, PartitionInfo *piPtr) { Blt_ChainLink link; int total; total = 0; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; int pad, size; rcPtr = Blt_Chain_GetValue(link); pad = PADDING(rcPtr->pad) + piPtr->ePad; /* * Restore the real bounds after temporarily setting nominal size. * These values may have been set in ResetPartitions to restrict the * size of the partition to the requested range. */ rcPtr->min = rcPtr->reqSize.min + pad; rcPtr->max = rcPtr->reqSize.max + pad; size = rcPtr->size; if (size > rcPtr->max) { size = rcPtr->max; } else if (size < rcPtr->min) { size = rcPtr->min; } if ((piPtr->ePad > 0) && (size < tablePtr->editPtr->min)) { size = tablePtr->editPtr->min; } rcPtr->nom = rcPtr->size = size; /* * If a partition can't be resized (to either expand or shrink), hold * its respective limit at its normal size. */ if (!(rcPtr->resize & RESIZE_EXPAND)) { rcPtr->max = rcPtr->nom; } if (!(rcPtr->resize & RESIZE_SHRINK)) { rcPtr->min = rcPtr->nom; } if (rcPtr->control == NULL) { /* If a row/column contains no entries, then its size should be * locked. */ if (rcPtr->resize & RESIZE_VIRGIN) { rcPtr->max = rcPtr->min = size; } else { if (!(rcPtr->resize & RESIZE_EXPAND)) { rcPtr->max = size; } if (!(rcPtr->resize & RESIZE_SHRINK)) { rcPtr->min = size; } } rcPtr->nom = size; } #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "SetNominalSizes %s: %s %d min=%d max=%d nom=%d, size=%d total=%d\n", Tk_Name(tablePtr->tkwin), piPtr->type, rcPtr->index, rcPtr->min, rcPtr->max, rcPtr->nom, rcPtr->size, total); } #endif total += rcPtr->nom; } return total; } /* *--------------------------------------------------------------------------- * * LockPartitions * * Sets the maximum size of a row or column, if the partition has a * widget that controls it. * * Results: * None. * *--------------------------------------------------------------------------- */ static void LockPartitions(PartitionInfo *piPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); if (rcPtr->control != NULL) { /* Partition is controlled by this widget */ rcPtr->max = rcPtr->size; } } } /* *--------------------------------------------------------------------------- * * LayoutPartitions -- * * Calculates the normal space requirements for both the row and column * partitions. Each widget is added in order of the number of rows or * columns spanned, which defines the space needed among in the * partitions spanned. * * Results: * None. * * Side Effects: * The sum of normal sizes set here will be used as the normal size for * the container widget. * *--------------------------------------------------------------------------- */ static void LayoutPartitions(Table *tablePtr) { Blt_ListNode node; int total; PartitionInfo *piPtr; piPtr = &tablePtr->cols; ResetPartitions(tablePtr, piPtr, GetBoundedWidth); for (node = Blt_List_FirstNode(piPtr->list); node != NULL; node = Blt_List_NextNode(node)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_List_GetValue(node); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; int needed, used; tePtr = Blt_Chain_GetValue(link); if (tePtr->column.control != CONTROL_FULL) { continue; } needed = GetReqWidth(tePtr) + PADDING(tePtr->xPad) + 2 * (tePtr->borderWidth + tablePtr->eEntryPad); if (needed <= 0) { continue; } used = GetSpan(piPtr, tePtr); if (needed > used) { GrowSpan(tablePtr, piPtr, tePtr, needed - used); } } } LockPartitions(piPtr); for (node = Blt_List_FirstNode(piPtr->list); node != NULL; node = Blt_List_NextNode(node)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_List_GetValue(node); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; int needed, used; tePtr = Blt_Chain_GetValue(link); needed = GetReqWidth(tePtr) + PADDING(tePtr->xPad) + 2 * (tePtr->borderWidth + tablePtr->eEntryPad); if (tePtr->column.control >= 0.0) { needed = (int)(needed * tePtr->column.control); } if (needed <= 0) { continue; } used = GetSpan(piPtr, tePtr); if (needed > used) { GrowSpan(tablePtr, piPtr, tePtr, needed - used); } } } total = SetNominalSizes(tablePtr, piPtr); tablePtr->normal.width = GetBoundedWidth(total, &tablePtr->reqWidth) + PADDING(tablePtr->xPad) + 2 * (tablePtr->eTablePad + Tk_InternalBorderWidth(tablePtr->tkwin)); piPtr = &tablePtr->rows; ResetPartitions(tablePtr, piPtr, GetBoundedHeight); for (node = Blt_List_FirstNode(piPtr->list); node != NULL; node = Blt_List_NextNode(node)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_List_GetValue(node); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; int needed, used; tePtr = Blt_Chain_GetValue(link); if (tePtr->row.control != CONTROL_FULL) { continue; } needed = GetReqHeight(tePtr) + PADDING(tePtr->yPad) + 2 * (tePtr->borderWidth + tablePtr->eEntryPad); if (needed <= 0) { continue; } used = GetSpan(piPtr, tePtr); if (needed > used) { GrowSpan(tablePtr, piPtr, tePtr, needed - used); } #ifdef notdef if (strcmp(Tk_Name(tePtr->tkwin), "ss") == 0) { fprintf(stderr, "pass1 %s used=%d needed=%d\n", Tk_Name(tePtr->tkwin), used, needed); } #endif } } LockPartitions(&tablePtr->rows); for (node = Blt_List_FirstNode(piPtr->list); node != NULL; node = Blt_List_NextNode(node)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_Chain_GetValue(node); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; int needed, used; tePtr = Blt_Chain_GetValue(link); needed = GetReqHeight(tePtr) + PADDING(tePtr->yPad) + 2 * (tePtr->borderWidth + tablePtr->eEntryPad); if (tePtr->row.control >= 0.0) { needed = (int)(needed * tePtr->row.control); } if (needed <= 0) { continue; } used = GetSpan(piPtr, tePtr); if (needed > used) { GrowSpan(tablePtr, piPtr, tePtr, needed - used); } #ifdef notdef if (strcmp(Tk_Name(tePtr->tkwin), "ss") == 0) { fprintf(stderr, "pass2 %s used=%d needed=%d\n", Tk_Name(tePtr->tkwin), used, needed); } #endif } } total = SetNominalSizes(tablePtr, piPtr); tablePtr->normal.height = GetBoundedHeight(total, &tablePtr->reqHeight) + PADDING(tablePtr->yPad) + 2 * (tablePtr->eTablePad + Tk_InternalBorderWidth(tablePtr->tkwin)); #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "%s normal height=%d\n", Tk_PathName(tablePtr->tkwin), tablePtr->normal.height); fprintf(stderr, "total=%d boundedheight=%d reqHeight=%d normal=%d\n", total, GetBoundedHeight(total, &tablePtr->reqHeight), tablePtr->reqHeight.nom, tablePtr->normal.height); } #endif } /* *--------------------------------------------------------------------------- * * ArrangeEntries * * Places each widget at its proper location. First determines the size * and position of the each widget. It then considers the following: * * 1. translation of widget position its parent widget. * 2. fill style * 3. anchor * 4. external and internal padding * 5. widget size must be greater than zero * * Results: * None. * * Side Effects: * The size of each partition is re-initialized its minimum size. * *--------------------------------------------------------------------------- */ static void ArrangeEntries(Table *tablePtr) /* Table widget structure */ { Blt_ChainLink link; int xMax, yMax; xMax = tablePtr->container.width - (Tk_InternalBorderWidth(tablePtr->tkwin) + tablePtr->padRight + tablePtr->eTablePad); yMax = tablePtr->container.height - (Tk_InternalBorderWidth(tablePtr->tkwin) + tablePtr->padBottom + tablePtr->eTablePad); for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; int dx, dy; int extra; int spanWidth, spanHeight; int winWidth, winHeight; int x, y; tePtr = Blt_Chain_GetValue(link); x = tePtr->column.rcPtr->offset + tePtr->column.rcPtr->pad.side1 + tePtr->padLeft + Tk_Changes(tePtr->tkwin)->border_width + tablePtr->eEntryPad; y = tePtr->row.rcPtr->offset + tePtr->row.rcPtr->pad.side1 + tePtr->padTop + Tk_Changes(tePtr->tkwin)->border_width + tablePtr->eEntryPad; /* * Unmap any widgets that start beyond of the right edge of the * container. */ if ((x >= xMax) || (y >= yMax)) { if (Tk_IsMapped(tePtr->tkwin)) { if (Tk_Parent(tePtr->tkwin) != tablePtr->tkwin) { Tk_UnmaintainGeometry(tePtr->tkwin, tablePtr->tkwin); } Tk_UnmapWindow(tePtr->tkwin); } continue; } extra = 2 * (tePtr->borderWidth + tablePtr->eEntryPad); spanWidth = GetSpan(&tablePtr->cols, tePtr) - (extra + PADDING(tePtr->xPad)); spanHeight = GetSpan(&tablePtr->rows, tePtr) - (extra + PADDING(tePtr->yPad)); winWidth = GetReqWidth(tePtr); winHeight = GetReqHeight(tePtr); /* * * Compare the widget's requested size to the size of the span. * * 1) If the widget is larger than the span or if the fill flag is * set, make the widget the size of the span. Check that the new size * is within the bounds set for the widget. * * 2) Otherwise, position the widget in the space according to its * anchor. * */ if ((spanWidth <= winWidth) || (tePtr->fill & FILL_X)) { winWidth = spanWidth; if (winWidth > tePtr->reqWidth.max) { winWidth = tePtr->reqWidth.max; } } if ((spanHeight <= winHeight) || (tePtr->fill & FILL_Y)) { winHeight = spanHeight; if (winHeight > tePtr->reqHeight.max) { winHeight = tePtr->reqHeight.max; } } dx = dy = 0; if (spanWidth > winWidth) { dx = (spanWidth - winWidth); } if (spanHeight > winHeight) { dy = (spanHeight - winHeight); } if ((dx > 0) || (dy > 0)) { TranslateAnchor(dx, dy, tePtr->anchor, &x, &y); } /* * Clip the widget at the bottom and/or right edge of the container. */ if (winWidth > (xMax - x)) { winWidth = (xMax - x); } if (winHeight > (yMax - y)) { winHeight = (yMax - y); } /* * If the widget is too small (i.e. it has only an external border) * then unmap it. */ if ((winWidth < 1) || (winHeight < 1)) { if (Tk_IsMapped(tePtr->tkwin)) { if (tablePtr->tkwin != Tk_Parent(tePtr->tkwin)) { Tk_UnmaintainGeometry(tePtr->tkwin, tablePtr->tkwin); } Tk_UnmapWindow(tePtr->tkwin); } continue; } /* * Resize and/or move the widget as necessary. */ tePtr->x = x; tePtr->y = y; #ifdef notdef if (strcmp(Tk_Name(tePtr->tkwin), "fs") == 0) { fprintf(stderr, "ArrangeEntries: %s rw=%d rh=%d w=%d h=%d\n", Tk_PathName(tePtr->tkwin), Tk_ReqWidth(tePtr->tkwin), Tk_ReqHeight(tePtr->tkwin), winWidth, winHeight); } #endif if (tablePtr->tkwin != Tk_Parent(tePtr->tkwin)) { Tk_MaintainGeometry(tePtr->tkwin, tablePtr->tkwin, x, y, winWidth, winHeight); } else { if ((x != Tk_X(tePtr->tkwin)) || (y != Tk_Y(tePtr->tkwin)) || (winWidth != Tk_Width(tePtr->tkwin)) || (winHeight != Tk_Height(tePtr->tkwin))) { #ifdef notdef if (strcmp(Tk_Name(tePtr->tkwin), "fs") == 0) { fprintf(stderr, "ArrangeEntries: %s rw=%d rh=%d w=%d h=%d\n", Tk_PathName(tePtr->tkwin), Tk_ReqWidth(tePtr->tkwin), Tk_ReqHeight(tePtr->tkwin), winWidth, winHeight); } #endif Tk_MoveResizeWindow(tePtr->tkwin, x, y, winWidth, winHeight); } if (!Tk_IsMapped(tePtr->tkwin)) { Tk_MapWindow(tePtr->tkwin); } } } } /* *--------------------------------------------------------------------------- * * ArrangeTable -- * * * Results: * None. * * Side Effects: * The widgets in the table are possibly resized and redrawn. * *--------------------------------------------------------------------------- */ static void ArrangeTable(ClientData clientData) { Table *tablePtr = clientData; int width, height; int offset, delta; int xPad, yPad; int outerPad; Blt_ChainLink link; #ifdef notdef fprintf(stderr, "ArrangeTable(%s)\n", Tk_PathName(tablePtr->tkwin)); #endif Tcl_Preserve(tablePtr); tablePtr->flags &= ~ARRANGE_PENDING; tablePtr->rows.ePad = tablePtr->cols.ePad = tablePtr->eTablePad = tablePtr->eEntryPad = 0; if (tablePtr->editPtr != NULL) { tablePtr->rows.ePad = tablePtr->cols.ePad = tablePtr->editPtr->gridLineWidth; tablePtr->eTablePad = tablePtr->editPtr->gridLineWidth; tablePtr->eEntryPad = tablePtr->editPtr->entryPad; } /* * If the table has no children anymore, then don't do anything at all: * just leave the container widget's size as-is. */ if ((Blt_Chain_GetLength(tablePtr->chain) == 0) || (tablePtr->tkwin == NULL)) { Tcl_Release(tablePtr); return; } if (tablePtr->flags & REQUEST_LAYOUT) { tablePtr->flags &= ~REQUEST_LAYOUT; LayoutPartitions(tablePtr); } /* * Initially, try to fit the partitions exactly into the container by * resizing the container. If the widget's requested size is different, * send a request to the container widget's geometry manager to resize. */ if ((tablePtr->propagate) && ((tablePtr->normal.width != Tk_ReqWidth(tablePtr->tkwin)) || (tablePtr->normal.height != Tk_ReqHeight(tablePtr->tkwin)))) { Tk_GeometryRequest(tablePtr->tkwin, tablePtr->normal.width, tablePtr->normal.height); EventuallyArrangeTable(tablePtr); Tcl_Release(tablePtr); return; } /* * Save the width and height of the container so we know when its size has * changed during ConfigureNotify events. */ tablePtr->container.width = Tk_Width(tablePtr->tkwin); tablePtr->container.height = Tk_Height(tablePtr->tkwin); outerPad = 2 * (Tk_InternalBorderWidth(tablePtr->tkwin) + tablePtr->eTablePad); xPad = outerPad + tablePtr->cols.ePad + PADDING(tablePtr->xPad); yPad = outerPad + tablePtr->rows.ePad + PADDING(tablePtr->yPad); width = GetTotalSpan(&tablePtr->cols) + xPad; height = GetTotalSpan(&tablePtr->rows) + yPad; /* * If the previous geometry request was not fulfilled (i.e. the size of * the container is different from partitions' space requirements), try to * adjust size of the partitions to fit the widget. */ delta = tablePtr->container.width - width; if (delta != 0) { if (delta > 0) { GrowPartitions(&tablePtr->cols, delta); } else { ShrinkPartitions(&tablePtr->cols, delta); } width = GetTotalSpan(&tablePtr->cols) + xPad; } delta = tablePtr->container.height - height; if (delta != 0) { if (delta > 0) { #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "GrowPartiions %s delta=%d container=%d rh=%d h=%d\n", Tk_Name(tablePtr->tkwin), delta, tablePtr->container.height, Tk_ReqHeight(tablePtr->tkwin), height); } #endif GrowPartitions(&tablePtr->rows, delta); } else { #ifdef notdef if (strcmp(Tk_Name(tablePtr->tkwin), "fs") == 0) { fprintf(stderr, "ShrinkPartiions %s delta=%d container=%d rh=%d h=%d\n", Tk_Name(tablePtr->tkwin), delta, tablePtr->container.height, Tk_ReqHeight(tablePtr->tkwin), height); } #endif ShrinkPartitions(&tablePtr->rows, delta); } height = GetTotalSpan(&tablePtr->rows) + yPad; } /* * If after adjusting the size of the partitions the space required does * not equal the size of the widget, do one of the following: * * 1) If it's smaller, center the table in the widget. * 2) If it's bigger, clip the partitions that extend beyond * the edge of the container. * * Set the row and column offsets (including the container's internal * border width). To be used later when positioning the widgets. */ offset = Tk_InternalBorderWidth(tablePtr->tkwin) + tablePtr->padLeft + tablePtr->eTablePad; if (width < tablePtr->container.width) { offset += (tablePtr->container.width - width) / 2; } for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *columnPtr; columnPtr = Blt_Chain_GetValue(link); columnPtr->offset = offset + tablePtr->cols.ePad; offset += columnPtr->size; } offset = Tk_InternalBorderWidth(tablePtr->tkwin) + tablePtr->padTop + tablePtr->eTablePad; if (height < tablePtr->container.height) { offset += (tablePtr->container.height - height) / 2; } for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rowPtr; rowPtr = Blt_Chain_GetValue(link); rowPtr->offset = offset + tablePtr->rows.ePad; offset += rowPtr->size; } ArrangeEntries(tablePtr); if (tablePtr->editPtr != NULL) { /* Redraw the editor */ (*tablePtr->editPtr->drawProc) (tablePtr->editPtr); } Tcl_Release(tablePtr); } /* *--------------------------------------------------------------------------- * * ArrangeOp -- * * Forces layout of the table geometry manager. This is useful mostly * for debugging the geometry manager. You can get the geometry manager * to calculate the normal (requested) width and height of each row and * column. Otherwise, you need to first withdraw the container widget, * invoke "update", and then query the geometry manager. * * Results: * Returns a standard TCL result. If the table is successfully * rearranged, TCL_OK is returned. Otherwise, TCL_ERROR is returned and * an error message is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ArrangeOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) /* Path name of container associated with the * table */ { Table *tablePtr; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } tablePtr->flags |= REQUEST_LAYOUT; ArrangeTable(tablePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Returns the name, position and options of a widget in the table. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PartitionInfo *piPtr; Table *tablePtr; const char *string; char c; int length; int n; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { return Blt_ConfigureValueFromObj(interp, tablePtr->tkwin, tableConfigSpecs, (char *)tablePtr, objv[3], 0); } string = Tcl_GetStringFromObj(objv[3], &length); c = string[0]; if (c == '.') { /* Configure widget */ TableEntry *tePtr; if (GetEntry(interp, tablePtr, Tcl_GetString(objv[3]), &tePtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, tePtr->tkwin, entryConfigSpecs, (char *)tePtr, objv[4], 0); } else if ((c == 'c') && (strncmp(string, "container", length) == 0)) { return Blt_ConfigureValueFromObj(interp, tablePtr->tkwin, tableConfigSpecs, (char *)tablePtr, objv[4], 0); } piPtr = ParseRowColumn(tablePtr, objv[3], &n); if (piPtr == NULL) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, tablePtr->tkwin, piPtr->configSpecs, (char *)GetRowColumn(piPtr, n), objv[4], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Returns the name, position and options of a widget in the table. * * Results: * Returns a standard TCL result. A list of the table configuration * option information is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; int count; int result; Tcl_Obj *const *items; int i; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } /* * Find the end of the items. Search until we see an option (-). */ objc -= 3, objv += 3; for (count = 0; count < objc; count++) { const char *string; string = Tcl_GetString(objv[count]); if (string[0] == '-') { break; } } items = objv; /* Save the start of the item list */ objc -= count; /* Move beyond the items to the options */ objv += count; result = TCL_ERROR; /* Suppress compiler warning */ if (count == 0) { result = ConfigureTable(tablePtr, interp, objc, objv); } for (i = 0; i < count; i++) { const char *string; char c1, c2; int length; string = Tcl_GetStringFromObj(items[i], &length); c1 = string[0]; c2 = string[1]; if (c1 == '.') { /* Configure widget */ TableEntry *tePtr; if (GetEntry(interp, tablePtr, string, &tePtr) != TCL_OK) { return TCL_ERROR; } result = ConfigureEntry(tablePtr, interp, tePtr, objc, objv); } else if ((c1 == 'r') || (c1 == 'R')) { result = ConfigureRowColumn(tablePtr, &tablePtr->rows, string, objc, objv); } else if ((c1 == 'c') && (c2 == 'o') && (strncmp(string, "container", length) == 0)) { result = ConfigureTable(tablePtr, interp, objc, objv); } else if ((c1 == 'c') || (c1 == 'C')) { result = ConfigureRowColumn(tablePtr, &tablePtr->cols, string, objc, objv); } else { Tcl_AppendResult(interp, "unknown item \"", string, "\": should be widget, row or column index, or \"container\"", (char *)NULL); return TCL_ERROR; } if (result == TCL_ERROR) { break; } if ((i + 1) < count) { Tcl_AppendResult(interp, "\n", (char *)NULL); } } tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); return result; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the specified rows and/or columns from the table. Note that * the row/column indices can be fixed only after all the deletions have * occurred. * * table delete .f r0 r1 r4 c0 * * Results: * Returns a standard TCL result. * * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; int matches; int i; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } for (i = 3; i < objc; i++) { const char *pattern; char c; pattern = Tcl_GetString(objv[i]); c = tolower(pattern[0]); if ((c != 'r') && (c != 'c')) { Tcl_AppendResult(interp, "bad index \"", pattern, "\": must start with \"r\" or \"c\"", (char *)NULL); return TCL_ERROR; } } matches = 0; for (i = 3; i < objc; i++) { Blt_ChainLink link, next; PartitionInfo *piPtr; const char *pattern; char c; pattern = Tcl_GetString(objv[i]); c = tolower(pattern[0]); piPtr = (c == 'r') ? &tablePtr->rows : &tablePtr->cols; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = next) { RowColumn *rcPtr; char ident[200]; next = Blt_Chain_NextLink(link); rcPtr = Blt_Chain_GetValue(link); sprintf_s(ident, 200, "%c%d", c, rcPtr->index); if (Tcl_StringMatch(ident, pattern)) { matches++; DeleteRowColumn(tablePtr, piPtr, rcPtr); Blt_Chain_DeleteLink(piPtr->chain, link); } } } if (matches > 0) { /* Fix indices */ Blt_ChainLink link; i = 0; for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); rcPtr->index = i++; } i = 0; for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); rcPtr->index = i++; } tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * JoinOp -- * * Joins the specified span of rows/columns together into a partition. * The row/column indices can be fixed only after all the deletions have * occurred. * * table join .f r0 r3 * table join .f c2 c4 * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int JoinOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; Blt_ChainLink link, nextl, froml; PartitionInfo *piPtr, *info2Ptr; TableEntry *tePtr; int from, to; /* Indices marking the span of partitions to * be joined together. */ int start, end; /* Entry indices. */ int i; RowColumn *rcPtr; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } piPtr = ParseRowColumn(tablePtr, objv[3], &from); if (piPtr == NULL) { return TCL_ERROR; } info2Ptr = ParseRowColumn(tablePtr, objv[4], &to); if (info2Ptr == NULL) { return TCL_ERROR; } if (piPtr != info2Ptr) { Tcl_AppendResult(interp, "\"from\" and \"to\" must both be rows or columns", (char *)NULL); return TCL_ERROR; } if (from >= to) { return TCL_OK; /* No-op. */ } froml = Blt_Chain_GetNthLink(piPtr->chain, from); rcPtr = Blt_Chain_GetValue(froml); /* * Reduce the span of all entries that currently cross any of the * trailing rows/columns. Also, if the entry starts in one of these * rows/columns, moved it to the designated "joined" row/column. */ if (piPtr->type == rowUid) { for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); start = tePtr->row.rcPtr->index + 1; end = tePtr->row.rcPtr->index + tePtr->row.span - 1; if ((end < from) || ((start > to))) { continue; } tePtr->row.span -= to - start + 1; if (start >= from) {/* Entry starts in a trailing partition. */ tePtr->row.rcPtr = rcPtr; } } } else { for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); start = tePtr->column.rcPtr->index + 1; end = tePtr->column.rcPtr->index + tePtr->column.span - 1; if ((end < from) || ((start > to))) { continue; } tePtr->column.span -= to - start + 1; if (start >= from) {/* Entry starts in a trailing partition. */ tePtr->column.rcPtr = rcPtr; } } } link = Blt_Chain_NextLink(froml); for (i = from + 1; i <= to; i++) { nextl = Blt_Chain_NextLink(link); rcPtr = Blt_Chain_GetValue(link); DeleteRowColumn(tablePtr, piPtr, rcPtr); Blt_Chain_DeleteLink(piPtr->chain, link); link = nextl; } i = 0; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); rcPtr->index = i++; } tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExtentsOp -- * * Returns a list of all the pathnames of the widgets managed by a table. * The table is determined from the name of the container widget * associated with the table. * * table extents .frame r0 c0 container * * Results: * Returns a standard TCL result. If no error occurred, TCL_OK is * returned and a list of widgets managed by the table is left in * interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExtentsOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return results to. */ int objc, /* # of arguments */ Tcl_Obj *const *objv) /* Command line arguments. */ { Table *tablePtr; Blt_ChainLink link; PartitionInfo *piPtr; Tcl_DString dString; char *pattern; char c; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } pattern = Tcl_GetString(objv[3]); c = tolower(pattern[0]); if (c == 'r') { piPtr = &tablePtr->rows; } else if (c == 'c') { piPtr = &tablePtr->cols; } else { Tcl_AppendResult(interp, "unknown item \"", pattern, "\": should be widget, row, or column", (char *)NULL); return TCL_ERROR; } Tcl_DStringInit(&dString); for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; char ident[200]; rcPtr = Blt_Chain_GetValue(link); sprintf_s(ident, 200, "%c%d", c, rcPtr->index); if (Tcl_StringMatch(ident, pattern)) { int x, y, width, height; RowColumn *c1Ptr, *r1Ptr, *c2Ptr, *r2Ptr; if (c == 'r') { r1Ptr = r2Ptr = rcPtr; c1Ptr = GetRowColumn(&tablePtr->cols, 0); c2Ptr = GetRowColumn(&tablePtr->cols, tablePtr->nColumns - 1); } else { c1Ptr = c2Ptr = rcPtr; r1Ptr = GetRowColumn(&tablePtr->rows, 0); r2Ptr = GetRowColumn(&tablePtr->rows, tablePtr->nRows - 1); } x = c1Ptr->offset; y = r1Ptr->offset; width = c2Ptr->offset + c2Ptr->size - x; height = r2Ptr->offset + r2Ptr->size - y; Tcl_DStringAppend(&dString, ident, -1); Tcl_DStringAppend(&dString, " ", 1); Tcl_DStringAppend(&dString, Blt_Itoa(rcPtr->index), -1); Tcl_DStringAppend(&dString, " ", 1); Tcl_DStringAppend(&dString, Blt_Itoa(x), -1); Tcl_DStringAppend(&dString, " ", 1); Tcl_DStringAppend(&dString, Blt_Itoa(y), -1); Tcl_DStringAppend(&dString, " ", 1); Tcl_DStringAppend(&dString, Blt_Itoa(width), -1); Tcl_DStringAppend(&dString, " ", 1); Tcl_DStringAppend(&dString, Blt_Itoa(height), -1); Tcl_DStringAppend(&dString, "\n", 1); } } Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ForgetOp -- * * Processes an objv/objc list of widget names and purges their entries * from their respective tables. The widgets are unmapped and the tables * are rearranged at the next idle point. Note that all the named * widgets do not need to exist in the same table. * * Results: * Returns a standard TCL result. If an error occurred, TCL_ERROR is * returned and an error message is left in interp->result. * * Side Effects: * Memory is deallocated (the entry is destroyed), etc. The affected * tables are is re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int ForgetOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TableEntry *tePtr; int i; Blt_HashEntry *hPtr; Blt_HashSearch iter; Table *tablePtr; Tk_Window tkwin; char *string; tablePtr = NULL; for (i = 2; i < objc; i++) { tePtr = NULL; string = Tcl_GetString(objv[i]); tkwin = Tk_NameToWindow(interp, string, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } for (hPtr = Blt_FirstHashEntry(&dataPtr->tableTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { tablePtr = Blt_GetHashValue(hPtr); if (tablePtr->interp != interp) { continue; } tePtr = FindEntry(tablePtr, tkwin); if (tePtr != NULL) { break; } } if (tePtr == NULL) { Tcl_AppendResult(interp, "\"", string, "\" is not managed by any table", (char *)NULL); return TCL_ERROR; } if (Tk_IsMapped(tePtr->tkwin)) { Tk_UnmapWindow(tePtr->tkwin); } /* Arrange for the call back here in the loop, because the widgets may * not belong to the same table. */ tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); DestroyEntry(tePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * InfoOp -- * * Returns the options of a widget or partition in the table. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InfoOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; int result; char c; int i; char *string; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } for (i = 3; i < objc; i++) { string = Tcl_GetString(objv[i]); c = string[0]; if (c == '.') { /* Entry information */ TableEntry *tePtr; if (GetEntry(interp, tablePtr, string, &tePtr) != TCL_OK) { return TCL_ERROR; } result = InfoEntry(interp, tablePtr, tePtr); } else if ((c == 'r') || (c == 'R') || (c == 'c') || (c == 'C')) { result = InfoRowColumn(tablePtr, interp, string); } else { Tcl_AppendResult(interp, "unknown item \"", string, "\": should be widget, row, or column", (char *)NULL); return TCL_ERROR; } if (result != TCL_OK) { return TCL_ERROR; } if ((i + 1) < objc) { Tcl_AppendResult(interp, "\n", (char *)NULL); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Inserts a span of rows/columns into the table. * * table insert .f r0 2 * table insert .f c0 5 * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InsertOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; long int span; int iBefore; PartitionInfo *piPtr; RowColumn *rcPtr; int i; Blt_ChainLink before, link; int linkBefore; char *string; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } linkBefore = TRUE; string = Tcl_GetString(objv[3]); if (string[0] == '-') { if (strcmp(string, "-before") == 0) { linkBefore = TRUE; objv++; objc--; } else if (strcmp(string, "-after") == 0) { linkBefore = FALSE; objv++; objc--; } } if (objc == 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), "insert ", Tcl_GetString(objv[2]), "row|column ?span?", (char *)NULL); return TCL_ERROR; } piPtr = ParseRowColumn(tablePtr, objv[3], &iBefore); if (piPtr == NULL) { return TCL_ERROR; } span = 1; if ((objc > 4) && (Tcl_ExprLong(interp, Tcl_GetString(objv[4]), &span) != TCL_OK)) { return TCL_ERROR; } if (span < 1) { Tcl_AppendResult(interp, "span value \"", Tcl_GetString(objv[4]), "\" can't be negative", (char *)NULL); return TCL_ERROR; } before = Blt_Chain_GetNthLink(piPtr->chain, iBefore); /* * Insert the new rows/columns from the designated point in the * chain. */ for (i = 0; i < span; i++) { rcPtr = CreateRowColumn(); link = Blt_Chain_NewLink(); Blt_Chain_SetValue(link, rcPtr); if (linkBefore) { Blt_Chain_LinkBefore(piPtr->chain, link, before); } else { Blt_Chain_LinkAfter(piPtr->chain, link, before); } rcPtr->link = link; } i = 0; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); /* Reset the indices of the trailing rows/columns. */ rcPtr->index = i++; } tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SplitOp -- * * Splits a single row/column into multiple partitions. Any widgets that * span this row/column will be automatically corrected to include the * new rows/columns. * * table split .f r0 3 * table split .f c2 2 * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SplitOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; int number, split; int start, end; PartitionInfo *piPtr; RowColumn *rcPtr; int i; Blt_ChainLink after, link; TableEntry *tePtr; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } piPtr = ParseRowColumn(tablePtr, objv[3], &number); if (piPtr == NULL) { return TCL_ERROR; } split = 2; if (objc > 4) { if (Tcl_GetIntFromObj(interp, objv[4], &split) != TCL_OK) { return TCL_ERROR; } } if (split < 2) { Tcl_AppendResult(interp, "bad split value \"", Tcl_GetString(objv[4]), "\": should be 2 or greater", (char *)NULL); return TCL_ERROR; } after = Blt_Chain_GetNthLink(piPtr->chain, number); /* * Append (split - 1) additional rows/columns starting * from the current point in the chain. */ for (i = 1; i < split; i++) { rcPtr = CreateRowColumn(); link = Blt_Chain_NewLink(); Blt_Chain_SetValue(link, rcPtr); Blt_Chain_LinkAfter(piPtr->chain, link, after); rcPtr->link = link; } /* * Also increase the span of all entries that span this row/column by * split - 1. */ if (piPtr->type == rowUid) { for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); start = tePtr->row.rcPtr->index; end = tePtr->row.rcPtr->index + tePtr->row.span; if ((start <= number) && (number < end)) { tePtr->row.span += (split - 1); } } } else { for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); start = tePtr->column.rcPtr->index; end = tePtr->column.rcPtr->index + tePtr->column.span; if ((start <= number) && (number < end)) { tePtr->column.span += (split - 1); } } } /* * Be careful to renumber the rows or columns only after processing each * entry. Otherwise row/column numbering will be out of sync with the * index. */ i = number; for (link = after; link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); rcPtr->index = i++; /* Renumber the trailing indices. */ } tablePtr->flags |= REQUEST_LAYOUT; EventuallyArrangeTable(tablePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowColumnSearch -- * * Searches for the row or column designated by an x or y coordinate. * * Results: * Returns a pointer to the row/column containing the given point. If no * row/column contains the coordinate, NULL is returned. * *--------------------------------------------------------------------------- */ static RowColumn * RowColumnSearch(PartitionInfo *piPtr, int x) { Blt_ChainLink link; /* * This search assumes that rows/columns are organized in increasing * order. */ for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); /* *| |offset |offset+size | | * ^ * x */ if (x < rcPtr->offset) { return NULL; /* Too far, can't find row/column. */ } if (x < (rcPtr->offset + rcPtr->size)) { return rcPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * LocateOp -- * * * Returns the row,column index given a screen coordinate. * * Results: * Returns a standard TCL result. * * table locate .t %X %Y * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int LocateOp(TableInterpData *dataPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { RowColumn *rowPtr, *columnPtr; Table *tablePtr; Tcl_Obj *listObjPtr; int x, y; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } if (Blt_GetPixelsFromObj(interp, tablePtr->tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) { return TCL_ERROR; } if (Blt_GetPixelsFromObj(interp, tablePtr->tkwin, objv[4], PIXELS_ANY, &y) != TCL_OK) { return TCL_ERROR; } rowPtr = RowColumnSearch(&tablePtr->rows, y); if (rowPtr == NULL) { return TCL_OK; } columnPtr = RowColumnSearch(&tablePtr->cols, x); if (columnPtr == NULL) { return TCL_OK; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(rowPtr->index)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(columnPtr->index)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns a list of tables currently in use. A table is associated by * the name of its container widget. All tables matching a given pattern * are included in this list. If no pattern is present (objc == 0), all * tables are included. * * Results: * Returns a standard TCL result. If no error occurred, TCL_OK is * returned and a list of tables is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return list of names to */ int objc, Tcl_Obj *const *objv) /* Contains 0-1 arguments: search pattern */ { NamesSwitches switches; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, namesSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.slave != NULL) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tk_Window tkwin; tkwin = Tk_NameToWindow(interp, switches.slave, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } for (hPtr = Blt_FirstHashEntry(&dataPtr->tableTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Table *tablePtr; tablePtr = Blt_GetHashValue(hPtr); if (FindEntry(tablePtr, tkwin) != NULL) { Tcl_AppendElement(interp, Tk_PathName(tablePtr->tkwin)); } } } else { Blt_HashEntry *hPtr; Blt_HashSearch iter; const char *pattern; pattern = (switches.pattern == NULL) ? Tcl_GetString(objv[3]) : switches.pattern; for (hPtr = Blt_FirstHashEntry(&dataPtr->tableTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Table *tablePtr; tablePtr = Blt_GetHashValue(hPtr); if (tablePtr->interp == interp) { if ((pattern == NULL) || (Tcl_StringMatch(Tk_PathName(tablePtr->tkwin), pattern))) { Tcl_AppendElement(interp, Tk_PathName(tablePtr->tkwin)); } } } } Blt_FreeSwitches(namesSwitches, (char *)&switches, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SaveOp -- * * Returns a list of all the commands necessary to rebuild the the table. * This includes the layout of the widgets and any row, column, or table * options set. * * Results: * Returns a standard TCL result. If no error occurred, TCL_OK is * returned and a list of widget path names is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SaveOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Table *tablePtr; Blt_ChainLink link, lastl; PartitionInfo *piPtr; Tcl_DString dString; int start, last; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "\n# Table widget layout\n\n", -1); Tcl_DStringAppend(&dString, Tcl_GetString(objv[0]), -1); Tcl_DStringAppend(&dString, " ", -1); Tcl_DStringAppend(&dString, Tk_PathName(tablePtr->tkwin), -1); Tcl_DStringAppend(&dString, " \\\n", -1); lastl = Blt_Chain_LastLink(tablePtr->chain); for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; tePtr = Blt_Chain_GetValue(link); PrintEntry(tePtr, &dString); if (link != lastl) { Tcl_DStringAppend(&dString, " \\\n", -1); } } Tcl_DStringAppend(&dString, "\n\n# Row configuration options\n\n", -1); piPtr = &tablePtr->rows; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); start = Tcl_DStringLength(&dString); Tcl_DStringAppend(&dString, Tcl_GetString(objv[0]), -1); Tcl_DStringAppend(&dString, " configure ", -1); Tcl_DStringAppend(&dString, Tk_PathName(tablePtr->tkwin), -1); Tcl_DStringAppend(&dString, " r", -1); Tcl_DStringAppend(&dString, Blt_Itoa(rcPtr->index), -1); last = Tcl_DStringLength(&dString); PrintRowColumn(interp, piPtr, rcPtr, &dString); if (Tcl_DStringLength(&dString) == last) { Tcl_DStringSetLength(&dString, start); } else { Tcl_DStringAppend(&dString, "\n", -1); } } Tcl_DStringAppend(&dString, "\n\n# Column configuration options\n\n", -1); piPtr = &tablePtr->cols; for (link = Blt_Chain_FirstLink(piPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { RowColumn *rcPtr; rcPtr = Blt_Chain_GetValue(link); start = Tcl_DStringLength(&dString); Tcl_DStringAppend(&dString, Tcl_GetString(objv[0]), -1); Tcl_DStringAppend(&dString, " configure ", -1); Tcl_DStringAppend(&dString, Tk_PathName(tablePtr->tkwin), -1); Tcl_DStringAppend(&dString, " c", -1); Tcl_DStringAppend(&dString, Blt_Itoa(rcPtr->index), -1); last = Tcl_DStringLength(&dString); PrintRowColumn(interp, piPtr, rcPtr, &dString); if (Tcl_DStringLength(&dString) == last) { Tcl_DStringSetLength(&dString, start); } else { Tcl_DStringAppend(&dString, "\n", -1); } } start = Tcl_DStringLength(&dString); Tcl_DStringAppend(&dString, "\n\n# Table configuration options\n\n", -1); Tcl_DStringAppend(&dString, Tcl_GetString(objv[0]), -1); Tcl_DStringAppend(&dString, " configure ", -1); Tcl_DStringAppend(&dString, Tk_PathName(tablePtr->tkwin), -1); last = Tcl_DStringLength(&dString); PrintTable(tablePtr, &dString); if (Tcl_DStringLength(&dString) == last) { Tcl_DStringSetLength(&dString, start); } else { Tcl_DStringAppend(&dString, "\n", -1); } Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SearchOp -- * * Returns a list of all the pathnames of the widgets managed by a table * geometry manager. The table is given by the path name of a container * widget associated with the table. * * Results: * Returns a standard TCL result. If no error occurred, TCL_OK is * returned and a list of widget path names is left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SearchOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return list of names to */ int objc, /* Number of arguments */ Tcl_Obj *const *objv) /* Contains 1-2 arguments: pathname of * container widget associated with the table * and search pattern */ { Table *tablePtr; Blt_ChainLink link; SearchSwitches switches; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); switches.tablePtr = tablePtr; if (Blt_ParseSwitches(interp, searchSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } /* Find entries that match the search criteria. */ for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { TableEntry *tePtr; tePtr = Blt_Chain_GetValue(link); if (switches.pattern != NULL) { if (!Tcl_StringMatch(Tk_PathName(tePtr->tkwin), switches.pattern)) { continue; } } if (switches.flags & MATCH_SPAN) { if ((switches.rspan >= 0) && (tePtr->row.rcPtr->index > switches.rspan) && ((tePtr->row.rcPtr->index + tePtr->row.span) < switches.rspan)){ continue; } if ((switches.cspan >= 0) && ((tePtr->column.rcPtr->index > switches.cspan) || ((tePtr->column.rcPtr->index + tePtr->column.span) < switches.cspan))) { continue; } } if (switches.flags & MATCH_START) { if ((switches.rstart >= 0) && (tePtr->row.rcPtr->index != switches.rstart)) { continue; } if ((switches.cstart >= 0) && (tePtr->column.rcPtr->index != switches.cstart)) { continue; } } Tcl_AppendElement(interp, Tk_PathName(tePtr->tkwin)); } Blt_FreeSwitches(searchSwitches, (char *)&switches, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Table operations. * * The fields for Blt_OpSpec are as follows: * * - operation name * - minimum number of characters required to disambiguate the operation name. * - function associated with operation. * - minimum number of arguments required. * - maximum number of arguments allowed (0 indicates no limit). * - usage string * *--------------------------------------------------------------------------- */ static Blt_OpSpec tableOps[] = { {"arrange", 1, ArrangeOp, 3, 3, "container",}, {"cget", 2, CgetOp, 4, 5, "container ?row|column|widget? option",}, {"configure", 3, ConfigureOp, 3, 0, "container ?row|column|widget?... ?option value?...",}, {"containers", 3, NamesOp, 2, 4, "?switch? ?arg?",}, {"delete", 1, DeleteOp, 3, 0, "container row|column ?row|column?",}, {"extents", 1, ExtentsOp, 4, 4, "container row|column|widget",}, {"forget", 1, ForgetOp, 3, 0, "widget ?widget?...",}, {"info", 3, InfoOp, 3, 0, "container ?row|column|widget?...",}, {"insert", 3, InsertOp, 4, 6, "container ?-before|-after? row|column ?count?",}, {"join", 1, JoinOp, 5, 5, "container first last",}, {"locate", 2, LocateOp, 5, 5, "container x y",}, {"names", 1, NamesOp, 2, 4, "?switch? ?arg?",}, {"save", 2, SaveOp, 3, 3, "container",}, {"search", 2, SearchOp, 3, 0, "container ?switch arg?...",}, {"split", 2, SplitOp, 4, 5, "container row|column div",}, }; static int nTableOps = sizeof(tableOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * TableCmd -- * * This procedure is invoked to process the TCL command that corresponds * to the table geometry manager. See the user documentation for details * on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int TableCmd( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TableInterpData *dataPtr = clientData; TableCmdProc *proc; if (objc > 1) { char *string; string = Tcl_GetString(objv[1]); if (string[0] == '.') { Table *tablePtr; if (Blt_GetTableFromObj(clientData, interp, objv[1], &tablePtr) != TCL_OK) { Tcl_ResetResult(interp); tablePtr = CreateTable(dataPtr, interp, string); if (tablePtr == NULL) { return TCL_ERROR; } } return BuildTable(tablePtr, interp, objc, objv); } } proc = Blt_GetOpFromObj(interp, nTableOps, tableOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc)(dataPtr, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * TableInterpDeleteProc -- * * This is called when the interpreter hosting the table command is * destroyed. * * Results: * None. * * Side effects: * Destroys all the hash table maintaining the names of the table * geometry managers. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TableInterpDeleteProc( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp) { TableInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->tableTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Table *tablePtr; tablePtr = Blt_GetHashValue(hPtr); tablePtr->hashPtr = NULL; DestroyTable((DestroyData)tablePtr); } Blt_DeleteHashTable(&dataPtr->tableTable); Tcl_DeleteAssocData(interp, TABLE_THREAD_KEY); Blt_Free(dataPtr); } static TableInterpData * GetTableInterpData(Tcl_Interp *interp) { TableInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (TableInterpData *) Tcl_GetAssocData(interp, TABLE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(TableInterpData)); dataPtr->tkMain = Tk_MainWindow(interp); Tcl_SetAssocData(interp, TABLE_THREAD_KEY, TableInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->tableTable, BLT_ONE_WORD_KEYS); } return dataPtr; } /* *--------------------------------------------------------------------------- * * Blt_TableMgrCmdInitProc -- * * This procedure is invoked to initialize the TCL command that * corresponds to the table geometry manager. * * Results: * None. * * Side effects: * Creates the new TCL command. * *--------------------------------------------------------------------------- */ int Blt_TableMgrCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "table", TableCmd, }; cmdSpec.clientData = GetTableInterpData(interp); rowUid = (Blt_Uid)Tk_GetUid("row"); columnUid = (Blt_Uid)Tk_GetUid("column"); return Blt_InitCmd(interp, "::blt", &cmdSpec); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTvStyle.c������������������������������������������������������������������0000644�0001750�0001750�00000236064�11462120063�015321� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTvStyle.c -- * * This module implements styles for treeview widget cells. * * Copyright 1998-2008 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_TREEVIEW #include <X11/Xutil.h> #include <X11/Xatom.h> #include "bltOp.h" #include "bltTreeView.h" #include "bltList.h" #include "bltPicture.h" #include "bltPainter.h" typedef int (TreeViewCmdProc)(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #define STYLE_GAP 2 #define ARROW_WIDTH 13 static Blt_OptionParseProc ObjToIcon; static Blt_OptionPrintProc IconToObj; static Blt_OptionFreeProc FreeIcon; Blt_CustomOption bltTreeViewIconOption = { ObjToIcon, IconToObj, FreeIcon, NULL, }; #define DEF_STYLE_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_STYLE_HIGHLIGHT_FOREGROUND STD_NORMAL_FOREGROUND #ifdef WIN32 #define DEF_STYLE_ACTIVE_BACKGROUND RGB_GREY85 #else #define DEF_STYLE_ACTIVE_BACKGROUND RGB_GREY95 #endif #define DEF_STYLE_ACTIVE_FOREGROUND STD_ACTIVE_FOREGROUND #define DEF_STYLE_GAP "2" typedef struct { int refCount; /* Usage reference count. */ unsigned int flags; const char *name; TreeViewStyleClass *classPtr; /* Class-specific routines to manage * style. */ Blt_HashEntry *hashPtr; Blt_ChainLink link; /* General style fields. */ Tk_Cursor cursor; /* X Cursor */ TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be * drawn in the cell. */ int gap; /* # pixels gap between icon and * text. */ Blt_Font font; XColor *fgColor; /* Normal foreground color of cell. */ XColor *highlightFgColor; /* Foreground color of cell when * highlighted. */ XColor *activeFgColor; /* Foreground color of cell when * active. */ XColor *selFgColor; /* Foreground color of a selected * cell. If non-NULL, overrides default * foreground color specification. */ Blt_Background bg; /* Normal background color of cell. */ Blt_Background highlightBg; /* Background color of cell when * highlighted. */ Blt_Background activeBg; /* Background color of cell when * active. */ Blt_Background selBg; /* Background color of a selected * cell. If non-NULL, overrides the * default background color * specification. */ const char *validateCmd; /* TextBox-specific fields */ GC gc; GC highlightGC; GC activeGC; int side; /* Position of the text in relation to * the icon. */ Blt_TreeKey key; /* Actual data resides in this tree value. */ Tcl_Obj *cmdObjPtr; } TreeViewTextBox; #ifdef WIN32 #define DEF_TEXTBOX_CURSOR "arrow" #else #define DEF_TEXTBOX_CURSOR "hand2" #endif /*WIN32*/ #define DEF_TEXTBOX_SIDE "left" #define DEF_TEXTBOX_VALIDATE_COMMAND (char *)NULL #define DEF_TEXTBOX_COMMAND (char *)NULL #define TextBoxOffset(x) Blt_Offset(TreeViewTextBox, x) static Blt_ConfigSpec textBoxSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND, TextBoxOffset(activeBg), 0}, {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND, TextBoxOffset(activeFgColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", (char *)NULL, TextBoxOffset(bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_TEXTBOX_COMMAND, TextBoxOffset(cmdObjPtr), 0}, {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor", DEF_TEXTBOX_CURSOR, TextBoxOffset(cursor), 0}, {BLT_CONFIG_BITMASK, "-edit", "edit", "Edit", (char *)NULL, TextBoxOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)STYLE_EDITABLE}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", (char *)NULL, TextBoxOffset(font), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", (char *)NULL, TextBoxOffset(fgColor),BLT_CONFIG_NULL_OK }, {BLT_CONFIG_PIXELS_NNEG, "-gap", "gap", "Gap", DEF_STYLE_GAP, TextBoxOffset(gap), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND, TextBoxOffset(highlightBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground", "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND, TextBoxOffset(highlightFgColor), 0}, {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", (char *)NULL, TextBoxOffset(icon), BLT_CONFIG_NULL_OK, &bltTreeViewIconOption}, {BLT_CONFIG_STRING, "-key", "key", "key", (char *)NULL, TextBoxOffset(key), BLT_CONFIG_NULL_OK, 0}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", (char *)NULL, TextBoxOffset(selBg), 0}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", (char *)NULL, TextBoxOffset(selFgColor), 0}, {BLT_CONFIG_SIDE, "-side", "side", "side", DEF_TEXTBOX_SIDE, TextBoxOffset(side), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-validatecommand", "validateCommand", "ValidateCommand", DEF_TEXTBOX_VALIDATE_COMMAND, TextBoxOffset(validateCmd), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; typedef struct { int refCount; /* Usage reference count. */ unsigned int flags; /* Contains style type and update * flags. */ const char *name; /* Instance name. */ TreeViewStyleClass *classPtr; /* Class-specific routines to manage * style. */ Blt_HashEntry *hashPtr; Blt_ChainLink link; /* General style fields. */ Tk_Cursor cursor; /* X Cursor */ TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be * drawn in the cell. */ int gap; /* # pixels gap between icon and * text. */ Blt_Font font; XColor *fgColor; /* Normal foreground color of cell. */ XColor *highlightFgColor; /* Foreground color of cell when * highlighted. */ XColor *activeFgColor; /* Foreground color of cell when * active. */ XColor *selFgColor; /* Foreground color of a selected * cell. If non-NULL, overrides * default foreground color * specification. */ Blt_Background bg; /* Normal background color of cell. */ Blt_Background highlightBg; /* Background color of cell when * highlighted. */ Blt_Background activeBg; /* Background color of cell when * active. */ Blt_Background selBg; /* Background color of a selected * cell. If non-NULL, overrides the * default background color * specification. */ const char *validateCmd; /* Checkbox specific fields. */ GC gc; GC highlightGC; GC activeGC; Blt_TreeKey key; /* Actual data resides in this tree value. */ int size; /* Size of the checkbox. */ int showValue; /* If non-zero, display the on/off * value. */ const char *onValue; const char *offValue; int lineWidth; /* Linewidth of the surrounding * box. */ XColor *boxColor; /* Rectangle (box) color (grey). */ XColor *fillColor; /* Fill color (white) */ XColor *checkColor; /* Check color (red). */ TextLayout *onPtr, *offPtr; Blt_Painter painter; Blt_Picture selectedPicture; Blt_Picture normalPicture; Blt_Picture disabledPicture; Tcl_Obj *cmdObjPtr; /* If non-NULL, command to be invoked * when check is clicked. */ } TreeViewCheckBox; #define DEF_CHECKBOX_BOX_COLOR (char *)NULL #define DEF_CHECKBOX_CHECK_COLOR "red" #define DEF_CHECKBOX_COMMAND (char *)NULL #define DEF_CHECKBOX_FILL_COLOR (char *)NULL #define DEF_CHECKBOX_OFFVALUE "0" #define DEF_CHECKBOX_ONVALUE "1" #define DEF_CHECKBOX_SHOWVALUE "yes" #define DEF_CHECKBOX_SIZE "11" #define DEF_CHECKBOX_LINEWIDTH "2" #define DEF_CHECKBOX_GAP "4" #ifdef WIN32 #define DEF_CHECKBOX_CURSOR "arrow" #else #define DEF_CHECKBOX_CURSOR "hand2" #endif /*WIN32*/ #define CheckBoxOffset(x) Blt_Offset(TreeViewCheckBox, x) static Blt_ConfigSpec checkBoxSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND, CheckBoxOffset(activeBg), 0}, {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND, CheckBoxOffset(activeFgColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", (char *)NULL, CheckBoxOffset(bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_POS, "-boxsize", "boxSize", "BoxSize", DEF_CHECKBOX_SIZE, CheckBoxOffset(size), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_CHECKBOX_COMMAND, CheckBoxOffset(cmdObjPtr), 0}, {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor", DEF_CHECKBOX_CURSOR, CheckBoxOffset(cursor), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", (char *)NULL, CheckBoxOffset(font), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", (char *)NULL, CheckBoxOffset(fgColor), BLT_CONFIG_NULL_OK }, {BLT_CONFIG_PIXELS_NNEG, "-gap", "gap", "Gap", DEF_CHECKBOX_GAP, CheckBoxOffset(gap), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND, CheckBoxOffset(highlightBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground", "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND, CheckBoxOffset(highlightFgColor), 0}, {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", (char *)NULL, CheckBoxOffset(icon), BLT_CONFIG_NULL_OK, &bltTreeViewIconOption}, {BLT_CONFIG_STRING, "-key", "key", "key", (char *)NULL, CheckBoxOffset(key), BLT_CONFIG_NULL_OK, 0}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_CHECKBOX_LINEWIDTH, CheckBoxOffset(lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-checkcolor", "checkColor", "CheckColor", DEF_CHECKBOX_CHECK_COLOR, CheckBoxOffset(checkColor), 0}, {BLT_CONFIG_COLOR, "-boxcolor", "boxColor", "BoxColor", DEF_CHECKBOX_BOX_COLOR, CheckBoxOffset(boxColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-fillcolor", "fillColor", "FillColor", DEF_CHECKBOX_FILL_COLOR, CheckBoxOffset(fillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-offvalue", "offValue", "OffValue", DEF_CHECKBOX_OFFVALUE, CheckBoxOffset(offValue), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-onvalue", "onValue", "OnValue", DEF_CHECKBOX_ONVALUE, CheckBoxOffset(onValue), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-key", "key", "key", (char *)NULL, CheckBoxOffset(key), BLT_CONFIG_NULL_OK, 0}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", (char *)NULL, CheckBoxOffset(selBg), 0}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", (char *)NULL, CheckBoxOffset(selFgColor), 0}, {BLT_CONFIG_BOOLEAN, "-showvalue", "showValue", "ShowValue", DEF_CHECKBOX_SHOWVALUE, CheckBoxOffset(showValue), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; typedef struct { int refCount; /* Usage reference count. */ unsigned int flags; const char *name; TreeViewStyleClass *classPtr; /* Class-specific style routines. */ Blt_HashEntry *hashPtr; Blt_ChainLink link; /* General style fields. */ Tk_Cursor cursor; /* X Cursor */ TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be * drawn in the cell. */ int gap; /* # pixels gap between icon and * text. */ Blt_Font font; XColor *fgColor; /* Normal foreground color of cell. */ XColor *highlightFgColor; /* Foreground color of cell when * highlighted. */ XColor *activeFgColor; /* Foreground color of cell when * active. */ XColor *selFgColor; /* Foreground color of a selected * cell. If non-NULL, overrides * default foreground color * specification. */ Blt_Background bg; /* Normal background color of cell. */ Blt_Background highlightBg; /* Background color of cell when * highlighted. */ Blt_Background activeBg; /* Background color of cell when * active. */ Blt_Background selBg; /* Background color of a selected * cell. If non-NULL, overrides the * default background color * specification. */ const char *validateCmd; /* ComboBox-specific fields */ GC gc; GC highlightGC; GC activeGC; int borderWidth; /* Width of outer border surrounding * the entire box. */ int relief; /* Relief of outer border. */ Blt_TreeKey key; /* Actual data resides in this tree value. */ const char *choices; /* List of available choices. */ const char *choiceIcons; /* List of icons associated with * choices. */ int scrollWidth; int arrow; int arrowWidth; int arrowBW; /* Border width of arrow. */ int arrowRelief; /* Normal relief of arrow. */ } TreeViewComboBox; #define DEF_COMBOBOX_BORDERWIDTH "1" #define DEF_COMBOBOX_ARROW_BORDERWIDTH "1" #define DEF_COMBOBOX_ARROW_RELIEF "raised" #define DEF_COMBOBOX_RELIEF "flat" #ifdef WIN32 #define DEF_COMBOBOX_CURSOR "arrow" #else #define DEF_COMBOBOX_CURSOR "hand2" #endif /*WIN32*/ #define ComboBoxOffset(x) Blt_Offset(TreeViewComboBox, x) static Blt_ConfigSpec comboBoxSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND, ComboBoxOffset(activeBg), 0}, {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND, ComboBoxOffset(activeFgColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", (char *)NULL, ComboBoxOffset(bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_COMBOBOX_BORDERWIDTH, ComboBoxOffset(borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-arrowrelief", "arrowRelief", "ArrowRelief", DEF_COMBOBOX_ARROW_RELIEF, ComboBoxOffset(arrowRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-arrowborderwidth", "arrowBorderWidth", "ArrowBorderWidth", DEF_COMBOBOX_ARROW_BORDERWIDTH, ComboBoxOffset(arrowBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor", DEF_COMBOBOX_CURSOR, ComboBoxOffset(cursor), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", (char *)NULL, ComboBoxOffset(font), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", (char *)NULL, ComboBoxOffset(fgColor), BLT_CONFIG_NULL_OK }, {BLT_CONFIG_PIXELS_NNEG, "-gap", "gap", "Gap", DEF_STYLE_GAP, ComboBoxOffset(gap), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND, ComboBoxOffset(highlightBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground", "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND, ComboBoxOffset(highlightFgColor), 0}, {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", (char *)NULL, ComboBoxOffset(icon), BLT_CONFIG_NULL_OK, &bltTreeViewIconOption}, {BLT_CONFIG_STRING, "-key", "key", "key", (char *)NULL, ComboBoxOffset(key), BLT_CONFIG_NULL_OK, 0}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_COMBOBOX_RELIEF, ComboBoxOffset(relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", (char *)NULL, ComboBoxOffset(selBg), 0}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", (char *)NULL, ComboBoxOffset(selFgColor), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; typedef TreeViewStyle *(StyleCreateProc)(TreeView *viewPtr,Blt_HashEntry *hPtr); static StyleConfigProc ConfigureTextBox, ConfigureCheckBox, ConfigureComboBox; static StyleCreateProc CreateTextBox, CreateCheckBox, CreateComboBox; static StyleDrawProc DrawTextBox, DrawCheckBox, DrawComboBox; static StyleEditProc EditTextBox, EditCheckBox, EditComboBox; static StyleFreeProc FreeTextBox, FreeCheckBox, FreeComboBox; static StyleMeasureProc MeasureTextBox, MeasureCheckBox, MeasureComboBox; #ifdef notdef static StylePickProc PickCheckBox; #endif static StylePickProc PickComboBox; /* *--------------------------------------------------------------------------- * * ObjToIcon -- * * Convert the name of an icon into a Tk image. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIcon( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeView *viewPtr = clientData; TreeViewIcon *iconPtr = (TreeViewIcon *)(widgRec + offset); TreeViewIcon icon; const char *string; int length; string = Tcl_GetStringFromObj(objPtr, &length); icon = NULL; if (length > 0) { icon = Blt_TreeView_GetIcon(viewPtr, Tcl_GetString(objPtr)); if (icon == NULL) { return TCL_ERROR; } } if (*iconPtr != NULL) { Blt_TreeView_FreeIcon(viewPtr, *iconPtr); } *iconPtr = icon; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObj -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewIcon icon = *(TreeViewIcon *)(widgRec + offset); if (icon == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(Blt_Image_Name((icon)->tkImage), -1); } } /*ARGSUSED*/ static void FreeIcon( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { TreeViewIcon *iconPtr = (TreeViewIcon *)(widgRec + offset); TreeView *viewPtr = clientData; if (*iconPtr != NULL) { Blt_TreeView_FreeIcon(viewPtr, *iconPtr); *iconPtr = NULL; } } static TreeViewStyleClass textBoxClass = { "TextBoxStyle", textBoxSpecs, ConfigureTextBox, MeasureTextBox, DrawTextBox, NULL, EditTextBox, FreeTextBox, }; static TreeViewStyleClass checkBoxClass = { "CheckBoxStyle", checkBoxSpecs, ConfigureCheckBox, MeasureCheckBox, DrawCheckBox, NULL, EditCheckBox, FreeCheckBox, }; static TreeViewStyleClass comboBoxClass = { "ComboBoxStyle", comboBoxSpecs, ConfigureComboBox, MeasureComboBox, DrawComboBox, NULL, EditComboBox, FreeComboBox, }; /* *--------------------------------------------------------------------------- * * CreateTextBox -- * * Creates a "textbox" style. * * Results: * A pointer to the new style structure. * *--------------------------------------------------------------------------- */ static TreeViewStyle * CreateTextBox(TreeView *viewPtr, Blt_HashEntry *hPtr) { TreeViewTextBox *tbPtr; tbPtr = Blt_AssertCalloc(1, sizeof(TreeViewTextBox)); tbPtr->classPtr = &textBoxClass; tbPtr->side = SIDE_LEFT; tbPtr->gap = STYLE_GAP; tbPtr->name = Blt_AssertStrdup(Blt_GetHashKey(&viewPtr->styleTable, hPtr)); tbPtr->hashPtr = hPtr; tbPtr->link = NULL; tbPtr->flags = STYLE_TEXTBOX; tbPtr->refCount = 1; Blt_SetHashValue(hPtr, tbPtr); return (TreeViewStyle *)tbPtr; } /* *--------------------------------------------------------------------------- * * ConfigureTextBox -- * * Configures a "textbox" style. This routine performs generates the GCs * required for a textbox style. * * Results: * None. * * Side Effects: * GCs are created for the style. * *--------------------------------------------------------------------------- */ static void ConfigureTextBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; GC newGC; XGCValues gcValues; unsigned long gcMask; gcMask = GCForeground | GCFont; gcValues.font = Blt_FontId(CHOOSE(viewPtr->font, tbPtr->font)); /* Normal GC */ gcValues.foreground = CHOOSE(viewPtr->fgColor, tbPtr->fgColor)->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (tbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->gc); } tbPtr->gc = newGC; /* Highlight GC */ gcValues.foreground = tbPtr->highlightFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (tbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->highlightGC); } tbPtr->highlightGC = newGC; /* Active GC */ gcValues.foreground = tbPtr->activeFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (tbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->activeGC); } tbPtr->activeGC = newGC; tbPtr->flags |= STYLE_DIRTY; } /* *--------------------------------------------------------------------------- * * MeasureTextBox -- * * Determines the space requirements for the "textbox" given the value to * be displayed. Depending upon whether an icon or text is displayed and * their relative placements, this routine computes the space needed for * the text entry. * * Results: * None. * * Side Effects: * The width and height fields of *valuePtr* are set with the computed * dimensions. * *--------------------------------------------------------------------------- */ static void MeasureTextBox( TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewValue *valuePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; int iconWidth, iconHeight; int textWidth, textHeight; int gap; textWidth = textHeight = 0; iconWidth = iconHeight = 0; valuePtr->width = valuePtr->height = 0; if (tbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(tbPtr->icon); iconHeight = TreeView_IconHeight(tbPtr->icon); } if (valuePtr->textPtr != NULL) { Blt_Free(valuePtr->textPtr); valuePtr->textPtr = NULL; } if (valuePtr->fmtString != NULL) { /* New string defined. */ TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, CHOOSE(viewPtr->font, tbPtr->font)); valuePtr->textPtr = Blt_Ts_CreateLayout(valuePtr->fmtString, -1, &ts); } gap = 0; if (valuePtr->textPtr != NULL) { textWidth = valuePtr->textPtr->width; textHeight = valuePtr->textPtr->height; if (tbPtr->icon != NULL) { gap = tbPtr->gap; } } if (tbPtr->side & (SIDE_TOP | SIDE_BOTTOM)) { valuePtr->width = MAX(textWidth, iconWidth); valuePtr->height = iconHeight + gap + textHeight; } else { valuePtr->width = iconWidth + gap + textWidth; valuePtr->height = MAX(textHeight, iconHeight); } } /* *--------------------------------------------------------------------------- * * DrawTextBox -- * * Draws the "textbox" given the screen coordinates and the value to be * displayed. * * Results: * None. * * Side Effects: * The textbox value is drawn. * *--------------------------------------------------------------------------- */ static void DrawTextBox(TreeView *viewPtr, Drawable drawable, TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int x, int y) { TreeViewColumn *colPtr; TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; int iconX, iconY, iconWidth, iconHeight; int textX, textY, textWidth, textHeight; int gap, columnWidth; Blt_Background bg; XColor *fgColor; colPtr = valuePtr->columnPtr; if (stylePtr->flags & STYLE_HIGHLIGHT) { bg = tbPtr->highlightBg; fgColor = tbPtr->highlightFgColor; } else { if (tbPtr->bg != NULL) { bg = tbPtr->bg; } else { bg = ((viewPtr->altBg != NULL) && (entryPtr->flatIndex & 0x1)) ? viewPtr->altBg : viewPtr->bg; } fgColor = CHOOSE(viewPtr->fgColor, tbPtr->fgColor); } if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { bg = (stylePtr->selBg != NULL) ? stylePtr->selBg : viewPtr->selBg; } /* * Draw the active or normal background color over the entire label area. * This includes both the tab's text and image. The rectangle should be 2 * pixels wider/taller than this area. So if the label consists of just an * image, we get an halo around the image when the tab is active. */ if (bg != NULL) { Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, colPtr->width, entryPtr->height + 1, 0, TK_RELIEF_FLAT); } columnWidth = colPtr->width - (2 * colPtr->borderWidth + PADDING(colPtr->pad)); if (columnWidth > valuePtr->width) { switch(colPtr->justify) { case TK_JUSTIFY_RIGHT: x += (columnWidth - valuePtr->width); break; case TK_JUSTIFY_CENTER: x += (columnWidth - valuePtr->width) / 2; break; case TK_JUSTIFY_LEFT: break; } } textX = textY = iconX = iconY = 0; /* Suppress compiler warning. */ iconWidth = iconHeight = 0; if (tbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(tbPtr->icon); iconHeight = TreeView_IconHeight(tbPtr->icon); } textWidth = textHeight = 0; if (valuePtr->textPtr != NULL) { textWidth = valuePtr->textPtr->width; textHeight = valuePtr->textPtr->height; } gap = 0; if ((tbPtr->icon != NULL) && (valuePtr->textPtr != NULL)) { gap = tbPtr->gap; } switch (tbPtr->side) { case SIDE_RIGHT: textX = x; textY = y + (entryPtr->height - textHeight) / 2; iconX = textX + textWidth + gap; iconY = y + (entryPtr->height - iconHeight) / 2; break; case SIDE_LEFT: iconX = x; iconY = y + (entryPtr->height - iconHeight) / 2; textX = iconX + iconWidth + gap; textY = y + (entryPtr->height - textHeight) / 2; break; case SIDE_TOP: iconY = y; iconX = x + (columnWidth - iconWidth) / 2; textY = iconY + iconHeight + gap; textX = x + (columnWidth - textWidth) / 2; break; case SIDE_BOTTOM: textY = y; textX = x + (columnWidth - textWidth) / 2; iconY = textY + textHeight + gap; iconX = x + (columnWidth - iconWidth) / 2; break; } if (tbPtr->icon != NULL) { Tk_RedrawImage(TreeView_IconBits(tbPtr->icon), 0, 0, iconWidth, iconHeight, drawable, iconX, iconY); } if (valuePtr->textPtr != NULL) { TextStyle ts; XColor *color; Blt_Font font; int xMax; font = CHOOSE(viewPtr->font, tbPtr->font); if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { if (stylePtr->selFgColor != NULL) { color = stylePtr->selFgColor; } else { color = viewPtr->selFgColor; } } else if (entryPtr->color != NULL) { color = entryPtr->color; } else { color = fgColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); Blt_Ts_SetForeground(ts, color); xMax = colPtr->width - colPtr->titleBW - colPtr->pad.side2; Blt_Ts_SetMaxLength(ts, xMax); Blt_Ts_DrawLayout(viewPtr->tkwin, drawable, valuePtr->textPtr, &ts, textX, textY); } stylePtr->flags &= ~STYLE_DIRTY; } /* *--------------------------------------------------------------------------- * * EditCombobox -- * * Edits the "combobox". * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EditTextBox(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr, TreeViewStyle *stylePtr) { return Blt_TreeView_CreateTextbox(viewPtr, entryPtr, colPtr); } /* *--------------------------------------------------------------------------- * * FreeTextBox -- * * Releases resources allocated for the textbox. The resources freed by * this routine are specific only to the "textbox". Other resources * (common to all styles) are freed in the Blt_TreeView_FreeStyle * routine. * * Results: * None. * * Side Effects: * GCs allocated for the textbox are freed. * *--------------------------------------------------------------------------- */ static void FreeTextBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; if (tbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->highlightGC); } if (tbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->activeGC); } if (tbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, tbPtr->gc); } if (tbPtr->icon != NULL) { Blt_TreeView_FreeIcon(viewPtr, tbPtr->icon); } } /* *--------------------------------------------------------------------------- * * CreateCheckbox -- * * Creates a "checkbox" style. * * Results: * A pointer to the new style structure. * *--------------------------------------------------------------------------- */ static TreeViewStyle * CreateCheckBox(TreeView *viewPtr, Blt_HashEntry *hPtr) { TreeViewCheckBox *cbPtr; cbPtr = Blt_AssertCalloc(1, sizeof(TreeViewCheckBox)); cbPtr->classPtr = &checkBoxClass; cbPtr->gap = 4; cbPtr->size = 18; cbPtr->lineWidth = 2; cbPtr->showValue = TRUE; cbPtr->name = Blt_AssertStrdup(Blt_GetHashKey(&viewPtr->styleTable, hPtr)); cbPtr->hashPtr = hPtr; cbPtr->link = NULL; cbPtr->flags = STYLE_CHECKBOX; cbPtr->refCount = 1; Blt_SetHashValue(hPtr, cbPtr); return (TreeViewStyle *)cbPtr; } /* *--------------------------------------------------------------------------- * * ConfigureCheckbox -- * * Configures a "checkbox" style. This routine performs generates the * GCs required for a checkbox style. * * Results: * None. * * Side Effects: * GCs are created for the style. * *--------------------------------------------------------------------------- */ static void ConfigureCheckBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { GC newGC; TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; XColor *bgColor; XGCValues gcValues; unsigned long gcMask; gcMask = GCForeground | GCBackground | GCFont; gcValues.font = Blt_FontId(CHOOSE(viewPtr->font, cbPtr->font)); bgColor = Blt_BackgroundBorderColor(CHOOSE(viewPtr->bg, cbPtr->bg)); gcValues.background = bgColor->pixel; gcValues.foreground = CHOOSE(viewPtr->fgColor, cbPtr->fgColor)->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->gc); } cbPtr->gc = newGC; gcValues.background = Blt_BackgroundBorderColor(cbPtr->highlightBg)->pixel; gcValues.foreground = cbPtr->highlightFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->highlightGC); } cbPtr->highlightGC = newGC; gcValues.background = Blt_BackgroundBorderColor(cbPtr->activeBg)->pixel; gcValues.foreground = cbPtr->activeFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->activeGC); } cbPtr->activeGC = newGC; cbPtr->flags |= STYLE_DIRTY; } /* *--------------------------------------------------------------------------- * * MeasureCheckbox -- * * Determines the space requirements for the "checkbox" given the value * to be displayed. Depending upon whether an icon or text is displayed * and their relative placements, this routine computes the space needed * for the text entry. * * Results: * None. * * Side Effects: * The width and height fields of *valuePtr* are set with the * computed dimensions. * *--------------------------------------------------------------------------- */ static void MeasureCheckBox(TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewValue *valuePtr) { TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; int iconWidth, iconHeight; int textWidth, textHeight; int gap; int boxWidth, boxHeight; boxWidth = boxHeight = ODD(cbPtr->size); textWidth = textHeight = iconWidth = iconHeight = 0; valuePtr->width = valuePtr->height = 0; if (cbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(cbPtr->icon); iconHeight = TreeView_IconHeight(cbPtr->icon); } if (cbPtr->onPtr != NULL) { Blt_Free(cbPtr->onPtr); cbPtr->onPtr = NULL; } if (cbPtr->offPtr != NULL) { Blt_Free(cbPtr->offPtr); cbPtr->offPtr = NULL; } gap = 0; if (cbPtr->showValue) { TextStyle ts; const char *string; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, CHOOSE(viewPtr->font, cbPtr->font)); string = (cbPtr->onValue != NULL) ? cbPtr->onValue : valuePtr->fmtString; cbPtr->onPtr = Blt_Ts_CreateLayout(string, -1, &ts); string = (cbPtr->offValue != NULL) ? cbPtr->offValue : valuePtr->fmtString; cbPtr->offPtr = Blt_Ts_CreateLayout(string, -1, &ts); textWidth = MAX(cbPtr->offPtr->width, cbPtr->onPtr->width); textHeight = MAX(cbPtr->offPtr->height, cbPtr->onPtr->height); if (cbPtr->icon != NULL) { gap = cbPtr->gap; } } valuePtr->width = cbPtr->gap * 2 + boxWidth + iconWidth + gap + textWidth; valuePtr->height = MAX3(boxHeight, textHeight, iconHeight) | 0x1; } /* *--------------------------------------------------------------------------- * * DrawCheckbox -- * * Draws the "checkbox" given the screen coordinates and the * value to be displayed. * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ static void DrawCheckBox(TreeView *viewPtr, Drawable drawable, TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int x, int y) { Blt_Background bg; Blt_Font font; TextLayout *textPtr; TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; TreeViewColumn *colPtr; XColor *fgColor; int bool; int borderWidth, relief; int gap, columnWidth; int iconX, iconY, iconWidth, iconHeight; int textX, textY, textHeight; int xBox, yBox, boxWidth, boxHeight; font = CHOOSE(viewPtr->font, cbPtr->font); colPtr = valuePtr->columnPtr; borderWidth = 0; relief = TK_RELIEF_FLAT; if (valuePtr == viewPtr->activeValuePtr) { bg = cbPtr->activeBg; fgColor = cbPtr->activeFgColor; borderWidth = 1; relief = TK_RELIEF_RAISED; } else if (stylePtr->flags & STYLE_HIGHLIGHT) { bg = cbPtr->highlightBg; fgColor = cbPtr->highlightFgColor; } else { /* If a background was specified, override the current background. * Otherwise, use the standard background taking into consideration if * its the odd or even color. */ if (cbPtr->bg != NULL) { bg = cbPtr->bg; } else { bg = ((viewPtr->altBg != NULL) && (entryPtr->flatIndex & 0x1)) ? viewPtr->altBg : viewPtr->bg; } fgColor = CHOOSE(viewPtr->fgColor, cbPtr->fgColor); } columnWidth = colPtr->width - PADDING(colPtr->pad); /* * Draw the active or normal background color over the entire label area. * This includes both the tab's text and image. The rectangle should be 2 * pixels wider/taller than this area. So if the label consists of just an * image, we get an halo around the image when the tab is active. */ if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { bg = CHOOSE(viewPtr->selBg, stylePtr->selBg); } Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y+1, columnWidth, entryPtr->height - 2, borderWidth, relief); if (columnWidth > valuePtr->width) { switch(colPtr->justify) { case TK_JUSTIFY_RIGHT: x += (columnWidth - valuePtr->width); break; case TK_JUSTIFY_CENTER: x += (columnWidth - valuePtr->width) / 2; break; case TK_JUSTIFY_LEFT: break; } } bool = (strcmp(valuePtr->fmtString, cbPtr->onValue) == 0); textPtr = (bool) ? cbPtr->onPtr : cbPtr->offPtr; /* * Draw the box and check. * * +-----------+ * | | * | * | * | * | * | * * | * | * * | * | * * | * | * | * +-----------+ */ boxWidth = boxHeight = ODD(cbPtr->size); xBox = x + cbPtr->gap; yBox = y + (entryPtr->height - boxHeight) / 2; { Blt_Picture picture; if (0) { if (cbPtr->disabledPicture == NULL) { cbPtr->disabledPicture = Blt_PaintCheckbox(boxWidth, boxHeight, cbPtr->fillColor, cbPtr->boxColor, cbPtr->boxColor, bool); } picture = cbPtr->disabledPicture; } else if (bool) { if (cbPtr->selectedPicture == NULL) { cbPtr->selectedPicture = Blt_PaintCheckbox(boxWidth, boxHeight, cbPtr->fillColor, cbPtr->boxColor, cbPtr->checkColor, TRUE); } picture = cbPtr->selectedPicture; } else { if (cbPtr->normalPicture == NULL) { cbPtr->normalPicture = Blt_PaintCheckbox(boxWidth, boxHeight, cbPtr->fillColor, cbPtr->boxColor, cbPtr->checkColor, FALSE); } picture = cbPtr->normalPicture; } if (cbPtr->painter == NULL) { cbPtr->painter = Blt_GetPainter(viewPtr->tkwin, 1.0); } Blt_PaintPicture(cbPtr->painter, drawable, picture, 0, 0, boxWidth, boxHeight, xBox, yBox, 0); } iconWidth = iconHeight = 0; if (cbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(cbPtr->icon); iconHeight = TreeView_IconHeight(cbPtr->icon); } textHeight = 0; gap = 0; if (cbPtr->showValue) { textHeight = textPtr->height; if (cbPtr->icon != NULL) { gap = cbPtr->gap; } } x = xBox + boxWidth + cbPtr->gap; /* The icon sits to the left of the text. */ iconX = x; iconY = y + (entryPtr->height - iconHeight) / 2; textX = iconX + iconWidth + gap; textY = y + (entryPtr->height - textHeight) / 2; if (cbPtr->icon != NULL) { Tk_RedrawImage(TreeView_IconBits(cbPtr->icon), 0, 0, iconWidth, iconHeight, drawable, iconX, iconY); } if ((cbPtr->showValue) && (textPtr != NULL)) { TextStyle ts; XColor *color; int xMax; if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { if (stylePtr->selFgColor != NULL) { color = stylePtr->selFgColor; } else { color = viewPtr->selFgColor; } } else if (entryPtr->color != NULL) { color = entryPtr->color; } else { color = fgColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); Blt_Ts_SetForeground(ts, color); Blt_Ts_SetMaxLength(ts, xMax - textX); xMax = SCREENX(viewPtr, colPtr->worldX) + colPtr->width - colPtr->titleBW - colPtr->pad.side2; Blt_Ts_DrawLayout(viewPtr->tkwin, drawable, textPtr, &ts, textX, textY); } stylePtr->flags &= ~STYLE_DIRTY; } #ifdef notdef /* *--------------------------------------------------------------------------- * * PickCheckbox -- * * Draws the "checkbox" given the screen coordinates and the value to be * displayed. * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ static int PickCheckBox(TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int worldX, int worldY) { TreeViewColumn *colPtr; TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; int columnWidth; int x, y, width, height; colPtr = valuePtr->columnPtr; columnWidth = colPtr->width - (2 * colPtr->borderWidth + PADDING(colPtr->pad)); if (columnWidth > valuePtr->width) { switch(colPtr->justify) { case TK_JUSTIFY_RIGHT: worldX += (columnWidth - valuePtr->width); break; case TK_JUSTIFY_CENTER: worldX += (columnWidth - valuePtr->width) / 2; break; case TK_JUSTIFY_LEFT: break; } } width = height = ODD(cbPtr->size) + 2 * cbPtr->lineWidth; x = colPtr->worldX + colPtr->pad.side1 + cbPtr->gap - cbPtr->lineWidth; y = entryPtr->worldY + (entryPtr->height - height) / 2; if ((worldX >= x) && (worldX < (x + width)) && (worldY >= y) && (worldY < (y + height))) { return TRUE; } return FALSE; } #endif /* *--------------------------------------------------------------------------- * * EditCheckbox -- * * Edits the "checkbox". * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ static int EditCheckBox(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr, TreeViewStyle *stylePtr) { TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; Tcl_Obj *objPtr; if (Blt_Tree_GetValueByKey(viewPtr->interp, viewPtr->tree, entryPtr->node, colPtr->key, &objPtr) != TCL_OK) { return TCL_ERROR; } if (strcmp(Tcl_GetString(objPtr), cbPtr->onValue) == 0) { objPtr = Tcl_NewStringObj(cbPtr->offValue, -1); } else { objPtr = Tcl_NewStringObj(cbPtr->onValue, -1); } entryPtr->flags |= ENTRY_DIRTY; viewPtr->flags |= (DIRTY | LAYOUT_PENDING | SCROLL_PENDING); if (Blt_Tree_SetValueByKey(viewPtr->interp, viewPtr->tree, entryPtr->node, colPtr->key, objPtr) != TCL_OK) { return TCL_ERROR; } if (cbPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; int result; cmdObjPtr = Tcl_DuplicateObj(cbPtr->cmdObjPtr); Tcl_ListObjAppendElement(viewPtr->interp, cmdObjPtr, Tcl_NewLongObj(Blt_Tree_NodeId(entryPtr->node))); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(viewPtr->interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreeCheckbox -- * * Releases resources allocated for the checkbox. The resources freed by * this routine are specific only to the "checkbox". Other resources * (common to all styles) are freed in the Blt_TreeView_FreeStyle * routine. * * Results: * None. * * Side Effects: * GCs allocated for the checkbox are freed. * *--------------------------------------------------------------------------- */ static void FreeCheckBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr; if (cbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->highlightGC); } if (cbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->activeGC); } if (cbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->gc); } if (cbPtr->icon != NULL) { Blt_TreeView_FreeIcon(viewPtr, cbPtr->icon); } if (cbPtr->offPtr != NULL) { Blt_Free(cbPtr->offPtr); } if (cbPtr->onPtr != NULL) { Blt_Free(cbPtr->onPtr); } } /* *--------------------------------------------------------------------------- * * CreateComboBox -- * * Creates a "combobox" style. * * Results: * A pointer to the new style structure. * *--------------------------------------------------------------------------- */ static TreeViewStyle * CreateComboBox(TreeView *viewPtr, Blt_HashEntry *hPtr) { TreeViewComboBox *cbPtr; cbPtr = Blt_AssertCalloc(1, sizeof(TreeViewComboBox)); cbPtr->classPtr = &comboBoxClass; cbPtr->gap = STYLE_GAP; cbPtr->arrowRelief = TK_RELIEF_RAISED; cbPtr->arrowBW = 1; cbPtr->borderWidth = 1; cbPtr->relief = TK_RELIEF_FLAT; cbPtr->name = Blt_AssertStrdup(Blt_GetHashKey(&viewPtr->styleTable, hPtr)); cbPtr->hashPtr = hPtr; cbPtr->link = NULL; cbPtr->flags = STYLE_COMBOBOX; cbPtr->refCount = 1; Blt_SetHashValue(hPtr, cbPtr); return (TreeViewStyle *)cbPtr; } /* *--------------------------------------------------------------------------- * * ConfigureComboBox -- * * Configures a "combobox" style. This routine performs generates the * GCs required for a combobox style. * * Results: * None. * * Side Effects: * GCs are created for the style. * *--------------------------------------------------------------------------- */ static void ConfigureComboBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { GC newGC; TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr; XColor *bgColor; XGCValues gcValues; unsigned long gcMask; gcValues.font = Blt_FontId(CHOOSE(viewPtr->font, cbPtr->font)); bgColor = Blt_BackgroundBorderColor(CHOOSE(viewPtr->bg, cbPtr->bg)); gcMask = GCForeground | GCBackground | GCFont; /* Normal foreground */ gcValues.background = bgColor->pixel; gcValues.foreground = CHOOSE(viewPtr->fgColor, cbPtr->fgColor)->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->gc); } cbPtr->gc = newGC; /* Highlight foreground */ gcValues.background = Blt_BackgroundBorderColor(cbPtr->highlightBg)->pixel; gcValues.foreground = cbPtr->highlightFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->highlightGC); } cbPtr->highlightGC = newGC; /* Active foreground */ gcValues.background = Blt_BackgroundBorderColor(cbPtr->activeBg)->pixel; gcValues.foreground = cbPtr->activeFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (cbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->activeGC); } cbPtr->activeGC = newGC; cbPtr->flags |= STYLE_DIRTY; } /* *--------------------------------------------------------------------------- * * MeasureComboBox -- * * Determines the space requirements for the "combobox" given the value * to be displayed. Depending upon whether an icon or text is displayed * and their relative placements, this routine computes the space needed * for the text entry. * * Results: * None. * * Side Effects: * The width and height fields of *valuePtr* are set with the computed * dimensions. * *--------------------------------------------------------------------------- */ static void MeasureComboBox(TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewValue *valuePtr) { TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr; int iconWidth, iconHeight; int textWidth, textHeight; int gap; Blt_Font font; textWidth = textHeight = 0; iconWidth = iconHeight = 0; valuePtr->width = valuePtr->height = 0; if (cbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(cbPtr->icon); iconHeight = TreeView_IconHeight(cbPtr->icon); } if (valuePtr->textPtr != NULL) { Blt_Free(valuePtr->textPtr); valuePtr->textPtr = NULL; } font = CHOOSE(viewPtr->font, cbPtr->font); if (valuePtr->fmtString != NULL) { /* New string defined. */ TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); valuePtr->textPtr = Blt_Ts_CreateLayout(valuePtr->fmtString, -1, &ts); } gap = 0; if (valuePtr->textPtr != NULL) { textWidth = valuePtr->textPtr->width; textHeight = valuePtr->textPtr->height; if (cbPtr->icon != NULL) { gap = cbPtr->gap; } } cbPtr->arrowWidth = Blt_TextWidth(font, "0", 1); cbPtr->arrowWidth += 2 * cbPtr->arrowBW; valuePtr->width = 2 * cbPtr->borderWidth + iconWidth + 4 * gap + cbPtr->arrowWidth + textWidth; valuePtr->height = MAX(textHeight, iconHeight) + 2 * cbPtr->borderWidth; } /* *--------------------------------------------------------------------------- * * DrawComboBox -- * * Draws the "combobox" given the screen coordinates and the * value to be displayed. * * Results: * None. * * Side Effects: * The combobox value is drawn. * *--------------------------------------------------------------------------- */ static void DrawComboBox(TreeView *viewPtr, Drawable drawable, TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int x, int y) { Blt_Background bg; TreeViewColumn *colPtr; TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr; XColor *fgColor; int arrowX, arrowY; int gap, columnWidth; int iconX, iconY, iconWidth, iconHeight; int textX, textY, textHeight; int relief; int borderWidth; borderWidth = 0; relief = TK_RELIEF_FLAT; colPtr = valuePtr->columnPtr; if (valuePtr == viewPtr->activeValuePtr) { bg = cbPtr->activeBg; fgColor = cbPtr->activeFgColor; borderWidth = 1; relief = TK_RELIEF_RAISED; } else if (stylePtr->flags & STYLE_HIGHLIGHT) { bg = cbPtr->highlightBg; fgColor = cbPtr->highlightFgColor; } else { /* If a background was specified, override the current background. * Otherwise, use the standard background taking into consideration if * its the odd or even color. */ if (cbPtr->bg != NULL) { bg = cbPtr->bg; } else { bg = ((viewPtr->altBg != NULL) && (entryPtr->flatIndex & 0x1)) ? viewPtr->altBg : viewPtr->bg; } fgColor = CHOOSE(viewPtr->fgColor, cbPtr->fgColor); } columnWidth = colPtr->width - PADDING(colPtr->pad); /* if (valuePtr == viewPtr->activeValuePtr) */ { /* * Draw the active or normal background color over the entire label * area. This includes both the tab's text and image. The rectangle * should be 2 pixels wider/taller than this area. So if the label * consists of just an image, we get an halo around the image when the * tab is active. */ if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { if (stylePtr->selBg != NULL) { bg = stylePtr->selBg; } else { bg = viewPtr->selBg; } Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y+1, columnWidth, entryPtr->height - 2, borderWidth, relief); } else { Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y+1, columnWidth, entryPtr->height - 2, borderWidth, relief); } } if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { fgColor = viewPtr->selFgColor; } arrowX = x + colPtr->width; arrowX -= colPtr->pad.side2 + cbPtr->borderWidth + cbPtr->arrowWidth + cbPtr->gap; arrowY = y; if (columnWidth > valuePtr->width) { switch(colPtr->justify) { case TK_JUSTIFY_RIGHT: x += (columnWidth - valuePtr->width); break; case TK_JUSTIFY_CENTER: x += (columnWidth - valuePtr->width) / 2; break; case TK_JUSTIFY_LEFT: break; } } #ifdef notdef textX = textY = iconX = iconY = 0; /* Suppress compiler warning. */ #endif iconWidth = iconHeight = 0; if (cbPtr->icon != NULL) { iconWidth = TreeView_IconWidth(cbPtr->icon); iconHeight = TreeView_IconHeight(cbPtr->icon); } textHeight = 0; if (valuePtr->textPtr != NULL) { textHeight = valuePtr->textPtr->height; } gap = 0; if ((cbPtr->icon != NULL) && (valuePtr->textPtr != NULL)) { gap = cbPtr->gap; } iconX = x + gap; iconY = y + (entryPtr->height - iconHeight) / 2; textX = iconX + iconWidth + gap; textY = y + (entryPtr->height - textHeight) / 2; if (cbPtr->icon != NULL) { Tk_RedrawImage(TreeView_IconBits(cbPtr->icon), 0, 0, iconWidth, iconHeight, drawable, iconX, iconY); } if (valuePtr->textPtr != NULL) { TextStyle ts; XColor *color; Blt_Font font; int xMax; font = CHOOSE(viewPtr->font, cbPtr->font); if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { color = CHOOSE(viewPtr->selFgColor, stylePtr->selFgColor); } else if (entryPtr->color != NULL) { color = entryPtr->color; } else { color = fgColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); Blt_Ts_SetForeground(ts, color); Blt_Ts_SetMaxLength(ts, xMax - textX); xMax = SCREENX(viewPtr, colPtr->worldX) + colPtr->width - colPtr->titleBW - colPtr->pad.side2 - cbPtr->arrowWidth; Blt_Ts_DrawLayout(viewPtr->tkwin, drawable, valuePtr->textPtr, &ts, textX, textY); } if (valuePtr == viewPtr->activeValuePtr) { bg = stylePtr->activeBg; } else { bg = colPtr->titleBg; #ifdef notdef bg = CHOOSE(viewPtr->bg, cbPtr->bg); #endif } #ifdef notdef Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, arrowX, arrowY + cbPtr->borderWidth, cbPtr->arrowWidth, entryPtr->height - 2 * cbPtr->borderWidth, cbPtr->arrowBW, cbPtr->arrowRelief); #endif Blt_DrawArrow(viewPtr->display, drawable, fgColor, arrowX, arrowY - 1, cbPtr->arrowWidth, entryPtr->height, cbPtr->arrowBW, ARROW_DOWN); stylePtr->flags &= ~STYLE_DIRTY; } /* *--------------------------------------------------------------------------- * * PickCombobox -- * * Draws the "checkbox" given the screen coordinates and the * value to be displayed. * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ static int PickComboBox(TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int worldX, int worldY) { TreeViewColumn *colPtr; TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr; int x, y, width, height; colPtr = valuePtr->columnPtr; width = colPtr->width; height = entryPtr->height - 4; x = colPtr->worldX + cbPtr->borderWidth; y = entryPtr->worldY + cbPtr->borderWidth; if ((worldX >= x) && (worldX < (x + width)) && (worldY >= y) && (worldY < (y + height))) { return TRUE; } return FALSE; } /* *--------------------------------------------------------------------------- * * EditCombobox -- * * Edits the "combobox". * * Results: * None. * * Side Effects: * The checkbox value is drawn. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EditComboBox( TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr, TreeViewStyle *stylePtr) /* Not used. */ { return Blt_TreeView_CreateTextbox(viewPtr, entryPtr, colPtr); } /* *--------------------------------------------------------------------------- * * FreeComboBox -- * * Releases resources allocated for the combobox. The resources freed by * this routine are specific only to the "combobox". Other resources * (common to all styles) are freed in the Blt_TreeView_FreeStyle * routine. * * Results: * None. * * Side Effects: * GCs allocated for the combobox are freed. * *--------------------------------------------------------------------------- */ static void FreeComboBox(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr; if (cbPtr->highlightGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->highlightGC); } if (cbPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->activeGC); } if (cbPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, cbPtr->gc); } if (cbPtr->icon != NULL) { Blt_TreeView_FreeIcon(viewPtr, cbPtr->icon); } } static TreeViewStyle * GetStyle(Tcl_Interp *interp, TreeView *viewPtr, const char *styleName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->styleTable, styleName); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find cell style \"", styleName, "\"", (char *)NULL); } return NULL; } return Blt_GetHashValue(hPtr); } int Blt_TreeView_GetStyle(Tcl_Interp *interp, TreeView *viewPtr, const char *styleName, TreeViewStyle **stylePtrPtr) { TreeViewStyle *stylePtr; stylePtr = GetStyle(interp, viewPtr, styleName); if (stylePtr == NULL) { return TCL_ERROR; } stylePtr->refCount++; *stylePtrPtr = stylePtr; return TCL_OK; } #ifdef notdef int Blt_TreeView_GetStyleFromObj(Tcl_Interp *interp, TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewStyle **stylePtrPtr) { return Blt_TreeView_GetStyle(interp, viewPtr, Tcl_GetString(objPtr), stylePtrPtr); } #endif static TreeViewStyle * CreateStyle( Tcl_Interp *interp, TreeView *viewPtr, /* Blt_TreeView_ widget. */ int type, /* Type of style: either * STYLE_TEXTBOX, * STYLE_COMBOBOX, or * STYLE_CHECKBOX */ const char *styleName, /* Name of the new style. */ int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; int isNew; TreeViewStyle *stylePtr; hPtr = Blt_CreateHashEntry(&viewPtr->styleTable, styleName, &isNew); if (!isNew) { if (interp != NULL) { Tcl_AppendResult(interp, "cell style \"", styleName, "\" already exists", (char *)NULL); } return NULL; } /* Create the new marker based upon the given type */ switch (type) { case STYLE_TEXTBOX: stylePtr = CreateTextBox(viewPtr, hPtr); break; case STYLE_COMBOBOX: stylePtr = CreateComboBox(viewPtr, hPtr); break; case STYLE_CHECKBOX: stylePtr = CreateCheckBox(viewPtr, hPtr); break; default: return NULL; } bltTreeViewIconOption.clientData = viewPtr; if (Blt_ConfigureComponentFromObj(interp, viewPtr->tkwin, styleName, stylePtr->classPtr->className, stylePtr->classPtr->specsPtr, objc, objv, (char *)stylePtr, 0) != TCL_OK) { Blt_TreeView_FreeStyle(viewPtr, stylePtr); return NULL; } return stylePtr; } void Blt_TreeView_UpdateStyleGCs(TreeView *viewPtr, TreeViewStyle *stylePtr) { (*stylePtr->classPtr->configProc)(viewPtr, stylePtr); stylePtr->flags |= STYLE_DIRTY; Blt_TreeView_EventuallyRedraw(viewPtr); } TreeViewStyle * Blt_TreeView_CreateStyle( Tcl_Interp *interp, TreeView *viewPtr, /* Blt_TreeView_ widget. */ int type, /* Type of style: either * STYLE_TEXTBOX, * STYLE_COMBOBOX, or * STYLE_CHECKBOX */ const char *styleName) /* Name of the new style. */ { TreeViewStyle *stylePtr; stylePtr = CreateStyle(interp, viewPtr, type, styleName, 0, (Tcl_Obj **)NULL); if (stylePtr == NULL) { return NULL; } return stylePtr; } void Blt_TreeView_FreeStyle(TreeView *viewPtr, TreeViewStyle *stylePtr) { stylePtr->refCount--; #ifdef notdef fprintf(stderr, "Blt_TreeView_FreeStyle %s count=%d\n", stylePtr->name, stylePtr->refCount); #endif /* Remove the style from the hash table so that it's name can be used.*/ /* If no cell is using the style, remove it.*/ if (stylePtr->refCount <= 0) { #ifdef notdef fprintf(stderr, "freeing %s\n", stylePtr->name); #endif bltTreeViewIconOption.clientData = viewPtr; Blt_FreeOptions(stylePtr->classPtr->specsPtr, (char *)stylePtr, viewPtr->display, 0); (*stylePtr->classPtr->freeProc)(viewPtr, stylePtr); if (stylePtr->hashPtr != NULL) { Blt_DeleteHashEntry(&viewPtr->styleTable, stylePtr->hashPtr); } if (stylePtr->link != NULL) { /* Only user-generated styles will be in the list. */ Blt_Chain_DeleteLink(viewPtr->userStyles, stylePtr->link); } if (stylePtr->name != NULL) { Blt_Free(stylePtr->name); } Blt_Free(stylePtr); } } void Blt_TreeView_SetStyleIcon(TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewIcon icon) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; if (tbPtr->icon != NULL) { Blt_TreeView_FreeIcon(viewPtr, tbPtr->icon); } tbPtr->icon = icon; } GC Blt_TreeView_GetStyleGC(TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; return tbPtr->gc; } Blt_Background Blt_TreeView_GetStyleBackground(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; Blt_Background bg; bg = (tbPtr->flags & STYLE_HIGHLIGHT) ? tbPtr->highlightBg : tbPtr->bg; return (bg != NULL) ? bg : viewPtr->bg; } Blt_Font Blt_TreeView_GetStyleFont(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; if (tbPtr->font != NULL) { return tbPtr->font; } return viewPtr->font; } XColor * Blt_TreeView_GetStyleFg(TreeView *viewPtr, TreeViewStyle *stylePtr) { TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr; if (tbPtr->fgColor != NULL) { return tbPtr->fgColor; } return viewPtr->fgColor; } static void DrawValue(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewValue *valuePtr) { int srcX, srcY, x, y; int w, h; int pixWidth, pixHeight; int x1, x2, y1, y2; TreeViewColumn *colPtr; TreeViewStyle *stylePtr; Blt_Background bg; int overlap; stylePtr = valuePtr->stylePtr; if (stylePtr == NULL) { stylePtr = valuePtr->columnPtr->stylePtr; } if (stylePtr->cursor != None) { if (valuePtr == viewPtr->activeValuePtr) { Tk_DefineCursor(viewPtr->tkwin, stylePtr->cursor); } else { if (viewPtr->cursor != None) { Tk_DefineCursor(viewPtr->tkwin, viewPtr->cursor); } else { Tk_UndefineCursor(viewPtr->tkwin); } } } colPtr = valuePtr->columnPtr; x = SCREENX(viewPtr, colPtr->worldX) + colPtr->pad.side1; y = SCREENY(viewPtr, entryPtr->worldY); h = entryPtr->height - 2; w = valuePtr->columnPtr->width - PADDING(colPtr->pad); y1 = viewPtr->titleHeight + viewPtr->inset; y2 = Tk_Height(viewPtr->tkwin) - viewPtr->inset; x1 = viewPtr->inset; x2 = Tk_Width(viewPtr->tkwin) - viewPtr->inset; if (((x + w) < x1) || (x > x2) || ((y + h) < y1) || (y > y2)) { return; /* Value is entirely clipped. */ } /* Draw the background of the value. */ if ((valuePtr == viewPtr->activeValuePtr) || (!Blt_TreeView_EntryIsSelected(viewPtr, entryPtr))) { bg = Blt_TreeView_GetStyleBackground(viewPtr, viewPtr->stylePtr); } else { bg = CHOOSE(viewPtr->selBg, stylePtr->selBg); } /*FIXME*/ /* bg = CHOOSE(viewPtr->selBg, stylePtr->selBg); */ overlap = FALSE; /* Clip the drawable if necessary */ srcX = srcY = 0; pixWidth = w, pixHeight = h; if (x < x1) { pixWidth -= x1 - x; srcX += x1 - x; x = x1; overlap = TRUE; } if ((x + w) >= x2) { pixWidth -= (x + w) - x2; overlap = TRUE; } if (y < y1) { pixHeight -= y1 - y; srcY += y1 - y; y = y1; overlap = TRUE; } if ((y + h) >= y2) { pixHeight -= (y + h) - y2; overlap = TRUE; } if (overlap) { Drawable drawable; drawable = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), pixWidth, pixHeight, Tk_Depth(viewPtr->tkwin)); Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, 0, 0, pixWidth, pixHeight, 0, TK_RELIEF_FLAT); Blt_TreeView_DrawValue(viewPtr, entryPtr, valuePtr, drawable, srcX, srcY); XCopyArea(viewPtr->display, drawable, Tk_WindowId(viewPtr->tkwin), viewPtr->lineGC, 0, 0, pixWidth, pixHeight, x, y+1); Tk_FreePixmap(viewPtr->display, drawable); } else { Drawable drawable; drawable = Tk_WindowId(viewPtr->tkwin); Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y+1, w, h, 0, TK_RELIEF_FLAT); Blt_TreeView_DrawValue(viewPtr, entryPtr, valuePtr, drawable, x, y); } } /* *--------------------------------------------------------------------------- * * StyleActivateOp -- * * Turns on/off highlighting for a particular style. * * .t style activate entry column * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleActivateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewValue *oldValuePtr; oldValuePtr = viewPtr->activeValuePtr; if (objc == 3) { Tcl_Obj *listObjPtr; TreeViewEntry *ep; TreeViewValue *vp; vp = viewPtr->activeValuePtr; ep = viewPtr->activePtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if ((ep != NULL) && (vp != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(ep->node)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj(vp->columnPtr->key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else if (objc == 4) { viewPtr->activeValuePtr = NULL; if ((oldValuePtr != NULL) && (viewPtr->activePtr != NULL)) { DrawValue(viewPtr, viewPtr->activePtr, oldValuePtr); } } else { TreeViewColumn *colPtr; TreeViewEntry *ep; TreeViewValue *vp; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &ep) != TCL_OK) { return TCL_ERROR; } if (Blt_TreeView_GetColumn(interp, viewPtr, objv[4], &colPtr) != TCL_OK) { return TCL_ERROR; } vp = Blt_TreeView_FindValue(ep, colPtr); if (vp != NULL) { viewPtr->activePtr = ep; viewPtr->activeColumnPtr = colPtr; oldValuePtr = viewPtr->activeValuePtr; viewPtr->activeValuePtr = vp; if (vp != oldValuePtr) { if (oldValuePtr != NULL) { DrawValue(viewPtr, ep, oldValuePtr); } DrawValue(viewPtr, ep, vp); } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleCgetOp -- * * .t style cget "styleName" -background * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleCgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[3])); if (stylePtr == NULL) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, stylePtr->classPtr->specsPtr, (char *)viewPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * StyleCheckBoxOp -- * * .t style checkbox "styleName" -background blue * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleCheckBoxOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; stylePtr = CreateStyle(interp, viewPtr, STYLE_CHECKBOX, Tcl_GetString(objv[3]), objc - 4, objv + 4); if (stylePtr == NULL) { return TCL_ERROR; } stylePtr->link = Blt_Chain_Append(viewPtr->userStyles, stylePtr); Blt_TreeView_UpdateStyleGCs(viewPtr, stylePtr); Tcl_SetObjResult(interp, objv[3]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleComboBoxOp -- * * .t style combobox "styleName" -background blue * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleComboBoxOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; stylePtr = CreateStyle(interp, viewPtr, STYLE_COMBOBOX, Tcl_GetString(objv[3]), objc - 4, objv + 4); if (stylePtr == NULL) { return TCL_ERROR; } stylePtr->link = Blt_Chain_Append(viewPtr->userStyles, stylePtr); Blt_TreeView_UpdateStyleGCs(viewPtr, stylePtr); Tcl_SetObjResult(interp, objv[3]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure a style. * * .t style configure "styleName" option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for stylePtr; old resources get freed, if there were any. * *--------------------------------------------------------------------------- */ static int StyleConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[3])); if (stylePtr == NULL) { return TCL_ERROR; } if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, stylePtr->classPtr->specsPtr, (char *)stylePtr, (Tcl_Obj *)NULL, 0); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, stylePtr->classPtr->specsPtr, (char *)stylePtr, objv[5], 0); } bltTreeViewIconOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, stylePtr->classPtr->specsPtr, objc - 4, objv + 4, (char *)stylePtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } (*stylePtr->classPtr->configProc)(viewPtr, stylePtr); stylePtr->flags |= STYLE_DIRTY; viewPtr->flags |= (LAYOUT_PENDING | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleForgetOp -- * * Eliminates one or more style names. A style still may be in use after * its name has been officially removed. Only its hash table entry is * removed. The style itself remains until its reference count returns * to zero (i.e. no one else is using it). * * .t style forget "styleName"... * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ static int StyleForgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; int i; for (i = 3; i < objc; i++) { stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[i])); if (stylePtr == NULL) { return TCL_ERROR; } /* * Removing the style from the hash tables frees up the style * name again. The style itself may not be removed until it's * been released by everything using it. */ if (stylePtr->hashPtr != NULL) { Blt_DeleteHashEntry(&viewPtr->styleTable, stylePtr->hashPtr); stylePtr->hashPtr = NULL; } Blt_TreeView_FreeStyle(viewPtr, stylePtr); } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleHighlightOp -- * * Turns on/off highlighting for a particular style. * * .t style highlight styleName on|off * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleHighlightOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; int bool, oldBool; stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[3])); if (stylePtr == NULL) { return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[4], &bool) != TCL_OK) { return TCL_ERROR; } oldBool = ((stylePtr->flags & STYLE_HIGHLIGHT) != 0); if (oldBool != bool) { if (bool) { stylePtr->flags |= STYLE_HIGHLIGHT; } else { stylePtr->flags &= ~STYLE_HIGHLIGHT; } Blt_TreeView_EventuallyRedraw(viewPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleNamesOp -- * * Lists the names of all the current styles in the treeview widget. * * .t style names * * Results: * Always TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleNamesOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr, *objPtr; TreeViewStyle *stylePtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&viewPtr->styleTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { stylePtr = Blt_GetHashValue(hPtr); objPtr = Tcl_NewStringObj(stylePtr->name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleSetOp -- * * Sets a style for a given key for all the ids given. * * .t style set styleName key node... * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ static int StyleSetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeKey key; TreeViewStyle *stylePtr; int i; stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[3])); if (stylePtr == NULL) { return TCL_ERROR; } key = Blt_Tree_GetKey(viewPtr->tree, Tcl_GetString(objv[4])); stylePtr->flags |= STYLE_LAYOUT; for (i = 5; i < objc; i++) { TreeViewEntry *entryPtr; TreeViewTagIter iter; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { TreeViewValue *vp; for (vp = entryPtr->values; vp != NULL; vp = vp->nextPtr) { if (vp->columnPtr->key == key) { TreeViewStyle *oldStylePtr; stylePtr->refCount++; oldStylePtr = vp->stylePtr; vp->stylePtr = stylePtr; if (oldStylePtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, oldStylePtr); } break; } } } } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleTextBoxOp -- * * .t style text "styleName" -background blue * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StyleTextBoxOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewStyle *stylePtr; stylePtr = CreateStyle(interp, viewPtr, STYLE_TEXTBOX, Tcl_GetString(objv[3]), objc - 4, objv + 4); if (stylePtr == NULL) { return TCL_ERROR; } stylePtr->link = Blt_Chain_Append(viewPtr->userStyles, stylePtr); Blt_TreeView_UpdateStyleGCs(viewPtr, stylePtr); Tcl_SetObjResult(interp, objv[3]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleUnsetOp -- * * Removes a style for a given key for all the ids given. * The cell's style is returned to its default state. * * .t style unset styleName key node... * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * *--------------------------------------------------------------------------- */ static int StyleUnsetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeKey key; TreeViewStyle *stylePtr; int i; stylePtr = GetStyle(interp, viewPtr, Tcl_GetString(objv[3])); if (stylePtr == NULL) { return TCL_ERROR; } key = Blt_Tree_GetKey(viewPtr->tree, Tcl_GetString(objv[4])); stylePtr->flags |= STYLE_LAYOUT; for (i = 5; i < objc; i++) { TreeViewTagIter iter; TreeViewEntry *entryPtr; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { TreeViewValue *vp; for (vp = entryPtr->values; vp != NULL; vp = vp->nextPtr) { if (vp->columnPtr->key == key) { if (vp->stylePtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, vp->stylePtr); vp->stylePtr = NULL; } break; } } } } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleOp -- * * .t style activate $node $column * .t style activate * .t style cget "highlight" -foreground * .t style configure "highlight" -fg blue -bg green * .t style checkbox "highlight" * .t style highlight "highlight" on|off * .t style combobox "highlight" * .t style text "highlight" * .t style forget "highlight" * .t style get "mtime" $node * .t style names * .t style set "mtime" "highlight" all * .t style unset "mtime" all * *--------------------------------------------------------------------------- */ static Blt_OpSpec styleOps[] = { {"activate", 1, StyleActivateOp, 3, 5, "entry column",}, {"cget", 2, StyleCgetOp, 5, 5, "styleName option",}, {"checkbox", 2, StyleCheckBoxOp, 4, 0, "styleName options...",}, {"combobox", 3, StyleComboBoxOp, 4, 0, "styleName options...",}, {"configure", 3, StyleConfigureOp, 4, 0, "styleName options...",}, {"forget", 1, StyleForgetOp, 3, 0, "styleName...",}, {"highlight", 1, StyleHighlightOp, 5, 5, "styleName boolean",}, {"names", 1, StyleNamesOp, 3, 3, "",}, {"set", 1, StyleSetOp, 6, 6, "key styleName tagOrId...",}, {"textbox", 1, StyleTextBoxOp, 4, 0, "styleName options...",}, {"unset", 1, StyleUnsetOp, 5, 5, "key tagOrId",}, }; static int nStyleOps = sizeof(styleOps) / sizeof(Blt_OpSpec); int Blt_TreeView_StyleOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nStyleOps, styleOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(viewPtr, interp, objc, objv); return result; } #endif /* NO_TREEVIEW */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTreeCmd.c������������������������������������������������������������������0000644�0001750�0001750�00000467230�11462120063�015233� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltTreeCmd.c -- * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* tree create t0 t1 t2 tree names t0 destroy -or- tree destroy t0 tree copy tree@node tree@node -recurse -tags tree move node after|before|into t2@node $t apply -recurse $root command arg arg $t attach treename $t children $n t0 copy node1 node2 node3 node4 node5 destName $t delete $n... $t depth $n $t dump $root $t dumpfile $root fileName $t dup $t2 $t find $root -name pat -name pattern $t firstchild $n $t get $n $key $t get $n $key(abc) $t index $n $t insert $parent $switches? $t isancestor $n1 $n2 $t isbefore $n1 $n2 $t isleaf $n $t lastchild $n $t move $n1 after|before|into $n2 $t next $n $t nextsibling $n $t path $n1 $n2 $n3... $t parent $n $t previous $n $t prevsibling $n $t restore $root data -overwrite $t root ?$n? $t set $n $key $value ?$key $value? $t size $n $t slink $n $t2@$node ??? $t sort -recurse $root $t tag delete tag1 tag2 tag3... $t tag names $t tag nodes $tag $t tag set $n tag1 tag2 tag3... $t tag unset $n tag1 tag2 tag3... $t trace create $n $key how -whenidle command $t trace delete id1 id2 id3... $t trace names $t trace info $id $t unset $n key1 key2 key3... $t notify create -oncreate -ondelete -onmove command $t notify create -oncreate -ondelete -onmove -onsort command arg arg arg $t notify delete id1 id2 id3 $t notify names $t notify info id for { set n [$t firstchild $node] } { $n >= 0 } { set n [$t nextsibling $n] } { } foreach n [$t children $node] { } set n [$t next $node] set n [$t previous $node] */ #include <bltInt.h> #ifndef NO_TREE #include "bltOp.h" #include <bltTree.h> #include <bltHash.h> #include <bltList.h> #include "bltNsUtil.h" #include "bltSwitch.h" #include <ctype.h> #define TREE_THREAD_KEY "BLT Tree Command Data" #define TREE_MAGIC ((unsigned int) 0x46170277) enum TagTypes { TAG_TYPE_NONE, TAG_TYPE_ALL, TAG_TYPE_TAG }; typedef struct { const char *name; /* Name of format. */ int isLoaded; Blt_TreeImportProc *importProc; Blt_TreeExportProc *exportProc; } DataFormat; typedef struct { Tcl_Interp *interp; Blt_HashTable treeTable; /* Hash table of trees keyed by * address. */ Blt_HashTable fmtTable; } TreeCmdInterpData; typedef struct { Tcl_Interp *interp; Tcl_Command cmdToken; /* Token for tree's TCL command. */ Blt_Tree tree; /* Token holding internal tree. */ Blt_HashEntry *hashPtr; Blt_HashTable *tablePtr; TreeCmdInterpData *tdPtr; /* */ int traceCounter; /* Used to generate trace id * strings. */ Blt_HashTable traceTable; /* Table of active traces. Maps trace * ids back to their TraceInfo * records. */ int notifyCounter; /* Used to generate notify id * strings. */ Blt_HashTable notifyTable; /* Table of event handlers. Maps * notify ids back to their Notifier * records. */ Blt_Chain notifiers; } TreeCmd; typedef struct { TreeCmd *cmdPtr; Blt_TreeNode node; Blt_TreeTrace traceToken; const char *withTag; /* If non-NULL, the event or trace was * specified with this tag. This * value is saved for informational * purposes. The tree's trace * matching routines do the real * checking, not the client's * callback. */ char command[1]; /* Command prefix for the trace or * notify Tcl callback. Extra * arguments will be appended to the * end. Extra space will be allocated * for the length of the string */ } TraceInfo; typedef struct { TreeCmd *cmdPtr; int mask; /* Requested event mask. */ long inode; /* If >= 0, inode to match. */ const char *tag; /* If non-NULL, tag to match. */ Tcl_Obj *cmdObjPtr; /* Command to be executed when * matching event is found. */ Blt_TreeNode node; /* (out) Node affected by event. */ Blt_TreeTrace notifyToken; Blt_HashEntry *hashPtr; /* Pointer to entry in hash table. */ Blt_ChainLink link; /* Pointer to entry in list of * notifiers. */ } Notifier; BLT_EXTERN Blt_SwitchParseProc Blt_TreeNodeSwitchProc; static Blt_SwitchCustom nodeSwitch = { Blt_TreeNodeSwitchProc, NULL, (ClientData)0, }; typedef struct { int mask; } AttachSwitches; static Blt_SwitchSpec attachSwitches[] = { {BLT_SWITCH_BITMASK, "-newtags", "", Blt_Offset(AttachSwitches, mask), 0, TREE_NEWTAGS}, {BLT_SWITCH_END} }; typedef struct { int mask; Blt_TreeNode node; const char *tag; } NotifySwitches; static Blt_SwitchSpec notifySwitches[] = { {BLT_SWITCH_BITMASK, "-create", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_CREATE}, {BLT_SWITCH_BITMASK, "-delete", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_DELETE}, {BLT_SWITCH_BITMASK, "-move", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_MOVE}, {BLT_SWITCH_BITMASK, "-sort", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_SORT}, {BLT_SWITCH_BITMASK, "-relabel", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_RELABEL}, {BLT_SWITCH_BITMASK, "-allevents", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_ALL}, {BLT_SWITCH_BITMASK, "-whenidle", "", Blt_Offset(NotifySwitches, mask), 0, TREE_NOTIFY_WHENIDLE}, {BLT_SWITCH_CUSTOM, "-node", "node", Blt_Offset(NotifySwitches, node), 0, 0, &nodeSwitch}, {BLT_SWITCH_STRING, "-tag", "string", Blt_Offset(NotifySwitches, tag), 0}, {BLT_SWITCH_END} }; static Blt_SwitchParseProc ChildSwitch; #define INSERT_BEFORE (ClientData)0 #define INSERT_AFTER (ClientData)1 static Blt_SwitchCustom beforeSwitch = { ChildSwitch, NULL, INSERT_BEFORE, }; static Blt_SwitchCustom afterSwitch = { ChildSwitch, NULL, INSERT_AFTER, }; typedef struct { const char *label; long position; long inode; Tcl_Obj *tagsObjPtr; char **dataPairs; Blt_TreeNode parent; } InsertSwitches; static Blt_SwitchSpec insertSwitches[] = { {BLT_SWITCH_CUSTOM, "-after", "position", Blt_Offset(InsertSwitches, position), 0, 0, &afterSwitch}, {BLT_SWITCH_LONG_NNEG, "-at", "position", Blt_Offset(InsertSwitches, position), 0}, {BLT_SWITCH_CUSTOM, "-before", "position", Blt_Offset(InsertSwitches, position), 0, 0, &beforeSwitch}, {BLT_SWITCH_LIST, "-data", "{name value ?name value?...}", Blt_Offset(InsertSwitches, dataPairs), 0}, {BLT_SWITCH_STRING, "-label", "string", Blt_Offset(InsertSwitches, label), 0}, {BLT_SWITCH_LONG_NNEG, "-node", "number", Blt_Offset(InsertSwitches, inode), 0}, {BLT_SWITCH_OBJ, "-tags", "{?tagName?...}", Blt_Offset(InsertSwitches, tagsObjPtr), 0}, {BLT_SWITCH_END} }; #define MATCH_INVERT (1<<8) #define MATCH_LEAFONLY (1<<4) #define MATCH_NOCASE (1<<5) #define MATCH_PATHNAME (1<<6) #define PATTERN_NONE (0) #define PATTERN_EXACT (1) #define PATTERN_GLOB (2) #define PATTERN_REGEXP (3) #define PATTERN_MASK (0x3) typedef struct { TreeCmd *cmdPtr; /* Tree to examine. */ Tcl_Obj *listObjPtr; /* List to accumulate the indices of * matching nodes. */ Tcl_Obj *cmdObjPtr; /* If non-NULL, command to be executed * for each found node. */ unsigned int flags; /* See flags definitions above. */ size_t nMatches; /* Current number of matches. */ size_t maxMatches; /* If > 0, stop after this many * matches. */ unsigned int order; /* Order of search: Can be either * TREE_PREORDER, TREE_POSTORDER, * TREE_INORDER, TREE_BREADTHFIRST. */ long maxDepth; /* If >= 0, don't descend more than * this many levels. */ Blt_List patternList; /* List of patterns to compare with * labels or values. */ const char *addTag; /* If non-NULL, tag added to selected * nodes. */ Blt_List keyList; /* List of key name patterns. */ Blt_List tagList; /* List of tag names. */ Blt_HashTable excludeTable; /* Table of nodes to exclude. */ } FindSwitches; static Blt_SwitchParseProc OrderSwitch; static Blt_SwitchCustom orderSwitch = { OrderSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc PatternSwitch; static Blt_SwitchFreeProc FreePatterns; static Blt_SwitchCustom regexpSwitch = { PatternSwitch, FreePatterns, (ClientData)PATTERN_REGEXP, }; static Blt_SwitchCustom globSwitch = { PatternSwitch, FreePatterns, (ClientData)PATTERN_GLOB, }; static Blt_SwitchCustom exactSwitch = { PatternSwitch, FreePatterns, (ClientData)PATTERN_EXACT, }; static Blt_SwitchCustom tagSwitch = { PatternSwitch, FreePatterns, (ClientData)PATTERN_EXACT, }; static Blt_SwitchParseProc NodesSwitch; static Blt_SwitchFreeProc FreeNodes; static Blt_SwitchCustom nodesSwitch = { NodesSwitch, FreeNodes, (ClientData)0, }; static Blt_SwitchSpec findSwitches[] = { {BLT_SWITCH_STRING, "-addtag", "tagName", Blt_Offset(FindSwitches, addTag), 0}, {BLT_SWITCH_LONG_NNEG, "-count", "number", Blt_Offset(FindSwitches, maxMatches), 0}, {BLT_SWITCH_LONG_NNEG, "-depth", "number", Blt_Offset(FindSwitches, maxDepth), 0}, {BLT_SWITCH_CUSTOM, "-exact", "string", Blt_Offset(FindSwitches, patternList),0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-excludes", "nodes", Blt_Offset(FindSwitches, excludeTable),0, 0, &nodesSwitch}, {BLT_SWITCH_OBJ, "-exec", "command", Blt_Offset(FindSwitches, cmdObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-glob", "pattern", Blt_Offset(FindSwitches, patternList),0, 0, &globSwitch}, {BLT_SWITCH_BITMASK, "-invert", "", Blt_Offset(FindSwitches, flags), 0, MATCH_INVERT}, {BLT_SWITCH_CUSTOM, "-key", "string", Blt_Offset(FindSwitches, keyList), 0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-keyexact", "string", Blt_Offset(FindSwitches, keyList), 0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-keyglob", "pattern", Blt_Offset(FindSwitches, keyList), 0, 0, &globSwitch}, {BLT_SWITCH_CUSTOM, "-keyregexp","pattern", Blt_Offset(FindSwitches, keyList), 0, 0, &regexpSwitch}, {BLT_SWITCH_BITMASK, "-leafonly", "", Blt_Offset(FindSwitches, flags), 0, MATCH_LEAFONLY}, {BLT_SWITCH_BITMASK, "-nocase", "", Blt_Offset(FindSwitches, flags), 0, MATCH_NOCASE}, {BLT_SWITCH_CUSTOM, "-order", "order", Blt_Offset(FindSwitches, order), 0, 0, &orderSwitch}, {BLT_SWITCH_BITMASK, "-path", "", Blt_Offset(FindSwitches, flags), 0, MATCH_PATHNAME}, {BLT_SWITCH_CUSTOM, "-regexp", "pattern", Blt_Offset(FindSwitches, patternList),0, 0, &regexpSwitch}, {BLT_SWITCH_CUSTOM, "-tag", "{?tag?...}", Blt_Offset(FindSwitches, tagList), 0, 0, &tagSwitch}, {BLT_SWITCH_END} }; #undef _off typedef struct { TreeCmd *cmdPtr; /* Tree to move nodes. */ Blt_TreeNode node; long movePos; } MoveSwitches; static Blt_SwitchSpec moveSwitches[] = { {BLT_SWITCH_CUSTOM, "-after", "child", Blt_Offset(MoveSwitches, node), 0, 0, &nodeSwitch}, {BLT_SWITCH_LONG_NNEG, "-at", "position", Blt_Offset(MoveSwitches, movePos), 0}, {BLT_SWITCH_CUSTOM, "-before", "child", Blt_Offset(MoveSwitches, node), 0, 0, &nodeSwitch}, {BLT_SWITCH_END} }; #undef _off typedef struct { Blt_TreeNode srcNode; Blt_Tree srcTree, destTree; TreeCmd *srcPtr, *destPtr; const char *label; unsigned int flags; } CopySwitches; #define COPY_RECURSE (1<<0) #define COPY_TAGS (1<<1) #define COPY_OVERWRITE (1<<2) static Blt_SwitchSpec copySwitches[] = { {BLT_SWITCH_STRING, "-label", "string", Blt_Offset(CopySwitches, label), 0}, {BLT_SWITCH_BITMASK, "-recurse", "", Blt_Offset(CopySwitches, flags), 0, COPY_RECURSE}, {BLT_SWITCH_BITMASK, "-tags", "", Blt_Offset(CopySwitches, flags), 0, COPY_TAGS}, {BLT_SWITCH_BITMASK, "-overwrite", "", Blt_Offset(CopySwitches, flags), 0, COPY_OVERWRITE}, {BLT_SWITCH_END} }; typedef struct { TreeCmd *cmdPtr; /* Tree to examine. */ unsigned int flags; /* See flags definitions above. */ long maxDepth; /* If >= 0, don't descend more than * this many levels. */ /* String options. */ Blt_List patternList; /* List of label or value patterns. */ Tcl_Obj *preCmdObjPtr; /* Pre-command. */ Tcl_Obj *postCmdObjPtr; /* Post-command. */ Blt_List keyList; /* List of key-name patterns. */ Blt_List tagList; } ApplySwitches; static Blt_SwitchSpec applySwitches[] = { {BLT_SWITCH_OBJ, "-precommand", "command", Blt_Offset(ApplySwitches, preCmdObjPtr), 0}, {BLT_SWITCH_OBJ, "-postcommand", "command", Blt_Offset(ApplySwitches, postCmdObjPtr), 0}, {BLT_SWITCH_LONG_NNEG, "-depth", "number", Blt_Offset(ApplySwitches, maxDepth), 0}, {BLT_SWITCH_CUSTOM, "-exact", "string", Blt_Offset(ApplySwitches, patternList), 0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-glob", "pattern", Blt_Offset(ApplySwitches, patternList), 0, 0, &globSwitch}, {BLT_SWITCH_BITMASK, "-invert", "", Blt_Offset(ApplySwitches, flags), 0, MATCH_INVERT}, {BLT_SWITCH_CUSTOM, "-key", "pattern", Blt_Offset(ApplySwitches, keyList), 0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-keyexact", "string", Blt_Offset(ApplySwitches, keyList), 0, 0, &exactSwitch}, {BLT_SWITCH_CUSTOM, "-keyglob", "pattern", Blt_Offset(ApplySwitches, keyList), 0, 0, &globSwitch}, {BLT_SWITCH_CUSTOM, "-keyregexp", "pattern", Blt_Offset(ApplySwitches, keyList), 0, 0, &regexpSwitch}, {BLT_SWITCH_BITMASK, "-leafonly", "", Blt_Offset(ApplySwitches, flags), 0, MATCH_LEAFONLY}, {BLT_SWITCH_BITMASK, "-nocase", "", Blt_Offset(ApplySwitches, flags), 0, MATCH_NOCASE}, {BLT_SWITCH_BITMASK, "-path", "", Blt_Offset(ApplySwitches, flags), 0, MATCH_PATHNAME}, {BLT_SWITCH_CUSTOM, "-regexp", "pattern", Blt_Offset(ApplySwitches, patternList), 0, 0, &regexpSwitch}, {BLT_SWITCH_CUSTOM, "-tag", "{?tag?...}", Blt_Offset(ApplySwitches, tagList), 0, 0, &tagSwitch}, {BLT_SWITCH_END} }; typedef struct { unsigned int flags; } RestoreSwitches; #define RESTORE_NO_TAGS (1<<0) #define RESTORE_OVERWRITE (1<<1) static Blt_SwitchSpec restoreSwitches[] = { {BLT_SWITCH_BITMASK, "-notags", "", Blt_Offset(RestoreSwitches, flags), 0, RESTORE_NO_TAGS}, {BLT_SWITCH_BITMASK, "-overwrite", "", Blt_Offset(RestoreSwitches, flags), 0, RESTORE_OVERWRITE}, {BLT_SWITCH_END} }; static Blt_SwitchParseProc FormatSwitch; static Blt_SwitchCustom formatSwitch = { FormatSwitch, NULL, (ClientData)0, }; typedef struct { int sort; /* If non-zero, sort the nodes. */ int withParent; /* If non-zero, add the parent node id * to the output of the command.*/ int withId; /* If non-zero, echo the node id in * the output of the command. */ } PositionSwitches; #define POSITION_SORTED (1<<0) static Blt_SwitchSpec positionSwitches[] = { {BLT_SWITCH_BITMASK, "-sort", "", Blt_Offset(PositionSwitches, sort), 0, POSITION_SORTED}, {BLT_SWITCH_CUSTOM, "-format", "format", 0, 0, 0, &formatSwitch}, {BLT_SWITCH_END} }; #define PATH_LEAF (1<<0) #define PATH_PARENTS (1<<1) #define PATH_NOCOMPLAIN (1<<2) typedef struct { unsigned int flags; /* Parse flags. */ const char *separator; /* Path separator. */ } PathSwitches; static Blt_SwitchSpec pathSwitches[] = { {BLT_SWITCH_BITMASK, "-parents", "", Blt_Offset(PathSwitches, flags), 0, PATH_PARENTS}, {BLT_SWITCH_BITMASK, "-leaf", "", Blt_Offset(PathSwitches, flags), 0, PATH_LEAF}, {BLT_SWITCH_BITMASK, "-nocomplain", "", Blt_Offset(PathSwitches, flags), 0, PATH_NOCOMPLAIN}, {BLT_SWITCH_STRING, "-separator", "char", Blt_Offset(PathSwitches, separator), 0}, {BLT_SWITCH_END} }; typedef struct { int mask; } TraceSwitches; static Blt_SwitchSpec traceSwitches[] = { {BLT_SWITCH_BITMASK, "-whenidle", "", Blt_Offset(TraceSwitches, mask), 0, TREE_NOTIFY_WHENIDLE}, {BLT_SWITCH_END} }; static Tcl_InterpDeleteProc TreeInterpDeleteProc; static Blt_TreeApplyProc MatchNodeProc, SortApplyProc; static Blt_TreeApplyProc ApplyNodeProc; static Blt_TreeTraceProc TreeTraceProc; static Tcl_CmdDeleteProc TreeInstDeleteProc; static Blt_TreeCompareNodesProc CompareNodes; static Tcl_ObjCmdProc TreeObjCmd; static Tcl_ObjCmdProc CompareDictionaryCmd; static Tcl_ObjCmdProc ExitCmd; static Blt_TreeNotifyEventProc TreeEventProc; typedef int (TreeCmdProc)(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int GetNodeFromObj(Tcl_Interp *interp, Blt_Tree tree, Tcl_Obj *objPtr, Blt_TreeNode *nodePtr); static int IsTag(Blt_Tree tree, const char *string) { if (strcmp(string, "all") == 0) { return TRUE; } else if (strcmp(string, "root") == 0) { return TRUE; } else { Blt_HashTable *tablePtr; tablePtr = Blt_Tree_TagHashTable(tree, string); if (tablePtr == NULL) { return FALSE; } } return TRUE; } static int IsNodeId(const char *string) { long value; return (Tcl_GetLong(NULL, string, &value) == TCL_OK); } static int IsNodeIdOrModifier(const char *string) { if (strstr(string, "->") == NULL) { return IsNodeId(string); } return TRUE; } /* *--------------------------------------------------------------------------- * * ChildSwitch -- * * Convert a Tcl_Obj representing the label of a child node into its * integer node id. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ChildSwitch( ClientData clientData, /* Flag indicating if the node is * considered before or after the * insertion position. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Not used. */ int flags) /* Not used. */ { InsertSwitches *insertPtr = (InsertSwitches *)record; Blt_TreeNode node; const char *string; string = Tcl_GetString(objPtr); node = Blt_Tree_FindChild(insertPtr->parent, string); if (node == NULL) { Tcl_AppendResult(interp, "can't find a child named \"", string, "\" in \"", Blt_Tree_NodeLabel(insertPtr->parent), "\"", (char *)NULL); return TCL_ERROR; } insertPtr->position = Blt_Tree_NodeDegree(node); if (clientData == INSERT_AFTER) { insertPtr->position++; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeNodeSwitchProc -- * * Convert a Tcl_Obj representing a node number into its integer value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_TreeNodeSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_TreeNode *nodePtr = (Blt_TreeNode *)(record + offset); Blt_TreeNode node; Blt_Tree tree = clientData; int result; result = GetNodeFromObj(interp, tree, objPtr, &node); if (result != TCL_OK) { return TCL_ERROR; } *nodePtr = node; return TCL_OK; } /* *--------------------------------------------------------------------------- * * OrderSwitch -- * * Convert a string represent a node number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OrderSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *orderPtr = (int *)(record + offset); char c; char *string; string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'b') && (strcmp(string, "breadthfirst") == 0)) { *orderPtr = TREE_BREADTHFIRST; } else if ((c == 'i') && (strcmp(string, "inorder") == 0)) { *orderPtr = TREE_INORDER; } else if ((c == 'p') && (strcmp(string, "preorder") == 0)) { *orderPtr = TREE_PREORDER; } else if ((c == 'p') && (strcmp(string, "postorder") == 0)) { *orderPtr = TREE_POSTORDER; } else { Tcl_AppendResult(interp, "bad order \"", string, "\": should be breadthfirst, inorder, preorder, or postorder", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PatternSwitch -- * * Convert a string represent a node number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PatternSwitch( ClientData clientData, /* Flag indicating type of pattern. */ Tcl_Interp *interp, /* Not used. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_List *listPtr = (Blt_List *)(record + offset); if (*listPtr == NULL) { *listPtr = Blt_List_Create(BLT_STRING_KEYS); } Blt_List_Append(*listPtr, Tcl_GetString(objPtr), clientData); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreePatterns -- * * Convert a string represent a node number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreePatterns(char *record, int offset, int flags) { Blt_List *listPtr = (Blt_List *)(record + offset); if (*listPtr != NULL) { Blt_List_Destroy(*listPtr); /* * This routine can be called several times for each switch that * appends to this list. Mark it NULL, so we don't try to destroy the * list again. */ *listPtr = NULL; } } /* *--------------------------------------------------------------------------- * * FormatSwitch -- * * Convert a string represent a node number into its integer value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FormatSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Not used. */ int flags) /* Not used. */ { PositionSwitches *pdPtr = (PositionSwitches *)record; char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "position") == 0) { pdPtr->withParent = FALSE; pdPtr->withId = FALSE; } else if (strcmp(string, "id+position") == 0) { pdPtr->withParent = FALSE; pdPtr->withId = TRUE; } else if (strcmp(string, "parent-at-position") == 0) { pdPtr->withParent = TRUE; pdPtr->withId = FALSE; } else if (strcmp(string, "id+parent-at-position") == 0) { pdPtr->withParent = TRUE; pdPtr->withId = TRUE; } else { Tcl_AppendResult(interp, "bad format \"", string, "\": should be position, parent-at-position, id+position, or id+parent-at-position", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreeNodes -- * * Convert a string represent a node number into its integer value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeNodes(char *record, int offset, int flags) { Blt_HashTable *tablePtr = (Blt_HashTable *)(record + offset); Blt_DeleteHashTable(tablePtr); } /* *--------------------------------------------------------------------------- * * NodesSwitch -- * * Convert a Tcl_Obj representing a node number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NodesSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Not used. */ int flags) /* Not used. */ { FindSwitches *findPtr = (FindSwitches *)record; int objc; Tcl_Obj **objv; int i; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < objc; i++) { int isNew; Blt_TreeNode node; if (GetNodeFromObj(interp, findPtr->cmdPtr->tree, objv[i], &node) != TCL_OK) { Blt_DeleteHashTable(&findPtr->excludeTable); return TCL_ERROR; } Blt_CreateHashEntry(&findPtr->excludeTable, (char *)node, &isNew); } return TCL_OK; } static void FreeNotifier(TreeCmd *cmdPtr, Notifier *notifyPtr) { if (notifyPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&cmdPtr->notifyTable, notifyPtr->hashPtr); } if (notifyPtr->link != NULL) { Blt_Chain_DeleteLink(cmdPtr->notifiers, notifyPtr->link); } Tcl_DecrRefCount(notifyPtr->cmdObjPtr); if (notifyPtr->tag != NULL) { Blt_Free(notifyPtr->tag); } Blt_Free(notifyPtr); } /* *--------------------------------------------------------------------------- * * GetTreeCmdInterpData -- * *--------------------------------------------------------------------------- */ static TreeCmdInterpData * GetTreeCmdInterpData(Tcl_Interp *interp) { TreeCmdInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (TreeCmdInterpData *) Tcl_GetAssocData(interp, TREE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(TreeCmdInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, TREE_THREAD_KEY, TreeInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->treeTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&dataPtr->fmtTable, BLT_STRING_KEYS); } return dataPtr; } /* *--------------------------------------------------------------------------- * * GetTreeCmd -- * * Find the tree command associated with the TCL command "string". * * We have to do multiple lookups to get this right. * * The first step is to generate a canonical command name. If an * unqualified command name (i.e. no namespace qualifier) is given, we * should search first the current namespace and then the global one. * Most TCL commands (like Tcl_GetCmdInfo) look only at the global * namespace. * * Next check if the string is * a) a TCL command and * b) really is a command for a tree object. * Tcl_GetCommandInfo will get us the objClientData field that should be * a cmdPtr. We can verify that by searching our hashtable of cmdPtr * addresses. * * Results: * A pointer to the tree command. If no associated tree command can be * found, NULL is returned. It's up to the calling routines to generate * an error message. * *--------------------------------------------------------------------------- */ static TreeCmd * GetTreeCmd( TreeCmdInterpData *tdPtr, Tcl_Interp *interp, const char *string) { Blt_ObjectName objName; Tcl_CmdInfo cmdInfo; Blt_HashEntry *hPtr; Tcl_DString dString; const char *treeName; int result; /* Pull apart the tree name and put it back together in a standard * format. */ if (!Blt_ParseObjectName(interp, string, &objName, BLT_NO_ERROR_MSG)) { return NULL; /* No such parent namespace. */ } /* Rebuild the fully qualified name. */ treeName = Blt_MakeQualifiedName(&objName, &dString); result = Tcl_GetCommandInfo(interp, treeName, &cmdInfo); Tcl_DStringFree(&dString); if (!result) { return NULL; } hPtr = Blt_FindHashEntry(&tdPtr->treeTable, (char *)(cmdInfo.objClientData)); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } static Blt_TreeNode ParseModifiers(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, char *modifiers) { char *p, *token; p = modifiers; do { p += 2; /* Skip the initial "->" */ token = strstr(p, "->"); if (token != NULL) { *token = '\0'; } if (IsNodeId(p)) { long inode; if (Tcl_GetLong(interp, p, &inode) != TCL_OK) { node = NULL; } else { node = Blt_Tree_GetNode(tree, inode); } } else if ((*p == 'p') && (strcmp(p, "parent") == 0)) { node = Blt_Tree_ParentNode(node); } else if ((*p == 'f') && (strcmp(p, "firstchild") == 0)) { node = Blt_Tree_FirstChild(node); } else if ((*p == 'l') && (strcmp(p, "lastchild") == 0)) { node = Blt_Tree_LastChild(node); } else if ((*p == 'n') && (strcmp(p, "next") == 0)) { node = Blt_Tree_NextNode(NULL, node); } else if ((*p == 'n') && (strcmp(p, "nextsibling") == 0)) { node = Blt_Tree_NextSibling(node); } else if ((*p == 'p') && (strcmp(p, "previous") == 0)) { node = Blt_Tree_PrevNode(NULL, node); } else if ((*p == 'p') && (strcmp(p, "prevsibling") == 0)) { node = Blt_Tree_PrevSibling(node); } else { int length; length = strlen(p); if (length > 0) { char *endp; endp = p + length - 1; if ((*p == '"') && (*endp == '"')) { *endp = '\0'; node = Blt_Tree_FindChild(node, p + 1); *endp = '"'; } else { node = Blt_Tree_FindChild(node, p); } } } if (node == NULL) { goto error; } if (token != NULL) { *token = '-'; /* Repair the string */ } p = token; } while (token != NULL); return node; error: if (token != NULL) { *token = '-'; /* Repair the string */ } return NULL; } /* *--------------------------------------------------------------------------- * * GetForeignNode -- * *--------------------------------------------------------------------------- */ static int GetForeignNode(Tcl_Interp *interp, Blt_Tree tree, Tcl_Obj *objPtr, Blt_TreeNode *nodePtr) { Blt_TreeNode node; char *string; char *p; char save; save = '\0'; /* Suppress compiler warning. */ string = Tcl_GetString(objPtr); /* Check if modifiers are present. */ p = strstr(string, "->"); if (p != NULL) { save = *p; *p = '\0'; } if (IsNodeId(string)) { long inode; if (p != NULL) { if (Tcl_GetLong(interp, string, &inode) != TCL_OK) { goto error; } } else { if (Tcl_GetLongFromObj(interp, objPtr, &inode) != TCL_OK) { goto error; } } node = Blt_Tree_GetNode(tree, inode); if (p != NULL) { node = ParseModifiers(interp, tree, node, p); } if (node != NULL) { *nodePtr = node; if (p != NULL) { *p = save; } return TCL_OK; } } Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(tree), (char *)NULL); error: if (p != NULL) { *p = save; /* Restore the string */ } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * GetNodeFromObj -- * *--------------------------------------------------------------------------- */ static int GetNodeFromObj(Tcl_Interp *interp, Blt_Tree tree, Tcl_Obj *objPtr, Blt_TreeNode *nodePtr) { Blt_TreeNode node; char *string; char *p; char save; node = NULL; /* Suppress compiler warnings. */ save = '\0'; string = Tcl_GetString(objPtr); /* Check if modifiers are present. */ p = strstr(string, "->"); if (p != NULL) { save = *p; *p = '\0'; } if (IsNodeId(string)) { long inode; if (p != NULL) { if (Tcl_GetLong(interp, string, &inode) != TCL_OK) { goto error; } } else { if (Tcl_GetLongFromObj(interp, objPtr, &inode) != TCL_OK) { goto error; } } node = Blt_Tree_GetNode(tree, inode); } else if (tree != NULL) { if (strcmp(string, "all") == 0) { if (Blt_Tree_Size(Blt_Tree_RootNode(tree)) > 1) { if (interp != NULL) { Tcl_AppendResult(interp, "more than one node tagged as \"", string, "\"", (char *)NULL); } goto error; } node = Blt_Tree_RootNode(tree); } else if (strcmp(string, "root") == 0) { node = Blt_Tree_RootNode(tree); } else { Blt_HashTable *tablePtr; Blt_HashSearch cursor; Blt_HashEntry *hPtr; node = NULL; tablePtr = Blt_Tree_TagHashTable(tree, string); if (tablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(tree), (char *)NULL); } goto error; } else if (tablePtr->numEntries > 1) { if (interp != NULL) { Tcl_AppendResult(interp, "more than one node tagged as \"", string, "\"", (char *)NULL); } goto error; } else if (tablePtr->numEntries > 0) { hPtr = Blt_FirstHashEntry(tablePtr, &cursor); node = Blt_GetHashValue(hPtr); if (p != NULL) { *p = save; } } } } if (node != NULL) { if (p != NULL) { node = ParseModifiers(interp, tree, node, p); if (node == NULL) { if (interp != NULL) { *p = save; /* Need entire string. */ Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(tree), (char *)NULL); } goto error; } } if (p != NULL) { *p = save; } *nodePtr = node; return TCL_OK; } if (interp != NULL) { Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(tree), (char *)NULL); } error: if (p != NULL) { *p = save; } return TCL_ERROR; } typedef struct { int tagType; Blt_TreeNode root; Blt_HashSearch cursor; } TagSearch; /* *--------------------------------------------------------------------------- * * FirstTaggedNode -- * * Returns the id of the first node tagged by the given tag in objPtr. * It basically hides much of the cumbersome special case details. For * example, the special tags "root" and "all" always exist, so they don't * have entries in the tag hashtable. If it's a hashed tag (not "root" * or "all"), we have to save the place of where we are in the table for * the next call to NextTaggedNode. * *--------------------------------------------------------------------------- */ static int FirstTaggedNode(Tcl_Interp *interp, TreeCmd *cmdPtr, Tcl_Obj *objPtr, TagSearch *cursorPtr, Blt_TreeNode *nodePtr) { const char *string; *nodePtr = NULL; string = Tcl_GetString(objPtr); cursorPtr->tagType = TAG_TYPE_NONE; cursorPtr->root = Blt_Tree_RootNode(cmdPtr->tree); /* Process strings with modifiers or digits as simple ids, not tags. */ if (GetNodeFromObj(NULL, cmdPtr->tree, objPtr, nodePtr) == TCL_OK) { return TCL_OK; } if (strcmp(string, "all") == 0) { cursorPtr->tagType = TAG_TYPE_ALL; *nodePtr = cursorPtr->root; return TCL_OK; } else if (strcmp(string, "root") == 0) { *nodePtr = cursorPtr->root; return TCL_OK; } else { Blt_HashTable *tablePtr; tablePtr = Blt_Tree_TagHashTable(cmdPtr->tree, string); if (tablePtr != NULL) { Blt_HashEntry *hPtr; cursorPtr->tagType = TAG_TYPE_TAG; hPtr = Blt_FirstHashEntry(tablePtr, &cursorPtr->cursor); if (hPtr == NULL) { *nodePtr = NULL; return TCL_OK; } *nodePtr = Blt_GetHashValue(hPtr); return TCL_OK; } } Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(cmdPtr->tree), (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * SkipSeparators -- * * Moves the character pointer past one of more separators. * * Results: * Returns the updates character pointer. * *--------------------------------------------------------------------------- */ static char * SkipSeparators(char *path, const char *separator, int length) { while ((*path == *separator) && (strncmp(path, separator, length) == 0)) { path += length; } return path; } /* *--------------------------------------------------------------------------- * * SplitPath -- * * Returns the trailing component of the given path. Trailing separators * are ignored. * * Results: * Returns the string of the tail component. * *--------------------------------------------------------------------------- */ static int SplitPath(Tcl_Interp *interp, char *path, const char *separator, int *argcPtr, const char ***argvPtr) { int skipLen, pathLen; int depth; size_t listSize; const char **components; char *p; char *sp; if ((separator == NULL) || (*separator == '\0')) { if (Tcl_SplitList(interp, path, argcPtr, argvPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } pathLen = strlen(path); skipLen = strlen(separator); path = SkipSeparators(path, separator, skipLen); depth = pathLen / skipLen; listSize = (depth + 1) * sizeof(char *); components = Blt_AssertMalloc(listSize + (pathLen + 1)); p = (char *)components + listSize; strcpy(p, path); depth = 0; for (sp = strstr(p, separator); ((*p != '\0') && (sp != NULL)); sp = strstr(p, separator)) { *sp = '\0'; components[depth++] = p; p = SkipSeparators(sp + skipLen, separator, skipLen); } if (*p != '\0') { components[depth++] = p; } components[depth] = NULL; *argcPtr = depth; *argvPtr = components; return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextTaggedNode -- * *--------------------------------------------------------------------------- */ static Blt_TreeNode NextTaggedNode(Blt_TreeNode node, TagSearch *cursorPtr) { if (cursorPtr->tagType == TAG_TYPE_ALL) { return Blt_Tree_NextNode(NULL, node); } if (cursorPtr->tagType == TAG_TYPE_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&cursorPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } return NULL; } static int AddTag(TreeCmd *cmdPtr, Blt_TreeNode node, const char *tagName) { if (strcmp(tagName, "root") == 0) { Tcl_AppendResult(cmdPtr->interp, "can't add reserved tag \"", tagName, "\"", (char *)NULL); return TCL_ERROR; } Blt_Tree_AddTag(cmdPtr->tree, node, tagName); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteNode -- * *--------------------------------------------------------------------------- */ static void DeleteNode(TreeCmd *cmdPtr, Blt_TreeNode node) { Blt_TreeNode root; if (!Blt_Tree_TagTableIsShared(cmdPtr->tree)) { Blt_Tree_ClearTags(cmdPtr->tree, node); } root = Blt_Tree_RootNode(cmdPtr->tree); if (node == root) { Blt_TreeNode next; /* Don't delete the root node. Simply clean out the tree. */ for (node = Blt_Tree_FirstChild(node); node != NULL; node = next) { next = Blt_Tree_NextSibling(node); Blt_Tree_DeleteNode(cmdPtr->tree, node); } } else if (Blt_Tree_IsAncestor(root, node)) { Blt_Tree_DeleteNode(cmdPtr->tree, node); } } /* *--------------------------------------------------------------------------- * * PrintTraceFlags -- * *--------------------------------------------------------------------------- */ static void PrintTraceFlags(unsigned int flags, char *string) { char *s; s = string; if (flags & TREE_TRACE_READ) { *s++ = 'r'; } if (flags & TREE_TRACE_WRITE) { *s++ = 'w'; } if (flags & TREE_TRACE_UNSET) { *s++ = 'u'; } if (flags & TREE_TRACE_CREATE) { *s++ = 'c'; } *s = '\0'; } /* *--------------------------------------------------------------------------- * * GetTraceFlags -- * *--------------------------------------------------------------------------- */ static int GetTraceFlags(const char *string) { const char *s; unsigned int flags; flags = 0; for (s = string; *s != '\0'; s++) { int c; c = toupper(*s); switch (c) { case 'R': flags |= TREE_TRACE_READ; break; case 'W': flags |= TREE_TRACE_WRITE; break; case 'U': flags |= TREE_TRACE_UNSET; break; case 'C': flags |= TREE_TRACE_CREATE; break; default: return -1; } } return flags; } /* *--------------------------------------------------------------------------- * * SetValues -- * *--------------------------------------------------------------------------- */ static int SetValues(TreeCmd *cmdPtr, Blt_TreeNode node, int objc, Tcl_Obj *const *objv) { int i; for (i = 0; i < objc; i += 2) { const char *string; string = Tcl_GetString(objv[i]); if ((i + 1) == objc) { Tcl_AppendResult(cmdPtr->interp, "missing value for field \"", string, "\"", (char *)NULL); return TCL_ERROR; } if (Blt_Tree_SetValue(cmdPtr->interp, cmdPtr->tree, node, string, objv[i + 1]) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnsetValues -- * *--------------------------------------------------------------------------- */ static int UnsetValues(TreeCmd *cmdPtr, Blt_TreeNode node, int objc, Tcl_Obj *const *objv) { if (objc == 0) { Blt_TreeKey key; Blt_TreeKeyIterator iter; for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &iter)) { if (Blt_Tree_UnsetValueByKey(cmdPtr->interp, cmdPtr->tree, node, key) != TCL_OK) { return TCL_ERROR; } } } else { int i; for (i = 0; i < objc; i ++) { if (Blt_Tree_UnsetValue(cmdPtr->interp, cmdPtr->tree, node, Tcl_GetString(objv[i])) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } static int ComparePatterns(Blt_List patternList, const char *string, int nocase) { Blt_ListNode node; int result; if (nocase) { string = Blt_AssertStrdup(string); strtolower((char *)string); } result = FALSE; for (node = Blt_List_FirstNode(patternList); node != NULL; node = Blt_List_NextNode(node)) { size_t type; char *pattern; type = (size_t)Blt_List_GetValue(node); pattern = (char *)Blt_List_GetKey(node); switch (type) { case PATTERN_EXACT: result = (strcmp(string, pattern) == 0); break; case PATTERN_GLOB: result = Tcl_StringMatch(string, pattern); break; case PATTERN_REGEXP: result = Tcl_RegExpMatch((Tcl_Interp *)NULL, string, pattern); break; } } if (nocase) { Blt_Free((char *)string); } return result; } static int CompareTags( Blt_Tree tree, Blt_TreeNode node, Blt_List tagList) { Blt_ListNode tn; for (tn = Blt_List_FirstNode(tagList); tn != NULL; tn = Blt_List_NextNode(tn)) { char *tag; tag = (char *)Blt_List_GetKey(tn); if (Blt_Tree_HasTag(tree, node, tag)) { return TRUE; } } return FALSE; } /* *--------------------------------------------------------------------------- * * MatchNodeProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MatchNodeProc(Blt_TreeNode node, ClientData clientData, int order) { FindSwitches *findPtr = clientData; Tcl_DString dString; TreeCmd *cmdPtr = findPtr->cmdPtr; Tcl_Interp *interp = findPtr->cmdPtr->interp; int result, invert; if ((findPtr->flags & MATCH_LEAFONLY) && (!Blt_Tree_IsLeaf(node))) { return TCL_OK; } if ((findPtr->maxDepth >= 0) && (findPtr->maxDepth < Blt_Tree_NodeDepth(node))) { return TCL_OK; } result = TRUE; Tcl_DStringInit(&dString); if (findPtr->keyList != NULL) { Blt_TreeKey key; Blt_TreeKeyIterator iter; result = FALSE; /* It's false if no keys match. */ for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &iter)) { result = ComparePatterns(findPtr->keyList, key, 0); if (!result) { continue; } if (findPtr->patternList != NULL) { const char *string; Tcl_Obj *objPtr; Blt_Tree_GetValue(interp, cmdPtr->tree, node, key, &objPtr); string = (objPtr == NULL) ? "" : Tcl_GetString(objPtr); result = ComparePatterns(findPtr->patternList, string, findPtr->flags & MATCH_NOCASE); if (!result) { continue; } } break; } } else if (findPtr->patternList != NULL) { const char *string; if (findPtr->flags & MATCH_PATHNAME) { string = Blt_Tree_NodePath(node, &dString); } else { string = Blt_Tree_NodeLabel(node); } result = ComparePatterns(findPtr->patternList, string, findPtr->flags & MATCH_NOCASE); } if (findPtr->tagList != NULL) { result = CompareTags(cmdPtr->tree, node, findPtr->tagList); } Tcl_DStringFree(&dString); invert = (findPtr->flags & MATCH_INVERT) ? TRUE : FALSE; if ((result != invert) && /* Check if the matching node is on the exclude list. */ ((findPtr->excludeTable.numEntries == 0) || (Blt_FindHashEntry(&findPtr->excludeTable, (char *)node) == NULL))) { Tcl_Obj *objPtr; if (findPtr->addTag != NULL) { if (AddTag(cmdPtr, node, findPtr->addTag) != TCL_OK) { return TCL_ERROR; } } /* Save the node id in our list. */ objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(node)); Tcl_ListObjAppendElement(interp, findPtr->listObjPtr, objPtr); /* Execute a procedure for the matching node. */ if (findPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; cmdObjPtr = Tcl_DuplicateObj(findPtr->cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { return result; } } findPtr->nMatches++; if ((findPtr->maxMatches > 0) && (findPtr->nMatches >= findPtr->maxMatches)) { return TCL_BREAK; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ApplyNodeProc -- * *--------------------------------------------------------------------------- */ static int ApplyNodeProc(Blt_TreeNode node, ClientData clientData, int order) { ApplySwitches *applyPtr = clientData; TreeCmd *cmdPtr = applyPtr->cmdPtr; Tcl_Interp *interp = cmdPtr->interp; int invert, result; Tcl_DString dString; if ((applyPtr->flags & MATCH_LEAFONLY) && (!Blt_Tree_IsLeaf(node))) { return TCL_OK; } if ((applyPtr->maxDepth >= 0) && (applyPtr->maxDepth < Blt_Tree_NodeDepth(node))) { return TCL_OK; } Tcl_DStringInit(&dString); result = TRUE; if (applyPtr->keyList != NULL) { Blt_TreeKey key; Blt_TreeKeyIterator iter; result = FALSE; /* It's false if no keys match. */ for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &iter)) { result = ComparePatterns(applyPtr->keyList, key, 0); if (!result) { continue; } if (applyPtr->patternList != NULL) { const char *string; Tcl_Obj *objPtr; Blt_Tree_GetValue(interp, cmdPtr->tree, node, key, &objPtr); string = (objPtr == NULL) ? "" : Tcl_GetString(objPtr); result = ComparePatterns(applyPtr->patternList, string, applyPtr->flags & MATCH_NOCASE); if (!result) { continue; } } break; } } else if (applyPtr->patternList != NULL) { const char *string; if (applyPtr->flags & MATCH_PATHNAME) { string = Blt_Tree_NodePath(node, &dString); } else { string = Blt_Tree_NodeLabel(node); } result = ComparePatterns(applyPtr->patternList, string, applyPtr->flags & MATCH_NOCASE); } Tcl_DStringFree(&dString); if (applyPtr->tagList != NULL) { result = CompareTags(cmdPtr->tree, node, applyPtr->tagList); } invert = (applyPtr->flags & MATCH_INVERT) ? 1 : 0; if (result != invert) { Tcl_Obj *cmdObjPtr; if (order == TREE_PREORDER) { cmdObjPtr = Tcl_DuplicateObj(applyPtr->preCmdObjPtr); } else if (order == TREE_PREORDER) { cmdObjPtr = Tcl_DuplicateObj(applyPtr->postCmdObjPtr); } else { return TCL_OK; } Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewLongObj(Blt_Tree_NodeId(node))); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); return result; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ClearTracesAndEvents -- * *--------------------------------------------------------------------------- */ static void ClearTracesAndEvents(TreeCmd *cmdPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_ChainLink link, next; /* * When the tree token is released, all the traces and notification events * are automatically removed. But we still need to clean up the * bookkeeping kept for traces. Clear all the tags and trace information. */ for (hPtr = Blt_FirstHashEntry(&cmdPtr->traceTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { TraceInfo *tracePtr; tracePtr = Blt_GetHashValue(hPtr); Blt_Free(tracePtr); } Blt_DeleteHashTable(&cmdPtr->traceTable); Blt_InitHashTable(&cmdPtr->traceTable, BLT_STRING_KEYS); for (link = Blt_Chain_FirstLink(cmdPtr->notifiers); link != NULL; link = next) { Notifier *notifyPtr; next = Blt_Chain_NextLink(link); notifyPtr = Blt_Chain_GetValue(link); FreeNotifier(cmdPtr, notifyPtr); } } /* *--------------------------------------------------------------------------- * * ReleaseTreeObject -- * *--------------------------------------------------------------------------- */ static void ReleaseTreeObject(TreeCmd *cmdPtr) { ClearTracesAndEvents(cmdPtr); Blt_Tree_Close(cmdPtr->tree); cmdPtr->tree = NULL; } /* *--------------------------------------------------------------------------- * * TreeTraceProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeTraceProc( ClientData clientData, Tcl_Interp *interp, Blt_TreeNode node, /* Node that has just been updated. */ Blt_TreeKey key, /* Field that's updated. */ unsigned int flags) { TraceInfo *tracePtr = clientData; Tcl_DString dsName; char string[5]; char *qualName; int result; Blt_ObjectName objName; Tcl_Obj *cmdObjPtr; cmdObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj(tracePtr->command, -1)); Tcl_DStringInit(&dsName); objName.name = Tcl_GetCommandName(interp, tracePtr->cmdPtr->cmdToken); objName.nsPtr = Blt_GetCommandNamespace(tracePtr->cmdPtr->cmdToken); qualName = Blt_MakeQualifiedName(&objName, &dsName); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj(qualName, -1)); Tcl_DStringFree(&dsName); if (node != NULL) { Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewLongObj(Blt_Tree_NodeId(node))); } else { Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj("", -1)); } Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj(key, -1)); PrintTraceFlags(flags, string); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewStringObj(string, -1)); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); return result; } /* *--------------------------------------------------------------------------- * * TreeEventProc -- * *--------------------------------------------------------------------------- */ static int TreeEventProc(ClientData clientData, Blt_TreeNotifyEvent *eventPtr) { TreeCmd *cmdPtr = clientData; Blt_TreeNode node; const char *string; Blt_ChainLink link, next; switch (eventPtr->type) { case TREE_NOTIFY_CREATE: string = "-create"; break; case TREE_NOTIFY_DELETE: node = Blt_Tree_GetNode(cmdPtr->tree, eventPtr->inode); if (node != NULL) { Blt_Tree_ClearTags(cmdPtr->tree, node); } string = "-delete"; break; case TREE_NOTIFY_MOVE: string = "-move"; break; case TREE_NOTIFY_SORT: string = "-sort"; break; case TREE_NOTIFY_RELABEL: string = "-relabel"; break; default: /* empty */ string = "???"; break; } for (link = Blt_Chain_FirstLink(cmdPtr->notifiers); link != NULL; link = next) { Notifier *notifyPtr; int result; Tcl_Obj *cmdObjPtr, *objPtr; int remove; result = TCL_OK; next = Blt_Chain_NextLink(link); notifyPtr = Blt_Chain_GetValue(link); remove = FALSE; if (notifyPtr->inode >= 0) { /* Test for specific node id. */ if (notifyPtr->inode != eventPtr->inode) { continue; /* No match. */ } if (eventPtr->type == TREE_NOTIFY_DELETE) { remove = TRUE; /* Must destroy notifier. Node no * longer exists. */ } } if ((notifyPtr->tag != NULL) && (!Blt_Tree_HasTag(cmdPtr->tree, eventPtr->node, notifyPtr->tag))) { goto next; /* Doesn't have the tag. */ } if ((notifyPtr->mask & eventPtr->type) == 0) { goto next; /* Event not matching. */ } cmdObjPtr = Tcl_DuplicateObj(notifyPtr->cmdObjPtr); objPtr = Tcl_NewStringObj(string, -1); Tcl_ListObjAppendElement(cmdPtr->interp, cmdObjPtr, objPtr); objPtr = Tcl_NewLongObj(eventPtr->inode); Tcl_ListObjAppendElement(cmdPtr->interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(cmdPtr->interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(cmdPtr->interp); } next: if (remove) { FreeNotifier(cmdPtr, notifyPtr); } if (result != TCL_OK) { return TCL_ERROR; } Tcl_ResetResult(cmdPtr->interp); } return TCL_OK; } /* Tree command operations. */ /* *--------------------------------------------------------------------------- * * ApplyOp -- * * t0 apply root -precommand {command} -postcommand {command} * *--------------------------------------------------------------------------- */ static int ApplyOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Blt_TreeNode node; ApplySwitches switches; int order; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); switches.maxDepth = -1; switches.cmdPtr = cmdPtr; /* Process switches */ if (Blt_ParseSwitches(interp, applySwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } order = 0; if (switches.flags & MATCH_NOCASE) { Blt_ListNode ln; for (ln = Blt_List_FirstNode(switches.patternList); ln != NULL; ln = Blt_List_NextNode(ln)) { strtolower((char *)Blt_List_GetKey(ln)); } } if (switches.preCmdObjPtr != NULL) { order |= TREE_PREORDER; } if (switches.postCmdObjPtr != NULL) { order |= TREE_POSTORDER; } result = Blt_Tree_ApplyDFS(node, ApplyNodeProc, &switches, order); Blt_FreeSwitches(applySwitches, (char *)&switches, 0); if (result == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } /*ARGSUSED*/ static int AncestorOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { long d1, d2, minDepth; long i; Blt_TreeNode ancestor, node1, node2; if ((GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node1) != TCL_OK) || (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node2) != TCL_OK)) { return TCL_ERROR; } if (node1 == node2) { ancestor = node1; goto done; } d1 = Blt_Tree_NodeDepth(node1); d2 = Blt_Tree_NodeDepth(node2); minDepth = MIN(d1, d2); if (minDepth == 0) { /* One of the nodes is root. */ ancestor = Blt_Tree_RootNode(cmdPtr->tree); goto done; } /* * Traverse back from the deepest node, until the both nodes are at the * same depth. Check if the ancestor node found is the other node. */ for (i = d1; i > minDepth; i--) { node1 = Blt_Tree_ParentNode(node1); } if (node1 == node2) { ancestor = node2; goto done; } for (i = d2; i > minDepth; i--) { node2 = Blt_Tree_ParentNode(node2); } if (node2 == node1) { ancestor = node1; goto done; } /* * First find the mutual ancestor of both nodes. Look at each preceding * ancestor level-by-level for both nodes. Eventually we'll find a node * that's the parent of both ancestors. Then find the first ancestor in * the parent's list of subnodes. */ for (i = minDepth; i > 0; i--) { node1 = Blt_Tree_ParentNode(node1); node2 = Blt_Tree_ParentNode(node2); if (node1 == node2) { ancestor = node2; goto done; } } Tcl_AppendResult(interp, "unknown ancestor", (char *)NULL); return TCL_ERROR; done: Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeId(ancestor)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AttachOp -- * *--------------------------------------------------------------------------- */ static int AttachOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *treeName; AttachSwitches switches; treeName = Tcl_GetString(objv[2]); switches.mask = 0; /* Process switches */ if (Blt_ParseSwitches(interp, attachSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (Blt_Tree_Attach(interp, cmdPtr->tree, treeName) != TCL_OK) { return TCL_ERROR; } if (switches.mask & TREE_NEWTAGS) { Blt_Tree_NewTagTable(cmdPtr->tree); } ClearTracesAndEvents(cmdPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ChildrenOp -- * *--------------------------------------------------------------------------- */ static int ChildrenOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (node = Blt_Tree_FirstChild(node); node != NULL; node = Blt_Tree_NextSibling(node)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(node)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else if (objc == 4) { long childPos; long inode; long count; /* Get the node at */ if (Tcl_GetLongFromObj(interp, objv[3], &childPos) != TCL_OK) { return TCL_ERROR; } count = 0; inode = -1; for (node = Blt_Tree_FirstChild(node); node != NULL; node = Blt_Tree_NextSibling(node)) { if (count == childPos) { inode = Blt_Tree_NodeId(node); break; } count++; } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } else if (objc == 5) { long firstPos, lastPos; long count; Tcl_Obj *listObjPtr; char *string; firstPos = lastPos = Blt_Tree_NodeDegree(node) - 1; string = Tcl_GetString(objv[3]); if ((strcmp(string, "end") != 0) && (Tcl_GetLongFromObj(interp, objv[3], &firstPos) != TCL_OK)) { return TCL_ERROR; } string = Tcl_GetString(objv[4]); if ((strcmp(string, "end") != 0) && (Tcl_GetLongFromObj(interp, objv[4], &lastPos) != TCL_OK)) { return TCL_ERROR; } count = 0; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (node = Blt_Tree_FirstChild(node); node != NULL; node = Blt_Tree_NextSibling(node)) { if ((count >= firstPos) && (count <= lastPos)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(node)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } count++; } Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } static Blt_TreeNode CopyNodes( CopySwitches *copyPtr, Blt_TreeNode node, /* Node to be copied. */ Blt_TreeNode parent) /* New parent for the copied node. */ { Blt_TreeNode newNode; /* Newly created copy. */ const char *label; newNode = NULL; label = Blt_Tree_NodeLabel(node); if (copyPtr->flags & COPY_OVERWRITE) { newNode = Blt_Tree_FindChild(parent, label); } if (newNode == NULL) { /* Create node in new parent. */ newNode = Blt_Tree_CreateNode(copyPtr->destTree, parent, label, -1); } /* Copy the data fields. */ { Blt_TreeKey key; Blt_TreeKeyIterator iter; for (key = Blt_Tree_FirstKey(copyPtr->srcTree, node, &iter); key != NULL; key = Blt_Tree_NextKey(copyPtr->srcTree, &iter)) { Tcl_Obj *objPtr; if (Blt_Tree_GetValueByKey((Tcl_Interp *)NULL, copyPtr->srcTree, node, key, &objPtr) == TCL_OK) { Blt_Tree_SetValueByKey((Tcl_Interp *)NULL, copyPtr->destTree, newNode, key, objPtr); } } } /* Add tags to destination tree command. */ if ((copyPtr->destPtr != NULL) && (copyPtr->flags & COPY_TAGS)) { Blt_HashSearch iter; Blt_HashEntry *hPtr; for (hPtr = Blt_Tree_FirstTag(copyPtr->srcPtr->tree, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashEntry *h2Ptr; Blt_TreeTagEntry *tPtr; tPtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(&tPtr->nodeTable, (char *)node); if (h2Ptr != NULL) { if (AddTag(copyPtr->destPtr, newNode, tPtr->tagName)!= TCL_OK) { return NULL; } } } } if (copyPtr->flags & COPY_RECURSE) { Blt_TreeNode child; for (child = Blt_Tree_FirstChild(node); child != NULL; child = Blt_Tree_NextSibling(child)) { if (CopyNodes(copyPtr, child, newNode) == NULL) { return NULL; } } } return newNode; } /* *--------------------------------------------------------------------------- * * CopyOp -- * * t0 copy node tree node * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CopyOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmd *srcPtr, *destPtr; Blt_Tree srcTree, destTree; Blt_TreeNode copyNode; Blt_TreeNode parent; CopySwitches switches; int nArgs, nSwitches; Blt_TreeNode root; int i; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &parent) != TCL_OK) { return TCL_ERROR; } srcTree = destTree = cmdPtr->tree; srcPtr = destPtr = cmdPtr; /* Find the first switch. */ for(i = 3; i < objc; i++) { char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } } nArgs = i - 2; nSwitches = objc - i; if ((nArgs < 2) || (nArgs > 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " copy parent ?tree? node ?switches?", (char *)NULL); return TCL_ERROR; } if (nArgs == 3) { char *string; /* * The tree name is either the name of a tree command (first choice) * or an internal tree object. */ string = Tcl_GetString(objv[3]); srcPtr = GetTreeCmd(cmdPtr->tdPtr, interp, string); if (srcPtr != NULL) { srcTree = srcPtr->tree; } else { /* Try to get the tree as an internal tree data object. */ srcTree = Blt_Tree_Open(interp, string, 0); if (srcTree == NULL) { return TCL_ERROR; } } objv++; } root = NULL; if (srcPtr == NULL) { if (GetForeignNode(interp, srcTree, objv[3], &copyNode) != TCL_OK) { goto error; } } else { if (GetNodeFromObj(interp, srcPtr->tree, objv[3], &copyNode) != TCL_OK) { goto error; } } memset((char *)&switches, 0, sizeof(switches)); switches.destPtr = destPtr; switches.destTree = destTree; switches.srcPtr = srcPtr; switches.srcTree = srcTree; /* Process switches */ if (Blt_ParseSwitches(interp, copySwitches, nSwitches, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } if ((switches.flags & COPY_OVERWRITE) && (Blt_Tree_ParentNode(copyNode) == parent)) { Tcl_AppendResult(interp, "source and destination nodes are the same", (char *)NULL); goto error; } if ((srcTree == destTree) && (switches.flags & COPY_RECURSE) && (Blt_Tree_IsAncestor(copyNode, parent))) { Tcl_AppendResult(interp, "can't make cyclic copy: ", "source node is an ancestor of the destination", (char *)NULL); goto error; } /* Copy nodes to destination. */ root = CopyNodes(&switches, copyNode, parent); if (root != NULL) { if (switches.label != NULL) { Blt_Tree_RelabelNode(switches.destTree, root, switches.label); } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeId(root)); } error: if (srcPtr == NULL) { Blt_Tree_Close(srcTree); } return (root == NULL) ? TCL_ERROR : TCL_OK; } /* *--------------------------------------------------------------------------- * * DegreeOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DegreeOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeDegree(node)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes one or more nodes from the tree. Nodes may be specified by * their id (a number) or a tag. * * Tags have to be handled carefully here. We can't use the normal * GetTaggedNode, NextTaggedNode, etc. routines because they walk * hashtables while we're deleting nodes. Also, remember that deleting a * node recursively deletes all its children. If a parent and its * children have the same tag, its possible that the tag list may contain * nodes than no longer exist. So save the node indices in a list and * then delete then in a second pass. * *--------------------------------------------------------------------------- */ static int DeleteOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; char *string; string = NULL; for (i = 2; i < objc; i++) { string = Tcl_GetString(objv[i]); if (IsNodeIdOrModifier(string)) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[i], &node) != TCL_OK){ return TCL_ERROR; } DeleteNode(cmdPtr, node); } else { Blt_Chain chain; Blt_ChainLink link, next; Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_HashTable *tablePtr; if ((strcmp(string, "all") == 0) || (strcmp(string, "root") == 0)) { Blt_TreeNode node; node = Blt_Tree_RootNode(cmdPtr->tree); DeleteNode(cmdPtr, node); continue; } tablePtr = Blt_Tree_TagHashTable(cmdPtr->tree, string); if (tablePtr == NULL) { goto error; } /* * Generate a list of tagged nodes. Save the inode instead of the * node itself since a pruned branch may contain more tagged * nodes. */ chain = Blt_Chain_Create(); for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeNode node; node = Blt_GetHashValue(hPtr); Blt_Chain_Append(chain, (ClientData)Blt_Tree_NodeId(node)); } /* * Iterate through this list to delete the nodes. By side-effect * the tag table is deleted and Uids are released. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = next) { Blt_TreeNode node; long inode; next = Blt_Chain_NextLink(link); inode = (long)Blt_Chain_GetValue(link); node = Blt_Tree_GetNode(cmdPtr->tree, inode); if (node != NULL) { DeleteNode(cmdPtr, node); } } Blt_Chain_Destroy(chain); } } return TCL_OK; error: Tcl_AppendResult(interp, "can't find tag or id \"", string, "\" in ", Blt_Tree_Name(cmdPtr->tree), (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DepthOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DepthOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeDepth(node)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DumpOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DumpOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode top; Tcl_DString dString; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &top) != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&dString); Blt_Tree_Dump(cmdPtr->tree, top, &dString); Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DumpfileOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DumpfileOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode top; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &top) != TCL_OK) { return TCL_ERROR; } return Blt_Tree_DumpToFile(interp, cmdPtr->tree, top, Tcl_GetString(objv[3])); } /* *--------------------------------------------------------------------------- * * ExistsOp -- * *--------------------------------------------------------------------------- */ static int ExistsOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; int bool; bool = TRUE; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { bool = FALSE; } else if (objc == 4) { Tcl_Obj *valueObjPtr; char *string; string = Tcl_GetString(objv[3]); if (Blt_Tree_GetValue((Tcl_Interp *)NULL, cmdPtr->tree, node, string, &valueObjPtr) != TCL_OK) { bool = FALSE; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExportOp -- * *--------------------------------------------------------------------------- */ static int ExportOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TreeCmdInterpData *dataPtr; dataPtr = GetTreeCmdInterpData(interp); if (objc == 2) { Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->exportProc != NULL) { Tcl_AppendElement(interp, fmtPtr->name); } } return TCL_OK; } hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, Tcl_GetString(objv[2])); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't export \"", Tcl_GetString(objv[2]), "\": format not registered", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->exportProc == NULL) { Tcl_AppendResult(interp, "no export procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } return (*fmtPtr->exportProc) (interp, cmdPtr->tree, objc, objv); } /* *--------------------------------------------------------------------------- * * FindOp -- * *--------------------------------------------------------------------------- */ static int FindOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; FindSwitches switches; int result; Tcl_Obj **objArr; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); switches.maxDepth = -1; switches.order = TREE_POSTORDER; switches.cmdPtr = cmdPtr; Blt_InitHashTable(&switches.excludeTable, BLT_ONE_WORD_KEYS); objArr = NULL; /* Process switches */ if (Blt_ParseSwitches(interp, findSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.maxDepth >= 0) { switches.maxDepth += Blt_Tree_NodeDepth(node); } if (switches.flags & MATCH_NOCASE) { Blt_ListNode lnode; for (lnode = Blt_List_FirstNode(switches.patternList); lnode != NULL; lnode = Blt_List_NextNode(lnode)) { strtolower((char *)Blt_List_GetKey(lnode)); } } switches.listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); switches.cmdPtr = cmdPtr; if (switches.order == TREE_BREADTHFIRST) { result = Blt_Tree_ApplyBFS(node, MatchNodeProc, &switches); } else { result = Blt_Tree_ApplyDFS(node, MatchNodeProc, &switches, switches.order); } Blt_FreeSwitches(findSwitches, (char *)&switches, 0); if (result == TCL_ERROR) { return TCL_ERROR; } Tcl_SetObjResult(interp, switches.listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindChildOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FindChildOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode parent, child; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &parent) != TCL_OK) { return TCL_ERROR; } inode = -1; child = Blt_Tree_FindChild(parent, Tcl_GetString(objv[3])); if (child != NULL) { inode = Blt_Tree_NodeId(child); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FirstChildOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FirstChildOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } inode = -1; node = Blt_Tree_FirstChild(node); if (node != NULL) { inode = Blt_Tree_NodeId(node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * *--------------------------------------------------------------------------- */ static int GetOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { Blt_TreeKey key; Tcl_Obj *valueObjPtr, *listObjPtr; Blt_TreeKeyIterator iter; /* Add the key-value pairs to a new Tcl_Obj */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &iter)) { if (Blt_Tree_GetValue((Tcl_Interp *)NULL, cmdPtr->tree, node, key, &valueObjPtr) == TCL_OK) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_ListObjAppendElement(interp, listObjPtr, valueObjPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } else { Tcl_Obj *valueObjPtr; const char *string; string = Tcl_GetString(objv[3]); if (Blt_Tree_GetValue((Tcl_Interp *)NULL, cmdPtr->tree, node, string, &valueObjPtr) != TCL_OK) { if (objc == 4) { Tcl_DString dString; const char *path; Tcl_DStringInit(&dString); path = Blt_Tree_NodePath(node, &dString); Tcl_AppendResult(interp, "can't find field \"", string, "\" in \"", path, "\"", (char *)NULL); Tcl_DStringFree(&dString); return TCL_ERROR; } /* Default to given value */ valueObjPtr = objv[4]; } Tcl_SetObjResult(interp, valueObjPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImportOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ImportOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TreeCmdInterpData *dataPtr; dataPtr = GetTreeCmdInterpData(interp); if (objc == 2) { Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->importProc != NULL) { Tcl_AppendElement(interp, fmtPtr->name); } } return TCL_OK; } hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, Tcl_GetString(objv[2])); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't import \"", Tcl_GetString(objv[2]), "\": format not registered", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->importProc == NULL) { Tcl_AppendResult(interp, "no import procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } return (*fmtPtr->importProc) (interp, cmdPtr->tree, objc, objv); } /* *--------------------------------------------------------------------------- * * IndexOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; char *string; inode = -1; string = Tcl_GetString(objv[2]); if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) == TCL_OK) { if (node != NULL) { inode = Blt_Tree_NodeId(node); } } else { int i; Blt_TreeNode parent; Tcl_Obj **pathv; int pathc; if (Tcl_ListObjGetElements(interp, objv[2], &pathc, &pathv) != TCL_OK) { goto done; /* Can't split object. */ } /* Start from the root and verify each path component. */ parent = Blt_Tree_RootNode(cmdPtr->tree); for (i = 0; i < pathc; i++) { string = Tcl_GetString(pathv[i]); if (string[0] == '\0') { continue; /* Skip null separators. */ } node = Blt_Tree_FindChild(parent, string); if (node == NULL) { goto done; /* Can't find component */ } parent = node; } inode = Blt_Tree_NodeId(node); } done: Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * *--------------------------------------------------------------------------- */ static int InsertOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode parent, child; InsertSwitches switches; child = NULL; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &parent) != TCL_OK) { return TCL_ERROR; } /* Initialize switch flags */ memset(&switches, 0, sizeof(switches)); switches.position = -1; /* Default to append node. */ switches.parent = parent; switches.inode = -1; if (Blt_ParseSwitches(interp, insertSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } if (switches.inode > 0) { Blt_TreeNode node; node = Blt_Tree_GetNode(cmdPtr->tree, switches.inode); if (node != NULL) { Tcl_AppendResult(interp, "can't reissue node id \"", Blt_Ltoa(switches.inode), "\": id already exists.", (char *)NULL); goto error; } child = Blt_Tree_CreateNodeWithId(cmdPtr->tree, parent, switches.label, switches.inode, switches.position); } else { child = Blt_Tree_CreateNode(cmdPtr->tree, parent, switches.label, switches.position); } if (child == NULL) { Tcl_AppendResult(interp, "can't allocate new node", (char *)NULL); goto error; } if (switches.label == NULL) { char string[200]; sprintf_s(string, 200, "node%ld", Blt_Tree_NodeId(child)); Blt_Tree_RelabelNodeWithoutNotify(child, string); } if (switches.tagsObjPtr != NULL) { int i, nTags; Tcl_Obj **tags; if (Tcl_ListObjGetElements(interp, switches.tagsObjPtr, &nTags, &tags) != TCL_OK) { goto error; } for (i = 0; i < nTags; i++) { if (AddTag(cmdPtr, child, Tcl_GetString(tags[i])) != TCL_OK) { goto error; } } } if (switches.dataPairs != NULL) { char **p; for (p = switches.dataPairs; *p != NULL; p++) { Tcl_Obj *objPtr; char *key; key = *p; p++; if (*p == NULL) { Tcl_AppendResult(interp, "missing value for \"", key, "\"", (char *)NULL); goto error; } objPtr = Tcl_NewStringObj(*p, -1); if (Blt_Tree_SetValue(interp, cmdPtr->tree, child, key, objPtr) != TCL_OK) { Tcl_DecrRefCount(objPtr); goto error; } } } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeId(child)); Blt_FreeSwitches(insertSwitches, (char *)&switches, 0); return TCL_OK; error: if (child != NULL) { Blt_Tree_DeleteNode(cmdPtr->tree, child); } Blt_FreeSwitches(insertSwitches, (char *)&switches, 0); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * IsAncestorOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsAncestorOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node1, node2; int bool; if ((GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node1) != TCL_OK) || (GetNodeFromObj(interp, cmdPtr->tree, objv[4], &node2) != TCL_OK)) { return TCL_ERROR; } bool = Blt_Tree_IsAncestor(node1, node2); Tcl_SetIntObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsBeforeOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsBeforeOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node1, node2; int bool; if ((GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node1) != TCL_OK) || (GetNodeFromObj(interp, cmdPtr->tree, objv[4], &node2) != TCL_OK)) { return TCL_ERROR; } bool = Blt_Tree_IsBefore(node1, node2); Tcl_SetIntObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsLeafOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsLeafOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), Blt_Tree_IsLeaf(node)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsRootOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsRootOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; int bool; if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } bool = (node == Blt_Tree_RootNode(cmdPtr->tree)); Tcl_SetIntObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsOp -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec isOps[] = { {"ancestor", 1, IsAncestorOp, 5, 5, "node1 node2",}, {"before", 1, IsBeforeOp, 5, 5, "node1 node2",}, {"leaf", 2, IsLeafOp, 4, 4, "node",}, {"root", 1, IsRootOp, 4, 4, "node",}, }; static int nIsOps = sizeof(isOps) / sizeof(Blt_OpSpec); static int IsOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nIsOps, isOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * KeysOp -- * * Returns the key names of values for a node or array value. * *--------------------------------------------------------------------------- */ static int KeysOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable keyTable; int i; Blt_InitHashTableWithPool(&keyTable, BLT_ONE_WORD_KEYS); for (i = 2; i < objc; i++) { Blt_TreeNode node; TagSearch iter; int isNew; if (FirstTaggedNode(interp, cmdPtr, objv[i], &iter, &node) != TCL_OK) { return TCL_ERROR; } for (/* empty */; node != NULL; node = NextTaggedNode(node, &iter)) { Blt_TreeKey key; Blt_TreeKeyIterator keyIter; for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &keyIter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &keyIter)) { Blt_CreateHashEntry(&keyTable, key, &isNew); } } } { Blt_HashSearch tagSearch; Blt_HashEntry *hPtr; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&keyTable, &tagSearch); hPtr != NULL; hPtr = Blt_NextHashEntry(&tagSearch)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_GetHashKey(&keyTable, hPtr), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_DeleteHashTable(&keyTable); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LabelOp -- * *--------------------------------------------------------------------------- */ static int LabelOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { Blt_Tree_RelabelNode(cmdPtr->tree, node, Tcl_GetString(objv[3])); } Tcl_SetStringObj(Tcl_GetObjResult(interp), Blt_Tree_NodeLabel(node), -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LastChildOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int LastChildOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_LastChild(node); inode = (node != NULL) ? Blt_Tree_NodeId(node) : -1 ; Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MoveOp -- * * The trick here is to not consider the node to be moved in determining * it's new location. Ideally, you would temporarily pull it from the * tree and replace it (back in its old location if something went * wrong), but you could still pick the node by its serial number. So * here we make lots of checks for the node to be moved. * *--------------------------------------------------------------------------- */ static int MoveOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode root, parent, node; Blt_TreeNode before; MoveSwitches switches; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &parent) != TCL_OK) { return TCL_ERROR; } root = Blt_Tree_RootNode(cmdPtr->tree); if (node == root) { Tcl_AppendResult(interp, "can't move root node", (char *)NULL); return TCL_ERROR; } if (parent == node) { Tcl_AppendResult(interp, "can't move node to self", (char *)NULL); return TCL_ERROR; } switches.node = NULL; switches.cmdPtr = cmdPtr; switches.movePos = -1; nodeSwitch.clientData = cmdPtr->tree; /* Process switches */ if (Blt_ParseSwitches(interp, moveSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } /* Verify they aren't ancestors. */ if (Blt_Tree_IsAncestor(node, parent)) { Tcl_AppendResult(interp, "can't move node: \"", Tcl_GetString(objv[2]), (char *)NULL); Tcl_AppendResult(interp, "\" is an ancestor of \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } before = NULL; /* If before is NULL, this appends the node to * the parent's child list. */ if (switches.node != NULL) { /* -before or -after */ if (Blt_Tree_ParentNode(switches.node) != parent) { Tcl_AppendResult(interp, Tcl_GetString(objv[2]), " isn't the parent of ", Blt_Tree_NodeLabel(switches.node), (char *)NULL); return TCL_ERROR; } if (Blt_SwitchChanged(moveSwitches, "-before", (char *)NULL)) { before = switches.node; if (before == node) { Tcl_AppendResult(interp, "can't move node before itself", (char *)NULL); return TCL_ERROR; } } else { before = Blt_Tree_NextSibling(switches.node); if (before == node) { Tcl_AppendResult(interp, "can't move node after itself", (char *)NULL); return TCL_ERROR; } } } else if (switches.movePos >= 0) { /* -at */ int count; /* Tracks the current list index. */ Blt_TreeNode child; /* * If the node is in the list, ignore it when determining the "before" * node using the -at index. An index of -1 means to append the node * to the list. */ count = 0; for(child = Blt_Tree_FirstChild(parent); child != NULL; child = Blt_Tree_NextSibling(child)) { if (child == node) { continue; /* Ignore the node to be moved. */ } if (count == switches.movePos) { before = child; break; } count++; } } if (Blt_Tree_MoveNode(cmdPtr->tree, node, parent, before) != TCL_OK) { Tcl_AppendResult(interp, "can't move node ", Tcl_GetString(objv[2]), " to ", Tcl_GetString(objv[3]), (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NextOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_NextNode(NULL, node); inode = (node != NULL) ? Blt_Tree_NodeId(node) : -1; Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextSiblingOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NextSiblingOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } inode = -1; node = Blt_Tree_NextSibling(node); if (node != NULL) { inode = Blt_Tree_NodeId(node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyCreateOp -- * * tree0 notify create ?flags? command arg *--------------------------------------------------------------------------- */ static int NotifyCreateOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Notifier *notifyPtr; NotifySwitches switches; int i; nodeSwitch.clientData = cmdPtr->tree; memset(&switches, 0, sizeof(switches)); /* Process switches */ i = Blt_ParseSwitches(interp, notifySwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { return TCL_ERROR; } objc -= 3 + i; objv += 3 + i; notifyPtr = Blt_AssertCalloc(1, sizeof(Notifier)); notifyPtr->inode = -1; if (switches.node != NULL) { notifyPtr->inode = Blt_Tree_NodeId(switches.node); } if (switches.tag != NULL) { notifyPtr->tag = Blt_Strdup(switches.tag); } notifyPtr->cmdObjPtr = Tcl_NewListObj(objc, objv); Tcl_IncrRefCount(notifyPtr->cmdObjPtr); notifyPtr->cmdPtr = cmdPtr; if (switches.mask == 0) { switches.mask = TREE_NOTIFY_ALL; } notifyPtr->mask = switches.mask; { Blt_HashEntry *hPtr; char idString[200]; int isNew; sprintf_s(idString, 200, "notify%d", cmdPtr->notifyCounter++); hPtr = Blt_CreateHashEntry(&cmdPtr->notifyTable, idString, &isNew); assert(isNew); notifyPtr->link = Blt_Chain_Append(cmdPtr->notifiers, notifyPtr); Blt_SetHashValue(hPtr, notifyPtr); notifyPtr->hashPtr = hPtr; Tcl_SetStringObj(Tcl_GetObjResult(interp), idString, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyDeleteOp -- * *--------------------------------------------------------------------------- */ static int NotifyDeleteOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Blt_HashEntry *hPtr; Notifier *notifyPtr; char *string; string = Tcl_GetString(objv[i]); hPtr = Blt_FindHashEntry(&cmdPtr->notifyTable, string); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown notify name \"", string, "\"", (char *)NULL); return TCL_ERROR; } notifyPtr = Blt_GetHashValue(hPtr); FreeNotifier(cmdPtr, notifyPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyInfoOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NotifyInfoOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Notifier *notifyPtr; Blt_HashEntry *hPtr; Tcl_DString dString; char *string; string = Tcl_GetString(objv[3]); hPtr = Blt_FindHashEntry(&cmdPtr->notifyTable, string); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown notify name \"", string, "\"", (char *)NULL); return TCL_ERROR; } notifyPtr = Blt_GetHashValue(hPtr); Tcl_DStringInit(&dString); Tcl_DStringAppendElement(&dString, string); /* Copy notify Id */ Tcl_DStringStartSublist(&dString); if (notifyPtr->mask & TREE_NOTIFY_CREATE) { Tcl_DStringAppendElement(&dString, "-create"); } if (notifyPtr->mask & TREE_NOTIFY_DELETE) { Tcl_DStringAppendElement(&dString, "-delete"); } if (notifyPtr->mask & TREE_NOTIFY_MOVE) { Tcl_DStringAppendElement(&dString, "-move"); } if (notifyPtr->mask & TREE_NOTIFY_SORT) { Tcl_DStringAppendElement(&dString, "-sort"); } if (notifyPtr->mask & TREE_NOTIFY_RELABEL) { Tcl_DStringAppendElement(&dString, "-relabel"); } if (notifyPtr->mask & TREE_NOTIFY_WHENIDLE) { Tcl_DStringAppendElement(&dString, "-whenidle"); } Tcl_DStringEndSublist(&dString); Tcl_DStringStartSublist(&dString); Tcl_DStringAppendElement(&dString, Tcl_GetString(notifyPtr->cmdObjPtr)); Tcl_DStringEndSublist(&dString); Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyNamesOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NotifyNamesOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&cmdPtr->notifyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_Obj *objPtr; char *notifyId; notifyId = Blt_GetHashKey(&cmdPtr->notifyTable, hPtr); objPtr = Tcl_NewStringObj(notifyId, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyOp -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec notifyOps[] = { {"create", 1, NotifyCreateOp, 4, 0, "?flags? command",}, {"delete", 1, NotifyDeleteOp, 3, 0, "notifyId...",}, {"info", 1, NotifyInfoOp, 4, 4, "notifyId",}, {"names", 1, NotifyNamesOp, 3, 3, "",}, }; static int nNotifyOps = sizeof(notifyOps) / sizeof(Blt_OpSpec); static int NotifyOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nNotifyOps, notifyOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int ParentOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } inode = -1; node = Blt_Tree_ParentNode(node); if (node != NULL) { inode = Blt_Tree_NodeId(node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PathOp -- * * $tree path $node * $t path $node -separator * $t path $node $path -separator / *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PathOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode parent; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &parent) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { Tcl_DString dString; Tcl_DStringInit(&dString); Blt_Tree_NodePath(parent, &dString); Tcl_DStringResult(interp, &dString); return TCL_OK; } else { Blt_TreeNode child; PathSwitches switches; const char **argv; int argc; int i; int result; const char *path; /* Process switches */ memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, pathSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = SplitPath(interp, Tcl_GetString(objv[3]), switches.separator, &argc, &argv); Blt_FreeSwitches(pathSwitches, (char *)&switches, 0); if (argc == 0) { goto done; } if (result != TCL_OK) { return TCL_ERROR; } for (i = 0; i < (argc - 1); i++) { Blt_TreeNode child; child = Blt_Tree_FindChild(parent, argv[i]); if (child == NULL) { if (switches.flags & PATH_PARENTS) { child = Blt_Tree_CreateNode(cmdPtr->tree, parent, argv[i], -1); } else if (switches.flags & PATH_NOCOMPLAIN) { parent = NULL; goto done; } else { Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_AppendResult(interp, "can't find \"", argv[i], "\" in ", Blt_Tree_NodePath(parent, &ds), "\"", (char *)NULL); Tcl_DStringFree(&ds); Blt_Free(argv); return TCL_ERROR; } } parent = child; } child = Blt_Tree_FindChild(parent, argv[i]); if (child == NULL) { if (switches.flags & (PATH_PARENTS | PATH_LEAF)) { child = Blt_Tree_CreateNode(cmdPtr->tree, parent, argv[i], -1); } else if (switches.flags & PATH_NOCOMPLAIN){ parent = NULL; goto done; } else { Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_AppendResult(interp, "can't find \"", argv[i], "\" in ", Blt_Tree_NodePath(parent, &ds), "\"", (char *)NULL); Tcl_DStringFree(&ds); Blt_Free(argv); return TCL_ERROR; } } parent = child; done: Blt_Free(argv); } inode = -1; if (parent != NULL) { inode = Blt_Tree_NodeId(parent); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } static int ComparePositions(Blt_TreeNode *n1Ptr, Blt_TreeNode *n2Ptr) { if (*n1Ptr == *n2Ptr) { return 0; } if (Blt_Tree_IsBefore(*n1Ptr, *n2Ptr)) { return -1; } return 1; } /* *--------------------------------------------------------------------------- * * PositionOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PositionOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PositionSwitches switches; Blt_TreeNode *nodeArr, *nodePtr; Blt_TreeNode lastParent; Tcl_Obj *listObjPtr, *objPtr; int i; long position; Tcl_DString dString; int n; memset((char *)&switches, 0, sizeof(switches)); /* Process switches */ n = Blt_ParseSwitches(interp, positionSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_OBJV_PARTIAL); if (n < 0) { return TCL_ERROR; } objc -= n + 2, objv += n + 2; /* Collect the node ids into an array */ nodeArr = Blt_AssertMalloc((objc + 1) * sizeof(Blt_TreeNode)); for (i = 0; i < objc; i++) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[i], &node) != TCL_OK) { Blt_Free(nodeArr); return TCL_ERROR; } nodeArr[i] = node; } nodeArr[i] = NULL; if (switches.sort) { /* Sort the nodes by depth-first order * if requested. */ qsort((char *)nodeArr, objc, sizeof(Blt_TreeNode), (QSortCompareProc *)ComparePositions); } position = 0; /* Suppress compiler warning. */ lastParent = NULL; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_DStringInit(&dString); for (nodePtr = nodeArr; *nodePtr != NULL; nodePtr++) { Blt_TreeNode parent; parent = Blt_Tree_ParentNode(*nodePtr); if ((parent != NULL) && (parent == lastParent)) { Blt_TreeNode node; /* * Since we've sorted the nodes already, we can safely assume that * if two consecutive nodes have the same parent, the first node * came before the second. If this is the case, use the last node * as a starting point. */ /* * Note that we start comparing from the last node, not its * successor. Some one may give us the same node more than once. */ node = *(nodePtr - 1); /* Can't get here unless there's more than * one node. */ for(/*empty*/; node != NULL; node = Blt_Tree_NextSibling(node)) { if (node == *nodePtr) { break; } position++; } } else { /* * The fallback is to linearly search through the parent's list of * children, counting the number of preceding siblings. Except for * nodes with many siblings (100+), this should be okay. */ position = Blt_Tree_NodePosition(*nodePtr); } if (switches.sort) { lastParent = parent; /* Update the last parent. */ } /* * Add an element in the form "parent -at position" to the list that * we're generating. */ if (switches.withId) { objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(*nodePtr)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } if (switches.withParent) { const char *string; Tcl_DStringSetLength(&dString, 0); /* Clear the string. */ string = (parent == NULL) ? "" : Blt_Tree_NodeIdAscii(parent); Tcl_DStringAppendElement(&dString, string); Tcl_DStringAppendElement(&dString, "-at"); Tcl_DStringAppendElement(&dString, Blt_Ltoa(position)); objPtr = Tcl_NewStringObj(Tcl_DStringValue(&dString), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } else { objPtr = Tcl_NewLongObj(position); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_DStringFree(&dString); Blt_Free(nodeArr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PreviousOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PreviousOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_PrevNode(NULL, node); inode = (node != NULL) ? Blt_Tree_NodeId(node) : -1; Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /*ARGSUSED*/ static int PrevSiblingOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; long inode; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } inode = -1; node = Blt_Tree_PrevSibling(node); if (node != NULL) { inode = Blt_Tree_NodeId(node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RestoreOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RestoreOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode root; /* Root node of restored subtree. */ RestoreSwitches switches; char *string; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &root) != TCL_OK) { return TCL_ERROR; } memset((char *)&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, restoreSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } string = Tcl_GetString(objv[3]); if (strcmp(Tcl_GetString(objv[1]), "restore") == 0) { return Blt_Tree_Restore(interp, cmdPtr->tree, root, string, switches.flags); } else { return Blt_Tree_RestoreFromFile(interp, cmdPtr->tree, root, string, switches.flags); } } /* *--------------------------------------------------------------------------- * * RootOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RootOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode root; root = Blt_Tree_RootNode(cmdPtr->tree); Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeId(root)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetOp -- * *--------------------------------------------------------------------------- */ static int SetOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; TagSearch iter; if (FirstTaggedNode(interp, cmdPtr, objv[2], &iter, &node) != TCL_OK) { return TCL_ERROR; } while (node != NULL) { if (SetValues(cmdPtr, node, objc - 3, objv + 3) != TCL_OK) { return TCL_ERROR; } node = NextTaggedNode(node, &iter); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SizeOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SizeOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_Size(node)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagAddOp -- * * .t tag add tagName node1 node2 node3 * *--------------------------------------------------------------------------- */ static int TagAddOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *string; long nodeId; string = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &nodeId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", string, "\": can't be a number", (char *)NULL); return TCL_ERROR; } if ((strcmp(string, "all") == 0) || (strcmp(string, "root") == 0)) { Tcl_AppendResult(cmdPtr->interp, "can't add reserved tag \"", string, "\"", (char *)NULL); return TCL_ERROR; } if (objc == 4) { /* No nodes specified. Just add the tag. */ if (AddTag(cmdPtr, NULL, string) != TCL_OK) { return TCL_ERROR; } } else { int i; for (i = 4; i < objc; i++) { Blt_TreeNode node; TagSearch iter; if (FirstTaggedNode(interp, cmdPtr, objv[i], &iter, &node) != TCL_OK) { return TCL_ERROR; } for (/* empty */; node != NULL; node = NextTaggedNode(node, &iter)) { if (AddTag(cmdPtr, node, string) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagDeleteOp -- * * .t add tag node1 node2 node3 * *--------------------------------------------------------------------------- */ static int TagDeleteOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *string; Blt_HashTable *tablePtr; long nodeId; string = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &nodeId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", string, "\": can't be a number", (char *)NULL); return TCL_ERROR; } if ((strcmp(string, "all") == 0) || (strcmp(string, "root") == 0)) { Tcl_AppendResult(interp, "can't delete reserved tag \"", string, "\"", (char *)NULL); return TCL_ERROR; } tablePtr = Blt_Tree_TagHashTable(cmdPtr->tree, string); if (tablePtr != NULL) { int i; for (i = 4; i < objc; i++) { Blt_TreeNode node; TagSearch iter; if (FirstTaggedNode(interp, cmdPtr, objv[i], &iter, &node) != TCL_OK) { return TCL_ERROR; } for (/* empty */; node != NULL; node = NextTaggedNode(node, &iter)) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)node); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagDumpOp -- * * Like "dump", but dumps only the contents of nodes tagged by a given * tag. * *--------------------------------------------------------------------------- */ static int TagDumpOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode root; Tcl_DString dString; int i; Tcl_DStringInit(&dString); root = Blt_Tree_RootNode(cmdPtr->tree); for (i = 3; i < objc; i++) { Blt_TreeNode node; TagSearch iter; if (FirstTaggedNode(interp, cmdPtr, objv[i], &iter, &node) != TCL_OK) { Tcl_DStringFree(&dString); return TCL_ERROR; } for (/* empty */; node != NULL; node = NextTaggedNode(node, &iter)) { Blt_Tree_DumpNode(cmdPtr->tree, root, node, &dString); } } Tcl_DStringResult(interp, &dString); Tcl_DStringFree(&dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagExistsOp -- * * Returns the existence of the one or more tags in the given node. If * the node has any the tags, true is return in the interpreter. * * .t tag exists tag1 node * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagExistsOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; const char *tagName; tagName = Tcl_GetString(objv[3]); bool = (Blt_Tree_TagHashTable(cmdPtr->tree, tagName) != NULL); if (objc == 5) { Blt_TreeNode node; if (GetNodeFromObj(interp, cmdPtr->tree, objv[4], &node) != TCL_OK) { return TCL_ERROR; } bool = Blt_Tree_HasTag(cmdPtr->tree, node, tagName); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagForgetOp -- * * Removes the given tags from all nodes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagForgetOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { const char *string; long nodeId; string = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &nodeId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", string, "\": can't be a number", (char *)NULL); return TCL_ERROR; } Blt_Tree_ForgetTag(cmdPtr->tree, string); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagGetOp -- * * Returns tag names for a given node. If one of more pattern arguments * are provided, then only those matching tags are returned. * * .t tag get node pat1 pat2... * *--------------------------------------------------------------------------- */ static int TagGetOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; Tcl_Obj *listObjPtr; if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 4) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *objPtr; /* Dump all tags for this node. */ if (node == Blt_Tree_RootNode(cmdPtr->tree)) { objPtr = Tcl_NewStringObj("root", 4); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } for (hPtr = Blt_Tree_FirstTag(cmdPtr->tree, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeTagEntry *tPtr; Blt_HashEntry *h2Ptr; tPtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(&tPtr->nodeTable, (char *)node); if (h2Ptr != NULL) { objPtr = Tcl_NewStringObj(tPtr->tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } objPtr = Tcl_NewStringObj("all", 3); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } else { int i; Tcl_Obj *objPtr; /* Check if we need to add the special tags "all" and "root" */ for (i = 4; i < objc; i++) { char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch("all", pattern)) { objPtr = Tcl_NewStringObj("all", 3); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } if (node == Blt_Tree_RootNode(cmdPtr->tree)) { for (i = 4; i < objc; i++) { char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch("root", pattern)) { objPtr = Tcl_NewStringObj("root", 4); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } } /* Now process any standard tags. */ for (i = 4; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch iter; char *pattern; pattern = Tcl_GetString(objv[i]); for (hPtr = Blt_Tree_FirstTag(cmdPtr->tree, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeTagEntry *tPtr; tPtr = Blt_GetHashValue(hPtr); if (Tcl_StringMatch(tPtr->tagName, pattern)) { Blt_HashEntry *h2Ptr; h2Ptr = Blt_FindHashEntry(&tPtr->nodeTable, (char *)node); if (h2Ptr != NULL) { objPtr = Tcl_NewStringObj(tPtr->tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagNamesOp -- * * Returns the names of all the tags in the tree. If one of more node * arguments are provided, then only the tags found in those nodes are * returned. * * .t tag names node node node... * *--------------------------------------------------------------------------- */ static int TagNamesOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr, *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); objPtr = Tcl_NewStringObj("all", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; objPtr = Tcl_NewStringObj("root", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); for (hPtr = Blt_Tree_FirstTag(cmdPtr->tree, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeTagEntry *tPtr; tPtr = Blt_GetHashValue(hPtr); objPtr = Tcl_NewStringObj(tPtr->tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_HashTable uniqTable; int i; Blt_InitHashTable(&uniqTable, BLT_STRING_KEYS); for (i = 3; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_TreeNode node; int isNew; if (GetNodeFromObj(interp, cmdPtr->tree, objv[i], &node) != TCL_OK) { goto error; } if (node == Blt_Tree_RootNode(cmdPtr->tree)) { Blt_CreateHashEntry(&uniqTable, "root", &isNew); } for (hPtr = Blt_Tree_FirstTag(cmdPtr->tree, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeTagEntry *tPtr; Blt_HashEntry *h2Ptr; tPtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(&tPtr->nodeTable, (char *)node); if (h2Ptr != NULL) { Blt_CreateHashEntry(&uniqTable, tPtr->tagName, &isNew); } } } { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&uniqTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { objPtr = Tcl_NewStringObj(Blt_GetHashKey(&uniqTable, hPtr), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_DeleteHashTable(&uniqTable); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: Tcl_DecrRefCount(listObjPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagNodesOp -- * * Returns the node ids for the given tags. The ids returned will * represent the union of nodes for all the given tags. * * .t nodes tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ static int TagNodesOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable nodeTable; int i; Blt_InitHashTable(&nodeTable, BLT_ONE_WORD_KEYS); for (i = 3; i < objc; i++) { const char *string; int isNew; long nodeId; string = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &nodeId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", string, "\": can't be a number", (char *)NULL); goto error; } if (strcmp(string, "all") == 0) { break; } else if (strcmp(string, "root") == 0) { Blt_CreateHashEntry(&nodeTable, (char *)Blt_Tree_RootNode(cmdPtr->tree), &isNew); continue; } else { Blt_HashTable *tablePtr; tablePtr = Blt_Tree_TagHashTable(cmdPtr->tree, string); if (tablePtr != NULL) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeNode node; node = Blt_GetHashValue(hPtr); Blt_CreateHashEntry(&nodeTable, (char *)node, &isNew); } continue; } } Blt_DeleteHashTable(&nodeTable); return TCL_OK; } { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&nodeTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TreeNode node; Tcl_Obj *objPtr; node = (Blt_TreeNode)Blt_GetHashKey(&nodeTable, hPtr); objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(node)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_DeleteHashTable(&nodeTable); return TCL_OK; error: Blt_DeleteHashTable(&nodeTable); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagSetOp -- * * Sets one or more tags for a given node. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("root" or "all"). * * .t tag set node tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagSetOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; int i; if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { const char *string; long nodeId; string = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &nodeId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", string, "\": can't be a number", (char *)NULL); return TCL_ERROR; } if ((strcmp(string, "all") == 0) || (strcmp(string, "root") == 0)) { Tcl_AppendResult(interp, "can't add reserved tag \"", string, "\"", (char *)NULL); return TCL_ERROR; } if (AddTag(cmdPtr, node, string) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagUnsetOp -- * * Removes one or more tags from a given node. If a tag doesn't exist or * is a reserved tag ("root" or "all"), nothing will be done and no error * message will be returned. * * .t tag unset node tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagUnsetOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; int i; if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { Blt_Tree_RemoveTag(cmdPtr->tree, node, Tcl_GetString(objv[i])); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagOp -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec tagOps[] = { {"add", 1, TagAddOp, 4, 0, "tag ?node...?",}, {"delete", 2, TagDeleteOp, 5, 0, "tag node...",}, {"dump", 2, TagDumpOp, 4, 0, "tag...",}, {"exists", 1, TagExistsOp, 4, 5, "tag ?node?",}, {"forget", 1, TagForgetOp, 4, 0, "tag...",}, {"get", 1, TagGetOp, 4, 0, "node ?pattern...?",}, {"names", 2, TagNamesOp, 3, 0, "?node...?",}, {"nodes", 2, TagNodesOp, 4, 0, "tag ?tag...?",}, {"set", 1, TagSetOp, 4, 0, "node tag...",}, {"unset", 1, TagUnsetOp, 4, 0, "node tag...",}, }; static int nTagOps = sizeof(tagOps) / sizeof(Blt_OpSpec); static int TagOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTagOps, tagOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * TraceCreateOp -- * * $tree trace create nodeIdOrTag key rwu cmd switches * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceCreateOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; TraceInfo *tracePtr; const char *key, *command; const char *string; const char *tagName; int flags; int length; TraceSwitches switches; long nodeId; string = Tcl_GetString(objv[3]); if (IsTag(cmdPtr->tree, string)) { tagName = Blt_AssertStrdup(string); node = NULL; } else if (Tcl_GetLongFromObj(NULL, objv[3], &nodeId) == TCL_OK) { if (GetNodeFromObj(interp, cmdPtr->tree, objv[3], &node) != TCL_OK) { return TCL_ERROR; } tagName = NULL; } key = Tcl_GetString(objv[4]); string = Tcl_GetString(objv[5]); flags = GetTraceFlags(string); if (flags < 0) { Tcl_AppendResult(interp, "unknown flag in \"", string, "\"", (char *)NULL); return TCL_ERROR; } command = Tcl_GetStringFromObj(objv[6], &length); /* Process switches */ switches.mask = 0; if (Blt_ParseSwitches(interp, traceSwitches, objc-7, objv+7, &switches, BLT_SWITCH_DEFAULTS | BLT_SWITCH_OBJV_PARTIAL) < 0) { return TCL_ERROR; } /* Stash away the command in structure and pass that to the trace. */ tracePtr = Blt_AssertCalloc(1, length + sizeof(TraceInfo)); strcpy(tracePtr->command, command); tracePtr->cmdPtr = cmdPtr; tracePtr->withTag = tagName; tracePtr->node = node; flags |= switches.mask; tracePtr->traceToken = Blt_Tree_CreateTrace(cmdPtr->tree, node, key, tagName, flags, TreeTraceProc, tracePtr); { Blt_HashEntry *hPtr; char idString[200]; int isNew; sprintf_s(idString, 200, "trace%d", cmdPtr->traceCounter++); hPtr = Blt_CreateHashEntry(&cmdPtr->traceTable, idString, &isNew); Blt_SetHashValue(hPtr, tracePtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), idString, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceDeleteOp -- * *--------------------------------------------------------------------------- */ static int TraceDeleteOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Blt_HashEntry *hPtr; TraceInfo *tracePtr; char *key; key = Tcl_GetString(objv[i]); hPtr = Blt_FindHashEntry(&cmdPtr->traceTable, key); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown trace \"", key, "\"", (char *)NULL); return TCL_ERROR; } tracePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashEntry(&cmdPtr->traceTable, hPtr); Blt_Tree_DeleteTrace(tracePtr->traceToken); if (tracePtr->withTag != NULL) { Blt_Free(tracePtr->withTag); } Blt_Free(tracePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceNamesOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceNamesOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&cmdPtr->traceTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_AppendElement(interp, Blt_GetHashKey(&cmdPtr->traceTable, hPtr)); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceInfoOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceInfoOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TraceInfo *tracePtr; struct _Blt_TreeTrace *tokenPtr; Blt_HashEntry *hPtr; char string[5]; char *key; Tcl_Obj *listObjPtr, *objPtr; key = Tcl_GetString(objv[3]); hPtr = Blt_FindHashEntry(&cmdPtr->traceTable, key); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown trace \"", key, "\"", (char *)NULL); return TCL_ERROR; } tracePtr = Blt_GetHashValue(hPtr); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (tracePtr->withTag != NULL) { objPtr = Tcl_NewStringObj(tracePtr->withTag, -1); } else { objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(tracePtr->node)); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); tokenPtr = (struct _Blt_TreeTrace *)tracePtr->traceToken; objPtr = Tcl_NewStringObj(tokenPtr->key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); PrintTraceFlags(tokenPtr->mask, string); objPtr = Tcl_NewStringObj(string, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj(tracePtr->command, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceOp -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec traceOps[] = { {"create", 1, TraceCreateOp, 7, 0, "node key how command ?-whenidle?",}, {"delete", 1, TraceDeleteOp, 3, 0, "id...",}, {"info", 1, TraceInfoOp, 4, 4, "id",}, {"names", 1, TraceNamesOp, 3, 3, "",}, }; static int nTraceOps = sizeof(traceOps) / sizeof(Blt_OpSpec); static int TraceOp(TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTraceOps, traceOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * GetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_TreeNode node; Tcl_Obj *valueObjPtr; char *string; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetString(objv[3]); if (Blt_Tree_GetValue(interp, cmdPtr->tree, node, string, &valueObjPtr) != TCL_OK) { return TCL_ERROR; } if (valueObjPtr->typePtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), valueObjPtr->typePtr->name, -1); } else { Tcl_SetStringObj(Tcl_GetObjResult(interp), "string", 6); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnsetOp -- * *--------------------------------------------------------------------------- */ static int UnsetOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; const char *string; long nodeId; string = Tcl_GetString(objv[2]); if (Tcl_GetLongFromObj(NULL, objv[2], &nodeId) == TCL_OK) { if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } if (UnsetValues(cmdPtr, node, objc - 3, objv + 3) != TCL_OK) { return TCL_ERROR; } } else { TagSearch iter; if (FirstTaggedNode(interp, cmdPtr, objv[2], &iter, &node) != TCL_OK) { return TCL_ERROR; } for (/* empty */; node != NULL; node = NextTaggedNode(node, &iter)) { if (UnsetValues(cmdPtr, node, objc - 3, objv + 3) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } typedef struct { TreeCmd *cmdPtr; unsigned int flags; int type; int mode; char *key; const char *command; } SortSwitches; #define SORT_RECURSE (1<<2) #define SORT_DECREASING (1<<3) #define SORT_PATHNAME (1<<4) enum SortTypes { SORT_DICTIONARY, SORT_REAL, SORT_INTEGER, SORT_ASCII, SORT_COMMAND }; enum SortModes { SORT_FLAT, SORT_REORDER }; #define _off(x) Blt_Offset(SortSwitches, x) static Blt_SwitchSpec sortSwitches[] = { {BLT_SWITCH_VALUE, "-ascii", "", Blt_Offset(SortSwitches, type), 0, SORT_ASCII}, {BLT_SWITCH_STRING, "-command", "command", Blt_Offset(SortSwitches, command), 0}, {BLT_SWITCH_BITMASK, "-decreasing", "", Blt_Offset(SortSwitches, flags), 0, SORT_DECREASING}, {BLT_SWITCH_VALUE, "-dictionary", "", Blt_Offset(SortSwitches, type), 0, SORT_DICTIONARY}, {BLT_SWITCH_VALUE, "-integer", "", Blt_Offset(SortSwitches, type), 0, SORT_INTEGER}, {BLT_SWITCH_STRING, "-key", "string", Blt_Offset(SortSwitches, key), 0}, {BLT_SWITCH_BITMASK, "-path", "", Blt_Offset(SortSwitches, flags), 0, SORT_PATHNAME}, {BLT_SWITCH_VALUE, "-real", "", Blt_Offset(SortSwitches, type), 0, SORT_REAL}, {BLT_SWITCH_VALUE, "-recurse", "", Blt_Offset(SortSwitches, flags), 0, SORT_RECURSE}, {BLT_SWITCH_VALUE, "-reorder", "", Blt_Offset(SortSwitches, mode), 0, SORT_REORDER}, {BLT_SWITCH_END} }; #undef _off static SortSwitches sortData; static int CompareNodes(Blt_TreeNode *n1Ptr, Blt_TreeNode *n2Ptr) { TreeCmd *cmdPtr = sortData.cmdPtr; const char *s1, *s2; int result; Tcl_DString dString1, dString2; s1 = s2 = ""; result = 0; if (sortData.flags & SORT_PATHNAME) { Tcl_DStringInit(&dString1); Tcl_DStringInit(&dString2); } if (sortData.key != NULL) { Tcl_Obj *valueObjPtr; if (Blt_Tree_GetValue((Tcl_Interp *)NULL, cmdPtr->tree, *n1Ptr, sortData.key, &valueObjPtr) == TCL_OK) { s1 = Tcl_GetString(valueObjPtr); } if (Blt_Tree_GetValue((Tcl_Interp *)NULL, cmdPtr->tree, *n2Ptr, sortData.key, &valueObjPtr) == TCL_OK) { s2 = Tcl_GetString(valueObjPtr); } } else if (sortData.flags & SORT_PATHNAME) { Blt_TreeNode root; root = Blt_Tree_RootNode(cmdPtr->tree); Tcl_DStringInit(&dString1), Tcl_DStringInit(&dString2); s1 = Blt_Tree_NodeRelativePath(root, *n1Ptr, NULL, 0, &dString1); s2 = Blt_Tree_NodeRelativePath(root, *n2Ptr, NULL, 0, &dString2); } else { s1 = Blt_Tree_NodeLabel(*n1Ptr); s2 = Blt_Tree_NodeLabel(*n2Ptr); } switch (sortData.type) { case SORT_ASCII: result = strcmp(s1, s2); break; case SORT_COMMAND: if (sortData.command == NULL) { result = Blt_DictionaryCompare(s1, s2); } else { Blt_ObjectName objName; Tcl_DString dsCmd, dsName; char *qualName; result = 0; /* Hopefully this will be okay even if the TCL command * fails to return the correct result. */ Tcl_DStringInit(&dsCmd); Tcl_DStringAppend(&dsCmd, sortData.command, -1); Tcl_DStringInit(&dsName); objName.name = Tcl_GetCommandName(cmdPtr->interp, cmdPtr->cmdToken); objName.nsPtr = Blt_GetCommandNamespace(cmdPtr->cmdToken); qualName = Blt_MakeQualifiedName(&objName, &dsName); Tcl_DStringAppendElement(&dsCmd, qualName); Tcl_DStringFree(&dsName); Tcl_DStringAppendElement(&dsCmd, Blt_Tree_NodeIdAscii(*n1Ptr)); Tcl_DStringAppendElement(&dsCmd, Blt_Tree_NodeIdAscii(*n2Ptr)); Tcl_DStringAppendElement(&dsCmd, s1); Tcl_DStringAppendElement(&dsCmd, s2); result = Tcl_GlobalEval(cmdPtr->interp, Tcl_DStringValue(&dsCmd)); Tcl_DStringFree(&dsCmd); if ((result != TCL_OK) || (Tcl_GetInt(cmdPtr->interp, Tcl_GetStringResult(cmdPtr->interp), &result) != TCL_OK)) { Tcl_BackgroundError(cmdPtr->interp); } Tcl_ResetResult(cmdPtr->interp); } break; case SORT_DICTIONARY: result = Blt_DictionaryCompare(s1, s2); break; case SORT_INTEGER: { int i1, i2; if (Tcl_GetInt(NULL, s1, &i1) == TCL_OK) { if (Tcl_GetInt(NULL, s2, &i2) == TCL_OK) { result = i1 - i2; } else { result = -1; } } else if (Tcl_GetInt(NULL, s2, &i2) == TCL_OK) { result = 1; } else { result = Blt_DictionaryCompare(s1, s2); } } break; case SORT_REAL: { double r1, r2; if (Tcl_GetDouble(NULL, s1, &r1) == TCL_OK) { if (Tcl_GetDouble(NULL, s2, &r2) == TCL_OK) { result = (r1 < r2) ? -1 : (r1 > r2) ? 1 : 0; } else { result = -1; } } else if (Tcl_GetDouble(NULL, s2, &r2) == TCL_OK) { result = 1; } else { result = Blt_DictionaryCompare(s1, s2); } } break; } if (result == 0) { result = Blt_Tree_NodeId(*n1Ptr) - Blt_Tree_NodeId(*n2Ptr); } if (sortData.flags & SORT_DECREASING) { result = -result; } if (sortData.flags & SORT_PATHNAME) { Tcl_DStringFree(&dString1); Tcl_DStringFree(&dString2); } return result; } /* *--------------------------------------------------------------------------- * * SortApplyProc -- * * Sorts the subnodes at a given node. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SortApplyProc( Blt_TreeNode node, ClientData clientData, int order) /* Not used. */ { TreeCmd *cmdPtr = clientData; if (!Blt_Tree_IsLeaf(node)) { Blt_Tree_SortNode(cmdPtr->tree, node, CompareNodes); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SortOp -- * *--------------------------------------------------------------------------- */ static int SortOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode top; SortSwitches switches; int result; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &top) != TCL_OK) { return TCL_ERROR; } /* Process switches */ memset(&switches, 0, sizeof(switches)); switches.cmdPtr = cmdPtr; if (Blt_ParseSwitches(interp, sortSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.command != NULL) { switches.type = SORT_COMMAND; } switches.cmdPtr = cmdPtr; sortData = switches; if (switches.mode == SORT_FLAT) { Blt_TreeNode *nodeArr; long nNodes; long i; if (switches.flags & SORT_RECURSE) { nNodes = Blt_Tree_Size(top); } else { nNodes = Blt_Tree_NodeDegree(top); } nodeArr = Blt_AssertMalloc(nNodes * sizeof(Blt_TreeNode)); if (switches.flags & SORT_RECURSE) { Blt_TreeNode node, *p; p = nodeArr; for(p = nodeArr, node = top; node != NULL; node = Blt_Tree_NextNode(top, node)) { *p++ = node; } } else { Blt_TreeNode node, *p; for (p = nodeArr, node = Blt_Tree_FirstChild(top); node != NULL; node = Blt_Tree_NextSibling(node)) { *p++ = node; } } qsort((char *)nodeArr, nNodes, sizeof(Blt_TreeNode), (QSortCompareProc *)CompareNodes); { Tcl_Obj *listObjPtr; Blt_TreeNode *p; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (p = nodeArr, i = 0; i < nNodes; i++, p++) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(*p)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_Free(nodeArr); result = TCL_OK; } else { if (switches.flags & SORT_RECURSE) { result = Blt_Tree_Apply(top, SortApplyProc, cmdPtr); } else { result = SortApplyProc(top, cmdPtr, TREE_PREORDER); } } Blt_FreeSwitches(sortSwitches, (char *)&switches, 0); return result; } /* *--------------------------------------------------------------------------- * * ValuesOp -- * * Returns the names of values for a node or array value. * *--------------------------------------------------------------------------- */ static int ValuesOp( TreeCmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node; Tcl_Obj *listObjPtr; if (GetNodeFromObj(interp, cmdPtr->tree, objv[2], &node) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 4) { char *string; string = Tcl_GetString(objv[3]); if (Blt_Tree_ArrayNames(interp, cmdPtr->tree, node, string, listObjPtr) != TCL_OK) { return TCL_ERROR; } } else { Blt_TreeKey key; Blt_TreeKeyIterator iter; for (key = Blt_Tree_FirstKey(cmdPtr->tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(cmdPtr->tree, &iter)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TreeInstObjCmd -- * * This procedure is invoked to process commands on behalf of the tree * object. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec treeOps[] = { {"ancestor", 2, AncestorOp, 4, 4, "node1 node2",}, {"apply", 1, ApplyOp, 3, 0, "node ?switches?",}, {"attach", 2, AttachOp, 3, 0, "tree ?switches?",}, {"children", 2, ChildrenOp, 3, 5, "node ?first? ?last?",}, {"copy", 2, CopyOp, 4, 0, "parent ?tree? node ?switches?",}, {"degree", 2, DegreeOp, 3, 0, "node",}, {"delete", 2, DeleteOp, 2, 0, "?node...?",}, {"depth", 3, DepthOp, 3, 3, "node",}, {"dump", 4, DumpOp, 3, 3, "node",}, {"dumpfile", 5, DumpfileOp, 4, 4, "node fileName",}, {"exists", 3, ExistsOp, 3, 4, "node ?key?",}, {"export", 3, ExportOp, 2, 0, "format ?switches?",}, {"find", 4, FindOp, 3, 0, "node ?switches?",}, {"findchild", 5, FindChildOp, 4, 4, "node label",}, {"firstchild", 3, FirstChildOp, 3, 3, "node",}, {"get", 1, GetOp, 3, 5, "node ?key? ?defaultValue?",}, {"import", 2, ImportOp, 2, 0, "format ?switches?",}, {"index", 3, IndexOp, 3, 3, "label|list",}, {"insert", 3, InsertOp, 3, 0, "parent ?switches?",}, {"is", 2, IsOp, 2, 0, "oper args...",}, {"keys", 1, KeysOp, 3, 0, "node ?node...?",}, {"label", 3, LabelOp, 3, 4, "node ?newLabel?",}, {"lastchild", 3, LastChildOp, 3, 3, "node",}, {"move", 1, MoveOp, 4, 0, "node newParent ?switches?",}, {"next", 4, NextOp, 3, 3, "node",}, {"nextsibling", 5, NextSiblingOp, 3, 3, "node",}, {"notify", 2, NotifyOp, 2, 0, "args...",}, {"parent", 3, ParentOp, 3, 3, "node",}, {"path", 3, PathOp, 3, 0, "node ?string switches?",}, {"position", 2, PositionOp, 3, 0, "?switches? node...",}, {"previous", 5, PreviousOp, 3, 3, "node",}, {"prevsibling", 5, PrevSiblingOp, 3, 3, "node",}, {"restore", 7, RestoreOp, 4, 5, "node data ?switches?",}, {"restorefile", 8, RestoreOp, 4, 5, "node fileName ?switches?",}, {"root", 2, RootOp, 2, 2, "",}, {"set", 3, SetOp, 3, 0, "node ?key value...?",}, {"size", 2, SizeOp, 3, 3, "node",}, {"sort", 2, SortOp, 3, 0, "node ?flags...?",}, {"tag", 2, TagOp, 3, 0, "args...",}, {"trace", 2, TraceOp, 2, 0, "args...",}, {"type", 2, TypeOp, 4, 4, "node key",}, {"unset", 3, UnsetOp, 3, 0, "node ?key...?",}, {"values", 1, ValuesOp, 3, 4, "node ?key?",}, }; static int nTreeOps = sizeof(treeOps) / sizeof(Blt_OpSpec); static int TreeInstObjCmd( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Vector of argument strings. */ { TreeCmdProc *proc; TreeCmd *cmdPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nTreeOps, treeOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(cmdPtr); result = (*proc) (cmdPtr, interp, objc, objv); Tcl_Release(cmdPtr); return result; } /* *--------------------------------------------------------------------------- * * TreeInstDeleteProc -- * * Deletes the command associated with the tree. This is called only * when the command associated with the tree is destroyed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void TreeInstDeleteProc(ClientData clientData) { TreeCmd *cmdPtr = clientData; ReleaseTreeObject(cmdPtr); if (cmdPtr->hashPtr != NULL) { Blt_DeleteHashEntry(cmdPtr->tablePtr, cmdPtr->hashPtr); } Blt_Chain_Destroy(cmdPtr->notifiers); Blt_DeleteHashTable(&cmdPtr->notifyTable); Blt_DeleteHashTable(&cmdPtr->traceTable); Blt_Free(cmdPtr); } /* *--------------------------------------------------------------------------- * * GenerateName -- * * Generates an unique tree command name. Tree names are in the form * "treeN", where N is a non-negative integer. Check each name generated * to see if it is already a tree. We want to recycle names if possible. * * Results: * Returns the unique name. The string itself is stored in the dynamic * string passed into the routine. * *--------------------------------------------------------------------------- */ static const char * GenerateName( Tcl_Interp *interp, const char *prefix, const char *suffix, Tcl_DString *resultPtr) { int i; const char *treeName; /* * Parse the command and put back so that it's in a consistent * format. * * t1 <current namespace>::t1 * n1::t1 <current namespace>::n1::t1 * ::t1 ::t1 * ::n1::t1 ::n1::t1 */ treeName = NULL; /* Suppress compiler warning. */ for (i = 0; i < INT_MAX; i++) { Blt_ObjectName objName; Tcl_CmdInfo cmdInfo; Tcl_DString ds; char string[200]; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, prefix, -1); sprintf_s(string, 200, "tree%d", i); Tcl_DStringAppend(&ds, string, -1); Tcl_DStringAppend(&ds, suffix, -1); if (!Blt_ParseObjectName(interp, Tcl_DStringValue(&ds), &objName, 0)) { Tcl_DStringFree(&ds); return NULL; } treeName = Blt_MakeQualifiedName(&objName, resultPtr); Tcl_DStringFree(&ds); if (Blt_Tree_Exists(interp, treeName)) { continue; /* A tree by this name already exists. */ } if (Tcl_GetCommandInfo(interp, (char *)treeName, &cmdInfo)) { continue; /* A command by this name already exists. */ } break; } return treeName; } /* *--------------------------------------------------------------------------- * * TreeCreateOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeCreateOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdInterpData *tdPtr = clientData; const char *name; Tcl_DString ds; Blt_Tree tree; name = NULL; if (objc == 3) { name = Tcl_GetString(objv[2]); } Tcl_DStringInit(&ds); if (name == NULL) { name = GenerateName(interp, "", "", &ds); } else { char *p; p = strstr(name, "#auto"); if (p != NULL) { *p = '\0'; name = GenerateName(interp, name, p + 5, &ds); *p = '#'; } else { Blt_ObjectName objName; Tcl_CmdInfo cmdInfo; /* * Parse the command and put back so that it's in a consistent * format. * * t1 <current namespace>::t1 * n1::t1 <current namespace>::n1::t1 * ::t1 ::t1 * ::n1::t1 ::n1::t1 */ if (!Blt_ParseObjectName(interp, name, &objName, 0)) { return TCL_ERROR; } name = Blt_MakeQualifiedName(&objName, &ds); /* * Check if the command already exists. */ if (Tcl_GetCommandInfo(interp, (char *)name, &cmdInfo)) { Tcl_AppendResult(interp, "a command \"", name, "\" already exists", (char *)NULL); goto error; } if (Blt_Tree_Exists(interp, name)) { Tcl_AppendResult(interp, "a tree \"", name, "\" already exists", (char *)NULL); goto error; } } } if (name == NULL) { goto error; } tree = Blt_Tree_Open(interp, name, TREE_CREATE); if (tree != NULL) { int isNew; TreeCmd *cmdPtr; cmdPtr = Blt_AssertCalloc(1, sizeof(TreeCmd)); cmdPtr->tdPtr = tdPtr; cmdPtr->tree = tree; cmdPtr->interp = interp; Blt_InitHashTable(&cmdPtr->traceTable, BLT_STRING_KEYS); Blt_InitHashTable(&cmdPtr->notifyTable, BLT_STRING_KEYS); cmdPtr->notifiers = Blt_Chain_Create(); cmdPtr->cmdToken = Tcl_CreateObjCommand(interp, (char *)name, (Tcl_ObjCmdProc *)TreeInstObjCmd, cmdPtr, TreeInstDeleteProc); cmdPtr->tablePtr = &tdPtr->treeTable; cmdPtr->hashPtr = Blt_CreateHashEntry(cmdPtr->tablePtr, (char *)cmdPtr, &isNew); Blt_SetHashValue(cmdPtr->hashPtr, cmdPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), (char *)name, -1); Tcl_DStringFree(&ds); /* * Since we store the TCL command and notifier information * on the client side, we need to also cleanup when we see a * delete event. So just register a callback for all tree events * to catch anything we need to know about. */ Blt_Tree_CreateEventHandler(cmdPtr->tree, TREE_NOTIFY_ALL, TreeEventProc, cmdPtr); return TCL_OK; } error: Tcl_DStringFree(&ds); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TreeDestroyOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeDestroyOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdInterpData *tdPtr = clientData; int i; for (i = 2; i < objc; i++) { TreeCmd *cmdPtr; char *string; string = Tcl_GetString(objv[i]); cmdPtr = GetTreeCmd(tdPtr, interp, string); if (cmdPtr == NULL) { Tcl_AppendResult(interp, "can't find a tree named \"", string, "\"", (char *)NULL); return TCL_ERROR; } Tcl_DeleteCommandFromToken(interp, cmdPtr->cmdToken); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TreeNamesOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeNamesOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeCmdInterpData *tdPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; Tcl_DString ds; Tcl_DStringInit(&ds); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&tdPtr->treeTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_ObjectName objName; TreeCmd *cmdPtr; char *qualName; Tcl_Obj *objPtr; cmdPtr = Blt_GetHashValue(hPtr); objName.name = Tcl_GetCommandName(interp, cmdPtr->cmdToken); objName.nsPtr = Blt_GetCommandNamespace(cmdPtr->cmdToken); qualName = Blt_MakeQualifiedName(&objName, &ds); if (objc == 3) { if (!Tcl_StringMatch(qualName, Tcl_GetString(objv[2]))) { continue; } } objPtr = Tcl_NewStringObj(qualName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Tcl_DStringFree(&ds); return TCL_OK; } /*ARGSUSED*/ static int TreeLoadOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; TreeCmdInterpData *dataPtr = clientData; Tcl_DString libName; char *fmt; char *safeProcName, *initProcName; int result; int length; fmt = Tcl_GetStringFromObj(objv[2], &length); hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, fmt); if (hPtr != NULL) { return TCL_OK; /* Converter for format is already loaded. */ } Tcl_DStringInit(&libName); { Tcl_DString pathName; const char *path; Tcl_DStringInit(&pathName); path = Tcl_TranslateFileName(interp, Tcl_GetString(objv[3]), &pathName); if (path == NULL) { Tcl_DStringFree(&pathName); return TCL_ERROR; } Tcl_DStringAppend(&libName, path, -1); Tcl_DStringFree(&pathName); } Tcl_DStringAppend(&libName, "/", -1); Tcl_UtfToTitle(fmt); Tcl_DStringAppend(&libName, "Tree", 4); Tcl_DStringAppend(&libName, fmt, -1); Tcl_DStringAppend(&libName, Blt_Itoa(BLT_MAJOR_VERSION), 1); Tcl_DStringAppend(&libName, Blt_Itoa(BLT_MINOR_VERSION), 1); Tcl_DStringAppend(&libName, BLT_LIB_SUFFIX, -1); Tcl_DStringAppend(&libName, BLT_SO_EXT, -1); initProcName = Blt_AssertMalloc(8 + length + 4 + 1); sprintf_s(initProcName, 8 + length + 4 + 1, "Blt_Tree%sInit", fmt); safeProcName = Blt_AssertMalloc(8 + length + 8 + 1); sprintf_s(safeProcName, 8 + length + 9 + 1, "Blt_Tree%sSafeInit", fmt); result = Blt_LoadLibrary(interp, Tcl_DStringValue(&libName), initProcName, safeProcName); Tcl_DStringFree(&libName); if (safeProcName != NULL) { Blt_Free(safeProcName); } if (initProcName != NULL) { Blt_Free(initProcName); } return result; } /* *--------------------------------------------------------------------------- * * TreeObjCmd -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec treeCmdOps[] = { {"create", 1, TreeCreateOp, 2, 3, "?name?",}, {"destroy", 1, TreeDestroyOp, 3, 0, "name...",}, {"load", 1, TreeLoadOp, 4, 4, "name libpath",}, {"names", 1, TreeNamesOp, 2, 3, "?pattern?...",}, }; static int nCmdOps = sizeof(treeCmdOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int TreeObjCmd( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nCmdOps, treeCmdOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * TreeInterpDeleteProc -- * * This is called when the interpreter hosting the "tree" command * is deleted. * * Results: * None. * * Side effects: * Removes the hash table managing all tree names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TreeInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { TreeCmdInterpData *tdPtr = clientData; /* * All tree instances should already have been destroyed when their * respective TCL commands were deleted. */ Blt_DeleteHashTable(&tdPtr->treeTable); Tcl_DeleteAssocData(interp, TREE_THREAD_KEY); Blt_Free(tdPtr); } /*ARGSUSED*/ static int CompareDictionaryCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { int result; const char *s1, *s2; s1 = Tcl_GetString(objv[1]); s2 = Tcl_GetString(objv[2]); result = Blt_DictionaryCompare(s1, s2); Tcl_SetIntObj(Tcl_GetObjResult(interp), result); return TCL_OK; } /*ARGSUSED*/ static int ExitCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { int code; if (Tcl_GetIntFromObj(interp, objv[1], &code) != TCL_OK) { return TCL_ERROR; } #ifdef TCL_THREADS Tcl_Exit(code); #else exit(code); #endif /*NOTREACHED*/ return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeCmdInitProc -- * * This procedure is invoked to initialize the "tree" command. * * Results: * None. * * Side effects: * Creates the new command and adds a new entry into a global Tcl * associative array. * *--------------------------------------------------------------------------- */ int Blt_TreeCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "tree", TreeObjCmd, }; static Blt_InitCmdSpec utilSpecs[] = { { "compare", CompareDictionaryCmd, }, { "_exit", ExitCmd, } }; if (Blt_InitCmds(interp, "::blt::util", utilSpecs, 2) != TCL_OK) { return TCL_ERROR; } cmdSpec.clientData = GetTreeCmdInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* Dump tree to dbm */ /* Convert node data to datablock */ int Blt_Tree_RegisterFormat( Tcl_Interp *interp, const char *fmt, Blt_TreeImportProc *importProc, Blt_TreeExportProc *exportProc) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TreeCmdInterpData *dataPtr; int isNew; dataPtr = GetTreeCmdInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->fmtTable, fmt, &isNew); if (isNew) { fmtPtr = Blt_AssertMalloc(sizeof(DataFormat)); fmtPtr->name = Blt_AssertStrdup(fmt); Blt_SetHashValue(hPtr, fmtPtr); } else { fmtPtr = Blt_GetHashValue(hPtr); } fmtPtr->isLoaded = TRUE; fmtPtr->importProc = importProc; fmtPtr->exportProc = exportProc; return TCL_OK; } #endif /* NO_TREE */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTabset.c�������������������������������������������������������������������0000644�0001750�0001750�00000670275�11462120063�015137� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTabset.c -- * * This module implements a tabnotebook widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_TABSET #include "bltOp.h" #include "bltBind.h" #include "bltChain.h" #include "bltFont.h" #include "bltBgStyle.h" #include "bltImage.h" #include "bltPicture.h" #include "bltPainter.h" #include "bltText.h" #include "bltHash.h" #define DEBUG0 0 #define DEBUG1 0 #define DEBUG2 1 #define INVALID_FAIL 0 #define INVALID_OK 1 #define TABWIDTH_NONE -2 #define TABWIDTH_SAME -1 #define TABWIDTH_VARIABLE 0 #define PHOTO_ICON 1 #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define SWAP(a,b) { int tmp; tmp = (a), (a) = (b), (b) = tmp; } #define GAP 1 #define SELECT_PADX 4 #define SELECT_PADY 2 #define OUTER_PAD 0 #define LABEL_PAD 4 #define CORNER_OFFSET 3 #define CLOSE_WIDTH 16 #define CLOSE_HEIGHT 16 #define TAB_SCROLL_OFFSET 10 #define END (-1) #define ODD(x) ((x) | 0x01) #define SIDE_LEFT (1<<0) #define SIDE_TOP (1<<1) #define SIDE_RIGHT (1<<2) #define SIDE_BOTTOM (1<<3) #define VPORTWIDTH(b) \ ((((b)->side) & (SIDE_TOP|SIDE_BOTTOM)) ? \ (Tk_Width((b)->tkwin) - 2 * (b)->inset) : \ (Tk_Height((b)->tkwin) - 2 * (b)->inset)) #define VPORTHEIGHT(b) \ ((((b)->side) & (SIDE_LEFT|SIDE_RIGHT)) ? \ (Tk_Width((b)->tkwin) - 2 * (b)->inset) : \ (Tk_Height((b)->tkwin) - 2 * (b)->inset)) #define GETATTR(t,attr) \ (((t)->attr != NULL) ? (t)->attr : (t)->setPtr->defStyle.attr) /* *--------------------------------------------------------------------------- * * Internal widget flags: * * LAYOUT_PENDING The layout of the widget needs to be recomputed. * * REDRAW_PENDING A redraw request is pending for the widget. * * SCROLL_PENDING A scroll request is pending. * * FOCUS The widget is receiving keyboard events. * Draw the focus highlight border around the widget. * * MULTIPLE_TIER Tabset is using multiple tiers. * * SCROLLING Tabset has enough tabs to be scrolled. * * SCROLL_TABS Scroll tabs if there are enough tabs to be scrolled. * * SHOW_SINGLE_TAB Display window in a tab even if only one tab. * * CLOSE_NEEDED Include a "x" button on each tab that automatically * closes the tab. * *--------------------------------------------------------------------------- */ #define LAYOUT_PENDING (1<<0) /* Indicates the tabset has been * changed so that it geometry needs * to be recalculated before its * redrawn. */ #define REDRAW_PENDING (1<<1) /* Indicates the tabset needs to be * redrawn at the next idle point. */ #define SCROLL_PENDING (1<<2) /* Indicates a scroll request that */ #define FOCUS (1<<3) /* Indicates the tabset/tab has * focus. */ #define TEAROFF (1<<4) /* Indicates if the perforation should * be drawn (see -tearoff). */ #define SCROLLING (1<<5) #define MULTIPLE_TIER (1<<6) /* Indicates the tabset is using * multiple tiers of tabs. */ #define ACTIVE_PERFORATION (1<<7) /* Indicates if the perforation should * should be drawn with active * colors. */ #define REDRAW_ALL (1<<9) /* Draw the entire tabset including * the folder. If not set, indicates * that only the tabs need to be drawn * (activate, deactivate, scroll, * etc). This avoids drawing the * folder again. */ #define SLANT_NONE 0 #define SLANT_LEFT (1<<10) #define SLANT_RIGHT (1<<11) #define SLANT_BOTH (SLANT_LEFT | SLANT_RIGHT) #define CLOSE_NEEDED (1<<13) /* Draw a close button on each tab. */ #define SHOW_SINGLE_TAB (1<<14) /* Display window in a tab even if * there is only one tab displayed. */ #define SCROLL_TABS (1<<15) /* Allow tabs to be scrolled if * needed. Otherwise tab sizes will * shrink to fit the space. */ #define TAB_LABEL (ClientData)0 #define TAB_PERFORATION (ClientData)1 #define TAB_BUTTON (ClientData)2 #ifdef notdef #define DEF_ACTIVEBACKGROUND RBG_GREY85 #define DEF_ACTIVEFOREGROUND STD_ACTIVE_FOREGROUND #else #define DEF_ACTIVEBACKGROUND RGB_SKYBLUE4 #define DEF_ACTIVEFOREGROUND RGB_WHITE #endif #define DEF_BACKGROUND RGB_GREY77 #define DEF_BORDERWIDTH "0" #define DEF_COMMAND (char *)NULL #define DEF_CURSOR (char *)NULL #define DEF_DASHES "1" #define DEF_FONT STD_FONT_SMALL #define DEF_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_GAP "1" #define DEF_HEIGHT "0" #define DEF_HIGHLIGHTBACKGROUND STD_NORMAL_BACKGROUND #define DEF_HIGHLIGHTCOLOR RGB_BLACK #define DEF_HIGHLIGHTTHICKNESS "0" #define DEF_JUSTIFY "center" #define DEF_OUTERPAD "0" #define DEF_PAGEHEIGHT "0" #define DEF_PAGEWIDTH "0" #define DEF_RELIEF "flat" #define DEF_ROTATE "0.0" #define DEF_SCROLLINCREMENT "0" #define DEF_SCROLLTABS "0" #define DEF_SELECTBACKGROUND STD_NORMAL_BACKGROUND #define DEF_SELECTBORDERWIDTH "1" #define DEF_SELECTCOMMAND (char *)NULL #define DEF_CLOSECOMMAND (char *)NULL #define DEF_SELECTFOREGROUND RGB_BLACK #define DEF_SELECTMODE "multiple" #define DEF_SELECTPADX "4" #define DEF_SELECTPADY "2" #define DEF_SELECTRELIEF "raised" #define DEF_SHADOWCOLOR RGB_BLACK #define DEF_CLOSEBUTTON "0" #define DEF_SHOWSINGLETAB "1" #define DEF_SIDE "top" #define DEF_SLANT "none" #define DEF_TABRELIEF "raised" #define DEF_TABWIDTH "same" #define DEF_TAKEFOCUS "1" #define DEF_TEAROFF "no" #define DEF_ICONPOSITION "left" #define DEF_TIERS "1" #define DEF_TROUGHCOLOR "grey60" #define DEF_WIDTH "0" #define DEF_CLOSEBUTTON_ACTIVEBACKGROUND RGB_RED #define DEF_CLOSEBUTTON_ACTIVEFOREGROUND RGB_WHITE #define DEF_CLOSEBUTTON_ACTIVERELIEF "raised" #define DEF_CLOSEBUTTON_BACKGROUND RGB_GREY70 #define DEF_CLOSEBUTTON_BORDERWIDTH "0" #define DEF_CLOSEBUTTON_COMMAND (char *)NULL #define DEF_CLOSEBUTTON_FOREGROUND RGB_GREY95 #define DEF_CLOSEBUTTON_RELIEF "flat" #define DEF_TAB_ACTIVEBACKGROUND (char *)NULL #define DEF_TAB_ACTIVEFOREGROUND (char *)NULL #define DEF_TAB_ANCHOR "center" #define DEF_TAB_BACKGROUND (char *)NULL #define DEF_TAB_BORDERWIDTH "1" #define DEF_TAB_BUTTON (char *)NULL #define DEF_TAB_CLOSEBUTTON "1" #define DEF_TAB_COMMAND (char *)NULL #define DEF_TAB_DATA (char *)NULL #define DEF_TAB_FILL "none" #define DEF_TAB_FONT (char *)NULL #define DEF_TAB_FOREGROUND (char *)NULL #define DEF_TAB_HEIGHT "0" #define DEF_TAB_HIDE "no" #define DEF_TAB_IMAGE (char *)NULL #define DEF_TAB_IPAD "0" #define DEF_TAB_PAD "3" #define DEF_TAB_PERFORATIONCOMMAND (char *)NULL #define DEF_TAB_SELECTBACKGROUND (char *)NULL #define DEF_TAB_SELECTBORDERWIDTH "1" #define DEF_TAB_SELECTCOMMAND (char *)NULL #define DEF_TAB_SELECTFOREGROUND (char *)NULL #define DEF_TAB_STATE "normal" #define DEF_TAB_STIPPLE "BLT" #define DEF_TAB_TEXT (char *)NULL #define DEF_TAB_VISUAL (char *)NULL #define DEF_TAB_WIDTH "0" #define DEF_TAB_WINDOW (char *)NULL #define DEF_TAB_WINDOWHEIGHT "0" #define DEF_TAB_WINDOWWIDTH "0" typedef struct _Tabset Tabset; static Tk_GeomRequestProc EmbeddedWidgetGeometryProc; static Tk_GeomLostSlaveProc EmbeddedWidgetCustodyProc; static Tk_GeomMgr tabMgrInfo = { (char *)"tabset", /* Name of geometry manager used by * winfo */ EmbeddedWidgetGeometryProc, /* Procedure to for new geometry * requests */ EmbeddedWidgetCustodyProc, /* Procedure when window is taken away */ }; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToChildProc; static Blt_OptionPrintProc ChildToObjProc; static Blt_OptionParseProc ObjToSlantProc; static Blt_OptionPrintProc SlantToObjProc; static Blt_OptionParseProc ObjToTabWidthProc; static Blt_OptionPrintProc TabWidthToObjProc; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; /* * Contains a pointer to the widget that's currently being configured. This * is used in the custom configuration parse routine for icons. */ static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0, }; static Blt_CustomOption childOption = { ObjToChildProc, ChildToObjProc, NULL, (ClientData)0, }; static Blt_CustomOption slantOption = { ObjToSlantProc, SlantToObjProc, NULL, (ClientData)0, }; static Blt_CustomOption tabWidthOption = { ObjToTabWidthProc, TabWidthToObjProc, NULL, (ClientData)0, }; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; typedef struct { short int x, y; /* Location of region. */ short int w, h; /* Dimensions of region. */ } GadgetRegion; /* * Icon -- * * When multiple instances of an image are displayed in the same widget, * this can be inefficient in terms of both memory and time. We only * need one instance of each image, regardless of number of times we use * it. And searching/deleting instances can be very slow as the list * gets large. * * The workaround, employed below, is to maintain a hash table of images * that maintains a reference count for each image. */ typedef struct _Icon { Blt_HashEntry *hashPtr; /* Hash table pointer to the image. */ Tk_Image tkImage; /* The Tk image being cached. */ Blt_Picture picture; float angle; short int width, height; /* Dimensions of the cached image. */ int refCount; /* Reference counter for this image. */ } *Icon; #define IconHeight(i) (((i) == NULL) ? 0 : (i)->height) #define IconWidth(i) (((i) == NULL) ? 0 : (i)->width) #define IconBits(i) ((i)->tkImage) /* * Button -- */ typedef struct { int borderWidth; /* Width of 3D border around this * button. */ int pad; /* Amount of extra padding around * the button. */ int relief; /* 3D relief of button. */ int activeRelief; /* 3D relief when the button is * active. */ XColor *normalFg; /* Foreground color of the button when * the button is inactive. */ XColor *normalBg; /* Background color of the button when * the button is inactive. */ XColor *activeFg; /* Foreground color of the button * when the button is active. */ XColor *activeBg; /* Background color of the button * when the button is active. */ Tcl_Obj *cmdObjPtr; /* Command to be executed when the the * button is invoked. */ Blt_Picture normal0; /* Contains the image to be displayed * when the button is inactive at 0 * degrees rotation. */ Blt_Picture active0; /* Contains the image to be displayed * when the button is active at 0 * degreees rotation. */ Blt_Picture normal; /* Contains the image to be displayed * when the button is inactive at 0 * degrees rotation. */ Blt_Picture active; /* Contains the image to be displayed * when the button is active at 0 * degreees rotation. */ short int width, height; /* The dimensions of the button. */ } Button; static Blt_ConfigSpec buttonSpecs[] = { {BLT_CONFIG_COLOR, "-activebackground", "activeBackrgound", "ActiveBackground", DEF_CLOSEBUTTON_ACTIVEBACKGROUND, Blt_Offset(Button, activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForergound", "ActiveForeground", DEF_CLOSEBUTTON_ACTIVEFOREGROUND, Blt_Offset(Button, activeFg), 0}, {BLT_CONFIG_COLOR, "-background", "backrgound", "Background", DEF_CLOSEBUTTON_BACKGROUND, Blt_Offset(Button, normalBg), 0}, {BLT_CONFIG_COLOR, "-foreground", "forergound", "Foreground", DEF_CLOSEBUTTON_FOREGROUND, Blt_Offset(Button, normalFg), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "ActiveRelief", DEF_CLOSEBUTTON_ACTIVERELIEF, Blt_Offset(Button, activeRelief), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_CLOSEBUTTON_BORDERWIDTH, Blt_Offset(Button, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_CLOSEBUTTON_RELIEF, Blt_Offset(Button, relief), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; #define NORMAL (0) #define ACTIVE (1<<0) #define DISABLED (1<<1) #define HIDE (1<<2) #define STATE_MASK (ACTIVE|DISABLED|HIDE) #define ONSCREEN (1<<3) #define TEAROFF_REDRAW (1<<4) typedef struct { const char *name; /* Identifier for tab. */ Blt_HashEntry *hashPtr; int index; /* Index of the tab. */ unsigned int flags; int tier; /* Index of tier [1..numTiers] * containing this tab. */ int worldX, worldY; /* Position of tab in world * coordinates. */ int worldWidth, worldHeight; /* Dimensions of the tab at 0 degree * rotation. It includes the * * border, padding, label, etc. */ int screenX, screenY; /* Location of tab on screen. */ int screenWidth; int screenHeight; /* */ Tabset *setPtr; /* Tabset that includes this * tab. Needed for callbacks can pass * only a tab pointer. */ /* * Tab label: */ const char *text; /* String displayed as the tab's * label. */ TextLayout *layoutPtr; Icon icon; /* Icon displayed as the label. */ /* Dimensions of the tab label, corrected for side. */ short int rotWidth, rotHeight; short int textWidth0, textHeight0; short int labelWidth0, labelHeight0; Blt_Pad iPadX, iPadY; /* Internal padding around the text */ Blt_Font font; /* * Normal: */ XColor *textColor; /* Text color */ Blt_Background bg; /* Background color and border for * tab. */ /* * Selected: Tab is currently selected. */ XColor *selColor; /* Selected text color */ Blt_Background selBg; /* 3D border of selected folder. */ /* * Active: Mouse passes over the tab. */ Blt_Background activeBg; /* Active background color. */ XColor *activeFg; /* Active text color */ Pixmap stipple; /* Stipple for outline of embedded * window when torn off. */ /* * Embedded widget information: */ Tk_Window tkwin; /* Widget to be mapped when the tab is * selected. If NULL, don't make * space for the page. */ int reqSlaveWidth, reqSlaveHeight; /* If non-zero, overrides the * requested dimensions of the * embedded widget. */ Tk_Window container; /* The window containing the embedded * widget. Does not necessarily have * to be the parent. */ Tk_Anchor anchor; /* Anchor: indicates how the embedded * widget is positioned within the * extra space on the page. */ Blt_Pad xPad, yPad; /* Padding around embedded widget. */ int fill; /* Indicates how the window should * fill the page. */ /* * Auxillary information: */ Tcl_Obj *cmdObjPtr; /* Command invoked when the tab is * selected */ const char *data; /* This value isn't used in C code. * It may be used by clients in Tcl * bindings * to associate extra data * (other than the * label or name) * with the tab. */ Tcl_Obj *closeObjPtr; /* Command to be executed when the tab * is closed. */ Blt_ChainLink link; /* Pointer to where the tab resides in * the list of tabs. */ Tcl_Obj *perfCmdObjPtr; /* Command invoked when the tab is * selected */ GC textGC; GC backGC; /* Gadget positions and locations: */ GadgetRegion buttonRegion; GadgetRegion textRegion; GadgetRegion iconRegion; GadgetRegion focusRegion; } Tab; static Blt_ConfigSpec tabSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_TAB_ACTIVEBACKGROUND, Blt_Offset(Tab, activeBg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_TAB_ACTIVEFOREGROUND, Blt_Offset(Tab, activeFg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_TAB_ANCHOR, Blt_Offset(Tab, anchor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", (char *)NULL, Blt_Offset(Tab, bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BITMASK, "-closebutton", "closeButton", "CloseButton", DEF_TAB_CLOSEBUTTON, Blt_Offset(Tab, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)CLOSE_NEEDED}, {BLT_CONFIG_OBJ, "-closecommand", "closeCommand", "CloseCommand", DEF_CLOSECOMMAND, Blt_Offset(Tab, closeObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_TAB_COMMAND, Blt_Offset(Tab, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-data", "data", "data", DEF_TAB_DATA, Blt_Offset(Tab, data), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FILL, "-fill", "fill", "Fill", DEF_TAB_FILL, Blt_Offset(Tab, fill), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", (char *)NULL, Blt_Offset(Tab, textColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FONT, "-font", "font", "Font", (char *)NULL, Blt_Offset(Tab, font), 0}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", DEF_TAB_IMAGE, Blt_Offset(Tab, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_PAD, "-ipadx", "iPadX", "PadX", DEF_TAB_IPAD, Blt_Offset(Tab, iPadX), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-ipady", "iPadY", "PadY", DEF_TAB_IPAD, Blt_Offset(Tab, iPadY), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-padx", "padX", "PadX", DEF_TAB_PAD, Blt_Offset(Tab, xPad), 0}, {BLT_CONFIG_PAD, "-pady", "padY", "PadY", DEF_TAB_PAD, Blt_Offset(Tab, yPad), 0}, {BLT_CONFIG_OBJ, "-perforationcommand", "perforationcommand", "PerforationCommand", DEF_TAB_PERFORATIONCOMMAND, Blt_Offset(Tab, perfCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Background", DEF_TAB_SELECTBACKGROUND, Blt_Offset(Tab, selBg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_TAB_SELECTFOREGROUND, Blt_Offset(Tab, selColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-state", "state", "State", DEF_TAB_STATE, Blt_Offset(Tab, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_TAB_STIPPLE, Blt_Offset(Tab, stipple), 0}, {BLT_CONFIG_STRING, "-text", "Text", "Text", DEF_TAB_TEXT, Blt_Offset(Tab, text), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-window", "window", "Window", DEF_TAB_WINDOW, Blt_Offset(Tab, tkwin), BLT_CONFIG_NULL_OK, &childOption}, {BLT_CONFIG_PIXELS_NNEG, "-windowheight", "windowHeight", "WindowHeight", DEF_TAB_WINDOWHEIGHT, Blt_Offset(Tab, reqSlaveHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-windowwidth", "windowWidth", "WindowWidth", DEF_TAB_WINDOWWIDTH, Blt_Offset(Tab, reqSlaveWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * TabStyle -- */ typedef struct { Tk_Window tkwin; /* Default window to map pages. */ int borderWidth; /* Width of 3D border around the tab's * label. */ int pad; /* Extra padding of a tab entry */ Blt_Font font; XColor *textColor; Blt_Background bg; /* Normal background. */ XColor *selColor; /* Selected foreground. */ Blt_Background selBg; /* Selected background. */ Blt_Background activeBg; /* Active background. */ XColor *activeFg; /* Active foreground. */ Blt_Dashes dashes; GC activeGC; int relief; Tcl_Obj *cmdObjPtr; /* Command invoked when the tab is * selected */ Tcl_Obj *perfCmdObjPtr; } TabStyle; struct _Tabset { Tk_Window tkwin; /* Window that embodies the widget. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up.*/ Display *display; /* Display containing widget; needed, * among other things, to release * resources after tkwin has already * gone away. */ Tcl_Interp *interp; /* Interpreter associated with * widget. */ Tcl_Command cmdToken; /* Token for widget's command. */ unsigned int flags; /* For bitfield definitions, see * below */ short int inset; /* Total width of all borders, * including traversal highlight and * 3-D border. Indicates how much * interior stuff must be offset from * outside edges to leave room for * borders. */ short int inset2; /* Total width of 3-D folder border + * corner, Indicates how much interior * stuff must be offset from outside * edges of folder.*/ short int ySelectPad2; /* Extra offset for selected tab. Only * for single tiers. */ short int pageTop; /* Offset from top of tabset to the * start of the page. */ short int xOffset, yOffset; /* Offset of pixmap buffer to top of * window. */ Blt_Painter painter; Tk_Cursor cursor; /* X Cursor */ Blt_Background bg; /* 3D border surrounding the * window. */ int borderWidth; /* Width of 3D border. */ int relief; /* 3D border relief. */ XColor *shadowColor; /* Shadow color around folder. */ int justify; int iconPos; float angle; /* Angle to rotate tab. This includes * the icon, text, and close * buttons. The tab can only be rotated * at right angles: 0, 90, 180, 270, * etc. */ int quad; /* * Focus highlight ring */ int highlightWidth; /* Width in pixels of highlight to * draw around widget when it has the * focus. <= 0 means don't draw a * highlight. */ XColor *highlightBg; /* Color for drawing traversal * highlight area when highlight is * off. */ XColor *highlightColor; /* Color for drawing traversal * highlight. */ GC highlightGC; /* GC for focus highlight. */ const char *takeFocus; /* Says whether to select this widget * during tab traveral operations. * This value isn't used in C code, * but for the widget's Tcl * bindings. */ int side; /* Orientation of the tabset: either * SIDE_LEFT, SIDE_RIGHT, SIDE_TOP, or * SIDE_BOTTOM. */ int reqSlant; /* Determines slant on either side * of tab. */ int overlap; /* Amount of */ int gap; int reqTabWidth; /* Requested tab size. */ short int tabWidth, tabHeight; int xSelectPad, ySelectPad; /* Padding around label of the * selected tab. */ int outerPad; /* Padding around the exterior of the * tabset and folder. */ Button closeButton; /* Close tab button drawn on right * side of a tab. */ Tcl_Obj *closeObjPtr; /* Command to be executed when the tab * is closed. */ TabStyle defStyle; /* Global attribute information * specific to tabs. */ int reqWidth, reqHeight; /* Requested dimensions of the tabset * window. */ int pageWidth, pageHeight; /* Dimensions of a page in the * folder. */ int reqPageWidth, reqPageHeight; /* Requested dimensions of a page. */ int lastX, lastY; /* * Scrolling information: */ int worldWidth; int scrollOffset; /* Offset of viewport in world * coordinates. */ Tcl_Obj *scrollCmdObjPtr; /* Command strings to control * scrollbar.*/ int scrollUnits; /* Smallest unit of scrolling for * tabs. */ /* * Scanning information: */ int scanAnchor; /* Scan anchor in screen coordinates. */ int scanOffset; /* Offset of the start of the scan in * world coordinates.*/ int corner; /* Number of pixels to offset next * point when drawing corners of the * folder. */ int reqTiers; /* Requested number of tiers. Zero * means to dynamically scroll if * there are * too many tabs to be * display on a single * tier. */ int nTiers; /* Actual number of tiers. */ Blt_HashTable iconTable; Tab *plusPtr; /* Special tab always at end of tab * set. */ Tab *selectPtr; /* The currently selected tab. * (i.e. its page is displayed). */ Tab *activePtr; /* Tab last located under the pointer. * It is displayed with its active * foreground / background * colors. */ Tab *activeButtonPtr; /* Tab where to pointer is located * over the close button. The button * is displayed with its active * foreground / background colors. */ Tab *focusPtr; /* Tab currently receiving focus. */ Tab *startPtr; /* The first tab on the first tier. */ Blt_Chain chain; /* List of tab entries. Used to * arrange placement of tabs. */ Blt_HashTable tabTable; /* Hash table of tab entries. Used for * lookups of tabs by name. */ int nextId; int nVisible; /* Number of tabs that are currently * visible in the view port. */ Blt_BindTable bindTable; /* Tab binding information */ Blt_HashTable tagTable; /* Table of tags. */ Blt_HashTable bindTagTable; /* Table of binding tags. */ }; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "activeBackground", DEF_ACTIVEBACKGROUND, Blt_Offset(Tabset, defStyle.activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "activeForeground", DEF_ACTIVEFOREGROUND, Blt_Offset(Tabset, defStyle.activeFg), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BACKGROUND, Blt_Offset(Tabset, defStyle.bg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(Tabset, defStyle.borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-closebutton", "closeButton", "CloseButton", DEF_CLOSEBUTTON, Blt_Offset(Tabset, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)CLOSE_NEEDED}, {BLT_CONFIG_OBJ, "-closecommand", "closeCommand", "CloseCommand", DEF_CLOSECOMMAND, Blt_Offset(Tabset, closeObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(Tabset, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_DASHES, Blt_Offset(Tabset, defStyle.dashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_FOREGROUND, Blt_Offset(Tabset, defStyle.textColor), 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_FONT, Blt_Offset(Tabset, defStyle.font), 0}, {BLT_CONFIG_PIXELS_NNEG, "-gap", "gap", "Gap", DEF_GAP, Blt_Offset(Tabset, gap), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(Tabset, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HIGHLIGHTBACKGROUND, Blt_Offset(Tabset, highlightBg), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHTCOLOR, Blt_Offset(Tabset, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHTTHICKNESS, Blt_Offset(Tabset, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SIDE, "-iconposition", "iconPosition", "IconPosition", DEF_ICONPOSITION, Blt_Offset(Tabset, iconPos), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_JUSTIFY, "-justify", "Justify", "Justify", DEF_JUSTIFY, Blt_Offset(Tabset, justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-outerborderwidth", "outerBorderWidth", "OuterBorderWidth", DEF_BORDERWIDTH, Blt_Offset(Tabset, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-outerpad", "outerPad", "OuterPad", DEF_OUTERPAD, Blt_Offset(Tabset, outerPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-outerrelief", "outerRelief", "OuterRelief", DEF_RELIEF, Blt_Offset(Tabset, relief), 0}, {BLT_CONFIG_PIXELS_NNEG, "-pageheight", "pageHeight", "PageHeight", DEF_PAGEHEIGHT, Blt_Offset(Tabset, reqPageHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-pagewidth", "pageWidth", "PageWidth", DEF_PAGEWIDTH, Blt_Offset(Tabset, reqPageWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-perforationcommand", "perforationcommand", "PerforationCommand", DEF_TAB_PERFORATIONCOMMAND, Blt_Offset(Tabset, defStyle.perfCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_TABRELIEF, Blt_Offset(Tabset, defStyle.relief), 0}, {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_ROTATE, Blt_Offset(Tabset, angle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-tabwidth", "tabWidth", "TabWidth", DEF_TABWIDTH, Blt_Offset(Tabset, reqTabWidth), BLT_CONFIG_DONT_SET_DEFAULT, &tabWidthOption}, {BLT_CONFIG_OBJ, "-scrollcommand", "scrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(Tabset, scrollCmdObjPtr),BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-scrollincrement", "scrollIncrement", "ScrollIncrement", DEF_SCROLLINCREMENT, Blt_Offset(Tabset, scrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-scrolltabs", "scrollTabs", "ScrollTabs", DEF_SCROLLTABS, Blt_Offset(Tabset, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SCROLL_TABS}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", DEF_SELECTBACKGROUND, Blt_Offset(Tabset, defStyle.selBg), 0}, {BLT_CONFIG_OBJ, "-selectcommand", "selectCommand", "SelectCommand", DEF_SELECTCOMMAND, Blt_Offset(Tabset, defStyle.cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_SELECTFOREGROUND, Blt_Offset(Tabset, defStyle.selColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-selectpadx", "selectPadX", "SelectPadX", DEF_SELECTPADX, Blt_Offset(Tabset, xSelectPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-selectpady", "selectPad", "SelectPad", DEF_SELECTPADY, Blt_Offset(Tabset, ySelectPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-shadowcolor", "shadowColor", "ShadowColor", DEF_SHADOWCOLOR, Blt_Offset(Tabset, shadowColor), 0}, {BLT_CONFIG_BITMASK, "-showsingletab", "showSingleTab", "ShowSingleTab", DEF_SHOWSINGLETAB, Blt_Offset(Tabset, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SHOW_SINGLE_TAB}, {BLT_CONFIG_SIDE, "-side", "side", "side", DEF_SIDE, Blt_Offset(Tabset, side), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-slant", "slant", "Slant", DEF_SLANT, Blt_Offset(Tabset, reqSlant), BLT_CONFIG_DONT_SET_DEFAULT, &slantOption}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKEFOCUS, Blt_Offset(Tabset, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-tearoff", "tearoff", "Tearoff", DEF_TEAROFF, Blt_Offset(Tabset, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TEAROFF}, {BLT_CONFIG_INT_POS, "-tiers", "tiers", "Tiers", DEF_TIERS, Blt_Offset(Tabset, reqTiers), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-troughcolor", "troughColor", "TroughColor", DEF_TROUGHCOLOR, Blt_Offset(Tabset, bg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Tabset, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * TabIterator -- * * Tabs may be tagged with strings. A tab may have many tags. The * same tag may be used for many tabs. * */ typedef enum { ITER_SINGLE, ITER_ALL, ITER_TAG, ITER_PATTERN, } IteratorType; typedef struct _Iterator { Tabset *setPtr; /* Tabset that we're iterating over. */ IteratorType type; /* Type of iteration: * ITER_TAG By item tag. * ITER_ALL By every item. * ITER_SINGLE Single item: either * tag or index. * ITER_PATTERN Over a consecutive * range of indices. */ Tab *startPtr; /* Starting item. Starting point of * search, saved if iterator is reused. * Used for ITER_ALL and ITER_SINGLE * searches. */ Tab *endPtr; /* Ending item (inclusive). */ Tab *nextPtr; /* Next item. */ /* For tag-based searches. */ char *tagName; /* If non-NULL, is the tag that we are * currently iterating over. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Search iterator for tag hash * table. */ Blt_ChainLink link; } TabIterator; /* Forward Declarations */ static Blt_BindPickProc PickTabProc; static Blt_BindTagProc GetTagsProc; static Tcl_CmdDeleteProc TabsetInstDeletedCmd; static Tcl_FreeProc DestroyTabset; static Tcl_FreeProc DestroyTearoff; static Tcl_IdleProc AdoptWindow; static Tcl_IdleProc DisplayTabset; static Tcl_IdleProc DisplayTearoff; static Tcl_ObjCmdProc TabsetCmd; static Tcl_ObjCmdProc TabsetInstCmd; static Tk_EventProc EmbeddedWidgetEventProc; static Tk_EventProc TabsetEventProc; static Tk_EventProc TearoffEventProc; static Tk_ImageChangedProc IconChangedProc; static void DrawLabel(Tabset *setPtr, Tab *tabPtr, Drawable drawable); static void DrawFolder(Tabset *setPtr, Tab *tabPtr, Drawable drawable); static void GetWindowRectangle(Tab *tabPtr, Tk_Window parent, int hasTearOff, XRectangle *rectPtr); static void ArrangeWindow(Tk_Window tkwin, XRectangle *rectPtr, int force); static void EventuallyRedraw(Tabset *setPtr); static void EventuallyRedrawTearoff(Tab *tabPtr); static void ComputeLayout(Tabset *setPtr); static void DrawOuterBorders(Tabset *setPtr, Drawable drawable); static int GetTabIterator(Tcl_Interp *interp, Tabset *setPtr, Tcl_Obj *objPtr, TabIterator *iterPtr); static int GetTabFromObj(Tcl_Interp *interp, Tabset *setPtr, Tcl_Obj *objPtr, Tab **tabPtrPtr); static void ComputeLabelOffsets(Tabset *setPtr, Tab *tabPtr); typedef int (TabsetCmdProc)(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * WorldToScreen -- * * Converts world coordinates to screen coordinates. Note that the world * view is always tabs side top. * * Results: * The screen coordinates are returned via *xScreenPtr and *yScreenPtr. * *--------------------------------------------------------------------------- */ static void WorldToScreen(Tabset *setPtr, int x, int y, int *xScreenPtr, int *yScreenPtr) { int sx, sy; sx = sy = 0; /* Suppress compiler warning. */ /* Translate world X-Y to screen coordinates */ /* * Note that the world X-coordinate is translated by the selected label's * X padding. This is done only to keep the scroll range is between 0.0 * and 1.0, rather adding/subtracting the pad in various locations. It * may be changed back in the future. */ x += setPtr->inset + setPtr->xSelectPad - setPtr->scrollOffset; y += setPtr->inset; if (setPtr->nTiers == 1) { y += setPtr->ySelectPad; } switch (setPtr->side) { case SIDE_TOP: sx = x, sy = y; /* Do nothing */ break; case SIDE_RIGHT: sx = Tk_Width(setPtr->tkwin) - y; sy = x; break; case SIDE_LEFT: sy = x; sx = y; /* Flip coordinates */ break; case SIDE_BOTTOM: sx = x; sy = Tk_Height(setPtr->tkwin) - y; break; } *xScreenPtr = sx; *yScreenPtr = sy; } /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Tabset *setPtr) { if ((setPtr->tkwin != NULL) && !(setPtr->flags & REDRAW_PENDING)) { setPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayTabset, setPtr); } } /* *--------------------------------------------------------------------------- * * EventuallyRedrawTearoff -- * * Queues a request to redraw the tearoff at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawTearoff(Tab *tabPtr) { if ((tabPtr->tkwin != NULL) && !(tabPtr->flags & TEAROFF_REDRAW)) { tabPtr->flags |= TEAROFF_REDRAW; Tcl_DoWhenIdle(DisplayTearoff, tabPtr); } } static void FreeIcon(Tabset *setPtr, struct _Icon *iconPtr) { iconPtr->refCount--; if (iconPtr->refCount == 0) { Blt_DeleteHashEntry(&setPtr->iconTable, iconPtr->hashPtr); Tk_FreeImage(iconPtr->tkImage); if (iconPtr->picture != NULL) { Blt_FreePicture(iconPtr->picture); } Blt_Free(iconPtr); } } /* *--------------------------------------------------------------------------- * * IconChangedProc * * This routine is called whenever an image displayed in a tab changes. * In this case, we assume that everything will change and queue a * request to re-layout and redraw the entire tabset. * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, /* Not used. */ int width, int height, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Tabset *setPtr = clientData; setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * GetIcon -- * * This is a wrapper procedure for Tk_GetImage. The problem is that if * the same image is used repeatedly in the same widget, the separate * instances are saved in a linked list. This makes it especially slow * to destroy the widget. As a workaround, this routine hashes the image * and maintains a reference count for it. * * Results: * Returns a pointer to the new image. * *--------------------------------------------------------------------------- */ static Icon GetIcon(Tabset *setPtr, Tcl_Interp *interp, Tk_Window tkwin, const char *name) { struct _Icon *iconPtr; int isNew; Blt_HashEntry *hPtr; hPtr = Blt_CreateHashEntry(&setPtr->iconTable, name, &isNew); if (isNew) { Tk_Image tkImage; int width, height; Blt_Picture picture; tkImage = Tk_GetImage(interp, tkwin, name, IconChangedProc, setPtr); if (tkImage == NULL) { Blt_DeleteHashEntry(&setPtr->iconTable, hPtr); return NULL; } Tk_SizeOfImage(tkImage, &width, &height); iconPtr = Blt_AssertMalloc(sizeof(struct _Icon)); iconPtr->tkImage = tkImage; iconPtr->hashPtr = hPtr; iconPtr->refCount = 1; iconPtr->width = width; iconPtr->height = height; iconPtr->picture = picture; iconPtr->angle = 0.0; iconPtr->picture = NULL; Blt_SetHashValue(hPtr, iconPtr); } else { iconPtr = Blt_GetHashValue(hPtr); iconPtr->refCount++; } return iconPtr; } /* *--------------------------------------------------------------------------- * * FreeIconProc -- * * Releases the image if it's not being used anymore by this widget. * Note there may be several uses of the same image by many tabs. * * Results: * None. * * Side Effects: * The reference count is decremented and the image is freed is it's not * being used anymore. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeIconProc(ClientData clientData, Display *display, char *widgRec, int offset) { Icon *iconPtr = (Icon *)(widgRec + offset); Tabset *setPtr = clientData; if (*iconPtr != NULL) { FreeIcon(setPtr, *iconPtr); *iconPtr = NULL; } } static Blt_HashTable * GetTagTable(Tabset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&setPtr->tagTable, tagName); if (hPtr == NULL) { return NULL; /* No tag by name. */ } return Blt_GetHashValue(hPtr); } static int HasTag(Tab *tabPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; if (strcmp(tagName, "all") == 0) { return TRUE; } tablePtr = GetTagTable(tabPtr->setPtr, tagName); if (tablePtr == NULL) { return FALSE; } hPtr = Blt_FindHashEntry(tablePtr, (char *)tabPtr); if (hPtr == NULL) { return FALSE; } return TRUE; } static Blt_HashTable * AddTagTable(Tabset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; int isNew; hPtr = Blt_CreateHashEntry(&setPtr->tagTable, tagName, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } return tablePtr; } static void AddTag(Tabset *setPtr, Tab *tabPtr, const char *tagName) { int isNew; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; tablePtr = AddTagTable(setPtr, tagName); hPtr = Blt_CreateHashEntry(tablePtr, (char *)tabPtr, &isNew); if (isNew) { Blt_SetHashValue(hPtr, tabPtr); } } static void ForgetTag(Tabset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; if (strcmp(tagName, "all") == 0) { return; /* Can't remove tag "all". */ } hPtr = Blt_FindHashEntry(&setPtr->tagTable, tagName); if (hPtr == NULL) { return; /* No tag by name. */ } tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); Blt_DeleteHashEntry(&setPtr->tagTable, hPtr); } static void DestroyTags(Tabset *setPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); } } static void RemoveTag(Tab *tabPtr, const char *tagName) { Blt_HashTable *tablePtr; Tabset *setPtr; setPtr = tabPtr->setPtr; tablePtr = GetTagTable(setPtr, tagName); if (tablePtr != NULL) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)tabPtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } static void ClearTags(Tab *tabPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tabset *setPtr; setPtr = tabPtr->setPtr; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)tabPtr); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tablePtr, h2Ptr); } } } static void AppendTags(Tabset *setPtr, Tab *tabPtr, Blt_List list) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(tablePtr, (char *)tabPtr) != NULL) { Blt_List_Append(list, Blt_GetHashKey(&setPtr->tagTable, hPtr), 0); } } } static ClientData MakeBindTag(Tabset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&setPtr->bindTagTable, tagName, &isNew); return Blt_GetHashKey(&setPtr->bindTagTable, hPtr); } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Converts an image name into a Tk image token. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Contains a pointer to the tabset containing * this image. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window associated with the tabset. */ Tcl_Obj *objPtr, /* String representation */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tabset *setPtr = clientData; Icon *iconPtr = (Icon *) (widgRec + offset); Icon icon; const char *string; int length; icon = NULL; string = Tcl_GetStringFromObj(objPtr, &length); if (length > 0) { icon = GetIcon(setPtr, interp, tkwin, string); if (icon == NULL) { return TCL_ERROR; } } *iconPtr = icon; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObj -- * * Converts the Tk image back to a Tcl_Obj representation (i.e. its * name). * * Results: * The name of the image is returned as a Tcl_Obj. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Pointer to tabset containing image. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tabset *setPtr = clientData; Icon *iconPtr = (Icon *) (widgRec + offset); Tcl_Obj *objPtr; if (*iconPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { const char *name; name = Blt_GetHashKey(&setPtr->iconTable, (*iconPtr)->hashPtr); objPtr = Tcl_NewStringObj(name, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToSlantProc -- * * Converts the slant style string into its numeric representation. * * Valid style strings are: * * "none" Both sides are straight. * "left" Left side is slanted. * "right" Right side is slanted. * "both" Both sides are slanted. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSlantProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of * attribute. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { const char *string; char c; int *slantPtr = (int *)(widgRec + offset); int slant; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "none", length) == 0)) { slant = SLANT_NONE; } else if ((c == 'l') && (strncmp(string, "left", length) == 0)) { slant = SLANT_LEFT; } else if ((c == 'r') && (strncmp(string, "right", length) == 0)) { slant = SLANT_RIGHT; } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) { slant = SLANT_BOTH; } else { Tcl_AppendResult(interp, "bad argument \"", string, "\": should be \"none\", \"left\", \"right\", or \"both\"", (char *)NULL); return TCL_ERROR; } *slantPtr &= ~SLANT_BOTH; *slantPtr |= slant; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SlantToObjProc -- * * Returns the slant style string based upon the slant flags. * * Results: * The slant style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SlantToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget structure record. */ int offset, /* Offset to field in structure */ int flags) { int slant = *(int *)(widgRec + offset); const char *string; switch (slant & SLANT_BOTH) { case SLANT_LEFT: string = "left"; break; case SLANT_RIGHT: string = "right"; break; case SLANT_NONE: string = "none"; break; case SLANT_BOTH: string = "both"; break; default: string = "???"; break; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToChildProc -- * * Converts a window name into Tk window. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToChildProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window parent, /* Parent window */ Tcl_Obj *objPtr, /* String representation. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tab *tabPtr = (Tab *)widgRec; Tk_Window *tkwinPtr = (Tk_Window *)(widgRec + offset); Tk_Window old, tkwin; Tabset *setPtr; const char *string; old = *tkwinPtr; tkwin = NULL; setPtr = tabPtr->setPtr; string = Tcl_GetString(objPtr); if (string[0] != '\0') { tkwin = Tk_NameToWindow(interp, string, parent); if (tkwin == NULL) { return TCL_ERROR; } if (tkwin == old) { return TCL_OK; } /* * Allow only widgets that are children of the tabset to be embedded * into the page. This way we can make assumptions about the window * based upon its parent; either it's the tabset window or it has * been torn off. */ parent = Tk_Parent(tkwin); if (parent != setPtr->tkwin) { Tcl_AppendResult(interp, "can't manage \"", Tk_PathName(tkwin), "\" in tabset \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } Tk_ManageGeometry(tkwin, &tabMgrInfo, tabPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, tabPtr); /* * We need to make the window to exist immediately. If the window is * torn off (placed into another container window), the timing between * the container and the its new child (this window) gets tricky. * This should work for Tk 4.2. */ Tk_MakeWindowExist(tkwin); } if (old != NULL) { if (tabPtr->container != NULL) { Tcl_EventuallyFree(tabPtr, DestroyTearoff); } Tk_DeleteEventHandler(old, StructureNotifyMask, EmbeddedWidgetEventProc, tabPtr); Tk_ManageGeometry(old, (Tk_GeomMgr *) NULL, tabPtr); Tk_UnmapWindow(old); } *tkwinPtr = tkwin; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ChildToObjProc -- * * Converts the Tk window back to a Tcl_Obj (i.e. its name). * * Results: * The name of the window is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ChildToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window parent, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tk_Window tkwin = *(Tk_Window *)(widgRec + offset); Tcl_Obj *objPtr; if (tkwin == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToTabWidthProc -- * * Converts the tab width style string into its numeric representation. * * Valid width strings are: * * "variable" Tab width determined by text/image label. * "same" Tab width is max of all text/image labels. * "1i" Tab width is set to 1 inch. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTabWidthProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of * attribute. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { const char *string; char c; int *widthPtr = (int *)(widgRec + offset); int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'v') && (strncmp(string, "variable", length) == 0)) { *widthPtr = TABWIDTH_VARIABLE; } else if ((c == 's') && (strncmp(string, "same", length) == 0)) { *widthPtr = TABWIDTH_SAME; } else if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_POS, widthPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TabWidthToObjProc -- * * Returns the tabwidth string based upon the tabwidth. * * Results: * The tabwidth string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TabWidthToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget structure record. */ int offset, /* Offset to field in structure */ int flags) { int width = *(int *)(widgRec + offset); switch (width) { case TABWIDTH_VARIABLE: return Tcl_NewStringObj("variable", 8); case TABWIDTH_SAME: return Tcl_NewStringObj("same", 4); default: return Tcl_NewIntObj(width); } } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Convert the string representation of an tab state into a flag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tab *tabPtr = (Tab *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; Tabset *setPtr; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "active") == 0) { flag = ACTIVE; } else if (strcmp(string, "disabled") == 0) { flag = DISABLED; } else if (strcmp(string, "hidden") == 0) { flag = HIDE; } else if (strcmp(string, "normal") == 0) { flag = NORMAL; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, hidden, or normal.", (char *)NULL); return TCL_ERROR; } if (tabPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } setPtr = tabPtr->setPtr; if (setPtr->activePtr != tabPtr) { setPtr->activePtr = NULL; } *flagsPtr &= ~STATE_MASK; *flagsPtr |= flag; if (flag == ACTIVE) { setPtr->activePtr = tabPtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); Tcl_Obj *objPtr; if (state & HIDE) { objPtr = Tcl_NewStringObj("hidden", -1); } else if (state & DISABLED) { objPtr = Tcl_NewStringObj("disabled", -1); } else if (state & ACTIVE) { objPtr = Tcl_NewStringObj("active", -1); } else { objPtr = Tcl_NewStringObj("normal", -1); } return objPtr; } static int WorldY(Tab *tabPtr) { int tier; tier = tabPtr->setPtr->nTiers - tabPtr->tier; return tier * tabPtr->setPtr->tabHeight; } static INLINE Tab * FirstTab(Tabset *setPtr, unsigned int hateFlags) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(link); if ((tabPtr->flags & hateFlags) == 0) { return tabPtr; } } return NULL; } static INLINE Tab * LastTab(Tabset *setPtr, unsigned int hateFlags) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(setPtr->chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(link); if ((tabPtr->flags & hateFlags) == 0) { return tabPtr; } } return NULL; } static Tab * NextTab(Tab *tabPtr, unsigned int hateFlags) { if (tabPtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_NextLink(tabPtr->link); link != NULL; link = Blt_Chain_NextLink(link)) { tabPtr = Blt_Chain_GetValue(link); if ((tabPtr->flags & hateFlags) == 0) { return tabPtr; } } } return NULL; } static Tab * PrevTab(Tab *tabPtr, unsigned int hateFlags) { if (tabPtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_PrevLink(tabPtr->link); link != NULL; link = Blt_Chain_PrevLink(link)) { tabPtr = Blt_Chain_GetValue(link); if ((tabPtr->flags & hateFlags) == 0) { return tabPtr; } } } return NULL; } static INLINE Tab * BeginTab(Tabset *setPtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(setPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static INLINE Tab * EndTab(Tabset *setPtr) { Blt_ChainLink link; link = Blt_Chain_LastLink(setPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static Tab * StepTab(Tab *tabPtr) { if (tabPtr != NULL) { Blt_ChainLink link; link = Blt_Chain_NextLink(tabPtr->link); if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } static void ReindexTabs(Tabset *setPtr) { int count; Tab *tabPtr; count = 0; for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { tabPtr->index = count; count++; } } /* *--------------------------------------------------------------------------- * * RenumberTiers -- * * In multi-tier mode, we need to find the start of the tier containing * the newly selected tab. * * Tiers are draw from the last tier to the first, so that the the * lower-tiered tabs will partially cover the bottoms of tab directly * above it. This simplifies the drawing of tabs because we don't worry * how tabs are clipped by their neighbors. * * In addition, tabs are re-marked with the correct tier number. * * Results: * None. * * Side Effects: * Renumbering the tab's tier will change the vertical placement * of the tab (i.e. shift tiers). * *--------------------------------------------------------------------------- */ static void RenumberTiers(Tabset *setPtr, Tab *tabPtr) { int tier; Blt_ChainLink link, last; setPtr->focusPtr = setPtr->selectPtr = tabPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); tier = tabPtr->tier; for (link = Blt_Chain_PrevLink(tabPtr->link); link != NULL; link = last) { Tab *prevPtr; last = Blt_Chain_PrevLink(link); prevPtr = Blt_Chain_GetValue(link); if ((prevPtr == NULL) || (prevPtr->tier != tier)) { break; } tabPtr = prevPtr; } setPtr->startPtr = tabPtr; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tabPtr = Blt_Chain_GetValue(link); tabPtr->tier = (tabPtr->tier - tier + 1); if (tabPtr->tier < 1) { tabPtr->tier += setPtr->nTiers; } tabPtr->worldY = WorldY(tabPtr); } } /* *--------------------------------------------------------------------------- * * PickTabProc -- * * Searches the tab located within the given screen X-Y coordinates in * the viewport. Note that tabs overlap slightly, so that its important * to search from the innermost tier out. * * Results: * Returns the pointer to the tab. If the pointer isn't contained by any * tab, NULL is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static ClientData PickTabProc(ClientData clientData, int x, int y, ClientData *contextPtr) { Tabset *setPtr = clientData; Tab *tabPtr; int xSelPad, ySelPad; if (contextPtr != NULL) { *contextPtr = NULL; } tabPtr = setPtr->selectPtr; if ((setPtr->flags & TEAROFF) && (tabPtr != NULL) && (tabPtr->container == NULL) && (tabPtr->tkwin != NULL)) { int top, bottom, left, right; int sx, sy; /* Check first for perforation on the selected tab. */ WorldToScreen(setPtr, tabPtr->worldX + 2, tabPtr->worldY + tabPtr->worldHeight + 4, &sx, &sy); if (setPtr->side & (SIDE_TOP|SIDE_BOTTOM)) { left = sx - 2; right = left + tabPtr->screenWidth; top = sy - 4; bottom = sy + 4; } else { left = sx - 4; right = sx + 4; top = sy - 2; bottom = top + tabPtr->screenHeight; } if ((x >= left) && (y >= top) && (x < right) && (y < bottom)) { if (contextPtr != NULL) { *contextPtr = TAB_PERFORATION; } return setPtr->selectPtr; } } /* Adjust the label's area according to the tab's slant. */ if (setPtr->side & (SIDE_RIGHT | SIDE_LEFT)) { y -= (setPtr->flags & SLANT_LEFT) ? setPtr->tabHeight : setPtr->inset2; } else { x -= (setPtr->flags & SLANT_LEFT) ? setPtr->tabHeight : setPtr->inset2; } for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { GadgetRegion *rPtr; if ((tabPtr->flags & ONSCREEN) == 0) { continue; } if ((x >= tabPtr->screenX) && (y >= tabPtr->screenY) && (x <= (tabPtr->screenX + tabPtr->screenWidth)) && (y < (tabPtr->screenY + tabPtr->screenHeight + 4 + setPtr->ySelectPad))) { if (contextPtr != NULL) { *contextPtr = TAB_LABEL; } rPtr = &tabPtr->buttonRegion; if ((tabPtr->flags & CLOSE_NEEDED) && (x >= (tabPtr->screenX + rPtr->x)) && (x < (tabPtr->screenX + rPtr->x + rPtr->w)) && (y >= (tabPtr->screenY + rPtr->y)) && (y < (tabPtr->screenY + rPtr->y + rPtr->h))) { *contextPtr = TAB_BUTTON; } return tabPtr; } } return NULL; } static Tab * TabLeft(Tab *tabPtr) { Blt_ChainLink link; link = Blt_Chain_PrevLink(tabPtr->link); if (link != NULL) { Tab *newPtr; newPtr = Blt_Chain_GetValue(link); /* Move only if the next tab is the same tier. */ if (newPtr->tier == tabPtr->tier) { tabPtr = newPtr; } } return tabPtr; } static Tab * TabRight(Tab *tabPtr) { Blt_ChainLink link; link = Blt_Chain_NextLink(tabPtr->link); if (link != NULL) { Tab *newPtr; newPtr = Blt_Chain_GetValue(link); /* Move only if the next tab is on the same tier. */ if (newPtr->tier == tabPtr->tier) { tabPtr = newPtr; } } return tabPtr; } static Tab * TabUp(Tab *tabPtr) { if (tabPtr != NULL) { Tabset *setPtr; int x, y; int worldX, worldY; setPtr = tabPtr->setPtr; worldX = tabPtr->worldX + (tabPtr->worldWidth / 2); worldY = tabPtr->worldY - (setPtr->tabHeight / 2); WorldToScreen(setPtr, worldX, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); if (tabPtr == NULL) { /* * We might have inadvertly picked the gap between two tabs, so if * the first pick fails, try again a little to the left. */ WorldToScreen(setPtr, worldX + setPtr->gap, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } if ((tabPtr == NULL) && (setPtr->focusPtr->tier < (setPtr->nTiers - 1))) { worldY -= setPtr->tabHeight; WorldToScreen(setPtr, worldX, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } if (tabPtr == NULL) { tabPtr = setPtr->focusPtr; } } return tabPtr; } static Tab * TabDown(Tab *tabPtr) { if (tabPtr != NULL) { Tabset *setPtr; int x, y; int worldX, worldY; setPtr = tabPtr->setPtr; worldX = tabPtr->worldX + (tabPtr->worldWidth / 2); worldY = tabPtr->worldY + (3 * setPtr->tabHeight) / 2; WorldToScreen(setPtr, worldX, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); if (tabPtr == NULL) { /* * We might have inadvertly picked the gap between two tabs, so if * the first pick fails, try again a little to the left. */ WorldToScreen(setPtr, worldX - setPtr->gap, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } if ((tabPtr == NULL) && (setPtr->focusPtr->tier > 2)) { worldY += setPtr->tabHeight; WorldToScreen(setPtr, worldX, worldY, &x, &y); tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } if (tabPtr == NULL) { tabPtr = setPtr->focusPtr; } } return tabPtr; } /* *--------------------------------------------------------------------------- * * NextTaggedTab -- * * Returns the next tab derived from the given tag. * * Results: * Returns the pointer to the next tab in the iterator. If no more tabs * are available, then NULL is returned. * *--------------------------------------------------------------------------- */ static Tab * NextTaggedTab(TabIterator *iterPtr) { switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } break; } case ITER_ALL: if (iterPtr->link != NULL) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return tabPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(tabPtr->text, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return tabPtr; } } break; } default: break; } return NULL; } /* *--------------------------------------------------------------------------- * * FirstTaggedTab -- * * Returns the first tab derived from the given tag. * * Results: * Returns the first tab in the sequence. If no more tabs are in * the list, then NULL is returned. * *--------------------------------------------------------------------------- */ static Tab * FirstTaggedTab(TabIterator *iterPtr) { switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } case ITER_ALL: if (iterPtr->link != NULL) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return tabPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(tabPtr->text, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return tabPtr; } } break; } case ITER_SINGLE: return iterPtr->startPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * GetTabFromObj -- * * Gets the tab associated the given index, tag, or label. This routine * is used when you want only one tab. It's an error if more than one * tab is specified (e.g. "all" tag or range "1:4"). It's also an error * if the tag is empty (no tabs are currently tagged). * *--------------------------------------------------------------------------- */ static int GetTabFromObj(Tcl_Interp *interp, Tabset *setPtr, Tcl_Obj *objPtr, Tab **tabPtrPtr) { TabIterator iter; Tab *firstPtr; if (GetTabIterator(interp, setPtr, objPtr, &iter) != TCL_OK) { return TCL_ERROR; } firstPtr = FirstTaggedTab(&iter); if (firstPtr != NULL) { Tab *nextPtr; nextPtr = NextTaggedTab(&iter); if (nextPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple tabs specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } *tabPtrPtr = firstPtr; return TCL_OK; } static int GetTabByIndex(Tcl_Interp *interp, Tabset *setPtr, const char *string, int length, Tab **tabPtrPtr) { Tab *tabPtr; char c; long pos; tabPtr = NULL; c = string[0]; length = strlen(string); if (Tcl_GetLong(NULL, string, &pos) == TCL_OK) { Blt_ChainLink link; link = Blt_Chain_GetNthLink(setPtr->chain, pos); if (link != NULL) { tabPtr = Blt_Chain_GetValue(link); } if (tabPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find tab: bad index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } } else if ((c == 'a') && (strncmp(string, "active", length) == 0)) { tabPtr = setPtr->activePtr; } else if ((c == 'c') && (strncmp(string, "current", length) == 0)) { tabPtr = (Tab *)Blt_GetCurrentItem(setPtr->bindTable); } else if ((c == 'd') && (strncmp(string, "down", length) == 0)) { switch (setPtr->side) { case SIDE_LEFT: case SIDE_RIGHT: tabPtr = TabRight(setPtr->focusPtr); break; case SIDE_BOTTOM: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_TOP: tabPtr = TabDown(setPtr->focusPtr); break; } } else if ((c == 'f') && (length > 1) && (strncmp(string, "focus", length) == 0)) { tabPtr = setPtr->focusPtr; } else if ((c == 'f') && (length > 1) && (strncmp(string, "first", length) == 0)) { tabPtr = FirstTab(setPtr, HIDE | DISABLED); } else if ((c == 's') && (strncmp(string, "selected", length) == 0)) { tabPtr = setPtr->selectPtr; } else if ((c == 'l') && (length > 1) && (strncmp(string, "last", length) == 0)) { tabPtr = LastTab(setPtr, HIDE | DISABLED); } else if ((c == 'l') && (length > 1) && (strncmp(string, "left", length) == 0)) { switch (setPtr->side) { case SIDE_LEFT: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_RIGHT: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_BOTTOM: case SIDE_TOP: tabPtr = TabLeft(setPtr->focusPtr); break; } } else if ((c == 'n') && (strncmp(string, "none", length) == 0)) { tabPtr = NULL; } else if ((c == 'r') && (strncmp(string, "right", length) == 0)) { switch (setPtr->side) { case SIDE_LEFT: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_RIGHT: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_BOTTOM: case SIDE_TOP: tabPtr = TabRight(setPtr->focusPtr); break; } } else if ((c == 'u') && (strncmp(string, "up", length) == 0)) { switch (setPtr->side) { case SIDE_LEFT: case SIDE_RIGHT: tabPtr = TabLeft(setPtr->focusPtr); break; case SIDE_BOTTOM: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_TOP: tabPtr = TabUp(setPtr->focusPtr); break; } } else if (c == '@') { int x, y; if (Blt_GetXY(interp, setPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } else { return TCL_CONTINUE; } *tabPtrPtr = tabPtr; return TCL_OK; } static Tab * GetTabByName(Tabset *setPtr, const char *string) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&setPtr->tabTable, string); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * GetTabIterator -- * * Converts a string representing a tab index into an tab pointer. The * index may be in one of the following forms: * * number Tab at index in the list of tabs. * @x,y Tab closest to the specified X-Y screen coordinates. * "active" Tab where mouse pointer is located. * "posted" Tab is the currently posted cascade tab. * "next" Next tab from the focus tab. * "previous" Previous tab from the focus tab. * "end" Last tab. * "none" No tab. * * number Tab at position in the list of tabs. * @x,y Tab closest to the specified X-Y screen coordinates. * "active" Tab mouse is located over. * "focus" Tab is the widget's focus. * "select" Currently selected tab. * "right" Next tab from the focus tab. * "left" Previous tab from the focus tab. * "up" Next tab from the focus tab. * "down" Previous tab from the focus tab. * "end" Last tab in list. * "name:string" Tab named "string". * "index:number" Tab at index number in list of tabs. * "tag:string" Tab(s) tagged by "string". * "label:pattern" Tab(s) with label matching "pattern". * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via tabPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetTabIterator(Tcl_Interp *interp, Tabset *setPtr, Tcl_Obj *objPtr, TabIterator *iterPtr) { Tab *tabPtr, *startPtr, *endPtr; Blt_HashTable *tablePtr; char *string; char c; int nBytes; int length; int result; iterPtr->setPtr = setPtr; iterPtr->type = ITER_SINGLE; iterPtr->tagName = Tcl_GetStringFromObj(objPtr, &nBytes); iterPtr->nextPtr = NULL; iterPtr->startPtr = iterPtr->endPtr = NULL; if (setPtr->focusPtr == NULL) { setPtr->focusPtr = setPtr->selectPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); } string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; iterPtr->startPtr = iterPtr->endPtr = setPtr->activePtr; startPtr = endPtr = tabPtr = NULL; if (c == '\0') { startPtr = endPtr = NULL; } iterPtr->type = ITER_SINGLE; result = GetTabByIndex(interp, setPtr, string, length, &tabPtr); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_OK) { iterPtr->startPtr = iterPtr->endPtr = tabPtr; return TCL_OK; } if ((c == 'a') && (strcmp(iterPtr->tagName, "all") == 0)) { iterPtr->type = ITER_ALL; iterPtr->link = Blt_Chain_FirstLink(setPtr->chain); } else if ((c == 'i') && (length > 6) && (strncmp(string, "index:", 6) == 0)) { if (GetTabByIndex(interp, setPtr, string + 6, length - 6, &tabPtr) != TCL_OK) { return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = tabPtr; } else if ((c == 'n') && (length > 5) && (strncmp(string, "name:", 5) == 0)) { tabPtr = GetTabByName(setPtr, string + 5); if (tabPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find a tab name \"", string + 5, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = tabPtr; } else if ((c == 't') && (length > 4) && (strncmp(string, "tag:", 4) == 0)) { Blt_HashTable *tablePtr; tablePtr = GetTagTable(setPtr, string + 4); if (tablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find a tag \"", string + 5, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->tagName = string + 4; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else if ((c == 'l') && (length > 6) && (strncmp(string, "label:", 6) == 0)) { iterPtr->link = Blt_Chain_FirstLink(setPtr->chain); iterPtr->tagName = string + 6; iterPtr->type = ITER_PATTERN; } else if ((tabPtr = GetTabByName(setPtr, string)) != NULL) { iterPtr->startPtr = iterPtr->endPtr = tabPtr; } else if ((tablePtr = GetTagTable(setPtr, string)) != NULL) { iterPtr->tagName = string; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else { if (interp != NULL) { Tcl_AppendResult(interp, "can't find tab index, name, or tag \"", string, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } return TCL_OK; } #ifdef notdef /* *--------------------------------------------------------------------------- * * GetTabFromObj -- * * Converts a string representing a tab index into a tab pointer. The * index may be in one of the following forms: * * number Tab at position in the list of tabs. * @x,y Tab closest to the specified X-Y screen coordinates. * "active" Tab mouse is located over. * "focus" Tab is the widget's focus. * "select" Currently selected tab. * "right" Next tab from the focus tab. * "left" Previous tab from the focus tab. * "up" Next tab from the focus tab. * "down" Previous tab from the focus tab. * "end" Last tab in list. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via tabPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetTabFromObj(Tabset *setPtr, Tcl_Obj *objPtr, Tab **tabPtrPtr, int allowNull) { Tab *tabPtr; Blt_ChainLink link; int position; char c; const char *string; string = Tcl_GetString(objPtr); c = string[0]; tabPtr = NULL; if (setPtr->focusPtr == NULL) { setPtr->focusPtr = setPtr->selectPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); } if ((isdigit(UCHAR(c))) && (Tcl_GetIntFromObj(setPtr->interp, objPtr, &position) == TCL_OK)) { link = Blt_Chain_GetNthLink(setPtr->chain, position); if (link == NULL) { Tcl_AppendResult(setPtr->interp, "can't find tab \"", string, "\" in \"", Tk_PathName(setPtr->tkwin), "\": no such index", (char *)NULL); return TCL_ERROR; } tabPtr = Blt_Chain_GetValue(link); } else if ((c == 'a') && (strcmp(string, "active") == 0)) { tabPtr = setPtr->activePtr; } else if ((c == 'c') && (strcmp(string, "current") == 0)) { tabPtr = (Tab *)Blt_GetCurrentItem(setPtr->bindTable); } else if ((c == 's') && (strcmp(string, "select") == 0)) { tabPtr = setPtr->selectPtr; } else if ((c == 'f') && (strcmp(string, "focus") == 0)) { tabPtr = setPtr->focusPtr; } else if ((c == 'u') && (strcmp(string, "up") == 0)) { switch (setPtr->side) { case SIDE_LEFT: case SIDE_RIGHT: tabPtr = TabLeft(setPtr->focusPtr); break; case SIDE_BOTTOM: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_TOP: tabPtr = TabUp(setPtr->focusPtr); break; } } else if ((c == 'd') && (strcmp(string, "down") == 0)) { switch (setPtr->side) { case SIDE_LEFT: case SIDE_RIGHT: tabPtr = TabRight(setPtr->focusPtr); break; case SIDE_BOTTOM: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_TOP: tabPtr = TabDown(setPtr->focusPtr); break; } } else if ((c == 'l') && (strcmp(string, "left") == 0)) { switch (setPtr->side) { case SIDE_LEFT: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_RIGHT: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_BOTTOM: case SIDE_TOP: tabPtr = TabLeft(setPtr->focusPtr); break; } } else if ((c == 'r') && (strcmp(string, "right") == 0)) { switch (setPtr->side) { case SIDE_LEFT: tabPtr = TabDown(setPtr->focusPtr); break; case SIDE_RIGHT: tabPtr = TabUp(setPtr->focusPtr); break; case SIDE_BOTTOM: case SIDE_TOP: tabPtr = TabRight(setPtr->focusPtr); break; } } else if ((c == 'e') && (strcmp(string, "end") == 0)) { tabPtr = LastTab(setPtr, 0); } else if (c == '@') { int x, y; if (Blt_GetXY(setPtr->interp, setPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); } else { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&setPtr->tabTable, string); if (hPtr != NULL) { tabPtr = Blt_GetHashValue(hPtr); } } *tabPtrPtr = tabPtr; Tcl_ResetResult(setPtr->interp); if ((!allowNull) && (tabPtr == NULL)) { Tcl_AppendResult(setPtr->interp, "can't find tab \"", string, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } #endif static Tab * NextOrLastTab(Tab *tabPtr) { if (tabPtr->link != NULL) { Blt_ChainLink link; link = Blt_Chain_NextLink(tabPtr->link); if (link == NULL) { link = Blt_Chain_PrevLink(tabPtr->link); } if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } static Tab * PreviousOrFirstTab(Tab *tabPtr) { if (tabPtr->link != NULL) { Blt_ChainLink link; link = Blt_Chain_PrevLink(tabPtr->link); if (link == NULL) { link = Blt_Chain_NextLink(tabPtr->link); } if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * embedded widgets contained in the tabset. * * Results: * None. * * Side effects: * When an embedded widget gets deleted, internal structures get cleaned * up. When it gets resized, the tabset is redisplayed. * *--------------------------------------------------------------------------- */ static void EmbeddedWidgetEventProc(ClientData clientData, XEvent *eventPtr) { Tab *tabPtr = clientData; if ((tabPtr == NULL) || (tabPtr->tkwin == NULL)) { return; } switch (eventPtr->type) { case ConfigureNotify: /* * If the window's requested size changes, redraw the window. But * only if it's currently the selected page. */ if ((tabPtr->container == NULL) && (Tk_IsMapped(tabPtr->tkwin)) && (tabPtr->setPtr->selectPtr == tabPtr)) { tabPtr->setPtr->flags |= REDRAW_ALL; EventuallyRedraw(tabPtr->setPtr); } break; case DestroyNotify: /* * Mark the tab as deleted by dereferencing the Tk window * pointer. Redraw the window only if the tab is currently visible. */ if ((Tk_IsMapped(tabPtr->tkwin)) && (tabPtr->setPtr->selectPtr == tabPtr)) { tabPtr->setPtr->flags |= REDRAW_ALL; EventuallyRedraw(tabPtr->setPtr); } Tk_DeleteEventHandler(tabPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, tabPtr); tabPtr->tkwin = NULL; break; } } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetCustodyProc -- * * This procedure is invoked when a tab window has been stolen by another * geometry manager. The information and memory associated with the tab * window is released. * * Results: * None. * * Side effects: * Arranges for the widget formerly associated with the tab window to * have its layout re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void EmbeddedWidgetCustodyProc(ClientData clientData, Tk_Window tkwin) { Tab *tabPtr = clientData; Tabset *setPtr; if ((tabPtr == NULL) || (tabPtr->tkwin == NULL)) { return; } setPtr = tabPtr->setPtr; if (tabPtr->container != NULL) { Tcl_EventuallyFree(tabPtr, DestroyTearoff); } /* * Mark the tab as deleted by dereferencing the Tk window pointer. Redraw * the window only if the tab is currently visible. */ if (tabPtr->tkwin != NULL) { if (Tk_IsMapped(tabPtr->tkwin) && (setPtr->selectPtr == tabPtr)) { setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); } Tk_DeleteEventHandler(tabPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, tabPtr); tabPtr->tkwin = NULL; } } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for tab windows * managed by the widget. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to be repacked and * drawn at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void EmbeddedWidgetGeometryProc(ClientData clientData, Tk_Window tkwin) { Tab *tabPtr = clientData; if ((tabPtr == NULL) || (tabPtr->tkwin == NULL)) { fprintf(stderr, "%s: line %d \"tkwin is null\"", __FILE__, __LINE__); return; } tabPtr->setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(tabPtr->setPtr); } /* *--------------------------------------------------------------------------- * * DestroyTab -- * *--------------------------------------------------------------------------- */ static void DestroyTab(Tabset *setPtr, Tab *tabPtr) { iconOption.clientData = setPtr; Blt_FreeOptions(tabSpecs, (char *)tabPtr, setPtr->display, 0); ClearTags(tabPtr); if (tabPtr->flags & TEAROFF_REDRAW) { Tcl_CancelIdleCall(DisplayTearoff, tabPtr); } if (tabPtr->container != NULL) { Tk_DestroyWindow(tabPtr->container); } if (tabPtr == setPtr->plusPtr) { setPtr->plusPtr = NULL; /* Indicate that the plus tab has now * been deleted. */ } if (tabPtr->tkwin != NULL) { Tk_ManageGeometry(tabPtr->tkwin, (Tk_GeomMgr *)NULL, tabPtr); Tk_DeleteEventHandler(tabPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, tabPtr); if (Tk_IsMapped(tabPtr->tkwin)) { Tk_UnmapWindow(tabPtr->tkwin); } } if (tabPtr == setPtr->activePtr) { setPtr->activePtr = NULL; } if (tabPtr == setPtr->selectPtr) { setPtr->selectPtr = PreviousOrFirstTab(tabPtr); } if (tabPtr == setPtr->focusPtr) { setPtr->focusPtr = setPtr->selectPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); } if (tabPtr == setPtr->startPtr) { setPtr->startPtr = NULL; } if (tabPtr->text != NULL) { Blt_Free(tabPtr->text); } if (tabPtr->textGC != NULL) { Tk_FreeGC(setPtr->display, tabPtr->textGC); } if (tabPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&setPtr->tabTable, tabPtr->hashPtr); } if (tabPtr->backGC != NULL) { Tk_FreeGC(setPtr->display, tabPtr->backGC); } if (tabPtr->link != NULL) { Blt_Chain_DeleteLink(setPtr->chain, tabPtr->link); } if (tabPtr->layoutPtr != NULL) { Blt_Free(tabPtr->layoutPtr); } Blt_DeleteBindings(setPtr->bindTable, tabPtr); Blt_Free(tabPtr); } /* *--------------------------------------------------------------------------- * * NewTab -- * * Creates a new tab structure. A tab contains information about the * state of the tab and its embedded window. * * Results: * Returns a pointer to the new tab structure. * *--------------------------------------------------------------------------- */ static Tab * NewTab(Tcl_Interp *interp, Tabset *setPtr, const char *tabName) { Tab *tabPtr; Blt_HashEntry *hPtr; int isNew; char string[200]; if (tabName == NULL) { sprintf_s(string, 200, "tab%d", setPtr->nextId++); tabName = string; } hPtr = Blt_CreateHashEntry(&setPtr->tabTable, tabName, &isNew); if (!isNew) { if (interp != NULL) { Tcl_AppendResult(interp, "a tab \"", tabName, "\" already exists in \"", Tk_PathName(setPtr->tkwin), "\".", (char *)NULL); } return NULL; } tabPtr = Blt_AssertCalloc(1, sizeof(Tab)); tabPtr->setPtr = setPtr; if (strcmp(tabName, "+") == 0) { setPtr->plusPtr = tabPtr; } tabPtr->text = Blt_AssertStrdup(tabName); tabPtr->fill = FILL_NONE; tabPtr->anchor = TK_ANCHOR_CENTER; tabPtr->container = NULL; tabPtr->flags = NORMAL | CLOSE_NEEDED; tabPtr->name = Blt_GetHashKey(&setPtr->tabTable, hPtr); Blt_SetHashValue(hPtr, tabPtr); tabPtr->hashPtr = hPtr; return tabPtr; } /* *--------------------------------------------------------------------------- * * BackgroundChangedProc * * Stub for image change notifications. Since we immediately draw the * image into a pixmap, we don't really care about image changes. * * It would be better if Tk checked for NULL proc pointers. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void BackgroundChangedProc(ClientData clientData) { Tabset *setPtr = clientData; if (setPtr->tkwin != NULL) { setPtr->flags |= REDRAW_ALL; EventuallyRedraw(setPtr); } } static int ConfigureTab(Tabset *setPtr, Tab *tabPtr) { Blt_Background bg; Blt_Font font; GC newGC; XGCValues gcValues; unsigned long gcMask; font = GETATTR(tabPtr, font); newGC = NULL; if (tabPtr->text != NULL) { XColor *colorPtr; gcMask = GCForeground | GCFont; colorPtr = GETATTR(tabPtr, textColor); gcValues.foreground = colorPtr->pixel; gcValues.font = Blt_FontId(font); newGC = Tk_GetGC(setPtr->tkwin, gcMask, &gcValues); } if (tabPtr->textGC != NULL) { Tk_FreeGC(setPtr->display, tabPtr->textGC); } tabPtr->textGC = newGC; gcMask = GCForeground | GCStipple | GCFillStyle; gcValues.fill_style = FillStippled; bg = GETATTR(tabPtr, bg); gcValues.foreground = Blt_BackgroundBorderColor(bg)->pixel; gcValues.stipple = tabPtr->stipple; newGC = Tk_GetGC(setPtr->tkwin, gcMask, &gcValues); if (tabPtr->backGC != NULL) { Tk_FreeGC(setPtr->display, tabPtr->backGC); } tabPtr->backGC = newGC; if (tabPtr->bg != NULL) { Blt_SetBackgroundChangedProc(tabPtr->bg, BackgroundChangedProc, setPtr); } if (Blt_ConfigModified(tabSpecs, "-image", "-*pad*", "-state", "-text", "-window*", (char *)NULL)) { setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); } if (tabPtr->flags & HIDE) { if (setPtr->selectPtr == tabPtr) { setPtr->selectPtr = FirstTab(setPtr, HIDE | DISABLED); } if (setPtr->activePtr == tabPtr) { setPtr->activePtr = NULL; } } EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureButton -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static void DestroyButton(Tabset *setPtr, Button *butPtr) { iconOption.clientData = setPtr; Blt_FreeOptions(buttonSpecs, (char *)butPtr, setPtr->display, 0); if (butPtr->active != butPtr->active0) { Blt_FreePicture(butPtr->active); } if (butPtr->normal != butPtr->normal0) { Blt_FreePicture(butPtr->normal); } if (butPtr->active0 != NULL) { Blt_FreePicture(butPtr->active0); } if (butPtr->normal0 != NULL) { Blt_FreePicture(butPtr->normal0); } } /* *--------------------------------------------------------------------------- * * ConfigureButton -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureButton( Tcl_Interp *interp, /* Interpreter to report errors. */ Tabset *setPtr, /* Information about widget; may or * may not already have values for some * fields. */ int objc, Tcl_Obj *const *objv, int flags) { Button *butPtr = &setPtr->closeButton; iconOption.clientData = setPtr; if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, buttonSpecs, objc, objv, (char *)butPtr, flags) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); #ifdef notdef if ((setPtr->reqHeight > 0) && (setPtr->reqWidth > 0)) { Tk_GeometryRequest(setPtr->tkwin, setPtr->reqWidth, setPtr->reqHeight); } #endif setPtr->flags |= REDRAW_ALL; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TearoffEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * the tearoff widget. * * Results: * None. * * Side effects: * When the tearoff gets deleted, internal structures get cleaned up. * When it gets resized or exposed, it's redisplayed. * *--------------------------------------------------------------------------- */ static void TearoffEventProc(ClientData clientData, XEvent *eventPtr) { Tab *tabPtr = clientData; if ((tabPtr == NULL) || (tabPtr->tkwin == NULL) || (tabPtr->container == NULL)) { return; } switch (eventPtr->type) { case Expose: if (eventPtr->xexpose.count == 0) { EventuallyRedrawTearoff(tabPtr); } break; case ConfigureNotify: EventuallyRedrawTearoff(tabPtr); break; case DestroyNotify: if (tabPtr->flags & TEAROFF_REDRAW) { tabPtr->flags &= ~TEAROFF_REDRAW; Tcl_CancelIdleCall(DisplayTearoff, clientData); } Tk_DestroyWindow(tabPtr->container); tabPtr->container = NULL; break; } } /* *--------------------------------------------------------------------------- * * GetReqWidth -- * * Returns the width requested by the embedded tab window and any * requested padding around it. This represents the requested width of * the page. * * Results: * Returns the requested width of the page. * *--------------------------------------------------------------------------- */ static int GetReqWidth(Tab *tabPtr) { int width; if (tabPtr->reqSlaveWidth > 0) { width = tabPtr->reqSlaveWidth; } else { width = Tk_ReqWidth(tabPtr->tkwin); } width += PADDING(tabPtr->xPad) + 2 * Tk_Changes(tabPtr->tkwin)->border_width; if (width < 1) { width = 1; } return width; } /* *--------------------------------------------------------------------------- * * GetReqHeight -- * * Returns the height requested by the window and padding around the * window. This represents the requested height of the page. * * Results: * Returns the requested height of the page. * *--------------------------------------------------------------------------- */ static int GetReqHeight(Tab *tabPtr) { int height; if (tabPtr->reqSlaveHeight > 0) { height = tabPtr->reqSlaveHeight; } else { height = Tk_ReqHeight(tabPtr->tkwin); } height += PADDING(tabPtr->yPad) + 2 * Tk_Changes(tabPtr->tkwin)->border_width; if (height < 1) { height = 1; } return height; } /* *--------------------------------------------------------------------------- * * TranslateAnchor -- * * Translate the coordinates of a given bounding box based upon the * anchor specified. The anchor indicates where the given xy position * is in relation to the bounding box. * * nw --- n --- ne * | | x,y ---+ * w center e | | * | | +-----+ * sw --- s --- se * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ static void TranslateAnchor(int dx, int dy, Tk_Anchor anchor, int *xPtr, int *yPtr) { int x, y; x = y = 0; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y = (dy / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ y = dy; break; case TK_ANCHOR_N: /* Top center */ x = (dx / 2); break; case TK_ANCHOR_CENTER: /* Centered */ x = (dx / 2); y = (dy / 2); break; case TK_ANCHOR_S: /* Bottom center */ x = (dx / 2); y = dy; break; case TK_ANCHOR_NE: /* Upper right corner */ x = dx; break; case TK_ANCHOR_E: /* Right center */ x = dx; y = (dy / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ x = dx; y = dy; break; } *xPtr = (*xPtr) + x; *yPtr = (*yPtr) + y; } static void GetWindowRectangle(Tab *tabPtr, Tk_Window parent, int hasTearOff, XRectangle *rectPtr) { int pad; Tabset *setPtr; int cavityWidth, cavityHeight; int width, height; int dx, dy; int x, y; setPtr = tabPtr->setPtr; pad = setPtr->inset + setPtr->inset2; x = y = 0; /* Suppress compiler warning. */ if (!hasTearOff) { switch (setPtr->side) { case SIDE_RIGHT: case SIDE_BOTTOM: x = setPtr->inset + setPtr->inset2; y = setPtr->inset + setPtr->inset2; break; case SIDE_LEFT: x = setPtr->pageTop; y = setPtr->inset + setPtr->inset2; break; case SIDE_TOP: x = setPtr->inset + setPtr->inset2; y = setPtr->pageTop; break; } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { cavityWidth = Tk_Width(setPtr->tkwin) - (setPtr->pageTop + pad); cavityHeight = Tk_Height(setPtr->tkwin) - (2 * pad); } else { cavityWidth = Tk_Width(setPtr->tkwin) - (2 * pad); cavityHeight = Tk_Height(setPtr->tkwin) - (setPtr->pageTop + pad); } } else { x = setPtr->inset + setPtr->inset2; #define TEAR_OFF_TAB_SIZE 5 y = setPtr->inset + setPtr->inset2 + setPtr->outerPad + TEAR_OFF_TAB_SIZE; if (setPtr->nTiers == 1) { y += setPtr->ySelectPad; } cavityWidth = Tk_Width(parent) - (2 * pad); cavityHeight = Tk_Height(parent) - (y + pad); } cavityWidth -= PADDING(tabPtr->xPad); cavityHeight -= PADDING(tabPtr->yPad); if (cavityWidth < 1) { cavityWidth = 1; } if (cavityHeight < 1) { cavityHeight = 1; } width = GetReqWidth(tabPtr); height = GetReqHeight(tabPtr); /* * Resize the embedded window is of the following is true: * * 1) It's been torn off. * 2) The -fill option (horizontal or vertical) is set. * 3) the window is bigger than the cavity. */ if ((hasTearOff) || (cavityWidth < width) || (tabPtr->fill & FILL_X)) { width = cavityWidth; } if ((hasTearOff) || (cavityHeight < height) || (tabPtr->fill & FILL_Y)) { height = cavityHeight; } dx = (cavityWidth - width); dy = (cavityHeight - height); if ((dx > 0) || (dy > 0)) { TranslateAnchor(dx, dy, tabPtr->anchor, &x, &y); } /* Remember that X11 windows must be at least 1 pixel. */ if (width < 1) { width = 1; } if (height < 1) { height = 1; } rectPtr->x = (short)(x + tabPtr->padLeft); rectPtr->y = (short)(y + tabPtr->padTop); rectPtr->width = (short)width; rectPtr->height = (short)height; } static void ArrangeWindow(Tk_Window tkwin, XRectangle *rectPtr, int force) { if ((force) || (rectPtr->x != Tk_X(tkwin)) || (rectPtr->y != Tk_Y(tkwin)) || (rectPtr->width != Tk_Width(tkwin)) || (rectPtr->height != Tk_Height(tkwin))) { Tk_MoveResizeWindow(tkwin, rectPtr->x, rectPtr->y, rectPtr->width, rectPtr->height); } if (!Tk_IsMapped(tkwin)) { Tk_MapWindow(tkwin); } } /*ARGSUSED*/ static void GetTagsProc(Blt_BindTable table, ClientData object, ClientData context, Blt_List list) { Tab *tabPtr = (Tab *)object; Tabset *setPtr; setPtr = table->clientData; if (context == TAB_PERFORATION) { Blt_List_Append(list, MakeBindTag(setPtr, "Perforation"), 0); } else if (context == TAB_BUTTON) { ClientData tag; Blt_List_Append(list, MakeBindTag(setPtr, "Button"), 0); tag = MakeBindTag(setPtr, tabPtr->name); Blt_List_Append(list, tag, 0); } else if (context == TAB_LABEL) { ClientData tag; tag = MakeBindTag(setPtr, tabPtr->name); Blt_List_Append(list, tag, 0); AppendTags(setPtr, tabPtr, list); Blt_List_Append(list, MakeBindTag(setPtr, "all"), 0); } } /* *--------------------------------------------------------------------------- * * TabsetEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * tabset widgets. * * Results: * None. * * Side Effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void TabsetEventProc(ClientData clientData, XEvent *eventPtr) { Tabset *setPtr = clientData; switch (eventPtr->type) { case Expose: setPtr->flags |= REDRAW_ALL; if (eventPtr->xexpose.count == 0) { EventuallyRedraw(setPtr); } break; case ConfigureNotify: setPtr->flags |= REDRAW_ALL; setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(setPtr); break; case FocusIn: case FocusOut: if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { setPtr->flags |= FOCUS; } else { setPtr->flags &= ~FOCUS; } EventuallyRedraw(setPtr); } break; case DestroyNotify: if (setPtr->tkwin != NULL) { setPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(setPtr->interp, setPtr->cmdToken); } if (setPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTabset, setPtr); } Tcl_EventuallyFree(setPtr, DestroyTabset); break; } } /* *--------------------------------------------------------------------------- * * DestroyTabset -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyTabset(DestroyData dataPtr) { Tabset *setPtr = (Tabset *)dataPtr; Tab *tabPtr; Blt_ChainLink link, next; if (setPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTabset, setPtr); } iconOption.clientData = setPtr; Blt_FreeOptions(configSpecs, (char *)setPtr, setPtr->display, 0); if (setPtr->highlightGC != NULL) { Tk_FreeGC(setPtr->display, setPtr->highlightGC); } if (setPtr->defStyle.activeGC != NULL) { Blt_FreePrivateGC(setPtr->display, setPtr->defStyle.activeGC); } if (setPtr->painter != NULL) { Blt_FreePainter(setPtr->painter); } for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = next) { next = Blt_Chain_NextLink(link); tabPtr = Blt_Chain_GetValue(link); tabPtr->link = NULL; tabPtr->hashPtr = NULL; DestroyTab(setPtr, tabPtr); } DestroyTags(setPtr); DestroyButton(setPtr, &setPtr->closeButton); Blt_Chain_Destroy(setPtr->chain); Blt_DestroyBindingTable(setPtr->bindTable); Blt_DeleteHashTable(&setPtr->iconTable); Blt_DeleteHashTable(&setPtr->tagTable); Blt_DeleteHashTable(&setPtr->bindTagTable); Blt_Free(setPtr); } /* *--------------------------------------------------------------------------- * * NewTabset -- * *--------------------------------------------------------------------------- */ static Tabset * NewTabset(Tcl_Interp *interp, Tk_Window tkwin) { Tabset *setPtr; setPtr = Blt_AssertCalloc(1, sizeof(Tabset)); Tk_SetClass(tkwin, "Tabset"); setPtr->borderWidth = setPtr->highlightWidth = 0; setPtr->corner = CORNER_OFFSET; setPtr->defStyle.borderWidth = 1; setPtr->defStyle.relief = TK_RELIEF_RAISED; setPtr->iconPos = SIDE_LEFT; setPtr->angle = 0.0f; setPtr->justify = TK_JUSTIFY_CENTER; setPtr->reqTabWidth = TABWIDTH_SAME; setPtr->reqTiers = 1; setPtr->reqSlant = SLANT_NONE; setPtr->display = Tk_Display(tkwin); setPtr->flags |= LAYOUT_PENDING | SCROLL_PENDING; setPtr->gap = GAP; setPtr->interp = interp; setPtr->relief = TK_RELIEF_FLAT; setPtr->scrollUnits = 2; setPtr->side = SIDE_TOP; setPtr->tkwin = tkwin; setPtr->closeButton.borderWidth = 0; setPtr->xSelectPad = SELECT_PADX; setPtr->ySelectPad = SELECT_PADY; setPtr->bindTable = Blt_CreateBindingTable(interp, tkwin, setPtr, PickTabProc, GetTagsProc); setPtr->chain = Blt_Chain_Create(); Blt_InitHashTable(&setPtr->tabTable, BLT_STRING_KEYS); Blt_InitHashTable(&setPtr->iconTable, BLT_STRING_KEYS); Blt_InitHashTable(&setPtr->tagTable, BLT_STRING_KEYS); Blt_InitHashTable(&setPtr->bindTagTable, BLT_STRING_KEYS); Blt_SetWindowInstanceData(tkwin, setPtr); return setPtr; } /* *--------------------------------------------------------------------------- * * ConfigureTabset -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureTabset( Tcl_Interp *interp, /* Interpreter to report errors. */ Tabset *setPtr, /* Information about widget; may or may not * already have values for some fields. */ int objc, Tcl_Obj *const *objv, int flags) { XGCValues gcValues; unsigned long gcMask; GC newGC; int slantLeft, slantRight; iconOption.clientData = setPtr; if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, configSpecs, objc, objv, (char *)setPtr, flags) != TCL_OK) { return TCL_ERROR; } if (Blt_ConfigModified(configSpecs, "-width", "-height", "-side", "-gap", "-slant", "-iconposition", "-rotate", "-tiers", "-tabwidth", "-scrolltabs", "-showsingletab", "-closebutton", "-justify", "-iconposition", (char *)NULL)) { setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); } if ((setPtr->reqHeight > 0) && (setPtr->reqWidth > 0)) { Tk_GeometryRequest(setPtr->tkwin, setPtr->reqWidth, setPtr->reqHeight); } /* * GC for focus highlight. */ gcMask = GCForeground; gcValues.foreground = setPtr->highlightColor->pixel; newGC = Tk_GetGC(setPtr->tkwin, gcMask, &gcValues); if (setPtr->highlightGC != NULL) { Tk_FreeGC(setPtr->display, setPtr->highlightGC); } setPtr->highlightGC = newGC; if (setPtr->bg != NULL) { Blt_SetBackgroundChangedProc(setPtr->bg, BackgroundChangedProc, setPtr); } /* * GC for active line. */ gcMask = GCForeground | GCLineWidth | GCLineStyle | GCCapStyle; gcValues.foreground = setPtr->defStyle.textColor->pixel; gcValues.line_width = 0; gcValues.cap_style = CapProjecting; gcValues.line_style = (LineIsDashed(setPtr->defStyle.dashes)) ? LineOnOffDash : LineSolid; newGC = Blt_GetPrivateGC(setPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(setPtr->defStyle.dashes)) { setPtr->defStyle.dashes.offset = 2; Blt_SetDashes(setPtr->display, newGC, &setPtr->defStyle.dashes); } if (setPtr->defStyle.activeGC != NULL) { Blt_FreePrivateGC(setPtr->display, setPtr->defStyle.activeGC); } setPtr->defStyle.activeGC = newGC; setPtr->angle = FMOD(setPtr->angle, 360.0); if (setPtr->angle < 0.0) { setPtr->angle += 360.0; } setPtr->quad = (int)(setPtr->angle / 90.0); setPtr->inset = setPtr->highlightWidth + setPtr->borderWidth + setPtr->outerPad; #ifndef notdef if (Blt_ConfigModified(configSpecs, "-font", "-*foreground", "-rotate", "-*background", "-side", "-iconposition", "-tiers", "-tabwidth", (char *)NULL)) { Tab *tabPtr; for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { ConfigureTab(setPtr, tabPtr); } setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); } #endif /* Swap slant flags if side is left. */ slantLeft = slantRight = FALSE; if (setPtr->reqSlant & SLANT_LEFT) { slantLeft = TRUE; } if (setPtr->reqSlant & SLANT_RIGHT) { slantRight = TRUE; } if (setPtr->side & SIDE_LEFT) { SWAP(slantLeft, slantRight); } setPtr->flags &= ~SLANT_BOTH; if (slantLeft) { setPtr->flags |= SLANT_LEFT; } if (slantRight) { setPtr->flags |= SLANT_RIGHT; } setPtr->inset2 = setPtr->defStyle.borderWidth + setPtr->corner; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Tabset operations * *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Selects the tab to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ActivateOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; const char *string; string = Tcl_GetString(objv[2]); if (string[0] == '\0') { tabPtr = NULL; } else if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr != NULL) && (tabPtr->flags & (HIDE|DISABLED))) { tabPtr = NULL; } if (tabPtr != setPtr->activePtr) { setPtr->activePtr = tabPtr; EventuallyRedraw(setPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Adds a new tab to the tabset widget. The tab is automatically * placed on the end of the tab list. * * .t add ?label? ?option-value...? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AddOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; const char *string; string = NULL; if (objc > 2) { const char *name; name = Tcl_GetString(objv[2]); if (name[0] != '-') { string = name; objc--, objv++; } } tabPtr = NewTab(interp, setPtr, string); if (tabPtr == NULL) { return TCL_ERROR; } iconOption.clientData = setPtr; if (Blt_ConfigureComponentFromObj(interp, setPtr->tkwin, tabPtr->name, "Tab", tabSpecs, objc-2, objv+2, (char *)tabPtr, 0) != TCL_OK) { DestroyTab(setPtr, tabPtr); return TCL_ERROR; } if (ConfigureTab(setPtr, tabPtr) != TCL_OK) { DestroyTab(setPtr, tabPtr); return TCL_ERROR; } tabPtr->link = Blt_Chain_Append(setPtr->chain, tabPtr); if (setPtr->plusPtr != NULL) { Blt_ChainLink link; /* Move plus tab to the end. */ link = setPtr->plusPtr->link; Blt_Chain_UnlinkLink(setPtr->chain, link); Blt_Chain_AppendLink(setPtr->chain, link); } ReindexTabs(setPtr); setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), tabPtr->name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BindOp -- * * .t bind index sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData tag; if (objc == 2) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr, *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { objPtr = Blt_GetHashValue(hPtr); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } tag = MakeBindTag(setPtr, Tcl_GetString(objv[2])); return Blt_ConfigureBindingsFromObj(interp, setPtr->bindTable, tag, objc - 3, objv + 3); } /* *--------------------------------------------------------------------------- * * ButtonActivateOp -- * * This procedure is called to highlight the button. * * .h button activate tab * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonActivateOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; const char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { tabPtr = NULL; } else if (GetTabFromObj(interp, setPtr, objv[3], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr != NULL) && (tabPtr->flags & (HIDE|DISABLED))) { tabPtr = NULL; } if (tabPtr != setPtr->activeButtonPtr) { setPtr->activeButtonPtr = tabPtr; EventuallyRedraw(setPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonCgetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = setPtr; return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, buttonSpecs, (char *)&setPtr->closeButton, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ButtonConfigureOp -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ButtonConfigureOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = setPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, buttonSpecs, (char *)&setPtr->closeButton, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, buttonSpecs, (char *)&setPtr->closeButton, objv[2], 0); } if (ConfigureButton(interp, setPtr, objc - 3, objv + 3, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= REDRAW_ALL; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonOp -- * * This procedure handles tab operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec buttonOps[] = { {"activate", 1, ButtonActivateOp, 4, 4, "tab" }, {"cget", 2, ButtonCgetOp, 4, 4, "option",}, {"configure", 2, ButtonConfigureOp, 3, 0, "?option value?...",}, }; static int nButtonOps = sizeof(buttonOps) / sizeof(Blt_OpSpec); static int ButtonOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TabsetCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nButtonOps, buttonOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (setPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = setPtr; return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, configSpecs, (char *)setPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * CloseOp -- * * Invokes a TCL command when a tab is closed. * * .t close tab * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CloseOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; Tcl_Obj *cmdObjPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr != NULL) && (tabPtr->flags & (HIDE|DISABLED))) { return TCL_OK; } cmdObjPtr = (tabPtr->closeObjPtr == NULL) ? setPtr->closeObjPtr : tabPtr->closeObjPtr; if (cmdObjPtr != NULL) { int result; cmdObjPtr = Tcl_DuplicateObj(cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, Tcl_NewIntObj(tabPtr->index)); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); return result; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = setPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, configSpecs, (char *)setPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, configSpecs, (char *)setPtr, objv[2], 0); } if (ConfigureTabset(interp, setPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= REDRAW_ALL; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes tab from the set. Deletes either a range of tabs or a single * node. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable delTable; int i; Blt_InitHashTable(&delTable, BLT_ONE_WORD_KEYS); for (i = 2; i < objc; i++) { TabIterator iter; Tab *tabPtr; if (GetTabIterator(interp, setPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&delTable, tabPtr, &isNew); Blt_SetHashValue(hPtr, tabPtr); } } if (delTable.numEntries > 0) { Blt_HashSearch iter; Blt_HashEntry *hPtr; for (hPtr = Blt_FirstHashEntry(&delTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tab *tabPtr; tabPtr = Blt_GetHashValue(hPtr); DestroyTab(setPtr, tabPtr); } ReindexTabs(setPtr); setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); } Blt_DeleteHashTable(&delTable); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DockallOp -- * * .h dockall * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DockallOp(Tabset *bookPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(bookPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Tab *tabPtr; tabPtr = Blt_Chain_GetValue(link); if (tabPtr->container != NULL) { Tcl_EventuallyFree(tabPtr, DestroyTearoff); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Converts a string representing a tab index. * * Results: * A standard TCL result. Interp->result will contain the identifier of * each index found. If an index could not be found, then the serial * identifier will be the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExistsOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; int state; state = FALSE; if (GetTabFromObj(NULL, setPtr, objv[2], &tabPtr) == TCL_OK) { if (tabPtr != NULL) { state = TRUE; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), state); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExtentsOp -- * * Returns the extents of the tab in root coordinates. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExtentsOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if (tabPtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[2]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (tabPtr->flags & ONSCREEN) { Tcl_Obj *listObjPtr, *objPtr; int rootX, rootY; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tk_GetRootCoords(setPtr->tkwin, &rootX, &rootY); objPtr = Tcl_NewIntObj(tabPtr->screenX + rootX); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(tabPtr->screenY + rootY); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(tabPtr->screenX + rootX + tabPtr->screenWidth); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(tabPtr->screenY + rootY + tabPtr->screenHeight); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FocusOp -- * * Sets focus on the specified tab. A dotted outline will be drawn * around this tab. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FocusOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; long index; if (objc == 3) { if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr != NULL) && ((tabPtr->flags & (DISABLED|HIDE)) == 0)) { setPtr->focusPtr = tabPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); EventuallyRedraw(setPtr); } } index = -1; if (setPtr->focusPtr != NULL) { index = setPtr->focusPtr->index; } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Converts a string representing a tab index. * * Results: * A standard TCL result. Interp->result will contain the identifier of * each index found. If an index could not be found, then the serial * identifier will be the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; int index; index = -1; if (GetTabFromObj(NULL, setPtr, objv[2], &tabPtr) == TCL_OK) { if (tabPtr != NULL) { index = tabPtr->index; } } Tcl_SetIntObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IdOp -- * * Converts a tab index into the tab identifier. * * Results: * A standard TCL result. Interp->result will contain the identifier of * each index found. If an index could not be found, then the serial * identifier will be the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IdOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if (tabPtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[2]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), tabPtr->name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Add new entries into a tab set. * * .t insert position ?label? option-value label option-value... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InsertOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; Blt_ChainLink link, before; char c; const char *string; string = Tcl_GetString(objv[2]); c = string[0]; if ((c == 'e') && (strcmp(string, "end") == 0)) { before = NULL; } else if (isdigit(UCHAR(c))) { int pos; if (Tcl_GetIntFromObj(interp, objv[2], &pos) != TCL_OK) { return TCL_ERROR; } if (pos < 0) { before = Blt_Chain_FirstLink(setPtr->chain); } else if (pos > Blt_Chain_GetLength(setPtr->chain)) { before = NULL; } else { before = Blt_Chain_GetNthLink(setPtr->chain, pos); } } else { Tab *beforePtr; if (GetTabFromObj(interp, setPtr, objv[2], &beforePtr) != TCL_OK) { return TCL_ERROR; } if (beforePtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[2]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } before = beforePtr->link; } string = NULL; if (objc > 3) { const char *name; name = Tcl_GetString(objv[3]); if (name[0] != '-') { string = name; objc--, objv++; } } tabPtr = NewTab(interp, setPtr, string); if (tabPtr == NULL) { return TCL_ERROR; } setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); iconOption.clientData = setPtr; if (Blt_ConfigureComponentFromObj(interp, setPtr->tkwin, tabPtr->name, "Tab", tabSpecs, objc - 3, objv + 3, (char *)tabPtr, 0) != TCL_OK) { DestroyTab(setPtr, tabPtr); return TCL_ERROR; } if (ConfigureTab(setPtr, tabPtr) != TCL_OK) { DestroyTab(setPtr, tabPtr); return TCL_ERROR; } link = Blt_Chain_NewLink(); if (before != NULL) { Blt_Chain_LinkBefore(setPtr->chain, link, before); } else { Blt_Chain_AppendLink(setPtr->chain, link); } tabPtr->link = link; Blt_Chain_SetValue(link, tabPtr); if (setPtr->plusPtr != NULL) { /* Move plus tab to the end. */ link = setPtr->plusPtr->link; Blt_Chain_UnlinkLink(setPtr->chain, link); Blt_Chain_AppendLink(setPtr->chain, link); } ReindexTabs(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), tabPtr->name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * This procedure is called to invoke a selection command. * * .h invoke index * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set; old resources get freed, if there were any. The widget is * redisplayed if needed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InvokeOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; Tcl_Obj *cmdObjPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr == NULL) || (tabPtr->flags & (DISABLED|HIDE))) { return TCL_OK; } cmdObjPtr = GETATTR(tabPtr, cmdObjPtr); if (cmdObjPtr != NULL) { Tcl_Obj **args; Tcl_Obj **cmdv; int cmdc; int i; int result; if (Tcl_ListObjGetElements(interp, cmdObjPtr, &cmdc, &cmdv) != TCL_OK) { return TCL_ERROR; } args = Blt_AssertMalloc(sizeof(Tcl_Obj *) * (cmdc + 1)); for (i = 0; i < cmdc; i++) { args[i] = cmdv[i]; } args[i] = Tcl_NewIntObj(tabPtr->index); result = Blt_GlobalEvalObjv(interp, cmdc + 1, args); Blt_Free(args); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * MoveOp -- * * Moves a tab to a new location. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MoveOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr, *fromPtr; char c; const char *string; int isBefore; int length; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr == NULL) || (tabPtr->flags & DISABLED)) { return TCL_OK; } string = Tcl_GetStringFromObj(objv[3], &length); c = string[0]; if ((c == 'b') && (strncmp(string, "before", length) == 0)) { isBefore = TRUE; } else if ((c == 'a') && (strncmp(string, "after", length) == 0)) { isBefore = FALSE; } else { Tcl_AppendResult(interp, "bad key word \"", string, "\": should be \"after\" or \"before\"", (char *)NULL); return TCL_ERROR; } if (GetTabFromObj(interp, setPtr, objv[4], &fromPtr) != TCL_OK) { return TCL_ERROR; } if (fromPtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[4]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (tabPtr == fromPtr) { return TCL_OK; } Blt_Chain_UnlinkLink(setPtr->chain, tabPtr->link); if (isBefore) { Blt_Chain_LinkBefore(setPtr->chain, tabPtr->link, fromPtr->link); } else { Blt_Chain_LinkAfter(setPtr->chain, tabPtr->link, fromPtr->link); } setPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | REDRAW_ALL); EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * .h names pattern * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 2) { Tab *tabPtr; for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tabPtr->name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Tab *tabPtr; for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { int i; for (i = 2; i < objc; i++) { if (Tcl_StringMatch(tabPtr->name, Tcl_GetString(objv[i]))) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tabPtr->name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int NearestOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; /* Screen coordinates of the test point. */ Tab *tabPtr; if ((Tk_GetPixelsFromObj(interp, setPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, setPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (setPtr->nVisible > 0) { tabPtr = (Tab *)PickTabProc(setPtr, x, y, NULL); if ((tabPtr != NULL) && ((tabPtr->flags & DISABLED) == 0)) { Tcl_SetStringObj(Tcl_GetObjResult(interp), tabPtr->name, -1); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectOp -- * * This procedure is called to select a tab. * * .h select index * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, * etc. get set; old resources get freed, if there were any. * The widget is redisplayed if needed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr == NULL) || (tabPtr->flags & (HIDE|DISABLED))) { return TCL_OK; } if ((setPtr->selectPtr != NULL) && (setPtr->selectPtr != tabPtr) && (setPtr->selectPtr->tkwin != NULL)) { if (setPtr->selectPtr->container == NULL) { if (Tk_IsMapped(setPtr->selectPtr->tkwin)) { Tk_UnmapWindow(setPtr->selectPtr->tkwin); } } else { /* Redraw now unselected container. */ EventuallyRedrawTearoff(setPtr->selectPtr); } } setPtr->selectPtr = tabPtr; if ((setPtr->nTiers > 1) && (tabPtr->tier != setPtr->startPtr->tier)) { RenumberTiers(setPtr, tabPtr); Blt_PickCurrentItem(setPtr->bindTable); } setPtr->flags |= SCROLL_PENDING; if (tabPtr->container != NULL) { EventuallyRedrawTearoff(tabPtr); } EventuallyRedraw(setPtr); return TCL_OK; } static int ViewOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width; width = VPORTWIDTH(setPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)setPtr->scrollOffset / setPtr->worldWidth; objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(setPtr->scrollOffset + width) / setPtr->worldWidth; objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &setPtr->scrollOffset, setPtr->worldWidth, width, setPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } static void AdoptWindow(ClientData clientData) { Tab *tabPtr = clientData; int x, y; Tabset *setPtr = tabPtr->setPtr; x = setPtr->inset + setPtr->inset2 + tabPtr->padLeft; #define TEAR_OFF_TAB_SIZE 5 y = setPtr->inset + setPtr->inset2 + setPtr->outerPad + TEAR_OFF_TAB_SIZE + tabPtr->padTop; if (setPtr->nTiers == 1) { y += setPtr->ySelectPad; } Blt_RelinkWindow(tabPtr->tkwin, tabPtr->container, x, y); Tk_MapWindow(tabPtr->tkwin); } static void DestroyTearoff(DestroyData dataPtr) { Tab *tabPtr = (Tab *)dataPtr; if (tabPtr->container != NULL) { Tabset *setPtr; Tk_Window tkwin; setPtr = tabPtr->setPtr; tkwin = tabPtr->container; if (tabPtr->flags & TEAROFF_REDRAW) { Tcl_CancelIdleCall(DisplayTearoff, tabPtr); } Tk_DeleteEventHandler(tkwin, StructureNotifyMask, TearoffEventProc, tabPtr); if (tabPtr->tkwin != NULL) { XRectangle rect; GetWindowRectangle(tabPtr, setPtr->tkwin, FALSE, &rect); Blt_RelinkWindow(tabPtr->tkwin, setPtr->tkwin, rect.x, rect.y); if (tabPtr == setPtr->selectPtr) { ArrangeWindow(tabPtr->tkwin, &rect, TRUE); } else { Tk_UnmapWindow(tabPtr->tkwin); } } Tk_DestroyWindow(tkwin); tabPtr->container = NULL; } } static int NewTearoff(Tabset *setPtr, Tcl_Obj *objPtr, Tab *tabPtr) { Tk_Window tkwin; const char *name; int w, h; name = Tcl_GetString(objPtr); tkwin = Tk_CreateWindowFromPath(setPtr->interp, setPtr->tkwin, name, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } tabPtr->container = tkwin; if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } Tk_SetClass(tkwin, "Tearoff"); Tk_CreateEventHandler(tkwin, (ExposureMask | StructureNotifyMask), TearoffEventProc, tabPtr); if (Tk_WindowId(tabPtr->tkwin) == None) { Tk_MakeWindowExist(tabPtr->tkwin); } w = Tk_Width(tabPtr->tkwin); if (w < 2) { w = (tabPtr->reqSlaveWidth > 0) ? tabPtr->reqSlaveWidth : Tk_ReqWidth(tabPtr->tkwin); } w += PADDING(tabPtr->xPad) + 2 * Tk_Changes(tabPtr->tkwin)->border_width; w += 2 * (setPtr->inset2 + setPtr->inset); #define TEAR_OFF_TAB_SIZE 5 h = Tk_Height(tabPtr->tkwin); if (h < 2) { h = (tabPtr->reqSlaveHeight > 0) ? tabPtr->reqSlaveHeight : Tk_ReqHeight(tabPtr->tkwin); } h += PADDING(tabPtr->yPad) + 2 * Tk_Changes(tabPtr->tkwin)->border_width; h += setPtr->inset + setPtr->inset2 + TEAR_OFF_TAB_SIZE + setPtr->outerPad; if (setPtr->nTiers == 1) { h += setPtr->ySelectPad; } Tk_GeometryRequest(tkwin, w, h); Tk_UnmapWindow(tabPtr->tkwin); /* Tk_MoveWindow(tabPtr->tkwin, 0, 0); */ #ifdef WIN32 AdoptWindow(tabPtr); #else Tcl_DoWhenIdle(AdoptWindow, tabPtr); #endif Tcl_SetStringObj(Tcl_GetObjResult(setPtr->interp), Tk_PathName(tkwin), -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TabCgetOp -- * * .h tab cget index option * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TabCgetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; if (GetTabFromObj(interp, setPtr, objv[3], &tabPtr) != TCL_OK) { return TCL_ERROR; } if (tabPtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[3]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } iconOption.clientData = setPtr; return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, tabSpecs, (char *)tabPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * TabConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure the options for one or more tabs in * the widget. * * .h tab configure index ?index...? ?option value?... * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set; old resources get freed, if there were any. The widget is * redisplayed if needed. * *--------------------------------------------------------------------------- */ static int TabConfigureOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; TabIterator iter; iconOption.clientData = setPtr; if ((objc == 4) || (objc == 5)) { if (GetTabFromObj(interp, setPtr, objv[3], &tabPtr) != TCL_OK) { return TCL_ERROR; /* Can't find node. */ } if (tabPtr == NULL) { Tcl_AppendResult(interp, "can't find a tab \"", Tcl_GetString(objv[3]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, tabSpecs, (char *)tabPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, tabSpecs, (char *)tabPtr, objv[4], 0); } } if (GetTabIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; /* Can't find node. */ } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { int result; Tcl_Preserve(tabPtr); result = Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, tabSpecs, objc - 4, objv + 4, (char *)tabPtr, BLT_CONFIG_OBJV_ONLY); Tcl_Release(tabPtr); if (result == TCL_ERROR) { return TCL_ERROR; } if (ConfigureTab(setPtr, tabPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TabOp -- * * This procedure handles tab operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec tabOps[] = { {"cget", 2, TabCgetOp, 5, 5, "tab option",}, {"configure", 2, TabConfigureOp, 4, 0, "tab ?option value?...",}, }; static int nTabOps = sizeof(tabOps) / sizeof(Blt_OpSpec); static int TabOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TabsetCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTabOps, tabOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (setPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * PerforationActivateOp -- * * This procedure is called to highlight the perforation. * * .h perforation highlight boolean * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PerforationActivateOp( Tabset *setPtr, Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { int bool; if (Tcl_GetBooleanFromObj(interp, objv[3], &bool) != TCL_OK) { return TCL_ERROR; } if (bool) { setPtr->flags |= ACTIVE_PERFORATION; } else { setPtr->flags &= ~ACTIVE_PERFORATION; } EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PerforationInvokeOp -- * * This procedure is called to invoke a perforation command. * * .t perforation invoke * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PerforationInvokeOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *objPtr; Tab *tabPtr; if (setPtr->selectPtr == NULL) { return TCL_OK; } tabPtr = setPtr->selectPtr; objPtr = GETATTR(tabPtr, perfCmdObjPtr); if (objPtr != NULL) { Tcl_Obj **args; Tcl_Obj **cmdv; int cmdc; int i; int result; if (Tcl_ListObjGetElements(interp, objPtr, &cmdc, &cmdv) != TCL_OK) { return TCL_ERROR; } args = Blt_AssertMalloc(sizeof(Tcl_Obj *) * (cmdc + 1)); for (i = 0; i < cmdc; i++) { args[i] = cmdv[i]; } args[i] = Tcl_NewIntObj(tabPtr->index); result = Blt_GlobalEvalObjv(interp, cmdc + 1, args); Blt_Free(args); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PerforationOp -- * * This procedure handles tab operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec perforationOps[] = { {"activate", 1, PerforationActivateOp, 4, 4, "boolean" }, {"invoke", 1, PerforationInvokeOp, 3, 3, "",}, }; static int nPerforationOps = sizeof(perforationOps) / sizeof(Blt_OpSpec); static int PerforationOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TabsetCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nPerforationOps, perforationOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (setPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char c; const char *string; int length; int oper; int x, y; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, setPtr->tkwin, objv[3], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, setPtr->tkwin, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } if (oper == SCAN_MARK) { if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { setPtr->scanAnchor = y; } else { setPtr->scanAnchor = x; } setPtr->scanOffset = setPtr->scrollOffset; } else { int offset, delta; if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { delta = setPtr->scanAnchor - y; } else { delta = setPtr->scanAnchor - x; } offset = setPtr->scanOffset + (10 * delta); offset = Blt_AdjustViewport(offset, setPtr->worldWidth, VPORTWIDTH(setPtr), setPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX); setPtr->scrollOffset = offset; setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); } return TCL_OK; } /*ARGSUSED*/ static int SeeOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if (tabPtr != NULL) { int left, right, width; width = VPORTWIDTH(setPtr); left = setPtr->scrollOffset + setPtr->xSelectPad; right = setPtr->scrollOffset + width - setPtr->xSelectPad; /* If the tab is partially obscured, scroll so that it's * entirely in view. */ if (tabPtr->worldX < left) { setPtr->scrollOffset = tabPtr->worldX; if (tabPtr->index > 0) { setPtr->scrollOffset -= TAB_SCROLL_OFFSET; } } else if ((tabPtr->worldX + tabPtr->worldWidth) >= right) { Blt_ChainLink link; setPtr->scrollOffset = tabPtr->worldX + tabPtr->worldWidth - (width - 2 * setPtr->xSelectPad); link = Blt_Chain_NextLink(tabPtr->link); if (link != NULL) { Tab *nextPtr; nextPtr = Blt_Chain_GetValue(link); if (nextPtr->tier == tabPtr->tier) { setPtr->scrollOffset += TAB_SCROLL_OFFSET; } } } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); } return TCL_OK; } /*ARGSUSED*/ static int SizeOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int nTabs; nTabs = Blt_Chain_GetLength(setPtr->chain); Tcl_SetIntObj(Tcl_GetObjResult(interp), nTabs); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagAddOp -- * * .t tag add tagName tab1 tab2 tab2 tab4 * *--------------------------------------------------------------------------- */ static int TagAddOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *tag; long tagId; tag = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &tagId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't add reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } if (objc == 4) { /* No nodes specified. Just add the tag. */ AddTag(setPtr, NULL, tag); } else { int i; for (i = 4; i < objc; i++) { Tab *tabPtr; TabIterator iter; if (GetTabIterator(interp, setPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { AddTag(setPtr, tabPtr, tag); } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagDeleteOp -- * * .t delete tagName tab1 tab2 tab3 * *--------------------------------------------------------------------------- */ static int TagDeleteOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *tag; Blt_HashTable *tablePtr; long tagId; tag = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &tagId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't delete reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } tablePtr = GetTagTable(setPtr, tag); if (tablePtr != NULL) { int i; for (i = 4; i < objc; i++) { Tab *tabPtr; TabIterator iter; if (GetTabIterator(interp, setPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)tabPtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagExistsOp -- * * Returns the existence of the one or more tags in the given node. If * the node has any the tags, true is return in the interpreter. * * .t tag exists tab tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagExistsOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; TabIterator iter; if (GetTabIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { const char *tag; Tab *tabPtr; tag = Tcl_GetString(objv[i]); for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { if (HasTag(tabPtr, tag)) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), TRUE); return TCL_OK; } } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), FALSE); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagForgetOp -- * * Removes the given tags from all tabs. * * .ts tab forget tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagForgetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { const char *tag; long tagId; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &tagId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } ForgetTag(setPtr, tag); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagGetOp -- * * Returns tag names for a given node. If one of more pattern arguments * are provided, then only those matching tags are returned. * * .t tag get tab pat1 pat2... * *--------------------------------------------------------------------------- */ static int TagGetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; TabIterator iter; Tcl_Obj *listObjPtr; if (GetTabIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { if (objc == 4) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(tablePtr, (char *)tabPtr) != NULL) { const char *tag; Tcl_Obj *objPtr; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("all", 3)); } else { int i; /* Check if we need to add the special tags "all" */ for (i = 4; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch("all", pattern)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj("all", 3); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } /* Now process any standard tags. */ for (i = 4; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; const char *pattern; pattern = Tcl_GetString(objv[i]); for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { const char *tag; Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); if (!Tcl_StringMatch(tag, pattern)) { continue; } if (Blt_FindHashEntry(tablePtr, (char *)tabPtr) != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr,objPtr); } } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagNamesOp -- * * Returns the names of all the tags in the tabset. If one of more node * arguments are provided, then only the tags found in those nodes are * returned. * * .t tag names tab tab tab... * *--------------------------------------------------------------------------- */ static int TagNamesOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr, *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); objPtr = Tcl_NewStringObj("all", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { const char *tag; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_HashTable uniqTable; int i; Blt_InitHashTable(&uniqTable, BLT_STRING_KEYS); for (i = 3; i < objc; i++) { TabIterator iter; Tab *tabPtr; if (GetTabIterator(interp, setPtr, objPtr, &iter) != TCL_OK) { goto error; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { const char *tag; Blt_HashTable *tablePtr; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); tablePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(tablePtr, tabPtr) != NULL) { int isNew; Blt_CreateHashEntry(&uniqTable, tag, &isNew); } } } } { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&uniqTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { objPtr = Tcl_NewStringObj(Blt_GetHashKey(&uniqTable, hPtr), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_DeleteHashTable(&uniqTable); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: Tcl_DecrRefCount(listObjPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagIndicesOp -- * * Returns the indices associated with the given tags. The indices * returned will represent the union of tabs for all the given tags. * * .t tag indices tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ static int TagIndicesOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable tabTable; int i; Blt_InitHashTable(&tabTable, BLT_ONE_WORD_KEYS); for (i = 3; i < objc; i++) { const char *tag; long tagId; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &tagId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); goto error; } if (strcmp(tag, "all") == 0) { break; } else { Blt_HashTable *tablePtr; tablePtr = GetTagTable(setPtr, tag); if (tablePtr != NULL) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tab *tabPtr; int isNew; tabPtr = Blt_GetHashValue(hPtr); if (tabPtr != NULL) { Blt_CreateHashEntry(&tabTable, (char *)tabPtr, &isNew); } } continue; } } Tcl_AppendResult(interp, "can't find a tag \"", tag, "\"", (char *)NULL); goto error; } { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&tabTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tab *tabPtr; Tcl_Obj *objPtr; tabPtr = (Tab *)Blt_GetHashKey(&tabTable, hPtr); objPtr = Tcl_NewLongObj(tabPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_DeleteHashTable(&tabTable); return TCL_OK; error: Blt_DeleteHashTable(&tabTable); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagSetOp -- * * Sets one or more tags for a given tab. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all"). * * .t tag set tab tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagSetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; TabIterator iter; if (GetTabIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { const char *tag; long tagId; Tab *tabPtr; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &tagId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't add reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { AddTag(setPtr, tabPtr, tag); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagUnsetOp -- * * Removes one or more tags from a given tab. If a tag doesn't exist or * is a reserved tag ("all"), nothing will be done and no error * message will be returned. * * .t tag unset tab tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagUnsetOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; TabIterator iter; if (GetTabIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (tabPtr = FirstTaggedTab(&iter); tabPtr != NULL; tabPtr = NextTaggedTab(&iter)) { int i; for (i = 4; i < objc; i++) { RemoveTag(tabPtr, Tcl_GetString(objv[i])); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagOp -- * * This procedure is invoked to process tag operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec tagOps[] = { {"add", 1, TagAddOp, 4, 0, "tab ?tag...?",}, {"delete", 1, TagDeleteOp, 4, 0, "tab ?tag...?",}, {"exists", 1, TagExistsOp, 4, 0, "tab ?tag...?",}, {"forget", 1, TagForgetOp, 3, 0, "?tag...?",}, {"get", 1, TagGetOp, 4, 0, "tab ?pattern...?",}, {"indices", 1, TagIndicesOp, 3, 0, "?tag...?",}, {"names", 2, TagNamesOp, 3, 0, "?tab...?",}, {"set", 1, TagSetOp, 4, 0, "tab ?tag...",}, {"unset", 1, TagUnsetOp, 4, 0, "tab ?tag...",}, }; static int nTagOps = sizeof(tagOps) / sizeof(Blt_OpSpec); static int TagOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TabsetCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTagOps, tagOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(setPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * TearoffOp -- * * .h tearoff index ?title? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TearoffOp(Tabset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tab *tabPtr; Tk_Window tkwin; const char *string; int result; if (GetTabFromObj(interp, setPtr, objv[2], &tabPtr) != TCL_OK) { return TCL_ERROR; } if ((tabPtr == NULL) || (tabPtr->tkwin == NULL) || (tabPtr->flags & (DISABLED|HIDE))) { return TCL_OK; /* No-op */ } if (objc == 3) { Tk_Window parent; parent = (tabPtr->container == NULL) ? setPtr->tkwin : tabPtr->container; Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(parent), -1); return TCL_OK; } Tcl_Preserve(tabPtr); result = TCL_OK; string = Tcl_GetString(objv[3]); tkwin = Tk_NameToWindow(interp, string, setPtr->tkwin); Tcl_ResetResult(interp); if (tabPtr->container != NULL) { Tcl_EventuallyFree(tabPtr, DestroyTearoff); } if ((tkwin != setPtr->tkwin) && (tabPtr->container == NULL)) { result = NewTearoff(setPtr, objv[3], tabPtr); } Tcl_Release(tabPtr); EventuallyRedraw(setPtr); return result; } static void ComputeTabGeometry(Tabset *setPtr, Tab *tabPtr) { Blt_Font font; int iconWidth0, iconHeight0; unsigned int w, h; font = GETATTR(tabPtr, font); w = h = 0; if (tabPtr->text != NULL) { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); Blt_Ts_SetPadding(ts, 2, 2, 0, 0); if (tabPtr->layoutPtr != NULL) { Blt_Free(tabPtr->layoutPtr); } tabPtr->layoutPtr = Blt_Ts_CreateLayout(tabPtr->text, -1, &ts); tabPtr->textWidth0 = ODD(tabPtr->layoutPtr->width); tabPtr->textHeight0 = ODD(tabPtr->layoutPtr->height); } else { tabPtr->textWidth0 = tabPtr->textHeight0 = 0; } if (tabPtr->icon != NULL) { iconWidth0 = IconWidth(tabPtr->icon); iconHeight0 = IconHeight(tabPtr->icon); } else { iconWidth0 = iconHeight0 = 0; } w = iconWidth0 + tabPtr->textWidth0 + PADDING(tabPtr->iPadX); if ((iconWidth0 > 0) && (tabPtr->textWidth0 > 0)) { w += LABEL_PAD; } h = MAX(iconHeight0, tabPtr->textHeight0) + PADDING(tabPtr->iPadY); if ((setPtr->flags & CLOSE_NEEDED) && (setPtr->plusPtr != tabPtr)) { w += CLOSE_WIDTH + LABEL_PAD + 2 * setPtr->closeButton.borderWidth; } tabPtr->labelWidth0 = w; tabPtr->labelHeight0 = h; } /* *--------------------------------------------------------------------------- * * ComputeWorldGeometry -- * * Compute the sizes of the tabset and each tab in world coordinates. * World coordinates are not rotated according to the side the widget * where the tabs are located. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ComputeWorldGeometry(Tabset *setPtr) { int count; int maxPageWidth, maxPageHeight; int maxTabWidth, maxTabHeight; Tab *tabPtr; maxPageWidth = maxPageHeight = 0; maxTabWidth = maxTabHeight = 0; count = 0; /* * Step 1: Figure out the maximum area needed for a label and a * page. Both the label and page dimensions are adjusted * for orientation. In addition, reset the visibility * flags and reorder the tabs. */ for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { /* Reset visibility flag and order of tabs. */ tabPtr->flags &= ~ONSCREEN; if (tabPtr->flags & HIDE) { continue; } ComputeTabGeometry(setPtr, tabPtr); count++; if (tabPtr->tkwin != NULL) { int w, h; w = GetReqWidth(tabPtr); if (maxPageWidth < w) { maxPageWidth = w; } h = GetReqHeight(tabPtr); if (maxPageHeight < h) { maxPageHeight = h; } } if (maxTabWidth < tabPtr->labelWidth0) { maxTabWidth = tabPtr->labelWidth0; } if (maxTabHeight < tabPtr->labelHeight0) { maxTabHeight = tabPtr->labelHeight0; } } setPtr->overlap = 0; /* * Step 2: Set the sizes for each tab. This is different * for constant and variable width tabs. Add the extra space * needed for slanted tabs, now that we know maximum tab * height. */ if (setPtr->reqTabWidth != TABWIDTH_VARIABLE) { int slant; Tab *tabPtr; int w, h; w = (setPtr->reqTabWidth > 0) ? setPtr->reqTabWidth : maxTabWidth; h = maxTabHeight; if ((setPtr->quad == ROTATE_90) || (setPtr->quad == ROTATE_270)) { SWAP(w, h); } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { SWAP(w, h); } slant = h; w += (setPtr->flags & SLANT_LEFT) ? slant : setPtr->inset2; w += (setPtr->flags & SLANT_RIGHT) ? slant : setPtr->inset2; if (setPtr->flags & SLANT_LEFT) { setPtr->overlap += slant / 2; } if (setPtr->flags & SLANT_RIGHT) { setPtr->overlap += slant / 2; } setPtr->tabWidth = w; setPtr->tabHeight = h; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { if (setPtr->plusPtr == tabPtr) { tabPtr->worldWidth = tabPtr->labelWidth0; tabPtr->worldWidth += (setPtr->flags & SLANT_LEFT) ? slant : setPtr->inset2; tabPtr->worldWidth += (setPtr->flags & SLANT_RIGHT) ? slant : setPtr->inset2; } else { tabPtr->worldWidth = w; } tabPtr->worldHeight = h; } } else { /* Variable width tabs. */ int slant; Tab *tabPtr; int tabWidth, tabHeight; int w, h; tabWidth = tabHeight = 0; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { w = tabPtr->labelWidth0; h = maxTabHeight; if ((setPtr->quad == ROTATE_90) || (setPtr->quad == ROTATE_270)) { SWAP(w, h); } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { SWAP(w, h); } slant = h; w += (setPtr->flags & SLANT_LEFT) ? slant : setPtr->inset2; w += (setPtr->flags & SLANT_RIGHT) ? slant : setPtr->inset2; tabPtr->worldWidth = w; tabPtr->worldHeight = h; if (tabWidth < w) { tabWidth = w; } if (tabHeight < h) { tabHeight = h; } } if (setPtr->flags & SLANT_LEFT) { setPtr->overlap += tabHeight / 2; } if (setPtr->flags & SLANT_RIGHT) { setPtr->overlap += tabHeight / 2; } setPtr->tabWidth = tabWidth; setPtr->tabHeight = tabHeight; } /* * Let the user override any page dimension. */ setPtr->pageWidth = maxPageWidth; setPtr->pageHeight = maxPageHeight; if (setPtr->reqPageWidth > 0) { setPtr->pageWidth = setPtr->reqPageWidth; } if (setPtr->reqPageHeight > 0) { setPtr->pageHeight = setPtr->reqPageHeight; } return count; } #ifdef notdef static int CompareTabSizes(const void *a, const void *b) { Tab *tab1Ptr, *tab2Ptr; tab1Ptr = *(Tab **)a; tab2Ptr = *(Tab **)b; if (tab1Ptr == setPtr->plusPtr) { return -1; } if (tab2Ptr == setPtr->plusPtr) { return 1; } return tab1Ptr->worldWidth - tab2Ptr->worldWidth; } /* * Two pass shrink. * 1) Any space beyond the normal size. * 2) Any space beyong the defined minimum. */ static void ShrinkTabs2(Tabset *setPtr, Tab *startPtr, int nTabs, int adjustment) { int x; int i; Tab *tabPtr; /* Sort tabs according to size. */ tabs = Blt_AssertMalloc(nTabs * sizeof(Tab *)); for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs); tabPtr = NextTab(tabPtr, HIDE), i++) { tabs[i] = tabPtr; } qsort(tabs, nTabs, sizeof(Tab *), CompareTabSizes); for (i = 1; i < tabIndex; i++) { avail = (tabs[i-1].worldWidth - tabs[i].worldWidth) * i; if (avail > adjustment) { avail = adjustment; } ration = (avail+(i-1))/ i; for (j = 0; j < i; j++) { if (adjustment > ration) { ration = adjustment; } tabs[j].worldWidth -= ration; adjustment -= ration; } accum += tabs[i].worldWidth - tabs[tabIndex].worldWidth; if (accum >= adjustment) { break; /* Have enough room. */ } } x = startPtr->tier; while (adjustment > 0) { int count; int ration; Tab *tabPtr; ration = adjustment / count; if (ration == 0) { ration = 1; } count = 0; for (i = 0; (i < nTabs) && (adjustment > 0); i++) { tabPtr = tabs[i]; if (tabPtr->worldWidth) tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { count++; } } ration = adjustment / count; if (ration == 0) { ration = 1; } for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs) && (adjustment > 0); tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { adjustment -= ration; tabPtr->worldWidth -= ration; assert(x == tabPtr->tier); } } } /* * Go back and reset the world X-coordinates of the tabs, * now that their widths have changed. */ x = 0; for (tabPtr = startPtr, i = 0; (i < nTabs) && (tabPtr != NULL); tabPtr = NextTab(tabPtr, HIDE), i++) { tabPtr->worldX = x; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; } } #endif static void ShrinkTabs(Tabset *setPtr, Tab *startPtr, int nTabs, int adjustment) { int x; int i; Tab *tabPtr; x = startPtr->tier; while (adjustment > 0) { int count; int ration; Tab *tabPtr; count = 0; for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs) && (adjustment > 0); tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { count++; } } ration = adjustment / count; if (ration == 0) { ration = 1; } for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs) && (adjustment > 0); tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { adjustment -= ration; tabPtr->worldWidth -= ration; assert(x == tabPtr->tier); } } } /* * Go back and reset the world X-coordinates of the tabs, * now that their widths have changed. */ x = 0; for (tabPtr = startPtr, i = 0; (i < nTabs) && (tabPtr != NULL); tabPtr = NextTab(tabPtr, HIDE), i++) { tabPtr->worldX = x; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; } } static void GrowTabs(Tabset *setPtr, Tab *startPtr, int nTabs, int adjustment) { int x; int i; Tab *tabPtr; x = startPtr->tier; while (adjustment > 0) { int count; int ration; Tab *tabPtr; count = 0; for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs) && (adjustment > 0); tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { count++; } } ration = adjustment / count; if (ration == 0) { ration = 1; } for (tabPtr = startPtr, i = 0; (tabPtr != NULL) && (i < nTabs) && (adjustment > 0); tabPtr = NextTab(tabPtr, HIDE), i++) { if (tabPtr != setPtr->plusPtr) { adjustment -= ration; tabPtr->worldWidth += ration; assert(x == tabPtr->tier); } } } /* * Go back and reset the world X-coordinates of the tabs, * now that their widths have changed. */ x = 0; for (tabPtr = startPtr, i = 0; (i < nTabs) && (tabPtr != NULL); tabPtr = NextTab(tabPtr, HIDE), i++) { tabPtr->worldX = x; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; } } static void AdjustTabSizes(Tabset *setPtr, int nTabs) { int tabsPerTier; int total, count, extra, plus; Tab *startPtr, *nextPtr; Blt_ChainLink link; Tab *tabPtr; int x, maxWidth; tabsPerTier = (nTabs + (setPtr->nTiers - 1)) / setPtr->nTiers; x = 0; link = NULL; maxWidth = 0; if (setPtr->reqTabWidth != TABWIDTH_VARIABLE) { link = Blt_Chain_FirstLink(setPtr->chain); count = 1; while (link != NULL) { int i; for (i = 0; i < tabsPerTier; i++) { tabPtr = Blt_Chain_GetValue(link); if ((tabPtr->flags & HIDE) == 0) { tabPtr->tier = count; tabPtr->worldX = x; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; if (x > maxWidth) { maxWidth = x; } } link = Blt_Chain_NextLink(link); if (link == NULL) { goto done; } } count++; x = 0; } } done: /* Add to tab widths to fill out row. */ if (((nTabs % tabsPerTier) != 0) && (setPtr->reqTabWidth != TABWIDTH_VARIABLE)) { return; } startPtr = NULL; count = total = 0; plus = 0; #ifndef notdef if (setPtr->plusPtr != NULL) { plus += setPtr->inset2 * 2; } #endif for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { if (startPtr == NULL) { startPtr = tabPtr; } count++; total += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; link = Blt_Chain_NextLink(tabPtr->link); if (link != NULL) { nextPtr = Blt_Chain_GetValue(link); if (tabPtr->tier == nextPtr->tier) { continue; } } total += setPtr->overlap; extra = setPtr->worldWidth - plus - total; assert(count > 0); if ((extra > 0) && (setPtr->nTiers > 1)) { GrowTabs(setPtr, startPtr, count, extra); } else if (extra < 0) { ShrinkTabs(setPtr, startPtr, count, -extra); } count = total = 0; startPtr = NULL; } } /* * * tabWidth = textWidth0 + gap + (2 * (pad + outerBW)); * * tabHeight = textHeight0 + 2 * (pad + outerBW) + topMargin; * */ static void ComputeLayout(Tabset *setPtr) { int width; Blt_ChainLink link; int x, extra; int nTiers, nTabs; setPtr->nTiers = 0; setPtr->pageTop = 0; setPtr->worldWidth = 1; nTabs = ComputeWorldGeometry(setPtr); if (nTabs == 0) { return; } /* Reset the pointers to the selected and starting tab. */ if (setPtr->selectPtr == NULL) { link = Blt_Chain_FirstLink(setPtr->chain); if (link != NULL) { setPtr->selectPtr = Blt_Chain_GetValue(link); } } if (setPtr->startPtr == NULL) { setPtr->startPtr = setPtr->selectPtr; } if (setPtr->focusPtr == NULL) { setPtr->focusPtr = setPtr->selectPtr; Blt_SetFocusItem(setPtr->bindTable, setPtr->focusPtr, NULL); } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { width = Tk_ReqHeight(setPtr->tkwin) - 2 * (setPtr->inset2 + setPtr->xSelectPad); } else { width = Tk_ReqWidth(setPtr->tkwin) - (2 * setPtr->inset) - setPtr->xSelectPad - setPtr->inset2; } setPtr->flags &= ~SCROLLING; if (setPtr->reqTiers > 1) { int total, maxWidth; Tab *tabPtr; /* Static multiple tier mode. */ /* Sum tab widths and determine the number of tiers needed. */ nTiers = 1; total = x = 0; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { if ((x + tabPtr->worldWidth) > width) { nTiers++; x = 0; } tabPtr->worldX = x; tabPtr->tier = nTiers; extra = tabPtr->worldWidth + setPtr->gap - setPtr->overlap; total += extra, x += extra; } maxWidth = width; if (nTiers > setPtr->reqTiers) { Tab *tabPtr; /* * The tabs do not fit into the requested number of tiers. * Go into scrolling mode. */ width = ((total + setPtr->tabWidth) / setPtr->reqTiers); x = 0; nTiers = 1; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->tier = nTiers; /* * Keep adding tabs to a tier until we overfill it. */ tabPtr->worldX = x; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; if (x > width) { nTiers++; if (x > maxWidth) { maxWidth = x; } x = 0; } } setPtr->flags |= SCROLLING; } setPtr->worldWidth = maxWidth; setPtr->nTiers = nTiers; if (nTiers > 1) { AdjustTabSizes(setPtr, nTabs); } if ((setPtr->flags & (SCROLLING|SCROLL_TABS)) == (SCROLLING|SCROLL_TABS)) { /* Do you add an offset ? */ setPtr->worldWidth += (setPtr->xSelectPad + setPtr->inset2); setPtr->worldWidth += setPtr->overlap; } else { if (VPORTWIDTH(setPtr) > 1) { setPtr->worldWidth = VPORTWIDTH(setPtr) - (setPtr->xSelectPad + setPtr->inset2); } } if (setPtr->selectPtr != NULL) { RenumberTiers(setPtr, setPtr->selectPtr); } } else { Tab *tabPtr; /* * Scrollable single tier mode. */ nTiers = 1; x = 0; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->tier = nTiers; tabPtr->worldX = x; tabPtr->worldY = 0; x += tabPtr->worldWidth + setPtr->gap - setPtr->overlap; } /* Subtract off the last gap. */ setPtr->worldWidth = x + setPtr->inset2 - setPtr->gap + setPtr->xSelectPad + setPtr->overlap; setPtr->flags |= SCROLLING; } setPtr->nTiers = nTiers; if (nTiers == 1) { /* We only need the extra space at top of the widget for selected tab * if there's only one tier. */ if ((setPtr->flags & (SCROLLING|SCROLL_TABS)) == SCROLLING) { if (VPORTWIDTH(setPtr) > 1) { setPtr->worldWidth = VPORTWIDTH(setPtr) - (setPtr->xSelectPad + setPtr->inset2); } AdjustTabSizes(setPtr, nTabs); } } setPtr->nTiers = nTiers; setPtr->pageTop = setPtr->inset + setPtr->inset2 + (setPtr->nTiers * setPtr->tabHeight); if (setPtr->nTiers == 1) { setPtr->pageTop += setPtr->ySelectPad; } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { Tab *tabPtr; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->screenWidth = (short int)setPtr->tabHeight; tabPtr->screenHeight = (short int)tabPtr->worldWidth; } } else { Tab *tabPtr; for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->screenWidth = (short int)tabPtr->worldWidth; tabPtr->screenHeight = (short int)setPtr->tabHeight; } } } static void ComputeVisibleTabs(Tabset *setPtr) { int nVisibleTabs; Tab *tabPtr; setPtr->nVisible = 0; if (Blt_Chain_GetLength(setPtr->chain) == 0) { return; } nVisibleTabs = 0; if (setPtr->flags & SCROLLING) { int width, offset; Tab *tabPtr; /* * Scrollable (single or multiple) tier mode. */ offset = setPtr->scrollOffset - (setPtr->outerPad + setPtr->xSelectPad); width = VPORTWIDTH(setPtr) + setPtr->scrollOffset + 2 * setPtr->outerPad; for (tabPtr = FirstTab(setPtr, 0); tabPtr != NULL; tabPtr = NextTab(tabPtr, 0)) { if (tabPtr->flags & HIDE) { tabPtr->flags &= ~ONSCREEN; continue; } if ((tabPtr->worldX >= width) || ((tabPtr->worldX + tabPtr->worldWidth) < offset)) { tabPtr->flags &= ~ONSCREEN; } else { tabPtr->flags |= ONSCREEN; nVisibleTabs++; } } } else { Tab *tabPtr; /* Static multiple tier mode. */ for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->flags |= ONSCREEN; nVisibleTabs++; } } for (tabPtr = FirstTab(setPtr, HIDE); tabPtr != NULL; tabPtr = NextTab(tabPtr, HIDE)) { tabPtr->screenX = tabPtr->screenY = -1000; if (tabPtr->flags & ONSCREEN) { WorldToScreen(setPtr, tabPtr->worldX, tabPtr->worldY, &tabPtr->screenX, &tabPtr->screenY); switch (setPtr->side) { case SIDE_RIGHT: tabPtr->screenX -= setPtr->tabHeight; break; case SIDE_BOTTOM: tabPtr->screenY -= setPtr->tabHeight; break; } } } setPtr->nVisible = nVisibleTabs; Blt_PickCurrentItem(setPtr->bindTable); } static void Draw3dFolder(Tabset *setPtr, Tab *tabPtr, Drawable drawable, int side, XPoint *points, int nPoints) { int relief, borderWidth; Blt_Background bg; if (tabPtr == setPtr->selectPtr) { bg = GETATTR(tabPtr, selBg); } else if ((tabPtr == setPtr->activePtr) || (tabPtr == setPtr->activeButtonPtr)) { bg = GETATTR(tabPtr, activeBg); } else if (tabPtr->bg != NULL) { bg = tabPtr->bg; } else { bg = setPtr->defStyle.bg; } relief = setPtr->defStyle.relief; if ((side == SIDE_RIGHT) || (side == SIDE_TOP)) { borderWidth = -setPtr->defStyle.borderWidth; if (relief == TK_RELIEF_SUNKEN) { relief = TK_RELIEF_RAISED; } else if (relief == TK_RELIEF_RAISED) { relief = TK_RELIEF_SUNKEN; } } else { borderWidth = setPtr->defStyle.borderWidth; } Blt_FillBackgroundPolygon(setPtr->tkwin, drawable, bg, points, nPoints, borderWidth, relief); } static void DrawPerforation(Tabset *setPtr, Tab *tabPtr, Drawable drawable) { int x, y; int segmentWidth, max; Blt_Background bg, perfBg; if ((tabPtr->container != NULL) || (tabPtr->tkwin == NULL)) { return; } WorldToScreen(setPtr, tabPtr->worldX + 2, tabPtr->worldY + tabPtr->worldHeight + 2, &x, &y); x += setPtr->xOffset; y += setPtr->yOffset; bg = GETATTR(tabPtr, selBg); segmentWidth = 3; if (setPtr->flags & ACTIVE_PERFORATION) { perfBg = GETATTR(tabPtr, activeBg); } else { perfBg = GETATTR(tabPtr, selBg); } if (setPtr->side & (SIDE_TOP|SIDE_BOTTOM)) { XPoint points[2]; points[0].x = x; points[0].y = points[1].y = y; max = tabPtr->screenX + setPtr->xOffset + tabPtr->screenWidth - 2; Blt_FillBackgroundRectangle(setPtr->tkwin, drawable, perfBg, x-2, y-4, tabPtr->screenWidth, 8, 0, TK_RELIEF_FLAT); while (points[0].x < max) { points[1].x = points[0].x + segmentWidth; if (points[1].x > max) { points[1].x = max; } Blt_DrawBackgroundPolygon(setPtr->tkwin, drawable, bg, points, 2, 1, TK_RELIEF_RAISED); points[0].x += 2 * segmentWidth; } } else { XPoint points[2]; points[0].x = points[1].x = x; points[0].y = y; max = tabPtr->screenY + tabPtr->screenHeight - 2; Blt_FillBackgroundRectangle(setPtr->tkwin, drawable, perfBg, x - 4, y - 2, 8, tabPtr->screenHeight, 0, TK_RELIEF_FLAT); while (points[0].y < max) { points[1].y = points[0].y + segmentWidth; if (points[1].y > max) { points[1].y = max; } Blt_DrawBackgroundPolygon(setPtr->tkwin, drawable, bg, points, 2, 1, TK_RELIEF_RAISED); points[0].y += 2 * segmentWidth; } } } #define NextPoint(px, py) \ pointPtr->x = (px), pointPtr->y = (py), pointPtr++, nPoints++ #define EndPoint(px, py) \ pointPtr->x = (px), pointPtr->y = (py), nPoints++ #define BottomLeft(px, py) \ NextPoint((px) + setPtr->corner, (py)), \ NextPoint((px), (py) - setPtr->corner) #define TopLeft(px, py) \ NextPoint((px), (py) + setPtr->corner), \ NextPoint((px) + setPtr->corner, (py)) #define TopRight(px, py) \ NextPoint((px) - setPtr->corner, (py)), \ NextPoint((px), (py) + setPtr->corner) #define BottomRight(px, py) \ NextPoint((px), (py) - setPtr->corner), \ NextPoint((px) - setPtr->corner, (py)) /* * From the left edge: * * |a|b|c|d|e| f |d|e|g|h| i |h|g|e|d|f| j |e|d|c|b|a| * * a. highlight ring * b. tabset 3D border * c. outer gap * d. page border * e. page corner * f. gap + select pad * g. label pad x (worldX) * h. internal pad x * i. label width * j. rest of page width * * worldX, worldY * | * | * * 4+ . . +5 * 3+ +6 * . . * . . * 1+. . .2+ +7 . . . .+8 * 0+ +9 * . . * . . *13+ +10 * 12+-------------------------+11 * */ static void DrawFolder(Tabset *setPtr, Tab *tabPtr, Drawable drawable) { XPoint points[16]; XPoint *pointPtr; int width, height; int left, bottom, right, top, yBot, yTop; int x, y; int i; int nPoints; int ySelectPad; width = VPORTWIDTH(setPtr); height = VPORTHEIGHT(setPtr); x = tabPtr->worldX; y = tabPtr->worldY; nPoints = 0; pointPtr = points; ySelectPad = 0; if (setPtr->nTiers == 1) { ySelectPad = setPtr->ySelectPad; } /* Remember these are all world coordinates. */ /* * x,y * | * * + . . + * + + * . . * left . . * +. . .2+---------+7 . . . .+8 * 0+ +9 * x Left side of tab. * y Top of tab. * yTop Top of folder. * yBot Bottom of the tab. * left Left side of the folder. * right Right side of the folder. * top Top of folder. * bottom Bottom of folder. */ left = setPtr->scrollOffset - setPtr->xSelectPad; right = left + width; yTop = y + tabPtr->worldHeight; yBot = setPtr->pageTop - (setPtr->inset + ySelectPad) + 1; top = yBot - setPtr->inset2 /* - 4 */; bottom = MAX(height - ySelectPad, yBot); if (setPtr->pageHeight == 0) { top = yBot - 1; yTop = bottom - setPtr->corner; yBot = bottom; } if (tabPtr != setPtr->selectPtr) { /* * Case 1: Unselected tab * * * 2+ . . +3 * 1+ +4 * . . * 0+-------- +5 * */ if (setPtr->flags & SLANT_LEFT) { NextPoint(x, yBot); NextPoint(x, yTop); NextPoint(x + setPtr->tabHeight, y); } else { NextPoint(x, yBot); TopLeft(x, y); } x += tabPtr->worldWidth; if (setPtr->flags & SLANT_RIGHT) { NextPoint(x - setPtr->tabHeight, y); NextPoint(x, yTop); NextPoint(x, yBot); } else { TopRight(x, y); NextPoint(x, yBot); } } else if ((tabPtr->flags & ONSCREEN) == 0) { /* * Case 2: Selected tab not visible in viewport. Draw folder only. * * * 2+ . . +3 * 1+ +4 * . . * 0+-------- +5 */ TopLeft(left, top); TopRight(right, top); NextPoint(right, bottom); NextPoint(left, bottom); } else { int flags; int tabWidth; x -= setPtr->xSelectPad; y -= setPtr->ySelectPad; tabWidth = tabPtr->worldWidth + 2 * setPtr->xSelectPad; #define CLIP_NONE 0 #define CLIP_LEFT (1<<0) #define CLIP_RIGHT (1<<1) flags = 0; if (x < left) { flags |= CLIP_LEFT; } if ((x + tabWidth) > right) { flags |= CLIP_RIGHT; } switch (flags) { case CLIP_NONE: /* * worldX, worldY * | * * 4+ . . +5 * 3+ +6 * . . * . . * 1+. . .2+---------+7 . . . .+8 * 0+ +9 * . . * . . * . . *11+ . . . . . . . . . . . . . . +10 */ if (x < (left + setPtr->corner)) { NextPoint(left, top); } else { TopLeft(left, top); } if (setPtr->flags & SLANT_LEFT) { NextPoint(x, yTop); NextPoint(x + setPtr->tabHeight + ySelectPad, y); } else { NextPoint(x, top); TopLeft(x, y); } x += tabWidth; if (setPtr->flags & SLANT_RIGHT) { NextPoint(x - setPtr->tabHeight - ySelectPad, y); NextPoint(x, yTop); } else { TopRight(x, y); NextPoint(x, top); } if (x > (right - setPtr->corner)) { NextPoint(right, top + setPtr->corner); } else { TopRight(right, top); } NextPoint(right, bottom); NextPoint(left, bottom); break; case CLIP_LEFT: /* * worldX, worldY * | * * 4+ . . +5 * 3+ +6 * . . * . . * 2+--------+7 . . . .+8 * 1+ . . . +0 +9 * . . * . . * . . * 11+ . . . . . +10 */ NextPoint(left, yBot); if (setPtr->flags & SLANT_LEFT) { NextPoint(x, yBot); NextPoint(x, yTop); NextPoint(x + setPtr->tabHeight + ySelectPad, y); } else { BottomLeft(x, yBot); TopLeft(x, y); } x += tabWidth; if (setPtr->flags & SLANT_RIGHT) { NextPoint(x - setPtr->tabHeight - ySelectPad, y); NextPoint(x, yTop); NextPoint(x, top); } else { TopRight(x, y); NextPoint(x, top); } if (x > (right - setPtr->corner)) { NextPoint(right, top + setPtr->corner); } else { TopRight(right, top); } NextPoint(right, bottom); NextPoint(left, bottom); break; case CLIP_RIGHT: /* * worldX, worldY * | * * 7+ . . +8 * 6+ +9 * . . * . . * 4+ . . . .5+---------+10 * 3+ 0+ . . . +11 * . . * . . * . . * 2+ . . . . . +1 */ NextPoint(right, yBot); NextPoint(right, bottom); NextPoint(left, bottom); if (x < (left + setPtr->corner)) { NextPoint(left, top); } else { TopLeft(left, top); } NextPoint(x, top); if (setPtr->flags & SLANT_LEFT) { NextPoint(x, yTop); NextPoint(x + setPtr->tabHeight + ySelectPad, y); } else { TopLeft(x, y); } x += tabWidth; if (setPtr->flags & SLANT_RIGHT) { NextPoint(x - setPtr->tabHeight - ySelectPad, y); NextPoint(x, yTop); NextPoint(x, yBot); } else { TopRight(x, y); BottomRight(x, yBot); } break; case (CLIP_LEFT | CLIP_RIGHT): /* * worldX, worldY * | * * 4+ . . . . . . . . +5 * 3+ +6 * . . * . . * 1+---------------------+7 * 2+ 0+ +9 .+8 * . . * . . * . . * 11+ . . . . .+10 */ NextPoint(left, yBot); if (setPtr->flags & SLANT_LEFT) { NextPoint(x, yBot); NextPoint(x, yTop); NextPoint(x + setPtr->tabHeight + ySelectPad, y); } else { BottomLeft(x, yBot); TopLeft(x, y); } x += tabPtr->worldWidth; if (setPtr->flags & SLANT_RIGHT) { NextPoint(x - setPtr->tabHeight - ySelectPad, y); NextPoint(x, yTop); NextPoint(x, yBot); } else { TopRight(x, y); BottomRight(x, yBot); } NextPoint(right, yBot); NextPoint(right, bottom); NextPoint(left, bottom); break; } } EndPoint(points[0].x, points[0].y); for (i = 0; i < nPoints; i++) { WorldToScreen(setPtr, points[i].x, points[i].y, &x, &y); points[i].x = x + setPtr->xOffset; points[i].y = y + setPtr->yOffset; } Draw3dFolder(setPtr, tabPtr, drawable, setPtr->side, points, nPoints); DrawLabel(setPtr, tabPtr, drawable); if (tabPtr->container != NULL) { XRectangle rect; /* Draw a rectangle covering the spot representing the window */ GetWindowRectangle(tabPtr, setPtr->tkwin, FALSE, &rect); XFillRectangles(setPtr->display, drawable, tabPtr->backGC, &rect, 1); } } static void DrawOuterBorders(Tabset *setPtr, Drawable drawable) { /* * Draw 3D border just inside of the focus highlight ring. We draw the * border even if the relief is flat so that any tabs that hang over the * edge will be clipped. */ if (setPtr->borderWidth > 0) { Blt_DrawBackgroundRectangle(setPtr->tkwin, drawable, setPtr->bg, setPtr->highlightWidth + setPtr->xOffset, setPtr->highlightWidth + setPtr->yOffset, Tk_Width(setPtr->tkwin) - 2 * setPtr->highlightWidth, Tk_Height(setPtr->tkwin) - 2 * setPtr->highlightWidth, setPtr->borderWidth, setPtr->relief); } /* Draw focus highlight ring. */ if (setPtr->highlightWidth > 0) { XColor *color; GC gc; color = (setPtr->flags & FOCUS) ? setPtr->highlightColor : setPtr->highlightBg; gc = Tk_GCForColor(color, drawable); Tk_DrawFocusHighlight(setPtr->tkwin, gc, setPtr->highlightWidth, drawable); } } /* *--------------------------------------------------------------------------- * * DisplayTabset -- * * This procedure is invoked to display the widget. * * Recomputes the layout of the widget if necessary. This is necessary if * the world coordinate system has changed. Sets the vertical and * horizontal scrollbars. This is done here since the window width and * height are needed for the scrollbar calculations. * * Results: * None. * * Side effects: * The widget is redisplayed. * *--------------------------------------------------------------------------- */ static void DisplayTabset(ClientData clientData) /* Information about widget. */ { Tabset *setPtr = clientData; Pixmap pixmap; int width, height; int redrawAll; redrawAll = setPtr->flags & REDRAW_ALL; setPtr->flags &= ~(REDRAW_PENDING | REDRAW_ALL); if (setPtr->tkwin == NULL) { return; /* Window has been destroyed. */ } if (setPtr->flags & LAYOUT_PENDING) { ComputeLayout(setPtr); setPtr->flags &= ~LAYOUT_PENDING; } if ((setPtr->reqHeight == 0) || (setPtr->reqWidth == 0)) { width = height = 0; if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { height = setPtr->worldWidth; } else { width = setPtr->worldWidth; } if (setPtr->reqWidth > 0) { width = setPtr->reqWidth; } else if (setPtr->pageWidth > 0) { width = setPtr->pageWidth; } if (setPtr->reqHeight > 0) { height = setPtr->reqHeight; } else if (setPtr->pageHeight > 0) { height = setPtr->pageHeight; } if (setPtr->side & (SIDE_LEFT | SIDE_RIGHT)) { #ifdef notdef width += setPtr->pageTop + setPtr->inset + setPtr->inset2; height += setPtr->inset + setPtr->inset2; #else width += 2 * setPtr->inset + setPtr->pageTop + setPtr->inset2; height += 2 * setPtr->inset; #endif } else { height += 2 * setPtr->inset + setPtr->pageTop + setPtr->inset2; width += 2 * setPtr->inset; } if ((Tk_ReqWidth(setPtr->tkwin) != width) || (Tk_ReqHeight(setPtr->tkwin) != height)) { Tk_GeometryRequest(setPtr->tkwin, width, height); } } if (setPtr->flags & SCROLL_PENDING) { width = VPORTWIDTH(setPtr); setPtr->scrollOffset = Blt_AdjustViewport(setPtr->scrollOffset, setPtr->worldWidth, width, setPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX); if (setPtr->scrollCmdObjPtr != NULL) { Blt_UpdateScrollbar(setPtr->interp, setPtr->scrollCmdObjPtr, setPtr->scrollOffset, setPtr->scrollOffset + width, setPtr->worldWidth); } ComputeVisibleTabs(setPtr); setPtr->flags &= ~SCROLL_PENDING; } if (!Tk_IsMapped(setPtr->tkwin)) { return; } width = Tk_Width(setPtr->tkwin); height = Tk_Height(setPtr->tkwin); setPtr->xOffset = setPtr->yOffset = 0; /* Offset of the window origin * from the pixmap created * below. */ if (!redrawAll) { /* Create a pixmap only the size of the tab region. This saves the X * server from rendering the entire folder background polygon each * time. This is good for scrolling and active tabs. */ switch (setPtr->side) { case SIDE_TOP: height = setPtr->pageTop + setPtr->inset + setPtr->inset2; break; case SIDE_BOTTOM: setPtr->yOffset = setPtr->pageTop - height; height = setPtr->pageTop + setPtr->inset + setPtr->inset2; break; case SIDE_LEFT: width = setPtr->pageTop + setPtr->inset + setPtr->inset2; break; case SIDE_RIGHT: setPtr->xOffset = setPtr->pageTop - width; width = setPtr->pageTop + setPtr->inset + setPtr->inset2; break; } } pixmap = Tk_GetPixmap(setPtr->display, Tk_WindowId(setPtr->tkwin), width, height, Tk_Depth(setPtr->tkwin)); /* * Clear the background either by tiling a pixmap or filling with a solid * color. Tiling takes precedence. */ Blt_FillBackgroundRectangle(setPtr->tkwin, pixmap, setPtr->bg, setPtr->xOffset, setPtr->yOffset, Tk_Width(setPtr->tkwin), Tk_Height(setPtr->tkwin), 0, TK_RELIEF_FLAT); if (setPtr->nVisible > 0) { int i; Tab *tabPtr; Blt_ChainLink link; link = setPtr->startPtr->link; for (i = 0; i < Blt_Chain_GetLength(setPtr->chain); i++) { link = Blt_Chain_PrevLink(link); if (link == NULL) { link = Blt_Chain_LastLink(setPtr->chain); } tabPtr = Blt_Chain_GetValue(link); if ((tabPtr != setPtr->selectPtr) && (tabPtr->flags & ONSCREEN)) { DrawFolder(setPtr, tabPtr, pixmap); } } DrawFolder(setPtr, setPtr->selectPtr, pixmap); if (setPtr->flags & TEAROFF) { DrawPerforation(setPtr, setPtr->selectPtr, pixmap); } if ((setPtr->selectPtr->tkwin != NULL) && (setPtr->selectPtr->container == NULL)) { XRectangle rect; GetWindowRectangle(setPtr->selectPtr, setPtr->tkwin, FALSE, &rect); ArrangeWindow(setPtr->selectPtr->tkwin, &rect, 0); } } DrawOuterBorders(setPtr, pixmap); XCopyArea(setPtr->display, pixmap, Tk_WindowId(setPtr->tkwin), setPtr->highlightGC, 0, 0, width, height, -setPtr->xOffset, -setPtr->yOffset); Tk_FreePixmap(setPtr->display, pixmap); } /* * From the left edge: * * |a|b|c|d|e| f |d|e|g|h| i |h|g|e|d|f| j |e|d|c|b|a| * * a. highlight ring * b. tabset 3D border * c. outer gap * d. page border * e. page corner * f. gap + select pad * g. label pad x (worldX) * h. internal pad x * i. label width * j. rest of page width * * worldX, worldY * | * | * * 4+ . . +5 * 3+ +6 * . . * . . * 1+. . .2+ +7 . . . .+8 * 0+ +9 * . . * . . * . . *11+------------------------------+10 * */ static void DisplayTearoff(ClientData clientData) { Tabset *setPtr; Tab *tabPtr; Drawable drawable; XPoint points[16]; XPoint *pointPtr; int width, height; int left, bottom, right, top; int x, y; int nPoints; Tk_Window tkwin; Tk_Window parent; XRectangle rect; tabPtr = clientData; if (tabPtr == NULL) { return; } tabPtr->flags &= ~TEAROFF_REDRAW; setPtr = tabPtr->setPtr; if (setPtr->tkwin == NULL) { return; } tkwin = tabPtr->container; drawable = Tk_WindowId(tkwin); Blt_FillBackgroundRectangle(tkwin, drawable, setPtr->bg, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); width = Tk_Width(tkwin) - 2 * setPtr->inset; height = Tk_Height(tkwin) - 2 * setPtr->inset; x = setPtr->inset + setPtr->gap + setPtr->corner; y = setPtr->inset; left = setPtr->inset; right = setPtr->inset + width; top = setPtr->inset + setPtr->corner + setPtr->xSelectPad; bottom = setPtr->inset + height; /* * worldX, worldY * | * * 4+ . . +5 * 3+ +6 * . . * . . * 1+. . .2+ +7 . . . .+8 * 0+ +9 * . . * . . * . . *11+------------------------------+10 */ nPoints = 0; pointPtr = points; TopLeft(left, top); NextPoint(x, top); TopLeft(x, y); x += tabPtr->worldWidth; TopRight(x, y); NextPoint(x, top); TopRight(right, top); NextPoint(right, bottom); NextPoint(left, bottom); EndPoint(points[0].x, points[0].y); Draw3dFolder(setPtr, tabPtr, drawable, SIDE_TOP, points, nPoints); parent = (tabPtr->container == NULL) ? setPtr->tkwin : tabPtr->container; GetWindowRectangle(tabPtr, parent, TRUE, &rect); ArrangeWindow(tabPtr->tkwin, &rect, TRUE); /* Draw 3D border. */ if ((setPtr->borderWidth > 0) && (setPtr->relief != TK_RELIEF_FLAT)) { Blt_DrawBackgroundRectangle(tkwin, drawable, setPtr->bg, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), setPtr->borderWidth, setPtr->relief); } } /* *--------------------------------------------------------------------------- * * TabsetCmd -- * * This procedure is invoked to process the "tabset" command. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec tabsetOps[] = { {"activate", 2, ActivateOp, 3, 3, "tab",}, {"add", 2, AddOp, 2, 0, "?label? ?option-value..?",}, {"bind", 2, BindOp, 2, 5, "tab ?sequence command?",}, {"button", 2, ButtonOp, 2, 0, "args",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"close", 2, CloseOp, 3, 3, "tab",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"delete", 2, DeleteOp, 2, 0, "?tab...?",}, {"dockall", 2, DockallOp, 2, 2, "" }, {"exists", 3, ExistsOp, 3, 3, "tab",}, {"extents", 1, ExtentsOp, 3, 3, "tab",}, {"focus", 1, FocusOp, 2, 3, "?tab?",}, {"highlight", 1, ActivateOp, 3, 3, "tab",}, {"id", 2, IdOp, 3, 3, "tab",}, {"index", 3, IndexOp, 3, 3, "tab",}, {"insert", 3, InsertOp, 3, 0, "position ?option value?",}, {"invoke", 3, InvokeOp, 3, 3, "tab",}, {"move", 1, MoveOp, 5, 5, "tab after|before tab",}, {"names", 2, NamesOp, 2, 0, "?pattern...?",}, {"nearest", 2, NearestOp, 4, 4, "x y",}, {"perforation", 1, PerforationOp, 2, 0, "args",}, {"scan", 2, ScanOp, 5, 5, "dragto|mark x y",}, {"see", 3, SeeOp, 3, 3, "tab",}, {"select", 3, SelectOp, 3, 3, "tab",}, {"size", 2, SizeOp, 2, 2, "",}, {"tab", 2, TabOp, 2, 0, "oper args",}, {"tag", 2, TagOp, 2, 0, "oper args",}, {"tearoff", 2, TearoffOp, 3, 4, "tab ?parent?",}, {"view", 1, ViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nTabsetOps = sizeof(tabsetOps) / sizeof(Blt_OpSpec); static int TabsetInstCmd( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Vector of argument strings. */ { TabsetCmdProc *proc; Tabset *setPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nTabsetOps, tabsetOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(setPtr); result = (*proc) (setPtr, interp, objc, objv); Tcl_Release(setPtr); return result; } /* *--------------------------------------------------------------------------- * * TabsetInstDeletedCmd -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void TabsetInstDeletedCmd(ClientData clientData) { Tabset *setPtr = clientData; if (setPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = setPtr->tkwin; setPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * TabsetCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * * * blt::tabset pathName ?option value?... * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int TabsetCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tabset *setPtr; Tk_Window tkwin; unsigned int mask; Tcl_CmdInfo cmdInfo; const char *pathName; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } pathName = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), pathName, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } /* * Try to invoke a procedure to initialize various bindings on tabs. * Source the file containing the procedure now if the procedure isn't * currently defined. We deferred this to now so that the user could set * the variable "blt_library" within the script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Tabset::Init", &cmdInfo)) { static char initCmd[] = "source [file join $blt_library tabset.tcl]"; if (Tcl_GlobalEval(interp, initCmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); Tk_DestroyWindow(setPtr->tkwin); return TCL_ERROR; } } setPtr = NewTabset(interp, tkwin); if (ConfigureTabset(interp, setPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(setPtr->tkwin); return TCL_ERROR; } if (ConfigureButton(interp, setPtr, 0, NULL, 0) != TCL_OK) { Tk_DestroyWindow(setPtr->tkwin); return TCL_ERROR; } mask = (ExposureMask | StructureNotifyMask | FocusChangeMask); Tk_CreateEventHandler(tkwin, mask, TabsetEventProc, setPtr); setPtr->cmdToken = Tcl_CreateObjCommand(interp, pathName, TabsetInstCmd, setPtr, TabsetInstDeletedCmd); if (Tcl_VarEval(interp, "::blt::Tabset::Init ", Tk_PathName(setPtr->tkwin), (char *)NULL) != TCL_OK) { Tk_DestroyWindow(setPtr->tkwin); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), pathName, -1); return TCL_OK; } int Blt_TabsetCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[2] = { { "tabset", TabsetCmd, }, { "tabnotebook", TabsetCmd, }, }; return Blt_InitCmds(interp, "::blt", cmdSpecs, 2); } #endif /* NO_TABSET */ static GadgetRegion RotateRegion(Tab *tabPtr, int x, int y, unsigned int w, unsigned int h) { Tabset *setPtr; GadgetRegion r; setPtr = tabPtr->setPtr; if (setPtr->quad == ROTATE_90) { r.x = y; r.y = tabPtr->rotWidth - (x + w); r.w = h; r.h = w; } else if (setPtr->quad == ROTATE_270) { r.x = tabPtr->rotHeight - (y + h); r.y = x; r.w = h; r.h = w; } else { r.x = x; r.y = y; r.w = w, r.h = h; } return r; } /* * Computes the location and dimensions of the * * 1. icon * 2. text or image * 3. close button. * 4. focus rectangle * 5. * x,y * |1|2|3| 4 |5| 4 |3|2|1| * * 1. tab borderwidth * 2. corner offset or slant * 3. label pad * 4. label or text width * 5. pad */ static void ComputeLabelOffsets(Tabset *setPtr, Tab *tabPtr) { int w, h; int x1, x2, y1, y2; int tx, ty, tw, th, maxLength; int ix, iy, iw, ih; int fx, fy, fw, fh; int worldWidth, worldHeight, labelWidth; int xSelPad, ySelPad; worldWidth = tabPtr->worldWidth; worldHeight = setPtr->tabHeight + setPtr->inset2; /* The world width of tab has to be fixed to remove the extra padding for * the slant/corner and the rotation based upon the side. */ worldWidth -= (setPtr->flags & SLANT_LEFT) ? tabPtr->worldHeight : setPtr->inset2; worldWidth -= (setPtr->flags & SLANT_RIGHT) ? tabPtr->worldHeight : setPtr->inset2; xSelPad = ySelPad = 0; if (tabPtr == setPtr->selectPtr) { worldWidth += setPtr->xSelectPad; xSelPad = setPtr->xSelectPad / 2; ySelPad = setPtr->ySelectPad / 2; } if ((setPtr->quad == ROTATE_90) || (setPtr->quad == ROTATE_270)) { SWAP(worldWidth, worldHeight); } if (setPtr->side & (SIDE_RIGHT | SIDE_LEFT)) { SWAP(worldWidth, worldHeight); } tabPtr->rotWidth = worldWidth; tabPtr->rotHeight = worldHeight; x1 = y1 = 0; x2 = x1 + tabPtr->rotWidth; y2 = y1 + tabPtr->rotHeight; #if DEBUG1 fprintf(stderr, "ComputeLabelOffset: -1. tab=%s x1=%d,y1=%d,x2=%d,y2=%d,w=%d,h=%d, w0=%d h0=%d\n", tabPtr->text, x1, y1, x2, y2, w, h, tabPtr->rotWidth, tabPtr->rotHeight); #endif /* Compute the positions of the tab in world coordinates (rotated 0 * degrees). */ /* Start with the upper/left and lower/right corners of the label inside of * the tab. This excludes the tab's borderwidth. */ /* This is the available area for the label. */ w = x2 - x1; h = y2 - y1; if ((w < 0) || (h < 0)) { return; } #if DEBUG1 fprintf(stderr, "ComputeLabelOffset: 0. tab=%s x1=%d,y1=%d,x2=%d,y2=%d,w=%d,h=%d, w0=%d h0=%d\n", tabPtr->text, x1, y1, x2, y2, w, h, tabPtr->rotWidth, tabPtr->rotHeight); #endif /* Focus dashed rectangle. */ { fx = x1; fy = y1; fw = ODD(w); fh = ODD(h); tabPtr->focusRegion = RotateRegion(tabPtr, fx, fy, fw, fh); } /* Close button geometry. */ if ((setPtr->plusPtr != tabPtr) && (setPtr->flags & CLOSE_NEEDED)) { int bx, by, bw, bh; /* Close button is always located on the right side of the tab, * it's height is centered. */ bx = x2 - CLOSE_WIDTH - setPtr->closeButton.borderWidth; by = y1; bw = CLOSE_WIDTH; bh = CLOSE_HEIGHT; if (h > bh) { by += (h - bh) / 2; } else { bh = h; } if (w < bw) { bw = w; } if ((setPtr->quad == ROTATE_0) || (setPtr->quad == ROTATE_180)) { bx += 2 * xSelPad; } tabPtr->buttonRegion = RotateRegion(tabPtr, bx, by, bw, bh); #if DEBUG1 fprintf(stderr, "ComputeLabelOffset: button tab=%s x=%d,y=%d,w=%d,h=%d => x=%d,y=%d w=%d,h=%d\n", tabPtr->text, bx, by, bw, bh, tabPtr->buttonRegion.x, tabPtr->buttonRegion.y, tabPtr->buttonRegion.width, tabPtr->buttonRegion.height); #endif x2 -= bw + LABEL_PAD + 2 * setPtr->closeButton.borderWidth; } /* Label/image and icon. Their positioning is related because of * the -iconposition option. */ w = x2 - x1; h = y2 - y1; if (tabPtr->icon != NULL) { iw = IconWidth(tabPtr->icon); ih = IconHeight(tabPtr->icon); } else { iw = ih = 0; } if (iw > w) { iw = w; } w = x2 - x1; h = y2 - y1; labelWidth = tabPtr->labelWidth0; if ((tabPtr != setPtr->plusPtr) && (setPtr->flags & CLOSE_NEEDED)) { labelWidth -= CLOSE_WIDTH + 2 * setPtr->closeButton.borderWidth; } if (w > labelWidth) { if (setPtr->justify == TK_JUSTIFY_CENTER) { x1 += (w - labelWidth) / 2; } else if (setPtr->justify == TK_JUSTIFY_RIGHT) { x1 += (w - labelWidth); } } if (tabPtr->text != NULL) { tw = tabPtr->textWidth0; th = tabPtr->textHeight0; } else { tw = th = 0; } w = x2 - x1; h = y2 - y1; #if DEBUG1 fprintf(stderr, "ComputeLabelOffset: 1 tab=%s x=%d,y=%d,w=%d,h=%d, ww=%d wh=%d tabLabelWidth=%d lw=%d\n", tabPtr->text, x1, y1, w, h, tabPtr->worldWidth, tabPtr->worldHeight, tabPtr->labelWidth0, labelWidth); #endif maxLength = x2 - x1; if (tw > w) { tw = w; } /* Now compute the text/image and icon positions according to the text * side. Don't use the text/image width/height to compute the position of * the icon because the text will shrink with the available room. */ switch (setPtr->iconPos) { case SIDE_LEFT: if (iw > w) { /* Not enough space for icon. */ iw = w; w = 0; } else { w -= iw; /* Subtract space taken by icon. */ } if (tw > w) { /* Not enough space for text. */ tw = w; w = 0; } else { w -= tw; /* Subtract space taken by text. */ } if (w < 0) { w = 0; } /* The text/image is to the right of the icon. */ ix = x1; iy = y1; if (h > ih) { iy += (h - ih) / 2; } tx = ix + iw; if ((iw > 0) && (tw > 0)) { tx += LABEL_PAD; } ty = y1; if (h > th) { ty += (h - th) / 2; } #if DEBUG1 fprintf(stderr, "tab=%s textWidth=%d, textHeight=%d => %d,%d %dx%d iw=%d ih=%d\n", tabPtr->text, tabPtr->textWidth0, tabPtr->textHeight0, tx, ty, tw, th, iw, ih); #endif break; case SIDE_RIGHT: /* The text/image is to the left of the icon. */ tx = x1; ty = y1 + (h - th) / 2; ix = x2 - iw; iy = y1 + (h - ih) / 2; if ((iw > 0) && (tw > 0)) { ix += LABEL_PAD; } break; } tabPtr->iconRegion = RotateRegion(tabPtr, ix, iy, iw, ih); #ifdef DEBUG fprintf(stderr, "ComputeLabelOffset: icon tab=%s x=%d,y=%d,w=%d,h=%d => x=%d,y=%d w=%d,h=%d\n", tabPtr->text, ix, iy, iw, ih, tabPtr->iconRegion.x, tabPtr->iconRegion.y, tabPtr->iconRegion.width, tabPtr->iconRegion.height); #endif tabPtr->textRegion = RotateRegion(tabPtr, tx, ty, ODD(tw), ODD(th)); #if DEBUG1 fprintf(stderr, "ComputeLabelOffset: text tab=%s x=%d,y=%d,w=%d,h=%d => x=%d,y=%d w=%d,h=%d\n", tabPtr->text, tx, ty, tw, th, tabPtr->textRegion.x, tabPtr->textRegion.y, tabPtr->textRegion.width, tabPtr->textRegion.height); #endif /* Focus dashed rectangle. */ { fx = tx; fy = ty; fw = ODD(tw); fh = ODD(th); tabPtr->focusRegion = RotateRegion(tabPtr, fx, fy, fw, fh); } } static void DrawButtonPictures(Tabset *setPtr) { Button *butPtr = &setPtr->closeButton; if (butPtr->active0 == NULL) { butPtr->active0 = Blt_PaintDelete(CLOSE_WIDTH, CLOSE_HEIGHT, butPtr->activeBg, butPtr->activeFg); } if ((butPtr->active != NULL) && (butPtr->active != butPtr->active0)) { Blt_FreePicture(butPtr->active); } if (setPtr->angle == 0.0) { butPtr->active = butPtr->active0; } else { butPtr->active = Blt_RotatePicture(butPtr->active0, setPtr->angle); } if (butPtr->normal0 == NULL) { butPtr->normal0 = Blt_PaintDelete(CLOSE_WIDTH, CLOSE_HEIGHT, butPtr->normalBg, butPtr->normalFg); } if ((butPtr->normal != NULL) && (butPtr->normal != butPtr->normal0)) { Blt_FreePicture(butPtr->normal); } if (setPtr->angle == 0.0) { butPtr->normal = butPtr->normal0; } else { butPtr->normal = Blt_RotatePicture(butPtr->normal0, setPtr->angle); } } /* * x,y * |1|2|3| 4 |5| 4 |3|2|1| * * 1. tab borderwidth * 2. corner offset or slant * 3. label pad * 4. label or text width * 5. pad */ static void DrawLabel(Tabset *setPtr, Tab *tabPtr, Drawable drawable) { int x, y; int maxLength; XColor *bgColor; Blt_Background bg; TabStyle *stylePtr; int xSelPad, ySelPad; GadgetRegion *rPtr; if ((tabPtr->flags & ONSCREEN) == 0) { return; } ComputeLabelOffsets(setPtr, tabPtr); /* Get origin of tab. */ WorldToScreen(setPtr, tabPtr->worldX, tabPtr->worldY, &x, &y); x += setPtr->xOffset; /* Adjust for pixmap offsets. */ y += setPtr->yOffset; /* Adjust according the side. */ if (setPtr->side & SIDE_BOTTOM) { y -= setPtr->tabHeight + tabPtr->padTop; } else if (setPtr->side & SIDE_LEFT) { /* y -= tabPtr->worldWidth; */ } else if (setPtr->side & SIDE_RIGHT) { x -= setPtr->tabHeight + tabPtr->padTop; } /* Adjust the label's area according to the tab's slant. */ if (setPtr->side & (SIDE_RIGHT | SIDE_LEFT)) { y += (setPtr->flags & SLANT_LEFT) ? setPtr->tabHeight : setPtr->inset2; } else { x += (setPtr->flags & SLANT_LEFT) ? setPtr->tabHeight : setPtr->inset2; } #if DEBUG0 fprintf(stderr, "DrawLabel: tab=%s x=%d,y=%d wx=%d,wy=%d,ww=%d,wh=%d\n", tabPtr->text, x, y, tabPtr->worldX, tabPtr->worldY, tabPtr->worldWidth, tabPtr->worldHeight); #endif stylePtr = &setPtr->defStyle; bg = GETATTR(tabPtr, bg); xSelPad = ySelPad = 0; if (tabPtr == setPtr->selectPtr) { x -= setPtr->xSelectPad / 2; if (setPtr->side & SIDE_TOP) { y -= setPtr->ySelectPad; } if (setPtr->side & SIDE_BOTTOM) { y += setPtr->ySelectPad; } xSelPad = setPtr->xSelectPad / 2; ySelPad = setPtr->ySelectPad / 2; bg = GETATTR(tabPtr, selBg); } bgColor = Blt_BackgroundBorderColor(bg); if ((tabPtr == setPtr->activePtr) || (tabPtr == setPtr->activeButtonPtr)) { Blt_Background activeBg; activeBg = GETATTR(tabPtr, activeBg); bgColor = Blt_BackgroundBorderColor(activeBg); } rPtr = &tabPtr->buttonRegion; if ((setPtr->plusPtr != tabPtr) && (setPtr->flags & CLOSE_NEEDED) && (tabPtr->flags & CLOSE_NEEDED) && (rPtr->w > 0) && (rPtr->h > 0)) { Button *butPtr = &setPtr->closeButton; Blt_Picture picture; int bx, by; DrawButtonPictures(setPtr); picture = (setPtr->activeButtonPtr == tabPtr) ? butPtr->active : butPtr->normal; if (setPtr->painter == NULL) { setPtr->painter = Blt_GetPainter(setPtr->tkwin, 1.0); } bx = x + rPtr->x; by = y + rPtr->y; Blt_PaintPictureWithBlend(setPtr->painter, drawable, picture, 0, 0, rPtr->w, rPtr->h, bx, by, 0, 1.0); } rPtr = &tabPtr->iconRegion; if ((tabPtr->icon != NULL) && (rPtr->w > 0) && (rPtr->h > 0)) { Tk_Image tkImage; int maxLength; maxLength = 10000; tkImage = IconBits(tabPtr->icon); if (setPtr->angle == 0.0) { Tk_RedrawImage(tkImage, 0, 0, rPtr->w, rPtr->h, drawable, x + rPtr->x, y + rPtr->y); } else { struct _Icon *iconPtr; iconPtr = tabPtr->icon; if (iconPtr->angle != setPtr->angle) { int isPhoto; Blt_Picture picture, rotated; if (iconPtr->picture != NULL) { Blt_FreePicture(iconPtr->picture); } picture = Blt_GetPictureFromImage(setPtr->interp, tkImage, &isPhoto); rotated = Blt_RotatePicture(picture, setPtr->angle); iconPtr->picture = rotated; iconPtr->angle = setPtr->angle; if (isPhoto) { Blt_FreePicture(picture); } } if (setPtr->painter == NULL) { setPtr->painter = Blt_GetPainter(setPtr->tkwin, 1.0); } Blt_PaintPictureWithBlend(setPtr->painter, drawable, iconPtr->picture, 0, 0, rPtr->w, rPtr->h, x + rPtr->x, y + rPtr->y, 0, 1.0); } } rPtr = &tabPtr->textRegion; if ((tabPtr->text != NULL) && (rPtr->w > 0) && (rPtr->h > 0)) { TextStyle ts; XColor *fgColor; Blt_Font font; int maxLength = -1; font = GETATTR(tabPtr, font); if (tabPtr == setPtr->selectPtr) { fgColor = GETATTR(tabPtr, selColor); } else if ((tabPtr == setPtr->activePtr) || (tabPtr == setPtr->activeButtonPtr)) { fgColor = GETATTR(tabPtr, activeFg); } else { fgColor = GETATTR(tabPtr, textColor); } Blt_Ts_InitStyle(ts); Blt_Ts_SetAngle(ts, setPtr->angle); Blt_Ts_SetBackground(ts, bg); Blt_Ts_SetFont(ts, font); Blt_Ts_SetPadding(ts, 2, 2, 0, 0); if (tabPtr->flags & DISABLED) { Blt_Ts_SetState(ts, STATE_DISABLED); } else if (tabPtr->flags & ACTIVE) { Blt_Ts_SetState(ts, STATE_ACTIVE); } Blt_Ts_SetForeground(ts, fgColor); if ((setPtr->quad == ROTATE_90) || (setPtr->quad == ROTATE_270)) { maxLength = rPtr->h; } else { maxLength = rPtr->w; } if (tabPtr == setPtr->selectPtr) { maxLength += setPtr->xSelectPad; } #if DEBUG0 fprintf(stderr, "DrawLayout: text tab=%s coords=%d,%d text=%dx%d ml=%d => region: x=%d,y=%d w=%d,h=%d\n", tabPtr->text, x, y, tabPtr->textWidth0, tabPtr->textHeight0, maxLength, rPtr->x, rPtr->y, rPtr->w, rPtr->h); #endif Blt_Ts_SetMaxLength(ts, maxLength); Blt_Ts_DrawLayout(setPtr->tkwin, drawable, tabPtr->layoutPtr, &ts, x + rPtr->x, y + rPtr->y); } rPtr = &tabPtr->focusRegion; if ((setPtr->flags & FOCUS) && (setPtr->focusPtr == tabPtr) && (rPtr->w > 0) && (rPtr->h > 0)) { XColor *fg; if (tabPtr == setPtr->selectPtr) { fg = GETATTR(tabPtr, selColor); } else if (tabPtr == setPtr->activePtr) { fg = GETATTR(tabPtr, activeFg); } else { fg = GETATTR(tabPtr, textColor); } XSetForeground(setPtr->display, stylePtr->activeGC, fg->pixel); maxLength = rPtr->w + xSelPad; if ((setPtr->quad == ROTATE_0) || (setPtr->quad == ROTATE_180)) { XDrawRectangle(setPtr->display, drawable, stylePtr->activeGC, x + rPtr->x - 1, y + rPtr->y, maxLength + 1, rPtr->h); } else { XDrawRectangle(setPtr->display, drawable, stylePtr->activeGC, x + rPtr->x, y + rPtr->y - 1, maxLength, rPtr->h + 1); } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacImage.c�����������������������������������������������������������������0000644�0001750�0001750�00000204023�11462120062�015337� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSXImage.c -- * * This module implements MacOSX-specific image processing procedures * for the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltImage.h" /* #include <X11/Xutil.h> */ #include "tkDisplay.h" typedef struct _Blt_Picture _Picture; #define Cursor MacOSX_Cursor #define Picture MacOSX_Picture #define TextStyle MacOSX_TextStyle #include <Carbon/Carbon.h> #undef Picture #undef Cursor #undef TextStyle struct TkWindow; struct _MacDrawable { TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */ CGrafPtr grafPtr; ControlRef rootControl; int xOffset; /* X offset from toplevel window. */ int yOffset; /* Y offset from toplevel window. */ RgnHandle clipRgn; /* Visable region of window. */ RgnHandle aboveClipRgn; /* Visable region of window and its * children. */ int referenceCount; /* Don't delete toplevel until * children are gone. */ /* Pointer to the toplevel datastruct. */ struct _MacDrawable *toplevel; int flags; /* Various state see defines below. */ }; typedef struct _MacDrawable *MacDrawable; #define COLOR_WINDOW (1<<0) #define BLACK_AND_WHITE (1<<1) #define MAP_COLORS (1<<2) static Blt_HashTable painterTable; static int initialized = 0; /* * PainterKey -- * * This structure represents the key used to uniquely identify * painters. A painter is specified by a combination of display, * visual, colormap, depth, and monitor gamma value. */ typedef struct { Display *display; /* Display of painter. Used to free * colors allocated. */ Visual *visualPtr; /* Visual information for the class of * windows displaying the image. */ Colormap colormap; /* Colormap used. This may be the * default colormap, or an allocated * private map. */ int depth; /* Pixel depth of the display. */ double gamma; /* Gamma correction value of monitor. */ } PainterKey; /* * Painter -- * * This structure represents a painter used to display picture images. * A painter is specified by a combination of display, visual, * colormap, depth, and monitor gamma value. Painters contain * information necessary to display a picture. This includes both an * RGB to pixel map, and a RGB to allocated color map. * * Painters may be shared by more than one client and are reference * counted. When no clients are using the painter, it is freed. */ typedef struct _Blt_Painter { Display *display; /* Display of painter. Used to free * colors allocated. */ Visual *visualPtr; /* Visual information for the class of * windows displaying the image. */ Colormap colormap; /* Colormap used. This may be the default * colormap, or an allocated private map. */ int depth; /* Pixel depth of the display. */ double gamma; /* Gamma correction value of monitor. */ unsigned int flags; /* Flags listed below. */ int refCount; /* # of clients using this painter. If * zero, the painter is freed. */ Blt_HashEntry *hashPtr; /* Used to delete the painter entry * from the hash table of painters. */ int nColors; /* # of colors allocated. */ int nRed, nGreen, nBlue; /* # of intensities for each RGB component. */ unsigned long pixels[256]; /* Array of pixel values. Needed to * deallocate the color palette. Also * contains the mapping between linear * pixel values (rBits, gBits, bBits) * and the actual pixel for * PsuedoColor, StaticColor, * Greyscale, and StaticGrey visuals. */ int nPixels; /* # of pixels allocated in above array. */ GC gc; /* GC used to draw the image. */ /* * The following arrays are used for DirectColor, PsuedoColor, * StaticColor, Greyscale, and StaticGrey visuals to convert RGB * triplets to a parts of a pixel index. */ unsigned int rBits[256], gBits[256], bBits[256]; /* * This following as used for TrueColor and DirectColor visuals * only. They are used to directly compute of pixel values from * picture RGB components. */ unsigned int rAdjust, gAdjust, bAdjust; unsigned int rShift, gShift, bShift; unsigned int rMask, gMask, bMask; unsigned char gammaTable[256]; /* Input gamma lookup table. Used to * map non-linear monitor values back * to RGB values. This is used * whenever we take a snapshot of the * screen (e.g. alpha blending). * Computes the power mapping. * D = I^gamma. */ unsigned char igammaTable[256]; /* Output gamma lookup table. Used to * map RGB values to non-linear * monitor values. Computes the * inverse power mapping. * I~ = D^1/gamma. */ int isMonochrome; /* Indicates if the display uses a single * color component (e.g. 4-bit grayscale). */ Blt_Pixel palette[256]; /* Maps the picture's 8-bit RGB values to the * RGB values of the colors actually * allocated. This is used for dithering the * picture. */ } Painter; #define GC_PRIVATE 1 /* Indicates if the GC in the painter * was shared (allocated by Tk_GetGC) * or private (by XCreateGC). */ static Tcl_FreeProc FreePainter; typedef struct _Blt_Picture Picture; #define GetBit(x, y) \ srcBits[(srcBytesPerRow * (srcHeight - y - 1)) + (x>>3)] & (0x80 >> (x&7)) #define SetBit(x, y) \ destBits[(destBytesPerRow * (destHeight - y - 1)) + (x>>3)] |= (0x80 >>(x&7)) /* *--------------------------------------------------------------------------- * * FindShift -- * * Returns the position of the least significant (low) bit in * the given mask. * * For TrueColor and DirectColor visuals, a pixel value is * formed by OR-ing the red, green, and blue colormap indices * into a single 32-bit word. The visual's color masks tell * you where in the word the indices are supposed to be. The * masks contain bits only where the index is found. By counting * the leading zeros in the mask, we know how many bits to shift * to the individual red, green, and blue values to form a pixel. * * Results: * The number of the least significant bit. * *--------------------------------------------------------------------------- */ static int FindShift(unsigned int mask) /* 32-bit word */ { int bit; for (bit = 0; bit < 32; bit++) { if (mask & (1 << bit)) { break; } } return bit; } /* *--------------------------------------------------------------------------- * * CountBits -- * * Returns the number of bits set in the given 32-bit mask. * * Reference: Graphics Gems Volume II. * * Results: * The number of bits to set in the mask. * * *--------------------------------------------------------------------------- */ static int CountBits(unsigned long mask) /* 32 1-bit tallies */ { /* 16 2-bit tallies */ mask = (mask & 0x55555555) + ((mask >> 1) & (0x55555555)); /* 8 4-bit tallies */ mask = (mask & 0x33333333) + ((mask >> 2) & (0x33333333)); /* 4 8-bit tallies */ mask = (mask & 0x07070707) + ((mask >> 4) & (0x07070707)); /* 2 16-bit tallies */ mask = (mask & 0x000F000F) + ((mask >> 8) & (0x000F000F)); /* 1 32-bit tally */ mask = (mask & 0x0000001F) + ((mask >> 16) & (0x0000001F)); return mask; } /* *--------------------------------------------------------------------------- * * ComputeGammaTables -- * * Initializes both the power and inverse power tables for the * painter with a given gamma value. These tables are used * to/from map linear RGB values to/from non-linear monitor * intensities. * * Results: * The *gammaTable* and *igammaTable* arrays are filled out to * contain the mapped values. * *--------------------------------------------------------------------------- */ static void ComputeGammaTables(Painter *painterPtr) { int i; double igamma, gamma; gamma = painterPtr->gamma; igamma = 1.0 / gamma; for (i = 0; i < 256; i++) { double x, y; y = i / 255.0; x = pow(y, gamma) * 255.0 + 0.5; painterPtr->gammaTable[i] = (unsigned char)CLAMP(x); x = pow(y, igamma) * 255.0 + 0.5; painterPtr->igammaTable[i] = (unsigned char)CLAMP(x); } } /* *--------------------------------------------------------------------------- * * QueryPalette -- * * Queries the X display server for the colors currently used in * the colormap. These values will then be used to map screen * pixels back to RGB values (see Blt_DrawableToPicture). The * queried non-linear color intensities are reverse mapped back * to to linear RGB values. * * Results: * The *palette* array is filled in with the RGB color values * of the colors allocated. * *--------------------------------------------------------------------------- */ static void QueryPalette(Painter *painterPtr, Blt_Pixel *palette) { Visual *visualPtr; XColor colors[256]; visualPtr = painterPtr->visualPtr; assert(visualPtr->map_entries <= 256); if ((visualPtr->class == DirectColor) || (visualPtr->class == TrueColor)) { XColor *cp, *cend; unsigned int nRed, nGreen, nBlue; unsigned int r, g, b; r = g = b = 0; nRed = (painterPtr->rMask >> painterPtr->rShift) + 1; nGreen = (painterPtr->gMask >> painterPtr->gShift) + 1; nBlue = (painterPtr->bMask >> painterPtr->bShift) + 1; for (cp = colors, cend = cp + visualPtr->map_entries; cp < cend; cp++) { cp->pixel = ((r << painterPtr->rShift) | (g << painterPtr->gShift) | (b << painterPtr->bShift)); cp->pad = 0; r++, b++, g++; if (r >= nRed) { r = 0; } if (g >= nGreen) { g = 0; } if (b >= nBlue) { b = 0; } } } else { XColor *cp; int i; for (cp = colors, i = 0; i < visualPtr->map_entries; i++, cp++) { cp->pixel = i; cp->pad = 0; } } #ifdef notdef /* FIXME */ XQueryColors(painterPtr->display, painterPtr->colormap, colors, visualPtr->map_entries); #endif /* Scale to convert XColor component value (0..65535) to unsigned * char (0..255). */ if (painterPtr->gamma == 1.0) { Blt_Pixel *dp, *dend; XColor *cp; double a; a = 1.0 / 257.0; cp = colors; for (dp = palette, dend = dp + visualPtr->map_entries; dp < dend; dp++) { dp->Red = (unsigned char)(cp->red * a + 0.5); dp->Green = (unsigned char)(cp->green * a + 0.5); dp->Blue = (unsigned char)(cp->blue * a + 0.5); cp++; } } else { Blt_Pixel *dp, *dend; XColor *cp; double a; a = 1.0 / 257.0; cp = colors; for (dp = palette, dend = dp + visualPtr->map_entries; dp < dend; dp++) { dp->Red = painterPtr->gammaTable[(int)(cp->red * a + 0.5)]; dp->Green = painterPtr->gammaTable[(int)(cp->green * a + 0.5)]; dp->Blue = painterPtr->gammaTable[(int)(cp->blue * a + 0.5)]; cp++; } } } /* *--------------------------------------------------------------------------- * * ColorRamp -- * * Computes a color ramp based upon the number of colors * available for each color component. It returns an array of * the desired colors (XColor structures). The screen gamma is * factored into the desired colors. * * Results: * Returns the number of colors desired. The *colors* array * is filled out to contain the component values. * *--------------------------------------------------------------------------- */ static int ColorRamp(Painter *painterPtr, XColor *colors) { int nColors; XColor *cp; double rScale, gScale, bScale; double igamma; int i; nColors = 0; /* Suppress compiler warning. */ /* * Calculate the RGB coordinates of the colors we want to allocate * and store them in *colors. */ igamma = 1.0 / painterPtr->gamma; rScale = 255.0 / (painterPtr->nRed - 1); gScale = 255.0 / (painterPtr->nGreen - 1); bScale = 255.0 / (painterPtr->nBlue - 1); switch (painterPtr->visualPtr->class) { case TrueColor: case DirectColor: nColors = MAX3(painterPtr->nRed, painterPtr->nGreen,painterPtr->nBlue); if (painterPtr->isMonochrome) { nColors = painterPtr->nBlue = painterPtr->nGreen = painterPtr->nRed; } /* Compute the 16-bit RGB values from each possible 8-bit * value. */ cp = colors; for (i = 0; i < nColors; i++) { int r, g, b; r = (int)(i * rScale + 0.5); g = (int)(i * gScale + 0.5); b = (int)(i * bScale + 0.5); r = painterPtr->igammaTable[r]; g = painterPtr->igammaTable[g]; b = painterPtr->igammaTable[b]; cp->red = (r << 8) + r; cp->green = (g << 8) + g; cp->blue = (b << 8) + b; cp++; } break; case PseudoColor: case StaticColor: case GrayScale: case StaticGray: nColors = (painterPtr->nRed * painterPtr->nGreen * painterPtr->nBlue); if (painterPtr->isMonochrome) { nColors = painterPtr->nRed; } if (!painterPtr->isMonochrome) { XColor *cp; int i; cp = colors; for (i = 0; i < painterPtr->nRed; i++) { int j; unsigned char r; r = (unsigned char)(i * rScale + 0.5); r = painterPtr->igammaTable[r]; for (j = 0; j < painterPtr->nGreen; j++) { int k; unsigned int g; g = (unsigned char)(j * gScale + 0.5); g = painterPtr->igammaTable[g]; for (k = 0; k < painterPtr->nBlue; k++) { unsigned int b; b = (unsigned char)(k * bScale + 0.5); b = painterPtr->igammaTable[b]; cp->red = (r << 8) | r; cp->green = (g << 8) | g; cp->blue = (b << 8) | b; cp++; } } } } break; default: /* Monochrome */ { XColor *cp; double scale; int i; scale = 255.0 / (nColors - 1); cp = colors; for (i = 0; i < nColors; ++i) { int c; c = (int)(i * scale + 0.5); c = painterPtr->igammaTable[c]; cp->red = cp->green = cp->blue = (c << 8) | c; cp++; } } } /* end switch */ return nColors; } /* *--------------------------------------------------------------------------- * * AllocateColors -- * * Individually allocates each of the desired colors (as * specified by the *colors* array). If a color can't be * allocated the desired colors allocated to that point as * released, the number of component intensities is reduced, * and 0 is returned. * * For TrueColor visuals, we don't need to allocate colors * at all, since we can compute them directly. * * Results: * Returns 1 if all desired colors were allocated successfully. * If unsuccessful, returns 0. All colors allocated up to that * point are freed and a smaller color palette size is computed * and reset in the painter structure. * *--------------------------------------------------------------------------- */ static int AllocateColors(Painter *painterPtr, XColor *colors, int nColors) { if (painterPtr->visualPtr->class == TrueColor) { XColor *cp, *cend; /* * For TrueColor visuals, don't call XAllocColor, compute the * pixel value directly. */ for (cp = colors, cend = cp + nColors; cp < cend; cp++) { unsigned int r, g, b; r = ((cp->red >> 8) >> painterPtr->rAdjust); g = ((cp->green >> 8) >> painterPtr->gAdjust); b = ((cp->blue >> 8) >> painterPtr->bAdjust); /* Shift each color into the proper location of the pixel index. */ r = (r << painterPtr->rShift) & painterPtr->rMask; g = (g << painterPtr->gShift) & painterPtr->gMask; b = (b << painterPtr->bShift) & painterPtr->bMask; cp->pixel = (r | g | b); } painterPtr->nPixels = 0; /* This will indicate that we didn't * use XAllocColor to obtain pixel * values. */ return TRUE; } else { int i; XColor *cp; cp = colors; for (i = 0; i < nColors; i++) { if (!XAllocColor(painterPtr->display, painterPtr->colormap, cp)){ fprintf(stderr, "can't allocate color #%d: r=%x g=%x b=%x\n", i, cp->red, cp->green, cp->blue); break; } #ifdef notdef fprintf(stderr, "picture: allocated r=%x g=%x b=%x\n", colors[i].red, colors[i].green, colors[i].blue); #endif painterPtr->pixels[i] = cp->pixel; cp++; } painterPtr->nPixels = i; /* # of pixels in array */ if (i == nColors) { fprintf(stderr, "painter palette %d/%d/%d colors okay\n", painterPtr->nRed, painterPtr->nGreen, painterPtr->nBlue); return TRUE; /* Success. */ } } /* * If we didn't get all of the colors, free the current palette, * reduce the palette RGB component sizes. */ fprintf(stderr, "can't allocate %d/%d/%d colors\n", painterPtr->nRed, painterPtr->nGreen, painterPtr->nBlue); XFreeColors(painterPtr->display, painterPtr->colormap, painterPtr->pixels, painterPtr->nPixels, 0); return FALSE; } /* *--------------------------------------------------------------------------- * * FillPalette -- * * Base upon the colors allocated, generate two mappings from * the picture's 8-bit RGB components. * * 1) Map 8-bit RGB values to the bits of the pixel. Each component * contains a portion of the pixel value. For mapped visuals * (pseudocolor, staticcolor, grayscale, and staticgray) this * pixel value will be translated to the actual pixel used by * the display. * * 2) Map 8-bit RGB values to the actual color values used. The * color ramp generated may be only a subset of the possible * color values. The resulting palette is used in dithering the * image, using the error between the desired picture RGB value * and the actual value used. * * Results: * Color palette and pixel maps are filled in. * *--------------------------------------------------------------------------- */ static void FillPalette(Painter *painterPtr, XColor *colors, int nColors) { painterPtr->nColors = nColors; if (!painterPtr->isMonochrome) { painterPtr->flags |= PAINER_COLOR_WINDOW; if ((painterPtr->visualPtr->class != DirectColor) && (painterPtr->visualPtr->class != TrueColor)) { painterPtr->flags |= PAINTER_MAP_COLORS; } } if (painterPtr->isMonochrome) { int i; for (i = 0; i < 256; i++) { int c; c = (i + 127) / 255; painterPtr->rBits[i] = colors[c].pixel; painterPtr->palette[i].Blue = painterPtr->palette[i].Green = painterPtr->palette[i].Red = (unsigned char)(c * 255 + 0.5); } } else { int i, rMult; double rScale, gScale, bScale; rMult = painterPtr->nGreen * painterPtr->nBlue; rScale = 255.0 / (painterPtr->nRed - 1); gScale = 255.0 / (painterPtr->nGreen - 1); bScale = 255.0 / (painterPtr->nBlue - 1); for (i = 0; i < 256; i++) { int r, g, b; r = (i * (painterPtr->nRed - 1) + 127) / 255; g = (i * (painterPtr->nGreen - 1) + 127) / 255; b = (i * (painterPtr->nBlue - 1) + 127) / 255; if ((painterPtr->visualPtr->class == DirectColor) || (painterPtr->visualPtr->class == TrueColor)) { painterPtr->rBits[i] = colors[r].pixel & painterPtr->rMask; painterPtr->gBits[i] = colors[g].pixel & painterPtr->gMask; painterPtr->bBits[i] = colors[b].pixel & painterPtr->bMask; } else { painterPtr->rBits[i] = r * rMult; painterPtr->gBits[i] = g * painterPtr->nBlue; painterPtr->bBits[i] = b; } painterPtr->palette[i].Red = (unsigned char)(r * rScale + 0.5); painterPtr->palette[i].Green = (unsigned char)(g * gScale + 0.5); painterPtr->palette[i].Blue = (unsigned char)(b * bScale + 0.5); #ifdef notdef fprintf(stderr, "picture: %d color=%x %x %x\n", i, painterPtr->palette[i].Red, painterPtr->palette[i].Green, painterPtr->palette[i].Blue); #endif } } } /* *--------------------------------------------------------------------------- * * AllocatePalette -- * * This procedure allocates the colors required by a color table, * and sets up the fields in the color table data structure which * are used in dithering. * * This routine essentially mimics what is done in tkImgPhoto.c. * It's purpose is to allocate exactly the same color ramp as the * photo image. That way both image types can co-exist without * fighting over available colors. * * Results: * None. * * Side effects: * Colors are allocated from the X server. The color palette * and pixel indices are updated. * *--------------------------------------------------------------------------- */ static void AllocatePalette( Painter *painterPtr) /* Pointer to the color table requiring * colors to be allocated. */ { XColor colors[256]; int nColors; static int stdPalettes[13][3] = { /* nRed, nGreen, nBlue */ { 2, 2, 2 }, /* 3 bits, 8 colors */ { 2, 3, 2 }, /* 4 bits, 12 colors */ { 3, 4, 2 }, /* 5 bits, 24 colors */ { 4, 5, 3 }, /* 6 bits, 60 colors */ { 5, 6, 4 }, /* 7 bits, 120 colors */ { 7, 7, 4 }, /* 8 bits, 198 colors */ { 8, 10, 6 }, /* 9 bits, 480 colors */ { 10, 12, 8 }, /* 10 bits, 960 colors */ { 14, 15, 9 }, /* 11 bits, 1890 colors */ { 16, 20, 12 }, /* 12 bits, 3840 colors */ { 20, 24, 16 }, /* 13 bits, 7680 colors */ { 26, 30, 20 }, /* 14 bits, 15600 colors */ { 32, 32, 30 }, /* 15 bits, 30720 colors */ }; painterPtr->isMonochrome = FALSE; switch (painterPtr->visualPtr->class) { case TrueColor: case DirectColor: painterPtr->nRed = 1 << CountBits(painterPtr->rMask); painterPtr->nGreen = 1 << CountBits(painterPtr->gMask); painterPtr->nBlue = 1 << CountBits(painterPtr->bMask); break; case GrayScale: case StaticGray: case PseudoColor: case StaticColor: if (painterPtr->depth > 15) { painterPtr->nRed = painterPtr->nGreen = painterPtr->nBlue = 32; } else if (painterPtr->depth >= 3) { int *ip = stdPalettes[painterPtr->depth - 3]; painterPtr->nRed = ip[0]; painterPtr->nGreen = ip[1]; painterPtr->nBlue = ip[2]; } break; default: painterPtr->nGreen = painterPtr->nBlue = 0; painterPtr->nRed = 1 << painterPtr->depth; painterPtr->isMonochrome = TRUE; break; } /* * Each time around this loop, we reduce the number of colors * we're trying to allocate until we succeed in allocating all of * the colors we need. */ for (;;) { /* * If we are using 1 bit/pixel, we don't need to allocate any * colors (we just use the foreground and background colors in * the GC). */ if ((painterPtr->isMonochrome) && (painterPtr->nRed <= 2)) { painterPtr->flags |= BLACK_AND_WHITE; /* return; */ } /* * Calculate the RGB values of a color ramp, given the some * number of red, green, blue intensities available. */ nColors = ColorRamp(painterPtr, colors); /* Now try to allocate the colors we've calculated. */ if (AllocateColors(painterPtr, colors, nColors)) { break; /* Success. */ } if (!painterPtr->isMonochrome) { if ((painterPtr->nRed == 2) && (painterPtr->nGreen == 2) && (painterPtr->nBlue == 2)) { break; /* Fall back to 1-bit monochrome display. */ /* painterPtr->mono = TRUE; */ } else { /* * Reduce the number of shades of each primary to * about 3/4 of the previous value. This will reduce * the total number of colors required to less than * half (27/64) the previous value for PseudoColor * displays. */ painterPtr->nRed = (painterPtr->nRed * 3 + 2) / 4; painterPtr->nGreen = (painterPtr->nGreen * 3 + 2) / 4; painterPtr->nBlue = (painterPtr->nBlue * 3 + 2) / 4; } } else { painterPtr->nRed /= 2; } } FillPalette(painterPtr, colors, nColors); } /* *--------------------------------------------------------------------------- * * NewPainter -- * * Creates a new painter to be used to paint pictures. Painters * are keyed by the combination of display, colormap, visual, * depth, and gamma value used. * * Results: * A pointer to the new painter is returned. * * Side Effects: * A color ramp is allocated (not true for TrueColor visuals). * Gamma tables are computed and filled. * *--------------------------------------------------------------------------- */ static Painter * NewPainter(PainterKey *keyPtr) { Painter *painterPtr; painterPtr = Blt_AssertCalloc(1, sizeof(Painter)); painterPtr->colormap = keyPtr->colormap; painterPtr->depth = keyPtr->depth; painterPtr->display = keyPtr->display; painterPtr->gamma = keyPtr->gamma; painterPtr->visualPtr = keyPtr->visualPtr; painterPtr->refCount = 0; painterPtr->rMask = (unsigned int)painterPtr->visualPtr->red_mask; painterPtr->gMask = (unsigned int)painterPtr->visualPtr->green_mask; painterPtr->bMask = (unsigned int)painterPtr->visualPtr->blue_mask; painterPtr->rShift = FindShift(painterPtr->rMask); painterPtr->gShift = FindShift(painterPtr->gMask); painterPtr->bShift = FindShift(painterPtr->bMask); painterPtr->rAdjust = painterPtr->gAdjust = painterPtr->bAdjust = 0; { int nRedBits, nGreenBits, nBlueBits; nRedBits = CountBits(painterPtr->rMask); nGreenBits = CountBits(painterPtr->gMask); nBlueBits = CountBits(painterPtr->bMask); if (nRedBits < 8) { painterPtr->rAdjust = 8 - nRedBits; } if (nGreenBits < 8) { painterPtr->gAdjust = 8 - nGreenBits; } if (nBlueBits < 8) { painterPtr->bAdjust = 8 - nBlueBits; } } ComputeGammaTables(painterPtr); AllocatePalette(painterPtr); return painterPtr; } /* *--------------------------------------------------------------------------- * * FreePainter -- * * Called when the TCL interpreter is idle, this routine frees the * painter. Painters are reference counted. Only when no clients * are using the painter (the count is zero) is the painter * actually freed. By deferring its deletion, this allows client * code to call Blt_GetPainter after Blt_FreePainter without * incurring a performance penalty. * *--------------------------------------------------------------------------- */ static void FreePainter(DestroyData data) { Painter *painterPtr = (Painter *)data; if (painterPtr->refCount <= 0) { if (painterPtr->nColors > 0) { XFreeColors(painterPtr->display, painterPtr->colormap, painterPtr->pixels, painterPtr->nPixels, 0); } Blt_DeleteHashEntry(&painterTable, painterPtr->hashPtr); if (painterPtr->gc != NULL) { if (painterPtr->flags & GC_PRIVATE) { XFreeGC(painterPtr->display, painterPtr->gc); } else { Tk_FreeGC(painterPtr->display, painterPtr->gc); } painterPtr->gc = NULL; } Blt_Free(painterPtr); } } /* *--------------------------------------------------------------------------- * * GetPainter -- * * Attempts to retrieve a painter for a particular combination of * display, colormap, visual, depth, and gamma value. If no * specific painter exists, then one is created. * * Results: * A pointer to the new painter is returned. * * Side Effects: * If no current painter exists, a new painter is added to the * hash table of painters. Otherwise, the current painter's * reference count is incremented indicated how many clients * are using the painter. * *--------------------------------------------------------------------------- */ static Painter * GetPainter( Display *display, Colormap colormap, Visual *visualPtr, int depth, double gamma) { Painter *painterPtr; PainterKey key; int isNew; Blt_HashEntry *hPtr; if (!initialized) { Blt_InitHashTable(&painterTable, sizeof(PainterKey) / sizeof(int)); initialized = TRUE; } key.display = display; key.colormap = colormap; key.visualPtr = visualPtr; key.depth = depth; key.gamma = gamma; hPtr = Blt_CreateHashEntry(&painterTable, (char *)&key, &isNew); if (isNew) { painterPtr = NewPainter(&key); painterPtr->hashPtr = hPtr; Blt_SetHashValue(hPtr, painterPtr); } else { painterPtr = Blt_GetHashValue(hPtr); } painterPtr->refCount++; return painterPtr; } /* *--------------------------------------------------------------------------- * * Blt_GetPainterFromDrawable -- * * Gets a painter for a particular combination of display, * colormap, visual, depth, and gamma value. This information is * retrieved from the drawable which is assumed to be a window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainterFromDrawable( Display *display, Drawable drawable, double gamma) { XGCValues gcValues; unsigned long gcMask; Painter *painterPtr; Colormap colormap; int screenNum; Visual *visual; int depth; screenNum = 0; /* Need colormap, visual, depth. */ colormap = DefaultColormap(display, DefaultScreen(display)); visual = DefaultVisual(display, screenNum); depth = DefaultDepth(display, screenNum); painterPtr = GetPainter(display, colormap, visual, depth, gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; painterPtr->gc = XCreateGC(display, drawable, gcMask, &gcValues); painterPtr->flags |= GC_PRIVATE; return painterPtr; } /* *--------------------------------------------------------------------------- * * Blt_GetPainter -- * * Gets a painter for a particular combination of display, * colormap, visual, depth, and gamma value. This information * (except for the monitor's gamma value) is retrieved from the * given Tk window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainter(Tk_Window tkwin, double gamma) { Painter *painterPtr; XGCValues gcValues; unsigned long gcMask; painterPtr = GetPainter(Tk_Display(tkwin), Tk_Colormap(tkwin), Tk_Visual(tkwin), Tk_Depth(tkwin), gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; painterPtr->gc = Tk_GetGC(tkwin, gcMask, &gcValues); painterPtr->flags &= ~GC_PRIVATE; return painterPtr; } /* *--------------------------------------------------------------------------- * * Blt_FreePainter -- * * Frees the painter. Painters are reference counted. Only when * no clients are using the painter (the count is zero) is the * painter actually freed. * *--------------------------------------------------------------------------- */ void Blt_FreePainter(Painter *painterPtr) { painterPtr->refCount--; if (painterPtr->refCount <= 0) { Tcl_EventuallyFree(painterPtr, FreePainter); } } /* *--------------------------------------------------------------------------- * * DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Picture DrawableToPicture( Painter *painterPtr, Drawable drawable, int x, int y, int width, int height) /* Dimension of the drawable. */ { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr srcPort, destPort; Picture *destPtr; srcPort = TkMacOSXGetDrawablePort(drawable); destPtr = Blt_CreatePicture(width, height); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, x, y, x + width, y + height); SetRect(&destRect, 0, 0, width, height); GetGWorld(&saveWorld, &saveDevice); SetGWorld(srcPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)destPtr->bits; pm.rowBytes = destPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, * not a BitMap. */ CopyBits(GetPortBitMapForCopyBits(destPort), (BitMap *)&pm, &srcRect, &destRect, srcCopy, NULL); } SetGWorld(saveWorld, saveDevice); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_WindowToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * This routine is used to snap foreign (non-Tk) windows. For * pixmaps and Tk windows, Blt_DrawableToPicture is preferred. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_WindowToPicture( Display *display, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainterFromDrawable(display, drawable, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } /* *--------------------------------------------------------------------------- * * Blt_DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_DrawableToPicture( Tk_Window tkwin, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainter(tkwin, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } Pixmap Blt_PhotoImageMask( Tk_Window tkwin, Tk_PhotoImageBlock src) { TkWinBitmap *twdPtr; int offset, count; int x, y; unsigned char *srcPtr; int destBytesPerRow; int destHeight; unsigned char *destBits; destBytesPerRow = ((src.width + 31) & ~31) / 8; destBits = Blt_AssertCalloc(src.height, destBytesPerRow); destHeight = src.height; offset = count = 0; /* FIXME: figure out why this is so! */ for (y = src.height - 1; y >= 0; y--) { srcPtr = src.pixelPtr + offset; for (x = 0; x < src.width; x++) { if (srcPtr[src.offset[3]] == 0x00) { SetBit(x, y); count++; } srcPtr += src.pixelSize; } offset += src.pitch; } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = src.width; bm.bmHeight = src.height; bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } Pixmap Blt_PictureMask( Tk_Window tkwin, Blt_Picture pict) { TkWinBitmap *twdPtr; int count; int x, y; Blt_Pixel *sp; int destBytesPerRow; int destWidth, destHeight; unsigned char *destBits; destWidth = Blt_PictureWidth(pict); destHeight = Blt_PictureHeight(pict); destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); count = 0; sp = Blt_PictureBits(pict); for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { if (sp->Alpha == 0x00) { SetBit(x, y); count++; } sp++; } } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = Blt_PictureWidth(pict); bm.bmHeight = Blt_PictureHeight(pict); bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given * bitmap. We also need a special GC of depth 1, so that we do * not need to rotate more than one plane of the bitmap. * * Note that under Windows, monochrome bitmaps are stored * bottom-to-top. This is why the right angle rotations 0/180 * and 90/270 look reversed. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* Right angle rotation to perform */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; double rotWidth, rotHeight; HDC hDC; TkWinDCState state; int x, y; /* Destination bitmap coordinates */ int sx, sy; /* Source bitmap coordinates */ unsigned long pixel; HBITMAP hBitmap; int result; struct MonoBitmap { BITMAPINFOHEADER bi; RGBQUAD colors[2]; } mb; int srcBytesPerRow, destBytesPerRow; int destWidth, destHeight; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = (int)ceil(rotWidth); destHeight = (int)ceil(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; /* Handle right-angle rotations specially. */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { sx = y; for (x = 0; x < destWidth; x++) { sy = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sx = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sy = x; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { pixel = GetBit(x, y); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double srcCX, srcCY; /* Center of source rectangle */ double destCX, destCY; /* Center of destination rectangle */ double tx, ty; double rx, ry; /* Angle of rotation for x and y coordinates */ radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ srcCX = srcWidth * 0.5; srcCY = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* Rotate each pixel of dest image, placing results in source image */ for (y = 0; y < destHeight; y++) { ty = y - destCY; for (x = 0; x < destWidth; x++) { /* Translate origin to center of destination image */ tx = x - destCX; /* Rotate the coordinates about the origin */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image */ rx += srcCX; ry += srcCY; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bi.biSize = sizeof(BITMAPINFOHEADER); mb.bi.biPlanes = 1; mb.bi.biBitCount = 1; mb.bi.biCompression = BI_RGB; mb.bi.biWidth = destWidth; mb.bi.biHeight = destHeight; mb.bi.biSizeImage = destBytesPerRow * destHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, destHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } *destWidthPtr = destWidth; *destHeightPtr = destHeight; return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { TkWinDCState srcState, destState; HDC src, dest; Pixmap destBitmap; Window root; Display *display; /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; } src = TkWinGetDrawableDC(display, srcBitmap, &srcState); dest = TkWinGetDrawableDC(display, destBitmap, &destState); StretchBlt(dest, 0, 0, destWidth, destHeight, src, 0, 0, srcWidth, srcHeight, SRCCOPY); TkWinReleaseDrawableDC(srcBitmap, src, &srcState); TkWinReleaseDrawableDC(destBitmap, dest, &destState); return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleRotateBitmapRegion -- * * Creates a scaled and rotated bitmap from a given bitmap. The * caller also provides (offsets and dimensions) the region of * interest in the destination bitmap. This saves having to * process the entire destination bitmap is only part of it is * showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the * destination image. For each pixel, the corresponding * pixel in the source bitmap is used. This means that * destination coordinates are first scaled to the size of * the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapRegion( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual * destination bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int virtWidth, unsigned int virtHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Pixmap destBitmap; Window root; /* Root window drawable */ double rWidth, rHeight; double xScale, yScale; int srcBytesPerRow, destBytesPerRow; int destHeight; int result; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((regionWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(regionHeight, destBytesPerRow); destHeight = regionHeight; angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rWidth, &rHeight, (Point2d *)NULL); xScale = rWidth / (double)virtWidth; yScale = rHeight / (double)virtHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(y+regionY)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sy; sy = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sx; sx = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < (int)regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double scx, scy; /* Offset from the center of the * source rectangle. */ double rcx, rcy; /* Offset to the center of the * rotated rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ scx = srcWidth * 0.5; scy = srcHeight * 0.5; rcx = rWidth * 0.5; rcy = rHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < (int)regionHeight; y++) { int x; double ty; /* Translated coordinates from center */ ty = (yScale * (double)(y + regionY)) - rcy; for (x = 0; x < (int)regionWidth; x++) { double rx, ry; /* Angle of rotation for x and y coordinates */ double tx; /* Translated coordinates from center */ int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rcx; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += scx; ry += scy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= (int)srcWidth) || (sx < 0) || (sy >= (int)srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } { HBITMAP hBitmap; HDC hDC; TkWinDCState state; struct MonoBitmap { BITMAPINFOHEADER bmiHeader; RGBQUAD colors[2]; } mb; /* Write the rotated image into the destination bitmap. */ hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mb.bmiHeader.biPlanes = 1; mb.bmiHeader.biBitCount = 1; mb.bmiHeader.biCompression = BI_RGB; mb.bmiHeader.biWidth = regionWidth; mb.bmiHeader.biHeight = regionHeight; mb.bmiHeader.biSizeImage = destBytesPerRow * regionHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, regionHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); } if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } return destBitmap; } #ifdef HAVE_IJL_H #include <ijl.h> Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { JPEG_CORE_PROPERTIES jpgProps; Blt_Picture pict; ZeroMemory(&jpgProps, sizeof(JPEG_CORE_PROPERTIES)); if(ijlInit(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't initialize Intel JPEG library", (char *)NULL); return NULL; } jpgProps.JPGFile = fileName; if (ijlRead(&jpgProps, IJL_JFILE_READPARAMS) != IJL_OK) { Tcl_AppendResult(interp, "can't read JPEG file header from \"", fileName, "\" file.", (char *)NULL); goto error; } // !dudnik: to fix bug case 584680, [OT:287A305B] // Set the JPG color space ... this will always be // somewhat of an educated guess at best because JPEG // is "color blind" (i.e., nothing in the bit stream // tells you what color space the data was encoded from). // However, in this example we assume that we are // reading JFIF files which means that 3 channel images // are in the YCbCr color space and 1 channel images are // in the Y color space. switch(jpgProps.JPGChannels) { case 1: jpgProps.JPGColor = IJL_G; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 3: jpgProps.JPGColor = IJL_YCBCR; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 4: jpgProps.JPGColor = IJL_YCBCRA_FPX; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; default: /* This catches everything else, but no color twist will be performed by the IJL. */ jpgProps.DIBColor = (IJL_COLOR)IJL_OTHER; jpgProps.JPGColor = (IJL_COLOR)IJL_OTHER; jpgProps.DIBChannels = jpgProps.JPGChannels; break; } jpgProps.DIBWidth = jpgProps.JPGWidth; jpgProps.DIBHeight = jpgProps.JPGHeight; jpgProps.DIBPadBytes = IJL_DIB_PAD_BYTES(jpgProps.DIBWidth, jpgProps.DIBChannels); pict = Blt_CreatePicture(jpgProps.JPGWidth, jpgProps.JPGHeight); jpgProps.DIBBytes = (BYTE *)Blt_PictureBits(pict); if (ijlRead(&jpgProps, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { Tcl_AppendResult(interp, "can't read image data from \"", fileName, "\"", (char *)NULL); goto error; } if (ijlFree(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't free Intel(R) JPEG library.", (char *)NULL); } return pict; error: ijlFree(&jpgProps); if (pict != NULL) { Blt_FreePicture(pict); } ijlFree(&jpgProps); return NULL; } #else #ifdef HAVE_JPEGLIB_H #undef HAVE_STDLIB_H #ifdef WIN32 #define XMD_H 1 #endif #include "jpeglib.h" #include <setjmp.h> typedef struct { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf jmpBuf; Tcl_DString dString; } ReaderHandler; static void ErrorProc(j_common_ptr jpegInfo); static void MessageProc(j_common_ptr jpegInfo); /* * Here's the routine that will replace the standard error_exit method: */ static void ErrorProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; (*handlerPtr->pub.output_message) (jpgPtr); longjmp(handlerPtr->jmpBuf, 1); } static void MessageProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; char buffer[JMSG_LENGTH_MAX]; /* Create the message and append it into the dynamic string. */ (*handlerPtr->pub.format_message) (jpgPtr, buffer); Tcl_DStringAppend(&handlerPtr->dString, " ", -1); Tcl_DStringAppend(&handlerPtr->dString, buffer, -1); } /* *--------------------------------------------------------------------------- * * Blt_JPEGToPicture -- * * Reads a JPEG file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { struct jpeg_decompress_struct jpg; Blt_Picture pict; unsigned int pictWidth, pictHeight; Blt_Pixel *dp; ReaderHandler handler; FILE *f; JSAMPLE **readBuffer; int row_stride; int i; JSAMPLE *bufPtr; f = Blt_OpenFile(interp, fileName, "rb"); if (f == NULL) { return NULL; } pict = NULL; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ jpg.dct_method = JDCT_IFAST; jpg.err = jpeg_std_error(&handler.pub); handler.pub.error_exit = ErrorProc; handler.pub.output_message = MessageProc; Tcl_DStringInit(&handler.dString); Tcl_DStringAppend(&handler.dString, "error reading \"", -1); Tcl_DStringAppend(&handler.dString, fileName, -1); Tcl_DStringAppend(&handler.dString, "\": ", -1); if (setjmp(handler.jmpBuf)) { jpeg_destroy_decompress(&jpg); fclose(f); Tcl_DStringResult(interp, &handler.dString); return NULL; } jpeg_create_decompress(&jpg); jpeg_stdio_src(&jpg, f); jpeg_read_header(&jpg, TRUE); /* Step 3: read file parameters */ jpeg_start_decompress(&jpg); /* Step 5: Start decompressor */ pictWidth = jpg.output_width; pictHeight = jpg.output_height; if ((pictWidth < 1) || (pictHeight < 1)) { Tcl_AppendResult(interp, "bad JPEG image size", (char *)NULL); fclose(f); return NULL; } /* JSAMPLEs per row in output buffer */ row_stride = pictWidth * jpg.output_components; /* Make a one-row-high sample array that will go away when done * with image */ readBuffer = (*jpg.mem->alloc_sarray) ((j_common_ptr)&jpg, JPOOL_IMAGE, row_stride, 1); pict = Blt_CreatePicture(pictWidth, pictHeight); dp = Blt_PictureBits(pict); if (jpg.output_components == 1) { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = dp->Green = dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } else { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = *bufPtr++; dp->Green = *bufPtr++; dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } jpeg_finish_decompress(&jpg); /* We can ignore the return value * since suspension is not * possible with the stdio data * source. */ jpeg_destroy_decompress(&jpg); /* * After finish_decompress, we can close the input file. Here we * postpone it until after no more JPEG errors are possible, so as * to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume * anything...) */ fclose(f); /* * At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ if (handler.pub.num_warnings > 0) { Tcl_SetErrorCode(interp, "IMAGE", "JPEG", Tcl_DStringValue(&handler.dString), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } /* * We're ready to call the Tk_Photo routines. They'll take the RGB * array we've processed to build the Tk image of the JPEG. */ Tcl_DStringFree(&handler.dString); return pict; } #endif /* HAVE_JPEGLIB_H */ #endif /* HAVE_IJL_H */ /* *--------------------------------------------------------------------------- * * PaintPicture -- * * Paints the picture to the given drawable. The region of * the picture is specified and the coordinates where in the * destination drawable is the image to be displayed. * * The image may be dithered depending upon the bit set in * the flags parameter: 0 no dithering, 1 for dithering. * * Results: * Returns TRUE is the picture was successfully display, * Otherwise FALSE is returned if the particular combination * visual and image depth is not handled. * *--------------------------------------------------------------------------- */ static int PaintPicture( Painter *painterPtr, Drawable drawable, Picture *srcPtr, int srcX, int srcY, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Region * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; Picture *ditherPtr; ditherPtr = NULL; if (flags & BLT_PAINTER_DITHER) { ditherPtr = Blt_DitherPicture(srcPtr, painterPtr->palette); if (ditherPtr != NULL) { srcPtr = ditherPtr; } } destPort = TkMacOSXGetDrawablePort(drawable); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, srcX, srcY, srcX + width, srcY + height); SetRect(&destRect, destX + dstDraw->xOffset, destY + dstDraw->yOffset, destX + width + dstDraw->xOffset, destY + height + dstDraw->yOffset); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)srcPtr->bits; pm.rowBytes = srcPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, * not a BitMap. */ CopyBits((BitMap *)&pm, GetPortBitMapForCopyBits(destPort), &srcRect, &destRect, srcCopy, NULL); } if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } SetGWorld(saveWorld, saveDevice); return TRUE; } /* *--------------------------------------------------------------------------- * * PaintPictureWithBlend -- * * Blends and paints the picture with the given drawable. The * region of the picture is specified and the coordinates where * in the destination drawable is the image to be displayed. * * The background is snapped from the drawable and converted into * a picture. This picture is then blended with the current * picture (the background always assumed to be 100% opaque). * * Results: * Returns TRUE is the picture was successfully display, * Otherwise FALSE is returned. This may happen if the * background can not be obtained from the drawable. * *--------------------------------------------------------------------------- */ static int PaintPictureWithBlend( Painter *painterPtr, Drawable drawable, Blt_Picture fg, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Region * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, int alpha) { Blt_Picture bg; if (destX < 0) { width += destX; destX = 0; } if (destY < 0) { height += destY; destY = 0; } if ((width < 0) || (height < 0)) { return FALSE; } bg = DrawableToPicture(painterPtr, drawable, destX, destY, width, height); if (bg == NULL) { return FALSE; } #ifdef notdef Blt_FadePicture(bg, fg, x, y, width, height, 0, 0, alpha); #else Blt_BlendPictures(bg, fg, x, y, bg->width, bg->height, 0, 0); #endif PaintPicture(painterPtr, drawable, bg, 0, 0, bg->width, bg->height, destX, destY, flags); Blt_FreePicture(bg); return TRUE; } int Blt_PaintPicture( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Region * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { if ((picture == NULL) || (x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))) { /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } if ((width <= 0) || (height <= 0)) { return TRUE; } if (Blt_IsOpaquePicture(picture)) { return PaintPicture(painter, drawable, picture, x, y, width, height, destX, destY, flags); } else { int alpha = 128; return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } } int Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Region * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, /* Indicates whether to dither the * picture before displaying. */ double falpha) { int alpha; alpha = (int)(falpha * 255.0 + 0.5); assert((x >= 0) && (y >= 0)); /* assert((destX >= 0) && (destY >= 0)); */ assert((width >= 0) && (height >= 0)); if ((x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))){ /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } /* * Check that the region defined does not extend beyond the end of * the picture. * * Clip the end of the region if it is too big. */ if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } GC Blt_PainterGC(Painter *painterPtr) { return painterPtr->gc; } int Blt_PainterDepth(Painter *painterPtr) { return painterPtr->depth; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltParse.h��������������������������������������������������������������������0000644�0001750�0001750�00000003221�11462120062�014750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltParse.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_PARSE_H #define _BLT_PARSE_H #include "tclInterp.h" BLT_EXTERN int Blt_ParseBraces(Tcl_Interp *interp, const char *string, const char **termPtr, ParseValue *pvPtr); BLT_EXTERN int Blt_ParseNestedCmd(Tcl_Interp *interp, const char *string, int flags, const char **termPtr, ParseValue *pvPtr); BLT_EXTERN int Blt_ParseQuotes(Tcl_Interp *interp, const char *string, int termChar, int flags, const char **termPtr, ParseValue * pvPtr); BLT_EXTERN void Blt_ExpandParseValue(ParseValue *pvPtr, int needed); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDtTree.c�������������������������������������������������������������������0000644�0001750�0001750�00000021706�11462120062�015070� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtTree.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #include "config.h" #ifndef NO_DATATABLE #include <tcl.h> #include <bltDataTable.h> #include <bltTree.h> #include <bltSwitch.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ /* * Format Import Export * csv file/data file/data * tree data data * vector data data * xml file/data file/data * sql data data * * $table import csv -file fileName -data dataString * $table export csv -file defaultFileName * $table import tree $treeName $node ?switches? * $table export tree $treeName $node "label" "label" "label" * $table import vector $vecName label $vecName label... * $table export vector label $vecName label $vecName... * $table import xml -file fileName -data dataString ?switches? * $table export xml -file fileName -data dataString ?switches? * $table import sql -host $host -password $pw -db $db -port $port */ /* * ExportSwitches -- */ typedef struct { /* Private data. */ Blt_TreeNode node; /* Public fields */ Blt_TableIterator rIter, cIter; Blt_TableIterator hIter; Tcl_Obj *nodeObjPtr; } ExportSwitches; BLT_EXTERN Blt_SwitchFreeProc Blt_Table_ColumnIterFreeProc; BLT_EXTERN Blt_SwitchFreeProc Blt_Table_RowIterFreeProc; BLT_EXTERN Blt_SwitchParseProc Blt_Table_ColumnIterSwitchProc; BLT_EXTERN Blt_SwitchParseProc Blt_Table_RowIterSwitchProc; static Blt_SwitchCustom columnIterSwitch = { Blt_Table_ColumnIterSwitchProc, Blt_Table_ColumnIterFreeProc, 0, }; static Blt_SwitchCustom rowIterSwitch = { Blt_Table_RowIterSwitchProc, Blt_Table_RowIterFreeProc, 0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-columns", "columns", Blt_Offset(ExportSwitches, cIter), 0, 0, &columnIterSwitch}, {BLT_SWITCH_CUSTOM, "-hierarchy", "columns", Blt_Offset(ExportSwitches, hIter), 0, 0, &columnIterSwitch}, {BLT_SWITCH_OBJ, "-node", "node", Blt_Offset(ExportSwitches, nodeObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-rows", "rows", Blt_Offset(ExportSwitches, rIter), 0, 0, &rowIterSwitch}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_Table_TreeInit; static Blt_TableImportProc ImportTreeProc; static Blt_TableExportProc ExportTreeProc; static int ImportTree(Tcl_Interp *interp, Blt_Table table, Blt_Tree tree, Blt_TreeNode top) { Blt_TreeNode node; int maxDepth, topDepth; long iRow, nCols; /* * Fill in the table data in 2 passes. We need to know the * maximum depth of the leaf nodes, to generate columns for each * level of the hierarchy. We have to do this before adding * node data values. */ /* Pass 1. Create entries for all the nodes. Add entries for * the node and it's ancestor's labels. */ maxDepth = topDepth = Blt_Tree_NodeDepth(top); nCols = Blt_Table_NumColumns(table); for (node = Blt_Tree_NextNode(top, top); node != NULL; node = Blt_Tree_NextNode(top, node)) { Blt_TreeNode parent; int depth; Blt_TableRow row; size_t iCol; depth = Blt_Tree_NodeDepth(node); if (depth > maxDepth) { Blt_TableColumn col; if (Blt_Table_ExtendColumns(interp, table, 1, &col) != TCL_OK) { return TCL_ERROR; } iCol = Blt_Table_ColumnIndex(col); maxDepth = depth; } else { iCol = depth - topDepth; } if (Blt_Table_ExtendRows(interp, table, 1, &row) != TCL_OK) { return TCL_ERROR; } for (parent = node; parent != top; parent = Blt_Tree_ParentNode(parent)){ const char *label; Blt_TableColumn col; col = Blt_Table_FindColumnByIndex(table, iCol); label = Blt_Tree_NodeLabel(parent); if (Blt_Table_SetString(table, row, col, label, -1)!=TCL_OK) { return TCL_ERROR; } iCol--; } } /* Pass 2. Fill in entries for all the data fields found. */ for (iRow = 1, node = Blt_Tree_NextNode(top, top); node != NULL; node = Blt_Tree_NextNode(top, node), iRow++) { Blt_TreeKey key; Blt_TreeKeyIterator iter; Blt_TableRow row; row = Blt_Table_FindRowByIndex(table, iRow); for (key = Blt_Tree_FirstKey(tree, node, &iter); key != NULL; key = Blt_Tree_NextKey(tree, &iter)) { Blt_TableColumn col; Tcl_Obj *objPtr; if (Blt_Tree_GetValue(interp, tree, node, key, &objPtr) != TCL_OK) { return TCL_ERROR; } col = Blt_Table_FindColumnByLabel(table, key); if (col == NULL) { col = Blt_Table_CreateColumn(interp, table, key); if (col == NULL) { return TCL_ERROR; } } if (Blt_Table_SetObj(table, row, col, objPtr) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } static int ImportTreeProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Tree tree; Blt_TreeNode node; /* FIXME: * 2. Export *GetNode tag parsing routines from bltTreeCmd.c, * instead of using node id to select the top node. */ tree = Blt_Tree_Open(interp, Tcl_GetString(objv[3]), 0); if (tree == NULL) { return TCL_ERROR; } if (objc == 5) { long inode; if (Tcl_GetLongFromObj(interp, objv[4], &inode) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_GetNode(tree, inode); if (node == NULL) { return TCL_ERROR; } } else { node = Blt_Tree_RootNode(tree); } return ImportTree(interp, table, tree, node); } static int ExportTree(Tcl_Interp *interp, Blt_Table table, Blt_Tree tree, Blt_TreeNode parent, ExportSwitches *switchesPtr) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&switchesPtr->rIter); row != NULL; row = Blt_Table_NextTaggedRow(&switchesPtr->rIter)) { Blt_TableColumn col; Blt_TreeNode node; const char *label; label = Blt_Table_RowLabel(row); node = Blt_Tree_CreateNode(tree, parent, label, -1); for (col = Blt_Table_FirstTaggedColumn(&switchesPtr->cIter); col != NULL; col = Blt_Table_NextTaggedColumn(&switchesPtr->cIter)) { Tcl_Obj *objPtr; const char *key; objPtr = Blt_Table_GetObj(table, row, col); key = Blt_Table_ColumnLabel(col); if (Blt_Tree_SetValue(interp, tree, node, key, objPtr) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } static int ExportTreeProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Tree tree; Blt_TreeNode node; ExportSwitches switches; int result; if (objc < 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", Tcl_GetString(objv[0]), " export tree treeName ?switches?\"", (char *)NULL); return TCL_ERROR; } tree = Blt_Tree_Open(interp, Tcl_GetString(objv[3]), 0); if (tree == NULL) { return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); rowIterSwitch.clientData = table; columnIterSwitch.clientData = table; Blt_Table_IterateAllRows(table, &switches.rIter); Blt_Table_IterateAllColumns(table, &switches.cIter); if (Blt_ParseSwitches(interp, exportSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.nodeObjPtr != NULL) { long inode; if (Tcl_GetLongFromObj(interp, switches.nodeObjPtr, &inode) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_GetNode(tree, inode); if (node == NULL) { return TCL_ERROR; } } else { node = Blt_Tree_RootNode(tree); } result = ExportTree(interp, table, tree, node, &switches); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return result; } int Blt_Table_TreeInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_datatable_tree", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_Table_RegisterFormat(interp, "tree", /* Name of format. */ ImportTreeProc, /* Import procedure. */ ExportTreeProc); /* Export procedure. */ } #endif /* NO_DATATABLE */ ����������������������������������������������������������./saods9/blt3.0.1/src/bltCrc32.c��������������������������������������������������������������������0000644�0001750�0001750�00000017533�11462120062�014560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltCrc32.c -- * * This module implements a CRC32 procedure for the BLT toolkit. * * Copyright 1991-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <stdio.h> /* open a file * calculate the CRC32 of the entire contents * return the CRC * if there is an error rdet the global variable Crcerror */ /* -------------------------------------------------------------------------- */ /* * this is the CRC32 lookup table * thanks Gary S. Brown * 64 lines of 4 values for a 256 dword table (1024 bytes) */ static unsigned long crc32[256] = { /* CRC polynomial 0xedb88320 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; #define CRC32(c, b) (crc32[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) static int Crc32FromObj(Tcl_Obj *objPtr, unsigned long *sumPtr) { char *bp, *bend, *buffer; int nBytes; unsigned long sum; buffer = Tcl_GetStringFromObj(objPtr, &nBytes); sum = *sumPtr; for (bp = buffer, bend = bp + nBytes; bp < bend; bp++) { sum = CRC32(sum, *bp); } *sumPtr = sum; return TCL_OK; } static int Crc32File(Tcl_Interp *interp, char *fileName, unsigned long *sumPtr) { Tcl_Channel channel; int closeChannel; int done; unsigned long sum; #define BUFFSIZE 8192 closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for writing", (char *)NULL); return TCL_ERROR; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return TCL_ERROR; } } if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") != TCL_OK) { return TCL_ERROR; } done = FALSE; sum = *sumPtr; while (!done) { char *bp, *bend; int nBytes; #define BUFFSIZE 8192 char buffer[BUFFSIZE]; nBytes = Tcl_Read(channel, buffer, sizeof(char) * BUFFSIZE); if (nBytes < 0) { Tcl_AppendResult(interp, "\nread error: ", Tcl_PosixError(interp), (char *)NULL); if (closeChannel) { Tcl_Close(interp, channel); } return TCL_ERROR; } done = Tcl_Eof(channel); for (bp = buffer, bend = bp + nBytes; bp < bend; bp++) { sum = CRC32(sum, *bp); } } if (closeChannel) { Tcl_Close(interp, channel); } *sumPtr = sum; return TCL_OK; } /*ARGSUSED*/ static int Crc32Cmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { unsigned long crc; crc = 0L; crc = crc ^ 0xffffffffUL; if (objc == 2) { if (Crc32File(interp, Tcl_GetString(objv[1]), &crc) != TCL_OK) { return TCL_ERROR; } } else if (objc == 3) { char *string; string = Tcl_GetString(objv[1]); if (strcmp(string, "-data") == 0) { if (Crc32FromObj(objv[2], &crc) != TCL_OK) { return TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ?fileName? ?-data dataString?", (char *)NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ?fileName? ?-data dataString?", (char *)NULL); return TCL_ERROR; } crc = crc ^ 0xffffffffUL; { char buf[200]; sprintf_s(buf, 200, "%lx", crc); Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); } return TCL_OK; } int Blt_Crc32CmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"crc32", Crc32Cmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPainter.c������������������������������������������������������������������0000644�0001750�0001750�00000062525�11462120062�015307� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPainter.c -- * * This module implements generic painting procedures for pictures in * the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the Tk * library distrubution. The photo image type was designed and implemented by * Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #include "bltInt.h" #include "bltHash.h" #include "bltPicture.h" #include "bltPainterInt.h" typedef struct _Blt_Picture Picture; #define CFRAC(i, n) ((i) * 65535 / (n)) /* As for CFRAC, but apply exponent of g. */ #define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) #define MAXIMAGESIZE(dpy) (XMaxRequestSize(dpy) << 2) - 24 #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) static Blt_HashTable painterTable; static int initialized = 0; #define COLOR_WINDOW (1<<0) #define BLACK_AND_WHITE (1<<1) #define MAP_COLORS (1<<2) /* * PainterKey -- * * This structure represents the key used to uniquely identify painters. A * painter is specified by a combination of display, visual, colormap, depth, * and monitor gamma value. */ typedef struct { Display *display; /* Display of painter. Used to free colors * allocated. */ Visual *visualPtr; /* Visual information for the class of windows * displaying the image. */ Colormap colormap; /* Colormap used. This may be the default * colormap, or an allocated private map. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value of monitor. */ } PainterKey; #define GC_PRIVATE 1 /* Indicates if the GC in the painter was * shared (allocated by Tk_GetGC) or private * (by XCreateGC). */ static Tcl_FreeProc FreePainter; /* *--------------------------------------------------------------------------- * * FindShift -- * * Returns the position of the least significant (low) bit in the given * mask. * * For TrueColor and DirectColor visuals, a pixel value is formed by * OR-ing the red, green, and blue colormap indices into a single 32-bit * word. The visual's color masks tell you where in the word the indices * are supposed to be. The masks contain bits only where the index is * found. By counting the leading zeros in the mask, we know how many * bits to shift to the individual red, green, and blue values to form a * pixel. * * Results: * The number of the least significant bit. * *--------------------------------------------------------------------------- */ static int FindShift(unsigned int mask) /* 32-bit word */ { int bit; for (bit = 0; bit < 32; bit++) { if (mask & (1 << bit)) { break; } } return bit; } /* *--------------------------------------------------------------------------- * * CountBits -- * * Returns the number of bits set in the given 32-bit mask. * * Reference: Graphics Gems Volume II. * * Results: * The number of bits to set in the mask. * * *--------------------------------------------------------------------------- */ static int CountBits(unsigned long mask) /* 32 1-bit tallies */ { /* 16 2-bit tallies */ mask = (mask & 0x55555555) + ((mask >> 1) & (0x55555555)); /* 8 4-bit tallies */ mask = (mask & 0x33333333) + ((mask >> 2) & (0x33333333)); /* 4 8-bit tallies */ mask = (mask & 0x07070707) + ((mask >> 4) & (0x07070707)); /* 2 16-bit tallies */ mask = (mask & 0x000F000F) + ((mask >> 8) & (0x000F000F)); /* 1 32-bit tally */ mask = (mask & 0x0000001F) + ((mask >> 16) & (0x0000001F)); return mask; } /* *--------------------------------------------------------------------------- * * ComputeGammaTables -- * * Initializes both the power and inverse power tables for the painter * with a given gamma value. These tables are used to/from map linear * RGB values to/from non-linear monitor intensities. * * Results: * The *gammaTable* and *igammaTable* arrays are filled out to * contain the mapped values. * *--------------------------------------------------------------------------- */ static void ComputeGammaTables(Painter *p) { int i; double igamma, gamma; gamma = (double)p->gamma; igamma = 1.0 / gamma; for (i = 0; i < 256; i++) { double value, y; y = i / 255.0; value = pow(y, gamma) * 255.0 + 0.5; p->gammaTable[i] = (unsigned char)CLAMP(value); value = pow(y, igamma) * 255.0 + 0.5; p->igammaTable[i] = (unsigned char)CLAMP(value); } } /* *--------------------------------------------------------------------------- * * Blt_QueryPalette -- * * Queries the X display server for the colors currently used in the * colormap. These values will then be used to map screen pixels back to * RGB values (see Blt_DrawableToPicture). The queried non-linear color * intensities are reverse mapped back to to linear RGB values. * * Results: * The *palette* array is filled in with the RGB color values of the * colors allocated. * *--------------------------------------------------------------------------- */ void Blt_QueryPalette(Painter *p, Blt_Pixel *palette) { Visual *visualPtr; XColor colors[256]; visualPtr = p->visualPtr; assert(visualPtr->map_entries <= 256); if ((visualPtr->class == DirectColor) || (visualPtr->class == TrueColor)) { XColor *cp, *cend; int nRed, nGreen, nBlue; unsigned int r, g, b; r = g = b = 0; nRed = (p->rMask >> p->rShift) + 1; nGreen = (p->gMask >> p->gShift) + 1; nBlue = (p->bMask >> p->bShift) + 1; for (cp = colors, cend = cp + visualPtr->map_entries; cp < cend; cp++) { cp->pixel = ((r << p->rShift)|(g << p->gShift) | (b << p->bShift)); cp->pad = 0; r++, b++, g++; if (r >= nRed) { r = 0; } if (g >= nGreen) { g = 0; } if (b >= nBlue) { b = 0; } } } else { XColor *cp; int i; for (cp = colors, i = 0; i < visualPtr->map_entries; i++, cp++) { cp->pixel = i; cp->pad = 0; } } XQueryColors(p->display, p->colormap, colors, visualPtr->map_entries); /* Scale to convert XColor component value (0..65535) to unsigned * char (0..255). */ if (p->gamma == 1.0f) { Blt_Pixel *dp; XColor *cp; int i; double a; a = 1.0 / 257.0; cp = colors, dp = palette; for (i = 0; i < visualPtr->map_entries; i++) { dp->Red = (unsigned char)(cp->red * a + 0.5); dp->Green = (unsigned char)(cp->green * a + 0.5); dp->Blue = (unsigned char)(cp->blue * a + 0.5); cp++, dp++; } } else { Blt_Pixel *dp; XColor *cp; int i; double a; a = 1.0 / 257.0; cp = colors, dp = palette; for (i = 0; i < visualPtr->map_entries; i++) { dp->Red = p->gammaTable[(int)(cp->red * a + 0.5)]; dp->Green = p->gammaTable[(int)(cp->green * a + 0.5)]; dp->Blue = p->gammaTable[(int)(cp->blue * a + 0.5)]; cp++, dp++; } } } /* *--------------------------------------------------------------------------- * * ColorRamp -- * * Computes a smooth color ramp based upon the number of colors available * for each color component. It returns an array of the desired colors * (XColor structures). The screen gamma is factored into the desired * colors. * * Results: * Returns the number of colors desired. The *colors* array is filled * out to contain the component values. * *--------------------------------------------------------------------------- */ static int ColorRamp(Painter *p, XColor *colors) { int nColors; XColor *cp; double rScale, gScale, bScale; double igamma; int i; nColors = 0; /* Suppress compiler warning. */ /* * Calculate the RGB coordinates of the colors we want to allocate and * store them in *colors. */ igamma = 1.0 / (double)p->gamma; rScale = 255.0 / (p->nRed - 1); gScale = 255.0 / (p->nGreen - 1); bScale = 255.0 / (p->nBlue - 1); switch (p->visualPtr->class) { case TrueColor: case DirectColor: nColors = MAX3(p->nRed, p->nGreen, p->nBlue); if (p->isMonochrome) { nColors = p->nBlue = p->nGreen = p->nRed; } /* Compute the 16-bit RGB values from each possible 8-bit value. */ cp = colors; for (i = 0; i < nColors; i++) { int r, g, b; r = (int)(i * rScale + 0.5); g = (int)(i * gScale + 0.5); b = (int)(i * bScale + 0.5); r = p->igammaTable[r]; g = p->igammaTable[g]; b = p->igammaTable[b]; cp->red = (r << 8) + r; cp->green = (g << 8) + g; cp->blue = (b << 8) + b; cp++; } break; case PseudoColor: case StaticColor: case GrayScale: case StaticGray: nColors = (p->nRed * p->nGreen * p->nBlue); if (p->isMonochrome) { nColors = p->nRed; } if (!p->isMonochrome) { XColor *cp; int i; cp = colors; for (i = 0; i < p->nRed; i++) { int j; unsigned char r; r = (unsigned char)(i * rScale + 0.5); r = p->igammaTable[r]; for (j = 0; j < p->nGreen; j++) { int k; unsigned int g; g = (unsigned char)(j * gScale + 0.5); g = p->igammaTable[g]; for (k = 0; k < p->nBlue; k++) { unsigned int b; b = (unsigned char)(k * bScale + 0.5); b = p->igammaTable[b]; cp->red = (r << 8) | r; cp->green = (g << 8) | g; cp->blue = (b << 8) | b; cp++; } } } } break; default: /* Monochrome */ { XColor *cp; double scale; int i; scale = 255.0 / (nColors - 1); cp = colors; for (i = 0; i < nColors; ++i) { int c; c = (int)(i * scale + 0.5); c = p->igammaTable[c]; cp->red = cp->green = cp->blue = (c << 8) | c; cp++; } } } /* end switch */ return nColors; } /* *--------------------------------------------------------------------------- * * AllocateColors -- * * Individually allocates each of the desired colors (as specified by the * *colors* array). If a color can't be allocated the desired colors * allocated to that point as released, the number of component * intensities is reduced, and 0 is returned. * * For TrueColor visuals, we don't need to allocate colors at all, since * we can compute them directly. * * Results: * Returns 1 if all desired colors were allocated successfully. If * unsuccessful, returns 0. All colors allocated up to that point are * freed and a smaller color palette size is computed and reset in the * painter structure. * *--------------------------------------------------------------------------- */ static int AllocateColors(Painter *p, XColor *colors, int nColors) { if (p->visualPtr->class == TrueColor) { XColor *cp, *cend; /* * For TrueColor visuals, don't call XAllocColor, compute the pixel * value directly. */ for (cp = colors, cend = cp + nColors; cp < cend; cp++) { unsigned int r, g, b; r = ((cp->red >> 8) >> p->rAdjust); g = ((cp->green >> 8) >> p->gAdjust); b = ((cp->blue >> 8) >> p->bAdjust); /* Shift each color into the proper location of the pixel index. */ r = (r << p->rShift) & p->rMask; g = (g << p->gShift) & p->gMask; b = (b << p->bShift) & p->bMask; cp->pixel = (r | g | b); } p->nPixels = 0; /* This will indicate that we didn't use * XAllocColor to obtain pixel values. */ return TRUE; } else { int i; XColor *cp; cp = colors; for (i = 0; i < nColors; i++) { if (!XAllocColor(p->display, p->colormap, cp)){ #ifdef notdef fprintf(stderr, "can't allocate color #%d: r=%x g=%x b=%x\n", i, cp->red, cp->green, cp->blue); #endif break; } #ifdef notdef fprintf(stderr, "picture: allocated r=%x g=%x b=%x\n", colors[i].red, colors[i].green, colors[i].blue); #endif p->pixels[i] = cp->pixel; cp++; } p->nPixels = i; /* # of pixels in array */ if (i == nColors) { fprintf(stderr, "painter palette %d/%d/%d colors okay\n", p->nRed, p->nGreen, p->nBlue); return TRUE; /* Success. */ } } /* * If we didn't get all of the colors, free the current palette, reduce * the palette RGB component sizes. */ #ifdef notdef fprintf(stderr, "can't allocate %d/%d/%d colors\n", p->nRed, p->nGreen, p->nBlue); #endif XFreeColors(p->display, p->colormap, p->pixels, p->nPixels, 0); return FALSE; } /* *--------------------------------------------------------------------------- * * FillPalette -- * * Base upon the colors allocated, generate two mappings from the * picture's 8-bit RGB components. * * 1) Map 8-bit RGB values to the bits of the pixel. Each component * contains a portion of the pixel value. For mapped visuals * (pseudocolor, staticcolor, grayscale, and staticgray) this pixel * value will be translated to the actual pixel used by the display. * * 2) Map 8-bit RGB values to the actual color values used. The * color ramp generated may be only a subset of the possible * color values. The resulting palette is used in dithering the * image, using the error between the desired picture RGB value * and the actual value used. * * Results: * Color palette and pixel maps are filled in. * *--------------------------------------------------------------------------- */ static void FillPalette(Painter *p, XColor *colors, int nColors) { p->nColors = nColors; if (!p->isMonochrome) { p->flags |= COLOR_WINDOW; if ((p->visualPtr->class != DirectColor) && (p->visualPtr->class != TrueColor)) { p->flags |= MAP_COLORS; } } if (p->isMonochrome) { int i; for (i = 0; i < 256; i++) { int c; c = (i + 127) / 255; p->rBits[i] = colors[c].pixel; p->palette[i].Blue = p->palette[i].Green = p->palette[i].Red = (unsigned char)(c * 255 + 0.5); } } else { int i, rMult; double rScale, gScale, bScale; rMult = p->nGreen * p->nBlue; rScale = 255.0 / (p->nRed - 1); gScale = 255.0 / (p->nGreen - 1); bScale = 255.0 / (p->nBlue - 1); for (i = 0; i < 256; i++) { int r, g, b; r = (i * (p->nRed - 1) + 127) / 255; g = (i * (p->nGreen - 1) + 127) / 255; b = (i * (p->nBlue - 1) + 127) / 255; if ((p->visualPtr->class == DirectColor) || (p->visualPtr->class == TrueColor)) { p->rBits[i] = colors[r].pixel & p->rMask; p->gBits[i] = colors[g].pixel & p->gMask; p->bBits[i] = colors[b].pixel & p->bMask; } else { p->rBits[i] = r * rMult; p->gBits[i] = g * p->nBlue; p->bBits[i] = b; } p->palette[i].Red = (unsigned char)(r * rScale + 0.5); p->palette[i].Green = (unsigned char)(g * gScale + 0.5); p->palette[i].Blue = (unsigned char)(b * bScale + 0.5); } } } /* *--------------------------------------------------------------------------- * * AllocatePalette -- * * This procedure allocates the colors required by a color table, and * sets up the fields in the color table data structure which are used in * dithering. * * This routine essentially mimics what is done in tkImgPhoto.c. It's * purpose is to allocate exactly the same color ramp as the photo * image. That way both image types can co-exist without fighting over * available colors. * * Results: * None. * * Side effects: * Colors are allocated from the X server. The color palette and pixel * indices are updated. * *--------------------------------------------------------------------------- */ static void AllocatePalette( Painter *p) /* Pointer to the color table requiring * colors to be allocated. */ { XColor colors[256]; int nColors; static int stdPalettes[13][3] = { /* nRed, nGreen, nBlue */ { 2, 2, 2 }, /* 3 bits, 8 colors */ { 2, 3, 2 }, /* 4 bits, 12 colors */ { 3, 4, 2 }, /* 5 bits, 24 colors */ { 4, 5, 3 }, /* 6 bits, 60 colors */ { 5, 6, 4 }, /* 7 bits, 120 colors */ { 7, 7, 4 }, /* 8 bits, 198 colors */ { 8, 10, 6 }, /* 9 bits, 480 colors */ { 10, 12, 8 }, /* 10 bits, 960 colors */ { 14, 15, 9 }, /* 11 bits, 1890 colors */ { 16, 20, 12 }, /* 12 bits, 3840 colors */ { 20, 24, 16 }, /* 13 bits, 7680 colors */ { 26, 30, 20 }, /* 14 bits, 15600 colors */ { 32, 32, 30 }, /* 15 bits, 30720 colors */ }; p->isMonochrome = FALSE; switch (p->visualPtr->class) { case TrueColor: case DirectColor: p->nRed = 1 << CountBits(p->rMask); p->nGreen = 1 << CountBits(p->gMask); p->nBlue = 1 << CountBits(p->bMask); break; case GrayScale: case StaticGray: case PseudoColor: case StaticColor: if (p->depth > 15) { p->nRed = p->nGreen = p->nBlue = 32; } else if (p->depth >= 3) { int *ip = stdPalettes[p->depth - 3]; p->nRed = ip[0]; p->nGreen = ip[1]; p->nBlue = ip[2]; } break; default: p->nGreen = p->nBlue = 0; p->nRed = 1 << p->depth; p->isMonochrome = TRUE; break; } /* * Each time around this loop, we reduce the number of colors * we're trying to allocate until we succeed in allocating all of * the colors we need. */ for (;;) { /* * If we are using 1 bit/pixel, we don't need to allocate any * colors (we just use the foreground and background colors in * the GC). */ if ((p->isMonochrome) && (p->nRed <= 2)) { p->flags |= BLACK_AND_WHITE; /* return; */ } /* * Calculate the RGB values of a color ramp, given the some * number of red, green, blue intensities available. */ nColors = ColorRamp(p, colors); /* Now try to allocate the colors we've calculated. */ if (AllocateColors(p, colors, nColors)) { break; /* Success. */ } if (!p->isMonochrome) { if ((p->nRed == 2) && (p->nGreen == 2) && (p->nBlue == 2)) { break; /* Fall back to 1-bit monochrome display. */ /* p->mono = TRUE; */ } else { /* * Reduce the number of shades of each primary to * about 3/4 of the previous value. This will reduce * the total number of colors required to less than * half (27/64) the previous value for PseudoColor * displays. */ p->nRed = (p->nRed * 3 + 2) / 4; p->nGreen = (p->nGreen * 3 + 2) / 4; p->nBlue = (p->nBlue * 3 + 2) / 4; } } else { p->nRed /= 2; } } FillPalette(p, colors, nColors); } /* *--------------------------------------------------------------------------- * * NewPainter -- * * Creates a new painter to be used to paint pictures. Painters are keyed * by the combination of display, colormap, visual, depth, and gamma * value used. * * Results: * A pointer to the new painter is returned. * * Side Effects: * A color ramp is allocated (not true for TrueColor visuals). Gamma * tables are computed and filled. * *--------------------------------------------------------------------------- */ static Painter * NewPainter(PainterKey *keyPtr) { Painter *p; p = Blt_AssertCalloc(1, sizeof(Painter)); p->colormap = keyPtr->colormap; p->depth = keyPtr->depth; p->display = keyPtr->display; p->gamma = keyPtr->gamma; p->visualPtr = keyPtr->visualPtr; p->refCount = 0; p->rMask = (unsigned int)p->visualPtr->red_mask; p->gMask = (unsigned int)p->visualPtr->green_mask; p->bMask = (unsigned int)p->visualPtr->blue_mask; p->rShift = FindShift(p->rMask); p->gShift = FindShift(p->gMask); p->bShift = FindShift(p->bMask); p->rAdjust = p->gAdjust = p->bAdjust = 0; { int nRedBits, nGreenBits, nBlueBits; nRedBits = CountBits(p->rMask); nGreenBits = CountBits(p->gMask); nBlueBits = CountBits(p->bMask); if (nRedBits < 8) { p->rAdjust = 8 - nRedBits; } if (nGreenBits < 8) { p->gAdjust = 8 - nGreenBits; } if (nBlueBits < 8) { p->bAdjust = 8 - nBlueBits; } } ComputeGammaTables(p); AllocatePalette(p); return p; } GC Blt_PainterGC(Painter *p) { return p->gc; } int Blt_PainterDepth(Painter *p) { return p->depth; } /* *--------------------------------------------------------------------------- * * FreePainter -- * * Called when the TCL interpreter is idle, this routine frees the * painter. Painters are reference counted. Only when no clients are using * the painter (the count is zero) is the painter actually freed. By * deferring its deletion, this allows client code to call Blt_GetPainter * after Blt_FreePainter without incurring a performance penalty. * *--------------------------------------------------------------------------- */ static void FreePainter(DestroyData data) { Painter *p = (Painter *)data; if (p->refCount <= 0) { if (p->nColors > 0) { XFreeColors(p->display, p->colormap, p->pixels, p->nPixels, 0); } Blt_DeleteHashEntry(&painterTable, p->hashPtr); if (p->gc != NULL) { if (p->flags & GC_PRIVATE) { XFreeGC(p->display, p->gc); } else { Tk_FreeGC(p->display, p->gc); } p->gc = NULL; } Blt_Free(p); } } /* *--------------------------------------------------------------------------- * * GetPainter -- * * Attempts to retrieve a painter for a particular combination of * display, colormap, visual, depth, and gamma value. If no specific * painter exists, then one is created. * * Results: * A pointer to the new painter is returned. * * Side Effects: * If no current painter exists, a new painter is added to the hash table * of painters. Otherwise, the current painter's reference count is * incremented indicated how many clients are using the painter. * *--------------------------------------------------------------------------- */ static Painter * GetPainter( Display *display, Colormap colormap, Visual *visualPtr, int depth, float gamma) { Painter *p; PainterKey key; int isNew; Blt_HashEntry *hPtr; if (!initialized) { Blt_InitHashTable(&painterTable, sizeof(PainterKey) / sizeof(int)); initialized = TRUE; } key.display = display; key.colormap = colormap; key.visualPtr = visualPtr; key.depth = depth; key.gamma = gamma; hPtr = Blt_CreateHashEntry(&painterTable, (char *)&key, &isNew); if (isNew) { p = NewPainter(&key); p->hashPtr = hPtr; Blt_SetHashValue(hPtr, p); } else { p = Blt_GetHashValue(hPtr); } p->refCount++; return p; } /* *--------------------------------------------------------------------------- * * Blt_GetPainterFromDrawable -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information is retrieved from * the drawable which is assumed to be a window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainterFromDrawable(Display *display, Drawable drawable, float gamma) { XGCValues gcValues; unsigned long gcMask; Painter *p; Visual *visual; Colormap colormap; int depth; Blt_GetDrawableInfo(display, drawable, &visual, &colormap, &depth); p = GetPainter(display, colormap, visual, depth, gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = XCreateGC(display, drawable, gcMask, &gcValues); p->flags |= GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_GetPainter -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information (except for the * monitor's gamma value) is retrieved from the given Tk window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainter(Tk_Window tkwin, float gamma) { Painter *p; XGCValues gcValues; unsigned long gcMask; p = GetPainter(Tk_Display(tkwin), Tk_Colormap(tkwin), Tk_Visual(tkwin), Tk_Depth(tkwin), gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = Tk_GetGC(tkwin, gcMask, &gcValues); p->flags &= ~GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_FreePainter -- * * Frees the painter. Painters are reference counted. Only when no * clients are using the painter (the count is zero) is the painter * actually freed. * *--------------------------------------------------------------------------- */ void Blt_FreePainter(Painter *p) { p->refCount--; if (p->refCount <= 0) { Tcl_EventuallyFree(p, FreePainter); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltText.h���������������������������������������������������������������������0000644�0001750�0001750�00000022420�11462120063�014625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltText.h -- * * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_TEXT_H #define _BLT_TEXT_H #include "bltBgStyle.h" #define DEF_TEXT_FLAGS (TK_PARTIAL_OK | TK_IGNORE_NEWLINES) #define UPDATE_GC 1 /* * TextFragment -- */ typedef struct { const char *text; /* Text string to be displayed */ size_t count; /* Number of bytes in text. The actual * character count may differ because of * multi-byte UTF encodings. */ short x, y; /* X-Y offset of the baseline from the * upper-left corner of the bbox. */ short sx, sy; /* Starting offset of text using rotated * font. */ int width; /* Width of segment in pixels. This * information is used to draw * PostScript strings the same width * as X. */ } TextFragment; /* * TextItem -- * * Parsed form for markup string. Each item is a scrap of text * describes the font, position, and characters to be displayed. * * subscript x_y very small subset of latex markup. * superscript x^y * grouping a^{x+y} a_{i,j} * supersuper a^{10^8} * \hat{a} \bar{b} \vec{c} * \overline{} \underline{} * \frac \tfrac * \Alpha \Beta ... * \mathbf{} \mathit{} \mathrm{} \boldsymbol{} * \angstrom \degree * * -mathtext instead of -text * * Can use TextItem where you don't directly edit the text: * label, treeview, graph, barchart... * * Font selector (bold, italic, size adjust) from base font. * Global font table reference counted. * */ typedef struct { const char *text; /* Text string to be displayed */ size_t count; /* Number of bytes in text. The actual * character count may differ because of * multi-byte UTF encodings. */ short int x, y; /* X-Y offset of the baseline from the * upper-left corner of the bbox. */ short int sx, sy; /* Starting offset of text using rotated * font. */ Blt_Font font; /* Allocated font for this chunk. * If NULL, use the global font. */ int underline; /* Text is underlined */ int width; /* Width of segment in pixels. This * information is used to draw * PostScript strings the same width * as X. (deprecated) */ } TextItem; /* * TextLayout -- */ typedef struct { TextFragment *underlinePtr; int underline; size_t width, height; /* Dimensions of text bounding box */ size_t nFrags; /* # fragments of text */ TextFragment fragments[1]; /* Information about each fragment of text */ } TextLayout; /* * TextStyle -- * * A somewhat convenient structure to hold text attributes that determine * how a text string is to be displayed on the screen or drawn with * PostScript commands. The alternative is to pass lots of parameters to * the drawing and printing routines. This seems like a more efficient * and less cumbersome way of passing parameters. */ typedef struct { unsigned int state; /* If non-zero, indicates to draw text * in the active color */ XColor *color; /* Color to draw the text. */ Blt_Font font; /* Font to use to draw text */ Blt_Background bg; /* Background color of text. This is * also used for drawing disabled * text. */ float angle; /* Rotation of text in degrees. */ Tk_Justify justify; /* Justification of the text * string. This only matters if the * text is composed of multiple * lines. */ Tk_Anchor anchor; /* Indicates how the text is anchored * around its x,y coordinates. */ Blt_Pad xPad, yPad; /* # pixels padding of around text * region. */ unsigned short int leader; /* # pixels spacing between lines of * text. */ short int underline; /* Index of character to be underlined, * -1 if no underline. */ int maxLength; /* Maximum length in pixels of text */ /* Private fields. */ unsigned short flags; GC gc; /* GC used to draw the text */ } TextStyle; BLT_EXTERN TextLayout *Blt_Ts_CreateLayout(const char *string, int length, TextStyle *tsPtr); BLT_EXTERN void Blt_Ts_DrawLayout(Tk_Window tkwin, Drawable drawable, TextLayout *textPtr, TextStyle *tsPtr, int x, int y); BLT_EXTERN void Blt_Ts_GetExtents(TextStyle *tsPtr, const char *text, unsigned int *widthPtr, unsigned int *heightPtr); BLT_EXTERN void Blt_Ts_ResetStyle(Tk_Window tkwin, TextStyle *tsPtr); BLT_EXTERN void Blt_Ts_FreeStyle(Display *display, TextStyle *tsPtr); BLT_EXTERN void Blt_Ts_SetDrawStyle (TextStyle *tsPtr, Blt_Font font, GC gc, XColor *fgColor, float angle, Tk_Anchor anchor, Tk_Justify justify, int leader); BLT_EXTERN void Blt_Ts_SetPrintStyle(TextStyle *tsPtr, Blt_Font font, XColor *fgColor, XColor *bgColor, float angle, Tk_Anchor anchor, Tk_Justify justify, int leader); BLT_EXTERN void Blt_DrawText(Tk_Window tkwin, Drawable drawable, const char *string, TextStyle *tsPtr, int x, int y); BLT_EXTERN void Blt_DrawText2(Tk_Window tkwin, Drawable drawable, const char *string, TextStyle *tsPtr, int x, int y, Dim2D * dimPtr); BLT_EXTERN Pixmap Blt_Ts_Bitmap(Tk_Window tkwin, TextLayout *textPtr, TextStyle *tsPtr, int *widthPtr, int *heightPtr); BLT_EXTERN int Blt_DrawTextWithRotatedFont(Tk_Window tkwin, Drawable drawable, float angle, TextStyle *tsPtr, TextLayout *textPtr, int x, int y); BLT_EXTERN void Blt_DrawLayout(Tk_Window tkwin, Drawable drawable, GC gc, Blt_Font font, int depth, float angle, int x, int y, TextLayout *layoutPtr, int maxLength); BLT_EXTERN void Blt_GetTextExtents(Blt_Font font, int leader, const char *text, int textLen, unsigned int *widthPtr, unsigned int *heightPtr); BLT_EXTERN void Blt_RotateStartingTextPositions(TextLayout *textPtr, float angle); BLT_EXTERN Tk_TextLayout Blt_ComputeTextLayout(Blt_Font font, const char *string, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); BLT_EXTERN void Blt_DrawTextLayout(Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); BLT_EXTERN int Blt_CharBbox(Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); BLT_EXTERN void Blt_UnderlineTextLayout(Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); BLT_EXTERN void Blt_Ts_UnderlineLayout(Tk_Window tkwin, Drawable drawable, TextLayout *layoutPtr, TextStyle *tsPtr, int x, int y); BLT_EXTERN void Blt_Ts_DrawText(Tk_Window tkwin, Drawable drawable, const char *text, int textLen, TextStyle *tsPtr, int x, int y); BLT_EXTERN int Blt_MeasureText(Blt_Font font, const char *text, int textLen, int maxLength, int *nBytesPtr); BLT_EXTERN void Blt_FreeTextLayout(Tk_TextLayout layout); #define Blt_Ts_GetAnchor(ts) ((ts).anchor) #define Blt_Ts_GetAngle(ts) ((ts).angle) #define Blt_Ts_GetBackground(ts) ((ts).bg) #define Blt_Ts_GetFont(ts) ((ts).font) #define Blt_Ts_GetForeground(ts) ((ts).color) #define Blt_Ts_GetJustify(ts) ((ts).justify) #define Blt_Ts_GetLeader(ts) ((ts).leader) #define Blt_Ts_SetAnchor(ts, a) ((ts).anchor = (a)) #define Blt_Ts_SetAngle(ts, r) ((ts).angle = (float)(r)) #define Blt_Ts_SetBackground(ts, b) ((ts).bg = (b)) #define Blt_Ts_SetFont(ts, f) \ (((ts).font != (f)) ? ((ts).font = (f), (ts).flags |= UPDATE_GC) : 0) #define Blt_Ts_SetForeground(ts, c) \ (((ts).color != (c)) ? ((ts).color = (c), (ts).flags |= UPDATE_GC) : 0) #define Blt_Ts_SetGC(ts, g) ((ts).gc = (g)) #define Blt_Ts_SetJustify(ts, j) ((ts).justify = (j)) #define Blt_Ts_SetLeader(ts, l) ((ts).leader = (l)) #define Blt_Ts_SetMaxLength(ts, l) ((ts).maxLength = (l)) #define Blt_Ts_SetPadding(ts, l, r, t, b) \ ((ts).xPad.side1 = (l), \ (ts).xPad.side2 = (r), \ (ts).yPad.side1 = (t), \ (ts).yPad.side2 = (b)) #define Blt_Ts_SetState(ts, s) ((ts).state = (s)) #define Blt_Ts_SetUnderline(ts, ul) ((ts).underline = (ul)) #define Blt_Ts_InitStyle(ts) \ ((ts).anchor = TK_ANCHOR_NW, \ (ts).color = (XColor *)NULL, \ (ts).font = NULL, \ (ts).justify = TK_JUSTIFY_LEFT, \ (ts).leader = 0, \ (ts).underline = -1, \ (ts).xPad.side1 = (ts).xPad.side2 = 0, \ (ts).yPad.side1 = (ts).yPad.side2 = 0, \ (ts).state = 0, \ (ts).flags = 0, \ (ts).gc = NULL, \ (ts).maxLength = -1, \ (ts).angle = 0.0) #endif /* _BLT_TEXT_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrHairs.c������������������������������������������������������������������0000644�0001750�0001750�00000034001�11462120062�015230� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrHairs.c -- * * This module implements crosshairs for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" typedef int (GraphCrosshairProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * Crosshairs * * Contains the line segments positions and graphics context used * to simulate crosshairs (by XORing) on the graph. * *--------------------------------------------------------------------------- */ struct _Crosshairs { XPoint hotSpot; /* Hot spot for crosshairs */ int visible; /* Internal state of crosshairs. If non-zero, * crosshairs are displayed. */ int hidden; /* If non-zero, crosshairs are not displayed. * This is not necessarily consistent with the * internal state variable. This is true when * the hot spot is off the graph. */ Blt_Dashes dashes; /* Dashstyle of the crosshairs. This represents * an array of alternatingly drawn pixel * values. If NULL, the hairs are drawn as a * solid line */ int lineWidth; /* Width of the simulated crosshair lines */ XSegment segArr[2]; /* Positions of line segments representing the * simulated crosshairs. */ XColor *colorPtr; /* Foreground color of crosshairs */ GC gc; /* Graphics context for crosshairs. Set to * GXxor to not require redraws of graph */ }; #define DEF_HAIRS_DASHES (char *)NULL #define DEF_HAIRS_FOREGROUND RGB_BLACK #define DEF_HAIRS_LINE_WIDTH "0" #define DEF_HAIRS_HIDE "yes" #define DEF_HAIRS_POSITION (char *)NULL BLT_EXTERN Blt_CustomOption bltPointOption; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_HAIRS_FOREGROUND, Blt_Offset(Crosshairs, colorPtr), 0}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_HAIRS_DASHES, Blt_Offset(Crosshairs, dashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", DEF_HAIRS_HIDE, Blt_Offset(Crosshairs, hidden), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "Linewidth", DEF_HAIRS_LINE_WIDTH, Blt_Offset(Crosshairs, lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-position", "position", "Position", DEF_HAIRS_POSITION, Blt_Offset(Crosshairs, hotSpot), 0, &bltPointOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* *--------------------------------------------------------------------------- * * TurnOffHairs -- * * XOR's the existing line segments (representing the crosshairs), * thereby erasing them. The internal state of the crosshairs is * tracked. * * Results: * None * * Side Effects: * Crosshairs are erased. * *--------------------------------------------------------------------------- */ static void TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr) { if (Tk_IsMapped(tkwin) && (chPtr->visible)) { XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc, chPtr->segArr, 2); chPtr->visible = FALSE; } } /* *--------------------------------------------------------------------------- * * TurnOnHairs -- * * Draws (by XORing) new line segments, creating the effect of * crosshairs. The internal state of the crosshairs is tracked. * * Results: * None * * Side Effects: * Crosshairs are displayed. * *--------------------------------------------------------------------------- */ static void TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr) { if (Tk_IsMapped(graphPtr->tkwin) && (!chPtr->visible)) { if (!PointInGraph(graphPtr, chPtr->hotSpot.x, chPtr->hotSpot.y)) { return; /* Coordinates are off the graph */ } XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin), chPtr->gc, chPtr->segArr, 2); chPtr->visible = TRUE; } } /* *--------------------------------------------------------------------------- * * ConfigureCrosshairs -- * * Configures attributes of the crosshairs such as line width, * dashes, and position. The crosshairs are first turned off * before any of the attributes changes. * * Results: * None * * Side Effects: * Crosshair GC is allocated. * *--------------------------------------------------------------------------- */ void Blt_ConfigureCrosshairs(Graph *graphPtr) { XGCValues gcValues; unsigned long gcMask; GC newGC; unsigned long int pixel; Crosshairs *chPtr = graphPtr->crosshairs; /* * Turn off the crosshairs temporarily. This is in case the new * configuration changes the size, style, or position of the lines. */ TurnOffHairs(graphPtr->tkwin, chPtr); gcValues.function = GXxor; if (graphPtr->plotBg == NULL) { /* The graph's color option may not have been set yet */ pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin)); } else { pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel; } gcValues.background = pixel; gcValues.foreground = (pixel ^ chPtr->colorPtr->pixel); gcValues.line_width = LineWidth(chPtr->lineWidth); gcMask = (GCForeground | GCBackground | GCFunction | GCLineWidth); if (LineIsDashed(chPtr->dashes)) { gcValues.line_style = LineOnOffDash; gcMask |= GCLineStyle; } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(chPtr->dashes)) { Blt_SetDashes(graphPtr->display, newGC, &chPtr->dashes); } if (chPtr->gc != NULL) { Blt_FreePrivateGC(graphPtr->display, chPtr->gc); } chPtr->gc = newGC; /* * Are the new coordinates on the graph? */ chPtr->segArr[0].x2 = chPtr->segArr[0].x1 = chPtr->hotSpot.x; chPtr->segArr[0].y1 = graphPtr->bottom; chPtr->segArr[0].y2 = graphPtr->top; chPtr->segArr[1].y2 = chPtr->segArr[1].y1 = chPtr->hotSpot.y; chPtr->segArr[1].x1 = graphPtr->left; chPtr->segArr[1].x2 = graphPtr->right; if (!chPtr->hidden) { TurnOnHairs(graphPtr, chPtr); } } void Blt_EnableCrosshairs(Graph *graphPtr) { if (!graphPtr->crosshairs->hidden) { TurnOnHairs(graphPtr, graphPtr->crosshairs); } } void Blt_DisableCrosshairs(Graph *graphPtr) { if (!graphPtr->crosshairs->hidden) { TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs); } } /* *--------------------------------------------------------------------------- * * UpdateCrosshairs -- * * Update the length of the hairs (not the hot spot). * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_UpdateCrosshairs(Graph *graphPtr) { Crosshairs *chPtr = graphPtr->crosshairs; chPtr->segArr[0].y1 = graphPtr->bottom; chPtr->segArr[0].y2 = graphPtr->top; chPtr->segArr[1].x1 = graphPtr->left; chPtr->segArr[1].x2 = graphPtr->right; } /* *--------------------------------------------------------------------------- * * Blt_DestroyCrosshairs -- * * Results: * None * * Side Effects: * Crosshair GC is allocated. * *--------------------------------------------------------------------------- */ void Blt_DestroyCrosshairs(Graph *graphPtr) { if (graphPtr->crosshairs != NULL) { Crosshairs *chPtr = graphPtr->crosshairs; Blt_FreeOptions(configSpecs, (char *)chPtr, graphPtr->display, 0); if (chPtr->gc != NULL) { Blt_FreePrivateGC(graphPtr->display, chPtr->gc); } Blt_Free(chPtr); } } /* *--------------------------------------------------------------------------- * * Blt_CreateCrosshairs -- * * Creates and initializes a new crosshair structure. * * Results: * Returns TCL_ERROR if the crosshair structure can't be created, * otherwise TCL_OK. * * Side Effects: * Crosshair GC is allocated. * *--------------------------------------------------------------------------- */ int Blt_CreateCrosshairs(Graph *graphPtr) { Crosshairs *chPtr; chPtr = Blt_AssertCalloc(1, sizeof(Crosshairs)); chPtr->hidden = TRUE; chPtr->hotSpot.x = chPtr->hotSpot.y = -1; graphPtr->crosshairs = chPtr; if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, "crosshairs", "Crosshairs", configSpecs, 0, (Tcl_Obj **)NULL, (char *)chPtr, 0) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Queries configuration attributes of the crosshairs such as * line width, dashes, and position. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CgetOp( Graph *graphPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Crosshairs *chPtr = graphPtr->crosshairs; return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, (char *)chPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Queries or resets configuration attributes of the crosshairs * such as line width, dashes, and position. * * Results: * A standard TCL result. * * Side Effects: * Crosshairs are reset. * *--------------------------------------------------------------------------- */ static int ConfigureOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Crosshairs *chPtr = graphPtr->crosshairs; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)chPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)chPtr, objv[3], 0); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)chPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } Blt_ConfigureCrosshairs(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * OnOp -- * * Maps the crosshairs. * * Results: * A standard TCL result. * * Side Effects: * Crosshairs are reset if necessary. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OnOp( Graph *graphPtr, Tcl_Interp *interp, /* Not used. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { Crosshairs *chPtr = graphPtr->crosshairs; if (chPtr->hidden) { TurnOnHairs(graphPtr, chPtr); chPtr->hidden = FALSE; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * OffOp -- * * Unmaps the crosshairs. * * Results: * A standard TCL result. * * Side Effects: * Crosshairs are reset if necessary. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OffOp( Graph *graphPtr, Tcl_Interp *interp, /* Not used. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { Crosshairs *chPtr = graphPtr->crosshairs; if (!chPtr->hidden) { TurnOffHairs(graphPtr->tkwin, chPtr); chPtr->hidden = TRUE; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ToggleOp -- * * Toggles the state of the crosshairs. * * Results: * A standard TCL result. * * Side Effects: * Crosshairs are reset. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ToggleOp( Graph *graphPtr, Tcl_Interp *interp, /* Not used. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { Crosshairs *chPtr = graphPtr->crosshairs; chPtr->hidden = (chPtr->hidden == 0); if (chPtr->hidden) { TurnOffHairs(graphPtr->tkwin, chPtr); } else { TurnOnHairs(graphPtr, chPtr); } return TCL_OK; } static Blt_OpSpec xhairOps[] = { {"cget", 2, CgetOp, 4, 4, "option",}, {"configure", 2, ConfigureOp, 3, 0, "?options...?",}, {"off", 2, OffOp, 3, 3, "",}, {"on", 2, OnOp, 3, 3, "",}, {"toggle", 1, ToggleOp, 3, 3, "",}, }; static int nXhairOps = sizeof(xhairOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * Blt_CrosshairsOp -- * * User routine to configure crosshair simulation. Crosshairs * are simulated by drawing line segments parallel to both axes * using the XOR drawing function. The allows the lines to be * erased (by drawing them again) without redrawing the entire * graph. Care must be taken to erase crosshairs before redrawing * the graph and redraw them after the graph is redraw. * * Results: * The return value is a standard TCL result. * * Side Effects: * Crosshairs may be drawn in the plotting area. * *--------------------------------------------------------------------------- */ int Blt_CrosshairsOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphCrosshairProc *proc; proc = Blt_GetOpFromObj(interp, nXhairOps, xhairOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (graphPtr, interp, objc, objv); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltNsUtil.h�������������������������������������������������������������������0000644�0001750�0001750�00000006367�11462120062�015132� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltNsUtil.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BLT_NS_UTIL_H #define BLT_NS_UTIL_H 1 #ifndef TCL_NAMESPACE_ONLY #define TCL_NAMESPACE_ONLY TCL_GLOBAL_ONLY #endif #define NS_SEARCH_NONE (0) #define NS_SEARCH_CURRENT (1<<0) #define NS_SEARCH_GLOBAL (1<<1) #define NS_SEARCH_BOTH (NS_SEARCH_GLOBAL | NS_SEARCH_CURRENT) typedef struct { const char *name; Tcl_Namespace *nsPtr; } Blt_ObjectName; #define BLT_NO_DEFAULT_NS (1<<0) #define BLT_NO_ERROR_MSG (1<<1) #ifndef USE_TCL_STUBS BLT_EXTERN Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name, Tcl_Namespace *nsPtr, int flags); /* * Namespace procedures not prototyped defined in Tcl.h */ BLT_EXTERN Tcl_Namespace *Tcl_GetCurrentNamespace(Tcl_Interp *interp); BLT_EXTERN Tcl_Namespace *Tcl_GetGlobalNamespace(Tcl_Interp *interp); BLT_EXTERN Tcl_Namespace *Tcl_CreateNamespace(Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *nsDelProc); BLT_EXTERN void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr); BLT_EXTERN Tcl_Namespace *Tcl_FindNamespace(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags); BLT_EXTERN int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *name, int resetFlag); BLT_EXTERN Tcl_Var Tcl_FindNamespaceVar(Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); BLT_EXTERN void Tcl_PopCallFrame(Tcl_Interp *interp); BLT_EXTERN int Tcl_PushCallFrame(Tcl_Interp *interp, Tcl_CallFrame *framePtr, Tcl_Namespace *nsPtr, int isProcCallFrame); #endif /* USE_TCL_STUBS */ /* * Auxillary procedures */ BLT_EXTERN Tcl_Namespace *Blt_GetVariableNamespace(Tcl_Interp *interp, const char *varName); BLT_EXTERN Tcl_Namespace *Blt_GetCommandNamespace(Tcl_Command cmdToken); BLT_EXTERN Tcl_CallFrame *Blt_EnterNamespace(Tcl_Interp *interp, Tcl_Namespace *nsPtr); BLT_EXTERN void Blt_LeaveNamespace(Tcl_Interp *interp, Tcl_CallFrame *framePtr); BLT_EXTERN int Blt_ParseObjectName(Tcl_Interp *interp, const char *name, Blt_ObjectName *objNamePtr, unsigned int flags); BLT_EXTERN char *Blt_MakeQualifiedName(Blt_ObjectName *objNamePtr, Tcl_DString *resultPtr); #endif /* BLT_NS_UTIL_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkFont.h����������������������������������������������������������������������0000644�0001750�0001750�00000014154�11462120063�014451� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkFont.h -- * * * This file contains definitions of internal Tk font structures. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _TK_FONT_H #define _TK_FONT_H /* * Possible values for the "weight" field in a TkFontAttributes structure. * Weight is a subjective term and depends on what the company that created * the font considers bold. */ #define TK_FW_NORMAL 0 #define TK_FW_BOLD 1 #define TK_FW_UNKNOWN -1 /* Unknown weight. This value is used for * error checking and is never actually stored * in the weight field. */ /* * Possible values for the "slant" field in a TkFontAttributes structure. */ #define TK_FS_ROMAN 0 #define TK_FS_ITALIC 1 #define TK_FS_OBLIQUE 2 /* This value is only used when parsing X * font names to determine the closest * match. It is only stored in the * XLFDAttributes structure, never in the * slant field of the TkFontAttributes. */ #define TK_FS_UNKNOWN -1 /* Unknown slant. This value is used for * error checking and is never actually stored * in the slant field. */ typedef struct { Tk_Uid family; /* Font family. The most important field. */ int size; /* Pointsize of font, 0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ int underline; /* Non-zero for underline font. */ int overstrike; /* Non-zero for overstrike font. */ } TkFontAttributes; typedef struct { int ascent; /* From baseline to top of font. */ int descent; /* From baseline to bottom of font. */ int maxWidth; /* Width of widest character in font. */ int fixed; /* Non-zero if this is a fixed-width font, * 0 otherwise. */ } TkFontMetrics; typedef struct _TkFont { /* * Fields used and maintained exclusively by generic code. */ #if (_TK_VERSION >= _VERSION(8,1,0)) int resourceRefCount; /* Number of active uses of this font (each * active use corresponds to a call to * Tk_AllocFontFromTable or Tk_GetFont). * If this count is 0, then this TkFont * structure is no longer valid and it isn't * present in a hash table: it is being * kept around only because there are objects * referring to it. The structure is freed * when resourceRefCount and objRefCount * are both 0. */ int objRefCount; /* The number of TCL objects that reference * this structure. */ #else int refCount; /* Number of users of the TkFont. */ #endif Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure, * used when deleting it. */ Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that * corresponds to the named font that the * tkfont was based on, or NULL if the tkfont * was not based on a named font. */ #if (_TK_VERSION >= _VERSION(8,1,0)) Screen *screen; /* The screen where this font is valid. */ #endif /* _TK_VERSION >= 8.1.0 */ int tabWidth; /* Width of tabs in this font (pixels). */ int underlinePos; /* Offset from baseline to origin of * underline bar (used for drawing underlines * on a non-underlined font). */ int underlineHeight; /* Height of underline bar (used for drawing * underlines on a non-underlined font). */ /* * Fields in the generic font structure that are filled in by * platform-specific code. */ Font fid; /* For backwards compatibility with XGCValues * structures. Remove when TkGCValues is * implemented. */ TkFontAttributes fa; /* Actual font attributes obtained when the * the font was created, as opposed to the * desired attributes passed in to * TkpGetFontFromAttributes(). The desired * metrics can be determined from the string * that was used to create this font. */ TkFontMetrics fm; /* Font metrics determined when font was * created. */ #if (_TK_VERSION >= _VERSION(8,1,0)) struct _TkFont *nextPtr; /* Points to the next TkFont structure with * the same name. All fonts with the * same name (but different displays) are * chained together off a single entry in * a hash table. */ #endif /* _TK_VERSION >= 8.1.0 */ } TkFont; typedef struct TkXLFDAttributes { Tk_Uid foundry; /* The foundry of the font. */ int slant; /* The tristate value for the slant, which * is significant under X. */ int setwidth; /* The proportionate width, see below for * definition. */ Tk_Uid charset; /* The actual charset string. */ } TkXLFDAttributes; #ifdef notdef static const char *encodingList[] = { "ucs-2be", "iso8859-1", "jis0208", "jis0212", NULL }; #endif /* * The following structure and definition is used to keep track of the * alternative names for various encodings. Asking for an encoding that * matches one of the alias patterns will result in actually getting the * encoding by its real name. */ typedef struct EncodingAlias { char *realName; /* The real name of the encoding to load if * the provided name matched the pattern. */ char *aliasPattern; /* Pattern for encoding name, of the form * that is acceptable to Tcl_StringMatch. */ } EncodingAlias; /* * Just some utility structures used for passing around values in helper * procedures. */ typedef struct FontAttributes { TkFontAttributes fa; TkXLFDAttributes xa; } FontAttributes; typedef struct TkFontInfo { Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font. * Keys are string font names, values are * TkFont pointers. */ Tcl_HashTable namedTable; /* Map a name to a set of attributes for a * font, used when constructing a Tk_Font from * a named font description. Keys are * strings, values are NamedFont pointers. */ TkMainInfo *mainPtr; /* Application that owns this structure. */ int updatePending; /* Non-zero when a World Changed event has * already been queued to handle a change to * a named font. */ } TkFontInfo; #endif /* _TK_FONT_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinMain.c������������������������������������������������������������������0000644�0001750�0001750�00000037671�11462120063�015254� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinMain.c -- * * Main entry point for wish and other Tk-based applications. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from the Tk library distribution. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "config.h" #undef USE_TK_STUBS #undef USE_TCL_STUBS #include "blt.h" #include <tcl.h> #include <tk.h> #include <locale.h> #include <stdio.h> #ifdef HAVE_STRING_H #include <string.h> #endif #define _VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #define _TCL_VERSION _VERSION(TCL_MAJOR_VERSION, TCL_MINOR_VERSION, TCL_RELEASE_SERIAL) #define _TK_VERSION _VERSION(TK_MAJOR_VERSION, TK_MINOR_VERSION, TK_RELEASE_SERIAL) #ifdef WIN32 # define STRICT # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef STRICT # undef WIN32_LEAN_AND_MEAN # include <windowsx.h> #endif /* WIN32 */ #define vsnprintf _vsnprintf /* * Forward declarations for procedures defined later in this file: */ static void setargv(int *argcPtr, char ***argvPtr); #ifndef TCL_ONLY #if (_TCL_VERSION >= _VERSION(8,2,0)) static BOOL consoleRequired = TRUE; #endif #endif static Tcl_AppInitProc Initialize; #ifndef TCL_ONLY static Tcl_PanicProc WishPanic; #endif #if (_TK_VERSION < _VERSION(8,2,0)) /* * The following declarations refer to internal Tk routines. These interfaces * are available for use, but are not supported. */ extern void Blt_ConsoleCreate(void); extern int Blt_ConsoleInit(Tcl_Interp *interp); #endif /* _TK_VERSION < 8.2.0 */ /* *--------------------------------------------------------------------------- * * setargv -- * * Parse the Windows command line string into argc/argv. Done here * because we don't trust the builtin argument parser in crt0. Windows * applications are responsible for breaking their command line into * arguments. * * 2N backslashes + quote -> N backslashes + begin quoted string * 2N + 1 backslashes + quote -> literal * N backslashes + non-quote -> literal * quote + quote in a quoted string -> single quote * quote + quote not in quoted string -> empty string * quote -> begin quoted string * * Results: * Fills argcPtr with the number of arguments and argvPtr with the * array of arguments. * * Side effects: * Memory allocated. * *--------------------------------------------------------------------------- */ static void setargv( int *argcPtr, /* Filled with number of argument strings. */ char ***argvPtr) { /* Filled with argument strings (malloc'd). */ char *cmdLine, *p, *arg, *argSpace; char **argv; int argc, size, inquote, copy, slashes; cmdLine = GetCommandLine(); /* INTL: BUG */ /* * Precompute an overly pessimistic guess at the number of arguments in * the command line by counting non-space spans. */ size = 2; for (p = cmdLine; *p != '\0'; p++) { if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ size++; while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ p++; } if (*p == '\0') { break; } } } argSpace = (char *)Tcl_Alloc( (unsigned)(size * sizeof(char *) + strlen(cmdLine) + 1)); argv = (char **)argSpace; argSpace += size * sizeof(char *); size--; p = cmdLine; for (argc = 0; argc < size; argc++) { argv[argc] = arg = argSpace; while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ p++; } if (*p == '\0') { break; } inquote = 0; slashes = 0; while (1) { copy = 1; while (*p == '\\') { slashes++; p++; } if (*p == '"') { if ((slashes & 1) == 0) { copy = 0; if ((inquote) && (p[1] == '"')) { p++; copy = 1; } else { inquote = !inquote; } } slashes >>= 1; } while (slashes) { *arg = '\\'; arg++; slashes--; } if ((*p == '\0') || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ break; } if (copy != 0) { *arg = *p; arg++; } p++; } *arg = '\0'; argSpace = arg + 1; } argv[argc] = NULL; *argcPtr = argc; *argvPtr = argv; } /* *--------------------------------------------------------------------------- * * Initialize -- * * This procedure performs application-specific initialization. Most * applications, especially those that incorporate additional packages, * will have their own version of this procedure. * * Results: * Returns a standard TCL completion code, and leaves an error message in * the interp's result if an error occurs. * * Side effects: * Depends on the startup script. * *--------------------------------------------------------------------------- */ BLT_EXTERN Tcl_AppInitProc Blt_core_Init; BLT_EXTERN Tcl_AppInitProc Blt_core_SafeInit; #ifndef TCL_ONLY BLT_EXTERN Tcl_AppInitProc Blt_x_Init; BLT_EXTERN Tcl_AppInitProc Blt_x_SafeInit; #endif #ifdef STATIC_PKGS /* Picture format packages. */ #ifndef TCL_ONLY BLT_EXTERN Tcl_AppInitProc Blt_PictureBmpInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureGifInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureJpgInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePbmInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePdfInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePhotoInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePngInit; BLT_EXTERN Tcl_AppInitProc Blt_PicturePsInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureTifInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureXbmInit; BLT_EXTERN Tcl_AppInitProc Blt_PictureXpmInit; #endif /* TCL_ONLY */ /* Data table format packages. */ BLT_EXTERN Tcl_AppInitProc Blt_Table_CsvInit; #ifdef HAVE_LIBMYSQL BLT_EXTERN Tcl_AppInitProc Blt_Table_MysqlInit; #endif /* HAVE_LIBMYSQL */ BLT_EXTERN Tcl_AppInitProc Blt_Table_TreeInit; BLT_EXTERN Tcl_AppInitProc Blt_Table_VectorInit; #ifdef HAVE_LIBEXPAT BLT_EXTERN Tcl_AppInitProc Blt_Table_XmlInit; #endif /* Tree format packages. */ #ifdef HAVE_LIBEXPAT BLT_EXTERN Tcl_AppInitProc Blt_TreeXmlInit; #endif #endif /* STATIC_PKGS */ int Initialize(Tcl_Interp *interp) /* Interpreter for application. */ { #ifdef TCLLIBPATH /* * It seems that some distributions of TCL don't compile-in a * default location of the library. This causes Tcl_Init to fail * if bltwish and bltsh are moved to another directory. The * workaround is to set the magic variable "tclDefaultLibrary". */ Tcl_SetVar(interp, "tclDefaultLibrary", TCLLIBPATH, TCL_GLOBAL_ONLY); #endif /* TCLLIBPATH */ if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (Blt_core_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_core", Blt_core_Init, Blt_core_SafeInit); #ifdef STATIC_PKGS /* Tcl-only static packages */ if (Blt_Table_CsvInit(interp) != TCL_OK) { return TCL_ERROR; } /* Data table packages. */ Tcl_StaticPackage(interp, "blt_datatable_csv", Blt_Table_CsvInit, Blt_Table_CsvInit); #ifdef HAVE_LIBMYSQL if (Blt_Table_MysqlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_mysql", Blt_Table_MysqlInit, Blt_Table_MysqlInit); #endif /* HAVE_LIBMYSQL */ if (Blt_Table_TreeInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_tree", Blt_Table_TreeInit, Blt_Table_TreeInit); if (Blt_Table_VectorInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_vector", Blt_Table_VectorInit, Blt_Table_VectorInit); #ifdef HAVE_LIBEXPAT if (Blt_Table_XmlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_datatable_xml", Blt_Table_XmlInit, Blt_Table_XmlInit); #endif /* HAVE_LIBEXPAT */ /* Tree packages. */ #ifdef HAVE_LIBEXPAT if (Blt_TreeXmlInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_tree_xml", Blt_TreeXmlInit, Blt_TreeXmlInit); #endif /* HAVE_LIBEXPAT */ #endif /* STATIC_PKGS */ #ifndef TCL_ONLY if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Blt_x_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_extra", Blt_x_Init, Blt_x_SafeInit); #ifdef STATIC_PKGS /* Picture packages. */ if (Blt_PictureBmpInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_bmp", Blt_PictureBmpInit, Blt_PictureBmpInit); if (Blt_PictureGifInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_gif", Blt_PictureGifInit, Blt_PictureGifInit); #ifdef HAVE_LIBJPG if (Blt_PictureJpgInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_jpg", Blt_PictureJpgInit, Blt_PictureJpgInit); #endif /*HAVE_LIBJPG*/ if (Blt_PicturePbmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_pbm", Blt_PicturePbmInit, Blt_PicturePbmInit); if (Blt_PicturePhotoInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_photo", Blt_PicturePhotoInit, Blt_PicturePhotoInit); #ifdef HAVE_LIBPNG if (Blt_PicturePngInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_png", Blt_PicturePngInit, Blt_PicturePngInit); #endif /*HAVE_LIBPNG*/ if (Blt_PicturePsInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_ps", Blt_PicturePsInit, Blt_PicturePsInit); if (Blt_PicturePdfInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_pdf", Blt_PicturePdfInit, Blt_PicturePdfInit); #ifdef HAVE_LIBTIF if (Blt_PictureTifInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_tif", Blt_PictureTifInit, Blt_PictureTifInit); #endif /*HAVE_LIBTIF*/ if (Blt_PictureXbmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_xbm", Blt_PictureXbmInit, Blt_PictureXbmInit); #ifdef HAVE_LIBXPM if (Blt_PictureXpmInit(interp) != TCL_OK) { return TCL_ERROR; } Tcl_StaticPackage(interp, "blt_picture_xpm", Blt_PictureXpmInit, Blt_PictureXpmInit); #endif /*HAVE_LIBXPM*/ #endif /* STATIC_PKGS */ #endif /*TCL_ONLY*/ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ #ifdef TCL_ONLY Tcl_SetVar(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY); #else Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY); #endif #ifndef TCL_ONLY #if (_TCL_VERSION >= _VERSION(8,2,0)) if (consoleRequired) { if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { goto error; } } #else /* * Initialize the console only if we are running as an interactive * application. */ if (Blt_ConsoleInit(interp) == TCL_ERROR) { goto error; } #endif /* _TCL_VERSION >= 8.2.0 */ #endif /* TCL_ONLY */ return TCL_OK; #ifndef TCL_ONLY error: WishPanic(Tcl_GetStringResult(interp)); #endif return TCL_ERROR; } #ifdef TCL_ONLY /* *--------------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tcl_Main never returns here, so this procedure never returns * either. * * Side effects: * Whatever the application does. * *--------------------------------------------------------------------------- */ int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { char buffer[MAX_PATH +1]; char *p; /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. */ setlocale(LC_ALL, "C"); setargv(&argc, &argv); /* * Replace argv[0] with full pathname of executable, and forward slashes * substituted for backslashes. */ GetModuleFileName(NULL, buffer, sizeof(buffer)); argv[0] = buffer; for (p = buffer; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } Tcl_Main(argc, argv, Initialize); return 0; /* Needed only to prevent compiler warning. */ } #else /* TCL_ONLY */ /* *--------------------------------------------------------------------------- * * WishPanic -- * * Display a message and exit. * * Results: * None. * * Side effects: * Exits the program. * *--------------------------------------------------------------------------- */ static void WishPanic TCL_VARARGS_DEF(const char *, arg1) { va_list argList; char buf[1024]; const char *format; format = TCL_VARARGS_START(char *, arg1, argList); vsnprintf(buf, 1024, format, argList); buf[1023] = '\0'; MessageBeep(MB_ICONEXCLAMATION); MessageBox(NULL, buf, "Fatal Error in Wish", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND); #if defined(_MSC_VER) || defined(__BORLANDC__) DebugBreak(); #ifdef notdef /* Panics shouldn't cause exceptions. Simply * let the program exit. */ _asm { int 3 } #endif #endif /* _MSC_VER || __BORLANDC__ */ ExitProcess(1); } /* *--------------------------------------------------------------------------- * * WinMain -- * * Main entry point from Windows. * * Results: * Returns false if initialization fails, otherwise it never returns. * * Side effects: * Just about anything, since from here we call arbitrary TCL code. * *--------------------------------------------------------------------------- */ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { char **argv; int argc; Tcl_SetPanicProc(WishPanic); /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. */ setlocale(LC_ALL, "C"); setargv(&argc, &argv); /* * Increase the application queue size from default value of 8. At the * default value, cross application SendMessage of WM_KILLFOCUS will fail * because the handler will not be able to do a PostMessage! This is only * needed for Windows 3.x, since NT dynamically expands the queue. */ SetMessageQueue(64); /* * Create the console channels and install them as the standard channels. * All I/O will be discarded until Blt_ConsoleInit is called to attach the * console to a text widget. */ #if (_TCL_VERSION >= _VERSION(8,2,0)) consoleRequired = TRUE; #else Blt_ConsoleCreate(); #endif Tk_Main(argc, argv, Initialize); return 1; } #endif /* TCL_ONLY */ �����������������������������������������������������������������������./saods9/blt3.0.1/src/tkWinFont.h�������������������������������������������������������������������0000644�0001750�0001750�00000013557�11462120063�015135� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkWinFont.h -- * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file contains structure definitions from tkWinFont.h of the Tk * library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #ifndef _TK_WINFONT_H #define _TK_WINFONT_H /* * The following structure represents a font family. It is assumed that * all screen fonts constructed from the same "font family" share certain * properties; all screen fonts with the same "font family" point to a * shared instance of this structure. The most important shared property * is the character existence metrics, used to determine if a screen font * can display a given Unicode character. * * Under Windows, a "font family" is uniquely identified by its face name. */ #define FONTMAP_SHIFT 10 #define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT)) #define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) typedef struct FontFamily { struct FontFamily *nextPtr; /* Next in list of all known font families. */ int refCount; /* How many SubFonts are referring to this * FontFamily. When the refCount drops to * zero, this FontFamily may be freed. */ /* * Key. */ Tk_Uid faceName; /* Face name key for this FontFamily. */ /* * Derived properties. */ Tcl_Encoding encoding; /* Encoding for this font family. */ int isSymbolFont; /* Non-zero if this is a symbol font. */ int isWideFont; /* 1 if this is a double-byte font, 0 * otherwise. */ BOOL (WINAPI *textOutProc)(HDC, int, int, TCHAR *, int); /* The procedure to use to draw text after * it has been converted from UTF-8 to the * encoding of this font. */ BOOL (WINAPI *getTextExtentPoint32Proc)(HDC, TCHAR *, int, LPSIZE); /* The procedure to use to measure text after * it has been converted from UTF-8 to the * encoding of this font. */ char *fontMap[FONTMAP_PAGES]; /* Two-level sparse table used to determine * quickly if the specified character exists. * As characters are encountered, more pages * in this table are dynamically added. The * contents of each page is a bitmask * consisting of FONTMAP_BITSPERPAGE bits, * representing whether this font can be used * to display the given character at the * corresponding bit position. The high bits * of the character are used to pick which * page of the table is used. */ /* * Cached Truetype font info. */ int segCount; /* The length of the following arrays. */ USHORT *startCount; /* Truetype information about the font, */ USHORT *endCount; /* indicating which characters this font * can display (malloced). The format of * this information is (relatively) compact, * but would take longer to search than * indexing into the fontMap[][] table. */ } FontFamily; /* * The following structure encapsulates an individual screen font. A font * object is made up of however many SubFonts are necessary to display a * stream of multilingual characters. */ typedef struct SubFont { char **fontMap; /* Pointer to font map from the FontFamily, * cached here to save a dereference. */ HFONT hFont; /* The specific screen font that will be * used when displaying/measuring chars * belonging to the FontFamily. */ FontFamily *familyPtr; /* The FontFamily for this SubFont. */ } SubFont; /* * The following structure represents Windows' implementation of a font * object. */ #define SUBFONT_SPACE 3 #define BASE_CHARS 128 typedef struct WinFont { TkFont font; /* Stuff used by generic font package. Must * be first in structure. */ SubFont staticSubFonts[SUBFONT_SPACE]; /* Builtin space for a limited number of * SubFonts. */ int numSubFonts; /* Length of following array. */ SubFont *subFontArray; /* Array of SubFonts that have been loaded * in order to draw/measure all the characters * encountered by this font so far. All fonts * start off with one SubFont initialized by * AllocFont() from the original set of font * attributes. Usually points to * staticSubFonts, but may point to malloced * space if there are lots of SubFonts. */ HWND hwnd; /* Toplevel window of application that owns * this font, used for getting HDC for * offscreen measurements. */ int pixelSize; /* Original pixel size used when font was * constructed. */ int widths[BASE_CHARS]; /* Widths of first 128 chars in the base * font, for handling common case. The base * font is always used to draw characters * between 0x0000 and 0x007f. */ } WinFont; #endif /* _TK_WINFONT_H */ �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinDraw.c������������������������������������������������������������������0000644�0001750�0001750�00000227510�11462120063�015256� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinDraw.c -- * * This module contains WIN32 routines not included in the Tcl/Tk * libraries. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <bltInt.h> #include <X11/Xutil.h> #include <X11/Xlib.h> #include <bltFont.h> #include <bltText.h> #include "tkDisplay.h" #include "tkFont.h" #include "tkIntBorder.h" #define WINDEBUG 0 /* * Data structure for setting graphics context. */ typedef struct { int function; /* logical operation */ unsigned long plane_mask; /* plane mask */ unsigned long foreground; /* foreground pixel */ unsigned long background; /* background pixel */ int line_width; /* line width */ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ int join_style; /* JoinMiter, JoinRound, JoinBevel */ int fill_style; /* FillSolid, FillTiled, FillStippled, FillOpaeueStippled */ int fill_rule; /* EvenOddRule, WindingRule */ int arc_mode; /* ArcChord, ArcPieSlice */ Pixmap tile; /* tile pixmap for tiling operations */ Pixmap stipple; /* stipple 1 plane pixmap for stipping */ int ts_x_origin; /* offset for tile or stipple operations */ int ts_y_origin; Font font; /* default text font for text operations */ int subwindow_mode; /* ClipByChildren, IncludeInferiors */ Bool graphics_exposures; /* boolean, should exposures be generated */ int clip_x_origin; /* origin for clipping */ int clip_y_origin; Pixmap clip_mask; /* bitmap clipping; other calls for rects */ int dash_offset; /* patterned/dashed line information */ char dashes; /* If -1, indicates that the extended * information below is available. */ int nDashValues; char dashValues[12]; } XGCValuesEx; static int tkpWinRopModes[] = { R2_BLACK, /* GXclear */ R2_MASKPEN, /* GXand */ R2_MASKPENNOT, /* GXandReverse */ R2_COPYPEN, /* GXcopy */ R2_MASKNOTPEN, /* GXandInverted */ R2_NOT, /* GXnoop */ R2_XORPEN, /* GXxor */ R2_MERGEPEN, /* GXor */ R2_NOTMERGEPEN, /* GXnor */ R2_NOTXORPEN, /* GXequiv */ R2_NOT, /* GXinvert */ R2_MERGEPENNOT, /* GXorReverse */ R2_NOTCOPYPEN, /* GXcopyInverted */ R2_MERGENOTPEN, /* GXorInverted */ R2_NOTMASKPEN, /* GXnand */ R2_WHITE /* GXset */ }; #define MASKPAT 0x00E20746 /* dest = (src & pat) | (!src & dst) */ #define COPYFG 0x00CA0749 /* dest = (pat & src) | (!pat & dst) */ #define COPYBG 0x00AC0744 /* dest = (!pat & src) | (pat & dst) */ /* * Translation table between X gc functions and Win32 BitBlt op modes. Some * of the operations defined in X don't have names, so we have to construct * new opcodes for those functions. This is arcane and probably not all that * useful, but at least it's accurate. */ #define NOTSRCAND (DWORD)0x00220326 /* dest = (NOT src) AND dest */ #define NOTSRCINVERT (DWORD)0x00990066 /* dest = (NOT src) XOR dest */ #define SRCORREVERSE (DWORD)0x00DD0228 /* dest = src OR (NOT dest) */ #define SRCNAND (DWORD)0x007700E6 /* dest = NOT (src AND dest) */ static int bltModes[] = { BLACKNESS, /* GXclear */ SRCAND, /* GXand */ SRCERASE, /* GXandReverse */ SRCCOPY, /* GXcopy */ NOTSRCAND, /* GXandInverted */ PATCOPY, /* GXnoop */ SRCINVERT, /* GXxor */ SRCPAINT, /* GXor */ NOTSRCERASE, /* GXnor */ NOTSRCINVERT, /* GXequiv */ DSTINVERT, /* GXinvert */ SRCORREVERSE, /* GXorReverse */ NOTSRCCOPY, /* GXcopyInverted */ MERGEPAINT, /* GXorInverted */ SRCNAND, /* GXnand */ WHITENESS /* GXset */ }; #if (_TCL_VERSION < _VERSION(8,1,0)) typedef void *Tcl_Encoding; /* Make up dummy type for encoding. */ #else static Tcl_Encoding systemEncoding = NULL; #endif HPALETTE Blt_GetSystemPalette(void) { HDC hDC; HPALETTE hPalette; DWORD flags; hPalette = NULL; hDC = GetDC(NULL); /* Get the desktop device context */ flags = GetDeviceCaps(hDC, RASTERCAPS); if (flags & RC_PALETTE) { LOGPALETTE *palettePtr; palettePtr = (LOGPALETTE *) GlobalAlloc(GPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)); palettePtr->palVersion = 0x300; palettePtr->palNumEntries = 256; GetSystemPaletteEntries(hDC, 0, 256, palettePtr->palPalEntry); hPalette = CreatePalette(palettePtr); GlobalFree(palettePtr); } ReleaseDC(NULL, hDC); return hPalette; } /* *--------------------------------------------------------------------------- * * CreateRotatedFont -- * * Creates a rotated copy of the given font. This only works * for TrueType fonts. * * Results: * Returns the newly create font or NULL if the font could not * be created. * *--------------------------------------------------------------------------- */ static HFONT CreateRotatedFont( unsigned long fontId, /* Font identifier (actually a Tk_Font) */ float angle) { /* Number of degrees to rotate font */ TkFontAttributes *faPtr; /* Set of attributes to match. */ TkFont *fontPtr; HFONT hFont; LOGFONTW lf; fontPtr = (TkFont *) fontId; faPtr = &fontPtr->fa; ZeroMemory(&lf, sizeof(LOGFONT)); lf.lfHeight = -faPtr->size; if (lf.lfHeight < 0) { HDC dc; dc = GetDC(NULL); lf.lfHeight = -MulDiv(faPtr->size, GetDeviceCaps(dc, LOGPIXELSY), 72); ReleaseDC(NULL, dc); } lf.lfWidth = 0; lf.lfEscapement = lf.lfOrientation = ROUND(angle * 10.0); #define TK_FW_NORMAL 0 lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; lf.lfItalic = faPtr->slant; lf.lfUnderline = faPtr->underline; lf.lfStrikeOut = faPtr->overstrike; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfQuality = ANTIALIASED_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; hFont = NULL; if (faPtr->family == NULL) { lf.lfFaceName[0] = '\0'; } else { #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_DString dString; Tcl_UtfToExternalDString(systemEncoding, faPtr->family, -1, &dString); if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { Tcl_UniChar *src, *dst; /* * We can only store up to LF_FACESIZE wide characters */ if (Tcl_DStringLength(&dString) >= (LF_FACESIZE * sizeof(WCHAR))) { Tcl_DStringSetLength(&dString, LF_FACESIZE); } src = (Tcl_UniChar *)Tcl_DStringValue(&dString); dst = (Tcl_UniChar *)lf.lfFaceName; while (*src != '\0') { *dst++ = *src++; } *dst = '\0'; hFont = CreateFontIndirectW((LOGFONTW *)&lf); } else { /* * We can only store up to LF_FACESIZE characters */ if (Tcl_DStringLength(&dString) >= LF_FACESIZE) { Tcl_DStringSetLength(&dString, LF_FACESIZE); } strcpy((char *)lf.lfFaceName, Tcl_DStringValue(&dString)); hFont = CreateFontIndirectA((LOGFONTA *)&lf); } Tcl_DStringFree(&dString); #else strncpy((char *)lf.lfFaceName, faPtr->family, LF_FACESIZE - 1); lf.lfFaceName[LF_FACESIZE] = '\0'; #endif /* _TCL_VERSION >= 8.1.0 */ } if (hFont == NULL) { #if WINDEBUG PurifyPrintf("can't create font: %s\n", Blt_LastError()); #endif } else { HFONT oldFont; TEXTMETRIC tm; HDC hRefDC; int result; /* Check if the rotated font is really a TrueType font. */ hRefDC = GetDC(NULL); /* Get the desktop device context */ oldFont = SelectFont(hRefDC, hFont); result = ((GetTextMetrics(hRefDC, &tm)) && (tm.tmPitchAndFamily & TMPF_TRUETYPE)); SelectFont(hRefDC, oldFont); ReleaseDC(NULL, hRefDC); if (!result) { #if WINDEBUG PurifyPrintf("not a true type font\n"); #endif DeleteFont(hFont); return NULL; } } return hFont; } /* *--------------------------------------------------------------------------- * * Blt_GetBitmapData -- * * Returns the DIB bits from a bitmap. * * Results: * Returns a byte array of bitmap data or NULL if an error * occurred. The parameter pitchPtr returns the number * of bytes per row. * *--------------------------------------------------------------------------- */ unsigned char * Blt_GetBitmapData( Display *display, /* Display of bitmap */ Pixmap bitmap, /* Bitmap to query */ int width, /* Width of bitmap */ int height, /* Height of bitmap */ int *pitchPtr) /* (out) Number of bytes per row */ { TkWinDCState state; HDC hDC; int result; unsigned char *bits; unsigned int size; HBITMAP hBitmap; BITMAPINFOHEADER *bmihPtr; HANDLE hMem, hMem2; int bytesPerRow, imageSize; size = sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); hMem = GlobalAlloc(GHND, size); bmihPtr = (BITMAPINFOHEADER *)GlobalLock(hMem); bmihPtr->biSize = sizeof(BITMAPINFOHEADER); bmihPtr->biPlanes = 1; bmihPtr->biBitCount = 1; bmihPtr->biCompression = BI_RGB; bmihPtr->biWidth = width; bmihPtr->biHeight = height; hBitmap = ((TkWinDrawable *)bitmap)->bitmap.handle; hDC = TkWinGetDrawableDC(display, bitmap, &state); result = GetDIBits(hDC, hBitmap, 0, height, (LPVOID)NULL, (BITMAPINFO *)bmihPtr, DIB_RGB_COLORS); TkWinReleaseDrawableDC(bitmap, hDC, &state); if (!result) { GlobalUnlock(hMem); GlobalFree(hMem); return NULL; } imageSize = bmihPtr->biSizeImage; GlobalUnlock(hMem); bytesPerRow = ((width + 31) & ~31) / 8; if (imageSize == 0) { imageSize = bytesPerRow * height; } hMem2 = GlobalReAlloc(hMem, size + imageSize, 0); if (hMem2 == NULL) { GlobalFree(hMem); return NULL; } hMem = hMem2; bmihPtr = (BITMAPINFOHEADER *)GlobalLock(hMem); hDC = TkWinGetDrawableDC(display, bitmap, &state); result = GetDIBits(hDC, hBitmap, 0, height, (unsigned char *)bmihPtr + size, (BITMAPINFO *)bmihPtr, DIB_RGB_COLORS); TkWinReleaseDrawableDC(bitmap, hDC, &state); bits = NULL; if (!result) { OutputDebugString("GetDIBits failed\n"); } else { bits = Blt_Malloc(imageSize); if (bits != NULL) { memcpy (bits, (unsigned char *)bmihPtr + size, imageSize); } } GlobalUnlock(hMem); GlobalFree(hMem); *pitchPtr = bytesPerRow; return bits; } /* *--------------------------------------------------------------------------- * * XFree -- * *--------------------------------------------------------------------------- */ void Blt_EmulateXFree(void *ptr) { Blt_Free(ptr); } /* *--------------------------------------------------------------------------- * * XMaxRequestSize -- * *--------------------------------------------------------------------------- */ long Blt_EmulateXMaxRequestSize(Display *display) { return (SHRT_MAX / 4); } /* *--------------------------------------------------------------------------- * * XLowerWindow -- * *--------------------------------------------------------------------------- */ void Blt_EmulateXLowerWindow( Display *display, Window window) { HWND hWnd; hWnd = Tk_GetHWND(window); display->request++; SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } /* *--------------------------------------------------------------------------- * * XRaiseWindow -- * *--------------------------------------------------------------------------- */ void Blt_EmulateXRaiseWindow( Display *display, Window window) { HWND hWnd; hWnd = Tk_GetHWND(window); display->request++; SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } /* *--------------------------------------------------------------------------- * * XUnmapWindow -- * *--------------------------------------------------------------------------- */ void Blt_EmulateXUnmapWindow( Display *display, Window window) { HWND hWnd; hWnd = Tk_GetHWND(window); display->request++; ShowWindow(hWnd, SW_HIDE); /* SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); */ } /* *--------------------------------------------------------------------------- * * XWarpPointer -- * * If destWindow is None, moves the pointer by the offsets (destX, * destY) relative to the current position of the pointer. * If destWindow is a window, moves the pointer to the offsets * (destX, destY) relative to the origin of destWindow. However, * if srcWindow is a window, the move only takes place if the window * srcWindow contains the pointer and if the specified rectangle of * srcWindow contains the pointer. * * The srcX and srcY coordinates are relative to the origin of * srcWindow. If srcHeight is zero, it is replaced with the current * height of srcWindow minus srcY. If srcWidth is zero, it is * replaced with the current width of srcWindow minus srcX. * *--------------------------------------------------------------------------- */ void Blt_EmulateXWarpPointer( Display *display, Window srcWindow, Window destWindow, int srcX, int srcY, unsigned int srcWidth, unsigned int srcHeight, int destX, int destY) { HWND hWnd; POINT point; hWnd = Tk_GetHWND(destWindow); point.x = destX, point.y = destY; if (ClientToScreen(hWnd, &point)) { SetCursorPos(point.x, point.y); } } #ifdef notdef static Blt_HashTable gcTable; static int gcInitialized = FALSE; #endif typedef struct { HDC dc; int count; COLORREF color; int offset, nBits; } DashInfo; void Blt_SetDashes(Display *display, GC gc, Blt_Dashes *dashesPtr) { XGCValuesEx *gcPtr = (XGCValuesEx *)gc; /* This must be used only with a privately created GC */ assert((int)gcPtr->dashes == -1); gcPtr->nDashValues = strlen(dashesPtr->values); gcPtr->dash_offset = dashesPtr->offset; strcpy(gcPtr->dashValues, dashesPtr->values); } static int GetDashInfo( HDC dc, GC gc, DashInfo *infoPtr) { int dashOffset, dashValue; dashValue = 0; dashOffset = gc->dash_offset; if ((int)gc->dashes == -1) { XGCValuesEx *gcPtr = (XGCValuesEx *)gc; if (gcPtr->nDashValues == 1) { dashValue = gcPtr->dashValues[0]; } } else if (gc->dashes > 0) { dashValue = (int)gc->dashes; } if (dashValue == 0) { return FALSE; } infoPtr->dc = dc; infoPtr->nBits = dashValue; infoPtr->offset = dashOffset; infoPtr->count = 0; infoPtr->color = gc->foreground; return TRUE; } void Blt_SetROP2(HDC dc, int function) { SetROP2(dc, tkpWinRopModes[function]); } static XGCValuesEx * CreateGC() { XGCValuesEx *gcPtr; gcPtr = Blt_Malloc(sizeof(XGCValuesEx)); if (gcPtr == NULL) { return NULL; } gcPtr->arc_mode = ArcPieSlice; gcPtr->background = 0xffffff; gcPtr->cap_style = CapNotLast; gcPtr->clip_mask = None; gcPtr->clip_x_origin = gcPtr->clip_y_origin = 0; gcPtr->dash_offset = 0; gcPtr->fill_rule = WindingRule; gcPtr->fill_style = FillSolid; gcPtr->font = None; gcPtr->foreground = 0; gcPtr->function = GXcopy; gcPtr->graphics_exposures = True; gcPtr->join_style = JoinMiter; gcPtr->line_style = LineSolid; gcPtr->line_width = 0; gcPtr->plane_mask = ~0; gcPtr->stipple = None; gcPtr->subwindow_mode = ClipByChildren; gcPtr->tile = None; gcPtr->ts_x_origin = gcPtr->ts_y_origin = 0; gcPtr->dashes = -1; /* Mark that this an extended GC */ gcPtr->nDashValues = 0; return gcPtr; } /* *--------------------------------------------------------------------------- * * Blt_EmulateXCreateGC -- * * Allocate a new extended GC, and initialize the specified fields. * * Results: * Returns a newly allocated GC. * * Side effects: * None. * *--------------------------------------------------------------------------- */ GC Blt_EmulateXCreateGC( Display *display, Drawable drawable, unsigned long mask, XGCValues *srcPtr) { XGCValuesEx *destPtr; destPtr = CreateGC(); if (destPtr == NULL) { return None; } if (mask & GCFunction) { destPtr->function = srcPtr->function; } if (mask & GCPlaneMask) { destPtr->plane_mask = srcPtr->plane_mask; } if (mask & GCForeground) { destPtr->foreground = srcPtr->foreground; } if (mask & GCBackground) { destPtr->background = srcPtr->background; } if (mask & GCLineWidth) { destPtr->line_width = srcPtr->line_width; } if (mask & GCLineStyle) { destPtr->line_style = srcPtr->line_style; } if (mask & GCCapStyle) { destPtr->cap_style = srcPtr->cap_style; } if (mask & GCJoinStyle) { destPtr->join_style = srcPtr->join_style; } if (mask & GCFillStyle) { destPtr->fill_style = srcPtr->fill_style; } if (mask & GCFillRule) { destPtr->fill_rule = srcPtr->fill_rule; } if (mask & GCArcMode) { destPtr->arc_mode = srcPtr->arc_mode; } if (mask & GCTile) { destPtr->tile = srcPtr->tile; } if (mask & GCStipple) { destPtr->stipple = srcPtr->stipple; } if (mask & GCTileStipXOrigin) { destPtr->ts_x_origin = srcPtr->ts_x_origin; } if (mask & GCTileStipXOrigin) { destPtr->ts_y_origin = srcPtr->ts_y_origin; } if (mask & GCFont) { destPtr->font = srcPtr->font; } if (mask & GCSubwindowMode) { destPtr->subwindow_mode = srcPtr->subwindow_mode; } if (mask & GCGraphicsExposures) { destPtr->graphics_exposures = srcPtr->graphics_exposures; } if (mask & GCClipXOrigin) { destPtr->clip_x_origin = srcPtr->clip_x_origin; } if (mask & GCClipYOrigin) { destPtr->clip_y_origin = srcPtr->clip_y_origin; } if (mask & GCDashOffset) { destPtr->dash_offset = srcPtr->dash_offset; } if (mask & GCDashList) { destPtr->dashes = srcPtr->dashes; } if (mask & GCClipMask) { struct ClipMask { int type; /* TKP_CLIP_PIXMAP or TKP_CLIP_REGION */ Pixmap pixmap; } *clipPtr; clipPtr = Blt_AssertMalloc(sizeof(struct ClipMask)); #define TKP_CLIP_PIXMAP 0 clipPtr->type = TKP_CLIP_PIXMAP; clipPtr->pixmap = srcPtr->clip_mask; destPtr->clip_mask = (Pixmap) clipPtr; } return (GC)destPtr; } /* *--------------------------------------------------------------------------- * * Blt_GCToPen -- * * Set up the graphics port from the given GC. * * Geometric and cosmetic pens available under both 95 and NT. * Geometric pens differ from cosmetic pens in that they can * 1. Draw in world units (can have thick lines: line width > 1). * 2. Under NT, allow arbitrary line style. * 3. Can have caps and join (needed for thick lines). * 4. Draw very, very slowly. * * Cosmetic pens are single line width only. * * 95 98 NT * PS_SOLID c,g c,g c,g * PS_DASH c,g c,g c,g * PS_DOT c c c,g * PS_DASHDOT c - c,g * PS_DASHDOTDOT c - c,g * PS_USERSTYLE - - c,g * PS_ALTERNATE - - c * * Geometric only for 95/98 * * PS_ENDCAP_ROUND * PS_ENDCAP_SQUARE * PS_ENDCAP_FLAT * PS_JOIN_BEVEL * PS_JOIN_ROUND * PS_JOIN_MITER * * Results: * None. * * Side effects: * The current port is adjusted. * *--------------------------------------------------------------------------- */ HPEN Blt_GCToPen(HDC dc, GC gc) { DWORD lineAttrs, lineStyle; DWORD dashArr[12]; DWORD *dashPtr; int nValues, lineWidth; LOGBRUSH lBrush; HPEN pen; nValues = 0; lineWidth = (gc->line_width < 1) ? 1 : gc->line_width; if ((gc->line_style == LineOnOffDash) || (gc->line_style == LineDoubleDash)) { XGCValuesEx *gcPtr = (XGCValuesEx *)gc; if ((int)gc->dashes == -1) { int i; nValues = strlen(gcPtr->dashValues); for (i = 0; i < nValues; i++) { dashArr[i] = (DWORD)gcPtr->dashValues[i]; } if (nValues == 1) { dashArr[1] = dashArr[0]; nValues = 2; } } else { dashArr[1] = dashArr[0] = (DWORD) gc->dashes; nValues = 2; gc->dashes = -1; } } switch (nValues) { case 0: lineStyle = PS_SOLID; break; case 3: lineStyle = PS_DASHDOT; break; case 4: lineStyle = PS_DASHDOTDOT; break; case 2: default: /* PS_DASH style dash length is too long. */ lineStyle = PS_DOT; break; } lBrush.lbStyle = BS_SOLID; lBrush.lbColor = gc->foreground; lBrush.lbHatch = 0; /* Value is ignored when style is BS_SOLID. */ lineAttrs = 0; switch (gc->cap_style) { case CapNotLast: case CapButt: lineAttrs |= PS_ENDCAP_FLAT; break; case CapRound: lineAttrs |= PS_ENDCAP_ROUND; break; default: lineAttrs |= PS_ENDCAP_SQUARE; break; } switch (gc->join_style) { case JoinMiter: lineAttrs |= PS_JOIN_MITER; break; case JoinBevel: lineAttrs |= PS_JOIN_BEVEL; break; case JoinRound: default: lineAttrs |= PS_JOIN_ROUND; break; } SetBkMode(dc, TRANSPARENT); if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { /* Windows NT/2000/XP. */ if (nValues > 0) { lineStyle = PS_USERSTYLE; dashPtr = dashArr; } else { dashPtr = NULL; } if (lineWidth > 1) { /* Limit the use of geometric pens to thick lines. */ pen = ExtCreatePen(PS_GEOMETRIC | lineAttrs | lineStyle, lineWidth, &lBrush, nValues, dashPtr); } else { /* Cosmetic pens are much faster. */ pen = ExtCreatePen(PS_COSMETIC | lineAttrs | lineStyle, 1, &lBrush, nValues, dashPtr); } } else { /* Windows 95/98. */ if ((lineStyle == PS_SOLID) && (lineWidth > 1)) { /* Use geometric pens with solid, thick lines only. */ pen = ExtCreatePen(PS_GEOMETRIC | lineAttrs | lineStyle, lineWidth, &lBrush, 0, NULL); } else { /* Otherwise sacrifice thick lines for dashes. */ pen = ExtCreatePen(PS_COSMETIC | lineStyle, 1, &lBrush, 0, NULL); } } assert(pen != NULL); return pen; } /* *--------------------------------------------------------------------------- * * XDrawRectangles -- * * Draws the outlines of the specified rectangles as if a * five-point PolyLine protocol request were specified for each * rectangle: * * [x,y] [x+width,y] [x+width,y+height] [x,y+height] * [x,y] * * For the specified rectangles, these functions do not draw a * pixel more than once. XDrawRectangles draws the rectangles in * the order listed in the array. If rectangles intersect, the * intersecting pixels are drawn multiple times. Draws a * rectangle. * * Results: * None. * * Side effects: * Draws rectangles on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawRectangles( Display *display, Drawable drawable, GC gc, XRectangle *rectangles, int nRectangles) { HBRUSH hBrush, oldBrush; HDC hDC; HPEN hPen, oldPen; TkWinDCState state; XRectangle *rp, *rend; if (drawable == None) { return; } hDC = TkWinGetDrawableDC(display, drawable, &state); hPen = Blt_GCToPen(hDC, gc); oldPen = SelectPen(hDC, hPen); hBrush = GetStockObject(NULL_BRUSH); oldBrush = SelectBrush(hDC, hBrush); SetROP2(hDC, tkpWinRopModes[gc->function]); for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { Rectangle(hDC, (int)rp->x, (int)rp->y, (int)(rp->x + rp->width + 1), (int)(rp->y + rp->height + 1)); } SelectPen(hDC, oldPen), DeletePen(hPen); SelectBrush(hDC, oldBrush), DeleteBrush(hBrush); TkWinReleaseDrawableDC(drawable, hDC, &state); } #ifdef notdef /* * Implements the "pixeling" of small arcs, because GDI-performance * for this is awful * was made especially for BLT, graph4 demo now runs 4x faster * */ /* O-outer , I-inner, B-both */ #define NEITHER_ 0 #define OUTLINE 1 #define FILL 2 #define BOTH (OUTLINE|FILL) #define MINIARCS 5 static int arcus0[1] = { BOTH }; static int arcus1[4] = { BOTH, BOTH, BOTH, BOTH }; static int arcus2[9] = { NEITHER, OUTLINE, NEITHER, OUTLINE, FILL, OUTLINE, NEITHER, OUTLINE, NEITHER }; static int arcus3[16] = { NEITHER, OUTLINE, OUTLINE, NEITHER, OUTLINE, FILL, FILL, OUTLINE, OUTLINE, FILL, FILL, OUTLINE, NEITHER, OUTLINE, OUTLINE, NEITHER }; static int arcus4[25] = { NEITHER, OUTLINE, OUTLINE, OUTLINE, NEITHER, OUTLINE, FILL, FILL, FILL, OUTLINE, OUTLINE, FILL, FILL, FILL, OUTLINE, OUTLINE, FILL, FILL, FILL, OUTLINE, NEITHER, OUTLINE, OUTLINE, OUTLINE, NEITHER }; static int *arcis[MINIARCS] = { arcus0, arcus1, arcus2, arcus3, arcus4 }; static void DrawMiniArc( HDC dc, int width, int x, int y, int mask, COLORREF inner, COLORREF outer) { int *arc; int i, j; if (width > MINIARCS) { return; } arc = arcis[width]; for (i = 0; i <= width; i++) { for (j = 0; j <= width; j++) { bit = (mask & *arc); if (bit & OUTLINE) { SetPixelV(dc, x + i, y + j, outer); } else if (bit & FILL) { SetPixelV(dc, x + i, y + j, inner); } arc++; } } } #endif /* *--------------------------------------------------------------------------- * * DrawArc -- * * This procedure handles the rendering of drawn or filled * arcs and chords. * * Results: * None. * * Side effects: * Renders the requested arcs. * *--------------------------------------------------------------------------- */ static void DrawArc( HDC dc, int arcMode, /* Mode: either ArcChord or ArcPieSlice */ XArc *arcPtr, HPEN pen, HBRUSH brush) { int start, extent, clockwise; int xstart, ystart, xend, yend; double radian_start, radian_end, xr, yr; double dx, dy; if ((arcPtr->angle1 == 0) && (arcPtr->angle2 == 23040)) { /* Handle special case of circle or ellipse */ Ellipse(dc, arcPtr->x, arcPtr->y, arcPtr->x + arcPtr->width + 1, arcPtr->y + arcPtr->height + 1); return; } start = arcPtr->angle1, extent = arcPtr->angle2; clockwise = (extent < 0); /* Non-zero if clockwise */ /* * Compute the absolute starting and ending angles in normalized radians. * Swap the start and end if drawing clockwise. */ start = start % (64 * 360); if (start < 0) { start += (64 * 360); } extent = (start + extent) % (64 * 360); if (extent < 0) { extent += (64 * 360); } if (clockwise) { int tmp = start; start = extent; extent = tmp; } #define XAngleToRadians(a) ((double)(a) / 64 * M_PI / 180); radian_start = XAngleToRadians(start); radian_end = XAngleToRadians(extent); /* * Now compute points on the radial lines that define the starting and * ending angles. Be sure to take into account that the y-coordinate * system is inverted. */ dx = arcPtr->width * 0.5; dy = arcPtr->height * 0.5; xr = arcPtr->x + dx; yr = arcPtr->y + dy; xstart = (int)((xr + cos(radian_start) * dx) + 0.5); ystart = (int)((yr + sin(-radian_start) * dy) + 0.5); xend = (int)((xr + cos(radian_end) * dx) + 0.5); yend = (int)((yr + sin(-radian_end) * dy) + 0.5); /* * Now draw a filled or open figure. Note that we have to * increase the size of the bounding box by one to account for the * difference in pixel definitions between X and Windows. */ if (brush == 0) { /* * Note that this call will leave a gap of one pixel at the * end of the arc for thin arcs. We can't use ArcTo because * it's only supported under Windows NT. */ Arc(dc, arcPtr->x, arcPtr->y, arcPtr->x + arcPtr->width + 1, arcPtr->y + arcPtr->height + 1, xstart, ystart, xend, yend); /* FIXME: */ } else { if (arcMode == ArcChord) { Chord(dc, arcPtr->x, arcPtr->y, arcPtr->x + arcPtr->width + 1, arcPtr->y + arcPtr->height + 1, xstart, ystart, xend, yend); } else if (arcMode == ArcPieSlice) { Pie(dc, arcPtr->x, arcPtr->y, arcPtr->x + arcPtr->width + 1, arcPtr->y + arcPtr->height + 1, xstart, ystart, xend, yend); } } } /* *--------------------------------------------------------------------------- * * XDrawArcs -- * * Draws multiple circular or elliptical arcs. Each arc is * specified by a rectangle and two angles. The center of the * circle or ellipse is the center of the rect- angle, and the * major and minor axes are specified by the width and height. * Positive angles indicate counterclock- wise motion, and * negative angles indicate clockwise motion. If the magnitude * of angle2 is greater than 360 degrees, XDrawArcs truncates it * to 360 degrees. * * Results: * None. * * Side effects: * Draws an arc for each array element on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawArcs( Display *display, Drawable drawable, GC gc, XArc *arcArr, int nArcs) { HPEN pen, oldPen; HBRUSH brush, oldBrush; HDC dc; TkWinDCState state; display->request++; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); pen = Blt_GCToPen(dc, gc); oldPen = SelectPen(dc, pen); brush = GetStockBrush(NULL_BRUSH); oldBrush = SelectBrush(dc, brush); { XArc *ap, *aend; for (ap = arcArr, aend = ap + nArcs; ap < aend; ap++) { DrawArc(dc, gc->arc_mode, ap, pen, 0); } } DeleteBrush(SelectBrush(dc, oldBrush)); DeletePen(SelectPen(dc, oldPen)); TkWinReleaseDrawableDC(drawable, dc, &state); } /* *--------------------------------------------------------------------------- * * XFillArcs -- * * Draw a filled arc. * * Results: * None. * * Side effects: * Draws a filled arc for each array element on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXFillArcs( Display *display, Drawable drawable, GC gc, XArc *arcArr, int nArcs) { HBRUSH brush, oldBrush; HPEN pen, oldPen; HDC dc; TkWinDCState state; display->request++; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); pen = Blt_GCToPen(dc, gc); oldPen = SelectPen(dc, pen); brush = CreateSolidBrush(gc->foreground); oldBrush = SelectBrush(dc, brush); { XArc *ap, *aend; for (ap = arcArr, aend = ap + nArcs; ap < aend; ap++) { DrawArc(dc, gc->arc_mode, ap, pen, brush); } } DeleteBrush(SelectBrush(dc, oldBrush)); DeletePen(SelectPen(dc, oldPen)); TkWinReleaseDrawableDC(drawable, dc, &state); } /* *--------------------------------------------------------------------------- * * XDrawLines -- * * Draw connected lines. * * Results: * None. * * Side effects: * Renders a series of connected lines. * *--------------------------------------------------------------------------- */ static void CALLBACK DrawDot( int x, int y, /* Coordinates of point */ LPARAM clientData) { /* Line information */ DashInfo *infoPtr = (DashInfo *) clientData; int count; infoPtr->count++; count = (infoPtr->count + infoPtr->offset) / infoPtr->nBits; if (count & 0x1) { SetPixelV(infoPtr->dc, x, y, infoPtr->color); } } void Blt_EmulateXDrawLine( Display *display, Drawable drawable, GC gc, int x1, int y1, int x2, int y2) { TkWinDCState state; HDC dc; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); if (gc->line_style != LineSolid) { /* Handle dotted lines specially */ DashInfo info; int count; if (!GetDashInfo(dc, gc, &info)) { goto solidLine; } count = info.offset / info.nBits; if (x1 == x2) { /* Vertical line */ int y; for (y = y1; y <= y2; y += 2) { SetPixelV(dc, x1, y + count, info.color); } } else if (y1 == y2) { /* Horizontal line */ int x; for (x = x1; x <= x2; x += 2) { SetPixelV(dc, x + count, y1, info.color); } } else { LineDDA(x1, y1, x2, y2, DrawDot, (LPARAM)&info); } } else { HPEN pen, oldPen; HBRUSH brush, oldBrush; solidLine: pen = Blt_GCToPen(dc, gc); oldPen = SelectPen(dc, pen); brush = CreateSolidBrush(gc->foreground); oldBrush = SelectBrush(dc, brush); MoveToEx(dc, x1, y1, (LPPOINT)NULL); LineTo(dc, x2, y2); DeletePen(SelectPen(dc, oldPen)); DeleteBrush(SelectBrush(dc, oldBrush)); } TkWinReleaseDrawableDC(drawable, dc, &state); } static void DrawLine( Display *display, Drawable drawable, GC gc, POINT *points, int nPoints) { TkWinDCState state; HDC dc; int i, n; int start, extra, size; HPEN pen, oldPen; HBRUSH brush, oldBrush; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); pen = Blt_GCToPen(dc, gc); oldPen = SelectPen(dc, pen); brush = CreateSolidBrush(gc->foreground); oldBrush = SelectBrush(dc, brush); SetROP2(dc, tkpWinRopModes[gc->function]); start = extra = 0; /* * Depending if the line is wide (> 1 pixel), arbitrarily break * the line in sections of 100 points. This bit of weirdness has * to do with wide geometric pens. The longer the polyline, the * slower it draws. The trade off is that we lose dash and * cap uniformity for unbearably slow polyline draws. */ if (gc->line_width > 1) { size = 100; } else { size = nPoints; } for (i = nPoints; i > 0; i -= size) { n = MIN(i, size); Polyline(dc, points + start, n + extra); start += (n - 1); extra = 1; } DeletePen(SelectPen(dc, oldPen)); DeleteBrush(SelectBrush(dc, oldBrush)); TkWinReleaseDrawableDC(drawable, dc, &state); } void Blt_EmulateXDrawLines( Display *display, Drawable drawable, GC gc, XPoint *pointArr, int nPoints, int mode) { if (drawable == None) { return; } if (gc->line_style != LineSolid) { /* Handle dotted lines specially */ DashInfo info; TkWinDCState state; HDC dc; int result; dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); result = GetDashInfo(dc, gc, &info); if (result) { XPoint *p1, *p2; int i; p1 = pointArr; p2 = p1 + 1; for (i = 1; i < nPoints; i++, p1++, p2++) { LineDDA(p1->x, p1->y, p2->x, p2->y, DrawDot, (LPARAM)&info); } result = TCL_OK; } TkWinReleaseDrawableDC(drawable, dc, &state); if (result) { return; } } else { POINT *points; points = Blt_Malloc(sizeof(POINT) * nPoints); if (points == NULL) { return; } if (mode == CoordModeOrigin) { POINT *destPtr; XPoint *sp, *send; destPtr = points; for (sp = pointArr, send = sp + nPoints; sp < send; sp++) { destPtr->x = (int)sp->x; destPtr->y = (int)sp->y; destPtr++; } } else { XPoint *sp, *send; POINT *destPtr, *lastPtr; sp = pointArr; destPtr = points; destPtr->x = (int)sp->x; destPtr->y = (int)sp->y; lastPtr = destPtr; sp++, destPtr++; for (send = pointArr + nPoints; sp < send; sp++) { destPtr->x = lastPtr->x + (int)sp->x; destPtr->y = lastPtr->y + (int)sp->y; lastPtr = destPtr; destPtr++; } } DrawLine(display, drawable, gc, points, nPoints); Blt_Free(points); } } /* *--------------------------------------------------------------------------- * * Blt_EmultateXDrawSegments -- * * Draws multiple, unconnected lines. For each segment, draws a * line between (x1, y1) and (x2, y2). It draws the lines in the * order listed in the array of XSegment structures and does not * perform joining at coincident endpoints. For any given line, * does not draw a pixel more than once. If lines intersect, the * intersecting pixels are drawn multiple times. * * Results: * None. * * Side effects: * Draws unconnected line segments on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawSegments( Display *display, Drawable drawable, GC gc, XSegment *segArr, int nSegments) { HDC dc; TkWinDCState state; display->request++; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); if (gc->line_style != LineSolid) { XSegment *sp, *send; /* Handle dotted lines specially */ DashInfo info; if (!GetDashInfo(dc, gc, &info)) { goto solidLine; } for (sp = segArr, send = sp + nSegments; sp < send; sp++) { info.count = 0; /* Reset dash counter after every segment. */ LineDDA(sp->x1, sp->y1, sp->x2, sp->y2, DrawDot, (LPARAM)&info); } } else { XSegment *sp, *send; HPEN pen, oldPen; solidLine: pen = Blt_GCToPen(dc, gc); oldPen = SelectPen(dc, pen); for (sp = segArr, send = sp + nSegments; sp < send; sp++) { MoveToEx(dc, sp->x1, sp->y1, (LPPOINT)NULL); LineTo(dc, sp->x2, sp->y2); } DeletePen(SelectPen(dc, oldPen)); } TkWinReleaseDrawableDC(drawable, dc, &state); } /* *--------------------------------------------------------------------------- * * Blt_EmultateXDrawRectangle -- * * Draws the outlines of the specified rectangle as if a * five-point PolyLine protocol request were specified for each * rectangle: * * [x,y] [x+width,y] [x+width,y+height] [x,y+height] * [x,y] * * Results: * None. * * Side effects: * Draws a rectangle on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawRectangle( Display *display, Drawable drawable, GC gc, int x, int y, unsigned int width, unsigned int height) { TkWinDCState state; HPEN pen, oldPen; HBRUSH brush, oldBrush; HDC dc; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); pen = Blt_GCToPen(dc, gc); brush = GetStockObject(NULL_BRUSH); oldPen = SelectPen(dc, pen); oldBrush = SelectBrush(dc, brush); SetROP2(dc, tkpWinRopModes[gc->function]); if (gc->line_style != LineSolid) { /* Handle dotted lines specially */ int x2, y2; DashInfo info; if (!GetDashInfo(dc, gc, &info)) { goto solidLine; } x2 = x + width; y2 = y + height; LineDDA(x, y, x2, y, DrawDot, (LPARAM)&info); LineDDA(x2, y, x2, y2, DrawDot, (LPARAM)&info); LineDDA(x2, y2, x, y2, DrawDot, (LPARAM)&info); LineDDA(x, y2, x, y, DrawDot, (LPARAM)&info); } else { solidLine: Rectangle(dc, x, y, x + width + 1, y + height + 1); } DeletePen(SelectPen(dc, oldPen)); DeleteBrush(SelectBrush(dc, oldBrush)); TkWinReleaseDrawableDC(drawable, dc, &state); } /* *--------------------------------------------------------------------------- * * Blt_EmulateXDrawPoints -- * * Uses the foreground pixel and function components of the GC to * draw a multiple points into the specified drawable. * CoordModeOrigin treats all coordinates as relative to the * origin, and CoordModePrevious treats all coordinates after * the first as relative to the previous point. * * Results: * None. * * Side effects: * Draws points on the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawPoints( Display *display, Drawable drawable, GC gc, XPoint *points, int nPoints, int mode) { /* Ignored. CoordModeOrigin is assumed. */ HDC dc; XPoint *pp, *pend; TkWinDCState state; display->request++; if (drawable == None) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); SetROP2(dc, tkpWinRopModes[gc->function]); for (pp = points, pend = pp + nPoints; pp < pend; pp++) { SetPixelV(dc, pp->x, pp->y, gc->foreground); } TkWinReleaseDrawableDC(drawable, dc, &state); } /* *--------------------------------------------------------------------------- * * Blt_EmultateXReparentWindow -- * * If the specified window is mapped, automatically performs an * UnmapWindow request on it, removes it from its current * position in the hierarchy, and inserts it as the child of the * specified parent. The window is placed in the stacking order * on top with respect to sibling windows. * * Note: In WIN32 you can't reparent to/from another application. * * Results: * None. * * Side effects: * Reparents the specified window. * *--------------------------------------------------------------------------- */ void Blt_EmulateXReparentWindow( Display *display, Window window, Window parent, int x, int y) { HWND child, newParent; child = Tk_GetHWND(window); newParent = Tk_GetHWND(parent); SetParent(child, newParent); SetWindowLong(child, GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); XMoveWindow(display, window, x, y); XRaiseWindow(display, window); XMapWindow(display, window); } void Blt_EmulateXSetDashes( Display *display, GC gc, int dashOffset, _Xconst char *dashList, int n) { gc->dashes = (unsigned char)strlen(dashList); gc->dash_offset = (int)dashList; } /* *--------------------------------------------------------------------------- * * Blt_EmultateXDrawString -- * * Draw a single string in the current font. * * Results: * None. * * Side effects: * Renders the specified string in the drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXDrawString( Display *display, Drawable drawable, GC gc, int x, int y, _Xconst char *string, int length) { if (drawable == None) { return; } Tk_DrawChars(display, drawable, gc, (Tk_Font)gc->font, string, length, x, y); } static void TileArea( HDC destDC, HDC srcDC, int tileOriginX, int tileOriginY, int tileWidth, int tileHeight, int x, int y, int width, int height) { int destX, destY; int destWidth, destHeight; int srcX, srcY; int xOrigin, yOrigin; int delta; int left, top, right, bottom; xOrigin = x, yOrigin = y; if (x < tileOriginX) { delta = (tileOriginX - x) % tileWidth; if (delta > 0) { xOrigin -= (tileWidth - delta); } } else if (x > tileOriginX) { delta = (x - tileOriginX) % tileWidth; if (delta > 0) { xOrigin -= delta; } } if (y < tileOriginY) { delta = (tileOriginY - y) % tileHeight; if (delta > 0) { yOrigin -= (tileHeight - delta); } } else if (y >= tileOriginY) { delta = (y - tileOriginY) % tileHeight; if (delta > 0) { yOrigin -= delta; } } #ifdef notdef PurifyPrintf("tile is (%d,%d,%d,%d)\n", tileOriginX, tileOriginY, tileWidth, tileHeight); PurifyPrintf("region is (%d,%d,%d,%d)\n", x, y, width, height); PurifyPrintf("starting at %d,%d\n", xOrigin, yOrigin); #endif left = x; right = x + width; top = y; bottom = y + height; for (y = yOrigin; y < bottom; y += tileHeight) { srcY = 0; destY = y; destHeight = tileHeight; if (y < top) { srcY = (top - y); destHeight = tileHeight - srcY; destY = top; } if ((destY + destHeight) > bottom) { destHeight = (bottom - destY); } for (x = xOrigin; x < right; x += tileWidth) { srcX = 0; destX = x; destWidth = tileWidth; if (x < left) { srcX = (left - x); destWidth = tileWidth - srcX; destX = left; } if ((destX + destWidth) > right) { destWidth = (right - destX); } #ifdef notdef PurifyPrintf("drawing pattern (%d,%d,%d,%d) at %d,%d\n", srcX , srcY, destWidth, destHeight, destX, destY); #endif BitBlt(destDC, destX, destY, destWidth, destHeight, srcDC, srcX, srcY, SRCCOPY); } } } /* *--------------------------------------------------------------------------- * * Blt_EmultateXFillRectangles -- * * Fill multiple rectangular areas in the given drawable. * Handles tiling. * * Results: * None. * * Side effects: * Draws onto the specified drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXFillRectangles( Display *display, Drawable drawable, GC gc, XRectangle *rectangles, int nRectangles) { HBRUSH oldBrush, hFgBrush, hBgBrush, hBrush; HDC hDC; HDC memDC; TkWinDCState state; TkWinDrawable *twdPtr; XRectangle *rp, *rend; if (drawable == None) { return; } hDC = TkWinGetDrawableDC(display, drawable, &state); SetROP2(hDC, tkpWinRopModes[gc->function]); switch(gc->fill_style) { case FillTiled: if (gc->tile == None) { goto fillSolid; } #ifdef notdef if ((GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT) == 0) { goto fillSolid; } #endif twdPtr = (TkWinDrawable *)gc->tile; { HBITMAP oldBitmap; BITMAP bm; GetObject(twdPtr->bitmap.handle, sizeof(BITMAP), &bm); memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { TileArea(hDC, memDC, gc->ts_x_origin, gc->ts_y_origin, bm.bmWidth, bm.bmHeight, (int)rp->x, (int)rp->y, (int)rp->width, (int)rp->height); } SelectBitmap(memDC, oldBitmap); DeleteDC(memDC); } break; case FillOpaqueStippled: case FillStippled: if (gc->stipple == None) { goto fillSolid; } twdPtr = (TkWinDrawable *)gc->stipple; if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } hBrush = CreatePatternBrush(twdPtr->bitmap.handle); SetBrushOrgEx(hDC, gc->ts_x_origin, gc->ts_y_origin, NULL); oldBrush = SelectBrush(hDC, hBrush); memDC = CreateCompatibleDC(hDC); /* * For each rectangle, create a drawing surface which is the size of * the rectangle and fill it with the background color. Then merge the * result with the stipple pattern. */ hFgBrush = CreateSolidBrush(gc->foreground); hBgBrush = CreateSolidBrush(gc->background); for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { RECT rect; HBITMAP oldBitmap, hBitmap; hBitmap = CreateCompatibleBitmap(hDC, rp->width, rp->height); oldBitmap = SelectObject(memDC, hBitmap); rect.left = rect.top = 0; rect.right = rp->width; rect.bottom = rp->height; FillRect(memDC, &rect, hFgBrush); BitBlt(hDC, rp->x, rp->y, rp->width, rp->height, memDC, 0, 0, COPYBG); if (gc->fill_style == FillOpaqueStippled) { FillRect(memDC, &rect, hBgBrush); BitBlt(hDC, rp->x, rp->y, rp->width, rp->height, memDC, 0, 0, COPYFG); } SelectObject(memDC, oldBitmap); DeleteObject(hBitmap); } DeleteBrush(hFgBrush); DeleteBrush(hBgBrush); DeleteDC(memDC); SelectBrush(hDC, oldBrush); DeleteBrush(hBrush); break; case FillSolid: fillSolid: #ifdef notdef memDC = CreateCompatibleDC(hDC); #endif hFgBrush = CreateSolidBrush(gc->foreground); for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { RECT rect; #ifdef notdef HBITMAP oldBitmap, hBitmap; hBitmap = CreateCompatibleBitmap(hDC, rp->width, rp->height); oldBitmap = SelectObject(memDC, hBitmap); #endif /* Note that width and height is already assumed to be * subtracted by one. */ rect.left = rp->x, rect.top = rp->y; rect.right = rp->x + rp->width; rect.bottom = rp->y + rp->height; FillRect(hDC, &rect, hFgBrush); #ifdef notdef BitBlt(hDC, rp->x, rp->y, rp->width, rp->height, memDC, 0, 0, SRCCOPY); SelectObject(memDC, oldBitmap); DeleteObject(hBitmap); #endif } DeleteBrush(hFgBrush); #ifdef notdef DeleteDC(memDC); #endif break; } TkWinReleaseDrawableDC(drawable, hDC, &state); } void Blt_EmulateXFillRectangle( Display *display, Drawable drawable, GC gc, int x, int y, unsigned int width, unsigned int height) { HDC hDC; RECT rect; TkWinDCState state; if (drawable == None) { return; } hDC = TkWinGetDrawableDC(display, drawable, &state); SetROP2(hDC, tkpWinRopModes[gc->function]); rect.left = rect.top = 0; rect.right = width; rect.bottom = height; switch(gc->fill_style) { case FillTiled: { TkWinDrawable *twdPtr; HBITMAP oldBitmap; HDC memDC; BITMAP bm; if (gc->tile == None) { goto fillSolid; } #ifdef notdef if ((GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT) == 0) { goto fillSolid; } #endif twdPtr = (TkWinDrawable *)gc->tile; /* The tiling routine needs to know the size of the bitmap */ GetObject(twdPtr->bitmap.handle, sizeof(BITMAP), &bm); memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); TileArea(hDC, memDC, gc->ts_x_origin, gc->ts_y_origin, bm.bmWidth, bm.bmHeight, x, y, width, height); SelectBitmap(memDC, oldBitmap); DeleteDC(memDC); } break; case FillOpaqueStippled: case FillStippled: { TkWinDrawable *twdPtr; HBRUSH oldBrush, hBrush; HBRUSH hBrushFg, hBrushBg; HBITMAP oldBitmap, hBitmap; HDC memDC; if (gc->stipple == None) { goto fillSolid; } twdPtr = (TkWinDrawable *)gc->stipple; if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } hBrush = CreatePatternBrush(twdPtr->bitmap.handle); SetBrushOrgEx(hDC, gc->ts_x_origin, gc->ts_y_origin, NULL); oldBrush = SelectBrush(hDC, hBrush); memDC = CreateCompatibleDC(hDC); hBrushFg = CreateSolidBrush(gc->foreground); hBrushBg = CreateSolidBrush(gc->background); hBitmap = CreateCompatibleBitmap(hDC, width, height); oldBitmap = SelectObject(memDC, hBitmap); FillRect(memDC, &rect, hBrushFg); SetBkMode(hDC, TRANSPARENT); BitBlt(hDC, x, y, width, height, memDC, 0, 0, COPYFG); if (gc->fill_style == FillOpaqueStippled) { FillRect(memDC, &rect, hBrushBg); BitBlt(hDC, x, y, width, height, memDC, 0, 0, COPYBG); } SelectBrush(hDC, oldBrush); SelectBitmap(memDC, oldBitmap); DeleteBrush(hBrushFg); DeleteBrush(hBrushBg); DeleteBrush(hBrush); DeleteBitmap(hBitmap); DeleteDC(memDC); } break; case FillSolid: { HBRUSH hBrush; HBITMAP oldBitmap, hBitmap; HDC memDC; fillSolid: /* TkWinFillRect(hDC, x, y, width, height, gc->foreground); */ memDC = CreateCompatibleDC(hDC); hBrush = CreateSolidBrush(gc->foreground); hBitmap = CreateCompatibleBitmap(hDC, width, height); oldBitmap = SelectBitmap(memDC, hBitmap); rect.left = rect.top = 0; rect.right = width; rect.bottom = height; FillRect(memDC, &rect, hBrush); BitBlt(hDC, x, y, width, height, memDC, 0, 0, SRCCOPY); SelectObject(memDC, oldBitmap); DeleteBitmap(hBitmap); DeleteBrush(hBrush); DeleteDC(memDC); } break; } TkWinReleaseDrawableDC(drawable, hDC, &state); } #if (_TCL_VERSION >= _VERSION(8,1,0)) static BOOL DrawChars(HDC dc, int x, int y, char *string, int length) { BOOL result; if (systemEncoding == NULL) { result = TextOutA(dc, x, y, string, length); } else { Tcl_DString dString; const unsigned short *wstring; int wlength; Tcl_DStringInit(&dString); Tcl_UtfToExternalDString(systemEncoding, string, length, &dString); wlength = Tcl_DStringLength(&dString) >> 1; wstring = (const unsigned short *)Tcl_DStringValue(&dString); result = TextOutW(dc, x, y, wstring, wlength); Tcl_DStringFree(&dString); } return result; } #else static BOOL DrawChars(HDC dc, int x, int y, char *string, int length) { return TextOutA(dc, x, y, string, length); } #endif /* _TCL_VERSION >= _VERSION(8,1,0) */ #ifdef notef int Blt_DrawTextWithRotatedFont( Tk_Window tkwin, Drawable drawable, int depth, float angle, TextStyle *tsPtr, TextLayout *textPtr, int x, int y, int xMax) { Display *display; HFONT hFont, oldFont; TkWinDCState state; HDC hDC; int isActive; int bbWidth, bbHeight; double rotWidth, rotHeight; double sinTheta, cosTheta; double radians; Point2d p, q, center; TextFragment *fp, *fend; #if (_TCL_VERSION >= _VERSION(8,1,0)) static int initialized = 0; if (!initialized) { if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { /* * If running NT, then we will be calling some Unicode * functions explictly. So, even if the TCL system * encoding isn't Unicode, make sure we convert to/from * the Unicode char set. */ systemEncoding = Tcl_GetEncoding(NULL, "unicode"); } initialized = 1; } #endif display = Tk_Display(tkwin); hFont = CreateRotatedFont(tsPtr->gc->font, angle); if (hFont == NULL) { return FALSE; } Blt_RotateStartingTextPositions(layoutPtr, angle); Blt_GetBoundingBox(layoutPtr->width, layoutPtr->height, angle, &rotWidth, &rotHeight, (Point2d *)NULL); Blt_TranslateAnchor(x, y, ROUND(rotWidth), ROUND(rotHeight), tsPtr->anchor, &x, &y); isActive = (tsPtr->state & STATE_ACTIVE); hDC = TkWinGetDrawableDC(display, drawable, &state); SetROP2(hDC, tsPtr->gc->function); oldFont = SelectFont(hDC, hFont); SetBkMode(hDC, TRANSPARENT); SetTextAlign(hDC, TA_LEFT | TA_BASELINE); if (tsPtr->state & (STATE_DISABLED | STATE_EMPHASIS)) { TkBorder *borderPtr = (TkBorder *) tsPtr->border; XColor *color1, *color2; color1 = borderPtr->lightColor, color2 = borderPtr->darkColor; if (tsPtr->state & STATE_EMPHASIS) { XColor *hold; hold = color1, color1 = color2, color2 = hold; } if (color1 != NULL) { SetTextColor(hDC, color1->pixel); for (fp = textPtr->fragments, fend = fp + textPtr->nFrags; fp < fend; fp++) { DrawChars(hDC, fp->sx, fp->sy, fp->text, fp->count); } } if (color2 != NULL) { SetTextColor(hDC, color2->pixel); for (fp = textPtr->fragments, fend = fp + textPtr->nFrags; fp < fend; fp++) { DrawChars(hDC, fp->sx + 1, fp->sy + 1, fp->text, fp->count); } } goto done; /* Done */ } SetBkMode(hDC, TRANSPARENT); SetTextColor(hDC, tsPtr->color->pixel); for (fp = textPtr->fragments, fend = fp + textPtr->nFrags; fp < fend; fp++) { DrawChars(hDC, fp->sx, fp->sy, fp->text, fp->count); } done: SelectFont(hDC, oldFont); DeleteFont(hFont); TkWinReleaseDrawableDC(drawable, hDC, &state); return TRUE; } #endif static void DrawPixel( HDC hDC, int x, int y, COLORREF color) { HDC memDC; HBRUSH hBrushFg; HBITMAP oldBitmap, hBitmap; RECT rect; int size; size = 1; memDC = CreateCompatibleDC(hDC); hBrushFg = CreateSolidBrush(color); hBitmap = CreateCompatibleBitmap(hDC, size, size); oldBitmap = SelectObject(memDC, hBitmap); rect.left = rect.top = 0; rect.right = rect.bottom = size; FillRect(memDC, &rect, hBrushFg); BitBlt(hDC, x, y, size, size, memDC, 0, 0, SRCCOPY); SelectObject(memDC, oldBitmap); DeleteObject(hBitmap); DeleteBrush(hBrushFg); DeleteDC(memDC); } /* *--------------------------------------------------------------------------- * * PixelateBitmap -- * * Draws a masked bitmap in given device (should be printer) * context. Bit operations on print devices usually fail because * there's no way to read back from the device surface to get the * previous pixel values, rendering BitBlt useless. The bandaid * solution here is to draw 1x1 pixel rectangles at each * coordinate as directed by the the mask and source bitmaps. * * Results: * None. * * Side effects: * Draws onto the specified drawable. * *--------------------------------------------------------------------------- */ static void PixelateBitmap( Display *display, Drawable drawable, Pixmap srcBitmap, Pixmap maskBitmap, int width, int height, GC gc, int destX, int destY) { int x, y; int dx, dy; int pixel; unsigned char *srcBits; unsigned char *srcPtr; int bitPos, bytesPerRow; HDC hDC; TkWinDCState state; srcBits = Blt_GetBitmapData(display, srcBitmap, width, height, &bytesPerRow); if (srcBits == NULL) { return; } hDC = TkWinGetDrawableDC(display, drawable, &state); if (maskBitmap != None) { unsigned char *maskPtr; unsigned char *maskBits; maskBits = Blt_GetBitmapData(display, maskBitmap, width, height, &bytesPerRow); bytesPerRow = ((width + 31) & ~31) / 8; for (dy = destY, y = height - 1; y >= 0; y--, dy++) { maskPtr = maskBits + (bytesPerRow * y); srcPtr = srcBits + (bytesPerRow * y); for (dx = destX, x = 0; x < width; x++, dx++) { bitPos = x % 8; pixel = (*maskPtr & (0x80 >> bitPos)); if (pixel) { pixel = (*srcPtr & (0x80 >> bitPos)); DrawPixel(hDC, dx, dy, (pixel) ? gc->foreground : gc->background); } if (bitPos == 7) { srcPtr++, maskPtr++; } } /* x */ } Blt_Free(maskBits); } else { bytesPerRow = ((width + 31) & ~31) / 8; for (dy = destY, y = height - 1; y >= 0; y--, dy++) { srcPtr = srcBits + (bytesPerRow * y); for (dx = destX, x = 0; x < width; x++, dx++) { bitPos = x % 8; pixel = (*srcPtr & (0x80 >> bitPos)); DrawPixel(hDC, dx, dy, (pixel) ? gc->foreground : gc->background); if (bitPos == 7) { srcPtr++; } } } } TkWinReleaseDrawableDC(drawable, hDC, &state); Blt_Free(srcBits); } /* *--------------------------------------------------------------------------- * * Blt_EmulateXCopyPlane -- * * Simplified version of XCopyPlane. Right now it ignores * function, * clip_x_origin, * clip_y_origin * * The plane argument must always be 1. * * This routine differs from the Tk version in how it handles * transparency. It uses a different method of drawing transparent * bitmaps that doesn't copy the background or use brushes. The * second change is to call a special routine when the destDC is * a printer. Stippling is done by a very slow brute-force * method of drawing 1x1 rectangles for each pixel (bleech). * * Results: * None. * * Side effects: * Changes the destination drawable. * *--------------------------------------------------------------------------- */ void Blt_EmulateXCopyPlane( Display *display, Drawable src, Drawable dest, GC gc, int srcX, int srcY, unsigned int width, unsigned int height, int destX, int destY, unsigned long plane) { HDC srcDC, destDC; TkWinDCState srcState, destState; TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; display->request++; if (plane != 1) { panic("Unexpected plane specified for XCopyPlane"); } srcDC = TkWinGetDrawableDC(display, src, &srcState); if (src != dest) { destDC = TkWinGetDrawableDC(display, dest, &destState); } else { destDC = srcDC; } if ((clipPtr == NULL) || (clipPtr->type == TKP_CLIP_REGION)) { /* * Case 1: opaque bitmaps. Windows handles the conversion * from one bit to multiple bits by setting 0 to the * foreground color, and 1 to the background color (seems * backwards, but there you are). */ if ((clipPtr != NULL) && (clipPtr->type == TKP_CLIP_REGION)) { SelectClipRgn(destDC, (HRGN) clipPtr->value.region); OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); } SetBkMode(destDC, OPAQUE); SetBkColor(destDC, gc->foreground); SetTextColor(destDC, gc->background); BitBlt(destDC, destX, destY, width, height, srcDC, srcX, srcY, SRCCOPY); SelectClipRgn(destDC, NULL); } else if (clipPtr->type == TKP_CLIP_PIXMAP) { Drawable mask; /* * Case 2: transparent bitmaps are handled by setting the * destination to the foreground color whenever the source * pixel is set. */ /* * Case 3: two arbitrary bitmaps. Copy the source rectangle * into a color pixmap. Use the result as a brush when * copying the clip mask into the destination. */ mask = clipPtr->value.pixmap; #if WINDEBUG PurifyPrintf("mask %s src\n", (mask == src) ? "==" : "!="); PurifyPrintf("GetDeviceCaps=%x\n", GetDeviceCaps(destDC, TECHNOLOGY) & TABLE_RASDISPLAY); #endif { HDC maskDC; TkWinDCState maskState; if (mask != src) { maskDC = TkWinGetDrawableDC(display, mask, &maskState); } else { maskDC = srcDC; } SetBkMode(destDC, OPAQUE); SetTextColor(destDC, gc->background); SetBkColor(destDC, gc->foreground); BitBlt(destDC, destX, destY, width, height, srcDC, srcX, srcY, SRCINVERT); /* * Make sure we treat the mask as a monochrome bitmap. * We can get alpha-blending with non-black/white fg/bg * color selections. */ SetTextColor(destDC, RGB(255,255,255)); SetBkColor(destDC, RGB(0,0,0)); /* FIXME: Handle gc->clip_?_origin's */ BitBlt(destDC, destX, destY, width, height, maskDC, 0, 0, SRCAND); SetTextColor(destDC, gc->background); SetBkColor(destDC, gc->foreground); BitBlt(destDC, destX, destY, width, height, srcDC, srcX, srcY, SRCINVERT); if (mask != src) { TkWinReleaseDrawableDC(mask, maskDC, &maskState); } } } if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState); } /* *--------------------------------------------------------------------------- * * Blt_EmulateXCopyArea -- * * Copies data from one drawable to another using block transfer * routines. The small enhancement over the version in Tk is * that it doesn't assume that the source and destination devices * have the same resolution. This isn't true when the destination * device is a printer. * * FIXME: not true anymore. delete this routine. * * Results: * None. * * Side effects: * Data is moved from a window or bitmap to a second window, * bitmap, or printer. * *--------------------------------------------------------------------------- */ void Blt_EmulateXCopyArea( Display *display, Drawable src, Drawable dest, GC gc, int srcX, /* Source X-coordinate */ int srcY, /* Source Y-coordinate. */ unsigned int width, /* Width of area. */ unsigned int height, /* Height of area. */ int destX, /* Destination X-coordinate (in screen * coordinates). */ int destY) /* Destination Y-coordinate (in screen * coordinates). */ { HDC srcDC, destDC; TkWinDCState srcState, destState; TkpClipMask *clipPtr; srcDC = TkWinGetDrawableDC(display, src, &srcState); if (src != dest) { destDC = TkWinGetDrawableDC(display, dest, &destState); } else { destDC = srcDC; } clipPtr = (TkpClipMask *)gc->clip_mask; if ((clipPtr != NULL) && (clipPtr->type == TKP_CLIP_REGION)) { SelectClipRgn(destDC, (HRGN)clipPtr->value.region); OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); } BitBlt(destDC, destX, destY, width, height, srcDC, srcX, srcY, bltModes[gc->function]); SelectClipRgn(destDC, NULL); if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState); } static void StippleArea( Display *display, HDC hDC, /* Device context: For polygons, clip * region will be installed. */ GC gc, int x, int y, int width, int height) { BITMAP bm; HBITMAP oldBitmap; HDC maskDC, memDC; Pixmap mask; TkWinDCState maskState; TkWinDrawable *twdPtr; int dx, dy; int left, top, right, bottom; int startX, startY; /* Starting upper left corner of region. */ twdPtr = (TkWinDrawable *)gc->stipple; GetObject(twdPtr->bitmap.handle, sizeof(BITMAP), &bm); startX = x; if (x < gc->ts_x_origin) { dx = (gc->ts_x_origin - x) % bm.bmWidth; if (dx > 0) { startX -= (bm.bmWidth - dx); } } else if (x > gc->ts_x_origin) { dx = (x - gc->ts_x_origin) % bm.bmWidth; if (dx > 0) { startX -= dx; } } startY = y; if (y < gc->ts_y_origin) { dy = (gc->ts_y_origin - y) % bm.bmHeight; if (dy > 0) { startY -= (bm.bmHeight - dy); } } else if (y >= gc->ts_y_origin) { dy = (y - gc->ts_y_origin) % bm.bmHeight; if (dy > 0) { startY -= dy; } } #ifdef notdef PurifyPrintf("tile is (%d,%d,%d,%d)\n", gc->ts_x_origin, gc->ts_y_origin, bm.bmWidth, bm.bmHeight); PurifyPrintf("region is (%d,%d,%d,%d)\n", x, y, width, height); PurifyPrintf("starting at %d,%d\n", startX, startY); #endif left = x; right = x + width; top = y; bottom = y + height; maskDC = memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); mask = gc->stipple; if (gc->fill_style == FillStippled) { /* With transparency. */ if (gc->clip_mask != None) { TkpClipMask *clipPtr; mask = gc->stipple; clipPtr = (TkpClipMask *)gc->clip_mask; if (clipPtr->type == TKP_CLIP_PIXMAP) { mask = clipPtr->value.pixmap; } } if (mask != gc->stipple) { maskDC = TkWinGetDrawableDC(display, mask, &maskState); } } for (y = startY; y < bottom; y += bm.bmHeight) { int srcX, srcY; int destX, destY, destWidth, destHeight; srcY = 0; destY = y; destHeight = bm.bmHeight; if (y < top) { srcY = (top - y); destHeight = bm.bmHeight - srcY; destY = top; } if ((destY + destHeight) > bottom) { destHeight = (bottom - destY); } for (x = startX; x < right; x += bm.bmWidth) { srcX = 0; destX = x; destWidth = bm.bmWidth; if (x < left) { srcX = (left - x); destWidth = bm.bmWidth - srcX; destX = left; } if ((destX + destWidth) > right) { destWidth = (right - destX); } #ifdef notdef PurifyPrintf("drawing pattern (%d,%d,%d,%d) at %d,%d\n", srcX , srcY, destWidth, destHeight, destX, destY); #endif if (gc->fill_style == FillStippled) { /* With transparency. */ SetBkMode(hDC, OPAQUE); SetTextColor(hDC, gc->background); SetBkColor(hDC, gc->foreground); BitBlt(hDC, destX, destY, destWidth, destHeight, memDC, srcX, srcY, SRCINVERT); SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, RGB(0,0,0)); BitBlt(hDC, destX, destY, destWidth, destHeight, maskDC, srcX, srcY, SRCAND); SetTextColor(hDC, gc->background); SetBkColor(hDC, gc->foreground); BitBlt(hDC, destX, destY, destWidth, destHeight, memDC, srcX, srcY, SRCINVERT); } else if (gc->fill_style == FillOpaqueStippled) { /* Opaque. */ SetBkColor(hDC, gc->foreground); SetTextColor(hDC, gc->background); BitBlt(hDC, destX, destY, destWidth, destHeight, memDC, srcX, srcY, SRCCOPY); } } } SelectBitmap(memDC, oldBitmap); if (maskDC != memDC) { TkWinReleaseDrawableDC(mask, maskDC, &maskState); } DeleteDC(memDC); } /* *--------------------------------------------------------------------------- * * Blt_EmulateXFillPolygon -- * * This differs from Tk's XFillPolygon in that it works around * deficencies in Windows 95/98: * 1. Stippling bitmap is limited to 8x8. * 2. No tiling (with or without mask). * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_EmulateXFillPolygon( Display *display, Drawable drawable, GC gc, XPoint *points, int nPoints, int shape, int mode) { HDC hDC; int left, right, top, bottom; TkWinDCState state; int fillMode; POINT *winPts; if (drawable == None) { return; } /* Allocate array of POINTS to create the polygon's path. */ winPts = Blt_Malloc(sizeof(POINT) * nPoints); if (winPts == NULL) { return; } { POINT *wp; XPoint *p, *pend; /* Determine the bounding box of the polygon. */ left = right = points[0].x; top = bottom = points[0].y; wp = winPts; for (p = points, pend = p + nPoints; p < pend; p++) { if (p->x < left) { left = p->x; } if (p->x > right) { right = p->x; } if (p->y < top) { top = p->y; } if (p->y > bottom) { bottom = p->y; } wp->x = p->x; wp->y = p->y; wp++; } } hDC = TkWinGetDrawableDC(display, drawable, &state); SetROP2(hDC, tkpWinRopModes[gc->function]); fillMode = (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING; if ((gc->fill_style == FillStippled) || (gc->fill_style == FillOpaqueStippled)) { #ifndef notdef POINT *wp, *wend; HRGN hRgn; /* Points are offsets within the bounding box. */ for (wp = winPts, wend = wp + nPoints; wp < wend; wp++) { wp->x -= left; wp->y -= top; } /* Use the polygon as a clip path. */ LPtoDP(hDC, winPts, nPoints); hRgn = CreatePolygonRgn(winPts, nPoints, fillMode); SelectClipRgn(hDC, hRgn); OffsetClipRgn(hDC, left, top); /* Tile the bounding box. */ StippleArea(display, hDC, gc, left, top, right - left + 1, bottom - top + 1); SelectClipRgn(hDC, NULL), DeleteRgn(hRgn); #else TkWinDrawable *twdPtr; HBITMAP hBitmap; HBRUSH hBrush, oldBrush; HPEN hPen, oldPen; HDC hMem; HBITMAP oldBitmap; twdPtr = (TkWinDrawable *)gc->stipple; if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } { BITMAP bm; int bytesPerRow; int y; unsigned char *srcRowPtr; unsigned char *bits; GetObject(twdPtr->bitmap.handle, sizeof(BITMAP), &bm); bits = Blt_GetBitmapData(display, gc->stipple, bm.bmWidth, bm.bmHeight, &bytesPerRow); if (bits == NULL) { panic("help me"); } srcRowPtr = bits; for (y = 0; y < bm.bmHeight; y++) { unsigned char *bp, *bend; for (bp = srcRowPtr, bend = bp + bytesPerRow; bp < bend; bp++) { *bp = ~*bp; } srcRowPtr += bytesPerRow; } bm.bmBits = bits; bm.bmType = 0; bm.bmPlanes = 1; bm.bmBitsPixel = 1; hBitmap = CreateBitmapIndirect(&bm); Blt_Free(bits); } /* hBrush = CreatePatternBrush(twdPtr->bitmap.handle); */ hBrush = CreateHatchBrush(HS_VERTICAL, gc->foreground); SetBrushOrgEx(hDC, gc->ts_x_origin, gc->ts_y_origin, NULL); hPen = GetStockObject(NULL_PEN); SetTextColor(hDC, gc->foreground); SetBkMode(hDC, TRANSPARENT); oldPen = SelectPen(hDC, hPen); oldBrush = SelectBrush(hDC, hBrush); if (gc->fill_style == FillOpaqueStippled) { SetBkColor(hDC, gc->background); } else { SetBkMode(hDC, TRANSPARENT); } SetPolyFillMode(hDC, fillMode); Polygon(hDC, winPts, nPoints); SelectPen(hDC, oldPen), DeletePen(hPen); SelectBrush(hDC, oldBrush), DeleteBrush(hBrush); #endif } else { HPEN hPen, oldPen; HBRUSH hBrush, oldBrush; /* * FIXME: Right now, we're assuming that it's solid or * stippled and ignoring tiling. I'll merge the bits from * Blt_TilePolygon later. */ hPen = GetStockObject(NULL_PEN); oldPen = SelectPen(hDC, hPen); hBrush = CreateSolidBrush(gc->foreground); oldBrush = SelectBrush(hDC, hBrush); SetPolyFillMode(hDC, fillMode); Polygon(hDC, winPts, nPoints); SelectPen(hDC, oldPen), DeletePen(hPen); SelectBrush(hDC, oldBrush), DeleteBrush(hBrush); } Blt_Free(winPts); TkWinReleaseDrawableDC(drawable, hDC, &state); } static void DrawTextOut( HDC hDC, /* HDC to draw into. */ HFONT hFont, /* Contains set of fonts to use when drawing * following string. */ const char *text, /* Potentially multilingual UTF-8 string. */ size_t length, /* Length of string in bytes. */ int x, int y) /* Coordinates at which to place origin * * of string when drawing. */ { HFONT oldFont; Tcl_Encoding encoding; TEXTMETRIC tm; oldFont = SelectFont(hDC, hFont); encoding = Tcl_GetEncoding(NULL, "unicode"); GetTextMetrics(hDC, &tm); x -= tm.tmOverhang /2; if (encoding == NULL) { TextOutA(hDC, x, y, text, length); } else { Tcl_DString ds; const unsigned short *wideText; int wideLength; Tcl_DStringInit(&ds); Tcl_UtfToExternalDString(encoding, text, length, &ds); wideLength = Tcl_DStringLength(&ds) >> 1; wideText = (const unsigned short *)Tcl_DStringValue(&ds); TextOutW(hDC, x, y, wideText, wideLength); Tcl_DStringFree(&ds); } SelectFont(hDC, oldFont); } void Blt_TextOut( HDC hDC, GC gc, /* Graphics context for drawing characters. */ HFONT hFont, /* Font in which characters will be drawn; * must be the same as font used in GC. */ const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int nBytes, /* Number of bytes in string. */ int x, int y) /* Coordinates at which to place origin of * string when drawing. */ { TEXTMETRIC tm; SetROP2(hDC, bltModes[gc->function]); if ((gc->clip_mask != None) && ((TkpClipMask*)gc->clip_mask)->type == TKP_CLIP_REGION) { SelectClipRgn(hDC, (HRGN)((TkpClipMask*)gc->clip_mask)->value.region); } if (((gc->fill_style == FillStippled) || (gc->fill_style == FillOpaqueStippled)) && (gc->stipple != None)) { TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; HBRUSH oldBrush, hBrush; HBITMAP oldBitmap, hBitmap; HDC memDC; TEXTMETRIC tm; SIZE size; if (twdPtr->type != TWD_BITMAP) { Tcl_Panic("unexpected drawable type in stipple"); } /* * Select stipple pattern into destination dc. */ memDC = CreateCompatibleDC(hDC); hBrush = CreatePatternBrush(twdPtr->bitmap.handle); SetBrushOrgEx(hDC, gc->ts_x_origin, gc->ts_y_origin, NULL); oldBrush = SelectBrush(hDC, hBrush); SetTextAlign(memDC, TA_LEFT | TA_BASELINE); SetTextColor(memDC, gc->foreground); SetBkMode(memDC, TRANSPARENT); SetBkColor(memDC, RGB(0, 0, 0)); /* * Compute the bounding box and create a compatible bitmap. */ GetTextExtentPoint(memDC, text, nBytes, &size); GetTextMetrics(memDC, &tm); size.cx -= tm.tmOverhang; hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy); oldBitmap = SelectBitmap(memDC, hBitmap); /* * The following code is tricky because fonts are rendered in multiple * colors. First we draw onto a black background and copy the white * bits. Then we draw onto a white background and copy the black bits. * Both the foreground and background bits of the font are ANDed with * the stipple pattern as they are copied. */ PatBlt(memDC, 0, 0, size.cx, size.cy, BLACKNESS); DrawTextOut(hDC, hFont, text, nBytes, x, y); BitBlt(hDC, x, y-tm.tmAscent, size.cx, size.cy, memDC, 0, 0, 0xEA02E9); PatBlt(memDC, 0, 0, size.cx, size.cy, WHITENESS); DrawTextOut(hDC, hFont, text, nBytes, x, y); BitBlt(hDC, x, y-tm.tmAscent, size.cx, size.cy, memDC, 0, 0, 0x8A0E06); /* * Destroy the temporary bitmap and restore the device context. */ SelectBrush(memDC, oldBitmap); DeleteBitmap(hBitmap); DeleteDC(memDC); SelectBrush(hDC, oldBrush); DeleteBrush(hBrush); } else if (gc->function == GXcopy) { SetTextAlign(hDC, TA_LEFT | TA_BASELINE); SetTextColor(hDC, gc->foreground); SetBkMode(hDC, TRANSPARENT); DrawTextOut(hDC, hFont, text, nBytes, x, y); } else { HBITMAP oldBitmap, hBitmap; HDC memDC; TEXTMETRIC tm; SIZE size; memDC = CreateCompatibleDC(hDC); SetTextAlign(memDC, TA_LEFT | TA_BASELINE); SetTextColor(memDC, gc->foreground); SetBkMode(memDC, TRANSPARENT); SetBkColor(memDC, RGB(0, 0, 0)); /* * Compute the bounding box and create a compatible bitmap. */ GetTextExtentPoint(memDC, text, nBytes, &size); GetTextMetrics(memDC, &tm); size.cx -= tm.tmOverhang; hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy); oldBitmap = SelectObject(memDC, hBitmap); DrawTextOut(memDC, hFont, text, nBytes, 0, tm.tmAscent); BitBlt(hDC, x, y - tm.tmAscent, size.cx, size.cy, memDC, 0, 0, bltModes[gc->function]); SelectBitmap(memDC, oldBitmap); DeleteBitmap(hBitmap); DeleteDC(memDC); } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinBitmap.c����������������������������������������������������������������0000644�0001750�0001750�00000060267�11462120063�015601� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinPainter.c -- * * This module implements Win32-specific image processing procedures for the * BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltBitmap.h" #include "bltPicture.h" #include "bltPictInt.h" #include "bltPainter.h" #include "bltWinPainter.h" #include <X11/Xutil.h> #include "tkDisplay.h" #define GetBit(x, y) \ srcBits[(srcBytesPerRow * (srcHeight - y - 1)) + (x>>3)] & (0x80 >> (x&7)) #define SetBit(x, y) \ destBits[(destBytesPerRow * (destHeight - y - 1)) + (x>>3)] |= (0x80 >>(x&7)) Pixmap Blt_PhotoImageMask( Tk_Window tkwin, Tk_PhotoImageBlock src) { TkWinBitmap *twdPtr; int offset, count; int x, y; unsigned char *srcPtr; int destBytesPerRow; int destHeight; unsigned char *destBits; destBytesPerRow = ((src.width + 31) & ~31) / 8; destBits = Blt_AssertCalloc(src.height, destBytesPerRow); destHeight = src.height; offset = count = 0; /* FIXME: figure out why this is so! */ for (y = src.height - 1; y >= 0; y--) { srcPtr = src.pixelPtr + offset; for (x = 0; x < src.width; x++) { if (srcPtr[src.offset[3]] == 0x00) { SetBit(x, y); count++; } srcPtr += src.pixelSize; } offset += src.pitch; } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = src.width; bm.bmHeight = src.height; bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } Pixmap Blt_PictureMask( Tk_Window tkwin, Blt_Picture pict) { TkWinBitmap *twdPtr; int count; int x, y; Blt_Pixel *sp; int destBytesPerRow; int destWidth, destHeight; unsigned char *destBits; destWidth = Blt_PictureWidth(pict); destHeight = Blt_PictureHeight(pict); destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); count = 0; sp = Blt_PictureBits(pict); for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { if (sp->Alpha == 0x00) { SetBit(x, y); count++; } sp++; } } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = Blt_PictureWidth(pict); bm.bmHeight = Blt_PictureHeight(pict); bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given * bitmap. We also need a special GC of depth 1, so that we do * not need to rotate more than one plane of the bitmap. * * Note that under Windows, monochrome bitmaps are stored * bottom-to-top. This is why the right angle rotations 0/180 * and 90/270 look reversed. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* Right angle rotation to perform */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; double rotWidth, rotHeight; HDC hDC; TkWinDCState state; int x, y; /* Destination bitmap coordinates */ int sx, sy; /* Source bitmap coordinates */ unsigned long pixel; HBITMAP hBitmap; int result; struct MonoBitmap { BITMAPINFOHEADER bi; RGBQUAD colors[2]; } mb; int srcBytesPerRow, destBytesPerRow; int destWidth, destHeight; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = (int)ceil(rotWidth); destHeight = (int)ceil(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; /* Handle right-angle rotations specially. */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { sx = y; for (x = 0; x < destWidth; x++) { sy = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sx = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sy = x; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { pixel = GetBit(x, y); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double srcCX, srcCY; /* Center of source rectangle */ double destCX, destCY; /* Center of destination rectangle */ double tx, ty; double rx, ry; /* Angle of rotation for x and y coordinates */ radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ srcCX = srcWidth * 0.5; srcCY = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* Rotate each pixel of dest image, placing results in source image */ for (y = 0; y < destHeight; y++) { ty = y - destCY; for (x = 0; x < destWidth; x++) { /* Translate origin to center of destination image */ tx = x - destCX; /* Rotate the coordinates about the origin */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image */ rx += srcCX; ry += srcCY; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bi.biSize = sizeof(BITMAPINFOHEADER); mb.bi.biPlanes = 1; mb.bi.biBitCount = 1; mb.bi.biCompression = BI_RGB; mb.bi.biWidth = destWidth; mb.bi.biHeight = destHeight; mb.bi.biSizeImage = destBytesPerRow * destHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, destHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } *destWidthPtr = destWidth; *destHeightPtr = destHeight; return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { TkWinDCState srcState, destState; HDC src, dest; Pixmap destBitmap; Window root; Display *display; /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; } src = TkWinGetDrawableDC(display, srcBitmap, &srcState); dest = TkWinGetDrawableDC(display, destBitmap, &destState); StretchBlt(dest, 0, 0, destWidth, destHeight, src, 0, 0, srcWidth, srcHeight, SRCCOPY); TkWinReleaseDrawableDC(srcBitmap, src, &srcState); TkWinReleaseDrawableDC(destBitmap, dest, &destState); return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleRotateBitmapArea -- * * Creates a scaled and rotated bitmap from a given bitmap. The * caller also provides (offsets and dimensions) the region of * interest in the destination bitmap. This saves having to * process the entire destination bitmap is only part of it is * showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the * destination image. For each pixel, the corresponding * pixel in the source bitmap is used. This means that * destination coordinates are first scaled to the size of * the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapArea( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual * destination bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int virtWidth, unsigned int virtHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Pixmap destBitmap; Window root; /* Root window drawable */ double rWidth, rHeight; double xScale, yScale; int srcBytesPerRow, destBytesPerRow; int destHeight; int result; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((regionWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(regionHeight, destBytesPerRow); destHeight = regionHeight; angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rWidth, &rHeight, (Point2d *)NULL); xScale = rWidth / (double)virtWidth; yScale = rHeight / (double)virtHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(y+regionY)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sy; sy = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sx; sx = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < (int)regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double scx, scy; /* Offset from the center of the * source rectangle. */ double rcx, rcy; /* Offset to the center of the * rotated rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ scx = srcWidth * 0.5; scy = srcHeight * 0.5; rcx = rWidth * 0.5; rcy = rHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < (int)regionHeight; y++) { int x; double ty; /* Translated coordinates from center */ ty = (yScale * (double)(y + regionY)) - rcy; for (x = 0; x < (int)regionWidth; x++) { double rx, ry; /* Angle of rotation for x and y coordinates */ double tx; /* Translated coordinates from center */ int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rcx; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += scx; ry += scy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= (int)srcWidth) || (sx < 0) || (sy >= (int)srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } { HBITMAP hBitmap; HDC hDC; TkWinDCState state; struct MonoBitmap { BITMAPINFOHEADER bmiHeader; RGBQUAD colors[2]; } mb; /* Write the rotated image into the destination bitmap. */ hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mb.bmiHeader.biPlanes = 1; mb.bmiHeader.biBitCount = 1; mb.bmiHeader.biCompression = BI_RGB; mb.bmiHeader.biWidth = regionWidth; mb.bmiHeader.biHeight = regionHeight; mb.bmiHeader.biSizeImage = destBytesPerRow * regionHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, regionHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); } if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } return destBitmap; } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_PaintPictureWithBlend -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ void Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, int width, int height, /* Dimension of the drawable. */ Region2d *regionPtr) /* Area to be snapped. */ { void *data; BITMAPINFO bmi; DIBSECTION ds; HBITMAP hBitmap, oldBitmap; HDC memDC; unsigned char *bits; unsigned char *srcPtr; HDC hDC; TkWinDCState state; Blt_Pixel *destRowPtr; Pict *destPtr; int x, y; if (regionPtr == NULL) { regionPtr = Blt_SetRegion(0, 0, PictureWidth(pict), PictureHeight(pict), &region); } if (regionPtr->left < 0) { regionPtr->left = 0; } if (regionPtr->right >= destWidth) { regionPtr->right = destWidth - 1; } if (regionPtr->top < 0) { regionPtr->top = 0; } if (regionPtr->bottom >= destHeight) { regionPtr->bottom = destHeight - 1; } width = RegionWidth(regionPtr); height = RegionHeight(regionPtr); hDC = TkWinGetDrawableDC(display, drawable, &state); /* Create the intermediate drawing surface at window resolution. */ ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; hBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, &data, NULL, 0); memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, hBitmap); #ifdef notdef if (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE) { TkWinColormap *cmap; cmap = (TkWinColormap *)painterPtr->colormap; SelectPalette(hDC, cmap->palette, FALSE); RealizePalette(hDC); SelectPalette(memDC, cmap->palette, FALSE); RealizePalette(memDC); } #endif pict = NULL; /* Copy the window contents to the memory surface. */ if (!BitBlt(memDC, 0, 0, width, height, hDC, regionPtr->left, regionPtr->top, SRCCOPY)) { #ifdef notdef PurifyPrintf("can't blit: %s\n", Blt_LastError()); #endif goto done; } if (GetObject(hBitmap, sizeof(DIBSECTION), &ds) == 0) { #ifdef notdef PurifyPrintf("can't get object: %s\n", Blt_LastError()); #endif goto done; } bits = (unsigned char *)ds.dsBm.bmBits; destPtr = Blt_CreatePicture(width, height); destRowPtr = destPtr->bits; /* * Copy the DIB RGB data into the picture. The DIB scanlines * are stored bottom-to-top and the order of the RGBA color * components is BGRA. Who says Win32 GDI programming isn't * backwards? */ for (y = height - 1; y >= 0; y--) { unsigned char *sp; Blt_Pixel *dp; sp = bits + (y * ds.dsBm.bmWidthBytes); dp = destRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend, dp++) { if (dp->Alpha > 0) { /* Blend picture with background. */ dp->Blue = *sp++; dp->Green = *sp++; dp->Red = *sp++; dp->Alpha = ALPHA_OPAQUE; sp++; } } destRowPtr += destPtr->pixelsPerRow; } done: DeleteBitmap(SelectBitmap(memDC, oldBitmap)); DeleteDC(memDC); TkWinReleaseDrawableDC(drawable, hDC, &state); return pict; } #endif #ifdef HAVE_IJL_H #include <ijl.h> Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { JPEG_CORE_PROPERTIES jpgProps; Blt_Picture pict; ZeroMemory(&jpgProps, sizeof(JPEG_CORE_PROPERTIES)); if(ijlInit(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't initialize Intel JPEG library", (char *)NULL); return NULL; } jpgProps.JPGFile = fileName; if (ijlRead(&jpgProps, IJL_JFILE_READPARAMS) != IJL_OK) { Tcl_AppendResult(interp, "can't read JPEG file header from \"", fileName, "\" file.", (char *)NULL); goto error; } // !dudnik: to fix bug case 584680, [OT:287A305B] // Set the JPG color space ... this will always be // somewhat of an educated guess at best because JPEG // is "color blind" (i.e., nothing in the bit stream // tells you what color space the data was encoded from). // However, in this example we assume that we are // reading JFIF files which means that 3 channel images // are in the YCbCr color space and 1 channel images are // in the Y color space. switch(jpgProps.JPGChannels) { case 1: jpgProps.JPGColor = IJL_G; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 3: jpgProps.JPGColor = IJL_YCBCR; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 4: jpgProps.JPGColor = IJL_YCBCRA_FPX; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; default: /* This catches everything else, but no color twist will be performed by the IJL. */ jpgProps.DIBColor = (IJL_COLOR)IJL_OTHER; jpgProps.JPGColor = (IJL_COLOR)IJL_OTHER; jpgProps.DIBChannels = jpgProps.JPGChannels; break; } jpgProps.DIBWidth = jpgProps.JPGWidth; jpgProps.DIBHeight = jpgProps.JPGHeight; jpgProps.DIBPadBytes = IJL_DIB_PAD_BYTES(jpgProps.DIBWidth, jpgProps.DIBChannels); pict = Blt_CreatePicture(jpgProps.JPGWidth, jpgProps.JPGHeight); jpgProps.DIBBytes = (BYTE *)Blt_PictureBits(pict); if (ijlRead(&jpgProps, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { Tcl_AppendResult(interp, "can't read image data from \"", fileName, "\"", (char *)NULL); goto error; } if (ijlFree(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't free Intel(R) JPEG library.", (char *)NULL); } return pict; error: ijlFree(&jpgProps); if (pict != NULL) { Blt_FreePicture(pict); } ijlFree(&jpgProps); return NULL; } #endif /* HAVE_IJL_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltConfig.h�������������������������������������������������������������������0000644�0001750�0001750�00000031052�11462120062�015106� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltConfig.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BLT_CONFIG_H #define BLT_CONFIG_H #ifdef HAVE_STDDEF_H # include <stddef.h> #endif /* HAVE_STDDEF_H */ #ifndef Blt_Offset #ifdef offsetof #define Blt_Offset(type, field) ((int) offsetof(type, field)) #else #define Blt_Offset(type, field) ((int) ((char *) &((type *) 0)->field)) #endif #endif /* Blt_Offset */ typedef int (Blt_OptionParseProc)(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, int offset, int flags); typedef Tcl_Obj *(Blt_OptionPrintProc)(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, char *widgRec, int offset, int flags); typedef void (Blt_OptionFreeProc)(ClientData clientData, Display *display, char *widgRec, int offset); typedef struct Blt_CustomOption { Blt_OptionParseProc *parseProc; /* Procedure to call to parse * an option and store it in * converted form. */ Blt_OptionPrintProc *printProc; /* Procedure to return a * Tcl_Obj representing an * existing option value. */ Blt_OptionFreeProc *freeProc; /* Procedure used to free the * value. */ ClientData clientData; /* Arbitrary one-word value * used by option parser: * passed to parseProc and * printProc. */ } Blt_CustomOption; /* * Structure used to specify information for Tk_ConfigureWidget. Each * structure gives complete information for one option, including * how the option is specified on the command line, where it appears * in the option database, etc. */ typedef struct { int type; /* Type of option, such as * BLT_CONFIG_COLOR; see definitions * below. Last option in table must * have type BLT_CONFIG_END. */ const char *switchName; /* Switch used to specify option in * argv. NULL means this spec is part * of a group. */ Tk_Uid dbName; /* Name for option in option * database. */ Tk_Uid dbClass; /* Class for option in database. */ Tk_Uid defValue; /* Default value for option if not * specified in command line or * database. */ int offset; /* Where in widget record to store * value; use Blt_Offset macro to * generate values for this. */ int specFlags; /* Any combination of the values * defined below; other bits are used * internally by tkConfig.c. */ Blt_CustomOption *customPtr; /* If type is BLT_CONFIG_CUSTOM then * this is a pointer to info about how * to parse and print the option. * Otherwise it is irrelevant. */ } Blt_ConfigSpec; /* * Type values for Blt_ConfigSpec structures. See the user * documentation for details. */ typedef enum { BLT_CONFIG_ACTIVE_CURSOR, BLT_CONFIG_ANCHOR, BLT_CONFIG_BITMAP, BLT_CONFIG_BOOLEAN, BLT_CONFIG_BORDER, BLT_CONFIG_CAP_STYLE, BLT_CONFIG_COLOR, BLT_CONFIG_CURSOR, BLT_CONFIG_CUSTOM, BLT_CONFIG_DOUBLE, BLT_CONFIG_FONT, BLT_CONFIG_INT, BLT_CONFIG_JOIN_STYLE, BLT_CONFIG_JUSTIFY, BLT_CONFIG_MM, BLT_CONFIG_RELIEF, BLT_CONFIG_STRING, BLT_CONFIG_SYNONYM, BLT_CONFIG_UID, BLT_CONFIG_WINDOW, BLT_CONFIG_BITMASK, BLT_CONFIG_BITMASK_INVERT, BLT_CONFIG_DASHES, BLT_CONFIG_FILL, BLT_CONFIG_FLOAT, BLT_CONFIG_INT_NNEG, /* 0..N */ BLT_CONFIG_INT_POS, /* 1..N */ BLT_CONFIG_LIST, BLT_CONFIG_LONG, BLT_CONFIG_LONG_NNEG, /* 0..N */ BLT_CONFIG_LONG_POS, /* 1..N */ BLT_CONFIG_OBJ, BLT_CONFIG_PAD, BLT_CONFIG_PIXELS_NNEG, /* 1.1c 2m 3.2i excluding negative values. */ BLT_CONFIG_PIXELS_POS, /* 1.1c 2m 3.2i excluding negative * values and zero. */ BLT_CONFIG_PIXELS, /* 1.1c 2m 3.2i. */ BLT_CONFIG_RESIZE, BLT_CONFIG_SIDE, BLT_CONFIG_STATE, BLT_CONFIG_BACKGROUND, BLT_CONFIG_PIX32, BLT_CONFIG_TK_FONT, BLT_CONFIG_END } Blt_ConfigTypes; /* * Possible values for flags argument to Tk_ConfigureWidget: */ #define BLT_CONFIG_OBJV_ONLY 1 /* * Possible flag values for Blt_ConfigSpec structures. Any bits at or * above BLT_CONFIG_USER_BIT may be used by clients for selecting * certain entries. Before changing any values here, coordinate with * tkOldConfig.c (internal-use-only flags are defined there). */ /* * Values for "flags" field of Blt_ConfigSpec structures. Be sure to * coordinate these values with those defined in tk.h * (BLT_CONFIG_COLOR_ONLY, etc.). There must not be overlap! * * INIT - Non-zero means (char *) things have been * converted to Tk_Uid's. */ #define INIT (1<<0) #define BLT_CONFIG_NULL_OK (1<<1) #define BLT_CONFIG_COLOR_ONLY (1<<2) #define BLT_CONFIG_MONO_ONLY (1<<3) #define BLT_CONFIG_DONT_SET_DEFAULT (1<<4) #define BLT_CONFIG_OPTION_SPECIFIED (1<<5) #define BLT_CONFIG_USER_BIT (1<<8) #define SIDE_LEFT (1<<0) #define SIDE_TOP (1<<1) #define SIDE_RIGHT (1<<2) #define SIDE_BOTTOM (1<<3) #define STATE_NORMAL (0) #define STATE_ACTIVE (1<<0) #define STATE_DISABLED (1<<1) #define STATE_EMPHASIS (1<<2) /* *--------------------------------------------------------------------------- * * Blt_Pad -- * * Specifies vertical and horizontal padding. * * Padding can be specified on a per side basis. The fields * side1 and side2 refer to the opposite sides, either * horizontally or vertically. * * side1 side2 * ----- ----- * x | left right * y | top bottom * *--------------------------------------------------------------------------- */ typedef struct { unsigned short int side1, side2; } Blt_Pad; #define padLeft xPad.side1 #define padRight xPad.side2 #define padTop yPad.side1 #define padBottom yPad.side2 #define PADDING(x) ((x).side1 + (x).side2) /* *--------------------------------------------------------------------------- * * The following enumerated values are used as bit flags. * FILL_NONE Neither coordinate plane is specified * FILL_X Horizontal plane. * FILL_Y Vertical plane. * FILL_BOTH Both vertical and horizontal planes. * *--------------------------------------------------------------------------- */ #define FILL_NONE 0 #define FILL_X 1 #define FILL_Y 2 #define FILL_BOTH 3 /* * Resize -- * * These flags indicate in what ways each partition in a table can be * resized from its default dimensions. The normal size of a row/column * is the minimum amount of space needed to hold the widgets that span * it. The table may then be stretched or shrunk depending if the * container is larger or smaller than the table. This can occur if 1) * the user resizes the toplevel widget, or 2) the container is in turn * packed into a larger widget and the "fill" option is set. * * RESIZE_NONE - No resizing from normal size. * RESIZE_EXPAND - Do not allow the size to decrease. * The size may increase however. * RESIZE_SHRINK - Do not allow the size to increase. * The size may decrease however. * RESIZE_BOTH - Allow the size to increase or * decrease from the normal size. * RESIZE_VIRGIN - Special case of the resize flag. Used to * indicate the initial state of the flag. * Empty rows/columns are treated differently * if this row/column is set. */ #define RESIZE_NONE 0 #define RESIZE_EXPAND (1<<0) #define RESIZE_SHRINK (1<<1) #define RESIZE_BOTH (RESIZE_EXPAND | RESIZE_SHRINK) /* *--------------------------------------------------------------------------- * * Blt_Dashes -- * * List of dash values (maximum 11 based upon PostScript limit). * *--------------------------------------------------------------------------- */ typedef struct { unsigned char values[12]; int offset; } Blt_Dashes; #define LineIsDashed(d) ((d).values[0] != 0) /* * Blt_Limits -- * * Defines the bounding of a size (width or height) in the paneset. It may * be related to the widget, pane or paneset size. */ typedef struct { int flags; /* Flags indicate whether using default * values for limits or not. See flags * below. */ int max, min; /* Values for respective limits. */ int nom; /* Nominal starting value. */ } Blt_Limits; #define LIMITS_MIN_SET (1<<0) #define LIMITS_MAX_SET (1<<1) #define LIMITS_NOM_SET (1<<2) #define LIMITS_MIN 0 /* Default minimum limit */ #define LIMITS_MAX SHRT_MAX /* Default maximum limit */ #define LIMITS_NOM -1000 /* Default nomimal value. Indicates * if a pane has received any space * yet */ BLT_EXTERN void Blt_SetDashes (Display *display, GC gc, Blt_Dashes *dashesPtr); BLT_EXTERN Blt_Dashes *Blt_GetDashes (GC gc); BLT_EXTERN void Blt_ResetLimits(Blt_Limits *limitsPtr); BLT_EXTERN int Blt_GetLimitsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Blt_Limits *limitsPtr); BLT_EXTERN int Blt_ConfigureInfoFromObj(Tcl_Interp *interp, Tk_Window tkwin, Blt_ConfigSpec *specs, char *widgRec, Tcl_Obj *objPtr, int flags); BLT_EXTERN int Blt_ConfigureValueFromObj(Tcl_Interp *interp, Tk_Window tkwin, Blt_ConfigSpec *specs, char *widgRec, Tcl_Obj *objPtr, int flags); BLT_EXTERN int Blt_ConfigureWidgetFromObj(Tcl_Interp *interp, Tk_Window tkwin, Blt_ConfigSpec *specs, int objc, Tcl_Obj *const *objv, char *widgRec, int flags); BLT_EXTERN int Blt_ConfigureComponentFromObj(Tcl_Interp *interp, Tk_Window tkwin, const char *name, const char *className, Blt_ConfigSpec *specs, int objc, Tcl_Obj *const *objv, char *widgRec, int flags); BLT_EXTERN int Blt_ConfigModified TCL_VARARGS(Blt_ConfigSpec *, specs); BLT_EXTERN const char *Blt_NameOfState(int state); BLT_EXTERN const char *Blt_NameOfSide(int side); BLT_EXTERN void Blt_FreeOptions(Blt_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); BLT_EXTERN int Blt_ObjIsOption(Blt_ConfigSpec *specs, Tcl_Obj *objPtr, int flags); BLT_EXTERN int Blt_GetSideFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *sidePtr); BLT_EXTERN int Blt_GetPositionFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *indexPtr); BLT_EXTERN int Blt_GetPixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int flags, int *valuePtr); BLT_EXTERN int Blt_GetPadFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Blt_Pad *padPtr); BLT_EXTERN int Blt_GetStateFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr); BLT_EXTERN int Blt_GetFillFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *fillPtr); BLT_EXTERN int Blt_GetResizeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *fillPtr); BLT_EXTERN int Blt_GetDashesFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Dashes *dashesPtr); #if (_TK_VERSION < _VERSION(8,1,0)) BLT_EXTERN int Tk_GetAnchorFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); BLT_EXTERN int Tk_GetJustifyFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); BLT_EXTERN int Tk_GetReliefFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *reliefPtr); BLT_EXTERN int Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); BLT_EXTERN int Tk_GetPixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); BLT_EXTERN Tk_3DBorder Tk_Alloc3DBorderFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN Pixmap Tk_AllocBitmapFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN Tk_Font Tk_AllocFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN Tk_Cursor Tk_AllocCursorFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN XColor *Tk_AllocColorFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); #endif /* < 8.1 */ #endif /* BLT_CONFIG_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltSwitch.c�������������������������������������������������������������������0000644�0001750�0001750�00000033741�11462120062�015144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltSwitch.c -- * * This module implements command/argument switch parsing procedures for the * BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <stdarg.h> #include "bltSwitch.h" static void DoHelp(Tcl_Interp *interp, Blt_SwitchSpec *specs) { Tcl_DString ds; Blt_SwitchSpec *sp; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "following switches are available:", -1); for (sp = specs; sp->type != BLT_SWITCH_END; sp++) { Tcl_DStringAppend(&ds, "\n ", 4); Tcl_DStringAppend(&ds, sp->switchName, -1); Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, sp->help, -1); } Tcl_AppendResult(interp, Tcl_DStringValue(&ds), (char *)NULL); Tcl_DStringFree(&ds); } /* *--------------------------------------------------------------------------- * * FindSwitchSpec -- * * Search through a table of configuration specs, looking for one that * matches a given argvName. * * Results: * The return value is a pointer to the matching entry, or NULL if * nothing matched. In that case an error message is left in the * interp's result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_SwitchSpec * FindSwitchSpec( Tcl_Interp *interp, /* Used for reporting errors. */ Blt_SwitchSpec *specs, /* Pointer to table of configuration * specifications for a widget. */ const char *name, /* Name identifying a particular switch. */ int length, /* Length of name. */ int needFlags, /* Flags that must be present in matching * entry. */ int hateFlags) /* Flags that must NOT be present in matching * entry. */ { Blt_SwitchSpec *sp; char c; /* First character of current argument. */ Blt_SwitchSpec *matchPtr; /* Matching spec, or NULL. */ c = name[1]; matchPtr = NULL; for (sp = specs; sp->type != BLT_SWITCH_END; sp++) { if (sp->switchName == NULL) { continue; } if (((sp->flags & needFlags) != needFlags) || (sp->flags & hateFlags)) { continue; } if ((sp->switchName[1] != c) || (strncmp(sp->switchName, name, length) != 0)) { continue; } if (sp->switchName[length] == '\0') { return sp; /* Stop on a perfect match. */ } if (matchPtr != NULL) { Tcl_AppendResult(interp, "ambiguous switch \"", name, "\"\n", (char *) NULL); DoHelp(interp, specs); return NULL; } matchPtr = sp; } if (strcmp(name, "-help") == 0) { DoHelp(interp, specs); return NULL; } if (matchPtr == NULL) { Tcl_AppendResult(interp, "unknown switch \"", name, "\"\n", (char *)NULL); DoHelp(interp, specs); return NULL; } return matchPtr; } /* *--------------------------------------------------------------------------- * * DoSwitch -- * * This procedure applies a single configuration switch to a widget * record. * * Results: * A standard TCL return value. * * Side effects: * WidgRec is modified as indicated by specPtr and value. The old value * is recycled, if that is appropriate for the value type. * *--------------------------------------------------------------------------- */ static int DoSwitch( Tcl_Interp *interp, /* Interpreter for error reporting. */ Blt_SwitchSpec *sp, /* Specifier to apply. */ Tcl_Obj *objPtr, /* Value to use to fill in widgRec. */ void *record) /* Record whose fields are to be modified. * Values must be properly initialized. */ { do { char *ptr; ptr = (char *)record + sp->offset; switch (sp->type) { case BLT_SWITCH_BOOLEAN: { int bool; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } if (sp->mask > 0) { if (bool) { *((int *)ptr) |= sp->mask; } else { *((int *)ptr) &= ~sp->mask; } } else { *((int *)ptr) = bool; } } break; case BLT_SWITCH_DOUBLE: if (Tcl_GetDoubleFromObj(interp, objPtr, (double *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_SWITCH_OBJ: Tcl_IncrRefCount(objPtr); *(Tcl_Obj **)ptr = objPtr; break; case BLT_SWITCH_FLOAT: { double value; if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(float *)ptr = (float)value; } break; case BLT_SWITCH_INT: if (Tcl_GetIntFromObj(interp, objPtr, (int *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_SWITCH_INT_NNEG: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = (int)value; } break; case BLT_SWITCH_INT_POS: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = (int)value; } break; case BLT_SWITCH_LIST: { int argc; if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, (const char ***)ptr) != TCL_OK) { return TCL_ERROR; } } break; case BLT_SWITCH_LONG: if (Tcl_GetLongFromObj(interp, objPtr, (long *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_SWITCH_LONG_NNEG: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, &value) != TCL_OK) { return TCL_ERROR; } *(long *)ptr = value; } break; case BLT_SWITCH_LONG_POS: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) != TCL_OK) { return TCL_ERROR; } *(long *)ptr = value; } break; case BLT_SWITCH_STRING: { char *value; value = Tcl_GetString(objPtr); value = (*value == '\0') ? NULL : Blt_AssertStrdup(value); if (*(char **)ptr != NULL) { Blt_Free(*(char **)ptr); } *(char **)ptr = value; } #ifdef notdef { char *old, *new, **strPtr; char *string; string = Tcl_GetString(objPtr); strPtr = (char **)ptr; new = ((*string == '\0') && (sp->flags & BLT_SWITCH_NULL_OK)) ? NULL : Blt_AssertStrdup(string); old = *strPtr; if (old != NULL) { Blt_Free(old); } *strPtr = new; } #endif break; case BLT_SWITCH_CUSTOM: assert(sp->customPtr != NULL); if ((*sp->customPtr->parseProc)(sp->customPtr->clientData, interp, sp->switchName, objPtr, (char *)record, sp->offset, sp->flags) != TCL_OK) { return TCL_ERROR; } break; default: Tcl_AppendResult(interp, "bad switch table: unknown type \"", Blt_Itoa(sp->type), "\"", (char *)NULL); return TCL_ERROR; } sp++; } while ((sp->switchName == NULL) && (sp->type != BLT_SWITCH_END)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ParseSwitches -- * * Process command-line switches to fill in fields of a record with * resources and other parameters. * * Results: * Returns the number of arguments comsumed by parsing the command line. * If an error occurred, -1 will be returned and an error messages can be * found as the interpreter result. * * Side effects: * The fields of widgRec get filled in with information from argc/argv. * Old information in widgRec's fields gets recycled. * *--------------------------------------------------------------------------- */ int Blt_ParseSwitches( Tcl_Interp *interp, /* Interpreter for error reporting. */ Blt_SwitchSpec *specs, /* Describes legal switches. */ int objc, /* Number of elements in argv. */ Tcl_Obj *const *objv, /* Command-line switches. */ void *record, /* Record whose fields are to be modified. * Values must be properly initialized. */ int flags) /* Used to specify additional flags that must * be present in switch specs for them to be * considered. */ { Blt_SwitchSpec *sp; int count; int needFlags; /* Specs must contain this set of flags or * else they are not considered. */ int hateFlags; /* If a spec contains any bits here, it's not * considered. */ needFlags = flags & ~(BLT_SWITCH_USER_BIT - 1); hateFlags = 0; /* * Pass 1: Clear the change flags on all the specs so that we * can check it later. */ for (sp = specs; sp->type != BLT_SWITCH_END; sp++) { sp->flags &= ~BLT_SWITCH_SPECIFIED; } /* * Pass 2: Process the arguments that match entries in the specs. * It's an error if the argument doesn't match anything. */ for (count = 0; count < objc; count++) { char *arg; int length; arg = Tcl_GetStringFromObj(objv[count], &length); if (flags & BLT_SWITCH_OBJV_PARTIAL) { /* * If the argument doesn't start with a '-' (not a switch) or is * '--', stop processing and return the number of arguments * comsumed. */ if (arg[0] != '-') { return count; } if ((arg[1] == '-') && (arg[2] == '\0')) { return count + 1; /* include the "--" in the count. */ } } sp = FindSwitchSpec(interp, specs, arg, length, needFlags, hateFlags); if (sp == NULL) { return -1; } if (sp->type == BLT_SWITCH_BITMASK) { char *ptr; ptr = (char *)record + sp->offset; *((int *)ptr) |= sp->mask; } else if (sp->type == BLT_SWITCH_BITMASK_INVERT) { char *ptr; ptr = (char *)record + sp->offset; *((int *)ptr) &= ~sp->mask; } else if (sp->type == BLT_SWITCH_VALUE) { char *ptr; ptr = (char *)record + sp->offset; *((int *)ptr) = sp->mask; } else { count++; if (count == objc) { Tcl_AppendResult(interp, "value for \"", arg, "\" missing", (char *) NULL); return -1; } if (DoSwitch(interp, sp, objv[count], record) != TCL_OK) { char msg[200]; sprintf_s(msg, 200, "\n (processing \"%.40s\" switch)", sp->switchName); Tcl_AddErrorInfo(interp, msg); return -1; } } sp->flags |= BLT_SWITCH_SPECIFIED; } return count; } /* *--------------------------------------------------------------------------- * * Blt_FreeSwitches -- * * Free up all resources associated with switches. * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ void Blt_FreeSwitches( Blt_SwitchSpec *specs, /* Describes legal switches. */ void *record, /* Record whose fields contain current values * for switches. */ int needFlags) /* Used to specify additional flags that must * be present in config specs for them to be * considered. */ { Blt_SwitchSpec *sp; for (sp = specs; sp->type != BLT_SWITCH_END; sp++) { if ((sp->flags & needFlags) == needFlags) { char *ptr; ptr = (char *)record + sp->offset; switch (sp->type) { case BLT_SWITCH_STRING: case BLT_SWITCH_LIST: if (*((char **) ptr) != NULL) { Blt_Free(*((char **) ptr)); *((char **) ptr) = NULL; } break; case BLT_SWITCH_OBJ: if (*((Tcl_Obj **) ptr) != NULL) { Tcl_DecrRefCount(*((Tcl_Obj **)ptr)); *((Tcl_Obj **) ptr) = NULL; } break; case BLT_SWITCH_CUSTOM: assert(sp->customPtr != NULL); if ((*(char **)ptr != NULL) && (sp->customPtr->freeProc != NULL)) { (*sp->customPtr->freeProc)((char *)record, sp->offset, sp->flags); } break; default: break; } } } } /* *--------------------------------------------------------------------------- * * Blt_SwitchModified -- * * Given the configuration specifications and one or more switch patterns * (terminated by a NULL), indicate if any of the matching switches has * been reset. * * Results: * Returns 1 if one of the switches have changed, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_SwitchChanged TCL_VARARGS_DEF(Blt_SwitchSpec *, arg1) { va_list argList; Blt_SwitchSpec *specs; Blt_SwitchSpec *sp; char *switchName; specs = TCL_VARARGS_START(Blt_SwitchSpec *, arg1, argList); while ((switchName = va_arg(argList, char *)) != NULL) { for (sp = specs; sp->type != BLT_SWITCH_END; sp++) { if ((Tcl_StringMatch(sp->switchName, switchName)) && (sp->flags & BLT_SWITCH_SPECIFIED)) { va_end(argList); return 1; } } } va_end(argList); return 0; } int Blt_ExprDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr) { /* First try to extract the value as a double precision number. */ if (Tcl_GetDoubleFromObj((Tcl_Interp *)NULL, objPtr, valuePtr) == TCL_OK) { return TCL_OK; } /* Then try to parse it as an expression. */ if (Tcl_ExprDouble(interp, Tcl_GetString(objPtr), valuePtr) == TCL_OK) { return TCL_OK; } return TCL_ERROR; } int Blt_ExprIntFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, int *valuePtr) { long lvalue; /* First try to extract the value as a simple integer. */ if (Tcl_GetIntFromObj((Tcl_Interp *)NULL, objPtr, valuePtr) == TCL_OK) { return TCL_OK; } /* Otherwise try to parse it as an expression. */ if (Tcl_ExprLong(interp, Tcl_GetString(objPtr), &lvalue) == TCL_OK) { *valuePtr = lvalue; return TCL_OK; } return TCL_ERROR; } �������������������������������./saods9/blt3.0.1/src/bltPictXbm.c������������������������������������������������������������������0000644�0001750�0001750�00000046304�11462120062�015250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictXbm.c -- * * This module implements XBM file format conversion routines for * the picture image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #include <tcl.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include "bltPicture.h" #include "bltPictFmts.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #define UCHAR(c) ((unsigned char) (c)) #define ISASCII(c) (UCHAR(c)<=0177) DLLEXPORT extern Tcl_AppInitProc Blt_PictureXbmInit; extern char *Blt_Itoa(int); extern char *Blt_InitHexTable(unsigned char *); #define TRUE 1 #define FALSE 0 typedef struct _Blt_Picture Picture; #include <ctype.h> typedef struct { int hotX, hotY; int width, height; int version; } Xbm; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; Blt_Pixel bg, fg; /* Colors for XBM image format. */ } XbmImportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; Blt_Pixel bg; int index; } XbmExportSwitches; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(XbmImportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(XbmImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-fg", "color", Blt_Offset(XbmImportSwitches, fg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(XbmImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(XbmExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(XbmExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(XbmExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(XbmExportSwitches, index), 0}, {BLT_SWITCH_END} }; /* * Parse the lines that define the dimensions of the bitmap, * plus the first line that defines the bitmap data (it declares * the name of a data variable but doesn't include any actual * data). These lines look something like the following: * * #define foo_width 16 * #define foo_height 16 * #define foo_x_hot 3 * #define foo_y_hot 3 * static char foo_bits[] = { * * The x_hot and y_hot lines may or may not be present. It's * important to check for "char" in the last line, in order to * reject old X10-style bitmaps that used shorts. */ static int XbmHeader(Blt_DBuffer data, Xbm *xbmPtr) { unsigned char *line, *next; xbmPtr->width = xbmPtr->height = 0; xbmPtr->hotX = xbmPtr->hotY = -1; xbmPtr->version = 11; Blt_DBuffer_ResetCursor(data); for (line = Blt_DBuffer_Pointer(data); *line != '\0'; line = next) { #define XBM_MAX_LINE 1023 char substring[XBM_MAX_LINE+1]; char *s; int value; /* Find the start of the next line */ if ((*line == '\n') || (*line == '\r')) { line++; } next = line; while ((*next != '\r') && (*next != '\n') && (*next != '\0')) { if (*next & !ISASCII(*next)) { return FALSE; } next++; } /* Verify that we won't overrun the buffer with "sscanf". */ if ((next - line) > XBM_MAX_LINE) { return FALSE; } s = (char *)line; if (sscanf(s, "#define %s %d", substring, &value) == 2) { char *name; char c; char *p; p = strrchr(substring, '_'); if (p == NULL) { name = substring; } else { name = p + 1; } c = name[0]; if ((c == 'w') && (strcmp("width", name) == 0)) { xbmPtr->width = value; } else if ((c == 'h') && (strcmp("height", name) == 0)){ xbmPtr->height = value; } else if ((c == 'h') && (strcmp("hot", name) == 0)) { name -= 2; if (name > substring) { if (name[1] == '_') { if (name[0] == 'x') { xbmPtr->hotX = value; } else if (name[0] == 'y') { xbmPtr->hotY = value; } } } } continue; } else if (sscanf(s, "static short %s = {", substring) == 1) { xbmPtr->version = 10; } else if (sscanf(s,"static unsigned char %s = {", substring) == 1) { xbmPtr->version = 11; } else if (sscanf(s, "static char %s = {", substring) == 1) { xbmPtr->version = 11; } else { continue; } if (*next == '\r') { next++; } Blt_DBuffer_SetPointer(data, next); return TRUE; } return FALSE; } /* *--------------------------------------------------------------------------- * * XbmGetHexValue -- * * Converts the hexadecimal string into an unsigned integer * value. The hexadecimal string need not have a leading "0x". * * Results: * Returns a standard TCL result. If the conversion was * successful, TCL_OK is returned, otherwise TCL_ERROR. * * Side Effects: * If the conversion fails, interp->result is filled with an * error message. * *--------------------------------------------------------------------------- */ static int XbmGetHexValue(const char *string, int *valuePtr) { static unsigned char hexTable[256]; static int initialized = 0; const char *s; int accum; if (!initialized) { Blt_InitHexTable(hexTable); initialized++; } s = string; if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) { s += 2; } if (s[0] == '\0') { return FALSE; /* Error: empty string or only found "0x". */ } accum = 0; for ( /*empty*/ ; *s != '\0'; s++) { unsigned char byte; /* Check if character is a hex digit and accumulate. */ byte = hexTable[(int)*s]; if (byte == 0xFF) { return FALSE; /* Not a hexadecimal number */ } accum = (accum << 4) | byte; } *valuePtr = accum; return TRUE; } /* *--------------------------------------------------------------------------- * * XbmBitmapData -- * * Converts a list of ASCII values into a picture. * * Results: * A standard TCL result. * * Side Effects: * If an error occurs while processing the data, interp->result * is filled with a corresponding error message. * * The data sink is damaged by "strtok". Unlike XbmReadHeader, * here it's okay, since if we're already this far, we know it's * an XBM image and we assume that the data sink won't be reused. * *--------------------------------------------------------------------------- */ static int XbmBitmapData( Blt_DBuffer data, /* Data sink to be read from. */ int version, /* X10 or X11. */ Blt_Pixel *fgColorPtr, /* Foreground bitmap color (bit is 1). */ Blt_Pixel *bgColorPtr, /* Background bitmap color (bit is 0). */ Picture *destPtr) /* Picture to be populated from XBM * image. */ { Blt_Pixel *destRowPtr; char *string; /* Used to tell strtok that have * continued processing the same * string. */ int y; destRowPtr = destPtr->bits; string = (char *)Blt_DBuffer_Pointer(data); for (y = 0; y < destPtr->height; y++) { int x; Blt_Pixel *dp; dp = destRowPtr; if (version == 10) { for (x = 0; x < destPtr->width; /* empty */) { char *p; int i, u16; p = strtok(string, ",;}\n\r\t "), string = NULL; if ((p == NULL) || (!XbmGetHexValue(p, &u16))) { return FALSE; } for (i = 0; (x < destPtr->width) && (i < 16); i++, x++) { dp->u32 = (u16 & (1<<i)) ? fgColorPtr->u32 : bgColorPtr->u32; dp++; } } } else { for (x = 0; x < destPtr->width; /* empty */) { char *p; int i, u8; p = strtok(string, ",;}\n\r\t "), string = NULL; if ((p == NULL) || (!XbmGetHexValue(p, &u8))) { return FALSE; } for (i = 0; (x < destPtr->width) && (i < 8); i++, x++) { dp->u32 = (u8 & (1<<i)) ? fgColorPtr->u32 : bgColorPtr->u32; dp++; } } } destRowPtr += destPtr->pixelsPerRow; } if (bgColorPtr->Alpha == 0x00) { /* Background is 100% transparent. */ if (fgColorPtr->Alpha == 0xFF) { destPtr->flags |= BLT_PIC_MASK; } else { destPtr->flags |= BLT_PIC_BLEND; } } else if (bgColorPtr->Alpha != 0xFF) { /* Partial transparency. */ destPtr->flags |= BLT_PIC_BLEND; } else if (fgColorPtr->Alpha == 0x00) { /* Background is 100% opaque and foreground is 100% * transparent. */ destPtr->flags |= BLT_PIC_MASK; } return TRUE; } /* *--------------------------------------------------------------------------- * * IsXbm -- * * Attempts to parse an XBM file header. * * Results: * Returns 1 is the header is XBM and 0 otherwise. Note that * the validity of the header values is not checked here. That's * done in Blt_XbmToPicture. * *--------------------------------------------------------------------------- */ static int IsXbm(Blt_DBuffer data) { Xbm xbm; int bool; bool = XbmHeader(data, &xbm); return bool; } /* *--------------------------------------------------------------------------- * * XbmToPicture -- * * Reads an XBM file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain XbmToPicture( Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer, XbmImportSwitches *switchesPtr) { Blt_Picture picture; Xbm xbm; picture = NULL; if (!XbmHeader(buffer, &xbm)) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" invalid XBM header", (char *)NULL); goto error; } if ((xbm.width > 0) && (xbm.height > 0)) { picture = Blt_CreatePicture(xbm.width, xbm.height); if (!XbmBitmapData(buffer, xbm.version, &switchesPtr->fg, &switchesPtr->bg, picture)) { Tcl_AppendResult(interp, "error reading \"", fileName, "\" invalid XBM data", (char *)NULL); goto error; } } else { Tcl_AppendResult(interp, "error reading \"", fileName, "\" invalid XBM dimensions \"", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(xbm.width), " x ", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(xbm.height), "\"", (char *)NULL); goto error; } Blt_DBuffer_Free(buffer); if (picture) { Blt_Chain chain; chain = Blt_Chain_Create(); Blt_Chain_Append(chain, picture); return chain; } error: if (picture) { Blt_FreePicture(picture); } Blt_DBuffer_Free(buffer); return NULL; } /* *--------------------------------------------------------------------------- * * PictureToXbm -- * * Writes a XBM format image to the provided data buffer. * * Results: * A standard TCL result. If an error occured, TCL_ERROR is * returned and an error message will be place in the interpreter * result. Otherwise, the data sink will contain the binary * output of the image. * * Side Effects: * Memory is allocated for the data sink. * *--------------------------------------------------------------------------- */ static int PictureToXbm(Tcl_Interp *interp, Blt_Picture original, Blt_DBuffer buffer, XbmExportSwitches *switchesPtr) { Picture *srcPtr; srcPtr = original; Blt_DBuffer_Print(buffer, "#define picture_width %d\n", srcPtr->width); Blt_DBuffer_Print(buffer, "#define picture_height %d\n", srcPtr->height); Blt_DBuffer_Print(buffer, "#define picture_x_hot %d\n", srcPtr->width / 2); Blt_DBuffer_Print(buffer, "#define picture_y_hot %d\n", srcPtr->height / 2); Blt_DBuffer_Print(buffer, "static char picture_bits[] = {\n "); { Blt_Pixel *cp, *srcRowPtr; Blt_Pixel palette[256]; int count, i; int y; /* Create a B&W palette for dithering the image. */ for (cp = palette, i = 0; i < 256; i++, cp++) { int c; c = (i + 127) / 255; cp->Blue = cp->Green = cp->Red = (unsigned char) (c * 255 + 0.5); cp->Alpha = ALPHA_OPAQUE; } /* Remove any transparent pixels by blending into a solid * white background. */ if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_Picture unassoc; /* * The picture has an alpha burned into the components. Create a * temporary copy removing pre-multiplied alphas. */ unassoc = Blt_ClonePicture(srcPtr); Blt_UnassociateColors(unassoc); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = unassoc; } /* Now dither the picture to 2 colors. */ { Blt_Picture dither; dither = Blt_DitherPicture(srcPtr, palette); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = dither; } /* Write the dithered image data. */ count = 0; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int x; sp = srcRowPtr; for (x = 0; x < srcPtr->width; /* empty */) { unsigned char bits; int i; bits = 0; for (i = 0; (x < srcPtr->width) && (i < 8); i++, x++) { if (sp->Red == 0x00) { bits |= (1<<i); } sp++; } count++; Blt_DBuffer_Print(buffer, "0x%02x, ", bits); if (count > 11) { Blt_DBuffer_Print(buffer, "\n "); count = 0; } } srcRowPtr += srcPtr->pixelsPerRow; } Blt_DBuffer_Print(buffer, "\n};\n"); /* Free the temporary images. */ if (srcPtr != original) { Blt_FreePicture(srcPtr); } } return TCL_OK; } static Blt_Chain ReadXbm(Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer) { XbmImportSwitches switches; memset(&switches, 0, sizeof(switches)); return XbmToPicture(interp, fileName, buffer, &switches); } static Tcl_Obj * WriteXbm(Tcl_Interp *interp, Blt_Picture picture) { Tcl_Obj *objPtr; Blt_DBuffer buffer; XbmExportSwitches switches; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* white */ buffer = Blt_DBuffer_Create(); if (PictureToXbm(interp, picture, buffer, &switches) != TCL_OK) { objPtr = NULL; } else { objPtr = Tcl_NewStringObj((char *)Blt_DBuffer_Bytes(buffer), Blt_DBuffer_Length(buffer)); } Blt_DBuffer_Destroy(buffer); return objPtr; } static Blt_Chain ImportXbm( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer buffer; XbmImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } buffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { int nBytes; string = Tcl_GetStringFromObj(switches.dataObjPtr, &nBytes); Blt_DBuffer_AppendData(buffer, (unsigned char *)string, nBytes); string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); if (Blt_DBuffer_LoadFile(interp, string, buffer) != TCL_OK) { goto error; } *fileNamePtr = string; } chain = XbmToPicture(interp, string, buffer, &switches); error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(buffer); return chain; } static int ExportXbm(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { XbmExportSwitches switches; Blt_DBuffer buffer; int result; Blt_Picture picture; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } buffer = Blt_DBuffer_Create(); result = PictureToXbm(interp, picture, buffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, buffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = Blt_DBuffer_StringObj(buffer); objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, objPtr, 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { Tcl_SetObjResult(interp, Blt_DBuffer_StringObj(buffer)); } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(buffer); return result; } int Blt_PictureXbmInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_xbm", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "xbm", /* Name of format. */ IsXbm, /* Discovery routine. */ ReadXbm, /* Read format procedure. */ WriteXbm, /* Write format procedure. */ ImportXbm, /* Import format procedure. */ ExportXbm); /* Export format procedure. */ } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/Makefile-macosx.in������������������������������������������������������������0000644�0001750�0001750�00000040360�11462120063�016366� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for static version of BLT library # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ BLT_LIBRARY = @BLT_LIBRARY@ CC = @CC@ CFLAGS = @CFLAGS@ DEFINES = @DEFINES@ EXTRA_CFLAGS = @GCCFLAGS@ $(SO_CFLAGS) LDFLAGS = @LDFLAGS@ @LD_RUN_PATH@ LIB_PREFIX = @LIB_PREFIX@ TCLLIBPATH = @TCL_LIB_DIR@/tcl@TCL_VERSION@ TCL_DBG = @TCL_DBGX@ SO_CFLAGS = @BLT_SO_CFLAGS@ LIB_SUFFIX = @BLT_LIB_SUFFIX@ SO_EXT = @BLT_SO_EXT@ SO_PREFIX = @BLT_SO_PREFIX@ SO_LD = @BLT_SO_LD@ SO_LDFLAGS = @BLT_SO_LDFLAGS@ @LD_RUN_PATH@ EXPAT_INC_SPEC = @EXPAT_INC_SPEC@ EXPAT_LIB_SPEC = @EXPAT_LIB_SPEC@ FT2_INC_SPEC = @FT2_INC_SPEC@ FT2_LIB_SPEC = @FT2_LIB_SPEC@ JPG_INC_SPEC = @JPG_INC_SPEC@ JPG_LIB_SPEC = @JPG_LIB_SPEC@ MYSQL_INC_SPEC = @MYSQL_INC_SPEC@ MYSQL_LIB_SPEC = @MYSQL_LIB_SPEC@ PNG_INC_SPEC = @PNG_INC_SPEC@ PNG_LIB_SPEC = @PNG_LIB_SPEC@ $(Z_LIB_SPEC) TCL_INC_SPEC = @TCL_INC_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUBS_SPEC = @TCL_STUBS_SPEC@ TIF_INC_SPEC = @TIF_INC_SPEC@ TIF_LIB_SPEC = @TIF_LIB_SPEC@ TK_INC_SPEC = @TK_INC_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ TK_STUBS_SPEC = @TK_STUBS_SPEC@ X11_INC_SPEC = @X11_INC_SPEC@ X11_LIB_SPEC = @X11_LIB_SPEC@ XFT_INC_SPEC = @XFT_INC_SPEC@ XFT_LIB_SPEC = @XFT_LIB_SPEC@ XPM_INC_SPEC = @XPM_INC_SPEC@ XPM_LIB_SPEC = @XPM_LIB_SPEC@ XAU_LIB_SPEC = @XAU_LIB_SPEC@ XRANDR_LIB_SPEC = @XRANDR_LIB_SPEC@ XRENDER_LIB_SPEC = @XRENDER_LIB_SPEC@ FTCFG_LIB_SPEC = @FTCFG_LIB_SPEC@ XDMCP_LIB_SPEC = @XDMCP_LIB_SPEC@ Z_LIB_SPEC = @Z_LIB_SPEC@ version = @BLT_MAJOR_VERSION@@BLT_MINOR_VERSION@ # ------------------------------------------------------------------------ # Source and targer installation directories # ------------------------------------------------------------------------ bindir = $(exec_prefix)/bin datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ incdir = $(prefix)/include includedir = @includedir@ libdir = @libdir@ prefix = @prefix@ scriptdir = $(exec_prefix)/lib srcdir = @srcdir@ pkgdir = @BLT_LIBRARY@ instdirs = $(prefix) \ $(exec_prefix) \ $(bindir) \ $(libdir) \ $(incdir) \ $(pkgdir) \ $(scriptdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ INCLUDES = -I. -I$(srcdir) \ @INCLUDES@ # ------------------------------------------------------------------------ # Libraries directives for Tcl, Tk, X11, and BLT # ------------------------------------------------------------------------ EXTRA_CORE_LIBS = @LIBS@ @EXTRA_LIBS@ EXTRA_X_LIBS = $(X11_LIB_SPEC) \ $(XAU_LIB_SPEC) \ $(XDMCP_LIB_SPEC) \ $(XRANDR_LIB_SPEC) \ $(XRENDER_LIB_SPEC) \ $(EXTRA_CORE_LIBS) BLT_X_SO_LIBS = $(TK_LIB_SPEC) \ $(XFT_LIB_SPEC) \ $(FTCFG_LIB_SPEC) \ $(XRANDR_LIB_SPEC) \ $(FT2_LIB_SPEC) \ $(EXTRA_X_LIBS) BLT_X_A_LIBS = $(BLT_X_SO_LIBS) \ $(JPG_LIB_SPEC) \ $(PNG_LIB_SPEC) \ $(TIF_LIB_SPEC) \ $(XPM_LIB_SPEC) BLT_CORE_SO_LIBS = $(TCL_LIB_SPEC) BLT_CORE_A_LIBS = $(BLT_CORE_SO_LIBS) \ $(MYSQL_LIB_SPEC) \ $(EXPAT_LIB_SPEC) blt_core_name = BLTCore$(version)$(LIB_SUFFIX) blt_x_name = BLTX$(version)$(LIB_SUFFIX) blt_core_so = lib$(blt_core_name)$(SO_EXT) blt_core_a = lib$(blt_core_name).a blt_x_so = lib$(blt_x_name)$(SO_EXT) blt_x_a = lib$(blt_x_name).a blt_dt_csv_name = TableCsv$(version)$(LIB_SUFFIX) blt_dt_mysql_name = TableMysql$(version)$(LIB_SUFFIX) blt_dt_tree_name = TableTree$(version)$(LIB_SUFFIX) blt_dt_vec_name = TableVector$(version)$(LIB_SUFFIX) blt_dt_xml_name = TableXml$(version)$(LIB_SUFFIX) blt_dt_csv_so = $(blt_dt_csv_name)$(SO_EXT) blt_dt_mysql_so = $(blt_dt_mysql_name)$(SO_EXT) blt_dt_tree_so = $(blt_dt_tree_name)$(SO_EXT) blt_dt_vec_so = $(blt_dt_vec_name)$(SO_EXT) blt_dt_xml_so = $(blt_dt_xml_name)$(SO_EXT) blt_pict_bmp_name = PictureBmp$(version)$(LIB_SUFFIX) blt_pict_gif_name = PictureGif$(version)$(LIB_SUFFIX) blt_pict_jpg_name = PictureJpg$(version)$(LIB_SUFFIX) blt_pict_pbm_name = PicturePbm$(version)$(LIB_SUFFIX) blt_pict_pdf_name = PicturePdf$(version)$(LIB_SUFFIX) blt_pict_photo_name = PicturePhoto$(version)$(LIB_SUFFIX) blt_pict_png_name = PicturePng$(version)$(LIB_SUFFIX) blt_pict_ps_name = PicturePs$(version)$(LIB_SUFFIX) blt_pict_tif_name = PictureTif$(version)$(LIB_SUFFIX) blt_pict_xbm_name = PictureXbm$(version)$(LIB_SUFFIX) blt_pict_xpm_name = PictureXpm$(version)$(LIB_SUFFIX) blt_pict_bmp_so = $(blt_pict_bmp_name)$(SO_EXT) blt_pict_gif_so = $(blt_pict_gif_name)$(SO_EXT) blt_pict_jpg_so = $(blt_pict_jpg_name)$(SO_EXT) blt_pict_pbm_so = $(blt_pict_pbm_name)$(SO_EXT) blt_pict_pdf_so = $(blt_pict_pdf_name)$(SO_EXT) blt_pict_photo_so = $(blt_pict_photo_name)$(SO_EXT) blt_pict_png_so = $(blt_pict_png_name)$(SO_EXT) blt_pict_ps_so = $(blt_pict_ps_name)$(SO_EXT) blt_pict_tif_so = $(blt_pict_tif_name)$(SO_EXT) blt_pict_xbm_so = $(blt_pict_xbm_name)$(SO_EXT) blt_pict_xpm_so = $(blt_pict_xpm_name)$(SO_EXT) blt_tree_xml_name = TreeXml$(version)$(LIB_SUFFIX) blt_tree_xml_so = $(blt_tree_xml_name)$(SO_EXT) blt_core_pkgs_so = $(blt_dt_csv_so) \ $(blt_dt_tree_so) \ $(blt_dt_vec_so) ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif ifneq ("$(MYSQL_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_mysql_so) endif blt_x_pkgs_so = $(blt_pict_gif_so) \ $(blt_pict_xbm_so) \ $(blt_pict_bmp_so) \ $(blt_pict_pbm_so) \ $(blt_pict_pdf_so) \ $(blt_pict_ps_so) \ $(blt_pict_photo_so) ifneq ("$(JPG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_jpg_so) endif ifneq ("$(PNG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_png_so) endif ifneq ("$(XPM_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_xpm_so) endif ifneq ("$(XPM_TIF_SPEC)", "") blt_x_pkgs_so += $(blt_pict_tif_so) endif ifneq ("$(TCL_STUBS_SPEC)", "") tcl_lib_spec=$(TCL_STUBS_SPEC) else tcl_lib_spec=$(TCL_LIB_SPEC) endif ifneq ("$(TK_STUBS_SPEC)", "") tk_lib_spec=$(TK_STUBS_SPEC) else tk_lib_spec=$(TK_LIB_SPEC) endif ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ N_OBJS = bltTed.o V3_OBJS = bltTri.o bltGrMt.o TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o TREEVIEW_OBJS = bltTreeView.o \ bltTvCmd.o \ bltTvCol.o \ bltTvEdit.o \ bltTvStyle.o PICTURE_OBJS = bltPicture.o \ bltPictCmd.o \ bltPictDraw.o \ bltPictMmx.o PICTURE_PKG_OBJS = bltPictBmp.o \ bltPictGif.o \ bltPictJpg.o \ bltPictPbm.o \ bltPictPdf.o \ bltPictPhoto.o \ bltPictPng.o \ bltPictPs.o \ bltPictTif.o \ bltPictXbm.o \ bltPictXpm.o TREE_OBJS = bltTree.o \ bltTreeCmd.o \ TREE_PKG_OBJS = bltTreeXml.o DATATABLE_OBJS = bltDataTable.o \ bltDtCmd.o \ DATATABLE_PKG_OBJS = bltDtCsv.o \ bltDtMysql.o \ bltDtTree.o \ bltDtVec.o \ bltDtXml.o BLT_CORE_SO_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBase64.o \ bltBgexec.o \ bltChain.o \ bltCrc32.o \ bltCsv.o \ $(DATATABLE_OBJS) \ bltDebug.o \ bltHash.o \ bltInit.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltDBuffer.o \ bltSpline.o \ bltSwitch.o \ $(TREE_OBJS) \ bltUtil.o \ bltVar.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltWatch.o \ bltTri.o \ bltUnixBgexec.o \ bltUnixPipe.o \ bltCoreInit.o BLT_CORE_A_OBJS = $(BLT_CORE_SO_OBJS) \ $(TREE_PKG_OBJS) \ $(DATATABLE_PKG_OBJS) BLT_X_SO_OBJS = $(GRAPH_OBJS) \ $(PICTURE_OBJS) \ $(TREEVIEW_OBJS) \ bltBeep.o \ bltBgStyle.o \ bltBind.o \ bltBitmap.o \ bltBusy.o \ bltCanvEps.o \ bltComboBtn.o \ bltComboEntry.o \ bltComboMenu.o \ bltComboTree.o \ bltConfig.o \ bltContainer.o \ bltCutbuffer.o \ bltDragdrop.o \ bltHtext.o \ bltImage.o \ bltListView.o \ bltMenubar.o \ bltOldConfig.o \ bltPaneset.o \ bltPs.o \ bltPsAfm.o \ bltScrollset.o \ bltTable.o \ bltTabset.o \ bltText.o \ bltUnixBitmap.o \ bltUnixDnd.o \ bltUnixFont.o \ bltUnixPainter.o \ bltUnixWindow.o \ bltWindow.o \ bltWinop.o \ bltExtInit.o \ $(TK_OBJS) $(N_OBJS) BLT_X_A_OBJS = $(BLT_X_SO_OBJS) \ $(PICTURE_PKG_OBJS) BLT_SO_OBJS = $(BLT_CORE_SO_OBJS) \ $(BLT_X_SO_OBJS) BLT_A_OBJS = $(BLT_CORE_A_OBJS) \ $(BLT_X_A_OBJS) # GNU Make-specific macro SRCS = $(patsubst %.o,$(srcdir)/%.c,$(BLT_A_OBJS)) bltwish = bltwish$(version) bltsh = bltsh$(version) # Public headers to be installed headers = $(srcdir)/blt.h \ $(srcdir)/bltBind.h \ $(srcdir)/bltChain.h \ bltHash.h \ $(srcdir)/bltList.h \ $(srcdir)/bltPool.h \ $(srcdir)/bltTree.h \ $(srcdir)/bltVector.h CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) MAIN_CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_ROOT = RANLIB = @RANLIB@ SHELL = /bin/sh AR = ar rc RM = rm -f LINT = splint LINTFLAGS = #-axhbns XREF = cxref XREFFLAGS = -dltR LN_S = @LN_S@ VPATH = $(srcdir) all: build_libs build_demos build_demos: $(bltsh) $(bltwish) build_libs: build_@BLT_TARGET@ build_shared: $(blt_core_so) $(blt_x_so) build_core_pkgs build_x_pkgs build_static: $(blt_core_a) $(blt_x_a) build_core_pkgs: $(blt_core_so) $(blt_core_pkgs_so) build_x_pkgs: $(blt_x_so) $(blt_x_pkgs_so) $(bltwish): $(blt_core_a) $(blt_x_a) $(srcdir)/bltUnixMain.c $(RM) $(bltwish) $(CC) $(MAIN_CC_OPTS) $(LDFLAGS) -o $(bltwish) \ -DSTATIC_PKGS -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltUnixMain.c \ $(blt_x_a) $(blt_core_a) $(TK_LIB_SPEC) $(TCL_LIB_SPEC) \ $(BLT_X_A_LIBS) $(BLT_CORE_A_LIBS) $(EXTRA_X_LIBS) $(bltsh): $(blt_core_a) $(srcdir)/bltUnixMain.c $(RM) $(bltsh) $(CC) $(CC_OPTS) $(LDFLAGS) -o $(bltsh) \ -DTCL_ONLY -DSTATIC_PKGS -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltUnixMain.c \ $(blt_core_a) $(TCL_STUBS_SPEC) $(TCL_LIB_SPEC) \ $(BLT_CORE_A_LIBS) $(EXTRA_CORE_LIBS) $(blt_core_a): $(BLT_CORE_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_CORE_A_OBJS) $(RANLIB) $@ $(blt_x_a): $(BLT_X_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_X_A_OBJS) $(RANLIB) $@ $(blt_core_so): $(BLT_CORE_SO_OBJS) $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ $(BLT_CORE_SO_OBJS) $(BLT_CORE_SO_LIBS) \ $(core_lib_spec) $(blt_x_so): $(BLT_X_SO_OBJS) $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ $(BLT_X_SO_OBJS) $(BLT_X_SO_LIBS) \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_mysql_so): bltDtMysql.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtMysql.o $(MYSQL_LIB_SPEC) \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_xml_so): bltDtXml.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtXml.o $(EXPAT_LIB_SPEC) \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_csv_so): bltDtCsv.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtCsv.o \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_vec_so): bltDtVec.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtVec.o \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_tree_so): bltDtTree.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtTree.o \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_pict_bmp_so): bltPictBmp.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictBmp.o \ $(blt_x_so) $(blt_core_so) \ $(TCL_LIB_SPEC) $(blt_pict_gif_so): bltPictGif.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictGif.o \ $(blt_x_so) $(blt_core_so) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(blt_pict_jpg_so): bltPictJpg.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictJpg.o $(JPG_LIB_SPEC) $(blt_pict_png_so): bltPictPng.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPng.o $(PNG_LIB_SPEC) $(blt_pict_pbm_so): bltPictPbm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPbm.o \ $(blt_x_so) $(blt_core_so) $(TCL_LIB_SPEC) $(blt_pict_tif_so): bltPictTif.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictTif.o $(TIF_LIB_SPEC) $(blt_pict_xbm_so): bltPictXbm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictXbm.o \ $(blt_x_so) $(blt_core_so) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(blt_pict_xpm_so): bltPictXpm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictXpm.o \ $(blt_x_so) $(blt_core_so) \ $(TCL_LIB_SPEC) $(X11_LIB_SPEC) $(XPM_LIB_SPEC) $(blt_pict_pdf_so): bltPictPdf.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPdf.o \ $(blt_x_so) $(blt_core_so) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(blt_pict_ps_so): bltPictPs.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPs.o \ $(blt_x_so) $(blt_core_so) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(blt_pict_photo_so): bltPictPhoto.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPhoto.o \ $(blt_x_so) $(blt_core_so) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(blt_tree_xml_so): bltTreeXml.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltTreeXml.o $(EXPAT_LIB_SPEC) \ $(blt_core_so) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) install: mkdirs install-demos install-libs install-headers install-libs: install-@BLT_TARGET@ install-demos: $(bltwish) $(bltsh) $(INSTALL) -m 0755 $(bltwish) $(DESTDIR)$(bindir) $(INSTALL) -m 0755 $(bltsh) $(DESTDIR)$(bindir) install-shared: $(blt_core_so) $(blt_x_so) install-pkgs install-static $(INSTALL) -m 0755 $(blt_core_so) $(DESTDIR)$(libdir) $(INSTALL) -m 0755 $(blt_x_so) $(DESTDIR)$(libdir) install-static: $(blt_core_a) $(blt_x_a) $(INSTALL_DATA) $(blt_core_a) $(DESTDIR)$(libdir) $(RANLIB) $(DESTDIR)$(libdir)/$(blt_core_a) $(INSTALL_DATA) $(blt_x_a) $(DESTDIR)$(libdir) $(RANLIB) $(DESTDIR)$(libdir)/$(blt_x_a) install-pkgs: $(blt_core_pkgs_so) $(blt_x_pkgs_so) for i in $(blt_core_pkgs_so) $(blt_x_pkgs_so) ; do \ echo $(RM) $(DESTDIR)$(libdir)/$$i ; \ $(RM) $(DESTDIR)$(libdir)/$$i ; \ echo $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ done install-headers: @for i in $(headers) ; do \ echo "installing $$i..." ; \ $(INSTALL_DATA) -m 0444 $$i $(DESTDIR)$(incdir) ; \ done mkdirs: @for i in $(instdirs) ; do \ if test -d $(DESTDIR)$$i ; then \ : ; \ else \ echo " mkdir $(DESTDIR)$$i" ; \ $(INSTALL) -d $(DESTDIR)$$i ; \ fi ; \ done lint: $(LINT) $(LINTFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) xref: $(XREF) $(XREFFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) clean: clean-objs clean-libs clean-demos clean-libs: clean-@BLT_TARGET@ clean-objs: $(RM) $(BLT_A_OBJS) clean-demos: $(RM) $(bltsh)* $(bltwish)* *pure* .pure* clean-static: $(RM) $(blt_core_a) $(blt_x_a) clean-pkgs: $(RM) $(blt_core_pkgs_so) $(blt_x_pkgs_so) clean-shared: clean-pkgs clean-static $(RM) $(blt_core_so) $(blt_x_so) distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile $(RM) config.h bltHash.h Makefile TAGS bltDtMysql.o: $(srcdir)/bltDtMysql.c $(CC) -c $(CC_OPTS) $(MYSQL_INC_SPEC) $? bltDtXml.o: $(srcdir)/bltDtXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTree.o: $(srcdir)/bltTree.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTreeXml.o: $(srcdir)/bltTreeXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltUnixFont.o: $(srcdir)/bltUnixFont.c $(CC) -c $(CC_OPTS) $(FT2_INC_SPEC) $? bltPictDraw.o: $(srcdir)/bltPictDraw.c $(srcdir)/bltPaintDraw.c $(CC) -c $(CC_OPTS) $(FT2_INC_SPEC) $< bltPictJpg.o: $(srcdir)/bltPictJpg.c $(CC) -c $(CC_OPTS) $(JPG_INC_SPEC) $? bltPictTif.o: $(srcdir)/bltPictTif.c $(CC) -c $(CC_OPTS) $(TIF_INC_SPEC) $? bltPictPng.o: $(srcdir)/bltPictPng.c $(CC) -c $(CC_OPTS) $(PNG_INC_SPEC) $? bltPictXpm.o: $(srcdir)/bltPictXpm.c $(CC) -c $(CC_OPTS) $(XPM_INC_SPEC) $? bltCoreInit.o: $(srcdir)/bltCoreInit.c $(CC) -c $(CC_OPTS) -DTCL_ONLY -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ $(srcdir)/bltCoreInit.c .c.o: $(CC) -c $(CC_OPTS) $< ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixPipe.c�����������������������������������������������������������������0000644�0001750�0001750�00000067443�11462120063�015453� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixPipe.c -- * * This module implements the former Tcl_CreatePipeline API. This file * contains the generic portion of the command channel driver as well * as various utility routines used in managing subprocesses. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from tclPipe.c and tclUnixPipe.c of the Tcl * distribution. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #include "bltInt.h" #include <fcntl.h> #include <signal.h> #include "bltWait.h" typedef int Tcl_File; static int GetFdFromChannel(Tcl_Channel channel, int direction) { long f; ClientData clientData; if (Tcl_GetChannelHandle(channel, direction, &clientData) != TCL_OK) { return -1; } f = (long)clientData; return (int)f; } /* *--------------------------------------------------------------------------- * * OpenFile -- * * Open a file for use in a pipeline. * * Results: * Returns a new TclFile handle or NULL on failure. * * Side effects: * May cause a file to be created on the file system. * *--------------------------------------------------------------------------- */ static int OpenFile( char *fname, /* The name of the file to open. */ int mode) /* In what mode to open the file? */ { int fd; fd = open(fname, mode, 0666); if (fd != -1) { fcntl(fd, F_SETFD, FD_CLOEXEC); /* * If the file is being opened for writing, seek to the end so we can * append to any data already in the file. */ if (mode & O_WRONLY) { lseek(fd, 0, SEEK_END); } return fd; } return -1; } /* *--------------------------------------------------------------------------- * * CreateTempFile -- * * This function creates a temporary file initialized with an * optional string, and returns a file handle with the file pointer * at the beginning of the file. * * Results: * A handle to a file. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int CreateTempFile(char *contents) /* String to write into temp file, or NULL. */ { char fileName[L_tmpnam]; int fd; size_t length = (contents == NULL) ? 0 : strlen(contents); if (mkstemp(fileName) < 0) { panic("can't create temp file"); } fd = OpenFile(fileName, O_RDWR | O_CREAT | O_TRUNC); unlink(fileName); if ((fd >= 0) && (length > 0)) { for (;;) { if (write(fd, contents, length) != -1) { break; } else if (errno != EINTR) { close(fd); return -1; } } lseek(fd, 0, SEEK_SET); } return fd; } /* *--------------------------------------------------------------------------- * * CreatePipe -- * * Creates a pipe by simply calling the pipe() function. * * Results: * Returns 1 on success, 0 on failure. * * Side effects: * Creates a pipe. * *--------------------------------------------------------------------------- */ static int CreatePipe( Tcl_Interp *interp, int *inPtr, /* (out) Descriptor for read side of * pipe. */ int *outPtr) /* (out) Descriptor for write side of * pipe. */ { int fd[2]; if (pipe(fd) < 0) { Tcl_AppendResult(interp, "can't create pipe for command: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } fcntl(fd[0], F_SETFD, FD_CLOEXEC); fcntl(fd[1], F_SETFD, FD_CLOEXEC); *inPtr = fd[0]; *outPtr = fd[1]; return TCL_OK; } /* *--------------------------------------------------------------------------- * * CloseFile -- * * Implements a mechanism to close a UNIX file. * * Results: * Returns 0 on success, or -1 on error, setting errno. * * Side effects: * The file is closed. * *--------------------------------------------------------------------------- */ static int CloseFile(int fd) /* File descriptor to be closed. */ { if ((fd == 0) || (fd == 1) || (fd == 2)) { return 0; /* Don't close stdin, stdout or * stderr. */ } Tcl_DeleteFileHandler(fd); return close(fd); } /* *--------------------------------------------------------------------------- * * RestoreSignals -- * * This procedure is invoked in a forked child process just before * exec-ing a new program to restore all signals to their default * settings. * * Results: * None. * * Side effects: * Signal settings get changed. * *--------------------------------------------------------------------------- */ static void RestoreSignals(void) { #ifdef SIGABRT signal(SIGABRT, SIG_DFL); #endif #ifdef SIGALRM signal(SIGALRM, SIG_DFL); #endif #ifdef SIGFPE signal(SIGFPE, SIG_DFL); #endif #ifdef SIGHUP signal(SIGHUP, SIG_DFL); #endif #ifdef SIGILL signal(SIGILL, SIG_DFL); #endif #ifdef SIGINT signal(SIGINT, SIG_DFL); #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_DFL); #endif #ifdef SIGQUIT signal(SIGQUIT, SIG_DFL); #endif #ifdef SIGSEGV signal(SIGSEGV, SIG_DFL); #endif #ifdef SIGTERM signal(SIGTERM, SIG_DFL); #endif #ifdef SIGUSR1 signal(SIGUSR1, SIG_DFL); #endif #ifdef SIGUSR2 signal(SIGUSR2, SIG_DFL); #endif #ifdef SIGCHLD signal(SIGCHLD, SIG_DFL); #endif #ifdef SIGCONT signal(SIGCONT, SIG_DFL); #endif #ifdef SIGTSTP signal(SIGTSTP, SIG_DFL); #endif #ifdef SIGTTIN signal(SIGTTIN, SIG_DFL); #endif #ifdef SIGTTOU signal(SIGTTOU, SIG_DFL); #endif } /* *--------------------------------------------------------------------------- * * SetupStdFile -- * * Set up stdio file handles for the child process, using the * current standard channels if no other files are specified. * If no standard channel is defined, or if no file is associated * with the channel, then the corresponding standard fd is closed. * * Results: * Returns 1 on success, or 0 on failure. * * Side effects: * Replaces stdio fds. * *--------------------------------------------------------------------------- */ static int SetupStdFile( int fd, /* File descriptor to dup, or -1. */ int type) /* One of TCL_STDIN, TCL_STDOUT, * TCL_STDERR */ { int targetFd = 0; /* Initializations here needed only * to */ int direction = 0; /* Prevent warnings about using * uninitialized variables. */ switch (type) { case TCL_STDIN: targetFd = 0; direction = TCL_READABLE; break; case TCL_STDOUT: targetFd = 1; direction = TCL_WRITABLE; break; case TCL_STDERR: targetFd = 2; direction = TCL_WRITABLE; break; } if (fd < 0) { Tcl_Channel channel; channel = Tcl_GetStdChannel(type); if (channel) { fd = GetFdFromChannel(channel, direction); } } if (fd >= 0) { if (fd != targetFd) { if (dup2(fd, targetFd) == -1) { return 0; } /* * Must clear the close-on-exec flag for the target FD, since some * systems (e.g. Ultrix) do not clear the CLOEXEC flag on the * target FD. */ fcntl(targetFd, F_SETFD, 0); } else { /* * Since we aren't dup'ing the file, we need to explicitly clear * the close-on-exec flag. */ fcntl(fd, F_SETFD, 0); } } else { close(targetFd); } return 1; } /* *--------------------------------------------------------------------------- * * CreateProcess -- * * Create a child process that has the specified files as its standard * input, output, and error. The child process runs asynchronously and * runs with the same environment variables as the creating process. * * The path is searched to find the specified executable. * * Results: * The return value is TCL_ERROR and an error message is left in * interp->result if there was a problem creating the child process. * Otherwise, the return value is TCL_OK and *pidPtr is filled with the * process id of the child process. * * Side effects: * A process is created. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CreateProcess( Tcl_Interp *interp, /* Interpreter in which to leave errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to stderrFd. */ int argc, /* Number of arguments in following array. */ char **argv, /* Array of argument strings. argv[0] * contains the name of the executable * converted to native format (using the * Tcl_TranslateFileName call). Additional * arguments have not been converted. */ int stdinFd, /* The file to use as input for the child * process. If stdinFd file is -1, input is * read from the standard input channel. If * the file isn't readable, the child will * receive no standard input. */ int stdoutFd, /* The file that receives output from the * child process. If stdoutFd is -1, output * is sent to the standard output channel. If * the file is not writeable, output from the * child will be discarded. */ int stderrFd, /* The file that receives errors from the * child process. If stderrFd file is -1, * errors will be sent to the standard error * channel. If the file isn't writeable, * errors from the child will be discarded. * stderrFd may be the same as stdoutFd. */ int *pidPtr) /* (out) If this procedure is successful, * pidPtr is filled with the process id of the * child process. */ { #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_DString *dsArr; Tcl_Encoding encoding; #endif char errSpace[200]; int errPipeIn, errPipeOut; int i; int joinThisError, status, fd; long pid; size_t count; errPipeIn = errPipeOut = -1; pid = -1; #if (_TCL_VERSION >= _VERSION(8,1,0)) dsArr = Blt_AssertMalloc(argc * sizeof(Tcl_DString)); encoding = Tcl_GetEncoding(interp, NULL); for(i = 0; i < argc; i++) { argv[i] = Tcl_UtfToExternalDString(encoding, argv[i], strlen(argv[i]), dsArr + i); } #endif /* * Create a pipe that the child can use to return error information if * anything goes wrong. */ if (CreatePipe(interp, &errPipeIn, &errPipeOut) != TCL_OK) { goto error; } joinThisError = (stderrFd == stdoutFd); pid = fork(); if (pid == 0) { ssize_t nWritten; fd = errPipeOut; /* * Set up stdio file handles for the child process. */ if (!SetupStdFile(stdinFd, TCL_STDIN) || !SetupStdFile(stdoutFd, TCL_STDOUT) || (!joinThisError && !SetupStdFile(stderrFd, TCL_STDERR)) || (joinThisError && ((dup2(1, 2) == -1) || (fcntl(2, F_SETFD, 0) != 0)))) { sprintf_s(errSpace, 200, "%dforked process can't set up input/output: ", errno); nWritten = write(fd, errSpace, (size_t) strlen(errSpace)); _exit(1); } /* * Close the input side of the error pipe. */ RestoreSignals(); execvp(argv[0], &argv[0]); sprintf_s(errSpace, 200, "%dcan't execute \"%.150s\": ", errno, argv[0]); nWritten = write(fd, errSpace, (size_t)strlen(errSpace)); _exit(1); } if (pid == -1) { Tcl_AppendResult(interp, "can't fork child process: ", Tcl_PosixError(interp), (char *)NULL); goto error; } /* * Read back from the error pipe to see if the child started up OK. The * info in the pipe (if any) consists of a decimal errno value followed by * an error message. */ CloseFile(errPipeOut); errPipeOut = -1; fd = errPipeIn; count = read(fd, errSpace, (size_t) (sizeof(errSpace) - 1)); if (count > 0) { char *end; errSpace[count] = 0; errno = strtol(errSpace, &end, 10); Tcl_AppendResult(interp, end, Tcl_PosixError(interp), (char *)NULL); goto error; } #if (_TCL_VERSION >= _VERSION(8,1,0)) for(i = 0; i < argc; i++) { Tcl_DStringFree(dsArr + i); } Blt_Free(dsArr); #endif CloseFile(errPipeIn); *pidPtr = pid; return TCL_OK; error: if (pid != -1) { /* * Reap the child process now if an error occurred during its startup. */ Tcl_WaitPid((Tcl_Pid)pid, &status, WNOHANG); } if (errPipeIn >= 0) { CloseFile(errPipeIn); } if (errPipeOut >= 0) { CloseFile(errPipeOut); } #if (_TCL_VERSION >= _VERSION(8,1,0)) for(i = 0; i < argc; i++) { Tcl_DStringFree(dsArr + i); } Blt_Free(dsArr); #endif return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * FileForRedirect -- * * This procedure does much of the work of parsing redirection operators. * It handles "@" if specified and allowed, and a file name, and opens * the file if necessary. * * Results: * The return value is the descriptor number for the file. If an error * occurs then NULL is returned and an error message is left in * interp->result. Several arguments are side-effected; see the argument * list below for details. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int FileForRedirect( Tcl_Interp *interp, /* Intepreter to use for error reporting. */ char *spec, /* Points to character just after redirection * character. */ char *arg, /* Pointer to entire argument containing spec: * used for error reporting. */ int atOK, /* Non-zero means that '@' notation can be * used to specify a channel, zero means that * it isn't. */ char *nextArg, /* Next argument in argc/argv array, if needed * for file name or channel name. May be * NULL. */ int flags, /* Flags to use for opening file or to specify * mode for channel. */ int *skipPtr, /* (out) Filled with 1 if redirection target * was in spec, 2 if it was in nextArg. */ int *closePtr) /* (out) Filled with one if the caller should * close the file when done with it, zero * otherwise. */ { int writing = (flags & O_WRONLY); int fd; *skipPtr = 1; if ((atOK != 0) && (*spec == '@')) { int direction; Tcl_Channel chan; spec++; if (*spec == '\0') { spec = nextArg; if (spec == NULL) { goto badLastArg; } *skipPtr = 2; } chan = Tcl_GetChannel(interp, spec, NULL); if (chan == NULL) { return -1; } direction = (writing) ? TCL_WRITABLE : TCL_READABLE; fd = GetFdFromChannel(chan, direction); if (fd < 0) { Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(chan), "\" wasn't opened for ", ((writing) ? "writing" : "reading"), (char *)NULL); return -1; } if (writing) { /* * Be sure to flush output to the file, so that anything * written by the child appears after stuff we've already * written. */ Tcl_Flush(chan); } } else { char *name; Tcl_DString nameString; if (*spec == '\0') { spec = nextArg; if (spec == NULL) { goto badLastArg; } *skipPtr = 2; } name = Tcl_TranslateFileName(interp, spec, &nameString); if (name != NULL) { fd = OpenFile(name, flags); } else { fd = -1; } Tcl_DStringFree(&nameString); if (fd < 0) { Tcl_AppendResult(interp, "can't ", ((writing) ? "write" : "read"), " file \"", spec, "\": ", Tcl_PosixError(interp), (char *)NULL); return -1; } *closePtr = TRUE; } return fd; badLastArg: Tcl_AppendResult(interp, "can't specify \"", arg, "\" as last word in command", (char *)NULL); return -1; } /* *--------------------------------------------------------------------------- * * Blt_CreatePipeline -- * * Given an objc/objv array, instantiate a pipeline of processes as * described by the objv. * * Results: * The return value is a count of the number of new processes created, or * -1 if an error occurred while creating the pipeline. *pidArrayPtr is * filled in with the address of a dynamically allocated array giving the * ids of all of the processes. * * It is up to the caller to free this array when it isn't needed * anymore. * * If stdinPipePtr isn't NULL, then *stdinPipePtr is filled with the file * id for the input pipe for the pipeline (if any): the caller must * eventually close this file. * * If stdoutPipePtr isn't NULL, then *stdoutPipePtr is filled with the * file id for the output pipe from the pipeline: the caller must close * this file. * * If stderrPipePtr isn't NULL, then *stderrPipePtr is filled with a file * id that may be used to read error output after the pipeline completes. * * Side effects: * Processes and pipes are created. * *--------------------------------------------------------------------------- */ int Blt_CreatePipeline( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ int objc, /* Number of entries in objv. */ Tcl_Obj *const *objv, /* Array of strings describing commands in * pipeline plus I/O redirection with <, <<, * >, etc. Objv[objc] must be NULL. */ ProcessId **pidArrayPtr, /* (out) Word at *pidArrayPtr gets filled in * with address of array of pids for processes * in pipeline (first pid is first process in * pipeline). */ int *stdinPipePtr, /* (out) If non-NULL, input to the pipeline * comes from a pipe (unless overridden by * redirection in the command). The file id * with which to write to this pipe is stored * at *stdinPipePtr. NULL means command * specified its own input source. */ int *stdoutPipePtr, /* (out) If non-NULL, output to the pipeline * goes to a pipe, unless overriden by * redirection in the command. The file id * with which to read frome this pipe is * stored at *stdoutPipePtr. NULL means * command specified its own output sink. */ int *stderrPipePtr) /* (out) If non-NULL, all stderr output from * the pipeline will go to a temporary file * created here, and a descriptor to read the * file will be left at *stderrPipePtr. The * file will be removed already, so closing * this descriptor will be the end of the * file. If this is NULL, then all stderr * output goes to our stderr. If the pipeline * specifies redirection then the file will * still be created but it will never get any * data. */ { int *pids = NULL; /* Points to malloc-ed array holding all the * pids of child processes. */ int nPids; /* Actual number of processes that exist at * *pids right now. */ int cmdCount; /* Count of number of distinct commands found * in objc/objv. */ char *inputLiteral = NULL; /* If non-null, then this points to a string * containing input data (specified via <<) to * be piped to the first process in the * pipeline. */ char *p; int skip, lastBar, lastArg, i, j, atOK, flags, errorToOutput; Tcl_DString execBuffer; int pipeIn; int isOpen[3]; int curFd[3]; /* If non-zero, then fd should be closed * when cleaning up. */ int fd[3]; char **argv; fd[0] = fd[1] = fd[2] = -1; isOpen[0] = isOpen[1] = isOpen[2] = FALSE; if (stdinPipePtr != NULL) { *stdinPipePtr = -1; } if (stdoutPipePtr != NULL) { *stdoutPipePtr = -1; } if (stderrPipePtr != NULL) { *stderrPipePtr = -1; } Tcl_DStringInit(&execBuffer); pipeIn = curFd[0] = curFd[1] = -1; nPids = 0; /* * First, scan through all the arguments to figure out the structure of * the pipeline. Process all of the input and output redirection * arguments and remove them from the argument list in the pipeline. * Count the number of distinct processes (it's the number of "|" * arguments plus one) but don't remove the "|" arguments because they'll * be used in the second pass to seperate the individual child processes. * * Cannot start the child processes in this pass because the redirection * symbols may appear anywhere in the command line -- e.g., the '<' that * specifies the input to the entire pipe may appear at the very end of * the argument list. */ /* Convert all the Tcl_Objs to strings. */ argv = Blt_AssertMalloc((objc + 1) * sizeof(char *)); for (i = 0; i < objc; i++) { argv[i] = Tcl_GetString(objv[i]); } argv[i] = NULL; lastBar = -1; cmdCount = 1; for (i = 0; i < objc; i++) { skip = 0; p = argv[i]; switch (*p++) { case '\\': p++; continue; case '|': if (*p == '&') { p++; } if (*p == '\0') { if ((i == (lastBar + 1)) || (i == (objc - 1))) { Tcl_AppendResult(interp, "illegal use of | or |& in command", (char *)NULL); goto error; } } lastBar = i; cmdCount++; break; case '<': if (isOpen[0] != 0) { isOpen[0] = FALSE; CloseFile(fd[0]); } if (*p == '<') { fd[0] = -1; inputLiteral = p + 1; skip = 1; if (*inputLiteral == '\0') { inputLiteral = argv[i + 1]; if (inputLiteral == NULL) { Tcl_AppendResult(interp, "can't specify \"", argv[i], "\" as last word in command", (char *)NULL); goto error; } skip = 2; } } else { inputLiteral = NULL; fd[0] = FileForRedirect(interp, p, argv[i], TRUE, argv[i + 1], O_RDONLY, &skip, &isOpen[0]); if (fd[0] < 0) { goto error; } } break; case '>': atOK = TRUE; flags = O_WRONLY | O_CREAT | O_TRUNC; errorToOutput = FALSE; if (*p == '>') { p++; atOK = FALSE; flags = O_WRONLY | O_CREAT; } if (*p == '&') { if (isOpen[2] != 0) { isOpen[2] = FALSE; CloseFile(fd[2]); } errorToOutput = TRUE; p++; } if (isOpen[1] != 0) { isOpen[1] = FALSE; CloseFile(fd[1]); } fd[1] = FileForRedirect(interp, p, argv[i], atOK, argv[i + 1], flags, &skip, &isOpen[1]); if (fd[1] < 0) { goto error; } if (errorToOutput) { isOpen[2] = FALSE; fd[2] = fd[1]; } break; case '2': if (*p != '>') { break; } p++; atOK = TRUE; flags = O_WRONLY | O_CREAT | O_TRUNC; if (*p == '>') { p++; atOK = FALSE; flags = O_WRONLY | O_CREAT; } if (isOpen[2] != 0) { isOpen[2] = FALSE; CloseFile(fd[2]); } fd[2] = FileForRedirect(interp, p, argv[i], atOK, argv[i + 1], flags, &skip, &isOpen[2]); if (fd[2] < 0) { goto error; } break; } if (skip != 0) { for (j = i + skip; j < objc; j++) { argv[j - skip] = argv[j]; } objc -= skip; i -= 1; } } if (fd[0] == -1) { if (inputLiteral != NULL) { /* * The input for the first process is immediate data coming from * Tcl. Create a temporary file for it and put the data into the * file. */ fd[0] = CreateTempFile(inputLiteral); if (fd[0] < 0) { Tcl_AppendResult(interp, "can't create input file for command: ", Tcl_PosixError(interp), (char *)NULL); goto error; } isOpen[0] = TRUE; } else if (stdinPipePtr != NULL) { /* * The input for the first process in the pipeline is to come from * a pipe that can be written from by the caller. */ if (CreatePipe(interp, &fd[0], stdinPipePtr) != TCL_OK) { goto error; } isOpen[0] = TRUE; } else { /* * The input for the first process comes from stdin. */ fd[0] = 0; } } if (fd[1] == -1) { if (stdoutPipePtr != NULL) { /* * Output from the last process in the pipeline is to go to a pipe * that can be read by the caller. */ if (CreatePipe(interp, stdoutPipePtr, &fd[1]) != TCL_OK) { goto error; } isOpen[1] = TRUE; } else { /* * The output for the last process goes to stdout. */ fd[1] = 1; } } if (fd[2] == -1) { if (stderrPipePtr != NULL) { /* * Stderr from the last process in the pipeline is to go to a pipe * that can be read by the caller. */ if (CreatePipe(interp, stderrPipePtr, &fd[2]) != TCL_OK) { goto error; } isOpen[2] = TRUE; } else { /* * Errors from the pipeline go to stderr. */ fd[2] = 2; } } /* * Scan through the objc array, creating a process for each group of * arguments between the "|" characters. */ Tcl_ReapDetachedProcs(); pids = Blt_AssertMalloc(cmdCount * sizeof(int)); curFd[0] = fd[0]; lastArg = 0; /* Suppress compiler warning */ for (i = 0; i < objc; i = lastArg + 1) { int joinThisError; int pid; /* * Convert the program name into native form. */ argv[i] = Tcl_TranslateFileName(interp, argv[i], &execBuffer); if (argv[i] == NULL) { goto error; } /* * Find the end of the curent segment of the pipeline. */ joinThisError = 0; for (lastArg = i + 1; lastArg < objc; lastArg++) { if (argv[lastArg][0] == '|') { if (argv[lastArg][1] == '\0') { break; } if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) { joinThisError = 1; break; } } } argv[lastArg] = NULL; /* * If this is the last segment, use the specified fd[1]. Otherwise * create an intermediate pipe. pipeIn will become the curInFile for * the next segment of the pipe. */ if (lastArg == objc) { curFd[1] = fd[1]; } else { if (CreatePipe(interp, &pipeIn, &curFd[1]) != TCL_OK) { goto error; } } if (joinThisError != 0) { curFd[2] = curFd[1]; } else { curFd[2] = fd[2]; } if (CreateProcess(interp, lastArg - i, argv + i, curFd[0], curFd[1], curFd[2], &pid) != TCL_OK) { goto error; } Tcl_DStringFree(&execBuffer); pids[nPids] = pid; nPids++; /* * Close off our copies of file descriptors that were set up for this * child, then set up the input for the next child. */ if ((curFd[0] >= 0) && (curFd[0] != fd[0])) { CloseFile(curFd[0]); } curFd[0] = pipeIn; pipeIn = -1; if ((curFd[1] >= 0) && (curFd[1] != fd[1])) { CloseFile(curFd[1]); } curFd[1] = -1; } *pidArrayPtr = pids; /* * All done. Cleanup open files lying around and then return. */ cleanup: Tcl_DStringFree(&execBuffer); for (i = 0; i < 3; i++) { if (isOpen[i]) { CloseFile(fd[i]); } } if (argv != NULL) { Blt_Free(argv); } return nPids; /* * An error occured. There could have been extra files open, such as * pipes between children. Clean them all up. Detach any child processes * that have been created. */ error: if (pipeIn >= 0) { CloseFile(pipeIn); } if ((curFd[2] >= 0) && (curFd[2] != fd[2])) { CloseFile(curFd[2]); } if ((curFd[1] >= 0) && (curFd[1] != fd[1])) { CloseFile(curFd[1]); } if ((curFd[0] >= 0) && (curFd[0] != fd[0])) { CloseFile(curFd[0]); } if ((stdinPipePtr != NULL) && (*stdinPipePtr >= 0)) { CloseFile(*stdinPipePtr); *stdinPipePtr = -1; } if ((stdoutPipePtr != NULL) && (*stdoutPipePtr >= 0)) { CloseFile(*stdoutPipePtr); *stdoutPipePtr = -1; } if ((stderrPipePtr != NULL) && (*stderrPipePtr >= 0)) { CloseFile(*stderrPipePtr); *stderrPipePtr = -1; } if (pids != NULL) { for (i = 0; i < nPids; i++) { if (pids[i] != -1) { Tcl_DetachPids(1, (Tcl_Pid *)(pids + i)); } } Blt_Free(pids); } nPids = -1; goto cleanup; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTreeXml.c������������������������������������������������������������������0000644�0001750�0001750�00000066314�11462120063�015266� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltTreeXml.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #include "config.h" #include <tcl.h> #include <bltSwitch.h> #include <bltAssert.h> #include <bltAlloc.h> #include <bltTree.h> #include <string.h> #ifdef HAVE_CTYPE_H # include <ctype.h> #endif /* HAVE_CTYPE_H */ #define TRUE 1 #define FALSE 0 /* * The macro below is used to modify a "char" value (e.g. by casting * it to an unsigned character) so that it can be used safely with * macros such as isspace. */ #define UCHAR(c) ((unsigned char) (c)) DLLEXPORT extern Tcl_AppInitProc Blt_TreeXmlInit; static Blt_TreeImportProc ImportXmlProc; static Blt_TreeExportProc ExportXmlProc; extern char *Blt_Itoa(int); /* * Format Import Export * xml file/data file/data * html file/data file/data * * $tree import xml $node fileName -data dataString * $table export xml $node -file defaultFileName * $tree import html $node -file fileName -data dataString * $table export html $node -file defaultFileName */ /* * ImportSwitches -- */ typedef struct { Tcl_Obj *fileObj; /* Name of file representing the channel. */ Tcl_Obj *dataObj; Tcl_Interp *interp; unsigned int flags; Blt_TreeNode root; } ImportSwitches; #define IMPORT_TRIMCDATA (1<<0) #define IMPORT_OVERWRITE (1<<1) #define IMPORT_ATTRIBUTES (1<<2) #define IMPORT_BASEURI (1<<3) #define IMPORT_CDATA (1<<4) #define IMPORT_COMMENTS (1<<5) #define IMPORT_DTD (1<<6) #define IMPORT_LOCATION (1<<7) #define IMPORT_PI (1<<8) #define IMPORT_NS (1<<9) #define IMPORT_ALL (IMPORT_ATTRIBUTES | IMPORT_COMMENTS | IMPORT_CDATA |\ IMPORT_DTD | IMPORT_PI | IMPORT_LOCATION | \ IMPORT_BASEURI) #define SYM_BASEURI "#baseuri" #define SYM_BYTEIDX "#byteindex" #define SYM_CDATA "#cdata" #define SYM_COLNO "#column" #define SYM_COMMENT "#comment" #define SYM_LINENO "#line" #define SYM_NS "#namespace" #define SYM_NOTATION "#notation" #define SYM_PI "#pi" #define SYM_PUBID "#publicid" #define SYM_SYSID "#systemid" extern Blt_SwitchParseProc Blt_TreeNodeSwitchProc; static Blt_SwitchCustom nodeSwitch = { Blt_TreeNodeSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_BITMASK, "-all", "", Blt_Offset(ImportSwitches, flags), 0, IMPORT_ALL}, {BLT_SWITCH_BOOLEAN, "-comments", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_COMMENTS}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(ImportSwitches, dataObj), 0, 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ImportSwitches, fileObj), 0, 0}, {BLT_SWITCH_BOOLEAN, "-locations", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_LOCATION}, {BLT_SWITCH_CUSTOM, "-root", "node", Blt_Offset(ImportSwitches, root), 0, 0, &nodeSwitch}, {BLT_SWITCH_BOOLEAN, "-attributes", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_ATTRIBUTES}, {BLT_SWITCH_BOOLEAN, "-namespace", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_NS}, {BLT_SWITCH_BOOLEAN, "-cdata", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_CDATA}, {BLT_SWITCH_BOOLEAN, "-overwrite", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_OVERWRITE}, {BLT_SWITCH_BOOLEAN, "-processinginstructions", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_PI}, {BLT_SWITCH_BOOLEAN, "-trimwhitespace", "bool", Blt_Offset(ImportSwitches, flags), 0, IMPORT_TRIMCDATA}, {BLT_SWITCH_END} }; /* * ExportSwitches -- */ typedef struct { Tcl_Obj *fileObj; Tcl_Obj *dataObj; Blt_TreeNode root; /* Private fields. */ Tcl_Interp *interp; unsigned int flags; Tcl_Channel channel; /* If non-NULL, channel to write output to. */ Tcl_DString *dsPtr; } ExportSwitches; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(ExportSwitches, dataObj), 0, 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ExportSwitches, fileObj), 0, 0}, {BLT_SWITCH_END} }; #ifdef HAVE_LIBEXPAT #include <expat.h> typedef struct { Blt_Tree tree; Blt_TreeNode root; Blt_TreeNode parent; Tcl_Interp *interp; int flags; Blt_HashTable stringTable; XML_Parser parser; } ImportData; static Tcl_Obj * GetStringObj(ImportData *importPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&importPtr->stringTable, string, &isNew); if (isNew) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Tcl_IncrRefCount(objPtr); Blt_SetHashValue(hPtr, objPtr); return objPtr; } return Blt_GetHashValue(hPtr); } static const char * GetBaseUri(ImportData *importPtr, Blt_TreeNode node) { Blt_TreeNode top; top = Blt_Tree_ParentNode(importPtr->root); do { if (Blt_Tree_ValueExists(importPtr->tree, node, SYM_BASEURI)) { Tcl_Obj *objPtr; if (Blt_Tree_GetValue((Tcl_Interp *)NULL, importPtr->tree, node, SYM_BASEURI, &objPtr) == TCL_OK) { return Tcl_GetString(objPtr); } } node = Blt_Tree_ParentNode(node); } while (node != top); return NULL; } static void SetLocation(ImportData *importPtr, Blt_TreeNode node) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, node, SYM_LINENO, Tcl_NewIntObj(XML_GetCurrentLineNumber(importPtr->parser))); Blt_Tree_SetValue(importPtr->interp, importPtr->tree, node, SYM_COLNO, Tcl_NewIntObj(XML_GetCurrentColumnNumber(importPtr->parser))); Blt_Tree_SetValue(importPtr->interp, importPtr->tree, node, SYM_BYTEIDX, Tcl_NewLongObj(XML_GetCurrentByteIndex(importPtr->parser))); } static void GetNotationProc( void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId) { ImportData *importPtr = userData; if (publicId != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->parent, SYM_PUBID, Tcl_NewStringObj(publicId, -1)); } if (systemId != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->parent, SYM_SYSID, Tcl_NewStringObj(systemId, -1)); } if (base != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->parent, SYM_BASEURI, Tcl_NewStringObj(base, -1)); } if (notationName != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->parent, SYM_NOTATION, Tcl_NewStringObj(notationName, -1)); } } static void GetCommentProc(void *userData, const XML_Char *string) { ImportData *importPtr = userData; if ((importPtr->flags & IMPORT_DTD) == 0) { Blt_Tree tree; Blt_TreeNode child; Tcl_Obj *objPtr; tree = importPtr->tree; objPtr = GetStringObj(importPtr, string); child = Blt_Tree_CreateNode(tree, importPtr->parent, SYM_COMMENT, -1); Blt_Tree_SetValue(importPtr->interp, tree, child, SYM_COMMENT, objPtr); if (importPtr->flags & IMPORT_LOCATION) { SetLocation(importPtr, child); } } } static void GetProcessingInstructionProc( void *userData, const char *target, const char *data) { ImportData *importPtr = userData; if ((importPtr->flags & IMPORT_DTD) == 0) { Tcl_Obj *objPtr; Blt_Tree tree; Blt_TreeNode child; tree = importPtr->tree; objPtr = GetStringObj(importPtr, data); child = Blt_Tree_CreateNode(tree, importPtr->parent, SYM_PI, -1); Blt_Tree_SetValue(importPtr->interp, tree, child, target, objPtr); if (importPtr->flags & IMPORT_LOCATION) { SetLocation(importPtr, child); } } } static void GetCharacterDataProc(void *userData, const XML_Char *string, int length) { ImportData *importPtr = userData; Blt_Tree tree; Blt_TreeNode child; Tcl_Obj *objPtr; if (importPtr->flags & IMPORT_TRIMCDATA) { const char *p, *pend; for (p = string, pend = p + length; p < pend; p++) { if (!isspace(UCHAR(*p))) { break; } } if (p == pend) { return; } length = pend - p; string = p; } tree = importPtr->tree; child = Blt_Tree_LastChild(importPtr->parent); if ((child != NULL) && (strcmp(Blt_Tree_NodeLabel(child), SYM_CDATA)==0)) { /* Last child added was a CDATA node, append new data to it. */ if (Blt_Tree_GetValue(importPtr->interp, tree, child, SYM_CDATA, &objPtr) == TCL_OK) { Tcl_AppendToObj(objPtr, string, length); return; } } objPtr = Tcl_NewStringObj(string, length); child = Blt_Tree_CreateNode(tree, importPtr->parent, SYM_CDATA,-1); Blt_Tree_SetValue(importPtr->interp, tree, child, SYM_CDATA, objPtr); if (importPtr->flags & IMPORT_LOCATION) { SetLocation(importPtr, child); } } static void DumpStringTable(Blt_HashTable *tablePtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_Obj *objPtr; objPtr = Blt_GetHashValue(hPtr); Tcl_DecrRefCount(objPtr); } Blt_DeleteHashTable(tablePtr); } static void StartDocTypeProc( void *userData, const char *doctypeName, const char *systemId, const char *publicId, int has_internal_subset) { ImportData *importPtr = userData; if (publicId != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->root, SYM_PUBID, Tcl_NewStringObj(publicId, -1)); } if (systemId != NULL) { Blt_Tree_SetValue(importPtr->interp, importPtr->tree, importPtr->root, SYM_SYSID, Tcl_NewStringObj(systemId, -1)); } importPtr->flags |= IMPORT_DTD; } static void EndDocTypeProc(void *userData) { ImportData *importPtr = userData; importPtr->flags &= ~IMPORT_DTD; } static void StartElementProc(void *userData, const char *element, const char **attr) { Blt_TreeNode child; ImportData *importPtr = userData; Blt_Tree tree; tree = importPtr->tree; child = NULL; if (importPtr->flags & IMPORT_OVERWRITE) { child = Blt_Tree_FindChild(importPtr->parent, element); } if (child == NULL) { child = Blt_Tree_CreateNode(tree, importPtr->parent, element, -1); } if (importPtr->flags & IMPORT_ATTRIBUTES) { const char **p; for (p = attr; *p != NULL; p += 2) { Tcl_Obj *objPtr; objPtr = GetStringObj(importPtr, *(p+1)); Blt_Tree_SetValue(importPtr->interp, tree, child, *p, objPtr); } } if (importPtr->flags & IMPORT_LOCATION) { SetLocation(importPtr, child); } if (importPtr->flags & IMPORT_BASEURI) { const char *oldBase, *newBase; newBase = XML_GetBase(importPtr->parser); oldBase = GetBaseUri(importPtr, importPtr->parent); assert(oldBase != NULL); if (strcmp(oldBase, newBase) != 0) { Blt_Tree_SetValue(importPtr->interp, tree, importPtr->parent, SYM_BASEURI, Tcl_NewStringObj(newBase, -1)); } } importPtr->parent = child; /* Increase depth. */ } static void EndElementProc(void *userData, const char *element) { ImportData *importPtr = userData; importPtr->parent = Blt_Tree_ParentNode(importPtr->parent); } static int ReadXmlFromFile( Tcl_Interp *interp, XML_Parser parser, const char *fileName) { int closeChannel; int done; Tcl_Channel channel; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return FALSE; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); return FALSE; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return FALSE; /* Can't open dump file. */ } } done = FALSE; while (!done) { int length; #define BUFFSIZE 8191 char buffer[BUFFSIZE+1]; length = Tcl_Read(channel, buffer, sizeof(char) * BUFFSIZE); if (length < 0) { Tcl_AppendResult(interp, "\nread error: ", Tcl_PosixError(interp), (char *)NULL); if (closeChannel) { Tcl_Close(interp, channel); } return FALSE; } done = Tcl_Eof(channel); if (!XML_Parse(parser, buffer, length, done)) { Tcl_AppendResult(interp, "\n", fileName, ":", Blt_Itoa(XML_GetCurrentLineNumber(parser)), ": ", "error: ", XML_ErrorString(XML_GetErrorCode(parser)), (char *)NULL); Tcl_AppendResult(interp, "\n", fileName, ":", Blt_Itoa(XML_GetCurrentByteIndex(parser)), ": ", "error: ", XML_ErrorString(XML_GetErrorCode(parser)), (char *)NULL); fprintf(stderr, "buffer=%.*s\n", (int)XML_GetCurrentByteIndex(parser), buffer); if (closeChannel) { Tcl_Close(interp, channel); } return FALSE; } } if (closeChannel) { Tcl_Close(interp, channel); } return TRUE; } static int GetExternalEntityRefProc( XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId) { ImportData *importPtr; Tcl_DString ds; Tcl_Interp *interp; XML_Parser newParser, oldParser; int result; importPtr = XML_GetUserData(parser); assert(importPtr != NULL); interp = importPtr->interp; Tcl_DStringInit(&ds); if ((base != NULL) && (Tcl_GetPathType(systemId) == TCL_PATH_RELATIVE)) { const char **argv; const char **baseNames, **sysIdNames; int argc; int i, j; int nBase, nSysId; Tcl_SplitPath(base, &nBase, &baseNames); Tcl_SplitPath(systemId, &nSysId, &sysIdNames); argc = nBase + nSysId; argv = Blt_Malloc(sizeof(char *) * (argc + 1)); if (argv == NULL) { return FALSE; } for (i = 0; i < nBase; i++) { argv[i] = baseNames[i]; } for (j = 0; j < nSysId; j++, i++) { argv[i] = sysIdNames[j]; } argv[i] = NULL; Tcl_JoinPath(argc, argv, &ds); Blt_Free(baseNames); Blt_Free(sysIdNames); Blt_Free(argv); } else { Tcl_DStringAppend(&ds, systemId, -1); } newParser = XML_ExternalEntityParserCreate(parser, context, NULL); if (newParser == NULL) { Tcl_AppendResult(interp, "can't create external entity ref parser", (char *)NULL); return FALSE; } oldParser = importPtr->parser; importPtr->parser = newParser; result = ReadXmlFromFile(interp, newParser, Tcl_DStringValue(&ds)); importPtr->parser = oldParser; Tcl_DStringFree(&ds); XML_ParserFree(newParser); return result; } static int ImportXmlFile( Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode parent, Tcl_Obj *objPtr, unsigned int flags) { ImportData import; XML_Parser parser; int result; char *fileName; if (flags & IMPORT_NS) { parser = XML_ParserCreateNS(NULL, ':'); } else { parser = XML_ParserCreate(NULL); } if (parser == NULL) { Tcl_AppendResult(interp, "can't create XML parser", (char *)NULL); return TCL_ERROR; } import.flags = flags; import.interp = interp; import.parent = parent; import.parser = parser; import.root = parent; import.tree = tree; Blt_InitHashTable(&import.stringTable, BLT_STRING_KEYS); XML_SetUserData(parser, &import); fileName = Tcl_GetString(objPtr); /* Set baseURI */ { Tcl_DString ds; int argc; const char **argv; Tcl_DStringInit(&ds); Tcl_SplitPath(fileName, &argc, &argv); Tcl_JoinPath(argc - 1, argv, &ds); XML_SetBase(parser, Tcl_DStringValue(&ds)); if (flags & IMPORT_BASEURI) { Blt_Tree_SetValue(interp, tree, parent, SYM_BASEURI, Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds))); } Blt_Free(argv); Tcl_DStringFree(&ds); } XML_SetExternalEntityRefHandler(parser, GetExternalEntityRefProc); XML_SetElementHandler(parser, StartElementProc, EndElementProc); if (flags & IMPORT_CDATA) { XML_SetCharacterDataHandler(parser, GetCharacterDataProc); } if (flags & IMPORT_BASEURI) { XML_SetNotationDeclHandler(parser, GetNotationProc); XML_SetDoctypeDeclHandler(parser, StartDocTypeProc, EndDocTypeProc); } if (flags & IMPORT_PI) { XML_SetProcessingInstructionHandler(parser, GetProcessingInstructionProc); } if (flags & IMPORT_COMMENTS) { XML_SetCommentHandler(parser, GetCommentProc); } result = ReadXmlFromFile(interp, parser, fileName); XML_ParserFree(parser); DumpStringTable(&import.stringTable); return (result) ? TCL_OK : TCL_ERROR; } static int ImportXmlData( Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode parent, Tcl_Obj *dataObjPtr, unsigned int flags) { ImportData import; XML_Parser parser; char *string; int length; int result; if (flags & IMPORT_NS) { parser = XML_ParserCreateNS(NULL, ':'); } else { parser = XML_ParserCreate(NULL); } if (parser == NULL) { Tcl_AppendResult(interp, "can't create parser", (char *)NULL); return TCL_ERROR; } import.flags = flags; import.interp = interp; import.parent = parent; import.parser = parser; import.root = parent; import.tree = tree; Blt_InitHashTable(&import.stringTable, BLT_STRING_KEYS); XML_SetBase(parser, "."); XML_SetUserData(parser, &import); XML_SetExternalEntityRefHandler(parser, GetExternalEntityRefProc); XML_SetElementHandler(parser, StartElementProc, EndElementProc); if (flags & IMPORT_CDATA) { XML_SetCharacterDataHandler(parser, GetCharacterDataProc); } if (flags & IMPORT_BASEURI) { XML_SetNotationDeclHandler(parser, GetNotationProc); XML_SetDoctypeDeclHandler(parser, StartDocTypeProc, EndDocTypeProc); } if (flags & IMPORT_PI) { XML_SetProcessingInstructionHandler(parser, GetProcessingInstructionProc); } if (flags & IMPORT_COMMENTS) { XML_SetCommentHandler(parser, GetCommentProc); } string = Tcl_GetStringFromObj(dataObjPtr, &length); result = XML_Parse(parser, string, length, 1); if (!result) { Tcl_AppendResult(interp, "\nparse error at line ", Blt_Itoa(XML_GetCurrentLineNumber(parser)), ": ", XML_ErrorString(XML_GetErrorCode(parser)), (char *)NULL); } XML_ParserFree(parser); DumpStringTable(&import.stringTable); return (result) ? TCL_OK : TCL_ERROR; } static int ImportXmlProc( Tcl_Interp *interp, Blt_Tree tree, int objc, Tcl_Obj *const *objv) { int result; ImportSwitches switches; memset(&switches, 0, sizeof(switches)); nodeSwitch.clientData = tree; switches.root = Blt_Tree_RootNode(tree); switches.flags = IMPORT_ATTRIBUTES | IMPORT_CDATA; if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if ((switches.dataObj != NULL) && (switches.fileObj != NULL)) { Tcl_AppendResult(interp, "can't set both -file and -data switches.", (char *)NULL); goto error; } if (switches.fileObj != NULL) { result = ImportXmlFile(interp, tree, switches.root, switches.fileObj, switches.flags); } else if (switches.dataObj != NULL) { result = ImportXmlData(interp, tree, switches.root, switches.dataObj, switches.flags); } else { result = TCL_OK; } error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return result; } #endif /* HAVE_LIBEXPAT */ static int XmlFlush(ExportSwitches *exportPtr) { int nWritten; char *line; int length; line = Tcl_DStringValue(exportPtr->dsPtr); length = Tcl_DStringLength(exportPtr->dsPtr); nWritten = Tcl_Write(exportPtr->channel, line, length); if (nWritten != length) { Tcl_AppendResult(exportPtr->interp, "can't write xml element: ", Tcl_PosixError(exportPtr->interp), (char *)NULL); return TCL_ERROR; } Tcl_DStringSetLength(exportPtr->dsPtr, 0); return TCL_OK; } static void XmlPutEscapeString(const char *from, size_t length, ExportSwitches *exportPtr) { const char *p, *pend; for (p = from, pend = from + length; p < pend; /*empty*/) { switch (*p) { case '\'': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&apos;", 6); break; case '&': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&amp;", 5); break; case '>': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&gt;", 4); break; case '<': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&lt;", 4); break; case '"': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&quot;", 6); break; default: p++; break; } } if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } } static void XmlOpenStartElement(ExportSwitches *exportPtr, Blt_TreeNode node) { size_t i; if (exportPtr->channel != NULL) { Tcl_DStringSetLength(exportPtr->dsPtr, 0); } for (i = 0; i < Blt_Tree_NodeDepth(node); i++) { Tcl_DStringAppend(exportPtr->dsPtr, " ", 2); } Tcl_DStringAppend(exportPtr->dsPtr, "<", 1); Tcl_DStringAppend(exportPtr->dsPtr, Blt_Tree_NodeLabel(node), -1); } static int XmlCloseStartElement(ExportSwitches *exportPtr) { Tcl_DStringAppend(exportPtr->dsPtr, ">\n", 2); if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static int XmlEndElement(ExportSwitches *exportPtr, Blt_TreeNode node) { size_t i; Tcl_DStringAppend(exportPtr->dsPtr, "\n", 1); for (i = 0; i < Blt_Tree_NodeDepth(node); i++) { Tcl_DStringAppend(exportPtr->dsPtr, " ", 2); } Tcl_DStringAppend(exportPtr->dsPtr, "</", 2); Tcl_DStringAppend(exportPtr->dsPtr, Blt_Tree_NodeLabel(node), -1); Tcl_DStringAppend(exportPtr->dsPtr, ">\n", 2); if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static void XmlAppendAttribute( ExportSwitches *exportPtr, const char *attrName, const char *value, int length) { size_t valueLen; if (length < 0) { valueLen = strlen(value); } else { valueLen = (size_t)length; } Tcl_DStringAppend(exportPtr->dsPtr, " ", 1); Tcl_DStringAppend(exportPtr->dsPtr, attrName, -1); Tcl_DStringAppend(exportPtr->dsPtr, "=", 1); Tcl_DStringAppend(exportPtr->dsPtr, "\"", 1); XmlPutEscapeString(value, valueLen, exportPtr); Tcl_DStringAppend(exportPtr->dsPtr, "\"", 1); } static void XmlAppendCharacterData( ExportSwitches *exportPtr, const char *string, int length) { if (length < 0) { length = strlen(string); } Tcl_DStringAppend(exportPtr->dsPtr, "CDATA=(", -1); XmlPutEscapeString(string, length, exportPtr); Tcl_DStringAppend(exportPtr->dsPtr, ")", -1); } static int XmlExportElement(Blt_Tree tree, Blt_TreeNode parent, ExportSwitches *exportPtr) { Blt_TreeKey key; Blt_TreeKeyIterator iter; Blt_TreeNode child; if (strcmp(Blt_Tree_NodeLabel(parent), SYM_CDATA) == 0) { Tcl_Obj *valueObjPtr; const char *value; int nBytes; /* Just output the CDATA field. */ if (Blt_Tree_GetValue(exportPtr->interp, tree, parent, SYM_CDATA, &valueObjPtr) != TCL_OK) { return TCL_ERROR; } value = Tcl_GetStringFromObj(valueObjPtr, &nBytes); XmlAppendCharacterData(exportPtr, value, nBytes); return TCL_OK; } XmlOpenStartElement(exportPtr, parent); for (key = Blt_Tree_FirstKey(tree, parent, &iter); key != NULL; key = Blt_Tree_NextKey(tree, &iter)) { Tcl_Obj *valueObjPtr; const char *value; int nBytes; if (Blt_Tree_GetValueByKey(exportPtr->interp, tree, parent, key, &valueObjPtr) != TCL_OK) { return TCL_ERROR; } value = Tcl_GetStringFromObj(valueObjPtr, &nBytes); XmlAppendAttribute(exportPtr, key, value, nBytes); } XmlCloseStartElement(exportPtr); for (child = Blt_Tree_FirstChild(parent); child != NULL; child = Blt_Tree_NextSibling(child)) { if (XmlExportElement(tree, child, exportPtr) != TCL_OK) { return TCL_ERROR; } } return XmlEndElement(exportPtr, parent); } static int XmlExport(Blt_Tree tree, ExportSwitches *exportPtr) { if (XmlExportElement(tree, exportPtr->root, exportPtr) != TCL_OK) { return TCL_ERROR; } if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static int ExportXmlProc( Tcl_Interp *interp, Blt_Tree tree, int objc, Tcl_Obj *const *objv) { ExportSwitches switches; Tcl_Channel channel; Tcl_DString ds; int closeChannel; int result; closeChannel = FALSE; channel = NULL; Tcl_DStringInit(&ds); memset(&switches, 0, sizeof(switches)); nodeSwitch.clientData = tree; switches.root = Blt_Tree_RootNode(tree); switches.flags = IMPORT_ATTRIBUTES | IMPORT_CDATA; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3 , objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if (switches.fileObj != NULL) { char *fileName; closeChannel = TRUE; fileName = Tcl_GetString(switches.fileObj); if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { goto error; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for writing", (char *)NULL); goto error; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { goto error; /* Can't open export file. */ } } } switches.interp = interp; switches.dsPtr = &ds; switches.channel = channel; result = XmlExport(tree, &switches); if ((switches.channel == NULL) && (result == TCL_OK)) { Tcl_DStringResult(interp, &ds); } error: Tcl_DStringFree(&ds); if (closeChannel) { Tcl_Close(interp, channel); } Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return result; } int Blt_TreeXmlInit(Tcl_Interp *interp) { if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_tree_xml", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_Tree_RegisterFormat(interp, "xml", /* Name of format. */ #ifdef HAVE_LIBEXPAT ImportXmlProc, /* Import procedure. */ #else NULL, /* Import procedure. */ #endif /* HAVE_LIBEXPAT */ ExportXmlProc); /* Export procedure. */ } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDataTable.h����������������������������������������������������������������0000644�0001750�0001750�00000066264�11462120062�015537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltDataTable.h -- * * Copyright 1998-2004 George A. Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_DATATABLE_H #define _BLT_DATATABLE_H #include <bltChain.h> #include <bltHash.h> typedef struct _Blt_TableTags *Blt_TableTags; typedef enum { TABLE_COLUMN_TYPE_UNKNOWN=-1, TABLE_COLUMN_TYPE_STRING, TABLE_COLUMN_TYPE_INT, TABLE_COLUMN_TYPE_DOUBLE, TABLE_COLUMN_TYPE_LONG, } Blt_TableColumnType; typedef struct _Blt_TableValue { union { long l; double d; Tcl_WideInt w; } datum; /* Internal representation of data: * used to speed comparisons, sorting, * etc. */ char *string; /* String representation of value. If * NULL, indicates empty value. */ } *Blt_TableValue; typedef struct _Blt_TableHeader { const char *label; /* Label of row or column. */ long index; /* Reverse lookup offset-to-index. */ long offset; unsigned int flags; } *Blt_TableHeader; typedef struct _Blt_TableRow { const char *label; /* Label of row or column. */ long index; /* Reverse lookup offset-to-index. */ long offset; unsigned int flags; } *Blt_TableRow; typedef struct _Blt_TableColumn { const char *label; /* Label of row or column. */ long index; /* Reverse lookup offset-to-index. */ long offset; unsigned short flags; Blt_TableColumnType type; } *Blt_TableColumn; typedef struct { const char *name; long headerSize; } Blt_TableRowColumnClass; /* * Blt_TableRowColumn -- * * Structure representing a row or column in the table. */ typedef struct _Blt_TableRowColumn { Blt_TableRowColumnClass *classPtr; Blt_Pool headerPool; long nAllocated; /* Length of allocated array * below. May exceed the number of row * or column headers used. */ long nUsed; Blt_TableHeader *map; /* Array of row or column headers. */ Blt_Chain freeList; /* Tracks free row or column * headers. */ Blt_HashTable labelTable; /* Hash table of labels. Maps labels * to table offsets. */ long nextId; /* Used to generate default labels. */ } Blt_TableRowColumn; /* * Blt_TableCore -- * * Structure representing a table object. * * The table object is an array of column vectors. Each vector is an * array of Blt_TableValue's, representing the data for the column. * Empty row entries are designated by 0 length values. Column vectors are * allocated when needed. Every column in the table has the same length. * * Rows and columns are indexed by a map of pointers to headers. This * map represents the order of the rows or columns. A table object can * be shared by several clients. When a client wants to use a table * object, it is given a token that represents the table. The object * tracks its clients by its token. When all clients have released their * tokens, the tuple object is automatically destroyed. */ typedef struct _Blt_TableCore { Blt_TableRowColumn rows, columns; Blt_TableValue *data; /* Array of column vector pointers */ unsigned int flags; /* Internal flags. See definitions * below. */ Blt_Chain clients; /* List of clients using this table */ unsigned long mtime, ctime; unsigned int notifyFlags; /* Notification flags. See definitions * below. */ int notifyHold; } Blt_TableCore; /* * Blt_Table -- * * A client is uniquely identified by a combination of its name and the * originating namespace. Two table objects in the same interpreter can * have similar names but must reside in different namespaces. * * Two or more clients can share the same table object. Each client * structure which acts as a ticket for the underlying table object. * Clients can designate notifier routines that are automatically invoked * by the table object whenever the table is changed is specific ways by * other clients. */ typedef struct _Blt_Table { unsigned int magic; /* Magic value indicating whether a * generic pointer is really a * datatable token or not. */ const char *name; /* Fully namespace-qualified name of * the client. */ Blt_TableCore *corePtr; /* Pointer to the structure containing * the master information about the * table used by the client. If NULL, * this indicates that the table has * been destroyed (but as of yet, this * client hasn't recognized it). */ Tcl_Interp *interp; Blt_HashTable *tablePtr; /* Interpreter-specific global hash * table of all datatable clients. * Each entry is a chain of clients * that are sharing the same core * datatable. */ Blt_HashEntry *hPtr; /* This client's entry in the above * hash table. This is a list of * clients that * all using the core * datatable. */ Blt_ChainLink link2; /* This client's entry in the list * found in the above list (hashtable * entry). */ Blt_ChainLink link; /* Pointer into the server's chain of * clients. */ Blt_HashTable *rowTags; Blt_HashTable *columnTags; Blt_Chain traces; /* Chain of traces. */ Blt_Chain columnNotifiers; /* Chain of event handlers. */ Blt_Chain rowNotifiers; /* Chain of event handlers. */ Blt_TableTags tags; Blt_HashTable *keyTables; /* Array of primary keys. */ long nKeys; /* Length of the above array. */ Blt_TableRow *masterKey; /* Master key entry. */ Blt_HashTable masterKeyTable; Blt_Chain primaryKeys; unsigned int flags; } *Blt_Table; BLT_EXTERN void Blt_Table_ReleaseTags(Blt_Table table); BLT_EXTERN int Blt_Table_TableExists(Tcl_Interp *interp, const char *name); BLT_EXTERN int Blt_Table_CreateTable(Tcl_Interp *interp, const char *name, Blt_Table *tablePtr); BLT_EXTERN int Blt_Table_Open(Tcl_Interp *interp, const char *name, Blt_Table *tablePtr); BLT_EXTERN void Blt_Table_Close(Blt_Table table); BLT_EXTERN int Blt_Table_SameTableObject(Blt_Table table1, Blt_Table table2); BLT_EXTERN const char *Blt_Table_Name(Blt_Table table); BLT_EXTERN Blt_TableRow Blt_Table_FindRowByLabel(Blt_Table table, const char *label); BLT_EXTERN Blt_TableColumn Blt_Table_FindColumnByLabel(Blt_Table table, const char *label); BLT_EXTERN Blt_TableRow Blt_Table_FindRowByIndex(Blt_Table table, long index); BLT_EXTERN Blt_TableColumn Blt_Table_FindColumnByIndex(Blt_Table table, long index); BLT_EXTERN int Blt_Table_SetRowLabel(Tcl_Interp *interp, Blt_Table table, Blt_TableRow row, const char *label); BLT_EXTERN int Blt_Table_SetColumnLabel(Tcl_Interp *interp, Blt_Table table, Blt_TableColumn column, const char *label); BLT_EXTERN Blt_TableColumnType Blt_Table_ColumnType(Blt_TableColumn column); BLT_EXTERN Blt_TableColumnType Blt_Table_GetColumnType(const char *typeName); BLT_EXTERN int Blt_Table_SetColumnType(Blt_Table table, Blt_TableColumn column, Blt_TableColumnType type); BLT_EXTERN const char *Blt_Table_NameOfType(Blt_TableColumnType type); BLT_EXTERN int Blt_Table_SetColumnTag(Tcl_Interp *interp, Blt_Table table, Blt_TableColumn column, const char *tagName); BLT_EXTERN int Blt_Table_SetRowTag(Tcl_Interp *interp, Blt_Table table, Blt_TableRow row, const char *tagName); BLT_EXTERN Blt_TableRow Blt_Table_CreateRow(Tcl_Interp *interp, Blt_Table table, const char *label); BLT_EXTERN Blt_TableColumn Blt_Table_CreateColumn(Tcl_Interp *interp, Blt_Table table, const char *label); BLT_EXTERN int Blt_Table_ExtendRows(Tcl_Interp *interp, Blt_Table table, size_t n, Blt_TableRow *rows); BLT_EXTERN int Blt_Table_ExtendColumns(Tcl_Interp *interp, Blt_Table table, size_t n, Blt_TableColumn *columms); BLT_EXTERN int Blt_Table_DeleteRow(Blt_Table table, Blt_TableRow row); BLT_EXTERN int Blt_Table_DeleteColumn(Blt_Table table, Blt_TableColumn column); BLT_EXTERN int Blt_Table_MoveRows(Tcl_Interp *interp, Blt_Table table, Blt_TableRow from, Blt_TableRow to, size_t n); BLT_EXTERN int Blt_Table_MoveColumns(Tcl_Interp *interp, Blt_Table table, Blt_TableColumn from, Blt_TableColumn to, size_t n); BLT_EXTERN Tcl_Obj *Blt_Table_GetObj(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN int Blt_Table_SetObj(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, Tcl_Obj *objPtr); BLT_EXTERN const char *Blt_Table_GetString(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN int Blt_Table_SetString(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, const char *string, int length); BLT_EXTERN int Blt_Table_AppendString(Tcl_Interp *interp, Blt_Table table, Blt_TableRow row, Blt_TableColumn column, const char *string, int length); BLT_EXTERN double Blt_Table_GetDouble(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN int Blt_Table_SetDouble(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, double value); BLT_EXTERN long Blt_Table_GetLong(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, long defValue); BLT_EXTERN int Blt_Table_SetLong(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, long value); BLT_EXTERN Blt_TableValue Blt_Table_GetValue(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN int Blt_Table_SetValue(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, Blt_TableValue value); BLT_EXTERN int Blt_Table_UnsetValue(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN int Blt_Table_ValueExists(Blt_Table table, Blt_TableRow row, Blt_TableColumn column); BLT_EXTERN Blt_HashTable *Blt_Table_FindRowTagTable(Blt_Table table, const char *tagName); BLT_EXTERN Blt_HashTable *Blt_Table_FindColumnTagTable(Blt_Table table, const char *tagName); BLT_EXTERN Blt_Chain Blt_Table_RowTags(Blt_Table table, Blt_TableRow row); BLT_EXTERN Blt_Chain Blt_Table_ColumnTags(Blt_Table table, Blt_TableColumn column); BLT_EXTERN Blt_Chain Blt_Table_Traces(Blt_Table table); BLT_EXTERN int Blt_Table_TagsAreShared(Blt_Table table); BLT_EXTERN int Blt_Table_HasRowTag(Blt_Table table, Blt_TableRow row, const char *tagName); BLT_EXTERN int Blt_Table_HasColumnTag(Blt_Table table, Blt_TableColumn column, const char *tagName); BLT_EXTERN void Blt_Table_AddColumnTag(Blt_Table table, Blt_TableColumn column, const char *tagName); BLT_EXTERN void Blt_Table_AddRowTag(Blt_Table table, Blt_TableRow row, const char *tagName); BLT_EXTERN int Blt_Table_ForgetRowTag(Tcl_Interp *interp, Blt_Table table, const char *tagName); BLT_EXTERN int Blt_Table_ForgetColumnTag(Tcl_Interp *interp, Blt_Table table, const char *tagName); BLT_EXTERN int Blt_Table_UnsetRowTag(Tcl_Interp *interp, Blt_Table table, Blt_TableRow row, const char *tagName); BLT_EXTERN int Blt_Table_UnsetColumnTag(Tcl_Interp *interp, Blt_Table table, Blt_TableColumn column, const char *tagName); BLT_EXTERN Blt_HashEntry *Blt_Table_FirstRowTag(Blt_Table table, Blt_HashSearch *cursorPtr); BLT_EXTERN Blt_HashEntry *Blt_Table_FirstColumnTag(Blt_Table table, Blt_HashSearch *cursorPtr); BLT_EXTERN Blt_TableColumn Blt_Table_FirstColumn(Blt_Table table); BLT_EXTERN Blt_TableColumn Blt_Table_NextColumn(Blt_Table table, Blt_TableColumn column); BLT_EXTERN Blt_TableRow Blt_Table_FirstRow(Blt_Table table); BLT_EXTERN Blt_TableRow Blt_Table_NextRow(Blt_Table table, Blt_TableRow row); typedef enum { TABLE_SPEC_UNKNOWN, TABLE_SPEC_INDEX, TABLE_SPEC_RANGE, TABLE_SPEC_LABEL, TABLE_SPEC_TAG, } Blt_TableRowColumnSpec; BLT_EXTERN Blt_TableRowColumnSpec Blt_Table_RowSpec(Blt_Table table, Tcl_Obj *objPtr, const char **stringPtr); BLT_EXTERN Blt_TableRowColumnSpec Blt_Table_ColumnSpec(Blt_Table table, Tcl_Obj *objPtr, const char **stringPtr); /* * Blt_TableIterator -- * * Structure representing a trace used by a client of the table. * * Table rows and columns may be tagged with strings. A row may * have many tags. The same tag may be used for many rows. Tags * are used and stored by clients of a table. Tags can also be * shared between clients of the same table. * * Both rowTable and columnTable are hash tables keyed by the * physical row or column location in the table respectively. * This is not the same as the client's view (the order of rows * or columns as seen by the client). This is so that clients * (which may have different views) can share tags without * sharing the same view. */ typedef enum { TABLE_ITERATOR_INDEX, TABLE_ITERATOR_LABEL, TABLE_ITERATOR_TAG, TABLE_ITERATOR_RANGE, TABLE_ITERATOR_ALL, TABLE_ITERATOR_CHAIN } Blt_TableIteratorType; typedef struct _Blt_TableIterator { Blt_Table table; /* Table that we're iterating over. */ Blt_TableIteratorType type; /* Type of iteration: * TABLE_ITERATOR_TAG by row or column tag. * TABLE_ITERATOR_ALL * by every row or column. * TABLE_ITERATOR_INDEX single item: either * label or index. * TABLE_ITERATOR_RANGE over a consecutive * range of indices. * TABLE_ITERATOR_CHAIN over an expanded, * non-overlapping * list of tags, labels, * and indices. */ const char *tagName; /* Used by notification routines to * determine if a tag is being * used. */ long start; /* Starting index. Starting point of * search, saved if iterator is * reused. Used for TABLE_ITERATOR_ALL and * TABLE_ITERATOR_INDEX searches. */ long end; /* Ending index (inclusive). */ long next; /* Next index. */ /* For tag-based searches. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Iterator for tag hash table. */ /* For chain-based searches (multiple tags). */ Blt_Chain chain; /* This chain, unlike the above hash * table must be freed after its * use. */ Blt_ChainLink link; /* Search iterator for chain. */ } Blt_TableIterator; BLT_EXTERN int Blt_Table_IterateRows(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iter); BLT_EXTERN int Blt_Table_IterateColumns(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iter); BLT_EXTERN int Blt_Table_IterateRowsObjv(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_TableIterator *iterPtr); BLT_EXTERN int Blt_Table_IterateColumnsObjv(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_TableIterator *iterPtr); BLT_EXTERN void Blt_Table_FreeIteratorObjv(Blt_TableIterator *iterPtr); BLT_EXTERN void Blt_Table_IterateAllRows(Blt_Table table, Blt_TableIterator *iterPtr); BLT_EXTERN void Blt_Table_IterateAllColumns(Blt_Table table, Blt_TableIterator *iterPtr); BLT_EXTERN Blt_TableRow Blt_Table_FirstTaggedRow(Blt_TableIterator *iter); BLT_EXTERN Blt_TableColumn Blt_Table_FirstTaggedColumn(Blt_TableIterator *iter); BLT_EXTERN Blt_TableRow Blt_Table_NextTaggedRow(Blt_TableIterator *iter); BLT_EXTERN Blt_TableColumn Blt_Table_NextTaggedColumn(Blt_TableIterator *iter); BLT_EXTERN Blt_TableRow Blt_Table_FindRow(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr); BLT_EXTERN Blt_TableColumn Blt_Table_FindColumn(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr); BLT_EXTERN int Blt_Table_ListRows(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_Chain chain); BLT_EXTERN int Blt_Table_ListColumns(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_Chain chain); /* * Blt_TableTraceEvent -- * * Structure representing an event matching a trace set by a client of * the table. * * Table rows and columns may be tagged with strings. A row may have * many tags. The same tag may be used for many rows. Tags are used and * stored by clients of a table. Tags can also be shared between clients * of the same table. * * Both rowTable and columnTable are hash tables keyed by the physical * row or column location in the table respectively. This is not the * same as the client's view (the order of rows or columns as seen by the * client). This is so that clients (which may have different views) can * share tags without sharing the same view. */ typedef struct { Tcl_Interp *interp; /* Interpreter to report to */ Blt_Table table; /* Table object client that received * the event. */ Blt_TableRow row; /* Matching row and column. */ Blt_TableColumn column; unsigned int mask; /* Type of event received. */ } Blt_TableTraceEvent; typedef int (Blt_TableTraceProc)(ClientData clientData, Blt_TableTraceEvent *eventPtr); typedef void (Blt_TableTraceDeleteProc)(ClientData clientData); /* * Blt_TableTrace -- * * Structure representing a trace used by a client of the table. * * Table rows and columns may be tagged with strings. A row may have * many tags. The same tag may be used for many rows. Tags are used and * stored by clients of a table. Tags can also be shared between clients * of the same table. * * Both rowTable and columnTable are hash tables keyed by the physical * row or column location in the table respectively. This is not the * same as the client's view (the order of rows or columns as seen by the * client). This is so that clients (which may have different views) can * share tags without sharing the same view. */ typedef struct _Blt_TableTrace { unsigned int flags; const char *rowTag, *colTag; Blt_TableRow row; Blt_TableColumn column; Blt_TableTraceProc *proc; Blt_TableTraceDeleteProc *deleteProc; ClientData clientData; Blt_Chain chain; Blt_ChainLink link; } *Blt_TableTrace; #define TABLE_TRACE_READS (1<<0) #define TABLE_TRACE_CREATES (1<<1) #define TABLE_TRACE_WRITES (1<<2) #define TABLE_TRACE_UNSETS (1<<3) #define TABLE_TRACE_ALL (TABLE_TRACE_UNSETS | TABLE_TRACE_WRITES | \ TABLE_TRACE_READS | TABLE_TRACE_CREATES) #define TABLE_TRACE_MASK (TRACE_ALL) #define TABLE_TRACE_FOREIGN_ONLY (1<<8) #define TABLE_TRACE_ACTIVE (1<<9) #define TABLE_TRACE_SELF (1<<10) #define TABLE_TRACE_DESTROYED (1<<11) BLT_EXTERN void Blt_Table_ClearRowTags(Blt_Table table, Blt_TableRow row); BLT_EXTERN void Blt_Table_ClearColumnTags(Blt_Table table, Blt_TableColumn column); BLT_EXTERN void Blt_Table_ClearRowTraces(Blt_Table table, Blt_TableRow row); BLT_EXTERN void Blt_Table_ClearColumnTraces(Blt_Table table, Blt_TableColumn column); BLT_EXTERN Blt_TableTrace Blt_Table_CreateTrace(Blt_Table table, Blt_TableRow row, Blt_TableColumn column, const char *rowTag, const char *columnTag, unsigned int mask, Blt_TableTraceProc *proc, Blt_TableTraceDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableTrace Blt_Table_CreateColumnTrace(Blt_Table table, Blt_TableColumn column, unsigned int mask, Blt_TableTraceProc *proc, Blt_TableTraceDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableTrace Blt_Table_CreateColumnTagTrace(Blt_Table table, const char *tag, unsigned int mask, Blt_TableTraceProc *proc, Blt_TableTraceDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableTrace Blt_Table_CreateRowTrace(Blt_Table table, Blt_TableRow row, unsigned int mask, Blt_TableTraceProc *proc, Blt_TableTraceDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableTrace Blt_Table_CreateRowTagTrace(Blt_Table table, const char *tag, unsigned int mask, Blt_TableTraceProc *proc, Blt_TableTraceDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN void Blt_Table_DeleteTrace(Blt_TableTrace trace); /* * Blt_TableNotifyEvent -- * * Structure representing a trace used by a client of the table. * * Table rows and columns may be tagged with strings. A row may have * many tags. The same tag may be used for many rows. Tags are used and * stored by clients of a table. Tags can also be shared between clients * of the same table. * * Both rowTable and columnTable are hash tables keyed by the physical * row or column location in the table respectively. This is not the * same as the client's view (the order of rows or columns as seen by the * client). This is so that clients (which may have different views) can * share tags without sharing the same view. */ typedef struct { Tcl_Interp *interp; /* Interpreter to report results. */ Blt_Table table; /* Table object client that received * the event. */ Blt_TableHeader header; /* Matching row or column. */ int self; /* Indicates if this table client * generated the event. */ int type; /* Indicates type of event * received. */ } Blt_TableNotifyEvent; typedef int (Blt_TableNotifyEventProc)(ClientData clientData, Blt_TableNotifyEvent *eventPtr); typedef void (Blt_TableNotifierDeleteProc)(ClientData clientData); typedef struct _Blt_TableNotifier { Blt_Table table; Blt_ChainLink link; Blt_Chain chain; Blt_TableNotifyEvent event; Blt_TableNotifyEventProc *proc; Blt_TableNotifierDeleteProc *deleteProc; ClientData clientData; Tcl_Interp *interp; Blt_TableHeader header; char *tag; unsigned int flags; } *Blt_TableNotifier; #define TABLE_NOTIFY_ROW_CREATED (1<<0) #define TABLE_NOTIFY_COLUMN_CREATED (1<<1) #define TABLE_NOTIFY_CREATE (TABLE_NOTIFY_COLUMN_CREATED | \ TABLE_NOTIFY_ROW_CREATED) #define TABLE_NOTIFY_ROW_DELETED (1<<2) #define TABLE_NOTIFY_COLUMN_DELETED (1<<3) #define TABLE_NOTIFY_DELETE (TABLE_NOTIFY_COLUMN_DELETED | \ TABLE_NOTIFY_ROW_DELETED) #define TABLE_NOTIFY_ROW_MOVED (1<<4) #define TABLE_NOTIFY_COLUMN_MOVED (1<<5) #define TABLE_NOTIFY_MOVE (TABLE_NOTIFY_COLUMN_MOVED | \ TABLE_NOTIFY_ROW_MOVED) #define TABLE_NOTIFY_COLUMN_CHANGED \ (TABLE_NOTIFY_COLUMN_CREATED | TABLE_NOTIFY_COLUMN_DELETED | \ TABLE_NOTIFY_COLUMN_MOVED) #define TABLE_NOTIFY_ROW_CHANGED \ (TABLE_NOTIFY_ROW_CREATED | TABLE_NOTIFY_ROW_DELETED | \ TABLE_NOTIFY_ROW_MOVED) #define TABLE_NOTIFY_ALL_EVENTS (TABLE_NOTIFY_ROW_CHANGED | \ TABLE_NOTIFY_COLUMN_CHANGED) #define TABLE_NOTIFY_ROW (1<<6) #define TABLE_NOTIFY_COLUMN (1<<7) #define TABLE_NOTIFY_TYPE_MASK (TABLE_NOTIFY_ROW | TABLE_NOTIFY_COLUMN) #define TABLE_NOTIFY_EVENT_MASK TABLE_NOTIFY_ALL_EVENTS #define TABLE_NOTIFY_MASK (TABLE_NOTIFY_EVENT_MASK | \ TABLE_NOTIFY_TYPE_MASK) #define TABLE_NOTIFY_WHENIDLE (1<<10) #define TABLE_NOTIFY_FOREIGN_ONLY (1<<11) #define TABLE_NOTIFY_PENDING (1<<12) #define TABLE_NOTIFY_ACTIVE (1<<13) #define TABLE_NOTIFY_DESTROYED (1<<14) #define TABLE_NOTIFY_ALL (NULL) BLT_EXTERN Blt_TableNotifier Blt_Table_CreateRowNotifier(Tcl_Interp *interp, Blt_Table table, Blt_TableRow row, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableNotifier Blt_Table_CreateRowTagNotifier(Tcl_Interp *interp, Blt_Table table, const char *tag, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableNotifier Blt_Table_CreateColumnNotifier( Tcl_Interp *interp, Blt_Table table, Blt_TableColumn column, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN Blt_TableNotifier Blt_Table_CreateColumnTagNotifier( Tcl_Interp *interp, Blt_Table table, const char *tag, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deleteProc, ClientData clientData); BLT_EXTERN void Blt_Table_DeleteNotifier(Blt_TableNotifier notifier); /* * Blt_TableSortOrder -- * */ typedef int (Blt_TableSortProc)(ClientData clientData, Blt_TableValue value1, Blt_TableValue value2); typedef struct { int type; /* Type of sort to be performed: see * flags below. */ Blt_TableSortProc *sortProc; /* Procedures to be called to compare * two entries in the same row or * column. */ Blt_TableSortProc *userProc; /* Procedures to be called to compare * two entries in the same row or * column. */ ClientData clientData; /* One word of data passed to the sort * comparison procedure above. */ Blt_TableColumn column; /* Column to be compared. */ } Blt_TableSortOrder; #define SORT_DECREASING (1<<0) #define SORT_LIST (1<<1) #define SORT_TYPE_MASK (3<<2) #define SORT_NONE (0) #define SORT_ASCII (1<<2) #define SORT_DICTIONARY (2<<2) #define SORT_FREQUENCY (3<<2) BLT_EXTERN Blt_TableRow *Blt_Table_SortRows(Blt_Table table, Blt_TableSortOrder *order, size_t nCompares, unsigned int flags); BLT_EXTERN Blt_TableRow *Blt_Table_RowMap(Blt_Table table); BLT_EXTERN Blt_TableColumn *Blt_Table_ColumnMap(Blt_Table table); BLT_EXTERN void Blt_Table_SetRowMap(Blt_Table table, Blt_TableRow *map); BLT_EXTERN void Blt_Table_SetColumnMap(Blt_Table table, Blt_TableColumn *map); #define TABLE_RESTORE_NO_TAGS (1<<0) #define TABLE_RESTORE_OVERWRITE (1<<1) BLT_EXTERN int Blt_Table_Restore(Tcl_Interp *interp, Blt_Table table, char *string, unsigned int flags); BLT_EXTERN int Blt_Table_FileRestore(Tcl_Interp *interp, Blt_Table table, const char *fileName, unsigned int flags); BLT_EXTERN int Blt_Table_Dump(Tcl_Interp *interp, Blt_Table table, Blt_TableRow *rowMap, Blt_TableColumn *colMap, Tcl_DString *dsPtr); BLT_EXTERN int Blt_Table_FileDump(Tcl_Interp *interp, Blt_Table table, Blt_TableRow *rowMap, Blt_TableColumn *colMap, const char *fileName); typedef int (Blt_TableImportProc)(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); typedef int (Blt_TableExportProc)(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_Table_RegisterFormat(Tcl_Interp *interp, const char *name, Blt_TableImportProc *importProc, Blt_TableExportProc *exportProc); BLT_EXTERN void Blt_Table_UnsetKeys(Blt_Table table); BLT_EXTERN Blt_Chain Blt_Table_GetKeys(Blt_Table table); BLT_EXTERN int Blt_Table_SetKeys(Blt_Table table, Blt_Chain keys, int unique); BLT_EXTERN int Blt_Table_KeyLookup(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_TableRow *rowPtr); #define Blt_Table_NumRows(t) ((t)->corePtr->rows.nUsed) #define Blt_Table_RowIndex(r) ((r)->index) #define Blt_Table_RowLabel(r) ((r)->label) #define Blt_Table_Row(t,i) \ (Blt_TableRow)((t)->corePtr->rows.map[(i)-1]) #define Blt_Table_NumColumns(t) ((t)->corePtr->columns.nUsed) #define Blt_Table_ColumnIndex(c) ((c)->index) #define Blt_Table_ColumnLabel(c) ((c)->label) #define Blt_Table_Column(t,i) \ (Blt_TableColumn)((t)->corePtr->columns.map[(i)-1]) #define Blt_Table_TableName(t) ((t)->name) #define Blt_Table_EmptyValue(t) ((t)->emptyValue) #define Blt_Table_ColumnType(c) ((c)->type) #endif /* BLT_DATATABLE_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltInit.c���������������������������������������������������������������������0000644�0001750�0001750�00000007724�11462120062�014610� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltInit.c -- * * This module initials the BLT toolkit, registering its commands with the * Tcl/Tk interpreter. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltNsUtil.h" /* *--------------------------------------------------------------------------- * * Blt_InitCmd -- * * Given the name of a command, return a pointer to the clientData field * of the command. * * Results: * A standard TCL result. If the command is found, TCL_OK is returned * and clientDataPtr points to the clientData field of the command (if * the clientDataPtr in not NULL). * * Side effects: * If the command is found, clientDataPtr is set to the address of the * clientData of the command. If not found, an error message is left * in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_InitCmd(Tcl_Interp *interp, const char *nsName, Blt_InitCmdSpec *specPtr) { const char *cmdPath; Tcl_DString dString; Tcl_Command cmdToken; Tcl_Namespace *nsPtr; Tcl_DStringInit(&dString); if (nsName != NULL) { Tcl_DStringAppend(&dString, nsName, -1); } Tcl_DStringAppend(&dString, "::", -1); Tcl_DStringAppend(&dString, specPtr->name, -1); cmdPath = Tcl_DStringValue(&dString); cmdToken = Tcl_FindCommand(interp, cmdPath, (Tcl_Namespace *)NULL, 0); if (cmdToken != NULL) { Tcl_DStringFree(&dString); return TCL_OK; /* Assume command was already initialized */ } cmdToken = Tcl_CreateObjCommand(interp, cmdPath, specPtr->cmdProc, specPtr->clientData, specPtr->cmdDeleteProc); Tcl_DStringFree(&dString); nsPtr = Tcl_FindNamespace(interp, nsName, (Tcl_Namespace *)NULL, TCL_LEAVE_ERR_MSG); if (nsPtr == NULL) { return TCL_ERROR; } if (Tcl_Export(interp, nsPtr, specPtr->name, FALSE) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_InitCmds -- * * Given the name of a command, return a pointer to the clientData field * of the command. * * Results: * A standard TCL result. If the command is found, TCL_OK is returned and * clientDataPtr points to the clientData field of the command (if the * clientDataPtr in not NULL). * * Side effects: * If the command is found, clientDataPtr is set to the address of the * clientData of the command. If not found, an error message is left in * interp->result. * *--------------------------------------------------------------------------- */ int Blt_InitCmds( Tcl_Interp *interp, const char *nsName, Blt_InitCmdSpec *specs, int nCmds) { Blt_InitCmdSpec *sp, *endPtr; for (sp = specs, endPtr = specs + nCmds; sp < endPtr; sp++) { if (Blt_InitCmd(interp, nsName, sp) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } ��������������������������������������������./saods9/blt3.0.1/src/bltPictBmp.c������������������������������������������������������������������0000644�0001750�0001750�00000127762�11462120062�015250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictBmp.c -- * * This module implements BMP file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #include <tcl.h> #include <bltAlloc.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include "bltPicture.h" #include "bltPictFmts.h" #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifdef _MSC_VER #define vsnprintf _vsnprintf #endif #include <setjmp.h> typedef struct _Blt_Picture Picture; #define TRUE 1 #define FALSE 0 #define OFF_TYPE 0 #define OFF_FILE_SIZE 2 #define OFF_RESERVED1 6 #define OFF_RESERVED2 8 #define OFF_OFFBITS 10 #define OFF_SIZE 14 #define OFF_WIDTH 18 #define OFF_HEIGHT 22 #define OFF_PLANES 26 #define OFF_BIT_COUNT 28 #define OFF_COMPRESSION 30 #define OFF_SIZE_IMAGE 34 #define OFF_X_PELS_PER_METER 38 #define OFF_Y_PELS_PER_METER 42 #define OFF_CLR_USED 46 #define OFF_CLR_IMPORTANT 50 #define OFF_RED_MASK 54 #define OFF_GREEN_MASK 58 #define OFF_BLUE_MASK 62 #define OFF_ALPHA_MASK 66 #define OFF_CS_TYPE 70 #define OFF_END_POINTS 74 #define OFF_GAMMA_RED 110 #define OFF_GAMMA_GREEN 114 #define OFF_GAMMA_BLUE 118 #define OFF_INTENT 122 #define OFF_PROFILE_DATA 126 #define OFF_PROFILE_SIZE 130 #define OFF_RESERVED3 134 #define OFF_OSV1_SIZE 14 #define OFF_OSV1_WIDTH 18 #define OFF_OSV1_HEIGHT 20 #define OFF_OSV1_PLANES 22 #define OFF_OSV1_BIT_COUNT 24 #define SIZEOF_BITMAPOS2V1HEADER 12 #define SIZEOF_BITMAPOS2V2HEADER 64 #define SIZEOF_BITMAPV3HEADER 40 #define SIZEOF_BITMAPV4HEADER 108 #define SIZEOF_BITMAPV5HEADER 124 typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; } BmpImportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int flags; /* Flag. */ Blt_Pixel bg; int index; } BmpExportSwitches; #define EXPORT_ALPHA (1<<0) static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(BmpImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(BmpImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(BmpExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(BmpExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(BmpExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_BITMASK, "-alpha", "", Blt_Offset(BmpExportSwitches, flags), 0, EXPORT_ALPHA}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(BmpExportSwitches, index), 0}, {BLT_SWITCH_END} }; typedef struct { jmp_buf jmpbuf; Tcl_DString errors; Tcl_DString warnings; int nWarnings, nErrors; } BmpMessage; static BmpMessage *bmpMessagePtr; static const char *compression_types[] = { "RGB", "RLE8", "RLE4", "BITFIELDS", "JPEG", "PNG" }; enum CompressionTypes { BI_RGB, /* No compression. */ BI_RLE8, /* RLE 8-bits/pixel. Only used with * 8-bit/pixel bitmaps */ BI_RLE4, /* RLE 4-bits/pixel. Can be used only with * 4-bit/pixel bitmaps */ BI_BITFIELDS, /* Bit fields. Can be used only with 16 and * 32-bit/pixel bitmaps. */ BI_JPEG, /* The bitmap contains a JPEG image. */ BI_PNG, /* The bitmap contains a PNG image. */ }; typedef struct { unsigned short bfType; unsigned int bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned int bfOffBits; } BitmapFileHeader; typedef struct { int RedX; /* X coordinate of red endpoint */ int RedY; /* Y coordinate of red endpoint */ int RedZ; /* Z coordinate of red endpoint */ int GreenX; /* X coordinate of green endpoint */ int GreenY; /* Y coordinate of green endpoint */ int GreenZ; /* Z coordinate of green endpoint */ int BlueX; /* X coordinate of blue endpoint */ int BlueY; /* Y coordinate of blue endpoint */ int BlueZ; /* Z coordinate of blue endpoint */ } CieXyzTriple; typedef struct { unsigned int biSize; /* Size of this structure. This determines * what version of the header is used. */ int biWidth; int biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned int biCompression; unsigned int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; unsigned int biClrUsed; unsigned int biClrImportant; /* Fields related to Version 4 of header. */ unsigned int biRedMask; unsigned int biGreenMask; unsigned int biBlueMask; unsigned int biAlphaMask; unsigned int biCSType; CieXyzTriple biEndpoints; unsigned int biGammaRed; unsigned int biGammaGreen; unsigned int biGammaBlue; /* Fields related to Version 5 of header. */ unsigned int biIntent; unsigned int biProfileData; unsigned int biProfileSize; unsigned int biReserved; } BitmapInfoHeader; #define MAXCOLORS 256 typedef struct { BitmapFileHeader bmfh; BitmapInfoHeader bmih; Blt_Pixel colorTable[MAXCOLORS]; const char *name; } Bmp; DLLEXPORT extern Tcl_AppInitProc Blt_PictureBmpInit; /*ARGSUSED*/ static void BmpError TCL_VARARGS_DEF(const char *, arg1) { const char *fmt; char string[BUFSIZ+4]; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&bmpMessagePtr->errors, string, -1); va_end(args); longjmp(bmpMessagePtr->jmpbuf, 0); } /*ARGSUSED*/ static void BmpWarning TCL_VARARGS_DEF(const char *, arg1) { const char *fmt; char string[BUFSIZ+4]; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&bmpMessagePtr->warnings, string, -1); va_end(args); bmpMessagePtr->nWarnings++; } static INLINE unsigned int BmpGetLong(unsigned char *buf) { #ifdef WORDS_BIGENDIAN return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; #else return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); #endif } static INLINE unsigned short BmpGetShort(unsigned char *buf) { #ifdef WORDS_BIGENDIAN return (buf[0] << 8) | buf[1]; #else return buf[0] | (buf[1] << 8); #endif } static INLINE unsigned char * BmpSetLong(unsigned char *buf, unsigned long value) { #ifdef WORDS_BIGENDIAN buf[0] = (value >> 24) & 0xFF; buf[1] = (value >> 16) & 0xFF; buf[2] = (value >> 8) & 0xFF; buf[3] = (value) & 0xFF; #else buf[0] = (value) & 0xFF; buf[1] = (value >> 8) & 0xFF; buf[2] = (value >> 16) & 0xFF; buf[3] = (value >> 24) & 0xFF; #endif return buf + 4; } static INLINE unsigned char * BmpSetShort(unsigned char *buf, unsigned long value) { #ifdef WORDS_BIGENDIAN buf[0] = (value >> 8) & 0xFF; buf[1] = (value) & 0xFF; #else buf[0] = (value) & 0xFF; buf[1] = (value >> 8) & 0xFF; #endif return buf + 2; } /* * Field Name Type * | 0| 1| bfType 2 Bytes * | 2| 3| 4| 5| bfSize 4 Bytes * | 6| 7| bfReserved1 4 Bytes * | 8| 9| bfReserved2 4 Bytes * |10|11|12|13| bfOffBits 4 Bytes * */ static int BmpHeader(Blt_DBuffer dbuffer, Bmp *bmpPtr) { unsigned char *bp; size_t fileSize; Blt_DBuffer_ResetCursor(dbuffer); fileSize = Blt_DBuffer_BytesLeft(dbuffer); if (fileSize < 14) { return FALSE; } bp = Blt_DBuffer_Pointer(dbuffer); if ((bp[0] != 'B') || (bp[1] != 'M')) { return FALSE; } bmpPtr->bmfh.bfSize = BmpGetLong (bp + OFF_FILE_SIZE); bmpPtr->bmfh.bfReserved1 = BmpGetShort(bp + OFF_RESERVED1); bmpPtr->bmfh.bfReserved2 = BmpGetShort(bp + OFF_RESERVED2); bmpPtr->bmfh.bfOffBits = BmpGetLong (bp + OFF_OFFBITS); return TRUE; } /* * Version 2 Field Name Size * | 0| 1| 2| 3| biSize 4 Bytes * | 4| 5| biWidth 2 Bytes * | 6| 7| biHeight 2 Bytes * | 8| 9| biPlanes 2 Bytes * |10|11| biBitCount 2 Bytes * Version 3 * | 0| 1| 2| 3| biSize 4 Bytes * | 4| 5| 6| 7| biWidth 4 Bytes * | 8| 9|10|11| biHeight 4 Bytes * |12|13| biPlanes 2 Bytes * |14|15| biBitCount 2 Bytes * |16|17|18|19| biCompression 4 Bytes * |20|21|22|23| biSizeImage 4 Bytes * |24|25|26|27| biXPelsPerMeter 4 Bytes * |28|29|30|31| biYPelsPerMeter 4 Bytes * |32|33|34|35| biClrUsed 4 Bytes * |36|37|38|39| biClrImportant 4 Bytes * Version 4 * |40|41|42|43| biRedMask 4 Bytes * |44|45|46|47| biGreenMask 4 Bytes * |48|49|50|51| biBlueMask 4 Bytes * |52|53|54|55| biAlphaMask 4 Bytes * |56|57|58|59| biCSType 4 Bytes * |60--95| biEndpoints 36 Bytes * |96|97|98|99| biGammaRed 4 Bytes * |00|01|02|03| biGammaGreen 4 Bytes * |04|05|06|07| biGammaBlue 4 Bytes * Version 5 * |08|09|10|11| bV5Intent 4 Bytes * |12|13|14|15| bV5ProfileData 4 Bytes * |16|17|18|19| bV5ProfileSize 4 Bytes * |20|21|22|23| bV5Reserved 4 Bytes */ static int BmpHeaderInfo(Blt_DBuffer dbuffer, Bmp *bmpPtr) { unsigned char *bp; bp = Blt_DBuffer_Pointer(dbuffer); bmpPtr->bmih.biSize = BmpGetLong(bp + OFF_SIZE); /* Verify header size. */ switch (bmpPtr->bmih.biSize) { case SIZEOF_BITMAPOS2V1HEADER: case SIZEOF_BITMAPOS2V2HEADER: case SIZEOF_BITMAPV3HEADER: case SIZEOF_BITMAPV4HEADER: case SIZEOF_BITMAPV5HEADER: break; default: BmpError("unknown BMP bitmap header (size=%d).", bmpPtr->bmih.biSize); } if (bmpPtr->bmih.biSize == SIZEOF_BITMAPOS2V1HEADER) { bmpPtr->bmih.biWidth = (int)BmpGetShort(bp + OFF_OSV1_WIDTH); bmpPtr->bmih.biHeight = (int)BmpGetShort(bp + OFF_OSV1_HEIGHT); bmpPtr->bmih.biPlanes = BmpGetShort(bp + OFF_OSV1_PLANES); bmpPtr->bmih.biBitCount = BmpGetShort(bp + OFF_OSV1_BIT_COUNT); bmpPtr->bmih.biCompression = BI_RGB; } else { bmpPtr->bmih.biWidth = (int)BmpGetLong(bp + OFF_WIDTH); bmpPtr->bmih.biHeight = (int)BmpGetLong(bp + OFF_HEIGHT); bmpPtr->bmih.biPlanes = BmpGetShort(bp + OFF_PLANES); bmpPtr->bmih.biBitCount = BmpGetShort(bp + OFF_BIT_COUNT); bmpPtr->bmih.biCompression = BmpGetLong(bp + OFF_COMPRESSION); bmpPtr->bmih.biSizeImage = BmpGetLong(bp + OFF_SIZE_IMAGE); bmpPtr->bmih.biXPelsPerMeter = (int)BmpGetLong(bp + OFF_X_PELS_PER_METER); bmpPtr->bmih.biYPelsPerMeter = (int)BmpGetLong(bp + OFF_Y_PELS_PER_METER); bmpPtr->bmih.biClrUsed = BmpGetLong(bp + OFF_CLR_USED); bmpPtr->bmih.biClrImportant = BmpGetLong(bp + OFF_CLR_IMPORTANT); } #ifdef notdef fprintf(stderr, "fileName=%s\n", bmpPtr->name); fprintf(stderr, " biSize=%d\n", bmpPtr->bmih.biSize); fprintf(stderr, " biWidth=%d\n", bmpPtr->bmih.biWidth); fprintf(stderr, " biHeight=%d\n", bmpPtr->bmih.biHeight); fprintf(stderr, " biPlanes=%d\n", bmpPtr->bmih.biPlanes); fprintf(stderr, " biBitCount=%d\n", bmpPtr->bmih.biBitCount); fprintf(stderr, " biCompression=%d\n", bmpPtr->bmih.biCompression); fprintf(stderr, " biSizeImage=%d\n", bmpPtr->bmih.biSizeImage); fprintf(stderr, " biClrUsed=%d\n", bmpPtr->bmih.biClrUsed); #endif if (Blt_DBuffer_BytesLeft(dbuffer) < bmpPtr->bmih.biSize) { BmpError("bad BMP header, short file"); } if (bmpPtr->bmih.biWidth <= 0) { BmpError("invalid image width %d.", bmpPtr->bmih.biWidth); } if (bmpPtr->bmih.biHeight == 0) { BmpError("invalid image height %d.", bmpPtr->bmih.biHeight); } /* According to the MicroSoft documentation, if the image height is * negative, the image data is in top-down order. Since virtually no one * does this, read the image data bottom-up. The user can always flip the * resulting image. */ if (bmpPtr->bmih.biHeight < 0) { bmpPtr->bmih.biHeight = -bmpPtr->bmih.biHeight; } if (Blt_DBuffer_Length(dbuffer) < bmpPtr->bmfh.bfSize) { int old; old = Blt_DBuffer_Length(dbuffer); Blt_DBuffer_Resize(dbuffer, bmpPtr->bmfh.bfSize); memset(bp + old, 0, bmpPtr->bmfh.bfSize - old); Blt_DBuffer_SetLength(dbuffer, bmpPtr->bmfh.bfSize); } if (bmpPtr->bmih.biSize >= SIZEOF_BITMAPV4HEADER) { bmpPtr->bmih.biRedMask = BmpGetLong(bp + OFF_RED_MASK); bmpPtr->bmih.biGreenMask = BmpGetLong(bp + OFF_GREEN_MASK); bmpPtr->bmih.biBlueMask = BmpGetLong(bp + OFF_BLUE_MASK); bmpPtr->bmih.biAlphaMask = BmpGetLong(bp + OFF_ALPHA_MASK); bmpPtr->bmih.biCSType = BmpGetLong(bp + OFF_CS_TYPE); /* Skip CIEXYZ endpoints */ bmpPtr->bmih.biGammaRed = BmpGetLong(bp + OFF_GAMMA_RED); bmpPtr->bmih.biGammaGreen = BmpGetLong(bp + OFF_GAMMA_GREEN); bmpPtr->bmih.biGammaBlue = BmpGetLong(bp + OFF_GAMMA_BLUE); } if (bmpPtr->bmih.biSize >= SIZEOF_BITMAPV5HEADER) { bmpPtr->bmih.biIntent = BmpGetLong(bp + OFF_INTENT); bmpPtr->bmih.biProfileData = BmpGetLong(bp + OFF_PROFILE_DATA); bmpPtr->bmih.biProfileSize = BmpGetLong(bp + OFF_PROFILE_SIZE); bmpPtr->bmih.biReserved = BmpGetLong(bp + OFF_RESERVED3); } #ifdef notdef if (bmpPtr->bmih.biCSType != 0) { fprintf(stderr, "fileName=%s\n", bmpPtr->name); fprintf(stderr, " biRedMask=%x\n", bmpPtr->bmih.biRedMask); fprintf(stderr, " biGreenMask=%x\n", bmpPtr->bmih.biGreenMask); fprintf(stderr, " biBlueMask=%x\n", bmpPtr->bmih.biBlueMask); fprintf(stderr, " biAlphaMask=%x\n", bmpPtr->bmih.biAlphaMask); fprintf(stderr, " biCSType=%d\n", bmpPtr->bmih.biCSType); fprintf(stderr, " biGammaRed=%d\n", bmpPtr->bmih.biGammaRed); fprintf(stderr, " biGammaGreen=%d\n", bmpPtr->bmih.biGammaGreen); fprintf(stderr, " biGammaBlue=%d\n", bmpPtr->bmih.biGammaBlue); fprintf(stderr, " biIntent=%d\n", bmpPtr->bmih.biIntent); fprintf(stderr, " biProfileData=%d\n", bmpPtr->bmih.biProfileData); fprintf(stderr, " biProfileSize=%d\n", bmpPtr->bmih.biProfileSize); fprintf(stderr, " biReserved=%d\n", bmpPtr->bmih.biReserved); } #endif /* Verify bits per pixel count and colors used. */ switch (bmpPtr->bmih.biBitCount) { case 1: /* 2-bits, Monochrome */ if (bmpPtr->bmih.biClrUsed > 2) { BmpError("wrong # colors (%d), expecting <= 2 colors.", bmpPtr->bmih.biClrUsed); } if (bmpPtr->bmih.biClrUsed == 0) { bmpPtr->bmih.biClrUsed = 2; } break; case 4: /* 4-bits, 16 colors. */ if (bmpPtr->bmih.biClrUsed > 16) { BmpError("wrong # colors (%d), expecting <= 16 colors.", bmpPtr->bmih.biClrUsed); } if (bmpPtr->bmih.biClrUsed == 0) { bmpPtr->bmih.biClrUsed = 16; } break; case 8: /* 8-bits, 256 colors */ if (bmpPtr->bmih.biClrUsed > 256) { BmpError("wrong # colors (%d), expecting <= 256 colors.", bmpPtr->bmih.biClrUsed); } if (bmpPtr->bmih.biClrUsed == 0) { bmpPtr->bmih.biClrUsed = 256; } break; case 16: case 24: case 32: /* True color. */ if (bmpPtr->bmih.biClrUsed != 0) { BmpWarning("# colors is %d, expecting 0 colors in %d-bit image.", bmpPtr->bmih.biClrUsed, bmpPtr->bmih.biBitCount); bmpPtr->bmih.biClrUsed = 0; } break; default: BmpError("invalid # bits per pixel (%d)", bmpPtr->bmih.biBitCount); break; } /* Verify compression type. */ switch (bmpPtr->bmih.biCompression) { case BI_RGB: break; case BI_RLE4: if (bmpPtr->bmih.biBitCount != 4) { BmpError("wrong # bits per pixel (%d) for RLE4 compression", bmpPtr->bmih.biBitCount); } break; case BI_RLE8: if (bmpPtr->bmih.biBitCount != 8) { BmpError("wrong # bits per pixel (%d) for RLE8 compression", bmpPtr->bmih.biBitCount); } break; case BI_BITFIELDS: if ((bmpPtr->bmih.biBitCount != 16)&&(bmpPtr->bmih.biBitCount != 32)) { BmpError("wrong # bits per pixel (%d) for BITFIELD compression", bmpPtr->bmih.biBitCount); } break; case BI_PNG: case BI_JPEG: BmpError("compression type \"%s\" not implemented", compression_types[bmpPtr->bmih.biCompression]); break; default: BmpError("unknown compression type (%d)", bmpPtr->bmih.biCompression); } Blt_DBuffer_SetPointer(dbuffer, bp + bmpPtr->bmih.biSize + 14); return TRUE; } static int BmpPalette(Blt_DBuffer dbuffer, Bmp *bmpPtr) { unsigned char *bp; bp = Blt_DBuffer_Pointer(dbuffer); if (bmpPtr->bmih.biClrUsed == 0) { if (bmpPtr->bmih.biSize == SIZEOF_BITMAPV3HEADER) { bmpPtr->bmih.biRedMask = BmpGetLong(bp); bmpPtr->bmih.biGreenMask = BmpGetLong(bp + 4); bmpPtr->bmih.biBlueMask = BmpGetLong(bp + 8); bmpPtr->bmih.biAlphaMask = 0; } } else { int sizeElem; int i; assert(bmpPtr->bmih.biClrUsed <= 256); sizeElem = (bmpPtr->bmih.biSize == SIZEOF_BITMAPOS2V1HEADER) ? 3 : 4; if (Blt_DBuffer_BytesLeft(dbuffer) < (bmpPtr->bmih.biClrUsed * sizeElem)) { BmpError("short file"); } for (i = 0; i < bmpPtr->bmih.biClrUsed; i++, bp += sizeElem) { /* Colormap components are ordered BGBA. */ bmpPtr->colorTable[i].Blue = bp[0]; bmpPtr->colorTable[i].Green = bp[1]; bmpPtr->colorTable[i].Red = bp[2]; bmpPtr->colorTable[i].Alpha = ALPHA_OPAQUE; } } Blt_DBuffer_SetPointer(dbuffer, bp); return TRUE; } static Blt_Picture BmpRgbImageData(Blt_DBuffer dbuffer, Bmp *bmpPtr) { Blt_Pixel *destRowPtr; Picture *destPtr; unsigned char *srcBits; unsigned int bytesPerRow, wordsPerRow; int w, h; w = bmpPtr->bmih.biWidth; h = bmpPtr->bmih.biHeight; wordsPerRow = (w * bmpPtr->bmih.biBitCount + 31) / 32; bytesPerRow = wordsPerRow * 4; srcBits = Blt_DBuffer_Pointer(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < (bytesPerRow * h)) { BmpError("image size is %d, need %u bytes", Blt_DBuffer_BytesLeft(dbuffer), bytesPerRow * (unsigned int)h); } destPtr = Blt_CreatePicture(w, h); destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * h); switch (bmpPtr->bmih.biBitCount) { case 1: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; destRowPtr -= destPtr->pixelsPerRow; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { int x; unsigned char byte; x = dp - destRowPtr; byte = srcRowPtr[x>>3]; dp->u32 = (byte & (0x80 >> (x & 7))) ? bmpPtr->colorTable[1].u32 : bmpPtr->colorTable[0].u32; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += bytesPerRow; } } break; case 4: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; /*empty*/) { unsigned int pixel; pixel = ((sp[0] >> 4) & 0x0F); dp->u32 = bmpPtr->colorTable[pixel].u32; dp++; pixel = (sp[0] & 0x0F); dp->u32 = bmpPtr->colorTable[pixel].u32; dp++; sp++; } srcRowPtr += bytesPerRow; } } break; case 8: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { dp->u32 = bmpPtr->colorTable[*sp].u32; sp++; } srcRowPtr += bytesPerRow; } break; } case 16: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { unsigned int pixel; pixel = BmpGetShort(sp); dp->Blue = (pixel & 0x001f) << 3; dp->Green = (pixel & 0x03e0) >> 2; dp->Red = (pixel & 0x7c00) >> 7; dp->Alpha = ALPHA_OPAQUE; sp += 2; } srcRowPtr += bytesPerRow; } } break; case 24: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { dp->Blue = sp[0]; dp->Green = sp[1]; dp->Red = sp[2]; dp->Alpha = ALPHA_OPAQUE; sp += 3; } srcRowPtr += bytesPerRow; } } break; case 32: { int y; unsigned char *srcRowPtr; srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { dp->Blue = sp[0]; dp->Green = sp[1]; dp->Red = sp[2]; dp->Alpha = ALPHA_OPAQUE; sp += 4; } srcRowPtr += bytesPerRow; } } break; } return destPtr; } /*------------------------------------------------------------------------------- * * CountBits -- * * Returns the number of bits set in the given 32-bit mask. * * Reference: Graphics Gems Volume II. * * Results: * The number of bits to set in the mask. * * *--------------------------------------------------------------------------- */ static int CountBits(unsigned long mask) /* 32 1-bit tallies */ { /* 16 2-bit tallies */ mask = (mask & 0x55555555) + ((mask >> 1) & (0x55555555)); /* 8 4-bit tallies */ mask = (mask & 0x33333333) + ((mask >> 2) & (0x33333333)); /* 4 8-bit tallies */ mask = (mask & 0x07070707) + ((mask >> 4) & (0x07070707)); /* 2 16-bit tallies */ mask = (mask & 0x000F000F) + ((mask >> 8) & (0x000F000F)); /* 1 32-bit tally */ mask = (mask & 0x0000001F) + ((mask >> 16) & (0x0000001F)); return mask; } /* *--------------------------------------------------------------------------- * * FindShift -- * * Returns the position of the least significant (low) bit in the given * mask. * * Results: * The number of the least significant bit. * *--------------------------------------------------------------------------- */ static int FindShift(unsigned int mask) { int bit; for (bit = 0; bit < 32; bit++) { if (mask & (1 << bit)) { break; } } return bit; } static int GetAdjust(unsigned int mask) { int n; int adjust = 0; n = CountBits(mask); if (n < 8) { adjust = 8 - n; } return adjust; } static Blt_Picture BmpBitfieldImageData(Blt_DBuffer dbuffer, Bmp *bmpPtr) { Picture *destPtr; unsigned char *srcBits; unsigned int bytesPerRow, wordsPerRow; int w, h; unsigned int rShift, gShift, bShift, aShift; unsigned int rMask, gMask, bMask, aMask; unsigned int rAdjust, gAdjust, bAdjust, aAdjust; rMask = bmpPtr->bmih.biRedMask; gMask = bmpPtr->bmih.biGreenMask; bMask = bmpPtr->bmih.biBlueMask; aMask = bmpPtr->bmih.biAlphaMask; rShift = FindShift(rMask); gShift = FindShift(gMask); bShift = FindShift(bMask); aShift = FindShift(aMask); rAdjust = GetAdjust(rMask); gAdjust = GetAdjust(gMask); bAdjust = GetAdjust(bMask); aAdjust = GetAdjust(aMask); w = bmpPtr->bmih.biWidth; h = bmpPtr->bmih.biHeight; wordsPerRow = (w * bmpPtr->bmih.biBitCount + 31) / 32; bytesPerRow = wordsPerRow * 4; srcBits = Blt_DBuffer_Pointer(dbuffer); destPtr = Blt_CreatePicture(w, h); if (bmpPtr->bmih.biBitCount == 32) { Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * h); srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { unsigned int pixel; pixel = BmpGetLong(sp); dp->Red = ((pixel & rMask) >> rShift) << rAdjust; dp->Green = ((pixel & gMask) >> gShift) << gAdjust; dp->Blue = ((pixel & bMask) >> bShift) << bAdjust; dp->Alpha = ((pixel & aMask) >> aShift) << aAdjust; sp += 4; } srcRowPtr += bytesPerRow; } } else if (bmpPtr->bmih.biBitCount == 16) { Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * h); srcRowPtr = srcBits; for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; unsigned char *sp; destRowPtr -= destPtr->pixelsPerRow; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { unsigned int pixel; pixel = BmpGetShort(sp); dp->Red = ((pixel & rMask) >> rShift) << rAdjust; dp->Green = ((pixel & gMask) >> gShift) << gAdjust; dp->Blue = ((pixel & bMask) >> bShift) << bAdjust; dp->Alpha = ((pixel & aMask) >> aShift) << aAdjust; sp += 2; } srcRowPtr += bytesPerRow; } } else { return NULL; } if (aMask != 0) { /* The image may or may not be transparent. Check */ Blt_ClassifyPicture(destPtr); } return destPtr; } static Blt_Picture BmpRleImageData(Blt_DBuffer dbuffer, Bmp *bmpPtr) { Picture *destPtr; unsigned char *srcBits, *sp; unsigned int bytesPerRow, wordsPerRow; int w, h; w = bmpPtr->bmih.biWidth; h = bmpPtr->bmih.biHeight; wordsPerRow = (w * bmpPtr->bmih.biBitCount + 31) / 32; bytesPerRow = wordsPerRow * 4; srcBits = Blt_DBuffer_Pointer(dbuffer); destPtr = Blt_CreatePicture(w, h); Blt_BlankPicture(destPtr, bmpPtr->colorTable); sp = srcBits; if (bmpPtr->bmih.biBitCount == 8) { int x, y; x = 0, y = h - 1; for (;;) { unsigned int index, count; count = sp[0]; index = sp[1]; sp += 2; if (count == 0) { switch (index) { case 0: /* End-of-line */ x = 0; y--; if (y < 0) { goto done; } break; case 1: /* End-of-bitmap */ goto done; case 2: /* Delta */ x += sp[2]; y -= sp[3]; if (y < 0) { goto done; } sp += 2; break; default: /* Absolute mode. index is # of bytes. */ { int i; Blt_Pixel *dp; count = index; if ((x + count) > w) { Blt_FreePicture(destPtr); BmpError("invalid image data: abs run of %d pixels will overrun row (%d,%d) %d index=%d", count, x, y, w, index); } /* The run is always padded to an even number of bytes * (16-bit boundary). This loop relies on the fact * that picture data is also padded. */ dp = Blt_PicturePixel(destPtr, x, y); for (i = 0; i < count; i += 2) { dp->u32 = bmpPtr->colorTable[sp[0]].u32; dp++; dp->u32 = bmpPtr->colorTable[sp[1]].u32; dp++, sp += 2; } x += count; } break; } } else { int i; Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x, y); for (i = 0; (x < w) && (i < count); i++, x++) { dp->u32 = bmpPtr->colorTable[index].u32; dp++; } } } } else if (bmpPtr->bmih.biBitCount == 4) { int x, y; x = 0, y = h - 1; for (;;) { unsigned int index, count; count = sp[0]; index = sp[1]; sp += 2; if (count == 0) { switch (index) { case 0: /* End-of-line */ x = 0; y--; if (y < 0) { goto done; } break; case 1: /* End-of-bitmap */ goto done; case 2: /* Delta */ x += sp[2]; y -= sp[3]; if (y < 0) { goto done; } sp += 2; break; default: /* Absolute mode. index is # of pixels. */ { int i; Blt_Pixel *dp; unsigned char *send; count = index; dp = Blt_PicturePixel(destPtr, x, y); /* The run may be padded up to 12 bits. */ send = sp + ((count + 3) / 4) * 2; if ((x + count) > w) { Blt_FreePicture(destPtr); BmpError("invalid image data: abs run of %d pixels will overrun row (%d,%d) %d index=%d", count, x, y, w, index); } for (i = 0; i < count; i += 2) { int i1, i2; i1 = (sp[0] >> 4) & 0x0F; i2 = sp[0] & 0x0F; sp++; dp->u32 = bmpPtr->colorTable[i1].u32; dp++; dp->u32 = bmpPtr->colorTable[i2].u32; dp++; } x += count; sp = send; } break; } } else { /* Encoded mode */ int i; Blt_Pixel *dp; unsigned int c1, c2; c1 = bmpPtr->colorTable[(index >> 4) & 0x0F].u32; c2 = bmpPtr->colorTable[index & 0x0F].u32; dp = Blt_PicturePixel(destPtr, x, y); for (i = 0; (x < w) && (i < count); i++, x++) { dp->u32 = (i & 0x1) ? c2 : c1; dp++; } } } } done: return destPtr; } static Blt_Picture BmpImageData(Blt_DBuffer dbuffer, Bmp *bmpPtr) { Blt_Picture picture; picture = NULL; Blt_DBuffer_SetCursor(dbuffer, bmpPtr->bmfh.bfOffBits); if (Blt_DBuffer_BytesLeft(dbuffer) < (bmpPtr->bmih.biSizeImage)) { BmpError("short file: not enough bytes for image data"); } switch(bmpPtr->bmih.biCompression) { case BI_RGB: picture = BmpRgbImageData(dbuffer, bmpPtr); break; case BI_BITFIELDS: picture = BmpBitfieldImageData(dbuffer, bmpPtr); break; case BI_RLE4: case BI_RLE8: picture = BmpRleImageData(dbuffer, bmpPtr); break; case BI_PNG: case BI_JPEG: break; } return picture; } /* *--------------------------------------------------------------------------- * * BmpToPicture -- * * Reads a BMP file, converts it into a picture, and appends it * to the list of images. We only handle only single BMP images. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain BmpToPicture(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, BmpImportSwitches *switchesPtr) { Blt_Chain chain; Blt_Picture picture; Bmp bmp; BmpMessage message; bmpMessagePtr = &message; memset(&bmp, 0, sizeof(bmp)); /* Clear the structure. */ message.nWarnings = 0; bmp.name = fileName; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); Tcl_DStringAppend(&message.errors, "error reading \"", -1); Tcl_DStringAppend(&message.errors, fileName, -1); Tcl_DStringAppend(&message.errors, "\": ", -1); Tcl_DStringAppend(&message.warnings, "\"", -1); Tcl_DStringAppend(&message.warnings, fileName, -1); Tcl_DStringAppend(&message.warnings, "\": ", -1); if (setjmp(message.jmpbuf)) { Tcl_DStringResult(interp, &message.errors); Tcl_DStringFree(&message.warnings); return NULL; } chain = NULL; if (!BmpHeader(dbuffer, &bmp)) { BmpError("bad BMP header"); } if (!BmpHeaderInfo(dbuffer, &bmp)) { BmpError("bad BMP logical screen descriptor"); } if (!BmpPalette(dbuffer, &bmp)) { BmpError("bad BMP color table"); } picture = BmpImageData(dbuffer, &bmp); if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "BMP_READ_WARNINGS", Tcl_DStringValue(&message.warnings), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); Tcl_DStringFree(&message.errors); if (picture != NULL) { chain = Blt_Chain_Create(); Blt_Chain_Append(chain, picture); } return chain; } /* *--------------------------------------------------------------------------- * * PictureToBmp -- * * Reads an BMP file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such as the designated * file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static int PictureToBmp(Tcl_Interp *interp, Blt_Picture original, Blt_DBuffer dbuffer, BmpExportSwitches *switchesPtr) { int nColors; int format; int bitsPerPixel; Picture *srcPtr; Blt_HashTable colorTable; unsigned int wordsPerRow, bytesPerRow; unsigned int imageSize, fileSize, infoHeaderSize, offsetToData; unsigned char *bp, *destBits; srcPtr = original; if (switchesPtr->flags & EXPORT_ALPHA) { bitsPerPixel = 32; format = BI_BITFIELDS; nColors = 0; infoHeaderSize = SIZEOF_BITMAPV4HEADER; } else { if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; } nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); format = BI_RGB; infoHeaderSize = SIZEOF_BITMAPV3HEADER; if (nColors <= 256) { bitsPerPixel = 8; Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); nColors = Blt_QueryColors(srcPtr, &colorTable); } else { bitsPerPixel = 24; nColors = 0; } } wordsPerRow = (srcPtr->width * bitsPerPixel + 31) / 32; bytesPerRow = wordsPerRow * 4; imageSize = bytesPerRow * srcPtr->height; /* * Compute the size of the structure. * * header + infoheader + colortable + imagedata * * 14 + 108 + 0-256 * 4 + bytesPerRow * height; */ fileSize = imageSize + (nColors * 4) + infoHeaderSize + 14; offsetToData = 14 + infoHeaderSize + (nColors * 4); bp = Blt_DBuffer_Extend(dbuffer, fileSize); memset(bp, 0, fileSize); /* File header. */ bp[0] = 'B', bp[1] = 'M'; BmpSetLong(bp + OFF_FILE_SIZE, fileSize); BmpSetLong(bp + OFF_OFFBITS, offsetToData); /* Image header. */ BmpSetLong (bp + OFF_SIZE, infoHeaderSize); BmpSetLong (bp + OFF_WIDTH, srcPtr->width); BmpSetLong (bp + OFF_HEIGHT, srcPtr->height); BmpSetShort(bp + OFF_PLANES, 1); BmpSetShort(bp + OFF_BIT_COUNT, bitsPerPixel); BmpSetLong (bp + OFF_COMPRESSION, format); BmpSetLong (bp + OFF_SIZE_IMAGE, bytesPerRow * srcPtr->height); BmpSetLong (bp + OFF_X_PELS_PER_METER, 0); BmpSetLong (bp + OFF_Y_PELS_PER_METER, 0); BmpSetLong (bp + OFF_CLR_USED, nColors); BmpSetLong (bp + OFF_CLR_IMPORTANT, 0); if (bitsPerPixel == 32) { BmpSetLong(bp + OFF_RED_MASK, 0x00FF0000); /* biRedMask */ BmpSetLong(bp + OFF_GREEN_MASK, 0x0000FF00); /* biGreenMask */ BmpSetLong(bp + OFF_BLUE_MASK, 0x000000FF); /* biBlueMask */ BmpSetLong(bp + OFF_ALPHA_MASK, 0xFF000000); /* biAlphaMask */ } /* Color table. */ if (bitsPerPixel == 8) { unsigned long i; Blt_HashEntry *hPtr; Blt_HashSearch cursor; i = 0; bp += 14 + infoHeaderSize; for (hPtr = Blt_FirstHashEntry(&colorTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_Pixel pixel; unsigned long key; Blt_SetHashValue(hPtr, i); key = (unsigned long)Blt_GetHashKey(&colorTable, hPtr); pixel.u32 = (unsigned int)key; /* Colormap components are ordered BGBA. */ bp[0] = pixel.Blue; bp[1] = pixel.Green; bp[2] = pixel.Red; bp[3] = pixel.Alpha; bp += 4; i++; } assert(i == nColors); } destBits = Blt_DBuffer_Pointer(dbuffer) + offsetToData; /* Image data. */ switch (bitsPerPixel) { case 32: { Blt_Pixel *srcRowPtr; int y; unsigned char *destRowPtr; destRowPtr = destBits; srcRowPtr = srcPtr->bits+((srcPtr->height-1)*srcPtr->pixelsPerRow); for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp+srcPtr->width; sp < send; sp++) { BmpSetLong(dp, sp->u32); dp += 4; } destRowPtr += bytesPerRow; srcRowPtr -= srcPtr->pixelsPerRow; } assert((destRowPtr - Blt_DBuffer_Pointer(dbuffer)) == fileSize); } break; case 24: { Blt_Pixel *srcRowPtr; int y; unsigned char *destRowPtr; destRowPtr = destBits; srcRowPtr = srcPtr->bits+((srcPtr->height-1)*srcPtr->pixelsPerRow); for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp+srcPtr->width; sp < send; sp++) { dp[0] = sp->Blue; dp[1] = sp->Green; dp[2] = sp->Red; dp += 3; } destRowPtr += bytesPerRow; srcRowPtr -= srcPtr->pixelsPerRow; } assert((destRowPtr - Blt_DBuffer_Pointer(dbuffer)) == fileSize); } break; case 8: { Blt_Pixel *srcRowPtr; int y; unsigned char *destRowPtr; destRowPtr = destBits; srcRowPtr = srcPtr->bits+((srcPtr->height-1)*srcPtr->pixelsPerRow); for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp+srcPtr->width; sp < send; sp++) { Blt_HashEntry *hPtr; unsigned long index; union { Blt_Pixel color; char *key; } value; value.color.u32 = sp->u32; value.color.Alpha = 0xFF; hPtr = Blt_FindHashEntry(&colorTable, value.key); if (hPtr == NULL) { fprintf(stderr, "can't find %x\n", sp->u32); continue; } index = (unsigned long)Blt_GetHashValue(hPtr); *dp = (unsigned char)(index & 0xFF); dp++; } destRowPtr += bytesPerRow; srcRowPtr -= srcPtr->pixelsPerRow; } assert((destRowPtr - Blt_DBuffer_Pointer(dbuffer)) == fileSize); } break; } if (bitsPerPixel == 8) { Blt_DeleteHashTable(&colorTable); } if (srcPtr != original) { Blt_FreePicture(srcPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsBmp -- * * Attempts to parse a BMP file header. * * Results: * Returns 1 is the header is BMP and 0 otherwise. Note that * the validity of the header contents is not checked here. That's * done in BmpToPicture. * *--------------------------------------------------------------------------- */ static int IsBmp(Blt_DBuffer dbuffer) { Bmp bmp; return BmpHeader(dbuffer, &bmp); } static Blt_Chain ReadBmp(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { BmpImportSwitches switches; memset(&switches, 0, sizeof(switches)); return BmpToPicture(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WriteBmp(Tcl_Interp *interp, Blt_Picture picture) { Blt_DBuffer dbuffer; BmpExportSwitches switches; Tcl_Obj *objPtr; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* white */ dbuffer = Blt_DBuffer_Create(); objPtr = NULL; if (PictureToBmp(interp, picture, dbuffer, &switches) == TCL_OK) { char *bytes; bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } } return objPtr; } static Blt_Chain ImportBmp( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_DBuffer dbuffer; Blt_Chain chain; const char *string; BmpImportSwitches switches; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_SaveFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = BmpToPicture(interp, string, dbuffer, &switches); if (chain == NULL) { return NULL; } error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportBmp(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer dbuffer; Blt_Picture picture; BmpExportSwitches switches; int result; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data switch.", (char *)NULL); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "bad picture index.", (char *)NULL); return TCL_ERROR; } dbuffer = Blt_DBuffer_Create(); result = PictureToBmp(interp, picture, dbuffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { const char *fileName; /* Write the image into the designated file. */ fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; /* Write the image into the designated TCL variable. */ objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; /* Return the image as a base64 string in the interpreter result. */ result = TCL_ERROR; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); result = TCL_OK; } } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PictureBmpInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_bmp", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "bmp", /* Name of format. */ IsBmp, /* Discovery routine. */ ReadBmp, /* Read format procedure. */ WriteBmp, /* Write format procedure. */ ImportBmp, /* Import format procedure. */ ExportBmp); /* Export format switches. */ } ��������������./saods9/blt3.0.1/src/bltChain.h��������������������������������������������������������������������0000644�0001750�0001750�00000007202�11462120062�014723� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltChain.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_CHAIN_H #define _BLT_CHAIN_H typedef struct _Blt_Chain *Blt_Chain; typedef struct _Blt_ChainLink *Blt_ChainLink; /* * A Blt_ChainLink is the container structure for the Blt_Chain. */ struct _Blt_ChainLink { Blt_ChainLink prev; /* Link to the previous link */ Blt_ChainLink next; /* Link to the next link */ ClientData clientData; /* Pointer to the data object */ }; typedef int (Blt_ChainCompareProc)(Blt_ChainLink *l1Ptr, Blt_ChainLink *l2Ptr); /* * A Blt_Chain is a doubly chained list structure. */ struct _Blt_Chain { Blt_ChainLink head; /* Pointer to first element in chain */ Blt_ChainLink tail; /* Pointer to last element in chain */ long nLinks; /* Number of elements in chain */ }; BLT_EXTERN void Blt_Chain_Init(Blt_Chain chain); BLT_EXTERN Blt_Chain Blt_Chain_Create(void); BLT_EXTERN void Blt_Chain_Destroy(Blt_Chain chain); BLT_EXTERN Blt_ChainLink Blt_Chain_NewLink(void); BLT_EXTERN Blt_ChainLink Blt_Chain_AllocLink(size_t size); BLT_EXTERN Blt_ChainLink Blt_Chain_Append(Blt_Chain chain, ClientData clientData); BLT_EXTERN Blt_ChainLink Blt_Chain_Prepend(Blt_Chain chain, ClientData clientData); BLT_EXTERN void Blt_Chain_Reset(Blt_Chain chain); BLT_EXTERN void Blt_Chain_InitLink(Blt_ChainLink link); BLT_EXTERN void Blt_Chain_LinkAfter(Blt_Chain chain, Blt_ChainLink link, Blt_ChainLink after); BLT_EXTERN void Blt_Chain_LinkBefore(Blt_Chain chain, Blt_ChainLink link, Blt_ChainLink before); BLT_EXTERN void Blt_Chain_UnlinkLink(Blt_Chain chain, Blt_ChainLink link); BLT_EXTERN void Blt_Chain_DeleteLink(Blt_Chain chain, Blt_ChainLink link); BLT_EXTERN Blt_ChainLink Blt_Chain_GetNthLink(Blt_Chain chain, long position); BLT_EXTERN void Blt_Chain_Sort(Blt_Chain chain, Blt_ChainCompareProc *proc); BLT_EXTERN int Blt_Chain_IsBefore(Blt_ChainLink first, Blt_ChainLink last); #define Blt_Chain_GetLength(c) (((c) == NULL) ? 0 : (c)->nLinks) #define Blt_Chain_FirstLink(c) (((c) == NULL) ? NULL : (c)->head) #define Blt_Chain_LastLink(c) (((c) == NULL) ? NULL : (c)->tail) #define Blt_Chain_PrevLink(l) ((l)->prev) #define Blt_Chain_NextLink(l) ((l)->next) #define Blt_Chain_GetValue(l) ((l)->clientData) #define Blt_Chain_FirstValue(c) (((c)->head == NULL) ? NULL : (c)->head->clientData) #define Blt_Chain_SetValue(l, value) ((l)->clientData = (ClientData)(value)) #define Blt_Chain_AppendLink(c, l) \ (Blt_Chain_LinkAfter((c), (l), (Blt_ChainLink)NULL)) #define Blt_Chain_PrependLink(c, l) \ (Blt_Chain_LinkBefore((c), (l), (Blt_ChainLink)NULL)) #endif /* _BLT_CHAIN_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltHash.c���������������������������������������������������������������������0000644�0001750�0001750�00000107635�11462120062�014572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltHash.c -- * * This module implements an in-memory hash table for the BLT toolkit. Built * upon the TCL hash table, it adds pool allocation 64-bit address handling, * improved array hash function. * * Copyright 2001 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Both the MIX32 and MIX64 routine are from Bob Jenkins. * * Bob Jenkins, 1996. hash.c. Public Domain. * Bob Jenkins, 1997. lookup8.c. Public Domain. * * The hash table implementation is base upon the one in the Tcl distribution. * * Copyright (c) 1991-1993 The Regents of the University of * California. * * Copyright (c) 1994 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #include <bltInt.h> #include <stdio.h> #include <string.h> /* The following header is required for LP64 compilation */ #include <stdlib.h> #include "bltHash.h" /* * When there are this many entries per bucket, on average, rebuild the hash * table to make it larger. */ #define REBUILD_MULTIPLIER 3 #if (SIZEOF_VOID_P == 8) #define RANDOM_INDEX HashOneWord #define DOWNSHIFT_START 62 static Blt_Hash HashOneWord(Blt_HashTable *tablePtr, const void *key); #else /* * The following macro takes a preliminary integer hash value and produces an * index into a hash tables bucket list. The idea is to make it so that * preliminary values that are arbitrarily similar will end up in different * buckets. The hash function was taken from a random-number generator. */ #define RANDOM_INDEX(tablePtr, i) \ (((((long) (i))*1103515245) >> (tablePtr)->downShift) & (tablePtr)->mask) #define DOWNSHIFT_START 28 #endif /* * Procedure prototypes for static procedures in this file: */ static Blt_Hash HashArray(const void *key, size_t length); static Blt_HashEntry *ArrayFind(Blt_HashTable *tablePtr, const void *key); static Blt_HashEntry *ArrayCreate(Blt_HashTable *tablePtr, const void *key, int *isNewPtr); static Blt_HashEntry *BogusFind(Blt_HashTable *tablePtr, const void *key); static Blt_HashEntry *BogusCreate(Blt_HashTable *tablePtr, const void *key, int *isNewPtr); static Blt_Hash HashString(const char *string); static void RebuildTable(Blt_HashTable *tablePtr); static Blt_HashEntry *StringFind(Blt_HashTable *tablePtr, const void *key); static Blt_HashEntry *StringCreate(Blt_HashTable *tablePtr, const void *key, int *isNewPtr); static Blt_HashEntry *OneWordFind(Blt_HashTable *tablePtr, const void *key); static Blt_HashEntry *OneWordCreate(Blt_HashTable *tablePtr, const void *key, int *isNewPtr); /* *--------------------------------------------------------------------------- * * HashString -- * * Compute a one-word summary of a text string, which can be used to * generate a hash index. * * Results: * The return value is a one-word summary of the information in string. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_Hash HashString(const char *string) /* String from which to compute hash * value. */ { Blt_Hash result; Blt_Hash c; /* * I tried a zillion different hash functions and asked many other * people for advice. Many people had their own favorite functions, * all different, but no-one had much idea why they were good ones. * I chose the one below (multiply by 9 and add new character) * because of the following reasons: * * 1. Multiplying by 10 is perfect for keys that are decimal strings, * and multiplying by 9 is just about as good. * 2. Times-9 is (shift-left-3) plus (old). This means that each * character's bits hang around in the low-order bits of the * hash value for ever, plus they spread fairly rapidly up to * the high-order bits to fill out the hash value. This seems * to work well both for decimal and non-decimal strings. */ result = 0; while ((c = *string++) != 0) { result += (result << 3) + c; } return (Blt_Hash)result; } /* *--------------------------------------------------------------------------- * * StringFind -- * * Given a hash table with string keys, and a string key, find the entry * with a matching key. * * Results: * The return value is a token for the matching entry in the hash table, * or NULL if there was no matching entry. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * StringFind( Blt_HashTable *tablePtr, /* Table in which to lookup entry. */ const void *key) /* Key to find matching entry. */ { Blt_Hash hval; Blt_HashEntry *hPtr; size_t hindex; hval = HashString((const char *)key); hindex = hval & tablePtr->mask; /* * Search all of the entries in the appropriate bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->hval == hval) { const char *p1, *p2; for (p1 = key, p2 = hPtr->key.string; ; p1++, p2++) { if (*p1 != *p2) { break; } if (*p1 == '\0') { return hPtr; } } } } return NULL; } /* *--------------------------------------------------------------------------- * * StringCreate -- * * Given a hash table with string keys, and a string key, find the entry * with a matching key. If there is no matching entry, then create a new * entry that does match. * * Results: * The return value is a pointer to the matching entry. If this is a * newly-created entry, then *isNewPtr will be set to a non-zero value; * otherwise *isNewPtr will be set to 0. If this is a new entry the * value stored in the entry will initially be 0. * * Side effects: * A new entry may be added to the hash table. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * StringCreate( Blt_HashTable *tablePtr, /* Table in which to lookup entry. */ const void *key, /* Key to use to find or create * matching entry. */ int *isNewPtr) /* Store info here telling whether a * new entry was created. */ { Blt_Hash hval; Blt_HashEntry **bucketPtr; Blt_HashEntry *hPtr; size_t size, hindex; hval = HashString(key); hindex = hval & tablePtr->mask; /* Search all of the entries in this bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->hval == hval) { const char *p1, *p2; for (p1 = key, p2 = hPtr->key.string; ; p1++, p2++) { if (*p1 != *p2) { break; } if (*p1 == '\0') { *isNewPtr = FALSE; return hPtr; } } } } /* Entry not found. Add a new one to the bucket. */ *isNewPtr = TRUE; size = sizeof(Blt_HashEntry) + strlen(key) - sizeof(Blt_HashKey) + 1; if (tablePtr->hPool != NULL) { hPtr = Blt_PoolAllocItem(tablePtr->hPool, size); } else { hPtr = Blt_AssertMalloc(size); } bucketPtr = tablePtr->buckets + hindex; hPtr->nextPtr = *bucketPtr; hPtr->hval = hval; hPtr->clientData = 0; strcpy(hPtr->key.string, key); *bucketPtr = hPtr; tablePtr->numEntries++; /* * If the table has exceeded a decent size, rebuild it with many more * buckets. */ if (tablePtr->numEntries >= tablePtr->rebuildSize) { RebuildTable(tablePtr); } return hPtr; } #if (SIZEOF_VOID_P == 8) /* *--------------------------------------------------------------------------- * * HashOneWord -- * * Compute a one-word hash value of a 64-bit word, which then can be used * to generate a hash index. * * From Knuth, it's a multiplicative hash. Multiplies an unsigned 64-bit * value with the golden ratio (sqrt(5) - 1) / 2. The downshift value is * 64 - n, where n is the log2 of the size of the hash table. * * Results: * The return value is a one-word summary of the information in 64 bit * word. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_Hash HashOneWord( Blt_HashTable *tablePtr, const void *key) { uint64_t a0, a1; uint64_t y0, y1; uint64_t y2, y3; uint64_t p1, p2; uint64_t result; /* Compute key * GOLDEN_RATIO in 128-bit arithmetic */ a0 = (uint64_t)key & 0x00000000FFFFFFFF; a1 = (uint64_t)key >> 32; y0 = a0 * 0x000000007f4a7c13; y1 = a0 * 0x000000009e3779b9; y2 = a1 * 0x000000007f4a7c13; y3 = a1 * 0x000000009e3779b9; y1 += y0 >> 32; /* Can't carry */ y1 += y2; /* Might carry */ if (y1 < y2) { y3 += (1LL << 32); /* Propagate */ } /* 128-bit product: p1 = loword, p2 = hiword */ p1 = ((y1 & 0x00000000FFFFFFFF) << 32) + (y0 & 0x00000000FFFFFFFF); p2 = y3 + (y1 >> 32); /* Left shift the value downward by the size of the table */ if (tablePtr->downShift > 0) { if (tablePtr->downShift < 64) { result = ((p2 << (64 - tablePtr->downShift)) | (p1 >> (tablePtr->downShift & 63))); } else { result = p2 >> (tablePtr->downShift & 63); } } else { result = p1; } /* Finally mask off the high bits */ return (Blt_Hash)(result & tablePtr->mask); } #endif /* SIZEOF_VOID_P == 8 */ /* *--------------------------------------------------------------------------- * * OneWordFind -- * * Given a hash table with one-word keys, and a one-word key, find the * entry with a matching key. * * Results: * The return value is a token for the matching entry in the hash table, * or NULL if there was no matching entry. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * OneWordFind( Blt_HashTable *tablePtr, /* Table where to lookup entry. */ const void *key) /* Key that we're searching for. */ { Blt_HashEntry *hPtr; size_t hindex; hindex = RANDOM_INDEX(tablePtr, key); /* Search all of the entries in the appropriate bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->key.oneWordValue == key) { return hPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * OneWordCreate -- * * Given a hash table with one-word keys, and a one-word key, find the * entry with a matching key. If there is no matching entry, then create * a new entry that does match. * * Results: * The return value is a pointer to the matching entry. If this is a * newly-created entry, then *isNewPtr will be set to a non-zero value; * otherwise *isNewPtr will be set to 0. If this is a new entry the value * stored in the entry will initially be 0. * * Side effects: * A new entry may be added to the hash table. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * OneWordCreate( Blt_HashTable *tablePtr, /* Table in which to lookup entry. */ const void *key, /* Key to use to find or create * matching entry. */ int *isNewPtr) /* Store info here telling whether a * new entry was created. */ { Blt_HashEntry **bucketPtr; Blt_HashEntry *hPtr; size_t hindex; hindex = RANDOM_INDEX(tablePtr, key); /* Search all of the entries in this bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->key.oneWordValue == key) { *isNewPtr = FALSE; return hPtr; } } /* Entry not found. Add a new one to the bucket. */ *isNewPtr = TRUE; if (tablePtr->hPool != NULL) { hPtr = Blt_PoolAllocItem(tablePtr->hPool, sizeof(Blt_HashEntry)); } else { hPtr = Blt_AssertMalloc(sizeof(Blt_HashEntry)); } bucketPtr = tablePtr->buckets + hindex; hPtr->nextPtr = *bucketPtr; hPtr->hval = (Blt_Hash)key; hPtr->clientData = 0; hPtr->key.oneWordValue = (void *)key; /* const XXXX */ *bucketPtr = hPtr; tablePtr->numEntries++; /* * If the table has exceeded a decent size, rebuild it with many more * buckets. */ if (tablePtr->numEntries >= tablePtr->rebuildSize) { RebuildTable(tablePtr); } return hPtr; } #if (SIZEOF_VOID_P == 4) /* *--------------------------------------------------------------------------- * * MIX32 -- * * Bob Jenkins, 1996. Public Domain. * * Mix 3 32/64-bit values reversibly. For every delta with one or two * bit set, and the deltas of all three high bits or all three low bits, * whether the original value of a,b,c is almost all zero or is uniformly * distributed, If mix() is run forward or backward, at least 32 bits in * a,b,c have at least 1/4 probability of changing. * If mix() is run * forward, every bit of c will change between 1/3 and 2/3 of the time. * (Well, 22/100 and 78/100 for some 2-bit deltas.) mix() was built out * of 36 single-cycle latency instructions in a structure that could * supported 2x parallelism, like so: * * a -= b; * a -= c; x = (c>>13); * b -= c; a ^= x; * b -= a; x = (a<<8); * c -= a; b ^= x; * c -= b; x = (b>>13); * ... * * Unfortunately, superscalar Pentiums and Sparcs can't take advantage * of that parallelism. They've also turned some of those single-cycle * latency instructions into multi-cycle latency instructions. Still, * this is the fastest good hash I could find. There were about 2^^68 * to choose from. I only looked at a billion or so. * * -------------------------------------------------------------------------- */ #define MIX32(a,b,c) \ a -= b, a -= c, a ^= (c >> 13), \ b -= c, b -= a, b ^= (a << 8), \ c -= a, c -= b, c ^= (b >> 13), \ a -= b, a -= c, a ^= (c >> 12), \ b -= c, b -= a, b ^= (a << 16), \ c -= a, c -= b, c ^= (b >> 5), \ a -= b, a -= c, a ^= (c >> 3), \ b -= c, b -= a, b ^= (a << 10), \ c -= a, c -= b, c ^= (b >> 15) #define GOLDEN_RATIO32 0x9e3779b9 /* An arbitrary value */ /* *--------------------------------------------------------------------------- * * HashArray -- * * Bob Jenkins, 1996. Public Domain. * * This works on all machines. Length has to be measured in unsigned * longs instead of bytes. It requires that * * o The key be an array of unsigned ints. * o All your machines have the same endianness * o The length be the number of unsigned ints in the key. * *--------------------------------------------------------------------------- */ static Blt_Hash HashArray(const void *key, size_t length) { uint32_t a, b, c, len; uint32_t *arrayPtr = (uint32_t *)key; /* Set up the internal state */ len = length; a = b = GOLDEN_RATIO32; /* An arbitrary value */ c = 0; /* Previous hash value */ while (len >= 3) { /* Handle most of the key */ a += arrayPtr[0]; b += arrayPtr[1]; c += arrayPtr[2]; MIX32(a, b, c); arrayPtr += 3; len -= 3; } c += length; /* And now the last 2 words */ /* Note that all the case statements fall through */ switch(len) { /* c is reserved for the length */ case 2 : b += arrayPtr[1]; case 1 : a += arrayPtr[0]; /* case 0: nothing left to add */ } MIX32(a, b, c); return (Blt_Hash)c; } #endif /* SIZEOF_VOID_P == 4 */ #if (SIZEOF_VOID_P == 8) /* *--------------------------------------------------------------------------- * * MIX64 -- * * Bob Jenkins, January 4 1997, Public Domain. You can use this free for * any purpose. It has no warranty. * * Returns a 64-bit value. Every bit of the key affects every bit of the * return value. No funnels. Every 1-bit and 2-bit delta achieves * avalanche. About 41+5len instructions. * * The best hash table sizes are powers of 2. There is no need to do mod * a prime (mod is sooo slow!). If you need less than 64 bits, use a * bitmask. For example, if you need only 10 bits, do h = (h & * hashmask(10)); In which case, the hash table should have hashsize(10) * elements. * * By Bob Jenkins, Jan 4 1997. bob_jenkins@burtleburtle.net. You may * use this code any way you wish, private, educational, or commercial, * as long as this whole comment accompanies it. * * See http://burtleburtle.net/bob/hash/evahash.html Use for hash table * lookup, or anything where one collision in 2^^64 * is acceptable. Do * NOT use for cryptographic purposes. * *--------------------------------------------------------------------------- */ #define MIX64(a,b,c) \ a -= b, a -= c, a ^= (c >> 43), \ b -= c, b -= a, b ^= (a << 9), \ c -= a, c -= b, c ^= (b >> 8), \ a -= b, a -= c, a ^= (c >> 38), \ b -= c, b -= a, b ^= (a << 23), \ c -= a, c -= b, c ^= (b >> 5), \ a -= b, a -= c, a ^= (c >> 35), \ b -= c, b -= a, b ^= (a << 49), \ c -= a, c -= b, c ^= (b >> 11), \ a -= b, a -= c, a ^= (c >> 12), \ b -= c, b -= a, b ^= (a << 18), \ c -= a, c -= b, c ^= (b >> 22) #define GOLDEN_RATIO64 0x9e3779b97f4a7c13LL /* *--------------------------------------------------------------------------- * * HashArray -- * * Bob Jenkins, January 4 1997, Public Domain. You can use this free for * any purpose. It has no warranty. * * This works on all machines. The length has to be measured in 64 bit * words, instead of bytes. It requires that * * o The key be an array of 64 bit words (unsigned longs). * o All your machines have the same endianness. * o The length be the number of 64 bit words in the key. * *--------------------------------------------------------------------------- */ static Blt_Hash HashArray(const void *key, size_t length) { uint64_t a, b, c, len; uint32_t *ip = (uint32_t *)key; #ifdef WORDS_BIGENDIAN #define PACK(a,b) ((uint64_t)(b) | ((uint64_t)(a) << 32)) #else #define PACK(a,b) ((uint64_t)(a) | ((uint64_t)(b) << 32)) #endif /* Set up the internal state */ len = length; /* Length is the number of 64-bit * words. */ a = b = GOLDEN_RATIO64; /* An arbitrary value */ c = 0; /* Previous hash value */ while (len >= 6) { /* Handle most of the key */ a += PACK(ip[0], ip[1]); b += PACK(ip[2], ip[3]); c += PACK(ip[4], ip[5]); MIX64(a,b,c); ip += 6; len -= 6; } c += length; /* And now the last 2 words */ /* Note that all the case statements fall through */ switch(len) { /* c is reserved for the length */ case 5 : case 4 : a += PACK(ip[0], ip[1]); b += PACK(ip[2], ip[3]); ip += 4; len -= 4; break; case 3 : case 2 : a += PACK(ip[0], ip[1]); ip += 2; len -= 2; /* case 0: nothing left to add */ } if (len > 0) { b += ip[0]; } MIX64(a,b,c); return (Blt_Hash)c; } #endif /* SIZEOF_VOID_P == 8 */ /* *--------------------------------------------------------------------------- * * ArrayFind -- * * Given a hash table with array-of-int keys, and a key, find the entry * with a matching key. * * Results: * The return value is a token for the matching entry in the hash table, * or NULL if there was no matching entry. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * ArrayFind( Blt_HashTable *tablePtr, /* Table in which to lookup entry. */ const void *key) /* Key to use to find matching entry. */ { Blt_Hash hval; Blt_HashEntry *hPtr; size_t hindex; hval = HashArray(key, tablePtr->keyType); hindex = hval & tablePtr->mask; /* Search all of the entries in the appropriate bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->hval == hval) { uint32_t *ip1, *ip2; size_t count; for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words, count = tablePtr->keyType; ; count--, ip1++, ip2++) { if (count == 0) { return hPtr; } if (*ip1 != *ip2) { break; } } } } return NULL; } /* *--------------------------------------------------------------------------- * * ArrayCreate -- * * Given a hash table with one-word keys, and a one-word key, find the * entry with a matching key. If there is no matching entry, then create a * new entry that does match. * * Results: * The return value is a pointer to the matching entry. If this is a * newly-created entry, then *isNewPtr will be set to a non-zero value; * otherwise *isNewPtr will be set to 0. If this is a new entry the value * stored in the entry will initially be 0. * * Side effects: * A new entry may be added to the hash table. * *--------------------------------------------------------------------------- */ static Blt_HashEntry * ArrayCreate( Blt_HashTable *tablePtr, /* Table in which to lookup entry. */ const void *key, /* Key to use to find or create * matching entry. */ int *isNewPtr) /* Store info here telling whether a * new entry was created. */ { Blt_Hash hval; Blt_HashEntry **bucketPtr; size_t count; Blt_HashEntry *hPtr; uint32_t *ip1, *ip2; size_t size, hindex; hval = HashArray(key, tablePtr->keyType); hindex = hval & tablePtr->mask; /* Search all of the entries in the appropriate bucket. */ for (hPtr = tablePtr->buckets[hindex]; hPtr != NULL; hPtr = hPtr->nextPtr) { if (hPtr->hval == hval) { for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words, count = tablePtr->keyType; ; count--, ip1++, ip2++) { if (count == 0) { *isNewPtr = FALSE; return hPtr; } if (*ip1 != *ip2) { break; } } } } /* Entry not found. Add a new one to the bucket. */ *isNewPtr = TRUE; /* We assume here that the size of the key is at least 2 words */ size = sizeof(Blt_HashEntry) + tablePtr->keyType * sizeof(uint32_t) - sizeof(Blt_HashKey); if (tablePtr->hPool != NULL) { hPtr = Blt_PoolAllocItem(tablePtr->hPool, size); } else { hPtr = Blt_AssertMalloc(size); } bucketPtr = tablePtr->buckets + hindex; hPtr->nextPtr = *bucketPtr; hPtr->hval = hval; hPtr->clientData = 0; count = tablePtr->keyType; for (ip1 = (uint32_t *)key, ip2 = (uint32_t *)hPtr->key.words; count > 0; count--, ip1++, ip2++) { *ip2 = *ip1; } *bucketPtr = hPtr; tablePtr->numEntries++; /* * If the table has exceeded a decent size, rebuild it with many more * buckets. */ if (tablePtr->numEntries >= tablePtr->rebuildSize) { RebuildTable(tablePtr); } return hPtr; } /* *--------------------------------------------------------------------------- * * BogusFind -- * * This procedure is invoked when an Blt_FindHashEntry is called on a * table that has been deleted. * * Results: * If panic returns (which it shouldn't) this procedure returns NULL. * * Side effects: * Generates a panic. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static Blt_HashEntry * BogusFind( Blt_HashTable *tablePtr, /* Not used. */ const void *key) /* Not used.*/ { Blt_Panic("called Blt_FindHashEntry on deleted table"); return NULL; } /* *--------------------------------------------------------------------------- * * BogusCreate -- * * This procedure is invoked when an Blt_CreateHashEntry is called on a * table that has been deleted. * * Results: * If panic returns (which it shouldn't) this procedure returns NULL. * * Side effects: * Generates a panic. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static Blt_HashEntry * BogusCreate( Blt_HashTable *tablePtr, /* Not used. */ const void *key, /* Not used. */ int *isNewPtr) /* Not used. */ { Blt_Panic("called Blt_CreateHashEntry on deleted table"); return NULL; } /* *--------------------------------------------------------------------------- * * RebuildTable -- * * This procedure is invoked when the ratio of entries to hash buckets * becomes too large. It creates a new table with a larger bucket array * and moves all of the entries into the new table. * * Results: * None. * * Side effects: * Memory gets reallocated and entries get re-hashed to new buckets. * *--------------------------------------------------------------------------- */ static void RebuildTable(Blt_HashTable *tablePtr) /* Table to enlarge. */ { Blt_HashEntry **oldBuckets; int oldNumBuckets; oldBuckets = tablePtr->buckets; oldNumBuckets = tablePtr->numBuckets; /* * Allocate and initialize the new bucket array, and set up hashing * constants for new array size. */ tablePtr->numBuckets <<= 2; tablePtr->buckets = Blt_AssertCalloc(tablePtr->numBuckets, sizeof(Blt_HashEntry *)); tablePtr->rebuildSize <<= 2; tablePtr->downShift -= 2; tablePtr->mask = tablePtr->numBuckets - 1; /* * Move all of the existing entries into the new bucket array, based on * their hash values. */ if (tablePtr->keyType == BLT_ONE_WORD_KEYS) { Blt_HashEntry **hpp, **hend; /* * BLT_ONE_WORD_KEYS are handled slightly differently because they use * the current table size (number of buckets) to distribute the entries. */ for (hpp = oldBuckets, hend = hpp + oldNumBuckets; hpp < hend; hpp++) { Blt_HashEntry *hPtr, *nextPtr; for (hPtr = *hpp; hPtr != NULL; hPtr = nextPtr) { Blt_HashEntry **bucketPtr; size_t hindex; nextPtr = hPtr->nextPtr; hindex = RANDOM_INDEX(tablePtr, hPtr->key.oneWordValue); bucketPtr = tablePtr->buckets + hindex; hPtr->nextPtr = *bucketPtr; *bucketPtr = hPtr; } } } else { Blt_HashEntry **hpp, **hend; for (hpp = oldBuckets, hend = hpp + oldNumBuckets; hpp < hend; hpp++) { Blt_HashEntry *hPtr, *nextPtr; for (hPtr = *hpp; hPtr != NULL; hPtr = nextPtr) { Blt_HashEntry **bucketPtr; size_t hindex; nextPtr = hPtr->nextPtr; hindex = hPtr->hval & tablePtr->mask; bucketPtr = tablePtr->buckets + hindex; hPtr->nextPtr = *bucketPtr; *bucketPtr = hPtr; } } } /* * Free up the old bucket array, if it was dynamically allocated. */ if (oldBuckets != tablePtr->staticBuckets) { Blt_Free(oldBuckets); } } /* Public hash table routines */ /* *--------------------------------------------------------------------------- * * Blt_InitHashTable -- * * Given storage for a hash table, set up the fields to prepare the hash * table for use. * * Results: * None. * * Side effects: * TablePtr is now ready to be passed to Blt_FindHashEntry and * Blt_CreateHashEntry. * *--------------------------------------------------------------------------- */ void Blt_InitHashTable(Blt_HashTable *tablePtr, size_t keyType) { #if (BLT_SMALL_HASH_TABLE != 4) Blt_Panic("Blt_InitHashTable: BLT_SMALL_HASH_TABLE is %d, not 4\n", BLT_SMALL_HASH_TABLE); #endif tablePtr->buckets = tablePtr->staticBuckets; tablePtr->numBuckets = BLT_SMALL_HASH_TABLE; tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0; tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0; tablePtr->numEntries = 0; tablePtr->rebuildSize = BLT_SMALL_HASH_TABLE * REBUILD_MULTIPLIER; tablePtr->downShift = DOWNSHIFT_START; /* The number of buckets is always a power of 2, so we can generate the mask * by simply subtracting 1 from the number of buckets. */ tablePtr->mask = (Blt_Hash)(tablePtr->numBuckets - 1); tablePtr->keyType = keyType; switch (keyType) { case BLT_STRING_KEYS: /* NUL terminated string keys. */ tablePtr->findProc = StringFind; tablePtr->createProc = StringCreate; break; case BLT_ONE_WORD_KEYS: /* 32 or 64-bit atomic keys. */ tablePtr->findProc = OneWordFind; tablePtr->createProc = OneWordCreate; break; default: /* Structures/arrays. */ if (keyType == 0) { Blt_Panic("Blt_InitHashTable: Key size can't be %d, must be > 0\n", keyType); } tablePtr->findProc = ArrayFind; tablePtr->createProc = ArrayCreate; break; } tablePtr->hPool = NULL; } /* *--------------------------------------------------------------------------- * * Blt_InitHashTableWithPool -- * * Given storage for a hash table, set up the fields to prepare the hash * table for use. The only difference between this routine and * Blt_InitHashTable is that is uses a pool allocator to allocate memory * for hash table entries. The type of pool is either fixed or variable * size (string) keys. * * Results: * None. * * Side effects: * TablePtr is now ready to be passed to Blt_FindHashEntry and * Blt_CreateHashEntry. * *--------------------------------------------------------------------------- */ void Blt_InitHashTableWithPool(Blt_HashTable *tablePtr, size_t keyType) { Blt_InitHashTable(tablePtr, keyType); if (keyType == BLT_STRING_KEYS) { tablePtr->hPool = Blt_PoolCreate(BLT_VARIABLE_SIZE_ITEMS); } else { tablePtr->hPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); } } /* *--------------------------------------------------------------------------- * * Blt_DeleteHashEntry -- * * Remove a single entry from a hash table. * * Results: * None. * * Side effects: * The entry given by entryPtr is deleted from its table and should never * again be used by the caller. It is up to the caller to free the * clientData field of the entry, if that is relevant. * *--------------------------------------------------------------------------- */ void Blt_DeleteHashEntry(Blt_HashTable *tablePtr, Blt_HashEntry *entryPtr) { Blt_HashEntry **bucketPtr; size_t hindex; if (tablePtr->keyType == BLT_ONE_WORD_KEYS) { hindex = RANDOM_INDEX(tablePtr, (const void *)entryPtr->hval); } else { hindex = (entryPtr->hval & tablePtr->mask); } bucketPtr = tablePtr->buckets + hindex; if (*bucketPtr == entryPtr) { *bucketPtr = entryPtr->nextPtr; } else { Blt_HashEntry *prevPtr; for (prevPtr = *bucketPtr; /*empty*/; prevPtr = prevPtr->nextPtr) { if (prevPtr == NULL) { Blt_Panic("malformed bucket chain in Blt_DeleteHashEntry"); } if (prevPtr->nextPtr == entryPtr) { prevPtr->nextPtr = entryPtr->nextPtr; break; } } } tablePtr->numEntries--; if (tablePtr->hPool != NULL) { Blt_PoolFreeItem(tablePtr->hPool, entryPtr); } else { Blt_Free(entryPtr); } } /* *--------------------------------------------------------------------------- * * Blt_DeleteHashTable -- * * Free up everything associated with a hash table except for the record * for the table itself. * * Results: * None. * * Side effects: * The hash table is no longer useable. * *--------------------------------------------------------------------------- */ void Blt_DeleteHashTable(Blt_HashTable *tablePtr) /* Table to delete. */ { /* Free up all the entries in the table. */ if (tablePtr->hPool != NULL) { Blt_PoolDestroy(tablePtr->hPool); tablePtr->hPool = NULL; } else { size_t i; for (i = 0; i < tablePtr->numBuckets; i++) { Blt_HashEntry *hPtr; hPtr = tablePtr->buckets[i]; while (hPtr != NULL) { Blt_HashEntry *nextPtr; nextPtr = hPtr->nextPtr; Blt_Free(hPtr); hPtr = nextPtr; } } } /* Free up the bucket array, if it was dynamically allocated. */ if (tablePtr->buckets != tablePtr->staticBuckets) { Blt_Free(tablePtr->buckets); } /* * Arrange for panics if the table is used again without re-initialization. */ tablePtr->findProc = BogusFind; tablePtr->createProc = BogusCreate; } /* *--------------------------------------------------------------------------- * * Blt_FirstHashEntry -- * * Locate the first entry in a hash table and set up a record that can be * used to step through all the remaining entries of the table. * * Results: * The return value is a pointer to the first entry in tablePtr, or NULL * if tablePtr has no entries in it. The memory at *searchPtr is * initialized so that subsequent calls to Blt_NextHashEntry will return * all of the entries in the table, one at a time. * * Side effects: * None. * *--------------------------------------------------------------------------- */ Blt_HashEntry * Blt_FirstHashEntry( Blt_HashTable *tablePtr, /* Table to search. */ Blt_HashSearch *searchPtr) /* Place to store information about * progress through the table. */ { searchPtr->tablePtr = tablePtr; searchPtr->nextIndex = 0; searchPtr->nextEntryPtr = NULL; return Blt_NextHashEntry(searchPtr); } /* *--------------------------------------------------------------------------- * * Blt_NextHashEntry -- * * Once a hash table enumeration has been initiated by calling * Blt_FirstHashEntry, this procedure may be called to return successive * elements of the table. * * Results: * The return value is the next entry in the hash table being enumerated, * or NULL if the end of the table is reached. * * Side effects: * None. * *--------------------------------------------------------------------------- */ Blt_HashEntry * Blt_NextHashEntry(Blt_HashSearch *searchPtr) { Blt_HashEntry *hPtr; while (searchPtr->nextEntryPtr == NULL) { if (searchPtr->nextIndex >= searchPtr->tablePtr->numBuckets) { return NULL; } searchPtr->nextEntryPtr = searchPtr->tablePtr->buckets[searchPtr->nextIndex]; searchPtr->nextIndex++; } hPtr = searchPtr->nextEntryPtr; searchPtr->nextEntryPtr = hPtr->nextPtr; return hPtr; } /* *--------------------------------------------------------------------------- * * Blt_HashStats -- * * Return statistics describing the layout of the hash table in its hash * buckets. * * Results: * The return value is a malloc-ed string containing information about * tablePtr. It is the caller's responsibility to free this string. * * Side effects: * None. * *--------------------------------------------------------------------------- */ const char * Blt_HashStats(Blt_HashTable *tablePtr) /* Table for which to produce stats. */ { Blt_HashEntry **bp, **bend; char *result, *p; double average, tmp; #define NUM_COUNTERS 10 size_t count[NUM_COUNTERS], overflow, i, max; /* Compute a histogram of bucket usage. */ for (i = 0; i < NUM_COUNTERS; i++) { count[i] = 0; } overflow = 0; average = 0.0; max = 0; for (bp = tablePtr->buckets, bend = bp + tablePtr->numBuckets; bp < bend; bp++) { Blt_HashEntry *hPtr; size_t j; j = 0; for (hPtr = *bp; hPtr != NULL; hPtr = hPtr->nextPtr) { j++; } if (j > max) { max = j; } if (j < NUM_COUNTERS) { count[j]++; } else { overflow++; } tmp = j; average += (tmp+1.0)*(tmp/tablePtr->numEntries)/2.0; } /* Print out the histogram and a few other pieces of information. */ result = Blt_AssertMalloc((unsigned) ((NUM_COUNTERS*60) + 300)); sprintf(result, "%lu entries in table, %lu buckets\n", (unsigned long)tablePtr->numEntries, (unsigned long)tablePtr->numBuckets); p = result + strlen(result); for (i = 0; i < NUM_COUNTERS; i++) { sprintf(p, "number of buckets with %lu entries: %lu\n", (unsigned long)i, (unsigned long)count[i]); p += strlen(p); } sprintf(p, "number of buckets with %d or more entries: %lu\n", NUM_COUNTERS, (unsigned long)overflow); p += strlen(p); sprintf(p, "average search distance for entry: %.2f\n", average); p += strlen(p); sprintf(p, "maximum search distance for entry: %lu", (unsigned long)max); return result; } ���������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrContour.c����������������������������������������������������������������0000644�0001750�0001750�00000234301�11462120062�015620� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrContour.c -- * * This module implements contour elements for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include <X11/Xutil.h> #include "bltGrElem.h" /* * .c element create * .c level create name 0 0 -min -max -foreground -linewidth -background -color * .c level configure * .c level closest x y * .c element closest x y * .c element level add x y z */ typedef struct { float x, y; } MeshKey; typedef struct { float x, y, z; } Point3; typedef struct { Point3 *A, Point3 *B; /* Index of two edge points in x, y, and * z vectors. */ } Edge; typedef struct { Edge *AB, *BC, *AC; } Triangle; typedef struct { double min, max; /* Minimum and maximum values for the triangle * indexed at the same value. */ } Limits; typedef struct { ElemValues *x, *y; } MeshKey; typedef struct { int refCount; /* Indicates how many contour elements are * using this mesh. When refCount is zero, it * means that this mesh can be destroyed. */ ElemValues *x, *y; /* The x and y vectors containing the points * of the mesh. */ long nPoints; /* The number of points in the mesh */ Edge *edges; /* Array of edges generated from the points. */ long nEdges; /* # of edges in above array. */ Triangle *triangles; /* Array of triangles generated from the * edges. */ long nTriangles; /* # of triangles in the above array. */ } TriMesh; typedef struct { Point2d a, b, c; /* Filled triangle. */ struct Polygon3 *next; } Polygon3; typedef struct { Point2d a, b, c, d; /* Filled quadrilateral. */ struct Polygon4 *next; } Polygon4; typedef struct { char *name; /* */ char *label; /* Label to be displayed in the legend. */ double min, max; int symbol; /* Symbol to be displayed at each point. */ int lineWidth; /* Width of contour line. */ Dashes dashes; XColor *bgColor, *fgColor; GC fillGC; GC lineGC; Polygon4 *quadilaterals; int nQuads; Polygon3 *triangles; int nTriangles; Segment2d *segments; int nSegments; } ContourLevel; typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to elements. */ char *label; /* Label displayed in legend. There may be * sub-labels for each contour range/value. */ unsigned short row, col; /* Position of the entry in the legend. */ int legendRelief; /* Relief of label in legend. */ Axis2d axes; /* X-axis and Y-axis mapping the element */ ElemValues x, y, w; /* Contains array of floating point graph * coordinate values. Also holds min/max and * the number of coordinates */ int *activeIndices; /* Array of indices (malloc-ed) which indicate * which data points are active (drawn with * "active" colors). */ int nActiveIndices; /* Number of active data points. Special * case: if nActiveIndices < 0 and the active * bit is set in "flags", then all data points * are drawn active. */ ElementProcs *procsPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications. */ Pen *activePenPtr; /* Standard Pens */ Pen *normalPenPtr; Pen *builtinPenPtr; /* There is no style for a particular x, y */ Blt_Chain stylePalette; /* Palette of pens. */ /* Symbol scaling */ int scaleSymbols; /* If non-zero, the symbols will scale in size * as the graph is zoomed in/out. */ double xRange, yRange; /* Initial X-axis and Y-axis ranges: used to * scale the size of element's symbol. */ int state; TriMesh *meshPtr; /* Mesh associated with contour data set. */ ElemValues z; Limits *limits; /* Array of limits (min/max) associated with * each triangle in the above mesh. */ } ContourElement; typedef struct { float x1, y1, x2, y2; } BarRegion; typedef struct { char *name; /* Pen style identifier. If NULL pen was * statically allocated. */ ClassId classId; /* Type of pen */ char *typeId; /* String token identifying the type of pen */ unsigned int flags; /* Indicates if the pen element is active or * normal */ int refCount; /* Reference count for elements using * this pen. */ Blt_HashEntry *hashPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications */ PenConfigureProc *configProc; PenDestroyProc *destroyProc; Graph *graphPtr; /* Graph that the pen is associated with. */ /* Contour Plot specific pen fields start here. */ XColor *fgColor; /* Foreground color of bar */ Blt_Background bg; /* 3D border and background color */ int borderWidth; /* 3D border width of bar */ int relief; /* Relief of the bar */ Pixmap stipple; /* Stipple */ GC gc; /* Graphics context */ /* Error bar attributes. */ int errorBarShow; /* Describes which error bars to display: * none, x, y, or * both. */ int errorBarLineWidth; /* Width of the error bar segments. */ int errorBarCapWidth; XColor *errorBarColor; /* Color of the error bar. */ GC errorBarGC; /* Error bar graphics context. */ /* Show value attributes. */ int valueShow; /* Indicates whether to display data value. * Values are x, y, or none. */ char *valueFormat; /* A printf format string. */ TextStyle valueStyle; /* Text attributes (color, font, rotation, * etc.) of the value. */ } ContourPen; typedef struct { Weight weight; /* Weight range where this pen is valid. */ ContourPen *penPtr; /* Pen to use. */ XRectangle *bars; /* Indicates starting location in bar array * for this pen. */ int nBars; /* Number of bar segments for this pen. */ GraphSegments xeb, yeb; /* X and Y error bars. */ int symbolSize; /* Size of the pen's symbol scaled to the * current graph size. */ int errorBarCapWidth; /* Length of the cap ends on each error * bar. */ } ContourStyle; typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to elements. */ char *label; /* Label displayed in legend */ int legendRelief; /* Relief of label in legend. */ Axis2d axes; /* X-axis and Y-axis mapping the element */ ElemValues x, y, w; /* Contains array of floating point graph * coordinate values. Also holds min/max and * the number of coordinates */ int *activeIndices; /* Array of indices (malloc-ed) which indicate * which data points are active (drawn with * "active" colors). */ int nActiveIndices; /* Number of active data points. Special * case: if nActiveIndices < 0 and the active * bit is set in "flags", then all data points * are drawn active. */ ElementProcs *procsPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications. */ ContourPen *activePenPtr; /* Standard Pens */ ContourPen *normalPenPtr; ContourPen *builtinPenPtr; Blt_Chain stylePalette; /* Palette of pens. */ /* Symbol scaling */ int scaleSymbols; /* If non-zero, the symbols will scale in size * as the graph is zoomed in/out. */ double xRange, yRange; /* Initial X-axis and Y-axis ranges: used to * scale the size of element's symbol. */ int state; /* Fields specific to the contour element */ float barWidth; int *barToData; XRectangle *bars; /* Array of rectangles comprising the bar * segments of the element. */ int *activeToData; XRectangle *activeRects; int nBars; /* # of visible bar segments for element */ int nActive; ContourPen builtinPen; ElemValues z; /* Contains array of floating point graph * coordinate values. Also holds min/max and * the number of coordinates */ Triangle *triangles; int nTriangles; } ContourElement; BLT_EXTERN Blt_CustomOption bltContourPenOption; BLT_EXTERN Blt_CustomOption bltValuesOption; BLT_EXTERN Blt_CustomOption bltValuePairsOption; BLT_EXTERN Blt_CustomOption bltXAxisOption; BLT_EXTERN Blt_CustomOption bltYAxisOption; BLT_EXTERN Blt_CustomOption bltColorOption; BLT_EXTERN Blt_CustomOption bltContourStylesOption; static Blt_OptionParseProc ObjToBarMode; static Blt_OptionPrintProc BarModeToObj; Blt_CustomOption bltBarModeOption = { ObjToBarMode, BarModeToObj, NULL, (ClientData)0 }; #define DEF_CONTOUR_ACTIVE_PEN "activeBar" #define DEF_CONTOUR_AXIS_X "x" #define DEF_CONTOUR_AXIS_Y "y" #define DEF_CONTOUR_BACKGROUND "navyblue" #define DEF_CONTOUR_BORDERWIDTH "2" #define DEF_CONTOUR_ERRORBAR_COLOR "defcolor" #define DEF_CONTOUR_ERRORBAR_LINE_WIDTH "1" #define DEF_CONTOUR_ERRORBAR_CAP_WIDTH "1" #define DEF_CONTOUR_FOREGROUND "blue" #define DEF_CONTOUR_HIDE "no" #define DEF_CONTOUR_LABEL_RELIEF "flat" #define DEF_CONTOUR_NORMAL_STIPPLE "" #define DEF_CONTOUR_RELIEF "raised" #define DEF_CONTOUR_SHOW_ERRORBARS "both" #define DEF_CONTOUR_STATE "normal" #define DEF_CONTOUR_STYLES "" #define DEF_CONTOUR_TAGS "all" #define DEF_CONTOUR_WIDTH "0.0" #define DEF_PEN_ACTIVE_BACKGROUND "red" #define DEF_PEN_ACTIVE_FOREGROUND "pink" #define DEF_PEN_BORDERWIDTH "2" #define DEF_PEN_NORMAL_BACKGROUND "navyblue" #define DEF_PEN_NORMAL_FOREGROUND "blue" #define DEF_PEN_RELIEF "raised" #define DEF_PEN_STIPPLE "" #define DEF_PEN_TYPE "bar" #define DEF_PEN_VALUE_ANCHOR "s" #define DEF_PEN_VALUE_COLOR RGB_BLACK #define DEF_PEN_VALUE_FONT STD_FONT_SMALL #define DEF_PEN_VALUE_FORMAT "%g" #define DEF_PEN_SHOW_VALUES "no" static Blt_ConfigSpec contourPenConfigSpecs[] = { {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_PEN_ACTIVE_BACKGROUND, Blt_Offset(ContourPen, bg), BLT_CONFIG_NULL_OK | ACTIVE_PEN}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_PEN_NORMAL_BACKGROUND, Blt_Offset(ContourPen, bg), BLT_CONFIG_NULL_OK | NORMAL_PEN}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_PEN_BORDERWIDTH, Blt_Offset(ContourPen, borderWidth), ALL_PENS}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_CONTOUR_ERRORBAR_COLOR, Blt_Offset(ContourPen, errorBarColor), ALL_PENS, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth","ErrorBarWidth", DEF_CONTOUR_ERRORBAR_LINE_WIDTH, Blt_Offset(ContourPen, errorBarLineWidth), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_CONTOUR_ERRORBAR_CAP_WIDTH, Blt_Offset(ContourPen, errorBarCapWidth), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_PEN_ACTIVE_FOREGROUND, Blt_Offset(ContourPen, fgColor), ACTIVE_PEN | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_PEN_NORMAL_FOREGROUND, Blt_Offset(ContourPen, fgColor), NORMAL_PEN | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_PEN_RELIEF, Blt_Offset(ContourPen, relief), ALL_PENS}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_CONTOUR_SHOW_ERRORBARS, Blt_Offset(ContourPen, errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(ContourPen, valueShow), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_PEN_STIPPLE, Blt_Offset(ContourPen, stipple), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_PEN_TYPE, Blt_Offset(ContourPen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(ContourPen, valueStyle.anchor), ALL_PENS}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(ContourPen, valueStyle.color), ALL_PENS}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(ContourPen, valueStyle.font), ALL_PENS}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(ContourPen, valueFormat), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", (char *)NULL, Blt_Offset(ContourPen, valueStyle.angle), ALL_PENS}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec contourElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", DEF_CONTOUR_ACTIVE_PEN, Blt_Offset(ContourElement, activePenPtr), BLT_CONFIG_NULL_OK, &bltContourPenOption}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_CONTOUR_BACKGROUND, Blt_Offset(ContourElement, builtinPen.bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-barwidth", "barWidth", "BarWidth", DEF_CONTOUR_WIDTH, Blt_Offset(ContourElement, barWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL,(char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_CONTOUR_TAGS, Blt_Offset(ContourElement, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_CONTOUR_BORDERWIDTH, Blt_Offset(ContourElement, builtinPen.borderWidth), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-data", "data", "Data", (char *)NULL, 0, 0, &bltValuePairsOption}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_CONTOUR_FOREGROUND, Blt_Offset(ContourElement, builtinPen.fgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, Blt_Offset(ContourElement, label), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief", DEF_CONTOUR_LABEL_RELIEF, Blt_Offset(ContourElement, legendRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_CONTOUR_HIDE, Blt_Offset(ContourElement, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_CONTOUR_AXIS_X, Blt_Offset(ContourElement, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_CONTOUR_AXIS_Y, Blt_Offset(ContourElement, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, Blt_Offset(ContourElement, normalPenPtr), BLT_CONFIG_NULL_OK, &bltContourPenOption}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_CONTOUR_RELIEF, Blt_Offset(ContourElement, builtinPen.relief), 0}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(ContourElement, builtinPen.valueShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_CONTOUR_STATE, Blt_Offset(ContourElement, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_CONTOUR_NORMAL_STIPPLE, Blt_Offset(ContourElement, builtinPen.stipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_CONTOUR_STYLES, Blt_Offset(ContourElement, stylePalette), 0, &bltContourStylesOption}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(ContourElement, builtinPen.valueStyle.anchor), 0}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(ContourElement, builtinPen.valueStyle.color), 0}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(ContourElement, builtinPen.valueStyle.font), 0}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(ContourElement, builtinPen.valueFormat), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", (char *)NULL, Blt_Offset(ContourElement, builtinPen.valueStyle.angle), 0}, {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, Blt_Offset(ContourElement, w), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-x", "xdata", "Xdata", (char *)NULL, Blt_Offset(ContourElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-y", "ydata", "Ydata", (char *)NULL, Blt_Offset(ContourElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-z", "zdata", "Zdata", (char *)NULL, Blt_Offset(ContourElement, z), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xdata", "xdata", "Xdata", (char *)NULL, Blt_Offset(ContourElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ydata", "ydata", "Ydata", (char *)NULL, Blt_Offset(ContourElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-zdata", "zdata", "Zdata", (char *)NULL, Blt_Offset(ContourElement, z), 0, &bltValuesOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* Forward declarations */ static PenConfigureProc ConfigureContourPenProc; static PenDestroyProc DestroyContourPenProc; static ElementClosestProc ClosestBarProc; static ElementConfigProc ConfigureBarProc; static ElementDestroyProc DestroyBarProc; static ElementDrawProc DrawActiveBarProc; static ElementDrawProc DrawNormalBarProc; static ElementDrawSymbolProc DrawSymbolProc; static ElementExtentsProc GetContourExtentsProc; static ElementToPostScriptProc ActiveBarToPostScriptProc; static ElementToPostScriptProc NormalBarToPostScriptProc; static ElementSymbolToPostScriptProc SymbolToPostScriptProc; static ElementMapProc MapBarProc; INLINE static int Round(double x) { return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); } /* *--------------------------------------------------------------------------- * Custom option parse and print procedures *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * NameOfBarMode -- * * Converts the integer representing the mode style into a string. * *--------------------------------------------------------------------------- */ static char * NameOfBarMode(BarMode mode) { switch (mode) { case MODE_INFRONT: return "infront"; case MODE_OVERLAP: return "overlap"; case MODE_STACKED: return "stacked"; case MODE_ALIGNED: return "aligned"; default: return "unknown mode value"; } } /* *--------------------------------------------------------------------------- * * ObjToMode -- * * Converts the mode string into its numeric representation. * * Valid mode strings are: * * "infront" Draw a full bar at each point in the element. * * "stacked" Stack bar segments vertically. Each stack is defined * by each ordinate at a particular abscissa. The height * of each segment is represented by the sum the previous * ordinates. * * "aligned" Align bar segments as smaller slices one next to * the other. Like "stacks", aligned segments are * defined by each ordinate at a particular abscissa. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToBarMode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Mode style string */ char *widgRec, /* Cubicle structure record */ int offset, /* Offset to field in structure */ int flags) { BarMode *modePtr = (BarMode *)(widgRec + offset); int length; char c; char *string; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "normal", length) == 0)) { *modePtr = MODE_INFRONT; } else if ((c == 'i') && (strncmp(string, "infront", length) == 0)) { *modePtr = MODE_INFRONT; } else if ((c == 's') && (strncmp(string, "stacked", length) == 0)) { *modePtr = MODE_STACKED; } else if ((c == 'a') && (strncmp(string, "aligned", length) == 0)) { *modePtr = MODE_ALIGNED; } else if ((c == 'o') && (strncmp(string, "overlap", length) == 0)) { *modePtr = MODE_OVERLAP; } else { Tcl_AppendResult(interp, "bad mode argument \"", string, "\": should be \"infront\", \"stacked\", \"overlap\", or \"aligned\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BarModeToObj -- * * Returns the mode style string based upon the mode flags. * * Results: * The mode style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * BarModeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { BarMode mode = *(BarMode *)(widgRec + offset); return Tcl_NewStringObj(NameOfBarMode(mode), -1); } /* * Zero out the style's number of bars and errorbars. */ static void ResetStylePalette(Blt_Chain stylePalette) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); stylePtr->xeb.length = stylePtr->yeb.length = 0; stylePtr->nBars = 0; } } static int ConfigureContourPen(Graph *graphPtr, ContourPen *penPtr) { XGCValues gcValues; unsigned long gcMask; GC newGC; long defColor; gcMask = GCForeground; if (penPtr->fgColor != NULL) { defColor = penPtr->fgColor->pixel; gcValues.foreground = penPtr->fgColor->pixel; } else if (penPtr->bg != NULL) { defColor = Blt_BackgroundBorderColor(penPtr->bg)->pixel; gcValues.foreground = defColor; } else { defColor = BlackPixel(graphPtr->display, Tk_ScreenNumber(graphPtr->tkwin)); } if (penPtr->stipple != None) { gcValues.stipple = penPtr->stipple; gcValues.fill_style = FillStippled; gcMask |= (GCStipple | GCFillStyle); } newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (penPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, penPtr->gc); } penPtr->gc = newGC; gcMask = GCForeground | GCLineWidth; if (penPtr->errorBarColor == COLOR_DEFAULT) { gcValues.foreground = defColor; } else { gcValues.foreground = penPtr->errorBarColor->pixel; } gcValues.line_width = LineWidth(penPtr->errorBarLineWidth); newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (penPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->errorBarGC); } penPtr->errorBarGC = newGC; return TCL_OK; } static void DestroyContourPen(Graph *graphPtr, ContourPen *penPtr) { Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle); if (penPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, penPtr->gc); } if (penPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->errorBarGC); } } static int ConfigureContourPenProc(Graph *graphPtr, Pen *basePtr) { return ConfigureContourPen(graphPtr, (ContourPen *)basePtr); } static void DestroyContourPenProc(Graph *graphPtr, Pen *basePtr) { DestroyContourPen(graphPtr, (ContourPen *)basePtr); } static void InitContourPen(ContourPen *penPtr) { /* Generic fields common to all pen types. */ penPtr->configProc = ConfigureContourPenProc; penPtr->destroyProc = DestroyContourPenProc; penPtr->flags = NORMAL_PEN; penPtr->configSpecs = contourPenConfigSpecs; /* Initialize fields specific to contour pens. */ Blt_Ts_InitStyle(penPtr->valueStyle); penPtr->relief = TK_RELIEF_RAISED; penPtr->valueShow = SHOW_NONE; penPtr->borderWidth = 2; penPtr->errorBarShow = SHOW_BOTH; } Pen * Blt_ContourPen(char *penName) { ContourPen *penPtr; penPtr = Blt_AssertCalloc(1, sizeof(ContourPen)); InitContourPen(penPtr); penPtr->name = Blt_AssertStrdup(penName); if (strcmp(penName, "activeBar") == 0) { penPtr->flags = ACTIVE_PEN; } return (Pen *)penPtr; } /* *--------------------------------------------------------------------------- * * CheckStacks -- * * Check that the data limits are not superseded by the heights * of stacked bar segments. The heights are calculated by * Blt_ComputeStacks. * * Results: * If the y-axis limits need to be adjusted for stacked segments, * *minPtr* or *maxPtr* are updated. * * Side effects: * Autoscaling of the y-axis is affected. * *--------------------------------------------------------------------------- */ static void CheckStacks(Graph *graphPtr, Axis2d *pairPtr, double *minPtr, double *maxPtr) { BarGroup *stackPtr; int i; if ((graphPtr->mode != MODE_STACKED) || (graphPtr->nStacks == 0)) { return; } infoPtr = graphPtr->freqArr; for (i = 0; i < graphPtr->nStacks; i++) { if ((infoPtr->axes.x == pairPtr->x) && (infoPtr->axes.y == pairPtr->y)) { /* * Check if any of the y-values (because of stacking) are * greater than the current limits of the graph. */ if (infoPtr->sum < 0.0) { if (*minPtr > infoPtr->sum) { *minPtr = infoPtr->sum; } } else { if (*maxPtr < infoPtr->sum) { *maxPtr = infoPtr->sum; } } } infoPtr++; } } /* *--------------------------------------------------------------------------- * * ConfigureBarProc -- * * Sets up the appropriate configuration parameters in the GC. * It is assumed the parameters have been previously set by * a call to Blt_ConfigureWidget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information such as bar foreground/background * color and stipple etc. get set in a new GC. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureBarProc(Graph *graphPtr, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; Blt_ChainLink link; ContourStyle *stylePtr; if (ConfigureContourPen(graphPtr, elemPtr->builtinPenPtr)!= TCL_OK) { return TCL_ERROR; } /* * Point to the static normal pen if no external pens have * been selected. */ link = Blt_Chain_FirstLink(elemPtr->stylePalette); if (link == NULL) { link = Blt_Chain_AllocLink(sizeof(ContourStyle)); Blt_Chain_LinkAfter(elemPtr->stylePalette, link, NULL); } stylePtr = Blt_Chain_GetValue(link); stylePtr->penPtr = NORMALPEN(elemPtr); if (Blt_ConfigModified(elemPtr->configSpecs, "-barwidth", "-*data", "-map*", "-label", "-hide", "-x", "-y", (char *)NULL)) { elemPtr->flags |= MAP_ITEM; } return TCL_OK; } static void GetContourExtentsProc(Element *basePtr, Region2d *extsPtr) { ContourElement *elemPtr = (ContourElement *)basePtr; Mesh *meshPtr; extsPtr->top = extsPtr->left = DBL_MAX; extsPtr->bottom = extsPtr->right = -DBL_MAX; meshPtr = elemPtr->meshPtr; if ((meshPtr == NULL) || (elemPtr->values == NULL)) { return; /* No mesh or values configured. */ } if (meshPtr->nPoints < 3) { return; } extsPtr->left = (elemPtr->axes.x->logScale) ? meshPtr->xLogMin : meshPtr->xMin; extsPtr->top = (elemPtr->axes.y->logScale) ? meshPtr->yLogMin : meshPtr->yMin; extsPtr->right = meshPtr->xMax; extsPtr->bottom = meshPtr->yMax; } /* *--------------------------------------------------------------------------- * * ClosestBar -- * * Find the bar segment closest to the window coordinates point * specified. * * Note: This does not return the height of the stacked segment * (in graph coordinates) properly. * * Results: * Returns 1 if the point is width any bar segment, otherwise 0. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void ClosestBarProc( Graph *graphPtr, /* Graph widget record */ Element *basePtr, /* Bar element */ ClosestSearch *searchPtr) /* Info of closest point in element */ { ContourElement *elemPtr = (ContourElement *)basePtr; XRectangle *bp; double minDist; int imin; int i; minDist = searchPtr->dist; imin = 0; for (bp = elemPtr->bars, i = 0; i < elemPtr->nBars; i++, bp++) { Point2d *pp, *pend; Point2d outline[5]; double left, right, top, bottom; if (PointInRectangle(bp, searchPtr->x, searchPtr->y)) { imin = elemPtr->barToData[i]; minDist = 0.0; break; } left = bp->x, top = bp->y; right = (double)(bp->x + bp->width); bottom = (double)(bp->y + bp->height); outline[4].x = outline[3].x = outline[0].x = left; outline[4].y = outline[1].y = outline[0].y = top; outline[2].x = outline[1].x = right; outline[3].y = outline[2].y = bottom; for (pp = outline, pend = outline + 4; pp < pend; pp++) { Point2d t; double dist; t = Blt_GetProjection(searchPtr->x, searchPtr->y, pp, pp + 1); if (t.x > right) { t.x = right; } else if (t.x < left) { t.x = left; } if (t.y > bottom) { t.y = bottom; } else if (t.y < top) { t.y = top; } dist = hypot((t.x - searchPtr->x), (t.y - searchPtr->y)); if (dist < minDist) { minDist = dist; imin = elemPtr->barToData[i]; } } } if (minDist < searchPtr->dist) { searchPtr->elemPtr = (Element *)elemPtr; searchPtr->dist = minDist; searchPtr->index = imin; searchPtr->point.x = (double)elemPtr->x.values[imin]; searchPtr->point.y = (double)elemPtr->y.values[imin]; } } /* *--------------------------------------------------------------------------- * * MergePens -- * * Reorders the both arrays of points and errorbars to merge pens. * * Results: * None. * * Side effects: * The old arrays are freed and new ones allocated containing * the reordered points and errorbars. * *--------------------------------------------------------------------------- */ static void MergePens(ContourElement *elemPtr, ContourStyle **dataToStyle) { if (Blt_Chain_GetLength(elemPtr->stylePalette) < 2) { Blt_ChainLink link; ContourStyle *stylePtr; link = Blt_Chain_FirstLink(elemPtr->stylePalette); stylePtr = Blt_Chain_GetValue(link); stylePtr->nBars = elemPtr->nBars; stylePtr->bars = elemPtr->bars; stylePtr->symbolSize = elemPtr->bars->width / 2; stylePtr->xeb.length = elemPtr->xeb.length; stylePtr->xeb.segments = elemPtr->xeb.segments; stylePtr->yeb.length = elemPtr->yeb.length; stylePtr->yeb.segments = elemPtr->yeb.segments; return; } /* We have more than one style. Group bar segments of like pen * styles together. */ if (elemPtr->nBars > 0) { Blt_ChainLink link; XRectangle *bars, *bp; int *ip, *barToData; bars = Blt_AssertMalloc(elemPtr->nBars * sizeof(XRectangle)); barToData = Blt_AssertMalloc(elemPtr->nBars * sizeof(int)); bp = bars, ip = barToData; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->symbolSize = bp->width / 2; stylePtr->bars = bp; for (i = 0; i < elemPtr->nBars; i++) { int iData; iData = elemPtr->barToData[i]; if (dataToStyle[iData] == stylePtr) { *bp++ = elemPtr->bars[i]; *ip++ = iData; } } stylePtr->nBars = bp - stylePtr->bars; } Blt_Free(elemPtr->bars); Blt_Free(elemPtr->barToData); elemPtr->bars = bars; elemPtr->barToData = barToData; } if (elemPtr->xeb.length > 0) { Blt_ChainLink link; Segment2d *bars, *sp; int *map, *ip; bars = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(int)); sp = bars, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->xeb.segments = sp; for (i = 0; i < elemPtr->xeb.length; i++) { int iData; iData = elemPtr->xeb.map[i]; if (dataToStyle[iData] == stylePtr) { *sp++ = elemPtr->xeb.segments[i]; *ip++ = iData; } } stylePtr->xeb.length = sp - stylePtr->xeb.segments; } Blt_Free(elemPtr->xeb.segments); elemPtr->xeb.segments = bars; Blt_Free(elemPtr->xeb.map); elemPtr->xeb.map = map; } if (elemPtr->yeb.length > 0) { Blt_ChainLink link; Segment2d *bars, *sp; int *map, *ip; bars = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(int)); sp = bars, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->yeb.segments = sp; for (i = 0; i < elemPtr->yeb.length; i++) { int iData; iData = elemPtr->yeb.map[i]; if (dataToStyle[iData] == stylePtr) { *sp++ = elemPtr->yeb.segments[i]; *ip++ = iData; } } stylePtr->yeb.length = sp - stylePtr->yeb.segments; } Blt_Free(elemPtr->yeb.segments); elemPtr->yeb.segments = bars; Blt_Free(elemPtr->yeb.map); elemPtr->yeb.map = map; } } /* *--------------------------------------------------------------------------- * * MapActiveBars -- * * Creates an array of points of the active graph coordinates. * * Results: * None. * * Side effects: * Memory is freed and allocated for the active point array. * *--------------------------------------------------------------------------- */ static void MapActiveBars(ContourElement *elemPtr) { if (elemPtr->activeRects != NULL) { Blt_Free(elemPtr->activeRects); elemPtr->activeRects = NULL; } if (elemPtr->activeToData != NULL) { Blt_Free(elemPtr->activeToData); elemPtr->activeToData = NULL; } elemPtr->nActive = 0; if (elemPtr->nActiveIndices > 0) { XRectangle *activeRects; int *activeToData; int i; int count; activeRects = Blt_AssertMalloc(sizeof(XRectangle) * elemPtr->nActiveIndices); activeToData = Blt_AssertMalloc(sizeof(int) * elemPtr->nActiveIndices); count = 0; for (i = 0; i < elemPtr->nBars; i++) { int *ip, *iend; for (ip = elemPtr->activeIndices, iend = ip + elemPtr->nActiveIndices; ip < iend; ip++) { if (elemPtr->barToData[i] == *ip) { activeRects[count] = elemPtr->bars[i]; activeToData[count] = i; count++; } } } elemPtr->nActive = count; elemPtr->activeRects = activeRects; elemPtr->activeToData = activeToData; } elemPtr->flags &= ~ACTIVE_PENDING; } static void ResetBar(ContourElement *elemPtr) { /* Release any storage associated with the display of the bar */ ResetStylePalette(elemPtr->stylePalette); if (elemPtr->activeRects != NULL) { Blt_Free(elemPtr->activeRects); } if (elemPtr->activeToData != NULL) { Blt_Free(elemPtr->activeToData); } if (elemPtr->xeb.segments != NULL) { Blt_Free(elemPtr->xeb.segments); } if (elemPtr->xeb.map != NULL) { Blt_Free(elemPtr->xeb.map); } if (elemPtr->yeb.segments != NULL) { Blt_Free(elemPtr->yeb.segments); } if (elemPtr->yeb.map != NULL) { Blt_Free(elemPtr->yeb.map); } if (elemPtr->bars != NULL) { Blt_Free(elemPtr->bars); } if (elemPtr->barToData != NULL) { Blt_Free(elemPtr->barToData); } elemPtr->activeToData = elemPtr->xeb.map = elemPtr->yeb.map = elemPtr->barToData = NULL; elemPtr->activeRects = elemPtr->bars = NULL; elemPtr->xeb.segments = elemPtr->yeb.segments = NULL; elemPtr->nActive = elemPtr->xeb.length = elemPtr->yeb.length = elemPtr->nBars = 0; } /* *--------------------------------------------------------------------------- * * Blt_MapErrorBars -- * * Creates two arrays of points and pen indices, filled with * the screen coordinates of the visible * * Results: * None. * * Side effects: * Memory is freed and allocated for the index array. * *--------------------------------------------------------------------------- */ static void MapErrorBars(Graph *graphPtr, ContourElement *elemPtr, ContourStyle **dataToStyle) { int n, nPoints; Region2d exts; Blt_GraphExtents(graphPtr, &exts); nPoints = NUMBEROFPOINTS(elemPtr); if (elemPtr->xError.nValues > 0) { n = MIN(elemPtr->xError.nValues, nPoints); } else { n = MIN3(elemPtr->xHigh.nValues, elemPtr->xLow.nValues, nPoints); } if (n > 0) { Segment2d *bars; Segment2d *segPtr; int *map; int *indexPtr; int i; segPtr = bars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = map = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; ContourStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = dataToStyle[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->xError.nValues > 0) { high = x + elemPtr->xError.values[i]; low = x - elemPtr->xError.values[i]; } else { high = elemPtr->xHigh.values[i]; low = elemPtr->xLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, high, y, &elemPtr->axes); q = Blt_Map2D(graphPtr, low, y, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Left cap */ segPtr->p.x = segPtr->q.x = p.x; segPtr->p.y = p.y - stylePtr->errorBarCapWidth; segPtr->q.y = p.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Right cap */ segPtr->p.x = segPtr->q.x = q.x; segPtr->p.y = q.y - stylePtr->errorBarCapWidth; segPtr->q.y = q.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->xeb.segments = bars; elemPtr->xeb.length = segPtr - bars; elemPtr->xeb.map = map; } if (elemPtr->yError.nValues > 0) { n = MIN(elemPtr->yError.nValues, nPoints); } else { n = MIN3(elemPtr->yHigh.nValues, elemPtr->yLow.nValues, nPoints); } if (n > 0) { Segment2d *bars; Segment2d *segPtr; int *map; int *indexPtr; int i; segPtr = bars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = map = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; ContourStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = dataToStyle[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->yError.nValues > 0) { high = y + elemPtr->yError.values[i]; low = y - elemPtr->yError.values[i]; } else { high = elemPtr->yHigh.values[i]; low = elemPtr->yLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, x, high, &elemPtr->axes); q = Blt_Map2D(graphPtr, x, low, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Top cap. */ segPtr->p.y = segPtr->q.y = p.y; segPtr->p.x = p.x - stylePtr->errorBarCapWidth; segPtr->q.x = p.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Bottom cap. */ segPtr->p.y = segPtr->q.y = q.y; segPtr->p.x = q.x - stylePtr->errorBarCapWidth; segPtr->q.x = q.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->yeb.segments = bars; elemPtr->yeb.length = segPtr - bars; elemPtr->yeb.map = map; } } /* *--------------------------------------------------------------------------- * * MapContourElementProc -- * * Calculates the actual window coordinates of the bar element. * The window coordinates are saved in the bar element structure. * * Results: * None. * * Notes: * A bar can have multiple segments (more than one x,y pairs). * In this case, the bar can be represented as either a set of * non-contiguous bars or a single multi-segmented (stacked) bar. * * The x-axis layout for a contour plot may be presented in one of * two ways. If abscissas are used, the bars are placed at those * coordinates. Otherwise, the range will represent the number * of values. * *--------------------------------------------------------------------------- */ static void MapContourElementProc(Graph *graphPtr, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; ContourStyle **dataToStyle; double *x, *y; double barWidth, barOffset; double baseline; int *barToData; /* Maps bars to data point indices */ int invertBar; int nPoints, count; XRectangle *rp, *bars; int i; int size; ResetBar(elemPtr); nPoints = NUMBEROFPOINTS(elemPtr); if (nPoints < 1) { return; /* No data points */ } barWidth = graphPtr->barWidth; if (elemPtr->barWidth > 0.0) { barWidth = elemPtr->barWidth; } baseline = (elemPtr->axes.y->logScale) ? 1.0 : graphPtr->baseline; barOffset = barWidth * 0.5; /* * Create an array of bars representing the screen coordinates * of all the segments in the bar. */ bars = Blt_AssertCalloc(nPoints, sizeof(XRectangle)); barToData = Blt_AssertCalloc(nPoints, sizeof(int)); x = elemPtr->x.values, y = elemPtr->y.values; count = 0; for (rp = bars, i = 0; i < nPoints; i++) { Point2d c1, c2; /* Two opposite corners of the rectangle * in graph coordinates. */ double dx, dy; int height; if (((x[i] - barWidth) > elemPtr->axes.x->axisRange.max) || ((x[i] + barWidth) < elemPtr->axes.x->axisRange.min)) { continue; /* Abscissa is out of range of the x-axis */ } c1.x = x[i] - barOffset; c1.y = y[i]; c2.x = c1.x + barWidth; c2.y = baseline; /* * If the mode is "aligned" or "stacked" we need to adjust the * x or y coordinates of the two corners. */ if ((graphPtr->nStacks > 0) && (graphPtr->mode != MODE_INFRONT)) { Blt_HashEntry *hPtr; FreqKey key; key.value = x[i]; key.axes = elemPtr->axes; hPtr = Blt_FindHashEntry(&graphPtr->freqTable, (char *)&key); if (hPtr != NULL) { FreqInfo *infoPtr; double slice, width; infoPtr = Blt_GetHashValue(hPtr); switch (graphPtr->mode) { case MODE_STACKED: c2.y = infoPtr->lastY; c1.y += c2.y; infoPtr->lastY = c1.y; break; case MODE_ALIGNED: infoPtr->count++; slice = barWidth / (double)infoPtr->freq; c1.x += slice * (infoPtr->freq - infoPtr->count); c2.x = c1.x + slice; break; case MODE_OVERLAP: infoPtr->count++; slice = barWidth / (double)(infoPtr->freq * 2); width = slice * (infoPtr->freq + 1); c1.x += slice * (infoPtr->freq - infoPtr->count); c2.x = c1.x + width; break; case MODE_INFRONT: break; } } } invertBar = FALSE; if (c1.y < c2.y) { double temp; /* Handle negative bar values by swapping ordinates */ temp = c1.y, c1.y = c2.y, c2.y = temp; invertBar = TRUE; } /* * Get the two corners of the bar segment and compute the rectangle */ c1 = Blt_Map2D(graphPtr, c1.x, c1.y, &elemPtr->axes); c2 = Blt_Map2D(graphPtr, c2.x, c2.y, &elemPtr->axes); /* Bound the bars horizontally by the width of the graph window */ /* Bound the bars vertically by the position of the axis. */ if (graphPtr->stackAxes) { int right, left, top, bottom; if (graphPtr->inverted) { left = elemPtr->axes.y->screenMin; right = elemPtr->axes.y->screenMin + elemPtr->axes.y->screenRange; top = graphPtr->top; bottom = graphPtr->bottom; } else { top = elemPtr->axes.y->screenMin; bottom = elemPtr->axes.y->screenMin + elemPtr->axes.y->screenRange; left = graphPtr->left; right = graphPtr->right; } if (c1.y < (double)top) { c1.y = (double)top; } else if (c1.y > (double)bottom) { c1.y = (double)bottom; } if (c2.y < (double)top) { c2.y = (double)top; } else if (c2.y > (double)bottom) { c2.y = (double)bottom; } if (c1.x < (double)left) { c1.x = (double)left; } else if (c1.x > (double)right) { c1.x = (double)right; } if (c2.x < (double)left) { c2.x = (double)left; } else if (c2.x > (double)right) { c2.x = (double)right; } } else { int right, left, top, bottom; if (graphPtr->inverted) { top = graphPtr->left; bottom = graphPtr->right; left = graphPtr->top; right = graphPtr->bottom; } else { top = graphPtr->top; bottom = graphPtr->bottom; left = graphPtr->left; right = graphPtr->right; } if (c1.y < 0.0) { c1.y = 0.0; } else if (c1.y > (double)graphPtr->height) { c1.y = (double)graphPtr->height; } if (c2.y < 0.0) { c2.y = 0.0; } else if (c2.y > (double)graphPtr->height) { c2.y = (double)graphPtr->height; } } dx = FABS(c1.x - c2.x); dy = FABS(c1.y - c2.y); if ((dx == 0) || (dy == 0)) { continue; } height = (int)dy; if (invertBar) { rp->y = (short int)MIN(c1.y, c2.y); } else { rp->y = (short int)(MAX(c1.y, c2.y)) - height; } rp->x = (short int)MIN(c1.x, c2.x); rp->width = (short int)dx + 1; if (rp->width < 1) { rp->width = 1; } rp->height = height + 1; if (rp->height < 1) { rp->height = 1; } barToData[count] = i; /* Save the data index corresponding to the * rectangle */ count++; rp++; } elemPtr->nBars = count; elemPtr->bars = bars; elemPtr->barToData = barToData; if (elemPtr->nActiveIndices > 0) { MapActiveBars(elemPtr); } size = 20; if (count > 0) { size = bars->width; } { Blt_ChainLink link; /* Set the symbol size of all the pen styles. */ for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); stylePtr->symbolSize = size; stylePtr->errorBarCapWidth = (stylePtr->penPtr->errorBarCapWidth > 0) ? stylePtr->penPtr->errorBarCapWidth : (size * 66666) / 100000; stylePtr->errorBarCapWidth /= 2; } } dataToStyle = (ContourStyle **)Blt_StyleMap((Element *)elemPtr); if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) || ((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) || (elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) { MapErrorBars(graphPtr, elemPtr, dataToStyle); } MergePens(elemPtr, dataToStyle); Blt_Free(dataToStyle); } /* *--------------------------------------------------------------------------- * * DrawSymbolProc -- * * Draw a symbol centered at the given x,y window coordinate * based upon the element symbol type and size. * * Results: * None. * * Problems: * Most notable is the round-off errors generated when * calculating the centered position of the symbol. *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void DrawSymbolProc( Graph *graphPtr, Drawable drawable, /* Pixmap or window to draw into */ Element *basePtr, int x, int y, int size) { ContourElement *elemPtr = (ContourElement *)basePtr; ContourPen *penPtr; int radius; penPtr = NORMALPEN(elemPtr); if ((penPtr->bg == NULL) && (penPtr->fgColor == NULL)) { return; } radius = (size / 2); size--; x -= radius; y -= radius; XSetTSOrigin(graphPtr->display, penPtr->gc, x, y); XFillRectangle(graphPtr->display, drawable, penPtr->gc, x, y, size, size); XSetTSOrigin(graphPtr->display, penPtr->gc, 0, 0); } /* *--------------------------------------------------------------------------- * * DrawContourSegments -- * * Draws each of the rectangular segments for the element. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawContourSegments( Graph *graphPtr, Drawable drawable, /* Pixmap or window to draw into */ ContourPen *penPtr, XRectangle *bars, int nBars) { if ((penPtr->bg == NULL) && (penPtr->fgColor == NULL)) { return; } if (penPtr->bg != NULL) { XRectangle *rp, *rend; for (rp = bars, rend = rp + nBars; rp < rend; rp++) { Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, penPtr->bg, rp->x, rp->y, rp->width, rp->height, penPtr->borderWidth, penPtr->relief); } } if (penPtr->fgColor != NULL) { XFillRectangles(graphPtr->display, drawable, penPtr->gc, bars, nBars); } } /* *--------------------------------------------------------------------------- * * DrawContourValues -- * * Draws the numeric value of the bar. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawContourValues( Graph *graphPtr, Drawable drawable, ContourElement *elemPtr, ContourPen *penPtr, XRectangle *bars, int nBars, int *barToData) { XRectangle *rp, *rend; int count; char *fmt; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } count = 0; for (rp = bars, rend = rp + nBars; rp < rend; rp++) { Point2d anchorPos; double x, y; char string[TCL_DOUBLE_SPACE * 2 + 2]; x = elemPtr->x.values[barToData[count]]; y = elemPtr->y.values[barToData[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } if (graphPtr->inverted) { anchorPos.y = rp->y + rp->height * 0.5; anchorPos.x = rp->x + rp->width; if (y < graphPtr->baseline) { anchorPos.x -= rp->width; } } else { anchorPos.x = rp->x + rp->width * 0.5; anchorPos.y = rp->y; if (y < graphPtr->baseline) { anchorPos.y += rp->height; } } Blt_DrawText(graphPtr->tkwin, drawable, string, &penPtr->valueStyle, (int)anchorPos.x, (int)anchorPos.y); } } /* *--------------------------------------------------------------------------- * * DrawNormalContourProc -- * * Draws the rectangle representing the bar element. If the * relief option is set to "raised" or "sunken" and the bar * borderwidth is set (borderwidth > 0), a 3D border is drawn * around the bar. * * Don't draw bars that aren't visible (i.e. within the limits * of the axis). * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawNormalContourProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; int count; Blt_ChainLink link; count = 0; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; ContourPen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = stylePtr->penPtr; if (stylePtr->nBars > 0) { DrawBarSegments(graphPtr, drawable, penPtr, stylePtr->bars, stylePtr->nBars); } if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->yeb.segments, stylePtr->yeb.length); } if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, stylePtr->bars, stylePtr->nBars, elemPtr->barToData + count); } count += stylePtr->nBars; } } /* *--------------------------------------------------------------------------- * * DrawActiveContourProc -- * * Draws contours representing the active segments of the * bar element. If the -relief option is set (other than "flat") * and the borderwidth is greater than 0, a 3D border is drawn * around the each bar segment. * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawActiveContourProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; if (elemPtr->activePenPtr != NULL) { ContourPen *penPtr = elemPtr->activePenPtr; if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveBars(elemPtr); } DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->activeRects, elemPtr->nActive); if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->activeRects, elemPtr->nActive, elemPtr->activeToData); } } else if (elemPtr->nActiveIndices < 0) { DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->bars, elemPtr->nBars); if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->bars, elemPtr->nBars, elemPtr->barToData); } } } } /* *--------------------------------------------------------------------------- * * SymbolToPostScript -- * * Draw a symbol centered at the given x,y window coordinate * based upon the element symbol type and size. * * Results: * None. * * Problems: * Most notable is the round-off errors generated when * calculating the centered position of the symbol. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void SymbolToPostScriptProc( Graph *graphPtr, Blt_Ps ps, Element *basePtr, double x, double y, int size) { ContourElement *elemPtr = (ContourElement *)basePtr; ContourPen *penPtr; penPtr = NORMALPEN(elemPtr); if ((penPtr->bg == NULL) && (penPtr->fgColor == NULL)) { return; } /* * Build a PostScript procedure to draw the fill and outline of * the symbol after the path of the symbol shape has been formed */ Blt_Ps_VarAppend(ps, "\n", "/DrawSymbolProc {\n", " gsave\n ", (char *)NULL); if (penPtr->stipple != None) { if (penPtr->bg != NULL) { Blt_Ps_XSetBackground(ps, Blt_BackgroundBorderColor(penPtr->bg)); Blt_Ps_Append(ps, " gsave fill grestore\n "); } if (penPtr->fgColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->fgColor); } else { Blt_Ps_XSetForeground(ps, Blt_BackgroundBorderColor(penPtr->bg)); } Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple); } else if (penPtr->fgColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->fgColor); Blt_Ps_Append(ps, " fill\n"); } Blt_Ps_Append(ps, " grestore\n"); Blt_Ps_Append(ps, "} def\n\n"); Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size); } static void SegmentsToPostScript( Graph *graphPtr, Blt_Ps ps, ContourPen *penPtr, XRectangle *bars, int nBars) { XRectangle *rp, *rend; if ((penPtr->bg == NULL) && (penPtr->fgColor == NULL)) { return; } for (rp = bars, rend = rp + nBars; rp < rend; rp++) { if ((rp->width < 1) || (rp->height < 1)) { continue; } if (penPtr->stipple != None) { Blt_Ps_Rectangle(ps, rp->x, rp->y, rp->width - 1, rp->height - 1); if (penPtr->bg != NULL) { Blt_Ps_XSetBackground(ps,Blt_BackgroundBorderColor(penPtr->bg)); Blt_Ps_Append(ps, "gsave fill grestore\n"); } if (penPtr->fgColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->fgColor); } else { Blt_Ps_XSetForeground(ps,Blt_BackgroundBorderColor(penPtr->bg)); } Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple); } else if (penPtr->fgColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->fgColor); Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y, (int)rp->width - 1, (int)rp->height - 1); } if ((penPtr->bg != NULL) && (penPtr->borderWidth > 0) && (penPtr->relief != TK_RELIEF_FLAT)) { Blt_Ps_Draw3DRectangle(ps, Blt_BackgroundBorder(penPtr->bg), (double)rp->x, (double)rp->y, (int)rp->width, (int)rp->height, penPtr->borderWidth, penPtr->relief); } } } static void BarValuesToPostScript( Graph *graphPtr, Blt_Ps ps, ContourElement *elemPtr, ContourPen *penPtr, XRectangle *bars, int nBars, int *barToData) { XRectangle *rp, *rend; int count; char *fmt; char string[TCL_DOUBLE_SPACE * 2 + 2]; double x, y; Point2d anchorPos; count = 0; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } for (rp = bars, rend = rp + nBars; rp < rend; rp++) { x = elemPtr->x.values[barToData[count]]; y = elemPtr->y.values[barToData[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } if (graphPtr->inverted) { anchorPos.y = rp->y + rp->height * 0.5; anchorPos.x = rp->x + rp->width; if (y < graphPtr->baseline) { anchorPos.x -= rp->width; } } else { anchorPos.x = rp->x + rp->width * 0.5; anchorPos.y = rp->y; if (y < graphPtr->baseline) { anchorPos.y += rp->height; } } Blt_Ps_DrawText(ps, string, &penPtr->valueStyle, anchorPos.x, anchorPos.y); } } /* *--------------------------------------------------------------------------- * * ActiveBarToPostScript -- * * Similar to the NormalBarToPostScript procedure, generates * PostScript commands to display the bars representing the * active bar segments of the element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void ActiveBarToPostScriptProc( Graph *graphPtr, Blt_Ps ps, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; if (elemPtr->activePenPtr != NULL) { ContourPen *penPtr = elemPtr->activePenPtr; if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveBars(elemPtr); } SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->activeRects, elemPtr->nActive); if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, elemPtr->activeRects, elemPtr->nActive, elemPtr->activeToData); } } else if (elemPtr->nActiveIndices < 0) { SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->bars, elemPtr->nBars); if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, elemPtr->bars, elemPtr->nBars, elemPtr->barToData); } } } } /* *--------------------------------------------------------------------------- * * NormalBarToPostScript -- * * Generates PostScript commands to form the bars * representing the segments of the bar element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void NormalBarToPostScriptProc( Graph *graphPtr, Blt_Ps ps, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; Blt_ChainLink link; int count; count = 0; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { ContourStyle *stylePtr; ContourPen *penPtr; XColor *colorPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = stylePtr->penPtr; if (stylePtr->nBars > 0) { SegmentsToPostScript(graphPtr, ps, penPtr, stylePtr->bars, stylePtr->nBars); } colorPtr = penPtr->errorBarColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = penPtr->fgColor; } if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments, stylePtr->yeb.length); } if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, stylePtr->bars, stylePtr->nBars, elemPtr->barToData + count); } count += stylePtr->nBars; } } /* *--------------------------------------------------------------------------- * * DestroyBar -- * * Release memory and resources allocated for the bar element. * * Results: * None. * * Side effects: * Everything associated with the bar element is freed up. * *--------------------------------------------------------------------------- */ static void DestroyBarProc(Graph *graphPtr, Element *basePtr) { ContourElement *elemPtr = (ContourElement *)basePtr; DestroyContourPen(graphPtr, elemPtr->builtinPenPtr); if (elemPtr->activePenPtr != NULL) { Blt_FreePen((Pen *)elemPtr->activePenPtr); } ResetBar(elemPtr); if (elemPtr->stylePalette != NULL) { Blt_FreeStylePalette(elemPtr->stylePalette); Blt_Chain_Destroy(elemPtr->stylePalette); } if (elemPtr->activeIndices != NULL) { Blt_Free(elemPtr->activeIndices); } } /* *--------------------------------------------------------------------------- * * Blt_ContourElement -- * * Allocate memory and initialize methods for the new bar element. * * Results: * The pointer to the newly allocated element structure is returned. * * Side effects: * Memory is allocated for the bar element structure. * *--------------------------------------------------------------------------- */ static ElementProcs barProcs = { ClosestBarProc, ConfigureBarProc, DestroyBarProc, DrawActiveBarProc, DrawNormalBarProc, DrawSymbolProc, GetBarExtentsProc, ActiveBarToPostScriptProc, NormalBarToPostScriptProc, SymbolToPostScriptProc, MapBarProc, }; Element * Blt_ContourElement(Graph *graphPtr, char *name, ClassId classId) { ContourElement *elemPtr; elemPtr = Blt_AssertCalloc(1, sizeof(ContourElement)); elemPtr->procsPtr = &barProcs; elemPtr->configSpecs = contourElemConfigSpecs; elemPtr->legendRelief = TK_RELIEF_FLAT; Blt_GraphSetObjectClass(&elemPtr->object, classId); elemPtr->obj.name = Blt_AssertStrdup(name); elemPtr->obj.graphPtr = graphPtr; /* By default, an element's name and label are the same. */ elemPtr->label = Blt_AssertStrdup(name); elemPtr->builtinPenPtr = &elemPtr->builtinPen; InitContourPen(elemPtr->builtinPenPtr); elemPtr->stylePalette = Blt_Chain_Create(); bltContourStylesOption.clientData = (ClientData)sizeof(ContourStyle); return (Element *)elemPtr; } /* *--------------------------------------------------------------------------- * * Blt_InitFreqTable -- * * Generate a table of abscissa frequencies. Duplicate * x-coordinates (depending upon the bar drawing mode) indicate * that something special should be done with each bar segment * mapped to the same abscissa (i.e. it should be stacked, * aligned, or overlay-ed with other segments) * * Results: * None. * * Side effects: * Memory is allocated for the bar element structure. * *--------------------------------------------------------------------------- */ void Blt_InitFreqTable(Graph *graphPtr) { Blt_ChainLink link; int nStacks, nSegs; Blt_HashTable freqTable; /* * Free resources associated with a previous frequency table. This * includes the array of frequency information and the table itself */ if (graphPtr->freqArr != NULL) { Blt_Free(graphPtr->freqArr); graphPtr->freqArr = NULL; } if (graphPtr->nStacks > 0) { Blt_DeleteHashTable(&graphPtr->freqTable); graphPtr->nStacks = 0; } if (graphPtr->mode == MODE_INFRONT) { return; /* No frequency table is needed for * "infront" mode */ } Blt_InitHashTable(&graphPtr->freqTable, sizeof(FreqKey) / sizeof(int)); /* * Initialize a hash table and fill it with unique abscissas. * Keep track of the frequency of each x-coordinate and how many * abscissas have duplicate mappings. */ Blt_InitHashTable(&freqTable, sizeof(FreqKey) / sizeof(int)); nSegs = nStacks = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { ContourElement *elemPtr; double *xArr; int nPoints; int i; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & (HIDE|DELETE_PENDING) || (elemPtr->obj.classId != CID_ELEM_CONTOUR)) { continue; } nSegs++; xArr = elemPtr->x.values; nPoints = NUMBEROFPOINTS(elemPtr); for (i = 0; i < nPoints; i++) { Blt_HashEntry *hPtr; FreqKey key; int isNew; size_t count; key.value = xArr[i]; key.axes = elemPtr->axes; hPtr = Blt_CreateHashEntry(&freqTable, (char *)&key, &isNew); if (isNew) { count = 1; } else { count = (size_t)Blt_GetHashValue(hPtr); if (count == 1) { nStacks++; } count++; } Blt_SetHashValue(hPtr, (ClientData)count); } } if (nSegs == 0) { return; /* No bar elements to be displayed */ } if (nStacks > 0) { FreqInfo *fp; Blt_HashEntry *h1; Blt_HashSearch cursor; graphPtr->freqArr = Blt_AssertCalloc(nStacks, sizeof(FreqInfo)); fp = graphPtr->freqArr; for (h1 = Blt_FirstHashEntry(&freqTable, &cursor); h1 != NULL; h1 = Blt_NextHashEntry(&cursor)) { FreqKey *keyPtr; size_t count; count = (size_t)Blt_GetHashValue(h1); keyPtr = (FreqKey *)Blt_GetHashKey(&freqTable, h1); if (count > 1) { Blt_HashEntry *h2; int isNew; h2 = Blt_CreateHashEntry(&graphPtr->freqTable, (char *)keyPtr, &isNew); count = (size_t)Blt_GetHashValue(h1); fp->freq = count; fp->axes = keyPtr->axes; Blt_SetHashValue(h2, fp); fp++; } } } Blt_DeleteHashTable(&freqTable); graphPtr->nStacks = nStacks; } /* *--------------------------------------------------------------------------- * * Blt_ComputeStacks -- * * Determine the height of each stack of bar segments. A stack * is created by designating two or more points with the same * abscissa. Each ordinate defines the height of a segment in * the stack. This procedure simply looks at all the data points * summing the heights of each stacked segment. The sum is saved * in the frequency information table. This value will be used * to calculate the y-axis limits (data limits aren't sufficient). * * Results: * None. * * Side effects: * The heights of each stack is computed. CheckStacks will * use this information to adjust the y-axis limits if necessary. * *--------------------------------------------------------------------------- */ void Blt_ComputeStacks(Graph *graphPtr) { Blt_ChainLink link; if ((graphPtr->mode != MODE_STACKED) || (graphPtr->nStacks == 0)) { return; } /* Reset the sums for all duplicate values to zero. */ { FreqInfo *infoPtr; int i; infoPtr = graphPtr->freqArr; for (i = 0; i < graphPtr->nStacks; i++) { infoPtr->sum = 0.0; infoPtr++; } } /* Look at each bar point, adding the ordinates of duplicate abscissas */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { ContourElement *elemPtr; double *xArr, *yArr; int nPoints; int i; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & (HIDE|DELETE_PENDING) || (elemPtr->obj.classId != CID_ELEM_CONTOUR)) { continue; } xArr = elemPtr->x.values; yArr = elemPtr->y.values; nPoints = NUMBEROFPOINTS(elemPtr); for (i = 0; i < nPoints; i++) { Blt_HashEntry *hPtr; FreqKey key; FreqInfo *infoPtr; key.value = xArr[i]; key.axes = elemPtr->axes; hPtr = Blt_FindHashEntry(&graphPtr->freqTable, (char *)&key); if (hPtr == NULL) { continue; } infoPtr = Blt_GetHashValue(hPtr); infoPtr->sum += yArr[i]; } } } void Blt_ResetBarGroups(Graph *graphPtr) { FreqInfo *fp, *fend; for (fp = graphPtr->freqArr, fend = fp+graphPtr->nStacks; fp < fend; fp++) { fp->lastY = 0.0; fp->count = 0; } } /* *--------------------------------------------------------------------------- * * GetScreenPoints -- * * Generates a coordinate array of transformed screen coordinates from * the data points. * * Results: * The transformed screen coordinates are returned. * * Side effects: * Memory is allocated for the coordinate array. * *--------------------------------------------------------------------------- */ static void GetScreenPoints(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { double *x, *y; int i, n; int count; Point3 *points; int *map; MeshKey key; n = MIN3(elemPtr->x.nValues, elemPtr->y.nValues, elemPtr->z.nValues); x = elemPtr->x.values; y = elemPtr->y.values; z = elemPtr->z.values; points = Blt_AssertMalloc(sizeof(Point3) * n); map = Blt_AssertMalloc(sizeof(int) * n); count = 0; /* Count the valid screen coordinates */ next = 0; zmin = zmax = 0.0; /* Suppress compiler warning. */ Blt_InitHashTable(&table, sizeof(MeshKey) / sizeof(int)); p = points; p->x = x[0]; p->y = y[0]; p->z = z[0]; zmin = zmax = p->z; p++; /* * Generate array of points. Check for duplicates. This is a quick+dirty * (slow) solution. */ hPtr = Blt_CreateHashEntry(&table, (char *)&key, &isNew); for (i = 1; i < n; i++) { Blt_HashEntry *hPtr; MeshKey key; key.x = x[i]; key.y = y[i]; hPtr = Blt_CreateHashEntry(&table, (char *)&key, &isNew); if (!isNew) { continue; /* Already have coordinate pair. */ } p->x = key.x; p->y = key.y; p->z = z[i]; if (p->z < zMin) { zMin = p->z; } else if (p->z > zMax) { zMax = p->z; } p++; } Tcl_DeleteHashTable(&table); nPnts = points - p; tol = (zMax - zMin) * tol; /* * Mesh the points to get triangles */ R = Blt_Malloc(2 * nPnts * sizeof(Triplet)); if (R == NULL) { Tcl_AppendResult(interp, "can't allocate ", Itoa(nPnts), " triplets", (char *)NULL); return TCL_ERROR; } nTriangles = Triangulate(nPnts, points, R); assert(nTriangles <= 2 * nPnts); if (graphPtr->inverted) { for (i = 0; i < n; i++) { if ((FINITE(x[i])) && (FINITE(y[i]))) { points[count].x = Blt_HMap(elemPtr->axes.y, y[i]); points[count].y = Blt_VMap(elemPtr->axes.x, x[i]); map[count] = i; count++; } } } else { for (i = 0; i < n; i++) { if ((FINITE(x[i])) && (FINITE(y[i]))) { points[count].x = Blt_HMap(elemPtr->axes.x, x[i]); points[count].y = Blt_VMap(elemPtr->axes.y, y[i]); map[count] = i; count++; } } } mapPtr->screenPts = points; mapPtr->nScreenPts = count; mapPtr->map = map; } /* *--------------------------------------------------------------------------- * * IsolineOp -- * * .g isoline create -name $name -value $value -color $color -pen $pen * .g isoline configure $name -value $value -color $color -hide no * .g isoline delete $name * .g isoline names * *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * IsolineOp -- * * .g isoline create -name $name -value $value -color $color * .g isoline configure $name -value $value -color $color -hide no * .g isoline * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsolineOp( Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; char *tagName; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { tagName = Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tagName, -1)); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } /* make up an edge */ static INLINE void MakeEdgeKey(Edge *keyPtr, int a, int b) { if (a < b) { keyPtr->a = a; keyPtr->b = b; } else { keyPtr->a = b; keyPtr->b = a; } } /* interpolate 2 points and add possible result to points array */ static int Interpolate(ContourElement *contPtr, int a, int b, double isovalue) { int ab, junk; Edge *edgePtr; EdgeInfo *eiPtr; Blt_HashEntry *hPtr; double zA, zB, r, absr; Point2f *points = contPtr->meshPtr->points; EdgeKey key; /* Create the edge key. */ MakeEdgeKey(&key, a, b); hPtr = Blt_CreateHashEntry(contPtr->edgeTable, (char *)key, &isNew); if (!isNew) { int index; index = (int)Blt_GetHashValue(hPtr); #if DEBUG printf("A=%d(%g,%g,%g) B=%d(%g,%g,%g) isovalue=%g -> old %d\n", a, points[a].x, points[a].y, values[a], b, points[b].x, points[b].y, values[b], isovalue, index); #endif return index; } /* No, then do the interpolation */ zA = contPtr->values[a] - isovalue; if (fabs(zA/isovalue) < contPtr->fuzz) { zA = 0.0; } zB = contPtr->values[b] - isovalue; if (fabs(zB/isovalue) < contPtr->fuzz) { zB = 0.0; } /* Does there exist an intermediate point? */ if (sign(zA) != sign(zB)) { double t; int i; i = contPtr->nAdditional; t = zA / (zA - zB); points[i].x = points[a].x + t * (points[b].x - points[a].x); points[i].y = points[a].y + t * (points[b].y - points[a].y); values[i] = isovalue; ab = i; contPtr->nAdditional++; } else { ab = 0; } #if DEBUG printf("A=%d(%g,%g,%g) B=%d(%g,%g,%g) isovalue=%g -> new %d\n", a, points[a].x, points[a].y, values[a], b, points[b].x, points[b].y, values[b], isovalue, ab); #endif /* add the new point to the hash table */ Blt_SetHashValue(hPtr, (ClientData)ab); return ab; } /* process a Cont triangle */ void ProcessTriangle(ContourElement *contPtr, Triangle *t, float isovalue) { int ab, bc, ca; if (isovalue <= t->min) { if ((t->a != t->b) && (t->b != t->c) && (t->a != t->c)) { AddTriangle(t->a, t->b, t->c); } return; } /* Interpolate the three sides of the triangle. */ ab = Interpolate(contPtr, t->a, t->b, isovalue); bc = Interpolate(contPtr, t->b, t->c, isovalue); ca = Interpolate(contPtr, t->c, t->a, isovalue); if ((ab) && (bc) && (!ca)) { if (contPtr->values[t->b] > isovalue) { AddTriangle(ab, t->b, bc); } else { AddQuadrilateral(t->a, ab, bc, t->c); } return; } if ((ab) && (!bc) && (ca)) { if (contPtr->values[t->a] > isovalue) { AddTriangle(t->a, ab, ca); } else { AddQuadrilateral(ab, t->b, t->c, ca); } return; } if ((!ab) && (bc) && (ca)) { if (contPtr->values[t->c] > isovalue) { AddTriangle(bc, t->c, ca); } else { AddQuadrilateral(t->b, bc, ca, t->a); } return; } } static int CompareTriangles(const void *a, const void *b) { const Triangle *t1 = a; const Triangle *t2 = b; /* Sort by the minimum. */ if (t1->min < t2->min) { return -1; } else if (t1->min > t2->min) { return 1; } /* Secondarily sort by the maximum. */ if (t1->max < t2->max) { return -1; } else if (t1->max > t2->max) { return 1; } return 0; } static void SortTriangles(Mesh *meshPtr, int nValues, float *values) { /* Compute the min/max of the z-values of the triangle */ for (i = 0; i < meshPtr->nTriangles; i++) { Triangle *t; t = meshPtr->triangles + i; t->min = t->max = values[t->a]; if (values[t->b] > t->max) { t->max = values[t->b]; } else if (values[t->b] < t->min) { t->min = values[t->b]; } if (values[t->c] > t->max) { t->max = values[t->c]; } else if (values[t->c] < t->min) { t->min = values[t->c]; } } /* Sort the triangles by the current set of values associates with the * mesh. */ qsort(meshPtr->triangles, meshPtr->nTriangles, sizeof(Triangle), CompareTriangles); } /* Display a cont widget */ static int MapContour(Tcl_Interp *interp, Element *elemPtr) { ContourElement *contPtr = (ContourElement *)elemPtr; Polygon *P; int i, k, N, M; Tcl_Obj *listObjPtr, *subListObjPtr, *objPtr; init_extra_points(contPtr); init_poly_table(); SortTriangles(contPtr->meshPtr, contPtr->nValues, contPtr->values); for (i = 0; i < contPtr->nIsolines; i++) { double z; z = contPtr->isolines[i]; for (j = 0; j < contPtr->meshPtr->nTriangles; j++) { Triangle *t; t = contPtr->meshPtr->triangles + j; if (z < t->min) { break; /* No more triangles in range. */ } if (z > t->max) { continue; /* Not in range. */ } ProcessTriangle(contPtr, t, z); } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTree.h���������������������������������������������������������������������0000644�0001750�0001750�00000043705�11462120063�014611� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTree.h -- * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_TREE_H #define _BLT_TREE_H #include <bltChain.h> #include <bltHash.h> #include <bltPool.h> typedef struct _Blt_TreeSlink *Blt_TreeSlink; typedef struct _Blt_TreeNode *Blt_TreeNode; typedef struct _Blt_TreeObject *Blt_TreeObject; typedef struct _Blt_Tree *Blt_Tree; typedef struct _Blt_TreeTrace *Blt_TreeTrace; typedef struct _Blt_TreeValue *Blt_TreeValue; typedef struct _Blt_TreeTagEntry Blt_TreeTagEntry; typedef struct _Blt_TreeTagTable Blt_TreeTagTable; typedef struct _Blt_TreeInterpData Blt_TreeInterpData; typedef const char *Blt_TreeKey; #define TREE_CREATE (1<<0) #define TREE_NEWTAGS (1<<1) #define TREE_PREORDER (1<<0) #define TREE_POSTORDER (1<<1) #define TREE_INORDER (1<<2) #define TREE_BREADTHFIRST (1<<3) #define TREE_NODE_LINK (1<<0) #define TREE_TRACE_UNSET (1<<3) #define TREE_TRACE_WRITE (1<<4) #define TREE_TRACE_READ (1<<5) #define TREE_TRACE_CREATE (1<<6) #define TREE_TRACE_ALL \ (TREE_TRACE_UNSET | TREE_TRACE_WRITE | TREE_TRACE_READ | TREE_TRACE_CREATE) #define TREE_TRACE_MASK (TREE_TRACE_ALL) #define TREE_TRACE_WHENIDLE (1<<8) #define TREE_TRACE_FOREIGN_ONLY (1<<9) #define TREE_TRACE_ACTIVE (1<<10) #define TREE_NOTIFY_CREATE (1<<0) #define TREE_NOTIFY_DELETE (1<<1) #define TREE_NOTIFY_MOVE (1<<2) #define TREE_NOTIFY_SORT (1<<3) #define TREE_NOTIFY_RELABEL (1<<4) #define TREE_NOTIFY_ALL \ (TREE_NOTIFY_CREATE | TREE_NOTIFY_DELETE | TREE_NOTIFY_MOVE | \ TREE_NOTIFY_SORT | TREE_NOTIFY_RELABEL) #define TREE_NOTIFY_MASK (TREE_NOTIFY_ALL) #define TREE_NOTIFY_WHENIDLE (1<<8) #define TREE_NOTIFY_FOREIGN_ONLY (1<<9) #define TREE_NOTIFY_ACTIVE (1<<10) #define TREE_RESTORE_NO_TAGS (1<<0) #define TREE_RESTORE_OVERWRITE (1<<1) #define TREE_INCLUDE_ROOT (1<<0) typedef struct { int type; Blt_Tree tree; long inode; /* Node of event */ Blt_TreeNode node; Tcl_Interp *interp; } Blt_TreeNotifyEvent; typedef struct { Blt_TreeNode node; /* Node being searched. */ unsigned long nextIndex; /* Index of next bucket to be enumerated after * present one. */ Blt_TreeValue nextValue; /* Next entry to be enumerated in the the * current bucket. */ } Blt_TreeKeyIterator; /* * Blt_TreeObject -- * * Structure providing the internal representation of the tree object. A * tree is uniquely identified by a combination of its name and * originating namespace. Two trees in the same interpreter can have the * same names but must reside in different namespaces. * * The tree object represents a general-ordered tree of nodes. Each node * may contain a heterogeneous collection of data values. Each value is * identified by a field name and nodes do not need to contain the same * data fields. Data field names are saved as reference counted strings * and can be shared among nodes. * * The tree is threaded. Each node contains pointers to back its parents * to its next sibling. * * A tree object can be shared by several clients. When a client wants * to use a tree object, it is given a token that represents the tree. * The tree object uses the tokens to keep track of its clients. When * all clients have released their tokens the tree is automatically * destroyed. */ struct _Blt_TreeObject { Blt_TreeNode root; /* Root of the entire tree. */ const char *sortNodesCmd; /* TCL command to invoke to sort entries */ Blt_Chain clients; /* List of clients using this tree */ Blt_Pool nodePool; Blt_Pool valuePool; Blt_HashTable nodeTable; /* Table of node identifiers. Used to * search for a node pointer given an inode.*/ Blt_TreeInterpData *dataPtr; long nextInode; long nNodes; /* Always counts root node. */ long depth; /* Maximum depth of the tree. */ unsigned int flags; /* Internal flags. See definitions below. */ unsigned int notifyFlags; /* Notification flags. See definitions * below. */ }; /* * _Blt_TreeNode -- * * Structure representing a node in a general ordered tree. Nodes are * identified by their index, or inode. Nodes also have names, but nodes * names are not unique and can be changed. Inodes are valid even if the * node is moved. * * Each node can contain a list of data fields. Fields are name-value * pairs. The values are represented by Tcl_Objs. * */ struct _Blt_TreeNode { Blt_TreeNode parent; /* Parent node. If NULL, then this is the root node. */ Blt_TreeNode next, prev; /* Next/previous sibling nodes. */ Blt_TreeNode hnext; /* Next node in the hash bucket. */ Blt_TreeKey label; /* Node label (doesn't have to be unique). */ long inode; /* Serial number of the node. */ Blt_TreeObject corePtr; /* Pointer back to the tree object that * contains this node. */ size_t depth; /* The depth of this node in the tree. */ size_t nChildren; /* # of children for this node. */ Blt_TreeNode first, last; /* First/last nodes of child nodes stored as a * linked list. */ Blt_TreeNode *nodeTable; /* Hash table of child nodes. */ size_t nodeTableSize2; /* Log2 size of child node hash table. */ Blt_TreeValue values; /* Chain of Blt_TreeValue structures. Each * value structure contains a key/value data * pair. The data value is a Tcl_Obj. */ Blt_TreeValue *valueTable; /* Hash table for values. When the number of * values reaches exceeds a threshold, values * will also be linked into this hash * table. */ unsigned short nValues; /* # of values for this node. */ unsigned short valueTableSize2; /* Size of hash table indicated as a power * of 2 (e.g. if logSize=3, then table size is * 8). If 0, this indicates that the node's * values are stored as a list. */ unsigned int flags; /* Indicates if this node is currently used * within an active trace. */ }; struct _Blt_TreeTagEntry { const char *tagName; Blt_HashEntry *hashPtr; Blt_HashTable nodeTable; }; struct _Blt_TreeTagTable { Blt_HashTable tagTable; int refCount; }; /* * _Blt_Tree -- * * A tree may be shared by several clients. Each client allocates this * structure which acts as a ticket for using the tree. Each client can * * - Designate notifier routines that are automatically invoked by the * tree object when nodes are created, deleted, moved, etc. by other * clients. * - Place traces on the values of specific nodes. * - Manage its own set or common of tags for nodes of the tree. By * default, clients share tags. */ struct _Blt_Tree { unsigned int magic; /* Magic value indicating whether a generic * pointer is really a datatable token or * not. */ const char *name; /* Fully namespace-qualified name of the * client. */ Blt_TreeObject corePtr; /* Pointer to the structure containing the * master information about the tree used by * the client. If NULL, this indicates that * the tree has been destroyed (but as of yet, * this client hasn't recognized it). */ Tcl_Interp *interp; /* Interpreter associated with this tree. */ Blt_HashEntry *hPtr; /* This client's entry in the above * table. This is a list of clients that all * have the same qualified table name * (i.e. are sharing the same table. */ Blt_ChainLink link; /* Pointer to this link in the server's chain * of clients. */ Blt_Chain events; /* Chain of node event handlers. */ Blt_Chain traces; /* Chain of data field callbacks. */ Blt_TreeNode root; /* Designated root for this client */ Blt_TreeTagTable *tagTablePtr; /* Tag table used by this client. */ }; typedef int (Blt_TreeNotifyEventProc)(ClientData clientData, Blt_TreeNotifyEvent *eventPtr); typedef int (Blt_TreeTraceProc)(ClientData clientData, Tcl_Interp *interp, Blt_TreeNode node, Blt_TreeKey key, unsigned int flags); typedef int (Blt_TreeEnumProc)(Blt_TreeNode node, Blt_TreeKey key, Tcl_Obj *valuePtr); typedef int (Blt_TreeCompareNodesProc)(Blt_TreeNode *n1Ptr, Blt_TreeNode *n2Ptr); typedef int (Blt_TreeApplyProc) _ANSI_ARGS_((Blt_TreeNode node, ClientData clientData, int order)); struct _Blt_TreeTrace { ClientData clientData; Blt_TreeKey key; Blt_TreeNode node; unsigned int mask; Blt_TreeTraceProc *proc; }; /* * Structure definition for information used to keep track of searches through * hash tables: */ struct _Blt_TreeKeyIterator { Blt_TreeNode node; /* Table being searched. */ unsigned long nextIndex; /* Index of next bucket to be enumerated after * present one. */ Blt_TreeValue nextValue; /* Next entry to be enumerated in the the * current bucket. */ }; BLT_EXTERN Blt_TreeKey Blt_Tree_GetKey(Blt_Tree tree, const char *string); BLT_EXTERN Blt_TreeKey Blt_Tree_GetKeyFromNode(Blt_TreeNode node, const char *string); BLT_EXTERN Blt_TreeKey Blt_Tree_GetKeyFromInterp(Tcl_Interp *interp, const char *string); BLT_EXTERN Blt_TreeNode Blt_Tree_CreateNode(Blt_Tree tree, Blt_TreeNode parent, const char *name, long position); BLT_EXTERN Blt_TreeNode Blt_Tree_CreateNodeWithId(Blt_Tree tree, Blt_TreeNode parent, const char *name, long inode, long position); BLT_EXTERN int Blt_Tree_DeleteNode(Blt_Tree tree, Blt_TreeNode node); BLT_EXTERN int Blt_Tree_MoveNode(Blt_Tree tree, Blt_TreeNode node, Blt_TreeNode parent, Blt_TreeNode before); BLT_EXTERN Blt_TreeNode Blt_Tree_GetNode(Blt_Tree tree, long inode); BLT_EXTERN Blt_TreeNode Blt_Tree_FindChild(Blt_TreeNode parent, const char *name); BLT_EXTERN Blt_TreeNode Blt_Tree_NextNode(Blt_TreeNode root, Blt_TreeNode node); BLT_EXTERN Blt_TreeNode Blt_Tree_PrevNode(Blt_TreeNode root, Blt_TreeNode node); BLT_EXTERN Blt_TreeNode Blt_Tree_FirstChild(Blt_TreeNode parent); BLT_EXTERN Blt_TreeNode Blt_Tree_LastChild(Blt_TreeNode parent); BLT_EXTERN Blt_TreeNode Blt_Tree_ChangeRoot(Blt_Tree tree, Blt_TreeNode node); BLT_EXTERN Blt_TreeNode Blt_Tree_EndNode(Blt_TreeNode node, unsigned int nodeFlags); BLT_EXTERN int Blt_Tree_IsBefore(Blt_TreeNode node1, Blt_TreeNode node2); BLT_EXTERN int Blt_Tree_IsAncestor(Blt_TreeNode node1, Blt_TreeNode node2); BLT_EXTERN int Blt_Tree_PrivateValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key); BLT_EXTERN int Blt_Tree_PublicValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key); BLT_EXTERN int Blt_Tree_GetValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *string, Tcl_Obj **valuePtr); BLT_EXTERN int Blt_Tree_ValueExists(Blt_Tree tree, Blt_TreeNode node, const char *string); BLT_EXTERN int Blt_Tree_SetValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *string, Tcl_Obj *valuePtr); BLT_EXTERN int Blt_Tree_UnsetValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *string); BLT_EXTERN int Blt_Tree_GetArrayValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *arrayName, const char *elemName, Tcl_Obj **valueObjPtrPtr); BLT_EXTERN int Blt_Tree_SetArrayValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *arrayName, const char *elemName, Tcl_Obj *valueObjPtr); BLT_EXTERN int Blt_Tree_UnsetArrayValue(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *arrayName, const char *elemName); BLT_EXTERN int Blt_Tree_ArrayValueExists(Blt_Tree tree, Blt_TreeNode node, const char *arrayName, const char *elemName); BLT_EXTERN int Blt_Tree_ArrayNames(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, const char *arrayName, Tcl_Obj *listObjPtr); BLT_EXTERN int Blt_Tree_GetValueByKey(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key, Tcl_Obj **valuePtr); BLT_EXTERN int Blt_Tree_SetValueByKey(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key, Tcl_Obj *valuePtr); BLT_EXTERN int Blt_Tree_UnsetValueByKey(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key); BLT_EXTERN int Blt_Tree_ValueExistsByKey(Blt_Tree tree, Blt_TreeNode node, Blt_TreeKey key); BLT_EXTERN Blt_TreeKey Blt_Tree_FirstKey(Blt_Tree tree, Blt_TreeNode node, Blt_TreeKeyIterator *iterPtr); BLT_EXTERN Blt_TreeKey Blt_Tree_NextKey(Blt_Tree tree, Blt_TreeKeyIterator *iterPtr); BLT_EXTERN int Blt_Tree_Apply(Blt_TreeNode root, Blt_TreeApplyProc *proc, ClientData clientData); BLT_EXTERN int Blt_Tree_ApplyDFS(Blt_TreeNode root, Blt_TreeApplyProc *proc, ClientData clientData, int order); BLT_EXTERN int Blt_Tree_ApplyBFS(Blt_TreeNode root, Blt_TreeApplyProc *proc, ClientData clientData); BLT_EXTERN int Blt_Tree_SortNode(Blt_Tree tree, Blt_TreeNode node, Blt_TreeCompareNodesProc *proc); BLT_EXTERN int Blt_Tree_Exists(Tcl_Interp *interp, const char *name); BLT_EXTERN Blt_Tree Blt_Tree_Open(Tcl_Interp *interp, const char *name, int flags); BLT_EXTERN void Blt_Tree_Close(Blt_Tree tree); BLT_EXTERN int Blt_Tree_Attach(Tcl_Interp *interp, Blt_Tree tree, const char *name); BLT_EXTERN int Blt_Tree_Size(Blt_TreeNode node); BLT_EXTERN Blt_TreeTrace Blt_Tree_CreateTrace(Blt_Tree tree, Blt_TreeNode node, const char *keyPattern, const char *tagName, unsigned int mask, Blt_TreeTraceProc *proc, ClientData clientData); BLT_EXTERN void Blt_Tree_DeleteTrace(Blt_TreeTrace token); BLT_EXTERN void Blt_Tree_CreateEventHandler(Blt_Tree tree, unsigned int mask, Blt_TreeNotifyEventProc *proc, ClientData clientData); BLT_EXTERN void Blt_Tree_CreateTagEventHandler(Blt_Tree tree, unsigned int mask, const char *tag, Blt_TreeNotifyEventProc *proc, ClientData clientData); BLT_EXTERN void Blt_Tree_CreateNodeEventHandler(Blt_Tree tree, unsigned int mask, Blt_TreeNode node, Blt_TreeNotifyEventProc *proc, ClientData clientData); BLT_EXTERN void Blt_Tree_DeleteEventHandler(Blt_Tree tree, unsigned int mask, Blt_TreeNotifyEventProc *proc, ClientData clientData); BLT_EXTERN void Blt_Tree_RelabelNode(Blt_Tree tree, Blt_TreeNode node, const char *string); BLT_EXTERN void Blt_Tree_RelabelNodeWithoutNotify(Blt_TreeNode node, const char *string); BLT_EXTERN const char *Blt_Tree_NodeIdAscii(Blt_TreeNode node); BLT_EXTERN const char *Blt_Tree_NodePath(Blt_TreeNode node, Tcl_DString *resultPtr); BLT_EXTERN const char *Blt_Tree_NodeRelativePath(Blt_TreeNode root, Blt_TreeNode node, const char *separator, unsigned int flags, Tcl_DString *resultPtr); BLT_EXTERN long Blt_Tree_NodePosition(Blt_TreeNode node); BLT_EXTERN void Blt_Tree_ClearTags(Blt_Tree tree, Blt_TreeNode node); BLT_EXTERN int Blt_Tree_HasTag(Blt_Tree tree, Blt_TreeNode node, const char *tagName); BLT_EXTERN void Blt_Tree_AddTag(Blt_Tree tree, Blt_TreeNode node, const char *tagName); BLT_EXTERN void Blt_Tree_RemoveTag(Blt_Tree tree, Blt_TreeNode node, const char *tagName); BLT_EXTERN void Blt_Tree_ForgetTag(Blt_Tree tree, const char *tagName); BLT_EXTERN Blt_HashTable *Blt_Tree_TagHashTable(Blt_Tree tree, const char *tagName); BLT_EXTERN int Blt_Tree_TagTableIsShared(Blt_Tree tree); BLT_EXTERN void Blt_Tree_NewTagTable(Blt_Tree tree); BLT_EXTERN Blt_HashEntry *Blt_Tree_FirstTag(Blt_Tree tree, Blt_HashSearch *searchPtr); BLT_EXTERN int Blt_Tree_ImportData(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode root, Tcl_Obj *objPtr, unsigned int flags); BLT_EXTERN int Blt_Tree_ImportFile(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode root, Tcl_Obj *objPtr, unsigned int flags); BLT_EXTERN void Blt_Tree_DumpNode(Blt_Tree tree, Blt_TreeNode root, Blt_TreeNode node, Tcl_DString *resultPtr); BLT_EXTERN int Blt_Tree_Dump(Blt_Tree tree, Blt_TreeNode root, Tcl_DString *resultPtr); BLT_EXTERN int Blt_Tree_DumpToFile(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode root, const char *fileName); BLT_EXTERN int Blt_Tree_Restore _ANSI_ARGS_((Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode root, const char *string, unsigned int flags)); BLT_EXTERN int Blt_Tree_RestoreFromFile(Tcl_Interp *interp, Blt_Tree tree, Blt_TreeNode root, const char *fileName, unsigned int flags); #define Blt_Tree_Name(token) ((token)->name) #define Blt_Tree_RootNode(token) ((token)->root) #define Blt_Tree_NodeDegree(node) ((node)->nChildren) #define Blt_Tree_NodeDepth(node) ((node)->depth) #define Blt_Tree_NodeLabel(node) ((node)->label) #define Blt_Tree_NodeId(node) ((node)->inode) #define Blt_Tree_NextNodeId(token) ((token)->corePtr->nextInode) #define Blt_Tree_ParentNode(node) ((node == NULL) ? NULL : (node)->parent) #define Blt_Tree_IsLeaf(node) ((node)->nChildren == 0) #define Blt_Tree_IsLink(node) ((node)->flags & TREE_NODE_LINK) #define Blt_Tree_NextSibling(node) (((node) == NULL) ? NULL : (node)->next) #define Blt_Tree_PrevSibling(node) (((node) == NULL) ? NULL : (node)->prev) typedef int (Blt_TreeImportProc)(Tcl_Interp *interp, Blt_Tree tree, int objc, Tcl_Obj *const *objv); typedef int (Blt_TreeExportProc)(Tcl_Interp *interp, Blt_Tree tree, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_Tree_RegisterFormat(Tcl_Interp *interp, const char *fmtName, Blt_TreeImportProc *importProc, Blt_TreeExportProc *exportProc); BLT_EXTERN Blt_TreeTagEntry *Blt_Tree_RememberTag(Blt_Tree tree, const char *name); #endif /* _BLT_TREE_H */ �����������������������������������������������������������./saods9/blt3.0.1/src/bltComboEntry.c���������������������������������������������������������������0000644�0001750�0001750�00000404111�11462120062�015755� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltComboEntry.c -- * * This module implements a comboentry widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltImage.h" #include "bltHash.h" #include "bltBgStyle.h" #include "bltPicture.h" #include "bltPainter.h" #include <X11/Xutil.h> #include <X11/Xatom.h> #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define IPAD 4 /* Internal pad between components. */ #define YPAD 2 /* Internal pad between components. */ #define ICWIDTH 2 /* External pad between border and * arrow. */ #define ARROW_WIDTH 13 #define ARROW_HEIGHT 13 #define CLOSE_WIDTH 16 #define CLOSE_HEIGHT 16 #define EVENT_MASK (ExposureMask|StructureNotifyMask|FocusChangeMask) #define CHILD_EVENT_MASK (ExposureMask|StructureNotifyMask) #define REDRAW_PENDING (1<<0) /* The widget is scheduled to be * redrawn. */ #define LAYOUT_PENDING (1<<1) /* The widget's layout needs to be * recomputed. */ #define ICURSOR (1<<2) /* Insertion cursor is active. * Depending upon the timer interval, * it may be drawn or not drawn. */ #define SCROLL_PENDING (1<<3) /* The widget needs to be scrolled. */ #define FOCUS (1<<4) /* The widget has focus. */ #define SELECT_PENDING (1<<5) /* The widget is scheduled to invoke a * -selectcommand in response to a * change in its selection. */ #define INVOKE_PENDING (1<<6) /* The widget is scheduled to invoke a * -command. */ #define CIPHER (1<<7) /* Don't display the actual text on * the screen. */ #define READONLY (1<<8) /* The widget's editting functions * are disabled. */ #define EXPORT_SELECTION (1<<9) /* The selection is exported to the * clipboard. */ #define NORMAL (1<<10) /* The widget is drawn normally. */ #define DISABLED (1<<11) /* The widget is is disabled. */ #define POSTED (1<<12) /* The widget has posted a menu. */ #define STATE_MASK ((DISABLED)|(NORMAL)|(POSTED)) #define ICURSOR_ON (1<<13) /* The insertion cursor is currently * visible on screen. */ #define ARROW (1<<14) /* Display the arrow button on the far * right.*/ #define CLOSE (1<<15) /* Display the close button on the * right when text has been * entered. */ #define ACTIVE_ARROW (1<<16) /* The arrow button is currently active. */ #define ACTIVE_CLOSE (1<<17) /* The close button is currently * active. */ #define ACTIVE_MASK ((ACTIVE_ARROW)|(ACTIVE_CLOSE)) #define MODIFIED (1<<18) /* The contents of the text of the * entry have been modified. */ #define TRACE_VAR_FLAGS (TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS) #define DEF_ARROW_ACTIVE_BG STD_ACTIVE_BACKGROUND #define DEF_ARROW_ACTIVE_FG STD_ACTIVE_FOREGROUND #define DEF_BORDERWIDTH "0" #define DEF_ARROW "1" #define DEF_ARROW_BORDERWIDTH "2" #define DEF_ARROW_PAD "0" #define DEF_ARROW_RELIEF "raised" #define DEF_ARROW_WIDTH "0" #define DEF_CIPHER "0" #define DEF_CLOSE "0" #define DEF_CMD ((char *)NULL) #define DEF_CURSOR ((char *)NULL) #define DEF_DISABLED_BG STD_DISABLED_BACKGROUND #define DEF_DISABLED_FG STD_DISABLED_FOREGROUND #define DEF_EXPORTSELECTION "1" #define DEF_FONT STD_FONT_SMALL #define DEF_HEIGHT "0" #define DEF_HIGHLIGHT_BG_COLOR ((char *)NULL) #define DEF_HIGHLIGHT_COLOR "black" #define DEF_HIGHLIGHT_WIDTH "2" #define DEF_ICON ((char *)NULL) #define DEF_ICON_VARIABLE ((char *)NULL) #define DEF_IMAGE ((char *)NULL) #define DEF_INSERT_COLOR STD_NORMAL_FOREGROUND #define DEF_INSERT_OFFTIME "300" #define DEF_INSERT_ONTIME "600" #define DEF_JUSTIFY "left" #define DEF_MENU ((char *)NULL) #define DEF_MENU_ANCHOR "sw" #define DEF_NORMAL_BG STD_NORMAL_BACKGROUND #define DEF_NORMAL_FG STD_NORMAL_FOREGROUND #define DEF_EDITABLE "1" #define DEF_RELIEF "sunken" #define DEF_SCROLL_CMD ((char *)NULL) #define DEF_SCROLL_INCR "2" #define DEF_SELECT_BORDERWIDTH "0" #define DEF_SELECT_CMD ((char *)NULL) #define DEF_SELECT_FG RGB_WHITE #define DEF_SELECT_BG RGB_SKYBLUE4 #define DEF_SELECT_RELIEF "flat" #define DEF_STATE "normal" #define DEF_TAKE_FOCUS "1" #define DEF_TEXT (char *)NULL #define DEF_TEXT_FOCUS_BG RGB_WHITE #define DEF_TEXT_FOCUS_FG RGB_BLACK #define DEF_TEXT_NORMAL_BG RGB_WHITE #define DEF_TEXT_NORMAL_FG RGB_BLACK #define DEF_TEXT_VARIABLE ((char *)NULL) #define DEF_UNDERLINE "-1" #define DEF_WIDTH "0" #define DEF_BUTTON_ACTIVEBACKGROUND RGB_RED #define DEF_BUTTON_ACTIVEFOREGROUND RGB_WHITE #define DEF_BUTTON_ACTIVERELIEF "raised" #define DEF_BUTTON_BACKGROUND RGB_GREY70 #define DEF_BUTTON_BORDERWIDTH "1" #define DEF_BUTTON_COMMAND (char *)NULL #define DEF_BUTTON_FOREGROUND RGB_GREY95 #define DEF_BUTTON_RELIEF "flat" static Tcl_VarTraceProc TextVarTraceProc; static Tcl_VarTraceProc IconVarTraceProc; static Blt_OptionFreeProc FreeTextProc; static Blt_OptionParseProc ObjToTextProc; static Blt_OptionPrintProc TextToObjProc; static Blt_CustomOption textOption = { ObjToTextProc, TextToObjProc, FreeTextProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0 }; static Blt_OptionFreeProc FreeTextVarProc; static Blt_OptionParseProc ObjToTextVarProc; static Blt_OptionPrintProc TextVarToObjProc; static Blt_CustomOption textVarOption = { ObjToTextVarProc, TextVarToObjProc, FreeTextVarProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconVarProc; static Blt_OptionParseProc ObjToIconVarProc; static Blt_OptionPrintProc IconVarToObjProc; static Blt_CustomOption iconVarOption = { ObjToIconVarProc, IconVarToObjProc, FreeIconVarProc, (ClientData)0 }; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; /* * Icon -- * * Since instances of the same Tk image can be displayed in different * windows with possibly different color palettes, Tk internally stores * each instance in a linked list. But if the instances are used in the * same widget and therefore use the same color palette, this adds a lot * of overhead, especially when deleting instances from the linked list. * * For the comboentry widget, we never need more than a single instance * of an image, regardless of how many times it's used. Cache the image, * maintaining a reference count for each image used in the widget. It's * likely that the comboview widget will use many instances of the same * image. */ typedef struct Icon { Tk_Image tkImage; /* The Tk image being cached. */ short int width, height; /* Dimensions of the cached image. */ } *Icon; #define IconHeight(i) ((i)->height) #define IconWidth(i) ((i)->width) #define IconImage(i) ((i)->tkImage) #define IconName(i) (Blt_Image_Name((i)->tkImage)) #define INSERT_OP 1 #define DELETE_OP 2 /* * Button -- */ typedef struct { int borderWidth; /* Width of 3D border around the tab's * button. */ int pad; /* Extra padding around button. */ int activeRelief; /* 3D relief when the button is * active. */ int relief; /* 3D relief of button. */ XColor *normalFg; /* If non-NULL, image to be displayed * when button is displayed. */ XColor *normalBg; /* If non-NULL, image to be displayed * when the button is active. */ XColor *activeFg; /* If non-NULL, image to be displayed * when button is displayed. */ XColor *activeBg; /* If non-NULL, image to be displayed * when the button is active. */ Tcl_Obj *cmdObjPtr; /* Command to be executed when the * the button is invoked. */ Blt_Painter painter; Blt_Picture normalPicture; /* If non-NULL, image to be displayed * when button is displayed. */ Blt_Picture activePicture; /* If non-NULL, image to be displayed * when the button is active. */ short int x, y; /* Location of the button in the * entry. Used for picking. */ short int width, height; /* Dimension of the button. */ } Button; static Blt_ConfigSpec buttonSpecs[] = { {BLT_CONFIG_COLOR, "-activebackground", "activeBackrgound", "ActiveBackground", DEF_BUTTON_ACTIVEBACKGROUND, Blt_Offset(Button, activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForergound", "ActiveForeground", DEF_BUTTON_ACTIVEFOREGROUND, Blt_Offset(Button, activeFg), 0}, {BLT_CONFIG_COLOR, "-background", "backrgound", "Background", DEF_BUTTON_BACKGROUND, Blt_Offset(Button, normalBg), 0}, {BLT_CONFIG_COLOR, "-foreground", "forergound", "Foreground", DEF_BUTTON_FOREGROUND, Blt_Offset(Button, normalFg), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "ActiveRelief", DEF_BUTTON_ACTIVERELIEF, Blt_Offset(Button, activeRelief), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BUTTON_BORDERWIDTH, Blt_Offset(Button, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_BUTTON_COMMAND, Blt_Offset(Button, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_BUTTON_RELIEF, Blt_Offset(Button, relief), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static char emptyString[] = ""; typedef struct _EditRecord { struct _EditRecord *nextPtr; short int type; short int insertOffset; short int offset; short int textLen; char text[1]; } EditRecord; typedef struct { Tcl_Interp *interp; /* Interpreter associated with * entry. */ Tk_Window tkwin; /* Window that embodies the * comboentry. If NULL, indicates the * window has been destroyed but the * data structures haven't yet been * cleaned up.*/ Display *display; /* Display containing widget. Used, * among other things, so that * resources can be freed even after * tkwin has gone away. */ Tcl_Command cmdToken; /* Token for comboentry's widget * command. */ Tk_Cursor cursor; /* Current cursor for window or * None. */ int reqWidth, reqHeight; int relief; int borderWidth; Blt_Background inFocusBg; Blt_Background outFocusBg; Blt_Background normalBg; Blt_Background activeBg; Blt_Background disabledBg; XColor *normalColor; XColor *activeColor; XColor *disabledColor; Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not * used in the C code, but used by * keyboard traversal scripts. */ /* * Selection Information: * * The selection is the rectangle that contains selected text. It is * displayed as a solid colored entry with optionally a 3D border. */ int selAnchor; /* Fixed end of selection. Used to * extend the selection while * maintaining the * other end of the * selection. */ short int selFirst; /* Byte offset of the 1st character in * the selection. */ short int selLast; /* Byte offset of the last character * in the selection. */ int selRelief; /* Relief of selected items. Currently * is always raised. */ int selBW; /* Border width of a selected text.*/ XColor *selFgColor; /* Text color of a selected text. */ GC selectGC; Tcl_Obj *selCmdObjPtr; Blt_Background selectBg; Button closeButton; /* * Scanning Information: */ int scanAnchor; /* Scan anchor in screen * coordinates. */ int scanX; /* x-offset of the start of the scan * in world coordinates.*/ /* * Scrolling Information: */ Tcl_Obj *scrollCmdObjPtr; /* Command prefix for communicating * with scrollbars. If NULL, * indicates no command to issue. */ int scrollUnits; /* # of pixels per scroll unit. */ int scrollX; /* x-offset of the start of visible * text in the viewport. */ int viewWidth; /* Width of the viewport. */ /* * In/Out Focus Highlight Ring: */ XColor *highlightColor; XColor *highlightBgColor; GC highlightBgGC; GC highlightGC; int highlightWidth; /* * Entry entry: * * The entry contains optionally an icon and a text string. The rectangle * surrounding an entry may have a 3D border. */ Icon icon; /* If non-NULL, image to be displayed * in entry. Its value may be * overridden by the -iconvariable * option. */ Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable contains the name of * an image representing the icon. * This overrides the value of the * above field. */ Icon image; /* If non-NULL, image to be displayed * instead of text in the entry. */ char *text; /* Text string to be displayed in the * entry if an image has no been * designated. Its value is overridden * by the -textvariable option. */ char *screenText; /* Text string to be displayed in the * entry if an image has no been * designated. Its value is overridden * by the -textvariable option. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable contains the text * string to * be displayed in the * entry. This overrides the above * field. */ Blt_Font font; /* Font of text to be display in * entry. */ XColor *textInFocusColor; XColor *textOutFocusColor; GC textInFocusGC; GC textOutFocusGC; int textLen; /* # bytes of text. */ /* * Arrow Information: */ int arrowBW; int arrowRelief; int reqArrowWidth; int arrowPad; /* * Insertion cursor information: */ XColor *insertColor; /* Color used to draw vertical bar for * insertion cursor. */ int insertOffTime; /* Time in milliseconds cursor should * spend in "off" state for each * blink. */ int insertOnTime; /* Time in milliseconds cursor should * spend in "off" state for each * blink. */ Tcl_TimerToken insertTimerToken; /* Handle for a timer event called * periodically to blink the insertion * cursor. */ int insertWidth; /* Total width of insert cursor. */ int insertOffset; /* Byte offset of insertion cursor in * the text string. */ GC insertGC; int prefTextWidth; /* Desired width of text, measured in * average characters. */ int prefIconWidth; /* Desired width of icon, measured in * pixels. */ int inset; short int arrowWidth, arrowHeight; short int iconWidth, iconHeight; short int entryWidth, entryHeight; short int textWidth, textHeight; short int width, height; short int firstOffset, lastOffset; /* Byte offset of first and last * characters visible in viewport. */ int firstX, lastX; /* x-coordinates of first and last * characters visible in viewport. */ Tcl_Obj *cmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ Tcl_Obj *menuObjPtr; Tk_Window menuWin; Tcl_Obj *postCmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ int menuAnchor; unsigned int flags; EditRecord *undoPtr, *redoPtr; } ComboEntry; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_ARROW_ACTIVE_BG, Blt_Offset(ComboEntry, activeBg),0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_ARROW_ACTIVE_FG, Blt_Offset(ComboEntry, activeColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-arrowborderwidth", "arrowBorderWidth", "ArrowBorderWidth", DEF_ARROW_BORDERWIDTH, Blt_Offset(ComboEntry, arrowBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-arrowpad", "arrowPad", "ArrowPad", DEF_ARROW_PAD, Blt_Offset(ComboEntry, arrowPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-arrowrelief", "arrowRelief","ArrowRelief", DEF_ARROW_RELIEF, Blt_Offset(ComboEntry, arrowRelief), 0}, {BLT_CONFIG_PIXELS_NNEG, "-arrowwidth", "arrowWidth","ArrowWidth", DEF_ARROW_WIDTH, Blt_Offset(ComboEntry, reqArrowWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_NORMAL_BG, Blt_Offset(ComboEntry, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(ComboEntry, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-cipher", "cipher", "Cipher", DEF_CIPHER, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)CIPHER}, {BLT_CONFIG_BITMASK, "-closebutton", "closeButton", "CloseButton", DEF_CLOSE, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)CLOSE}, {BLT_CONFIG_OBJ, "-closecommand", "closeCommand", "CloseCommand", DEF_BUTTON_COMMAND, Blt_Offset(ComboEntry, closeButton.cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_CMD, Blt_Offset(ComboEntry, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(ComboEntry, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", "disabledBackground", "DisabledBackground", DEF_DISABLED_BG, Blt_Offset(ComboEntry, disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_DISABLED_FG, Blt_Offset(ComboEntry, disabledColor), 0}, {BLT_CONFIG_BITMASK, "-exportselection", "exportSelection", "ExportSelection", DEF_EXPORTSELECTION, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)EXPORT_SELECTION}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_FONT, Blt_Offset(ComboEntry, font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_NORMAL_FG, Blt_Offset(ComboEntry, normalColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(ComboEntry, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK_INVERT, "-hidearrow", "hideArrow", "HideArrow", DEF_ARROW, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)ARROW}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HIGHLIGHT_BG_COLOR, Blt_Offset(ComboEntry, highlightBgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHT_COLOR, Blt_Offset(ComboEntry, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHT_WIDTH, Blt_Offset(ComboEntry, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", DEF_ICON, Blt_Offset(ComboEntry, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-iconvariable", "iconVariable", "IconVariable", DEF_TEXT_VARIABLE, Blt_Offset(ComboEntry, iconVarObjPtr), BLT_CONFIG_NULL_OK, &iconVarOption}, {BLT_CONFIG_PIXELS_NNEG, "-iconwidth", "iconWidth", "IconWidth", DEF_WIDTH, Blt_Offset(ComboEntry, prefIconWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", DEF_IMAGE, Blt_Offset(ComboEntry, image), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_COLOR, "-insertbackground", "insertBackground", "InsertBackground", DEF_INSERT_COLOR, Blt_Offset(ComboEntry, insertColor), 0}, {BLT_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", DEF_INSERT_OFFTIME, Blt_Offset(ComboEntry, insertOffTime), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", DEF_INSERT_ONTIME, Blt_Offset(ComboEntry, insertOnTime), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-menu", "menu", "Menu", DEF_MENU, Blt_Offset(ComboEntry, menuObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-menuanchor", "menuAnchor", "MenuAnchor", DEF_MENU_ANCHOR, Blt_Offset(ComboEntry, menuAnchor),BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-postcommand", "postCommand", "PostCommand", DEF_CMD, Blt_Offset(ComboEntry, postCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK_INVERT, "-editable", "editable", "Editable", DEF_EDITABLE, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)READONLY}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_RELIEF, Blt_Offset(ComboEntry, relief), 0}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", DEF_SELECT_BG, Blt_Offset(ComboEntry, selectBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_SELECT_BORDERWIDTH, Blt_Offset(ComboEntry, selBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-selectcommand", "selectCommand", "SelectCommand", DEF_SELECT_CMD, Blt_Offset(ComboEntry, selCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_SELECT_FG, Blt_Offset(ComboEntry, selFgColor), 0}, {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief", DEF_SELECT_RELIEF, Blt_Offset(ComboEntry, selRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-state", "state", "State", DEF_STATE, Blt_Offset(ComboEntry, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, Blt_Offset(ComboEntry, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-text", "text", "Text", DEF_TEXT, Blt_Offset(ComboEntry, text), 0, &textOption}, {BLT_CONFIG_BACKGROUND, "-textbackground", "textBackground", "Background", DEF_TEXT_NORMAL_BG, Blt_Offset(ComboEntry, outFocusBg), 0}, {BLT_CONFIG_BACKGROUND, "-textfocusbackground", "textFocusBackground", "FocusBackground", DEF_TEXT_FOCUS_BG, Blt_Offset(ComboEntry, inFocusBg), 0}, {BLT_CONFIG_COLOR, "-textfocusforeground", "textFocusForeground", "focusForeground", DEF_TEXT_FOCUS_FG, Blt_Offset(ComboEntry, textInFocusColor), 0}, {BLT_CONFIG_COLOR, "-textforeground", "textForeground", "TextForeground", DEF_TEXT_NORMAL_FG, Blt_Offset(ComboEntry, textOutFocusColor), 0}, {BLT_CONFIG_CUSTOM, "-textvariable", "textVariable", "TextVariable", DEF_TEXT_VARIABLE, Blt_Offset(ComboEntry, textVarObjPtr), BLT_CONFIG_NULL_OK, &textVarOption}, {BLT_CONFIG_PIXELS_NNEG, "-textwidth", "textWidth", "TextWidth", DEF_WIDTH, Blt_Offset(ComboEntry, prefTextWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(ComboEntry, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_SCROLL_CMD, Blt_Offset(ComboEntry, scrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_SCROLL_INCR, Blt_Offset(ComboEntry, scrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Tcl_IdleProc DisplayComboEntry; static Tcl_IdleProc ComboEntrySelectCmdProc; static Tcl_IdleProc ComboEntryInvokeCmdProc; static Tcl_FreeProc FreeComboEntryProc; static Tk_EventProc ComboEntryEventProc; static Tcl_ObjCmdProc ComboEntryInstCmdProc; static Tcl_CmdDeleteProc ComboEntryInstCmdDeletedProc; static Tk_LostSelProc ComboEntryLostSelProc; static Tk_SelectionProc ComboEntrySelectionProc; static Tcl_TimerProc BlinkInsertCursorProc; typedef int (ComboEntryCmdProc)(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the comboentry display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(ComboEntry *comboPtr) { if ((comboPtr->tkwin != NULL) && ((comboPtr->flags & REDRAW_PENDING)==0)) { comboPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayComboEntry, comboPtr); } } /* *--------------------------------------------------------------------------- * * EventuallyInvokeSelectCmd -- * * Queues a request to execute the -selectcommand code associated with * the widget at the next idle point. Invoked whenever the selection * changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void EventuallyInvokeSelectCmd(ComboEntry *comboPtr) { if ((comboPtr->flags & SELECT_PENDING) == 0) { comboPtr->flags |= SELECT_PENDING; Tcl_DoWhenIdle(ComboEntrySelectCmdProc, comboPtr); } } /* *--------------------------------------------------------------------------- * * EventuallyInvokeCmd -- * * Queues a request to execute the -selectcommand code associated with * the widget at the next idle point. Invoked whenever the selection * changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void EventuallyInvokeCmd(ComboEntry *comboPtr) { if ((comboPtr->flags & INVOKE_PENDING) == 0) { comboPtr->flags |= INVOKE_PENDING; Tcl_DoWhenIdle(ComboEntryInvokeCmdProc, comboPtr); } } /* *---------------------------------------------------------------------- * * GenerateModifiedEvent -- * * Send an event that the text was modified. This is equivalent to * event generate $textWidget <<Modified>> * * Results: * None * * Side effects: * May force the text window into existence. * *---------------------------------------------------------------------- */ static void GenerateModifiedEvent(ComboEntry *comboPtr) { XVirtualEvent event; Tk_MakeWindowExist(comboPtr->tkwin); memset(&event, 0, sizeof(event)); event.type = VirtualEvent; event.serial = NextRequest(comboPtr->display); event.send_event = False; event.event = Tk_WindowId(comboPtr->tkwin); event.display = comboPtr->display; event.name = Tk_GetUid("Modified"); Tk_HandleEvent((XEvent *)&event); comboPtr->flags &= ~MODIFIED; } static int InvokeCommand(Tcl_Interp *interp, ComboEntry *comboPtr) { int result; Tcl_Preserve(comboPtr); Tcl_IncrRefCount(comboPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->cmdObjPtr); Tcl_Release(comboPtr); return result; } static int UpdateTextVariable(Tcl_Interp *interp, ComboEntry *comboPtr) { Tcl_Obj *resultObjPtr, *objPtr; const char *varName; objPtr = Tcl_NewStringObj(comboPtr->text, comboPtr->textLen); varName = Tcl_GetString(comboPtr->textVarObjPtr); Tcl_UntraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc,comboPtr); Tcl_IncrRefCount(objPtr); resultObjPtr = Tcl_ObjSetVar2(interp, comboPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); Tcl_DecrRefCount(objPtr); Tcl_TraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); if (resultObjPtr == NULL) { return TCL_ERROR; } return TCL_OK; } static void FreeUndoRecords(ComboEntry *comboPtr) { EditRecord *recPtr, *nextPtr; for (recPtr = comboPtr->undoPtr; recPtr != NULL; recPtr = nextPtr) { nextPtr = recPtr->nextPtr; Blt_Free(recPtr); } comboPtr->undoPtr = NULL; } static void FreeRedoRecords(ComboEntry *comboPtr) { EditRecord *recPtr, *nextPtr; for (recPtr = comboPtr->redoPtr; recPtr != NULL; recPtr = nextPtr) { nextPtr = recPtr->nextPtr; Blt_Free(recPtr); } comboPtr->redoPtr = NULL; } static void RecordEdit(ComboEntry *comboPtr, int type, int offset, int textLen, const char *text) { EditRecord *recPtr; recPtr = Blt_AssertMalloc(sizeof(EditRecord) + textLen); recPtr->type = type; recPtr->insertOffset = comboPtr->insertOffset; recPtr->offset = offset; recPtr->textLen = textLen; memcpy(recPtr->text, text, textLen); recPtr->nextPtr = comboPtr->undoPtr; comboPtr->undoPtr = recPtr; } static void CleanText(ComboEntry *comboPtr) { char *p, *q, *pend; if (comboPtr->screenText != NULL) { Blt_Free(comboPtr->screenText); } comboPtr->screenText = Blt_AssertMalloc(comboPtr->textLen + 1); for (p = comboPtr->text, q = comboPtr->screenText, pend = p + comboPtr->textLen; p < pend; p++, q++) { if (comboPtr->flags & CIPHER) { *q = '*'; } else if ((*p == '\n') || (*p == '\t')) { *q = ' '; } else { *q = *p; } } } static void DeleteText(ComboEntry *comboPtr, int first, int last) { int nBytes; int i, j; nBytes = last - first; comboPtr->selFirst = comboPtr->selLast = -1; if (comboPtr->insertOffset >= first) { if (comboPtr->insertOffset >= last) { comboPtr->insertOffset -= nBytes; } else { comboPtr->insertOffset = first; } } for (i = first, j = last; j < comboPtr->textLen; i++, j++) { comboPtr->text[i] = comboPtr->text[j]; } comboPtr->text[i] = '\0'; comboPtr->textLen -= nBytes; CleanText(comboPtr); if (comboPtr->textVarObjPtr != NULL) { UpdateTextVariable(comboPtr->interp, comboPtr); } comboPtr->selFirst = comboPtr->selLast = -1; comboPtr->flags |= (MODIFIED | LAYOUT_PENDING | SCROLL_PENDING); } static int InsertText(ComboEntry *comboPtr, int offset, int nBytes, const char *insertText) { char *text; /* Create a larger buffer to hold the text. */ text = Blt_Malloc(comboPtr->textLen + nBytes); if (text == NULL) { return TCL_ERROR; } /* Copy the old + extra to the new text. */ memcpy(text, comboPtr->text, offset); memcpy(text + offset, insertText, nBytes); memcpy(text + offset + nBytes, comboPtr->text + offset, comboPtr->textLen - offset); comboPtr->textLen += nBytes; if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); } comboPtr->text = text; if (comboPtr->insertOffset >= offset) { comboPtr->insertOffset += nBytes; } comboPtr->selFirst = comboPtr->selLast = -1; CleanText(comboPtr); if (comboPtr->textVarObjPtr != NULL) { UpdateTextVariable(comboPtr->interp, comboPtr); } comboPtr->flags |= (MODIFIED | LAYOUT_PENDING | SCROLL_PENDING); return TCL_OK; } /* *--------------------------------------------------------------------------- * H * C * L * P * max of icon/text/image/arrow * P * L * C * H * * |H|C|L|P| icon |P| text/image |P|L|B| arrow |B|C|H| * * H = highlight thickness * C = comboentry borderwidth * L = label borderwidth * P = pad * I = icon * T = text or image *--------------------------------------------------------------------------- */ static void ComputeGeometry(ComboEntry *comboPtr) { Button *butPtr = &comboPtr->closeButton; /* Determine the height of the entry. It's the maximum height of all it's * components: icon, label, close button, and arrow. */ comboPtr->iconWidth = comboPtr->iconHeight = 0; comboPtr->entryWidth = comboPtr->entryHeight = 0; comboPtr->textWidth = comboPtr->textHeight = 0; comboPtr->arrowWidth = comboPtr->arrowHeight = 0; butPtr->width = butPtr->height = 0; comboPtr->inset = comboPtr->borderWidth + comboPtr->highlightWidth; comboPtr->width = 2 * comboPtr->inset + IPAD; comboPtr->height = 2 * comboPtr->inset; if (comboPtr->icon != NULL) { comboPtr->iconWidth = IconWidth(comboPtr->icon) + IPAD; comboPtr->iconHeight = IconHeight(comboPtr->icon) + 2 * YPAD; } if (comboPtr->prefIconWidth > 0) { comboPtr->iconWidth = comboPtr->prefIconWidth + IPAD; } comboPtr->entryWidth += comboPtr->iconWidth; if (comboPtr->entryHeight < comboPtr->iconHeight) { comboPtr->entryHeight = comboPtr->iconHeight; } if (comboPtr->image != NULL) { comboPtr->textWidth = IconWidth(comboPtr->image) + IPAD; comboPtr->textHeight = IconHeight(comboPtr->image) + YPAD * 2; } else { unsigned int w, h; CleanText(comboPtr); if (comboPtr->textLen == 0) { Blt_GetTextExtents(comboPtr->font, 0, "0", 1, &w, &h); } else { Blt_GetTextExtents(comboPtr->font, 0, comboPtr->screenText, comboPtr->textLen, &w, &h); } comboPtr->textWidth = w; comboPtr->textHeight = h + 2 * YPAD; if (comboPtr->prefTextWidth > 0) { w = Blt_TextWidth(comboPtr->font, "0", 1); comboPtr->entryWidth += comboPtr->prefTextWidth * w; } else { comboPtr->entryWidth += comboPtr->textWidth; } comboPtr->entryWidth += IPAD; } if (comboPtr->entryHeight < comboPtr->textHeight) { comboPtr->entryHeight = comboPtr->textHeight; } comboPtr->width += comboPtr->entryWidth; comboPtr->height += comboPtr->entryHeight; if (comboPtr->flags & ARROW) { comboPtr->arrowHeight = ARROW_HEIGHT; if (comboPtr->reqArrowWidth > 0) { comboPtr->arrowWidth = comboPtr->reqArrowWidth; } else { comboPtr->arrowWidth = Blt_TextWidth(comboPtr->font, "0", 1); comboPtr->arrowWidth = comboPtr->arrowWidth + 4; } comboPtr->arrowWidth += 2 * (comboPtr->arrowBW + comboPtr->arrowPad); comboPtr->arrowHeight += 2 * comboPtr->arrowBW; if (comboPtr->arrowHeight > comboPtr->entryHeight) { comboPtr->height = comboPtr->entryHeight = comboPtr->arrowHeight; } comboPtr->arrowWidth |= 0x1; comboPtr->width += comboPtr->arrowWidth; } if (comboPtr->flags & CLOSE) { Button *butPtr = &comboPtr->closeButton; butPtr->height = CLOSE_HEIGHT; butPtr->width = CLOSE_WIDTH; butPtr->width += 2 * (butPtr->borderWidth + butPtr->pad); butPtr->height += 2 * (butPtr->borderWidth + butPtr->pad); if (butPtr->height > comboPtr->entryHeight) { comboPtr->height = comboPtr->entryHeight = butPtr->height; } comboPtr->width += butPtr->width; } { int w, h; w = (comboPtr->reqWidth > 0) ? comboPtr->reqWidth : comboPtr->width; h = (comboPtr->reqHeight > 0) ? comboPtr->reqHeight : comboPtr->height; if ((w != Tk_ReqWidth(comboPtr->tkwin)) || (h != Tk_ReqHeight(comboPtr->tkwin))) { Tk_GeometryRequest(comboPtr->tkwin, w, h); } } comboPtr->flags &= ~LAYOUT_PENDING; } static int UpdateIconVariable(Tcl_Interp *interp, ComboEntry *comboPtr) { Tcl_Obj *resultObjPtr, *objPtr; if (comboPtr->icon != NULL) { objPtr = Tcl_NewStringObj(IconName(comboPtr->icon), -1); } else { objPtr = Tcl_NewStringObj("", -1); } Tcl_IncrRefCount(objPtr); resultObjPtr = Tcl_ObjSetVar2(interp, comboPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); Tcl_DecrRefCount(objPtr); if (resultObjPtr == NULL) { return TCL_ERROR; } return TCL_OK; } static void FreeIcon(ComboEntry *comboPtr, Icon icon) { Tk_FreeImage(IconImage(icon)); Blt_Free(icon); } static char * GetInterpResult(Tcl_Interp *interp) { #define MAX_ERR_MSG 1023 static char mesg[MAX_ERR_MSG+1]; strncpy(mesg, Tcl_GetStringResult(interp), MAX_ERR_MSG); mesg[MAX_ERR_MSG] = '\0'; return mesg; } static void SetTextFromObj(ComboEntry *comboPtr, Tcl_Obj *objPtr) { int nBytes; char *string; if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); } string = Tcl_GetStringFromObj(objPtr, &nBytes); comboPtr->text = Blt_AssertMalloc(nBytes + 1); memcpy(comboPtr->text, string, nBytes); comboPtr->text[nBytes] = '\0'; comboPtr->textLen = nBytes; CleanText(comboPtr); comboPtr->flags |= (ICURSOR | SCROLL_PENDING | LAYOUT_PENDING); comboPtr->scrollX = 0; comboPtr->selFirst = comboPtr->selLast = -1; comboPtr->insertOffset = nBytes; } /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { ComboEntry *comboPtr = clientData; comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); } static int GetIconFromObj(Tcl_Interp *interp, ComboEntry *comboPtr, Tcl_Obj *objPtr, Icon *iconPtr) { Tk_Image tkImage; const char *iconName; iconName = Tcl_GetString(objPtr); if (iconName[0] == '\0') { *iconPtr = NULL; return TCL_OK; } tkImage = Tk_GetImage(interp, comboPtr->tkwin, iconName, IconChangedProc, comboPtr); if (tkImage != NULL) { struct Icon *ip; int width, height; ip = Blt_AssertMalloc(sizeof(struct Icon)); Tk_SizeOfImage(tkImage, &width, &height); ip->tkImage = tkImage; ip->width = width; ip->height = height; *iconPtr = ip; return TCL_OK; } return TCL_ERROR; } static void BlinkCursor(ComboEntry *comboPtr) { int time; if (comboPtr->flags & ICURSOR_ON) { comboPtr->flags &= ~ICURSOR_ON; time = comboPtr->insertOffTime; } else { comboPtr->flags |= ICURSOR_ON; time = comboPtr->insertOnTime; } comboPtr->insertTimerToken = Tcl_CreateTimerHandler(time, BlinkInsertCursorProc, comboPtr); } /* *--------------------------------------------------------------------------- * * BlinkInsertCursorProc -- * * This procedure is called as a timer handler to blink the insertion * cursor off and on. * * Results: * None. * * Side effects: * The cursor gets turned on or off, redisplay gets invoked, and this * procedure reschedules itself. * *--------------------------------------------------------------------------- */ static void BlinkInsertCursorProc(ClientData clientData) { ComboEntry *comboPtr = clientData; if (((comboPtr->flags & FOCUS) == 0)||(comboPtr->insertOffTime == 0)) { return; } if (comboPtr->flags & ICURSOR) { BlinkCursor(comboPtr); EventuallyRedraw(comboPtr); } } /* *--------------------------------------------------------------------------- * * ComboEntryEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * comboentry widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ComboEntryEventProc(ClientData clientData, XEvent *eventPtr) { ComboEntry *comboPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(comboPtr); } } else if (eventPtr->type == ConfigureNotify) { comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { comboPtr->flags |= FOCUS; } else { comboPtr->flags &= ~FOCUS; } if (comboPtr->insertTimerToken != NULL) { Tcl_DeleteTimerHandler(comboPtr->insertTimerToken); comboPtr->insertTimerToken = NULL; } if ((comboPtr->flags & (FOCUS|ICURSOR|READONLY))==(FOCUS|ICURSOR)) { if (comboPtr->flags & ICURSOR_ON) { comboPtr->flags &= ~ICURSOR_ON; } else { comboPtr->flags |= ICURSOR_ON; } if (comboPtr->insertOffTime != 0) { BlinkCursor(comboPtr); } } EventuallyRedraw(comboPtr); } else if (eventPtr->type == DestroyNotify) { if (comboPtr->tkwin != NULL) { comboPtr->tkwin = NULL; } if (comboPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayComboEntry, comboPtr); } if (comboPtr->flags & SELECT_PENDING) { Tcl_CancelIdleCall(ComboEntrySelectCmdProc, comboPtr); } if (comboPtr->flags & INVOKE_PENDING) { Tcl_CancelIdleCall(ComboEntryInvokeCmdProc, comboPtr); } if (comboPtr->insertTimerToken != NULL) { Tcl_DeleteTimerHandler(comboPtr->insertTimerToken); } Tcl_EventuallyFree(comboPtr, FreeComboEntryProc); } } /* *--------------------------------------------------------------------------- * * ComboEntryLostSelProc -- * * This procedure is called back by Tk when the selection is grabbed away * from the comboentry widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is marked as * not containing a selection. * *--------------------------------------------------------------------------- */ static void ComboEntryLostSelProc(ClientData clientData) { ComboEntry *comboPtr = clientData; if ((comboPtr->selFirst >= 0) && (comboPtr->flags & EXPORT_SELECTION)) { comboPtr->selFirst = comboPtr->selLast = -1; EventuallyRedraw(comboPtr); } } /* *--------------------------------------------------------------------------- * * ChildEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * sub-menus of comboentry widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ChildEventProc(ClientData clientData, XEvent *eventPtr) { ComboEntry *comboPtr = clientData; if ((eventPtr->type == UnmapNotify) || (eventPtr->type == DestroyNotify)) { comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= NORMAL; } else if (eventPtr->type == MapNotify) { comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= POSTED; } } /* *--------------------------------------------------------------------------- * * ComboEntryInvokeCmdProc -- * * Invoked at the next idle point whenever the current * selection changes. Executes some application-specific code * in the -selectcommand option. This provides a way for * applications to handle selection changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void ComboEntryInvokeCmdProc(ClientData clientData) { ComboEntry *comboPtr = clientData; comboPtr->flags &= ~INVOKE_PENDING; if (comboPtr->cmdObjPtr != NULL) { if (InvokeCommand(comboPtr->interp, comboPtr) != TCL_OK) { Tcl_BackgroundError(comboPtr->interp); } } } /* *--------------------------------------------------------------------------- * * SelectText -- * * Modify the selection by moving its un-anchored end. This could make * the selection either larger or smaller. * * 1) If index is before the anchor point, sets the selection to the * characters from index up to but not including the anchor point. * 2) If index is the same as the anchor point, does nothing. * 3) If index is after the anchor point, set the selection to the * characters from the anchor point up to but not including index. * The anchor point is determined by the most recent select from * or select adjust command in this widget. * 4) If the selection isn't in this widget then a new selection is * created using the most recent anchor point specified for the * widget. * * Results: * None. * * Side effects: * The widget is possibly redrawn with the new selection. * *--------------------------------------------------------------------------- */ static int SelectText(ComboEntry *comboPtr, int offset) { int selFirst, selLast; /* * Grab the selection if we don't own it already. */ if ((comboPtr->flags & EXPORT_SELECTION) && (comboPtr->selFirst == -1)) { Tk_OwnSelection(comboPtr->tkwin, XA_PRIMARY, ComboEntryLostSelProc, comboPtr); } /* If the anchor hasn't been set yet, assume the beginning of the text*/ if (comboPtr->selAnchor < 0) { comboPtr->selAnchor = 0; } if (comboPtr->selAnchor <= offset) { selFirst = comboPtr->selAnchor; selLast = offset; } else { selFirst = offset; selLast = comboPtr->selAnchor; } if (((comboPtr->selFirst != selFirst) || (comboPtr->selLast != selLast)) && (selFirst != selLast)) { comboPtr->selFirst = selFirst; comboPtr->selLast = selLast; EventuallyRedraw(comboPtr); if (comboPtr->selCmdObjPtr != NULL) { EventuallyInvokeSelectCmd(comboPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ComboEntrySelectCmdProc -- * * Invoked at the next idle point whenever the current * selection changes. Executes some application-specific code * in the -selectcommand option. This provides a way for * applications to handle selection changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void ComboEntrySelectCmdProc(ClientData clientData) { ComboEntry *comboPtr = clientData; if (comboPtr->selCmdObjPtr != NULL) { int result; comboPtr->flags &= ~SELECT_PENDING; Tcl_Preserve(comboPtr); Tcl_IncrRefCount(comboPtr->selCmdObjPtr); result = Tcl_EvalObjEx(comboPtr->interp, comboPtr->selCmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->selCmdObjPtr); Tcl_Release(comboPtr); if (result != TCL_OK) { Tcl_BackgroundError(comboPtr->interp); } } } /* *--------------------------------------------------------------------------- * * ComboEntrySelectionProc -- * * This procedure is called back by Tk when the selection is requested by * someone. It returns part or all of the selection in a buffer provided * by the caller. * * Results: * The return value is the number of non-NULL bytes stored at buffer. * Buffer is filled (or partially filled) with a NUL-terminated string * containing part or all of the selection, as given by offset and * maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ComboEntrySelectionProc( ClientData clientData, /* Information about the widget. */ int offset, /* Offset within the selection of the * first character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place at * buffer, not including terminating * NULL character. */ { ComboEntry *comboPtr = clientData; int size; size = 0; if (comboPtr->selFirst >= 0) { size = comboPtr->selLast - comboPtr->selFirst - offset; assert(size >= 0); if (size > maxBytes) { size = maxBytes; } memcpy(buffer, comboPtr->text + comboPtr->selFirst + offset, size); buffer[size] = '\0'; } return size; } /* *--------------------------------------------------------------------------- * * TextVarTraceProc -- * * This procedure is invoked when someone changes the state variable * associated with a comboentry entry. The entry's selected state is set * to match the value of the variable. * * Results: * NULL is always returned. * * Side effects: * The comboentry entry may become selected or deselected. * *--------------------------------------------------------------------------- */ static char * TextVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { ComboEntry *comboPtr = clientData; assert(comboPtr->textVarObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { if (flags & TCL_TRACE_DESTROYED) { Tcl_SetVar(interp, name1, comboPtr->text, TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, name1, TRACE_VAR_FLAGS, TextVarTraceProc, clientData); } return NULL; } if (comboPtr->flags & DISABLED) { return NULL; } if (flags & TCL_TRACE_WRITES) { Tcl_Obj *valueObjPtr; /* * Update the comboentry's text with the value of the variable, unless * the widget already has that value (this happens when the variable * changes value because we changed it because someone typed in the * entry). */ valueObjPtr = Tcl_ObjGetVar2(interp, comboPtr->textVarObjPtr, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (valueObjPtr == NULL) { return GetInterpResult(interp); } else { SetTextFromObj(comboPtr, valueObjPtr); if (comboPtr->cmdObjPtr != NULL) { EventuallyInvokeCmd(comboPtr); } } EventuallyRedraw(comboPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * IconVarTraceProc -- * * This procedure is invoked when someone changes the state variable * associated with a comboentry entry. The entry's selected state is set * to match the value of the variable. * * Results: * NULL is always returned. * * Side effects: * The comboentry entry may become selected or deselected. * *--------------------------------------------------------------------------- */ static char * IconVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { ComboEntry *comboPtr = clientData; assert(comboPtr->iconVarObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { if (flags & TCL_TRACE_DESTROYED) { Tcl_SetVar(interp, name1, IconName(comboPtr->icon),TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, name1, TRACE_VAR_FLAGS, IconVarTraceProc, clientData); } return NULL; } if (comboPtr->flags & DISABLED) { return NULL; } if (flags & TCL_TRACE_WRITES) { Icon icon; Tcl_Obj *valueObjPtr; /* * Update the comboentry's icon with the image whose name is * stored in the variable. */ valueObjPtr = Tcl_ObjGetVar2(interp, comboPtr->iconVarObjPtr, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (valueObjPtr == NULL) { return GetInterpResult(interp); } if (GetIconFromObj(interp, comboPtr, valueObjPtr, &icon) != TCL_OK) { return GetInterpResult(interp); } if (comboPtr->icon != NULL) { FreeIcon(comboPtr, comboPtr->icon); } comboPtr->icon = icon; comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } return NULL; } /*ARGSUSED*/ static void FreeIconVarProc(ClientData clientData, Display *display, char *widgRec, int offset) { Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); if (*objPtrPtr != NULL) { ComboEntry *comboPtr = (ComboEntry *)widgRec; Tcl_UntraceVar(comboPtr->interp, Tcl_GetString(*objPtrPtr), TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToIconVarProc -- * * Convert the variable to a traced variable. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); char *varName; Tcl_Obj *valueObjPtr; /* Remove the current trace on the variable. */ if (*objPtrPtr != NULL) { Tcl_UntraceVar(interp, Tcl_GetString(*objPtrPtr), TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } valueObjPtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_GLOBAL_ONLY); if (valueObjPtr != NULL) { Icon icon; if (GetIconFromObj(interp, comboPtr, valueObjPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (comboPtr->icon != NULL) { FreeIcon(comboPtr, comboPtr->icon); } comboPtr->icon = icon; } *objPtrPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconVarToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *objPtr = *(Tcl_Obj **)(widgRec + offset); if (objPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /*ARGSUSED*/ static void FreeTextVarProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); if (*objPtrPtr != NULL) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); const char *varName; varName = Tcl_GetString(*objPtrPtr); Tcl_UntraceVar(comboPtr->interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToTextVarProc -- * * Convert the variable to a traced variable. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTextVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); const char *varName; Tcl_Obj *valueObjPtr; /* Remove the current trace on the variable. */ if (*objPtrPtr != NULL) { varName = Tcl_GetString(*objPtrPtr); Tcl_UntraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } valueObjPtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_GLOBAL_ONLY); if (valueObjPtr != NULL) { SetTextFromObj(comboPtr, valueObjPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVariable(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } } *objPtrPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); comboPtr->flags |= MODIFIED; return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextVarToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TextVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *objPtr = *(Tcl_Obj **)(widgRec + offset); if (objPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Converts the string represents an entry state into a bitflag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "normal") == 0) { flag = NORMAL; } else if (strcmp(string, "posted") == 0) { flag = POSTED; } else if (strcmp(string, "disabled") == 0) { flag = DISABLED; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, normal, or posted.", (char *)NULL); return TCL_ERROR; } if (comboPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } *flagsPtr &= ~STATE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); const char *string; if (state & NORMAL) { string = "normal"; } else if (state & DISABLED) { string = "disabled"; } else if (state & POSTED) { string = "posted"; } else { string = "???"; } return Tcl_NewStringObj(string, -1); } /*ARGSUSED*/ static void FreeIconProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Icon icon = *(Icon *)(widgRec + offset); if (icon != NULL) { ComboEntry *comboPtr = (ComboEntry *)widgRec; FreeIcon(comboPtr, icon); } } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Convert a image into a hashed icon. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)widgRec; Icon *iconPtr = (Icon *)(widgRec + offset); Icon icon; if (GetIconFromObj(interp, comboPtr, objPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (*iconPtr != NULL) { FreeIcon(comboPtr, *iconPtr); } *iconPtr = icon; if (comboPtr->iconVarObjPtr != NULL) { if (UpdateIconVariable(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon icon = *(Icon *)(widgRec + offset); Tcl_Obj *objPtr; if (icon == NULL) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr =Tcl_NewStringObj(Blt_Image_Name(IconImage(icon)), -1); } return objPtr; } /*ARGSUSED*/ static void FreeTextProc(ClientData clientData, Display *display, char *widgRec, int offset) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); comboPtr->text = emptyString; comboPtr->textLen = 0; } } /* *--------------------------------------------------------------------------- * * ObjToTextProc -- * * Save the text and add the item to the text hashtable. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTextProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); comboPtr->text = emptyString; comboPtr->textLen = 0; } SetTextFromObj(comboPtr, objPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVariable(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= MODIFIED; return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextToObjProc -- * * Returns the current text of the entry. * * Results: * The text is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TextToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { ComboEntry *comboPtr = (ComboEntry *)(widgRec); return Tcl_NewStringObj(comboPtr->text, comboPtr->textLen); } static int PrevUtfOffset(const char *string) { int i; for (i = 1; i <= TCL_UTF_MAX; i++) { unsigned char byte; string--; byte = *(unsigned char *)string; if (byte < 0x80) { break; } if (byte >= 0xC0) { return i; } } return i; } /* *--------------------------------------------------------------------------- * * GetTextOffset -- * * Converts a string representing a item index into an item pointer. * The index may be in one of the following forms: * * number Specifies the character as a numerical index, * where 0 corresponds to the first character in * the string. * "anchor" Indicates the anchor point for the selection, * which is set with the select from and select * adjust widget commands. * "end" Indicates the character just after the last one * in the entry's string. This is equivalent to * specifying a numerical index equal to the length * of the entry's string. * "insert" Indicates the character adjacent to and immediately * following the insertion cursor. * "sel.first" Indicates the first character in the selection. * It is an error to use this form if the selection * isn't in the entry window. * "sel.last" Indicates the character just after the last one * in the selection. It is an error to use this form * if the selection isn't in the entry window. * @x X-coordinate in the entry's window; the character * spanning that x-coordinate is used. For example, * "@0" indicates the left-most character in the window. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via itemPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetTextOffset(Tcl_Interp *interp, ComboEntry *comboPtr, Tcl_Obj *objPtr, int *offsetPtr) { char *string; char c; int nChars, offset; if (Tcl_GetIntFromObj((Tcl_Interp *)NULL, objPtr, &nChars) == TCL_OK) { int nBytes, maxChars; /* Convert the character index into a byte offset. */ if (comboPtr->text == NULL) { *offsetPtr = 0; return TCL_OK; } nBytes = comboPtr->textLen; maxChars = Tcl_NumUtfChars(comboPtr->text, comboPtr->textLen); if (nChars < 0) { nBytes = 0; } else if (nChars <= maxChars) { nBytes = Tcl_UtfAtIndex(comboPtr->text, nChars) - comboPtr->text; } *offsetPtr = nBytes; return TCL_OK; } string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'a') && (strcmp(string, "anchor") == 0)) { if (comboPtr->selAnchor < 0) { Tcl_AppendResult(interp, "bad index \"", string, "\": no selection present.", (char *)NULL); return TCL_ERROR; } *offsetPtr = comboPtr->selAnchor; } else if ((c == 'e') && (strcmp(string, "end") == 0)) { *offsetPtr = comboPtr->textLen; } else if ((c == 'i') && (strcmp(string, "insert") == 0)) { *offsetPtr = comboPtr->insertOffset; } else if ((c == 'n') && (strcmp(string, "next") == 0)) { offset = comboPtr->insertOffset; if (offset < comboPtr->textLen) { Tcl_UniChar dummy; int nBytes; nBytes = Tcl_UtfToUniChar(comboPtr->text + comboPtr->insertOffset, &dummy); offset = comboPtr->insertOffset + nBytes; } *offsetPtr = offset; } else if ((c == 'p') && (strcmp(string, "previous") == 0)) { offset = comboPtr->insertOffset; if (offset > 0) { int nBytes; nBytes = PrevUtfOffset(comboPtr->text + comboPtr->insertOffset); offset = comboPtr->insertOffset - nBytes; } *offsetPtr = offset; } else if ((c == 's') && (strcmp(string, "sel.first") == 0)) { *offsetPtr = (int)comboPtr->selFirst; } else if ((c == 's') && (strcmp(string, "sel.last") == 0)) { *offsetPtr = (int)comboPtr->selLast; } else if (c == '@') { int x, dummy; if (Tcl_GetInt(interp, string+1, &x) != TCL_OK) { return TCL_ERROR; } /* Convert screen position to character index */ x -= comboPtr->inset + comboPtr->iconWidth; x += comboPtr->scrollX; *offsetPtr = Blt_MeasureChars(comboPtr->font, comboPtr->screenText, comboPtr->textLen, x, TK_PARTIAL_OK|TK_AT_LEAST_ONE, &dummy); } else { Tcl_AppendResult(interp, "unknown index \"", string, "\"",(char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyButton -- * *--------------------------------------------------------------------------- */ static void DestroyButton(ComboEntry *comboPtr, Button *butPtr) { iconOption.clientData = comboPtr; Blt_FreeOptions(buttonSpecs, (char *)butPtr, comboPtr->display, 0); if (butPtr->activePicture != NULL) { Blt_FreePicture(butPtr->activePicture); } if (butPtr->normalPicture != NULL) { Blt_FreePicture(butPtr->normalPicture); } if (butPtr->painter != NULL) { Blt_FreePainter(butPtr->painter); } } /* *--------------------------------------------------------------------------- * * ConfigureButton -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for setPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureButton( Tcl_Interp *interp, /* Interpreter to report errors. */ ComboEntry *comboPtr, /* Information about widget; may or * may not already have values for * some fields. */ int objc, Tcl_Obj *const *objv, int flags) { Button *butPtr = &comboPtr->closeButton; iconOption.clientData = comboPtr; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, buttonSpecs, objc, objv, (char *)butPtr, flags) != TCL_OK) { return TCL_ERROR; } butPtr->width = butPtr->height = 0; if (comboPtr->flags & CLOSE) { butPtr->width = CLOSE_WIDTH + 2 * butPtr->borderWidth; butPtr->height = CLOSE_HEIGHT + 2 * butPtr->borderWidth; } EventuallyRedraw(comboPtr); return TCL_OK; } static int ConfigureComboEntry(Tcl_Interp *interp, ComboEntry *comboPtr, int objc, Tcl_Obj *const *objv, int flags) { unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, configSpecs, objc, objv, (char *)comboPtr, flags) != TCL_OK) { return TCL_ERROR; } /* Text in/out focus GCs. */ gcMask = GCForeground | GCFont; if (comboPtr->flags & DISABLED) { gcValues.foreground = comboPtr->disabledColor->pixel; } else { gcValues.foreground = comboPtr->textInFocusColor->pixel; } gcValues.font = Blt_FontId(comboPtr->font); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->textInFocusGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->textInFocusGC); } comboPtr->textInFocusGC = newGC; gcMask = GCForeground | GCFont; if (comboPtr->flags & DISABLED) { gcValues.foreground = comboPtr->disabledColor->pixel; } else { gcValues.foreground = comboPtr->textOutFocusColor->pixel; } gcValues.font = Blt_FontId(comboPtr->font); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->textOutFocusGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->textOutFocusGC); } comboPtr->textOutFocusGC = newGC; /* Selection foreground. */ gcMask = GCForeground | GCFont; gcValues.foreground = comboPtr->selFgColor->pixel; gcValues.font = Blt_FontId(comboPtr->font); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->selectGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->selectGC); } comboPtr->selectGC = newGC; /* Arrow. */ if (comboPtr->flags & ARROW) { gcMask = GCForeground; if (comboPtr->flags & ACTIVE_ARROW) { gcValues.foreground = comboPtr->activeColor->pixel; } else if (comboPtr->flags & NORMAL) { gcValues.foreground = comboPtr->normalColor->pixel; } else if (comboPtr->flags & DISABLED) { gcValues.foreground = comboPtr->disabledColor->pixel; } newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); } else { newGC = NULL; } /* Focus highlight GCs */ gcMask = GCForeground; gcValues.foreground = comboPtr->highlightColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->highlightGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightGC); } comboPtr->highlightGC = newGC; if (comboPtr->highlightBgColor != NULL) { gcMask = GCForeground; gcValues.foreground = comboPtr->highlightBgColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); } else { newGC = NULL; } if (comboPtr->highlightBgGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightBgGC); } comboPtr->highlightBgGC = newGC; /* Insert cursor. */ gcMask = GCForeground; gcValues.foreground = comboPtr->insertColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->insertGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->insertGC); } comboPtr->insertGC = newGC; ComputeGeometry(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activates * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb activate bool * *--------------------------------------------------------------------------- */ static int ActivateOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *string; unsigned int old; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Writing is currently disabled. */ } string = Tcl_GetString(objv[2]); old = (comboPtr->flags & ACTIVE_MASK); comboPtr->flags &= ~ACTIVE_MASK; if (strcmp(string, "close") == 0) { comboPtr->flags |= ACTIVE_CLOSE; } else if (strcmp(string, "arrow") == 0) { comboPtr->flags |= ACTIVE_ARROW; } if (old != (comboPtr->flags & ACTIVE_MASK)) { EventuallyRedraw(comboPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BboxOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb bentry option * *--------------------------------------------------------------------------- */ static int BboxOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ButtonCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonCgetOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)&comboPtr->closeButton, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ButtonConfigureOp -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set for comboPtr; old resources get freed, if there were any. The * widget is redisplayed. * * .ce button configure ?optio value? * *--------------------------------------------------------------------------- */ static int ButtonConfigureOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)&comboPtr->closeButton, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)&comboPtr->closeButton, objv[2], 0); } if (ConfigureButton(interp, comboPtr, objc - 3, objv + 3, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonInvokeOp -- * * This procedure is called to invoke a button command. * * .t button invoke * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonInvokeOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (comboPtr->closeButton.cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; int result; cmdObjPtr = Tcl_DuplicateObj(comboPtr->closeButton.cmdObjPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonOp -- * * This procedure handles tab operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec buttonOps[] = { {"cget", 2, ButtonCgetOp, 4, 4, "option",}, {"configure", 2, ButtonConfigureOp, 3, 0, "?option value?...",}, {"invoke", 1, ButtonInvokeOp, 3, 3, "",}, }; static int nButtonOps = sizeof(buttonOps) / sizeof(Blt_OpSpec); static int ButtonOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboEntryCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nButtonOps, buttonOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb cget option * *--------------------------------------------------------------------------- */ static int CgetOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * ClosestOp -- * * Returns the index of the edge closest to the given x-coordinate. * * Results: * A standard TCL result. If the argument does not represent a valid * index, then TCL_ERROR is returned and the interpreter result will * contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ClosestOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; int x; if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) { return TCL_ERROR; } /* Convert screen position to character index */ x -= comboPtr->inset; if (comboPtr->icon != NULL) { x -= comboPtr->iconWidth; } x += comboPtr->scrollX; if (x <= 0) { offset = 0; } else if (x >= comboPtr->textWidth) { offset = comboPtr->textLen; } else { int prev; int dummy, leftEdge, rightEdge, mid; offset = Blt_MeasureChars(comboPtr->font, comboPtr->screenText, comboPtr->textLen, x, TK_PARTIAL_OK|TK_AT_LEAST_ONE, &dummy); /* Get the previous character */ prev = offset - PrevUtfOffset(comboPtr->text + offset); /* Measure the two strings. */ rightEdge = Blt_TextWidth(comboPtr->font, comboPtr->screenText, offset); leftEdge = Blt_TextWidth(comboPtr->font, comboPtr->screenText, prev); mid = (rightEdge + leftEdge + 1) / 2; if (x <= mid) { offset = prev; } } Tcl_SetIntObj(Tcl_GetObjResult(interp), offset); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp( ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; iconOption.clientData = comboPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, (Tcl_Obj *)NULL, BLT_CONFIG_OBJV_ONLY); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } Tcl_Preserve(comboPtr); result = ConfigureComboEntry(interp, comboPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(comboPtr); if (result == TCL_ERROR) { return TCL_ERROR; } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes one of more characters in the label's text label. The range * of characters is specified by the range first/last. If no last * argument is provided, then only the single character is deleted. * * Tv\a * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb delete first ?last? * *--------------------------------------------------------------------------- */ static int DeleteOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int first, last; if (comboPtr->flags & (READONLY|DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[2], &first) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { if (GetTextOffset(interp, comboPtr, objv[3], &last) != TCL_OK) { return TCL_ERROR; } } else { last = first + 1; } if ((first == -1) || (last == -1)) { return TCL_OK; } /* Record the delete for futher redo/undos. */ RecordEdit(comboPtr, DELETE_OP, first, last - first, comboPtr->text+first); DeleteText(comboPtr, first, last); FreeRedoRecords(comboPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVariable(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= MODIFIED; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * Returns the current text string in the widget. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb bentry option * *--------------------------------------------------------------------------- */ static int GetOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(comboPtr->text, comboPtr->textLen); Tcl_SetObjResult(interp, objPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Returns the actual character index of the index supplied. This * converts text indices such as "end" to the number of UTF characters in * the text string. * * It's an error if the index refers to a non-present selection. Empty * text strings always return an index of 0. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb index index * *--------------------------------------------------------------------------- */ static int IndexOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset, nChars; if (GetTextOffset(interp, comboPtr, objv[2], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { nChars = -1; } else { /* Convert the Utf byte offset into an Unicode character index. */ nChars = Tcl_NumUtfChars(comboPtr->text, offset); } Tcl_SetIntObj(Tcl_GetObjResult(interp), nChars); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IcursorOp -- * * Sets the cursor to a new location. * * Results: * A standard TCL result. If the argument does not represent a valid * index, then TCL_ERROR is returned and the interpreter result will * contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IcursorOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[2], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } comboPtr->insertOffset = offset; comboPtr->flags |= ICURSOR; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IdentifyOp -- * * Returns the name of the element under the point given by x and y * (such as arrow1), or an empty string if the point does not lie * in any element of the comboentry. X and Y must be pixel * coordinates relative to the widget. * * Results: * A standard TCL result. If the argument does not represent a valid * index, then TCL_ERROR is returned and the interpreter result will * contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IdentifyOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y, width, height; int isRoot; char *string; isRoot = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } width = Tk_Width(comboPtr->tkwin); height = Tk_Height(comboPtr->tkwin); if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) { return TCL_OK; } if (comboPtr->flags & READONLY) { Tcl_SetObjResult(interp, Tcl_NewStringObj("arrow", 5)); return TCL_OK; } if (height > comboPtr->entryHeight) { y += (height - comboPtr->entryHeight) / 2; } if (comboPtr->icon) { int iconX; iconX = comboPtr->inset; if ((x >= iconX) && (x < (iconX + IconWidth(comboPtr->icon)))) { Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", 4)); return TCL_OK; } } if (comboPtr->flags & ARROW) { int arrowX; arrowX = Tk_Width(comboPtr->tkwin) - (comboPtr->inset + comboPtr->arrowWidth); if (arrowX < 0) { arrowX = comboPtr->inset; } if ((x >= arrowX) && (x < (arrowX + comboPtr->arrowWidth))) { Tcl_SetObjResult(interp, Tcl_NewStringObj("arrow", 5)); return TCL_OK; } } if (comboPtr->flags & CLOSE) { Button *butPtr = &comboPtr->closeButton; if ((x >= butPtr->x) && (x < (butPtr->x + butPtr->width)) && (y >= butPtr->y) && (y < (butPtr->y + butPtr->height))) { Tcl_SetObjResult(interp, Tcl_NewStringObj("close", 5)); return TCL_OK; } } { int textX, textY; textX = comboPtr->inset; textY = y; if (comboPtr->iconWidth > 0) { textX += comboPtr->iconWidth; } textY += (comboPtr->entryHeight - comboPtr->textHeight) / 2; if ((x >= textX) && (x < (textX + comboPtr->textWidth))) { Tcl_SetObjResult(interp, Tcl_NewStringObj("text", 4)); return TCL_OK; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb invoke item * *--------------------------------------------------------------------------- */ static int InvokeOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Item is currently disabled. */ } result = TCL_OK; if (comboPtr->cmdObjPtr != NULL) { result = InvokeCommand(interp, comboPtr); } return result; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Inserts a new item into the comboentry at the given index. * * Results: * NULL is always returned. * * Side effects: * The comboentry gets a new item. * * .cb insert index string * *--------------------------------------------------------------------------- */ static int InsertOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; char *insertText; int nBytes; if (comboPtr->flags & (READONLY|DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[2], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } insertText = Tcl_GetStringFromObj(objv[3], &nBytes); /* Record the operation for future undo/redos. */ RecordEdit(comboPtr, INSERT_OP, offset, nBytes, insertText); if (InsertText(comboPtr, offset, nBytes, insertText) != TCL_OK) { return TCL_ERROR; } FreeRedoRecords(comboPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVariable(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= MODIFIED; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostOp -- * * Posts the menu associated with this widget. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .ce post * *--------------------------------------------------------------------------- */ static int PostOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *menuName; Tk_Window menuWin; if (comboPtr->flags & (POSTED|DISABLED)) { return TCL_OK; /* Entry's menu is currently posted or entry * is disabled. */ } if (comboPtr->menuObjPtr == NULL) { return TCL_OK; } menuName = Tcl_GetString(comboPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); comboPtr->menuWin = menuWin; if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "can't post \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (comboPtr->menuWin != NULL) { Tk_DeleteEventHandler(comboPtr->menuWin, CHILD_EVENT_MASK, ChildEventProc, comboPtr); } comboPtr->menuWin = menuWin; Tk_CreateEventHandler(menuWin, CHILD_EVENT_MASK, ChildEventProc, comboPtr); if (comboPtr->postCmdObjPtr) { int result; Tcl_Preserve(comboPtr); Tcl_IncrRefCount(comboPtr->postCmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->postCmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->postCmdObjPtr); Tcl_Release(comboPtr); if (result != TCL_OK) { return TCL_ERROR; } } { Tcl_Obj *cmd[5]; int result; int rootX, rootY; Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); cmd[0] = comboPtr->menuObjPtr; cmd[1] = Tcl_NewStringObj("post", 4); cmd[2] = Tcl_NewIntObj(rootX + Tk_Width(comboPtr->tkwin)); cmd[3] = Tcl_NewIntObj(rootY + Tk_Height(comboPtr->tkwin)); cmd[4] = Tcl_NewStringObj("right", 5); Tcl_Preserve(comboPtr); result = Blt_GlobalEvalObjv(interp, 5, cmd); Tcl_Release(comboPtr); if (result == TCL_OK) { comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= POSTED; } return result; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int oper; int x; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 { char *string; char c; int length; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } } if (objc == 3) { if (oper == SCAN_MARK) { Tcl_SetIntObj(Tcl_GetObjResult(interp), comboPtr->scanAnchor); } return TCL_OK; } if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (Blt_GetPixelsFromObj(interp, comboPtr->tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) { return TCL_ERROR; } if (oper == SCAN_MARK) { comboPtr->scanAnchor = x; comboPtr->scanX = comboPtr->scrollX; } else { int worldX, xMax; int dx; dx = comboPtr->scanAnchor - x; worldX = comboPtr->scanX + (10 * dx); xMax = comboPtr->viewWidth - ICWIDTH; if (worldX < 0) { worldX = 0; } else if ((worldX + xMax) >= comboPtr->textWidth) { worldX = comboPtr->textWidth; /* - (8 * xMax / 10); */ } comboPtr->scrollX = worldX; comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); } return TCL_OK; } static int SeeOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[2], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } if ((offset <= comboPtr->firstOffset) || (offset >= (comboPtr->lastOffset-1))) { int xMax, x; x = Blt_TextWidth(comboPtr->font, comboPtr->screenText, offset); xMax = comboPtr->viewWidth - ICWIDTH; if (x >= xMax) { x -= xMax; if (offset <= comboPtr->firstOffset) { x += 9 * xMax / 10; } else { x += 1 * xMax / 10; } } else { x = 0; } comboPtr->scrollX = x; } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionAdjustOp -- * * Locates the end of the selection nearest to the character given by * index, and adjusts that end of the selection to be at index * (i.e. including but not going beyond index). The other end of the * selection is made the anchor point for future select to commands. If * the selection isn't currently in the comboentry, then a new selection * is created to include the characters between index and the most recent * selection anchor point, inclusive. * * This procedure is called back by Tk when the selection is requested by * someone. It returns part or all of the selection in a buffer provided * by the caller. * * Results: * A standard TCL result. * * Side effects: * The widget is possibly redrawn with the new selection. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionAdjustOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; int half1, half2; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[3], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } half1 = (comboPtr->selFirst + comboPtr->selLast) / 2; half2 = (comboPtr->selFirst + comboPtr->selLast + 1) / 2; if (offset < half1) { comboPtr->selAnchor = comboPtr->selLast; } else if (offset > half2) { comboPtr->selAnchor = comboPtr->selFirst; } return SelectText(comboPtr, offset); } /* *--------------------------------------------------------------------------- * * SelectionClearOp -- * * Clears the selection. * * Results: * A standard TCL result. * * Side effects: * The widget is possibly redrawn. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionClearOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (comboPtr->selFirst != -1) { comboPtr->selFirst = comboPtr->selLast = -1; EventuallyRedraw(comboPtr); if (comboPtr->selCmdObjPtr != NULL) { EventuallyInvokeSelectCmd(comboPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionFromOp -- * * Sets the selection anchor point to just before the character * designated by the given index. Doesn't change the selection, just * resets the anchor of the existing selection. Returns an empty string. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionFromOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[3], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } comboPtr->selAnchor = offset; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionPresentOp -- * * Indicates if there are characters selected in the comboentry. * * Results: * Returns in the interpreter result, 1 if there is are characters * selected, 0 if nothing is selected. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionPresentOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (comboPtr->selFirst != -1)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionRangeOp -- * * Sets the selection to include the characters starting with the one * indexed by start and ending with the one just before end. If end * refers to the same character as start or an earlier one, then the * entry's selection is cleared. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionRangeOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int selFirst, selLast; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[3], &selFirst) != TCL_OK) { return TCL_ERROR; } if (GetTextOffset(interp, comboPtr, objv[4], &selLast) != TCL_OK) { return TCL_ERROR; } if ((selFirst == -1) || (selLast == -1)) { return TCL_OK; } comboPtr->selAnchor = selFirst; return SelectText(comboPtr, selLast); } /* *--------------------------------------------------------------------------- * * SelectionToOp -- * * Resets the selection depending upon the given new index. Returns an * empty string. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionToOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int offset; if (comboPtr->flags & DISABLED) { return TCL_OK; /* Widget is currently disabled. */ } if (GetTextOffset(interp, comboPtr, objv[3], &offset) != TCL_OK) { return TCL_ERROR; } if (offset == -1) { return TCL_OK; } return SelectText(comboPtr, offset); } static Blt_OpSpec selectionOps[] = { {"adjust", 1, SelectionAdjustOp, 4, 4, "index",}, {"clear", 1, SelectionClearOp, 3, 3, "",}, {"from", 1, SelectionFromOp, 4, 4, "index"}, {"present", 1, SelectionPresentOp, 3, 3, ""}, {"range", 1, SelectionRangeOp, 5, 5, "start end",}, {"to", 1, SelectionToOp, 4, 4, "index"}, }; static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * SelectionOp -- * * This procedure handles the individual options for text * selections. * *--------------------------------------------------------------------------- */ static int SelectionOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboEntryCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * RedoOp -- * * Inserts a new item into the comboentry at the given index. * * Results: * NULL is always returned. * * Side effects: * The comboentry gets a new item. * * .cb insert index string * *--------------------------------------------------------------------------- */ static int RedoOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (comboPtr->flags & (READONLY|DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } if (comboPtr->redoPtr != NULL) { EditRecord *recPtr; recPtr = comboPtr->redoPtr; if (recPtr->type == INSERT_OP) { InsertText(comboPtr, recPtr->offset, recPtr->textLen, recPtr->text); } else if (recPtr->type == DELETE_OP) { DeleteText(comboPtr, recPtr->offset, recPtr->offset + recPtr->textLen); } else { Tcl_AppendResult(interp, "unknown record type \"", Blt_Itoa(recPtr->type), "\"", (char *)NULL); return TCL_ERROR; } comboPtr->insertOffset = recPtr->insertOffset; comboPtr->redoPtr = recPtr->nextPtr; recPtr->nextPtr = comboPtr->undoPtr; comboPtr->undoPtr = recPtr; EventuallyRedraw(comboPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UndoOp -- * * Inserts a new item into the comboentry at the given index. * * Results: * NULL is always returned. * * Side effects: * The comboentry gets a new item. * * .cb insert index string * *--------------------------------------------------------------------------- */ static int UndoOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (comboPtr->flags & (READONLY|DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } if (comboPtr->undoPtr != NULL) { EditRecord *recPtr; recPtr = comboPtr->undoPtr; if (recPtr->type == INSERT_OP) { DeleteText(comboPtr, recPtr->offset, recPtr->offset + recPtr->textLen); } else if (recPtr->type == DELETE_OP) { InsertText(comboPtr, recPtr->offset, recPtr->textLen, recPtr->text); } else { Tcl_AppendResult(interp, "unknown record type \"", Blt_Itoa(recPtr->type), "\"", (char *)NULL); return TCL_ERROR; } comboPtr->insertOffset = recPtr->insertOffset; comboPtr->undoPtr = recPtr->nextPtr; recPtr->nextPtr = comboPtr->redoPtr; comboPtr->redoPtr = recPtr; EventuallyRedraw(comboPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnpostOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .ce unpost * *--------------------------------------------------------------------------- */ static int UnpostOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if ((comboPtr->menuObjPtr != NULL) && ((comboPtr->flags & (POSTED|DISABLED)) == POSTED)) { char *menuName; Tk_Window menuWin; comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= NORMAL; menuName = Tcl_GetString(comboPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "can't unpost \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); return TCL_ERROR; } Blt_UnmapToplevelWindow(menuWin); if (Tk_IsMapped(menuWin)) { Tk_UnmapWindow(menuWin); } } return TCL_OK; } static int XviewOp(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width; if (comboPtr->flags & (DISABLED|READONLY)) { return TCL_OK; /* Widget is currently disabled. */ } width = comboPtr->viewWidth; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)comboPtr->scrollX / comboPtr->textWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); fract = (double)(comboPtr->scrollX + width) / comboPtr->textWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &comboPtr->scrollX, comboPtr->textWidth, width, comboPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreeComboEntryProc -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void FreeComboEntryProc(DestroyData dataPtr) /* Pointer to the widget record. */ { ComboEntry *comboPtr = (ComboEntry *)dataPtr; iconOption.clientData = comboPtr; Blt_FreeOptions(configSpecs, (char *)comboPtr, comboPtr->display, 0); if (comboPtr->textInFocusGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->textInFocusGC); } if (comboPtr->textOutFocusGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->textOutFocusGC); } FreeUndoRecords(comboPtr); FreeRedoRecords(comboPtr); DestroyButton(comboPtr, &comboPtr->closeButton); if (comboPtr->screenText != NULL) { Blt_Free(comboPtr->screenText); } if (comboPtr->selectGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->selectGC); } if (comboPtr->highlightGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightGC); } if (comboPtr->highlightBgGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightBgGC); } if (comboPtr->insertGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->insertGC); } if (comboPtr->insertTimerToken != NULL) { Tcl_DeleteTimerHandler(comboPtr->insertTimerToken); } if (comboPtr->tkwin != NULL) { Tk_DeleteSelHandler(comboPtr->tkwin, XA_PRIMARY, XA_STRING); Tk_DeleteEventHandler(comboPtr->tkwin, EVENT_MASK, ComboEntryEventProc, comboPtr); } if (comboPtr->insertTimerToken != NULL) { Tcl_DeleteTimerHandler(comboPtr->insertTimerToken); } Tcl_DeleteCommandFromToken(comboPtr->interp, comboPtr->cmdToken); Blt_Free(comboPtr); } /* *--------------------------------------------------------------------------- * * NewComboEntry -- * *--------------------------------------------------------------------------- */ static ComboEntry * NewComboEntry(Tcl_Interp *interp, Tk_Window tkwin) { ComboEntry *comboPtr; comboPtr = Blt_AssertCalloc(1, sizeof(ComboEntry)); comboPtr->borderWidth = 2; comboPtr->arrowBW = 2; comboPtr->arrowRelief = TK_RELIEF_RAISED; comboPtr->display = Tk_Display(tkwin); comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | NORMAL | ARROW | EXPORT_SELECTION); comboPtr->highlightWidth = 2; comboPtr->insertOffTime = 300; comboPtr->insertOffset = 0; comboPtr->insertOnTime = 600; comboPtr->interp = interp; comboPtr->menuAnchor = TK_ANCHOR_SW; comboPtr->relief = TK_RELIEF_SUNKEN; comboPtr->scrollUnits = 2; comboPtr->selAnchor = -1; comboPtr->selFirst = -1; comboPtr->selLast = -1; comboPtr->text = emptyString; comboPtr->textLen = 0; comboPtr->tkwin = tkwin; return comboPtr; } /* *--------------------------------------------------------------------------- * * ComboEntryCmd -- * * This procedure is invoked to process the "comboentry" command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec comboEntryOps[] = { {"activate", 1, ActivateOp, 3, 3, "what",}, {"bbox", 1, BboxOp, 3, 3, "index",}, {"button", 2, ButtonOp, 2, 0, "args",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"closest", 2, ClosestOp, 3, 3, "x",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"delete", 1, DeleteOp, 2, 0, "first ?last?",}, {"get", 1, GetOp, 2, 2, "",}, {"icursor", 2, IcursorOp, 3, 3, "index",}, {"identify", 2, IdentifyOp, 4, 5, "x y",}, {"index", 3, IndexOp, 3, 3, "index",}, {"insert", 3, InsertOp, 3, 0, "index string",}, {"invoke", 3, InvokeOp, 2, 2, "",}, {"post", 1, PostOp, 2, 2, "",}, {"redo", 2, RedoOp, 2, 2, "",}, {"scan", 2, ScanOp, 3, 4, "dragto|mark x",}, {"see", 3, SeeOp, 3, 3, "index",}, {"selection", 3, SelectionOp, 2, 0, "args",}, {"undo", 3, UndoOp, 2, 2, "",}, {"unpost", 3, UnpostOp, 2, 2, "",}, #ifdef notdef {"validate", 1, ValidateOp, 3, 3, "item",}, #endif {"xview", 1, XviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nComboEntryOps = sizeof(comboEntryOps) / sizeof(Blt_OpSpec); typedef int (ComboInstOp)(ComboEntry *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int ComboEntryInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { ComboInstOp *proc; ComboEntry *comboPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nComboEntryOps, comboEntryOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(comboPtr); result = (*proc) (comboPtr, interp, objc, objv); Tcl_Release(comboPtr); return result; } /* *--------------------------------------------------------------------------- * * ComboEntryInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ComboEntryInstCmdDeletedProc(ClientData clientData) { ComboEntry *comboPtr = clientData; /* Pointer to widget record. */ if (comboPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = comboPtr->tkwin; comboPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ComboEntryCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ComboEntryCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { ComboEntry *comboPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, set up procs and initialize various * bindings for the widget. If the proc doesn't already exist, source it * from "$blt_library/comboentry.tcl". We've deferred sourcing this file * until now so that the user could reset the variable $blt_library from * within her script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ComboEntry::PostMenu", &cmdInfo)) { static char cmd[] = "source [file join $blt_library comboentry.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } comboPtr = NewComboEntry(interp, tkwin); Tk_CreateEventHandler(tkwin, EVENT_MASK, ComboEntryEventProc, comboPtr); Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING, ComboEntrySelectionProc, comboPtr, XA_STRING); Tk_SetClass(tkwin, "ComboEntry"); comboPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ComboEntryInstCmdProc, comboPtr, ComboEntryInstCmdDeletedProc); Blt_SetWindowInstanceData(tkwin, comboPtr); if (ConfigureComboEntry(interp, comboPtr, objc-2, objv+2, 0) != TCL_OK) { Tk_DestroyWindow(comboPtr->tkwin); return TCL_ERROR; } if (ConfigureButton(interp, comboPtr, 0, NULL, 0) != TCL_OK) { Tk_DestroyWindow(comboPtr->tkwin); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_ComboEntryInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "comboentry", ComboEntryCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* *--------------------------------------------------------------------------- * * DrawEntry -- * * Draw the editable text associated with the entry. The widget may be * scrolled so the text may be clipped. We use a temporary pixmap to * draw the visible portion of the text. * * We assume that text strings will be small for the most part. The bad * part of this is that we measure the text string 5 times. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static void DrawEntry(ComboEntry *comboPtr, Drawable drawable, int x, int y, int w, int h) { Blt_FontMetrics fm; Pixmap pixmap; int insertX; int textX, textY; Blt_Background bg; GC gc; #define TEXT_FLAGS (TK_PARTIAL_OK | TK_AT_LEAST_ONE) if (comboPtr->textHeight <= 0) { return; } if (h > comboPtr->entryHeight) { h = comboPtr->entryHeight; } if (comboPtr->image != NULL) { int imgX, imgY, imgWidth, imgHeight; imgWidth = comboPtr->textWidth; if (comboPtr->scrollX < imgWidth) { imgX = comboPtr->scrollX; imgY = y; if (comboPtr->entryHeight > comboPtr->iconHeight) { imgY += (comboPtr->entryHeight - comboPtr->iconHeight) / 2; } imgWidth -= comboPtr->scrollX; if (imgWidth > w) { imgWidth = w; } imgHeight = MIN(h, comboPtr->iconHeight); Tk_RedrawImage(IconImage(comboPtr->image), imgX, 0, imgWidth, imgHeight, drawable, x, y); } return; } Blt_GetFontMetrics(comboPtr->font, &fm); textY = fm.ascent; if (comboPtr->entryHeight > comboPtr->textHeight) { textY += (comboPtr->entryHeight - comboPtr->textHeight) / 2; } #ifdef WIN32 assert(drawable != None); #endif /* * Create a pixmap the size of visible text area. This will be used for * clipping the scrolled text string. */ pixmap = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); if ((comboPtr->flags & (FOCUS|READONLY)) == FOCUS) { bg = comboPtr->inFocusBg; gc = comboPtr->textInFocusGC; } else { bg = comboPtr->outFocusBg; gc = comboPtr->textOutFocusGC; } /* Text background. */ { int xOrigin, yOrigin; Blt_GetBackgroundOrigin(bg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(comboPtr->tkwin, bg, xOrigin+x, yOrigin+y); Blt_FillBackgroundRectangle(comboPtr->tkwin, pixmap, bg, 0, 0, w, h, 0, TK_RELIEF_FLAT); Blt_SetBackgroundOrigin(comboPtr->tkwin, bg, xOrigin, yOrigin); } if (comboPtr->flags & SCROLL_PENDING) { int firstX, textWidth; /* Find the range of visible characters in both bytes and pixels. */ comboPtr->firstOffset = comboPtr->lastOffset = Blt_MeasureChars(comboPtr->font, comboPtr->screenText, comboPtr->textLen, comboPtr->scrollX, 0, &firstX); comboPtr->lastOffset += Blt_MeasureChars(comboPtr->font, comboPtr->screenText + comboPtr->firstOffset, comboPtr->textLen - comboPtr->firstOffset, w, TEXT_FLAGS, &textWidth); if (comboPtr->lastOffset < comboPtr->textLen) { comboPtr->lastOffset++; } comboPtr->firstX = firstX; comboPtr->lastX = textWidth + firstX; } /* * The viewport starts somewhere over the first visible character, but not * necessarily at the start of the character. Subtract the viewport * offset from the start of the first character. This is zero or a * negative x-coordinate, indicating where start drawing the text so that * it's properly clipped by the temporary pixmap. */ textX = comboPtr->firstX - comboPtr->scrollX; insertX = -1; if (((comboPtr->flags & (FOCUS|ICURSOR_ON|DISABLED|READONLY)) == (FOCUS|ICURSOR_ON)) && (comboPtr->selFirst == -1) && (comboPtr->insertOffset >= comboPtr->firstOffset) && (comboPtr->insertOffset <= comboPtr->lastOffset)) { insertX = textX; if (comboPtr->insertOffset > comboPtr->firstOffset) { insertX += Blt_TextWidth(comboPtr->font, comboPtr->screenText + comboPtr->firstOffset, comboPtr->insertOffset - comboPtr->firstOffset); } if (insertX > (comboPtr->lastX - comboPtr->firstX)) { insertX = -1; } } /* * Text is drawn in (up to) three segments. * * 1) Any text before the start the selection. 2) The selected text * (drawn with a flat border) 3) Any text following the selection. * This step will draw the text string if there is no selection. */ /* Step 1. Draw any text preceding the selection that's still visible in * the viewport. */ if (comboPtr->selFirst >= comboPtr->firstOffset) { int nPixels, len, nBytes; int selFirst; selFirst = comboPtr->selFirst; if (selFirst > comboPtr->lastOffset) { selFirst = comboPtr->lastOffset; } len = selFirst - comboPtr->firstOffset; nBytes = Blt_MeasureChars(comboPtr->font, comboPtr->screenText + comboPtr->firstOffset, len, w, TEXT_FLAGS, &nPixels); Blt_DrawChars(Tk_Display(comboPtr->tkwin), pixmap, gc, comboPtr->font, Tk_Depth(comboPtr->tkwin), 0.0f, comboPtr->screenText + comboPtr->firstOffset, nBytes, textX, textY); textX += nPixels; } /* Step 2. Draw the selection itself, if it's visible in the * viewport. Otherwise step 1 drew as much as we need. */ if ((comboPtr->selFirst >= 0) && (comboPtr->selFirst <= comboPtr->lastOffset)) { Blt_Background bg; int nBytes, nPixels; int selFirst, selLast; /* The background of the selection rectangle is different depending * whether the widget has focus or not. */ bg = comboPtr->selectBg; selFirst = comboPtr->selFirst; if (selFirst < comboPtr->firstOffset) { selFirst = comboPtr->firstOffset; } selLast = comboPtr->selLast; if (selLast > comboPtr->lastOffset) { selLast = comboPtr->lastOffset; } nBytes = Blt_MeasureChars(comboPtr->font, comboPtr->screenText + selFirst, selLast - selFirst, w, TEXT_FLAGS, &nPixels); Blt_FillBackgroundRectangle(comboPtr->tkwin, pixmap, bg, textX, 0, nPixels, h, 0, TK_RELIEF_FLAT); Blt_DrawChars(Tk_Display(comboPtr->tkwin), pixmap, comboPtr->selectGC, comboPtr->font, Tk_Depth(comboPtr->tkwin), 0.0f, comboPtr->screenText + selFirst, nBytes, textX, textY); textX += nPixels; } /* Step 3. Draw any text following the selection that's visible * in the viewport. In the case of no selection, we draw * the entire text string. */ if (comboPtr->selLast < comboPtr->lastOffset) { int selLast; selLast = comboPtr->selLast; if (selLast < comboPtr->firstOffset) { selLast = comboPtr->firstOffset; } Blt_DrawChars(Tk_Display(comboPtr->tkwin), pixmap, gc, comboPtr->font, Tk_Depth(comboPtr->tkwin), 0.0f, comboPtr->screenText + selLast, comboPtr->lastOffset - selLast, textX, textY); } /* Draw the insertion cursor, if one is needed. */ if (insertX >= 0) { int y1, y2; y1 = 1; y2 = h - 2; XDrawLine(Tk_Display(comboPtr->tkwin), pixmap, comboPtr->insertGC, insertX, y1, insertX, y2); #ifdef notdef XDrawLine(Tk_Display(comboPtr->tkwin), pixmap, comboPtr->insertGC, insertX + 1, y1, insertX + 1, y2); #endif } XCopyArea(comboPtr->display, pixmap, drawable, gc, 0, 0, w, h, x, y); Tk_FreePixmap(comboPtr->display, pixmap); } static void DrawComboEntry(ComboEntry *comboPtr, Drawable drawable, int width, int height) { Blt_Background bg; int x, y, w, h, tx, ty; Button *butPtr = &comboPtr->closeButton; int closeButtonNeeded; /* Background (just inside of focus highlight ring). */ x = y = comboPtr->inset; w = width - (2 * comboPtr->inset); h = height - (2 * comboPtr->inset); if (comboPtr->flags & FOCUS) { bg = comboPtr->inFocusBg; } else { bg = comboPtr->outFocusBg; } Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, w, h, 0, TK_RELIEF_FLAT); /* Label: includes icon and text. */ if (comboPtr->flags & ARROW) { w -= comboPtr->arrowWidth; } closeButtonNeeded = ((comboPtr->flags & CLOSE) && (comboPtr->textLen > 0)); if (closeButtonNeeded) { w -= butPtr->width; } if (h > comboPtr->entryHeight) { y += (h - comboPtr->entryHeight) / 2; } /* Draw Icon. */ if (comboPtr->icon != NULL) { int ix, iy, iw, ih; ix = x + IPAD; iy = y + YPAD; iw = MIN(w, comboPtr->iconWidth); ih = MIN(h, comboPtr->iconHeight); if (comboPtr->iconHeight < comboPtr->entryHeight) { iy += (comboPtr->entryHeight - comboPtr->iconHeight) / 2; } if ((Blt_IsPicture(IconImage(comboPtr->icon))) && (comboPtr->flags & DISABLED)) { Blt_Picture picture; Blt_Painter painter; painter = Blt_GetPainter(comboPtr->tkwin, 1.0); picture = Blt_GetPictureFromPictureImage(comboPtr->interp, IconImage(comboPtr->icon)); picture = Blt_GreyscalePicture(picture); Blt_PaintPicture(painter, drawable, picture, 0, 0, iw, ih,ix,iy,0); Blt_FreePicture(picture); } else { Tk_RedrawImage(IconImage(comboPtr->icon), 0, 0, iw, ih, drawable, ix, iy); } x += comboPtr->iconWidth; w -= comboPtr->iconWidth; } tx = x + IPAD; ty = y + 1; if ((w > 0) && (h > 0)) { #ifdef notdef DrawEntry(comboPtr, drawable, x + IPAD, y + 1, w, h - 2); x += comboPtr->entryWidth; #endif } if (comboPtr->flags & DISABLED) { bg = comboPtr->disabledBg; } else if (comboPtr->flags & ACTIVE_ARROW) { bg = comboPtr->activeBg; } else { bg = comboPtr->normalBg; } /* Close button. */ if (closeButtonNeeded) { Button *butPtr = &comboPtr->closeButton; Blt_Picture picture; int bx; comboPtr->viewWidth -= butPtr->width + comboPtr->inset + 2 * (butPtr->borderWidth + butPtr->pad); bx = width - (comboPtr->inset + comboPtr->arrowWidth + butPtr->width); y = comboPtr->inset + comboPtr->arrowPad; if (bx < 0) { bx = comboPtr->inset; } butPtr->x = bx + butPtr->borderWidth + butPtr->pad; butPtr->y = y; x += butPtr->width; w -= 6; if (comboPtr->entryHeight > butPtr->height) { butPtr->y += (comboPtr->entryHeight - butPtr->height) / 2; } if (comboPtr->flags & ACTIVE_CLOSE) { if (butPtr->activePicture == NULL) { butPtr->activePicture = Blt_PaintDelete(CLOSE_WIDTH, CLOSE_HEIGHT, butPtr->activeBg, butPtr->activeFg); } picture = butPtr->activePicture; } else { if (butPtr->normalPicture == NULL) { butPtr->normalPicture = Blt_PaintDelete(CLOSE_WIDTH, CLOSE_HEIGHT, butPtr->normalBg, butPtr->normalFg); } picture = butPtr->normalPicture; } if (butPtr->painter == NULL) { butPtr->painter = Blt_GetPainter(comboPtr->tkwin, 1.0); } Blt_PaintPictureWithBlend(butPtr->painter, drawable, picture, 0, 0, butPtr->width, butPtr->height, butPtr->x, butPtr->y, 0, 1.0); } /* Arrow. */ if (comboPtr->flags & ARROW) { XColor *color; int bw, bh; x = width - comboPtr->inset - comboPtr->arrowWidth; y = comboPtr->inset; if (x < 0) { x = comboPtr->inset; } bw = comboPtr->arrowWidth - 2 * comboPtr->arrowPad; bh = h; x += comboPtr->arrowPad; Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, bw, bh, comboPtr->arrowBW, comboPtr->arrowRelief); if (comboPtr->flags & ACTIVE_ARROW) { color = comboPtr->activeColor; } else if (comboPtr->flags & DISABLED) { color = comboPtr->disabledColor; } else { color = comboPtr->normalColor; } x += comboPtr->arrowBW; y += comboPtr->arrowBW; bw -= 2 * comboPtr->arrowBW; bh -= 2 * comboPtr->arrowBW; Blt_DrawArrow(comboPtr->display, drawable, color, x, y, bw, bh, comboPtr->arrowBW, ARROW_DOWN); } comboPtr->viewWidth = w; if ((w > 0) && (h > 0)) { DrawEntry(comboPtr, drawable, tx, ty, w, h - 2); } /* Draw focus highlight ring. */ if (comboPtr->highlightWidth > 0) { GC gc; if ((comboPtr->flags & (FOCUS|READONLY)) == FOCUS) { gc = comboPtr->highlightGC; Tk_DrawFocusHighlight(comboPtr->tkwin, gc, comboPtr->highlightWidth, drawable); } else { Blt_DrawFocusBackground(comboPtr->tkwin, comboPtr->normalBg, comboPtr->highlightWidth, drawable); } } if ((comboPtr->relief != TK_RELIEF_FLAT) && (comboPtr->borderWidth > 0)) { Blt_DrawBackgroundRectangle(comboPtr->tkwin, drawable, comboPtr->normalBg, comboPtr->highlightWidth, comboPtr->highlightWidth, width - 2 * comboPtr->highlightWidth, height - 2 * comboPtr->highlightWidth, comboPtr->borderWidth, comboPtr->relief); } } /* *--------------------------------------------------------------------------- * * DisplayComboEntry -- * * This procedure is invoked to display a comboentry widget. * * Results: * None. * * Side effects: * Commands are output to X to display the comboentry. * *--------------------------------------------------------------------------- */ static void DisplayComboEntry(ClientData clientData) { ComboEntry *comboPtr = clientData; Pixmap drawable; int w, h; /* Window width and height. */ comboPtr->flags &= ~REDRAW_PENDING; if (comboPtr->tkwin == NULL) { return; /* Window destroyed (should not get here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayComboEntry(%s)\n", Tk_PathName(comboPtr->tkwin)); #endif w = Tk_Width(comboPtr->tkwin); h = Tk_Height(comboPtr->tkwin); if ((w <= 1) || (h <=1)) { /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (comboPtr->flags & LAYOUT_PENDING) { ComputeGeometry(comboPtr); comboPtr->flags |= SCROLL_PENDING; } if (!Tk_IsMapped(comboPtr->tkwin)) { /* The widget's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the comboentry's new layout. */ return; } /* * Create a pixmap the size of the window for double buffering. */ drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif DrawComboEntry(comboPtr, drawable, w, h); XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->textInFocusGC, 0, 0, w, h, 0, 0); Tk_FreePixmap(comboPtr->display, drawable); if (comboPtr->flags & SCROLL_PENDING) { if (comboPtr->scrollCmdObjPtr != NULL) { Blt_UpdateScrollbar(comboPtr->interp, comboPtr->scrollCmdObjPtr, comboPtr->scrollX, comboPtr->scrollX + comboPtr->viewWidth, comboPtr->textWidth); } comboPtr->flags &= ~SCROLL_PENDING; } if (comboPtr->flags & MODIFIED) { GenerateModifiedEvent(comboPtr); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/shared/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014267� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/shared/Makefile.in������������������������������������������������������������0000644�0001750�0001750�00000035501�11462120063�016345� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for shared version of BLT library # ------------------------------------------------------------------------ SO_SUFFIX = @SO_SUFFIX@ version = @BLT_MAJOR_VERSION@@BLT_MINOR_VERSION@ # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ CC = @CC@ CFLAGS = @CFLAGS@ DBG = @LIB_SUFFIX@ DEFINES = @DEFINES@ DEF_BLTINIT = -DBLT_LIBRARY=\"$(pkgdir)\" EXTRA_CFLAGS = @GCCFLAGS@ @SO_CFLAGS@ EXTRA_LIBS = @EXTRA_LIBS@ LDFLAGS = @LDFLAGS@ @LD_RUN_PATH@ LIB_PREFIX = @LIB_PREFIX@ SO_LD = @SO_LD@ SO_LD_FLAGS = @SO_LD_FLAGS@ @LD_RUN_PATH@ SO_STD_LIBS = @SO_LIBS@ SO_TCL_ONLY_LIBS = @SO_TCL_ONLY_LIBS@ STD_LIBS = @LIBS@ STUB_DEFINES = @TCL_STUB_DEFINES@ TCL_STUB_SPEC = @TCL_STUB_SPEC@ TK_STUB_SPEC = @TK_STUB_SPEC@ cyg_prefix = @LIB_PREFIX@ EXPAT_INC_SPEC = @EXPAT_INC_SPEC@ EXPAT_LIB_SPEC = @EXPAT_LIB_SPEC@ FT_INC_SPEC = @FT_INC_SPEC@ FT_LIB_SPEC = @FT_LIB_SPEC@ JPG_INC_SPEC = @JPG_INC_SPEC@ JPG_LIB_SPEC = @JPG_LIB_SPEC@ MYSQL_INC_SPEC = @MYSQL_INC_SPEC@ MYSQL_LIB_SPEC = @MYSQL_LIB_SPEC@ PNG_INC_SPEC = @PNG_INC_SPEC@ PNG_LIB_SPEC = @PNG_LIB_SPEC@ TCL_INC_SPEC = @TCL_INC_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TIF_INC_SPEC = @TIF_INC_SPEC@ TIF_LIB_SPEC = @TIF_LIB_SPEC@ TK_INC_SPEC = @TK_INC_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ X11_INC_SPEC = @X11_INC_SPEC@ X11_LIB_SPEC = @X11_LIB_SPEC@ XFT_INC_SPEC = @XFT_INC_SPEC@ XFT_LIB_SPEC = @XFT_LIB_SPEC@ XPM_INC_SPEC = @XPM_INC_SPEC@ XPM_LIB_SPEC = @XPM_LIB_SPEC@ prefix = @prefix@ exec_prefix = @exec_prefix@ libdir = @libdir@ bindir = $(exec_prefix)/bin srcdir = @srcdir@/.. instdirs = $(exec_prefix) $(libdir) pkgdir = @BLT_LIBRARY@ BLT_LIBS = $(TK_LIB_SPEC) \ $(TCL_LIB_SPEC) \ $(FT_LIB_SPEC) \ $(XFT_LIB_SPEC) \ $(X11_LIB_SPEC) \ $(EXTRA_LIBS) BLT_LITE_LIBS = $(TCL_LIB_SPEC) \ $(EXTRA_LIBS) # ------------------------------------------------------------------------ # Don't edit anything beyond this point # ------------------------------------------------------------------------ N_OBJS = bltTed.o V3_OBJS = bltTri.o bltGrMt.o TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o PICTURE_OBJS = bltPicture.o \ bltPictCmd.o \ bltPictDraw.o \ bltPictMmx.o TREEVIEW_OBJS = bltTreeView.o \ bltTvCmd.o \ bltTvCol.o \ bltTvEdit.o \ bltTvStyle.o TREE_OBJS = bltTree.o \ bltTreeCmd.o DATATABLE_OBJS = bltDataTable.o \ bltDtCmd.o BLT_LITE_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBase64.o \ bltBgexec.o \ bltChain.o \ bltCrc32.o \ bltCsv.o \ $(DATATABLE_OBJS) \ bltDebug.o \ bltHash.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltSink.o \ bltSpline.o \ bltSwitch.o \ $(TREE_OBJS) \ bltUnixPipe.o \ bltUtil.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltWatch.o BLT_OBJS = $(BLT_LITE_OBJS) \ $(GRAPH_OBJS) \ $(PICTURE_OBJS) \ $(TREEVIEW_OBJS) \ bltBeep.o \ bltBgStyle.o \ bltBind.o \ bltBitmap.o \ bltBusy.o \ bltCanvEps.o \ bltComboBtn.o \ bltComboEntry.o \ bltComboMenu.o \ bltComboTree.o \ bltConfig.o \ bltContainer.o \ bltCutbuffer.o \ bltDragdrop.o \ bltHtext.o \ bltImage.o \ bltOldConfig.o \ bltPainter.o \ bltPs.o \ bltTable.o \ bltTabnotebook.o \ bltTabset.o \ bltText.o \ bltTile.o \ bltUnixBitmap.o \ bltUnixFont.o \ bltUnixDnd.o \ bltUnixPainter.o \ bltUnixWindow.o \ bltWindow.o \ bltWinop.o \ $(TK_OBJS) $(N_OBJS) INCLUDES = -I.. -I$(srcdir) -I$(srcdir)/.. @INCLUDES@ CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(STUB_DEFINES) $(INCLUDES) MAIN_CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_ROOT = SHELL = /bin/sh RM = rm -f LN_S = @LN_S@ bltwish = bltwish$(version) bltsh = bltsh$(version) lib_blt_so = $(LIB_PREFIX)BLT$(version)$(DBG)$(SO_SUFFIX) lib_blt_lite_so = $(LIB_PREFIX)BLTlite$(version)$(DBG)$(SO_SUFFIX) lib_blt_dt_xml_so = $(LIB_PREFIX)BltDataTableXml$(version)$(DBG)$(SO_SUFFIX) lib_blt_dt_mysql_so = $(LIB_PREFIX)BltDataTableMysql$(version)$(DBG)$(SO_SUFFIX) lib_blt_dt_tree_so = $(LIB_PREFIX)BltDataTableTree$(version)$(DBG)$(SO_SUFFIX) lib_blt_dt_vec_so = $(LIB_PREFIX)BltDataTableVector$(version)$(DBG)$(SO_SUFFIX) lib_blt_dt_csv_so = $(LIB_PREFIX)BltDataTableCsv$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_gif_so = $(LIB_PREFIX)BltPictureGif$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_jpg_so = $(LIB_PREFIX)BltPictureJpg$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_png_so = $(LIB_PREFIX)BltPicturePng$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_tif_so = $(LIB_PREFIX)BltPictureTif$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_xbm_so = $(LIB_PREFIX)BltPictureXbm$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_xpm_so = $(LIB_PREFIX)BltPictureXpm$(version)$(DBG)$(SO_SUFFIX) lib_blt_pict_photo_so = $(LIB_PREFIX)BltPicturePhoto$(version)$(DBG)$(SO_SUFFIX) lib_blt_tree_xml_so = $(LIB_PREFIX)BltTreeXml$(version)$(DBG)$(SO_SUFFIX) blt_libs_so = \ $(lib_blt_lite_so) \ $(lib_blt_so) \ $(blt_pkg_libs_so) blt_pkg_libs_so = \ $(lib_blt_dt_csv_so) \ $(lib_blt_dt_mysql_so) \ $(lib_blt_dt_tree_so) \ $(lib_blt_dt_vec_so) \ $(lib_blt_dt_xml_so) \ $(lib_blt_pict_gif_so) \ $(lib_blt_pict_jpg_so) \ $(lib_blt_pict_photo_so) \ $(lib_blt_pict_png_so) \ $(lib_blt_pict_tif_so) \ $(lib_blt_pict_xbm_so) \ $(lib_blt_pict_xpm_so) \ $(lib_blt_tree_xml_so) all: build_demo build_demo: $(blt_libs_so) $(bltsh) $(bltwish) $(bltwish): $(lib_blt_so) $(RM) $(bltwish) $(CC) $(MAIN_CC_OPTS) $(LDFLAGS) -o $(bltwish) $(srcdir)/bltUnixMain.c \ $(lib_blt_so) $(BLT_LIBS) $(bltsh): $(lib_blt_lite_so) $(RM) $(bltsh) $(CC) $(MAIN_CC_OPTS) $(LDFLAGS) -DTCL_ONLY -o $(bltsh) \ $(srcdir)/bltUnixMain.c $(lib_blt_lite_so) \ $(BLT_LITE_LIBS) build_lib: $(blt_libs_so) $(lib_blt_so): $(BLT_OBJS) $(srcdir)/bltInit.c $(CC) -c $(CC_OPTS) -DBLT_LIBRARY=\"$(pkgdir)\" \ $(srcdir)/bltInit.c $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltInit.o $(BLT_OBJS) $(BLT_LIBS) \ $(TK_STUB_SPEC) $(TCL_STUB_SPEC) $(lib_blt_lite_so): $(BLT_LITE_OBJS) $(srcdir)/bltInit.c $(CC) -c $(CC_OPTS) -DTCL_ONLY -DBLT_LIBRARY=\"$(pkgdir)\" \ $(srcdir)/bltInit.c $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltInit.o $(BLT_LITE_OBJS) \ $(BLT_LITE_LIBS) $(TCL_STUB_SPEC) $(lib_blt_dt_mysql_so): bltDtMysql.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtMysql.o $(MYSQL_LIB_SPEC) $(lib_blt_dt_xml_so): bltDtXml.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtXml.o $(EXPAT_LIB_SPEC) $(lib_blt_dt_csv_so): bltDtCsv.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtCsv.o $(lib_blt_dt_vec_so): bltDtVec.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtVec.o $(lib_blt_dt_tree_so): bltDtTree.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtTree.o $(lib_blt_pict_gif_so): bltPictGif.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictGif.o $(lib_blt_pict_jpg_so): bltPictJpg.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictJpg.o $(JPG_LIB_SPEC) $(lib_blt_pict_png_so): bltPictPng.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictPng.o $(PNG_LIB_SPEC) $(lib_blt_pict_tif_so): bltPictTif.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictTif.o $(TIF_LIB_SPEC) $(lib_blt_pict_xbm_so): bltPictXbm.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictXbm.o $(lib_blt_pict_xpm_so): bltPictXpm.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictXpm.o $(X11_LIB_SPEC) $(XPM_LIB_SPEC) $(lib_blt_pict_photo_so): bltPictPhoto.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictPhoto.o $(lib_blt_tree_xml_so): bltTreeXml.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltTreeXml.o $(EXPAT_LIB_SPEC) install: mkdirs install-libs install-demo install-demo: $(bltwish) $(bltsh) $(INSTALL) -m 0755 bltwish$(version) $(INSTALL_ROOT)$(bindir) $(INSTALL) -m 0755 bltsh$(version) $(INSTALL_ROOT)$(bindir) install-libs: $(lib_blt_so) $(lib_blt_lite_so) $(blt_pkg_libs_so) $(INSTALL) -m 0755 $(lib_blt_so) $(INSTALL_ROOT)$(libdir) $(INSTALL) -m 0755 $(lib_blt_lite_so) $(INSTALL_ROOT)$(libdir) @for i in $(blt_pkg_libs_so) ; do \ echo $(RM) $(INSTALL_ROOT)$(libdir)/$$i ; \ $(RM) $(INSTALL_ROOT)$(libdir)/$$i ; \ echo $(INSTALL) -m 0755 $$i $(INSTALL_ROOT)$(pkgdir) ; \ $(INSTALL) -m 0755 $$i $(INSTALL_ROOT)$(pkgdir) ; \ done mkdirs: @for i in $(instdirs) ; do \ if test -d $(INSTALL_ROOT)$$i ; then \ : ;\ else \ echo " mkdir $(INSTALL_ROOT)$$i" ; \ mkdir $(INSTALL_ROOT)$$i ; \ fi ; \ done clean: $(RM) $(BLT_OBJS) bltInit.o $(lib_blt_so) $(lib_blt_lite_so) \ $(bltsh) $(bltwish) *pure* .pure* distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile TAGS # ------------------------------------------------------------------------ # in lieu of viewpath-ing... # bltAlloc.o: $(srcdir)/bltAlloc.c $(CC) -c $(CC_OPTS) $? bltArrayObj.o: $(srcdir)/bltArrayObj.c $(CC) -c $(CC_OPTS) $? bltBase64.o: $(srcdir)/bltBase64.c $(CC) -c $(CC_OPTS) $? bltBeep.o: $(srcdir)/bltBeep.c $(CC) -c $(CC_OPTS) $? bltBgexec.o: $(srcdir)/bltBgexec.c $(CC) -c $(CC_OPTS) $? bltBind.o: $(srcdir)/bltBind.c $(CC) -c $(CC_OPTS) $? bltBitmap.o: $(srcdir)/bltBitmap.c $(CC) -c $(CC_OPTS) $? bltBusy.o: $(srcdir)/bltBusy.c $(CC) -c $(CC_OPTS) $? bltCanvEps.o: $(srcdir)/bltCanvEps.c $(CC) -c $(CC_OPTS) $? bltChain.o: $(srcdir)/bltChain.c $(CC) -c $(CC_OPTS) $? bltComboBtn.o: $(srcdir)/bltComboBtn.c $(CC) -c $(CC_OPTS) $? bltComboEntry.o: $(srcdir)/bltComboEntry.c $(CC) -c $(CC_OPTS) $? bltComboMenu.o: $(srcdir)/bltComboMenu.c $(CC) -c $(CC_OPTS) $? bltComboTree.o: $(srcdir)/bltComboTree.c $(CC) -c $(CC_OPTS) $? bltConfig.o: $(srcdir)/bltConfig.c $(CC) -c $(CC_OPTS) $? bltContainer.o: $(srcdir)/bltContainer.c $(CC) -c $(CC_OPTS) $? bltCrc32.o: $(srcdir)/bltCrc32.c $(CC) -c $(CC_OPTS) $? bltCsv.o: $(srcdir)/bltCsv.c $(CC) -c $(CC_OPTS) $? bltCutbuffer.o: $(srcdir)/bltCutbuffer.c $(CC) -c $(CC_OPTS) $? bltDebug.o: $(srcdir)/bltDebug.c $(CC) -c $(CC_OPTS) $? bltDragdrop.o: $(srcdir)/bltDragdrop.c $(CC) -c $(CC_OPTS) $? bltGrAxis.o: $(srcdir)/bltGrAxis.c $(CC) -c $(CC_OPTS) $? bltGrBar.o: $(srcdir)/bltGrBar.c $(CC) -c $(CC_OPTS) $? bltGrElem.o: $(srcdir)/bltGrElem.c $(CC) -c $(CC_OPTS) $? bltGrHairs.o: $(srcdir)/bltGrHairs.c $(CC) -c $(CC_OPTS) $? bltGrLegd.o: $(srcdir)/bltGrLegd.c $(CC) -c $(CC_OPTS) $? bltGrLine.o: $(srcdir)/bltGrLine.c $(CC) -c $(CC_OPTS) $? bltGrMisc.o: $(srcdir)/bltGrMisc.c $(CC) -c $(CC_OPTS) $? bltGrPen.o: $(srcdir)/bltGrPen.c $(CC) -c $(CC_OPTS) $? bltGrPs.o: $(srcdir)/bltGrPs.c $(CC) -c $(CC_OPTS) $? bltGrMarker.o: $(srcdir)/bltGrMarker.c $(CC) -c $(CC_OPTS) $? bltGraph.o: $(srcdir)/bltGraph.c $(CC) -c $(CC_OPTS) $? bltHash.o: $(srcdir)/bltHash.c $(CC) -c $(CC_OPTS) $? bltHtext.o: $(srcdir)/bltHtext.c $(CC) -c $(CC_OPTS) $? bltImage.o: $(srcdir)/bltImage.c $(CC) -c $(CC_OPTS) $(srcdir)/bltImage.c bltList.o: $(srcdir)/bltList.c $(CC) -c $(CC_OPTS) $? bltNsUtil.o: $(srcdir)/bltNsUtil.c $(CC) -c $(CC_OPTS) $? bltOldConfig.o: $(srcdir)/bltOldConfig.c $(CC) -c $(CC_OPTS) $? bltPicture.o: $(srcdir)/bltPicture.c $(CC) -c $(CC_OPTS) $(srcdir)/bltPicture.c bltPictCmd.o: $(srcdir)/bltPictCmd.c $(CC) -c $(CC_OPTS) $? bltPictDraw.o: $(srcdir)/bltPictDraw.c $(srcdir)/bltPaintDraw.c $(CC) -c $(CC_OPTS) $(FT_INC_SPEC) $< bltPictJpg.o: $(srcdir)/bltPictJpg.c $(CC) -c $(CC_OPTS) $(JPG_INC_SPEC) $? bltPictTif.o: $(srcdir)/bltPictTif.c $(CC) -c $(CC_OPTS) $(TIF_INC_SPEC) $? bltPictPng.o: $(srcdir)/bltPictPng.c $(CC) -c $(CC_OPTS) $(PNG_INC_SPEC) $? bltPictXpm.o: $(srcdir)/bltPictXpm.c $(CC) -c $(CC_OPTS) $(XPM_INC_SPEC) $? bltPictXbm.o: $(srcdir)/bltPictXbm.c $(CC) -c $(CC_OPTS) $? bltPictGif.o: $(srcdir)/bltPictGif.c $(CC) -c $(CC_OPTS) $? bltPictPhoto.o: $(srcdir)/bltPictPhoto.c $(CC) -c $(CC_OPTS) $? bltPictMmx.o: $(srcdir)/bltPictMmx.c $(CC) -c $(CC_OPTS) $(srcdir)/bltPictMmx.c bltPainter.o: $(srcdir)/bltPainter.c $(CC) -c $(CC_OPTS) $(srcdir)/bltPainter.c bltParse.o: $(srcdir)/bltParse.c $(CC) -c $(CC_OPTS) $? bltPool.o: $(srcdir)/bltPool.c $(CC) -c $(CC_OPTS) $? bltPs.o: $(srcdir)/bltPs.c $(CC) -c $(CC_OPTS) $? bltSink.o: $(srcdir)/bltSink.c $(CC) -c $(CC_OPTS) $? bltSpline.o: $(srcdir)/bltSpline.c $(CC) -c $(CC_OPTS) $? bltSwitch.o: $(srcdir)/bltSwitch.c $(CC) -c $(CC_OPTS) $? bltTable.o: $(srcdir)/bltTable.c $(CC) -c $(CC_OPTS) $? bltTabset.o: $(srcdir)/bltTabset.c $(CC) -c $(CC_OPTS) $? bltTabnotebook.o: $(srcdir)/bltTabnotebook.c $(CC) -c $(CC_OPTS) $? bltTed.o: $(srcdir)/bltTed.c $(CC) -c $(CC_OPTS) $? bltText.o: $(srcdir)/bltText.c $(CC) -c $(CC_OPTS) $? bltTile.o: $(srcdir)/bltTile.c $(CC) -c $(CC_OPTS) $? bltTree.o: $(srcdir)/bltTree.c $(CC) -c $(CC_OPTS) $? bltTreeCmd.o: $(srcdir)/bltTreeCmd.c $(CC) -c $(CC_OPTS) $? bltTreeXml.o: $(srcdir)/bltTreeXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTreeView.o: $(srcdir)/bltTreeView.c $(CC) -c $(CC_OPTS) $? bltTvCmd.o: $(srcdir)/bltTvCmd.c $(CC) -c $(CC_OPTS) $? bltTvCol.o: $(srcdir)/bltTvCol.c $(CC) -c $(CC_OPTS) $? bltTvEdit.o: $(srcdir)/bltTvEdit.c $(CC) -c $(CC_OPTS) $? bltTvStyle.o: $(srcdir)/bltTvStyle.c $(CC) -c $(CC_OPTS) $? bltDataTable.o: $(srcdir)/bltDataTable.c $(CC) -c $(CC_OPTS) $? bltDtCmd.o: $(srcdir)/bltDtCmd.c $(CC) -c $(CC_OPTS) $? bltDtCsv.o: $(srcdir)/bltDtCsv.c $(CC) -c $(CC_OPTS) $? bltDtMysql.o: $(srcdir)/bltDtMysql.c $(CC) -c $(CC_OPTS) $(MYSQL_INC_SPEC) $? bltDtTree.o: $(srcdir)/bltDtTree.c $(CC) -c $(CC_OPTS) $? bltDtVec.o: $(srcdir)/bltDtVec.c $(CC) -c $(CC_OPTS) $? bltDtXml.o: $(srcdir)/bltDtXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltUnixBitmap.o: $(srcdir)/bltUnixBitmap.c $(CC) -c $(CC_OPTS) $? bltUnixDnd.o: $(srcdir)/bltUnixDnd.c $(CC) -c $(CC_OPTS) $? bltUnixFont.o: $(srcdir)/bltUnixFont.c $(CC) -c $(CC_OPTS) $(FT_INC_SPEC) $? bltUnixPainter.o: $(srcdir)/bltUnixPainter.c $(CC) -c $(CC_OPTS) $? bltUnixPipe.o: $(srcdir)/bltUnixPipe.c $(CC) -c $(CC_OPTS) $? bltUnixWindow.o: $(srcdir)/bltUnixWindow.c $(CC) -c $(CC_OPTS) $? bltUtil.o: $(srcdir)/bltUtil.c $(CC) -c $(CC_OPTS) $? bltVector.o: $(srcdir)/bltVector.c $(CC) -c $(CC_OPTS) $? bltVecCmd.o: $(srcdir)/bltVecCmd.c $(CC) -c $(CC_OPTS) $? bltVecMath.o: $(srcdir)/bltVecMath.c $(CC) -c $(CC_OPTS) $? bltWatch.o: $(srcdir)/bltWatch.c $(CC) -c $(CC_OPTS) $? bltWindow.o: $(srcdir)/bltWindow.c $(CC) -c $(CC_OPTS) $? bltWinop.o: $(srcdir)/bltWinop.c $(CC) -c $(CC_OPTS) $? tkButton.o: $(srcdir)/tkButton.c $(CC) -c $(CC_OPTS) $? tkFrame.o: $(srcdir)/tkFrame.c $(CC) -c $(CC_OPTS) $? tkMenubutton.o: $(srcdir)/tkMenubutton.c $(CC) -c $(CC_OPTS) $? bltScrollbar.o: $(srcdir)/bltScrollbar.c $(CC) -c $(CC_OPTS) $? bltBgStyle.o: $(srcdir)/bltBgStyle.c $(CC) -c $(CC_OPTS) $? �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPool.c���������������������������������������������������������������������0000644�0001750�0001750�00000035612�11462120062�014613� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPool.c -- * * Copyright 2001-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltPool.h" /* * Blt_Pool -- * * Implements a pool memory allocator. * * + It's faster allocating memory since malloc/free are called * only a fraction of the normal times. Fixed size items can * be reused without deallocating/reallocating memory. * + You don't have the extra 8-16 byte overhead per malloc. * - Memory is freed only when the entire pool is destroyed. * - Memory is allocated in chunks. More memory is allocated * than used. * 0 Depending upon allocation/deallocation patterns, locality * may be improved or degraded. * * The pool is a chain of malloc'ed blocks. * * +---------+ +---------+ +---------+ * NULL<-| nextPtr |<-| nextPtr |<-| nextPtr |<- headPtr * |---------| |---------| |---------| * | chunk1 | | chunk2 | | chunk3 | * +---------+ | | | | * +---------+ | | * | | * | | * +---------+ * * Each chunk contains an integral number of fixed size items. * The number of items doubles until a maximum size is reached * (each subsequent new chunk will be the maximum). Chunks * are allocated only when needed (no more space is available * in the last chunk). * * The chain of blocks is only freed when the entire pool is * destroyed. * * A freelist of unused items also maintained. Each freed item * is prepended to a free list. Before allocating new chunks * the freelist is examined to see if any unused items exist. * * chunk1 chunk2 chunk3 * +---------+ +---------+ +---------+ * NULL<-| unused | | | | | * +----^----+ +---------+ +---------+ * | unused |<-| unused |<-| unused | * +---------+ +---------+ +----^----+ * | | | | | unused | * +---------+ | | +----^----+ * | | | | | * +---------+ +----|----+ * | usused |<- freePtr * +---------+ */ #define POOL_MAX_CHUNK_SIZE ((1<<16) - sizeof(PoolChain)) #ifndef ALIGN #define ALIGN(a) \ (((size_t)a + (sizeof(void *) - 1)) & (~(sizeof(void *) - 1))) #endif /* ALIGN */ typedef struct _PoolChain { struct _PoolChain *nextPtr; } PoolChain; typedef struct { Blt_PoolAllocProc *allocProc; Blt_PoolFreeProc *freeProc; PoolChain *headPtr; /* Chain of malloc'ed chunks. */ PoolChain *freePtr; /* List of deleted items. This is only used * for fixed size items. */ size_t poolSize; /* Log2 of # of items in the current block. */ size_t itemSize; /* Size of an item. */ size_t bytesLeft; /* # of bytes left in the current chunk. */ size_t waste; } Pool; static Blt_PoolAllocProc VariablePoolAllocItem; static Blt_PoolFreeProc VariablePoolFreeItem; static Blt_PoolAllocProc FixedPoolAllocItem; static Blt_PoolFreeProc FixedPoolFreeItem; static Blt_PoolAllocProc StringPoolAllocItem; static Blt_PoolFreeProc StringPoolFreeItem; /* *--------------------------------------------------------------------------- * * VariablePoolAllocItem -- * * Returns a new item. First check if there is any more space * left in the current chunk. If there isn't then next check * the free list for unused items. Finally allocate a new * chunk and return its first item. * * Results: * Returns a new (possible reused) item. * * Side Effects: * A new memory chunk may be allocated. * *--------------------------------------------------------------------------- */ static void * VariablePoolAllocItem( Blt_Pool pool, size_t size) /* Number of bytes to allocate. */ { Pool *poolPtr = (Pool *)pool; PoolChain *chainPtr; void *memory; size = ALIGN(size); if (size >= POOL_MAX_CHUNK_SIZE) { /* * Handle oversized requests by allocating a chunk to hold the * single item and immediately placing it into the in-use list. */ chainPtr = Blt_AssertMalloc(sizeof(PoolChain) + size); if (poolPtr->headPtr == NULL) { poolPtr->headPtr = chainPtr; } else { chainPtr->nextPtr = poolPtr->headPtr->nextPtr; poolPtr->headPtr->nextPtr = chainPtr; } memory = (void *)chainPtr; } else { if (poolPtr->bytesLeft >= size) { poolPtr->bytesLeft -= size; memory = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft; } else { poolPtr->waste += poolPtr->bytesLeft; /* Create a new block of items and prepend it to the in-use list */ poolPtr->bytesLeft = POOL_MAX_CHUNK_SIZE; /* Allocate the requested chunk size, plus the header */ chainPtr = Blt_AssertMalloc(sizeof(PoolChain) + poolPtr->bytesLeft); chainPtr->nextPtr = poolPtr->headPtr; poolPtr->headPtr = chainPtr; /* Peel off a new item. */ poolPtr->bytesLeft -= size; memory = (char *)(chainPtr + 1) + poolPtr->bytesLeft; } } return memory; } /* *--------------------------------------------------------------------------- * * VariablePoolFreeItem -- * * Placeholder for freeProc routine. The pool memory is * not reclaimed or freed until the entire pool is released. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void VariablePoolFreeItem(Blt_Pool pool, void *item) { /* Does nothing */ } /* *--------------------------------------------------------------------------- * * StringPoolAllocItem -- * * Returns a new item. First check if there is any more space * left in the current chunk. If there isn't then next check * the free list for unused items. Finally allocate a new * chunk and return its first item. * * Results: * Returns a new (possible reused) item. * * Side Effects: * A new memory chunk may be allocated. * *--------------------------------------------------------------------------- */ static void * StringPoolAllocItem(Blt_Pool pool, size_t size) { Pool *poolPtr = (Pool *)pool; PoolChain *chainPtr; void *memory; if (size >= POOL_MAX_CHUNK_SIZE) { /* * Handle oversized requests by allocating a chunk to hold the * single item and immediately placing it into the in-use list. */ chainPtr = Blt_AssertMalloc(sizeof(PoolChain) + size); if (poolPtr->headPtr == NULL) { poolPtr->headPtr = chainPtr; } else { chainPtr->nextPtr = poolPtr->headPtr->nextPtr; poolPtr->headPtr->nextPtr = chainPtr; } memory = (void *)chainPtr; } else { if (poolPtr->bytesLeft >= size) { poolPtr->bytesLeft -= size; memory = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft; } else { poolPtr->waste += poolPtr->bytesLeft; /* Create a new block of items and prepend it to the * in-use list */ poolPtr->bytesLeft = POOL_MAX_CHUNK_SIZE; /* Allocate the requested chunk size, plus the header */ chainPtr = Blt_AssertMalloc(sizeof(PoolChain) + poolPtr->bytesLeft); chainPtr->nextPtr = poolPtr->headPtr; poolPtr->headPtr = chainPtr; /* Peel off a new item. */ poolPtr->bytesLeft -= size; memory = (char *)(chainPtr + 1) + poolPtr->bytesLeft; } } return memory; } /* *--------------------------------------------------------------------------- * * StringPoolFreeItem -- * * Placeholder for freeProc routine. String pool memory is * not reclaimed or freed until the entire pool is released. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void StringPoolFreeItem(Blt_Pool pool, void *item) { /* Does nothing */ } /* * The fixed size pool is a chain of malloc'ed blocks. * * +---------+ +---------+ +---------+ * NULL<-| nextPtr |<-| nextPtr |<-| nextPtr |<- headPtr * |---------| |---------| |---------| * | chunk1 | | chunk2 | | chunk3 | * +---------+ | | | | * +---------+ | | * | | * | | * +---------+ * * Each chunk contains an integral number of fixed size items. * The number of items doubles until a maximum size is reached * (each subsequent new chunk will be the maximum). Chunks * are allocated only when needed (no more space is available * in the last chunk). * * The chain of blocks is only freed when the entire pool is * destroyed. * * A freelist of unused items also maintained. Each freed item * is prepended to a free list. Before allocating new chunks * the freelist is examined to see if an unused items exist. * * chunk1 chunk2 chunk3 * +---------+ +---------+ +---------+ * NULL<-| unused | | | | | * +----^----+ +---------+ +---------+ * | unused |<-| unused |<-| unused | * +---------+ +---------+ +----^----+ * | | | | | unused | * +---------+ | | +----^----+ * | | | | | * +---------+ +----|----+ * | usused |<- freePtr * +---------+ */ /* *--------------------------------------------------------------------------- * * FixedPoolFreeItem -- * * Returns a new item. First check if there is any more space * left in the current chunk. If there isn't then next check * the free list for unused items. Finally allocate a new * chunk and return its first item. * * Results: * Returns a new (possible reused) item. * * Side Effects: * A new memory chunk may be allocated. * *--------------------------------------------------------------------------- */ static void * FixedPoolAllocItem(Blt_Pool pool, size_t size) { Pool *poolPtr = (Pool *)pool; PoolChain *chainPtr; void *newPtr; size = ALIGN(size); if (poolPtr->itemSize == 0) { poolPtr->itemSize = size; } assert(size == poolPtr->itemSize); if (poolPtr->bytesLeft > 0) { poolPtr->bytesLeft -= poolPtr->itemSize; newPtr = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft; } else if (poolPtr->freePtr != NULL) { /* Reuse from the free list. */ /* Reuse items on the free list */ chainPtr = poolPtr->freePtr; poolPtr->freePtr = chainPtr->nextPtr; newPtr = (void *)chainPtr; } else { /* Allocate another block. */ /* Create a new block of items and prepend it to the in-use list */ poolPtr->bytesLeft = poolPtr->itemSize * (1 << poolPtr->poolSize); if (poolPtr->bytesLeft < POOL_MAX_CHUNK_SIZE) { poolPtr->poolSize++; /* Keep doubling the size of the new * chunk up to a maximum size. */ } /* Allocate the requested chunk size, plus the header */ chainPtr = Blt_AssertMalloc(sizeof(PoolChain) + poolPtr->bytesLeft); chainPtr->nextPtr = poolPtr->headPtr; poolPtr->headPtr = chainPtr; /* Peel off a new item. */ poolPtr->bytesLeft -= poolPtr->itemSize; newPtr = (char *)(poolPtr->headPtr + 1) + poolPtr->bytesLeft; } return newPtr; } /* *--------------------------------------------------------------------------- * * FixedPoolFreeItem -- * * Frees an item. The actual memory is not freed. The item * instead is prepended to a freelist where it may be reclaimed * and used again. * * Results: * None. * * Side Effects: * Item is placed on the pool's free list. * *--------------------------------------------------------------------------- */ static void FixedPoolFreeItem(Blt_Pool pool, void *item) { Pool *poolPtr = (Pool *)pool; PoolChain *chainPtr = (PoolChain *)item; /* Prepend the newly deallocated item to the free list. */ chainPtr->nextPtr = poolPtr->freePtr; poolPtr->freePtr = chainPtr; } /* *--------------------------------------------------------------------------- * * Blt_PoolCreate -- * * Creates a new memory pool for fixed-size/variable-size/string * items. * * Results: * Returns a pointer to the newly allocated pool. * *--------------------------------------------------------------------------- */ Blt_Pool Blt_PoolCreate(int type) { Pool *poolPtr; poolPtr = Blt_AssertMalloc(sizeof(Pool)); switch (type) { case BLT_VARIABLE_SIZE_ITEMS: poolPtr->allocProc = VariablePoolAllocItem; poolPtr->freeProc = VariablePoolFreeItem; break; case BLT_FIXED_SIZE_ITEMS: poolPtr->allocProc = FixedPoolAllocItem; poolPtr->freeProc = FixedPoolFreeItem; break; case BLT_STRING_ITEMS: poolPtr->allocProc = StringPoolAllocItem; poolPtr->freeProc = StringPoolFreeItem; break; } poolPtr->headPtr = poolPtr->freePtr = NULL; poolPtr->waste = poolPtr->bytesLeft = 0; poolPtr->poolSize = poolPtr->itemSize = 0; return (Blt_Pool)poolPtr; } /* *--------------------------------------------------------------------------- * * Blt_PoolDestroy -- * * Destroys the given memory pool. The chain of allocated blocks * are freed. The is the only time that memory is actually freed. * * Results: * None. * * Side Effects: * All memory used by the pool is freed. * *--------------------------------------------------------------------------- */ void Blt_PoolDestroy(Blt_Pool pool) { Pool *poolPtr = (Pool *)pool; PoolChain *chainPtr, *nextPtr; for (chainPtr = poolPtr->headPtr; chainPtr != NULL; chainPtr = nextPtr) { nextPtr = chainPtr->nextPtr; Blt_Free(chainPtr); } Blt_Free(poolPtr); } ����������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWin.h����������������������������������������������������������������������0000644�0001750�0001750�00000023475�11462120063�014451� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWin.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_WIN_H #define _BLT_WIN_H #define _CRT_SECURE_NO_DEPRECATE #define STRICT #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef STRICT #undef WIN32_LEAN_AND_MEAN #include <windowsx.h> #undef STD_NORMAL_BACKGROUND #undef STD_NORMAL_FOREGROUND #undef STD_SELECT_BACKGROUND #undef STD_SELECT_FOREGROUND #undef STD_TEXT_FOREGROUND #undef STD_FONT #undef STD_FONT_LARGE #undef STD_FONT_SMALL #define STD_NORMAL_BACKGROUND "SystemButtonFace" #define STD_NORMAL_FOREGROUND "SystemButtonText" #define STD_SELECT_BACKGROUND "SystemHighlight" #define STD_SELECT_FOREGROUND "SystemHighlightText" #define STD_TEXT_FOREGROUND "SystemWindowText" #define STD_FONT "Arial 8" #define STD_FONT_LARGE "Arial 12" #define STD_FONT_SMALL "Arial 6" #ifdef CHECK_UNICODE_CALLS #define _UNICODE #define UNICODE #define __TCHAR_DEFINED typedef float *_TCHAR; #define _TCHAR_DEFINED typedef float *TCHAR; #endif /* CHECK_UNICODE_CALLS */ /* DOS Encapsulated PostScript File Header */ #pragma pack(2) typedef struct { BYTE magic[4]; /* Magic number for a DOS EPS file * C5,D0,D3,C6 */ DWORD psStart; /* Offset of PostScript section. */ DWORD psLength; /* Length of the PostScript section. */ DWORD wmfStart; /* Offset of Windows Meta File section. */ DWORD wmfLength; /* Length of Meta file section. */ DWORD tiffStart; /* Offset of TIFF section. */ DWORD tiffLength; /* Length of TIFF section. */ WORD checksum; /* Checksum of header. If FFFF, ignore. */ } DOSEPSHEADER; #pragma pack() /* Aldus Portable Metafile Header */ #pragma pack(2) typedef struct { DWORD key; /* Type of metafile */ WORD hmf; /* Unused. Must be NULL. */ SMALL_RECT bbox; /* Bounding rectangle */ WORD inch; /* Units per inch. */ DWORD reserved; /* Unused. */ WORD checksum; /* XOR of previous fields (10 32-bit words). */ } APMHEADER; #pragma pack() #undef Blt_Export #define Blt_Export __declspec(dllexport) #if defined(_MSC_VER) || defined(__BORLANDC__) #define fstat _fstat #define stat _stat #ifdef _MSC_VER #define fileno _fileno #endif #define isnan(x) _isnan(x) #define strcasecmp(s1,s2) _stricmp(s1,s2) #define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n) #define vsnprintf _vsnprintf #define isascii(c) __isascii(c) #endif /* _MSC_VER || __BORLANDC__ */ #ifdef __BORLANDC__ #define isnan(x) _isnan(x) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) #ifdef FINITE #undef FINITE #define FINITE(x) _finite(x) #endif #endif /* __BORLANDC__ || _MSC_VER */ #ifdef __GNUC__ #include <wingdi.h> #include <windowsx.h> #undef Status #include <winspool.h> #define Status int /* * Add definitions missing from windgi.h, windowsx.h, and winspool.h */ #include <missing.h> #endif /* __GNUC__ */ #undef XCopyArea #define XCopyArea Blt_EmulateXCopyArea #undef XCopyPlane #define XCopyPlane Blt_EmulateXCopyPlane #undef XDrawArcs #define XDrawArcs Blt_EmulateXDrawArcs #undef XDrawLine #define XDrawLine Blt_EmulateXDrawLine #undef XDrawLines #define XDrawLines Blt_EmulateXDrawLines #undef XDrawPoints #define XDrawPoints Blt_EmulateXDrawPoints #undef XDrawRectangle #define XDrawRectangle Blt_EmulateXDrawRectangle #undef XDrawRectangles #define XDrawRectangles Blt_EmulateXDrawRectangles #undef XDrawSegments #define XDrawSegments Blt_EmulateXDrawSegments #undef XDrawString #define XDrawString Blt_EmulateXDrawString #undef XFillArcs #define XFillArcs Blt_EmulateXFillArcs #undef XFillPolygon #define XFillPolygon Blt_EmulateXFillPolygon #undef XFillRectangle #define XFillRectangle Blt_EmulateXFillRectangle #undef XFillRectangles #define XFillRectangles Blt_EmulateXFillRectangles #undef XFree #define XFree Blt_EmulateXFree #undef XGetWindowAttributes #define XGetWindowAttributes Blt_EmulateXGetWindowAttributes #undef XLowerWindow #define XLowerWindow Blt_EmulateXLowerWindow #undef XMaxRequestSize #define XMaxRequestSize Blt_EmulateXMaxRequestSize #undef XRaiseWindow #define XRaiseWindow Blt_EmulateXRaiseWindow #undef XReparentWindow #define XReparentWindow Blt_EmulateXReparentWindow #undef XSetDashes #define XSetDashes Blt_EmulateXSetDashes #undef XUnmapWindow #define XUnmapWindow Blt_EmulateXUnmapWindow #undef XWarpPointer #define XWarpPointer Blt_EmulateXWarpPointer BLT_EXTERN GC Blt_EmulateXCreateGC(Display *display, Drawable drawable, unsigned long mask, XGCValues *valuesPtr); BLT_EXTERN void Blt_EmulateXCopyArea(Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y); BLT_EXTERN void Blt_EmulateXCopyPlane(Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y, unsigned long plane); BLT_EXTERN void Blt_EmulateXDrawArcs(Display *display, Drawable drawable, GC gc, XArc *arcArr, int nArcs); BLT_EXTERN void Blt_EmulateXDrawLine(Display *display, Drawable drawable, GC gc, int x1, int y1, int x2, int y2); BLT_EXTERN void Blt_EmulateXDrawLines(Display *display, Drawable drawable, GC gc, XPoint *pointArr, int nPoints, int mode); BLT_EXTERN void Blt_EmulateXDrawPoints(Display *display, Drawable drawable, GC gc, XPoint *pointArr, int nPoints, int mode); BLT_EXTERN void Blt_EmulateXDrawRectangle(Display *display, Drawable drawable, GC gc, int x, int y, unsigned int width, unsigned int height); BLT_EXTERN void Blt_EmulateXDrawRectangles(Display *display, Drawable drawable, GC gc, XRectangle *rectArr, int nRects); BLT_EXTERN void Blt_EmulateXDrawSegments(Display *display, Drawable drawable, GC gc, XSegment *segArr, int nSegments); BLT_EXTERN void Blt_EmulateXDrawSegments(Display *display, Drawable drawable, GC gc, XSegment *segArr, int nSegments); BLT_EXTERN void Blt_EmulateXDrawString(Display *display, Drawable drawable, GC gc, int x, int y, _Xconst char *string, int length); BLT_EXTERN void Blt_EmulateXFillArcs(Display *display, Drawable drawable, GC gc, XArc *arcArr, int nArcs); BLT_EXTERN void Blt_EmulateXFillPolygon(Display *display, Drawable drawable, GC gc, XPoint *points, int nPoints, int shape, int mode); BLT_EXTERN void Blt_EmulateXFillRectangle(Display *display, Drawable drawable, GC gc, int x, int y, unsigned int width, unsigned int height); BLT_EXTERN void Blt_EmulateXFillRectangles(Display *display, Drawable drawable, GC gc, XRectangle *rectArr, int nRects); BLT_EXTERN void Blt_EmulateXFree(void *ptr); BLT_EXTERN int Blt_EmulateXGetWindowAttributes(Display *display, Window window, XWindowAttributes * attrsPtr); BLT_EXTERN void Blt_EmulateXLowerWindow(Display *display, Window window); BLT_EXTERN void Blt_EmulateXMapWindow(Display *display, Window window); BLT_EXTERN long Blt_EmulateXMaxRequestSize(Display *display); BLT_EXTERN void Blt_EmulateXRaiseWindow(Display *display, Window window); BLT_EXTERN void Blt_EmulateXReparentWindow(Display *display, Window window, Window parent, int x, int y); BLT_EXTERN void Blt_EmulateXSetDashes(Display *display, GC gc, int dashOffset, _Xconst char *dashList, int n); BLT_EXTERN void Blt_EmulateXUnmapWindow(Display *display, Window window); BLT_EXTERN void Blt_EmulateXWarpPointer(Display *display, Window srcWindow, Window destWindow, int srcX, int srcY, unsigned int srcWidth, unsigned int srcHeight, int destX, int destY); BLT_EXTERN void Blt_DrawLine2D(Display *display, Drawable drawable, GC gc, POINT *screenPts, int nScreenPts); BLT_EXTERN unsigned char *Blt_GetBitmapData(Display *display, Pixmap bitmap, int width, int height, int *pitchPtr); BLT_EXTERN HFONT Blt_CreateRotatedFont(Tk_Window tkwin, unsigned long font, float angle); BLT_EXTERN HPALETTE Blt_GetSystemPalette(void); BLT_EXTERN HPEN Blt_GCToPen(HDC dc, GC gc); BLT_EXTERN double hypot(double x, double y); BLT_EXTERN int Blt_AsyncRead(int fd, char *buffer, unsigned int size); BLT_EXTERN int Blt_AsyncWrite(int fd, const char *buffer, unsigned int size); BLT_EXTERN void Blt_CreateFileHandler(int fd, int flags, Tcl_FileProc * proc, ClientData clientData); BLT_EXTERN void Blt_DeleteFileHandler(int fd); BLT_EXTERN int Blt_GetPlatformId(void); BLT_EXTERN const char *Blt_LastError(void); BLT_EXTERN const char *Blt_PrintError(int error); BLT_EXTERN int Blt_GetOpenPrinter(Tcl_Interp *interp, const char *id, Drawable *drawablePtr); BLT_EXTERN int Blt_PrintDialog(Tcl_Interp *interp, Drawable *drawablePtr); BLT_EXTERN int Blt_OpenPrinterDoc(Tcl_Interp *interp, const char *id); BLT_EXTERN int Blt_ClosePrinterDoc(Tcl_Interp *interp, const char *id); BLT_EXTERN void Blt_GetPrinterScale(HDC dc, double *xRatio, double *yRatio); BLT_EXTERN int Blt_StartPrintJob(Tcl_Interp *interp, Drawable drawable); BLT_EXTERN int Blt_EndPrintJob(Tcl_Interp *interp, Drawable drawable); #endif /*_BLT_WIN_H*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltContainer.c����������������������������������������������������������������0000644�0001750�0001750�00000161131�11462120062�015620� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltContainer.c -- * * This module implements a container widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_CONTAINER #include "bltOp.h" #include "bltChain.h" #include "bltTree.h" #if !defined(WIN32) && !defined(MACOSX) #include <X11/Xatom.h> #include <X11/Xproto.h> #include <X11/Xutil.h> #endif #include "tkDisplay.h" #define XDEBUG #define SEARCH_TRIES 100 /* Maximum number of attempts to check for * a given window before failing. */ #define SEARCH_INTERVAL 20 /* Number milliseconds to wait after each * attempt to find a window. */ #define SEARCH_TKWIN (1<<0) /* Search via Tk window pathname. */ #define SEARCH_XID (1<<1) /* Search via an XID 0x0000000. */ #define SEARCH_CMD (1<<2) /* Search via a command-line arguments. */ #define SEARCH_NAME (1<<3) /* Search via the application name. */ #define SEARCH_PROPERTY (1<<4) /* Search via the application name. */ #define SEARCH_ALL (SEARCH_TKWIN | SEARCH_XID | SEARCH_CMD | SEARCH_NAME) #define CONTAINER_REDRAW (1<<1) #define CONTAINER_MAPPED (1<<2) #define CONTAINER_FOCUS (1<<4) #define CONTAINER_INIT (1<<5) #define CONTAINER_MOVE (1<<7) #define DEF_CONTAINER_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_CONTAINER_BORDERWIDTH STD_BORDERWIDTH #define DEF_CONTAINER_COMMAND (char *)NULL #define DEF_CONTAINER_CURSOR (char *)NULL #define DEF_CONTAINER_HEIGHT "0" #define DEF_CONTAINER_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_CONTAINER_HIGHLIGHT_COLOR RGB_BLACK #define DEF_CONTAINER_HIGHLIGHT_WIDTH "2" #define DEF_CONTAINER_RELIEF "sunken" #define DEF_CONTAINER_TAKE_FOCUS "0" #define DEF_CONTAINER_TIMEOUT "20" #define DEF_CONTAINER_WIDTH "0" #define DEF_CONTAINER_WINDOW (char *)NULL typedef struct _SearchInfo SearchInfo; typedef void (SearchProc)(Display *display, Window window, SearchInfo *searchPtr); struct _SearchInfo { SearchProc *proc; char *pattern; /* Search pattern. */ Window window; /* XID of last window that matches criteria. */ int nMatches; /* Number of windows that match the pattern. */ int saveNames; /* Indicates to save the names of the * window XIDs that match the search * criteria. */ Tcl_DString dString; /* Will contain the strings of the * window XIDs matching the search * criteria. */ Atom atom; }; typedef struct { Tk_Window tkwin; /* Window that embodies the widget. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up.*/ Display *display; /* Display containing widget; needed, * among other things, to release * resources after tkwin has already * gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. */ Tcl_Command cmdToken; /* Token for widget's command. */ unsigned int flags; /* For bit-field definitions, see above. */ int inset; /* Total width of borders; focus * highlight and 3-D border. Indicates * the offset from outside edges to * leave room for borders. */ Tk_Cursor cursor; /* X Cursor */ Tk_3DBorder border; /* 3D border surrounding the adopted * window. */ int borderWidth; /* Width of 3D border. */ int relief; /* 3D border relief. */ Tk_Window tkToplevel; /* Toplevel (wrapper) window of * container. It's used to track the * location of the container. If it * moves we need to notify the * embedded application. */ /* * Focus highlight ring */ int highlightWidth; /* Width in pixels of highlight to * draw around widget when it has the * focus. <= 0 means don't draw a * highlight. */ XColor *highlightBgColor; /* Color for drawing traversal * highlight area when highlight is * off. */ XColor *highlightColor; /* Color for drawing traversal highlight. */ GC highlightGC; /* GC for focus highlight. */ char *takeFocus; /* Says whether to select this widget during * tab traveral operations. This value isn't * used in C code, but for the widget's Tcl * bindings. */ int reqWidth, reqHeight; /* Requested dimensions of the container * window. */ Window adopted; /* X window Id or Win32 handle of adopted * window contained by the widget. If None, * no window has been reparented. */ Tk_Window tkAdopted; /* Non-NULL if this is a Tk window that's * been adopted. */ int adoptedX, adoptedY; /* Current position of the adopted window. */ int adoptedWidth; /* Current width of the adopted window. */ int adoptedHeight; /* Current height of the adopted window. */ int origX, origY; int origWidth, origHeight; /* Dimensions of the window when it * was adopted. When the window is * released it's returned to it's * original dimensions. */ int timeout; int nextId; } Container; static Blt_OptionParseProc ObjToXID; static Blt_OptionPrintProc XIDToObj; static Blt_CustomOption XIDOption = { ObjToXID, XIDToObj, NULL, (ClientData)(SEARCH_TKWIN | SEARCH_XID), }; #ifndef WIN32 static Blt_CustomOption XIDNameOption = { ObjToXID, XIDToObj, NULL, (ClientData)SEARCH_NAME, }; static Blt_CustomOption XIDCmdOption = { ObjToXID, XIDToObj, NULL, (ClientData)SEARCH_CMD, }; static Blt_CustomOption XIDPropertyOption = { ObjToXID, XIDToObj, NULL, (ClientData)SEARCH_PROPERTY, }; #endif static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_CONTAINER_BACKGROUND, Blt_Offset(Container, border), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_CONTAINER_BORDERWIDTH, Blt_Offset(Container, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, #ifndef WIN32 {BLT_CONFIG_CUSTOM, "-command", "command", "Command", DEF_CONTAINER_WINDOW, Blt_Offset(Container, adopted), BLT_CONFIG_DONT_SET_DEFAULT, &XIDCmdOption}, #endif {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CONTAINER_CURSOR, Blt_Offset(Container, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_CONTAINER_HEIGHT, Blt_Offset(Container, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_CONTAINER_HIGHLIGHT_BACKGROUND, Blt_Offset(Container, highlightBgColor), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_CONTAINER_HIGHLIGHT_COLOR, Blt_Offset(Container, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_CONTAINER_HIGHLIGHT_WIDTH, Blt_Offset(Container, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, #ifndef WIN32 {BLT_CONFIG_CUSTOM, "-name", "name", "Name", DEF_CONTAINER_WINDOW, Blt_Offset(Container, adopted), BLT_CONFIG_DONT_SET_DEFAULT, &XIDNameOption}, {BLT_CONFIG_CUSTOM, "-property", "property", "Property", DEF_CONTAINER_WINDOW, Blt_Offset(Container, adopted), BLT_CONFIG_DONT_SET_DEFAULT, &XIDPropertyOption}, #endif {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_CONTAINER_RELIEF, Blt_Offset(Container, relief), 0}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_CONTAINER_TAKE_FOCUS, Blt_Offset(Container, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_INT_POS, "-timeout", "timeout", "Timeout", DEF_CONTAINER_TIMEOUT, Blt_Offset(Container, timeout), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_CONTAINER_WIDTH, Blt_Offset(Container, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-window", "window", "Window", DEF_CONTAINER_WINDOW, Blt_Offset(Container, adopted), BLT_CONFIG_DONT_SET_DEFAULT, &XIDOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Forward Declarations */ static Tcl_CmdDeleteProc ContainerInstCmdDeleteProc; static Tcl_FreeProc DestroyContainer; static Tcl_IdleProc DisplayContainer; static Tcl_ObjCmdProc ContainerCmd; static Tcl_ObjCmdProc ContainerInstCmd; static Tk_EventProc ContainerEventProc; static Tk_EventProc ToplevelEventProc; static Tk_GenericProc AdoptedWindowEventProc; static void EventuallyRedraw(Container *cntrPtr); typedef int (ContainerCmdProc)(Container *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #ifdef notdef /* *--------------------------------------------------------------------------- * * GetWindowId -- * * Returns the XID for the Tk_Window given. Starting in Tk 8.0, * the toplevel widgets are wrapped by another window. * Currently there's no way to get at that window, other than * what is done here: query the X window hierarchy and grab the * parent. * * Results: * Returns the X Window ID of the widget. If it's a toplevel, then * the XID of the wrapper is returned. * *--------------------------------------------------------------------------- */ Window GetXID(Tk_Window tkwin) { HWND hWnd; TkWinWindow *twdPtr; hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); if (Tk_IsTopLevel(tkwin)) { hWnd = GetParent(hWnd); } twdPtr = Blt_AssertMalloc(sizeof(TkWinWindow)); twdPtr->handle = hWnd; twdPtr->type = TWD_WINDOW; twdPtr->winPtr = tkwin; return (Window)twdPtr; } #endif /* *--------------------------------------------------------------------------- * * NameOfId -- * * Returns a string representing the given XID. * * Results: * A static string containing either the hexidecimal number or * the pathname of a Tk window. * *--------------------------------------------------------------------------- */ static const char * NameOfId( Display *display, /* Display containing both the container widget * and the adopted window. */ Window window) /* XID of the adopted window. */ { if (window != None) { Tk_Window tkwin; static char string[200]; /* See first if it's a window that Tk knows about. */ /* * Note: If the wrapper window is reparented, Tk pretends it's * no longer connected to the toplevel, so if you look for * the child of the wrapper tkwin, it's NULL. */ tkwin = Tk_IdToWindow(display, window); if ((tkwin != NULL) && (Tk_PathName(tkwin) != NULL)) { return Tk_PathName(tkwin); } sprintf_s(string, 200, "0x%lx", (unsigned long)window); return string; } return ""; /* Return empty string if XID is None. */ } #ifndef WIN32 /* *--------------------------------------------------------------------------- * * XGeometryErrorProc -- * * Flags errors generated from XGetGeometry calls to the X server. * * Results: * Always returns 0. * * Side Effects: * Sets a flag, indicating an error occurred. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int XGeometryErrorProc( ClientData clientData, XErrorEvent *eventPtr) /* Not used. */ { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } /* *--------------------------------------------------------------------------- * * GetAdoptedWindowGeometry -- * * Computes the requested geometry of the container using the * size of adopted window as a reference. * * Results: * A standard TCL result. * * Side Effects: * Sets a flag, indicating an error occurred. * *--------------------------------------------------------------------------- */ static int GetAdoptedWindowGeometry( Tcl_Interp *interp, Container *cntrPtr) { int x, y, width, height, borderWidth, depth; int xOffset, yOffset; Window root, dummy; Tk_ErrorHandler handler; int result; int any = -1; width = height = 1; xOffset = yOffset = 0; if (cntrPtr->adopted != None) { handler = Tk_CreateErrorHandler(cntrPtr->display, any, X_GetGeometry, any, XGeometryErrorProc, &result); root = Tk_RootWindow(cntrPtr->tkwin); XTranslateCoordinates(cntrPtr->display, cntrPtr->adopted, root, 0, 0, &xOffset, &yOffset, &dummy); result = XGetGeometry(cntrPtr->display, cntrPtr->adopted, &root, &x, &y, (unsigned int *)&width, (unsigned int *)&height, (unsigned int *)&borderWidth, (unsigned int *)&depth); Tk_DeleteErrorHandler(handler); XSync(cntrPtr->display, False); if (result == 0) { Tcl_AppendResult(interp, "can't get geometry for \"", NameOfId(cntrPtr->display, cntrPtr->adopted), "\"", (char *)NULL); return TCL_ERROR; } cntrPtr->origX = xOffset; cntrPtr->origY = yOffset; cntrPtr->origWidth = width; cntrPtr->origHeight = height; } else { cntrPtr->origX = cntrPtr->origY = 0; cntrPtr->origWidth = cntrPtr->origHeight = 0; } cntrPtr->adoptedX = x; cntrPtr->adoptedY = y; cntrPtr->adoptedWidth = width; cntrPtr->adoptedHeight = height; return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetChildren -- * * Returns a chain of the child windows according to their stacking * order. The window ids are ordered from top to bottom. * *--------------------------------------------------------------------------- */ static Blt_Chain GetChildren(Display *display, Window window) { Window *children; unsigned int nChildren; Window parent, root; if (XQueryTree(display, window, &parent, &root, &children, &nChildren)) { if (nChildren > 0) { Blt_Chain chain; size_t i; chain = Blt_Chain_Create(); for (i = 0; i < nChildren; i++) { /* * XQuery returns windows in bottom to top order. We'll * reverse the order. */ Blt_Chain_Prepend(chain, (ClientData)children[i]); } XFree((char *)children); return chain; } } return NULL; } static int GetMaxPropertySize(Display *display) { int size; size = Blt_MaxRequestSize(display, sizeof(char)); size -= 32; return size; } static unsigned char * GetProperty(Display *display, Window window, Atom atom) { unsigned char *data; int result, format; Atom typeAtom; unsigned long nItems, bytesAfter; if (window == None) { return NULL; } data = NULL; result = XGetWindowProperty( display, /* Display of window. */ window, /* Window holding the property. */ atom, /* Name of property. */ 0, /* Offset of data (for multiple reads). */ GetMaxPropertySize(display), /* Maximum number of items to read. */ False, /* If true, delete the property. */ XA_STRING, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the property. */ &nItems, /* (out) # of items in specified format. */ &bytesAfter, /* (out) # of bytes remaining to be read. */ &data); if ((result != Success) || (format != 8) /*|| (typeAtom != XA_STRING)*/) { if ((result == Success) && (format != None)) { fprintf(stderr, "format=%d typeAtom=%d\n", format, (int)typeAtom); } if (data != NULL) { XFree((char *)data); data = NULL; } } return data; } /* *--------------------------------------------------------------------------- * * PropertySearch -- * * Traverses the entire window hierarchy, searching for windows * matching the name field in the SearchInfo structure. This * routine is recursively called for each successive level in * the window hierarchy. * * Results: * None. * * Side Effects: * The SearchInfo structure will track the number of windows that * match the given criteria. * *--------------------------------------------------------------------------- */ static void PropertySearch(Display *display, Window window, SearchInfo *searchPtr) { Blt_Chain chain; char *data; data = (char *)GetProperty(display, window, searchPtr->atom); if (data != NULL) { /* Compare the name of the window to the search pattern. */ if (Tcl_StringMatch(data, searchPtr->pattern)) { fprintf(stderr, "window 0x%x matched %s property (%s) with %s\n", (int)window, XGetAtomName(display, searchPtr->atom), data, searchPtr->pattern); if (searchPtr->saveNames) { /* Record names of matching windows. */ Tcl_DStringAppendElement(&searchPtr->dString, NameOfId(display, window)); Tcl_DStringAppendElement(&searchPtr->dString, data); } searchPtr->window = window; searchPtr->nMatches++; } XFree(data); } /* Process the window's descendants. */ chain = GetChildren(display, window); if (chain != NULL) { Blt_ChainLink link; Window child; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { child = (Window)Blt_Chain_GetValue(link); PropertySearch(display, child, searchPtr); } Blt_Chain_Destroy(chain); } } /* *--------------------------------------------------------------------------- * * NameSearch -- * * Traverses the entire window hierarchy, searching for windows * matching the name field in the SearchInfo structure. This * routine is recursively called for each successive level in * the window hierarchy. * * Results: * None. * * Side Effects: * The SearchInfo structure will track the number of windows that * match the given criteria. * *--------------------------------------------------------------------------- */ static void NameSearch( Display *display, Window window, SearchInfo *searchPtr) { Blt_Chain chain; char *wmName; if (XFetchName(display, window, &wmName)) { /* Compare the name of the window to the search pattern. */ if (Tcl_StringMatch(wmName, searchPtr->pattern)) { if (searchPtr->saveNames) { /* Record names of matching windows. */ Tcl_DStringAppendElement(&searchPtr->dString, NameOfId(display, window)); Tcl_DStringAppendElement(&searchPtr->dString, wmName); } searchPtr->window = window; searchPtr->nMatches++; } XFree(wmName); } /* Process the window's descendants. */ chain = GetChildren(display, window); if (chain != NULL) { Blt_ChainLink link; Window child; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { child = (Window)Blt_Chain_GetValue(link); NameSearch(display, child, searchPtr); } Blt_Chain_Destroy(chain); } } /* *--------------------------------------------------------------------------- * * CmdSearch -- * * Traverses the entire window hierarchy, searching for windows * matching the command-line specified in the SearchInfo structure. * This routine is recursively called for each successive level * in the window hierarchy. * * Results: * None. * * Side Effects: * The SearchInfo structure will track the number of windows that * match the given command-line. * *--------------------------------------------------------------------------- */ static void CmdSearch( Display *display, Window window, SearchInfo *searchPtr) { Blt_Chain chain; int argc; char **argv; if (XGetCommand(display, window, &argv, &argc)) { char *string; string = Tcl_Merge(argc, (const char **)argv); XFreeStringList(argv); if (Tcl_StringMatch(string, searchPtr->pattern)) { if (searchPtr->saveNames) { /* Record names of matching windows. */ Tcl_DStringAppendElement(&searchPtr->dString, NameOfId(display, window)); Tcl_DStringAppendElement(&searchPtr->dString, string); } searchPtr->window = window; searchPtr->nMatches++; } Blt_Free(string); } /* Process the window's descendants. */ chain = GetChildren(display, window); if (chain != NULL) { Blt_ChainLink link; Window child; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { child = (Window)Blt_Chain_GetValue(link); CmdSearch(display, child, searchPtr); } Blt_Chain_Destroy(chain); } } /* *--------------------------------------------------------------------------- * * TimeoutProc -- * * Procedure called when the timer event elapses. Used to wait * between attempts checking for the designated window. * * Results: * None. * * Side Effects: * Sets a flag, indicating the timeout occurred. * *--------------------------------------------------------------------------- */ static void TimeoutProc(ClientData clientData) { int *expirePtr = clientData; *expirePtr = TRUE; } /* *--------------------------------------------------------------------------- * * TestAndWaitForWindow -- * * Searches, possibly multiple times, for windows matching the * criteria given, using the search proc also given. * * Results: * None. * * Side Effects: * Sets a flag, indicating the timeout occurred. * *--------------------------------------------------------------------------- */ static void TestAndWaitForWindow( Container *cntrPtr, /* Container widget record. */ SearchInfo *searchPtr) /* Search criteria. */ { Window root; Tcl_TimerToken timerToken; int expire; int i; /* Get the root window to start the search. */ root = Tk_RootWindow(cntrPtr->tkwin); timerToken = NULL; for (i = 0; i < SEARCH_TRIES; i++) { searchPtr->nMatches = 0; (*searchPtr->proc)(cntrPtr->display, root, searchPtr); if (searchPtr->nMatches > 0) { if (timerToken != NULL) { Tcl_DeleteTimerHandler(timerToken); } return; } expire = FALSE; /* * If the X11 application associated with the adopted window * was just started (via "exec" or "bgexec"), the window may * not exist yet. We have to wait a little bit for the program * to start up. Create a timer event break us out of an wait * loop. We'll wait for a given interval for the adopted window * to appear. */ timerToken = Tcl_CreateTimerHandler(cntrPtr->timeout, TimeoutProc, &expire); while (!expire) { /* Should file events be allowed? */ Tcl_DoOneEvent(TCL_TIMER_EVENTS | TCL_WINDOW_EVENTS | TCL_FILE_EVENTS); } } } #else /* *--------------------------------------------------------------------------- * * GetChildren -- * * Returns a chain of the child windows according to their stacking * order. The window ids are ordered from top to bottom. * *--------------------------------------------------------------------------- */ static Blt_Chain GetChildren(Display *display, Window window) { Blt_Chain chain; HWND hWnd; HWND parent; parent = Tk_GetHWND(window); chain = Blt_Chain_Create(); for (hWnd = GetTopWindow(parent); hWnd != NULL; hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)) { Blt_Chain_Append(chain, (ClientData)hWnd); } return chain; } /* *--------------------------------------------------------------------------- * * GetAdoptedWindowGeometry -- * * Computes the requested geometry of the container using the * size of adopted window as a reference. * * Results: * A standard TCL result. * * Side Effects: * Sets a flag, indicating an error occurred. * *--------------------------------------------------------------------------- */ static int GetAdoptedWindowGeometry( Tcl_Interp *interp, Container *cntrPtr) { int x, y, width, height; int xOffset, yOffset; Window root, dummy; width = height = 1; xOffset = yOffset = 0; x = y = 0; if (cntrPtr->adopted != None) { HWND hWnd; RECT rect; hWnd = Tk_GetHWND(cntrPtr->adopted); if (GetWindowRect(hWnd, &rect)) { x = rect.left; y = rect.top; width = rect.right - rect.left + 1; height = rect.bottom - rect.top + 1; } else { Tcl_AppendResult(interp, "can't get geometry for \"", NameOfId(cntrPtr->display, cntrPtr->adopted), "\"", (char *)NULL); return TCL_ERROR; } root = Tk_RootWindow(cntrPtr->tkwin); XTranslateCoordinates(cntrPtr->display, cntrPtr->adopted, root, 0, 0, &xOffset, &yOffset, &dummy); cntrPtr->origX = xOffset; cntrPtr->origY = yOffset; cntrPtr->origWidth = width; cntrPtr->origHeight = height; } else { cntrPtr->origX = cntrPtr->origY = 0; cntrPtr->origWidth = cntrPtr->origHeight = 0; } cntrPtr->adoptedX = x; cntrPtr->adoptedY = y; cntrPtr->adoptedWidth = width; cntrPtr->adoptedHeight = height; return TCL_OK; } #endif /*WIN32*/ /* *--------------------------------------------------------------------------- * * MapTree -- * * Maps each window in the hierarchy. This is needed because * * Results: * None. * * Side Effects: * Each window in the hierarchy is mapped. * *--------------------------------------------------------------------------- */ static void MapTree( Display *display, Window window) { Blt_Chain chain; XMapWindow(display, window); chain = GetChildren(display, window); if (chain != NULL) { Blt_ChainLink link; Window child; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { child = (Window)Blt_Chain_GetValue(link); MapTree(display, child); } Blt_Chain_Destroy(chain); } } /* *--------------------------------------------------------------------------- * * StringToXID -- * * Converts a string into an X window Id. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToXID( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window parent, /* Parent window */ Tcl_Obj *objPtr, /* String representation. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { unsigned long searchFlags = (unsigned long)clientData; Container *cntrPtr = (Container *)widgRec; Window *winPtr = (Window *) (widgRec + offset); Tk_Window tkAdopted; Window window; char *string; string = Tcl_GetString(objPtr); tkAdopted = NULL; window = None; if ((searchFlags & SEARCH_TKWIN) && (string[0] == '.')) { Tk_Window tkwin; tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (!Tk_IsTopLevel(tkwin)) { Tcl_AppendResult(interp, "can't reparent non-toplevel Tk windows", (char *)NULL); return TCL_ERROR; } tkAdopted = tkwin; Tk_MakeWindowExist(tkwin); window = Blt_GetWindowId(tkwin); #ifndef WIN32 } else if ((searchFlags & SEARCH_XID) && (string[0] == '0') && (string[1] == 'x')) { int token; /* Hexidecimal string specifying the Window token. */ if (Tcl_GetInt(interp, string, &token) != TCL_OK) { return TCL_ERROR; } window = token; } else if ((string == NULL) || (string[0] == '\0')) { window = None; } else { SearchInfo search; memset(&search, 0, sizeof(search)); if (searchFlags & (SEARCH_NAME | SEARCH_CMD | SEARCH_PROPERTY)) { if (searchFlags & SEARCH_NAME) { search.pattern = string; search.proc = NameSearch; } else if (searchFlags & SEARCH_CMD) { search.pattern = string; search.proc = CmdSearch; } else if (searchFlags & SEARCH_PROPERTY) { Tk_Window tkwin; char *atomName; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc != 2) { return TCL_ERROR; } tkwin = Tk_MainWindow(interp); atomName = Tcl_GetString(objv[0]); string = search.pattern = Tcl_GetString(objv[1]); search.atom = XInternAtom(Tk_Display(tkwin), atomName, False); search.proc = PropertySearch; } TestAndWaitForWindow(cntrPtr, &search); if (search.nMatches > 1) { Tcl_AppendResult(interp, "more than one window matches \"", search.pattern, "\"", (char *)NULL); return TCL_ERROR; } } if (search.nMatches == 0) { Tcl_AppendResult(interp, "can't find window from pattern \"", search.pattern, "\"", (char *)NULL); return TCL_ERROR; } window = search.window; #endif /*WIN32*/ } if (*winPtr != None) { Window root; root = Tk_RootWindow(cntrPtr->tkwin); if (Blt_ReparentWindow(cntrPtr->display, *winPtr, root, cntrPtr->origX, cntrPtr->origY) != TCL_OK) { Tcl_AppendResult(interp, "can't restore \"", NameOfId(cntrPtr->display, *winPtr), "\" window to root", (char *)NULL); return TCL_ERROR; } cntrPtr->flags &= ~CONTAINER_MAPPED; if (cntrPtr->tkAdopted == NULL) { /* This wasn't a Tk window. So deselect the event mask. */ XSelectInput(cntrPtr->display, *winPtr, 0); } else { MapTree(cntrPtr->display, *winPtr); } XMoveResizeWindow(cntrPtr->display, *winPtr, cntrPtr->origX, cntrPtr->origY, cntrPtr->origWidth, cntrPtr->origHeight); } cntrPtr->tkAdopted = tkAdopted; *winPtr = window; return TCL_OK; } /* *--------------------------------------------------------------------------- * * XIDToString -- * * Converts the Tk window back to its string representation (i.e. * its name). * * Results: * The name of the window is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * XIDToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window parent, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Container *cntrPtr = (Container *) widgRec; Window window = *(Window *)(widgRec + offset); Tcl_Obj *objPtr; if (cntrPtr->tkAdopted != NULL) { objPtr = Tcl_NewStringObj(Tk_PathName(cntrPtr->tkAdopted), -1); } else { objPtr = Tcl_NewStringObj(NameOfId(cntrPtr->display, window), -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Container *cntrPtr) { if ((cntrPtr->tkwin != NULL) && !(cntrPtr->flags & CONTAINER_REDRAW)) { cntrPtr->flags |= CONTAINER_REDRAW; Tcl_DoWhenIdle(DisplayContainer, cntrPtr); } } /* *--------------------------------------------------------------------------- * * AdoptedWindowEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on the encapsulated window. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets resized or exposed, it's redisplayed. * *--------------------------------------------------------------------------- */ static int AdoptedWindowEventProc( ClientData clientData, /* Information about the tab window. */ XEvent *eventPtr) /* Information about event. */ { Container *cntrPtr = (Container *) clientData; if ((eventPtr->type == CreateNotify) && (cntrPtr->adopted == None)) { fprintf(stderr, "window found is %x\n", (unsigned int)eventPtr->xmaprequest.window); if (Blt_ReparentWindow(cntrPtr->display, eventPtr->xmaprequest.window, Tk_WindowId(cntrPtr->tkwin), cntrPtr->inset, cntrPtr->inset) != TCL_OK) { fprintf(stderr, "can't adopt window \"%s\"\n", NameOfId(cntrPtr->display, eventPtr->xmaprequest.window)); return 0; } cntrPtr->adopted = eventPtr->xmaprequest.window; XSelectInput(cntrPtr->display, cntrPtr->adopted, StructureNotifyMask); XSelectInput(cntrPtr->display, Tk_RootWindow(cntrPtr->tkwin), 0); return 1; } if (eventPtr->xany.window != cntrPtr->adopted) { return 0; } if (eventPtr->type == DestroyNotify) { cntrPtr->adopted = None; EventuallyRedraw(cntrPtr); } return 1; } /* *--------------------------------------------------------------------------- * * ContainerEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on container widgets. * * Results: * None. * * Side Effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ContainerEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { Container *cntrPtr = clientData; switch (eventPtr->type) { case Expose: if (eventPtr->xexpose.count == 0) { EventuallyRedraw(cntrPtr); } break; case FocusIn: case FocusOut: if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { cntrPtr->flags |= CONTAINER_FOCUS; } else { cntrPtr->flags &= ~CONTAINER_FOCUS; } EventuallyRedraw(cntrPtr); } break; case ConfigureNotify: EventuallyRedraw(cntrPtr); break; case DestroyNotify: if (cntrPtr->tkwin != NULL) { cntrPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(cntrPtr->interp, cntrPtr->cmdToken); } if (cntrPtr->flags & CONTAINER_REDRAW) { Tcl_CancelIdleCall(DisplayContainer, cntrPtr); } Tcl_EventuallyFree(cntrPtr, DestroyContainer); break; } } /* *--------------------------------------------------------------------------- * * ToplevelEventProc -- * * Some applications assume that they are always a toplevel * window and play tricks accordingly. For example, Netscape * positions menus in relation to the toplevel. But if the * container's toplevel is moved, this positioning is wrong. * So watch if the toplevel is moved. * * [This would be easier and cleaner if Tk toplevels weren't so * botched by the addition of menubars. It's not enough to * track the ) * * Results: * None. * *--------------------------------------------------------------------------- */ static void ToplevelEventProc(ClientData clientData, XEvent *eventPtr) { Container *cntrPtr = clientData; if ((cntrPtr->adopted != None) && (cntrPtr->tkwin != NULL) && (eventPtr->type == ConfigureNotify)) { cntrPtr->flags |= CONTAINER_MOVE; EventuallyRedraw(cntrPtr); } } /* *--------------------------------------------------------------------------- * * DestroyContainer -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of the widget at a safe * time (when no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyContainer(DestroyData dataPtr) { Container *cntrPtr = (Container *) dataPtr; if (cntrPtr->highlightGC != NULL) { Tk_FreeGC(cntrPtr->display, cntrPtr->highlightGC); } if (cntrPtr->flags & CONTAINER_INIT) { Tk_DeleteGenericHandler(AdoptedWindowEventProc, cntrPtr); } if (cntrPtr->tkToplevel != NULL) { Tk_DeleteEventHandler(cntrPtr->tkToplevel, StructureNotifyMask, ToplevelEventProc, cntrPtr); } Blt_FreeOptions(configSpecs, (char *)cntrPtr, cntrPtr->display, 0); Blt_Free(cntrPtr); } /* *--------------------------------------------------------------------------- * * ConfigureContainer -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or reconfigure) * the widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, * etc. get set for cntrPtr; old resources get freed, if there * were any. The widget is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureContainer( Tcl_Interp *interp, /* Interpreter to report errors. */ Container *cntrPtr, /* Information about widget; may or * may not already have values for * some fields. */ int objc, Tcl_Obj *const *objv, int flags) { XGCValues gcValues; unsigned long gcMask; GC newGC; int width, height; if (Blt_ConfigureWidgetFromObj(interp, cntrPtr->tkwin, configSpecs, objc, objv, (char *)cntrPtr, flags) != TCL_OK) { return TCL_ERROR; } cntrPtr->inset = cntrPtr->borderWidth + cntrPtr->highlightWidth; if (Tk_WindowId(cntrPtr->tkwin) == None) { Tk_MakeWindowExist(cntrPtr->tkwin); } if (GetAdoptedWindowGeometry(interp, cntrPtr) != TCL_OK) { return TCL_ERROR; } if (Blt_ConfigModified(configSpecs, "-window", "-name", "-command", (char *)NULL)) { cntrPtr->flags &= ~CONTAINER_MAPPED; if (cntrPtr->adopted != None) { if (Blt_ReparentWindow(cntrPtr->display, cntrPtr->adopted, Tk_WindowId(cntrPtr->tkwin), cntrPtr->inset, cntrPtr->inset) != TCL_OK) { Tcl_AppendResult(interp, "can't adopt window \"", NameOfId(cntrPtr->display, cntrPtr->adopted), "\"", (char *)NULL); return TCL_ERROR; } XSelectInput(cntrPtr->display, cntrPtr->adopted, StructureNotifyMask); if ((cntrPtr->flags & CONTAINER_INIT) == 0) { Tk_CreateGenericHandler(AdoptedWindowEventProc, cntrPtr); cntrPtr->flags |= CONTAINER_INIT; } } } /* Add the designated inset to the requested dimensions. */ width = cntrPtr->origWidth + 2 * cntrPtr->inset; height = cntrPtr->origHeight + 2 * cntrPtr->inset; if (cntrPtr->reqWidth > 0) { width = cntrPtr->reqWidth; } if (cntrPtr->reqHeight > 0) { height = cntrPtr->reqHeight; } /* Set the requested width and height for the container. */ if ((Tk_ReqWidth(cntrPtr->tkwin) != width) || (Tk_ReqHeight(cntrPtr->tkwin) != height)) { Tk_GeometryRequest(cntrPtr->tkwin, width, height); } /* * GC for focus highlight. */ gcMask = GCForeground; gcValues.foreground = cntrPtr->highlightColor->pixel; newGC = Tk_GetGC(cntrPtr->tkwin, gcMask, &gcValues); if (cntrPtr->highlightGC != NULL) { Tk_FreeGC(cntrPtr->display, cntrPtr->highlightGC); } cntrPtr->highlightGC = newGC; EventuallyRedraw(cntrPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ContainerInstCmdDeleteProc -- * * This procedure can be called if the window was destroyed * (tkwin will be NULL) and the command was deleted * automatically. In this case, we need to do nothing. * * Otherwise this routine was called because the command was * deleted. Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ContainerInstCmdDeleteProc( ClientData clientData) /* Pointer to widget record for widget. */ { Container *cntrPtr = clientData; if (cntrPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = cntrPtr->tkwin; cntrPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ContainerCmd -- * * This procedure is invoked to process the TCL command that * corresponds to a widget managed by this module. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ContainerCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Container *cntrPtr; Tk_Window tkwin; unsigned int mask; char *path; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } tkwin = Tk_MainWindow(interp); path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, tkwin, path, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } cntrPtr = Blt_AssertCalloc(1, sizeof(Container)); cntrPtr->tkwin = tkwin; cntrPtr->display = Tk_Display(tkwin); cntrPtr->interp = interp; cntrPtr->flags = 0; cntrPtr->timeout = SEARCH_INTERVAL; cntrPtr->borderWidth = cntrPtr->highlightWidth = 2; cntrPtr->relief = TK_RELIEF_SUNKEN; Tk_SetClass(tkwin, "Container"); Blt_SetWindowInstanceData(tkwin, cntrPtr); if ((cntrPtr->flags & CONTAINER_INIT) == 0) { Tk_CreateGenericHandler(AdoptedWindowEventProc, cntrPtr); cntrPtr->flags |= CONTAINER_INIT; } { #ifdef notdef XSetWindowAttributes attr; attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask; XChangeWindowAttributes(cntrPtr->display, Tk_RootWindow(tkwin), CWEventMask, &attr); #endif XSelectInput(cntrPtr->display, DefaultRootWindow(cntrPtr->display), SubstructureNotifyMask | StructureNotifyMask); } if (ConfigureContainer(interp, cntrPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(cntrPtr->tkwin); return TCL_ERROR; } mask = (StructureNotifyMask | ExposureMask | FocusChangeMask); Tk_CreateEventHandler(tkwin, mask, ContainerEventProc, cntrPtr); cntrPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ContainerInstCmd, cntrPtr, ContainerInstCmdDeleteProc); Tk_MakeWindowExist(tkwin); Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DisplayContainer -- * * This procedure is invoked to display the widget. * * Results: * None. * * Side effects: * The widget is redisplayed. * *--------------------------------------------------------------------------- */ static void DisplayContainer(ClientData clientData) { Container *cntrPtr = clientData; Drawable drawable; int width, height; cntrPtr->flags &= ~CONTAINER_REDRAW; if (cntrPtr->tkwin == NULL) { return; /* Window has been destroyed. */ } if (!Tk_IsMapped(cntrPtr->tkwin)) { return; } drawable = Tk_WindowId(cntrPtr->tkwin); #ifndef WIN32 if (cntrPtr->tkToplevel == NULL) { Window window; Tk_Window tkToplevel; /* Create an event handler for the toplevel of the container. */ tkToplevel = Blt_Toplevel(cntrPtr->tkwin); window = Blt_GetWindowId(tkToplevel); cntrPtr->tkToplevel = Tk_IdToWindow(cntrPtr->display, window); if (cntrPtr->tkToplevel != NULL) { Tk_CreateEventHandler(cntrPtr->tkToplevel, StructureNotifyMask, ToplevelEventProc, cntrPtr); } } #endif /* WIN32 */ if (cntrPtr->adopted != None) { #ifndef WIN32 if (cntrPtr->flags & CONTAINER_MOVE) { /* * Some applications like Netscape cache its location to * position its popup menus. But when it's reparented, it * thinks it's always at the same position. It doesn't * know when the container's moved. The hack here is to * force the application to update its coordinates by * moving the adopted window (over by 1 pixel and * then back in case the application is comparing the last * location). */ XMoveWindow(cntrPtr->display, cntrPtr->adopted, cntrPtr->inset + 1, cntrPtr->inset + 1); XMoveWindow(cntrPtr->display, cntrPtr->adopted, cntrPtr->inset, cntrPtr->inset); cntrPtr->flags &= ~CONTAINER_MOVE; } #endif /* WIN32 */ /* Compute the available space inside the container. */ width = Tk_Width(cntrPtr->tkwin) - (2 * cntrPtr->inset); height = Tk_Height(cntrPtr->tkwin) - (2 * cntrPtr->inset); if ((cntrPtr->adoptedX != cntrPtr->inset) || (cntrPtr->adoptedY != cntrPtr->inset) || (cntrPtr->adoptedWidth != width) || (cntrPtr->adoptedHeight != height)) { /* Resize the window to the new size */ if (width < 1) { width = 1; } if (height < 1) { height = 1; } XMoveResizeWindow(cntrPtr->display, cntrPtr->adopted, cntrPtr->inset, cntrPtr->inset, width, height); cntrPtr->adoptedWidth = width; cntrPtr->adoptedHeight = height; cntrPtr->adoptedX = cntrPtr->adoptedY = cntrPtr->inset; if (cntrPtr->tkAdopted != NULL) { Tk_ResizeWindow(cntrPtr->tkAdopted, width, height); } } #ifndef WIN32 if (!(cntrPtr->flags & CONTAINER_MAPPED)) { XMapWindow(cntrPtr->display, cntrPtr->adopted); cntrPtr->flags |= CONTAINER_MAPPED; } #endif if (cntrPtr->borderWidth > 0) { Blt_Draw3DRectangle(cntrPtr->tkwin, drawable, cntrPtr->border, cntrPtr->highlightWidth, cntrPtr->highlightWidth, Tk_Width(cntrPtr->tkwin) - 2 * cntrPtr->highlightWidth, Tk_Height(cntrPtr->tkwin) - 2 * cntrPtr->highlightWidth, cntrPtr->borderWidth, cntrPtr->relief); } } else { Blt_Fill3DRectangle(cntrPtr->tkwin, drawable, cntrPtr->border, cntrPtr->highlightWidth, cntrPtr->highlightWidth, Tk_Width(cntrPtr->tkwin) - 2 * cntrPtr->highlightWidth, Tk_Height(cntrPtr->tkwin) - 2 * cntrPtr->highlightWidth, cntrPtr->borderWidth, cntrPtr->relief); } /* Draw focus highlight ring. */ if (cntrPtr->highlightWidth > 0) { XColor *color; GC gc; color = (cntrPtr->flags & CONTAINER_FOCUS) ? cntrPtr->highlightColor : cntrPtr->highlightBgColor; gc = Tk_GCForColor(color, drawable); Tk_DrawFocusHighlight(cntrPtr->tkwin, gc, cntrPtr->highlightWidth, drawable); } } #ifdef notdef /* *--------------------------------------------------------------------------- * * SendOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SendOp(cntrPtr, interp, objc, objv) Container *cntrPtr; Tcl_Interp *interp; int objc; /* Not used. */ Tcl_Obj *const *objv; { if (cntrPtr->adopted != None) { XEvent event; char *p; KeySym symbol; int xid; Window window; if (Tcl_GetIntFromObj(interp, objv[2], &xid) != TCL_OK) { return TCL_ERROR; } window = (Window)xid; event.xkey.type = KeyPress; event.xkey.serial = 0; event.xkey.display = cntrPtr->display; event.xkey.window = event.xkey.subwindow = window; event.xkey.time = CurrentTime; event.xkey.x = event.xkey.x = 100; event.xkey.root = Tk_RootWindow(cntrPtr->tkwin); event.xkey.x_root = Tk_X(cntrPtr->tkwin) + cntrPtr->inset; event.xkey.x_root = Tk_Y(cntrPtr->tkwin) + cntrPtr->inset; event.xkey.state = 0; event.xkey.same_screen = TRUE; for (p = Tcl_GetString(objv[3]); *p != '\0'; p++) { if (*p == '\r') { symbol = XStringToKeysym("Return"); } else if (*p == ' ') { symbol = XStringToKeysym("space"); } else { char save; save = *(p+1); *(p+1) = '\0'; symbol = XStringToKeysym(p); *(p+1) = save; } event.xkey.keycode = XKeysymToKeycode(cntrPtr->display, symbol); event.xkey.type = KeyPress; if (!XSendEvent(cntrPtr->display, window, False, KeyPress, &event)) { fprintf(stderr, "send press event failed\n"); } event.xkey.type = KeyRelease; if (!XSendEvent(cntrPtr->display, window, False, KeyRelease, &event)) { fprintf(stderr, "send release event failed\n"); } } } return TCL_OK; } #endif #ifndef WIN32 /* *--------------------------------------------------------------------------- * * FindOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FindOp( Container *cntrPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Window root; SearchInfo search; char *string; memset(&search, 0, sizeof(search)); search.pattern = Tcl_GetString(objv[3]); Tcl_DStringInit(&search.dString); search.saveNames = TRUE; /* Indicates to record all matching XIDs. */ string = Tcl_GetString(objv[2]); if (strcmp(string, "-name") == 0) { search.proc = NameSearch; } else if (strcmp(string, "-command") == 0) { search.proc = CmdSearch; } else { Tcl_AppendResult(interp, "missing \"-name\" or \"-command\" switch", (char *)NULL); return TCL_ERROR; } root = Tk_RootWindow(cntrPtr->tkwin); (*search.proc)(cntrPtr->display, root, &search); Tcl_DStringResult(interp, &search.dString); return TCL_OK; } #endif /*WIN32*/ /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp( Container *cntrPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, cntrPtr->tkwin, configSpecs, (char *)cntrPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or reconfigure) * the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, * etc. get set for cntrPtr; old resources get freed, if there * were any. The widget is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp( Container *cntrPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, cntrPtr->tkwin, configSpecs, (char *)cntrPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, cntrPtr->tkwin, configSpecs, (char *)cntrPtr, objv[2], 0); } if (ConfigureContainer(interp, cntrPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } EventuallyRedraw(cntrPtr); return TCL_OK; } #ifndef WIN32 static int IgnoreErrors(Display *display, XErrorEvent *eventPtr) { return 0; } static int GetAtomName(Display *display, Atom atom, char **namePtr) { char *atomName; XErrorHandler handler; static char name[200]; int result; handler = XSetErrorHandler(IgnoreErrors); atomName = XGetAtomName(display, atom); XSetErrorHandler(handler); name[0] = '\0'; if (atomName == NULL) { sprintf(name, "undefined atom # 0x%lx", atom); result = FALSE; } else { size_t length = strlen(atomName); if (length > 200) { length = 200; } memcpy(name, atomName, length); name[length] = '\0'; XFree(atomName); result = TRUE; } *namePtr = name; return result; } static void FillTree(Container *cntrPtr, Window window, Blt_Tree tree, Blt_TreeNode parent) { char string[200]; Atom *atoms; int i; int nProps; Blt_Chain chain; /* Process the window's descendants. */ atoms = XListProperties(cntrPtr->display, window, &nProps); for (i = 0; i < nProps; i++) { char *name; if (GetAtomName(cntrPtr->display, atoms[i], &name)) { char *data; int result, format; Atom typeAtom; unsigned long nItems, bytesAfter; result = XGetWindowProperty( cntrPtr->display, /* Display of window. */ window, /* Window holding the property. */ atoms[i], /* Name of property. */ 0, /* Offset of data (for multiple reads). */ GetMaxPropertySize(cntrPtr->display), /* Maximum number of items to read. */ False, /* If true, delete the property. */ XA_STRING, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the property. */ &nItems, /* (out) # of items in specified format. */ &bytesAfter, /* (out) # of bytes remaining to be read. */ (unsigned char **)&data); #ifdef notdef fprintf(stderr, "%x: property name is %s (format=%d(%d) type=%d result=%d)\n", window, name, format, nItems, typeAtom, result == Success); #endif if (result == Success) { if (format == 8) { if (data != NULL) { Blt_Tree_SetValue(cntrPtr->interp, tree, parent, name, Tcl_NewStringObj(data, nItems)); } } else if (typeAtom == XA_WINDOW) { int *iPtr = (int *)&data; sprintf(string, "0x%x", *iPtr); Blt_Tree_SetValue(cntrPtr->interp, tree, parent, name, Tcl_NewStringObj(string, -1)); } else { Blt_Tree_SetValue(cntrPtr->interp, tree, parent, name, Tcl_NewStringObj("???", -1)); } XFree(data); } } } if (atoms != NULL) { XFree(atoms); } chain = GetChildren(cntrPtr->display, window); if (chain != NULL) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Blt_TreeNode child; char *wmName; Window w; w = (Window)Blt_Chain_GetValue(link); sprintf(string, "0x%x", (int)w); if (XFetchName(cntrPtr->display, w, &wmName)) { child = Blt_Tree_CreateNode(tree, parent, wmName, -1); if (w == 0x220001c) { fprintf(stderr, "found xterm (%s)\n", wmName); } XFree(wmName); } else { child = Blt_Tree_CreateNode(tree, parent, string, -1); } if (w == 0x220001c) { fprintf(stderr, "found xterm (%s) node=%ld\n", string, (long)Blt_Tree_NodeId(child)); } Blt_Tree_SetValue(cntrPtr->interp, tree, child, "id", Tcl_NewStringObj(string, -1)); FillTree(cntrPtr, w, tree, child); } Blt_Chain_Destroy(chain); } } /* *--------------------------------------------------------------------------- * * TreeOp -- * * .c tree $tree *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeOp( Container *cntrPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Window root; Blt_TreeNode node; char string[200]; Blt_Tree tree; tree = Blt_Tree_Open(interp, Tcl_GetString(objv[2]), 0); if (tree == NULL) { return TCL_ERROR; } node = Blt_Tree_RootNode(tree); Blt_Tree_RelabelNode(tree, node, "root"); root = Tk_RootWindow(cntrPtr->tkwin); sprintf(string, "0x%ux", (unsigned int)root); Blt_Tree_SetValue(interp, tree, node, "id", Tcl_NewStringObj(string, -1)); FillTree(cntrPtr, root, tree, node); Blt_Tree_Close(tree); return TCL_OK; } #endif /*WIN32*/ /* *--------------------------------------------------------------------------- * * ContainerCmd -- * * This procedure is invoked to process the "container" command. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec opSpecs[] = { {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, #ifndef WIN32 {"find", 1, FindOp, 3, 4, "?-command|-name? pattern",}, #endif /*WIN32*/ #ifdef notdef {"send", 1, SendOp, 4, 4, "window string",}, #endif #ifndef WIN32 {"tree", 1, TreeOp, 3, 3, "treeName",}, #endif /*WIN32*/ }; static int nSpecs = sizeof(opSpecs) / sizeof(Blt_OpSpec); static int ContainerInstCmd( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Vector of argument strings. */ { ContainerCmdProc *proc; Container *cntrPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nSpecs, opSpecs, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(cntrPtr); result = (*proc)(cntrPtr, interp, objc, objv); Tcl_Release(cntrPtr); return result; } int Blt_ContainerCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "container", ContainerCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_CONTAINER */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltInt.h����������������������������������������������������������������������0000644�0001750�0001750�00000066177�11502726613�014464� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltInt.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_INT_H #define _BLT_INT_H #undef SIZEOF_LONG #include "config.h" #include "blt.h" #undef BLT_STORAGE_CLASS #define BLT_STORAGE_CLASS DLLEXPORT #define _VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #define _TCL_VERSION _VERSION(TCL_MAJOR_VERSION, TCL_MINOR_VERSION, TCL_RELEASE_SERIAL) #define _TK_VERSION _VERSION(TK_MAJOR_VERSION, TK_MINOR_VERSION, TK_RELEASE_SERIAL) #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) # define __WIN32__ # ifndef WIN32 # define WIN32 # endif # endif #endif #ifdef _MSC_VER # define _CRT_SECURE_NO_DEPRECATE # define _CRT_NONSTDC_NO_DEPRECATE #endif #ifdef WIN32 # define STRICT # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef STRICT # undef WIN32_LEAN_AND_MEAN # include <windowsx.h> #endif /* WIN32 */ #include <tcl.h> #ifdef USE_TCL_STUBS # include "tclIntDecls.h" # ifdef WIN32 # include "tclIntPlatDecls.h" # endif #endif /* USE_TCL_STUBS */ #define USE_COMPOSITELESS_PHOTO_PUT_BLOCK #include <tk.h> #ifdef USE_TK_STUBS # include "tkIntDecls.h" # ifdef WIN32 # include "tkPlatDecls.h" # include "tkIntXlibDecls.h" # endif #endif /* USE_TK_STUBS */ #include <stdio.h> #ifdef WIN32 # ifndef __GNUC__ # ifdef O_NONBLOCK # define O_NONBLOCK 1 # endif # endif /* __GNUC__ */ #endif /* WIN32 */ #ifdef HAVE_STDLIB_H # include <stdlib.h> #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDDEF_H # include <stddef.h> #endif /* HAVE_STDDEF_H */ #ifdef HAVE_ERRNO_H # include <errno.h> #endif /* HAVE_ERRNO_H */ #ifdef HAVE_CTYPE_H # include <ctype.h> #endif /* HAVE_CTYPE_H */ #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* HAVE_UNISTD_H */ #ifdef HAVE_LIMITS_H # include <limits.h> #endif #include "bltMath.h" #include "bltString.h" #undef INLINE #ifdef __GNUC__ # define INLINE __inline__ #else # define INLINE #endif #if defined(__GNUC__) && defined(HAVE_X86) && defined(__OPTIMIZE__) # define HAVE_X86_ASM #endif #undef VARARGS #ifdef __cplusplus # define ANYARGS (...) # define VARARGS(first) (first, ...) # define VARARGS2(first, second) (first, second, ...) #else # define ANYARGS () # define VARARGS(first) () # define VARARGS2(first, second) () #endif /* __cplusplus */ #undef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #undef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #undef MIN3 #define MIN3(a,b,c) (((a)<(b))?(((a)<(c))?(a):(c)):(((b)<(c))?(b):(c))) #undef MAX3 #define MAX3(a,b,c) (((a)>(b))?(((a)>(c))?(a):(c)):(((b)>(c))?(b):(c))) #define TRUE 1 #define FALSE 0 /* * The macro below is used to modify a "char" value (e.g. by casting * it to an unsigned character) so that it can be used safely with * macros such as isspace. */ #define UCHAR(c) ((unsigned char) (c)) #define BLT_ANCHOR_TOP (TK_ANCHOR_CENTER+1) #define BLT_ANCHOR_BOTTOM (TK_ANCHOR_CENTER+2) #define BLT_ANCHOR_LEFT (TK_ANCHOR_CENTER+3) #define BLT_ANCHOR_RIGHT (TK_ANCHOR_CENTER+4) /* *--------------------------------------------------------------------------- * * Blt_InitCmdSpec -- * *--------------------------------------------------------------------------- */ typedef struct { const char *name; /* Name of command */ Tcl_ObjCmdProc *cmdProc; Tcl_CmdDeleteProc *cmdDeleteProc; ClientData clientData; } Blt_InitCmdSpec; BLT_EXTERN int Blt_DictionaryCompare (const char *s1, const char *s2); BLT_EXTERN void Blt_Draw3DRectangle(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); BLT_EXTERN void Blt_Fill3DRectangle(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* ---------------------------------------------------------------- */ #define PIXELS_NNEG 0 #define PIXELS_POS 1 #define PIXELS_ANY 2 #define COUNT_NNEG 0 #define COUNT_POS 1 #define COUNT_ANY 2 #define BLT_SCROLL_MODE_CANVAS (1<<0) #define BLT_SCROLL_MODE_LISTBOX (1<<1) #define BLT_SCROLL_MODE_HIERBOX (1<<2) #define RGB_ANTIQUEWHITE1 "#ffefdb" #define RGB_BISQUE1 "#ffe4c4" #define RGB_BISQUE2 "#eed5b7" #define RGB_BISQUE3 "#cdb79e" #define RGB_BLACK "#000000" #define RGB_BLUE "#0000ff" #define RGB_GREEN "#00ff00" #define RGB_GREY "#b0b0b0" #define RGB_GREY15 "#262626" #define RGB_GREY20 "#333333" #define RGB_GREY25 "#404040" #define RGB_GREY30 "#4d4d4d" #define RGB_GREY35 "#595959" #define RGB_GREY40 "#666666" #define RGB_GREY50 "#7f7f7f" #define RGB_GREY64 "#a3a3a3" #define RGB_GREY70 "#b3b3b3" #define RGB_GREY75 "#bfbfbf" #define RGB_GREY77 "#c3c3c3" #define RGB_GREY82 "#d1d1d1" #define RGB_GREY85 "#d9d9d9" #define RGB_GREY90 "#e5e5e5" #define RGB_GREY93 "#ececec" #define RGB_GREY95 "#f2f2f2" #define RGB_GREY97 "#f7f7f7" #define RGB_LIGHTBLUE0 "#e4f7ff" #define RGB_LIGHTBLUE00 "#D9F5FF" #define RGB_LIGHTBLUE1 "#bfefff" #define RGB_LIGHTBLUE2 "#b2dfee" #define RGB_LIGHTSKYBLUE1 "#b0e2ff" #define RGB_MAROON "#b03060" #define RGB_NAVYBLUE "#000080" #define RGB_PINK "#ffc0cb" #define RGB_BISQUE1 "#ffe4c4" #define RGB_RED "#ff0000" #define RGB_RED3 "#cd0000" #define RGB_WHITE "#ffffff" #define RGB_YELLOW "#ffff00" #define RGB_SKYBLUE4 "#4a708b" #ifdef OLD_TK_COLORS #define STD_NORMAL_BACKGROUND RGB_BISQUE1 #define STD_ACTIVE_BACKGROUND RGB_BISQUE2 #define STD_SELECT_BACKGROUND RGB_LIGHTBLUE1 #define STD_SELECT_FOREGROUND RGB_BLACK #else #define STD_NORMAL_BACKGROUND RGB_GREY85 #define STD_ACTIVE_BACKGROUND RGB_GREY90 #define STD_SELECT_BACKGROUND RGB_SKYBLUE4 #define STD_SELECT_FOREGROUND RGB_WHITE #endif /* OLD_TK_COLORS */ #define STD_ACTIVE_BG_MONO RGB_BLACK #define STD_ACTIVE_FOREGROUND RGB_BLACK #define STD_ACTIVE_FG_MONO RGB_WHITE #define STD_BORDERWIDTH "2" #define STD_FONT_HUGE "{Sans Serif} 18" #define STD_FONT_LARGE "{Sans Serif} 14" #define STD_FONT_MEDIUM "{Sans Serif} 11" #define STD_FONT_NORMAL "{Sans Serif} 9" #define STD_FONT_SMALL "{Sans Serif} 8" #define STD_FONT_NUMBERS "Math 8" #define STD_FONT STD_FONT_NORMAL #define STD_INDICATOR_COLOR RGB_RED3 #define STD_NORMAL_BG_MONO RGB_WHITE #define STD_NORMAL_FOREGROUND RGB_BLACK #define STD_NORMAL_FG_MONO RGB_BLACK #define STD_SELECT_BG_MONO RGB_BLACK #define STD_SELECT_BORDERWIDTH "2" #define STD_SELECT_FG_MONO RGB_WHITE #define STD_SHADOW_MONO RGB_BLACK #define STD_SELECT_FONT_HUGE "{Sans Serif} 18 Bold" #define STD_SELECT_FONT_LARGE "{Sans Serif} 14 Bold" #define STD_SELECT_FONT_MEDIUM "{Sans Serif} 11 Bold" #define STD_SELECT_FONT_NORMAL "{Sans Serif} 9 Bold" #define STD_SELECT_FONT_SMALL "{Sans Serif} 8 Bold" #define STD_SELECT_FONT STD_SELECT_FONT_NORMAL #define STD_DISABLED_FOREGROUND RGB_GREY70 #define STD_DISABLED_BACKGROUND RGB_GREY90 #define LineWidth(w) (((w) > 1) ? (w) : 0) typedef char *Blt_Uid; BLT_EXTERN Blt_Uid Blt_GetUid(const char *string); BLT_EXTERN void Blt_FreeUid(Blt_Uid uid); BLT_EXTERN Blt_Uid Blt_FindUid(const char *string); #ifdef TCL_UTF_MAX # define HAVE_UTF 1 #else # define HAVE_UTF 0 #endif /* TCL_UTF_MAX */ #include <bltAlloc.h> typedef char *DestroyData; #ifndef TK_RELIEF_SOLID # define TK_RELIEF_SOLID TK_RELIEF_FLAT #endif typedef int (QSortCompareProc) (const void *, const void *); /* *--------------------------------------------------------------------------- * * Point2 -- * * 2-D coordinate. * *--------------------------------------------------------------------------- */ typedef struct { double x, y; } Point2d; typedef struct { float x, y; } Point2f; typedef struct { int x, y; } Point2i; typedef struct { size_t nValues; void *values; } Array; /* *--------------------------------------------------------------------------- * * Point3D -- * * 3-D coordinate. * *--------------------------------------------------------------------------- */ typedef struct { double x, y, z; } Point3D; /* *--------------------------------------------------------------------------- * * Segment2 -- * * 2-D line segment. * *--------------------------------------------------------------------------- */ typedef struct { Point2f p, q; /* The two end points of the segment. */ } Segment2f; typedef struct { Point2d p, q; /* The two end points of the segment. */ } Segment2d; /* *--------------------------------------------------------------------------- * * Dim2D -- * * 2-D dimension. * *--------------------------------------------------------------------------- */ typedef struct { short int width, height; } Dim2D; /* *--------------------------------------------------------------------------- * * Region2d -- * * 2-D region. Used to copy parts of images. * *--------------------------------------------------------------------------- */ typedef struct { float left, right, top, bottom; } Region2f; typedef struct { double left, right, top, bottom; } Region2d; typedef struct { double left, right, top, bottom, front, back; } Region3D; #define RegionWidth(r) ((r)->right - (r)->left + 1) #define RegionHeight(r) ((r)->bottom - (r)->top + 1) #define PointInRegion(e,x,y) \ (((x) <= (e)->right) && ((x) >= (e)->left) && \ ((y) <= (e)->bottom) && ((y) >= (e)->top)) #define PointInRectangle(r,x0,y0) \ (((x0) <= (int)((r)->x + (r)->width - 1)) && ((x0) >= (int)(r)->x) && \ ((y0) <= (int)((r)->y + (r)->height - 1)) && ((y0) >= (int)(r)->y)) /*------------------------------------------------------------------------------- * * ColorPair -- * * Holds a pair of foreground, background colors. * *--------------------------------------------------------------------------- */ typedef struct { XColor *fgColor, *bgColor; } ColorPair; #define COLOR_NONE (XColor *)0 #define COLOR_DEFAULT (XColor *)1 #define COLOR_ALLOW_DEFAULTS 1 BLT_EXTERN int Blt_GetColorPair (Tcl_Interp *interp, Tk_Window tkwin, char *fgColor, char *bgColor, ColorPair *pairPtr, int colorFlag); BLT_EXTERN void Blt_FreeColorPair (ColorPair *pairPtr); #define ARROW_LEFT (0) #define ARROW_UP (1) #define ARROW_RIGHT (2) #define ARROW_DOWN (3) #define ARROW_OFFSET 4 #define STD_ARROW_HEIGHT 3 #define STD_ARROW_WIDTH ((2 * (ARROW_OFFSET - 1)) + 1) /* *--------------------------------------------------------------------------- * * X11/Xosdefs.h requires XNOSTDHDRS be set for some systems. This is a * guess. If I can't find STDC headers or unistd.h, assume that this is * non-POSIX and non-STDC environment. (needed for Encore Umax 3.4 ?) * *--------------------------------------------------------------------------- */ #if !defined(STDC_HEADERS) && !defined(HAVE_UNISTD_H) # define XNOSTDHDRS 1 #endif BLT_EXTERN FILE *Blt_OpenFile(Tcl_Interp *interp, const char *fileName, const char *mode); BLT_EXTERN int Blt_ExprDoubleFromObj (Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr); BLT_EXTERN int Blt_ExprIntFromObj (Tcl_Interp *interp, Tcl_Obj *objPtr, int *valuePtr); BLT_EXTERN const char *Blt_Itoa(int value); BLT_EXTERN const char *Blt_Ltoa(long value); BLT_EXTERN const char *Blt_Utoa(unsigned int value); BLT_EXTERN const char *Blt_Dtoa(Tcl_Interp *interp, double value); BLT_EXTERN unsigned char *Blt_Base64_Decode(Tcl_Interp *interp, const char *string, size_t *lengthPtr); BLT_EXTERN char *Blt_Base64_Encode(Tcl_Interp *interp, const unsigned char *buffer, size_t bufsize); BLT_EXTERN int Blt_IsBase64(const unsigned char *buf, size_t length); BLT_EXTERN int Blt_InitCmd (Tcl_Interp *interp, const char *namespace, Blt_InitCmdSpec *specPtr); BLT_EXTERN int Blt_InitCmds (Tcl_Interp *interp, const char *namespace, Blt_InitCmdSpec *specPtr, int nCmds); BLT_EXTERN int Blt_GlobalEvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_GlobalEvalListObj(Tcl_Interp *interp, Tcl_Obj *cmdObjPtr); BLT_EXTERN int Blt_GetDoubleFromString(Tcl_Interp *interp, const char *s, double *valuePtr); BLT_EXTERN int Blt_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr); #ifdef WIN32 typedef struct { DWORD pid; HANDLE hProcess; } ProcessId; #else typedef pid_t ProcessId; #endif BLT_EXTERN int Blt_CreatePipeline(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ProcessId **pidArrayPtr, int *stdinPipePtr, int *stdoutPipePtr, int *stderrPipePtr); BLT_EXTERN void Blt_GetLineExtents(size_t nPoints, Point2d *points, Region2d *r); BLT_EXTERN int Blt_LineRectClip(Region2d *regionPtr, Point2d *p, Point2d *q); #if (_TCL_VERSION < _VERSION(8,1,0)) BLT_EXTERN const char *Tcl_GetString (Tcl_Obj *objPtr); BLT_EXTERN int Tcl_EvalObjv (Tcl_Interp *interp, int objc, Tcl_Obj **objv, int flags); BLT_EXTERN int Tcl_WriteObj (Tcl_Channel channel, Tcl_Obj *objPtr); BLT_EXTERN char *Tcl_SetVar2Ex (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *objPtr, int flags); BLT_EXTERN Tcl_Obj *Tcl_GetVar2Ex (Tcl_Interp *interp, const char *part1, const char *part2, int flags); #endif /* _TCL_VERSION < 8.1.0 */ BLT_EXTERN int Blt_NaturalSpline (Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts); BLT_EXTERN int Blt_QuadraticSpline (Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts); BLT_EXTERN int Blt_SimplifyLine (Point2d *origPts, int low, int high, double tolerance, int *indices); BLT_EXTERN int Blt_NaturalParametricSpline (Point2d *origPts, int nOrigPts, Region2d *extsPtr, int isClosed, Point2d *intpPts, int nIntpPts); BLT_EXTERN int Blt_CatromParametricSpline (Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts); BLT_EXTERN int Blt_StringToFlag (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec, int flags); BLT_EXTERN char *Blt_FlagToString (ClientData clientData, Tk_Window tkwin, char *string, int offset, Tcl_FreeProc **freeProc); BLT_EXTERN void Blt_InitHexTable (unsigned char *table); BLT_EXTERN GC Blt_GetPrivateGC(Tk_Window tkwin, unsigned long gcMask, XGCValues *valuePtr); BLT_EXTERN GC Blt_GetPrivateGCFromDrawable(Display *display, Drawable drawable, unsigned long gcMask, XGCValues *valuePtr); BLT_EXTERN void Blt_FreePrivateGC(Display *display, GC gc); BLT_EXTERN int Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr); BLT_EXTERN Window Blt_GetParentWindow(Display *display, Window window); BLT_EXTERN Tk_Window Blt_FindChild(Tk_Window parent, char *name); BLT_EXTERN Tk_Window Blt_FirstChild(Tk_Window parent); BLT_EXTERN Tk_Window Blt_NextChild(Tk_Window tkwin); BLT_EXTERN void Blt_RelinkWindow (Tk_Window tkwin, Tk_Window newParent, int x, int y); BLT_EXTERN Tk_Window Blt_Toplevel(Tk_Window tkwin); BLT_EXTERN Tk_Window Blt_GetToplevelWindow(Tk_Window tkwin); BLT_EXTERN int Blt_GetPixels(Tcl_Interp *interp, Tk_Window tkwin, const char *string, int check, int *valuePtr); BLT_EXTERN int Blt_GetPosition(Tcl_Interp *interp, const char *string, long *valuePtr); BLT_EXTERN int Blt_GetCount(Tcl_Interp *interp, const char *string, int check, long *valuePtr); BLT_EXTERN int Blt_GetCountFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int check, long *valuePtr); BLT_EXTERN const char *Blt_NameOfFill(int fill); BLT_EXTERN const char *Blt_NameOfResize(int resize); BLT_EXTERN int Blt_GetXY (Tcl_Interp *interp, Tk_Window tkwin, const char *string, int *xPtr, int *yPtr); BLT_EXTERN Point2d Blt_GetProjection (int x, int y, Point2d *p, Point2d *q); BLT_EXTERN void Blt_DrawArrowOld(Display *display, Drawable drawable, GC gc, int x, int y, int w, int h, int borderWidth, int orientation); BLT_EXTERN void Blt_DrawArrow (Display *display, Drawable drawable, XColor *color, int x, int y, int w, int h, int borderWidth, int orientation); BLT_EXTERN int Blt_OldConfigModified TCL_VARARGS(Tk_ConfigSpec *, specs); BLT_EXTERN void Blt_DStringAppendElements TCL_VARARGS(Tcl_DString *, args); BLT_EXTERN void Blt_MakeTransparentWindowExist (Tk_Window tkwin, Window parent, int isBusy); BLT_EXTERN Window Blt_GetParent (Display *display, Window tkwin); BLT_EXTERN void Blt_GetBoundingBox (int width, int height, float angle, double *widthPtr, double *heightPtr, Point2d *points); BLT_EXTERN void Blt_InitEpsCanvasItem (Tcl_Interp *interp); BLT_EXTERN void Blt_TranslateAnchor (int x, int y, int width, int height, Tk_Anchor anchor, int *transXPtr, int *transYPtr); BLT_EXTERN Point2d Blt_AnchorPoint (double x, double y, double width, double height, Tk_Anchor anchor); BLT_EXTERN void Blt_HSV (XColor *colorPtr, double *huePtr, double *valPtr, double *satPtr); BLT_EXTERN void Blt_RGB (double hue, double sat, double val, XColor *colorPtr); BLT_EXTERN int Blt_ParseFlag (ClientData, Tcl_Interp *, Tk_Window, char *, char *, int); BLT_EXTERN char *Blt_FlagPrint (ClientData, Tk_Window, char *, int, Tcl_FreeProc **); BLT_EXTERN long Blt_MaxRequestSize (Display *display, size_t elemSize); BLT_EXTERN Window Blt_GetWindowId (Tk_Window tkwin); BLT_EXTERN void Blt_InitXRandrConfig(Tcl_Interp *interp); BLT_EXTERN void Blt_SizeOfScreen(Tk_Window tkwin, int *widthPtr,int *heightPtr); BLT_EXTERN int Blt_RootX (Tk_Window tkwin); BLT_EXTERN int Blt_RootY (Tk_Window tkwin); BLT_EXTERN void Blt_RootCoordinates (Tk_Window tkwin, int x, int y, int *rootXPtr, int *rootYPtr); BLT_EXTERN void Blt_MapToplevelWindow(Tk_Window tkwin); BLT_EXTERN void Blt_UnmapToplevelWindow(Tk_Window tkwin); BLT_EXTERN void Blt_RaiseToplevelWindow(Tk_Window tkwin); BLT_EXTERN void Blt_LowerToplevelWindow(Tk_Window tkwin); BLT_EXTERN void Blt_ResizeToplevelWindow(Tk_Window tkwin, int w, int h); BLT_EXTERN void Blt_MoveToplevelWindow(Tk_Window tkwin, int x, int y); BLT_EXTERN void Blt_MoveResizeToplevelWindow(Tk_Window tkwin, int x, int y, int w, int h); BLT_EXTERN int Blt_GetWindowRegion(Display *display, Window window, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); BLT_EXTERN ClientData Blt_GetWindowInstanceData (Tk_Window tkwin); BLT_EXTERN void Blt_SetWindowInstanceData (Tk_Window tkwin, ClientData instanceData); BLT_EXTERN void Blt_DeleteWindowInstanceData (Tk_Window tkwin); BLT_EXTERN int Blt_AdjustViewport (int offset, int worldSize, int windowSize, int scrollUnits, int scrollMode); BLT_EXTERN int Blt_GetScrollInfoFromObj (Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int *offsetPtr, int worldSize, int windowSize, int scrollUnits, int scrollMode); BLT_EXTERN void Blt_UpdateScrollbar(Tcl_Interp *interp, Tcl_Obj *scrollCmdObjPtr, int first, int last, int width); BLT_EXTERN int Blt_ReparentWindow (Display *display, Window window, Window newParent, int x, int y); BLT_EXTERN int Blt_LoadLibrary(Tcl_Interp *interp, const char *libPath, const char *initProcName, const char *safeProcName); extern void Blt_RegisterPictureImageType(Tcl_Interp *interp); extern int Blt_CpuFeatures(Tcl_Interp *interp, int *featuresPtr); extern void Blt_RegisterEpsCanvasItem(void); typedef struct { Drawable id; unsigned short int width, height; int depth; Colormap colormap; Visual *visual; } Blt_DrawableAttributes; BLT_EXTERN Blt_DrawableAttributes *Blt_GetDrawableAttribs(Display *display, Drawable drawable); BLT_EXTERN void Blt_SetDrawableAttribs(Display *display, Drawable drawable, int width, int height, int depth, Colormap colormap, Visual *visual); BLT_EXTERN void Blt_SetDrawableAttribsFromWindow(Tk_Window tkwin, Drawable drawable); BLT_EXTERN void Blt_FreeDrawableAttribs(Display *display, Drawable drawable); BLT_EXTERN GC Blt_GetBitmapGC(Tk_Window tkwin); #define Tk_RootWindow(tkwin) \ RootWindow(Tk_Display(tkwin),Tk_ScreenNumber(tkwin)) #ifndef WIN32 # define PurifyPrintf printf #endif /* WIN32 */ #include "bltConfig.h" #define NO_AFM 1 #define NO_BASE64 1 #define NO_BEEP 1 #define NO_BGEXEC 1 #define NO_BGPATTER 1 #define NO_BITMAP 1 #define NO_COMBOTREE 1 #define NO_CONTAINER 1 #define NO_CRC32 1 #define NO_CSV 1 #define NO_CUTBUFFER 1 #define NO_DATATABLE 1 #define NO_DEBUG 1 #define NO_DDE 1 #define NO_DND 1 #define NO_DRAGDROP 1 #define NO_HIERBOX 1 #define NO_HIERTABLE 1 #define NO_HTEXT 1 #define NO_MOUNTAIN 1 #define NO_PANESET 1 #define NO_PICTURE 1 #define NO_PRINTER 1 #define NO_PTYEXEC 1 #define NO_SENDEVENT 1 #define NO_SCROLLSET 1 #define NO_SPLINE 1 #define NO_TABSET 1 #define NO_TABLEMGR 1 #define NO_TED #define NO_TKFRAME 1 #define NO_TKBUTTON 1 #define NO_TKSCROLLBAR 1 #define NO_TREE 1 #define NO_TREEVIEW 1 #define NO_WATCH 1 #define NO_WINOP 1 /* * Define this if you want to be able to tile to the main window "." This * will cause a conflict with Tk if you try to compile and link statically. */ #undef TK_MAINWINDOW #ifdef WIN32 # define NO_PTYEXEC 1 # define NO_CUTBUFFER 1 # define NO_DND 1 #else # define NO_DDE 1 # define NO_PRINTER 1 # ifdef MACOSX # define NO_BUSY 1 # define NO_CONTAINER 1 # endif #endif /* WIN32 */ #ifndef NO_BASE64 BLT_EXTERN Tcl_AppInitProc Blt_Base64CmdInitProc; #endif #ifndef NO_BEEP BLT_EXTERN Tcl_AppInitProc Blt_BeepCmdInitProc; #endif #ifndef NO_BGEXEC BLT_EXTERN Tcl_AppInitProc Blt_BgexecCmdInitProc; #endif #ifndef NO_PTYEXEC BLT_EXTERN Tcl_AppInitProc Blt_PtyExecCmdInitProc; #endif #ifndef NO_BITMAP BLT_EXTERN Tcl_AppInitProc Blt_BitmapCmdInitProc; #endif #ifndef NO_BUSY BLT_EXTERN Tcl_AppInitProc Blt_BusyCmdInitProc; #endif #ifndef NO_CONTAINER BLT_EXTERN Tcl_AppInitProc Blt_ContainerCmdInitProc; #endif #ifndef NO_CRC32 BLT_EXTERN Tcl_AppInitProc Blt_Crc32CmdInitProc; #endif #ifndef NO_CSV BLT_EXTERN Tcl_AppInitProc Blt_CsvCmdInitProc; #endif #ifndef NO_CUTBUFFER BLT_EXTERN Tcl_AppInitProc Blt_CutbufferCmdInitProc; #endif #ifndef NO_DEBUG BLT_EXTERN Tcl_AppInitProc Blt_DebugCmdInitProc; #endif #ifndef NO_DRAGDROP BLT_EXTERN Tcl_AppInitProc Blt_DragDropCmdInitProc; #endif #ifndef NO_DND BLT_EXTERN Tcl_AppInitProc Blt_DndCmdInitProc; #endif #ifndef NO_GRAPH BLT_EXTERN Tcl_AppInitProc Blt_GraphCmdInitProc; #endif #ifndef NO_HIERBOX BLT_EXTERN Tcl_AppInitProc Blt_HierboxCmdInitProc; #endif #ifndef NO_HIERTABLE BLT_EXTERN Tcl_AppInitProc Blt_HiertableCmdInitProc; #endif #ifndef NO_HTEXT BLT_EXTERN Tcl_AppInitProc Blt_HtextCmdInitProc; #endif #ifdef WIN32 # ifndef NO_PRINTER BLT_EXTERN Tcl_AppInitProc Blt_PrinterCmdInitProc; # endif #endif #ifndef NO_AFM BLT_EXTERN Tcl_AppInitProc Blt_AfmCmdInitProc; #endif #ifndef NO_PICTURE BLT_EXTERN Tcl_AppInitProc Blt_PictureCmdInitProc; #endif #ifndef NO_TABLEMGR BLT_EXTERN Tcl_AppInitProc Blt_TableMgrCmdInitProc; #endif #ifndef NO_VECTOR BLT_EXTERN Tcl_AppInitProc Blt_VectorCmdInitProc; #endif #ifndef NO_WINOP BLT_EXTERN Tcl_AppInitProc Blt_WinopCmdInitProc; #endif #ifndef NO_WATCH BLT_EXTERN Tcl_AppInitProc Blt_WatchCmdInitProc; #endif #ifndef NO_SPLINE BLT_EXTERN Tcl_AppInitProc Blt_SplineCmdInitProc; #endif #ifndef NO_TABSET BLT_EXTERN Tcl_AppInitProc Blt_TabsetCmdInitProc; #endif #ifndef NO_DATATABLE BLT_EXTERN Tcl_AppInitProc Blt_TableCmdInitProc; #endif #ifndef NO_TREE BLT_EXTERN Tcl_AppInitProc Blt_TreeCmdInitProc; #endif #ifndef NO_TREEVIEW BLT_EXTERN Tcl_AppInitProc Blt_TreeViewCmdInitProc; #endif #ifndef NO_TKFRAME BLT_EXTERN Tcl_AppInitProc Blt_FrameCmdInitProc; #endif #ifndef NO_TKBUTTON BLT_EXTERN Tcl_AppInitProc Blt_ButtonCmdInitProc; #endif #ifndef NO_SCROLLSET BLT_EXTERN Tcl_AppInitProc Blt_ScrollsetCmdInitProc; #endif #ifndef NO_PANESET BLT_EXTERN Tcl_AppInitProc Blt_PanesetCmdInitProc; #endif #ifndef NO_TKSCROLLBAR BLT_EXTERN Tcl_AppInitProc Blt_ScrollbarCmdInitProc; #endif #ifndef NO_BGPATTERN BLT_EXTERN Tcl_AppInitProc Blt_BgPatternCmdInitProc; #endif #if (BLT_MAJOR_VERSION == 3) # ifndef NO_MOUNTAIN BLT_EXTERN Tcl_AppInitProc Blt_MountainCmdInitProc; # endif #endif #ifndef NO_TED BLT_EXTERN Tcl_AppInitProc Blt_TedCmdInitProc; #endif #ifndef NO_COMBOTREE BLT_EXTERN Tcl_AppInitProc Blt_ComboButtonInitProc; BLT_EXTERN Tcl_AppInitProc Blt_ComboEntryInitProc; BLT_EXTERN Tcl_AppInitProc Blt_ComboMenuInitProc; BLT_EXTERN Tcl_AppInitProc Blt_ComboTreeInitProc; BLT_EXTERN Tcl_AppInitProc Blt_ListViewInitProc; #endif #ifndef NO_SENDEVENT BLT_EXTERN Tcl_AppInitProc Blt_SendEventCmdInitProc; #endif #ifndef NO_DDE BLT_EXTERN Tcl_AppInitProc Blt_DdeCmdInitProc; #endif #define Tcl_GetLong(i,s,p) TclGetLong(i,s,p) #ifndef USE_TCL_STUBS BLT_EXTERN int TclGetLong(Tcl_Interp *interp, const char *s, long *longPtr); #endif #ifndef HAVE_SPRINTF_S BLT_EXTERN int sprintf_s(char *s, size_t size, const char *fmt, /*args*/ ...); #endif /* HAVE_SPRINTF_S */ BLT_EXTERN Pixmap Blt_GetPixmap(Display *dpy, Drawable draw, int w, int h, int depth, int lineNum, const char *fileName); #define Tk_GetPixmap(dpy, draw, w, h, depth) \ Blt_GetPixmap(dpy, draw, w, h, depth, __LINE__, __FILE__) #if defined(HAVE_LIBXRANDR) && defined(HAVE_X11_EXTENSIONS_RANDR_H) #define HAVE_RANDR 1 #else #define HAVE_RANDR 0 #endif #undef panic #define panic(mesg) Blt_Panic("%s:%d %s", __FILE__, __LINE__, (mesg)) BLT_EXTERN void Blt_Panic TCL_VARARGS(const char *, args); #ifdef WIN32 # include "bltWin.h" #else #ifdef MACOSX # include "bltMacOSX.h" #endif /* MACOSX */ #endif /* WIN32 */ BLT_EXTERN double Blt_NaN(void); BLT_EXTERN void Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, unsigned int *yPtr); #include <bltAlloc.h> #include <bltAssert.h> #if defined (WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TCL) typedef struct _TkRegion *TkRegion; /* Opaque type */ /* 114 */ extern TkRegion TkCreateRegion(void); /* 115 */ extern void TkDestroyRegion (TkRegion rgn); /* 116 */ extern void TkIntersectRegion (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 117 */ extern int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 118 */ extern void TkSetRegion(Display* display, GC gc, TkRegion rgn); /* 119 */ extern void TkUnionRectWithRegion(XRectangle* rect, TkRegion src, TkRegion dr_return); #else typedef struct _TkRegion *TkRegion; /* Opaque type */ #define TkClipBox(rgn, rect) XClipBox((Region) rgn, rect) #define TkCreateRegion() (TkRegion) XCreateRegion() #define TkDestroyRegion(rgn) XDestroyRegion((Region) rgn) #define TkIntersectRegion(a, b, r) XIntersectRegion((Region) a, \ (Region) b, (Region) r) #define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) r, x, y, w, h) #define TkSetRegion(d, gc, rgn) XSetRegion(d, gc, (Region) rgn) #define TkSubtractRegion(a, b, r) XSubtractRegion((Region) a, \ (Region) b, (Region) r) #define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion(rect, \ (Region) src, (Region) ret) #endif #endif /*_BLT_INT_H*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/Makefile.bc�������������������������������������������������������������������0000644�0001750�0001750�00000022242�11462120063�015053� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for BLT library using BCC55. # ------------------------------------------------------------------------ .SUFFIXES: .obj .c !include ..\win\makedefs prefix = C:\Program Files\Tcl exec_prefix = $(prefix) includedir = $(prefix)\include bindir = $(prefix)\bin libdir = $(prefix)\lib scriptdir = $(libdir)\blt$(BLT_VERSION) BLT_LIBRARY = $(libdir)\blt$(BLT_VERSION) TCLLIBPATH = $(libdir)\tcl$(v1) SHLIB_SUFFIX = .dll SHELL = bash.exe RM = -del TOOLS32 = c:\Borland\BCC55 AR = $(TOOLS32)\bin\implib.exe LD = $(TOOLS32)\bin\ilink32.exe CC = $(TOOLS32)\bin\bcc32.exe rc32 = $(TOOLS32)\bin\rc.exe !if ($(WITH_JPEG) == 0) EXTRA_DEFINES = !endif !if ($(WITH_JPEG) == 1) EXTRA_DEFINES = -DHAVE_JPEGLIB_H=1 JPEGDIR = $(srcdir)\..\..\jpeg-6b JPEGLIB = $(JPEGDIR)\libjpeg.lib JPEGINC = $(JPEGDIR) !endif !if ($(WITH_JPEG) == 2) EXTRA_DEFINES = -DHAVE_IJL_H=1 JPEGDIR = c:\Program\ Files\Intel\IJL JPEGLIB = $(JPEGDIR)\lib\ijl15l.lib JPEGINC = $(JPEGDIR)\Include !endif # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ DEFINES = -D__STDC__ -DWIN32 -DCONSOLE -D_MT -DNO_STRICT -D_NO_VCL \ $(DEBUG_DEFINES) $(SHLIB_DEFINES) $(EXTRA_DEFINES) !if ($(SHARED) == 1) SHLIB_DEFINES = -D_DLL SHLIB_TARGET = build-dll LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) !else SHLIB_CFLAGS = SHLIB_DEFINES = LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) !endif !if ($(DEBUG) == 1) # -Od Disable all optimizations. # -k Turn on standard stack frame. # -r- Disable use of registers. # -v Turn on source debugging. # -vG All code guard options on. # -vi- Turn off expansion of inline functions. # -y Debug line numbers on. DEBUG_CFLAGS = -v -k -Od -vi- -y -r- -lv -tW -tWM # -v Turn on source debugging. DEBUG_LDFLAGS = -v DEBUG_DEFINES = -DUSE_TCLALLOC=0 DEBUG_DEFINES = TK_LIB = $(TKDIR)\win\Debug\tk$(v2)d.lib TCL_LIB = $(TCLDIR)\win\Debug\tcl$(v2)d.lib MSVCRT = !else # -v- Turn off source debugging. # -vi- Turn off expansion of inline functions. # -O2 Generate fastest code possible. DEBUG_CFLAGS = -v- -vi- -O2 -D_DEBUG DEBUG_LDFLAGS = TK_LIB = $(TKDIR)\win\Release\tk$(v2).lib TCL_LIB = $(TCLDIR)\win\Release\tcl$(v2).lib MSVCRT = !endif # Turn off the following bcc warnings: # -w-pro Call to function with no prototype # -w-par Parameter is never used. # -w-sus Suspicious pointer conversion (bltCanvEps.c). # -w-eff Code has no effect (pure_api.c). # WARNINGS = -w-pro -w-par -w-eff -w-sus # -q Suppress compiler identification banner. # -g1 Stop after the first warning. # -tWC Target is a Windows console application. # -X Disable compiler autodependency output. # -ps Use stdcall calling convention. EXTRA_CFLAGS = -q -g1 -tWC -X CFLAGS = $(WARNINGS) $(DEBUG_CFLAGS) $(SHLIB_CFLAGS) $(EXTRA_CFLAGS) # ------------------------------------------------------------------------ # Linker flags and options # ------------------------------------------------------------------------ # -D Save specified description. # -w Turn on warnings. # -c Treate case as significant in symbols. # -x # -Gi Generate .lib file. # -r Verbose linking. # -x Suppresses map creation. COMMON_LDFLAGS = -D"" -w -c -x $(DEBUG_LDFLAGS) -L$(TOOLS32)\lib SHLIB_LDFLAGS = $(COMMON_LDFLAGS) -x -Gi -Tpd $(TOOLS32)\lib\c0d32 LDFLAGS = $(COMMON_LDFLAGS) -x -Tpe -S:2400000 COMMON_LIBS = $(TK_LIB) $(TCL_LIB) import32 cw32 EXTRA_LIBS = $(OLELIB) \ $(JPEGLIB) TCL_ONLY_COMMON_LIBS = $(TCL_LIB) import32 cw32 TCL_ONLY_LIBS = $(TCL_ONLY_COMMON_LIBS) $(EXTRA_LIBS) # ------------------------------------------------------------------------ # Source and target installation directories # ------------------------------------------------------------------------ srcdir = . instdirs = $(prefix) $(exec_prefix) $(bindir) $(libdir) $(includedir) instdirs = $(exec_prefix) $(prefix) $(libdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ TCLDIR = $(srcdir)\..\..\tcl$(v3) TKDIR = $(srcdir)\..\..\tk$(v3) INCLUDES = -I. -I$(srcdir) \ -I$(TOOLS32)\include \ -I$(JPEGINC) \ -I$(TCLDIR)\win -I$(TCLDIR)\generic \ -I$(TKDIR)\win -I$(TKDIR)\generic -I$(TKDIR)\xlib \ SHLIB_LD_LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) SHLIB_TCL_ONLY_LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ N_OBJS = bltTed.obj V3_OBJS = bltTri.obj bltGrMt.obj TK_OBJS = tkButton.obj tkFrame.obj bltScrollbar.obj GRAPH_OBJS = bltGrAxis.obj \ bltGrBar.obj \ bltGrElem.obj \ bltGrHairs.obj \ bltGrLegd.obj \ bltGrLine.obj \ bltGrMarker.obj \ bltGrMisc.obj \ bltGrPen.obj \ bltGrPs.obj \ bltGraph.obj TCL_ONLY_OBJS = bltAlloc.obj \ bltArrayObj.obj \ bltBgexec.obj \ bltChain.obj \ bltDebug.obj \ bltHash.obj \ bltList.obj \ bltNsUtil.obj \ bltParse.obj \ bltPool.obj \ bltSpline.obj \ bltSwitch.obj \ bltTree.obj \ bltTreeCmd.obj \ bltUtil.obj \ bltVecCmd.obj \ bltVecMath.obj \ bltVector.obj \ bltWatch.obj \ bltWinPipe.obj \ bltWinUtil.obj \ bltWinDde.obj \ pure_api.obj DEMO_OBJS = tkConsole.obj bltWinMain.obj OBJS = $(GRAPH_OBJS) \ $(TCL_ONLY_OBJS) \ bltBeep.obj \ bltBind.obj \ bltBitmap.obj \ bltBusy.obj \ bltCanvEps.obj \ bltConfig.obj \ bltContainer.obj \ bltDragdrop.obj \ bltHtext.obj \ bltImage.obj \ bltOldConfig.obj \ bltPs.obj \ bltTable.obj \ bltTabnotebook.obj \ bltTabset.obj \ bltText.obj \ bltTile.obj \ bltTreeView.obj \ bltTreeViewCmd.obj \ bltTreeViewColumn.obj \ bltTreeViewEdit.obj \ bltTreeViewStyle.obj \ bltWinDraw.obj \ bltWinImage.obj \ bltWinPrnt.obj \ bltWindow.obj \ bltWinop.obj \ $(TK_OBJS) $(N_OBJS) NOT_YET = bltContainer.obj bltCutBuffer.obj bltColor.obj HEADERS = blt.h bltChain.h bltVector.h bltTree.h bltPool.h bltHash.h # GNU Make-specific macro SRCS = $(patsubst %.obj,$(srcdir)\%.c,$(OBJS)) shell_name = bltwish version = $(BLT_MAJOR_VERSION)$(BLT_MINOR_VERSION) bltwish = bltwish.exe bltsh = bltsh.exe lib_name = BLT$(version) lib_a = BLT$(version).lib lib_so = BLT$(version).dll tcl_only_lib_a = BLTlite$(version).lib tcl_only_lib_so = BLTlite$(version).dll CC_SWITCHES = $(CFLAGS) $(DEFINES) $(INCLUDES) VPATH = $(srcdir) all: build-library build-demos build-demos: $(bltsh) $(bltwish) build-library: $(lib_a) $(tcl_only_lib_a) build-dll: build-library $(lib_so) $(tcl_only_lib_so) $(bltwish): $(lib_a) tkConsole.obj bltWinMain.c -del $(bltwish) 2>nul $(CC) -c $(CC_SWITCHES) -DTCLLIBPATH="\"$(TCLLIBPATH)\"" \ -obltWinMain.obj $(srcdir)\bltWinMain.c $(LD) $(LDFLAGS) -aa $(TOOLS32)\lib\c0w32 \ tkConsole.obj bltWinMain.obj, \ $(bltwish),, $(lib_a) $(LIBS) $(bltsh): $(tcl_only_lib_a) bltWinMain.c -del $(bltsh) 2>nul $(CC) -c $(CC_SWITCHES) -DTCL_ONLY \ -DTCLLIBPATH="\"$(TCLLIBPATH)\"" \ -obltWinMain.obj $(srcdir)\bltWinMain.c $(LD) $(LDFLAGS) -ap $(TOOLS32)\lib\c0x32 bltWinMain.obj, \ $(bltsh),, $(tcl_only_lib_a) $(TCL_ONLY_LIBS) $(lib_a): $(lib_so) bltHash.h $(OBJS) bltInit.c -del bltInit.obj 2>nul $(CC) -c $(CC_SWITCHES) -DBLT_LIBRARY="\"$(BLT_LIBRARY)\"" \ -obltInit.obj $(srcdir)\bltInit.c -del $@ 2>nul $(AR) $@ $(lib_so) $(lib_so): $(OBJS) bltInit.c -del bltInit.obj 2>nul $(CC) -c $(CC_SWITCHES) -DBLT_LIBRARY="\"$(BLT_LIBRARY)\"" \ -obltInit.obj $(srcdir)\bltInit.c -del $@ 2>nul $(LD) $(SHLIB_LDFLAGS) bltInit.obj $(OBJS), $@,, $(LIBS) $(tcl_only_lib_a): $(tcl_only_lib_so) bltHash.h $(TCL_ONLY_OBJS) bltInit.c -del bltInit.obj 2>nul $(CC) -c $(CC_SWITCHES) -DTCL_ONLY -DBLT_LIBRARY="\"$(BLT_LIBRARY)\"" \ -obltInit.obj $(srcdir)\bltInit.c -del $@ 2>nul $(AR) $@ $(tcl_only_lib_so) $(tcl_only_lib_so): $(TCL_ONLY_OBJS) bltInit.c -del bltInit.obj 2>nul $(CC) -c $(CC_SWITCHES) -DTCL_ONLY -DBLT_LIBRARY="\"$(BLT_LIBRARY)\"" \ -obltInit.obj $(srcdir)\bltInit.c -del $@ 2>nul $(LD) $(SHLIB_LDFLAGS) bltInit.obj $(TCL_ONLY_OBJS), $@, -x, \ $(TCL_ONLY_LIBS),, bltHash.h: bltHash.h.in sed -e 's/@SIZEOF_VOID_P@/4/' \ -e 's/@SIZEOF_INT@/4/' \ -e 's/@SIZEOF_LONG@/4/' \ -e 's/@SIZEOF_LONG_LONG@/8/' \ -e 's/@HAVE_INTTYPES_H@/0/' \ bltHash.h.in > bltHash.h clean: -del *.obj 2>nul -del *.pdb 2>nul -del *.exp 2>nul -del $(lib_a) 2>nul -del $(lib_so) 2>nul -del $(tcl_only_lib_a) 2>nul -del $(tcl_only_lib_so) 2>nul -del $(bltwish) 2>nul -del $(bltsh) 2>nul -del $(srcdir)\*.bak 2>nul -del $(srcdir)\*~ 2>nul -del $(srcdir)\"#"* 2>nul -del *.pdb 2>nul -del *.ilf 2>nul -del *.ils 2>nul -del *.ilc 2>nul -del *.ild 2>nul -del *.tds 2>nul -del *.td2 2>nul -del *.TR2 2>nul .c.obj: $(CC) -c $(CC_SWITCHES) $< ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrLegd.h�������������������������������������������������������������������0000644�0001750�0001750�00000005042�11462120062�015045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltGrLegd.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_GR_LEGEND_H #define _BLT_GR_LEGEND_H #define LEGEND_RIGHT (1<<0) /* Right margin */ #define LEGEND_LEFT (1<<1) /* Left margin */ #define LEGEND_BOTTOM (1<<2) /* Bottom margin */ #define LEGEND_TOP (1<<3) /* Top margin, below the graph title. */ #define LEGEND_PLOT (1<<4) /* Plot area */ #define LEGEND_XY (1<<5) /* Screen coordinates in the plotting * area. */ #define LEGEND_WINDOW (1<<6) /* External window. */ #define LEGEND_MARGIN_MASK \ (LEGEND_RIGHT | LEGEND_LEFT | LEGEND_BOTTOM | LEGEND_TOP) #define LEGEND_PLOTAREA_MASK (LEGEND_PLOT | LEGEND_XY) BLT_EXTERN int Blt_CreateLegend(Graph *graphPtr); BLT_EXTERN void Blt_DestroyLegend(Graph *graphPtr); BLT_EXTERN void Blt_DrawLegend(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_MapLegend(Graph *graphPtr, int width, int height); BLT_EXTERN int Blt_LegendOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_Legend_Site(Graph *graphPtr); BLT_EXTERN int Blt_Legend_Width(Graph *graphPtr); BLT_EXTERN int Blt_Legend_Height(Graph *graphPtr); BLT_EXTERN int Blt_Legend_IsHidden(Graph *graphPtr); BLT_EXTERN int Blt_Legend_IsRaised(Graph *graphPtr); BLT_EXTERN int Blt_Legend_X(Graph *graphPtr); BLT_EXTERN int Blt_Legend_Y(Graph *graphPtr); BLT_EXTERN void Blt_Legend_RemoveElement(Graph *graphPtr, Element *elemPtr); BLT_EXTERN void Blt_Legend_EventuallyRedraw(Graph *graphPtr); #endif /* BLT_GR_LEGEND_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltHtext.c��������������������������������������������������������������������0000644�0001750�0001750�00000371235�11462120062�015002� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltHtext.c -- * * This module implements a hypertext widget for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * To do: * * 1) Fix scroll unit round off errors. * * 2) Better error checking. * * 3) Use html format. * * 4) The dimension of cavities using -relwidth and -relheight * should be 0 when computing initial estimates for the size * of the virtual text. */ #include "bltInt.h" #ifndef NO_HTEXT #include "bltOp.h" #include <bltChain.h> #include <bltHash.h> #include "bltFont.h" #include "bltText.h" #include "bltBgStyle.h" #include <sys/stat.h> #include <X11/Xatom.h> #define DEF_LINES_ALLOC 512 /* Default block of lines allocated */ #define CLAMP(val,low,hi) \ (((val) < (low)) ? (low) : ((val) > (hi)) ? (hi) : (val)) /* * Justify option values */ typedef enum { JUSTIFY_CENTER, JUSTIFY_TOP, JUSTIFY_BOTTOM } Justify; static Blt_OptionParseProc ObjToWidth, ObjToHeight; static Blt_OptionPrintProc WidthHeightToObj; static Blt_CustomOption widthOption = { ObjToWidth, WidthHeightToObj, NULL, (ClientData)0 }; static Blt_CustomOption heightOption = { ObjToHeight, WidthHeightToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToJustify; static Blt_OptionPrintProc JustifyToObj; static Blt_CustomOption justifyOption = { ObjToJustify, JustifyToObj, NULL, (ClientData)0 }; static Tk_GeomRequestProc EmbeddedWidgetGeometryProc; static Tk_GeomLostSlaveProc EmbeddedWidgetCustodyProc; static Tk_GeomMgr htextMgrInfo = { (char *)"htext", /* Name of geometry manager used by * winfo */ EmbeddedWidgetGeometryProc, /* Procedure to for new geometry * requests */ EmbeddedWidgetCustodyProc, /* Procedure when window is taken * away */ }; /* * Line -- * * Structure to contain the contents of a single line of text and the * widgets on that line. * * Individual lines are not configurable, although changes to the size of * widgets do effect its values. */ typedef struct { int offset; /* Offset of line from y-origin (0) in * world coordinates */ int baseline; /* Baseline y-coordinate of the * text */ short int width, height; /* Dimensions of the line */ int textStart, textEnd; /* Start and end indices of characters * forming the line in the text array */ Blt_Chain chain; /* Chain of embedded widgets on the * line of text */ } Line; typedef struct { int textStart; int textEnd; } Segment; typedef struct { int x, y; } Position; /* * Hypertext widget. */ typedef struct { Tk_Window tkwin; /* Window that embodies the widget. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up.*/ Display *display; /* Display containing widget; needed, * among other things, to release * resources after tkwin has already * gone away. */ Tcl_Interp *interp; /* Interpreter associated with * widget. */ Tcl_Command cmdToken; /* Token for htext's widget command. */ int flags; /* User-configurable fields */ XColor *normalFg; Blt_Background normalBg; Blt_Font font; /* Font for normal text. May affect * the size of the viewport if the * width/height is specified in * columns/rows */ GC drawGC; /* Graphics context for normal text */ int tileOffsetPage; /* Set tile offset to top of page * instead of toplevel window */ GC fillGC; /* GC for clearing the window in the * designated background color. The * background color is the foreground * attribute in GC. */ int nRows, nColumns; /* # of characters of the current font * for a row or column of the viewport. * Used to determine the width and height * of the text window (i.e. viewport) */ int reqWidth, reqHeight; /* Requested dimensions of the * viewport */ int maxWidth, maxHeight; /* Maximum dimensions allowed for the * viewport, regardless of the size of * the text */ Tk_Cursor cursor; /* X Cursor */ char *fileName; /* If non-NULL, indicates the name of a * hypertext file to be read into the * widget. If NULL, the *text* field is * considered instead */ char *text; /* Hypertext to be loaded into the * widget. This value is ignored if * *fileName* * is non-NULL */ int specChar; /* Special character designating a TCL * command block in a hypertext * file. */ int leader; /* # of pixels between lines */ Tcl_Obj *yScrollCmdObjPtr; /* Name of vertical scrollbar to invoke */ int yScrollUnits; /* # of pixels per vertical scroll */ Tcl_Obj *xScrollCmdObjPtr; /* Name of horizontal scroll bar to invoke */ int xScrollUnits; /* # of pixels per horizontal # scroll */ int reqLineNum; /* Line requested by "goto" command */ /* * The view port is the width and height of the window and the * origin of the viewport (upper left corner) in world coordinates. */ int worldWidth, worldHeight;/* Size of view text in world coordinates */ int xOffset, yOffset; /* Position of viewport in world coordinates */ int pendingX, pendingY; /* New upper-left corner (origin) of * the viewport (not yet posted) */ int first, last; /* Range of lines displayed */ int lastWidth, lastHeight; /* Last known size of the window: saved to * recognize when the viewport is resized. */ Blt_HashTable widgetTable; /* Table of embedded widgets. */ /* * Selection display information: */ Blt_Background selBg; /* Border and background color */ int selBW; /* Border width */ XColor *selFgColor; /* Text foreground color */ GC selectGC; /* GC for drawing selected text */ int selAnchor; /* Fixed end of selection * (i.e. "selection to" operation will * use this as one end of the selection).*/ int selFirst; /* The index of first character in the * text array selected */ int selLast; /* The index of the last character selected */ int exportSelection; /* Non-zero means to export the internal text * selection to the X server. */ char *takeFocus; /* * Scanning information: */ XPoint scanMark; /* Anchor position of scan */ XPoint scanPt; /* x,y position where the scan started. */ char *charArr; /* Pool of characters representing the text * to be displayed */ int nChars; /* Length of the text pool */ Line *lineArr; /* Array of pointers to text lines */ int nLines; /* # of line entered into array. */ int arraySize; /* Size of array allocated. */ } HText; /* * Bit flags for the hypertext widget: */ #define REDRAW_PENDING (1<<0) /* A DoWhenIdle handler has already * been queued to redraw the window */ #define IGNORE_EXPOSURES (1<<1) /* Ignore exposure events in the text * window. Potentially many expose * events can occur while rearranging * embedded widgets during a single call to * the DisplayText. */ #define REQUEST_LAYOUT (1<<4) /* Something has happened which * requires the layout of text and * embedded widget positions to be * recalculated. The following * actions may cause this: * * 1) the contents of the hypertext * has changed by either the -file or * -text options. * * 2) a text attribute has changed * (line spacing, font, etc) * * 3) a embedded widget has been resized or * moved. * * 4) a widget configuration option has * changed. */ #define TEXT_DIRTY (1<<5) /* The layout was recalculated and the * size of the world (text layout) has * changed. */ #define GOTO_PENDING (1<<6) /* Indicates the starting text line * number has changed. To be reflected * the next time the widget is redrawn. */ #define WIDGET_APPENDED (1<<7) /* Indicates a embedded widget has just * been appended to the text. This is * used to determine when to add a * space to the text array */ #define DEF_HTEXT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_HTEXT_CURSOR "arrow" #define DEF_HTEXT_EXPORT_SELECTION "1" #define DEF_HTEXT_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_HTEXT_FILE_NAME (char *)NULL #define DEF_HTEXT_FONT STD_FONT #define DEF_HTEXT_HEIGHT "0" #define DEF_HTEXT_LINE_SPACING "1" #define DEF_HTEXT_MAX_HEIGHT (char *)NULL #define DEF_HTEXT_MAX_WIDTH (char *)NULL #define DEF_HTEXT_SCROLL_UNITS "10" #define DEF_HTEXT_SPEC_CHAR "0x25" #define DEF_HTEXT_SELECT_BORDERWIDTH STD_SELECT_BORDERWIDTH #define DEF_HTEXT_SELECT_BACKGROUND STD_SELECT_BACKGROUND #define DEF_HTEXT_SELECT_FOREGROUND STD_SELECT_FOREGROUND #define DEF_HTEXT_TAKE_FOCUS "1" #define DEF_HTEXT_TEXT (char *)NULL #define DEF_HTEXT_TILE_OFFSET "1" #define DEF_HTEXT_WIDTH "0" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_HTEXT_BACKGROUND, Blt_Offset(HText, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_HTEXT_CURSOR, Blt_Offset(HText, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", DEF_HTEXT_EXPORT_SELECTION, Blt_Offset(HText, exportSelection), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_STRING, "-file", "file", "File", DEF_HTEXT_FILE_NAME, Blt_Offset(HText, fileName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_HTEXT_FONT, Blt_Offset(HText, font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_HTEXT_FOREGROUND, Blt_Offset(HText, normalFg), 0}, {BLT_CONFIG_CUSTOM, "-height", "height", "Height", DEF_HTEXT_HEIGHT, Blt_Offset(HText, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT, &heightOption}, {BLT_CONFIG_PIXELS_NNEG, "-linespacing", "lineSpacing", "LineSpacing", DEF_HTEXT_LINE_SPACING, Blt_Offset(HText, leader), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-maxheight", "maxHeight", "MaxHeight", DEF_HTEXT_MAX_HEIGHT, Blt_Offset(HText, maxHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-maxwidth", "maxWidth", "MaxWidth", DEF_HTEXT_MAX_WIDTH, Blt_Offset(HText, maxWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BORDER, "-selectbackground", "selectBackground", "Background", DEF_HTEXT_SELECT_BACKGROUND, Blt_Offset(HText, selBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_HTEXT_SELECT_BORDERWIDTH, Blt_Offset(HText, selBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_HTEXT_SELECT_FOREGROUND, Blt_Offset(HText, selFgColor), 0}, {BLT_CONFIG_INT, "-specialchar", "specialChar", "SpecialChar", DEF_HTEXT_SPEC_CHAR, Blt_Offset(HText, specChar), 0}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_HTEXT_TAKE_FOCUS, Blt_Offset(HText, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-tileoffset", "tileOffset", "TileOffset", DEF_HTEXT_TILE_OFFSET, Blt_Offset(HText, tileOffsetPage), 0}, {BLT_CONFIG_STRING, "-text", "text", "Text", DEF_HTEXT_TEXT, Blt_Offset(HText, text), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-width", "width", "Width", DEF_HTEXT_WIDTH, Blt_Offset(HText, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT, &widthOption}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(HText, xScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-xscrollunits", "xScrollUnits", "ScrollUnits", DEF_HTEXT_SCROLL_UNITS, Blt_Offset(HText, xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(HText, yScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-yscrollunits", "yScrollUnits", "yScrollUnits", DEF_HTEXT_SCROLL_UNITS, Blt_Offset(HText, yScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; typedef struct { HText *htPtr; /* Pointer to parent's Htext structure */ Tk_Window tkwin; /* Widget window */ int flags; int x, y; /* Origin of embedded widget in text */ int cavityWidth, cavityHeight; /* Dimensions of the cavity * surrounding the embedded widget */ /* * Dimensions of the embedded widget. Compared against actual * embedded widget sizes when checking for resizing. */ int winWidth, winHeight; int precedingTextEnd; /* Index (in charArr) of the the last * character immediatedly preceding * the embedded widget */ int precedingTextWidth; /* Width of normal text preceding widget. */ Tk_Anchor anchor; Justify justify; /* Justification of region wrt to line */ /* * Requested dimensions of the cavity (includes padding). If non-zero, * it overrides the calculated dimension of the cavity. */ int reqCavityWidth, reqCavityHeight; /* * Relative dimensions of cavity wrt the size of the viewport. If * greater than 0.0. */ double relCavityWidth, relCavityHeight; int reqWidth, reqHeight; /* If non-zero, overrides the requested * dimension of the embedded widget */ double relWidth, relHeight; /* Relative dimensions of embedded * widget wrt the size of the viewport */ Blt_Pad xPad, yPad; /* Extra padding to frame around */ int ixPad, iyPad; /* internal padding for window */ int fill; /* Fill style flag */ } EmbeddedWidget; /* * Flag bits embedded widgets: */ #define WIDGET_VISIBLE (1<<2) /* Widget is currently visible in the * viewport. */ #define WIDGET_NOT_CHILD (1<<3) /* Widget is not a child of hypertext. */ /* * Defaults for embedded widgets: */ #define DEF_WIDGET_ANCHOR "center" #define DEF_WIDGET_FILL "none" #define DEF_WIDGET_HEIGHT "0" #define DEF_WIDGET_JUSTIFY "center" #define DEF_WIDGET_PAD_X "0" #define DEF_WIDGET_PAD_Y "0" #define DEF_WIDGET_REL_HEIGHT "0.0" #define DEF_WIDGET_REL_WIDTH "0.0" #define DEF_WIDGET_WIDTH "0" static Blt_ConfigSpec widgetConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", (char *)NULL, (char *)NULL, DEF_WIDGET_ANCHOR, Blt_Offset(EmbeddedWidget, anchor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-fill", (char *)NULL, (char *)NULL, DEF_WIDGET_FILL, Blt_Offset(EmbeddedWidget, fill), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-cavityheight", (char *)NULL, (char *)NULL, DEF_WIDGET_HEIGHT, Blt_Offset(EmbeddedWidget, reqCavityHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-cavitywidth", (char *)NULL, (char *)NULL, DEF_WIDGET_WIDTH, Blt_Offset(EmbeddedWidget, reqCavityWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-height", (char *)NULL, (char *)NULL, DEF_WIDGET_HEIGHT, Blt_Offset(EmbeddedWidget, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-justify", (char *)NULL, (char *)NULL, DEF_WIDGET_JUSTIFY, Blt_Offset(EmbeddedWidget, justify), BLT_CONFIG_DONT_SET_DEFAULT, &justifyOption}, {BLT_CONFIG_PAD, "-padx", (char *)NULL, (char *)NULL, DEF_WIDGET_PAD_X, Blt_Offset(EmbeddedWidget, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", (char *)NULL, (char *)NULL, DEF_WIDGET_PAD_Y, Blt_Offset(EmbeddedWidget, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-relcavityheight", (char *)NULL, (char *)NULL, DEF_WIDGET_REL_HEIGHT, Blt_Offset(EmbeddedWidget, relCavityHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-relcavitywidth", (char *)NULL, (char *)NULL, DEF_WIDGET_REL_WIDTH, Blt_Offset(EmbeddedWidget, relCavityWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-relheight", (char *)NULL, (char *)NULL, DEF_WIDGET_REL_HEIGHT, Blt_Offset(EmbeddedWidget, relHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-relwidth", (char *)NULL, (char *)NULL, DEF_WIDGET_REL_WIDTH, Blt_Offset(EmbeddedWidget, relWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-width", (char *)NULL, (char *)NULL, DEF_WIDGET_WIDTH, Blt_Offset(EmbeddedWidget, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Forward Declarations */ static Tcl_FreeProc DestroyText; static Tk_EventProc EmbeddedWidgetEventProc; static Tcl_IdleProc DisplayText; static Tcl_CmdDeleteProc TextDeleteCmdProc; static Tcl_VarTraceProc TextVarProc; static Blt_BackgroundChangedProc BackgroundChangedProc; static Tk_LostSelProc TextLostSelection; static Tk_SelectionProc TextSelectionProc; static Tk_EventProc TextEventProc; static Tcl_ObjCmdProc TextWidgetCmd; static Tcl_ObjCmdProc TextCmd; typedef int (HTextCmdProc)(HText *htextPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* end of Forward Declarations */ /* Custom options */ /* *--------------------------------------------------------------------------- * * ObjToJustify -- * * Converts the justification string into its numeric * representation. This configuration option affects how the * embedded widget is positioned with respect to the line on which * it sits. * * Valid style strings are: * * "top" Uppermost point of region is top of the line's * text * "center" Center point of region is line's baseline. * "bottom" Lowermost point of region is bottom of the * line's text * * Returns: * A standard TCL result. If the value was not valid * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToJustify( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Justification string */ char *widgRec, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Justify *justPtr = (Justify *)(widgRec + offset); char *string; char c; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'c') && (strncmp(string, "center", length) == 0)) { *justPtr = JUSTIFY_CENTER; } else if ((c == 't') && (strncmp(string, "top", length) == 0)) { *justPtr = JUSTIFY_TOP; } else if ((c == 'b') && (strncmp(string, "bottom", length) == 0)) { *justPtr = JUSTIFY_BOTTOM; } else { Tcl_AppendResult(interp, "bad justification argument \"", string, "\": should be \"center\", \"top\", or \"bottom\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NameOfJustify -- * * Returns the justification style string based upon the value. * * Results: * The static justification style string is returned. * *--------------------------------------------------------------------------- */ static const char * NameOfJustify(Justify justify) { switch (justify) { case JUSTIFY_CENTER: return "center"; case JUSTIFY_TOP: return "top"; case JUSTIFY_BOTTOM: return "bottom"; default: return "unknown justification value"; } } /* *--------------------------------------------------------------------------- * * JustifyToObj -- * * Returns the justification style string based upon the value. * * Results: * The justification style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * JustifyToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Justify justify = *(Justify *)(widgRec + offset); return Tcl_NewStringObj(NameOfJustify(justify), -1); } /* *--------------------------------------------------------------------------- * * GetScreenDistance -- * * Converts the given string into the screen distance or number * of characters. The valid formats are * * N - pixels Nm - millimeters * Ni - inches Np - pica * Nc - centimeters N# - number of characters * * where N is a non-negative decimal number. * * Results: * A standard TCL result. The screen distance and the number of * characters are returned. If the string can't be converted, * TCL_ERROR is returned and interp->result will contain an error * message. * *--------------------------------------------------------------------------- */ static int GetScreenDistance( Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *sizePtr, int *countPtr) { int nPixels, nChars; char *endPtr; /* Pointer to last character scanned */ double value; int rounded; char *string; string = Tcl_GetString(objPtr); value = strtod(string, &endPtr); if (endPtr == string) { Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", (char *)NULL); return TCL_ERROR; } if (value < 0.0) { Tcl_AppendResult(interp, "screen distance \"", string, "\" must be non-negative value", (char *)NULL); return TCL_ERROR; } while (isspace(UCHAR(*endPtr))) { if (*endPtr == '\0') { break; } endPtr++; } nPixels = nChars = 0; rounded = ROUND(value); switch (*endPtr) { case '\0': /* Distance in pixels */ nPixels = rounded; break; case '#': /* Number of characters */ nChars = rounded; break; default: /* cm, mm, pica, inches */ if (Tk_GetPixelsFromObj(interp, tkwin, objPtr, &rounded) != TCL_OK) { return TCL_ERROR; } nPixels = rounded; break; } *sizePtr = nPixels; *countPtr = nChars; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StringToHeight -- * * Like BLT_CONFIG_PIXELS, but adds an extra check for negative * values. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToHeight( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window */ Tcl_Obj *objPtr, /* Pixel value string */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { HText *htPtr = (HText *)widgRec; int height, nRows; if (GetScreenDistance(interp, tkwin, objPtr, &height, &nRows) != TCL_OK) { return TCL_ERROR; } htPtr->nRows = nRows; htPtr->reqHeight = height; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StringToWidth -- * * Like BLT_CONFIG_PIXELS, but adds an extra check for negative * values. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToWidth( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window */ Tcl_Obj *objPtr, /* Pixel value string */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { HText *htPtr = (HText *)widgRec; int width, nColumns; if (GetScreenDistance(interp, tkwin, objPtr, &width, &nColumns) != TCL_OK) { return TCL_ERROR; } htPtr->nColumns = nColumns; htPtr->reqWidth = width; return TCL_OK; } /* *--------------------------------------------------------------------------- * * WidthHeightToObj -- * * Returns the string representing the positive pixel size. * * Results: * The pixel size string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * WidthHeightToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) { int pixels = *(int *)(widgRec + offset); return Tcl_NewIntObj(pixels); } /* General routines */ /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the text window at the next idle * point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. This doesn't * seem to hurt performance noticeably, but if it does then this * could be changed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(HText *htPtr) { if ((htPtr->tkwin != NULL) && !(htPtr->flags & REDRAW_PENDING)) { htPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayText, htPtr); } } /* *--------------------------------------------------------------------------- * * ResizeArray -- * * Reallocates memory to the new size given. New memory * is also cleared (zeros). * * Results: * Returns a pointer to the new object or NULL if an error occurred. * * Side Effects: * Memory is re/allocated. * *--------------------------------------------------------------------------- */ static void * ResizeArray( void *array, int elemSize, int newSize, int prevSize) { void *newArray; if (newSize == prevSize) { return array; } if (newSize == 0) { /* Free entire array */ return NULL; } newArray = Blt_AssertCalloc(elemSize, newSize); if ((prevSize > 0) && (array != NULL)) { int size; size = MIN(prevSize, newSize) * elemSize; if (size > 0) { memcpy(newArray, array, size); } Blt_Free(array); } return newArray; } /* *--------------------------------------------------------------------------- * * LineSearch -- * * Performs a binary search for the line of text located at some * world y-coordinate (not screen y-coordinate). The search is * inclusive of those lines from low to high. * * Results: * Returns the array index of the line found at the given * y-coordinate. If the y-coordinate is outside of the given range * of lines, -1 is returned. * *--------------------------------------------------------------------------- */ static int LineSearch( HText *htPtr, /* HText widget */ int yCoord, /* Search y-coordinate */ int low, int high) /* Range of lines to search */ { int median; Line *linePtr; while (low <= high) { median = (low + high) >> 1; linePtr = htPtr->lineArr + median; if (yCoord < linePtr->offset) { high = median - 1; } else if (yCoord >= (linePtr->offset + linePtr->height)) { low = median + 1; } else { return median; } } return -1; } /* *--------------------------------------------------------------------------- * * IndexSearch -- * * Try to find what line contains a given text index. Performs * a binary search for the text line which contains the given index. * The search is inclusive of those lines from low and high. * * Results: * Returns the line number containing the given index. If the index * is outside the range of lines, -1 is returned. * *--------------------------------------------------------------------------- */ static int IndexSearch( HText *htPtr, /* HText widget */ int key, /* Search index */ int low, int high) /* Range of lines to search */ { int median; Line *linePtr; while (low <= high) { median = (low + high) >> 1; linePtr = htPtr->lineArr + median; if (key < linePtr->textStart) { high = median - 1; } else if (key > linePtr->textEnd) { low = median + 1; } else { return median; } } return -1; } /* *--------------------------------------------------------------------------- * * GetXYPosIndex -- * * Converts a string in the form "@x,y", where x and y are * window coordinates, to a text index. * * Window coordinates are first translated into world coordinates. * Any coordinate outside of the bounds of the virtual text is * silently set the nearest boundary. * * Results: * A standard TCL result. If "string" is a valid index, then * *indexPtr is filled with the numeric index corresponding. * Otherwise an error message is left in interp->result. * *--------------------------------------------------------------------------- */ static int GetXYPosIndex( HText *htPtr, Tcl_Obj *objPtr, int *indexPtr) { int x, y, curX, dummy; int textLength, textStart; int cindex, lindex; Line *linePtr; char *string; string = Tcl_GetString(objPtr); if (Blt_GetXY(htPtr->interp, htPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } /* Locate the line corresponding to the window y-coordinate position */ y += htPtr->yOffset; if (y < 0) { lindex = htPtr->first; } else if (y >= htPtr->worldHeight) { lindex = htPtr->last; } else { lindex = LineSearch(htPtr, y, 0, htPtr->nLines - 1); } if (lindex < 0) { Tcl_AppendResult(htPtr->interp, "can't find line at \"", string, "\"", (char *)NULL); return TCL_ERROR; } x += htPtr->xOffset; if (x < 0) { x = 0; } else if (x > htPtr->worldWidth) { x = htPtr->worldWidth; } linePtr = htPtr->lineArr + lindex; curX = 0; textStart = linePtr->textStart; textLength = linePtr->textEnd - linePtr->textStart; if (Blt_Chain_GetLength(linePtr->chain) > 0) { Blt_ChainLink link; int deltaX; EmbeddedWidget *winPtr; for (link = Blt_Chain_FirstLink(linePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); deltaX = winPtr->precedingTextWidth + winPtr->cavityWidth; if ((curX + deltaX) > x) { textLength = (winPtr->precedingTextEnd - textStart); break; } curX += deltaX; /* * Skip over the trailing space. It designates the position of * a embedded widget in the text */ textStart = winPtr->precedingTextEnd + 1; } } cindex = Blt_MeasureChars(htPtr->font, htPtr->charArr + textStart, textLength, 10000, DEF_TEXT_FLAGS, &dummy); *indexPtr = textStart + cindex; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ParseIndex -- * * Parse a string representing a text index into numeric * value. A text index can be in one of the following forms. * * "anchor" - anchor position of the selection. * "sel.first" - index of the first character in the selection. * "sel.last" - index of the last character in the selection. * "page.top" - index of the first character on the page. * "page.bottom" - index of the last character on the page. * "@x,y" - x and y are window coordinates. * "number - raw index of text * "line.char" - line number and character position * * Results: * A standard TCL result. If "string" is a valid index, then * *indexPtr is filled with the corresponding numeric index. * Otherwise an error message is left in interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ParseIndex( HText *htPtr, /* Text for which the index is being * specified. */ Tcl_Obj *objPtr, /* Numerical index into htPtr's element * list, or "end" to refer to last element. */ int *indexPtr) /* Where to store converted relief. */ { Tcl_Interp *interp = htPtr->interp; char *string; char c; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'a') && (strncmp(string, "anchor", length) == 0)) { *indexPtr = htPtr->selAnchor; } else if ((c == 's') && (length > 4)) { if (strncmp(string, "sel.first", length) == 0) { *indexPtr = htPtr->selFirst; } else if (strncmp(string, "sel.last", length) == 0) { *indexPtr = htPtr->selLast; } else { goto badIndex; /* Not a valid index */ } if (*indexPtr < 0) { Tcl_AppendResult(interp, "bad index \"", string, "\": nothing selected in \"", Tk_PathName(htPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } } else if ((c == 'p') && (length > 5) && (strncmp(string, "page.top", length) == 0)) { int first; first = htPtr->first; if (first < 0) { first = 0; } *indexPtr = htPtr->lineArr[first].textStart; } else if ((c == 'p') && (length > 5) && (strncmp(string, "page.bottom", length) == 0)) { *indexPtr = htPtr->lineArr[htPtr->last].textEnd; } else if (c == '@') { /* Screen position */ if (GetXYPosIndex(htPtr, objPtr, indexPtr) != TCL_OK) { return TCL_ERROR; } } else { char *period; period = strchr(string, '.'); if (period == NULL) { /* Raw index */ int tindex; if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { tindex = htPtr->nChars - 1; } else if (Tcl_GetIntFromObj(interp, objPtr, &tindex) != TCL_OK) { goto badIndex; } if (tindex < 0) { tindex = 0; } else if (tindex > (htPtr->nChars - 1)) { tindex = htPtr->nChars - 1; } *indexPtr = tindex; } else { int lindex, cindex, offset; Line *linePtr; int result; *period = '\0'; result = TCL_OK; if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { lindex = htPtr->nLines - 1; } else { result = Tcl_GetIntFromObj(interp, objPtr, &lindex); } *period = '.'; /* Repair index string before returning */ if (result != TCL_OK) { goto badIndex; /* Bad line number */ } if (lindex < 0) { lindex = 0; /* Silently repair bad line numbers */ } if (htPtr->nChars == 0) { *indexPtr = 0; return TCL_OK; } if (lindex >= htPtr->nLines) { lindex = htPtr->nLines - 1; } linePtr = htPtr->lineArr + lindex; cindex = 0; if ((*(period + 1) != '\0')) { string = period + 1; if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { cindex = linePtr->textEnd - linePtr->textStart; } else if (Tcl_GetInt(interp, string, &cindex) != TCL_OK) { goto badIndex; } } if (cindex < 0) { cindex = 0; /* Silently fix bogus indices */ } offset = 0; if (htPtr->nChars > 0) { offset = linePtr->textStart + cindex; if (offset > linePtr->textEnd) { offset = linePtr->textEnd; } } *indexPtr = offset; } } if (htPtr->nChars == 0) { *indexPtr = 0; } return TCL_OK; badIndex: /* * Some of the paths here leave messages in interp->result, so we * have to clear it out before storing our own message. */ Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad index \"", string, "\": \ should be one of the following: anchor, sel.first, sel.last, page.bottom, \ page.top, @x,y, index, line.char", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * GetIndex -- * * Get the index from a string representing a text index. * * * Results: * A standard TCL result. If "string" is a valid index, then * *indexPtr is filled with the numeric index corresponding. * Otherwise an error message is left in interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int GetIndex( HText *htPtr, /* Text for which the index is being * specified. */ Tcl_Obj *objPtr, /* Numerical index into htPtr's element * list, or "end" to refer to last element. */ int *indexPtr) /* Where to store converted relief. */ { int tindex; if (ParseIndex(htPtr, objPtr, &tindex) != TCL_OK) { return TCL_ERROR; } *indexPtr = tindex; return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetTextPosition -- * * Performs a binary search for the index located on line in * the text. The search is limited to those lines between * low and high inclusive. * * Results: * Returns the line number at the given Y coordinate. If position * does not correspond to any of the lines in the given the set, * -1 is returned. * *--------------------------------------------------------------------------- */ static int GetTextPosition( HText *htPtr, int tindex, int *lindexPtr, int *cindexPtr) { int lindex, cindex; lindex = cindex = 0; if (htPtr->nChars > 0) { Line *linePtr; lindex = IndexSearch(htPtr, tindex, 0, htPtr->nLines - 1); if (lindex < 0) { char string[200]; sprintf_s(string, 200, "can't determine line number from index \"%d\"", tindex); Tcl_AppendResult(htPtr->interp, string, (char *)NULL); return TCL_ERROR; } linePtr = htPtr->lineArr + lindex; if (tindex > linePtr->textEnd) { tindex = linePtr->textEnd; } cindex = tindex - linePtr->textStart; } *lindexPtr = lindex; *cindexPtr = cindex; return TCL_OK; } /* EmbeddedWidget Procedures */ /* *--------------------------------------------------------------------------- * * GetEmbeddedWidgetWidth -- * * Returns the width requested by the embedded widget. The requested * space also includes any internal padding which has been designated * for this window. * * Results: * Returns the requested width of the embedded widget. * *--------------------------------------------------------------------------- */ static int GetEmbeddedWidgetWidth(EmbeddedWidget *winPtr) { int width; if (winPtr->reqWidth > 0) { width = winPtr->reqWidth; } else if (winPtr->relWidth > 0.0) { width = (int) ((double)Tk_Width(winPtr->htPtr->tkwin) * winPtr->relWidth + 0.5); } else { width = Tk_ReqWidth(winPtr->tkwin); } width += (2 * winPtr->ixPad); return width; } /* *--------------------------------------------------------------------------- * * GetEmbeddedWidgetHeight -- * * Returns the height requested by the embedded widget. The requested * space also includes any internal padding which has been designated * for this window. * * Results: * Returns the requested height of the embedded widget. * *--------------------------------------------------------------------------- */ static int GetEmbeddedWidgetHeight(EmbeddedWidget *winPtr) { int height; if (winPtr->reqHeight > 0) { height = winPtr->reqHeight; } else if (winPtr->relHeight > 0.0) { height = (int)((double)Tk_Height(winPtr->htPtr->tkwin) * winPtr->relHeight + 0.5); } else { height = Tk_ReqHeight(winPtr->tkwin); } height += (2 * winPtr->iyPad); return height; } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on hypertext widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void EmbeddedWidgetEventProc( ClientData clientData, /* Information about the embedded widget. */ XEvent *eventPtr) /* Information about event. */ { EmbeddedWidget *winPtr = clientData; HText *htPtr; if ((winPtr == NULL) || (winPtr->tkwin == NULL)) { return; } htPtr = winPtr->htPtr; if (eventPtr->type == DestroyNotify) { Blt_HashEntry *hPtr; /* * Mark the widget as deleted by dereferencing the Tk window * pointer. Zero out the height and width to collapse the area * used by the widget. Redraw the window only if the widget is * currently visible. */ winPtr->htPtr->flags |= REQUEST_LAYOUT; if (Tk_IsMapped(winPtr->tkwin) && (winPtr->flags & WIDGET_VISIBLE)) { EventuallyRedraw(htPtr); } Tk_DeleteEventHandler(winPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, winPtr); hPtr = Blt_FindHashEntry(&htPtr->widgetTable, (char *)winPtr->tkwin); Blt_DeleteHashEntry(&htPtr->widgetTable, hPtr); winPtr->cavityWidth = winPtr->cavityHeight = 0; winPtr->tkwin = NULL; } else if (eventPtr->type == ConfigureNotify) { /* * EmbeddedWidgets can't request new positions. Worry only about resizing. */ if (winPtr->winWidth != Tk_Width(winPtr->tkwin) || winPtr->winHeight != Tk_Height(winPtr->tkwin)) { EventuallyRedraw(htPtr); htPtr->flags |= REQUEST_LAYOUT; } } } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetCustodyProc -- * * This procedure is invoked when a embedded widget has been * stolen by another geometry manager. The information and * memory associated with the embedded widget is released. * * Results: * None. * * Side effects: * Arranges for the widget formerly associated with the widget * to have its layout re-computed and arranged at the * next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void EmbeddedWidgetCustodyProc( ClientData clientData, /* Information about the former * embedded widget. */ Tk_Window tkwin) /* Not used. */ { Blt_HashEntry *hPtr; EmbeddedWidget *winPtr = clientData; /* * Mark the widget as deleted by dereferencing the Tk window * pointer. Zero out the height and width to collapse the area * used by the widget. Redraw the window only if the widget is * currently visible. */ winPtr->htPtr->flags |= REQUEST_LAYOUT; if (Tk_IsMapped(winPtr->tkwin) && (winPtr->flags & WIDGET_VISIBLE)) { EventuallyRedraw(winPtr->htPtr); } Tk_DeleteEventHandler(winPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, winPtr); hPtr = Blt_FindHashEntry(&winPtr->htPtr->widgetTable, (char *)winPtr->tkwin); Blt_DeleteHashEntry(&winPtr->htPtr->widgetTable, hPtr); winPtr->cavityWidth = winPtr->cavityHeight = 0; winPtr->tkwin = NULL; } /* *--------------------------------------------------------------------------- * * EmbeddedWidgetGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for * embedded widgets managed by the hypertext widget. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to * be repacked and drawn at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void EmbeddedWidgetGeometryProc( ClientData clientData, /* Information about window that got new * preferred geometry. */ Tk_Window tkwin) /* Not used. */ { EmbeddedWidget *winPtr = clientData; winPtr->htPtr->flags |= REQUEST_LAYOUT; EventuallyRedraw(winPtr->htPtr); } /* *--------------------------------------------------------------------------- * * FindEmbeddedWidget -- * * Searches for a widget matching the path name given * If found, the pointer to the widget structure is returned, * otherwise NULL. * * Results: * The pointer to the widget structure. If not found, NULL. * *--------------------------------------------------------------------------- */ static EmbeddedWidget * FindEmbeddedWidget( HText *htPtr, /* Hypertext widget structure */ Tk_Window tkwin) /* Path name of embedded widget */ { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&htPtr->widgetTable, (char *)tkwin); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * CreateEmbeddedWidget -- * * This procedure creates and initializes a new embedded widget * in the hyper text widget. * * Results: * The return value is a pointer to a structure describing the * new embedded widget. If an error occurred, then the return * value is NULL and an error message is left in interp->result. * * Side effects: * Memory is allocated. EmbeddedWidget window is mapped. * Callbacks are set up for embedded widget resizes and geometry * requests. * *--------------------------------------------------------------------------- */ static EmbeddedWidget * CreateEmbeddedWidget( HText *htPtr, /* Hypertext widget */ char *name) /* Name of embedded widget */ { EmbeddedWidget *winPtr; Tk_Window tkwin; Blt_HashEntry *hPtr; int isNew; tkwin = Tk_NameToWindow(htPtr->interp, name, htPtr->tkwin); if (tkwin == NULL) { return NULL; } if (Tk_Parent(tkwin) != htPtr->tkwin) { Tcl_AppendResult(htPtr->interp, "parent window of \"", name, "\" must be \"", Tk_PathName(htPtr->tkwin), "\"", (char *)NULL); return NULL; } hPtr = Blt_CreateHashEntry(&htPtr->widgetTable, (char *)tkwin, &isNew); /* Check is the widget is already embedded into this widget */ if (!isNew) { Tcl_AppendResult(htPtr->interp, "\"", name, "\" is already appended to ", Tk_PathName(htPtr->tkwin), (char *)NULL); return NULL; } winPtr = Blt_AssertCalloc(1, sizeof(EmbeddedWidget)); winPtr->flags = 0; winPtr->tkwin = tkwin; winPtr->htPtr = htPtr; winPtr->x = winPtr->y = 0; winPtr->fill = FILL_NONE; winPtr->justify = JUSTIFY_CENTER; winPtr->anchor = TK_ANCHOR_CENTER; Blt_SetHashValue(hPtr, winPtr); Tk_ManageGeometry(tkwin, &htextMgrInfo, winPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, winPtr); return winPtr; } /* *--------------------------------------------------------------------------- * * DestroyEmbeddedWidget -- * * This procedure is invoked by DestroyLine to clean up the * internal structure of a widget. * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyEmbeddedWidget(EmbeddedWidget *winPtr) { /* Destroy the embedded widget if it still exists */ if (winPtr->tkwin != NULL) { Blt_HashEntry *hPtr; Tk_DeleteEventHandler(winPtr->tkwin, StructureNotifyMask, EmbeddedWidgetEventProc, winPtr); hPtr = Blt_FindHashEntry(&winPtr->htPtr->widgetTable, (char *)winPtr->tkwin); Blt_DeleteHashEntry(&winPtr->htPtr->widgetTable, hPtr); Tk_DestroyWindow(winPtr->tkwin); } Blt_Free(winPtr); } /* Line Procedures */ /* *--------------------------------------------------------------------------- * * CreateLine -- * * This procedure creates and initializes a new line of text. * * Results: * The return value is a pointer to a structure describing the new * line of text. If an error occurred, then the return value is NULL * and an error message is left in interp->result. * * Side effects: * Memory is allocated. * *--------------------------------------------------------------------------- */ static Line * CreateLine(HText *htPtr) { Line *linePtr; if (htPtr->nLines >= htPtr->arraySize) { if (htPtr->arraySize == 0) { htPtr->arraySize = DEF_LINES_ALLOC; } else { htPtr->arraySize += htPtr->arraySize; } htPtr->lineArr = ResizeArray(htPtr->lineArr, sizeof(Line), htPtr->arraySize, htPtr->nLines); } /* Initialize values in the new entry */ linePtr = htPtr->lineArr + htPtr->nLines; linePtr->offset = 0; linePtr->height = linePtr->width = 0; linePtr->textStart = 0; linePtr->textEnd = -1; linePtr->baseline = 0; linePtr->chain = Blt_Chain_Create(); htPtr->nLines++; return linePtr; } /* *--------------------------------------------------------------------------- * * DestroyLine -- * * This procedure is invoked to clean up the internal structure * of a line. * * Results: * None. * * Side effects: * Everything associated with the line (text and widgets) is * freed up. * *--------------------------------------------------------------------------- */ static void DestroyLine(Line *linePtr) { Blt_ChainLink link; EmbeddedWidget *winPtr; /* Free the list of embedded widget structures */ for (link = Blt_Chain_FirstLink(linePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); DestroyEmbeddedWidget(winPtr); } Blt_Chain_Destroy(linePtr->chain); } static void FreeText(HText *htPtr) { int i; for (i = 0; i < htPtr->nLines; i++) { DestroyLine(htPtr->lineArr + i); } htPtr->nLines = 0; htPtr->nChars = 0; if (htPtr->charArr != NULL) { Blt_Free(htPtr->charArr); htPtr->charArr = NULL; } } /* Text Procedures */ /* *--------------------------------------------------------------------------- * * DestroyText -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a HText at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyText(DestroyData dataPtr) /* Info about hypertext widget. */ { HText *htPtr = (HText *)dataPtr; Blt_FreeOptions(configSpecs, (char *)htPtr, htPtr->display, 0); if (htPtr->drawGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->drawGC); } if (htPtr->fillGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->fillGC); } if (htPtr->selectGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->selectGC); } FreeText(htPtr); if (htPtr->lineArr != NULL) { Blt_Free(htPtr->lineArr); } Blt_DeleteHashTable(&htPtr->widgetTable); Blt_Free(htPtr); } /* *--------------------------------------------------------------------------- * * TextEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on hypertext widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void TextEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { HText *htPtr = clientData; if (eventPtr->type == ConfigureNotify) { if ((htPtr->lastWidth != Tk_Width(htPtr->tkwin)) || (htPtr->lastHeight != Tk_Height(htPtr->tkwin))) { htPtr->flags |= (REQUEST_LAYOUT | TEXT_DIRTY); EventuallyRedraw(htPtr); } } else if (eventPtr->type == Expose) { /* * If the Expose event was synthetic (i.e. we manufactured it * ourselves during a redraw operation), toggle the bit flag * which controls redraws. */ if (eventPtr->xexpose.send_event) { htPtr->flags ^= IGNORE_EXPOSURES; return; } if ((eventPtr->xexpose.count == 0) && !(htPtr->flags & IGNORE_EXPOSURES)) { htPtr->flags |= TEXT_DIRTY; EventuallyRedraw(htPtr); } } else if (eventPtr->type == DestroyNotify) { if (htPtr->tkwin != NULL) { htPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(htPtr->interp, htPtr->cmdToken); } if (htPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayText, htPtr); } Tcl_EventuallyFree(htPtr, DestroyText); } } /* *--------------------------------------------------------------------------- * * TextDeleteCmdProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void TextDeleteCmdProc(ClientData clientData) /* Pointer to widget record. */ { HText *htPtr = clientData; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (htPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = htPtr->tkwin; htPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * BackgroundChangedProc * * Stub for image change notifications. Since we immediately draw * the image into a pixmap, we don't care about image changes. * * It would be better if Tk checked for NULL proc pointers. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void BackgroundChangedProc(ClientData clientData) { HText *htPtr = clientData; if (htPtr->tkwin != NULL) { EventuallyRedraw(htPtr); } } /* Configuration Procedures */ static void ResetTextInfo(HText *htPtr) { htPtr->first = 0; htPtr->last = htPtr->nLines - 1; htPtr->selFirst = htPtr->selLast = -1; htPtr->selAnchor = 0; htPtr->pendingX = htPtr->pendingY = 0; htPtr->worldWidth = htPtr->worldHeight = 0; htPtr->xOffset = htPtr->yOffset = 0; } static Line * GetLastLine(HText *htPtr) { if (htPtr->nLines == 0) { return CreateLine(htPtr); } return (htPtr->lineArr + (htPtr->nLines - 1)); } /* *--------------------------------------------------------------------------- * * ReadNamedFile -- * * Read the named file into a newly allocated buffer. * * Results: * Returns the size of the allocated buffer if the file was * read correctly. Otherwise -1 is returned and "interp->result" * will contain an error message. * * Side Effects: * If successful, the contents of "bufferPtr" will point * to the allocated buffer. * *--------------------------------------------------------------------------- */ static int ReadNamedFile(Tcl_Interp *interp, char *fileName, char **bufferPtr) { FILE *f; int nRead; size_t fileSize; int count, bytesLeft; char *buffer; struct stat fileInfo; f = Blt_OpenFile(interp, fileName, "r"); if (f == NULL) { return -1; } if (fstat(fileno(f), &fileInfo) < 0) { Tcl_AppendResult(interp, "can't stat \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); fclose(f); return -1; } fileSize = fileInfo.st_size + 1; buffer = Blt_Malloc(sizeof(char) * fileSize); if (buffer == NULL) { fclose(f); return -1; /* Can't allocate memory for file buffer */ } count = 0; for (bytesLeft = fileInfo.st_size; bytesLeft > 0; bytesLeft -= nRead) { nRead = fread(buffer + count, sizeof(char), bytesLeft, f); if (nRead < 0) { Tcl_AppendResult(interp, "error reading \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); fclose(f); Blt_Free(buffer); return -1; } else if (nRead == 0) { break; } count += nRead; } fclose(f); buffer[count] = '\0'; *bufferPtr = buffer; return count; } /* *--------------------------------------------------------------------------- * * CollectCommand -- * * Collect the characters representing a TCL command into a * given buffer. * * Results: * Returns the number of bytes examined. If an error occurred, * -1 is returned and "interp->result" will contain an error * message. * * Side Effects: * If successful, the "cmdArr" will be filled with the string * representing the TCL command. * *--------------------------------------------------------------------------- */ static int CollectCommand( HText *htPtr, /* Widget record */ char inputArr[], /* Array of bytes representing the * htext input */ int maxBytes, /* Maximum number of bytes left in input */ char cmdArr[]) /* Output buffer to be filled with the Tcl * command */ { int c; int i; int state, count; /* Simply collect the all the characters until %% into a buffer */ state = count = 0; for (i = 0; i < maxBytes; i++) { c = inputArr[i]; if (c == htPtr->specChar) { state++; } else if ((state == 0) && (c == '\\')) { state = 3; } else { state = 0; } switch (state) { case 2: /* End of command block found */ cmdArr[count - 1] = '\0'; return i; case 4: /* Escaped block designator */ cmdArr[count] = c; state = 0; break; default: /* Add to command buffer */ cmdArr[count++] = c; break; } } Tcl_AppendResult(htPtr->interp, "premature end of TCL command block", (char *)NULL); return -1; } /* *--------------------------------------------------------------------------- * * ParseInput -- * * Parse the input to the HText structure into an array of lines. * Each entry contains the beginning index and end index of the * characters in the text array which comprise the line. * * |*|*|*|\n|T|h|i|s| |a| |l|i|n|e| |o|f| |t|e|x|t|.|\n|*|*|*| * ^ ^ * textStart textEnd * * Note that the end index contains the '\n'. * * Results: * Returns TCL_OK or error depending if the file was read correctly. * *--------------------------------------------------------------------------- */ static int ParseInput( Tcl_Interp *interp, HText *htPtr, char input[], int nBytes) { int c; int i; char *textArr; char *cmdArr; int count, nLines; int length; int state; Line *linePtr; linePtr = CreateLine(htPtr); if (linePtr == NULL) { return TCL_ERROR; /* Error allocating the line structure */ } /* Right now, we replace the text array instead of appending to it */ linePtr->textStart = 0; /* In the worst case, assume the entire input could be TCL commands */ cmdArr = Blt_AssertMalloc(sizeof(char) * (nBytes + 1)); textArr = Blt_AssertMalloc(sizeof(char) * (nBytes + 1)); if (htPtr->charArr != NULL) { Blt_Free(htPtr->charArr); } htPtr->charArr = textArr; htPtr->nChars = 0; nLines = count = state = 0; htPtr->flags &= ~WIDGET_APPENDED; for (i = 0; i < nBytes; i++) { c = input[i]; if (c == htPtr->specChar) { state++; } else if (c == '\n') { state = -1; } else if ((state == 0) && (c == '\\')) { state = 3; } else { state = 0; } switch (state) { case 2: /* Block of TCL commands found */ count--, i++; length = CollectCommand(htPtr, input + i, nBytes - i, cmdArr); if (length < 0) { goto error; } i += length; linePtr->textEnd = count; htPtr->nChars = count + 1; if (Tcl_Eval(interp, cmdArr) != TCL_OK) { goto error; } if (htPtr->flags & WIDGET_APPENDED) { /* Indicates the location a embedded widget in the text array */ textArr[count++] = ' '; htPtr->flags &= ~WIDGET_APPENDED; } state = 0; break; case 4: /* Escaped block designator */ textArr[count - 1] = c; state = 0; break; case -1: /* End of line or input */ linePtr->textEnd = count; textArr[count++] = '\n'; nLines++; linePtr = CreateLine(htPtr); if (linePtr == NULL) { goto error; } linePtr->textStart = count; state = 0; break; default: /* Default action, add to text buffer */ textArr[count++] = c; break; } } if (count > linePtr->textStart) { linePtr->textEnd = count; textArr[count++] = '\n';/* Every line must end with a '\n' */ nLines++; } Blt_Free(cmdArr); /* Reset number of lines allocated */ htPtr->lineArr = ResizeArray(htPtr->lineArr, sizeof(Line), nLines, htPtr->arraySize); htPtr->nLines = htPtr->arraySize = nLines; /* and the size of the character array */ htPtr->charArr = ResizeArray(htPtr->charArr, sizeof(char), count, nBytes); htPtr->nChars = count; return TCL_OK; error: Blt_Free(cmdArr); return TCL_ERROR; } static int IncludeText( Tcl_Interp *interp, HText *htPtr, char *fileName) { char *buffer; int result; int nBytes; if ((htPtr->text == NULL) && (fileName == NULL)) { return TCL_OK; /* Empty text string */ } if (fileName != NULL) { nBytes = ReadNamedFile(interp, fileName, &buffer); if (nBytes < 0) { return TCL_ERROR; } } else { buffer = htPtr->text; nBytes = strlen(htPtr->text); } result = ParseInput(interp, htPtr, buffer, nBytes); if (fileName != NULL) { Blt_Free(buffer); } return result; } /* ARGSUSED */ static char * TextVarProc( ClientData clientData, /* Information about widget. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* Name of variable. */ const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { HText *htPtr = clientData; HText *lasthtPtr; /* Check to see of this is the most recent trace */ lasthtPtr = (HText *)Tcl_VarTraceInfo2(interp, name1, name2, flags, TextVarProc, NULL); if (lasthtPtr != htPtr) { return NULL; /* Ignore all but most current trace */ } if (flags & TCL_TRACE_READS) { char c; c = name2[0]; if ((c == 'w') && (strcmp(name2, "widget") == 0)) { Tcl_SetVar2(interp, name1, name2, Tk_PathName(htPtr->tkwin), flags); } else if ((c == 'l') && (strcmp(name2, "line") == 0)) { char buf[200]; int lineNum; lineNum = htPtr->nLines - 1; if (lineNum < 0) { lineNum = 0; } sprintf_s(buf, 200, "%d", lineNum); Tcl_SetVar2(interp, name1, name2, buf, flags); } else if ((c == 'i') && (strcmp(name2, "index") == 0)) { char buf[200]; sprintf_s(buf, 200, "%d", htPtr->nChars - 1); Tcl_SetVar2(interp, name1, name2, buf, flags); } else if ((c == 'f') && (strcmp(name2, "file") == 0)) { const char *fileName; fileName = htPtr->fileName; if (fileName == NULL) { fileName = ""; } Tcl_SetVar2(interp, name1, name2, fileName, flags); } else { return (char *)"?unknown?"; } } return NULL; } static const char *varNames[] = { "widget", "line", "file", "index", (char *)NULL }; static void CreateTraces(HText *htPtr) { const char **p; static char globalCmd[] = "global htext"; /* * Make the traced variables global to the widget */ Tcl_Eval(htPtr->interp, globalCmd); for (p = varNames; *p != NULL; p++) { Tcl_TraceVar2(htPtr->interp, "htext", *p, (TCL_GLOBAL_ONLY | TCL_TRACE_READS), TextVarProc, htPtr); } } static void DeleteTraces(HText *htPtr) { const char **p; for (p = varNames; *p != NULL; p++) { Tcl_UntraceVar2(htPtr->interp, "htext", *p, (TCL_GLOBAL_ONLY | TCL_TRACE_READS), TextVarProc, htPtr); } } /* *--------------------------------------------------------------------------- * * ConfigureText -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or reconfigure) * a hypertext widget. * * The layout of the text must be calculated (by ComputeLayout) * whenever particular options change; -font, -file, -linespacing * and -text options. If the user has changes one of these options, * it must be detected so that the layout can be recomputed. Since the * coordinates of the layout are virtual, there is no need to adjust * them if physical window attributes (window size, etc.) * change. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for htPtr; old resources get freed, if there were any. * The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureText( Tcl_Interp *interp, /* Used for error reporting. */ HText *htPtr) /* Information about widget; may or may not * already have values for some fields. */ { XGCValues gcValues; unsigned long gcMask; GC newGC; if (Blt_ConfigModified(configSpecs, "-font", "-linespacing", "-file", "-text", "-width", "-height", (char *)NULL)) { /* * These options change the layout of the text. Width/height * and rows/columns may change a relatively sized window or cavity. */ htPtr->flags |= (REQUEST_LAYOUT | TEXT_DIRTY); /* Mark for update */ } gcMask = GCForeground | GCFont; gcValues.font = Blt_FontId(htPtr->font); gcValues.foreground = htPtr->normalFg->pixel; newGC = Tk_GetGC(htPtr->tkwin, gcMask, &gcValues); if (htPtr->drawGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->drawGC); } htPtr->drawGC = newGC; gcValues.foreground = htPtr->selFgColor->pixel; newGC = Tk_GetGC(htPtr->tkwin, gcMask, &gcValues); if (htPtr->selectGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->selectGC); } htPtr->selectGC = newGC; if (htPtr->xScrollUnits < 1) { htPtr->xScrollUnits = 1; } if (htPtr->yScrollUnits < 1) { htPtr->yScrollUnits = 1; } if (htPtr->normalBg != NULL) { Blt_SetBackgroundChangedProc(htPtr->normalBg, BackgroundChangedProc, htPtr); } if (htPtr->selBg != NULL) { Blt_SetBackgroundChangedProc(htPtr->selBg, BackgroundChangedProc, htPtr); } gcValues.foreground = Blt_BackgroundBorderColor(htPtr->normalBg)->pixel; newGC = Tk_GetGC(htPtr->tkwin, gcMask, &gcValues); if (htPtr->fillGC != NULL) { Tk_FreeGC(htPtr->display, htPtr->fillGC); } htPtr->fillGC = newGC; if (htPtr->nColumns > 0) { htPtr->reqWidth = htPtr->nColumns * Blt_TextWidth(htPtr->font, "0", 1); } if (htPtr->nRows > 0) { Blt_FontMetrics fontMetrics; Blt_GetFontMetrics(htPtr->font, &fontMetrics); htPtr->reqHeight = htPtr->nRows * fontMetrics.linespace; } /* * If the either the -text or -file option changed, read in the * new text. The -text option supersedes any -file option. */ if (Blt_ConfigModified(configSpecs, "-file", "-text", (char *)NULL)) { int result; FreeText(htPtr); CreateTraces(htPtr); /* Create variable traces */ result = IncludeText(interp, htPtr, htPtr->fileName); DeleteTraces(htPtr); if (result == TCL_ERROR) { FreeText(htPtr); return TCL_ERROR; } ResetTextInfo(htPtr); } EventuallyRedraw(htPtr); return TCL_OK; } /* Layout Procedures */ /* *--------------------------------------------------------------------------- * * TranslateAnchor -- * * Translate the coordinates of a given bounding box based * upon the anchor specified. The anchor indicates where * the given xy position is in relation to the bounding box. * * nw --- n --- ne * | | x,y ---+ * w center e | | * | | +-----+ * sw --- s --- se * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ static XPoint TranslateAnchor( int deltaX, int deltaY, /* Difference between outer/inner regions */ Tk_Anchor anchor) /* Direction of the anchor */ { XPoint point; point.x = point.y = 0; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ point.y = (deltaY / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ point.y = deltaY; break; case TK_ANCHOR_N: /* Top center */ point.x = (deltaX / 2); break; case TK_ANCHOR_CENTER: /* Centered */ point.x = (deltaX / 2); point.y = (deltaY / 2); break; case TK_ANCHOR_S: /* Bottom center */ point.x = (deltaX / 2); point.y = deltaY; break; case TK_ANCHOR_NE: /* Upper right corner */ point.x = deltaX; break; case TK_ANCHOR_E: /* Right center */ point.x = deltaX; point.y = (deltaY / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ point.x = deltaX; point.y = deltaY; break; } return point; } /* *--------------------------------------------------------------------------- * * ComputeCavitySize -- * * Sets the width and height of the cavity based upon the * requested size of the embedded widget. The requested space also * includes any external padding which has been designated for * this window. * * Results: * None. * * Side Effects: * The size of the cavity is set in the embedded widget information * structure. These values can effect how the embedded widget is * packed into the master window. *--------------------------------------------------------------------------- */ static void ComputeCavitySize(EmbeddedWidget *winPtr) { int width, height; int twiceBW; twiceBW = 2 * Tk_Changes(winPtr->tkwin)->border_width; if (winPtr->reqCavityWidth > 0) { width = winPtr->reqCavityWidth; } else if (winPtr->relCavityWidth > 0.0) { width = (int)((double)Tk_Width(winPtr->htPtr->tkwin) * winPtr->relCavityWidth + 0.5); } else { width = GetEmbeddedWidgetWidth(winPtr) + PADDING(winPtr->xPad) + twiceBW; } winPtr->cavityWidth = width; if (winPtr->reqCavityHeight > 0) { height = winPtr->reqCavityHeight; } else if (winPtr->relCavityHeight > 0.0) { height = (int)((double)Tk_Height(winPtr->htPtr->tkwin) * winPtr->relCavityHeight + 0.5); } else { height = GetEmbeddedWidgetHeight(winPtr) + PADDING(winPtr->yPad) + twiceBW; } winPtr->cavityHeight = height; } /* *--------------------------------------------------------------------------- * * LayoutLine -- * * This procedure computes the total width and height needed * to contain the text and widgets for a particular line. * It also calculates the baseline of the text on the line with * respect to the other widgets on the line. * * Results: * None. * *--------------------------------------------------------------------------- */ static void LayoutLine(HText *htPtr, Line *linePtr) { EmbeddedWidget *winPtr; int textStart, textLength; int maxAscent, maxDescent, maxHeight; int ascent, descent; int median; /* Difference of font ascent/descent values */ Blt_ChainLink link; int x, y; int newX; Blt_FontMetrics fontMetrics; /* Initialize line defaults */ Blt_GetFontMetrics(htPtr->font, &fontMetrics); maxAscent = fontMetrics.ascent; maxDescent = fontMetrics.descent; median = fontMetrics.ascent - fontMetrics.descent; ascent = descent = 0; /* Suppress compiler warnings */ /* * Pass 1: Determine the maximum ascent (baseline) and descent * needed for the line. We'll need this for figuring the top, * bottom, and center anchors. */ for (link = Blt_Chain_FirstLink(linePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); if (winPtr->tkwin == NULL) { continue; } ComputeCavitySize(winPtr); switch (winPtr->justify) { case JUSTIFY_TOP: ascent = fontMetrics.ascent + winPtr->padTop; descent = winPtr->cavityHeight - fontMetrics.ascent; break; case JUSTIFY_CENTER: ascent = (winPtr->cavityHeight + median) / 2; descent = (winPtr->cavityHeight - median) / 2; break; case JUSTIFY_BOTTOM: ascent = winPtr->cavityHeight - fontMetrics.descent; descent = fontMetrics.descent; break; } if (descent > maxDescent) { maxDescent = descent; } if (ascent > maxAscent) { maxAscent = ascent; } } maxHeight = maxAscent + maxDescent + htPtr->leader; x = 0; /* Always starts from x=0 */ y = 0; /* Suppress compiler warning */ textStart = linePtr->textStart; /* * Pass 2: Find the placements of the text and widgets along each * line. */ for (link = Blt_Chain_FirstLink(linePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); if (winPtr->tkwin == NULL) { continue; } /* Get the width of the text leading to the widget. */ textLength = (winPtr->precedingTextEnd - textStart); if (textLength > 0) { Blt_MeasureChars(htPtr->font, htPtr->charArr + textStart, textLength, 10000, TK_AT_LEAST_ONE, &newX); winPtr->precedingTextWidth = newX; x += newX; } switch (winPtr->justify) { case JUSTIFY_TOP: y = maxAscent - fontMetrics.ascent; break; case JUSTIFY_CENTER: y = maxAscent - (winPtr->cavityHeight + median) / 2; break; case JUSTIFY_BOTTOM: y = maxAscent + fontMetrics.descent - winPtr->cavityHeight; break; } winPtr->x = x, winPtr->y = y; /* Skip over trailing space */ textStart = winPtr->precedingTextEnd + 1; x += winPtr->cavityWidth; } /* * This can be either the trailing piece of a line after the last widget * or the entire line if no widgets are embedded in it. */ textLength = (linePtr->textEnd - textStart) + 1; if (textLength > 0) { Blt_MeasureChars(htPtr->font, htPtr->charArr + textStart, textLength, 10000, DEF_TEXT_FLAGS, &newX); x += newX; } /* Update line parameters */ if ((linePtr->width != x) || (linePtr->height != maxHeight) || (linePtr->baseline != maxAscent)) { htPtr->flags |= TEXT_DIRTY; } linePtr->width = x; linePtr->height = maxHeight; linePtr->baseline = maxAscent; } /* *--------------------------------------------------------------------------- * * ComputeLayout -- * * This procedure computes the total width and height needed * to contain the text and widgets from all the lines of text. * It merely sums the heights and finds the maximum width of * all the lines. The width and height are needed for scrolling. * * Results: * None. * *--------------------------------------------------------------------------- */ static void ComputeLayout(HText *htPtr) { int count; Line *linePtr; int height, width; width = height = 0; for (count = 0; count < htPtr->nLines; count++) { linePtr = htPtr->lineArr + count; linePtr->offset = height; LayoutLine(htPtr, linePtr); height += linePtr->height; if (linePtr->width > width) { width = linePtr->width; } } /* * Set changed flag if new layout changed size of virtual text. */ if ((height != htPtr->worldHeight) || (width != htPtr->worldWidth)) { htPtr->worldHeight = height, htPtr->worldWidth = width; htPtr->flags |= TEXT_DIRTY; } } /* Display Procedures */ /* *--------------------------------------------------------------------------- * * GetVisibleLines -- * * Calculates which lines are visible using the height * of the viewport and y offset from the top of the text. * * Results: * None. * * Side effects: * Only those line between first and last inclusive are * redrawn. * *--------------------------------------------------------------------------- */ static int GetVisibleLines(HText *htPtr) { int topLine, bottomLine; int firstY, lastY; int lastLine; if (htPtr->nLines == 0) { htPtr->first = 0; htPtr->last = -1; return TCL_OK; } firstY = htPtr->pendingY; lastLine = htPtr->nLines - 1; /* First line */ topLine = LineSearch(htPtr, firstY, 0, lastLine); if (topLine < 0) { /* * This can't be. The y-coordinate offset must be corrupted. */ fprintf(stderr, "internal error: First position not found `%d'\n", firstY); return TCL_ERROR; } htPtr->first = topLine; /* * If there is less text than window space, the bottom line is the * last line of text. Otherwise search for the line at the bottom * of the window. */ lastY = firstY + Tk_Height(htPtr->tkwin) - 1; if (lastY < htPtr->worldHeight) { bottomLine = LineSearch(htPtr, lastY, topLine, lastLine); } else { bottomLine = lastLine; } if (bottomLine < 0) { /* * This can't be. The newY offset must be corrupted. */ fprintf(stderr, "internal error: Last position not found `%d'\n", lastY); #ifdef notdef fprintf(stderr, "worldHeight=%d,height=%d,top=%d,first=%d,last=%d\n", htPtr->worldHeight, Tk_Height(htPtr->tkwin), firstY, htPtr->lineArr[topLine].offset, htPtr->lineArr[lastLine].offset); #endif return TCL_ERROR; } htPtr->last = bottomLine; return TCL_OK; } /* *--------------------------------------------------------------------------- * * DrawSegment -- * * Draws a line segment, designated by the segment structure. * This routine handles the display of selected text by drawing * a raised 3D border underneath the selected text. * * Results: * None. * * Side effects: * The line segment is drawn on *draw*. * *--------------------------------------------------------------------------- */ static void DrawSegment( HText *htPtr, Drawable draw, Line *linePtr, int x, int y, Segment *segPtr) { int lastX, curPos, nChars; int textLength; int selStart, selEnd, selLength; Blt_FontMetrics fontMetrics; #ifdef notdef fprintf(stderr, "DS select: first=%d,last=%d text: first=%d,last=%d\n", htPtr->selFirst, htPtr->selLast, segPtr->textStart, segPtr->textEnd); #endif textLength = (segPtr->textEnd - segPtr->textStart) + 1; if (textLength < 1) { return; } Blt_GetFontMetrics(htPtr->font, &fontMetrics); if ((segPtr->textEnd < htPtr->selFirst) || (segPtr->textStart > htPtr->selLast)) { /* No selected text */ Blt_DrawChars(Tk_Display(htPtr->tkwin), draw, htPtr->drawGC, htPtr->font, Tk_Depth(htPtr->tkwin), 0.0f, htPtr->charArr + segPtr->textStart, textLength - 1, x, y + linePtr->baseline); return; } /* * Text in a segment (with selected text) may have * up to three regions: * * 1) the text before the start the selection * 2) the selected text itself (drawn in a raised border) * 3) the text following the selection. */ selStart = segPtr->textStart; selEnd = segPtr->textEnd; if (htPtr->selFirst > segPtr->textStart) { selStart = htPtr->selFirst; } if (htPtr->selLast < segPtr->textEnd) { selEnd = htPtr->selLast; } selLength = (selEnd - selStart) + 1; lastX = x; curPos = segPtr->textStart; if (selStart > segPtr->textStart) { /* Text preceding selection */ nChars = (selStart - segPtr->textStart); Blt_MeasureChars(htPtr->font, htPtr->charArr + segPtr->textStart, nChars, 10000, DEF_TEXT_FLAGS, &lastX); lastX += x; Blt_DrawChars(Tk_Display(htPtr->tkwin), draw, htPtr->drawGC, htPtr->font, Tk_Depth(htPtr->tkwin), 0.0f, htPtr->charArr + segPtr->textStart, nChars, x, y + linePtr->baseline); curPos = selStart; } if (selLength > 0) { /* The selection itself */ int width, nextX; Blt_MeasureChars(htPtr->font, htPtr->charArr + selStart, selLength, 10000, DEF_TEXT_FLAGS, &nextX); nextX += x; width = (selEnd == linePtr->textEnd) ? htPtr->worldWidth - htPtr->xOffset - lastX : nextX - lastX; Blt_FillBackgroundRectangle(htPtr->tkwin, draw, htPtr->selBg, lastX, y + linePtr->baseline - fontMetrics.ascent, width, fontMetrics.linespace, htPtr->selBW, TK_RELIEF_RAISED); Blt_DrawChars(Tk_Display(htPtr->tkwin), draw, htPtr->selectGC, htPtr->font, Tk_Depth(htPtr->tkwin), 0.0f, htPtr->charArr + selStart, selLength, lastX, y + linePtr->baseline); lastX = nextX; curPos = selStart + selLength; } nChars = segPtr->textEnd - curPos; if (nChars > 0) { /* Text following the selection */ Blt_DrawChars(Tk_Display(htPtr->tkwin), draw, htPtr->drawGC, htPtr->font, Tk_Depth(htPtr->tkwin), 0.0f, htPtr->charArr + curPos, nChars - 1, lastX, y + linePtr->baseline); } } /* *--------------------------------------------------------------------------- * * MoveEmbeddedWidget -- * * Move a embedded widget to a new location in the hypertext * parent window. If the window has no geometry (i.e. width, * or height is 0), simply unmap to window. * * Results: * None. * * Side effects: * Each embedded widget is moved to its new location, generating * Expose events in the parent for each embedded widget moved. * *--------------------------------------------------------------------------- */ static void MoveEmbeddedWidget(EmbeddedWidget *winPtr, int offset) { int winWidth, winHeight; int width, height; int deltaX, deltaY; int x, y; int intBW; winWidth = GetEmbeddedWidgetWidth(winPtr); winHeight = GetEmbeddedWidgetHeight(winPtr); if ((winWidth < 1) || (winHeight < 1)) { if (Tk_IsMapped(winPtr->tkwin)) { Tk_UnmapWindow(winPtr->tkwin); } return; } intBW = Tk_Changes(winPtr->tkwin)->border_width; x = (winPtr->x + intBW + winPtr->padLeft) - winPtr->htPtr->xOffset; y = offset + (winPtr->y + intBW + winPtr->padTop) - winPtr->htPtr->yOffset; width = winPtr->cavityWidth - (2 * intBW + PADDING(winPtr->xPad)); if (width < 0) { width = 0; } if ((width < winWidth) || (winPtr->fill & FILL_X)) { winWidth = width; } deltaX = width - winWidth; height = winPtr->cavityHeight - (2 * intBW + PADDING(winPtr->yPad)); if (height < 0) { height = 0; } if ((height < winHeight) || (winPtr->fill & FILL_Y)) { winHeight = height; } deltaY = height - winHeight; if ((deltaX > 0) || (deltaY > 0)) { XPoint point; point = TranslateAnchor(deltaX, deltaY, winPtr->anchor); x += point.x, y += point.y; } winPtr->winWidth = winWidth; winPtr->winHeight = winHeight; if ((x != Tk_X(winPtr->tkwin)) || (y != Tk_Y(winPtr->tkwin)) || (winWidth != Tk_Width(winPtr->tkwin)) || (winHeight != Tk_Height(winPtr->tkwin))) { Tk_MoveResizeWindow(winPtr->tkwin, x, y, winWidth, winHeight); } if (!Tk_IsMapped(winPtr->tkwin)) { Tk_MapWindow(winPtr->tkwin); } } /* *--------------------------------------------------------------------------- * * DrawPage -- * * This procedure displays the lines of text and moves the widgets * to their new positions. It draws lines with regard to * the direction of the scrolling. The idea here is to make the * text and buttons appear to move together. Otherwise you will * get a "jiggling" effect where the windows appear to bump into * the next line before that line is moved. In the worst case, where * every line has at least one widget, you can get an aquarium effect * (lines appear to ripple up). * * The text area may start between line boundaries (to accommodate * both variable height lines and constant scrolling). Subtract the * difference of the page offset and the line offset from the starting * coordinates. For horizontal scrolling, simply subtract the offset * of the viewport. The window will clip the top of the first line, * the bottom of the last line, whatever text extends to the left * or right of the viewport on any line. * * Results: * None. * * Side effects: * Commands are output to X to display the line in its current * mode. * *--------------------------------------------------------------------------- */ static void DrawPage(HText *htPtr, int deltaY) /* Change from previous Y coordinate */ { Line *linePtr; EmbeddedWidget *winPtr; Tk_Window tkwin = htPtr->tkwin; Segment sgmt; Pixmap pixmap; int forceCopy; int i; int lineNum; int x, y, lastY; Blt_ChainLink link; int width, height; Display *display; display = htPtr->display; width = Tk_Width(tkwin); height = Tk_Height(tkwin); /* Create an off-screen pixmap for semi-smooth scrolling. */ pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin)); x = -(htPtr->xOffset); y = -(htPtr->yOffset); if (htPtr->tileOffsetPage) { Blt_SetBackgroundOrigin(htPtr->tkwin, htPtr->normalBg, x, y); } else { Blt_SetBackgroundOrigin(htPtr->tkwin, htPtr->normalBg, 0, 0); } Blt_FillBackgroundRectangle(htPtr->tkwin, pixmap, htPtr->normalBg, 0, 0, width, height, TK_RELIEF_FLAT, 0); if (deltaY >= 0) { y += htPtr->lineArr[htPtr->first].offset; lineNum = htPtr->first; lastY = 0; } else { y += htPtr->lineArr[htPtr->last].offset; lineNum = htPtr->last; lastY = height; } forceCopy = 0; /* Draw each line */ for (i = htPtr->first; i <= htPtr->last; i++) { /* Initialize character position in text buffer to start */ linePtr = htPtr->lineArr + lineNum; sgmt.textStart = linePtr->textStart; sgmt.textEnd = linePtr->textEnd; /* Initialize X position */ x = -(htPtr->xOffset); for (link = Blt_Chain_FirstLink(linePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); if (winPtr->tkwin != NULL) { winPtr->flags |= WIDGET_VISIBLE; MoveEmbeddedWidget(winPtr, linePtr->offset); } sgmt.textEnd = winPtr->precedingTextEnd - 1; if (sgmt.textEnd >= sgmt.textStart) { DrawSegment(htPtr, pixmap, linePtr, x, y, &sgmt); x += winPtr->precedingTextWidth; } /* Skip over the extra trailing space which designates the widget */ sgmt.textStart = winPtr->precedingTextEnd + 1; x += winPtr->cavityWidth; forceCopy++; } /* * This may be the text trailing the last widget or the entire * line if no widgets occur on it. */ sgmt.textEnd = linePtr->textEnd; if (sgmt.textEnd >= sgmt.textStart) { DrawSegment(htPtr, pixmap, linePtr, x, y, &sgmt); } /* Go to the top of the next line */ if (deltaY >= 0) { y += htPtr->lineArr[lineNum].height; lineNum++; } if ((forceCopy > 0) && !(htPtr->flags & TEXT_DIRTY)) { if (deltaY >= 0) { XCopyArea(display, pixmap, Tk_WindowId(tkwin), htPtr->drawGC, 0, lastY, width, y - lastY, 0, lastY); } else { XCopyArea(display, pixmap, Tk_WindowId(tkwin), htPtr->drawGC, 0, y, width, lastY - y, 0, y); } forceCopy = 0; /* Reset drawing flag */ lastY = y; /* Record last Y position */ } if ((deltaY < 0) && (lineNum > 0)) { --lineNum; y -= htPtr->lineArr[lineNum].height; } } /* * If the viewport was resized, draw the page in one operation. * Otherwise draw any left-over block of text (either at the top * or bottom of the page) */ if (htPtr->flags & TEXT_DIRTY) { XCopyArea(display, pixmap, Tk_WindowId(tkwin), htPtr->drawGC, 0, 0, width, height, 0, 0); } else if (lastY != y) { if (deltaY >= 0) { height -= lastY; XCopyArea(display, pixmap, Tk_WindowId(tkwin), htPtr->drawGC, 0, lastY, width, height, 0, lastY); } else { height = lastY; XCopyArea(display, pixmap, Tk_WindowId(tkwin), htPtr->drawGC, 0, 0, width, height, 0, 0); } } Tk_FreePixmap(display, pixmap); } static void SendBogusEvent(Tk_Window tkwin) { #define DONTPROPAGATE 0 XEvent event; event.type = event.xexpose.type = Expose; event.xexpose.window = Tk_WindowId(tkwin); event.xexpose.display = Tk_Display(tkwin); event.xexpose.count = 0; event.xexpose.x = event.xexpose.y = 0; event.xexpose.width = Tk_Width(tkwin); event.xexpose.height = Tk_Height(tkwin); XSendEvent(Tk_Display(tkwin), Tk_WindowId(tkwin), DONTPROPAGATE, ExposureMask, &event); } /* *--------------------------------------------------------------------------- * * DisplayText -- * * This procedure is invoked to display a hypertext widget. * Many of the operations which might ordinarily be performed * elsewhere (e.g. in a configuration routine) are done here * because of the somewhat unusual interactions occurring between * the parent and embedded widgets. * * Recompute the layout of the text if necessary. This is * necessary if the world coordinate system has changed. * Specifically, the following may have occurred: * * 1. a text attribute has changed (font, linespacing, etc.). * 2. widget option changed (anchor, width, height). * 3. actual embedded widget was resized. * 4. new text string or file. * * This is deferred to the display routine since potentially * many of these may occur (especially embedded widget changes). * * Set the vertical and horizontal scrollbars (if they are * designated) by issuing a TCL command. Done here since * the text window width and height are needed. * * If the viewport position or contents have changed in the * vertical direction, the now out-of-view embedded widgets * must be moved off the viewport. Since embedded widgets will * obscure the text window, it is imperative that the widgets * are moved off before we try to redraw text in the same area. * This is necessary only for vertical movements. Horizontal * embedded widget movements are handled automatically in the * page drawing routine. * * Get the new first and last line numbers for the viewport. * These line numbers may have changed because either a) * the viewport changed size or position, or b) the text * (embedded widget sizes or text attributes) have changed. * * If the viewport has changed vertically (i.e. the first or * last line numbers have changed), move the now out-of-view * embedded widgets off the viewport. * * Potentially many expose events may be generated when the * the individual embedded widgets are moved and/or resized. * These events need to be ignored. Since (I think) expose * events are guaranteed to happen in order, we can bracket * them by sending phony events (via XSendEvent). The phony * events turn on and off flags indicating which events * should be ignored. * * Finally, the page drawing routine is called. * * Results: * None. * * Side effects: * Commands are output to X to display the hypertext in its * current mode. * *--------------------------------------------------------------------------- */ static void DisplayText(ClientData clientData) /* Information about widget. */ { HText *htPtr = clientData; Tk_Window tkwin = htPtr->tkwin; int oldFirst; /* First line of old viewport */ int oldLast; /* Last line of old viewport */ int deltaY; /* Change in viewport in Y direction */ int reqWidth, reqHeight; #ifdef notdef fprintf(stderr, "calling DisplayText(%s)\n", Tk_PathName(htPtr->tkwin)); #endif htPtr->flags &= ~REDRAW_PENDING; if (tkwin == NULL) { return; /* Window has been destroyed */ } if (htPtr->flags & REQUEST_LAYOUT) { /* * Recompute the layout when widgets are created, deleted, * moved, or resized. Also when text attributes (such as * font, linespacing) have changed. */ ComputeLayout(htPtr); } htPtr->lastWidth = Tk_Width(tkwin); htPtr->lastHeight = Tk_Height(tkwin); /* * Check the requested width and height. We allow two modes: * 1) If the user requested value is greater than zero, use it. * 2) Otherwise, let the window be as big as the virtual text. * This could be too large to display, so constrain it by * the maxWidth and maxHeight values. * * In any event, we need to calculate the size of the virtual * text and then make a geometry request. This is so that widgets * whose size is relative to the master, will be set once. */ if (htPtr->reqWidth > 0) { reqWidth = htPtr->reqWidth; } else { reqWidth = MIN(htPtr->worldWidth, htPtr->maxWidth); if (reqWidth < 1) { reqWidth = 1; } } if (htPtr->reqHeight > 0) { reqHeight = htPtr->reqHeight; } else { reqHeight = MIN(htPtr->worldHeight, htPtr->maxHeight); if (reqHeight < 1) { reqHeight = 1; } } if ((reqWidth != Tk_ReqWidth(tkwin)) || (reqHeight != Tk_ReqHeight(tkwin))) { Tk_GeometryRequest(tkwin, reqWidth, reqHeight); EventuallyRedraw(htPtr); return; /* Try again with new geometry */ } if (!Tk_IsMapped(tkwin)) { return; } /* * Turn off layout requests here, after the text window has been * mapped. Otherwise, relative embedded widget size requests wrt * to the size of parent text window will be wrong. */ htPtr->flags &= ~REQUEST_LAYOUT; /* Is there a pending goto request? */ if (htPtr->flags & GOTO_PENDING) { htPtr->pendingY = htPtr->lineArr[htPtr->reqLineNum].offset; htPtr->flags &= ~GOTO_PENDING; } deltaY = htPtr->pendingY - htPtr->yOffset; oldFirst = htPtr->first, oldLast = htPtr->last; /* * If the viewport has changed size or position, or the text * and/or embedded widgets have changed, adjust the scrollbars to * new positions. */ if (htPtr->flags & TEXT_DIRTY) { int width, height; width = Tk_Width(htPtr->tkwin); height = Tk_Height(htPtr->tkwin); /* Reset viewport origin and world extents */ htPtr->xOffset = Blt_AdjustViewport(htPtr->pendingX, htPtr->worldWidth, width, htPtr->xScrollUnits, BLT_SCROLL_MODE_LISTBOX); htPtr->yOffset = Blt_AdjustViewport(htPtr->pendingY, htPtr->worldHeight, height, htPtr->yScrollUnits, BLT_SCROLL_MODE_LISTBOX); if (htPtr->xScrollCmdObjPtr != NULL) { Blt_UpdateScrollbar(htPtr->interp, htPtr->xScrollCmdObjPtr, htPtr->xOffset, htPtr->xOffset + width, htPtr->worldWidth); } if (htPtr->yScrollCmdObjPtr != NULL) { Blt_UpdateScrollbar(htPtr->interp, htPtr->yScrollCmdObjPtr, htPtr->yOffset, htPtr->yOffset + height, htPtr->worldHeight); } /* * Given a new viewport or text height, find the first and * last line numbers of the new viewport. */ if (GetVisibleLines(htPtr) != TCL_OK) { return; } } /* * This is a kludge: Send an expose event before and after * drawing the page of text. Since moving and resizing of the * embedded widgets will cause redundant expose events in the parent * window, the phony events will bracket them indicating no * action should be taken. */ SendBogusEvent(tkwin); /* * If either the position of the viewport has changed or the size * of width or height of the entire text have changed, move the * widgets from the previous viewport out of the current * viewport. Worry only about the vertical embedded widget movements. * The page is always draw at full width and the viewport will clip * the text. */ if ((htPtr->first != oldFirst) || (htPtr->last != oldLast)) { int offset; int i; int first, last; Blt_ChainLink link; EmbeddedWidget *winPtr; /* Figure out which lines are now out of the viewport */ if ((htPtr->first > oldFirst) && (htPtr->first <= oldLast)) { first = oldFirst, last = htPtr->first; } else if ((htPtr->last < oldLast) && (htPtr->last >= oldFirst)) { first = htPtr->last, last = oldLast; } else { first = oldFirst, last = oldLast; } for (i = first; i <= last; i++) { offset = htPtr->lineArr[i].offset; for (link = Blt_Chain_FirstLink(htPtr->lineArr[i].chain); link != NULL; link = Blt_Chain_NextLink(link)) { winPtr = Blt_Chain_GetValue(link); if (winPtr->tkwin != NULL) { MoveEmbeddedWidget(winPtr, offset); winPtr->flags &= ~WIDGET_VISIBLE; } } } } DrawPage(htPtr, deltaY); SendBogusEvent(tkwin); /* Reset flags */ htPtr->flags &= ~TEXT_DIRTY; } /* Selection Procedures */ /* *--------------------------------------------------------------------------- * * TextSelectionProc -- * * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored * at buffer. Buffer is filled (or partially filled) with a * NULL-terminated string containing part or all of the selection, * as given by offset and maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int TextSelectionProc( ClientData clientData, /* Information about Text widget. */ int offset, /* Offset within selection of first * character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place * at buffer, not including terminating * NULL character. */ { HText *htPtr = clientData; int size; if ((htPtr->selFirst < 0) || (!htPtr->exportSelection)) { return -1; } size = (htPtr->selLast - htPtr->selFirst) + 1 - offset; if (size > maxBytes) { size = maxBytes; } if (size <= 0) { return 0; /* huh? */ } strncpy(buffer, htPtr->charArr + htPtr->selFirst + offset, size); buffer[size] = '\0'; return size; } /* *--------------------------------------------------------------------------- * * TextLostSelection -- * * This procedure is called back by Tk when the selection is * grabbed away from a Text widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *--------------------------------------------------------------------------- */ static void TextLostSelection(ClientData clientData) /* Information about Text widget. */ { HText *htPtr = clientData; if ((htPtr->selFirst >= 0) && (htPtr->exportSelection)) { htPtr->selFirst = htPtr->selLast = -1; EventuallyRedraw(htPtr); } } /* *--------------------------------------------------------------------------- * * SelectLine -- * * Modify the selection by moving both its anchored and un-anchored * ends. This could make the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectLine( HText *htPtr, /* Information about widget. */ int tindex) /* Index of element that is to * become the "other" end of the * selection. */ { int selFirst, selLast; int lineNum; Line *linePtr; lineNum = IndexSearch(htPtr, tindex, 0, htPtr->nLines - 1); if (lineNum < 0) { char string[200]; sprintf_s(string, 200, "can't determine line number from index \"%d\"", tindex); Tcl_AppendResult(htPtr->interp, string, (char *)NULL); return TCL_ERROR; } linePtr = htPtr->lineArr + lineNum; /* * Grab the selection if we don't own it already. */ if ((htPtr->exportSelection) && (htPtr->selFirst == -1)) { Tk_OwnSelection(htPtr->tkwin, XA_PRIMARY, TextLostSelection, htPtr); } selFirst = linePtr->textStart; selLast = linePtr->textEnd; htPtr->selAnchor = tindex; if ((htPtr->selFirst != selFirst) || (htPtr->selLast != selLast)) { htPtr->selFirst = selFirst; htPtr->selLast = selLast; EventuallyRedraw(htPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectWord -- * * Modify the selection by moving both its anchored and un-anchored * ends. This could make the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectWord( HText *htPtr, /* Information about widget. */ int tindex) /* Index of element that is to * become the "other" end of the * selection. */ { int selFirst, selLast; int i; for (i = tindex; i < htPtr->nChars; i++) { if (isspace(UCHAR(htPtr->charArr[i]))) { break; } } selLast = i - 1; for (i = tindex; i >= 0; i--) { if (isspace(UCHAR(htPtr->charArr[i]))) { break; } } selFirst = i + 1; if (selFirst > selLast) { selFirst = selLast = tindex; } /* * Grab the selection if we don't own it already. */ if ((htPtr->exportSelection) && (htPtr->selFirst == -1)) { Tk_OwnSelection(htPtr->tkwin, XA_PRIMARY, TextLostSelection, htPtr); } htPtr->selAnchor = tindex; if ((htPtr->selFirst != selFirst) || (htPtr->selLast != selLast)) { htPtr->selFirst = selFirst, htPtr->selLast = selLast; EventuallyRedraw(htPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectTextBlock -- * * Modify the selection by moving its un-anchored end. This * could make the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectTextBlock( HText *htPtr, /* Information about widget. */ int tindex) /* Index of element that is to * become the "other" end of the * selection. */ { int selFirst, selLast; /* * Grab the selection if we don't own it already. */ if ((htPtr->exportSelection) && (htPtr->selFirst == -1)) { Tk_OwnSelection(htPtr->tkwin, XA_PRIMARY, TextLostSelection, htPtr); } /* If the anchor hasn't been set yet, assume the beginning of the text*/ if (htPtr->selAnchor < 0) { htPtr->selAnchor = 0; } if (htPtr->selAnchor <= tindex) { selFirst = htPtr->selAnchor; selLast = tindex; } else { selFirst = tindex; selLast = htPtr->selAnchor; } if ((htPtr->selFirst != selFirst) || (htPtr->selLast != selLast)) { htPtr->selFirst = selFirst, htPtr->selLast = selLast; EventuallyRedraw(htPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectOp -- * * This procedure handles the individual options for text * selections. The selected text is designated by start and end * indices into the text pool. The selected segment has both a * anchored and unanchored ends. The following selection * operations are implemented: * * "adjust" - resets either the first or last index * of the selection. * "clear" - clears the selection. Sets first/last * indices to -1. * "from" - sets the index of the selection anchor. * "line" - sets the first of last indices to the * start and end of the line at the * designated point. * "present" - return "1" if a selection is available, * "0" otherwise. * "range" - sets the first and last indices. * "to" - sets the index of the un-anchored end. * "word" - sets the first of last indices to the * start and end of the word at the * designated point. * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *string; char c; int iselection; int length; int result = TCL_OK; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'c') && (strncmp(string, "clear", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " selection clear\"", (char *)NULL); return TCL_ERROR; } if (htPtr->selFirst != -1) { htPtr->selFirst = htPtr->selLast = -1; EventuallyRedraw(htPtr); } return TCL_OK; } else if ((c == 'p') && (strncmp(string, "present", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " selection present\"", (char *)NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (htPtr->selFirst != -1) ? "0" : "1", (char *)NULL); return TCL_OK; } else if ((c == 'r') && (strncmp(string, "range", length) == 0)) { int selFirst, selLast; if (objc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " selection range first last\"", (char *)NULL); return TCL_ERROR; } if (GetIndex(htPtr, objv[3], &selFirst) != TCL_OK) { return TCL_ERROR; } if (GetIndex(htPtr, objv[4], &selLast) != TCL_OK) { return TCL_ERROR; } htPtr->selAnchor = selFirst; SelectTextBlock(htPtr, selLast); return TCL_OK; } if (objc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " selection ", Tcl_GetString(objv[2]), " index\"", (char *)NULL); return TCL_ERROR; } if (GetIndex(htPtr, objv[3], &iselection) != TCL_OK) { return TCL_ERROR; } if ((c == 'f') && (strncmp(string, "from", length) == 0)) { htPtr->selAnchor = iselection; } else if ((c == 'a') && (strncmp(string, "adjust", length) == 0)) { int half1, half2; half1 = (htPtr->selFirst + htPtr->selLast) / 2; half2 = (htPtr->selFirst + htPtr->selLast + 1) / 2; if (iselection < half1) { htPtr->selAnchor = htPtr->selLast; } else if (iselection > half2) { htPtr->selAnchor = htPtr->selFirst; } result = SelectTextBlock(htPtr, iselection); } else if ((c == 't') && (strncmp(string, "to", length) == 0)) { result = SelectTextBlock(htPtr, iselection); } else if ((c == 'w') && (strncmp(string, "word", length) == 0)) { result = SelectWord(htPtr, iselection); } else if ((c == 'l') && (strncmp(string, "line", length) == 0)) { result = SelectLine(htPtr, iselection); } else { Tcl_AppendResult(interp, "bad selection operation \"", string, "\": should be \"adjust\", \"clear\", \"from\", \"line\", \ \"present\", \"range\", \"to\", or \"word\"", (char *)NULL); return TCL_ERROR; } return result; } /* *--------------------------------------------------------------------------- * * GotoOp -- * * Move the top line of the viewport to the new location based * upon the given line number. Force out-of-range requests to the * top or bottom of text. * * Results: * A standard TCL result. If TCL_OK, interp->result contains the * current line number. * * Side effects: * At the next idle point, the text viewport will be move to the * new line. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GotoOp( HText *htPtr, Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { int line; line = htPtr->first; if (objc == 3) { int tindex; if (GetIndex(htPtr, objv[2], &tindex) != TCL_OK) { return TCL_ERROR; } line = IndexSearch(htPtr, tindex, 0, htPtr->nLines - 1); if (line < 0) { char string[200]; sprintf_s(string, 200, "can't determine line number from index \"%d\"", tindex); Tcl_AppendResult(htPtr->interp, string, (char *)NULL); return TCL_ERROR; } htPtr->reqLineNum = line; htPtr->flags |= TEXT_DIRTY; /* * Make only a request for a change in the viewport. Defer * the actual scrolling until the text layout is adjusted at * the next idle point. */ if (line != htPtr->first) { htPtr->flags |= GOTO_PENDING; EventuallyRedraw(htPtr); } } Tcl_SetIntObj(Tcl_GetObjResult(htPtr->interp), line); return TCL_OK; } static int XViewOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width, worldWidth; width = Tk_Width(htPtr->tkwin); worldWidth = htPtr->worldWidth; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* Report first and last fractions */ fract = (double)htPtr->xOffset / worldWidth; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(CLAMP(fract, 0.0, 1.0))); fract = (double)(htPtr->xOffset + width) / worldWidth; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(CLAMP(fract, 0.0, 1.0))); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } htPtr->pendingX = htPtr->xOffset; if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &htPtr->pendingX, worldWidth, width, htPtr->xScrollUnits, BLT_SCROLL_MODE_LISTBOX) != TCL_OK) { return TCL_ERROR; } htPtr->flags |= TEXT_DIRTY; EventuallyRedraw(htPtr); return TCL_OK; } static int YViewOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int height, worldHeight; height = Tk_Height(htPtr->tkwin); worldHeight = htPtr->worldHeight; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); fract = (double)htPtr->yOffset / worldHeight; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(CLAMP(fract, 0.0, 1.0))); fract = (double)(htPtr->yOffset + height) / worldHeight; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(CLAMP(fract, 0.0, 1.0))); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } htPtr->pendingY = htPtr->yOffset; if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &htPtr->pendingY, worldHeight, height, htPtr->yScrollUnits, BLT_SCROLL_MODE_LISTBOX) != TCL_OK) { return TCL_ERROR; } htPtr->flags |= TEXT_DIRTY; EventuallyRedraw(htPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AppendOp -- * * This procedure embeds a Tk widget into the hypertext. * * Results: * A standard TCL result. * * Side effects: * Memory is allocated. EmbeddedWidget gets configured. * *--------------------------------------------------------------------------- */ static int AppendOp( HText *htPtr, /* Hypertext widget */ Tcl_Interp *interp, /* Interpreter associated with widget */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Line *linePtr; EmbeddedWidget *winPtr; winPtr = CreateEmbeddedWidget(htPtr, Tcl_GetString(objv[2])); if (winPtr == NULL) { return TCL_ERROR; } if (Blt_ConfigureWidgetFromObj(interp, htPtr->tkwin, widgetConfigSpecs, objc - 3, objv + 3, (char *)winPtr, 0) != TCL_OK) { return TCL_ERROR; } /* * Append widget to list of embedded widgets of the last line. */ linePtr = GetLastLine(htPtr); if (linePtr == NULL) { Tcl_AppendResult(interp, "can't allocate line structure", (char *)NULL); return TCL_ERROR; } Blt_Chain_Append(linePtr->chain, winPtr); linePtr->width += winPtr->cavityWidth; winPtr->precedingTextEnd = linePtr->textEnd; htPtr->flags |= (WIDGET_APPENDED | REQUEST_LAYOUT); EventuallyRedraw(htPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * WindowsOp -- * * Returns a list of all the pathNames of embedded widgets of the * HText widget. If a pattern argument is given, only the names * of windows matching it will be placed into the list. * * Results: * Standard TCL result. If TCL_OK, interp->result will contain * the list of the embedded widget pathnames. Otherwise it will * contain an error message. * *--------------------------------------------------------------------------- */ static int WindowsOp( HText *htPtr, /* Hypertext widget record */ Tcl_Interp *interp, /* Interpreter associated with widget */ int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; char *name; char *pattern; pattern = (objc == 2) ? NULL : Tcl_GetString(objv[2]); for (hPtr = Blt_FirstHashEntry(&htPtr->widgetTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { EmbeddedWidget *winPtr; winPtr = Blt_GetHashValue(hPtr); if (winPtr->tkwin == NULL) { fprintf(stderr, "window `%s' is null\n", Tk_PathName(Blt_GetHashKey(&htPtr->widgetTable, hPtr))); continue; } name = Tk_PathName(winPtr->tkwin); if ((pattern == NULL) || (Tcl_StringMatch(name, pattern))) { Tcl_AppendElement(interp, name); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp( HText *htPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { char *itemPtr; Blt_ConfigSpec *specsPtr; char *string; if (objc > 3) { string = Tcl_GetString(objv[2]); if (string[0] == '.') { Tk_Window tkwin; EmbeddedWidget *winPtr; /* EmbeddedWidget window to be configured */ tkwin = Tk_NameToWindow(interp, string, htPtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } winPtr = FindEmbeddedWidget(htPtr, tkwin); if (winPtr == NULL) { Tcl_AppendResult(interp, "window \"", string, "\" is not managed by \"", Tcl_GetString(objv[0]), "\"", (char *)NULL); return TCL_ERROR; } specsPtr = widgetConfigSpecs; itemPtr = (char *)winPtr; return Blt_ConfigureValueFromObj(interp, htPtr->tkwin, specsPtr, itemPtr, objv[3], 0); } } specsPtr = configSpecs; itemPtr = (char *)htPtr; return Blt_ConfigureValueFromObj(interp, htPtr->tkwin, specsPtr, itemPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or reconfigure) * a hypertext widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for htPtr; old resources get freed, if there were any. * The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *itemPtr; Blt_ConfigSpec *specsPtr; if (objc > 2) { char *string; string = Tcl_GetString(objv[2]); if (string[0] == '.') { Tk_Window tkwin; EmbeddedWidget *winPtr; /* EmbeddedWidget window to be configured */ tkwin = Tk_NameToWindow(interp, string, htPtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } winPtr = FindEmbeddedWidget(htPtr, tkwin); if (winPtr == NULL) { Tcl_AppendResult(interp, "window \"", string, "\" is not managed by \"", Tcl_GetString(objv[0]), "\"", (char *)NULL); return TCL_ERROR; } specsPtr = widgetConfigSpecs; itemPtr = (char *)winPtr; objv++; objc--; goto config; } } specsPtr = configSpecs; itemPtr = (char *)htPtr; config: if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, htPtr->tkwin, specsPtr, itemPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, htPtr->tkwin, specsPtr, itemPtr, objv[2], 0); } if (Blt_ConfigureWidgetFromObj(interp, htPtr->tkwin, specsPtr, objc - 2, objv + 2, itemPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if (itemPtr == (char *)htPtr) { /* Reconfigure the master */ if (ConfigureText(interp, htPtr) != TCL_OK) { return TCL_ERROR; } } else { htPtr->flags |= REQUEST_LAYOUT; } EventuallyRedraw(htPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan for hypertext widgets. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp( HText *htPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { char *string; char c; int length; int x, y; string = Tcl_GetString(objv[3]); if (Blt_GetXY(interp, htPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { htPtr->scanMark.x = x, htPtr->scanMark.y = y; htPtr->scanPt.x = htPtr->xOffset; htPtr->scanPt.y = htPtr->yOffset; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { int px, py; px = htPtr->scanPt.x - (10 * (x - htPtr->scanMark.x)); py = htPtr->scanPt.y - (10 * (y - htPtr->scanMark.y)); if (px < 0) { px = htPtr->scanPt.x = 0; htPtr->scanMark.x = x; } else if (px >= htPtr->worldWidth) { px = htPtr->scanPt.x = htPtr->worldWidth - htPtr->xScrollUnits; htPtr->scanMark.x = x; } if (py < 0) { py = htPtr->scanPt.y = 0; htPtr->scanMark.y = y; } else if (py >= htPtr->worldHeight) { py = htPtr->scanPt.y = htPtr->worldHeight - htPtr->yScrollUnits; htPtr->scanMark.y = y; } if ((py != htPtr->pendingY) || (px != htPtr->pendingX)) { htPtr->pendingX = px, htPtr->pendingY = py; htPtr->flags |= TEXT_DIRTY; EventuallyRedraw(htPtr); } } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SearchOp -- * * Returns the linenumber of the next line matching the given * pattern within the range of lines provided. If the first * line number is greater than the last, the search is done in * reverse. * *--------------------------------------------------------------------------- */ static int SearchOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *startPtr; Tcl_RegExp regExpToken; int iFirst, iLast; int matchStart, matchEnd; int match; char *string; string = Tcl_GetString(objv[2]); regExpToken = Tcl_RegExpCompile(interp, string); if (regExpToken == NULL) { return TCL_ERROR; } iFirst = 0; iLast = htPtr->nChars; if (objc > 3) { if (GetIndex(htPtr, objv[3], &iFirst) != TCL_OK) { return TCL_ERROR; } } if (objc == 4) { if (GetIndex(htPtr, objv[4], &iLast) != TCL_OK) { return TCL_ERROR; } } if (iLast < iFirst) { return TCL_ERROR; } matchStart = matchEnd = -1; startPtr = htPtr->charArr + iFirst; { char *p; char saved; p = htPtr->charArr + (iLast + 1); saved = *p; *p = '\0'; /* Make the line a string by changing the * '\n' into a NUL byte before searching */ match = Tcl_RegExpExec(interp, regExpToken, startPtr, startPtr); *p = saved; } if (match < 0) { return TCL_ERROR; } else if (match > 0) { const char *endPtr; Tcl_RegExpRange(regExpToken, 0, &startPtr, &endPtr); if ((startPtr != NULL) || (endPtr != NULL)) { matchStart = startPtr - htPtr->charArr; matchEnd = endPtr - htPtr->charArr - 1; } } if (match > 0) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(matchStart)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(matchEnd)); Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_ResetResult(interp); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RangeOp -- * * Returns the characters designated by the range of elements. * *--------------------------------------------------------------------------- */ static int RangeOp( HText *htPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *startPtr, *endPtr; char saved; int textFirst, textLast; textFirst = htPtr->selFirst; textLast = htPtr->selLast; if (textFirst < 0) { textFirst = 0; textLast = htPtr->nChars - 1; } if (objc > 2) { if (GetIndex(htPtr, objv[2], &textFirst) != TCL_OK) { return TCL_ERROR; } } if (objc == 4) { if (GetIndex(htPtr, objv[3], &textLast) != TCL_OK) { return TCL_ERROR; } } if (textLast < textFirst) { Tcl_AppendResult(interp, "first index is greater than last", (char *)NULL); return TCL_ERROR; } startPtr = htPtr->charArr + textFirst; endPtr = htPtr->charArr + (textLast + 1); saved = *endPtr; *endPtr = '\0'; /* Make the line into a string by * changing the * '\n' into a '\0' * before copying */ Tcl_SetStringObj(Tcl_GetObjResult(interp), startPtr, -1); *endPtr = saved; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp( HText *htPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { int tindex; if (GetIndex(htPtr, objv[2], &tindex) != TCL_OK) { return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), tindex); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LinePosOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int LinePosOp( HText *htPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { int line, cpos, tindex; char string[200]; if (GetIndex(htPtr, objv[2], &tindex) != TCL_OK) { return TCL_ERROR; } if (GetTextPosition(htPtr, tindex, &line, &cpos) != TCL_OK) { return TCL_ERROR; } sprintf_s(string, 200, "%d.%d", line, cpos); Tcl_SetStringObj(Tcl_GetObjResult(interp), string, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextWidgetCmd -- * * This procedure is invoked to process the TCL command that * corresponds to a widget managed by this module. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec textOps[] = { {"append", 1, AppendOp, 3, 0, "window ?option value?...",}, {"cget", 2, CgetOp, 3, 3, "?window? option",}, {"configure", 2, ConfigureOp, 2, 0, "?window? ?option value?...",}, {"gotoline", 2, GotoOp, 2, 3, "?line?",}, {"index", 1, IndexOp, 3, 3, "string",}, {"linepos", 1, LinePosOp, 3, 3, "string",}, {"range", 2, RangeOp, 2, 4, "?from? ?to?",}, {"scan", 2, ScanOp, 4, 4, "oper @x,y",}, {"search", 3, SearchOp, 3, 5, "pattern ?from? ?to?",}, {"selection", 3, SelectOp, 3, 5, "oper ?index?",}, {"windows", 6, WindowsOp, 2, 3, "?pattern?",}, {"xview", 1, XViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yview", 1, YViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nTextOps = sizeof(textOps) / sizeof(Blt_OpSpec); static int TextWidgetCmd( ClientData clientData, /* Information about hypertext widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { HTextCmdProc *proc; int result; HText *htPtr = clientData; proc = Blt_GetOpFromObj(interp, nTextOps, textOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(htPtr); result = (*proc) (htPtr, interp, objc, objv); Tcl_Release(htPtr); return result; } /* *--------------------------------------------------------------------------- * * TextCmd -- * * This procedure is invoked to process the "htext" TCL command. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int TextCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { HText *htPtr; Tk_Window tkwin; int screenWidth, screenHeight; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } htPtr = Blt_AssertCalloc(1, sizeof(HText)); tkwin = Tk_MainWindow(interp); tkwin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { Blt_Free(htPtr); return TCL_ERROR; } /* Initialize the new hypertext widget */ Tk_SetClass(tkwin, "Htext"); htPtr->tkwin = tkwin; htPtr->display = Tk_Display(tkwin); htPtr->interp = interp; htPtr->nLines = htPtr->arraySize = 0; htPtr->leader = 1; htPtr->xScrollUnits = htPtr->yScrollUnits = 10; htPtr->nRows = htPtr->nColumns = 0; htPtr->selFirst = htPtr->selLast = -1; htPtr->selAnchor = 0; htPtr->exportSelection = TRUE; htPtr->selBW = 2; Blt_SizeOfScreen(tkwin, &screenWidth, &screenHeight); htPtr->maxWidth = screenWidth; htPtr->maxHeight = screenHeight; Blt_InitHashTable(&htPtr->widgetTable, BLT_ONE_WORD_KEYS); Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING, TextSelectionProc, htPtr, XA_STRING); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, TextEventProc, htPtr); Blt_SetWindowInstanceData(tkwin, htPtr); /* *------------------------------------------------------------------------ * * Create the widget command before configuring the widget. This * is because the "-file" and "-text" options may have embedded * commands that self-reference the widget through the * "$blt_htext(widget)" variable. * *------------------------------------------------------------------------ */ htPtr->cmdToken = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), TextWidgetCmd, htPtr, TextDeleteCmdProc); if ((Blt_ConfigureWidgetFromObj(interp, htPtr->tkwin, configSpecs, objc - 2, objv + 2, (char *)htPtr, 0) != TCL_OK) || (ConfigureText(interp, htPtr) != TCL_OK)) { Tk_DestroyWindow(htPtr->tkwin); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_HtextCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"htext", TextCmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_HTEXT */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrLegd.c�������������������������������������������������������������������0000644�0001750�0001750�00000255374�11462120062�015057� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrLegd.c -- * * This module implements the legend for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" #include "bltGrElem.h" #include "bltPicture.h" #include <X11/Xutil.h> #include <X11/Xatom.h> /* * Selection related flags: * * SELECT_EXPORT Export the selection to X11. * * SELECT_PENDING A "selection" command idle task is pending. * * SELECT_CLEAR Clear selection flag of entry. * * SELECT_SET Set selection flag of entry. * * SELECT_TOGGLE Toggle selection flag of entry. * * SELECT_MASK Mask of selection set/clear/toggle flags. * * SELECT_SORTED Indicates if the entries in the selection * should be sorted or displayed in the order * they were selected. * */ #define SELECT_CLEAR (1<<16) #define SELECT_EXPORT (1<<17) #define SELECT_PENDING (1<<18) #define SELECT_SET (1<<19) #define SELECT_TOGGLE (SELECT_SET | SELECT_CLEAR) #define SELECT_MASK (SELECT_SET | SELECT_CLEAR) #define SELECT_SORTED (1<<20) #define RAISED (1<<21) #define SELECT_MODE_SINGLE (1<<0) #define SELECT_MODE_MULTIPLE (1<<1) typedef int (GraphLegendProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* * Legend -- * * Contains information specific to how the legend will be displayed. */ struct _Legend { unsigned int flags; ClassId classId; /* Type: Element or Marker. */ int nEntries; /* Number of element entries in * table. */ short int nColumns, nRows; /* Number of columns and rows in * legend */ short int width, height; /* Dimensions of the legend */ short int entryWidth, entryHeight; int site; short int xReq, yReq; /* User-requested site of legend, not * the final actual position. Used in * conjunction with the anchor below * to determine location of the * legend. */ Tk_Anchor anchor; /* Anchor of legend. Used to interpret * the positioning point of the legend * in the graph*/ int x, y; /* Computed origin of legend. */ Graph *graphPtr; Tcl_Command cmdToken; /* Token for graph's widget command. */ int reqColumns, reqRows; Blt_Pad ixPad, iyPad; /* # of pixels interior padding around * legend entries */ Blt_Pad xPad, yPad; /* # of pixels padding to exterior of * legend */ Tk_Window tkwin; /* If non-NULL, external window to draw * legend. */ TextStyle style; int maxSymSize; /* Size of largest symbol to be * displayed. Used to calculate size * of legend */ XColor *fgColor; Blt_Background activeBg; /* Active legend entry background * color. */ XColor *activeFgColor; int activeRelief; /* 3-D effect on active entry. */ int entryBW; /* Border width around each entry in * legend. */ Blt_Background normalBg; /* 3-D effect of legend. */ int borderWidth; /* Width of legend 3-D border */ int relief; /* 3-d effect of border around the * legend: TK_RELIEF_RAISED etc. */ Blt_BindTable bindTable; int selRelief; int selBW; XColor *selInFocusFgColor; /* Text color of a selected entry. */ XColor *selOutFocusFgColor; Blt_Background selInFocusBg; Blt_Background selOutFocusBg; XColor *focusColor; Blt_Dashes focusDashes; /* Dash on-off value. */ GC focusGC; /* Graphics context for the active * label. */ const char *takeFocus; int focus; /* Position of the focus entry. */ int cursorX, cursorY; /* Position of the insertion cursor in * the textbox window. */ short int cursorWidth; /* Size of the insertion cursor * symbol. */ short int cursorHeight; Element *focusPtr; /* Element that currently has the * focus. If NULL, no legend entry has * the focus. */ Element *selAnchorPtr; /* Fixed end of selection. Used to * extend the selection while * maintaining the other end of the * selection. */ Element *selMarkPtr; Element *selFirstPtr; /* First element selected in current * pick. */ Element *selLastPtr; /* Last element selected in current * pick. */ int exportSelection; int active; int cursorOn; /* Indicates if the cursor is * displayed. */ int onTime, offTime; /* Time in milliseconds to wait before * changing the cursor from off-to-on * and on-to-off. Setting offTime to 0 * makes the * cursor steady. */ Tcl_TimerToken timerToken; /* Handle for a timer event called * periodically to blink the cursor. */ const char *selectCmd; /* TCL script that's invoked whenever * the selection changes. */ int selectMode; /* Mode of selection: single or * multiple. */ Blt_HashTable selectTable; /* Table of selected elements. Used to * quickly determine whether an element * is selected. */ Blt_Chain selected; /* List of selected elements. */ const char *title; unsigned int titleWidth, titleHeight; TextStyle titleStyle; /* Legend title attributes */ }; #define padLeft xPad.side1 #define padRight xPad.side2 #define padTop yPad.side1 #define padBottom yPad.side2 #define PADDING(x) ((x).side1 + (x).side2) #define LABEL_PAD 2 #define DEF_LEGEND_ACTIVEBACKGROUND RGB_SKYBLUE4 #define DEF_LEGEND_ACTIVEBORDERWIDTH "2" #define DEF_LEGEND_ACTIVEFOREGROUND RGB_WHITE #define DEF_LEGEND_ACTIVERELIEF "flat" #define DEF_LEGEND_ANCHOR "n" #define DEF_LEGEND_BACKGROUND (char *)NULL #define DEF_LEGEND_BORDERWIDTH STD_BORDERWIDTH #define DEF_LEGEND_COLUMNS "0" #define DEF_LEGEND_EXPORTSELECTION "no" #define DEF_LEGEND_FONT "{Sans Serif} 8" #define DEF_LEGEND_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_LEGEND_HIDE "no" #define DEF_LEGEND_IPADX "1" #define DEF_LEGEND_IPADY "1" #define DEF_LEGEND_PADX "1" #define DEF_LEGEND_PADY "1" #define DEF_LEGEND_POSITION "rightmargin" #define DEF_LEGEND_RAISED "no" #define DEF_LEGEND_RELIEF "flat" #define DEF_LEGEND_ROWS "0" #define DEF_LEGEND_SELECTBACKGROUND RGB_SKYBLUE4 #define DEF_LEGEND_SELECT_BG_MONO STD_SELECT_BG_MONO #define DEF_LEGEND_SELECTBORDERWIDTH "1" #define DEF_LEGEND_SELECTMODE "multiple" #define DEF_LEGEND_SELECT_FG_MONO STD_SELECT_FG_MONO #define DEF_LEGEND_SELECTFOREGROUND RGB_WHITE /*STD_SELECT_FOREGROUND*/ #define DEF_LEGEND_SELECTRELIEF "flat" #define DEF_LEGEND_FOCUSDASHES "dot" #define DEF_LEGEND_FOCUSEDIT "no" #define DEF_LEGEND_FOCUSFOREGROUND STD_ACTIVE_FOREGROUND #define DEF_LEGEND_FOCUS_FG_MONO STD_ACTIVE_FG_MONO #define DEF_LEGEND_TAKEFOCUS "1" #define DEF_LEGEND_TITLE (char *)NULL #define DEF_LEGEND_TITLECOLOR STD_NORMAL_FOREGROUND #define DEF_LEGEND_TITLEFONT "{Sans Serif} 8 bold" static Blt_OptionParseProc ObjToPosition; static Blt_OptionPrintProc PositionToObj; static Blt_CustomOption legendPositionOption = { ObjToPosition, PositionToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToSelectmode; static Blt_OptionPrintProc SelectmodeToObj; static Blt_CustomOption selectmodeOption = { ObjToSelectmode, SelectmodeToObj, NULL, NULL, }; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_LEGEND_ACTIVEBACKGROUND, Blt_Offset(Legend, activeBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-activeborderwidth", "activeBorderWidth", "BorderWidth", DEF_LEGEND_BORDERWIDTH, Blt_Offset(Legend, entryBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_LEGEND_ACTIVEFOREGROUND, Blt_Offset(Legend, activeFgColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_LEGEND_ACTIVERELIEF, Blt_Offset(Legend, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_LEGEND_ANCHOR, Blt_Offset(Legend, anchor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_LEGEND_BACKGROUND, Blt_Offset(Legend, normalBg),BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_LEGEND_BORDERWIDTH, Blt_Offset(Legend, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_INT_NNEG, "-columns", "columns", "columns", DEF_LEGEND_COLUMNS, Blt_Offset(Legend, reqColumns), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-exportselection", "exportSelection", "ExportSelection", DEF_LEGEND_EXPORTSELECTION, Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SELECT_EXPORT}, {BLT_CONFIG_DASHES, "-focusdashes", "focusDashes", "FocusDashes", DEF_LEGEND_FOCUSDASHES, Blt_Offset(Legend, focusDashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground", DEF_LEGEND_FOCUSFOREGROUND, Blt_Offset(Legend, focusColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground", DEF_LEGEND_FOCUS_FG_MONO, Blt_Offset(Legend, focusColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_LEGEND_FONT, Blt_Offset(Legend, style.font), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_LEGEND_FOREGROUND, Blt_Offset(Legend, fgColor), 0}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_LEGEND_HIDE, Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_PAD, "-ipadx", "iPadX", "Pad", DEF_LEGEND_IPADX, Blt_Offset(Legend, ixPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-ipady", "iPadY", "Pad", DEF_LEGEND_IPADY, Blt_Offset(Legend, iyPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-nofocusselectbackground", "noFocusSelectBackground", "NoFocusSelectBackground", DEF_LEGEND_SELECTBACKGROUND, Blt_Offset(Legend, selOutFocusBg), 0}, {BLT_CONFIG_COLOR, "-nofocusselectforeground", "noFocusSelectForeground", "NoFocusSelectForeground", DEF_LEGEND_SELECTFOREGROUND, Blt_Offset(Legend, selOutFocusFgColor), 0}, {BLT_CONFIG_PAD, "-padx", "padX", "Pad", DEF_LEGEND_PADX, Blt_Offset(Legend, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", "padY", "Pad", DEF_LEGEND_PADY, Blt_Offset(Legend, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-position", "position", "Position", DEF_LEGEND_POSITION, 0, BLT_CONFIG_DONT_SET_DEFAULT, &legendPositionOption}, {BLT_CONFIG_BITMASK, "-raised", "raised", "Raised", DEF_LEGEND_RAISED, Blt_Offset(Legend, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)RAISED}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_LEGEND_RELIEF, Blt_Offset(Legend, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT_NNEG, "-rows", "rows", "rows", DEF_LEGEND_ROWS, Blt_Offset(Legend, reqRows), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Background", DEF_LEGEND_SELECTBACKGROUND, Blt_Offset(Legend, selInFocusBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_LEGEND_SELECTBORDERWIDTH, Blt_Offset(Legend, selBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-selectcommand", "selectCommand", "SelectCommand", (char *)NULL, Blt_Offset(Legend, selectCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_LEGEND_SELECT_FG_MONO, Blt_Offset(Legend, selInFocusFgColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_LEGEND_SELECTFOREGROUND, Blt_Offset(Legend, selInFocusFgColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_CUSTOM, "-selectmode", "selectMode", "SelectMode", DEF_LEGEND_SELECTMODE, Blt_Offset(Legend, selectMode), BLT_CONFIG_DONT_SET_DEFAULT, &selectmodeOption}, {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief", DEF_LEGEND_SELECTRELIEF, Blt_Offset(Legend, selRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_LEGEND_TAKEFOCUS, Blt_Offset(Legend, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-title", "title", "Title", DEF_LEGEND_TITLE, Blt_Offset(Legend, title), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-titlecolor", "titleColor", "Foreground", DEF_LEGEND_TITLECOLOR, Blt_Offset(Legend, titleStyle.color), 0}, {BLT_CONFIG_FONT, "-titlefont", "titleFont", "Font", DEF_LEGEND_TITLEFONT, Blt_Offset(Legend, titleStyle.font), 0}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Tcl_IdleProc DisplayLegend; static Blt_BindPickProc PickEntryProc; static Tk_EventProc LegendEventProc; static Tcl_TimerProc BlinkCursorProc; static Tk_LostSelProc LostSelectionProc; static Tk_SelectionProc SelectionProc; BLT_EXTERN Tcl_ObjCmdProc Blt_GraphInstCmdProc; /* *--------------------------------------------------------------------------- * * Blt_Legend_EventuallyRedraw -- * * Tells the Tk dispatcher to call the graph display routine at the next * idle point. This request is made only if the window is displayed and * no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ void Blt_Legend_EventuallyRedraw(Graph *graphPtr) { Legend *legendPtr = graphPtr->legend; if ((legendPtr->tkwin != NULL) && !(legendPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayLegend, legendPtr); legendPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * SelectCmdProc -- * * Invoked at the next idle point whenever the current selection changes. * Executes some application-specific code in the -selectcommand option. * This provides a way for applications to handle selection changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void SelectCmdProc(ClientData clientData) { Legend *legendPtr = clientData; Tcl_Preserve(legendPtr); legendPtr->flags &= ~SELECT_PENDING; if (legendPtr->selectCmd != NULL) { Tcl_Interp *interp; interp = legendPtr->graphPtr->interp; if (Tcl_GlobalEval(interp, legendPtr->selectCmd) != TCL_OK) { Tcl_BackgroundError(interp); } } Tcl_Release(legendPtr); } /* *--------------------------------------------------------------------------- * * EventuallyInvokeSelectCmd -- * * Queues a request to execute the -selectcommand code associated with * the widget at the next idle point. Invoked whenever the selection * changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void EventuallyInvokeSelectCmd(Legend *legendPtr) { if ((legendPtr->flags & SELECT_PENDING) == 0) { legendPtr->flags |= SELECT_PENDING; Tcl_DoWhenIdle(SelectCmdProc, legendPtr); } } static void ClearSelection(Legend *legendPtr) { Blt_DeleteHashTable(&legendPtr->selectTable); Blt_InitHashTable(&legendPtr->selectTable, BLT_ONE_WORD_KEYS); Blt_Chain_Reset(legendPtr->selected); Blt_Legend_EventuallyRedraw(legendPtr->graphPtr); if (legendPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(legendPtr); } } /* *--------------------------------------------------------------------------- * * LostSelectionProc -- * * This procedure is called back by Tk when the selection is grabbed away * from a Text widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is marked as * not containing a selection. * *--------------------------------------------------------------------------- */ static void LostSelectionProc(ClientData clientData) { Legend *legendPtr = clientData; if (legendPtr->flags & SELECT_EXPORT) { ClearSelection(legendPtr); } } /* *--------------------------------------------------------------------------- * * LegendEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * graphs. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, the graph is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void LegendEventProc(ClientData clientData, XEvent *eventPtr) { Graph *graphPtr = clientData; Legend *legendPtr; legendPtr = graphPtr->legend; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { Blt_Legend_EventuallyRedraw(graphPtr); } } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { legendPtr->flags |= FOCUS; } else { legendPtr->flags &= ~FOCUS; } Tcl_DeleteTimerHandler(legendPtr->timerToken); if ((legendPtr->active) && (legendPtr->flags & FOCUS)) { legendPtr->cursorOn = TRUE; if (legendPtr->offTime != 0) { legendPtr->timerToken = Tcl_CreateTimerHandler( legendPtr->onTime, BlinkCursorProc, graphPtr); } } else { legendPtr->cursorOn = FALSE; legendPtr->timerToken = (Tcl_TimerToken)NULL; } Blt_Legend_EventuallyRedraw(graphPtr); } else if (eventPtr->type == DestroyNotify) { Graph *graphPtr = legendPtr->graphPtr; if (legendPtr->site == LEGEND_WINDOW) { Blt_DeleteWindowInstanceData(legendPtr->tkwin); if (legendPtr->cmdToken != NULL) { Tcl_DeleteCommandFromToken(graphPtr->interp, legendPtr->cmdToken); legendPtr->cmdToken = NULL; } legendPtr->tkwin = graphPtr->tkwin; } if (legendPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayLegend, legendPtr); legendPtr->flags &= ~REDRAW_PENDING; } legendPtr->site = LEGEND_RIGHT; legendPtr->flags |= HIDE; graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); Blt_MoveBindingTable(legendPtr->bindTable, graphPtr->tkwin); Blt_EventuallyRedrawGraph(graphPtr); } else if (eventPtr->type == ConfigureNotify) { Blt_Legend_EventuallyRedraw(graphPtr); } } static int CreateLegendWindow(Tcl_Interp *interp, Legend *legendPtr, const char *pathName) { Graph *graphPtr; Tk_Window tkwin; graphPtr = legendPtr->graphPtr; tkwin = Tk_CreateWindowFromPath(interp, graphPtr->tkwin, pathName, NULL); if (tkwin == NULL) { return TCL_ERROR; } Blt_SetWindowInstanceData(tkwin, legendPtr); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, LegendEventProc, graphPtr); /* Move the legend's binding table to the new window. */ Blt_MoveBindingTable(legendPtr->bindTable, tkwin); if (legendPtr->tkwin != graphPtr->tkwin) { Tk_DestroyWindow(legendPtr->tkwin); } /* Create a command by the same name as the legend window so that Legend * bindings can use %W interchangably. */ legendPtr->cmdToken = Tcl_CreateObjCommand(interp, pathName, Blt_GraphInstCmdProc, graphPtr, NULL); legendPtr->tkwin = tkwin; legendPtr->site = LEGEND_WINDOW; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToPosition -- * * Convert the string representation of a legend XY position into window * coordinates. The form of the string must be "@x,y" or none. * * Results: * The return value is a standard TCL result. The symbol type is written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPosition( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New legend position string */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { Graph *graphPtr; Legend *legendPtr = (Legend *)widgRec; char c; int length; const char *string; graphPtr = legendPtr->graphPtr; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if (c == '\0') { legendPtr->site = LEGEND_RIGHT; } else if ((c == 'l') && (strncmp(string, "leftmargin", length) == 0)) { legendPtr->site = LEGEND_LEFT; } else if ((c == 'r') && (strncmp(string, "rightmargin", length) == 0)) { legendPtr->site = LEGEND_RIGHT; } else if ((c == 't') && (strncmp(string, "topmargin", length) == 0)) { legendPtr->site = LEGEND_TOP; } else if ((c == 'b') && (strncmp(string, "bottommargin", length) == 0)) { legendPtr->site = LEGEND_BOTTOM; } else if ((c == 'p') && (strncmp(string, "plotarea", length) == 0)) { legendPtr->site = LEGEND_PLOT; } else if (c == '@') { char *comma; long x, y; int result; comma = strchr(string + 1, ','); if (comma == NULL) { Tcl_AppendResult(interp, "bad screen position \"", string, "\": should be @x,y", (char *)NULL); return TCL_ERROR; } x = y = 0; *comma = '\0'; result = ((Tcl_ExprLong(interp, string + 1, &x) == TCL_OK) && (Tcl_ExprLong(interp, comma + 1, &y) == TCL_OK)); *comma = ','; if (!result) { return TCL_ERROR; } legendPtr->xReq = x; legendPtr->yReq = y; legendPtr->site = LEGEND_XY; } else if (c == '.') { if (CreateLegendWindow(interp, legendPtr, string) != TCL_OK) { return TCL_ERROR; } Blt_Legend_EventuallyRedraw(graphPtr); } else { Tcl_AppendResult(interp, "bad position \"", string, "\": should be \ \"leftmargin\", \"rightmargin\", \"topmargin\", \"bottommargin\", \ \"plotarea\", windowName or @x,y", (char *)NULL); return TCL_ERROR; } graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PositionToObj -- * * Convert the window coordinates into a string. * * Results: * The string representing the coordinate position is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PositionToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { Legend *legendPtr = (Legend *)widgRec; Tcl_Obj *objPtr; switch (legendPtr->site) { case LEGEND_LEFT: objPtr = Tcl_NewStringObj("leftmargin", -1); break; case LEGEND_RIGHT: objPtr = Tcl_NewStringObj("rightmargin", -1); break; case LEGEND_TOP: objPtr = Tcl_NewStringObj("topmargin", -1); break; case LEGEND_BOTTOM: objPtr = Tcl_NewStringObj("bottommargin", -1); break; case LEGEND_PLOT: objPtr = Tcl_NewStringObj("plotarea", -1); break; case LEGEND_WINDOW: objPtr = Tcl_NewStringObj(Tk_PathName(legendPtr->tkwin), -1); break; case LEGEND_XY: { char string[200]; sprintf_s(string, 200, "@%d,%d", legendPtr->xReq, legendPtr->yReq); objPtr = Tcl_NewStringObj(string, -1); } default: objPtr = Tcl_NewStringObj("unknown legend position", -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToSelectmode -- * * Convert the string reprsenting a select mode, to its numeric form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSelectmode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; char c; int *modePtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 's') && (strcmp(string, "single") == 0)) { *modePtr = SELECT_MODE_SINGLE; } else if ((c == 'm') && (strcmp(string, "multiple") == 0)) { *modePtr = SELECT_MODE_MULTIPLE; } else if ((c == 'a') && (strcmp(string, "active") == 0)) { *modePtr = SELECT_MODE_SINGLE; } else { Tcl_AppendResult(interp, "bad select mode \"", string, "\": should be \"single\" or \"multiple\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectmodeToObj -- * * Results: * The string representation of the select mode is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SelectmodeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mode = *(int *)(widgRec + offset); switch (mode) { case SELECT_MODE_SINGLE: return Tcl_NewStringObj("single", -1); case SELECT_MODE_MULTIPLE: return Tcl_NewStringObj("multiple", -1); default: return Tcl_NewStringObj("unknown scroll mode", -1); } } static void SetLegendOrigin(Legend *legendPtr) { Graph *graphPtr; int x, y, w, h; graphPtr = legendPtr->graphPtr; x = y = w = h = 0; /* Suppress compiler warning. */ switch (legendPtr->site) { case LEGEND_RIGHT: w = graphPtr->rightMargin.width - graphPtr->rightMargin.axesOffset; h = graphPtr->bottom - graphPtr->top; x = graphPtr->right + graphPtr->rightMargin.axesOffset; y = graphPtr->top; break; case LEGEND_LEFT: w = graphPtr->leftMargin.width - graphPtr->leftMargin.axesOffset; h = graphPtr->bottom - graphPtr->top; x = graphPtr->inset; y = graphPtr->top; break; case LEGEND_TOP: w = graphPtr->right - graphPtr->left; h = graphPtr->topMargin.height - graphPtr->topMargin.axesOffset; if (graphPtr->title != NULL) { h -= graphPtr->titleHeight; } x = graphPtr->left; y = graphPtr->inset; if (graphPtr->title != NULL) { y += graphPtr->titleHeight; } break; case LEGEND_BOTTOM: w = graphPtr->right - graphPtr->left; h = graphPtr->bottomMargin.height - graphPtr->bottomMargin.axesOffset; x = graphPtr->left; y = graphPtr->bottom + graphPtr->bottomMargin.axesOffset; break; case LEGEND_PLOT: w = graphPtr->right - graphPtr->left; h = graphPtr->bottom - graphPtr->top; x = graphPtr->left; y = graphPtr->top; break; case LEGEND_XY: w = legendPtr->width; h = legendPtr->height; x = legendPtr->xReq; y = legendPtr->yReq; if (x < 0) { x += graphPtr->width; } if (y < 0) { y += graphPtr->height; } break; case LEGEND_WINDOW: legendPtr->anchor = TK_ANCHOR_NW; legendPtr->x = legendPtr->y = 0; return; } switch (legendPtr->anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ if (h > legendPtr->height) { y += (h - legendPtr->height) / 2; } break; case TK_ANCHOR_SW: /* Lower left corner */ if (h > legendPtr->height) { y += (h - legendPtr->height); } break; case TK_ANCHOR_N: /* Top center */ if (w > legendPtr->width) { x += (w - legendPtr->width) / 2; } break; case TK_ANCHOR_CENTER: /* Center */ if (h > legendPtr->height) { y += (h - legendPtr->height) / 2; } if (w > legendPtr->width) { x += (w - legendPtr->width) / 2; } break; case TK_ANCHOR_S: /* Bottom center */ if (w > legendPtr->width) { x += (w - legendPtr->width) / 2; } if (h > legendPtr->height) { y += (h - legendPtr->height); } break; case TK_ANCHOR_NE: /* Upper right corner */ if (w > legendPtr->width) { x += w - legendPtr->width; } break; case TK_ANCHOR_E: /* Right center */ if (w > legendPtr->width) { x += w - legendPtr->width; } if (h > legendPtr->height) { y += (h - legendPtr->height) / 2; } break; case TK_ANCHOR_SE: /* Lower right corner */ if (w > legendPtr->width) { x += w - legendPtr->width; } if (h > legendPtr->height) { y += (h - legendPtr->height); } break; } legendPtr->x = x + legendPtr->padLeft; legendPtr->y = y + legendPtr->padTop; } static int EntryIsSelected(Legend *legendPtr, Element *elemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr); return (hPtr != NULL); } static void SelectElement(Legend *legendPtr, Element *elemPtr) { int isNew; Blt_HashEntry *hPtr; hPtr = Blt_CreateHashEntry(&legendPtr->selectTable, (char *)elemPtr,&isNew); if (isNew) { Blt_ChainLink link; link = Blt_Chain_Append(legendPtr->selected, elemPtr); Blt_SetHashValue(hPtr, link); } } static void DeselectElement(Legend *legendPtr, Element *elemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr); if (hPtr != NULL) { Blt_ChainLink link; link = Blt_GetHashValue(hPtr); Blt_Chain_DeleteLink(legendPtr->selected, link); Blt_DeleteHashEntry(&legendPtr->selectTable, hPtr); } } static void SelectEntry(Legend *legendPtr, Element *elemPtr) { Blt_HashEntry *hPtr; switch (legendPtr->flags & SELECT_MASK) { case SELECT_CLEAR: DeselectElement(legendPtr, elemPtr); break; case SELECT_SET: SelectElement(legendPtr, elemPtr); break; case SELECT_TOGGLE: hPtr = Blt_FindHashEntry(&legendPtr->selectTable, (char *)elemPtr); if (hPtr != NULL) { DeselectElement(legendPtr, elemPtr); } else { SelectElement(legendPtr, elemPtr); } break; } } #ifdef notdef static Element * PointerToElement(Legend *legendPtr, int x, int y) { Graph *graphPtr = legendPtr->graphPtr; int w, h; int n; w = legendPtr->width; h = legendPtr->height; x -= legendPtr->x + legendPtr->borderWidth; y -= legendPtr->y + legendPtr->borderWidth; w -= 2 * legendPtr->borderWidth + PADDING(legendPtr->xPad); h -= 2 * legendPtr->borderWidth + PADDING(legendPtr->yPad); if ((x < 0) || (x >= w) || (y < 0) || (y >= h)) { return NULL; } /* It's in the bounding box, so compute the index. */ { int row, column; row = y / legendPtr->entryHeight; column = x / legendPtr->entryWidth; n = (column * legendPtr->nRows) + row; } if (n < legendPtr->nEntries) { Blt_ChainLink link; int count; count = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; } if (count > n) { return NULL; } else if (count == n) { return elemPtr; } count++; } } return NULL; } #endif /*ARGSUSED*/ static ClientData PickEntryProc(ClientData clientData, int x, int y, ClientData *contextPtr) { Graph *graphPtr = clientData; Legend *legendPtr; int w, h; legendPtr = graphPtr->legend; w = legendPtr->width; h = legendPtr->height; if (legendPtr->titleHeight > 0) { y -= legendPtr->titleHeight + legendPtr->yPad.side1; } x -= legendPtr->x + legendPtr->borderWidth; y -= legendPtr->y + legendPtr->borderWidth; w -= 2 * legendPtr->borderWidth + PADDING(legendPtr->xPad); h -= 2 * legendPtr->borderWidth + PADDING(legendPtr->yPad); if ((x >= 0) && (x < w) && (y >= 0) && (y < h)) { int row, column; int n; /* * It's in the bounding box, so compute the index. */ row = y / legendPtr->entryHeight; column = x / legendPtr->entryWidth; n = (column * legendPtr->nRows) + row; if (n < legendPtr->nEntries) { Blt_ChainLink link; int count; /* Legend entries are stored in bottom-to-top. */ count = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label != NULL) { if (count == n) { return elemPtr; } count++; } } if (link != NULL) { return Blt_Chain_GetValue(link); } } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_MapLegend -- * * Calculates the dimensions (width and height) needed for the legend. * Also determines the number of rows and columns necessary to list all * the valid element labels. * * Results: * None. * * Side effects: * The following fields of the legend are calculated and set. * * nEntries - number of valid labels of elements in the * display list. * nRows - number of rows of entries * nColumns - number of columns of entries * entryHeight - height of each entry * entryWidth - width of each entry * height - width of legend (includes borders and padding) * width - height of legend (includes borders and padding) * *--------------------------------------------------------------------------- */ void Blt_MapLegend( Graph *graphPtr, int plotWidth, /* Maximum width available in window * to draw the legend. Will calculate * # of columns from this. */ int plotHeight) /* Maximum height available in window * to draw the legend. Will calculate * # of rows from this. */ { Legend *legendPtr = graphPtr->legend; Blt_ChainLink link; int nRows, nColumns, nEntries; int lw, lh; int maxWidth, maxHeight; int symbolWidth; Blt_FontMetrics fontMetrics; /* Initialize legend values to default (no legend displayed) */ legendPtr->entryWidth = legendPtr->entryHeight = 0; legendPtr->nRows = legendPtr->nColumns = legendPtr->nEntries = 0; legendPtr->height = legendPtr->width = 0; if (legendPtr->site == LEGEND_WINDOW) { if (Tk_Width(legendPtr->tkwin) > 1) { plotWidth = Tk_Width(legendPtr->tkwin); } if (Tk_Height(legendPtr->tkwin) > 1) { plotHeight = Tk_Height(legendPtr->tkwin); } } Blt_Ts_GetExtents(&legendPtr->titleStyle, legendPtr->title, &legendPtr->titleWidth, &legendPtr->titleHeight); /* * Count the number of legend entries and determine the widest and tallest * label. The number of entries would normally be the number of elements, * but elements can have no legend entry (-label ""). */ nEntries = 0; maxWidth = maxHeight = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { unsigned int w, h; Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; /* Element has no legend entry. */ } Blt_Ts_GetExtents(&legendPtr->style, elemPtr->label, &w, &h); if (maxWidth < w) { maxWidth = w; } if (maxHeight < h) { maxHeight = h; } nEntries++; } if (nEntries == 0) { return; /* No visible legend entries. */ } Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics); symbolWidth = 2 * fontMetrics.ascent; maxWidth += 2 * legendPtr->entryBW + PADDING(legendPtr->ixPad) + + symbolWidth + 3 * LABEL_PAD; maxHeight += 2 * legendPtr->entryBW + PADDING(legendPtr->iyPad); maxWidth |= 0x01; maxHeight |= 0x01; lw = plotWidth - 2 * legendPtr->borderWidth - PADDING(legendPtr->xPad); lh = plotHeight - 2 * legendPtr->borderWidth - PADDING(legendPtr->yPad); /* * The number of rows and columns is computed as one of the following: * * both options set User defined. * -rows Compute columns from rows. * -columns Compute rows from columns. * neither set Compute rows and columns from * size of plot. */ if (legendPtr->reqRows > 0) { nRows = MIN(legendPtr->reqRows, nEntries); if (legendPtr->reqColumns > 0) { nColumns = MIN(legendPtr->reqColumns, nEntries); } else { nColumns = ((nEntries - 1) / nRows) + 1; /* Only -rows. */ } } else if (legendPtr->reqColumns > 0) { /* Only -columns. */ nColumns = MIN(legendPtr->reqColumns, nEntries); nRows = ((nEntries - 1) / nColumns) + 1; } else { /* Compute # of rows and columns from the legend size. */ nRows = lh / maxHeight; nColumns = lw / maxWidth; if (nRows < 1) { nRows = nEntries; } if (nColumns < 1) { nColumns = nEntries; } if (nRows > nEntries) { nRows = nEntries; } switch (legendPtr->site) { case LEGEND_TOP: case LEGEND_BOTTOM: nRows = ((nEntries - 1) / nColumns) + 1; break; case LEGEND_LEFT: case LEGEND_RIGHT: default: nColumns = ((nEntries - 1) / nRows) + 1; break; } } if (nColumns < 1) { nColumns = 1; } if (nRows < 1) { nRows = 1; } lh = (nRows * maxHeight); if (legendPtr->titleHeight > 0) { lh += legendPtr->titleHeight + legendPtr->yPad.side1; } lw = nColumns * maxWidth; if (lw < legendPtr->titleWidth) { lw = legendPtr->titleWidth; } legendPtr->width = lw + 2 * legendPtr->borderWidth + PADDING(legendPtr->xPad); legendPtr->height = lh + 2 * legendPtr->borderWidth + PADDING(legendPtr->yPad); legendPtr->nRows = nRows; legendPtr->nColumns = nColumns; legendPtr->nEntries = nEntries; legendPtr->entryHeight = maxHeight; legendPtr->entryWidth = maxWidth; { int row, col, count; row = col = count = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); count++; elemPtr->row = row; elemPtr->col = col; row++; if ((count % nRows) == 0) { col++; row = 0; } } } if ((legendPtr->site == LEGEND_WINDOW) && ((Tk_ReqWidth(legendPtr->tkwin) != legendPtr->width) || (Tk_ReqHeight(legendPtr->tkwin) != legendPtr->height))) { Tk_GeometryRequest(legendPtr->tkwin,legendPtr->width,legendPtr->height); } } void Blt_DrawLegend(Graph *graphPtr, Drawable drawable) { Blt_Background bg; Blt_ChainLink link; Blt_FontMetrics fontMetrics; Legend *legendPtr = graphPtr->legend; Pixmap pixmap; Tk_Window tkwin; int count; int symbolSize, xMid, yMid; int x, y, w, h; int xLabel, yStart, xSymbol, ySymbol; if ((legendPtr->flags & HIDE) || (legendPtr->nEntries == 0)) { return; } SetLegendOrigin(legendPtr); graphPtr = legendPtr->graphPtr; tkwin = legendPtr->tkwin; if (legendPtr->site == LEGEND_WINDOW) { w = Tk_Width(tkwin); h = Tk_Height(tkwin); } else { w = legendPtr->width; h = legendPtr->height; } pixmap = Tk_GetPixmap(graphPtr->display, Tk_WindowId(tkwin), w, h, Tk_Depth(tkwin)); if (legendPtr->normalBg != NULL) { Blt_FillBackgroundRectangle(tkwin, pixmap, legendPtr->normalBg, 0, 0, w, h, 0, TK_RELIEF_FLAT); } else if (legendPtr->site & LEGEND_PLOTAREA_MASK) { /* * Legend background is transparent and is positioned over the the * plot area. Either copy the part of the background from the backing * store pixmap or (if no backing store exists) just fill it with the * background color of the plot. */ if (graphPtr->cache != None) { XCopyArea(graphPtr->display, graphPtr->cache, pixmap, graphPtr->drawGC, legendPtr->x, legendPtr->y, w, h, 0, 0); } else { Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->plotBg, 0, 0, w, h, TK_RELIEF_FLAT, 0); } } else { int xOrigin, yOrigin; /* * The legend is located in one of the margins or the external window. */ Blt_GetBackgroundOrigin(graphPtr->normalBg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(graphPtr->tkwin, graphPtr->normalBg, xOrigin - legendPtr->x,yOrigin - legendPtr->y); Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->normalBg, 0, 0, w, h, 0, TK_RELIEF_FLAT); Blt_SetBackgroundOrigin(tkwin, graphPtr->normalBg, xOrigin, yOrigin); } Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics); symbolSize = fontMetrics.ascent; xMid = symbolSize + 1 + legendPtr->entryBW; yMid = (symbolSize / 2) + 1 + legendPtr->entryBW; xLabel = 2 * symbolSize + legendPtr->entryBW + legendPtr->ixPad.side1 + 2 * LABEL_PAD; ySymbol = yMid + legendPtr->iyPad.side1; xSymbol = xMid + LABEL_PAD; x = legendPtr->padLeft + legendPtr->borderWidth; y = legendPtr->padTop + legendPtr->borderWidth; Blt_DrawText(tkwin, pixmap, legendPtr->title, &legendPtr->titleStyle, x, y); if (legendPtr->titleHeight > 0) { y += legendPtr->titleHeight + legendPtr->yPad.side1; } count = 0; yStart = y; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; int isSelected; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; /* Skip this entry */ } isSelected = EntryIsSelected(legendPtr, elemPtr); if (elemPtr->flags & LABEL_ACTIVE) { int xOrigin, yOrigin; Blt_GetBackgroundOrigin(legendPtr->activeBg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(tkwin, legendPtr->activeBg, xOrigin - legendPtr->x, yOrigin - legendPtr->y); Blt_Ts_SetForeground(legendPtr->style, legendPtr->activeFgColor); Blt_FillBackgroundRectangle(tkwin, pixmap, legendPtr->activeBg, x, y, legendPtr->entryWidth, legendPtr->entryHeight, legendPtr->entryBW, legendPtr->activeRelief); Blt_SetBackgroundOrigin(tkwin, legendPtr->activeBg, xOrigin, yOrigin); } else if (isSelected) { int xOrigin, yOrigin; Blt_Background bg; XColor *fg; fg = (legendPtr->flags & FOCUS) ? legendPtr->selInFocusFgColor : legendPtr->selOutFocusFgColor; bg = (legendPtr->flags & FOCUS) ? legendPtr->selInFocusBg : legendPtr->selOutFocusBg; Blt_GetBackgroundOrigin(bg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(tkwin, bg, xOrigin - legendPtr->x, yOrigin - legendPtr->y); Blt_Ts_SetForeground(legendPtr->style, fg); Blt_FillBackgroundRectangle(tkwin, pixmap, bg, x, y, legendPtr->entryWidth, legendPtr->entryHeight, legendPtr->selBW, legendPtr->selRelief); Blt_SetBackgroundOrigin(tkwin, bg, xOrigin, yOrigin); } else { Blt_Ts_SetForeground(legendPtr->style, legendPtr->fgColor); if (elemPtr->legendRelief != TK_RELIEF_FLAT) { Blt_FillBackgroundRectangle(tkwin, pixmap, graphPtr->normalBg, x, y, legendPtr->entryWidth, legendPtr->entryHeight, legendPtr->entryBW, elemPtr->legendRelief); } } (*elemPtr->procsPtr->drawSymbolProc) (graphPtr, pixmap, elemPtr, x + xSymbol, y + ySymbol, symbolSize); Blt_DrawText(tkwin, pixmap, elemPtr->label, &legendPtr->style, x + xLabel, y + legendPtr->entryBW + legendPtr->iyPad.side1); count++; if (legendPtr->focusPtr == elemPtr) { /* Focus outline */ if (isSelected) { XColor *color; color = (legendPtr->flags & FOCUS) ? legendPtr->selInFocusFgColor : legendPtr->selOutFocusFgColor; XSetForeground(graphPtr->display, legendPtr->focusGC, color->pixel); } XDrawRectangle(graphPtr->display, pixmap, legendPtr->focusGC, x + 1, y + 1, legendPtr->entryWidth - 3, legendPtr->entryHeight - 3); if (isSelected) { XSetForeground(graphPtr->display, legendPtr->focusGC, legendPtr->focusColor->pixel); } } /* Check when to move to the next column */ if ((count % legendPtr->nRows) > 0) { y += legendPtr->entryHeight; } else { x += legendPtr->entryWidth; y = yStart; } } /* * Draw the border and/or background of the legend. */ bg = legendPtr->normalBg; if (bg == NULL) { bg = graphPtr->normalBg; } /* Disable crosshairs before redisplaying to the screen */ if (legendPtr->site & LEGEND_PLOTAREA_MASK) { Blt_DisableCrosshairs(graphPtr); } Blt_DrawBackgroundRectangle(tkwin, pixmap, bg, 0, 0, w, h, legendPtr->borderWidth, legendPtr->relief); XCopyArea(graphPtr->display, pixmap, drawable, graphPtr->drawGC, 0, 0, w, h, legendPtr->x, legendPtr->y); if (legendPtr->site & LEGEND_PLOTAREA_MASK) { Blt_EnableCrosshairs(graphPtr); } Tk_FreePixmap(graphPtr->display, pixmap); graphPtr->flags &= ~DRAW_LEGEND; } /* *--------------------------------------------------------------------------- * * Blt_LegendToPostScript -- * *--------------------------------------------------------------------------- */ void Blt_LegendToPostScript(Graph *graphPtr, Blt_Ps ps) { Legend *legendPtr = graphPtr->legend; double x, y, yStart; int xLabel, xSymbol, ySymbol; int count; Blt_ChainLink link; int symbolSize, xMid, yMid; int width, height; Blt_FontMetrics fontMetrics; if ((legendPtr->flags & HIDE) || (legendPtr->nEntries == 0)) { return; } SetLegendOrigin(legendPtr); x = legendPtr->x, y = legendPtr->y; width = legendPtr->width - PADDING(legendPtr->xPad); height = legendPtr->height - PADDING(legendPtr->yPad); Blt_Ps_Append(ps, "% Legend\n"); graphPtr = legendPtr->graphPtr; if (graphPtr->pageSetup->flags & PS_DECORATIONS) { if (legendPtr->normalBg != NULL) { Tk_3DBorder border; border = Blt_BackgroundBorder(legendPtr->normalBg); Blt_Ps_Fill3DRectangle(ps, border, x, y, width, height, legendPtr->borderWidth, legendPtr->relief); } else { Tk_3DBorder border; border = Blt_BackgroundBorder(graphPtr->normalBg); Blt_Ps_Draw3DRectangle(ps, border, x, y, width, height, legendPtr->borderWidth, legendPtr->relief); } } else { Blt_Ps_SetClearBackground(ps); Blt_Ps_XFillRectangle(ps, x, y, width, height); } Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics); symbolSize = fontMetrics.ascent; xMid = symbolSize + 1 + legendPtr->entryBW; yMid = (symbolSize / 2) + 1 + legendPtr->entryBW; xLabel = 2 * symbolSize + legendPtr->entryBW + legendPtr->ixPad.side1 + 5; xSymbol = xMid + legendPtr->ixPad.side1; ySymbol = yMid + legendPtr->iyPad.side1; x += legendPtr->borderWidth; y += legendPtr->borderWidth; Blt_Ps_DrawText(ps, legendPtr->title, &legendPtr->titleStyle, x, y); if (legendPtr->titleHeight > 0) { y += legendPtr->titleHeight + legendPtr->yPad.side1; } count = 0; yStart = y; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; /* Skip this label */ } if (elemPtr->flags & LABEL_ACTIVE) { Tk_3DBorder border; border = Blt_BackgroundBorder(legendPtr->activeBg); Blt_Ts_SetForeground(legendPtr->style, legendPtr->activeFgColor); Blt_Ps_Fill3DRectangle(ps, border, x, y, legendPtr->entryWidth, legendPtr->entryHeight, legendPtr->entryBW, legendPtr->activeRelief); } else { Blt_Ts_SetForeground(legendPtr->style, legendPtr->fgColor); if (elemPtr->legendRelief != TK_RELIEF_FLAT) { Tk_3DBorder border; border = Blt_BackgroundBorder(graphPtr->normalBg); Blt_Ps_Draw3DRectangle(ps, border, x, y, legendPtr->entryWidth, legendPtr->entryHeight, legendPtr->entryBW, elemPtr->legendRelief); } } (*elemPtr->procsPtr->printSymbolProc) (graphPtr, ps, elemPtr, x + xSymbol, y + ySymbol, symbolSize); Blt_Ps_DrawText(ps, elemPtr->label, &legendPtr->style, x + xLabel, y + legendPtr->entryBW + legendPtr->iyPad.side1); count++; if ((count % legendPtr->nRows) > 0) { y += legendPtr->entryHeight; } else { x += legendPtr->entryWidth; y = yStart; } } } /* *--------------------------------------------------------------------------- * * DisplayLegend -- * *--------------------------------------------------------------------------- */ static void DisplayLegend(ClientData clientData) { Legend *legendPtr = clientData; Graph *graphPtr; legendPtr->flags &= ~REDRAW_PENDING; if (legendPtr->tkwin == NULL) { return; /* Window has been destroyed. */ } graphPtr = legendPtr->graphPtr; if (legendPtr->site == LEGEND_WINDOW) { int w, h; w = Tk_Width(legendPtr->tkwin); h = Tk_Height(legendPtr->tkwin); if ((w != legendPtr->width) || (h != legendPtr->height)) { Blt_MapLegend(graphPtr, w, h); } } if (Tk_IsMapped(legendPtr->tkwin)) { Blt_DrawLegend(graphPtr, Tk_WindowId(legendPtr->tkwin)); } } /* *--------------------------------------------------------------------------- * * Blt_ConfigureLegend -- * * Routine to configure the legend. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ void Blt_ConfigureLegend(Graph *graphPtr) { GC newGC; XGCValues gcValues; unsigned long gcMask; Legend *legendPtr; legendPtr = graphPtr->legend; /* GC for active label. Dashed outline. */ gcMask = GCForeground | GCLineStyle; gcValues.foreground = legendPtr->focusColor->pixel; gcValues.line_style = (LineIsDashed(legendPtr->focusDashes)) ? LineOnOffDash : LineSolid; newGC = Blt_GetPrivateGC(legendPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(legendPtr->focusDashes)) { legendPtr->focusDashes.offset = 2; Blt_SetDashes(graphPtr->display, newGC, &legendPtr->focusDashes); } if (legendPtr->focusGC != NULL) { Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC); } legendPtr->focusGC = newGC; /* * Update the layout of the graph (and redraw the elements) if any of * the following legend options (all of which affect the size of the * legend) have changed. * * -activeborderwidth, -borderwidth * -border * -font * -hide * -ipadx, -ipady, -padx, -pady * -rows * * If the position of the legend changed to/from the default * position, also indicate that a new layout is needed. * */ if (legendPtr->site == LEGEND_WINDOW) { Blt_Legend_EventuallyRedraw(graphPtr); } else if (Blt_ConfigModified(configSpecs, "-*border*", "-*pad?", "-hide", "-font", "-rows", (char *)NULL)) { graphPtr->flags |= RESET_WORLD; graphPtr->flags |= (REDRAW_WORLD | CACHE_DIRTY); Blt_EventuallyRedrawGraph(graphPtr); } } /* *--------------------------------------------------------------------------- * * Blt_DestroyLegend -- * * Results: * None. * * Side effects: * Resources associated with the legend are freed. * *--------------------------------------------------------------------------- */ void Blt_DestroyLegend(Graph *graphPtr) { Legend *legendPtr = graphPtr->legend; if (graphPtr->legend == NULL) { return; } Blt_FreeOptions(configSpecs, (char *)legendPtr, graphPtr->display, 0); Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->style); Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->titleStyle); Blt_DestroyBindingTable(legendPtr->bindTable); if (legendPtr->focusGC != NULL) { Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC); } if (legendPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(legendPtr->timerToken); } if (legendPtr->tkwin != NULL) { Tk_DeleteSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING); } if (legendPtr->site == LEGEND_WINDOW) { Tk_Window tkwin; /* The graph may be in the process of being torn down */ if (legendPtr->cmdToken != NULL) { Tcl_DeleteCommandFromToken(graphPtr->interp, legendPtr->cmdToken); } if (legendPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayLegend, legendPtr); legendPtr->flags &= ~REDRAW_PENDING; } tkwin = legendPtr->tkwin; legendPtr->tkwin = NULL; if (tkwin != NULL) { Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask, LegendEventProc, graphPtr); Blt_DeleteWindowInstanceData(tkwin); Tk_DestroyWindow(tkwin); } } Blt_Free(legendPtr); } /* *--------------------------------------------------------------------------- * * Blt_CreateLegend -- * * Creates and initializes a legend structure with default settings * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_CreateLegend(Graph *graphPtr) { Legend *legendPtr; legendPtr = Blt_AssertCalloc(1, sizeof(Legend)); graphPtr->legend = legendPtr; legendPtr->graphPtr = graphPtr; legendPtr->tkwin = graphPtr->tkwin; legendPtr->xReq = legendPtr->yReq = -SHRT_MAX; legendPtr->relief = TK_RELIEF_SUNKEN; legendPtr->activeRelief = TK_RELIEF_FLAT; legendPtr->entryBW = 2; legendPtr->borderWidth = 2; legendPtr->ixPad.side1 = legendPtr->ixPad.side2 = 1; legendPtr->iyPad.side1 = legendPtr->iyPad.side2 = 1; legendPtr->xPad.side1 = legendPtr->xPad.side2 = 1; legendPtr->yPad.side1 = legendPtr->yPad.side2 = 1; legendPtr->anchor = TK_ANCHOR_N; legendPtr->site = LEGEND_RIGHT; legendPtr->selectMode = SELECT_MODE_MULTIPLE; Blt_Ts_InitStyle(legendPtr->style); Blt_Ts_InitStyle(legendPtr->titleStyle); legendPtr->style.justify = TK_JUSTIFY_LEFT; legendPtr->style.anchor = TK_ANCHOR_NW; legendPtr->titleStyle.justify = TK_JUSTIFY_LEFT; legendPtr->titleStyle.anchor = TK_ANCHOR_NW; legendPtr->bindTable = Blt_CreateBindingTable(graphPtr->interp, graphPtr->tkwin, graphPtr, PickEntryProc, Blt_GraphTags); Blt_InitHashTable(&legendPtr->selectTable, BLT_ONE_WORD_KEYS); legendPtr->selected = Blt_Chain_Create(); Tk_CreateSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING, SelectionProc, legendPtr, XA_STRING); legendPtr->selRelief = TK_RELIEF_FLAT; legendPtr->selBW = 1; legendPtr->onTime = 600; legendPtr->offTime = 300; if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, "legend", "Legend", configSpecs, 0, (Tcl_Obj **)NULL, (char *)legendPtr, 0) != TCL_OK) { return TCL_ERROR; } Blt_ConfigureLegend(graphPtr); return TCL_OK; } static Element * GetNextRow(Graph *graphPtr, Element *focusPtr) { Blt_ChainLink link; int row, col; col = focusPtr->col; row = focusPtr->row + 1; for (link = focusPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; } if ((elemPtr->col == col) && (elemPtr->row == row)) { return elemPtr; } } return NULL; } static Element * GetNextColumn(Graph *graphPtr, Element *focusPtr) { Blt_ChainLink link; int row, col; col = focusPtr->col + 1; row = focusPtr->row; for (link = focusPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; } if ((elemPtr->col == col) && (elemPtr->row == row)) { return elemPtr; /* Don't go beyond legend boundaries. */ } } return NULL; } static Element * GetPreviousRow(Graph *graphPtr, Element *focusPtr) { Blt_ChainLink link; int row, col; col = focusPtr->col; row = focusPtr->row - 1; for (link = focusPtr->link; link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; } if ((elemPtr->col == col) && (elemPtr->row == row)) { return elemPtr; } } return NULL; } static Element * GetPreviousColumn(Graph *graphPtr, Element *focusPtr) { Blt_ChainLink link; int row, col; col = focusPtr->col - 1; row = focusPtr->row; for (link = focusPtr->link; link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label == NULL) { continue; } if ((elemPtr->col == col) && (elemPtr->row == row)) { return elemPtr; } } return NULL; } static Element * GetFirstElement(Graph *graphPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label != NULL) { return elemPtr; } } return NULL; } static Element * GetLastElement(Graph *graphPtr) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->label != NULL) { return elemPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * GetElementFromObj -- * * Parse an index into an entry and return either its value or an error. * * Results: * A standard TCL result. If all went well, then *indexPtr is filled in * with the character index (into entryPtr) corresponding to string. The * index value is guaranteed to lie between 0 and the number of characters * in the string, inclusive. If an error occurs then an error message is * left in the interp's result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int GetElementFromObj(Graph *graphPtr, Tcl_Obj *objPtr, Element **elemPtrPtr) { Element *elemPtr; Legend *legendPtr; Tcl_Interp *interp; char c; const char *string; int last; int index; legendPtr = graphPtr->legend; interp = graphPtr->interp; string = Tcl_GetString(objPtr); c = string[0]; elemPtr = NULL; last = Blt_Chain_GetLength(graphPtr->elements.displayList) - 1; if ((c == 'a') && (strcmp(string, "anchor") == 0)) { elemPtr = legendPtr->selAnchorPtr; } else if ((c == 'c') && (strcmp(string, "current") == 0)) { elemPtr = (Element *)Blt_GetCurrentItem(legendPtr->bindTable); } else if ((c == 'f') && (strcmp(string, "first") == 0)) { elemPtr = GetFirstElement(graphPtr); } else if ((c == 'f') && (strcmp(string, "focus") == 0)) { elemPtr = legendPtr->focusPtr; } else if ((c == 'l') && (strcmp(string, "last") == 0)) { elemPtr = GetLastElement(graphPtr); } else if ((c == 'e') && (strcmp(string, "end") == 0)) { elemPtr = GetLastElement(graphPtr); } else if ((c == 'n') && (strcmp(string, "next.row") == 0)) { elemPtr = GetNextRow(graphPtr, legendPtr->focusPtr); } else if ((c == 'n') && (strcmp(string, "next.column") == 0)) { elemPtr = GetNextColumn(graphPtr, legendPtr->focusPtr); } else if ((c == 'p') && (strcmp(string, "previous.row") == 0)) { elemPtr = GetPreviousRow(graphPtr, legendPtr->focusPtr); } else if ((c == 'p') && (strcmp(string, "previous.column") == 0)) { elemPtr = GetPreviousColumn(graphPtr, legendPtr->focusPtr); } else if ((c == 's') && (strcmp(string, "sel.first") == 0)) { elemPtr = legendPtr->selFirstPtr; } else if ((c == 's') && (strcmp(string, "sel.last") == 0)) { elemPtr = legendPtr->selLastPtr; } else if (c == '@') { int x, y; if (Blt_GetXY(interp, legendPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } elemPtr = (Element *)PickEntryProc(graphPtr, x, y, NULL); } else { if (Blt_GetElement(interp, graphPtr, objPtr, &elemPtr) != TCL_OK) { return TCL_ERROR; } if (elemPtr->link == NULL) { Tcl_AppendResult(interp, "bad legend index \"", string, "\"", (char *)NULL); return TCL_ERROR; } if (elemPtr->label == NULL) { elemPtr = NULL; } } *elemPtrPtr = elemPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectRange -- * * Sets the selection flag for a range of nodes. The range is determined * by two pointers which designate the first/last nodes of the range. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int SelectRange(Legend *legendPtr, Element *fromPtr, Element *toPtr) { if (Blt_Chain_IsBefore(fromPtr->link, toPtr->link)) { Blt_ChainLink link; for (link = fromPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); SelectEntry(legendPtr, elemPtr); if (link == toPtr->link) { break; } } } else { Blt_ChainLink link; for (link = fromPtr->link; link != NULL; link = Blt_Chain_PrevLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); SelectEntry(legendPtr, elemPtr); if (link == toPtr->link) { break; } } } return TCL_OK; } #ifdef notdef /* *--------------------------------------------------------------------------- * * SelectText -- * * Modify the selection by moving its un-anchored end. This could make * the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectText(Legend *legendPtr, Element *elemPtr) { Element *firstPtr, *lastPtr; Graph *graphPtr = legendPtr->graphPtr; /* Grab the selection if we don't own it already. */ if ((legendPtr->flags&SELECT_EXPORT) && (legendPtr->selFirstPtr == NULL)) { Tk_OwnSelection(legendPtr->tkwin, XA_PRIMARY, LostSelectionProc, legendPtr); } /* If the anchor hasn't been set, assume the beginning of the legend. */ if (legendPtr->selAnchorPtr == NULL) { legendPtr->selAnchorPtr = GetFirstElement(graphPtr); } if (legendPtr->selAnchorPtr != elemPtr) { firstPtr = legendPtr->selAnchorPtr; lastPtr = elemPtr; } else { firstPtr = elemPtr; lastPtr = legendPtr->selAnchorPtr; } if ((legendPtr->selFirstPtr != firstPtr) || (legendPtr->selLastPtr != lastPtr)) { legendPtr->selFirstPtr = firstPtr; legendPtr->selLastPtr = lastPtr; SelectRange(legendPtr, firstPtr, lastPtr); Blt_Legend_EventuallyRedraw(graphPtr); } return TCL_OK; } #endif /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activates a particular label in the legend. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ static int ActivateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; unsigned int active, redraw; const char *string; int i; string = Tcl_GetString(objv[2]); active = (string[0] == 'a') ? LABEL_ACTIVE : 0; redraw = FALSE; for (i = 3; i < objc; i++) { Blt_ChainLink link; const char *pattern; pattern = Tcl_GetString(objv[i]); for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (Tcl_StringMatch(elemPtr->obj.name, pattern)) { fprintf(stderr, "legend %s(%s) %s is currently %d\n", string, pattern, elemPtr->obj.name, (elemPtr->flags & LABEL_ACTIVE)); if (active) { if ((elemPtr->flags & LABEL_ACTIVE) == 0) { elemPtr->flags |= LABEL_ACTIVE; redraw = TRUE; } } else { if (elemPtr->flags & LABEL_ACTIVE) { elemPtr->flags &= ~LABEL_ACTIVE; redraw = TRUE; } } fprintf(stderr, "legend %s(%s) %s is now %d\n", string, pattern, elemPtr->obj.name, (elemPtr->flags & LABEL_ACTIVE)); } } } if ((redraw) && ((legendPtr->flags & HIDE) == 0)) { /* * See if how much we need to draw. If the graph is already scheduled * for a redraw, just make sure the right flags are set. Otherwise * redraw only the legend: it's either in an external window or it's * the only thing that need updating. */ if ((legendPtr->site != LEGEND_WINDOW) && (graphPtr->flags & REDRAW_PENDING)) { graphPtr->flags |= CACHE_DIRTY; graphPtr->flags |= REDRAW_WORLD; /* Redraw entire graph. */ } else { Blt_Legend_EventuallyRedraw(graphPtr); } } { Blt_ChainLink link; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* List active elements in stacking order. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (elemPtr->flags & LABEL_ACTIVE) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BindOp -- * * .t bind index sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&graphPtr->elements.tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { const char *tagName; Tcl_Obj *objPtr; tagName = Blt_GetHashKey(&graphPtr->elements.tagTable, hPtr); objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } return Blt_ConfigureBindingsFromObj(interp, graphPtr->legend->bindTable, Blt_MakeElementTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Queries or resets options for the legend. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, (char *)graphPtr->legend, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Queries or resets options for the legend. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int flags = BLT_CONFIG_OBJV_ONLY; Legend *legendPtr; legendPtr = graphPtr->legend; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)legendPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)legendPtr, objv[3], flags); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)legendPtr, flags) != TCL_OK) { return TCL_ERROR; } Blt_ConfigureLegend(graphPtr); return TCL_OK; } /*ARGSUSED*/ static int CurselectionOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (legendPtr->flags & SELECT_SORTED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(legendPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; Tcl_Obj *objPtr; elemPtr = Blt_Chain_GetValue(link); objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_ChainLink link; /* List of selected entries is in stacking order. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (EntryIsSelected(legendPtr, elemPtr)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int FocusOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; if (objc == 4) { Element *elemPtr; if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; } if ((elemPtr != NULL) && (elemPtr != legendPtr->focusPtr)) { /* Changing focus can only affect the visible entries. The entry * layout stays the same. */ legendPtr->focusPtr = elemPtr; } Blt_SetFocusItem(legendPtr->bindTable, legendPtr->focusPtr, CID_LEGEND_ENTRY); Blt_Legend_EventuallyRedraw(graphPtr); } if (legendPtr->focusPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), legendPtr->focusPtr->obj.name, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Find the legend entry from the given argument. The argument can be * either a screen position "@x,y" or the name of an element. * * I don't know how useful it is to test with the name of an element. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; if (((legendPtr->flags & HIDE) == 0) && (legendPtr->nEntries > 0)) { Element *elemPtr; if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; } if (elemPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name,-1); } } return TCL_OK; } /* *---------------------------------------------------------------------- * * IconOp -- * * Find the legend entry from the given argument. The argument * can be either a screen position "@x,y" or the name of an * element. * * I don't know how useful it is to test with the name of an * element. * * Results: * A standard Tcl result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * * .g legend icon elemName image * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int IconOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Picture picture; Element *elemPtr; Legend *legendPtr = graphPtr->legend; Pixmap pixmap; Blt_FontMetrics fontMetrics; Tk_PhotoHandle photo; const char *imageName; int isPicture; int w, h, x, y, s; if (GetElementFromObj(graphPtr, objv[3], &elemPtr) != TCL_OK) { return TCL_ERROR; } if (elemPtr == NULL) { return TCL_OK; /* Unknown index. */ } imageName = Tcl_GetString(objv[4]); photo = Tk_FindPhoto(interp, imageName); if (photo != NULL) { isPicture = FALSE; } else if (Blt_GetPicture(interp, imageName, &picture) == TCL_OK) { isPicture = TRUE; } else { return TCL_ERROR; } Blt_GetFontMetrics(legendPtr->style.font, &fontMetrics); s = fontMetrics.ascent; h = s + PADDING(legendPtr->iyPad) + 1; w = s + s + 1 + PADDING(legendPtr->ixPad); x = (w / 2); y = (h / 2); pixmap = Tk_GetPixmap(graphPtr->display, Tk_RootWindow(graphPtr->tkwin), w, h, Tk_Depth(graphPtr->tkwin)); Blt_FillBackgroundRectangle(graphPtr->tkwin, pixmap, graphPtr->plotBg, 0, 0, w, h, TK_RELIEF_FLAT, 0); (*elemPtr->procsPtr->drawSymbolProc) (graphPtr, pixmap, elemPtr, x, y, s); picture = Blt_DrawableToPicture(graphPtr->tkwin, pixmap, 0, 0, w, h, 1.0); Tk_FreePixmap(graphPtr->display, pixmap); if (picture == NULL) { Tcl_AppendResult(interp, "can't get picture of symbol.", (char *)NULL); return TCL_ERROR; } /* Make the background transparent. */ { int y; Blt_Pixel bg; Blt_Pixel *destRowPtr; XColor *colorPtr; colorPtr = Blt_BackgroundBorderColor(graphPtr->plotBg); bg.Red = colorPtr->red >> 8; bg.Green = colorPtr->green >> 8; bg.Blue = colorPtr->blue >> 8; bg.Alpha = 0xFF; destRowPtr = Blt_PictureBits(picture); for (y = 0; y < h; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { if (dp->u32 == bg.u32) { dp->Alpha = 0x0; } } destRowPtr += Blt_PictureStride(picture); } } Blt_ClassifyPicture(picture); if (isPicture) { Blt_ResetPicture(interp, imageName, picture); } else { Blt_PictureToPhoto(picture, photo); Blt_FreePicture(picture); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionAnchorOp -- * * Sets the selection anchor to the element given by a index. The * selection anchor is the end of the selection that is fixed while * dragging out a selection with the mouse. The index "anchor" may be * used to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionAnchorOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; Element *elemPtr; if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) { return TCL_ERROR; } /* Set both the anchor and the mark. Indicates that a single entry * is selected. */ legendPtr->selAnchorPtr = elemPtr; legendPtr->selMarkPtr = NULL; if (elemPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name, -1); } Blt_Legend_EventuallyRedraw(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionClearallOp * * Clears the entire selection. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionClearallOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; ClearSelection(legendPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionIncludesOp * * Returns 1 if the element indicated by index is currently * selected, 0 if it isn't. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionIncludesOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; Element *elemPtr; int bool; if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) { return TCL_ERROR; } bool = EntryIsSelected(legendPtr, elemPtr); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionMarkOp -- * * Sets the selection mark to the element given by a index. The * selection anchor is the end of the selection that is movable while * dragging out a selection with the mouse. The index "mark" may be used * to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionMarkOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; Element *elemPtr; if (GetElementFromObj(graphPtr, objv[4], &elemPtr) != TCL_OK) { return TCL_ERROR; } if (legendPtr->selAnchorPtr == NULL) { Tcl_AppendResult(interp, "selection anchor must be set first", (char *)NULL); return TCL_ERROR; } if (legendPtr->selMarkPtr != elemPtr) { Blt_ChainLink link, next; /* Deselect entry from the list all the way back to the anchor. */ for (link = Blt_Chain_LastLink(legendPtr->selected); link != NULL; link = next) { Element *selectPtr; next = Blt_Chain_PrevLink(link); selectPtr = Blt_Chain_GetValue(link); if (selectPtr == legendPtr->selAnchorPtr) { break; } DeselectElement(legendPtr, selectPtr); } legendPtr->flags &= ~SELECT_MASK; legendPtr->flags |= SELECT_SET; SelectRange(legendPtr, legendPtr->selAnchorPtr, elemPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), elemPtr->obj.name, -1); legendPtr->selMarkPtr = elemPtr; Blt_Legend_EventuallyRedraw(graphPtr); if (legendPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(legendPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionPresentOp * * Returns 1 if there is a selection and 0 if it isn't. * * Results: * A standard TCL result. interp->result will contain a boolean string * indicating if there is a selection. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionPresentOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; int bool; bool = (Blt_Chain_GetLength(legendPtr->selected) > 0); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionSetOp * * Selects, deselects, or toggles all of the elements in the range * between first and last, inclusive, without affecting the selection * state of elements outside that range. * * Results: * None. * * Side effects: * The selection changes. * * .g legend selection set first last * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionSetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Legend *legendPtr = graphPtr->legend; Element *firstPtr, *lastPtr; const char *string; legendPtr->flags &= ~SELECT_MASK; string = Tcl_GetString(objv[3]); switch (string[0]) { case 's': legendPtr->flags |= SELECT_SET; break; case 'c': legendPtr->flags |= SELECT_CLEAR; break; case 't': legendPtr->flags |= SELECT_TOGGLE; break; } if (GetElementFromObj(graphPtr, objv[4], &firstPtr) != TCL_OK) { return TCL_ERROR; } if ((firstPtr->flags & HIDE) && ((legendPtr->flags & SELECT_CLEAR)==0)) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } lastPtr = firstPtr; if (objc > 5) { if (GetElementFromObj(graphPtr, objv[5], &lastPtr) != TCL_OK) { return TCL_ERROR; } if ((lastPtr->flags & HIDE) && ((legendPtr->flags & SELECT_CLEAR) == 0)) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[5]), "\"", (char *)NULL); return TCL_ERROR; } } if (firstPtr == lastPtr) { SelectEntry(legendPtr, firstPtr); } else { SelectRange(legendPtr, firstPtr, lastPtr); } /* Set both the anchor and the mark. Indicates that a single entry is * selected. */ if (legendPtr->selAnchorPtr == NULL) { legendPtr->selAnchorPtr = firstPtr; } if (legendPtr->flags & SELECT_EXPORT) { Tk_OwnSelection(legendPtr->tkwin, XA_PRIMARY, LostSelectionProc, legendPtr); } Blt_Legend_EventuallyRedraw(graphPtr); if (legendPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(legendPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionOp -- * * This procedure handles the individual options for text selections. * The selected text is designated by start and end indices into the text * pool. The selected segment has both a anchored and unanchored ends. * * Results: * None. * * Side effects: * The selection changes. * * .g legend selection anchor *--------------------------------------------------------------------------- */ static Blt_OpSpec selectionOps[] = { {"anchor", 1, SelectionAnchorOp, 5, 5, "elem",}, {"clear", 5, SelectionSetOp, 5, 6, "firstElem ?lastElem?",}, {"clearall", 6, SelectionClearallOp, 4, 4, "",}, {"includes", 1, SelectionIncludesOp, 5, 5, "elem",}, {"mark", 1, SelectionMarkOp, 5, 5, "elem",}, {"present", 1, SelectionPresentOp, 4, 4, "",}, {"set", 1, SelectionSetOp, 5, 6, "firstElem ?lastElem?",}, {"toggle", 1, SelectionSetOp, 5, 6, "firstElem ?lastElem?",}, }; static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); static int SelectionOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphLegendProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG3, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (graphPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * Blt_LegendOp -- * * Results: * A standard TCL result. * * Side Effects: * Legend is possibly redrawn. * *--------------------------------------------------------------------------- */ static Blt_OpSpec legendOps[] = { {"activate", 1, ActivateOp, 3, 0, "?pattern?...",}, {"bind", 1, BindOp, 3, 6, "elem sequence command",}, {"cget", 2, CgetOp, 4, 4, "option",}, {"configure", 2, ConfigureOp, 3, 0, "?option value?...",}, {"curselection", 2, CurselectionOp, 3, 3, "",}, {"deactivate", 1, ActivateOp, 3, 0, "?pattern?...",}, {"focus", 1, FocusOp, 4, 4, "elem",}, {"get", 1, GetOp, 4, 4, "elem",}, {"icon", 1, IconOp, 5, 5, "elem image",}, {"selection", 1, SelectionOp, 3, 0, "args"}, }; static int nLegendOps = sizeof(legendOps) / sizeof(Blt_OpSpec); int Blt_LegendOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphLegendProc *proc; proc = Blt_GetOpFromObj(interp, nLegendOps, legendOps, BLT_OP_ARG2, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (graphPtr, interp, objc, objv); } int Blt_Legend_Site(Graph *graphPtr) { return graphPtr->legend->site; } int Blt_Legend_Width(Graph *graphPtr) { return graphPtr->legend->width; } int Blt_Legend_Height(Graph *graphPtr) { return graphPtr->legend->height; } int Blt_Legend_IsHidden(Graph *graphPtr) { return (graphPtr->legend->flags & HIDE); } int Blt_Legend_IsRaised(Graph *graphPtr) { return (graphPtr->legend->flags & RAISED); } int Blt_Legend_X(Graph *graphPtr) { return graphPtr->legend->x; } int Blt_Legend_Y(Graph *graphPtr) { return graphPtr->legend->y; } void Blt_Legend_RemoveElement(Graph *graphPtr, Element *elemPtr) { Blt_DeleteBindings(graphPtr->legend->bindTable, elemPtr); } /* *--------------------------------------------------------------------------- * * SelectionProc -- * * This procedure is called back by Tk when the selection is requested by * someone. It returns part or all of the selection in a buffer provided * by the caller. * * Results: * The return value is the number of non-NULL bytes stored at buffer. * Buffer is filled (or partially filled) with a NUL-terminated string * containing part or all of the selection, as given by offset and * maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int SelectionProc( ClientData clientData, /* Information about the widget. */ int offset, /* Offset within selection of first * character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place at * buffer, not including terminating * NULL character. */ { Legend *legendPtr = clientData; int nBytes; Tcl_DString dString; if ((legendPtr->flags & SELECT_EXPORT) == 0) { return -1; } /* Retrieve the names of the selected entries. */ Tcl_DStringInit(&dString); if (legendPtr->flags & SELECT_SORTED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(legendPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); Tcl_DStringAppend(&dString, elemPtr->obj.name, -1); Tcl_DStringAppend(&dString, "\n", -1); } } else { Blt_ChainLink link; Graph *graphPtr; graphPtr = legendPtr->graphPtr; /* List of selected entries is in stacking order. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); if (EntryIsSelected(legendPtr, elemPtr)) { Tcl_DStringAppend(&dString, elemPtr->obj.name, -1); Tcl_DStringAppend(&dString, "\n", -1); } } } nBytes = Tcl_DStringLength(&dString) - offset; strncpy(buffer, Tcl_DStringValue(&dString) + offset, maxBytes); Tcl_DStringFree(&dString); buffer[maxBytes] = '\0'; return MIN(nBytes, maxBytes); } /* *--------------------------------------------------------------------------- * * BlinkCursorProc -- * * This procedure is called as a timer handler to blink the insertion * cursor off and on. * * Results: * None. * * Side effects: * The cursor gets turned on or off, redisplay gets invoked, and this * procedure reschedules itself. * *--------------------------------------------------------------------------- */ static void BlinkCursorProc(ClientData clientData) { Graph *graphPtr = clientData; Legend *legendPtr; legendPtr = graphPtr->legend; if (!(legendPtr->flags & FOCUS) || (legendPtr->offTime == 0)) { return; } if (legendPtr->active) { int time; legendPtr->cursorOn ^= 1; time = (legendPtr->cursorOn) ? legendPtr->onTime : legendPtr->offTime; legendPtr->timerToken = Tcl_CreateTimerHandler(time, BlinkCursorProc, graphPtr); Blt_Legend_EventuallyRedraw(graphPtr); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/pure_api.c��������������������������������������������������������������������0000644�0001750�0001750�00000015427�11462120063�015007� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Header file of Pure API function declarations. * * Explicitly no copyright. * You may recompile and redistribute these definitions as required. * * NOTE1: In some situations when compiling with MFC, you should * enable the setting 'Not using precompiled headers' in Visual C++ * to avoid a compiler diagnostic. * * NOTE2: This file works through the use of deep magic. Calls to functions * in this file are replaced with calls into the OCI runtime system * when an instrumented version of this program is run. * * NOTE3: The static vars avoidGy_n (where n is a unique number) are used * to prevent optimizing the functions away when compiler option * /Gy is set. This is needed so that NOTE2 works properly. */ static int avoidGy_1; static int avoidGy_2; static int avoidGy_3; static int avoidGy_4; static int avoidGy_5; static int avoidGy_6; static int avoidGy_7; static int avoidGy_8; static int avoidGy_9; static int avoidGy_10; static int avoidGy_11; static int avoidGy_12; static int avoidGy_13; static int avoidGy_14; static int avoidGy_15; static int avoidGy_16; static int avoidGy_17; static int avoidGy_18; static int avoidGy_19; static int avoidGy_20; static int avoidGy_21; static int avoidGy_22; static int avoidGy_23; static int avoidGy_24; static int avoidGy_25; static int avoidGy_26; static int avoidGy_27; static int avoidGy_28; static int avoidGy_29; static int avoidGy_30; static int avoidGy_31; static int avoidGy_32; static int avoidGy_33; static int avoidGy_34; static int avoidGy_35; static int avoidGy_36; static int avoidGy_37; static int avoidGy_38; static int avoidGy_39; static int avoidGy_40; static int avoidGy_41; static int avoidGy_42; static int avoidGy_43; static int avoidGy_44; static int avoidGy_45; static int avoidGy_46; static int avoidGy_47; static int avoidGy_48; static int avoidGy_49; static int avoidGy_50; static int avoidGy_51; static int avoidGy_52; static int avoidGy_53; static int avoidGy_54; static int avoidGy_55; static int avoidGy_56; static int avoidGy_57; static int avoidGy_58; static int avoidGy_59; static int avoidGy_60; static int avoidGy_PL_01; __declspec(dllexport) int __cdecl PurePrintf(const char *fmt, ...) { avoidGy_1++; fmt; return 0; } __declspec(dllexport) int __cdecl PurifyIsRunning(void) { avoidGy_2++; return 0; } __declspec(dllexport) int __cdecl PurifyPrintf(const char *fmt, ...) { avoidGy_3++; fmt; return 0; } __declspec(dllexport) int __cdecl PurifyNewInuse(void) { avoidGy_4++; return 0; } __declspec(dllexport) int __cdecl PurifyAllInuse(void) { avoidGy_5++; return 0; } __declspec(dllexport) int __cdecl PurifyClearInuse(void) { avoidGy_6++; return 0; } __declspec(dllexport) int __cdecl PurifyNewLeaks(void) { avoidGy_7++; return 0; } __declspec(dllexport) int __cdecl PurifyAllLeaks(void) { avoidGy_8++; return 0; } __declspec(dllexport) int __cdecl PurifyClearLeaks(void) { avoidGy_9++; return 0; } __declspec(dllexport) int __cdecl PurifyAllHandlesInuse(void) { avoidGy_10++; return 0; } __declspec(dllexport) int __cdecl PurifyNewHandlesInuse(void) { avoidGy_11++; return 0; } __declspec(dllexport) int __cdecl PurifyDescribe(void *addr) { avoidGy_12++; addr; return 0; } __declspec(dllexport) int __cdecl PurifyWhatColors(void *addr, int size) { avoidGy_13++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyAssertIsReadable(const void *addr, int size) { avoidGy_14++; addr; size; return 1; } __declspec(dllexport) int __cdecl PurifyAssertIsWritable(const void *addr, int size) { avoidGy_15++; addr; size; return 1; } __declspec(dllexport) int __cdecl PurifyIsReadable(const void *addr, int size) { avoidGy_16++; addr; size; return 1; } __declspec(dllexport) int __cdecl PurifyIsWritable(const void *addr, int size) { avoidGy_17++; addr; size; return 1; } __declspec(dllexport) int __cdecl PurifyIsInitialized(const void *addr, int size) { avoidGy_18++; addr; size; return 1; } __declspec(dllexport) int __cdecl PurifyRed(void *addr, int size) { avoidGy_19++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyGreen(void *addr, int size) { avoidGy_20++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyYellow(void *addr, int size) { avoidGy_21++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyBlue(void *addr, int size) { avoidGy_22++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyMarkAsInitialized(void *addr, int size) { avoidGy_23++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyMarkAsUninitialized(void *addr, int size) { avoidGy_24++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyMarkForTrap(void *addr, int size) { avoidGy_25++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyMarkForNoTrap(void *addr, int size) { avoidGy_26++; addr; size; return 0; } __declspec(dllexport) int __cdecl PurifyHeapValidate(unsigned int hHeap, unsigned int dwFlags, const void *addr) { avoidGy_27++; hHeap; dwFlags; addr; return 1; } __declspec(dllexport) int __cdecl PurifySetLateDetectScanCounter(int counter) { avoidGy_28++; counter; return 0; }; __declspec(dllexport) int __cdecl PurifySetLateDetectScanInterval(int seconds) { avoidGy_29++; seconds; return 0; }; __declspec(dllexport) int __cdecl CoverageIsRunning(void) { avoidGy_30++; return 0; } __declspec(dllexport) int __cdecl CoverageDisableRecordingData(void) { avoidGy_31++; return 0; } __declspec(dllexport) int __cdecl CoverageStartRecordingData(void) { avoidGy_32++; return 0; } __declspec(dllexport) int __cdecl CoverageStopRecordingData(void) { avoidGy_33++; return 0; } __declspec(dllexport) int __cdecl CoverageClearData(void) { avoidGy_34++; return 0; } __declspec(dllexport) int __cdecl CoverageIsRecordingData(void) { avoidGy_35++; return 0; } __declspec(dllexport) int __cdecl CoverageAddAnnotation(char *str) { avoidGy_36++; str; return 0; } __declspec(dllexport) int __cdecl CoverageSaveData(void) { avoidGy_37++; return 0; } __declspec(dllexport) int __cdecl QuantifyIsRunning(void) { avoidGy_42++; return 0; } __declspec(dllexport) int __cdecl QuantifyDisableRecordingData(void) { avoidGy_43++; return 0; } __declspec(dllexport) int __cdecl QuantifyStartRecordingData(void) { avoidGy_44++; return 0; } __declspec(dllexport) int __cdecl QuantifyStopRecordingData(void) { avoidGy_45++; return 0; } __declspec(dllexport) int __cdecl QuantifyClearData(void) { avoidGy_46++; return 0; } __declspec(dllexport) int __cdecl QuantifyIsRecordingData(void) { avoidGy_47++; return 0; } __declspec(dllexport) int __cdecl QuantifyAddAnnotation(char *str) { avoidGy_48++; str; return 0; } __declspec(dllexport) int __cdecl QuantifySaveData(void) { avoidGy_49++; return 0; } __declspec(dllexport) int __cdecl PurelockIsRunning(void) { avoidGy_PL_01++; return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBitmap.h�������������������������������������������������������������������0000644�0001750�0001750�00000001203�11462120062�015110� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� BLT_EXTERN Pixmap Blt_PhotoImageMask(Tk_Window tkwin, Tk_PhotoImageBlock src); BLT_EXTERN Pixmap Blt_ScaleBitmap(Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight); BLT_EXTERN Pixmap Blt_RotateBitmap(Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, float angle, int *destWidthPtr, int *destHeightPtr); BLT_EXTERN Pixmap Blt_ScaleRotateBitmapArea(Tk_Window tkwin, Pixmap srcBitmap, unsigned int srcWidth, unsigned int srcHeight, int regionX, int regionY, unsigned int regionWidth, unsigned int regionHeight, unsigned int destWidth, unsigned int destHeight, float angle); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinPipe.c������������������������������������������������������������������0000644�0001750�0001750�00000210056�11462120063�015253� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinPipe.c -- * * This modules replacements for the former Tcl_CreatePipeline API * under Windows. This file contains the generic portion of the * command channel driver as well as various utility routines used in * managing subprocesses. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Parts taken from tclPipe.c and tclWinPipe.c in the TCL distribution. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ /* * Todo: * Test on win95 * Does terminating bltwish kill child processes? * Handle EOL translation more cleanly. */ #include "bltInt.h" #include "bltChain.h" #include <fcntl.h> #define PEEK_DEBUG 0 #define QUEUE_DEBUG 0 #define READER_DEBUG 0 #define ASYNC_DEBUG 0 #define KILL_DEBUG 0 /* * The following type identifies the various types of applications that * run under windows. There is special case code for the various types. */ typedef enum ApplicationTypes { APPL_NONE, APPL_DOS, APPL_WIN3X, APPL_WIN32, APPL_INTERP } ApplicationType; #ifndef IMAGE_OS2_SIGNATURE # define IMAGE_OS2_SIGNATURE (0x454E) #endif #ifndef IMAGE_VXD_SIGNATURE # define IMAGE_VXD_SIGNATURE (0x454C) #endif #define PIPE_BUFSIZ (BUFSIZ*2) /* Size of pipe read buffer. */ #define PIPE_PENDING (1<<13) /* Message is pending in the queue. */ #define PIPE_EOF (1<<14) /* Pipe has reached EOF. */ #define PIPE_DELETED (1<<15) /* Indicates if the pipe has been deleted * but its memory hasn't been freed yet. */ typedef struct { int flags; /* State flags, see above for a list. */ HANDLE hPipe; /* Pipe handle */ HANDLE thread; /* Thread watching I/O on this pipe. */ HANDLE parent; /* Handle of main thread. */ DWORD parentId; /* Main thread ID. */ HWND hWindow; /* Notifier window in main thread. Used to * goose the TCL notifier system indicating * that an event has occurred that it * needs to process. */ HANDLE idleEvent; /* Signals that the pipe is idle (no one * is reading/writing from it). */ HANDLE readyEvent; /* Signals that the pipe is ready for * the next I/O operation. */ DWORD lastError; /* Error. */ char *buffer; /* Current background output buffer. */ size_t start, end; /* Pointers into the output buffer */ size_t size; /* Size of buffer. */ Tcl_FileProc *proc; ClientData clientData; } PipeHandler; typedef struct { Tcl_Event header; /* Information that is standard for * all events. */ PipeHandler *pipePtr; /* Pointer to pipe handler structure. * Note that we still have to verify * that the pipe exists before * dereferencing this pointer. */ } PipeEvent; static int initialized = 0; static struct _Blt_Chain pipeChain; static CRITICAL_SECTION pipeCriticalSection; static DWORD WINAPI PipeWriterThread(void *clientData); static DWORD WINAPI PipeReaderThread(void *clientData); static Tcl_FreeProc DestroyPipe; BLT_EXTERN void Blt_MapPid(HANDLE hProcess, DWORD pid); #ifndef USE_TCL_STUBS BLT_EXTERN HINSTANCE TclWinGetTclInstance(void); BLT_EXTERN void TclWinConvertError(DWORD lastError); #endif /* *--------------------------------------------------------------------------- * * NotifierWindowProc -- * * This procedure is called to goose the TCL notifier layer when * service pending events. The notifier is built upon the * Windows message system. The Windows event loop may need to be * awakened if it's blocked waiting on messages. Our psuedo * pipes (e.g. data available on a pipe) won't do that. While * there may be events pending in the TCL queue, Windows knows * nothing about TCL events and won't unblock until the next * Windows message arrives. * * This routine sits in the main thread and is triggered by * messages posted to a notifier window (we set it up earlier) * from the reader/writer pipe threads. It's purpose is two * fold. * * 1) unblock Windows (posting the message does that) and * 2) call Tcl_ServiceAll from the main thread. * * Results: * A standard Windows result. * * Side effects: * Services any pending TCL events. * *--------------------------------------------------------------------------- */ static LRESULT CALLBACK NotifierWindowProc( HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_USER: case WM_TIMER: break; default: return DefWindowProc(hWindow, message, wParam, lParam); } Tcl_ServiceAll(); /* Process all run-able events. */ return 0; } static void WakeupNotifier(HWND hWindow) { PostMessage(hWindow, WM_USER, 0, 0); } /* *--------------------------------------------------------------------------- * * GetNotifierWindow -- * * Initializes the platform specific notifier state. * * Results: * Returns a handle to the notifier state for this thread.. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static HWND GetNotifierWindow(void) { static HWND hWindow = NULL; /* * Register Notifier window class if this is the first thread to * use this module. */ if (hWindow == NULL) { WNDCLASS class; HINSTANCE hInstance; memset(&class, 0, sizeof(WNDCLASS)); hInstance = TclWinGetTclInstance(); class.hInstance = hInstance; class.lpszClassName = "PipeNotifier"; class.lpfnWndProc = NotifierWindowProc; if (!RegisterClassA(&class)) { panic("Unable to register PipeNotifier window class"); } /* * Create a window for communication with the notifier. */ hWindow = CreateWindowA("PipeNotifier", "PipeNotifier", WS_TILED, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); } return hWindow; } /* *--------------------------------------------------------------------------- * * PeekOnPipe -- * * See if some data is available, the pipe is at EOF, or the * reader thread is currently blocked waiting for data. * * Results: * Return TRUE if data is available, FALSE if otherwise. Note * that errors and EOF always return TRUE. We always make the * condition available until the caller handles it by deleting * the pipe event handler. * * On TRUE, the number of bytes returned indicates the following: * 0 EOF. * -1 An error has occured or the thread is currently * blocked reading. In that last case, errno is set * to EAGAIN. * >0 Number of bytes of data in the buffer. * *--------------------------------------------------------------------------- */ static int PeekOnPipe( PipeHandler *pipePtr, /* Pipe state. */ int *nAvailPtr) { int state; *nAvailPtr = -1; #if PEEK_DEBUG PurifyPrintf("PEEK(%d): waiting for reader\n", pipePtr->hPipe); #endif state = WaitForSingleObject(pipePtr->readyEvent, 0); #if PEEK_DEBUG PurifyPrintf("PEEK(%d): state is %d\n", pipePtr->hPipe, state); #endif if (state == WAIT_TIMEOUT) { #if PEEK_DEBUG PurifyPrintf("PEEK(%d): try again, %d\n", pipePtr->hPipe, state); #endif errno = EAGAIN; return FALSE; /* Reader thread is currently blocked. */ } /* * At this point the two threads are synchronized. So it's safe * to access shared information. */ if (state == WAIT_OBJECT_0) { int nAvail; nAvail = pipePtr->end - pipePtr->start; #if PEEK_DEBUG PurifyPrintf("PEEK(%d): Found %d bytes available\n", pipePtr->hPipe, nAvail); #endif if ((nAvail <= 0) && !(pipePtr->flags & PIPE_EOF)) { TclWinConvertError(pipePtr->lastError); #if PEEK_DEBUG PurifyPrintf("PEEK(%d): Error = %d\n", pipePtr->hPipe, pipePtr->lastError); #endif nAvail = -1; } *nAvailPtr = nAvail; } #if PEEK_DEBUG PurifyPrintf("PEEK(%d): Reseting events\n", pipePtr->hPipe); #endif return TRUE; } /* *--------------------------------------------------------------------------- * * PipeEventProc -- * * This function is invoked by Tcl_ServiceEvent when a file event * reaches the front of the event queue. This procedure calls back * the handler procedure designated for this pipe. * * Results: * Returns 1 if the event was handled, meaning it should be removed * from the queue. Returns 0 if the event was not handled, meaning * it should stay on the queue. The only time the event isn't * handled is if the TCL_FILE_EVENTS flag bit isn't set. * * Side effects: * Whatever the pipe handler callback does. * *--------------------------------------------------------------------------- */ static int PipeEventProc(Tcl_Event * eventPtr, int flags) { PipeHandler *pipePtr; if (!(flags & TCL_FILE_EVENTS)) { return 0; } pipePtr = ((PipeEvent *) eventPtr)->pipePtr; if ((pipePtr != NULL) && !(pipePtr->flags & PIPE_DELETED)) { Tcl_Preserve(pipePtr); if (pipePtr->proc != NULL) { (*pipePtr->proc) (pipePtr->clientData, flags); } /* Allow more events again. */ pipePtr->flags &= ~PIPE_PENDING; Tcl_Release(pipePtr); } return 1; } /* *--------------------------------------------------------------------------- * * SetupHandlers -- * * This procedure is invoked before Tcl_DoOneEvent blocks waiting * for an event. * * Results: * None. * * Side effects: * Adjusts the block time if needed. * *--------------------------------------------------------------------------- */ static void SetupHandlers(ClientData clientData, int flags) { Blt_Chain chain = clientData; PipeHandler *pipePtr; Blt_ChainLink link; int dontBlock, nBytes; Tcl_Time blockTime; if (!(flags & TCL_FILE_EVENTS)) { return; } /* * Loop through the list of pipe handlers. Check if any I/O * events are currently pending. */ dontBlock = FALSE; blockTime.sec = blockTime.usec = 0L; #if QUEUE_DEBUG PurifyPrintf("SetupHandlers: before loop\n"); #endif for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { pipePtr = Blt_Chain_GetValue(link); if (pipePtr->flags & PIPE_DELETED) { continue; /* Ignore pipes pending to be freed. */ } if (pipePtr->flags & TCL_READABLE) { if (PeekOnPipe(pipePtr, &nBytes)) { dontBlock = TRUE; } } if (pipePtr->flags & TCL_WRITABLE) { if (WaitForSingleObject(pipePtr->readyEvent, 0) != WAIT_TIMEOUT) { dontBlock = TRUE; } } } #if QUEUE_DEBUG PurifyPrintf("SetupHandlers: after loop\n"); #endif if (dontBlock) { Tcl_SetMaxBlockTime(&blockTime); } } /* *--------------------------------------------------------------------------- * * CheckHandlers -- * * This procedure is called by Tcl_DoOneEvent to check the pipe * event source for events. * * Results: * None. * * Side effects: * May queue an event. * *--------------------------------------------------------------------------- */ static void CheckHandlers(ClientData clientData, int flags) { Blt_Chain chain = clientData; PipeHandler *pipePtr; Blt_ChainLink link; int queueEvent, nBytes; if ((flags & TCL_FILE_EVENTS) == 0) { return; } /* Queue events for any ready pipes that aren't already queued. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { pipePtr = Blt_Chain_GetValue(link); if (pipePtr->flags & (PIPE_PENDING | PIPE_DELETED)) { continue; /* If this pipe already is scheduled to * service an event, wait for it to handle * it. */ } /* Queue an event if the pipe is signaled for reading or writing. */ queueEvent = FALSE; if (pipePtr->flags & TCL_READABLE) { if (PeekOnPipe(pipePtr, &nBytes)) { queueEvent = TRUE; } } if (pipePtr->flags & TCL_WRITABLE) { if (WaitForSingleObject(pipePtr->readyEvent, 0) != WAIT_TIMEOUT) { queueEvent = TRUE; } } #if QUEUE_DEBUG PurifyPrintf("Queue event is %d \n", queueEvent); #endif if (queueEvent) { PipeEvent *eventPtr; pipePtr->flags |= PIPE_PENDING; eventPtr = Blt_AssertMalloc(sizeof(PipeEvent)); eventPtr->header.proc = PipeEventProc; eventPtr->pipePtr = pipePtr; Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_TAIL); } } } static PipeHandler * CreatePipeHandler(HANDLE hFile, int flags) { DWORD id; PipeHandler *pipePtr; LPTHREAD_START_ROUTINE threadProc; pipePtr = Blt_AssertCalloc(1, sizeof(PipeHandler)); pipePtr->hPipe = hFile; pipePtr->flags = flags; pipePtr->parentId = GetCurrentThreadId(); pipePtr->parent = GetCurrentThread(); pipePtr->hWindow = GetNotifierWindow(); pipePtr->readyEvent = CreateEvent( NULL, /* Security attributes. */ TRUE, /* Manual reset event */ FALSE, /* Initially not signaled. */ NULL); /* Event object's name. */ pipePtr->idleEvent = CreateEvent( NULL, /* Security attributes. */ FALSE, /* Auto reset event. */ TRUE, /* Initially signaled. */ NULL); /* Event object's name. */ if (flags & TCL_READABLE) { threadProc = (LPTHREAD_START_ROUTINE) PipeReaderThread; pipePtr->buffer = Blt_AssertCalloc(1, PIPE_BUFSIZ); pipePtr->size = PIPE_BUFSIZ; } else { threadProc = (LPTHREAD_START_ROUTINE) PipeWriterThread; } pipePtr->thread = CreateThread( NULL, /* Security attributes */ 8000, /* Initial stack size. */ threadProc, /* Starting address of thread routine */ (DWORD *) pipePtr, /* One-word of data passed to routine. */ 0, /* Creation flags */ &id); /* (out) Will contain Id of new thread. */ return pipePtr; } static void DestroyPipe(DestroyData data) { PipeHandler *pipePtr = (PipeHandler *)data; if (pipePtr->buffer != NULL) { Blt_Free(pipePtr->buffer); } Blt_Free(pipePtr); } static void DeletePipeHandler(PipeHandler * pipePtr) { #if KILL_DEBUG PurifyPrintf("DestroyPipeHandler(%d)\n", pipePtr->hPipe); #endif if ((pipePtr->flags & TCL_WRITABLE) && (pipePtr->hPipe != INVALID_HANDLE_VALUE)) { /* Wait for the writer thread to finish with the current buffer */ WaitForSingleObject(pipePtr->idleEvent, INFINITE); } if (pipePtr->hPipe != INVALID_HANDLE_VALUE) { CloseHandle(pipePtr->hPipe); } CloseHandle(pipePtr->readyEvent); CloseHandle(pipePtr->idleEvent); CloseHandle(pipePtr->thread); pipePtr->idleEvent = pipePtr->readyEvent = INVALID_HANDLE_VALUE; pipePtr->thread = pipePtr->hPipe = INVALID_HANDLE_VALUE; pipePtr->flags |= PIPE_DELETED; /* Mark the pipe has deleted. */ Tcl_EventuallyFree(pipePtr, DestroyPipe); } /* *--------------------------------------------------------------------------- * * PipeInit -- * * This function initializes the static variables for this file. * * Results: * None. * * Side effects: * Creates a new event source. * *--------------------------------------------------------------------------- */ static void PipeInit(void) { initialized = TRUE; InitializeCriticalSection(&pipeCriticalSection); Blt_Chain_Init(&pipeChain); Tcl_CreateEventSource(SetupHandlers, CheckHandlers, &pipeChain); } static PipeHandler * GetPipeHandler(HANDLE hPipe) { PipeHandler *pipePtr; Blt_ChainLink link; for (link = Blt_Chain_FirstLink(&pipeChain); link != NULL; link = Blt_Chain_NextLink(link)) { pipePtr = Blt_Chain_GetValue(link); if ((pipePtr->hPipe == hPipe) && !(pipePtr->flags & PIPE_DELETED)){ return pipePtr; } } return NULL; } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_PipeTeardown -- * * This function releases any storage allocated for this file. * * Results: * None. * * Side effects: * Creates a new event source. * *--------------------------------------------------------------------------- */ void Blt_PipeTeardown(void) { Blt_ChainLink link; PipeHandler *pipePtr; if (!initialized) { return; /* Was never initialized. */ } initialized = FALSE; EnterCriticalSection(&pipeCriticalSection); for (link = Blt_Chain_FirstLink(&pipeChain); link != NULL; link = Blt_Chain_NextLink(link)) { pipePtr = Blt_Chain_GetValue(link); if ((pipePtr != NULL) && !(pipePtr->flags & PIPE_DELETED)) { DeletePipeHandler(pipePtr); } } DestroyWindow(GetNotifierWindow()); UnregisterClassA("PipeNotifier", TclWinGetTclInstance()); Blt_Chain_Reset(&pipeChain); LeaveCriticalSection(&pipeCriticalSection); Tcl_DeleteEventSource(SetupHandlers, CheckHandlers, &pipeChain); DeleteCriticalSection(&pipeCriticalSection); } #endif /* *--------------------------------------------------------------------------- * * PipeReaderThread -- * * This function runs in a separate thread and waits for input * to become available on a pipe. * * Results: * None. * * Side effects: * Signals the main thread when input become available. May * cause the main thread to wake up by posting a message. * *--------------------------------------------------------------------------- */ static DWORD WINAPI PipeReaderThread(void *clientData) { PipeHandler *pipePtr = (PipeHandler *) clientData; DWORD count; BOOL result; for (;;) { if (pipePtr->flags & PIPE_DELETED) { break; } /* Synchronize with the main thread so that we don't try to * read from the pipe while it's copying to the buffer. */ #if READER_DEBUG PurifyPrintf("READER(%d): waiting\n", pipePtr->hPipe); #endif WaitForSingleObject(pipePtr->idleEvent, INFINITE); #if READER_DEBUG PurifyPrintf("READER(%d): ok\n", pipePtr->hPipe); #endif /* Read from the pipe. The thread will block here until some * data is read into its buffer. */ #if READER_DEBUG PurifyPrintf("READER(%d): before read\n", pipePtr->hPipe); #endif assert(pipePtr->start == pipePtr->end); result = ReadFile( pipePtr->hPipe, /* Handle to anonymous pipe. */ pipePtr->buffer, /* Data buffer. */ pipePtr->size, /* Requested number of bytes (the size * of the buffer) */ &count, /* (out) Number of bytes actually read. */ NULL); /* Overlapping I/O */ if (result) { #if READER_DEBUG PurifyPrintf("READER(%d): after read. status=%d, count=%d\n", pipePtr->hPipe, result, count); #endif } /* * Reset counters to indicate that the buffer has been refreshed. */ pipePtr->start = 0; pipePtr->end = count; if (count == 0) { /* We've hit EOF or an error. */ pipePtr->lastError = GetLastError(); if ((pipePtr->lastError == ERROR_BROKEN_PIPE) || (pipePtr->lastError == ERROR_HANDLE_EOF)) { pipePtr->flags |= PIPE_EOF; } #if READER_DEBUG PurifyPrintf("READER(%d): error is %s\n", pipePtr->hPipe, Blt_LastError()); #endif } WakeupNotifier(pipePtr->hWindow); SetEvent(pipePtr->readyEvent); if (count == 0) { #if READER_DEBUG PurifyPrintf("READER(%d): exiting\n", pipePtr->hPipe); #endif ExitThread(0); } } /* NOTREACHED */ return 0; } /* *--------------------------------------------------------------------------- * * PipeWriterThread -- * * This function runs in a separate thread and writes data * to the process' standard input pipe. * * Results: * Always returns 0. * * Side effects: * Signals the main thread when an output operation is completed. * May cause the main thread to wake up by posting a message. * *--------------------------------------------------------------------------- */ static DWORD WINAPI PipeWriterThread(void *clientData) { PipeHandler *pipePtr = (PipeHandler *) clientData; DWORD count, bytesLeft; char *ptr; for (;;) { if (pipePtr->flags & PIPE_DELETED) { break; } /* * Synchronize with the main thread so that we don't test the * pipe until its done writing. */ WaitForSingleObject(pipePtr->idleEvent, INFINITE); ptr = pipePtr->buffer; bytesLeft = pipePtr->end; /* Loop until all of the bytes are written or an error occurs. */ while (bytesLeft > 0) { if (!WriteFile(pipePtr->hPipe, ptr, bytesLeft, &count, NULL)) { pipePtr->lastError = GetLastError(); break; } bytesLeft -= count; ptr += count; } /* Tell the main thread that data can be written to the pipe. * Remember to wake up the notifier thread. */ SetEvent(pipePtr->readyEvent); WakeupNotifier(pipePtr->hWindow); } /* NOTREACHED */ return 0; } /* *--------------------------------------------------------------------------- * * TempFileName -- * * Gets a temporary file name and deals with the fact that the * temporary file path provided by Windows may not actually exist * if the TMP or TEMP environment variables refer to a * non-existent directory. * * Results: * 0 if error, non-zero otherwise. If non-zero is returned, the * name buffer will be filled with a name that can be used to * construct a temporary file. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int TempFileName(char *name) /* (out) Buffer to hold name of * temporary file. */ { if ((GetTempPath(MAX_PATH, name) > 0) && (GetTempFileName(name, "TCL", 0, name))) { return 1; } /* Bail out and use the current working directory. */ return GetTempFileName(".", "TCL", 0, name); } /* *--------------------------------------------------------------------------- * * OpenRedirectFile -- * * Open a file for use in a pipeline. * * Results: * Returns a new handle or NULL on failure. * * Side effects: * May cause a file to be created on the file system. * *--------------------------------------------------------------------------- */ static HANDLE OpenRedirectFile( const char *path, DWORD accessFlags, DWORD createFlags) { HANDLE hFile; DWORD attribFlags; int useExisting; attribFlags = 0; useExisting = (createFlags & (TRUNCATE_EXISTING | OPEN_EXISTING)); if (useExisting) { attribFlags = GetFileAttributes(path); if (attribFlags == 0xFFFFFFFF) { attribFlags = 0; } } hFile = CreateFile(path, accessFlags, /* Access mode flags */ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, /* No security */ createFlags, /* Creation attributes */ attribFlags, /* File attribute flags */ NULL); /* Template file */ if (hFile == INVALID_HANDLE_VALUE) { DWORD lastError; lastError = GetLastError(); if ((lastError & 0xffffL) == ERROR_OPEN_FAILED) { lastError = (useExisting) ? ERROR_FILE_NOT_FOUND : ERROR_FILE_EXISTS; } TclWinConvertError(lastError); return INVALID_HANDLE_VALUE; } /* * Seek to the end of file if we are writing. */ if (createFlags & GENERIC_WRITE) { SetFilePointer(hFile, 0, NULL, FILE_END); } return hFile; } /* *--------------------------------------------------------------------------- * * CreateTempFile -- * * This function creates a temporary file initialized with an * optional string, and returns a file handle with the file pointer * at the beginning of the file. * * Results: * A handle to a file. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static HANDLE CreateTempFile(const char *data) /* String to write into temp file, or * NULL. */ { char fileName[MAX_PATH + 1]; HANDLE hFile; DWORD lastError; if (!TempFileName(fileName)) { return INVALID_HANDLE_VALUE; } hFile = CreateFile( fileName, /* File path */ GENERIC_READ | GENERIC_WRITE, /* Access mode */ 0, /* No sharing. */ NULL, /* Security attributes */ CREATE_ALWAYS, /* Overwrite any existing file */ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); /* No template file */ if (hFile == INVALID_HANDLE_VALUE) { goto error; } if (data != NULL) { DWORD result, length; const char *p; const char *string; string = data; for (p = string; *p != '\0'; p++) { if (*p == '\n') { length = p - string; if (length > 0) { if (!WriteFile(hFile, string, length, &result, NULL)) { goto error; } } if (!WriteFile(hFile, "\r\n", 2, &result, NULL)) { goto error; } string = p + 1; } } length = p - string; if (length > 0) { if (!WriteFile(hFile, string, length, &result, NULL)) { goto error; } } if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == (DWORD) - 1) { goto error; } } return hFile; error: lastError = GetLastError(); CloseHandle(hFile); DeleteFile(fileName); /* Do I need this? Delete on close? */ TclWinConvertError(lastError); return INVALID_HANDLE_VALUE; } /* *--------------------------------------------------------------------------- * * HasConsole -- * * Determines whether the current application is attached to a * console. * * Results: * Returns TRUE if this application has a console, else FALSE. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static BOOL HasConsole(void) { HANDLE hFile; hFile = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return FALSE; } CloseHandle(hFile); return TRUE; } static ApplicationType GetApplicationType(const char *file, char *cmdPrefix) { char *dot; HANDLE hFile; IMAGE_DOS_HEADER imageDosHeader; ULONG signature; BOOL result; DWORD offset; DWORD nBytes; ApplicationType type; dot = strrchr(file, '.'); if ((dot != NULL) && (strcasecmp(dot, ".bat") == 0)) { return APPL_DOS; } /* Work a little harder. Open the binary and read the header */ hFile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return APPL_NONE; } type = APPL_NONE; result = ReadFile(hFile, &imageDosHeader, sizeof(IMAGE_DOS_HEADER), &nBytes, NULL); if ((!result) || (nBytes != sizeof(IMAGE_DOS_HEADER))) { goto done; } #if KILL_DEBUG PurifyPrintf("magic number is %x\n", imageDosHeader.e_magic); #endif if (imageDosHeader.e_magic == 0x2123) { /* #! */ char *p; unsigned int i; offset = SetFilePointer(hFile, 2, NULL, FILE_BEGIN); if (offset == (DWORD) - 1) { goto done; } result = ReadFile(hFile, cmdPrefix, MAX_PATH + 1, &nBytes, NULL); if ((!result) || (nBytes < 1)) { goto done; } for (p = cmdPrefix, i = 0; i < nBytes; i++, p++) { if ((*p == '\n') || (*p == '\r')) { break; } } *p = '\0'; type = APPL_INTERP; goto done; } /* * Doesn't have the magic number for relocatable executables. If * filename ends with .com, assume it's a DOS application anyhow. * Note that we didn't make this assumption at first, because some * supposed .com files are really 32-bit executables with all the * magic numbers and everything. */ if ((dot != NULL) && (strcmp(dot, ".com") == 0)) { #if KILL_DEBUG PurifyPrintf(".com\n"); #endif type = APPL_DOS; goto done; } if (imageDosHeader.e_magic != IMAGE_DOS_SIGNATURE) { #if KILL_DEBUG PurifyPrintf("Application doesn't have correct sig?\n"); #endif } if (imageDosHeader.e_lfarlc != sizeof(IMAGE_DOS_HEADER)) { /* This assumes that all 3.x and Win32 programs have their * file relocation table immediately following this header. */ /* * All Windows 3.X and Win32 and some DOS programs have this value * set here. If it doesn't, assume that since it already had the * other magic number it was a DOS application. */ #if KILL_DEBUG PurifyPrintf("wrong reloc table address\n"); #endif type = APPL_DOS; goto done; } offset = SetFilePointer(hFile, imageDosHeader.e_lfanew, NULL, FILE_BEGIN); if (offset == (DWORD) - 1) { goto done; } result = ReadFile(hFile, &signature, sizeof(ULONG), &nBytes, NULL); if ((!result) || (nBytes != sizeof(ULONG))) { goto done; } #if KILL_DEBUG PurifyPrintf("signature is %x\n", signature); #endif switch (signature) { case IMAGE_NT_SIGNATURE: type = APPL_WIN32; break; case IMAGE_OS2_SIGNATURE: type = APPL_WIN3X; break; case IMAGE_VXD_SIGNATURE: type = APPL_WIN32; break; default: type = APPL_DOS; break; } done: CloseHandle(hFile); return type; } /* *--------------------------------------------------------------------------- * * GetFullPath -- * * Look for the program as an external program. First try the * name as it is, then try adding .com, .exe, and .bat, in that * order, to the name, looking for an executable. * * Using the raw SearchPath() procedure doesn't do quite what is * necessary. If the name of the executable already contains a * '.' character, it will not try appending the specified * extension when searching (in other words, SearchPath will * not find the program "a.b.exe" if the arguments specified * "a.b" and ".exe"). So, first look for the file as it is * named. Then manually append extensions, looking for a * match. * * Results: * Always returns TCL_OK. * * Side Effects: * *--------------------------------------------------------------------------- */ static int GetFullPath( Tcl_Interp *interp, /* Interpreter to report errors to */ const char *program, /* Name of program. */ char *fullPath, /* (out) Returned full path. */ char *cmdPrefix, /* (out) If program is a script, this contains * the name of the interpreter. */ ApplicationType * typePtr) { /* (out) Type of program */ TCHAR *rest; DWORD attr; int length; char cmd[MAX_PATH + 5]; const char **p; char *ext; static const char *dosExts[] = { "", ".com", ".exe", ".bat", NULL }; *typePtr = APPL_NONE; length = strlen(program); strcpy(cmd, program); cmdPrefix[0] = '\0'; ext = cmd + length; for (p = dosExts; *p != NULL; p++) { *ext = '\0'; /* Reset to original program name. */ strcpy(ext, *p); /* Append the DOS extension to the * program name. */ if (!SearchPath( NULL, /* Use standard Windows search paths */ cmd, /* Program name */ NULL, /* Extension provided by program name. */ MAX_PATH, /* Buffer size */ fullPath, /* Buffer for absolute path of program */ &rest)) { continue; /* Can't find program with that extension */ } /* * Ignore matches on directories or data files. * Return when we identify a known program type. */ attr = GetFileAttributesA(fullPath); if ((attr == (DWORD)-1) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { continue; } *typePtr = GetApplicationType(fullPath, cmdPrefix); if (*typePtr != APPL_NONE) { break; } } if (*typePtr == APPL_NONE) { /* * Can't find the program. Check if it's an internal shell command * like "copy" or "dir" and let cmd.exe deal with it. */ static const char *shellCmds[] = { "copy", "del", "dir", "echo", "edit", "erase", "label", "md", "rd", "ren", "start", "time", "type", "ver", "vol", NULL }; for (p = shellCmds; *p != NULL; p++) { if (((*p)[0] == program[0]) && (strcmp(*p, program) == 0)) { break; } } if (*p == NULL) { Tcl_AppendResult(interp, "can't execute \"", program, "\": no such file or directory", (char *)NULL); return TCL_ERROR; } *typePtr = APPL_DOS; strcpy(fullPath, program); } if ((*typePtr == APPL_DOS) || (*typePtr == APPL_WIN3X)) { /* For 16-bit applications, convert the long executable path * name to a short one. Otherwise the application may not be * able to correctly parse its own command line. */ GetShortPathName(fullPath, fullPath, MAX_PATH); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConcatCmdArgs -- * * Concatonates command line arguments parsed from TCL into a * single string. If an argument contain spaces, it is grouped * with surrounding double quotes. Must also escape any quotes we * find. * * Results: * Returns a malloc-ed string containing the concatonated command * line. * *--------------------------------------------------------------------------- */ static char * ConcatCmdArgs( Tcl_Interp *interp, int argc, char **argv, Tcl_DString *resultPtr) { BOOL needQuote; const char *s; char *cp; char *string; /* Will contain the new command line */ int count; int i; /* * Pass 1. Compute how much space we need for an array to hold the entire * command line. Then allocate the string. */ count = 0; for (i = 0; i < argc; i++) { needQuote = FALSE; if (*argv[i] == '\0') { needQuote = TRUE; /* Zero length args also need quotes. */ } for (s = argv[i]; *s != '\0'; s++) { if (*s == '"') { const char *bp; count++; /* +1 Backslash needed to escape quote */ for (bp = s - 1; (*bp == '\\') && (bp >= argv[i]); bp--) { count++; /* +? one for each preceding backslash */ } } else if (isspace(*s)) { needQuote = TRUE; } count++; /* +1 Normal character */ } if (needQuote) { count += 2; /* +2 Pair of quotes */ } count++; /* +1 Space separating arguments */ } string = Blt_AssertMalloc(count + 1); /* * Pass 2. Copy the arguments, quoting arguments with embedded spaces and * escaping all other quotes in the string. */ cp = string; for (i = 0; i < argc; i++) { needQuote = FALSE; if (*argv[i] == '\0') { needQuote = TRUE; } for (s = argv[i]; *s != '\0'; s++) { if (isspace(*s)) { needQuote = TRUE; } } if (needQuote) { *cp++ = '"'; } for (s = argv[i]; *s; s++) { if (*s == '"') { const char *bp; for (bp = s - 1; (*bp == '\\') && (bp >= argv[i]); bp--) { *cp++ = '\\'; } *cp++ = '\\'; } *cp++ = *s; } if (needQuote) { *cp++ = '"'; } *cp++ = ' '; } *cp = '\0'; assert((cp - string) == count); #if (_TCL_VERSION >= _VERSION(8,1,0)) { Tcl_DString dString; Tcl_Encoding encoding; /* Convert to external encoding */ encoding = Tcl_GetEncoding(interp, NULL); Tcl_UtfToExternalDString(encoding, string, count, &dString); Tcl_DStringAppend(resultPtr, Tcl_DStringValue(&dString), -1); Tcl_DStringFree(&dString); } #else Tcl_DStringAppend(resultPtr, string, count); #endif Blt_Free(string); return Tcl_DStringValue(resultPtr); } /* *--------------------------------------------------------------------------- * * StartProcess -- * * Create a child process that has the specified files as its * standard input, output, and error. * * The complete Windows search path is searched to find the specified * executable. If an executable by the given name is not found, * automatically tries appending ".com", ".exe", and ".bat" to the * executable name. * * Results: * The return value is TCL_ERROR and an error message is left in * the interp's result if there was a problem creating the child * process. Otherwise, the return value is TCL_OK and *pidPtr is * filled with the process id of the child process. * * Side effects: * A process is created. * *--------------------------------------------------------------------------- */ static int StartProcess( Tcl_Interp *interp, /* Interpreter to report errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to errorFile. */ int argc, /* Number of arguments. */ char **argv, /* Command line arguments. */ HANDLE hStdin, /* File handle to use as input (stdin) for the * child process. If handle is -1, no * standard input. */ HANDLE hStdout, /* File handle to receive output (stdout) * from the child process. If -1, output * is discarded. */ HANDLE hStderr, /* File handle to receive errors (stderr) * from the child process. If -1, stderr * will be discarded. Can be the same handle * as hStdOut */ HANDLE *hProcessPtr, /* (out) Handle of child process. */ DWORD *pidPtr) /* (out) Id of child process. */ { int result, createFlags; ApplicationType applType; Tcl_DString dString; /* Complete command line */ char *command; BOOL hasConsole; #ifdef notdef DWORD idleResult; #endif STARTUPINFOA si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES securityAttrs; HANDLE hProcess, hPipe; char progPath[MAX_PATH]; char cmdPrefix[MAX_PATH]; *hProcessPtr = INVALID_HANDLE_VALUE; GetFullPath(interp, argv[0], progPath, cmdPrefix, &applType); #if KILL_DEBUG PurifyPrintf("Application type is %d\n", (int)applType); #endif if (applType == APPL_NONE) { return TCL_ERROR; } result = TCL_ERROR; hProcess = GetCurrentProcess(); ZeroMemory(&si, sizeof(STARTUPINFOA)); si.cb = sizeof(STARTUPINFOA); /* * The flag STARTF_USESTDHANDLES must be set to pass handles to * the child process. Using SetStdHandle and/or dup2 works only * when a console mode parent process is spawning an attached * console mode child process. */ si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = INVALID_HANDLE_VALUE; securityAttrs.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttrs.lpSecurityDescriptor = NULL; securityAttrs.bInheritHandle = TRUE; /* * Duplicate all the handles to be passed off as stdin, stdout and * stderr of the child process. The duplicate handles are set to * be inheritable, so the child process can use them. */ if (hStdin == INVALID_HANDLE_VALUE) { /* * If handle was not set, stdin should return immediate EOF. * Under Windows95, some applications (both 16 and 32 bit!) * can't read from the NUL device; they read from console * instead. When running tk, this is fatal because the child * process would hang forever waiting for EOF from the unmapped * console window used by the helper application. * * Fortunately, the helper application detects a closed pipe * as an immediate EOF and can pass that information to the * child process. */ if (CreatePipe(&si.hStdInput, &hPipe, &securityAttrs, 0)) { CloseHandle(hPipe); } } else { DuplicateHandle(hProcess, hStdin, hProcess, &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (si.hStdInput == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't duplicate input handle: ", Blt_LastError(), (char *)NULL); goto closeHandles; } if (hStdout == INVALID_HANDLE_VALUE) { /* * If handle was not set, output should be sent to an infinitely * deep sink. Under Windows 95, some 16 bit applications cannot * have stdout redirected to NUL; they send their output to * the console instead. Some applications, like "more" or "dir /p", * when outputting multiple pages to the console, also then try and * read from the console to go the next page. When running tk, this * is fatal because the child process would hang forever waiting * for input from the unmapped console window used by the helper * application. * * Fortunately, the helper application will detect a closed pipe * as a sink. */ if ((Blt_GetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) && (applType == APPL_DOS)) { if (CreatePipe(&hPipe, &si.hStdOutput, &securityAttrs, 0)) { CloseHandle(hPipe); } } else { si.hStdOutput = CreateFileA("NUL:", GENERIC_WRITE, 0, &securityAttrs, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } } else { DuplicateHandle(hProcess, hStdout, hProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (si.hStdOutput == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't duplicate output handle: ", Blt_LastError(), (char *)NULL); goto closeHandles; } if (hStderr == INVALID_HANDLE_VALUE) { /* * If handle was not set, errors should be sent to an infinitely * deep sink. */ si.hStdError = CreateFileA("NUL:", GENERIC_WRITE, 0, &securityAttrs, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { DuplicateHandle(hProcess, hStderr, hProcess, &si.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (si.hStdError == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't duplicate error handle: ", Blt_LastError(), (char *)NULL); goto closeHandles; } Tcl_DStringInit(&dString); createFlags = 0; hasConsole = HasConsole(); if (!hasConsole) { createFlags |= DETACHED_PROCESS; } /* * If we do not have a console window, then we must run DOS and * WIN32 console mode applications as detached processes. This tells * the loader that the child application should not inherit the * console, and that it should not create a new console window for * the child application. The child application should get its stdio * from the redirection handles provided by this application, and run * in the background. * * If we are starting a GUI process, they don't automatically get a * console, so it doesn't matter if they are started as foreground or * detached processes. The GUI window will still pop up to the * foreground. */ if (applType == APPL_DOS) { if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { /* * Under NT, 16-bit DOS applications will not run unless they * can be attached to a console. If we are running without a * console, run the 16-bit program as an normal process inside * of a hidden console application, and then run that hidden * console as a detached process. */ si.wShowWindow = SW_HIDE; si.dwFlags |= STARTF_USESHOWWINDOW; createFlags = CREATE_NEW_CONSOLE; Tcl_DStringAppend(&dString, "cmd.exe /c ", -1); } else { /* * Under Windows 95, 16-bit DOS applications do not work well * with pipes: * * 1. EOF on a pipe between a detached 16-bit DOS application * and another application is not seen at the other * end of the pipe, so the listening process blocks forever on * reads. This inablity to detect EOF happens when either a * 16-bit app or the 32-bit app is the listener. * * 2. If a 16-bit DOS application (detached or not) blocks when * writing to a pipe, it will never wake up again, and it * eventually brings the whole system down around it. * * The 16-bit application is run as a normal process * inside of a hidden helper console app, and this helper * may be run as a detached process. If a stdio handle is * a pipe, the helper application accumulates information * into temp files and forwards it to or from the DOS * application as appropriate. This means that DOS apps * must receive EOF from a stdin pipe before they will * actually begin, and must finish generating stdout or * stderr before the data will be sent to the next stage * of the pipe. * * The helper app should be located in the same directory * as the tcl dll. */ if (!hasConsole) { si.wShowWindow = SW_HIDE; si.dwFlags |= STARTF_USESHOWWINDOW; createFlags = CREATE_NEW_CONSOLE; } Tcl_DStringAppend(&dString, "tclpip" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll ", -1); } } else if (applType == APPL_INTERP) { Tcl_DStringAppend(&dString, cmdPrefix, -1); Tcl_DStringAppend(&dString, " ", -1); } argv[0] = progPath; command = ConcatCmdArgs(interp, argc, argv, &dString); #if KILL_DEBUG PurifyPrintf("command is %s\n", command); #endif result = CreateProcess( NULL, /* Module name. */ (TCHAR *)command, /* Command line */ NULL, /* Process security */ NULL, /* Thread security */ TRUE, /* Inherit handles */ createFlags, /* Creation flags */ NULL, /* Environment */ NULL, /* Current working directory */ &si, /* Initialization for process: includes * standard handles, appearance and location * of window */ &pi); /* (out) Information about newly created process */ Tcl_DStringFree(&dString); if (!result) { Tcl_AppendResult(interp, "can't execute \"", argv[0], "\": ", Blt_LastError(), (char *)NULL); goto closeHandles; } #if KILL_DEBUG PurifyPrintf("Starting process with handle of %d\n", pi.hProcess); PurifyPrintf("Starting process with id of %d\n", pi.dwProcessId); #endif if (applType == APPL_DOS) { /* Force the OS to give some time to the DOS process. */ WaitForSingleObject(hProcess, 50); } #ifdef notdef /* FIXME: I don't think this actually * ever worked. WaitForInputIdle * usually fails with "Access is * denied" (maybe the process handle * isn't valid yet?). When you add a * delay, WaitForInputIdle will time * out instead. */ /* * PSS ID Number: Q124121 * * "When an application spawns a process repeatedly, a new * thread instance will be created for each process but the * previous instances may not be cleaned up. This results in * a significant virtual memory loss each time the process is * spawned. If there is a WaitForInputIdle() call between * CreateProcess() and CloseHandle(), the problem does not * occur." */ idleResult = WaitForInputIdle(pi.hProcess, 1000); if (idleResult == (DWORD) - 1) { #if KILL_DEBUG PurifyPrintf("wait failed on %d: %s\n", pi.hProcess, Blt_LastError()); #endif } #endif CloseHandle(pi.hThread); *hProcessPtr = pi.hProcess; /* * Add the entry to mapping table. Its purpose is to translate * process handles to process ids. Most things we do with the * Win32 API take handles, but we still want to present process * ids to the user. */ *pidPtr = pi.dwProcessId; result = TCL_OK; closeHandles: if (si.hStdInput != INVALID_HANDLE_VALUE) { CloseHandle(si.hStdInput); } if (si.hStdOutput != INVALID_HANDLE_VALUE) { CloseHandle(si.hStdOutput); } if (si.hStdError != INVALID_HANDLE_VALUE) { CloseHandle(si.hStdError); } return result; } /* *--------------------------------------------------------------------------- * * FileForRedirect -- * * This procedure does much of the work of parsing redirection * operators. It handles "@" if specified and allowed, and a file * name, and opens the file if necessary. * * Results: * The return value is the descriptor number for the file. If an * error occurs then NULL is returned and an error message is left * in interp->result. Several arguments are side-effected; see * the argument list below for details. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static HANDLE FileForRedirect( Tcl_Interp *interp, /* Intepreter to use for error reporting. */ char *spec, /* Points to character just after * redirection character. */ BOOL atOK, /* Non-zero means that '@' notation can be * used to specify a channel, zero means that * it isn't. */ char *arg, /* Pointer to entire argument containing * spec: used for error reporting. */ char *nextArg, /* Next argument in argc/argv array, if needed * for file name or channel name. May be * NULL. */ DWORD accessFlags, /* Flags to use for opening file or to * specify mode for channel. */ DWORD createFlags, /* Flags to use for opening file or to * specify mode for channel. */ int *skipPtr, /* Filled with 1 if redirection target was * in spec, 2 if it was in nextArg. */ int *closePtr) /* Filled with one if the caller should * close the file when done with it, zero * otherwise. */ { int writing = (accessFlags & GENERIC_WRITE); Tcl_Channel chan; HANDLE hFile; *skipPtr = 1; *closePtr = FALSE; if ((atOK) && (*spec == '@')) { spec++; if (*spec == '\0') { spec = nextArg; if (spec == NULL) { goto badLastArg; } *skipPtr = 2; } chan = Tcl_GetChannel(interp, spec, NULL); if (chan == NULL) { return INVALID_HANDLE_VALUE; } if (Tcl_GetChannelHandle(chan, (writing) ? TCL_WRITABLE : TCL_READABLE, (ClientData *)&hFile) != TCL_OK) { hFile = INVALID_HANDLE_VALUE; } if (hFile == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(chan), "\" wasn't opened for ", ((writing) ? "writing" : "reading"), (char *)NULL); return INVALID_HANDLE_VALUE; } if (writing) { /* * Be sure to flush output to the file, so that anything * written by the child appears after stuff we've already * written. */ Tcl_Flush(chan); } } else { char *name; Tcl_DString dString; if (*spec == '\0') { spec = nextArg; if (spec == NULL) { goto badLastArg; } *skipPtr = 2; } name = Tcl_TranslateFileName(interp, spec, &dString); if (name != NULL) { hFile = OpenRedirectFile(name, accessFlags, createFlags); } else { hFile = INVALID_HANDLE_VALUE; } Tcl_DStringFree(&dString); if (hFile == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't ", (writing) ? "write" : "read", " file \"", spec, "\": ", Tcl_PosixError(interp), (char *)NULL); return INVALID_HANDLE_VALUE; } *closePtr = TRUE; } return hFile; badLastArg: Tcl_AppendResult(interp, "can't specify \"", arg, "\" as last word in command", (char *)NULL); return INVALID_HANDLE_VALUE; } /* *--------------------------------------------------------------------------- * * Blt_CreatePipeline -- * * Given an argc/argv array, instantiate a pipeline of processes * as described by the argv. * * Results: * The return value is a count of the number of new processes * created, or -1 if an error occurred while creating the pipeline. * *pidArrayPtr is filled in with the address of a dynamically * allocated array giving the ids of all of the processes. It * is up to the caller to free this array when it isn't needed * anymore. If inPipePtr is non-NULL, *inPipePtr is filled in * with the file id for the input pipe for the pipeline (if any): * the caller must eventually close this file. If outPipePtr * isn't NULL, then *outPipePtr is filled in with the file id * for the output pipe from the pipeline: the caller must close * this file. If errPipePtr isn't NULL, then *errPipePtr is filled * with a file id that may be used to read error output after the * pipeline completes. * * Side effects: * Processes and pipes are created. * *--------------------------------------------------------------------------- */ int Blt_CreatePipeline( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ int objc, /* Number of entries in objv. */ Tcl_Obj *const *objv, /* Array of strings describing commands in * pipeline plus I/O redirection with <, * <<, >, etc. Objv[objc] must be NULL. */ ProcessId **pidsPtr, /* *pidsPtr gets filled in with * address of array of pids for processes * in pipeline (first pid is first process * in pipeline). */ int *inPipePtr, /* If non-NULL, input to the pipeline comes * from a pipe (unless overridden by * redirection in the command). The file * id with which to write to this pipe is * stored at *inPipePtr. NULL means command * specified its own input source. */ int *outPipePtr, /* If non-NULL, output to the pipeline goes * to a pipe, unless overriden by redirection * in the command. The file id with which to * read frome this pipe is stored at * *outPipePtr. NULL means command specified * its own output sink. */ int *errPipePtr) /* If non-NULL, all stderr output from the * pipeline will go to a temporary file * created here, and a descriptor to read * the file will be left at *errPipePtr. * The file will be removed already, so * closing this descriptor will be the end * of the file. If this is NULL, then * all stderr output goes to our stderr. * If the pipeline specifies redirection * then the file will still be created * but it will never get any data. */ { ProcessId *pids = NULL; /* Points to malloc-ed array holding all * the handles of child processes. */ int nPids; /* Actual number of processes that exist * at *pids right now. */ int cmdCount; /* Count of number of distinct commands * found in objc/argv. */ char *inputLiteral = NULL; /* If non-null, then this points to a * string containing input data (specified * via <<) to be piped to the first process * in the pipeline. */ HANDLE hStdin; /* If != -1, gives file to use as input for * first process in pipeline (specified via < * or <@). */ BOOL closeStdin; /* If non-zero, then hStdin should be * closed when cleaning up. */ HANDLE hStdout; /* Writable file for output from last command * in pipeline (could be file or pipe). NULL * means use stdout. */ BOOL closeStdout; /* If non-zero, then hStdout should be * closed when cleaning up. */ HANDLE hStderr; /* Writable file for error output from all * commands in pipeline. NULL means use * stderr. */ BOOL closeStderr; /* If non-zero, then hStderr should be * closed when cleaning up. */ HANDLE hInPipe, hOutPipe, hErrPipe; char *p; int skip, lastBar, lastArg, i, j, flags; int pid; BOOL atOK, errorToOutput; Tcl_DString dString; HANDLE hPipe; HANDLE thisInput, thisOutput, thisError; char **argv; if (inPipePtr != NULL) { *inPipePtr = -1; } if (outPipePtr != NULL) { *outPipePtr = -1; } if (errPipePtr != NULL) { *errPipePtr = -1; } Tcl_DStringInit(&dString); hStdin = hStdout = hStderr = INVALID_HANDLE_VALUE; hPipe = thisInput = thisOutput = INVALID_HANDLE_VALUE; hInPipe = hOutPipe = hErrPipe = INVALID_HANDLE_VALUE; closeStdin = closeStdout = closeStderr = FALSE; nPids = 0; /* * First, scan through all the arguments to figure out the structure * of the pipeline. Process all of the input and output redirection * arguments and remove them from the argument list in the pipeline. * Count the number of distinct processes (it's the number of "|" * arguments plus one) but don't remove the "|" arguments because * they'll be used in the second pass to seperate the individual * child processes. Cannot start the child processes in this pass * because the redirection symbols may appear anywhere in the * command line -- e.g., the '<' that specifies the input to the * entire pipe may appear at the very end of the argument list. */ /* Convert all the Tcl_Objs to strings. */ argv = Blt_AssertMalloc((objc + 1) * sizeof(char *)); for (i = 0; i < objc; i++) { argv[i] = Tcl_GetString(objv[i]); } argv[i] = NULL; lastBar = -1; cmdCount = 1; for (i = 0; i < objc; i++) { skip = 0; p = argv[i]; switch (*p++) { case '|': if (*p == '&') { p++; } if (*p == '\0') { if ((i == (lastBar + 1)) || (i == (objc - 1))) { Tcl_AppendResult(interp, "illegal use of | or |& in command", (char *)NULL); goto error; } } lastBar = i; cmdCount++; break; case '<': if (closeStdin) { closeStdin = FALSE; CloseHandle(hStdin); } if (*p == '<') { hStdin = INVALID_HANDLE_VALUE; inputLiteral = p + 1; skip = 1; if (*inputLiteral == '\0') { inputLiteral = argv[i + 1]; if (inputLiteral == NULL) { Tcl_AppendResult(interp, "can't specify \"", argv[i], "\" as last word in command", (char *)NULL); goto error; } skip = 2; } } else { inputLiteral = NULL; hStdin = FileForRedirect(interp, p, TRUE, argv[i], argv[i + 1], GENERIC_READ, OPEN_EXISTING, &skip, &closeStdin); if (hStdin == INVALID_HANDLE_VALUE) { goto error; } } break; case '>': atOK = 1; flags = CREATE_ALWAYS; errorToOutput = FALSE; if (*p == '>') { p++; atOK = 0; flags = OPEN_ALWAYS; } if (*p == '&') { if (closeStderr) { closeStderr = FALSE; CloseHandle(hStderr); } errorToOutput = TRUE; p++; } if (closeStdout) { closeStdout = FALSE; CloseHandle(hStdout); } hStdout = FileForRedirect(interp, p, atOK, argv[i], argv[i + 1], GENERIC_WRITE, flags, &skip, &closeStdout); if (hStdout == INVALID_HANDLE_VALUE) { goto error; } if (errorToOutput) { closeStderr = FALSE; hStderr = hStdout; } break; case '2': if (*p != '>') { break; } p++; atOK = TRUE; flags = CREATE_ALWAYS; if (*p == '>') { p++; atOK = FALSE; flags = OPEN_ALWAYS; } if (closeStderr) { closeStderr = FALSE; CloseHandle(hStderr); } hStderr = FileForRedirect(interp, p, atOK, argv[i], argv[i + 1], GENERIC_WRITE, flags, &skip, &closeStderr); if (hStderr == INVALID_HANDLE_VALUE) { goto error; } break; } if (skip != 0) { for (j = i + skip; j < objc; j++) { argv[j - skip] = argv[j]; } objc -= skip; i -= 1; } } if (hStdin == INVALID_HANDLE_VALUE) { if (inputLiteral != NULL) { /* * The input for the first process is immediate data coming from * Tcl. Create a temporary file for it and put the data into the * file. */ hStdin = CreateTempFile(inputLiteral); if (hStdin == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't create input file for command: ", Tcl_PosixError(interp), (char *)NULL); goto error; } closeStdin = TRUE; } else if (inPipePtr != NULL) { /* * The input for the first process in the pipeline is to * come from a pipe that can be written from by the caller. */ if (!CreatePipe(&hStdin, &hInPipe, NULL, 0)) { Tcl_AppendResult(interp, "can't create input pipe for command: ", Tcl_PosixError(interp), (char *)NULL); goto error; } closeStdin = TRUE; } else { /* * The input for the first process comes from stdin. */ } } if (hStdout == INVALID_HANDLE_VALUE) { if (outPipePtr != NULL) { /* * Output from the last process in the pipeline is to go to a * pipe that can be read by the caller. */ if (!CreatePipe(&hOutPipe, &hStdout, NULL, 0)) { Tcl_AppendResult(interp, "can't create output pipe for command: ", Tcl_PosixError(interp), (char *)NULL); goto error; } closeStdout = TRUE; } else { /* * The output for the last process goes to stdout. */ } } if (hStderr == INVALID_HANDLE_VALUE) { if (errPipePtr != NULL) { /* * Stderr from the last process in the pipeline is to go to a * pipe that can be read by the caller. */ if (CreatePipe(&hErrPipe, &hStderr, NULL, 0) == 0) { Tcl_AppendResult(interp, "can't create error pipe for command: ", Tcl_PosixError(interp), (char *)NULL); goto error; } closeStderr = TRUE; } else { /* * Errors from the pipeline go to stderr. */ } } /* * Scan through the objc array, creating a process for each * group of arguments between the "|" characters. */ Tcl_ReapDetachedProcs(); pids = Blt_AssertMalloc((unsigned)((cmdCount + 1) * sizeof(ProcessId))); thisInput = hStdin; if (objc == 0) { Tcl_AppendResult(interp, "invalid null command", (char *)NULL); goto error; } lastArg = 0; /* Suppress compiler warning */ for (i = 0; i < objc; i = lastArg + 1) { BOOL joinThisError; HANDLE hProcess; DWORD dw_pid; /* Convert the program name into native form. */ argv[i] = Tcl_TranslateFileName(interp, argv[i], &dString); if (argv[i] == NULL) { goto error; } /* Find the end of the current segment of the pipeline. */ joinThisError = FALSE; for (lastArg = i; lastArg < objc; lastArg++) { if (argv[lastArg][0] == '|') { if (argv[lastArg][1] == '\0') { break; } if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) { joinThisError = TRUE; break; } } } argv[lastArg] = NULL; if ((lastArg - i) == 0) { Tcl_AppendResult(interp, "invalid null command", (char *)NULL); goto error; } /* * If this is the last segment, use the specified output handle. * Otherwise create an intermediate pipe. hPipe will become the * input for the next segment of the pipe. */ if (lastArg == objc) { thisOutput = hStdout; } else { if (CreatePipe(&hPipe, &thisOutput, NULL, 0) == 0) { Tcl_AppendResult(interp, "can't create pipe: ", Tcl_PosixError(interp), (char *)NULL); goto error; } } if (joinThisError) { thisError = thisOutput; } else { thisError = hStderr; } if (StartProcess(interp, lastArg - i, argv + i, thisInput, thisOutput, thisError, &hProcess, &dw_pid) != TCL_OK) { goto error; } pid = (int)dw_pid; Tcl_DStringFree(&dString); pids[nPids].hProcess = hProcess; pids[nPids].pid = pid; nPids++; /* * Close off our copies of file descriptors that were set up for * this child, then set up the input for the next child. */ if ((thisInput != INVALID_HANDLE_VALUE) && (thisInput != hStdin)) { CloseHandle(thisInput); } thisInput = hPipe; hPipe = INVALID_HANDLE_VALUE; if ((thisOutput != INVALID_HANDLE_VALUE) && (thisOutput != hStdout)) { CloseHandle(thisOutput); } thisOutput = INVALID_HANDLE_VALUE; } *pidsPtr = pids; if (inPipePtr != NULL) { *inPipePtr = (int)hInPipe; } if (outPipePtr != NULL) { *outPipePtr = (int)hOutPipe; } if (errPipePtr != NULL) { *errPipePtr = (int)hErrPipe; } /* * All done. Cleanup open files lying around and then return. */ cleanup: Tcl_DStringFree(&dString); if (closeStdin) { CloseHandle(hStdin); } if (closeStdout) { CloseHandle(hStdout); } if (closeStderr) { CloseHandle(hStderr); } if (argv != NULL) { Blt_Free(argv); } return nPids; /* * An error occurred. There could have been extra files open, such * as pipes between children. Clean them all up. Detach any child * processes that have been created. */ error: if (hPipe != INVALID_HANDLE_VALUE) { CloseHandle(hPipe); } if ((thisOutput != INVALID_HANDLE_VALUE) && (thisOutput != hStdout)) { CloseHandle(thisOutput); } if ((thisInput != INVALID_HANDLE_VALUE) && (thisInput != hStdin)) { CloseHandle(thisInput); } if (hInPipe != INVALID_HANDLE_VALUE) { CloseHandle(hInPipe); } if (hOutPipe != INVALID_HANDLE_VALUE) { CloseHandle(hOutPipe); } if (hErrPipe != INVALID_HANDLE_VALUE) { CloseHandle(hErrPipe); } if (pids != NULL) { for (i = 0; i < nPids; i++) { if (pids[i].hProcess != INVALID_HANDLE_VALUE) { /* It's Ok to use Tcl_DetachPids, since for WIN32 it's really * using process handles, not process ids. */ Tcl_DetachPids(1, (Tcl_Pid *)&pids[i].pid); } } Blt_Free(pids); } nPids = -1; goto cleanup; } /* *--------------------------------------------------------------------------- * * Blt_CreateFileHandler -- * * Limited emulation Tcl_CreateFileHandler for Win32. Works * with pipes. Don't know if anything else will (such as sockets). * * Results: * None. * * Side Effects: * Registers procedure and data to call back when data * is available on the pipe. * *--------------------------------------------------------------------------- */ void Blt_CreateFileHandler( int fd, /* Descriptor or handle of file */ int flags, /* TCL_READABLE or TCL_WRITABLE */ Tcl_FileProc *proc, ClientData clientData) { PipeHandler *pipePtr; if (!initialized) { PipeInit(); } if ((flags != TCL_READABLE) && (flags != TCL_WRITABLE)) { return; /* Only one of the flags can be set. */ } pipePtr = CreatePipeHandler((HANDLE) fd, flags); pipePtr->proc = proc; pipePtr->clientData = clientData; /* Add the handler to the list of managed pipes. */ EnterCriticalSection(&pipeCriticalSection); Blt_Chain_Append(&pipeChain, pipePtr); LeaveCriticalSection(&pipeCriticalSection); } /* *--------------------------------------------------------------------------- * * Blt_DeleteFileHandler -- * * Win32 emulation Tcl_DeleteFileHandler. Cleans up resources * used. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_DeleteFileHandler(int fd) /* Descriptor or handle of file */ { PipeHandler *pipePtr; Blt_ChainLink link; HANDLE hPipe; if (!initialized) { PipeInit(); } #if KILL_DEBUG PurifyPrintf("Blt_DeleteFileHandler(%d)\n", fd); #endif hPipe = (HANDLE) fd; EnterCriticalSection(&pipeCriticalSection); for (link = Blt_Chain_FirstLink(&pipeChain); link != NULL; link = Blt_Chain_NextLink(link)) { pipePtr = Blt_Chain_GetValue(link); if ((pipePtr->hPipe == hPipe) && !(pipePtr->flags & PIPE_DELETED)) { Blt_Chain_DeleteLink(&pipeChain, link); DeletePipeHandler(pipePtr); break; } } LeaveCriticalSection(&pipeCriticalSection); #if KILL_DEBUG PurifyPrintf("Blt_DeleteFileHandler: done\n"); #endif } /* *--------------------------------------------------------------------------- * * Blt_AsyncRead -- * * Reads input from the pipe into the given buffer. * * Results: * Returns the number of bytes read. * *--------------------------------------------------------------------------- */ int Blt_AsyncRead( int f, char *buffer, unsigned int size) { PipeHandler *pipePtr; unsigned int count; int nBytes; #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead(f=%d)\n", f); #endif pipePtr = GetPipeHandler((HANDLE) f); if ((pipePtr == NULL) || (pipePtr->flags & PIPE_DELETED)) { errno = EBADF; #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: bad file\n"); #endif return -1; } if (!PeekOnPipe(pipePtr, &nBytes)) { #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: pipe is drained (nBytes=%d).\n", nBytes); #endif return -1; /* No data available. */ } /* * nBytes is 0 EOF found. * -1 Error occured. * 1+ Number of bytes available. */ if (nBytes == -1) { #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: Error\n"); #endif return -1; } if (nBytes == 0) { #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: EOF\n"); #endif return 0; } count = pipePtr->end - pipePtr->start; #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: nBytes is %d, %d\n", nBytes, count); #endif assert(count == (unsigned int)nBytes); if (size > count) { size = count; /* Reset request to what's available. */ } memcpy(buffer, pipePtr->buffer + pipePtr->start, size); pipePtr->start += size; if (pipePtr->start == pipePtr->end) { #if ASYNC_DEBUG PurifyPrintf("Blt_AsyncRead: signaling idle\n"); #endif ResetEvent(pipePtr->readyEvent); SetEvent(pipePtr->idleEvent); } return size; } /* *--------------------------------------------------------------------------- * * Blt_AsyncWrite -- * * Writes output to the pipe from the given buffer. * * Results: * Returns the number of bytes written. * *--------------------------------------------------------------------------- */ int Blt_AsyncWrite( int f, const char *buffer, unsigned int size) { PipeHandler *pipePtr; pipePtr = GetPipeHandler((HANDLE) f); if ((pipePtr == NULL) || (pipePtr->flags & PIPE_DELETED)) { errno = EBADF; return -1; } if (WaitForSingleObject(pipePtr->readyEvent, 0) == WAIT_TIMEOUT) { /* * Writer thread is currently blocked waiting for a write to * complete. */ errno = EAGAIN; return -1; } /* Check for a background error on the last write. */ if (pipePtr->lastError) { TclWinConvertError(pipePtr->lastError); pipePtr->lastError = 0; return -1; } /* Reallocate the buffer to be large enough to hold the data. */ if (size > pipePtr->size) { char *ptr; ptr = Blt_AssertMalloc(size); Blt_Free(pipePtr->buffer); pipePtr->buffer = ptr; } memcpy(pipePtr->buffer, buffer, size); pipePtr->end = pipePtr->size = size; ResetEvent(pipePtr->readyEvent); SetEvent(pipePtr->idleEvent); return size; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPainter.h������������������������������������������������������������������0000644�0001750�0001750�00000006063�11462120062�015307� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPainter.h -- * * This module implements generic image painting procedures for * the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the * Tk library distrubution. The photo image type was designed and * implemented by Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #ifndef _BLT_PAINTER_H #define _BLT_PAINTER_H typedef struct _Blt_Painter *Blt_Painter; BLT_EXTERN void Blt_FreePainter(Blt_Painter painter); BLT_EXTERN Blt_Painter Blt_GetPainter(Tk_Window tkwin, float gamma); BLT_EXTERN Blt_Painter Blt_GetPainterFromDrawable(Display *display, Drawable drawable, float gamma); BLT_EXTERN GC Blt_PainterGC(Blt_Painter painter); BLT_EXTERN int Blt_PainterDepth(Blt_Painter painter); BLT_EXTERN Visual *Blt_PainterVisual(Blt_Painter painter); BLT_EXTERN Colormap Blt_PainterColormap(Blt_Painter painter); BLT_EXTERN int Blt_PaintPicture(Blt_Painter painter, Drawable drawable, Blt_Picture src, int srcX, int srcY, int width, int height, int destX, int destY, unsigned int flags); BLT_EXTERN int Blt_PaintPictureWithBlend(Blt_Painter painter, Drawable drawable, Blt_Picture src, int srcX, int srcY, int width, int height, int destX, int destY, unsigned int flags, double falpha); BLT_EXTERN Blt_Picture Blt_PaintCheckbox(int width, int height, XColor *fillColor, XColor *outlineColor, XColor *checkColor, int isOn); BLT_EXTERN Blt_Picture Blt_PaintRadioButton(int width, int height, XColor *fillColor, XColor *outlineColor, XColor *checkColor, int isOn); BLT_EXTERN Blt_Picture Blt_PaintDelete(int width, int height, XColor *bgColor, XColor *fgColor); BLT_EXTERN void Blt_PaintRectangle(Blt_Picture picture, int x, int y, int w, int h, int dx, int dy, Blt_Pixel *colorPtr); BLT_EXTERN void Blt_PaintPolygon(Blt_Picture picture, int n, Point2f *vertices, Blt_Pixel *colorPtr); #endif /* _BLT_PAINTER_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltHash.h.in������������������������������������������������������������������0000644�0001750�0001750�00000015754�11462120062�015204� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltHash.h -- * * Copyright 2000-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The hash table data structures are based upon the ones in the public header * file tcl.h in the Tcl library distribution. * * Copyright (c) 1991-1993 The Regents of the University of California. * * Copyright (c) 1994 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef BLT_HASH_H # define BLT_HASH_H 1 # ifndef BLT_INT_H # ifndef SIZEOF_LONG # define SIZEOF_LONG @SIZEOF_LONG@ # endif # ifndef SIZEOF_LONG_LONG # define SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@ # endif # ifndef SIZEOF_INT # define SIZEOF_INT @SIZEOF_INT@ # endif # ifndef SIZEOF_VOID_P # define SIZEOF_VOID_P @SIZEOF_VOID_P@ # endif #endif /* !BLT_INT_H */ #ifdef HAVE_INTTYPES_H # include <inttypes.h> #else # if (SIZEOF_VOID_P == 8) # if (SIZEOF_LONG == 8) typedef signed long int64_t; typedef unsigned long uint64_t; # else typedef signed long long int64_t; typedef unsigned long long uint64_t; # endif /* SIZEOF_LONG == 8 */ # else # ifndef __CYGWIN__ typedef signed int int32_t; typedef unsigned int uint32_t; # endif /* __CYGWIN__ */ # endif /* SIZEOF_VOID_P == 8 */ #endif /* HAVE_INTTYPES_H */ #if (SIZEOF_VOID_P == 8) typedef uint64_t Blt_Hash; #else typedef uint32_t Blt_Hash; #endif /* SIZEOF_VOID_P == 8 */ #include "bltPool.h" /* * Acceptable key types for hash tables: */ #ifndef BLT_STRING_KEYS # define BLT_STRING_KEYS 0L #endif #ifndef BLT_ONE_WORD_KEYS # define BLT_ONE_WORD_KEYS ((size_t)-1L) #endif /* * Forward declaration of Blt_HashTable. Needed by some C++ compilers to * prevent errors when the forward reference to Blt_HashTable is encountered * in the Blt_HashEntry structure. */ #ifdef __cplusplus struct Blt_HashTable; #endif typedef union { /* Key has one of these forms: */ void *oneWordValue; /* One-word value for key. */ unsigned long words[1]; /* Multiple integer words for key. The actual * size will be as large as necessary for this * table's keys. */ char string[4]; /* String for key. The actual size will be as * large as needed to hold the key. */ } Blt_HashKey; /* * Structure definition for an entry in a hash table. No one outside BLT * should access any of these fields directly; use the macros defined below. */ typedef struct Blt_HashEntry { struct Blt_HashEntry *nextPtr; /* Pointer to next entry in this hash * bucket, or NULL for end of chain.*/ Blt_Hash hval; ClientData clientData; /* Application stores something here with * Blt_SetHashValue. */ Blt_HashKey key; /* MUST BE LAST FIELD IN RECORD!! */ } Blt_HashEntry; /* * Structure definition for a hash table. Must be in blt.h so clients can * allocate space for these structures, but clients should never access any * fields in this structure. */ #define BLT_SMALL_HASH_TABLE 4 typedef struct Blt_HashTable { Blt_HashEntry **buckets; /* Pointer to bucket array. Each element * points to first entry in bucket's hash * chain, or NULL. */ Blt_HashEntry *staticBuckets[BLT_SMALL_HASH_TABLE]; /* Bucket array used for small tables (to * avoid mallocs and frees). */ size_t numBuckets; /* Total number of buckets allocated at * buckets. */ size_t numEntries; /* Total # of entries present in table. */ size_t rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ Blt_Hash mask; /* Mask value used in hashing function. */ unsigned int downShift; /* Shift count used in hashing function. * Designed to use high- order bits of * randomized keys. */ size_t keyType; /* Type of keys used in this table. It's * either BLT_STRING_KEYS, BLT_ONE_WORD_KEYS, * or an integer giving the number of ints * that is the size of the key. */ Blt_HashEntry *(*findProc) _ANSI_ARGS_((struct Blt_HashTable *tablePtr, CONST void *key)); Blt_HashEntry *(*createProc) _ANSI_ARGS_((struct Blt_HashTable *tablePtr, CONST void *key, int *newPtr)); Blt_Pool hPool; /* Pointer to the pool allocator used for * entries in this hash table. If NULL, the * standard Tcl_Alloc, Tcl_Free routines will * be used instead. */ } Blt_HashTable; /* * Structure definition for information used to keep track of searches through * hash tables: */ typedef struct { Blt_HashTable *tablePtr; /* Table being searched. */ unsigned long nextIndex; /* Index of next bucket to be enumerated after * present one. */ Blt_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the current * bucket. */ } Blt_HashSearch; /* * Macros for clients to use to access fields of hash entries: */ #define Blt_GetHashValue(h) ((h)->clientData) #define Blt_SetHashValue(h, value) ((h)->clientData = (ClientData)(value)) #define Blt_GetHashKey(tablePtr, h) \ ((void *) (((tablePtr)->keyType == BLT_ONE_WORD_KEYS) ? \ (void *)(h)->key.oneWordValue : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures for * hash tables: */ #define Blt_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Blt_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) BLT_EXTERN void Blt_InitHashTable _ANSI_ARGS_((Blt_HashTable *tablePtr, size_t keyType)); BLT_EXTERN void Blt_InitHashTableWithPool _ANSI_ARGS_((Blt_HashTable *tablePtr, size_t keyType)); BLT_EXTERN void Blt_DeleteHashTable _ANSI_ARGS_((Blt_HashTable *tablePtr)); BLT_EXTERN void Blt_DeleteHashEntry _ANSI_ARGS_((Blt_HashTable *tablePtr, Blt_HashEntry *entryPtr)); BLT_EXTERN Blt_HashEntry *Blt_FirstHashEntry _ANSI_ARGS_(( Blt_HashTable *tablePtr, Blt_HashSearch *searchPtr)); BLT_EXTERN Blt_HashEntry *Blt_NextHashEntry _ANSI_ARGS_(( Blt_HashSearch *srchPtr)); BLT_EXTERN const char *Blt_HashStats _ANSI_ARGS_((Blt_HashTable *tablePtr)); #endif /* BLT_HASH_H */ ��������������������./saods9/blt3.0.1/src/bltText.c���������������������������������������������������������������������0000644�0001750�0001750�00000160000�11462120063�014615� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltText.c -- * * This module implements multi-line, rotate-able text for the BLT toolkit. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include <X11/Xutil.h> #include "tkIntBorder.h" #include "tkDisplay.h" #include "bltImage.h" #include "bltBitmap.h" #include "bltFont.h" #include "bltText.h" #include "bltBgStyle.h" #define WINDEBUG 0 static Blt_HashTable bitmapGCTable; static int initialized; GC Blt_GetBitmapGC(Tk_Window tkwin) { int isNew; GC gc; Display *display; Blt_HashEntry *hPtr; if (!initialized) { Blt_InitHashTable(&bitmapGCTable, BLT_ONE_WORD_KEYS); initialized = TRUE; } display = Tk_Display(tkwin); hPtr = Blt_CreateHashEntry(&bitmapGCTable, (char *)display, &isNew); if (isNew) { Pixmap bitmap; XGCValues gcValues; unsigned long gcMask; Window root; root = Tk_RootWindow(tkwin); bitmap = Tk_GetPixmap(display, root, 1, 1, 1); gcValues.foreground = gcValues.background = 0; gcMask = (GCForeground | GCBackground); gc = Blt_GetPrivateGCFromDrawable(display, bitmap, gcMask, &gcValues); Tk_FreePixmap(display, bitmap); Blt_SetHashValue(hPtr, gc); } else { gc = (GC)Blt_GetHashValue(hPtr); } return gc; } /* *--------------------------------------------------------------------------- * * Blt_GetTextExtents -- * * Get the extents of a possibly multiple-lined text string. * * Results: * Returns via *widthPtr* and *heightPtr* the dimensions of the text * string. * *--------------------------------------------------------------------------- */ void Blt_GetTextExtents( Blt_Font font, int leader, const char *text, /* Text string to be measured. */ int textLen, /* Length of the text. If -1, indicates that * text is an ASCIZ string that the length * should be computed with strlen. */ unsigned int *widthPtr, unsigned int *heightPtr) { unsigned int lineHeight; if (text == NULL) { return; /* NULL string? */ } { Blt_FontMetrics fm; Blt_GetFontMetrics(font, &fm); lineHeight = fm.linespace; } if (textLen < 0) { textLen = strlen(text); } { unsigned int lineLen; /* # of characters on each line */ const char *p, *pend; const char *line; unsigned int maxWidth, maxHeight; maxWidth = maxHeight = 0; lineLen = 0; for (p = line = text, pend = text + textLen; p < pend; p++) { if (*p == '\n') { if (lineLen > 0) { unsigned int lineWidth; lineWidth = Blt_TextWidth(font, line, lineLen); if (lineWidth > maxWidth) { maxWidth = lineWidth; } } maxHeight += lineHeight; line = p + 1; /* Point to the start of the next line. */ lineLen = 0; /* Reset counter to indicate the start of a * new line. */ continue; } lineLen++; } if ((lineLen > 0) && (*(p - 1) != '\n')) { unsigned int lineWidth; maxHeight += lineHeight; lineWidth = Blt_TextWidth(font, line, lineLen); if (lineWidth > maxWidth) { maxWidth = lineWidth; } } *widthPtr = maxWidth; *heightPtr = maxHeight; } } /* *--------------------------------------------------------------------------- * * Blt_Ts_GetExtents -- * * Get the extents of a possibly multiple-lined text string. * * Results: * Returns via *widthPtr* and *heightPtr* the dimensions of * the text string. * *--------------------------------------------------------------------------- */ void Blt_Ts_GetExtents(TextStyle *tsPtr, const char *text, unsigned int *widthPtr, unsigned int *heightPtr) { if (text == NULL) { *widthPtr = *heightPtr = 0; } else { unsigned int w, h; Blt_GetTextExtents(tsPtr->font, tsPtr->leader, text, -1, &w, &h); *widthPtr = w + PADDING(tsPtr->xPad); *heightPtr = h + PADDING(tsPtr->yPad); } } /* *--------------------------------------------------------------------------- * * Blt_GetBoundingBox * * Computes the dimensions of the bounding box surrounding a rectangle * rotated about its center. If pointArr isn't NULL, the coordinates of * the rotated rectangle are also returned. * * The dimensions are determined by rotating the rectangle, and doubling * the maximum x-coordinate and y-coordinate. * * w = 2 * maxX, h = 2 * maxY * * Since the rectangle is centered at 0,0, the coordinates of the * bounding box are (-w/2,-h/2 w/2,-h/2, w/2,h/2 -w/2,h/2). * * 0 ------- 1 * | | * | x | * | | * 3 ------- 2 * * Results: * The width and height of the bounding box containing the rotated * rectangle are returned. * *--------------------------------------------------------------------------- */ void Blt_GetBoundingBox( int width, int height, /* Unrotated region */ float angle, /* Rotation of box */ double *rotWidthPtr, double *rotHeightPtr, /* (out) Bounding box region */ Point2d *bbox) /* (out) Points of the rotated box */ { int i; double sinTheta, cosTheta; double radians; double xMax, yMax; double x, y; Point2d corner[4]; angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int ll, ur, ul, lr; double rotWidth, rotHeight; int quadrant; /* Handle right-angle rotations specially. */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ ul = 3, ur = 0, lr = 1, ll = 2; rotWidth = (double)height; rotHeight = (double)width; break; case ROTATE_90: /* 90 degrees */ ul = 1, ur = 2, lr = 3, ll = 0; rotWidth = (double)height; rotHeight = (double)width; break; case ROTATE_180: /* 180 degrees */ ul = 2, ur = 3, lr = 0, ll = 1; rotWidth = (double)width; rotHeight = (double)height; break; default: case ROTATE_0: /* 0 degrees */ ul = 0, ur = 1, lr = 2, ll = 3; rotWidth = (double)width; rotHeight = (double)height; break; } if (bbox != NULL) { x = rotWidth * 0.5; y = rotHeight * 0.5; bbox[ll].x = bbox[ul].x = -x; bbox[ur].y = bbox[ul].y = -y; bbox[lr].x = bbox[ur].x = x; bbox[ll].y = bbox[lr].y = y; } *rotWidthPtr = rotWidth; *rotHeightPtr = rotHeight; return; } /* Set the four corners of the rectangle whose center is the origin. */ corner[1].x = corner[2].x = (double)width * 0.5; corner[0].x = corner[3].x = -corner[1].x; corner[2].y = corner[3].y = (double)height * 0.5; corner[0].y = corner[1].y = -corner[2].y; radians = (-angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); xMax = yMax = 0.0; /* Rotate the four corners and find the maximum X and Y coordinates */ for (i = 0; i < 4; i++) { x = (corner[i].x * cosTheta) - (corner[i].y * sinTheta); y = (corner[i].x * sinTheta) + (corner[i].y * cosTheta); if (x > xMax) { xMax = x; } if (y > yMax) { yMax = y; } if (bbox != NULL) { bbox[i].x = x; bbox[i].y = y; } } /* * By symmetry, the width and height of the bounding box are twice the * maximum x and y coordinates. */ *rotWidthPtr = xMax + xMax; *rotHeightPtr = yMax + yMax; } /* *--------------------------------------------------------------------------- * * Blt_TranslateAnchor -- * * Translate the coordinates of a given bounding box based upon the * anchor specified. The anchor indicates where the given x-y position * is in relation to the bounding box. * * nw --- n --- ne * | | * w center e * | | * sw --- s --- se * * The coordinates returned are translated to the origin of the bounding * box (suitable for giving to XCopyArea, XCopyPlane, etc.) * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ void Blt_TranslateAnchor( int x, int y, /* Window coordinates of anchor */ int w, int h, /* Extents of the bounding box */ Tk_Anchor anchor, /* Direction of the anchor */ int *xPtr, int *yPtr) { switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y -= (h / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ y -= h; break; case TK_ANCHOR_N: /* Top center */ x -= (w / 2); break; case TK_ANCHOR_CENTER: /* Center */ x -= (w / 2); y -= (h / 2); break; case TK_ANCHOR_S: /* Bottom center */ x -= (w / 2); y -= h; break; case TK_ANCHOR_NE: /* Upper right corner */ x -= w; break; case TK_ANCHOR_E: /* Right center */ x -= w; y -= (h / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ x -= w; y -= h; break; } *xPtr = x; *yPtr = y; } /* *--------------------------------------------------------------------------- * * Blt_AnchorPoint -- * * Translates a position, using both the dimensions of the bounding box, * and the anchor direction, returning the coordinates of the upper-left * corner of the box. The anchor indicates where the given x-y position * is in relation to the bounding box. * * nw --- n --- ne * | | * w center e * | | * sw --- s --- se * * The coordinates returned are translated to the origin of the bounding * box (suitable for giving to XCopyArea, XCopyPlane, etc.) * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ Point2d Blt_AnchorPoint( double x, double y, /* Coordinates of anchor. */ double w, double h, /* Extents of the bounding box */ Tk_Anchor anchor) /* Direction of the anchor */ { Point2d t; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y -= (h * 0.5); break; case TK_ANCHOR_SW: /* Lower left corner */ y -= h; break; case TK_ANCHOR_N: /* Top center */ x -= (w * 0.5); break; case TK_ANCHOR_CENTER: /* Center */ x -= (w * 0.5); y -= (h * 0.5); break; case TK_ANCHOR_S: /* Bottom center */ x -= (w * 0.5); y -= h; break; case TK_ANCHOR_NE: /* Upper right corner */ x -= w; break; case TK_ANCHOR_E: /* Right center */ x -= w; y -= (h * 0.5); break; case TK_ANCHOR_SE: /* Lower right corner */ x -= w; y -= h; break; } t.x = x; t.y = y; return t; } static INLINE int SizeOfUtfChar(const char *s) /* Buffer in which the UTF-8 representation of * the Tcl_UniChar is stored. Buffer must be * large enough to hold the UTF-8 character * (at most TCL_UTF_MAX bytes). */ { int byte; byte = *((unsigned char *)s); if (byte < 0xC0) { return 1; } else if ((byte < 0xE0) && ((s[1] & 0xC0) == 0x80)) { return 2; } else if ((byte < 0xF0) && ((s[1] & 0xC0) == 0x80) && ((s[2] & 0xC0) == 0x80)) { return 3; } return 1; } /* *--------------------------------------------------------------------------- * * Blt_MeasureText -- * * Draw a string of characters on the screen. Blt_DrawChars() * expands control characters that occur in the string to * \xNN sequences. * * Results: * None. * * Side effects: * Information gets drawn on the screen. * *--------------------------------------------------------------------------- */ int Blt_MeasureText( Blt_Font font, /* Font in which characters will be drawn; * must be the same as font used in GC. */ const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int textLen, /* # of bytes to draw in text string. */ int maxLength, int *countPtr) { int elWidth; const char *s, *send; int accum, count, threshold; int nBytes; if (maxLength < 0) { if (countPtr != NULL) { nBytes = textLen; } return Blt_TextWidth(font, text, textLen); } elWidth = Blt_TextWidth(font, "...", 3); threshold = maxLength - elWidth; if (threshold <= 0) { return 0; } #if !HAVE_UTF nBytes = 1; #endif /* !HAVE_UTF */ count = accum = 0; for (s = text, send = s + textLen; s < send; s += nBytes) { #if HAVE_UTF Tcl_UniChar ch; #endif /* HAVE_UTF */ int w; #if HAVE_UTF nBytes = Tcl_UtfToUniChar (s, &ch); #endif /* HAVE_UTF */ w = Blt_TextWidth(font, s, nBytes); if ((accum + w) > threshold) { if (countPtr != NULL) { *countPtr = count; } return accum + elWidth; } accum += w; count += nBytes; } if (countPtr != NULL) { *countPtr = count; } return accum; } /* *--------------------------------------------------------------------------- * * Blt_Ts_CreateLayout -- * * Get the extents of a possibly multiple-lined text string. * * Results: * Returns via *widthPtr* and *heightPtr* the dimensions of the text * string. * *--------------------------------------------------------------------------- */ TextLayout * Blt_Ts_CreateLayout(const char *text, int textLen, TextStyle *tsPtr) { TextFragment *fp; TextLayout *layoutPtr; Blt_FontMetrics fm; int count; /* Count # of characters on each line */ int lineHeight; size_t maxHeight, maxWidth; size_t nFrags; int width; /* Running dimensions of the text */ const char *p, *endp, *start; int i; size_t size; nFrags = 0; endp = text + ((textLen < 0) ? strlen(text) : textLen); for (p = text; p < endp; p++) { if (*p == '\n') { nFrags++; } } if ((p != text) && (*(p - 1) != '\n')) { nFrags++; } size = sizeof(TextLayout) + (sizeof(TextFragment) * (nFrags - 1)); layoutPtr = Blt_AssertCalloc(1, size); layoutPtr->nFrags = nFrags; nFrags = count = 0; width = maxWidth = 0; maxHeight = tsPtr->padTop; Blt_GetFontMetrics(tsPtr->font, &fm); lineHeight = fm.linespace + tsPtr->leader; fp = layoutPtr->fragments; for (p = start = text; p < endp; p++) { if (*p == '\n') { if (count > 0) { width = Blt_TextWidth(tsPtr->font, start, count); if (width > maxWidth) { maxWidth = width; } } else { width = 0; } fp->width = width; fp->count = count; fp->sy = fp->y = maxHeight + fm.ascent; fp->text = start; maxHeight += lineHeight; fp++; nFrags++; start = p + 1; /* Start the text on the next line */ count = 0; /* Reset to indicate the start of a new * line */ continue; } count++; } if (nFrags < layoutPtr->nFrags) { width = Blt_TextWidth(tsPtr->font, start, count); if (width > maxWidth) { maxWidth = width; } fp->width = width; fp->count = count; fp->sy = fp->y = maxHeight + fm.ascent; fp->text = start; maxHeight += lineHeight; nFrags++; } maxHeight += tsPtr->padBottom; maxWidth += PADDING(tsPtr->xPad); fp = layoutPtr->fragments; for (i = 0; i < nFrags; i++, fp++) { switch (tsPtr->justify) { default: case TK_JUSTIFY_LEFT: /* No offset for left justified text strings */ fp->x = fp->sx = tsPtr->padLeft; break; case TK_JUSTIFY_RIGHT: fp->x = fp->sx = (maxWidth - fp->width) - tsPtr->padRight; break; case TK_JUSTIFY_CENTER: fp->x = fp->sx = (maxWidth - fp->width) / 2; break; } } if (tsPtr->underline >= 0) { fp = layoutPtr->fragments; for (i = 0; i < nFrags; i++, fp++) { int first, last; first = fp->text - text; last = first + fp->count; if ((tsPtr->underline >= first) && (tsPtr->underline < last)) { layoutPtr->underlinePtr = fp; layoutPtr->underline = tsPtr->underline - first; break; } } } layoutPtr->width = maxWidth; layoutPtr->height = maxHeight - tsPtr->leader; return layoutPtr; } /* *--------------------------------------------------------------------------- * * Blt_DrawCharsWithEllipsis -- * * Draw a string of characters on the screen. Blt_DrawChars() * expands control characters that occur in the string to * \xNN sequences. * * Results: * None. * * Side effects: * Information gets drawn on the screen. * *--------------------------------------------------------------------------- */ void Blt_DrawCharsWithEllipsis( Tk_Window tkwin, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing characters. */ Blt_Font font, /* Font in which characters will be drawn; * must be the same as font used in GC. */ int depth, float angle, const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int textLen, /* # of bytes to draw in text string. */ int x, int y, /* Coordinates at which to place origin of * string when drawing. */ int maxLength) { int elWidth; const char *s, *send; Tcl_DString dString; int nBytes; int accum, threshold; #if HAVE_UTF Tcl_UniChar ch; #endif /* HAVE_UTF */ accum = 0; elWidth = Blt_TextWidth(font, "...", 3); if (maxLength < elWidth) { return; } threshold = maxLength - elWidth; Tcl_DStringInit(&dString); #if !HAVE_UTF nBytes = 1; #endif /* !HAVE_UTF */ for (s = text, send = s + textLen; s < send; s += nBytes) { #if HAVE_UTF nBytes = Tcl_UtfToUniChar (s, &ch); #endif /* HAVE_UTF */ accum += Blt_TextWidth(font, s, nBytes); if (accum > threshold) { break; } Tcl_DStringAppend(&dString, s, nBytes); } if (s < send) { Tcl_DStringAppend(&dString, "...", 3); } Blt_DrawChars(Tk_Display(tkwin), drawable, gc, font, depth, angle, Tcl_DStringValue(&dString), Tcl_DStringLength(&dString), x, y); Tcl_DStringFree(&dString); } void Blt_DrawLayout(Tk_Window tkwin, Drawable drawable, GC gc, Blt_Font font, int depth, float angle, int x, int y, TextLayout *layoutPtr, int maxLength) { TextFragment *fp, *fend; Blt_FontMetrics fm; Blt_GetFontMetrics(font, &fm); for (fp = layoutPtr->fragments, fend = fp + layoutPtr->nFrags; fp < fend; fp++) { int sx, sy; sx = x + fp->sx, sy = y + fp->sy; if ((maxLength > 0) && ((fp->width + fp->x) > maxLength)) { Blt_DrawCharsWithEllipsis(tkwin, drawable, gc, font, depth, angle, fp->text, fp->count, sx, sy, maxLength - fp->x); } else { Blt_DrawChars(Tk_Display(tkwin), drawable, gc, font, depth, angle, fp->text, fp->count, sx, sy); } } if (layoutPtr->underlinePtr != NULL) { fp = layoutPtr->underlinePtr; Blt_UnderlineChars(Tk_Display(tkwin), drawable, gc, font, fp->text, fp->count, x + fp->sx, y + fp->sy, layoutPtr->underline, layoutPtr->underline + 1, maxLength); } } #ifdef WIN32 /* *--------------------------------------------------------------------------- * * Blt_Ts_Bitmap -- * * Draw a bitmap, using the the given window coordinates as an anchor for * the text bounding box. * * Results: * Returns the bitmap representing the text string. * * Side Effects: * Bitmap is drawn using the given font and GC in the drawable at the * given coordinates, anchor, and rotation. * *--------------------------------------------------------------------------- */ Pixmap Blt_Ts_Bitmap( Tk_Window tkwin, TextLayout *layoutPtr, /* Text string to draw */ TextStyle *stylePtr, /* Text attributes: rotation, color, * font, linespacing, justification, * etc. */ int *bmWidthPtr, int *bmHeightPtr) /* Extents of rotated text string */ { Pixmap bitmap; Window root; GC gc; HDC hDC; TkWinDCState state; /* Create a temporary bitmap to contain the text string */ root = Tk_RootWindow(tkwin); bitmap = Tk_GetPixmap(Tk_Display(tkwin), root, layoutPtr->width, layoutPtr->height, 1); assert(bitmap != None); if (bitmap == None) { return None; /* Can't allocate pixmap. */ } gc = Blt_GetBitmapGC(tkwin); /* Clear the pixmap and draw the text string into it */ hDC = TkWinGetDrawableDC(Tk_Display(tkwin), bitmap, &state); PatBlt(hDC, 0, 0, layoutPtr->width, layoutPtr->height, WHITENESS); TkWinReleaseDrawableDC(bitmap, hDC, &state); XSetFont(Tk_Display(tkwin), gc, Blt_FontId(stylePtr->font)); XSetForeground(Tk_Display(tkwin), gc, 1); Blt_DrawLayout(tkwin, bitmap, gc, stylePtr->font, 1, 0.0f, 0, 0, layoutPtr, stylePtr->maxLength); /* * Under Win32, 1 is off and 0 is on. That's why we're inverting the * bitmap here. */ hDC = TkWinGetDrawableDC(Tk_Display(tkwin), bitmap, &state); PatBlt(hDC, 0, 0, layoutPtr->width, layoutPtr->height, DSTINVERT); TkWinReleaseDrawableDC(bitmap, hDC, &state); *bmWidthPtr = layoutPtr->width, *bmHeightPtr = layoutPtr->height; return bitmap; } #else /* *--------------------------------------------------------------------------- * * Blt_Ts_Bitmap -- * * Draw a bitmap, using the the given window coordinates as an anchor for * the text bounding box. * * Results: * Returns the bitmap representing the text string. * * Side Effects: * Bitmap is drawn using the given font and GC in the drawable at the * given coordinates, anchor, and rotation. * *--------------------------------------------------------------------------- */ Pixmap Blt_Ts_Bitmap( Tk_Window tkwin, TextLayout *layoutPtr, /* Text string to draw */ TextStyle *stylePtr, /* Text attributes: rotation, color, * font, linespacing, justification, * etc. */ int *bmWidthPtr, int *bmHeightPtr) /* Extents of rotated text string */ { Pixmap bitmap; GC gc; /* Create a bitmap big enough to contain the text. */ bitmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_RootWindow(tkwin), layoutPtr->width, layoutPtr->height, 1); assert(bitmap != None); if (bitmap == None) { return None; /* Can't allocate pixmap. */ } gc = Blt_GetBitmapGC(tkwin); /* Clear the bitmap. Background is 0. */ XSetForeground(Tk_Display(tkwin), gc, 0); XFillRectangle(Tk_Display(tkwin), bitmap, gc, 0, 0, layoutPtr->width, layoutPtr->height); /* Draw the text into the bitmap. Foreground is 1. */ XSetFont(Tk_Display(tkwin), gc, Blt_FontId(stylePtr->font)); XSetForeground(Tk_Display(tkwin), gc, 1); Blt_DrawLayout(tkwin, bitmap, gc, stylePtr->font, 1, 0.0f, 0, 0, layoutPtr, stylePtr->maxLength); *bmWidthPtr = layoutPtr->width, *bmHeightPtr = layoutPtr->height; return bitmap; } #endif /* WIN32 */ void Blt_Ts_SetDrawStyle( TextStyle *stylePtr, Blt_Font font, GC gc, XColor *normalColor, float angle, Tk_Anchor anchor, Tk_Justify justify, int leader) { stylePtr->xPad.side1 = stylePtr->xPad.side2 = 0; stylePtr->yPad.side1 = stylePtr->yPad.side2 = 0; stylePtr->state = 0; stylePtr->anchor = anchor; stylePtr->color = normalColor; stylePtr->font = font; stylePtr->gc = gc; stylePtr->justify = justify; stylePtr->leader = leader; stylePtr->angle = (float)angle; } static void DrawStandardLayout(Tk_Window tkwin, Drawable drawable, TextStyle *stylePtr, TextLayout *layoutPtr, int x, int y) { int w, h; /* * This is the easy case of no rotation. Simply draw the text * using the standard drawing routines. Handle offset printing * for engraved (disabled) text. */ w = layoutPtr->width; h = layoutPtr->height; if ((stylePtr->maxLength > 0) && (stylePtr->maxLength < w)) { w = stylePtr->maxLength; } Blt_TranslateAnchor(x, y, w, h, stylePtr->anchor, &x, &y); if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) { TkBorder *borderPtr = (TkBorder *) Blt_BackgroundBorder(stylePtr->bg); XColor *color1, *color2; color1 = borderPtr->lightColor, color2 = borderPtr->darkColor; if (stylePtr->state & STATE_EMPHASIS) { XColor *hold; hold = color1, color1 = color2, color2 = hold; } if (color1 != NULL) { XSetForeground(Tk_Display(tkwin), stylePtr->gc, color1->pixel); } Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), 0.0f, x+1, y+1, layoutPtr,stylePtr->maxLength); if (color2 != NULL) { XSetForeground(Tk_Display(tkwin), stylePtr->gc, color2->pixel); } Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), 0.0f, x, y, layoutPtr, stylePtr->maxLength); /* Reset the foreground color back to its original setting, so not to * invalidate the GC cache. */ XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel); return; /* Done */ } Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), 0.0f, x, y, layoutPtr, stylePtr->maxLength); } static void RotateStartingTextPositions(TextLayout *lPtr, int w, int h, float angle) { Point2d off1, off2; TextFragment *fp, *fend; double radians; double rw, rh; double sinTheta, cosTheta; Blt_GetBoundingBox(w, h, angle, &rw, &rh, (Point2d *)NULL); off1.x = (double)w * 0.5; off1.y = (double)h * 0.5; off2.x = rw * 0.5; off2.y = rh * 0.5; radians = (-angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); for (fp = lPtr->fragments, fend = fp + lPtr->nFrags; fp < fend; fp++) { Point2d p, q; p.x = fp->x - off1.x; p.y = fp->y - off1.y; q.x = (p.x * cosTheta) - (p.y * sinTheta); q.y = (p.x * sinTheta) + (p.y * cosTheta); q.x += off2.x; q.y += off2.y; fp->sx = ROUND(q.x); fp->sy = ROUND(q.y); } } void Blt_RotateStartingTextPositions(TextLayout *lPtr, float angle) { RotateStartingTextPositions(lPtr, lPtr->width, lPtr->height, angle); } int Blt_DrawTextWithRotatedFont(Tk_Window tkwin, Drawable drawable, float angle, TextStyle *stylePtr, TextLayout *layoutPtr, int x, int y) { double rw, rh; int w, h; w = layoutPtr->width; h = layoutPtr->height; if ((stylePtr->maxLength > 0) && (stylePtr->maxLength < w)) { w = stylePtr->maxLength; } RotateStartingTextPositions(layoutPtr, w, h, angle); Blt_GetBoundingBox(w, h, angle, &rw, &rh, (Point2d *)NULL); Blt_TranslateAnchor(x, y, (int)rw, (int)rh, stylePtr->anchor, &x, &y); if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) { TkBorder *borderPtr = (TkBorder *)Blt_BackgroundBorder(stylePtr->bg); XColor *color1, *color2; color1 = borderPtr->lightColor, color2 = borderPtr->darkColor; if (stylePtr->state & STATE_EMPHASIS) { XColor *hold; hold = color1, color1 = color2, color2 = hold; } if (color1 != NULL) { XSetForeground(Tk_Display(tkwin), stylePtr->gc, color1->pixel); Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); } if (color2 != NULL) { XSetForeground(Tk_Display(tkwin), stylePtr->gc, color2->pixel); Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); } XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel); return TRUE; } XSetForeground(Tk_Display(tkwin), stylePtr->gc, stylePtr->color->pixel); Blt_DrawLayout(tkwin, drawable, stylePtr->gc, stylePtr->font, Tk_Depth(tkwin), angle, x, y, layoutPtr, stylePtr->maxLength); return TRUE; } static void Blt_DrawTextWithRotatedBitmap( Tk_Window tkwin, Drawable drawable, float angle, TextStyle *stylePtr, /* Text attribute information */ TextLayout *layoutPtr, int x, int y) /* Window coordinates to draw text */ { int width, height; Display *display; Pixmap bitmap; display = Tk_Display(tkwin); /* * Rotate the text by writing the text into a bitmap and rotating the * bitmap. Set the clip mask and origin in the GC first. And make sure * we restore the GC because it may be shared. */ stylePtr->angle = angle; bitmap = Blt_Ts_Bitmap(tkwin, layoutPtr, stylePtr, &width, &height); if (bitmap == None) { return; } if ((bitmap != None) && (stylePtr->angle != 0.0)) { Pixmap rotated; rotated = Blt_RotateBitmap(tkwin, bitmap, width, height, stylePtr->angle, &width, &height); Tk_FreePixmap(display, bitmap); bitmap = rotated; } Blt_TranslateAnchor(x, y, width, height, stylePtr->anchor, &x, &y); XSetClipMask(display, stylePtr->gc, bitmap); if (stylePtr->state & (STATE_DISABLED | STATE_EMPHASIS)) { TkBorder *borderPtr = (TkBorder *) Blt_BackgroundBorder(stylePtr->bg); XColor *color1, *color2; color1 = borderPtr->lightColor, color2 = borderPtr->darkColor; if (stylePtr->state & STATE_EMPHASIS) { XColor *hold; hold = color1, color1 = color2, color2 = hold; } if (color1 != NULL) { XSetForeground(display, stylePtr->gc, color1->pixel); } XSetClipOrigin(display, stylePtr->gc, x + 1, y + 1); XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, height, x + 1, y + 1, 1); if (color2 != NULL) { XSetForeground(display, stylePtr->gc, color2->pixel); } XSetClipOrigin(display, stylePtr->gc, x, y); XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, height, x, y, 1); XSetForeground(display, stylePtr->gc, stylePtr->color->pixel); } else { XSetForeground(display, stylePtr->gc, stylePtr->color->pixel); XSetClipOrigin(display, stylePtr->gc, x, y); XCopyPlane(display, bitmap, drawable, stylePtr->gc, 0, 0, width, height, x, y, 1); } XSetClipMask(display, stylePtr->gc, None); Tk_FreePixmap(display, bitmap); } /* *--------------------------------------------------------------------------- * * Blt_Ts_DrawLayout -- * * Draw a text string, possibly rotated, using the the given window * coordinates as an anchor for the text bounding box. If the text is * not rotated, simply use the X text drawing routines. Otherwise, * generate a bitmap of the rotated text. * * Results: * Returns the x-coordinate to the right of the text. * * Side Effects: * Text string is drawn using the given font and GC at the the given * window coordinates. * * The Stipple, FillStyle, and TSOrigin fields of the GC are modified for * rotated text. This assumes the GC is private, *not* shared (via * Tk_GetGC) * *--------------------------------------------------------------------------- */ void Blt_Ts_DrawLayout( Tk_Window tkwin, Drawable drawable, TextLayout *layoutPtr, TextStyle *stylePtr, /* Text attribute information */ int x, int y) /* Window coordinates to draw text */ { float angle; if ((stylePtr->gc == NULL) || (stylePtr->flags & UPDATE_GC)) { Blt_Ts_ResetStyle(tkwin, stylePtr); } angle = (float)FMOD(stylePtr->angle, 360.0); if (angle < 0.0) { angle += 360.0; } if (angle == 0.0) { /* * This is the easy case of no rotation. Simply draw the text using * the standard drawing routines. Handle offset printing for engraved * (disabled) text. */ DrawStandardLayout(tkwin, drawable, stylePtr, layoutPtr, x, y); return; } if (Blt_CanRotateFont(stylePtr->font, angle)) { if (Blt_DrawTextWithRotatedFont(tkwin, drawable, angle, stylePtr, layoutPtr, x, y)) { return; /* Success. */ } } /*Fallthru*/ stylePtr->angle = (float)angle; Blt_DrawTextWithRotatedBitmap(tkwin, drawable, angle, stylePtr, layoutPtr, x, y); } void Blt_Ts_UnderlineLayout( Tk_Window tkwin, Drawable drawable, TextLayout *layoutPtr, TextStyle *stylePtr, /* Text attribute information */ int x, int y) /* Window coordinates to draw text */ { float angle; if ((stylePtr->gc == NULL) || (stylePtr->flags & UPDATE_GC)) { Blt_Ts_ResetStyle(tkwin, stylePtr); } angle = (float)FMOD(stylePtr->angle, 360.0); if (angle < 0.0) { angle += 360.0; } if (angle == 0.0) { TextFragment *fp, *fend; for (fp = layoutPtr->fragments, fend = fp + layoutPtr->nFrags; fp < fend; fp++) { int sx, sy; sx = x + fp->sx, sy = y + fp->sy; Blt_UnderlineChars(Tk_Display(tkwin), drawable, stylePtr->gc, stylePtr->font, fp->text, fp->count, sx, sy, 0, fp->count, stylePtr->maxLength); } } } /* *--------------------------------------------------------------------------- * * Blt_Ts_DrawLayout -- * * Draw a text string, possibly rotated, using the the given window * coordinates as an anchor for the text bounding box. If the text is * not rotated, simply use the X text drawing routines. Otherwise, * generate a bitmap of the rotated text. * * Results: * Returns the x-coordinate to the right of the text. * * Side Effects: * Text string is drawn using the given font and GC at the the given * window coordinates. * * The Stipple, FillStyle, and TSOrigin fields of the GC are modified for * rotated text. This assumes the GC is private, *not* shared (via * Tk_GetGC) * *--------------------------------------------------------------------------- */ void Blt_Ts_DrawText( Tk_Window tkwin, Drawable drawable, const char *text, int textLen, TextStyle *stylePtr, /* Text attribute information */ int x, int y) /* Window coordinates to draw text */ { TextLayout *layoutPtr; layoutPtr = Blt_Ts_CreateLayout(text, textLen, stylePtr); Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y); Blt_Free(layoutPtr); } void Blt_DrawText2( Tk_Window tkwin, Drawable drawable, const char *string, TextStyle *stylePtr, /* Text attribute information */ int x, int y, /* Window coordinates to draw text */ Dim2D *areaPtr) { TextLayout *layoutPtr; int width, height; float angle; if ((string == NULL) || (*string == '\0')) { return; /* Empty string, do nothing */ } layoutPtr = Blt_Ts_CreateLayout(string, -1, stylePtr); Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y); angle = FMOD(stylePtr->angle, 360.0); if (angle < 0.0) { angle += 360.0; } width = layoutPtr->width; height = layoutPtr->height; if (angle != 0.0) { double rotWidth, rotHeight; Blt_GetBoundingBox(width, height, angle, &rotWidth, &rotHeight, (Point2d *)NULL); width = ROUND(rotWidth); height = ROUND(rotHeight); } areaPtr->width = width; areaPtr->height = height; Blt_Free(layoutPtr); } void Blt_DrawText( Tk_Window tkwin, Drawable drawable, const char *string, TextStyle *stylePtr, /* Text attribute information */ int x, int y) /* Window coordinates to draw text */ { TextLayout *layoutPtr; if ((string == NULL) || (*string == '\0')) { return; /* Empty string, do nothing */ } layoutPtr = Blt_Ts_CreateLayout(string, -1, stylePtr); Blt_Ts_DrawLayout(tkwin, drawable, layoutPtr, stylePtr, x, y); Blt_Free(layoutPtr); } void Blt_Ts_ResetStyle(Tk_Window tkwin, TextStyle *stylePtr) { GC newGC; XGCValues gcValues; unsigned long gcMask; gcMask = GCFont; gcValues.font = Blt_FontId(stylePtr->font); if (stylePtr->color != NULL) { gcMask |= GCForeground; gcValues.foreground = stylePtr->color->pixel; } newGC = Tk_GetGC(tkwin, gcMask, &gcValues); if (stylePtr->gc != NULL) { Tk_FreeGC(Tk_Display(tkwin), stylePtr->gc); } stylePtr->gc = newGC; stylePtr->flags &= ~UPDATE_GC; } void Blt_Ts_FreeStyle(Display *display, TextStyle *stylePtr) { if (stylePtr->gc != NULL) { Tk_FreeGC(display, stylePtr->gc); } } /* * The following two structures are used to keep track of string * measurement information when using the text layout facilities. * * A LayoutChunk represents a contiguous range of text that can be measured * and displayed by low-level text calls. In general, chunks will be * delimited by newlines and tabs. Low-level, platform-specific things * like kerning and non-integer character widths may occur between the * characters in a single chunk, but not between characters in different * chunks. * * A TextLayout is a collection of LayoutChunks. It can be displayed with * respect to any origin. It is the implementation of the Tk_TextLayout * opaque token. */ typedef struct LayoutChunk { const char *start; /* Pointer to simple string to be displayed. * This is a pointer into the TkTextLayout's * string. */ int numBytes; /* The number of bytes in this chunk. */ int numChars; /* The number of characters in this chunk. */ int numDisplayChars; /* The number of characters to display when * this chunk is displayed. Can be less than * numChars if extra space characters were * absorbed by the end of the chunk. This * will be < 0 if this is a chunk that is * holding a tab or newline. */ int x, y; /* The origin of the first character in this * chunk with respect to the upper-left hand * corner of the TextLayout. */ int totalWidth; /* Width in pixels of this chunk. Used * when hit testing the invisible spaces at * the end of a chunk. */ int displayWidth; /* Width in pixels of the displayable * characters in this chunk. Can be less than * width if extra space characters were * absorbed by the end of the chunk. */ } LayoutChunk; typedef struct TkTextLayout { Blt_Font font; /* The font used when laying out the text. */ const char *string; /* The string that was layed out. */ int width; /* The maximum width of all lines in the * text layout. */ int numChunks; /* Number of chunks actually used in * following array. */ LayoutChunk chunks[1]; /* Array of chunks. The actual size will * be maxChunks. THIS FIELD MUST BE THE LAST * IN THE STRUCTURE. */ } TkTextLayout; /* *--------------------------------------------------------------------------- * * Blt_FreeTextLayout -- * * This procedure is called to release the storage associated with * a Tk_TextLayout when it is no longer needed. * * Results: * None. * * Side effects: * Memory is freed. * *--------------------------------------------------------------------------- */ void Blt_FreeTextLayout(Tk_TextLayout textLayout) { TkTextLayout *layoutPtr = (TkTextLayout *) textLayout; if (layoutPtr != NULL) { Blt_Free(layoutPtr); } } /* *--------------------------------------------------------------------------- * * NewChunk -- * * Helper function for Blt_ComputeTextLayout(). Encapsulates a * measured set of characters in a chunk that can be quickly * drawn. * * Results: * A pointer to the new chunk in the text layout. * * Side effects: * The text layout is reallocated to hold more chunks as necessary. * * Currently, Tk_ComputeTextLayout() stores contiguous ranges of * "normal" characters in a chunk, along with individual tab * and newline chars in their own chunks. All characters in the * text layout are accounted for. * *--------------------------------------------------------------------------- */ static LayoutChunk * NewChunk(TkTextLayout **layoutPtrPtr, int *maxPtr, const char *start, int numBytes, int curX, int newX, int y) { TkTextLayout *layoutPtr; LayoutChunk *chunkPtr; int maxChunks, numChars; size_t s; layoutPtr = *layoutPtrPtr; maxChunks = *maxPtr; if (layoutPtr->numChunks == maxChunks) { maxChunks *= 2; s = sizeof(TkTextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk)); layoutPtr = Blt_Realloc(layoutPtr, s); *layoutPtrPtr = layoutPtr; *maxPtr = maxChunks; } numChars = Tcl_NumUtfChars(start, numBytes); chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks]; chunkPtr->start = start; chunkPtr->numBytes = numBytes; chunkPtr->numChars = numChars; chunkPtr->numDisplayChars = numChars; chunkPtr->x = curX; chunkPtr->y = y; chunkPtr->totalWidth = newX - curX; chunkPtr->displayWidth = newX - curX; layoutPtr->numChunks++; return chunkPtr; } /* *--------------------------------------------------------------------------- * * Blt_ComputeTextLayout -- * * Computes the amount of screen space needed to display a multi-line, * justified string of text. Records all the measurements that were done * to determine to size and positioning of the individual lines of text; * this information can be used by the Tk_DrawTextLayout() procedure to * display the text quickly (without remeasuring it). * * This procedure is useful for simple widgets that want to display * single-font, multi-line text and want Tk to handle the details. * * Results: * The return value is a Tk_TextLayout token that holds the measurement * information for the given string. The token is only valid for the * given string. If the string is freed, the token is no longer valid * and must also be freed. To free the token, call Tk_FreeTextLayout(). * * The dimensions of the screen area needed to display the text are * stored in *widthPtr and *heightPtr. * * Side effects: * Memory is allocated to hold the measurement information. * *--------------------------------------------------------------------------- */ Tk_TextLayout Blt_ComputeTextLayout( Blt_Font font, /* Font that will be used to display text. */ const char *string, /* String whose dimensions are to be * computed. */ int numChars, /* Number of characters to consider from * string, or < 0 for strlen(). */ int wrapLength, /* Longest permissible line length, in * pixels. <= 0 means no automatic wrapping: * just let lines get as long as needed. */ Tk_Justify justify, /* How to justify lines. */ int flags, /* Flag bits OR-ed together. * TK_IGNORE_TABS means that tab characters * should not be expanded. TK_IGNORE_NEWLINES * means that newline characters should not * cause a line break. */ int *widthPtr, /* Filled with width of string. */ int *heightPtr) /* Filled with height of string. */ { const char *start, *end, *special; int n, y, bytesThisChunk, maxChunks; int baseline, height, curX, newX, maxWidth; TkTextLayout *layoutPtr; LayoutChunk *chunkPtr; Blt_FontMetrics fm; Tcl_DString lineBuffer; int *lineLengths; int curLine, layoutHeight; Tcl_DStringInit(&lineBuffer); if ((font == NULL) || (string == NULL)) { if (widthPtr != NULL) { *widthPtr = 0; } if (heightPtr != NULL) { *heightPtr = 0; } return NULL; } Blt_GetFontMetrics(font, &fm); height = fm.ascent + fm.descent; if (numChars < 0) { numChars = Tcl_NumUtfChars(string, -1); } if (wrapLength == 0) { wrapLength = -1; } maxChunks = 1; layoutPtr = Blt_AssertMalloc(sizeof(TkTextLayout) + (maxChunks - 1) * sizeof(LayoutChunk)); layoutPtr->font = font; layoutPtr->string = string; layoutPtr->numChunks = 0; baseline = fm.ascent; maxWidth = 0; /* * Divide the string up into simple strings and measure each string. */ curX = 0; end = Tcl_UtfAtIndex(string, numChars); special = string; flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES; flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE; for (start = string; start < end; ) { if (start >= special) { /* * Find the next special character in the string. * * INTL: Note that it is safe to increment by byte, because we are * looking for 7-bit characters that will appear unchanged in * UTF-8. At some point we may need to support the full Unicode * whitespace set. */ for (special = start; special < end; special++) { if (!(flags & TK_IGNORE_NEWLINES)) { if ((*special == '\n') || (*special == '\r')) { break; } } if (!(flags & TK_IGNORE_TABS)) { if (*special == '\t') { break; } } } } /* * Special points at the next special character (or the end of the * string). Process characters between start and special. */ chunkPtr = NULL; if (start < special) { bytesThisChunk = Blt_MeasureChars(font, start, special - start, wrapLength - curX, flags, &newX); newX += curX; flags &= ~TK_AT_LEAST_ONE; if (bytesThisChunk > 0) { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, bytesThisChunk, curX, newX, baseline); start += bytesThisChunk; curX = newX; } } if ((start == special) && (special < end)) { /* * Handle the special character. * * INTL: Special will be pointing at a 7-bit character so we * can safely treat it as a single byte. */ chunkPtr = NULL; if (*special == '\t') { newX = curX + fm.tabWidth; newX -= newX % fm.tabWidth; NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX, baseline)->numDisplayChars = -1; start++; if ((start < end) && ((wrapLength <= 0) || (newX <= wrapLength))) { /* * More chars can still fit on this line. */ curX = newX; flags &= ~TK_AT_LEAST_ONE; continue; } } else { NewChunk(&layoutPtr, &maxChunks, start, 1, curX, curX, baseline)->numDisplayChars = -1; start++; goto wrapLine; } } /* * No more characters are going to go on this line, either because * no more characters can fit or there are no more characters left. * Consume all extra spaces at end of line. */ while ((start < end) && isspace(UCHAR(*start))) { /* INTL: ISO space */ if (!(flags & TK_IGNORE_NEWLINES)) { if ((*start == '\n') || (*start == '\r')) { break; } } if (!(flags & TK_IGNORE_TABS)) { if (*start == '\t') { break; } } start++; } if (chunkPtr != NULL) { const char *end; /* * Append all the extra spaces on this line to the end of the * last text chunk. This is a little tricky because we are * switching back and forth between characters and bytes. */ end = chunkPtr->start + chunkPtr->numBytes; bytesThisChunk = start - end; if (bytesThisChunk > 0) { bytesThisChunk = Blt_MeasureChars(font, end, bytesThisChunk, -1, 0, &chunkPtr->totalWidth); chunkPtr->numBytes += bytesThisChunk; chunkPtr->numChars += Tcl_NumUtfChars(end, bytesThisChunk); chunkPtr->totalWidth += curX; } } wrapLine: flags |= TK_AT_LEAST_ONE; /* * Save current line length, then move current position to start of * next line. */ if (curX > maxWidth) { maxWidth = curX; } /* * Remember width of this line, so that all chunks on this line * can be centered or right justified, if necessary. */ Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); curX = 0; baseline += height; } /* * If last line ends with a newline, then we need to make a 0 width * chunk on the next line. Otherwise "Hello" and "Hello\n" are the * same height. */ if ((layoutPtr->numChunks > 0) && ((flags & TK_IGNORE_NEWLINES) == 0)) { if (layoutPtr->chunks[layoutPtr->numChunks - 1].start[0] == '\n') { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, 0, curX, curX, baseline); chunkPtr->numDisplayChars = -1; Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); baseline += height; } } layoutPtr->width = maxWidth; layoutHeight = baseline - fm.ascent; if (layoutPtr->numChunks == 0) { layoutHeight = height; /* * This fake chunk is used by the other procedures so that they can * pretend that there is a chunk with no chars in it, which makes * the coding simpler. */ layoutPtr->numChunks = 1; layoutPtr->chunks[0].start = string; layoutPtr->chunks[0].numBytes = 0; layoutPtr->chunks[0].numChars = 0; layoutPtr->chunks[0].numDisplayChars = -1; layoutPtr->chunks[0].x = 0; layoutPtr->chunks[0].y = fm.ascent; layoutPtr->chunks[0].totalWidth = 0; layoutPtr->chunks[0].displayWidth = 0; } else { /* * Using maximum line length, shift all the chunks so that the lines * are all justified correctly. */ curLine = 0; chunkPtr = layoutPtr->chunks; y = chunkPtr->y; lineLengths = (int *) Tcl_DStringValue(&lineBuffer); for (n = 0; n < layoutPtr->numChunks; n++) { int extra; if (chunkPtr->y != y) { curLine++; y = chunkPtr->y; } extra = maxWidth - lineLengths[curLine]; if (justify == TK_JUSTIFY_CENTER) { chunkPtr->x += extra / 2; } else if (justify == TK_JUSTIFY_RIGHT) { chunkPtr->x += extra; } chunkPtr++; } } if (widthPtr != NULL) { *widthPtr = layoutPtr->width; } if (heightPtr != NULL) { *heightPtr = layoutHeight; } Tcl_DStringFree(&lineBuffer); return (Tk_TextLayout) layoutPtr; } void Blt_DrawTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context to use for drawing text. */ Tk_TextLayout layout, /* Layout information, from a previous call * to Blt_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in * which to draw (pixels). */ int firstChar, /* The index of the first character to draw * from the given text item. 0 specfies the * beginning. */ int lastChar) /* The index just after the last character * to draw from the given text item. A number * < 0 means to draw all characters. */ { TkTextLayout *layoutPtr; int i, numDisplayChars, drawX; const char *firstByte; const char *lastByte; LayoutChunk *chunkPtr; int depth = 24; layoutPtr = (TkTextLayout *) layout; if (layoutPtr == NULL) { return; } if (lastChar < 0) { lastChar = 100000000; } chunkPtr = layoutPtr->chunks; for (i = 0; i < layoutPtr->numChunks; i++) { numDisplayChars = chunkPtr->numDisplayChars; if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) { if (firstChar <= 0) { drawX = 0; firstChar = 0; firstByte = chunkPtr->start; } else { firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar); Blt_MeasureChars(layoutPtr->font, chunkPtr->start, firstByte - chunkPtr->start, -1, 0, &drawX); } if (lastChar < numDisplayChars) { numDisplayChars = lastChar; } lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); Blt_DrawChars(display, drawable, gc, layoutPtr->font, depth, 0.0f, firstByte, lastByte - firstByte, x + chunkPtr->x + drawX, y + chunkPtr->y); } firstChar -= chunkPtr->numChars; lastChar -= chunkPtr->numChars; if (lastChar <= 0) { break; } chunkPtr++; } } /* *--------------------------------------------------------------------------- * * Tk_CharBbox -- * * Use the information in the Tk_TextLayout token to return the * bounding box for the character specified by index. * * The width of the bounding box is the advance width of the * character, and does not include and left- or right-bearing. * Any character that extends partially outside of the * text layout is considered to be truncated at the edge. Any * character which is located completely outside of the text * layout is considered to be zero-width and pegged against * the edge. * * The height of the bounding box is the line height for this font, * extending from the top of the ascent to the bottom of the * descent. Information about the actual height of the individual * letter is not available. * * A text layout that contains no characters is considered to * contain a single zero-width placeholder character. * * Results: * The return value is 0 if the index did not specify a character * in the text layout, or non-zero otherwise. In that case, * *bbox is filled with the bounding box of the character. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_CharBbox( Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int index, /* The index of the character whose bbox is * desired. */ int *xPtr, int *yPtr, /* Filled with the upper-left hand corner, in * pixels, of the bounding box for the character * specified by index, if non-NULL. */ int *widthPtr, int *heightPtr) /* Filled with the width and height of the * bounding box for the character specified by * index, if non-NULL. */ { TkTextLayout *layoutPtr; LayoutChunk *chunkPtr; int i, x, w; Blt_Font font; const char *end; Blt_FontMetrics fm; if (index < 0) { return 0; } layoutPtr = (TkTextLayout *) layout; chunkPtr = layoutPtr->chunks; font = layoutPtr->font; Blt_GetFontMetrics(font, &fm); for (i = 0; i < layoutPtr->numChunks; i++) { if (chunkPtr->numDisplayChars < 0) { if (index == 0) { x = chunkPtr->x; w = chunkPtr->totalWidth; goto check; } } else if (index < chunkPtr->numChars) { end = Tcl_UtfAtIndex(chunkPtr->start, index); if (xPtr != NULL) { Blt_MeasureChars(font, chunkPtr->start, end - chunkPtr->start, -1, 0, &x); x += chunkPtr->x; } if (widthPtr != NULL) { Blt_MeasureChars(font, end, Tcl_UtfNext(end) - end, -1, 0, &w); } goto check; } index -= chunkPtr->numChars; chunkPtr++; } if (index == 0) { /* * Special case to get location just past last char in layout. */ chunkPtr--; x = chunkPtr->x + chunkPtr->totalWidth; w = 0; } else { return 0; } /* * Ensure that the bbox lies within the text layout. This forces all * chars that extend off the right edge of the text layout to have * truncated widths, and all chars that are completely off the right * edge of the text layout to peg to the edge and have 0 width. */ check: if (yPtr != NULL) { *yPtr = chunkPtr->y - fm.ascent; } if (heightPtr != NULL) { *heightPtr = fm.ascent + fm.descent; } if (x > layoutPtr->width) { x = layoutPtr->width; } if (xPtr != NULL) { *xPtr = x; } if (widthPtr != NULL) { if (x + w > layoutPtr->width) { w = layoutPtr->width - x; } *widthPtr = w; } return 1; } /* *--------------------------------------------------------------------------- * * Blt_UnderlineTextLayout -- * * Use the information in the Tk_TextLayout token to display an * underline below an individual character. This procedure does * not draw the text, just the underline. * * This procedure is useful for simple widgets that need to * display single-font, multi-line text with an individual * character underlined and want Tk to handle the details. * To display larger amounts of underlined text, construct * and use an underlined font. * * Results: * None. * * Side effects: * Underline drawn on the screen. * *--------------------------------------------------------------------------- */ void Blt_UnderlineTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context to use for drawing text. */ Tk_TextLayout layout, /* Layout information, from a previous call * to Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in * which to draw (pixels). */ int underline) /* Index of the single character to * underline, or -1 for no underline. */ { TkTextLayout *layoutPtr; int xx, yy, width, height; if ((Blt_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0) && (width != 0)) { Blt_FontMetrics fm; layoutPtr = (TkTextLayout *) layout; Blt_GetFontMetrics(layoutPtr->font, &fm); XFillRectangle(display, drawable, gc, x + xx, y + yy + fm.ascent + fm.underlinePos, (unsigned int) width, fm.underlineHeight); } } ./saods9/blt3.0.1/src/bltPool.h���������������������������������������������������������������������0000644�0001750�0001750�00000001202�11462120062�014604� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef BLT_POOL_H #define BLT_POOL_H #define BLT_STRING_ITEMS 0 #define BLT_FIXED_SIZE_ITEMS 1 #define BLT_VARIABLE_SIZE_ITEMS 2 typedef struct _Blt_Pool *Blt_Pool; typedef void *(Blt_PoolAllocProc)(Blt_Pool pool, size_t size); typedef void (Blt_PoolFreeProc)(Blt_Pool pool, void *item); struct _Blt_Pool { Blt_PoolAllocProc *allocProc; Blt_PoolFreeProc *freeProc; }; BLT_EXTERN Blt_Pool Blt_PoolCreate(int type); BLT_EXTERN void Blt_PoolDestroy(Blt_Pool pool); #define Blt_PoolAllocItem(pool, n) (*((pool)->allocProc))(pool, n) #define Blt_PoolFreeItem(pool, item) (*((pool)->freeProc))(pool, item) #endif /* BLT_POOL_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltListView.c�����������������������������������������������������������������0000644�0001750�0001750�00000530433�11462120062�015451� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltListView.c -- * * This module implements a listview widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltBind.h" #include "bltImage.h" #include "bltPicture.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltHash.h" #include "bltBgStyle.h" #include "bltPainter.h" #include "bltSwitch.h" #include <X11/Xutil.h> #include <X11/Xatom.h> static const char emptyString[] = ""; #define REDRAW_PENDING (1<<0) /* The widget needs to be redrawn. */ #define LAYOUT_PENDING (1<<1) /* The layout of widget needs to be * recomputed. */ #define SORT_PENDING (1<<3) /* The items in the need to be * sorted. */ #define FOCUS (1<<4) /* The widget currently has focus. */ #define SORTED (1<<5) /* The items are currently sorted. */ #define SCROLLX (1<<6) /* The widget needs to be scrolled in * the x direction. */ #define SCROLLY (1<<7) /* The widget needs to be scrolled in * the y direction. */ #define SCROLL_PENDING (SCROLLX|SCROLLY) #define RESTRICT_MIN (1<<10) #define RESTRICT_MAX (1<<11) #define RESTRICT_NONE (0) #define SELECT_SINGLE (1<<12) /* Single mode: Select only one item * at a time.*/ #define SELECT_MULTIPLE (1<<13) /* Multiple mode: Select one or more * items. */ #define SELECT_MODE_MASK (SELECT_MULTIPLE|SELECT_SINGLE) #define SELECT_EXPORT (1<<16) /* Export the selection to X11. */ #define SELECT_ORDERED (1<<17) /* Indicates that the selection should * be set in the order that the items * were selected. */ #define SELECT_PENDING (1<<18) /* A "selection" command idle task is * pending. */ #define SELECT_SET (1<<19) /* Select the item. */ #define SELECT_CLEAR (1<<20) /* Deselect the item. */ #define SELECT_TOGGLE (SELECT_SET | SELECT_CLEAR) #define SELECT_MASK (SELECT_SET | SELECT_CLEAR) #define SORT_AUTO (1<<26) /* Automatically sort the items as * items are added or deleted. */ #define SORT_DECREASING (1<<27) /* Sort items in decreasing order. */ #define SORT_DICTIONARY (1<<28) /* Sort the items in dictionary * order. */ #define SORT_TYPE (1<<29) /* Sort the items by their type. */ #define SORT_LABEL (1<<30) /* Sort the items by their label. */ #define SORT_MODE_MASK (SORT_TYPE|SORT_LABEL) #define VAR_FLAGS (TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS) #define PIXMAPX(l, wx) ((wx) - (l)->xOffset) #define PIXMAPY(l, wy) ((wy) - (l)->yOffset) #define SCREENX(l, wx) ((wx) - (l)->xOffset + (l)->inset) #define SCREENY(l, wy) ((wy) - (l)->yOffset + (l)->inset) #define WORLDX(l, sx) ((sx) - (l)->inset + (l)->xOffset) #define WORLDY(l, sy) ((sy) - (l)->inset + (l)->yOffset) #define VPORTWIDTH(l) \ (Tk_Width((l)->tkwin) - 2 * (l)->inset) #define VPORTHEIGHT(l) \ (Tk_Height((l)->tkwin) - 2 * (l)->inset) #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define CLAMP(x,min,max) ((((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x))) #define ITEM_IPAD 5 #define ITEM_XPAD 0 #define ITEM_YPAD 0 #define ITEM_REDRAW (1<<2) /* Item needs to be redrawn. */ #define ITEM_HIDE (1<<5) /* The item is hidden. */ /* Item state. */ #define ITEM_NORMAL (1<<8) /* Draw item normally. */ #define ITEM_DISABLED (1<<9) /* Item is disabled. */ #define ITEM_STATE_MASK ((ITEM_DISABLED)|(ITEM_NORMAL)) #define DEF_MAXWIDTH "1i" #define DEF_AUTO_SORT "0" #define DEF_BORDERWIDTH "1" #define DEF_CURSOR ((char *)NULL) #define DEF_EXPORT_SELECTION "1" #define DEF_HEIGHT "0" #define DEF_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_HIGHLIGHT_COLOR RGB_BLACK #define DEF_HIGHLIGHT_WIDTH "2" #define DEF_ICON_VARIABLE ((char *)NULL) #define DEF_LAYOUTMODE "column" #define DEF_RELIEF "sunken" #define DEF_SELECTMODE "single" #define DEF_SORT_DICTIONARY "0" #define DEF_SORT_COMMAND ((char *)NULL) #define DEF_SORT_DECREASING "0" #define DEF_SORT_SELECTION "1" #define DEF_SORT_TYPE "label" #define DEF_TAKEFOCUS "1" #define DEF_TEXTVARIABLE ((char *)NULL) #define DEF_WIDTH "0" #define DEF_XSCROLLCOMMAND ((char *)NULL) #define DEF_XSCROLLINCREMENT "20" #define DEF_YSCROLLCOMMAND ((char *)NULL) #define DEF_YSCROLLINCREMENT "20" #define DEF_ITEM_COMMAND ((char *)NULL) #define DEF_ITEM_DATA ((char *)NULL) #define DEF_ITEM_ICON ((char *)NULL) #define DEF_ITEM_IMAGE ((char *)NULL) #define DEF_ITEM_INDENT "0" #define DEF_ITEM_MENU ((char *)NULL) #define DEF_ITEM_STATE "normal" #define DEF_ITEM_STYLE "default" #define DEF_ITEM_TAGS ((char *)NULL) #define DEF_ITEM_TEXT ((char *)NULL) #define DEF_ITEM_TIP ((char *)NULL) #define DEF_ITEM_TYPE ((char *)NULL) #define DEF_STYLE_ACTIVE_BG RGB_WHITE #define DEF_STYLE_ACTIVE_FG RGB_BLACK #define DEF_STYLE_ACTIVE_RELIEF "flat" #define DEF_STYLE_BG RGB_WHITE #define DEF_STYLE_BORDERWIDTH "0" #define DEF_STYLE_DISABLED_ACCEL_FG STD_DISABLED_FOREGROUND #define DEF_STYLE_DISABLED_BG DISABLED_BACKGROUND #define DEF_STYLE_DISABLED_FG DISABLED_FOREGROUND #define DEF_STYLE_FG RGB_BLACK #define DEF_STYLE_FONT STD_FONT_SMALL #define DEF_STYLE_RELIEF "flat" #define DEF_STYLE_SELECT_BG RGB_SKYBLUE4 #define DEF_STYLE_SELECT_FG RGB_WHITE #define DEF_STYLE_SELECT_RELIEF "flat" #define DISABLED_BACKGROUND RGB_GREY90 #define DISABLED_FOREGROUND RGB_GREY70 static Blt_OptionFreeProc FreeStyleProc; static Blt_OptionParseProc ObjToStyleProc; static Blt_OptionPrintProc StyleToObjProc; static Blt_CustomOption styleOption = { ObjToStyleProc, StyleToObjProc, FreeStyleProc, (ClientData)0 }; static Blt_OptionFreeProc FreeTagsProc; static Blt_OptionParseProc ObjToTagsProc; static Blt_OptionPrintProc TagsToObjProc; static Blt_CustomOption tagsOption = { ObjToTagsProc, TagsToObjProc, FreeTagsProc, (ClientData)0 }; static Blt_OptionFreeProc FreeLabelProc; static Blt_OptionParseProc ObjToLabelProc; static Blt_OptionPrintProc LabelToObjProc; static Blt_CustomOption labelOption = { ObjToLabelProc, LabelToObjProc, FreeLabelProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0 }; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToRestrictProc; static Blt_OptionPrintProc RestrictToObjProc; static Blt_CustomOption restrictOption = { ObjToRestrictProc, RestrictToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToSelectmode; static Blt_OptionPrintProc SelectmodeToObj; static Blt_CustomOption selectModeOption = { ObjToSelectmode, SelectmodeToObj, NULL, NULL, }; static Blt_OptionParseProc ObjToLayoutmode; static Blt_OptionPrintProc LayoutmodeToObj; static Blt_CustomOption layoutModeOption = { ObjToLayoutmode, LayoutmodeToObj, NULL, NULL, }; static Blt_OptionParseProc ObjToSortType; static Blt_OptionPrintProc SortTypeToObj; static Blt_CustomOption sortTypeOption = { ObjToSortType, SortTypeToObj, NULL, NULL, }; extern Blt_CustomOption bltLimitsOption; typedef struct _ListView ListView; typedef enum LayoutModes { LAYOUT_LIST_COLUMN, /* Layout items in a single list, * one item per row. */ LAYOUT_LIST_ROW, /* Layout items in multiple columns. */ LAYOUT_ICONS, /* Layout items in multiple rows * using the big icon with the label * underneath. */ LAYOUT_TILES /* Layout items using the big icon * with 3 lines of text on the * right. */ } LayoutMode; /* * Icon -- * * Since instances of the same Tk image can be displayed in different * windows with possibly different color palettes, Tk internally stores * each instance in a linked list. But if the instances are used in the * same widget and therefore use the same color palette, this adds a lot * of overhead, especially when deleting instances from the linked list. * * For the listview widget, we never need more than a single instance of * an image, regardless of how many times it's used. Cache the image, * maintaining a reference count for each image used in the widget. It's * likely that the listview widget will use many instances of the same * image. */ typedef struct _Icon { Tk_Image tkImage; /* The Tk image being cached. */ Blt_HashEntry *hPtr; /* Hash table pointer to the image. */ int refCount; /* Reference count for this image. */ short int width, height; /* Dimensions of the cached image. */ } *Icon; #define IconHeight(i) ((i)->height) #define IconWidth(i) ((i)->width) #define IconImage(i) ((i)->tkImage) #define IconName(i) (Blt_Image_Name(IconImage(i))) typedef struct { const char *name; Blt_HashEntry *hPtr; ListView *viewPtr; int refCount; /* Indicates if the style is currently * in use in the listview. */ int borderWidth; int relief; int activeRelief; int selectRelief; Blt_Background normalBg; Blt_Background activeBg; Blt_Background selectBg; Blt_Background disabledBg; Blt_Font labelFont; /* Font of the label */ XColor *labelNormalColor; /* Color of label text. */ XColor *labelDisabledColor; /* Color of label background. */ XColor *labelActiveColor; /* Color of label background. */ XColor *labelSelectColor; /* Color of label background. */ } Style; static Blt_ConfigSpec styleSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_BG, Blt_Offset(Style, activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_FG, Blt_Offset(Style, labelActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(Style, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", (char *)NULL, (char *)NULL, DEF_STYLE_BG, Blt_Offset(Style, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", (char *)NULL, (char *)NULL, DEF_STYLE_BORDERWIDTH, Blt_Offset(Style, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", (char *)NULL, (char *)NULL, DEF_STYLE_DISABLED_BG, Blt_Offset(Style, disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", (char *)NULL, (char *)NULL, DEF_STYLE_DISABLED_FG, Blt_Offset(Style, labelDisabledColor), 0}, {BLT_CONFIG_SYNONYM, "-fg", (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", (char *)NULL, (char *)NULL, DEF_STYLE_FG, Blt_Offset(Style, labelNormalColor), 0}, {BLT_CONFIG_FONT, "-font", (char *)NULL, (char *)NULL, DEF_STYLE_FONT, Blt_Offset(Style, labelFont), 0}, {BLT_CONFIG_RELIEF, "-relief", (char *)NULL, (char *)NULL, DEF_STYLE_RELIEF, Blt_Offset(Style, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-selectbackground", (char *)NULL, (char *)NULL, DEF_STYLE_SELECT_BG, Blt_Offset(Style, selectBg), 0}, {BLT_CONFIG_COLOR, "-selectforeground", (char *)NULL, (char *)NULL, DEF_STYLE_SELECT_FG, Blt_Offset(Style, labelSelectColor), 0}, {BLT_CONFIG_RELIEF, "-selectrelief", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(Style, selectRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * * [icon] [label] * * icon: all entries. * label: all entries. */ typedef struct { ListView *viewPtr; /* ListView containing this item. */ long index; /* Index of the item (numbered from 0)*/ int worldX, worldY; /* Upper left world-coordinate of item * in menu. */ Style *stylePtr; /* Style used by this item. */ unsigned int flags; /* Contains various bits of * information about the item, such as * type, state. */ Blt_ChainLink link; int relief; int indent; /* # of pixels to indent the icon. */ Icon image; /* If non-NULL, image to be displayed * instead of text label. */ Icon icon; /* Small icon. */ Icon bigIcon; /* Big icon. */ const char *label; /* Label to be displayed. */ Tcl_Obj *cmdObjPtr; /* Command to be invoked when item is * clicked. */ Tcl_Obj *dataObjPtr; /* User-data associated with this * item. */ Tcl_Obj *tagsObjPtr; Tcl_Obj *tipObjPtr; const char *type; short int labelX, labelY, labelWidth, labelHeight; short int iconX, iconY, iconWidth, iconHeight; short int width, height; short int worldWidth, worldHeight; } Item; static Blt_ConfigSpec itemSpecs[] = { {BLT_CONFIG_CUSTOM, "-bigicon", (char *)NULL, (char *)NULL, DEF_ITEM_ICON, Blt_Offset(Item, bigIcon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_OBJ, "-command", (char *)NULL, (char *)NULL, DEF_ITEM_COMMAND, Blt_Offset(Item, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-data", (char *)NULL, (char *)NULL, DEF_ITEM_DATA, Blt_Offset(Item, dataObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-icon", (char *)NULL, (char *)NULL, DEF_ITEM_ICON, Blt_Offset(Item, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-image", (char *)NULL, (char *)NULL, DEF_ITEM_IMAGE, Blt_Offset(Item, image), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_PIXELS_NNEG, "-indent", (char *)NULL, (char *)NULL, DEF_ITEM_INDENT, Blt_Offset(Item, indent), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-state", (char *)NULL, (char *)NULL, DEF_ITEM_STATE, Blt_Offset(Item, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_CUSTOM, "-style", (char *)NULL, (char *)NULL, DEF_ITEM_STYLE, Blt_Offset(Item, stylePtr), 0, &styleOption}, {BLT_CONFIG_CUSTOM, "-tags", (char *)NULL, (char *)NULL, DEF_ITEM_TAGS, 0, BLT_CONFIG_NULL_OK, &tagsOption}, {BLT_CONFIG_CUSTOM, "-text", (char *)NULL, (char *)NULL, DEF_ITEM_TEXT, Blt_Offset(Item, label), BLT_CONFIG_NULL_OK, &labelOption}, {BLT_CONFIG_OBJ, "-tooltip", (char *)NULL, (char *)NULL, DEF_ITEM_TIP, Blt_Offset(Item, tipObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_ITEM_TYPE, Blt_Offset(Item, type), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; struct _ListView { /* * This works around a bug in the Tk API. Under Win32, Tk tries to * read the widget record of toplevel windows (TopLevel or Frame widget), * to get its menu name field. What this means is that we must carefully * arrange the fields of this widget so that the menuName field is at the * same offset in the structure. */ Tk_Window tkwin; /* Window that embodies the frame. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up. */ Display *display; /* Display containing widget. Used, * among other things, so that * resources can be freed even after * tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. * Used to delete widget command. */ Tcl_Command cmdToken; /* Token for widget's command. */ LayoutMode layoutMode; unsigned int flags; Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * name of the Tk image representing * the icon of the selected item. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * text string of the label of the * selected item. */ Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not * used in the C code, but used by * keyboard * traversal scripts. */ Tk_Cursor cursor; /* Current cursor for window or None. */ Blt_Limits reqWidth, reqHeight; int relief; int borderWidth; int highlightWidth; /* Width in pixels of highlight to * draw around widget when it has the * focus. <= 0 means don't draw a * highlight. */ XColor *highlightColor; /* Color for drawing traversal * highlight. */ int inset; /* Sum of highlight thickness and * borderwidth. */ XColor *focusColor; /* Color of focus highlight * rectangle. */ GC focusGC; Style defStyle; /* Default style. */ int maxWidth; int xScrollUnits, yScrollUnits; /* Commands to control horizontal and vertical scrollbars. */ Tcl_Obj *xScrollCmdObjPtr, *yScrollCmdObjPtr; Blt_HashTable tagTable; /* Table of tags. */ Blt_HashTable labelTable; /* Table of labels (hashtables). */ Blt_HashTable iconTable; /* Table of icons. */ Blt_Chain chain; Item *activePtr; /* If non-NULL, item that is currently * active. */ Item *focusPtr; /* If non-NULL, item that currently * has focus. */ int xOffset, yOffset; /* Scroll offsets of viewport in * world. */ int worldWidth, worldHeight; /* Dimension of entire menu. */ short int labelWidth, iconWidth; short int labelHeight, iconHeight; int itemHeight; Blt_HashTable styleTable; /* Table of styles used. */ /* * Scanning Information: */ short int scanAnchorX; /* Horizontal scan anchor in screen * x-coordinates. */ short int scanAnchorY; /* Vertical scan anchor in screen * y-coordinates. */ int scanX; /* x-offset of the start of the * horizontal scan in world * coordinates.*/ int scanY; /* y-offset of the start of the * vertical scan in world * coordinates.*/ /* * Selection Information: */ Item *selAnchorPtr; /* Fixed end of selection (i.e. item * at which selection was started.) */ Item *selMarkPtr; Tcl_Obj *selectCmdObjPtr; /* TCL script that's invoked whenever * the selection changes. */ Blt_HashTable selectTable; /* Hash table of currently selected * entries. */ Blt_Chain selected; /* Chain of currently selected entries. * Contains the same information as the * above hash table, but maintains the * order in which entries are * selected. */ Tcl_Obj *sortCmdPtr; short int width, height; Blt_Painter painter; }; static Blt_ConfigSpec listViewSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BG, Blt_Offset(ListView, defStyle.activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FG, Blt_Offset(ListView, defStyle.labelActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "ActiveRelief", DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(ListView, defStyle.activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_STYLE_BG, Blt_Offset(ListView, defStyle.normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(ListView, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(ListView, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", "disabledBackground", "DisabledBackground", DEF_STYLE_DISABLED_BG, Blt_Offset(ListView, defStyle.disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_STYLE_DISABLED_FG, Blt_Offset(ListView, defStyle.labelDisabledColor), 0}, {BLT_CONFIG_BITMASK, "-exportselection", "exportSelection", "ExportSelection", DEF_EXPORT_SELECTION, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SELECT_EXPORT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-focuscolor", "focusColor", "FocusColor", DEF_HIGHLIGHT_COLOR, Blt_Offset(ListView, focusColor), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_STYLE_FG, Blt_Offset(ListView, defStyle.labelNormalColor), 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_STYLE_FONT, Blt_Offset(ListView, defStyle.labelFont), 0}, {BLT_CONFIG_CUSTOM, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(ListView, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT, &bltLimitsOption}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHT_COLOR, Blt_Offset(ListView, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHT_WIDTH, Blt_Offset(ListView, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-maxwidth", "maxWidth", "MaxWidth", DEF_MAXWIDTH, Blt_Offset(ListView, maxWidth), 0}, {BLT_CONFIG_OBJ, "-iconvariable", "iconVariable", "IconVariable", DEF_ICON_VARIABLE, Blt_Offset(ListView, iconVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-itemborderwidth", "itemBorderWidth", "ItemBorderWidth", DEF_STYLE_BORDERWIDTH, Blt_Offset(ListView, defStyle.borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-layoutmode", "layoutMode", "LayoutMode", DEF_LAYOUTMODE, Blt_Offset(ListView, layoutMode), BLT_CONFIG_DONT_SET_DEFAULT, &layoutModeOption}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_RELIEF, Blt_Offset(ListView, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-restrictwidth", "restrictWidth", "RestrictWidth", (char *)NULL, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, &restrictOption}, {BLT_CONFIG_BACKGROUND, "-selectbackground", (char *)NULL, (char *)NULL, DEF_STYLE_SELECT_BG, Blt_Offset(ListView, defStyle.selectBg), 0}, {BLT_CONFIG_OBJ, "-selectcommand", "selectCommand", "SelectCommand", (char *)NULL, Blt_Offset(ListView, selectCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", (char *)NULL, (char *)NULL, DEF_STYLE_SELECT_FG, Blt_Offset(ListView, defStyle.labelSelectColor),0}, {BLT_CONFIG_RELIEF, "-selectrelief", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(ListView, defStyle.selectRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-selectmode", "selectMode", "SelectMode", DEF_SELECTMODE, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, &selectModeOption}, {BLT_CONFIG_BITMASK, "-orderselection", "orderSelection", "OrderSelection", DEF_SORT_SELECTION, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SELECT_ORDERED}, {BLT_CONFIG_OBJ, "-textvariable", "textVariable", "TextVariable", DEF_TEXTVARIABLE, Blt_Offset(ListView, textVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_XSCROLLCOMMAND, Blt_Offset(ListView, xScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_XSCROLLINCREMENT, Blt_Offset(ListView, xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", DEF_YSCROLLCOMMAND, Blt_Offset(ListView, yScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_YSCROLLINCREMENT, Blt_Offset(ListView, yScrollUnits),BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKEFOCUS, Blt_Offset(ListView, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(ListView, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT, &bltLimitsOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec sortSpecs[] = { {BLT_CONFIG_BITMASK, "-autosort", "autoSort", "AutoSort", DEF_AUTO_SORT, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SORT_AUTO}, {BLT_CONFIG_BITMASK, "-dictionary", "dictionary", "Dictionary", DEF_SORT_DICTIONARY, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SORT_DICTIONARY}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_SORT_COMMAND, Blt_Offset(ListView, sortCmdPtr), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-decreasing", "decreasing", "Decreasing", DEF_SORT_DECREASING, Blt_Offset(ListView, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)SORT_DECREASING}, {BLT_CONFIG_CUSTOM, "-by", "by", "By", DEF_SORT_TYPE, Blt_Offset(ListView, flags), 0, &sortTypeOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * ItemIterator -- * * Items may be tagged with strings. An item may have many tags. The * same tag may be used for many items. * */ typedef enum { ITER_SINGLE, ITER_ALL, ITER_TAG, ITER_PATTERN } IteratorType; typedef struct _Iterator { ListView *viewPtr; /* ListView that we're iterating * over. */ IteratorType type; /* Type of iteration: * ITER_TAG By item tag. * ITER_ALL By every item. * ITER_SINGLE Single item: either * tag or index. */ Item *startPtr, *last; /* Starting and ending item. Starting * point of search, saved if iterator * is reused. Used for ITER_ALL and * ITER_SINGLE searches. */ Item *endPtr; /* Ending item (inclusive). */ Item *nextPtr; /* Next item. */ char *tagName; /* If non-NULL, is the tag that we are * currently iterating over. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Search iterator for tag hash * table. */ Blt_ChainLink link; } ItemIterator; static Blt_SwitchParseProc ItemSwitch; static Blt_SwitchCustom itemSwitch = { ItemSwitch, NULL, NULL, }; static Blt_SwitchParseProc PatternSwitch; static Blt_SwitchCustom patternSwitch = { PatternSwitch, NULL, NULL, }; #define FIND_GLOB (0) /* Default pattern type. */ #define FIND_REGEXP (1<<0) #define FIND_EXACT (1<<1) #define FIND_PATTERN_MASK (FIND_EXACT|FIND_GLOB|FIND_REGEXP) #define FIND_HIDDEN (1<<2) #define FIND_DISABLED (1<<3) #define FIND_ANY (FIND_HIDDEN|FIND_DISABLED) #define FIND_WRAP (1<<4) #define FIND_REVERSE (1<<5) typedef struct { unsigned int flags; int count; Item *fromPtr, *toPtr; } FindSwitches; static Blt_SwitchSpec findSwitches[] = { {BLT_SWITCH_BITMASK, "-any", "", Blt_Offset(FindSwitches, flags), 0, FIND_ANY}, {BLT_SWITCH_INT_NNEG, "-count", "number", Blt_Offset(FindSwitches, count), 0, 0}, {BLT_SWITCH_BITMASK, "-disabled", "", Blt_Offset(FindSwitches, flags), 0, FIND_DISABLED}, {BLT_SWITCH_CUSTOM, "-from", "item", Blt_Offset(FindSwitches, fromPtr), 0, 0, &itemSwitch}, {BLT_SWITCH_BITMASK, "-hidden", "", Blt_Offset(FindSwitches, flags), 0, FIND_HIDDEN}, {BLT_SWITCH_BITMASK, "-reverse", "", Blt_Offset(FindSwitches, flags), 0, FIND_REVERSE}, {BLT_SWITCH_CUSTOM, "-to", "item", Blt_Offset(FindSwitches, toPtr), 0, 0, &itemSwitch}, {BLT_SWITCH_CUSTOM, "-type", "glob|regexp|exact", Blt_Offset(FindSwitches, flags), 0, 0, &patternSwitch}, {BLT_SWITCH_BITMASK, "-wrap", "", Blt_Offset(FindSwitches, flags), 0, FIND_WRAP}, {BLT_SWITCH_END} }; typedef int (ListViewCmdProc)(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int GetItemIterator(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, ItemIterator *iterPtr); static int GetItemFromObj(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, Item **itemPtrPtr); static Tcl_IdleProc DisplayItem; static Tcl_IdleProc DisplayListView; static Tcl_FreeProc DestroyListView; static Tk_EventProc ListViewEventProc; static Tcl_ObjCmdProc ListViewInstCmdProc; static Tcl_CmdDeleteProc ListViewInstCmdDeletedProc; static Tk_ImageChangedProc IconChangedProc; /* *--------------------------------------------------------------------------- * * ChildSwitch -- * * Convert a Tcl_Obj representing the label of a child node into its * integer node id. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PatternSwitch( ClientData clientData, /* Flag indicating if the node is considered * before or after the insertion position. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Not used. */ int flags) /* Not used. */ { char c; const char *string; int length; unsigned int *flagsPtr = (unsigned int *)(record + offset); unsigned int flag; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'g') && (strncmp(string, "glob", length) == 0)) { flag = FIND_GLOB; } else if ((c == 'r') && (strncmp(string, "regexp", length) == 0)) { flag = FIND_REGEXP; } else if ((c == 'e') && (strncmp(string, "exact", length) == 0)) { flag = FIND_EXACT; } else { Tcl_AppendResult(interp, "unknown pattern type \"", string, "\": should be glob, regexp, or exact.", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~FIND_PATTERN_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToLayoutmode -- * * Convert the string reprsenting a layout mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLayoutmode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ListView *viewPtr = (ListView *)widgRec; char *string; char c; int *modePtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'c') && (strcmp(string, "column") == 0)) { *modePtr = LAYOUT_LIST_COLUMN; } else if ((c == 'r') && (strcmp(string, "row") == 0)) { *modePtr = LAYOUT_LIST_ROW; } else if ((c == 'i') && (strcmp(string, "icons") == 0)) { *modePtr = LAYOUT_ICONS; } else if ((c == 't') && (strcmp(string, "tiles") == 0)) { *modePtr = LAYOUT_TILES; } else { Tcl_AppendResult(interp, "bad select mode \"", string, "\": should be column, row, icons, or tiles.", (char *)NULL); return TCL_ERROR; } viewPtr->flags |= LAYOUT_PENDING; return TCL_OK; } /* *--------------------------------------------------------------------------- * * LayoutmodeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LayoutmodeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mode = *(int *)(widgRec + offset); switch (mode) { case LAYOUT_LIST_COLUMN: return Tcl_NewStringObj("column", -1); case LAYOUT_LIST_ROW: return Tcl_NewStringObj("row", -1); case LAYOUT_ICONS: return Tcl_NewStringObj("icons", -1); case LAYOUT_TILES: return Tcl_NewStringObj("tiles", -1); default: return Tcl_NewStringObj("???", -1); } } /* *--------------------------------------------------------------------------- * * ObjToSelectmode -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSelectmode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; char c; int flag; int *flagsPtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 's') && (strcmp(string, "single") == 0)) { flag = SELECT_SINGLE; } else if ((c == 'm') && (strcmp(string, "multiple") == 0)) { flag = SELECT_MULTIPLE; } else { Tcl_AppendResult(interp, "bad select mode \"", string, "\": should be \"single\" or \"multiple\"", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~SELECT_MODE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectmodeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SelectmodeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mask = *(int *)(widgRec + offset); switch (mask & SELECT_MODE_MASK) { case SELECT_SINGLE: return Tcl_NewStringObj("single", -1); case SELECT_MULTIPLE: return Tcl_NewStringObj("multiple", -1); default: return Tcl_NewStringObj("???", -1); } } /* *--------------------------------------------------------------------------- * * ObjToSortType -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSortType( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; char c; int flag; int *flagsPtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'l') && (strcmp(string, "label") == 0)) { flag = SORT_LABEL; } else if ((c == 't') && (strcmp(string, "type") == 0)) { flag = SORT_TYPE; } else { Tcl_AppendResult(interp, "bad sort mode \"", string, "\": should be \"label\" or \"type\"", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~SORT_MODE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SortTypeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SortTypeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mask = *(int *)(widgRec + offset); switch (mask & SORT_MODE_MASK) { case SORT_TYPE: return Tcl_NewStringObj("type", -1); case SORT_LABEL: return Tcl_NewStringObj("label", -1); default: return Tcl_NewStringObj("???", -1); } } /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the listview display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(ListView *viewPtr) { if ((viewPtr->tkwin != NULL) && !(viewPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayListView, viewPtr); viewPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * SelectCmdProc -- * * Invoked at the next idle point whenever the current selection changes. * Executes some application-specific code in the -selectcommand option. * This provides a way for applications to handle selection changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void SelectCmdProc(ClientData clientData) { ListView *viewPtr = clientData; viewPtr->flags &= ~SELECT_PENDING; Tcl_Preserve(viewPtr); if (viewPtr->selectCmdObjPtr != NULL) { if (Tcl_EvalObjEx(viewPtr->interp, viewPtr->selectCmdObjPtr, TCL_EVAL_GLOBAL) != TCL_OK) { Tcl_BackgroundError(viewPtr->interp); } } Tcl_Release(viewPtr); } /* *--------------------------------------------------------------------------- * * EventuallyInvokeSelectCmd -- * * Queues a request to execute the -selectcommand code associated with * the widget at the next idle point. Invoked whenever the selection * changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void EventuallyInvokeSelectCmd(ListView *viewPtr) { if ((viewPtr->flags & SELECT_PENDING) == 0) { viewPtr->flags |= SELECT_PENDING; Tcl_DoWhenIdle(SelectCmdProc, viewPtr); } } static INLINE Item * FirstItem(ListView *viewPtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(viewPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static INLINE Item * LastItem(ListView *viewPtr) { Blt_ChainLink link; link = Blt_Chain_LastLink(viewPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static Item * NextItem(Item *itemPtr) { if (itemPtr != NULL) { Blt_ChainLink link; link = Blt_Chain_NextLink(itemPtr->link); if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } static INLINE Item * PrevItem(Item *itemPtr) { if (itemPtr != NULL) { Blt_ChainLink link; link = Blt_Chain_PrevLink(itemPtr->link); if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } static Item * NextItemAvailable(Item *itemPtr) { for (itemPtr = NextItem(itemPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if ((itemPtr->flags & (ITEM_HIDE|ITEM_DISABLED)) == 0) { return itemPtr; } } return NULL; } static Item * PrevItemAvailable(Item *itemPtr) { for (itemPtr = PrevItem(itemPtr); itemPtr != NULL; itemPtr = PrevItem(itemPtr)) { if ((itemPtr->flags & (ITEM_HIDE|ITEM_DISABLED)) == 0) { return itemPtr; } } return NULL; } static int ItemIsSelected(ListView *viewPtr, Item *itemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->selectTable, (char *)itemPtr); return (hPtr != NULL); } static void SelectItem(ListView *viewPtr, Item *itemPtr) { int isNew; Blt_HashEntry *hPtr; hPtr = Blt_CreateHashEntry(&viewPtr->selectTable, (char *)itemPtr, &isNew); if (isNew) { Blt_ChainLink link; link = Blt_Chain_Append(viewPtr->selected, itemPtr); Blt_SetHashValue(hPtr, link); } if ((viewPtr->textVarObjPtr != NULL) && (itemPtr->label != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(itemPtr->label, -1); if (Tcl_ObjSetVar2(viewPtr->interp, viewPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return; } } if ((viewPtr->iconVarObjPtr != NULL) && (itemPtr->icon != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(IconName(itemPtr->icon), -1); if (Tcl_ObjSetVar2(viewPtr->interp, viewPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return; } } } static void DeselectItem(ListView *viewPtr, Item *itemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->selectTable, (char *)itemPtr); if (hPtr != NULL) { Blt_ChainLink link; link = Blt_GetHashValue(hPtr); Blt_Chain_DeleteLink(viewPtr->selected, link); Blt_DeleteHashEntry(&viewPtr->selectTable, hPtr); } } static void SelectItemUsingFlags(ListView *viewPtr, Item *itemPtr) { switch (viewPtr->flags & SELECT_MASK) { case SELECT_CLEAR: DeselectItem(viewPtr, itemPtr); break; case SELECT_SET: SelectItem(viewPtr, itemPtr); break; case SELECT_TOGGLE: if (ItemIsSelected(viewPtr, itemPtr)) { DeselectItem(viewPtr, itemPtr); } else { SelectItem(viewPtr, itemPtr); } break; } } static void ClearSelection(ListView *viewPtr) { Blt_DeleteHashTable(&viewPtr->selectTable); Blt_InitHashTable(&viewPtr->selectTable, BLT_ONE_WORD_KEYS); Blt_Chain_Reset(viewPtr->selected); EventuallyRedraw(viewPtr); if (viewPtr->selectCmdObjPtr != NULL) { EventuallyInvokeSelectCmd(viewPtr); } } /* *--------------------------------------------------------------------------- * * LostSelection -- * * This procedure is called back by Tk when the selection is grabbed * away. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *--------------------------------------------------------------------------- */ static void LostSelection(ClientData clientData) { ListView *viewPtr = clientData; if (viewPtr->flags & SELECT_EXPORT) { ClearSelection(viewPtr); } } /* *--------------------------------------------------------------------------- * * SelectRange -- * * Sets the selection flag for a range of nodes. The range is * determined by two pointers which designate the first/last * nodes of the range. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int SelectRange(ListView *viewPtr, Item *fromPtr, Item *toPtr) { Blt_ChainLink link; if (fromPtr->index > toPtr->index) { Item *tmpPtr; tmpPtr = fromPtr; fromPtr = toPtr; toPtr = tmpPtr; } for (link = fromPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & ITEM_DISABLED) == 0) { SelectItemUsingFlags(viewPtr, itemPtr); } if (itemPtr->index >= toPtr->index) { break; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionProc -- * * This procedure is called back by Tk when the selection is requested by * someone. It returns part or all of the selection in a buffer provided * by the caller. * * Results: * The return value is the number of non-NULL bytes stored at buffer. * Buffer is filled (or partially filled) with a NUL-terminated string * containing part or all of the selection, as given by offset and * maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int SelectionProc( ClientData clientData, /* Information about the widget. */ int offset, /* Offset within selection of first * character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place at * buffer, not including terminating * NULL character. */ { ListView *viewPtr = clientData; Tcl_DString dString; int size; if ((viewPtr->flags & SELECT_EXPORT) == 0) { return -1; } /* * Retrieve the names of the selected entries. */ Tcl_DStringInit(&dString); if (viewPtr->flags & SELECT_ORDERED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(viewPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); Tcl_DStringAppend(&dString, itemPtr->label, -1); Tcl_DStringAppend(&dString, "\n", -1); } } else { Item *itemPtr; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (ItemIsSelected(viewPtr, itemPtr)) { Tcl_DStringAppend(&dString, itemPtr->label, -1); Tcl_DStringAppend(&dString, "\n", -1); } } } size = Tcl_DStringLength(&dString) - offset; strncpy(buffer, Tcl_DStringValue(&dString) + offset, maxBytes); Tcl_DStringFree(&dString); buffer[maxBytes] = '\0'; return (size > maxBytes) ? maxBytes : size; } /* *--------------------------------------------------------------------------- * * EventuallyRedrawItem -- * * Tells the Tk dispatcher to call the listview display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawItem(Item *itemPtr) { ListView *viewPtr; if (itemPtr->flags & (ITEM_HIDE|ITEM_REDRAW)) { return; } viewPtr = itemPtr->viewPtr; if (viewPtr->flags & REDRAW_PENDING) { return; } if (viewPtr->tkwin != NULL) { Tcl_DoWhenIdle(DisplayItem, itemPtr); itemPtr->flags |= ITEM_REDRAW; } } /* *--------------------------------------------------------------------------- * * ReleaseTags -- * * Releases the tags used by this item. * *--------------------------------------------------------------------------- */ static void ReleaseTags(ListView *viewPtr, Item *itemPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&viewPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tagTablePtr; Blt_HashEntry *h2Ptr; tagTablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tagTablePtr, (char *)itemPtr->index); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tagTablePtr, h2Ptr); } } } static void DestroyItem(Item *itemPtr) { ListView *viewPtr = itemPtr->viewPtr; DeselectItem(viewPtr, itemPtr); ReleaseTags(viewPtr, itemPtr); iconOption.clientData = viewPtr; Blt_FreeOptions(itemSpecs, (char *)itemPtr, viewPtr->display, 0); if (viewPtr->activePtr == itemPtr) { viewPtr->activePtr = NULL; } if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } viewPtr->flags |= LAYOUT_PENDING; Blt_Chain_DeleteLink(viewPtr->chain, itemPtr->link); } static void DestroyItems(ListView *viewPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(viewPtr->chain); link != NULL; link = next) { Item *itemPtr; next = Blt_Chain_NextLink(link); itemPtr = Blt_Chain_GetValue(link); DestroyItem(itemPtr); } if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } viewPtr->flags |= LAYOUT_PENDING; Blt_Chain_Destroy(viewPtr->chain); } static Item * NewItem(ListView *viewPtr) { Item *itemPtr; Blt_ChainLink link; link = Blt_Chain_AllocLink(sizeof(Item)); itemPtr = Blt_Chain_GetValue(link); itemPtr->viewPtr = viewPtr; itemPtr->flags |= ITEM_NORMAL; itemPtr->link = link; itemPtr->index = Blt_Chain_GetLength(viewPtr->chain); Blt_Chain_LinkAfter(viewPtr->chain, link, NULL); itemPtr->label = emptyString; return itemPtr; } static INLINE Item * FindItemByIndex(ListView *viewPtr, long index) { Blt_ChainLink link; if ((index < 1) || (index > Blt_Chain_GetLength(viewPtr->chain))) { return NULL; } link = Blt_Chain_GetNthLink(viewPtr->chain, index - 1); return Blt_Chain_GetValue(link); } static INLINE Item * BeginItem(ListView *viewPtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(viewPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static INLINE Item * EndItem(ListView *viewPtr) { Blt_ChainLink link; link = Blt_Chain_LastLink(viewPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } /* *--------------------------------------------------------------------------- * * ActivateItem -- * * Marks the designated item as active. The item is redrawn with its * active colors. The previously active item is deactivated. If the new * item is NULL, then this means that no new item is to be activated. * * Results: * None. * * Side effects: * Menu items may be scheduled to be drawn. * *--------------------------------------------------------------------------- */ static void ActivateItem(ListView *viewPtr, Item *itemPtr) { if ((viewPtr->activePtr == itemPtr) && (itemPtr != NULL)) { return; /* Item is already active. */ } if (viewPtr->activePtr != NULL) { EventuallyRedrawItem(viewPtr->activePtr); } viewPtr->activePtr = itemPtr; if (itemPtr != NULL) { EventuallyRedrawItem(itemPtr); } } /* *--------------------------------------------------------------------------- * * GetBoundedWidth -- * * Bounds a given width value to the limits described in the limit * structure. The initial starting value may be overridden by the nominal * value in the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedWidth(ListView *viewPtr, int w) { /* * Check widgets for requested width values; */ if (viewPtr->reqWidth.flags & LIMITS_NOM_SET) { w = viewPtr->reqWidth.nom; /* Override initial value */ } if (w < viewPtr->reqWidth.min) { w = viewPtr->reqWidth.min; /* Bounded by minimum value */ } if (w > viewPtr->reqWidth.max) { w = viewPtr->reqWidth.max; /* Bounded by maximum value */ } if (viewPtr->flags & (RESTRICT_MIN|RESTRICT_MAX)) { Tk_Window parent; parent = Tk_Parent(viewPtr->tkwin); if ((viewPtr->flags & RESTRICT_MIN) && (w < Tk_Width(parent))) { w = Tk_Width(parent); } if ((viewPtr->flags & RESTRICT_MAX) && (w > Tk_Width(parent))) { w = Tk_Width(parent); } } { int screenWidth, screenHeight; Blt_SizeOfScreen(viewPtr->tkwin, &screenWidth, &screenHeight); if (w > screenWidth) { w = screenWidth; } } return w; } /* *--------------------------------------------------------------------------- * * GetBoundedHeight -- * * Bounds a given value to the limits described in the limit structure. * The initial starting value may be overridden by the nominal value in * the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedHeight(ListView *viewPtr, int h) { /* * Check widgets for requested height values; */ if (viewPtr->reqHeight.flags & LIMITS_NOM_SET) { h = viewPtr->reqHeight.nom; /* Override initial value */ } if (h < viewPtr->reqHeight.min) { h = viewPtr->reqHeight.min; /* Bounded by minimum value */ } if (h > viewPtr->reqHeight.max) { h = viewPtr->reqHeight.max; /* Bounded by maximum value */ } if (h > HeightOfScreen(Tk_Screen(viewPtr->tkwin))) { h = HeightOfScreen(Tk_Screen(viewPtr->tkwin)); } return h; } static void ComputeIconsItemGeometry(ListView *viewPtr, Item *itemPtr) { Icon icon; /* Determine the height of the item. It's the maximum height of all it's * components: left gadget (radiobutton or checkbutton), icon, label, * right gadget (cascade), and accelerator. */ itemPtr->labelWidth = itemPtr->labelHeight = 0; itemPtr->iconWidth = itemPtr->iconHeight = 0; itemPtr->height = itemPtr->width = 0; if (itemPtr->flags & ITEM_HIDE) { return; } icon = itemPtr->bigIcon; if (icon != NULL) { itemPtr->iconWidth = IconWidth(icon) + 2; itemPtr->iconHeight = IconHeight(icon) + 2; } if (itemPtr->image != NULL) { itemPtr->labelWidth = IconWidth(itemPtr->image); itemPtr->labelHeight = IconHeight(itemPtr->image); itemPtr->labelWidth += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelHeight += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelWidth |= 0x1; itemPtr->labelHeight |= 0x1; } else if (itemPtr->label != emptyString) { unsigned int w, h; Blt_GetTextExtents(itemPtr->stylePtr->labelFont, 0, itemPtr->label, -1, &w, &h); w += 2 * itemPtr->stylePtr->borderWidth; h += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelWidth = w | 0x1; itemPtr->labelHeight = h | 0x1; } if ((itemPtr->iconWidth > 0) && (itemPtr->iconHeight > 0)) { itemPtr->height += itemPtr->iconHeight; if (itemPtr->width < itemPtr->iconWidth) { itemPtr->width = itemPtr->iconWidth; } } if ((itemPtr->labelWidth > 0) && (itemPtr->labelHeight > 0)) { int w; w = itemPtr->labelWidth + 6; itemPtr->height += itemPtr->labelHeight + 6; if (itemPtr->width < w) { itemPtr->width = w; } } if ((itemPtr->labelHeight > 0) && (itemPtr->iconHeight > 0)) { itemPtr->width += ITEM_IPAD; } } static void ComputeListItemGeometry(ListView *viewPtr, Item *itemPtr) { Icon icon; /* Determine the height of the item. It's the maximum height of all it's * components: left gadget (radiobutton or checkbutton), icon, label, * right gadget (cascade), and accelerator. */ itemPtr->labelWidth = itemPtr->labelHeight = 0; itemPtr->iconWidth = itemPtr->iconHeight = 0; itemPtr->height = itemPtr->width = 0; itemPtr->worldWidth = itemPtr->worldHeight = 0; if (itemPtr->flags & ITEM_HIDE) { return; } icon = (viewPtr->layoutMode == LAYOUT_ICONS) ? itemPtr->bigIcon : itemPtr->icon; if (icon != NULL) { itemPtr->iconWidth = IconWidth(icon) + 2; itemPtr->iconHeight = IconHeight(icon) + 2; } if (itemPtr->image != NULL) { itemPtr->labelWidth = IconWidth(itemPtr->image); itemPtr->labelHeight = IconHeight(itemPtr->image); itemPtr->labelWidth += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelHeight += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelWidth |= 0x1; itemPtr->labelHeight |= 0x1; } else if (itemPtr->label != emptyString) { unsigned int w, h; Blt_GetTextExtents(itemPtr->stylePtr->labelFont, 0, itemPtr->label, -1, &w, &h); w += 2 * itemPtr->stylePtr->borderWidth; h += 2 * itemPtr->stylePtr->borderWidth; itemPtr->labelWidth = w | 0x1; itemPtr->labelHeight = h | 0x1; } if ((itemPtr->iconWidth > 0) && (itemPtr->iconHeight > 0)) { itemPtr->width += itemPtr->iconWidth; if (itemPtr->height < itemPtr->iconHeight) { itemPtr->height = itemPtr->iconHeight; } if (viewPtr->iconWidth < itemPtr->iconWidth) { viewPtr->iconWidth = itemPtr->iconWidth; } } if ((itemPtr->labelWidth > 0) && (itemPtr->labelHeight > 0)) { int h; itemPtr->width += itemPtr->labelWidth + 6; h = itemPtr->labelHeight + 6; if (itemPtr->height < h) { itemPtr->height = h; } } if ((itemPtr->labelWidth > 0) && (itemPtr->iconWidth > 0)) { itemPtr->width += ITEM_IPAD; } } /* *--------------------------------------------------------------------------- * * ComputeRowLayout -- * * Computes the layout of the widget with the items displayed * one per row. * *--------------------------------------------------------------------------- */ static void ComputeRowLayout(ListView *viewPtr) { int x, y, w, h; int reqWidth, reqHeight; Item *itemPtr; /* * Step 1. Get the maximum width of all the items. */ x = y = 0; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } itemPtr->worldX = 0; itemPtr->worldY = viewPtr->worldHeight; itemPtr->worldWidth = itemPtr->width; itemPtr->worldHeight = itemPtr->height; ComputeListItemGeometry(viewPtr, itemPtr); if (viewPtr->worldWidth < itemPtr->width) { viewPtr->worldWidth = itemPtr->width; } viewPtr->worldHeight += itemPtr->height; } /* Figure out the requested size of the widget. This will also tell us if * we need scrollbars. */ reqWidth = viewPtr->worldWidth + 2 * viewPtr->inset; reqHeight = viewPtr->worldHeight + 2 * viewPtr->inset; w = GetBoundedWidth(viewPtr, reqWidth); h = GetBoundedHeight(viewPtr, reqHeight); if ((w != Tk_ReqWidth(viewPtr->tkwin)) || (h != Tk_ReqHeight(viewPtr->tkwin))) { Tk_GeometryRequest(viewPtr->tkwin, w, h); } } /* *--------------------------------------------------------------------------- * * ComputeColumnLayout -- * * Computes the layout of the widget with the items displayed multiple * columns. The current height of the widget is used as a basis for the * number of rows in a column. * *--------------------------------------------------------------------------- */ static void ComputeColumnLayout(ListView *viewPtr) { int x, y, w, h; int reqWidth, reqHeight; int maxWidth, maxHeight; int winHeight; int nRows, nColumns, nEntries; int count, lastMaxWidth, maxIconWidth; Item *itemPtr; nEntries = maxWidth = maxHeight = maxIconWidth = 0; viewPtr->itemHeight = 0; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } ComputeListItemGeometry(viewPtr, itemPtr); if (maxIconWidth < itemPtr->iconWidth) { maxIconWidth = itemPtr->iconWidth; } if (maxWidth < itemPtr->width) { maxWidth = itemPtr->width; } if (maxHeight < itemPtr->height) { maxHeight = itemPtr->height; } nEntries++; } if (nEntries == 0) { return; } winHeight = VPORTHEIGHT(viewPtr); if (winHeight <= 1) { winHeight = Tk_ReqHeight(viewPtr->tkwin) - 2 * viewPtr->inset; } nRows = winHeight / maxHeight; if (nRows <= 0) { nRows = 1; } nColumns = nEntries / nRows; /* Now compute the worldX positions */ x = y = 0; count = 0; lastMaxWidth = 0; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } itemPtr->worldX = x; itemPtr->worldY = y; itemPtr->worldWidth = itemPtr->width; itemPtr->worldHeight = maxHeight; if (itemPtr->width > lastMaxWidth) { lastMaxWidth = itemPtr->width; } itemPtr->iconX = 1 + (maxIconWidth - itemPtr->iconWidth) / 2; itemPtr->iconY = 1 + (maxHeight - itemPtr->iconHeight) / 2; itemPtr->labelX = 2 + maxIconWidth; if ((itemPtr->labelWidth > 0) && (itemPtr->iconWidth > 0)) { itemPtr->labelX += ITEM_IPAD; } itemPtr->labelY = 1 + (maxHeight - itemPtr->labelHeight) / 2; y += maxHeight; count++; if ((count % nRows) == 0) { x += lastMaxWidth; y = 0; lastMaxWidth = 0; } } if (count > 0) { x += lastMaxWidth; } viewPtr->worldWidth = x; viewPtr->worldHeight = nRows * maxHeight; reqWidth = viewPtr->worldWidth + 2 * viewPtr->inset; reqHeight = viewPtr->worldHeight + 2 * viewPtr->inset; w = GetBoundedWidth(viewPtr, reqWidth); h = GetBoundedHeight(viewPtr, reqHeight); if ((w != Tk_ReqWidth(viewPtr->tkwin)) || (h != Tk_ReqHeight(viewPtr->tkwin))) { Tk_GeometryRequest(viewPtr->tkwin, w, h); } } /* *--------------------------------------------------------------------------- * * ComputeIconsLayout -- * * Computes the layout of the widget with the items displayed multiple * columns. The current height of the widget is used as a basis for the * number of rows in a column. * *--------------------------------------------------------------------------- */ static void ComputeIconsLayout(ListView *viewPtr) { int x, y, w, h; int reqWidth, reqHeight; int maxHeight, maxWidth; int winWidth; int nRows, nColumns, nEntries; int count; Item *itemPtr; maxHeight = maxWidth = 0; nEntries = 0; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } ComputeIconsItemGeometry(viewPtr, itemPtr); if (maxWidth < itemPtr->width) { maxWidth = itemPtr->width; } if (maxHeight < itemPtr->height) { maxHeight = itemPtr->height; } if (itemPtr->height > viewPtr->itemHeight) { viewPtr->itemHeight = itemPtr->height; } nEntries++; } if (nEntries == 0) { return; } winWidth = VPORTWIDTH(viewPtr); if (winWidth <= 1) { winWidth = Tk_ReqWidth(viewPtr->tkwin) - 2 * viewPtr->inset; } if ((viewPtr->maxWidth > 0) && (viewPtr->maxWidth < maxWidth)) { maxWidth = viewPtr->maxWidth; } nColumns = winWidth / maxWidth; if (nColumns <= 0) { nColumns = 1; } maxWidth = winWidth / nColumns; viewPtr->labelWidth = maxWidth - 6; nRows = nEntries / nColumns; /* Now compute the worldX positions */ x = y = 0; count = 0; maxHeight = 0; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } if (itemPtr->height > maxHeight) { maxHeight = itemPtr->height; } itemPtr->worldX = x; itemPtr->worldY = y; itemPtr->worldWidth = maxWidth; itemPtr->worldHeight = maxHeight; itemPtr->iconX = (maxWidth - itemPtr->iconWidth) / 2; itemPtr->iconY = 1; itemPtr->labelX = 1; if (maxWidth > itemPtr->labelWidth) { itemPtr->labelX = (maxWidth - itemPtr->labelWidth) / 2; } itemPtr->labelY = itemPtr->iconHeight; if ((itemPtr->labelHeight > 0) && (itemPtr->iconHeight > 0)) { /* itemPtr->labelY += ITEM_IPAD; */ } x += maxWidth; count++; if ((count % nColumns) == 0) { y += maxHeight; viewPtr->worldHeight += maxHeight; maxHeight = 0; x = 0; } } if (count > 0) { x += maxWidth; viewPtr->worldHeight += maxHeight; } viewPtr->worldWidth = nColumns * maxWidth; reqWidth = viewPtr->worldWidth + 2 * viewPtr->inset; reqHeight = viewPtr->worldHeight + 2 * viewPtr->inset; w = GetBoundedWidth(viewPtr, reqWidth); h = GetBoundedHeight(viewPtr, reqHeight); if ((w != Tk_ReqWidth(viewPtr->tkwin)) || (h != Tk_ReqHeight(viewPtr->tkwin))) { Tk_GeometryRequest(viewPtr->tkwin, w, h); } } /* *--------------------------------------------------------------------------- * * ComputeLayout -- * * Computes the layout of the widget with the items displayed multiple * columns. The current height of the widget is used as a basis for the * number of rows in a column. * *--------------------------------------------------------------------------- */ static void ComputeLayout(ListView *viewPtr) { int viewWidth, viewHeight; viewPtr->worldWidth = viewPtr->worldHeight = 0; viewPtr->iconWidth = viewPtr->labelWidth = 0; viewPtr->labelWidth = -1; viewPtr->itemHeight = 0; switch (viewPtr->layoutMode) { case LAYOUT_LIST_ROW: ComputeRowLayout(viewPtr); break; case LAYOUT_LIST_COLUMN: ComputeColumnLayout(viewPtr); break; case LAYOUT_ICONS: ComputeIconsLayout(viewPtr); break; case LAYOUT_TILES: fprintf(stderr, "layout not implemented\n"); break; } viewWidth = VPORTWIDTH(viewPtr); if (viewPtr->xOffset > (viewPtr->worldWidth - viewWidth)) { viewPtr->xOffset = viewPtr->worldWidth - viewWidth; } if (viewPtr->xOffset < 0) { viewPtr->xOffset = 0; } viewHeight = VPORTHEIGHT(viewPtr); if (viewPtr->yOffset > (viewPtr->worldHeight - viewHeight)) { viewPtr->yOffset = viewPtr->worldHeight - viewHeight; } if (viewPtr->yOffset < 0) { viewPtr->yOffset = 0; } viewPtr->flags &= ~LAYOUT_PENDING; viewPtr->flags |= SCROLL_PENDING; } /* *--------------------------------------------------------------------------- * * SearchForItem -- * * Performs a binary search for the item at the given y-offset in world * coordinates. The range of items is specified by menu indices (high * and low). The item must be (visible) in the viewport. * * Results: * Returns 0 if no item is found, other the index of the item (menu * indices start from 1). * *--------------------------------------------------------------------------- */ static Item * SearchForItem(ListView *viewPtr, int x, int y) { Item *itemPtr; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->flags & ITEM_HIDE) { continue; } if ((x >= itemPtr->worldX) && (x < (itemPtr->worldX+itemPtr->worldWidth)) && (y >= itemPtr->worldY) && (y < (itemPtr->worldY+itemPtr->worldHeight))) { return itemPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * NearestItem -- * * Find the item closest to the x-y screen coordinate given. The item * must be (visible) in the viewport. * * Results: * Returns the closest item. If selectOne is set, then always returns an * item (unless the menu is empty). Otherwise, NULL is returned is the * pointer is not over an item. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Item * NearestItem(ListView *viewPtr, int x, int y, int selectOne) { Item *itemPtr; if ((x < 0) || (x >= Tk_Width(viewPtr->tkwin)) || (y < 0) || (y >= Tk_Height(viewPtr->tkwin))) { return NULL; /* Screen coordinates are outside of * menu. */ } /* * Item positions are saved in world coordinates. Convert the text point * screen y-coordinate to a world coordinate. */ itemPtr = SearchForItem(viewPtr, WORLDX(viewPtr, x), WORLDY(viewPtr, y)); if (itemPtr == NULL) { if (!selectOne) { return NULL; } if (y < viewPtr->inset) { return FirstItem(viewPtr); } return LastItem(viewPtr); } return itemPtr; } static void DestroyStyle(Style *stylePtr) { ListView *viewPtr; stylePtr->refCount--; if (stylePtr->refCount > 0) { return; } viewPtr = stylePtr->viewPtr; iconOption.clientData = viewPtr; Blt_FreeOptions(styleSpecs, (char *)stylePtr, viewPtr->display, 0); if (stylePtr->hPtr != NULL) { Blt_DeleteHashEntry(&stylePtr->viewPtr->styleTable, stylePtr->hPtr); } if (stylePtr != &stylePtr->viewPtr->defStyle) { Blt_Free(stylePtr); } } static Style * AddDefaultStyle(Tcl_Interp *interp, ListView *viewPtr) { Blt_HashEntry *hPtr; int isNew; Style *stylePtr; hPtr = Blt_CreateHashEntry(&viewPtr->styleTable, "default", &isNew); if (!isNew) { Tcl_AppendResult(interp, "listview style \"", "default", "\" already exists.", (char *)NULL); return NULL; } stylePtr = &viewPtr->defStyle; assert(stylePtr); stylePtr->refCount = 1; stylePtr->name = Blt_GetHashKey(&viewPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->viewPtr = viewPtr; stylePtr->borderWidth = 0; stylePtr->activeRelief = TK_RELIEF_FLAT; Blt_SetHashValue(hPtr, stylePtr); return TCL_OK; } static void DestroyStyles(ListView *viewPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&viewPtr->styleTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Style *stylePtr; stylePtr = Blt_GetHashValue(hPtr); stylePtr->hPtr = NULL; stylePtr->refCount = 0; DestroyStyle(stylePtr); } Blt_DeleteHashTable(&viewPtr->styleTable); } /* *--------------------------------------------------------------------------- * * GetStyleFromObj -- * * Gets the style associated with the given name. * *--------------------------------------------------------------------------- */ static int GetStyleFromObj(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, Style **stylePtrPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->styleTable, Tcl_GetString(objPtr)); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find style \"", Tcl_GetString(objPtr), "\" in listview \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *stylePtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetTag -- * * Associates a tag with a given row. Individual row tags are * stored in hash tables keyed by the tag name. Each table is in * turn stored in a hash table keyed by the row location. * * Results: * None. * * Side Effects: * A tag is stored for a particular row. * *--------------------------------------------------------------------------- */ static int SetTag(Tcl_Interp *interp, Item *itemPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; ListView *viewPtr; int isNew; long dummy; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Don't need to create reserved * tags. */ } if (tagName[0] == '\0') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be empty.", (char *)NULL); } return TCL_ERROR; } if (tagName[0] == '-') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't start with a '-'.", (char *)NULL); } return TCL_ERROR; } if (Tcl_GetLong(NULL, (char *)tagName, &dummy) == TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be a number.", (char *)NULL); } return TCL_ERROR; } viewPtr = itemPtr->viewPtr; hPtr = Blt_CreateHashEntry(&viewPtr->tagTable, tagName, &isNew); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't add tag \"", tagName, "\": out of memory", (char *)NULL); } return TCL_ERROR; } if (isNew) { tagTablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tagTablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tagTablePtr); } else { tagTablePtr = Blt_GetHashValue(hPtr); } hPtr = Blt_CreateHashEntry(tagTablePtr, (char *)itemPtr->index, &isNew); if (isNew) { Blt_SetHashValue(hPtr, itemPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetTagTable -- * * Returns the hash table containing row indices for a tag. * * Results: * Returns a pointer to the hash table containing indices for the * given tag. If the row has no tags, then NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_HashTable * GetTagTable(ListView *viewPtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->tagTable, tagName); if (hPtr == NULL) { return NULL; /* No tag by that name. */ } return Blt_GetHashValue(hPtr); } static int GetIconFromObj(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, Icon *iconPtr) { Blt_HashEntry *hPtr; struct _Icon *iPtr; int isNew; const char *iconName; iconName = Tcl_GetString(objPtr); if (iconName[0] == '\0') { *iconPtr = NULL; return TCL_OK; } hPtr = Blt_CreateHashEntry(&viewPtr->iconTable, iconName, &isNew); if (isNew) { Tk_Image tkImage; int w, h; tkImage = Tk_GetImage(interp, viewPtr->tkwin, (char *)iconName, IconChangedProc, viewPtr); if (tkImage == NULL) { Blt_DeleteHashEntry(&viewPtr->iconTable, hPtr); return TCL_ERROR; } Tk_SizeOfImage(tkImage, &w, &h); iPtr = Blt_AssertMalloc(sizeof(struct _Icon )); iPtr->tkImage = tkImage; iPtr->hPtr = hPtr; iPtr->refCount = 1; iPtr->width = w; iPtr->height = h; Blt_SetHashValue(hPtr, iPtr); } else { iPtr = Blt_GetHashValue(hPtr); iPtr->refCount++; } *iconPtr = iPtr; return TCL_OK; } static void FreeIcon(ListView *viewPtr, struct _Icon *iPtr) { iPtr->refCount--; if (iPtr->refCount == 0) { Blt_DeleteHashEntry(&viewPtr->iconTable, iPtr->hPtr); Tk_FreeImage(iPtr->tkImage); Blt_Free(iPtr); } } static void DestroyIcons(ListView *viewPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&viewPtr->iconTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Icon icon; icon = Blt_GetHashValue(hPtr); Tk_FreeImage(IconImage(icon)); Blt_Free(icon); } Blt_DeleteHashTable(&viewPtr->iconTable); } static INLINE Item * FindItemByLabel(ListView *viewPtr, const char *label) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->labelTable, label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; Blt_HashSearch iter; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FirstHashEntry(tablePtr, &iter); if (h2Ptr != NULL) { return Blt_GetHashValue(h2Ptr); } } return NULL; } static char * NewLabel(Item *itemPtr, const char *label) { Blt_HashEntry *hPtr, *h2Ptr; Blt_HashTable *tablePtr; int isNew; ListView *viewPtr; viewPtr = itemPtr->viewPtr; hPtr = Blt_CreateHashEntry(&viewPtr->labelTable, label, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } h2Ptr = Blt_CreateHashEntry(tablePtr, (char *)itemPtr, &isNew); Blt_SetHashValue(h2Ptr, itemPtr); return Blt_GetHashKey(&viewPtr->labelTable, hPtr); } static void RemoveLabel(ListView *viewPtr, Item *itemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->labelTable, itemPtr->label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)itemPtr); if (h2Ptr != NULL) { itemPtr->label = emptyString; Blt_DeleteHashEntry(tablePtr, h2Ptr); if (tablePtr->numEntries == 0) { Blt_DeleteHashEntry(&viewPtr->labelTable, hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } } } } static void DestroyLabels(ListView *viewPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&viewPtr->labelTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&viewPtr->labelTable); } static void MoveItem(ListView *viewPtr, Item *itemPtr, int dir, Item *wherePtr) { if (Blt_Chain_GetLength(viewPtr->chain) == 1) { return; /* Can't rearrange one item. */ } Blt_Chain_UnlinkLink(viewPtr->chain, itemPtr->link); switch(dir) { case 0: /* After */ Blt_Chain_LinkAfter(viewPtr->chain, itemPtr->link, wherePtr->link); break; case 1: /* At */ Blt_Chain_LinkAfter(viewPtr->chain, itemPtr->link, wherePtr->link); break; default: case 2: /* Before */ Blt_Chain_LinkBefore(viewPtr->chain, itemPtr->link, wherePtr->link); break; } { long count; for (count = 0, itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr), count++) { itemPtr->index = count; } } } /* *--------------------------------------------------------------------------- * * NextTaggedItem -- * * Returns the next item derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows can be * found, then NULL is returned. * *--------------------------------------------------------------------------- */ static Item * NextTaggedItem(ItemIterator *iterPtr) { Item *itemPtr; switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } break; case ITER_ALL: if (iterPtr->link != NULL) { itemPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return itemPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(itemPtr->label, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return itemPtr; } } break; } default: break; } return NULL; } /* *--------------------------------------------------------------------------- * * FirstTaggedItem -- * * Returns the first item derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows can be * found, then -1 is returned. * *--------------------------------------------------------------------------- */ static Item * FirstTaggedItem(ItemIterator *iterPtr) { Item *itemPtr; switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } break; case ITER_ALL: if (iterPtr->link != NULL) { itemPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return itemPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(itemPtr->label, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return itemPtr; } } } break; case ITER_SINGLE: itemPtr = iterPtr->startPtr; iterPtr->nextPtr = NextTaggedItem(iterPtr); return itemPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * GetItemFromObj -- * * Get the item associated the given index, tag, or label. This routine * is used when you want only one item. It's an error if more than one * item is specified (e.g. "all" tag). It's also an error if the tag is * empty (no items are currently tagged). * *--------------------------------------------------------------------------- */ static int GetItemFromObj(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, Item **itemPtrPtr) { ItemIterator iter; Item *firstPtr; if (GetItemIterator(interp, viewPtr, objPtr, &iter) != TCL_OK) { return TCL_ERROR; } firstPtr = FirstTaggedItem(&iter); if (firstPtr != NULL) { Item *nextPtr; nextPtr = NextTaggedItem(&iter); if (nextPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple items specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } *itemPtrPtr = firstPtr; return TCL_OK; } static int GetItemByIndex(Tcl_Interp *interp, ListView *viewPtr, const char *string, int length, Item **itemPtrPtr) { Item *itemPtr; char c; long pos; itemPtr = NULL; c = string[0]; if ((isdigit(c)) && (Tcl_GetLong(NULL, string, &pos) == TCL_OK)) { Blt_ChainLink link; link = Blt_Chain_GetNthLink(viewPtr->chain, pos); if (link != NULL) { itemPtr = Blt_Chain_GetValue(link); } if (itemPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item: bad index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } } else if ((c == 'n') && (strcmp(string, "next") == 0)) { itemPtr = NextItemAvailable(viewPtr->focusPtr); if (itemPtr == NULL) { itemPtr = viewPtr->focusPtr; } } else if ((c == 'p') && (strcmp(string, "previous") == 0)) { itemPtr = PrevItemAvailable(viewPtr->focusPtr); if (itemPtr == NULL) { itemPtr = viewPtr->focusPtr; } } else if ((c == 'e') && (strcmp(string, "end") == 0)) { itemPtr = LastItem(viewPtr); } else if ((c == 'f') && (strcmp(string, "first") == 0)) { itemPtr = FirstItem(viewPtr); } else if ((c == 'l') && (strcmp(string, "last") == 0)) { itemPtr = LastItem(viewPtr); } else if ((c == 'n') && (strcmp(string, "none") == 0)) { itemPtr = NULL; } else if ((c == 'a') && (strcmp(string, "active") == 0)) { itemPtr = viewPtr->activePtr; } else if ((c == 'f') && (strcmp(string, "focus") == 0)) { itemPtr = viewPtr->focusPtr; } else if (c == '@') { int x, y; if (Blt_GetXY(viewPtr->interp, viewPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } itemPtr = NearestItem(viewPtr, x, y, FALSE); } else { return TCL_CONTINUE; } *itemPtrPtr = itemPtr; return TCL_OK; } static Item * GetItemByLabel(ListView *viewPtr, const char *string) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->labelTable, string); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; Blt_HashSearch iter; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FirstHashEntry(tablePtr, &iter); if (h2Ptr != NULL) { return Blt_GetHashValue(h2Ptr); } } return NULL; } /* *--------------------------------------------------------------------------- * * GetItemIterator -- * * Converts a string representing a item index into an item pointer. The * index may be in one of the following forms: * * number Item at index in the list of items. * @x,y Item closest to the specified X-Y screen coordinates. * "active" Item where mouse pointer is located. * "posted" Item is the currently posted cascade item. * "next" Next item from the focus item. * "previous" Previous item from the focus item. * "end" Last item. * "none" No item. * * number Item at position in the list of items. * @x,y Item closest to the specified X-Y screen coordinates. * "active" Item mouse is located over. * "focus" Item is the widget's focus. * "select" Currently selected item. * "right" Next item from the focus item. * "left" Previous item from the focus item. * "up" Next item from the focus item. * "down" Previous item from the focus item. * "end" Last item in list. * "index:number" Item at index number in list of items. * "tag:string" Item(s) tagged by "string". * "label:pattern" Item(s) with label matching "pattern". * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via itemPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetItemIterator(Tcl_Interp *interp, ListView *viewPtr, Tcl_Obj *objPtr, ItemIterator *iterPtr) { Item *itemPtr, *startPtr, *endPtr; Blt_HashTable *tablePtr; char *string; char c; int nBytes; int length; int result; iterPtr->viewPtr = viewPtr; iterPtr->type = ITER_SINGLE; iterPtr->tagName = Tcl_GetStringFromObj(objPtr, &nBytes); iterPtr->nextPtr = NULL; iterPtr->startPtr = iterPtr->endPtr = NULL; if (viewPtr->flags & LAYOUT_PENDING) { ComputeLayout(viewPtr); } string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; iterPtr->startPtr = iterPtr->endPtr = viewPtr->activePtr; startPtr = endPtr = itemPtr = NULL; if (c == '\0') { startPtr = endPtr = NULL; } iterPtr->type = ITER_SINGLE; result = GetItemByIndex(interp, viewPtr, string, length, &itemPtr); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_OK) { iterPtr->startPtr = iterPtr->endPtr = itemPtr; return TCL_OK; } if ((c == 'a') && (strcmp(iterPtr->tagName, "all") == 0)) { iterPtr->type = ITER_ALL; iterPtr->link = Blt_Chain_FirstLink(viewPtr->chain); } else if ((c == 'i') && (length > 6) && (strncmp(string, "index:", 6) == 0)) { if (GetItemByIndex(interp, viewPtr, string + 6, length - 6, &itemPtr) != TCL_OK) { return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = itemPtr; } else if ((c == 't') && (length > 4) && (strncmp(string, "tag:", 4) == 0)) { Blt_HashTable *tablePtr; tablePtr = GetTagTable(viewPtr, string + 4); if (tablePtr == NULL) { Tcl_AppendResult(interp, "can't find a tag \"", string + 5, "\" in \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } iterPtr->tagName = string + 4; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else if ((c == 'l') && (length > 6) && (strncmp(string, "label:", 6) == 0)) { iterPtr->link = Blt_Chain_FirstLink(viewPtr->chain); iterPtr->tagName = string + 6; iterPtr->type = ITER_PATTERN; } else if ((itemPtr = GetItemByLabel(viewPtr, string)) != NULL) { iterPtr->startPtr = iterPtr->endPtr = itemPtr; } else if ((tablePtr = GetTagTable(viewPtr, string)) != NULL) { iterPtr->tagName = string; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item index, label, or tag \"", string, "\" in \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } return TCL_OK; } static int ConfigureItem(Tcl_Interp *interp, Item *itemPtr, int objc, Tcl_Obj *const *objv, int flags) { ListView *viewPtr; viewPtr = itemPtr->viewPtr; iconOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, itemSpecs, objc, objv, (char *)itemPtr, flags) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= LAYOUT_PENDING; return TCL_OK; } static int ConfigureStyle(Tcl_Interp *interp, Style *stylePtr, int objc, Tcl_Obj *const *objv, int flags) { ListView *viewPtr = stylePtr->viewPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, styleSpecs, objc, objv, (char *)stylePtr, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static int ConfigureListView(Tcl_Interp *interp, ListView *viewPtr, int objc, Tcl_Obj *const *objv, int flags) { unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, listViewSpecs, objc, objv, (char *)viewPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureStyle(interp, &viewPtr->defStyle, 0, NULL, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } viewPtr->inset = viewPtr->borderWidth + viewPtr->highlightWidth; /* Focus rectangle */ gcMask = GCForeground | GCLineWidth | GCLineStyle | GCDashList; gcValues.line_width = 0; gcValues.foreground = viewPtr->focusColor->pixel; gcValues.line_style = LineOnOffDash; gcValues.dashes = 1; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (viewPtr->focusGC != NULL) { Tk_FreeGC(viewPtr->display, viewPtr->focusGC); } viewPtr->focusGC = newGC; return TCL_OK; } /* Widget Callbacks */ /* *--------------------------------------------------------------------------- * * ListViewEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * listview widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ListViewEventProc(ClientData clientData, XEvent *eventPtr) { ListView *viewPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(viewPtr); } } else if (eventPtr->type == UnmapNotify) { EventuallyRedraw(viewPtr); } else if (eventPtr->type == ConfigureNotify) { viewPtr->flags |= (SCROLL_PENDING | LAYOUT_PENDING); EventuallyRedraw(viewPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { viewPtr->flags |= FOCUS; } else { viewPtr->flags &= ~FOCUS; } EventuallyRedraw(viewPtr); } else if (eventPtr->type == DestroyNotify) { if (viewPtr->tkwin != NULL) { viewPtr->tkwin = NULL; } if (viewPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayListView, viewPtr); } Tcl_EventuallyFree(viewPtr, DestroyListView); } } /*ARGSUSED*/ static void FreeStyleProc(ClientData clientData, Display *display, char *widgRec, int offset) { Style *stylePtr = *(Style **)(widgRec + offset); if ((stylePtr != NULL) && (stylePtr != &stylePtr->viewPtr->defStyle)) { DestroyStyle(stylePtr); } } /* *--------------------------------------------------------------------------- * * ObjToStyleProc -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyleProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ListView *viewPtr; Item *itemPtr = (Item *)widgRec; Style **stylePtrPtr = (Style **)(widgRec + offset); Style *stylePtr; char *string; string = Tcl_GetString(objPtr); viewPtr = itemPtr->viewPtr; if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { stylePtr = NULL; } else if (GetStyleFromObj(interp, viewPtr, objPtr, &stylePtr) != TCL_OK) { return TCL_ERROR; } /* Release the old style. */ if ((*stylePtrPtr != NULL) && (*stylePtrPtr != &viewPtr->defStyle)) { DestroyStyle(*stylePtrPtr); } stylePtr->refCount++; *stylePtrPtr = stylePtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StyleToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Style *stylePtr = *(Style **)(widgRec + offset); Tcl_Obj *objPtr; if (stylePtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(stylePtr->name, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToRestrictProc -- * * Convert the string representation of an item state into a flag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToRestrictProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "min") == 0) { flag = RESTRICT_MIN; } else if (strcmp(string, "max") == 0) { flag = RESTRICT_MAX; } else if (strcmp(string, "both") == 0) { flag = RESTRICT_MIN|RESTRICT_MAX; } else if (strcmp(string, "none") == 0) { flag = 0; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~(RESTRICT_MIN|RESTRICT_MAX); *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * RestrictToObjProc -- * * Return the string representation of the restrict flags. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * RestrictToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); int restrict; const char *string; restrict = *flagsPtr & (RESTRICT_MIN|RESTRICT_MAX); switch (restrict) { case RESTRICT_MIN: string = "min"; break; case RESTRICT_MAX: string = "max"; break; case RESTRICT_NONE: string = "none"; break; case (RESTRICT_MIN|RESTRICT_MAX): string = "both"; break; } return Tcl_NewStringObj(string, -1); return NULL; } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Convert the string representation of an item state into a flag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; ListView *viewPtr; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "disabled") == 0) { flag = ITEM_DISABLED; } else if (strcmp(string, "normal") == 0) { flag = ITEM_NORMAL; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } if (itemPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } viewPtr = itemPtr->viewPtr; if (viewPtr->activePtr != itemPtr) { ActivateItem(viewPtr, NULL); viewPtr->activePtr = NULL; } *flagsPtr &= ~ITEM_STATE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); Tcl_Obj *objPtr; if (state & ITEM_NORMAL) { objPtr = Tcl_NewStringObj("normal", -1); } else if (state & ITEM_DISABLED) { objPtr = Tcl_NewStringObj("disabled", -1); } else { objPtr = Tcl_NewStringObj("???", -1); } return objPtr; } /*ARGSUSED*/ static void FreeTagsProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { ListView *viewPtr; Item *itemPtr = (Item *)widgRec; viewPtr = itemPtr->viewPtr; ReleaseTags(viewPtr, itemPtr); } /* *--------------------------------------------------------------------------- * * ObjToTagsProc -- * * Convert the string representation of a list of tags. * * Results: * The return value is a standard TCL result. The tags are * save in the widget. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTagsProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ListView *viewPtr; Item *itemPtr = (Item *)widgRec; int i; char *string; int objc; Tcl_Obj **objv; viewPtr = itemPtr->viewPtr; ReleaseTags(viewPtr, itemPtr); string = Tcl_GetString(objPtr); if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < objc; i++) { SetTag(interp, itemPtr, Tcl_GetString(objv[i])); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagsToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TagsToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Blt_HashEntry *hPtr; Blt_HashSearch iter; ListView *viewPtr; Item *itemPtr = (Item *)widgRec; Tcl_Obj *listObjPtr; viewPtr = itemPtr->viewPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&viewPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tagTablePtr; Blt_HashEntry *h2Ptr; tagTablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tagTablePtr, (char *)itemPtr->index); if (h2Ptr != NULL) { Tcl_Obj *objPtr; const char *name; name = Tcl_GetHashKey(&viewPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { ListView *viewPtr = clientData; viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(viewPtr); } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Convert a image into a hashed icon. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ListView *viewPtr = clientData; Icon *iconPtr = (Icon *)(widgRec + offset); Icon icon; if (GetIconFromObj(interp, viewPtr, objPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (*iconPtr != NULL) { FreeIcon(viewPtr, *iconPtr); } *iconPtr = icon; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon icon = *(Icon *)(widgRec + offset); Tcl_Obj *objPtr; if (icon == NULL) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr =Tcl_NewStringObj(Blt_Image_Name(IconImage(icon)), -1); } return objPtr; } /*ARGSUSED*/ static void FreeIconProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Icon *iconPtr = (Icon *)(widgRec + offset); if (*iconPtr != NULL) { ListView *viewPtr = clientData; FreeIcon(viewPtr, *iconPtr); *iconPtr = NULL; } } /*ARGSUSED*/ static void FreeLabelProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Item *itemPtr = (Item *)widgRec; if (itemPtr->label != emptyString) { RemoveLabel(itemPtr->viewPtr, itemPtr); } } /* *--------------------------------------------------------------------------- * * ObjToLabelProc -- * * Save the label and add the item to the label hashtable. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLabelProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); char *string; if (itemPtr->label != emptyString) { RemoveLabel(itemPtr->viewPtr, itemPtr); } string = Tcl_GetString(objPtr); if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } itemPtr->label = NewLabel(itemPtr, string); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LabelToObjProc -- * * Return the label of the item. * * Results: * The label is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LabelToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); Tcl_Obj *objPtr; if (itemPtr->label == emptyString) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(itemPtr->label, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ItemSwitch -- * * Convert a string representing an item into its pointer. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ItemSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Item **itemPtrPtr = (Item **)(record + offset); ListView *viewPtr = clientData; Item *itemPtr; if (GetItemFromObj(interp, viewPtr, objPtr, &itemPtr) != TCL_OK) { return TCL_ERROR; } *itemPtrPtr = itemPtr; return TCL_OK; } /* Widget Operations */ /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm activate item * *--------------------------------------------------------------------------- */ static int ActivateOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->activePtr == itemPtr) { return TCL_OK; /* Item is already active. */ } ActivateItem(viewPtr, NULL); viewPtr->activePtr = NULL; if ((itemPtr != NULL) && ((itemPtr->flags & (ITEM_DISABLED|ITEM_HIDE))==0)){ ActivateItem(viewPtr, itemPtr); viewPtr->activePtr = itemPtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Appends a new item to the listview. * * Results: * NULL is always returned. * * Side effects: * The listview entry may become selected or deselected. * * .cm add -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int AddOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; itemPtr = NewItem(viewPtr); if (ConfigureItem(interp, itemPtr, objc - 2, objv + 2, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } viewPtr->flags |= LAYOUT_PENDING; viewPtr->flags &= ~SORTED; EventuallyRedraw(viewPtr); Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddListOp -- * * Appends a list of items to the listview. * * Results: * A standard TCL result. * * Side effects: * New items are added to the listview. * * .cm add labelList -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int AddListOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; int iobjc; Tcl_Obj **iobjv; Tcl_Obj *listObjPtr; if (Tcl_ListObjGetElements(interp, objv[2], &iobjc, &iobjv) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 0; i < iobjc; i++) { Tcl_Obj *objPtr; Item *itemPtr; itemPtr = NewItem(viewPtr); if (ConfigureItem(interp, itemPtr, objc - 3, objv + 3, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; } itemPtr->label = NewLabel(itemPtr, Tcl_GetString(iobjv[i])); objPtr = Tcl_NewLongObj(itemPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } viewPtr->flags |= LAYOUT_PENDING; viewPtr->flags &= ~SORTED; EventuallyRedraw(viewPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; iconOption.clientData = viewPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, listViewSpecs, (char *)viewPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, listViewSpecs, (char *)viewPtr, objv[2], 0); } Tcl_Preserve(viewPtr); result = ConfigureListView(interp, viewPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(viewPtr); if (result == TCL_ERROR) { return TCL_ERROR; } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm cget option * *--------------------------------------------------------------------------- */ static int CgetOp( ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = viewPtr; return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, listViewSpecs, (char *)viewPtr, objv[2], 0); } /*ARGSUSED*/ static int CurselectionOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (viewPtr->flags & SELECT_ORDERED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(viewPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; Tcl_Obj *objPtr; itemPtr = Blt_Chain_GetValue(link); objPtr = Tcl_NewLongObj(itemPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Item *itemPtr; for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (ItemIsSelected(viewPtr, itemPtr)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(itemPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm delete item... * *--------------------------------------------------------------------------- */ static int DeleteOp( ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { ItemIterator iter; Item *itemPtr, *nextPtr; if (GetItemIterator(interp, viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (itemPtr = FirstTaggedItem(&iter); itemPtr != NULL; itemPtr = nextPtr) { nextPtr = NextTaggedItem(&iter); DestroyItem(itemPtr); } } EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExistsOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm exists item * *--------------------------------------------------------------------------- */ static int ExistsOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int bool; bool = FALSE; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) == TCL_OK) { if (itemPtr != NULL) { bool = TRUE; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindOp -- * * Search for an item according to the string given. * * Results: * The index of the found item is returned. If no item is found * -1 is returned. * * .cm find string -from active -previous -all -count 1 * .cm find pattern \ * -type glob|regexp|exact \ * -from item -to item \ * -previous -wrap \ * -count 1 * *--------------------------------------------------------------------------- */ static int FindOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { FindSwitches switches; Tcl_Obj *listObjPtr; const char *pattern; long count; /* Process switches */ pattern = Tcl_GetString(objv[2]); itemSwitch.clientData = viewPtr; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, findSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.fromPtr == NULL) { switches.fromPtr = FirstItem(viewPtr); } if (switches.toPtr == NULL) { switches.toPtr = LastItem(viewPtr); } if ((switches.fromPtr->index > switches.toPtr->index) && ((switches.flags & FIND_REVERSE) == 0)) { switches.flags |= FIND_WRAP; } if ((switches.fromPtr->index < switches.toPtr->index) && (switches.flags & FIND_REVERSE)) { switches.flags |= FIND_WRAP; } count = 0; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (switches.flags & FIND_REVERSE) { Item *itemPtr, *prevPtr; for (itemPtr = switches.fromPtr; itemPtr != NULL; itemPtr = prevPtr) { int found; prevPtr = PrevItem(itemPtr); if ((prevPtr == NULL) && (switches.flags & FIND_WRAP)) { itemPtr = LastItem(viewPtr); } if ((itemPtr->flags & ITEM_HIDE) && ((switches.flags & FIND_HIDDEN) == 0)) { continue; } if ((itemPtr->flags & ITEM_DISABLED) && ((switches.flags & FIND_DISABLED) == 0)) { continue; } if (switches.flags & FIND_EXACT) { found = (strcmp(itemPtr->label, pattern) == 0); } else if (switches.flags & FIND_REGEXP) { found = Tcl_RegExpMatch(NULL, itemPtr->label, pattern); } else { found = Tcl_StringMatch(itemPtr->label, pattern); } if (found) { count++; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(itemPtr->index)); if (switches.count == count) { break; } } if ((itemPtr == switches.toPtr) && ((switches.flags & FIND_WRAP) == 0)) { break; } if (prevPtr == switches.fromPtr) { break; } } } else { Item *itemPtr, *nextPtr; for (itemPtr = switches.fromPtr; itemPtr != NULL; itemPtr = nextPtr) { int found; nextPtr = NextItem(itemPtr); if ((nextPtr == NULL) && (switches.flags & FIND_WRAP)) { nextPtr = FirstItem(viewPtr); } if ((itemPtr->flags & ITEM_HIDE) && ((switches.flags & FIND_HIDDEN) == 0)) { continue; } if ((itemPtr->flags & ITEM_DISABLED) && ((switches.flags & FIND_DISABLED) == 0)) { continue; } if (switches.flags & FIND_EXACT) { found = (strcmp(itemPtr->label, pattern) == 0); } else if (switches.flags & FIND_REGEXP) { found = Tcl_RegExpMatch(NULL, itemPtr->label, pattern); } else { found = Tcl_StringMatch(itemPtr->label, pattern); } if (found) { count++; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(itemPtr->index)); if (switches.count == count) { break; } } if ((itemPtr == switches.toPtr) && ((switches.flags & FIND_WRAP) == 0)) { break; } if (nextPtr == switches.fromPtr) { break; } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FocusOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm index item * *--------------------------------------------------------------------------- */ static int FocusOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) == TCL_OK) { viewPtr->focusPtr = itemPtr; if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm index item * *--------------------------------------------------------------------------- */ static int IndexOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) == TCL_OK) { if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm invoke item * *--------------------------------------------------------------------------- */ static int InvokeOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Item *itemPtr; if (GetItemFromObj(interp, viewPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if ((itemPtr == NULL) || (itemPtr->flags & ITEM_DISABLED)) { return TCL_OK; /* Item is currently disabled. */ } Tcl_Preserve(itemPtr); SelectItem(viewPtr, itemPtr); /* * We check nItems in addition to whether the item has a command because * that goes to zero if the listview is deleted (e.g., during command * evaluation). */ if ((Blt_Chain_GetLength(viewPtr->chain) > 0) && (itemPtr->cmdObjPtr != NULL)) { Tcl_IncrRefCount(itemPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, itemPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(itemPtr->cmdObjPtr); } Tcl_Release(itemPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Inserts a new item into the listview at the given index. * * Results: * NULL is always returned. * * Side effects: * The listview gets a new item. * * .cm insert before 0 after 1 -text label * *--------------------------------------------------------------------------- */ static int InsertOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr, *wherePtr; int dir; static const char *dirs[] = { "after", "at", "before" , NULL}; if (Tcl_GetIndexFromObj(interp, objv[2], dirs, "key", 0, &dir) != TCL_OK) { return TCL_ERROR; } if (GetItemFromObj(interp, viewPtr, objv[3], &wherePtr) != TCL_OK) { return TCL_ERROR; } if (wherePtr == NULL) { Tcl_AppendResult(interp, "can't insert item: no index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; /* No item. */ } itemPtr = NewItem(viewPtr); if (ConfigureItem(interp, itemPtr, objc - 4, objv + 4, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } MoveItem(viewPtr, itemPtr, dir, wherePtr); if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } viewPtr->flags |= LAYOUT_PENDING; viewPtr->flags &= ~SORTED; EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemConfigureOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * * .cm item configure item ?option value?... * *--------------------------------------------------------------------------- */ static int ItemConfigureOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; ItemIterator iter; if (GetItemIterator(interp, viewPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = viewPtr; for (itemPtr = FirstTaggedItem(&iter); itemPtr != NULL; itemPtr = NextTaggedItem(&iter)) { int result; unsigned int flags; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, itemSpecs, (char *)itemPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, itemSpecs, (char *)itemPtr, objv[4], flags); } Tcl_Preserve(itemPtr); result = ConfigureItem(interp, itemPtr, objc - 4, objv + 4, flags); Tcl_Release(itemPtr); if (result == TCL_ERROR) { return TCL_ERROR; } } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemCgetOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * * .cm item cget item option * *--------------------------------------------------------------------------- */ static int ItemCgetOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't retrieve item \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } iconOption.clientData = viewPtr; return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, itemSpecs, (char *)itemPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * ItemOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec itemOps[] = { {"cget", 2, ItemCgetOp, 5, 5, "item option",}, {"configure", 2, ItemConfigureOp, 4, 0, "item ?option value?...",}, }; static int nItemOps = sizeof(itemOps) / sizeof(Blt_OpSpec); static int ItemOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ListViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nItemOps, itemOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * .cm names pattern... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; int i; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 2; i < objc; i++) { const char *pattern; Item *itemPtr; pattern = Tcl_GetString(objv[i]); for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (Tcl_StringMatch(itemPtr->label, pattern)) { Tcl_Obj *objPtr; if (itemPtr->label == emptyString) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(itemPtr->label, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int NearestOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; int wx, wy; Item *itemPtr; int isRoot; char *string; isRoot = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(viewPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } itemPtr = NearestItem(viewPtr, x, y, TRUE); if (itemPtr == NULL) { return TCL_OK; } x = WORLDX(viewPtr, x); y = WORLDY(viewPtr, y); wx = itemPtr->worldX + ITEM_XPAD; wy = itemPtr->worldY + ITEM_XPAD; if (objc > 4) { const char *where; where = ""; if (itemPtr->icon != NULL) { int ix, iy, iw, ih; ih = IconHeight(itemPtr->icon); iw = IconWidth(itemPtr->icon); ix = wx; iy = wy; wx += viewPtr->iconWidth; if ((x >= ix) && (x <= (ix + iw)) && (y >= iy) && (y < (iy + ih))) { where = "icon"; goto done; } } if ((itemPtr->label != emptyString) || (itemPtr->image != NULL)) { int lx, ly; lx = wx; ly = wy; wx += itemPtr->labelWidth + ITEM_IPAD; if ((x >= lx) && (x < (lx + itemPtr->labelWidth)) && (y >= ly) && (y < (ly + itemPtr->labelHeight))) { where = "label"; goto done; } } done: if (Tcl_SetVar(interp, Tcl_GetString(objv[4]), where, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm next item * *--------------------------------------------------------------------------- */ static int NextOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) == TCL_OK) { for (itemPtr = NextItem(itemPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if ((itemPtr->flags & (ITEM_HIDE|ITEM_DISABLED)) == 0) { break; } } if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PreviousOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm previous item * *--------------------------------------------------------------------------- */ static int PreviousOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, viewPtr, objv[2], &itemPtr) == TCL_OK) { for (itemPtr = PrevItem(itemPtr); itemPtr != NULL; itemPtr = PrevItem(itemPtr)) { if ((itemPtr->flags & (ITEM_HIDE|ITEM_DISABLED)) == 0) { break; } } if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int oper; int x, y; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 { char *string; char c; int length; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } } if ((Blt_GetPixelsFromObj(interp, viewPtr->tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) || (Blt_GetPixelsFromObj(interp, viewPtr->tkwin, objv[4], PIXELS_ANY, &y) != TCL_OK)) { return TCL_ERROR; } if (oper == SCAN_MARK) { viewPtr->scanAnchorX = x; viewPtr->scanAnchorY = y; viewPtr->scanX = viewPtr->xOffset; viewPtr->scanY = viewPtr->yOffset; } else { int xWorld, yWorld; int viewWidth, viewHeight; int dx, dy; dx = viewPtr->scanAnchorX - x; dy = viewPtr->scanAnchorY - y; xWorld = viewPtr->scanX + (10 * dx); yWorld = viewPtr->scanY + (10 * dy); viewWidth = VPORTWIDTH(viewPtr); if (xWorld > (viewPtr->worldWidth - viewWidth)) { xWorld = viewPtr->worldWidth - viewWidth; } if (xWorld < 0) { xWorld = 0; } viewHeight = VPORTHEIGHT(viewPtr); if (yWorld > (viewPtr->worldHeight - viewHeight)) { yWorld = viewPtr->worldHeight - viewHeight; } if (yWorld < 0) { yWorld = 0; } viewPtr->xOffset = xWorld; viewPtr->yOffset = yWorld; viewPtr->flags |= SCROLL_PENDING; EventuallyRedraw(viewPtr); } return TCL_OK; } /*ARGSUSED*/ static int SeeOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int x, y, width, height; int left, right, top, bottom; int maxWidth; if (GetItemFromObj(interp, viewPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } if (itemPtr->flags & ITEM_HIDE) { return TCL_OK; } width = VPORTWIDTH(viewPtr); height = VPORTHEIGHT(viewPtr); x = viewPtr->xOffset; y = viewPtr->yOffset; /* * XVIEW: If the entry is left or right of the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ left = viewPtr->xOffset; right = viewPtr->xOffset + width; top = viewPtr->yOffset; bottom = viewPtr->yOffset + height; maxWidth = itemPtr->width; if (viewPtr->maxWidth < maxWidth) { maxWidth = viewPtr->maxWidth; } if (itemPtr->worldX < left) { /* Adjust the scroll so that item starts at the left border. */ x = itemPtr->worldX; } else if ((itemPtr->worldX + maxWidth) > right) { /* Adjust the scroll so that item ends at the right border. */ x = itemPtr->worldX + maxWidth - width; } if (itemPtr->worldY < top) { /* Adjust the scroll so that item starts at the top border. */ y = itemPtr->worldY; } else if ((itemPtr->worldY + itemPtr->height) > bottom) { /* Adjust the scroll so that item ends at the right border. */ y = itemPtr->worldY + itemPtr->height - height; } if ((y != viewPtr->yOffset) || (x != viewPtr->xOffset)) { viewPtr->xOffset = x; viewPtr->yOffset = y; } EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionAnchorOp -- * * Sets the selection anchor to the element given by a index. The * selection anchor is the end of the selection that is fixed while * dragging out a selection with the mouse. The index "anchor" may be * used to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionAnchorOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; long index; index = -1; if (objc == 3) { if (viewPtr->selAnchorPtr != NULL) { index = viewPtr->selAnchorPtr->index; } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } /* Set both the anchor and the mark. Indicates that a single entry * is selected. */ viewPtr->selAnchorPtr = itemPtr; viewPtr->selMarkPtr = NULL; if (itemPtr != NULL) { index = itemPtr->index; } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionClearallOp * * Clears the entire selection. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionClearallOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClearSelection(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionIncludesOp * * Returns 1 if the element indicated by index is currently selected, 0 * if it isn't. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionIncludesOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int bool; if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } bool = FALSE; if (itemPtr == NULL) { bool = ItemIsSelected(viewPtr, itemPtr); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionMarkOp -- * * Sets the selection mark to the element given by a index. The * selection anchor is the end of the selection that is movable while * dragging out a selection with the mouse. The index "mark" may be used * to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionMarkOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; long index; index = -1; if (objc == 3) { if (viewPtr->selMarkPtr != NULL) { index = viewPtr->selMarkPtr->index; } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->selAnchorPtr == NULL) { Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; /* The selection anchor must be set * first. But don't flag this as * an error. */ } if ((itemPtr != NULL) && (viewPtr->selMarkPtr != itemPtr)) { Blt_ChainLink link, prev; /* Deselect entry from the list all the way back to the anchor. */ for (link = Blt_Chain_LastLink(viewPtr->selected); link != NULL; link = prev) { Item *selectPtr; prev = Blt_Chain_PrevLink(link); selectPtr = Blt_Chain_GetValue(link); if (selectPtr == viewPtr->selAnchorPtr) { break; } DeselectItem(viewPtr, selectPtr); } viewPtr->flags &= ~SELECT_MASK; viewPtr->flags |= SELECT_SET; SelectRange(viewPtr, viewPtr->selAnchorPtr, itemPtr); viewPtr->selMarkPtr = itemPtr; EventuallyRedraw(viewPtr); index = itemPtr->index; if (viewPtr->selectCmdObjPtr != NULL) { EventuallyInvokeSelectCmd(viewPtr); } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionPresentOp * * Returns 1 if there is a selection and 0 if it isn't. * * Results: * A standard TCL result. interp->result will contain a boolean string * indicating if there is a selection. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionPresentOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; bool = (Blt_Chain_GetLength(viewPtr->selected) > 0); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionSetOp * * Selects, deselects, or toggles all of the elements in the range * between first and last, inclusive, without affecting the selection * state of elements outside that range. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionSetOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *string; viewPtr->flags &= ~SELECT_MASK; if (viewPtr->flags & LAYOUT_PENDING) { /* * The layout is dirty. Recompute it now so that we can use * view.top and view.bottom for nodes. */ ComputeLayout(viewPtr); } string = Tcl_GetString(objv[2]); switch (string[0]) { case 's': viewPtr->flags |= SELECT_SET; break; case 'c': viewPtr->flags |= SELECT_CLEAR; break; case 't': viewPtr->flags |= SELECT_TOGGLE; break; } if (objc > 4) { Item *firstPtr, *lastPtr; if (GetItemFromObj(interp, viewPtr, objv[3], &firstPtr) != TCL_OK) { return TCL_ERROR; } if (firstPtr == NULL) { return TCL_OK; /* Didn't pick an entry. */ } if ((firstPtr->flags & ITEM_HIDE) && (!(viewPtr->flags & SELECT_CLEAR))) { if (objc > 4) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } else { return TCL_OK; } } lastPtr = firstPtr; if (objc > 4) { if (GetItemFromObj(interp, viewPtr, objv[4], &lastPtr) != TCL_OK) { return TCL_ERROR; } if (lastPtr == NULL) { return TCL_OK; } if ((lastPtr->flags & ITEM_HIDE) && (!(viewPtr->flags & SELECT_CLEAR))) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } } if (firstPtr == lastPtr) { SelectItemUsingFlags(viewPtr, firstPtr); } else { SelectRange(viewPtr, firstPtr, lastPtr); } /* Set both the anchor and the mark. Indicates that a single entry is * selected. */ if (viewPtr->selAnchorPtr == NULL) { viewPtr->selAnchorPtr = firstPtr; } } else { Item *itemPtr; ItemIterator iter; if (GetItemIterator(interp, viewPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (itemPtr = FirstTaggedItem(&iter); itemPtr != NULL; itemPtr = NextTaggedItem(&iter)) { if ((itemPtr->flags & ITEM_HIDE) && ((viewPtr->flags & SELECT_CLEAR) == 0)) { continue; } SelectItemUsingFlags(viewPtr, itemPtr); } /* Set both the anchor and the mark. Indicates that a single entry is * selected. */ if (viewPtr->selAnchorPtr == NULL) { viewPtr->selAnchorPtr = itemPtr; } } if (viewPtr->flags & SELECT_EXPORT) { Tk_OwnSelection(viewPtr->tkwin, XA_PRIMARY, LostSelection, viewPtr); } EventuallyRedraw(viewPtr); if (viewPtr->selectCmdObjPtr != NULL) { EventuallyInvokeSelectCmd(viewPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionOp -- * * This procedure handles the individual options for text selections. * The selected text is designated by start and end indices into the text * pool. The selected segment has both a anchored and unanchored ends. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static Blt_OpSpec selectionOps[] = { {"anchor", 1, SelectionAnchorOp, 3, 4, "?item?",}, {"clear", 5, SelectionSetOp, 4, 5, "first ?last?",}, {"clearall", 6, SelectionClearallOp, 3, 3, "",}, {"includes", 1, SelectionIncludesOp, 4, 4, "item",}, {"mark", 1, SelectionMarkOp, 3, 4, "?item?",}, {"present", 1, SelectionPresentOp, 3, 3, "",}, {"set", 1, SelectionSetOp, 4, 5, "first ?last?",}, {"toggle", 1, SelectionSetOp, 4, 5, "first ?last?",}, }; static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); static int SelectionOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ListViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int SizeOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Chain_GetLength(viewPtr->chain)); return TCL_OK; } static int InvokeCompare(ListView *viewPtr, const char *s1, const char *s2, Tcl_Obj *cmdPtr) { Tcl_Interp *interp; int result; Tcl_Obj *objv[4]; interp = viewPtr->interp; objv[0] = cmdPtr; objv[1] = Tcl_NewStringObj(Tk_PathName(viewPtr->tkwin), -1); objv[2] = Tcl_NewStringObj(s1, -1); objv[3] = Tcl_NewStringObj(s2, -1); result = Blt_GlobalEvalObjv(interp, 4, objv); if ((result != TCL_OK) || (Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp),&result)!=TCL_OK)) { Tcl_BackgroundError(interp); } Tcl_ResetResult(interp); return result; } static ListView *listViewInstance; static int CompareLinks(Blt_ChainLink *aPtr, Blt_ChainLink *bPtr) { ListView *viewPtr; Item *i1Ptr, *i2Ptr; const char *s1, *s2; int result; i1Ptr = (Item *)Blt_Chain_GetValue(*aPtr); i2Ptr = (Item *)Blt_Chain_GetValue(*bPtr); viewPtr = i1Ptr->viewPtr; if (viewPtr->flags & SORT_TYPE) { s1 = i1Ptr->type; s2 = i2Ptr->type; } else { s1 = i1Ptr->label; s2 = i2Ptr->label; } if (s1 == NULL) { s1 = ""; } if (s2 == NULL) { s2 = ""; } result = 0; if (viewPtr->sortCmdPtr != NULL) { result = InvokeCompare(viewPtr, s1, s2, viewPtr->sortCmdPtr); if (viewPtr->flags & SORT_DECREASING) { result = -result; } return result; } if (viewPtr->flags & SORT_DICTIONARY) { result = Blt_DictionaryCompare(s1, s2); } else { result = strcmp(s1, s2); } if (result == 0) { if (viewPtr->flags & SORT_TYPE) { s1 = i1Ptr->label; s2 = i2Ptr->label; } else { s1 = i1Ptr->type; s2 = i2Ptr->type; } if (viewPtr->flags & SORT_DICTIONARY) { result = Blt_DictionaryCompare(s1, s2); } else { result = strcmp(s1, s2); } } if (viewPtr->flags & SORT_DECREASING) { return -result; } return result; } /* *--------------------------------------------------------------------------- * * SortCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SortCgetOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * SortConfigureOp -- * * This procedure is called to process a list of configuration * options database, in order to reconfigure the one of more * entries in the widget. * * .h sort configure option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for viewPtr; old resources get freed, if there * were any. The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int SortConfigureOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int oldType; Tcl_Obj *oldCmdPtr; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, objv[3], 0); } oldType = viewPtr->flags & SORT_MODE_MASK; oldCmdPtr = viewPtr->sortCmdPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, sortSpecs, objc - 3, objv + 3, (char *)viewPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if ((oldType != (viewPtr->flags & SORT_MODE_MASK)) || (oldCmdPtr != viewPtr->sortCmdPtr)) { viewPtr->flags &= ~SORTED; } if (viewPtr->flags & SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } EventuallyRedraw(viewPtr); return TCL_OK; } /*ARGSUSED*/ static int SortNowOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, sortSpecs, objc - 3, objv + 3, (char *)viewPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= SORT_PENDING; EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SortOp -- * * Comparison routine (used by qsort) to sort a chain of subnodes. * A simple string comparison is performed on each node name. * * .h sort now * * Results: * 1 is the first is greater, -1 is the second is greater, 0 * if equal. * *--------------------------------------------------------------------------- */ static Blt_OpSpec sortOps[] = { {"cget", 2, SortCgetOp, 4, 4, "option",}, {"configure", 2, SortConfigureOp, 3, 0, "?option value?...",}, {"now", 1, SortNowOp, 3, 0, "?option value?",}, }; static int nSortOps = sizeof(sortOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int SortOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ListViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSortOps, sortOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /* .m style create name option value option value */ static int StyleCreateOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&viewPtr->styleTable, Tcl_GetString(objv[3]), &isNew); if (!isNew) { Tcl_AppendResult(interp, "listview style \"", Tcl_GetString(objv[3]), "\" already exists.", (char *)NULL); return TCL_ERROR; } stylePtr = Blt_AssertCalloc(1, sizeof(Style)); stylePtr->name = Blt_GetHashKey(&viewPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->viewPtr = viewPtr; stylePtr->borderWidth = 0; stylePtr->activeRelief = TK_RELIEF_RAISED; Blt_SetHashValue(hPtr, stylePtr); iconOption.clientData = viewPtr; if (ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, 0) != TCL_OK) { DestroyStyle(stylePtr); return TCL_ERROR; } return TCL_OK; } static int StyleCgetOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, viewPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = viewPtr; return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, styleSpecs, (char *)stylePtr, objv[4], 0); } static int StyleConfigureOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result, flags; Style *stylePtr; if (GetStyleFromObj(interp, viewPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = viewPtr; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, styleSpecs, (char *)stylePtr, (Tcl_Obj *)NULL, flags); } else if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, styleSpecs, (char *)stylePtr, objv[2], flags); } Tcl_Preserve(stylePtr); result = ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, flags); Tcl_Release(stylePtr); if (result == TCL_ERROR) { return TCL_ERROR; } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(viewPtr); return TCL_OK; } static int StyleDeleteOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, viewPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } if (stylePtr->refCount > 0) { Tcl_AppendResult(interp, "can't destroy listview style \"", stylePtr->name, "\": style in use.", (char *)NULL); return TCL_ERROR; } DestroyStyle(stylePtr); return TCL_OK; } static int StyleNamesOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&viewPtr->styleTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Style *stylePtr; int found; int i; found = TRUE; stylePtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); found = Tcl_StringMatch(stylePtr->name, pattern); if (found) { break; } } if (found) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(stylePtr->name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static Blt_OpSpec styleOps[] = { {"cget", 2, StyleCgetOp, 5, 5, "name option",}, {"configure", 2, StyleConfigureOp, 4, 0, "name ?option value?...",}, {"create", 2, StyleCreateOp, 4, 0, "name ?option value?...",}, {"delete", 1, StyleDeleteOp, 3, 0, "?name...?",}, {"names", 1, StyleNamesOp, 3, 0, "?pattern...?",}, }; static int nStyleOps = sizeof(styleOps) / sizeof(Blt_OpSpec); static int StyleOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ListViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nStyleOps, styleOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } static int XpositionOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't get x-position of item: no item \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), itemPtr->worldX-viewPtr->xOffset); return TCL_OK; } static int XviewOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int w; w = VPORTWIDTH(viewPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)viewPtr->xOffset / (viewPtr->worldWidth+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(viewPtr->xOffset + w) / (viewPtr->worldWidth+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &viewPtr->xOffset, viewPtr->worldWidth, w, viewPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= SCROLL_PENDING; EventuallyRedraw(viewPtr); return TCL_OK; } static int YpositionOp(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, viewPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't get y-position of item: such index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), itemPtr->worldY-viewPtr->yOffset); return TCL_OK; } static int YviewOp( ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int height; height = VPORTHEIGHT(viewPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)viewPtr->yOffset / (viewPtr->worldHeight+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(viewPtr->yOffset + height) /(viewPtr->worldHeight+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &viewPtr->yOffset, viewPtr->worldHeight, height, viewPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= SCROLL_PENDING; EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyListView -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyListView(DestroyData dataPtr) /* Pointer to the widget record. */ { ListView *viewPtr = (ListView *)dataPtr; DestroyItems(viewPtr); DestroyStyles(viewPtr); DestroyLabels(viewPtr); Blt_DeleteHashTable(&viewPtr->tagTable); DestroyIcons(viewPtr); if (viewPtr->painter != NULL) { Blt_FreePainter(viewPtr->painter); } if (viewPtr->focusGC != NULL) { Tk_FreeGC(viewPtr->display, viewPtr->focusGC); } iconOption.clientData = viewPtr; Blt_FreeOptions(listViewSpecs, (char *)viewPtr, viewPtr->display, 0); Tcl_DeleteCommandFromToken(viewPtr->interp, viewPtr->cmdToken); Blt_Free(viewPtr); } /* *--------------------------------------------------------------------------- * * NewListView -- * *--------------------------------------------------------------------------- */ static ListView * NewListView(Tcl_Interp *interp, Tk_Window tkwin) { ListView *viewPtr; viewPtr = Blt_AssertCalloc(1, sizeof(ListView)); Tk_SetClass(tkwin, "ListView"); viewPtr->tkwin = tkwin; viewPtr->display = Tk_Display(tkwin); viewPtr->interp = interp; viewPtr->flags = LAYOUT_PENDING | SCROLL_PENDING | SELECT_EXPORT | SELECT_ORDERED; viewPtr->relief = TK_RELIEF_SUNKEN; viewPtr->xScrollUnits = viewPtr->yScrollUnits = 20; viewPtr->borderWidth = 1; viewPtr->highlightWidth = 2; viewPtr->chain = Blt_Chain_Create(); viewPtr->layoutMode = LAYOUT_LIST_COLUMN; viewPtr->painter = Blt_GetPainter(tkwin, 1.0); Blt_ResetLimits(&viewPtr->reqWidth); Blt_ResetLimits(&viewPtr->reqHeight); Blt_InitHashTable(&viewPtr->iconTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->labelTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->styleTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->tagTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->selectTable, BLT_ONE_WORD_KEYS); viewPtr->selected = Blt_Chain_Create(); AddDefaultStyle(interp, viewPtr); Blt_SetWindowInstanceData(tkwin, viewPtr); return viewPtr; } /* *--------------------------------------------------------------------------- * * ListViewCmd -- * * This procedure is invoked to process the "listview" command. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec listViewOps[] = { {"activate", 2, ActivateOp, 3, 3, "item",}, {"add", 2, AddOp, 2, 0, "?option value?",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"curselection",2, CurselectionOp,2, 2, "",}, {"delete", 3, DeleteOp, 2, 0, "items...",}, {"exists", 3, ExistsOp, 3, 3, "item",}, {"find", 2, FindOp, 3, 0, "string ?switches?",}, {"focus", 2, FocusOp, 3, 3, "item",}, {"index", 3, IndexOp, 3, 3, "item",}, {"insert", 3, InsertOp, 3, 0, "after|at|before index ?option value?",}, {"invoke", 3, InvokeOp, 3, 3, "item",}, {"item", 2, ItemOp, 2, 0, "oper args",}, {"listadd", 1, AddListOp, 3, 0, "labelList ?option value?",}, {"names", 2, NamesOp, 2, 0, "?pattern...?",}, {"nearest", 3, NearestOp, 4, 4, "x y",}, {"next", 3, NextOp, 3, 3, "item",}, {"previous", 2, PreviousOp, 3, 3, "item",}, {"scan", 2, ScanOp, 5, 5, "dragto|mark x y",}, {"see", 3, SeeOp, 3, 3, "item",}, {"selection", 3, SelectionOp, 2, 0, "op ?args?",}, {"size", 2, SizeOp, 2, 2, "",}, {"sort", 2, SortOp, 2, 0, "op ?args...?",}, {"style", 2, StyleOp, 2, 0, "op ?args...?",}, {"xposition", 2, XpositionOp, 3, 3, "item",}, {"xview", 2, XviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yposition", 2, YpositionOp, 3, 3, "item",}, {"yview", 2, YviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nListViewOps = sizeof(listViewOps) / sizeof(Blt_OpSpec); typedef int (ListViewInstOp)(ListView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int ListViewInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { ListViewInstOp *proc; ListView *viewPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nListViewOps, listViewOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(viewPtr); result = (*proc) (viewPtr, interp, objc, objv); Tcl_Release(viewPtr); return result; } /* *--------------------------------------------------------------------------- * * ListViewInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ListViewInstCmdDeletedProc(ClientData clientData) { ListView *viewPtr = clientData; /* Pointer to widget record. */ if (viewPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = viewPtr->tkwin; viewPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ListViewCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ListViewCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { ListView *viewPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; unsigned int mask; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, invoke a procedure to initialize * various bindings on the listview widget. If the procedure doesn't * already exist, source it from "$blt_library/listview.tcl". We * deferred sourcing the file until now so that the variable $blt_library * could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ListView::AutoScroll", &cmdInfo)) { if (Tcl_GlobalEval(interp, "source [file join $blt_library listview.tcl]") != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, NULL); if (tkwin == NULL) { return TCL_ERROR; } viewPtr = NewListView(interp, tkwin); if (ConfigureListView(interp, viewPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(viewPtr->tkwin); return TCL_ERROR; } mask = (ExposureMask | StructureNotifyMask | FocusChangeMask); Tk_CreateEventHandler(tkwin, mask, ListViewEventProc, viewPtr); Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING, SelectionProc, viewPtr, XA_STRING); viewPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ListViewInstCmdProc, viewPtr, ListViewInstCmdDeletedProc); Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_ListViewInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec[1] = { { "listview", ListViewCmd }, }; return Blt_InitCmds(interp, "::blt", cmdSpec, 1); } static void DrawItemBackground(Item *itemPtr, Drawable drawable, int x, int y) { Blt_Background bg; Style *stylePtr; ListView *viewPtr; int relief; int w, h; stylePtr = itemPtr->stylePtr; viewPtr = itemPtr->viewPtr; relief = itemPtr->relief; if (itemPtr->flags & ITEM_DISABLED) { bg = stylePtr->disabledBg; } else if (viewPtr->activePtr == itemPtr) { bg = stylePtr->activeBg; } else { bg = stylePtr->normalBg; } w = itemPtr->worldWidth; h = itemPtr->worldHeight; #ifndef notdef if (y == 0) { int xOrigin, yOrigin; int px, py; Blt_GetBackgroundOrigin(bg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(viewPtr->tkwin, bg, px, py); Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); Blt_SetBackgroundOrigin(viewPtr->tkwin, bg, xOrigin, yOrigin); } else { Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); } #else Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); #endif } static void DrawItem(Item *itemPtr, Drawable drawable, int x, int y) { ListView *viewPtr; Style *stylePtr; int x0, y0, w, h; int labelWidth; Icon icon; itemPtr->flags &= ~ITEM_REDRAW; stylePtr = itemPtr->stylePtr; viewPtr = itemPtr->viewPtr; x0 = x, y0 = y; labelWidth = itemPtr->labelWidth; if ((viewPtr->labelWidth>0) && (viewPtr->labelWidth<itemPtr->labelWidth)) { labelWidth = viewPtr->labelWidth; } w = itemPtr->width; h = itemPtr->height; x += itemPtr->indent; /* Icon. */ icon = (viewPtr->layoutMode == LAYOUT_ICONS) ? itemPtr->bigIcon : itemPtr->icon; if (icon != NULL) { if ((Blt_IsPicture(IconImage(icon))) && (itemPtr->flags & ITEM_DISABLED)) { Blt_Picture picture; Blt_Painter painter; painter = Blt_GetPainter(viewPtr->tkwin, 1.0); picture = Blt_GetPictureFromPictureImage(viewPtr->interp, IconImage(icon)); picture = Blt_GreyscalePicture(picture); Blt_PaintPicture(painter, drawable, picture, 0, 0, IconWidth(icon), IconHeight(icon), x + itemPtr->iconX, y + itemPtr->iconY, 0); Blt_FreePicture(picture); } else { Tk_RedrawImage(IconImage(icon), 0, 0, IconWidth(icon), IconHeight(icon), drawable, x + itemPtr->iconX, y + itemPtr->iconY); } } /* Image or label. */ if (ItemIsSelected(viewPtr, itemPtr)) { Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, stylePtr->selectBg, x + itemPtr->labelX - 3, y + itemPtr->labelY - 1, labelWidth + 6, itemPtr->labelHeight + 3, stylePtr->borderWidth, stylePtr->selectRelief); } if (itemPtr->image != NULL) { Tk_RedrawImage(IconImage(itemPtr->image), 0, 0, IconWidth(itemPtr->image), IconHeight(itemPtr->image), drawable, x + itemPtr->labelX, y + itemPtr->labelY); } else if (itemPtr->label != emptyString) { TextStyle ts; XColor *fg; TextLayout *layoutPtr; if (itemPtr->flags & ITEM_DISABLED) { fg = stylePtr->labelDisabledColor; } else if (ItemIsSelected(viewPtr, itemPtr)) { fg = stylePtr->labelSelectColor; } else if (viewPtr->activePtr == itemPtr) { fg = stylePtr->labelActiveColor; } else { fg = stylePtr->labelNormalColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, stylePtr->labelFont); Blt_Ts_SetForeground(ts, fg); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetJustify(ts, TK_JUSTIFY_LEFT); Blt_Ts_SetMaxLength(ts, labelWidth); layoutPtr = Blt_Ts_CreateLayout(itemPtr->label, -1, &ts); Blt_Ts_DrawLayout(viewPtr->tkwin, drawable, layoutPtr, &ts, x + stylePtr->borderWidth + itemPtr->labelX, y + stylePtr->borderWidth + itemPtr->labelY); if (itemPtr == viewPtr->activePtr) { Blt_Ts_UnderlineLayout(viewPtr->tkwin, drawable, layoutPtr, &ts, x + stylePtr->borderWidth + itemPtr->labelX, y + stylePtr->borderWidth + itemPtr->labelY); } Blt_Free(layoutPtr); } if ((viewPtr->flags & FOCUS) && (viewPtr->focusPtr == itemPtr)) { if (ItemIsSelected(viewPtr, itemPtr)) { XSetForeground(viewPtr->display, viewPtr->focusGC, stylePtr->labelSelectColor->pixel); } else { XSetForeground(viewPtr->display, viewPtr->focusGC, stylePtr->labelNormalColor->pixel); } XDrawRectangle(viewPtr->display, drawable, viewPtr->focusGC, x - 2 + stylePtr->borderWidth + itemPtr->labelX, y - 2 + stylePtr->borderWidth + itemPtr->labelY, labelWidth + 3 - 2 * stylePtr->borderWidth, itemPtr->labelHeight + 3 - 2 * stylePtr->borderWidth); } } static void DrawListView(ListView *viewPtr, Drawable drawable) { int left, right, top, bottom; /* Draw each visible item. */ Item *itemPtr; left = viewPtr->inset; right = VPORTWIDTH(viewPtr); top = viewPtr->inset; bottom = VPORTHEIGHT(viewPtr); for (itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { int x, y; if (itemPtr->flags & ITEM_HIDE) { continue; } x = SCREENX(viewPtr, itemPtr->worldX); y = SCREENY(viewPtr, itemPtr->worldY); if ((x > right) || ((x + itemPtr->width) < left) || (y > bottom) || ((y + itemPtr->height) < top)) { continue; } DrawItemBackground(itemPtr, drawable, x, y); DrawItem(itemPtr, drawable, x, y); } } /* *--------------------------------------------------------------------------- * * DisplayItem -- * * This procedure is invoked to display an item in the listview widget. * * Results: * None. * * Side effects: * Commands are output to X to display the item. * *--------------------------------------------------------------------------- */ static void DisplayItem(ClientData clientData) { Item *itemPtr = clientData; int x, y, w, h; Pixmap drawable; ListView *viewPtr; int sx, sy, x1, x2, y1, y2; /* * Create a pixmap the size of the item for double buffering. */ viewPtr = itemPtr->viewPtr; h = itemPtr->worldHeight; w = itemPtr->worldWidth; if ((w < 1) || (h < 1)) { fprintf(stderr, "w=%d h=%d\n", w, h); return; } drawable = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), w, h, Tk_Depth(viewPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif DrawItemBackground(itemPtr, drawable, 0, 0); DrawItem(itemPtr, drawable, 0, 0); x = SCREENX(viewPtr, itemPtr->worldX); y = SCREENY(viewPtr, itemPtr->worldY); /* Don't let the item overlap the widget's border. Reduce the pixmap * accordingly. */ x1 = y1 = viewPtr->inset; x2 = Tk_Width(viewPtr->tkwin) - viewPtr->inset; y2 = Tk_Height(viewPtr->tkwin) - viewPtr->inset; sx = sy = 0; if (x < x1) { /* Overlaps on the left. */ sx = x1 - x; w -= sx; x = x1; } if ((x + w) > x2) { /* Overlaps on the right. */ w = x2 - x; } if (y < y1) { /* Overlaps on the top. */ sy = y1 - y; h -= sy; y = y1; } if ((y + h) > y2) { /* Overlaps on the bottom. */ h = y2 - y; } XCopyArea(viewPtr->display, drawable, Tk_WindowId(viewPtr->tkwin), viewPtr->focusGC, sx, sy, w, h, x, y); Tk_FreePixmap(viewPtr->display, drawable); } /* *--------------------------------------------------------------------------- * * SortItems -- * * Sorts the items in the list. * *--------------------------------------------------------------------------- */ static void SortItems(ListView *viewPtr) { Item *itemPtr; long count; listViewInstance = viewPtr; viewPtr->flags &= ~SORT_PENDING; Blt_Chain_Sort(viewPtr->chain, CompareLinks); viewPtr->flags |= SORTED; for (count = 0, itemPtr = FirstItem(viewPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr), count++) { itemPtr->index = count; } viewPtr->flags |= LAYOUT_PENDING; } /* *--------------------------------------------------------------------------- * * DisplayListView -- * * This procedure is invoked to display a listview widget. * * Results: * None. * * Side effects: * Commands are output to X to display the menu. * *--------------------------------------------------------------------------- */ static void DisplayListView(ClientData clientData) { ListView *viewPtr = clientData; Pixmap drawable; int w, h; /* Window width and height. */ viewPtr->flags &= ~REDRAW_PENDING; if (viewPtr->tkwin == NULL) { return; /* Window destroyed (should not get * here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayListView(%s) w=%d h=%d\n", Tk_PathName(viewPtr->tkwin), Tk_Width(viewPtr->tkwin), Tk_Height(viewPtr->tkwin)); #endif if (viewPtr->flags & SORT_PENDING) { SortItems(viewPtr); } if (viewPtr->flags & LAYOUT_PENDING) { ComputeLayout(viewPtr); } viewPtr->width = Tk_Width(viewPtr->tkwin); viewPtr->height = Tk_Height(viewPtr->tkwin); if ((Tk_Width(viewPtr->tkwin) <= 1) || (Tk_Height(viewPtr->tkwin) <= 1)){ /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (!Tk_IsMapped(viewPtr->tkwin)) { /* The menu's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the listview's new layout. */ return; } if (viewPtr->flags & SCROLL_PENDING) { int vw, vh; /* Viewport width and height. */ /* * The view port has changed. The visible items need to be recomputed * and the scrollbars updated. */ vw = VPORTWIDTH(viewPtr); vh = VPORTHEIGHT(viewPtr); if ((viewPtr->xScrollCmdObjPtr != NULL) && (viewPtr->flags & SCROLLX)) { Blt_UpdateScrollbar(viewPtr->interp, viewPtr->xScrollCmdObjPtr, viewPtr->xOffset, viewPtr->xOffset + vw, viewPtr->worldWidth); } if ((viewPtr->yScrollCmdObjPtr != NULL) && (viewPtr->flags & SCROLLY)) { Blt_UpdateScrollbar(viewPtr->interp, viewPtr->yScrollCmdObjPtr, viewPtr->yOffset, viewPtr->yOffset+vh, viewPtr->worldHeight); } viewPtr->flags &= ~SCROLL_PENDING; } /* * Create a pixmap the size of the window for double buffering. */ w = Tk_Width(viewPtr->tkwin); h = Tk_Height(viewPtr->tkwin); drawable = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), w, h, Tk_Depth(viewPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif /* Background */ Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, viewPtr->defStyle.normalBg, 0, 0, w, h, 0, TK_RELIEF_FLAT); DrawListView(viewPtr, drawable); Blt_DrawBackgroundRectangle(viewPtr->tkwin, drawable, viewPtr->defStyle.normalBg, 0, 0, Tk_Width(viewPtr->tkwin), Tk_Height(viewPtr->tkwin), viewPtr->borderWidth, viewPtr->relief); /* Draw focus highlight ring. */ if ((viewPtr->highlightWidth > 0) && (viewPtr->flags & FOCUS)) { GC gc; gc = Tk_GCForColor(viewPtr->highlightColor, drawable); Tk_DrawFocusHighlight(viewPtr->tkwin, gc, viewPtr->highlightWidth, drawable); } XCopyArea(viewPtr->display, drawable, Tk_WindowId(viewPtr->tkwin), viewPtr->focusGC, 0, 0, w, h, 0, 0); Tk_FreePixmap(viewPtr->display, drawable); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPsInt.h��������������������������������������������������������������������0000644�0001750�0001750�00000003244�11462120062�014740� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPsInt.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_PS_INT_H #define _BLT_PS_INT_H #include "bltPs.h" struct _Blt_Ps { Tcl_Interp *interp; /* Interpreter to report errors to. */ Tcl_DString dString; /* Dynamic string used to contain the * PostScript generated. */ PageSetup *setupPtr; #define POSTSCRIPT_BUFSIZ ((BUFSIZ*2)-1) /* * Utility space for building strings. Currently used to create * PostScript output for the "postscript" command. */ char scratchArr[POSTSCRIPT_BUFSIZ+1]; }; typedef struct _Blt_Ps PostScript; #endif /* BLT_PS_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDtXml.c��������������������������������������������������������������������0000644�0001750�0001750�00000053735�11462120062�014740� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtXml.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #include "config.h" #define USE_NON_const 1 #include <tcl.h> #include <bltSwitch.h> #include <bltDataTable.h> #include <bltTree.h> #include <bltList.h> #include <bltAlloc.h> #include <bltAssert.h> #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ DLLEXPORT extern Tcl_AppInitProc Blt_Table_XmlInit; extern const char *Blt_Itoa(int); #define TRUE 1 #define FALSE 0 static Blt_TableImportProc ImportXmlProc; static Blt_TableExportProc ExportXmlProc; /* * Format Import Export * csv file/data file/data * tree data data * vector data data * xml file/data file/data * sql data data * * $table import csv -file fileName -data dataString * $table export csv -file defaultFileName * $table import tree $treeName $node ?switches? * $table export tree $treeName $node "label" "label" "label" * $table import vector $vecName label $vecName label... * $table export vector label $vecName label $vecName... * $table import xml -file fileName -data dataString ?switches? * $table export xml -file fileName -data dataString ?switches? * $table import sql -host $host -password $pw -db $db -port $port */ /* * ImportSwitches -- */ typedef struct { Tcl_Obj *fileObj; /* Name of file representing the channel. */ Tcl_Obj *dataObj; Tcl_Interp *interp; unsigned int flags; } ImportSwitches; #define IMPORT_ATTRIBUTES (1<<0) #define IMPORT_ELEMENTS (1<<1) #define IMPORT_CDATA (1<<2) #define IMPORT_MASK (IMPORT_ATTRIBUTES | IMPORT_CDATA | IMPORT_ELEMENTS) static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "string", Blt_Offset(ImportSwitches, dataObj), 0, 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ImportSwitches, fileObj), 0, 0}, {BLT_SWITCH_BITMASK_INVERT,"-noattrs", "", Blt_Offset(ImportSwitches, flags), 0, IMPORT_ATTRIBUTES}, {BLT_SWITCH_BITMASK_INVERT,"-noelems", "", Blt_Offset(ImportSwitches, flags), 0, IMPORT_ELEMENTS}, {BLT_SWITCH_BITMASK_INVERT,"-nocdata", "", Blt_Offset(ImportSwitches, flags), 0, IMPORT_CDATA}, {BLT_SWITCH_END} }; /* * ExportSwitches -- */ typedef struct { Blt_TableIterator rIter, cIter; Tcl_Obj *fileObj; /* Private fields. */ Tcl_Interp *interp; unsigned int flags; Tcl_Channel channel; /* If non-NULL, channel to write output to. */ Tcl_DString *dsPtr; } ExportSwitches; extern Blt_SwitchFreeProc Blt_Table_ColumnIterFreeProc; extern Blt_SwitchFreeProc Blt_Table_RowIterFreeProc; extern Blt_SwitchParseProc Blt_Table_ColumnIterSwitchProc; extern Blt_SwitchParseProc Blt_Table_RowIterSwitchProc; static Blt_SwitchCustom columnIterSwitch = { Blt_Table_ColumnIterSwitchProc, Blt_Table_ColumnIterFreeProc, 0, }; static Blt_SwitchCustom rowIterSwitch = { Blt_Table_RowIterSwitchProc, Blt_Table_RowIterFreeProc, 0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-columns", "columns", Blt_Offset(ExportSwitches, cIter), 0, 0, &columnIterSwitch}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ExportSwitches, fileObj), 0, 0}, {BLT_SWITCH_CUSTOM, "-rows", "rows", Blt_Offset(ExportSwitches, rIter), 0, 0, &rowIterSwitch}, {BLT_SWITCH_END} }; #ifdef HAVE_LIBEXPAT #include <expat.h> typedef struct { Blt_TableRow row; Blt_TableColumn col; Blt_Table table; Tcl_Interp *interp; int flags; Blt_HashTable attrTable; Blt_HashTable elemTable; Blt_HashTable stringTable; Blt_List elemList; Blt_ListNode node; } ImportData; static Tcl_Obj * GetStringObj(ImportData *importPtr, const char *string, size_t length) { Blt_HashEntry *hPtr; int isNew; char *key; #define MAX_STATIC_STRING 1023 char store[MAX_STATIC_STRING+1]; if (length > MAX_STATIC_STRING) { key = Blt_AssertMalloc(length + 1); } else { key = store; } memcpy(key, string, length); key[length] = '\0'; hPtr = Blt_CreateHashEntry(&importPtr->stringTable, key, &isNew); if (length > MAX_STATIC_STRING) { Blt_Free(key); } if (isNew) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, length); Tcl_IncrRefCount(objPtr); Blt_SetHashValue(hPtr, objPtr); return objPtr; } return Blt_GetHashValue(hPtr); } static void DumpStringTable(Blt_HashTable *tablePtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_Obj *objPtr; objPtr = Blt_GetHashValue(hPtr); Tcl_DecrRefCount(objPtr); } Blt_DeleteHashTable(tablePtr); } static void GetXmlCharacterData(void *userData, const XML_Char *string, int length) { ImportData *importPtr = userData; assert(length >= 0); if (importPtr->flags & IMPORT_CDATA) { Tcl_Obj *objPtr; Blt_ListNode node; /* Replicate the data for each sub-element. */ objPtr = GetStringObj(importPtr, string, length); assert(importPtr->node != NULL); Blt_List_SetValue(importPtr->node, objPtr); for (node = Blt_List_FirstNode(importPtr->elemList); node != NULL; node = Blt_List_NextNode(node)) { Blt_TableColumn col; objPtr = Blt_List_GetValue(node); col = (Blt_TableColumn)Blt_List_GetKey(node); if (Blt_Table_SetObj(importPtr->table, importPtr->row, col, objPtr) != TCL_OK) { Tcl_BackgroundError(importPtr->interp); } } } } static void StartXmlTag(void *userData, const char *element, const char **attr) { Blt_Table table; Blt_TableRow row; ImportData *importPtr = userData; Tcl_Interp *interp; interp = importPtr->interp; table = importPtr->table; importPtr->node = NULL; if (importPtr->flags & IMPORT_ELEMENTS) { Blt_TableColumn col; Blt_HashEntry *hPtr; int isNew; /* * If this is the first time we're seeing this element, create a new * column labeled as the element. This is different than the table's * set of labels, because the table may already have a label by the * same name. We want to create a new column in this case. */ hPtr = Blt_CreateHashEntry(&importPtr->elemTable, element, &isNew); if (isNew) { col = Blt_Table_CreateColumn(interp, table, element); if (col == NULL) { goto error; } Blt_SetHashValue(hPtr, col); } else { col = Blt_GetHashValue(hPtr); } importPtr->col = col; importPtr->node = Blt_List_Append(importPtr->elemList, (char *)col,NULL); } if (Blt_Table_ExtendRows(interp, table, 1, &row) != TCL_OK) { goto error; } importPtr->row = row; if (importPtr->flags & IMPORT_ATTRIBUTES) { const char **p; for (p = attr; *p != NULL; p += 2) { Blt_TableColumn col; Blt_HashEntry *hPtr; const char *name, *value; int isNew; name = *p, value = *(p+1); /* * If this is the first time we're seeing this attribute, create a * new column labeled as the attribute. */ hPtr = Blt_CreateHashEntry(&importPtr->attrTable, name, &isNew); if (isNew) { col = Blt_Table_CreateColumn(interp, table, name); if (col == NULL) { goto error; } Blt_SetHashValue(hPtr, col); } else { col = Blt_GetHashValue(hPtr); } /* Set the attribute value as the cell value. */ if (Blt_Table_SetString(table, row, col, value, -1)!=TCL_OK) { goto error; } } } return; error: Tcl_BackgroundError(importPtr->interp); } static void EndXmlTag(void *userData, const char *element) { ImportData *importPtr = userData; if (importPtr->node != NULL) { Blt_ListNode prev; /* Pop the tag from the stack. */ prev = Blt_List_PrevNode(importPtr->node); Blt_List_DeleteNode(importPtr->node); importPtr->node = prev; } } static int ReadXmlFromFile(Tcl_Interp *interp, XML_Parser parser, const char *fileName) { int closeChannel; int done; Tcl_Channel channel; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return FALSE; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); return FALSE; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return FALSE; /* Can't open dump file. */ } } done = FALSE; while (!done) { int length; #define BUFFSIZE 8192 char buffer[BUFFSIZE]; length = Tcl_Read(channel, buffer, sizeof(char) * BUFFSIZE); if (length < 0) { Tcl_AppendResult(interp, "\nread error: ", Tcl_PosixError(interp), (char *)NULL); if (closeChannel) { Tcl_Close(interp, channel); } return FALSE; } done = Tcl_Eof(channel); if (!XML_Parse(parser, buffer, length, done)) { Tcl_AppendResult(interp, "\n", fileName, ":", Blt_Itoa(XML_GetCurrentLineNumber(parser)), ": ", "error: ", XML_ErrorString(XML_GetErrorCode(parser)), (char *)NULL); if (closeChannel) { Tcl_Close(interp, channel); } return FALSE; } } if (closeChannel) { Tcl_Close(interp, channel); } return TRUE; } static int GetXmlExternalEntityRef(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId) { ImportData *dataPtr; Tcl_DString dString; Tcl_Interp *interp; XML_Parser newParser; int result; dataPtr = XML_GetUserData(parser); assert(dataPtr != NULL); interp = dataPtr->interp; Tcl_DStringInit(&dString); if ((base != NULL) && (Tcl_GetPathType(systemId) == TCL_PATH_RELATIVE)) { const char **argv; const char **baseArr, **sysIdArr; int argc; int i, j; int nBase, nSysId; Tcl_SplitPath(base, &nBase, &baseArr); Tcl_SplitPath(systemId, &nSysId, &sysIdArr); argc = nBase + nSysId; argv = Blt_Malloc(sizeof(char *) * (argc + 1)); if (argv == NULL) { return FALSE; } for (i = 0; i < nBase; i++) { argv[i] = baseArr[i]; } for (j = 0; j < nSysId; j++, i++) { argv[i] = sysIdArr[j]; } argv[i] = NULL; Tcl_JoinPath(argc, argv, &dString); Blt_Free(baseArr); Blt_Free(sysIdArr); Blt_Free(argv); } else { Tcl_DStringAppend(&dString, systemId, -1); } newParser = XML_ExternalEntityParserCreate(parser, context, NULL); if (newParser == NULL) { Tcl_AppendResult(interp, "can't create external entity ref parser", (char *)NULL); return FALSE; } result = ReadXmlFromFile(interp, newParser, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); XML_ParserFree(newParser); return result; } static int ImportXmlFile(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *fileObjPtr, unsigned int flags) { ImportData import; XML_Parser parser; int result; char *fileName; parser = XML_ParserCreate(NULL); if (parser == NULL) { Tcl_AppendResult(interp, "can't create XML parser", (char *)NULL); return TCL_ERROR; } import.table = table; import.row = NULL; import.interp = interp; import.flags = flags; Blt_InitHashTable(&import.stringTable, BLT_STRING_KEYS); Blt_InitHashTable(&import.attrTable, BLT_STRING_KEYS); Blt_InitHashTable(&import.elemTable, BLT_STRING_KEYS); import.elemList = Blt_List_Create(BLT_ONE_WORD_KEYS); XML_SetUserData(parser, &import); fileName = Tcl_GetString(fileObjPtr); { Tcl_DString dString; int argc; const char **argv; Tcl_DStringInit(&dString); Tcl_SplitPath(fileName, &argc, &argv); Tcl_JoinPath(argc - 1, argv, &dString); XML_SetBase(parser, Tcl_DStringValue(&dString)); Blt_Free(argv); Tcl_DStringFree(&dString); } XML_SetElementHandler(parser, StartXmlTag, EndXmlTag); XML_SetCharacterDataHandler(parser, GetXmlCharacterData); XML_SetExternalEntityRefHandler(parser, GetXmlExternalEntityRef); result = ReadXmlFromFile(interp, parser, fileName); XML_ParserFree(parser); Blt_DeleteHashTable(&import.attrTable); Blt_DeleteHashTable(&import.elemTable); DumpStringTable(&import.stringTable); Blt_List_Destroy(import.elemList); return (result) ? TCL_OK : TCL_ERROR; } static int ImportXmlData(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *dataObjPtr, unsigned int flags) { ImportData import; XML_Parser parser; char *string; int length; int result; parser = XML_ParserCreate(NULL); if (parser == NULL) { Tcl_AppendResult(interp, "can't create parser", (char *)NULL); return TCL_ERROR; } import.table = table; import.row = NULL; import.interp = interp; import.flags = flags; Blt_InitHashTable(&import.attrTable, BLT_STRING_KEYS); Blt_InitHashTable(&import.elemTable, BLT_STRING_KEYS); Blt_InitHashTable(&import.stringTable, BLT_STRING_KEYS); import.elemList = Blt_List_Create(BLT_ONE_WORD_KEYS); XML_SetUserData(parser, &import); XML_SetElementHandler(parser, StartXmlTag, EndXmlTag); XML_SetCharacterDataHandler(parser, GetXmlCharacterData); string = Tcl_GetStringFromObj(dataObjPtr, &length); result = XML_Parse(parser, string, length, 1); if (!result) { Tcl_AppendResult(interp, "\nparse error at line ", Blt_Itoa(XML_GetCurrentLineNumber(parser)), ": ", XML_ErrorString(XML_GetErrorCode(parser)), (char *)NULL); } XML_ParserFree(parser); Blt_DeleteHashTable(&import.attrTable); Blt_DeleteHashTable(&import.elemTable); DumpStringTable(&import.stringTable); Blt_List_Destroy(import.elemList); return (result) ? TCL_OK : TCL_ERROR; } static int ImportXmlProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; ImportSwitches switches; memset(&switches, 0, sizeof(switches)); switches.flags = IMPORT_MASK; if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if ((switches.dataObj != NULL) && (switches.fileObj != NULL)) { Tcl_AppendResult(interp, "can't set both -file and -data switches.", (char *)NULL); goto error; } if ((switches.flags & IMPORT_MASK) == 0) { Tcl_AppendResult(interp, "can't set both -noelems and -noattrs switches.", (char *)NULL); goto error; } if (switches.fileObj != NULL) { result = ImportXmlFile(interp, table, switches.fileObj, switches.flags); } else { result = ImportXmlData(interp, table, switches.dataObj, switches.flags); } error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return result; } #endif /* HAVE_LIBEXPAT */ static int XmlFlush(ExportSwitches *exportPtr) { int nWritten; char *line; int length; line = Tcl_DStringValue(exportPtr->dsPtr); length = Tcl_DStringLength(exportPtr->dsPtr); nWritten = Tcl_Write(exportPtr->channel, line, length); if (nWritten != length) { Tcl_AppendResult(exportPtr->interp, "can't write xml element: ", Tcl_PosixError(exportPtr->interp), (char *)NULL); return TCL_ERROR; } Tcl_DStringSetLength(exportPtr->dsPtr, 0); return TCL_OK; } static void XmlPutEscapeString(const char *from, size_t length, ExportSwitches *exportPtr) { const char *p, *pend; for (p = from, pend = from + length; p < pend; /*empty*/) { switch (*p) { case '\'': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&apos;", 6); break; case '&': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&amp;", 5); break; case '>': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&gt;", 4); break; case '<': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&lt;", 4); break; case '"': if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } from = ++p; Tcl_DStringAppend(exportPtr->dsPtr, "&quot;", 6); break; default: p++; break; } } if (p > from) { Tcl_DStringAppend(exportPtr->dsPtr, from, p - from); } } static int XmlStartTable(ExportSwitches *exportPtr, const char *tableName) { Tcl_DStringSetLength(exportPtr->dsPtr, 0); Tcl_DStringAppend(exportPtr->dsPtr, "<", 1); Tcl_DStringAppend(exportPtr->dsPtr, tableName, -1); Tcl_DStringAppend(exportPtr->dsPtr, ">\n", 2); if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static int XmlEndTable(ExportSwitches *exportPtr, const char *tableName) { Tcl_DStringAppend(exportPtr->dsPtr, "</", 2); Tcl_DStringAppend(exportPtr->dsPtr, tableName, -1); Tcl_DStringAppend(exportPtr->dsPtr, ">\n", 2); if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static void XmlStartElement(ExportSwitches *exportPtr, const char *elemName) { if (exportPtr->channel != NULL) { Tcl_DStringSetLength(exportPtr->dsPtr, 0); } Tcl_DStringAppend(exportPtr->dsPtr, " <", 3); Tcl_DStringAppend(exportPtr->dsPtr, elemName, -1); } static int XmlEndElement(ExportSwitches *exportPtr) { Tcl_DStringAppend(exportPtr->dsPtr, "/>\n", 3); if (exportPtr->channel != NULL) { return XmlFlush(exportPtr); } return TCL_OK; } static void XmlAppendAttrib(ExportSwitches *exportPtr, const char *attrName, const char *value, int length) { size_t valueLen; if (length < 0) { valueLen = strlen(value); } else { valueLen = (size_t)length; } Tcl_DStringAppend(exportPtr->dsPtr, " ", 1); Tcl_DStringAppend(exportPtr->dsPtr, attrName, -1); Tcl_DStringAppend(exportPtr->dsPtr, "=", 1); Tcl_DStringAppend(exportPtr->dsPtr, "\"", 1); XmlPutEscapeString(value, valueLen, exportPtr); Tcl_DStringAppend(exportPtr->dsPtr, "\"", 1); } static int XmlExport(Blt_Table table, ExportSwitches *exportPtr) { Blt_TableRow row; XmlStartTable(exportPtr, "root"); for (row = Blt_Table_FirstTaggedRow(&exportPtr->rIter); row != NULL; row = Blt_Table_NextTaggedRow(&exportPtr->rIter)) { Blt_TableColumn col; const char *label; XmlStartElement(exportPtr, "row"); label = Blt_Table_RowLabel(row); XmlAppendAttrib(exportPtr, "name", label, -1); for (col = Blt_Table_FirstTaggedColumn(&exportPtr->cIter); col != NULL; col = Blt_Table_NextTaggedColumn(&exportPtr->cIter)) { const char *string; label = Blt_Table_ColumnLabel(col); string = Blt_Table_GetString(table, row, col); if (string != NULL) { XmlAppendAttrib(exportPtr, label, string, -1); } } if (XmlEndElement(exportPtr) != TCL_OK) { return TCL_ERROR; } } XmlEndTable(exportPtr, "root"); return TCL_OK; } static int ExportXmlProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ExportSwitches switches; Tcl_Channel channel; Tcl_DString ds; int closeChannel; int result; closeChannel = FALSE; channel = NULL; Tcl_DStringInit(&ds); memset(&switches, 0, sizeof(switches)); rowIterSwitch.clientData = table; columnIterSwitch.clientData = table; Blt_Table_IterateAllRows(table, &switches.rIter); Blt_Table_IterateAllColumns(table, &switches.cIter); if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } result = TCL_ERROR; if (switches.fileObj != NULL) { char *fileName; closeChannel = TRUE; fileName = Tcl_GetString(switches.fileObj); if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { goto error; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for writing", (char *)NULL); goto error; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { goto error; /* Can't open export file. */ } } } switches.interp = interp; switches.dsPtr = &ds; switches.channel = channel; result = XmlExport(table, &switches); if ((switches.channel == NULL) && (result == TCL_OK)) { Tcl_DStringResult(interp, &ds); } error: Tcl_DStringFree(&ds); if (closeChannel) { Tcl_Close(interp, channel); } Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return result; } int Blt_Table_XmlInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_datatable_xml", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_Table_RegisterFormat(interp, "xml", /* Name of format. */ #ifdef HAVE_LIBEXPAT ImportXmlProc, /* Import procedure. */ #else NULL, /* Import procedure. */ #endif /* HAVE_LIBEXPAT */ ExportXmlProc); /* Export procedure. */ } �����������������������������������./saods9/blt3.0.1/src/bltString.h�������������������������������������������������������������������0000644�0001750�0001750�00000003611�11462120062�015147� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltString.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_STRING_H #define _BLT_STRING_H #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include <string.h> #endif /* HAVE_STRING_H */ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ /* * On some systems "strncasecmp" and "strcasecmp" are in the C library * but have no declarations in the C header files. Make sure we supply * them here. */ #if !HAVE_DECL_STRTOLOWER BLT_EXTERN void strtolower(char *s); #endif /* !HAVE_DECL_STRTOLOWER */ #if !HAVE_DECL_STRCASECMP BLT_EXTERN int strcasecmp(const char *s1, const char *s2); #endif /* !HAVE_DECL_STRDUP */ #if !HAVE_DECL_STRNCASECMP BLT_EXTERN int strncasecmp(const char *s1, const char *s2, size_t length); #endif /* !HAVE_DECL_STRDUP */ #endif �����������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltComboBtn.c�����������������������������������������������������������������0000644�0001750�0001750�00000167535�11462120062�015417� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltComboButton.c -- * * This module implements a combo button widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltImage.h" #include "bltHash.h" #include "bltBgStyle.h" #define IPAD 2 /* Internal pad between components. */ #define YPAD 2 /* External pad between components. */ #define XPAD 2 /* External pad between border and * button. */ #define ARROW_WIDTH 13 #define ARROW_HEIGHT 13 #define STATE_NORMAL (0) /* Draw widget normally. */ #define STATE_ACTIVE (1<<0) /* Widget is currently active. */ #define STATE_DISABLED (1<<1) /* Widget is disabled. */ #define STATE_POSTED (1<<2) /* Widget is currently posting its * menu. */ #define STATE_MASK (STATE_ACTIVE|STATE_DISABLED|STATE_POSTED) #define REDRAW_PENDING (1<<3) /* Widget is scheduled to be * redrawn. */ #define LAYOUT_PENDING (1<<4) /* Widget layout needs to be * recomputed. */ #define FOCUS (1<<5) /* Widget has focus. */ #define ARROW (1<<8) #define TEXT_VAR_TRACED (1<<16) #define ICON_VAR_TRACED (1<<17) #define TRACE_VAR_FLAGS (TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|\ TCL_TRACE_UNSETS) #define DEF_ACTIVEBACKGROUND STD_ACTIVE_BACKGROUND #define DEF_ACTIVEFOREGROUND STD_ACTIVE_FOREGROUND #define DEF_BORDERWIDTH "2" #define DEF_CMD ((char *)NULL) #define DEF_CURSOR ((char *)NULL) #define DEF_DIRECTION ((char *)NULL) #define DEF_DISABLED_BG STD_DISABLED_BACKGROUND #define DEF_DISABLED_FG STD_DISABLED_FOREGROUND #define DEF_ENTRY_BG RGB_GREY90 #define DEF_FONT STD_FONT #define DEF_HEIGHT "0" #define DEF_HIGHLIGHTBACKGROUND "" #define DEF_HIGHLIGHTCOLOR "black" #define DEF_HIGHLIGHTTHICKNESS "2" #define DEF_ICON ((char *)NULL) #define DEF_ICON_VARIABLE ((char *)NULL) #define DEF_IMAGE ((char *)NULL) #define DEF_ARROW_ON "0" #define DEF_ARROW_WIDTH "0" #define DEF_INDICTOR_ACTIVE_FG STD_ACTIVE_FOREGROUND #define DEF_ARROW_BORDERWIDTH "2" #define DEF_ARROW_DISABLED_FG STD_DISABLED_FOREGROUND #define DEF_ARROW_POSTED_FG STD_DISABLED_FOREGROUND #define DEF_ARROW_NORMAL_FG STD_NORMAL_FOREGROUND #define DEF_ARROW_RELIEF "flat" #define DEF_JUSTIFY "left" #define DEF_MENU ((char *)NULL) #define DEF_MENU_ANCHOR "sw" #define DEF_NORMAL_BG STD_NORMAL_BACKGROUND #define DEF_NORMAL_FG STD_NORMAL_FOREGROUND #define DEF_POSTED_BG RGB_SKYBLUE4 #define DEF_POSTED_FG RGB_WHITE #define DEF_NORMAL_RELIEF "raised" #define DEF_POSTED_RELIEF "flat" #define DEF_ACTIVERELIEF "raised" #define DEF_STATE "normal" #define DEF_TAKE_FOCUS "1" #define DEF_TEXT ((char *)NULL) #define DEF_TEXT_VARIABLE ((char *)NULL) #define DEF_TYPE "button" #define DEF_UNDERLINE "-1" #define DEF_WIDTH "0" static Tcl_VarTraceProc TextVarTraceProc; static Tcl_VarTraceProc IconVarTraceProc; static Blt_OptionFreeProc FreeTextProc; static Blt_OptionParseProc ObjToTextProc; static Blt_OptionPrintProc TextToObjProc; static Blt_CustomOption textOption = { ObjToTextProc, TextToObjProc, FreeTextProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0 }; static Blt_OptionFreeProc FreeTextVarProc; static Blt_OptionParseProc ObjToTextVarProc; static Blt_OptionPrintProc TextVarToObjProc; static Blt_CustomOption textVarOption = { ObjToTextVarProc, TextVarToObjProc, FreeTextVarProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconVarProc; static Blt_OptionParseProc ObjToIconVarProc; static Blt_OptionPrintProc IconVarToObjProc; static Blt_CustomOption iconVarOption = { ObjToIconVarProc, IconVarToObjProc, FreeIconVarProc, (ClientData)0 }; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; static const char *emptyString = ""; /* * Icon -- * * Since instances of the same Tk image can be displayed in different * windows with possibly different color palettes, Tk internally stores * each instance in a linked list. But if the instances are used in the * same widget and therefore use the same color palette, this adds a lot * of overhead, especially when deleting instances from the linked list. * * For the combobutton widget, we never need more than a single instance * of an image, regardless of how many times it's used. Cache the image, * maintaining a reference count for each image used in the widget. It's * likely that the comboview widget will use many instances of the same * image. */ typedef struct Icon { Tk_Image tkImage; /* The Tk image being cached. */ short int width, height; /* Dimensions of the cached image. */ } *Icon; #define IconHeight(i) ((i)->height) #define IconWidth(i) ((i)->width) #define IconImage(i) ((i)->tkImage) #define IconName(i) (Blt_Image_Name((i)->tkImage)) typedef struct { Tcl_Interp *interp; /* Interpreter associated with * button. */ Tk_Window tkwin; /* Window that embodies the combo * button. If NULL, indicates the * window has been destroyed but the * data structures haven't yet been * cleaned up.*/ Display *display; /* Display containing widget. Used, * among other things, so that * resources can be freed even after * tkwin has gone away. */ Tcl_Command cmdToken; /* Token for widget command. */ int reqWidth, reqHeight; int relief, postedRelief, activeRelief; int borderWidth; Blt_Background normalBg; Blt_Background activeBg; Blt_Background postedBg; Blt_Background disabledBg; Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not * used in the C code, but used by * keyboard traversal scripts. */ /* * In/Out Focus Highlight Ring: */ XColor *highlightColor; GC highlightGC; XColor *highlightBgColor; GC highlightBgGC; int highlightWidth; /* * The button contains an optional icon and text string. */ Icon icon; /* If non-NULL, image to be displayed * in button. Its value may be * overridden by the -iconvariable * option. */ Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable contains the name of * an image representing the icon. * This overrides the value of the * above field. */ Icon image; /* If non-NULL, image to be displayed * instead of text in the button. */ const char *text; /* Text string to be displayed in the * button if an image has no been * designated. Its value is overridden * by the -textvariable option. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable contains the text * string to be displayed in the * button. This overrides the above * field. */ Blt_Font font; /* Font of text to be display in * button. */ Tk_Justify justify; /* Justification to use for text * within the button. */ int textLen; /* # bytes of text. */ int underline; /* Character index of character to be * underlined. If -1, no character is * underlined. */ XColor *textNormalColor; XColor *textActiveColor; XColor *textPostedColor; XColor *textDisabledColor; /* * Arrow (button) Information: * * The arrow is a button with an optional 3D border. */ int arrowBW; int arrowPad; int arrowRelief; int reqArrowWidth; Tk_Cursor cursor; /* Current cursor or * None. */ int prefWidth; /* Desired width of window, measured * in average characters. */ int inset; short int arrowWidth, arrowHeight; short int iconWidth, iconHeight; short int entryWidth, entryHeight; short int textWidth, textHeight; short int width, height; Tcl_Obj *cmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ Tcl_Obj *menuObjPtr; Tcl_Obj *postCmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ int menuAnchor; unsigned int flags; } ComboButton; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_ACTIVEBACKGROUND, Blt_Offset(ComboButton, activeBg),0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_ACTIVEFOREGROUND, Blt_Offset(ComboButton, textActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_ACTIVERELIEF, Blt_Offset(ComboButton, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-arrowon", "arrowOn", "ArrowOn", DEF_ARROW_ON, Blt_Offset(ComboButton, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)ARROW}, {BLT_CONFIG_PIXELS_NNEG, "-arrowborderwidth", "arrowBorderWidth", "ArrowBorderWidth", DEF_ARROW_BORDERWIDTH, Blt_Offset(ComboButton, arrowBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-arrowrelief", "arrowRelief","ArrowRelief", DEF_ARROW_RELIEF, Blt_Offset(ComboButton, arrowRelief), 0}, {BLT_CONFIG_PIXELS_NNEG, "-arrowwidth", "arrowWidth","ArrowWidth", DEF_ARROW_WIDTH, Blt_Offset(ComboButton, reqArrowWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_NORMAL_BG, Blt_Offset(ComboButton, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(ComboButton, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_CMD, Blt_Offset(ComboButton, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(ComboButton, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", "disabledBackground", "DisabledBackground", DEF_DISABLED_BG, Blt_Offset(ComboButton, disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_DISABLED_FG, Blt_Offset(ComboButton, textDisabledColor), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_FONT, Blt_Offset(ComboButton, font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_NORMAL_FG, Blt_Offset(ComboButton, textNormalColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(ComboButton, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HIGHLIGHTBACKGROUND, Blt_Offset(ComboButton, highlightBgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHTCOLOR, Blt_Offset(ComboButton, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHTTHICKNESS, Blt_Offset(ComboButton, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", DEF_ICON, Blt_Offset(ComboButton, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-iconvariable", "iconVariable", "IconVariable", DEF_TEXT_VARIABLE, Blt_Offset(ComboButton, iconVarObjPtr), BLT_CONFIG_NULL_OK, &iconVarOption}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", DEF_IMAGE, Blt_Offset(ComboButton, image), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_JUSTIFY, Blt_Offset(ComboButton, justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-menu", "menu", "Menu", DEF_MENU, Blt_Offset(ComboButton, menuObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-menuanchor", "menuAnchor", "MenuAnchor", DEF_MENU_ANCHOR, Blt_Offset(ComboButton, menuAnchor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-postcommand", "postCommand", "PostCommand", DEF_CMD, Blt_Offset(ComboButton, postCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-postedbackground", "postedBackground", "PostedBackground", DEF_POSTED_BG, Blt_Offset(ComboButton, postedBg),0}, {BLT_CONFIG_COLOR, "-postedforeground", "postedForeground", "PostedForeground", DEF_POSTED_FG, Blt_Offset(ComboButton, textPostedColor), 0}, {BLT_CONFIG_RELIEF, "-postedrelief", "postedRelief", "PostedRelief", DEF_POSTED_RELIEF, Blt_Offset(ComboButton, postedRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_NORMAL_RELIEF, Blt_Offset(ComboButton, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-state", "state", "State", DEF_STATE, Blt_Offset(ComboButton, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, Blt_Offset(ComboButton, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-text", "text", "Text", DEF_TEXT, Blt_Offset(ComboButton, text), 0, &textOption}, {BLT_CONFIG_CUSTOM, "-textvariable", "textVariable", "TextVariable", DEF_TEXT_VARIABLE, Blt_Offset(ComboButton, textVarObjPtr), BLT_CONFIG_NULL_OK, &textVarOption}, {BLT_CONFIG_INT, "-underline", "underline", "Underline", DEF_UNDERLINE, Blt_Offset(ComboButton, underline), BLT_CONFIG_DONT_SET_DEFAULT }, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(ComboButton, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Tcl_IdleProc DisplayComboButton; static Tcl_FreeProc DestroyComboButton; static Tk_EventProc ComboButtonEventProc; static Tcl_ObjCmdProc ComboButtonInstCmdProc; static Tcl_CmdDeleteProc ComboButtonInstCmdDeletedProc; /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the combobutton display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(ComboButton *comboPtr) { if ((comboPtr->tkwin != NULL) && ((comboPtr->flags & REDRAW_PENDING) == 0)){ comboPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayComboButton, comboPtr); } } static int UpdateTextVar(Tcl_Interp *interp, ComboButton *comboPtr) { Tcl_Obj *resultObjPtr, *objPtr; objPtr = Tcl_NewStringObj(comboPtr->text, comboPtr->textLen); Tcl_IncrRefCount(objPtr); resultObjPtr = Tcl_ObjSetVar2(interp, comboPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); Tcl_DecrRefCount(objPtr); if (resultObjPtr == NULL) { return TCL_ERROR; } return TCL_OK; } static int UpdateIconVar(Tcl_Interp *interp, ComboButton *comboPtr) { Tcl_Obj *resultObjPtr, *objPtr; if (comboPtr->icon != NULL) { objPtr = Tcl_NewStringObj(IconName(comboPtr->icon), -1); } else { objPtr = Tcl_NewStringObj("", -1); } Tcl_IncrRefCount(objPtr); resultObjPtr = Tcl_ObjSetVar2(interp, comboPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); Tcl_DecrRefCount(objPtr); if (resultObjPtr == NULL) { return TCL_ERROR; } return TCL_OK; } static void FreeIcon(ComboButton *comboPtr, Icon icon) { Tk_FreeImage(IconImage(icon)); Blt_Free(icon); } static char * GetInterpResult(Tcl_Interp *interp) { #define MAX_ERR_MSG 1023 static char mesg[MAX_ERR_MSG+1]; strncpy(mesg, Tcl_GetStringResult(interp), MAX_ERR_MSG); mesg[MAX_ERR_MSG] = '\0'; return mesg; } static void SetTextFromObj(ComboButton *comboPtr, Tcl_Obj *objPtr) { int nBytes; const char *string; if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); } string = Tcl_GetStringFromObj(objPtr, &nBytes); comboPtr->text = Blt_AssertMalloc(nBytes + 1); strcpy((char *)comboPtr->text, string); comboPtr->textLen = nBytes; comboPtr->flags |= LAYOUT_PENDING; comboPtr->underline = -1; } /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { ComboButton *comboPtr = clientData; comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } static int GetIconFromObj( Tcl_Interp *interp, ComboButton *comboPtr, Tcl_Obj *objPtr, Icon *iconPtr) { Tk_Image tkImage; const char *iconName; iconName = Tcl_GetString(objPtr); if (iconName[0] == '\0') { *iconPtr = NULL; return TCL_OK; } tkImage = Tk_GetImage(interp, comboPtr->tkwin, iconName, IconChangedProc, comboPtr); if (tkImage != NULL) { struct Icon *ip; int width, height; ip = Blt_AssertMalloc(sizeof(struct Icon)); Tk_SizeOfImage(tkImage, &width, &height); ip->tkImage = tkImage; ip->width = width; ip->height = height; *iconPtr = ip; return TCL_OK; } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ComboButtonEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * combobutton widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ComboButtonEventProc(ClientData clientData, XEvent *eventPtr) { ComboButton *comboPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(comboPtr); } } else if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(comboPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { comboPtr->flags |= FOCUS; } else { comboPtr->flags &= ~FOCUS; } EventuallyRedraw(comboPtr); } else if (eventPtr->type == DestroyNotify) { if (comboPtr->tkwin != NULL) { comboPtr->tkwin = NULL; } if (comboPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayComboButton, comboPtr); } Tcl_EventuallyFree(comboPtr, DestroyComboButton); } } /* *--------------------------------------------------------------------------- * * TextVarTraceProc -- * * This procedure is invoked when someone changes the state variable * associated with a combobutton. * * Results: * NULL is always returned. * *--------------------------------------------------------------------------- */ static char * TextVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { ComboButton *comboPtr = clientData; assert(comboPtr->textVarObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { if (flags & TCL_TRACE_DESTROYED) { Tcl_SetVar(interp, name1, comboPtr->text, TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, name1, TRACE_VAR_FLAGS, TextVarTraceProc, clientData); comboPtr->flags |= TEXT_VAR_TRACED; } return NULL; } if (flags & TCL_TRACE_WRITES) { Tcl_Obj *valueObjPtr; /* * Update the combobutton's text with the value of the variable, * unless the widget already has that value (this happens when the * variable changes value because we changed it because someone typed * in the entry). */ valueObjPtr = Tcl_ObjGetVar2(interp, comboPtr->textVarObjPtr, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (valueObjPtr == NULL) { return GetInterpResult(interp); } else { SetTextFromObj(comboPtr, valueObjPtr); } EventuallyRedraw(comboPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * IconVarTraceProc -- * * This procedure is invoked when someone changes the state * variable associated with combobutton. * * Results: * NULL is always returned. * *--------------------------------------------------------------------------- */ static char * IconVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { ComboButton *comboPtr = clientData; assert(comboPtr->iconVarObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { if (flags & TCL_TRACE_DESTROYED) { Tcl_SetVar(interp, name1, IconName(comboPtr->icon),TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, name1, TRACE_VAR_FLAGS, IconVarTraceProc, clientData); comboPtr->flags |= ICON_VAR_TRACED; } return NULL; } if (flags & TCL_TRACE_WRITES) { Icon icon; Tcl_Obj *valueObjPtr; /* * Update the combobutton's icon with the image whose name is * stored in the variable. */ valueObjPtr = Tcl_ObjGetVar2(interp, comboPtr->iconVarObjPtr, NULL, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); if (valueObjPtr == NULL) { return GetInterpResult(interp); } if (GetIconFromObj(interp, comboPtr, valueObjPtr, &icon) != TCL_OK) { return GetInterpResult(interp); } if (comboPtr->icon != NULL) { FreeIcon(comboPtr, comboPtr->icon); } comboPtr->icon = icon; comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } return NULL; } /*ARGSUSED*/ static void FreeIconVarProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); if (*objPtrPtr != NULL) { ComboButton *comboPtr = (ComboButton *)widgRec; Tcl_UntraceVar(comboPtr->interp, Tcl_GetString(*objPtrPtr), TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToIconVarProc -- * * Convert the variable to a traced variable. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)(widgRec); Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); char *varName; Tcl_Obj *valueObjPtr; /* Remove the current trace on the variable. */ if (*objPtrPtr != NULL) { Tcl_UntraceVar(interp, Tcl_GetString(*objPtrPtr), TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } valueObjPtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_GLOBAL_ONLY); if (valueObjPtr != NULL) { Icon icon; if (GetIconFromObj(interp, comboPtr, valueObjPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (comboPtr->icon != NULL) { FreeIcon(comboPtr, comboPtr->icon); } comboPtr->icon = icon; } *objPtrPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, TRACE_VAR_FLAGS, IconVarTraceProc, comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconVarToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *objPtr = *(Tcl_Obj **)(widgRec + offset); if (objPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /*ARGSUSED*/ static void FreeTextVarProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); if (*objPtrPtr != NULL) { ComboButton *comboPtr = (ComboButton *)(widgRec); char *varName; varName = Tcl_GetString(*objPtrPtr); Tcl_UntraceVar(comboPtr->interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToTextVarProc -- * * Convert the variable to a traced variable. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTextVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)(widgRec); Tcl_Obj **objPtrPtr = (Tcl_Obj **)(widgRec + offset); char *varName; Tcl_Obj *valueObjPtr; /* Remove the current trace on the variable. */ if (*objPtrPtr != NULL) { varName = Tcl_GetString(*objPtrPtr); Tcl_UntraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); Tcl_DecrRefCount(*objPtrPtr); *objPtrPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } valueObjPtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_GLOBAL_ONLY); if (valueObjPtr != NULL) { SetTextFromObj(comboPtr, valueObjPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVar(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } } *objPtrPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, TRACE_VAR_FLAGS, TextVarTraceProc, comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextVarToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TextVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *objPtr = *(Tcl_Obj **)(widgRec + offset); if (objPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Converts the string representing a state into a bitflag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "disabled") == 0) { flag = STATE_DISABLED; } else if (strcmp(string, "normal") == 0) { flag = STATE_NORMAL; } else if (strcmp(string, "active") == 0) { flag = STATE_ACTIVE; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } if (comboPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } *flagsPtr &= ~STATE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); const char *string; switch (state & STATE_MASK) { case STATE_NORMAL: string = "normal"; break; case STATE_ACTIVE: string = "active"; break; case STATE_POSTED: string = "posted"; break; case STATE_DISABLED: string = "disabled"; break; default: string = Blt_Itoa(state & STATE_MASK); break; } return Tcl_NewStringObj(string, -1); } /*ARGSUSED*/ static void FreeIconProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Icon icon = *(Icon *)(widgRec + offset); if (icon != NULL) { ComboButton *comboPtr = (ComboButton *)widgRec; FreeIcon(comboPtr, icon); } } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Convert a image into a hashed icon. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)widgRec; Icon *iconPtr = (Icon *)(widgRec + offset); Icon icon; if (GetIconFromObj(interp, comboPtr, objPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (*iconPtr != NULL) { FreeIcon(comboPtr, *iconPtr); } *iconPtr = icon; if (comboPtr->iconVarObjPtr != NULL) { if (UpdateIconVar(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon icon = *(Icon *)(widgRec + offset); Tcl_Obj *objPtr; if (icon == NULL) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr =Tcl_NewStringObj(Blt_Image_Name(IconImage(icon)), -1); } return objPtr; } /*ARGSUSED*/ static void FreeTextProc(ClientData clientData, Display *display, char *widgRec, int offset) { ComboButton *comboPtr = (ComboButton *)(widgRec); if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); comboPtr->text = emptyString; comboPtr->textLen = 0; } } /* *--------------------------------------------------------------------------- * * ObjToTextProc -- * * Save the text and add the item to the text hashtable. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTextProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)(widgRec); if (comboPtr->text != emptyString) { Blt_Free(comboPtr->text); comboPtr->text = emptyString; comboPtr->textLen = 0; } SetTextFromObj(comboPtr, objPtr); if (comboPtr->textVarObjPtr != NULL) { if (UpdateTextVar(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextToObjProc -- * * Return the text of the item. * * Results: * The text is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TextToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { ComboButton *comboPtr = (ComboButton *)(widgRec); return Tcl_NewStringObj(comboPtr->text, comboPtr->textLen); } /* *--------------------------------------------------------------------------- * H * C * L * P * max of icon/text/image/button * P * L * C * H * * |H|C|L|P| icon |P| text/image |P|L|B| button |B|C|H| * * H = highlight thickness * C = combobutton borderwidth * L = label borderwidth * P = pad * I = icon * T = text or image *--------------------------------------------------------------------------- */ static void ComputeGeometry(ComboButton *comboPtr) { int width, height; /* Determine the height of the button. It's the maximum height of all * it's components: icon, label, and button. */ comboPtr->iconWidth = comboPtr->iconHeight = 0; comboPtr->entryWidth = comboPtr->entryHeight = 0; comboPtr->textWidth = comboPtr->textHeight = 0; comboPtr->arrowWidth = comboPtr->arrowHeight = 0; comboPtr->inset = comboPtr->arrowWidth + comboPtr->highlightWidth; if (comboPtr->icon != NULL) { comboPtr->iconWidth = IconWidth(comboPtr->icon); comboPtr->iconHeight = IconHeight(comboPtr->icon); } comboPtr->entryWidth += comboPtr->iconWidth; if (comboPtr->entryHeight < comboPtr->iconHeight) { comboPtr->entryHeight = comboPtr->iconHeight; } if (comboPtr->image != NULL) { comboPtr->textWidth = IconWidth(comboPtr->image); comboPtr->textHeight = IconHeight(comboPtr->image); } else if (comboPtr->text != NULL) { unsigned int w, h; if (comboPtr->text[0] == '\0') { Blt_FontMetrics fm; Blt_GetFontMetrics(comboPtr->font, &fm); comboPtr->textHeight = fm.linespace; } else { Blt_GetTextExtents(comboPtr->font, 0, comboPtr->text, comboPtr->textLen, &w, &h); comboPtr->textWidth = w + 2 * IPAD; comboPtr->textHeight = h; } } comboPtr->entryWidth += comboPtr->textWidth + IPAD; if (comboPtr->iconWidth == 0) { comboPtr->entryWidth += IPAD; } if (comboPtr->entryHeight < comboPtr->textHeight) { comboPtr->entryHeight = comboPtr->textHeight; } if (comboPtr->flags & ARROW) { comboPtr->arrowHeight = ARROW_HEIGHT; if (comboPtr->reqArrowWidth > 0) { comboPtr->arrowWidth = comboPtr->reqArrowWidth; } else { comboPtr->arrowWidth = Blt_TextWidth(comboPtr->font, "0", 1) + 4; } comboPtr->arrowWidth += 2 * (comboPtr->arrowBW + comboPtr->arrowPad); comboPtr->arrowHeight += 2 * (comboPtr->arrowBW + comboPtr->arrowPad); if (comboPtr->arrowHeight > comboPtr->entryHeight) { comboPtr->entryHeight = comboPtr->arrowHeight; } } comboPtr->entryHeight += 2 * YPAD; comboPtr->entryWidth += 2 * XPAD; comboPtr->width = comboPtr->entryWidth + comboPtr->arrowWidth + 2 * comboPtr->inset; comboPtr->height = comboPtr->entryHeight + 2 * comboPtr->inset; if (comboPtr->flags & ARROW) { comboPtr->width += comboPtr->borderWidth; } width = (comboPtr->reqWidth > 0) ? comboPtr->reqWidth : comboPtr->width; height = (comboPtr->reqHeight > 0) ? comboPtr->reqHeight : comboPtr->height; if ((width != Tk_ReqWidth(comboPtr->tkwin)) || (height != Tk_ReqHeight(comboPtr->tkwin))) { Tk_GeometryRequest(comboPtr->tkwin, width, height); } comboPtr->flags &= ~LAYOUT_PENDING; } static int ConfigureComboButton( Tcl_Interp *interp, ComboButton *comboPtr, int objc, Tcl_Obj *const *objv, int flags) { unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, configSpecs, objc, objv, (char *)comboPtr, flags) != TCL_OK) { return TCL_ERROR; } /* Focus highlight GCs */ gcMask = GCForeground; gcValues.foreground = comboPtr->highlightColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->highlightGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightGC); } comboPtr->highlightGC = newGC; if (comboPtr->highlightBgColor != NULL) { gcValues.foreground = comboPtr->highlightBgColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); } else { newGC = NULL; } if (comboPtr->highlightBgGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightBgGC); } comboPtr->highlightBgGC = newGC; ComputeGeometry(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activates * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb activate bool * *--------------------------------------------------------------------------- */ static int ActivateOp(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; if (comboPtr->flags & (STATE_POSTED|STATE_DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } if (Tcl_GetBooleanFromObj(interp, objv[2], &bool) != TCL_OK) { return TCL_ERROR; } comboPtr->flags &= ~STATE_ACTIVE; if (bool) { comboPtr->flags |= STATE_ACTIVE; } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb cget option * *--------------------------------------------------------------------------- */ static int CgetOp(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; iconOption.clientData = comboPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, (Tcl_Obj *)NULL, BLT_CONFIG_OBJV_ONLY); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, configSpecs, (char *)comboPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } Tcl_Preserve(comboPtr); result = ConfigureComboButton(interp, comboPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(comboPtr); if (result == TCL_ERROR) { return TCL_ERROR; } comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cb invoke item * *--------------------------------------------------------------------------- */ static int InvokeOp(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; if (comboPtr->flags & STATE_DISABLED) { return TCL_OK; /* Item is currently disabled. */ } result = TCL_OK; if (comboPtr->cmdObjPtr != NULL) { Tcl_Preserve(comboPtr); Tcl_IncrRefCount(comboPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->cmdObjPtr); Tcl_Release(comboPtr); } return result; } /* *--------------------------------------------------------------------------- * * PostOp -- * * Posts the menu associated with this widget. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .ce post * *--------------------------------------------------------------------------- */ static int PostOp(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *menuName; Tk_Window menuWin; if (comboPtr->flags & (STATE_POSTED|STATE_DISABLED)) { return TCL_OK; /* Button's menu is currently posted * or entry is disabled. */ } if (comboPtr->menuObjPtr == NULL) { return TCL_OK; } menuName = Tcl_GetString(comboPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "can't post \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (comboPtr->postCmdObjPtr) { int result; Tcl_Preserve(comboPtr); Tcl_IncrRefCount(comboPtr->postCmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->postCmdObjPtr,TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->postCmdObjPtr); Tcl_Release(comboPtr); if (result != TCL_OK) { return TCL_ERROR; } } if (Tk_IsMapped(comboPtr->tkwin)) { Tcl_Obj *cmd[5]; int result; int rootX, rootY; Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); cmd[0] = comboPtr->menuObjPtr; cmd[1] = Tcl_NewStringObj("post", 4); cmd[2] = Tcl_NewIntObj(rootX); cmd[3] = Tcl_NewIntObj(rootY + Tk_Height(comboPtr->tkwin)); cmd[4] = Tcl_NewStringObj("left", 4); Tcl_Preserve(comboPtr); result = Blt_GlobalEvalObjv(interp, 5, cmd); Tcl_Release(comboPtr); if (result == TCL_OK) { comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= STATE_POSTED; } EventuallyRedraw(comboPtr); return result; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnpostOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .ce unpost * *--------------------------------------------------------------------------- */ static int UnpostOp( ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { #ifdef notdef fprintf(stderr, "UnpostOp\n"); fprintf(stderr, "menuObjPtr=%x\n", comboPtr->menuObjPtr); fprintf(stderr, "flags=Posted%d,Disabled%d\n", comboPtr->flags & STATE_POSTED, comboPtr->flags & STATE_DISABLED); #endif if ((comboPtr->menuObjPtr != NULL) && (comboPtr->flags & STATE_POSTED)) { char *menuName; Tk_Window menuWin; comboPtr->flags &= ~STATE_MASK; comboPtr->flags |= STATE_NORMAL; menuName = Tcl_GetString(comboPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "can't unpost \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (Tk_IsMapped(menuWin)) { Tk_UnmapWindow(menuWin); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyComboButton -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed. * *--------------------------------------------------------------------------- */ static void DestroyComboButton(DestroyData dataPtr) /* Pointer to the widget record. */ { ComboButton *comboPtr = (ComboButton *)dataPtr; iconOption.clientData = comboPtr; Blt_FreeOptions(configSpecs, (char *)comboPtr, comboPtr->display, 0); if (comboPtr->highlightGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightGC); } if (comboPtr->highlightBgGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->highlightBgGC); } Tcl_DeleteCommandFromToken(comboPtr->interp, comboPtr->cmdToken); Blt_Free(comboPtr); } /* *--------------------------------------------------------------------------- * * NewComboButton -- * *--------------------------------------------------------------------------- */ static ComboButton * NewComboButton(Tcl_Interp *interp, Tk_Window tkwin) { ComboButton *comboPtr; comboPtr = Blt_AssertCalloc(1, sizeof(ComboButton)); comboPtr->borderWidth = 1; comboPtr->display = Tk_Display(tkwin); comboPtr->flags = (LAYOUT_PENDING | STATE_NORMAL); comboPtr->highlightWidth = 2; comboPtr->arrowBW = 2; comboPtr->arrowRelief = TK_RELIEF_FLAT; comboPtr->interp = interp; comboPtr->menuAnchor = TK_ANCHOR_SW; comboPtr->relief = TK_RELIEF_RAISED; comboPtr->postedRelief = TK_RELIEF_FLAT; comboPtr->activeRelief = TK_RELIEF_RAISED; comboPtr->text = emptyString; comboPtr->textLen = 0; comboPtr->tkwin = tkwin; comboPtr->underline = -1; return comboPtr; } /* *--------------------------------------------------------------------------- * * ComboButtonCmd -- * * This procedure is invoked to process the "combobutton" command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec comboButtonOps[] = { {"activate", 1, ActivateOp, 3, 3, "bool",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"invoke", 1, InvokeOp, 2, 2, "",}, {"post", 1, PostOp, 2, 2, "",}, {"unpost", 1, UnpostOp, 2, 2, "",}, }; static int nComboButtonOps = sizeof(comboButtonOps) / sizeof(Blt_OpSpec); typedef int (ComboInstOp)(ComboButton *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int ComboButtonInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { ComboInstOp *proc; ComboButton *comboPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nComboButtonOps, comboButtonOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(comboPtr); result = (*proc) (comboPtr, interp, objc, objv); Tcl_Release(comboPtr); return result; } /* *--------------------------------------------------------------------------- * * ComboButtonInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ComboButtonInstCmdDeletedProc(ClientData clientData) { ComboButton *comboPtr = clientData; /* Pointer to widget record. */ if (comboPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = comboPtr->tkwin; comboPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ComboButtonCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ComboButtonCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboButton *comboPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, set up procs and initialize various * bindings for the widget. If the proc doesn't already exist, source it * from "$blt_library/comboentry.tcl". We've deferred sourcing this file * until now so that the user could reset the variable $blt_library from * within her script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ComboButton::PostMenu", &cmdInfo)) { static char cmd[] = "source [file join $blt_library combobutton.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } comboPtr = NewComboButton(interp, tkwin); #define EVENT_MASK (ExposureMask|StructureNotifyMask|FocusChangeMask) Tk_CreateEventHandler(tkwin, EVENT_MASK, ComboButtonEventProc, comboPtr); Tk_SetClass(tkwin, "ComboButton"); comboPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ComboButtonInstCmdProc, comboPtr, ComboButtonInstCmdDeletedProc); Blt_SetWindowInstanceData(tkwin, comboPtr); if (ConfigureComboButton(interp, comboPtr, objc-2, objv+2, 0) != TCL_OK) { Tk_DestroyWindow(comboPtr->tkwin); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_ComboButtonInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "combobutton", ComboButtonCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* *--------------------------------------------------------------------------- * * DrawLabel -- * * Draws the text associated with the label. This is used when the * widget acts like a standard label. * * Results: * Nothing. * *--------------------------------------------------------------------------- */ static void DrawLabel(ComboButton *comboPtr, Drawable drawable, int x, int y, int w, int h) { if (comboPtr->image != NULL) { int imgWidth, imgHeight; imgWidth = MIN(w, comboPtr->textWidth) - IPAD; imgHeight = MIN(h, comboPtr->textHeight); Tk_RedrawImage(IconImage(comboPtr->image), 0, 0, imgWidth, imgHeight, drawable, x + IPAD, y); } else { TextStyle ts; XColor *fg; if (comboPtr->flags & STATE_POSTED) { fg = comboPtr->textPostedColor; } else if (comboPtr->flags & STATE_ACTIVE) { fg = comboPtr->textActiveColor; } else if (comboPtr->flags & STATE_DISABLED) { fg = comboPtr->textDisabledColor; } else { fg = comboPtr->textNormalColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, comboPtr->font); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetJustify(ts, comboPtr->justify); Blt_Ts_SetUnderline(ts, comboPtr->underline); Blt_Ts_SetMaxLength(ts, w); Blt_Ts_SetForeground(ts, fg); Blt_Ts_DrawText(comboPtr->tkwin, drawable, comboPtr->text, comboPtr->textLen, &ts, x + IPAD, y); } } static void DrawComboButton(ComboButton *comboPtr, Drawable drawable) { Blt_Background bg; int x, y; int w, h; int relief; /* ComboButton background (just inside of focus highlight ring). */ if (comboPtr->flags & STATE_POSTED) { bg = comboPtr->postedBg; } else if (comboPtr->flags & STATE_ACTIVE) { bg = comboPtr->activeBg; } else if (comboPtr->flags & STATE_DISABLED) { bg = comboPtr->disabledBg; } else { bg = comboPtr->normalBg; } Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, 0, 0, Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin), comboPtr->borderWidth, TK_RELIEF_FLAT); x = y = comboPtr->inset; w = Tk_Width(comboPtr->tkwin) - (2 * comboPtr->inset); h = Tk_Height(comboPtr->tkwin) - (2 * comboPtr->inset); /* Label: includes icon and text. */ if (h > comboPtr->entryHeight) { y += (h - comboPtr->entryHeight) / 2; } x += XPAD; /* Draw Icon. */ if (comboPtr->icon != NULL) { int ix, iy, iw, ih; ix = x; iy = y; if (comboPtr->iconHeight < comboPtr->entryHeight) { iy += (comboPtr->entryHeight - comboPtr->iconHeight) / 2; } iw = MIN(w, comboPtr->iconWidth); ih = MIN(h, comboPtr->iconHeight); Tk_RedrawImage(IconImage(comboPtr->icon), 0, 0, iw, ih,drawable, ix,iy); x += comboPtr->iconWidth + IPAD; w -= comboPtr->iconWidth + IPAD; } if ((w > 0) && (h > 0)) { int tx, ty, tw, th; tx = x + IPAD; ty = y; if (comboPtr->entryHeight > comboPtr->textHeight) { ty += (comboPtr->entryHeight - comboPtr->textHeight) / 2; } tw = MIN(w, comboPtr->textWidth); th = MIN(h, comboPtr->textHeight); DrawLabel(comboPtr, drawable, tx, ty, tw, th); } /* Arrow button. */ if (comboPtr->flags & ARROW) { XColor *color; x = Tk_Width(comboPtr->tkwin) - comboPtr->inset - comboPtr->arrowWidth; y = comboPtr->inset; if (h > comboPtr->entryHeight) { y += (h - comboPtr->entryHeight) / 2; } if (x < 0) { x = comboPtr->inset; } Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, comboPtr->arrowWidth, comboPtr->entryHeight, comboPtr->arrowBW, comboPtr->arrowRelief); if (comboPtr->flags & STATE_POSTED) { color = comboPtr->textPostedColor; } else if (comboPtr->flags & STATE_ACTIVE) { color = comboPtr->textActiveColor; } else if (comboPtr->flags & STATE_DISABLED) { color = comboPtr->textDisabledColor; } else { color = comboPtr->textNormalColor; } Blt_DrawArrow(comboPtr->display, drawable, color, x, y, comboPtr->arrowWidth, comboPtr->entryHeight, comboPtr->arrowBW, ARROW_DOWN); } /* Draw focus highlight ring. */ if (comboPtr->highlightWidth > 0) { if (comboPtr->flags & FOCUS) { Tk_DrawFocusHighlight(comboPtr->tkwin, comboPtr->highlightGC, comboPtr->highlightWidth, drawable); } else { Blt_Background bg; if (comboPtr->flags & STATE_POSTED) { bg = comboPtr->postedBg; } else if (comboPtr->flags & STATE_DISABLED) { bg = comboPtr->disabledBg; } else { bg = comboPtr->normalBg; } Blt_DrawFocusBackground(comboPtr->tkwin, bg, comboPtr->highlightWidth, drawable); } } if (comboPtr->flags & STATE_POSTED) { relief = comboPtr->postedRelief; } else if (comboPtr->flags & STATE_ACTIVE) { relief = comboPtr->activeRelief; } else { relief = comboPtr->relief; } if (relief != TK_RELIEF_FLAT) { Blt_DrawBackgroundRectangle(comboPtr->tkwin, drawable, bg, comboPtr->highlightWidth, comboPtr->highlightWidth, Tk_Width(comboPtr->tkwin) - 2 * comboPtr->highlightWidth, Tk_Height(comboPtr->tkwin) - 2 * comboPtr->highlightWidth, comboPtr->borderWidth, relief); } } /* *--------------------------------------------------------------------------- * * DisplayComboButton -- * * This procedure is invoked to display a combobutton widget. * * Results: * None. * * Side effects: * Commands are output to X to display the button. * *--------------------------------------------------------------------------- */ static void DisplayComboButton(ClientData clientData) { ComboButton *comboPtr = clientData; Pixmap drawable; int w, h; /* Window width and height. */ comboPtr->flags &= ~REDRAW_PENDING; if (comboPtr->tkwin == NULL) { return; /* Window destroyed (should not get * here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayComboButton(%s)\n", Tk_PathName(comboPtr->tkwin)); #endif w = Tk_Width(comboPtr->tkwin); h = Tk_Height(comboPtr->tkwin); if ((w <= 1) || (h <=1)) { /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (comboPtr->flags & LAYOUT_PENDING) { ComputeGeometry(comboPtr); } if (!Tk_IsMapped(comboPtr->tkwin)) { /* The widget's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the combobutton's new layout. */ return; } /* Create a pixmap the size of the window for double buffering. */ drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif DrawComboButton(comboPtr, drawable); XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->highlightGC, 0, 0, w, h, 0, 0); Tk_FreePixmap(comboPtr->display, drawable); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltNsUtil.c�������������������������������������������������������������������0000644�0001750�0001750�00000013511�11462120062�015112� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltNsUtil.c -- * * This module implements utility namespace procedures for the BLT toolkit. * * Copyright 1997-2008 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltNsUtil.h" /* * A Command structure exists for each command in a namespace. The Tcl_Command * opaque type actually refers to these structures. */ typedef struct CompileProc CompileProc; typedef struct ImportRef ImportRef; typedef struct CommandTrace CommandTrace; typedef struct { Tcl_HashEntry *hPtr; /* Pointer to the hash table entry that refers * to this command. The hash table is either a * namespace's command table or an * interpreter's hidden command table. This * pointer is used to get a command's name * from its Tcl_Command handle. NULL means * that the hash table entry has been removed * already (this can happen if deleteProc * causes the command to be deleted or * recreated). */ Tcl_Namespace *nsPtr; /* Points to the namespace containing this * command. */ int refCount; /* 1 if in command hashtable plus 1 for each * reference from a CmdName TCL object * representing a command's name in a ByteCode * instruction sequence. This structure can be * freed when refCount becomes zero. */ int cmdEpoch; /* Incremented to invalidate any references * that point to this command when it is * renamed, deleted, hidden, or exposed. */ CompileProc *compileProc; /* Procedure called to compile command. NULL * if no compile proc exists for command. */ Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */ ClientData objClientData; /* Arbitrary value passed to object proc. */ Tcl_CmdProc *proc; /* String-based command procedure. */ ClientData clientData; /* Arbitrary value passed to string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure invoked when deleting command * to, e.g., free all client data. */ ClientData deleteData; /* Arbitrary value passed to deleteProc. */ int flags; /* Means that the command is in the process of * being deleted (its deleteProc is currently * executing). Other attempts to delete the * command should be ignored. */ ImportRef *importRefPtr; /* List of each imported Command created in * another namespace when this command is * imported. These imported commands redirect * invocations back to this command. The list * is used to remove all those imported * commands when deleting this "real" * command. */ CommandTrace *tracePtr; /* First in list of all traces set for this * command. */ } Command; /*ARGSUSED*/ Tcl_Namespace * Blt_GetCommandNamespace(Tcl_Command cmdToken) { Command *cmdPtr = (Command *)cmdToken; return (Tcl_Namespace *)cmdPtr->nsPtr; } Tcl_CallFrame * Blt_EnterNamespace(Tcl_Interp *interp, Tcl_Namespace *nsPtr) { Tcl_CallFrame *framePtr; framePtr = Blt_AssertMalloc(sizeof(Tcl_CallFrame)); if (Tcl_PushCallFrame(interp, framePtr, (Tcl_Namespace *)nsPtr, 0) != TCL_OK) { Blt_Free(framePtr); return NULL; } return framePtr; } void Blt_LeaveNamespace(Tcl_Interp *interp, Tcl_CallFrame *framePtr) { Tcl_PopCallFrame(interp); Blt_Free(framePtr); } int Blt_ParseObjectName(Tcl_Interp *interp, const char *path, Blt_ObjectName *namePtr, unsigned int flags) { char *last, *colon; namePtr->nsPtr = NULL; namePtr->name = NULL; colon = NULL; /* Find the last namespace separator in the qualified name. */ last = (char *)(path + strlen(path)); while (--last > path) { if ((*last == ':') && (*(last - 1) == ':')) { last++; /* just after the last "::" */ colon = last - 2; break; } } if (colon == NULL) { namePtr->name = path; if ((flags & BLT_NO_DEFAULT_NS) == 0) { namePtr->nsPtr = Tcl_GetCurrentNamespace(interp); } return TRUE; /* No namespace designated in name. */ } /* Separate the namespace and the object name. */ *colon = '\0'; if (path[0] == '\0') { namePtr->nsPtr = Tcl_GetGlobalNamespace(interp); } else { namePtr->nsPtr = Tcl_FindNamespace(interp, (char *)path, NULL, (flags & BLT_NO_ERROR_MSG) ? 0 : TCL_LEAVE_ERR_MSG); } /* Repair the string. */ *colon = ':'; if (namePtr->nsPtr == NULL) { return FALSE; /* Namespace doesn't exist. */ } namePtr->name =last; return TRUE; } char * Blt_MakeQualifiedName(Blt_ObjectName *namePtr, Tcl_DString *resultPtr) { Tcl_DStringInit(resultPtr); if ((namePtr->nsPtr->fullName[0] != ':') || (namePtr->nsPtr->fullName[1] != ':') || (namePtr->nsPtr->fullName[2] != '\0')) { Tcl_DStringAppend(resultPtr, namePtr->nsPtr->fullName, -1); } Tcl_DStringAppend(resultPtr, "::", -1); Tcl_DStringAppend(resultPtr, (char *)namePtr->name, -1); return Tcl_DStringValue(resultPtr); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltParse.c��������������������������������������������������������������������0000644�0001750�0001750�00000043014�11462120062�014747� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltParse.c -- * * Contains a collection of procedures that are used to parse Tcl * commands or parts of commands (like quoted strings or nested * sub-commands). * * This file is copied from tclParse.c in the TCL library distribution. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 1994-1998 Sun Microsystems, Inc. * */ /* * Since TCL 8.1.0 these routines have been replaced by ones that * generate byte-codes. But since these routines are used in vector * expressions, where no such byte-compilation is necessary, I now * include them. In fact, the byte-compiled versions would be slower * since the compiled code typically runs only one time. */ #include <bltInt.h> #include "bltParse.h" /* * A table used to classify input characters to assist in parsing * TCL commands. The table should be indexed with a signed character * using the CHAR_TYPE macro. The character may have a negative * value. The CHAR_TYPE macro takes a pointer to a signed character * and a pointer to the last character in the source string. If the * src pointer is pointing at the terminating null of the string, * CHAR_TYPE returns TCL_COMMAND_END. */ #define STATIC_STRING_SPACE 150 #define UCHAR(c) ((unsigned char) (c)) #define TCL_NORMAL 0x01 #define TCL_SPACE 0x02 #define TCL_COMMAND_END 0x04 #define TCL_QUOTE 0x08 #define TCL_OPEN_BRACKET 0x10 #define TCL_OPEN_BRACE 0x20 #define TCL_CLOSE_BRACE 0x40 #define TCL_BACKSLASH 0x80 #define TCL_DOLLAR 0x00 /* * The following table assigns a type to each character. Only types * meaningful to TCL parsing are represented here. The table is * designed to be referenced with either signed or unsigned characters, * so it has 384 entries. The first 128 entries correspond to negative * character values, the next 256 correspond to positive character * values. The last 128 entries are identical to the first 128. The * table is always indexed with a 128-byte offset (the 128th entry * corresponds to a 0 character value). */ static unsigned char tclTypeTable[] = { /* * Negative character values, from -128 to -1: */ TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, /* * Positive character values, from 0-127: */ TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_SPACE, TCL_COMMAND_END, TCL_SPACE, TCL_SPACE, TCL_SPACE, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_SPACE, TCL_NORMAL, TCL_QUOTE, TCL_NORMAL, TCL_DOLLAR, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_COMMAND_END, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_OPEN_BRACKET, TCL_BACKSLASH, TCL_COMMAND_END, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_OPEN_BRACE, TCL_NORMAL, TCL_CLOSE_BRACE, TCL_NORMAL, TCL_NORMAL, /* * Large unsigned character values, from 128-255: */ TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, TCL_NORMAL, }; #define CHAR_TYPE(src,last) \ (((src)==(last))?TCL_COMMAND_END:(tclTypeTable+128)[(int)*(src)]) /* *--------------------------------------------------------------------------- * * Blt_ParseNestedCmd -- * * This procedure parses a nested TCL command between * brackets, returning the result of the command. * * Results: * The return value is a standard TCL result, which is * TCL_OK unless there was an error while executing the * nested command. If an error occurs then interp->result * contains a standard error message. *TermPtr is filled * in with the address of the character just after the * last one processed; this is usually the character just * after the matching close-bracket, or the null character * at the end of the string if the close-bracket was missing * (a missing close bracket is an error). The result returned * by the command is stored in standard fashion in *parsePtr, * null-terminated, with parsePtr->next pointing to the null * character. * * Side effects: * The storage space at *parsePtr may be expanded. * *--------------------------------------------------------------------------- */ int Blt_ParseNestedCmd( Tcl_Interp *interp, /* Interpreter to use for nested command * evaluations and error messages. */ const char *string, /* Character just after opening bracket. */ int flags, /* Flags to pass to nested Tcl_Eval. */ const char **termPtr, /* Store address of terminating character * here. */ ParseValue *parsePtr) /* Information about where to place * result of command. */ { int result, length, shortfall; Interp *iPtr = (Interp *)interp; iPtr->evalFlags = flags | TCL_BRACKET_TERM; result = Tcl_Eval(interp, string); *termPtr = (string + iPtr->termOffset); if (result != TCL_OK) { /* * The increment below results in slightly cleaner message in * the errorInfo variable (the close-bracket will appear). */ if (**termPtr == ']') { *termPtr += 1; } return result; } (*termPtr) += 1; length = (int)strlen(iPtr->result); shortfall = length + 1 - (parsePtr->end - parsePtr->next); if (shortfall > 0) { (*parsePtr->expandProc) (parsePtr, shortfall); } strcpy(parsePtr->next, iPtr->result); parsePtr->next += length; Tcl_FreeResult(interp); iPtr->result = iPtr->resultSpace; iPtr->resultSpace[0] = '\0'; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ParseBraces -- * * This procedure scans the information between matching * curly braces. * * Results: * The return value is a standard TCL result, which is * TCL_OK unless there was an error while parsing string. * If an error occurs then interp->result contains a * standard error message. *TermPtr is filled * in with the address of the character just after the * last one successfully processed; this is usually the * character just after the matching close-brace. The * information between curly braces is stored in standard * fashion in *parsePtr, null-terminated with parsePtr->next * pointing to the terminating null character. * * Side effects: * The storage space at *parsePtr may be expanded. * *--------------------------------------------------------------------------- */ int Blt_ParseBraces( Tcl_Interp *interp, /* Interpreter to use for nested command * evaluations and error messages. */ const char *string, /* Character just after opening bracket. */ const char **termPtr, /* Store address of terminating character * here. */ ParseValue *parsePtr) /* Information about where to place * result of command. */ { int level; const char *src; char *dest, *end; char c; const char *lastChar = string + strlen(string); src = string; dest = parsePtr->next; end = parsePtr->end; level = 1; /* * Copy the characters one at a time to the result area, stopping * when the matching close-brace is found. */ for (;;) { c = *src; src++; if (dest == end) { parsePtr->next = dest; (*parsePtr->expandProc) (parsePtr, 20); dest = parsePtr->next; end = parsePtr->end; } *dest = c; dest++; if (CHAR_TYPE(src - 1, lastChar) == TCL_NORMAL) { continue; } else if (c == '{') { level++; } else if (c == '}') { level--; if (level == 0) { dest--; /* Don't copy the last close brace. */ break; } } else if (c == '\\') { int count; /* * Must always squish out backslash-newlines, even when in * braces. This is needed so that this sequence can appear * anywhere in a command, such as the middle of an expression. */ if (*src == '\n') { dest[-1] = Tcl_Backslash(src - 1, &count); src += count - 1; } else { Tcl_Backslash(src - 1, &count); while (count > 1) { if (dest == end) { parsePtr->next = dest; (*parsePtr->expandProc) (parsePtr, 20); dest = parsePtr->next; end = parsePtr->end; } *dest = *src; dest++; src++; count--; } } } else if (c == '\0') { Tcl_AppendResult(interp, "missing close-brace", (char *)NULL); *termPtr = string - 1; return TCL_ERROR; } } *dest = '\0'; parsePtr->next = dest; *termPtr = src; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ExpandParseValue -- * * This procedure is commonly used as the value of the * expandProc in a ParseValue. It uses malloc to allocate * more space for the result of a parse. * * Results: * The buffer space in *parsePtr is reallocated to something * larger, and if parsePtr->clientData is non-zero the old * buffer is freed. Information is copied from the old * buffer to the new one. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void Blt_ExpandParseValue( ParseValue *parsePtr, /* Information about buffer that * must be expanded. If the clientData * in the structure is non-zero, it * means that the current buffer is * dynamically allocated. */ int needed) /* Minimum amount of additional space * to allocate. */ { int size; char *buffer; /* * Either double the size of the buffer or add enough new space * to meet the demand, whichever produces a larger new buffer. */ size = (parsePtr->end - parsePtr->buffer) + 1; if (size < needed) { size += needed; } else { size += size; } buffer = Blt_AssertMalloc((unsigned int)size); /* * Copy from old buffer to new, free old buffer if needed, and * mark new buffer as malloc-ed. */ memcpy((VOID *) buffer, (VOID *) parsePtr->buffer, (size_t) (parsePtr->next - parsePtr->buffer)); parsePtr->next = buffer + (parsePtr->next - parsePtr->buffer); if (parsePtr->clientData != 0) { Blt_Free(parsePtr->buffer); } parsePtr->buffer = buffer; parsePtr->end = buffer + size - 1; parsePtr->clientData = (ClientData)1; } /* *--------------------------------------------------------------------------- * * Blt_ParseQuotes -- * * This procedure parses a double-quoted string such as a * quoted TCL command argument or a quoted value in a Tcl * expression. This procedure is also used to parse array * element names within parentheses, or anything else that * needs all the substitutions that happen in quotes. * * Results: * The return value is a standard TCL result, which is * TCL_OK unless there was an error while parsing the * quoted string. If an error occurs then interp->result * contains a standard error message. *TermPtr is filled * in with the address of the character just after the * last one successfully processed; this is usually the * character just after the matching close-quote. The * fully-substituted contents of the quotes are stored in * standard fashion in *parsePtr, null-terminated with * parsePtr->next pointing to the terminating null character. * * Side effects: * The buffer space in parsePtr may be enlarged by calling its * expandProc. * *--------------------------------------------------------------------------- */ int Blt_ParseQuotes( Tcl_Interp *interp, /* Interpreter to use for nested command * evaluations and error messages. */ const char *string, /* Character just after opening double- * quote. */ int termChar, /* Character that terminates "quoted" string * (usually double-quote, but sometimes * right-paren or something else). */ int flags, /* Flags to pass to nested Tcl_Eval calls. */ const char **termPtr, /* Store address of terminating character * here. */ ParseValue *parsePtr) /* Information about where to place * fully-substituted result of parse. */ { const char *src; char *dest, c; const char *lastChar = string + strlen(string); src = string; dest = parsePtr->next; for (;;) { if (dest == parsePtr->end) { /* * Target buffer space is about to run out. Make more space. */ parsePtr->next = dest; (*parsePtr->expandProc) (parsePtr, 1); dest = parsePtr->next; } c = *src; src++; if (c == termChar) { *dest = '\0'; parsePtr->next = dest; *termPtr = src; return TCL_OK; } else if (CHAR_TYPE(src - 1, lastChar) == TCL_NORMAL) { copy: *dest = c; dest++; continue; } else if (c == '$') { int length; const char *value; value = Tcl_ParseVar(interp, src - 1, termPtr); if (value == NULL) { return TCL_ERROR; } src = *termPtr; length = strlen(value); if ((parsePtr->end - dest) <= length) { parsePtr->next = dest; (*parsePtr->expandProc) (parsePtr, length); dest = parsePtr->next; } strcpy(dest, value); dest += length; continue; } else if (c == '[') { int result; parsePtr->next = dest; result = Blt_ParseNestedCmd(interp, src, flags, termPtr, parsePtr); if (result != TCL_OK) { return result; } src = *termPtr; dest = parsePtr->next; continue; } else if (c == '\\') { int nRead; src--; *dest = Tcl_Backslash(src, &nRead); dest++; src += nRead; continue; } else if (c == '\0') { char buf[10]; Tcl_ResetResult(interp); sprintf_s(buf, 10, "missing %c", termChar); Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, 9); *termPtr = string - 1; return TCL_ERROR; } else { goto copy; } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUtil.c���������������������������������������������������������������������0000644�0001750�0001750�00000112243�11462120063�014614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUtil.c -- * * This module implements utility procedures for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include <stdarg.h> #include <bltHash.h> #include <bltDBuffer.h> #ifndef HAVE_STRTOLOWER void strtolower(char *s) { while (*s != '\0') { *s = tolower(UCHAR(*s)); s++; } } #endif /* !HAVE_STRTOLOWER */ #ifndef HAVE_STRCASECMP static unsigned char caseTable[] = { (unsigned char)'\000', (unsigned char)'\001', (unsigned char)'\002', (unsigned char)'\003', (unsigned char)'\004', (unsigned char)'\005', (unsigned char)'\006', (unsigned char)'\007', (unsigned char)'\010', (unsigned char)'\011', (unsigned char)'\012', (unsigned char)'\013', (unsigned char)'\014', (unsigned char)'\015', (unsigned char)'\016', (unsigned char)'\017', (unsigned char)'\020', (unsigned char)'\021', (unsigned char)'\022', (unsigned char)'\023', (unsigned char)'\024', (unsigned char)'\025', (unsigned char)'\026', (unsigned char)'\027', (unsigned char)'\030', (unsigned char)'\031', (unsigned char)'\032', (unsigned char)'\033', (unsigned char)'\034', (unsigned char)'\035', (unsigned char)'\036', (unsigned char)'\037', (unsigned char)'\040', (unsigned char)'\041', (unsigned char)'\042', (unsigned char)'\043', (unsigned char)'\044', (unsigned char)'\045', (unsigned char)'\046', (unsigned char)'\047', (unsigned char)'\050', (unsigned char)'\051', (unsigned char)'\052', (unsigned char)'\053', (unsigned char)'\054', (unsigned char)'\055', (unsigned char)'\056', (unsigned char)'\057', (unsigned char)'\060', (unsigned char)'\061', (unsigned char)'\062', (unsigned char)'\063', (unsigned char)'\064', (unsigned char)'\065', (unsigned char)'\066', (unsigned char)'\067', (unsigned char)'\070', (unsigned char)'\071', (unsigned char)'\072', (unsigned char)'\073', (unsigned char)'\074', (unsigned char)'\075', (unsigned char)'\076', (unsigned char)'\077', (unsigned char)'\100', (unsigned char)'\141', (unsigned char)'\142', (unsigned char)'\143', (unsigned char)'\144', (unsigned char)'\145', (unsigned char)'\146', (unsigned char)'\147', (unsigned char)'\150', (unsigned char)'\151', (unsigned char)'\152', (unsigned char)'\153', (unsigned char)'\154', (unsigned char)'\155', (unsigned char)'\156', (unsigned char)'\157', (unsigned char)'\160', (unsigned char)'\161', (unsigned char)'\162', (unsigned char)'\163', (unsigned char)'\164', (unsigned char)'\165', (unsigned char)'\166', (unsigned char)'\167', (unsigned char)'\170', (unsigned char)'\171', (unsigned char)'\172', (unsigned char)'\133', (unsigned char)'\134', (unsigned char)'\135', (unsigned char)'\136', (unsigned char)'\137', (unsigned char)'\140', (unsigned char)'\141', (unsigned char)'\142', (unsigned char)'\143', (unsigned char)'\144', (unsigned char)'\145', (unsigned char)'\146', (unsigned char)'\147', (unsigned char)'\150', (unsigned char)'\151', (unsigned char)'\152', (unsigned char)'\153', (unsigned char)'\154', (unsigned char)'\155', (unsigned char)'\156', (unsigned char)'\157', (unsigned char)'\160', (unsigned char)'\161', (unsigned char)'\162', (unsigned char)'\163', (unsigned char)'\164', (unsigned char)'\165', (unsigned char)'\166', (unsigned char)'\167', (unsigned char)'\170', (unsigned char)'\171', (unsigned char)'\172', (unsigned char)'\173', (unsigned char)'\174', (unsigned char)'\175', (unsigned char)'\176', (unsigned char)'\177', (unsigned char)'\200', (unsigned char)'\201', (unsigned char)'\202', (unsigned char)'\203', (unsigned char)'\204', (unsigned char)'\205', (unsigned char)'\206', (unsigned char)'\207', (unsigned char)'\210', (unsigned char)'\211', (unsigned char)'\212', (unsigned char)'\213', (unsigned char)'\214', (unsigned char)'\215', (unsigned char)'\216', (unsigned char)'\217', (unsigned char)'\220', (unsigned char)'\221', (unsigned char)'\222', (unsigned char)'\223', (unsigned char)'\224', (unsigned char)'\225', (unsigned char)'\226', (unsigned char)'\227', (unsigned char)'\230', (unsigned char)'\231', (unsigned char)'\232', (unsigned char)'\233', (unsigned char)'\234', (unsigned char)'\235', (unsigned char)'\236', (unsigned char)'\237', (unsigned char)'\240', (unsigned char)'\241', (unsigned char)'\242', (unsigned char)'\243', (unsigned char)'\244', (unsigned char)'\245', (unsigned char)'\246', (unsigned char)'\247', (unsigned char)'\250', (unsigned char)'\251', (unsigned char)'\252', (unsigned char)'\253', (unsigned char)'\254', (unsigned char)'\255', (unsigned char)'\256', (unsigned char)'\257', (unsigned char)'\260', (unsigned char)'\261', (unsigned char)'\262', (unsigned char)'\263', (unsigned char)'\264', (unsigned char)'\265', (unsigned char)'\266', (unsigned char)'\267', (unsigned char)'\270', (unsigned char)'\271', (unsigned char)'\272', (unsigned char)'\273', (unsigned char)'\274', (unsigned char)'\275', (unsigned char)'\276', (unsigned char)'\277', (unsigned char)'\300', (unsigned char)'\341', (unsigned char)'\342', (unsigned char)'\343', (unsigned char)'\344', (unsigned char)'\345', (unsigned char)'\346', (unsigned char)'\347', (unsigned char)'\350', (unsigned char)'\351', (unsigned char)'\352', (unsigned char)'\353', (unsigned char)'\354', (unsigned char)'\355', (unsigned char)'\356', (unsigned char)'\357', (unsigned char)'\360', (unsigned char)'\361', (unsigned char)'\362', (unsigned char)'\363', (unsigned char)'\364', (unsigned char)'\365', (unsigned char)'\366', (unsigned char)'\367', (unsigned char)'\370', (unsigned char)'\371', (unsigned char)'\372', (unsigned char)'\333', (unsigned char)'\334', (unsigned char)'\335', (unsigned char)'\336', (unsigned char)'\337', (unsigned char)'\340', (unsigned char)'\341', (unsigned char)'\342', (unsigned char)'\343', (unsigned char)'\344', (unsigned char)'\345', (unsigned char)'\346', (unsigned char)'\347', (unsigned char)'\350', (unsigned char)'\351', (unsigned char)'\352', (unsigned char)'\353', (unsigned char)'\354', (unsigned char)'\355', (unsigned char)'\356', (unsigned char)'\357', (unsigned char)'\360', (unsigned char)'\361', (unsigned char)'\362', (unsigned char)'\363', (unsigned char)'\364', (unsigned char)'\365', (unsigned char)'\366', (unsigned char)'\367', (unsigned char)'\370', (unsigned char)'\371', (unsigned char)'\372', (unsigned char)'\373', (unsigned char)'\374', (unsigned char)'\375', (unsigned char)'\376', (unsigned char)'\377', }; /* *--------------------------------------------------------------------------- * * strcasecmp -- * * Compare two strings, disregarding case. * * Results: * Returns a signed integer representing the following: * * zero - two strings are equal * negative - first string is less than second * positive - first string is greater than second * *--------------------------------------------------------------------------- */ int strcasecmp(const char *s1, const char *s2) { unsigned char *s = (unsigned char *)s1; unsigned char *t = (unsigned char *)s2; for ( /* empty */ ; (caseTable[*s] == caseTable[*t]); s++, t++) { if (*s == '\0') { return 0; } } return (caseTable[*s] - caseTable[*t]); } /* *--------------------------------------------------------------------------- * * strncasecmp -- * * Compare two strings, disregarding case, up to a given length. * * Results: * Returns a signed integer representing the following: * * zero - two strings are equal * negative - first string is less than second * positive - first string is greater than second * *--------------------------------------------------------------------------- */ int strncasecmp(const char *s1, const char *s2, size_t length) { unsigned char *s = (unsigned char *)s1; unsigned char *t = (unsigned char *)s2; for ( /* empty */ ; (length > 0); s++, t++, length--) { if (caseTable[*s] != caseTable[*t]) { return (caseTable[*s] - caseTable[*t]); } if (*s == '\0') { return 0; } } return 0; } #endif /* !HAVE_STRCASECMP */ #if !HAVE_DRAND48 #define XDR48 0x000100010001LL #define MNDR48 0x0005deece66dLL #define DODDR48 0xbLL static long long int xdr48 = XDR48; double drand48(void) // works only on compilers with long long int! { xdr48 = MNDR48 * xdr48 + DODDR48; xdr48 &= 0xffffffffffffLL; return xdr48 / 281474976710656.0; } // Random number generator initialization // parameters: // s - seed // return: void srand48(long x0) { xdr48 = ((unsigned long)x0<<16) + 0x330e; } #endif /*HAVE_DRAND48*/ #if (_TCL_VERSION < _VERSION(8,1,0)) char * Tcl_GetString(Tcl_Obj *objPtr) { unsigned int dummy; return Tcl_GetStringFromObj(objPtr, &dummy); } int Tcl_EvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj **objv, int flags) { Tcl_DString dString; int i; int result; Tcl_DStringInit(&dString); for (i = 0; i < objc; i++) { Tcl_DStringAppendElement(&dString, Tcl_GetString(objv[i])); } result = Tcl_Eval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); return result; } int Tcl_WriteObj(Tcl_Channel channel, Tcl_Obj *objPtr) { char *string; int nBytes; string = Tcl_GetStringFromObj(objPtr, &nBytes); return Tcl_Write(channel, string, nBytes); } char * Tcl_SetVar2Ex( Tcl_Interp *interp, char *part1, char *part2, Tcl_Obj *objPtr, int flags) { return Tcl_SetVar2(interp, part1, part2, Tcl_GetString(objPtr), flags); } Tcl_Obj * Tcl_GetVar2Ex( Tcl_Interp *interp, char *part1, char *part2, int flags) { char *result; result = Tcl_GetVar2(interp, part1, part2, flags); if (result == NULL) { return NULL; } return Tcl_NewStringObj(result, -1); } #endif /* *--------------------------------------------------------------------------- * * Blt_GetDoubleFromString -- * * Converts a string into a double precision number. This differs from * Tcl's version in that it also allows NaN and +/-Inf. There are * cases where NaNs are used to indicate holes in the data. * * Results: * Returns a standard Tcl result. * *--------------------------------------------------------------------------- */ int Blt_GetDoubleFromString(Tcl_Interp *interp, const char *s, double *valuePtr) { char *end; double d; errno = 0; d = strtod(s, &end); /* INTL: Tcl source. */ if (end == s) { badDouble: if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "expected floating-point number but got \"", s, "\"", (char *) NULL); } return TCL_ERROR; } if (errno != 0 && (d == HUGE_VAL || d == -HUGE_VAL || d == 0)) { if (interp != (Tcl_Interp *) NULL) { char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "unknown floating-point error, errno = %d", errno); Tcl_AppendToObj(Tcl_GetObjResult(interp), msg, -1); Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", msg, (char *) NULL); } return TCL_ERROR; } while ((*end != 0) && isspace(UCHAR(*end))) { /* INTL: ISO space. */ end++; } if (*end != 0) { goto badDouble; } *valuePtr = d; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetDoubleFromString -- * * Converts a Tcl_Obj into a double precision number. This differs from * Tcl's version in that it also allows NaN and +/-Inf. There are * cases where NaNs are used to indicate holes in the data. * * Results: * Returns a standard Tcl result. * * Side Effects: * tclDoubleType is no longer available (in 8.5) as a global variable. * We have to get a double obj and save its type pointer. * *--------------------------------------------------------------------------- */ int Blt_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr) { const char *string; static Tcl_ObjType *tclDoubleTypePtr = NULL; if (tclDoubleTypePtr == NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewDoubleObj(0.0); tclDoubleTypePtr = objPtr->typePtr; Tcl_DecrRefCount(objPtr); } if (objPtr->typePtr == tclDoubleTypePtr) { *valuePtr = objPtr->internalRep.doubleValue; return TCL_OK; } string = Tcl_GetString(objPtr); return Blt_GetDoubleFromString(interp, string, valuePtr); } /* *--------------------------------------------------------------------------- * * Blt_CompareDictionary * * This function compares two strings as if they were being used in * an index or card catalog. The case of alphabetic characters is * ignored, except to break ties. Thus "B" comes before "b" but * after "a". Also, integers embedded in the strings compare in * numerical order. In other words, "x10y" comes after "x9y", not * before it as it would when using strcmp(). * * Results: * A negative result means that the first element comes before the * second, and a positive result means that the second element * should come first. A result of zero means the two elements * are equal and it doesn't matter which comes first. * * Side effects: * None. * *--------------------------------------------------------------------------- */ #if HAVE_UTF int Blt_DictionaryCompare(const char *left, const char *right) { Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower; int diff, zeros; int secondaryDiff = 0; for(;;) { if ((isdigit(UCHAR(*right))) && (isdigit(UCHAR(*left)))) { /* * There are decimal numbers embedded in the two strings. Compare * them as numbers, rather than strings. If one number has more * leading zeros than the other, the number with more leading * zeros sorts later, but only as a secondary choice. */ zeros = 0; while ((*right == '0') && (isdigit(UCHAR(right[1])))) { right++; zeros--; } while ((*left == '0') && (isdigit(UCHAR(left[1])))) { left++; zeros++; } if (secondaryDiff == 0) { secondaryDiff = zeros; } /* * The code below compares the numbers in the two strings without * ever converting them to integers. It does this by first * comparing the lengths of the numbers and then comparing the * digit values. */ diff = 0; for (;;) { if (diff == 0) { diff = UCHAR(*left) - UCHAR(*right); } right++; left++; /* Ignore commas in numbers. */ if (*left == ',') { left++; } if (*right == ',') { right++; } if (!isdigit(UCHAR(*right))) { /* INTL: digit */ if (isdigit(UCHAR(*left))) { /* INTL: digit */ return 1; } else { /* * The two numbers have the same length. See * if their values are different. */ if (diff != 0) { return diff; } break; } } else if (!isdigit(UCHAR(*left))) { /* INTL: digit */ return -1; } } continue; } /* * Convert character to Unicode for comparison purposes. If either * string is at the terminating null, do a byte-wise comparison and * bail out immediately. */ if ((*left != '\0') && (*right != '\0')) { left += Tcl_UtfToUniChar(left, &uniLeft); right += Tcl_UtfToUniChar(right, &uniRight); /* * Convert both chars to lower for the comparison, because * dictionary sorts are case insensitve. Convert to lower, not * upper, so chars between Z and a will sort before A (where most * other interesting punctuations occur) */ uniLeftLower = Tcl_UniCharToLower(uniLeft); uniRightLower = Tcl_UniCharToLower(uniRight); } else { diff = UCHAR(*left) - UCHAR(*right); break; } diff = uniLeftLower - uniRightLower; if (diff) { return diff; } else if (secondaryDiff == 0) { if (Tcl_UniCharIsUpper(uniLeft) && Tcl_UniCharIsLower(uniRight)) { secondaryDiff = -1; } else if (Tcl_UniCharIsUpper(uniRight) && Tcl_UniCharIsLower(uniLeft)) { secondaryDiff = 1; } } } if (diff == 0) { diff = secondaryDiff; } return diff; } #else int Blt_DictionaryCompare(const char *left, const char *right) { int diff, zeros; int secondaryDiff = 0; while (1) { if (isdigit(UCHAR(*right)) && isdigit(UCHAR(*left))) { /* * There are decimal numbers embedded in the two strings. Compare * them as numbers, rather than strings. If one number has more * leading zeros than the other, the number with more leading * zeros sorts later, but only as a secondary choice. */ zeros = 0; while ((*right == '0') && (isdigit(UCHAR(right[1])))) { right++; zeros--; } while ((*left == '0') && (isdigit(UCHAR(left[1])))) { left++; zeros++; } if (secondaryDiff == 0) { secondaryDiff = zeros; } /* * The code below compares the numbers in the two strings without * ever converting them to integers. It does this by first * comparing the lengths of the numbers and then comparing the * digit values. */ diff = 0; while (1) { if (diff == 0) { diff = UCHAR(*left) - UCHAR(*right); } right++; left++; /* Ignore commas in numbers. */ if (*left == ',') { left++; } if (*right == ',') { right++; } if (!isdigit(UCHAR(*right))) { if (isdigit(UCHAR(*left))) { return 1; } else { /* * The two numbers have the same length. See * if their values are different. */ if (diff != 0) { return diff; } break; } } else if (!isdigit(UCHAR(*left))) { return -1; } } continue; } diff = UCHAR(*left) - UCHAR(*right); if (diff) { if (isupper(UCHAR(*left)) && islower(UCHAR(*right))) { diff = UCHAR(tolower(*left)) - UCHAR(*right); if (diff) { return diff; } else if (secondaryDiff == 0) { secondaryDiff = -1; } } else if (isupper(UCHAR(*right)) && islower(UCHAR(*left))) { diff = UCHAR(*left) - UCHAR(tolower(UCHAR(*right))); if (diff) { return diff; } else if (secondaryDiff == 0) { secondaryDiff = 1; } } else { return diff; } } if (*left == 0) { break; } left++; right++; } if (diff == 0) { diff = secondaryDiff; } return diff; } #endif #ifndef NDEBUG void Blt_Assert(const char *testExpr, const char *fileName, int lineNumber) { #ifdef WINDEBUG PurifyPrintf("line %d of %s: Assert \"%s\" failed\n", lineNumber, fileName, testExpr); #endif fprintf(stderr, "line %d of %s: Assert \"%s\" failed\n", lineNumber, fileName, testExpr); fflush(stderr); abort(); } #endif /* NDEBUG */ /*ARGSUSED*/ void Blt_Panic TCL_VARARGS_DEF(const char *, arg1) { const char *format; va_list args; format = TCL_VARARGS_START(const char *, arg1, args); vfprintf(stderr, format, args); fprintf(stderr, "\n"); fflush(stderr); abort(); } void Blt_DStringAppendElements TCL_VARARGS_DEF(Tcl_DString *, arg1) { Tcl_DString *dsPtr; char *elem; va_list args; dsPtr = TCL_VARARGS_START(Tcl_DString *, arg1, args); while ((elem = va_arg(args, char *)) != NULL) { Tcl_DStringAppendElement(dsPtr, elem); } va_end(args); } /*ARGSUSED*/ #ifndef HAVE_SPRINTF_S int sprintf_s(char *s, size_t size, const char *fmt, /*args*/ ...) { va_list ap; int n; va_start(ap, fmt); n = vsnprintf(s, size, fmt, ap); if ((n != (int)size) && (size > 0)) { s[size-1] = '\0'; } va_end(ap); return n; } #endif /* HAVE_SPRINTF_S */ static char stringRep[200]; const char * Blt_Itoa(int value) { sprintf_s(stringRep, 200, "%d", value); return stringRep; } const char * Blt_Ltoa(long value) { sprintf_s(stringRep, 200, "%ld", value); return stringRep; } const char * Blt_Utoa(unsigned int value) { sprintf_s(stringRep, 200, "%u", value); return stringRep; } const char * Blt_Dtoa(Tcl_Interp *interp, double value) { Tcl_PrintDouble(interp, value, stringRep); return stringRep; } FILE * Blt_OpenFile(Tcl_Interp *interp, const char *fileName, const char *mode) { FILE *f; #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_DString dString, nativeDString; char *native; native = Tcl_TranslateFileName(interp, fileName, &nativeDString); if (native == NULL) { return NULL; } fileName = Tcl_UtfToExternalDString(NULL, native, -1, &dString); if (fileName == NULL) { Tcl_AppendResult(interp, "can't convert filename \"", native, "\" to system encoding", (char *)NULL); Tcl_DStringFree(&nativeDString); return NULL; } f = fopen(fileName, mode); #else f = fopen(fileName, mode); #endif if (f == NULL) { Tcl_AppendResult(interp, "can't open \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); } Tcl_DStringFree(&dString); Tcl_DStringFree(&nativeDString); return f; } int Blt_GlobalEvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; int result; for (i = 0; i < objc; i++) { Tcl_IncrRefCount(objv[i]); } result = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL); for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objv[i]); } return result; } int Blt_GlobalEvalListObj(Tcl_Interp *interp, Tcl_Obj *cmdObjPtr) { Tcl_Obj **objv; int objc; int i; int result; if (Tcl_ListObjGetElements(interp, cmdObjPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < objc; i++) { Tcl_IncrRefCount(objv[i]); } result = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL); for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objv[i]); } return result; } /* *--------------------------------------------------------------------------- * * Blt_InitHexTable -- * * Table index for the hex values. Initialized once, first time. Used * for translation value or delimiter significance lookup. * * We build the table at run time for several reasons: * * 1. portable to non-ASCII machines. * 2. still reentrant since we set the init flag after setting * table. * 3. easier to extend. * 4. less prone to bugs. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_InitHexTable(unsigned char *hexTable) { memset(hexTable, 0xFF, 256); hexTable['0'] = 0; hexTable['1'] = 1; hexTable['2'] = 2; hexTable['3'] = 3; hexTable['4'] = 4; hexTable['5'] = 5; hexTable['6'] = 6; hexTable['7'] = 7; hexTable['8'] = 8; hexTable['9'] = 9; hexTable['a'] = hexTable['A'] = 10; hexTable['b'] = hexTable['B'] = 11; hexTable['c'] = hexTable['C'] = 12; hexTable['d'] = hexTable['D'] = 13; hexTable['e'] = hexTable['E'] = 14; hexTable['f'] = hexTable['F'] = 15; } /* *--------------------------------------------------------------------------- * * Blt_GetPosition -- * * Convert a string representing a numeric position. A position can be * in one of the following forms. * * number - number of the item in the hierarchy, indexed * from zero. * "end" - last position in the hierarchy. * * Results: * A standard TCL result. If "string" is a valid index, then *indexPtr * is filled with the corresponding numeric index. If "end" was selected * then *indexPtr is set to -1. Otherwise an error message is left in * interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_GetPosition( Tcl_Interp *interp, /* Interpreter to report results back * to. */ const char *string, /* String representation of the index. * Can be an integer or "end" to refer * to the last index. */ long *indexPtr) /* Holds the converted index. */ { if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { *indexPtr = -1; /* Indicates last position in * hierarchy. */ } else { long position; if (Tcl_GetLong(interp, string, &position) != TCL_OK) { return TCL_ERROR; } if (position < 0) { Tcl_AppendResult(interp, "bad position \"", string, "\"", (char *)NULL); return TCL_ERROR; } *indexPtr = position; } return TCL_OK; } int Blt_GetCountFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, int check, /* Can be COUNT_POS, COUNT_NNEG, * or COUNT_ANY, */ long *valuePtr) { long count; if (Tcl_GetLongFromObj(interp, objPtr, &count) != TCL_OK) { return TCL_ERROR; } switch (check) { case COUNT_NNEG: if (count < 0) { Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objPtr), "\": can't be negative", (char *)NULL); return TCL_ERROR; } break; case COUNT_POS: if (count <= 0) { Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objPtr), "\": must be positive", (char *)NULL); return TCL_ERROR; } break; case COUNT_ANY: break; } *valuePtr = count; return TCL_OK; } /* * The hash table below is used to keep track of all the Blt_Uids created * so far. */ static Blt_HashTable uidTable; static int uidInitialized = 0; /* *--------------------------------------------------------------------------- * * Blt_GetUid -- * * Given a string, returns a unique identifier for the string. A * reference count is maintained, so that the identifier can be freed * when it is not needed any more. This can be used in many places to * replace Tcl_GetUid. * * Results: * This procedure returns a Blt_Uid corresponding to the "string" * argument. The Blt_Uid has a string value identical to string (strcmp * will return 0), but it's guaranteed that any other calls to this * procedure with a string equal to "string" will return exactly the same * result (i.e. can compare Blt_Uid *values* directly, without having to * call strcmp on what they point to). * * Side effects: * New information may be entered into the identifier table. * *--------------------------------------------------------------------------- */ Blt_Uid Blt_GetUid(const char *string) /* String to convert. */ { Blt_HashEntry *hPtr; int isNew; size_t refCount; if (!uidInitialized) { Blt_InitHashTable(&uidTable, BLT_STRING_KEYS); uidInitialized = 1; } hPtr = Blt_CreateHashEntry(&uidTable, string, &isNew); if (isNew) { refCount = 0; } else { refCount = (size_t)Blt_GetHashValue(hPtr); } refCount++; Blt_SetHashValue(hPtr, (ClientData)refCount); return (Blt_Uid)Blt_GetHashKey(&uidTable, hPtr); } /* *--------------------------------------------------------------------------- * * Blt_FreeUid -- * * Frees the Blt_Uid if there are no more clients using this identifier. * * Results: * None. * * Side effects: * The identifier may be deleted from the identifier table. * *--------------------------------------------------------------------------- */ void Blt_FreeUid(Blt_Uid uid) /* Identifier to release. */ { Blt_HashEntry *hPtr; if (!uidInitialized) { Blt_InitHashTable(&uidTable, BLT_STRING_KEYS); uidInitialized = 1; } hPtr = Blt_FindHashEntry(&uidTable, uid); if (hPtr) { size_t refCount; refCount = (size_t)Blt_GetHashValue(hPtr); refCount--; if (refCount == 0) { Blt_DeleteHashEntry(&uidTable, hPtr); } else { Blt_SetHashValue(hPtr, refCount); } } else { fprintf(stderr, "tried to release unknown identifier \"%s\"\n", uid); } } /* *--------------------------------------------------------------------------- * * Blt_FindUid -- * * Returns a Blt_Uid associated with a given string, if one exists. * * Results: * A Blt_Uid for the string if one exists. Otherwise NULL. * *--------------------------------------------------------------------------- */ Blt_Uid Blt_FindUid(const char *string) /* String to find. */ { Blt_HashEntry *hPtr; if (!uidInitialized) { Blt_InitHashTable(&uidTable, BLT_STRING_KEYS); uidInitialized = 1; } hPtr = Blt_FindHashEntry(&uidTable, string); if (hPtr == NULL) { return NULL; } return (Blt_Uid) Blt_GetHashKey(&uidTable, hPtr); } /* *--------------------------------------------------------------------------- * * BinaryOpSearch -- * * Performs a binary search on the array of command operation * specifications to find a partial, anchored match for the given * operation string. * * Results: * If the string matches unambiguously the index of the specification in * the array is returned. If the string does not match, even as an * abbreviation, any operation, -1 is returned. If the string matches, * but ambiguously -2 is returned. * *--------------------------------------------------------------------------- */ static int BinaryOpSearch(Blt_OpSpec *specs, int nSpecs, const char *string, int length) { char c; int high, low; low = 0; high = nSpecs - 1; c = string[0]; while (low <= high) { Blt_OpSpec *specPtr; int compare; int median; median = (low + high) >> 1; specPtr = specs + median; /* Test the first character */ compare = c - specPtr->name[0]; if (compare == 0) { /* Now test the entire string */ compare = strncmp(string, specPtr->name, length); if (compare == 0) { if ((int)length < specPtr->minChars) { return -2; /* Ambiguous operation name */ } } } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return median; /* Op found. */ } } return -1; /* Can't find operation */ } /* *--------------------------------------------------------------------------- * * LinearOpSearch -- * * Performs a binary search on the array of command operation * specifications to find a partial, anchored match for the given * operation string. * * Results: * If the string matches unambiguously the index of the specification in * the array is returned. If the string does not match, even as an * abbreviation, any operation, -1 is returned. If the string matches, * but ambiguously -2 is returned. * *--------------------------------------------------------------------------- */ static int LinearOpSearch(Blt_OpSpec *specs, int nSpecs, const char *string, int length) { Blt_OpSpec *specPtr; char c; int nMatches, last; int i; c = string[0]; nMatches = 0; last = -1; for (specPtr = specs, i = 0; i < nSpecs; i++, specPtr++) { if ((c == specPtr->name[0]) && (strncmp(string, specPtr->name, length) == 0)) { last = i; nMatches++; if ((int)length == specPtr->minChars) { break; } } } if (nMatches > 1) { return -2; /* Ambiguous operation name */ } if (nMatches == 0) { return -1; /* Can't find operation */ } return last; /* Op found. */ } /* *--------------------------------------------------------------------------- * * Blt_GetOpFromObj -- * * Find the command operation given a string name. This is useful where * a group of command operations have the same argument signature. * * Results: * If found, a pointer to the procedure (function pointer) is returned. * Otherwise NULL is returned and an error message containing a list of * the possible commands is returned in interp->result. * *--------------------------------------------------------------------------- */ void * Blt_GetOpFromObj( Tcl_Interp *interp, /* Interpreter to report errors to */ int nSpecs, /* # of specifications in array */ Blt_OpSpec *specs, /* Op specification array */ int operPos, /* Position of operation in argument * list. */ int objc, /* # of arguments in the argument * * vector. This includes any * prefixed arguments */ Tcl_Obj *const *objv, /* Argument vector */ int flags) { Blt_OpSpec *specPtr; const char *string; int length; int n; if (objc <= operPos) { /* No operation argument */ Tcl_AppendResult(interp, "wrong # args: ", (char *)NULL); usage: Tcl_AppendResult(interp, "should be one of...", (char *)NULL); for (n = 0; n < nSpecs; n++) { int i; Tcl_AppendResult(interp, "\n ", (char *)NULL); for (i = 0; i < operPos; i++) { Tcl_AppendResult(interp, Tcl_GetString(objv[i]), " ", (char *)NULL); } specPtr = specs + n; Tcl_AppendResult(interp, specPtr->name, " ", specPtr->usage, (char *)NULL); } return NULL; } string = Tcl_GetStringFromObj(objv[operPos], &length); if (flags & BLT_OP_LINEAR_SEARCH) { n = LinearOpSearch(specs, nSpecs, string, length); } else { n = BinaryOpSearch(specs, nSpecs, string, length); } if (n == -2) { char c; Tcl_AppendResult(interp, "ambiguous", (char *)NULL); if (operPos > 2) { Tcl_AppendResult(interp, " ", Tcl_GetString(objv[operPos - 1]), (char *)NULL); } Tcl_AppendResult(interp, " operation \"", string, "\" matches: ", (char *)NULL); c = string[0]; for (n = 0; n < nSpecs; n++) { specPtr = specs + n; if ((c == specPtr->name[0]) && (strncmp(string, specPtr->name, length) == 0)) { Tcl_AppendResult(interp, " ", specPtr->name, (char *)NULL); } } return NULL; } else if (n == -1) { /* Can't find operation, display help */ Tcl_AppendResult(interp, "bad", (char *)NULL); if (operPos > 2) { Tcl_AppendResult(interp, " ", Tcl_GetString(objv[operPos - 1]), (char *)NULL); } Tcl_AppendResult(interp, " operation \"", string, "\": ", (char *)NULL); goto usage; } specPtr = specs + n; if ((objc < specPtr->minArgs) || ((specPtr->maxArgs > 0) && (objc > specPtr->maxArgs))) { int i; Tcl_AppendResult(interp, "wrong # args: should be \"", (char *)NULL); for (i = 0; i < operPos; i++) { Tcl_AppendResult(interp, Tcl_GetString(objv[i]), " ", (char *)NULL); } Tcl_AppendResult(interp, specPtr->name, " ", specPtr->usage, "\"", (char *)NULL); return NULL; } return specPtr->proc; } #if (_TCL_VERSION >= _VERSION(8,4,0)) /*ARGSUSED*/ int Blt_LoadLibrary(Tcl_Interp *interp, const char *libPath, const char *initProcName, const char *safeProcName) { Tcl_FSUnloadFileProc *unLoadProcPtr = NULL; Tcl_LoadHandle loadHandle; Tcl_PackageInitProc *initProc, *safeProc; int result; Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(libPath, -1); Tcl_IncrRefCount(objPtr); result = Tcl_FSLoadFile(interp, objPtr, initProcName, safeProcName, &initProc, &safeProc, &loadHandle, &unLoadProcPtr); if (result != TCL_OK) { goto done; } if (initProc == NULL) { Tcl_AppendResult(interp, "couldn't find procedure ", initProcName, (char *) NULL); result = TCL_ERROR; goto done; } if (Tcl_IsSafe(interp)) { if (safeProc == NULL) { Tcl_AppendResult(interp, "can't use package in a safe interpreter: no ", safeProcName, " procedure", (char *) NULL); result = TCL_ERROR; goto done; } result = (*safeProc)(interp); } else { result = (*initProc)(interp); } done: Tcl_DecrRefCount(objPtr); if (result != TCL_OK) { if (unLoadProcPtr != NULL) { (*unLoadProcPtr)(loadHandle); } return TCL_ERROR; } return TCL_OK; } #else int Blt_LoadLibrary(Tcl_Interp *interp, const char *libPath, const char *initProcName, const char *safeProcName) { ClientData loadData; Tcl_PackageInitProc *initProc, *safeProc; int result; result = TclpLoadFile(interp, libPath, initProcName, safeProcName, &initProc, &safeProc, &loadData); if (result != TCL_OK) { return TCL_ERROR; } if (initProc == NULL) { Tcl_AppendResult(interp, "couldn't find procedure ", initProcName, (char *) NULL); result = TCL_ERROR; goto done; } if (Tcl_IsSafe(interp)) { if (safeProc == NULL) { Tcl_AppendResult(interp, "can't use package in a safe interpreter: ", "no ", safeProcName, " procedure", (char *) NULL); result = TCL_ERROR; goto done; } result = (*safeProc)(interp); } else { result = (*initProc)(interp); } done: if (result != TCL_OK) { TclpUnloadFile(loadData); return TCL_ERROR; } return TCL_OK; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBgStyle.h������������������������������������������������������������������0000644�0001750�0001750�00000006302�11462120062�015252� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBgPattern.h -- * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_BGPATTERN_H #define _BLT_BGPATTERN_H typedef struct _Blt_Background *Blt_Background; typedef void Blt_BackgroundChangedProc(ClientData clientData); BLT_EXTERN Blt_Background Blt_GetBackground(Tcl_Interp *interp, Tk_Window tkwin, const char *styleName); BLT_EXTERN Blt_Background Blt_GetBackgroundFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN XColor *Blt_BackgroundBorderColor(Blt_Background bg); BLT_EXTERN Tk_3DBorder Blt_BackgroundBorder(Blt_Background bg); BLT_EXTERN const char *Blt_NameOfBackground(Blt_Background bg); BLT_EXTERN void Blt_FreeBackground(Blt_Background bg); BLT_EXTERN void Blt_DrawBackgroundRectangle(Tk_Window tkwin, Drawable drawable, Blt_Background bg, int x, int y, int width, int height, int borderWidth, int relief); BLT_EXTERN void Blt_FillBackgroundRectangle(Tk_Window tkwin, Drawable drawable, Blt_Background bg, int x, int y, int width, int height, int borderWidth, int relief); BLT_EXTERN void Blt_DrawBackgroundPolygon(Tk_Window tkwin, Drawable drawable, Blt_Background bg, XPoint *points, int nPoints, int borderWidth, int leftRelief); BLT_EXTERN void Blt_FillBackgroundPolygon(Tk_Window tkwin, Drawable drawable, Blt_Background bg, XPoint *points, int nPoints, int borderWidth, int leftRelief); BLT_EXTERN void Blt_GetBackgroundOrigin(Blt_Background bg, int *xPtr,int *yPtr); BLT_EXTERN void Blt_SetBackgroundChangedProc(Blt_Background bg, Blt_BackgroundChangedProc *notifyProc, ClientData clientData); BLT_EXTERN void Blt_SetBackgroundOrigin(Tk_Window tkwin, Blt_Background bg, int x, int y); BLT_EXTERN void Blt_DrawFocusBackground(Tk_Window tkwin, Blt_Background bg, int highlightWidth, Drawable drawable); BLT_EXTERN GC Blt_BackgroundBorderGC(Tk_Window tkwin, Blt_Background bg, int which); BLT_EXTERN void Blt_SetBackgroundFromBackground(Tk_Window tkwin, Blt_Background bg); BLT_EXTERN void Blt_UnsetBackgroundClipRegion(Tk_Window tkwin, Blt_Background bg); BLT_EXTERN void Blt_SetBackgroundClipRegion(Tk_Window tkwin, Blt_Background bg, TkRegion rgn); #endif /* BLT_BGPATTERN_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/Makefile.vc�������������������������������������������������������������������0000644�0001750�0001750�00000053031�11462120063�015077� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for BLT library using VC++. # ------------------------------------------------------------------------ include ../vc.config srcdir = ../$(TOP)/src libsrcdir = $(srcdir)/../.. TOOLS32 = C:\Program Files\Microsoft Visual Studio 8\Vc BIN = C:/Program\ Files/Microsoft\ Visual\ Studio\ 8/Vc/bin AR = lib.exe -link50compat LD = link.exe CC = cl.exe rc32 = rc.exe MT = mt.exe SDK = C:/Program Files/Microsoft Platform SDK for Windows Server 2003 R2 mslibs = $(TOOLS32)\lib;$(SDK)\lib;. ifeq ($(WITH_JPG),1) JPG_DEFINES = -DHAVE_LIBJPG endif # WITH_JPG ifeq ($(WITH_PNG),1) PNG_DEFINES = -DHAVE_LIBPNG endif # WITH_PNG ifeq ($(WITH_PNG),1) PNGDEF = -DHAVE_PNG_H -DHAVE_LIBPNG PNGDIR = $(libsrcdir)/libpng-1.2.5 ZLIBDIR = $(libsrcdir)/zlib-1.2.1 PNGLIB = $(PNGDIR)/libpng.lib $(ZLIBDIR)/zlib.lib PNGINC = -I$(PNGDIR) -I$(ZLIBDIR) endif # WITH_PNG ifeq ($(WITH_TIF),1) TIFDEF = -DHAVE_TIFF_H -DHAVE_LIBTIFF TIFDIR = $(libsrcdir)/tiff-v3.4beta037/libtiff TIFLIB = $(TIFDIR)/libtiff.lib TIFINC = -I$(TIFDIR) endif # WITH_TIF ifeq ($(WITH_EXPAT),1) EXPAT_DEFINES = -DHAVE_EXPAT_H -DHAVE_LIBEXPAT endif ifeq ($(WITH_FT2),1) FT2_DEFINES = -DHAVE_FT2BUILD_H -DHAVE_LIBFT2 $(FT2_INC_SPEC) endif PICTURE_DEFINES = $(JPGDEF) $(PNGDEF) $(TIFDEF) PICTURE_INCLUDES = $(JPGINC) $(PNGINC) $(TIFINC) TCL_STUBS_SPEC = TK_STUBS_SPEC = STUB_DEFINES = ifeq ($(ENABLE_STUBS),1) STUB_DEFINES = -DUSE_TCL_STUBS -DUSE_TK_STUBS endif # ENABLE_STUBS # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ DEFINES = -D_X86_=1 -D__STDC__ -DWIN32 -DCONSOLE -D_MT \ $(DEBUG_DEFINES) $(STUB_DEFINES) $(SO_DEFINES) $(EXTRA_DEFINES) LIB_DEFINES = -DBLT_LIB_SUFFIX=\"$(DBG)\" -DBLT_SO_PREFIX=\"\" \ -DBLT_SO_EXT=\".dll\" ifeq ($(ENABLE_SHARED),1) SO_DEFINES = -D_DLL SO_TARGET = build-dll LIBS = $(COMMON_LIBS) else SO_DEFINES = -D_CTYPE_DISABLE_MACROS LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) endif # ENABLE_SHARED ifeq ($(ENABLE_SYMBOLS),1) CFLAGS = -Z7 -Od DEBUG_LDFLAGS = -debug:full -debugtype:cv DEBUG_DEFINES = -DUSE_TCLALLOC=0 TK_LIB_SPEC = $(TKDIR)/lib/tk$(v2).lib TCL_LIB_SPEC = $(TCLDIR)/lib/tcl$(v2).lib MSVCRT = msvcrt.lib TCL_STUBS_SPEC = $(TCLDIR)/lib/tclstub$(v2).lib TK_STUBS_SPEC = $(TKDIR)/lib/tkstub$(v2).lib else CFLAGS = -Ox -GB -GD DEBUG_LDFLAGS = -debug:full -debugtype:cv TK_LIB_SPEC = $(TKDIR)/lib/tk$(v2).lib TCL_LIB_SPEC = $(TCLDIR)/lib/tcl$(v2).lib MSVCRT = msvcrt.lib TCL_STUBS_SPEC = $(TCLDIR)/lib/tclstub$(v2).lib TK_STUBS_SPEC = $(TKDIR)/lib/tkstub$(v2).lib endif # ENABLE_SYMBOLS ifeq ($(ENABLE_STUBS), 1) tcl_lib_spec=$(TCL_STUBS_SPEC) tk_lib_spec=$(TK_STUBS_SPEC) else tcl_lib_spec=$(TCL_LIB_SPEC) tk_lib_spec=$(TK_LIB_SPEC) endif EXTRA_CFLAGS = -nologo -W3 # ------------------------------------------------------------------------ # Linker flags and options # ------------------------------------------------------------------------ #-align:0x1000 COMMON_LDFLAGS = -nodefaultlib -release -nologo -warn:3 \ -machine:IX86 \ $(DEBUG_LDFLAGS) # -opt:ref -opt:icf,3 -opt:nowin98 DLLENTRY = @12 SO_LDFLAGS = $(COMMON_LDFLAGS) \ -subsystem:console -entry:mainCRTStartup \ -subsystem:windows -entry:WinMainCRTStartup \ -entry:_DllMainCRTStartup$(DLLENTRY) -dll BLT_TCL_SO_LDFLAGS = $(COMMON_LDFLAGS) \ -subsystem:console -entry:mainCRTStartup \ -entry:_DllMainCRTStartup$(DLLENTRY) -dll BLT_TCL_SO_LDFLAGS = $(COMMON_LDFLAGS) -dll BLT_TK_SO_LDFLAGS = $(COMMON_LDFLAGS) \ -subsystem:windows -entry:WinMainCRTStartup \ -entry:_DllMainCRTStartup$(DLLENTRY) -dll BLT_TK_SO_LDFLAGS = $(COMMON_LDFLAGS) -dll LDFLAGS = $(COMMON_LDFLAGS) \ -fixed:NO -stack:2300000 COMMON_LIBS = $(MSVCRT) \ kernel32.lib user32.lib advapi32.lib EXTRA_LIBS = $(OLELIB) \ $(JPG_LIB_SPEC) $(PNG_LIB_SPEC) $(TIFLIB) \ gdi32.lib \ oldnames.lib \ advapi32.lib \ winspool.lib \ comdlg32.lib BLT_TCL_LIBS = $(MSVCRT) \ kernel32.lib user32.lib advapi32.lib BLT_TK_LIBS = $(OLELIB) \ $(JPG_LIB_SPEC) $(PNG_LIB_SPEC) $(TIF_LIB_SPEC) \ $(FT2_LIB_SPEC) \ $(MSVCRT) \ kernel32.lib user32.lib \ gdi32.lib oldnames.lib advapi32.lib winspool.lib \ comdlg32.lib # ------------------------------------------------------------------------ # Source and target installation directories # ------------------------------------------------------------------------ instdirs = $(prefix) $(exec_prefix) $(bindir) $(libdir) \ $(includedir) instdirs = $(exec_prefix) $(prefix) $(libdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ INCLUDES = -I. -I$(srcdir) -I$(srcdir)/win \ -I'$(TOOLS32)/include' \ -I$(TCLDIR)/include -I$(TKDIR)/include #-I$(TCLROOT)/include SO_LD_LIBS = $(COMMON_LIBS) $(EXTRA_LIBS) # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ blt_dt_csv_name = BltDataTableCsv$(version)$(DBG) blt_dt_mysql_name = BltDataTableMysql$(version)$(DBG) blt_dt_tree_name = BltDataTableTree$(version)$(DBG) blt_dt_vec_name = BltDataTableVector$(version)$(DBG) blt_dt_xml_name = BltDataTableXml$(version)$(DBG) blt_dt_xml_so = $(blt_dt_xml_name).dll blt_dt_mysql_so = $(blt_dt_mysql_name).dll blt_dt_tree_so = $(blt_dt_tree_name).dll blt_dt_vec_so = $(blt_dt_vec_name).dll blt_dt_csv_so = $(blt_dt_csv_name).dll blt_dt_xml_implib = $(blt_dt_xml_name).lib blt_dt_mysql_implib = $(blt_dt_mysql_name).lib blt_dt_tree_implib = $(blt_dt_tree_name).lib blt_dt_vec_implib = $(blt_dt_vec_name).lib blt_dt_csv_implib = $(blt_dt_csv_name).lib blt_pict_gif_name = BltPictureGif$(version)$(DBG) blt_pict_jpg_name = BltPictureJpg$(version)$(DBG) blt_pict_photo_name = BltPicturePhoto$(version)$(DBG) blt_pict_png_name = BltPicturePng$(version)$(DBG) blt_pict_tif_name = BltPictureTif$(version)$(DBG) blt_pict_xbm_name = BltPictureXbm$(version)$(DBG) blt_pict_xpm_name = BltPictureXpm$(version)$(DBG) blt_pict_gif_so = $(blt_pict_gif_name).dll blt_pict_jpg_so = $(blt_pict_jpg_name).dll blt_pict_png_so = $(blt_pict_png_name).dll blt_pict_tif_so = $(blt_pict_tif_name).dll blt_pict_xbm_so = $(blt_pict_xbm_name).dll blt_pict_xpm_so = $(blt_pict_xpm_name).dll blt_pict_photo_so = $(blt_pict_photo_name).dll blt_pict_gif_implib = $(blt_pict_gif_name).lib blt_pict_jpg_implib = $(blt_pict_jpg_name).lib blt_pict_png_implib = $(blt_pict_png_name).lib blt_pict_tif_implib = $(blt_pict_tif_name).lib blt_pict_xbm_implib = $(blt_pict_xbm_name).lib blt_pict_xpm_implib = $(blt_pict_xpm_name).lib blt_pict_photo_implib = $(blt_pict_photo_name).lib blt_tree_xml_name = BltTreeXml$(version)$(DBG) blt_tree_xml_so = $(blt_tree_xml_name).dll blt_tree_xml_implib = $(blt_tree_xml_name).lib blt_tcl_pkgs_so = $(blt_dt_csv_so) \ $(blt_dt_tree_so) \ $(blt_dt_vec_so) ifeq ($(WITH_EXPAT), 1) blt_tcl_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif ifneq ($(WITH_MYSQL), 1) blt_tcl_pkgs_so += $(blt_dt_mysql_so) endif blt_tk_pkgs_so = $(blt_pict_gif_so) \ $(blt_pict_xbm_so) \ $(blt_pict_photo_so) ifneq ($(WITH_JPG), 1) blt_tk_pkgs_so += $(blt_pict_jpg_so) endif ifneq ("$(PNG_LIB_SPEC)", "") blt_tk_pkgs_so += $(blt_pict_png_so) endif ifneq ("$(XPM_LIB_SPEC)", "") blt_tk_pkgs_so += $(blt_pict_xpm_so) endif ifneq ("$(XPM_TIF_SPEC)", "") blt_tk_pkgs_so += $(blt_pict_tif_so) endif N_OBJS = bltTed.o V3_OBJS = bltTri.o bltGrMt.o TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o TREEVIEW_OBJS = bltTreeView.o \ bltTvCmd.o \ bltTvCol.o \ bltTvEdit.o \ bltTvStyle.o PICTURE_OBJS = bltPicture.o \ bltPictCmd.o \ bltPictDraw.o \ bltPictMmx.o PICTURE_PKG_OBJS = bltPictGif.o \ bltPictJpg.o \ bltPictPhoto.o \ bltPictPng.o \ bltPictTif.o \ bltPictXbm.o \ bltPictXpm.o TREE_OBJS = bltTree.o \ bltTreeCmd.o \ TREE_PKG_OBJS = bltTreeXml.o DATATABLE_OBJS = bltDataTable.o \ bltDtCmd.o \ DATATABLE_PKG_OBJS = bltDtCsv.o \ bltDtMysql.o \ bltDtTree.o \ bltDtVec.o \ bltDtXml.o BLT_TCL_SO_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBase64.o \ bltBgexec.o \ bltChain.o \ bltCrc32.o \ bltCsv.o \ $(DATATABLE_OBJS) \ bltDebug.o \ bltHash.o \ bltInit.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltDBuffer.o \ bltSpline.o \ bltSwitch.o \ $(TREE_OBJS) \ bltUtil.o \ bltVar.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltWatch.o \ bltWinDde.o \ bltWinPipe.o \ bltWinUtil.o \ pure_api.o BLT_TCL_A_OBJS = $(BLT_TCL_SO_OBJS) \ $(TREE_PKG_OBJS) \ $(DATATABLE_PKG_OBJS) BLT_TK_SO_OBJS = $(GRAPH_OBJS) \ $(PICTURE_OBJS) \ $(TREEVIEW_OBJS) \ bltBeep.o \ bltBgStyle.o \ bltBind.o \ bltBitmap.o \ bltBusy.o \ bltCanvEps.o \ bltComboBtn.o \ bltComboEntry.o \ bltComboMenu.o \ bltComboTree.o \ bltConfig.o \ bltContainer.o \ bltCutbuffer.o \ bltDragdrop.o \ bltHtext.o \ bltImage.o \ bltOldConfig.o \ bltPs.o \ bltTable.o \ bltTabnotebook.o \ bltTabset.o \ bltText.o \ bltTile.o \ bltWinBitmap.o \ bltWinDraw.o \ bltWinFont.o \ bltWinPainter.o \ bltWinPrnt.o \ bltWinWindow.o \ bltWindow.o \ bltWinop.o \ $(TK_OBJS) $(N_OBJS) BLT_TK_A_OBJS = $(BLT_TK_SO_OBJS) \ $(PICTURE_PKG_OBJS) BLT_SO_OBJS = $(BLT_TCL_SO_OBJS) \ $(BLT_TK_SO_OBJS) BLT_A_OBJS = $(BLT_TCL_A_OBJS) \ $(BLT_TK_A_OBJS) DEMO_OBJS = tkConsole.o bltWinMain.o NOT_YET = bltContainer.o bltCutBuffer.o bltColor.o # GNU Make-specific macro SRCS = $(patsubst %.o,$(srcdir)/%.c,$(OBJS)) HEADERS = blt.h bltChain.h bltVector.h bltTree.h bltPool.h GENERATED_HEADERS = bltHash.h # GNU Make-specific macro SRCS = $(patsubst %.o,$(srcdir)/%.c,$(BLT_A_OBJS)) shell_name = bltwish version = $(BLT_MAJOR_VERSION)$(BLT_MINOR_VERSION) bltwish = bltwish.exe bltsh = bltsh.exe bltwish2 = bltwish$(version).exe bltsh2 = bltsh$(version).exe blt_tcl_name = BltTcl$(version)$(DBG) blt_tk_name = BltTk$(version)$(DBG) blt_tcl_spec = -L. -l$(blt_tcl_name) blt_tk_spec = -L. -l$(blt_tcl_name) blt_tcl_so = $(blt_tcl_name).dll blt_tcl_a = $(blt_tcl_name).a blt_tcl_implib = $(blt_tcl_name).lib blt_tk_so = $(blt_tk_name).dll blt_tk_a = $(blt_tk_name).a blt_tk_implib = $(blt_tk_name).lib CC_OPTS = $(CFLAGS) $(EXTRA_CFLAGS) $(DEFINES) $(INCLUDES) MAIN_CC_OPTS = $(CC_OPTS) $(JPG_DEFINES) $(PNG_DEFINES) VPATH = $(srcdir) all: bltHash.h build-library $(SO_TARGET) build-demos install: all install-dirs install-headers install-binaries install-demos build-demos: $(SO_TARGET) $(bltsh) $(bltwish) build-library: $(blt_tcl_so) $(blt_tcl_a) $(blt_tk_so) $(blt_tk_a) build-dll: build-library $(blt_tcl_so) $(blt_tk_so) build_tcl_pkgs: $(blt_tcl_pkgs_so) build_tk_pkgs: $(blt_tk_pkgs_so) $(bltwish): $(blt_tcl_so) $(blt_tk_so) tkConsole.o $(srcdir)/bltWinMain.c $(RM) $(bltwish) $(CC) -c $(MAIN_CC_OPTS) -DSTATIC_PKGS -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ -FobltWinMain.o $(srcdir)/bltWinMain.c $(LD) $(LDFLAGS) tkConsole.o bltWinMain.o -out:$(bltwish) \ -subsystem:windows -entry:WinMainCRTStartup \ $(blt_tk_a) $(blt_tcl_a) \ $(TK_STUBS_SPEC) $(TK_LIB_SPEC) \ $(TCL_STUBS_SPEC) $(TCL_LIB_SPEC) \ $(BLT_TK_LIBS) if test -r "$(bltwish).manifest" ; then \ $(MT) -nologo -manifest $(bltwish).manifest \ -outputresource:$(bltwish)\;1 ; \ fi $(bltsh): $(blt_tcl_so) $(srcdir)/bltWinMain.c $(RM) $(bltsh) $(CC) -c $(MAIN_CC_OPTS) -DTCL_ONLY -DSTATIC_PKGS \ -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ -FobltWinMain.o $(srcdir)/bltWinMain.c $(LD) $(LDFLAGS) bltWinMain.o -out:$(bltsh) \ -subsystem:console -entry:mainCRTStartup \ $(blt_tcl_a) \ $(TCL_STUBS_SPEC) $(TCL_LIB_SPEC) \ $(BLT_TCL_LIBS) if test -r "$(bltsh).manifest" ; then \ $(MT) -nologo -manifest $(bltsh).manifest \ -outputresource:$(bltsh)\;1 ; \ fi $(blt_tk_a): $(BLT_TK_A_OBJS) bltTkInit.c $(RM) bltTkInit.o $(CC) -c $(CC_OPTS) -FobltTkInit.o $(srcdir)/bltTkInit.c $(RM) $@ $(AR) -out:$@ bltTkInit.o $(BLT_TK_A_OBJS) $(blt_tk_so): $(blt_tcl_a) $(BLT_TK_SO_OBJS) bltTkInit.c $(RM) bltTkInit.o $(CC) -c $(CC_OPTS) -DUSE_DLL -FobltTkInit.o $(srcdir)/bltTkInit.c $(RM) $@ $(LD) $(BLT_TK_SO_LDFLAGS) -out:$@ bltTkInit.o $(BLT_TK_SO_OBJS) \ $(blt_tcl_implib) $(tk_lib_spec) $(tcl_lib_spec) \ $(BLT_TK_LIBS) if test -r "$(blt_tk_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_tk_so).manifest \ -outputresource:$(blt_tk_so)\;2 ; \ fi $(blt_tcl_a): bltHash.h $(BLT_TCL_A_OBJS) bltTclInit.c $(RM) bltTclInit.o $(CC) -c $(CC_OPTS) -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltTclInit.o $(srcdir)/bltTclInit.c $(RM) $@ $(AR) -out:$@ bltTclInit.o $(BLT_TCL_A_OBJS) $(blt_tcl_so): $(blt_tcl_a) $(BLT_TCL_SO_OBJS) bltTkInit.c $(RM) bltTclInit.o $(CC) -c $(CC_OPTS) -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" -DUSE_DLL \ -FobltTclInit.o $(srcdir)/bltTclInit.c $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltTclInit.o $(BLT_TCL_SO_OBJS) \ $(tcl_lib_spec) $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_tcl_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_tcl_so).manifest \ -outputresource:$(blt_tcl_so)\;2 ; \ fi $(blt_dt_mysql_so): bltDtMysql.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_dt_xml_so): bltDtXml.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtXml.o $(EXPAT_LIB_SPEC) $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtXml.o $(EXPAT_LIB_SPEC) \ $(blt_tcl_implib) $(tcl_lib_spec) $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_xml_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_xml_so).manifest \ -outputresource:$(blt_dt_xml_so)\;2 ; \ fi $(blt_dt_csv_so): bltDtCsv.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtCsv.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_dt_vec_so): bltDtVec.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtVec.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_dt_tree_so): bltDtTree.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltDtTree.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_gif_so): bltPictGif.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictGif.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_jpg_so): bltPictJpg.o $(RM) $@ $(LD) $(BLT_TK_SO_LDFLAGS) -out:$@ bltPictJpg.o $(JPG_LIB_SPEC) \ $(blt_tcl_implib) $(tcl_lib_spec) $(LIBS) if test -r "$(blt_pict_jpg_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_pict_jpg_so).manifest \ -outputresource:$(blt_pict_jpg_so)\;2 ; \ fi $(blt_pict_png_so): bltPictPng.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictPng.o $(PNG_LIB_SPEC) $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_tif_so): bltPictTif.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictTif.o $(TIF_LIB_SPEC) $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_xbm_so): bltPictXbm.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictXbm.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_xpm_so): bltPictXpm.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictXpm.o \ $(X11_LIB_SPEC) $(XPM_LIB_SPEC) $(RM) $@ $(LD) $(BLT_TK_SO_LDFLAGS) -out:$@ bltDtMysql.o \ $(blt_tcl_implib) $(tcl_lib_spec) $(tk_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_dt_mysql_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_dt_mysql_so).manifest \ -outputresource:$(blt_dt_mysql_so)\;2 ; \ fi $(blt_pict_photo_so): bltPictPhoto.o $(RM) $@ $(SO_LD) $(SO_LD_FLAGS) -o $@ bltPictPhoto.o $(RM) $@ $(LD) $(BLT_TK_SO_LDFLAGS) -out:$@ bltPictPhoto.o \ $(blt_tk_implib) $(blt_tcl_implib) \ $(tk_lib_spec) $(tcl_lib_spec) \ $(BLT_TK_LIBS) $(LIBS) if test -r "$(blt_pict_photo_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_pict_photo_so).manifest \ -outputresource:$(blt_pict_photo_so)\;2 ; \ fi $(blt_tree_xml_so): bltTreeXml.o $(RM) $@ $(LD) $(BLT_TCL_SO_LDFLAGS) -out:$@ bltTreeXml.o $(EXPAT_LIB_SPEC) \ $(blt_tcl_implib) $(tcl_lib_spec) \ $(BLT_TCL_LIBS) $(LIBS) if test -r "$(blt_tree_xml_so).manifest" ; then \ $(MT) -nologo -manifest $(blt_tree_xml_so).manifest \ -outputresource:$(blt_tree_xml_so)\;2 ; \ fi bltWinMain.o: $(srcdir)/bltWinMain.c $(CC) -c $(CC_OPTS) -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ -FobltWinMain.o $(srcdir)/bltWinMain.c bltPictureDraw.o: $(srcdir)/bltPictureDraw.c $(CC) -c $(CC_OPTS) $(FREETYPE2_INC_SPEC) \ -FobltPictureDraw.o $(srcdir)/bltPictureDraw.c bltDtMysql.o: $(srcdir)/bltDtMysql.c $(CC) -c $(CC_OPTS) $(MYSQL_DEFINES) $(MYSQL_INC_SPEC) \ -FobltDtMysql.o $(srcdir)/bltDtMysql.c bltDtXml.o: $(srcdir)/bltDtXml.c $(CC) -c $(CC_OPTS) $(EXPAT_DEFINES) $(EXPAT_INC_SPEC) \ -FobltDtXml.o $(srcdir)/bltDtXml.c bltTreeXml.o: $(srcdir)/bltTreeXml.c $(CC) -c $(CC_OPTS) $(EXPAT_DEFINES) $(EXPAT_INC_SPEC) \ -FobltTreeXml.o $(srcdir)/bltTreeXml.c bltPictJpg.o: $(srcdir)/bltPictJpg.c $(CC) -c $(CC_OPTS) $(JPG_DEFINES) $(JPG_INC_SPEC) \ -FobltPictJpg.o $(srcdir)/bltPictJpg.c bltPictPng.o: $(srcdir)/bltPictPng.c $(CC) -c $(CC_OPTS) $(PNG_DEFINES) $(PNG_INC_SPEC) \ -FobltPictPng.o $(srcdir)/bltPictPng.c bltPictureFormats.o: $(srcdir)/bltPictureFormats.c $(CC) -c $(CC_OPTS) $(PICTURE_DEFINES) \ $(FREETYPE2_INC_SPEC) $(PICTURE_INCLUDES) \ -FobltPictureFormats.o $(srcdir)/bltPictureFormats.c bltPictureImage.o: $(srcdir)/bltPictureImage.c $(CC) -c $(CC_OPTS) $(PICTURE_DEFINES) \ -FobltPictureImage.o $(srcdir)/bltPictureImage.c bltHash.h: $(srcdir)/bltHash.h.in sed -e 's/@SIZEOF_VOID_P@/4/' \ -e 's/@SIZEOF_INT@/4/' \ -e 's/@SIZEOF_LONG@/4/' \ -e 's/@SIZEOF_LONG_LONG@/8/' \ -e 's/@HAVE_INTTYPES_H@/0/' \ $(srcdir)/bltHash.h.in > bltHash.h bltHash.c: bltHash.h install-dirs: @for i in $(instdirs) ; do \ if test ! -d "$$i" ; then \ echo " mkdir $$i" ; \ mkdir "$$i" ; \ fi ; \ done install-binaries: install-lib install-demos install-demos: build-demos $(INSTALL) $(bltwish) $(bindir)/$(bltwish) $(INSTALL) $(bltwish) $(bindir)/$(bltwish2) $(INSTALL) $(bltsh) $(bindir)/$(bltsh) $(INSTALL) $(bltsh) $(bindir)/$(bltsh2) install-lib: $(blt_tcl_so) $(blt_tk_so) $(blt_tcl_a) $(blt_tk_a) $(INSTALL) $(blt_tcl_so) $(bindir) $(INSTALL) $(blt_tk_so) $(bindir) $(INSTALL_DATA) $(blt_tcl_a) $(libdir) $(INSTALL_DATA) $(blt_tk_a) $(libdir) install-headers: bltHash.h for i in $(HEADERS) ; do \ $(INSTALL_DATA) "$(srcdir)/$$i" $(includedir) ; \ done $(INSTALL_DATA) bltHash.h $(includedir) lint: $(LINT) $(LINTFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) clean: $(RM) *.o *.pdb *.exp *.manifest *.lib \ $(blt_tcl_a) $(blt_tcl_so) \ $(blt_tk_a) $(blt_tk_so) \ $(bltwish) $(bltsh) $(bltwish2) $(bltsh2) $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* distclean: clean $(RM) Makefile bltTclInit.o: bltTclInit.c $(CC) -c $(CC_OPTS) -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ -FobltTclInit.o $(srcdir)/bltTclInit.c bltPictCmd.o: $(srcdir)/bltPictCmd.c $(CC) -c $(CC_OPTS) $(LIB_DEFINES) -Fo$@ $(srcdir)/bltPictCmd.c bltDtCmd.o: $(srcdir)/bltDtCmd.c $(CC) -c $(CC_OPTS) $(LIB_DEFINES) -Fo$@ $(srcdir)/bltDtCmd.c bltTreeCmd.o: $(srcdir)/bltTreeCmd.c $(CC) -c $(CC_OPTS) $(LIB_DEFINES) -Fo$@ $(srcdir)/bltTreeCmd.c bltPictDraw.o: $(srcdir)/bltPictDraw.c $(CC) -c $(CC_OPTS) $(FT2_DEFINES) -Fo$@ $(srcdir)/bltPictDraw.c .c.o: $(CC) -c $(CC_OPTS) -Fo$@ $< �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDragdrop.c�����������������������������������������������������������������0000644�0001750�0001750�00000236203�11462120062�015443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltDragdrop.c -- * * This module implements a drag-and-drop mechanism for the Tk Toolkit. * Allows widgets to be registered as drag&drop sources and targets for * handling "drag-and-drop" operations between Tcl/Tk applications. * * The "drag&drop" command was created by Michael J. McLennan. * * Copyright 1993-1998 Lucent Technologies, Inc. * * Permission to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is * hereby granted, provided that the above copyright notice * appear in all copies and that both that the copyright notice * and warranty disclaimer appear in supporting documentation, * and that the names of Lucent Technologies any of their * entities not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. * * Lucent Technologies disclaims all warranties with regard to * this software, including all implied warranties of * merchantability and fitness. In no event shall Lucent * Technologies be liable for any special, indirect or * consequential damages or any damages whatsoever resulting from * loss of use, data or profits, whether in an action of * contract, negligence or other tortuous action, arising out of * or in connection with the use or performance of this software. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "bltInt.h" #ifndef NO_DRAGDROP #include "bltOp.h" #include "bltHash.h" #include "bltChain.h" #include <X11/Xatom.h> #include "tkDisplay.h" #define DRAGDROP_THREAD_KEY "BLT Dragdrop Command Data" #ifdef WIN32 #define MAX_PROP_SIZE 255 /* Maximum size of property. */ typedef HWND WINDOW; #else #define MAX_PROP_SIZE 1000 /* Maximum size of property. */ typedef Window WINDOW; static Atom dndAtom; #endif /* * Each "drag&drop" target widget is tagged with a "BltDrag&DropTarget" * property in XA_STRING format. This property identifies the window * as a "drag&drop" target. It's formated as a TCL list and contains * the following information: * * "INTERP_NAME TARGET_NAME DATA_TYPE DATA_TYPE ..." * * INTERP_NAME Name of the target application's interpreter. * TARGET_NAME Path name of widget registered as the drop target. * DATA_TYPE One or more "types" handled by the target. * * When the user invokes the "drag" operation, the window hierarchy * is progressively examined. Window information is cached during * the operation, to minimize X server traffic. Windows carrying a * "BltDrag&DropTarget" property are identified. When the token is * dropped over a valid site, the drop information is sent to the * application * via the usual "send" command. If communication fails, the drag&drop * facility automatically posts a rejection symbol on the token window. */ #define INTERP_NAME 0 #define TARGET_NAME 1 #define DATA_TYPE 2 /* Error Proc used to report drag&drop background errors */ #define DEF_ERROR_PROC "bgerror" /* * CONFIG PARAMETERS */ #define DEF_DND_BUTTON_BACKGROUND RGB_YELLOW #define DEF_DND_BUTTON_NUMBER "3" #define DEF_DND_PACKAGE_COMMAND (char *)NULL #define DEF_DND_SELF_TARGET "no" #define DEF_DND_SEND "all" #define DEF_DND_SITE_COMMAND (char *)NULL #define DEF_TOKEN_ACTIVE_BACKGROUND STD_ACTIVE_BACKGROUND #define DEF_TOKEN_ACTIVE_BORDERWIDTH "3" #define DEF_TOKEN_ACTIVE_RELIEF "sunken" #define DEF_TOKEN_ANCHOR "se" #define DEF_TOKEN_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_TOKEN_BORDERWIDTH "3" #define DEF_TOKEN_CURSOR "arrow" #define DEF_TOKEN_OUTLINE_COLOR RGB_BLACK #define DEF_TOKEN_REJECT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_TOKEN_REJECT_FOREGROUND RGB_RED #define DEF_TOKEN_REJECT_STIPPLE_COLOR (char *)NULL #define DEF_TOKEN_RELIEF "raised" static char dragDropCmd[] = "::blt::drag&drop"; static char className[] = "DragDropToken"; /* CLASS NAME of token window */ static char propName[] = "BltDrag&DropTarget"; /* Property name */ #ifndef WIN32 static int initialized = FALSE; #endif typedef struct { Blt_HashTable sourceTable; Blt_HashTable targetTable; int nActive; int locX, locY; Tcl_Interp *interp; Tk_Window tkMain; /* Main window of the interpreter. */ } DragdropCmdInterpData; /* * Percent substitutions */ typedef struct { char letter; /* character like 'x' in "%x" */ const char *value; /* value to be substituted in place of "%x" */ } SubstDescriptors; /* * AnyWindow -- * * This structure represents a window hierarchy examined during * a single "drag" operation. It's used to cache information * to reduce the round-trip calls to the server needed to query * window geometry information and grab the target property. */ typedef struct _AnyWindow AnyWindow; struct _AnyWindow { WINDOW nativeWindow; /* Native window: HWINDOW (Win32) or * Window (X11). */ int initialized; /* If non-zero, the rest of this structure's * information had been previously built. */ int x1, y1, x2, y2; /* Extents of the window (upper-left and * lower-right corners). */ AnyWindow *parentPtr; /* Parent node. NULL if root. Used to * compute offset for X11 windows. */ Blt_Chain chain; /* List of this window's children. If NULL, * there are no children. */ const char **targetInfo; /* An array of target window drag&drop * information: target interpreter, * pathname, and optionally possible * type matches. NULL if the window is * not a drag&drop target or is not a * valid match for the drop source. */ }; /* * Drag&Drop Registration Data */ typedef struct { /* * This is a goof in the Tk API. It assumes that only an official * Tk "toplevel" widget will ever become a toplevel window (i.e. a * window whose parent is the root window). Because under Win32, * Tk tries to use the widget record associated with the TopLevel * as a Tk frame widget, to read its menu name. What this means * is that any widget that's going to be a toplevel, must also look * like a frame. Therefore we've copied the frame widget structure * fields into the token. */ Tk_Window tkwin; /* Window that embodies the frame. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up. */ Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tcl_Command widgetCmd; /* Token for frame's widget command. */ const char *className; /* Class name for widget (from configuration * option). Malloc-ed. */ int mask; /* Either FRAME or TOPLEVEL; used to select * which configuration options are valid for * widget. */ const char *screenName; /* Screen on which widget is created. Non-null * only for top-levels. Malloc-ed, may be * NULL. */ const char *visualName; /* Textual description of visual for window, * from -visual option. Malloc-ed, may be * NULL. */ const char *colormapName; /* Textual description of colormap for window, * from -colormap option. Malloc-ed, may be * NULL. */ const char *menuName; /* Textual description of menu to use for * menubar. Malloc-ed, may be NULL. */ Colormap colormap; /* If not None, identifies a colormap * allocated for this window, which must be * freed when the window is deleted. */ Tk_3DBorder border; /* Structure used to draw 3-D border and * background. NULL means no background * or border. */ int borderWidth; /* Width of 3-D border (if any). */ int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int width; /* Width to request for window. <= 0 means * don't request any size. */ int height; /* Height to request for window. <= 0 means * don't request any size. */ Tk_Cursor cursor; /* Current cursor for window, or None. */ const char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ int isContainer; /* 1 means this window is a container, 0 means * that it isn't. */ const char *useThis; /* If the window is embedded, this points to * the name of the window in which it is * embedded (malloc'ed). For non-embedded * windows this is NULL. */ int flags; /* Various flags; see below for * definitions. */ /* Token specific fields */ int lastX, lastY; /* last position of token window */ int active; /* non-zero => over target window */ Tcl_TimerToken timer; /* token for routine to hide tokenwin */ GC rejectFgGC; /* GC used to draw rejection fg: (\) */ GC rejectBgGC; /* GC used to draw rejection bg: (\) */ /* User-configurable fields */ Tk_Anchor anchor; /* Position of token win relative to mouse */ Tk_3DBorder outline; /* Outline border around token window */ Tk_3DBorder normalBorder; /* Border/background for token window */ Tk_3DBorder activeBorder; /* Border/background for token window */ int activeRelief; int activeBW; /* Border width in pixels */ XColor *rejectFg; /* Color used to draw rejection fg: (\) */ XColor *rejectBg; /* Color used to draw rejection bg: (\) */ Pixmap rejectStipple; /* Stipple used to draw rejection: (\) */ } Token; typedef struct { Tcl_Interp *interp; /* Interpreter associated with the Tk source * widget. */ Tk_Window tkwin; /* Tk window registered as the drag&drop * source. */ Display *display; /* Drag&drop source window display */ Blt_HashTable handlerTable; /* Table of data handlers (converters) * registered for this source. */ int button; /* Button used to invoke drag operation. */ Token token; /* Token used to provide special cursor. */ int pkgCmdInProgress; /* Indicates if a pkgCmd is currently active. */ const char *pkgCmd; /* TCL command executed at start of "drag" * operation to gather information about * the source data. */ const char *pkgCmdResult; /* Result returned by the most recent * pkgCmd. */ const char *siteCmd; /* TCL command executed to update token * window. */ AnyWindow *rootPtr; /* Cached window information: Gathered * and used during the "drag" operation * to see if the mouse pointer is over a * valid target. */ int selfTarget; /* Indicated if the source should drop onto * itself. */ Tk_Cursor cursor; /* cursor restored after dragging */ const char **sendTypes; /* list of data handler names or "all" */ Blt_HashEntry *hashPtr; AnyWindow *windowPtr; /* Last target examined. If NULL, mouse * pointer is not currently over a valid * target. */ Tcl_Obj *errorCmdObjPtr; DragdropCmdInterpData *dataPtr; } Source; typedef struct { Tcl_Interp *interp; Tk_Window tkwin; /* drag&drop target window */ Display *display; /* drag&drop target window display */ Blt_HashTable handlerTable; /* Table of data handlers (converters) * registered for this target. */ Blt_HashEntry *hashPtr; DragdropCmdInterpData *dataPtr; } Target; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_INT, "-button", "buttonBinding", "ButtonBinding", DEF_DND_BUTTON_NUMBER, Blt_Offset(Source, button), 0}, {BLT_CONFIG_OBJ, "-errorcmd", "errorCommand", "ErrorCommand", "bgerror", Blt_Offset(Source, errorCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-packagecmd", "packageCommand", "PackageCommand", DEF_DND_PACKAGE_COMMAND, Blt_Offset(Source, pkgCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-rejectbg", "rejectBackground", "Background", DEF_TOKEN_REJECT_BACKGROUND, Blt_Offset(Source, token.rejectBg), 0}, {BLT_CONFIG_COLOR, "-rejectfg", "rejectForeground", "Foreground", DEF_TOKEN_REJECT_FOREGROUND, Blt_Offset(Source, token.rejectFg), 0}, {BLT_CONFIG_BITMAP, "-rejectstipple", "rejectStipple", "Stipple", DEF_TOKEN_REJECT_STIPPLE_COLOR, Blt_Offset(Source, token.rejectStipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-selftarget", "selfTarget", "SelfTarget", DEF_DND_SELF_TARGET, Blt_Offset(Source, selfTarget), 0}, {BLT_CONFIG_LIST, "-send", "send", "Send", DEF_DND_SEND, Blt_Offset(Source, sendTypes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-sitecmd", "siteCommand", "Command", DEF_DND_SITE_COMMAND, Blt_Offset(Source, siteCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-tokenanchor", "tokenAnchor", "Anchor", DEF_TOKEN_ANCHOR, Blt_Offset(Source, token.anchor), 0}, {BLT_CONFIG_BORDER, "-tokenactivebackground", "tokenActiveBackground", "ActiveBackground", DEF_TOKEN_ACTIVE_BACKGROUND, Blt_Offset(Source, token.activeBorder), 0}, {BLT_CONFIG_BORDER, "-tokenbg", "tokenBackground", "Background", DEF_TOKEN_BACKGROUND, Blt_Offset(Source, token.normalBorder), 0}, {BLT_CONFIG_BORDER, "-tokenoutline", "tokenOutline", "Outline", DEF_TOKEN_OUTLINE_COLOR, Blt_Offset(Source, token.outline), 0}, {BLT_CONFIG_PIXELS_NNEG, "-tokenborderwidth", "tokenBorderWidth", "BorderWidth", DEF_TOKEN_BORDERWIDTH, Blt_Offset(Source, token.borderWidth), 0}, {BLT_CONFIG_CURSOR, "-tokencursor", "tokenCursor", "Cursor", DEF_TOKEN_CURSOR, Blt_Offset(Source, token.cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, }; static Blt_ConfigSpec tokenConfigSpecs[] = { {BLT_CONFIG_BORDER, "-activebackground", "activeBackground", "ActiveBackground", DEF_TOKEN_ACTIVE_BACKGROUND, Blt_Offset(Token, activeBorder), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "activeRelief", DEF_TOKEN_ACTIVE_RELIEF, Blt_Offset(Token, activeRelief), 0}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_TOKEN_ANCHOR, Blt_Offset(Token, anchor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-activeborderwidth", "activeBorderWidth", "ActiveBorderWidth", DEF_TOKEN_ACTIVE_BORDERWIDTH, Blt_Offset(Token, activeBW), 0}, {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_TOKEN_BACKGROUND, Blt_Offset(Token, normalBorder), 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_TOKEN_BORDERWIDTH, Blt_Offset(Token, borderWidth), 0}, {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor", DEF_TOKEN_CURSOR, Blt_Offset(Token, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BORDER, "-outline", "outline", "Outline", DEF_TOKEN_OUTLINE_COLOR, Blt_Offset(Token, outline), 0}, {BLT_CONFIG_COLOR, "-rejectbg", "rejectBackground", "Background", DEF_TOKEN_REJECT_BACKGROUND, Blt_Offset(Token, rejectBg), 0}, {BLT_CONFIG_COLOR, "-rejectfg", "rejectForeground", "Foreground", DEF_TOKEN_REJECT_FOREGROUND, Blt_Offset(Token, rejectFg), 0}, {BLT_CONFIG_BITMAP, "-rejectstipple", "rejectStipple", "Stipple", DEF_TOKEN_REJECT_STIPPLE_COLOR, Blt_Offset(Token, rejectStipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_TOKEN_RELIEF, Blt_Offset(Token, relief), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, }; /* * Forward Declarations */ static Tcl_ObjCmdProc DragDropCmd; static Tk_EventProc TokenEventProc; static Tk_EventProc TargetEventProc; static void MoveToken(Source * srcPtr, Token *tokenPtr); static void UpdateToken(ClientData clientData); static void HideToken(Token *tokenPtr); static void RejectToken(Token *tokenPtr); static int GetSourceFromObj(DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, Source **srcPtrPtr); static Source *CreateSource(DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, int *newEntry); static void DestroySource(Source * srcPtr); static void SourceEventProc(ClientData clientData, XEvent *eventPtr); static int ConfigureSource(Tcl_Interp *interp, Source * srcPtr, int objc, Tcl_Obj *const *objv, int flags); static int ConfigureToken(Tcl_Interp *interp, Source * srcPtr, int objc, Tcl_Obj *const *objv); static Target *CreateTarget(DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tk_Window tkwin); static Target *FindTarget(DragdropCmdInterpData *dataPtr, Tk_Window tkwin); static void DestroyTarget(DestroyData data); static int OverTarget(Source * srcPtr, int x, int y); static void AddTargetProperty(Tcl_Interp *interp, Target *targetPtr); static void DndSend(Source *srcPtr); static void InitRoot(Source * srcPtr); static void RemoveWindow(AnyWindow *wr); static void QueryWindow(Display *display, AnyWindow * windowPtr); static const char *ExpandPercents(const char *str, SubstDescriptors *subs, int nsubs, Tcl_DString *resultPtr); /* *--------------------------------------------------------------------------- * * DragdropInterpDeleteProc -- * * This is called when the interpreter hosting the "dragdrop" * command is deleted. * * Results: * None. * * Side effects: * Removes the hash table managing all dragdrop names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void DragdropInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { DragdropCmdInterpData *dataPtr = clientData; /* All dragdrop instances should already have been destroyed when * their respective TCL commands were deleted. */ Blt_DeleteHashTable(&dataPtr->sourceTable); Blt_DeleteHashTable(&dataPtr->targetTable); Tcl_DeleteAssocData(interp, DRAGDROP_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * GetDragdropdCmdInterpData -- * *--------------------------------------------------------------------------- */ static DragdropCmdInterpData * GetDragdropCmdInterpData(Tcl_Interp *interp) { DragdropCmdInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (DragdropCmdInterpData *) Tcl_GetAssocData(interp, DRAGDROP_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(DragdropCmdInterpData)); dataPtr->interp = interp; dataPtr->tkMain = Tk_MainWindow(interp); Tcl_SetAssocData(interp, DRAGDROP_THREAD_KEY, DragdropInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->sourceTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&dataPtr->targetTable, BLT_ONE_WORD_KEYS); dataPtr->nActive = 0; dataPtr->locX = dataPtr->locY = 0; } return dataPtr; } #ifdef WIN32 #if defined( _MSC_VER) || defined(__BORLANDC__) #include <tchar.h> #endif /* _MSC_VER || __BORLANDC__ */ typedef struct { const char *prefix; int prefixSize; const char *propReturn; } PropertyInfo; #ifdef notdef static BOOL CALLBACK GetEnumWindowsProc(HWND hWnd, LPARAM clientData) { Blt_Chain chain = (Blt_Chain)clientData; Blt_Chain_Append(chain, (ClientData)hWnd); return TRUE; } #endif static WINDOW GetNativeWindow(Tk_Window tkwin) { return (WINDOW) Tk_GetHWND(Tk_WindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * GetWindowZOrder -- * * Returns a list of the child windows according to their stacking * order. The window handles are ordered from top to bottom. * *--------------------------------------------------------------------------- */ static Blt_Chain GetWindowZOrder(Display *display, HWND parent) { Blt_Chain chain; HWND hWnd; chain = Blt_Chain_Create(); for (hWnd = GetTopWindow(parent); hWnd != NULL; hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)) { Blt_Chain_Append(chain, (ClientData)hWnd); } return chain; } /* *--------------------------------------------------------------------------- * * GetEnumPropsExProc -- * *--------------------------------------------------------------------------- */ static BOOL CALLBACK GetEnumPropsExProc( HWND hwnd, LPCTSTR atom, HANDLE hData, DWORD clientData) { PropertyInfo *infoPtr = (PropertyInfo *) clientData; if (strncmp(infoPtr->prefix, atom, infoPtr->prefixSize) == 0) { assert(infoPtr->propReturn == NULL); infoPtr->propReturn = (const char *)atom; return FALSE; } return TRUE; } #ifdef notdef /* *--------------------------------------------------------------------------- * * GetPropData -- * * This is a bad Windows hack to pass property information between * applications. (Ab)Normally the property data (one-word value) is * stored in the data handle. But the data content is available only * within the application. The pointer value is meaningless outside * of the current application address space. Not really useful at all. * * So the trick here is to encode the property name with all the * necessary information and to loop through all the properties * of a window, looking for one that starts with our property name * prefix. The downside is that the property name is limited to * 255 bytes. But that should be enough. It's also slower since * we examine each property until we find ours. * * We'll plug in the OLE stuff later. * *--------------------------------------------------------------------------- */ static const char * GetPropData(HWND hWnd, char *atom) { PropertyInfo propInfo; if (hWnd == NULL) { return NULL; } propInfo.prefix = atom; propInfo.prefixSize = strlen(atom); propInfo.propReturn = NULL; EnumPropsEx(hWnd, (PROPENUMPROCEX)GetEnumPropsExProc, (DWORD)&propInfo); return propInfo.propReturn; } #endif static const unsigned char * GetProperty(Display *display, HWND hWnd) { HANDLE handle; handle = GetProp(hWnd, propName); if (handle != NULL) { ATOM atom; char buffer[MAX_PROP_SIZE + 1]; UINT nBytes; atom = (ATOM)((int)handle); nBytes = GlobalGetAtomName(atom, buffer, MAX_PROP_SIZE); if (nBytes > 0) { buffer[nBytes] = '\0'; return Blt_AssertStrdup(buffer); } } return NULL; } static void SetProperty(Tk_Window tkwin, const char *data) { HANDLE handle; HWND hWnd; ATOM atom; hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); if (hWnd == NULL) { return; } handle = GetProp(hWnd, propName); atom = (ATOM)((int)handle); if (atom != (ATOM)0) { GlobalDeleteAtom(atom); } atom = GlobalAddAtom((unsigned char *)data); if (atom != (ATOM)0) { handle = (HANDLE)((int)atom); SetProp(hWnd, propName, handle); } } static void RemoveProperty(Tk_Window tkwin) { HWND hWnd; HANDLE handle; hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); if (hWnd == NULL) { return; } handle = GetProp(hWnd, propName); if (handle != NULL) { ATOM atom; atom = (ATOM)((int)handle); GlobalDeleteAtom(atom); } RemoveProp(hWnd, propName); } /* *--------------------------------------------------------------------------- * * GetWindowRegion -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GetWindowRegion( Display *display, /* Not used. */ HWND hWnd, int *x1Ptr, int *y1Ptr, int *x2Ptr, int *y2Ptr) { RECT rect; if (GetWindowRect(hWnd, &rect)) { *x1Ptr = rect.left; *y1Ptr = rect.top; *x2Ptr = rect.right; *y2Ptr = rect.bottom; return IsWindowVisible(hWnd); } return FALSE; } #else static WINDOW GetNativeWindow(Tk_Window tkwin) { return Tk_WindowId(tkwin); } /* *--------------------------------------------------------------------------- * * GetWindowZOrder -- * * Returns a chain of the child windows according to their stacking * order. The window ids are ordered from top to bottom. * *--------------------------------------------------------------------------- */ static Blt_Chain GetWindowZOrder(Display *display, Window window) { Blt_Chain chain; Window *winv; unsigned int winc; Window dummy; chain = NULL; if ((XQueryTree(display, window, &dummy, &dummy, &winv, &winc)) && (winc > 0)) { unsigned int i; chain = Blt_Chain_Create(); for (i = 0; i < winc; i++) { /* * XQuery returns windows in bottom to top order. * We only care about the top window. */ Blt_Chain_Prepend(chain, (ClientData)winv[i]); } if (winv != NULL) { XFree((char *)winv); /* done with list of kids */ } } return chain; } static const unsigned char * GetProperty( Display *display, Window window) { unsigned char *data; int result, actualFormat; Atom actualType; unsigned long nItems, bytesAfter; if (window == None) { return NULL; } data = NULL; result = XGetWindowProperty(display, window, dndAtom, 0, MAX_PROP_SIZE, False, XA_STRING, &actualType, &actualFormat, &nItems, &bytesAfter, &data); if ((result != Success) || (actualFormat != 8) || (actualType != XA_STRING)) { if (data != NULL) { XFree(data); data = NULL; } } return data; } static void SetProperty(Tk_Window tkwin, char *data) { XChangeProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), dndAtom, XA_STRING, 8, PropModeReplace, (unsigned char *)data, strlen(data) + 1); } static int GetWindowRegion( Display *display, Window window, int *x1Ptr, int *y1Ptr, int *x2Ptr, int *y2Ptr) { XWindowAttributes winAttrs; if (XGetWindowAttributes(display, window, &winAttrs)) { *x1Ptr = winAttrs.x; *y1Ptr = winAttrs.y; *x2Ptr = winAttrs.x + winAttrs.width - 1; *y2Ptr = winAttrs.y + winAttrs.height - 1; } return (winAttrs.map_state == IsViewable); } #endif /* WIN32 */ /* *--------------------------------------------------------------------------- * * ChangeToken -- * *--------------------------------------------------------------------------- */ static void ChangeToken(Token *tokenPtr, int active) { int relief; Tk_3DBorder border; int borderWidth; Blt_Fill3DRectangle(tokenPtr->tkwin, Tk_WindowId(tokenPtr->tkwin), tokenPtr->outline, 0, 0, Tk_Width(tokenPtr->tkwin), Tk_Height(tokenPtr->tkwin), 0, TK_RELIEF_FLAT); if (active) { relief = tokenPtr->activeRelief; border = tokenPtr->activeBorder; borderWidth = tokenPtr->activeBW; } else { relief = tokenPtr->relief; border = tokenPtr->normalBorder; borderWidth = tokenPtr->borderWidth; } Blt_Fill3DRectangle(tokenPtr->tkwin, Tk_WindowId(tokenPtr->tkwin), border, 2, 2, Tk_Width(tokenPtr->tkwin) - 4, Tk_Height(tokenPtr->tkwin) - 4, borderWidth, relief); } /* *--------------------------------------------------------------------------- * * TokenEventProc -- * * Invoked by the Tk dispatcher to handle widget events. * Manages redraws for the drag&drop token window. * *--------------------------------------------------------------------------- */ static void TokenEventProc( ClientData clientData, /* data associated with widget */ XEvent *eventPtr) /* information about event */ { Token *tokenPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { if (tokenPtr->tkwin != NULL) { ChangeToken(tokenPtr, tokenPtr->active); } } else if (eventPtr->type == DestroyNotify) { tokenPtr->tkwin = NULL; } } /* *--------------------------------------------------------------------------- * * HideToken -- * * Unmaps the drag&drop token. Invoked directly at the end of a * successful communication, or after a delay if the communication * fails (allowing the user to see a graphical picture of failure). * *--------------------------------------------------------------------------- */ static void HideToken(Token *tokenPtr) { if (tokenPtr->tkwin != NULL) { Tk_UnmapWindow(tokenPtr->tkwin); } tokenPtr->timer = NULL; } /* *--------------------------------------------------------------------------- * * RaiseToken -- * *--------------------------------------------------------------------------- */ static void RaiseToken(Token *tokenPtr) { Blt_MapToplevelWindow(tokenPtr->tkwin); Blt_RaiseToplevelWindow(tokenPtr->tkwin); } /* *--------------------------------------------------------------------------- * * MoveToken -- * * Invoked during "drag" operations to move a token window to its * current "drag" coordinate. * *--------------------------------------------------------------------------- */ static void MoveToken( Source *srcPtr, /* drag&drop source window data */ Token *tokenPtr) { int x, y; int maxX, maxY; int vx, vy, vw, vh; int screenWidth, screenHeight; Blt_SizeOfScreen(srcPtr->tkwin, &screenWidth, &screenHeight); /* Adjust current location for virtual root windows. */ Tk_GetVRootGeometry(srcPtr->tkwin, &vx, &vy, &vw, &vh); x = tokenPtr->lastX + vx - 3; y = tokenPtr->lastY + vy - 3; maxX = screenWidth - Tk_Width(tokenPtr->tkwin); maxY = screenHeight - Tk_Height(tokenPtr->tkwin); Blt_TranslateAnchor(x, y, Tk_Width(tokenPtr->tkwin), Tk_Height(tokenPtr->tkwin), tokenPtr->anchor, &x, &y); if (x > maxX) { x = maxX; } else if (x < 0) { x = 0; } if (y > maxY) { y = maxY; } else if (y < 0) { y = 0; } if ((x != Tk_X(tokenPtr->tkwin)) || (y != Tk_Y(tokenPtr->tkwin))) { Tk_MoveToplevelWindow(tokenPtr->tkwin, x, y); } RaiseToken(tokenPtr); } static Tk_Cursor GetWidgetCursor( Tcl_Interp *interp, Tk_Window tkwin) { const char *cursorName; Tk_Cursor cursor; cursor = None; if (Tcl_VarEval(interp, Tk_PathName(tkwin), " cget -cursor", (char *)NULL) != TCL_OK) { return None; } cursorName = Tcl_GetStringResult(interp); if ((cursorName != NULL) && (cursorName[0] != '\0')) { cursor = Tk_GetCursor(interp, tkwin, Tk_GetUid((char *)cursorName)); } Tcl_ResetResult(interp); return cursor; } static void Bgerror(Source *srcPtr) { if (srcPtr->errorCmdObjPtr != NULL) { Tcl_Obj *objv[2]; objv[0] = srcPtr->errorCmdObjPtr; objv[1] = Tcl_GetObjResult(srcPtr->interp); Tcl_IncrRefCount(objv[0]); Tcl_IncrRefCount(objv[1]); Tcl_EvalObjv(srcPtr->interp, 2, objv, 0); Tcl_DecrRefCount(objv[1]); Tcl_DecrRefCount(objv[0]); } } /* *--------------------------------------------------------------------------- * * UpdateToken -- * * Invoked when the event loop is idle to determine whether or not * the current drag&drop token position is over another drag&drop * target. * *--------------------------------------------------------------------------- */ static void UpdateToken(ClientData clientData) /* widget data */ { Source *srcPtr = clientData; Token *tokenPtr = &srcPtr->token; ChangeToken(tokenPtr, tokenPtr->active); /* * If the source has a site command, then invoke it to * modify the appearance of the token window. Pass any * errors onto the drag&drop error handler. */ if (srcPtr->siteCmd) { char buffer[200]; Tcl_DString dString; int result; SubstDescriptors subs[2]; sprintf_s(buffer, 200, "%d", tokenPtr->active); subs[0].letter = 's'; subs[0].value = buffer; subs[1].letter = 't'; subs[1].value = Tk_PathName(tokenPtr->tkwin); Tcl_DStringInit(&dString); result = Tcl_Eval(srcPtr->interp, ExpandPercents(srcPtr->siteCmd, subs, 2, &dString)); Tcl_DStringFree(&dString); if (result != TCL_OK) { Bgerror(srcPtr); } } } /* *--------------------------------------------------------------------------- * * RejectToken -- * * Draws a rejection mark on the current drag&drop token, and arranges * for the token to be unmapped after a small delay. * *--------------------------------------------------------------------------- */ static void RejectToken(Token *tokenPtr) { int divisor = 6; /* controls size of rejection symbol */ int w, h, lineWidth, x, y, margin; margin = 2 * tokenPtr->borderWidth; w = Tk_Width(tokenPtr->tkwin) - 2 * margin; h = Tk_Height(tokenPtr->tkwin) - 2 * margin; lineWidth = (w < h) ? w / divisor : h / divisor; lineWidth = (lineWidth < 1) ? 1 : lineWidth; w = h = lineWidth * (divisor - 1); x = (Tk_Width(tokenPtr->tkwin) - w) / 2; y = (Tk_Height(tokenPtr->tkwin) - h) / 2; /* * Draw the rejection symbol background (\) on the token window... */ XSetLineAttributes(Tk_Display(tokenPtr->tkwin), tokenPtr->rejectBgGC, lineWidth + 4, LineSolid, CapButt, JoinBevel); XDrawArc(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->rejectBgGC, x, y, w, h, 0, 23040); XDrawLine(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->rejectBgGC, x + lineWidth, y + lineWidth, x + w - lineWidth, y + h - lineWidth); /* * Draw the rejection symbol foreground (\) on the token window... */ XSetLineAttributes(Tk_Display(tokenPtr->tkwin), tokenPtr->rejectFgGC, lineWidth, LineSolid, CapButt, JoinBevel); XDrawArc(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->rejectFgGC, x, y, w, h, 0, 23040); XDrawLine(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->rejectFgGC, x + lineWidth, y + lineWidth, x + w - lineWidth, y + h - lineWidth); /* * Arrange for token window to disappear eventually. */ tokenPtr->timer = Tcl_CreateTimerHandler(1000, (Tcl_TimerProc *) HideToken, tokenPtr); } /* *--------------------------------------------------------------------------- * * ConfigureToken -- * *--------------------------------------------------------------------------- */ static int ConfigureToken( Tcl_Interp *interp, Source *srcPtr, int objc, Tcl_Obj *const *objv) { Token *tokenPtr; tokenPtr = &srcPtr->token; if (Blt_ConfigureWidgetFromObj(interp, srcPtr->tkwin, tokenConfigSpecs, objc, objv, (char *)tokenPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } return ConfigureSource(interp, srcPtr, 0, (Tcl_Obj **)NULL, BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * CreateToken -- * *--------------------------------------------------------------------------- */ static int CreateToken( Tcl_Interp *interp, Source *srcPtr) { XSetWindowAttributes attrs; Tk_Window tkwin; char string[200]; static int nextTokenId = 0; unsigned int mask; Token *tokenPtr = &srcPtr->token; sprintf_s(string, 200, "dd-token%d", ++nextTokenId); /* Create toplevel on parent's screen. */ tkwin = Tk_CreateWindow(interp, srcPtr->tkwin, string, ""); if (tkwin == NULL) { return TCL_ERROR; } Tk_SetClass(tkwin, className); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, TokenEventProc, tokenPtr); attrs.override_redirect = True; attrs.backing_store = WhenMapped; attrs.save_under = True; mask = CWOverrideRedirect | CWSaveUnder | CWBackingStore; Tk_ChangeWindowAttributes(tkwin, mask, &attrs); Tk_SetInternalBorder(tkwin, tokenPtr->borderWidth + 2); tokenPtr->tkwin = tkwin; #ifdef WIN32 { Tk_FakeWin *winPtr = (Tk_FakeWin *) tkwin; winPtr->dummy18 = tokenPtr; } #endif /* WIN32 */ Tk_MakeWindowExist(tkwin); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateSource -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Creates a new record if the widget name is not already * registered. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static Source * CreateSource( DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, /* widget pathname for desired record */ int *newPtr) /* returns non-zero => new record created */ { char *pathName; /* widget pathname for desired record */ Blt_HashEntry *hPtr; Tk_Window tkwin; Source *srcPtr; pathName = Tcl_GetString(objPtr); tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return NULL; } hPtr = Blt_CreateHashEntry(&dataPtr->sourceTable, (char *)tkwin, newPtr); if (!(*newPtr)) { return Blt_GetHashValue(hPtr); } srcPtr = Blt_AssertCalloc(1, sizeof(Source)); srcPtr->tkwin = tkwin; srcPtr->display = Tk_Display(tkwin); srcPtr->interp = interp; srcPtr->token.anchor = TK_ANCHOR_SE; srcPtr->token.relief = TK_RELIEF_RAISED; srcPtr->token.activeRelief = TK_RELIEF_SUNKEN; srcPtr->token.borderWidth = srcPtr->token.activeBW = 3; srcPtr->hashPtr = hPtr; srcPtr->dataPtr = dataPtr; Blt_InitHashTable(&srcPtr->handlerTable, BLT_STRING_KEYS); if (ConfigureSource(interp, srcPtr, 0, (Tcl_Obj **)NULL, 0) != TCL_OK) { DestroySource(srcPtr); return NULL; } Blt_SetHashValue(hPtr, srcPtr); /* * Arrange for the window to unregister itself when it * is destroyed. */ Tk_CreateEventHandler(tkwin, StructureNotifyMask, SourceEventProc, srcPtr); return srcPtr; } /* *--------------------------------------------------------------------------- * * DestroySource -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Destroys the record if found. * *--------------------------------------------------------------------------- */ static void DestroySource(Source *srcPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_CancelIdleCall(UpdateToken, srcPtr); if (srcPtr->token.timer) { Tcl_DeleteTimerHandler(srcPtr->token.timer); } Blt_FreeOptions(configSpecs, (char *)srcPtr, srcPtr->display, 0); if (srcPtr->token.rejectFgGC != NULL) { Tk_FreeGC(srcPtr->display, srcPtr->token.rejectFgGC); } if (srcPtr->token.rejectBgGC != NULL) { Tk_FreeGC(srcPtr->display, srcPtr->token.rejectBgGC); } if (srcPtr->pkgCmdResult) { Blt_Free(srcPtr->pkgCmdResult); } if (srcPtr->rootPtr != NULL) { RemoveWindow(srcPtr->rootPtr); } if (srcPtr->cursor != None) { Tk_FreeCursor(srcPtr->display, srcPtr->cursor); } if (srcPtr->token.cursor != None) { Tk_FreeCursor(srcPtr->display, srcPtr->token.cursor); } Blt_Free(srcPtr->sendTypes); for (hPtr = Blt_FirstHashEntry(&srcPtr->handlerTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { const char *cmd; cmd = Blt_GetHashValue(hPtr); if (cmd != NULL) { Blt_Free(cmd); } } Blt_DeleteHashTable(&srcPtr->handlerTable); if (srcPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&srcPtr->dataPtr->sourceTable, srcPtr->hashPtr); } Blt_Free(srcPtr); } /* *--------------------------------------------------------------------------- * * GetSourceFromObj -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static int GetSourceFromObj( DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, /* widget pathname for desired record */ Source **srcPtrPtr) { Blt_HashEntry *hPtr; Tk_Window tkwin; char *pathName; pathName = Tcl_GetString(objPtr); tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(&dataPtr->sourceTable, (char *)tkwin); if (hPtr == NULL) { Tcl_AppendResult(interp, "window \"", pathName, "\" has not been initialized as a drag&drop source", (char *)NULL); return TCL_ERROR; } *srcPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } static char * ConcatArgs(int objc, Tcl_Obj *const *objv) { char *string; if (objc == 1) { string = Blt_AssertStrdup(Tcl_GetString(objv[0])); } else { Tcl_DString dString; int i; Tcl_DStringInit(&dString); for(i = 0; i < objc; i++) { Tcl_DStringAppendElement(&dString, Tcl_GetString(objv[i])); } string = Blt_AssertStrdup(Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); } return string; } /* *--------------------------------------------------------------------------- * * ConfigureSource -- * * Called to process an (objc,objv) list to configure (or * reconfigure) a drag&drop source widget. * *--------------------------------------------------------------------------- */ static int ConfigureSource( Tcl_Interp *interp, /* current interpreter */ Source *srcPtr, /* drag&drop source widget record */ int objc, /* number of arguments */ Tcl_Obj *const *objv, /* argument strings */ int flags) /* flags controlling interpretation */ { unsigned long gcMask; XGCValues gcValues; GC newGC; Tcl_DString dString; Tcl_CmdInfo cmdInfo; int result; /* * Handle the bulk of the options... */ if (Blt_ConfigureWidgetFromObj(interp, srcPtr->tkwin, configSpecs, objc, objv, (char *)srcPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Check the button binding for valid range (0 or 1-5) */ if ((srcPtr->button < 0) || (srcPtr->button > 5)) { Tcl_AppendResult(interp, "button number must be 1-5, or 0 for no bindings", (char *)NULL); return TCL_ERROR; } /* * Set up the rejection foreground GC for the token window... */ gcValues.foreground = srcPtr->token.rejectFg->pixel; gcValues.subwindow_mode = IncludeInferiors; gcValues.graphics_exposures = False; gcMask = GCForeground | GCSubwindowMode | GCGraphicsExposures; if (srcPtr->token.rejectStipple != None) { gcValues.stipple = srcPtr->token.rejectStipple; gcValues.fill_style = FillStippled; gcMask |= GCForeground | GCStipple | GCFillStyle; } newGC = Tk_GetGC(srcPtr->tkwin, gcMask, &gcValues); if (srcPtr->token.rejectFgGC != NULL) { Tk_FreeGC(srcPtr->display, srcPtr->token.rejectFgGC); } srcPtr->token.rejectFgGC = newGC; /* * Set up the rejection background GC for the token window... */ gcValues.foreground = srcPtr->token.rejectBg->pixel; gcValues.subwindow_mode = IncludeInferiors; gcValues.graphics_exposures = False; gcMask = GCForeground | GCSubwindowMode | GCGraphicsExposures; newGC = Tk_GetGC(srcPtr->tkwin, gcMask, &gcValues); if (srcPtr->token.rejectBgGC != NULL) { Tk_FreeGC(srcPtr->display, srcPtr->token.rejectBgGC); } srcPtr->token.rejectBgGC = newGC; /* * Reset the border width in case it has changed... */ if (srcPtr->token.tkwin) { Tk_SetInternalBorder(srcPtr->token.tkwin, srcPtr->token.borderWidth + 2); } if (!Tcl_GetCommandInfo(interp, "::blt::Drag&DropInit", &cmdInfo)) { static char cmd[] = "source [file join $blt_library dragdrop.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (while loading bindings for blt::drag&drop)"); return TCL_ERROR; } } Tcl_DStringInit(&dString); Blt_DStringAppendElements(&dString, "::blt::Drag&DropInit", Tk_PathName(srcPtr->tkwin), Blt_Itoa(srcPtr->button), (char *)NULL); result = Tcl_Eval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); return result; } /* *--------------------------------------------------------------------------- * * SourceEventProc -- * * Invoked by Tk_HandleEvent whenever a DestroyNotify event is received * on a registered drag&drop source widget. * *--------------------------------------------------------------------------- */ static void SourceEventProc( ClientData clientData, /* drag&drop registration list */ XEvent *eventPtr) /* event description */ { Source *srcPtr = (Source *) clientData; if (eventPtr->type == DestroyNotify) { DestroySource(srcPtr); } } /* *--------------------------------------------------------------------------- * * FindTarget -- * * Looks for a Target record in the hash table for drag&drop * target widgets. Creates a new record if the widget name is * not already registered. Returns a pointer to the desired * record. * *--------------------------------------------------------------------------- */ static Target * FindTarget( DragdropCmdInterpData *dataPtr, Tk_Window tkwin) /* Widget pathname for desired record */ { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&dataPtr->targetTable, (char *)tkwin); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * CreateTarget -- * * Looks for a Target record in the hash table for drag&drop * target widgets. Creates a new record if the widget name is * not already registered. Returns a pointer to the desired * record. * *--------------------------------------------------------------------------- */ static Target * CreateTarget( DragdropCmdInterpData *dataPtr, Tcl_Interp *interp, Tk_Window tkwin) /* Widget pathname for desired record */ { Target *targetPtr; int isNew; targetPtr = Blt_AssertCalloc(1, sizeof(Target)); targetPtr->display = Tk_Display(tkwin); targetPtr->tkwin = tkwin; targetPtr->dataPtr = dataPtr; Blt_InitHashTable(&targetPtr->handlerTable, BLT_STRING_KEYS); targetPtr->hashPtr = Blt_CreateHashEntry(&dataPtr->targetTable, (char *)tkwin, &isNew); Blt_SetHashValue(targetPtr->hashPtr, targetPtr); /* * Arrange for the target to removed if the host window is destroyed. */ Tk_CreateEventHandler(tkwin, StructureNotifyMask, TargetEventProc, targetPtr); /* * If this is a new target, attach a property to identify * window as "drag&drop" target, and arrange for the window * to un-register itself when it is destroyed. */ Tk_MakeWindowExist(targetPtr->tkwin); AddTargetProperty(interp, targetPtr); return targetPtr; } /* *--------------------------------------------------------------------------- * * DestroyTarget -- * *--------------------------------------------------------------------------- */ static void DestroyTarget(DestroyData data) { Target *targetPtr = (Target *)data; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&targetPtr->handlerTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { char *cmd; cmd = Blt_GetHashValue(hPtr); if (cmd != NULL) { Blt_Free(cmd); } } Blt_DeleteHashTable(&targetPtr->handlerTable); if (targetPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&targetPtr->dataPtr->targetTable, targetPtr->hashPtr); } Tk_DeleteEventHandler(targetPtr->tkwin, StructureNotifyMask, TargetEventProc, targetPtr); Blt_Free(targetPtr); } /* *--------------------------------------------------------------------------- * * TargetEventProc -- * * Invoked by Tk_HandleEvent whenever a DestroyNotify event is received * on a registered drag&drop target widget. * *--------------------------------------------------------------------------- */ static void TargetEventProc( ClientData clientData, /* drag&drop registration list */ XEvent *eventPtr) /* event description */ { Target *targetPtr = (Target *) clientData; if (eventPtr->type == DestroyNotify) { #ifdef WIN32 /* * Under Win32 the properties must be removed before the window * can be destroyed. */ RemoveProperty(targetPtr->tkwin); #endif DestroyTarget((DestroyData)targetPtr); } } /* *--------------------------------------------------------------------------- * * DndSend -- * * Invoked after a drop operation to send data to the drop * application. * *--------------------------------------------------------------------------- */ static void DndSend(Source *srcPtr) /* drag&drop source record */ { int status; SubstDescriptors subs[3]; Tcl_DString dString; Blt_HashEntry *hPtr; const char *dataType; const char **targv; char *cmd; /* See if current position is over drop point. */ if (!OverTarget(srcPtr, srcPtr->token.lastX, srcPtr->token.lastY)) { return; } targv = srcPtr->windowPtr->targetInfo; Tcl_DStringInit(&dString); Blt_DStringAppendElements(&dString, "send", targv[INTERP_NAME], dragDropCmd, "location", (char *)NULL); Tcl_DStringAppendElement(&dString, Blt_Itoa(srcPtr->token.lastX)); Tcl_DStringAppendElement(&dString, Blt_Itoa(srcPtr->token.lastY)); status = Tcl_Eval(srcPtr->interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (status != TCL_OK) { goto reject; } if (targv[DATA_TYPE] == NULL) { Blt_HashSearch cursor; hPtr = Blt_FirstHashEntry(&srcPtr->handlerTable, &cursor); dataType = Blt_GetHashKey(&srcPtr->handlerTable, hPtr); } else { hPtr = Blt_FindHashEntry(&srcPtr->handlerTable, targv[DATA_TYPE]); dataType = targv[DATA_TYPE]; } /* Start building the command line here, before we invoke any Tcl * commands. The is because the TCL command may let in another * drag event and change the target property data. */ Tcl_DStringInit(&dString); Blt_DStringAppendElements(&dString, "send", targv[INTERP_NAME], dragDropCmd, "target", targv[TARGET_NAME], "handle", dataType, (char *)NULL); cmd = NULL; if (hPtr != NULL) { cmd = Blt_GetHashValue(hPtr); } if (cmd != NULL) { Tcl_DString cmdString; subs[0].letter = 'i'; subs[0].value = targv[INTERP_NAME]; subs[1].letter = 'w'; subs[1].value = targv[TARGET_NAME]; subs[2].letter = 'v'; subs[2].value = srcPtr->pkgCmdResult; Tcl_DStringInit(&cmdString); status = Tcl_Eval(srcPtr->interp, ExpandPercents(cmd, subs, 3, &cmdString)); Tcl_DStringFree(&cmdString); if (status != TCL_OK) { goto reject; } Tcl_DStringAppendElement(&dString, Tcl_GetStringResult(srcPtr->interp)); } else { Tcl_DStringAppendElement(&dString, srcPtr->pkgCmdResult); } /* * Part 2: Now tell target application to handle the data. */ status = Tcl_Eval(srcPtr->interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (status != TCL_OK) { goto reject; } HideToken(&srcPtr->token); return; reject: /* * Give failure information to user. If an error occurred and an * error proc is defined, then use it to handle the error. */ RejectToken(&srcPtr->token); Bgerror(srcPtr); } /* *--------------------------------------------------------------------------- * * InitRoot -- * * Invoked at the start of a "drag" operation to capture the * positions of all windows on the current root. Queries the * entire window hierarchy and determines the placement of each * window. Queries the "BltDrag&DropTarget" property info where * appropriate. This information is used during the drag * operation to determine when the drag&drop token is over a * valid drag&drop target. * * Results: * Returns the record for the root window, which contains records * for all other windows as children. * *--------------------------------------------------------------------------- */ static void InitRoot(Source *srcPtr) { srcPtr->rootPtr = Blt_AssertCalloc(1, sizeof(AnyWindow)); #ifdef WIN32 srcPtr->rootPtr->nativeWindow = GetDesktopWindow(); #else srcPtr->rootPtr->nativeWindow = DefaultRootWindow(srcPtr->display); #endif srcPtr->windowPtr = NULL; QueryWindow(srcPtr->display, srcPtr->rootPtr); } /* *--------------------------------------------------------------------------- * * FindTopWindow -- * * Searches for the topmost window at a given pair of X-Y coordinates. * * Results: * Returns a pointer to the node representing the window containing * the point. If one can't be found, NULL is returned. * *--------------------------------------------------------------------------- */ static AnyWindow * FindTopWindow( Source *srcPtr, int x, int y) { AnyWindow *rootPtr; Blt_ChainLink link; AnyWindow *windowPtr; WINDOW nativeTokenWindow; rootPtr = srcPtr->rootPtr; if (!rootPtr->initialized) { QueryWindow(srcPtr->display, rootPtr); } if ((x < rootPtr->x1) || (x > rootPtr->x2) || (y < rootPtr->y1) || (y > rootPtr->y2)) { return NULL; /* Point is not over window */ } windowPtr = rootPtr; nativeTokenWindow = (WINDOW)Blt_GetWindowId(srcPtr->token.tkwin); /* * The window list is ordered top to bottom, so stop when we find * the first child that contains the X-Y coordinate. It will be * the topmost window in that hierarchy. If none exists, then we * already have the topmost window. */ descend: for (link = Blt_Chain_FirstLink(rootPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { rootPtr = Blt_Chain_GetValue(link); if (!rootPtr->initialized) { QueryWindow(srcPtr->display, rootPtr); } if (rootPtr->nativeWindow == nativeTokenWindow) { continue; /* Don't examine the token window. */ } if ((x >= rootPtr->x1) && (x <= rootPtr->x2) && (y >= rootPtr->y1) && (y <= rootPtr->y2)) { /* * Remember the last window containing the pointer and * descend into its window hierarchy. We'll look for a * child that also contains the pointer. */ windowPtr = rootPtr; goto descend; } } return windowPtr; } /* *--------------------------------------------------------------------------- * * OverTarget -- * * Checks to see if a compatible drag&drop target exists at the * given position. A target is "compatible" if it is a drag&drop * window, and if it has a handler that is compatible with the * current source window. * * Results: * Returns a pointer to a structure describing the target, or NULL * if no compatible target is found. * *--------------------------------------------------------------------------- */ static int OverTarget( Source *srcPtr, /* drag&drop source window */ int x, int y) /* current drag&drop location * (in virtual coords) */ { int virtX, virtY; int dummy; AnyWindow *newPtr, *oldPtr; const char **argv; int argc; const unsigned char *data; int result; /* * If no window info has been been gathered yet for this target, * then abort this call. This probably means that the token is * moved before it has been properly built. */ if (srcPtr->rootPtr == NULL) { return FALSE; } if (srcPtr->sendTypes == NULL) { return FALSE; /* Send is turned off. */ } /* Adjust current location for virtual root windows. */ Tk_GetVRootGeometry(srcPtr->tkwin, &virtX, &virtY, &dummy, &dummy); x += virtX; y += virtY; oldPtr = srcPtr->windowPtr; srcPtr->windowPtr = NULL; newPtr = FindTopWindow(srcPtr, x, y); if (newPtr == NULL) { return FALSE; /* Not over a window. */ } if ((!srcPtr->selfTarget) && (GetNativeWindow(srcPtr->tkwin) == newPtr->nativeWindow)) { return FALSE; /* If the self-target flag isn't set, * don't allow the source window to * drop onto itself. */ } if (newPtr == oldPtr) { srcPtr->windowPtr = oldPtr; /* No need to collect the target information if we're still * over the same window. */ return (newPtr->targetInfo != NULL); } /* See if this window has a "BltDrag&DropTarget" property. */ data = GetProperty(srcPtr->display, newPtr->nativeWindow); if (data == NULL) { return FALSE; /* No such property on window. */ } result = Tcl_SplitList(srcPtr->interp, (char *)data, &argc, &argv); XFree((char *)data); if (result != TCL_OK) { return FALSE; /* Malformed property list. */ } srcPtr->windowPtr = newPtr; /* Interpreter name, target name, type1, type2, ... */ if (argc > 2) { const char **s; int count; int i; /* * The candidate target has a list of possible types. * Compare this with what types the source is willing to * transmit and compress the list down to just the matching * types. It's up to the target to request the specific type * it wants. */ count = 2; for (i = 2; i < argc; i++) { for (s = srcPtr->sendTypes; *s != NULL; s++) { if (((**s == 'a') && (strcmp(*s, "all") == 0)) || ((**s == argv[i][0]) && (strcmp(*s, argv[i]) == 0))) { argv[count++] = argv[i]; } } } if (count == 2) { Blt_Free(argv); fprintf(stderr, "source/target mismatch: No matching types\n"); return FALSE; /* No matching data type. */ } argv[count] = NULL; } newPtr->targetInfo = argv; return TRUE; } /* *--------------------------------------------------------------------------- * * RemoveWindow -- * *--------------------------------------------------------------------------- */ static void RemoveWindow(AnyWindow *windowPtr) /* window rep to be freed */ { AnyWindow *childPtr; Blt_ChainLink link; /* Throw away leftover slots. */ for (link = Blt_Chain_FirstLink(windowPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { childPtr = Blt_Chain_GetValue(link); RemoveWindow(childPtr); } Blt_Chain_Destroy(windowPtr->chain); if (windowPtr->targetInfo != NULL) { Blt_Free(windowPtr->targetInfo); } Blt_Free(windowPtr); } /* *--------------------------------------------------------------------------- * * QueryWindow -- * * Invoked during "drag" operations. Digs into the root window * hierarchy and caches the resulting information. * If a point coordinate lies within an uninitialized AnyWindow, * this routine is called to query window coordinates and * drag&drop info. If this particular window has any children, * more uninitialized AnyWindow structures are allocated. * Further queries will cause these structures to be initialized * in turn. * *--------------------------------------------------------------------------- */ static void QueryWindow( Display *display, AnyWindow *winPtr) /* window rep to be initialized */ { int visible; if (winPtr->initialized) { return; } /* * Query for the window coordinates. */ visible = GetWindowRegion(display, winPtr->nativeWindow, &winPtr->x1, &winPtr->y1, &winPtr->x2, &winPtr->y2); if (visible) { Blt_ChainLink link; Blt_Chain chain; AnyWindow *childPtr; /* * Collect a list of child windows, sorted in z-order. The * topmost window will be first in the list. */ chain = GetWindowZOrder(display, winPtr->nativeWindow); /* Add and initialize extra slots if needed. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { childPtr = Blt_AssertCalloc(1, sizeof(AnyWindow)); childPtr->initialized = FALSE; childPtr->nativeWindow = (WINDOW)Blt_Chain_GetValue(link); childPtr->parentPtr = winPtr; Blt_Chain_SetValue(link, childPtr); } winPtr->chain = chain; } else { /* If it's not viewable don't bother doing anything else. */ winPtr->x1 = winPtr->y1 = winPtr->x2 = winPtr->y2 = -1; winPtr->chain = NULL; } winPtr->initialized = TRUE; } /* *--------------------------------------------------------------------------- * * AddTargetProperty -- * * Attaches a drag&drop property to the given target window. * This property allows us to recognize the window later as a * valid target. It also stores important information including * the interpreter managing the target and the pathname of the * target window. Usually this routine is called when the target * is first registered or first exposed (so that the X-window * really exists). * *--------------------------------------------------------------------------- */ static void AddTargetProperty( Tcl_Interp *interp, Target *targetPtr) /* drag&drop target window data */ { Tcl_DString dString; Blt_HashEntry *hPtr; Blt_HashSearch cursor; if (targetPtr->tkwin == NULL) { return; } Tcl_DStringInit(&dString); /* * Each target window's dnd property contains * * 1. name of the application (ie. the interpreter's name). * 2. Tk path name of the target window. * 3. List of all the data types that can be handled. If none * are listed, then all can be handled. */ Tcl_DStringAppendElement(&dString, Tk_Name(Tk_MainWindow(interp))); Tcl_DStringAppendElement(&dString, Tk_PathName(targetPtr->tkwin)); for (hPtr = Blt_FirstHashEntry(&targetPtr->handlerTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_DStringAppendElement(&dString, Blt_GetHashKey(&targetPtr->handlerTable, hPtr)); } SetProperty(targetPtr->tkwin, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); } /* *--------------------------------------------------------------------------- * * ExpandPercents -- * * Expands all percent substitutions found in the input "str" * that match specifications in the "subs" list. Any percent * field that is not found in the "subs" list is left alone. * Returns a string that remains valid until the next call to * this routine. * *--------------------------------------------------------------------------- */ static const char * ExpandPercents( const char *string, /* Incoming command string */ SubstDescriptors *subsArr, /* Array of known substitutions */ int nSubs, /* Number of elements in subs array */ Tcl_DString *resultPtr) { const char *chunk, *p; char letter; int i; /* * Scan through the copy of the input string, look for * the next '%' character, and try to make the substitution. * Continue doing this to the end of the string. */ chunk = p = string; while ((p = strchr(p, '%')) != NULL) { /* Copy up to the percent sign. Repair the string afterwards */ Tcl_DStringAppend(resultPtr, chunk, p - chunk); /* Search for a matching substitution rule */ letter = *(p + 1); for (i = 0; i < nSubs; i++) { if (subsArr[i].letter == letter) { break; } } if (i < nSubs) { /* Make the substitution */ Tcl_DStringAppend(resultPtr, subsArr[i].value, -1); } else { /* Copy in the %letter verbatim */ char verbatim[3]; verbatim[0] = '%'; verbatim[1] = letter; verbatim[2] = '\0'; Tcl_DStringAppend(resultPtr, verbatim, -1); } p += 2; /* Skip % + letter */ if (letter == '\0') { p += 1; /* Premature % substitution (end of string) */ } chunk = p; } /* Pick up last chunk if a substition wasn't the last thing in the string */ if (*chunk != '\0') { Tcl_DStringAppend(resultPtr, chunk, -1); } return Tcl_DStringValue(resultPtr); } /*ARGSUSED*/ static int DragOp( ClientData clientData, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; int x, y; Token *tokenPtr; int status; Source *srcPtr; SubstDescriptors subst[2]; int active; const char *result; /* * HANDLE: drag&drop drag <path> <x> <y> */ if ((GetSourceFromObj(dataPtr, interp, objv[2], &srcPtr) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } tokenPtr = &srcPtr->token; tokenPtr->lastX = dataPtr->locX = x; /* Save drag&drop location */ tokenPtr->lastY = dataPtr->locY = y; /* If HideToken() is pending, then do it now! */ if (tokenPtr->timer != 0) { Tcl_DeleteTimerHandler(tokenPtr->timer); HideToken(tokenPtr); } /* * If pkgCmd is in progress, then ignore subsequent calls * until it completes. Only perform drag if pkgCmd * completed successfully and token window is mapped. */ if ((!Tk_IsMapped(tokenPtr->tkwin)) && (!srcPtr->pkgCmdInProgress)) { Tcl_DString dString; /* * No list of send handlers? Then source is disabled. * Abort drag quietly. */ if (srcPtr->sendTypes == NULL) { return TCL_OK; } /* * No token command? Then cannot build token. * Signal error. */ if (srcPtr->pkgCmd == NULL) { Tcl_AppendResult(interp, "missing -packagecmd: ", objv[2], (char *)NULL); return TCL_ERROR; } /* * Execute token command to initialize token window. */ srcPtr->pkgCmdInProgress = TRUE; subst[0].letter = 'W'; subst[0].value = Tk_PathName(srcPtr->tkwin); subst[1].letter = 't'; subst[1].value = Tk_PathName(tokenPtr->tkwin); Tcl_DStringInit(&dString); status = Tcl_Eval(srcPtr->interp, ExpandPercents(srcPtr->pkgCmd, subst, 2, &dString)); Tcl_DStringFree(&dString); srcPtr->pkgCmdInProgress = FALSE; result = Tcl_GetStringResult(interp); /* * Null string from the package command? * Then quietly abort the drag&drop operation. */ if (result[0] == '\0') { return TCL_OK; } /* Save result of token command for send command. */ if (srcPtr->pkgCmdResult != NULL) { Blt_Free(srcPtr->pkgCmdResult); } srcPtr->pkgCmdResult = Blt_AssertStrdup(result); if (status != TCL_OK) { /* * Token building failed. If an error handler is defined, * then signal the error. Otherwise, abort quietly. */ Bgerror(srcPtr); return TCL_OK; } /* Install token cursor. */ if (tokenPtr->cursor != None) { Tk_Cursor cursor; /* Save the old cursor */ cursor = GetWidgetCursor(srcPtr->interp, srcPtr->tkwin); if (srcPtr->cursor != None) { Tk_FreeCursor(srcPtr->display, srcPtr->cursor); } srcPtr->cursor = cursor; /* Temporarily install the token cursor */ Tk_DefineCursor(srcPtr->tkwin, tokenPtr->cursor); } /* * Get ready to drag token window... * 1) Cache info for all windows on root * 2) Map token window to begin drag operation */ if (srcPtr->rootPtr != NULL) { RemoveWindow(srcPtr->rootPtr); } InitRoot(srcPtr); dataPtr->nActive++; /* One more drag&drop window active */ if (Tk_WindowId(tokenPtr->tkwin) == None) { Tk_MakeWindowExist(tokenPtr->tkwin); } if (!Tk_IsMapped(tokenPtr->tkwin)) { Tk_MapWindow(tokenPtr->tkwin); } RaiseToken(tokenPtr); } /* Arrange to update status of token window. */ Tcl_CancelIdleCall(UpdateToken, srcPtr); active = OverTarget(srcPtr, x, y); if (tokenPtr->active != active) { tokenPtr->active = active; Tcl_DoWhenIdle(UpdateToken, srcPtr); } MoveToken(srcPtr, tokenPtr); /* Move token window to current drag point. */ return TCL_OK; } /* * HANDLE: drag&drop drop <path> <x> <y> */ /*ARGSUSED*/ static int DropOp( ClientData clientData, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; Source *srcPtr; Token *tokenPtr; int x, y; if ((GetSourceFromObj(dataPtr, interp, objv[2], &srcPtr) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } tokenPtr = &srcPtr->token; tokenPtr->lastX = dataPtr->locX = x; /* Save drag&drop location */ tokenPtr->lastY = dataPtr->locY = y; /* Put the cursor back to its usual state. */ if (srcPtr->cursor == None) { Tk_UndefineCursor(srcPtr->tkwin); } else { Tk_DefineCursor(srcPtr->tkwin, srcPtr->cursor); } Tcl_CancelIdleCall(UpdateToken, srcPtr); /* * Make sure that token window was not dropped before it * was either mapped or packed with info. */ if ((Tk_IsMapped(tokenPtr->tkwin)) && (!srcPtr->pkgCmdInProgress)) { int active; active = OverTarget(srcPtr, tokenPtr->lastX, tokenPtr->lastY); if (tokenPtr->active != active) { tokenPtr->active = active; UpdateToken(srcPtr); } if (srcPtr->sendTypes != NULL) { if (tokenPtr->active) { DndSend(srcPtr); } else { HideToken(tokenPtr); } } dataPtr->nActive--; /* One less active token window. */ } return TCL_OK; } /* * HANDLE: drag&drop active */ /*ARGSUSED*/ static int ActiveOp( ClientData clientData, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (dataPtr->nActive > 0)); return TCL_OK; } /* * HANDLE: drag&drop location ?<x> <y>? */ static int LocationOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; Tcl_Obj *listObjPtr; if ((objc != 2) && (objc != 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " location ?x y?\"", (char *)NULL); return TCL_ERROR; } if (objc == 4) { int x, y; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } dataPtr->locX = x; dataPtr->locY = y; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(dataPtr->locX)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(dataPtr->locY)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* * HANDLE: drag&drop token <pathName> */ static int TokenOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; Source *srcPtr; if (GetSourceFromObj(dataPtr, interp, objv[2], &srcPtr) != TCL_OK) { return TCL_ERROR; } if ((objc > 3) && (ConfigureToken(interp, srcPtr, objc - 3, objv + 3) != TCL_OK)) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(srcPtr->token.tkwin), -1); return TCL_OK; } static int HandlerOpOp(Source *srcPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; const char *cmd; int isNew; /* * HANDLE: drag&drop source <pathName> handler \ * ?<data>? ?<scmd>...? */ if (objc == 4) { /* Show source handler data types */ for (hPtr = Blt_FirstHashEntry(&srcPtr->handlerTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_AppendElement(interp, Blt_GetHashKey(&srcPtr->handlerTable, hPtr)); } return TCL_OK; } hPtr = Blt_CreateHashEntry(&srcPtr->handlerTable, Tcl_GetString(objv[4]), &isNew); /* * HANDLE: drag&drop source <pathName> handler <data> * * Create the new <data> type if it doesn't already * exist, and return the code associated with it. */ if (objc == 5) { cmd = Blt_GetHashValue(hPtr); if (cmd == NULL) { cmd = ""; } Tcl_SetStringObj(Tcl_GetObjResult(interp), cmd, -1); return TCL_OK; } /* * HANDLE: drag&drop source <pathName> handler \ * <data> <cmd> ?<arg>...? * * Create the new <data> type and set its command */ cmd = ConcatArgs(objc - 5, objv + 5); Blt_SetHashValue(hPtr, cmd); return TCL_OK; } /* * HANDLE: drag&drop source * drag&drop source <pathName> ?options...? * drag&drop source <pathName> handler ?<data>? ?<scmd> <arg>...? */ static int SourceOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; Source *srcPtr; int isNew; Token *tokenPtr; if (objc == 2) { Blt_HashSearch cursor; Blt_HashEntry *hPtr; Tk_Window tkwin; for (hPtr = Blt_FirstHashEntry(&dataPtr->sourceTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { tkwin = (Tk_Window)Blt_GetHashKey(&dataPtr->sourceTable, hPtr); Tcl_AppendElement(interp, Tk_PathName(tkwin)); } return TCL_OK; } /* * Find or create source info... */ srcPtr = CreateSource(dataPtr, interp, objv[2], &isNew); if (srcPtr == NULL) { return TCL_ERROR; } tokenPtr = &srcPtr->token; if (objc > 3) { char c; int length; int status; char *string; /* * HANDLE: drag&drop source <pathName> ?options...? */ string = Tcl_GetStringFromObj(objv[3], &length); c = string[0]; if (c == '-') { if (objc == 3) { status = Blt_ConfigureInfoFromObj(interp, tokenPtr->tkwin, configSpecs, (char *)srcPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { status = Blt_ConfigureInfoFromObj(interp, tokenPtr->tkwin, configSpecs, (char *)srcPtr, objv[3], 0); } else { status = ConfigureSource(interp, srcPtr, objc - 3, objv + 3, BLT_CONFIG_OBJV_ONLY); } if (status != TCL_OK) { return TCL_ERROR; } } else if ((c == 'h') && strncmp(string, "handler", length) == 0) { return HandlerOpOp(srcPtr, interp, objc, objv); } else { Tcl_AppendResult(interp, "bad operation \"", string, "\": must be \"handler\" or a configuration option", (char *)NULL); return TCL_ERROR; } } if (isNew) { /* * Create the window for the drag&drop token... */ if (CreateToken(interp, srcPtr) != TCL_OK) { DestroySource(srcPtr); return TCL_ERROR; } } return TCL_OK; } /* * HANDLE: drag&drop target ?<pathName>? ?handling info...? */ static int TargetOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DragdropCmdInterpData *dataPtr = clientData; SubstDescriptors subst[2]; Tk_Window tkwin; Blt_HashEntry *hPtr; Target *targetPtr; int isNew; char *string; if (objc == 2) { Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->targetTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { tkwin = (Tk_Window)Blt_GetHashKey(&dataPtr->targetTable, hPtr); Tcl_AppendElement(interp, Tk_PathName(tkwin)); } return TCL_OK; } string = Tcl_GetString(objv[2]); tkwin = Tk_NameToWindow(interp, string, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } targetPtr = FindTarget(dataPtr, tkwin); if (targetPtr == NULL) { targetPtr = CreateTarget(dataPtr, interp, tkwin); } if (targetPtr == NULL) { return TCL_ERROR; } if (objc >= 4) { string = Tcl_GetString(objv[3]); if (strcmp(string, "handler") == 0) { /* * HANDLE: drag&drop target <pathName> handler drag&drop * target <pathName> handler ?<data> <cmd> <arg>...? */ if (objc == 4) { Blt_HashSearch cursor; for (hPtr =Blt_FirstHashEntry(&targetPtr->handlerTable,&cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_AppendElement(interp, Blt_GetHashKey(&targetPtr->handlerTable, hPtr)); } return TCL_OK; } else if (objc >= 6) { char *cmd; /* * Process handler definition */ hPtr = Blt_CreateHashEntry(&targetPtr->handlerTable, Tcl_GetString(objv[4]), &isNew); cmd = ConcatArgs(objc - 5, objv + 5); if (hPtr != NULL) { const char *oldCmd; oldCmd = Blt_GetHashValue(hPtr); if (oldCmd != NULL) { Blt_Free(oldCmd); } } Blt_SetHashValue(hPtr, cmd); /* * Update the target property on the window. */ AddTargetProperty(interp, targetPtr); return TCL_OK; } Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ", Tcl_GetString(objv[2]), " ", Tcl_GetString(objv[3]), " data command ?arg arg...?", (char *)NULL); return TCL_ERROR; } else if (strcmp(string, "handle") == 0) { /* * HANDLE: drag&drop target <pathName> handle <data> ?<value>? */ Tcl_DString dString; int result; char *cmd; if (objc < 5 || objc > 6) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ", Tcl_GetString(objv[2]), " handle data ?value?", (char *)NULL); return TCL_ERROR; } hPtr = Blt_FindHashEntry(&targetPtr->handlerTable, Tcl_GetString(objv[4])); if (hPtr == NULL) { Tcl_AppendResult(interp, "target can't handle datatype: ", Tcl_GetString(objv[4]), (char *)NULL); return TCL_ERROR; /* no handler found */ } cmd = Blt_GetHashValue(hPtr); if (cmd != NULL) { subst[0].letter = 'W'; subst[0].value = Tk_PathName(targetPtr->tkwin); subst[1].letter = 'v'; if (objc > 5) { subst[1].value = Tcl_GetString(objv[5]); } else { subst[1].value = ""; } Tcl_DStringInit(&dString); result = Tcl_Eval(interp, ExpandPercents(cmd, subst, 2, &dString)); Tcl_DStringFree(&dString); return result; } return TCL_OK; } } Tcl_AppendResult(interp, "usage: ", Tcl_GetString(objv[0]), " target ", Tcl_GetString(objv[2]), " handler ?data command arg arg...?\n or: ", Tcl_GetString(objv[0]), " target ", Tcl_GetString(objv[2]), " handle <data>", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DragDropCmd -- * * Invoked by TCL whenever the user issues a drag&drop command. * Handles the following syntax: * * drag&drop source * drag&drop source <pathName> ?options...? * drag&drop source <pathName> handler ?<dataType>? ?<cmd> <arg>...? * * drag&drop target * drag&drop target <pathName> handler ?<dataType> <cmd> <arg>...? * drag&drop target <pathName> handle <dataType> ?<value>? * * drag&drop token <pathName> * drag&drop drag <pathName> <x> <y> * drag&drop drop <pathName> <x> <y> * * drag&drop active * drag&drop location ?<x> <y>? * *--------------------------------------------------------------------------- */ static Blt_OpSpec dndOps[] = { {"active", 1, ActiveOp, 2, 2, "",}, {"drag", 2, DragOp, 5, 5, "pathname x y",}, {"drop", 2, DropOp, 5, 5, "pathname x y",}, {"location", 1, LocationOp, 2, 4, "?x y?",}, {"source", 1, SourceOp, 2, 0, "?pathname? ?options...?",}, {"target", 2, TargetOp, 2, 0, "?pathname? ?options...?",}, {"token", 2, TokenOp, 2, 0, "?option value?...",}, }; static int nDndOps = sizeof(dndOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int DragDropCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* # of arguments */ Tcl_Obj *const *objv) /* Argument strings */ { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nDndOps, dndOps, BLT_OP_ARG1, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * Blt_DragDropCmdInitProc -- * * Adds the drag&drop command to the given interpreter. Should * be invoked to properly install the command whenever a new * interpreter is created. * *--------------------------------------------------------------------------- */ int Blt_DragDropCmdInitProc(Tcl_Interp *interp) /* interpreter to be updated */ { static Blt_InitCmdSpec cmdSpec = { "drag&drop", DragDropCmd, }; cmdSpec.clientData = GetDragdropCmdInterpData(interp); #ifndef WIN32 if (!initialized) { dndAtom = XInternAtom(Tk_Display(Tk_MainWindow(interp)), propName, False); initialized = TRUE; } #endif return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_DRAGDROP */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictPng.c������������������������������������������������������������������0000644�0001750�0001750�00000050174�11462120062�015246� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictPng.c -- * * This module implements PNG file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #ifdef HAVE_LIBPNG #include <tcl.h> #include <bltSwitch.h> #include <bltAlloc.h> #include <bltAssert.h> #include <bltDBuffer.h> #include <bltHash.h> #include "bltPicture.h" #include "bltPictFmts.h" #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #define TRUE 1 #define FALSE 0 typedef struct _Blt_Picture Picture; #include <png.h> typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; char **comments; /* Comment pairs */ int index; } PngExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; } PngImportSwitches; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PngExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PngExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_LIST, "-comments", "{key string...}", Blt_Offset(PngExportSwitches, comments), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PngExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PngImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PngImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; typedef struct { Tcl_DString errors; Tcl_DString warnings; int nErrors, nWarnings; } PngMessage; DLLEXPORT extern Tcl_AppInitProc Blt_PicturePngInit; extern const char *Blt_Itoa(int); static void PngError(png_struct *pngPtr, const char *mesg) { PngMessage *mesgPtr; mesgPtr = png_get_error_ptr(pngPtr); Tcl_DStringAppend(&mesgPtr->errors, mesg, -1); mesgPtr->nErrors++; } static void PngWarning(png_structp png, const char *mesg) { PngMessage *mesgPtr; mesgPtr = png_get_error_ptr(png); Tcl_DStringAppend(&mesgPtr->warnings, mesg, -1); mesgPtr->nWarnings++; } static void PngReadFromBuffer(png_structp png, png_byte *out, png_size_t nWanted) { Blt_DBuffer dbuffer; dbuffer = png_get_io_ptr(png); if (Blt_DBuffer_BytesLeft(dbuffer) < nWanted) { nWanted = Blt_DBuffer_BytesLeft(dbuffer); } if (nWanted > 0) { memcpy(out, Blt_DBuffer_Pointer(dbuffer), nWanted); Blt_DBuffer_IncrCursor(dbuffer, nWanted); } } static void PngWriteToBuffer( png_struct *pngPtr, png_byte *out, png_size_t nBytes) { Blt_DBuffer dbuffer; dbuffer = png_get_io_ptr(pngPtr); if (!Blt_DBuffer_AppendData(dbuffer, out, nBytes)) { return; } } static void PngFlush(png_struct *pngPtr) { /* Do nothing */ } #ifdef PNG_TEXT_SUPPORTED static void PngAddText(Tcl_Interp *interp, png_struct *pngPtr, png_info *infoPtr, char **comments) { png_text *text, *textPtr; char **p, **pend; int count; count = 0; for (p = comments; *p != NULL; p++) { count++; } if (count == 0) { return; } text = Blt_AssertMalloc(sizeof(png_text) * count); textPtr = text; for (p = comments, pend = p + count; p < pend; p += 2) { textPtr->compression = PNG_TEXT_COMPRESSION_NONE; textPtr->key = *p; if (*(p+1) == NULL) { continue; } textPtr->text = *(p+1); textPtr++; } if (count > 0) { png_set_text(pngPtr, infoPtr, text, textPtr - text); } Blt_Free(text); } #endif /* PNG_TEXT_SUPPORTED */ /* *--------------------------------------------------------------------------- * * IsPng -- * * Attempts to parse a PNG file header. * * Results: * Returns 1 is the header is PNG and 0 otherwise. Note that only the * signature is compared and the validity of the image contents is not * checked here. That's done in Blt_PngToPicture. * *--------------------------------------------------------------------------- */ static int IsPng(Blt_DBuffer dbuffer) { #define PNG_BYTES_TO_CHECK 4 Blt_DBuffer_ResetCursor(dbuffer); if (Blt_DBuffer_Length(dbuffer) > PNG_BYTES_TO_CHECK) { unsigned char *bp; int bool; bp = Blt_DBuffer_Pointer(dbuffer); bool = (png_sig_cmp(bp, (png_size_t)0, PNG_BYTES_TO_CHECK) == 0); return bool; } return FALSE; } /* *--------------------------------------------------------------------------- * * PngToPicture -- * * Reads a PNG file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such as the designated * file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain PngToPicture(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PngImportSwitches *switchesPtr) { Picture *destPtr; PngMessage message; int transform; png_infop info; png_structp png; unsigned int bitDepth, colorType; unsigned int interlace, filter, nChannels; unsigned int width, height; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); message.nErrors = message.nWarnings = 0; Tcl_DStringAppend(&message.errors, "error reading \"", -1); Tcl_DStringAppend(&message.errors, fileName, -1); Tcl_DStringAppend(&message.errors, "\": ", -1); png = png_create_read_struct(PNG_LIBPNG_VER_STRING, &message, PngError, PngWarning); if (png == NULL) { return NULL; } destPtr = NULL; /* Mark to indicate failure. */ info = png_create_info_struct(png); if (info == NULL) { goto bad; } if (setjmp(png->jmpbuf)) { goto bad; } png_set_read_fn(png, dbuffer, PngReadFromBuffer); transform = (PNG_TRANSFORM_EXPAND | /* Expand 1,2 and 4 bit to 8 bits. */ PNG_TRANSFORM_STRIP_16); /* Convert 16-bit components to 8. */ png_read_png(png, info, transform, (void *)NULL); bitDepth = png_get_bit_depth(png, info); colorType = png_get_color_type(png, info); filter = png_get_filter_type(png, info); height = png_get_image_height(png, info); interlace = png_get_interlace_type(png, info); nChannels = png_get_channels(png, info); width = png_get_image_width(png, info); #ifdef notdef fprintf(stderr, "%s: %dx%d, bit_depth=%d, channels=%d, interlace=%d\n", fileName, width, height, bitDepth, nChannels, interlace); fprintf(stderr, "colortype= %s %s %s \n", (colorType & 1) ? "palette" : "", (colorType & 2) ? "color" : "", (colorType & 4) ? "alpha" : ""); #endif destPtr = Blt_CreatePicture(width, height); if (colorType & PNG_COLOR_MASK_ALPHA) { assert((nChannels == 4) || (nChannels == 2)); destPtr->flags |= BLT_PIC_BLEND; } if ((nChannels == 4) || (nChannels == 3)) { destPtr->flags |= BLT_PIC_COLOR; } { unsigned int y; Blt_Pixel *destRowPtr; png_byte **row_pointers; destRowPtr = destPtr->bits; row_pointers = png_get_rows(png, info); switch (nChannels) { case 4: /* 1 red, 1 green, 1 blue, 1 alpha */ for (y = 0; y < height; y++) { Blt_Pixel *dp; png_byte *sp; unsigned int x; dp = destRowPtr; sp = row_pointers[y]; for (x = 0; x < width; x++) { dp->Red = sp[0]; dp->Green = sp[1]; dp->Blue = sp[2]; dp->Alpha = sp[3]; dp++, sp += 4; } destRowPtr += destPtr->pixelsPerRow; } break; case 3: /* 1 red, 1 green, 1 blue */ for (y = 0; y < height; y++) { Blt_Pixel *dp; unsigned char *sp; unsigned int x; dp = destRowPtr; sp = row_pointers[y]; for (x = 0; x < width; x++) { dp->Red = sp[0]; dp->Green = sp[1]; dp->Blue = sp[2]; dp->Alpha = ALPHA_OPAQUE; dp++, sp += 3; } destRowPtr += destPtr->pixelsPerRow; } break; case 2: /* 1 greyscale, 1 alpha */ for (y = 0; y < height; y++) { Blt_Pixel *dp; unsigned char *sp; unsigned int x; dp = destRowPtr; sp = row_pointers[y]; for (x = 0; x < width; x++) { dp->Red = dp->Green = dp->Blue = sp[0]; dp->Alpha = sp[1]; dp++, sp += 2; } destRowPtr += destPtr->pixelsPerRow; } break; case 1: /* 1 greyscale */ for (y = 0; y < height; y++) { Blt_Pixel *dp; unsigned char *sp; unsigned int x; dp = destRowPtr; sp = row_pointers[y]; for (x = 0; x < width; x++) { dp->Red = dp->Green = dp->Blue = *sp++; dp->Alpha = ALPHA_OPAQUE; dp++; } destRowPtr += destPtr->pixelsPerRow; } break; } } bad: png_destroy_read_struct(&png, &info, (png_infop *)NULL); if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "PNG_READ_WARNINGS", Tcl_DStringValue(&message.errors), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); if (message.nErrors > 0) { Tcl_DStringResult(interp, &message.errors); } Tcl_DStringFree(&message.errors); if (destPtr != NULL) { Blt_Chain chain; chain = Blt_Chain_Create(); Blt_Chain_Append(chain, destPtr); return chain; } return NULL; } /* *--------------------------------------------------------------------------- * * PictureToPng -- * * Writes a PNG format image to the provided data buffer. * * Results: * A standard TCL result. If an error occured, TCL_ERROR is returned and * an error message will be place in the interpreter result. Otherwise, * the data buffer will contain the binary output of the image. * * Side Effects: * Memory is allocated for the data buffer. * *--------------------------------------------------------------------------- */ static int PictureToPng(Tcl_Interp *interp, Blt_Picture picture, Blt_DBuffer dbuffer, PngExportSwitches *switchesPtr) { PngMessage message; int nColors; png_infop info; png_structp png; unsigned int colorType, nChannels, bitsPerPixel; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); message.nErrors = message.nWarnings = 0; Tcl_DStringAppend(&message.errors, "error writing PNG output: ", -1); png = png_create_write_struct(PNG_LIBPNG_VER_STRING, &message, PngError, PngWarning); if (png == NULL) { return TCL_ERROR; } info = png_create_info_struct(png); if (info == NULL) { png_destroy_write_struct(&png, (png_infop *)NULL); return TCL_ERROR; } if (setjmp(png->jmpbuf)) { goto bad; } png_set_write_fn(png, (void *)dbuffer, PngWriteToBuffer, PngFlush); png_set_compression_level(png, Z_BEST_COMPRESSION); nColors = Blt_QueryColors(picture, (Blt_HashTable *)NULL); if (Blt_PictureIsColor(picture)) { nChannels = 3; colorType = PNG_COLOR_TYPE_RGB; } else { nChannels = 1; colorType = PNG_COLOR_TYPE_GRAY; } if (!Blt_PictureIsOpaque(picture)) { nChannels++; colorType |= PNG_COLOR_MASK_ALPHA; } bitsPerPixel = 8; png_set_IHDR(png, info, Blt_PictureWidth(picture), /* Width */ Blt_PictureHeight(picture), /* Height */ bitsPerPixel, /* Bits per pixel. */ colorType, /* Color type: RGB or GRAY */ PNG_INTERLACE_NONE, /* Interlace */ PNG_COMPRESSION_TYPE_DEFAULT, /* Compression */ PNG_FILTER_TYPE_DEFAULT); /* Filter */ #ifdef PNG_TEXT_SUPPORTED if (switchesPtr->comments != NULL) { PngAddText(interp, png, info, switchesPtr->comments); } #endif png_write_info(png, info); png_set_packing(png); { Picture *srcPtr; Blt_Pixel *srcRowPtr; int bytesPerRow; int y; unsigned char **rowArray; unsigned char *destBuffer, *destRowPtr; srcPtr = picture; bytesPerRow = nChannels * srcPtr->width; destBuffer = Blt_Malloc(bytesPerRow * srcPtr->height); if (destBuffer == NULL) { goto bad; } rowArray = Blt_Malloc(sizeof(unsigned char *) * srcPtr->height); if (rowArray == NULL) { Blt_Free(destBuffer); goto bad; } destRowPtr = destBuffer; srcRowPtr = srcPtr->bits; switch (nChannels) { case 4: /* RGBA */ for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp<send; sp++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp[3] = sp->Alpha; dp += 4; } rowArray[y] = destRowPtr; destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } break; case 3: /* RGB, 100% opaque image. */ for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp<send; sp++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp += 3; } rowArray[y] = destRowPtr; destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } break; case 2: /* Greyscale with alpha component. */ for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp<send; sp++) { dp[0] = sp->Red; dp[1] = sp->Alpha; dp += 2; } rowArray[y] = destRowPtr; destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } break; case 1: /* Greyscale, 100% opaque image. */ for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp<send; sp++) { *dp++ = sp->Red; } rowArray[y] = destRowPtr; destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } break; } png_write_image(png, rowArray); png_write_end(png, NULL); Blt_Free(destBuffer); Blt_Free(rowArray); } bad: png_destroy_write_struct(&png, &info); if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "PNG_WRITE_WARNINGS", Tcl_DStringValue(&message.errors), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); if (message.nErrors > 0) { Tcl_DStringResult(interp, &message.errors); return TCL_ERROR; } Tcl_DStringFree(&message.errors); return TCL_OK; } static Blt_Chain ReadPng(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { PngImportSwitches switches; memset(&switches, 0, sizeof(switches)); return PngToPicture(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WritePng(Tcl_Interp *interp, Blt_Picture picture) { Blt_DBuffer dbuffer; PngExportSwitches switches; Tcl_Obj *objPtr; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); objPtr = NULL; dbuffer = Blt_DBuffer_Create(); if (PictureToPng(interp, picture, dbuffer, &switches) == TCL_OK) { char *bytes; bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } } Blt_DBuffer_Destroy(dbuffer); return objPtr; } static Blt_Chain ImportPng(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer dbuffer; PngImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_SaveFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = PngToPicture(interp, string, dbuffer, &switches); error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportPng(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { PngExportSwitches switches; Blt_DBuffer dbuffer; int result; Blt_Picture picture; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } dbuffer = Blt_DBuffer_Create(); result = PictureToPng(interp, picture, dbuffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } /* Write the PNG data to file or convert it to a base64 string. */ if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; result = TCL_ERROR; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); result = TCL_OK; } } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PicturePngInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_png", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "png", /* Name of format. */ IsPng, /* Format discovery procedure. */ ReadPng, /* Read format procedure. */ WritePng, /* Write format procedure. */ ImportPng, /* Import format procedure. */ ExportPng); /* Export format procedure. */ } #endif /* HAVE_LIBPNG */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWait.h���������������������������������������������������������������������0000644�0001750�0001750�00000014150�11462120063�014606� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltWait.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_WAIT_H #define _BLT_WAIT_H #ifdef HAVE_WAITFLAGS_H # include <waitflags.h> #endif #ifdef HAVE_SYS_WAIT_H # include <sys/wait.h> #endif #ifdef HAVE_ERRNO_H # include <errno.h> #endif /* * Define EINPROGRESS in terms of WSAEINPROGRESS. */ #ifndef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS #endif /* * If ENOTSUP is not defined, define it to a value that will never occur. */ #ifndef ENOTSUP #define ENOTSUP -1030507 #endif /* * The following defines redefine the Windows Socket errors as * BSD errors so Tcl_PosixError can do the right thing. */ #ifndef EWOULDBLOCK #define EWOULDBLOCK EAGAIN #endif #ifndef EALREADY #define EALREADY 149 /* operation already in progress */ #endif #ifndef ENOTSOCK #define ENOTSOCK 95 /* Socket operation on non-socket */ #endif #ifndef EDESTADDRREQ #define EDESTADDRREQ 96 /* Destination address required */ #endif #ifndef EMSGSIZE #define EMSGSIZE 97 /* Message too long */ #endif #ifndef EPROTOTYPE #define EPROTOTYPE 98 /* Protocol wrong type for socket */ #endif #ifndef ENOPROTOOPT #define ENOPROTOOPT 99 /* Protocol not available */ #endif #ifndef EPROTONOSUPPORT #define EPROTONOSUPPORT 120 /* Protocol not supported */ #endif #ifndef ESOCKTNOSUPPORT #define ESOCKTNOSUPPORT 121 /* Socket type not supported */ #endif #ifndef EOPNOTSUPP #define EOPNOTSUPP 122 /* Operation not supported on socket */ #endif #ifndef EPFNOSUPPORT #define EPFNOSUPPORT 123 /* Protocol family not supported */ #endif #ifndef EAFNOSUPPORT #define EAFNOSUPPORT 124 /* Address family not supported */ #endif #ifndef EADDRINUSE #define EADDRINUSE 125 /* Address already in use */ #endif #ifndef EADDRNOTAVAIL #define EADDRNOTAVAIL 126 /* Can't assign requested address */ #endif #ifndef ENETDOWN #define ENETDOWN 127 /* Network is down */ #endif #ifndef ENETUNREACH #define ENETUNREACH 128 /* Network is unreachable */ #endif #ifndef ENETRESET #define ENETRESET 129 /* Network dropped connection on reset */ #endif #ifndef ECONNABORTED #define ECONNABORTED 130 /* Software caused connection abort */ #endif #ifndef ECONNRESET #define ECONNRESET 131 /* Connection reset by peer */ #endif #ifndef ENOBUFS #define ENOBUFS 132 /* No buffer space available */ #endif #ifndef EISCONN #define EISCONN 133 /* Socket is already connected */ #endif #ifndef ENOTCONN #define ENOTCONN 134 /* Socket is not connected */ #endif #ifndef ESHUTDOWN #define ESHUTDOWN 143 /* Can't send after socket shutdown */ #endif #ifndef ETOOMANYREFS #define ETOOMANYREFS 144 /* Too many references: can't splice */ #endif #ifndef ETIMEDOUT #define ETIMEDOUT 145 /* Connection timed out */ #endif #ifndef ECONNREFUSED #define ECONNREFUSED 146 /* Connection refused */ #endif #ifndef ELOOP #define ELOOP 90 /* Symbolic link loop */ #endif #ifndef EHOSTDOWN #define EHOSTDOWN 147 /* Host is down */ #endif #ifndef EHOSTUNREACH #define EHOSTUNREACH 148 /* No route to host */ #endif #ifndef ENOTEMPTY #define ENOTEMPTY 93 /* directory not empty */ #endif #ifndef EUSERS #define EUSERS 94 /* Too many users (for UFS) */ #endif #ifndef EDQUOT #define EDQUOT 49 /* Disc quota exceeded */ #endif #ifndef ESTALE #define ESTALE 151 /* Stale NFS file handle */ #endif #ifndef EREMOTE #define EREMOTE 66 /* The object is remote */ #endif #ifndef WIFEXITED # define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0) #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #ifndef WIFSIGNALED # define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff))) #endif #ifndef WTERMSIG # define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f) #endif #ifndef WIFSTOPPED # define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177) #endif #ifndef WSTOPSIG # define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif /* * Define constants for waitpid() system call if they aren't defined * by a system header file. */ #ifndef WNOHANG # define WNOHANG 1 #endif #ifndef WUNTRACED # define WUNTRACED 2 #endif /* * The type of the status returned by wait varies from UNIX system * to UNIX system. The macro below defines it: */ #ifdef AIX # define WAIT_STATUS_TYPE pid_t #else #ifdef HAVE_UNION_WAIT # define WAIT_STATUS_TYPE union wait #else # define WAIT_STATUS_TYPE int #endif #endif /* * Supply definitions for macros to query wait status, if not already * defined in header files above. */ #ifndef WIFEXITED # define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0) #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #ifndef WIFSIGNALED # define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff))) #endif #ifndef WTERMSIG # define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f) #endif #ifndef WIFSTOPPED # define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177) #endif #ifndef WSTOPSIG # define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #endif /* _BLT_WAIT_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWatch.c��������������������������������������������������������������������0000644�0001750�0001750�00000056353�11462120063�014756� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWatch.c -- * * This module implements watch procedure callbacks for TCL commands * and procedures. * * Copyright 1994-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include <bltHash.h> #include "bltSwitch.h" #define UNKNOWN_RETURN_CODE 5 static const char *codeNames[] = { "OK", "ERROR", "RETURN", "BREAK", "CONTINUE" }; #define WATCH_THREAD_KEY "BLT Watch Command Data" #define WATCH_MAX_LEVEL 10000 /* Maximum depth of TCL traces. */ enum WatchStates { WATCH_STATE_DONT_CARE = -1, /* Select watch regardless of state */ WATCH_STATE_IDLE = 0, /* */ WATCH_STATE_ACTIVE = 1 }; typedef struct { Tcl_Interp *interp; /* Interpreter associated with the watch */ char *name; /* Watch identifier */ /* User-configurable fields */ enum WatchStates state; /* Current state of watch: either * WATCH_STATE_IDLE or WATCH_STATE_ACTIVE */ int maxLevel; /* Maximum depth of tracing allowed */ char **preCmd; /* Procedure to be invoked before the * command is executed (but after * substitutions have occurred). */ char **postCmd; /* Procedure to be invoked after the command * is executed. */ Tcl_Trace trace; /* Trace handler which activates "pre" * command procedures */ Tcl_AsyncHandler asyncHandle; /* Async handler which triggers the * "post" command procedure (if one * exists) */ int active; /* Indicates if a trace is currently * active. This prevents recursive * tracing of the "pre" and "post" * procedures. */ int level; /* Current level of traced command. */ char *cmdPtr; /* Command string before substitutions. * Points to a original command buffer. */ char *args; /* TCL list of the command after * substitutions. List is malloc-ed by * Tcl_Merge. Must be freed in handler * procs */ } Watch; typedef struct { Blt_HashTable watchTable; /* Hash table of trees keyed by address. */ Tcl_Interp *interp; } WatchCmdInterpData; static Blt_SwitchSpec switchSpecs[] = { {BLT_SWITCH_LIST, "-precmd", "command", Blt_Offset(Watch, preCmd), 0}, {BLT_SWITCH_LIST, "-postcmd", "command", Blt_Offset(Watch, postCmd), 0}, {BLT_SWITCH_BOOLEAN, "-active", "bool", Blt_Offset(Watch, state), 0}, {BLT_SWITCH_INT_NNEG, "-maxlevel", "number", Blt_Offset(Watch, maxLevel), 0}, {BLT_SWITCH_END} }; static Tcl_CmdTraceProc PreCmdProc; static Tcl_AsyncProc PostCmdProc; static Tcl_ObjCmdProc WatchCmd; /* *--------------------------------------------------------------------------- * * TreeInterpDeleteProc -- * * This is called when the interpreter hosting the "tree" command * is deleted. * * Results: * None. * * Side effects: * Removes the hash table managing all tree names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void WatchInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { WatchCmdInterpData *dataPtr = clientData; /* All tree instances should already have been destroyed when * their respective TCL commands were deleted. */ Blt_DeleteHashTable(&dataPtr->watchTable); Tcl_DeleteAssocData(interp, WATCH_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * GetWatchCmdInterpData -- * *--------------------------------------------------------------------------- */ static WatchCmdInterpData * GetWatchCmdInterpData(Tcl_Interp *interp) { WatchCmdInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (WatchCmdInterpData *) Tcl_GetAssocData(interp, WATCH_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(WatchCmdInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, WATCH_THREAD_KEY, WatchInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->watchTable, BLT_ONE_WORD_KEYS); } return dataPtr; } /* *--------------------------------------------------------------------------- * * PreCmdProc -- * * Procedure callback for Tcl_Trace. Gets called before the * command is executed, but after substitutions have occurred. * If a watch procedure is active, it evals a TCL command. * Activates the "precmd" callback, if one exists. * * Stashes some information for the "pre" callback: command * string, substituted argument list, and current level. * * Format of "pre" proc: * * proc beforeCmd { level cmdStr argList } { * * } * * * Results: * None. * * Side Effects: * A Tcl_AsyncHandler may be triggered, if a "post" procedure is * defined. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void PreCmdProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ int level, /* Current level */ char *command, /* Command before substitution */ Tcl_CmdProc *cmdProc, /* Not used. */ ClientData cmdClientData, /* Not used. */ int argc, const char **argv) /* Command after parsing, but before * evaluation */ { Watch *watchPtr = clientData; if (watchPtr->active) { return; /* Don't re-enter from Tcl_Eval below */ } watchPtr->cmdPtr = command; watchPtr->level = level; /* * There's no guarantee that the calls to PreCmdProc will match * up with PostCmdProc. So free up argument lists that are still * hanging around before allocating a new one. */ if (watchPtr->args != NULL) { Blt_Free(watchPtr->args); } watchPtr->args = Tcl_Merge(argc, argv); if (watchPtr->preCmd != NULL) { Tcl_DString buffer; char string[200]; int status; char **p; /* Create the "pre" command procedure call */ Tcl_DStringInit(&buffer); for (p = watchPtr->preCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&buffer, *p); } sprintf_s(string, 200, "%d", watchPtr->level); Tcl_DStringAppendElement(&buffer, string); Tcl_DStringAppendElement(&buffer, watchPtr->cmdPtr); Tcl_DStringAppendElement(&buffer, watchPtr->args); watchPtr->active = 1; status = Tcl_Eval(interp, Tcl_DStringValue(&buffer)); watchPtr->active = 0; Tcl_DStringFree(&buffer); if (status != TCL_OK) { fprintf(stderr, "%s failed: %s\n", watchPtr->preCmd[0], Tcl_GetStringResult(interp)); } } /* Set the trigger for the "post" command procedure */ if (watchPtr->postCmd != NULL) { Tcl_AsyncMark(watchPtr->asyncHandle); } } /* *--------------------------------------------------------------------------- * * PostCmdProc -- * * Procedure callback for Tcl_AsyncHandler. Gets called after * the command has executed. It tests for a "post" command, but * you really can't get here, if one doesn't exist. * * Save the current contents of interp->result before calling * the "post" command, and restore it afterwards. * * Format of "post" proc: * * proc afterCmd { level cmdStr argList retCode results } { * * } * * Results: * None. * * Side Effects: * Memory for argument list is released. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PostCmdProc(ClientData clientData, Tcl_Interp *interp, int code) { Watch *watchPtr = clientData; if (watchPtr->active) { return code; } if (watchPtr->postCmd != NULL) { int status; Tcl_DString buffer; char string[200]; const char *results; char **p; const char *retCode; char *errorCode, *errorInfo; errorInfo = errorCode = NULL; results = "NO INTERPRETER AVAILABLE"; /* * Save the state of the interpreter. */ if (interp != NULL) { errorInfo = (char *)Tcl_GetVar2(interp, "errorInfo", (char *)NULL, TCL_GLOBAL_ONLY); if (errorInfo != NULL) { errorInfo = Blt_AssertStrdup(errorInfo); } errorCode = (char *)Tcl_GetVar2(interp, "errorCode", (char *)NULL, TCL_GLOBAL_ONLY); if (errorCode != NULL) { errorCode = Blt_AssertStrdup(errorCode); } results = Blt_AssertStrdup(Tcl_GetStringResult(interp)); } /* Create the "post" command procedure call */ Tcl_DStringInit(&buffer); for (p = watchPtr->postCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&buffer, *p); } sprintf_s(string, 200, "%d", watchPtr->level); Tcl_DStringAppendElement(&buffer, string); Tcl_DStringAppendElement(&buffer, watchPtr->cmdPtr); Tcl_DStringAppendElement(&buffer, watchPtr->args); if (code < UNKNOWN_RETURN_CODE) { retCode = codeNames[code]; } else { sprintf_s(string, 200, "%d", code); retCode = string; } Tcl_DStringAppendElement(&buffer, retCode); Tcl_DStringAppendElement(&buffer, results); watchPtr->active = 1; status = Tcl_Eval(watchPtr->interp, Tcl_DStringValue(&buffer)); watchPtr->active = 0; Tcl_DStringFree(&buffer); Blt_Free(watchPtr->args); watchPtr->args = NULL; if (status != TCL_OK) { fprintf(stderr, "%s failed: %s\n", watchPtr->postCmd[0], Tcl_GetStringResult(watchPtr->interp)); } /* * Restore the state of the interpreter. */ if (interp != NULL) { if (errorInfo != NULL) { Tcl_SetVar2(interp, "errorInfo", (char *)NULL, errorInfo, TCL_GLOBAL_ONLY); Blt_Free(errorInfo); } if (errorCode != NULL) { Tcl_SetVar2(interp, "errorCode", (char *)NULL, errorCode, TCL_GLOBAL_ONLY); Blt_Free(errorCode); } Tcl_SetStringObj(Tcl_GetObjResult(interp), results, -1); } } return code; } /* *--------------------------------------------------------------------------- * * NewWatch -- * * Creates a new watch. The new watch is registered into the * "watchTable" hash table. Also creates a Tcl_AsyncHandler for * triggering "post" events. * * Results: * If memory for the watch could be allocated, a pointer to * the new watch is returned. Otherwise NULL, and interp->result * points to an error message. * * Side Effects: * A new Tcl_AsyncHandler is created. A new hash table entry * is created. Memory the watch structure is allocated. * *--------------------------------------------------------------------------- */ static Watch * NewWatch(Tcl_Interp *interp, const char *name) { Watch *watchPtr; watchPtr = Blt_Calloc(1, sizeof(Watch)); if (watchPtr == NULL) { Tcl_AppendResult(interp, "can't allocate watch structure", (char *)NULL); return NULL; } watchPtr->state = WATCH_STATE_ACTIVE; watchPtr->maxLevel = WATCH_MAX_LEVEL; watchPtr->name = Blt_AssertStrdup(name); watchPtr->interp = interp; watchPtr->asyncHandle = Tcl_AsyncCreate(PostCmdProc, watchPtr); return watchPtr; } /* *--------------------------------------------------------------------------- * * DestroyWatch -- * * Removes the watch. The resources used by the watch * are released. * 1) If the watch is active, its trace is deleted. * 2) Memory for command strings is free-ed. * 3) Entry is removed from watch registry. * 4) Async handler is deleted. * 5) Memory for watch itself is released. * * Results: * None. * * Side Effects: * Everything associated with the watch is freed. * *--------------------------------------------------------------------------- */ static void DestroyWatch(WatchCmdInterpData *dataPtr, Watch *watchPtr) { Blt_HashEntry *hPtr; Tcl_AsyncDelete(watchPtr->asyncHandle); if (watchPtr->state == WATCH_STATE_ACTIVE) { Tcl_DeleteTrace(watchPtr->interp, watchPtr->trace); } if (watchPtr->preCmd != NULL) { Blt_Free(watchPtr->preCmd); } if (watchPtr->postCmd != NULL) { Blt_Free(watchPtr->postCmd); } if (watchPtr->args != NULL) { Blt_Free(watchPtr->args); } hPtr = Blt_FindHashEntry(&dataPtr->watchTable, (char *)watchPtr->name); Blt_DeleteHashEntry(&dataPtr->watchTable, hPtr); if (watchPtr->name != NULL) { Blt_Free(watchPtr->name); } Blt_Free(watchPtr); } /* *--------------------------------------------------------------------------- * * GetWatchFromObj -- * * Searches for the watch represented by the watch name and its * associated interpreter in its directory. * * Results: * If found, the pointer to the watch structure is returned, * otherwise NULL. If requested, interp-result will be filled * with an error message. * *--------------------------------------------------------------------------- */ static int GetWatchFromObj( WatchCmdInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, Watch **watchPtrPtr) { Blt_HashEntry *hPtr; char *string; string = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&dataPtr->watchTable, (char *)string); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find any watch named \"", string, "\"", (char *)NULL); } return TCL_ERROR; } *watchPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListWatches -- * * Creates a list of all watches in the interpreter. The * list search may be restricted to selected states by * setting "state" to something other than WATCH_STATE_DONT_CARE. * * Results: * A standard TCL result. Interp->result will contain a list * of all watches matches the state criteria. * *--------------------------------------------------------------------------- */ static int ListWatches(WatchCmdInterpData *dataPtr, Tcl_Interp *interp, enum WatchStates state) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&dataPtr->watchTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Watch *watchPtr; watchPtr = Blt_GetHashValue(hPtr); if ((state == WATCH_STATE_DONT_CARE) || (state == watchPtr->state)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(watchPtr->name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigWatch -- * * Processes argument list of switches and values, setting * Watch fields. * * Results: * If found, the pointer to the watch structure is returned, * otherwise NULL. If requested, interp-result will be filled * with an error message. * *--------------------------------------------------------------------------- */ static int ConfigWatch(Watch *watchPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (Blt_ParseSwitches(interp, switchSpecs, objc, objv, watchPtr, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } /* * If the watch's max depth changed or its state, reset the traces. */ if (watchPtr->trace != (Tcl_Trace) 0) { Tcl_DeleteTrace(interp, watchPtr->trace); watchPtr->trace = (Tcl_Trace) 0; } if (watchPtr->state == WATCH_STATE_ACTIVE) { watchPtr->trace = Tcl_CreateTrace(interp, watchPtr->maxLevel, PreCmdProc, watchPtr); } return TCL_OK; } /* TCL interface routines */ /* *--------------------------------------------------------------------------- * * CreateOp -- * * Creates a new watch and processes any extra switches. * * Results: * A standard TCL result. * * Side Effects: * A new watch is created. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CreateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { WatchCmdInterpData *dataPtr = clientData; Watch *watchPtr; int isNew; char *string; Blt_HashEntry *hPtr; string = Tcl_GetString(objv[2]); hPtr = Blt_CreateHashEntry(&dataPtr->watchTable, string, &isNew); if (!isNew) { Tcl_AppendResult(interp, "a watch \"", string, "\" already exists", (char *)NULL); return TCL_ERROR; } watchPtr = NewWatch(interp, string); if (watchPtr == NULL) { return TCL_ERROR; /* Can't create new watch */ } Blt_SetHashValue(hPtr, watchPtr); return ConfigWatch(watchPtr, interp, objc - 3, objv + 3); } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the watch. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Watch *watchPtr; WatchCmdInterpData *dataPtr = clientData; if (GetWatchFromObj(dataPtr, interp, objv[2], &watchPtr) != TCL_OK) { return TCL_ERROR; } DestroyWatch(dataPtr, watchPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activate/deactivates the named watch. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ActivateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { WatchCmdInterpData *dataPtr = clientData; Watch *watchPtr; enum WatchStates state; char *string; if (GetWatchFromObj(dataPtr, interp, objv[2], &watchPtr) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetString(objv[1]); state = (string[0] == 'a') ? WATCH_STATE_ACTIVE : WATCH_STATE_IDLE; if (state != watchPtr->state) { if (watchPtr->trace == (Tcl_Trace) 0) { watchPtr->trace = Tcl_CreateTrace(interp, watchPtr->maxLevel, PreCmdProc, watchPtr); } else { Tcl_DeleteTrace(interp, watchPtr->trace); watchPtr->trace = (Tcl_Trace) 0; } watchPtr->state = state; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns the names of all watches in the interpreter. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { WatchCmdInterpData *dataPtr = clientData; enum WatchStates state; state = WATCH_STATE_DONT_CARE; if (objc == 3) { char c; char *string; string = Tcl_GetString(objv[2]); c = string[0]; if ((c == 'a') && (strcmp(string, "active") == 0)) { state = WATCH_STATE_ACTIVE; } else if ((c == 'i') && (strcmp(string, "idle") == 0)) { state = WATCH_STATE_IDLE; } else if ((c == 'i') && (strcmp(string, "ignore") == 0)) { state = WATCH_STATE_DONT_CARE; } else { Tcl_AppendResult(interp, "bad state \"", string, "\" should be \ \"active\", \"idle\", or \"ignore\"", (char *)NULL); return TCL_ERROR; } } return ListWatches(dataPtr, interp, state); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Convert the range of the pixel values allowed into a list. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { WatchCmdInterpData *dataPtr = clientData; Watch *watchPtr; if (GetWatchFromObj(dataPtr, interp, objv[2], &watchPtr) != TCL_OK) { return TCL_ERROR; } return ConfigWatch(watchPtr, interp, objc - 3, objv + 3); } /* *--------------------------------------------------------------------------- * * InfoOp -- * * Convert the limits of the pixel values allowed into a list. * * Results: * The string representation of the limits is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InfoOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { WatchCmdInterpData *dataPtr = clientData; Watch *watchPtr; char **p; if (GetWatchFromObj(dataPtr, interp, objv[2], &watchPtr) != TCL_OK) { return TCL_ERROR; } if (watchPtr->preCmd != NULL) { Tcl_AppendResult(interp, "-precmd", (char *)NULL); for (p = watchPtr->preCmd; *p != NULL; p++) { Tcl_AppendResult(interp, " ", *p, (char *)NULL); } } if (watchPtr->postCmd != NULL) { Tcl_AppendResult(interp, "-postcmd", (char *)NULL); for (p = watchPtr->postCmd; *p != NULL; p++) { Tcl_AppendResult(interp, " ", *p, (char *)NULL); } } Tcl_AppendResult(interp, "-maxlevel ", Blt_Itoa(watchPtr->maxLevel), " ", (char *)NULL); Tcl_AppendResult(interp, "-active ", (watchPtr->state == WATCH_STATE_ACTIVE) ? "true" : "false", " ", (char *)NULL); return TCL_OK; } /* *--------------------------------------------------------------------------- * * WatchCmd -- * * This procedure is invoked to process the TCL "blt_watch" * command. See the user documentation for details on what * it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec watchOps[] = { {"activate", 1, ActivateOp, 3, 3, "watchName",}, {"configure", 2, ConfigureOp, 3, 0, "watchName ?options...?"}, {"create", 2, CreateOp, 3, 0, "watchName ?switches?",}, {"deactivate", 3, ActivateOp, 3, 3, "watchName",}, {"delete", 3, DeleteOp, 3, 3, "watchName",}, {"info", 1, InfoOp, 3, 3, "watchName",}, {"names", 1, NamesOp, 2, 3, "?state?",}, }; static int nWatchOps = sizeof(watchOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int WatchCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nWatchOps, watchOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } /* Public initialization routine */ /* *--------------------------------------------------------------------------- * * Blt_WatchCmdInitProc -- * * This procedure is invoked to initialize the TCL command * "blt_watch". * * Results: * None. * * Side effects: * Creates the new command and adds a new entry into a * global Tcl associative array. * *--------------------------------------------------------------------------- */ int Blt_WatchCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"watch", WatchCmd, NULL}; cmdSpec.clientData = GetWatchCmdInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltAssert.h�������������������������������������������������������������������0000644�0001750�0001750�00000001141�11462120062�015136� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _BLT_ASSERT_H #define _BLT_ASSERT_H /* * Since the Tcl/Tk distribution doesn't perform any asserts, dynamic * loading can fail to find the __assert function. As a workaround, * we'll include our own. */ #undef assert #ifdef NDEBUG # define assert(EX) ((void)0) #else BLT_EXTERN void Blt_Assert(const char *expr, const char *file, int line); #ifdef __STDC__ # define assert(EX) (void)((EX) || (Blt_Assert(#EX, __FILE__, __LINE__), 0)) #else # define assert(EX) (void)((EX) || (Blt_Assert("EX", __FILE__, __LINE__), 0)) #endif /* __STDC__ */ #endif /* NDEBUG */ #endif /* _BLT_ASSERT_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBgexec.c�������������������������������������������������������������������0000644�0001750�0001750�00000147201�11462120062�015075� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBgexec.c -- * * This module implements a background "exec" command for the BLT toolkit. * * Copyright 1993-1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_BGEXEC #include <fcntl.h> #include <signal.h> #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif #include <sys/types.h> #include "bltWait.h" #include "bltSwitch.h" #include "bltChain.h" static Tcl_ObjCmdProc BgexecCmd; #define WINDEBUG 0 #if (_TCL_VERSION < _VERSION(8,1,0)) typedef void *Tcl_Encoding; /* Make up dummy type for encoding. */ #endif #define ENCODING_ASCII ((Tcl_Encoding)NULL) #define ENCODING_BINARY ((Tcl_Encoding)1) /* * This module creates a replacement of the old Tcl_CreatePipeline call in * the TCL C library. The prescribed workaround is Tcl_OpenCommandChannel. * But it hides the pids of the pipeline away (unless of course you pry open * the undocumented structure PipeStatus as clientData). The bigger problem * is that I couldn't figure any way to make one side of the pipe to be * non-blocking. */ #ifdef WIN32 #define read(fd, buf, size) Blt_AsyncRead((fd),(buf),(size)) #define close(fd) CloseHandle((HANDLE)fd) #define Tcl_CreateFileHandler Blt_CreateFileHandler #define Tcl_DeleteFileHandler Blt_DeleteFileHandler #define kill KillProcess #define waitpid WaitProcess #endif #define BGEXEC_THREAD_KEY "BLT Bgexec Data" #define READ_AGAIN (0) #define READ_EOF (-1) #define READ_ERROR (-2) /* The wait-related definitions are taken from tclUnix.h */ #define TRACE_FLAGS (TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY) #define BLOCK_SIZE 1024 /* Size of allocation blocks for * buffer */ #define DEF_BUFFER_SIZE (BLOCK_SIZE * 8) #define MAX_READS 100 /* Maximum # of successful reads * before stopping to let TCL catch up * on events */ #ifndef NSIG #define NSIG 32 /* # of signals available */ #endif /*NSIG*/ #ifndef SIGINT #define SIGINT 2 #endif /* SIGINT */ #ifndef SIGQUIT #define SIGQUIT 3 #endif /* SIGQUIT */ #ifndef SIGKILL #define SIGKILL 9 #endif /* SIGKILL */ #ifndef SIGTERM #define SIGTERM 14 #endif /* SIGTERM */ typedef struct { int number; const char *name; } SignalToken; static SignalToken signalTokens[] = { #ifdef SIGABRT {SIGABRT, "SIGABRT"}, #endif #ifdef SIGALRM {SIGALRM, "SIGALRM"}, #endif #ifdef SIGBUS {SIGBUS, "SIGBUS"}, #endif #ifdef SIGCHLD {SIGCHLD, "SIGCHLD"}, #endif #if defined(SIGCLD) && (!defined(SIGCHLD) || (SIGCLD != SIGCHLD)) {SIGCLD, "SIGCLD"}, #endif #ifdef SIGCONT {SIGCONT, "SIGCONT"}, #endif #if defined(SIGEMT) && (!defined(SIGXCPU) || (SIGEMT != SIGXCPU)) {SIGEMT, "SIGEMT"}, #endif #ifdef SIGFPE {SIGFPE, "SIGFPE"}, #endif #ifdef SIGHUP {SIGHUP, "SIGHUP"}, #endif #ifdef SIGILL {SIGILL, "SIGILL"}, #endif #ifdef SIGINT {SIGINT, "SIGINT"}, #endif #ifdef SIGIO {SIGIO, "SIGIO"}, #endif #if defined(SIGIOT) && (!defined(SIGABRT) || (SIGIOT != SIGABRT)) {SIGIOT, "SIGIOT"}, #endif #ifdef SIGKILL {SIGKILL, "SIGKILL"}, #endif #if defined(SIGLOST) && (!defined(SIGIOT) || (SIGLOST != SIGIOT)) && (!defined(SIGURG) || (SIGLOST != SIGURG)) {SIGLOST, "SIGLOST"}, #endif #ifdef SIGPIPE {SIGPIPE, "SIGPIPE"}, #endif #if defined(SIGPOLL) && (!defined(SIGIO) || (SIGPOLL != SIGIO)) {SIGPOLL, "SIGPOLL"}, #endif #ifdef SIGPROF {SIGPROF, "SIGPROF"}, #endif #if defined(SIGPWR) && (!defined(SIGXFSZ) || (SIGPWR != SIGXFSZ)) {SIGPWR, "SIGPWR"}, #endif #ifdef SIGQUIT {SIGQUIT, "SIGQUIT"}, #endif #ifdef SIGSEGV {SIGSEGV, "SIGSEGV"}, #endif #ifdef SIGSTOP {SIGSTOP, "SIGSTOP"}, #endif #ifdef SIGSYS {SIGSYS, "SIGSYS"}, #endif #ifdef SIGTERM {SIGTERM, "SIGTERM"}, #endif #ifdef SIGTRAP {SIGTRAP, "SIGTRAP"}, #endif #ifdef SIGTSTP {SIGTSTP, "SIGTSTP"}, #endif #ifdef SIGTTIN {SIGTTIN, "SIGTTIN"}, #endif #ifdef SIGTTOU {SIGTTOU, "SIGTTOU"}, #endif #if defined(SIGURG) && (!defined(SIGIO) || (SIGURG != SIGIO)) {SIGURG, "SIGURG"}, #endif #if defined(SIGUSR1) && (!defined(SIGIO) || (SIGUSR1 != SIGIO)) {SIGUSR1, "SIGUSR1"}, #endif #if defined(SIGUSR2) && (!defined(SIGURG) || (SIGUSR2 != SIGURG)) {SIGUSR2, "SIGUSR2"}, #endif #ifdef SIGVTALRM {SIGVTALRM, "SIGVTALRM"}, #endif #ifdef SIGWINCH {SIGWINCH, "SIGWINCH"}, #endif #ifdef SIGXCPU {SIGXCPU, "SIGXCPU"}, #endif #ifdef SIGXFSZ {SIGXFSZ, "SIGXFSZ"}, #endif {-1, "unknown signal"}, }; #ifdef TCL_THREADS static Tcl_Mutex *mutexPtr = NULL; #endif static Blt_Chain activePipelines; /* List of active pipelines and their * bgexec structures. */ /* * Sink buffer: * ____________________ * | | "size" current allocated length of buffer. * | | * |--------------------| "fill" fill point (# characters in buffer). * | Raw | * |--------------------| "mark" Marks end of cooked characters. * | | * | Cooked | * | | * | | * |--------------------| "lastMark" Mark end of processed characters. * | | * | | * | Processed | * | | * |____________________| 0 */ typedef struct { const char *name; /* Name of the sink */ const char *doneVar; /* Name of a TCL variable (malloc'ed) * set to the collected data of the * last UNIX * subprocess. */ const char *updateVar; /* Name of a TCL variable (malloc'ed) * updated as data is read from the * pipe. */ Tcl_Obj *cmdObjPtr; /* Start of a TCL command executed * whenever data is read from the * pipe. */ int flags; Tcl_Encoding encoding; /* Decoding scheme to use when * translating data. */ int fd; /* File descriptor of the pipe. */ int status; int echo; /* Indicates if the pipeline's stderr * stream should be echoed */ unsigned char *bytes; /* Stores pipeline output (malloc-ed): * Initially points to static * storage */ int size; /* Size of dynamically allocated * buffer. */ int fill; /* # of bytes read into the * buffer. Marks the current fill * point of the buffer. */ int mark; /* # of bytes translated (cooked). */ int lastMark; /* # of bytes as of the last read. This * indicates the start of the new data * in the buffer since the last time * the "update" variable was set. */ unsigned char staticSpace[DEF_BUFFER_SIZE]; /* Static space */ } Sink; #define SINK_BUFFERED (1<<0) #define SINK_KEEP_NL (1<<1) #define SINK_NOTIFY (1<<2) typedef struct { const char *statVar; /* Name of a TCL variable set to the * exit status of the last * process. Setting this variable * triggers the termination of all * subprocesses (regardless whether * they have already completed) */ int signalNum; /* If non-zero, indicates the signal * to send subprocesses when cleaning * up.*/ unsigned int flags; /* Various bit flags: see below. */ int interval; /* Interval to poll for the exiting * processes */ /* Private */ Tcl_Interp *interp; /* Interpreter containing variables */ int nProcs; /* # of processes in pipeline */ ProcessId *procIds; /* Array of process tokens from * pipeline. Under Unix, tokens are * pid_t, while for Win32 they're * handles. */ Tcl_TimerToken timerToken; /* Token for timer handler which polls * for the exit status of each * sub-process. If zero, there's no * timer handler queued. */ int *exitCodePtr; /* Pointer to a memory location to * contain the last process' exit * code. */ int *donePtr; Sink err, out; /* Data sinks for pipeline's output * and error channels. */ Blt_ChainLink link; } Bgexec; #define KEEPNEWLINE (1<<0) /* Indicates to set TCL output * variables with trailing newlines * intact */ #define LINEBUFFERED (1<<1) /* Indicates to provide data to update * variable and update proc on a * line-by-line * basis. */ #define IGNOREEXITCODE (1<<2) /* Don't check for 0 exit status of * the pipeline. */ #define TRACED (1<<3) /* Indicates that the status variable * is currently being traced. */ #define DETACHED (1<<4) /* Indicates that the pipeline is * detached from standard I/O, running * in the background. */ static Blt_SwitchParseProc ObjToSignalProc; static Blt_SwitchCustom killSignalSwitch = { ObjToSignalProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc ObjToEncodingProc; static Blt_SwitchFreeProc FreeEncodingProc; static Blt_SwitchCustom encodingSwitch = { ObjToEncodingProc, FreeEncodingProc, (ClientData)0, }; static Blt_SwitchSpec switchSpecs[] = { {BLT_SWITCH_CUSTOM, "-decodeoutput", "encoding", Blt_Offset(Bgexec, out.encoding), 0, 0, &encodingSwitch}, {BLT_SWITCH_CUSTOM, "-decodeerror", "encoding", Blt_Offset(Bgexec, err.encoding), 0, 0, &encodingSwitch}, {BLT_SWITCH_BOOLEAN, "-echo", "bool", Blt_Offset(Bgexec, err.echo), 0}, {BLT_SWITCH_STRING, "-error", "variable", Blt_Offset(Bgexec, err.doneVar), 0}, {BLT_SWITCH_STRING, "-update", "variable", Blt_Offset(Bgexec, out.updateVar), 0}, {BLT_SWITCH_STRING, "-output", "variable", Blt_Offset(Bgexec, out.doneVar), 0}, {BLT_SWITCH_STRING, "-lasterror", "variable", Blt_Offset(Bgexec, err.updateVar), 0}, {BLT_SWITCH_STRING, "-lastoutput", "variable", Blt_Offset(Bgexec, out.updateVar), 0}, {BLT_SWITCH_OBJ, "-onerror", "command", Blt_Offset(Bgexec, err.cmdObjPtr), 0}, {BLT_SWITCH_OBJ, "-onoutput", "command", Blt_Offset(Bgexec, out.cmdObjPtr), 0}, {BLT_SWITCH_BOOLEAN, "-keepnewline", "bool", Blt_Offset(Bgexec, flags), 0, KEEPNEWLINE}, {BLT_SWITCH_INT, "-check", "interval", Blt_Offset(Bgexec, interval), 0}, {BLT_SWITCH_CUSTOM, "-killsignal", "signal", Blt_Offset(Bgexec, signalNum), 0, 0, &killSignalSwitch}, {BLT_SWITCH_BOOLEAN, "-linebuffered", "bool", Blt_Offset(Bgexec, flags), 0, LINEBUFFERED}, {BLT_SWITCH_BOOLEAN, "-ignoreexitcode", "bool", Blt_Offset(Bgexec, flags), 0, IGNOREEXITCODE}, {BLT_SWITCH_END} }; static Tcl_VarTraceProc VariableProc; static Tcl_TimerProc TimerProc; static Tcl_FileProc StdoutProc, StderrProc; static Tcl_ExitProc BgexecExitProc; /* *--------------------------------------------------------------------------- * * ObjToSignalProc -- * * Convert a Tcl_Obj representing a signal number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSignalProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Intrepreter to return results */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Value representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { char *string; int *signalPtr = (int *)(record + offset); int signalNum; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *signalPtr = 0; return TCL_OK; } if (isdigit(UCHAR(string[0]))) { if (Tcl_GetIntFromObj(interp, objPtr, &signalNum) != TCL_OK) { return TCL_ERROR; } } else { char *name; SignalToken *sp; name = string; /* Clip off any "SIG" prefix from the signal name */ if ((name[0] == 'S') && (name[1] == 'I') && (name[2] == 'G')) { name += 3; } signalNum = -1; for (sp = signalTokens; sp->number > 0; sp++) { if (strcmp(sp->name + 3, name) == 0) { signalNum = sp->number; break; } } if (signalNum < 0) { Tcl_AppendResult(interp, "unknown signal \"", string, "\"", (char *)NULL); return TCL_ERROR; } } if ((signalNum < 0) || (signalNum > NSIG)) { /* Outside range of signals */ Tcl_AppendResult(interp, "signal number \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } *signalPtr = signalNum; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToEncodingProc -- * * Convert a Tcl_Obj representing a encoding into a Tcl_Encoding. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToEncodingProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Intrepreter to return results */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Value representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Tcl_Encoding *encodingPtr = (Tcl_Encoding *)(record + offset); Tcl_Encoding encoding; const char *name; name = Tcl_GetString(objPtr); encoding = ENCODING_ASCII; if (name != NULL) { if (strcmp(name, "binary") == 0) { encoding = ENCODING_BINARY; } else { #if (_TCL_VERSION >= _VERSION(8,1,0)) encoding = Tcl_GetEncoding(interp, name); if (encoding == NULL) { return TCL_ERROR; } #endif } } if ((*encodingPtr != ENCODING_BINARY) && (*encodingPtr != ENCODING_ASCII)) { Tcl_FreeEncoding(*encodingPtr); } *encodingPtr = encoding; return TCL_OK; } /*ARGSUSED*/ static void FreeEncodingProc(char *record, int offset, int flags) { Tcl_Encoding *encodingPtr = (Tcl_Encoding *)(record + offset); if ((*encodingPtr != ENCODING_BINARY) && (*encodingPtr != ENCODING_ASCII)) { Tcl_FreeEncoding(*encodingPtr); } } /* *--------------------------------------------------------------------------- * * GetSinkData -- * * Returns the data currently saved in the buffer * *--------------------------------------------------------------------------- */ static void GetSinkData(Sink *sinkPtr, unsigned char **dataPtr, int *lengthPtr) { int length; sinkPtr->bytes[sinkPtr->mark] = '\0'; length = sinkPtr->mark; if ((sinkPtr->mark > 0) && (sinkPtr->encoding != ENCODING_BINARY)) { unsigned char *last; last = sinkPtr->bytes + (sinkPtr->mark - 1); if (((sinkPtr->flags & SINK_KEEP_NL) == 0) && (*last == '\n')) { length--; } } *dataPtr = sinkPtr->bytes; *lengthPtr = length; } /* *--------------------------------------------------------------------------- * * NextBlock -- * * Returns the next block of data since the last time this routine was * called. * *--------------------------------------------------------------------------- */ static unsigned char * NextBlock(Sink *sinkPtr, int *lengthPtr) { unsigned char *string; int length; string = sinkPtr->bytes + sinkPtr->lastMark; length = sinkPtr->mark - sinkPtr->lastMark; sinkPtr->lastMark = sinkPtr->mark; if (length > 0) { if ((!(sinkPtr->flags & SINK_KEEP_NL)) && (string[length-1] == '\n')) { length--; } *lengthPtr = length; return string; } return NULL; } /* *--------------------------------------------------------------------------- * * NextLine -- * * Returns the next line of data. * *--------------------------------------------------------------------------- */ static unsigned char * NextLine(Sink *sinkPtr, int *lengthPtr) { if (sinkPtr->mark > sinkPtr->lastMark) { unsigned char *string; int newBytes; int i; string = sinkPtr->bytes + sinkPtr->lastMark; newBytes = sinkPtr->mark - sinkPtr->lastMark; for (i = 0; i < newBytes; i++) { if (string[i] == '\n') { int length; length = i + 1; sinkPtr->lastMark += length; if (!(sinkPtr->flags & SINK_KEEP_NL)) { length--; /* Backup over the newline. */ } *lengthPtr = length; return string; } } /* Newline not found. On errors or EOF, also return a partial line. */ if (sinkPtr->status < 0) { *lengthPtr = newBytes; sinkPtr->lastMark = sinkPtr->mark; return string; } } return NULL; } /* *--------------------------------------------------------------------------- * * ResetSink -- * * Removes the bytes already processed from the buffer, possibly * resetting it to empty. This used when we don't care about keeping all * the data collected from the channel (no -output flag and the process * is detached). * *--------------------------------------------------------------------------- */ static void ResetSink(Sink *sinkPtr) { if ((sinkPtr->flags & SINK_BUFFERED) && (sinkPtr->fill > sinkPtr->lastMark)) { int i, j; /* There may be bytes remaining in the buffer, awaiting another read * before we see the next newline. So move the bytes to the front of * the array. */ for (i = 0, j = sinkPtr->lastMark; j < sinkPtr->fill; i++, j++) { sinkPtr->bytes[i] = sinkPtr->bytes[j]; } /* Move back the fill point and processed point. */ sinkPtr->fill -= sinkPtr->lastMark; sinkPtr->mark -= sinkPtr->lastMark; } else { sinkPtr->mark = sinkPtr->fill = 0; } sinkPtr->lastMark = 0; } /* *--------------------------------------------------------------------------- * * InitSink -- * * Initializes the buffer's storage. * * Results: * None. * * Side effects: * Storage is cleared. * *--------------------------------------------------------------------------- */ static void InitSink(Bgexec *bgPtr, Sink *sinkPtr, const char *name) { sinkPtr->name = name; sinkPtr->echo = FALSE; sinkPtr->fd = -1; sinkPtr->bytes = sinkPtr->staticSpace; sinkPtr->size = DEF_BUFFER_SIZE; if (bgPtr->flags & KEEPNEWLINE) { sinkPtr->flags |= SINK_KEEP_NL; } if (bgPtr->flags & LINEBUFFERED) { sinkPtr->flags |= SINK_BUFFERED; } if ((sinkPtr->cmdObjPtr != NULL) || (sinkPtr->updateVar != NULL) || (sinkPtr->echo)) { sinkPtr->flags |= SINK_NOTIFY; } ResetSink(sinkPtr); } /* *--------------------------------------------------------------------------- * * FreeSinkBuffer -- * * Frees the buffer's storage, freeing any malloc'ed space. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeSinkBuffer(Sink *sinkPtr) { if (sinkPtr->bytes != sinkPtr->staticSpace) { Blt_Free(sinkPtr->bytes); } sinkPtr->fd = -1; } /* *--------------------------------------------------------------------------- * * ExtendSinkBuffer -- * * Doubles the size of the current buffer. * * Results: * None. * *--------------------------------------------------------------------------- */ static int ExtendSinkBuffer(Sink *sinkPtr) { unsigned char *bytes; /* * Allocate a new array, double the old size */ sinkPtr->size += sinkPtr->size; bytes = Blt_Malloc(sizeof(unsigned char) * sinkPtr->size); if (bytes != NULL) { unsigned char *sp, *dp, *send; dp = bytes; for (sp = sinkPtr->bytes, send = sp + sinkPtr->fill; sp < send; /*empty*/) { *dp++ = *sp++; } if (sinkPtr->bytes != sinkPtr->staticSpace) { Blt_Free(sinkPtr->bytes); } sinkPtr->bytes = bytes; return (sinkPtr->size - sinkPtr->fill); /* Return bytes left. */ } return -1; } /* *--------------------------------------------------------------------------- * * ReadBytes -- * * Reads and appends any available data from a given file descriptor * to the buffer. * * Results: * Returns TCL_OK when EOF is found, TCL_RETURN if reading data would * block, and TCL_ERROR if an error occurred. * *--------------------------------------------------------------------------- */ static void ReadBytes(Sink *sinkPtr) { int i; int nBytes; /* * Worry about indefinite postponement. * * Typically we want to stay in the read loop as long as it takes to * collect all the data that's currently available. But if it's coming * in at a constant high rate, we need to arbitrarily break out at some * point. This allows for both setting the update variable and the Tk * program to handle idle events. */ nBytes = 0; for (i = 0; i < MAX_READS; i++) { int bytesLeft; unsigned char *array; /* Allocate a larger buffer when the number of remaining bytes is * below the threshold BLOCK_SIZE. */ bytesLeft = sinkPtr->size - sinkPtr->fill; if (bytesLeft < BLOCK_SIZE) { bytesLeft = ExtendSinkBuffer(sinkPtr); if (bytesLeft < 0) { errno = ENOMEM; sinkPtr->status = READ_ERROR; return; } } array = sinkPtr->bytes + sinkPtr->fill; /* Read into a buffer but make sure we leave room for a trailing NUL * byte. */ nBytes = read(sinkPtr->fd, array, bytesLeft - 1); if (nBytes == 0) { /* EOF: break out of loop. */ sinkPtr->status = READ_EOF; return; } if (nBytes < 0) { #ifdef O_NONBLOCK #define BLOCKED EAGAIN #else #define BLOCKED EWOULDBLOCK #endif /*O_NONBLOCK*/ /* Either an error has occurred or no more data is currently * available to read. */ if (errno == BLOCKED) { sinkPtr->status = READ_AGAIN; return; } sinkPtr->bytes[0] = '\0'; sinkPtr->status = READ_ERROR; return; } sinkPtr->fill += nBytes; sinkPtr->bytes[sinkPtr->fill] = '\0'; } sinkPtr->status = nBytes; } #define SINKOPEN(sinkPtr) ((sinkPtr)->fd != -1) static void CloseSink(Tcl_Interp *interp, Sink *sinkPtr) { if (SINKOPEN(sinkPtr)) { close(sinkPtr->fd); Tcl_DeleteFileHandler(sinkPtr->fd); sinkPtr->fd = -1; #if WINDEBUG PurifyPrintf("CloseSink: set done var %s\n", sinkPtr->name); #endif if (sinkPtr->doneVar != NULL) { unsigned char *data; int length; /* * If data is to be collected, set the "done" variable with the * contents of the buffer. */ GetSinkData(sinkPtr, &data, &length); #if (_TCL_VERSION < _VERSION(8,1,0)) data[length] = '\0'; if (Tcl_SetVar(interp, sinkPtr->doneVar, data, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } #else if (Tcl_SetVar2Ex(interp, sinkPtr->doneVar, NULL, Tcl_NewByteArrayObj(data, (int)length), TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } #endif } #if WINDEBUG PurifyPrintf("CloseSink %s: done\n", sinkPtr->name); #endif } } /* *--------------------------------------------------------------------------- * * CookSink -- * * For Windows, translate CR/NL combinations to NL alone. * * Results: * None. * * Side Effects: * The size of the byte array may shrink and array contents shifted as * carriage returns are found and removed. * *--------------------------------------------------------------------------- */ static void CookSink(Tcl_Interp *interp, Sink *sinkPtr) { unsigned char *srcPtr, *endPtr; #ifdef WIN32 int oldMark; oldMark = sinkPtr->mark; #endif if (sinkPtr->encoding == ENCODING_BINARY) { /* binary */ /* No translation needed. */ sinkPtr->mark = sinkPtr->fill; } else if (sinkPtr->encoding == ENCODING_ASCII) { /* ascii */ #if (_TCL_VERSION < _VERSION(8,1,0)) /* Convert NUL bytes to question marks. */ srcPtr = sinkPtr->bytes + sinkPtr->mark; endPtr = sinkPtr->bytes + sinkPtr->fill; while (srcPtr < endPtr) { if (*srcPtr == '\0') { *srcPtr = '?'; } srcPtr++; } #endif /* < 8.1.0 */ /* One-to-one translation. mark == fill. */ sinkPtr->mark = sinkPtr->fill; #if (_TCL_VERSION >= _VERSION(8,1,0)) } else { /* unicode. */ int nSrcCooked, nCooked; int result; int cookedSize, spaceLeft, needed; int nRaw, nLeftOver; unsigned char *destPtr; unsigned char *raw, *cooked; unsigned char leftover[100]; raw = sinkPtr->bytes + sinkPtr->mark; nRaw = sinkPtr->fill - sinkPtr->mark; /* Ideally, the cooked buffer size should be smaller */ cookedSize = nRaw * TCL_UTF_MAX + 1; cooked = Blt_AssertMalloc(cookedSize); result = Tcl_ExternalToUtf(interp, sinkPtr->encoding, (char *)raw, nRaw, 0, NULL, (char *)cooked, cookedSize, &nSrcCooked, &nCooked, NULL); nLeftOver = 0; if (result == TCL_CONVERT_MULTIBYTE) { /* * Last multibyte sequence wasn't completed. Save the extra * characters in a temporary buffer. */ nLeftOver = (nRaw - nSrcCooked); srcPtr = sinkPtr->bytes + (sinkPtr->mark + nSrcCooked); endPtr = srcPtr + nLeftOver; destPtr = leftover; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } } /* * Create a bigger sink. */ needed = nLeftOver + nCooked; spaceLeft = sinkPtr->size - sinkPtr->mark; if (spaceLeft >= needed) { spaceLeft = ExtendSinkBuffer(sinkPtr); } assert(spaceLeft > needed); /* * Replace the characters from the mark with the translated * characters. */ srcPtr = cooked; endPtr = cooked + nCooked; destPtr = sinkPtr->bytes + sinkPtr->mark; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } /* Add the number of newly translated characters to the mark */ sinkPtr->mark += nCooked; srcPtr = leftover; endPtr = leftover + nLeftOver; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } sinkPtr->fill = sinkPtr->mark + nLeftOver; #endif /* >= 8.1.0 */ } #ifdef WIN32 /* * Translate CRLF character sequences to LF characters. We have to do * this after converting the string to UTF from UNICODE. */ if (sinkPtr->encoding != ENCODING_BINARY) { int count; unsigned char *destPtr; destPtr = srcPtr = sinkPtr->bytes + oldMark; endPtr = sinkPtr->bytes + sinkPtr->fill; *endPtr = '\0'; count = 0; for (endPtr--; srcPtr < endPtr; srcPtr++) { if ((*srcPtr == '\r') && (*(srcPtr + 1) == '\n')) { count++; continue; /* Skip the CR in CR/LF sequences. */ } if (srcPtr != destPtr) { *destPtr = *srcPtr; /* Collapse the string, overwriting * the \r's encountered. */ } destPtr++; } sinkPtr->mark -= count; sinkPtr->fill -= count; *destPtr = *srcPtr; /* Copy the last byte */ if (*destPtr == '\r') { sinkPtr->mark--; } } #endif /* WIN32 */ } #ifdef WIN32 /* *--------------------------------------------------------------------------- * * WaitProcess -- * * Emulates the waitpid system call under the Win32 API. * * Results: * Returns 0 if the process is still alive, -1 on an error, or the pid on * a clean close. * * Side effects: * Unless WNOHANG is set and the wait times out, the process information * record will be deleted and the process handle will be closed. * *--------------------------------------------------------------------------- */ static int WaitProcess( ProcessId child, int *statusPtr, int flags) { DWORD status, exitCode; int result; int timeout; #if WINDEBUG PurifyPrintf("WAITPID(%x)\n", child.hProcess); #endif *statusPtr = 0; if (child.hProcess == INVALID_HANDLE_VALUE) { errno = EINVAL; return -1; } #if WINDEBUG PurifyPrintf("WAITPID: waiting for 0x%x\n", child.hProcess); #endif timeout = (flags & WNOHANG) ? 0 : INFINITE; status = WaitForSingleObject(child.hProcess, timeout); #if WINDEBUG PurifyPrintf("WAITPID: wait status is %d\n", status); #endif switch (status) { case WAIT_FAILED: errno = ECHILD; *statusPtr = ECHILD; result = -1; break; case WAIT_TIMEOUT: if (timeout == 0) { return 0; /* Try again */ } result = 0; break; default: case WAIT_ABANDONED: case WAIT_OBJECT_0: GetExitCodeProcess(child.hProcess, &exitCode); *statusPtr = ((exitCode << 8) & 0xff00); #if WINDEBUG PurifyPrintf("WAITPID: exit code of %d is %d (%x)\n", child.hProcess, *statusPtr, exitCode); #endif result = child.pid; assert(result != -1); break; } CloseHandle(child.hProcess); return result; } static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { DWORD pid = 0; ProcessId *procPtr = (ProcessId *)lParam; GetWindowThreadProcessId(hWnd, &pid); if (pid == procPtr->pid) { PostMessage(hWnd, WM_CLOSE, 0, 0); } return TRUE; } /* *--------------------------------------------------------------------------- * * KillProcess -- * * Emulates the UNIX kill system call under Win32 API. * * Results: * Returns 0 if the process is killed, -1 on an error. * * Side effects: * Process is terminated. * *--------------------------------------------------------------------------- */ static int KillProcess(ProcessId proc, int signal) { DWORD status; if ((proc.hProcess == NULL) || (proc.hProcess == INVALID_HANDLE_VALUE)) { errno = EINVAL; return -1; } EnumWindows(EnumWindowsProc, (LPARAM)&proc); /* * Wait on the handle. If it signals, great. If it times out, then call * TerminateProcess on it. * * On Windows 95/98 this also has the added benefit of stopping * KERNEL32.dll from dumping. The 2 second number is arbitrary (1 second * seems to fail intermittently). */ status = WaitForSingleObject(proc.hProcess, 2000); if (status == WAIT_OBJECT_0) { return 0; } if (!TerminateProcess(proc.hProcess, 1)) { #if WINDEBUG PurifyPrintf("can't terminate process (handle=%d): %s\n", proc.hProcess, Blt_LastError()); #endif /* WINDEBUG */ return -1; } return 0; } #endif /* WIN32 */ #if (_TCL_VERSION < _VERSION(8,1,0)) static void NotifyOnUpdate(Tcl_Interp *interp, Sink *sinkPtr, unsigned char *data, int nBytes) { char save; #if WINDEBUG PurifyPrintf("read %s\n", data); #endif if (data[0] == '\0') { return; } save = data[nBytes]; data[nBytes] = '\0'; if (sinkPtr->echo) { Tcl_Channel channel; channel = Tcl_GetStdChannel(TCL_STDERR); if (channel == NULL) { Tcl_AppendResult(interp, "can't get stderr channel", (char *)NULL); Tcl_BackgroundError(interp); sinkPtr->echo = FALSE; } else { Tcl_Write(channel, data, nBytes); if (save == '\n') { Tcl_Write(channel, "\n", 1); } Tcl_Flush(channel); } } objPtr = Tcl_NewByteArrayObj(data, (int)nBytes); Tcl_IncrRefCount(objPtr); if (sinkPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr, *objPtr; int result; cmdObjPtr = Tcl_DuplicateObj(sinkPtr->cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(interp); } } if (sinkPtr->updateVar != NULL) { if (Tcl_SetVar2Ex(interp, sinkPtr->updateVar, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } } Tcl_DecrRefCount(objPtr); data[nBytes] = save; } #else static void NotifyOnUpdate(Tcl_Interp *interp, Sink *sinkPtr, unsigned char *data, int nBytes) { Tcl_Obj *objPtr; #if WINDEBUG PurifyPrintf("read %s\n", data); #endif if ((nBytes == 0) || (data[0] == '\0')) { return; } if (sinkPtr->echo) { Tcl_Channel channel; channel = Tcl_GetStdChannel(TCL_STDERR); if (channel == NULL) { Tcl_AppendResult(interp, "can't get stderr channel", (char *)NULL); Tcl_BackgroundError(interp); sinkPtr->echo = FALSE; } else { if (data[nBytes] == '\n') { objPtr = Tcl_NewByteArrayObj(data, nBytes + 1); } else { objPtr = Tcl_NewByteArrayObj(data, nBytes); } Tcl_WriteObj(channel, objPtr); Tcl_Flush(channel); } } objPtr = Tcl_NewByteArrayObj(data, nBytes); Tcl_IncrRefCount(objPtr); if (sinkPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; int result; cmdObjPtr = Tcl_DuplicateObj(sinkPtr->cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(interp); } } if (sinkPtr->updateVar != NULL) { if (Tcl_SetVar2Ex(interp, sinkPtr->updateVar, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } } Tcl_DecrRefCount(objPtr); } #endif /* < 8.1.0 */ static int CollectData(Bgexec *bgPtr, Sink *sinkPtr) { if ((bgPtr->flags & DETACHED) && (sinkPtr->doneVar == NULL)) { ResetSink(sinkPtr); } ReadBytes(sinkPtr); CookSink(bgPtr->interp, sinkPtr); if ((sinkPtr->mark > sinkPtr->lastMark) && (sinkPtr->flags & SINK_NOTIFY)) { if (sinkPtr->flags & SINK_BUFFERED) { int length; unsigned char *data; /* For line-by-line updates, call NotifyOnUpdate for each new * complete line. */ while ((data = NextLine(sinkPtr, &length)) != NULL) { NotifyOnUpdate(bgPtr->interp, sinkPtr, data, length); } } else { int length; unsigned char *data; length = 0; /* Suppress compiler warning. */ data = NextBlock(sinkPtr, &length); NotifyOnUpdate(bgPtr->interp, sinkPtr, data, length); } } if (sinkPtr->status >= 0) { return TCL_OK; } if (sinkPtr->status == READ_ERROR) { Tcl_AppendResult(bgPtr->interp, "can't read data from ", sinkPtr->name, ": ", Tcl_PosixError(bgPtr->interp), (char *)NULL); Tcl_BackgroundError(bgPtr->interp); return TCL_ERROR; } #if WINDEBUG PurifyPrintf("CollectData %s: done\n", sinkPtr->name); #endif return TCL_RETURN; } /* *--------------------------------------------------------------------------- * * CreateSinkHandler -- * * Creates a file handler for the given sink. The file descriptor is * also set for non-blocking I/O. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ static int CreateSinkHandler(Bgexec *bgPtr, Sink *sinkPtr, Tcl_FileProc *proc) { #ifndef WIN32 int flags; flags = fcntl(sinkPtr->fd, F_GETFL); #ifdef O_NONBLOCK flags |= O_NONBLOCK; #else flags |= O_NDELAY; #endif if (fcntl(sinkPtr->fd, F_SETFL, flags) < 0) { Tcl_AppendResult(bgPtr->interp, "can't set file descriptor ", Blt_Itoa(sinkPtr->fd), " to non-blocking:", Tcl_PosixError(bgPtr->interp), (char *)NULL); return TCL_ERROR; } #endif /* WIN32 */ Tcl_CreateFileHandler(sinkPtr->fd, TCL_READABLE, proc, bgPtr); return TCL_OK; } static void DisableTriggers(Bgexec *bgPtr) /* Background info record. */ { if (bgPtr->flags & TRACED) { Tcl_UntraceVar(bgPtr->interp, bgPtr->statVar, TRACE_FLAGS, VariableProc, bgPtr); bgPtr->flags &= ~TRACED; } if (SINKOPEN(&bgPtr->out)) { CloseSink(bgPtr->interp, &bgPtr->out); } if (SINKOPEN(&bgPtr->err)) { CloseSink(bgPtr->interp, &bgPtr->err); } if (bgPtr->timerToken != (Tcl_TimerToken) 0) { Tcl_DeleteTimerHandler(bgPtr->timerToken); bgPtr->timerToken = 0; } if (bgPtr->donePtr != NULL) { *bgPtr->donePtr = TRUE; } } /* *--------------------------------------------------------------------------- * * FreeBgexec -- * * Releases the memory allocated for the backgrounded process. * *--------------------------------------------------------------------------- */ static void FreeBgexec(Bgexec *bgPtr) { Blt_FreeSwitches(switchSpecs, (char *)bgPtr, 0); if (bgPtr->statVar != NULL) { Blt_Free(bgPtr->statVar); } if (bgPtr->procIds != NULL) { Blt_Free(bgPtr->procIds); } if (bgPtr->link != NULL) { Tcl_MutexLock(mutexPtr); Blt_Chain_DeleteLink(activePipelines, bgPtr->link); Tcl_MutexUnlock(mutexPtr); } Blt_Free(bgPtr); } /* *--------------------------------------------------------------------------- * * KillProcesses -- * * Cleans up background execution processes and memory. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void KillProcesses(Bgexec *bgPtr) /* Background info record. */ { if (bgPtr->procIds != NULL) { int i; for (i = 0; i < bgPtr->nProcs; i++) { Tcl_Pid tclPid; if (bgPtr->signalNum > 0) { kill(bgPtr->procIds[i], bgPtr->signalNum); } #ifdef WIN32 tclPid = (Tcl_Pid)bgPtr->procIds[i].pid; #else { unsigned long pid; pid = (long)bgPtr->procIds[i]; tclPid = (Tcl_Pid)pid; } #endif /* WIN32 */ Tcl_DetachPids(1, &tclPid); } } Tcl_ReapDetachedProcs(); } /* *--------------------------------------------------------------------------- * * DestroyBgexec -- * * Cleans up background execution processes and memory. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void DestroyBgexec(Bgexec *bgPtr) /* Background info record. */ { DisableTriggers(bgPtr); FreeSinkBuffer(&bgPtr->err); FreeSinkBuffer(&bgPtr->out); KillProcesses(bgPtr); FreeBgexec(bgPtr); } /* *--------------------------------------------------------------------------- * * VariableProc -- * * Kills all currently running subprocesses (given the specified * signal). This procedure is called when the user sets the status * variable associated with this group of child subprocesses. * * Results: * Always returns NULL. Only called from a variable trace. * * Side effects: * The subprocesses are signaled for termination using the specified kill * signal. Additionally, any resources allocated to track the * subprocesses is released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static char * VariableProc( ClientData clientData, /* File output information. */ Tcl_Interp *interp, /* Not used. */ const char *part1, /* Not used. */ const char *part2, /* Not Used. */ int flags) { if (flags & TRACE_FLAGS) { Bgexec *bgPtr = clientData; /* Kill all child processes that remain alive. */ KillProcesses(bgPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * TimerProc -- * * This is a timer handler procedure which gets called periodically to * reap any of the sub-processes if they have terminated. After the last * process has terminated, the contents of standard output are stored in * the output variable, which triggers the cleanup proc (using a variable * trace). The status the last process to exit is written to the status * variable. * * Results: * None. Called from the TCL event loop. * * Side effects: * Many. The contents of procIds is shifted, leaving only those * sub-processes which have not yet terminated. If there are still * subprocesses left, this procedure is placed in the timer queue * again. Otherwise the output and possibly the status variables are * updated. The former triggers the cleanup routine which will destroy * the information and resources associated with these background * processes. * *--------------------------------------------------------------------------- */ static void TimerProc(ClientData clientData) { enum PROCESS_STATUS { PROCESS_EXITED, PROCESS_STOPPED, PROCESS_KILLED, PROCESS_UNKNOWN } pcode; static const char *tokens[] = { "EXITED", "KILLED", "STOPPED", "UNKNOWN" }; Bgexec *bgPtr = clientData; Tcl_Obj *listObjPtr, *objPtr; Tcl_Interp *interp; WAIT_STATUS_TYPE waitStatus, lastStatus; char string[200]; const char *mesg; int code; int i; int nLeft; /* # of processes still not reaped */ unsigned int lastPid; interp = bgPtr->interp; lastPid = (unsigned int)-1; *((int *)&waitStatus) = 0; *((int *)&lastStatus) = 0; nLeft = 0; for (i = 0; i < bgPtr->nProcs; i++) { int pid; #ifdef WIN32 pid = WaitProcess(bgPtr->procIds[i], (int *)&waitStatus, WNOHANG); #else pid = waitpid(bgPtr->procIds[i], (int *)&waitStatus, WNOHANG); #endif if (pid == 0) { /* Process has not terminated yet */ if (nLeft < i) { bgPtr->procIds[nLeft] = bgPtr->procIds[i]; } nLeft++; /* Count the # of processes left */ } else if (pid != -1) { /* * Save the status information associated with the subprocess. * We'll use it only if this is the last subprocess to be reaped. */ lastStatus = waitStatus; lastPid = (unsigned int)pid; } } bgPtr->nProcs = nLeft; if ((nLeft > 0) || (SINKOPEN(&bgPtr->out)) || (SINKOPEN(&bgPtr->err))) { /* Keep polling for the status of the children that are left */ bgPtr->timerToken = Tcl_CreateTimerHandler(bgPtr->interval, TimerProc, bgPtr); #if WINDEBUG PurifyPrintf("schedule TimerProc(nProcs=%d)\n", nLeft); #endif return; } /* * All child processes have completed. Set the status variable with the * status of the last process reaped. The status is a list of an error * token, the exit status, and a message. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); code = WEXITSTATUS(lastStatus); if (WIFEXITED(lastStatus)) { pcode = PROCESS_EXITED; } else if (WIFSIGNALED(lastStatus)) { pcode = PROCESS_KILLED; code = -1; } else if (WIFSTOPPED(lastStatus)) { pcode = PROCESS_STOPPED; code = -1; } else { pcode = PROCESS_UNKNOWN; } objPtr = Tcl_NewStringObj(tokens[pcode], -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewLongObj(lastPid); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); switch(pcode) { case PROCESS_EXITED: mesg = "child completed normally"; break; case PROCESS_KILLED: mesg = Tcl_SignalMsg((int)(WTERMSIG(lastStatus))); break; case PROCESS_STOPPED: mesg = Tcl_SignalMsg((int)(WSTOPSIG(lastStatus))); break; case PROCESS_UNKNOWN: sprintf_s(string, 200, "child completed with unknown status 0x%x", *((int *)&lastStatus)); mesg = string; break; } objPtr = Tcl_NewStringObj(mesg, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (bgPtr->exitCodePtr != NULL) { *bgPtr->exitCodePtr = code; } DisableTriggers(bgPtr); if (Tcl_SetVar2Ex(interp, bgPtr->statVar, NULL, listObjPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } if (bgPtr->flags & DETACHED) { DestroyBgexec(bgPtr); } } /* *--------------------------------------------------------------------------- * * Stdoutproc -- * * This procedure is called when output from the detached pipeline is * available. The output is read and saved in a buffer in the Bgexec * structure. * * Results: * None. * * Side effects: * Data is stored in the buffer. This character array may be increased * as more space is required to contain the output of the pipeline. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void StdoutProc(ClientData clientData, int mask) { Bgexec *bgPtr = clientData; if (CollectData(bgPtr, &bgPtr->out) == TCL_OK) { return; } /* * Either EOF or an error has occurred. In either case, close the * sink. Note that closing the sink will also remove the file handler, so * this routine will not be called again. */ CloseSink(bgPtr->interp, &bgPtr->out); /* * If both sinks (stdout and stderr) are closed, this doesn't necessarily * mean that the process has terminated. Set up a timer handler to * periodically poll for the exit status of each process. Initially check * at the next idle interval. */ if (!SINKOPEN(&bgPtr->err)) { bgPtr->timerToken = Tcl_CreateTimerHandler(0, TimerProc, clientData); } } /* *--------------------------------------------------------------------------- * * StderrProc -- * * This procedure is called when error from the detached pipeline is * available. The error is read and saved in a buffer in the Bgexec * structure. * * Results: * None. * * Side effects: * Data is stored in the buffer. This character array may be increased * as more space is required to contain the stderr of the pipeline. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void StderrProc(ClientData clientData, int mask) { Bgexec *bgPtr = clientData; if (CollectData(bgPtr, &bgPtr->err) == TCL_OK) { return; } /* * Either EOF or an error has occurred. In either case, close the * sink. Note that closing the sink will also remove the file handler, so * this routine will not be called again. */ CloseSink(bgPtr->interp, &bgPtr->err); /* * If both sinks (stdout and stderr) are closed, this doesn't necessarily * mean that the process has terminated. Set up a timer handler to * periodically poll for the exit status of each process. Initially check * at the next idle interval. */ if (!SINKOPEN(&bgPtr->out)) { bgPtr->timerToken = Tcl_CreateTimerHandler(0, TimerProc, clientData); } } /* *--------------------------------------------------------------------------- * * BgexecCmd -- * * This procedure is invoked to process the "bgexec" TCL command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int BgexecCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Bgexec *bgPtr; ProcessId *pidPtr; char *lastArg; int *outFdPtr, *errFdPtr; int isDetached; int i; int nProcs; if (objc < 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " varName ?options? command ?arg...?\"", (char *)NULL); return TCL_ERROR; } /* Check if the command line is to be run detached (the last argument is * "&") */ lastArg = Tcl_GetString(objv[objc - 1]); isDetached = ((lastArg[0] == '&') && (lastArg[1] == '\0')); if (isDetached) { objc--; /* Remove the '&' argument */ } bgPtr = Blt_AssertCalloc(1, sizeof(Bgexec)); /* Initialize the background information record */ bgPtr->interp = interp; bgPtr->signalNum = SIGTERM; bgPtr->nProcs = -1; bgPtr->interval = 1000; if (isDetached) { bgPtr->flags |= DETACHED; } bgPtr->statVar = Blt_AssertStrdup(Tcl_GetString(objv[1])); Tcl_MutexLock(mutexPtr); bgPtr->link = Blt_Chain_Append(activePipelines, bgPtr); Tcl_MutexUnlock(mutexPtr); bgPtr->out.encoding = ENCODING_ASCII; bgPtr->err.encoding = ENCODING_ASCII; /* Try to clean up any detached processes */ Tcl_ReapDetachedProcs(); i = Blt_ParseSwitches(interp, switchSpecs, objc - 2, objv + 2, bgPtr, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { FreeBgexec(bgPtr); return TCL_ERROR; } i += 2; /* Must be at least one argument left as the command to execute. */ if (objc <= i) { Tcl_AppendResult(interp, "missing command to execute: should be \"", Tcl_GetString(objv[0]), " varName ?options? command ?arg...?\"", (char *)NULL); FreeBgexec(bgPtr); return TCL_ERROR; } /* Put a trace on the exit status variable. The will also allow the user * to terminate the pipeline by simply setting the variable. */ Tcl_TraceVar(interp, bgPtr->statVar, TRACE_FLAGS, VariableProc, bgPtr); bgPtr->flags |= TRACED; InitSink(bgPtr, &bgPtr->out, "stdout"); InitSink(bgPtr, &bgPtr->err, "stderr"); outFdPtr = errFdPtr = (int *)NULL; #ifdef WIN32 if ((!isDetached) || (bgPtr->out.doneVar != NULL) || (bgPtr->out.updateVar != NULL) || (bgPtr->out.cmdObjPtr != NULL)) { outFdPtr = &bgPtr->out.fd; } #else outFdPtr = &bgPtr->out.fd; #endif if ((bgPtr->err.doneVar != NULL) || (bgPtr->err.updateVar != NULL) || (bgPtr->err.cmdObjPtr != NULL) || (bgPtr->err.echo)) { errFdPtr = &bgPtr->err.fd; } nProcs = Blt_CreatePipeline(interp, objc - i, objv + i, &pidPtr, (int *)NULL, outFdPtr, errFdPtr); if (nProcs < 0) { goto error; } bgPtr->procIds = pidPtr; bgPtr->nProcs = nProcs; if (bgPtr->out.fd == -1) { /* * If output has been redirected, start polling immediately for the * exit status of each process. Normally, this is done only after * stdout has been closed by the last process, but here stdout has * been redirected. The default polling interval is every 1 second. */ bgPtr->timerToken = Tcl_CreateTimerHandler(bgPtr->interval, TimerProc, bgPtr); } else if (CreateSinkHandler(bgPtr, &bgPtr->out, StdoutProc) != TCL_OK) { goto error; } if ((bgPtr->err.fd != -1) && (CreateSinkHandler(bgPtr, &bgPtr->err, StderrProc) != TCL_OK)) { goto error; } if (isDetached) { Tcl_Obj *listObjPtr; /* If detached, return a list of the child process ids instead of the * output of the pipeline. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (i = 0; i < nProcs; i++) { Tcl_Obj *objPtr; #ifdef WIN32 objPtr = Tcl_NewLongObj((unsigned int)bgPtr->procIds[i].pid); #else objPtr = Tcl_NewLongObj(bgPtr->procIds[i]); #endif Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else { int exitCode; int done; bgPtr->exitCodePtr = &exitCode; bgPtr->donePtr = &done; exitCode = done = 0; while (!done) { Tcl_DoOneEvent(0); } DisableTriggers(bgPtr); if ((bgPtr->flags & IGNOREEXITCODE) || (exitCode == 0)) { if (bgPtr->out.doneVar == NULL) { unsigned char *data; int length; /* Return the output of the pipeline. */ GetSinkData(&bgPtr->out, &data, &length); assert(length <= UINT_MAX); #if (_TCL_VERSION < _VERSION(8,1,0)) data[length] = '\0'; Tcl_SetObjResult(interp, Tcl_NewStringObj(data, length)); #else Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(data, length)); #endif } } else { DestroyBgexec(bgPtr); Tcl_AppendResult(interp, "child process exited abnormally", (char *)NULL); return TCL_ERROR; } DestroyBgexec(bgPtr); } return TCL_OK; error: DestroyBgexec(bgPtr); return TCL_ERROR; } static void BgexecExitProc(ClientData clientData) { Blt_ChainLink link, next; Tcl_MutexLock(mutexPtr); for (link = Blt_Chain_FirstLink(activePipelines); link != NULL; link = next) { next = Blt_Chain_NextLink(link); Bgexec *bgPtr; bgPtr = Blt_Chain_GetValue(link); bgPtr->link = NULL; KillProcesses(bgPtr); } Blt_Chain_Destroy(activePipelines); Tcl_MutexUnlock(mutexPtr); } /* *--------------------------------------------------------------------------- * * Blt_BgexecCmdInitProc -- * * This procedure is invoked to initialize the "bgexec" TCL command. See * the user documentation for details on what it does. * * Results: * None. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int Blt_BgexecCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "bgexec", BgexecCmd, }; if (activePipelines == NULL) { #ifdef TCL_THREADS mutexPtr = Tcl_GetAllocMutex(); #endif activePipelines = Blt_Chain_Create(); Tcl_CreateExitHandler(BgexecExitProc, activePipelines); } return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_BGEXEC */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBeep.c���������������������������������������������������������������������0000644�0001750�0001750�00000004772�11462120062�014560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBeep.c -- * * Copyright 1993-2003 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_BEEP /* *--------------------------------------------------------------------------- * * Blt_BeepCmd -- * * This procedure is invoked to process the "beep" command. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Tcl_ObjCmdProc BeepCmd; /* ARGSUSED */ static int BeepCmd( ClientData clientData, /* Main window associated with interpreter.*/ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { int percent; if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ?volumePercent?\"", (char *)NULL); return TCL_ERROR; } percent = 50; /* Default setting */ if (objc == 2) { if (Tcl_GetIntFromObj(interp, objv[1], &percent) != TCL_OK) { return TCL_ERROR; } if (percent < -100) { percent = -100; } else if (percent > 100) { percent = 100; } } XBell(Tk_Display(Tk_MainWindow(interp)), percent); return TCL_OK; } int Blt_BeepCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "beep", BeepCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_BEEP */ ������./saods9/blt3.0.1/src/bltGrPs.c���������������������������������������������������������������������0000644�0001750�0001750�00000054577�11462120062�014570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrPs.c -- * * This module implements the "postscript" operation for BLT graph widget. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* *--------------------------------------------------------------------------- * * PostScript routines to print a graph * *--------------------------------------------------------------------------- */ #include "bltGraph.h" #include "bltOp.h" #include "bltPsInt.h" #include "bltPicture.h" #include <X11/Xutil.h> #include "tkDisplay.h" #include <stdarg.h> #define MM_INCH 25.4 #define PICA_INCH 72.0 typedef int (GraphPsProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static Blt_OptionParseProc ObjToPicaProc; static Blt_OptionPrintProc PicaToObjProc; static Blt_CustomOption picaOption = { ObjToPicaProc, PicaToObjProc, NULL, (ClientData)0, }; static Blt_OptionParseProc ObjToPad; static Blt_OptionPrintProc PadToObj; static Blt_CustomOption padOption = { ObjToPad, PadToObj, NULL, (ClientData)0, }; #define DEF_PS_CENTER "yes" #define DEF_PS_COLOR_MAP (char *)NULL #define DEF_PS_GREYSCALE "no" #define DEF_PS_DECORATIONS "no" #define DEF_PS_FONT_MAP (char *)NULL #define DEF_PS_FOOTER "no" #define DEF_PS_LEVEL "2" #define DEF_PS_HEIGHT "0" #define DEF_PS_LANDSCAPE "no" #define DEF_PS_PADX "1.0i" #define DEF_PS_PADY "1.0i" #define DEF_PS_PAPERHEIGHT "11.0i" #define DEF_PS_PAPERWIDTH "8.5i" #define DEF_PS_WIDTH "0" #define DEF_PS_COMMENTS "" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BITMASK, "-center", "center", "Center", DEF_PS_CENTER, Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_CENTER}, {BLT_CONFIG_STRING, "-colormap", "colorMap", "ColorMap", DEF_PS_COLOR_MAP, Blt_Offset(PageSetup, colorVarName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-comments", "comments", "Comments", DEF_PS_COMMENTS, Blt_Offset(PageSetup, comments), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-decorations", "decorations", "Decorations", DEF_PS_DECORATIONS, Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_DECORATIONS}, {BLT_CONFIG_STRING, "-fontmap", "fontMap", "FontMap", DEF_PS_FONT_MAP, Blt_Offset(PageSetup, fontVarName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-footer", "footer", "Footer", DEF_PS_FOOTER, Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_FOOTER}, {BLT_CONFIG_BITMASK, "-greyscale", "greyscale", "Greyscale", DEF_PS_GREYSCALE, Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_GREYSCALE}, {BLT_CONFIG_CUSTOM, "-height", "height", "Height", DEF_PS_HEIGHT, Blt_Offset(PageSetup, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT, &picaOption}, {BLT_CONFIG_BITMASK, "-landscape", "landscape", "Landscape", DEF_PS_LANDSCAPE, Blt_Offset(PageSetup, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)PS_LANDSCAPE}, {BLT_CONFIG_INT_POS, "-level", "level", "Level", DEF_PS_LEVEL, Blt_Offset(PageSetup, level), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-padx", "padX", "PadX", DEF_PS_PADX, Blt_Offset(PageSetup, xPad), 0, &padOption}, {BLT_CONFIG_CUSTOM, "-pady", "padY", "PadY", DEF_PS_PADY, Blt_Offset(PageSetup, yPad), 0, &padOption}, {BLT_CONFIG_CUSTOM, "-paperheight", "paperHeight", "PaperHeight", DEF_PS_PAPERHEIGHT, Blt_Offset(PageSetup, reqPaperHeight), 0, &picaOption}, {BLT_CONFIG_CUSTOM, "-paperwidth", "paperWidth", "PaperWidth", DEF_PS_PAPERWIDTH, Blt_Offset(PageSetup, reqPaperWidth), 0, &picaOption}, {BLT_CONFIG_CUSTOM, "-width", "width", "Width", DEF_PS_WIDTH, Blt_Offset(PageSetup, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT, &picaOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* *--------------------------------------------------------------------------- * * ObjToPicaProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPicaProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New value. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *picaPtr = (int *)(widgRec + offset); return Blt_Ps_GetPicaFromObj(interp, objPtr, picaPtr); } /* *--------------------------------------------------------------------------- * * PicaToObj -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PicaToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* PostScript structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int pica = *(int *)(widgRec + offset); return Tcl_NewIntObj(pica); } /* *--------------------------------------------------------------------------- * * ObjToPad -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPad( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New value. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Pad *padPtr = (Blt_Pad *) (widgRec + offset); return Blt_Ps_GetPadFromObj(interp, objPtr, padPtr); } /* *--------------------------------------------------------------------------- * * PadToObj -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PadToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* PostScript structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset); Tcl_Obj *objPtr, *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); objPtr = Tcl_NewIntObj(padPtr->side1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(padPtr->side2); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); return listObjPtr; } static void AddComments(Blt_Ps ps, const char **comments) { const char **p; for (p = comments; *p != NULL; p += 2) { if (*(p+1) == NULL) { break; } Blt_Ps_Format(ps, "%% %s: %s\n", *p, *(p+1)); } } /* *--------------------------------------------------------------------------- * * PostScriptPreamble * * The PostScript preamble calculates the needed translation and scaling * to make X11 coordinates compatible with PostScript. * *--------------------------------------------------------------------------- */ #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #endif /* TIME_WITH_SYS_TIME */ static int PostScriptPreamble(Graph *graphPtr, const char *fileName, Blt_Ps ps) { PageSetup *setupPtr = graphPtr->pageSetup; time_t ticks; char date[200]; /* Holds the date string from ctime() */ const char *version; char *newline; if (fileName == NULL) { fileName = Tk_PathName(graphPtr->tkwin); } Blt_Ps_Append(ps, "%!PS-Adobe-3.0 EPSF-3.0\n"); /* * The "BoundingBox" comment is required for EPS files. The box * coordinates are integers, so we need round away from the center of the * box. */ Blt_Ps_Format(ps, "%%%%BoundingBox: %d %d %d %d\n", setupPtr->left, setupPtr->paperHeight - setupPtr->top, setupPtr->right, setupPtr->paperHeight - setupPtr->bottom); Blt_Ps_Append(ps, "%%Pages: 0\n"); version = Tcl_GetVar(graphPtr->interp, "blt_version", TCL_GLOBAL_ONLY); if (version == NULL) { version = "???"; } Blt_Ps_Format(ps, "%%%%Creator: (BLT %s %s)\n", version, Tk_Class(graphPtr->tkwin)); ticks = time((time_t *) NULL); strcpy(date, ctime(&ticks)); newline = date + strlen(date) - 1; if (*newline == '\n') { *newline = '\0'; } Blt_Ps_Format(ps, "%%%%CreationDate: (%s)\n", date); Blt_Ps_Format(ps, "%%%%Title: (%s)\n", fileName); Blt_Ps_Append(ps, "%%DocumentData: Clean7Bit\n"); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Append(ps, "%%Orientation: Landscape\n"); } else { Blt_Ps_Append(ps, "%%Orientation: Portrait\n"); } Blt_Ps_Append(ps, "%%DocumentNeededResources: font Helvetica Courier\n"); AddComments(ps, setupPtr->comments); Blt_Ps_Append(ps, "%%EndComments\n\n"); if (Blt_Ps_IncludeFile(graphPtr->interp, ps, "bltGraph.pro") != TCL_OK) { return TCL_ERROR; } if (setupPtr->flags & PS_FOOTER) { const char *who; who = getenv("LOGNAME"); if (who == NULL) { who = "???"; } Blt_Ps_VarAppend(ps, "8 /Helvetica SetFont\n", "10 30 moveto\n", "(Date: ", date, ") show\n", "10 20 moveto\n", "(File: ", fileName, ") show\n", "10 10 moveto\n", "(Created by: ", who, "@", Tcl_GetHostName(), ") show\n", "0 0 moveto\n", (char *)NULL); } /* * Set the conversion from PostScript to X11 coordinates. Scale pica to * pixels and flip the y-axis (the origin is the upperleft corner). */ Blt_Ps_VarAppend(ps, "% Transform coordinate system to use X11 coordinates\n\n", "% 1. Flip y-axis over by reversing the scale,\n", "% 2. Translate the origin to the other side of the page,\n", "% making the origin the upper left corner\n", (char *)NULL); Blt_Ps_Format(ps, "1 -1 scale\n"); /* Papersize is in pixels. Translate the new origin *after* changing the * scale. */ Blt_Ps_Format(ps, "0 %d translate\n\n", -setupPtr->paperHeight); Blt_Ps_VarAppend(ps, "% User defined page layout\n\n", "% Set color level\n", (char *)NULL); Blt_Ps_Format(ps, "%% Set origin\n%d %d translate\n\n", setupPtr->left, setupPtr->bottom); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Format(ps, "%% Landscape orientation\n0 %g translate\n-90 rotate\n", ((double)graphPtr->width * setupPtr->scale)); } #ifdef notdef if (setupPtr->scale != 1.0f) { Blt_Ps_Append(ps, "\n% Setting graph scale factor\n"); Blt_Ps_Format(ps, " %g %g scale\n", setupPtr->scale, setupPtr->scale); } #endif Blt_Ps_Append(ps, "\n%%EndSetup\n\n"); return TCL_OK; } static void MarginsToPostScript(Graph *graphPtr, Blt_Ps ps) { PageSetup *setupPtr = graphPtr->pageSetup; XRectangle margin[4]; margin[0].x = margin[0].y = margin[3].x = margin[1].x = 0; margin[0].width = margin[3].width = graphPtr->width; margin[0].height = graphPtr->top; margin[3].y = graphPtr->bottom; margin[3].height = graphPtr->height - graphPtr->bottom; margin[2].y = margin[1].y = graphPtr->top; margin[1].width = graphPtr->left; margin[2].height = margin[1].height = graphPtr->bottom - graphPtr->top; margin[2].x = graphPtr->right; margin[2].width = graphPtr->width - graphPtr->right; /* Clear the surrounding margins and clip the plotting surface */ if (setupPtr->flags & PS_DECORATIONS) { Blt_Ps_XSetBackground(ps,Blt_BackgroundBorderColor(graphPtr->normalBg)); } else { Blt_Ps_SetClearBackground(ps); } Blt_Ps_Append(ps, "% Margins\n"); Blt_Ps_XFillRectangles(ps, margin, 4); Blt_Ps_Append(ps, "% Interior 3D border\n"); /* Interior 3D border */ if (graphPtr->plotBW > 0) { Tk_3DBorder border; int x, y, w, h; x = graphPtr->left - graphPtr->plotBW; y = graphPtr->top - graphPtr->plotBW; w = (graphPtr->right - graphPtr->left) + (2*graphPtr->plotBW); h = (graphPtr->bottom - graphPtr->top) + (2*graphPtr->plotBW); border = Blt_BackgroundBorder(graphPtr->normalBg); Blt_Ps_Draw3DRectangle(ps, border, (double)x, (double)y, w, h, graphPtr->plotBW, graphPtr->plotRelief); } if (Blt_Legend_Site(graphPtr) & LEGEND_MARGIN_MASK) { /* * Print the legend if we're using a site which lies in one of the * margins (left, right, top, or bottom) of the graph. */ Blt_LegendToPostScript(graphPtr, ps); } if (graphPtr->title != NULL) { Blt_Ps_Append(ps, "% Graph title\n"); Blt_Ps_DrawText(ps, graphPtr->title, &graphPtr->titleTextStyle, (double)graphPtr->titleX, (double)graphPtr->titleY); } Blt_AxesToPostScript(graphPtr, ps); } static int GraphToPostScript(Graph *graphPtr, const char *ident, Blt_Ps ps) { int x, y, w, h; int result; PageSetup *setupPtr = graphPtr->pageSetup; /* * We need to know how big a graph to print. If the graph hasn't been drawn * yet, the width and height will be 1. Instead use the requested size of * the widget. The user can still override this with the -width and -height * postscript options. */ if (setupPtr->reqWidth > 0) { graphPtr->width = setupPtr->reqWidth; } else if (graphPtr->width < 2) { graphPtr->width = Tk_ReqWidth(graphPtr->tkwin); } if (setupPtr->reqHeight > 0) { graphPtr->height = setupPtr->reqHeight; } else if (graphPtr->height < 2) { graphPtr->height = Tk_ReqHeight(graphPtr->tkwin); } Blt_Ps_ComputeBoundingBox(setupPtr, graphPtr->width, graphPtr->height); graphPtr->flags |= LAYOUT_NEEDED | RESET_WORLD; /* Turn on PostScript measurements when computing the graph's layout. */ Blt_Ps_SetPrinting(ps, TRUE); Blt_ReconfigureGraph(graphPtr); Blt_MapGraph(graphPtr); result = PostScriptPreamble(graphPtr, ident, ps); if (result != TCL_OK) { goto error; } /* Determine rectangle of the plotting area for the graph window */ x = graphPtr->left - graphPtr->plotBW; y = graphPtr->top - graphPtr->plotBW; w = (graphPtr->right - graphPtr->left + 1) + (2*graphPtr->plotBW); h = (graphPtr->bottom - graphPtr->top + 1) + (2*graphPtr->plotBW); Blt_Ps_XSetFont(ps, Blt_Ts_GetFont(graphPtr->titleTextStyle)); if (graphPtr->pageSetup->flags & PS_DECORATIONS) { Blt_Ps_XSetBackground(ps, Blt_BackgroundBorderColor(graphPtr->plotBg)); } else { Blt_Ps_SetClearBackground(ps); } Blt_Ps_XFillRectangle(ps, x, y, w, h); Blt_Ps_Rectangle(ps, x, y, w, h); Blt_Ps_Append(ps, "gsave clip\n\n"); /* Draw the grid, elements, and markers in the plotting area. */ Blt_GridsToPostScript(graphPtr, ps); Blt_MarkersToPostScript(graphPtr, ps, TRUE); if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && (!Blt_Legend_IsRaised(graphPtr))) { /* Print legend underneath elements and markers */ Blt_LegendToPostScript(graphPtr, ps); } Blt_AxisLimitsToPostScript(graphPtr, ps); Blt_ElementsToPostScript(graphPtr, ps); if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && (Blt_Legend_IsRaised(graphPtr))) { /* Print legend above elements (but not markers) */ Blt_LegendToPostScript(graphPtr, ps); } Blt_MarkersToPostScript(graphPtr, ps, FALSE); Blt_ActiveElementsToPostScript(graphPtr, ps); Blt_Ps_VarAppend(ps, "\n", "% Unset clipping\n", "grestore\n\n", (char *)NULL); MarginsToPostScript(graphPtr, ps); Blt_Ps_VarAppend(ps, "showpage\n", "%Trailer\n", "grestore\n", "end\n", "%EOF\n", (char *)NULL); error: /* Reset height and width of graph window */ graphPtr->width = Tk_Width(graphPtr->tkwin); graphPtr->height = Tk_Height(graphPtr->tkwin); graphPtr->flags |= MAP_WORLD; Blt_Ps_SetPrinting(ps, FALSE); Blt_ReconfigureGraph(graphPtr); Blt_MapGraph(graphPtr); /* * Redraw the graph in order to re-calculate the layout as soon as * possible. This is in the case the crosshairs are active. */ Blt_EventuallyRedrawGraph(graphPtr); return result; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PageSetup *setupPtr = graphPtr->pageSetup; if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, (char *)setupPtr, objv[3], 0) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is invoked to print the graph in a file. * * Results: * A standard TCL result. * * Side effects: * A new PostScript file is created. * *--------------------------------------------------------------------------- */ static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int flags = BLT_CONFIG_OBJV_ONLY; PageSetup *setupPtr = graphPtr->pageSetup; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)setupPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)setupPtr, objv[3], flags); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)setupPtr, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * OutputOp -- * * This procedure is invoked to print the graph in a file. * * Results: * Standard TCL result. TCL_OK if plot was successfully printed, * TCL_ERROR otherwise. * * Side effects: * A new PostScript file is created. * *--------------------------------------------------------------------------- */ static int OutputOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *buffer; PostScript *psPtr; Tcl_Channel channel; const char *fileName; /* Name of file to write PostScript * output If NULL, output is returned * via interp->result. */ int length; fileName = NULL; /* Used to identify the output sink. */ channel = NULL; if (objc > 3) { fileName = Tcl_GetString(objv[3]); if (fileName[0] != '-') { objv++, objc--; /* First argument is the file name. */ channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { return TCL_ERROR; } if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") != TCL_OK) { return TCL_ERROR; } } } psPtr = Blt_Ps_Create(graphPtr->interp, graphPtr->pageSetup); if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)graphPtr->pageSetup, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if (GraphToPostScript(graphPtr, fileName, psPtr) != TCL_OK) { goto error; } buffer = Blt_Ps_GetValue(psPtr, &length); if (channel != NULL) { int nBytes; /* * If a file name was given, write the results to that file */ nBytes = Tcl_Write(channel, buffer, length); if (nBytes < 0) { Tcl_AppendResult(interp, "error writing file \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); goto error; } Tcl_Close(interp, channel); } else { Tcl_SetStringObj(Tcl_GetObjResult(interp), buffer, length); } Blt_Ps_Free(psPtr); return TCL_OK; error: if (channel != NULL) { Tcl_Close(interp, channel); } Blt_Ps_Free(psPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * Blt_CreatePostScript -- * * Creates a postscript structure. * * Results: * Always TCL_OK. * * Side effects: * A new PostScript structure is created. * *--------------------------------------------------------------------------- */ int Blt_CreatePageSetup(Graph *graphPtr) { PageSetup *setupPtr; setupPtr = Blt_AssertCalloc(1, sizeof(PostScript)); setupPtr->flags = PS_CENTER; setupPtr->level = 2; graphPtr->pageSetup = setupPtr; if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, "postscript", "Postscript", configSpecs, 0, (Tcl_Obj **)NULL, (char *)setupPtr, 0) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_PostScriptOp -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec psOps[] = { {"cget", 2, CgetOp, 4, 4, "option",}, {"configure", 2, ConfigureOp, 3, 0, "?option value?...",}, {"output", 1, OutputOp, 3, 0, "?fileName? ?option value?...",}, }; static int nPsOps = sizeof(psOps) / sizeof(Blt_OpSpec); int Blt_PostScriptOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphPsProc *proc; int result; proc = Blt_GetOpFromObj(interp, nPsOps, psOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (graphPtr, interp, objc, objv); return result; } void Blt_DestroyPageSetup(Graph *graphPtr) { if (graphPtr->pageSetup != NULL) { Blt_FreeOptions(configSpecs, (char *)graphPtr->pageSetup, graphPtr->display, 0); Blt_Free(graphPtr->pageSetup); } } ���������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltImage.c��������������������������������������������������������������������0000644�0001750�0001750�00000011674�11462120062�014726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltImage.c -- * * This module implements image processing procedures for the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltImage.h" #include <X11/Xutil.h> /* * Each call to Tk_GetImage returns a pointer to one of the following * structures, which is used as a token by clients (widgets) that display * images. */ typedef struct _TkImage { Tk_Window tkwin; /* Window passed to Tk_GetImage (needed * to "re-get" the image later if the * * manager changes). */ Display *display; /* Display for tkwin. Needed because * when the image is eventually freed * tkwin may not exist anymore. */ struct _TkImageMaster *masterPtr; /* Master for this image (identifiers * image manager, for example). */ ClientData instanceData; /* One word argument to pass to image * manager when dealing with this image * instance. */ Tk_ImageChangedProc *changeProc; /* Code in widget to call when image * changes in a way that affects * redisplay. */ ClientData widgetClientData; /* Argument to pass to changeProc. */ struct _TkImage *nextPtr; /* Next in list of all image instances * associated with the same name. */ } TkImage; /* * For each image master there is one of the following structures, which * represents a name in the image table and all of the images instantiated from * it. Entries in mainPtr->imageTable point to these structures. */ typedef struct _TkImageMaster { Tk_ImageType *typePtr; /* Information about image type. NULL * means that no image manager owns this * image: the image was deleted. */ ClientData masterData; /* One-word argument to pass to image * mgr when dealing with the master, as * opposed to instances. */ int width, height; /* Last known dimensions for image. */ void *tablePtr; /* Pointer to hash table containing * image (the imageTable field in some * TkMainInfo structure). */ void *hPtr; /* Hash entry in mainPtr->imageTable for * this structure (used to delete the * hash entry). */ void *instancePtr; /* Pointer to first in list of instances * derived from this name. */ int deleted; /* Flag set when image is being * deleted. */ Tk_Window tkwin; /* Main window of interpreter (used to * detect when the world is falling * apart.) */ } TkImageMaster; /* *--------------------------------------------------------------------------- * * Blt_Image_IsDeleted -- * * Is there any other way to determine if an image has been deleted? * * Results: * Returns 1 if the image has been deleted, 0 otherwise. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_Image_IsDeleted(Tk_Image tkImage) /* Token for image. */ { TkImage *imagePtr = (TkImage *) tkImage; if (imagePtr->masterPtr == NULL) { return TRUE; } return (imagePtr->masterPtr->typePtr == NULL); } /*LINTLIBRARY*/ Tk_ImageMaster Blt_Image_GetMaster(Tk_Image tkImage) /* Token for image. */ { TkImage *imagePtr = (TkImage *)tkImage; return (Tk_ImageMaster)imagePtr->masterPtr; } /*LINTLIBRARY*/ ClientData Blt_Image_GetInstanceData(Tk_Image tkImage) /* Token for image. */ { TkImage *imagePtr = (TkImage *)tkImage; return imagePtr->instanceData; } /*LINTLIBRARY*/ Tk_ImageType * Blt_Image_GetType(Tk_Image tkImage) /* Token for image. */ { TkImageMaster *masterPtr; masterPtr = (TkImageMaster *)Blt_Image_GetMaster(tkImage); return masterPtr->typePtr; } const char * Blt_Image_Name(Tk_Image tkImage) { Tk_ImageMaster master; master = Blt_Image_GetMaster(tkImage); return Tk_NameOfImage(master); } const char * Blt_Image_NameOfType(Tk_Image tkImage) { TkImageMaster *masterPtr; masterPtr = (TkImageMaster *)Blt_Image_GetMaster(tkImage); return masterPtr->typePtr->name; } ��������������������������������������������������������������������./saods9/blt3.0.1/src/bltVecMath.c������������������������������������������������������������������0000644�0001750�0001750�00000130032�11462120063�015222� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVecMath.c -- * * This module implements mathematical expressions with vector data * objects. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltVecInt.h" #include "bltNsUtil.h" #include "bltParse.h" /* * Three types of math functions: * * ComponentProc Function is applied in multiple calls to * each component of the vector. * VectorProc Entire vector is passed, each component is * modified. * ScalarProc Entire vector is passed, single scalar value * is returned. */ typedef double (ComponentProc)(double value); typedef int (VectorProc)(Vector *vPtr); typedef double (ScalarProc)(Vector *vPtr); /* * Built-in math functions: */ typedef int (GenericMathProc) _ANSI_ARGS_(ANYARGS); /* * MathFunction -- * * Contains information about math functions that can be called * for vectors. The table of math functions is global within the * application. So you can't define two different "sqrt" * functions. */ typedef struct { const char *name; /* Name of built-in math function. If * NULL, indicates that the function * was user-defined and dynamically * allocated. Function names are * global across all interpreters. */ void *proc; /* Procedure that implements this math * function. */ ClientData clientData; /* Argument to pass when invoking the * function. */ } MathFunction; /* * Macros for testing floating-point values for certain special cases: * * IS_NAN Test for not-a-number by comparing a value against itself * IF_INF Test for infinity by comparing against the largest floating * point value. */ #define IS_NAN(v) ((v) != (v)) #ifdef DBL_MAX # define IS_INF(v) (((v) > DBL_MAX) || ((v) < -DBL_MAX)) #else # define IS_INF(v) 0 #endif /* The data structure below is used to describe an expression value, * which can be either a double-precision floating-point value, or a * string. A given number has only one value at a time. */ #define STATIC_STRING_SPACE 150 /* * Tokens -- * * The token types are defined below. In addition, there is a * table associating a precedence with each operator. The order * of types is important. Consult the code before changing it. */ enum Tokens { VALUE, OPEN_PAREN, CLOSE_PAREN, COMMA, END, UNKNOWN, MULT = 8, DIVIDE, MOD, PLUS, MINUS, LEFT_SHIFT, RIGHT_SHIFT, LESS, GREATER, LEQ, GEQ, EQUAL, NEQ, OLD_BIT_AND, EXPONENT, OLD_BIT_OR, OLD_QUESTY, OLD_COLON, AND, OR, UNARY_MINUS, OLD_UNARY_PLUS, NOT, OLD_BIT_NOT }; typedef struct { Vector *vPtr; char staticSpace[STATIC_STRING_SPACE]; ParseValue pv; /* Used to hold a string value, if any. */ } Value; /* * ParseInfo -- * * The data structure below describes the state of parsing an * expression. It's passed among the routines in this module. */ typedef struct { const char *expr; /* The entire right-hand side of the * expression, as originally passed to * Blt_ExprVector. */ const char *nextPtr; /* Position of the next character to * be scanned from the expression * string. */ enum Tokens token; /* Type of the last token to be parsed * from nextPtr. See below for * definitions. Corresponds to the * characters just before nextPtr. */ } ParseInfo; /* * Precedence table. The values for non-operator token types are ignored. */ static int precTable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, /* MULT, DIVIDE, MOD */ 11, 11, /* PLUS, MINUS */ 10, 10, /* LEFT_SHIFT, RIGHT_SHIFT */ 9, 9, 9, 9, /* LESS, GREATER, LEQ, GEQ */ 8, 8, /* EQUAL, NEQ */ 7, /* OLD_BIT_AND */ 13, /* EXPONENTIATION */ 5, /* OLD_BIT_OR */ 4, /* AND */ 3, /* OR */ 2, /* OLD_QUESTY */ 1, /* OLD_COLON */ 14, 14, 14, 14 /* UNARY_MINUS, OLD_UNARY_PLUS, NOT, * OLD_BIT_NOT */ }; /* * Forward declarations. */ static int NextValue(Tcl_Interp *interp, ParseInfo *piPtr, int prec, Value *valuePtr); #include <bltMath.h> /* *--------------------------------------------------------------------------- * * Sort -- * * A vector math function. Sorts the values of the given * vector. * * Results: * Always TCL_OK. * * Side Effects: * The vector is sorted. * *--------------------------------------------------------------------------- */ static int Sort(Vector *vPtr) { size_t *map; double *values; int i; map = Blt_Vec_SortMap(&vPtr, 1); values = Blt_AssertMalloc(sizeof(double) * vPtr->length); for(i = vPtr->first; i <= vPtr->last; i++) { values[i] = vPtr->valueArr[map[i]]; } Blt_Free(map); for (i = vPtr->first; i <= vPtr->last; i++) { vPtr->valueArr[i] = values[i]; } Blt_Free(values); return TCL_OK; } static double Length(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; return (double)(vPtr->last - vPtr->first + 1); } double Blt_VecMax(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; return Blt_Vec_Max(vPtr); } double Blt_VecMin(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; return Blt_Vec_Min(vPtr); } static double Product(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double prod; double *vp, *vend; prod = 1.0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { prod *= *vp; } return prod; } static double Sum(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double sum, c; double *vp, *vend; /* Kahan summation algorithm */ vp = vPtr->valueArr + vPtr->first; sum = *vp++; c = 0.0; /* A running compensation for lost * low-order bits.*/ for (vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { double y, t; y = *vp - c; /* So far, so good: c is zero.*/ t = sum + y; /* Alas, sum is big, y small, so * low-order digits of y are lost.*/ c = (t - sum) - y; /* (t - sum) recovers the high-order * part of y; subtracting y recovers * -(low part of y) */ sum = t; } return sum; } static double Mean(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double sum; int n; sum = Sum(vectorPtr); n = vPtr->last - vPtr->first + 1; return sum / (double)n; } /* * var = 1/N Sum( (x[i] - mean)^2 ) */ static double Variance(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double var, mean; double *vp, *vend; int count; mean = Mean(vectorPtr); var = 0.0; count = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { double dx; dx = *vp - mean; var += dx * dx; count++; } if (count < 2) { return 0.0; } var /= (double)(count - 1); return var; } /* * skew = Sum( (x[i] - mean)^3 ) / (var^3/2) */ static double Skew(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double diff, var, skew, mean, diffsq; double *vp, *vend; int count; mean = Mean(vectorPtr); var = skew = 0.0; count = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { diff = *vp - mean; diff = FABS(diff); diffsq = diff * diff; var += diffsq; skew += diffsq * diff; count++; } if (count < 2) { return 0.0; } var /= (double)(count - 1); skew /= count * var * sqrt(var); return skew; } static double StdDeviation(Blt_Vector *vectorPtr) { double var; var = Variance(vectorPtr); if (var > 0.0) { return sqrt(var); } return 0.0; } static double AvgDeviation(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double diff, avg, mean; double *vp, *vend; int count; mean = Mean(vectorPtr); avg = 0.0; count = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { diff = *vp - mean; avg += FABS(diff); count++; } if (count < 2) { return 0.0; } avg /= (double)count; return avg; } static double Kurtosis(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double diff, diffsq, kurt, var, mean; double *vp, *vend; int count; mean = Mean(vectorPtr); var = kurt = 0.0; count = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { diff = *vp - mean; diffsq = diff * diff; var += diffsq; kurt += diffsq * diffsq; count++; } if (count < 2) { return 0.0; } var /= (double)(count - 1); if (var == 0.0) { return 0.0; } kurt /= (count * var * var); return kurt - 3.0; /* Fisher Kurtosis */ } static double Median(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; size_t *map; double q2; int mid; if (vPtr->length == 0) { return -DBL_MAX; } map = Blt_Vec_SortMap(&vPtr, 1); mid = (vPtr->length - 1) / 2; /* * Determine Q2 by checking if the number of elements [0..n-1] is * odd or even. If even, we must take the average of the two * middle values. */ if (vPtr->length & 1) { /* Odd */ q2 = vPtr->valueArr[map[mid]]; } else { /* Even */ q2 = (vPtr->valueArr[map[mid]] + vPtr->valueArr[map[mid + 1]]) * 0.5; } Blt_Free(map); return q2; } static double Q1(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double q1; size_t *map; if (vPtr->length == 0) { return -DBL_MAX; } map = Blt_Vec_SortMap(&vPtr, 1); if (vPtr->length < 4) { q1 = vPtr->valueArr[map[0]]; } else { int mid, q; mid = (vPtr->length - 1) / 2; q = mid / 2; /* * Determine Q1 by checking if the number of elements in the * bottom half [0..mid) is odd or even. If even, we must * take the average of the two middle values. */ if (mid & 1) { /* Odd */ q1 = vPtr->valueArr[map[q]]; } else { /* Even */ q1 = (vPtr->valueArr[map[q]] + vPtr->valueArr[map[q + 1]]) * 0.5; } } Blt_Free(map); return q1; } static double Q3(Blt_Vector *vectorPtr) { Vector *vPtr = (Vector *)vectorPtr; double q3; size_t *map; if (vPtr->length == 0) { return -DBL_MAX; } map = Blt_Vec_SortMap(&vPtr, 1); if (vPtr->length < 4) { q3 = vPtr->valueArr[map[vPtr->length - 1]]; } else { int mid, q; mid = (vPtr->length - 1) / 2; q = (vPtr->length + mid) / 2; /* * Determine Q3 by checking if the number of elements in the * upper half (mid..n-1] is odd or even. If even, we must * take the average of the two middle values. */ if (mid & 1) { /* Odd */ q3 = vPtr->valueArr[map[q]]; } else { /* Even */ q3 = (vPtr->valueArr[map[q]] + vPtr->valueArr[map[q + 1]]) * 0.5; } } Blt_Free(map); return q3; } static int Norm(Blt_Vector *vector) { Vector *vPtr = (Vector *)vector; double norm, range, min, max; int i; min = Blt_Vec_Min(vPtr); max = Blt_Vec_Max(vPtr); range = max - min; for (i = 0; i < vPtr->length; i++) { norm = (vPtr->valueArr[i] - min) / range; vPtr->valueArr[i] = norm; } return TCL_OK; } static double Nonzeros(Blt_Vector *vector) { Vector *vPtr = (Vector *)vector; int count; double *vp, *vend; count = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { if (*vp == 0.0) { count++; } } return (double) count; } static double Fabs(double value) { if (value < 0.0) { return -value; } return value; } static double Round(double value) { if (value < 0.0) { return ceil(value - 0.5); } else { return floor(value + 0.5); } } static double Fmod(double x, double y) { if (y == 0.0) { return 0.0; } return x - (floor(x / y) * y); } /* *--------------------------------------------------------------------------- * * MathError -- * * This procedure is called when an error occurs during a * floating-point operation. It reads errno and sets * interp->result accordingly. * * Results: * Interp->result is set to hold an error message. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void MathError( Tcl_Interp *interp, /* Where to store error message. */ double value) /* Value returned after error; used to * distinguish underflows from * overflows. */ { if ((errno == EDOM) || (value != value)) { Tcl_AppendResult(interp, "domain error: argument not in valid range", (char *)NULL); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", interp->result, (char *)NULL); } else if ((errno == ERANGE) || IS_INF(value)) { if (value == 0.0) { Tcl_AppendResult(interp, "floating-point value too small to represent", (char *)NULL); Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", interp->result, (char *)NULL); } else { Tcl_AppendResult(interp, "floating-point value too large to represent", (char *)NULL); Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", interp->result, (char *)NULL); } } else { Tcl_AppendResult(interp, "unknown floating-point error, ", "errno = ", Blt_Itoa(errno), (char *)NULL); Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", interp->result, (char *)NULL); } } /* *--------------------------------------------------------------------------- * * ParseString -- * * Given a string (such as one coming from command or variable * substitution), make a Value based on the string. The value * will be a floating-point or integer, if possible, or else it * will just be a copy of the string. * * Results: * TCL_OK is returned under normal circumstances, and TCL_ERROR * is returned if a floating-point overflow or underflow occurred * while reading in a number. The value at *valuePtr is modified * to hold a number, if possible. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ParseString( Tcl_Interp *interp, /* Where to store error message. */ const char *string, /* String to turn into value. */ Value *valuePtr) /* Where to store value information. * Caller must have initialized pv field. */ { const char *endPtr; double value; errno = 0; /* * The string can be either a number or a vector. First try to * convert the string to a number. If that fails then see if * we can find a vector by that name. */ value = strtod(string, (char **)&endPtr); if ((endPtr != string) && (*endPtr == '\0')) { if (errno != 0) { Tcl_ResetResult(interp); MathError(interp, value); return TCL_ERROR; } /* Numbers are stored as single element vectors. */ if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { return TCL_ERROR; } valuePtr->vPtr->valueArr[0] = value; return TCL_OK; } else { Vector *vPtr; while (isspace(UCHAR(*string))) { string++; /* Skip spaces leading the vector name. */ } vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, string, &endPtr, NS_SEARCH_BOTH); if (vPtr == NULL) { return TCL_ERROR; } if (*endPtr != '\0') { Tcl_AppendResult(interp, "extra characters after vector", (char *)NULL); return TCL_ERROR; } /* Copy the designated vector to our temporary. */ Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ParseMathFunction -- * * This procedure is invoked to parse a math function from an * expression string, carry out the function, and return the * value computed. * * Results: * TCL_OK is returned if all went well and the function's value * was computed successfully. If the name doesn't match any * known math function, returns TCL_RETURN. And if a format error * was found, TCL_ERROR is returned and an error message is left * in interp->result. * * After a successful return piPtr will be updated to point to * the character just after the function call, the token is set * to VALUE, and the value is stored in valuePtr. * * Side effects: * Embedded commands could have arbitrary side-effects. * *--------------------------------------------------------------------------- */ static int ParseMathFunction( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ const char *start, /* Start of string to parse */ ParseInfo *piPtr, /* Describes the state of the parse. * piPtr->nextPtr must point to the * first character of the function's * name. */ Value *valuePtr) /* Where to store value, if that is * what's parsed from string. Caller * must have initialized pv field * correctly. */ { Blt_HashEntry *hPtr; MathFunction *mathPtr; /* Info about math function. */ char *p; VectorInterpData *dataPtr; /* Interpreter-specific data. */ GenericMathProc *proc; /* * Find the end of the math function's name and lookup the * record for the function. */ p = (char *)start; while (isspace(UCHAR(*p))) { p++; } piPtr->nextPtr = p; while (isalnum(UCHAR(*p)) || (*p == '_')) { p++; } if (*p != '(') { return TCL_RETURN; /* Must start with open parenthesis */ } dataPtr = valuePtr->vPtr->dataPtr; *p = '\0'; hPtr = Blt_FindHashEntry(&dataPtr->mathProcTable, piPtr->nextPtr); *p = '('; if (hPtr == NULL) { return TCL_RETURN; /* Name doesn't match any known function */ } /* Pick up the single value as the argument to the function */ piPtr->token = OPEN_PAREN; piPtr->nextPtr = p + 1; valuePtr->pv.next = valuePtr->pv.buffer; if (NextValue(interp, piPtr, -1, valuePtr) != TCL_OK) { return TCL_ERROR; /* Parse error */ } if (piPtr->token != CLOSE_PAREN) { Tcl_AppendResult(interp, "unmatched parentheses in expression \"", piPtr->expr, "\"", (char *)NULL); return TCL_ERROR; /* Missing right parenthesis */ } mathPtr = Blt_GetHashValue(hPtr); proc = mathPtr->proc; if ((*proc) (mathPtr->clientData, interp, valuePtr->vPtr) != TCL_OK) { return TCL_ERROR; /* Function invocation error */ } piPtr->token = VALUE; return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextToken -- * * Lexical analyzer for expression parser: parses a single value, * operator, or other syntactic element from an expression string. * * Results: * TCL_OK is returned unless an error occurred while doing lexical * analysis or executing an embedded command. In that case a * standard TCL error is returned, using interp->result to hold * an error message. In the event of a successful return, the token * and field in piPtr is updated to refer to the next symbol in * the expression string, and the expr field is advanced past that * token; if the token is a value, then the value is stored at * valuePtr. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int NextToken( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ ParseInfo *piPtr, /* Describes the state of the parse. */ Value *valuePtr) /* Where to store value, if that is * what's parsed from string. Caller * must have initialized pv field * correctly. */ { const char *p; const char *endPtr; const char *var; int result; p = piPtr->nextPtr; while (isspace(UCHAR(*p))) { p++; } if (*p == '\0') { piPtr->token = END; piPtr->nextPtr = p; return TCL_OK; } /* * Try to parse the token as a floating-point number. But check * that the first character isn't a "-" or "+", which "strtod" * will happily accept as an unary operator. Otherwise, we might * accidently treat a binary operator as unary by mistake, which * will eventually cause a syntax error. */ if ((*p != '-') && (*p != '+')) { double value; errno = 0; value = strtod(p, (char **)&endPtr); if (endPtr != p) { if (errno != 0) { MathError(interp, value); return TCL_ERROR; } piPtr->token = VALUE; piPtr->nextPtr = endPtr; /* * Save the single floating-point value as an 1-component vector. */ if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { return TCL_ERROR; } valuePtr->vPtr->valueArr[0] = value; return TCL_OK; } } piPtr->nextPtr = p + 1; switch (*p) { case '$': piPtr->token = VALUE; var = Tcl_ParseVar(interp, p, &endPtr); if (var == NULL) { return TCL_ERROR; } piPtr->nextPtr = endPtr; Tcl_ResetResult(interp); result = ParseString(interp, var, valuePtr); return result; case '[': piPtr->token = VALUE; result = Blt_ParseNestedCmd(interp, p + 1, 0, &endPtr, &valuePtr->pv); if (result != TCL_OK) { return result; } piPtr->nextPtr = endPtr; Tcl_ResetResult(interp); result = ParseString(interp, valuePtr->pv.buffer, valuePtr); return result; case '"': piPtr->token = VALUE; result = Blt_ParseQuotes(interp, p + 1, '"', 0, &endPtr, &valuePtr->pv); if (result != TCL_OK) { return result; } piPtr->nextPtr = endPtr; Tcl_ResetResult(interp); result = ParseString(interp, valuePtr->pv.buffer, valuePtr); return result; case '{': piPtr->token = VALUE; result = Blt_ParseBraces(interp, p + 1, &endPtr, &valuePtr->pv); if (result != TCL_OK) { return result; } piPtr->nextPtr = endPtr; Tcl_ResetResult(interp); result = ParseString(interp, valuePtr->pv.buffer, valuePtr); return result; case '(': piPtr->token = OPEN_PAREN; break; case ')': piPtr->token = CLOSE_PAREN; break; case ',': piPtr->token = COMMA; break; case '*': piPtr->token = MULT; break; case '/': piPtr->token = DIVIDE; break; case '%': piPtr->token = MOD; break; case '+': piPtr->token = PLUS; break; case '-': piPtr->token = MINUS; break; case '^': piPtr->token = EXPONENT; break; case '<': switch (*(p + 1)) { case '<': piPtr->nextPtr = p + 2; piPtr->token = LEFT_SHIFT; break; case '=': piPtr->nextPtr = p + 2; piPtr->token = LEQ; break; default: piPtr->token = LESS; break; } break; case '>': switch (*(p + 1)) { case '>': piPtr->nextPtr = p + 2; piPtr->token = RIGHT_SHIFT; break; case '=': piPtr->nextPtr = p + 2; piPtr->token = GEQ; break; default: piPtr->token = GREATER; break; } break; case '=': if (*(p + 1) == '=') { piPtr->nextPtr = p + 2; piPtr->token = EQUAL; } else { piPtr->token = UNKNOWN; } break; case '&': if (*(p + 1) == '&') { piPtr->nextPtr = p + 2; piPtr->token = AND; } else { piPtr->token = UNKNOWN; } break; case '|': if (*(p + 1) == '|') { piPtr->nextPtr = p + 2; piPtr->token = OR; } else { piPtr->token = UNKNOWN; } break; case '!': if (*(p + 1) == '=') { piPtr->nextPtr = p + 2; piPtr->token = NEQ; } else { piPtr->token = NOT; } break; default: piPtr->token = VALUE; result = ParseMathFunction(interp, p, piPtr, valuePtr); if ((result == TCL_OK) || (result == TCL_ERROR)) { return result; } else { Vector *vPtr; while (isspace(UCHAR(*p))) { p++; /* Skip spaces leading the vector name. */ } vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, p, &endPtr, NS_SEARCH_BOTH); if (vPtr == NULL) { return TCL_ERROR; } Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); piPtr->nextPtr = endPtr; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextValue -- * * Parse a "value" from the remainder of the expression in piPtr. * * Results: * Normally TCL_OK is returned. The value of the expression is * returned in *valuePtr. If an error occurred, then interp->result * contains an error message and TCL_ERROR is returned. * InfoPtr->token will be left pointing to the token AFTER the * expression, and piPtr->nextPtr will point to the character just * after the terminating token. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int NextValue( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ ParseInfo *piPtr, /* Describes the state of the parse * just before the value (i.e. NextToken will * be called to get first token of value). */ int prec, /* Treat any un-parenthesized operator * with precedence <= this as the end * of the expression. */ Value *valuePtr) /* Where to store the value of the expression. * Caller must have initialized pv field. */ { Value value2; /* Second operand for current operator. */ int operator; /* Current operator (either unary or binary). */ int gotOp; /* Non-zero means already lexed the operator * (while picking up value for unary operator). * Don't lex again. */ int result; Vector *vPtr, *v2Ptr; int i; /* * There are two phases to this procedure. First, pick off an initial * value. Then, parse (binary operator, value) pairs until done. */ vPtr = valuePtr->vPtr; v2Ptr = Blt_Vec_New(vPtr->dataPtr); gotOp = FALSE; value2.vPtr = v2Ptr; value2.pv.buffer = value2.pv.next = value2.staticSpace; value2.pv.end = value2.pv.buffer + STATIC_STRING_SPACE - 1; value2.pv.expandProc = Blt_ExpandParseValue; value2.pv.clientData = NULL; result = NextToken(interp, piPtr, valuePtr); if (result != TCL_OK) { goto done; } if (piPtr->token == OPEN_PAREN) { /* Parenthesized sub-expression. */ result = NextValue(interp, piPtr, -1, valuePtr); if (result != TCL_OK) { goto done; } if (piPtr->token != CLOSE_PAREN) { Tcl_AppendResult(interp, "unmatched parentheses in expression \"", piPtr->expr, "\"", (char *)NULL); result = TCL_ERROR; goto done; } } else { if (piPtr->token == MINUS) { piPtr->token = UNARY_MINUS; } if (piPtr->token >= UNARY_MINUS) { operator = piPtr->token; result = NextValue(interp, piPtr, precTable[operator], valuePtr); if (result != TCL_OK) { goto done; } gotOp = TRUE; /* Process unary operators. */ switch (operator) { case UNARY_MINUS: for(i = 0; i < vPtr->length; i++) { vPtr->valueArr[i] = -(vPtr->valueArr[i]); } break; case NOT: for(i = 0; i < vPtr->length; i++) { vPtr->valueArr[i] = (double)(!vPtr->valueArr[i]); } break; default: Tcl_AppendResult(interp, "unknown operator", (char *)NULL); goto error; } } else if (piPtr->token != VALUE) { Tcl_AppendResult(interp, "missing operand", (char *)NULL); goto error; } } if (!gotOp) { result = NextToken(interp, piPtr, &value2); if (result != TCL_OK) { goto done; } } /* * Got the first operand. Now fetch (operator, operand) pairs. */ for (;;) { operator = piPtr->token; value2.pv.next = value2.pv.buffer; if ((operator < MULT) || (operator >= UNARY_MINUS)) { if ((operator == END) || (operator == CLOSE_PAREN) || (operator == COMMA)) { result = TCL_OK; goto done; } else { Tcl_AppendResult(interp, "bad operator", (char *)NULL); goto error; } } if (precTable[operator] <= prec) { result = TCL_OK; goto done; } result = NextValue(interp, piPtr, precTable[operator], &value2); if (result != TCL_OK) { goto done; } if ((piPtr->token < MULT) && (piPtr->token != VALUE) && (piPtr->token != END) && (piPtr->token != CLOSE_PAREN) && (piPtr->token != COMMA)) { Tcl_AppendResult(interp, "unexpected token in expression", (char *)NULL); goto error; } /* * At this point we have two vectors and an operator. */ if (v2Ptr->length == 1) { double *opnd; double scalar; /* * 2nd operand is a scalar. */ scalar = v2Ptr->valueArr[0]; opnd = vPtr->valueArr; switch (operator) { case MULT: for(i = 0; i < vPtr->length; i++) { opnd[i] *= scalar; } break; case DIVIDE: if (scalar == 0.0) { Tcl_AppendResult(interp, "divide by zero", (char *)NULL); goto error; } for(i = 0; i < vPtr->length; i++) { opnd[i] /= scalar; } break; case PLUS: for(i = 0; i < vPtr->length; i++) { opnd[i] += scalar; } break; case MINUS: for(i = 0; i < vPtr->length; i++) { opnd[i] -= scalar; } break; case EXPONENT: for(i = 0; i < vPtr->length; i++) { opnd[i] = pow(opnd[i], scalar); } break; case MOD: for(i = 0; i < vPtr->length; i++) { opnd[i] = Fmod(opnd[i], scalar); } break; case LESS: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] < scalar); } break; case GREATER: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] > scalar); } break; case LEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] <= scalar); } break; case GEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] >= scalar); } break; case EQUAL: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] == scalar); } break; case NEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] != scalar); } break; case AND: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] && scalar); } break; case OR: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] || scalar); } break; case LEFT_SHIFT: { int offset; offset = (int)scalar % vPtr->length; if (offset > 0) { double *hold; int j; hold = Blt_AssertMalloc(sizeof(double) * offset); for (i = 0; i < offset; i++) { hold[i] = opnd[i]; } for (i = offset, j = 0; i < vPtr->length; i++, j++) { opnd[j] = opnd[i]; } for (i = 0, j = vPtr->length - offset; j < vPtr->length; i++, j++) { opnd[j] = hold[i]; } Blt_Free(hold); } } break; case RIGHT_SHIFT: { int offset; offset = (int)scalar % vPtr->length; if (offset > 0) { double *hold; int j; hold = Blt_AssertMalloc(sizeof(double) * offset); for (i = vPtr->length - offset, j = 0; i < vPtr->length; i++, j++) { hold[j] = opnd[i]; } for (i = vPtr->length - offset - 1, j = vPtr->length - 1; i >= 0; i--, j--) { opnd[j] = opnd[i]; } for (i = 0; i < offset; i++) { opnd[i] = hold[i]; } Blt_Free(hold); } } break; default: Tcl_AppendResult(interp, "unknown operator in expression", (char *)NULL); goto error; } } else if (vPtr->length == 1) { double *opnd; double scalar; /* * 1st operand is a scalar. */ scalar = vPtr->valueArr[0]; Blt_Vec_Duplicate(vPtr, v2Ptr); opnd = vPtr->valueArr; switch (operator) { case MULT: for(i = 0; i < vPtr->length; i++) { opnd[i] *= scalar; } break; case PLUS: for(i = 0; i < vPtr->length; i++) { opnd[i] += scalar; } break; case DIVIDE: for(i = 0; i < vPtr->length; i++) { if (opnd[i] == 0.0) { Tcl_AppendResult(interp, "divide by zero", (char *)NULL); goto error; } opnd[i] = (scalar / opnd[i]); } break; case MINUS: for(i = 0; i < vPtr->length; i++) { opnd[i] = scalar - opnd[i]; } break; case EXPONENT: for(i = 0; i < vPtr->length; i++) { opnd[i] = pow(scalar, opnd[i]); } break; case MOD: for(i = 0; i < vPtr->length; i++) { opnd[i] = Fmod(scalar, opnd[i]); } break; case LESS: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(scalar < opnd[i]); } break; case GREATER: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(scalar > opnd[i]); } break; case LEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(scalar >= opnd[i]); } break; case GEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(scalar <= opnd[i]); } break; case EQUAL: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] == scalar); } break; case NEQ: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] != scalar); } break; case AND: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] && scalar); } break; case OR: for(i = 0; i < vPtr->length; i++) { opnd[i] = (double)(opnd[i] || scalar); } break; case LEFT_SHIFT: case RIGHT_SHIFT: Tcl_AppendResult(interp, "second shift operand must be scalar", (char *)NULL); goto error; default: Tcl_AppendResult(interp, "unknown operator in expression", (char *)NULL); goto error; } } else { double *opnd1, *opnd2; /* * Carry out the function of the specified operator. */ if (vPtr->length != v2Ptr->length) { Tcl_AppendResult(interp, "vectors are different lengths", (char *)NULL); goto error; } opnd1 = vPtr->valueArr, opnd2 = v2Ptr->valueArr; switch (operator) { case MULT: for (i = 0; i < vPtr->length; i++) { opnd1[i] *= opnd2[i]; } break; case DIVIDE: for (i = 0; i < vPtr->length; i++) { if (opnd2[i] == 0.0) { Tcl_AppendResult(interp, "can't divide by 0.0 vector component", (char *)NULL); goto error; } opnd1[i] /= opnd2[i]; } break; case PLUS: for (i = 0; i < vPtr->length; i++) { opnd1[i] += opnd2[i]; } break; case MINUS: for (i = 0; i < vPtr->length; i++) { opnd1[i] -= opnd2[i]; } break; case MOD: for (i = 0; i < vPtr->length; i++) { opnd1[i] = Fmod(opnd1[i], opnd2[i]); } break; case EXPONENT: for (i = 0; i < vPtr->length; i++) { opnd1[i] = pow(opnd1[i], opnd2[i]); } break; case LESS: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] < opnd2[i]); } break; case GREATER: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] > opnd2[i]); } break; case LEQ: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] <= opnd2[i]); } break; case GEQ: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] >= opnd2[i]); } break; case EQUAL: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] == opnd2[i]); } break; case NEQ: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] != opnd2[i]); } break; case AND: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] && opnd2[i]); } break; case OR: for (i = 0; i < vPtr->length; i++) { opnd1[i] = (double)(opnd1[i] || opnd2[i]); } break; case LEFT_SHIFT: case RIGHT_SHIFT: Tcl_AppendResult(interp, "second shift operand must be scalar", (char *)NULL); goto error; default: Tcl_AppendResult(interp, "unknown operator in expression", (char *)NULL); goto error; } } } done: if (value2.pv.buffer != value2.staticSpace) { Blt_Free(value2.pv.buffer); } Blt_Vec_Free(v2Ptr); return result; error: if (value2.pv.buffer != value2.staticSpace) { Blt_Free(value2.pv.buffer); } Blt_Vec_Free(v2Ptr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * EvaluateExpression -- * * This procedure provides top-level functionality shared by * procedures like Tcl_ExprInt, Tcl_ExprDouble, etc. * * Results: * The result is a standard TCL return value. If an error * occurs then an error message is left in interp->result. * The value of the expression is returned in *valuePtr, in * whatever form it ends up in (could be string or integer * or double). Caller may need to convert result. Caller * is also responsible for freeing string memory in *valuePtr, * if any was allocated. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int EvaluateExpression( Tcl_Interp *interp, /* Context in which to evaluate the * expression. */ char *string, /* Expression to evaluate. */ Value *valuePtr) /* Where to store result. Should * not be initialized by caller. */ { ParseInfo info; int result; Vector *vPtr; double *vp, *vend; info.expr = info.nextPtr = string; valuePtr->pv.buffer = valuePtr->pv.next = valuePtr->staticSpace; valuePtr->pv.end = valuePtr->pv.buffer + STATIC_STRING_SPACE - 1; valuePtr->pv.expandProc = Blt_ExpandParseValue; valuePtr->pv.clientData = NULL; result = NextValue(interp, &info, -1, valuePtr); if (result != TCL_OK) { return result; } if (info.token != END) { Tcl_AppendResult(interp, ": syntax error in expression \"", string, "\"", (char *)NULL); return TCL_ERROR; } vPtr = valuePtr->vPtr; /* Check for NaN's and overflows. */ for (vp = vPtr->valueArr, vend = vp + vPtr->length; vp < vend; vp++) { if (!FINITE(*vp)) { /* * IEEE floating-point error. */ MathError(interp, *vp); return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Math Functions -- * * This page contains the procedures that implement all of the * built-in math functions for expressions. * * Results: * Each procedure returns TCL_OK if it succeeds and places result * information at *resultPtr. If it fails it returns TCL_ERROR * and leaves an error message in interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ComponentFunc( ClientData clientData, /* Contains address of procedure that * takes one double argument and * returns a double result. */ Tcl_Interp *interp, Vector *vPtr) { ComponentProc *procPtr = (ComponentProc *) clientData; double *vp, *vend; errno = 0; for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { *vp = (*procPtr) (*vp); if (errno != 0) { MathError(interp, *vp); return TCL_ERROR; } if (!FINITE(*vp)) { /* * IEEE floating-point error. */ MathError(interp, *vp); return TCL_ERROR; } } return TCL_OK; } static int ScalarFunc(ClientData clientData, Tcl_Interp *interp, Vector *vPtr) { double value; ScalarProc *procPtr = (ScalarProc *) clientData; errno = 0; value = (*procPtr) (vPtr); if (errno != 0) { MathError(interp, value); return TCL_ERROR; } if (Blt_Vec_ChangeLength(interp, vPtr, 1) != TCL_OK) { return TCL_ERROR; } vPtr->valueArr[0] = value; return TCL_OK; } /*ARGSUSED*/ static int VectorFunc(ClientData clientData, Tcl_Interp *interp, Vector *vPtr) { VectorProc *procPtr = (VectorProc *) clientData; return (*procPtr) (vPtr); } static MathFunction mathFunctions[] = { {"abs", ComponentFunc, Fabs}, {"acos", ComponentFunc, acos}, {"asin", ComponentFunc, asin}, {"atan", ComponentFunc, atan}, {"adev", ScalarFunc, AvgDeviation}, {"ceil", ComponentFunc, ceil}, {"cos", ComponentFunc, cos}, {"cosh", ComponentFunc, cosh}, {"exp", ComponentFunc, exp}, {"floor", ComponentFunc, floor}, {"kurtosis",ScalarFunc, Kurtosis}, {"length", ScalarFunc, Length}, {"log", ComponentFunc, log}, {"log10", ComponentFunc, log10}, {"max", ScalarFunc, Blt_VecMax}, {"mean", ScalarFunc, Mean}, {"median", ScalarFunc, Median}, {"min", ScalarFunc, Blt_VecMin}, {"norm", VectorFunc, Norm}, {"nz", ScalarFunc, Nonzeros}, {"q1", ScalarFunc, Q1}, {"q3", ScalarFunc, Q3}, {"prod", ScalarFunc, Product}, {"random", ComponentFunc, drand48}, {"round", ComponentFunc, Round}, {"sdev", ScalarFunc, StdDeviation}, {"sin", ComponentFunc, sin}, {"sinh", ComponentFunc, sinh}, {"skew", ScalarFunc, Skew}, {"sort", VectorFunc, Sort}, {"sqrt", ComponentFunc, sqrt}, {"sum", ScalarFunc, Sum}, {"tan", ComponentFunc, tan}, {"tanh", ComponentFunc, tanh}, {"var", ScalarFunc, Variance}, {(char *)NULL,}, }; void Blt_Vec_InstallMathFunctions(Blt_HashTable *tablePtr) { MathFunction *mathPtr; for (mathPtr = mathFunctions; mathPtr->name != NULL; mathPtr++) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(tablePtr, mathPtr->name, &isNew); Blt_SetHashValue(hPtr, (ClientData)mathPtr); } } void Blt_Vec_UninstallMathFunctions(Blt_HashTable *tablePtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { MathFunction *mathPtr; mathPtr = Blt_GetHashValue(hPtr); if (mathPtr->name == NULL) { Blt_Free(mathPtr); } } } static void InstallIndexProc( Blt_HashTable *tablePtr, const char *string, Blt_VectorIndexProc *procPtr) /* Pointer to function to be called * when the vector finds the named index. * If NULL, this indicates to remove * the index from the table. */ { Blt_HashEntry *hPtr; int dummy; hPtr = Blt_CreateHashEntry(tablePtr, string, &dummy); if (procPtr == NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } else { Blt_SetHashValue(hPtr, (ClientData)procPtr); } } void Blt_Vec_InstallSpecialIndices(Blt_HashTable *tablePtr) { InstallIndexProc(tablePtr, "min", Blt_VecMin); InstallIndexProc(tablePtr, "max", Blt_VecMax); InstallIndexProc(tablePtr, "mean", Mean); InstallIndexProc(tablePtr, "sum", Sum); InstallIndexProc(tablePtr, "prod", Product); } /* *--------------------------------------------------------------------------- * * Blt_ExprVector -- * * Evaluates an vector expression and returns its value(s). * * Results: * Each of the procedures below returns a standard TCL result. * If an error occurs then an error message is left in * interp->result. Otherwise the value of the expression, * in the appropriate form, is stored at *resultPtr. If * the expression had a result that was incompatible with the * desired form then an error is returned. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_ExprVector( Tcl_Interp *interp, /* Context in which to evaluate the * expression. */ char *string, /* Expression to evaluate. */ Blt_Vector *vector) /* Where to store result. */ { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr = (Vector *)vector; Value value; dataPtr = (vector != NULL) ? vPtr->dataPtr : Blt_Vec_GetInterpData(interp); value.vPtr = Blt_Vec_New(dataPtr); if (EvaluateExpression(interp, string, &value) != TCL_OK) { Blt_Vec_Free(value.vPtr); return TCL_ERROR; } if (vPtr != NULL) { Blt_Vec_Duplicate(vPtr, value.vPtr); } else { Tcl_Obj *listObjPtr; double *vp, *vend; /* No result vector. Put values in interp->result. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (vp = value.vPtr->valueArr, vend = vp + value.vPtr->length; vp < vend; vp++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(*vp)); } Tcl_SetObjResult(interp, listObjPtr); } Blt_Vec_Free(value.vPtr); return TCL_OK; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltRound.h��������������������������������������������������������������������0000644�0001750�0001750�00000001103�11462120062�014762� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #if (SIZEOF_FLOAT == 8) #define REAL64 float #else #define REAL64 double #endif /* SIZE_VOID_P == 8 */ #define DOUBLE_MAGIC 6755399441055744.0 #define DEFAULT_CONVERSION 1 #ifdef WORDS_BIGENDIAN #define IMAN 1 #define IEXP 0 #else #define IMAN 0 #define IEXP 1 #endif /* WORDS_BIGENDIAN */ static INLINE int CRoundToInt(REAL64 val) { #if DEFAULT_CONVERSION==0 val += DOUBLE_MAGIC; #ifdef WORDS_BIGENDIAN return ((int *)&val)[1]; #else return ((int *)&val)[0]; #endif /* WORD_BIGENDIAN */ #else return (int)(floor(val+.5)); #endif /* DEFAULT_CONVERSION */ } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrLine.c�������������������������������������������������������������������0000644�0001750�0001750�00000463767�11462120062�015102� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrLine.c -- * * This module implements line graph and stripchart elements for the BLT graph * widget. * * Copyright (c) 1993 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltChain.h" #include <X11/Xutil.h> #include "bltGrElem.h" #include "tkDisplay.h" #include "bltBgStyle.h" #include "bltImage.h" #include "bltBitmap.h" #define COLOR_DEFAULT (XColor *)1 #define PATTERN_SOLID ((Pixmap)1) #define PEN_INCREASING 1 /* Draw line segments for only those * data points whose abscissas are * monotonically increasing in * order. */ #define PEN_DECREASING 2 /* Lines will be drawn between only * those points whose abscissas are * decreasing in order. */ #define PEN_BOTH_DIRECTIONS (PEN_INCREASING | PEN_DECREASING) /* Lines will be drawn between points regardless of the ordering of the * abscissas */ #define BROKEN_TRACE(dir,last,next) \ (((((dir) & PEN_DECREASING) == 0) && ((next) < (last))) || \ ((((dir) & PEN_INCREASING) == 0) && ((next) > (last)))) #define DRAW_SYMBOL(linePtr) \ (((linePtr)->symbolCounter % (linePtr)->symbolInterval) == 0) typedef enum { PEN_SMOOTH_LINEAR, /* Line segments */ PEN_SMOOTH_STEP, /* Step-and-hold */ PEN_SMOOTH_NATURAL, /* Natural cubic spline */ PEN_SMOOTH_QUADRATIC, /* Quadratic spline */ PEN_SMOOTH_CATROM, /* Catrom parametric spline */ PEN_SMOOTH_LAST /* Sentinel */ } Smoothing; typedef struct { const char *name; Smoothing value; } SmoothingInfo; static SmoothingInfo smoothingInfo[] = { { "none", PEN_SMOOTH_LINEAR }, { "linear", PEN_SMOOTH_LINEAR }, { "step", PEN_SMOOTH_STEP }, { "natural", PEN_SMOOTH_NATURAL }, { "cubic", PEN_SMOOTH_NATURAL }, { "quadratic", PEN_SMOOTH_QUADRATIC }, { "catrom", PEN_SMOOTH_CATROM }, { (char *)NULL, PEN_SMOOTH_LAST } }; typedef struct { Point2d *screenPts; /* Array of transformed coordinates */ int nScreenPts; /* Number of coordinates */ int *styleMap; /* Index of pen styles */ int *map; /* Maps segments/traces to data * points */ } MapInfo; /* Symbol types for line elements */ typedef enum { SYMBOL_NONE, SYMBOL_SQUARE, SYMBOL_CIRCLE, SYMBOL_DIAMOND, SYMBOL_PLUS, SYMBOL_CROSS, SYMBOL_SPLUS, SYMBOL_SCROSS, SYMBOL_TRIANGLE, SYMBOL_ARROW, SYMBOL_BITMAP, SYMBOL_IMAGE } SymbolType; typedef struct { const char *name; unsigned int minChars; SymbolType type; } GraphSymbolType; static GraphSymbolType graphSymbols[] = { { "arrow", 1, SYMBOL_ARROW, }, { "circle", 2, SYMBOL_CIRCLE, }, { "cross", 2, SYMBOL_CROSS, }, { "diamond", 1, SYMBOL_DIAMOND, }, { "none", 1, SYMBOL_NONE, }, { "plus", 1, SYMBOL_PLUS, }, { "scross", 2, SYMBOL_SCROSS, }, { "splus", 2, SYMBOL_SPLUS, }, { "square", 2, SYMBOL_SQUARE, }, { "triangle", 1, SYMBOL_TRIANGLE, }, { NULL, 0, 0 }, }; typedef struct { SymbolType type; /* Type of symbol to be drawn/printed */ int size; /* Requested size of symbol in pixels */ XColor *outlineColor; /* Outline color */ int outlineWidth; /* Width of the outline */ GC outlineGC; /* Outline graphics context */ XColor *fillColor; /* Normal fill color */ GC fillGC; /* Fill graphics context */ Tk_Image image; /* This is used of image symbols. */ /* The last two fields are used only for bitmap symbols. */ Pixmap bitmap; /* Bitmap to determine * foreground/background pixels of the * symbol */ Pixmap mask; /* Bitmap representing the transparent * pixels of the symbol */ } Symbol; typedef struct { int start; /* Index into the X-Y coordinate arrays * indicating where trace starts. */ GraphPoints screenPts; /* Array of screen coordinates * (malloc-ed) representing the * trace. */ } Trace; typedef struct { const char *name; /* Pen style identifier. If NULL pen * was statically allocated. */ ClassId classId; /* Type of pen */ const char *typeId; /* String token identifying the type of * pen */ unsigned int flags; /* Indicates if the pen element is * active or normal */ int refCount; /* Reference count for elements using * this pen. */ Blt_HashEntry *hashPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications */ PenConfigureProc *configProc; PenDestroyProc *destroyProc; Graph *graphPtr; /* Graph that the pen is associated * with. */ /* Symbol attributes. */ Symbol symbol; /* Element symbol type */ /* Trace attributes. */ int traceWidth; /* Width of the line segments. If * lineWidth is 0, no line will be * drawn, only symbols. */ Blt_Dashes traceDashes; /* Dash on-off list value */ XColor *traceColor; /* Line segment color */ XColor *traceOffColor; /* Line segment dash gap color */ GC traceGC; /* Line segment graphics context */ /* Error bar attributes. */ int errorBarShow; /* Describes which error bars to display: * none, x, y, or * both. */ int errorBarLineWidth; /* Width of the error bar segments. */ int errorBarCapWidth; /* Width of the cap on error bars. */ XColor *errorBarColor; /* Color of the error bar. */ GC errorBarGC; /* Error bar graphics context. */ /* Show value attributes. */ int valueShow; /* Indicates whether to display data * value. Values are x, y, both, or * none. */ const char *valueFormat; /* A printf format string. */ TextStyle valueStyle; /* Text attributes (color, font, * rotation, etc.) of the value. */ } LinePen; typedef struct { Weight weight; /* Weight range where this pen is * valid. */ LinePen *penPtr; /* Pen to use. */ GraphPoints symbolPts; GraphSegments lines; /* Points to start of the line segments * for this pen. */ GraphSegments xeb, yeb; /* X and Y axis error bars. */ int symbolSize; /* Size of the pen's symbol scaled to * the current graph size. */ int errorBarCapWidth; /* Length of the cap ends on each error * bar. */ } LineStyle; typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to elements. */ const char *label; /* Label displayed in legend */ unsigned short row, col; /* Position of the entry in the * legend. */ int legendRelief; /* Relief of label in legend. */ Axis2d axes; /* X-axis and Y-axis mapping the * element */ ElemValues x, y, w; /* Contains array of floating point * graph coordinate values. Also holds * min/max * and the number of * coordinates */ int *activeIndices; /* Array of indices (malloc-ed) which * indicate which data points are active * (drawn * with "active" colors). */ int nActiveIndices; /* Number of active data points. * Special case: if nActiveIndices < 0 * and the * active bit is set in * "flags", then all data points are * drawn active. */ ElementProcs *procsPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications. */ LinePen *activePenPtr; /* Standard Pens */ LinePen *normalPenPtr; LinePen *builtinPenPtr; Blt_Chain styles; /* Palette of pens. */ /* Symbol scaling */ int scaleSymbols; /* If non-zero, the symbols will scale * in size as the graph is zoomed * in/out. */ double xRange, yRange; /* Initial X-axis and Y-axis ranges: * used to scale the size of element's * symbol. */ int state; Blt_ChainLink link; /* Element's link in display list. */ /* The line element specific fields start here. */ ElemValues xError; /* Relative/symmetric X error values. */ ElemValues yError; /* Relative/symmetric Y error values. */ ElemValues xHigh, xLow; /* Absolute/asymmetric X-coordinate * high/low error values. */ ElemValues yHigh, yLow; /* Absolute/asymmetric Y-coordinate * high/low error values. */ LinePen builtinPen; int errorBarCapWidth; /* Length of cap on error bars */ /* Line smoothing */ Smoothing reqSmooth; /* Requested smoothing function to use * for connecting the data points */ Smoothing smooth; /* Smoothing function used. */ float rTolerance; /* Tolerance to reduce the number of * points displayed. */ /* Drawing-related data structures. */ /* Area-under-curve fill attributes. */ XColor *fillFgColor; XColor *fillBgColor; GC fillGC; Blt_Background fillBg; /* Background for fill area. */ Point2d *fillPts; /* Array of points used to draw polygon * to fill area under the curve */ int nFillPts; /* Symbol points */ GraphPoints symbolPts; /* Active symbol points */ GraphPoints activePts; GraphSegments xeb, yeb; /* Point to start of this pen's X-error * bar segments in the element's * array. */ int reqMaxSymbols; int symbolInterval; int symbolCounter; /* X-Y graph-specific fields */ int penDir; /* Indicates if a change in the pen * direction should be considered a * retrace (line segment is not * drawn). */ Blt_Chain traces; /* List of traces (a trace is a series * of contiguous line segments). New * traces are generated when either * the next segment changes the pen * direction, or the end point is * clipped by the plotting area. */ /* Stripchart-specific fields */ GraphSegments lines; /* Holds the the line segments of the * element trace. The segments are * grouped by pen style. */ } LineElement; static Blt_OptionParseProc ObjToSmoothProc; static Blt_OptionPrintProc SmoothToObjProc; static Blt_CustomOption smoothOption = { ObjToSmoothProc, SmoothToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToPenDirProc; static Blt_OptionPrintProc PenDirToObjProc; static Blt_CustomOption penDirOption = { ObjToPenDirProc, PenDirToObjProc, NULL, (ClientData)0 }; static Blt_OptionFreeProc FreeSymbolProc; static Blt_OptionParseProc ObjToSymbolProc; static Blt_OptionPrintProc SymbolToObjProc; static Blt_CustomOption symbolOption = { ObjToSymbolProc, SymbolToObjProc, FreeSymbolProc, (ClientData)0 }; BLT_EXTERN Blt_CustomOption bltLineStylesOption; BLT_EXTERN Blt_CustomOption bltColorOption; BLT_EXTERN Blt_CustomOption bltValuesOption; BLT_EXTERN Blt_CustomOption bltValuePairsOption; BLT_EXTERN Blt_CustomOption bltLinePenOption; BLT_EXTERN Blt_CustomOption bltXAxisOption; BLT_EXTERN Blt_CustomOption bltYAxisOption; #define DEF_LINE_ACTIVE_PEN "activeLine" #define DEF_LINE_AXIS_X "x" #define DEF_LINE_AXIS_Y "y" #define DEF_LINE_DASHES (char *)NULL #define DEF_LINE_DATA (char *)NULL #define DEF_LINE_FILL_COLOR "defcolor" #define DEF_LINE_HIDE "no" #define DEF_LINE_LABEL (char *)NULL #define DEF_LINE_LABEL_RELIEF "flat" #define DEF_LINE_MAX_SYMBOLS "0" #define DEF_LINE_OFFDASH_COLOR (char *)NULL #define DEF_LINE_OUTLINE_COLOR "defcolor" #define DEF_LINE_OUTLINE_WIDTH "1" #define DEF_LINE_PATTERN_BG (char *)NULL #define DEF_LINE_PATTERN_FG "black" #define DEF_LINE_PEN_COLOR RGB_NAVYBLUE #define DEF_LINE_PEN_DIRECTION "both" #define DEF_LINE_PEN_WIDTH "1" #define DEF_LINE_PIXELS "0.1i" #define DEF_LINE_REDUCE "0.0" #define DEF_LINE_SCALE_SYMBOLS "yes" #define DEF_LINE_SMOOTH "linear" #define DEF_LINE_STATE "normal" #define DEF_LINE_STIPPLE (char *)NULL #define DEF_LINE_STYLES "" #define DEF_LINE_SYMBOL "circle" #define DEF_LINE_TAGS "all" #define DEF_LINE_X_DATA (char *)NULL #define DEF_LINE_Y_DATA (char *)NULL #define DEF_LINE_ERRORBAR_COLOR "defcolor" #define DEF_LINE_ERRORBAR_LINE_WIDTH "2" #define DEF_LINE_ERRORBAR_CAP_WIDTH "2" #define DEF_LINE_SHOW_ERRORBARS "both" #define DEF_PEN_ACTIVE_COLOR RGB_BLUE #define DEF_PEN_DASHES (char *)NULL #define DEF_PEN_FILL_COLOR "defcolor" #define DEF_PEN_LINE_WIDTH "1" #define DEF_PEN_NORMAL_COLOR RGB_NAVYBLUE #define DEF_PEN_OFFDASH_COLOR (char *)NULL #define DEF_PEN_OUTLINE_COLOR "defcolor" #define DEF_PEN_OUTLINE_WIDTH "1" #define DEF_PEN_PIXELS "0.1i" #define DEF_PEN_SYMBOL "circle" #define DEF_PEN_TYPE "line" #define DEF_PEN_VALUE_ANCHOR "s" #define DEF_PEN_VALUE_COLOR RGB_BLACK #define DEF_PEN_VALUE_FONT STD_FONT_NUMBERS #define DEF_PEN_VALUE_FORMAT "%g" #define DEF_PEN_VALUE_ANGLE (char *)NULL #define DEF_PEN_SHOW_VALUES "no" static Blt_ConfigSpec lineElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", DEF_LINE_ACTIVE_PEN, Blt_Offset(LineElement, activePenPtr), BLT_CONFIG_NULL_OK, &bltLinePenOption}, {BLT_CONFIG_COLOR, "-areaforeground", "areaForeground", "AreaForeground", DEF_LINE_PATTERN_FG, Blt_Offset(LineElement, fillFgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-areabackground", "areaBackground", "AreaBackground", DEF_LINE_PATTERN_BG, Blt_Offset(LineElement, fillBg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_LINE_TAGS, Blt_Offset(LineElement, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_LINE_PEN_COLOR, Blt_Offset(LineElement, builtinPen.traceColor), 0}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_LINE_DASHES, Blt_Offset(LineElement, builtinPen.traceDashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-data", "data", "Data", DEF_LINE_DATA, 0, 0, &bltValuePairsOption}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_LINE_ERRORBAR_COLOR, Blt_Offset(LineElement, builtinPen.errorBarColor), 0, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth", DEF_LINE_ERRORBAR_LINE_WIDTH, Blt_Offset(LineElement, builtinPen.errorBarLineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_LINE_ERRORBAR_CAP_WIDTH, Blt_Offset(LineElement, builtinPen.errorBarCapWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_LINE_FILL_COLOR, Blt_Offset(LineElement, builtinPen.symbol.fillColor), BLT_CONFIG_NULL_OK, &bltColorOption}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_LINE_HIDE, Blt_Offset(LineElement, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, Blt_Offset(LineElement, label), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief", DEF_LINE_LABEL_RELIEF, Blt_Offset(LineElement, legendRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_LINE_PEN_WIDTH, Blt_Offset(LineElement, builtinPen.traceWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_LINE_AXIS_X, Blt_Offset(LineElement, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_LINE_AXIS_Y, Blt_Offset(LineElement, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_INT_NNEG, "-maxsymbols", "maxSymbols", "MaxSymbols", DEF_LINE_MAX_SYMBOLS, Blt_Offset(LineElement, reqMaxSymbols), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-offdash", "offDash", "OffDash", DEF_LINE_OFFDASH_COLOR, Blt_Offset(LineElement, builtinPen.traceOffColor), BLT_CONFIG_NULL_OK, &bltColorOption}, {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", DEF_LINE_OUTLINE_COLOR, Blt_Offset(LineElement, builtinPen.symbol.outlineColor), 0, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-outlinewidth", "outlineWidth", "OutlineWidth", DEF_LINE_OUTLINE_WIDTH, Blt_Offset(LineElement, builtinPen.symbol.outlineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, Blt_Offset(LineElement, normalPenPtr), BLT_CONFIG_NULL_OK, &bltLinePenOption}, {BLT_CONFIG_PIXELS_NNEG, "-pixels", "pixels", "Pixels", DEF_LINE_PIXELS, Blt_Offset(LineElement, builtinPen.symbol.size), GRAPH | STRIPCHART}, {BLT_CONFIG_FLOAT, "-reduce", "reduce", "Reduce", DEF_LINE_REDUCE, Blt_Offset(LineElement, rTolerance), GRAPH | STRIPCHART | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-scalesymbols", "scaleSymbols", "ScaleSymbols", DEF_LINE_SCALE_SYMBOLS, Blt_Offset(LineElement, scaleSymbols), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_LINE_SHOW_ERRORBARS, Blt_Offset(LineElement, builtinPen.errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(LineElement, builtinPen.valueShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-smooth", "smooth", "Smooth", DEF_LINE_SMOOTH, Blt_Offset(LineElement, reqSmooth), BLT_CONFIG_DONT_SET_DEFAULT, &smoothOption}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_LINE_STATE, Blt_Offset(LineElement, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_LINE_STYLES, Blt_Offset(LineElement, styles), 0, &bltLineStylesOption}, {BLT_CONFIG_CUSTOM, "-symbol", "symbol", "Symbol", DEF_LINE_SYMBOL, Blt_Offset(LineElement, builtinPen.symbol), BLT_CONFIG_DONT_SET_DEFAULT, &symbolOption}, {BLT_CONFIG_CUSTOM, "-trace", "trace", "Trace", DEF_LINE_PEN_DIRECTION, Blt_Offset(LineElement, penDir), BLT_CONFIG_DONT_SET_DEFAULT, &penDirOption}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(LineElement, builtinPen.valueStyle.anchor), 0}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(LineElement, builtinPen.valueStyle.color), 0}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(LineElement, builtinPen.valueStyle.font), 0}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(LineElement, builtinPen.valueFormat), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", DEF_PEN_VALUE_ANGLE, Blt_Offset(LineElement, builtinPen.valueStyle.angle), 0}, {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, Blt_Offset(LineElement, w), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(LineElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xdata", "xData", "XData", (char *)NULL, Blt_Offset(LineElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL, Blt_Offset(LineElement, xError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL, Blt_Offset(LineElement, xHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL, Blt_Offset(LineElement, xLow), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(LineElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ydata", "yData", "YData", (char *)NULL, Blt_Offset(LineElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL, Blt_Offset(LineElement, yError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL, Blt_Offset(LineElement, yHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL, Blt_Offset(LineElement, yLow), 0, &bltValuesOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec stripElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", DEF_LINE_ACTIVE_PEN, Blt_Offset(LineElement, activePenPtr), BLT_CONFIG_NULL_OK, &bltLinePenOption}, {BLT_CONFIG_COLOR, "-areaforeground", "areaForeground", "areaForeground", DEF_LINE_PATTERN_FG, Blt_Offset(LineElement, fillFgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-areabackground", "areaBackground", "areaBackground", DEF_LINE_PATTERN_BG, Blt_Offset(LineElement, fillBg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_LINE_TAGS, Blt_Offset(LineElement, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_LINE_PEN_COLOR, Blt_Offset(LineElement, builtinPen.traceColor), 0}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_LINE_DASHES, Blt_Offset(LineElement, builtinPen.traceDashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-data", "data", "Data", DEF_LINE_DATA, 0, 0, &bltValuePairsOption}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_LINE_ERRORBAR_COLOR, Blt_Offset(LineElement, builtinPen.errorBarColor), 0, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth", "ErrorBarWidth", DEF_LINE_ERRORBAR_LINE_WIDTH, Blt_Offset(LineElement, builtinPen.errorBarLineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_LINE_ERRORBAR_CAP_WIDTH, Blt_Offset(LineElement, builtinPen.errorBarCapWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_LINE_FILL_COLOR, Blt_Offset(LineElement, builtinPen.symbol.fillColor), BLT_CONFIG_NULL_OK, &bltColorOption}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_LINE_HIDE, Blt_Offset(LineElement, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, Blt_Offset(LineElement, label), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief", DEF_LINE_LABEL_RELIEF, Blt_Offset(LineElement, legendRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_LINE_PEN_WIDTH, Blt_Offset(LineElement, builtinPen.traceWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_LINE_AXIS_X, Blt_Offset(LineElement, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_LINE_AXIS_Y, Blt_Offset(LineElement, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_INT_NNEG, "-maxsymbols", "maxSymbols", "MaxSymbols", DEF_LINE_MAX_SYMBOLS, Blt_Offset(LineElement, reqMaxSymbols), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-offdash", "offDash", "OffDash", DEF_LINE_OFFDASH_COLOR, Blt_Offset(LineElement, builtinPen.traceOffColor), BLT_CONFIG_NULL_OK, &bltColorOption}, {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", DEF_LINE_OUTLINE_COLOR, Blt_Offset(LineElement, builtinPen.symbol.outlineColor), 0, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-outlinewidth", "outlineWidth", "OutlineWidth", DEF_LINE_OUTLINE_WIDTH, Blt_Offset(LineElement, builtinPen.symbol.outlineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, Blt_Offset(LineElement, normalPenPtr), BLT_CONFIG_NULL_OK, &bltLinePenOption}, {BLT_CONFIG_PIXELS_NNEG, "-pixels", "pixels", "Pixels", DEF_LINE_PIXELS, Blt_Offset(LineElement, builtinPen.symbol.size), 0}, {BLT_CONFIG_BOOLEAN, "-scalesymbols", "scaleSymbols", "ScaleSymbols", DEF_LINE_SCALE_SYMBOLS, Blt_Offset(LineElement, scaleSymbols), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_LINE_SHOW_ERRORBARS, Blt_Offset(LineElement, builtinPen.errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(LineElement, builtinPen.valueShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-smooth", "smooth", "Smooth", DEF_LINE_SMOOTH, Blt_Offset(LineElement, reqSmooth), BLT_CONFIG_DONT_SET_DEFAULT, &smoothOption}, {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_LINE_STYLES, Blt_Offset(LineElement, styles), 0, &bltLineStylesOption}, {BLT_CONFIG_CUSTOM, "-symbol", "symbol", "Symbol", DEF_LINE_SYMBOL, Blt_Offset(LineElement, builtinPen.symbol), BLT_CONFIG_DONT_SET_DEFAULT, &symbolOption}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(LineElement, builtinPen.valueStyle.anchor), 0}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(LineElement, builtinPen.valueStyle.color), 0}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(LineElement, builtinPen.valueStyle.font), 0}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(LineElement, builtinPen.valueFormat), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", DEF_PEN_VALUE_ANGLE, Blt_Offset(LineElement, builtinPen.valueStyle.angle),0}, {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, Blt_Offset(LineElement, w), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(LineElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xdata", "xData", "XData", (char *)NULL, Blt_Offset(LineElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(LineElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL, Blt_Offset(LineElement, xError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ydata", "yData", "YData", (char *)NULL, Blt_Offset(LineElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL, Blt_Offset(LineElement, yError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL, Blt_Offset(LineElement, xHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL, Blt_Offset(LineElement, xLow), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL, Blt_Offset(LineElement, xHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL, Blt_Offset(LineElement, yLow), 0, &bltValuesOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec linePenConfigSpecs[] = { {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_PEN_ACTIVE_COLOR, Blt_Offset(LinePen, traceColor), ACTIVE_PEN}, {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_PEN_NORMAL_COLOR, Blt_Offset(LinePen, traceColor), NORMAL_PEN}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_PEN_DASHES, Blt_Offset(LinePen, traceDashes), BLT_CONFIG_NULL_OK | ALL_PENS}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_LINE_ERRORBAR_COLOR, Blt_Offset(LinePen, errorBarColor), ALL_PENS, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth", "ErrorBarWidth", DEF_LINE_ERRORBAR_LINE_WIDTH, Blt_Offset(LinePen, errorBarLineWidth), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_LINE_ERRORBAR_CAP_WIDTH, Blt_Offset(LinePen, errorBarCapWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_PEN_FILL_COLOR, Blt_Offset(LinePen, symbol.fillColor), BLT_CONFIG_NULL_OK | ALL_PENS, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", (char *)NULL, Blt_Offset(LinePen, traceWidth), ALL_PENS| BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-offdash", "offDash", "OffDash", DEF_PEN_OFFDASH_COLOR, Blt_Offset(LinePen, traceOffColor), BLT_CONFIG_NULL_OK | ALL_PENS, &bltColorOption}, {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", DEF_PEN_OUTLINE_COLOR, Blt_Offset(LinePen, symbol.outlineColor), ALL_PENS, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-outlinewidth", "outlineWidth", "OutlineWidth", DEF_PEN_OUTLINE_WIDTH, Blt_Offset(LinePen, symbol.outlineWidth), BLT_CONFIG_DONT_SET_DEFAULT | ALL_PENS}, {BLT_CONFIG_PIXELS_NNEG, "-pixels", "pixels", "Pixels", DEF_PEN_PIXELS, Blt_Offset(LinePen, symbol.size), ALL_PENS}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_LINE_SHOW_ERRORBARS, Blt_Offset(LinePen, errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(LinePen, valueShow), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-symbol", "symbol", "Symbol", DEF_PEN_SYMBOL, Blt_Offset(LinePen, symbol), BLT_CONFIG_DONT_SET_DEFAULT | ALL_PENS, &symbolOption}, {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_PEN_TYPE, Blt_Offset(Pen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(LinePen, valueStyle.anchor), ALL_PENS}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(LinePen, valueStyle.color), ALL_PENS}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(LinePen, valueStyle.font), ALL_PENS}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(LinePen, valueFormat), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", DEF_PEN_VALUE_ANGLE, Blt_Offset(LinePen, valueStyle.angle), ALL_PENS}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; typedef double (DistanceProc)(int x, int y, Point2d *p, Point2d *q, Point2d *t); /* Forward declarations */ static PenConfigureProc ConfigurePenProc; static PenDestroyProc DestroyPenProc; static ElementClosestProc ClosestLineProc; static ElementConfigProc ConfigureLineProc; static ElementDestroyProc DestroyLineProc; static ElementDrawProc DrawActiveLineProc; static ElementDrawProc DrawNormalLineProc; static ElementDrawSymbolProc DrawSymbolProc; static ElementExtentsProc GetLineExtentsProc; static ElementToPostScriptProc ActiveLineToPostScriptProc; static ElementToPostScriptProc NormalLineToPostScriptProc; static ElementSymbolToPostScriptProc SymbolToPostScriptProc; static ElementMapProc MapLineProc; static DistanceProc DistanceToYProc; static DistanceProc DistanceToXProc; static DistanceProc DistanceToLineProc; static Blt_BackgroundChangedProc BackgroundChangedProc; #ifdef WIN32 static int tkpWinRopModes[] = { R2_BLACK, /* GXclear */ R2_MASKPEN, /* GXand */ R2_MASKPENNOT, /* GXandReverse */ R2_COPYPEN, /* GXcopy */ R2_MASKNOTPEN, /* GXandInverted */ R2_NOT, /* GXnoop */ R2_XORPEN, /* GXxor */ R2_MERGEPEN, /* GXor */ R2_NOTMERGEPEN, /* GXnor */ R2_NOTXORPEN, /* GXequiv */ R2_NOT, /* GXinvert */ R2_MERGEPENNOT, /* GXorReverse */ R2_NOTCOPYPEN, /* GXcopyInverted */ R2_MERGENOTPEN, /* GXorInverted */ R2_NOTMASKPEN, /* GXnand */ R2_WHITE /* GXset */ }; #endif #ifndef notdef INLINE static int Round(double x) { return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); } #else #define Round Round #endif /* *--------------------------------------------------------------------------- * Custom configuration option (parse and print) routines *--------------------------------------------------------------------------- */ static void DestroySymbol(Display *display, Symbol *symbolPtr) { if (symbolPtr->image != NULL) { Tk_FreeImage(symbolPtr->image); symbolPtr->image = NULL; } if (symbolPtr->bitmap != None) { Tk_FreeBitmap(display, symbolPtr->bitmap); symbolPtr->bitmap = None; } if (symbolPtr->mask != None) { Tk_FreeBitmap(display, symbolPtr->mask); symbolPtr->mask = None; } symbolPtr->type = SYMBOL_NONE; } /* *--------------------------------------------------------------------------- * * ImageChangedProc * * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Element *elemPtr; Graph *graphPtr; elemPtr = clientData; elemPtr->flags |= MAP_ITEM; graphPtr = elemPtr->obj.graphPtr; graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } /*ARGSUSED*/ static void FreeSymbolProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { Symbol *symbolPtr = (Symbol *)(widgRec + offset); DestroySymbol(display, symbolPtr); } /* *--------------------------------------------------------------------------- * * ObjToSymbol -- * * Convert the string representation of a line style or symbol name into * its numeric form. * * Results: * The return value is a standard TCL result. The symbol type is written * into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSymbolProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing symbol type */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Symbol *symbolPtr = (Symbol *)(widgRec + offset); const char *string; { int length; GraphSymbolType *p; char c; string = Tcl_GetStringFromObj(objPtr, &length); if (length == 0) { DestroySymbol(Tk_Display(tkwin), symbolPtr); symbolPtr->type = SYMBOL_NONE; return TCL_OK; } c = string[0]; for (p = graphSymbols; p->name != NULL; p++) { if (length < p->minChars) { continue; } if ((c == p->name[0]) && (strncmp(string, p->name, length) == 0)) { DestroySymbol(Tk_Display(tkwin), symbolPtr); symbolPtr->type = p->type; return TCL_OK; } } } { Tk_Image tkImage; Element *elemPtr = (Element *)widgRec; tkImage = Tk_GetImage(interp, tkwin, string, ImageChangedProc, elemPtr); if (tkImage != NULL) { DestroySymbol(Tk_Display(tkwin), symbolPtr); symbolPtr->image = tkImage; symbolPtr->type = SYMBOL_IMAGE; return TCL_OK; } } { Pixmap bitmap, mask; Tcl_Obj **objv; int objc; if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc > 2)) { goto error; } bitmap = mask = None; if (objc > 0) { bitmap = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, tkwin, objv[0]); if (bitmap == None) { goto error; } } if (objc > 1) { mask = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, tkwin, objv[1]); if (mask == None) { goto error; } } DestroySymbol(Tk_Display(tkwin), symbolPtr); symbolPtr->bitmap = bitmap; symbolPtr->mask = mask; symbolPtr->type = SYMBOL_BITMAP; return TCL_OK; } error: Tcl_AppendResult(interp, "bad symbol \"", string, "\": should be \"none\", \"circle\", \"square\", \"diamond\", " "\"plus\", \"cross\", \"splus\", \"scross\", \"triangle\", " "\"arrow\" or the name of a bitmap", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * SymbolToObj -- * * Convert the symbol value into a string. * * Results: * The string representing the symbol type or line style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SymbolToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Symbol *symbolPtr = (Symbol *)(widgRec + offset); if (symbolPtr->type == SYMBOL_BITMAP) { Tcl_Obj *listObjPtr, *objPtr; const char *name; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); name = Tk_NameOfBitmap(Tk_Display(tkwin), symbolPtr->bitmap); objPtr = Tcl_NewStringObj(name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (symbolPtr->mask == None) { objPtr = Tcl_NewStringObj("", -1); } else { name = Tk_NameOfBitmap(Tk_Display(tkwin), symbolPtr->mask); objPtr = Tcl_NewStringObj(name, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); return listObjPtr; } else { GraphSymbolType *p; for (p = graphSymbols; p->name != NULL; p++) { if (p->type == symbolPtr->type) { return Tcl_NewStringObj(p->name, -1); } } return Tcl_NewStringObj("?unknown symbol type?", -1); } } /* *--------------------------------------------------------------------------- * * NameOfSmooth -- * * Converts the smooth value into its string representation. * * Results: * The static string representing the smooth type is returned. * *--------------------------------------------------------------------------- */ static const char * NameOfSmooth(Smoothing value) { SmoothingInfo *siPtr; for (siPtr = smoothingInfo; siPtr->name != NULL; siPtr++) { if (siPtr->value == value) { return siPtr->name; } } return "unknown smooth value"; } /* *--------------------------------------------------------------------------- * * ObjToSmooth -- * * Convert the string representation of a line style or smooth name * into its numeric form. * * Results: * The return value is a standard TCL result. The smooth type is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSmoothProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing smooth type */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Smoothing *valuePtr = (Smoothing *)(widgRec + offset); SmoothingInfo *siPtr; const char *string; char c; string = Tcl_GetString(objPtr); c = string[0]; for (siPtr = smoothingInfo; siPtr->name != NULL; siPtr++) { if ((c == siPtr->name[0]) && (strcmp(string, siPtr->name) == 0)) { *valuePtr = siPtr->value; return TCL_OK; } } Tcl_AppendResult(interp, "bad smooth value \"", string, "\": should be \ linear, step, natural, or quadratic", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * SmoothToObj -- * * Convert the smooth value into a string. * * Results: * The string representing the smooth type or line style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SmoothToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int smooth = *(int *)(widgRec + offset); return Tcl_NewStringObj(NameOfSmooth(smooth), -1); } /* *--------------------------------------------------------------------------- * * ObjToPenDir -- * * Convert the string representation of a line style or symbol name * into its numeric form. * * Results: * The return value is a standard TCL result. The symbol type is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPenDirProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing pen direction */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *penDirPtr = (int *)(widgRec + offset); int length; char c; char *string; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'i') && (strncmp(string, "increasing", length) == 0)) { *penDirPtr = PEN_INCREASING; } else if ((c == 'd') && (strncmp(string, "decreasing", length) == 0)) { *penDirPtr = PEN_DECREASING; } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) { *penDirPtr = PEN_BOTH_DIRECTIONS; } else { Tcl_AppendResult(interp, "bad trace value \"", string, "\" : should be \"increasing\", \"decreasing\", or \"both\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NameOfPenDir -- * * Convert the pen direction into a string. * * Results: * The static string representing the pen direction is returned. * *--------------------------------------------------------------------------- */ static const char * NameOfPenDir(int penDir) { switch (penDir) { case PEN_INCREASING: return "increasing"; case PEN_DECREASING: return "decreasing"; case PEN_BOTH_DIRECTIONS: return "both"; default: return "unknown trace direction"; } } /* *--------------------------------------------------------------------------- * * PenDirToObj -- * * Convert the pen direction into a string. * * Results: * The string representing the pen drawing direction is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PenDirToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int penDir = *(int *)(widgRec + offset); return Tcl_NewStringObj(NameOfPenDir(penDir), -1); } /* * Reset the number of points and segments, in case there are no segments or * points */ static void ResetStylePalette(Blt_Chain styles) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); stylePtr->lines.length = stylePtr->symbolPts.length = 0; stylePtr->xeb.length = stylePtr->yeb.length = 0; } } /* *--------------------------------------------------------------------------- * * ConfigurePenProc -- * * Sets up the appropriate configuration parameters in the GC. It is * assumed the parameters have been previously set by a call to * Blt_ConfigureWidget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information such as line width, line style, color * etc. get set in a new GC. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigurePenProc(Graph *graphPtr, Pen *penPtr) { LinePen *lpPtr = (LinePen *)penPtr; unsigned long gcMask; GC newGC; XGCValues gcValues; XColor *colorPtr; /* * Set the outline GC for this pen: GCForeground is outline color. * GCBackground is the fill color (only used for bitmap symbols). */ gcMask = (GCLineWidth | GCForeground); colorPtr = lpPtr->symbol.outlineColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = lpPtr->traceColor; } gcValues.foreground = colorPtr->pixel; if (lpPtr->symbol.type == SYMBOL_BITMAP) { colorPtr = lpPtr->symbol.fillColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = lpPtr->traceColor; } /* * Set a clip mask if either * 1) no background color was designated or * 2) a masking bitmap was specified. * * These aren't necessarily the bitmaps we'll be using for clipping. But * this makes it unlikely that anyone else will be sharing this GC when * we set the clip origin (at the time the bitmap is drawn). */ if (colorPtr != NULL) { gcValues.background = colorPtr->pixel; gcMask |= GCBackground; if (lpPtr->symbol.mask != None) { gcValues.clip_mask = lpPtr->symbol.mask; gcMask |= GCClipMask; } } else { gcValues.clip_mask = lpPtr->symbol.bitmap; gcMask |= GCClipMask; } } gcValues.line_width = LineWidth(lpPtr->symbol.outlineWidth); newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (lpPtr->symbol.outlineGC != NULL) { Tk_FreeGC(graphPtr->display, lpPtr->symbol.outlineGC); } lpPtr->symbol.outlineGC = newGC; /* Fill GC for symbols: GCForeground is fill color */ gcMask = (GCLineWidth | GCForeground); colorPtr = lpPtr->symbol.fillColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = lpPtr->traceColor; } newGC = NULL; if (colorPtr != NULL) { gcValues.foreground = colorPtr->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); } if (lpPtr->symbol.fillGC != NULL) { Tk_FreeGC(graphPtr->display, lpPtr->symbol.fillGC); } lpPtr->symbol.fillGC = newGC; /* Line segments */ gcMask = (GCLineWidth | GCForeground | GCLineStyle | GCCapStyle | GCJoinStyle); gcValues.cap_style = CapButt; gcValues.join_style = JoinRound; gcValues.line_style = LineSolid; gcValues.line_width = LineWidth(lpPtr->traceWidth); colorPtr = lpPtr->traceOffColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = lpPtr->traceColor; } if (colorPtr != NULL) { gcMask |= GCBackground; gcValues.background = colorPtr->pixel; } gcValues.foreground = lpPtr->traceColor->pixel; if (LineIsDashed(lpPtr->traceDashes)) { gcValues.line_width = lpPtr->traceWidth; gcValues.line_style = (colorPtr == NULL) ? LineOnOffDash : LineDoubleDash; } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (lpPtr->traceGC != NULL) { Blt_FreePrivateGC(graphPtr->display, lpPtr->traceGC); } if (LineIsDashed(lpPtr->traceDashes)) { lpPtr->traceDashes.offset = lpPtr->traceDashes.values[0] / 2; Blt_SetDashes(graphPtr->display, newGC, &lpPtr->traceDashes); } lpPtr->traceGC = newGC; gcMask = (GCLineWidth | GCForeground); colorPtr = lpPtr->errorBarColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = lpPtr->traceColor; } gcValues.line_width = LineWidth(lpPtr->errorBarLineWidth); gcValues.foreground = colorPtr->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (lpPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, lpPtr->errorBarGC); } lpPtr->errorBarGC = newGC; return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyPenProc -- * * Release memory and resources allocated for the style. * * Results: * None. * * Side effects: * Everything associated with the pen style is freed up. * *--------------------------------------------------------------------------- */ static void DestroyPenProc(Graph *graphPtr, Pen *basePtr) { LinePen *penPtr = (LinePen *)basePtr; Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle); if (penPtr->symbol.outlineGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->symbol.outlineGC); } if (penPtr->symbol.fillGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->symbol.fillGC); } if (penPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->errorBarGC); } if (penPtr->traceGC != NULL) { Blt_FreePrivateGC(graphPtr->display, penPtr->traceGC); } if (penPtr->symbol.bitmap != None) { Tk_FreeBitmap(graphPtr->display, penPtr->symbol.bitmap); penPtr->symbol.bitmap = None; } if (penPtr->symbol.mask != None) { Tk_FreeBitmap(graphPtr->display, penPtr->symbol.mask); penPtr->symbol.mask = None; } } static void InitLinePen(LinePen *penPtr) { Blt_Ts_InitStyle(penPtr->valueStyle); penPtr->errorBarLineWidth = 2; penPtr->errorBarShow = SHOW_BOTH; penPtr->configProc = ConfigurePenProc; penPtr->configSpecs = linePenConfigSpecs; penPtr->destroyProc = DestroyPenProc; penPtr->flags = NORMAL_PEN; penPtr->name = ""; penPtr->symbol.bitmap = penPtr->symbol.mask = None; penPtr->symbol.outlineColor = penPtr->symbol.fillColor = COLOR_DEFAULT; penPtr->symbol.outlineWidth = penPtr->traceWidth = 1; penPtr->symbol.type = SYMBOL_CIRCLE; penPtr->valueShow = SHOW_NONE; } Pen * Blt_LinePen(const char *penName) { LinePen *penPtr; penPtr = Blt_AssertCalloc(1, sizeof(LinePen)); InitLinePen(penPtr); penPtr->name = Blt_AssertStrdup(penName); penPtr->classId = CID_ELEM_LINE; if (strcmp(penName, "activeLine") == 0) { penPtr->flags = ACTIVE_PEN; } return (Pen *)penPtr; } /* *--------------------------------------------------------------------------- * * In this section, the routines deal with building and filling the * element's data structures with transformed screen coordinates. They are * triggered from TranformLine which is called whenever the data or * coordinates axes have changed and new screen coordinates need to be * calculated. * *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * ScaleSymbol -- * * Returns the scaled size for the line element. Scaling depends upon when * the base line ranges for the element were set and the current range of * the graph. * * Results: * The new size of the symbol, after considering how much the graph has * been scaled, is returned. * *--------------------------------------------------------------------------- */ static int ScaleSymbol(LineElement *elemPtr, int normalSize) { int maxSize; double scale; int newSize; scale = 1.0; if (elemPtr->scaleSymbols) { double xRange, yRange; xRange = (elemPtr->axes.x->max - elemPtr->axes.x->min); yRange = (elemPtr->axes.y->max - elemPtr->axes.y->min); if (elemPtr->flags & SCALE_SYMBOL) { /* Save the ranges as a baseline for future scaling. */ elemPtr->xRange = xRange; elemPtr->yRange = yRange; elemPtr->flags &= ~SCALE_SYMBOL; } else { double xScale, yScale; /* Scale the symbol by the smallest change in the X or Y axes */ xScale = elemPtr->xRange / xRange; yScale = elemPtr->yRange / yRange; scale = MIN(xScale, yScale); } } newSize = Round(normalSize * scale); /* * Don't let the size of symbols go unbounded. Both X and Win32 drawing * routines assume coordinates to be a signed short int. */ maxSize = (int)MIN(elemPtr->obj.graphPtr->hRange, elemPtr->obj.graphPtr->vRange); if (newSize > maxSize) { newSize = maxSize; } /* Make the symbol size odd so that its center is a single pixel. */ newSize |= 0x01; return newSize; } /* *--------------------------------------------------------------------------- * * GetScreenPoints -- * * Generates a coordinate array of transformed screen coordinates from * the data points. Coordinates with Inf, -Inf, or NaN values are * removed. * * Results: * The transformed screen coordinates are returned. * * Side effects: * Memory is allocated for the coordinate array. * * * Future ideas: * Allow bad values to be removed (as done currently) or break * into separate traces. Smoothing would be affected. * *--------------------------------------------------------------------------- */ static void GetScreenPoints(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { double *x, *y; int i, np; int count; Point2d *points; int *map; np = NUMBEROFPOINTS(elemPtr); x = elemPtr->x.values; y = elemPtr->y.values; points = Blt_AssertMalloc(sizeof(Point2d) * np); map = Blt_AssertMalloc(sizeof(int) * np); count = 0; /* Count the valid screen coordinates */ if (graphPtr->inverted) { for (i = 0; i < np; i++) { if ((FINITE(x[i])) && (FINITE(y[i]))) { points[count].x = Blt_HMap(elemPtr->axes.y, y[i]); points[count].y = Blt_VMap(elemPtr->axes.x, x[i]); map[count] = i; count++; } } } else { for (i = 0; i < np; i++) { if ((FINITE(x[i])) && (FINITE(y[i]))) { points[count].x = Blt_HMap(elemPtr->axes.x, x[i]); points[count].y = Blt_VMap(elemPtr->axes.y, y[i]); map[count] = i; count++; } } } mapPtr->screenPts = points; mapPtr->nScreenPts = count; mapPtr->map = map; } /* *--------------------------------------------------------------------------- * * ReducePoints -- * * Generates a coordinate array of transformed screen coordinates from * the data points. * * Results: * The transformed screen coordinates are returned. * * Side effects: * Memory is allocated for the coordinate array. * *--------------------------------------------------------------------------- */ static void ReducePoints(MapInfo *mapPtr, double tolerance) { int i, np; Point2d *screenPts; int *map, *simple; simple = Blt_AssertMalloc(mapPtr->nScreenPts * sizeof(int)); map = Blt_AssertMalloc(mapPtr->nScreenPts * sizeof(int)); screenPts = Blt_AssertMalloc(mapPtr->nScreenPts * sizeof(Point2d)); np = Blt_SimplifyLine(mapPtr->screenPts, 0, mapPtr->nScreenPts - 1, tolerance, simple); for (i = 0; i < np; i++) { int k; k = simple[i]; screenPts[i] = mapPtr->screenPts[k]; map[i] = mapPtr->map[k]; } #ifdef notdef if (np < mapPtr->nScreenPts) { fprintf(stderr, "reduced from %d to %d\n", mapPtr->nScreenPts, np); } #endif Blt_Free(mapPtr->screenPts); Blt_Free(mapPtr->map); Blt_Free(simple); mapPtr->screenPts = screenPts; mapPtr->map = map; mapPtr->nScreenPts = np; } /* *--------------------------------------------------------------------------- * * GenerateSteps -- * * Resets the coordinate and pen index arrays adding new points for * step-and-hold type smoothing. * * Results: * None. * * Side Effects: * The temporary arrays for screen coordinates and pen indices * are updated. * *--------------------------------------------------------------------------- */ static void GenerateSteps(MapInfo *mapPtr) { int newSize; int i, count; Point2d *screenPts; int *map; newSize = ((mapPtr->nScreenPts - 1) * 2) + 1; screenPts = Blt_AssertMalloc(newSize * sizeof(Point2d)); map = Blt_AssertMalloc(sizeof(int) * newSize); screenPts[0] = mapPtr->screenPts[0]; map[0] = 0; count = 1; for (i = 1; i < mapPtr->nScreenPts; i++) { screenPts[count + 1] = mapPtr->screenPts[i]; /* Hold last y-coordinate, use new x-coordinate */ screenPts[count].x = screenPts[count + 1].x; screenPts[count].y = screenPts[count - 1].y; /* Use the same style for both the hold and the step points */ map[count] = map[count + 1] = mapPtr->map[i]; count += 2; } Blt_Free(mapPtr->screenPts); Blt_Free(mapPtr->map); mapPtr->map = map; mapPtr->screenPts = screenPts; mapPtr->nScreenPts = newSize; } /* *--------------------------------------------------------------------------- * * GenerateSpline -- * * Computes a spline based upon the data points, returning a new (larger) * coordinate array or points. * * Results: * None. * * Side Effects: * The temporary arrays for screen coordinates and data map are updated * based upon spline. * * FIXME: Can't interpolate knots along the Y-axis. Need to break * up point array into interchangable X and Y vectors earlier. * Pass extents (left/right or top/bottom) as parameters. * *--------------------------------------------------------------------------- */ static void GenerateSpline(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Point2d *origPts, *iPts; int *map; int extra; int niPts, nOrigPts; int result; int i, j, count; nOrigPts = mapPtr->nScreenPts; origPts = mapPtr->screenPts; assert(mapPtr->nScreenPts > 0); for (i = 0, j = 1; j < nOrigPts; i++, j++) { if (origPts[j].x <= origPts[i].x) { return; /* Points are not monotonically * increasing */ } } if (((origPts[0].x > (double)graphPtr->right)) || ((origPts[mapPtr->nScreenPts - 1].x < (double)graphPtr->left))) { return; /* All points are clipped */ } /* * The spline is computed in screen coordinates instead of data points so * that we can select the abscissas of the interpolated points from each * pixel horizontally across the plotting area. */ extra = (graphPtr->right - graphPtr->left) + 1; if (extra < 1) { return; } niPts = nOrigPts + extra + 1; iPts = Blt_AssertMalloc(niPts * sizeof(Point2d)); map = Blt_AssertMalloc(sizeof(int) * niPts); /* Populate the x2 array with both the original X-coordinates and extra * X-coordinates for each horizontal pixel that the line segment * contains. */ count = 0; for (i = 0, j = 1; j < nOrigPts; i++, j++) { /* Add the original x-coordinate */ iPts[count].x = origPts[i].x; /* Include the starting offset of the point in the offset array */ map[count] = mapPtr->map[i]; count++; /* Is any part of the interval (line segment) in the plotting area? */ if ((origPts[j].x >= (double)graphPtr->left) || (origPts[i].x <= (double)graphPtr->right)) { double x, last; x = origPts[i].x + 1.0; /* * Since the line segment may be partially clipped on the left or * right side, the points to interpolate are always interior to * the plotting area. * * left right * x1----|---------------------------|---x2 * * Pick the max of the starting X-coordinate and the left edge and * the min of the last X-coordinate and the right edge. */ x = MAX(x, (double)graphPtr->left); last = MIN(origPts[j].x, (double)graphPtr->right); /* Add the extra x-coordinates to the interval. */ while (x < last) { map[count] = mapPtr->map[i]; iPts[count++].x = x; x++; } } } niPts = count; result = FALSE; if (elemPtr->smooth == PEN_SMOOTH_NATURAL) { result = Blt_NaturalSpline(origPts, nOrigPts, iPts, niPts); } else if (elemPtr->smooth == PEN_SMOOTH_QUADRATIC) { result = Blt_QuadraticSpline(origPts, nOrigPts, iPts, niPts); } if (!result) { /* The spline interpolation failed. We'll fallback to the current * coordinates and do no smoothing (standard line segments). */ elemPtr->smooth = PEN_SMOOTH_LINEAR; Blt_Free(iPts); Blt_Free(map); } else { Blt_Free(mapPtr->screenPts); Blt_Free(mapPtr->map); mapPtr->map = map; mapPtr->screenPts = iPts; mapPtr->nScreenPts = niPts; } } /* *--------------------------------------------------------------------------- * * GenerateParametricSpline -- * * Computes a spline based upon the data points, returning a new (larger) * coordinate array or points. * * Results: * None. * * Side Effects: * The temporary arrays for screen coordinates and data map are updated * based upon spline. * * FIXME: Can't interpolate knots along the Y-axis. Need to break * up point array into interchangable X and Y vectors earlier. * Pass extents (left/right or top/bottom) as parameters. * *--------------------------------------------------------------------------- */ static void GenerateParametricSpline(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Region2d exts; Point2d *origPts, *iPts; int *map; int niPts, nOrigPts; int result; int i, j, count; nOrigPts = mapPtr->nScreenPts; origPts = mapPtr->screenPts; assert(mapPtr->nScreenPts > 0); Blt_GraphExtents(graphPtr, &exts); /* * Populate the x2 array with both the original X-coordinates and extra * X-coordinates for each horizontal pixel that the line segment contains. */ count = 1; for (i = 0, j = 1; j < nOrigPts; i++, j++) { Point2d p, q; p = origPts[i]; q = origPts[j]; count++; if (Blt_LineRectClip(&exts, &p, &q)) { count += (int)(hypot(q.x - p.x, q.y - p.y) * 0.5); } } niPts = count; iPts = Blt_AssertMalloc(niPts * sizeof(Point2d)); map = Blt_AssertMalloc(sizeof(int) * niPts); /* * FIXME: This is just plain wrong. The spline should be computed * and evaluated in separate steps. This will mean breaking * up this routine since the catrom coefficients can be * independently computed for original data point. This * also handles the problem of allocating enough points * since evaluation is independent of the number of points * to be evalualted. The interpolated * line segments should be clipped, not the original segments. */ count = 0; for (i = 0, j = 1; j < nOrigPts; i++, j++) { Point2d p, q; double d; p = origPts[i]; q = origPts[j]; d = hypot(q.x - p.x, q.y - p.y); /* Add the original x-coordinate */ iPts[count].x = (double)i; iPts[count].y = 0.0; /* Include the starting offset of the point in the offset array */ map[count] = mapPtr->map[i]; count++; /* Is any part of the interval (line segment) in the plotting * area? */ if (Blt_LineRectClip(&exts, &p, &q)) { double dp, dq; /* Distance of original point to p. */ dp = hypot(p.x - origPts[i].x, p.y - origPts[i].y); /* Distance of original point to q. */ dq = hypot(q.x - origPts[i].x, q.y - origPts[i].y); dp += 2.0; while(dp <= dq) { /* Point is indicated by its interval and parameter t. */ iPts[count].x = (double)i; iPts[count].y = dp / d; map[count] = mapPtr->map[i]; count++; dp += 2.0; } } } iPts[count].x = (double)i; iPts[count].y = 0.0; map[count] = mapPtr->map[i]; count++; niPts = count; result = FALSE; if (elemPtr->smooth == PEN_SMOOTH_NATURAL) { result = Blt_NaturalParametricSpline(origPts, nOrigPts, &exts, FALSE, iPts, niPts); } else if (elemPtr->smooth == PEN_SMOOTH_CATROM) { result = Blt_CatromParametricSpline(origPts, nOrigPts, iPts, niPts); } if (!result) { /* The spline interpolation failed. We will fall back to the current * coordinates and do no smoothing (standard line segments). */ elemPtr->smooth = PEN_SMOOTH_LINEAR; Blt_Free(iPts); Blt_Free(map); } else { Blt_Free(mapPtr->screenPts); Blt_Free(mapPtr->map); mapPtr->map = map; mapPtr->screenPts = iPts; mapPtr->nScreenPts = niPts; } } /* *--------------------------------------------------------------------------- * * MapSymbols -- * * Creates two arrays of points and pen map, filled with the screen * coordinates of the visible * * Results: * None. * * Side effects: * Memory is freed and allocated for the index array. * *--------------------------------------------------------------------------- */ static void MapSymbols(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Region2d exts; Point2d *pp, *points; int *map; int i, count; points = Blt_AssertMalloc(sizeof(Point2d) * mapPtr->nScreenPts); map = Blt_AssertMalloc(sizeof(int) * mapPtr->nScreenPts); Blt_GraphExtents(graphPtr, &exts); count = 0; /* Count the number of visible points */ for (pp = mapPtr->screenPts, i = 0; i < mapPtr->nScreenPts; i++, pp++) { if (PointInRegion(&exts, pp->x, pp->y)) { points[count].x = pp->x; points[count].y = pp->y; map[count] = mapPtr->map[i]; count++; } } elemPtr->symbolPts.points = points; elemPtr->symbolPts.length = count; elemPtr->symbolPts.map = map; } /* *--------------------------------------------------------------------------- * * MapActiveSymbols -- * * Creates an array of points of the active graph coordinates. * * Results: * None. * * Side effects: * Memory is freed and allocated for the active point array. * *--------------------------------------------------------------------------- */ static void MapActiveSymbols(Graph *graphPtr, LineElement *elemPtr) { Point2d *points; Region2d exts; int *map; int count, i, np; if (elemPtr->activePts.points != NULL) { Blt_Free(elemPtr->activePts.points); elemPtr->activePts.points = NULL; } if (elemPtr->activePts.map != NULL) { Blt_Free(elemPtr->activePts.map); elemPtr->activePts.map = NULL; } Blt_GraphExtents(graphPtr, &exts); points = Blt_AssertMalloc(sizeof(Point2d) * elemPtr->nActiveIndices); map = Blt_AssertMalloc(sizeof(int) * elemPtr->nActiveIndices); np = NUMBEROFPOINTS(elemPtr); count = 0; /* Count the visible active points */ for (i = 0; i < elemPtr->nActiveIndices; i++) { double x, y; int iPoint; iPoint = elemPtr->activeIndices[i]; if (iPoint >= np) { continue; /* Index not available */ } x = elemPtr->x.values[iPoint]; y = elemPtr->y.values[iPoint]; points[count] = Blt_Map2D(graphPtr, x, y, &elemPtr->axes); map[count] = iPoint; if (PointInRegion(&exts, points[count].x, points[count].y)) { count++; } } if (count > 0) { elemPtr->activePts.points = points; elemPtr->activePts.map = map; } else { /* No active points were visible. */ Blt_Free(points); Blt_Free(map); } elemPtr->activePts.length = count; elemPtr->flags &= ~ACTIVE_PENDING; } /* *--------------------------------------------------------------------------- * * MapStrip -- * * Creates an array of line segments of the graph coordinates. * * Results: * None. * * Side effects: * Memory is allocated for the line segment array. * *--------------------------------------------------------------------------- */ static void MapStrip(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Region2d exts; Segment2d *lines; int *indices, *indexPtr; Point2d *pend, *pp; Segment2d *sp; int count; indices = Blt_AssertMalloc(sizeof(int) * mapPtr->nScreenPts); /* * Create array to hold points for line segments (not polyline * coordinates). So allocate twice the number of points. */ sp = lines = Blt_AssertMalloc(mapPtr->nScreenPts * sizeof(Segment2d)); Blt_GraphExtents(graphPtr, &exts); count = 0; /* Count the number of segments. */ indexPtr = mapPtr->map; for (pp = mapPtr->screenPts, pend = pp + (mapPtr->nScreenPts - 1); pp < pend; pp++, indexPtr++) { sp->p = pp[0], sp->q = pp[1]; if (Blt_LineRectClip(&exts, &sp->p, &sp->q)) { sp++; indices[count] = *indexPtr; count++; } } elemPtr->lines.map = indices; elemPtr->lines.length = count; elemPtr->lines.segments = lines; } /* *--------------------------------------------------------------------------- * * MergePens -- * * Reorders the both arrays of points and segments to merge pens. * * Results: * None. * * Side effects: * The old arrays are freed and new ones allocated containing * the reordered points and segments. * *--------------------------------------------------------------------------- */ static void MergePens(LineElement *elemPtr, LineStyle **styleMap) { if (Blt_Chain_GetLength(elemPtr->styles) < 2) { Blt_ChainLink link; LineStyle *stylePtr; link = Blt_Chain_FirstLink(elemPtr->styles); stylePtr = Blt_Chain_GetValue(link); stylePtr->errorBarCapWidth = elemPtr->errorBarCapWidth; stylePtr->lines.length = elemPtr->lines.length; stylePtr->lines.segments = elemPtr->lines.segments; stylePtr->symbolPts.length = elemPtr->symbolPts.length; stylePtr->symbolPts.points = elemPtr->symbolPts.points; stylePtr->xeb.length = elemPtr->xeb.length; stylePtr->xeb.segments = elemPtr->xeb.segments; stylePtr->yeb.length = elemPtr->yeb.length; stylePtr->yeb.segments = elemPtr->yeb.segments; return; } /* We have more than one style. Group line segments and points of like pen * styles. */ if (elemPtr->lines.length > 0) { Blt_ChainLink link; Segment2d *sp, *segments; int *ip; int *map; segments = Blt_AssertMalloc(elemPtr->lines.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->lines.length * sizeof(int)); sp = segments, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->lines.segments = sp; for (i = 0; i < elemPtr->lines.length; i++) { int iData; iData = elemPtr->lines.map[i]; if (styleMap[iData] == stylePtr) { *sp++ = elemPtr->lines.segments[i]; *ip++ = iData; } } stylePtr->lines.length = sp - stylePtr->lines.segments; } Blt_Free(elemPtr->lines.segments); elemPtr->lines.segments = segments; Blt_Free(elemPtr->lines.map); elemPtr->lines.map = map; } if (elemPtr->symbolPts.length > 0) { Blt_ChainLink link; int *ip; Point2d *points, *pp; int *map; points = Blt_AssertMalloc(elemPtr->symbolPts.length * sizeof(Point2d)); map = Blt_AssertMalloc(elemPtr->symbolPts.length * sizeof(int)); pp = points, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->symbolPts.points = pp; for (i = 0; i < elemPtr->symbolPts.length; i++) { int iData; iData = elemPtr->symbolPts.map[i]; if (styleMap[iData] == stylePtr) { *pp++ = elemPtr->symbolPts.points[i]; *ip++ = iData; } } stylePtr->symbolPts.length = pp - stylePtr->symbolPts.points; } Blt_Free(elemPtr->symbolPts.points); Blt_Free(elemPtr->symbolPts.map); elemPtr->symbolPts.points = points; elemPtr->symbolPts.map = map; } if (elemPtr->xeb.length > 0) { Segment2d *segments, *sp; int *map, *ip; Blt_ChainLink link; segments = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(int)); sp = segments, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->xeb.segments = sp; for (i = 0; i < elemPtr->xeb.length; i++) { int iData; iData = elemPtr->xeb.map[i]; if (styleMap[iData] == stylePtr) { *sp++ = elemPtr->xeb.segments[i]; *ip++ = iData; } } stylePtr->xeb.length = sp - stylePtr->xeb.segments; } Blt_Free(elemPtr->xeb.segments); Blt_Free(elemPtr->xeb.map); elemPtr->xeb.segments = segments; elemPtr->xeb.map = map; } if (elemPtr->yeb.length > 0) { Segment2d *segments, *sp; int *map, *ip; Blt_ChainLink link; segments = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(int)); sp = segments, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->yeb.segments = sp; for (i = 0; i < elemPtr->yeb.length; i++) { int iData; iData = elemPtr->yeb.map[i]; if (styleMap[iData] == stylePtr) { *sp++ = elemPtr->yeb.segments[i]; *ip++ = iData; } } stylePtr->yeb.length = sp - stylePtr->yeb.segments; } Blt_Free(elemPtr->yeb.segments); elemPtr->yeb.segments = segments; Blt_Free(elemPtr->yeb.map); elemPtr->yeb.map = map; } } #define CLIP_TOP (1<<0) #define CLIP_BOTTOM (1<<1) #define CLIP_RIGHT (1<<2) #define CLIP_LEFT (1<<3) INLINE static int OutCode(Region2d *extsPtr, Point2d *p) { int code; code = 0; if (p->x > extsPtr->right) { code |= CLIP_RIGHT; } else if (p->x < extsPtr->left) { code |= CLIP_LEFT; } if (p->y > extsPtr->bottom) { code |= CLIP_BOTTOM; } else if (p->y < extsPtr->top) { code |= CLIP_TOP; } return code; } static int ClipSegment( Region2d *extsPtr, int code1, int code2, Point2d *p, Point2d *q) { int inside, outside; inside = ((code1 | code2) == 0); outside = ((code1 & code2) != 0); /* * In the worst case, we'll clip the line segment against each of the four * sides of the bounding rectangle. */ while ((!outside) && (!inside)) { if (code1 == 0) { Point2d *tmp; int code; /* Swap pointers and out codes */ tmp = p, p = q, q = tmp; code = code1, code1 = code2, code2 = code; } if (code1 & CLIP_LEFT) { p->y += (q->y - p->y) * (extsPtr->left - p->x) / (q->x - p->x); p->x = extsPtr->left; } else if (code1 & CLIP_RIGHT) { p->y += (q->y - p->y) * (extsPtr->right - p->x) / (q->x - p->x); p->x = extsPtr->right; } else if (code1 & CLIP_BOTTOM) { p->x += (q->x - p->x) * (extsPtr->bottom - p->y) / (q->y - p->y); p->y = extsPtr->bottom; } else if (code1 & CLIP_TOP) { p->x += (q->x - p->x) * (extsPtr->top - p->y) / (q->y - p->y); p->y = extsPtr->top; } code1 = OutCode(extsPtr, p); inside = ((code1 | code2) == 0); outside = ((code1 & code2) != 0); } return (!inside); } /* *--------------------------------------------------------------------------- * * SaveTrace -- * * Creates a new trace and inserts it into the line's list of traces. * * Results: * None. * *--------------------------------------------------------------------------- */ static void SaveTrace( LineElement *elemPtr, int start, /* Starting index of the trace in data point * array. Used to figure out closest point */ int length, /* Number of points forming the trace */ MapInfo *mapPtr) { Trace *tracePtr; Point2d *screenPts; int *map; int i, j; tracePtr = Blt_AssertMalloc(sizeof(Trace)); screenPts = Blt_AssertMalloc(sizeof(Point2d) * length); map = Blt_AssertMalloc(sizeof(int) * length); /* Copy the screen coordinates of the trace into the point array */ if (mapPtr->map != NULL) { for (i = 0, j = start; i < length; i++, j++) { screenPts[i].x = mapPtr->screenPts[j].x; screenPts[i].y = mapPtr->screenPts[j].y; map[i] = mapPtr->map[j]; } } else { for (i = 0, j = start; i < length; i++, j++) { screenPts[i].x = mapPtr->screenPts[j].x; screenPts[i].y = mapPtr->screenPts[j].y; map[i] = j; } } tracePtr->screenPts.length = length; tracePtr->screenPts.points = screenPts; tracePtr->screenPts.map = map; tracePtr->start = start; if (elemPtr->traces == NULL) { elemPtr->traces = Blt_Chain_Create(); } Blt_Chain_Append(elemPtr->traces, tracePtr); } /* *--------------------------------------------------------------------------- * * FreeTraces -- * * Deletes all the traces for the line. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeTraces(LineElement *elemPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { Trace *tracePtr; tracePtr = Blt_Chain_GetValue(link); Blt_Free(tracePtr->screenPts.map); Blt_Free(tracePtr->screenPts.points); Blt_Free(tracePtr); } Blt_Chain_Destroy(elemPtr->traces); elemPtr->traces = NULL; } /* *--------------------------------------------------------------------------- * * MapTraces -- * * Creates an array of line segments of the graph coordinates. * * Results: * None. * * Side effects: * Memory is allocated for the line segment array. * *--------------------------------------------------------------------------- */ static void MapTraces(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Point2d *p, *q; Region2d exts; int code1; int i; int start, count; Blt_GraphExtents(graphPtr, &exts); count = 1; code1 = OutCode(&exts, mapPtr->screenPts); p = mapPtr->screenPts; q = p + 1; for (i = 1; i < mapPtr->nScreenPts; i++, p++, q++) { Point2d s; int code2; int broken, offscreen; s.x = s.y = 0; code2 = OutCode(&exts, q); if (code2 != 0) { /* Save the coordinates of the last point, before clipping */ s = *q; } broken = BROKEN_TRACE(elemPtr->penDir, p->x, q->x); offscreen = ClipSegment(&exts, code1, code2, p, q); if (broken || offscreen) { /* * The last line segment is either totally clipped by the plotting * area or the x-direction is wrong, breaking the trace. Either * way, save information about the last trace (if one exists), * discarding the current line segment */ if (count > 1) { start = i - count; SaveTrace(elemPtr, start, count, mapPtr); count = 1; } } else { count++; /* Add the point to the trace. */ if (code2 != 0) { /* * If the last point is clipped, this means that the trace is * broken after this point. Restore the original coordinate * (before clipping) after saving the trace. */ start = i - (count - 1); SaveTrace(elemPtr, start, count, mapPtr); mapPtr->screenPts[i] = s; count = 1; } } code1 = code2; } if (count > 1) { start = i - count; SaveTrace(elemPtr, start, count, mapPtr); } } /* *--------------------------------------------------------------------------- * * MapFillArea -- * * Creates an array of points that represent a polygon that fills * the area under the element. * * Results: * None. * * Side effects: * Memory is allocated for the polygon point array. * *--------------------------------------------------------------------------- */ static void MapFillArea(Graph *graphPtr, LineElement *elemPtr, MapInfo *mapPtr) { Point2d *origPts, *clipPts; Region2d exts; int np; if (elemPtr->fillPts != NULL) { Blt_Free(elemPtr->fillPts); elemPtr->fillPts = NULL; elemPtr->nFillPts = 0; } if (mapPtr->nScreenPts < 3) { return; } np = mapPtr->nScreenPts + 3; Blt_GraphExtents(graphPtr, &exts); origPts = Blt_AssertMalloc(sizeof(Point2d) * np); if (graphPtr->inverted) { double minX; int i; minX = (double)elemPtr->axes.y->screenMin; for (i = 0; i < mapPtr->nScreenPts; i++) { origPts[i].x = mapPtr->screenPts[i].x + 1; origPts[i].y = mapPtr->screenPts[i].y; if (origPts[i].x < minX) { minX = origPts[i].x; } } /* Add edges to make (if necessary) the polygon fill to the bottom of * plotting window */ origPts[i].x = minX; origPts[i].y = origPts[i - 1].y; i++; origPts[i].x = minX; origPts[i].y = origPts[0].y; i++; origPts[i] = origPts[0]; } else { double maxY; int i; maxY = (double)elemPtr->axes.y->bottom; for (i = 0; i < mapPtr->nScreenPts; i++) { origPts[i].x = mapPtr->screenPts[i].x + 1; origPts[i].y = mapPtr->screenPts[i].y; if (origPts[i].y > maxY) { maxY = origPts[i].y; } } /* Add edges to extend the fill polygon to the bottom of plotting * window */ origPts[i].x = origPts[i - 1].x; origPts[i].y = maxY; i++; origPts[i].x = origPts[0].x; origPts[i].y = maxY; i++; origPts[i] = origPts[0]; } clipPts = Blt_AssertMalloc(sizeof(Point2d) * np * 3); np = Blt_PolyRectClip(&exts, origPts, np - 1, clipPts); Blt_Free(origPts); if (np < 3) { Blt_Free(clipPts); } else { elemPtr->fillPts = clipPts; elemPtr->nFillPts = np; } } static void ResetLine(LineElement *elemPtr) { FreeTraces(elemPtr); ResetStylePalette(elemPtr->styles); if (elemPtr->symbolPts.points != NULL) { Blt_Free(elemPtr->symbolPts.points); } if (elemPtr->symbolPts.map != NULL) { Blt_Free(elemPtr->symbolPts.map); } if (elemPtr->lines.segments != NULL) { Blt_Free(elemPtr->lines.segments); } if (elemPtr->lines.map != NULL) { Blt_Free(elemPtr->lines.map); } if (elemPtr->activePts.points != NULL) { Blt_Free(elemPtr->activePts.points); } if (elemPtr->activePts.map != NULL) { Blt_Free(elemPtr->activePts.map); } if (elemPtr->xeb.segments != NULL) { Blt_Free(elemPtr->xeb.segments); } if (elemPtr->xeb.map != NULL) { Blt_Free(elemPtr->xeb.map); } if (elemPtr->yeb.segments != NULL) { Blt_Free(elemPtr->yeb.segments); } if (elemPtr->yeb.map != NULL) { Blt_Free(elemPtr->yeb.map); } elemPtr->xeb.segments = elemPtr->yeb.segments = elemPtr->lines.segments = NULL; elemPtr->symbolPts.points = elemPtr->activePts.points = NULL; elemPtr->lines.map = elemPtr->symbolPts.map = elemPtr->xeb.map = elemPtr->yeb.map = elemPtr->activePts.map = NULL; elemPtr->activePts.length = elemPtr->symbolPts.length = elemPtr->lines.length = elemPtr->xeb.length = elemPtr->yeb.length = 0; } /* *--------------------------------------------------------------------------- * * MapErrorBars -- * * Creates two arrays of points and pen indices, filled with the screen * coordinates of the visible * * Results: * None. * * Side effects: * Memory is freed and allocated for the index array. * *--------------------------------------------------------------------------- */ static void MapErrorBars(Graph *graphPtr, LineElement *elemPtr, LineStyle **styleMap) { int n, np; Region2d exts; Blt_GraphExtents(graphPtr, &exts); np = NUMBEROFPOINTS(elemPtr); if (elemPtr->xError.nValues > 0) { n = MIN(elemPtr->xError.nValues, np); } else { n = MIN3(elemPtr->xHigh.nValues, elemPtr->xLow.nValues, np); } if (n > 0) { Segment2d *errorBars; Segment2d *segPtr; int *errorToData; int *indexPtr; int i; segPtr = errorBars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = errorToData = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; LineStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = styleMap[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->xError.nValues > 0) { high = x + elemPtr->xError.values[i]; low = x - elemPtr->xError.values[i]; } else { high = elemPtr->xHigh.values[i]; low = elemPtr->xLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, high, y, &elemPtr->axes); q = Blt_Map2D(graphPtr, low, y, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Left cap */ segPtr->p.x = segPtr->q.x = p.x; segPtr->p.y = p.y - stylePtr->errorBarCapWidth; segPtr->q.y = p.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Right cap */ segPtr->p.x = segPtr->q.x = q.x; segPtr->p.y = q.y - stylePtr->errorBarCapWidth; segPtr->q.y = q.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->xeb.segments = errorBars; elemPtr->xeb.length = segPtr - errorBars; elemPtr->xeb.map = errorToData; } if (elemPtr->yError.nValues > 0) { n = MIN(elemPtr->yError.nValues, np); } else { n = MIN3(elemPtr->yHigh.nValues, elemPtr->yLow.nValues, np); } if (n > 0) { Segment2d *errorBars; Segment2d *segPtr; int *errorToData; int *indexPtr; int i; segPtr = errorBars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = errorToData = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; LineStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = styleMap[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->yError.nValues > 0) { high = y + elemPtr->yError.values[i]; low = y - elemPtr->yError.values[i]; } else { high = elemPtr->yHigh.values[i]; low = elemPtr->yLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, x, high, &elemPtr->axes); q = Blt_Map2D(graphPtr, x, low, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Top cap. */ segPtr->p.y = segPtr->q.y = p.y; segPtr->p.x = p.x - stylePtr->errorBarCapWidth; segPtr->q.x = p.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Bottom cap. */ segPtr->p.y = segPtr->q.y = q.y; segPtr->p.x = q.x - stylePtr->errorBarCapWidth; segPtr->q.x = q.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->yeb.segments = errorBars; elemPtr->yeb.length = segPtr - errorBars; elemPtr->yeb.map = errorToData; } } /* *--------------------------------------------------------------------------- * * MapLineProc -- * * Calculates the actual window coordinates of the line element. The * window coordinates are saved in an allocated point array. * * Results: * None. * * Side effects: * Memory is (re)allocated for the point array. * *--------------------------------------------------------------------------- */ static void MapLineProc(Graph *graphPtr, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; MapInfo mi; int size, np; LineStyle **styleMap; Blt_ChainLink link; ResetLine(elemPtr); np = NUMBEROFPOINTS(elemPtr); if (np < 1) { return; /* No data points */ } GetScreenPoints(graphPtr, elemPtr, &mi); MapSymbols(graphPtr, elemPtr, &mi); if ((elemPtr->flags & ACTIVE_PENDING) && (elemPtr->nActiveIndices > 0)) { MapActiveSymbols(graphPtr, elemPtr); } /* * Map connecting line segments if they are to be displayed. */ elemPtr->smooth = elemPtr->reqSmooth; if ((np > 1) && ((graphPtr->classId == CID_ELEM_STRIP) || (elemPtr->builtinPen.traceWidth > 0))) { /* * Do smoothing if necessary. This can extend the coordinate array, * so both mi.points and mi.nPoints may change. */ switch (elemPtr->smooth) { case PEN_SMOOTH_STEP: GenerateSteps(&mi); break; case PEN_SMOOTH_NATURAL: case PEN_SMOOTH_QUADRATIC: if (mi.nScreenPts < 3) { /* Can't interpolate with less than three points. */ elemPtr->smooth = PEN_SMOOTH_LINEAR; } else { GenerateSpline(graphPtr, elemPtr, &mi); } break; case PEN_SMOOTH_CATROM: if (mi.nScreenPts < 3) { /* Can't interpolate with less than three points. */ elemPtr->smooth = PEN_SMOOTH_LINEAR; } else { GenerateParametricSpline(graphPtr, elemPtr, &mi); } break; default: break; } if (elemPtr->rTolerance > 0.0) { ReducePoints(&mi, elemPtr->rTolerance); } if (elemPtr->fillBg != NULL) { MapFillArea(graphPtr, elemPtr, &mi); } if (graphPtr->classId == CID_ELEM_STRIP) { MapStrip(graphPtr, elemPtr, &mi); } else { MapTraces(graphPtr, elemPtr, &mi); } } Blt_Free(mi.screenPts); Blt_Free(mi.map); /* Set the symbol size of all the pen styles. */ for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; size = ScaleSymbol(elemPtr, penPtr->symbol.size); stylePtr->symbolSize = size; stylePtr->errorBarCapWidth = (penPtr->errorBarCapWidth > 0) ? penPtr->errorBarCapWidth : Round(size * 0.6666666); stylePtr->errorBarCapWidth /= 2; } styleMap = (LineStyle **)Blt_StyleMap((Element *)elemPtr); if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) || ((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) || (elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) { MapErrorBars(graphPtr, elemPtr, styleMap); } MergePens(elemPtr, styleMap); Blt_Free(styleMap); } static double DistanceToLineProc( int x, int y, /* Sample X-Y coordinate. */ Point2d *p, Point2d *q, /* End points of the line segment. */ Point2d *t) /* (out) Point on line segment. */ { double right, left, top, bottom; *t = Blt_GetProjection(x, y, p, q); if (p->x > q->x) { right = p->x, left = q->x; } else { left = p->x, right = q->x; } if (p->y > q->y) { bottom = p->y, top = q->y; } else { top = p->y, bottom = q->y; } if (t->x > right) { t->x = right; } else if (t->x < left) { t->x = left; } if (t->y > bottom) { t->y = bottom; } else if (t->y < top) { t->y = top; } return hypot((t->x - x), (t->y - y)); } static double DistanceToXProc( int x, int y, /* Search X-Y coordinate. */ Point2d *p, Point2d *q, /* End points of the line segment. */ Point2d *t) /* (out) Point on line segment. */ { double dx, dy; double d; if (p->x > q->x) { if ((x > p->x) || (x < q->x)) { return DBL_MAX; /* X-coordinate outside line segment. */ } } else { if ((x > q->x) || (x < p->x)) { return DBL_MAX; /* X-coordinate outside line segment. */ } } dx = p->x - q->x; dy = p->y - q->y; t->x = (double)x; if (FABS(dx) < DBL_EPSILON) { double d1, d2; /* * Same X-coordinate indicates a vertical line. Pick the closest end * point. */ d1 = p->y - y; d2 = q->y - y; if (FABS(d1) < FABS(d2)) { t->y = p->y, d = d1; } else { t->y = q->y, d = d2; } } else if (FABS(dy) < DBL_EPSILON) { /* Horizontal line. */ t->y = p->y, d = p->y - y; } else { double m, b; m = dy / dx; b = p->y - (m * p->x); t->y = (x * m) + b; d = y - t->y; } return FABS(d); } static double DistanceToYProc( int x, int y, /* Search X-Y coordinate. */ Point2d *p, Point2d *q, /* End points of the line segment. */ Point2d *t) /* (out) Point on line segment. */ { double dx, dy; double d; if (p->y > q->y) { if ((y > p->y) || (y < q->y)) { return DBL_MAX; } } else { if ((y > q->y) || (y < p->y)) { return DBL_MAX; } } dx = p->x - q->x; dy = p->y - q->y; t->y = y; if (FABS(dy) < DBL_EPSILON) { double d1, d2; /* Save Y-coordinate indicates an horizontal line. Pick the closest end * point. */ d1 = p->x - x; d2 = q->x - x; if (FABS(d1) < FABS(d2)) { t->x = p->x, d = d1; } else { t->x = q->x, d = d2; } } else if (FABS(dx) < DBL_EPSILON) { /* Vertical line. */ t->x = p->x, d = p->x - x; } else { double m, b; m = dy / dx; b = p->y - (m * p->x); t->x = (y - b) / m; d = x - t->x; } return FABS(d); } /* *--------------------------------------------------------------------------- * * ClosestTrace -- * * Find the line segment closest to the given window coordinate in the * element. * * Results: * If a new minimum distance is found, the information regarding it is * returned via searchPtr. * *--------------------------------------------------------------------------- */ static int ClosestTrace( Graph *graphPtr, /* Graph widget record */ LineElement *elemPtr, ClosestSearch *searchPtr, /* Info about closest point in * element */ DistanceProc *distProc) { Blt_ChainLink link; Point2d closest; double dMin; int iClose; iClose = -1; /* Suppress compiler warning. */ dMin = searchPtr->dist; closest.x = closest.y = 0; /* Suppress compiler warning. */ for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { Trace *tracePtr; Point2d *p, *pend; tracePtr = Blt_Chain_GetValue(link); for (p = tracePtr->screenPts.points, pend = p + (tracePtr->screenPts.length - 1); p < pend; p++) { Point2d b; double d; d = (*distProc)(searchPtr->x, searchPtr->y, p, p + 1, &b); if (d < dMin) { closest = b; iClose = tracePtr->screenPts.map[p-tracePtr->screenPts.points]; dMin = d; } } } if (dMin < searchPtr->dist) { searchPtr->dist = dMin; searchPtr->elemPtr = (Element *)elemPtr; searchPtr->index = iClose; searchPtr->point = Blt_InvMap2D(graphPtr, closest.x, closest.y, &elemPtr->axes); return TRUE; } return FALSE; } /* *--------------------------------------------------------------------------- * * ClosestStrip -- * * Find the line segment closest to the given window coordinate in the * element. * * Results: * If a new minimum distance is found, the information regarding it is * returned via searchPtr. * *--------------------------------------------------------------------------- */ static int ClosestStrip( Graph *graphPtr, /* Graph widget record */ LineElement *elemPtr, /* Line element record */ ClosestSearch *searchPtr, /* Info about closest point in * element */ DistanceProc *distProc) { Point2d closest; double dMin; int count; int iClose; Segment2d *sp; iClose = 0; dMin = searchPtr->dist; closest.x = closest.y = 0; for (sp = elemPtr->lines.segments, count = 0; count < elemPtr->lines.length; count++, sp++) { double d; Point2d b; d = (*distProc)(searchPtr->x, searchPtr->y, &sp->p, &sp->q, &b); if (d < dMin) { closest = b; iClose = elemPtr->lines.map[count]; dMin = d; } } if (dMin < searchPtr->dist) { searchPtr->dist = dMin; searchPtr->elemPtr = (Element *)elemPtr; searchPtr->index = iClose; searchPtr->point = Blt_InvMap2D(graphPtr, closest.x, closest.y, &elemPtr->axes); return TRUE; } return FALSE; } /* *--------------------------------------------------------------------------- * * ClosestPoint -- * * Find the element whose data point is closest to the given screen * coordinate. * * Results: * If a new minimum distance is found, the information regarding * it is returned via searchPtr. * *--------------------------------------------------------------------------- */ static void ClosestPoint( LineElement *elemPtr, /* Line element to be searched. */ ClosestSearch *searchPtr) /* Assorted information related to * searching for the closest point */ { double dMin; int count, iClose; Point2d *pp; dMin = searchPtr->dist; iClose = 0; /* * Instead of testing each data point in graph coordinates, look at the * array of mapped screen coordinates. The advantages are * 1) only examine points that are visible (unclipped), and * 2) the computed distance is already in screen coordinates. */ for (pp = elemPtr->symbolPts.points, count = 0; count < elemPtr->symbolPts.length; count++, pp++) { double dx, dy; double d; dx = (double)(searchPtr->x - pp->x); dy = (double)(searchPtr->y - pp->y); if (searchPtr->along == SEARCH_BOTH) { d = hypot(dx, dy); } else if (searchPtr->along == SEARCH_X) { d = dx; } else if (searchPtr->along == SEARCH_Y) { d = dy; } else { /* This can't happen */ continue; } if (d < dMin) { iClose = elemPtr->symbolPts.map[count]; dMin = d; } } if (dMin < searchPtr->dist) { searchPtr->elemPtr = (Element *)elemPtr; searchPtr->dist = dMin; searchPtr->index = iClose; searchPtr->point.x = elemPtr->x.values[iClose]; searchPtr->point.y = elemPtr->y.values[iClose]; } } /* *--------------------------------------------------------------------------- * * GetLineExtentsProc -- * * Retrieves the range of the line element * * Results: * Returns the number of data points in the element. * *--------------------------------------------------------------------------- */ static void GetLineExtentsProc(Element *basePtr, Region2d *extsPtr) { LineElement *elemPtr = (LineElement *)basePtr; int np; extsPtr->top = extsPtr->left = DBL_MAX; extsPtr->bottom = extsPtr->right = -DBL_MAX; np = NUMBEROFPOINTS(elemPtr); if (np < 1) { return; } extsPtr->right = elemPtr->x.max; if ((elemPtr->x.min <= 0.0) && (elemPtr->axes.x->logScale)) { extsPtr->left = Blt_FindElemValuesMinimum(&elemPtr->x, DBL_MIN); } else { extsPtr->left = elemPtr->x.min; } extsPtr->bottom = elemPtr->y.max; if ((elemPtr->y.min <= 0.0) && (elemPtr->axes.y->logScale)) { extsPtr->top = Blt_FindElemValuesMinimum(&elemPtr->y, DBL_MIN); } else { extsPtr->top = elemPtr->y.min; } /* Correct the data limits for error bars */ if (elemPtr->xError.nValues > 0) { int i; np = MIN(elemPtr->xError.nValues, np); for (i = 0; i < np; i++) { double x; x = elemPtr->x.values[i] + elemPtr->xError.values[i]; if (x > extsPtr->right) { extsPtr->right = x; } x = elemPtr->x.values[i] - elemPtr->xError.values[i]; if (elemPtr->axes.x->logScale) { if (x < 0.0) { x = -x; /* Mirror negative values, instead of * ignoring them. */ } if ((x > DBL_MIN) && (x < extsPtr->left)) { extsPtr->left = x; } } else if (x < extsPtr->left) { extsPtr->left = x; } } } else { if ((elemPtr->xHigh.nValues > 0) && (elemPtr->xHigh.max > extsPtr->right)) { extsPtr->right = elemPtr->xHigh.max; } if (elemPtr->xLow.nValues > 0) { double left; if ((elemPtr->xLow.min <= 0.0) && (elemPtr->axes.x->logScale)) { left = Blt_FindElemValuesMinimum(&elemPtr->xLow, DBL_MIN); } else { left = elemPtr->xLow.min; } if (left < extsPtr->left) { extsPtr->left = left; } } } if (elemPtr->yError.nValues > 0) { int i; np = MIN(elemPtr->yError.nValues, np); for (i = 0; i < np; i++) { double y; y = elemPtr->y.values[i] + elemPtr->yError.values[i]; if (y > extsPtr->bottom) { extsPtr->bottom = y; } y = elemPtr->y.values[i] - elemPtr->yError.values[i]; if (elemPtr->axes.y->logScale) { if (y < 0.0) { y = -y; /* Mirror negative values, instead of * ignoring them. */ } if ((y > DBL_MIN) && (y < extsPtr->left)) { extsPtr->top = y; } } else if (y < extsPtr->top) { extsPtr->top = y; } } } else { if ((elemPtr->yHigh.nValues > 0) && (elemPtr->yHigh.max > extsPtr->bottom)) { extsPtr->bottom = elemPtr->yHigh.max; } if (elemPtr->yLow.nValues > 0) { double top; if ((elemPtr->yLow.min <= 0.0) && (elemPtr->axes.y->logScale)) { top = Blt_FindElemValuesMinimum(&elemPtr->yLow, DBL_MIN); } else { top = elemPtr->yLow.min; } if (top < extsPtr->top) { extsPtr->top = top; } } } } /* *--------------------------------------------------------------------------- * * BackgroundChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void BackgroundChangedProc(ClientData clientData) { Element *elemPtr = clientData; Graph *graphPtr; graphPtr = elemPtr->obj.graphPtr; if (graphPtr->tkwin != NULL) { graphPtr->flags |= REDRAW_WORLD; Blt_EventuallyRedrawGraph(graphPtr); } } /* *--------------------------------------------------------------------------- * * ConfigureLineProc -- * * Sets up the appropriate configuration parameters in the GC. It is * assumed the parameters have been previously set by a call to * Blt_ConfigureWidget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information such as line width, line style, color * etc. get set in a new GC. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureLineProc(Graph *graphPtr, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; unsigned long gcMask; XGCValues gcValues; GC newGC; Blt_ChainLink link; LineStyle *stylePtr; if (ConfigurePenProc(graphPtr, (Pen *)&elemPtr->builtinPen) != TCL_OK) { return TCL_ERROR; } /* * Point to the static normal/active pens if no external pens have been * selected. */ link = Blt_Chain_FirstLink(elemPtr->styles); if (link == NULL) { link = Blt_Chain_AllocLink(sizeof(LineStyle)); Blt_Chain_LinkAfter(elemPtr->styles, link, NULL); } stylePtr = Blt_Chain_GetValue(link); stylePtr->penPtr = NORMALPEN(elemPtr); if (elemPtr->fillBg != NULL) { Blt_SetBackgroundChangedProc(elemPtr->fillBg, BackgroundChangedProc, elemPtr); } /* * Set the outline GC for this pen: GCForeground is outline color. * GCBackground is the fill color (only used for bitmap symbols). */ gcMask = 0; if (elemPtr->fillFgColor != NULL) { gcMask |= GCForeground; gcValues.foreground = elemPtr->fillFgColor->pixel; } if (elemPtr->fillBgColor != NULL) { gcMask |= GCBackground; gcValues.background = elemPtr->fillBgColor->pixel; } newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (elemPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, elemPtr->fillGC); } elemPtr->fillGC = newGC; if (Blt_ConfigModified(elemPtr->configSpecs, "-scalesymbols", (char *)NULL)) { elemPtr->flags |= (MAP_ITEM | SCALE_SYMBOL); } if (Blt_ConfigModified(elemPtr->configSpecs, "-pixels", "-trace", "-*data", "-smooth", "-map*", "-label", "-hide", "-x", "-y", "-areabackground", (char *)NULL)) { elemPtr->flags |= MAP_ITEM; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ClosestLineProc -- * * Find the closest point or line segment (if interpolated) to the given * window coordinate in the line element. * * Results: * Returns the distance of the closest point among other information. * *--------------------------------------------------------------------------- */ static void ClosestLineProc(Graph *graphPtr, Element *basePtr, ClosestSearch *searchPtr) { LineElement *elemPtr = (LineElement *)basePtr; int mode; mode = searchPtr->mode; if (mode == SEARCH_AUTO) { LinePen *penPtr; penPtr = NORMALPEN(elemPtr); mode = SEARCH_POINTS; if ((NUMBEROFPOINTS(elemPtr) > 1) && (penPtr->traceWidth > 0)) { mode = SEARCH_TRACES; } } if (mode == SEARCH_POINTS) { ClosestPoint(elemPtr, searchPtr); } else { DistanceProc *distProc; int found; if (searchPtr->along == SEARCH_X) { distProc = DistanceToXProc; } else if (searchPtr->along == SEARCH_Y) { distProc = DistanceToYProc; } else { distProc = DistanceToLineProc; } if (elemPtr->obj.classId == CID_ELEM_STRIP) { found = ClosestStrip(graphPtr, elemPtr, searchPtr, distProc); } else { found = ClosestTrace(graphPtr, elemPtr, searchPtr, distProc); } if ((!found) && (searchPtr->along != SEARCH_BOTH)) { ClosestPoint(elemPtr, searchPtr); } } } /* * XDrawLines() points: XMaxRequestSize(dpy) - 3 * XFillPolygon() points: XMaxRequestSize(dpy) - 4 * XDrawSegments() segments: (XMaxRequestSize(dpy) - 3) / 2 * XDrawRectangles() rectangles: (XMaxRequestSize(dpy) - 3) / 2 * XFillRectangles() rectangles: (XMaxRequestSize(dpy) - 3) / 2 * XDrawArcs() or XFillArcs() arcs: (XMaxRequestSize(dpy) - 3) / 3 */ #define MAX_DRAWLINES(d) Blt_MaxRequestSize(d, sizeof(XPoint)) #define MAX_DRAWPOLYGON(d) Blt_MaxRequestSize(d, sizeof(XPoint)) #define MAX_DRAWSEGMENTS(d) Blt_MaxRequestSize(d, sizeof(XSegment)) #define MAX_DRAWRECTANGLES(d) Blt_MaxRequestSize(d, sizeof(XRectangle)) #define MAX_DRAWARCS(d) Blt_MaxRequestSize(d, sizeof(XArc)) #ifdef WIN32 static void DrawCircles( Display *display, Drawable drawable, LineElement *elemPtr, LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int radius) { HBRUSH brush, oldBrush; HPEN pen, oldPen; HDC dc; TkWinDCState state; if (drawable == None) { return; /* Huh? */ } if ((penPtr->symbol.fillGC == NULL) && (penPtr->symbol.outlineWidth == 0)) { return; } dc = TkWinGetDrawableDC(display, drawable, &state); /* SetROP2(dc, tkpWinRopModes[penPtr->symbol.fillGC->function]); */ if (penPtr->symbol.fillGC != NULL) { brush = CreateSolidBrush(penPtr->symbol.fillGC->foreground); } else { brush = GetStockBrush(NULL_BRUSH); } if (penPtr->symbol.outlineWidth > 0) { pen = Blt_GCToPen(dc, penPtr->symbol.outlineGC); } else { pen = GetStockPen(NULL_PEN); } oldPen = SelectPen(dc, pen); oldBrush = SelectBrush(dc, brush); { Point2d *pp, *pend; for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) { int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); Ellipse(dc, rndx - radius, rndy - radius, rndx + radius + 1, rndy + radius + 1); } } DeleteBrush(SelectBrush(dc, oldBrush)); DeletePen(SelectPen(dc, oldPen)); TkWinReleaseDrawableDC(drawable, dc, &state); } #else static void DrawCircles(Display *display, Drawable drawable, LineElement *elemPtr, LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int radius) { int i; XArc *arcs; /* Array of arcs (circle) */ int reqSize; int s; int count; s = radius + radius; arcs = Blt_AssertMalloc(nSymbolPts * sizeof(XArc)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *pend; XArc *ap; ap = arcs; count = 0; for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) { if (DRAW_SYMBOL(elemPtr)) { ap->x = Round(pp->x) - radius; ap->y = Round(pp->y) - radius; ap->width = ap->height = (unsigned short)s; ap->angle1 = 0; ap->angle2 = 23040; ap++, count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *pend; XArc *ap; ap = arcs; for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) { ap->x = Round(pp->x) - radius; ap->y = Round(pp->y) - radius; ap->width = ap->height = (unsigned short)s; ap->angle1 = 0; ap->angle2 = 23040; ap++; } count = nSymbolPts; } reqSize = MAX_DRAWARCS(display); for (i = 0; i < count; i += reqSize) { int n; n = ((i + reqSize) > count) ? (count - i) : reqSize; if (penPtr->symbol.fillGC != NULL) { XFillArcs(display, drawable, penPtr->symbol.fillGC, arcs + i, n); } if (penPtr->symbol.outlineWidth > 0) { XDrawArcs(display, drawable, penPtr->symbol.outlineGC, arcs + i, n); } } Blt_Free(arcs); } #endif static void DrawSquares(Display *display, Drawable drawable, LineElement *elemPtr, LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int r) { XRectangle *rectangles; XRectangle *rp, *rend; int reqSize; int s, count; s = r + r; rectangles = Blt_AssertMalloc(nSymbolPts * sizeof(XRectangle)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *pend; XRectangle *rp; count = 0; rp = rectangles; for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) { if (DRAW_SYMBOL(elemPtr)) { rp->x = Round(pp->x) - r; rp->y = Round(pp->y) - r; rp->width = rp->height = (unsigned short)s; rp++, count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *pend; XRectangle *rp; rp = rectangles; for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) { rp->x = Round(pp->x) - r; rp->y = Round(pp->y) - r; rp->width = rp->height = (unsigned short)s; rp++; } count = nSymbolPts; } reqSize = MAX_DRAWRECTANGLES(display) - 3; for (rp = rectangles, rend = rp + count; rp < rend; rp += reqSize) { int n; n = rend - rp; if (n > reqSize) { n = reqSize; } if (penPtr->symbol.fillGC != NULL) { XFillRectangles(display, drawable, penPtr->symbol.fillGC, rp, n); } if (penPtr->symbol.outlineWidth > 0) { XDrawRectangles(display, drawable, penPtr->symbol.outlineGC, rp, n); } } Blt_Free(rectangles); } /* *--------------------------------------------------------------------------- * * DrawSymbols -- * * Draw the symbols centered at the each given x,y coordinate in the array * of points. * * Results: * None. * * Side Effects: * Draws a symbol at each coordinate given. If active, only those * coordinates which are currently active are drawn. * *--------------------------------------------------------------------------- */ static void DrawSymbols( Graph *graphPtr, /* Graph widget record */ Drawable drawable, /* Pixmap or window to draw into */ LineElement *elemPtr, LinePen *penPtr, int size, /* Size of element */ int nSymbolPts, /* Number of coordinates in array */ Point2d *symbolPts) /* Array of x,y coordinates for line */ { XPoint pattern[13]; /* Template for polygon symbols */ int r1, r2; int count; #define SQRT_PI 1.77245385090552 #define S_RATIO 0.886226925452758 if (size < 3) { if (penPtr->symbol.fillGC != NULL) { Point2d *pp, *endp; XPoint *points, *xpp; xpp = points = Blt_AssertMalloc(nSymbolPts * sizeof(XPoint)); for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { xpp->x = Round(pp->x); xpp->y = Round(pp->y); xpp++; } XDrawPoints(graphPtr->display, drawable, penPtr->symbol.fillGC, points, nSymbolPts, CoordModeOrigin); Blt_Free(points); } return; } r1 = (int)ceil(size * 0.5); r2 = (int)ceil(size * S_RATIO * 0.5); switch (penPtr->symbol.type) { case SYMBOL_NONE: break; case SYMBOL_SQUARE: DrawSquares(graphPtr->display, drawable, elemPtr, penPtr, nSymbolPts, symbolPts, r2); break; case SYMBOL_CIRCLE: DrawCircles(graphPtr->display, drawable, elemPtr, penPtr, nSymbolPts, symbolPts, r1); break; case SYMBOL_SPLUS: case SYMBOL_SCROSS: { XSegment *segments; /* Array of line segments (splus, * scross) */ int i; int reqSize, nSegs; if (penPtr->symbol.type == SYMBOL_SCROSS) { r2 = Round((double)r2 * M_SQRT1_2); pattern[3].y = pattern[2].x = pattern[0].x = pattern[0].y = -r2; pattern[3].x = pattern[2].y = pattern[1].y = pattern[1].x = r2; } else { pattern[0].y = pattern[1].y = pattern[2].x = pattern[3].x = 0; pattern[0].x = pattern[2].y = -r2; pattern[1].x = pattern[3].y = r2; } segments = Blt_AssertMalloc(nSymbolPts * 2 * sizeof(XSegment)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; XSegment *sp; sp = segments; count = 0; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { if (DRAW_SYMBOL(elemPtr)) { int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); sp->x1 = pattern[0].x + rndx; sp->y1 = pattern[0].y + rndy; sp->x2 = pattern[1].x + rndx; sp->y2 = pattern[1].y + rndy; sp++; sp->x1 = pattern[2].x + rndx; sp->y1 = pattern[2].y + rndy; sp->x2 = pattern[3].x + rndx; sp->y2 = pattern[3].y + rndy; sp++; count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; XSegment *sp; sp = segments; count = nSymbolPts; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); sp->x1 = pattern[0].x + rndx; sp->y1 = pattern[0].y + rndy; sp->x2 = pattern[1].x + rndx; sp->y2 = pattern[1].y + rndy; sp++; sp->x1 = pattern[2].x + rndx; sp->y1 = pattern[2].y + rndy; sp->x2 = pattern[3].x + rndx; sp->y2 = pattern[3].y + rndy; sp++; } } nSegs = count * 2; /* Always draw skinny symbols regardless of the outline width */ reqSize = MAX_DRAWSEGMENTS(graphPtr->display); for (i = 0; i < nSegs; i += reqSize) { int chunk; chunk = ((i + reqSize) > nSegs) ? (nSegs - i) : reqSize; XDrawSegments(graphPtr->display, drawable, penPtr->symbol.outlineGC, segments + i, chunk); } Blt_Free(segments); } break; case SYMBOL_PLUS: case SYMBOL_CROSS: { XPoint *polygon; int d; /* Small delta for cross/plus * thickness */ d = (r2 / 3); /* * * 2 3 The plus/cross symbol is a closed polygon * of 12 points. The diagram to the left * 0,12 1 4 5 represents the positions of the points * x,y which are computed below. The extra * 11 10 7 6 (thirteenth) point connects the first and * last points. * 9 8 */ pattern[0].x = pattern[11].x = pattern[12].x = -r2; pattern[2].x = pattern[1].x = pattern[10].x = pattern[9].x = -d; pattern[3].x = pattern[4].x = pattern[7].x = pattern[8].x = d; pattern[5].x = pattern[6].x = r2; pattern[2].y = pattern[3].y = -r2; pattern[0].y = pattern[1].y = pattern[4].y = pattern[5].y = pattern[12].y = -d; pattern[11].y = pattern[10].y = pattern[7].y = pattern[6].y = d; pattern[9].y = pattern[8].y = r2; if (penPtr->symbol.type == SYMBOL_CROSS) { int i; /* For the cross symbol, rotate the points by 45 degrees. */ for (i = 0; i < 12; i++) { double dx, dy; dx = (double)pattern[i].x * M_SQRT1_2; dy = (double)pattern[i].y * M_SQRT1_2; pattern[i].x = Round(dx - dy); pattern[i].y = Round(dx + dy); } pattern[12] = pattern[0]; } polygon = Blt_AssertMalloc(nSymbolPts * 13 * sizeof(XPoint)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; XPoint *xpp; count = 0; xpp = polygon; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { if (DRAW_SYMBOL(elemPtr)) { int i; int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 13; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; XPoint *xpp; xpp = polygon; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int i; int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 13; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } } count = nSymbolPts; } if (penPtr->symbol.fillGC != NULL) { int i; XPoint *xpp; for (xpp = polygon, i = 0; i < count; i++, xpp += 13) { XFillPolygon(graphPtr->display, drawable, penPtr->symbol.fillGC, xpp, 13, Complex, CoordModeOrigin); } } if (penPtr->symbol.outlineWidth > 0) { int i; XPoint *xpp; for (xpp = polygon, i = 0; i < count; i++, xpp += 13) { XDrawLines(graphPtr->display, drawable, penPtr->symbol.outlineGC, xpp, 13, CoordModeOrigin); } } Blt_Free(polygon); } break; case SYMBOL_DIAMOND: { XPoint *polygon; /* * * The plus symbol is a closed polygon * 1 of 4 points. The diagram to the left * represents the positions of the points * 0,4 x,y 2 which are computed below. The extra * (fifth) point connects the first and * 3 last points. * */ pattern[1].y = pattern[0].x = -r1; pattern[2].y = pattern[3].x = pattern[0].y = pattern[1].x = 0; pattern[3].y = pattern[2].x = r1; pattern[4] = pattern[0]; polygon = Blt_AssertMalloc(nSymbolPts * 5 * sizeof(XPoint)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; XPoint *xpp; xpp = polygon; count = 0; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int i; if (DRAW_SYMBOL(elemPtr)) { int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 5; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; XPoint *xpp; xpp = polygon; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int i; int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 5; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } } count = nSymbolPts; } if (penPtr->symbol.fillGC != NULL) { XPoint *xpp; int i; for (xpp = polygon, i = 0; i < count; i++, xpp += 5) { XFillPolygon(graphPtr->display, drawable, penPtr->symbol.fillGC, xpp, 5, Convex, CoordModeOrigin); } } if (penPtr->symbol.outlineWidth > 0) { XPoint *xpp; int i; for (xpp = polygon, i = 0; i < count; i++, xpp += 5) { XDrawLines(graphPtr->display, drawable, penPtr->symbol.outlineGC, xpp, 5, CoordModeOrigin); } } Blt_Free(polygon); } break; case SYMBOL_TRIANGLE: case SYMBOL_ARROW: { XPoint *polygon; double b; int b2, h1, h2; #define H_RATIO 1.1663402261671607 #define B_RATIO 1.3467736870885982 #define TAN30 0.57735026918962573 #define COS30 0.86602540378443871 b = Round(size * B_RATIO * 0.7); b2 = Round(b * 0.5); h2 = Round(TAN30 * b2); h1 = Round(b2 / COS30); /* * * The triangle symbol is a closed polygon * 0,3 of 3 points. The diagram to the left * represents the positions of the points * x,y which are computed below. The extra * (fourth) point connects the first and * 2 1 last points. * */ if (penPtr->symbol.type == SYMBOL_ARROW) { pattern[3].x = pattern[0].x = 0; pattern[3].y = pattern[0].y = h1; pattern[1].x = b2; pattern[2].y = pattern[1].y = -h2; pattern[2].x = -b2; } else { pattern[3].x = pattern[0].x = 0; pattern[3].y = pattern[0].y = -h1; pattern[1].x = b2; pattern[2].y = pattern[1].y = h2; pattern[2].x = -b2; } polygon = Blt_AssertMalloc(nSymbolPts * 4 * sizeof(XPoint)); if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; XPoint *xpp; xpp = polygon; count = 0; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int i; if (DRAW_SYMBOL(elemPtr)) { int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 4; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } count++; } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; XPoint *xpp; xpp = polygon; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int i; int rndx, rndy; rndx = Round(pp->x), rndy = Round(pp->y); for (i = 0; i < 4; i++) { xpp->x = pattern[i].x + rndx; xpp->y = pattern[i].y + rndy; xpp++; } } count = nSymbolPts; } if (penPtr->symbol.fillGC != NULL) { XPoint *xpp; int i; xpp = polygon; for (xpp = polygon, i = 0; i < count; i++, xpp += 4) { XFillPolygon(graphPtr->display, drawable, penPtr->symbol.fillGC, xpp, 4, Convex, CoordModeOrigin); } } if (penPtr->symbol.outlineWidth > 0) { XPoint *xpp; int i; xpp = polygon; for (xpp = polygon, i = 0; i < count; i++, xpp += 4) { XDrawLines(graphPtr->display, drawable, penPtr->symbol.outlineGC, xpp, 4, CoordModeOrigin); } } Blt_Free(polygon); } break; case SYMBOL_IMAGE: { int w, h; int dx, dy; Tk_SizeOfImage(penPtr->symbol.image, &w, &h); dx = w / 2; dy = h / 2; if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { if (DRAW_SYMBOL(elemPtr)) { int x, y; x = Round(pp->x) - dx; y = Round(pp->y) - dy; Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h, drawable, x, y); } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int x, y; x = Round(pp->x) - dx; y = Round(pp->y) - dy; Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h, drawable, x, y); } } } break; case SYMBOL_BITMAP: { Pixmap bitmap, mask; int w, h, bw, bh; double scale, sx, sy; int dx, dy; Tk_SizeOfBitmap(graphPtr->display, penPtr->symbol.bitmap, &w, &h); mask = None; /* * Compute the size of the scaled bitmap. Stretch the bitmap to fit * a nxn bounding box. */ sx = (double)size / (double)w; sy = (double)size / (double)h; scale = MIN(sx, sy); bw = (int)(w * scale); bh = (int)(h * scale); XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, None); if (penPtr->symbol.mask != None) { mask = Blt_ScaleBitmap(graphPtr->tkwin, penPtr->symbol.mask, w, h, bw, bh); XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, mask); } bitmap = Blt_ScaleBitmap(graphPtr->tkwin, penPtr->symbol.bitmap, w, h, bw, bh); if (penPtr->symbol.fillGC == NULL) { XSetClipMask(graphPtr->display, penPtr->symbol.outlineGC, bitmap); } dx = bw / 2; dy = bh / 2; if (elemPtr->symbolInterval > 0) { Point2d *pp, *endp; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { if (DRAW_SYMBOL(elemPtr)) { int x, y; x = Round(pp->x) - dx; y = Round(pp->y) - dy; if ((penPtr->symbol.fillGC == NULL) || (mask !=None)) { XSetClipOrigin(graphPtr->display, penPtr->symbol.outlineGC, x, y); } XCopyPlane(graphPtr->display, bitmap, drawable, penPtr->symbol.outlineGC, 0, 0, bw, bh, x, y, 1); } elemPtr->symbolCounter++; } } else { Point2d *pp, *endp; for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) { int x, y; x = Round(pp->x) - dx; y = Round(pp->y) - dy; if ((penPtr->symbol.fillGC == NULL) || (mask != None)) { XSetClipOrigin(graphPtr->display, penPtr->symbol.outlineGC, x, y); } XCopyPlane(graphPtr->display, bitmap, drawable, penPtr->symbol.outlineGC, 0, 0, bw, bh, x, y, 1); } } Tk_FreePixmap(graphPtr->display, bitmap); if (mask != None) { Tk_FreePixmap(graphPtr->display, mask); } } break; } } /* *--------------------------------------------------------------------------- * * DrawSymbolProc -- * * Draw the symbol centered at the each given x,y coordinate. * * Results: * None. * * Side Effects: * Draws a symbol at the coordinate given. * *--------------------------------------------------------------------------- */ static void DrawSymbolProc( Graph *graphPtr, /* Graph widget record */ Drawable drawable, /* Pixmap or window to draw into */ Element *basePtr, /* Line element information */ int x, int y, /* Center position of symbol */ int size) /* Size of symbol. */ { LineElement *elemPtr = (LineElement *)basePtr; LinePen *penPtr; penPtr = NORMALPEN(elemPtr); if (penPtr->traceWidth > 0) { /* * Draw an extra line offset by one pixel from the previous to give a * thicker appearance. This is only for the legend entry. This routine * is never called for drawing the actual line segments. */ XDrawLine(graphPtr->display, drawable, penPtr->traceGC, x - size, y, x + size, y); XDrawLine(graphPtr->display, drawable, penPtr->traceGC, x - size, y + 1, x + size, y + 1); } if (penPtr->symbol.type != SYMBOL_NONE) { Point2d point; point.x = x, point.y = y; DrawSymbols(graphPtr, drawable, elemPtr, penPtr, size, 1, &point); } } #ifdef WIN32 static void DrawTraces( Graph *graphPtr, Drawable drawable, /* Pixmap or window to draw into */ LineElement *elemPtr, LinePen *penPtr) { Blt_ChainLink link; HBRUSH brush, oldBrush; HDC dc; HPEN pen, oldPen; POINT *points; TkWinDCState state; int np; /* * Depending if the line is wide (> 1 pixel), arbitrarily break the line in * sections of 100 points. This bit of weirdness has to do with wide * geometric pens. The longer the polyline, the slower it draws. The trade * off is that we lose dash and cap uniformity for unbearably slow polyline * draws. */ if (penPtr->traceGC->line_width > 1) { np = 100; } else { np = Blt_MaxRequestSize(graphPtr->display, sizeof(POINT)) - 1; } points = Blt_AssertMalloc((np + 1) * sizeof(POINT)); dc = TkWinGetDrawableDC(graphPtr->display, drawable, &state); pen = Blt_GCToPen(dc, penPtr->traceGC); oldPen = SelectPen(dc, pen); brush = CreateSolidBrush(penPtr->traceGC->foreground); oldBrush = SelectBrush(dc, brush); SetROP2(dc, tkpWinRopModes[penPtr->traceGC->function]); for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { POINT *p; Trace *tracePtr; int count, remaining; tracePtr = Blt_Chain_GetValue(link); /* * If the trace has to be split into separate XDrawLines calls, then the * end point of the current trace is also the starting point of the new * split. */ /* Step 1. Convert and draw the first section of the trace. * It may contain the entire trace. */ for (p = points, count = 0; count < MIN(np, tracePtr->screenPts.length); count++, p++) { p->x = Round(tracePtr->screenPts.points[count].x); p->y = Round(tracePtr->screenPts.points[count].y); } Polyline(dc, points, count); /* Step 2. Next handle any full-size chunks left. */ while ((count + np) < tracePtr->screenPts.length) { int j; /* Start with the last point of the previous trace. */ points[0].x = points[np - 1].x; points[0].y = points[np - 1].y; for (p = points + 1, j = 0; j < np; j++, count++, p++) { p->x = Round(tracePtr->screenPts.points[count].x); p->y = Round(tracePtr->screenPts.points[count].y); } Polyline(dc, points, np + 1); } /* Step 3. Convert and draw the remaining points. */ remaining = tracePtr->screenPts.length - count; if (remaining > 0) { /* Start with the last point of the previous trace. */ points[0].x = points[np - 1].x; points[0].y = points[np - 1].y; for (p = points + 1; count < tracePtr->screenPts.length; count++, p++) { p->x = Round(tracePtr->screenPts.points[count].x); p->y = Round(tracePtr->screenPts.points[count].y); } Polyline(dc, points, remaining + 1); } } Blt_Free(points); DeletePen(SelectPen(dc, oldPen)); DeleteBrush(SelectBrush(dc, oldBrush)); TkWinReleaseDrawableDC(drawable, dc, &state); } #else static void DrawTraces(Graph *graphPtr, Drawable drawable, LineElement *elemPtr, LinePen *penPtr) { Blt_ChainLink link; XPoint *points; int np; np = Blt_MaxRequestSize(graphPtr->display, sizeof(XPoint)) - 1; points = Blt_AssertMalloc((np + 1) * sizeof(XPoint)); for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { XPoint *xpp; Trace *tracePtr; int remaining, count; int n; tracePtr = Blt_Chain_GetValue(link); /* * If the trace has to be split into separate XDrawLines calls, then the * end point of the current trace is also the starting point of the new * split. */ /* Step 1. Convert and draw the first section of the trace. * It may contain the entire trace. */ n = MIN(np, tracePtr->screenPts.length); for (xpp = points, count = 0; count < n; count++, xpp++) { xpp->x = Round(tracePtr->screenPts.points[count].x); xpp->y = Round(tracePtr->screenPts.points[count].y); } XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, count, CoordModeOrigin); /* Step 2. Next handle any full-size chunks left. */ while ((count + np) < tracePtr->screenPts.length) { int j; /* Start with the last point of the previous trace. */ points[0].x = points[np - 1].x; points[0].y = points[np - 1].y; for (xpp = points + 1, j = 0; j < np; j++, count++, xpp++) { xpp->x = Round(tracePtr->screenPts.points[count].x); xpp->y = Round(tracePtr->screenPts.points[count].y); } XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, np + 1, CoordModeOrigin); } /* Step 3. Convert and draw the remaining points. */ remaining = tracePtr->screenPts.length - count; if (remaining > 0) { /* Start with the last point of the previous trace. */ points[0].x = points[np - 1].x; points[0].y = points[np - 1].y; for (xpp = points + 1; count < tracePtr->screenPts.length; count++, xpp++) { xpp->x = Round(tracePtr->screenPts.points[count].x); xpp->y = Round(tracePtr->screenPts.points[count].y); } XDrawLines(graphPtr->display, drawable, penPtr->traceGC, points, remaining + 1, CoordModeOrigin); } } Blt_Free(points); } #endif /* WIN32 */ static void DrawValues(Graph *graphPtr, Drawable drawable, LineElement *elemPtr, LinePen *penPtr, int length, Point2d *points, int *map) { Point2d *pp, *endp; double *xval, *yval; const char *fmt; char string[TCL_DOUBLE_SPACE * 2 + 2]; int count; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } count = 0; xval = elemPtr->x.values, yval = elemPtr->y.values; for (pp = points, endp = points + length; pp < endp; pp++) { double x, y; x = xval[map[count]]; y = yval[map[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } Blt_DrawText(graphPtr->tkwin, drawable, string, &penPtr->valueStyle, Round(pp->x), Round(pp->y)); } } /* *--------------------------------------------------------------------------- * * DrawActiveLineProc -- * * Draws the connected line(s) representing the element. If the line is * made up of non-line symbols and the line width parameter has been set * (linewidth > 0), the element will also be drawn as a line (with the * linewidth requested). The line may consist of separate line segments. * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawActiveLineProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; LinePen *penPtr = (LinePen *)elemPtr->activePenPtr; int symbolSize; if (penPtr == NULL) { return; } symbolSize = ScaleSymbol(elemPtr, penPtr->symbol.size); /* * nActiveIndices * > 0 Some points are active. Uses activeArr. * < 0 All points are active. * == 0 No points are active. */ if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveSymbols(graphPtr, elemPtr); } if (penPtr->symbol.type != SYMBOL_NONE) { DrawSymbols(graphPtr, drawable, elemPtr, penPtr, symbolSize, elemPtr->activePts.length, elemPtr->activePts.points); } if (penPtr->valueShow != SHOW_NONE) { DrawValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->activePts.length, elemPtr->activePts.points, elemPtr->activePts.map); } } else if (elemPtr->nActiveIndices < 0) { if (penPtr->traceWidth > 0) { if (elemPtr->lines.length > 0) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->traceGC, elemPtr->lines.segments, elemPtr->lines.length); } else if (Blt_Chain_GetLength(elemPtr->traces) > 0) { DrawTraces(graphPtr, drawable, elemPtr, penPtr); } } if (penPtr->symbol.type != SYMBOL_NONE) { DrawSymbols(graphPtr, drawable, elemPtr, penPtr, symbolSize, elemPtr->symbolPts.length, elemPtr->symbolPts.points); } if (penPtr->valueShow != SHOW_NONE) { DrawValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->symbolPts.length, elemPtr->symbolPts.points, elemPtr->symbolPts.map); } } } /* *--------------------------------------------------------------------------- * * DrawNormalLine -- * * Draws the connected line(s) representing the element. If the line is * made up of non-line symbols and the line width parameter has been set * (linewidth > 0), the element will also be drawn as a line (with the * linewidth requested). The line may consist of separate line segments. * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawNormalLineProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; Blt_ChainLink link; unsigned int count; /* Fill area under the curve */ if (elemPtr->fillPts != NULL) { XPoint *points; Point2d *endp, *pp; points = Blt_AssertMalloc(sizeof(XPoint) * elemPtr->nFillPts); count = 0; for (pp = elemPtr->fillPts, endp = pp + elemPtr->nFillPts; pp < endp; pp++) { points[count].x = Round(pp->x); points[count].y = Round(pp->y); count++; } if (elemPtr->fillBg != NULL) { Blt_SetBackgroundOrigin(graphPtr->tkwin, elemPtr->fillBg, 0, 0); Blt_FillBackgroundPolygon(graphPtr->tkwin, drawable, elemPtr->fillBg, points, elemPtr->nFillPts, 0, TK_RELIEF_FLAT); } Blt_Free(points); } /* Lines: stripchart segments or graph traces. */ if (elemPtr->lines.length > 0) { for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; if ((stylePtr->lines.length > 0) && (penPtr->errorBarLineWidth > 0)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->traceGC, stylePtr->lines.segments, stylePtr->lines.length); } } } else { LinePen *penPtr; penPtr = NORMALPEN(elemPtr); if ((Blt_Chain_GetLength(elemPtr->traces) > 0) && (penPtr->traceWidth > 0)) { DrawTraces(graphPtr, drawable, elemPtr, penPtr); } } if (elemPtr->reqMaxSymbols > 0) { int total; total = 0; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); total += stylePtr->symbolPts.length; } elemPtr->symbolInterval = total / elemPtr->reqMaxSymbols; elemPtr->symbolCounter = 0; } /* Symbols, error bars, values. */ count = 0; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->yeb.segments, stylePtr->yeb.length); } if ((stylePtr->symbolPts.length > 0) && (penPtr->symbol.type != SYMBOL_NONE)) { DrawSymbols(graphPtr, drawable, elemPtr, penPtr, stylePtr->symbolSize, stylePtr->symbolPts.length, stylePtr->symbolPts.points); } if (penPtr->valueShow != SHOW_NONE) { DrawValues(graphPtr, drawable, elemPtr, penPtr, stylePtr->symbolPts.length, stylePtr->symbolPts.points, elemPtr->symbolPts.map + count); } count += stylePtr->symbolPts.length; } elemPtr->symbolInterval = 0; } /* *--------------------------------------------------------------------------- * * GetSymbolPostScriptInfo -- * * Set up the PostScript environment with the macros and attributes needed * to draw the symbols of the element. * * Results: * None. * *--------------------------------------------------------------------------- */ static void GetSymbolPostScriptInfo( Graph *graphPtr, Blt_Ps ps, LinePen *penPtr, int size) { XColor *outlineColor, *fillColor, *defaultColor; /* Set line and foreground attributes */ outlineColor = penPtr->symbol.outlineColor; fillColor = penPtr->symbol.fillColor; defaultColor = penPtr->traceColor; if (fillColor == COLOR_DEFAULT) { fillColor = defaultColor; } if (outlineColor == COLOR_DEFAULT) { outlineColor = defaultColor; } if (penPtr->symbol.type == SYMBOL_NONE) { Blt_Ps_XSetLineAttributes(ps, defaultColor, penPtr->traceWidth + 2, &penPtr->traceDashes, CapButt, JoinMiter); } else { Blt_Ps_XSetLineWidth(ps, penPtr->symbol.outlineWidth); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); } /* * Build a PostScript procedure to draw the symbols. For bitmaps, paint * both the bitmap and its mask. Otherwise fill and stroke the path formed * already. */ Blt_Ps_Append(ps, "\n/DrawSymbolProc {\n"); switch (penPtr->symbol.type) { case SYMBOL_NONE: break; /* Do nothing */ case SYMBOL_BITMAP: { int w, h; double sx, sy, scale; /* * Compute how much to scale the bitmap. Don't let the scaled * bitmap exceed the bounding square for the symbol. */ Tk_SizeOfBitmap(graphPtr->display, penPtr->symbol.bitmap, &w, &h); sx = (double)size / (double)w; sy = (double)size / (double)h; scale = MIN(sx, sy); if ((penPtr->symbol.mask != None) && (fillColor != NULL)) { Blt_Ps_VarAppend(ps, "\n % Bitmap mask is \"", Tk_NameOfBitmap(graphPtr->display, penPtr->symbol.mask), "\"\n\n ", (char *)NULL); Blt_Ps_XSetBackground(ps, fillColor); Blt_Ps_DrawBitmap(ps, graphPtr->display, penPtr->symbol.mask, scale, scale); } Blt_Ps_VarAppend(ps, "\n % Bitmap symbol is \"", Tk_NameOfBitmap(graphPtr->display, penPtr->symbol.bitmap), "\"\n\n ", (char *)NULL); Blt_Ps_XSetForeground(ps, outlineColor); Blt_Ps_DrawBitmap(ps, graphPtr->display, penPtr->symbol.bitmap, scale, scale); } break; default: if (fillColor != NULL) { Blt_Ps_Append(ps, " "); Blt_Ps_XSetBackground(ps, fillColor); Blt_Ps_Append(ps, " gsave fill grestore\n"); } if ((outlineColor != NULL) && (penPtr->symbol.outlineWidth > 0)) { Blt_Ps_Append(ps, " "); Blt_Ps_XSetForeground(ps, outlineColor); Blt_Ps_Append(ps, " stroke\n"); } break; } Blt_Ps_Append(ps, "} def\n\n"); } /* *--------------------------------------------------------------------------- * * SymbolsToPostScript -- * * Draw a symbol centered at the given x,y window coordinate based upon the * element symbol type and size. * * Results: * None. * * Problems: * Most notable is the round-off errors generated when calculating the * centered position of the symbol. * *--------------------------------------------------------------------------- */ static void SymbolsToPostScript( Graph *graphPtr, Blt_Ps ps, LinePen *penPtr, int size, int nSymbolPts, Point2d *symbolPts) { double symbolSize; static const char *symbolMacros[] = { "Li", "Sq", "Ci", "Di", "Pl", "Cr", "Sp", "Sc", "Tr", "Ar", "Bm", (char *)NULL, }; GetSymbolPostScriptInfo(graphPtr, ps, penPtr, size); symbolSize = (double)size; switch (penPtr->symbol.type) { case SYMBOL_SQUARE: case SYMBOL_CROSS: case SYMBOL_PLUS: case SYMBOL_SCROSS: case SYMBOL_SPLUS: symbolSize = (double)Round(size * S_RATIO); break; case SYMBOL_TRIANGLE: case SYMBOL_ARROW: symbolSize = (double)Round(size * 0.7); break; case SYMBOL_DIAMOND: symbolSize = (double)Round(size * M_SQRT1_2); break; default: break; } { Point2d *pp, *endp; for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) { Blt_Ps_Format(ps, "%g %g %g %s\n", pp->x, pp->y, symbolSize, symbolMacros[penPtr->symbol.type]); } } } /* *--------------------------------------------------------------------------- * * SymbolToPostScriptProc -- * * Draw the symbol centered at the each given x,y coordinate. * * Results: * None. * * Side Effects: * Draws a symbol at the coordinate given. * *--------------------------------------------------------------------------- */ static void SymbolToPostScriptProc( Graph *graphPtr, /* Graph widget record */ Blt_Ps ps, Element *basePtr, /* Line element information */ double x, double y, /* Center position of symbol */ int size) /* Size of element */ { LineElement *elemPtr = (LineElement *)basePtr; LinePen *penPtr; penPtr = NORMALPEN(elemPtr); if (penPtr->traceWidth > 0) { /* * Draw an extra line offset by one pixel from the previous to give a * thicker appearance. This is only for the legend entry. This routine * is never called for drawing the actual line segments. */ Blt_Ps_XSetLineAttributes(ps, penPtr->traceColor, penPtr->traceWidth, &penPtr->traceDashes, CapButt, JoinMiter); Blt_Ps_Format(ps, "%g %g %d Li\n", x, y, size + size); } if (penPtr->symbol.type != SYMBOL_NONE) { Point2d point; point.x = x, point.y = y; SymbolsToPostScript(graphPtr, ps, penPtr, size, 1, &point); } } static void SetLineAttributes(Blt_Ps ps, LinePen *penPtr) { /* Set the attributes of the line (color, dashes, linewidth) */ Blt_Ps_XSetLineAttributes(ps, penPtr->traceColor, penPtr->traceWidth, &penPtr->traceDashes, CapButt, JoinMiter); if ((LineIsDashed(penPtr->traceDashes)) && (penPtr->traceOffColor != NULL)) { Blt_Ps_Append(ps, "/DashesProc {\n gsave\n "); Blt_Ps_XSetBackground(ps, penPtr->traceOffColor); Blt_Ps_Append(ps, " "); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); Blt_Ps_Append(ps, "stroke\n grestore\n} def\n"); } else { Blt_Ps_Append(ps, "/DashesProc {} def\n"); } } static void TracesToPostScript(Blt_Ps ps, LineElement *elemPtr, LinePen *penPtr) { Blt_ChainLink link; SetLineAttributes(ps, penPtr); for (link = Blt_Chain_FirstLink(elemPtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { Trace *tracePtr; tracePtr = Blt_Chain_GetValue(link); if (tracePtr->screenPts.length > 0) { Blt_Ps_Append(ps, "% start trace\n"); Blt_Ps_DrawPolyline(ps, tracePtr->screenPts.points, tracePtr->screenPts.length); Blt_Ps_Append(ps, "% end trace\n"); } } } static void ValuesToPostScript(Blt_Ps ps, LineElement *elemPtr, LinePen *penPtr, int nSymbolPts, Point2d *symbolPts, int *pointToData) { Point2d *pp, *endp; int count; char string[TCL_DOUBLE_SPACE * 2 + 2]; const char *fmt; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } count = 0; for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) { double x, y; x = elemPtr->x.values[pointToData[count]]; y = elemPtr->y.values[pointToData[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } Blt_Ps_DrawText(ps, string, &penPtr->valueStyle, pp->x, pp->y); } } /* *--------------------------------------------------------------------------- * * ActiveLineToPostScript -- * * Generates PostScript commands to draw as "active" the points (symbols) * and or line segments (trace) representing the element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ static void ActiveLineToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; LinePen *penPtr = (LinePen *)elemPtr->activePenPtr; int symbolSize; if (penPtr == NULL) { return; } symbolSize = ScaleSymbol(elemPtr, penPtr->symbol.size); if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveSymbols(graphPtr, elemPtr); } if (penPtr->symbol.type != SYMBOL_NONE) { SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize, elemPtr->activePts.length, elemPtr->activePts.points); } if (penPtr->valueShow != SHOW_NONE) { ValuesToPostScript(ps, elemPtr, penPtr, elemPtr->activePts.length, elemPtr->activePts.points, elemPtr->activePts.map); } } else if (elemPtr->nActiveIndices < 0) { if (penPtr->traceWidth > 0) { if (elemPtr->lines.length > 0) { SetLineAttributes(ps, penPtr); Blt_Ps_Draw2DSegments(ps, elemPtr->lines.segments, elemPtr->lines.length); } if (Blt_Chain_GetLength(elemPtr->traces) > 0) { TracesToPostScript(ps, elemPtr, (LinePen *)penPtr); } } if (penPtr->symbol.type != SYMBOL_NONE) { SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize, elemPtr->symbolPts.length, elemPtr->symbolPts.points); } if (penPtr->valueShow != SHOW_NONE) { ValuesToPostScript(ps, elemPtr, penPtr, elemPtr->symbolPts.length, elemPtr->symbolPts.points, elemPtr->symbolPts.map); } } } /* *--------------------------------------------------------------------------- * * NormalLineToPostScriptProc -- * * Similar to the DrawLine procedure, prints PostScript related commands to * form the connected line(s) representing the element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ static void NormalLineToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; Blt_ChainLink link; unsigned int count; /* Draw fill area */ if (elemPtr->fillPts != NULL) { /* Create a path to use for both the polygon and its outline. */ Blt_Ps_Append(ps, "% start fill area\n"); Blt_Ps_Polyline(ps, elemPtr->fillPts, elemPtr->nFillPts); /* If the background fill color was specified, draw the polygon in a * solid fashion with that color. */ if (elemPtr->fillBgColor != NULL) { Blt_Ps_XSetBackground(ps, elemPtr->fillBgColor); Blt_Ps_Append(ps, "gsave fill grestore\n"); } Blt_Ps_XSetForeground(ps, elemPtr->fillFgColor); if (elemPtr->fillBg != NULL) { Blt_Ps_Append(ps, "gsave fill grestore\n"); /* TBA: Transparent tiling is the hard part. */ } else { Blt_Ps_Append(ps, "gsave fill grestore\n"); } Blt_Ps_Append(ps, "% end fill area\n"); } /* Draw lines (strip chart) or traces (xy graph) */ if (elemPtr->lines.length > 0) { for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; if ((stylePtr->lines.length > 0) && (penPtr->traceWidth > 0)) { SetLineAttributes(ps, penPtr); Blt_Ps_Append(ps, "% start segments\n"); Blt_Ps_Draw2DSegments(ps, stylePtr->lines.segments, stylePtr->lines.length); Blt_Ps_Append(ps, "% end segments\n"); } } } else { LinePen *penPtr; penPtr = NORMALPEN(elemPtr); if ((Blt_Chain_GetLength(elemPtr->traces) > 0) && (penPtr->traceWidth > 0)) { TracesToPostScript(ps, elemPtr, penPtr); } } /* Draw symbols, error bars, values. */ count = 0; for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; XColor *colorPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; colorPtr = penPtr->errorBarColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = penPtr->traceColor; } if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments, stylePtr->yeb.length); } if ((stylePtr->symbolPts.length > 0) && (penPtr->symbol.type != SYMBOL_NONE)) { SymbolsToPostScript(graphPtr, ps, penPtr, stylePtr->symbolSize, stylePtr->symbolPts.length, stylePtr->symbolPts.points); } if (penPtr->valueShow != SHOW_NONE) { ValuesToPostScript(ps, elemPtr, penPtr, stylePtr->symbolPts.length, stylePtr->symbolPts.points, elemPtr->symbolPts.map + count); } count += stylePtr->symbolPts.length; } } /* *--------------------------------------------------------------------------- * * DestroyLineProc -- * * Release memory and resources allocated for the line element. * * Results: * None. * * Side effects: * Everything associated with the line element is freed up. * *--------------------------------------------------------------------------- */ static void DestroyLineProc(Graph *graphPtr, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; DestroyPenProc(graphPtr, (Pen *)&elemPtr->builtinPen); if (elemPtr->activePenPtr != NULL) { Blt_FreePen((Pen *)elemPtr->activePenPtr); } ResetLine(elemPtr); if (elemPtr->styles != NULL) { Blt_FreeStylePalette(elemPtr->styles); Blt_Chain_Destroy(elemPtr->styles); } if (elemPtr->activeIndices != NULL) { Blt_Free(elemPtr->activeIndices); } if (elemPtr->fillPts != NULL) { Blt_Free(elemPtr->fillPts); } if (elemPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, elemPtr->fillGC); } } /* *--------------------------------------------------------------------------- * * Blt_LineElement -- * * Allocate memory and initialize methods for the new line element. * * Results: * The pointer to the newly allocated element structure is returned. * * Side effects: * Memory is allocated for the line element structure. * *--------------------------------------------------------------------------- */ static ElementProcs lineProcs = { ClosestLineProc, /* Finds the closest element/data * point */ ConfigureLineProc, /* Configures the element. */ DestroyLineProc, /* Destroys the element. */ DrawActiveLineProc, /* Draws active element */ DrawNormalLineProc, /* Draws normal element */ DrawSymbolProc, /* Draws the element symbol. */ GetLineExtentsProc, /* Find the extents of the element's * data. */ ActiveLineToPostScriptProc, /* Prints active element. */ NormalLineToPostScriptProc, /* Prints normal element. */ SymbolToPostScriptProc, /* Prints the line's symbol. */ MapLineProc /* Compute element's screen * coordinates. */ }; Element * Blt_LineElement(Graph *graphPtr, const char *name, ClassId classId) { LineElement *elemPtr; elemPtr = Blt_AssertCalloc(1, sizeof(LineElement)); elemPtr->procsPtr = &lineProcs; if (classId == CID_ELEM_LINE) { elemPtr->configSpecs = lineElemConfigSpecs; } else { elemPtr->configSpecs = stripElemConfigSpecs; } elemPtr->obj.name = Blt_AssertStrdup(name); Blt_GraphSetObjectClass(&elemPtr->obj, classId); elemPtr->flags = SCALE_SYMBOL; elemPtr->obj.graphPtr = graphPtr; /* By default an element's name and label are the same. */ elemPtr->label = Blt_AssertStrdup(name); elemPtr->legendRelief = TK_RELIEF_FLAT; elemPtr->penDir = PEN_BOTH_DIRECTIONS; elemPtr->styles = Blt_Chain_Create(); elemPtr->builtinPenPtr = &elemPtr->builtinPen; elemPtr->reqSmooth = PEN_SMOOTH_LINEAR; InitLinePen(elemPtr->builtinPenPtr); bltLineStylesOption.clientData = (ClientData)sizeof(LineStyle); return (Element *)elemPtr; } #ifdef notdef /* *--------------------------------------------------------------------------- * * MapLineProc -- * * Calculates the actual window coordinates of the line element. The * window coordinates are saved in an allocated point array. * * Results: * None. * * Side effects: * Memory is (re)allocated for the point array. * *--------------------------------------------------------------------------- */ static void MapLineProc(Graph *graphPtr, Element *basePtr) { LineElement *elemPtr = (LineElement *)basePtr; MapInfo mi; int size, np; LineStyle **styleMap; Blt_ChainLink link; ResetLine(elemPtr); np = NUMBEROFPOINTS(elemPtr); if (np < 1) { return; /* No data points */ } GetScreenPoints(graphPtr, elemPtr, &mi); MapSymbols(graphPtr, elemPtr, &mi); if ((elemPtr->flags & ACTIVE_PENDING) && (elemPtr->nActiveIndices > 0)) { MapActiveSymbols(graphPtr, elemPtr); } /* * Map connecting line segments if they are to be displayed. */ elemPtr->smooth = elemPtr->reqSmooth; if ((np > 1) && ((graphPtr->classId == CID_ELEM_STRIP) || (elemPtr->builtinPen.traceWidth > 0))) { /* * Do smoothing if necessary. This can extend the coordinate array, * so both mi.points and mi.nPoints may change. */ switch (elemPtr->smooth) { case PEN_SMOOTH_STEP: GenerateSteps(&mi); break; case PEN_SMOOTH_NATURAL: case PEN_SMOOTH_QUADRATIC: if (mi.nScreenPts < 3) { /* Can't interpolate with less than three points. */ elemPtr->smooth = PEN_SMOOTH_LINEAR; } else { GenerateSpline(graphPtr, elemPtr, &mi); } break; case PEN_SMOOTH_CATROM: if (mi.nScreenPts < 3) { /* Can't interpolate with less than three points. */ elemPtr->smooth = PEN_SMOOTH_LINEAR; } else { GenerateParametricSpline(graphPtr, elemPtr, &mi); } break; default: break; } if (elemPtr->rTolerance > 0.0) { ReducePoints(&mi, elemPtr->rTolerance); } if (elemPtr->fillBg != NULL) { MapFillArea(graphPtr, elemPtr, &mi); } if (graphPtr->classId == CID_ELEM_STRIP) { MapStrip(graphPtr, elemPtr, &mi); } else { MapTraces(graphPtr, elemPtr, &mi); } } Blt_Free(mi.screenPts); Blt_Free(mi.map); /* Set the symbol size of all the pen styles. */ for (link = Blt_Chain_FirstLink(elemPtr->styles); link != NULL; link = Blt_Chain_NextLink(link)) { LineStyle *stylePtr; LinePen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = (LinePen *)stylePtr->penPtr; size = ScaleSymbol(elemPtr, penPtr->symbol.size); stylePtr->symbolSize = size; stylePtr->errorBarCapWidth = (penPtr->errorBarCapWidth > 0) ? penPtr->errorBarCapWidth : Round(size * 0.6666666); stylePtr->errorBarCapWidth /= 2; } styleMap = (LineStyle **)Blt_StyleMap((Element *)elemPtr); if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) || ((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) || (elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) { MapErrorBars(graphPtr, elemPtr, styleMap); } MergePens(elemPtr, styleMap); Blt_Free(styleMap); } #endif ���������./saods9/blt3.0.1/src/bltWinDde.c�������������������������������������������������������������������0000644�0001750�0001750�00000105570�11462120063�015056� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinDde.c -- * * This file provides procedures that implement the "send" command, * allowing commands to be passed from interpreter to interpreter. * * Copyright 1994-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This was copied from tclWinDde.c of the TCL library distribution. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #include "bltInt.h" #ifndef NO_DDE #include <ddeml.h> /* * The following structure is used to keep track of the interpreters * registered by this process. */ typedef struct RegisteredInterp { struct RegisteredInterp *nextPtr; /* The next interp this application knows * about. */ Tcl_Interp *interp; /* The interpreter attached to this name. */ char name[1]; /* Interpreter's name. Malloc-ed as * part of the structure. */ } RegisteredInterp; /* * Used to keep track of conversations. */ typedef struct Conversation { struct Conversation *nextPtr; /* The next conversation in the list. */ RegisteredInterp *riPtr; /* The info we know about the conversation. */ HCONV hConv; /* The DDE handle for this conversation. */ Tcl_Obj *returnPackagePtr; /* The result package for this conversation. */ } Conversation; static Conversation *conversations; /* A list of conversations currently * being processed. */ static RegisteredInterp *interps; /* List of all interpreters registered * in the current process. */ static HSZ globalService; static DWORD instance; /* The application instance handle given * to us by DdeInitialize. */ static int isServer; #define TCL_DDE_VERSION "1.2" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME "TclEval" /* * Forward declarations for procedures defined later in this file. */ static Tcl_Obj *ExecuteRemoteObject(Tcl_Interp *interp, Tcl_Obj *objPtr); static int MakeConnection(Tcl_Interp *interp, const char *name, HCONV *convPtr); static HDDEDATA CALLBACK ServerProc(UINT uType, UINT uFmt, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hData, DWORD dwData1, DWORD dwData2); static Tcl_ExitProc ExitProc; static Tcl_CmdDeleteProc DeleteProc; static void SetError(Tcl_Interp *interp); static Tcl_ObjCmdProc DdeObjCmd; /* *--------------------------------------------------------------------------- * * Initialize -- * * Initialize the global DDE instance. * * Results: * None. * * Side effects: * Registers the DDE server proc. * *--------------------------------------------------------------------------- */ static void Initialize(void) { int nameFound = 0; /* * See if the application is already registered; if so, remove its * current name from the registry. The deletion of the command * will take care of disposing of this entry. */ if (interps != NULL) { nameFound = 1; } /* * Make sure that the DDE server is there. This is done only once, * add an exit handler tear it down. */ if (instance == 0) { if (instance == 0) { unsigned int flags; flags = (CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS | CBF_FAIL_POKES); if (DdeInitialize(&instance, ServerProc, flags, 0) != DMLERR_NO_ERROR) { instance = 0; } } } if ((globalService == 0) && (nameFound != 0)) { if ((globalService == 0) && (nameFound != 0)) { isServer = TRUE; Tcl_CreateExitHandler(ExitProc, NULL); globalService = DdeCreateStringHandle(instance, TCL_DDE_SERVICE_NAME, 0); DdeNameService(instance, globalService, 0L, DNS_REGISTER); } else { isServer = FALSE; } } } /* *--------------------------------------------------------------------------- * * SetServerName -- * * This procedure is called to associate an ASCII name with a Dde * server. If the interpreter has already been named, the * name replaces the old one. * * Results: * The return value is the name actually given to the interp. * This will normally be the same as name, but if name was already * in use for a Dde Server then a name of the form "name #2" will * be chosen, with a high enough number to make the name unique. * * Side effects: * Registration info is saved, thereby allowing the "send" command * to be used later to invoke commands in the application. In * addition, the "send" command is created in the application's * interpreter. The registration will be removed automatically * if the interpreter is deleted or the "send" command is removed. * *--------------------------------------------------------------------------- */ static const char * SetServerName( Tcl_Interp *interp, const char *name) /* The name that will be used to * refer to the interpreter in later * "send" commands. Must be globally * unique. */ { int suffix, offset; RegisteredInterp *riPtr, *prevPtr; Tcl_DString dString; /* * See if the application is already registered; if so, remove its * current name from the registry. The deletion of the command * will take care of disposing of this entry. */ for (riPtr = interps, prevPtr = NULL; riPtr != NULL; prevPtr = riPtr, riPtr = riPtr->nextPtr) { if (riPtr->interp == interp) { if (name != NULL) { if (prevPtr == NULL) { interps = interps->nextPtr; } else { prevPtr->nextPtr = riPtr->nextPtr; } break; } else { /* * the name was NULL, so the caller is asking for * the name of the current interp. */ return riPtr->name; } } } if (name == NULL) { /* * the name was NULL, so the caller is asking for * the name of the current interp, but it doesn't * have a name. */ return ""; } /* * Pick a name to use for the application. Use "name" if it's not * already in use. Otherwise add a suffix such as " #2", trying * larger and larger numbers until we eventually find one that is * unique. */ suffix = 1; offset = 0; Tcl_DStringInit(&dString); /* * We have found a unique name. Now add it to the registry. */ riPtr = Blt_AssertMalloc(sizeof(RegisteredInterp) + strlen(name)); riPtr->interp = interp; riPtr->nextPtr = interps; interps = riPtr; strcpy(riPtr->name, name); Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, riPtr, DeleteProc); if (Tcl_IsSafe(interp)) { Tcl_HideCommand(interp, "dde", "dde"); } Tcl_DStringFree(&dString); /* * re-initialize with the new name */ Initialize(); return riPtr->name; } /* *--------------------------------------------------------------------------- * * DeleteProc * * This procedure is called when the command "dde" is destroyed. * * Results: * none * * Side effects: * The interpreter given by riPtr is unregistered. * *--------------------------------------------------------------------------- */ static void DeleteProc(clientData) ClientData clientData; /* The interp we are deleting passed * as ClientData. */ { RegisteredInterp *riPtr = clientData; RegisteredInterp *searchPtr, *prevPtr; for (searchPtr = interps, prevPtr = NULL; (searchPtr != NULL) && (searchPtr != riPtr); prevPtr = searchPtr, searchPtr = searchPtr->nextPtr) { /* * Empty loop body. */ } if (searchPtr != NULL) { if (prevPtr == NULL) { interps = interps->nextPtr; } else { prevPtr->nextPtr = searchPtr->nextPtr; } } Tcl_EventuallyFree(clientData, TCL_DYNAMIC); } /* *--------------------------------------------------------------------------- * * ExecuteRemoteObject -- * * Takes the package delivered by DDE and executes it in * the server's interpreter. * * Results: * A list Tcl_Obj * that describes what happened. The first * element is the numerical return code (TCL_ERROR, etc.). * The second element is the result of the script. If the * return result was TCL_ERROR, then the third element * will be the value of the global "errorCode", and the * fourth will be the value of the global "errorInfo". * The return result will have a refCount of 0. * * Side effects: * A TCL script is run, which can cause all kinds of other * things to happen. * *--------------------------------------------------------------------------- */ static Tcl_Obj * ExecuteRemoteObject( Tcl_Interp *interp, /* Remote interpreter. */ Tcl_Obj *objPtr) /* The object to execute. */ { Tcl_Obj *listObjPtr; int result; result = Tcl_GlobalEval(interp, Tcl_GetString(objPtr)); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_ListObjAppendElement(NULL, listObjPtr, Tcl_NewIntObj(result)); Tcl_ListObjAppendElement(NULL, listObjPtr, Tcl_GetObjResult(interp)); if (result == TCL_ERROR) { const char *value; Tcl_Obj *objPtr; value = Tcl_GetVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY); objPtr = Tcl_NewStringObj(value, -1); Tcl_ListObjAppendElement(NULL, listObjPtr, objPtr); value = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY); objPtr = Tcl_NewStringObj(value, -1); Tcl_ListObjAppendElement(NULL, listObjPtr, objPtr); } return listObjPtr; } /* *--------------------------------------------------------------------------- * * ServerProc -- * * Handles all transactions for this server. Can handle * execute, request, and connect protocols. Dde will * call this routine when a client attempts to run a dde * command using this server. * * Results: * A DDE Handle with the result of the dde command. * * Side effects: * Depending on which command is executed, arbitrary * Tcl scripts can be run. * *--------------------------------------------------------------------------- */ static HDDEDATA CALLBACK ServerProc ( UINT uType, /* The type of DDE transaction we * are performing. */ UINT uFmt, /* The format that data is sent or * received. */ HCONV hConv, /* The conversation associated with the * current transaction. */ HSZ topic, /* A string handle. Transaction-type * dependent. */ HSZ item, /* A string handle. Transaction-type * dependent. */ HDDEDATA hData, /* DDE data. Transaction-type dependent. */ DWORD dwData1, /* Transaction-dependent data. */ DWORD dwData2) /* Transaction-dependent data. */ { Tcl_DString dString; char *utilString; Tcl_Obj *objPtr; HDDEDATA code = NULL; RegisteredInterp *riPtr; Conversation *convPtr, *prevConvPtr; switch(uType) { case XTYP_CONNECT: { int length; /* * Dde is trying to initialize a conversation with us. Check * and make sure we have a valid topic. */ length = DdeQueryString(instance, topic, NULL, 0, 0); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, length); utilString = Tcl_DStringValue(&dString); DdeQueryString(instance, topic, utilString, length + 1, CP_WINANSI); for (riPtr = interps; riPtr != NULL; riPtr = riPtr->nextPtr) { if (strcasecmp(utilString, riPtr->name) == 0) { Tcl_DStringFree(&dString); return (HDDEDATA) TRUE; } } Tcl_DStringFree(&dString); return (HDDEDATA) FALSE; } case XTYP_CONNECT_CONFIRM: { DWORD length; /* * Dde has decided that we can connect, so it gives us a * conversation handle. We need to keep track of it * so we know which execution result to return in an * XTYP_REQUEST. */ length = DdeQueryString(instance, topic, NULL, 0, 0); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, length); utilString = Tcl_DStringValue(&dString); DdeQueryString(instance, topic, utilString, length + 1, CP_WINANSI); for (riPtr = interps; riPtr != NULL; riPtr = riPtr->nextPtr) { if (strcasecmp(riPtr->name, utilString) == 0) { convPtr = Blt_AssertMalloc(sizeof(Conversation)); convPtr->nextPtr = conversations; convPtr->returnPackagePtr = NULL; convPtr->hConv = hConv; convPtr->riPtr = riPtr; conversations = convPtr; break; } } Tcl_DStringFree(&dString); return (HDDEDATA) TRUE; } case XTYP_DISCONNECT: { /* * The client has disconnected from our server. Forget this * conversation. */ for (convPtr = conversations, prevConvPtr = NULL; convPtr != NULL; prevConvPtr = convPtr, convPtr = convPtr->nextPtr) { if (hConv == convPtr->hConv) { if (prevConvPtr == NULL) { conversations = convPtr->nextPtr; } else { prevConvPtr->nextPtr = convPtr->nextPtr; } if (convPtr->returnPackagePtr != NULL) { Tcl_DecrRefCount(convPtr->returnPackagePtr); } Blt_Free(convPtr); break; } } return (HDDEDATA) TRUE; } case XTYP_REQUEST: { int length; /* * This could be either a request for a value of a TCL variable, * or it could be the send command requesting the results of the * last execute. */ if (uFmt != CF_TEXT) { return (HDDEDATA) FALSE; } code = (HDDEDATA) FALSE; for (convPtr = conversations; (convPtr != NULL) && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) { /* * Empty loop body. */ } if (convPtr != NULL) { length = DdeQueryString(instance, item, NULL, 0, CP_WINANSI); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, length); utilString = Tcl_DStringValue(&dString); DdeQueryString(instance, item, utilString, length + 1, CP_WINANSI); if (strcasecmp(utilString, "$TCLEVAL$EXECUTE$RESULT") == 0) { const char *value; value = Tcl_GetStringFromObj(convPtr->returnPackagePtr, &length); code = DdeCreateDataHandle(instance, (char *)value, length+1, 0, item, CF_TEXT, 0); } else { const char *value; value = Tcl_GetVar2(convPtr->riPtr->interp, utilString, NULL, TCL_GLOBAL_ONLY); if (value != NULL) { length = strlen(value); code = DdeCreateDataHandle(instance, (char *)value, length+1, 0, item, CF_TEXT, 0); } else { code = NULL; } } Tcl_DStringFree(&dString); } return code; } case XTYP_EXECUTE: { DWORD length; /* * Execute this script. The results will be saved into * a list object which will be retreived later. See * ExecuteRemoteObject. */ Tcl_Obj *returnPackagePtr; for (convPtr = conversations; (convPtr != NULL) && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) { /* * Empty loop body. */ } if (convPtr == NULL) { return (HDDEDATA) DDE_FNOTPROCESSED; } utilString = (char *) DdeAccessData(hData, &length); objPtr = Tcl_NewStringObj(utilString, -1); Tcl_IncrRefCount(objPtr); DdeUnaccessData(hData); if (convPtr->returnPackagePtr != NULL) { Tcl_DecrRefCount(convPtr->returnPackagePtr); } convPtr->returnPackagePtr = NULL; returnPackagePtr = ExecuteRemoteObject(convPtr->riPtr->interp, objPtr); for (convPtr = conversations; (convPtr != NULL) && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) { /* * Empty loop body. */ } if (convPtr != NULL) { Tcl_IncrRefCount(returnPackagePtr); convPtr->returnPackagePtr = returnPackagePtr; } Tcl_DecrRefCount(objPtr); if (returnPackagePtr == NULL) { return (HDDEDATA) DDE_FNOTPROCESSED; } else { return (HDDEDATA) DDE_FACK; } } case XTYP_WILDCONNECT: { DWORD length; /* * Dde wants a list of services and topics that we support. */ HSZPAIR *returnPtr; int i; int numItems; for (i = 0, riPtr = interps; riPtr != NULL; i++, riPtr = riPtr->nextPtr) { /* * Empty loop body. */ } numItems = i; code = DdeCreateDataHandle(instance, NULL, (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0); returnPtr = (HSZPAIR *) DdeAccessData(code, &length); for (i = 0, riPtr = interps; i < numItems; i++, riPtr = riPtr->nextPtr) { returnPtr[i].hszSvc = DdeCreateStringHandle( instance, "TclEval", CP_WINANSI); returnPtr[i].hszTopic = DdeCreateStringHandle( instance, riPtr->name, CP_WINANSI); } returnPtr[i].hszSvc = NULL; returnPtr[i].hszTopic = NULL; DdeUnaccessData(code); return code; } } return NULL; } /* *--------------------------------------------------------------------------- * * ExitProc -- * * Gets rid of our DDE server when we go away. * * Results: * None. * * Side effects: * The DDE server is deleted. * *--------------------------------------------------------------------------- */ static void ExitProc( ClientData clientData) /* Not used in this handler. */ { DdeNameService(instance, NULL, 0, DNS_UNREGISTER); DdeUninitialize(instance); instance = 0; } /* *--------------------------------------------------------------------------- * * MakeConnection -- * * This procedure is a utility used to connect to a DDE * server when given a server name and a topic name. * * Results: * A standard TCL result. * * * Side effects: * Passes back a conversation through ddeConvPtr * *--------------------------------------------------------------------------- */ static int MakeConnection( Tcl_Interp *interp, /* Used to report errors. */ const char *name, /* The connection to use. */ HCONV *convPtr) { HSZ topic, service; HCONV conv; service = DdeCreateStringHandle(instance, "TclEval", 0); topic = DdeCreateStringHandle(instance, name, 0); conv = DdeConnect(instance, service, topic, NULL); DdeFreeStringHandle(instance, service); DdeFreeStringHandle(instance, topic); if (conv == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "no registered server named \"", name, "\"", (char *) NULL); } return TCL_ERROR; } *convPtr = conv; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetError -- * * Sets the interp result to a cogent error message * describing the last DDE error. * * Results: * None. * * * Side effects: * The interp's result object is changed. * *--------------------------------------------------------------------------- */ static void SetError( Tcl_Interp *interp) /* The interp to put the message in.*/ { int err; const char *mesg; err = DdeGetLastError(instance); switch (err) { case DMLERR_DATAACKTIMEOUT: case DMLERR_EXECACKTIMEOUT: case DMLERR_POKEACKTIMEOUT: mesg = "remote interpreter did not respond"; break; case DMLERR_BUSY: mesg = "remote server is busy"; break; case DMLERR_NOTPROCESSED: mesg = "remote server cannot handle this command"; break; default: mesg = "dde command failed"; break; } Tcl_SetStringObj(Tcl_GetObjResult(interp), mesg, -1); } /* *--------------------------------------------------------------------------- * * DdeObjCmd -- * * This procedure is invoked to process the "dde" TCL command. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int DdeObjCmd( ClientData clientData, /* Used only for deletion */ Tcl_Interp *interp, /* The interp we are sending from */ int objc, /* Number of arguments */ Tcl_Obj *const objv[]) /* The arguments */ { enum { DDE_SERVERNAME, DDE_EXECUTE, DDE_POKE, DDE_REQUEST, DDE_SERVICES, DDE_EVAL }; static const char *commands[] = { "servername", "execute", "poke", "request", "services", "eval", (char *) NULL }; static const char *options[] = { "-async", (char *) NULL }; int index, argIndex; int async = 0, binary = 0; int result = TCL_OK; HSZ service = NULL; HSZ topic = NULL; HSZ item = NULL; HDDEDATA data = NULL; HDDEDATA itemData = NULL; HCONV hConv = NULL; HSZ cookie = 0; const char *serviceName, *topicName, *itemString, *dataString; const char *string; int firstArg, length, dataLength; HDDEDATA code; RegisteredInterp *riPtr; Tcl_Interp *sendInterp; Tcl_Obj *objPtr; /* * Initialize DDE server/client */ if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "?-async? serviceName topicName value"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], commands, "command", 0, &index) != TCL_OK) { return TCL_ERROR; } serviceName = NULL; /* Suppress compiler warning. */ firstArg = 1; switch (index) { case DDE_SERVERNAME: if ((objc != 3) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "servername ?serverName?"); return TCL_ERROR; } firstArg = (objc - 1); break; case DDE_EXECUTE: if ((objc < 5) || (objc > 6)) { Tcl_WrongNumArgs(interp, 1, objv, "execute ?-async? serviceName topicName value"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(NULL, objv[2], options, "option", 0, &argIndex) != TCL_OK) { if (objc != 5) { Tcl_WrongNumArgs(interp, 1, objv, "execute ?-async? serviceName topicName value"); return TCL_ERROR; } async = 0; firstArg = 2; } else { if (objc != 6) { Tcl_WrongNumArgs(interp, 1, objv, "execute ?-async? serviceName topicName value"); return TCL_ERROR; } async = 1; firstArg = 3; } break; case DDE_POKE: if (objc != 6) { Tcl_WrongNumArgs(interp, 1, objv, "poke serviceName topicName item value"); return TCL_ERROR; } firstArg = 2; break; case DDE_REQUEST: if (objc != 5) { Tcl_WrongNumArgs(interp, 1, objv, "request serviceName topicName value"); return TCL_ERROR; } binary = 0; firstArg = 2; break; case DDE_SERVICES: if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "services serviceName topicName"); return TCL_ERROR; } firstArg = 2; break; case DDE_EVAL: if (objc < 4) { Tcl_WrongNumArgs(interp, 1, objv, "eval ?-async? serviceName args"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(NULL, objv[2], options, "option", 0, &argIndex) != TCL_OK) { if (objc < 4) { Tcl_WrongNumArgs(interp, 1, objv, "eval ?-async? serviceName args"); return TCL_ERROR; } async = 0; firstArg = 2; } else { if (objc < 5) { Tcl_WrongNumArgs(interp, 1, objv, "eval ?-async? serviceName args"); return TCL_ERROR; } async = 1; firstArg = 3; } break; } Initialize(); if (firstArg != 1) { serviceName = Tcl_GetStringFromObj(objv[firstArg], &length); } else { length = 0; } if (length == 0) { serviceName = NULL; } else if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { service = DdeCreateStringHandle(instance, serviceName, CP_WINANSI); } if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length); if (length == 0) { topicName = NULL; } else { topic = DdeCreateStringHandle(instance, topicName, CP_WINANSI); } } switch (index) { case DDE_SERVERNAME: serviceName = SetServerName(interp, serviceName); if (serviceName != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), serviceName, -1); } else { Tcl_ResetResult(interp); } break; case DDE_EXECUTE: { dataString = Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength); if (dataLength == 0) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "cannot execute null data", -1); result = TCL_ERROR; break; } hConv = DdeConnect(instance, service, topic, NULL); DdeFreeStringHandle(instance, service); DdeFreeStringHandle(instance, topic); if (hConv == NULL) { SetError(interp); result = TCL_ERROR; break; } data = DdeCreateDataHandle(instance, (char *)dataString, dataLength + 1, 0, 0, CF_TEXT, 0); if (data != NULL) { if (async) { DWORD status; DdeClientTransaction((LPBYTE) data, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &status); DdeAbandonTransaction(instance, hConv, status); } else { code = DdeClientTransaction((LPBYTE) data, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL); if (code == 0) { SetError(interp); result = TCL_ERROR; } } DdeFreeDataHandle(data); } else { SetError(interp); result = TCL_ERROR; } break; } case DDE_REQUEST: { itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); if (length == 0) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "cannot request value of null data", -1); return TCL_ERROR; } hConv = DdeConnect(instance, service, topic, NULL); DdeFreeStringHandle(instance, service); DdeFreeStringHandle(instance, topic); if (hConv == NULL) { SetError(interp); result = TCL_ERROR; } else { item = DdeCreateStringHandle(instance, itemString, CP_WINANSI); if (item != NULL) { data = DdeClientTransaction(NULL, 0, hConv, item, CF_TEXT, XTYP_REQUEST, 5000, NULL); if (data == NULL) { SetError(interp); result = TCL_ERROR; } else { Tcl_Obj *objPtr; DWORD dataLength; dataString = DdeAccessData(data, &dataLength); objPtr = Tcl_NewStringObj(dataString, -1); DdeUnaccessData(data); DdeFreeDataHandle(data); Tcl_SetObjResult(interp, objPtr); } } else { SetError(interp); result = TCL_ERROR; } } break; } case DDE_POKE: { itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); if (length == 0) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "cannot have a null item", -1); return TCL_ERROR; } dataString = Tcl_GetStringFromObj(objv[firstArg + 3], &length); hConv = DdeConnect(instance, service, topic, NULL); DdeFreeStringHandle(instance, service); DdeFreeStringHandle(instance, topic); if (hConv == NULL) { SetError(interp); result = TCL_ERROR; } else { item = DdeCreateStringHandle(instance, itemString, CP_WINANSI); if (item != NULL) { data = DdeClientTransaction((char *)dataString, length+1, hConv, item, CF_TEXT, XTYP_POKE, 5000, NULL); if (data == NULL) { SetError(interp); result = TCL_ERROR; } } else { SetError(interp); result = TCL_ERROR; } } break; } case DDE_SERVICES: { HCONVLIST hConvList; CONVINFO convInfo; Tcl_Obj *convListObjPtr, *elementObjPtr; Tcl_DString dString; const char *name; convInfo.cb = sizeof(CONVINFO); hConvList = DdeConnectList(instance, service, topic, 0, NULL); DdeFreeStringHandle(instance, service); DdeFreeStringHandle(instance, topic); hConv = 0; convListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_DStringInit(&dString); while (hConv = DdeQueryNextServer(hConvList, hConv), hConv != 0) { elementObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); DdeQueryConvInfo(hConv, QID_SYNC, &convInfo); length = DdeQueryString(instance, convInfo.hszSvcPartner, NULL, 0, CP_WINANSI); Tcl_DStringSetLength(&dString, length); name = Tcl_DStringValue(&dString); DdeQueryString(instance, convInfo.hszSvcPartner, (char *)name, length + 1, CP_WINANSI); Tcl_ListObjAppendElement(interp, elementObjPtr, Tcl_NewStringObj(name, length)); length = DdeQueryString(instance, convInfo.hszTopic, NULL, 0, CP_WINANSI); Tcl_DStringSetLength(&dString, length); name = Tcl_DStringValue(&dString); DdeQueryString(instance, convInfo.hszTopic, (char *)name, length + 1, CP_WINANSI); Tcl_ListObjAppendElement(interp, elementObjPtr, Tcl_NewStringObj(name, length)); Tcl_ListObjAppendElement(interp, convListObjPtr, elementObjPtr); } DdeDisconnectList(hConvList); Tcl_SetObjResult(interp, convListObjPtr); Tcl_DStringFree(&dString); break; } case DDE_EVAL: { objc -= (async + 3); objv += (async + 3); /* * See if the target interpreter is local. If so, execute * the command directly without going through the DDE * server. Don't exchange objects between interps. The * target interp could compile an object, producing a * bytecode structure that refers to other objects owned * by the target interp. If the target interp is then * deleted, the bytecode structure would be referring to * deallocated objects. */ for (riPtr = interps; riPtr != NULL; riPtr = riPtr->nextPtr) { if (strcasecmp(serviceName, riPtr->name) == 0) { break; } } if (riPtr != NULL) { /* * This command is to a local interp. No need to go through * the server. */ Tcl_Preserve(riPtr); sendInterp = riPtr->interp; Tcl_Preserve(sendInterp); /* * Don't exchange objects between interps. The target interp * would compile an object, producing a bytecode structure that * refers to other objects owned by the target interp. If the * target interp is then deleted, the bytecode structure would * be referring to deallocated objects. */ if (objc == 1) { result = Tcl_GlobalEval(sendInterp,Tcl_GetString(objv[0])); } else { objPtr = Tcl_ConcatObj(objc, objv); Tcl_IncrRefCount(objPtr); result = Tcl_GlobalEval(sendInterp, Tcl_GetString(objPtr)); Tcl_DecrRefCount(objPtr); } if (interp != sendInterp) { if (result == TCL_ERROR) { const char *value; /* * An error occurred, so transfer error information * from the destination interpreter back to our * interpreter. */ Tcl_ResetResult(interp); value = Tcl_GetVar2(sendInterp, "errorInfo", NULL, TCL_GLOBAL_ONLY); Tcl_AddObjErrorInfo(interp, value, length); value = Tcl_GetVar2(sendInterp, "errorCode", NULL, TCL_GLOBAL_ONLY); Tcl_SetErrorCode(interp, value, (char *)NULL); } Tcl_SetObjResult(interp, Tcl_GetObjResult(sendInterp)); } Tcl_Release(riPtr); Tcl_Release(sendInterp); } else { /* * This is a non-local request. Send the script to the server * and poll it for a result. */ if (MakeConnection(interp, serviceName, &hConv) != TCL_OK) { goto error; } objPtr = Tcl_ConcatObj(objc, objv); string = Tcl_GetStringFromObj(objPtr, &length); itemData = DdeCreateDataHandle(instance, (char *)string, length+1, 0, 0, CF_TEXT, 0); if (async) { DWORD status; data = DdeClientTransaction((LPBYTE) itemData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &status); DdeAbandonTransaction(instance, hConv, status); } else { data = DdeClientTransaction((LPBYTE) itemData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL); if (data != 0) { cookie = DdeCreateStringHandle(instance, "$TCLEVAL$EXECUTE$RESULT", CP_WINANSI); data = DdeClientTransaction(NULL, 0, hConv, cookie, CF_TEXT, XTYP_REQUEST, 30000, NULL); } } Tcl_DecrRefCount(objPtr); if (data == 0) { SetError(interp); goto errorNoResult; } if (async == 0) { Tcl_Obj *resultPtr; /* * The return handle has a two or four element list in * it. The first element is the return code (TCL_OK, * TCL_ERROR, etc.). The second is the result of the * script. If the return code is TCL_ERROR, then the third * element is the value of the variable "errorCode", and * the fourth is the value of the variable "errorInfo". */ resultPtr = Tcl_NewObj(); length = DdeGetData(data, NULL, 0, 0); Tcl_SetObjLength(resultPtr, length); string = Tcl_GetStringFromObj(resultPtr, length); DdeGetData(data, (char *)string, length, 0); Tcl_SetObjLength(resultPtr, strlen(string)); if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) { Tcl_DecrRefCount(resultPtr); goto error; } if (Tcl_GetIntFromObj(NULL, objPtr, &result) != TCL_OK) { Tcl_DecrRefCount(resultPtr); goto error; } if (result == TCL_ERROR) { Tcl_ResetResult(interp); if (Tcl_ListObjIndex(NULL, resultPtr, 3, &objPtr) != TCL_OK) { Tcl_DecrRefCount(resultPtr); goto error; } length = -1; string = Tcl_GetStringFromObj(objPtr, &length); Tcl_AddObjErrorInfo(interp, string, length); Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr); Tcl_SetObjErrorCode(interp, objPtr); } if (Tcl_ListObjIndex(NULL, resultPtr, 1, &objPtr) != TCL_OK) { Tcl_DecrRefCount(resultPtr); goto error; } Tcl_SetObjResult(interp, objPtr); Tcl_DecrRefCount(resultPtr); } } } } if (cookie != NULL) { DdeFreeStringHandle(instance, cookie); } if (item != NULL) { DdeFreeStringHandle(instance, item); } if (itemData != NULL) { DdeFreeDataHandle(itemData); } if (data != NULL) { DdeFreeDataHandle(data); } if (hConv != NULL) { DdeDisconnect(hConv); } return result; error: Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid data returned from server", -1); errorNoResult: if (cookie != NULL) { DdeFreeStringHandle(instance, cookie); } if (item != NULL) { DdeFreeStringHandle(instance, item); } if (itemData != NULL) { DdeFreeDataHandle(itemData); } if (data != NULL) { DdeFreeDataHandle(data); } if (hConv != NULL) { DdeDisconnect(hConv); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * Blt_DdeCmdInitProc -- * * This procedure initializes the dde command. * * Results: * A standard TCL result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_DdeCmdInitProc(interp) Tcl_Interp *interp; { Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL); conversations = NULL; interps = NULL; Tcl_CreateExitHandler(ExitProc, NULL); return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION); } #endif /* NO_DDE */ ����������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDBuffer.h������������������������������������������������������������������0000644�0001750�0001750�00000007555�11462120062�015231� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltDBuffer.h -- * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_DBUFFER_H #define _BLT_DBUFFER_H typedef struct _Blt_DBuffer { unsigned char *bytes; /* Stores output (malloc-ed).*/ size_t nBytes; /* Size of dynamically allocated buffer. */ size_t count; /* # of bytes read into the buffer. Marks the * # current fill point of the buffer. */ size_t cursor; /* Current position in buffer. */ size_t chunk; /* Buffer growth size. */ } *Blt_DBuffer; BLT_EXTERN void Blt_DBuffer_VarAppend TCL_VARARGS(Blt_DBuffer, buffer); BLT_EXTERN void Blt_DBuffer_Print TCL_VARARGS(Blt_DBuffer, buffer); BLT_EXTERN void Blt_DBuffer_Init(Blt_DBuffer buffer); BLT_EXTERN void Blt_DBuffer_Free(Blt_DBuffer buffer); BLT_EXTERN unsigned char *Blt_DBuffer_Extend(Blt_DBuffer buffer, size_t extra); BLT_EXTERN int Blt_DBuffer_AppendData(Blt_DBuffer buffer, const unsigned char *bytes, size_t extra); BLT_EXTERN int Blt_DBuffer_Resize(Blt_DBuffer buffer, size_t length); BLT_EXTERN Blt_DBuffer Blt_DBuffer_Create(void); BLT_EXTERN void Blt_DBuffer_Destroy(Blt_DBuffer buffer); BLT_EXTERN int Blt_DBuffer_LoadFile(Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer); BLT_EXTERN int Blt_DBuffer_SaveFile(Tcl_Interp *interp, const char *fileName, Blt_DBuffer buffer); BLT_EXTERN void Blt_DBuffer_AppendByte(Blt_DBuffer buffer, unsigned char byte); BLT_EXTERN void Blt_DBuffer_AppendShort(Blt_DBuffer buffer, unsigned short value); BLT_EXTERN void Blt_DBuffer_AppendLong(Blt_DBuffer buffer, unsigned int value); BLT_EXTERN Tcl_Obj *Blt_DBuffer_ByteArrayObj(Blt_DBuffer buffer); BLT_EXTERN Tcl_Obj *Blt_DBuffer_StringObj(Blt_DBuffer buffer); #define Blt_DBuffer_Bytes(s) ((s)->bytes) #define Blt_DBuffer_Size(s) ((s)->nBytes) #define Blt_DBuffer_BytesLeft(s) ((s)->count - (s)->cursor) #define Blt_DBuffer_NextByte(s) ((s)->bytes[(s)->cursor++]) #define Blt_DBuffer_Pointer(s) ((s)->bytes + (s)->cursor) #define Blt_DBuffer_SetPointer(s,p) ((s)->cursor = (p) - (s)->bytes) #define Blt_DBuffer_ResetCursor(s) ((s)->cursor = 0) #define Blt_DBuffer_Cursor(s) ((s)->cursor) #define Blt_DBuffer_SetCursor(s,n) ((s)->cursor = (n)) #define Blt_DBuffer_IncrCursor(s,i) ((s)->cursor += (i)) #define Blt_DBuffer_End(s) ((s)->bytes + (s)->count) #define Blt_DBuffer_Length(s) ((s)->count) #define Blt_DBuffer_SetLengthFromPointer(s,p) \ ((s)->count = ((p) - (s)->bytes)) #define Blt_DBuffer_SetLength(s,i) \ ((s)->count = (i), (s)->bytes[(s)->count] = '\0') #define Blt_DBuffer_IncrLength(s,i) ((s)->count += (i)) BLT_EXTERN int Blt_DBuffer_DecodeBase64(Tcl_Interp *interp, const char *string, size_t length, Blt_DBuffer buffer); BLT_EXTERN char *Blt_DBuffer_EncodeBase64(Tcl_Interp *interp, Blt_DBuffer buffer); BLT_EXTERN int Blt_IsBase64(const unsigned char *bytes, size_t length); #endif /*_BLT_DBUFFER_H*/ ���������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrMesh.c�������������������������������������������������������������������0000644�0001750�0001750�00000134254�11462120062�015071� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� typedef unsigned int PointIndex; typedef struct { float x, y; int index; } MeshPoint; typedef struct { PointIndex a, b; /* Index of two points in x, y, point array */ } Edge; typedef struct { PointIndex ab, bc, ac; /* Index of three edges representing a * triangle in the edge array. */ float min, max; } Triangle; typedef Mesh *(MeshCreateProc)(void); typedef void (MeshDestroyProc)(Mesh *meshPtr); typedef void (MeshConfigureProc)(Mesh *meshPtr); typedef enum MeshTypes { MESH_CLOUD, MESH_REGULAR, MESH_IRREGULAR, MESH_TRIANGULAR } MeshType; typedef struct { enum MeshTypes type; /* Indicates type of mesh. */ const char *name; /* String representation for type of class. */ Blt_ConfigSpec *configSpecs; /* Mesh configuration specifications. */ MeshDestroyProc *destroyProc; MeshConfigureProc *configProc; } MeshClass; typedef enum SourceTypes { SOURCE_LIST, SOURCE_VECTOR, SOURCE_TABLE, SOURCE_NONE } SourceType; typedef struct { enum SourceTypes type; /* Selects the type of data populating this * vector: SOURCE_VECTOR, * SOURCE_TABLE, or SOURCE_LIST */ SourceGetProc *getProc; SourceDestroyProc *destroyProc; SourcePrintProc *printProc; } DataSourceClass; typedef struct { float min, max, logMin; float *values; float nValues; } DataSourceResult; typedef struct { DataSourceClass *classPtr; DataSourceChangedProc *proc; ClientData clientData; } DataSource; typedef int (SourceGetProc)(Tcl_Interp *interp, DataSource *srcPtr, DataSourceResult *resultPtr); typedef int (SourceDestroyProc)(DataSource *srcPtr); typedef Tcl_Obj * (SourcePrintProc)(DataSource *srcPtr); typedef struct { DataSourceClass *classPtr; DataSourceChangedProc *proc; ClientData clientData; Blt_VectorId vector; } VectorDataSource; typedef struct { DataSourceClass *classPtr; DataSourceChangedProc *proc; ClientData clientData; float *values; int nValues; } ListDataSource; typedef struct { Blt_Table table; int refCount; } TableClient; typedef struct { DataSourceClass *classPtr; DataSourceChangedProc *proc; ClientData clientData; Blt_Table table; /* Data table. */ Blt_TableColumn column; /* Column of data used. */ Blt_TableNotifier notifier; /* Notifier used for column (destroy). */ Blt_TableTrace trace; /* Trace used for column (set/get/unset). */ Blt_HashEntry *hashPtr; /* Pointer to entry of source in graph's hash * table of datatables. One graph may use * multiple columns from the same data * table. */ } TableDataSource; typedef struct { const char *name; /* Mesh identifier. */ MeshClass *classPtr; Graph *graphPtr; /* Graph that the mesh is associated with. */ unsigned int flags; /* Indicates if the mesh element is active or * normal */ int refCount; /* Reference count for elements using this * mesh. */ Blt_HashEntry *hashPtr; /* Resulting mesh is a triangular grid. */ MeshPoint *points; /* Array of points representing the mesh. */ int nPoints; /* # of points in array. */ int *hull; /* Array of indices of points representing the * convex hull of the mesh. */ int nHullPts; float xMin, yMin, xMax, yMax, xLogMin, yLogMin; Edges *edges; /* Array of edges. */ int nEdges; /* # of edges in array. */ Triangles *triangles; /* Array of triangles. */ int nTriangles; /* # of triangles in array. */ DataSource *x, *y; } Mesh; typedef struct { const char *name; /* Mesh identifier. */ MeshClass *classPtr; Graph *graphPtr; /* Graph that the mesh is associated with. */ unsigned int flags; /* Indicates if the mesh element is active or * normal */ int refCount; /* Reference count for elements using this * mesh. */ Blt_HashEntry *hashPtr; /* Resulting mesh is a triangular grid. */ MeshPoint *points; /* Array of points representing the mesh. */ int nPoints; /* # of points in array. */ int *hull; /* Array of indices of points representing the * convex hull of the mesh. */ int nHullPts; float xMin, yMin, xMax, yMax, xLogMin, yLogMin; Edges *edges; /* Array of edges. */ int nEdges; /* # of edges in array. */ Triangles *triangles; /* Array of triangles. */ int nTriangles; /* # of triangles in array. */ DataSource *x, *y; } RegularMesh; typedef struct { const char *name; /* Mesh identifier. */ MeshClass *classPtr; Graph *graphPtr; /* Graph that the mesh is associated with. */ unsigned int flags; /* Indicates if the mesh element is active or * normal */ int refCount; /* Reference count for elements using this * mesh. */ Blt_HashEntry *hashPtr; /* Resulting mesh is a triangular grid. */ MeshPoint *points; /* Array of points representing the mesh. */ int nPoints; /* # of points in array. */ int *hull; /* Array of indices of points representing the * convex hull of the mesh. */ int nHullPts; float xMin, yMin, xMax, yMax, xLogMin, yLogMin; Edges *edges; /* Array of edges. */ int nEdges; /* # of edges in array. */ Triangles *triangles; /* Array of triangles. */ int nTriangles; /* # of triangles in array. */ DataSource *x, *y; } IrregularMesh; typedef struct { const char *name; /* Mesh identifier. */ MeshClass *classPtr; Graph *graphPtr; /* Graph that the mesh is associated with. */ unsigned int flags; /* Indicates if the mesh element is active or * normal */ int refCount; /* Reference count for elements using this * mesh. */ Blt_HashEntry *hashPtr; /* Resulting mesh is a triangular grid. */ MeshPoint *points; /* Array of points representing the mesh. */ int nPoints; /* # of points in array. */ int *hull; /* Array of indices of points representing the * convex hull of the mesh. */ int nHullPts; float xMin, yMin, xMax, yMax, xLogMin, yLogMin; Edges *edges; /* Array of edges. */ int nEdges; /* # of edges in array. */ Triangles *triangles; /* Array of triangles. */ int nTriangles; /* # of triangles in array. */ DataSource *x, *y; } CloudMesh; static MeshConfigureProc CloudMeshConfigureProc; static MeshDestroyProc CloudMeshDestroyProc; static MeshConfigureProc IrregularMeshConfigureProc; static MeshDestroyProc IrregularMeshDestroyProc; static MeshConfigureProc RegularMeshConfigureProc; static MeshDestroyProc RegularMeshDestroyProc; static MeshConfigureProc TriangularMeshConfigureProc; static MeshDestroyProc TriangularMeshDestroyProc; static MeshClass cloudMeshClass = { MESH_CLOUD, "Cloud", CloudMeshConfigureProc, CloudMeshDestroyProc, }; static MeshClass regularMeshClass = { MESH_REGULAR, "Regular", RegularMeshConfigureProc, RegularMeshDestroyProc, }; static MeshClass triangularMeshClass = { MESH_TRIANGULAR, "Triangular", TriangularMeshConfigureProc, TriangularMeshDestroyProc, }; static MeshClass irregularMeshClass = { MESH_IRREGULAR, "Irregular", IrregularMeshConfigureProc, IrregularMeshDestroyProc, }; static SourceGetProc ListDataSourceGetProc; static SourcePrintProc ListDataSourcePrintProc; static SourceDestroyProc ListDataSourceDestroyProc; static SourceGetProc TableDataSourceGetProc; static SourcePrintProc TableDataSourcePrintProc; static SourceDestroyProc TableDataSourceDestroyProc; static SourceGetProc VectorDataSourceGetProc; static SourcePrintProc VectorDataSourcePrintProc; static SourceDestroyProc VectorDataSourceDestroyProc; static DataSourceClass listDataSourceClass = { SOURCE_LIST, "List", ListDataSourceGetProc, ListDataSourceDestroyProc, ListDataSourcePrintProc }; static DataSourceClass vectorDataSourceClass = { SOURCE_VECTOR, "Vector", VectorDataSourceGetProc, VectorDataSourceDestroyProc, VectorDataSourcePrintProc }; static DataSourceClass tableDataSourceClass = { SOURCE_TABLE, "Table", TableDataSourceGetProc, TableDataSourceDestroyProc, TableDataSourcePrintProc }; static Blt_OptionFreeProc FreeDataSource; static Blt_OptionParseProc ObjToDataSource; static Blt_OptionPrintProc DataSourceToObj; Blt_CustomOption bltDataSourceOption = { ObjToDataSourceProc, DataSourceToObjProc, FreeDataSourceProc, (ClientData)0 }; static Blt_ConfigSpec cloudMeshSpecs[] = { {BLT_CONFIG_STRING, "-name", "name", "name", (char *)NULL, Blt_Offset(Cloud, name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(Cloud, x), 0, &bltDataSourceOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(Cloud, y), 0, &bltDataSourceOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec regularMeshSpecs[] = { {BLT_CONFIG_STRING, "-name", "name", "name", (char *)NULL, Blt_Offset(Cloud, name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(Cloud, x), 0, &bltDataSourceOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(Cloud, y), 0, &bltDataSourceOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec irregularMeshSpecs[] = { {BLT_CONFIG_STRING, "-name", "name", "name", (char *)NULL, Blt_Offset(Cloud, name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(Cloud, x), 0, &bltDataSourceOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(Cloud, y), 0, &bltDataSourceOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec triangularMeshSpecs[] = { {BLT_CONFIG_STRING, "-name", "name", "name", (char *)NULL, Blt_Offset(Cloud, name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-x", "xData", "XData", (char *)NULL, Blt_Offset(Cloud, x), 0, &bltDataSourceOption}, {BLT_CONFIG_CUSTOM, "-y", "yData", "YData", (char *)NULL, Blt_Offset(Cloud, y), 0, &bltDataSourceOption}, {BLT_CONFIG_CUSTOM, "-triangles", "triangles", "Triangles", (char *)NULL, Blt_Offset(Cloud, triangles), 0, &trianglesOption}, {BLT_CONFIG_CUSTOM, "-edges", "edges", "Edges", (char *)NULL, Blt_Offset(Cloud, edges), 0, &edgesOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Tcl_Obj * VectorDataSourcePrintProc(DataSource *dataSrcPtr) { VectorDataSource *srcPtr = (VectorDataSource *)dataSrcPtr; return Tcl_NewStringObj(Blt_NameOfVectorId(srcPtr->vector), -1); } static void VectorDataSourceDestroyProc(DataSource *dataSrcPtr) { VectorDataSource *srcPtr = (VectorDataSource *)dataSrcPtr; Blt_SetVectorChangedProc(srcPtr->vector, NULL, NULL); if (srcPtr->vector != NULL) { Blt_FreeVectorId(srcPtr->vector); } } /* *--------------------------------------------------------------------------- * * VectorChangedProc -- * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static void VectorChangedProc(Tcl_Interp *interp, ClientData clientData, Blt_VectorNotify notify) { VectorDataSource *srcPtr = clientData; if (notify == BLT_VECTOR_NOTIFY_DESTROY) { DestroyDataSource(srcPtr); return; } (*srcPtr->proc)(srcPtr->clientData); } static DataSource * CreateVectorDataSource(Tcl_Interp *interp, const char *name) { Blt_Vector *vecPtr; VectorDataSource *srcPtr; srcPtr = Blt_AssertCalloc(sizeof(VectorDataSource)); srcPtr->type = SOURCE_VECTOR; srcPtr->vector = Blt_AllocVectorId(interp, name); if (Blt_GetVectorById(interp, srcPtr->vector, &vecPtr) != TCL_OK) { Blt_Free(srcPtr); return NULL; } Blt_SetVectorChangedProc(srcPtr->vector, VectorChangedProc, srcPtr); return (DataSource *)srcPtr; } static int VectorDataSourceGetProc(Tcl_Interp *interp, DataSource *dataSrcPtr, DataSourceResult *resultPtr) { VectorDataSource *srcPtr = (VectorDataSource *)dataSrcPtr; size_t nBytes; Blt_Vector *vector; if (Blt_GetVectorById(interp, srcPtr->vector, &vector) != TCL_OK) { return TCL_ERROR; } nBytes = Blt_VecLength(vector) * sizeof(float); values = Blt_Malloc(nBytes); if (values == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); } return TCL_ERROR; } { float *values; float min, max, logMin; double *data; double *p; int i; p = Blt_VecData(vector); logMin = min = max = (float)*p++; for (i = 0; i < Blt_VecLength(vector); i++, p++) { values[i] = (float)*p; if (*p > max) { max = (float)*p; } else if (*p < min) { min = (float)*p; } if ((*p > 0.0f) && (*p < logMin)) { logMin = (float)*p; } } resultPtr->min = min; resultPtr->max = max; resultPtr->logMin = logMin; } resultPtr->values = values; resultPtr->nValues = Blt_VecLength(vector); return TCL_OK; } static Tcl_Obj * ListDataSourcePrintProc(DataSource *dataSrcPtr) { ListDataSource *srcPtr = (ListDataSource *)dataSrcPtr; Tcl_Obj *listObjPtr; float *vp, *vend; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (vp = srcPtr->values, vend = vp + srcPtr->nValues; vp < vend; vp++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj((double)*vp)); } return listObjPtr; } static void ListDataSourceDestroyProc(DataSource *dataSrcPtr) { ListDataSource *srcPtr = (ListDataSource *)dataSrcPtr; if (srcPtr->values != NULL) { Blt_Free(srcPtr->values); } (*srcPtr->proc)(srcPtr, srcPtr->clientData); } static DataSource * CreateListDataSource(Tcl_Interp *interp, int objc, Tcl_Obj **objv) { float *values; int nValues; ListDataSource *srcPtr; srcPtr = Blt_AssertMalloc(sizeof(ListDataSource)); srcPtr->type = SOURCE_LIST; nValues = 0; values = NULL; if (objc > 0) { float *p; int i; values = Blt_Malloc(sizeof(float) * objc); if (values == NULL) { Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); return NULL; } for (p = values, i = 0; i < objc; i++, p++) { double value; if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { Blt_Free(array); return TCL_ERROR; } *p = (float)value; } srcPtr->values = values; srcPtr->nValues = objc; } return (DataSource *)srcPtr; } static int ListDataSourceGetProc(Tcl_Interp *interp, SourceData *dataSrcPtr, float *minPtr, DataSourceResult *resultPtr) { long i, j; float *values; float min, max, logMin; ListDataSource *srcPtr = (ListDataSource *)dataSrcPtr; values = Blt_Malloc(sizeof(float) * srcPtr->nValues); if (values == NULL) { return TCL_ERROR; } sp = srcPtr->values; logMin = min = max = values[0] = *sp++; for (send = srcPtr->values + srcPtr->nValues; sp < send; sp++) { if (*sp > max) { max = *sp; } else if (*sp < min) { min = *sp; } if ((*sp > 0.0f) && (*sp < logMin)) { logMin = *sp; } values[j] = *sp; } resultPtr->min = min; resultPtr->max = max; resultPtr->logMin = logMin; resultPtr->values = values; resultPtr->nValues = srcPtr->nValues; return TCL_OK; } static void TableDataSourceDestroyProc(DataSource *dataSrcPtr) { TableDataSource *srcPtr = (TableDataSource *)dataSrcPtr; if (srcPtr->trace != NULL) { Blt_Table_DeleteTrace(srcPtr->trace); } if (srcPtr->notifier != NULL) { Blt_Table_DeleteNotifier(srcPtr->notifier); } if (srcPtr->hashPtr != NULL) { TableClient *clientPtr; clientPtr = Blt_GetHashValue(srcPtr->hashPtr); clientPtr->refCount--; if (clientPtr->refCount == 0) { if (srcPtr->table != NULL) { Blt_Table_Close(srcPtr->table); } Blt_Free(clientPtr); Blt_DeleteHashEntry(&graphPtr->dataTables, srcPtr->hashPtr); } (*srcPtr->proc)(srcPtr, srcPtr->clientData); } } /* *--------------------------------------------------------------------------- * * TableNotifyProc -- * * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static int TableNotifyProc(ClientData clientData, Blt_TableNotifyEvent *eventPtr) { TableDataSource *srcPtr = clientData; if (eventPtr->type == TABLE_NOTIFY_COLUMN_DELETED) { (*srcPtr->classPtr->destroyProc)(srcPtr); srcPtr->classPtr = NULL; return TCL_ERROR; } (*srcPtr->proc)(srcPtr->clientData); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TableTraceProc -- * * * Results: * None. * * Side Effects: * Graph is redrawn. * *--------------------------------------------------------------------------- */ static int TableTraceProc(ClientData clientData, Blt_TableTraceEvent *eventPtr) { TableDataSource *srcPtr = clientData; assert(eventPtr->column == srcPtr->column); (*srcPtr->proc)(srcPtr->clientData); return TCL_OK; } static DataSource * CreateTableDataSource(Tcl_Interp *interp, const char *name, Tcl_Obj *colObjPtr) { TableDataSource *srcPtr; TableClient *clientPtr; int isNew; srcPtr = Blt_AssertMalloc(sizeof(TableDataSource)); srcPtr->type = SOURCE_TABLE; /* See if the graph is already using this table. */ srcPtr->hashPtr = Blt_CreateHashEntry(&graphPtr->dataTables, name, &isNew); if (isNew) { if (Blt_Table_Open(interp, name, &srcPtr->table) != TCL_OK) { return TCL_ERROR; } clientPtr = Blt_AssertMalloc(sizeof(TableClient)); clientPtr->table = srcPtr->table; clientPtr->refCount = 1; Blt_SetHashValue(srcPtr->hashPtr, clientPtr); } else { clientPtr = Blt_GetHashValue(srcPtr->hashPtr); srcPtr->table = clientPtr->table; clientPtr->refCount++; } srcPtr->column = Blt_Table_FindColumn(interp, srcPtr->table, colObjPtr); if (srcPtr->column == NULL) { goto error; } srcPtr->notifier = Blt_Table_CreateColumnNotifier(interp, srcPtr->table, srcPtr->column, TABLE_NOTIFY_COLUMN_CHANGED, TableNotifyProc, (Blt_TableNotifierDeleteProc *)NULL, srcPtr); srcPtr->trace = Blt_Table_CreateColumnTrace(srcPtr->table, srcPtr->column, (TABLE_TRACE_WRITES | TABLE_TRACE_UNSETS | TABLE_TRACE_CREATES), TableTraceProc, (Blt_TableTraceDeleteProc *)NULL, srcPtr); return (DataSource *)srcPtr; error: DestroyDataSource(srcPtr); return NULL; } static Tcl_Obj * TableDataSourcePrintProc(DataSource *dataSrcPtr) { TableDataSource *srcPtr = (TableDataSource *)dataSrcPtr; Tcl_Obj *listObjPtr; const char *name; long index; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); name = Blt_Table_TableName(srcPtr->table); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(name, -1)); index = Blt_Table_ColumnIndex(srcPtr->column); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(index)); return listObjPtr; } static int TableDataSourceGetProc(Tcl_Interp *interp, SourceData *dataSrcPtr, DataSourceResult *resultPtr) { Blt_Table table; float *values; float min, max, logMin; long i, j; table = srcPtr->table; values = Blt_Malloc(sizeof(float) * Blt_Table_NumRows(table)); if (values == NULL) { return TCL_ERROR; } logMin = min = FLT_MAX, max = -FLT_MAX; for (j = 0, i = 1; i <= Blt_Table_NumRows(table); i++) { Blt_TableRow row; Tcl_Obj *objPtr; double value; row = Blt_Table_GetRowByIndex(table, i); objPtr = Blt_Table_GetObj(table, row, col); if (objPtr == NULL) { continue; /* Ignore empty values. */ } if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } values[j] = (float)value; if (values[j] < min) { min = values[j]; } if (values[j] > max) { max = values[j]; } if ((values[j] > 0.0f) && (values[j] < logMin)) { logMin = values[j]; } j++; } resultPtr->min = min; resultPtr->max = max; resultPtr->logMin = logMin; resultPtr->values = values; resultPtr->nValues = j; return TCL_OK; } static void DestroyDataSource(DataSource *dataSrcPtr) { if ((dataSrcPtr->classPtr != NULL) && (dataSrcPtr->classPtr->destroyProc != NULL)) { (*dataSrcPtr->classPtr->destroyProc)(dataSrcPtr); } Blt_Free(dataSrcPtr); } /*ARGSUSED*/ static void FreeDataSourceProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { DataSource *srcPtr = (DataSource *)(widgRec + offset); DestroyDataSource(srcPtr); } /* *--------------------------------------------------------------------------- * * ObjToDataSourceProc -- * * Given a string representation of a data source, converts it into its * equivalent data source. A data source may be a list of numbers, a * vector name, or a two element list of table name and column. * * Results: * The return value is a standard TCL result. The data source is passed * back via the srcPtr. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToDataSourceProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* TCL list of expressions */ char *widgRec, /* Element record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Mesh *meshPtr = clientData; DataSource *srcPtr; DataSource **dataSrcPtrPtr = (DataSource **)(widgRec + offset); Tcl_Obj **objv; int objc; const char *string; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc == 0) { if (*dataSrcPtrPtr != NULL) { DestroyDataSource(*dataSrcPtrPtr); } *dataSrcPtrPtr = NULL; return TCL_OK; } string = Tcl_GetString(objv[0]); if ((objc == 1) && (Blt_VectorExists2(interp, string))) { srcPtr = CreateVectorDataSource(interp, string); } else if ((objc == 2) && (Blt_Table_TableExists(interp, string))) { srcPtr = CreateTableDataSource(interp, string, objv[1]); } else { srcPtr = CreateListDataSource(interp, objc, objv); } srcPtr->clientData = meshPtr; srcPtr->proc = meshPtr->classPtr->configProc; if (*dataSrcPtrPtr != NULL) { DestroyDataSource(*dataSrcPtrPtr); } *dataSrcPtrPtr = srcPtr; return result; } /* *--------------------------------------------------------------------------- * * DataSourceToObjProc -- * * Converts the data source to its equivalent string representation. * The data source may be a table, vector, or list. * * Results: * The string representation of the data source is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * DataSourceToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { DataSource *srcPtr = (DataSource *)(widgRec + offset); return (srcPtr->classPtr->printProc)(srcPtr); } static void DestroyMesh(Mesh *meshPtr) { Graph *graphPtr = meshPtr->graphPtr; if (meshPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&graphPtr->meshTable, meshPtr->hashPtr); } if (meshPtr->link != NULL) { Blt_Chain_DeleteLink(&graphPtr->meshChain, meshPtr->link); } if (meshPtr->classPtr->destroyProc != NULL) { (*meshPtr->classPtr->destroyProc)(meshPtr); } Blt_FreeOptions(meshPtr->classPtr->configSpecs, (char *)meshPtr, graphPtr->display, 0); if (meshPtr->triangles != NULL) { Blt_Free(meshPtr->triangles); } if (meshPtr->edges != NULL) { Blt_Free(meshPtr->edges); } if (meshPtr->points != NULL) { Blt_Free(meshPtr->points); } if (meshPtr->hull != NULL) { Blt_Free(meshPtr->hull); } if (meshPtr->x != NULL) { DestroyDataSource(meshPtr->x); } if (meshPtr->y != NULL) { DestroyDataSource(meshPtr->y); } Blt_Free(meshPtr); return TCL_OK; } static Mesh * GetMeshFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Mesh **meshPtrPtr) { const char *string; Blt_HashEntry *hPtr; string = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->meshTable, string); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find mesh \"", string, "\" in graph \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } *meshPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } static int RegularMeshConfigureProc(Mesh *meshPtr) { Tcl_Interp *interp; RegularMesh *regPtr = (RegularMesh *)meshPtr; MeshPoint *points; int i; float xStep, yStep; int count; DataSourceResult x, y; interp = meshPtr->interp; if ((regPtr->x->classPtr == NULL) || (regPtr->y->classPtr == NULL)) { return TCL_OK; } if ((*regPtr->x->classPtr->getProc)(interp, regPtr->x, &x) != TCL_OK) { return TCL_ERROR; } if (x.nValues != 3) { Tcl_AppendResult(interp, "wrong # of elements for x regular mesh description.", (char *)NULL); return TCL_ERROR; } if ((*regPtr->y->classPtr->getProc)(interp, regPtr->y, &y) != TCL_OK) { return TCL_ERROR; } if (y.nValues != 3) { Tcl_AppendResult(interp, "wrong # of elements for y rectangular mesh description.", (char *)NULL); return TCL_ERROR; } regPtr->xMin = x.values[0]; regPtr->xMax = x.values[1]; regPtr->xNum = (int)x.values[2]; regPtr->yMin = y.values[0]; regPtr->yMax = y.values[1]; regPtr->yNum = (int)y.values[2]; regPtr->xLogMin = x.logMin; regPtr->yLogMin = y.logMin; Blt_Free(x.values); Blt_Free(y.values); if (regPtr->xNum) { Tcl_AppendResult(interp, "# of x-values for rectangular mesh", (char *)NULL); return TCL_ERROR; } if (regPtr->yNum) { Tcl_AppendResult(interp, "# of y-values for rectangular mesh", (char *)NULL); return TCL_ERROR; } if (regPtr->xMin == regPtr->xMax) { return TCL_ERROR; } if (regPtr->yMin == regPtr->yMax) { return TCL_ERROR; } nPoints = x.nValues * y.nValues; points = Blt_Malloc(nPoints * sizeof(MeshPoint)); if (points == NULL) { Tcl_AppendResult(interp, "can't allocate ", Itoa(nPoints), " points", (char *)NULL); return TCL_ERROR; } xStep = (regPtr->xMax - regPtr->xMin) / (float)(regPtr->xNum - 1); yStep = (regPtr->yMax - regPtr->yMin) / (float)(regPtr->yNum - 1); { int count; MeshPoint *p; p = points; count = 0; for (i = 0; i < regPtr->yNum; i++) { float y0; int j; y0 = regPtr->yMin + (yStep * i); for (j = 0; j < regPtr->xNum; j++) { p->x = regPtr->xMin + (xStep * j); p->y = y; p->index = count; count++; p++; } } } if (regPtr->points != NULL) { Blt_Free(regPtr->points); } regPtr->points = points; regPtr->nPoints = nPoints; if (Triangulate(interp, regPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static int IrregularMeshConfigureProc(Mesh *meshPtr) { IrregularMesh *irregPtr = (IrregularMesh *)meshPtr; MeshPoint *points; int i; DataSourceResult x, y; if ((irregPtr->x->classPtr == NULL) || (irregPtr->y->classPtr == NULL)) { return TCL_OK; } if ((*irregPtr->x->classPtr->getProc)(irregPtr->interp, irregPtr->x, &x) != TCL_OK) { return TCL_ERROR; } if (x.nValues < 2) { Tcl_AppendResult(interp, "wrong # of elements for x rectangular mesh description.", (char *)NULL); return TCL_ERROR; } irregPtr->xMin = x.min; irregPtr->xMax = x.max; irregPtr->xLogMin = x.logMin; if ((*irregPtr->y->classPtr->getProc)(irregPtr->interp, irregPtr->y, &y) != TCL_OK) { return TCL_ERROR; } if (y.nValues != 2) { Tcl_AppendResult(interp, "wrong # of elements for y rectangular mesh description.", (char *)NULL); return TCL_ERROR; } irregPtr->yMin = y.min; irregPtr->yMax = y.max; irregPtr->yLogMin = y.logMin; nPoints = x.nValues * y.nValues; points = Blt_Malloc(nPoints * sizeof(MeshPoint)); if (points == NULL) { Tcl_AppendResult(interp, "can't allocate ", Itoa(nPoints), " points", (char *)NULL); return TCL_ERROR; } { int i, count; MeshPoint *p; p = points; count = 0; for (i = 0; i < y.nValues; i++) { int j; for (j = 0; j < x.nValues; j++) { p->x = x.values[j]; p->y = y.values[i]; p->index = count; count++; p++; } } } Blt_Free(x.values); Blt_Free(y.values); if (irregPtr->points != NULL) { Blt_Free(irregPtr->points); } irregPtr->points = points; irregPtr->nPoints = nPoints; irregPtr->xMin = x.min; irregPtr->xLogMin = x.logMin; irregPtr->xMax = x.max; irregPtr->yMin = y.min; irregPtr->yLogMin = y.logMin; irregPtr->yMax = y.max; if (Triangulate(interp, irregPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static int CloudMeshConfigureProc(Mesh *meshPtr) { CloudMesh *cloudPtr = (CloudMesh *)meshPtr; MeshPoint *points; DataSourceResult x, y; int i, nPoints; if ((cloudPtr->x->classPtr == NULL) || (cloudPtr->y->classPtr == NULL)) { return TCL_OK; } if ((*cloudPtr->x->classPtr->getProc)(cloudPtr->interp, cloudPtr->x, &x) != TCL_OK) { return TCL_ERROR; } if (x.nValues < 3) { Tcl_AppendResult(interp, "too few values for x cloud mesh description.", (char *)NULL); return TCL_ERROR; } cloudPtr->xMin = x.min, cloudPtr->xMax = x.max; cloudPtr->logMin = x.logMin; if ((*cloudPtr->y->classPtr->getProc)(cloudPtr->interp, cloudPtr->y, &y) != TCL_OK) { return TCL_ERROR; } if (y.nValues < 3) { Tcl_AppendResult(interp, "too few values for y cloud mesh description.", (char *)NULL); return TCL_ERROR; } cloudPtr->yMin = y.min, cloudPtr->yMax = y.max; cloudPtr->logMin = y.logMin; if (x.nValues != y.nValues) { Tcl_AppendResult(interp, " # of values for x and y do not match.", (char *)NULL); return TCL_ERROR; } nPoints = x.nValues; points = Blt_Malloc(nPoints * sizeof(MeshPoint)); if (points == NULL) { Tcl_AppendResult(interp, "can't allocate ", Itoa(nPoints), " points", (char *)NULL); return TCL_ERROR; } if (cloudPtr->points != NULL) { Blt_Free(cloudPtr->points); } for (i = 0; i < nPoints; i++) { p->x = x.values[i]; p->y = y.values[i]; p->index = i; p++; } Blt_Free(x.values); Blt_Free(y.values); if (cloudPtr->points != NULL) { Blt_Free(cloudPtr->points); } cloudPtr->points = points; cloudPtr->nPoints = nPoints; if (Triangulate(interp, cloudPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static int TriangularMeshConfigureProc(Mesh *meshPtr) { return TCL_OK; } static Mesh * CreateTriangularMesh(const char *name) { TriangularMesh *meshPtr; /* Allocate memory for the new mesh. */ meshPtr = Blt_AssertCalloc(1, sizeof(TriangularMesh)); meshPtr->classPtr = &triangularMeshClass; meshPtr->name = Blt_AssertStrdup(name); return (Mesh *)meshPtr; } static Mesh * CreateRegularMesh(const char *name) { RegularMesh *meshPtr; /* Allocate memory for the new mesh. */ meshPtr = Blt_AssertCalloc(1, sizeof(RegularMesh)); meshPtr->classPtr = &regularMeshClass; meshPtr->name = Blt_AssertStrdup(name); return (Mesh *)meshPtr; } static Mesh * CreateIrregularMesh(const char *name) { IrregularMesh *meshPtr; /* Allocate memory for the new mesh. */ meshPtr = Blt_AssertCalloc(1, sizeof(IrregularMesh)); meshPtr->classPtr = &irregularMeshClass; meshPtr->name = Blt_AssertStrdup(name); return (Mesh *)meshPtr; } static Mesh * CreateCloudMesh(const char *name) { CloudMesh *meshPtr; /* Allocate memory for the new mesh. */ meshPtr = Blt_AssertCalloc(1, sizeof(CloudMesh)); meshPtr->classPtr = &cloudMeshClass; meshPtr->name = Blt_AssertStrdup(name); return (Mesh *)meshPtr; } static int TypeOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Mesh *meshPtr; if (GetMeshFromObj(interp, graphPtr, objv[3], &meshPtr) != TCL_OK) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), meshPtr->classPtr->type, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns a list of marker identifiers in interp->result; * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static int NamesOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->meshTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Mesh *meshPtr; meshPtr = Blt_GetHashValue(hPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(meshPtr->name, -1)); } } else { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->meshTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Marker *markerPtr; int i; markerPtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(meshPtr->name, pattern)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(meshPtr->name, -1)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Mesh *meshPtr; if (GetMeshFromObj(interp, graphPtr, objv[3], &meshPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 0) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, meshPtr->classPtr->configSpecs, (char *)meshPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, meshPtr->classPtr->configSpecs, (char *)meshPtr, objv[4], flags); } bltDataSourceOption.clientData = meshPtr; if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, meshPtr->classPtr->configSpecs, objc - 3, objv + 3, (char *)meshPtr, flags) != TCL_OK) { return TCL_ERROR; } if ((*meshPtr->classPtr->configProc)(meshPtr) != TCL_OK) { return TCL_ERROR; /* Failed to configure element */ } return TCL_OK; } static int CreateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Mesh *meshPtr; Blt_HashEntry *hPtr; char ident[200]; char *name; int i; char c; char *string; int length; /* Scan for "-name" option. We need it for the component name */ name = NULL; for (i = 4; i < objc; i += 2) { string = Tcl_GetStringFromObj(objv[i], &length); if ((length > 1) && (strncmp(string, "-name", length) == 0)) { name = Tcl_GetString(objv[i + 1]); break; } } /* If no name was given for the marker, make up one. */ if (name == NULL) { sprintf_s(ident, 200, "mesh%d", graphPtr->nextMeshId++); name = ident; } else if (name[0] == '-') { Tcl_AppendResult(interp, "name of marker \"", name, "\" can't start with a '-'", (char *)NULL); return TCL_ERROR; } string = Tcl_GetString(objv[3]); c = string[0]; length = strlen(string); if ((c == 't') && (strncmp(string, "triangle", length) == 0)) { meshPtr = CreateTrigangularMesh(name); } else if ((c == 'r') && (strncmp(string, "regular", length) == 0)) { meshPtr = CreateRegularMesh(name); } else if ((c == 'i') && (strncmp(string, "irregular", length) == 0)) { meshPtr = CreateIrregularMesh(name); } else if ((c == 'c') && (strncmp(string, "cloud", length) == 0)) { meshPtr = CreateCloudMesh(name); } else { Tcl_AppendResult(interp, "unknown mesh type \"", string, "\"", (char *)NULL); return TCL_ERROR; } meshPtr->graphPtr = graphPtr; meshPtr->interp = interp; meshPtr->refCount = 1; /* Parse the configuration options. */ if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, name, meshPtr->classPtr->name, meshPtr->classPtr->configSpecs, objc - 4, objv + 4, (char *)meshPtr, 0) != TCL_OK) { DestroyMesh(meshPtr); return TCL_ERROR; } hPtr = Blt_CreateHashEntry(&graphPtr->meshTable, meshPtr->name, &isNew); if (!isNew) { Mesh *oldMeshPtr; oldMeshPtr = Blt_GetHashValue(hPtr); if ((oldMeshPtr->flags & DELETE_PENDING) == 0) { Tcl_AppendResult(graphPtr->interp, "mesh \"", meshPtr->name, "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); DestroyMesh(meshPtr); return TCL_ERROR; } oldMeshPtr->hashPtr = NULL; /* Remove the mesh from the table. */ } Blt_SetHashValue(hPtr, meshPtr); meshPtr->hashPtr = hPtr; if ((meshPtr->classPtr->configProc)(meshPtr) != TCL_OK) { DestroyMesh(meshPtr); return TCL_ERROR; } meshPtr->link = Blt_Chain_Append(graphPtr->meshChain, meshPtr); return TCL_OK; } static int DeleteOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Mesh *meshPtr; if (GetMeshFromObj(interp, graphPtr, objv[i], &meshPtr) != TCL_OK) { return TCL_ERROR; } if (meshPtr->flags & DELETE_PENDING) { Tcl_AppendResult(interp, "can't find mesh \"", Tcl_GetString(objv[i]), "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } meshPtr->flags |= DELETE_PENDING; if (meshPtr->refCount == 0) { DestroyMesh(meshPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * MeshOp -- * * .g mesh create regular -name $name -x {x0 xN n} -y {y0 yN n} * .g mesh create irregular -name $name -x $xvalues -y $yvalues * .g mesh create triangular -name $name -x x -y y -edges $edges \ * -triangles $triangles * .g mesh create cloud -name $name -x x -y y * .g mesh type $name * .g mesh names ?pattern? * .g mesh delete $name * .g mesh configure $name -hide no -linewidth 1 -color black * *--------------------------------------------------------------------------- */ static Blt_OpSpec meshOps[] = { {"cget", 2, CgetOp, 4, 4, "meshName option",}, {"create", 2, CreateOp, 4, 0, "type ?option value?...",}, {"configure", 2, ConfigureOp, 3, 0, "meshName ?option value?...",}, {"delete", 1, DeleteOp, 3, 0, "?meshName?...",}, {"names", 1, NamesOp, 3, 0, "?pattern?...",}, {"type", 2, TypeOp, 4, 4, "meshName",}, }; static int nMeshOps = sizeof(meshOps) / sizeof(Blt_OpSpec); int Blt_MeshOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nMeshOps, meshOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (interp, graphPtr, objc, objv); } void Blt_DestroyMeshes(Graph *graphPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(graphPtr->meshChain); link != NULL; link = next) { Mesh *meshPtr; next = Blt_Chain_NextLink(link); meshPtr = Blt_Chain_GetValue(link); DestroyMesh(meshPtr); } } void Blt_FreeMesh(Mesh *meshPtr) { if (meshPtr != NULL) { meshPtr->refCount--; if ((meshPtr->refCount == 0) && (meshPtr->flags & DELETE_PENDING)) { DestroyMesh(meshPtr); } } } int Blt_GetMeshFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Mesh **meshPtrPtr) { Mesh *meshPtr; if (GetMeshFromObj(interp, graphPtr, objPtr, &meshPtr) != TCL_OK) { return TCL_ERROR; } meshPtr->refCount++; *meshPtrPtr = meshPtr; return TCL_OK; } static void ComputeRanges(int nTriangles, Triangle *triangles, float *values) { Triangle *p, *tend; for (p = triangles, tend = triangles + nTriangles; p < tend; p++) { float za, zb, zc; za = values[points[p->a].index].z; zb = values[points[p->b].index].z; zc = values[points[p->c].index].z; p->min = p->max = za; if (zb < p->min) { p->min = zb; } if (zc < p->min) { p->min = zc; } if (zb > p->max) { p->max = zb; } if (zc > p->max) { p->max = zc; } } } static INLINE float IsLeft(MeshPoint *points, int i, int j, int k) { return (((points[i].x - points[j].x) * (points[k].y - points[j].y)) - ((points[i].y - points[j].y) * (points[k].x - points[j].x))); } /* *--------------------------------------------------------------------------- * * ChainHull2d -- * * Computes the convex hull from the points of the mesh. * * Notes: 1. The array of points is assumed to be sorted. * 2. An array to contain the points is assumed. This is * allocated by the caller. * * Results: * The number of points in the convex hull is returned. The coordinates * of the hull will be written in the given point array. * * Copyright 2001, softSurfer (www.softsurfer.com) * This code may be freely used and modified for any purpose * providing that this copyright notice is included with it. * SoftSurfer makes no warranty for this code, and cannot be held * liable for any real or imagined damage resulting from its use. * Users of this code must verify correctness for their application. * *--------------------------------------------------------------------------- */ #define Push(index) (hull[top] = (index), top++) #define Pop() (top--) static int ChainHull2d(int nPts, MeshPoint *pts, int *hull) { int bot, top, i; int minMin, minMax; int maxMin, maxMax; float xMin, xMax; bot = top = 0; /* Points to next location on stack. */ minMin = 0; /* * Step 1. Get the indices of points with max x-coord and min|max * y-coord . */ xMin = pts[0].x; for (i = 1; i < nPts; i++) { if (pts[i].x != xMin) { break; } } minMax = i - 1; if (minMax == (nPts - 1)) { /* Degenerate case: all x-coords == xMin */ Push(minMin) if (pts[minMax].y != pts[minMin].y) { Push(minMax); /* A nontrivial segment. */ } Push(minMin); return top; } maxMax = nPts - 1; xMax = pts[maxMax].x; for (i = maxMax - 1; i >= 0; i--) { if (pts[i].x != xMax) { break; } } maxMin = i+1; /* * Step 2. Compute the lower hull on the stack. */ Push(minMin); /* push minMin point onto stack */ i = minMax; while (++i <= maxMin) { /* The lower line joins pts[minMin] with pts[maxMin]. */ if ((IsLeft(pts[minMin], pts[maxMin], pts[i]) >= 0.0f) && (i < maxMin)) { continue; /* Ignore pts[i] above or on the lower line */ } while (top > 1) { /* There are at least 2 pts on the stack. */ /* Test if pts[i] is left of the line at the stack top. */ if (IsLeft(pts[hull[top-2]], pts[hull[top-1]], pts[i]) > 0.0f) { break; /* Pts[i] is a new hull vertex. */ } else { Pop(); /* Pop top point off stack */ } } Push(i); /* Push point[i] onto stack. */ } /* * Step 3. Compute the upper hull on the stack above the bottom hull. */ if (maxMax != maxMin) { // if distinct xMax points Push(maxMax); /* Push maxMax point onto stack. */ } bot = top - 1; /* The bottom point of the upper hull stack. */ i = maxMin; while (--i >= minMax) { /* The upper line joins pts[maxMax] with pts[minMax]. */ if ((IsLeft(pts[maxMax], pts[minMax], pts[i]) >= 0) && (i > minMax)) { continue; /* Ignore pts[i] below or on the upper * line. */ } while (top >= bot) { /* There are at least 2 points on the upper stack. */ /* Test if points[i] is left of the line at the stack top. */ if (Isleft(pts[hull[top-2]], pts[hull[top-1]], pts[i]) > 0) { break; /* pts[i] is a new hull vertex. */ } else { Pop(); /* Pop top point off stack. */ } } Push(i); /* Push pts[i] onto stack. */ } if (minMax != minMin) { Push(minMin); /* Push joining endpoint onto stack. */ } return top; } static int ConvexHull(Tcl_Interp *interp, Mesh *meshPtr) { int *hull; int n; /* Allocate worst-case storage initially for the hull. */ hull = Blt_Malloc(meshPtr->nPoints * sizeof(int)); if (hull == NULL) { Tcl_AppendResult(interp, "can't allocate memory for convex hull ", (char *)NULL); return TCL_ERROR; } /* Compute the convex hull. */ n = ChainHull2d(meshPtr->nPoints, meshPtr->points, hull); /* Resize the hull array to the actual # of boundary points. */ if (n < meshPtr->nPoints) { hull = Blt_Realloc(hull, n * sizeof(int)); if (hull == NULL) { Tcl_AppendResult(interp, "can't reallocate memory for convex hull ", (char *)NULL); return TCL_ERROR; } } if (meshPtr->hull != NULL) { Blt_Free(meshPtr->hull); } meshPtr->hull = hull; meshPtr->nHullPts = n; return TCL_OK; } static int ComparePoints(const void *a, const void *b) { const MeshPoint *s1 = a; const MeshPoint *s2 = b; if (s1->y < s2->y) { return -1; } if (s1->y > s2->y) { return 1; } if (s1->x < s2->x) { return -1; } if (s1->x > s2->x) { return 1; } return 0; } static void Triangulate(Tcl_Interp *interp, Mesh *meshPtr) { Triangle *triangles; int nTriangles; /* Sort the points in the mesh. This is useful for both computing the * convex hull and triangulating the mesh. */ qsort(meshPtr->points, meshPtr->nPoints, sizeof(MeshPoint), ComparePoints); /* Compute the convex hull first, this will provide an estimate for the * boundary points and therefore the number of triangles and edges. */ if (ConvexHull(interp, meshPtr) != TCL_OK) { return TCL_ERROR; } /* Determine the number of triangles and edges. */ meshPtr->nTriangles = 2 * meshPtr->nPoints - 2 - meshPtr->nHullPts; meshPtr->nEdges = 3 * meshPtr->nPoints - 3 - meshPtr->nHullPts; triangles = Blt_Malloc(meshPtr->nTriangles * sizeof(Triangle)); if (triangles == NULL) { Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(meshPtr->nTriangles), " triplets", (char *)NULL); return TCL_ERROR; } /* * Mesh the points to get triangles. */ nTriangles = Blt_Triangulate(meshPtr->nPoints, meshPtr->points, TRUE, triangles); if (meshPtr->triangles != NULL) { Blt_Free(meshPtr->triangles); } meshPtr->nTriangles = nTriangles; meshPtr->triangles = triangles; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltArrayObj.c�����������������������������������������������������������������0000644�0001750�0001750�00000015576�11462120062�015422� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltArrayObj.c -- * * This file implements an array-based Tcl_Obj. * * Copyright (c) 2000 George A. Howlett * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltArrayObj.h" #include "bltHash.h" static Tcl_DupInternalRepProc DupArrayInternalRep; static Tcl_FreeInternalRepProc FreeArrayInternalRep; static Tcl_UpdateStringProc UpdateStringOfArray; static Tcl_SetFromAnyProc SetArrayFromAny; static Tcl_ObjType arrayObjType = { (char *)"array", FreeArrayInternalRep, /* Called when an object is freed. */ DupArrayInternalRep, /* Copies an internal representation from one * object to another. */ UpdateStringOfArray, /* Creates string representation from an * object's internal representation. */ SetArrayFromAny, /* Creates valid internal representation from * an object's string representation. */ }; static int SetArrayFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { Blt_HashTable *tablePtr; Tcl_ObjType *oldTypePtr = objPtr->typePtr; const char **argv, *string; int argc, i; if (objPtr->typePtr == &arrayObjType) { return TCL_OK; } /* Get the string representation. Make it up-to-date if necessary. */ string = Tcl_GetString(objPtr); if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { return TCL_ERROR; } tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_STRING_KEYS); for (i = 0; i < argc; i += 2) { Blt_HashEntry *hPtr; Tcl_Obj *elemObjPtr; int isNew; hPtr = Blt_CreateHashEntry(tablePtr, argv[i], &isNew); elemObjPtr = Tcl_NewStringObj(argv[i + 1], -1); Blt_SetHashValue(hPtr, elemObjPtr); /* Make sure we increment the reference count */ Tcl_IncrRefCount(elemObjPtr); } if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { oldTypePtr->freeIntRepProc(objPtr); } objPtr->internalRep.otherValuePtr = (VOID *)tablePtr; objPtr->typePtr = &arrayObjType; Blt_Free(argv); return TCL_OK; } static void DupArrayInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *destPtr) /* Object with internal rep to set. */ { Blt_HashEntry *hp; Blt_HashSearch iter; Blt_HashTable *srcTablePtr, *destTablePtr; srcTablePtr = (Blt_HashTable *)srcPtr->internalRep.otherValuePtr; destTablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(destTablePtr, BLT_STRING_KEYS); for (hp = Blt_FirstHashEntry(srcTablePtr, &iter); hp != NULL; hp = Blt_NextHashEntry(&iter)) { Tcl_Obj *valueObjPtr; const char *key; int isNew; key = Blt_GetHashKey(srcTablePtr, hp); Blt_CreateHashEntry(destTablePtr, key, &isNew); valueObjPtr = Blt_GetHashValue(hp); Blt_SetHashValue(hp, valueObjPtr); /* Make sure we increment the reference count now that both array * objects are using the same elements. */ Tcl_IncrRefCount(valueObjPtr); } Tcl_InvalidateStringRep(destPtr); destPtr->internalRep.otherValuePtr = (VOID *)destTablePtr; destPtr->typePtr = &arrayObjType; } static void UpdateStringOfArray(Tcl_Obj *objPtr) /* Array object w/ string rep to update. */ { Tcl_DString dString; Blt_HashTable *tablePtr; Blt_HashEntry *hp; Blt_HashSearch iter; tablePtr = (Blt_HashTable *)objPtr->internalRep.otherValuePtr; Tcl_DStringInit(&dString); for (hp = Blt_FirstHashEntry(tablePtr, &iter); hp != NULL; hp = Blt_NextHashEntry(&iter)) { Tcl_Obj *elemObjPtr; elemObjPtr = Blt_GetHashValue(hp); Tcl_DStringAppendElement(&dString, Blt_GetHashKey(tablePtr, hp)); Tcl_DStringAppendElement(&dString, Tcl_GetString(elemObjPtr)); } objPtr->bytes = Blt_AssertStrdup(Tcl_DStringValue(&dString)); objPtr->length = strlen(Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); } static void FreeArrayInternalRep(Tcl_Obj *objPtr) /* Array object to release. */ { Blt_HashEntry *hp; Blt_HashSearch iter; Blt_HashTable *tablePtr; Tcl_InvalidateStringRep(objPtr); tablePtr = (Blt_HashTable *)objPtr->internalRep.otherValuePtr; for (hp = Blt_FirstHashEntry(tablePtr, &iter); hp != NULL; hp = Blt_NextHashEntry(&iter)) { Tcl_Obj *elemObjPtr; elemObjPtr = Blt_GetHashValue(hp); Tcl_DecrRefCount(elemObjPtr); } Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } int Blt_GetArrayFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_HashTable **tablePtrPtr) { if (objPtr->typePtr == &arrayObjType) { *tablePtrPtr = (Blt_HashTable *)objPtr->internalRep.otherValuePtr; return TCL_OK; } if (SetArrayFromAny(interp, objPtr) == TCL_OK) { *tablePtrPtr = (Blt_HashTable *)objPtr->internalRep.otherValuePtr; return TCL_OK; } return TCL_ERROR; } Tcl_Obj * Blt_NewArrayObj(int objc, Tcl_Obj **objv) { Blt_HashTable *tablePtr; Tcl_Obj *arrayObjPtr; int i; tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_STRING_KEYS); for (i = 0; i < objc; i += 2) { Blt_HashEntry *hp; Tcl_Obj *objPtr; int isNew; hp = Blt_CreateHashEntry(tablePtr, Tcl_GetString(objv[i]), &isNew); objPtr = ((i + 1) == objc) ? Tcl_NewStringObj("", -1) : objv[i+1]; Tcl_IncrRefCount(objPtr); if (!isNew) { Tcl_Obj *oldObjPtr; oldObjPtr = Blt_GetHashValue(hp); Tcl_DecrRefCount(oldObjPtr); } Blt_SetHashValue(hp, objPtr); } arrayObjPtr = Tcl_NewObj(); /* * Reference counts for entry objects are initialized to 0. They are * incremented as they are inserted into the tree via the Blt_Tree_SetValue * call. */ arrayObjPtr->refCount = 0; arrayObjPtr->internalRep.otherValuePtr = (VOID *)tablePtr; arrayObjPtr->bytes = NULL; arrayObjPtr->length = 0; arrayObjPtr->typePtr = &arrayObjType; return arrayObjPtr; } int Blt_IsArrayObj(Tcl_Obj *objPtr) { return (objPtr->typePtr == &arrayObjType); } /*ARGSUSED*/ void Blt_RegisterArrayObj(void) { Tcl_RegisterObjType(&arrayObjType); } ����������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPsAfm.c��������������������������������������������������������������������0000644�0001750�0001750�00000141773�11462120062�014716� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPsAfm.c -- * * This module implements an Adobe Font Metric File parser for the purpose of * determining font metrics when generating PostScript. * * Copyright 2009 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include <ctype.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include <bltInt.h> #include <bltHash.h> #include "bltPs.h" #include "bltOp.h" #include "bltText.h" #include "bltFont.h" #define AFM_MAXSTATES 50 #define AFM_MAXLINE 512 #define FM(x) Blt_Offset(AdobeFontMetrics, x) #define CM(x) Blt_Offset(CharMetrics, x) #define FTOA(x) Blt_Dtoa(interp, (double)x) typedef struct { const char *name; short int code; } Symbol; static Symbol isoLatin1Symbols[] = { { "A", 65 }, { "AE", 198 }, { "Aacute", 193 }, { "Acircumflex", 194 }, { "Adieresis", 196 }, { "Agrave", 192 }, { "Aring", 197 }, { "Atilde", 195 }, { "B", 66 }, { "C", 67 }, { "Ccedilla", 199 }, { "D", 68 }, { "E", 69 }, { "Eacute", 201 }, { "Ecircumflex", 202 }, { "Edieresis", 203 }, { "Egrave", 200 }, { "Eth", 208 }, { "F", 70 }, { "G", 71 }, { "H", 72 }, { "I", 73 }, { "Iacute", 205 }, { "Icircumflex", 206 }, { "Idieresis", 207 }, { "Igrave", 204 }, { "J", 74 }, { "K", 75 }, { "L", 76 }, { "M", 77 }, { "N", 78 }, { "Ntilde", 209 }, { "O", 79 }, { "Oacute", 211 }, { "Ocircumflex", 212 }, { "Odieresis", 214 }, { "Ograve", 210 }, { "Oslash", 216 }, { "Otilde", 213 }, { "P", 80 }, { "Q", 81 }, { "R", 82 }, { "S", 83 }, { "T", 84 }, { "Thorn", 222 }, { "U", 85 }, { "Uacute", 218 }, { "Ucircumflex", 219 }, { "Udieresis", 220 }, { "Ugrave", 217 }, { "V", 86 }, { "W", 87 }, { "X", 88 }, { "Y", 89 }, { "Yacute", 221 }, { "Z", 90 }, { "a", 97 }, { "aacute", 225 }, { "acircumflex", 226 }, { "acute", 180 }, { "adieresis", 228 }, { "ae", 230 }, { "agrave", 224 }, { "ampersand", 38 }, { "aring", 229 }, { "asciicircum", 94 }, { "asciitilde", 126 }, { "asterisk", 42 }, { "at", 64 }, { "atilde", 227 }, { "b", 98 }, { "backslash", 92 }, { "bar", 124 }, { "braceleft", 123 }, { "braceright", 125 }, { "bracketleft", 91 }, { "bracketright", 93 }, { "brokenbar", 166 }, { "florin", 166 }, { "c", 99 }, { "ccedilla", 231 }, { "cedilla", 184 }, { "cent", 162 }, { "colon", 58 }, { "comma", 44 }, { "controlACK", 6 }, { "controlBEL", 7 }, { "controlBS", 8 }, { "controlCAN", 24 }, { "controlCR", 13 }, { "controlDC1", 17 }, { "controlDC2", 18 }, { "controlDC3", 19 }, { "controlDC4", 20 }, { "controlDEL", 127 }, { "controlDLE", 16 }, { "controlEM", 25 }, { "controlENQ", 5 }, { "controlEOT", 4 }, { "controlESC", 27 }, { "controlETB", 23 }, { "controlETX", 3 }, { "controlFF", 12 }, { "controlFS", 28 }, { "controlGS", 29 }, { "controlHT", 9 }, { "controlLF", 10 }, { "controlNAK", 21 }, { "controlRS", 30 }, { "controlSI", 15 }, { "controlSO", 14 }, { "controlSOT", 2 }, { "controlSTX", 1 }, { "controlSUB", 26 }, { "controlSYN", 22 }, { "controlUS", 31 }, { "controlVT", 11 }, { "copyright", 169 }, { "currency", 164 }, { "fraction", 164 }, { "d", 100 }, { "degree", 176 }, { "dieresis", 168 }, { "divide", 247 }, { "dollar", 36 }, { "e", 101 }, { "eacute", 233 }, { "ecircumflex", 234 }, { "edieresis", 235 }, { "egrave", 232 }, { "eight", 56 }, { "equal", 61 }, { "eth", 240 }, { "exclam", 33 }, { "exclamdown", 161 }, { "f", 102 }, { "five", 53 }, { "four", 52 }, { "g", 103 }, { "germandbls", 223 }, { "grave", 96 }, { "quoteleft", 96 }, { "greater", 62 }, { "guillemotleft", 171 }, { "guillemotright", 187 }, { "h", 104 }, { "hyphen", 45 }, { "i", 105 }, { "iacute", 237 }, { "icircumflex", 238 }, { "idieresis", 239 }, { "igrave", 236 }, { "j", 106 }, { "k", 107 }, { "l", 108 }, { "less", 60 }, { "logicalnot", 172 }, { "m", 109 }, { "macron", 175 }, { "middot", 183 }, { "mu", 181 }, { "mu1", 181 }, { "multiply", 215 }, { "n", 110 }, { "nbspace", 160 }, { "nine", 57 }, { "nonbreakingspace", 160 }, { "ntilde", 241 }, { "numbersign", 35 }, { "o", 111 }, { "oacute", 243 }, { "ocircumflex", 244 }, { "odieresis", 246 }, { "ograve", 242 }, { "one", 49 }, { "onehalf", 189 }, { "onequarter", 188 }, { "onesuperior", 185 }, { "ordfeminine", 170 }, { "ordmasculine", 186 }, { "oslash", 248 }, { "otilde", 245 }, { "overscore", 175 }, { "p", 112 }, { "paragraph", 182 }, { "parenleft", 40 }, { "parenright", 41 }, { "percent", 37 }, { "period", 46 }, { "periodcentered", 183 }, { "plus", 43 }, { "plusminus", 177 }, { "q", 113 }, { "question", 63 }, { "questiondown", 191 }, { "quotedbl", 34 }, { "quotesingle", 39 }, { "quoteright", 39 }, { "r", 114 }, { "registered", 174 }, { "s", 115 }, { "section", 167 }, { "semicolon", 59 }, { "seven", 55 }, { "sfthyphen", 173 }, { "six", 54 }, { "slash", 47 }, { "softhyphen", 173 }, { "space", 32 }, { "spacehackarabic", 32 }, { "sterling", 163 }, { "t", 116 }, { "thorn", 254 }, { "three", 51 }, { "threequarters", 190 }, { "threesuperior", 179 }, { "two", 50 }, { "twosuperior", 178 }, { "u", 117 }, { "uacute", 250 }, { "ucircumflex", 251 }, { "udieresis", 252 }, { "ugrave", 249 }, { "underscore", 95 }, { "v", 118 }, { "verticalbar", 124 }, { "w", 119 }, { "x", 120 }, { "y", 121 }, { "yacute", 253 }, { "ydieresis", 255 }, { "yen", 165 }, { "z", 122 }, { "zero", 48 }, { NULL, -1 } }; typedef struct _Parser Parser; typedef int (ParseProc) (Parser *parserPtr, char *record, int offset); typedef struct { const char *key; unsigned int nArgs; ParseProc *proc; size_t offset; } ParserSpec; typedef struct { float llx, lly, urx, ury; } CharBBox; typedef struct { float x, y; } Point; typedef struct { short int first, second; } LigatureKey; typedef struct { const char *successor; const char *ligature; short int index; } Ligature; typedef struct { CharBBox bbox; int index; const char *name; int hasLigature; int hasKernPair; Point w; Point vVector; } CharMetrics; typedef struct { float x, y; short int first, second; } KernPairs; typedef struct { short int first, second; } KernPairsKey; typedef struct { float degree; float minPointSize, maxPointSize; float minKern, maxKern; } TrackKern; typedef struct { const char *afmVersion; const char *familyName; const char *fontName; const char *fullName; const char *weight; const char *comment; const char *copyright; const char *notice; float italicAngle; CharBBox fontBBox; float underlinePosition; float underlineThickness; const char *characterSet; int characters; const char *version; const char *encodingScheme; float capHeight; float xHeight; float ascender, descender; int metricSets; Point charWidth; int escChar; int isFixedPitch; int isBaseFont; int isCIDFont; int isFixedV; int mappingScheme; int nCharMetrics; int nComposites; int nDirection; int nKernPairs; int nTrackKern; float stdHW, stdVW; Point vVector; TrackKern *trackKern; KernPairs *kernPairs; CharMetrics metrics[256]; Blt_HashTable metricsTable; Blt_HashTable kernPairsTable; Blt_HashTable ligatureTable; Blt_HashTable symbolTable; #ifdef notdef Composites *composites; Blt_HashTable compositeTable; #endif int refCount; Blt_HashEntry *hashPtr; float pointSize; /* Current point size of font. */ } AdobeFontMetrics; struct _Parser { Tcl_Channel channel; /* Channel to AdobeFontMetrics file. */ AdobeFontMetrics *afmPtr; jmp_buf jmpbuf; Tcl_DString errors; /* Contains error message. */ int nErrors; int argc; /* # arguments (word) of last line. */ const char **argv; /* Split of last line. */ Tcl_DString lastLine; /* Contains last line read from file. */ int lineNumber; }; static Blt_HashTable fontTable; static int initialized; static int ParseLine(Parser *parserPtr, ParserSpec *specs, int nSpecs, ClientData clientData); static INLINE int Points(AdobeFontMetrics *afmPtr, double x) { return (int)round((afmPtr->pointSize * x) / 1000.0); } /*ARGSUSED*/ static void ParserError TCL_VARARGS_DEF(Parser *, arg1) { Parser *parserPtr; const char *fmt; char string[BUFSIZ+4]; int length; va_list args; parserPtr = TCL_VARARGS_START(Parser *, arg1, args); fmt = va_arg(args, char *); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&parserPtr->errors, "line ", 5); Tcl_DStringAppend(&parserPtr->errors, Blt_Itoa(parserPtr->lineNumber), -1); Tcl_DStringAppend(&parserPtr->errors, ": ", 2); Tcl_DStringAppend(&parserPtr->errors, string, -1); Tcl_DStringAppend(&parserPtr->errors, "\n", -1); va_end(args); longjmp(parserPtr->jmpbuf, 0); } static int GetNumber(Parser *parserPtr, const char *string, float *valuePtr) { char *end; double d; errno = 0; d = strtod(string, &end); /* INTL: Tcl source. */ if (end == string) { badDouble: ParserError(parserPtr, "expected floating-point number but got \"%s\"", string); } if (errno != 0 && (d == HUGE_VAL || d == -HUGE_VAL || d == 0)) { ParserError(parserPtr, "number \"%s\" is too big to represent", string); } while ((*end != 0) && isspace(UCHAR(*end))) { /* INTL: ISO space. */ end++; } if (*end != 0) { goto badDouble; } *valuePtr = (float)d; return TCL_OK; } static int GetHexNumber(Parser *parserPtr, const char *string, int *valuePtr) { char *p; int value; if (*string == '<') { string++; } value = strtoul(string, &p, 8); if ((p == string) || (*p != '>')) { ParserError(parserPtr, "expected hex number but got \"%s\"", string); } *valuePtr = value; return TCL_OK; } static int GetLine(Parser *parserPtr) { Tcl_DStringSetLength(&parserPtr->lastLine, 0); while (!Tcl_Eof(parserPtr->channel)) { const char *p; int code; code = Tcl_Gets(parserPtr->channel, &parserPtr->lastLine); if (code < 0) { if (Tcl_Eof(parserPtr->channel)) { return TCL_RETURN; } ParserError(parserPtr, "error reading channel: %s\n", strerror(errno)); } parserPtr->lineNumber++; for (p = Tcl_DStringValue(&parserPtr->lastLine); isspace(*p); p++) { /* skip blanks */ } if (*p == '\0') { continue; } return TCL_OK; } return TCL_RETURN; } static void SplitLine(Parser *parserPtr, const char *line) { const char *p; int count; size_t strSize, addrSize; if (parserPtr->argv != NULL) { Blt_Free((char *)parserPtr->argv); parserPtr->argv = NULL; parserPtr->argc = 0; } /* Count the # of arguments to determine what size array to allocate. */ count = 0; p = line; while (*p != '\0') { while (isspace(*p)) p++; /* Skip whitespace. */ if (*p == '\0') { break; } while (!isspace(*p) && (*p != '\0')) p++; /* Skip the word itself. */ count++; } if (count == 0) { return; /* No arguments. */ } addrSize = sizeof(char **) * (count + 1); strSize = p - line + 1; { char *buffer, *p; const char **array; buffer = Blt_Malloc(addrSize + strSize); assert(buffer); p = buffer + addrSize; strcpy(p, line); /* Copy the string into the buffer. */ array = (const char **)buffer; count = 0; while (*p != '\0') { while (isspace(*p)) { *p++ = '\0'; /* Convert whitespace to NULs. */ } if (*p == '\0') { break; } array[count] = p; while (!isspace(*p) && (*p != '\0')) p++; count++; } array[count] = NULL; parserPtr->argv = array; parserPtr->argc = count; } } static int SplitNextLine(Parser *parserPtr) { int result; if (parserPtr->argv != NULL) { Blt_Free((char *)parserPtr->argv); parserPtr->argv = NULL; parserPtr->argc = 0; } result = GetLine(parserPtr); if (result == TCL_OK) { SplitLine(parserPtr, Tcl_DStringValue(&parserPtr->lastLine)); return TCL_OK; } return result; } /* *--------------------------------------------------------------------------- * * LookupKeyword -- * *--------------------------------------------------------------------------- */ static ParserSpec * LookupKeyword(ParserSpec *specs, int nSpecs, const char *string) { char c; int high, low; low = 0; high = nSpecs - 1; c = string[0]; while (low <= high) { ParserSpec *specPtr; int compare; int median; median = (low + high) >> 1; specPtr = specs + median; /* Test the first character */ compare = c - specPtr->key[0]; if (compare == 0) { /* Now test the entire string */ compare = strcmp(string, specPtr->key); } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return specPtr; } } return NULL; /* Can't find operation */ } static int ParseLine(Parser *parserPtr, ParserSpec *specs, int nSpecs, ClientData clientData) { ParserSpec *specPtr; specPtr = LookupKeyword(specs, nSpecs, parserPtr->argv[0]); if (specPtr == NULL) { ParserError(parserPtr, "unknown keyword \"%s\"", parserPtr->argv[0]); } if ((specPtr->nArgs > 0) && (specPtr->nArgs != parserPtr->argc)) { ParserError(parserPtr, "wrong # arguments for \"%s\"", specPtr->key); } if (specPtr->proc == NULL) { return TCL_OK; } return (*specPtr->proc)(parserPtr, clientData, specPtr->offset); } static int ParseEndSection(Parser *parserPtr, char *record, int offset) { return TCL_CONTINUE; /* Indicates end of section. */ } static long LookupSymbol(AdobeFontMetrics *afmPtr, const char *symbol) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&afmPtr->symbolTable, symbol); if (hPtr != NULL) { return (long)Blt_GetHashValue(hPtr); } /*fprintf(stderr, "unknown symbol \"%s\"\n", symbol);*/ return -1; } static void InitSymbolTable(AdobeFontMetrics *afmPtr) { Symbol *symPtr; Blt_InitHashTable(&afmPtr->symbolTable, BLT_STRING_KEYS); for (symPtr = isoLatin1Symbols; symPtr->name != NULL; symPtr++) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&afmPtr->symbolTable, symPtr->name, &isNew); Blt_SetHashValue(hPtr, (ClientData)(long)symPtr->code); } } static void UpdateSymbol(AdobeFontMetrics *afmPtr, long code, const char *symbol) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&afmPtr->symbolTable, symbol, &isNew); #ifdef notdef if (!isNew) { long oldCode; oldCode = (long)Blt_GetHashValue(hPtr); if (code != oldCode) { fprintf(stderr, "rewriting symbol %s with %d (was %ld)\n", symbol, code, oldCode); } } #endif Blt_SetHashValue(hPtr, (ClientData)code); } static void BuildKernPairsTable(AdobeFontMetrics *afmPtr) { KernPairs *kp, *kend; Blt_InitHashTable(&afmPtr->kernPairsTable, sizeof(KernPairsKey) / sizeof(int)); for (kp = afmPtr->kernPairs, kend = kp + afmPtr->nKernPairs; kp < kend; kp++) { KernPairsKey key; Blt_HashEntry *hPtr; int isNew; memset(&key, 0, sizeof(key)); key.first = kp->first; key.second = kp->second; hPtr = Blt_CreateHashEntry(&afmPtr->kernPairsTable, (char *)&key, &isNew); Blt_SetHashValue(hPtr, (ClientData)kp); } } static KernPairs * GetKernPairs(AdobeFontMetrics *afmPtr, int c1, int c2) { KernPairsKey key; Blt_HashEntry *hPtr; key.first = c1; key.second = c2; hPtr = Blt_FindHashEntry(&afmPtr->kernPairsTable, (char *)&key); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } static KernPairs * GetLigature(AdobeFontMetrics *afmPtr, int c1, int c2) { KernPairsKey key; Blt_HashEntry *hPtr; key.first = c1; key.second = c2; hPtr = Blt_FindHashEntry(&afmPtr->kernPairsTable, (char *)&key); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } static Ligature * NewLigature(Parser *parserPtr, int first, int second) { Blt_HashEntry *hPtr; Ligature *ligPtr; int isNew; LigatureKey key; key.first = first; key.second = second; ligPtr = Blt_Calloc(1, sizeof(Ligature)); assert(ligPtr); hPtr = Blt_CreateHashEntry(&parserPtr->afmPtr->ligatureTable, (char *)&key, &isNew); Tcl_SetHashValue(hPtr, ligPtr); return ligPtr; } static Parser * NewParser(AdobeFontMetrics *afmPtr, const char *fileName) { Parser *parserPtr; Tcl_Channel channel; channel = Tcl_OpenFileChannel(NULL, fileName, "r", 0); if (channel == NULL) { fprintf(stderr, "can't open %s\n", fileName); return NULL; } if ((Tcl_SetChannelOption(NULL, channel, "-translation","auto")!=TCL_OK)|| (Tcl_SetChannelOption(NULL, channel, "-eofchar", "\x1a") != TCL_OK)) { return NULL; } parserPtr = Blt_Calloc(1, sizeof(Parser)); assert(parserPtr); parserPtr->channel = channel; parserPtr->afmPtr = afmPtr; InitSymbolTable(afmPtr); Tcl_DStringInit(&parserPtr->errors); Tcl_DStringAppend(&parserPtr->errors, "error reading \"", -1); Tcl_DStringAppend(&parserPtr->errors, fileName, -1); Tcl_DStringAppend(&parserPtr->errors, "\": ", -1); Tcl_DStringInit(&parserPtr->lastLine); return parserPtr; } static void DestroyParser(Parser *parserPtr) { if (parserPtr->argv != NULL) { Blt_Free((char *)parserPtr->argv); } Tcl_Close(NULL, parserPtr->channel); Tcl_DStringFree(&parserPtr->errors); Tcl_DStringFree(&parserPtr->lastLine); Blt_Free(parserPtr); } static void DestroyAdobeFontMetrics(AdobeFontMetrics *afmPtr) { if (afmPtr->afmVersion != NULL) { Blt_Free((char *)afmPtr->afmVersion); } if (afmPtr->characterSet != NULL) { Blt_Free((char *)afmPtr->characterSet); } if (afmPtr->comment != NULL) { Blt_Free((char *)afmPtr->comment); } if (afmPtr->copyright != NULL) { Blt_Free((char *)afmPtr->copyright); } if (afmPtr->encodingScheme != NULL) { Blt_Free((char *)afmPtr->encodingScheme); } if (afmPtr->familyName != NULL) { Blt_Free((char *)afmPtr->familyName); } if (afmPtr->fontName != NULL) { Blt_Free((char *)afmPtr->fontName); } if (afmPtr->fullName != NULL) { Blt_Free((char *)afmPtr->fullName); } if (afmPtr->notice != NULL) { Blt_Free((char *)afmPtr->notice); } if (afmPtr->version != NULL) { Blt_Free((char *)afmPtr->version); } if (afmPtr->weight != NULL) { Blt_Free((char *)afmPtr->weight); } if (afmPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&fontTable, afmPtr->hashPtr); } Blt_DeleteHashTable(&afmPtr->kernPairsTable); Blt_DeleteHashTable(&afmPtr->metricsTable); Blt_DeleteHashTable(&afmPtr->symbolTable); Blt_DeleteHashTable(&afmPtr->ligatureTable); if (afmPtr->kernPairs != NULL) { Blt_Free(afmPtr->kernPairs); } if (afmPtr->trackKern != NULL) { Blt_Free(afmPtr->trackKern); } Blt_Free((char *)afmPtr); } static int ParseInt(Parser *parserPtr, char *record, int offset) { int *valuePtr = (int *)(record + offset); if (Tcl_GetInt(NULL, parserPtr->argv[1], valuePtr) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer.", parserPtr->argv[1]); } return TCL_OK; } static int ParseHex(Parser *parserPtr, char *record, int offset) { int *valuePtr = (int *)(record + offset); return GetHexNumber(parserPtr, parserPtr->argv[1], valuePtr); } static int ParseBoolean(Parser *parserPtr, char *record, int offset) { int *valuePtr = (int *)(record + offset); if (Tcl_GetBoolean(NULL, parserPtr->argv[1], valuePtr) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to boolean.", parserPtr->argv[1]); } return TCL_OK; } static int ParseNumber(Parser *parserPtr, char *record, int offset) { float *valuePtr = (float *)(record + offset); return GetNumber(parserPtr, parserPtr->argv[1], valuePtr); } static int ParsePoint(Parser *parserPtr, char *record, int offset) { Point *pointPtr = (Point *)(record + offset); if ((GetNumber(parserPtr, parserPtr->argv[1], &pointPtr->x) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[2], &pointPtr->y) != TCL_OK)) { return TCL_ERROR; } return TCL_OK; } static int ParseBBox(Parser *parserPtr, char *record, int offset) { CharBBox *bboxPtr = (CharBBox *)(record + offset); if ((GetNumber(parserPtr, parserPtr->argv[1], &bboxPtr->llx) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[2], &bboxPtr->lly) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[3], &bboxPtr->urx) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[4], &bboxPtr->ury) != TCL_OK)) { return TCL_ERROR; } return TCL_OK; } static int ParseString(Parser *parserPtr, char *record, int offset) { char **args = (char **)(record + offset); if (*args != NULL) { Blt_Free(*args); *args = NULL; } *args = Tcl_Merge(parserPtr->argc - 1 , parserPtr->argv + 1); if (*args == NULL) { ParserError(parserPtr, "can't merge \"%s\" string.", parserPtr->argv[0]); } return TCL_OK; } static int ParseName(Parser *parserPtr, char *record, int offset) { const char **valuePtr = (const char **)(record + offset); if (*valuePtr != NULL) { Blt_Free((char *)*valuePtr); } *valuePtr = Blt_Strdup(parserPtr->argv[1]); return TCL_OK; } static int ParseStartComposites(Parser *parserPtr, char *record, int offset) { int *valuePtr = (int *)(record + offset); int n; assert(*valuePtr == 0); if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer", parserPtr->argv[1]); } n++; *valuePtr = n; for (;;) { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartComposites"); } if (strcmp(parserPtr->argv[0], "EndComposites") == 0) { return TCL_OK; } } /*notreached*/ return TCL_ERROR; } static ParserSpec directionSpecs[] = { { "CharWidth", 3, ParsePoint, FM(charWidth) }, { "EndDirection", 1, ParseEndSection, 0 }, { "IsFixedPitch", 2, ParseBoolean, FM(isFixedPitch) }, { "ItalicAngle", 2, ParseNumber, FM(italicAngle) }, { "UnderlinePosition", 2, ParseNumber, FM(underlinePosition) }, { "UnderlineThickness",2, ParseNumber, FM(underlineThickness) } }; static int nDirectionSpecs = sizeof(directionSpecs) / sizeof(ParserSpec); static int ParseStartDirection(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; int *valuePtr = (int *)(record + offset); int n; int result; assert(*valuePtr == 0); if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer.", parserPtr->argv[1]); } do { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartDirection"); } result = ParseLine(parserPtr, directionSpecs, nDirectionSpecs, afmPtr); } while (result == TCL_OK); if (result == TCL_CONTINUE) { return TCL_OK; /* Found EndKernPairs */ } return TCL_ERROR; } static int ParseTrackKern(Parser *parserPtr, char *record, int offset) { TrackKern *tp = (TrackKern *)(record + offset); if ((GetNumber(parserPtr, parserPtr->argv[1], &tp->degree) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[2], &tp->minPointSize)!=TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[3], &tp->minKern) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[4], &tp->maxPointSize)!=TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[5], &tp->maxKern) != TCL_OK)) { return TCL_ERROR; } return TCL_OK; } static ParserSpec trackKernSpecs[] = { { "EndTrackKern", 1, ParseEndSection, 0 }, { "TrackKern", 6, ParseTrackKern, 0 }, }; static int nTrackKernSpecs = sizeof(trackKernSpecs) / sizeof(ParserSpec); static int ParseStartTrackKern(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; TrackKern *tp; int *valuePtr = (int *)(record + offset); int n; int result; assert(*valuePtr == 0); if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer.", parserPtr->argv[1]); } n++; *valuePtr = n; afmPtr->trackKern = Blt_Calloc(n, sizeof(TrackKern)); assert(afmPtr->trackKern); tp = afmPtr->trackKern; do { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartTrackKern"); } result = ParseLine(parserPtr, trackKernSpecs, nTrackKernSpecs, tp); tp++; } while (result == TCL_OK); if (result == TCL_CONTINUE) { assert((tp - afmPtr->trackKern) == n); return TCL_OK; /* Found EndTrackKern */ } return TCL_ERROR; } static int ParseKP(Parser *parserPtr, char *record, int offset) { KernPairs *pairPtr = (KernPairs *)(record + offset); pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]); pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]); if ((GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->x) != TCL_OK) || (GetNumber(parserPtr, parserPtr->argv[4], &pairPtr->y) != TCL_OK)) { return TCL_ERROR; } return TCL_OK; } static int ParseKPH(Parser *parserPtr, char *record, int offset) { KernPairs *pairPtr = (KernPairs *)(record + offset); int x, y; pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]); pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]); if ((GetHexNumber(parserPtr, parserPtr->argv[3], &x) != TCL_OK) || (GetHexNumber(parserPtr, parserPtr->argv[4], &y) != TCL_OK)) { return TCL_ERROR; } pairPtr->x = (float)x; pairPtr->y = (float)y; return TCL_OK; } static int ParseKPX(Parser *parserPtr, char *record, int offset) { KernPairs *pairPtr = (KernPairs *)(record + offset); pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]); pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]); if (GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->x) != TCL_OK) { return TCL_ERROR; } pairPtr->y = 0; return TCL_OK; } static int ParseKPY(Parser *parserPtr, char *record, int offset) { KernPairs *pairPtr = (KernPairs *)(record + offset); pairPtr->first = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]); pairPtr->second = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[2]); if (GetNumber(parserPtr, parserPtr->argv[3], &pairPtr->y) != TCL_OK) { return TCL_ERROR; } pairPtr->x = 0; return TCL_OK; } static ParserSpec kernPairsSpecs[] = { { "EndKernPairs", 1, ParseEndSection, 0 }, { "KP", 5, ParseKP, 0 }, { "KPH", 5, ParseKPH, 0 }, { "KPX", 4, ParseKPX, 0 }, { "KPY", 4, ParseKPY, 0 }, }; static int nKernPairsSpecs = sizeof(kernPairsSpecs) / sizeof(ParserSpec); static int ParseStartKernPairs(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; int *valuePtr = (int *)(record + offset); int n; int result; KernPairs *kp; assert(*valuePtr == 0); if (Tcl_GetInt(NULL, parserPtr->argv[1], &n) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer.", parserPtr->argv[1]); } n++; *valuePtr = n; afmPtr->kernPairs = Blt_Calloc(n, sizeof(KernPairs)); assert(afmPtr->kernPairs); kp = afmPtr->kernPairs; do { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartKernPairs"); } result = ParseLine(parserPtr, kernPairsSpecs, nKernPairsSpecs, kp); kp++; } while (result == TCL_OK); if (result == TCL_CONTINUE) { assert((kp - afmPtr->kernPairs) == *valuePtr); return TCL_OK; /* Found EndKernPairs */ } return TCL_ERROR; } static ParserSpec kernDataSpecs[] = { { "EndKernData", 1, ParseEndSection, 0 }, { "StartKernPairs", 2, ParseStartKernPairs, FM(nKernPairs) }, { "StartKernPairs0", 2, ParseStartKernPairs, FM(nKernPairs) }, { "StartKernPairs1", 2, ParseStartKernPairs, FM(nKernPairs) }, { "StartTrackKern", 2, ParseStartTrackKern, FM(nTrackKern) }, }; static int nKernDataSpecs = sizeof(kernDataSpecs) / sizeof(ParserSpec); static int ParseStartKernData(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; int result; do { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartKernPairs"); } result = ParseLine(parserPtr, kernDataSpecs, nKernDataSpecs, afmPtr); } while (result == TCL_OK); if (result == TCL_CONTINUE) { return TCL_OK; /* Found EndKernData */ } return TCL_ERROR; } static int ParseLigature(Parser *parserPtr, char *record, int offset) { #ifdef notdef CharMetrics *cmPtr = (CharMetrics *)record; int successor; cmPtr->ligature = TRUE; successor = LookupSymbol(parserPtr->afmPtr, parserPtr->argv[1]); ligPtr = NewLigature(cmPtr->index, successor); ligPtr->name = Blt_Strdup(parserPtr->argv[2]); #endif return TCL_OK; } static ParserSpec charMetricsSpecs[] = { { "B", 5, ParseBBox, CM(bbox) }, { "C", 2, ParseInt, CM(index) }, { "CH", 2, ParseHex, CM(index) }, { "EndCharMetrics", 1, ParseEndSection, 0 }, { "L", 3, ParseLigature, CM(hasLigature) }, { "N", 2, ParseName, CM(name) }, { "VV", 3, ParsePoint, CM(vVector) }, { "W", 3, ParsePoint, CM(w) }, { "W0", 3, ParsePoint, CM(w) }, { "W1", 3, ParsePoint, CM(w) }, { "W0X", 2, ParseNumber, CM(w.x) }, { "W0Y", 2, ParseNumber, CM(w.y) }, { "W1X", 2, ParseNumber, CM(w.x) }, { "W1Y", 2, ParseNumber, CM(w.y) }, { "WX", 2, ParseNumber, CM(w.x) }, { "WY", 2, ParseNumber, CM(w.y) } }; static int nCharMetricsSpecs = sizeof(charMetricsSpecs) / sizeof(ParserSpec); static int ParseStartCharMetrics(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; int *valuePtr = (int *)(record + offset); int count; int i; assert(*valuePtr == 0); if (Tcl_GetInt(NULL, parserPtr->argv[1], &i) != TCL_OK) { ParserError(parserPtr, "can't convert \"%s\" to integer.", parserPtr->argv[1]); } i++; *valuePtr = i; for(i = 0; i < 256; i++) { afmPtr->metrics[i].index = -1; } count = 0; for (;;) { int result; CharMetrics cm; const char *p; result = GetLine(parserPtr); if (result == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartCharMetrics"); } memset(&cm, 0, sizeof(CharMetrics)); for(p = strtok(Tcl_DStringValue(&parserPtr->lastLine), ";"); p != NULL; p = strtok(NULL, ";")) { SplitLine(parserPtr, p); if (parserPtr->argc == 0) { continue; } result = ParseLine(parserPtr, charMetricsSpecs, nCharMetricsSpecs, &cm); if (result != TCL_OK) { break; } } count++; if (cm.index != -1) { if (cm.name != NULL) { UpdateSymbol(parserPtr->afmPtr, cm.index, cm.name); } afmPtr->metrics[cm.index] = cm; } if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_CONTINUE) { assert(count == *valuePtr); return TCL_OK; /* Found EndCharMetrics */ } } return TCL_ERROR; } static ParserSpec fontMetricsSpecs[] = { { "Ascender", 2, ParseNumber, FM(ascender) }, { "CapHeight", 2, ParseNumber, FM(capHeight) }, { "CharWidth", 3, ParsePoint, FM(charWidth) }, { "CharacterSet", 0, ParseString, FM(characterSet) }, { "Characters", 2, ParseInt, FM(characters) }, { "Comment", 0, NULL, FM(comment) }, { "Copyright", 0, NULL, FM(copyright) }, { "Descender", 2, ParseNumber, FM(descender) }, { "EncodingScheme", 0, ParseString, FM(encodingScheme) }, { "EndFontMetrics", 1, ParseEndSection, 0 }, { "EscChar", 2, ParseInt, FM(escChar) }, { "FamilyName", 0, ParseString, FM(familyName) }, { "FontBBox", 5, ParseBBox, FM(fontBBox) }, { "FontName", 0, ParseString, FM(fontName) }, { "FullName", 0, ParseString, FM(fullName) }, { "IsBaseFont", 2, ParseBoolean, FM(isBaseFont) }, { "IsCIDFont", 2, ParseBoolean, FM(isCIDFont) }, { "IsFixedPitch", 2, ParseBoolean, FM(isFixedPitch) }, { "IsFixedV", 2, ParseBoolean, FM(isFixedV) }, { "ItalicAngle", 2, ParseNumber, FM(italicAngle) }, { "MappingScheme", 2, ParseInt, FM(mappingScheme) }, { "MetricSets", 2, ParseInt, FM(metricSets) }, { "Notice", 0, NULL, FM(notice) }, { "StartCharMetrics", 2, ParseStartCharMetrics, FM(nCharMetrics) }, { "StartComposites", 2, ParseStartComposites, FM(nComposites) }, { "StartDirection", 2, ParseStartDirection, FM(nDirection) }, { "StartKernData", 1, ParseStartKernData, 0 }, { "StdHW", 2, ParseNumber, FM(stdHW) }, { "StdVW", 2, ParseNumber, FM(stdVW) }, { "UnderlinePosition", 2, ParseNumber, FM(underlinePosition) }, { "UnderlineThickness", 2, ParseNumber, FM(underlineThickness) }, { "VVector", 2, ParsePoint, FM(vVector) }, { "Version", 0, ParseString, FM(version) }, { "Weight", 0, ParseString, FM(weight) }, { "XHeight", 2, ParseNumber, FM(xHeight) } }; static int nFontMetricsSpecs = sizeof(fontMetricsSpecs) / sizeof(ParserSpec); static int ParseStartFontMetrics(Parser *parserPtr, char *record, int offset) { AdobeFontMetrics *afmPtr = (AdobeFontMetrics *)record; const char **versionPtr = (const char **)(record + offset); int result; assert(*versionPtr == NULL); *versionPtr = Blt_Strdup(parserPtr->argv[1]); do { if (SplitNextLine(parserPtr) == TCL_RETURN) { ParserError(parserPtr, "unexpected EOF in StartFontMetrics"); } result = ParseLine(parserPtr, fontMetricsSpecs, nFontMetricsSpecs, afmPtr); } while (result == TCL_OK); if (result == TCL_CONTINUE) { return TCL_OK; /* Found EndFontMetrics */ } return TCL_ERROR; } static ParserSpec afmSpecs[] = { { "StartFontMetrics", 2, ParseStartFontMetrics, FM(afmVersion) }, }; static int nAfmSpecs = sizeof(afmSpecs) / sizeof(ParserSpec); static AdobeFontMetrics * ParseAdobeFontMetricsFile(Tcl_Interp *interp, const char *fileName) { AdobeFontMetrics *afmPtr; Parser *parserPtr; int result; afmPtr = Blt_Calloc(1, sizeof(AdobeFontMetrics)); assert(afmPtr); parserPtr = NewParser(afmPtr, fileName); if (parserPtr == NULL) { Blt_Free(afmPtr); return NULL; } /* Set up jump for errors. */ if (setjmp(parserPtr->jmpbuf)) { fprintf(stderr, "%s\n", Tcl_DStringValue(&parserPtr->errors)); DestroyParser(parserPtr); DestroyAdobeFontMetrics(afmPtr); return NULL; } for (;;) { result = SplitNextLine(parserPtr); if (result == TCL_RETURN) { break; } result = ParseLine(parserPtr, afmSpecs, nAfmSpecs, afmPtr); } DestroyParser(parserPtr); if (result != TCL_RETURN) { DestroyAdobeFontMetrics(afmPtr); return NULL; } BuildKernPairsTable(afmPtr); return afmPtr; } typedef struct { const char *alias; const char *fontName; } FontMap; static FontMap psFontMap[] = { { "Arial", "Helvetica" }, { "AvantGarde", "AvantGarde" }, { "Bookman", "Bookman" }, { "Courier New", "Courier" }, { "Courier", "Courier" }, { "Geneva", "Helvetica" }, { "Helvetica", "Helvetica" }, { "Mathematica1", "Helvetica" }, { "Monaco", "Courier" }, { "New Century Schoolbook", "NewCenturySchlbk" }, { "New York", "Times" }, { "Nimbus Roman No9 L" "Times" }, { "Nimbus Sans L Condensed","Helvetica" }, { "Nimbus Sans L", "Helvetica" }, { "Palatino", "Palatino" }, { "Standard Symbols L", "Symbol" }, { "Symbol", "Symbol" }, { "Times New Roman", "Times" }, { "Times Roman", "Times" }, { "Times", "Times" }, { "ZapfChancery", "ZapfChancery" }, { "ZapfDingbats", "ZapfDingbats" } }; static int nPsFonts = sizeof(psFontMap) / sizeof(FontMap); /* *--------------------------------------------------------------------------- * * LookupFontName -- * *--------------------------------------------------------------------------- */ static const char * LookupFontName(const char *string) { char c; int high, low; low = 0; high = nPsFonts - 1; c = string[0]; while (low <= high) { FontMap *mapPtr; int compare; int median; median = (low + high) >> 1; mapPtr = psFontMap + median; /* Test the first character */ compare = c - mapPtr->alias[0]; if (compare == 0) { /* Now test the entire string */ compare = strcmp(string, mapPtr->alias); } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return mapPtr->fontName; } } return "Helvetica"; /* Can't find font. */ } static AdobeFontMetrics * GetAdobeFontMetrics(Tcl_Interp *interp, const char *psFontName) { AdobeFontMetrics *afmPtr; Blt_HashEntry *hPtr; int isNew; if (!initialized) { Blt_InitHashTable(&fontTable, BLT_STRING_KEYS); initialized = TRUE; } #ifdef notdef fprintf(stderr, "Lookup for %s\n", psFontName); #endif psFontName = LookupFontName(psFontName); #ifdef notdef fprintf(stderr, "returning %s\n", psFontName); #endif hPtr = Blt_CreateHashEntry(&fontTable, psFontName, &isNew); if (isNew) { const char *path; Tcl_DString ds; path = Tcl_GetVar(interp, "blt_library", TCL_GLOBAL_ONLY); if (path == NULL) { Tcl_AppendResult(interp, "can't find \"blt_library\" variable", (char *)NULL); Blt_DeleteHashEntry(&fontTable, hPtr); return NULL; } Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, path, -1); Tcl_DStringAppend(&ds, "/afm/", 5); Tcl_DStringAppend(&ds, psFontName, -1); Tcl_DStringAppend(&ds, ".afm", 4); afmPtr = ParseAdobeFontMetricsFile(interp, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); if (afmPtr == NULL) { Blt_DeleteHashEntry(&fontTable, hPtr); return NULL; } Blt_SetHashValue(hPtr, afmPtr); afmPtr->hashPtr = hPtr; } else { afmPtr = Blt_GetHashValue(hPtr); } return afmPtr; } static AdobeFontMetrics * GetAdobeFontMetricsFromFont(Blt_Font font) { AdobeFontMetrics *afmPtr; Tcl_DString ds; double pointSize; Tcl_Interp *interp; Tcl_DStringInit(&ds); pointSize = Blt_PostscriptFontName(font, &ds); interp = Blt_GetFontInterp(font); afmPtr = GetAdobeFontMetrics(interp, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); if (afmPtr != NULL) { afmPtr->pointSize = pointSize; return afmPtr; } return NULL; } int Blt_Ps_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr) { AdobeFontMetrics *afmPtr; afmPtr = GetAdobeFontMetricsFromFont(font); if (afmPtr == NULL) { return TCL_ERROR; } #ifndef notdef fmPtr->ascent = Points(afmPtr, afmPtr->ascender); #else fmPtr->ascent = Points(afmPtr, afmPtr->capHeight); #endif fmPtr->descent = Points(afmPtr, -afmPtr->descender); fmPtr->linespace = Points(afmPtr, afmPtr->ascender - afmPtr->descender); #ifdef notdef fprintf(stderr, "GetFontMetrics(%s), ascent=%d descent=%d linespace=%d\n", Blt_NameOfFont(font), fmPtr->ascent, fmPtr->descent, fmPtr->linespace); #endif return TCL_OK; } int Blt_Ps_TextWidth(Blt_Font font, const char *string, int nBytes) { AdobeFontMetrics *afmPtr; const char *p, *pend; float width; #ifdef notdef fprintf(stderr, "Ps_TextWidth(%s,\"%s\")\n", Blt_NameOfFont(font), string); #endif afmPtr = GetAdobeFontMetricsFromFont(font); if (afmPtr == NULL) { fprintf(stderr, "can't find font\n"); return -1; } width = 0; #ifdef notdef fprintf(stderr, "string=\"%s\"\n", string); #endif for (p = string, pend = string + nBytes; p < pend; /*empty*/) { CharMetrics *cmPtr; unsigned char c; Tcl_UniChar ch; p += Tcl_UtfToUniChar(p, &ch); c = (unsigned char)(ch & 0xff); cmPtr = afmPtr->metrics + c; if (cmPtr->index < 0) { continue; /* Ignore unencoded characters. */ } #ifdef notdef fprintf(stderr, "width=%g, incr=%g, char=%c\n", width, cmPtr->w.x, c); #endif width += cmPtr->w.x; } { /* Kerning */ unsigned char c1, c2; Tcl_UniChar ch; p = string; p += Tcl_UtfToUniChar(string, &ch); c1 = (unsigned char)(ch & 0xff); while (p < pend) { p += Tcl_UtfToUniChar(p, &ch); c2 = (unsigned char)(ch & 0xff); if (afmPtr->metrics[c1].hasKernPair) { KernPairs *kp; kp = GetKernPairs(afmPtr, c1, c2); width += kp->x; } c1 = c2; } } #ifdef notdef fprintf(stderr, "StringWidth of \"%s\" is %d (ps=%f)\n", string, Points(afmPtr, width), afmPtr->pointSize); #endif return Points(afmPtr, width); } static int LoadOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { AdobeFontMetrics *afmPtr; afmPtr = ParseAdobeFontMetricsFile(interp, Tcl_GetString(objv[2])); if (afmPtr == NULL) { return TCL_ERROR; } return TCL_OK; } static int DumpOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { AdobeFontMetrics *afmPtr; const char *fileName; int i; fileName = Tcl_GetString(objv[2]); afmPtr = ParseAdobeFontMetricsFile(interp, fileName); if (afmPtr == NULL) { return TCL_ERROR; } if (afmPtr->familyName != NULL) { Tcl_AppendElement(interp, "familyName"); Tcl_AppendElement(interp, afmPtr->familyName); } if (afmPtr->fontName != NULL) { Tcl_AppendElement(interp, "fontName"); Tcl_AppendElement(interp, afmPtr->fontName); } if (afmPtr->fullName != NULL) { Tcl_AppendElement(interp, "fullName"); Tcl_AppendElement(interp, afmPtr->fullName); } if (afmPtr->version != NULL) { Tcl_AppendElement(interp, "version"); Tcl_AppendElement(interp, afmPtr->version); } if (afmPtr->weight != NULL) { Tcl_AppendElement(interp, "weight"); Tcl_AppendElement(interp, afmPtr->weight); } if (afmPtr->comment != NULL) { Tcl_AppendElement(interp, "comment"); Tcl_AppendElement(interp, afmPtr->comment); } if (afmPtr->notice != NULL) { Tcl_AppendElement(interp, "notice"); Tcl_AppendElement(interp, afmPtr->notice); } if (afmPtr->characterSet != NULL) { Tcl_AppendElement(interp, "characterSet"); Tcl_AppendElement(interp, afmPtr->characterSet); } if (afmPtr->encodingScheme != NULL) { Tcl_AppendElement(interp, "encodingScheme"); Tcl_AppendElement(interp, afmPtr->encodingScheme); } Tcl_AppendElement(interp, "underlinePosition"); Tcl_AppendElement(interp, FTOA(afmPtr->underlinePosition)); Tcl_AppendElement(interp, "underlineThickness"); Tcl_AppendElement(interp, FTOA(afmPtr->underlineThickness)); Tcl_AppendElement(interp, "italicAngle"); Tcl_AppendElement(interp, FTOA(afmPtr->italicAngle)); Tcl_AppendElement(interp, "capHeight"); Tcl_AppendElement(interp, FTOA(afmPtr->capHeight)); Tcl_AppendElement(interp, "xHeight"); Tcl_AppendElement(interp, FTOA(afmPtr->xHeight)); Tcl_AppendElement(interp, "ascender"); Tcl_AppendElement(interp, FTOA(afmPtr->ascender)); Tcl_AppendElement(interp, "descender"); Tcl_AppendElement(interp, FTOA(afmPtr->descender)); Tcl_AppendElement(interp, "isFixedPitch"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->isFixedPitch)); Tcl_AppendElement(interp, "isBaseFont"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->isBaseFont)); Tcl_AppendElement(interp, "isCIDFont"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->isCIDFont)); Tcl_AppendElement(interp, "isFixedV"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->isFixedV)); Tcl_AppendElement(interp, "nCharMetrics"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->nCharMetrics)); Tcl_AppendElement(interp, "nComposites"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->nComposites)); Tcl_AppendElement(interp, "nDirection"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->nDirection)); Tcl_AppendElement(interp, "nKernPairs"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->nKernPairs)); Tcl_AppendElement(interp, "nTrackKern"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->nTrackKern)); Tcl_AppendElement(interp, "escChar"); Tcl_AppendElement(interp, Blt_Itoa(afmPtr->escChar)); Tcl_AppendElement(interp, "vvector x"); Tcl_AppendElement(interp, FTOA(afmPtr->vVector.x)); Tcl_AppendElement(interp, "vvector y"); Tcl_AppendElement(interp, FTOA(afmPtr->vVector.y)); Tcl_AppendElement(interp, "stdHW"); Tcl_AppendElement(interp, FTOA(afmPtr->stdHW)); Tcl_AppendElement(interp, "stdVW"); Tcl_AppendElement(interp, FTOA(afmPtr->stdVW)); for (i = 0; i < 256; i++) { if (afmPtr->metrics[i].index >= 0) { if (afmPtr->metrics[i].hasLigature) { Tcl_AppendElement(interp, "index"); Tcl_AppendElement(interp, "x"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].w.x)); Tcl_AppendElement(interp, "y"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].w.y)); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].index)); if (afmPtr->metrics[i].name != NULL) { int code; code = LookupSymbol(afmPtr, afmPtr->metrics[i].name); if (code != afmPtr->metrics[i].index) { fprintf(stderr, "index=%d, code=%d, name=%s\n", afmPtr->metrics[i].index, code, afmPtr->metrics[i].name); } Tcl_AppendElement(interp, "name"); Tcl_AppendElement(interp, afmPtr->metrics[i].name); } Tcl_AppendElement(interp, "llx"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].bbox.llx)); Tcl_AppendElement(interp, "lly"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].bbox.lly)); Tcl_AppendElement(interp, "urx"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].bbox.urx)); Tcl_AppendElement(interp, "ury"); Tcl_AppendElement(interp, FTOA(afmPtr->metrics[i].bbox.ury)); } } } DestroyAdobeFontMetrics(afmPtr); return TCL_OK; } static Blt_OpSpec afmOps[] = { {"dump", 1, DumpOp, 3, 3, "fileName",}, {"load", 1, LoadOp, 3, 3, "fileName",}, }; static int nAfmOps = sizeof(afmOps) / sizeof(Blt_OpSpec); static int AfmCmdProc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nAfmOps, afmOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } int Blt_AfmCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "afm", AfmCmdProc, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } static int AfmStringWidthOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { AdobeFontMetrics *afmPtr; afmPtr = ParseAdobeFontMetricsFile(interp, Tcl_GetString(objv[2])); if (afmPtr == NULL) { return TCL_ERROR; } return TCL_OK; } �����./saods9/blt3.0.1/src/bltAlloc.c��������������������������������������������������������������������0000644�0001750�0001750�00000012545�11462120062�014734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "bltInt.h" #ifdef HAVE_MALLOC_H #include <malloc.h> #endif /* HAVE_MALLOC_H */ /* * Memory allocation/deallocation in BLT is performed via the global * variables bltMallocPtr, bltFreePtr, and bltReallocPtr. By default, * they point to the same routines that TCL uses. The routine * Blt_AllocInit allows you to specify your own memory allocation and * deallocation routines for BLT on a library-wide basis. */ #ifdef WIN32 #ifdef __GNUC__ #ifndef USE_TCL_STUBS EXTERN char *Tcl_Alloc(unsigned int size); EXTERN void Tcl_Free(char * ptr); EXTERN char *Tcl_Realloc(char *ptr, unsigned int size); #endif #endif /*__GNUC__*/ #else #if (_TCL_VERSION >= _VERSION(8,1,0)) #ifndef USE_TCL_STUBS BLT_EXTERN Blt_MallocProc TclpAlloc; BLT_EXTERN Blt_FreeProc TclpFree; BLT_EXTERN Blt_ReallocProc TclpRealloc; #endif #else #if !HAVE_DECL_FREE BLT_EXTERN void free (void *); #endif #endif /* >= 8.1.0 */ #endif /* WIN32 */ static Blt_MallocProc *bltMallocPtr; static Blt_ReallocProc *bltReallocPtr; static Blt_FreeProc *bltFreePtr; void * Blt_Malloc(size_t size) { return (*bltMallocPtr)(size); } void Blt_Free(const void *mem) { (*bltFreePtr)((void *)mem); } void * Blt_Realloc(void *ptr, size_t size) { return (*bltReallocPtr)(ptr, size); } void * Blt_Calloc(size_t nElem, size_t elemSize) { void *ptr; size_t size; size = nElem * elemSize; ptr = (*bltMallocPtr)(size); if (ptr != NULL) { memset(ptr, 0, size); } return ptr; } void * Blt_MallocAbortOnError(size_t size, const char *fileName, int lineNum) { void *ptr; ptr = (*bltMallocPtr)(size); if (ptr == NULL) { #ifdef WINDEBUG PurifyPrintf("line %d of %s: can't allocate %lu bytes of memory\n", lineNum, fileName, (unsigned long)size); #endif fprintf(stderr, "line %d of %s: can't allocate %lu bytes of memory\n", lineNum, fileName, (unsigned long)size); fflush(stderr); abort(); } return ptr; } void * Blt_CallocAbortOnError(size_t nElem, size_t elemSize, const char *fileName, int lineNum) { void *ptr; size_t size; size = nElem * elemSize; ptr = (*bltMallocPtr)(size); if (ptr == NULL) { #ifdef WINDEBUG PurifyPrintf( "line %d of %s: can't allocate %lu item(s) of size %lu each\n", lineNum, fileName, (unsigned long)nElem, (unsigned long)elemSize); #endif fprintf(stderr, "line %d of %s: can't allocate %lu item(s) of size %lu each\n", lineNum, fileName, (unsigned long)nElem, (unsigned long)elemSize); fflush(stderr); abort(); } memset(ptr, 0, size); return ptr; } /* *--------------------------------------------------------------------------- * * Blt_Strdup -- * * Create a copy of the string from heap storage. * * Results: * Returns a pointer to the need string copy. * *--------------------------------------------------------------------------- */ char * Blt_Strdup(const char *string) { size_t size; char *ptr; size = strlen(string) + 1; ptr = (*bltMallocPtr)(size * sizeof(char)); if (ptr != NULL) { strcpy(ptr, string); } return ptr; } /* *--------------------------------------------------------------------------- * * Blt_StrdupAbortOnError -- * * Create a copy of the string from heap storage. * * Results: * Returns a pointer to the need string copy. * *--------------------------------------------------------------------------- */ char * Blt_StrdupAbortOnError(const char *string, const char *fileName, int lineNum) { size_t size; char *ptr; size = strlen(string) + 1; ptr = (*bltMallocPtr)(size * sizeof(char)); if (ptr == NULL) { #ifdef WINDEBUG PurifyPrintf("line %d of %s: can't allocate string of %lu bytes\n", lineNum, fileName, (unsigned long)size); #endif fprintf(stderr, "line %d of %s: can't allocate string of %lu bytes\n", lineNum, fileName, (unsigned long)size); fflush(stderr); abort(); } strcpy(ptr, string); return ptr; } void Blt_AllocInit( Blt_MallocProc *mallocProc, Blt_ReallocProc *reallocProc, Blt_FreeProc *freeProc) { Blt_MallocProc *defMallocProc; Blt_FreeProc *defFreeProc; Blt_ReallocProc *defReallocProc; /* * Try to use the same memory allocator/deallocator that TCL is * using. Before 8.1 it used malloc/free. */ #ifdef WIN32 defMallocProc = (Blt_MallocProc *)Tcl_Alloc; defFreeProc = (Blt_FreeProc *)Tcl_Free; defReallocProc = (Blt_ReallocProc *)Tcl_Realloc; #else #if (_TCL_VERSION >= _VERSION(8,1,0)) /* * We're pointing to the private TclpAlloc/TclpFree instead of public * Tcl_Alloc/Tcl_Free routines because they don't automatically trigger a * panic when not enough memory is available. There are cases (such as * allocating a very large vector) where an out-of-memory error is * recoverable. */ defMallocProc = (Blt_MallocProc *)TclpAlloc; defFreeProc = (Blt_FreeProc *)TclpFree; defReallocProc = (Blt_ReallocProc *)TclpRealloc; #else defMallocProc = malloc; defFreeProc = free; defReallocProc = realloc; #endif /* >= 8.1.0 */ #endif /* WIN32 */ if (bltMallocPtr == NULL) { bltMallocPtr = (mallocProc != NULL) ? mallocProc : defMallocProc; } if (bltFreePtr == NULL) { bltFreePtr = (freeProc != NULL) ? freeProc : defFreeProc; } if (bltReallocPtr == NULL) { bltReallocPtr = (reallocProc != NULL) ? reallocProc : defReallocProc; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinWindow.c����������������������������������������������������������������0000644�0001750�0001750�00000027150�11462120063�015626� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinWindow.c -- * * This module implements additional window functionality for the BLT toolkit, * such as transparent Tk windows, and reparenting Tk windows. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <X11/Xlib.h> #include "tkDisplay.h" /* *--------------------------------------------------------------------------- * * WindowToHandle -- * *--------------------------------------------------------------------------- */ static HWND WindowToHandle(Tk_Window tkwin) { HWND hWnd; Window window; window = Tk_WindowId(tkwin); if (window == None) { Tk_MakeWindowExist(tkwin); } hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); if (Tk_IsTopLevel(tkwin)) { hWnd = GetParent(hWnd); } return hWnd; } /* *--------------------------------------------------------------------------- * * DoConfigureNotify -- * * Generate a ConfigureNotify event describing the current configuration * of a window. * * Results: * None. * * Side effects: * An event is generated and processed by Tk_HandleEvent. * *--------------------------------------------------------------------------- */ static void DoConfigureNotify(Tk_FakeWin *winPtr) /* Window whose configuration * was just changed. */ { XEvent event; event.type = ConfigureNotify; event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); event.xconfigure.send_event = False; event.xconfigure.display = winPtr->display; event.xconfigure.event = winPtr->window; event.xconfigure.window = winPtr->window; event.xconfigure.x = winPtr->changes.x; event.xconfigure.y = winPtr->changes.y; event.xconfigure.width = winPtr->changes.width; event.xconfigure.height = winPtr->changes.height; event.xconfigure.border_width = winPtr->changes.border_width; if (winPtr->changes.stack_mode == Above) { event.xconfigure.above = winPtr->changes.sibling; } else { event.xconfigure.above = None; } event.xconfigure.override_redirect = winPtr->atts.override_redirect; Tk_HandleEvent(&event); } /* *--------------------------------------------------------------------------- * * Blt_MakeTransparentWindowExist -- * * Similar to Tk_MakeWindowExist but instead creates a transparent window * to block for user events from sibling windows. * * Differences from Tk_MakeWindowExist. * * 1. This is always a "busy" window. There's never a platform-specific * class procedure to execute. * * 2. The window is transparent and never will have children, so * colormap information is irrelevant. * * Results: * None. * * Side effects: * When the procedure returns, the internal window associated with tkwin * is guaranteed to exist. This may require the window's ancestors to be * created too. * *--------------------------------------------------------------------------- */ void Blt_MakeTransparentWindowExist( Tk_Window tkwin, /* Token for window. */ Window parent, /* Parent window. */ int isBusy) /* */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *winPtr2; Tcl_HashEntry *hPtr; int notUsed; TkDisplay *dispPtr; HWND hParent; int style; DWORD exStyle; HWND hWnd; if (winPtr->window != None) { return; /* Window already exists. */ } /* Create a transparent window and put it on top. */ hParent = (HWND) parent; style = (WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); exStyle = (WS_EX_TRANSPARENT | WS_EX_TOPMOST); #define TK_WIN_CHILD_CLASS_NAME "TkChild" hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style, Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), hParent, NULL, (HINSTANCE)Tk_GetHINSTANCE(), NULL); winPtr->window = Tk_AttachHWND(tkwin, hWnd); dispPtr = winPtr->dispPtr; hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *)winPtr->window, &notUsed); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; #ifdef TK_USE_INPUT_METHODS winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (!(winPtr->flags & TK_TOP_LEVEL)) { /* * If any siblings higher up in the stacking order have already been * created then move this window to its rightful position in the * stacking order. * * NOTE: this code ignores any changes anyone might have made to the * sibling and stack_mode field of the window's attributes, so it * really isn't safe for these to be manipulated except by calling * Tk_RestackWindow. */ for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; winPtr2 = winPtr2->nextPtr) { if ((winPtr2->window != None) && !(winPtr2->flags & TK_TOP_LEVEL)) { XWindowChanges changes; changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, CWSibling | CWStackMode, &changes); break; } } } /* * Issue a ConfigureNotify event if there were deferred configuration * changes (but skip it if the window is being deleted; the * ConfigureNotify event could cause problems if we're being called from * Tk_DestroyWindow under some conditions). */ if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) && !(winPtr->flags & TK_ALREADY_DEAD)) { winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; DoConfigureNotify((Tk_FakeWin *)tkwin); } } /* *--------------------------------------------------------------------------- * * Blt_GetWindowRegion -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_GetWindowRegion( Display *display, /* Not used. */ Window window, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr) { int result; RECT region; TkWinWindow *winPtr = (TkWinWindow *)window; result = GetWindowRect(winPtr->handle, &region); if (!result) { return TCL_ERROR; } if (xPtr != NULL) { *xPtr = region.left; } if (yPtr != NULL) { *yPtr = region.top; } if (widthPtr != NULL) { *widthPtr = region.right - region.left; } if (heightPtr != NULL) { *heightPtr = region.bottom - region.top; } return TCL_OK; } void Blt_GetRootCoords( Display *display, Window window, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr) { int result; RECT region; TkWinWindow *winPtr = (TkWinWindow *)window; result = GetWindowRect(winPtr->handle, &region); if (!result) { return TCL_ERROR; } if (xPtr != NULL) { *xPtr = region.left; } if (yPtr != NULL) { *yPtr = region.top; } if (widthPtr != NULL) { *widthPtr = region.right - region.left; } if (heightPtr != NULL) { *heightPtr = region.bottom - region.top; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetWindowId -- * * Returns the XID for the Tk_Window given. Starting in Tk 8.0, the * toplevel widgets are wrapped by another window. Currently there's no * way to get at that window, other than what is done here: query the X * window hierarchy and grab the parent. * * Results: * Returns the X Window ID of the widget. If it's a toplevel, then * the * XID of the wrapper is returned. * *--------------------------------------------------------------------------- */ Window Blt_GetWindowId(Tk_Window tkwin) { return (Window) WindowToHandle(tkwin); } /* *--------------------------------------------------------------------------- * * Blt_GetToplevelWindow -- * * Retrieves the toplevel window which is the nearest ancestor of of the * specified window. * * Results: * Returns the toplevel window or NULL if the window has no ancestor * which is a toplevel. * * Side effects: * None. * *--------------------------------------------------------------------------- */ Tk_Window Blt_GetToplevelWindow(Tk_Window tkwin) /* Window for which the toplevel * should be deterined. */ { while (!Tk_IsTopLevel(tkwin)) { tkwin = Tk_Parent(tkwin); if (tkwin == NULL) { return NULL; } } return tkwin; } /* *--------------------------------------------------------------------------- * * Blt_RaiseTopLevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_RaiseToplevelWindow(Tk_Window tkwin) { SetWindowPos(WindowToHandle(tkwin), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } /* *--------------------------------------------------------------------------- * * Blt_MapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MapToplevelWindow(Tk_Window tkwin) { ShowWindow(WindowToHandle(tkwin), SW_SHOWNORMAL); } /* *--------------------------------------------------------------------------- * * Blt_UnmapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_UnmapToplevelWindow(Tk_Window tkwin) { ShowWindow(WindowToHandle(tkwin), SW_HIDE); } /* *--------------------------------------------------------------------------- * * Blt_MoveResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MoveResizeToplevelWindow(Tk_Window tkwin, int x, int y, int w, int h) { SetWindowPos(WindowToHandle(tkwin), HWND_TOP, x, y, w, h, 0); } int Blt_ReparentWindow( Display *display, Window window, Window newParent, int x, int y) { XReparentWindow(display, window, newParent, x, y); return TCL_OK; } int Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr) { char *string; string = Tcl_GetString(objPtr); if (string[0] == '.') { Tk_Window tkwin; tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } *windowPtr = (Tk_IsTopLevel(tkwin)) ? Blt_GetWindowId(tkwin) : Tk_WindowId(tkwin); } else if (strcmp(string, "root") == 0) { *windowPtr = Tk_RootWindow(Tk_MainWindow(interp)); } else { static TkWinWindow tkWinWindow; int id; if (Tcl_GetIntFromObj(interp, objPtr, &id) != TCL_OK) { return TCL_ERROR; } tkWinWindow.handle = (HWND)id; tkWinWindow.winPtr = NULL; tkWinWindow.type = TWD_WINDOW; *windowPtr = (Window)&tkWinWindow; } return TCL_OK; } Window Blt_GetParentWindow(Display *display, Window window) { HWND hWnd; hWnd = Tk_GetHWND(window); hWnd = GetParent(hWnd); return (Window)hWnd; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDtCmd.c��������������������������������������������������������������������0000644�0001750�0001750�00000641431�11462120062�014677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtCmd.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* blt::datatable create t0 t1 t2 blt::datatable names t0 destroy -or- blt::datatable destroy t0 blt::datatable copy table@node table@node -recurse -tags table move node after|before|into t2@node $t apply -recurse $root command arg arg $t attach tablename $t children $n t0 copy node1 node2 node3 node4 node5 destName $t delete $n... $t delete 0 $t delete 0 10 $t delete all $t depth $n $t dump $t dump -file fileName $t dup $t2 $t find $root -name pat -name pattern $t firstchild $n $t get $n $key $t get $n $key(abc) $t index $n $t insert $parent $switches? $t isancestor $n1 $n2 $t isbefore $n1 $n2 $t isleaf $n $t lastchild $n $t move $n1 after|before|into $n2 $t next $n $t nextsibling $n $t path $n1 $n2 $n3... $t parent $n $t previous $n $t prevsibling $n $t restore $root data -overwrite $t root ?$n? $t set $n $key $value ?$key $value? $t size $n $t slink $n $t2@$node ??? $t sort -recurse $root $t tag delete tag1 tag2 tag3... $t tag names $t tag nodes $tag $t tag set $n tag1 tag2 tag3... $t tag unset $n tag1 tag2 tag3... $t trace create $n $key how command $t trace delete id1 id2 id3... $t trace names $t trace info $id $t unset $n key1 key2 key3... $t row notify $row ?flags? command $t column notify $column ?flags? command arg arg arg $t notify create -oncreate -ondelete -onmove command $t notify create -oncreate -ondelete -onmove -onsort command arg arg arg $t notify delete id1 id2 id3 $t notify names $t notify info id for { set n [$t firstchild $node] } { $n >= 0 } { set n [$t nextsibling $n] } { } foreach n [$t children $node] { } set n [$t next $node] set n [$t previous $node] */ /* * * datatable create ?name? * datatable names * datatable destroy $table * * $t column label ?newLabel? * $t column labels ?index newLabel...? * * $t column index $c * $t column indices $c * $t column get $c * $t column delete $r $r $r $r * $t column extend label label label... * $t column get $column * $t column insert $column "label" * $t column select $expr * $t column set {1 20} $list * $t column set 1-20 $list * $t column set 1:20 $list * $t column trace $row rwu proc * $t column unset $column * $t copy fromTable * $t copy newTable * $t dup newTable -includerows $tag $tag $tag -excludecolumns $tag $tag * $t get $row $column $value ?$defValue? * $t pack * $t row delete row row row row * $t row create -tags $tags -label $label -before -after * $t row extend 1 * $t row get $row -nolabels * $t row create $column "label" "label" * $t row select $expr * $t row set $row $list -nolabels * $t row trace $row rwu proc * $t row unset $row * $t row tag add where expr * $t row tag forget $tag $tag * $t row tag delete $tag $row $row $row * $t row tag find $row ?pattern*? * $t row tag add $row tag tag tag tag * $t row tag unset $row tag tag tag * $t row find $expr * $t row unique $rowexpr * $t select $expr * $t set $row $column $value * $t trace $row $column rwu proc * $t unset $row $column * $t column find $expr * $t import -format {csv} -overwrite fileName * $t export -format {csv,xml} fileName * $t dumpdata -deftags -deflabels -columns "tags" -rows "tags" string * $t dump -notags -nolabels -columns "tags" -rows "tags" fileName * $t dup $destTable -notags -nolabels -columns "tags" -rows "tags" * $t restore -overwrite -notags -nolabels string * $t restoredata -overwrite -notags -nolabels -data string * $t restore -overwrite -notags -nolabels fileName * * $t row hide label * $t row unhide label * * $t emptyvalue ?value? * $t key set ?key key key? * $t key lookup ?key key key? */ /* * $t import -format tree {tree 10} * $t import -format csv $fileName.csv * * $t import tree $tree 10 ?switches? * $t import csv ?switches? fileName.xml * $t importdata csv -separator , -quote " $fileName.csv * $t import csv -separator , -quote " -data string * $t exportdata xml ?switches? ?$fileName.xml? * $t export csv -separator \t -quote ' $fileName.csv * $t export csv -separator \t -quote ' * $t export -format dbm $fileName.dbm * $t export -format db $fileName.db * $t export -format csv $fileName.csv */ /* * $vector attach "$t c $column" * $vector detach * $graph element create x -x "${table} column ${column}" \ * "table0 r abc" * $tree attach 0 $t */ #include <bltInt.h> #include "bltOp.h" #include <bltNsUtil.h> #include <bltSwitch.h> #include <bltHash.h> #include <bltVar.h> #include <bltDataTable.h> #include <ctype.h> #define TABLE_THREAD_KEY "BLT DataTable Command Interface" /* * TableCmdInterpData -- * * Structure containing global data, used on a interpreter by interpreter * basis. * * This structure holds the hash table of instances of datatable commands * associated with a particular interpreter. */ typedef struct { Blt_HashTable instTable; /* Tracks tables in use. */ Tcl_Interp *interp; Blt_HashTable fmtTable; Blt_HashTable findTable; /* Tracks temporary "find" search * information keyed by a specific * namespace. */ } TableCmdInterpData; typedef struct { long freq; /* Frequency of value */ const char *value; /* String representation of value. */ } UniqueValue; /* * Cmd -- * * Structure representing the TCL command used to manipulate the * underlying table object. * * This structure acts as a shell for a table object. A table object * maybe shared by more than one client. This shell provides Tcl * commands to access and change values as well as the structure of the * table itself. It manages the traces and notifier events that it * creates, providing a TCL interface to those facilities. It also * provides a user-selectable value for empty-cell values. */ typedef struct { Tcl_Interp *interp; /* Interpreter this command is * associated with. */ Blt_Table table; /* Handle representing the client * table. */ Tcl_Command cmdToken; /* Token for TCL command representing * this table. */ const char *emptyValue; /* String representing an empty value in * the table. */ Blt_HashTable *tablePtr; /* Pointer to hash table containing a * pointer to this structure. Used to * delete * this table entry from the * table. */ Blt_HashEntry *hPtr; /* Pointer to the hash table entry for * this table in the interpreter * specific hash table. */ int nextTraceId; /* Used to generate trace id * strings. */ Blt_HashTable traceTable; /* Table of active traces. Maps trace * ids back to their TraceInfo * records. */ int nextNotifyId; /* Used to generate notify id * strings. */ Blt_HashTable notifyTable; /* Table of event handlers. Maps * notify ids back to their NotifyInfo * records. */ } Cmd; typedef struct { const char *name; /* Name of format. */ int isLoaded; Blt_TableImportProc *importProc; Blt_TableExportProc *exportProc; } DataFormat; typedef struct { Tcl_Obj *cmd0; Tcl_Interp *interp; } CompareData; /* * TraceInfo -- * * Structure containing information about a trace set from this command * shell. * * This auxillary structure houses data to be used for a callback to a * Tcl procedure when a table object trace fires. It is stored in a hash * table in the Dt_Cmd structure to keep track of traces issued by this * shell. */ typedef struct { Blt_TableTrace trace; Cmd *cmdPtr; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; int type; int cmdc; Tcl_Obj **cmdv; } TraceInfo; /* * NotifierInfo -- * * Structure containing information about a notifier set from * this command shell. * * This auxillary structure houses data to be used for a callback * to a TCL procedure when a table object notify event fires. It * is stored in a hash table in the Dt_Cmd structure to keep * track of notifiers issued by this shell. */ typedef struct { Blt_TableNotifier notifier; Cmd *cmdPtr; Blt_HashEntry *hPtr; int cmdc; Tcl_Obj **cmdv; } NotifierInfo; BLT_EXTERN Blt_SwitchFreeProc Blt_Table_ColumnIterFreeProc; BLT_EXTERN Blt_SwitchFreeProc Blt_Table_RowIterFreeProc; BLT_EXTERN Blt_SwitchParseProc Blt_Table_ColumnIterSwitchProc; BLT_EXTERN Blt_SwitchParseProc Blt_Table_RowIterSwitchProc; static Blt_SwitchParseProc TableSwitchProc; static Blt_SwitchFreeProc TableFreeProc; static Blt_SwitchParseProc PositionSwitch; static Blt_SwitchParseProc TypeSwitchProc; static Blt_SwitchCustom columnIterSwitch = { Blt_Table_ColumnIterSwitchProc, Blt_Table_ColumnIterFreeProc, 0, }; static Blt_SwitchCustom rowIterSwitch = { Blt_Table_RowIterSwitchProc, Blt_Table_RowIterFreeProc, 0, }; static Blt_SwitchCustom tableSwitch = { TableSwitchProc, TableFreeProc, 0, }; static Blt_SwitchCustom typeSwitch = { TypeSwitchProc, NULL, 0, }; #define INSERT_BEFORE (ClientData)(1<<0) #define INSERT_AFTER (ClientData)(1<<1) #define INSERT_ROW (BLT_SWITCH_USER_BIT<<1) #define INSERT_COL (BLT_SWITCH_USER_BIT<<2) static Blt_SwitchCustom beforeSwitch = { PositionSwitch, NULL, INSERT_BEFORE, }; static Blt_SwitchCustom afterSwitch = { PositionSwitch, NULL, INSERT_AFTER, }; typedef struct { Cmd *cmdPtr; Blt_TableRow row; /* Index where to install new row or * column. */ Blt_TableColumn column; const char *label; /* New label. */ Tcl_Obj *tags; /* List of tags to be applied to this * row or column. */ Blt_TableColumnType type; } InsertSwitches; static Blt_SwitchSpec insertSwitches[] = { {BLT_SWITCH_CUSTOM, "-after", "column", Blt_Offset(InsertSwitches, column), INSERT_COL, 0, &afterSwitch}, {BLT_SWITCH_CUSTOM, "-after", "row", Blt_Offset(InsertSwitches, row), INSERT_ROW, 0, &afterSwitch}, {BLT_SWITCH_CUSTOM, "-before", "column", Blt_Offset(InsertSwitches, column), INSERT_COL, 0, &beforeSwitch}, {BLT_SWITCH_CUSTOM, "-before", "row", Blt_Offset(InsertSwitches, row), INSERT_ROW, 0, &beforeSwitch}, {BLT_SWITCH_STRING, "-label", "string", Blt_Offset(InsertSwitches, label), INSERT_ROW | INSERT_COL}, {BLT_SWITCH_OBJ, "-tags", "tags", Blt_Offset(InsertSwitches, tags), INSERT_ROW | INSERT_COL}, {BLT_SWITCH_CUSTOM, "-type", "type", Blt_Offset(InsertSwitches, type), INSERT_COL, 0, &typeSwitch}, {BLT_SWITCH_END} }; typedef struct { unsigned int flags; Blt_Table table; } CopySwitches; #define COPY_NOTAGS (1<<1) #define COPY_LABEL (1<<3) static Blt_SwitchSpec copySwitches[] = { {BLT_SWITCH_BITMASK, "-notags", "", Blt_Offset(CopySwitches, flags), 0, COPY_NOTAGS}, {BLT_SWITCH_CUSTOM, "-table", "srcTable", Blt_Offset(CopySwitches, table), 0, 0, &tableSwitch}, {BLT_SWITCH_END} }; typedef struct { unsigned int flags; } AddSwitches; #define ADD_NOTAGS (1<<1) static Blt_SwitchSpec addSwitches[] = { {BLT_SWITCH_BITMASK, "-notags", "", Blt_Offset(CopySwitches, flags), 0, ADD_NOTAGS}, {BLT_SWITCH_END} }; typedef struct { /* Private data */ Tcl_Channel channel; Tcl_DString *dsPtr; unsigned int flags; /* Public fields */ Blt_TableIterator ri, ci; Tcl_Obj *fileObjPtr; } DumpSwitches; static Blt_SwitchSpec dumpSwitches[] = { {BLT_SWITCH_CUSTOM, "-rows", "rows", Blt_Offset(DumpSwitches, ri), 0, 0, &rowIterSwitch}, {BLT_SWITCH_CUSTOM, "-columns", "columns", Blt_Offset(DumpSwitches, ci), 0, 0, &columnIterSwitch}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(DumpSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; typedef struct { Blt_HashTable idTable; Tcl_Obj *fileObjPtr; Tcl_Obj *dataObjPtr; unsigned int flags; } RestoreSwitches; static Blt_SwitchSpec restoreSwitches[] = { {BLT_SWITCH_OBJ, "-data", "string", Blt_Offset(RestoreSwitches, dataObjPtr), 0, 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(RestoreSwitches, fileObjPtr), 0, 0}, {BLT_SWITCH_BITMASK, "-notags", "", Blt_Offset(RestoreSwitches, flags), 0, TABLE_RESTORE_NO_TAGS}, {BLT_SWITCH_BITMASK, "-overwrite", "", Blt_Offset(RestoreSwitches, flags), 0, TABLE_RESTORE_OVERWRITE}, {BLT_SWITCH_END} }; typedef struct { unsigned int flags; } SortSwitches; static Blt_SwitchSpec sortSwitches[] = { {BLT_SWITCH_BITMASK, "-decreasing", "", Blt_Offset(SortSwitches, flags), 0, SORT_DECREASING}, {BLT_SWITCH_BITMASK, "-list", "", Blt_Offset(SortSwitches, flags), 0, SORT_LIST}, {BLT_SWITCH_END} }; typedef struct { unsigned int flags; } NotifySwitches; static Blt_SwitchSpec notifySwitches[] = { {BLT_SWITCH_BITMASK, "-allevents", "", Blt_Offset(NotifySwitches, flags), 0, TABLE_NOTIFY_ALL_EVENTS}, {BLT_SWITCH_BITMASK, "-create", "", Blt_Offset(NotifySwitches, flags), 0, TABLE_NOTIFY_CREATE}, {BLT_SWITCH_BITMASK, "-delete", "", Blt_Offset(NotifySwitches, flags), 0, TABLE_NOTIFY_DELETE}, {BLT_SWITCH_BITMASK, "-move", "", Blt_Offset(NotifySwitches, flags), 0, TABLE_NOTIFY_MOVE}, {BLT_SWITCH_BITMASK, "-whenidle", "", Blt_Offset(NotifySwitches, flags), 0, TABLE_NOTIFY_WHENIDLE}, {BLT_SWITCH_END} }; typedef struct { Blt_Table table; /* Table to be evaluated */ Blt_TableRow row; /* Current row. */ Blt_HashTable varTable; /* Variable cache. */ Blt_TableIterator iter; /* Public values */ Tcl_Obj *emptyValueObjPtr; const char *tag; unsigned int flags; } FindSwitches; #define FIND_INVERT (1<<0) static Blt_SwitchSpec findSwitches[] = { {BLT_SWITCH_CUSTOM, "-rows", "rows", Blt_Offset(FindSwitches, iter), 0, 0, &rowIterSwitch}, {BLT_SWITCH_OBJ, "-emptyvalue", "string", Blt_Offset(FindSwitches, emptyValueObjPtr), 0}, {BLT_SWITCH_STRING, "-addtag", "tagName", Blt_Offset(FindSwitches, tag), 0}, {BLT_SWITCH_BITMASK, "-invert", "", Blt_Offset(FindSwitches, flags), 0, FIND_INVERT}, {BLT_SWITCH_END} }; typedef struct { int flags; } UniqueSwitches; static Blt_SwitchSpec uniqueSwitches[] = { {BLT_SWITCH_BITMASK, "-ascii", "", Blt_Offset(UniqueSwitches, flags), 0, SORT_ASCII}, {BLT_SWITCH_BITMASK, "-decreasing", "", Blt_Offset(SortSwitches, flags), 0, SORT_DECREASING}, {BLT_SWITCH_BITMASK, "-dictionary", "", Blt_Offset(UniqueSwitches, flags), 0, SORT_DICTIONARY}, {BLT_SWITCH_BITMASK, "-freq", "", Blt_Offset(UniqueSwitches, flags), 0, SORT_FREQUENCY}, {BLT_SWITCH_END} }; static Blt_TableTraceProc TraceProc; static Blt_TableTraceDeleteProc TraceDeleteProc; static Blt_TableNotifyEventProc NotifyProc; static Blt_TableNotifierDeleteProc NotifierDeleteProc; static Tcl_CmdDeleteProc TableInstDeleteProc; static Tcl_InterpDeleteProc TableInterpDeleteProc; static Tcl_ObjCmdProc TableInstObjCmd; static Tcl_ObjCmdProc TableObjCmd; typedef int (CmdProc)(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #ifdef notdef static int FirstOption(int objc, Tcl_Obj *const *objv, int start) { int i; for (i = start; i < objc; i++) { const char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } } return i; } #endif /* *--------------------------------------------------------------------------- * * PositionSwitch -- * * Convert a Tcl_Obj representing an offset in the table. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PositionSwitch( ClientData clientData, /* Flag indicating if the node is * considered before or after the * insertion position. */ Tcl_Interp *interp, /* Interpreter to report results. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Not used. */ int flags) /* Indicates whether this is a row or * column index. */ { InsertSwitches *insertPtr = (InsertSwitches *)record; Blt_Table table; table = insertPtr->cmdPtr->table; if (flags & INSERT_COL) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objPtr); if (col == NULL) { return TCL_ERROR; } if (clientData == INSERT_AFTER) { col = Blt_Table_NextColumn(table, col); } insertPtr->column = col; } else if (flags & INSERT_ROW) { Blt_TableRow row; row = Blt_Table_FindRow(interp, table, objPtr); if (row == NULL) { return TCL_ERROR; } if (clientData == INSERT_AFTER) { row = Blt_Table_NextRow(table, row); } insertPtr->row = row; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_ColumnIterFreeProc -- * * Free the storage associated with the -columns switch. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ void Blt_Table_ColumnIterFreeProc(char *record, int offset, int flags) { Blt_TableIterator *iterPtr = (Blt_TableIterator *)(record + offset); Blt_Table_FreeIteratorObjv(iterPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_ColumnIterSwitchProc -- * * Convert a Tcl_Obj representing an offset in the table. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_Table_ColumnIterSwitchProc( ClientData clientData, /* Flag indicating if the node is * considered before or after the * insertion position. */ Tcl_Interp *interp, /* Interpreter to report results. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_TableIterator *iterPtr = (Blt_TableIterator *)(record + offset); Blt_Table table; Tcl_Obj **objv; int objc; table = clientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (Blt_Table_IterateColumnsObjv(interp, table, objc, objv, iterPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreeRowIter -- * * Free the storage associated with the -rows switch. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ void Blt_Table_RowIterFreeProc(char *record, int offset, int flags) { Blt_TableIterator *iterPtr = (Blt_TableIterator *)(record + offset); Blt_Table_FreeIteratorObjv(iterPtr); } /* *--------------------------------------------------------------------------- * * RowIterSwitch -- * * Convert a Tcl_Obj representing an offset in the table. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_Table_RowIterSwitchProc( ClientData clientData, /* Flag indicating if the node is * considered before or after the * insertion position. */ Tcl_Interp *interp, /* Interpreter to report results. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_TableIterator *iterPtr = (Blt_TableIterator *)(record + offset); Blt_Table table; Tcl_Obj **objv; int objc; table = clientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (Blt_Table_IterateRowsObjv(interp, table, objc, objv, iterPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TableSwitchProc -- * * Convert a Tcl_Obj representing an offset in the table. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TableSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report result. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Table *tablePtr = (Blt_Table *)(record + offset); Blt_Table table; if (Blt_Table_Open(interp, Tcl_GetString(objPtr), &table) != TCL_OK) { return TCL_ERROR; } *tablePtr = table; return TCL_OK; } /* *--------------------------------------------------------------------------- * * TableFreeProc -- * * Free the storage associated with the -table switch. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void TableFreeProc(char *record, int offset, int flags) { Blt_Table table = *(Blt_Table *)(record + offset); Blt_Table_Close(table); } /* *--------------------------------------------------------------------------- * * TypeSwitchProc -- * * Convert a Tcl_Obj representing the type of the values in a table * column. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_TableColumnType *typePtr = (Blt_TableColumnType *)(record + offset); Blt_TableColumnType type; type = Blt_Table_GetColumnType(Tcl_GetString(objPtr)); if (type == TABLE_COLUMN_TYPE_UNKNOWN) { Tcl_AppendResult(interp, "unknown table column type \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_OK; } *typePtr = type; return TCL_OK; } static int MakeRows(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr) { const char *string; Blt_TableRowColumnSpec spec; long n; spec = Blt_Table_RowSpec(table, objPtr, &string); switch(spec) { case TABLE_SPEC_UNKNOWN: case TABLE_SPEC_LABEL: Tcl_ResetResult(interp); if (Blt_Table_CreateRow(interp, table, string) == NULL) { return TCL_ERROR; } break; case TABLE_SPEC_INDEX: Tcl_ResetResult(interp); if (Tcl_GetLong(interp, string, &n) != TCL_OK) { return TCL_ERROR; } n -= Blt_Table_NumRows(table); Blt_Table_ExtendRows(interp, table, n, NULL); break; default: return TCL_ERROR; } return TCL_OK; } static int CompareValueFreq(const void *a, const void *b) { const UniqueValue *fPtr1, *fPtr2; fPtr1 = a; fPtr2 = b; return (fPtr1->freq - fPtr2->freq); } static int CompareValueAscii(const void *a, const void *b) { const UniqueValue *fPtr1, *fPtr2; fPtr1 = a; fPtr2 = b; return strcmp(fPtr1->value, fPtr2->value); } static int CompareValueDictionary(const void *a, const void *b) { const UniqueValue *fPtr1, *fPtr2; fPtr1 = a; fPtr2 = b; return Blt_DictionaryCompare(fPtr1->value, fPtr2->value); } static Tcl_Obj * SortColumnValues(Tcl_Interp *interp, Blt_HashTable *tablePtr, int flags) { Blt_HashEntry *hPtr; Blt_HashSearch iter; QSortCompareProc *proc; Tcl_Obj *listObjPtr; UniqueValue *p, *pend, *array; long i; i = 0; array = Blt_Malloc(tablePtr->numEntries * sizeof(UniqueValue)); if (array == NULL) { return NULL; } p = array; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { p->value = Blt_GetHashKey(tablePtr, hPtr); p->freq = (long)Blt_GetHashValue(hPtr); p++; } switch (flags & SORT_TYPE_MASK) { case SORT_ASCII: proc = CompareValueAscii; break; case SORT_FREQUENCY: proc = CompareValueFreq; break; case SORT_DICTIONARY: proc = CompareValueDictionary; break; case SORT_NONE: proc = NULL; break; } if (proc != NULL) { qsort(array, tablePtr->numEntries, sizeof(UniqueValue), proc); } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (flags & SORT_DECREASING) { for (p = array + tablePtr->numEntries, pend = array; p > pend;) { Tcl_Obj *objPtr; p--; objPtr = Tcl_NewStringObj(p->value, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { for (p = array, pend = p + tablePtr->numEntries; p < pend; p++) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(p->value, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_Free(array); return listObjPtr; } static int IterateRows(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iterPtr) { if (Blt_Table_IterateRows(interp, table, objPtr, iterPtr) != TCL_OK) { /* * We could not parse the row descriptor. If the row specification is * a label or index that doesn't exist, create the new rows and try to * load the iterator again. */ if (MakeRows(interp, table, objPtr) != TCL_OK) { return TCL_ERROR; } if (Blt_Table_IterateRows(interp, table, objPtr, iterPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int MakeColumns(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr) { const char *string; Blt_TableRowColumnSpec spec; long n; spec = Blt_Table_ColumnSpec(table, objPtr, &string); switch(spec) { case TABLE_SPEC_UNKNOWN: case TABLE_SPEC_LABEL: Tcl_ResetResult(interp); if (Blt_Table_CreateColumn(interp, table, string) == NULL) { return TCL_ERROR; } break; case TABLE_SPEC_INDEX: Tcl_ResetResult(interp); if (Tcl_GetLong(interp, string, &n) != TCL_OK) { return TCL_ERROR; } n -= Blt_Table_NumColumns(table); Blt_Table_ExtendColumns(interp, table, n, NULL); break; default: return TCL_ERROR; } return TCL_OK; } static int IterateColumns(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iterPtr) { if (Blt_Table_IterateColumns(interp, table, objPtr, iterPtr) != TCL_OK) { /* * We could not parse column descriptor. If the column specification * is a label that doesn't exist, create a new column with that label * and try to load the iterator again. */ if (MakeColumns(interp, table, objPtr) != TCL_OK) { return TCL_ERROR; } if (Blt_Table_IterateColumns(interp, table, objPtr, iterPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetTableCmdInterpData -- * *--------------------------------------------------------------------------- */ static TableCmdInterpData * GetTableCmdInterpData(Tcl_Interp *interp) { TableCmdInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (TableCmdInterpData *) Tcl_GetAssocData(interp, TABLE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(TableCmdInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, TABLE_THREAD_KEY, TableInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->instTable, BLT_STRING_KEYS); Blt_InitHashTable(&dataPtr->fmtTable, BLT_STRING_KEYS); Blt_InitHashTable(&dataPtr->findTable, BLT_ONE_WORD_KEYS); } return dataPtr; } /* *--------------------------------------------------------------------------- * * NewTableCmd -- * * This is a helper routine used by TableCreateOp. It create a * new instance of a table command. Memory is allocated for the * command structure and a new TCL command is created (same as * the instance name). All table commands have hash table * entries in a global (interpreter-specific) registry. * * Results: * Returns a pointer to the newly allocated table command structure. * * Side Effects: * Memory is allocated for the structure and a hash table entry is * added. * *--------------------------------------------------------------------------- */ static Cmd * NewTableCmd(Tcl_Interp *interp, Blt_Table table, const char *name) { Cmd *cmdPtr; TableCmdInterpData *dataPtr; int isNew; cmdPtr = Blt_AssertCalloc(1, sizeof(Cmd)); cmdPtr->table = table; cmdPtr->interp = interp; cmdPtr->emptyValue = Blt_AssertStrdup(""); Blt_InitHashTable(&cmdPtr->traceTable, BLT_STRING_KEYS); Blt_InitHashTable(&cmdPtr->notifyTable, BLT_STRING_KEYS); cmdPtr->cmdToken = Tcl_CreateObjCommand(interp, name, TableInstObjCmd, cmdPtr, TableInstDeleteProc); dataPtr = GetTableCmdInterpData(interp); cmdPtr->tablePtr = &dataPtr->instTable; cmdPtr->hPtr = Blt_CreateHashEntry(&dataPtr->instTable, name, &isNew); Blt_SetHashValue(cmdPtr->hPtr, cmdPtr); return cmdPtr; } /* *--------------------------------------------------------------------------- * * GenerateName -- * * Generates an unique table command name. Table names are in the form * "datatableN", where N is a non-negative integer. Check each name * generated to see if it is already a table. We want to recycle names if * possible. * * Results: * Returns the unique name. The string itself is stored in the dynamic * string passed into the routine. * *--------------------------------------------------------------------------- */ static const char * GenerateName(Tcl_Interp *interp, const char *prefix, const char *suffix, Tcl_DString *resultPtr) { int n; const char *instName; /* * Parse the command and put back so that it's in a consistent format. * * t1 <current namespace>::t1 * n1::t1 <current namespace>::n1::t1 * ::t1 ::t1 * ::n1::t1 ::n1::t1 */ instName = NULL; /* Suppress compiler warning. */ for (n = 0; n < INT_MAX; n++) { Blt_ObjectName objName; Tcl_CmdInfo cmdInfo; Tcl_DString ds; char string[200]; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, prefix, -1); sprintf_s(string, 200, "datatable%d", n); Tcl_DStringAppend(&ds, string, -1); Tcl_DStringAppend(&ds, suffix, -1); if (!Blt_ParseObjectName(interp, Tcl_DStringValue(&ds), &objName, 0)) { return NULL; } instName = Blt_MakeQualifiedName(&objName, resultPtr); Tcl_DStringFree(&ds); /* * Check if the command already exists. */ if (Tcl_GetCommandInfo(interp, (char *)instName, &cmdInfo)) { continue; } if (!Blt_Table_TableExists(interp, instName)) { /* * We want the name of the table command and the underlying table * object to be the same. Check that the free command name isn't * an already a table object name. */ break; } } return instName; } /* *--------------------------------------------------------------------------- * * GetTableCmd -- * * Find the table command associated with the TCL command "string". * * We have to perform multiple lookups to get this right. * * The first step is to generate a canonical command name. If an * unqualified command name (i.e. no namespace qualifier) is given, we * should search first the current namespace and then the global one. * Most TCL commands (like Tcl_GetCmdInfo) look only at the global * namespace. * * Next check if the string is * a) a TCL command and * b) really is a command for a table object. * Tcl_GetCommandInfo will get us the objClientData field that should be * a cmdPtr. We verify that by searching our hashtable of cmdPtr * addresses. * * Results: * A pointer to the table command. If no associated table command can be * found, NULL is returned. It's up to the calling routines to generate * an error message. * *--------------------------------------------------------------------------- */ static Cmd * GetTableCmd(Tcl_Interp *interp, const char *name) { Blt_HashEntry *hPtr; Tcl_DString ds; TableCmdInterpData *dataPtr; Blt_ObjectName objName; const char *qualName; /* Put apart the table name and put is back together in a standard * format. */ if (!Blt_ParseObjectName(interp, name, &objName, BLT_NO_ERROR_MSG)) { return NULL; /* No such parent namespace. */ } /* Rebuild the fully qualified name. */ qualName = Blt_MakeQualifiedName(&objName, &ds); dataPtr = GetTableCmdInterpData(interp); hPtr = Blt_FindHashEntry(&dataPtr->instTable, qualName); Tcl_DStringFree(&ds); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * GetTraceFlags -- * * Parses a string representation of the trace bit flags and returns the * mask. * * Results: * The trace mask is returned. * *--------------------------------------------------------------------------- */ static int GetTraceFlags(const char *string) { const char *p; unsigned int flags; flags = 0; for (p = string; *p != '\0'; p++) { switch (toupper(UCHAR(*p))) { case 'R': flags |= TABLE_TRACE_READS; break; case 'W': flags |= TABLE_TRACE_WRITES; break; case 'U': flags |= TABLE_TRACE_UNSETS; break; case 'C': flags |= TABLE_TRACE_CREATES; break; default: return -1; } } return flags; } /* *--------------------------------------------------------------------------- * * PrintTraceFlags -- * * Generates a string representation of the trace bit flags. It's * assumed that the provided string is at least 5 bytes. * * Results: * None. * * Side Effects: * The bitflag information is written to the provided string. * *--------------------------------------------------------------------------- */ static void PrintTraceFlags(unsigned int flags, char *string) { char *p; p = string; if (flags & TABLE_TRACE_READS) { *p++ = 'r'; } if (flags & TABLE_TRACE_WRITES) { *p++ = 'w'; } if (flags & TABLE_TRACE_UNSETS) { *p++ = 'u'; } if (flags & TABLE_TRACE_CREATES) { *p++ = 'c'; } *p = '\0'; } static void PrintTraceInfo(Tcl_Interp *interp, TraceInfo *tiPtr, Tcl_Obj *listObjPtr) { Tcl_Obj *objPtr; int i; char string[5]; struct _Blt_TableTrace *tracePtr; Blt_Table table; table = tiPtr->cmdPtr->table; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("id", 2)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tiPtr->hPtr->key.string, -1)); tracePtr = tiPtr->trace; if (tracePtr->rowTag != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("row", 3)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tracePtr->rowTag, -1)); } if (tracePtr->row != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("row", 3)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(Blt_Table_RowIndex(tracePtr->row))); } if (tracePtr->colTag != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("column", 6)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(tracePtr->colTag, -1)); } if (tracePtr->column != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("column", 6)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(Blt_Table_ColumnIndex(tracePtr->column))); } PrintTraceFlags(tracePtr->flags, string); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("flags", 5)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(string, -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("command", 7)); objPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (i = 0; i < tiPtr->cmdc; i++) { Tcl_ListObjAppendElement(interp, objPtr, tiPtr->cmdv[i]); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } /* *--------------------------------------------------------------------------- * * FreeNotifierInfo -- * * This is a helper routine used to delete notifiers. It releases the * Tcl_Objs used in the notification callback command and the actual * table notifier. Memory for the notifier is also freed. * * Results: * None. * * Side Effects: * Memory is deallocated and the notitifer is no longer active. * *--------------------------------------------------------------------------- */ static void FreeNotifierInfo(NotifierInfo *niPtr) { int i; for (i = 0; i < niPtr->cmdc; i++) { Tcl_DecrRefCount(niPtr->cmdv[i]); } Blt_Table_DeleteNotifier(niPtr->notifier); Blt_Free(niPtr->cmdv); Blt_Free(niPtr); } /* *--------------------------------------------------------------------------- * * TraceProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceProc(ClientData clientData, Blt_TableTraceEvent *eventPtr) { TraceInfo *tracePtr = clientData; char string[5]; int result; int i; i = tracePtr->cmdc; /* Add extra command arguments starting at * this index. */ tracePtr->cmdv[i+1]=Tcl_NewLongObj(Blt_Table_RowIndex(eventPtr->row)); tracePtr->cmdv[i+2]=Tcl_NewLongObj(Blt_Table_ColumnIndex(eventPtr->column)); PrintTraceFlags(eventPtr->mask, string); tracePtr->cmdv[i+3] = Tcl_NewStringObj(string, -1); Tcl_IncrRefCount(tracePtr->cmdv[i+1]); Tcl_IncrRefCount(tracePtr->cmdv[i+2]); Tcl_IncrRefCount(tracePtr->cmdv[i+3]); result = Tcl_EvalObjv(eventPtr->interp, i + 4, tracePtr->cmdv, 0); Tcl_DecrRefCount(tracePtr->cmdv[i+3]); Tcl_DecrRefCount(tracePtr->cmdv[i+2]); Tcl_DecrRefCount(tracePtr->cmdv[i+1]); if (result != TCL_OK) { Tcl_BackgroundError(eventPtr->interp); } return result; } /* *--------------------------------------------------------------------------- * * TraceDeleteProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void TraceDeleteProc(ClientData clientData) { TraceInfo *tiPtr = clientData; int i; for (i = 0; i <= tiPtr->cmdc; i++) { Tcl_DecrRefCount(tiPtr->cmdv[i]); } Blt_Free(tiPtr->cmdv); if (tiPtr->hPtr != NULL) { Blt_DeleteHashEntry(tiPtr->tablePtr, tiPtr->hPtr); } Blt_Free(tiPtr); } static const char * GetEventName(int type) { if (type & TABLE_NOTIFY_CREATE) { return "-create"; } if (type & TABLE_NOTIFY_DELETE) { return "-delete"; } if (type & TABLE_NOTIFY_MOVE) { return "-move"; } return "???"; } /* *--------------------------------------------------------------------------- * * NotifierDeleteProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void NotifierDeleteProc(ClientData clientData) { NotifierInfo *niPtr; niPtr = clientData; FreeNotifierInfo(niPtr); } /* *--------------------------------------------------------------------------- * * NotifyProc -- * *--------------------------------------------------------------------------- */ static int NotifyProc(ClientData clientData, Blt_TableNotifyEvent *eventPtr) { NotifierInfo *niPtr; Tcl_Interp *interp; int i, result; long index; niPtr = clientData; interp = niPtr->cmdPtr->interp; i = niPtr->cmdc; niPtr->cmdv[i] = Tcl_NewStringObj(GetEventName(eventPtr->type), -1); if (eventPtr->type & TABLE_NOTIFY_ROW) { index = Blt_Table_RowIndex(eventPtr->header); } else { index = Blt_Table_ColumnIndex(eventPtr->header); } niPtr->cmdv[i+1] = Tcl_NewLongObj(index); Tcl_IncrRefCount(niPtr->cmdv[i]); Tcl_IncrRefCount(niPtr->cmdv[i+1]); Tcl_IncrRefCount(niPtr->cmdv[i+2]); result = Tcl_EvalObjv(interp, niPtr->cmdc + 3, niPtr->cmdv, 0); Tcl_DecrRefCount(niPtr->cmdv[i+2]); Tcl_DecrRefCount(niPtr->cmdv[i+1]); Tcl_DecrRefCount(niPtr->cmdv[i]); if (result != TCL_OK) { Tcl_BackgroundError(interp); return TCL_ERROR; } Tcl_ResetResult(interp); return TCL_OK; } static int ColumnVarResolver( Tcl_Interp *interp, /* Current interpreter. */ const char *name, /* Variable name being resolved. */ Tcl_Namespace *nsPtr, /* Current namespace context. */ int flags, /* TCL_LEAVE_ERR_MSG => leave error * message. */ Tcl_Var *varPtr) /* (out) Resolved variable. */ { Blt_HashEntry *hPtr; Blt_TableColumn col; FindSwitches *findPtr; TableCmdInterpData *dataPtr; Tcl_Interp *errInterp; Tcl_Obj *valueObjPtr, *nameObjPtr; dataPtr = GetTableCmdInterpData(interp); hPtr = Blt_FindHashEntry(&dataPtr->findTable, nsPtr); if (hPtr == NULL) { /* This should never happen. We can't find in data associated with * the current namespace. But this routine should never be called * unless we're in a namespace that with linked with this variable * resolver. */ return TCL_CONTINUE; } findPtr = Blt_GetHashValue(hPtr); if (flags & TCL_LEAVE_ERR_MSG) { errInterp = interp; } else { errInterp = NULL; } /* Look up the column from the variable name given. */ nameObjPtr = Tcl_NewStringObj(name, -1); col = Blt_Table_FindColumn(NULL, findPtr->table, nameObjPtr); Tcl_DecrRefCount(nameObjPtr); if (col == NULL) { /* Variable name doesn't refer to any column. Pass it back to the Tcl * interpreter and let it resolve it normally. */ return TCL_CONTINUE; } valueObjPtr = Blt_Table_GetObj(findPtr->table, findPtr->row, col); if (valueObjPtr == NULL) { valueObjPtr = findPtr->emptyValueObjPtr; if (valueObjPtr == NULL) { return TCL_CONTINUE; } } Tcl_IncrRefCount(valueObjPtr); *varPtr = Blt_GetCachedVar(&findPtr->varTable, name, valueObjPtr); return TCL_OK; } static int EvaluateExpr(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *exprObjPtr, FindSwitches *findPtr, int *boolPtr) { Tcl_Obj *resultObjPtr; int bool; if (Tcl_ExprObj(interp, exprObjPtr, &resultObjPtr) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, resultObjPtr, &bool) != TCL_OK) { return TCL_ERROR; } if (findPtr->flags & FIND_INVERT) { bool = !bool; } if ((bool) && (findPtr->tag != NULL)) { Blt_Table_SetRowTag(interp, table, findPtr->row, findPtr->tag); } Tcl_DecrRefCount(resultObjPtr); *boolPtr = bool; return TCL_OK; } static int FindRows(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, FindSwitches *findPtr) { Blt_HashEntry *hPtr; TableCmdInterpData *dataPtr; Tcl_CallFrame frame; Tcl_Namespace *nsPtr; const char *name; int isNew; int result = TCL_OK; name = Blt_Table_TableName(table); nsPtr = Tcl_FindNamespace(interp, name, NULL, TCL_GLOBAL_ONLY); if (nsPtr != NULL) { /* This limits us to only one expression evaluated per table at a * time--no concurrent expressions in the same table. Otherwise we * need to generate unique namespace names. That's a bit harder with * the current TCL namespace API. */ Tcl_AppendResult(interp, "can't evaluate expression: namespace \"", name, "\" exists.", (char *)NULL); return TCL_ERROR; } /* Create a namespace from which to evaluate the expression. */ nsPtr = Tcl_CreateNamespace(interp, name, NULL, NULL); if (nsPtr == NULL) { return TCL_ERROR; } /* Register our variable resolver in this namespace to link table values * with TCL variables. */ Tcl_SetNamespaceResolvers(nsPtr, (Tcl_ResolveCmdProc*)NULL, ColumnVarResolver, (Tcl_ResolveCompiledVarProc*)NULL); /* Make this namespace the current one. */ Tcl_PushCallFrame(interp, &frame, nsPtr, /* isProcCallFrame */ FALSE); dataPtr = GetTableCmdInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->findTable, (char *)nsPtr, &isNew); assert(isNew); Blt_SetHashValue(hPtr, findPtr); /* Now process each row, evaluating the expression. */ { Blt_TableRow row; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (row = Blt_Table_FirstTaggedRow(&findPtr->iter); row != NULL; row = Blt_Table_NextTaggedRow(&findPtr->iter)) { int bool; findPtr->row = row; result = EvaluateExpr(interp, table, objPtr, findPtr, &bool); if (result != TCL_OK) { break; } if (bool) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(Blt_Table_RowIndex(row))); } } if (result != TCL_OK) { Tcl_DecrRefCount(listObjPtr); } else { Tcl_SetObjResult(interp, listObjPtr); } } /* Clean up. */ Tcl_PopCallFrame(interp); Tcl_DeleteNamespace(nsPtr); Blt_DeleteHashEntry(&dataPtr->findTable, hPtr); Blt_FreeCachedVars(&findPtr->varTable); return result; } static int CopyColumn(Tcl_Interp *interp, Blt_Table srcTable, Blt_Table destTable, Blt_TableColumn src, /* Column in the source table. */ Blt_TableColumn dest) /* Column in the destination table. */ { long i; if ((Blt_Table_SameTableObject(srcTable, destTable)) && (src == dest)) { return TCL_OK; /* Source and destination are the same. */ } if (Blt_Table_NumRows(srcTable) > Blt_Table_NumRows(destTable)) { long need; need = (Blt_Table_NumRows(srcTable) - Blt_Table_NumRows(destTable)); if (Blt_Table_ExtendRows(interp, destTable, need, NULL) != TCL_OK) { return TCL_ERROR; } } Blt_Table_SetColumnType(destTable, dest, Blt_Table_ColumnType(src)); for (i = 1; i <= Blt_Table_NumRows(srcTable); i++) { Blt_TableRow row; Blt_TableValue value; row = Blt_Table_Row(srcTable, i); value = Blt_Table_GetValue(srcTable, row, src); if (value == NULL) { continue; } row = Blt_Table_Row(destTable, i); if (Blt_Table_SetValue(destTable, row, dest, value) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static void CopyColumnTags(Blt_Table srcTable, Blt_Table destTable, Blt_TableColumn src, /* Column in the source table. */ Blt_TableColumn dest) /* Column in the destination table. */ { Blt_HashEntry *hPtr; Blt_HashSearch iter; /* Find all tags for with this column index. */ for (hPtr = Blt_Table_FirstColumnTag(srcTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)src); if (h2Ptr != NULL) { /* We know the tag tables are keyed by strings, so we don't need * to call Blt_GetHashKey or use the hash table pointer to * retrieve the key. */ Blt_Table_SetColumnTag(NULL, destTable, dest, hPtr->key.string); } } } /************* Column Operations ****************/ /* *--------------------------------------------------------------------------- * * ColumnCopyOp -- * * Copies the specified columns to the table. A different table may be * selected as the source. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $dest column copy $srccol $destcol ?-table srcTable? * *--------------------------------------------------------------------------- */ static int ColumnCopyOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CopySwitches switches; Blt_Table srcTable, destTable; int result; Blt_TableColumn src, dest; /* Process switches following the column names. */ memset(&switches, 0, sizeof(switches)); result = TCL_ERROR; if (Blt_ParseSwitches(interp, copySwitches, objc - 5, objv + 5, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } srcTable = destTable = cmdPtr->table; if (switches.table != NULL) { srcTable = switches.table; } src = Blt_Table_FindColumn(interp, srcTable, objv[3]); if (src == NULL) { goto error; } dest = Blt_Table_FindColumn(interp, destTable, objv[4]); if (dest == NULL) { dest = Blt_Table_CreateColumn(interp, destTable, Tcl_GetString(objv[4])); if (dest == NULL) { goto error; } } if (CopyColumn(interp, srcTable, destTable, src, dest) != TCL_OK) { goto error; } if ((switches.flags & COPY_NOTAGS) == 0) { CopyColumnTags(srcTable, destTable, src, dest); } result = TCL_OK; error: Blt_FreeSwitches(copySwitches, &switches, 0); return result; } /* *--------------------------------------------------------------------------- * * ColumnDeleteOp -- * * Deletes the columns designated. One or more columns may be deleted * using a tag. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column delete ?column?... * *--------------------------------------------------------------------------- */ static int ColumnDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Blt_TableColumn col; int result; result = TCL_ERROR; if (Blt_Table_IterateColumnsObjv(interp, cmdPtr->table, objc - 3, objv + 3, &iter) != TCL_OK) { return TCL_ERROR; } /* * Walk through the list of column offsets, deleting each column. */ for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (Blt_Table_DeleteColumn(cmdPtr->table, col) != TCL_OK) { goto error; } } result = TCL_OK; error: Blt_Table_FreeIteratorObjv(&iter); return result; } /* *--------------------------------------------------------------------------- * * ColumnDupOp -- * * Duplicates the specified columns in the table. This differs from * ColumnCopyOp, since the same table is the source and destination. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $dest column dup column... * *--------------------------------------------------------------------------- */ static int ColumnDupOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Tcl_Obj *listObjPtr; Blt_TableIterator iter; Blt_TableColumn src; table = cmdPtr->table; listObjPtr = NULL; if (Blt_Table_IterateColumnsObjv(interp, table, objc - 3, objv + 3, &iter) != TCL_OK) { goto error; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (src = Blt_Table_FirstTaggedColumn(&iter); src != NULL; src = Blt_Table_NextTaggedColumn(&iter)) { long i; Blt_TableColumn dest; dest = Blt_Table_CreateColumn(interp, table,Blt_Table_ColumnLabel(src)); if (dest == NULL) { goto error; } if (CopyColumn(interp, table, table, src, dest) != TCL_OK) { goto error; } CopyColumnTags(table, table, src, dest); i = Blt_Table_ColumnIndex(dest); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(i)); } Blt_Table_FreeIteratorObjv(&iter); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: Blt_Table_FreeIteratorObjv(&iter); if (listObjPtr != NULL) { Tcl_DecrRefCount(listObjPtr); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ColumnExistsOp -- * * Indicates is the given column exists. The column description can be * either an index, label, or single tag. * * Problem: The Blt_Table_IterateColumns function checks both for * 1) valid/invalid indices, labels, and tags and 2) * syntax errors. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column exists n * *--------------------------------------------------------------------------- */ static int ColumnExistsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableColumn col; int bool; col = Blt_Table_FindColumn(NULL, cmdPtr->table, objv[3]); bool = (col != NULL); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnExtendOp -- * * Extends the table by the given number of columns. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column extend n * *--------------------------------------------------------------------------- */ static int ColumnExtendOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Tcl_Obj *listObjPtr; Blt_TableColumn *cols; long i, n; int addLabels; table = cmdPtr->table; if (objc == 3) { return TCL_OK; } n = 0; addLabels = FALSE; if (objc == 4) { long lcount; if (Tcl_GetLongFromObj(NULL, objv[3], &lcount) == TCL_OK) { if (lcount < 0) { Tcl_AppendResult(interp, "bad count \"", Blt_Itoa(lcount), "\": # columns can't be negative.", (char *)NULL); return TCL_ERROR; } n = lcount; } else { addLabels = TRUE; n = 1; } } else { addLabels = TRUE; n = objc - 3; } if (n == 0) { return TCL_OK; } cols = Blt_AssertMalloc(n * sizeof(Blt_TableColumn)); if (Blt_Table_ExtendColumns(interp, table, n, cols) != TCL_OK) { goto error; } if (addLabels) { long j; for (i = 0, j = 3; i < n; i++, j++) { if (Blt_Table_SetColumnLabel(interp, table, cols[i], Tcl_GetString(objv[j])) != TCL_OK) { goto error; } } } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (i = 0; i < n; i++) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Table_ColumnIndex(cols[i])); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(cols); return TCL_OK; error: Blt_Free(cols); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ColumnGetOp -- * * Retrieves a column of values. The column argument can be either a * tag, label, or column index. If it is a tag, it must refer to exactly * one column. If row arguments exist they must refer to label or row. * We always return the row label. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the column index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t column get -labels $c ?row...? * *--------------------------------------------------------------------------- */ static int ColumnGetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableColumn col; Tcl_Obj *listObjPtr; const char *string; int needLabels; string = Tcl_GetString(objv[3]); needLabels = FALSE; if (strcmp(string, "-labels") == 0) { objv++, objc--; needLabels = TRUE; } table = cmdPtr->table; col = Blt_Table_FindColumn(interp, cmdPtr->table, objv[3]); if (col == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 4) { Blt_TableRow row; for (row = Blt_Table_FirstRow(cmdPtr->table); row != NULL; row = Blt_Table_NextRow(cmdPtr->table, row)) { Tcl_Obj *objPtr; if (needLabels) { objPtr = Tcl_NewStringObj(Blt_Table_RowLabel(row), -1); } else { objPtr = Tcl_NewLongObj(Blt_Table_RowIndex(row)); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Blt_Table_GetObj(cmdPtr->table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_TableIterator iter; Blt_TableRow row; if (Blt_Table_IterateRowsObjv(interp, table, objc - 4, objv + 4, &iter) != TCL_OK) { return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Tcl_Obj *objPtr; if (needLabels) { objPtr = Tcl_NewStringObj(Blt_Table_RowLabel(row), -1); } else { objPtr = Tcl_NewLongObj(Blt_Table_RowIndex(row)); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Blt_Table_GetObj(cmdPtr->table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnIndexOp -- * * Returns the column index of the given column tag, label, or index. A * tag can't represent more than one column. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column index $column * *--------------------------------------------------------------------------- */ static int ColumnIndexOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableColumn col; long i; i = -1; col = Blt_Table_FindColumn(NULL, cmdPtr->table, objv[3]); if (col != NULL) { i = Blt_Table_ColumnIndex(col); } Tcl_SetLongObj(Tcl_GetObjResult(interp), i); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnIndicesOp -- * * Returns a list of indices for the given columns. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column indices $col $col * *--------------------------------------------------------------------------- */ static int ColumnIndicesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Blt_TableIterator iter; Blt_TableColumn col; if (Blt_Table_IterateColumnsObjv(interp, cmdPtr->table, objc - 3, objv + 3, &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Table_ColumnIndex(col)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Blt_Table_FreeIteratorObjv(&iter); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnCreateOp -- * * Creates a single new column in the table. The location of the new * column may be specified by -before or -after switches. By default the * new column is added to the end of the table. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column create -before 0 -after 1 -label label * *--------------------------------------------------------------------------- */ static int ColumnCreateOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { InsertSwitches switches; Blt_TableColumn col; unsigned int flags; memset(&switches, 0, sizeof(switches)); switches.cmdPtr = cmdPtr; switches.type = TABLE_COLUMN_TYPE_STRING; flags = INSERT_COL; if (Blt_ParseSwitches(interp, insertSwitches, objc - 3, objv + 3, &switches, flags) < 0) { goto error; } col = Blt_Table_CreateColumn(interp, cmdPtr->table, switches.label); if (col == NULL) { goto error; } Blt_Table_SetColumnType(cmdPtr->table, col, switches.type); if (switches.column != NULL) { if (Blt_Table_MoveColumns(interp, cmdPtr->table, col, switches.column, 1) != TCL_OK) { goto error; } } if (switches.tags != NULL) { Tcl_Obj **elv; int elc; int i; if (Tcl_ListObjGetElements(interp, switches.tags, &elc, &elv) != TCL_OK) { goto error; } for (i = 0; i < elc; i++) { if (Blt_Table_SetColumnTag(interp, cmdPtr->table, col, Tcl_GetString(elv[i])) != TCL_OK) { goto error; } } } Tcl_SetObjResult(interp, Tcl_NewLongObj(Blt_Table_ColumnIndex(col))); Blt_FreeSwitches(insertSwitches, &switches, flags); return TCL_OK; error: Blt_FreeSwitches(insertSwitches, &switches, flags); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ColumnLabelOp -- * * Gets/sets one or more column labels. * * Results: * A standard TCL result. If successful, the old column label is * returned in the interpreter result. If the column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column label column ?label? ?column label? * $t column label 1 * $t column label 1 newLabel * $t column label 1 lab1 2 lab2 3 lab3 5 lab5 * *--------------------------------------------------------------------------- */ static int ColumnLabelOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; table = cmdPtr->table; if (objc == 4) { const char *label; Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[3]); if (col == NULL) { return TCL_ERROR; } label = Blt_Table_ColumnLabel(col); Tcl_SetStringObj(Tcl_GetObjResult(interp), label, -1); } else { int i; if ((objc - 3) & 1) { Tcl_AppendResult(interp,"odd # of column/label pairs: should be \"", Tcl_GetString(objv[0]), " column label ?column label?...", (char *)NULL); return TCL_ERROR; } for (i = 3; i < objc; i += 2) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[i]); if (col == NULL) { return TCL_ERROR; } if (Blt_Table_SetColumnLabel(interp, table, col, Tcl_GetString(objv[i+1])) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnLabelsOp -- * * Gets/sets all the column labels in the table. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. * * Example: * $t column labels ?labelList? * *--------------------------------------------------------------------------- */ static int ColumnLabelsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; table = cmdPtr->table; if (objc == 3) { Blt_TableColumn col; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (col = Blt_Table_FirstColumn(cmdPtr->table); col != NULL; col = Blt_Table_NextColumn(cmdPtr->table, col)) { const char *label; Tcl_Obj *objPtr; label = Blt_Table_ColumnLabel(col); objPtr = Tcl_NewStringObj(label, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_Obj **elv; int elc, n; int i; if (Tcl_ListObjGetElements(interp, objv[3], &elc, &elv) != TCL_OK) { return TCL_ERROR; } n = MIN(elc, Blt_Table_NumColumns(table)); for (i = 0; i < n; i++) { Blt_TableColumn col; col = Blt_Table_Column(table, i + 1); if (Blt_Table_SetColumnLabel(interp, table, col, Tcl_GetString(elv[i])) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnLengthOp -- * * Returns the number of columns the client sees. * * Results: * A standard TCL result. If successful, the old column label is * returned in the interpreter result. If the column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column length * *--------------------------------------------------------------------------- */ static int ColumnLengthOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Table_NumColumns(cmdPtr->table)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnMoveOp -- * * Moves the given number of columns to another location in the table. * * Results: * A standard TCL result. If the column index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t column move from to ?n? * *--------------------------------------------------------------------------- */ static int ColumnMoveOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableColumn from, to; long count; from = Blt_Table_FindColumn(interp, cmdPtr->table, objv[3]); if (from == NULL) { return TCL_ERROR; } to = Blt_Table_FindColumn(interp, cmdPtr->table, objv[4]); if (to == NULL) { return TCL_ERROR; } count = 1; if (objc == 6) { long lcount; if (Tcl_GetLongFromObj(interp, objv[5], &lcount) != TCL_OK) { return TCL_ERROR; } if (lcount == 0) { return TCL_OK; } if (lcount < 0) { Tcl_AppendResult(interp, "can't move columns: # of columns can't be negative", (char *)NULL); return TCL_ERROR; } count = lcount; } return Blt_Table_MoveColumns(interp, cmdPtr->table, from, to, count); } /* *--------------------------------------------------------------------------- * * ColumnNamesOp -- * * Reports the labels of all columns. * * Results: * Always returns TCL_OK. The interpreter result is a list of column * labels. * * Example: * $t column names pattern * *--------------------------------------------------------------------------- */ static int ColumnNamesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Blt_TableColumn col; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (col = Blt_Table_FirstColumn(cmdPtr->table); col != NULL; col = Blt_Table_NextColumn(cmdPtr->table, col)) { const char *label; int match; int i; label = Blt_Table_ColumnLabel(col); match = (objc == 3); for (i = 3; i < objc; i++) { char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(label, pattern)) { match = TRUE; break; } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(label, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnNotifyOp -- * * Creates a notifier for this instance. Notifiers represent a bitmask * of events and a command prefix to be invoked when a matching event * occurs. * * The command prefix is parsed and saved in an array of Tcl_Objs. Extra * slots are allocated for the * * Results: * A standard TCL result. The name of the new notifier is returned in * the interpreter result. Otherwise, if it failed to parse a switch, * then TCL_ERROR is returned and an error message is left in the * interpreter result. * * Example: * table0 column notify col ?flags? command arg * *--------------------------------------------------------------------------- */ static int ColumnNotifyOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableColumn col; Blt_TableRowColumnSpec spec; NotifierInfo *niPtr; NotifySwitches switches; const char *tag, *string; int count, i; int nArgs; table = cmdPtr->table; spec = Blt_Table_ColumnSpec(table, objv[3], &string); col = NULL; tag = NULL; if (spec == TABLE_SPEC_TAG) { tag = string; } else { col = Blt_Table_FindColumn(interp, table, objv[3]); if (col == NULL) { return TCL_ERROR; } } count = 0; for (i = 4; i < objc; i++) { const char *string; string = Tcl_GetString(objv[i]); if (string[0] != '-') { break; } count++; } switches.flags = 0; /* Process switches */ if (Blt_ParseSwitches(interp, notifySwitches, count, objv + 4, &switches, 0) < 0) { return TCL_ERROR; } niPtr = Blt_AssertMalloc(sizeof(NotifierInfo)); niPtr->cmdPtr = cmdPtr; if (tag == NULL) { niPtr->notifier = Blt_Table_CreateColumnNotifier(interp, cmdPtr->table, col, switches.flags, NotifyProc, NotifierDeleteProc, niPtr); } else { niPtr->notifier = Blt_Table_CreateColumnTagNotifier(interp, cmdPtr->table, tag, switches.flags, NotifyProc, NotifierDeleteProc, niPtr); } nArgs = (objc - i) + 2; /* Stash away the command in structure and pass that to the notifier. */ niPtr->cmdv = Blt_AssertMalloc(nArgs * sizeof(Tcl_Obj *)); for (count = 0; i < objc; i++, count++) { Tcl_IncrRefCount(objv[i]); niPtr->cmdv[count] = objv[i]; } niPtr->cmdc = nArgs; if (switches.flags == 0) { switches.flags = TABLE_NOTIFY_ALL_EVENTS; } { char notifyId[200]; Blt_HashEntry *hPtr; int isNew; sprintf_s(notifyId, 200, "notify%d", cmdPtr->nextNotifyId++); hPtr = Blt_CreateHashEntry(&cmdPtr->notifyTable, notifyId, &isNew); assert(isNew); Blt_SetHashValue(hPtr, niPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), notifyId, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnSetOp -- * * Sets one of values in a column. One or more columns may be set using * a tag. The row order is always the table's current view of the table. * There may be less values than needed. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column set $column a 1 b 2 c 3 * *--------------------------------------------------------------------------- */ static int ColumnSetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Blt_TableColumn col; Blt_Table table; table = cmdPtr->table; /* May set more than one row with the same values. */ if (IterateColumns(interp, table, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { return TCL_OK; } if ((objc - 4) & 1) { Tcl_AppendResult(interp, "odd # of row/value pairs: should be \"", Tcl_GetString(objv[0]), " column assign col row value...", (char *)NULL); return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { long i; /* The remaining arguments are index/value pairs. */ for (i = 4; i < objc; i += 2) { Blt_TableRow row; row = Blt_Table_FindRow(interp, table, objv[i]); if (row == NULL) { /* Can't find the row. Create it and try to find it again. */ if (MakeRows(interp, table, objv[i]) != TCL_OK) { return TCL_ERROR; } row = Blt_Table_FindRow(interp, table, objv[i]); } if (Blt_Table_SetObj(table, row, col, objv[i+1]) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagAddOp -- * * Adds a given tag to one or more columns. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all" or "end"). * * .t column tag add tag ?column...? * *--------------------------------------------------------------------------- */ static int ColumnTagAddOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; const char *tagName; table = cmdPtr->table; tagName = Tcl_GetString(objv[4]); if (Blt_Table_SetColumnTag(interp, table, NULL, tagName) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { Blt_TableColumn col; Blt_TableIterator iter; if (Blt_Table_IterateColumns(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (Blt_Table_SetColumnTag(interp, table, col, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagDeleteOp -- * * Removes a given tag from one or more columns. If a tag doesn't exist or * is a reserved tag ("all" or "end"), nothing will be done and no error * message will be returned. * * .t column tag delete tag ?column...? * *--------------------------------------------------------------------------- */ static int ColumnTagDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; const char *tagName; table = cmdPtr->table; tagName = Tcl_GetString(objv[4]); for (i = 5; i < objc; i++) { Blt_TableColumn col; if (Blt_Table_IterateColumns(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (Blt_Table_UnsetColumnTag(interp, table, col, tagName)!=TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagExistsOp -- * * Returns the existence of a tag in the table. If a column is * specified then the tag is search for for that column. * * .t tag column exists tag ?column? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnTagExistsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; const char *tagName; Blt_Table table; tagName = Tcl_GetString(objv[3]); table = cmdPtr->table; bool = (Blt_Table_FindColumnTagTable(table, tagName) != NULL); if (objc == 5) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[4]); if (col == NULL) { bool = FALSE; } else { bool = Blt_Table_HasColumnTag(table, col, tagName); } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagForgetOp -- * * Removes the given tags from all nodes. * * Example: * $t column tag forget tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnTagForgetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 4; i < objc; i++) { if (Blt_Table_ForgetColumnTag(interp, cmdPtr->table, Tcl_GetString(objv[i])) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagGetOp -- * * Returns the tag names for a given column. If one of more pattern * arguments are provided, then only those matching tags are returned. * * .t column tag get column pat1 pat2... * *--------------------------------------------------------------------------- */ static int ColumnTagGetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch hsearch; Blt_HashTable tagTable; Blt_Table table; Blt_TableColumn col; Blt_TableIterator iter; Tcl_Obj *listObjPtr; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Blt_InitHashTable(&tagTable, BLT_STRING_KEYS); /* Collect all the tags into a hash table. */ for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_Table_ColumnTags(table, col); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { const char *tagName; int isNew; tagName = Blt_Chain_GetValue(link); Blt_CreateHashEntry(&tagTable, tagName, &isNew); } Blt_Chain_Destroy(chain); } for (hPtr = Blt_FirstHashEntry(&tagTable, &hsearch); hPtr != NULL; hPtr = Blt_NextHashEntry(&hsearch)) { int match; const char *tagName; tagName = Blt_GetHashKey(&tagTable, hPtr); match = TRUE; if (objc > 5) { int i; match = FALSE; for (i = 5; i < objc; i++) { if (Tcl_StringMatch(tagName, Tcl_GetString(objv[i]))) { match = TRUE; } } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_DeleteHashTable(&tagTable); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static unsigned char * GetColumnTagMatches(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv) { long nCols; int i; unsigned char *matches; nCols = Blt_Table_NumColumns(table); matches = Blt_AssertCalloc(nCols + 1, sizeof(unsigned char)); /* Handle the reserved tags "all" or "end". */ for (i = 0; i < objc; i++) { char *tagName; long j; tagName = Tcl_GetString(objv[i]); if (strcmp("all", tagName) == 0) { for (j = 1; j <= nCols; j++) { matches[j] = TRUE; } return matches; /* Don't care other tags. */ } if (strcmp("end", tagName) == 0) { matches[nCols] = TRUE; } } /* Now check user-defined tags. */ for (i = 0; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_HashTable *tagTablePtr; const char *tagName; tagName = Tcl_GetString(objv[i]); if ((strcmp("all", tagName) == 0) || (strcmp("end", tagName) == 0)) { continue; } tagTablePtr = Blt_Table_FindColumnTagTable(table, tagName); if (tagTablePtr == NULL) { Tcl_AppendResult(interp, "unknown column tag \"", tagName, "\"", (char *)NULL); Blt_Free(matches); return NULL; } for (hPtr = Blt_FirstHashEntry(tagTablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TableColumn col; long j; col = Blt_GetHashValue(hPtr); j = Blt_Table_ColumnIndex(col); assert(j >= 0); matches[j] = TRUE; } } return matches; } /* *--------------------------------------------------------------------------- * * ColumnTagIndicesOp -- * * Returns column indices names for the given tags. If one of more tag * names are provided, then only those matching indices are returned. * * Example: * .t column tag indices tag1 tag2... * *--------------------------------------------------------------------------- */ static int ColumnTagIndicesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; long j; long nCols; unsigned char *matches; matches = GetColumnTagMatches(interp, cmdPtr->table, objc - 4, objv + 4); if (matches == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); nCols = Blt_Table_NumColumns(cmdPtr->table); for (j = 1; j <= nCols; j++) { if (matches[j]) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(j)); } } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(matches); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagLabelsOp -- * * Returns column labels for the given tags. If one of more tag * names are provided, then only those matching indices are returned. * * Example: * .t column tag labels tag1 tag2... * *--------------------------------------------------------------------------- */ static int ColumnTagLabelsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; long j; long nCols; unsigned char *matches; matches = GetColumnTagMatches(interp, cmdPtr->table, objc - 4, objv + 4); if (matches == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); nCols = Blt_Table_NumColumns(cmdPtr->table); for (j = 1; j <= nCols; j++) { if (matches[j]) { Blt_TableColumn col; Tcl_Obj *objPtr; col = Blt_Table_Column(cmdPtr->table, j); objPtr = Tcl_NewStringObj(Blt_Table_ColumnLabel(col), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(matches); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagRangeOp -- * * Adds one or more tags for a given column. Tag names can't start with * a digit (to distinquish them from node ids) and can't be a reserved * tag ("all" or "end"). * * Example: * .t column tag range $from $to tag1 tag2... * *--------------------------------------------------------------------------- */ static int ColumnTagRangeOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableColumn from, to; int i; table = cmdPtr->table; from = Blt_Table_FindColumn(interp, table, objv[4]); if (from == NULL) { return TCL_ERROR; } to = Blt_Table_FindColumn(interp, table, objv[5]); if (to == NULL) { return TCL_ERROR; } if (Blt_Table_ColumnIndex(from) > Blt_Table_ColumnIndex(to)) { Blt_TableColumn tmp; tmp = to, to = from, from = tmp; } for (i = 6; i < objc; i++) { const char *tagName; long j; tagName = Tcl_GetString(objv[i]); for (j = Blt_Table_ColumnIndex(from); j <= Blt_Table_ColumnIndex(to); j++) { Blt_TableColumn col; col = Blt_Table_Column(table, j); if (Blt_Table_SetColumnTag(interp, table, col, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagSearchOp -- * * Returns tag names for a given column. If one of more pattern * arguments are provided, then only those matching tags are returned. * * Example: * .t column tag find $column pat1 pat2... * *--------------------------------------------------------------------------- */ static int ColumnTagSearchOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_Table_FirstColumnTag(table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashTable *tablePtr; Blt_TableColumn col; tablePtr = Blt_GetHashValue(hPtr); for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Blt_HashEntry *h2Ptr; h2Ptr = Blt_FindHashEntry(tablePtr, (char *)col); if (h2Ptr != NULL) { const char *tagName; int match; int i; match = (objc == 5); tagName = hPtr->key.string; for (i = 5; i < objc; i++) { if (Tcl_StringMatch(tagName, Tcl_GetString(objv[i]))) { match = TRUE; break; /* Found match. */ } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; /* Tag matches this column. Don't care if it * matches any other columns. */ } } } } /* Handle reserved tags specially. */ { int i; int allMatch, endMatch; endMatch = allMatch = (objc == 5); for (i = 5; i < objc; i++) { if (Tcl_StringMatch("all", Tcl_GetString(objv[i]))) { allMatch = TRUE; } if (Tcl_StringMatch("end", Tcl_GetString(objv[i]))) { endMatch = TRUE; } } if (allMatch) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("all", 3)); } if (endMatch) { Blt_TableColumn col, lastCol; lastCol = Blt_Table_Column(table, Blt_Table_NumColumns(table)); for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (col == lastCol) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("end", 3)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagSetOp -- * * Adds one or more tags for a given column. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all" or "end"). * * .t column tag set $column tag1 tag2... * *--------------------------------------------------------------------------- */ static int ColumnTagSetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { const char *tagName; Blt_TableColumn col; tagName = Tcl_GetString(objv[i]); for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (Blt_Table_SetColumnTag(interp, table, col, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagUnsetOp -- * * Removes one or more tags from a given column. If a tag doesn't exist or * is a reserved tag ("all" or "end"), nothing will be done and no error * message will be returned. * * .t column tag unset $column tag1 tag2... * *--------------------------------------------------------------------------- */ static int ColumnTagUnsetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { const char *tagName; Blt_TableColumn col; tagName = Tcl_GetString(objv[i]); for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { if (Blt_Table_UnsetColumnTag(interp, table, col, tagName)!=TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTagOp -- * * This procedure is invoked to process tag operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec columnTagOps[] = { {"add", 1, ColumnTagAddOp, 5, 0, "tag ?column...?",}, {"delete", 1, ColumnTagDeleteOp, 5, 0, "tag ?column...?",}, {"exists", 1, ColumnTagExistsOp, 4, 5, "tag ?column?",}, {"forget", 1, ColumnTagForgetOp, 4, 0, "?tag...?",}, {"get", 1, ColumnTagGetOp, 5, 0, "column ?pattern...?",}, {"indices", 1, ColumnTagIndicesOp, 4, 0, "?tag...?",}, {"labels", 1, ColumnTagLabelsOp, 4, 0, "?tag...?",}, {"range", 1, ColumnTagRangeOp, 6, 0, "from to ?tag...?",}, {"search", 3, ColumnTagSearchOp, 5, 6, "column ?pattern?",}, {"set", 3, ColumnTagSetOp, 5, 0, "column tag...",}, {"unset", 1, ColumnTagUnsetOp, 5, 0, "column tag...",}, }; static int nColumnTagOps = sizeof(columnTagOps) / sizeof(Blt_OpSpec); static int ColumnTagOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nColumnTagOps, columnTagOps, BLT_OP_ARG3, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * ColumnTraceOp -- * * Creates a trace for this instance. Traces represent list of keys, a * bitmask of trace flags, and a command prefix to be invoked when a * matching trace event occurs. * * The command prefix is parsed and saved in an array of Tcl_Objs. The * qualified name of the instance is saved also. * * Results: * A standard TCL result. The name of the new trace is returned in the * interpreter result. Otherwise, if it failed to parse a switch, then * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column trace tag rwx proc * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnTraceOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Blt_TableTrace trace; TraceInfo *tiPtr; const char *tag; int flags; Blt_TableColumn col; Blt_Table table; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } flags = GetTraceFlags(Tcl_GetString(objv[4])); if (flags < 0) { Tcl_AppendResult(interp, "unknown flag in \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } col = NULL; tag = NULL; if (iter.type == TABLE_ITERATOR_RANGE) { Tcl_AppendResult(interp, "can't trace range of columns: use a tag", (char *)NULL); return TCL_ERROR; } if ((iter.type == TABLE_ITERATOR_INDEX) || (iter.type == TABLE_ITERATOR_LABEL)) { col = Blt_Table_FirstTaggedColumn(&iter); } else { tag = iter.tagName; } tiPtr = Blt_Malloc(sizeof(TraceInfo)); if (tiPtr == NULL) { Tcl_AppendResult(interp, "can't allocate trace: out of memory", (char *)NULL); return TCL_ERROR; } trace = Blt_Table_CreateTrace(table, NULL, col, NULL, tag, flags, TraceProc, TraceDeleteProc, tiPtr); if (trace == NULL) { Tcl_AppendResult(interp, "can't create column trace: out of memory", (char *)NULL); Blt_Free(tiPtr); return TCL_ERROR; } /* Initialize the trace information structure. */ tiPtr->cmdPtr = cmdPtr; tiPtr->trace = trace; tiPtr->tablePtr = &cmdPtr->traceTable; { Tcl_Obj **elv, **cmdv; int elc, i; if (Tcl_ListObjGetElements(interp, objv[5], &elc, &elv) != TCL_OK) { return TCL_ERROR; } cmdv = Blt_AssertCalloc(elc + 1 + 3 + 1, sizeof(Tcl_Obj *)); for(i = 0; i < elc; i++) { cmdv[i] = elv[i]; Tcl_IncrRefCount(cmdv[i]); } cmdv[i] = Tcl_NewStringObj(cmdPtr->hPtr->key.string, -1); Tcl_IncrRefCount(cmdv[i]); tiPtr->cmdc = elc; tiPtr->cmdv = cmdv; } { char traceId[200]; int isNew; sprintf_s(traceId, 200, "trace%d", cmdPtr->nextTraceId++); tiPtr->hPtr = Blt_CreateHashEntry(&cmdPtr->traceTable, traceId, &isNew); Blt_SetHashValue(tiPtr->hPtr, tiPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), traceId, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnTypeOp -- * * Reports and/or sets the type of a column. * * Results: * A standard TCL result. If successful, the old column label is * returned in the interpreter result. If the column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column type column ?newType? * *--------------------------------------------------------------------------- */ static int ColumnTypeOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Tcl_Obj *listObjPtr; Blt_TableColumn col; Blt_Table table; Blt_TableColumnType type; table = cmdPtr->table; if (Blt_Table_IterateColumns(interp, table, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 5) { type = Blt_Table_GetColumnType(Tcl_GetString(objv[4])); if (type == TABLE_COLUMN_TYPE_UNKNOWN) { Tcl_AppendResult(interp, "unknown column type \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Tcl_Obj *objPtr; if (objc == 5) { if (Blt_Table_SetColumnType(table, col, type) != TCL_OK) { return TCL_ERROR; } } type = Blt_Table_ColumnType(col); objPtr = Tcl_NewStringObj(Blt_Table_NameOfType(type), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnUnsetOp -- * * Unsets one or more columns of values. One or more columns may be * unset (using tags or multiple arguments). It's an error if the column * doesn't exist. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column unset column ?column? * *--------------------------------------------------------------------------- */ static int ColumnUnsetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; Blt_Table table; table = cmdPtr->table; for (i = 3; i < objc; i++) { Blt_TableIterator iter; Blt_TableColumn col; if (Blt_Table_IterateColumns(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Blt_TableRow row; for (row = Blt_Table_FirstRow(table); row != NULL; row = Blt_Table_NextRow(table, row)) { if (Blt_Table_UnsetValue(table, row, col) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnUniqueOp -- * * Reports the unique values for a given column. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t column unique column * *--------------------------------------------------------------------------- */ static int ColumnUniqueOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable values; Blt_Table table; Tcl_Obj *listObjPtr; Blt_TableColumn col; Blt_TableRow row; UniqueSwitches switches; table = cmdPtr->table; col = Blt_Table_FindColumn(interp, table, objv[3]); if (col == NULL) { return TCL_ERROR; } switches.flags = 0; if (Blt_ParseSwitches(interp, uniqueSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } Blt_InitHashTableWithPool(&values, BLT_STRING_KEYS); for (row = Blt_Table_FirstRow(table); row != NULL; row = Blt_Table_NextRow(table, row)) { Blt_HashEntry *hPtr; const char *string; int isNew; long refCount; string = Blt_Table_GetString(table, row, col); if (string == NULL) { string = cmdPtr->emptyValue; } hPtr = Blt_CreateHashEntry(&values, string, &isNew); if (isNew) { refCount = 0; } else { refCount = (long)Blt_GetHashValue(hPtr); } refCount++; Blt_SetHashValue(hPtr, (long)refCount); } listObjPtr = SortColumnValues(interp, &values, switches.flags); Blt_DeleteHashTable(&values); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnValuesOp -- * * Retrieves a column of values. The column argument can be either a * tag, label, or column index. If it is a tag, it must refer to exactly * one column. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the column index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t column values column ?valueList? * *--------------------------------------------------------------------------- */ static int ColumnValuesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableColumn col; table = cmdPtr->table; col = Blt_Table_FindColumn(interp, cmdPtr->table, objv[3]); if (col == NULL) { return TCL_ERROR; } if (objc == 4) { Blt_TableRow row; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (row = Blt_Table_FirstRow(cmdPtr->table); row != NULL; row = Blt_Table_NextRow(cmdPtr->table, row)) { Tcl_Obj *objPtr; objPtr = Blt_Table_GetObj(cmdPtr->table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_Obj **elv; int elc; int i; if (Tcl_ListObjGetElements(interp, objv[4], &elc, &elv) != TCL_OK) { return TCL_ERROR; } if (elc > Blt_Table_NumRows(table)) { long needed; needed = elc - Blt_Table_NumRows(table); if (Blt_Table_ExtendRows(interp, table, needed, NULL) != TCL_OK) { return TCL_ERROR; } } for (i = 0; i < elc; i++) { Blt_TableRow row; row = Blt_Table_Row(cmdPtr->table, i + 1); if (Blt_Table_SetObj(table, row, col, elv[i]) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnOp -- * * Parses the given command line and calls one of several column-specific * operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * *--------------------------------------------------------------------------- */ static Blt_OpSpec columnOps[] = { {"copy", 2, ColumnCopyOp, 4, 0, "src dest ?switches...?",}, {"create", 2, ColumnCreateOp, 3, 0, "?switches?",}, {"delete", 2, ColumnDeleteOp, 4, 0, "column...",}, {"dup", 2, ColumnDupOp, 3, 0, "column...",}, {"exists", 3, ColumnExistsOp, 4, 4, "column",}, {"extend", 3, ColumnExtendOp, 4, 0, "label ?label...?",}, {"get", 1, ColumnGetOp, 4, 0, "column ?switches?",}, {"index", 4, ColumnIndexOp, 4, 4, "column",}, {"indices",4, ColumnIndicesOp, 3, 0, "column ?column...?",}, {"label", 5, ColumnLabelOp, 4, 0, "column ?label?",}, {"labels", 6, ColumnLabelsOp, 3, 4, "?labelList?",}, {"length", 2, ColumnLengthOp, 3, 3, "",}, {"move", 1, ColumnMoveOp, 5, 6, "from to ?count?",}, {"names", 2, ColumnNamesOp, 3, 0, "?pattern...?",}, {"notify", 2, ColumnNotifyOp, 5, 0, "column ?flags? command",}, {"set", 2, ColumnSetOp, 5, 0, "column row value...",}, {"tag", 2, ColumnTagOp, 3, 0, "op args...",}, {"trace", 2, ColumnTraceOp, 6, 6, "column how command",}, {"type", 2, ColumnTypeOp, 4, 5, "column ?type?",}, {"unique", 3, ColumnUniqueOp, 4, 0, "column ?switches?",}, {"unset", 3, ColumnUnsetOp, 4, 0, "column...",}, {"values", 1, ColumnValuesOp, 4, 5, "column ?valueList?",}, }; static int nColumnOps = sizeof(columnOps) / sizeof(Blt_OpSpec); static int ColumnOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nColumnOps, columnOps, BLT_OP_ARG2, objc, objv, BLT_OP_LINEAR_SEARCH); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /************ Row Operations ***************/ static int CopyRow(Tcl_Interp *interp, Blt_Table srcTable, Blt_Table destTable, Blt_TableRow srcRow, /* Row offset in the source table. */ Blt_TableRow destRow) /* Row offset in the destination. */ { long i; if ((Blt_Table_SameTableObject(srcTable, destTable)) && (srcRow == destRow)) { return TCL_OK; /* Source and destination are the same. */ } if (Blt_Table_NumColumns(srcTable) > Blt_Table_NumColumns(destTable)) { long needed; needed = Blt_Table_NumColumns(srcTable) - Blt_Table_NumColumns(destTable); if (Blt_Table_ExtendColumns(interp, destTable, needed, NULL)!=TCL_OK) { return TCL_ERROR; } } for (i = 1; i <= Blt_Table_NumColumns(srcTable); i++) { Blt_TableColumn col; Blt_TableValue value; col = Blt_Table_Column(srcTable, i); value = Blt_Table_GetValue(srcTable, srcRow, col); col = Blt_Table_Column(destTable, i); if (Blt_Table_SetValue(destTable, destRow, col, value)!= TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static void CopyRowTags(Blt_Table srcTable, Blt_Table destTable, Blt_TableRow srcRow, /* Row offset in the source table. */ Blt_TableRow destRow) /* Row offset in the destination. */ { Blt_HashEntry *hPtr; Blt_HashSearch iter; /* Find all tags for with this row index. */ for (hPtr = Blt_Table_FirstRowTag(srcTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)srcRow); if (h2Ptr != NULL) { /* We know the tag tables are keyed by strings, so we don't need * to call Blt_GetHashKey and hence the hash table pointer to * retrieve the key. */ Blt_Table_SetRowTag(NULL, destTable, destRow, hPtr->key.string); } } } /* *--------------------------------------------------------------------------- * * RowCopyOp -- * * Copies the specified rows to the table. A different table may be * selected as the source. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $dest row copy $srcrow $destrow ?-table srcTable? * *--------------------------------------------------------------------------- */ static int RowCopyOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CopySwitches switches; Blt_Table srcTable, destTable; int result; Blt_TableRow src, dest; /* Process switches following the row names. */ switches.flags = 0; switches.table = NULL; result = TCL_ERROR; if (Blt_ParseSwitches(interp, copySwitches, objc - 5, objv + 5, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } srcTable = destTable = cmdPtr->table; if (switches.table != NULL) { srcTable = switches.table; } src = Blt_Table_FindRow(interp, srcTable, objv[3]); if (src == NULL) { goto error; } dest = Blt_Table_FindRow(interp, destTable, objv[4]); if (dest == NULL) { dest = Blt_Table_CreateRow(interp, destTable, Tcl_GetString(objv[4])); if (dest == NULL) { goto error; } } if (CopyRow(interp, srcTable, destTable, src, dest) != TCL_OK) { goto error; } if ((switches.flags & COPY_NOTAGS) == 0) { CopyRowTags(srcTable, destTable, src, dest); } result = TCL_OK; error: Blt_FreeSwitches(copySwitches, &switches, 0); return result; } /* *--------------------------------------------------------------------------- * * RowDeleteOp -- * * Deletes the rows designated. One or more rows may be deleted using a * tag. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row delete ?row?... * *--------------------------------------------------------------------------- */ static int RowDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Blt_TableRow row; int result; result = TCL_ERROR; if (Blt_Table_IterateRowsObjv(interp, cmdPtr->table, objc - 3, objv + 3, &iter) != TCL_OK) { goto error; } /* Walk through the list of row offsets, deleting each row. */ for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (Blt_Table_DeleteRow(cmdPtr->table, row) != TCL_OK) { goto error; } } result = TCL_OK; error: Blt_Table_FreeIteratorObjv(&iter); return result; } /* *--------------------------------------------------------------------------- * * RowDupOp -- * * Duplicates the specified rows in the table. This differs from * RowCopyOp, since the same table is always the source and destination. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $dest row dup label ?label?... * *--------------------------------------------------------------------------- */ static int RowDupOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Blt_TableIterator iter; Blt_TableRow src; int result; if (Blt_Table_IterateRowsObjv(interp, cmdPtr->table, objc - 3, objv + 3, &iter) != TCL_OK) { return TCL_ERROR; } result = TCL_ERROR; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (src = Blt_Table_FirstTaggedRow(&iter); src != NULL; src = Blt_Table_NextTaggedRow(&iter)) { const char *label; long j; Blt_TableRow dest; label = Blt_Table_RowLabel(src); dest = Blt_Table_CreateRow(interp, cmdPtr->table, label); if (dest == NULL) { goto error; } if (CopyRow(interp, cmdPtr->table, cmdPtr->table, src, dest)!= TCL_OK) { goto error; } CopyRowTags(cmdPtr->table, cmdPtr->table, src, dest); j = Blt_Table_RowIndex(dest); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(j)); } Tcl_SetObjResult(interp, listObjPtr); result = TCL_OK; error: Blt_Table_FreeIteratorObjv(&iter); if (result != TCL_OK) { Tcl_DecrRefCount(listObjPtr); } return result; } /* *--------------------------------------------------------------------------- * * RowExistsOp -- * * Indicates is the given row exists. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row exists n * *--------------------------------------------------------------------------- */ static int RowExistsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; Blt_TableRow row; row = Blt_Table_FindRow(NULL, cmdPtr->table, objv[3]); bool = (row != NULL); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowExtendOp -- * * Extends the table by the given number of rows. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row extend n * *--------------------------------------------------------------------------- */ static int RowExtendOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Blt_TableRow *rows; long i, n; int addLabels; addLabels = FALSE; if (objc == 3) { return TCL_OK; } n = 0; if ((objc > 4) || (Tcl_GetLongFromObj(NULL, objv[3], &n) != TCL_OK)) { n = objc - 3; addLabels = TRUE; } if (n == 0) { return TCL_OK; } if (n < 0) { Tcl_AppendResult(interp, "bad count \"", Blt_Itoa(n), "\": # rows can't be negative.", (char *)NULL); return TCL_ERROR; } rows = Blt_AssertMalloc(n * sizeof(Blt_TableRow)); if (Blt_Table_ExtendRows(interp, cmdPtr->table, n, rows) != TCL_OK) { Blt_Free(rows); goto error; } if (addLabels) { long j; for (i = 0, j = 3; i < n; i++, j++) { if (Blt_Table_SetRowLabel(interp, cmdPtr->table, rows[i], Tcl_GetString(objv[j])) != TCL_OK) { goto error; } } } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (i = 0; i < n; i++) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Table_RowIndex(rows[i])); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(rows); return TCL_OK; error: Blt_Free(rows); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * RowGetOp -- * * Retrieves the values from a given row. The row argument can be either * a tag, label, or row index. If it is a tag, it must refer to exactly * one row. An optional argument specifies how to return empty values. * By default, the global empty value representation is used. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row get row ?col...? * *--------------------------------------------------------------------------- */ static int RowGetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; Blt_TableRow row; Blt_Table table; const char *string; int needLabels; string = Tcl_GetString(objv[3]); needLabels = FALSE; if (strcmp(string, "-labels") == 0) { objv++, objc--; needLabels = TRUE; } table = cmdPtr->table; row = Blt_Table_FindRow(interp, table, objv[3]); if (row == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 4) { Blt_TableColumn col; for (col = Blt_Table_FirstColumn(table); col != NULL; col = Blt_Table_NextColumn(table, col)) { Tcl_Obj *objPtr; if (needLabels) { objPtr = Tcl_NewStringObj(Blt_Table_ColumnLabel(col), -1); } else { objPtr = Tcl_NewLongObj(Blt_Table_ColumnIndex(col)); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Blt_Table_GetObj(table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_TableIterator iter; Blt_TableColumn col; if (Blt_Table_IterateColumnsObjv(interp, table, objc - 4, objv + 4, &iter) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { Tcl_Obj *objPtr; if (needLabels) { objPtr = Tcl_NewStringObj(Blt_Table_ColumnLabel(col), -1); } else { objPtr = Tcl_NewLongObj(Blt_Table_ColumnIndex(col)); } objPtr = Tcl_NewLongObj(Blt_Table_ColumnIndex(col)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Blt_Table_GetObj(table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowIndexOp -- * * Returns the row index of the given row tag, label, or index. A tag * can't represent more than one row. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row index $row * *--------------------------------------------------------------------------- */ static int RowIndexOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableRow row; long i; i = -1; row = Blt_Table_FindRow(NULL, cmdPtr->table, objv[3]); if (row != NULL) { i = Blt_Table_RowIndex(row); } Tcl_SetLongObj(Tcl_GetObjResult(interp), i); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowIndicesOp -- * * Returns a list of indices for the given rows. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row indices $row $row * *--------------------------------------------------------------------------- */ static int RowIndicesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableIterator iter; Blt_TableRow row; Tcl_Obj *listObjPtr; if (Blt_Table_IterateRowsObjv(interp, cmdPtr->table, objc - 3, objv + 3, &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Tcl_Obj *objPtr; objPtr = Tcl_NewLongObj(Blt_Table_RowIndex(row)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Blt_Table_FreeIteratorObjv(&iter); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowCreateOp -- * * Creates a single new row into the table. The location of the new row * may be specified by -before or -after switches. By default the new * row is added to to the end of the table. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row create -before 0 -after 1 -label label * *--------------------------------------------------------------------------- */ static int RowCreateOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableRow row; InsertSwitches switches; unsigned int flags; switches.row = NULL; switches.label = NULL; switches.tags = NULL; switches.cmdPtr = cmdPtr; table = cmdPtr->table; flags = INSERT_ROW; if (Blt_ParseSwitches(interp, insertSwitches, objc - 3, objv + 3, &switches, flags) < 0) { goto error; } row = Blt_Table_CreateRow(interp, table, switches.label); if (row == NULL) { goto error; } if (switches.row != NULL) { if (Blt_Table_MoveRows(interp, table, row, switches.row, 1) != TCL_OK) { goto error; } } if (switches.tags != NULL) { Tcl_Obj **elv; int elc; int i; if (Tcl_ListObjGetElements(interp, switches.tags, &elc, &elv) != TCL_OK) { goto error; } for (i = 0; i < elc; i++) { if (Blt_Table_SetRowTag(interp, table, row, Tcl_GetString(elv[i])) != TCL_OK) { goto error; } } } Tcl_SetObjResult(interp, Tcl_NewLongObj(Blt_Table_RowIndex(row))); Blt_FreeSwitches(insertSwitches, &switches, flags); return TCL_OK; error: Blt_FreeSwitches(insertSwitches, &switches, flags); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * RowLabelOp -- * * Gets/sets a label for one or more rows. * * Results: * A standard TCL result. If successful, the old row label is returned * in the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row label row ?label? ?row label? * $t row label 1 * $t row label 1 newLabel * $t row label 1 lab1 2 lab2 3 lab3 5 lab5 * *--------------------------------------------------------------------------- */ static int RowLabelOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; table = cmdPtr->table; if (objc == 4) { const char *label; Blt_TableRow row; row = Blt_Table_FindRow(interp, table, objv[3]); if (row == NULL) { return TCL_ERROR; } label = Blt_Table_RowLabel(row); Tcl_SetStringObj(Tcl_GetObjResult(interp), label, -1); } else { int i; if ((objc - 3) & 1) { Tcl_AppendResult(interp,"odd # of row/label pairs: should be \"", Tcl_GetString(objv[0]), " row label ?row label?...", (char *)NULL); return TCL_ERROR; } for (i = 3; i < objc; i += 2) { Blt_TableRow row; const char *label; row = Blt_Table_FindRow(interp, table, objv[i]); if (row == NULL) { return TCL_ERROR; } label = Tcl_GetString(objv[i+1]); if (Blt_Table_SetRowLabel(interp, table, row, label) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowLabelsOp -- * * Gets/sets all the row label in the table. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row labels ?labelList? * *--------------------------------------------------------------------------- */ static int RowLabelsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; table = cmdPtr->table; if (objc == 3) { Blt_TableRow row; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (row = Blt_Table_FirstRow(table); row != NULL; row = Blt_Table_NextRow(table, row)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_Table_RowLabel(row), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else if (objc == 4) { Tcl_Obj **elv; int elc, n; int i; Blt_TableRow row; if (Tcl_ListObjGetElements(interp, objv[3], &elc, &elv) != TCL_OK) { return TCL_ERROR; } n = MIN(elc, Blt_Table_NumRows(table)); for (i = 0, row = Blt_Table_FirstRow(table); (row != NULL) && (i < n); row = Blt_Table_NextRow(table, row), i++) { const char *label; label = Tcl_GetString(elv[i]); if (Blt_Table_SetRowLabel(interp, table, row, label) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowLengthOp -- * * Returns the number of rows the client sees. * * Results: * A standard TCL result. If successful, the old row label is returned * in the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row label row ?newLabel? * *--------------------------------------------------------------------------- */ static int RowLengthOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Table_NumRows(cmdPtr->table)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowMoveOp -- * * Moves the given number of rows to another location in the table. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row move from to ?n? * *--------------------------------------------------------------------------- */ static int RowMoveOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TableRow from, to; long count; from = Blt_Table_FindRow(interp, cmdPtr->table, objv[3]); if (from == NULL) { return TCL_ERROR; } to = Blt_Table_FindRow(interp, cmdPtr->table, objv[4]); if (to == NULL) { return TCL_ERROR; } count = 1; if (objc == 6) { long lcount; if (Tcl_GetLongFromObj(interp, objv[5], &lcount) != TCL_OK) { return TCL_ERROR; } if (lcount == 0) { return TCL_OK; } if (lcount < 0) { Tcl_AppendResult(interp, "# of rows can't be negative", (char *)NULL); return TCL_ERROR; } count = lcount; } return Blt_Table_MoveRows(interp, cmdPtr->table, from, to, count); } /* *--------------------------------------------------------------------------- * * RowNamesOp -- * * Reports the labels of all rows. * * Results: * Always returns TCL_OK. The interpreter result is a list of row * labels. * * Example: * $t row names pattern... * *--------------------------------------------------------------------------- */ static int RowNamesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Tcl_Obj *listObjPtr; Blt_TableRow row; table = cmdPtr->table; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (row = Blt_Table_FirstRow(table); row != NULL; row = Blt_Table_NextRow(table, row)) { const char *label; int match; int i; label = Blt_Table_RowLabel(row); match = (objc == 3); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(label, pattern)) { match = TRUE; break; } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(label, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowNotifyOp -- * * Creates a notifier for this instance. Notifiers represent a bitmask * of events and a command prefix to be invoked when a matching event * occurs. * * The command prefix is parsed and saved in an array of Tcl_Objs. Extra * slots are allocated for the * * Results: * A standard TCL result. The name of the new notifier is returned in * the interpreter result. Otherwise, if it failed to parse a switch, * then TCL_ERROR is returned and an error message is left in the * interpreter result. * * Example: * table0 row notify row ?flags? command arg * *--------------------------------------------------------------------------- */ static int RowNotifyOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; NotifierInfo *niPtr; NotifySwitches switches; const char *tag, *string; int count; int i; int nArgs; Blt_TableRow row; Blt_TableRowColumnSpec spec; table = cmdPtr->table; spec = Blt_Table_RowSpec(table, objv[3], &string); row = NULL; tag = NULL; if (spec == TABLE_SPEC_TAG) { tag = string; } else { row = Blt_Table_FindRow(interp, table, objv[3]); if (row == NULL) { return TCL_ERROR; } } count = 0; for (i = 4; i < objc; i++) { const char *string; string = Tcl_GetString(objv[i]); if (string[0] != '-') { break; } count++; } switches.flags = 0; /* Process switches */ if (Blt_ParseSwitches(interp, notifySwitches, count, objv + 4, &switches, 0) < 0) { return TCL_ERROR; } niPtr = Blt_AssertMalloc(sizeof(NotifierInfo)); niPtr->cmdPtr = cmdPtr; if (tag == NULL) { niPtr->notifier = Blt_Table_CreateRowNotifier(interp, cmdPtr->table, row, switches.flags, NotifyProc, NotifierDeleteProc, niPtr); } else { niPtr->notifier = Blt_Table_CreateRowTagNotifier(interp, cmdPtr->table, tag, switches.flags, NotifyProc, NotifierDeleteProc, niPtr); } nArgs = (objc - i) + 2; /* Stash away the command in structure and pass that to the notifier. */ niPtr->cmdv = Blt_AssertMalloc(nArgs * sizeof(Tcl_Obj *)); for (count = 0; i < objc; i++, count++) { Tcl_IncrRefCount(objv[i]); niPtr->cmdv[count] = objv[i]; } niPtr->cmdc = nArgs; if (switches.flags == 0) { switches.flags = TABLE_NOTIFY_ALL_EVENTS; } { char notifyId[200]; Blt_HashEntry *hPtr; int isNew; sprintf_s(notifyId, 200, "notify%d", cmdPtr->nextNotifyId++); hPtr = Blt_CreateHashEntry(&cmdPtr->notifyTable, notifyId, &isNew); assert(isNew); Blt_SetHashValue(hPtr, niPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), notifyId, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowSetOp -- * * Sets a row of values. One or more rows may be set using a tag. The * column order is always the table's current view of the table. There * may be less values than needed. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row set row ?switches? ?column value?... * $t row set row ?switches? ?column value?... * *--------------------------------------------------------------------------- */ static int RowSetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; long nCols; Blt_TableRow row; table = cmdPtr->table; /* May set more than one row with the same values. */ if (IterateRows(interp, table, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { return TCL_OK; } nCols = objc - 4; if (nCols & 1) { Tcl_AppendResult(interp, "odd # of column/value pairs: should be \"", Tcl_GetString(objv[0]), " row set column value...", (char *)NULL); return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { long i; /* The remaining arguments are index/value pairs. */ for (i = 4; i < objc; i += 2) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[i]); if (col == NULL) { /* Can't find the column. Create it and try to find it * again. */ if (MakeColumns(interp, table, objv[i]) != TCL_OK) { return TCL_ERROR; } col = Blt_Table_FindColumn(interp, table, objv[i]); } if (Blt_Table_SetObj(table, row, col, objv[i+1]) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagAddOp -- * * Adds a given tag to one or more rows. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all" or "end"). * * .t row tag add tag ?row...? * *--------------------------------------------------------------------------- */ static int RowTagAddOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; const char *tagName; table = cmdPtr->table; tagName = Tcl_GetString(objv[4]); if (Blt_Table_SetRowTag(interp, table, NULL, tagName) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { Blt_TableRow row; Blt_TableIterator iter; if (Blt_Table_IterateRows(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (Blt_Table_SetRowTag(interp, table, row, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagDeleteOp -- * * Removes a given tag from one or more rows. If a tag doesn't exist or * is a reserved tag ("all" or "end"), nothing will be done and no error * message will be returned. * * .t row tag delete tag ?row...? * *--------------------------------------------------------------------------- */ static int RowTagDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; const char *tagName; table = cmdPtr->table; tagName = Tcl_GetString(objv[4]); for (i = 5; i < objc; i++) { Blt_TableRow row; if (Blt_Table_IterateRows(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (Blt_Table_UnsetRowTag(interp, table, row, tagName)!=TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagExistsOp -- * * Returns the existence of a tag in the table. If a row is specified * then the tag is search for for that row. * * .t tag row exists tag ?row? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RowTagExistsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; const char *tagName; tagName = Tcl_GetString(objv[3]); bool = (Blt_Table_FindRowTagTable(cmdPtr->table, tagName) != NULL); if (objc == 5) { Blt_TableRow row; row = Blt_Table_FindRow(interp, cmdPtr->table, objv[4]); if (row == NULL) { bool = FALSE; } else { bool = Blt_Table_HasRowTag(cmdPtr->table, row, tagName); } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagForgetOp -- * * Removes the given tags from all nodes. * * $t row tag forget tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RowTagForgetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; table = cmdPtr->table; for (i = 4; i < objc; i++) { if (Blt_Table_ForgetRowTag(interp, table, Tcl_GetString(objv[i])) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagGetOp -- * * Returns the tag names for a given row. If one of more pattern * arguments are provided, then only those matching tags are returned. * * .t row tag get row pat1 pat2... * *--------------------------------------------------------------------------- */ static int RowTagGetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch hsearch; Blt_HashTable tagTable; Blt_Table table; Blt_TableIterator iter; Blt_TableRow row; Tcl_Obj *listObjPtr; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Blt_InitHashTable(&tagTable, BLT_STRING_KEYS); /* Collect all the tags into a hash table. */ for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Blt_Chain chain; Blt_ChainLink link; chain = Blt_Table_RowTags(table, row); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { const char *tagName; int isNew; tagName = Blt_Chain_GetValue(link); Blt_CreateHashEntry(&tagTable, tagName, &isNew); } Blt_Chain_Destroy(chain); } for (hPtr = Blt_FirstHashEntry(&tagTable, &hsearch); hPtr != NULL; hPtr = Blt_NextHashEntry(&hsearch)) { int match; const char *tagName; tagName = Blt_GetHashKey(&tagTable, hPtr); match = TRUE; if (objc > 5) { int i; match = FALSE; for (i = 5; i < objc; i++) { if (Tcl_StringMatch(tagName, Tcl_GetString(objv[i]))) { match = TRUE; } } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_DeleteHashTable(&tagTable); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static unsigned char * GetRowTagMatches(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv) { long nRows; int i; unsigned char *matches; nRows = Blt_Table_NumRows(table); matches = Blt_AssertCalloc(nRows + 1, sizeof(unsigned char)); /* Handle the reserved tags "all" or "end". */ for (i = 0; i < objc; i++) { char *tagName; long j; tagName = Tcl_GetString(objv[i]); if (strcmp("all", tagName) == 0) { for (j = 1; j <= nRows; j++) { matches[j] = TRUE; } return matches; /* Don't care other tags. */ } if (strcmp("end", tagName) == 0) { matches[nRows] = TRUE; } } /* Now check user-defined tags. */ for (i = 0; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_HashTable *tagTablePtr; const char *tagName; tagName = Tcl_GetString(objv[i]); if ((strcmp("all", tagName) == 0) || (strcmp("end", tagName) == 0)) { continue; } tagTablePtr = Blt_Table_FindRowTagTable(table, tagName); if (tagTablePtr == NULL) { Tcl_AppendResult(interp, "unknown row tag \"", tagName, "\"", (char *)NULL); Blt_Free(matches); return NULL; } for (hPtr = Blt_FirstHashEntry(tagTablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_TableRow row; long j; row = Blt_GetHashValue(hPtr); j = Blt_Table_RowIndex(row); assert(j >= 0); matches[j] = TRUE; } } return matches; } /* *--------------------------------------------------------------------------- * * RowTagIndicesOp -- * * Returns row indices names for the given tags. If one of more tag * names are provided, then only those matching indices are returned. * * .t row tag indices tag1 tag2... * *--------------------------------------------------------------------------- */ static int RowTagIndicesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; long j; long nRows; unsigned char *matches; matches = GetRowTagMatches(interp, cmdPtr->table, objc - 4, objv + 4); if (matches == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); nRows = Blt_Table_NumRows(cmdPtr->table); for (j = 1; j <= nRows; j++) { if (matches[j]) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(j)); } } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(matches); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagLabelsOp -- * * Returns row labels for the given tags. If one of more tag * names are provided, then only those matching indices are returned. * * Example: * .t row tag labels tag1 tag2... * *--------------------------------------------------------------------------- */ static int RowTagLabelsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; long j; long nRows; unsigned char *matches; matches = GetRowTagMatches(interp, cmdPtr->table, objc - 4, objv + 4); if (matches == NULL) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); nRows = Blt_Table_NumRows(cmdPtr->table); for (j = 1; j <= nRows; j++) { if (matches[j]) { Blt_TableRow row; Tcl_Obj *objPtr; row = Blt_Table_Row(cmdPtr->table, j); objPtr = Tcl_NewStringObj(Blt_Table_RowLabel(row), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(matches); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagRangeOp -- * * Adds one or more tags for a given row. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all" or "end"). * * .t row tag range $from $to tag1 tag2... * *--------------------------------------------------------------------------- */ static int RowTagRangeOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; Blt_TableRow from, to; table = cmdPtr->table; from = Blt_Table_FindRow(interp, table, objv[4]); if (from == NULL) { return TCL_ERROR; } to = Blt_Table_FindRow(interp, table, objv[5]); if (to == NULL) { return TCL_ERROR; } if (Blt_Table_RowIndex(from) > Blt_Table_RowIndex(to)) { Blt_TableRow tmp; tmp = to, to = from, from = tmp; } for (i = 6; i < objc; i++) { const char *tagName; long j; tagName = Tcl_GetString(objv[i]); for (j = Blt_Table_RowIndex(from); j <= Blt_Table_RowIndex(to); j++) { Blt_TableRow row; row = Blt_Table_Row(table, j); if (Blt_Table_SetRowTag(interp, table, row, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagSearchOp -- * * Returns tag names for a given row. If one of more pattern arguments * are provided, then only those matching tags are returned. * * .t row tag find $row pat1 pat2... * *--------------------------------------------------------------------------- */ static int RowTagSearchOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_HashEntry *hPtr; Blt_HashSearch cursor; Blt_TableIterator iter; Tcl_Obj *listObjPtr; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_Table_FirstRowTag(table, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashTable *tablePtr; Blt_TableRow row; tablePtr = Blt_GetHashValue(hPtr); for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Blt_HashEntry *h2Ptr; h2Ptr = Blt_FindHashEntry(tablePtr, (char *)row); if (h2Ptr != NULL) { const char *tagName; int match; int i; match = (objc == 5); tagName = hPtr->key.string; for (i = 5; i < objc; i++) { if (Tcl_StringMatch(tagName, Tcl_GetString(objv[i]))) { match = TRUE; break; /* Found match. */ } } if (match) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; /* Tag matches this row. Don't care if it * matches any other rows. */ } } } } /* Handle reserved tags specially. */ { int i; int allMatch, endMatch; endMatch = allMatch = (objc == 5); for (i = 5; i < objc; i++) { if (Tcl_StringMatch("all", Tcl_GetString(objv[i]))) { allMatch = TRUE; } if (Tcl_StringMatch("end", Tcl_GetString(objv[i]))) { endMatch = TRUE; } } if (allMatch) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("all", 3)); } if (endMatch) { Blt_TableRow row, lastRow; lastRow = Blt_Table_Row(table, Blt_Table_NumRows(table)); for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (row == lastRow) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("end", 3)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagSetOp -- * * Adds one or more tags for a given row. * * .t row tag set $row tag1 tag2... * *--------------------------------------------------------------------------- */ static int RowTagSetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { const char *tagName; Blt_TableRow row; tagName = Tcl_GetString(objv[i]); for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (Blt_Table_SetRowTag(interp, table, row, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagUnsetOp -- * * Removes one or more tags from a given row. * * .t row tag unset $row tag1 tag2... * *--------------------------------------------------------------------------- */ static int RowTagUnsetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; int i; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[4], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 5; i < objc; i++) { const char *tagName; Blt_TableRow row; tagName = Tcl_GetString(objv[i]); for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { if (Blt_Table_UnsetRowTag(interp, table, row, tagName)!=TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowTagOp -- * * This procedure is invoked to process tag operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec rowTagOps[] = { {"add", 1, RowTagAddOp, 5, 0, "tag ?row...?",}, {"delete", 1, RowTagDeleteOp, 5, 0, "tag ?row...?",}, {"exists", 1, RowTagExistsOp, 5, 6, "tag ?row?",}, {"forget", 1, RowTagForgetOp, 4, 0, "?tag...?",}, {"get", 1, RowTagGetOp, 5, 0, "row ?pattern...?",}, {"indices", 1, RowTagIndicesOp, 4, 0, "?tag...?",}, {"labels", 1, RowTagLabelsOp, 4, 0, "?tag...?",}, {"range", 1, RowTagRangeOp, 6, 0, "from to ?tag...?",}, {"search", 3, RowTagSearchOp, 5, 6, "row ?pattern?",}, {"set", 3, RowTagSetOp, 5, 0, "row tag...",}, {"unset", 1, RowTagUnsetOp, 5, 0, "row tag...",}, }; static int nRowTagOps = sizeof(rowTagOps) / sizeof(Blt_OpSpec); static int RowTagOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nRowTagOps, rowTagOps, BLT_OP_ARG3, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * RowTraceOp -- * * Creates a trace for this instance. Traces represent list of keys, a * bitmask of trace flags, and a command prefix to be invoked when a * matching trace event occurs. * * The command prefix is parsed and saved in an array of Tcl_Objs. The * qualified name of the instance is saved also. * * Results: * A standard TCL result. The name of the new trace is returned in the * interpreter result. Otherwise, if it failed to parse a switch, then * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t row trace tag rwx proc * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RowTraceOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator iter; Blt_TableTrace trace; TraceInfo *tiPtr; const char *tag; int flags; Blt_TableRow row; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } flags = GetTraceFlags(Tcl_GetString(objv[4])); if (flags < 0) { Tcl_AppendResult(interp, "unknown flag in \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } row = NULL; tag = NULL; if (iter.type == TABLE_ITERATOR_RANGE) { Tcl_AppendResult(interp, "can't trace range of rows: use a tag", (char *)NULL); return TCL_ERROR; } if ((iter.type == TABLE_ITERATOR_INDEX) || (iter.type == TABLE_ITERATOR_LABEL)) { row = Blt_Table_FirstTaggedRow(&iter); } else { tag = iter.tagName; } tiPtr = Blt_Malloc(sizeof(TraceInfo)); if (tiPtr == NULL) { Tcl_AppendResult(interp, "can't allocate trace: out of memory", (char *)NULL); return TCL_ERROR; } trace = Blt_Table_CreateTrace(table, row, NULL, tag, NULL, flags, TraceProc, TraceDeleteProc, tiPtr); if (trace == NULL) { Tcl_AppendResult(interp, "can't create row trace: out of memory", (char *)NULL); Blt_Free(tiPtr); return TCL_ERROR; } /* Initialize the trace information structure. */ tiPtr->cmdPtr = cmdPtr; tiPtr->trace = trace; tiPtr->tablePtr = &cmdPtr->traceTable; { Tcl_Obj **elv, **cmdv; int elc, i; if (Tcl_ListObjGetElements(interp, objv[5], &elc, &elv) != TCL_OK) { return TCL_ERROR; } cmdv = Blt_AssertCalloc(elc + 1 + 3 + 1, sizeof(Tcl_Obj *)); for(i = 0; i < elc; i++) { cmdv[i] = elv[i]; Tcl_IncrRefCount(cmdv[i]); } cmdv[i] = Tcl_NewStringObj(cmdPtr->hPtr->key.string, -1); Tcl_IncrRefCount(cmdv[i]); tiPtr->cmdc = elc; tiPtr->cmdv = cmdv; } { char traceId[200]; int isNew; sprintf_s(traceId, 200, "trace%d", cmdPtr->nextTraceId++); tiPtr->hPtr = Blt_CreateHashEntry(&cmdPtr->traceTable, traceId, &isNew); Blt_SetHashValue(tiPtr->hPtr, tiPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), traceId, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowUnsetOp -- * * Unsets one or more rows of values. One or more rows may be unset * (using tags or multiple arguments). * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row unset row ?row? * *--------------------------------------------------------------------------- */ static int RowUnsetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; table = cmdPtr->table; for (i = 3; i < objc; i++) { Blt_TableIterator iter; Blt_TableRow row; if (Blt_Table_IterateRows(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Blt_TableColumn col; for (col = Blt_Table_FirstColumn(table); col != NULL; col = Blt_Table_NextColumn(table, col)) { if (Blt_Table_UnsetValue(table, row, col) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowUniqueOp -- * * Reports the unique values for a given row. * * Results: * A standard TCL result. If the tag or row index is invalid, TCL_ERROR * is returned and an error message is left in the interpreter result. * * Example: * $t row unique row * *--------------------------------------------------------------------------- */ static int RowUniqueOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; Blt_HashTable values; table = cmdPtr->table; Blt_InitHashTableWithPool(&values, BLT_STRING_KEYS); for (i = 3; i < objc; i++) { Blt_TableIterator iter; Blt_TableRow row; if (Blt_Table_IterateRows(interp, table, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { Blt_TableColumn col; for (col = Blt_Table_FirstColumn(table); col != NULL; col = Blt_Table_NextColumn(table, col)) { const char *string; Blt_HashEntry *hPtr; int isNew; string = Blt_Table_GetString(table, row, col); if (string == NULL) { string = cmdPtr->emptyValue; } hPtr = Blt_CreateHashEntry(&values, string, &isNew); if (hPtr == NULL) { return TCL_ERROR; } } } } { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&values, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_AppendElement(interp, Blt_GetHashKey(&values, hPtr)); } } Blt_DeleteHashTable(&values); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowValuesOp -- * * Retrieves a row of values. The row argument can be either a tag, * label, or row index. If it is a tag, it must refer to exactly one * row. * * Results: * A standard TCL result. If successful, a list of values is returned in * the interpreter result. If the row index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t row listget row ?defValue? * *--------------------------------------------------------------------------- */ static int RowValuesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableRow row; Tcl_Obj *listObjPtr; table = cmdPtr->table; row = Blt_Table_FindRow(interp, cmdPtr->table, objv[3]); if (row == NULL) { return TCL_ERROR; } if (objc == 4) { Blt_TableColumn col; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (col = Blt_Table_FirstColumn(cmdPtr->table); col != NULL; col = Blt_Table_NextColumn(cmdPtr->table, col)) { Tcl_Obj *objPtr; objPtr = Blt_Table_GetObj(cmdPtr->table, row, col); if (objPtr == NULL) { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_Obj **elv; int elc; long i, j; if (Tcl_ListObjGetElements(interp, objv[4], &elc, &elv) != TCL_OK) { return TCL_ERROR; } if (elc > Blt_Table_NumColumns(table)) { long n; n = elc - Blt_Table_NumColumns(table); if (Blt_Table_ExtendColumns(interp, table, n, NULL) != TCL_OK) { return TCL_ERROR; } } for (i = 0, j = 1; i < elc; i++, j++) { Blt_TableColumn col; col = Blt_Table_Column(table, j); if (Blt_Table_SetObj(table, row, col, elv[i]) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RowOp -- * * Parses the given command line and calls one of several row-specific * operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * *--------------------------------------------------------------------------- */ static Blt_OpSpec rowOps[] = { {"copy", 2, RowCopyOp, 4, 0, "src dest ?switches...?",}, {"create", 2, RowCreateOp, 3, 0, "?switches...?",}, {"delete", 2, RowDeleteOp, 4, 0, "row...",}, {"dup", 2, RowDupOp, 3, 0, "row...",}, {"exists", 3, RowExistsOp, 4, 4, "row",}, {"extend", 3, RowExtendOp, 4, 0, "label ?label...?",}, {"get", 1, RowGetOp, 4, 0, "row ?switches?",}, {"index", 4, RowIndexOp, 4, 4, "row",}, {"indices", 4, RowIndicesOp,3, 0, "row ?row...?",}, {"label", 5, RowLabelOp, 4, 0, "row ?label?",}, {"labels", 6, RowLabelsOp, 3, 4, "?labelList?",}, {"length", 2, RowLengthOp, 3, 3, "",}, {"move", 1, RowMoveOp, 5, 6, "from to ?count?",}, {"names", 2, RowNamesOp, 3, 0, "?pattern...?",}, {"notify", 2, RowNotifyOp, 5, 0, "row ?flags? command",}, {"set", 2, RowSetOp, 5, 0, "row column value...",}, {"tag", 2, RowTagOp, 3, 0, "op args...",}, {"trace", 2, RowTraceOp, 6, 6, "row how command",}, {"unique", 3, RowUniqueOp, 4, 4, "row",}, {"unset", 3, RowUnsetOp, 4, 0, "row...",}, {"values", 1, RowValuesOp, 4, 5, "row ?valueList?",}, }; static int nRowOps = sizeof(rowOps) / sizeof(Blt_OpSpec); static int RowOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nRowOps, rowOps, BLT_OP_ARG2, objc, objv, BLT_OP_LINEAR_SEARCH); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Concatenates the source table onto the destination. * * Results: * A standard TCL result. If the tag or column index is invalid, * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * * $dest add $src ?switches? * *--------------------------------------------------------------------------- */ static int AddOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { AddSwitches switches; Blt_Table srcTable; size_t oldSize, extra; int result; Blt_TableColumn src; /* Process switches following the column names. */ if (Blt_Table_Open(interp, Tcl_GetString(objv[2]), &srcTable) != TCL_OK) { return TCL_ERROR; } switches.flags = 0; result = TCL_ERROR; if (Blt_ParseSwitches(interp, addSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } oldSize = Blt_Table_NumRows(cmdPtr->table); extra = Blt_Table_NumRows(srcTable); Blt_Table_ExtendRows(interp, cmdPtr->table, extra, NULL); for (src = Blt_Table_FirstColumn(srcTable); src != NULL; src = Blt_Table_NextColumn(srcTable, src)) { const char *label; Blt_TableColumn dest; long i; label = Blt_Table_ColumnLabel(src); dest = Blt_Table_FindColumnByLabel(cmdPtr->table, label); if (dest == NULL) { /* If column doesn't exist in destination table, create a new * column, copying the label and the column type. */ if (Blt_Table_ExtendColumns(interp, cmdPtr->table, 1, &dest) != TCL_OK) { goto error; } if (Blt_Table_SetColumnLabel(interp, cmdPtr->table, dest, label) != TCL_OK) { goto error; } Blt_Table_SetColumnType(cmdPtr->table, dest, Blt_Table_ColumnType(src)); } for (i = 1; i <= Blt_Table_NumRows(srcTable); i++) { Blt_TableRow row; Blt_TableValue value; row = Blt_Table_Row(srcTable, i); value = Blt_Table_GetValue(srcTable, row, src); if (value == NULL) { continue; } row = Blt_Table_Row(cmdPtr->table, i+oldSize); if (Blt_Table_SetValue(cmdPtr->table, row, dest, value) != TCL_OK) { goto error; } } if ((switches.flags & COPY_NOTAGS) == 0) { CopyColumnTags(srcTable, cmdPtr->table, src, dest); } } result = TCL_OK; error: Blt_Table_Close(srcTable); Blt_FreeSwitches(addSwitches, &switches, 0); return result; } /* *--------------------------------------------------------------------------- * * AppendOp -- * * * Appends one or more values to the current value at the given * location. If the column or row doesn't already exist, it will * automatically be created. * * Results: * A standard TCL result. If the tag or index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t append $row $column $value ?value...? * *--------------------------------------------------------------------------- */ static int AppendOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator ri, ci; Blt_TableColumn col; int i, extra; table = cmdPtr->table; if (IterateRows(interp, table, objv[2], &ri) != TCL_OK) { return TCL_ERROR; } if (IterateColumns(interp, table, objv[3], &ci) != TCL_OK) { return TCL_ERROR; } extra = 0; for (i = 4; i < objc; i++) { int length; Tcl_GetStringFromObj(objv[i], &length); extra += length; } if (extra == 0) { return TCL_OK; } for (col = Blt_Table_FirstTaggedColumn(&ci); col != NULL; col = Blt_Table_NextTaggedColumn(&ci)) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&ri); row != NULL; row = Blt_Table_NextTaggedRow(&ri)) { int i; for (i = 4; i < objc; i++) { const char *s; int length; s = Tcl_GetStringFromObj(objv[i], &length); if (Blt_Table_AppendString(interp, table, row, col, s, length) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExportOp -- * * Parses the given command line and calls one of several export-specific * operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * *--------------------------------------------------------------------------- */ static int ExportOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TableCmdInterpData *dataPtr; dataPtr = GetTableCmdInterpData(interp); if (objc == 2) { Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->exportProc != NULL) { Tcl_AppendElement(interp, fmtPtr->name); } } return TCL_OK; } hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, Tcl_GetString(objv[2])); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't export \"", Tcl_GetString(objv[2]), "\": format not registered", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->exportProc == NULL) { Tcl_AppendResult(interp, "no export procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } return (*fmtPtr->exportProc) (cmdPtr->table, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * KeysOp -- * * This procedure is invoked to process key operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * * Example: * $t keys key key key key * $t keys * *--------------------------------------------------------------------------- */ static int KeysOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Chain keys; Blt_Table table; int i; if (objc == 2) { Tcl_Obj *listObjPtr; Blt_ChainLink link; keys = Blt_Table_GetKeys(cmdPtr->table); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (link = Blt_Chain_FirstLink(keys); link != NULL; link = Blt_Chain_NextLink(link)) { Blt_TableColumn col; Tcl_Obj *objPtr; col = Blt_Chain_GetValue(link); objPtr = Tcl_NewStringObj(Blt_Table_ColumnLabel(col), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } table = cmdPtr->table; keys = Blt_Chain_Create(); for (i = 2; i < objc; i++) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[i]); if (col == NULL) { Blt_Chain_Destroy(keys); return TCL_ERROR; } Blt_Chain_Append(keys, col); } Blt_Table_SetKeys(table, keys, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LappendOp -- * * * Appends one or more elements to the list at the given row, column * location. If the column or row doesn't already exist, it will * automatically be created. * * Results: * A standard TCL result. If the tag or index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t append $row $column $value ?value...? * *--------------------------------------------------------------------------- */ static int LappendOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator ri, ci; Blt_TableColumn col; table = cmdPtr->table; if (IterateRows(interp, table, objv[2], &ri) != TCL_OK) { return TCL_ERROR; } if (IterateColumns(interp, table, objv[3], &ci) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&ci); col != NULL; col = Blt_Table_NextTaggedColumn(&ci)) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&ri); row != NULL; row = Blt_Table_NextTaggedRow(&ri)) { Tcl_Obj *listObjPtr; int i, result; listObjPtr = Blt_Table_GetObj(table, row, col); if (listObjPtr == NULL) { listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); } Tcl_IncrRefCount(listObjPtr); for (i = 4; i < objc; i++) { Tcl_ListObjAppendElement(interp, listObjPtr, objv[i]); } result = Blt_Table_SetObj(table, row, col, listObjPtr); Tcl_DecrRefCount(listObjPtr); if (result != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } static int LookupOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { long nKeys; Blt_Chain keys; Blt_TableRow row; Blt_Table table; long i; keys = Blt_Table_GetKeys(cmdPtr->table); nKeys = Blt_Chain_GetLength(keys); if ((objc - 2) != nKeys) { Blt_ChainLink link; Tcl_AppendResult(interp, "wrong # of keys: should be \"", (char *)NULL); for (link = Blt_Chain_FirstLink(keys); link != NULL; link = Blt_Chain_NextLink(link)) { Blt_TableColumn col; col = Blt_Chain_GetValue(link); Tcl_AppendResult(interp, Blt_Table_ColumnLabel(col), " ", (char *)NULL); } Tcl_AppendResult(interp, "\"", (char *)NULL); return TCL_ERROR; } table = cmdPtr->table; if (Blt_Table_KeyLookup(interp, table, objc - 2, objv + 2, &row)!=TCL_OK) { return TCL_ERROR; } i = (row == NULL) ? -1 : Blt_Table_RowIndex(row); Tcl_SetLongObj(Tcl_GetObjResult(interp), i); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImportOp -- * * Parses the given command line and calls one of several import-specific * operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * *--------------------------------------------------------------------------- */ static int ImportOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TableCmdInterpData *dataPtr; dataPtr = GetTableCmdInterpData(interp); if (objc == 2) { Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->importProc != NULL) { Tcl_AppendElement(interp, fmtPtr->name); } } return TCL_OK; } hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, Tcl_GetString(objv[2])); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't import \"", Tcl_GetString(objv[2]), "\": format not registered", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->importProc == NULL) { Tcl_AppendResult(interp, "no import procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } return (*fmtPtr->importProc) (cmdPtr->table, interp, objc, objv); } /**************** Notify Operations *******************/ /* *--------------------------------------------------------------------------- * * NotifyDeleteOp -- * * Deletes one or more notifiers. * * Results: * A standard TCL result. If a name given doesn't represent a notifier, * then TCL_ERROR is returned and an error message is left in the * interpreter result. * *--------------------------------------------------------------------------- */ static int NotifyDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Blt_HashEntry *hPtr; NotifierInfo *niPtr; hPtr = Blt_FindHashEntry(&cmdPtr->notifyTable, Tcl_GetString(objv[i])); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown notifier id \"", Tcl_GetString(objv[i]), "\"", (char *)NULL); return TCL_ERROR; } niPtr = Blt_GetHashValue(hPtr); Blt_DeleteHashEntry(&cmdPtr->notifyTable, hPtr); FreeNotifierInfo(niPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifierInfoOp -- * * Returns the details for a given notifier. The string id of the * notifier is passed as an argument. * * Results: * A standard TCL result. If the name given doesn't represent a * notifier, then TCL_ERROR is returned and an error message is left in * the interpreter result. Otherwise the details of the notifier handler * are returned as a list of three elements: notifier id, flags, and * command. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NotifyInfoOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_HashEntry *hPtr; NotifierInfo *niPtr; const char *what; Tcl_Obj *listObjPtr, *subListObjPtr, *objPtr; int i; struct _Blt_TableNotifier *notifierPtr; table = cmdPtr->table; hPtr = Blt_FindHashEntry(&cmdPtr->notifyTable, Tcl_GetString(objv[3])); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown notifier id \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } niPtr = Blt_GetHashValue(hPtr); notifierPtr = niPtr->notifier; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); Tcl_ListObjAppendElement(interp, listObjPtr, objv[3]); /* Copy notify Id */ subListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (notifierPtr->flags & TABLE_NOTIFY_CREATE) { objPtr = Tcl_NewStringObj("-create", -1); Tcl_ListObjAppendElement(interp, subListObjPtr, objPtr); } if (notifierPtr->flags & TABLE_NOTIFY_DELETE) { objPtr = Tcl_NewStringObj("-delete", -1); Tcl_ListObjAppendElement(interp, subListObjPtr, objPtr); } if (notifierPtr->flags & TABLE_NOTIFY_WHENIDLE) { objPtr = Tcl_NewStringObj("-whenidle", -1); Tcl_ListObjAppendElement(interp, subListObjPtr, objPtr); } Tcl_ListObjAppendElement(interp, listObjPtr, subListObjPtr); what = (notifierPtr->flags & TABLE_NOTIFY_ROW) ? "row" : "column"; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(what, -1)); if (notifierPtr->tag != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(notifierPtr->tag, -1)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewLongObj(Blt_Table_RowIndex(notifierPtr->header))); } subListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (i = 0; i < niPtr->cmdc; i++) { Tcl_ListObjAppendElement(interp, subListObjPtr, niPtr->cmdv[i]); } Tcl_ListObjAppendElement(interp, listObjPtr, subListObjPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyNamesOp -- * * Returns the names of all the notifiers in use by this instance. * Notifiers issues by other instances or object clients are not * reported. * * Results: * Always TCL_OK. A list of notifier names is left in the interpreter * result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NotifyNamesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&cmdPtr->notifyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_Obj *objPtr; const char *name; name = Blt_GetHashKey(&cmdPtr->notifyTable, hPtr); objPtr = Tcl_NewStringObj(name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NotifyOp -- * * Parses the given command line and calls one of several notifier * specific operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * *--------------------------------------------------------------------------- */ static Blt_OpSpec notifyOps[] = { {"delete", 1, NotifyDeleteOp, 3, 0, "notifyId...",}, {"info", 1, NotifyInfoOp, 4, 4, "notifyId",}, {"names", 1, NotifyNamesOp, 3, 3, "",}, }; static int nNotifyOps = sizeof(notifyOps) / sizeof(Blt_OpSpec); static int NotifyOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nNotifyOps, notifyOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * SortOp -- * * $t sort -dictionary -decreasing -list -ascii a b c * *--------------------------------------------------------------------------- */ static int SortOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableSortOrder *sp, *order; SortSwitches switches; int i; int result; long n; Blt_TableRow *map; table = cmdPtr->table; result = TCL_ERROR; /* Process switches */ switches.flags = 0; i = Blt_ParseSwitches(interp, sortSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { return TCL_ERROR; } n = objc - i; sp = order = Blt_AssertCalloc(n, sizeof(Blt_TableSortOrder)); for (/*empty*/; i < objc; i++) { Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[i]); if (col == NULL) { goto error; } sp->column = col; } map = Blt_Table_SortRows(table, order, sp - order, switches.flags); if (map == NULL) { Tcl_AppendResult(interp, "out of memory: can't allocate sort map", (char *)NULL); goto error; } if (switches.flags & SORT_LIST) { Tcl_Obj *listObjPtr; Blt_TableRow *ip, *iend; /* Return the new row order as a list. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (ip = map, iend = ip + Blt_Table_NumRows(table); ip < iend; ip++) { Tcl_Obj *objPtr; /* Convert the table offset back to a client index. */ objPtr = Tcl_NewLongObj(Blt_Table_RowIndex(*ip)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); Blt_Free(map); } else { /* Make row order permanent. */ Blt_Table_SetRowMap(table, map); } result = TCL_OK; error: Blt_Free(order); return result; } /************* Trace Operations *****************/ /* *--------------------------------------------------------------------------- * * TraceCreateOp -- * * Creates a trace for this instance. Traces represent list of keys, a * bitmask of trace flags, and a command prefix to be invoked when a * matching trace event occurs. * * The command prefix is parsed and saved in an array of Tcl_Objs. The * qualified name of the instance is saved also. * * Results: * A standard TCL result. The name of the new trace is returned in the * interpreter result. Otherwise, if it failed to parse a switch, then * TCL_ERROR is returned and an error message is left in the interpreter * result. * * Example: * $t trace create row column how command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceCreateOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; Blt_TableIterator ri, ci; Blt_TableTrace trace; TraceInfo *tiPtr; const char *rowTag, *colTag; int flags; Blt_TableRow row; Blt_TableColumn col; table = cmdPtr->table; if (Blt_Table_IterateRows(interp, table, objv[3], &ri) != TCL_OK) { return TCL_ERROR; } if (Blt_Table_IterateColumns(interp, table, objv[4], &ci) != TCL_OK) { return TCL_ERROR; } flags = GetTraceFlags(Tcl_GetString(objv[5])); if (flags < 0) { Tcl_AppendResult(interp, "unknown flag in \"", Tcl_GetString(objv[5]), "\"", (char *)NULL); return TCL_ERROR; } row = NULL; col = NULL; colTag = rowTag = NULL; if (ri.type == TABLE_ITERATOR_RANGE) { Tcl_AppendResult(interp, "can't trace range of rows: use a tag", (char *)NULL); return TCL_ERROR; } if (ci.type == TABLE_ITERATOR_RANGE) { Tcl_AppendResult(interp, "can't trace range of columns: use a tag", (char *)NULL); return TCL_ERROR; } if ((ri.type == TABLE_ITERATOR_INDEX) || (ri.type == TABLE_ITERATOR_LABEL)) { row = Blt_Table_FirstTaggedRow(&ri); } else { rowTag = ri.tagName; } if ((ci.type == TABLE_ITERATOR_INDEX) || (ci.type == TABLE_ITERATOR_LABEL)) { col = Blt_Table_FirstTaggedColumn(&ci); } else { colTag = ci.tagName; } tiPtr = Blt_Malloc(sizeof(TraceInfo)); if (tiPtr == NULL) { Tcl_AppendResult(interp, "can't allocate trace: out of memory", (char *)NULL); return TCL_ERROR; } trace = Blt_Table_CreateTrace(table, row, col, rowTag, colTag, flags, TraceProc, TraceDeleteProc, tiPtr); if (trace == NULL) { Tcl_AppendResult(interp, "can't create individual trace: out of memory", (char *)NULL); Blt_Free(tiPtr); return TCL_ERROR; } /* Initialize the trace information structure. */ tiPtr->cmdPtr = cmdPtr; tiPtr->trace = trace; tiPtr->tablePtr = &cmdPtr->traceTable; { Tcl_Obj **elv, **cmdv; int elc, i; if (Tcl_ListObjGetElements(interp, objv[6], &elc, &elv) != TCL_OK) { return TCL_ERROR; } /* * Command + tableName + row + column + flags + NULL */ cmdv = Blt_AssertCalloc(elc + 1 + 3 + 1, sizeof(Tcl_Obj *)); for(i = 0; i < elc; i++) { cmdv[i] = elv[i]; Tcl_IncrRefCount(cmdv[i]); } cmdv[i] = Tcl_NewStringObj(cmdPtr->hPtr->key.string, -1); Tcl_IncrRefCount(cmdv[i]); tiPtr->cmdc = elc; tiPtr->cmdv = cmdv; } { int isNew; char traceId[200]; Blt_HashEntry *hPtr; do { sprintf_s(traceId, 200, "trace%d", cmdPtr->nextTraceId++); hPtr = Blt_CreateHashEntry(&cmdPtr->traceTable, traceId, &isNew); } while (!isNew); tiPtr->hPtr = hPtr; Blt_SetHashValue(hPtr, tiPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), traceId, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceDeleteOp -- * * Deletes one or more traces. Can be any type of trace. * * Results: * A standard TCL result. If a name given doesn't represent a trace, * then TCL_ERROR is returned and an error message is left in the * interpreter result. * * Example: * $t trace delete $id... *--------------------------------------------------------------------------- */ static int TraceDeleteOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Blt_HashEntry *hPtr; TraceInfo *tiPtr; hPtr = Blt_FindHashEntry(&cmdPtr->traceTable, Tcl_GetString(objv[i])); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown trace \"", Tcl_GetString(objv[i]), "\"", (char *)NULL); return TCL_ERROR; } tiPtr = Blt_GetHashValue(hPtr); Blt_Table_DeleteTrace(tiPtr->trace); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceInfoOp -- * * Returns the details for a given trace. The name of the trace is * passed as an argument. The details are returned as a list of * key-value pairs: trace name, tag, row index, keys, flags, and the * command prefix. * * Results: * A standard TCL result. If the name given doesn't represent a trace, * then TCL_ERROR is returned and an error message is left in the * interpreter result. * * Example: * $t trace info $trace * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceInfoOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; TraceInfo *tiPtr; Tcl_Obj *listObjPtr; hPtr = Blt_FindHashEntry(&cmdPtr->traceTable, Tcl_GetString(objv[3])); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown trace \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } tiPtr = Blt_GetHashValue(hPtr); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); PrintTraceInfo(interp, tiPtr, listObjPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceNamesOp -- * * Returns the names of all the traces in use by this instance. Traces * created by other instances or object clients are not reported. * * Results: * Always TCL_OK. A list of trace names is left in the interpreter * result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TraceNamesOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&cmdPtr->traceTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_GetHashKey(&cmdPtr->traceTable, hPtr),-1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceOp -- * * This procedure is invoked to process trace operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec traceOps[] = { {"create", 1, TraceCreateOp, 7, 7, "row column how command",}, {"delete", 1, TraceDeleteOp, 3, 0, "traceId...",}, {"info", 1, TraceInfoOp, 4, 4, "traceId",}, {"names", 1, TraceNamesOp, 3, 3, "",}, }; static int nTraceOps = sizeof(traceOps) / sizeof(Blt_OpSpec); static int TraceOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTraceOps, traceOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (cmdPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * SetOp -- * * Sets one or more key-value pairs for tables. One or more tables may * be set. If any of the columns (keys) given don't already exist, the * columns will be automatically created. The same holds true for rows. * If a row index is beyond the end of the table (tags are always in * range), new rows are allocated. * * Results: * A standard TCL result. If the tag or index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t set $row $column $value ?row column value?... * *--------------------------------------------------------------------------- */ static int SetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; if (((objc - 2) % 3) != 0) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " set ?row column value?...\"", (char *)NULL); return TCL_ERROR; } table = cmdPtr->table; for (i = 2; i < objc; i += 3) { Blt_TableIterator ri, ci; Blt_TableColumn col; if (IterateRows(interp, table, objv[i], &ri) != TCL_OK) { return TCL_ERROR; } if (IterateColumns(interp, table, objv[i + 1], &ci) != TCL_OK) { return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&ci); col != NULL; col = Blt_Table_NextTaggedColumn(&ci)) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&ri); row != NULL; row = Blt_Table_NextTaggedRow(&ri)) { if (Blt_Table_SetObj(table, row, col, objv[i+2]) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnsetOp -- * * $t unset row column ?row column? * * Unsets one or more values. One or more tables may be unset (using * tags). It's not an error if one of the key names (columns) doesn't * exist. The same holds true for rows. If a row index is beyond the * end of the table (tags are always in range), it is also ignored. * * Results: * A standard TCL result. If the tag or index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * *--------------------------------------------------------------------------- */ static int UnsetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; int i; if ((objc - 2) & 1) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " unset ?row column?...", (char *)NULL); return TCL_ERROR; } table = cmdPtr->table; for (i = 2; i < objc; i += 2) { Blt_TableIterator ri, ci; Blt_TableColumn col; if (Blt_Table_IterateRows(NULL, table, objv[i], &ri) != TCL_OK) { return TCL_OK; } if (Blt_Table_IterateColumns(NULL, table, objv[i+1], &ci) != TCL_OK) { return TCL_OK; } for (col = Blt_Table_FirstTaggedColumn(&ci); col != NULL; col = Blt_Table_NextTaggedColumn(&ci)) { Blt_TableRow row; for (row = Blt_Table_FirstTaggedRow(&ri); row != NULL; row = Blt_Table_NextTaggedRow(&ri)) { if (Blt_Table_UnsetValue(table, row, col) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RestoreOp -- * * $t restore $string -overwrite -notags * $t restorefile $fileName -overwrite -notags * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RestoreOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { RestoreSwitches switches; int result; memset((char *)&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, restoreSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "can't set both -file and -data switches.", (char *)NULL); return TCL_ERROR; } if (switches.dataObjPtr != NULL) { result = Blt_Table_Restore(interp, cmdPtr->table, Tcl_GetString(switches.dataObjPtr), switches.flags); } else if (switches.fileObjPtr != NULL) { result = Blt_Table_FileRestore(interp, cmdPtr->table, Tcl_GetString(switches.fileObjPtr), switches.flags); } else { result = Blt_Table_FileRestore(interp, cmdPtr->table, "out.dump", switches.flags); } Blt_FreeSwitches(restoreSwitches, &switches, 0); return result; } static int WriteRecord(Tcl_Channel channel, Tcl_DString *dsPtr) { int length, nWritten; char *line; length = Tcl_DStringLength(dsPtr); line = Tcl_DStringValue(dsPtr); #if HAVE_UTF #ifdef notdef nWritten = Tcl_WriteChars(channel, line, length); #endif nWritten = Tcl_Write(channel, line, length); #else nWritten = Tcl_Write(channel, line, length); #endif if (nWritten != length) { return FALSE; } Tcl_DStringSetLength(dsPtr, 0); return TRUE; } /* *--------------------------------------------------------------------------- * * DumpHeader -- * * Prints the info associated with a column into a dynamic * string. * * Results: * None. * *--------------------------------------------------------------------------- */ static int DumpHeader(DumpSwitches *dumpPtr, long nRows, long nCols) { /* i rows columns ctime mtime \n */ Tcl_DStringAppendElement(dumpPtr->dsPtr, "i"); /* # of rows and columns may be a subset of the table. */ Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(nRows)); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(nCols)); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(0)); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(0)); Tcl_DStringAppend(dumpPtr->dsPtr, "\n", 1); if (dumpPtr->channel != NULL) { return WriteRecord(dumpPtr->channel, dumpPtr->dsPtr); } return TRUE; } /* *--------------------------------------------------------------------------- * * DumpValue -- * * Retrieves all tags for a given row or column into a tcl list. * * Results: * None. * *--------------------------------------------------------------------------- */ static int DumpValue(Blt_Table table, DumpSwitches *dumpPtr, Blt_TableRow row, Blt_TableColumn col) { const char *string; string = Blt_Table_GetString(table, row, col); if (string == NULL) { return TRUE; } /* d row column value \n */ Tcl_DStringAppendElement(dumpPtr->dsPtr, "d"); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(Blt_Table_RowIndex(row))); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(Blt_Table_ColumnIndex(col))); Tcl_DStringAppendElement(dumpPtr->dsPtr, string); Tcl_DStringAppend(dumpPtr->dsPtr, "\n", 1); if (dumpPtr->channel != NULL) { return WriteRecord(dumpPtr->channel, dumpPtr->dsPtr); } return TRUE; } /* *--------------------------------------------------------------------------- * * DumpColumn -- * * Prints the info associated with a column into a dynamic string. * *--------------------------------------------------------------------------- */ static int DumpColumn(Blt_Table table, DumpSwitches *dumpPtr, Blt_TableColumn col) { Blt_Chain colTags; Blt_ChainLink link; const char *name; /* c index label type tags \n */ Tcl_DStringAppendElement(dumpPtr->dsPtr, "c"); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(Blt_Table_ColumnIndex(col))); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Table_ColumnLabel(col)); name = Blt_Table_NameOfType(Blt_Table_ColumnType(col)); if (name == NULL) { name = ""; } Tcl_DStringAppendElement(dumpPtr->dsPtr, name); colTags = Blt_Table_ColumnTags(table, col); Tcl_DStringStartSublist(dumpPtr->dsPtr); for (link = Blt_Chain_FirstLink(colTags); link != NULL; link = Blt_Chain_NextLink(link)) { const char *tagName; tagName = Blt_Chain_GetValue(link); Tcl_DStringAppendElement(dumpPtr->dsPtr, tagName); } Blt_Chain_Destroy(colTags); Tcl_DStringEndSublist(dumpPtr->dsPtr); Tcl_DStringAppend(dumpPtr->dsPtr, "\n", 1); if (dumpPtr->channel != NULL) { return WriteRecord(dumpPtr->channel, dumpPtr->dsPtr); } return TRUE; } /* *--------------------------------------------------------------------------- * * DumpRow -- * * Prints the info associated with a row into a dynamic string. * *--------------------------------------------------------------------------- */ static int DumpRow(Blt_Table table, DumpSwitches *dumpPtr, Blt_TableRow row) { Blt_Chain rowTags; Blt_ChainLink link; /* r index label tags \n */ Tcl_DStringAppendElement(dumpPtr->dsPtr, "r"); Tcl_DStringAppendElement(dumpPtr->dsPtr, Blt_Ltoa(Blt_Table_RowIndex(row))); Tcl_DStringAppendElement(dumpPtr->dsPtr, (char *)Blt_Table_RowLabel(row)); Tcl_DStringStartSublist(dumpPtr->dsPtr); rowTags = Blt_Table_RowTags(table, row); for (link = Blt_Chain_FirstLink(rowTags); link != NULL; link = Blt_Chain_NextLink(link)) { const char *tagName; tagName = Blt_Chain_GetValue(link); Tcl_DStringAppendElement(dumpPtr->dsPtr, tagName); } Blt_Chain_Destroy(rowTags); Tcl_DStringEndSublist(dumpPtr->dsPtr); Tcl_DStringAppend(dumpPtr->dsPtr, "\n", 1); if (dumpPtr->channel != NULL) { return WriteRecord(dumpPtr->channel, dumpPtr->dsPtr); } return TRUE; } /* *--------------------------------------------------------------------------- * * DumpTable -- * * Dumps data from the given table based upon the row and column maps * provided which describe what rows and columns are to be dumped. The * dump information is written to the file named. If the file name starts * with an '@', then it is the name of an already opened channel to be * used. * * Results: * A standard TCL result. If the dump was successful, TCL_OK is * returned. Otherwise, TCL_ERROR is returned and an error message is * left in the interpreter result. * * Side Effects: * Dump information is written to the named file. * *--------------------------------------------------------------------------- */ static int DumpTable(Blt_Table table, DumpSwitches *dumpPtr) { int result; long nCols, nRows; Blt_TableColumn col; Blt_TableRow row; if (dumpPtr->ri.chain != NULL) { nRows = Blt_Chain_GetLength(dumpPtr->ri.chain); } else { nRows = Blt_Table_NumRows(table); } if (dumpPtr->ci.chain != NULL) { nCols = Blt_Chain_GetLength(dumpPtr->ci.chain); } else { nCols = Blt_Table_NumColumns(table); } result = DumpHeader(dumpPtr, nRows, nCols); for (col = Blt_Table_FirstTaggedColumn(&dumpPtr->ci); (result) && (col != NULL); col = Blt_Table_NextTaggedColumn(&dumpPtr->ci)) { result = DumpColumn(table, dumpPtr, col); } for (row = Blt_Table_FirstTaggedRow(&dumpPtr->ri); (result) && (row != NULL); row = Blt_Table_NextTaggedRow(&dumpPtr->ri)) { result = DumpRow(table, dumpPtr, row); } for (col = Blt_Table_FirstTaggedColumn(&dumpPtr->ci); (result) && (col != NULL); col = Blt_Table_NextTaggedColumn(&dumpPtr->ci)) { for (row = Blt_Table_FirstTaggedRow(&dumpPtr->ri); (result) && (row != NULL); row = Blt_Table_NextTaggedRow(&dumpPtr->ri)) { result = DumpValue(table, dumpPtr, row, col); } } return (result) ? TCL_OK : TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DumpOp -- * * set data [$t dump -rows {} -columns {}] * $t dump -file fileName -rows {} -columns {} *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DumpOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_Table table; DumpSwitches switches; int result; Tcl_DString ds; int closeChannel; Tcl_Channel channel; closeChannel = FALSE; channel = NULL; table = cmdPtr->table; result = TCL_ERROR; memset(&switches, 0, sizeof(switches)); switches.channel = channel; switches.dsPtr = &ds; rowIterSwitch.clientData = cmdPtr->table; columnIterSwitch.clientData = cmdPtr->table; Blt_Table_IterateAllRows(table, &switches.ri); Blt_Table_IterateAllColumns(table, &switches.ci); if (Blt_ParseSwitches(interp, dumpSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } if (switches.fileObjPtr != NULL) { const char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { goto error; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "can't dump table: channel \"", fileName, "\" not opened for writing", (char *)NULL); goto error; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { goto error; } } switches.channel = channel; } Tcl_DStringInit(&ds); result = DumpTable(table, &switches); if ((switches.channel == NULL) && (result == TCL_OK)) { Tcl_DStringResult(interp, &ds); } Tcl_DStringFree(&ds); error: if (closeChannel) { Tcl_Close(interp, channel); } Blt_FreeSwitches(dumpSwitches, &switches, 0); return result; } /* *--------------------------------------------------------------------------- * * EmptyValueOp -- * * $t emptyvalue ?$value? * *--------------------------------------------------------------------------- */ static int EmptyValueOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetStringObj(Tcl_GetObjResult(interp), cmdPtr->emptyValue, -1); if (objc == 3) { if (cmdPtr->emptyValue != NULL) { Blt_Free(cmdPtr->emptyValue); cmdPtr->emptyValue = Blt_AssertStrdup(Tcl_GetString(objv[2])); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExistsOp -- * * $t exists $row $column * *--------------------------------------------------------------------------- */ static int ExistsOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; Blt_TableRow row; Blt_TableColumn col; bool = FALSE; row = Blt_Table_FindRow(NULL, cmdPtr->table, objv[2]); col = Blt_Table_FindColumn(NULL, cmdPtr->table, objv[3]); if ((row != NULL) && (col != NULL)) { bool = Blt_Table_ValueExists(cmdPtr->table, row, col); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindOp -- * * Parses the given command line and calls one of several export-specific * operations. * * Results: * Returns a standard TCL result. It is the result of operation called. * * Example: * $t find expr ?switches? * *--------------------------------------------------------------------------- */ static int FindOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { FindSwitches switches; int result; memset(&switches, 0, sizeof(switches)); rowIterSwitch.clientData = cmdPtr->table; Blt_Table_IterateAllRows(cmdPtr->table, &switches.iter); if (Blt_ParseSwitches(interp, findSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } switches.table = cmdPtr->table; Blt_InitHashTable(&switches.varTable, BLT_ONE_WORD_KEYS); result = FindRows(interp, cmdPtr->table, objv[2], &switches); Blt_FreeSwitches(findSwitches, &switches, 0); return result; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Retrieves the value from a given table for a designated row,column * location. * * Normally it's an error if the column or row key is invalid or the data * slot is empty (the Tcl_Obj is NULL). But if an extra argument is * provided, then it is returned as a default value. * * Results: * A standard TCL result. If the tag or index is invalid, TCL_ERROR is * returned and an error message is left in the interpreter result. * * Example: * $t get row column ?defValue? * *--------------------------------------------------------------------------- */ static int GetOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *objPtr; Blt_TableRow row; Blt_TableColumn col; row = Blt_Table_FindRow(interp, cmdPtr->table, objv[2]); if (row == NULL) { if (objc == 5) { objPtr = objv[4]; goto done; } return TCL_ERROR; } col = Blt_Table_FindColumn(interp, cmdPtr->table, objv[3]); if (col == NULL) { if (objc == 5) { objPtr = objv[4]; goto done; } return TCL_ERROR; } objPtr = Blt_Table_GetObj(cmdPtr->table, row, col); if (objPtr == NULL) { if (objc == 5) { objPtr = objv[4]; } else { objPtr = Tcl_NewStringObj(cmdPtr->emptyValue, -1); } } done: Tcl_SetObjResult(interp, objPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AttachOp -- * *--------------------------------------------------------------------------- */ static int AttachOp(Cmd *cmdPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { const char *qualName; Blt_ObjectName objName; Blt_Table table; Tcl_DString ds; int result; if (!Blt_ParseObjectName(interp, Tcl_GetString(objv[2]), &objName, 0)) { return TCL_ERROR; } qualName = Blt_MakeQualifiedName(&objName, &ds); result = Blt_Table_Open(interp, qualName, &table); Tcl_DStringFree(&ds); if (result != TCL_OK) { return TCL_ERROR; } if (cmdPtr->table != NULL) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Blt_Table_Close(cmdPtr->table); /* Free the current set of tags, traces, and notifiers. */ for (hPtr = Blt_FirstHashEntry(&cmdPtr->traceTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { TraceInfo *tiPtr; tiPtr = Blt_GetHashValue(hPtr); Blt_Table_DeleteTrace(tiPtr->trace); } Blt_DeleteHashTable(&cmdPtr->traceTable); Blt_InitHashTable(&cmdPtr->traceTable, TCL_STRING_KEYS); for (hPtr = Blt_FirstHashEntry(&cmdPtr->notifyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { NotifierInfo *niPtr; niPtr = Blt_GetHashValue(hPtr); FreeNotifierInfo(niPtr); } Blt_DeleteHashTable(&cmdPtr->notifyTable); Blt_InitHashTable(&cmdPtr->notifyTable, TCL_STRING_KEYS); } cmdPtr->table = table; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Blt_Table_TableName(cmdPtr->table), -1); return TCL_OK; } static Blt_OpSpec tableOps[] = { {"add", 2, AddOp, 3, 0, "table ?switches?",}, {"append", 2, AppendOp, 5, 0, "row column value ?value...?",}, {"attach", 2, AttachOp, 3, 0, "args...",}, {"column", 3, ColumnOp, 3, 0, "op args...",}, #ifdef notdef {"dup", 1, DupOp, 3, 0, "args...",}, #endif {"dump", 1, DumpOp, 2, 0, "?switches?",}, {"emptyvalue", 2, EmptyValueOp, 2, 3, "?newValue?",}, {"exists", 3, ExistsOp, 4, 4, "row column",}, {"export", 3, ExportOp, 2, 0, "format args...",}, {"find", 1, FindOp, 3, 0, "expr ?switches?",}, {"get", 1, GetOp, 4, 5, "row column ?defValue?",}, {"import", 1, ImportOp, 2, 0, "format args...",}, {"keys", 1, KeysOp, 2, 0, "?column...?",}, {"lappend", 2, LappendOp, 5, 0, "row column value ?value...?",}, {"lookup", 2, LookupOp, 2, 0, "?value...?",}, {"notify", 1, NotifyOp, 2, 0, "op args...",}, {"restore", 2, RestoreOp, 2, 0, "?switches?",}, {"row", 2, RowOp, 3, 0, "op args...",}, {"set", 2, SetOp, 3, 0, "?row column value?...",}, {"sort", 2, SortOp, 3, 0, "?flags...?",}, {"trace", 2, TraceOp, 2, 0, "op args...",}, {"unset", 1, UnsetOp, 4, 0, "row column ?row column?",}, #ifdef notplanned {"-apply", 1, ApplyOp, 3, 0, "first last ?switches?",}, {"copy", 2, CopyOp, 4, 0, "srcNode ?destTable? destNode ?switches?",}, #endif }; static int nTableOps = sizeof(tableOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * TableInstObjCmd -- * * This procedure is invoked to process commands on behalf of * the * instance of the table-object. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int TableInstObjCmd( ClientData clientData, /* Pointer to the datatable command * structure. */ Tcl_Interp *interp, /* Interpreter to report errors. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Vector of argument strings. */ { CmdProc *proc; Cmd *cmdPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nTableOps, tableOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(cmdPtr); result = (*proc) (cmdPtr, interp, objc, objv); Tcl_Release(cmdPtr); return result; } /* *--------------------------------------------------------------------------- * * TableInstDeleteProc -- * * Deletes the command associated with the table. This is called only * when the command associated with the table is destroyed. * * Results: * None. * * Side Effects: * The table object is released and bookkeeping data for traces and * notifiers are freed. * *--------------------------------------------------------------------------- */ static void TableInstDeleteProc(ClientData clientData) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Cmd *cmdPtr = clientData; for (hPtr = Blt_FirstHashEntry(&cmdPtr->traceTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { TraceInfo *tiPtr; tiPtr = Blt_GetHashValue(hPtr); Blt_Table_DeleteTrace(tiPtr->trace); } Blt_DeleteHashTable(&cmdPtr->traceTable); for (hPtr = Blt_FirstHashEntry(&cmdPtr->notifyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { NotifierInfo *niPtr; niPtr = Blt_GetHashValue(hPtr); FreeNotifierInfo(niPtr); } if (cmdPtr->emptyValue != NULL) { Blt_Free(cmdPtr->emptyValue); } Blt_DeleteHashTable(&cmdPtr->notifyTable); if (cmdPtr->hPtr != NULL) { Blt_DeleteHashEntry(cmdPtr->tablePtr, cmdPtr->hPtr); } Blt_Table_Close(cmdPtr->table); Blt_Free(cmdPtr); } /* *--------------------------------------------------------------------------- * * TableCreateOp -- * * Creates a new instance of a table object. * * This routine insures that instance and object names are the same. For * example, you can't create an instance with the name of an object that * already exists. And because each instance has a TCL command * associated with it (used to access the object), we additionally check * more that it's not an existing TCL command. * * Instance names are namespace-qualified. If the given name doesn't * have a namespace qualifier, that instance will be created in the * current namespace (not the global namespace). * * Results: * A standard TCL result. If the instance is successfully created, the * namespace-qualified name of the instance is returned. If not, then * TCL_ERROR is returned and an error message is left in the interpreter * result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TableCreateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *instName; Tcl_DString ds; Blt_Table table; instName = NULL; if (objc == 3) { instName = Tcl_GetString(objv[2]); } Tcl_DStringInit(&ds); if (instName == NULL) { instName = GenerateName(interp, "", "", &ds); } else { char *p; p = strstr(instName, "#auto"); if (p != NULL) { *p = '\0'; instName = GenerateName(interp, instName, p + 5, &ds); *p = '#'; } else { Blt_ObjectName objName; Tcl_CmdInfo cmdInfo; /* * Parse the command and put back so that it's in a consistent * format. * * t1 <current namespace>::t1 * n1::t1 <current namespace>::n1::t1 * ::t1 ::t1 * ::n1::t1 ::n1::t1 */ if (!Blt_ParseObjectName(interp, instName, &objName, 0)) { return TCL_ERROR; } instName = Blt_MakeQualifiedName(&objName, &ds); /* * Check if the command already exists. */ if (Tcl_GetCommandInfo(interp, (char *)instName, &cmdInfo)) { Tcl_AppendResult(interp, "a command \"", instName, "\" already exists", (char *)NULL); goto error; } if (Blt_Table_TableExists(interp, instName)) { Tcl_AppendResult(interp, "a table \"", instName, "\" already exists", (char *)NULL); goto error; } } } if (instName == NULL) { goto error; } if (Blt_Table_CreateTable(interp, instName, &table) == TCL_OK) { Cmd *cmdPtr; cmdPtr = NewTableCmd(interp, table, instName); Tcl_SetStringObj(Tcl_GetObjResult(interp), instName, -1); Tcl_DStringFree(&ds); return TCL_OK; } error: Tcl_DStringFree(&ds); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TableDestroyOp -- * * Deletes one or more instances of table objects. The deletion process * is done by deleting the TCL command associated with the object. * * Results: * A standard TCL result. If one of the names given doesn't represent an * instance, TCL_ERROR is returned and an error message is left in the * interpreter result. * *--------------------------------------------------------------------------- */ static int TableDestroyOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { Cmd *cmdPtr; cmdPtr = GetTableCmd(interp, Tcl_GetString(objv[i])); if (cmdPtr == NULL) { Tcl_AppendResult(interp, "can't find table \"", Tcl_GetString(objv[i]), "\"", (char *)NULL); return TCL_ERROR; } Tcl_DeleteCommandFromToken(interp, cmdPtr->cmdToken); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TableNamesOp -- * * Returns the names of all the table-object instances matching a given * pattern. If no pattern argument is provided, then all object names * are returned. The names returned are namespace qualified. * * Results: * Always returns TCL_OK. The names of the matching objects is returned * via the interpreter result. * * Example: * $t names ?pattern? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TableNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TableCmdInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&dataPtr->instTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { const char *name; int match; int i; name = Blt_GetHashKey(&dataPtr->instTable, hPtr); match = TRUE; for (i = 2; i < objc; i++) { match = Tcl_StringMatch(name, Tcl_GetString(objv[i])); if (match) { break; } } if (!match) { continue; } Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(name, -1)); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int TableLoadOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; TableCmdInterpData *dataPtr = clientData; Tcl_DString libName; const char *fmt; char *safeProcName, *initProcName; int result; int length; fmt = Tcl_GetStringFromObj(objv[2], &length); hPtr = Blt_FindHashEntry(&dataPtr->fmtTable, fmt); if (hPtr != NULL) { return TCL_OK; /* Converter is already loaded. */ } Tcl_DStringInit(&libName); { Tcl_DString pathName; const char *path; Tcl_DStringInit(&pathName); path = Tcl_TranslateFileName(interp, Tcl_GetString(objv[3]), &pathName); if (path == NULL) { Tcl_DStringFree(&pathName); return TCL_ERROR; } Tcl_DStringAppend(&libName, path, -1); Tcl_DStringFree(&pathName); } Tcl_DStringAppend(&libName, "/", -1); Tcl_UtfToTitle((char *)fmt); Tcl_DStringAppend(&libName, "Table", 5); Tcl_DStringAppend(&libName, fmt, -1); Tcl_DStringAppend(&libName, Blt_Itoa(BLT_MAJOR_VERSION), 1); Tcl_DStringAppend(&libName, Blt_Itoa(BLT_MINOR_VERSION), 1); Tcl_DStringAppend(&libName, BLT_LIB_SUFFIX, -1); Tcl_DStringAppend(&libName, BLT_SO_EXT, -1); initProcName = Blt_AssertMalloc(10 + length + 4 + 1); sprintf_s(initProcName, 10 + length + 4 + 1, "Blt_Table_%sInit", fmt); safeProcName = Blt_AssertMalloc(10 + length + 8 + 1); sprintf_s(safeProcName, 10 + length + 8 + 1, "Blt_Table_%sSafeInit",fmt); result = Blt_LoadLibrary(interp, Tcl_DStringValue(&libName), initProcName, safeProcName); Tcl_DStringFree(&libName); if (safeProcName != NULL) { Blt_Free(safeProcName); } if (initProcName != NULL) { Blt_Free(initProcName); } return result; } /* *--------------------------------------------------------------------------- * * TableObjCmd -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec tableCmdOps[] = { {"create", 1, TableCreateOp, 2, 3, "?name?",}, {"destroy", 1, TableDestroyOp, 3, 0, "name...",}, {"load", 1, TableLoadOp, 4, 4, "name libpath",}, {"names", 1, TableNamesOp, 2, 3, "?pattern?...",}, }; static int nCmdOps = sizeof(tableCmdOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int TableObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { CmdProc *proc; proc = Blt_GetOpFromObj(interp, nCmdOps, tableCmdOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * TableInterpDeleteProc -- * * This is called when the interpreter registering the "datatable" * command is deleted. * * Results: * None. * * Side Effects: * Removes the hash table managing all table names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TableInterpDeleteProc(ClientData clientData, Tcl_Interp *interp) { TableCmdInterpData *dataPtr = clientData; /* All table instances should already have been destroyed when their * respective TCL commands were deleted. */ Blt_DeleteHashTable(&dataPtr->instTable); Blt_DeleteHashTable(&dataPtr->fmtTable); Blt_DeleteHashTable(&dataPtr->findTable); Tcl_DeleteAssocData(interp, TABLE_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * Blt_TableCmdInitProc -- * * This procedure is invoked to initialize the "dtable" command. * * Results: * None. * * Side Effects: * Creates the new command and adds a new entry into a global Tcl * associative array. * *--------------------------------------------------------------------------- */ int Blt_TableCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "datatable", TableObjCmd, }; cmdSpec.clientData = GetTableCmdInterpData(interp); if (Blt_InitCmd(interp, "::blt", &cmdSpec) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* Dump table to dbm */ /* Convert node data to datablock */ int Blt_Table_RegisterFormat(Tcl_Interp *interp, const char *fmt, Blt_TableImportProc *importProc, Blt_TableExportProc *exportProc) { Blt_HashEntry *hPtr; DataFormat *fmtPtr; TableCmdInterpData *dataPtr; int isNew; dataPtr = GetTableCmdInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->fmtTable, fmt, &isNew); if (isNew) { fmtPtr = Blt_AssertMalloc(sizeof(DataFormat)); fmtPtr->name = Blt_AssertStrdup(fmt); Blt_SetHashValue(hPtr, fmtPtr); } else { fmtPtr = Blt_GetHashValue(hPtr); } fmtPtr->isLoaded = TRUE; fmtPtr->importProc = importProc; fmtPtr->exportProc = exportProc; return TCL_OK; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPs.c�����������������������������������������������������������������������0000644�0001750�0001750�00000131454�11462120062�014265� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPs.c -- * * This module implements general PostScript conversion routines. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "bltInt.h" #include <stdarg.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include "tkIntBorder.h" #include "bltDBuffer.h" #include "bltPicture.h" #include "bltPsInt.h" #include "tkDisplay.h" #include "tkFont.h" #define PS_MAXPATH 1500 /* Maximum number of components in a * PostScript (level 1) path. */ #define PICA_MM 2.83464566929 #define PICA_INCH 72.0 #define PICA_CM 28.3464566929 static Tcl_Interp *psInterp = NULL; /* *--------------------------------------------------------------------------- * * Blt_Ps_GetPica -- * * Given a string, returns the number of pica corresponding to that * string. * * Results: * The return value is a standard TCL return result. If TCL_OK is * returned, then everything went well and the pixel distance is stored * at *doublePtr; otherwise TCL_ERROR is returned and an error message is * left in interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_Ps_GetPicaFromObj( Tcl_Interp *interp, /* Use this for error reporting. */ Tcl_Obj *objPtr, /* String describing a number of * pixels. */ int *picaPtr) /* Place to store converted result. */ { char *p; double pica; const char *string; string = Tcl_GetString(objPtr); pica = strtod((char *)string, &p); if (p == string) { goto error; } if (pica < 0.0) { goto error; } while ((*p != '\0') && isspace(UCHAR(*p))) { p++; } switch (*p) { case '\0': break; case 'c': pica *= PICA_CM; p++; break; case 'i': pica *= PICA_INCH; p++; break; case 'm': pica *= PICA_MM; p++; break; case 'p': p++; break; default: goto error; } while ((*p != '\0') && isspace(UCHAR(*p))) { p++; } if (*p == '\0') { *picaPtr = ROUND(pica); return TCL_OK; } error: Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", (char *) NULL); return TCL_ERROR; } int Blt_Ps_GetPadFromObj( Tcl_Interp *interp, /* Interpreter to send results back * to */ Tcl_Obj *objPtr, /* Pixel value string */ Blt_Pad *padPtr) { int side1, side2; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if ((objc < 1) || (objc > 2)) { Tcl_AppendResult(interp, "wrong # elements in padding list", (char *)NULL); return TCL_ERROR; } if (Blt_Ps_GetPicaFromObj(interp, objv[0], &side1) != TCL_OK) { return TCL_ERROR; } side2 = side1; if ((objc > 1) && (Blt_Ps_GetPicaFromObj(interp, objv[1], &side2) != TCL_OK)) { return TCL_ERROR; } /* Don't update the pad structure until we know both values are okay. */ padPtr->side1 = side1; padPtr->side2 = side2; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Ps_ComputeBoundingBox -- * * Computes the bounding box for the PostScript plot. First get the size * of the plot (by default, it's the size of graph's X window). If the * plot plus the page border is bigger than the designated paper size, or * if the "-maxpect" option is turned on, scale the plot to the page. * * Note: All coordinates/sizes are in screen coordinates, not PostScript * coordinates. This includes the computed bounding box and paper * size. They will be scaled to printer points later. * * Results: * Returns the height of the paper in screen coordinates. * * Side Effects: * The graph dimensions (width and height) are changed to the requested * PostScript plot size. * *--------------------------------------------------------------------------- */ int Blt_Ps_ComputeBoundingBox(PageSetup *setupPtr, int width, int height) { int paperWidth, paperHeight; int x, y, hSize, vSize, hBorder, vBorder; float hScale, vScale, scale; x = setupPtr->padLeft; y = setupPtr->padTop; hBorder = PADDING(setupPtr->xPad); vBorder = PADDING(setupPtr->yPad); if (setupPtr->flags & PS_LANDSCAPE) { hSize = height; vSize = width; } else { hSize = width; vSize = height; } /* * If the paper size wasn't specified, set it to the graph size plus the * paper border. */ paperWidth = (setupPtr->reqPaperWidth > 0) ? setupPtr->reqPaperWidth : hSize + hBorder; paperHeight = (setupPtr->reqPaperHeight > 0) ? setupPtr->reqPaperHeight : vSize + vBorder; /* * Scale the plot size (the graph itself doesn't change size) if it's * bigger than the paper or if -maxpect was set. */ hScale = vScale = 1.0f; if ((setupPtr->flags & PS_MAXPECT) || ((hSize + hBorder) > paperWidth)) { hScale = (float)(paperWidth - hBorder) / (float)hSize; } if ((setupPtr->flags & PS_MAXPECT) || ((vSize + vBorder) > paperHeight)) { vScale = (float)(paperHeight - vBorder) / (float)vSize; } scale = MIN(hScale, vScale); if (scale != 1.0f) { hSize = (int)((hSize * scale) + 0.5f); vSize = (int)((vSize * scale) + 0.5f); } setupPtr->scale = scale; if (setupPtr->flags & PS_CENTER) { if (paperWidth > hSize) { x = (paperWidth - hSize) / 2; } if (paperHeight > vSize) { y = (paperHeight - vSize) / 2; } } setupPtr->left = x; setupPtr->bottom = y; setupPtr->right = x + hSize - 1; setupPtr->top = y + vSize - 1; setupPtr->paperHeight = paperHeight; setupPtr->paperWidth = paperWidth; return paperHeight; } PostScript * Blt_Ps_Create(Tcl_Interp *interp, PageSetup *setupPtr) { PostScript *psPtr; psPtr = Blt_AssertMalloc(sizeof(PostScript)); psPtr->setupPtr = setupPtr; psPtr->interp = interp; Tcl_DStringInit(&psPtr->dString); return psPtr; } void Blt_Ps_SetPrinting(PostScript *psPtr, int state) { psInterp = ((state) && (psPtr != NULL)) ? psPtr->interp : NULL; } int Blt_Ps_IsPrinting(void) { return (psInterp != NULL); } void Blt_Ps_Free(PostScript *psPtr) { Tcl_DStringFree(&psPtr->dString); Blt_Free(psPtr); } const char * Blt_Ps_GetValue(PostScript *psPtr, int *lengthPtr) { *lengthPtr = strlen(Tcl_DStringValue(&psPtr->dString)); return Tcl_DStringValue(&psPtr->dString); } void Blt_Ps_SetInterp(PostScript *psPtr, Tcl_Interp *interp) { Tcl_DStringResult(interp, &psPtr->dString); } char * Blt_Ps_GetScratchBuffer(PostScript *psPtr) { return psPtr->scratchArr; } Tcl_Interp * Blt_Ps_GetInterp(PostScript *psPtr) { return psPtr->interp; } Tcl_DString * Blt_Ps_GetDString(PostScript *psPtr) { return &psPtr->dString; } int Blt_Ps_SaveFile(Tcl_Interp *interp, PostScript *psPtr, const char *fileName) { Tcl_Channel channel; int nWritten, nBytes; char *bytes; channel = Tcl_OpenFileChannel(interp, fileName, "w", 0660); if (channel == NULL) { return TCL_ERROR; } nBytes = Tcl_DStringLength(&psPtr->dString); bytes = Tcl_DStringValue(&psPtr->dString); nWritten = Tcl_Write(channel, bytes, nBytes); Tcl_Close(interp, channel); if (nWritten != nBytes) { Tcl_AppendResult(interp, "short file \"", fileName, (char *)NULL); Tcl_AppendResult(interp, "\" : wrote ", Blt_Itoa(nWritten), " of ", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(nBytes), " bytes.", (char *)NULL); return TCL_ERROR; } return TCL_OK; } void Blt_Ps_VarAppend TCL_VARARGS_DEF(PostScript *, arg1) { va_list argList; PostScript *psPtr; const char *string; psPtr = TCL_VARARGS_START(PostScript, arg1, argList); for (;;) { string = va_arg(argList, char *); if (string == NULL) { break; } Tcl_DStringAppend(&psPtr->dString, string, -1); } } void Blt_Ps_AppendBytes(PostScript *psPtr, const char *bytes, int length) { Tcl_DStringAppend(&psPtr->dString, bytes, length); } void Blt_Ps_Append(PostScript *psPtr, const char *string) { Tcl_DStringAppend(&psPtr->dString, string, -1); } void Blt_Ps_Format TCL_VARARGS_DEF(PostScript *, arg1) { va_list argList; PostScript *psPtr; char *fmt; psPtr = TCL_VARARGS_START(PostScript, arg1, argList); fmt = va_arg(argList, char *); vsnprintf(psPtr->scratchArr, POSTSCRIPT_BUFSIZ, fmt, argList); va_end(argList); Tcl_DStringAppend(&psPtr->dString, psPtr->scratchArr, -1); } int Blt_Ps_IncludeFile(Tcl_Interp *interp, Blt_Ps ps, const char *fileName) { Tcl_Channel channel; Tcl_DString dString; char *buf; char *libDir; int nBytes; buf = Blt_Ps_GetScratchBuffer(ps); /* * Read in a standard prolog file from file and append it to the * PostScript output stored in the Tcl_DString in psPtr. */ libDir = (char *)Tcl_GetVar(interp, "blt_library", TCL_GLOBAL_ONLY); if (libDir == NULL) { Tcl_AppendResult(interp, "couldn't find BLT script library:", "global variable \"blt_library\" doesn't exist", (char *)NULL); return TCL_ERROR; } Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, libDir, -1); Tcl_DStringAppend(&dString, "/", -1); Tcl_DStringAppend(&dString, fileName, -1); fileName = Tcl_DStringValue(&dString); Blt_Ps_VarAppend(ps, "\n% including file \"", fileName, "\"\n\n", (char *)NULL); channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { Tcl_AppendResult(interp, "couldn't open prologue file \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } for(;;) { nBytes = Tcl_Read(channel, buf, POSTSCRIPT_BUFSIZ); if (nBytes < 0) { Tcl_AppendResult(interp, "error reading prologue file \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); Tcl_Close(interp, channel); Tcl_DStringFree(&dString); return TCL_ERROR; } if (nBytes == 0) { break; } buf[nBytes] = '\0'; Blt_Ps_Append(ps, buf); } Tcl_DStringFree(&dString); Tcl_Close(interp, channel); return TCL_OK; } /* *--------------------------------------------------------------------------- * * XColorToPostScript -- * * Convert the a XColor (from its RGB values) to a PostScript command. * If a Tk color map variable exists, it will be consulted for a * PostScript translation based upon the color name. * * Maps an X color intensity (0 to 2^16-1) to a floating point value * [0..1]. Many versions of Tk don't properly handle the the lower 8 * bits of the color intensity, so we can only consider the upper 8 bits. * * Results: * The string representing the color mode is returned. * *--------------------------------------------------------------------------- */ static void XColorToPostScript(Blt_Ps ps, XColor *colorPtr) { /* * Shift off the lower byte before dividing because some versions of Tk * don't fill the lower byte correctly. */ Blt_Ps_Format(ps, "%g %g %g", ((double)(colorPtr->red >> 8) / 255.0), ((double)(colorPtr->green >> 8) / 255.0), ((double)(colorPtr->blue >> 8) / 255.0)); } void Blt_Ps_XSetBackground(PostScript *psPtr, XColor *colorPtr) { /* If the color name exists in TCL array variable, use that translation */ if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->colorVarName != NULL)) { const char *psColor; psColor = Tcl_GetVar2(psPtr->interp, psPtr->setupPtr->colorVarName, Tk_NameOfColor(colorPtr), 0); if (psColor != NULL) { Blt_Ps_VarAppend(psPtr, " ", psColor, "\n", (char *)NULL); return; } } XColorToPostScript(psPtr, colorPtr); Blt_Ps_Append(psPtr, " setrgbcolor\n"); if (psPtr->setupPtr->flags & PS_GREYSCALE) { Blt_Ps_Append(psPtr, " currentgray setgray\n"); } } void Blt_Ps_XSetForeground(PostScript *psPtr, XColor *colorPtr) { /* If the color name exists in TCL array variable, use that translation */ if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->colorVarName != NULL)) { const char *psColor; psColor = Tcl_GetVar2(psPtr->interp, psPtr->setupPtr->colorVarName, Tk_NameOfColor(colorPtr), 0); if (psColor != NULL) { Blt_Ps_VarAppend(psPtr, " ", psColor, "\n", (char *)NULL); return; } } XColorToPostScript(psPtr, colorPtr); Blt_Ps_Append(psPtr, " setrgbcolor\n"); if (psPtr->setupPtr->flags & PS_GREYSCALE) { Blt_Ps_Append(psPtr, " currentgray setgray\n"); } } /* *--------------------------------------------------------------------------- * * ReverseBits -- * * Convert a byte from a X image into PostScript image order. This * requires not only the nybbles to be reversed but also their bit * values. * * Results: * The converted byte is returned. * *--------------------------------------------------------------------------- */ INLINE static unsigned char ReverseBits(unsigned char byte) { byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xaa); byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xcc); byte = ((byte >> 4) & 0x0f) | ((byte << 4) & 0xf0); return byte; } /* *--------------------------------------------------------------------------- * * ByteToHex -- * * Convert a byte to its ASCII hexidecimal equivalent. * * Results: * The converted 2 ASCII character string is returned. * *--------------------------------------------------------------------------- */ INLINE static void ByteToHex(unsigned char byte, char *string) { static char hexDigits[] = "0123456789ABCDEF"; string[0] = hexDigits[byte >> 4]; string[1] = hexDigits[byte & 0x0F]; } #ifdef WIN32 /* *--------------------------------------------------------------------------- * * Blt_Ps_XSetBitmapData -- * * Output a PostScript image string of the given bitmap image. It is * assumed the image is one bit deep and a zero value indicates an * off-pixel. To convert to PostScript, the bits need to be reversed * from the X11 image order. * * Results: * None. * * Side Effects: * The PostScript image string is appended. * *--------------------------------------------------------------------------- */ void Blt_Ps_XSetBitmapData( PostScript *psPtr, Display *display, Pixmap bitmap, int width, int height) { unsigned char byte; int x, y, bitPos; unsigned long pixel; int byteCount; char string[10]; unsigned char *srcBits, *srcPtr; int bytesPerRow; srcBits = Blt_GetBitmapData(display, bitmap, width, height, &bytesPerRow); if (srcBits == NULL) { OutputDebugString("Can't get bitmap data"); return; } Blt_Ps_Append(psPtr, "\t<"); byteCount = bitPos = 0; /* Suppress compiler warning */ for (y = height - 1; y >= 0; y--) { srcPtr = srcBits + (bytesPerRow * y); byte = 0; for (x = 0; x < width; x++) { bitPos = x % 8; pixel = (*srcPtr & (0x80 >> bitPos)); if (pixel) { byte |= (unsigned char)(1 << bitPos); } if (bitPos == 7) { byte = ReverseBits(byte); ByteToHex(byte, string); string[2] = '\0'; byteCount++; srcPtr++; byte = 0; if (byteCount >= 30) { string[2] = '\n'; string[3] = '\t'; string[4] = '\0'; byteCount = 0; } Blt_Ps_Append(psPtr, string); } } /* x */ if (bitPos != 7) { byte = ReverseBits(byte); ByteToHex(byte, string); string[2] = '\0'; Blt_Ps_Append(psPtr, string); byteCount++; } } /* y */ Blt_Free(srcBits); Blt_Ps_Append(psPtr, ">\n"); } #else /* *--------------------------------------------------------------------------- * * Blt_Ps_XSetBitmapData -- * * Output a PostScript image string of the given bitmap image. It is * assumed the image is one bit deep and a zero value indicates an * off-pixel. To convert to PostScript, the bits need to be reversed * from the X11 image order. * * Results: * None. * * Side Effects: * The PostScript image string is appended to interp->result. * *--------------------------------------------------------------------------- */ void Blt_Ps_XSetBitmapData(Blt_Ps ps, Display *display, Pixmap bitmap, int w, int h) { XImage *imagePtr; int byteCount; int y, bitPos; imagePtr = XGetImage(display, bitmap, 0, 0, w, h, 1, ZPixmap); Blt_Ps_Append(ps, "\t<"); byteCount = bitPos = 0; /* Suppress compiler warning */ for (y = 0; y < h; y++) { unsigned char byte; char string[10]; int x; byte = 0; for (x = 0; x < w; x++) { unsigned long pixel; pixel = XGetPixel(imagePtr, x, y); bitPos = x % 8; byte |= (unsigned char)(pixel << bitPos); if (bitPos == 7) { byte = ReverseBits(byte); ByteToHex(byte, string); string[2] = '\0'; byteCount++; byte = 0; if (byteCount >= 30) { string[2] = '\n'; string[3] = '\t'; string[4] = '\0'; byteCount = 0; } Blt_Ps_Append(ps, string); } } /* x */ if (bitPos != 7) { byte = ReverseBits(byte); ByteToHex(byte, string); string[2] = '\0'; Blt_Ps_Append(ps, string); byteCount++; } } /* y */ Blt_Ps_Append(ps, ">\n"); XDestroyImage(imagePtr); } #endif /* WIN32 */ typedef struct { const char *alias; const char *fontName; } FamilyMap; static FamilyMap familyMap[] = { { "Arial", "Helvetica" }, { "AvantGarde", "AvantGarde" }, { "Bookman", "Bookman" }, { "Courier New", "Courier" }, { "Courier", "Courier" }, { "Geneva", "Helvetica" }, { "Helvetica", "Helvetica" }, { "Mathematica1", "Helvetica" }, { "Monaco", "Courier" }, { "New Century Schoolbook", "NewCenturySchlbk" }, { "New York", "Times" }, { "Nimbus Roman No9 L" "Times" }, { "Nimbus Sans L Condensed","Helvetica" }, { "Nimbus Sans L", "Helvetica" }, { "Palatino", "Palatino" }, { "Standard Symbols L", "Symbol" }, { "Swiss 721", "Helvetica" }, { "Symbol", "Symbol" }, { "Times New Roman", "Times" }, { "Times Roman", "Times" }, { "Times", "Times" }, { "ZapfChancery", "ZapfChancery" }, { "ZapfDingbats", "ZapfDingbats" } }; static int nFamilyNames = (sizeof(familyMap) / sizeof(FamilyMap)); static const char * FamilyToPsFamily(const char *family) { FamilyMap *fp, *fend; if (strncasecmp(family, "itc ", 4) == 0) { family += 4; } for (fp = familyMap, fend = fp + nFamilyNames; fp < fend; fp++) { if (strcasecmp(fp->alias, family) == 0) { return fp->fontName; } } return NULL; } /* *--------------------------------------------------------------------------- * Routines to convert X drawing functions to PostScript commands. *--------------------------------------------------------------------------- */ void Blt_Ps_SetClearBackground(Blt_Ps ps) { Blt_Ps_Append(ps, "1 1 1 setrgbcolor\n"); } void Blt_Ps_XSetCapStyle(Blt_Ps ps, int capStyle) { /* * X11:not last = 0, butt = 1, round = 2, projecting = 3 * PS: butt = 0, round = 1, projecting = 2 */ if (capStyle > 0) { capStyle--; } Blt_Ps_Format(ps, "%d setlinecap\n", capStyle); } void Blt_Ps_XSetJoinStyle(Blt_Ps ps, int joinStyle) { /* * miter = 0, round = 1, bevel = 2 */ Blt_Ps_Format(ps, "%d setlinejoin\n", joinStyle); } void Blt_Ps_XSetLineWidth(Blt_Ps ps, int lineWidth) { if (lineWidth < 1) { lineWidth = 1; } Blt_Ps_Format(ps, "%d setlinewidth\n", lineWidth); } void Blt_Ps_XSetDashes(Blt_Ps ps, Blt_Dashes *dashesPtr) { Blt_Ps_Append(ps, "[ "); if (dashesPtr != NULL) { unsigned char *vp; for (vp = dashesPtr->values; *vp != 0; vp++) { Blt_Ps_Format(ps, " %d", *vp); } } Blt_Ps_Append(ps, "] 0 setdash\n"); } void Blt_Ps_XSetLineAttributes( Blt_Ps ps, XColor *colorPtr, int lineWidth, Blt_Dashes *dashesPtr, int capStyle, int joinStyle) { Blt_Ps_XSetJoinStyle(ps, joinStyle); Blt_Ps_XSetCapStyle(ps, capStyle); Blt_Ps_XSetForeground(ps, colorPtr); Blt_Ps_XSetLineWidth(ps, lineWidth); Blt_Ps_XSetDashes(ps, dashesPtr); Blt_Ps_Append(ps, "/DashesProc {} def\n"); } void Blt_Ps_Rectangle(Blt_Ps ps, int x, int y, int width, int height) { Blt_Ps_Append(ps, "newpath\n"); Blt_Ps_Format(ps, " %d %d moveto\n", x, y); Blt_Ps_Format(ps, " %d %d rlineto\n", width, 0); Blt_Ps_Format(ps, " %d %d rlineto\n", 0, height); Blt_Ps_Format(ps, " %d %d rlineto\n", -width, 0); Blt_Ps_Append(ps, "closepath\n"); } void Blt_Ps_XFillRectangle(Blt_Ps ps, double x, double y, int width, int height) { Blt_Ps_Rectangle(ps, (int)x, (int)y, width, height); Blt_Ps_Append(ps, "fill\n"); } void Blt_Ps_PolylineFromXPoints(Blt_Ps ps, XPoint *points, int n) { XPoint *pp, *pend; pp = points; Blt_Ps_Append(ps, "newpath\n"); Blt_Ps_Format(ps, " %d %d moveto\n", pp->x, pp->y); pp++; for (pend = points + n; pp < pend; pp++) { Blt_Ps_Format(ps, " %d %d lineto\n", pp->x, pp->y); } } void Blt_Ps_Polyline(Blt_Ps ps, Point2d *screenPts, int nScreenPts) { Point2d *pp, *pend; pp = screenPts; Blt_Ps_Append(ps, "newpath\n"); Blt_Ps_Format(ps, " %g %g moveto\n", pp->x, pp->y); for (pp++, pend = screenPts + nScreenPts; pp < pend; pp++) { Blt_Ps_Format(ps, " %g %g lineto\n", pp->x, pp->y); } } void Blt_Ps_Polygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts) { Point2d *pp, *pend; pp = screenPts; Blt_Ps_Append(ps, "newpath\n"); Blt_Ps_Format(ps, " %g %g moveto\n", pp->x, pp->y); for (pp++, pend = screenPts + nScreenPts; pp < pend; pp++) { Blt_Ps_Format(ps, " %g %g lineto\n", pp->x, pp->y); } Blt_Ps_Format(ps, " %g %g lineto\n", screenPts[0].x, screenPts[0].y); Blt_Ps_Append(ps, "closepath\n"); } void Blt_Ps_XFillPolygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts) { Blt_Ps_Polygon(ps, screenPts, nScreenPts); Blt_Ps_Append(ps, "fill\n"); } void Blt_Ps_XDrawSegments(Blt_Ps ps, XSegment *segments, int nSegments) { XSegment *sp, *send; for (sp = segments, send = sp + nSegments; sp < send; sp++) { Blt_Ps_Format(ps, "%d %d moveto %d %d lineto\n", sp->x1, sp->y1, sp->x2, sp->y2); Blt_Ps_Append(ps, "DashesProc stroke\n"); } } void Blt_Ps_XFillRectangles(Blt_Ps ps, XRectangle *rectangles, int nRectangles) { XRectangle *rp, *rend; for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y, (int)rp->width, (int)rp->height); } } #ifndef TK_RELIEF_SOLID #define TK_RELIEF_SOLID -1 /* Set the an impossible value. */ #endif /* TK_RELIEF_SOLID */ void Blt_Ps_Draw3DRectangle( Blt_Ps ps, Tk_3DBorder border, /* Token for border to draw. */ double x, double y, /* Coordinates of rectangle */ int width, int height, /* Region to be drawn. */ int borderWidth, /* Desired width for border, in pixels. */ int relief) /* Should be either TK_RELIEF_RAISED or * TK_RELIEF_SUNKEN; indicates position of * interior of window relative to exterior. */ { Point2d points[7]; TkBorder *borderPtr = (TkBorder *) border; XColor *lightPtr, *darkPtr; XColor *topPtr, *bottomPtr; XColor light, dark; int twiceWidth = (borderWidth * 2); if ((width < twiceWidth) || (height < twiceWidth)) { return; } if ((relief == TK_RELIEF_SOLID) || (borderPtr->lightColor == NULL) || (borderPtr->darkColor == NULL)) { if (relief == TK_RELIEF_SOLID) { dark.red = dark.blue = dark.green = 0x00; light.red = light.blue = light.green = 0x00; relief = TK_RELIEF_SUNKEN; } else { light = *borderPtr->bgColor; dark.red = dark.blue = dark.green = 0xFF; } lightPtr = &light; darkPtr = &dark; } else { lightPtr = borderPtr->lightColor; darkPtr = borderPtr->darkColor; } /* Handle grooves and ridges with recursive calls. */ if ((relief == TK_RELIEF_GROOVE) || (relief == TK_RELIEF_RIDGE)) { int halfWidth, insideOffset; halfWidth = borderWidth / 2; insideOffset = borderWidth - halfWidth; Blt_Ps_Draw3DRectangle(ps, border, (double)x, (double)y, width, height, halfWidth, (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); Blt_Ps_Draw3DRectangle(ps, border, (double)(x + insideOffset), (double)(y + insideOffset), width - insideOffset * 2, height - insideOffset * 2, halfWidth, (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN); return; } if (relief == TK_RELIEF_RAISED) { topPtr = lightPtr; bottomPtr = darkPtr; } else if (relief == TK_RELIEF_SUNKEN) { topPtr = darkPtr; bottomPtr = lightPtr; } else { topPtr = bottomPtr = borderPtr->bgColor; } Blt_Ps_XSetBackground(ps, bottomPtr); Blt_Ps_XFillRectangle(ps, x, y + height - borderWidth, width, borderWidth); Blt_Ps_XFillRectangle(ps, x + width - borderWidth, y, borderWidth, height); points[0].x = points[1].x = points[6].x = x; points[0].y = points[6].y = y + height; points[1].y = points[2].y = y; points[2].x = x + width; points[3].x = x + width - borderWidth; points[3].y = points[4].y = y + borderWidth; points[4].x = points[5].x = x + borderWidth; points[5].y = y + height - borderWidth; if (relief != TK_RELIEF_FLAT) { Blt_Ps_XSetBackground(ps, topPtr); } Blt_Ps_XFillPolygon(ps, points, 7); } void Blt_Ps_Fill3DRectangle( Blt_Ps ps, Tk_3DBorder border, /* Token for border to draw. */ double x, double y, /* Coordinates of top-left of border area */ int width, int height, /* Dimension of border to be drawn. */ int borderWidth, /* Desired width for border, in pixels. */ int relief) /* Should be either TK_RELIEF_RAISED or * TK_RELIEF_SUNKEN; indicates position of * interior of window relative to exterior. */ { TkBorder *borderPtr = (TkBorder *) border; Blt_Ps_XSetBackground(ps, borderPtr->bgColor); Blt_Ps_XFillRectangle(ps, x, y, width, height); Blt_Ps_Draw3DRectangle(ps, border, x, y, width, height, borderWidth, relief); } void Blt_Ps_XSetStipple(Blt_Ps ps, Display *display, Pixmap bitmap) { int width, height; Tk_SizeOfBitmap(display, bitmap, &width, &height); Blt_Ps_Format(ps, "gsave\n" " clip\n" " %d %d\n", width, height); Blt_Ps_XSetBitmapData(ps, display, bitmap, width, height); Blt_Ps_VarAppend(ps, " StippleFill\n" "grestore\n", (char *)NULL); } static void Base85Encode(Blt_DBuffer dBuffer, Tcl_DString *resultPtr) { char *dp; int count; int length, nBytes, oldLength; int n; unsigned char *sp, *send; oldLength = Tcl_DStringLength(resultPtr); nBytes = Blt_DBuffer_Length(dBuffer); /* * Compute worst-case length of buffer needed for encoding. * That is 5 characters per 4 bytes. There are newlines every * 65 characters. The actual size can be smaller, depending upon * the number of 0 tuples ('z' bytes). */ length = oldLength + nBytes; length += ((nBytes + 3)/4) * 5; /* 5 characters per 4 bytes. */ length += (nBytes+64) / 65; /* # of newlines. */ Tcl_DStringSetLength(resultPtr, length); n = count = 0; dp = Tcl_DStringValue(resultPtr) + oldLength; for (sp = Blt_DBuffer_Bytes(dBuffer), send = sp + nBytes; sp < send; sp += 4) { unsigned int tuple; tuple = 0; #ifdef WORDS_BIGENDIAN tuple |= (sp[3] << 24); tuple |= (sp[2] << 16); tuple |= (sp[1] << 8); tuple |= sp[0]; #else tuple |= (sp[0] << 24); tuple |= (sp[1] << 16); tuple |= (sp[2] << 8); tuple |= sp[3]; #endif if (tuple == 0) { *dp++ = 'z'; count++; n++; } else { dp[4] = '!' + (tuple % 85); tuple /= 85; dp[3] = '!' + (tuple % 85); tuple /= 85; dp[2] = '!' + (tuple % 85); tuple /= 85; dp[1] = '!' + (tuple % 85); tuple /= 85; dp[0] = '!' + (tuple % 85); dp += 5; n += 5; count += 5; } if (count > 64) { *dp++ = '\n'; n++; count = 0; } } { unsigned int tuple; /* Handle remaining bytes (0-3). */ nBytes = (nBytes & 0x3); sp -= nBytes; tuple = 0; switch (nBytes) { #ifdef WORDS_BIGENDIAN case 3: tuple |= (sp[2] << 8); case 2: tuple |= (sp[1] << 16); case 1: tuple |= (sp[0] << 24); #else case 3: tuple |= (sp[2] << 24); case 2: tuple |= (sp[1] << 16); case 1: tuple |= (sp[0] << 8); #endif default: break; } if (nBytes > 0) { tuple /= 85; if (nBytes > 2) { dp[3] = '!' + (tuple % 85); n++; } tuple /= 85; if (nBytes > 1) { dp[2] = '!' + (tuple % 85); n++; } tuple /= 85; dp[1] = '!' + (tuple % 85); tuple /= 85; dp[0] = '!' + (tuple % 85); *dp++ = '\n'; n += 3; } Tcl_DStringSetLength(resultPtr, n); } } static void AsciiHexEncode(Blt_DBuffer dBuffer, Tcl_DString *resultPtr) { static char hexDigits[] = "0123456789ABCDEF"; int length, oldLength; int nBytes; /* * Compute the length of the buffer needed for the encoding. That is 2 * characters per byte. There are newlines every 64 characters. */ length = oldLength = Tcl_DStringLength(resultPtr); nBytes = Blt_DBuffer_Length(dBuffer) * 2; /* Two characters per byte */ length += nBytes; length += (nBytes+63)/64; /* Number of newlines required. */ Tcl_DStringSetLength(resultPtr, length); { unsigned char *sp, *send; char *bytes, *dp; int count, n; count = n = 0; dp = bytes = Tcl_DStringValue(resultPtr) + oldLength; for (sp = Blt_DBuffer_Bytes(dBuffer), send = sp + Blt_DBuffer_Length(dBuffer); sp < send; sp++) { dp[0] = hexDigits[*sp >> 4]; dp[1] = hexDigits[*sp & 0x0F]; dp += 2; n += 2; count++; if ((count & 0x1F) == 0) { *dp++ = '\n'; n++; } } *dp++ = '\0'; #ifdef notdef Tcl_DStringSetLength(resultPtr, n + oldLength); #endif } } /* *--------------------------------------------------------------------------- * * Blt_Ps_DrawPicture -- * * Translates a picture into 3 component RGB PostScript output. Uses PS * Language Level 2 operator "colorimage". * * Results: * The dynamic string will contain the PostScript output. * *--------------------------------------------------------------------------- */ void Blt_Ps_DrawPicture(PostScript *psPtr, Blt_Picture picture, double x, double y) { PageSetup *setupPtr = psPtr->setupPtr; int w, h; Blt_DBuffer dBuffer; w = Blt_PictureWidth(picture); h = Blt_PictureHeight(picture); Blt_Ps_Format(psPtr, "gsave\n" "/DeviceRGB setcolorspace\n" "%g %g translate\n" "%d %d scale\n", x, y, w, h); if ((setupPtr->flags & PS_GREYSCALE) || (setupPtr->level == 1)) { int strSize; strSize = (setupPtr->flags & PS_GREYSCALE) ? w : w * 3; Blt_Ps_Format(psPtr, "/picstr %d string def\n" "%d %d 8\n" "[%d 0 0 %d 0 %d]\n" "{\n" " currentfile picstr readhexstring pop\n" "}\n", strSize, w, h, w, -h, h); if (setupPtr->flags & PS_GREYSCALE) { Blt_Picture greyscale; Blt_Ps_Append(psPtr, "image\n"); greyscale = Blt_GreyscalePicture(picture); dBuffer = Blt_PictureToDBuffer(picture, 1); Blt_FreePicture(greyscale); } else { Blt_Ps_Append(psPtr, "false 3 colorimage\n"); dBuffer = Blt_PictureToDBuffer(picture, 3); } AsciiHexEncode(dBuffer, &psPtr->dString); Blt_DBuffer_Free(dBuffer); } else { Blt_Ps_Format(psPtr, "<<\n" "/ImageType 1\n" "/Width %d\n" "/Height %d\n" "/BitsPerComponent 8\n" "/Decode [0 1 0 1 0 1]\n" "/ImageMatrix [%d 0 0 %d 0 %d]\n" "/Interpolate true\n" "/DataSource currentfile /ASCII85Decode filter\n" ">>\n" "image\n", w, h, w, -h, h); dBuffer = Blt_PictureToDBuffer(picture, 3); Base85Encode(dBuffer, &psPtr->dString); Blt_DBuffer_Free(dBuffer); } Blt_Ps_Append(psPtr, "\ngrestore\n\n"); } /* *--------------------------------------------------------------------------- * * Blt_Ps_XDrawWindow -- * * Converts a Tk window to PostScript. If the window could not be * "snapped", then a grey rectangle is drawn in its place. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Ps_XDrawWindow(Blt_Ps ps, Tk_Window tkwin, double x, double y) { Blt_Picture picture; picture = Blt_DrawableToPicture(tkwin, Tk_WindowId(tkwin), 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), GAMMA); if (picture == NULL) { /* Can't grab window image so paint the window area grey */ Blt_Ps_VarAppend(ps, "% Can't grab window \"", Tk_PathName(tkwin), "\"\n", (char *)NULL); Blt_Ps_Append(ps, "0.5 0.5 0.5 setrgbcolor\n"); Blt_Ps_XFillRectangle(ps, x, y, Tk_Width(tkwin), Tk_Height(tkwin)); return; } Blt_Ps_DrawPicture(ps, picture, x, y); Blt_FreePicture(picture); } /* *--------------------------------------------------------------------------- * * Blt_Ps_DrawPhoto -- * * Output a PostScript image string of the given photo image. The photo * is first converted into a picture and then translated into PostScript. * * Results: * None. * * Side Effects: * The PostScript output representing the photo is appended to the * psPtr's dynamic string. * *--------------------------------------------------------------------------- */ void Blt_Ps_DrawPhoto(Blt_Ps ps, Tk_PhotoHandle photo, double x, double y) { Blt_Picture picture; picture = Blt_PhotoToPicture(photo); Blt_Ps_DrawPicture(ps, picture, x, y); Blt_FreePicture(picture); } /* *--------------------------------------------------------------------------- * * Blt_Ps_XSetFont -- * * Map the Tk font to a PostScript font and point size. * * If a TCL array variable was specified, each element should be indexed * by the X11 font name and contain a list of 1-2 elements; the * PostScript font name and the desired point size. The point size may * be omitted and the X font point size will be used. * * Otherwise, if the foundry is "Adobe", we try to do a plausible mapping * looking at the full name of the font and building a string in the form * of "Family-TypeFace". * * Returns: * None. * * Side Effects: * PostScript commands are output to change the type and the point size * of the current font. * *--------------------------------------------------------------------------- */ void Blt_Ps_XSetFont(PostScript *psPtr, Blt_Font font) { Tcl_Interp *interp = psPtr->interp; const char *family; /* Use the font variable information if it exists. */ if ((psPtr->setupPtr != NULL) && (psPtr->setupPtr->fontVarName != NULL)) { char *value; value = (char *)Tcl_GetVar2(interp, psPtr->setupPtr->fontVarName, Blt_NameOfFont(font), 0); if (value != NULL) { const char **argv = NULL; int argc; int newSize; double pointSize; const char *fontName; if (Tcl_SplitList(NULL, value, &argc, &argv) != TCL_OK) { return; } fontName = argv[0]; if ((argc != 2) || (Tcl_GetInt(interp, argv[1], &newSize) != TCL_OK)) { Blt_Free(argv); return; } pointSize = (double)newSize; Blt_Ps_Format(psPtr, "%g /%s SetFont\n", pointSize, fontName); Blt_Free(argv); return; } /*FallThru*/ } /* * Check to see if it's a PostScript font. Tk_PostScriptFontName silently * generates a bogus PostScript font name, so we have to check to see if * this is really a PostScript font first before we call it. */ family = FamilyToPsFamily(Blt_FamilyOfFont(font)); if (family != NULL) { Tcl_DString dString; double pointSize; Tcl_DStringInit(&dString); pointSize = (double)Blt_PostscriptFontName(font, &dString); Blt_Ps_Format(psPtr, "%g /%s SetFont\n", pointSize, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); return; } Blt_Ps_Append(psPtr, "12.0 /Helvetica-Bold SetFont\n"); } static void TextLayoutToPostScript(Blt_Ps ps, int x, int y, TextLayout *textPtr) { char *bp, *dst; int count; /* Counts the # of bytes written to the * intermediate scratch buffer. */ const char *src, *end; TextFragment *fragPtr; int i; unsigned char c; #if HAVE_UTF Tcl_UniChar ch; #endif int limit; limit = POSTSCRIPT_BUFSIZ - 4; /* High water mark for scratch buffer. */ fragPtr = textPtr->fragments; for (i = 0; i < textPtr->nFrags; i++, fragPtr++) { if (fragPtr->count < 1) { continue; } Blt_Ps_Append(ps, "("); count = 0; dst = Blt_Ps_GetScratchBuffer(ps); src = fragPtr->text; end = fragPtr->text + fragPtr->count; while (src < end) { if (count > limit) { /* Don't let the scatch buffer overflow */ dst = Blt_Ps_GetScratchBuffer(ps); dst[count] = '\0'; Blt_Ps_Append(ps, dst); count = 0; } #if HAVE_UTF /* * INTL: For now we just treat the characters as binary data and * display the lower byte. Eventually this should be revised to * handle international postscript fonts. */ src += Tcl_UtfToUniChar(src, &ch); c = (unsigned char)(ch & 0xff); #else c = *src++; #endif if ((c == '\\') || (c == '(') || (c == ')')) { /* * If special PostScript characters characters "\", "(", and * ")" are contained in the text string, prepend backslashes * to them. */ *dst++ = '\\'; *dst++ = c; count += 2; } else if ((c < ' ') || (c > '~')) { /* Convert non-printable characters into octal. */ sprintf_s(dst, 5, "\\%03o", c); dst += 4; count += 4; } else { *dst++ = c; count++; } } bp = Blt_Ps_GetScratchBuffer(ps); bp[count] = '\0'; Blt_Ps_Append(ps, bp); Blt_Ps_Format(ps, ") %d %d %d DrawAdjText\n", fragPtr->width, x + fragPtr->x, y + fragPtr->y); } } /* *--------------------------------------------------------------------------- * * Blt_Ps_DrawText -- * * Output PostScript commands to print a text string. The string may be * rotated at any arbitrary angle, and placed according the anchor type * given. The anchor indicates how to interpret the window coordinates as * an anchor for the text bounding box. * * Results: * None. * * Side Effects: * Text string is drawn using the given font and GC on the graph window * at the given coordinates, anchor, and rotation * *--------------------------------------------------------------------------- */ void Blt_Ps_DrawText( Blt_Ps ps, const char *string, /* String to convert to PostScript */ TextStyle *tsPtr, /* Text attribute information */ double x, double y) /* Window coordinates where to print text */ { TextLayout *textPtr; Point2d t; if ((string == NULL) || (*string == '\0')) { /* Empty string, do nothing */ return; } textPtr = Blt_Ts_CreateLayout(string, -1, tsPtr); { float angle; double rw, rh; angle = FMOD(tsPtr->angle, (double)360.0); Blt_GetBoundingBox(textPtr->width, textPtr->height, angle, &rw, &rh, (Point2d *)NULL); /* * Find the center of the bounding box */ t = Blt_AnchorPoint(x, y, rw, rh, tsPtr->anchor); t.x += rw * 0.5; t.y += rh * 0.5; } /* Initialize text (sets translation and rotation) */ Blt_Ps_Format(ps, "%d %d %g %g %g BeginText\n", textPtr->width, textPtr->height, tsPtr->angle, t.x, t.y); Blt_Ps_XSetFont(ps, tsPtr->font); Blt_Ps_XSetForeground(ps, tsPtr->color); TextLayoutToPostScript(ps, 0, 0, textPtr); Blt_Free(textPtr); Blt_Ps_Append(ps, "EndText\n"); } void Blt_Ps_XDrawLines(Blt_Ps ps, XPoint *points, int n) { int nLeft; if (n <= 0) { return; } for (nLeft = n; nLeft > 0; nLeft -= PS_MAXPATH) { int length; length = MIN(PS_MAXPATH, nLeft); Blt_Ps_PolylineFromXPoints(ps, points, length); Blt_Ps_Append(ps, "DashesProc stroke\n"); points += length; } } void Blt_Ps_DrawPolyline(Blt_Ps ps, Point2d *points, int nPoints) { int nLeft; if (nPoints <= 0) { return; } for (nLeft = nPoints; nLeft > 0; nLeft -= PS_MAXPATH) { int length; length = MIN(PS_MAXPATH, nLeft); Blt_Ps_Polyline(ps, points, length); Blt_Ps_Append(ps, "DashesProc stroke\n"); points += length; } } void Blt_Ps_DrawBitmap( Blt_Ps ps, Display *display, Pixmap bitmap, /* Bitmap to be converted to PostScript */ double xScale, double yScale) { int width, height; double sw, sh; Tk_SizeOfBitmap(display, bitmap, &width, &height); sw = (double)width * xScale; sh = (double)height * yScale; Blt_Ps_Append(ps, " gsave\n"); Blt_Ps_Format(ps, " %g %g translate\n", sw * -0.5, sh * 0.5); Blt_Ps_Format(ps, " %g %g scale\n", sw, -sh); Blt_Ps_Format(ps, " %d %d true [%d 0 0 %d 0 %d] {", width, height, width, -height, height); Blt_Ps_XSetBitmapData(ps, display, bitmap, width, height); Blt_Ps_Append(ps, " } imagemask\n grestore\n"); } void Blt_Ps_Draw2DSegments(Blt_Ps ps, Segment2d *segments, int nSegments) { Segment2d *sp, *send; Blt_Ps_Append(ps, "newpath\n"); for (sp = segments, send = sp + nSegments; sp < send; sp++) { Blt_Ps_Format(ps, " %g %g moveto %g %g lineto\n", sp->p.x, sp->p.y, sp->q.x, sp->q.y); Blt_Ps_Append(ps, "DashesProc stroke\n"); } } void Blt_Ps_FontName(const char *family, int flags, Tcl_DString *resultPtr) { const char *familyName, *weightName, *slantName; int len; len = Tcl_DStringLength(resultPtr); familyName = FamilyToPsFamily(family); if (familyName == NULL) { Tcl_UniChar ch; char *src, *dest; int upper; /* * Inline, capitalize the first letter of each word, lowercase the * rest of the letters in each word, and then take out the spaces * between the words. This may make the DString shorter, which is * safe to do. */ Tcl_DStringAppend(resultPtr, family, -1); src = dest = Tcl_DStringValue(resultPtr) + len; upper = TRUE; while (*src != '\0') { while (isspace(*src)) { /* INTL: ISO space */ src++; upper = TRUE; } src += Tcl_UtfToUniChar(src, &ch); if (upper) { ch = Tcl_UniCharToUpper(ch); upper = FALSE; } else { ch = Tcl_UniCharToLower(ch); } dest += Tcl_UniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(resultPtr, dest - Tcl_DStringValue(resultPtr)); familyName = Tcl_DStringValue(resultPtr) + len; } if (familyName != Tcl_DStringValue(resultPtr) + len) { Tcl_DStringAppend(resultPtr, familyName, -1); familyName = Tcl_DStringValue(resultPtr) + len; } if (strcasecmp(familyName, "NewCenturySchoolbook") == 0) { Tcl_DStringSetLength(resultPtr, len); Tcl_DStringAppend(resultPtr, "NewCenturySchlbk", -1); familyName = Tcl_DStringValue(resultPtr) + len; } /* Get the string to use for the weight. */ weightName = NULL; if (flags & FONT_BOLD) { if ((strcmp(familyName, "Bookman") == 0) || (strcmp(familyName, "AvantGarde") == 0)) { weightName = "Demi"; } else { weightName = "Bold"; } } else { if (strcmp(familyName, "Bookman") == 0) { weightName = "Light"; } else if (strcmp(familyName, "AvantGarde") == 0) { weightName = "Book"; } else if (strcmp(familyName, "ZapfChancery") == 0) { weightName = "Medium"; } } /* Get the string to use for the slant. */ slantName = NULL; if (flags & FONT_ITALIC) { if ((strcmp(familyName, "Helvetica") == 0) || (strcmp(familyName, "Courier") == 0) || (strcmp(familyName, "AvantGarde") == 0)) { slantName = "Oblique"; } else { slantName = "Italic"; } } /* * The string "Roman" needs to be added to some fonts that are not bold * and not italic. */ if ((slantName == NULL) && (weightName == NULL)) { if ((strcmp(familyName, "Times") == 0) || (strcmp(familyName, "NewCenturySchlbk") == 0) || (strcmp(familyName, "Palatino") == 0)) { Tcl_DStringAppend(resultPtr, "-Roman", -1); } } else { Tcl_DStringAppend(resultPtr, "-", -1); if (weightName != NULL) { Tcl_DStringAppend(resultPtr, weightName, -1); } if (slantName != NULL) { Tcl_DStringAppend(resultPtr, slantName, -1); } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacOSXPainter.c������������������������������������������������������������0000644�0001750�0001750�00000111677�11462120062�016325� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSXPainter.c -- * * This module implements MacOSX-specific image processing procedures * for the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltPicture.h" #include "bltPainter.h" #include <X11/Xutil.h> #include "tkDisplay.h" typedef struct _Blt_Picture Picture; #include <Carbon/Carbon.h> struct TkWindow; struct _MacDrawable { TkWindow *winPtr; /* Ptr to tk window or NULL if Pixmap */ CGrafPtr grafPtr; ControlRef rootControl; int xOffset; /* X offset from toplevel window. */ int yOffset; /* Y offset from toplevel window. */ RgnHandle clipRgn; /* Visable region of window. */ RgnHandle aboveClipRgn; /* Visable region of window and its * children. */ int referenceCount; /* Don't delete toplevel until * children are gone. */ /* Pointer to the toplevel datastruct. */ struct _MacDrawable *toplevel; int flags; /* Various state see defines below. */ }; typedef struct _MacDrawable *MacDrawable; /* *--------------------------------------------------------------------------- * * DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Picture DrawableToPicture( Painter *painterPtr, Drawable drawable, int x, int y, int width, int height) /* Dimension of the drawable. */ { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr srcPort; Picture *destPtr; srcPort = TkMacOSXGetDrawablePort(drawable); destPtr = Blt_CreatePicture(width, height); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, x, y, x + width, y + height); SetRect(&destRect, 0, 0, width, height); GetGWorld(&saveWorld, &saveDevice); SetGWorld(srcPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)destPtr->bits; pm.rowBytes = destPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, not a * BitMap. */ CopyBits(GetPortBitMapForCopyBits(destPort), (BitMap *)&pm, &srcRect, &destRect, srcCopy, NULL); } SetGWorld(saveWorld, saveDevice); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_WindowToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * This routine is used to snap foreign (non-Tk) windows. For * pixmaps and Tk windows, Blt_DrawableToPicture is preferred. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_WindowToPicture( Display *display, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainterFromDrawable(display, drawable, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } /* *--------------------------------------------------------------------------- * * Blt_DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Picture * Blt_DrawableToPicture( Tk_Window tkwin, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ double gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainter(tkwin, gamma); picture = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return picture; } Pixmap Blt_PhotoImageMask( Tk_Window tkwin, Tk_PhotoImageBlock src) { TkWinBitmap *twdPtr; int offset, count; int x, y; unsigned char *srcPtr; int destBytesPerRow; int destHeight; unsigned char *destBits; destBytesPerRow = ((src.width + 31) & ~31) / 8; destBits = Blt_AssertCalloc(src.height, destBytesPerRow); destHeight = src.height; offset = count = 0; /* FIXME: figure out why this is so! */ for (y = src.height - 1; y >= 0; y--) { srcPtr = src.pixelPtr + offset; for (x = 0; x < src.width; x++) { if (srcPtr[src.offset[3]] == 0x00) { SetBit(x, y); count++; } srcPtr += src.pixelSize; } offset += src.pitch; } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = src.width; bm.bmHeight = src.height; bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } Pixmap Blt_PictureMask( Tk_Window tkwin, Blt_Picture pict) { TkWinBitmap *twdPtr; int count; int x, y; Blt_Pixel *sp; int destBytesPerRow; int destWidth, destHeight; unsigned char *destBits; destWidth = Blt_PictureWidth(pict); destHeight = Blt_PictureHeight(pict); destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); count = 0; sp = Blt_PictureBits(pict); for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { if (sp->Alpha == 0x00) { SetBit(x, y); count++; } sp++; } } if (count > 0) { HBITMAP hBitmap; BITMAP bm; bm.bmType = 0; bm.bmWidth = Blt_PictureWidth(pict); bm.bmHeight = Blt_PictureHeight(pict); bm.bmWidthBytes = destBytesPerRow; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = destBits; hBitmap = CreateBitmapIndirect(&bm); twdPtr = Blt_AssertMalloc(sizeof(TkWinBitmap)); twdPtr->type = TWD_BITMAP; twdPtr->handle = hBitmap; twdPtr->depth = 1; if (Tk_WindowId(tkwin) == None) { twdPtr->colormap = DefaultColormap(Tk_Display(tkwin), DefaultScreen(Tk_Display(tkwin))); } else { twdPtr->colormap = Tk_Colormap(tkwin); } } else { twdPtr = NULL; } if (destBits != NULL) { Blt_Free(destBits); } return (Pixmap)twdPtr; } /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given * bitmap. We also need a special GC of depth 1, so that we do * not need to rotate more than one plane of the bitmap. * * Note that under Windows, monochrome bitmaps are stored * bottom-to-top. This is why the right angle rotations 0/180 * and 90/270 look reversed. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* Right angle rotation to perform */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; double rotWidth, rotHeight; HDC hDC; TkWinDCState state; int x, y; /* Destination bitmap coordinates */ int sx, sy; /* Source bitmap coordinates */ unsigned long pixel; HBITMAP hBitmap; int result; struct MonoBitmap { BITMAPINFOHEADER bi; RGBQUAD colors[2]; } mb; int srcBytesPerRow, destBytesPerRow; int destWidth, destHeight; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = (int)ceil(rotWidth); destHeight = (int)ceil(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((destWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(destHeight, destBytesPerRow); angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; /* Handle right-angle rotations specially. */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { sx = y; for (x = 0; x < destWidth; x++) { sy = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sx = destWidth - x - 1; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { sy = x; pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { for (x = 0; x < destWidth; x++) { pixel = GetBit(x, y); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double srcCX, srcCY; /* Center of source rectangle */ double destCX, destCY; /* Center of destination rectangle */ double tx, ty; double rx, ry; /* Angle of rotation for x and y coordinates */ radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ srcCX = srcWidth * 0.5; srcCY = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* Rotate each pixel of dest image, placing results in source image */ for (y = 0; y < destHeight; y++) { ty = y - destCY; for (x = 0; x < destWidth; x++) { /* Translate origin to center of destination image */ tx = x - destCX; /* Rotate the coordinates about the origin */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image */ rx += srcCX; ry += srcCY; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bi.biSize = sizeof(BITMAPINFOHEADER); mb.bi.biPlanes = 1; mb.bi.biBitCount = 1; mb.bi.biCompression = BI_RGB; mb.bi.biWidth = destWidth; mb.bi.biHeight = destHeight; mb.bi.biSizeImage = destBytesPerRow * destHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, destHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } *destWidthPtr = destWidth; *destHeightPtr = destHeight; return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { TkWinDCState srcState, destState; HDC src, dest; Pixmap destBitmap; Window root; Display *display; /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); if (destBitmap == None) { return None; } src = TkWinGetDrawableDC(display, srcBitmap, &srcState); dest = TkWinGetDrawableDC(display, destBitmap, &destState); StretchBlt(dest, 0, 0, destWidth, destHeight, src, 0, 0, srcWidth, srcHeight, SRCCOPY); TkWinReleaseDrawableDC(srcBitmap, src, &srcState); TkWinReleaseDrawableDC(destBitmap, dest, &destState); return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleRotateBitmapArea -- * * Creates a scaled and rotated bitmap from a given bitmap. The * caller also provides (offsets and dimensions) the region of * interest in the destination bitmap. This saves having to * process the entire destination bitmap is only part of it is * showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the * destination image. For each pixel, the corresponding * pixel in the source bitmap is used. This means that * destination coordinates are first scaled to the size of * the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapArea( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual * destination bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int virtWidth, unsigned int virtHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Pixmap destBitmap; Window root; /* Root window drawable */ double rWidth, rHeight; double xScale, yScale; int srcBytesPerRow, destBytesPerRow; int destHeight; int result; unsigned char *srcBits, *destBits; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); if (destBitmap == None) { return None; /* Can't allocate pixmap. */ } srcBits = Blt_GetBitmapData(display, srcBitmap, srcWidth, srcHeight, &srcBytesPerRow); if (srcBits == NULL) { OutputDebugString("Blt_GetBitmapData failed"); return None; } destBytesPerRow = ((regionWidth + 31) & ~31) / 8; destBits = Blt_AssertCalloc(regionHeight, destBytesPerRow); destHeight = regionHeight; angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rWidth, &rHeight, (Point2d *)NULL); xScale = rWidth / (double)virtWidth; yScale = rHeight / (double)virtHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(y+regionY)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sy; sy = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { unsigned long pixel; int sx; sx = (int)(xScale *(double)(virtWidth - (x+regionX) - 1)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sx, x; sx = (int)(yScale * (double)(virtHeight - (y + regionY) - 1)); for (x = 0; x < (int)regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < (int)regionHeight; y++) { int sy, x; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < (int)regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double scx, scy; /* Offset from the center of the * source rectangle. */ double rcx, rcy; /* Offset to the center of the * rotated rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ scx = srcWidth * 0.5; scy = srcHeight * 0.5; rcx = rWidth * 0.5; rcy = rHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < (int)regionHeight; y++) { int x; double ty; /* Translated coordinates from center */ ty = (yScale * (double)(y + regionY)) - rcy; for (x = 0; x < (int)regionWidth; x++) { double rx, ry; /* Angle of rotation for x and y coordinates */ double tx; /* Translated coordinates from center */ int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rcx; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += scx; ry += scy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= (int)srcWidth) || (sx < 0) || (sy >= (int)srcHeight) || (sy < 0)) { continue; } pixel = GetBit(sx, sy); if (pixel) { SetBit(x, y); } } } } { HBITMAP hBitmap; HDC hDC; TkWinDCState state; struct MonoBitmap { BITMAPINFOHEADER bmiHeader; RGBQUAD colors[2]; } mb; /* Write the rotated image into the destination bitmap. */ hBitmap = ((TkWinDrawable *)destBitmap)->bitmap.handle; ZeroMemory(&mb, sizeof(mb)); mb.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mb.bmiHeader.biPlanes = 1; mb.bmiHeader.biBitCount = 1; mb.bmiHeader.biCompression = BI_RGB; mb.bmiHeader.biWidth = regionWidth; mb.bmiHeader.biHeight = regionHeight; mb.bmiHeader.biSizeImage = destBytesPerRow * regionHeight; mb.colors[0].rgbBlue = mb.colors[0].rgbRed = mb.colors[0].rgbGreen = 0x0; mb.colors[1].rgbBlue = mb.colors[1].rgbRed = mb.colors[1].rgbGreen = 0xFF; hDC = TkWinGetDrawableDC(display, destBitmap, &state); result = SetDIBits(hDC, hBitmap, 0, regionHeight, (LPVOID)destBits, (BITMAPINFO *)&mb, DIB_RGB_COLORS); TkWinReleaseDrawableDC(destBitmap, hDC, &state); } if (!result) { #if WINDEBUG PurifyPrintf("can't setDIBits: %s\n", Blt_LastError()); #endif destBitmap = None; } if (destBits != NULL) { Blt_Free(destBits); } if (srcBits != NULL) { Blt_Free(srcBits); } return destBitmap; } #ifdef HAVE_IJL_H #include <ijl.h> Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { JPEG_CORE_PROPERTIES jpgProps; Blt_Picture pict; ZeroMemory(&jpgProps, sizeof(JPEG_CORE_PROPERTIES)); if(ijlInit(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't initialize Intel JPEG library", (char *)NULL); return NULL; } jpgProps.JPGFile = fileName; if (ijlRead(&jpgProps, IJL_JFILE_READPARAMS) != IJL_OK) { Tcl_AppendResult(interp, "can't read JPEG file header from \"", fileName, "\" file.", (char *)NULL); goto error; } // !dudnik: to fix bug case 584680, [OT:287A305B] // Set the JPG color space ... this will always be // somewhat of an educated guess at best because JPEG // is "color blind" (i.e., nothing in the bit stream // tells you what color space the data was encoded from). // However, in this example we assume that we are // reading JFIF files which means that 3 channel images // are in the YCbCr color space and 1 channel images are // in the Y color space. switch(jpgProps.JPGChannels) { case 1: jpgProps.JPGColor = IJL_G; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 3: jpgProps.JPGColor = IJL_YCBCR; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; case 4: jpgProps.JPGColor = IJL_YCBCRA_FPX; jpgProps.DIBChannels = 4; jpgProps.DIBColor = IJL_RGBA_FPX; break; default: /* This catches everything else, but no color twist will be performed by the IJL. */ jpgProps.DIBColor = (IJL_COLOR)IJL_OTHER; jpgProps.JPGColor = (IJL_COLOR)IJL_OTHER; jpgProps.DIBChannels = jpgProps.JPGChannels; break; } jpgProps.DIBWidth = jpgProps.JPGWidth; jpgProps.DIBHeight = jpgProps.JPGHeight; jpgProps.DIBPadBytes = IJL_DIB_PAD_BYTES(jpgProps.DIBWidth, jpgProps.DIBChannels); pict = Blt_CreatePicture(jpgProps.JPGWidth, jpgProps.JPGHeight); jpgProps.DIBBytes = (BYTE *)Blt_PictureBits(pict); if (ijlRead(&jpgProps, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { Tcl_AppendResult(interp, "can't read image data from \"", fileName, "\"", (char *)NULL); goto error; } if (ijlFree(&jpgProps) != IJL_OK) { Tcl_AppendResult(interp, "can't free Intel(R) JPEG library.", (char *)NULL); } return pict; error: ijlFree(&jpgProps); if (pict != NULL) { Blt_FreePicture(pict); } ijlFree(&jpgProps); return NULL; } #else #ifdef HAVE_JPEGLIB_H #undef HAVE_STDLIB_H #ifdef WIN32 #define XMD_H 1 #endif #include "jpeglib.h" #include <setjmp.h> typedef struct { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf jmpBuf; Tcl_DString dString; } ReaderHandler; static void ErrorProc(j_common_ptr jpegInfo); static void MessageProc(j_common_ptr jpegInfo); /* * Here's the routine that will replace the standard error_exit method: */ static void ErrorProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; (*handlerPtr->pub.output_message) (jpgPtr); longjmp(handlerPtr->jmpBuf, 1); } static void MessageProc(jpgPtr) j_common_ptr jpgPtr; { ReaderHandler *handlerPtr = (ReaderHandler *)jpgPtr->err; char buffer[JMSG_LENGTH_MAX]; /* Create the message and append it into the dynamic string. */ (*handlerPtr->pub.format_message) (jpgPtr, buffer); Tcl_DStringAppend(&handlerPtr->dString, " ", -1); Tcl_DStringAppend(&handlerPtr->dString, buffer, -1); } /* *--------------------------------------------------------------------------- * * Blt_JPEGToPicture -- * * Reads a JPEG file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_JPEGToPicture(interp, fileName) Tcl_Interp *interp; char *fileName; { struct jpeg_decompress_struct jpg; Blt_Picture pict; unsigned int pictWidth, pictHeight; Blt_Pixel *dp; ReaderHandler handler; FILE *f; JSAMPLE **readBuffer; int row_stride; int i; JSAMPLE *bufPtr; f = Blt_OpenFile(interp, fileName, "rb"); if (f == NULL) { return NULL; } pict = NULL; /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ jpg.dct_method = JDCT_IFAST; jpg.err = jpeg_std_error(&handler.pub); handler.pub.error_exit = ErrorProc; handler.pub.output_message = MessageProc; Tcl_DStringInit(&handler.dString); Tcl_DStringAppend(&handler.dString, "error reading \"", -1); Tcl_DStringAppend(&handler.dString, fileName, -1); Tcl_DStringAppend(&handler.dString, "\": ", -1); if (setjmp(handler.jmpBuf)) { jpeg_destroy_decompress(&jpg); fclose(f); Tcl_DStringResult(interp, &handler.dString); return NULL; } jpeg_create_decompress(&jpg); jpeg_stdio_src(&jpg, f); jpeg_read_header(&jpg, TRUE); /* Step 3: read file parameters */ jpeg_start_decompress(&jpg); /* Step 5: Start decompressor */ pictWidth = jpg.output_width; pictHeight = jpg.output_height; if ((pictWidth < 1) || (pictHeight < 1)) { Tcl_AppendResult(interp, "bad JPEG image size", (char *)NULL); fclose(f); return NULL; } /* JSAMPLEs per row in output buffer */ row_stride = pictWidth * jpg.output_components; /* Make a one-row-high sample array that will go away when done * with image */ readBuffer = (*jpg.mem->alloc_sarray) ((j_common_ptr)&jpg, JPOOL_IMAGE, row_stride, 1); pict = Blt_CreatePicture(pictWidth, pictHeight); dp = Blt_PictureBits(pict); if (jpg.output_components == 1) { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = dp->Green = dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } else { while (jpg.output_scanline < pictHeight) { jpeg_read_scanlines(&jpg, readBuffer, 1); bufPtr = readBuffer[0]; for (i = 0; i < (int)pictWidth; i++) { dp->Red = *bufPtr++; dp->Green = *bufPtr++; dp->Blue = *bufPtr++; dp->Alpha = ALPHA_OPAQUE; dp++; } } } jpeg_finish_decompress(&jpg); /* We can ignore the return value * since suspension is not * possible with the stdio data * source. */ jpeg_destroy_decompress(&jpg); /* * After finish_decompress, we can close the input file. Here we * postpone it until after no more JPEG errors are possible, so as * to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume * anything...) */ fclose(f); /* * At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ if (handler.pub.num_warnings > 0) { Tcl_SetErrorCode(interp, "IMAGE", "JPEG", Tcl_DStringValue(&handler.dString), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } /* * We're ready to call the Tk_Photo routines. They'll take the RGB * array we've processed to build the Tk image of the JPEG. */ Tcl_DStringFree(&handler.dString); return pict; } #endif /* HAVE_JPEGLIB_H */ #endif /* HAVE_IJL_H */ /* *--------------------------------------------------------------------------- * * PaintPicture -- * * Paints the picture to the given drawable. The region of * the picture is specified and the coordinates where in the * destination drawable is the image to be displayed. * * The image may be dithered depending upon the bit set in * the flags parameter: 0 no dithering, 1 for dithering. * * Results: * Returns TRUE is the picture was successfully display, * Otherwise FALSE is returned if the particular combination * visual and image depth is not handled. * *--------------------------------------------------------------------------- */ static int PaintPicture( Painter *painterPtr, Drawable drawable, Picture *srcPtr, int srcX, int srcY, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; Picture *ditherPtr; ditherPtr = NULL; if (flags & BLT_PAINTER_DITHER) { ditherPtr = Blt_DitherPicture(srcPtr, painterPtr->palette); if (ditherPtr != NULL) { srcPtr = ditherPtr; } } destPort = TkMacOSXGetDrawablePort(drawable); { Rect srcRect, destRect; MacDrawable dstDraw = (MacDrawable)drawable; PixMap pm; SetRect(&srcRect, srcX, srcY, srcX + width, srcY + height); SetRect(&destRect, destX + dstDraw->xOffset, destY + dstDraw->yOffset, destX + width + dstDraw->xOffset, destY + height + dstDraw->yOffset); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacOSXSetUpClippingRgn(drawable); pm.bounds.left = pm.bounds.top = 0; pm.bounds.right = (short)width; pm.bounds.bottom = (short)height; pm.pixelType = RGBDirect; pm.pmVersion = baseAddr32; /* 32bit clean */ pm.packType = pm.packSize = 0; pm.hRes = pm.vRes = 0x00480000; /* 72 dpi */ pm.pixelSize = sizeof(Blt_Pixel) * 8; /* Bits per pixel. */ pm.cmpCount = 3; /* 3 components for direct. */ pm.cmpSize = 8; /* 8 bits per component. */ pm.pixelFormat = k32ARGBPixelFormat; pm.pmTable = NULL; pm.pmExt = 0; pm.baseAddr = (Ptr)srcPtr->bits; pm.rowBytes = srcPtr->pixelsPerRow * sizeof(Blt_Pixel); pm.rowBytes |= 0x8000; /* Indicates structure a PixMap, * not a BitMap. */ CopyBits((BitMap *)&pm, GetPortBitMapForCopyBits(destPort), &srcRect, &destRect, srcCopy, NULL); } if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } SetGWorld(saveWorld, saveDevice); return TRUE; } /* *--------------------------------------------------------------------------- * * PaintPictureWithBlend -- * * Blends and paints the picture with the given drawable. The * region of the picture is specified and the coordinates where * in the destination drawable is the image to be displayed. * * The background is snapped from the drawable and converted into * a picture. This picture is then blended with the current * picture (the background always assumed to be 100% opaque). * * Results: * Returns TRUE is the picture was successfully display, * Otherwise FALSE is returned. This may happen if the * background can not be obtained from the drawable. * *--------------------------------------------------------------------------- */ static int PaintPictureWithBlend( Painter *painterPtr, Drawable drawable, Blt_Picture fg, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, int alpha) { Blt_Picture bg; if (destX < 0) { width += destX; destX = 0; } if (destY < 0) { height += destY; destY = 0; } if ((width < 0) || (height < 0)) { return FALSE; } bg = DrawableToPicture(painterPtr, drawable, destX, destY, width, height); if (bg == NULL) { return FALSE; } #ifdef notdef Blt_FadePicture(bg, fg, x, y, width, height, 0, 0, alpha); #else Blt_BlendPictures(bg, fg, x, y, bg->width, bg->height, 0, 0); #endif PaintPicture(painterPtr, drawable, bg, 0, 0, bg->width, bg->height, destX, destY, flags); Blt_FreePicture(bg); return TRUE; } int Blt_PaintPicture( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags) { if ((picture == NULL) || (x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))) { /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } if ((width <= 0) || (height <= 0)) { return TRUE; } if (Blt_PictureIsOpaque(picture)) { return PaintPicture(painter, drawable, picture, x, y, width, height, destX, destY, flags); } else { int alpha = 128; return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } } int Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int width, int height, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int destX, int destY, /* Coordinates of region in the * drawable. */ unsigned int flags, /* Indicates whether to dither the * picture before displaying. */ double falpha) { int alpha; alpha = (int)(falpha * 255.0 + 0.5); assert((x >= 0) && (y >= 0)); /* assert((destX >= 0) && (destY >= 0)); */ assert((width >= 0) && (height >= 0)); if ((x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture))){ /* Nothing to draw. The region offset starts beyond the end of * the picture. */ return TRUE; } /* * Check that the region defined does not extend beyond the end of * the picture. * * Clip the end of the region if it is too big. */ if ((width + x) > Blt_PictureWidth(picture)) { width = Blt_PictureWidth(picture) - x; } if ((height + y) > Blt_PictureHeight(picture)) { height = Blt_PictureHeight(picture) - y; } return PaintPictureWithBlend(painter, drawable, picture, x, y, width, height, destX, destY, flags, alpha); } GC Blt_PainterGC(Painter *painterPtr) { return painterPtr->gc; } int Blt_PainterDepth(Painter *painterPtr) { return painterPtr->depth; } �����������������������������������������������������������������./saods9/blt3.0.1/src/bltTri.c����������������������������������������������������������������������0000644�0001750�0001750�00000037372�11462120063�014446� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "bltInt.h" #include "bltChain.h" #define DELETED ((Edge *)-2) #define LE 0 #define RE 1 #define Dist(p,q) \ hypot((p)->point.x - (q)->point.x, (p)->point.y - (q)->point.y) typedef struct _HalfEdge HalfEdge; typedef struct _FreeNode FreeNode; typedef struct { int a, b, c; float min, max; } Triplet; struct _FreeNode { FreeNode *nextPtr; }; typedef struct { FreeNode *headPtr; int nodesize; } FreeList; typedef struct { Point2d point; int neighbor; int refCount; } Site; typedef struct { double a, b, c; Site *ep[2]; Site *leftReg, *rightReg; int neighbor; } Edge; struct _HalfEdge { HalfEdge *leftPtr, *rightPtr; Edge *edgePtr; int refCount; int pm; Site *vertex; double ystar; HalfEdge *pqNext; }; /* Static variables */ typedef struct { double xMin, xMax, yMin, yMax, xDelta, yDelta; Site *sites; int nSites; int siteIndex; int sqrtNumSites; int nVertices; Site *bottomsite; int nEdges; FreeList freeSites; FreeList freeEdges; FreeList freeHalfEdges; HalfEdge *elLeftEnd, *elRightEnd; int elHashsize; HalfEdge **elHash; int pqHashsize; HalfEdge *pqHash; int pqCount; int pqMin; Blt_Chain allocChain; } Voronoi; static void FreeInit(FreeList *listPtr, int size) { listPtr->headPtr = NULL; listPtr->nodesize = size; } static void InitMemorySystem(Voronoi *v) { if (v->allocChain == NULL) { v->allocChain = Blt_Chain_Create(); } FreeInit(&v->freeSites, sizeof(Site)); } static void * AllocMemory(Voronoi *v, size_t size) { void *ptr; ptr = Blt_Malloc(size); if (ptr == NULL) { return NULL; } Blt_Chain_Append(v->allocChain, ptr); return ptr; } static void ReleaseMemorySystem(Voronoi *v) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(v->allocChain); link != NULL; link = Blt_Chain_PrevLink(link)) { void *ptr; ptr = Blt_Chain_GetValue(link); if (ptr != NULL) { Blt_Free(ptr); } } Blt_Chain_Destroy(v->allocChain); v->allocChain = NULL; } INLINE static void MakeFree(void *item, FreeList *listPtr) { FreeNode *nodePtr = item; nodePtr->nextPtr = listPtr->headPtr; listPtr->headPtr = nodePtr; } static void * GetFree(Voronoi *v, FreeList *listPtr) { FreeNode *nodePtr; if (listPtr->headPtr == NULL) { int i; nodePtr = AllocMemory(v, v->sqrtNumSites * listPtr->nodesize); /* Thread the free nodes as a list */ for (i = 0; i < v->sqrtNumSites; i++) { MakeFree(((char *)nodePtr + i * listPtr->nodesize), listPtr); } } nodePtr = listPtr->headPtr; listPtr->headPtr = listPtr->headPtr->nextPtr; return nodePtr; } INLINE static void DecrRefCount(Voronoi *v, Site *vertexPtr) { vertexPtr->refCount--; if (vertexPtr->refCount == 0) { MakeFree(vertexPtr, &v->freeSites); } } INLINE static void IncrRefCount(Site *vertexPtr) { vertexPtr->refCount++; } INLINE static HalfEdge * HECreate(Voronoi *v, Edge *edgePtr, int pm) { HalfEdge *hePtr; hePtr = GetFree(v, &v->freeHalfEdges); hePtr->edgePtr = edgePtr; hePtr->pm = pm; hePtr->pqNext = NULL; hePtr->vertex = NULL; hePtr->refCount = 0; return hePtr; } static void ElInitialize(Voronoi *v) { FreeInit(&v->freeHalfEdges, sizeof(HalfEdge)); v->elHashsize = 2 * v->sqrtNumSites; v->elHash = AllocMemory(v, v->elHashsize * sizeof(HalfEdge *)); assert(v->elHash); memset(v->elHash, 0, v->elHashsize * sizeof(HalfEdge *)); v->elLeftEnd = HECreate(v, (Edge *)NULL, 0); v->elRightEnd = HECreate(v, (Edge *)NULL, 0); v->elLeftEnd->leftPtr = NULL; v->elLeftEnd->rightPtr = v->elRightEnd; v->elRightEnd->leftPtr = v->elLeftEnd; v->elRightEnd->rightPtr = NULL; v->elHash[0] = v->elLeftEnd; v->elHash[v->elHashsize - 1] = v->elRightEnd; } INLINE static void ElInsert(HalfEdge *lb, HalfEdge *edgePtr) { edgePtr->leftPtr = lb; edgePtr->rightPtr = lb->rightPtr; lb->rightPtr->leftPtr = edgePtr; lb->rightPtr = edgePtr; } static HalfEdge * ElGetHash(Voronoi *v, int b) { HalfEdge *hePtr; if ((b < 0) || (b >= v->elHashsize)) { return NULL; } hePtr = v->elHash[b]; if ((hePtr == NULL) || (hePtr->edgePtr != DELETED)) { return hePtr; } /* Hash table points to deleted half edge. Patch as necessary. */ v->elHash[b] = NULL; hePtr->refCount--; if (hePtr->refCount == 0) { MakeFree(hePtr, &v->freeHalfEdges); } return NULL; } static int RightOf(HalfEdge *hePtr, Point2d *p) { Edge *e; Site *topsite; int rightOfSite, above, fast; double dxp, dyp, dxs, t1, t2, t3, yl; e = hePtr->edgePtr; topsite = e->rightReg; rightOfSite = p->x > topsite->point.x; if ((rightOfSite) && (hePtr->pm == LE)) { return 1; } if ((!rightOfSite) && (hePtr->pm == RE)) { return 0; } if (e->a == 1.0) { dyp = p->y - topsite->point.y; dxp = p->x - topsite->point.x; fast = 0; if ((!rightOfSite & e->b < 0.0) | (rightOfSite & e->b >= 0.0)) { above = dyp >= e->b * dxp; fast = above; } else { above = p->x + p->y * e->b > e->c; if (e->b < 0.0) { above = !above; } if (!above) { fast = 1; } } if (!fast) { dxs = topsite->point.x - (e->leftReg)->point.x; above = e->b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1.0 + 2.0 * dxp / dxs + e->b * e->b); if (e->b < 0.0) { above = !above; } } } else { /* e->b==1.0 */ yl = e->c - e->a * p->x; t1 = p->y - yl; t2 = p->x - topsite->point.x; t3 = yl - topsite->point.y; above = t1 * t1 > t2 * t2 + t3 * t3; } return (hePtr->pm == LE ? above : !above); } static HalfEdge * ElLeftBnd(Voronoi *v, Point2d *p) { int i, bucket; HalfEdge *hePtr; /* Use hash table to get close to desired halfedge */ bucket = (p->x - v->xMin) / v->xDelta * v->elHashsize; if (bucket < 0) { bucket = 0; } else if (bucket >= v->elHashsize) { bucket = v->elHashsize - 1; } hePtr = ElGetHash(v, bucket); if (hePtr == NULL) { for (i = 1; /* empty */ ; i++) { hePtr = ElGetHash(v, bucket - i); if (hePtr != NULL) { break; } hePtr = ElGetHash(v, bucket + i); if (hePtr != NULL) { break; } } } /* Now search linear list of halfedges for the correct one */ if ((hePtr == v->elLeftEnd) || (hePtr != v->elRightEnd && RightOf(hePtr, p))) { do { hePtr = hePtr->rightPtr; } while ((hePtr != v->elRightEnd) && (RightOf(hePtr, p))); hePtr = hePtr->leftPtr; } else { do { hePtr = hePtr->leftPtr; } while ((hePtr != v->elLeftEnd) && (!RightOf(hePtr, p))); } /* Update hash table and reference counts */ if ((bucket > 0) && (bucket < (v->elHashsize - 1))) { if (v->elHash[bucket] != NULL) { v->elHash[bucket]->refCount--; } v->elHash[bucket] = hePtr; v->elHash[bucket]->refCount++; } return hePtr; } /* * This delete routine can't reclaim node, since pointers from hash table may * be present. */ INLINE static void ElDelete(HalfEdge *hePtr) { hePtr->leftPtr->rightPtr = hePtr->rightPtr; hePtr->rightPtr->leftPtr = hePtr->leftPtr; hePtr->edgePtr = DELETED; } INLINE static Site * LeftRegion(Voronoi *v, HalfEdge *hePtr) { if (hePtr->edgePtr == NULL) { return v->bottomsite; } return (hePtr->pm == LE) ? hePtr->edgePtr->leftReg : hePtr->edgePtr->rightReg; } INLINE static Site * RightRegion(Voronoi *v, HalfEdge *hePtr) { if (hePtr->edgePtr == NULL) { return v->bottomsite; } return (hePtr->pm == LE) ? hePtr->edgePtr->rightReg : hePtr->edgePtr->leftReg; } static void GeomInit(Voronoi *v) { FreeInit(&v->freeEdges, sizeof(Edge)); v->nVertices = v->nEdges = 0; v->sqrtNumSites = sqrt((double)(v->nSites + 4)); v->yDelta = v->xMax - v->xMax; v->xDelta = v->yMax - v->yMin; } static Edge * Bisect(Voronoi *v, Site *s1, Site *s2) { double dx, dy, adx, ady; Edge *edgePtr; edgePtr = GetFree(v, &v->freeEdges); edgePtr->leftReg = s1; edgePtr->rightReg = s2; IncrRefCount(s1); IncrRefCount(s2); edgePtr->ep[0] = edgePtr->ep[1] = NULL; dx = s2->point.x - s1->point.x; dy = s2->point.y - s1->point.y; adx = FABS(dx); ady = FABS(dy); edgePtr->c = (s1->point.x * dx) + (s1->point.y * dy) + ((dx * dx) + (dy * dy)) * 0.5; if (adx > ady) { edgePtr->a = 1.0; edgePtr->b = dy / dx; edgePtr->c /= dx; } else { edgePtr->b = 1.0; edgePtr->a = dx / dy; edgePtr->c /= dy; } edgePtr->neighbor = v->nEdges; v->nEdges++; return edgePtr; } static Site * Intersect(Voronoi *v, HalfEdge *hePtr1, HalfEdge *hePtr2) { Edge *e1, *e2, *e; HalfEdge *hePtr; double d, xint, yint; int rightOfSite; Site *sitePtr; e1 = hePtr1->edgePtr; e2 = hePtr2->edgePtr; if ((e1 == NULL) || (e2 == NULL)) { return NULL; } if (e1->rightReg == e2->rightReg) { return NULL; } d = (e1->a * e2->b) - (e1->b * e2->a); if ((-1.0e-10 < d) && (d < 1.0e-10)) { return NULL; } xint = ((e1->c * e2->b) - (e2->c * e1->b)) / d; yint = ((e2->c * e1->a) - (e1->c * e2->a)) / d; if ((e1->rightReg->point.y < e2->rightReg->point.y) || ((e1->rightReg->point.y == e2->rightReg->point.y) && (e1->rightReg->point.x < e2->rightReg->point.x))) { hePtr = hePtr1; e = e1; } else { hePtr = hePtr2; e = e2; } rightOfSite = (xint >= e->rightReg->point.x); if ((rightOfSite && hePtr->pm == LE) || (!rightOfSite && hePtr->pm == RE)) { return NULL; } sitePtr = GetFree(v, &v->freeSites); sitePtr->refCount = 0; sitePtr->point.x = xint; sitePtr->point.y = yint; return sitePtr; } INLINE static void EndPoint(Voronoi *v, Edge *e, int lr, Site *s) { e->ep[lr] = s; IncrRefCount(s); if (e->ep[RE - lr] == NULL) { return; } DecrRefCount(v, e->leftReg); DecrRefCount(v, e->rightReg); MakeFree(e, &v->freeEdges); } INLINE static void MakeVertex(Voronoi *v, Site *vertex) { vertex->neighbor = v->nVertices; v->nVertices++; } static int PQBucket(Voronoi *v, HalfEdge *hePtr) { int bucket; bucket = (hePtr->ystar - v->yMin) / v->yDelta * v->pqHashsize; if (bucket < 0) { bucket = 0; } if (bucket >= v->pqHashsize) { bucket = v->pqHashsize - 1; } if (bucket < v->pqMin) { v->pqMin = bucket; } return bucket; } static void PQInsert(Voronoi *v, HalfEdge *hePtr, Site *vertex, double offset) { HalfEdge *last, *next; hePtr->vertex = vertex; IncrRefCount(vertex); hePtr->ystar = vertex->point.y + offset; last = v->pqHash + PQBucket(v, hePtr); while (((next = last->pqNext) != NULL) && ((hePtr->ystar > next->ystar) || ((hePtr->ystar == next->ystar) && (vertex->point.x > next->vertex->point.x)))) { last = next; } hePtr->pqNext = last->pqNext; last->pqNext = hePtr; v->pqCount++; } static void PQDelete(Voronoi *v, HalfEdge *hePtr) { if (hePtr->vertex != NULL) { HalfEdge *last; last = v->pqHash + PQBucket(v, hePtr); while (last->pqNext != hePtr) { last = last->pqNext; } last->pqNext = hePtr->pqNext; v->pqCount--; DecrRefCount(v, hePtr->vertex); hePtr->vertex = NULL; } } INLINE static int PQEmpty(Voronoi *v) { return (v->pqCount == 0); } INLINE static Point2d PQMin(Voronoi *v) { Point2d p; while (v->pqHash[v->pqMin].pqNext == NULL) { v->pqMin++; } p.x = v->pqHash[v->pqMin].pqNext->vertex->point.x; p.y = v->pqHash[v->pqMin].pqNext->ystar; return p; } INLINE static HalfEdge * PQExtractMin(Voronoi *v) { HalfEdge *curr; curr = v->pqHash[v->pqMin].pqNext; v->pqHash[v->pqMin].pqNext = curr->pqNext; v->pqCount--; return curr; } static void PQInitialize(Voronoi *v) { size_t nBytes; v->pqCount = v->pqMin = 0; v->pqHashsize = 4 * v->sqrtNumSites; nBytes = v->pqHashsize * sizeof(HalfEdge); v->pqHash = AllocMemory(v, nBytes); assert(v->pqHash); memset(v->pqHash, 0, nBytes); } INLINE static Site * NextSite(Voronoi *v) { if (v->siteIndex < v->nSites) { Site *s; s = v->sites + v->siteIndex; v->siteIndex++; return s; } return NULL; } static int ComputeVoronoi(Voronoi *v, Triplet *triplets) { Site *newsite, *bot, *top, *temp, *p; Site *vertex; Point2d newintstar; int pm, count = 0; HalfEdge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; Edge *e; PQInitialize(v); v->bottomsite = NextSite(v); ElInitialize(v); newsite = NextSite(v); for (;;) { if (!PQEmpty(v)) { newintstar = PQMin(v); } if ((newsite != NULL) && ((PQEmpty(v)) || (newsite->point.y < newintstar.y) || (newsite->point.y == newintstar.y) && (newsite->point.x < newintstar.x))) { /* New site is smallest */ lbnd = ElLeftBnd(v, &newsite->point); rbnd = lbnd->rightPtr; bot = RightRegion(v, lbnd); e = Bisect(v, bot, newsite); bisector = HECreate(v, e, LE); ElInsert(lbnd, bisector); p = Intersect(v, lbnd, bisector); if (p != NULL) { PQDelete(v, lbnd); PQInsert(v, lbnd, p, Dist(p, newsite)); } lbnd = bisector; bisector = HECreate(v, e, RE); ElInsert(lbnd, bisector); p = Intersect(v, bisector, rbnd); if (p != NULL) { PQInsert(v, bisector, p, Dist(p, newsite)); } newsite = NextSite(v); } else if (!PQEmpty(v)) { /* Intersection is smallest */ lbnd = PQExtractMin(v); llbnd = lbnd->leftPtr; rbnd = lbnd->rightPtr; rrbnd = rbnd->rightPtr; bot = LeftRegion(v, lbnd); top = RightRegion(v, rbnd); triplets[count].a = bot->neighbor; triplets[count].b = top->neighbor; triplets[count].c = RightRegion(v, lbnd)->neighbor; ++count; vertex = lbnd->vertex; MakeVertex(v, vertex); EndPoint(v, lbnd->edgePtr, lbnd->pm, vertex); EndPoint(v, rbnd->edgePtr, rbnd->pm, vertex); ElDelete(lbnd); PQDelete(v, rbnd); ElDelete(rbnd); pm = LE; if (bot->point.y > top->point.y) { temp = bot, bot = top, top = temp; pm = RE; } e = Bisect(v, bot, top); bisector = HECreate(v, e, pm); ElInsert(llbnd, bisector); EndPoint(v, e, RE - pm, vertex); DecrRefCount(v, vertex); p = Intersect(v, llbnd, bisector); if (p != NULL) { PQDelete(v, llbnd); PQInsert(v, llbnd, p, Dist(p, bot)); } p = Intersect(v, bisector, rrbnd); if (p != NULL) { PQInsert(v, bisector, p, Dist(p, bot)); } } else { break; } } return count; } static int CompareSites(const void *a, const void *b) { const Site *s1 = a; const Site *s2 = b; if (s1->point.y < s2->point.y) { return -1; } if (s1->point.y > s2->point.y) { return 1; } if (s1->point.x < s2->point.x) { return -1; } if (s1->point.x > s2->point.x) { return 1; } return 0; } int Blt_Triangulate(Tcl_Interp *interp, size_t nPoints, Point2f *points, int sorted, int *nTrianglesPtr, Triplet **trianglesPtr) { int i; Site *sp, *send; int n; Voronoi v; Triplet *triangles; memset(&v, 0, sizeof(v)); InitMemorySystem(&v); v.nSites = nPoints; v.sites = AllocMemory(&v, nPoints * sizeof(Site)); for (sp = v.sites, send = sp + nPoints, i = 0; sp < send; i++, sp++) { sp->point.x = points[i].x; sp->point.y = points[i].y; sp->neighbor = i; sp->refCount = 0; } if (!sorted) { qsort(v.sites, v.nSites, sizeof(Site), CompareSites); } sp = v.sites; v.xMin = v.xMax = sp->point.x; v.yMin = sp->point.y; v.yMax = v.sites[nPoints - 1].point.y; for (sp++, send = v.sites + nPoints; sp < send; sp++) { if (sp->point.x < v.xMin) { v.xMin = sp->point.x; } else if (sp->point.x > v.xMax) { v.xMax = sp->point.x; } } v.siteIndex = 0; GeomInit(&v); n = ComputeVoronoi(&v, triangles); /* Release memory allocated for triangulation */ ReleaseMemorySystem(&v); *nTrianglesPtr = n; *trianglesPtr = triangles; return TCL_OK; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBgStyle.c������������������������������������������������������������������0000644�0001750�0001750�00000266217�11462120062�015262� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBgPattern.c -- * * This module creates background patterns for the BLT toolkit. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltChain.h" #include "bltHash.h" #include "bltImage.h" #include "bltPicture.h" #include "bltPainter.h" #include <X11/Xutil.h> #include "bltBgStyle.h" #define BG_PATTERN_THREAD_KEY "BLT Background Pattern Data" #define TEXTURE_CHECKERED 1 #define TEXTURE_STRIPED 0 /* bgpattern create pattern -image $image -color $color -darkcolor $color -lightcolor $color -resamplefilter $filter -opacity $alpha -xorigin $x -yorigin $y -tile yes -center yes -scale no -relativeto self|toplevel|window -mask image|bitmap bgpattern create tile -relativeto self|toplevel|window -image $image -bg $color bgpattern create picture -image $image -filter $filterName -bg $color bgpattern create gradient -type radial|xlinear|ylinear|diagonal -low $color -high $color -bg $color bgpattern create border -bg $color -alpha $color bgpattern create texture -type metal|wind|??? -bg $color bgpattern names bgpattern configure $tile bgpattern delete $tile */ enum PatternTypes { PATTERN_GRADIENT, /* Color gradient. */ PATTERN_TILE, /* Tiled or resizable color picture. */ PATTERN_SOLID, /* General pattern. */ PATTERN_TEXTURE, /* Procedural texture. */ }; static const char *patternTypes[] = { "gradient", "tile", "solid", "texture" }; enum ReferenceTypes { REFERENCE_SELF, /* Current window. */ REFERENCE_TOPLEVEL, /* Toplevel of current window. */ REFERENCE_WINDOW, /* Specifically named window. */ REFERENCE_NONE, /* Don't use reference * window. Background region will be * defined by user. */ }; typedef struct { int x, y; unsigned int w, h; Tk_Window tkwin; } Reference; typedef struct { int x, y, width, height; } BgRegion; typedef struct { Blt_HashTable patternTable; /* Hash table of pattern structures * keyed by the name of the image. */ Tcl_Interp *interp; /* Interpreter associated with this set * of background patterns. */ int nextId; /* Serial number of the identifier to be * used for next background pattern * created. */ } BackgroundInterpData; typedef struct _Pattern Pattern; typedef void (DestroyPatternProc)(Pattern *patternPtr); typedef int (ConfigurePatternProc)(Tcl_Interp *interp, Pattern *patternPtr, int objc, Tcl_Obj *const *objv, unsigned int flags); typedef void (DrawRectangleProc)(Tk_Window tkwin, Drawable drawable, Pattern *patternPtr, int x, int y, int w, int h); typedef void (DrawPolygonProc)(Tk_Window tkwin, Drawable drawable, Pattern *patternPtr, int nPoints, XPoint *points); typedef struct { enum PatternTypes type; /* Type of pattern style: solid, tile, * texture, or gradient. */ Blt_ConfigSpec *configSpecs; DestroyPatternProc *destroyProc; ConfigurePatternProc *configProc; DrawRectangleProc *drawRectangleProc; DrawPolygonProc *drawPolygonProc; } PatternClass; struct _Pattern { const char *name; /* Generated name of background * pattern. */ PatternClass *classPtr; BackgroundInterpData *dataPtr; Tk_Window tkwin; /* Main window. Used to query background * pattern options. */ Display *display; /* Display of this background * pattern. */ unsigned int flags; /* See definitions below. */ Blt_HashEntry *hashPtr; /* Hash entry in pattern table. */ Blt_Chain chain; /* List of pattern tokens. Used to * register callbacks for each client of * the background pattern. */ Blt_ChainLink link; /* Background token that is associated * with the pattern creation "bgpattern * create...". */ Tk_3DBorder border; /* 3D Border. May be used for all * background types. */ Tk_Window refWindow; /* Refer to coordinates in this window * when determining the tile/gradient * origin. */ BgRegion refRegion; Blt_HashTable pictTable; /* Table of pictures cached for each * pattern reference. */ int reference; /* "self", "toplevel", or "window". */ int xOrigin, yOrigin; }; typedef struct { const char *name; /* Generated name of background * pattern. */ PatternClass *classPtr; BackgroundInterpData *dataPtr; Tk_Window tkwin; /* Main window. Used to query background * pattern options. */ Display *display; /* Display of this background * pattern. */ unsigned int flags; /* See definitions below. */ Blt_HashEntry *hashPtr; /* Link to original client. */ Blt_Chain chain; /* List of pattern tokens. Used to * register callbacks for each client of * the background pattern. */ Blt_ChainLink link; /* Background token that is associated * with the pattern creation "bgpattern * create...". */ Tk_3DBorder border; /* 3D Border. May be used for all * pattern types. */ Tk_Window refWindow; /* Refer to coordinates in this window * when determining the tile/gradient * origin. */ BgRegion refRegion; Blt_HashTable pictTable; /* Table of pictures cached for each * pattern reference. */ int reference; /* "self", "toplevel", or "window". */ int xOrigin, yOrigin; /* Solid pattern specific fields. */ int alpha; /* Transparency value. */ } SolidPattern; typedef struct { const char *name; /* Generated name of background * pattern. */ PatternClass *classPtr; BackgroundInterpData *dataPtr; Tk_Window tkwin; /* Main window. Used to query background * pattern options. */ Display *display; /* Display of this background * pattern. */ unsigned int flags; /* See definitions below. */ Blt_HashEntry *hashPtr; /* Link to original client. */ Blt_Chain chain; /* List of pattern tokens. Used to * register callbacks for each client of * the background pattern. */ Blt_ChainLink link; /* Background token that is associated * with the pattern creation "bgpattern * create...". */ Tk_3DBorder border; /* 3D Border. May be used for all * pattern types. */ Tk_Window refWindow; /* Refer to coordinates in this window * when determining the tile/gradient * origin. */ BgRegion refRegion; Blt_HashTable pictTable; /* Table of pictures cached for each * pattern reference. */ int reference; /* "self", "toplevel", or "window". */ int xOrigin, yOrigin; /* Image pattern specific fields. */ Tk_Image tkImage; /* Original image (before * resampling). */ Blt_ResampleFilter filter; /* 1-D image filter to use to when * resizing the original picture. */ } TilePattern; typedef struct { const char *name; /* Generated name of background * pattern. */ PatternClass *classPtr; BackgroundInterpData *dataPtr; Tk_Window tkwin; /* Main window. Used to query background * pattern options. */ Display *display; /* Display of this background * pattern. */ unsigned int flags; /* See definitions below. */ Blt_HashEntry *hashPtr; /* Link to original client. */ Blt_Chain chain; /* List of pattern tokens. Used to * register callbacks for each client of * the background pattern. */ Blt_ChainLink link; /* Background token that is associated * with the pattern creation "bgpattern * create...". */ Tk_3DBorder border; /* 3D Border. May be used for all * pattern types. */ Tk_Window refWindow; /* Refer to coordinates in this window * when determining the tile/gradient * origin. */ BgRegion refRegion; Blt_HashTable pictTable; /* Table of pictures cached for each * pattern reference. */ int reference; /* "self", "toplevel", or "window". */ int xOrigin, yOrigin; /* Gradient pattern specific fields. */ Blt_Gradient gradient; Blt_Pixel low, high; /* Texture or gradient colors. */ int alpha; /* Transparency value. */ } GradientPattern; typedef struct { const char *name; /* Generated name of background * pattern. */ PatternClass *classPtr; BackgroundInterpData *dataPtr; Tk_Window tkwin; /* Main window. Used to query background * pattern options. */ Display *display; /* Display of this background * pattern. */ unsigned int flags; /* See definitions below. */ Blt_HashEntry *hashPtr; /* Link to original client. */ Blt_Chain chain; /* List of pattern tokens. Used to * register callbacks for each client of * the background pattern. */ Blt_ChainLink link; /* Background token that is associated * with the pattern creation "bgpattern * create...". */ Tk_3DBorder border; /* 3D Border. May be used for all * pattern types. */ Tk_Window refWindow; /* Refer to coordinates in this window * when determining the tile/gradient * origin. */ BgRegion refRegion; Blt_HashTable pictTable; /* Table of pictures cached for each * pattern reference. */ int reference; /* "self", "toplevel", or "window". */ int xOrigin, yOrigin; /* Texture pattern specific fields. */ Blt_Pixel low, high; /* Texture colors. */ int alpha; /* Transparency value. */ int type; } TexturePattern; struct _Blt_Background { Pattern *corePtr; /* Pointer to master background pattern * object. */ Blt_BackgroundChangedProc *notifyProc; ClientData clientData; /* Data to be passed on notifier * callbacks. */ Blt_ChainLink link; /* Entry in notifier list. */ }; #define DELETE_PENDING (1<<0) #define BG_CENTER (1<<2) #define BG_SCALE (1<<3) typedef struct _Blt_Background Background; #define DEF_OPACITY "100.0" #define DEF_ORIGIN_X "0" #define DEF_ORIGIN_Y "0" #define DEF_BORDER STD_NORMAL_BACKGROUND #define DEF_GRADIENT_PATH "y" #define DEF_GRADIENT_HIGH "grey90" #define DEF_GRADIENT_JITTER "no" #define DEF_GRADIENT_LOGSCALE "yes" #define DEF_GRADIENT_LOW "grey50" #define DEF_GRADIENT_MODE "xlinear" #define DEF_GRADIENT_SHAPE "linear" #define DEF_REFERENCE "toplevel" #define DEF_RESAMPLE_FILTER "box" #define DEF_SCALE "no" #define DEF_CENTER "no" #define DEF_TILE "no" static Blt_OptionParseProc ObjToImageProc; static Blt_OptionPrintProc ImageToObjProc; static Blt_OptionFreeProc FreeImageProc; static Blt_CustomOption imageOption = { ObjToImageProc, ImageToObjProc, FreeImageProc, (ClientData)0 }; extern Blt_CustomOption bltFilterOption; static Blt_OptionParseProc ObjToReferenceProc; static Blt_OptionPrintProc ReferenceToObjProc; static Blt_CustomOption referenceToOption = { ObjToReferenceProc, ReferenceToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToShapeProc; static Blt_OptionPrintProc ShapeToObjProc; static Blt_CustomOption shapeOption = { ObjToShapeProc, ShapeToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToPathProc; static Blt_OptionPrintProc PathToObjProc; static Blt_CustomOption pathOption = { ObjToPathProc, PathToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToOpacityProc; static Blt_OptionPrintProc OpacityToObjProc; static Blt_CustomOption opacityOption = { ObjToOpacityProc, OpacityToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToTypeProc; static Blt_OptionPrintProc TypeToObjProc; static Blt_CustomOption typeOption = { ObjToTypeProc, TypeToObjProc, NULL, (ClientData)0 }; static Blt_ConfigSpec solidConfigSpecs[] = { {BLT_CONFIG_SYNONYM, "-background", "color", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "color", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BORDER, "-color", "color", "Color", DEF_BORDER, Blt_Offset(SolidPattern, border), 0}, {BLT_CONFIG_CUSTOM, "-opacity", "opacity", "Opacity", "100.0", Blt_Offset(SolidPattern, alpha), BLT_CONFIG_DONT_SET_DEFAULT, &opacityOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec tileConfigSpecs[] = { {BLT_CONFIG_BITMASK, "-center", "center", "Center", DEF_CENTER, Blt_Offset(TilePattern, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)BG_CENTER}, {BLT_CONFIG_BORDER, "-color", "color", "Color", DEF_BORDER, Blt_Offset(TilePattern, border), 0}, {BLT_CONFIG_BORDER, "-darkcolor", "darkColor", "DarkColor", DEF_BORDER, Blt_Offset(TilePattern, border), 0}, {BLT_CONFIG_CUSTOM, "-filter", "filter", "Filter", DEF_RESAMPLE_FILTER, Blt_Offset(TilePattern, filter), 0, &bltFilterOption}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", (char *)NULL, Blt_Offset(TilePattern, tkImage), BLT_CONFIG_DONT_SET_DEFAULT, &imageOption}, {BLT_CONFIG_BORDER, "-lightcolor", "lightColor", "LightColor", DEF_BORDER, Blt_Offset(TilePattern, border), 0}, {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", DEF_REFERENCE, Blt_Offset(TilePattern, reference), BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption}, {BLT_CONFIG_BITMASK, "-scale", "scale", "scale", DEF_SCALE, Blt_Offset(TilePattern, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)BG_SCALE}, {BLT_CONFIG_PIXELS, "-xorigin", "xOrigin", "XOrigin", DEF_ORIGIN_X, Blt_Offset(TilePattern, xOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yorigin", "yOrigin", "YOrigin", DEF_ORIGIN_Y, Blt_Offset(TilePattern, yOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec gradientConfigSpecs[] = { {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_BORDER, Blt_Offset(GradientPattern, border), 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-direction", "direction", "Direction", DEF_GRADIENT_PATH, Blt_Offset(GradientPattern, gradient.path), BLT_CONFIG_DONT_SET_DEFAULT, &pathOption}, {BLT_CONFIG_PIX32, "-high", "high", "High", DEF_GRADIENT_HIGH, Blt_Offset(GradientPattern, high), 0}, {BLT_CONFIG_BOOLEAN, "-jitter", "jitter", "Jitter", DEF_GRADIENT_JITTER, Blt_Offset(GradientPattern, gradient.jitter), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-logscale", "logscale", "Logscale", DEF_GRADIENT_LOGSCALE, Blt_Offset(GradientPattern,gradient.logScale), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIX32, "-low", "low", "Low", DEF_GRADIENT_LOW, Blt_Offset(GradientPattern, low), 0}, {BLT_CONFIG_CUSTOM, "-opacity", "opacity", "Opacity", "100.0", Blt_Offset(GradientPattern, alpha), BLT_CONFIG_DONT_SET_DEFAULT, &opacityOption}, {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", DEF_REFERENCE, Blt_Offset(GradientPattern, reference), BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption}, {BLT_CONFIG_CUSTOM, "-shape", "shape", "Shape", DEF_GRADIENT_SHAPE, Blt_Offset(GradientPattern, gradient.shape), BLT_CONFIG_DONT_SET_DEFAULT, &shapeOption}, {BLT_CONFIG_PIXELS, "-xorigin", "xOrigin", "XOrigin", DEF_ORIGIN_X, Blt_Offset(GradientPattern, xOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yorigin", "yOrigin", "YOrigin", DEF_ORIGIN_Y, Blt_Offset(GradientPattern, yOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec textureConfigSpecs[] = { {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_BORDER, Blt_Offset(TexturePattern, border), 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIX32, "-high", "high", "High", DEF_GRADIENT_HIGH, Blt_Offset(TexturePattern, high), 0}, {BLT_CONFIG_PIX32, "-low", "low", "Low", DEF_GRADIENT_LOW, Blt_Offset(TexturePattern, low), 0}, {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", DEF_REFERENCE, Blt_Offset(TexturePattern, reference), BLT_CONFIG_DONT_SET_DEFAULT, &referenceToOption}, {BLT_CONFIG_CUSTOM, "-type", "type", "Type", DEF_REFERENCE, Blt_Offset(TexturePattern, type), BLT_CONFIG_DONT_SET_DEFAULT, &typeOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static void NotifyClients(Pattern *corePtr); static Blt_Picture ImageToPicture(TilePattern *patternPtr, int *isFreePtr) { Tcl_Interp *interp; interp = patternPtr->dataPtr->interp; return Blt_GetPictureFromImage(interp, patternPtr->tkImage, isFreePtr); } /* *--------------------------------------------------------------------------- * * ImageChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, int width, int height, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Pattern *corePtr = clientData; /* Propagate the change in the image to all the clients. */ NotifyClients(corePtr); } /*ARGSUSED*/ static void FreeImageProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { TilePattern *patternPtr = (TilePattern *)(widgRec); if (patternPtr->tkImage != NULL) { Tk_FreeImage(patternPtr->tkImage); patternPtr->tkImage = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToImageProc -- * * Given an image name, get the Tk image associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToImageProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { TilePattern *patternPtr = (TilePattern *)(widgRec); Tk_Image tkImage; tkImage = Tk_GetImage(interp, patternPtr->tkwin, Tcl_GetString(objPtr), ImageChangedProc, patternPtr); if (tkImage == NULL) { return TCL_ERROR; } patternPtr->tkImage = tkImage; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImageToObjProc -- * * Convert the image name into a string Tcl_Obj. * * Results: * The string representation of the image is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ImageToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { TilePattern *patternPtr = (TilePattern *)(widgRec); if (patternPtr->tkImage == NULL) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(Blt_Image_Name(patternPtr->tkImage), -1); } /* *--------------------------------------------------------------------------- * * ObjToReference -- * * Given a string name, get the resample filter associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToReferenceProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Pattern *patternPtr = (Pattern *)(widgRec); int *referencePtr = (int *)(widgRec + offset); const char *string; char c; int refType; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 's') && (strncmp(string, "self", length) == 0)) { refType = REFERENCE_SELF; } else if ((c == 't') && (strncmp(string, "toplevel", length) == 0)) { refType = REFERENCE_TOPLEVEL; } else if ((c == 'n') && (strncmp(string, "none", length) == 0)) { refType = REFERENCE_NONE; } else if (c == '.') { Tk_Window tkwin, tkMain; tkMain = Tk_MainWindow(interp); tkwin = Tk_NameToWindow(interp, string, tkMain); if (tkwin == NULL) { return TCL_ERROR; } refType = REFERENCE_WINDOW; patternPtr->refWindow = tkwin; } else { Tcl_AppendResult(interp, "unknown reference type \"", string, "\"", (char *)NULL); return TCL_ERROR; } *referencePtr = refType; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ReferenceToObjProc -- * * Convert the picture filter into a string Tcl_Obj. * * Results: * The string representation of the filter is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ReferenceToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { int reference = *(int *)(widgRec + offset); const char *string; switch (reference) { case REFERENCE_SELF: string = "self"; break; case REFERENCE_TOPLEVEL: string = "toplevel"; break; case REFERENCE_NONE: string = "none"; break; case REFERENCE_WINDOW: { Pattern *patternPtr = (Pattern *)(widgRec); string = Tk_PathName(patternPtr->refWindow); } break; default: string = "???"; break; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToShapeProc -- * * Translate the given string to the gradient shape is represents. Value * shapes are "linear", "bilinear", "radial", and "rectangular". * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToShapeProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Blt_GradientShape *shapePtr = (Blt_GradientShape *)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "linear") == 0) { *shapePtr = BLT_GRADIENT_SHAPE_LINEAR; } else if (strcmp(string, "bilinear") == 0) { *shapePtr = BLT_GRADIENT_SHAPE_BILINEAR; } else if (strcmp(string, "radial") == 0) { *shapePtr = BLT_GRADIENT_SHAPE_RADIAL; } else if (strcmp(string, "rectangular") == 0) { *shapePtr = BLT_GRADIENT_SHAPE_RECTANGULAR; } else { Tcl_AppendResult(interp, "unknown gradient type \"", string, "\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShapeToObjProc -- * * Returns the string representing the current gradiant shape. * * Results: * The string representation of the shape is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ShapeToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Blt_GradientShape shape = *(Blt_GradientShape *)(widgRec + offset); const char *string; switch (shape) { case BLT_GRADIENT_SHAPE_LINEAR: string = "linear"; break; case BLT_GRADIENT_SHAPE_BILINEAR: string = "bilinear"; break; case BLT_GRADIENT_SHAPE_RADIAL: string = "radial"; break; case BLT_GRADIENT_SHAPE_RECTANGULAR: string = "rectangular"; break; default: string = "???"; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToPathProc -- * * Translates the given string to the gradient path it represents. Valid * paths are "x", "y", "xy", and "yx". * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPathProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Blt_GradientPath *pathPtr = (Blt_GradientPath *)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "x") == 0) { *pathPtr = BLT_GRADIENT_PATH_X; } else if (strcmp(string, "y") == 0) { *pathPtr = BLT_GRADIENT_PATH_Y; } else if (strcmp(string, "xy") == 0) { *pathPtr = BLT_GRADIENT_PATH_XY; } else if (strcmp(string, "yx") == 0) { *pathPtr = BLT_GRADIENT_PATH_YX; } else { Tcl_AppendResult(interp, "unknown gradient path \"", string, "\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PathToObjProc -- * * Convert the picture filter into a string Tcl_Obj. * * Results: * The string representation of the filter is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PathToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Blt_GradientPath path = *(Blt_GradientPath *)(widgRec + offset); const char *string; switch (path) { case BLT_GRADIENT_PATH_X: string = "x"; break; case BLT_GRADIENT_PATH_Y: string = "y"; break; case BLT_GRADIENT_PATH_XY: string = "xy"; break; case BLT_GRADIENT_PATH_YX: string = "yx"; break; default: string = "?? unknown path ??"; break; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToOpacity -- * * Given a string name, get the resample filter associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToOpacityProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { int *alphaPtr = (int *)(widgRec + offset); double opacity; if (Tcl_GetDoubleFromObj(interp, objPtr, &opacity) != TCL_OK) { return TCL_ERROR; } if ((opacity < 0.0) || (opacity > 100.0)) { Tcl_AppendResult(interp, "invalid percent opacity \"", Tcl_GetString(objPtr), "\" should be 0 to 100", (char *)NULL); return TCL_ERROR; } opacity = (opacity / 100.0) * 255.0; *alphaPtr = ROUND(opacity); return TCL_OK; } /* *--------------------------------------------------------------------------- * * OpacityToObj -- * * Convert the picture filter into a string Tcl_Obj. * * Results: * The string representation of the filter is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * OpacityToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { int *alphaPtr = (int *)(widgRec + offset); double opacity; opacity = (*alphaPtr / 255.0) * 100.0; return Tcl_NewDoubleObj(opacity); } /* *--------------------------------------------------------------------------- * * ObjToTypeProc -- * * Translate the given string to the gradient shape is represents. Value * shapes are "linear", "bilinear", "radial", and "rectangular". * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTypeProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { int *typePtr = (int *)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "striped") == 0) { *typePtr = TEXTURE_STRIPED; } else if (strcmp(string, "checkered") == 0) { *typePtr = TEXTURE_CHECKERED; } else { Tcl_AppendResult(interp, "unknown pattern type \"", string, "\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeToObjProc -- * * Returns the string representing the current pattern type. * * Results: * The string representation of the pattern is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TypeToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { int type = *(int *)(widgRec + offset); const char *string; switch (type) { case TEXTURE_STRIPED: string = "striped"; break; case TEXTURE_CHECKERED: string = "checkered"; break; default: string = "???"; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * NotifyClients -- * * Notify each client that the background pattern has changed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void NotifyClients(Pattern *patternPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(patternPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Background *bgPtr; /* Notify each client that the background pattern has changed. The * client should schedule itself for redrawing. */ bgPtr = Blt_Chain_GetValue(link); if (bgPtr->notifyProc != NULL) { (*bgPtr->notifyProc)(bgPtr->clientData); } } } static const char * NameOfPattern(Pattern *patternPtr) { return patternTypes[patternPtr->classPtr->type]; } static int GetPatternTypeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *typePtr) { const char *string; char c; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 't') && (length > 1) && (strncmp(string, "tile", length) == 0)) { *typePtr = PATTERN_TILE; } else if ((c == 'g') && (strncmp(string, "gradient", length) == 0)) { *typePtr = PATTERN_GRADIENT; } else if ((c == 's') && (strncmp(string, "solid", length) == 0)) { *typePtr = PATTERN_SOLID; } else if ((c == 't') && (length > 1) && (strncmp(string, "texture", length) == 0)) { *typePtr = PATTERN_TEXTURE; } else { if (interp != NULL) { Tcl_AppendResult(interp, "unknown background pattern \"", string, "\"", (char *)NULL); } return TCL_ERROR; } return TCL_OK; } static void ClearCache(Pattern *corePtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&corePtr->pictTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_Picture picture; picture = Blt_GetHashValue(hPtr); Blt_FreePicture(picture); } } static void GetTileOffsets(Tk_Window tkwin, Pattern *patternPtr, Blt_Picture picture, int x, int y, int *xOffsetPtr, int *yOffsetPtr) { int dx, dy; int x0, y0; int tw, th; Tk_Window refWindow; if (patternPtr->reference == REFERENCE_SELF) { refWindow = tkwin; } else if (patternPtr->reference == REFERENCE_TOPLEVEL) { refWindow = Blt_Toplevel(tkwin); } else if (patternPtr->reference == REFERENCE_WINDOW) { refWindow = patternPtr->refWindow; } else if (patternPtr->reference == REFERENCE_NONE) { refWindow = NULL; } else { return; /* Unknown reference window. */ } if ((patternPtr->reference == REFERENCE_WINDOW) || (patternPtr->reference == REFERENCE_TOPLEVEL)) { Tk_Window tkwin2; tkwin2 = tkwin; while ((tkwin2 != refWindow) && (tkwin2 != NULL)) { x += Tk_X(tkwin2) + Tk_Changes(tkwin2)->border_width; y += Tk_Y(tkwin2) + Tk_Changes(tkwin2)->border_width; tkwin2 = Tk_Parent(tkwin2); } if (tkwin2 == NULL) { /* * The window associated with the background pattern isn't an * ancestor of the current window. That means we can't use the * reference window as a guide to the size of the picture. Simply * convert to a self reference. */ patternPtr->reference = REFERENCE_SELF; refWindow = tkwin; abort(); } } x0 = patternPtr->xOrigin; y0 = patternPtr->yOrigin; tw = Blt_PictureWidth(picture); th = Blt_PictureHeight(picture); /* Compute the starting x and y offsets of the tile/gradient from the * coordinates of the origin. */ dx = (x0 - x) % tw; if (dx > 0) { dx = (tw - dx); } else if (dx < 0) { dx = x - x0; } dy = (y0 - y) % th; if (dy > 0) { dy = (th - dy); } else if (dy < 0) { dy = y - y0; } *xOffsetPtr = dx % tw; *yOffsetPtr = dy % th; #ifdef notdef fprintf(stderr, "Tile offsets x0=%d y0=%d x=%d,y=%d sx=%d,sy=%d\n", x0, y0, x, y, *xOffsetPtr, *yOffsetPtr); #endif } static void Tile( Tk_Window tkwin, Drawable drawable, Pattern *patternPtr, Blt_Picture picture, /* Picture used as the tile. */ int x, int y, int w, int h) /* Region of destination picture to be * tiled. */ { Blt_Painter painter; int xOffset, yOffset; /* Starting upper left corner of * region. */ int tileWidth, tileHeight; /* Tile dimensions. */ int right, bottom, left, top; tileWidth = Blt_PictureWidth(picture); tileHeight = Blt_PictureHeight(picture); GetTileOffsets(tkwin, patternPtr, picture, x, y, &xOffset, &yOffset); #ifdef notdef fprintf(stderr, "tile is (xo=%d,yo=%d,tw=%d,th=%d)\n", patternPtr->xOrigin, patternPtr->yOrigin, tileWidth, tileHeight); fprintf(stderr, "region is (x=%d,y=%d,w=%d,h=%d)\n", x, y, w, h); fprintf(stderr, "starting offsets at sx=%d,sy=%d\n", xOffset, yOffset); #endif left = x; top = y; right = x + w; bottom = y + h; painter = Blt_GetPainter(tkwin, 1.0); for (y = (top - yOffset); y < bottom; y += tileHeight) { int sy, dy, ih; if (y < top) { dy = top; ih = MIN(tileHeight - yOffset, bottom - top); sy = yOffset; } else { dy = y; ih = MIN(tileHeight, bottom - y); sy = 0; } for (x = (left - xOffset); x < right; x += tileWidth) { int sx, dx, iw; if (x < left) { dx = left; iw = MIN(tileWidth - xOffset, right - left); sx = xOffset; } else { dx = x; iw = MIN(tileWidth, right - x); sx = 0; } Blt_PaintPicture(painter, drawable, picture, sx, sy, iw, ih, dx, dy, /*flags*/0); #ifdef notdef fprintf(stderr, "drawing pattern (sx=%d,sy=%d,iw=%d,ih=%d) at dx=%d,dy=%d\n", sx, sy, iw, ih, dx, dy); #endif } } } static void GetPolygonBBox(XPoint *points, int n, int *leftPtr, int *rightPtr, int *topPtr, int *bottomPtr) { XPoint *p, *pend; int left, right, bottom, top; /* Determine the bounding box of the polygon. */ left = right = points[0].x; top = bottom = points[0].y; for (p = points, pend = p + n; p < pend; p++) { if (p->x < left) { left = p->x; } if (p->x > right) { right = p->x; } if (p->y < top) { top = p->y; } if (p->y > bottom) { bottom = p->y; } } if (leftPtr != NULL) { *leftPtr = left; } if (rightPtr != NULL) { *rightPtr = right; } if (topPtr != NULL) { *topPtr = top; } if (bottomPtr != NULL) { *bottomPtr = bottom; } } /* * The following routines are directly from tk3d.c. * * tk3d.c -- * * This module provides procedures to draw borders in * the three-dimensional Motif style. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * They fix a problem in the Intersect procedure when the polygon is big (e.q * 1600x1200). The computation overflows the 32-bit integers used. */ /* *--------------------------------------------------------------------------- * * ShiftLine -- * * Given two points on a line, compute a point on a new line that is * parallel to the given line and a given distance away from it. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void ShiftLine( XPoint *p, /* First point on line. */ XPoint *q, /* Second point on line. */ int distance, /* New line is to be this many units * to the left of original line, when * looking from p1 to p2. May be * negative. */ XPoint *r) /* Store coords of point on new line * here. */ { int dx, dy, dxNeg, dyNeg; /* * The table below is used for a quick approximation in computing the new * point. An index into the table is 128 times the slope of the original * line (the slope must always be between 0 and 1). The value of the * table entry is 128 times the amount to displace the new line in y for * each unit of perpendicular distance. In other words, the table maps * from the tangent of an angle to the inverse of its cosine. If the * slope of the original line is greater than 1, then the displacement is * done in x rather than in y. */ static int shiftTable[129]; /* * Initialize the table if this is the first time it is * used. */ if (shiftTable[0] == 0) { int i; double tangent, cosine; for (i = 0; i <= 128; i++) { tangent = i/128.0; cosine = 128/cos(atan(tangent)) + .5; shiftTable[i] = (int) cosine; } } *r = *p; dx = q->x - p->x; dy = q->y - p->y; if (dy < 0) { dyNeg = 1; dy = -dy; } else { dyNeg = 0; } if (dx < 0) { dxNeg = 1; dx = -dx; } else { dxNeg = 0; } if (dy <= dx) { dy = ((distance * shiftTable[(dy<<7)/dx]) + 64) >> 7; if (!dxNeg) { dy = -dy; } r->y += dy; } else { dx = ((distance * shiftTable[(dx<<7)/dy]) + 64) >> 7; if (dyNeg) { dx = -dx; } r->x += dx; } } /* *---------------------------------------------------------------------------- * * Intersect -- * * Find the intersection point between two lines. * * Results: * Under normal conditions 0 is returned and the point at *iPtr is filled * in with the intersection between the two lines. If the two lines are * parallel, then -1 is returned and *iPtr isn't modified. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int Intersect(a1Ptr, a2Ptr, b1Ptr, b2Ptr, iPtr) XPoint *a1Ptr; /* First point of first line. */ XPoint *a2Ptr; /* Second point of first line. */ XPoint *b1Ptr; /* First point of second line. */ XPoint *b2Ptr; /* Second point of second line. */ XPoint *iPtr; /* Filled in with intersection point. */ { float dxadyb, dxbdya, dxadxb, dyadyb, p, q; /* * The code below is just a straightforward manipulation of two * equations of the form y = (x-x1)*(y2-y1)/(x2-x1) + y1 to solve * for the x-coordinate of intersection, then the y-coordinate. */ dxadyb = (a2Ptr->x - a1Ptr->x)*(b2Ptr->y - b1Ptr->y); dxbdya = (b2Ptr->x - b1Ptr->x)*(a2Ptr->y - a1Ptr->y); dxadxb = (a2Ptr->x - a1Ptr->x)*(b2Ptr->x - b1Ptr->x); dyadyb = (a2Ptr->y - a1Ptr->y)*(b2Ptr->y - b1Ptr->y); if (dxadyb == dxbdya) { return -1; } p = (a1Ptr->x*dxbdya - b1Ptr->x*dxadyb + (b1Ptr->y - a1Ptr->y)*dxadxb); q = dxbdya - dxadyb; if (q < 0) { p = -p; q = -q; } if (p < 0) { iPtr->x = - ((-p + q/2)/q); } else { iPtr->x = (p + q/2)/q; } p = (a1Ptr->y*dxadyb - b1Ptr->y*dxbdya + (b1Ptr->x - a1Ptr->x)*dyadyb); q = dxadyb - dxbdya; if (q < 0) { p = -p; q = -q; } if (p < 0) { iPtr->y = (int)(- ((-p + q/2)/q)); } else { iPtr->y = (int)((p + q/2)/q); } return 0; } /* *-------------------------------------------------------------- * * Draw3DPolygon -- * * Draw a border with 3-D appearance around the edge of a given polygon. * * Results: * None. * * Side effects: * Information is drawn in "drawable" in the form of a 3-D border * borderWidth units width wide on the left of the trajectory given by * pointPtr and n (or -borderWidth units wide on the right side, * if borderWidth is negative). * *-------------------------------------------------------------- */ static void Draw3DPolygon( Tk_Window tkwin, /* Window for which border was allocated. */ Drawable drawable, /* X window or pixmap in which to * draw. */ Tk_3DBorder border, /* Token for border to draw. */ XPoint *points, /* Array of points describing polygon. * All points must be absolute * (CoordModeOrigin). */ int n, /* Number of points at *points. */ int borderWidth, /* Width of border, measured in * pixels to the left of the polygon's * trajectory. May be negative. */ int leftRelief) /* TK_RELIEF_RAISED or * TK_RELIEF_SUNKEN: indicates how * stuff to left of trajectory looks * relative to stuff on right. */ { XPoint poly[4], b1, b2, newB1, newB2; XPoint perp, c, shift1, shift2; /* Used for handling parallel lines. */ XPoint *p, *q; GC gc; int i, lightOnLeft, dx, dy, parallel, pointsSeen; /* Handle grooves and ridges with recursive calls. */ if ((leftRelief == TK_RELIEF_GROOVE) || (leftRelief == TK_RELIEF_RIDGE)) { int halfWidth, relief; halfWidth = borderWidth / 2; relief = (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN; Draw3DPolygon(tkwin, drawable, border, points, n, halfWidth, relief); Draw3DPolygon(tkwin, drawable, border, points, n, -halfWidth, relief); return; } /* * If the polygon is already closed, drop the last point from it * (we'll close it automatically). */ p = points + (n-1); q = points; if ((p->x == q->x) && (p->y == q->y)) { n--; } /* * The loop below is executed once for each vertex in the polgon. * At the beginning of each iteration things look like this: * * poly[1] / * * / * | / * b1 * poly[0] (points[i-1]) * | | * | | * | | * | | * | | * | | *p *q * b2 *--------------------* * | * | * x------------------------- * * The job of this iteration is to do the following: * (a) Compute x (the border corner corresponding to * points[i]) and put it in poly[2]. As part of * this, compute a new b1 and b2 value for the next * side of the polygon. * (b) Put points[i] into poly[3]. * (c) Draw the polygon given by poly[0..3]. * (d) Advance poly[0], poly[1], b1, and b2 for the * next side of the polygon. */ /* * The above situation doesn't first come into existence until two points * have been processed; the first two points are used to "prime the pump", * so some parts of the processing are ommitted for these points. The * variable "pointsSeen" keeps track of the priming process; it has to be * separate from i in order to be able to ignore duplicate points in the * polygon. */ pointsSeen = 0; for (i = -2, p = points + (n-2), q = p+1; i < n; i++, p = q, q++) { if ((i == -1) || (i == n-1)) { q = points; } if ((q->x == p->x) && (q->y == p->y)) { /* * Ignore duplicate points (they'd cause core dumps in * ShiftLine calls below). */ continue; } ShiftLine(p, q, borderWidth, &newB1); newB2.x = newB1.x + (q->x - p->x); newB2.y = newB1.y + (q->y - p->y); poly[3] = *p; parallel = 0; if (pointsSeen >= 1) { parallel = Intersect(&newB1, &newB2, &b1, &b2, &poly[2]); /* * If two consecutive segments of the polygon are parallel, * then things get more complex. Consider the following * diagram: * * poly[1] * *----b1-----------b2------a * \ * \ * *---------*----------* b * poly[0] *q *p / * / * --*--------*----c * newB1 newB2 * * Instead of using x and *p for poly[2] and poly[3], as * in the original diagram, use a and b as above. Then instead * of using x and *p for the new poly[0] and poly[1], use * b and c as above. * * Do the computation in three stages: * 1. Compute a point "perp" such that the line p-perp * is perpendicular to p-q. * 2. Compute the points a and c by intersecting the lines * b1-b2 and newB1-newB2 with p-perp. * 3. Compute b by shifting p-perp to the right and * intersecting it with p-q. */ if (parallel) { perp.x = p->x + (q->y - p->y); perp.y = p->y - (q->x - p->x); Intersect(p, &perp, &b1, &b2, &poly[2]); Intersect(p, &perp, &newB1, &newB2, &c); ShiftLine(p, &perp, borderWidth, &shift1); shift2.x = shift1.x + (perp.x - p->x); shift2.y = shift1.y + (perp.y - p->y); Intersect(p, q, &shift1, &shift2, &poly[3]); } } if (pointsSeen >= 2) { dx = poly[3].x - poly[0].x; dy = poly[3].y - poly[0].y; if (dx > 0) { lightOnLeft = (dy <= dx); } else { lightOnLeft = (dy < dx); } if (lightOnLeft ^ (leftRelief == TK_RELIEF_RAISED)) { gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC); } else { gc = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC); } XFillPolygon(Tk_Display(tkwin), drawable, gc, poly, 4, Convex, CoordModeOrigin); } b1.x = newB1.x; b1.y = newB1.y; b2.x = newB2.x; b2.y = newB2.y; poly[0].x = poly[3].x; poly[0].y = poly[3].y; if (parallel) { poly[1].x = c.x; poly[1].y = c.y; } else if (pointsSeen >= 1) { poly[1].x = poly[2].x; poly[1].y = poly[2].y; } pointsSeen++; } } #ifdef notdef /* *--------------------------------------------------------------------------- * * DestroySolidPattern -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroySolidPattern(Pattern *patternPtr) { } #endif static int ConfigureSolidPattern(Tcl_Interp *interp, Pattern *corePtr, int objc, Tcl_Obj *const *objv, unsigned int flags) { SolidPattern *patternPtr = (SolidPattern *)corePtr; if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DrawSolidRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawSolidRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int x, int y, int w, int h) { SolidPattern *patternPtr = (SolidPattern *)corePtr; if ((h <= 0) || (w <= 0)) { return; } if (patternPtr->alpha == 0xFF) { Tk_Fill3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h, 0, TK_RELIEF_FLAT); } else if (patternPtr->alpha != 0x00) { Blt_Picture picture; Blt_Painter painter; Blt_Pixel color; picture = Blt_DrawableToPicture(tkwin, drawable, x, y, w, h, 1.0); if (picture == NULL) { return; /* Background is obscured. */ } color = Blt_XColorToPixel(Tk_3DBorderColor(patternPtr->border)); color.Alpha = patternPtr->alpha; Blt_PaintRectangle(picture, 0, 0, w, h, 0, 0, &color); painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x, y, 0); Blt_FreePicture(picture); } } /* *--------------------------------------------------------------------------- * * DrawSolidRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawSolidPolygon(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int n, XPoint *points) { SolidPattern *patternPtr = (SolidPattern *)corePtr; if (n < 3) { return; /* Not enough points for polygon */ } if (patternPtr->alpha == 0xFF) { XFillPolygon(Tk_Display(tkwin), drawable, Tk_3DBorderGC(tkwin, patternPtr->border, TK_3D_FLAT_GC), points, n, Complex, CoordModeOrigin); } else if (patternPtr->alpha != 0x00) { Blt_Picture picture; Blt_Painter painter; Blt_Pixel color; int x1, x2, y1, y2; int i; Point2f *vertices; int w, h; /* Get polygon bounding box. */ GetPolygonBBox(points, n, &x1, &x2, &y1, &y2); vertices = Blt_AssertMalloc(n * sizeof(Point2f)); /* Translate the polygon */ for (i = 0; i < n; i++) { vertices[i].x = (float)(points[i].x - x1); vertices[i].y = (float)(points[i].y - y1); } w = x2 - x1 + 1; h = y2 - y1 + 1; picture = Blt_DrawableToPicture(tkwin, drawable, x1, y1, w, h, 1.0); if (picture == NULL) { return; /* Background is obscured. */ } color = Blt_XColorToPixel(Tk_3DBorderColor(patternPtr->border)); color.Alpha = patternPtr->alpha; Blt_PaintPolygon(picture, n, vertices, &color); Blt_Free(vertices); painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x1, y1, 0); Blt_FreePicture(picture); } } static PatternClass solidPatternClass = { PATTERN_SOLID, solidConfigSpecs, NULL, /* DestroySolidPattern */ ConfigureSolidPattern, DrawSolidRectangle, DrawSolidPolygon }; /* *--------------------------------------------------------------------------- * * CreateSolidPattern -- * * Creates a new solid background pattern. * * Results: * Returns pointer to the new background pattern. * *--------------------------------------------------------------------------- */ static Pattern * CreateSolidPattern(void) { SolidPattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(SolidPattern)); if (patternPtr == NULL) { return NULL; } patternPtr->classPtr = &solidPatternClass; patternPtr->alpha = 0xFF; return (Pattern *)patternPtr; } #ifdef notdef /* *--------------------------------------------------------------------------- * * DestroyTilePattern -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyTilePattern(Pattern *corePtr) { } #endif /* *--------------------------------------------------------------------------- * * DrawTileRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawTileRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int x, int y, int w, int h) { TilePattern *patternPtr = (TilePattern *)corePtr; Blt_Painter painter; Tk_Window refWindow; if ((h <= 0) || (w <= 0)) { return; } if (patternPtr->tkImage == NULL) { /* No image so draw solid color background using border. */ Tk_Fill3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h, 0, TK_RELIEF_FLAT); return; } if (patternPtr->flags & BG_SCALE) { Blt_Picture picture; int refWidth, refHeight; Blt_HashEntry *hPtr; hPtr = NULL; picture = NULL; refWidth = w, refHeight = h; if (patternPtr->reference != REFERENCE_NONE) { int isNew; /* See if a picture has previously been generated. There will be a * picture for each reference window. */ hPtr = Blt_CreateHashEntry(&patternPtr->pictTable, (char *)refWindow, &isNew); if (!isNew) { picture = Blt_GetHashValue(hPtr); } refWidth = Tk_Width(refWindow); refHeight = Tk_Height(refWindow); } if ((picture == NULL) || (Blt_PictureWidth(picture) != refWidth) || (Blt_PictureHeight(picture) != refHeight)) { Blt_Picture original; int isNew; /* * Either the size of the reference window has changed or one of * the background pattern options has been reset. Resize the * picture if necessary and regenerate the background. */ if (picture == NULL) { picture = Blt_CreatePicture(refWidth, refHeight); if (hPtr != NULL) { Blt_SetHashValue(hPtr, picture); } } else { Blt_ResizePicture(picture, refWidth, refHeight); } original = ImageToPicture(patternPtr, &isNew); if (original != NULL) { Blt_ResamplePicture(picture, original, patternPtr->filter, patternPtr->filter); if (isNew) { Blt_FreePicture(original); } } } Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x, y, 0); } else { int isNew; Blt_Picture picture; picture = ImageToPicture(patternPtr, &isNew); Tile(tkwin, drawable, corePtr, picture, x, y, w, h); if (isNew) { Blt_FreePicture(picture); } } } static int ConfigureTilePattern(Tcl_Interp *interp, Pattern *corePtr, int objc, Tcl_Obj *const *objv, unsigned int flags) { TilePattern *patternPtr = (TilePattern *)corePtr; if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static PatternClass tilePatternClass = { PATTERN_TILE, tileConfigSpecs, NULL, /* DestroyTilePattern, */ ConfigureTilePattern, DrawTileRectangle, DrawSolidPolygon }; /* *--------------------------------------------------------------------------- * * CreateTilePattern -- * * Creates a new image background pattern. * * Results: * Returns pointer to the new background pattern. * *--------------------------------------------------------------------------- */ static Pattern * CreateTilePattern(void) { TilePattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(TilePattern)); if (patternPtr == NULL) { return NULL; } patternPtr->classPtr = &tilePatternClass; patternPtr->reference = REFERENCE_TOPLEVEL; return (Pattern *)patternPtr; } #ifdef notdef /* *--------------------------------------------------------------------------- * * DestroyGradientPattern -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyGradientPattern(Pattern *patternPtr) { } #endif /* *--------------------------------------------------------------------------- * * DrawGradientRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawGradientRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int x, int y, int w, int h) { GradientPattern *patternPtr = (GradientPattern *)corePtr; int sx, sy; Tk_Window refWindow; Blt_Picture picture; int refWidth, refHeight; Blt_HashEntry *hPtr; if ((h <= 0) || (w <= 0)) { return; } if (patternPtr->reference == REFERENCE_SELF) { refWindow = tkwin; } else if (patternPtr->reference == REFERENCE_TOPLEVEL) { refWindow = Blt_Toplevel(tkwin); } else if (patternPtr->reference == REFERENCE_WINDOW) { refWindow = patternPtr->refWindow; } else if (patternPtr->reference == REFERENCE_NONE) { refWindow = NULL; } else { return; /* Unknown reference window. */ } hPtr = NULL; picture = NULL; refWidth = w, refHeight = h; sx = x, sy = y; if (patternPtr->reference != REFERENCE_NONE) { int isNew; if ((patternPtr->reference == REFERENCE_WINDOW) || (patternPtr->reference == REFERENCE_TOPLEVEL)) { Tk_Window tkwin2; tkwin2 = tkwin; while ((tkwin2 != refWindow) && (tkwin2 != NULL)) { sx += Tk_X(tkwin2) + Tk_Changes(tkwin2)->border_width; sy += Tk_Y(tkwin2) + Tk_Changes(tkwin2)->border_width; tkwin2 = Tk_Parent(tkwin2); } if (tkwin2 == NULL) { /* * The window associated with the background pattern isn't an * ancestor of the current window. That means we can't use the * reference window as a guide to the size of the picture. * Simply convert to a self reference. */ patternPtr->reference = REFERENCE_SELF; refWindow = tkwin; sx = x, sy = y; } } /* See if a picture has previously been generated. There will be a * picture for each reference window. */ hPtr = Blt_CreateHashEntry(&patternPtr->pictTable, (char *)refWindow, &isNew); if (!isNew) { picture = Blt_GetHashValue(hPtr); } refWidth = Tk_Width(refWindow); refHeight = Tk_Height(refWindow); } if (patternPtr->reference == REFERENCE_SELF) { refWidth = Tk_Width(refWindow); refHeight = Tk_Height(refWindow); sx = x, sy = y; } if ((picture == NULL) || (Blt_PictureWidth(picture) != refWidth) || (Blt_PictureHeight(picture) != refHeight)) { /* * Either the size of the reference window has changed or one of the * background pattern options has been reset. Resize the picture if * necessary and regenerate the background. */ if (picture == NULL) { picture = Blt_CreatePicture(refWidth, refHeight); if (hPtr != NULL) { Blt_SetHashValue(hPtr, picture); } } else { Blt_ResizePicture(picture, refWidth, refHeight); } Blt_GradientPicture(picture, &patternPtr->high, &patternPtr->low, &patternPtr->gradient); } Tile(tkwin, drawable, corePtr, picture, x, y, w, h); #ifdef notdef painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, sx, sy, w, h, x, y, 0); #endif } /* *--------------------------------------------------------------------------- * * DrawGradientRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawGradientPolygon(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int n, XPoint *points) { GradientPattern *patternPtr = (GradientPattern *)corePtr; Tk_Window refWindow; if (patternPtr->reference == REFERENCE_SELF) { refWindow = tkwin; } else if (patternPtr->reference == REFERENCE_TOPLEVEL) { refWindow = Blt_Toplevel(tkwin); } else if (patternPtr->reference == REFERENCE_WINDOW) { refWindow = patternPtr->refWindow; } else if (patternPtr->reference == REFERENCE_NONE) { refWindow = NULL; } else { return; /* Unknown reference window. */ } if (n < 3) { return; /* Not enough points for polygon */ } if (patternPtr->alpha == 0xFF) { XFillPolygon(Tk_Display(tkwin), drawable, Tk_3DBorderGC(tkwin, patternPtr->border, TK_3D_FLAT_GC), points, n, Complex, CoordModeOrigin); } else if (patternPtr->alpha != 0x00) { Blt_Picture picture; Blt_Painter painter; Blt_Pixel color; int x1, x2, y1, y2; int i; Point2f *vertices; int w, h; /* Get polygon bounding box. */ GetPolygonBBox(points, n, &x1, &x2, &y1, &y2); vertices = Blt_AssertMalloc(n * sizeof(Point2f)); /* Translate the polygon */ for (i = 0; i < n; i++) { vertices[i].x = (float)(points[i].x - x1); vertices[i].y = (float)(points[i].y - y1); } w = x2 - x1 + 1; h = y2 - y1 + 1; picture = Blt_DrawableToPicture(tkwin, drawable, x1, y1, w, h, 1.0); if (picture == NULL) { return; /* Background is obscured. */ } color = Blt_XColorToPixel(Tk_3DBorderColor(patternPtr->border)); color.Alpha = patternPtr->alpha; Blt_PaintPolygon(picture, n, vertices, &color); Blt_Free(vertices); painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x1, y1, 0); Blt_FreePicture(picture); } } static int ConfigureGradientPattern(Tcl_Interp *interp, Pattern *corePtr, int objc, Tcl_Obj *const *objv, unsigned int flags) { GradientPattern *patternPtr = (GradientPattern *)corePtr; if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, flags) != TCL_OK) { return TCL_ERROR; } if (patternPtr->alpha != 0xFF) { patternPtr->low.Alpha = patternPtr->alpha; patternPtr->high.Alpha = patternPtr->alpha; } return TCL_OK; } static PatternClass gradientPatternClass = { PATTERN_GRADIENT, gradientConfigSpecs, NULL, /* DestroyGradientPattern, */ ConfigureGradientPattern, DrawGradientRectangle, DrawGradientPolygon, }; /* *--------------------------------------------------------------------------- * * CreateGradientPattern -- * * Creates a new solid background pattern. * * Results: * Returns pointer to the new background pattern. * *--------------------------------------------------------------------------- */ static Pattern * CreateGradientPattern(void) { GradientPattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(GradientPattern)); if (patternPtr == NULL) { return NULL; } patternPtr->classPtr = &gradientPatternClass; patternPtr->reference = REFERENCE_TOPLEVEL; patternPtr->gradient.shape = BLT_GRADIENT_SHAPE_LINEAR; patternPtr->gradient.path = BLT_GRADIENT_PATH_Y; patternPtr->gradient.jitter = FALSE; patternPtr->gradient.logScale = TRUE; patternPtr->alpha = 255; return (Pattern *)patternPtr; } #ifdef notdef /* *--------------------------------------------------------------------------- * * DestroyTexturePattern -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyTexturePattern(Pattern *patternPtr) { } #endif /* *--------------------------------------------------------------------------- * * DrawTextureRectangle -- * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawTextureRectangle(Tk_Window tkwin, Drawable drawable, Pattern *corePtr, int x, int y, int w, int h) { Blt_Painter painter; Blt_Picture picture; TexturePattern *patternPtr = (TexturePattern *)corePtr; Tk_Window refWindow; int refWidth, refHeight; Blt_HashEntry *hPtr; if ((h <= 0) || (w <= 0)) { return; } if (patternPtr->reference == REFERENCE_SELF) { refWindow = tkwin; } else if (patternPtr->reference == REFERENCE_TOPLEVEL) { refWindow = Blt_Toplevel(tkwin); } else if (patternPtr->reference == REFERENCE_WINDOW) { refWindow = patternPtr->refWindow; } else if (patternPtr->reference == REFERENCE_NONE) { refWindow = NULL; } else { return; /* Unknown reference window. */ } painter = Blt_GetPainter(tkwin, 1.0); picture = NULL; refWidth = w, refHeight = h; if (patternPtr->reference != REFERENCE_NONE) { int isNew; /* See if a picture has previously been generated. There will be a * picture for each reference window. */ hPtr = Blt_CreateHashEntry(&patternPtr->pictTable, (char *)refWindow, &isNew); if (!isNew) { picture = Blt_GetHashValue(hPtr); } refWidth = Tk_Width(refWindow); refHeight = Tk_Height(refWindow); } if ((picture == NULL) || (Blt_PictureWidth(picture) != refWidth) || (Blt_PictureHeight(picture) != refHeight)) { /* * Either the size of the reference window has changed or one of the * background pattern options has been reset. Resize the picture if * necessary and regenerate the background. */ if (picture == NULL) { picture = Blt_CreatePicture(refWidth, refHeight); if (hPtr != NULL) { Blt_SetHashValue(hPtr, picture); } } else { Blt_ResizePicture(picture, refWidth, refHeight); } Blt_TexturePicture(picture, &patternPtr->high, &patternPtr->low, patternPtr->type); } Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x, y, 0); } static int ConfigureTexturePattern(Tcl_Interp *interp, Pattern *corePtr, int objc, Tcl_Obj *const *objv, unsigned int flags) { TexturePattern *patternPtr = (TexturePattern *)corePtr; if (Blt_ConfigureWidgetFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, objc, objv, (char *)patternPtr, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static PatternClass texturePatternClass = { PATTERN_TEXTURE, textureConfigSpecs, NULL, /* DestroyTexturePattern, */ ConfigureTexturePattern, DrawTextureRectangle, DrawSolidPolygon }; /* *--------------------------------------------------------------------------- * * CreateTexturePattern -- * * Creates a new texture background pattern. * * Results: * Returns pointer to the new background pattern. * *--------------------------------------------------------------------------- */ static Pattern * CreateTexturePattern() { TexturePattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(TexturePattern)); if (patternPtr == NULL) { return NULL; } patternPtr->classPtr = &texturePatternClass; patternPtr->reference = REFERENCE_TOPLEVEL; return (Pattern *)patternPtr; } /* *--------------------------------------------------------------------------- * * CreatePattern -- * * Creates a new background pattern. * * Results: * Returns pointer to the new background pattern. * *--------------------------------------------------------------------------- */ static Pattern * CreatePattern(BackgroundInterpData *dataPtr, Tcl_Interp *interp, int type) { Pattern *patternPtr; switch (type) { case PATTERN_SOLID: patternPtr = CreateSolidPattern(); break; case PATTERN_TILE: patternPtr = CreateTilePattern(); break; case PATTERN_GRADIENT: patternPtr = CreateGradientPattern(); break; case PATTERN_TEXTURE: patternPtr = CreateTexturePattern(); break; default: abort(); break; } if (patternPtr == NULL) { Tcl_AppendResult(interp, "can't allocate background pattern", (char *)NULL); return NULL; } patternPtr->dataPtr = dataPtr; Blt_InitHashTable(&patternPtr->pictTable, BLT_ONE_WORD_KEYS); patternPtr->chain = Blt_Chain_Create(); patternPtr->tkwin = Tk_MainWindow(interp); patternPtr->display = Tk_Display(patternPtr->tkwin); return patternPtr; } /* *--------------------------------------------------------------------------- * * DestroyPattern -- * * Removes the client from the servers's list of clients and memory used * by the client token is released. When the last client is deleted, the * server is also removed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyPattern(Pattern *patternPtr) { Blt_FreeOptions(patternPtr->classPtr->configSpecs, (char *)patternPtr, patternPtr->display, 0); if (patternPtr->classPtr->destroyProc != NULL) { (*patternPtr->classPtr->destroyProc)(patternPtr); } if (patternPtr->border != NULL) { Tk_Free3DBorder(patternPtr->border); } if (patternPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&patternPtr->dataPtr->patternTable, patternPtr->hashPtr); } ClearCache(patternPtr); Blt_Chain_Destroy(patternPtr->chain); Blt_DeleteHashTable(&patternPtr->pictTable); Blt_Free(patternPtr); } /* *--------------------------------------------------------------------------- * * DestroyBackground -- * * Removes the client from the servers's list of clients and memory used * by the client token is released. When the last client is deleted, the * server is also removed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyBackground(Background *bgPtr) { Pattern *patternPtr = bgPtr->corePtr; Blt_Chain_DeleteLink(patternPtr->chain, bgPtr->link); if (Blt_Chain_GetLength(patternPtr->chain) <= 0) { DestroyPattern(patternPtr); } Blt_Free(bgPtr); } /* *--------------------------------------------------------------------------- * * GetPatternFromObj -- * * Retrieves the background pattern named by the given the Tcl_Obj. * * Results: * None. * *--------------------------------------------------------------------------- */ static int GetPatternFromObj(Tcl_Interp *interp, BackgroundInterpData *dataPtr, Tcl_Obj *objPtr, Pattern **patternPtrPtr) { Blt_HashEntry *hPtr; const char *string; string = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&dataPtr->patternTable, string); if (hPtr == NULL) { Tcl_AppendResult(dataPtr->interp, "can't find background pattern \"", string, "\"", (char *)NULL); return TCL_ERROR; } *patternPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* * bgpattern create type ?option values?... */ static int CreateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Background *bgPtr; BackgroundInterpData *dataPtr = clientData; Pattern *patternPtr; int type; if (GetPatternTypeFromObj(interp, objv[2], &type) != TCL_OK) { return TCL_ERROR; } patternPtr = CreatePattern(dataPtr, interp, type); if (patternPtr == NULL) { return TCL_ERROR; } if ((*patternPtr->classPtr->configProc)(interp, patternPtr, objc - 3, objv + 3, 0) != TCL_OK) { DestroyPattern(patternPtr); return TCL_ERROR; } /* Create the container for the pattern. */ bgPtr = Blt_Calloc(1, sizeof(Background)); if (bgPtr == NULL) { Tcl_AppendResult(interp, "can't allocate background.", (char *)NULL); DestroyPattern(patternPtr); return TCL_ERROR; } /* Generate a unique name for the pattern. */ { int isNew; char name[200]; Blt_HashEntry *hPtr; do { sprintf_s(name, 200, "bgpattern%d", dataPtr->nextId++); hPtr = Blt_CreateHashEntry(&dataPtr->patternTable, name, &isNew); } while (!isNew); assert(hPtr != NULL); assert(patternPtr != NULL); Blt_SetHashValue(hPtr, patternPtr); patternPtr->hashPtr = hPtr; patternPtr->name = Blt_GetHashKey(&dataPtr->patternTable, hPtr); } /* Add the container to the pattern's list. */ bgPtr->link = Blt_Chain_Append(patternPtr->chain, bgPtr); patternPtr->link = bgPtr->link; bgPtr->corePtr = patternPtr; Tcl_SetStringObj(Tcl_GetObjResult(interp), patternPtr->name, -1); return TCL_OK; } /* * bgpattern cget $pattern ?option?... */ static int CgetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BackgroundInterpData *dataPtr = clientData; Pattern *patternPtr; if (GetPatternFromObj(interp, dataPtr, objv[2], &patternPtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, (char *)patternPtr, objv[3], 0); } /* * bgpattern configure $pattern ?option?... */ static int ConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BackgroundInterpData *dataPtr = clientData; Pattern *patternPtr; int flags; if (GetPatternFromObj(interp, dataPtr, objv[2], &patternPtr) != TCL_OK) { return TCL_ERROR; } flags = BLT_CONFIG_OBJV_ONLY; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, (char *)patternPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, patternPtr->tkwin, patternPtr->classPtr->configSpecs, (char *)patternPtr, objv[3], flags); } else { if ((*patternPtr->classPtr->configProc)(interp, patternPtr, objc-3, objv+3, flags) != TCL_OK) { return TCL_ERROR; } ClearCache(patternPtr); NotifyClients(patternPtr); return TCL_OK; } } /* * bgpattern delete $pattern... */ static int DeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BackgroundInterpData *dataPtr = clientData; int i; for (i = 2; i < objc; i++) { Blt_HashEntry *hPtr; Pattern *patternPtr; const char *name; name = Tcl_GetString(objv[i]); hPtr = Blt_FindHashEntry(&dataPtr->patternTable, name); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find background pattern \"", name, "\"", (char *)NULL); return TCL_ERROR; } patternPtr = Blt_GetHashValue(hPtr); assert(patternPtr->hashPtr == hPtr); /* FIXME: Assuming that the first background token is always * associated with the command. Need to known when pattern was created * by bgpattern command. Does bgpattern delete #ffffff make sense? */ /* * Look up clientData from command hash table. If it's found it * represents a command? */ if (patternPtr->link != NULL) { Background *bgPtr; bgPtr = Blt_Chain_GetValue(patternPtr->link); assert(patternPtr->link == bgPtr->link); /* Take the pattern entry out of the hash table. */ Blt_DeleteHashEntry(&patternPtr->dataPtr->patternTable, patternPtr->hashPtr); patternPtr->name = NULL; patternPtr->hashPtr = NULL; patternPtr->link = NULL; /* Disconnect pattern. */ DestroyBackground(bgPtr); } } return TCL_OK; } /* * bgpattern type $pattern */ static int TypeOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BackgroundInterpData *dataPtr = clientData; Pattern *patternPtr; if (GetPatternFromObj(interp, dataPtr, objv[2], &patternPtr) != TCL_OK) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), NameOfPattern(patternPtr), -1); return TCL_OK; } static Blt_OpSpec patternOps[] = { {"cget", 2, CgetOp, 4, 4, "pattern option",}, {"configure", 2, ConfigureOp, 3, 0, "pattern ?option value?...",}, {"create", 2, CreateOp, 3, 0, "type ?args?",}, {"delete", 1, DeleteOp, 2, 0, "pattern...",}, {"type", 1, TypeOp, 3, 3, "pattern",}, }; static int nPatternOps = sizeof(patternOps) / sizeof(Blt_OpSpec); static int BgPatternCmdProc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nPatternOps, patternOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } static void BgPatternDeleteCmdProc(ClientData clientData) { BackgroundInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->patternTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pattern *patternPtr; Blt_ChainLink link, next; patternPtr = Blt_GetHashValue(hPtr); patternPtr->hashPtr = NULL; for (link = Blt_Chain_FirstLink(patternPtr->chain); link != NULL; link = next) { Background *bgPtr; next = Blt_Chain_NextLink(link); bgPtr = Blt_Chain_GetValue(link); DestroyBackground(bgPtr); } } Blt_DeleteHashTable(&dataPtr->patternTable); Tcl_DeleteAssocData(dataPtr->interp, BG_PATTERN_THREAD_KEY); } /* *--------------------------------------------------------------------------- * * GetBackgroundInterpData -- * *--------------------------------------------------------------------------- */ static BackgroundInterpData * GetBackgroundInterpData(Tcl_Interp *interp) { BackgroundInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (BackgroundInterpData *) Tcl_GetAssocData(interp, BG_PATTERN_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(BackgroundInterpData)); dataPtr->interp = interp; dataPtr->nextId = 1; /* FIXME: Create interp delete proc to teardown the hash table and * data entry. Must occur after all the widgets have been destroyed * (clients of the background pattern). */ Tcl_SetAssocData(interp, BG_PATTERN_THREAD_KEY, (Tcl_InterpDeleteProc *)NULL, dataPtr); Blt_InitHashTable(&dataPtr->patternTable, BLT_STRING_KEYS); } return dataPtr; } /*LINTLIBRARY*/ int Blt_BgPatternCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "bgpattern", BgPatternCmdProc, BgPatternDeleteCmdProc, }; cmdSpec.clientData = GetBackgroundInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* *--------------------------------------------------------------------------- * * Blt_GetBackground * * Creates a new background from the given pattern description. The * background structure returned is a token for the client to use the * background. If the pattern isn't a solid pattern (i.e. a solid color * that Tk_Get3DBorder will accept) then the pattern must already exist. * Solid patterns are the exception to this rule. This lets "-background * #ffffff" work without already having allocated a background pattern * "#ffffff". * * Results: * Returns a background pattern token. * * Side Effects: * Memory is allocated for the new token. * *--------------------------------------------------------------------------- */ Blt_Background Blt_GetBackground(Tcl_Interp *interp, Tk_Window tkwin, const char *name) { Pattern *patternPtr; BackgroundInterpData *dataPtr; Background *bgPtr; /* Pattern container. */ Blt_HashEntry *hPtr; int isNew; /* Create new token for the background. */ bgPtr = Blt_Calloc(1, sizeof(Background)); if (bgPtr == NULL) { Tcl_AppendResult(interp, "can't allocate background \"", name, "\".", (char *)NULL); return NULL; } dataPtr = GetBackgroundInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->patternTable, name, &isNew); if (isNew) { Tk_3DBorder border; /* Pattern doesn't already exist, see if it's a color name * (i.e. something that Tk_Get3DBorder will accept). */ border = Tk_Get3DBorder(interp, tkwin, name); if (border == NULL) { goto error; /* Nope. It's an error. */ } patternPtr = CreatePattern(dataPtr, interp, PATTERN_SOLID); if (patternPtr == NULL) { Tk_Free3DBorder(border); goto error; /* Can't allocate new pattern. */ } patternPtr->border = border; patternPtr->hashPtr = hPtr; patternPtr->name = Blt_GetHashKey(&dataPtr->patternTable, hPtr); patternPtr->link = NULL; Blt_SetHashValue(hPtr, patternPtr); } else { patternPtr = Blt_GetHashValue(hPtr); assert(patternPtr != NULL); } /* Add the new background to the pattern's list of clients. */ bgPtr->link = Blt_Chain_Append(patternPtr->chain, bgPtr); bgPtr->corePtr = patternPtr; return bgPtr; error: Blt_Free(bgPtr); Blt_DeleteHashEntry(&dataPtr->patternTable, hPtr); return NULL; } /* *--------------------------------------------------------------------------- * * Blt_GetBackgroundFromObj * * Retrieves a new token of a background pattern from the named background * pattern. * * Results: * Returns a background pattern token. * * Side Effects: * Memory is allocated for the new token. * *--------------------------------------------------------------------------- */ Blt_Background Blt_GetBackgroundFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { return Blt_GetBackground(interp, tkwin, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * Blt_SetBackgroundChangedProc * * Sets the routine to called when an image changes. * * Results: * None. * * Side Effects: * The designated routine will be called the next time the image * associated with the tile changes. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_SetBackgroundChangedProc( Background *bgPtr, /* Background to register callback * with. */ Blt_BackgroundChangedProc *notifyProc, /* Function to call when pattern * has changed. NULL indicates to * unset the callback.*/ ClientData clientData) { bgPtr->notifyProc = notifyProc; bgPtr->clientData = clientData; } /* *--------------------------------------------------------------------------- * * Blt_FreeBackground * * Removes the background pattern token. * * Results: * None. * * Side Effects: * Memory is freed. * *--------------------------------------------------------------------------- */ void Blt_FreeBackground(Background *bgPtr) { Pattern *patternPtr = bgPtr->corePtr; assert(patternPtr != NULL); DestroyBackground(bgPtr); } /* *--------------------------------------------------------------------------- * * Blt_GetBackgroundOrigin * * Returns the coordinates of the origin of the background pattern * referenced by the token. * * Results: * Returns the coordinates of the origin. * *--------------------------------------------------------------------------- */ void Blt_GetBackgroundOrigin(Background *bgPtr, int *xPtr, int *yPtr) { *xPtr = bgPtr->corePtr->xOrigin; *yPtr = bgPtr->corePtr->yOrigin; } /* *--------------------------------------------------------------------------- * * Blt_SetBackgroundOrigin * * Sets the origin of the background pattern referenced by the token. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_SetBackgroundOrigin(Tk_Window tkwin, Background *bgPtr, int x, int y) { Pattern *patternPtr = bgPtr->corePtr; patternPtr->xOrigin = x; patternPtr->yOrigin = y; } /* *--------------------------------------------------------------------------- * * Blt_NameOfBackground * * Returns the name of the core background pattern referenced by the * token. * * Results: * Return the name of the background pattern. * *--------------------------------------------------------------------------- */ const char * Blt_NameOfBackground(Background *bgPtr) { if (bgPtr->corePtr->name == NULL) { return ""; } return bgPtr->corePtr->name; } /* *--------------------------------------------------------------------------- * * Blt_BackgroundBorderColor * * Returns the border color of the background pattern referenced by the * token. * * Results: * Returns the XColor representing the border color of the pattern. * *--------------------------------------------------------------------------- */ XColor * Blt_BackgroundBorderColor(Background *bgPtr) { return Tk_3DBorderColor(bgPtr->corePtr->border); } /* *--------------------------------------------------------------------------- * * Blt_BackgroundBorder * * Returns the border of the background pattern referenced by the token. * * Results: * Return the border of the background pattern. * *--------------------------------------------------------------------------- */ Tk_3DBorder Blt_BackgroundBorder(Background *bgPtr) { return bgPtr->corePtr->border; } /* *--------------------------------------------------------------------------- * * Blt_DrawBackgroundRectangle * * Draws the background pattern in the designated window. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_DrawBackgroundRectangle(Tk_Window tkwin, Drawable drawable, Background *bgPtr, int x, int y, int w, int h, int borderWidth, int relief) { Tk_Draw3DRectangle(tkwin, drawable, bgPtr->corePtr->border, x, y, w, h, borderWidth, relief); } /* *--------------------------------------------------------------------------- * * Blt_FillBackgroundRectangle * * Draws the background pattern in the designated window. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_FillBackgroundRectangle(Tk_Window tkwin, Drawable drawable, Background *bgPtr, int x, int y, int w, int h, int borderWidth, int relief) { Pattern *patternPtr; if ((h < 1) || (w < 1)) { return; } patternPtr = bgPtr->corePtr; (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, x, y, w, h); if ((relief != TK_RELIEF_FLAT) && (borderWidth > 0)) { Tk_Draw3DRectangle(tkwin, drawable, patternPtr->border, x, y, w, h, borderWidth, relief); } } /* *--------------------------------------------------------------------------- * * Blt_DrawBackgroundPolygon * * Draws the background pattern in the designated window. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_DrawBackgroundPolygon(Tk_Window tkwin, Drawable drawable, Background *bgPtr, XPoint *points, int n, int borderWidth, int relief) { Pattern *patternPtr; #ifdef notdef if (n < 3) { return; } #endif patternPtr = bgPtr->corePtr; Draw3DPolygon(tkwin, drawable, patternPtr->border, points, n, borderWidth, relief); } /* *--------------------------------------------------------------------------- * * Blt_FillBackgroundPolygon * * Draws the background pattern in the designated window. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_FillBackgroundPolygon(Tk_Window tkwin, Drawable drawable, Background *bgPtr, XPoint *points, int n, int borderWidth, int relief) { Pattern *patternPtr; if (n < 3) { return; } patternPtr = bgPtr->corePtr; (*patternPtr->classPtr->drawPolygonProc)(tkwin, drawable, patternPtr, n, points); if ((relief != TK_RELIEF_FLAT) && (borderWidth != 0)) { Draw3DPolygon(tkwin, drawable, patternPtr->border, points, n, borderWidth, relief); } } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_FillPictureBackground * * Draws the background pattern in the designated picture. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_FillPictureBackground( Tk_Window tkwin, Blt_Picture dest, Background *bgPtr, int x, int y, int w, int h, int borderWidth, int relief) { Pattern *patternPtr; Blt_Picture picture; int sx, sy; patternPtr = bgPtr->corePtr; if (patternPtr->classPtr->pattern == PATTERN_BORDER) { return; } picture = GetBackgroundPicture(patternPtr, tkwin, x, y, &sx, &sy); if (picture == NULL) { return; } Blt_CopyPictureBits(dest, picture, sx, sy, w, h, x, y); } #endif /* *--------------------------------------------------------------------------- * * Blt_DrawFocusBackground * * Draws the background pattern in the designated picture. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_DrawFocusBackground(Tk_Window tkwin, Background *bgPtr, int highlightThickness, Drawable drawable) { Pattern *patternPtr = (Pattern *)bgPtr->corePtr; int w, h; w = Tk_Width(tkwin); h = Tk_Height(tkwin); /* Top */ (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, 0, 0, w, highlightThickness); /* Bottom */ (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, 0, h - highlightThickness, w, highlightThickness); /* Left */ (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, 0, highlightThickness, highlightThickness, h - 2 * highlightThickness); /* Right */ (*patternPtr->classPtr->drawRectangleProc)(tkwin, drawable, patternPtr, w - highlightThickness, highlightThickness, highlightThickness, h - 2 * highlightThickness); } #ifdef notdef static void Draw3DRectangle(Tk_Window tkwin, Drawable drawable, Background *bgPtr, int x, int y, int w, int h, int borderWidth, int relief) { int nSegments; XSegment *segments, *sp; int i; nSegments = borderWidth + borderWidth; segments = Blt_AssertMalloc(sizeof(XSegment) * nSegments); sp = segments; for (i = 0; i < borderWidth; i++) { sp->x1 = x + i; sp->y1 = y + i; sp->x2 = x + (w - 1) - i; sp->y2 = y + i; sp++; sp->x1 = x + i; sp->y1 = y + i; sp->x2 = x + i; sp->y2 = y + (h - 1) - i; sp++; } gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_LIGHT_GC); XDrawSegments(Tk_Display(tkwin), drawable, gc, segments, nSegments); sp = segments; for (i = 0; i < borderWidth; i++) { sp->x1 = x + i; sp->y1 = y + (h - 1) - i; sp->x2 = x + (w - 1) - i; sp->y2 = y + (h - 1) - i; sp++; sp->x1 = x + (w - 1 ) - i; sp->y1 = y + i; sp->x2 = x + (w - 1) - i; sp->y2 = y + (h - 1) - i; sp++; } gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_DARK_GC); XDrawSegments(Tk_Display(tkwin), drawable, gc, segments, nSegments); } #endif #ifdef notdef void Blt_SetBackgroundRegion(Background *bgPtr, int x, int y, int w, int h) { if (bgPtr->corePtr->reference == REFERENCE_NONE) { bgPtr->corePtr->refRegion.x = x; bgPtr->corePtr->refRegion.y = y; bgPtr->corePtr->refRegion.width = w; bgPtr->corePtr->refRegion.height = h; } } #endif void Blt_SetBackgroundFromBackground(Tk_Window tkwin, Background *bgPtr) { Tk_SetBackgroundFromBorder(tkwin, bgPtr->corePtr->border); } GC Blt_BackgroundBorderGC(Tk_Window tkwin, Background *bgPtr, int which) { return Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, which); } void Blt_SetBackgroundClipRegion(Tk_Window tkwin, Background *bgPtr, TkRegion rgn) { Blt_Painter painter; Display *display; GC gc; display = Tk_Display(tkwin); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_LIGHT_GC); TkSetRegion(display, gc, rgn); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_DARK_GC); TkSetRegion(display, gc, rgn); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_FLAT_GC); TkSetRegion(display, gc, rgn); painter = Blt_GetPainter(tkwin, 1.0); gc = Blt_PainterGC(painter); TkSetRegion(display, gc, rgn); } void Blt_UnsetBackgroundClipRegion(Tk_Window tkwin, Background *bgPtr) { Blt_Painter painter; Display *display; GC gc; display = Tk_Display(tkwin); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_LIGHT_GC); XSetClipMask(display, gc, None); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_DARK_GC); XSetClipMask(display, gc, None); gc = Tk_3DBorderGC(tkwin, bgPtr->corePtr->border, TK_3D_FLAT_GC); XSetClipMask(display, gc, None); painter = Blt_GetPainter(tkwin, 1.0); gc = Blt_PainterGC(painter); XSetClipMask(display, gc, None); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkWinDisplay.h����������������������������������������������������������������0000644�0001750�0001750�00000005444�11462120063�015630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkWinDisplay.h -- * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file contains excerpts from tkInt.h of the Tk library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #ifndef _TK_WIN_DISPLAY_H #define _TK_WIN_DISPLAY_H /* * The TkWinDrawable is the internal implementation of an X Drawable * (either a Window or a Pixmap). The following constants define the * valid Drawable types. */ #define TWD_BITMAP 1 #define TWD_WINDOW 2 #define TWD_WINDC 3 typedef struct { int type; HWND handle; TkWindow *winPtr; } TkWinWindow; typedef struct { int type; HBITMAP handle; Colormap colormap; int depth; } TkWinBitmap; typedef struct { int type; HDC hdc; } TkWinDC; typedef union { int type; TkWinWindow window; TkWinBitmap bitmap; TkWinDC winDC; } TkWinDrawable; /* * The TkWinDCState is used to save the state of a device context * so that it can be restored later. */ typedef struct { HPALETTE palette; int bkmode; /* This field was added in Tk * 8.3.1. Be careful that you don't * use this structure in a context * where its size is important. */ } TkWinDCState; #ifdef USE_TK_STUBS #include "tkIntPlatDecls.h" #else extern HDC TkWinGetDrawableDC(Display *display, Drawable drawable, TkWinDCState *state); extern HDC TkWinReleaseDrawableDC(Drawable drawable, HDC dc, TkWinDCState *state); extern HINSTANCE Tk_GetHINSTANCE(void); extern HWND Tk_GetHWND(Window window); extern Window Tk_AttachHWND(Tk_Window tkwin, HWND hWnd); #endif /* USE_TK_STUBS */ #endif /* _TK_WIN_DISPLAY_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTvEdit.c�������������������������������������������������������������������0000644�0001750�0001750�00000140047�11462120063�015101� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* Remember row,column where string was acquired. postcombobox x y icon?, text, row, column position, fg, bg button? based upon style. grab set SetIcon SetText SetBg SetFg SetFont SetButton */ /* * bltTvEdit.c -- * * This module implements an hierarchy widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_TREEVIEW #include "bltOp.h" #include "bltTreeView.h" #include <X11/Xutil.h> #include <X11/Xatom.h> #define TEXTBOX_FOCUS (1<<0) #define TEXTBOX_REDRAW (1<<1) static Tcl_IdleProc DisplayTextbox; static Tcl_FreeProc DestroyTextbox; static Tcl_TimerProc BlinkCursorProc; static Tcl_ObjCmdProc TextboxCmd; /* * Textbox -- * * This structure is shared by entries when their labels are * edited via the keyboard. It maintains the location of the * insertion cursor and the text selection for the editted entry. * The structure is shared since we need only one. The "focus" * entry should be the only entry receiving KeyPress/KeyRelease * events at any time. Information from the previously editted * entry is overwritten. * * Note that all the indices internally are in terms of bytes, * not characters. This is because UTF-8 strings may encode a * single character into a multi-byte sequence. To find the * respective character position * * n = Tcl_NumUtfChars(string, index); * * where n is the resulting character number. */ typedef struct { /* * This is a SNAFU in the Tk API. It assumes that only an official * Tk "toplevel" widget will ever become a toplevel window (i.e. a * window whose parent is the root window). Because under Win32, * Tk tries to use the widget record associated with the TopLevel * as a Tk frame widget, to read its menu name. What this means * is that any widget that's going to be a toplevel, must also look * like a frame. Therefore we've copied the frame widget structure * fields into the token. */ Tk_Window tkwin; /* Window that embodies the frame. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up. */ Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tcl_Command widgetCmd; /* Token for frame's widget command. */ char *className; /* Class name for widget (from configuration * option). Malloc-ed. */ int mask; /* Either FRAME or TOPLEVEL; used to select * which configuration options are valid for * widget. */ char *screenName; /* Screen on which widget is created. Non-null * only for top-levels. Malloc-ed, may be * NULL. */ char *visualName; /* Textual description of visual for window, * from -visual option. Malloc-ed, may be * NULL. */ char *colormapName; /* Textual description of colormap for window, * from -colormap option. Malloc-ed, may be * NULL. */ char *menuName; /* Textual description of menu to use for * menubar. Malloc-ed, may be NULL. */ Colormap colormap; /* If not None, identifies a colormap * allocated for this window, which must be * freed when the window is deleted. */ Tk_3DBorder border; /* Structure used to draw 3-D border and * background. NULL means no background * or border. */ int borderWidth; /* Width of 3-D border (if any). */ int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int width; /* Width to request for window. <= 0 means * don't request any size. */ int height; /* Height to request for window. <= 0 means * don't request any size. */ Tk_Cursor cursor; /* Current cursor for window, or None. */ char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ int isContainer; /* 1 means this window is a container, 0 means * that it isn't. */ char *useThis; /* If the window is embedded, this points to * the name of the window in which it is * embedded (malloc'ed). For non-embedded * windows this is NULL. */ int flags; /* Various flags; see below for * definitions. */ /* Textbox-specific fields */ TreeView *viewPtr; int x, y; /* Position of window. */ int active; /* Indicates that the frame is active. */ int exportSelection; int insertPos; /* Position of the cursor within the * array of bytes of the entry's label. */ int cursorX, cursorY; /* Position of the insertion cursor in the * textbox window. */ short int cursorWidth; /* Size of the insertion cursor symbol. */ short int cursorHeight; int selAnchor; /* Fixed end of selection. Used to extend * the selection while maintaining the * other end of the selection. */ int selFirst; /* Position of the first character in the * selection. */ int selLast; /* Position of the last character in the * selection. */ int cursorOn; /* Indicates if the cursor is displayed. */ int onTime, offTime; /* Time in milliseconds to wait before * changing the cursor from off-to-on * and on-to-off. Setting offTime to 0 makes * the cursor steady. */ Tcl_TimerToken timerToken; /* Handle for a timer event called periodically * to blink the cursor. */ /* Data-specific fields. */ TreeViewEntry *entryPtr; /* Selected entry */ TreeViewColumn *columnPtr; /* Column of entry to be edited */ TreeViewStyle *stylePtr; TreeViewIcon icon; int gap; char *string; TextLayout *textPtr; Blt_Font font; GC gc; Tk_3DBorder selBorder; int selRelief; int selBW; XColor *selFgColor; /* Text color of a selected entry. */ int buttonBW; Tk_3DBorder buttonBorder; int buttonRelief; } Textbox; #define DEF_TEXTBOX_BACKGROUND RGB_WHITE #define DEF_TEXTBOX_BORDERWIDTH STD_BORDERWIDTH #ifdef WIN32 #define DEF_TEXTBOX_BUTTON_BACKGROUND RGB_GREY85 #else #define DEF_TEXTBOX_BUTTON_BACKGROUND RGB_GREY90 #endif #define DEF_TEXTBOX_BUTTON_BORDERWIDTH "2" #define DEF_TEXTBOX_BUTTON_RELIEF "raised" #define DEF_TEXTBOX_CURSOR (char *)NULL #define DEF_TEXTBOX_EXPORT_SELECTION "no" #define DEF_TEXTBOX_NORMAL_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_TEXTBOX_NORMAL_FG_MONO STD_ACTIVE_FG_MONO #define DEF_TEXTBOX_RELIEF "solid" #define DEF_TEXTBOX_SELECT_BACKGROUND RGB_LIGHTBLUE0 #define DEF_TEXTBOX_SELECT_BG_MONO STD_SELECT_BG_MONO #define DEF_TEXTBOX_SELECT_BORDERWIDTH "1" #define DEF_TEXTBOX_SELECT_FOREGROUND STD_SELECT_FOREGROUND #define DEF_TEXTBOX_SELECT_FG_MONO STD_SELECT_FG_MONO #define DEF_TEXTBOX_SELECT_RELIEF "flat" /* Textbox Procedures */ static Blt_ConfigSpec textboxConfigSpecs[] = { {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_TEXTBOX_BACKGROUND, Blt_Offset(Textbox, border), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_TEXTBOX_CURSOR, Blt_Offset(Textbox, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_TEXTBOX_BORDERWIDTH, Blt_Offset(Textbox, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BORDER, "-buttonbackground", "buttonBackground", "ButtonBackground", DEF_TEXTBOX_BUTTON_BACKGROUND, Blt_Offset(Textbox, buttonBorder), 0}, {BLT_CONFIG_RELIEF, "-buttonrelief", "buttonRelief", "ButtonRelief", DEF_TEXTBOX_BUTTON_RELIEF, Blt_Offset(Textbox, buttonRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-buttonborderwidth", "buttonBorderWidth", "ButtonBorderWidth", DEF_TEXTBOX_BUTTON_BORDERWIDTH, Blt_Offset(Textbox, buttonBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", DEF_TEXTBOX_EXPORT_SELECTION, Blt_Offset(Textbox, exportSelection), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_TEXTBOX_RELIEF, Blt_Offset(Textbox, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BORDER, "-selectbackground", "selectBackground", "Background", DEF_TEXTBOX_SELECT_BG_MONO, Blt_Offset(Textbox, selBorder), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_BORDER, "-selectbackground", "selectBackground", "Background", DEF_TEXTBOX_SELECT_BACKGROUND, Blt_Offset(Textbox, selBorder), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_TEXTBOX_SELECT_BORDERWIDTH, Blt_Offset(Textbox, selBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_TEXTBOX_SELECT_FG_MONO, Blt_Offset(Textbox, selFgColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Foreground", DEF_TEXTBOX_SELECT_FOREGROUND, Blt_Offset(Textbox, selFgColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief", DEF_TEXTBOX_SELECT_RELIEF, Blt_Offset(Textbox, selRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Tk_LostSelProc TextboxLostSelectionProc; static Tk_SelectionProc TextboxSelectionProc; static Tk_EventProc TextboxEventProc; typedef int (TextboxCmdProc)(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Textbox *tbPtr) { if ((tbPtr->tkwin != NULL) && ((tbPtr->flags & TEXTBOX_REDRAW) == 0)) { tbPtr->flags |= TEXTBOX_REDRAW; Tcl_DoWhenIdle(DisplayTextbox, tbPtr); } } /* *--------------------------------------------------------------------------- * * BlinkCursorProc -- * * This procedure is called as a timer handler to blink the * insertion cursor off and on. * * Results: * None. * * Side effects: * The cursor gets turned on or off, redisplay gets invoked, * and this procedure reschedules itself. * *--------------------------------------------------------------------------- */ static void BlinkCursorProc(ClientData clientData) { Textbox *tbPtr = clientData; int interval; if (!(tbPtr->flags & TEXTBOX_FOCUS) || (tbPtr->offTime == 0)) { return; } if (tbPtr->active) { tbPtr->cursorOn ^= 1; interval = (tbPtr->cursorOn) ? tbPtr->onTime : tbPtr->offTime; tbPtr->timerToken = Tcl_CreateTimerHandler(interval, BlinkCursorProc, tbPtr); EventuallyRedraw(tbPtr); } } /* *--------------------------------------------------------------------------- * * TextboxEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on treeview widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void TextboxEventProc(ClientData clientData, XEvent *eventPtr) { Textbox *tbPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(tbPtr); } } else if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(tbPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { tbPtr->flags |= TEXTBOX_FOCUS; } else { tbPtr->flags &= ~TEXTBOX_FOCUS; } Tcl_DeleteTimerHandler(tbPtr->timerToken); if ((tbPtr->active) && (tbPtr->flags & TEXTBOX_FOCUS)) { tbPtr->cursorOn = TRUE; if (tbPtr->offTime != 0) { tbPtr->timerToken = Tcl_CreateTimerHandler(tbPtr->onTime, BlinkCursorProc, tbPtr); } } else { tbPtr->cursorOn = FALSE; tbPtr->timerToken = (Tcl_TimerToken) NULL; } EventuallyRedraw(tbPtr); } else if (eventPtr->type == DestroyNotify) { if (tbPtr->tkwin != NULL) { tbPtr->tkwin = NULL; } if (tbPtr->flags & TEXTBOX_REDRAW) { Tcl_CancelIdleCall(DisplayTextbox, tbPtr); } if (tbPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tbPtr->timerToken); } tbPtr->viewPtr->comboWin = NULL; Tcl_EventuallyFree(tbPtr, DestroyTextbox); } } /* *--------------------------------------------------------------------------- * * TextboxLostSelectionProc -- * * This procedure is called back by Tk when the selection is * grabbed away from a Text widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *--------------------------------------------------------------------------- */ static void TextboxLostSelectionProc(ClientData clientData) { Textbox *tbPtr = clientData; if ((tbPtr->selFirst >= 0) && (tbPtr->exportSelection)) { tbPtr->selFirst = tbPtr->selLast = -1; EventuallyRedraw(tbPtr); } } static int PointerToIndex(Textbox *tbPtr, int x, int y) { TextLayout *textPtr; Blt_FontMetrics fontMetrics; TextFragment *fragPtr; int nBytes; int i; int total; if ((tbPtr->string == NULL) || (tbPtr->string[0] == '\0')) { return 0; } x -= tbPtr->selBW; y -= tbPtr->selBW; textPtr = tbPtr->textPtr; /* Bound the y-coordinate within the window. */ if (y < 0) { y = 0; } else if (y >= textPtr->height) { y = textPtr->height - 1; } /* * Compute the line that contains the y-coordinate. * * FIXME: This assumes that segments are distributed * line-by-line. This may change in the future. */ Blt_GetFontMetrics(tbPtr->font, &fontMetrics); fragPtr = textPtr->fragments; total = 0; for (i = (y / fontMetrics.linespace); i > 0; i--) { total += fragPtr->count; fragPtr++; } if (x < 0) { nBytes = 0; } else if (x >= textPtr->width) { nBytes = fragPtr->count; } else { int newX; /* Find the character underneath the pointer. */ nBytes = Blt_MeasureChars(tbPtr->font, fragPtr->text, fragPtr->count, x, 0, &newX); if ((newX < x) && (nBytes < fragPtr->count)) { double fract; int length, charSize; const char *next; next = fragPtr->text + nBytes; #if HAVE_UTF { Tcl_UniChar dummy; length = Tcl_UtfToUniChar(next, &dummy); } #else length = 1; #endif charSize = Blt_TextWidth(tbPtr->font, next, length); fract = ((double)(x - newX) / (double)charSize); if (ROUND(fract)) { nBytes += length; } } } return nBytes + total; } static int IndexToPointer(Textbox *tbPtr) { int x, y; int maxLines; TextLayout *textPtr; Blt_FontMetrics fontMetrics; int nBytes; int sum; TextFragment *fragPtr; int i; textPtr = tbPtr->textPtr; Blt_GetFontMetrics(tbPtr->font, &fontMetrics); maxLines = (textPtr->height / fontMetrics.linespace) - 1; sum = 0; x = y = tbPtr->borderWidth; if (tbPtr->icon != NULL) { x += TreeView_IconWidth(tbPtr->icon) + 2 * tbPtr->gap; } fragPtr = textPtr->fragments; for (i = 0; i <= maxLines; i++) { /* Total the number of bytes on each line. Include newlines. */ nBytes = fragPtr->count + 1; if ((sum + nBytes) > tbPtr->insertPos) { x += Blt_TextWidth(tbPtr->font, fragPtr->text, tbPtr->insertPos - sum); break; } y += fontMetrics.linespace; sum += nBytes; fragPtr++; } tbPtr->cursorX = x; tbPtr->cursorY = y; tbPtr->cursorHeight = fontMetrics.linespace; tbPtr->cursorWidth = 3; return TCL_OK; } static void UpdateLayout(Textbox *tbPtr) { TreeView *viewPtr; TextStyle ts; int width, height; TextLayout *textPtr; int gap, offset; int iw, ih; viewPtr = tbPtr->viewPtr; offset = gap = iw = ih = 0; if (tbPtr->icon != NULL) { iw = TreeView_IconWidth(tbPtr->icon) + 4; ih = TreeView_IconHeight(tbPtr->icon); gap = tbPtr->gap; } /* The layout is based upon the current font. */ Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, tbPtr->font); textPtr = Blt_Ts_CreateLayout(tbPtr->string, -1, &ts); if (tbPtr->textPtr != NULL) { Blt_Free(tbPtr->textPtr); } tbPtr->textPtr = textPtr; width = iw + textPtr->width + gap * 2; height = MAX(ih, textPtr->height); if ((tbPtr->columnPtr == &viewPtr->treeColumn) && (!viewPtr->flatView)) { int level; level = DEPTH(viewPtr, tbPtr->entryPtr->node); offset = -(ICONWIDTH(level) + 2); } if (width <= (tbPtr->columnPtr->width + offset)) { width = (tbPtr->columnPtr->width + offset); } if (height < tbPtr->entryPtr->height) { height = tbPtr->entryPtr->height; } tbPtr->width = width + (2 * tbPtr->borderWidth); tbPtr->height = height + (2 * tbPtr->borderWidth); IndexToPointer(tbPtr); Tk_MoveResizeWindow(tbPtr->tkwin, tbPtr->x, tbPtr->y, tbPtr->width, tbPtr->height); Tk_MapWindow(tbPtr->tkwin); XRaiseWindow(tbPtr->display, Tk_WindowId(tbPtr->tkwin)); } static void InsertText(Textbox *tbPtr, char *insertText, int insertPos, int nBytes) { int oldSize, newSize; char *oldText, *newText; oldText = tbPtr->string; oldSize = (int)strlen(oldText); newSize = oldSize + nBytes + 1; newText = Blt_AssertMalloc(sizeof(char) * newSize); if (insertPos == oldSize) { /* Append */ sprintf_s(newText, newSize, "%s%s", oldText, insertText); } else if (insertPos == 0) {/* Prepend */ sprintf_s(newText, newSize, "%s%s", insertText, oldText); } else { /* Insert into existing. */ sprintf_s(newText, newSize, "%.*s%s%s", insertPos, oldText, insertText, oldText + insertPos); } /* * All indices from the start of the insertion to the end of the * string need to be updated. Simply move the indices down by the * number of characters added. */ if (tbPtr->selFirst >= insertPos) { tbPtr->selFirst += nBytes; } if (tbPtr->selLast > insertPos) { tbPtr->selLast += nBytes; } if ((tbPtr->selAnchor > insertPos) || (tbPtr->selFirst >= insertPos)) { tbPtr->selAnchor += nBytes; } if (tbPtr->string != NULL) { Blt_Free(tbPtr->string); } tbPtr->string = newText; tbPtr->insertPos = insertPos + nBytes; UpdateLayout(tbPtr); } static int DeleteText(Textbox *tbPtr, int firstPos, int lastPos) { char *oldText, *newText; int oldSize, newSize; int nBytes; char *p; oldText = tbPtr->string; if (firstPos > lastPos) { return TCL_OK; } lastPos++; /* Now is the position after the last * character. */ nBytes = lastPos - firstPos; oldSize = strlen(oldText) + 1; newSize = oldSize - nBytes + 1; newText = Blt_AssertMalloc(sizeof(char) * newSize); p = newText; if (firstPos > 0) { strncpy(p, oldText, firstPos); p += firstPos; } *p = '\0'; if (lastPos < oldSize) { strcpy(p, oldText + lastPos); } Blt_Free(oldText); /* * Since deleting characters compacts the character array, we need to * update the various character indices according. It depends where * the index occurs in relation to range of deleted characters: * * before Ignore. * within Move the index back to the start of the deletion. * after Subtract off the deleted number of characters, * since the array has been compressed by that * many characters. * */ if (tbPtr->selFirst >= firstPos) { if (tbPtr->selFirst >= lastPos) { tbPtr->selFirst -= nBytes; } else { tbPtr->selFirst = firstPos; } } if (tbPtr->selLast >= firstPos) { if (tbPtr->selLast >= lastPos) { tbPtr->selLast -= nBytes; } else { tbPtr->selLast = firstPos; } } if (tbPtr->selLast <= tbPtr->selFirst) { tbPtr->selFirst = tbPtr->selLast = -1; /* Cut away the entire * selection. */ } if (tbPtr->selAnchor >= firstPos) { if (tbPtr->selAnchor >= lastPos) { tbPtr->selAnchor -= nBytes; } else { tbPtr->selAnchor = firstPos; } } if (tbPtr->insertPos >= firstPos) { if (tbPtr->insertPos >= lastPos) { tbPtr->insertPos -= nBytes; } else { tbPtr->insertPos = firstPos; } } tbPtr->string = newText; UpdateLayout(tbPtr); EventuallyRedraw(tbPtr); return TCL_OK; } static int AcquireText(TreeView *viewPtr, Textbox *tbPtr, TreeViewEntry *entryPtr, TreeViewColumn *columnPtr) { TreeViewStyle *stylePtr; int x, y; const char *string; TreeViewIcon icon; if (columnPtr == &viewPtr->treeColumn) { int level; level = DEPTH(viewPtr, entryPtr->node); x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); #ifdef notdef x += ICONWIDTH(level) + ICONWIDTH(level + 1) + 4; #endif if (!viewPtr->flatView) { x += ICONWIDTH(level); } string = GETLABEL(entryPtr); stylePtr = columnPtr->stylePtr; icon = Blt_TreeView_GetEntryIcon(viewPtr, entryPtr); } else { TreeViewValue *valuePtr; x = SCREENX(viewPtr, columnPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); stylePtr = columnPtr->stylePtr; valuePtr = Blt_TreeView_FindValue(entryPtr, columnPtr); string = valuePtr->fmtString; if (valuePtr->stylePtr != NULL) { stylePtr = valuePtr->stylePtr; } icon = stylePtr->icon; } if (tbPtr->textPtr != NULL) { Blt_Free(tbPtr->textPtr); tbPtr->textPtr = NULL; } if (tbPtr->string != NULL) { Blt_Free(tbPtr->string); } if (string == NULL) { string = ""; } tbPtr->icon = icon; tbPtr->entryPtr = entryPtr; tbPtr->columnPtr = columnPtr; tbPtr->x = x - tbPtr->borderWidth; tbPtr->y = y - tbPtr->borderWidth; tbPtr->gap = stylePtr->gap; tbPtr->string = Blt_AssertStrdup(string); tbPtr->gc = Blt_TreeView_GetStyleGC(stylePtr); tbPtr->font = Blt_TreeView_GetStyleFont(viewPtr, stylePtr); tbPtr->selFirst = tbPtr->selLast = -1; UpdateLayout(tbPtr); Tk_MapWindow(tbPtr->tkwin); EventuallyRedraw(tbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetIndexFromObj -- * * Parse an index into an entry and return either its value * or an error. * * Results: * A standard TCL result. If all went well, then *indexPtr is * filled in with the character index (into entryPtr) corresponding to * string. The index value is guaranteed to lie between 0 and * the number of characters in the string, inclusive. If an * error occurs then an error message is left in the interp's result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int GetIndexFromObj(Tcl_Interp *interp, Textbox *tbPtr, Tcl_Obj *objPtr, int *indexPtr) { int textPos; char c; char *string; string = Tcl_GetString(objPtr); if ((tbPtr->string == NULL) || (tbPtr->string[0] == '\0')) { *indexPtr = 0; return TCL_OK; } c = string[0]; if ((c == 'a') && (strcmp(string, "anchor") == 0)) { textPos = tbPtr->selAnchor; } else if ((c == 'e') && (strcmp(string, "end") == 0)) { textPos = strlen(tbPtr->string); } else if ((c == 'i') && (strcmp(string, "insert") == 0)) { textPos = tbPtr->insertPos; } else if ((c == 'n') && (strcmp(string, "next") == 0)) { textPos = tbPtr->insertPos; if (textPos < (int)strlen(tbPtr->string)) { textPos++; } } else if ((c == 'l') && (strcmp(string, "last") == 0)) { textPos = tbPtr->insertPos; if (textPos > 0) { textPos--; } } else if ((c == 's') && (strcmp(string, "sel.first") == 0)) { if (tbPtr->selFirst < 0) { textPos = -1; } else { textPos = tbPtr->selFirst; } } else if ((c == 's') && (strcmp(string, "sel.last") == 0)) { if (tbPtr->selLast < 0) { textPos = -1; } else { textPos = tbPtr->selLast; } } else if (c == '@') { int x, y; if (Blt_GetXY(interp, tbPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } textPos = PointerToIndex(tbPtr, x, y); } else if (isdigit((int)c)) { int number; int maxChars; if (Tcl_GetIntFromObj(interp, objPtr, &number) != TCL_OK) { return TCL_ERROR; } /* Don't allow the index to point outside the label. */ maxChars = Tcl_NumUtfChars(tbPtr->string, -1); if (number < 0) { textPos = 0; } else if (number > maxChars) { textPos = strlen(tbPtr->string); } else { textPos = Tcl_UtfAtIndex(tbPtr->string, number) - tbPtr->string; } } else { if (interp != NULL) { Tcl_AppendResult(interp, "bad label index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } *indexPtr = textPos; return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectText -- * * Modify the selection by moving its un-anchored end. This * could make the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static int SelectText(Textbox *tbPtr, int textPos) { int selFirst, selLast; /* * Grab the selection if we don't own it already. */ if ((tbPtr->exportSelection) && (tbPtr->selFirst == -1)) { Tk_OwnSelection(tbPtr->tkwin, XA_PRIMARY, TextboxLostSelectionProc, tbPtr); } /* If the anchor hasn't been set yet, assume the beginning of the text*/ if (tbPtr->selAnchor < 0) { tbPtr->selAnchor = 0; } if (tbPtr->selAnchor <= textPos) { selFirst = tbPtr->selAnchor; selLast = textPos; } else { selFirst = textPos; selLast = tbPtr->selAnchor; } if ((tbPtr->selFirst != selFirst) || (tbPtr->selLast != selLast)) { tbPtr->selFirst = selFirst; tbPtr->selLast = selLast; EventuallyRedraw(tbPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextboxSelectionProc -- * * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored at * buffer. Buffer is filled (or partially filled) with a * NUL-terminated string containing part or all of the * selection, as given by offset and maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int TextboxSelectionProc( ClientData clientData, /* Information about the widget. */ int offset, /* Offset within selection of first * character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place * at buffer, not including terminating * NULL character. */ { Textbox *tbPtr = clientData; int size; size = (int)strlen(tbPtr->string + offset); /* * Return the string currently in the textbox. */ strncpy(buffer, tbPtr->string + offset, maxBytes); buffer[maxBytes] = '\0'; return (size > maxBytes) ? maxBytes : size; } static void DestroyTextbox(DestroyData data) { Textbox *tbPtr = (Textbox *)data; Blt_FreeOptions(textboxConfigSpecs, (char *)tbPtr, tbPtr->display, 0); if (tbPtr->string != NULL) { Blt_Free(tbPtr->string); } if (tbPtr->textPtr != NULL) { Blt_Free(tbPtr->textPtr); } if (tbPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tbPtr->timerToken); } if (tbPtr->tkwin != NULL) { Tk_DeleteSelHandler(tbPtr->tkwin, XA_PRIMARY, XA_STRING); } Blt_Free(tbPtr); } static void ConfigureTextbox(Textbox *tbPtr) { #ifdef notdef GC newGC; Textbox *tbPtr = viewPtr->tbPtr; XGCValues gcValues; unsigned long gcMask; /* * GC for edit window. */ gcMask = 0; newGC = Tk_GetGC(tbPtr->tkwin, gcMask, &gcValues); if (tbPtr->gc != NULL) { Tk_FreeGC(tbPtr->display, tbPtr->gc); } tbPtr->gc = newGC; tbPtr->width = tbPtr->textPtr->width + 2 * (tbPtr->borderWidth + tbPtr->highlightWidth); tbPtr->height = tbPtr->textPtr->height + 2 * (tbPtr->borderWidth + tbPtr->highlightWidth); if (Tk_IsMapped(tbPtr->tkwin)) { if ((tbPtr->height != Tk_Height(tbPtr->tkwin)) || (tbPtr->width != Tk_Width(tbPtr->tkwin))) { Tk_ResizeWindow(tbPtr->tkwin, tbPtr->width, tbPtr->height); } } #endif } int Blt_TreeView_CreateTextbox(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *columnPtr) { Tk_Window tkwin; Textbox *tbPtr; if (viewPtr->comboWin != NULL) { Tk_DestroyWindow(viewPtr->comboWin); } tkwin = Tk_CreateWindow(viewPtr->interp, viewPtr->tkwin, "edit", (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } Tk_MakeWindowExist(tkwin); Tk_SetClass(tkwin, "TreeViewEditor"); tbPtr = Blt_AssertCalloc(1, sizeof(Textbox)); tbPtr->interp = viewPtr->interp; tbPtr->display = Tk_Display(tkwin); tbPtr->tkwin = tkwin; tbPtr->borderWidth = 1; tbPtr->relief = TK_RELIEF_SOLID; tbPtr->selRelief = TK_RELIEF_FLAT; tbPtr->selBW = 1; tbPtr->selAnchor = -1; tbPtr->selFirst = tbPtr->selLast = -1; tbPtr->onTime = 600; tbPtr->active = TRUE; tbPtr->offTime = 300; tbPtr->viewPtr = viewPtr; tbPtr->buttonRelief = TK_RELIEF_SUNKEN; tbPtr->buttonBW = 1; viewPtr->comboWin = tkwin; Blt_SetWindowInstanceData(tkwin, tbPtr); Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING, TextboxSelectionProc, tbPtr, XA_STRING); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, TextboxEventProc, tbPtr); Tcl_CreateObjCommand(viewPtr->interp, Tk_PathName(tkwin), TextboxCmd, tbPtr, NULL); if (Blt_ConfigureWidgetFromObj(viewPtr->interp, tkwin, textboxConfigSpecs, 0, (Tcl_Obj **)NULL, (char *)tbPtr, 0) != TCL_OK) { Tk_DestroyWindow(tkwin); return TCL_ERROR; } AcquireText(viewPtr, tbPtr, entryPtr, columnPtr); tbPtr->insertPos = strlen(tbPtr->string); Tk_MoveResizeWindow(tkwin, tbPtr->x, tbPtr->y, tbPtr->width, tbPtr->height); Tk_MapWindow(tkwin); Tk_MakeWindowExist(tkwin); XRaiseWindow(tbPtr->display, Tk_WindowId(tkwin)); EventuallyRedraw(tbPtr); return TCL_OK; } static void DisplayTextbox(ClientData clientData) { Textbox *tbPtr = clientData; Pixmap drawable; int i; int x1, x2; int count, nChars; int selStart, selEnd, selLength; int x, y; TextFragment *fragPtr; Blt_FontMetrics fontMetrics; #ifdef notdef int buttonX, buttonY, buttonWidth, buttonHeight; #endif tbPtr->flags &= ~TEXTBOX_REDRAW; if (!Tk_IsMapped(tbPtr->tkwin)) { return; } if (tbPtr->columnPtr == NULL) { return; } drawable = Tk_GetPixmap(tbPtr->display, Tk_WindowId(tbPtr->tkwin), Tk_Width(tbPtr->tkwin), Tk_Height(tbPtr->tkwin), Tk_Depth(tbPtr->tkwin)); Blt_Fill3DRectangle(tbPtr->tkwin, drawable, tbPtr->border, 0, 0, Tk_Width(tbPtr->tkwin), Tk_Height(tbPtr->tkwin), tbPtr->borderWidth, tbPtr->relief); x = tbPtr->borderWidth + tbPtr->gap; y = tbPtr->borderWidth; #ifdef notdef buttonX = Tk_Width(tbPtr->tkwin) - (tbPtr->borderWidth + tbPtr->gap + 1); buttonY = tbPtr->borderWidth + 1; #endif if (tbPtr->icon != NULL) { y += (tbPtr->height - TreeView_IconHeight(tbPtr->icon)) / 2; Tk_RedrawImage(TreeView_IconBits(tbPtr->icon), 0, 0, TreeView_IconWidth(tbPtr->icon), TreeView_IconHeight(tbPtr->icon), drawable, x, y); x += TreeView_IconWidth(tbPtr->icon) + tbPtr->gap; } Blt_GetFontMetrics(tbPtr->font, &fontMetrics); fragPtr = tbPtr->textPtr->fragments; count = 0; y = tbPtr->borderWidth; if (tbPtr->height > fontMetrics.linespace) { y += (tbPtr->height - fontMetrics.linespace) / 2; } for (i = 0; i < tbPtr->textPtr->nFrags; i++, fragPtr++) { int leftPos, rightPos; leftPos = count; count += fragPtr->count; rightPos = count; if ((rightPos < tbPtr->selFirst) || (leftPos > tbPtr->selLast)) { /* No part of the text fragment is selected. */ Blt_DrawChars(Tk_Display(tbPtr->tkwin), drawable, tbPtr->gc, tbPtr->font, Tk_Depth(tbPtr->tkwin), 0.0f, fragPtr->text, fragPtr->count, x + fragPtr->x, y + fragPtr->y); continue; } /* * A text fragment can have up to 3 regions: * * 1. Text before the start the selection * 2. Selected text itself (drawn in a raised border) * 3. Text following the selection. */ selStart = leftPos; selEnd = rightPos; /* First adjust selected region for current line. */ if (tbPtr->selFirst > leftPos) { selStart = tbPtr->selFirst; } if (tbPtr->selLast < rightPos) { selEnd = tbPtr->selLast; } selLength = (selEnd - selStart); x1 = x; if (selStart > leftPos) { /* Normal text preceding the selection */ nChars = (selStart - leftPos); Blt_MeasureChars(tbPtr->font, tbPtr->string + leftPos, nChars, 10000, DEF_TEXT_FLAGS, &x1); x1 += x; } if (selLength > 0) { /* The selection itself */ int width; Blt_MeasureChars(tbPtr->font, fragPtr->text + selStart, selLength, 10000, DEF_TEXT_FLAGS, &x2); x2 += x; width = (x2 - x1) + 1; Blt_Fill3DRectangle(tbPtr->tkwin, drawable, tbPtr->selBorder, x1, y + fragPtr->y - fontMetrics.ascent, width, fontMetrics.linespace, tbPtr->selBW, tbPtr->selRelief); } Blt_DrawChars(Tk_Display(tbPtr->tkwin), drawable, tbPtr->gc, tbPtr->font, Tk_Depth(tbPtr->tkwin), 0.0f, fragPtr->text, fragPtr->count, fragPtr->x + x, fragPtr->y + y); } if ((tbPtr->flags & TEXTBOX_FOCUS) && (tbPtr->cursorOn)) { int left, top, right, bottom; IndexToPointer(tbPtr); left = tbPtr->cursorX + 1; right = left + 1; top = tbPtr->cursorY; if (tbPtr->height > fontMetrics.linespace) { top += (tbPtr->height - fontMetrics.linespace) / 2; } bottom = top + tbPtr->cursorHeight - 1; XDrawLine(tbPtr->display, drawable, tbPtr->gc, left, top, left, bottom); XDrawLine(tbPtr->display, drawable, tbPtr->gc, left - 1, top, right, top); XDrawLine(tbPtr->display, drawable, tbPtr->gc, left - 1, bottom, right, bottom); } Blt_Draw3DRectangle(tbPtr->tkwin, drawable, tbPtr->border, 0, 0, Tk_Width(tbPtr->tkwin), Tk_Height(tbPtr->tkwin), tbPtr->borderWidth, tbPtr->relief); XCopyArea(tbPtr->display, drawable, Tk_WindowId(tbPtr->tkwin), tbPtr->gc, 0, 0, Tk_Width(tbPtr->tkwin), Tk_Height(tbPtr->tkwin), 0, 0); Tk_FreePixmap(tbPtr->display, drawable); } /*ARGSUSED*/ static int ApplyOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; TreeView *viewPtr = tbPtr->viewPtr; TreeViewColumn *columnPtr; int valid; TreeViewStyle *stylePtr; char *newValue; entryPtr = tbPtr->entryPtr; valid = TRUE; newValue = tbPtr->string; columnPtr = tbPtr->columnPtr; stylePtr = NULL; if (columnPtr != &viewPtr->treeColumn) { TreeViewValue *valuePtr; valuePtr = Blt_TreeView_FindValue(tbPtr->entryPtr, columnPtr); if (valuePtr != NULL) { stylePtr = valuePtr->stylePtr; } } if (stylePtr == NULL) { stylePtr = columnPtr->stylePtr; } if (stylePtr->validateCmd != NULL) { Tcl_DString dString; int result; Blt_TreeView_PercentSubst(viewPtr, entryPtr, stylePtr->validateCmd, &dString); Tcl_DStringAppend(&dString, " ", -1); Tcl_DStringAppend(&dString, tbPtr->string, -1); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (result == TCL_OK) { newValue = Tcl_GetString(Tcl_GetObjResult(interp)); } else { valid = FALSE; } } if (valid) { if (columnPtr == &viewPtr->treeColumn) { if (entryPtr->labelUid != NULL) { Blt_TreeView_FreeUid(viewPtr, entryPtr->labelUid); } if (newValue == NULL) { entryPtr->labelUid = Blt_TreeView_GetUid(viewPtr, ""); } else { entryPtr->labelUid = Blt_TreeView_GetUid(viewPtr, newValue); } } else { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(newValue, -1); if (Blt_Tree_SetValueByKey(interp, viewPtr->tree, entryPtr->node, columnPtr->key, objPtr) != TCL_OK) { Tcl_DecrRefCount(objPtr); return TCL_ERROR; } entryPtr->flags |= ENTRY_DIRTY; } } if (viewPtr != NULL) { Blt_TreeView_ConfigureEntry(viewPtr, entryPtr, 0, NULL, BLT_CONFIG_OBJV_ONLY); viewPtr->flags |= (LAYOUT_PENDING | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); } Tk_DestroyWindow(tbPtr->tkwin); return TCL_OK; } /*ARGSUSED*/ static int CancelOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_DestroyWindow(tbPtr->tkwin); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, tbPtr->tkwin, textboxConfigSpecs, (char *)tbPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process a list of configuration * options database, in order to reconfigure the one of more * entries in the widget. * * .c configure option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for viewPtr; old resources get freed, if there * were any. The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, tbPtr->tkwin, textboxConfigSpecs, (char *)tbPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, tbPtr->tkwin, textboxConfigSpecs, (char *)tbPtr, objv[3], 0); } if (Blt_ConfigureWidgetFromObj(interp, tbPtr->tkwin, textboxConfigSpecs, objc - 2, objv + 2, (char *)tbPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } ConfigureTextbox(tbPtr); EventuallyRedraw(tbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Remove one or more characters from the label of an entry. * * Results: * None. * * Side effects: * Memory gets freed, the entry gets modified and (eventually) * redisplayed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int firstPos, lastPos; if (tbPtr->entryPtr == NULL) { return TCL_OK; } if (GetIndexFromObj(interp, tbPtr, objv[2], &firstPos) != TCL_OK) { return TCL_ERROR; } lastPos = firstPos; if ((objc == 4) && (GetIndexFromObj(interp, tbPtr, objv[3], &lastPos) != TCL_OK)) { return TCL_ERROR; } if (firstPos > lastPos) { return TCL_OK; } return DeleteText(tbPtr, firstPos, lastPos); } /* *--------------------------------------------------------------------------- * * IcursorOp -- * * Returns the numeric index of the given string. Indices can be * one of the following: * * "anchor" Selection anchor. * "end" End of the label. * "insert" Insertion cursor. * "sel.first" First character selected. * "sel.last" Last character selected. * @x,y Index at X-Y screen coordinate. * number Returns the same number. * * Results: * A standard TCL result. If the argument does not represent a * valid label index, then TCL_ERROR is returned and the interpreter * result will contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IcursorOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int textPos; if (GetIndexFromObj(interp, tbPtr, objv[2], &textPos) != TCL_OK) { return TCL_ERROR; } if (tbPtr->columnPtr != NULL) { tbPtr->insertPos = textPos; IndexToPointer(tbPtr); EventuallyRedraw(tbPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Returns the numeric index of the given string. Indices can be * one of the following: * * "anchor" Selection anchor. * "end" End of the label. * "insert" Insertion cursor. * "sel.first" First character selected. * "sel.last" Last character selected. * @x,y Index at X-Y screen coordinate. * number Returns the same number. * * Results: * A standard TCL result. If the argument does not represent a * valid label index, then TCL_ERROR is returned and the interpreter * result will contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int textPos; if (GetIndexFromObj(interp, tbPtr, objv[2], &textPos) != TCL_OK) { return TCL_ERROR; } if ((tbPtr->columnPtr != NULL) && (tbPtr->string != NULL)) { int nChars; nChars = Tcl_NumUtfChars(tbPtr->string, textPos); Tcl_SetIntObj(Tcl_GetObjResult(interp), nChars); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Add new characters to the label of an entry. * * Results: * None. * * Side effects: * New information gets added to tbPtr; it will be redisplayed * soon, but not necessarily immediately. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InsertOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int extra; int insertPos; char *string; if (tbPtr->entryPtr == NULL) { return TCL_ERROR; } if (GetIndexFromObj(interp, tbPtr, objv[2], &insertPos) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[3], &extra); if (extra == 0) { /* Nothing to insert. Move the cursor anyways. */ tbPtr->insertPos = insertPos; } else { InsertText(tbPtr, string, insertPos, extra); } return TCL_OK; } /*ARGSUSED*/ static int SelectionAdjustOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int textPos; int half1, half2; if (GetIndexFromObj(interp, tbPtr, objv[3], &textPos) != TCL_OK) { return TCL_ERROR; } half1 = (tbPtr->selFirst + tbPtr->selLast) / 2; half2 = (tbPtr->selFirst + tbPtr->selLast + 1) / 2; if (textPos < half1) { tbPtr->selAnchor = tbPtr->selLast; } else if (textPos > half2) { tbPtr->selAnchor = tbPtr->selFirst; } return SelectText(tbPtr, textPos); } /*ARGSUSED*/ static int SelectionClearOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (tbPtr->selFirst != -1) { tbPtr->selFirst = tbPtr->selLast = -1; EventuallyRedraw(tbPtr); } return TCL_OK; } /*ARGSUSED*/ static int SelectionFromOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int textPos; if (GetIndexFromObj(interp, tbPtr, objv[3], &textPos) != TCL_OK) { return TCL_ERROR; } tbPtr->selAnchor = textPos; return TCL_OK; } /*ARGSUSED*/ static int SelectionPresentOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (tbPtr->selFirst != -1)); return TCL_OK; } /*ARGSUSED*/ static int SelectionRangeOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int selFirst, selLast; if (GetIndexFromObj(interp, tbPtr, objv[3], &selFirst) != TCL_OK) { return TCL_ERROR; } if (GetIndexFromObj(interp, tbPtr, objv[4], &selLast) != TCL_OK) { return TCL_ERROR; } tbPtr->selAnchor = selFirst; return SelectText(tbPtr, selLast); } /*ARGSUSED*/ static int SelectionToOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int textPos; if (GetIndexFromObj(interp, tbPtr, objv[3], &textPos) != TCL_OK) { return TCL_ERROR; } return SelectText(tbPtr, textPos); } static Blt_OpSpec selectionOps[] = { {"adjust", 1, SelectionAdjustOp, 4, 4, "index",}, {"clear", 1, SelectionClearOp, 3, 3, "",}, {"from", 1, SelectionFromOp, 4, 4, "index"}, {"present", 1, SelectionPresentOp, 3, 3, ""}, {"range", 1, SelectionRangeOp, 5, 5, "start end",}, {"to", 1, SelectionToOp, 4, 4, "index"}, }; static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); /* * This procedure handles the individual options for text * selections. The selected text is designated by start and end * indices into the text pool. The selected segment has both a * anchored and unanchored ends. The following selection * operations are implemented: * * "adjust" - resets either the first or last index * of the selection. * "clear" - clears the selection. Sets first/last * indices to -1. * "from" - sets the index of the selection anchor. * "present" - return "1" if a selection is available, * "0" otherwise. * "range" - sets the first and last indices. * "to" - sets the index of the un-anchored end. */ static int SelectionOp(Textbox *tbPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TextboxCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (tbPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * TextboxCmd -- * * This procedure handles entry operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec comboOps[] = { {"apply", 1, ApplyOp, 2, 2, "",}, {"cancel", 2, CancelOp, 2, 2, "",}, {"cget", 2, CgetOp, 3, 3, "value",}, {"configure", 2, ConfigureOp, 2, 0, "?option value...?",}, {"delete", 1, DeleteOp, 3, 4, "first ?last?"}, {"icursor", 2, IcursorOp, 3, 3, "index"}, {"index", 3, IndexOp, 3, 3, "index"}, {"insert", 3, InsertOp, 4, 4, "index string"}, {"selection", 1, SelectionOp, 2, 0, "args"}, }; static int nComboOps = sizeof(comboOps) / sizeof(Blt_OpSpec); static int TextboxCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Textbox *tbPtr = clientData; TextboxCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nComboOps, comboOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (tbPtr, interp, objc, objv); return result; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMenubar.c������������������������������������������������������������������0000644�0001750�0001750�00000243303�11462120062�015271� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMenubar.c -- * * This module implements a menubar widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltImage.h" #include "bltHash.h" #include "bltBgStyle.h" #define IPAD 2 /* Internal pad between components. */ #define YPAD 2 /* External pad between components. */ #define XPAD 2 /* External pad between border and item. */ #define STATE_NORMAL (0) /* Draw widget normally. */ #define STATE_ACTIVE (1<<0) /* Widget is currently active. */ #define STATE_DISABLED (1<<1) /* Widget is disabled. */ #define STATE_POSTED (1<<2) /* Widget is currently posting its menu. */ #define STATE_MASK (STATE_ACTIVE|STATE_DISABLED|STATE_POSTED) #define REDRAW_PENDING (1<<3) /* Widget is scheduled to be redrawn. */ #define LAYOUT_PENDING (1<<4) /* Widget layout needs to be recomputed. */ #define FOCUS (1<<5) /* Widget has focus. */ #define VERTICAL (1<<6) #define ITEM_BUTTON (1<<7) #define ITEM_SEPARATOR (1<<8) #define ITEM_FILLER (1<<9) #define ITEM_MASK (ITEM_BUTTON|ITEM_SEPARATOR|ITEM_FILLER) #define DEF_ACTIVE_BG STD_ACTIVE_BACKGROUND #define DEF_ACTIVE_FG STD_ACTIVE_FOREGROUND #define DEF_BORDERWIDTH "2" #define DEF_CMD ((char *)NULL) #define DEF_CURSOR ((char *)NULL) #define DEF_DIRECTION ((char *)NULL) #define DEF_DISABLED_BG STD_DISABLED_BACKGROUND #define DEF_DISABLED_FG STD_DISABLED_FOREGROUND #define DEF_ENTRY_BG RGB_GREY90 #define DEF_FONT STD_FONT #define DEF_HEIGHT "0" #define DEF_HIGHLIGHT_BG_COLOR "" #define DEF_HIGHLIGHT_COLOR "black" #define DEF_HIGHLIGHT_WIDTH "2" #define DEF_ICON ((char *)NULL) #define DEF_IMAGE ((char *)NULL) #define DEF_JUSTIFY "left" #define DEF_MENU ((char *)NULL) #define DEF_MENU_ANCHOR "sw" #define DEF_NORMAL_BG STD_NORMAL_BACKGROUND #define DEF_NORMAL_FG STD_NORMAL_FOREGROUND #define DEF_ORIENT "horizonatal" #define DEF_POSTED_BG RGB_SKYBLUE4 #define DEF_POSTED_FG RGB_WHITE #define DEF_NORMAL_RELIEF "raised" #define DEF_POSTED_RELIEF "flat" #define DEF_ACTIVE_RELIEF "raised" #define DEF_STATE "normal" #define DEF_TAKE_FOCUS "1" #define DEF_TEXT ((char *)NULL) #define DEF_TYPE "button" #define DEF_UNDERLINE "-1" #define DEF_WIDTH "0" static Blt_OptionFreeProc FreeTextProc; static Blt_OptionParseProc ObjToTextProc; static Blt_OptionPrintProc TextToObjProc; static Blt_CustomOption textOption = { ObjToTextProc, TextToObjProc, FreeTextProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0 }; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToOrientProc; static Blt_OptionPrintProc OrientToObjProc; static Blt_CustomOption orientOption = { ObjToOrientProc, OrientToObjProc, NULL, (ClientData)0 }; static const char emptyString[] = ""; /* * Icon -- * * Since instances of the same Tk image can be displayed in different * windows with possibly different color palettes, Tk internally stores * each instance in a linked list. But if the instances are used in the * same widget and therefore use the same color palette, this adds a lot * of overhead, especially when deleting instances from the linked list. * * For the menubar widget, we never need more than a single instance * of an image, regardless of how many times it's used. Cache the image, * maintaining a reference count for each image used in the widget. It's * likely that the menubar widget will use many instances of the same * image. */ typedef struct Icon { Tk_Image tkImage; /* The Tk image being cached. */ short int width, height; /* Dimensions of the cached image. */ } *Icon; #define IconHeight(i) ((i)->height) #define IconWidth(i) ((i)->width) #define IconImage(i) ((i)->tkImage) #define IconName(i) (Blt_Image_Name((i)->tkImage)) typedef struct _Menubar Menubar; typedef struct { Menubar *mbPtr; Blt_ChainLink link; Blt_HashEntry *hashPtr; unsigned int flags; /* * The item contains optionally an icon and a text string. */ Icon icon; /* If non-NULL, image to be displayed * in item. */ Icon image; /* If non-NULL, image to be displayed * instead of text in the item. */ const char *text; /* Text string to be displayed in the * item if an image has no been * designated. */ Tk_Justify justify; /* Justification to use for text * within the item. */ short int textLen; /* # bytes of text. */ short int underline; /* Character index of character to be * underlined. If -1, no character is * underlined. */ Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not * used in the C code, but used by * keyboard traversal scripts. */ short int iconWidth, iconHeight; short int entryWidth, entryHeight; short int textWidth, textHeight; int reqWidth, reqHeight; Tcl_Obj *cmdObjPtr; /* If non-NULL, command to be executed when * this menu is posted. */ Tcl_Obj *menuObjPtr; Tcl_Obj *postCmdObjPtr; /* If non-NULL, command to be executed when * this menu is posted. */ int menuAnchor; short int inset; short int index; short int x, y, width, height; Blt_Pad xPad, yPad; } Item; struct _Menubar { Tcl_Interp *interp; /* Interpreter associated with menubar. */ Tk_Window tkwin; /* Window that embodies the menubar. If * NULL, indicates the window has been * destroyed but the data structures haven't * yet been cleaned up.*/ Tk_Window parent; /* Original parent of the menubar. */ XRectangle region; Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Command cmdToken; /* Token for widget command. */ Tk_Window floatWin; /* Toplevel window used to hold the menubar * when it's floating. */ Item *activePtr; /* Currently active item. */ Item *postedPtr; /* Currently posted item. */ Item *focusPtr; /* Item with focus. */ int reqWidth, reqHeight; int relief, postedRelief, activeRelief; int borderWidth; Blt_Background normalBg; Blt_Background activeBg; Blt_Background postedBg; Blt_Background disabledBg; Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not used in the * C code, but used by keyboard traversal * scripts. */ /* * In/Out Focus Highlight Ring: */ XColor *highlightColor; GC highlightGC; XColor *highlightBgColor; GC highlightBgGC; int highlightWidth; /* * The item contains optionally an icon and a text string. */ Icon icon; /* If non-NULL, image to be displayed in * item. */ Icon image; /* If non-NULL, image to be displayed instead * of text in the item. */ const char *text; /* Text string to be displayed in the item * if an image has no been designated. */ Blt_Font font; /* Font of text to be display in item. */ Tk_Justify justify; /* Justification to use for text within the * item. */ int textLen; /* # bytes of text. */ int underline; /* Character index of character to be * underlined. If -1, no character is * underlined. */ XColor *textNormalColor; XColor *textActiveColor; XColor *textPostedColor; XColor *textDisabledColor; GC textActiveGC; GC textNormalGC; GC textPostedGC; GC textDisabledGC; Tk_Cursor cursor; /* Current cursor for window or None. */ int inset; short int width, height; unsigned int flags; Blt_Chain chain; /* List of menu items. */ unsigned int nextId; Blt_HashTable itemTable; }; static Blt_ConfigSpec itemSpecs[] = { {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_CMD, Blt_Offset(Item, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(Item, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon", DEF_ICON, Blt_Offset(Item, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", DEF_IMAGE, Blt_Offset(Item, image), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_JUSTIFY, Blt_Offset(Item, justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-menu", "menu", "Menu", DEF_MENU, Blt_Offset(Item, menuObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-menuanchor", "menuAnchor", "MenuAnchor", DEF_MENU_ANCHOR, Blt_Offset(Item, menuAnchor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-postcommand", "postCommand", "PostCommand", DEF_CMD, Blt_Offset(Item, postCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-state", "state", "State", DEF_STATE, Blt_Offset(Item, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, Blt_Offset(Item, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-text", "text", "Text", DEF_TEXT, Blt_Offset(Item, text), 0, &textOption}, {BLT_CONFIG_INT, "-underline", "underline", "Underline", DEF_UNDERLINE, Blt_Offset(Item, underline), BLT_CONFIG_DONT_SET_DEFAULT }, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Item, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec menubarSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_ACTIVE_BG, Blt_Offset(Menubar, activeBg),0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_ACTIVE_FG, Blt_Offset(Menubar, textActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_POSTED_RELIEF, Blt_Offset(Menubar, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_NORMAL_BG, Blt_Offset(Menubar, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(Menubar, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(Menubar, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", "disabledBackground", "DisabledBackground", DEF_DISABLED_BG, Blt_Offset(Menubar, disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_DISABLED_FG, Blt_Offset(Menubar, textDisabledColor), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_FONT, Blt_Offset(Menubar, font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_NORMAL_FG, Blt_Offset(Menubar, textNormalColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(Menubar, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HIGHLIGHT_BG_COLOR, Blt_Offset(Menubar, highlightBgColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHT_COLOR, Blt_Offset(Menubar, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHT_WIDTH, Blt_Offset(Menubar, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-orient", "orient", "Orient", DEF_ORIENT, Blt_Offset(Menubar, flags), BLT_CONFIG_DONT_SET_DEFAULT, &orientOption}, {BLT_CONFIG_BACKGROUND, "-postedbackground", "postedBackground", "PostedBackground", DEF_POSTED_BG, Blt_Offset(Menubar, postedBg),0}, {BLT_CONFIG_COLOR, "-postedforeground", "postedForeground", "PostedForeground", DEF_POSTED_FG, Blt_Offset(Menubar, textPostedColor), 0}, {BLT_CONFIG_RELIEF, "-postedrelief", "postedRelief", "PostedRelief", DEF_POSTED_RELIEF, Blt_Offset(Menubar, postedRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_NORMAL_RELIEF, Blt_Offset(Menubar, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, Blt_Offset(Menubar, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Menubar, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Tk_EventProc FloatEventProc; static Tk_GeomRequestProc FloatGeometryProc; static Tk_GeomLostSlaveProc FloatCustodyProc; static Tk_GeomMgr menubarMgrInfo = { (char *)"menubar", /* Name of geometry manager used by winfo */ FloatGeometryProc, /* Procedure to for new geometry requests */ FloatCustodyProc, /* Procedure when window is taken away */ }; static Tcl_IdleProc DisplayMenubar; static Tcl_FreeProc DestroyMenubar; static Tcl_FreeProc FreeFloatProc; static Tk_EventProc MenubarEventProc; static Tcl_ObjCmdProc MenubarInstCmdProc; static Tcl_CmdDeleteProc MenubarInstCmdDeletedProc; /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the menubar display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Menubar *mbPtr) { if ((mbPtr->tkwin != NULL) && ((mbPtr->flags & REDRAW_PENDING) == 0)) { mbPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayMenubar, mbPtr); } } static void FreeIcon(Menubar *mbPtr, Icon icon) { Tk_FreeImage(IconImage(icon)); Blt_Free(icon); } #ifdef notdef static char * GetInterpResult(Tcl_Interp *interp) { #define MAX_ERR_MSG 1023 static char mesg[MAX_ERR_MSG+1]; strncpy(mesg, Tcl_GetStringResult(interp), MAX_ERR_MSG); mesg[MAX_ERR_MSG] = '\0'; return mesg; } #endif /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Menubar *mbPtr = clientData; mbPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(mbPtr); } static int GetIconFromObj(Tcl_Interp *interp, Menubar *mbPtr, Tcl_Obj *objPtr, Icon *iconPtr) { Tk_Image tkImage; const char *iconName; iconName = Tcl_GetString(objPtr); if (iconName[0] == '\0') { *iconPtr = NULL; return TCL_OK; } tkImage = Tk_GetImage(interp, mbPtr->tkwin, iconName, IconChangedProc, mbPtr); if (tkImage != NULL) { struct Icon *ip; int width, height; ip = Blt_AssertMalloc(sizeof(struct Icon)); Tk_SizeOfImage(tkImage, &width, &height); ip->tkImage = tkImage; ip->width = width; ip->height = height; *iconPtr = ip; return TCL_OK; } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * MenubarEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * menubar widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void MenubarEventProc(ClientData clientData, XEvent *eventPtr) { Menubar *mbPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(mbPtr); } } else if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(mbPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { mbPtr->flags |= FOCUS; } else { mbPtr->flags &= ~FOCUS; } EventuallyRedraw(mbPtr); } else if (eventPtr->type == DestroyNotify) { if (mbPtr->tkwin != NULL) { mbPtr->tkwin = NULL; } if (mbPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayMenubar, mbPtr); } Tcl_EventuallyFree(mbPtr, DestroyMenubar); } } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Converts the string representing a state into a bitflag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); const char *string; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "disabled") == 0) { flag = STATE_DISABLED; } else if (strcmp(string, "normal") == 0) { flag = STATE_NORMAL; } else if (strcmp(string, "active") == 0) { Menubar *mbPtr; mbPtr = itemPtr->mbPtr; if (mbPtr->activePtr != NULL) { mbPtr->activePtr->flags &= ~STATE_ACTIVE; } flag = STATE_ACTIVE; mbPtr->activePtr = itemPtr; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } if (itemPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } *flagsPtr &= ~STATE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); const char *string; switch (state & STATE_MASK) { case STATE_NORMAL: string = "normal"; break; case STATE_ACTIVE: string = "active"; break; case STATE_POSTED: string = "posted"; break; case STATE_DISABLED: string = "disabled"; break; default: string = Blt_Itoa(state & STATE_MASK); break; } return Tcl_NewStringObj(string, -1); } /*ARGSUSED*/ static void FreeIconProc(ClientData clientData, Display *display, char *widgRec, int offset) { Icon icon = *(Icon *)(widgRec + offset); if (icon != NULL) { Menubar *mbPtr = (Menubar *)widgRec; FreeIcon(mbPtr, icon); } } /* *--------------------------------------------------------------------------- * * ObjToOrientProc -- * * Converts the string representing a state into a bitflag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToOrientProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Menubar *mbPtr = (Menubar *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); const char *string; int length; string = Tcl_GetString(objPtr); length = strlen(string); if (strncmp(string, "vertical", length) == 0) { *flagsPtr |= VERTICAL; } else if (strncmp(string, "horizontal", length) == 0) { *flagsPtr &= ~VERTICAL; } else { Tcl_AppendResult(interp, "bad orientation \"", string, "\": must be vertical or horizontal", (char *)NULL); return TCL_ERROR; } mbPtr->flags |= LAYOUT_PENDING; return TCL_OK; } /* *--------------------------------------------------------------------------- * * OrientToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * OrientToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int mask = *(unsigned int *)(widgRec + offset); const char *string; string = (mask & VERTICAL) ? "vertical" : "horizontal"; return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Convert a image into a hashed icon. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Menubar *mbPtr = (Menubar *)widgRec; Icon *iconPtr = (Icon *)(widgRec + offset); Icon icon; if (GetIconFromObj(interp, mbPtr, objPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (*iconPtr != NULL) { FreeIcon(mbPtr, *iconPtr); } *iconPtr = icon; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon icon = *(Icon *)(widgRec + offset); Tcl_Obj *objPtr; if (icon == NULL) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr = Tcl_NewStringObj(Blt_Image_Name(IconImage(icon)), -1); } return objPtr; } /*ARGSUSED*/ static void FreeTextProc(ClientData clientData, Display *display, char *widgRec, int offset) { Item *itemPtr = (Item *)(widgRec); if (itemPtr->hashPtr != NULL) { Menubar *mbPtr = itemPtr->mbPtr; Blt_DeleteHashEntry(&mbPtr->itemTable, itemPtr->hashPtr); itemPtr->hashPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToTextProc -- * * Save the text and add the item to the text hashtable. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTextProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); Menubar *mbPtr; int isNew; Blt_HashEntry *hPtr; const char *string; mbPtr = itemPtr->mbPtr; string = Tcl_GetString(objPtr); hPtr = Blt_CreateHashEntry(&mbPtr->itemTable, string, &isNew); if (!isNew) { Tcl_AppendResult(interp, "item \"", string, "\" already exists in ", Tk_PathName(mbPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (itemPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&mbPtr->itemTable, itemPtr->hashPtr); } itemPtr->hashPtr = hPtr; itemPtr->text = Blt_GetHashKey(&mbPtr->itemTable, hPtr); Blt_SetHashValue(hPtr, itemPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextToObjProc -- * * Return the text of the item. * * Results: * The text is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TextToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); return Tcl_NewStringObj(itemPtr->text, -1); } static INLINE Item * FirstItem(Menubar *mbPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_BUTTON|STATE_DISABLED)) == ITEM_BUTTON) { return itemPtr; } } return NULL; } static INLINE Item * LastItem(Menubar *mbPtr) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(mbPtr->chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_BUTTON|STATE_DISABLED)) == ITEM_BUTTON) { return itemPtr; } } return NULL; } static Item * NextItem(Item *itemPtr) { Blt_ChainLink link; if (itemPtr == NULL) { return NULL; } for (link = Blt_Chain_NextLink(itemPtr->link); link != NULL; link = Blt_Chain_NextLink(link)) { itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_BUTTON|STATE_DISABLED)) == ITEM_BUTTON) { return itemPtr; } } return NULL; } static INLINE Item * PrevItem(Item *itemPtr) { Blt_ChainLink link; if (itemPtr == NULL) { return NULL; } for (link = Blt_Chain_PrevLink(itemPtr->link); link != NULL; link = Blt_Chain_PrevLink(link)) { itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_BUTTON|STATE_DISABLED)) == ITEM_BUTTON) { return itemPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * SearchForItem -- * * Performs a binary search for the item at the given y-offset in world * coordinates. The range of items is specified by menu indices (high * and low). The item must be (visible) in the viewport. * * Results: * Returns 0 if no item is found, other the index of the item (menu * indices start from 1). * *--------------------------------------------------------------------------- */ static Item * SearchForItem(Menubar *mbPtr, int x, int y) { Item *itemPtr; for (itemPtr = FirstItem(mbPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if ((x >= itemPtr->x) && (x < (itemPtr->x + itemPtr->width))) { return itemPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * NearestItem -- * * Find the item closest to the x-y screen coordinate given. The * item must be (visible) in the viewport. * * Results: * Returns the closest item. If selectOne is set, then always returns * an item (unless the menu is empty). Otherwise, NULL is returned is * the pointer is not over an item. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Item * NearestItem(Menubar *mbPtr, int x, int y, int selectOne) { Item *itemPtr; if ((x < 0) || (x >= Tk_Width(mbPtr->tkwin)) || (y < 0) || (y >= Tk_Height(mbPtr->tkwin))) { return NULL; /* Screen coordinates are outside of menu. */ } itemPtr = SearchForItem(mbPtr, x, y); if (itemPtr == NULL) { if (!selectOne) { return NULL; } if (x < mbPtr->borderWidth) { return FirstItem(mbPtr); } return LastItem(mbPtr); } return itemPtr; } /* *--------------------------------------------------------------------------- * H * C * L * P * max of icon/text/image/item * P * L * C * H * * |H|C|L|P| icon |P| text/image |P|L|B| item |B|C|H| * * H = highlight thickness * C = menubar borderwidth * L = label borderwidth * P = pad * I = icon * T = text or image *--------------------------------------------------------------------------- */ static void ComputeItemGeometry(Item *itemPtr) { Menubar *mbPtr = itemPtr->mbPtr; /* Determine the height of the item. It's the maximum height of all * it's components: icon, label, and item. */ itemPtr->iconWidth = itemPtr->iconHeight = 0; itemPtr->entryWidth = itemPtr->entryHeight = 0; itemPtr->textWidth = itemPtr->textHeight = 0; itemPtr->inset = mbPtr->highlightWidth; if (itemPtr->icon != NULL) { itemPtr->iconWidth = IconWidth(itemPtr->icon); itemPtr->iconHeight = IconHeight(itemPtr->icon); } itemPtr->entryWidth += itemPtr->iconWidth; if (itemPtr->entryHeight < itemPtr->iconHeight) { itemPtr->entryHeight = itemPtr->iconHeight; } if (itemPtr->image != NULL) { itemPtr->textWidth = IconWidth(itemPtr->image); itemPtr->textHeight = IconHeight(itemPtr->image); } else if (itemPtr->text != NULL) { unsigned int w, h; Blt_GetTextExtents(mbPtr->font, 0, itemPtr->text, itemPtr->textLen, &w, &h); itemPtr->textWidth = w + 2 * IPAD; itemPtr->textHeight = h; } itemPtr->entryWidth += itemPtr->textWidth + IPAD; if (itemPtr->iconWidth == 0) { itemPtr->entryWidth += IPAD; } if (itemPtr->entryHeight < itemPtr->textHeight) { itemPtr->entryHeight = itemPtr->textHeight; } itemPtr->entryHeight += 2 * YPAD; itemPtr->entryWidth += 2 * XPAD; itemPtr->width = itemPtr->entryWidth + 2 * itemPtr->inset; itemPtr->height = itemPtr->entryHeight + 2 * itemPtr->inset; itemPtr->flags &= ~LAYOUT_PENDING; } static void ComputeMenubarGeometry(Menubar *mbPtr) { Blt_ChainLink link; int maxWidth, maxHeight; int totalWidth, totalHeight; mbPtr->width = mbPtr->height = 0; mbPtr->inset = mbPtr->borderWidth + mbPtr->highlightWidth; if (mbPtr->flags & LAYOUT_PENDING) { for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); ComputeItemGeometry(itemPtr); } } totalWidth = totalHeight = 0; maxWidth = maxHeight = 0; for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); ComputeItemGeometry(itemPtr); if (itemPtr->width > maxWidth) { maxWidth = itemPtr->width; } if (itemPtr->height > maxHeight) { maxHeight = itemPtr->height; } totalWidth += itemPtr->width + IPAD; totalHeight += itemPtr->height + IPAD; } if (mbPtr->flags & VERTICAL) { mbPtr->height = totalHeight; mbPtr->width = maxWidth; } else { mbPtr->height = totalHeight; mbPtr->width = maxWidth; } if (mbPtr->reqHeight > 0) { mbPtr->width = mbPtr->reqHeight; } if (mbPtr->reqWidth > 0) { mbPtr->height = mbPtr->reqWidth; } mbPtr->height += 2 * mbPtr->inset; mbPtr->width += 2 * mbPtr->inset; if ((mbPtr->width != Tk_ReqWidth(mbPtr->tkwin)) || (mbPtr->height != Tk_ReqHeight(mbPtr->tkwin))) { Tk_GeometryRequest(mbPtr->tkwin, mbPtr->width, mbPtr->height); } mbPtr->flags &= ~LAYOUT_PENDING; } static int ConfigureMenubar(Tcl_Interp *interp, Menubar *mbPtr, int objc, Tcl_Obj *const *objv, int flags) { unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, mbPtr->tkwin, menubarSpecs, objc, objv, (char *)mbPtr, flags) != TCL_OK) { return TCL_ERROR; } gcMask = GCForeground | GCFont; gcValues.font = Blt_FontId(mbPtr->font); /* Text GCs. */ gcValues.foreground = mbPtr->textNormalColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); if (mbPtr->textNormalGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textNormalGC); } mbPtr->textNormalGC = newGC; gcValues.foreground = mbPtr->textActiveColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); if (mbPtr->textActiveGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textActiveGC); } mbPtr->textActiveGC = newGC; gcValues.foreground = mbPtr->textPostedColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); if (mbPtr->textPostedGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textPostedGC); } mbPtr->textPostedGC = newGC; gcValues.foreground = mbPtr->textDisabledColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); if (mbPtr->textDisabledGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textDisabledGC); } mbPtr->textDisabledGC = newGC; /* Focus highlight GCs */ gcMask = GCForeground; gcValues.foreground = mbPtr->highlightColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); if (mbPtr->highlightGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->highlightGC); } mbPtr->highlightGC = newGC; if (mbPtr->highlightBgColor != NULL) { gcValues.foreground = mbPtr->highlightBgColor->pixel; newGC = Tk_GetGC(mbPtr->tkwin, gcMask, &gcValues); } else { newGC = NULL; } if (mbPtr->highlightBgGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->highlightBgGC); } mbPtr->highlightBgGC = newGC; ComputeMenubarGeometry(mbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyMenubar -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyMenubar(DestroyData dataPtr) /* Pointer to the widget record. */ { Menubar *mbPtr = (Menubar *)dataPtr; iconOption.clientData = mbPtr; Blt_FreeOptions(menubarSpecs, (char *)mbPtr, mbPtr->display, 0); if (mbPtr->textNormalGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textNormalGC); } if (mbPtr->textActiveGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textActiveGC); } if (mbPtr->textDisabledGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textDisabledGC); } if (mbPtr->textPostedGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->textPostedGC); } if (mbPtr->highlightGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->highlightGC); } if (mbPtr->highlightBgGC != NULL) { Tk_FreeGC(mbPtr->display, mbPtr->highlightBgGC); } Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->cmdToken); Blt_Free(mbPtr); } /* *--------------------------------------------------------------------------- * * NewMenubar -- * *--------------------------------------------------------------------------- */ static Menubar * NewMenubar(Tcl_Interp *interp, Tk_Window tkwin) { Menubar *mbPtr; mbPtr = Blt_AssertCalloc(1, sizeof(Menubar)); mbPtr->borderWidth = 1; mbPtr->display = Tk_Display(tkwin); mbPtr->flags = (LAYOUT_PENDING | STATE_NORMAL); mbPtr->highlightWidth = 2; mbPtr->interp = interp; mbPtr->relief = TK_RELIEF_RAISED; mbPtr->postedRelief = TK_RELIEF_FLAT; mbPtr->activeRelief = TK_RELIEF_RAISED; mbPtr->tkwin = tkwin; mbPtr->parent = Tk_Parent(tkwin); return mbPtr; } static INLINE Item * FindItemByIndex(Menubar *mbPtr, long index) { Blt_ChainLink link; if ((index < 1) || (index > Blt_Chain_GetLength(mbPtr->chain))) { return NULL; } link = Blt_Chain_GetNthLink(mbPtr->chain, index - 1); return Blt_Chain_GetValue(link); } static INLINE Item * FindItemByLabel(Menubar *mbPtr, const char *string) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&mbPtr->itemTable, string); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * GetItemFromObj -- * * Gets the item associated the given index or label. Converts a * string representing a item index into an item pointer. The index * may be in one of the following forms: * * number Item at index in the list of items. * @x,y Item closest to the specified X-Y screen coordinates. * "active" Item where mouse pointer is located. * "posted" Item is the currently posted cascade item. * "next" Next item from the focus item. * "previous" Previous item from the focus item. * "end" Last item. * "none" No item. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via itemPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetItemFromObj(Tcl_Interp *interp, Menubar *mbPtr, Tcl_Obj *objPtr, Item **itemPtrPtr) { Item *itemPtr; const char *string; char c; long lval; if (mbPtr->flags & LAYOUT_PENDING) { ComputeMenubarGeometry(mbPtr); } string = Tcl_GetString(objPtr); c = string[0]; itemPtr = NULL; if (c == '\0') { itemPtr = NULL; } else if (Tcl_GetLongFromObj(NULL, objPtr, &lval) == TCL_OK) { if (lval < 0) { itemPtr = NULL; } else { itemPtr = FindItemByIndex(mbPtr, (long)lval); } if (itemPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item: bad index \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } else if ((c == 'a') && (strcmp(string, "active") == 0)) { itemPtr = mbPtr->activePtr; } else if ((c == 'n') && (strcmp(string, "next") == 0)) { itemPtr = NextItem(mbPtr->activePtr); if (itemPtr == NULL) { itemPtr = mbPtr->activePtr; } } else if ((c == 'p') && (strcmp(string, "item_previous") == 0)) { itemPtr = PrevItem(mbPtr->activePtr); if (itemPtr == NULL) { itemPtr = mbPtr->activePtr; } } else if ((c == 'e') && (strcmp(string, "end") == 0)) { itemPtr = LastItem(mbPtr); } else if ((c == 'f') && (strcmp(string, "first") == 0)) { itemPtr = FirstItem(mbPtr); } else if ((c == 'l') && (strcmp(string, "last") == 0)) { itemPtr = LastItem(mbPtr); } else if ((c == 'n') && (strcmp(string, "none") == 0)) { itemPtr = NULL; } else if (c == '@') { int x, y; if (Blt_GetXY(mbPtr->interp, mbPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } itemPtr = NearestItem(mbPtr, x, y, TRUE); if ((itemPtr != NULL) && (itemPtr->flags & STATE_DISABLED)) { itemPtr = NextItem(itemPtr); } } else { itemPtr = FindItemByLabel(mbPtr, string); if (itemPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item \"", string, "\" in \"", Tk_PathName(mbPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } } *itemPtrPtr = itemPtr; return TCL_OK; } static void RenumberItems(Menubar *mbPtr) { int count = 0; Blt_ChainLink link; for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); itemPtr->index = count; count++; } } static Item * NewItem(Menubar *mbPtr, int type) { Item *itemPtr; Blt_ChainLink link; Blt_HashEntry *hPtr; int isNew; link = Blt_Chain_AllocLink(sizeof(Item)); itemPtr = Blt_Chain_GetValue(link); memset(itemPtr, 0, sizeof(Item)); do { char string[200]; sprintf(string, "item%d", mbPtr->nextId++); hPtr = Blt_CreateHashEntry(&mbPtr->itemTable, string, &isNew); } while (!isNew); itemPtr->hashPtr = hPtr; itemPtr->text = Blt_GetHashKey(&mbPtr->itemTable, hPtr); itemPtr->textLen = strlen(itemPtr->text); itemPtr->mbPtr = mbPtr; itemPtr->flags = STATE_NORMAL | type; itemPtr->link = link; itemPtr->index = Blt_Chain_GetLength(mbPtr->chain) + 1; itemPtr->menuAnchor = TK_ANCHOR_SW; itemPtr->underline = -1; return itemPtr; } /* *--------------------------------------------------------------------------- * * DestroyItem -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyItem(Item *itemPtr) { Menubar *mbPtr = itemPtr->mbPtr; iconOption.clientData = mbPtr; Blt_FreeOptions(itemSpecs, (char *)itemPtr, mbPtr->display, 0); Blt_Chain_DeleteLink(mbPtr->chain, itemPtr->link); } static int ConfigureItem(Tcl_Interp *interp, Item *itemPtr, int objc, Tcl_Obj *const *objv, int flags) { Menubar *mbPtr; mbPtr = itemPtr->mbPtr; iconOption.clientData = mbPtr; if (Blt_ConfigureWidgetFromObj(interp, mbPtr->tkwin, itemSpecs, objc, objv, (char *)itemPtr, flags) != TCL_OK) { return TCL_ERROR; } ComputeItemGeometry(itemPtr); return TCL_OK; } static int PostMenu(Item *itemPtr) { const char *menuName; Tk_Window menuWin; Menubar *mbPtr; Tcl_Interp *interp; mbPtr = itemPtr->mbPtr; interp = itemPtr->mbPtr->interp; if (itemPtr->menuObjPtr == NULL) { return TCL_OK; } if ((itemPtr->flags & (ITEM_BUTTON|STATE_DISABLED|STATE_POSTED)) != ITEM_BUTTON) { return TCL_OK; } menuName = Tcl_GetString(itemPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, mbPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != mbPtr->tkwin) { Tcl_AppendResult(interp, "can't post \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(mbPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (itemPtr->postCmdObjPtr) { int result; Tcl_Preserve(itemPtr); Tcl_IncrRefCount(itemPtr->postCmdObjPtr); result = Tcl_EvalObjEx(interp, itemPtr->postCmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(itemPtr->postCmdObjPtr); Tcl_Release(itemPtr); if (result != TCL_OK) { return TCL_ERROR; } } if (Tk_IsMapped(mbPtr->tkwin)) { Tcl_Obj *cmd[2]; int result; Tcl_Preserve(mbPtr); cmd[0] = itemPtr->menuObjPtr; cmd[1] = Tcl_NewStringObj("post", 4); Tcl_IncrRefCount(cmd[0]); Tcl_IncrRefCount(cmd[1]); result = Tcl_EvalObjv(interp, 2, cmd, 0); Tcl_DecrRefCount(cmd[1]); Tcl_DecrRefCount(cmd[0]); Tcl_Release(mbPtr); if (result == TCL_OK) { itemPtr->flags &= ~STATE_MASK; itemPtr->flags |= STATE_POSTED; mbPtr->postedPtr = itemPtr; } EventuallyRedraw(mbPtr); return result; } return TCL_OK; } static int UnpostMenu(Item *itemPtr) { const char *menuName; Tk_Window menuWin; Menubar *mbPtr; Tcl_Interp *interp; if ((itemPtr->menuObjPtr == NULL) || ((itemPtr->flags & STATE_POSTED) == 0)) { return TCL_OK; } mbPtr = itemPtr->mbPtr; interp = mbPtr->interp; itemPtr->flags &= ~STATE_MASK; itemPtr->flags |= STATE_NORMAL; menuName = Tcl_GetString(itemPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, mbPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != mbPtr->tkwin) { Tcl_AppendResult(interp, "can't unpost \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(mbPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (Tk_IsMapped(menuWin)) { Tk_UnmapWindow(menuWin); } return TCL_OK; } static void DestroyFloat(Menubar *mbPtr) { if (mbPtr->floatWin != NULL) { if (mbPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayMenubar, mbPtr); } Tk_DeleteEventHandler(mbPtr->floatWin, StructureNotifyMask, FloatEventProc, mbPtr); if (mbPtr->tkwin != NULL) { Blt_RelinkWindow(mbPtr->tkwin, mbPtr->parent, 0, 0); Tk_MoveResizeWindow(mbPtr->tkwin, mbPtr->region.x, mbPtr->region.y, mbPtr->region.width, mbPtr->region.height); if (!Tk_IsMapped(mbPtr->tkwin)) { Tk_MapWindow(mbPtr->tkwin); } } Tk_DestroyWindow(mbPtr->floatWin); mbPtr->floatWin = NULL; } } static void FreeFloatProc(DestroyData dataPtr) { Menubar *mbPtr = (Menubar *)dataPtr; DestroyFloat(mbPtr); } /* *--------------------------------------------------------------------------- * * FloatEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * the floating menubar. * * Results: * None. * * Side effects: * When the tearoff gets deleted, internal structures get * cleaned up. When it gets resized or exposed, it's redisplayed. * *--------------------------------------------------------------------------- */ static void FloatEventProc(ClientData clientData, XEvent *eventPtr) { Menubar *mbPtr = clientData; if ((mbPtr == NULL) || (mbPtr->tkwin == NULL) || (mbPtr->floatWin == NULL)) { return; } switch (eventPtr->type) { case Expose: if (eventPtr->xexpose.count == 0) { EventuallyRedraw(mbPtr); } break; case ConfigureNotify: EventuallyRedraw(mbPtr); break; case DestroyNotify: DestroyFloat(mbPtr); mbPtr->floatWin = NULL; break; } } /* *--------------------------------------------------------------------------- * * FloatCustodyProc -- * * This procedure is invoked when the menubar has been stolen by another * geometry manager. The information and memory associated with the * window is released. * * Results: * None. * * Side effects: * Arranges for the widget formerly associated with the menubar to * have its layout re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void FloatCustodyProc(ClientData clientData, Tk_Window tkwin) { Menubar *mbPtr = clientData; if ((mbPtr == NULL) || (mbPtr->tkwin == NULL)) { return; } if (mbPtr->floatWin != NULL) { Tcl_EventuallyFree(mbPtr, FreeFloatProc); } /* * Mark the floating dock as deleted by dereferencing the Tk window * pointer. */ if (mbPtr->tkwin != NULL) { if (Tk_IsMapped(mbPtr->tkwin)) { mbPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(mbPtr); } Tk_DeleteEventHandler(mbPtr->floatWin, StructureNotifyMask, FloatEventProc, mbPtr); mbPtr->floatWin = NULL; } } /* *--------------------------------------------------------------------------- * * FloatGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for the floating * menubar managed by the widget. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to be repacked and * drawn at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void FloatGeometryProc(ClientData clientData, Tk_Window tkwin) { Menubar *mbPtr = clientData; if ((mbPtr == NULL) || (mbPtr->tkwin == NULL)) { fprintf(stderr, "%s: line %d \"tkwin is null\"", __FILE__, __LINE__); return; } mbPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(mbPtr); } static void FloatMenubar(ClientData clientData) { Menubar *mbPtr = clientData; Blt_RelinkWindow(mbPtr->tkwin, mbPtr->floatWin, 0, 0); Tk_MapWindow(mbPtr->tkwin); } static int CreateFloat(Menubar *mbPtr, const char *name) { Tk_Window tkwin; int width, height; tkwin = Tk_CreateWindowFromPath(mbPtr->interp, mbPtr->tkwin, name, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } mbPtr->floatWin = tkwin; if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } Tk_SetClass(tkwin, "MenubarDock"); Tk_CreateEventHandler(tkwin, (ExposureMask | StructureNotifyMask), FloatEventProc, mbPtr); if (Tk_WindowId(mbPtr->tkwin) == None) { Tk_MakeWindowExist(mbPtr->tkwin); } Tk_ManageGeometry(mbPtr->tkwin, &menubarMgrInfo, mbPtr); mbPtr->region.height = height = Tk_Height(mbPtr->tkwin); mbPtr->region.width = width = Tk_Width(mbPtr->tkwin); mbPtr->region.x = Tk_X(mbPtr->tkwin); mbPtr->region.y = Tk_Y(mbPtr->tkwin); if (width < 2) { width = (mbPtr->reqWidth > 0) ? mbPtr->reqWidth : Tk_ReqWidth(mbPtr->tkwin); } width += 2 * Tk_Changes(mbPtr->tkwin)->border_width; width += 2 * mbPtr->inset; if (height < 2) { height = (mbPtr->reqHeight > 0) ? mbPtr->reqHeight : Tk_ReqHeight(mbPtr->tkwin); } height += 2 * Tk_Changes(mbPtr->tkwin)->border_width; height += 2 * mbPtr->inset; Tk_GeometryRequest(tkwin, width, height); /* Tk_MoveWindow(mbPtr->tkwin, 0, 0); */ Tcl_SetStringObj(Tcl_GetObjResult(mbPtr->interp), Tk_PathName(tkwin), -1); Tk_UnmapWindow(mbPtr->tkwin); #ifdef WIN32 FloatMenubar(mbPtr); #else Tcl_DoWhenIdle(FloatMenubar, mbPtr); #endif return TCL_OK; } /* *--------------------------------------------------------------------------- * * DrawLabel -- * * Draws the text associated with the label. This is used when the * widget acts like a standard label. * * Results: * Nothing. * *--------------------------------------------------------------------------- */ static void DrawLabel(Item *itemPtr, Drawable drawable, int x, int y, int w, int h) { if (itemPtr->image != NULL) { int iw, ih; iw = MIN(w, itemPtr->textWidth) - IPAD; ih = MIN(h, itemPtr->textHeight); Tk_RedrawImage(IconImage(itemPtr->image), 0, 0, iw, ih, drawable, x + IPAD, y); } else { GC gc; Menubar *mbPtr; TextLayout *layoutPtr; TextStyle ts; mbPtr = itemPtr->mbPtr; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, mbPtr->font); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetJustify(ts, itemPtr->justify); Blt_Ts_SetUnderline(ts, itemPtr->underline); layoutPtr = Blt_Ts_CreateLayout(itemPtr->text, -1, &ts); if (itemPtr->flags & STATE_POSTED) { gc = mbPtr->textPostedGC; } else if (itemPtr->flags & STATE_ACTIVE) { gc = mbPtr->textActiveGC; } else if (itemPtr->flags & STATE_DISABLED) { gc = mbPtr->textDisabledGC; } else { gc = mbPtr->textNormalGC; } Blt_DrawLayout(mbPtr->tkwin, drawable, gc, mbPtr->font, Tk_Depth(mbPtr->tkwin), 0.0f, x + IPAD, y, layoutPtr, w); Blt_Free(layoutPtr); } } static void DrawSeparator(Item *itemPtr, Drawable drawable, int x, int y, int w, int h) { Menubar *mbPtr = itemPtr->mbPtr; XPoint points[2]; Tk_3DBorder border; points[1].x = points[0].x = x + w / 2; points[0].y = y + YPAD; points[1].y = h - 2 * YPAD; border = Blt_BackgroundBorder(mbPtr->normalBg); Tk_Draw3DPolygon(mbPtr->tkwin, drawable, border, points, 2, 1, TK_RELIEF_SUNKEN); } static void DrawItem(Item *itemPtr, Drawable drawable) { Menubar *mbPtr = itemPtr->mbPtr; Blt_Background bg; int relief; int x, y, w, h; if (itemPtr->flags & ITEM_FILLER) { return; /* No need to do anything. */ } x = itemPtr->x; y = itemPtr->y; w = itemPtr->width; h = mbPtr->height; if (itemPtr->flags & ITEM_SEPARATOR) { DrawSeparator(itemPtr, drawable, x, y, w, h); return; } /* Menubar background (just inside of focus highlight ring). */ if (itemPtr->flags & STATE_POSTED) { bg = mbPtr->postedBg; } else if (itemPtr->flags & STATE_ACTIVE) { bg = mbPtr->activeBg; } else if (itemPtr->flags & STATE_DISABLED) { bg = mbPtr->disabledBg; } else { bg = mbPtr->normalBg; } Blt_FillBackgroundRectangle(mbPtr->tkwin, drawable, bg, 0, 0, itemPtr->width, mbPtr->height, mbPtr->borderWidth, TK_RELIEF_FLAT); /* Label: includes icon and text. */ if (h > itemPtr->entryHeight) { y += (h - itemPtr->entryHeight) / 2; } x += XPAD; /* Draw Icon. */ if (itemPtr->icon != NULL) { int ix, iy, iw, ih; ix = x; iy = y; if (itemPtr->iconHeight < itemPtr->entryHeight) { iy += (itemPtr->entryHeight - itemPtr->iconHeight) / 2; } iw = MIN(w, itemPtr->iconWidth); ih = MIN(h, itemPtr->iconHeight); Tk_RedrawImage(IconImage(itemPtr->icon), 0, 0, iw, ih, drawable, ix, iy); x += itemPtr->iconWidth + IPAD; w -= itemPtr->iconWidth + IPAD; } if ((w > 0) && (h > 0)) { int tx, ty, tw, th; tx = x + IPAD; ty = y; if (itemPtr->entryHeight > itemPtr->textHeight) { ty += (itemPtr->entryHeight - itemPtr->textHeight) / 2; } tw = MIN(w, itemPtr->textWidth); th = MIN(h, itemPtr->textHeight); DrawLabel(itemPtr, drawable, tx, ty, tw, th); } /* Draw focus highlight ring. */ if (mbPtr->highlightWidth > 0) { GC gc; if (itemPtr->flags & FOCUS) { gc = mbPtr->highlightGC; } else { gc = mbPtr->highlightBgGC; } if (gc == NULL) { Blt_DrawFocusBackground(mbPtr->tkwin, bg, mbPtr->highlightWidth, drawable); } else { Tk_DrawFocusHighlight(mbPtr->tkwin, gc, mbPtr->highlightWidth, drawable); } } if (itemPtr->flags & STATE_POSTED) { relief = mbPtr->postedRelief; } else if (itemPtr->flags & STATE_ACTIVE) { relief = mbPtr->activeRelief; } else { relief = mbPtr->relief; } if (relief != TK_RELIEF_FLAT) { Blt_DrawBackgroundRectangle(mbPtr->tkwin, drawable, bg, mbPtr->highlightWidth, mbPtr->highlightWidth, itemPtr->width - 2 * mbPtr->highlightWidth, itemPtr->height - 2 * mbPtr->highlightWidth, mbPtr->borderWidth, relief); } } static void DrawItems(Menubar *mbPtr, Drawable drawable) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; int x, y, w, h; itemPtr = Blt_Chain_GetValue(link); x = y = itemPtr->inset; w = itemPtr->width - (2 * mbPtr->inset); h = itemPtr->height - (2 * mbPtr->inset); DrawItem(itemPtr, drawable); x += itemPtr->width + IPAD; } } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activates the designated button. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar activate $item * *--------------------------------------------------------------------------- */ static int ActivateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if ((itemPtr == NULL) || ((itemPtr->flags & ITEM_BUTTON) == 0)) { goto done; } if (itemPtr->flags & (STATE_POSTED|STATE_DISABLED)) { return TCL_OK; /* Writing is currently disabled. */ } itemPtr->flags |= STATE_ACTIVE; done: mbPtr->activePtr->flags &= ~STATE_ACTIVE; mbPtr->activePtr = itemPtr; EventuallyRedraw(mbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Appends a new item to the menubar. * * Results: * NULL is always returned. * * .mbar add ?type? -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int AddOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; int length, type; char c; const char *string; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; type = ITEM_BUTTON; if ((c == 'b') && (strncmp(string, "button", length) == 0)) { type = ITEM_BUTTON; objc--, objv--; } else if ((c == 's') && (strncmp(string, "separator", length) == 0)) { type = ITEM_SEPARATOR; objc--, objv--; } else if ((c == 's') && (strncmp(string, "filler", length) == 0)) { type = ITEM_FILLER; objc--, objv--; } itemPtr = NewItem(mbPtr, type); if (ConfigureItem(interp, itemPtr, objc - 2, objv + 2, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } EventuallyRedraw(mbPtr); Blt_Chain_LinkAfter(mbPtr->chain, itemPtr->link, NULL); Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .menubar cget option * *--------------------------------------------------------------------------- */ static int CgetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; iconOption.clientData = mbPtr; return Blt_ConfigureValueFromObj(interp, mbPtr->tkwin, menubarSpecs, (char *)mbPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .menubar configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Menubar *mbPtr = clientData; iconOption.clientData = mbPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, menubarSpecs, (char *)mbPtr, (Tcl_Obj *)NULL, BLT_CONFIG_OBJV_ONLY); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, menubarSpecs, (char *)mbPtr, objv[2], BLT_CONFIG_OBJV_ONLY); } Tcl_Preserve(mbPtr); result = ConfigureMenubar(interp, mbPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(mbPtr); if (result == TCL_ERROR) { return TCL_ERROR; } mbPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(mbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DockOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .menubar dock * .menubar undock *--------------------------------------------------------------------------- */ static int DockOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; if (mbPtr->floatWin == NULL) { CreateFloat(mbPtr, "dock"); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemCgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar item cget $button option * *--------------------------------------------------------------------------- */ static int ItemCgetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; if (GetItemFromObj(interp, mbPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } iconOption.clientData = mbPtr; return Blt_ConfigureValueFromObj(interp, mbPtr->tkwin, itemSpecs, (char *)itemPtr, objv[4], BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * ItemConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar item configure $button ?option value?... * *--------------------------------------------------------------------------- */ static int ItemConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; int result; if (GetItemFromObj(interp, mbPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } iconOption.clientData = mbPtr; if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, itemSpecs, (char *)itemPtr, (Tcl_Obj *)NULL, BLT_CONFIG_OBJV_ONLY); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, itemSpecs, (char *)itemPtr, objv[4], BLT_CONFIG_OBJV_ONLY); } Tcl_Preserve(itemPtr); result = ConfigureItem(interp, itemPtr, objc - 4, objv + 4, BLT_CONFIG_OBJV_ONLY); Tcl_Release(itemPtr); if (result == TCL_ERROR) { return TCL_ERROR; } mbPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(mbPtr); return TCL_OK; } static Blt_OpSpec itemOps[] = { {"cget", 2, ItemCgetOp, 5, 5, "item option",}, {"configure", 2, ItemConfigureOp, 4, 0, "item ?option value?...",}, }; static int nItemOps = sizeof(itemOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * ItemOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int ItemOp( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { Tcl_ObjCmdProc *proc; Menubar *mbPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nItemOps, itemOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(mbPtr); result = (*proc) (clientData, interp, objc, objv); Tcl_Release(mbPtr); return result; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes one or more item from the menubar. * * Results: * A standard TCL result. * * Side effects: * The menubar is redrawn. * * .mbar delete but1 but2 but3 but4... * *--------------------------------------------------------------------------- */ static int DeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; int i; for (i = 2; i < objc; i++) { Item *itemPtr; if (GetItemFromObj(interp, mbPtr, objv[i], &itemPtr) != TCL_OK) { RenumberItems(mbPtr); EventuallyRedraw(mbPtr); return TCL_ERROR; } if (itemPtr != NULL) { DestroyItem(itemPtr); } } RenumberItems(mbPtr); EventuallyRedraw(mbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Returns the index of the designated item or -1 if it doesn't * exist. * * Results: * A standard TCL result. * * Side effects: * The menubar is redrawn. * * .mbar index $item * *--------------------------------------------------------------------------- */ static int IndexOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; int index; index = -1; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr != NULL) { index = itemPtr->index; } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Inserts a new item into the menubar. * * Results: * A standard TCL result. * * Side effects: * The menubar is redrawn. * * .mbar insert ?type? -1 -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int InsertOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink before; Item *itemPtr; Menubar *mbPtr = clientData; char c; const char *string; int length, type; long insertPos; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; type = ITEM_BUTTON; if ((c == 'b') && (strncmp(string, "button", length) == 0)) { type = ITEM_BUTTON; objc--, objv--; } else if ((c == 's') && (strncmp(string, "separator", length) == 0)) { type = ITEM_SEPARATOR; objc--, objv--; } else if ((c == 's') && (strncmp(string, "filler", length) == 0)) { type = ITEM_FILLER; objc--, objv--; } if (Blt_GetPositionFromObj(interp, objv[2], &insertPos) != TCL_OK) { return TCL_ERROR; } if ((insertPos == -1) || (insertPos >= Blt_Chain_GetLength(mbPtr->chain))) { before = NULL; /* Insert at end of list. */ } else { before = Blt_Chain_GetNthLink(mbPtr->chain, insertPos); } itemPtr = NewItem(mbPtr, type); if (ConfigureItem(interp, itemPtr, objc - 3, objv + 3, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } EventuallyRedraw(mbPtr); Blt_Chain_LinkBefore(mbPtr->chain, itemPtr->link, before); RenumberItems(mbPtr); Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar invoke $item * *--------------------------------------------------------------------------- */ static int InvokeOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; int result; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if ((itemPtr == NULL) || ((itemPtr->flags & (STATE_DISABLED|ITEM_BUTTON)) != ITEM_BUTTON)) { return TCL_OK; /* Item is currently disabled. */ } result = TCL_OK; if (itemPtr->cmdObjPtr != NULL) { Tcl_Preserve(itemPtr); Tcl_IncrRefCount(itemPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, itemPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(itemPtr->cmdObjPtr); Tcl_Release(itemPtr); } return result; } /* *--------------------------------------------------------------------------- * * MoveOp -- * * Moves a item to a new location. * * .mbar move but1 after|before but2 * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MoveOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr, *b2Ptr; char c; const char *string; int isBefore; int length; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } string = Tcl_GetStringFromObj(objv[3], &length); c = string[0]; if ((c == 'b') && (strncmp(string, "before", length) == 0)) { isBefore = TRUE; } else if ((c == 'a') && (strncmp(string, "after", length) == 0)) { isBefore = FALSE; } else { Tcl_AppendResult(interp, "bad key word \"", string, "\": should be \"after\" or \"before\"", (char *)NULL); return TCL_ERROR; } if (GetItemFromObj(interp, mbPtr, objv[4], &b2Ptr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } Blt_Chain_UnlinkLink(mbPtr->chain, itemPtr->link); if (isBefore) { Blt_Chain_LinkBefore(mbPtr->chain, itemPtr->link, b2Ptr->link); } else { Blt_Chain_LinkAfter(mbPtr->chain, itemPtr->link, b2Ptr->link); } RenumberItems(mbPtr); EventuallyRedraw(mbPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Lists the names of the items in the menubar. * * Results: * A standard TCL result. * * Side effects: * The menubar is redrawn. * * .mbar names ?pattern? * *--------------------------------------------------------------------------- */ static int NamesOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Tcl_Obj *listObjPtr; int i; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 2; i < objc; i++) { const char *pattern; Blt_ChainLink link; pattern = Tcl_GetString(objv[i]); for (link = Blt_Chain_FirstLink(mbPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; Tcl_Obj *objPtr; itemPtr = Blt_Chain_GetValue(link); if (Tcl_StringMatch(itemPtr->text, pattern)) { if (itemPtr->text == emptyString) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(itemPtr->text, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostOp -- * * Posts the menu associated with this item. * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar post $item * *--------------------------------------------------------------------------- */ static int PostOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { if (mbPtr->postedPtr != NULL) { UnpostMenu(mbPtr->postedPtr); } return TCL_OK; } if ((itemPtr->flags & (STATE_POSTED|STATE_DISABLED|ITEM_BUTTON)) != ITEM_BUTTON) { return TCL_OK; /* Item's menu is currently posted or entry * is disabled. */ } if (itemPtr->menuObjPtr == NULL) { return TCL_OK; } if (mbPtr->postedPtr != NULL) { UnpostMenu(mbPtr->postedPtr); } if (itemPtr != NULL) { PostMenu(itemPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UndockOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .menubar dock * .menubar undock *--------------------------------------------------------------------------- */ static int UndockOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; if (mbPtr->floatWin != NULL) { DestroyFloat(mbPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnpostOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .mbar unpost $item * *--------------------------------------------------------------------------- */ static int UnpostOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Menubar *mbPtr = clientData; Item *itemPtr; if (GetItemFromObj(interp, mbPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } if ((itemPtr->flags & (STATE_POSTED|STATE_DISABLED|ITEM_BUTTON)) != ITEM_BUTTON) { return TCL_OK; /* Item's menu is currently posted or entry * is disabled. */ } if (itemPtr->menuObjPtr == NULL) { return TCL_OK; } UnpostMenu(itemPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MenubarCmd -- * * This procedure is invoked to process the "menubar" command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec menubarOps[] = { {"activate", 2, ActivateOp, 3, 3, "item",}, {"add", 2, AddOp, 3, 3, "?option value...?",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"delete", 2, DeleteOp, 2, 0, "item ?item?",}, {"dock", 2, DockOp, 2, 2, "",}, {"index", 3, IndexOp, 3, 3, "item",}, {"insert", 3, InsertOp, 2, 2, "position ?option value...?",}, {"invoke", 3, InvokeOp, 3, 3, "item",}, {"item", 3, ItemOp, 2, 0, "args",}, {"move", 1, MoveOp, 2, 2, "position item ?item?",}, {"names", 1, NamesOp, 2, 0, "?pattern...?",}, {"post", 1, PostOp, 3, 3, "item",}, {"undock", 3, UndockOp, 2, 2, "",}, {"unpost", 3, UnpostOp, 3, 3, "item",}, }; static int nMenubarOps = sizeof(menubarOps) / sizeof(Blt_OpSpec); static int MenubarInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { Tcl_ObjCmdProc *proc; Menubar *mbPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nMenubarOps, menubarOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(mbPtr); result = (*proc) (clientData, interp, objc, objv); Tcl_Release(mbPtr); return result; } /* *--------------------------------------------------------------------------- * * MenubarInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void MenubarInstCmdDeletedProc(ClientData clientData) { Menubar *mbPtr = clientData; /* Pointer to widget record. */ if (mbPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = mbPtr->tkwin; mbPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * MenubarCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int MenubarCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Menubar *mbPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, set up procs and initialize various * bindings for the widget. If the proc doesn't already exist, source it * from "$blt_library/menubar.tcl". We've deferred sourcing this file * until now so that the user could reset the variable $blt_library from * within her script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Menubar::PostMenu", &cmdInfo)) { static char cmd[] = "source [file join $blt_library menubar.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } mbPtr = NewMenubar(interp, tkwin); #define EVENT_MASK (ExposureMask|StructureNotifyMask|FocusChangeMask) Tk_CreateEventHandler(tkwin, EVENT_MASK, MenubarEventProc, mbPtr); Tk_SetClass(tkwin, "Menubar"); mbPtr->cmdToken = Tcl_CreateObjCommand(interp, path, MenubarInstCmdProc, mbPtr, MenubarInstCmdDeletedProc); Blt_SetWindowInstanceData(tkwin, mbPtr); if (ConfigureMenubar(interp, mbPtr, objc-2, objv+2, 0) != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_MenubarInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "menubar", MenubarCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #ifdef notdef /* *--------------------------------------------------------------------------- * * DrawLabel -- * * Draws the text associated with the label. This is used when the * widget acts like a standard label. * * Results: * Nothing. * *--------------------------------------------------------------------------- */ static void DrawLabel(Menubar *mbPtr, Drawable drawable, int x, int y, int w, int h) { if (mbPtr->image != NULL) { int imgWidth, imgHeight; imgWidth = MIN(w, itemPtr->textWidth) - IPAD; imgHeight = MIN(h, itemPtr->textHeight); Tk_RedrawImage(IconImage(mbPtr->image), 0, 0, imgWidth, imgHeight, drawable, x + IPAD, y); } else { TextStyle ts; TextLayout *layoutPtr; GC gc; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, mbPtr->font); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetJustify(ts, mbPtr->justify); Blt_Ts_SetUnderline(ts, mbPtr->underline); layoutPtr = Blt_Ts_CreateLayout(mbPtr->text, mbPtr->textLen, &ts); if (mbPtr->flags & STATE_POSTED) { gc = mbPtr->textPostedGC; } else if (mbPtr->flags & STATE_ACTIVE) { gc = mbPtr->textActiveGC; } else if (mbPtr->flags & STATE_DISABLED) { gc = mbPtr->textDisabledGC; } else { gc = mbPtr->textNormalGC; } Blt_DrawLayout(mbPtr->tkwin, drawable, gc, mbPtr->font, Tk_Depth(mbPtr->tkwin), 0.0f, x + IPAD, y, layoutPtr, w); Blt_Free(layoutPtr); } } #endif static void DrawMenubar(Menubar *mbPtr, Drawable drawable) { Blt_Background bg; int x, y; int w, h; /* Menubar background (just inside of focus highlight ring). */ if (mbPtr->flags & STATE_POSTED) { bg = mbPtr->postedBg; } else if (mbPtr->flags & STATE_ACTIVE) { bg = mbPtr->activeBg; } else if (mbPtr->flags & STATE_DISABLED) { bg = mbPtr->disabledBg; } else { bg = mbPtr->normalBg; } Blt_FillBackgroundRectangle(mbPtr->tkwin, drawable, bg, 0, 0, Tk_Width(mbPtr->tkwin), Tk_Height(mbPtr->tkwin), mbPtr->borderWidth, TK_RELIEF_FLAT); x = y = mbPtr->inset; w = Tk_Width(mbPtr->tkwin) - (2 * mbPtr->inset); h = Tk_Height(mbPtr->tkwin) - (2 * mbPtr->inset); DrawItems(mbPtr, drawable); } /* *--------------------------------------------------------------------------- * * DisplayMenubar -- * * This procedure is invoked to display a menubar widget. * * Results: * None. * * Side effects: * Commands are output to X to display the menubar. * *--------------------------------------------------------------------------- */ static void DisplayMenubar(ClientData clientData) { Menubar *mbPtr = clientData; Pixmap drawable; int ww, wh; /* Window width and height. */ mbPtr->flags &= ~REDRAW_PENDING; if (mbPtr->tkwin == NULL) { return; /* Window destroyed (should not get here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayMenubar(%s)\n", Tk_PathName(mbPtr->tkwin)); #endif ww = Tk_Width(mbPtr->tkwin); wh = Tk_Height(mbPtr->tkwin); if ((ww <= 1) || (wh <=1)) { /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (mbPtr->flags & LAYOUT_PENDING) { ComputeMenubarGeometry(mbPtr); } if (!Tk_IsMapped(mbPtr->tkwin)) { /* The widget's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the menubar's new layout. */ return; } /* * Create a pixmap the size of the window for double buffering. */ drawable = Tk_GetPixmap(mbPtr->display, Tk_WindowId(mbPtr->tkwin), ww, wh, Tk_Depth(mbPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif DrawMenubar(mbPtr, drawable); XCopyArea(mbPtr->display, drawable, Tk_WindowId(mbPtr->tkwin), mbPtr->textNormalGC, 0, 0, ww, wh, 0, 0); Tk_FreePixmap(mbPtr->display, drawable); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltOldConfig.c����������������������������������������������������������������0000644�0001750�0001750�00000020363�11462120062�015543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltOldConfig.c -- * * This module implements custom configuration options for the BLT * toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <stdarg.h> static int StringToPad(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *string, char *widgRec, int offset); static char *PadToString(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); Tk_CustomOption bltPadOption = { StringToPad, PadToString, (ClientData)0 }; static int StringToDistance(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *string, char *widgRec, int flags); static char *DistanceToString(ClientData, Tk_Window, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); Tk_CustomOption bltDistanceOption = { StringToDistance, DistanceToString, (ClientData)PIXELS_NNEG }; /* *--------------------------------------------------------------------------- * * Blt_GetPixels -- * * Like Tk_GetPixels, but checks for negative, zero. * Can be PIXELS_POS, PIXELS_NNEG, or PIXELS_ANY. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ int Blt_GetPixels(Tcl_Interp *interp, Tk_Window tkwin, const char *string, int check, int *valuePtr) { int length; if (Tk_GetPixels(interp, tkwin, string, &length) != TCL_OK) { return TCL_ERROR; } if (length >= SHRT_MAX) { Tcl_AppendResult(interp, "bad distance \"", string, "\": ", "too big to represent", (char *)NULL); return TCL_ERROR; } switch (check) { case PIXELS_NNEG: if (length < 0) { Tcl_AppendResult(interp, "bad distance \"", string, "\": ", "can't be negative", (char *)NULL); return TCL_ERROR; } break; case PIXELS_POS: if (length <= 0) { Tcl_AppendResult(interp, "bad distance \"", string, "\": ", "must be positive", (char *)NULL); return TCL_ERROR; } break; case PIXELS_ANY: break; } *valuePtr = length; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StringToDistance -- * * Like TK_CONFIG_PIXELS, but adds an extra check for negative * values. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StringToDistance( ClientData clientData, /* Indicated how to check distance */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window */ const char *string, /* Pixel value string */ char *widgRec, /* Widget record */ int offset) /* Offset of pixel size in record */ { int *valuePtr = (int *)(widgRec + offset); return Blt_GetPixels(interp, tkwin, string, (unsigned long)clientData, valuePtr); } /* *--------------------------------------------------------------------------- * * DistanceToString -- * * Returns the string representing the positive pixel size. * * Results: * The pixel size string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static char * DistanceToString( ClientData clientData, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget structure record */ int offset, /* Offset in widget record */ Tcl_FreeProc **freeProcPtr) /* Not used. */ { int value = *(int *)(widgRec + offset); char *result; result = Blt_AssertStrdup(Blt_Itoa(value)); *freeProcPtr = (Tcl_FreeProc *)Blt_Free; return result; } /* *--------------------------------------------------------------------------- * * StringToPad -- * * Convert a string into two pad values. The string may be in one of * the following forms: * * n - n is a non-negative integer. This sets both * pad values to n. * {n m} - both n and m are non-negative integers. side1 * is set to n, side2 is set to m. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interp->result. * * Side Effects: * The padding structure passed is updated with the new values. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StringToPad( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window */ const char *string, /* Pixel value string */ char *widgRec, /* Widget record */ int offset) /* Offset of pad in widget */ { Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset); const char **argv; int argc; int pad, result; if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { return TCL_ERROR; } result = TCL_ERROR; if ((argc < 1) || (argc > 2)) { Tcl_AppendResult(interp, "wrong # elements in padding list", (char *)NULL); goto error; } if (Blt_GetPixels(interp, tkwin, argv[0], PIXELS_NNEG, &pad) != TCL_OK) { goto error; } padPtr->side1 = pad; if ((argc > 1) && (Blt_GetPixels(interp, tkwin, argv[1], PIXELS_NNEG, &pad) != TCL_OK)) { goto error; } padPtr->side2 = pad; result = TCL_OK; error: Blt_Free(argv); return result; } /* *--------------------------------------------------------------------------- * * PadToString -- * * Converts the two pad values into a TCL list. Each pad has two * pixel values. For vertical pads, they represent the top and bottom * margins. For horizontal pads, they're the left and right margins. * All pad values are non-negative integers. * * Results: * The padding list is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static char * PadToString( ClientData clientData, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Structure record */ int offset, /* Offset of pad in record */ Tcl_FreeProc **freeProcPtr) /* Not used. */ { Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset); char *result; char string[200]; sprintf_s(string, 200, "%d %d", padPtr->side1, padPtr->side2); result = Blt_AssertStrdup(string); *freeProcPtr = (Tcl_FreeProc *)Blt_Free; return result; } /* *--------------------------------------------------------------------------- * * Blt_OldConfigModified -- * * Given the configuration specifications and one or more option * patterns (terminated by a NULL), indicate if any of the matching * configuration options has been reset. * * Results: * Returns 1 if one of the options has changed, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_OldConfigModified TCL_VARARGS_DEF(Tk_ConfigSpec *, arg1) { va_list argList; Tk_ConfigSpec *specs; char *option; specs = TCL_VARARGS_START(Tk_ConfigSpec *, arg1, argList); while ((option = va_arg(argList, char *)) != NULL) { Tk_ConfigSpec *specPtr; for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { if ((Tcl_StringMatch(specPtr->argvName, option)) && (specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)) { va_end(argList); return 1; } } } va_end(argList); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPs.h�����������������������������������������������������������������������0000644�0001750�0001750�00000015562�11462120062�014273� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPs.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_PS_H #define _BLT_PS_H #include "bltPicture.h" /* * PageSetup -- * * Structure contains information specific to the layout of the page for * printing the graph. * */ typedef struct { /* User configurable fields */ int reqWidth, reqHeight; /* If greater than zero, represents the * requested dimensions of the printed graph */ int reqPaperWidth; int reqPaperHeight; /* Requested dimensions for the PostScript * page. Can constrain the size of the graph * if the graph (plus padding) is larger than * the size of the page. */ Blt_Pad xPad, yPad; /* Requested padding on the exterior of the * graph. This forms the bounding box for * the page. */ const char *colorVarName; /* If non-NULL, is the name of a TCL array * variable containing X to output device color * translations */ const char *fontVarName; /* If non-NULL, is the name of a TCL array * variable containing X to output device font * translations */ int level; /* PostScript Language level 1-3 */ unsigned int flags; const char **comments; /* User supplied comments to be added. */ /* Computed fields */ short int left, bottom; /* Bounding box of the plot in the page. */ short int right, top; float scale; /* Scale of page. Set if "-maxpect" option * is set, otherwise 1.0. */ int paperHeight; int paperWidth; } PageSetup; #define PS_GREYSCALE (1<<0) #define PS_LANDSCAPE (1<<2) #define PS_CENTER (1<<3) #define PS_MAXPECT (1<<4) #define PS_DECORATIONS (1<<5) #define PS_FOOTER (1<<6) #define PS_FMT_NONE 0 #define PS_FMT_MASK (PS_FMT_WMF|PS_FMT_EPSI|PS_FMT_TIFF) #define PS_FMT_WMF (1<<8) #define PS_FMT_EPSI (1<<9) #define PS_FMT_TIFF (1<<10) typedef struct _Blt_Ps *Blt_Ps; BLT_EXTERN Blt_Ps Blt_Ps_Create(Tcl_Interp *interp, PageSetup *setupPtr); BLT_EXTERN void Blt_Ps_Free(Blt_Ps ps); BLT_EXTERN const char *Blt_Ps_GetValue(Blt_Ps ps, int *lengthPtr); BLT_EXTERN Tcl_Interp *Blt_Ps_GetInterp(Blt_Ps ps); BLT_EXTERN Tcl_DString *Blt_Ps_GetDString(Blt_Ps ps); BLT_EXTERN char *Blt_Ps_GetScratchBuffer(Blt_Ps ps); BLT_EXTERN void Blt_Ps_SetInterp(Blt_Ps ps, Tcl_Interp *interp); BLT_EXTERN void Blt_Ps_Append(Blt_Ps ps, const char *string); BLT_EXTERN void Blt_Ps_AppendBytes(Blt_Ps ps, const char *string, int nBytes); BLT_EXTERN void Blt_Ps_VarAppend TCL_VARARGS(Blt_Ps, ps); BLT_EXTERN void Blt_Ps_Format TCL_VARARGS(Blt_Ps, ps); BLT_EXTERN void Blt_Ps_SetClearBackground(Blt_Ps ps); BLT_EXTERN int Blt_Ps_IncludeFile(Tcl_Interp *interp, Blt_Ps ps, const char *fileName); BLT_EXTERN int Blt_Ps_GetPicaFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *picaPtr); BLT_EXTERN int Blt_Ps_GetPadFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Pad *padPtr); BLT_EXTERN int Blt_Ps_ComputeBoundingBox(PageSetup *setupPtr, int w, int h); BLT_EXTERN void Blt_Ps_DrawPicture(Blt_Ps ps, Blt_Picture picture, double x, double y); BLT_EXTERN void Blt_Ps_Rectangle(Blt_Ps ps, int x, int y, int w, int h); BLT_EXTERN int Blt_Ps_SaveFile(Tcl_Interp *interp, Blt_Ps ps, const char *fileName); #ifdef _TK #include "bltFont.h" #include "bltText.h" BLT_EXTERN void Blt_Ps_XSetLineWidth(Blt_Ps ps, int lineWidth); BLT_EXTERN void Blt_Ps_XSetBackground(Blt_Ps ps, XColor *colorPtr); BLT_EXTERN void Blt_Ps_XSetBitmapData(Blt_Ps ps, Display *display, Pixmap bitmap, int width, int height); BLT_EXTERN void Blt_Ps_XSetForeground(Blt_Ps ps, XColor *colorPtr); BLT_EXTERN void Blt_Ps_XSetFont(Blt_Ps ps, Blt_Font font); BLT_EXTERN void Blt_Ps_XSetDashes(Blt_Ps ps, Blt_Dashes *dashesPtr); BLT_EXTERN void Blt_Ps_XSetLineAttributes(Blt_Ps ps, XColor *colorPtr, int lineWidth, Blt_Dashes *dashesPtr, int capStyle, int joinStyle); BLT_EXTERN void Blt_Ps_XSetStipple(Blt_Ps ps, Display *display, Pixmap bitmap); BLT_EXTERN void Blt_Ps_Polyline(Blt_Ps ps, Point2d *screenPts, int nScreenPts); BLT_EXTERN void Blt_Ps_XDrawLines(Blt_Ps ps, XPoint *points, int n); BLT_EXTERN void Blt_Ps_XDrawSegments(Blt_Ps ps, XSegment *segments, int nSegments); BLT_EXTERN void Blt_Ps_DrawPolyline(Blt_Ps ps, Point2d *points, int n); BLT_EXTERN void Blt_Ps_Draw2DSegments(Blt_Ps ps, Segment2d *segments, int nSegments); BLT_EXTERN void Blt_Ps_Draw3DRectangle(Blt_Ps ps, Tk_3DBorder border, double x, double y, int width, int height, int borderWidth, int relief); BLT_EXTERN void Blt_Ps_Fill3DRectangle(Blt_Ps ps, Tk_3DBorder border, double x, double y, int width, int height, int borderWidth, int relief); BLT_EXTERN void Blt_Ps_XFillRectangle(Blt_Ps ps, double x, double y, int width, int height); BLT_EXTERN void Blt_Ps_XFillRectangles(Blt_Ps ps, XRectangle *rects, int n); BLT_EXTERN void Blt_Ps_XFillPolygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts); BLT_EXTERN void Blt_Ps_DrawPhoto(Blt_Ps ps, Tk_PhotoHandle photoToken, double x, double y); BLT_EXTERN void Blt_Ps_XDrawWindow(Blt_Ps ps, Tk_Window tkwin, double x, double y); BLT_EXTERN void Blt_Ps_DrawText(Blt_Ps ps, const char *string, TextStyle *attrPtr, double x, double y); BLT_EXTERN void Blt_Ps_DrawBitmap(Blt_Ps ps, Display *display, Pixmap bitmap, double scaleX, double scaleY); BLT_EXTERN void Blt_Ps_XSetCapStyle(Blt_Ps ps, int capStyle); BLT_EXTERN void Blt_Ps_XSetJoinStyle(Blt_Ps ps, int joinStyle); BLT_EXTERN void Blt_Ps_PolylineFromXPoints(Blt_Ps ps, XPoint *points, int n); BLT_EXTERN void Blt_Ps_Polygon(Blt_Ps ps, Point2d *screenPts, int nScreenPts); BLT_EXTERN void Blt_Ps_SetPrinting(Blt_Ps ps, int value); BLT_EXTERN int Blt_Ps_IsPrinting(void); BLT_EXTERN int Blt_Ps_TextWidth(Blt_Font font, const char *string, int nBytes); BLT_EXTERN int Blt_Ps_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr); BLT_EXTERN void Blt_Ps_FontName(const char *family, int flags, Tcl_DString *resultPtr); #endif /* _TK */ #endif /* BLT_PS_H */ ����������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkIntPlatDecls.h��������������������������������������������������������������0000644�0001750�0001750�00000010732�11462120063�016067� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkIntPlatDecls.h -- * * This file contains the declarations for all platform dependent * unsupported functions that are exported by the Tk library. These * interfaces are not guaranteed to remain the same between versions. * Use at your own risk. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from tkIntPlatDecls.h of the Tk library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. */ #ifndef _TKINTPLATDECLS #define _TKINTPLATDECLS #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tkInt.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ #ifdef __WIN32__ /* 16 */ extern HDC TkWinGetDrawableDC(Display *display, Drawable drawable, TkWinDCState *state); /* 22 */ extern void TkWinReleaseDrawableDC(Drawable drawable, HDC hdc, TkWinDCState *state); #endif /* __WIN32__ */ typedef struct TkIntPlatStubs { int magic; struct TkIntPlatStubHooks *hooks; void *hook0; void *hook1; void *hook2; void *hook3; void *hook4; void *hook5; void *hook6; void *hook7; void *hook8; void *hook9; void *hook10; void *hook11; void *hook12; void *hook13; void *hook14; void *hook15; #ifdef WIN32 HDC (*tkWinGetDrawableDC)(Display *display, Drawable drawable, TkWinDCState *state); /* 16 */ #else void *hook16; #endif void *hook17; void *hook18; void *hook19; void *hook20; void *hook21; #ifdef WIN32 void (*tkWinReleaseDrawableDC)(Drawable drawable, HDC hdc, TkWinDCState *state); /* 22 */ #else void *hook22; #endif void *hook23; void *hook24; void *hook25; void *hook26; void *hook27; void *hook28; void *hook29; void *hook30; void *hook31; void *hook32; void *hook33; void *hook34; void *hook35; void *hook36; void *hook37; void *hook38; void *hook39; void *hook40; void *hook41; void *hook42; void *hook43; void *hook44; void *hook45; void *hook46; void *hook47; void *hook48; void *hook49; void *hook50; void *hook51; void *hook52; void *hook53; void *hook54; void *hook55; void *hook56; void *hook57; void *hook58; void *hook59; void *hook60; void *hook61; void *hook62; void *hook63; void *hook64; void *hook65; void *hook66; } TkIntPlatStubs; #ifdef __cplusplus extern "C" { #endif extern TkIntPlatStubs *tkIntPlatStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) /* * Inline function declarations: */ #ifdef __WIN32__ #ifndef TkWinGetDrawableDC #define TkWinGetDrawableDC \ (tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 16 */ #endif #ifndef TkWinReleaseDrawableDC #define TkWinReleaseDrawableDC \ (tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 22 */ #endif #endif /* __WIN32__ */ #endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKINTPLATDECLS */ ��������������������������������������./saods9/blt3.0.1/src/bltList.c���������������������������������������������������������������������0000644�0001750�0001750�00000030301�11462120062�014603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltList.c -- * * The module implements generic linked lists for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include "bltList.h" typedef struct _Blt_ListNode Node; typedef struct _Blt_List List; static Node * FindString(List *listPtr, const char *key) { Node *np; char c; c = key[0]; for (np = listPtr->head; np != NULL; np = np->next) { if ((c == np->key.string[0]) && (strcmp(key, np->key.string) == 0)) { return np; } } return NULL; } static Blt_ListNode FindOneWord(List *listPtr, const char *key) { Node *np; for (np = listPtr->head; np != NULL; np = np->next) { if (key == np->key.oneWordValue) { return np; } } return NULL; } static Blt_ListNode FindArray(List *listPtr, const char *key) { Node *np; size_t nBytes; nBytes = sizeof(uint32_t) * listPtr->type; for (np = listPtr->head; np != NULL; np = np->next) { if (memcmp(key, np->key.words, nBytes) == 0) { return np; } } return NULL; } /* *--------------------------------------------------------------------------- * * FreeNode -- * * Free the memory allocated for the node. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeNode(Blt_ListNode node) { Blt_Free(node); } /* *--------------------------------------------------------------------------- * * Blt_List_Create -- * * Creates a new linked list structure and initializes its pointers * * Results: * Returns a pointer to the newly created list structure. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Blt_List Blt_List_Create(size_t type) { List *listPtr; listPtr = Blt_Malloc(sizeof(List)); if (listPtr != NULL) { Blt_List_Init(listPtr, type); } return listPtr; } /* *--------------------------------------------------------------------------- * * Blt_List_CreateNode -- * * Creates a list node holder. This routine does not insert the node * into the list, nor does it no attempt to maintain consistency of the * keys. For example, more than one node may use the same key. * * Results: * The return value is the pointer to the newly created node. * * Side Effects: * The key is not copied, only the Uid is kept. It is assumed this key * will not change in the life of the node. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Blt_ListNode Blt_List_CreateNode(List *listPtr, const char *key) { Node *np; size_t keySize; if (listPtr->type == BLT_STRING_KEYS) { keySize = strlen(key) + 1; } else if (listPtr->type == BLT_ONE_WORD_KEYS) { keySize = sizeof(void *); } else { keySize = sizeof(uint32_t) * listPtr->type; } np = Blt_AssertCalloc(1, sizeof(Node) + keySize - 4); np->clientData = NULL; np->next = np->prev = NULL; np->list = listPtr; switch (listPtr->type) { case BLT_STRING_KEYS: strcpy(np->key.string, key); break; case BLT_ONE_WORD_KEYS: np->key.oneWordValue = key; break; default: memcpy(np->key.words, key, keySize); break; } return np; } /* *--------------------------------------------------------------------------- * * Blt_List_Reset -- * * Removes all the entries from a list, removing pointers to the objects * and keys (not the objects or keys themselves). The node counter is * reset to zero. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_Reset(List *listPtr) /* List to clear */ { if (listPtr != NULL) { Node *nextPtr, *np; for (np = listPtr->head; np != NULL; np = nextPtr) { nextPtr = np->next; FreeNode(np); } Blt_List_Init(listPtr, listPtr->type); } } /* *--------------------------------------------------------------------------- * * Blt_List_Destroy * * Frees the list structure. * * Results: * Returns a pointer to the newly created list structure. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_Destroy(Blt_List list) { if (list != NULL) { Blt_List_Reset(list); Blt_Free(list); } } /* *--------------------------------------------------------------------------- * * Blt_List_Init -- * * Initializes a linked list. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_Init(List *listPtr, size_t type) { listPtr->nNodes = 0; listPtr->head = listPtr->tail = NULL; listPtr->type = type; } /* *--------------------------------------------------------------------------- * * Blt_List_LinkAfter -- * * Inserts an node following a given node. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_LinkAfter(List *listPtr, Node *np, Node *afterPtr) { if (listPtr->head == NULL) { listPtr->tail = listPtr->head = np; } else { if (afterPtr == NULL) { /* Prepend to the front of the list */ np->next = listPtr->head; np->prev = NULL; listPtr->head->prev = np; listPtr->head = np; } else { np->next = afterPtr->next; np->prev = afterPtr; if (afterPtr == listPtr->tail) { listPtr->tail = np; } else { afterPtr->next->prev = np; } afterPtr->next = np; } } np->list = listPtr; listPtr->nNodes++; } /* *--------------------------------------------------------------------------- * * Blt_List_LinkBefore -- * * Inserts an node preceding a given node. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_LinkBefore(List *listPtr, Node *np, Node *beforePtr) { if (listPtr->head == NULL) { listPtr->tail = listPtr->head = np; } else { if (beforePtr == NULL) { /* Append onto the end of the list */ np->next = NULL; np->prev = listPtr->tail; listPtr->tail->next = np; listPtr->tail = np; } else { np->prev = beforePtr->prev; np->next = beforePtr; if (beforePtr == listPtr->head) { listPtr->head = np; } else { beforePtr->prev->next = np; } beforePtr->prev = np; } } np->list = listPtr; listPtr->nNodes++; } /* *--------------------------------------------------------------------------- * * Blt_List_UnlinkNode -- * * Unlinks an node from the given list. The node itself is not * deallocated, but only removed from the list. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_UnlinkNode(Node *np) { List *listPtr; listPtr = np->list; if (listPtr != NULL) { int unlinked = 0; if (listPtr->head == np) { listPtr->head = np->next; unlinked++; } if (listPtr->tail == np) { listPtr->tail = np->prev; unlinked++; } if (np->next != NULL) { np->next->prev = np->prev; unlinked++; } if (np->prev != NULL) { np->prev->next = np->next; unlinked++; } np->list = NULL; if (unlinked) { assert(listPtr->nNodes > 0); listPtr->nNodes--; } } } /* *--------------------------------------------------------------------------- * * Blt_List_GetNode -- * * Find the first node matching the key given. * * Results: * Returns the pointer to the node. If no node matching the key given is * found, then NULL is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Blt_ListNode Blt_List_GetNode(List *listPtr, const char *key) { if (listPtr != NULL) { switch (listPtr->type) { case BLT_STRING_KEYS: return FindString(listPtr, key); case BLT_ONE_WORD_KEYS: return FindOneWord(listPtr, key); default: return FindArray(listPtr, key); } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_List_DeleteNode -- * * Unlinks and deletes the given node. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_DeleteNode(Blt_ListNode node) { Blt_List_UnlinkNode(node); FreeNode(node); } /* *--------------------------------------------------------------------------- * * Blt_List_DeleteNodeByKey -- * * Find the node and free the memory allocated for the node. * * Results: * None. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_DeleteNodeByKey(Blt_List list, const char *key) { Blt_ListNode node; node = Blt_List_GetNode(list, key); if (node != NULL) { Blt_List_DeleteNode(node); } } /*LINTLIBRARY*/ Blt_ListNode Blt_List_Append(Blt_List list, const char *key, ClientData clientData) { Blt_ListNode node; node = Blt_List_CreateNode(list, key); Blt_List_SetValue(node, clientData); Blt_List_AppendNode(list, node); return node; } /*LINTLIBRARY*/ Blt_ListNode Blt_List_Prepend(Blt_List list, const char *key, ClientData clientData) { Blt_ListNode node; node = Blt_List_CreateNode(list, key); Blt_List_SetValue(node, clientData); Blt_List_PrependNode(list, node); return node; } /* *--------------------------------------------------------------------------- * * Blt_List_GetNthNode -- * * Find the node based upon a given position in list. * * Results: * Returns the pointer to the node, if that numbered element * exists. Otherwise NULL. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Blt_ListNode Blt_List_GetNthNode(List *listPtr, long position, int direction) { if (listPtr == NULL) { return NULL; } if (direction > 0) { Node *np; for (np = listPtr->head; np != NULL; np = np->next) { if (position == 0) { return np; } position--; } } else { Node *np; for (np = listPtr->tail; np != NULL; np = np->prev) { if (position == 0) { return np; } position--; } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_List_Sort -- * * Find the node based upon a given position in list. * * Results: * Returns the pointer to the node, if that numbered element * exists. Otherwise NULL. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_List_Sort(List *listPtr, Blt_ListCompareProc *proc) { Node **nodes; Node *np; size_t i; if (listPtr->nNodes < 2) { return; } nodes = Blt_Malloc(sizeof(Node *) * (listPtr->nNodes + 1)); if (nodes == NULL) { return; /* Out of memory. */ } for (i = 0, np = listPtr->head; np != NULL; np = np->next) { nodes[i++] = np; } qsort(nodes, listPtr->nNodes, sizeof(Node *), (QSortCompareProc *)proc); /* Rethread the list. */ np = nodes[0]; listPtr->head = np; np->prev = NULL; for (i = 1; i < listPtr->nNodes; i++) { np->next = nodes[i]; np->next->prev = np; np = np->next; } listPtr->tail = np; np->next = NULL; Blt_Free(nodes); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTree.c���������������������������������������������������������������������0000644�0001750�0001750�00000346344�11462120063�014611� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTree.c -- * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" /* TODO: * Traces and notifiers should be in one list in tree object. * Notifier is always fired. * Incorporate first/next tag routines ? */ #include "bltNsUtil.h" #include "bltArrayObj.h" #include "bltTree.h" static Tcl_InterpDeleteProc TreeInterpDeleteProc; static Blt_TreeApplyProc SizeApplyProc; static Tcl_IdleProc NotifyIdleProc; static Tcl_IdleProc TraceIdleProc; #define TREE_THREAD_KEY "BLT Tree Data" #define TREE_MAGIC ((unsigned int) 0x46170277) #define TREE_DESTROYED (1<<0) #define TREE_NODE_REBUILD_SIZE 3U typedef struct _Blt_TreeNode Node; typedef struct _Blt_Tree Tree; typedef struct _Blt_TreeObject TreeObject; typedef struct _Blt_TreeValue Value; /* * Blt_TreeValue -- * * A tree node may have zero or more data fields or values that are * represented by these container structures. Each data field has both * the name of the field (Blt_TreeKey) and its data (Tcl_Obj). Values * are private or public. Private values are only be seen by the tree * client that created the field. * * Values are organized in two ways. They are stored in a linked list in * order that they were created. In addition, they may be placed into a * hash table when the number of values reaches a high-water mark. * */ struct _Blt_TreeValue { Blt_TreeKey key; /* String identifying the data field */ Tcl_Obj *objPtr; /* Data representation. */ Blt_Tree owner; /* Non-NULL if privately owned. */ Blt_TreeValue next; /* Next value in the chain. */ Blt_TreeValue hnext; /* Next value in hash table. */ }; typedef struct { Tree *treePtr; unsigned int flags; Node *rootPtr; Blt_HashTable idTable; int nLines; Blt_HashTable dataTable; } RestoreInfo; #include <stdio.h> #include <string.h> /* The following header is required for LP64 compilation */ #include <stdlib.h> #include "bltHash.h" static void TreeDestroyValues(Blt_TreeNode node); static Value *TreeFindValue(Blt_TreeNode node, Blt_TreeKey key); static Value *TreeCreateValue(Blt_TreeNode node, Blt_TreeKey key, int *newPtr); static int TreeDeleteValue(Blt_TreeNode node, Blt_TreeValue value); static Value *TreeFirstValue(Blt_TreeNode, Blt_TreeKeyIterator *iterPtr); static Value *TreeNextValue(Blt_TreeKeyIterator *iterPtr); /* * When there are this many entries per bucket, on average, rebuild the hash * table to make it larger. */ #define REBUILD_MULTIPLIER 3 #define START_LOGSIZE 5 /* Initial hash table size is 32. */ #define HASH_HIGH_WATER 20 /* Start a hash table when a node has this * many values or child nodes. */ #define HASH_LOW_WATER (HASH_HIGH_WATER << 1) #if (SIZEOF_VOID_P == 8) #define RANDOM_INDEX(i) HashOneWord(mask, downshift, i) static Blt_Hash HashOneWord(uint64_t mask, unsigned int downshift, const void *key); #define BITSPERWORD 64 #else /* * The following macro takes a preliminary integer hash value and produces an * index into a hash tables bucket list. The idea is to make it so that * preliminary values that are arbitrarily similar will end up in different * buckets. The hash function was taken from a random-number generator. */ #define RANDOM_INDEX(i) \ (((((long) (i))*1103515245) >> downshift) & mask) #define BITSPERWORD 32 #endif /* SIZEOF_VOID_P == 8 */ #define DOWNSHIFT_START (BITSPERWORD - 2) /* * The hash table below is used to keep track of all the Blt_TreeKeys created * so far. */ typedef struct _Blt_TreeInterpData { Tcl_Interp *interp; Blt_HashTable treeTable; /* Table of trees. */ Blt_HashTable keyTable; /* Table of string keys, shared among all the * trees within an interpreter. */ unsigned int nextId; /* Identifier used to generate automatic tree * names. */ } TreeInterpData; typedef struct { Tcl_Interp *interp; ClientData clientData; Blt_TreeKey key; Blt_TreeNotifyEventProc *proc; Blt_TreeNotifyEvent event; unsigned int mask; int notifyPending; } NotifyEventHandler; typedef struct { /* This must match _Blt_TreeTrace in bltTree.h */ ClientData clientData; const char *keyPattern; /* Pattern to be matched */ Node *nodePtr; /* Node to be matched. */ unsigned int mask; Blt_TreeTraceProc *proc; /* Private fields */ const char *withTag; Tree *treePtr; Blt_ChainLink link; Blt_HashTable idleTable; Tcl_Interp *interp; } TraceHandler; typedef struct { TraceHandler *tracePtr; /* Trace trace matched. */ Tcl_Interp *interp; /* Source interpreter. */ Blt_TreeKey key; /* Key that matched. */ int flags; /* Flags that matched. */ long inode; /* Node that matched. */ Blt_HashEntry *hashPtr; } TraceWhenIdle; /* *--------------------------------------------------------------------------- * * Blt_Tree_GetInterpData -- * * Creates or retrieves data associated with tree data objects for a * particular thread. We're using Tcl_GetAssocData rather than the Tcl * thread routines so BLT can work with pre-8.0 TCL versions that don't * have thread support. * * Results: * Returns a pointer to the tree interpreter data. * *--------------------------------------------------------------------------- */ static Blt_TreeInterpData * Blt_Tree_GetInterpData(Tcl_Interp *interp) { Tcl_InterpDeleteProc *proc; TreeInterpData *dataPtr; dataPtr = (TreeInterpData *) Tcl_GetAssocData(interp, TREE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(TreeInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, TREE_THREAD_KEY, TreeInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->treeTable, BLT_STRING_KEYS); Blt_InitHashTable(&dataPtr->keyTable, BLT_STRING_KEYS); } return dataPtr; } const char * Blt_Tree_NodeIdAscii(Node *nodePtr) { static char stringRep[200]; sprintf_s(stringRep, 200, "%ld", nodePtr->inode); return stringRep; } static Tree * FirstClient(TreeObject *corePtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(corePtr->clients); if (link == NULL) { return NULL; } return Blt_Chain_GetValue(link); } static Tree * NextClient(Tree *treePtr) { Blt_ChainLink link; if (treePtr == NULL) { return NULL; } link = Blt_Chain_NextLink(treePtr->link); if (link == NULL) { return NULL; } return Blt_Chain_GetValue(link); } /* *--------------------------------------------------------------------------- * * NewNode -- * * Creates a new node in the tree without installing it. The number of * nodes in the tree is incremented and a unique serial number is * generated for the node. * * Also, all nodes have a label. If no label was provided (name is NULL) * then automatically generate one in the form "nodeN" where N is the * serial number of the node. * * Results: * Returns a pointer to the new node. * * -------------------------------------------------------------- */ static Node * NewNode(TreeObject *corePtr, const char *name, long inode) { Node *np; /* Create the node structure */ np = Blt_PoolAllocItem(corePtr->nodePool, sizeof(Node)); np->inode = inode; np->corePtr = corePtr; np->parent = NULL; np->depth = 0; np->flags = 0; np->next = np->prev = NULL; np->first = np->last = NULL; np->nChildren = 0; np->values = NULL; np->valueTable = NULL; np->valueTableSize2 = 0; np->nValues = 0; np->nodeTable = NULL; np->nodeTableSize2 = 0; np->hnext = NULL; np->label = NULL; if (name != NULL) { np->label = Blt_Tree_GetKeyFromNode(np, name); } corePtr->nNodes++; return np; } /* *--------------------------------------------------------------------------- * * ReleaseTagTable -- * *--------------------------------------------------------------------------- */ static void ReleaseTagTable(Blt_TreeTagTable *tablePtr) { tablePtr->refCount--; if (tablePtr->refCount <= 0) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for(hPtr = Blt_FirstHashEntry(&tablePtr->tagTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_TreeTagEntry *tePtr; tePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(&tePtr->nodeTable); Blt_Free(tePtr); } Blt_DeleteHashTable(&tablePtr->tagTable); Blt_Free(tablePtr); } } /* *--------------------------------------------------------------------------- * * ResetDepths -- * * Called after moving a node, resets the depths of each node for the * entire branch (node and it's decendants). * * Results: * None. * * ---------------------------------------------------------------------- */ static void ResetDepths(Node *branchPtr, long depth) { Node *np; branchPtr->depth = depth; /* Also reset the depth for each descendant node. */ for (np = branchPtr->first; np != NULL; np = np->next) { ResetDepths(np, depth + 1); } } /* *--------------------------------------------------------------------------- * * RebuildNodeTable -- * * This procedure is invoked when the ratio of entries to hash buckets * becomes too large. It creates a new table with a larger bucket array * and moves all of the entries into the new table. * * Results: * None. * * Side effects: * Memory gets reallocated and entries get re-hashed to new * buckets. * *--------------------------------------------------------------------------- */ static void RebuildNodeTable(Node *parentPtr) /* Table to enlarge. */ { Node **bp, **bend; unsigned int downshift; unsigned long mask; Node **buckets; size_t nBuckets; nBuckets = (1 << parentPtr->nodeTableSize2); bend = parentPtr->nodeTable + nBuckets; /* * Allocate and initialize the new bucket array, and set up hashing * constants for new array size. */ parentPtr->nodeTableSize2 += 2; nBuckets = (1 << parentPtr->nodeTableSize2); buckets = Blt_AssertCalloc(nBuckets, sizeof(Node *)); /* * Move all of the existing entries into the new bucket array, based on * their new hash values. */ mask = nBuckets - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; for (bp = parentPtr->nodeTable; bp < bend; bp++) { Node *np, *nextPtr; for (np = *bp; np != NULL; np = nextPtr) { Node **bucketPtr; nextPtr = np->hnext; bucketPtr = buckets + RANDOM_INDEX(np->label); np->hnext = *bucketPtr; *bucketPtr = np; } } Blt_Free(parentPtr->nodeTable); parentPtr->nodeTable = buckets; } /* *--------------------------------------------------------------------------- * * MakeNodeTable -- * * Generates a hash table from the nodes list of children. * * Results: * None. * * Side effects: * Hash table for child nodes is created. * *--------------------------------------------------------------------------- */ static void MakeNodeTable(Node *parentPtr) { Node **buckets; Node *np, *nextPtr; int downshift; unsigned int mask; unsigned int nBuckets; assert(parentPtr->nodeTable == NULL); parentPtr->nodeTableSize2 = START_LOGSIZE; nBuckets = 1 << parentPtr->nodeTableSize2; buckets = Blt_AssertCalloc(nBuckets, sizeof(Node *)); mask = nBuckets - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; for (np = parentPtr->first; np != NULL; np = nextPtr) { Node **bucketPtr; nextPtr = np->next; bucketPtr = buckets + RANDOM_INDEX(np->label); np->hnext = *bucketPtr; *bucketPtr = np; } parentPtr->nodeTable = buckets; } /* *--------------------------------------------------------------------------- * * LinkBefore -- * * Inserts a link preceding a given link. * * Results: * None. * *--------------------------------------------------------------------------- */ static void LinkBefore( Node *parentPtr, /* Parent to hold the new entry. */ Node *nodePtr, /* New node to be inserted. */ Node *beforePtr) /* Node to link before. */ { if (parentPtr->first == NULL) { parentPtr->last = parentPtr->first = nodePtr; } else if (beforePtr == NULL) { /* Append onto the end of the chain */ nodePtr->next = NULL; nodePtr->prev = parentPtr->last; parentPtr->last->next = nodePtr; parentPtr->last = nodePtr; } else { nodePtr->prev = beforePtr->prev; nodePtr->next = beforePtr; if (beforePtr == parentPtr->first) { parentPtr->first = nodePtr; } else { beforePtr->prev->next = nodePtr; } beforePtr->prev = nodePtr; } parentPtr->nChildren++; nodePtr->parent = parentPtr; /* * Check if there as so many children that an addition hash table should * be created. */ if (parentPtr->nodeTable == NULL) { if (parentPtr->nChildren > HASH_HIGH_WATER) { MakeNodeTable(parentPtr); } } else { Node **bucketPtr; size_t nBuckets; unsigned int downshift; unsigned long mask; nBuckets = (1 << parentPtr->nodeTableSize2); mask = nBuckets - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; bucketPtr = parentPtr->nodeTable + RANDOM_INDEX(nodePtr->label); nodePtr->hnext = *bucketPtr; *bucketPtr = nodePtr; /* * If the table has exceeded a decent size, rebuild it with many more * buckets. */ if (parentPtr->nChildren >= (nBuckets * TREE_NODE_REBUILD_SIZE)) { RebuildNodeTable(parentPtr); } } } /* *--------------------------------------------------------------------------- * * UnlinkNode -- * * Unlinks a link from the chain. The link is not deallocated, but only * removed from the chain. * * Results: * None. * *--------------------------------------------------------------------------- */ static void UnlinkNode(Node *nodePtr) { Node *parentPtr; int unlinked; /* Indicates if the link is actually removed * from the chain. */ parentPtr = nodePtr->parent; unlinked = FALSE; if (parentPtr->first == nodePtr) { parentPtr->first = nodePtr->next; unlinked = TRUE; } if (parentPtr->last == nodePtr) { parentPtr->last = nodePtr->prev; unlinked = TRUE; } if (nodePtr->next != NULL) { nodePtr->next->prev = nodePtr->prev; unlinked = TRUE; } if (nodePtr->prev != NULL) { nodePtr->prev->next = nodePtr->next; unlinked = TRUE; } if (unlinked) { parentPtr->nChildren--; } nodePtr->prev = nodePtr->next = NULL; if (parentPtr->nodeTable != NULL) { Node **bucketPtr; unsigned int downshift; unsigned long mask; mask = (1 << parentPtr->nodeTableSize2) - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; bucketPtr = parentPtr->nodeTable + RANDOM_INDEX(nodePtr->label); if (*bucketPtr == nodePtr) { *bucketPtr = nodePtr->hnext; } else { Node *np; for (np = *bucketPtr; /*empty*/; np = np->hnext) { if (np == NULL) { return; /* Can't find node in hash bucket. */ } if (np->hnext == nodePtr) { np->hnext = nodePtr->hnext; break; } } } } nodePtr->hnext = NULL; if (parentPtr->nChildren < HASH_LOW_WATER) { Blt_Free(parentPtr->nodeTable); parentPtr->nodeTable = NULL; } } /* *--------------------------------------------------------------------------- * * FreeNode -- * * Unlinks a given node from the tree, removes its data, and frees memory * allocated to the node. * * Results: * None. * * -------------------------------------------------------------- */ static void FreeNode(TreeObject *corePtr, Node *nodePtr) { Blt_HashEntry *hPtr; /* Destroy any data fields associated with this node. */ if (nodePtr->values != NULL) { TreeDestroyValues(nodePtr); } if (nodePtr->nodeTable != NULL) { Blt_Free(nodePtr->nodeTable); } UnlinkNode(nodePtr); corePtr->nNodes--; hPtr = Blt_FindHashEntry(&corePtr->nodeTable, (char *)nodePtr->inode); assert(hPtr); Blt_DeleteHashEntry(&corePtr->nodeTable, hPtr); Blt_PoolFreeItem(corePtr->nodePool, nodePtr); } /* *--------------------------------------------------------------------------- * * TeardownTree -- * * Destroys an entire branch. This is a special purpose routine used to * speed up the final clean up of the tree. * * Results: * None. * * ---------------------------------------------------------------------- */ static void TeardownTree(TreeObject *corePtr, Node *branchPtr) { Node *np, *nextPtr; if (branchPtr->nodeTable != NULL) { Blt_Free(branchPtr->nodeTable); branchPtr->nodeTable = NULL; } if (branchPtr->values != NULL) { TreeDestroyValues(branchPtr); } for (np = branchPtr->first; np != NULL; np = nextPtr) { nextPtr = np->next; TeardownTree(corePtr, np); } Blt_PoolFreeItem(corePtr->nodePool, branchPtr); } /* *--------------------------------------------------------------------------- * * DestroyTreeObject -- * * Destroys a tree object, freeing its nodes and memory. * * Results: * None. * * ---------------------------------------------------------------------- */ static void DestroyTreeObject(TreeObject *corePtr) { corePtr->flags |= TREE_DESTROYED; corePtr->nNodes = 0; assert(Blt_Chain_GetLength(corePtr->clients) == 0); Blt_Chain_Destroy(corePtr->clients); TeardownTree(corePtr, corePtr->root); Blt_PoolDestroy(corePtr->nodePool); Blt_PoolDestroy(corePtr->valuePool); Blt_DeleteHashTable(&corePtr->nodeTable); Blt_Free(corePtr); } /* *--------------------------------------------------------------------------- * * ReleaseTreeObject -- * * Removes the client from the core tree object's list of clients. If * there are no more clients, then the tree object itself is destroyed. * * Results: * None. * * Side Effects: * The client is detached from the tree object. The tree object is * possibly destroyed, freeing memory. * *--------------------------------------------------------------------------- */ static void ReleaseTreeObject(Tree *treePtr) { if ((treePtr->link != NULL) && (treePtr->corePtr != NULL)) { /* Remove the client from the core's list */ Blt_Chain_DeleteLink(treePtr->corePtr->clients, treePtr->link); if (Blt_Chain_GetLength(treePtr->corePtr->clients) == 0) { DestroyTreeObject(treePtr->corePtr); } treePtr->corePtr = NULL; } } /* *--------------------------------------------------------------------------- * * NewTreeObject -- * * Creates and initializes a new tree object. Trees always contain a root * node, so one is allocated here. * * Results: * Returns a pointer to the new tree object is successful, NULL * otherwise. If a tree can't be generated, interp->result will contain * an error message. * *--------------------------------------------------------------------------- */ static TreeObject * NewTreeObject(TreeInterpData *dataPtr) { TreeObject *corePtr; int isNew; Blt_HashEntry *hPtr; corePtr = Blt_Calloc(1, sizeof(TreeObject)); if (corePtr == NULL) { return NULL; } corePtr->dataPtr = dataPtr; corePtr->valuePool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); corePtr->nodePool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); corePtr->clients = Blt_Chain_Create(); corePtr->depth = 1; corePtr->notifyFlags = 0; Blt_InitHashTableWithPool(&corePtr->nodeTable, BLT_ONE_WORD_KEYS); hPtr = Blt_CreateHashEntry(&corePtr->nodeTable, (char *)0, &isNew); corePtr->root = NewNode(corePtr, "", 0); Blt_SetHashValue(hPtr, corePtr->root); return corePtr; } static Tree * FindClientInNamespace(TreeInterpData *dataPtr, Blt_ObjectName *objNamePtr) { Tcl_DString ds; const char *qualName; Blt_HashEntry *hPtr; qualName = Blt_MakeQualifiedName(objNamePtr, &ds); hPtr = Blt_FindHashEntry(&dataPtr->treeTable, qualName); Tcl_DStringFree(&ds); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * GetTree -- * * Searches for the tree object associated by the name given. * * Results: * Returns a pointer to the tree if found, otherwise NULL. * *--------------------------------------------------------------------------- */ static Tree * GetTree(TreeInterpData *dataPtr, const char *name, int flags) { Blt_ObjectName objName; Tree *treePtr; Tcl_Interp *interp; treePtr = NULL; interp = dataPtr->interp; if (!Blt_ParseObjectName(interp, name, &objName, BLT_NO_DEFAULT_NS)) { return NULL; } if (objName.nsPtr != NULL) { treePtr = FindClientInNamespace(dataPtr, &objName); } else { if (flags & NS_SEARCH_CURRENT) { /* Look first in the current namespace. */ objName.nsPtr = Tcl_GetCurrentNamespace(interp); treePtr = FindClientInNamespace(dataPtr, &objName); } if ((treePtr == NULL) && (flags & NS_SEARCH_GLOBAL)) { objName.nsPtr = Tcl_GetGlobalNamespace(interp); treePtr = FindClientInNamespace(dataPtr, &objName); } } return treePtr; } static void ResetTree(Tree *treePtr) { Blt_ChainLink link; /* Remove any traces that may be set. */ for (link = Blt_Chain_FirstLink(treePtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { TraceHandler *tracePtr; tracePtr = Blt_Chain_GetValue(link); if (tracePtr->keyPattern != NULL) { Blt_Free(tracePtr->keyPattern); } if (tracePtr->idleTable.numEntries > 0) { Tcl_CancelIdleCall(TraceIdleProc, tracePtr); } Blt_Free(tracePtr); } Blt_Chain_Reset(treePtr->traces); /* And any event handlers. */ for(link = Blt_Chain_FirstLink(treePtr->events); link != NULL; link = Blt_Chain_NextLink(link)) { NotifyEventHandler *notifyPtr; notifyPtr = Blt_Chain_GetValue(link); if (notifyPtr->notifyPending) { Tcl_CancelIdleCall(NotifyIdleProc, notifyPtr); } Blt_Free(notifyPtr); } Blt_Chain_Reset(treePtr->events); } static void DestroyTree(Tree *treePtr) { TreeInterpData *dataPtr; dataPtr = treePtr->corePtr->dataPtr; if (treePtr->tagTablePtr != NULL) { ReleaseTagTable(treePtr->tagTablePtr); } ResetTree(treePtr); if (treePtr->hPtr != NULL) { Blt_DeleteHashEntry(&dataPtr->treeTable, treePtr->hPtr); } Blt_Chain_Destroy(treePtr->traces); Blt_Chain_Destroy(treePtr->events); treePtr->magic = 0; ReleaseTreeObject(treePtr); Blt_Free(treePtr); } /* *--------------------------------------------------------------------------- * * TreeInterpDeleteProc -- * * This is called when the interpreter hosting the tree object is deleted * from the interpreter. * * Results: * None. * * Side effects: * Destroys all remaining trees and removes the hash table used to * register tree names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TreeInterpDeleteProc(ClientData clientData, Tcl_Interp *interp) { TreeInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->treeTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tree *treePtr; treePtr = Blt_GetHashValue(hPtr); treePtr->hPtr = NULL; DestroyTree(treePtr); } Blt_DeleteHashTable(&dataPtr->treeTable); Blt_DeleteHashTable(&dataPtr->keyTable); Tcl_DeleteAssocData(interp, TREE_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * NotifyIdleProc -- * * Used to invoke event handler routines at some idle point. This * routine is called from the TCL event loop. Errors generated by the * event handler routines are backgrounded. * * Results: * None. * *--------------------------------------------------------------------------- */ static void NotifyIdleProc(ClientData clientData) { NotifyEventHandler *notifyPtr = clientData; int result; notifyPtr->notifyPending = FALSE; notifyPtr->mask |= TREE_NOTIFY_ACTIVE; result = (*notifyPtr->proc)(notifyPtr->clientData, &notifyPtr->event); notifyPtr->mask &= ~TREE_NOTIFY_ACTIVE; if (result != TCL_OK) { Tcl_BackgroundError(notifyPtr->interp); } } /* *--------------------------------------------------------------------------- * * CheckEventHandlers -- * * Traverses the list of client event callbacks and checks if one matches * the given event. A client may trigger an action that causes the tree * to notify it. The can be prevented by setting the * TREE_NOTIFY_FOREIGN_ONLY bit in the event handler. * * If a matching handler is found, a callback may be called either * immediately or at the next idle time depending upon the * TREE_NOTIFY_WHENIDLE bit. * * Since a handler routine may trigger yet another call to itself, * callbacks are ignored while the event handler is executing. * * Results: * None. * *--------------------------------------------------------------------------- */ static void CheckEventHandlers(Tree *treePtr, int isSource, Blt_TreeNotifyEvent *eventPtr) { Blt_ChainLink link, next; eventPtr->tree = treePtr; for (link = Blt_Chain_FirstLink(treePtr->events); link != NULL; link = next) { NotifyEventHandler *notifyPtr; next = Blt_Chain_NextLink(link); notifyPtr = Blt_Chain_GetValue(link); if ((notifyPtr->mask & TREE_NOTIFY_ACTIVE) || (notifyPtr->mask & eventPtr->type) == 0) { continue; /* Ignore callbacks that are generated * inside of a notify handler * routine. */ } if ((isSource) && (notifyPtr->mask & TREE_NOTIFY_FOREIGN_ONLY)) { continue; /* Don't notify yourself. */ } if (notifyPtr->mask & TREE_NOTIFY_WHENIDLE) { if (!notifyPtr->notifyPending) { notifyPtr->notifyPending = TRUE; notifyPtr->event = *eventPtr; Tcl_DoWhenIdle(NotifyIdleProc, notifyPtr); } } else { int result; notifyPtr->mask |= TREE_NOTIFY_ACTIVE; result = (*notifyPtr->proc) (notifyPtr->clientData, eventPtr); notifyPtr->mask &= ~TREE_NOTIFY_ACTIVE; if (result != TCL_OK) { Tcl_BackgroundError(notifyPtr->interp); } } } } /* *--------------------------------------------------------------------------- * * NotifyClients -- * * Traverses the list of clients for a particular tree and notifies each * client that an event occurred. Clients indicate interest in a * particular event through a bit flag. * *--------------------------------------------------------------------------- */ static void NotifyClients(Tree *sourcePtr, TreeObject *corePtr, Node *nodePtr, int eventFlag) { Blt_TreeNotifyEvent event; Tree *treePtr; event.type = eventFlag; event.inode = nodePtr->inode; event.node = nodePtr; /* * Issue callbacks to each client indicating that a new node has been * created. */ for (treePtr = FirstClient(corePtr); treePtr != NULL; treePtr = NextClient(treePtr)) { int isSource; isSource = (treePtr == sourcePtr); CheckEventHandlers(treePtr, isSource, &event); } } static void FreeValue(Node *nodePtr, Value *valuePtr) { if (valuePtr->objPtr != NULL) { Tcl_DecrRefCount(valuePtr->objPtr); } Blt_PoolFreeItem(nodePtr->corePtr->valuePool, valuePtr); } #if (SIZEOF_VOID_P == 8) /* *--------------------------------------------------------------------------- * * HashOneWord -- * * Compute a one-word hash value of a 64-bit word, which then can be used * to generate a hash index. * * From Knuth, it's a multiplicative hash. Multiplies an unsigned 64-bit * value with the golden ratio (sqrt(5) - 1) / 2. The downshift value is * 64 - n, when n is the log2 of the size of the hash table. * * Results: * The return value is a one-word summary of the information in 64 bit * word. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_Hash HashOneWord(uint64_t mask, unsigned int downshift, const void *key) { uint64_t a0, a1; uint64_t y0, y1; uint64_t y2, y3; uint64_t p1, p2; uint64_t result; /* Compute key * GOLDEN_RATIO in 128-bit arithmetic */ a0 = (uint64_t)key & 0x00000000FFFFFFFF; a1 = (uint64_t)key >> 32; y0 = a0 * 0x000000007f4a7c13; y1 = a0 * 0x000000009e3779b9; y2 = a1 * 0x000000007f4a7c13; y3 = a1 * 0x000000009e3779b9; y1 += y0 >> 32; /* Can't carry */ y1 += y2; /* Might carry */ if (y1 < y2) { y3 += (1LL << 32); /* Propagate */ } /* 128-bit product: p1 = loword, p2 = hiword */ p1 = ((y1 & 0x00000000FFFFFFFF) << 32) + (y0 & 0x00000000FFFFFFFF); p2 = y3 + (y1 >> 32); /* Left shift the value downward by the size of the table */ if (downshift > 0) { if (downshift < 64) { result = ((p2 << (64 - downshift)) | (p1 >> (downshift & 63))); } else { result = p2 >> (downshift & 63); } } else { result = p1; } /* Finally mask off the high bits */ return (Blt_Hash)(result & mask); } #endif /* SIZEOF_VOID_P == 8 */ /* *--------------------------------------------------------------------------- * * RebuildTable -- * * This procedure is invoked when the ratio of entries to hash buckets * becomes too large. It creates a new table with a larger bucket array * and moves all of the entries into the new table. * * Results: * None. * * Side effects: * Memory gets reallocated and entries get re-hashed to new buckets. * *--------------------------------------------------------------------------- */ static void RebuildValueTable(Node *nodePtr) /* Table to enlarge. */ { Value **bp, **bend, **buckets, **oldBuckets; size_t nBuckets; unsigned int downshift; unsigned long mask; oldBuckets = nodePtr->valueTable; nBuckets = (1 << nodePtr->valueTableSize2); bend = oldBuckets + nBuckets; /* * Allocate and initialize the new bucket array, and set up hashing * constants for new array size. */ nodePtr->valueTableSize2 += 2; nBuckets = (1 << nodePtr->valueTableSize2); buckets = Blt_AssertCalloc(nBuckets, sizeof(Value *)); /* * Move all of the existing entries into the new bucket array, based on * their hash values. */ mask = nBuckets - 1; downshift = DOWNSHIFT_START - nodePtr->valueTableSize2; for (bp = oldBuckets; bp < bend; bp++) { Value *vp, *nextPtr; for (vp = *bp; vp != NULL; vp = nextPtr) { Value **bucketPtr; nextPtr = vp->hnext; bucketPtr = buckets + RANDOM_INDEX(vp->key); vp->hnext = *bucketPtr; *bucketPtr = vp; } } nodePtr->valueTable = buckets; Blt_Free(oldBuckets); } static void MakeValueTable(Node *nodePtr) { unsigned int nBuckets; Value **buckets; unsigned int mask; int downshift; Value *vp, *nextPtr; assert(nodePtr->valueTable == NULL); /* Generate hash table from list of values. */ nodePtr->valueTableSize2 = START_LOGSIZE; nBuckets = 1 << nodePtr->valueTableSize2; buckets = Blt_AssertCalloc(nBuckets, sizeof(Value *)); mask = nBuckets - 1; downshift = DOWNSHIFT_START - nodePtr->valueTableSize2; for (vp = nodePtr->values; vp != NULL; vp = nextPtr) { Value **bucketPtr; nextPtr = vp->next; bucketPtr = buckets + RANDOM_INDEX(vp->key); vp->hnext = *bucketPtr; *bucketPtr = vp; } nodePtr->valueTable = buckets; } /* *--------------------------------------------------------------------------- * * TreeDeleteValue -- * * Remove a single entry from a hash table. * * Results: * None. * * Side effects: * The entry given by entryPtr is deleted from its table and should never * again be used by the caller. It is up to the caller to free the * clientData field of the entry, if that is relevant. * *--------------------------------------------------------------------------- */ static int TreeDeleteValue(Node *nodePtr, Blt_TreeValue value) { Value *vp, *prevPtr; if (nodePtr->valueTable != NULL) { Value **bucketPtr; unsigned int downshift; unsigned long mask; mask = (1 << nodePtr->valueTableSize2) - 1; downshift = DOWNSHIFT_START - nodePtr->valueTableSize2; bucketPtr = nodePtr->valueTable + RANDOM_INDEX(((Value *)value)->key); if (*bucketPtr == value) { *bucketPtr = ((Value *)value)->hnext; } else { Value *pp; for (pp = *bucketPtr; /*empty*/; pp = pp->hnext) { if (pp == NULL) { return TCL_ERROR; /* Can't find value in hash bucket. */ } if (pp->hnext == value) { pp->hnext = ((Value *)value)->hnext; break; } } } } prevPtr = NULL; for (vp = nodePtr->values; vp != NULL; vp = vp->next) { if (vp == value) { break; } prevPtr = vp; } if (vp == NULL) { return TCL_ERROR; /* Can't find value in list. */ } if (prevPtr == NULL) { nodePtr->values = vp->next; } else { prevPtr->next = vp->next; } nodePtr->nValues--; FreeValue(nodePtr, value); if (nodePtr->nValues < HASH_LOW_WATER) { Blt_Free(nodePtr->valueTable); nodePtr->valueTable = NULL; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TreeDestroyValues -- * * Free up everything associated with a hash table except for the record * for the table itself. * * Results: * None. * * Side effects: * The hash table is no longer useable. * *--------------------------------------------------------------------------- */ static void TreeDestroyValues(Node *nodePtr) { Value *vp; Value *nextPtr; /* Free value hash table. */ if (nodePtr->valueTable != NULL) { Blt_Free(nodePtr->valueTable); } /* Free all the entries in the value list. */ for (vp = nodePtr->values; vp != NULL; vp = nextPtr) { nextPtr = vp->next; FreeValue(nodePtr, vp); } nodePtr->values = NULL; nodePtr->valueTable = NULL; nodePtr->nValues = 0; nodePtr->valueTableSize2 = 0; } /* *--------------------------------------------------------------------------- * * TreeFirstValue -- * * Locate the first entry in a hash table and set up a record that can be * used to step through all the remaining entries of the table. * * Results: * The return value is a pointer to the first value in tablePtr, or NULL * if tablePtr has no entries in it. The memory at *searchPtr is * initialized so that subsequent calls to Blt_Tree_NextValue will return * all of the values in the table, one at a time. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Value * TreeFirstValue( Node *nodePtr, Blt_TreeKeyIterator *iterPtr) /* Place to store information about progress * through the table. */ { iterPtr->node = nodePtr; iterPtr->nextIndex = 0; iterPtr->nextValue = nodePtr->values; return TreeNextValue(iterPtr); } /* *--------------------------------------------------------------------------- * * TreeNextValue -- * * Once a hash table enumeration has been initiated by calling * Blt_Tree_FirstValue, this procedure may be called to return successive * elements of the table. * * Results: * The return value is the next entry in the hash table being enumerated, * or NULL if the end of the table is reached. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Value * TreeNextValue( Blt_TreeKeyIterator *iterPtr) /* Place to store information about progress * through the table. Must have been * initialized by calling * Blt_Tree_FirstValue. */ { Value *valuePtr; valuePtr = iterPtr->nextValue; if (valuePtr != NULL) { iterPtr->nextValue = valuePtr->next; } return valuePtr; } /* *--------------------------------------------------------------------------- * * TreeFindValue -- * * Given a hash table with one-word keys, and a one-word key, find the * entry with a matching key. * * Results: * The return value is a token for the matching entry in the hash table, * or NULL if there was no matching entry. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Value * TreeFindValue( Node *nodePtr, Blt_TreeKey key) /* Key to use to find matching entry. */ { Value *vp; if (nodePtr->valueTable != NULL) { unsigned int downshift; unsigned long mask; Value *bucket; mask = (1 << nodePtr->valueTableSize2) - 1; downshift = DOWNSHIFT_START - nodePtr->valueTableSize2; bucket = nodePtr->valueTable[RANDOM_INDEX(key)]; /* Search all of the entries in the appropriate bucket. */ for (vp = bucket; (vp != NULL) && (vp->key != key); vp = vp->hnext) { /* empty */; } } else { for (vp = nodePtr->values; (vp != NULL) && (vp->key != key); vp = vp->next) { /* empty */; } } return vp; } /* *--------------------------------------------------------------------------- * * TreeCreateValue -- * * Find the value with a matching key. If there is no matching value, * then create a new one. * * Results: * The return value is a pointer to the matching value. If this is a * newly-created value, then *newPtr will be set to a non-zero value; * otherwise *newPtr will be set to 0. * * Side effects: * A new value may be added to the hash table. * *--------------------------------------------------------------------------- */ static Value * TreeCreateValue( Node *nodePtr, Blt_TreeKey key, /* Key to use to find or create matching * entry. */ int *isNewPtr) /* (out) If non-zero, indicates a new hash * entry was created. */ { Value *vp, *prevPtr; prevPtr = NULL; *isNewPtr = FALSE; for (vp = nodePtr->values; vp != NULL; vp = vp->next) { if (vp->key == key) { return vp; } prevPtr = vp; } /* Value not found. Add a new value to the list. */ *isNewPtr = TRUE; vp = Blt_PoolAllocItem(nodePtr->corePtr->valuePool, sizeof(Value)); vp->key = key; vp->owner = NULL; vp->next = NULL; vp->hnext = NULL; vp->objPtr = NULL; if (prevPtr == NULL) { nodePtr->values = vp; } else { prevPtr->next = vp; } nodePtr->nValues++; if (nodePtr->valueTable == NULL) { /* * If we reach a threshold number of values, create a hash table of * values. */ if (nodePtr->nValues > HASH_HIGH_WATER) { MakeValueTable(nodePtr); } } else { Value **bucketPtr; size_t nBuckets; unsigned int downshift; unsigned long mask; nBuckets = (1 << nodePtr->valueTableSize2); mask = nBuckets - 1; downshift = DOWNSHIFT_START - nodePtr->valueTableSize2; bucketPtr = nodePtr->valueTable + RANDOM_INDEX((void *)key); vp->hnext = *bucketPtr; *bucketPtr = vp; /* * If the table has exceeded a decent size, rebuild it with many more * buckets. */ if ((unsigned int)nodePtr->nValues >= (nBuckets * 3)) { RebuildValueTable(nodePtr); } } return vp; } /* *--------------------------------------------------------------------------- * * ParseDumpRecord -- * * Gets the next full record in the dump string, returning the record as * a list. Blank lines and comments are ignored. * * Results: * TCL_RETURN The end of the string is reached. * TCL_ERROR An error occurred and an error message * is left in the interpreter result. * TCL_OK The next record has been successfully parsed. * *--------------------------------------------------------------------------- */ static int ParseDumpRecord( Tcl_Interp *interp, const char **stringPtr, /* (in/out) points to current location in in * dump string. Updated after parsing * record. */ int *argcPtr, /* (out) Will contain the length of the * record's list. */ const char ***argvPtr, /* (out) Will contain the list representing * the dump record of the node. */ RestoreInfo *restorePtr) { char *entry, *eol; char saved; int result; entry = (char *)*stringPtr; /* Get first line, ignoring blank lines and comments. */ for (;;) { char *first; first = NULL; restorePtr->nLines++; /* Find the end of the first line. */ for (eol = entry; (*eol != '\n') && (*eol != '\0'); eol++) { if ((first == NULL) && (!isspace(UCHAR(*eol)))) { first = eol; /* Track first non-whitespace character. */ } } if (first == NULL) { if (*eol == '\0') { return TCL_RETURN; } } else if (*first != '#') { break; /* Not a comment or blank line. */ } entry = eol + 1; } saved = *eol; *eol = '\0'; while (!Tcl_CommandComplete(entry)) { *eol = saved; if (*eol == '\0') { Tcl_AppendResult(interp, "incomplete dump record: \"", entry, "\"", (char *)NULL); return TCL_ERROR; /* Found EOF (incomplete entry) or error. */ } /* Get the next line. */ for (eol = eol + 1; (*eol != '\n') && (*eol != '\0'); eol++) { /*empty*/ } restorePtr->nLines++; saved = *eol; *eol = '\0'; } if (entry == eol) { return TCL_RETURN; } result = Tcl_SplitList(interp, entry, argcPtr, argvPtr); *eol = saved; *stringPtr = eol + 1; return result; } /* *--------------------------------------------------------------------------- * * ReadDumpRecord -- * * Reads the next full record from the given channel, returning the * record as a list. Blank lines and comments are ignored. * * Results: * TCL_RETURN The end of the file has been reached. * TCL_ERROR A read error has occurred and an error message * is left in the interpreter result. * TCL_OK The next record has been successfully parsed. * *--------------------------------------------------------------------------- */ static int ReadDumpRecord( Tcl_Interp *interp, Tcl_Channel channel, /* Channel from which to read the next * record. */ int *argcPtr, /* (out) Will contain the length of the * record's list. */ const char ***argvPtr, /* (out) Will contain the list representing * the dump record of the node. */ RestoreInfo *restorePtr) { int result; Tcl_DString ds; Tcl_DStringInit(&ds); /* Get first line, ignoring blank lines and comments. */ for (;;) { char *cp; int nBytes; Tcl_DStringSetLength(&ds, 0); nBytes = Tcl_Gets(channel, &ds); if (nBytes < 0) { if (Tcl_Eof(channel)) { return TCL_RETURN; } return TCL_ERROR; } restorePtr->nLines++; for (cp = Tcl_DStringValue(&ds); *cp != '\0'; cp++) { if (!isspace(UCHAR(*cp))) { break; } } if ((*cp != '\0') && (*cp != '#')) { break; /* Not a comment or blank line. */ } } Tcl_DStringAppend(&ds, "\n", 1); while (!Tcl_CommandComplete(Tcl_DStringValue(&ds))) { int nBytes; if (Tcl_Eof(channel)) { Tcl_AppendResult(interp, "unexpected EOF: short record.", (char *)NULL); Tcl_DStringFree(&ds); return TCL_ERROR; /* Found EOF (incomplete entry) or error. */ } /* Process additional lines if needed */ nBytes = Tcl_Gets(channel, &ds); if (nBytes < 0) { Tcl_AppendResult(interp, "read error: ", Tcl_PosixError(interp), (char *)NULL); Tcl_DStringFree(&ds); return TCL_ERROR; /* Found EOF (incomplete entry) or error. */ } restorePtr->nLines++; Tcl_DStringAppend(&ds, "\n", 1); } result = Tcl_SplitList(interp, Tcl_DStringValue(&ds), argcPtr, argvPtr); Tcl_DStringFree(&ds); return result; } static Tcl_Obj * GetStringObj(RestoreInfo *restorePtr, const char *string, int length) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&restorePtr->dataTable, string, &isNew); if (isNew) { Tcl_Obj *objPtr; if (length == -1) { length = strlen(string); } objPtr = Tcl_NewStringObj(string, length); Blt_SetHashValue(hPtr, objPtr); return objPtr; } return Blt_GetHashValue(hPtr); } static int RestoreValues( RestoreInfo *restorePtr, Tcl_Interp *interp, Node *nodePtr, int nValues, const char **values) { int i; for (i = 0; i < nValues; i += 2) { Tcl_Obj *valueObjPtr; int result; if ((i + 1) < nValues) { valueObjPtr = GetStringObj(restorePtr, values[i + 1], -1); } else { valueObjPtr = Tcl_NewStringObj("", -1); } Tcl_IncrRefCount(valueObjPtr); result = Blt_Tree_SetValue(interp, restorePtr->treePtr, nodePtr, values[i], valueObjPtr); Tcl_DecrRefCount(valueObjPtr); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int RestoreTags( Tree *treePtr, Node *nodePtr, int nTags, const char **tags) { int i; for (i = 0; i < nTags; i++) { Blt_Tree_AddTag(treePtr, nodePtr, tags[i]); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RestoreNode5 -- * * Parses and creates a node based upon the first 3 fields of a five * field entry. This is the new restore file format. * * parentId nodeId pathList dataList tagList ?attrList? * * The purpose is to attempt to save and restore the node ids embedded in * the restore file information. The old format could not distinquish * between two sibling nodes with the same label unless they were both * leaves. I'm trying to avoid dependencies upon labels. * * If you're starting from an empty tree, this obviously should work * without a hitch. We only need to map the file's root id to 0. It's a * little more complicated when adding node to an already full tree. * * First see if the node id isn't already in use. Otherwise, map the * node id (via a hashtable) to the real node. We'll need it later when * subsequent entries refer to their parent id. * * If a parent id is unknown (the restore file may be out of order), then * follow plan B and use its path. * *--------------------------------------------------------------------------- */ static int RestoreNode5( Tcl_Interp *interp, int argc, /* Not used. */ const char **argv, RestoreInfo *restorePtr) { Tree *treePtr; Blt_HashEntry *hPtr; Node *nodePtr, *parentPtr; int isNew; long pid, id; const char **attrs, **tags, **values, **names; int nTags, nValues, nNames; treePtr = restorePtr->treePtr; /* * The second and first fields respectively are the ids of the node and * its parent. The parent id of the root node is always -1. */ if ((Tcl_GetLong(interp, argv[0], &pid) != TCL_OK) || (Tcl_GetLong(interp, argv[1], &id) != TCL_OK)) { return TCL_ERROR; } names = values = tags = attrs = NULL; nodePtr = NULL; /* * The third, fourth, and fifth fields respectively are the list of * component names representing the path to the node including the name of * the node, a key-value list of data values, and a list of tag names. */ if ((Tcl_SplitList(interp, argv[2], &nNames, &names) != TCL_OK) || (Tcl_SplitList(interp, argv[3], &nValues, &values) != TCL_OK) || (Tcl_SplitList(interp, argv[4], &nTags, &tags) != TCL_OK)) { goto error; } /* Get the parent of the node. */ if (pid == -1) { /* Map -1 id to the root node of the subtree. */ nodePtr = restorePtr->rootPtr; hPtr = Blt_CreateHashEntry(&restorePtr->idTable, (char *)id, &isNew); Blt_SetHashValue(hPtr, nodePtr); Blt_Tree_RelabelNode(treePtr, nodePtr, names[0]); } else { /* * Check if the parent has been mapped to another id in the tree. * This can happen when there's a id collision with an existing node. */ hPtr = Blt_FindHashEntry(&restorePtr->idTable, (char *)pid); if (hPtr != NULL) { parentPtr = Blt_GetHashValue(hPtr); } else { parentPtr = Blt_Tree_GetNode(treePtr, pid); if (parentPtr == NULL) { /* * Normally the parent node should already exist in the tree, * but in a partial restore it might not. "Plan B" is to use * the list of path components to create the missing * components, including the parent. */ if (nNames == 0) { parentPtr = restorePtr->rootPtr; } else { int i; for (i = 1; i < (nNames - 2); i++) { nodePtr = Blt_Tree_FindChild(parentPtr, names[i]); if (nodePtr == NULL) { nodePtr = Blt_Tree_CreateNode(treePtr, parentPtr, names[i], -1); } parentPtr = nodePtr; } /* * If there's a node with the same label as the parent, * we'll use that node. Otherwise, try to create a new * node with the desired parent id. */ nodePtr = Blt_Tree_FindChild(parentPtr, names[nNames - 2]); if (nodePtr == NULL) { nodePtr = Blt_Tree_CreateNodeWithId(treePtr, parentPtr, names[nNames - 2], pid, -1); if (nodePtr == NULL) { goto error; } } parentPtr = nodePtr; } } } /* * It's an error if the desired id has already been remapped. That * means there were two nodes in the dump with the same id. */ hPtr = Blt_FindHashEntry(&restorePtr->idTable, (char *)id); if (hPtr != NULL) { Tcl_AppendResult(interp, "node \"", Blt_Ltoa(id), "\" has already been restored", (char *)NULL); goto error; } if (restorePtr->flags & TREE_RESTORE_OVERWRITE) { /* Can you find the child by name. */ nodePtr = Blt_Tree_FindChild(parentPtr, names[nNames - 1]); if (nodePtr != NULL) { hPtr = Blt_CreateHashEntry(&restorePtr->idTable, (char *)id, &isNew); Blt_SetHashValue(hPtr, nodePtr); } } if (nodePtr == NULL) { nodePtr = Blt_Tree_GetNode(treePtr, id); if (nodePtr == NULL) { nodePtr = Blt_Tree_CreateNodeWithId(treePtr, parentPtr, names[nNames - 1], id, -1); } else { nodePtr = Blt_Tree_CreateNode(treePtr, parentPtr, names[nNames - 1], -1); hPtr = Blt_CreateHashEntry(&restorePtr->idTable, (char *)id, &isNew); Blt_SetHashValue(hPtr, nodePtr); } } } if (nodePtr == NULL) { goto error; /* Couldn't create node with requested id. */ } Blt_Free(names); names = NULL; /* Values */ if (RestoreValues(restorePtr, interp, nodePtr, nValues, values) != TCL_OK) { goto error; } Blt_Free(values); values = NULL; /* Tags */ if (!(restorePtr->flags & TREE_RESTORE_NO_TAGS)) { RestoreTags(treePtr, nodePtr, nTags, tags); } Blt_Free(tags); tags = NULL; return TCL_OK; error: if (attrs != NULL) { Blt_Free(attrs); } if (tags != NULL) { Blt_Free(tags); } if (values != NULL) { Blt_Free(values); } if (names != NULL) { Blt_Free(names); } if (nodePtr != NULL) { Blt_Tree_DeleteNode(treePtr, nodePtr); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * RestoreNode3 -- * * Parses and creates a node based upon the first field of a three field * entry. This is the old restore file format. * * pathList dataList tagList * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RestoreNode3( Tcl_Interp *interp, int argc, /* Not used. */ const char **argv, RestoreInfo *restorePtr) { Tree *treePtr; Node *nodePtr, *parentPtr; int i; const char **names, **values, **tags; int nNames, nValues, nTags; /* The first field is a list of component names representing the path to * the node, including the name of the node. */ if (Tcl_SplitList(interp, argv[0], &nNames, &names) != TCL_OK) { return TCL_ERROR; } nodePtr = parentPtr = restorePtr->rootPtr; treePtr = restorePtr->treePtr; /* Automatically create ancestor nodes as needed. */ for (i = 0; i < (nNames - 1); i++) { nodePtr = Blt_Tree_FindChild(parentPtr, names[i]); if (nodePtr == NULL) { nodePtr = Blt_Tree_CreateNode(treePtr, parentPtr, names[i], -1); } parentPtr = nodePtr; } if (nNames > 0) { /* * By default duplicate nodes (two sibling nodes with the same label) * unless the -overwrite switch was given. */ nodePtr = NULL; if (restorePtr->flags & TREE_RESTORE_OVERWRITE) { nodePtr = Blt_Tree_FindChild(parentPtr, names[i]); } if (nodePtr == NULL) { nodePtr = Blt_Tree_CreateNode(treePtr, parentPtr, names[i], -1); } } Blt_Free(names); /* The second field is a key-value list of the node's values. */ if (Tcl_SplitList(interp, argv[1], &nValues, &values) != TCL_OK) { return TCL_ERROR; } if (RestoreValues(restorePtr, interp, nodePtr, nValues, values) != TCL_OK) { goto error; } Blt_Free(values); /* The third field is a list of tags. */ if (!(restorePtr->flags & TREE_RESTORE_NO_TAGS)) { /* Parse the tag list. */ if (Tcl_SplitList(interp, argv[2], &nTags, &tags) != TCL_OK) { goto error; } RestoreTags(treePtr, nodePtr, nTags, tags); Blt_Free(tags); } return TCL_OK; error: Blt_Free(argv); Blt_Tree_DeleteNode(treePtr, nodePtr); return TCL_ERROR; } /* Public Routines */ /* *--------------------------------------------------------------------------- * * Blt_Tree_GetKey -- * * Given a string, returns a unique identifier for the string. * *--------------------------------------------------------------------------- */ Blt_TreeKey Blt_Tree_GetKey(Tree *treePtr, const char *string) /* String to convert. */ { Blt_HashEntry *hPtr; int isNew; Blt_HashTable *tablePtr; tablePtr = &treePtr->corePtr->dataPtr->keyTable; hPtr = Blt_CreateHashEntry(tablePtr, string, &isNew); return (Blt_TreeKey)Blt_GetHashKey(tablePtr, hPtr); } /* *--------------------------------------------------------------------------- * * Blt_Tree_GetKeyFromNode -- * * Given a string, returns a unique identifier for the string. * *--------------------------------------------------------------------------- */ Blt_TreeKey Blt_Tree_GetKeyFromNode(Node *nodePtr, const char *string) { Blt_HashEntry *hPtr; int isNew; Blt_HashTable *tablePtr; tablePtr = &nodePtr->corePtr->dataPtr->keyTable; hPtr = Blt_CreateHashEntry(tablePtr, string, &isNew); return (Blt_TreeKey)Blt_GetHashKey(tablePtr, hPtr); } /* *--------------------------------------------------------------------------- * * Blt_Tree_GetKeyFromInterp -- * * Given a string, returns a unique identifier for the string. * *--------------------------------------------------------------------------- */ Blt_TreeKey Blt_Tree_GetKeyFromInterp(Tcl_Interp *interp, const char *string) { Blt_HashEntry *hPtr; TreeInterpData *dataPtr; int isNew; dataPtr = Blt_Tree_GetInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->keyTable, string, &isNew); return (Blt_TreeKey)Blt_GetHashKey(&dataPtr->keyTable, hPtr); } /* *--------------------------------------------------------------------------- * * Blt_Tree_CreateNode -- * * Creates a new node in the given parent node. The name and position in * the parent are also provided. * *--------------------------------------------------------------------------- */ Blt_TreeNode Blt_Tree_CreateNode( Tree *treePtr, /* The tree client that is creating this node. * If NULL, indicates to trigger notify events * on behalf of the initiating client also. */ Node *parentPtr, /* Parent node where the new node will be * inserted. */ const char *name, /* Name of node. */ long position) /* Position in the parent's list of children * where to insert the new node. */ { Blt_HashEntry *hPtr; Node *beforePtr; Node *nodePtr; /* Node to be inserted. */ TreeObject *corePtr; long inode; int isNew; corePtr = parentPtr->corePtr; /* Generate an unique serial number for this node. */ do { inode = corePtr->nextInode++; hPtr = Blt_CreateHashEntry(&corePtr->nodeTable,(char *)inode, &isNew); } while (!isNew); nodePtr = NewNode(corePtr, name, inode); Blt_SetHashValue(hPtr, nodePtr); if ((position == -1) || ((size_t)position >= parentPtr->nChildren)) { beforePtr = NULL; } else { beforePtr = parentPtr->first; while ((position > 0) && (beforePtr != NULL)) { position--; beforePtr = beforePtr->next; } } LinkBefore(parentPtr, nodePtr, beforePtr); nodePtr->depth = parentPtr->depth + 1; /* * Issue callbacks to each client indicating that a new node has been * created. */ NotifyClients(treePtr, corePtr, nodePtr, TREE_NOTIFY_CREATE); return nodePtr; } /* *--------------------------------------------------------------------------- * * Blt_Tree_CreateNodeWithId -- * * Like Blt_Tree_CreateNode, but provides a specific id to use for the * node. If the tree already contains a node by that id, NULL is * returned. * *--------------------------------------------------------------------------- */ Blt_TreeNode Blt_Tree_CreateNodeWithId( Tree *treePtr, Node *parentPtr, /* Parent node where the new node will be * inserted. */ const char *name, /* Name of node. */ long inode, /* Requested id of the new node. If a node by * this id already exists in the tree, no node * is created. */ long position) /* Position in the parent's list of children * where to insert the new node. */ { Blt_HashEntry *hPtr; Node *beforePtr; Node *nodePtr; /* Node to be inserted. */ TreeObject *corePtr; int isNew; corePtr = parentPtr->corePtr; hPtr = Blt_CreateHashEntry(&corePtr->nodeTable, (char *)inode, &isNew); if (!isNew) { return NULL; } nodePtr = NewNode(corePtr, name, inode); Blt_SetHashValue(hPtr, nodePtr); if ((position == -1) || ((size_t)position >= parentPtr->nChildren)) { beforePtr = NULL; } else { beforePtr = parentPtr->first; while ((position > 0) && (beforePtr != NULL)) { position--; beforePtr = beforePtr->next; } } LinkBefore(parentPtr, nodePtr, beforePtr); nodePtr->depth = parentPtr->depth + 1; /* * Issue callbacks to each client indicating that a new node has been * created. */ NotifyClients(treePtr, corePtr, nodePtr, TREE_NOTIFY_CREATE); return nodePtr; } /* *--------------------------------------------------------------------------- * * Blt_Tree_MoveNode -- * * Move an entry into a new location in the hierarchy. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_Tree_MoveNode(Tree *treePtr, Node *nodePtr, Node *parentPtr, Node *beforePtr) { TreeObject *corePtr = nodePtr->corePtr; size_t newDepth; if (nodePtr == beforePtr) { return TCL_ERROR; } if ((beforePtr != NULL) && (beforePtr->parent != parentPtr)) { return TCL_ERROR; } if (nodePtr->parent == NULL) { return TCL_ERROR; /* Can't move root. */ } /* Verify that the node isn't an ancestor of the new parent. */ if (Blt_Tree_IsAncestor(nodePtr, parentPtr)) { return TCL_ERROR; } UnlinkNode(nodePtr); /* Relink the node as a child of the new parent. */ LinkBefore(parentPtr, nodePtr, beforePtr); newDepth = parentPtr->depth + 1; if (nodePtr->depth != newDepth) { /* Recursively reset the depths of all descendant nodes. */ ResetDepths(nodePtr, newDepth); } /* * Issue callbacks to each client indicating that a node has been moved. */ NotifyClients(treePtr, corePtr, nodePtr, TREE_NOTIFY_MOVE); return TCL_OK; } int Blt_Tree_DeleteNode(Tree *treePtr, Node *nodePtr) { TreeObject *corePtr = nodePtr->corePtr; Node *np, *nextPtr; /* In depth-first order, delete each descendant node. */ for (np = nodePtr->first; np != NULL; np = nextPtr) { nextPtr = np->next; Blt_Tree_DeleteNode(treePtr, np); } /* * Issue callbacks to each client indicating that the node can no longer * be used. */ NotifyClients(treePtr, corePtr, nodePtr, TREE_NOTIFY_DELETE); /* Now remove the actual node. */ FreeNode(corePtr, nodePtr); return TCL_OK; } Blt_TreeNode Blt_Tree_GetNode(Tree *treePtr, long inode) { TreeObject *corePtr = treePtr->corePtr; Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&corePtr->nodeTable, (char *)inode); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return NULL; } Blt_TreeTrace Blt_Tree_CreateTrace(Tree *treePtr, Node *nodePtr, const char *keyPattern, const char *tagName, unsigned int mask, Blt_TreeTraceProc *proc, ClientData clientData) { TraceHandler *tracePtr; tracePtr = Blt_AssertCalloc(1, sizeof (TraceHandler)); tracePtr->link = Blt_Chain_Append(treePtr->traces, tracePtr); if (keyPattern != NULL) { tracePtr->keyPattern = Blt_AssertStrdup(keyPattern); } if (tagName != NULL) { tracePtr->withTag = Blt_AssertStrdup(tagName); } tracePtr->treePtr = treePtr; tracePtr->proc = proc; tracePtr->clientData = clientData; tracePtr->mask = mask; tracePtr->nodePtr = nodePtr; tracePtr->interp = treePtr->interp; Blt_InitHashTable(&tracePtr->idleTable, sizeof(TraceWhenIdle)/sizeof(int)); return (Blt_TreeTrace)tracePtr; } void Blt_Tree_DeleteTrace(Blt_TreeTrace trace) { TraceHandler *tracePtr = (TraceHandler *)trace; Blt_Chain_DeleteLink(tracePtr->treePtr->traces, tracePtr->link); if (tracePtr->keyPattern != NULL) { Blt_Free(tracePtr->keyPattern); } if (tracePtr->withTag != NULL) { Blt_Free(tracePtr->withTag); } Blt_Free(tracePtr); } void Blt_Tree_RelabelNodeWithoutNotify(Node *nodePtr, const char *string) { Blt_TreeKey oldLabel; Node **bucketPtr; Node *parentPtr; Node *np; unsigned int downshift; unsigned long mask; oldLabel = nodePtr->label; nodePtr->label = Blt_Tree_GetKeyFromNode(nodePtr, string); parentPtr = nodePtr->parent; if ((parentPtr == NULL) || (parentPtr->nodeTable == NULL)) { return; /* Root node. */ } /* Changing the node's name requires that we rehash the node in the * parent's table of children. */ mask = (1 << parentPtr->nodeTableSize2) - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; bucketPtr = parentPtr->nodeTable + RANDOM_INDEX(oldLabel); if (*bucketPtr == nodePtr) { *bucketPtr = nodePtr->hnext; } else { for (np = *bucketPtr; /*empty*/; np = np->hnext) { if (np == NULL) { return; /* Can't find node in hash bucket. */ } if (np->hnext == nodePtr) { np->hnext = nodePtr->hnext; break; } } } bucketPtr = parentPtr->nodeTable + RANDOM_INDEX(nodePtr->label); nodePtr->hnext = *bucketPtr; *bucketPtr = nodePtr; } void Blt_Tree_RelabelNode(Tree *treePtr, Node *nodePtr, const char *string) { Blt_Tree_RelabelNodeWithoutNotify(nodePtr, string); NotifyClients(treePtr, treePtr->corePtr, nodePtr, TREE_NOTIFY_RELABEL); } /* *--------------------------------------------------------------------------- * * Blt_Tree_FindChild -- * * Searches for the named node in a parent's chain of siblings. * * * Results: * If found, the child node is returned, otherwise NULL. * *--------------------------------------------------------------------------- */ Blt_TreeNode Blt_Tree_FindChild(Node *parentPtr, const char *string) { Blt_TreeKey key; Node *np; key = Blt_Tree_GetKeyFromNode(parentPtr, string); if (parentPtr->nodeTable != NULL) { unsigned int downshift; unsigned long mask; Node *bucket; mask = (1 << parentPtr->nodeTableSize2) - 1; downshift = DOWNSHIFT_START - parentPtr->nodeTableSize2; bucket = parentPtr->nodeTable[RANDOM_INDEX(key)]; /* Search all of the entries in the appropriate bucket. */ for (np = bucket; np != NULL; np = np->hnext) { if (key == np->label) { return np; } } } else { for (np = parentPtr->first; np != NULL; np = np->next) { if (key == np->label) { return np; } } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Tree_NodePosition -- * * Returns the position of the node in its parent's list of children. * The root's position is 0. * *--------------------------------------------------------------------------- */ long Blt_Tree_NodePosition(Node *nodePtr) { Node *parentPtr; long count; count = 0; parentPtr = nodePtr->parent; if (parentPtr != NULL) { Node *np; for (np = parentPtr->first; np != NULL; np = np->next) { if (nodePtr == np) { break; } count++; } } return count; } Blt_TreeNode Blt_Tree_FirstChild(Node *parentPtr) { return parentPtr->first; } Blt_TreeNode Blt_Tree_LastChild(Node *parentPtr) { return parentPtr->last; } /* *--------------------------------------------------------------------------- * * Blt_Tree_PrevNode -- * * Returns the "previous" node in the tree. This node (in depth-first * order) is its parent, if the node has no siblings that are previous to * it. Otherwise it is the last descendant of the last sibling. In this * case, descend the sibling's hierarchy, using the last child at any * ancestor, with we we find a leaf. * *--------------------------------------------------------------------------- */ Blt_TreeNode Blt_Tree_PrevNode( Node *rootPtr, /* Root of subtree. If NULL, indicates the * tree's root. */ Node *nodePtr) /* Current node in subtree. */ { Node *prevPtr; if (rootPtr == NULL) { rootPtr = nodePtr->corePtr->root; } if (nodePtr == rootPtr) { return NULL; /* The root is the first node. */ } prevPtr = nodePtr->prev; if (prevPtr == NULL) { /* There are no siblings previous to this one, so pick the parent. */ return nodePtr->parent; } /* * Traverse down the right-most thread, in order to select the next entry. * Stop when we reach a leaf. */ nodePtr = prevPtr; while ((prevPtr = nodePtr->last) != NULL) { nodePtr = prevPtr; } return nodePtr; } /* *--------------------------------------------------------------------------- * * Blt_Tree_NextNode -- * * Returns the "next" node in relation to the given node. The next node * (in depth-first order) is either the first child of the given node the * next sibling if the node has no children (the node is a leaf). If the * given node is the last sibling, then try it's parent next sibling. * Continue until we either find a next sibling for some ancestor or we * reach the root node. In this case the current node is the last node * in the tree. * *--------------------------------------------------------------------------- */ Blt_TreeNode Blt_Tree_NextNode( Node *rootPtr, /* Root of subtree. If NULL, indicates the * tree's root. */ Node *nodePtr) /* Current node in subtree. */ { Node *nextPtr; /* Pick the first sub-node. */ nextPtr = nodePtr->first; if (nextPtr != NULL) { return nextPtr; } /* * Back up until we can find a level where we can pick a "next sibling". * For the last entry we'll thread our way back to the root. */ if (rootPtr == NULL) { rootPtr = nodePtr->corePtr->root; } while (nodePtr != rootPtr) { nextPtr = nodePtr->next; if (nextPtr != NULL) { return nextPtr; } nodePtr = nodePtr->parent; } return NULL; /* At root, no next node. */ } int Blt_Tree_IsBefore(Node *n1Ptr, Node *n2Ptr) { long depth; long i; Node *nodePtr; if (n1Ptr == n2Ptr) { return FALSE; } depth = MIN(n1Ptr->depth, n2Ptr->depth); if (depth == 0) { /* One of the nodes is root. */ return (n1Ptr->parent == NULL); } /* * Traverse back from the deepest node, until both nodes are at the same * depth. Check if this ancestor node is the same for both nodes. */ for (i = n1Ptr->depth; i > depth; i--) { n1Ptr = n1Ptr->parent; } if (n1Ptr == n2Ptr) { return FALSE; } for (i = n2Ptr->depth; i > depth; i--) { n2Ptr = n2Ptr->parent; } if (n2Ptr == n1Ptr) { return TRUE; } /* * First find the mutual ancestor of both nodes. Look at each preceding * ancestor level-by-level for both nodes. Eventually we'll find a node * that's the parent of both ancestors. Then find the first ancestor in * the parent's list of subnodes. */ for (i = depth; i > 0; i--) { if (n1Ptr->parent == n2Ptr->parent) { break; } n1Ptr = n1Ptr->parent; n2Ptr = n2Ptr->parent; } for (nodePtr = n1Ptr->parent->first; nodePtr != NULL; nodePtr = nodePtr->next) { if (nodePtr == n1Ptr) { return TRUE; } else if (nodePtr == n2Ptr) { return FALSE; } } return FALSE; } /* *--------------------------------------------------------------------------- * * TraceIdleProc -- * * Used to invoke event handler routines at some idle point. This * routine is called from the TCL event loop. Errors generated by the * event handler routines are backgrounded. * * Results: * None. * *--------------------------------------------------------------------------- */ static void TraceIdleProc(ClientData clientData) { Blt_HashEntry *hashPtr = clientData; TraceWhenIdle *idlePtr; TraceHandler *tracePtr; int result; Node *nodePtr; Tcl_Interp *interp; Blt_TreeKey key; int flags; idlePtr = Blt_GetHashValue(hashPtr); tracePtr = idlePtr->tracePtr; interp = idlePtr->interp; /* Get the node from the inode since the node may be been deleted in the * time between the idle proc was issued and invoked. */ nodePtr = Blt_Tree_GetNode(tracePtr->treePtr, idlePtr->inode); if (nodePtr != NULL) { key = idlePtr->key; flags = idlePtr->flags; Blt_DeleteHashEntry(&tracePtr->idleTable, hashPtr); result = (*tracePtr->proc) (tracePtr->clientData, interp, nodePtr, key, flags); if (result != TCL_OK) { Tcl_BackgroundError(interp); } nodePtr->flags &= ~TREE_TRACE_ACTIVE; } } static void CallTraces( Tcl_Interp *interp, Tree *sourcePtr, /* Client holding a reference to the tree. If * NULL, indicates to execute all handlers, * including those of the caller. */ TreeObject *corePtr, /* Tree that was changed. */ Node *nodePtr, /* Node that received the event. */ Blt_TreeKey key, unsigned int flags) { Tree *treePtr; for(treePtr = FirstClient(corePtr); treePtr != NULL; treePtr = NextClient(treePtr)) { Blt_ChainLink link; for(link = Blt_Chain_FirstLink(treePtr->traces); link != NULL; link = Blt_Chain_NextLink(link)) { TraceHandler *tracePtr; tracePtr = Blt_Chain_GetValue(link); if ((tracePtr->keyPattern != NULL) && (!Tcl_StringMatch(key, tracePtr->keyPattern))) { continue; /* Key pattern doesn't match. */ } if ((tracePtr->withTag != NULL) && (!Blt_Tree_HasTag(treePtr, nodePtr, tracePtr->withTag))) { continue; /* Doesn't have the tag. */ } if ((tracePtr->mask & flags) == 0) { continue; /* Flags don't match. */ } if ((treePtr == sourcePtr) && (tracePtr->mask & TREE_TRACE_FOREIGN_ONLY)) { continue; /* This client initiated the trace. */ } if ((tracePtr->nodePtr != NULL) && (tracePtr->nodePtr != nodePtr)) { continue; /* Nodes don't match. */ } if (tracePtr->mask & TREE_TRACE_WHENIDLE) { TraceWhenIdle idle; int isNew; Blt_HashEntry *hPtr; memset(&idle, 0, sizeof(idle)); idle.interp = sourcePtr->interp; idle.tracePtr = tracePtr; idle.key = key; idle.flags = flags; idle.inode = nodePtr->inode; hPtr = Blt_CreateHashEntry(&tracePtr->idleTable, (char *)&idle, &isNew); if (isNew) { Blt_SetHashValue(hPtr, Blt_GetHashKey(&tracePtr->idleTable, hPtr)); Tcl_DoWhenIdle(TraceIdleProc, hPtr); } } else { nodePtr->flags |= TREE_TRACE_ACTIVE; if ((*tracePtr->proc) (tracePtr->clientData, sourcePtr->interp, nodePtr, key, flags) != TCL_OK) { if (interp != NULL) { Tcl_BackgroundError(interp); } } nodePtr->flags &= ~TREE_TRACE_ACTIVE; } } } } static Value * GetTreeValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, Blt_TreeKey key) { Value *valuePtr; valuePtr = TreeFindValue(nodePtr, key); if (valuePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find field \"", key, "\"", (char *)NULL); } return NULL; } if ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't access private field \"", key, "\"", (char *)NULL); } return NULL; } return valuePtr; } int Blt_Tree_PrivateValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, Blt_TreeKey key) { Value *valuePtr; valuePtr = TreeFindValue(nodePtr, key); if (valuePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find field \"", key, "\".", (char *)NULL); } return TCL_ERROR; } valuePtr->owner = treePtr; return TCL_OK; } int Blt_Tree_PublicValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, Blt_TreeKey key) { Value *valuePtr; valuePtr = TreeFindValue(nodePtr, key); if (valuePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find field \"", key, "\"", (char *)NULL); } return TCL_ERROR; } if (valuePtr->owner != treePtr) { if (interp != NULL) { Tcl_AppendResult(interp, "not the owner of \"", key, "\"", (char *)NULL); } return TCL_ERROR; } valuePtr->owner = NULL; return TCL_OK; } int Blt_Tree_ValueExistsByKey(Tree *treePtr, Node *nodePtr, Blt_TreeKey key) { Value *valuePtr; valuePtr = GetTreeValue((Tcl_Interp *)NULL, treePtr, nodePtr, key); if (valuePtr == NULL) { return FALSE; } return TRUE; } int Blt_Tree_GetValueByKey(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, Blt_TreeKey key, Tcl_Obj **valueObjPtrPtr) { Value *valuePtr; TreeObject *corePtr = nodePtr->corePtr; valuePtr = GetTreeValue(interp, treePtr, nodePtr, key); if (valuePtr == NULL) { return TCL_ERROR; } *valueObjPtrPtr = valuePtr->objPtr; if (!(nodePtr->flags & TREE_TRACE_ACTIVE)) { CallTraces(interp, treePtr, corePtr, nodePtr, key, TREE_TRACE_READ); } return TCL_OK; } int Blt_Tree_SetValueByKey( Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, /* Node to be updated. */ Blt_TreeKey key, /* Identifies the field key. */ Tcl_Obj *valueObjPtr) /* New value of field. */ { TreeObject *corePtr = nodePtr->corePtr; Value *valuePtr; int isNew; unsigned int flags; if (valueObjPtr == NULL) { return Blt_Tree_UnsetValueByKey(interp, treePtr, nodePtr, key); } valuePtr = TreeCreateValue(nodePtr, key, &isNew); if ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't set private field \"", key, "\"", (char *)NULL); } return TCL_ERROR; } if (valueObjPtr != valuePtr->objPtr) { Tcl_IncrRefCount(valueObjPtr); if (valuePtr->objPtr != NULL) { Tcl_DecrRefCount(valuePtr->objPtr); } valuePtr->objPtr = valueObjPtr; } flags = TREE_TRACE_WRITE; if (isNew) { flags |= TREE_TRACE_CREATE; } if (!(nodePtr->flags & TREE_TRACE_ACTIVE)) { CallTraces(interp, treePtr, corePtr, nodePtr, valuePtr->key, flags); } return TCL_OK; } int Blt_Tree_UnsetValueByKey( Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, /* Node to be updated. */ Blt_TreeKey key) /* Name of field in node. */ { TreeObject *corePtr = nodePtr->corePtr; Value *valuePtr; valuePtr = TreeFindValue(nodePtr, key); if (valuePtr == NULL) { return TCL_OK; /* It's okay to unset values that don't exist * in the node. */ } if ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't unset private field \"", key, "\"", (char *)NULL); } return TCL_ERROR; } TreeDeleteValue(nodePtr, valuePtr); CallTraces(interp, treePtr, corePtr, nodePtr, key, TREE_TRACE_UNSET); return TCL_OK; } static int ParseParentheses(Tcl_Interp *interp, const char *string, char **leftPtr, char **rightPtr) { char *p; char *left, *right; left = right = NULL; for (p = (char *)string; *p != '\0'; p++) { if (*p == '(') { left = p; } else if (*p == ')') { right = p; } } if (left != right) { if (((left != NULL) && (right == NULL)) || ((left == NULL) && (right != NULL)) || (left > right) || (right != (p - 1))) { if (interp != NULL) { Tcl_AppendResult(interp, "bad array specification \"", string, "\"", (char *)NULL); } return TCL_ERROR; } } *leftPtr = left; *rightPtr = right; return TCL_OK; } static Tree * NewTree(TreeInterpData *dataPtr, TreeObject *corePtr, const char *qualName) { Tree *treePtr; int isNew; treePtr = Blt_Calloc(1, sizeof(Tree)); if (treePtr == NULL) { return NULL; } treePtr->magic = TREE_MAGIC; treePtr->interp = dataPtr->interp; /* Add client to table object's list of clients. */ treePtr->link = Blt_Chain_Append(corePtr->clients, treePtr); treePtr->corePtr = corePtr; treePtr->root = corePtr->root; /* By default, use own sets of tags. */ Blt_Tree_NewTagTable(treePtr); treePtr->hPtr = Blt_CreateHashEntry(&dataPtr->treeTable, qualName, &isNew); Blt_SetHashValue(treePtr->hPtr, treePtr); treePtr->name = Blt_GetHashKey(&dataPtr->treeTable, treePtr->hPtr); treePtr->events = Blt_Chain_Create(); treePtr->traces = Blt_Chain_Create(); return treePtr; } static const char * MakeTreeName(TreeInterpData *dataPtr, char *string) { /* Generate a unique tree name in the current namespace. */ do { sprintf_s(string, 200, "tree%d", dataPtr->nextId++); } while (GetTree(dataPtr, string, NS_SEARCH_CURRENT) != NULL); return string; } /* *--------------------------------------------------------------------------- * * ShareTagTable -- * *--------------------------------------------------------------------------- */ static void ShareTagTable(Tree *sourcePtr, Tree *targetPtr) { sourcePtr->tagTablePtr->refCount++; if (targetPtr->tagTablePtr != NULL) { ReleaseTagTable(targetPtr->tagTablePtr); } targetPtr->tagTablePtr = sourcePtr->tagTablePtr; } int Blt_Tree_GetValue( Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, const char *string, /* String identifying the field in node. */ Tcl_Obj **valueObjPtrPtr) { char *left, *right; int result; if (ParseParentheses(interp, string, &left, &right) != TCL_OK) { return TCL_ERROR; } if (left != NULL) { *left = *right = '\0'; result = Blt_Tree_GetArrayValue(interp, treePtr, nodePtr, string, left + 1, valueObjPtrPtr); *left = '(', *right = ')'; } else { result = Blt_Tree_GetValueByKey(interp, treePtr, nodePtr, Blt_Tree_GetKey(treePtr, string), valueObjPtrPtr); } return result; } int Blt_Tree_SetValue( Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, /* Node to be updated. */ const char *string, /* String identifying the field in node. */ Tcl_Obj *valueObjPtr) /* New value of field. If NULL, field is * deleted. */ { char *left, *right; int result; if (ParseParentheses(interp, string, &left, &right) != TCL_OK) { return TCL_ERROR; } if (left != NULL) { *left = *right = '\0'; result = Blt_Tree_SetArrayValue(interp, treePtr, nodePtr, string, left + 1, valueObjPtr); *left = '(', *right = ')'; } else { result = Blt_Tree_SetValueByKey(interp, treePtr, nodePtr, Blt_Tree_GetKey(treePtr, string), valueObjPtr); } return result; } int Blt_Tree_UnsetValue( Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, /* Node to be updated. */ const char *string) /* String identifying the field in node. */ { char *left, *right; int result; if (ParseParentheses(interp, string, &left, &right) != TCL_OK) { return TCL_ERROR; } if (left != NULL) { *left = *right = '\0'; result = Blt_Tree_UnsetArrayValue(interp, treePtr, nodePtr, string, left + 1); *left = '(', *right = ')'; } else { result = Blt_Tree_UnsetValueByKey(interp, treePtr, nodePtr, Blt_Tree_GetKey(treePtr, string)); } return result; } int Blt_Tree_ValueExists(Tree *treePtr, Node *nodePtr, const char *string) { char *left, *right; int result; if (ParseParentheses((Tcl_Interp *)NULL, string, &left, &right) != TCL_OK) { return FALSE; } if (left != NULL) { *left = *right = '\0'; result = Blt_Tree_ArrayValueExists(treePtr, nodePtr, string, left + 1); *left = '(', *right = ')'; } else { result = Blt_Tree_ValueExistsByKey(treePtr, nodePtr, Blt_Tree_GetKey(treePtr, string)); } return result; } Blt_TreeKey Blt_Tree_FirstKey(Tree *treePtr, Node *nodePtr, Blt_TreeKeyIterator *iterPtr) { Value *valuePtr; valuePtr = TreeFirstValue(nodePtr, iterPtr); if (valuePtr == NULL) { return NULL; } while ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { valuePtr = TreeNextValue(iterPtr); if (valuePtr == NULL) { return NULL; } } return valuePtr->key; } Blt_TreeKey Blt_Tree_NextKey(Tree *treePtr, Blt_TreeKeyIterator *iterPtr) { Value *valuePtr; valuePtr = TreeNextValue(iterPtr); if (valuePtr == NULL) { return NULL; } while ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { valuePtr = TreeNextValue(iterPtr); if (valuePtr == NULL) { return NULL; } } return valuePtr->key; } int Blt_Tree_IsAncestor(Node *n1Ptr, Node *n2Ptr) { if (n2Ptr != NULL) { n2Ptr = n2Ptr->parent; while (n2Ptr != NULL) { if (n2Ptr == n1Ptr) { return TRUE; } n2Ptr = n2Ptr->parent; } } return FALSE; } /* *--------------------------------------------------------------------------- * * Blt_Tree_SortNode -- * * Sorts the subnodes at a given node. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ int Blt_Tree_SortNode(Tree *treePtr, Node *nodePtr, Blt_TreeCompareNodesProc *proc) { Node **nodes; int nNodes; Node *np, **npp; nNodes = nodePtr->nChildren; if (nNodes < 2) { return TCL_OK; } nodes = Blt_Malloc((nNodes + 1) * sizeof(Node *)); if (nodes == NULL) { return TCL_ERROR; /* Out of memory. */ } for (npp = nodes, np = nodePtr->first; np != NULL; np = np->next, npp++) { *npp = np; } *npp = NULL; qsort(nodes, nNodes, sizeof(Node *), (QSortCompareProc *)proc); for (npp = nodes; *npp != NULL; npp++) { UnlinkNode(*npp); LinkBefore(nodePtr, *npp, (Blt_TreeNode)NULL); } Blt_Free(nodes); NotifyClients(treePtr, nodePtr->corePtr, nodePtr, TREE_NOTIFY_SORT); return TCL_OK; } #define TEST_RESULT(result) \ switch (result) { \ case TCL_CONTINUE: \ return TCL_OK; \ case TCL_OK: \ break; \ default: \ return (result); \ } int Blt_Tree_Apply( Node *branchPtr, /* Root node of subtree. */ Blt_TreeApplyProc *proc, /* Procedure to call for each node. */ ClientData clientData) /* One-word of data passed when calling * proc. */ { Node *np, *nextPtr; for (np = branchPtr->first; np != NULL; np = nextPtr) { int result; /* * Get the next link in the chain before calling Blt_TreeApply * recursively. This is because the apply callback may delete the * node and its link. */ nextPtr = np->next; result = Blt_Tree_Apply(np, proc, clientData); TEST_RESULT(result); } return (*proc) (branchPtr, clientData, TREE_POSTORDER); } int Blt_Tree_ApplyDFS( Node *branchPtr, /* Root node of subtree. */ Blt_TreeApplyProc *proc, /* Procedure to call for each node. */ ClientData clientData, /* One-word of data passed when calling * proc. */ int order) /* Order of traversal. */ { Node *nodePtr, *nextPtr; int result; if (order & TREE_PREORDER) { result = (*proc) (branchPtr, clientData, TREE_PREORDER); TEST_RESULT(result); } nodePtr = branchPtr->first; if (order & TREE_INORDER) { if (nodePtr != NULL) { result = Blt_Tree_ApplyDFS(nodePtr, proc, clientData, order); TEST_RESULT(result); nodePtr = nodePtr->next; } result = (*proc) (branchPtr, clientData, TREE_INORDER); TEST_RESULT(result); } for (/* empty */; nodePtr != NULL; nodePtr = nextPtr) { /* * Get the next link in the chain before calling Blt_Tree_Apply * recursively. This is because the apply callback may delete the * node and its link. */ nextPtr = nodePtr->next; result = Blt_Tree_ApplyDFS(nodePtr, proc, clientData, order); TEST_RESULT(result); } if (order & TREE_POSTORDER) { return (*proc) (branchPtr, clientData, TREE_POSTORDER); } return TCL_OK; } int Blt_Tree_ApplyBFS( Node *branchPtr, /* Root node of subtree. */ Blt_TreeApplyProc *proc, /* Procedure to call for each node. */ ClientData clientData) /* One-word of data passed when calling * proc. */ { Blt_Chain queue; Blt_ChainLink link, next; Node *nodePtr; int result; queue = Blt_Chain_Create(); link = Blt_Chain_Append(queue, branchPtr); while (link != NULL) { Node *np; nodePtr = Blt_Chain_GetValue(link); /* Add the children to the queue. */ for (np = nodePtr->first; np != NULL; np = np->next) { Blt_Chain_Append(queue, np); } /* Process the node. */ result = (*proc) (nodePtr, clientData, TREE_BREADTHFIRST); switch (result) { case TCL_CONTINUE: Blt_Chain_Destroy(queue); return TCL_OK; case TCL_OK: break; default: Blt_Chain_Destroy(queue); return result; } /* Remove the node from the queue. */ next = Blt_Chain_NextLink(link); Blt_Chain_DeleteLink(queue, link); link = next; } Blt_Chain_Destroy(queue); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Tree_Attach -- * * Attaches the tree object of the named tree to the current one. This * lets a tree client change its core tree object. If the name of the * tree (used to get the tree object) is the empty string (""), then * create a new tree object. * * Results: * Returns a standard TCL result. If an error occurs, TCL_ERROR is * returned and an error message if left in the interpreter result. * * Side Effects: * The tree's traces and notifiers are deactivated and removed. The * tree's old core tree object is released. This may destroy the old * tree object is no client is still using it. The tag table is also * reset or shared with the named client. * *--------------------------------------------------------------------------- */ int Blt_Tree_Attach(Tcl_Interp *interp, Tree *treePtr, const char *name) { TreeObject *corePtr; Blt_ChainLink link; TreeInterpData *dataPtr; dataPtr = treePtr->corePtr->dataPtr; if (name[0] == '\0') { /* Create a new tree object. */ corePtr = NewTreeObject(dataPtr); if (corePtr == NULL) { Tcl_AppendResult(interp, "can't allocate a new tree object.", (char *)NULL); return TCL_ERROR; } } else { Tree *newPtr; newPtr = GetTree(dataPtr, name, NS_SEARCH_BOTH); if ((newPtr == NULL) || (newPtr->corePtr == NULL)) { Tcl_AppendResult(interp, "can't find a tree named \"", name, "\"", (char *)NULL); return TCL_ERROR; } corePtr = newPtr->corePtr; ShareTagTable(newPtr, treePtr); } /* * Be sure to add the client to new tree object, before releasing the old * tree object. This is so that reattaching to the same tree object * doesn't delete the tree object. */ link = Blt_Chain_Append(corePtr->clients, treePtr); ReleaseTreeObject(treePtr); ResetTree(treePtr); /* Reset the client's traces and notifiers. */ /* Update pointers in the client. */ treePtr->link = link; treePtr->corePtr = corePtr; treePtr->root = corePtr->root; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Tree_Open -- * * Creates a tree using an existing or new tree object. The returned * tree must be freed by the caller using Blt_Tree_Close. If the name of * the tree (used to get the tree object) is the empty string (""), then * create a new tree object. The following flags may be used: * * TREE_CREATE Create a tree named "name". A new tree object is * automatically created. If the "name" is NULL, then * automatically generate a new name. * * TREE_ATTACH Create a tree and use the tree object from an * existing tree given by "name". By default * the tag table is shared. * * TREE_NEWTAGS By default the tag table is shared. This flag * indicates to not share tags and to start with an * empty tag table. * * Results: * Returns a standard TCL result. If an error occurs, TCL_ERROR * is returned and an error message if left in the interpreter result. * * Side Effects: * The tree's traces and notifiers are deactivated and removed. The * tree's old core tree object is release. This may destroy the tree * object is no client is still using it. The tag table is also reset or * shared with the named client. * *--------------------------------------------------------------------------- */ Blt_Tree Blt_Tree_Open( Tcl_Interp *interp, /* Interpreter to report errors back to. */ const char *name, /* Name of tree in namespace. */ int flags) /* TREE_ATTACH|TREE_NEWTAGS */ { Blt_ObjectName objName; Tree *srcPtr, *destPtr; TreeObject *corePtr; Tcl_DString ds; TreeInterpData *dataPtr; const char *qualName; char string[200]; dataPtr = Blt_Tree_GetInterpData(interp); srcPtr = NULL; /* If there's a name available, see it's a tree. */ if (name != NULL) { srcPtr = GetTree(dataPtr, name, NS_SEARCH_BOTH); } else if ((flags & TREE_CREATE) == 0) { Tcl_AppendResult(interp, "no tree name given to attach", (char *)NULL); return NULL; } /* Either create a core tree object or use the one from the named tree.*/ if (flags & TREE_CREATE) { if (srcPtr != NULL) { Tcl_AppendResult(interp, "tree \"", name, "\" already exists", (char *)NULL); return NULL; } corePtr = NewTreeObject(dataPtr); if (corePtr == NULL) { Tcl_AppendResult(interp, "can't allocate tree object.", (char *)NULL); return NULL; } } else { if ((srcPtr == NULL) || (srcPtr->corePtr == NULL)) { Tcl_AppendResult(interp, "can't find a tree named \"", name, "\"", (char *)NULL); return NULL; } corePtr = srcPtr->corePtr; } /* Generate a new tree name if one wasn't already provided. */ if (name == NULL) { name = MakeTreeName(dataPtr, string); } /* * Tear apart and put back together the namespace-qualified name of the * tree. This is to ensure that naming is consistent. */ if (!Blt_ParseObjectName(interp, name, &objName, 0)) { return NULL; } qualName = Blt_MakeQualifiedName(&objName, &ds); destPtr = NewTree(dataPtr, corePtr, qualName); Tcl_DStringFree(&ds); if (destPtr == NULL) { Tcl_AppendResult(interp, "can't allocate tree token", (char *)NULL); return NULL; } if (((flags & TREE_NEWTAGS) == 0) && (srcPtr != NULL)) { ShareTagTable(srcPtr, destPtr); } return destPtr; } void Blt_Tree_Close(Tree *treePtr) { if (treePtr->magic != TREE_MAGIC) { fprintf(stderr, "invalid tree object token 0x%lx\n", (unsigned long)treePtr); return; } DestroyTree(treePtr); } int Blt_Tree_Exists(Tcl_Interp *interp, const char *name) { TreeInterpData *dataPtr; dataPtr = Blt_Tree_GetInterpData(interp); return (GetTree(dataPtr, name, NS_SEARCH_BOTH) != NULL); } /*ARGSUSED*/ static int SizeApplyProc(Node *nodePtr, ClientData clientData, int order) { int *sumPtr = clientData; *sumPtr = *sumPtr + 1; return TCL_OK; } int Blt_Tree_Size(Node *nodePtr) { int sum; sum = 0; Blt_Tree_Apply(nodePtr, SizeApplyProc, &sum); return sum; } void Blt_Tree_CreateEventHandler(Tree *treePtr, unsigned int mask, Blt_TreeNotifyEventProc *proc, ClientData clientData) { Blt_ChainLink link; NotifyEventHandler *notifyPtr; notifyPtr = NULL; /* Suppress compiler warning. */ /* Check if the event is already handled. */ for(link = Blt_Chain_FirstLink(treePtr->events); link != NULL; link = Blt_Chain_NextLink(link)) { notifyPtr = Blt_Chain_GetValue(link); if ((notifyPtr->proc == proc) && (notifyPtr->mask == mask) && (notifyPtr->clientData == clientData)) { break; } } if (link == NULL) { notifyPtr = Blt_AssertMalloc(sizeof (NotifyEventHandler)); link = Blt_Chain_Append(treePtr->events, notifyPtr); } if (proc == NULL) { Blt_Chain_DeleteLink(treePtr->events, link); Blt_Free(notifyPtr); } else { notifyPtr->proc = proc; notifyPtr->clientData = clientData; notifyPtr->mask = mask; notifyPtr->notifyPending = FALSE; notifyPtr->interp = treePtr->interp; } } void Blt_Tree_DeleteEventHandler(Tree *treePtr, unsigned int mask, Blt_TreeNotifyEventProc *proc, ClientData clientData) { Blt_ChainLink link; for(link = Blt_Chain_FirstLink(treePtr->events); link != NULL; link = Blt_Chain_NextLink(link)) { NotifyEventHandler *notifyPtr; notifyPtr = Blt_Chain_GetValue(link); if ((notifyPtr->proc == proc) && (notifyPtr->mask == mask) && (notifyPtr->clientData == clientData)) { if (notifyPtr->notifyPending) { Tcl_CancelIdleCall(NotifyIdleProc, notifyPtr); } Blt_Chain_DeleteLink(treePtr->events, link); Blt_Free(notifyPtr); return; } } } /* *--------------------------------------------------------------------------- * * Blt_Tree_PathFromNode -- * *--------------------------------------------------------------------------- */ const char * Blt_Tree_NodeRelativePath( Node *rootPtr, /* Root of subtree. */ Node *nodePtr, /* Node whose path is to be returned. */ const char *separator, /* Character string to separator elements. */ unsigned int flags, /* Indicates how to print the path. */ Tcl_DString *dsPtr) /* (out) Contains the path of the node. */ { const char **names; /* Used to stack the component names. */ const char *staticSpace[64]; long i; long nLevels; if (rootPtr == NULL) { rootPtr = nodePtr->corePtr->root; } nLevels = Blt_Tree_NodeDepth(nodePtr) - Blt_Tree_NodeDepth(rootPtr); if (flags & TREE_INCLUDE_ROOT) { nLevels++; } if (nLevels > 64) { names = Blt_AssertMalloc(nLevels * sizeof(const char *)); } else { names = staticSpace; } for (i = nLevels; i > 0; i--) { /* Save the name of each ancestor in the name array. Note that we * ignore the root. */ names[i - 1] = nodePtr->label; nodePtr = nodePtr->parent; } /* Append each the names in the array. */ if ((nLevels > 0) && (separator != NULL)) { Tcl_DStringAppend(dsPtr, names[0], -1); for (i = 1; i < nLevels; i++) { Tcl_DStringAppend(dsPtr, separator, -1); Tcl_DStringAppend(dsPtr, names[i], -1); } } else { for (i = 0; i < nLevels; i++) { Tcl_DStringAppendElement(dsPtr, names[i]); } } if (names != staticSpace) { Blt_Free(names); } return Tcl_DStringValue(dsPtr); } /* *--------------------------------------------------------------------------- * * Blt_Tree_NodePath -- * *--------------------------------------------------------------------------- */ const char * Blt_Tree_NodePath(Node *nodePtr, Tcl_DString *dsPtr) { Blt_TreeNode root; root = nodePtr->corePtr->root; return Blt_Tree_NodeRelativePath(root, nodePtr, NULL, 0, dsPtr); } int Blt_Tree_ArrayValueExists(Tree *treePtr, Node *nodePtr, const char *arrayName, const char *elemName) { Blt_TreeKey key; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; Value *valuePtr; key = Blt_Tree_GetKey(treePtr, arrayName); valuePtr = GetTreeValue((Tcl_Interp *)NULL, treePtr, nodePtr, key); if (valuePtr == NULL) { return FALSE; } if (Tcl_IsShared(valuePtr->objPtr)) { Tcl_DecrRefCount(valuePtr->objPtr); valuePtr->objPtr = Tcl_DuplicateObj(valuePtr->objPtr); Tcl_IncrRefCount(valuePtr->objPtr); } if (Blt_GetArrayFromObj((Tcl_Interp *)NULL, valuePtr->objPtr, &tablePtr) != TCL_OK) { return FALSE; } hPtr = Blt_FindHashEntry(tablePtr, elemName); return (hPtr != NULL); } int Blt_Tree_GetArrayValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, const char *arrayName, const char *elemName, Tcl_Obj **valueObjPtrPtr) { Blt_TreeKey key; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; Value *valuePtr; key = Blt_Tree_GetKey(treePtr, arrayName); valuePtr = GetTreeValue(interp, treePtr, nodePtr, key); if (valuePtr == NULL) { return TCL_ERROR; } if (Tcl_IsShared(valuePtr->objPtr)) { Tcl_DecrRefCount(valuePtr->objPtr); valuePtr->objPtr = Tcl_DuplicateObj(valuePtr->objPtr); Tcl_IncrRefCount(valuePtr->objPtr); } if (Blt_GetArrayFromObj(interp, valuePtr->objPtr, &tablePtr) != TCL_OK) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(tablePtr, elemName); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find \"", arrayName, "(", elemName, ")\"", (char *)NULL); } return TCL_ERROR; } *valueObjPtrPtr = Blt_GetHashValue(hPtr); /* Reading any element of the array can cause a trace to fire. */ if (!(nodePtr->flags & TREE_TRACE_ACTIVE)) { CallTraces(interp, treePtr, nodePtr->corePtr, nodePtr, key, TREE_TRACE_READ); } return TCL_OK; } int Blt_Tree_SetArrayValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, const char *arrayName, const char *elemName, Tcl_Obj *valueObjPtr) { Blt_TreeKey key; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; Value *valuePtr; unsigned int flags; int isNew; assert(valueObjPtr != NULL); /* * Search for the array in the list of data fields. If one doesn't exist, * create it. */ key = Blt_Tree_GetKey(treePtr, arrayName); valuePtr = TreeCreateValue(nodePtr, key, &isNew); if ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't set private field \"", key, "\"", (char *)NULL); } return TCL_ERROR; } flags = TREE_TRACE_WRITE; if (isNew) { valuePtr->objPtr = Blt_NewArrayObj(0, (Tcl_Obj **)NULL); Tcl_IncrRefCount(valuePtr->objPtr); flags |= TREE_TRACE_CREATE; } else if (Tcl_IsShared(valuePtr->objPtr)) { Tcl_DecrRefCount(valuePtr->objPtr); valuePtr->objPtr = Tcl_DuplicateObj(valuePtr->objPtr); Tcl_IncrRefCount(valuePtr->objPtr); } if (Blt_GetArrayFromObj(interp, valuePtr->objPtr, &tablePtr) != TCL_OK) { return TCL_ERROR; } Tcl_InvalidateStringRep(valuePtr->objPtr); hPtr = Blt_CreateHashEntry(tablePtr, elemName, &isNew); Tcl_IncrRefCount(valueObjPtr); if (!isNew) { Tcl_Obj *oldValueObjPtr; /* An element by the same name already exists. Decrement the reference * count of the old value. */ oldValueObjPtr = Blt_GetHashValue(hPtr); if (oldValueObjPtr != NULL) { Tcl_DecrRefCount(oldValueObjPtr); } } Blt_SetHashValue(hPtr, valueObjPtr); /* * We don't handle traces on a per array element basis. Setting any * element can fire traces for the value. */ if (!(nodePtr->flags & TREE_TRACE_ACTIVE)) { CallTraces(interp, treePtr, nodePtr->corePtr, nodePtr, valuePtr->key, flags); } return TCL_OK; } int Blt_Tree_UnsetArrayValue(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, const char *arrayName, const char *elemName) { Blt_TreeKey key; /* Name of field in node. */ Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; Tcl_Obj *valueObjPtr; Value *valuePtr; key = Blt_Tree_GetKey(treePtr, arrayName); valuePtr = TreeFindValue(nodePtr, key); if (valuePtr == NULL) { return TCL_OK; } if ((valuePtr->owner != NULL) && (valuePtr->owner != treePtr)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't unset private field \"", key, "\"", (char *)NULL); } return TCL_ERROR; } if (Tcl_IsShared(valuePtr->objPtr)) { Tcl_DecrRefCount(valuePtr->objPtr); valuePtr->objPtr = Tcl_DuplicateObj(valuePtr->objPtr); Tcl_IncrRefCount(valuePtr->objPtr); } if (Blt_GetArrayFromObj(interp, valuePtr->objPtr, &tablePtr) != TCL_OK) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(tablePtr, elemName); if (hPtr == NULL) { return TCL_OK; /* Element doesn't exist, Ok. */ } valueObjPtr = Blt_GetHashValue(hPtr); Tcl_DecrRefCount(valueObjPtr); Blt_DeleteHashEntry(tablePtr, hPtr); /* * Un-setting any element in the array can cause the trace on the value to * fire. */ if (!(nodePtr->flags & TREE_TRACE_ACTIVE)) { CallTraces(interp, treePtr, nodePtr->corePtr, nodePtr, valuePtr->key, TREE_TRACE_WRITE); } return TCL_OK; } int Blt_Tree_ArrayNames(Tcl_Interp *interp, Tree *treePtr, Node *nodePtr, const char *arrayName, Tcl_Obj *listObjPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Blt_HashTable *tablePtr; Value *valuePtr; const char *key; key = Blt_Tree_GetKey(treePtr, arrayName); valuePtr = GetTreeValue(interp, treePtr, nodePtr, key); if (valuePtr == NULL) { return TCL_ERROR; } if (Tcl_IsShared(valuePtr->objPtr)) { Tcl_DecrRefCount(valuePtr->objPtr); valuePtr->objPtr = Tcl_DuplicateObj(valuePtr->objPtr); Tcl_IncrRefCount(valuePtr->objPtr); } if (Blt_GetArrayFromObj(interp, valuePtr->objPtr, &tablePtr) != TCL_OK) { return TCL_ERROR; } tablePtr = (Blt_HashTable *)valuePtr->objPtr; for (hPtr = Blt_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_GetHashKey(tablePtr, hPtr), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } return TCL_OK; } void Blt_Tree_NewTagTable(Tree *treePtr) { Blt_TreeTagTable *tagTablePtr; if (treePtr->tagTablePtr != NULL) { ReleaseTagTable(treePtr->tagTablePtr); } /* By default, use own sets of tags. */ tagTablePtr = Blt_AssertMalloc(sizeof(Blt_TreeTagTable)); tagTablePtr->refCount = 1; Blt_InitHashTable(&tagTablePtr->tagTable, BLT_STRING_KEYS); treePtr->tagTablePtr = tagTablePtr; } int Blt_Tree_TagTableIsShared(Tree *treePtr) { return (treePtr->tagTablePtr->refCount > 1); } void Blt_Tree_ClearTags(Tree *treePtr, Node *nodePtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&treePtr->tagTablePtr->tagTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_TreeTagEntry *tePtr; Blt_HashEntry *h2Ptr; tePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(&tePtr->nodeTable, (char *)nodePtr); if (h2Ptr != NULL) { Blt_DeleteHashEntry(&tePtr->nodeTable, h2Ptr); } } } Blt_TreeTagEntry * Blt_Tree_RememberTag(Tree *treePtr, const char *tagName) { int isNew; Blt_HashEntry *hPtr; Blt_TreeTagEntry *tePtr; Blt_HashTable *tablePtr; tablePtr = &treePtr->tagTablePtr->tagTable; hPtr = Blt_CreateHashEntry(tablePtr, tagName, &isNew); if (isNew) { tePtr = Blt_AssertMalloc(sizeof(Blt_TreeTagEntry)); Blt_InitHashTable(&tePtr->nodeTable, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tePtr); tePtr->hashPtr = hPtr; tePtr->tagName = Blt_GetHashKey(tablePtr, hPtr); } else { tePtr = Blt_GetHashValue(hPtr); } return tePtr; } void Blt_Tree_ForgetTag(Tree *treePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_TreeTagEntry *tePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "root") == 0)) { return; } hPtr = Blt_FindHashEntry(&treePtr->tagTablePtr->tagTable, tagName); if (hPtr == NULL) { return; } tePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(&tePtr->nodeTable); Blt_Free(tePtr); Blt_DeleteHashEntry(&treePtr->tagTablePtr->tagTable, hPtr); } int Blt_Tree_HasTag( Tree *treePtr, Node *nodePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_TreeTagEntry *tePtr; if (strcmp(tagName, "all") == 0) { return TRUE; } if ((strcmp(tagName, "root") == 0) && (nodePtr == Blt_Tree_RootNode(treePtr))) { return TRUE; } hPtr = Blt_FindHashEntry(&treePtr->tagTablePtr->tagTable, tagName); if (hPtr == NULL) { return FALSE; } tePtr = Blt_GetHashValue(hPtr); hPtr = Blt_FindHashEntry(&tePtr->nodeTable, (char *)nodePtr); if (hPtr == NULL) { return FALSE; } return TRUE; } void Blt_Tree_AddTag(Tree *treePtr, Node *nodePtr, const char *tagName) { Blt_TreeTagEntry *tePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "root") == 0)) { return; } tePtr = Blt_Tree_RememberTag(treePtr, tagName); if (nodePtr != NULL) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&tePtr->nodeTable, (char *)nodePtr, &isNew); if (isNew) { Blt_SetHashValue(hPtr, nodePtr); } } } void Blt_Tree_RemoveTag(Tree *treePtr, Node *nodePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_TreeTagEntry *tePtr; if (strcmp(tagName, "all") == 0) { return; /* Can't remove tag "all". */ } if ((strcmp(tagName, "root") == 0) && (nodePtr == Blt_Tree_RootNode(treePtr))) { return; /* Can't remove tag "root" from root node. */ } hPtr = Blt_FindHashEntry(&treePtr->tagTablePtr->tagTable, tagName); if (hPtr == NULL) { return; /* No such tag. */ } tePtr = Blt_GetHashValue(hPtr); hPtr = Blt_FindHashEntry(&tePtr->nodeTable, (char *)nodePtr); if (hPtr == NULL) { return; /* Node isn't tagged. */ } Blt_DeleteHashEntry(&tePtr->nodeTable, hPtr); return; } /* *--------------------------------------------------------------------------- * * Blt_Tree_TagHashTable -- * *--------------------------------------------------------------------------- */ Blt_HashTable * Blt_Tree_TagHashTable(Tree *treePtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&treePtr->tagTablePtr->tagTable, tagName); if (hPtr != NULL) { Blt_TreeTagEntry *tePtr; tePtr = Blt_GetHashValue(hPtr); return &tePtr->nodeTable; } return NULL; } Blt_HashEntry * Blt_Tree_FirstTag(Tree *treePtr, Blt_HashSearch *cursorPtr) { return Blt_FirstHashEntry(&treePtr->tagTablePtr->tagTable, cursorPtr); } /* *--------------------------------------------------------------------------- * * Blt_Tree_DumpNode -- * *--------------------------------------------------------------------------- */ void Blt_Tree_DumpNode(Tree *treePtr, Node *rootPtr, Node *nodePtr, Tcl_DString *dsPtr) { if (nodePtr == rootPtr) { Tcl_DStringAppendElement(dsPtr, "-1"); } else { Tcl_DStringAppendElement(dsPtr, Blt_Tree_NodeIdAscii(nodePtr->parent)); } Tcl_DStringAppendElement(dsPtr, Blt_Tree_NodeIdAscii(nodePtr)); Tcl_DStringStartSublist(dsPtr); Blt_Tree_NodeRelativePath(rootPtr, nodePtr, NULL, TREE_INCLUDE_ROOT, dsPtr); Tcl_DStringEndSublist(dsPtr); Tcl_DStringStartSublist(dsPtr); { Blt_TreeKeyIterator iter; Blt_TreeKey key; /* Add list of key-value pairs. */ for (key = Blt_Tree_FirstKey(treePtr, nodePtr, &iter); key != NULL; key = Blt_Tree_NextKey(treePtr, &iter)) { Tcl_Obj *objPtr; if (Blt_Tree_GetValueByKey((Tcl_Interp *)NULL, treePtr, nodePtr, key, &objPtr) == TCL_OK) { Tcl_DStringAppendElement(dsPtr, key); Tcl_DStringAppendElement(dsPtr, Tcl_GetString(objPtr)); } } } Tcl_DStringEndSublist(dsPtr); Tcl_DStringStartSublist(dsPtr); { Blt_HashEntry *hPtr; Blt_HashSearch cursor; /* Add list of tags. */ for (hPtr = Blt_Tree_FirstTag(treePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_TreeTagEntry *tePtr; tePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(&tePtr->nodeTable, (char *)nodePtr) != NULL) { Tcl_DStringAppendElement(dsPtr, tePtr->tagName); } } } Tcl_DStringEndSublist(dsPtr); Tcl_DStringAppend(dsPtr, "\n", -1); } /* *--------------------------------------------------------------------------- * * Blt_Tree_Dump -- * * Dumps node information recursively from the given tree based starting * at *rootPtr*. The dump information is written to the TCL dynamic * string provided. It the caller's responsibility to initialize and free * the dynamic string. * * Results: * Always returns TCL_OK. * * Side Effects: * Dump information is written to the dynamic string provided. * *--------------------------------------------------------------------------- */ int Blt_Tree_Dump(Tree *treePtr, Node *rootPtr, Tcl_DString *dsPtr) { Node *np; for (np = rootPtr; np != NULL; np = Blt_Tree_NextNode(rootPtr, np)) { Blt_Tree_DumpNode(treePtr, rootPtr, np, dsPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Tree_DumpToFile -- * * Dumps node information recursively from the given tree based starting * at *rootPtr*. The dump information is written to the file named. If * the file name starts with an '@', then it is the name of an already * opened channel to be used. * * Results: * A standard TCL result. If the dump was successful, TCL_OK is * returned. Otherwise, TCL_ERROR is returned and an error message is * left in the interpreter result. * * Side Effects: * Dump information is written to the named file. * *--------------------------------------------------------------------------- */ int Blt_Tree_DumpToFile( Tcl_Interp *interp, Tree *treePtr, Node *rootPtr, /* Root node of subtree. */ const char *fileName) { Tcl_Channel channel; Node *np; Tcl_DString ds; int closeChannel; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for writing", (char *)NULL); return TCL_ERROR; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (channel == NULL) { return TCL_ERROR; } } Tcl_DStringInit(&ds); for (np = rootPtr; np != NULL; np = Blt_Tree_NextNode(rootPtr, np)) { int nWritten, length; Tcl_DStringSetLength(&ds, 0); Blt_Tree_DumpNode(treePtr, rootPtr, np, &ds); length = Tcl_DStringLength(&ds); #if HAVE_UTF nWritten = Tcl_WriteChars(channel, Tcl_DStringValue(&ds), length); #else nWritten = Tcl_Write(channel, Tcl_DStringValue(&ds), length); #endif if (nWritten < 0) { Tcl_AppendResult(interp, fileName, ": write error:", Tcl_PosixError(interp), (char *)NULL); Tcl_DStringFree(&ds); if (closeChannel) { Tcl_Close(interp, channel); } return TCL_ERROR; } } Tcl_DStringFree(&ds); if (closeChannel) { Tcl_Close(interp, channel); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Tree_RestoreFromFile -- * * Restores nodes to the given tree based upon the dump file * provided. The dump file should have been generated by Blt_Tree_Dump or * Blt_Tree_DumpToFile. If the file name starts with an '@', then it is * the name of an already opened channel to be used. Nodes are added * relative to the node *rootPtr* as the root of the sub-tree. Two bit * flags may be set. * * TREE_RESTORE_NO_TAGS Don't restore tag information. * TREE_RESTORE_OVERWRITE Look for nodes with the same label. * Overwrite if necessary. * * Results: * A standard TCL result. If the restore was successful, TCL_OK is * returned. Otherwise, TCL_ERROR is returned and an error message is * left in the interpreter result. * * Side Effects: * New nodes are created in the tree and may possibly generate notify * callbacks. * *--------------------------------------------------------------------------- */ int Blt_Tree_RestoreFromFile( Tcl_Interp *interp, Tree *treePtr, Node *rootPtr, /* Root node of branch to be restored. */ const char *fileName, unsigned int flags) { Tcl_Channel channel; RestoreInfo restore; int argc; const char **argv; int closeChannel; int result; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); return TCL_ERROR; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return TCL_ERROR; /* Can't open dump file. */ } } memset((char *)&restore, 0, sizeof(restore)); Blt_InitHashTable(&restore.idTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&restore.dataTable, BLT_STRING_KEYS); restore.rootPtr = rootPtr; restore.flags = flags; restore.treePtr = treePtr; argv = NULL; result = TCL_ERROR; for (;;) { result = ReadDumpRecord(interp, channel, &argc, &argv, &restore); if (result != TCL_OK) { break; /* Found error or EOF */ } if (argc == 0) { result = TCL_OK; /* Do nothing. */ } else if (argc == 3) { result = RestoreNode3(interp, argc, argv, &restore); } else if ((argc == 5) || (argc == 6)) { result = RestoreNode5(interp, argc, argv, &restore); } else { Tcl_AppendResult(interp, "line #", Blt_Itoa(restore.nLines), ": wrong # elements in restore entry", (char *)NULL); result = TCL_ERROR; } Blt_Free(argv); if (result != TCL_OK) { break; } } if (closeChannel) { Tcl_Close(interp, channel); } Blt_DeleteHashTable(&restore.idTable); Blt_DeleteHashTable(&restore.dataTable); if (result == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Tree_Restore -- * * Restores nodes to the given tree based upon the dump string. The dump * string should have been generated by Blt_Tree_Dump. Nodes are added * relative to the node *rootPtr* as the root of the sub-tree. Two bit * flags may be set. * * TREE_RESTORE_NO_TAGS Don't restore tag information. * TREE_RESTORE_OVERWRITE Look for nodes with the same label. * Overwrite if necessary. * * Results: * A standard TCL result. If the restore was successful, TCL_OK is * returned. Otherwise, TCL_ERROR is returned and an error message is * left in the interpreter result. * * Side Effects: * New nodes are created in the tree and may possibly generate * notify callbacks. * *--------------------------------------------------------------------------- */ int Blt_Tree_Restore( Tcl_Interp *interp, Tree *treePtr, Node *rootPtr, /* Root node of branch to be restored. */ const char *string, unsigned int flags) { RestoreInfo restore; int result; memset((char *)&restore, 0, sizeof(restore)); Blt_InitHashTable(&restore.idTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&restore.dataTable, BLT_STRING_KEYS); restore.treePtr = treePtr; restore.rootPtr = rootPtr; restore.flags = flags; result = TCL_ERROR; for (;;) { const char **argv; int argc; result = ParseDumpRecord(interp, &string, &argc, &argv, &restore); if (result != TCL_OK) { break; /* Found error or EOF */ } if (argc == 0) { result = TCL_OK; /* Do nothing. */ } else if (argc == 3) { result = RestoreNode3(interp, argc, argv, &restore); } else if ((argc == 5) || (argc == 6)) { result = RestoreNode5(interp, argc, argv, &restore); } else { Tcl_AppendResult(interp, "line #", Blt_Itoa(restore.nLines), ": wrong # elements in restore entry", (char *)NULL); result = TCL_ERROR; } Blt_Free(argv); if (result != TCL_OK) { break; } } Blt_DeleteHashTable(&restore.idTable); Blt_DeleteHashTable(&restore.dataTable); /* result will be TCL_RETURN if successful, TCL_ERROR otherwise. */ if (result == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrPen.c��������������������������������������������������������������������0000644�0001750�0001750�00000047013�11462120062�014713� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrPen.c -- * * This module implements pens for the BLT graph widget. * * Copyright 1996-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" #include <X11/Xutil.h> typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv); static Blt_OptionFreeProc FreeColor; static Blt_OptionParseProc ObjToColor; static Blt_OptionPrintProc ColorToObj; Blt_CustomOption bltColorOption = { ObjToColor, ColorToObj, FreeColor, (ClientData)0 }; static Blt_OptionFreeProc FreePen; static Blt_OptionParseProc ObjToPen; static Blt_OptionPrintProc PenToObj; Blt_CustomOption bltBarPenOption = { ObjToPen, PenToObj, FreePen, (ClientData)CID_ELEM_BAR }; Blt_CustomOption bltLinePenOption = { ObjToPen, PenToObj, FreePen, (ClientData)CID_ELEM_LINE }; /*ARGSUSED*/ static void FreeColor( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { XColor *colorPtr = *(XColor **)(widgRec + offset); if ((colorPtr != NULL) && (colorPtr != COLOR_DEFAULT)) { Tk_FreeColor(colorPtr); } } /* *--------------------------------------------------------------------------- * ObjToColor -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToColor( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing color */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { XColor **colorPtrPtr = (XColor **)(widgRec + offset); XColor *colorPtr; const char *string; char c; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == '\0') && (flags & BLT_CONFIG_NULL_OK)) { if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) { Tk_FreeColor(*colorPtrPtr); } *colorPtrPtr = NULL; return TCL_OK; } if ((c == 'd') && (strncmp(string, "defcolor", length) == 0)) { if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) { Tk_FreeColor(*colorPtrPtr); } *colorPtrPtr = COLOR_DEFAULT; return TCL_OK; } colorPtr = Tk_AllocColorFromObj(interp, tkwin, objPtr); if (colorPtr == NULL) { return TCL_ERROR; } if ((*colorPtrPtr != NULL) && (*colorPtrPtr != COLOR_DEFAULT)) { Tk_FreeColor(*colorPtrPtr); } *colorPtrPtr = colorPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColorToObj -- * * Convert the color value into a string. * * Results: * The string representing the symbol color is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ColorToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { XColor *colorPtr = *(XColor **)(widgRec + offset); Tcl_Obj *objPtr; if (colorPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else if (colorPtr == COLOR_DEFAULT) { objPtr = Tcl_NewStringObj("defcolor", -1); } else { objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1); } return objPtr; } /*ARGSUSED*/ static void FreePen( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { Pen **penPtrPtr = (Pen **)(widgRec + offset); if (*penPtrPtr != NULL) { Blt_FreePen(*penPtrPtr); } } /* *--------------------------------------------------------------------------- * * ObjToPen -- * * Convert the color value into a string. * * Results: * The string representing the symbol color is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPen( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing pen */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Pen **penPtrPtr = (Pen **)(widgRec + offset); const char *string; string = Tcl_GetString(objPtr); if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { Blt_FreePen(*penPtrPtr); *penPtrPtr = NULL; } else { Pen *penPtr; Graph *graphPtr; ClassId classId = (ClassId)clientData; /* Element type. */ graphPtr = Blt_GetGraphFromWindowData(tkwin); assert(graphPtr); if (classId == CID_NONE) { classId = graphPtr->classId; } if (Blt_GetPenFromObj(interp, graphPtr, objPtr, classId, &penPtr) != TCL_OK) { return TCL_ERROR; } Blt_FreePen(*penPtrPtr); *penPtrPtr = penPtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PenToObj -- * * Parse the name of the name. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PenToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Pen *penPtr = *(Pen **)(widgRec + offset); if (penPtr == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(penPtr->name, -1); } } /* *--------------------------------------------------------------------------- * * GetPenFromObj -- * * Find and return the pen style from a given name. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Pen **penPtrPtr) { Blt_HashEntry *hPtr; Pen *penPtr; const char *name; penPtr = NULL; name = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->penTable, name); if (hPtr != NULL) { penPtr = Blt_GetHashValue(hPtr); if (penPtr->flags & DELETE_PENDING) { penPtr = NULL; } } if (penPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *penPtrPtr = penPtr; return TCL_OK; } static void DestroyPen(Pen *penPtr) { Graph *graphPtr = penPtr->graphPtr; Blt_FreeOptions(penPtr->configSpecs, (char *)penPtr, graphPtr->display, 0); (*penPtr->destroyProc) (graphPtr, penPtr); if ((penPtr->name != NULL) && (penPtr->name[0] != '\0')) { Blt_Free(penPtr->name); } if (penPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&graphPtr->penTable, penPtr->hashPtr); } Blt_Free(penPtr); } void Blt_FreePen(Pen *penPtr) { if (penPtr != NULL) { penPtr->refCount--; if ((penPtr->refCount == 0) && (penPtr->flags & DELETE_PENDING)) { DestroyPen(penPtr); } } } Pen * Blt_CreatePen(Graph *graphPtr, const char *penName, ClassId classId, int objc, Tcl_Obj *const *objv) { Pen *penPtr; Blt_HashEntry *hPtr; unsigned int configFlags; int isNew; int i; /* * Scan the option list for a "-type" entry. This will indicate what type * of pen we are creating. Otherwise we'll default to the suggested type. * Last -type option wins. */ for (i = 0; i < objc; i += 2) { char *string; int length; string = Tcl_GetStringFromObj(objv[i], &length); if ((length > 2) && (strncmp(string, "-type", length) == 0)) { char *arg; arg = Tcl_GetString(objv[i + 1]); if (strcmp(arg, "bar") == 0) { classId = CID_ELEM_BAR; } else if (strcmp(arg, "line") == 0) { classId = CID_ELEM_LINE; } else if (strcmp(arg, "strip") == 0) { classId = CID_ELEM_LINE; } else if (strcmp(arg, "contour") == 0) { classId = CID_ELEM_CONTOUR; } else { Tcl_AppendResult(graphPtr->interp, "unknown pen type \"", arg, "\" specified", (char *)NULL); return NULL; } } } if (classId == CID_ELEM_STRIP) { classId = CID_ELEM_LINE; } hPtr = Blt_CreateHashEntry(&graphPtr->penTable, penName, &isNew); if (!isNew) { penPtr = Blt_GetHashValue(hPtr); if ((penPtr->flags & DELETE_PENDING) == 0) { Tcl_AppendResult(graphPtr->interp, "pen \"", penName, "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return NULL; } if (penPtr->classId != classId) { Tcl_AppendResult(graphPtr->interp, "pen \"", penName, "\" in-use: can't change pen type from \"", Blt_GraphClassName(penPtr->classId), "\" to \"", Blt_GraphClassName(classId), "\"", (char *)NULL); return NULL; } penPtr->flags &= ~DELETE_PENDING; /* Undelete the pen. */ } else { if (classId == CID_ELEM_BAR) { penPtr = Blt_BarPen(penName); } else { penPtr = Blt_LinePen(penName); } penPtr->classId = classId; penPtr->hashPtr = hPtr; penPtr->graphPtr = graphPtr; Blt_SetHashValue(hPtr, penPtr); } configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN)); if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, penPtr->name, "Pen", penPtr->configSpecs, objc, objv, (char *)penPtr, configFlags) != TCL_OK) { if (isNew) { DestroyPen(penPtr); } return NULL; } (*penPtr->configProc) (graphPtr, penPtr); return penPtr; } int Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, Pen **penPtrPtr) { Blt_HashEntry *hPtr; Pen *penPtr; const char *name; penPtr = NULL; name = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->penTable, name); if (hPtr != NULL) { penPtr = Blt_GetHashValue(hPtr); if (penPtr->flags & DELETE_PENDING) { penPtr = NULL; } } if (penPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find pen \"", name, "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } if (classId == CID_ELEM_STRIP) { classId = CID_ELEM_LINE; } if (penPtr->classId != classId) { if (interp != NULL) { Tcl_AppendResult(interp, "pen \"", name, "\" is the wrong type (is \"", Blt_GraphClassName(penPtr->classId), "\"", ", wanted \"", Blt_GraphClassName(classId), "\")", (char *)NULL); } return TCL_ERROR; } penPtr->refCount++; *penPtrPtr = penPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_DestroyPens -- * * Release memory and resources allocated for the style. * * Results: * None. * * Side effects: * Everything associated with the pen style is freed up. * *--------------------------------------------------------------------------- */ void Blt_DestroyPens(Graph *graphPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pen *penPtr; penPtr = Blt_GetHashValue(hPtr); penPtr->hashPtr = NULL; DestroyPen(penPtr); } Blt_DeleteHashTable(&graphPtr->penTable); } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Queries axis attributes (font, line width, label, etc). * * Results: * A standard TCL result. If querying configuration values, * interp->result will contain the results. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CgetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Pen *penPtr; unsigned int configFlags; if (GetPenFromObj(interp, graphPtr, objv[3], &penPtr) != TCL_OK) { return TCL_ERROR; } configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN)); return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, penPtr->configSpecs, (char *)penPtr, objv[4], configFlags); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Queries or resets pen attributes (font, line width, color, etc). * * Results: * A standard TCL result. If querying configuration values, * interp->result will contain the results. * * Side Effects: * Pen resources are possibly allocated (GC, font). * *--------------------------------------------------------------------------- */ static int ConfigureOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Pen *penPtr; int nNames, nOpts; int redraw; Tcl_Obj *const *options; int i; /* Figure out where the option value pairs begin */ objc -= 3; objv += 3; for (i = 0; i < objc; i++) { char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) { return TCL_ERROR; } } nNames = i; /* Number of pen names specified */ nOpts = objc - i; /* Number of options specified */ options = objv + i; /* Start of options in objv */ redraw = 0; for (i = 0; i < nNames; i++) { int flags; if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) { return TCL_ERROR; } flags = BLT_CONFIG_OBJV_ONLY | (penPtr->flags&(ACTIVE_PEN|NORMAL_PEN)); if (nOpts == 0) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, penPtr->configSpecs, (char *)penPtr, (Tcl_Obj *)NULL, flags); } else if (nOpts == 1) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, penPtr->configSpecs, (char *)penPtr, options[0], flags); } if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, penPtr->configSpecs, nOpts, options, (char *)penPtr, flags) != TCL_OK) { break; } (*penPtr->configProc) (graphPtr, penPtr); if (penPtr->refCount > 0) { redraw++; } } if (redraw) { graphPtr->flags |= CACHE_DIRTY; Blt_EventuallyRedrawGraph(graphPtr); } if (i < nNames) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateOp -- * * Adds a new penstyle to the graph. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int CreateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Pen *penPtr; penPtr = Blt_CreatePen(graphPtr, Tcl_GetString(objv[3]), graphPtr->classId, objc - 4, objv + 4); if (penPtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, objv[3]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Delete the given pen. * * Results: * Always returns TCL_OK. The interp->result field is a list of the * graph axis limits. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Pen *penPtr; if (GetPenFromObj(interp, graphPtr, objv[i], &penPtr) != TCL_OK) { return TCL_ERROR; } if (penPtr->flags & DELETE_PENDING) { Tcl_AppendResult(interp, "can't find pen \"", Tcl_GetString(objv[i]), "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } penPtr->flags |= DELETE_PENDING; if (penPtr->refCount == 0) { DestroyPen(penPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Return a list of the names of all the axes. * * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pen *penPtr; penPtr = Blt_GetHashValue(hPtr); if ((penPtr->flags & DELETE_PENDING) == 0) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(penPtr->name, -1)); } } } else { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->penTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pen *penPtr; penPtr = Blt_GetHashValue(hPtr); if ((penPtr->flags & DELETE_PENDING) == 0) { int i; for (i = 3; i < objc; i++) { char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(penPtr->name, pattern)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(penPtr->name, -1)); break; } } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeOp -- * * Return the type of pen. * * Results: * Returns a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { Pen *penPtr; if (GetPenFromObj(interp, graphPtr, objv[3], &penPtr) != TCL_OK) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Blt_GraphClassName(penPtr->classId), -1); return TCL_OK; } static Blt_OpSpec penOps[] = { {"cget", 2, CgetOp, 5, 5, "penName option",}, {"configure", 2, ConfigureOp, 4, 0, "penName ?penName?... ?option value?...",}, {"create", 2, CreateOp, 4, 0, "penName ?option value?...",}, {"delete", 2, DeleteOp, 3, 0, "?penName?...",}, {"names", 1, NamesOp, 3, 0, "?pattern?...",}, {"type", 1, TypeOp, 4, 4, "penName",}, }; static int nPenOps = sizeof(penOps) / sizeof(Blt_OpSpec); int Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphPenProc *proc; proc = Blt_GetOpFromObj(interp, nPenOps, penOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (interp, graphPtr, objc, objv); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBind.h���������������������������������������������������������������������0000644�0001750�0001750�00000010477�11462120062�014565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltBind.h -- * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_BIND_H #define _BLT_BIND_H #include <bltList.h> typedef struct _Blt_BindTable *Blt_BindTable; typedef ClientData (Blt_BindPickProc)(ClientData clientData, int x, int y, ClientData *contextPtr); typedef void (Blt_BindTagProc)(Blt_BindTable bindTable, ClientData object, ClientData context, Blt_List list); /* * Binding structure information: */ struct _Blt_BindTable { unsigned int flags; Tk_BindingTable bindingTable; /* Table of all bindings currently defined. * NULL means that no bindings exist, so the * table hasn't been created. Each "object" * used for this table is either a Tk_Uid for * a tag or the address of an item named by * id. */ ClientData currentItem; /* The item currently containing the mouse * pointer, or NULL if none. */ ClientData currentContext; /* One word indicating what kind of object was * picked. */ ClientData newItem; /* The item that is about to become the * current one, or NULL. This field is used * to detect deletions of the new current item * pointer that occur during Leave processing * of the previous current tab. */ ClientData newContext; /* One-word indicating what kind of object was * just picked. */ ClientData focusItem; ClientData focusContext; XEvent pickEvent; /* The event upon which the current choice of * the current tab is based. Must be saved so * that if the current item is deleted, we can * pick another. */ int activePick; /* The pick event has been initialized so that * we can repick it */ int state; /* Last known modifier state. Used to defer * picking a new current object while buttons * are down. */ ClientData clientData; Tk_Window tkwin; Blt_BindPickProc *pickProc; /* Routine to report the item the mouse is * currently over. */ Blt_BindTagProc *tagProc; /* Routine to report tags picked items. */ }; BLT_EXTERN void Blt_DestroyBindingTable(Blt_BindTable table); BLT_EXTERN Blt_BindTable Blt_CreateBindingTable(Tcl_Interp *interp, Tk_Window tkwin, ClientData clientData, Blt_BindPickProc *pickProc, Blt_BindTagProc *tagProc); BLT_EXTERN int Blt_ConfigureBindings(Tcl_Interp *interp, Blt_BindTable table, ClientData item, int argc, const char **argv); BLT_EXTERN int Blt_ConfigureBindingsFromObj(Tcl_Interp *interp, Blt_BindTable table, ClientData item, int objc, Tcl_Obj *const *objv); BLT_EXTERN void Blt_PickCurrentItem(Blt_BindTable table); BLT_EXTERN void Blt_DeleteBindings(Blt_BindTable table, ClientData object); BLT_EXTERN void Blt_MoveBindingTable(Blt_BindTable table, Tk_Window tkwin); #define Blt_SetFocusItem(bindPtr, object, context) \ ((bindPtr)->focusItem = (ClientData)(object),\ (bindPtr)->focusContext = (ClientData)(context)) #define Blt_SetCurrentItem(bindPtr, object, context) \ ((bindPtr)->currentItem = (ClientData)(object),\ (bindPtr)->currentContext = (ClientData)(context)) #define Blt_GetCurrentItem(bindPtr) ((bindPtr)->currentItem) #define Blt_GetCurrentContext(bindPtr) ((bindPtr)->currentContext) #define Blt_GetLatestItem(bindPtr) ((bindPtr)->newItem) #define Blt_GetBindingData(bindPtr) ((bindPtr)->clientData) #endif /*_BLT_BIND_H*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinDll.c�������������������������������������������������������������������0000644�0001750�0001750�00000004162�11462120063�015070� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinDll.c -- * * This module initials the non-Tk command of the BLT toolkit, * registering the commands with the TCL interpreter. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifdef WIN32 /* *--------------------------------------------------------------------------- * * DllMain -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. * * Results: * Returns TRUE; * * Side effects: * None. * *--------------------------------------------------------------------------- */ BOOL APIENTRY DllMain( HINSTANCE hInst, /* Library instance handle. */ DWORD reason, /* Reason this function is being called. */ LPVOID reserved) /* Not used. */ { return TRUE; } BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return DllMain(hInst, reason, reserved); } #endif /* WIN32 */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/Makefile-cyg.in���������������������������������������������������������������0000644�0001750�0001750�00000046031�11502726613�015667� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for static version of BLT library # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ BLT_LIBRARY = @BLT_LIBRARY@ CC = @CC@ CFLAGS = @CFLAGS@ DEFINES = @DEFINES@ EXTRA_CFLAGS = @GCCFLAGS@ $(SO_CFLAGS) LDFLAGS = @LDFLAGS@ @LD_RUN_PATH@ LIB_PREFIX = @LIB_PREFIX@ TCLLIBPATH = @TCL_LIB_DIR@/tcl@TCL_VERSION@ TCL_DBG = @TCL_DBGX@ SO_CFLAGS = @BLT_SO_CFLAGS@ LIB_SUFFIX = @BLT_LIB_SUFFIX@ SO_EXT = @BLT_SO_EXT@ SO_PREFIX = @BLT_SO_PREFIX@ SO_LD = @BLT_SO_LD@ SO_LDFLAGS = @BLT_SO_LD_FLAGS@ @LD_RUN_PATH@ IMPLIB_PREFIX = @IMPLIB_PREFIX@ IMPLIB_EXT = @IMPLIB_EXT@ EXPAT_INC_SPEC = @EXPAT_INC_SPEC@ EXPAT_LIB_SPEC = @EXPAT_LIB_SPEC@ FT2_INC_SPEC = @FT2_INC_SPEC@ FT2_LIB_SPEC = @FT2_LIB_SPEC@ JPG_INC_SPEC = @JPG_INC_SPEC@ JPG_LIB_SPEC = @JPG_LIB_SPEC@ MYSQL_INC_SPEC = @MYSQL_INC_SPEC@ MYSQL_LIB_SPEC = @MYSQL_LIB_SPEC@ PNG_INC_SPEC = @PNG_INC_SPEC@ PNG_LIB_SPEC = @PNG_LIB_SPEC@ $(Z_LIB_SPEC) TCL_INC_SPEC = @TCL_INC_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUBS_SPEC = @TCL_STUBS_SPEC@ TIF_INC_SPEC = @TIF_INC_SPEC@ TIF_LIB_SPEC = @TIF_LIB_SPEC@ TK_INC_SPEC = @TK_INC_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ TK_STUBS_SPEC = @TK_STUBS_SPEC@ X11_INC_SPEC = @X11_INC_SPEC@ X11_LIB_SPEC = @X11_LIB_SPEC@ XFT_INC_SPEC = @XFT_INC_SPEC@ XFT_LIB_SPEC = @XFT_LIB_SPEC@ XPM_INC_SPEC = @XPM_INC_SPEC@ XPM_LIB_SPEC = @XPM_LIB_SPEC@ FTCFG_LIB_SPEC = @FTCFG_LIB_SPEC@ Z_LIB_SPEC = @Z_LIB_SPEC@ version = @BLT_MAJOR_VERSION@@BLT_MINOR_VERSION@ # ------------------------------------------------------------------------ # Source and targer installation directories # ------------------------------------------------------------------------ bindir = $(exec_prefix)/bin datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ incdir = $(prefix)/include includedir = @includedir@ libdir = @libdir@ prefix = @prefix@ scriptdir = $(exec_prefix)/lib srcdir = @srcdir@ pkgdir = @BLT_LIBRARY@ instdirs = $(prefix) \ $(exec_prefix) \ $(bindir) \ $(libdir) \ $(incdir) \ $(pkgdir) \ $(scriptdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ INCLUDES = -I. -I$(srcdir) \ -I$(srcdir)/../win \ $(TK_INC_SPEC) \ $(TCL_INC_SPEC) \ @INCLUDES@ # ------------------------------------------------------------------------ # Libraries directives for Tcl, Tk, X11, and BLT # ------------------------------------------------------------------------ EXTRA_CORE_LIBS = @LIBS@ @EXTRA_LIBS@ EXTRA_X_LIBS = $(EXTRA_CORE_LIBS) BLT_X_SO_LIBS = $(TK_LIB_SPEC) \ $(XFT_LIB_SPEC) \ $(FTCFG_LIB_SPEC) \ $(FT2_LIB_SPEC) BLT_X_A_LIBS = $(BLT_X_SO_LIBS) \ $(JPG_LIB_SPEC) \ $(PNG_LIB_SPEC) \ $(TIF_LIB_SPEC) \ $(XPM_LIB_SPEC) BLT_CORE_SO_LIBS = BLT_CORE_A_LIBS = $(BLT_CORE_SO_LIBS) \ $(MYSQL_LIB_SPEC) \ $(EXPAT_LIB_SPEC) blt_core_name = BLTCore$(version)$(LIB_SUFFIX) blt_x_name = BLTX$(version)$(LIB_SUFFIX) blt_core_so = $(SO_PREFIX)$(blt_core_name)$(SO_EXT) blt_core_a = lib$(blt_core_name).a blt_x_so = $(SO_PREFIX)$(blt_x_name)$(SO_EXT) blt_x_a = lib$(blt_x_name).a blt_core_implib = $(IMPLIB_PREFIX)$(blt_core_name)$(IMPLIB_EXT) blt_x_implib = $(IMPLIB_PREFIX)$(blt_x_name)$(IMPLIB_EXT) blt_dt_csv_name = DataTableCsv$(version)$(LIB_SUFFIX) blt_dt_mysql_name = DataTableMysql$(version)$(LIB_SUFFIX) blt_dt_tree_name = DataTableTree$(version)$(LIB_SUFFIX) blt_dt_vec_name = DataTableVector$(version)$(LIB_SUFFIX) blt_dt_xml_name = DataTableXml$(version)$(LIB_SUFFIX) blt_dt_csv_so = $(blt_dt_csv_name)$(SO_EXT) blt_dt_mysql_so = $(blt_dt_mysql_name)$(SO_EXT) blt_dt_tree_so = $(blt_dt_tree_name)$(SO_EXT) blt_dt_xml_so = $(blt_dt_xml_name)$(SO_EXT) blt_dt_vec_so = $(blt_dt_vec_name)$(SO_EXT) blt_dt_csv_implib = $(IMPLIB_PREFIX)$(blt_dt_csv_name)$(IMPLIB_EXT) blt_dt_mysql_implib = $(IMPLIB_PREFIX)$(blt_dt_mysql_name)$(IMPLIB_EXT) blt_dt_tree_implib = $(IMPLIB_PREFIX)$(blt_dt_tree_name)$(IMPLIB_EXT) blt_dt_vec_implib = $(IMPLIB_PREFIX)$(blt_dt_vec_name)$(IMPLIB_EXT) blt_dt_xml_implib = $(IMPLIB_PREFIX)$(blt_dt_xml_name)$(IMPLIB_EXT) blt_pict_bmp_name = PictureBmp$(version)$(LIB_SUFFIX) blt_pict_gif_name = PictureGif$(version)$(LIB_SUFFIX) blt_pict_jpg_name = PictureJpg$(version)$(LIB_SUFFIX) blt_pict_pbm_name = PicturePbm$(version)$(LIB_SUFFIX) blt_pict_pdf_name = PicturePdf$(version)$(LIB_SUFFIX) blt_pict_photo_name = PicturePhoto$(version)$(LIB_SUFFIX) blt_pict_png_name = PicturePng$(version)$(LIB_SUFFIX) blt_pict_ps_name = PicturePs$(version)$(LIB_SUFFIX) blt_pict_tif_name = PictureTif$(version)$(LIB_SUFFIX) blt_pict_xbm_name = PictureXbm$(version)$(LIB_SUFFIX) blt_pict_xpm_name = PictureXpm$(version)$(LIB_SUFFIX) blt_pict_bmp_so = $(blt_pict_bmp_name)$(SO_EXT) blt_pict_gif_so = $(blt_pict_gif_name)$(SO_EXT) blt_pict_jpg_so = $(blt_pict_jpg_name)$(SO_EXT) blt_pict_pbm_so = $(blt_pict_pbm_name)$(SO_EXT) blt_pict_pdf_so = $(blt_pict_pdf_name)$(SO_EXT) blt_pict_photo_so = $(blt_pict_photo_name)$(SO_EXT) blt_pict_png_so = $(blt_pict_png_name)$(SO_EXT) blt_pict_ps_so = $(blt_pict_ps_name)$(SO_EXT) blt_pict_tif_so = $(blt_pict_tif_name)$(SO_EXT) blt_pict_xbm_so = $(blt_pict_xbm_name)$(SO_EXT) blt_pict_xpm_so = $(blt_pict_xpm_name)$(SO_EXT) blt_pict_bmp_implib = $(IMPLIB_PREFIX)$(blt_pict_bmp_name)$(IMPLIB_EXT) blt_pict_gif_implib = $(IMPLIB_PREFIX)$(blt_pict_gif_name)$(IMPLIB_EXT) blt_pict_jpg_implib = $(IMPLIB_PREFIX)$(blt_pict_jpg_name)$(IMPLIB_EXT) blt_pict_pbm_implib = $(IMPLIB_PREFIX)$(blt_pict_pbm_name)$(IMPLIB_EXT) blt_pict_pdf_implib = $(IMPLIB_PREFIX)$(blt_pict_pdf_name)$(IMPLIB_EXT) blt_pict_photo_implib = $(IMPLIB_PREFIX)$(blt_pict_photo_name)$(IMPLIB_EXT) blt_pict_png_implib = $(IMPLIB_PREFIX)$(blt_pict_png_name)$(IMPLIB_EXT) blt_pict_ps_implib = $(IMPLIB_PREFIX)$(blt_pict_ps_name)$(IMPLIB_EXT) blt_pict_tif_implib = $(IMPLIB_PREFIX)$(blt_pict_tif_name)$(IMPLIB_EXT) blt_pict_xbm_implib = $(IMPLIB_PREFIX)$(blt_pict_xbm_name)$(IMPLIB_EXT) blt_pict_xpm_implib = $(IMPLIB_PREFIX)$(blt_pict_xpm_name)$(IMPLIB_EXT) blt_tree_xml_name = TreeXml$(version)$(LIB_SUFFIX) blt_tree_xml_so = $(blt_tree_xml_name)$(SO_EXT) blt_tree_xml_implib = $(IMPLIB_PREFIX)$(blt_tree_xml_name)$(IMPLIB_EXT) blt_core_pkgs_so = $(blt_dt_csv_so) \ $(blt_dt_tree_so) \ $(blt_dt_vec_so) ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif ifneq ("$(MYSQL_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_mysql_so) endif blt_x_pkgs_so = $(blt_pict_gif_so) \ $(blt_pict_xbm_so) \ $(blt_pict_bmp_so) \ $(blt_pict_pbm_so) \ $(blt_pict_pdf_so) \ $(blt_pict_ps_so) \ $(blt_pict_photo_so) ifneq ("$(JPG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_jpg_so) endif ifneq ("$(PNG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_png_so) endif ifneq ("$(XPM_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_xpm_so) endif ifneq ("$(XPM_TIF_SPEC)", "") blt_x_pkgs_so += $(blt_pict_tif_so) endif ifneq ("$(TCL_STUBS_SPEC)", "") tcl_lib_spec=$(TCL_STUBS_SPEC) else tcl_lib_spec=$(TCL_LIB_SPEC) endif ifneq ("$(TK_STUBS_SPEC)", "") tk_lib_spec=$(TK_STUBS_SPEC) else tk_lib_spec=$(TK_LIB_SPEC) endif ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ #N_OBJS = bltTed.o #V3_OBJS = bltTri.o bltGrMt.o #TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o #TREEVIEW_OBJS = bltTreeView.o \ bltTvCmd.o \ bltTvCol.o \ bltTvEdit.o \ bltTvStyle.o PICTURE_OBJS = bltPicture.o \ bltPictCmd.o \ bltPictDraw.o \ # bltPictMmx.o #PICTURE_PKG_OBJS = bltPictBmp.o \ bltPictGif.o \ bltPictJpg.o \ bltPictPbm.o \ bltPictPdf.o \ bltPictPhoto.o \ bltPictPng.o \ bltPictPs.o \ bltPictTif.o \ bltPictXbm.o \ bltPictXpm.o #TREE_OBJS = bltTree.o \ bltTreeCmd.o \ #TREE_PKG_OBJS = bltTreeXml.o DATATABLE_OBJS = bltDataTable.o \ # bltDtCmd.o \ #DATATABLE_PKG_OBJS = bltDtCsv.o \ bltDtMysql.o \ bltDtTree.o \ bltDtVec.o \ bltDtXml.o BLT_CORE_SO_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBase64.o \ bltChain.o \ $(DATATABLE_OBJS) \ bltHash.o \ bltInit.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltDBuffer.o \ bltSpline.o \ bltSwitch.o \ $(TREE_OBJS) \ bltUtil.o \ bltVar.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltWinDde.o \ bltWinUtil.o \ bltCoreInit.o \ # bltBgexec.o \ bltCrc32.o \ bltCsv.o \ bltDebug.o \ bltWatch.o \ bltWinPipe.o \ pure_api.o BLT_CORE_A_OBJS = $(BLT_CORE_SO_OBJS) \ $(TREE_PKG_OBJS) \ $(DATATABLE_PKG_OBJS) BLT_X_SO_OBJS = $(GRAPH_OBJS) \ $(PICTURE_OBJS) \ $(TREEVIEW_OBJS) \ bltBgStyle.o \ bltBind.o \ bltBusy.o \ bltConfig.o \ bltImage.o \ bltPs.o \ bltPsAfm.o \ bltText.o \ bltWinBitmap.o \ bltWinDraw.o \ bltWinFont.o \ bltWinPainter.o \ bltWinPrnt.o \ bltWinWindow.o \ bltWindow.o \ bltExtInit.o \ $(TK_OBJS) $(N_OBJS) # bltBeep.o \ bltBitmap.o \ bltCanvEps.o \ bltComboBtn.o \ bltComboEntry.o \ bltComboMenu.o \ bltComboTree.o \ bltContainer.o \ bltCutbuffer.o \ bltDragdrop.o \ bltHtext.o \ bltListView.o \ bltMenubar.o \ bltOldConfig.o \ bltPaneset.o \ bltScrollset.o \ bltTable.o \ bltTabset.o \ bltWinop.o \ BLT_X_A_OBJS = $(BLT_X_SO_OBJS) \ $(PICTURE_PKG_OBJS) BLT_SO_OBJS = $(BLT_CORE_SO_OBJS) \ $(BLT_X_SO_OBJS) BLT_A_OBJS = $(BLT_CORE_A_OBJS) \ $(BLT_X_A_OBJS) # GNU Make-specific macro SRCS = $(patsubst %.o,$(srcdir)/%.c,$(BLT_A_OBJS)) bltwish = bltwish$(version).exe bltsh = bltsh$(version).exe # Public headers to be installed headers = $(srcdir)/blt.h \ $(srcdir)/bltBind.h \ $(srcdir)/bltChain.h \ bltHash.h \ $(srcdir)/bltList.h \ $(srcdir)/bltPool.h \ $(srcdir)/bltTree.h \ $(srcdir)/bltVector.h CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) MAIN_CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ DESTDIR = RANLIB = @RANLIB@ SHELL = /bin/sh AR = ar rc RM = rm -f LINT = splint LINTFLAGS = #-axhbns XREF = cxref XREFFLAGS = -dltR LN_S = @LN_S@ VPATH = $(srcdir) all: build_libs build_demos build_demos: $(bltsh) $(bltwish) build_libs: build_@BLT_TARGET@ build_shared: $(blt_core_so) $(blt_x_so) build_core_pkgs build_x_pkgs build_static: $(blt_core_a) $(blt_x_a) build_core_pkgs: $(blt_core_pkgs_so) build_x_pkgs: $(blt_x_pkgs_so) $(bltwish): $(blt_core_a) $(blt_x_a) $(srcdir)/bltWinMain.c $(srcdir)/tkConsole.o $(RM) $(bltwish) $(CC) $(MAIN_CC_OPTS) $(LDFLAGS) -o $(bltwish) \ -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltWinMain.c $(srcdir)/tkConsole.c \ $(blt_x_a) $(blt_core_a) \ $(TK_LIB_SPEC) $(TCL_LIB_SPEC) \ $(BLT_X_A_LIBS) $(BLT_CORE_A_LIBS) \ $(EXTRA_X_LIBS) -mwindows $(bltsh): $(blt_core_a) $(srcdir)/bltWinMain.c $(RM) $(bltsh) $(CC) $(CC_OPTS) $(LDFLAGS) -o $(bltsh) \ -DTCL_ONLY -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltWinMain.c \ $(blt_core_a) \ $(TCL_STUBS_SPEC) $(TCL_LIB_SPEC) \ $(BLT_CORE_A_LIBS) \ $(EXTRA_CORE_LIBS) -mconsole $(blt_core_a): $(BLT_CORE_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_CORE_A_OBJS) $(RANLIB) $@ $(blt_x_a): $(BLT_X_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_X_A_OBJS) $(RANLIB) $@ $(blt_core_so): $(BLT_CORE_SO_OBJS) $(RM) $@ $(CC) -shared -Wl,--dll -o $(blt_core_so) \ -Wl,--out-implib=$(blt_core_implib) \ $(BLT_CORE_SO_OBJS) $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) \ -mconsole $(blt_x_so): $(BLT_X_SO_OBJS) bltExtInit.o $(blt_core_so) $(RM) $@ $(CC) -shared -o $(blt_x_so) \ -Wl,--out-implib=$(blt_x_implib) \ $(BLT_X_SO_OBJS) $(blt_core_so) \ $(BLT_X_SO_LIBS) $(BLT_CORE_SO_LIBS) \ $(tcl_lib_spec) $(tk_lib_spec) \ -mwindows -lwinspool $(blt_dt_mysql_so): bltDtMysql.o $(blt_core_implib) $(RM) $@ $(CC) -shared -o $(blt_dt_mysql_so) \ -Wl,--out-implib=$(blt_dt_mysql_implib) bltDtMysql.o \ $(blt_core_so) $(tcl_lib_spec) $(MYSQL_LIB_SPEC) $(blt_dt_xml_so): bltDtXml.o $(blt_core_implib) $(RM) $@ $(CC) -shared -o $(blt_dt_xml_so) \ -Wl,--out-implib=$(blt_dt_xml_implib) bltDtXml.o \ $(blt_core_so) $(tcl_lib_spec) $(EXPAT_LIB_SPEC) $(blt_dt_csv_so): bltDtCsv.o $(blt_core_implib) $(RM) $@ $(CC) -shared -Wl,--dll -o $(blt_dt_csv_so) \ -Wl,--out-implib=$(blt_dt_csv_implib) bltDtCsv.o \ $(blt_core_so) $(tcl_lib_spec) $(blt_dt_vec_so): bltDtVec.o $(blt_core_implib) $(RM) $@ $(CC) -shared -o $(blt_dt_vec_so) \ -Wl,--out-implib=$(blt_dt_vec_implib) bltDtVec.o \ $(blt_core_so) $(tcl_lib_spec) $(blt_dt_tree_so): bltDtTree.o $(blt_core_implib) $(RM) $@ $(CC) -shared -o $(blt_dt_tree_so) \ -Wl,--out-implib=$(blt_dt_tree_implib) bltDtTree.o \ $(blt_core_so) $(tcl_lib_spec) $(blt_tree_xml_so): bltTreeXml.o $(blt_core_implib) $(RM) $@ $(CC) -shared -o $(blt_tree_xml_so) \ -Wl,--out-implib=$(blt_tree_xml_implib) bltTreeXml.o \ $(blt_core_so) $(tcl_lib_spec) $(EXPAT_LIB_SPEC) $(blt_pict_bmp_so): bltPictBmp.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_bmp_so) \ -Wl,--out-implib=$(blt_pict_bmp_implib) bltPictBmp.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(blt_pict_gif_so): bltPictGif.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_gif_so) \ -Wl,--out-implib=$(blt_pict_gif_implib) bltPictGif.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(blt_pict_jpg_so): bltPictJpg.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_jpg_so) \ -Wl,--out-implib=$(blt_pict_jpg_implib) bltPictJpg.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(JPG_LIB_SPEC) $(blt_pict_png_so): bltPictPng.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_png_so) \ -Wl,--out-implib=$(blt_pict_png_implib) bltPictPng.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(PNG_LIB_SPEC) $(blt_pict_pbm_so): bltPictPbm.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_pbm_so) \ -Wl,--out-implib=$(blt_pict_pbm_implib) bltPictPbm.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(blt_pict_pdf_so): bltPictPdf.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_pdf_so) \ -Wl,--out-implib=$(blt_pict_pdf_implib) bltPictPdf.o \ $(blt_core_so) $(blt_x_so) $(tk_lib_spec) $(tcl_lib_spec) $(blt_pict_tif_so): bltPictTif.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_tif_so) \ -Wl,--out-implib=$(blt_pict_tif_implib) bltPictTif.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(TIF_LIB_SPEC) $(blt_pict_xbm_so): bltPictXbm.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_xbm_so) \ -Wl,--out-implib=$(blt_pict_xbm_implib) bltPictXbm.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(blt_pict_xpm_so): bltPictXpm.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_xpm_so) \ -Wl,--out-implib=$(blt_pict_xpm_implib) bltPictXpm.o \ $(blt_core_so) $(blt_x_so) $(tcl_lib_spec) $(XPM_LIB_SPEC) $(blt_pict_ps_so): bltPictPs.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_ps_so) \ -Wl,--out-implib=$(blt_pict_ps_implib) bltPictPs.o \ $(blt_core_so) $(blt_x_so) $(tk_lib_spec) $(tcl_lib_spec) $(blt_pict_photo_so): bltPictPhoto.o $(blt_core_so) $(blt_x_so) $(RM) $@ $(CC) -shared -o $(blt_pict_photo_so) \ -Wl,--out-implib=$(blt_pict_photo_implib) bltPictPhoto.o \ $(blt_core_so) $(blt_x_so) $(tk_lib_spec) $(tcl_lib_spec) install: mkdirs install-demos install-libs install-headers install-libs: install-@BLT_TARGET@ install-demos: $(bltwish) $(bltsh) $(INSTALL) -m 0755 $(bltwish) $(DESTDIR)$(bindir) $(INSTALL) -m 0755 $(bltsh) $(DESTDIR)$(bindir) install-shared: $(blt_core_so) $(blt_x_so) install-pkgs install-static $(INSTALL) -m 0755 $(blt_core_so) $(DESTDIR)$(bindir) $(INSTALL) -m 0755 $(blt_x_so) $(DESTDIR)$(bindir) install-static: $(blt_core_a) $(blt_x_a) $(INSTALL_DATA) $(blt_core_a) $(DESTDIR)$(libdir) $(INSTALL_DATA) $(blt_x_a) $(DESTDIR)$(libdir) install-implib: $(blt_core_implib) $(blt_x_implib) $(INSTALL_DATA) $(blt_core_implib) $(DESTDIR)$(libdir) $(INSTALL_DATA) $(blt_x_implib) $(DESTDIR)$(libdir) install-pkgs: $(blt_core_pkgs_so) $(blt_x_pkgs_so) for i in $(blt_core_pkgs_so) $(blt_x_pkgs_so) ; do \ echo $(RM) $(DESTDIR)$(libdir)/$$i ; \ $(RM) $(DESTDIR)$(libdir)/$$i ; \ echo $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ done install-headers: @for i in $(headers) ; do \ echo "installing $$i..." ; \ $(INSTALL_DATA) -m 0444 $$i $(DESTDIR)$(incdir) ; \ done mkdirs: @for i in $(instdirs) ; do \ if test -d $(DESTDIR)$$i ; then \ : ; \ else \ echo " mkdir $(DESTDIR)$$i" ; \ $(INSTALL) -d $(DESTDIR)$$i ; \ fi ; \ done lint: $(LINT) $(LINTFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) xref: $(XREF) $(XREFFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) clean: clean-objs clean-libs clean-demos clean-libs: clean-@BLT_TARGET@ clean-objs: $(RM) $(BLT_A_OBJS) clean-demos: $(RM) $(bltsh)* $(bltwish)* *pure* .pure* clean-static: $(RM) $(blt_core_a) $(blt_x_a) clean-implib: $(RM) $(blt_core_implib) $(blt_x_implib) clean-pkgs: $(RM) $(blt_core_pkgs_so) $(blt_x_pkgs_so) clean-shared: clean-pkgs clean-static clean-implib $(RM) $(blt_core_so) $(blt_x_so) distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile $(RM) config.h bltHash.h Makefile TAGS bltDtMysql.o: $(srcdir)/bltDtMysql.c $(CC) -c $(CC_OPTS) $(MYSQL_INC_SPEC) $? bltDtXml.o: $(srcdir)/bltDtXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTree.o: $(srcdir)/bltTree.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTreeXml.o: $(srcdir)/bltTreeXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltPictDraw.o: $(srcdir)/bltPictDraw.c $(srcdir)/bltPaintDraw.c $(CC) -c $(CC_OPTS) $(FT2_INC_SPEC) $< bltPictJpg.o: $(srcdir)/bltPictJpg.c $(CC) -c $(CC_OPTS) $(JPG_INC_SPEC) $? bltPictTif.o: $(srcdir)/bltPictTif.c $(CC) -c $(CC_OPTS) $(TIF_INC_SPEC) $? bltPictPng.o: $(srcdir)/bltPictPng.c $(CC) -c $(CC_OPTS) $(PNG_INC_SPEC) $? bltPictXpm.o: $(srcdir)/bltPictXpm.c $(CC) -c $(CC_OPTS) $(XPM_INC_SPEC) $? bltCoreInit.o: $(srcdir)/bltCoreInit.c $(CC) -c $(CC_OPTS) -DTCL_ONLY -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ $(srcdir)/bltCoreInit.c .c.o: $(CC) -c $(CC_OPTS) $< �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWindow.c�������������������������������������������������������������������0000644�0001750�0001750�00000035475�11462120063�015161� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWindow.c -- * * This module implements additional window functions for the BLT * toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <X11/Xlib.h> #ifdef notdef /* WIN32 */ #include <X11/Xproto.h> #endif #include "tkDisplay.h" #include "bltHash.h" /* * Cache drawable information. * * There are specific times when we need information about the drawable * that is not available via the normal argument passing. For example, * XFT font rendering requires that the correct depth XftDraw be used. * If we create a painter from a drawable, we need to know its depth, * colormap, and visual also. * * We can usually get this information using XGetWindowAttributes at * the cost of a round-trip to the X server. Instead we'll cache it * in a hash table. We don't have to cache every window. We need to * watch destroy events and freeing pixmaps. */ typedef struct { Display *display; Drawable drawable; } DrawableKey; static Blt_HashTable attribTable; static int initialized = FALSE; Blt_DrawableAttributes * Blt_GetDrawableAttribs(Display *display, Drawable drawable) { if (drawable != None) { Blt_HashEntry *hPtr; DrawableKey key; if (!initialized) { Blt_InitHashTable(&attribTable, sizeof(DrawableKey)/sizeof(int)); initialized = TRUE; } memset(&key, 0, sizeof(key)); key.drawable = drawable; key.display = display; hPtr = Blt_FindHashEntry(&attribTable, &key); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } return NULL; /* Don't have any information about this * drawable. */ } void Blt_SetDrawableAttribs( Display *display, Drawable drawable, int depth, int width, int height, Colormap colormap, Visual *visual) { if (drawable != None) { Blt_DrawableAttributes *attrPtr; Blt_HashEntry *hPtr; int isNew; DrawableKey key; if (!initialized) { Blt_InitHashTable(&attribTable, sizeof(DrawableKey)/sizeof(int)); initialized = TRUE; } memset(&key, 0, sizeof(key)); key.drawable = drawable; key.display = display; hPtr = Blt_CreateHashEntry(&attribTable, &key, &isNew); if (isNew) { attrPtr = Blt_AssertMalloc(sizeof(Blt_DrawableAttributes)); Blt_SetHashValue(hPtr, attrPtr); } else { attrPtr = Blt_GetHashValue(hPtr); } /* Set or reset information for drawable. */ attrPtr->id = drawable; attrPtr->depth = depth; attrPtr->colormap = colormap; attrPtr->visual = visual; attrPtr->width = width; attrPtr->height = height; } } void Blt_SetDrawableAttribsFromWindow(Tk_Window tkwin, Drawable drawable) { if (drawable != None) { Blt_SetDrawableAttribs(Tk_Display(tkwin), drawable, Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin), Tk_Colormap(tkwin), Tk_Visual(tkwin)); } } void Blt_FreeDrawableAttribs(Display *display, Drawable drawable) { Blt_HashEntry *hPtr; DrawableKey key; if (drawable != None) { if (!initialized) { Blt_InitHashTable(&attribTable, sizeof(DrawableKey)/sizeof(int)); initialized = TRUE; } memset(&key, 0, sizeof(key)); key.drawable = drawable; key.display = display; hPtr = Blt_FindHashEntry(&attribTable, &key); if (hPtr != NULL) { Blt_DrawableAttributes *attrPtr; attrPtr = Blt_GetHashValue(hPtr); Blt_DeleteHashEntry(&attribTable, hPtr); Blt_Free(attrPtr); } } } /* *--------------------------------------------------------------------------- * * Blt_FindChild -- * * Performs a linear search for the named child window in a given * parent window. * * This can be done via Tcl, but not through Tk's C API. It's * simple enough, if you peek into the Tk_Window structure. * * Results: * The child Tk_Window. If the named child can't be found, NULL * is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Tk_Window Blt_FindChild(Tk_Window parent, char *name) { TkWindow *winPtr; TkWindow *parentPtr = (TkWindow *)parent; for (winPtr = parentPtr->childList; winPtr != NULL; winPtr = winPtr->nextPtr) { if (strcmp(name, winPtr->nameUid) == 0) { return (Tk_Window)winPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_FirstChildWindow -- * * Performs a linear search for the named child window in a given * parent window. * * This can be done via Tcl, but not through Tk's C API. It's * simple enough, if you peek into the Tk_Window structure. * * Results: * The child Tk_Window. If the named child can't be found, NULL * is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Tk_Window Blt_FirstChild(Tk_Window parent) { TkWindow *parentPtr = (TkWindow *)parent; return (Tk_Window)parentPtr->childList; } /* *--------------------------------------------------------------------------- * * Blt_FindChild -- * * Performs a linear search for the named child window in a given * parent window. * * This can be done via Tcl, but not through Tk's C API. It's * simple enough, if you peek into the Tk_Window structure. * * Results: * The child Tk_Window. If the named child can't be found, NULL * is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Tk_Window Blt_NextChild(Tk_Window tkwin) { TkWindow *winPtr = (TkWindow *)tkwin; if (winPtr == NULL) { return NULL; } return (Tk_Window)winPtr->nextPtr; } /* *--------------------------------------------------------------------------- * * UnlinkWindow -- * * This procedure removes a window from the childList of its * parent. * * Results: * None. * * Side effects: * The window is unlinked from its childList. * *--------------------------------------------------------------------------- */ static void UnlinkWindow(TkWindow *winPtr) { TkWindow *prevPtr; prevPtr = winPtr->parentPtr->childList; if (prevPtr == winPtr) { winPtr->parentPtr->childList = winPtr->nextPtr; if (winPtr->nextPtr == NULL) { winPtr->parentPtr->lastChildPtr = NULL; } } else { while (prevPtr->nextPtr != winPtr) { prevPtr = prevPtr->nextPtr; if (prevPtr == NULL) { panic("UnlinkWindow couldn't find child in parent"); } } prevPtr->nextPtr = winPtr->nextPtr; if (winPtr->nextPtr == NULL) { winPtr->parentPtr->lastChildPtr = prevPtr; } } } /* *--------------------------------------------------------------------------- * * Blt_RelinkWindow -- * * Relinks a window into a new parent. The window is unlinked * from its original parent's child list and added onto the end * of the new parent's list. * * FIXME: If the window has focus, the focus should be moved * to an ancestor. Otherwise, Tk becomes confused * about which Toplevel turns on focus for the window. * Right now this is done at the TCL layer. For example, * see blt::CreateTearoff in tabset.tcl. * * Results: * None. * * Side effects: * The window is unlinked from its childList. * *--------------------------------------------------------------------------- */ void Blt_RelinkWindow( Tk_Window tkwin, /* Child window to be linked. */ Tk_Window newParent, int x, int y) { TkWindow *winPtr, *parentWinPtr; if (Blt_ReparentWindow(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(newParent), x, y) != TCL_OK) { return; } winPtr = (TkWindow *)tkwin; parentWinPtr = (TkWindow *)newParent; winPtr->flags &= ~TK_REPARENTED; UnlinkWindow(winPtr); /* Remove the window from its parent's list */ /* Append the window onto the end of the parent's list of children */ winPtr->parentPtr = parentWinPtr; winPtr->nextPtr = NULL; if (parentWinPtr->childList == NULL) { parentWinPtr->childList = winPtr; } else { parentWinPtr->lastChildPtr->nextPtr = winPtr; } parentWinPtr->lastChildPtr = winPtr; } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_RelinkWindow -- * * Relinks a window into a new parent. The window is unlinked * from its original parent's child list and added onto the end * of the new parent's list. * * FIXME: If the window has focus, the focus should be moved * to an ancestor. Otherwise, Tk becomes confused * about which Toplevel turns on focus for the window. * Right now this is done at the TCL layer. For example, * see blt::CreateTearoff in tabset.tcl. * * Results: * None. * * Side effects: * The window is unlinked from its childList. * *--------------------------------------------------------------------------- */ void Blt_RelinkWindow2( Tk_Window tkwin, /* Child window to be linked. */ Window window, Tk_Window newParent, int x, int y) { #ifdef notdef TkWindow *winPtr, *parentWinPtr; #endif if (Blt_ReparentWindow(Tk_Display(tkwin), window, Tk_WindowId(newParent), x, y) != TCL_OK) { return; } #ifdef notdef winPtr = (TkWindow *)tkwin; parentWinPtr = (TkWindow *)newParent; winPtr->flags &= ~TK_REPARENTED; UnlinkWindow(winPtr); /* Remove the window from its parent's list */ /* Append the window onto the end of the parent's list of children */ winPtr->parentPtr = parentWinPtr; winPtr->nextPtr = NULL; if (parentWinPtr->childList == NULL) { parentWinPtr->childList = winPtr; } else { parentWinPtr->lastChildPtr->nextPtr = winPtr; } parentWinPtr->lastChildPtr = winPtr; #endif } void Blt_UnlinkWindow(Tk_Window tkwin) /* Child window to be linked. */ { TkWindow *winPtr; Window root; root = Tk_RootWindow(tkwin); if (Blt_ReparentWindow(Tk_Display(tkwin), Tk_WindowId(tkwin), root, 0, 0) != TCL_OK) { return; } winPtr = (TkWindow *)tkwin; winPtr->flags &= ~TK_REPARENTED; #ifdef notdef UnlinkWindow(winPtr); /* Remove the window from its parent's list */ #endif } #endif /* *--------------------------------------------------------------------------- * * Blt_Toplevel -- * * Climbs up the widget hierarchy to find the top level window of * the window given. * * Results: * Returns the Tk_Window of the toplevel widget. * *--------------------------------------------------------------------------- */ Tk_Window Blt_Toplevel(Tk_Window tkwin) { while (!Tk_IsTopLevel(tkwin)) { tkwin = Tk_Parent(tkwin); } return tkwin; } void Blt_RootCoordinates( Tk_Window tkwin, int x, int y, int *rootXPtr, int *rootYPtr) { int vx, vy, vw, vh; int rootX, rootY; Tk_GetRootCoords(tkwin, &rootX, &rootY); x += rootX; y += rootY; Tk_GetVRootGeometry(tkwin, &vx, &vy, &vw, &vh); x += vx; y += vy; *rootXPtr = x; *rootYPtr = y; } /* Find the toplevel then */ int Blt_RootX(Tk_Window tkwin) { int x; for (x = 0; tkwin != NULL; tkwin = Tk_Parent(tkwin)) { x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; if (Tk_IsTopLevel(tkwin)) { break; } } return x; } int Blt_RootY(Tk_Window tkwin) { int y; for (y = 0; tkwin != NULL; tkwin = Tk_Parent(tkwin)) { y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; if (Tk_IsTopLevel(tkwin)) { break; } } return y; } void Blt_SetWindowInstanceData(Tk_Window tkwin, ClientData instanceData) { TkWindow *winPtr = (TkWindow *)tkwin; winPtr->instanceData = instanceData; } ClientData Blt_GetWindowInstanceData(Tk_Window tkwin) { TkWindow *winPtr; while (tkwin != NULL) { winPtr = (TkWindow *)tkwin; if (winPtr->instanceData != NULL) { return (ClientData)winPtr->instanceData; } tkwin = Tk_Parent(tkwin); } return NULL; } void Blt_DeleteWindowInstanceData(Tk_Window tkwin) { /* empty */ } #if HAVE_RANDR #include <X11/Xlib.h> #include <X11/Xlibint.h> #include <X11/Xproto.h> #include <X11/extensions/randr.h> #include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrender.h> /* we share subpixel information */ typedef struct { int major, minor; /* XRandR version numbers. */ int eventNum, errorNum; /* Event offset of XRandr */ Display *display; Tk_Window mainWindow; /* Main window of interpreter. */ Window root; /* Root window of screen. */ } XRandr; /* *--------------------------------------------------------------------------- * * XRandrEventProc -- * * Invoked by Tk_HandleEvent whenever a ConfigureNotify or * RRScreenChangeNotify event is received on the root window. * *--------------------------------------------------------------------------- */ static int XRandrEventProc(ClientData clientData, XEvent *eventPtr) { XRandr *rrPtr = clientData; if (eventPtr->xany.window == rrPtr->root) { if ((eventPtr->type + (rrPtr->eventNum + RRScreenChangeNotify)) || (eventPtr->type == ConfigureNotify)) { if (!XRRUpdateConfiguration(eventPtr)) { fprintf(stderr, "can't update screen configuration\n"); } } } return 0; } void Blt_InitXRandrConfig(Tcl_Interp *interp) { Tk_Window tkwin; static XRandr rr; tkwin = Tk_MainWindow(interp); rr.mainWindow = tkwin; rr.root = Tk_RootWindow(tkwin); rr.display = Tk_Display(tkwin); if (!XRRQueryExtension(rr.display, &rr.eventNum, &rr.errorNum)) { fprintf(stderr, "Xserver does not support the RANDR extension.\n"); return; } if (!XRRQueryVersion(rr.display, &rr.major, &rr.minor)) { fprintf(stderr, "Xserver didn't report RANDR version numbers?\n"); } Tk_CreateGenericHandler(XRandrEventProc, &rr); XRRSelectInput(rr.display, rr.root, RRScreenChangeNotifyMask); #ifdef notdef XSelectInput(rr.display, rr.root, StructureNotifyMask); #endif } #else void Blt_InitXRandrConfig(Tcl_Interp *interp) { } #endif /* HAVE_XRANDR */ /* ARGSUSED */ void Blt_SizeOfScreen(Tk_Window tkwin, int *widthPtr, int *heightPtr) { *widthPtr = WidthOfScreen(Tk_Screen(tkwin)); *heightPtr = HeightOfScreen(Tk_Screen(tkwin)); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltConfig.c�������������������������������������������������������������������0000644�0001750�0001750�00000200512�11462120062�015100� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltConfig.c -- * * This file contains a Tcl_Obj based replacement for the widget * configuration functions in Tk. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * This is a Tcl_Obj based replacement for the widget configuration * functions in Tk. * * What not use the new Tk_Option interface? * * There were design changes in the new Tk_Option interface that * make it unwieldy. * * o You have to dynamically allocate, store, and deallocate * your option table. * o The Tk_FreeConfigOptions routine requires a tkwin argument. * Unfortunately, most widgets save the display pointer and * de-reference their tkwin when the window is destroyed. * o There's no TK_CONFIG_CUSTOM functionality. This means that * save special options must be saved as strings by * Tk_ConfigureWidget and processed later, thus losing the * benefits of Tcl_Objs. It also make error handling * problematic, since you don't pick up certain errors like * * .widget configure -myoption bad -myoption good * * You will never see the first "bad" value. * o Especially compared to the former Tk_ConfigureWidget calls, * the new interface is overly complex. If there was a big * performance win, it might be worth the effort. But let's * face it, this biggest wins are in processing custom options * values with thousands of elements. Most common resources * (font, color, etc) have string tokens anyways. * * On the other hand, the replacement functions in this file fell * into place quite easily both from the aspect of API writer and * user. The biggest benefit is that you don't need to change lots * of working code just to get the benefits of Tcl_Objs. * */ #include "bltInt.h" #include <stdarg.h> #include "bltFont.h" #include "bltPicture.h" #include "bltBgStyle.h" #if (_TK_VERSION < _VERSION(8,1,0)) /* *--------------------------------------------------------------------------- * * Tk_GetAnchorFromObj -- * * Return a Tk_Anchor value based on the value of the objPtr. * * Results: * The return value is a standard TCL result. If an error occurs during * conversion, an error message is left in the interpreter's result * unless "interp" is NULL. * * Side effects: * The object gets converted by Tcl_GetIndexFromObj. * *--------------------------------------------------------------------------- */ int Tk_GetAnchorFromObj( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Obj *objPtr, /* The object we are trying to get the * value from. */ Tk_Anchor *anchorPtr) /* Where to place the Tk_Anchor that * corresponds to the string value of * objPtr. */ { return Tk_GetAnchor(interp, Tcl_GetString(objPtr), anchorPtr); } /* *--------------------------------------------------------------------------- * * Tk_GetJustifyFromObj -- * * Return a Tk_Justify value based on the value of the objPtr. * * Results: * The return value is a standard TCL result. If an error occurs during * conversion, an error message is left in the interpreter's result * unless "interp" is NULL. * * Side effects: * The object gets converted by Tcl_GetIndexFromObj. * *--------------------------------------------------------------------------- */ int Tk_GetJustifyFromObj( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Obj *objPtr, /* The object we are trying to get the * value from. */ Tk_Justify *justifyPtr) /* Where to place the Tk_Justify that * corresponds to the string value of * objPtr. */ { return Tk_GetJustify(interp, Tcl_GetString(objPtr), justifyPtr); } /* *--------------------------------------------------------------------------- * * Tk_GetReliefFromObj -- * * Return an integer value based on the value of the objPtr. * * Results: * The return value is a standard TCL result. If an error occurs during * conversion, an error message is left in the interpreter's result * unless "interp" is NULL. * * Side effects: * The object gets converted by Tcl_GetIndexFromObj. * *--------------------------------------------------------------------------- */ int Tk_GetReliefFromObj( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Obj *objPtr, /* The object we are trying to get the * value from. */ int *reliefPtr) /* Where to place the answer. */ { return Tk_GetRelief(interp, Tcl_GetString(objPtr), reliefPtr); } /* *--------------------------------------------------------------------------- * * Tk_Alloc3DBorderFromObj -- * * Given a Tcl_Obj *, map the value to a corresponding * Tk_3DBorder structure based on the tkwin given. * * Results: * The return value is a token for a data structure describing a * 3-D border. This token may be passed to procedures such as * Blt_Draw3DRectangle and Tk_Free3DBorder. If an error prevented * the border from being created then NULL is returned and an error * message will be left in the interp's result. * * Side effects: * The border is added to an internal database with a reference * count. For each call to this procedure, there should eventually * be a call to FreeBorderObjProc so that the database is * cleaned up when borders aren't in use anymore. * *--------------------------------------------------------------------------- */ Tk_3DBorder Tk_Alloc3DBorderFromObj( Tcl_Interp *interp, /* Interp for error results. */ Tk_Window tkwin, /* Need the screen the border is used on.*/ Tcl_Obj *objPtr) /* Object giving name of color for window * background. */ { return Tk_Get3DBorder(interp, tkwin, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * Tk_AllocBitmapFromObj -- * * Given a Tcl_Obj *, map the value to a corresponding * Pixmap structure based on the tkwin given. * * Results: * The return value is the X identifer for the desired bitmap * (i.e. a Pixmap with a single plane), unless string couldn't be * parsed correctly. In this case, None is returned and an error * message is left in the interp's result. The caller should never * modify the bitmap that is returned, and should eventually call * Tk_FreeBitmapFromObj when the bitmap is no longer needed. * * Side effects: * The bitmap is added to an internal database with a reference count. * For each call to this procedure, there should eventually be a call * to Tk_FreeBitmapFromObj, so that the database can be cleaned up * when bitmaps aren't needed anymore. * *--------------------------------------------------------------------------- */ Pixmap Tk_AllocBitmapFromObj( Tcl_Interp *interp, /* Interp for error results. This may * be NULL. */ Tk_Window tkwin, /* Need the screen the bitmap is used on.*/ Tcl_Obj *objPtr) /* Object describing bitmap; see manual * entry for legal syntax of string value. */ { return Tk_GetBitmap(interp, tkwin, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * Tk_AllocFontFromObj -- * * Given a string description of a font, map the description to a * corresponding Blt_Font that represents the font. * * Results: * The return value is token for the font, or NULL if an error * prevented the font from being created. If NULL is returned, an * error message will be left in interp's result object. * * Side effects: * The font is added to an internal database with a reference * count. For each call to this procedure, there should eventually * be a call to Blt_FreeFont() or Blt_FreeFontFromObj() so that the * database is cleaned up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ Tk_Font Tk_AllocFontFromObj( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For screen on which font will be used. */ Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { return Tk_GetFont(interp, tkwin, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * Tk_AllocCursorFromObj -- * * Given a Tcl_Obj *, map the value to a corresponding * Tk_Cursor structure based on the tkwin given. * * Results: * The return value is the X identifer for the desired cursor, * unless objPtr couldn't be parsed correctly. In this case, * None is returned and an error message is left in the interp's result. * The caller should never modify the cursor that is returned, and * should eventually call Tk_FreeCursorFromObj when the cursor is no * longer needed. * * Side effects: * The cursor is added to an internal database with a reference count. * For each call to this procedure, there should eventually be a call * to Tk_FreeCursorFromObj, so that the database can be cleaned up * when cursors aren't needed anymore. * *--------------------------------------------------------------------------- */ Tk_Cursor Tk_AllocCursorFromObj( Tcl_Interp *interp, /* Interp for error results. */ Tk_Window tkwin, /* Window in which the cursor will be used.*/ Tcl_Obj *objPtr) /* Object describing cursor; see manual * entry for description of legal * syntax of this obj's string rep. */ { return Tk_GetCursor(interp, tkwin, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * Tk_AllocColorFromObj -- * * Given a Tcl_Obj *, map the value to a corresponding * XColor structure based on the tkwin given. * * Results: * The return value is a pointer to an XColor structure that * indicates the red, blue, and green intensities for the color * given by the string in objPtr, and also specifies a pixel value * to use to draw in that color. If an error occurs, NULL is * returned and an error message will be left in interp's result * (unless interp is NULL). * * Side effects: * The color is added to an internal database with a reference count. * For each call to this procedure, there should eventually be a call * to Tk_FreeColorFromObj so that the database is cleaned up when colors * aren't in use anymore. * *--------------------------------------------------------------------------- */ XColor * Tk_AllocColorFromObj( Tcl_Interp *interp, /* Used only for error reporting. If NULL, * then no messages are provided. */ Tk_Window tkwin, /* Window in which the color will be used.*/ Tcl_Obj *objPtr) /* Object that describes the color; string * value is a color name such as "red" or * "#ff0000".*/ { const char *string; string = Tcl_GetString(objPtr); return Tk_GetColor(interp, tkwin, Tk_GetUid(string)); } #endif /* *--------------------------------------------------------------------------- * * Blt_GetPositionFromObj -- * * Convert a string representing a numeric position. * A position can be in one of the following forms. * * number - number of the item in the hierarchy, indexed * from zero. * "end" - last position in the hierarchy. * * Results: * A standard TCL result. If "string" is a valid index, then * *indexPtr is filled with the corresponding numeric index. * If "end" was selected then *indexPtr is set to -1. * Otherwise an error message is left in interp->result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_GetPositionFromObj( Tcl_Interp *interp, /* Interpreter to report results back * to. */ Tcl_Obj *objPtr, /* Tcl_Obj representation of the index. * Can be an integer or "end" to refer * to the last index. */ long *indexPtr) /* Holds the converted index. */ { const char *string; string = Tcl_GetString(objPtr); if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { *indexPtr = -1; /* Indicates last position in hierarchy. */ } else { long position; if (Tcl_GetLongFromObj(interp, objPtr, &position) != TCL_OK) { return TCL_ERROR; } if (position < 0) { Tcl_AppendResult(interp, "bad position \"", string, "\"", (char *)NULL); return TCL_ERROR; } *indexPtr = position; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetPixelsFromObj -- * * Like Tk_GetPixelsFromObj, but checks for negative, zero. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ int Blt_GetPixelsFromObj( Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int check, /* Can be PIXELS_POS, PIXELS_NNEG, * or PIXELS_ANY, */ int *valuePtr) { int length; if (Tk_GetPixelsFromObj(interp, tkwin, objPtr, &length) != TCL_OK) { return TCL_ERROR; } if (length >= SHRT_MAX) { Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), "\": too big to represent", (char *)NULL); return TCL_ERROR; } switch (check) { case PIXELS_NNEG: if (length < 0) { Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), "\": can't be negative", (char *)NULL); return TCL_ERROR; } break; case PIXELS_POS: if (length <= 0) { Tcl_AppendResult(interp, "bad distance \"", Tcl_GetString(objPtr), "\": must be positive", (char *)NULL); return TCL_ERROR; } break; case PIXELS_ANY: break; } *valuePtr = length; return TCL_OK; } int Blt_GetPadFromObj( Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window */ Tcl_Obj *objPtr, /* Pixel value string */ Blt_Pad *padPtr) { int side1, side2; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if ((objc < 1) || (objc > 2)) { Tcl_AppendResult(interp, "wrong # elements in padding list", (char *)NULL); return TCL_ERROR; } if (Blt_GetPixelsFromObj(interp, tkwin, objv[0], PIXELS_NNEG, &side1) != TCL_OK) { return TCL_ERROR; } side2 = side1; if ((objc > 1) && (Blt_GetPixelsFromObj(interp, tkwin, objv[1], PIXELS_NNEG, &side2) != TCL_OK)) { return TCL_ERROR; } /* Don't update the pad structure until we know both values are okay. */ padPtr->side1 = side1; padPtr->side2 = side2; return TCL_OK; } int Blt_GetStateFromObj( Tcl_Interp *interp, /* Interpreter to send results back to */ Tcl_Obj *objPtr, /* Pixel value string */ int *statePtr) { char c; const char *string; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "normal", length) == 0)) { *statePtr = STATE_NORMAL; } else if ((c == 'd') && (strncmp(string, "disabled", length) == 0)) { *statePtr = STATE_DISABLED; } else if ((c == 'a') && (strncmp(string, "active", length) == 0)) { *statePtr = STATE_ACTIVE; } else { Tcl_AppendResult(interp, "bad state \"", string, "\": should be normal, active, or disabled", (char *)NULL); return TCL_ERROR; } return TCL_OK; } const char * Blt_NameOfState(int state) { switch (state) { case STATE_ACTIVE: return "active"; case STATE_DISABLED: return "disabled"; case STATE_NORMAL: return "normal"; default: return "???"; } } /* *--------------------------------------------------------------------------- * * Blt_NameOfFill -- * * Converts the integer representing the fill style into a string. * *--------------------------------------------------------------------------- */ const char * Blt_NameOfFill(int fill) { switch (fill) { case FILL_X: return "x"; case FILL_Y: return "y"; case FILL_NONE: return "none"; case FILL_BOTH: return "both"; default: return "unknown value"; } } /* *--------------------------------------------------------------------------- * * Blt_GetFillFromObj -- * * Converts the fill style string into its numeric representation. * * Valid style strings are: * * "none" Use neither plane. * "x" X-coordinate plane. * "y" Y-coordinate plane. * "both" Use both coordinate planes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_GetFillFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *fillPtr) { char c; const char *string; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "none", length) == 0)) { *fillPtr = FILL_NONE; } else if ((c == 'x') && (strncmp(string, "x", length) == 0)) { *fillPtr = FILL_X; } else if ((c == 'y') && (strncmp(string, "y", length) == 0)) { *fillPtr = FILL_Y; } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) { *fillPtr = FILL_BOTH; } else { Tcl_AppendResult(interp, "bad argument \"", string, "\": should be \"none\", \"x\", \"y\", or \"both\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_NameOfResize -- * * Converts the resize value into its string representation. * * Results: * Returns a pointer to the static name string. * *--------------------------------------------------------------------------- */ const char * Blt_NameOfResize(int resize) { switch (resize & RESIZE_BOTH) { case RESIZE_NONE: return "none"; case RESIZE_EXPAND: return "expand"; case RESIZE_SHRINK: return "shrink"; case RESIZE_BOTH: return "both"; default: return "unknown resize value"; } } /* *--------------------------------------------------------------------------- * * Blt_GetResizeFromObj -- * * Converts the resize string into its numeric representation. * * Valid style strings are: * * "none" * "expand" * "shrink" * "both" * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_GetResizeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resizePtr) { char c; const char *string; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "none", length) == 0)) { *resizePtr = RESIZE_NONE; } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) { *resizePtr = RESIZE_BOTH; } else if ((c == 'e') && (strncmp(string, "expand", length) == 0)) { *resizePtr = RESIZE_EXPAND; } else if ((c == 's') && (strncmp(string, "shrink", length) == 0)) { *resizePtr = RESIZE_SHRINK; } else { Tcl_AppendResult(interp, "bad resize argument \"", string, "\": should be \"none\", \"expand\", \"shrink\", or \"both\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetDashesFromObj -- * * Converts a TCL list of dash values into a dash list ready for * use with XSetDashes. * * A valid list dash values can have zero through 11 elements * (PostScript limit). Values must be between 1 and 255. Although * a list of 0 (like the empty string) means no dashes. * * Results: * A standard TCL result. If the list represented a valid dash * list TCL_OK is returned and *dashesPtr* will contain the * valid dash list. Otherwise, TCL_ERROR is returned and * interp->result will contain an error message. * * *--------------------------------------------------------------------------- */ int Blt_GetDashesFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Dashes *dashesPtr) { const char *string; char c; string = Tcl_GetString(objPtr); if (string == NULL) { dashesPtr->values[0] = 0; return TCL_OK; } c = string[0]; if (c == '\0') { dashesPtr->values[0] = 0; } else if ((c == 'd') && (strcmp(string, "dot") == 0)) { /* 1 */ dashesPtr->values[0] = 1; dashesPtr->values[1] = 0; } else if ((c == 'd') && (strcmp(string, "dash") == 0)) { /* 5 2 */ dashesPtr->values[0] = 5; dashesPtr->values[1] = 2; dashesPtr->values[2] = 0; } else if ((c == 'd') && (strcmp(string, "dashdot") == 0)) { /* 2 4 2 */ dashesPtr->values[0] = 2; dashesPtr->values[1] = 4; dashesPtr->values[2] = 2; dashesPtr->values[3] = 0; } else if ((c == 'd') && (strcmp(string, "dashdotdot") == 0)) { /* 2 4 2 2 */ dashesPtr->values[0] = 2; dashesPtr->values[1] = 4; dashesPtr->values[2] = 2; dashesPtr->values[3] = 2; dashesPtr->values[4] = 0; } else { int objc; Tcl_Obj **objv; int i; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 11) { /* This is the postscript limit */ Tcl_AppendResult(interp, "too many values in dash list \"", string, "\"", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i++) { int value; if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { return TCL_ERROR; } /* * Backward compatibility: * Allow list of 0 to turn off dashes */ if ((value == 0) && (objc == 1)) { break; } if ((value < 1) || (value > 255)) { Tcl_AppendResult(interp, "dash value \"", Tcl_GetString(objv[i]), "\" is out of range", (char *)NULL); return TCL_ERROR; } dashesPtr->values[i] = (unsigned char)value; } /* Make sure the array ends with a NUL byte */ dashesPtr->values[i] = 0; } return TCL_OK; } const char * Blt_NameOfSide(int side) { switch (side) { case SIDE_LEFT: return "left"; case SIDE_RIGHT: return "right"; case SIDE_BOTTOM: return "bottom"; case SIDE_TOP: return "top"; } return "unknown side value"; } /* *--------------------------------------------------------------------------- * * Blt_GetSideFromObj -- * * Converts the fill style string into its numeric representation. * * Valid style strings are "left", "right", "top", or "bottom". * *--------------------------------------------------------------------------- */ /*ARGSUSED */ int Blt_GetSideFromObj( Tcl_Interp *interp, /* Interpreter to send results back to */ Tcl_Obj *objPtr, /* Value string */ int *sidePtr) /* (out) Token representing side: * either SIDE_LEFT, SIDE_RIGHT, * SIDE_TOP, or SIDE_BOTTOM. */ { char c; const char *string; int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'l') && (strncmp(string, "left", length) == 0)) { *sidePtr = SIDE_LEFT; } else if ((c == 'r') && (strncmp(string, "right", length) == 0)) { *sidePtr = SIDE_RIGHT; } else if ((c == 't') && (strncmp(string, "top", length) == 0)) { *sidePtr = SIDE_TOP; } else if ((c == 'b') && (strncmp(string, "bottom", length) == 0)) { *sidePtr = SIDE_BOTTOM; } else { Tcl_AppendResult(interp, "bad side \"", string, "\": should be left, right, top, or bottom", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ResetLimits -- * * Resets the limits to their default values. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_ResetLimits(Blt_Limits *limitsPtr) /* Limits to be imposed on the value */ { limitsPtr->flags = 0; limitsPtr->min = LIMITS_MIN; limitsPtr->max = LIMITS_MAX; limitsPtr->nom = LIMITS_NOM; } int Blt_GetLimitsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Blt_Limits *limitsPtr) { int values[3]; int nValues; int limitsFlags; /* Initialize limits to default values */ values[2] = LIMITS_NOM; values[1] = LIMITS_MAX; values[0] = LIMITS_MIN; limitsFlags = 0; nValues = 0; if (objPtr != NULL) { Tcl_Obj **objv; int objc; int i; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 3) { Tcl_AppendResult(interp, "wrong # limits \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i++) { const char *string; int size; string = Tcl_GetString(objv[i]); if (string[0] == '\0') { continue; /* Empty string: use default value */ } limitsFlags |= (1 << i); if (Tk_GetPixelsFromObj(interp, tkwin, objv[i], &size) != TCL_OK) { return TCL_ERROR; } if ((size < LIMITS_MIN) || (size > LIMITS_MAX)) { Tcl_AppendResult(interp, "bad limit \"", string, "\"", (char *)NULL); return TCL_ERROR; } values[i] = size; } nValues = objc; } /* * Check the limits specified. We can't check the requested size of * widgets. */ switch (nValues) { case 1: limitsFlags |= (LIMITS_MIN_SET | LIMITS_MAX_SET); values[1] = values[0]; /* Set minimum and maximum to value */ break; case 2: if (values[1] < values[0]) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } break; case 3: if (values[1] < values[0]) { Tcl_AppendResult(interp, "bad range \"", Tcl_GetString(objPtr), "\": min > max", (char *)NULL); return TCL_ERROR; /* Minimum is greater than maximum */ } if ((values[2] < values[0]) || (values[2] > values[1])) { Tcl_AppendResult(interp, "nominal value \"", Tcl_GetString(objPtr), "\" out of range", (char *)NULL); return TCL_ERROR; /* Nominal is outside of range defined * by minimum and maximum */ } break; } limitsPtr->min = values[0]; limitsPtr->max = values[1]; limitsPtr->nom = values[2]; limitsPtr->flags = limitsFlags; return TCL_OK; } /* Configuration option helper routines */ /* *--------------------------------------------------------------------------- * * DoConfig -- * * This procedure applies a single configuration option * to a widget record. * * Results: * A standard TCL return value. * * Side effects: * WidgRec is modified as indicated by specPtr and value. * The old value is recycled, if that is appropriate for * the value type. * *--------------------------------------------------------------------------- */ static int DoConfig( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window containing widget (needed to * set up X resources). */ Blt_ConfigSpec *sp, /* Specifier to apply. */ Tcl_Obj *objPtr, /* Value to use to fill in widgRec. */ char *widgRec) /* Record whose fields are to be * modified. Values must be properly * initialized. */ { char *ptr; int objIsEmpty; objIsEmpty = FALSE; if (objPtr == NULL) { objIsEmpty = TRUE; } else if (sp->specFlags & BLT_CONFIG_NULL_OK) { int length; if (objPtr->bytes != NULL) { length = objPtr->length; } else { Tcl_GetStringFromObj(objPtr, &length); } objIsEmpty = (length == 0); } do { ptr = widgRec + sp->offset; switch (sp->type) { case BLT_CONFIG_ANCHOR: { Tk_Anchor anchor; if (Tk_GetAnchorFromObj(interp, objPtr, &anchor) != TCL_OK) { return TCL_ERROR; } *(Tk_Anchor *)ptr = anchor; } break; case BLT_CONFIG_BITMAP: { Pixmap bitmap; if (objIsEmpty) { bitmap = None; } else { bitmap = Tk_AllocBitmapFromObj(interp, tkwin, objPtr); if (bitmap == None) { return TCL_ERROR; } } if (*(Pixmap *)ptr != None) { Tk_FreeBitmap(Tk_Display(tkwin), *(Pixmap *)ptr); } *(Pixmap *)ptr = bitmap; } break; case BLT_CONFIG_BOOLEAN: { int bool; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = bool; } break; case BLT_CONFIG_BORDER: { Tk_3DBorder border; if (objIsEmpty) { border = NULL; } else { border = Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr); if (border == NULL) { return TCL_ERROR; } } if (*(Tk_3DBorder *)ptr != NULL) { Tk_Free3DBorder(*(Tk_3DBorder *)ptr); } *(Tk_3DBorder *)ptr = border; } break; case BLT_CONFIG_CAP_STYLE: { int cap; Tk_Uid uid; uid = Tk_GetUid(Tcl_GetString(objPtr)); if (Tk_GetCapStyle(interp, uid, &cap) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = cap; } break; case BLT_CONFIG_COLOR: { XColor *color; if (objIsEmpty) { color = NULL; } else { color = Tk_GetColor(interp, tkwin, Tk_GetUid(Tcl_GetString(objPtr))); if (color == NULL) { return TCL_ERROR; } } if (*(XColor **)ptr != NULL) { Tk_FreeColor(*(XColor **)ptr); } *(XColor **)ptr = color; } break; case BLT_CONFIG_CURSOR: case BLT_CONFIG_ACTIVE_CURSOR: { Tk_Cursor cursor; if (objIsEmpty) { cursor = None; } else { cursor = Tk_AllocCursorFromObj(interp, tkwin, objPtr); if (cursor == None) { return TCL_ERROR; } } if (*(Tk_Cursor *)ptr != None) { Tk_FreeCursor(Tk_Display(tkwin), *(Tk_Cursor *)ptr); } *(Tk_Cursor *)ptr = cursor; if (sp->type == BLT_CONFIG_ACTIVE_CURSOR) { Tk_DefineCursor(tkwin, cursor); } } break; case BLT_CONFIG_CUSTOM: if ((*sp->customPtr->parseProc)(sp->customPtr->clientData, interp, tkwin, objPtr, widgRec, sp->offset, sp->specFlags) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_DOUBLE: { double value; if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(double *)ptr = value; } break; case BLT_CONFIG_FONT: { Blt_Font font; if (objIsEmpty) { font = NULL; } else { font = Blt_AllocFontFromObj(interp, tkwin, objPtr); if (font == NULL) { return TCL_ERROR; } } if (*(Blt_Font *)ptr != NULL) { Blt_FreeFont(*(Blt_Font *)ptr); } *(Blt_Font *)ptr = font; } break; case BLT_CONFIG_TK_FONT: { Tk_Font font; if (objIsEmpty) { font = NULL; } else { font = Tk_AllocFontFromObj(interp, tkwin, objPtr); if (font == NULL) { return TCL_ERROR; } } if (*(Tk_Font *)ptr != NULL) { Tk_FreeFont(*(Tk_Font *)ptr); } *(Tk_Font *)ptr = font; } break; case BLT_CONFIG_INT: { int value; if (Tcl_GetIntFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = value; } break; case BLT_CONFIG_JOIN_STYLE: { int join; Tk_Uid uid; uid = Tk_GetUid(Tcl_GetString(objPtr)); if (Tk_GetJoinStyle(interp, uid, &join) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = join; } break; case BLT_CONFIG_JUSTIFY: { Tk_Justify justify; if (Tk_GetJustifyFromObj(interp, objPtr, &justify) != TCL_OK) { return TCL_ERROR; } *(Tk_Justify *)ptr = justify; } break; case BLT_CONFIG_MM: { double value; if (Tk_GetMMFromObj(interp, tkwin, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(double *)ptr = value; } break; case BLT_CONFIG_RELIEF: { int relief; if (Tk_GetReliefFromObj(interp, objPtr, &relief) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = relief; } break; case BLT_CONFIG_STRING: { char *value; value = (objIsEmpty) ? NULL : Blt_AssertStrdup(Tcl_GetString(objPtr)); if (*(char **)ptr != NULL) { Blt_Free(*(char **)ptr); } *(char **)ptr = value; } break; case BLT_CONFIG_UID: if (*(Blt_Uid *)ptr != NULL) { Blt_FreeUid(*(Blt_Uid *)ptr); } if (objIsEmpty) { *(Blt_Uid *)ptr = NULL; } else { *(Blt_Uid *)ptr = Blt_GetUid(Tcl_GetString(objPtr)); } break; case BLT_CONFIG_WINDOW: { Tk_Window tkwin2; if (objIsEmpty) { tkwin2 = None; } else { const char *path; path = Tcl_GetString(objPtr); tkwin2 = Tk_NameToWindow(interp, path, tkwin); if (tkwin2 == NULL) { return TCL_ERROR; } } *(Tk_Window *)ptr = tkwin2; } break; case BLT_CONFIG_BITMASK: { int bool; unsigned long mask, flags; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } mask = (unsigned long)sp->customPtr; flags = *(int *)ptr; flags &= ~mask; if (bool) { flags |= mask; } *(int *)ptr = flags; } break; case BLT_CONFIG_BITMASK_INVERT: { int bool; unsigned long mask, flags; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } mask = (unsigned long)sp->customPtr; flags = *(int *)ptr; flags &= ~mask; if (!bool) { flags |= mask; } *(int *)ptr = flags; } break; case BLT_CONFIG_DASHES: if (Blt_GetDashesFromObj(interp, objPtr, (Blt_Dashes *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_FILL: if (Blt_GetFillFromObj(interp, objPtr, (int *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_RESIZE: if (Blt_GetResizeFromObj(interp, objPtr, (int *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_FLOAT: { double value; if (Tcl_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(float *)ptr = (float)value; } break; case BLT_CONFIG_INT_NNEG: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = (int)value; } break; case BLT_CONFIG_INT_POS: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = (int)value; } break; case BLT_CONFIG_LIST: { const char **argv; int argc; if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) != TCL_OK) { return TCL_ERROR; } if (*(char ***)ptr != NULL) { Blt_Free(*(char ***)ptr); } *(const char ***)ptr = argv; } break; case BLT_CONFIG_LONG: { long value; if (Tcl_GetLongFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } *(long *)ptr = value; } break; case BLT_CONFIG_LONG_NNEG: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_NNEG, &value) != TCL_OK) { return TCL_ERROR; } *(long *)ptr = value; } break; case BLT_CONFIG_LONG_POS: { long value; if (Blt_GetCountFromObj(interp, objPtr, COUNT_POS, &value) != TCL_OK) { return TCL_ERROR; } *(long *)ptr = value; } break; case BLT_CONFIG_OBJ: { Tcl_IncrRefCount(objPtr); if (*(Tcl_Obj **)ptr != NULL) { Tcl_DecrRefCount(*(Tcl_Obj **)ptr); } *(Tcl_Obj **)ptr = objPtr; } break; case BLT_CONFIG_PAD: if (Blt_GetPadFromObj(interp, tkwin, objPtr, (Blt_Pad *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_PIXELS_NNEG: { int value; if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_NNEG, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = value; } break; case BLT_CONFIG_PIXELS: { int value; if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_ANY, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = value; } break; case BLT_CONFIG_PIXELS_POS: { int value; if (Blt_GetPixelsFromObj(interp, tkwin, objPtr, PIXELS_POS, &value) != TCL_OK) { return TCL_ERROR; } *(int *)ptr = value; } break; case BLT_CONFIG_STATE: if (Blt_GetStateFromObj(interp, objPtr, (int *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_SIDE: if (Blt_GetSideFromObj(interp, objPtr, (int *)ptr) != TCL_OK) { return TCL_ERROR; } break; case BLT_CONFIG_BACKGROUND: { Blt_Background style; if (objIsEmpty) { style = NULL; } else { style = Blt_GetBackgroundFromObj(interp, tkwin, objPtr); if (style == NULL) { return TCL_ERROR; } } if (*(Blt_Background *)ptr != NULL) { Blt_FreeBackground(*(Blt_Background *)ptr); } *(Blt_Background *)ptr = style; } break; case BLT_CONFIG_PIX32: if (Blt_GetPixelFromObj(interp, objPtr, (Blt_Pixel *)ptr)!=TCL_OK) { return TCL_ERROR; } break; default: Tcl_AppendResult(interp, "bad config table: unknown type ", Blt_Itoa(sp->type), (char *)NULL); return TCL_ERROR; } sp++; } while ((sp->switchName == NULL) && (sp->type != BLT_CONFIG_END)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FormatConfigValue -- * * This procedure formats the current value of a configuration * option. * * Results: * The return value is the formatted value of the option given * by specPtr and widgRec. If the value is static, so that it * need not be freed, *freeProcPtr will be set to NULL; otherwise * *freeProcPtr will be set to the address of a procedure to * free the result, and the caller must invoke this procedure * when it is finished with the result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Tcl_Obj * FormatConfigValue( Tcl_Interp *interp, /* Interpreter for use in real conversions. */ Tk_Window tkwin, /* Window corresponding to widget. */ Blt_ConfigSpec *sp, /* Pointer to information describing option. * Must not point to a synonym option. */ char *widgRec) /* Pointer to record holding current * values of info for widget. */ { char *ptr; const char *string; ptr = widgRec + sp->offset; string = ""; switch (sp->type) { case BLT_CONFIG_ANCHOR: string = Tk_NameOfAnchor(*(Tk_Anchor *)ptr); break; case BLT_CONFIG_BITMAP: if (*(Pixmap *)ptr != None) { string = Tk_NameOfBitmap(Tk_Display(tkwin), *(Pixmap *)ptr); } break; case BLT_CONFIG_BOOLEAN: return Tcl_NewBooleanObj(*(int *)ptr); case BLT_CONFIG_BORDER: if (*(Tk_3DBorder *)ptr != NULL) { string = Tk_NameOf3DBorder(*(Tk_3DBorder *)ptr); } break; case BLT_CONFIG_CAP_STYLE: string = Tk_NameOfCapStyle(*(int *)ptr); break; case BLT_CONFIG_COLOR: if (*(XColor **)ptr != NULL) { string = Tk_NameOfColor(*(XColor **)ptr); } break; case BLT_CONFIG_CURSOR: case BLT_CONFIG_ACTIVE_CURSOR: if (*(Tk_Cursor *)ptr != None) { string = Tk_NameOfCursor(Tk_Display(tkwin), *(Tk_Cursor *)ptr); } break; case BLT_CONFIG_CUSTOM: return (*sp->customPtr->printProc) (sp->customPtr->clientData, interp, tkwin, widgRec, sp->offset, sp->specFlags); case BLT_CONFIG_DOUBLE: return Tcl_NewDoubleObj(*(double *)ptr); case BLT_CONFIG_FONT: if (*(Blt_Font *)ptr != NULL) { string = Blt_NameOfFont(*(Blt_Font *)ptr); } break; case BLT_CONFIG_TK_FONT: if (*(Tk_Font *)ptr != NULL) { string = Tk_NameOfFont(*(Tk_Font *)ptr); } break; case BLT_CONFIG_INT: return Tcl_NewIntObj(*(int *)ptr); case BLT_CONFIG_JOIN_STYLE: string = Tk_NameOfJoinStyle(*(int *)ptr); break; case BLT_CONFIG_JUSTIFY: string = Tk_NameOfJustify(*(Tk_Justify *)ptr); break; case BLT_CONFIG_MM: return Tcl_NewDoubleObj(*(double *)ptr); case BLT_CONFIG_PIXELS: case BLT_CONFIG_PIXELS_POS: case BLT_CONFIG_PIXELS_NNEG: return Tcl_NewIntObj(*(int *)ptr); case BLT_CONFIG_RELIEF: string = Tk_NameOfRelief(*(int *)ptr); break; case BLT_CONFIG_STRING: case BLT_CONFIG_UID: if (*(char **)ptr != NULL) { string = *(char **)ptr; } break; case BLT_CONFIG_BITMASK: { unsigned long flag; flag = (*(unsigned long *)ptr) & (unsigned long)sp->customPtr; return Tcl_NewBooleanObj((flag != 0)); } case BLT_CONFIG_BITMASK_INVERT: { unsigned long flag; flag = (*(unsigned long *)ptr) & (unsigned long)sp->customPtr; return Tcl_NewBooleanObj((flag == 0)); } case BLT_CONFIG_DASHES: { unsigned char *p; Tcl_Obj *listObjPtr; Blt_Dashes *dashesPtr = (Blt_Dashes *)ptr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for(p = dashesPtr->values; *p != 0; p++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(*p)); } return listObjPtr; } case BLT_CONFIG_INT_NNEG: case BLT_CONFIG_INT_POS: return Tcl_NewIntObj(*(int *)ptr); case BLT_CONFIG_FILL: string = Blt_NameOfFill(*(int *)ptr); break; case BLT_CONFIG_RESIZE: string = Blt_NameOfResize(*(int *)ptr); break; case BLT_CONFIG_FLOAT: { double x = *(float *)ptr; return Tcl_NewDoubleObj(x); } case BLT_CONFIG_LIST: { Tcl_Obj *objPtr, *listObjPtr; char *const *p; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (p = *(char ***)ptr; *p != NULL; p++) { objPtr = Tcl_NewStringObj(*p, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } return listObjPtr; } case BLT_CONFIG_LONG: return Tcl_NewLongObj(*(long *)ptr); case BLT_CONFIG_LONG_NNEG: case BLT_CONFIG_LONG_POS: return Tcl_NewLongObj(*(long *)ptr); case BLT_CONFIG_OBJ: if (*(Tcl_Obj **)ptr != NULL) { return *(Tcl_Obj **)ptr; } break; case BLT_CONFIG_PAD: { Blt_Pad *padPtr = (Blt_Pad *)ptr; Tcl_Obj *objPtr, *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); objPtr = Tcl_NewIntObj(padPtr->side1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(padPtr->side2); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); return listObjPtr; } case BLT_CONFIG_STATE: string = Blt_NameOfState(*(int *)ptr); break; case BLT_CONFIG_SIDE: string = Blt_NameOfSide(*(int *)ptr); break; case BLT_CONFIG_BACKGROUND: if (*(Blt_Background *)ptr != NULL) { string = Blt_NameOfBackground(*(Blt_Background *)ptr); } break; case BLT_CONFIG_PIX32: string = Blt_NameOfPixel((Blt_Pixel *)ptr); break; default: string = "?? unknown type ??"; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * FormatConfigInfo -- * * Create a valid TCL list holding the configuration information * for a single configuration option. * * Results: * A TCL list, dynamically allocated. The caller is expected to * arrange for this list to be freed eventually. * * Side effects: * Memory is allocated. * *--------------------------------------------------------------------------- */ static Tcl_Obj * FormatConfigInfo( Tcl_Interp *interp, /* Interpreter to use for things * like floating-point precision. */ Tk_Window tkwin, /* Window corresponding to widget. */ Blt_ConfigSpec *sp, /* Pointer to information describing * option. */ char *widgRec) /* Pointer to record holding current * values of info for widget. */ { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (sp->switchName != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(sp->switchName, -1)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (sp->dbName != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(sp->dbName, -1)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (sp->type == BLT_CONFIG_SYNONYM) { return listObjPtr; } if (sp->dbClass != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(sp->dbClass, -1)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } if (sp->defValue != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(sp->defValue, -1)); } else { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("", -1)); } Tcl_ListObjAppendElement(interp, listObjPtr, FormatConfigValue(interp, tkwin, sp, widgRec)); return listObjPtr; } /* *--------------------------------------------------------------------------- * * FindConfigSpec -- * * Search through a table of configuration specs, looking for * one that matches a given switchName. * * Results: * The return value is a pointer to the matching entry, or NULL * if nothing matched. In that case an error message is left * in the interp's result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static Blt_ConfigSpec * FindConfigSpec( Tcl_Interp *interp, /* Used for reporting errors. */ Blt_ConfigSpec *specs, /* Pointer to table of configuration * specifications for a widget. */ Tcl_Obj *objPtr, /* Name (suitable for use in a "config" * command) identifying particular option. */ int needFlags, /* Flags that must be present in matching * entry. */ int hateFlags) /* Flags that must NOT be present in * matching entry. */ { Blt_ConfigSpec *matchPtr; /* Matching spec, or NULL. */ Blt_ConfigSpec *sp; const char *string; char c; /* First character of current argument. */ int length; string = Tcl_GetStringFromObj(objPtr, &length); c = string[1]; matchPtr = NULL; for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { if (sp->switchName == NULL) { continue; } if ((sp->switchName[1] != c) || (strncmp(sp->switchName, string, length) != 0)) { continue; } if (((sp->specFlags & needFlags) != needFlags) || (sp->specFlags & hateFlags)) { continue; } if (sp->switchName[length] == 0) { matchPtr = sp; goto gotMatch; } if (matchPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "ambiguous option \"", string, "\"", (char *)NULL); } return (Blt_ConfigSpec *)NULL; } matchPtr = sp; } if (matchPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown option \"", string, "\"", (char *)NULL); } return (Blt_ConfigSpec *)NULL; } /* * Found a matching entry. If it's a synonym, then find the * entry that it's a synonym for. */ gotMatch: sp = matchPtr; if (sp->type == BLT_CONFIG_SYNONYM) { for (sp = specs; /*empty*/; sp++) { if (sp->type == BLT_CONFIG_END) { if (interp != NULL) { Tcl_AppendResult(interp, "couldn't find synonym for option \"", string, "\"", (char *)NULL); } return (Blt_ConfigSpec *) NULL; } if ((sp->dbName == matchPtr->dbName) && (sp->type != BLT_CONFIG_SYNONYM) && ((sp->specFlags & needFlags) == needFlags) && !(sp->specFlags & hateFlags)) { break; } } } return sp; } /* Public routines */ /* *--------------------------------------------------------------------------- * * Blt_ConfigureWidgetFromObj -- * * Process command-line options and database options to * fill in fields of a widget record with resources and * other parameters. * * Results: * A standard TCL return value. In case of an error, * the interp's result will hold an error message. * * Side effects: * The fields of widgRec get filled in with information * from argc/argv and the option database. Old information * in widgRec's fields gets recycled. * *--------------------------------------------------------------------------- */ int Blt_ConfigureWidgetFromObj( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window containing widget (needed to * set up X resources). */ Blt_ConfigSpec *specs, /* Describes legal options. */ int objc, /* Number of elements in argv. */ Tcl_Obj *const *objv, /* Command-line options. */ char *widgRec, /* Record whose fields are to be * modified. Values must be properly * initialized. */ int flags) /* Used to specify additional flags * that must be present in config specs * for them to be considered. Also, * may have BLT_CONFIG_OBJV_ONLY set. */ { Blt_ConfigSpec *sp; int needFlags; /* Specs must contain this set of flags * or else they are not considered. */ int hateFlags; /* If a spec contains any bits here, it's * not considered. */ int result; if (tkwin == NULL) { /* * Either we're not really in Tk, or the main window was destroyed and * we're on our way out of the application */ Tcl_AppendResult(interp, "NULL main window", (char *)NULL); return TCL_ERROR; } needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1); if (Tk_Depth(tkwin) <= 1) { hateFlags = BLT_CONFIG_COLOR_ONLY; } else { hateFlags = BLT_CONFIG_MONO_ONLY; } /* * Pass one: scan through all the option specs, replacing strings * with Tk_Uid structs (if this hasn't been done already) and * clearing the BLT_CONFIG_OPTION_SPECIFIED flags. */ for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { if (!(sp->specFlags & INIT) && (sp->switchName != NULL)) { if (sp->dbName != NULL) { sp->dbName = Tk_GetUid(sp->dbName); } if (sp->dbClass != NULL) { sp->dbClass = Tk_GetUid(sp->dbClass); } if (sp->defValue != NULL) { sp->defValue = Tk_GetUid(sp->defValue); } } sp->specFlags = (sp->specFlags & ~BLT_CONFIG_OPTION_SPECIFIED) | INIT; } /* * Pass two: scan through all of the arguments, processing those * that match entries in the specs. */ while (objc > 0) { sp = FindConfigSpec(interp, specs, objv[0], needFlags, hateFlags); if (sp == NULL) { return TCL_ERROR; } /* Process the entry. */ if (objc < 2) { Tcl_AppendResult(interp, "value for \"", Tcl_GetString(objv[0]), "\" missing", (char *)NULL); return TCL_ERROR; } if (DoConfig(interp, tkwin, sp, objv[1], widgRec) != TCL_OK) { char msg[100]; sprintf_s(msg, 100, "\n (processing \"%.40s\" option)", sp->switchName); Tcl_AddErrorInfo(interp, msg); return TCL_ERROR; } sp->specFlags |= BLT_CONFIG_OPTION_SPECIFIED; objc -= 2, objv += 2; } /* * Pass three: scan through all of the specs again; if no * command-line argument matched a spec, then check for info * in the option database. If there was nothing in the * database, then use the default. */ if ((flags & BLT_CONFIG_OBJV_ONLY) == 0) { Tcl_Obj *objPtr; for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { if ((sp->specFlags & BLT_CONFIG_OPTION_SPECIFIED) || (sp->switchName == NULL) || (sp->type == BLT_CONFIG_SYNONYM)) { continue; } if (((sp->specFlags & needFlags) != needFlags) || (sp->specFlags & hateFlags)) { continue; } objPtr = NULL; if (sp->dbName != NULL) { Tk_Uid value; /* If a resource name was specified, check if there's * also a value was associated with it. This * overrides the default value. */ value = Tk_GetOption(tkwin, sp->dbName, sp->dbClass); if (value != NULL) { objPtr = Tcl_NewStringObj(value, -1); } } if (objPtr != NULL) { Tcl_IncrRefCount(objPtr); result = DoConfig(interp, tkwin, sp, objPtr, widgRec); Tcl_DecrRefCount(objPtr); if (result != TCL_OK) { char msg[200]; sprintf_s(msg, 200, "\n (%s \"%.50s\" in widget \"%.50s\")", "database entry for", sp->dbName, Tk_PathName(tkwin)); Tcl_AddErrorInfo(interp, msg); return TCL_ERROR; } } else if ((sp->defValue != NULL) && ((sp->specFlags & BLT_CONFIG_DONT_SET_DEFAULT) == 0)) { /* No resource value is found, use the default value. */ objPtr = Tcl_NewStringObj(sp->defValue, -1); Tcl_IncrRefCount(objPtr); result = DoConfig(interp, tkwin, sp, objPtr, widgRec); Tcl_DecrRefCount(objPtr); if (result != TCL_OK) { char msg[200]; sprintf_s(msg, 200, "\n (%s \"%.50s\" in widget \"%.50s\")", "default value for", sp->dbName, Tk_PathName(tkwin)); Tcl_AddErrorInfo(interp, msg); return TCL_ERROR; } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ConfigureInfoFromObj -- * * Return information about the configuration options * for a window, and their current values. * * Results: * Always returns TCL_OK. The interp's result will be modified * hold a description of either a single configuration option * available for "widgRec" via "specs", or all the configuration * options available. In the "all" case, the result will * available for "widgRec" via "specs". The result will * be a list, each of whose entries describes one option. * Each entry will itself be a list containing the option's * name for use on command lines, database name, database * class, default value, and current value (empty string * if none). For options that are synonyms, the list will * contain only two values: name and synonym name. If the * "name" argument is non-NULL, then the only information * returned is that for the named argument (i.e. the corresponding * entry in the overall list is returned). * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_ConfigureInfoFromObj( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window corresponding to widgRec. */ Blt_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current * values for options. */ Tcl_Obj *objPtr, /* If non-NULL, indicates a single option * whose info is to be returned. Otherwise * info is returned for all options. */ int flags) /* Used to specify additional flags * that must be present in config specs * for them to be considered. */ { Blt_ConfigSpec *sp; Tcl_Obj *listObjPtr, *valueObjPtr; const char *string; int needFlags, hateFlags; needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1); if (Tk_Depth(tkwin) <= 1) { hateFlags = BLT_CONFIG_COLOR_ONLY; } else { hateFlags = BLT_CONFIG_MONO_ONLY; } /* * If information is only wanted for a single configuration * spec, then handle that one spec specially. */ Tcl_SetResult(interp, (char *)NULL, TCL_STATIC); if (objPtr != NULL) { sp = FindConfigSpec(interp, specs, objPtr, needFlags, hateFlags); if (sp == NULL) { return TCL_ERROR; } valueObjPtr = FormatConfigInfo(interp, tkwin, sp, widgRec); Tcl_SetObjResult(interp, valueObjPtr); return TCL_OK; } /* * Loop through all the specs, creating a big list with all * their information. */ string = NULL; /* Suppress compiler warning. */ if (objPtr != NULL) { string = Tcl_GetString(objPtr); } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { if ((objPtr != NULL) && (sp->switchName != string)) { continue; } if (((sp->specFlags & needFlags) != needFlags) || (sp->specFlags & hateFlags)) { continue; } if (sp->switchName == NULL) { continue; } valueObjPtr = FormatConfigInfo(interp, tkwin, sp, widgRec); Tcl_ListObjAppendElement(interp, listObjPtr, valueObjPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ConfigureValueFromObj -- * * This procedure returns the current value of a configuration * option for a widget. * * Results: * The return value is a standard TCL completion code (TCL_OK or * TCL_ERROR). The interp's result will be set to hold either the value * of the option given by objPtr (if TCL_OK is returned) or * an error message (if TCL_ERROR is returned). * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_ConfigureValueFromObj( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window corresponding to widgRec. */ Blt_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current * values for options. */ Tcl_Obj *objPtr, /* Gives the command-line name for the * option whose value is to be returned. */ int flags) /* Used to specify additional flags * that must be present in config specs * for them to be considered. */ { Blt_ConfigSpec *sp; int needFlags, hateFlags; needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1); if (Tk_Depth(tkwin) <= 1) { hateFlags = BLT_CONFIG_COLOR_ONLY; } else { hateFlags = BLT_CONFIG_MONO_ONLY; } sp = FindConfigSpec(interp, specs, objPtr, needFlags, hateFlags); if (sp == NULL) { return TCL_ERROR; } objPtr = FormatConfigValue(interp, tkwin, sp, widgRec); Tcl_SetObjResult(interp, objPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_FreeOptions -- * * Free up all resources associated with configuration options. * * Results: * None. * * Side effects: * Any resource in widgRec that is controlled by a configuration * option (e.g. a Tk_3DBorder or XColor) is freed in the appropriate * fashion. * *--------------------------------------------------------------------------- */ void Blt_FreeOptions( Blt_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current * values for options. */ Display *display, /* X display; needed for freeing some * resources. */ int needFlags) /* Used to specify additional flags * that must be present in config specs * for them to be considered. */ { Blt_ConfigSpec *sp; for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { char *ptr; if ((sp->specFlags & needFlags) != needFlags) { continue; } ptr = widgRec + sp->offset; switch (sp->type) { case BLT_CONFIG_STRING: if (*((char **) ptr) != NULL) { Blt_Free(*((char **) ptr)); *((char **) ptr) = NULL; } break; case BLT_CONFIG_COLOR: if (*((XColor **) ptr) != NULL) { Tk_FreeColor(*((XColor **) ptr)); *((XColor **) ptr) = NULL; } break; case BLT_CONFIG_FONT: if (*((Blt_Font *) ptr) != None) { Blt_FreeFont(*((Blt_Font *) ptr)); *((Blt_Font *) ptr) = NULL; } break; case BLT_CONFIG_TK_FONT: if (*((Tk_Font *) ptr) != None) { Tk_FreeFont(*((Tk_Font *) ptr)); *((Tk_Font *) ptr) = NULL; } break; case BLT_CONFIG_BITMAP: if (*((Pixmap *) ptr) != None) { Tk_FreeBitmap(display, *((Pixmap *) ptr)); *((Pixmap *) ptr) = None; } break; case BLT_CONFIG_BORDER: if (*((Tk_3DBorder *) ptr) != NULL) { Tk_Free3DBorder(*((Tk_3DBorder *) ptr)); *((Tk_3DBorder *) ptr) = NULL; } break; case BLT_CONFIG_CURSOR: case BLT_CONFIG_ACTIVE_CURSOR: if (*((Tk_Cursor *) ptr) != None) { Tk_FreeCursor(display, *((Tk_Cursor *) ptr)); *((Tk_Cursor *) ptr) = None; } break; case BLT_CONFIG_OBJ: if (*(Tcl_Obj **)ptr != NULL) { Tcl_DecrRefCount(*(Tcl_Obj **)ptr); *(Tcl_Obj **)ptr = NULL; } break; case BLT_CONFIG_LIST: if (*((char ***) ptr) != NULL) { Blt_Free(*((char ***) ptr)); *((char ***) ptr) = NULL; } break; case BLT_CONFIG_UID: if (*(Blt_Uid *)ptr != NULL) { Blt_FreeUid(*(Blt_Uid *)ptr); *(Blt_Uid *)ptr = NULL; } break; case BLT_CONFIG_BACKGROUND: if (*((Blt_Background *)ptr) != NULL) { Blt_FreeBackground(*((Blt_Background *)ptr)); *((Blt_Background *)ptr) = NULL; } break; case BLT_CONFIG_CUSTOM: if ((sp->customPtr->freeProc != NULL) && (*(char **)ptr != NULL)) { (*sp->customPtr->freeProc)(sp->customPtr->clientData, display, widgRec, sp->offset); } break; } } } /* *--------------------------------------------------------------------------- * * Blt_ConfigModified -- * * Given the configuration specifications and one or more option * patterns (terminated by a NULL), indicate if any of the matching * configuration options has been reset. * * Results: * Returns 1 if one of the options has changed, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_ConfigModified TCL_VARARGS_DEF(Blt_ConfigSpec *, arg1) { va_list argList; Blt_ConfigSpec *specs; Blt_ConfigSpec *sp; const char *option; specs = TCL_VARARGS_START(Blt_ConfigSpec *, arg1, argList); while ((option = va_arg(argList, const char *)) != NULL) { for (sp = specs; sp->type != BLT_CONFIG_END; sp++) { if ((Tcl_StringMatch(sp->switchName, option)) && (sp->specFlags & BLT_CONFIG_OPTION_SPECIFIED)) { va_end(argList); return 1; } } } va_end(argList); return 0; } /* *--------------------------------------------------------------------------- * * Blt_ConfigureComponentFromObj -- * * Configures a component of a widget. This is useful for * widgets that have multiple components which aren't uniquely * identified by a Tk_Window. It allows us, for example, set * resources for axes of the graph widget. The graph really has * only one window, but its convenient to specify components in a * hierarchy of options. * * *graph.x.logScale yes * *graph.Axis.logScale yes * *graph.temperature.scaleSymbols yes * *graph.Element.scaleSymbols yes * * This is really a hack to work around the limitations of the Tk * resource database. It creates a temporary window, needed to * call Tk_ConfigureWidget, using the name of the component. * * Results: * A standard TCL result. * * Side Effects: * A temporary window is created merely to pass to Tk_ConfigureWidget. * *--------------------------------------------------------------------------- */ int Blt_ConfigureComponentFromObj( Tcl_Interp *interp, Tk_Window parent, /* Window to associate with component */ const char *name, /* Name of component */ const char *className, Blt_ConfigSpec *sp, int objc, Tcl_Obj *const *objv, char *widgRec, int flags) { Tk_Window tkwin; int result; char *tmpName; int isTemporary = FALSE; tmpName = Blt_AssertStrdup(name); /* Window name can't start with an upper case letter */ tmpName[0] = tolower(name[0]); /* * Create component if a child window by the component's name * doesn't already exist. */ tkwin = Blt_FindChild(parent, tmpName); if (tkwin == NULL) { tkwin = Tk_CreateWindow(interp, parent, tmpName, (char *)NULL); isTemporary = TRUE; } if (tkwin == NULL) { Tcl_AppendResult(interp, "can't find window in \"", Tk_PathName(parent), "\"", (char *)NULL); return TCL_ERROR; } assert(Tk_Depth(tkwin) == Tk_Depth(parent)); Blt_Free(tmpName); Tk_SetClass(tkwin, className); result = Blt_ConfigureWidgetFromObj(interp, tkwin, sp, objc, objv, widgRec, flags); if (isTemporary) { Tk_DestroyWindow(tkwin); } return result; } /* *--------------------------------------------------------------------------- * * Blt_ObjIsOption -- * * Indicates whether objPtr is a valid configuration option * such as -background. * * Results: * Returns 1 is a matching option is found and 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_ObjIsOption( Blt_ConfigSpec *specs, /* Describes legal options. */ Tcl_Obj *objPtr, /* Command-line option name. */ int flags) /* Used to specify additional flags * that must be present in config specs * for them to be considered. Also, * may have BLT_CONFIG_OBJV_ONLY set. */ { Blt_ConfigSpec *sp; int needFlags; /* Specs must contain this set of flags * or else they are not considered. */ needFlags = flags & ~(BLT_CONFIG_USER_BIT - 1); sp = FindConfigSpec((Tcl_Interp *)NULL, specs, objPtr, needFlags, 0); return (sp != NULL); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBind.c���������������������������������������������������������������������0000644�0001750�0001750�00000143006�11462120062�014553� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBind.c -- * * This module implements object binding procedures for the BLT toolkit. * * Copyright 1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltBind.h" #include <bltList.h> static Tk_EventProc BindProc; typedef struct _Blt_BindTable BindTable; /* Make button presses on objects have implicit grab. */ #define FULLY_SIMULATE_GRAB 1 /* * Binding table procedures. */ #define REPICK_IN_PROGRESS (1<<0) #define LEFT_GRABBED_ITEM (1<<1) #define ALL_BUTTONS_MASK \ (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask) #ifndef VirtualEventMask #define VirtualEventMask (1L << 30) #endif #define ALL_VALID_EVENTS_MASK \ (ButtonMotionMask | Button1MotionMask | Button2MotionMask | \ Button3MotionMask | Button4MotionMask | Button5MotionMask | \ ButtonPressMask | ButtonReleaseMask | EnterWindowMask | \ LeaveWindowMask | KeyPressMask | KeyReleaseMask | \ PointerMotionMask | VirtualEventMask) static int buttonMasks[] = { 0, /* No buttons pressed */ Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask, }; /* * How to make drag&drop work? * * Right now we generate pseudo <Enter> <Leave> events within button grab * on an object. They're marked NotifyVirtual instead of NotifyAncestor. * A better solution: generate new-style virtual <<DragEnter>> * <<DragMotion>> <<DragLeave>> events. These virtual events don't have * to exist as "real" event sequences, like virtual events do now. */ /* *--------------------------------------------------------------------------- * * DoEvent -- * * This procedure is called to invoke binding processing for a new event * that is associated with the current item for a legend. * * Results: * None. * * Side effects: * Depends on the bindings for the legend. A binding script could delete * an entry, so callers should protect themselves with Tcl_Preserve and * Tcl_Release. * *--------------------------------------------------------------------------- */ static void DoEvent( BindTable *bindPtr, /* Binding information for widget in which * event occurred. */ XEvent *eventPtr, /* Real or simulated X event that is to be * processed. */ ClientData item, /* Item picked. */ ClientData context) /* Context of item. */ { Blt_List tagList; if ((bindPtr->tkwin == NULL) || (bindPtr->bindingTable == NULL)) { return; } if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) { item = bindPtr->focusItem; context = bindPtr->focusContext; } if (item == NULL) { return; } /* * Invoke the binding system. */ tagList = Blt_List_Create(BLT_ONE_WORD_KEYS); if (bindPtr->tagProc == NULL) { Blt_List_Append(tagList, Tk_GetUid("all"), 0); Blt_List_Append(tagList, (char *)item, 0); } else { (*bindPtr->tagProc) (bindPtr, item, context, tagList); } if (Blt_List_GetLength(tagList) > 0) { int nTags; ClientData *tagArray; #define MAX_STATIC_TAGS 64 ClientData staticTags[MAX_STATIC_TAGS]; Blt_ListNode node; tagArray = staticTags; nTags = Blt_List_GetLength(tagList); if (nTags >= MAX_STATIC_TAGS) { tagArray = Blt_AssertMalloc(sizeof(ClientData) * nTags); } nTags = 0; for (node = Blt_List_FirstNode(tagList); node != NULL; node = Blt_List_NextNode(node)) { tagArray[nTags++] = (ClientData)Blt_List_GetKey(node); } Tk_BindEvent(bindPtr->bindingTable, eventPtr, bindPtr->tkwin, nTags, tagArray); if (tagArray != staticTags) { Blt_Free(tagArray); } } Blt_List_Destroy(tagList); } /* *--------------------------------------------------------------------------- * * PickCurrentItem -- * * Find the topmost item in a legend that contains a given location and * mark the the current item. If the current item has changed, generate * a fake exit event on the old current item and a fake enter event on * the new current item. * * Results: * None. * * Side effects: * The current item may change. If it does, then the commands associated * with item entry and exit could do just about anything. A binding * script could delete the legend, so callers should protect themselves * with Tcl_Preserve and Tcl_Release. * *--------------------------------------------------------------------------- */ static void PickCurrentItem( BindTable *bindPtr, /* Binding table information. */ XEvent *eventPtr) /* Event describing location of mouse cursor. * Must be EnterWindow, LeaveWindow, * ButtonRelease, or MotionNotify. */ { int buttonDown; ClientData newItem, oldItem; ClientData newContext; /* * Check whether or not a button is down. If so, we'll log entry and exit * into and out of the current item, but not entry into any other item. * This implements a form of grabbing equivalent to what the X server does * for windows. */ buttonDown = (bindPtr->state & ALL_BUTTONS_MASK); if (!buttonDown) { bindPtr->flags &= ~LEFT_GRABBED_ITEM; } /* * Save information about this event in the widget. The event in the * widget is used for two purposes: * * 1. Event bindings: if the current item changes, fake events are * generated to allow item-enter and item-leave bindings to trigger. * 2. Reselection: if the current item gets deleted, can use the * saved event to find a new current item. * Translate MotionNotify events into EnterNotify events, since that's * what gets reported to item handlers. */ if (eventPtr != &bindPtr->pickEvent) { if ((eventPtr->type == MotionNotify) || (eventPtr->type == ButtonRelease)) { bindPtr->pickEvent.xcrossing.type = EnterNotify; bindPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial; bindPtr->pickEvent.xcrossing.send_event = eventPtr->xmotion.send_event; bindPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display; bindPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window; bindPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root; bindPtr->pickEvent.xcrossing.subwindow = None; bindPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time; bindPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x; bindPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y; bindPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root; bindPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root; bindPtr->pickEvent.xcrossing.mode = NotifyNormal; bindPtr->pickEvent.xcrossing.detail = NotifyNonlinear; bindPtr->pickEvent.xcrossing.same_screen = eventPtr->xmotion.same_screen; bindPtr->pickEvent.xcrossing.focus = False; bindPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state; } else { bindPtr->pickEvent = *eventPtr; } } bindPtr->activePick = TRUE; /* * If this is a recursive call (there's already a partially completed call * pending on the stack; it's in the middle of processing a Leave event * handler for the old current item) then just return; the pending call * will do everything that's needed. */ if (bindPtr->flags & REPICK_IN_PROGRESS) { return; } /* * A LeaveNotify event automatically means that there's no current item, * so the check for closest item can be skipped. */ newContext = NULL; if (bindPtr->pickEvent.type != LeaveNotify) { int x, y; x = bindPtr->pickEvent.xcrossing.x; y = bindPtr->pickEvent.xcrossing.y; newItem = (*bindPtr->pickProc) (bindPtr->clientData, x, y, &newContext); } else { newItem = NULL; } if (((newItem == bindPtr->currentItem) && (newContext == bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) { /* * Nothing to do: the current item hasn't changed. */ return; } #if FULLY_SIMULATE_GRAB if (((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && (buttonDown)) { bindPtr->flags |= LEFT_GRABBED_ITEM; #ifdef notdef fprintf(stderr, "pickcurrentitem: simulate grab.\n"); #endif return; } #endif /* * Simulate a LeaveNotify event on the previous current item and an * EnterNotify event on the new current item. Remove the "current" tag * from the previous current item and place it on the new current item. */ oldItem = bindPtr->currentItem; Tcl_Preserve(oldItem); Tcl_Preserve(newItem); if ((bindPtr->currentItem != NULL) && ((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) { XEvent event; event = bindPtr->pickEvent; event.type = LeaveNotify; /* * If the event's detail happens to be NotifyInferior the binding * mechanism will discard the event. To be consistent, always use * NotifyAncestor. */ event.xcrossing.detail = NotifyAncestor; bindPtr->flags |= REPICK_IN_PROGRESS; DoEvent(bindPtr, &event, bindPtr->currentItem, bindPtr->currentContext); bindPtr->flags &= ~REPICK_IN_PROGRESS; /* * Note: during DoEvent above, it's possible that bindPtr->newItem got * reset to NULL because the item was deleted. */ } if (((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && (buttonDown)) { XEvent event; bindPtr->flags |= LEFT_GRABBED_ITEM; event = bindPtr->pickEvent; if ((newItem != bindPtr->newItem) || (newContext != bindPtr->newContext)) { ClientData savedItem; ClientData savedContext; /* * Generate <Enter> and <Leave> events for objects during button * grabs. This isn't standard. But for example, it allows one to * provide balloon help on the individual entries of the Hierbox * widget. */ savedItem = bindPtr->currentItem; savedContext = bindPtr->currentContext; if (bindPtr->newItem != NULL) { event.type = LeaveNotify; event.xcrossing.detail = NotifyVirtual /* Ancestor */ ; bindPtr->currentItem = bindPtr->newItem; DoEvent(bindPtr, &event, bindPtr->newItem, bindPtr->newContext); } bindPtr->newItem = newItem; bindPtr->newContext = newContext; if (newItem != NULL) { event.type = EnterNotify; event.xcrossing.detail = NotifyVirtual /* Ancestor */ ; bindPtr->currentItem = newItem; DoEvent(bindPtr, &event, newItem, newContext); } bindPtr->currentItem = savedItem; bindPtr->currentContext = savedContext; } goto done; } /* * Special note: it's possible that * bindPtr->newItem == bindPtr->currentItem * here. This can happen, for example, if LEFT_GRABBED_ITEM was set. */ bindPtr->flags &= ~LEFT_GRABBED_ITEM; bindPtr->currentItem = bindPtr->newItem = newItem; bindPtr->currentContext = bindPtr->newContext = newContext; if (bindPtr->currentItem != NULL) { XEvent event; event = bindPtr->pickEvent; event.type = EnterNotify; event.xcrossing.detail = NotifyAncestor; DoEvent(bindPtr, &event, newItem, newContext); #ifdef notdef if ((eventPtr->type == MotionNotify) || (eventPtr->type == ButtonRelease)) { fprintf(stderr, "pickcurrentitem: DoEvent Button buttondown=%d.\n", buttonDown); event.type = eventPtr->type; event.xbutton.button = eventPtr->xbutton.button; DoEvent(bindPtr, &event, newItem, newContext); fprintf(stderr, "pickcurrentitem: done.\n"); } #endif } done: Tcl_Release(newItem); Tcl_Release(oldItem); } /* *--------------------------------------------------------------------------- * * BindProc -- * * This procedure is invoked by the Tk dispatcher to handle events * associated with bindings on items. * * Results: * None. * * Side effects: * Depends on the command invoked as part of the binding * (if there was any). * *--------------------------------------------------------------------------- */ static void BindProc( ClientData clientData, /* Pointer to widget structure. */ XEvent *eventPtr) /* Pointer to X event that just happened. */ { BindTable *bindPtr = clientData; int mask; Tcl_Preserve(bindPtr->clientData); /* * This code below keeps track of the current modifier state in * bindPtr->state. This information is used to defer repicks of the * current item while buttons are down. */ switch (eventPtr->type) { case ButtonPress: case ButtonRelease: mask = 0; if ((eventPtr->xbutton.button >= Button1) && (eventPtr->xbutton.button <= Button5)) { mask = buttonMasks[eventPtr->xbutton.button]; } /* * For button press events, repick the current item using the button * state before the event, then process the event. For button release * events, first process the event, then repick the current item using * the button state *after* the event (the button has logically gone * up before we change the current item). */ if (eventPtr->type == ButtonPress) { /* * On a button press, first repick the current item using the * button state before the event, the process the event. */ bindPtr->state = eventPtr->xbutton.state; PickCurrentItem(bindPtr, eventPtr); bindPtr->state ^= mask; DoEvent(bindPtr, eventPtr, bindPtr->currentItem, bindPtr->currentContext); } else { /* * Button release: first process the event, with the button still * considered to be down. Then repick the current item under the * assumption that the button is no longer down. */ bindPtr->state = eventPtr->xbutton.state; DoEvent(bindPtr, eventPtr, bindPtr->currentItem, bindPtr->currentContext); eventPtr->xbutton.state ^= mask; bindPtr->state = eventPtr->xbutton.state; PickCurrentItem(bindPtr, eventPtr); eventPtr->xbutton.state ^= mask; } break; case EnterNotify: case LeaveNotify: bindPtr->state = eventPtr->xcrossing.state; PickCurrentItem(bindPtr, eventPtr); break; case MotionNotify: bindPtr->state = eventPtr->xmotion.state; PickCurrentItem(bindPtr, eventPtr); DoEvent(bindPtr, eventPtr, bindPtr->currentItem, bindPtr->currentContext); break; case KeyPress: case KeyRelease: bindPtr->state = eventPtr->xkey.state; PickCurrentItem(bindPtr, eventPtr); DoEvent(bindPtr, eventPtr, bindPtr->currentItem, bindPtr->currentContext); break; } Tcl_Release(bindPtr->clientData); } int Blt_ConfigureBindings( Tcl_Interp *interp, BindTable *bindPtr, ClientData item, int argc, const char **argv) { const char *command; unsigned long mask; const char *seq; if (argc == 0) { Tk_GetAllBindings(interp, bindPtr->bindingTable, item); return TCL_OK; } if (argc == 1) { command = Tk_GetBinding(interp, bindPtr->bindingTable, item, argv[0]); if (command == NULL) { Tcl_AppendResult(interp, "can't find event \"", argv[0], "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1); return TCL_OK; } seq = argv[0]; command = argv[1]; if (command[0] == '\0') { return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq); } if (command[0] == '+') { mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq, command + 1, TRUE); } else { mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq, command, FALSE); } if (mask == 0) { Tcl_AppendResult(interp, "event mask can't be zero for \"", item, "\"", (char *)NULL); return TCL_ERROR; } if (mask & (unsigned)~ALL_VALID_EVENTS_MASK) { Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "requested illegal events; ", "only key, button, motion, enter, leave, and virtual ", "events may be used", (char *)NULL); return TCL_ERROR; } return TCL_OK; } int Blt_ConfigureBindingsFromObj( Tcl_Interp *interp, BindTable *bindPtr, ClientData item, int objc, Tcl_Obj *const *objv) { const char *command; unsigned long mask; const char *seq; const char *string; if (objc == 0) { Tk_GetAllBindings(interp, bindPtr->bindingTable, item); return TCL_OK; } string = Tcl_GetString(objv[0]); if (objc == 1) { command = Tk_GetBinding(interp, bindPtr->bindingTable, item, string); if (command == NULL) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "invalid binding event \"", string, "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1); return TCL_OK; } seq = string; command = Tcl_GetString(objv[1]); if (command[0] == '\0') { return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq); } if (command[0] == '+') { mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq, command + 1, TRUE); } else { mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq, command, FALSE); } if (mask == 0) { return TCL_ERROR; } if (mask & (unsigned)~ALL_VALID_EVENTS_MASK) { Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "requested illegal events; ", "only key, button, motion, enter, leave, and virtual ", "events may be used", (char *)NULL); return TCL_ERROR; } return TCL_OK; } Blt_BindTable Blt_CreateBindingTable( Tcl_Interp *interp, Tk_Window tkwin, ClientData clientData, Blt_BindPickProc *pickProc, Blt_BindTagProc *tagProc) { unsigned int mask; BindTable *bindPtr; bindPtr = Blt_AssertCalloc(1, sizeof(BindTable)); bindPtr->bindingTable = Tk_CreateBindingTable(interp); bindPtr->clientData = clientData; bindPtr->tkwin = tkwin; bindPtr->pickProc = pickProc; bindPtr->tagProc = tagProc; mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask); Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr); return bindPtr; } void Blt_DestroyBindingTable(BindTable *bindPtr) { unsigned int mask; Tk_DeleteBindingTable(bindPtr->bindingTable); mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask); Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr); Blt_Free(bindPtr); } void Blt_PickCurrentItem(BindTable *bindPtr) { if (bindPtr->activePick) { PickCurrentItem(bindPtr, &bindPtr->pickEvent); } } void Blt_DeleteBindings( BindTable *bindPtr, ClientData object) { Tk_DeleteAllBindings(bindPtr->bindingTable, object); /* * If this is the object currently picked, we need to repick one. */ if (bindPtr->currentItem == object) { bindPtr->currentItem = NULL; bindPtr->currentContext = NULL; } if (bindPtr->newItem == object) { bindPtr->newItem = NULL; bindPtr->newContext = NULL; } if (bindPtr->focusItem == object) { bindPtr->focusItem = NULL; bindPtr->focusContext = NULL; } } void Blt_MoveBindingTable( BindTable *bindPtr, Tk_Window tkwin) { unsigned int mask; mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask); if (bindPtr->tkwin != NULL) { Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr); } Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr); bindPtr->tkwin = tkwin; } /* * The following union is used to hold the detail information from an * XEvent (including Tk's XVirtualEvent extension). */ typedef union { KeySym keySym; /* KeySym that corresponds to xkey.keycode. */ int button; /* Button that was pressed (xbutton.button). */ Tk_Uid name; /* Tk_Uid of virtual event. */ ClientData clientData; /* Used when type of Detail is unknown, and to * ensure that all bytes of Detail are initialized * when this structure is used in a hash key. */ } Detail; /* * The following structure defines a pattern, which is matched against X * events as part of the process of converting X events into TCL commands. */ typedef struct { int eventType; /* Type of X event, e.g. ButtonPress. */ int needMods; /* Mask of modifiers that must be * present (0 means no modifiers are * required). */ Detail detail; /* Additional information that must * match event. Normally this is 0, * meaning no additional information * must match. For KeyPress and * KeyRelease events, a keySym may * be specified to select a * particular keystroke (0 means any * keystrokes). For button events, * specifies a particular button (0 * means any buttons are OK). For virtual * events, specifies the Tk_Uid of the * virtual event name (never 0). */ } Pattern; typedef struct { const char *name; /* Name of modifier. */ int mask; /* Button/modifier mask value, such as * Button1Mask. */ int flags; /* Various flags; see below for * definitions. */ } EventModifier; /* * Flags for EventModifier structures: * * DOUBLE - Non-zero means duplicate this event, * e.g. for double-clicks. * TRIPLE - Non-zero means triplicate this event, * e.g. for triple-clicks. * QUADRUPLE - Non-zero means quadruple this event, * e.g. for 4-fold-clicks. * MULT_CLICKS - Combination of all of above. */ #define DOUBLE (1<<0) #define TRIPLE (1<<1) #define QUADRUPLE (1<<2) #define MULT_CLICKS (DOUBLE|TRIPLE|QUADRUPLE) #define META_MASK (AnyModifier<<1) #define ALT_MASK (AnyModifier<<2) static EventModifier eventModifiers[] = { {"Alt", ALT_MASK, 0}, {"Any", 0, 0}, /* Ignored: historical relic. */ {"B1", Button1Mask, 0}, {"B2", Button2Mask, 0}, {"B3", Button3Mask, 0}, {"B4", Button4Mask, 0}, {"B5", Button5Mask, 0}, {"Button1", Button1Mask, 0}, {"Button2", Button2Mask, 0}, {"Button3", Button3Mask, 0}, {"Button4", Button4Mask, 0}, {"Button5", Button5Mask, 0}, {"Command", Mod1Mask, 0}, {"Control", ControlMask, 0}, {"Double", 0, DOUBLE}, {"Lock", LockMask, 0}, {"M", META_MASK, 0}, {"M1", Mod1Mask, 0}, {"M2", Mod2Mask, 0}, {"M3", Mod3Mask, 0}, {"M4", Mod4Mask, 0}, {"M5", Mod5Mask, 0}, {"Meta", META_MASK, 0}, {"Mod1", Mod1Mask, 0}, {"Mod2", Mod2Mask, 0}, {"Mod3", Mod3Mask, 0}, {"Mod4", Mod4Mask, 0}, {"Mod5", Mod5Mask, 0}, {"Option", Mod2Mask, 0}, {"Quadruple", 0, QUADRUPLE}, {"Shift", ShiftMask, 0}, {"Triple", 0, TRIPLE}, }; typedef struct { const char *name; /* Name of event. */ int type; /* Event type for X, such as * ButtonPress. */ int eventMask; /* Mask bits (for XSelectInput) * for this event type. */ } EventInfo; /* * Note: some of the masks below are an OR-ed combination of * several masks. This is necessary because X doesn't report * up events unless you also ask for down events. Also, X * doesn't report button state in motion events unless you've * asked about button events. */ static EventInfo events[] = { {"Activate", ActivateNotify, ActivateMask}, {"Button", ButtonPress, ButtonPressMask}, {"ButtonPress", ButtonPress, ButtonPressMask}, {"ButtonRelease", ButtonRelease, ButtonPressMask|ButtonReleaseMask}, {"Circulate", CirculateNotify, StructureNotifyMask}, {"CirculateRequest", CirculateRequest, SubstructureRedirectMask}, {"Colormap", ColormapNotify, ColormapChangeMask}, {"Configure", ConfigureNotify, StructureNotifyMask}, {"ConfigureRequest", ConfigureRequest, SubstructureRedirectMask}, {"Create", CreateNotify, SubstructureNotifyMask}, {"Deactivate", DeactivateNotify, ActivateMask}, {"Destroy", DestroyNotify, StructureNotifyMask}, {"Enter", EnterNotify, EnterWindowMask}, {"Expose", Expose, ExposureMask}, {"FocusIn", FocusIn, FocusChangeMask}, {"FocusOut", FocusOut, FocusChangeMask}, {"Gravity", GravityNotify, StructureNotifyMask}, {"Key", KeyPress, KeyPressMask}, {"KeyPress", KeyPress, KeyPressMask}, {"KeyRelease", KeyRelease, KeyPressMask|KeyReleaseMask}, {"Leave", LeaveNotify, LeaveWindowMask}, {"Map", MapNotify, StructureNotifyMask}, {"MapRequest", MapRequest, SubstructureRedirectMask}, {"Motion", MotionNotify, ButtonPressMask|PointerMotionMask}, {"MouseWheel", MouseWheelEvent, MouseWheelMask}, {"Property", PropertyNotify, PropertyChangeMask}, {"Reparent", ReparentNotify, StructureNotifyMask}, {"ResizeRequest", ResizeRequest, ResizeRedirectMask}, {"Unmap", UnmapNotify, StructureNotifyMask}, {"Visibility", VisibilityNotify, VisibilityChangeMask}, }; /* * The defines and table below are used to classify events into * various groups. The reason for this is that logically identical * fields (e.g. "state") appear at different places in different * types of events. The classification masks can be used to figure * out quickly where to extract information from events. */ #define KEY 0x1 #define BUTTON 0x2 #define MOTION 0x4 #define CROSSING 0x8 #define FOCUS 0x10 #define EXPOSE 0x20 #define VISIBILITY 0x40 #define CREATE 0x80 #define DESTROY 0x100 #define UNMAP 0x200 #define MAP 0x400 #define REPARENT 0x800 #define CONFIG 0x1000 #define GRAVITY 0x2000 #define CIRC 0x4000 #define PROP 0x8000 #define COLORMAP 0x10000 #define VIRTUAL 0x20000 #define ACTIVATE 0x40000 #define MAPREQ 0x80000 #define CONFIGREQ 0x100000 #define RESIZEREQ 0x200000 #define CIRCREQ 0x400000 #define KEY_BUTTON_MOTION_VIRTUAL (KEY|BUTTON|MOTION|VIRTUAL) #define KEY_BUTTON_MOTION_CROSSING (KEY|BUTTON|MOTION|CROSSING|VIRTUAL) static int flagArray[TK_LASTEVENT+1] = { /* Not used */ 0, /* Not used */ 0, /* KeyPress */ KEY, /* KeyRelease */ KEY, /* ButtonPress */ BUTTON, /* ButtonRelease */ BUTTON, /* MotionNotify */ MOTION, /* EnterNotify */ CROSSING, /* LeaveNotify */ CROSSING, /* FocusIn */ FOCUS, /* FocusOut */ FOCUS, /* KeymapNotify */ 0, /* Expose */ EXPOSE, /* GraphicsExpose */ EXPOSE, /* NoExpose */ 0, /* VisibilityNotify */ VISIBILITY, /* CreateNotify */ CREATE, /* DestroyNotify */ DESTROY, /* UnmapNotify */ UNMAP, /* MapNotify */ MAP, /* MapRequest */ MAPREQ, /* ReparentNotify */ REPARENT, /* ConfigureNotify */ CONFIG, /* ConfigureRequest */ CONFIGREQ, /* GravityNotify */ GRAVITY, /* ResizeRequest */ RESIZEREQ, /* CirculateNotify */ CIRC, /* CirculateRequest */ 0, /* PropertyNotify */ PROP, /* SelectionClear */ 0, /* SelectionRequest */ 0, /* SelectionNotify */ 0, /* ColormapNotify */ COLORMAP, /* ClientMessage */ 0, /* MappingNotify */ 0, #ifdef GenericEvent /* GenericEvent */ 0, #endif /* VirtualEvent */ VIRTUAL, /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE, /* MouseWheel */ KEY }; static EventModifier * FindModifier(const char *string) { int high, low; char c; low = 0; high = (sizeof(eventModifiers) / sizeof(EventModifier)) - 1; c = string[0]; while (low <= high) { EventModifier *modPtr; int compare; int median; median = (low + high) >> 1; modPtr = eventModifiers + median; /* Test the first character */ compare = c - modPtr->name[0]; if (compare == 0) { compare = strcmp(string, modPtr->name); } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return modPtr; /* Modifier found. */ } } return NULL; /* Can't find modifier */ } static EventInfo * FindEvent(const char *string) { int high, low; char c; low = 0; high = (sizeof(events) / sizeof(EventInfo)) - 1; c = string[0]; while (low <= high) { EventInfo *infoPtr; int compare; int median; median = (low + high) >> 1; infoPtr = events + median; /* Test the first character */ compare = c - infoPtr->name[0]; if (compare == 0) { compare = strcmp(string, infoPtr->name); } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return infoPtr; /* Event found. */ } } return NULL; /* Can't find event. */ } /* *---------------------------------------------------------------------- * * GetField -- * * Used to parse pattern descriptions. Copies up to * size characters from p to copy, stopping at end of * string, space, "-", ">", or whenever size is * exceeded. * * Results: * The return value is a pointer to the character just * after the last one copied (usually "-" or space or * ">", but could be anything if size was exceeded). * Also places NULL-terminated string (up to size * character, including NULL), at copy. * * Side effects: * None. * *---------------------------------------------------------------------- */ static char * GetField(p, copy, size) char *p; /* Pointer to part of pattern. */ char *copy; /* Place to copy field. */ int size; /* Maximum number of characters to * copy. */ { while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '>') && (*p != '-') && (size > 1)) { *copy = *p; p++; copy++; size--; } *copy = '\0'; return p; } static int ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr, Pattern *patPtr, unsigned long *eventMaskPtr) { char *p; unsigned long eventMask; int count, eventFlags; #define FIELD_SIZE 48 char field[FIELD_SIZE]; EventInfo *infoPtr; Tcl_DString copy; Tcl_DStringInit(&copy); p = Tcl_DStringAppend(&copy, *eventStringPtr, -1); patPtr->eventType = -1; patPtr->needMods = 0; patPtr->detail.clientData = 0; eventMask = 0; count = 1; /* * Handle simple ASCII characters. */ if (*p != '<') { char string[2]; patPtr->eventType = KeyPress; eventMask = KeyPressMask; string[0] = *p; string[1] = 0; patPtr->detail.keySym = XStringToKeysym(string); if (patPtr->detail.keySym == NoSymbol) { if (isprint(UCHAR(*p))) { patPtr->detail.keySym = *p; } else { char buf[64]; sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p); Tcl_SetResult(interp, buf, TCL_VOLATILE); count = 0; goto done; } } p++; goto end; } /* * A physical event description consists of: * * 1. open angle bracket. * 2. any number of modifiers, each followed by spaces * or dashes. * 3. an optional event name. * 4. an option button or keysym name. Either this or * item 3 *must* be present; if both are present * then they are separated by spaces or dashes. * 5. a close angle bracket. */ p++; while (1) { EventModifier *modPtr; p = GetField(p, field, FIELD_SIZE); if (*p == '>') { /* * This solves the problem of, e.g., <Control-M> being * misinterpreted as Control + Meta + missing keysym * instead of Control + KeyPress + M. */ break; } modPtr = FindModifier(field); if (modPtr == NULL) { break; } patPtr->needMods |= modPtr->mask; if (modPtr->flags & (MULT_CLICKS)) { int i = modPtr->flags & MULT_CLICKS; count = 2; while (i >>= 1) count++; } while ((*p == '-') || isspace(UCHAR(*p))) { p++; } } eventFlags = 0; infoPtr = FindEvent(field); if (infoPtr != NULL) { patPtr->eventType = infoPtr->type; eventFlags = flagArray[infoPtr->type]; eventMask = infoPtr->eventMask; while ((*p == '-') || isspace(UCHAR(*p))) { p++; } p = GetField(p, field, FIELD_SIZE); } if (*field != '\0') { if ((*field >= '1') && (*field <= '5') && (field[1] == '\0')) { if (eventFlags == 0) { patPtr->eventType = ButtonPress; eventMask = ButtonPressMask; } else if (eventFlags & KEY) { goto getKeysym; } else if ((eventFlags & BUTTON) == 0) { Tcl_AppendResult(interp, "specified button \"", field, "\" for non-button event", (char *) NULL); count = 0; goto done; } patPtr->detail.button = (*field - '0'); } else { getKeysym: patPtr->detail.keySym = XStringToKeysym(field); if (patPtr->detail.keySym == NoSymbol) { Tcl_AppendResult(interp, "bad event type or keysym \"", field, "\"", (char *)NULL); count = 0; goto done; } if (eventFlags == 0) { patPtr->eventType = KeyPress; eventMask = KeyPressMask; } else if ((eventFlags & KEY) == 0) { Tcl_AppendResult(interp, "specified keysym \"", field, "\" for non-key event", (char *)NULL); count = 0; goto done; } } } else if (eventFlags == 0) { Tcl_AppendResult(interp, "no event type or button # or keysym", (char *)NULL); count = 0; goto done; } while ((*p == '-') || isspace(UCHAR(*p))) { p++; } if (*p != '>') { while (*p != '\0') { p++; if (*p == '>') { Tcl_AppendResult(interp, "extra characters after detail in binding", (char *)NULL); count = 0; goto done; } } Tcl_AppendResult(interp, "missing \">\" in binding", (char *)NULL); count = 0; goto done; } p++; end: *eventStringPtr += (p - Tcl_DStringValue(&copy)); *eventMaskPtr |= eventMask; done: Tcl_DStringFree(&copy); return count; } typedef struct { int numKey; /* Integer representation of a value. */ const char *strKey; /* String representation of a value. */ } TkStateMap; static TkStateMap notifyMode[] = { {NotifyNormal, "NotifyNormal"}, {NotifyGrab, "NotifyGrab"}, {NotifyUngrab, "NotifyUngrab"}, {NotifyWhileGrabbed, "NotifyWhileGrabbed"}, {-1, NULL} }; static TkStateMap notifyDetail[] = { {NotifyAncestor, "NotifyAncestor"}, {NotifyVirtual, "NotifyVirtual"}, {NotifyInferior, "NotifyInferior"}, {NotifyNonlinear, "NotifyNonlinear"}, {NotifyNonlinearVirtual, "NotifyNonlinearVirtual"}, {NotifyPointer, "NotifyPointer"}, {NotifyPointerRoot, "NotifyPointerRoot"}, {NotifyDetailNone, "NotifyDetailNone"}, {-1, NULL} }; static TkStateMap circPlace[] = { {PlaceOnTop, "PlaceOnTop"}, {PlaceOnBottom, "PlaceOnBottom"}, {-1, NULL} }; static TkStateMap visNotify[] = { {VisibilityUnobscured, "VisibilityUnobscured"}, {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, {VisibilityFullyObscured, "VisibilityFullyObscured"}, {-1, NULL} }; static TkStateMap configureRequestDetail[] = { {None, "None"}, {Above, "Above"}, {Below, "Below"}, {BottomIf, "BottomIf"}, {TopIf, "TopIf"}, {Opposite, "Opposite"}, {-1, NULL} }; static TkStateMap propNotify[] = { {PropertyNewValue, "NewValue"}, {PropertyDelete, "Delete"}, {-1, NULL} }; /* *--------------------------------------------------------------------------- * * HandleEventGenerate -- * * Helper function for the "event generate" command. Generate and * process an XEvent, constructed from information parsed from the * event description string and its optional arguments. * * argv[0] contains name of the target window. * argv[1] contains pattern string for one event (e.g, <Control-v>). * argv[2..argc-1] contains -field/option pairs for specifying * additional detail in the generated event. * * Either virtual or physical events can be generated this way. * The event description string must contain the specification * for only one event. * * Results: * None. * * Side effects: * When constructing the event, * event.xany.serial is filled with the current X serial number. * event.xany.window is filled with the target window. * event.xany.display is filled with the target window's display. * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * * The event may be handled sychronously or asynchronously, depending * on the value specified by the optional "-when" option. The * default setting is synchronous. * *--------------------------------------------------------------------------- */ static int SendEventCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { XEvent event; CONST char *p; char *name; Window window; Display *display; Tk_Window tkwin; int count, flags, synch, i, number, warp; Tcl_QueuePosition pos; Pattern pat; unsigned long eventMask; static CONST char *fieldStrings[] = { "-when", "-above", "-borderwidth", "-button", "-count", "-delta", "-detail", "-focus", "-height", "-keycode", "-keysym", "-mode", "-override", "-place", "-root", "-rootx", "-rooty", "-sendevent", "-serial", "-state", "-subwindow", "-time", "-warp", "-width", "-window", "-x", "-y", NULL }; enum field { EVENT_WHEN, EVENT_ABOVE, EVENT_BORDER, EVENT_BUTTON, EVENT_COUNT, EVENT_DELTA, EVENT_DETAIL, EVENT_FOCUS, EVENT_HEIGHT, EVENT_KEYCODE, EVENT_KEYSYM, EVENT_MODE, EVENT_OVERRIDE, EVENT_PLACE, EVENT_ROOT, EVENT_ROOTX, EVENT_ROOTY, EVENT_SEND, EVENT_SERIAL, EVENT_STATE, EVENT_SUBWINDOW, EVENT_TIME, EVENT_WARP, EVENT_WIDTH, EVENT_WINDOW, EVENT_X, EVENT_Y }; tkwin = Tk_MainWindow(interp); if (Blt_GetWindowFromObj(interp, objv[1], &window) != TCL_OK) { return TCL_ERROR; } name = Tcl_GetStringFromObj(objv[2], NULL); display = Tk_Display(tkwin); p = name; eventMask = 0; count = ParseEventDescription(interp, &p, &pat, &eventMask); if (count == 0) { return TCL_ERROR; } if (count != 1) { Tcl_AppendResult(interp, "Double or Triple modifier not allowed", (char *)NULL); return TCL_ERROR; } if (*p != '\0') { Tcl_AppendResult(interp, "only one event specification allowed", (char *)NULL); return TCL_ERROR; } memset((VOID *) &event, 0, sizeof(event)); event.xany.type = pat.eventType; event.xany.serial = NextRequest(display); event.xany.send_event = False; event.xany.window = window; event.xany.display = display; flags = flagArray[event.xany.type]; if (flags & DESTROY) { /* * Event DestroyNotify should be generated by destroying * the window. */ XDestroyWindow(display, window); return TCL_OK; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { event.xkey.state = pat.needMods; if ((flags & KEY) && (event.xany.type != MouseWheelEvent)) { TkpSetKeycodeAndState(tkwin, pat.detail.keySym, &event); } else if (flags & BUTTON) { event.xbutton.button = pat.detail.button; } else if (flags & VIRTUAL) { ((XVirtualEvent *) &event)->name = pat.detail.name; } } if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) { event.xcreatewindow.window = event.xany.window; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.x_root = -1; event.xkey.y_root = -1; } /* * Process the remaining arguments to fill in additional fields * of the event. */ synch = 1; warp = 0; pos = TCL_QUEUE_TAIL; for (i = 3; i < objc; i += 2) { Tcl_Obj *optionPtr, *valuePtr; int index; optionPtr = objv[i]; valuePtr = objv[i + 1]; if (Tcl_GetIndexFromObj(interp, optionPtr, fieldStrings, "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } if ((objc & 1) == 0) { /* * This test occurs after Tcl_GetIndexFromObj() so that * "event generate <Button> -xyz" will return the error message * that "-xyz" is a bad option, rather than that the value * for "-xyz" is missing. */ Tcl_AppendResult(interp, "value for \"", Tcl_GetStringFromObj(optionPtr, NULL), "\" missing", (char *)NULL); return TCL_ERROR; } switch ((enum field) index) { case EVENT_WARP: { if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { return TCL_ERROR; } if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { goto badopt; } break; } case EVENT_WHEN: { #ifdef notdef pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, queuePosition, valuePtr); if ((int) pos < -1) { return TCL_ERROR; } synch = 0; if ((int) pos == -1) { synch = 1; } #endif break; } case EVENT_ABOVE: { Window window2; if (Blt_GetWindowFromObj(interp, valuePtr, &window2) != TCL_OK) { return TCL_ERROR; } if (flags & CONFIG) { event.xconfigure.above = window2; } else { goto badopt; } break; } case EVENT_BORDER: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number)!=TCL_OK) { return TCL_ERROR; } if (flags & (CREATE|CONFIG)) { event.xcreatewindow.border_width = number; } else { goto badopt; } break; } case EVENT_BUTTON: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & BUTTON) { event.xbutton.button = number; } else { goto badopt; } break; } case EVENT_COUNT: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & EXPOSE) { event.xexpose.count = number; } else { goto badopt; } break; } case EVENT_DELTA: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { event.xkey.keycode = number; } else { goto badopt; } break; } case EVENT_DETAIL: { number = TkFindStateNumObj(interp, optionPtr, notifyDetail, valuePtr); if (number < 0) { return TCL_ERROR; } if (flags & FOCUS) { event.xfocus.detail = number; } else if (flags & CROSSING) { event.xcrossing.detail = number; } else { goto badopt; } break; } case EVENT_FOCUS: { if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & CROSSING) { event.xcrossing.focus = number; } else { goto badopt; } break; } case EVENT_HEIGHT: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & EXPOSE) { event.xexpose.height = number; } else if (flags & CONFIG) { event.xconfigure.height = number; } else { goto badopt; } break; } case EVENT_KEYCODE: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { event.xkey.keycode = number; } else { goto badopt; } break; } case EVENT_KEYSYM: { KeySym keysym; char *value; value = Tcl_GetStringFromObj(valuePtr, NULL); keysym = TkStringToKeysym(value); if (keysym == NoSymbol) { Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", (char *)NULL); return TCL_ERROR; } TkpSetKeycodeAndState(tkwin, keysym, &event); if (event.xkey.keycode == 0) { Tcl_AppendResult(interp, "no keycode for keysym \"", value, "\"", (char *)NULL); return TCL_ERROR; } if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { goto badopt; } break; } case EVENT_MODE: { number = TkFindStateNumObj(interp, optionPtr, notifyMode, valuePtr); if (number < 0) { return TCL_ERROR; } if (flags & CROSSING) { event.xcrossing.mode = number; } else if (flags & FOCUS) { event.xfocus.mode = number; } else { goto badopt; } break; } case EVENT_OVERRIDE: { if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & CREATE) { event.xcreatewindow.override_redirect = number; } else if (flags & MAP) { event.xmap.override_redirect = number; } else if (flags & REPARENT) { event.xreparent.override_redirect = number; } else if (flags & CONFIG) { event.xconfigure.override_redirect = number; } else { goto badopt; } break; } case EVENT_PLACE: { number = TkFindStateNumObj(interp, optionPtr, circPlace, valuePtr); if (number < 0) { return TCL_ERROR; } if (flags & CIRC) { event.xcirculate.place = number; } else { goto badopt; } break; } case EVENT_ROOT: { Window window2; if (Blt_GetWindowFromObj(interp, valuePtr, &window2) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.root = window2; } else { goto badopt; } break; } case EVENT_ROOTX: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.x_root = number; } else { goto badopt; } break; } case EVENT_ROOTY: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.y_root = number; } else { goto badopt; } break; } case EVENT_SEND: { CONST char *value; value = Tcl_GetStringFromObj(valuePtr, NULL); if (isdigit(UCHAR(value[0]))) { /* * Allow arbitrary integer values for the field; they * are needed by a few of the tests in the Tk test suite. */ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } } else { if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } } event.xany.send_event = number; break; } case EVENT_SERIAL: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } event.xany.serial = number; break; } case EVENT_STATE: { if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { event.xkey.state = number; } else { event.xcrossing.state = number; } } else if (flags & VISIBILITY) { number = TkFindStateNumObj(interp, optionPtr, visNotify, valuePtr); if (number < 0) { return TCL_ERROR; } event.xvisibility.state = number; } else { goto badopt; } break; } case EVENT_SUBWINDOW: { Window window2; if (Blt_GetWindowFromObj(interp, valuePtr, &window2) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.subwindow = window2; } else { goto badopt; } break; } case EVENT_TIME: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.time = (Time) number; } else if (flags & PROP) { event.xproperty.time = (Time) number; } else { goto badopt; } break; } case EVENT_WIDTH: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & EXPOSE) { event.xexpose.width = number; } else if (flags & (CREATE|CONFIG)) { event.xcreatewindow.width = number; } else { goto badopt; } break; } case EVENT_WINDOW: { Window window2; if (Blt_GetWindowFromObj(interp, valuePtr, &window2) != TCL_OK) { return TCL_ERROR; } if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG |GRAVITY|CIRC)) { event.xcreatewindow.window = window2; } else { goto badopt; } break; } case EVENT_X: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.x = number; /* * Only modify rootx as well if it hasn't been changed. */ if (event.xkey.x_root == -1) { int rootX, rootY; Tk_GetRootCoords(tkwin, &rootX, &rootY); event.xkey.x_root = rootX + number; } } else if (flags & EXPOSE) { event.xexpose.x = number; } else if (flags & (CREATE|CONFIG|GRAVITY)) { event.xcreatewindow.x = number; } else if (flags & REPARENT) { event.xreparent.x = number; } else { goto badopt; } break; } case EVENT_Y: { if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { event.xkey.y = number; /* * Only modify rooty as well if it hasn't been changed. */ if (event.xkey.y_root == -1) { int rootX, rootY; Tk_GetRootCoords(tkwin, &rootX, &rootY); event.xkey.y_root = rootY + number; } } else if (flags & EXPOSE) { event.xexpose.y = number; } else if (flags & (CREATE|CONFIG|GRAVITY)) { event.xcreatewindow.y = number; } else if (flags & REPARENT) { event.xreparent.y = number; } else { goto badopt; } break; } } continue; badopt: Tcl_AppendResult(interp, name, " event doesn't accept \"", Tcl_GetStringFromObj(optionPtr, NULL), "\" option", (char *)NULL); return TCL_ERROR; } if (!XSendEvent(display, window, False, pat.eventType, &event)) { fprintf(stderr, "synthethic event failed\n"); } return TCL_OK; } int Blt_SendEventCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "sendevent", SendEventCmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltScrollbar.c����������������������������������������������������������������0000644�0001750�0001750�00000125045�11462120062�015625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltScrollbar.c -- * * This module implements a scrollbar widgets for the Tk toolkit. A * scrollbar displays a slider and two arrows; mouse clicks on features * within the scrollbar cause scrolling commands to be invoked. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkScrollbar.c 1.79 96/02/15 18:52:40 */ #include "bltInt.h" #ifndef NO_TKSCROLLBAR #include "bltBgStyle.h" #define NORMAL_BG "#d9d9d9" #define ACTIVE_BG "#ececec" #define SELECT_BG "#c3c3c3" #define TROUGH "#c3c3c3" #define INDICATOR "#b03060" #define DISABLED "#a3a3a3" /* * Defaults for scrollbars: */ #define DEF_ACTIVE_BACKGROUND ACTIVE_BG #define DEF_ACTIVE_BG_MONO RGB_BLACK #define DEF_ACTIVE_RELIEF "raised" #define DEF_ARROW_COLOR "black" #define DEF_DISABLED_ARROW_COLOR RGB_GREY50 #define DEF_BACKGROUND NORMAL_BG #define DEF_BG_MONO RGB_WHITE #define DEF_BORDERWIDTH "2" #define DEF_COMMAND "" #define DEF_CURSOR "" #define DEF_ELEMENT_BORDERWIDTH "1" #define DEF_HIGHLIGHT RGB_BLACK #define DEF_HIGHLIGHT_BG NORMAL_BG #define DEF_HIGHLIGHT_WIDTH "2" #define DEF_JUMP "0" #define DEF_MIN_SLIDER_LENGTH "12" #define DEF_ORIENT "vertical" #define DEF_RELIEF "sunken" #define DEF_REPEAT_DELAY "300" #define DEF_REPEAT_INTERVAL "100" #define DEF_SELECT_BACKGROUND SELECT_BG #define DEF_TAKE_FOCUS (char *)NULL #define DEF_TROUGH_COLOR "grey" /*TROUGH*/ #define DEF_TROUGH_MONO RGB_WHITE #define DEF_WIDTH "3.0m" #define DEF_SELECT_RELIEF "sunken" #define SB_WIDTH 15 /* * A data structure of the following type is kept for each scrollbar widget * managed by this file: */ typedef struct { Tk_Window tkwin; /* Window that embodies the scrollbar. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up.*/ Display *display; /* Display containing widget. Used, * among other things, so that * resources can be freed even after * tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with * scrollbar. */ Tcl_Command widgetCmd; /* Token for scrollbar's widget * command. */ char *orientation; /* Orientation for window ("vertical" * or "horizontal"). */ int vertical; /* Non-zero means vertical orientation * requested, zero means horizontal. */ int width; /* Desired narrow dimension of * scrollbar, in pixels. */ char *command; /* Command prefix to use when invoking * scrolling commands. NULL means don't * invoke commands. Malloc'ed. */ int commandSize; /* Number of non-NULL bytes in * command. */ int repeatDelay; /* How long to wait before * auto-repeating on scrolling actions * (in * ms). */ int repeatInterval; /* Interval between autorepeats (in * ms). */ int jump; /* Value of -jump option. */ /* * Information used when displaying widget: */ int borderWidth; /* Width of 3-D borders. */ Blt_Background bg; /* Used for drawing background (all flat * surfaces except for trough). */ Blt_Background activeBg; /* For drawing backgrounds when active * (i.e. when mouse is positioned * over element). */ Blt_Background selBg; Blt_Background troughBg; /* For drawing trough. */ GC copyGC; /* Used for copying from pixmap onto screen. */ XColor *disabledArrowColor; /* Used for drawing the arrow. */ XColor *arrowColor; /* Used for drawing the arrow. */ int relief; /* Indicates whether window as a whole * is raised, sunken, or flat. */ int highlightWidth; /* Width in pixels of highlight to * draw around widget when it has the * focus. <= 0 means don't draw a * highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal * highlight area when highlight is * off. */ XColor *highlightColorPtr; /* Color for drawing traversal * highlight. */ int inset; /* Total width of all borders, * including traversal highlight and * 3-D * border. Indicates how much * interior stuff must be offset from * outside edges to leave room for * borders. */ int minSliderLength; /* Minimum size of thumb. */ int elementBW; /* Width of border to draw around * elements inside scrollbar (arrows * and * slider). -1 means use * borderWidth. */ int arrowLength; /* Length of arrows along long * dimension of scrollbar, including * space for a small gap between the * arrow and the slider. Recomputed * on window size changes. */ int sliderFirst; /* Pixel coordinate of top or left * edge of slider area, including * border. */ int sliderLast; /* Coordinate of pixel just after * bottom or right edge of slider * area, including border. */ int activeField; /* Names field to be displayed in * active colors, such as TOP_ARROW, * or 0 for no field. */ int activeRelief; /* Value of -activeRelief option: * relief to use for active element. */ int selRelief; int selField; /* Names field to be displayed in * active colors, such as TOP_ARROW, * or 0 for no field. */ /* * Information describing the application related to the scrollbar. This * information is provided by the application by invoking the "set" widget * command. This information can now be provided in two ways: the "old" * form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new" * form (firstFraction and lastFraction). FirstFraction and lastFraction * will always be valid, but the old-style information is only valid if * the NEW_STYLE_COMMANDS flag is 0. */ int totalUnits; /* Total dimension of application, in * units. Valid only if the * NEW_STYLE_COMMANDS flag isn't * set. */ int windowUnits; /* Maximum number of units that can be * displayed in the window at once. * Valid * only if the * NEW_STYLE_COMMANDS flag isn't * set. */ int firstUnit; /* Number of last unit visible in * application's window. Valid only * if the NEW_STYLE_COMMANDS flag * isn't set. */ int lastUnit; /* Index of last unit visible in * window. Valid only if the * NEW_STYLE_COMMANDS flag isn't set. */ double firstFraction; /* Position of first visible thing in * window, specified as a fraction * between 0 and 1.0. */ double lastFraction; /* Position of last visible thing in * window, specified as a fraction * between 0 and 1.0. */ /* * Miscellaneous information: */ Tk_Cursor cursor; /* Current cursor for window, or * None. */ char *takeFocus; /* Value of -takefocus option; not * used in the C code, but used by * keyboard traversal scripts. * Malloc'ed, but may be * NULL. */ int flags; /* Various flags; see below for * definitions. */ } Scrollbar; /* * Legal values for "activeField" field of Scrollbar structures. These are * also the return values from the ScrollbarPosition procedure. */ #define OUTSIDE 0 #define TOP_ARROW 1 #define TOP_GAP 2 #define SLIDER 3 #define BOTTOM_GAP 4 #define BOTTOM_ARROW 5 /* * Flag bits for scrollbars: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler * has already been queued to redraw * this window. * NEW_STYLE_COMMANDS: Non-zero means the new style of commands * should be used to communicate with the * widget: ".t yview scroll 2 lines", instead * of ".t yview 40", for example. * GOT_FOCUS: Non-zero means this window has the input * focus. */ #define REDRAW_PENDING 1 #define NEW_STYLE_COMMANDS 2 #define GOT_FOCUS 4 /* * Minimum slider length, in pixels (designed to make sure that the slider * is always easy to grab with the mouse). */ #define MIN_SLIDER_LENGTH 12 /* * Information used for objv parsing. */ static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Foreground", DEF_ACTIVE_BACKGROUND, Blt_Offset(Scrollbar, activeBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Foreground", DEF_ACTIVE_BG_MONO, Blt_Offset(Scrollbar, activeBg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_ACTIVE_RELIEF, Blt_Offset(Scrollbar, activeRelief), 0}, {BLT_CONFIG_COLOR, "-arrowcolor", "arrowColor", "ArrowColor", DEF_ARROW_COLOR, Blt_Offset(Scrollbar, arrowColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BACKGROUND, Blt_Offset(Scrollbar, bg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BG_MONO, Blt_Offset(Scrollbar, bg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, Blt_Offset(Scrollbar, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-command", "command", "Command", DEF_COMMAND, Blt_Offset(Scrollbar, command), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_CURSOR, Blt_Offset(Scrollbar, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-diabledarrowcolor", "disabledArrowColor", "DisabledArrowColor", DEF_DISABLED_ARROW_COLOR, Blt_Offset(Scrollbar, disabledArrowColor), 0}, {BLT_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth", "BorderWidth", DEF_ELEMENT_BORDERWIDTH, Blt_Offset(Scrollbar, elementBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_HIGHLIGHT_BG, Blt_Offset(Scrollbar, highlightBgColorPtr), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_HIGHLIGHT, Blt_Offset(Scrollbar, highlightColorPtr), 0}, {BLT_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHT_WIDTH, Blt_Offset(Scrollbar, highlightWidth), 0}, {BLT_CONFIG_BOOLEAN, "-jump", "jump", "Jump", DEF_JUMP, Blt_Offset(Scrollbar, jump), 0}, {BLT_CONFIG_PIXELS_POS, "-minsliderlength", "minSliderLength", "MinSliderLength", DEF_MIN_SLIDER_LENGTH, Blt_Offset(Scrollbar, minSliderLength), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-orient", "orient", "Orient", DEF_ORIENT, Blt_Offset(Scrollbar, orientation), 0}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_RELIEF, Blt_Offset(Scrollbar, relief), 0}, {BLT_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", DEF_REPEAT_DELAY, Blt_Offset(Scrollbar, repeatDelay), 0}, {BLT_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval", DEF_REPEAT_INTERVAL, Blt_Offset(Scrollbar, repeatInterval), 0}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", DEF_SELECT_BACKGROUND, Blt_Offset(Scrollbar, selBg), 0}, {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief", DEF_ACTIVE_RELIEF, Blt_Offset(Scrollbar, selRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, Blt_Offset(Scrollbar, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-troughcolor", "troughColor", "Background", DEF_TROUGH_COLOR, Blt_Offset(Scrollbar, troughBg), 0}, {BLT_CONFIG_PIXELS, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Scrollbar, width), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * Forward declarations for procedures defined later in this file: */ static void ComputeScrollbarGeometry(Scrollbar *scrollPtr); static int ConfigureScrollbar(Tcl_Interp *interp, Scrollbar *scrollPtr, int objc, Tcl_Obj *const *objv, int flags); static void DestroyScrollbar(DestroyData *memPtr); static void DisplayScrollbar(ClientData clientData); static void EventuallyRedraw(Scrollbar *scrollPtr); static void ScrollbarCmdDeletedProc(ClientData clientData); static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr); static int ScrollbarPosition(Scrollbar *scrollPtr, int x, int y); static int ScrollbarWidgetCmd(ClientData clientData, Tcl_Interp *, int objc, Tcl_Obj *const *objv); static Blt_BackgroundChangedProc BackgroundChangedProc; static Tcl_ObjCmdProc ScrollbarCmd; static const char * NameOfField(int field) { switch (field) { case BOTTOM_ARROW: return "arrow2"; case BOTTOM_GAP: return "trough2"; case SLIDER: return "slider"; case TOP_ARROW: return "arrow1"; case TOP_GAP: return "trough1"; default: return "???"; } } static int GetFieldFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *fieldPtr) { char *string; int length; char c; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'a') && (strcmp(string, "arrow1") == 0)) { *fieldPtr = TOP_ARROW; } else if ((c == 'a') && (strcmp(string, "arrow2") == 0)) { *fieldPtr = BOTTOM_ARROW; } else if ((c == 's') && (strncmp(string, "slider", length) == 0)) { *fieldPtr = SLIDER; } else { *fieldPtr = OUTSIDE; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScrollbarCmd -- * * This procedure is invoked to process the "scrollbar" TCL command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScrollbarCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Scrollbar *sp; Tk_Window tkwin; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?options?\"", (char *)NULL); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } /* * Initialize fields that won't be initialized by ConfigureScrollbar, or * which ConfigureScrollbar expects to have reasonable values * (e.g. resource pointers). */ sp = Blt_AssertCalloc(1, sizeof(Scrollbar)); sp->tkwin = tkwin; sp->display = Tk_Display(tkwin); sp->interp = interp; sp->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(sp->tkwin), ScrollbarWidgetCmd, (ClientData)sp, ScrollbarCmdDeletedProc); sp->relief = TK_RELIEF_FLAT; sp->elementBW = 2; sp->borderWidth = 1; sp->selRelief = TK_RELIEF_SUNKEN; sp->activeRelief = TK_RELIEF_RAISED; sp->minSliderLength = MIN_SLIDER_LENGTH; sp->width = SB_WIDTH; Tk_SetClass(sp->tkwin, "TkScrollbar"); Tk_CreateEventHandler(sp->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, ScrollbarEventProc, (ClientData)sp); if (ConfigureScrollbar(interp, sp, objc - 2, objv + 2, 0) != TCL_OK) { goto error; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; error: Tk_DestroyWindow(sp->tkwin); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ScrollbarWidgetCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int ScrollbarWidgetCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Scrollbar *scrollPtr = clientData; int result = TCL_OK; int length; int c; char *string; Tcl_CmdInfo cmdInfo; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", objv[0], " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, invoke a procedure to initialize * various bindings on the combomenu widget. If the procedure doesn't * already exist, source it from "$blt_library/scrollbar.tcl". We * deferred sourcing the file until now so that the variable $blt_library * could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::TkScrollbar::ScrollButtonDown", &cmdInfo)) { static char cmd[] = "source [file join $blt_library scrollbar.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } Tcl_Preserve((ClientData)scrollPtr); string = Tcl_GetStringFromObj(objv[1], &length); c = string[0]; if ((c == 'a') && (strncmp(string, "activate", length) == 0)) { if (objc > 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " activate element\"", (char *)NULL); goto error; } if (objc == 2) { Tcl_SetStringObj(Tcl_GetObjResult(interp), NameOfField(scrollPtr->activeField), -1); } else { GetFieldFromObj(interp, objv[2], &scrollPtr->activeField); EventuallyRedraw(scrollPtr); } } else if ((c == 'c') && (length >= 2) && (strncmp(string, "cget", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " cget option\"", (char *)NULL); goto error; } result = Blt_ConfigureValueFromObj(interp, scrollPtr->tkwin, configSpecs, (char *)scrollPtr, objv[2], 0); } else if ((c == 'c') && (length >= 2) && (strncmp(string, "configure", length) == 0)) { if (objc == 2) { result = Blt_ConfigureInfoFromObj(interp, scrollPtr->tkwin, configSpecs, (char *)scrollPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { result = Blt_ConfigureInfoFromObj(interp, scrollPtr->tkwin, configSpecs, (char *)scrollPtr, objv[2], 0); } else { result = ConfigureScrollbar(interp, scrollPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); } } else if ((c == 'd') && (strncmp(string, "delta", length) == 0)) { int xDelta, yDelta, pixels, barWidth; double fraction; if (objc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " delta xDelta yDelta\"", (char *)NULL); goto error; } if ((Tcl_GetIntFromObj(interp, objv[2], &xDelta) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &yDelta) != TCL_OK)) { goto error; } if (scrollPtr->vertical) { pixels = yDelta; barWidth = Tk_Height(scrollPtr->tkwin) - 1 - 2 * (scrollPtr->arrowLength + scrollPtr->inset); } else { pixels = xDelta; barWidth = Tk_Width(scrollPtr->tkwin) - 1 - 2 * (scrollPtr->arrowLength + scrollPtr->inset); } if (barWidth == 0) { fraction = 0.0; } else { fraction = ((double)pixels / (double)barWidth); } Tcl_SetDoubleObj(Tcl_GetObjResult(interp), fraction); } else if ((c == 'f') && (strncmp(string, "fraction", length) == 0)) { int x, y, pos, barWidth; double fraction; if (objc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " fraction x y\"", (char *)NULL); goto error; } if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } if (scrollPtr->vertical) { pos = y - (scrollPtr->arrowLength + scrollPtr->inset); barWidth = Tk_Height(scrollPtr->tkwin) - 1 - 2 * (scrollPtr->arrowLength + scrollPtr->inset); } else { pos = x - (scrollPtr->arrowLength + scrollPtr->inset); barWidth = Tk_Width(scrollPtr->tkwin) - 1 - 2 * (scrollPtr->arrowLength + scrollPtr->inset); } if (barWidth == 0) { fraction = 0.0; } else { fraction = ((double)pos / (double)barWidth); } if (fraction < 0.0) { fraction = 0.0; } else if (fraction > 1.0) { fraction = 1.0; } Tcl_SetDoubleObj(Tcl_GetObjResult(interp), fraction); } else if ((c == 'g') && (strncmp(string, "get", length) == 0)) { if (objc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " get\"", (char *)NULL); goto error; } if (scrollPtr->flags & NEW_STYLE_COMMANDS) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(scrollPtr->firstFraction)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(scrollPtr->lastFraction)); Tcl_SetObjResult(interp, listObjPtr); } else { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(scrollPtr->totalUnits)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(scrollPtr->windowUnits)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(scrollPtr->firstUnit)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(scrollPtr->lastUnit)); Tcl_SetObjResult(interp, listObjPtr); } } else if ((c == 'i') && (strncmp(string, "identify", length) == 0)) { int x, y, thing; if (objc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " identify x y\"", (char *)NULL); goto error; } if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } thing = ScrollbarPosition(scrollPtr, x, y); Tcl_SetStringObj(Tcl_GetObjResult(interp), NameOfField(thing), -1); } else if ((c == 's') && (strncmp(string, "set", length) == 0)) { int totalUnits, windowUnits, firstUnit, lastUnit; if (objc == 4) { double first, last; if ((Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[3], &last) != TCL_OK)) { goto error; } if (first < 0) { scrollPtr->firstFraction = 0; } else if (first > 1.0) { scrollPtr->firstFraction = 1.0; } else { scrollPtr->firstFraction = first; } if (last < scrollPtr->firstFraction) { scrollPtr->lastFraction = scrollPtr->firstFraction; } else if (last > 1.0) { scrollPtr->lastFraction = 1.0; } else { scrollPtr->lastFraction = last; } scrollPtr->flags |= NEW_STYLE_COMMANDS; } else if (objc == 6) { if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) { goto error; } if (totalUnits < 0) { totalUnits = 0; } if (Tcl_GetIntFromObj(interp, objv[3], &windowUnits) != TCL_OK) { goto error; } if (windowUnits < 0) { windowUnits = 0; } if (Tcl_GetIntFromObj(interp, objv[4], &firstUnit) != TCL_OK) { goto error; } if (Tcl_GetIntFromObj(interp, objv[5], &lastUnit) != TCL_OK) { goto error; } if (totalUnits > 0) { if (lastUnit < firstUnit) { lastUnit = firstUnit; } } else { firstUnit = lastUnit = 0; } scrollPtr->totalUnits = totalUnits; scrollPtr->windowUnits = windowUnits; scrollPtr->firstUnit = firstUnit; scrollPtr->lastUnit = lastUnit; if (scrollPtr->totalUnits == 0) { scrollPtr->firstFraction = 0.0; scrollPtr->lastFraction = 1.0; } else { scrollPtr->firstFraction = ((double)firstUnit) / totalUnits; scrollPtr->lastFraction = ((double)(lastUnit + 1)) / totalUnits; } scrollPtr->flags &= ~NEW_STYLE_COMMANDS; } else { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " set firstFraction lastFraction\" or \"", Tcl_GetString(objv[0]), " set totalUnits windowUnits firstUnit lastUnit\"", (char *)NULL); goto error; } ComputeScrollbarGeometry(scrollPtr); EventuallyRedraw(scrollPtr); } else if ((c == 's') && (strncmp(string, "select", length) == 0)) { if (objc > 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " select element\"", (char *)NULL); goto error; } if (objc == 2) { Tcl_SetStringObj(Tcl_GetObjResult(interp), NameOfField(scrollPtr->selField), -1); } else { GetFieldFromObj(interp, objv[2], &scrollPtr->selField); EventuallyRedraw(scrollPtr); } } else { Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be activate, cget, configure, delta, fraction, ", "get, identify, or set", (char *)NULL); goto error; } Tcl_Release((ClientData)scrollPtr); return result; error: Tcl_Release((ClientData)scrollPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DestroyScrollbar -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of a scrollbar at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the scrollbar is freed up. * *--------------------------------------------------------------------------- */ static void DestroyScrollbar(DestroyData *memPtr) /* Info about scrollbar widget. */ { Scrollbar *scrollPtr = (Scrollbar *)memPtr; /* * Free up all the stuff that requires special handling, then let * Blt_FreeOptions handle all the standard option-related stuff. */ if (scrollPtr->copyGC != None) { Tk_FreeGC(scrollPtr->display, scrollPtr->copyGC); } Blt_FreeOptions(configSpecs, (char *)scrollPtr, scrollPtr->display, 0); Blt_Free(scrollPtr); } /* *--------------------------------------------------------------------------- * * BackgroundChangedProc * * Routine for background change notifications. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void BackgroundChangedProc(ClientData clientData) { Scrollbar *scrollPtr = clientData; if (scrollPtr->tkwin != NULL) { EventuallyRedraw(scrollPtr); } } /* *--------------------------------------------------------------------------- * * ConfigureScrollbar -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a scrollbar * widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information, such as colors, border width, etc. get set * for scrollPtr; old resources get freed, if there were any. * *--------------------------------------------------------------------------- */ static int ConfigureScrollbar( Tcl_Interp *interp, /* Used for error reporting. */ Scrollbar *scrollPtr, /* Information about widget; may or * may not already have values for * some fields. */ int objc, /* Number of valid entries in objv. */ Tcl_Obj *const *objv, /* Arguments. */ int flags) /* Flags to pass to * Blt_ConfigureWidget. */ { size_t length; XGCValues gcValues; if (Blt_ConfigureWidgetFromObj(interp, scrollPtr->tkwin, configSpecs, objc, objv, (char *)scrollPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few options need special processing, such as parsing the orientation * or setting the background from a 3-D border. */ length = strlen(scrollPtr->orientation); if (strncmp(scrollPtr->orientation, "vertical", length) == 0) { scrollPtr->vertical = 1; } else if (strncmp(scrollPtr->orientation, "horizontal", length) == 0) { scrollPtr->vertical = 0; } else { Tcl_AppendResult(interp, "bad orientation \"", scrollPtr->orientation, "\": must be vertical or horizontal", (char *)NULL); return TCL_ERROR; } if (scrollPtr->command != NULL) { scrollPtr->commandSize = strlen(scrollPtr->command); } else { scrollPtr->commandSize = 0; } if (scrollPtr->activeBg != NULL) { Blt_SetBackgroundChangedProc(scrollPtr->activeBg, BackgroundChangedProc, scrollPtr); } if (scrollPtr->bg != NULL) { Blt_SetBackgroundChangedProc(scrollPtr->bg, BackgroundChangedProc, scrollPtr); } Blt_SetBackgroundFromBackground(scrollPtr->tkwin, scrollPtr->bg); if (scrollPtr->copyGC == None) { gcValues.graphics_exposures = False; scrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin, GCGraphicsExposures, &gcValues); } /* * Register the desired geometry for the window (leave enough space for * the two arrows plus a minimum-size slider, plus border around the whole * window, if any). Then arrange for the window to be redisplayed. */ ComputeScrollbarGeometry(scrollPtr); EventuallyRedraw(scrollPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DisplayScrollbar -- * * This procedure redraws the contents of a scrollbar window. It is * invoked as a do-when-idle handler, so it only runs when there's * nothing else for the application to do. * * Results: * None. * * Side effects: * Information appears on the screen. * *--------------------------------------------------------------------------- */ static void DisplayScrollbar(ClientData clientData) /* Information about window. */ { Blt_Background bg; XColor *fg; Pixmap pixmap; Scrollbar *scrollPtr = clientData; Tk_Window tkwin; XPoint points[7]; int relief, width, elementBW; scrollPtr->flags &= ~REDRAW_PENDING; tkwin = scrollPtr->tkwin; if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } if ((Tk_Width(tkwin) <= 1) || (Tk_Height(tkwin) <= 1)) { return; } if (scrollPtr->vertical) { width = Tk_Width(tkwin) - 2 * scrollPtr->inset; } else { width = Tk_Height(tkwin) - 2 * scrollPtr->inset; } elementBW = scrollPtr->elementBW; if (elementBW < 0) { elementBW = scrollPtr->borderWidth; } /* * In order to avoid screen flashes, this procedure redraws the scrollbar * in a pixmap, then copies the pixmap to the screen in a single * operation. This means that there's no point in time where the on-sreen * image has been cleared. */ pixmap = Tk_GetPixmap(scrollPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); if (scrollPtr->highlightWidth != 0) { GC gc; if (scrollPtr->flags & GOT_FOCUS) { gc = Tk_GCForColor(scrollPtr->highlightColorPtr, pixmap); } else { gc = Tk_GCForColor(scrollPtr->highlightBgColorPtr, pixmap); } Tk_DrawFocusHighlight(tkwin, gc, scrollPtr->highlightWidth, pixmap); } Blt_FillBackgroundRectangle(tkwin, pixmap, scrollPtr->troughBg, scrollPtr->highlightWidth, scrollPtr->highlightWidth, Tk_Width(tkwin) - 2 * scrollPtr->highlightWidth, Tk_Height(tkwin) - 2 * scrollPtr->highlightWidth, scrollPtr->borderWidth, scrollPtr->relief); /* * Draw the top or left arrow. The coordinates of the polygon points * probably seem odd, but they were carefully chosen with respect to X's * rules for filling polygons. These point choices cause the arrows to * just fill the narrow dimension of the scrollbar and be properly * centered. */ if (scrollPtr->selField == TOP_ARROW) { bg = scrollPtr->selBg; relief = scrollPtr->selRelief; } else if (scrollPtr->activeField == TOP_ARROW) { bg = scrollPtr->activeBg; relief = scrollPtr->activeRelief; } else { bg = scrollPtr->bg; relief = TK_RELIEF_RAISED; } if (scrollPtr->vertical) { points[0].x = scrollPtr->inset - 1; points[0].y = scrollPtr->arrowLength + scrollPtr->inset - 1; points[1].x = width + scrollPtr->inset; points[1].y = points[0].y; points[2].x = width / 2 + scrollPtr->inset; points[2].y = scrollPtr->inset - 1; } else { points[0].x = scrollPtr->arrowLength + scrollPtr->inset - 1; points[0].y = scrollPtr->inset - 1; points[1].x = scrollPtr->inset; points[1].y = width / 2 + scrollPtr->inset; points[2].x = points[0].x; points[2].y = width + scrollPtr->inset; } Blt_FillBackgroundRectangle(tkwin, pixmap, bg, scrollPtr->inset, scrollPtr->inset, width, width, elementBW, relief); fg = (scrollPtr->firstFraction <= 0.0) ? scrollPtr->disabledArrowColor : scrollPtr->arrowColor; Blt_DrawArrow(scrollPtr->display, pixmap, fg, scrollPtr->inset+1, scrollPtr->inset+1, width-2, width-2, elementBW, (scrollPtr->vertical) ? ARROW_UP : ARROW_LEFT); /* * Display the bottom or right arrow. */ if (scrollPtr->selField == BOTTOM_ARROW) { bg = scrollPtr->selBg; relief = scrollPtr->selRelief; } else if (scrollPtr->activeField == BOTTOM_ARROW) { bg = scrollPtr->activeBg; relief = scrollPtr->activeRelief; } else { bg = scrollPtr->bg; relief = TK_RELIEF_RAISED; } if (scrollPtr->vertical) { points[0].x = scrollPtr->inset; points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength - scrollPtr->inset + 1; points[1].x = width / 2 + scrollPtr->inset; points[1].y = Tk_Height(tkwin) - scrollPtr->inset; points[2].x = width + scrollPtr->inset; points[2].y = points[0].y; } else { points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength - scrollPtr->inset + 1; points[0].y = scrollPtr->inset - 1; points[1].x = points[0].x; points[1].y = width + scrollPtr->inset; points[2].x = Tk_Width(tkwin) - scrollPtr->inset; points[2].y = width / 2 + scrollPtr->inset; } #ifdef notdef Blt_FillBackgroundPolygon(tkwin, pixmap, bg, points, 3, elementBW, relief); } #else Blt_FillBackgroundRectangle(tkwin, pixmap, bg, Tk_Width(tkwin) - (width + scrollPtr->inset), Tk_Height(tkwin) - (width + scrollPtr->inset), width, width, elementBW, relief); fg = (scrollPtr->lastFraction >= 1.0) ? scrollPtr->disabledArrowColor : scrollPtr->arrowColor; Blt_DrawArrow(scrollPtr->display, pixmap, fg, Tk_Width(tkwin) - scrollPtr->inset - width + 1, Tk_Height(tkwin) - scrollPtr->inset - width + 1, width - 2, width - 2, elementBW, (scrollPtr->vertical) ? ARROW_DOWN : ARROW_RIGHT); #endif /* * Display the slider. */ if (scrollPtr->activeField == SLIDER) { bg = scrollPtr->activeBg; relief = TK_RELIEF_RAISED; } else if (scrollPtr->activeField == SLIDER) { bg = scrollPtr->activeBg; relief = scrollPtr->activeRelief; } else { bg = scrollPtr->bg; relief = TK_RELIEF_RAISED; } if (scrollPtr->vertical) { Blt_FillBackgroundRectangle(tkwin, pixmap, bg, scrollPtr->inset, scrollPtr->sliderFirst, width, scrollPtr->sliderLast - scrollPtr->sliderFirst, elementBW, relief); } else { Blt_FillBackgroundRectangle(tkwin, pixmap, bg, scrollPtr->sliderFirst, scrollPtr->inset, scrollPtr->sliderLast - scrollPtr->sliderFirst, width, elementBW, relief); } /* * Copy the information from the off-screen pixmap onto the screen, then * delete the pixmap. */ XCopyArea(scrollPtr->display, pixmap, Tk_WindowId(tkwin), scrollPtr->copyGC, 0, 0, (unsigned)Tk_Width(tkwin), (unsigned)Tk_Height(tkwin), 0, 0); Tk_FreePixmap(scrollPtr->display, pixmap); } /* *--------------------------------------------------------------------------- * * ScrollbarEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * scrollbars. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ScrollbarEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { Scrollbar *scrollPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { EventuallyRedraw(scrollPtr); } else if (eventPtr->type == DestroyNotify) { if (scrollPtr->tkwin != NULL) { scrollPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(scrollPtr->interp,scrollPtr->widgetCmd); } if (scrollPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayScrollbar, (ClientData)scrollPtr); } Tcl_EventuallyFree((ClientData)scrollPtr, (Tcl_FreeProc *)DestroyScrollbar); } else if (eventPtr->type == ConfigureNotify) { ComputeScrollbarGeometry(scrollPtr); EventuallyRedraw(scrollPtr); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { scrollPtr->flags |= GOT_FOCUS; if (scrollPtr->highlightWidth > 0) { EventuallyRedraw(scrollPtr); } } } else if (eventPtr->type == FocusOut) { if (eventPtr->xfocus.detail != NotifyInferior) { scrollPtr->flags &= ~GOT_FOCUS; if (scrollPtr->highlightWidth > 0) { EventuallyRedraw(scrollPtr); } } } } /* *--------------------------------------------------------------------------- * * ScrollbarCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ScrollbarCmdDeletedProc(ClientData clientData) { Scrollbar *scrollPtr = clientData; Tk_Window tkwin = scrollPtr->tkwin; /* * This procedure could be invoked either because the window was destroyed * and the command was then deleted (in which case tkwin is NULL) or * because the command was deleted, and then this procedure destroys the * widget. */ if (tkwin != NULL) { scrollPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ComputeScrollbarGeometry -- * * After changes in a scrollbar's size or configuration, this procedure * recomputes various geometry information used in displaying the * scrollbar. * * Results: * None. * * Side effects: * The scrollbar will be displayed differently. * *--------------------------------------------------------------------------- */ static void ComputeScrollbarGeometry(Scrollbar *sp) { int width, fieldLength; if (sp->highlightWidth < 0) { sp->highlightWidth = 0; } sp->inset = sp->highlightWidth + sp->borderWidth; width = (sp->vertical) ? Tk_Width(sp->tkwin) : Tk_Height(sp->tkwin); sp->arrowLength = width - (2 * sp->inset + 1); fieldLength = (sp->vertical ? Tk_Height(sp->tkwin) : Tk_Width(sp->tkwin)) - 2 * (sp->arrowLength + sp->inset); if (fieldLength < 0) { fieldLength = 0; } sp->sliderFirst = (int)(fieldLength * sp->firstFraction); sp->sliderLast = (int)(fieldLength * sp->lastFraction); /* * Adjust the slider so that some piece of it is always displayed in the * scrollbar and so that it has at least a minimal width (so it can be * grabbed with the mouse). */ { int minSliderLength, sliderLength; minSliderLength = sp->minSliderLength; if (minSliderLength > fieldLength) { minSliderLength = fieldLength; } sliderLength = sp->sliderLast - sp->sliderFirst; if (sliderLength < minSliderLength) { fieldLength -= minSliderLength - sliderLength; sp->sliderFirst = (int)(fieldLength * sp->firstFraction); sp->sliderLast = sp->sliderFirst + minSliderLength; } else { if (sp->sliderFirst > (fieldLength - 2 * sp->borderWidth)) { sp->sliderFirst = fieldLength - 2 * sp->borderWidth; } if (sp->sliderFirst < 0) { sp->sliderFirst = 0; } if (sp->sliderLast > fieldLength) { sp->sliderLast = fieldLength; } } } sp->sliderFirst += sp->arrowLength + sp->inset; sp->sliderLast += sp->arrowLength + sp->inset; /* * Register the desired geometry for the window (leave enough space for * the two arrows plus a minimum-size slider, plus border around the whole * window, if any). Then arrange for the window to be redisplayed. */ if (sp->vertical) { Tk_GeometryRequest(sp->tkwin, sp->width + 2 * sp->inset, 2 * (sp->arrowLength + sp->borderWidth + sp->inset)); } else { Tk_GeometryRequest(sp->tkwin, 2 * (sp->arrowLength + sp->borderWidth + sp->inset), sp->width + 2 * sp->inset); } Tk_SetInternalBorder(sp->tkwin, sp->inset); } /* *--------------------------------------------------------------------------- * * ScrollbarPosition -- * * Determine the scrollbar element corresponding to a given position. * * Results: * One of TOP_ARROW, TOP_GAP, etc., indicating which element of the * scrollbar covers the position given by (x, y). If (x,y) is outside * the scrollbar entirely, then OUTSIDE is returned. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ScrollbarPosition( Scrollbar *scrollPtr, /* Scrollbar widget record. */ int x, int y) /* Coordinates within scrollPtr's * window. */ { int length, width, tmp; if (scrollPtr->vertical) { length = Tk_Height(scrollPtr->tkwin); width = Tk_Width(scrollPtr->tkwin); } else { tmp = x; x = y; y = tmp; length = Tk_Width(scrollPtr->tkwin); width = Tk_Height(scrollPtr->tkwin); } if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset)) || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) { return OUTSIDE; } /* * All of the calculations in this procedure mirror those in * DisplayScrollbar. Be sure to keep the two consistent. */ if (y < (scrollPtr->inset + scrollPtr->arrowLength)) { return TOP_ARROW; } if (y < scrollPtr->sliderFirst) { return TOP_GAP; } if (y < scrollPtr->sliderLast) { return SLIDER; } if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) { return BOTTOM_ARROW; } return BOTTOM_GAP; } /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Arrange for one or more of the fields of a scrollbar to be redrawn. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Scrollbar *scrollPtr) /* Information about widget. */ { if ((scrollPtr->tkwin == NULL) || (!Tk_IsMapped(scrollPtr->tkwin))) { return; } if ((scrollPtr->flags & REDRAW_PENDING) == 0) { Tcl_DoWhenIdle(DisplayScrollbar, (ClientData)scrollPtr); scrollPtr->flags |= REDRAW_PENDING; } } int Blt_ScrollbarCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "scrollbar", ScrollbarCmd, }; return Blt_InitCmd(interp, "::blt::tk", &cmdSpec); } #endif /* NO_TKSCROLLBAR */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltSwitch.h�������������������������������������������������������������������0000644�0001750�0001750�00000010136�11462120062�015142� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltSwitch.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BLT_SWITCH_H #define BLT_SWITCH_H #ifdef HAVE_STDDEF_H # include <stddef.h> #endif /* HAVE_STDDEF_H */ #ifndef Blt_Offset #ifdef offsetof #define Blt_Offset(type, field) ((int) offsetof(type, field)) #else #define Blt_Offset(type, field) ((int) ((char *) &((type *) 0)->field)) #endif #endif /* Blt_Offset */ typedef int (Blt_SwitchParseProc)(ClientData clientData, Tcl_Interp *interp, const char *switchName, Tcl_Obj *valueObjPtr, char *record, int offset, int flags); typedef void (Blt_SwitchFreeProc)(char *record, int offset, int flags); typedef struct { Blt_SwitchParseProc *parseProc; /* Procedure to parse a switch * value and store it in its * * converted form in the data * * record. */ Blt_SwitchFreeProc *freeProc; /* Procedure to free a switch. */ ClientData clientData; /* Arbitrary one-word value used by * switch parser, passed to * parseProc. */ } Blt_SwitchCustom; /* * Type values for Blt_SwitchSpec structures. See the user * documentation for details. */ typedef enum { BLT_SWITCH_BOOLEAN, BLT_SWITCH_DOUBLE, BLT_SWITCH_BITMASK, BLT_SWITCH_BITMASK_INVERT, BLT_SWITCH_FLOAT, BLT_SWITCH_INT, BLT_SWITCH_INT_NNEG, BLT_SWITCH_INT_POS, BLT_SWITCH_LIST, BLT_SWITCH_LONG, BLT_SWITCH_LONG_NNEG, BLT_SWITCH_LONG_POS, BLT_SWITCH_OBJ, BLT_SWITCH_STRING, BLT_SWITCH_VALUE, BLT_SWITCH_CUSTOM, BLT_SWITCH_END } Blt_SwitchTypes; typedef struct { Blt_SwitchTypes type; /* Type of option, such as * BLT_SWITCH_COLOR; see definitions * below. Last option in table must * have type BLT_SWITCH_END. */ const char *switchName; /* Switch used to specify option in * argv. NULL means this spec is part * of a group. */ const char *help; /* Help string. */ int offset; /* Where in widget record to store * value; use Blt_Offset macro to * generate values for this. */ int flags; /* Any combination of the values * defined below. */ unsigned int mask; Blt_SwitchCustom *customPtr; /* If type is BLT_SWITCH_CUSTOM then * this is a pointer to info about how * to parse and print the option. * Otherwise it is irrelevant. */ } Blt_SwitchSpec; #define BLT_SWITCH_DEFAULTS (0) #define BLT_SWITCH_ARGV_PARTIAL (1<<1) #define BLT_SWITCH_OBJV_PARTIAL (1<<1) /* * Possible flag values for Blt_SwitchSpec structures. Any bits at or * above BLT_SWITCH_USER_BIT may be used by clients for selecting * certain entries. */ #define BLT_SWITCH_NULL_OK (1<<0) #define BLT_SWITCH_DONT_SET_DEFAULT (1<<3) #define BLT_SWITCH_SPECIFIED (1<<4) #define BLT_SWITCH_USER_BIT (1<<8) BLT_EXTERN int Blt_ParseSwitches(Tcl_Interp *interp, Blt_SwitchSpec *specPtr, int objc, Tcl_Obj *const *objv, void *rec, int flags); BLT_EXTERN void Blt_FreeSwitches(Blt_SwitchSpec *specs, void *rec, int flags); BLT_EXTERN int Blt_SwitchChanged TCL_VARARGS(Blt_SwitchSpec *, specs); #endif /* BLT_SWITCH_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tclIntPlatDecls.h�������������������������������������������������������������0000644�0001750�0001750�00000006526�11462120063�016241� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tclIntPlatDecls.h -- * * This file contains the declarations for all platform dependent * unsupported functions that are exported by the TCL library. These * * interfaces are not guaranteed to remain the same between * versions. Use at your own risk. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from tclIntPlatDecls.h of the TCL library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. All rights * reserved. * */ #ifndef _TCLINTPLATDECLS #define _TCLINTPLATDECLS /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tclInt.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ #ifdef __WIN32__ /* 0 */ extern void TclWinConvertError(DWORD errCode); /* 4 */ extern HINSTANCE TclWinGetTclInstance(void); #endif /* __WIN32__ */ typedef struct TclIntPlatStubs { int magic; struct TclIntPlatStubHooks *hooks; #ifdef WIN32 void (*tclWinConvertError)(DWORD errCode); /* 0 */ #else void *hook0; #endif void *hook1; void *hook2; void *hook3; #ifdef WIN32 HINSTANCE (*tclWinGetTclInstance)(void); /* 4 */ #else void *hook4; #endif void *hook5; void *hook6; void *hook7; void *hook8; void *hook9; void *hook10; void *hook11; void *hook12; void *hook13; void *hook14; void *hook15; void *hook16; void *hook17; void *hook18; void *hook19; void *hook20; void *hook21; void *hook22; void *hook23; void *hook24; void *hook25; } TclIntPlatStubs; #ifdef __cplusplus extern "C" { #endif extern TclIntPlatStubs *tclIntPlatStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) /* * Inline function declarations: */ #ifdef __WIN32__ #ifndef TclWinConvertError #define TclWinConvertError \ (tclIntPlatStubsPtr->tclWinConvertError) /* 0 */ #endif #ifndef TclWinGetTclInstance #define TclWinGetTclInstance \ (tclIntPlatStubsPtr->tclWinGetTclInstance) /* 4 */ #endif #endif /* __WIN32__ */ #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLINTPLATDECLS */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkMenubutton.c����������������������������������������������������������������0000644�0001750�0001750�00000113541�11462120063�015676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkMenubutton.c -- * * This module implements button-like widgets that are used * to invoke pull-down menus. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkMenubutton.c 1.77 96/02/15 18:52:22 */ #include "bltInt.h" /* * Defaults for menubuttons: */ #define DEF_MENUBUTTON_ANCHOR "center" #define DEF_MENUBUTTON_ACTIVE_BG STD_ACTIVE_BACKGROUND #define DEF_MENUBUTTON_ACTIVE_FG STD_ACTIVE_FOREGROUND #define DEF_MENUBUTTON_BG STD_NORMAL_BACKGROUND #define DEF_MENUBUTTON_BITMAP "" #define DEF_MENUBUTTON_BORDERWIDTH "2" #define DEF_MENUBUTTON_CURSOR "" #define DEF_MENUBUTTON_DIRECTION "below" #define DEF_MENUBUTTON_DISABLED_FG STD_DISABLED_FOREGROUND #define DEF_MENUBUTTON_FONT "Helvetica -12 bold" #define DEF_MENUBUTTON_FG STD_NORMAL_FOREGROUND #define DEF_MENUBUTTON_HEIGHT "0" #define DEF_MENUBUTTON_HIGHLIGHT_BG DEF_MENUBUTTON_BG #define DEF_MENUBUTTON_HIGHLIGHT RGB_BLACK #define DEF_MENUBUTTON_HIGHLIGHT_WIDTH "0" #define DEF_MENUBUTTON_IMAGE (char *) NULL #define DEF_MENUBUTTON_INDICATOR "0" #define DEF_MENUBUTTON_JUSTIFY "center" #define DEF_MENUBUTTON_MENU "" #define DEF_MENUBUTTON_PADX "4p" #define DEF_MENUBUTTON_PADY "3p" #define DEF_MENUBUTTON_RELIEF "flat" #define DEF_MENUBUTTON_STATE "normal" #define DEF_MENUBUTTON_TAKE_FOCUS "0" #define DEF_MENUBUTTON_TEXT "" #define DEF_MENUBUTTON_TEXT_VARIABLE "" #define DEF_MENUBUTTON_UNDERLINE "-1" #define DEF_MENUBUTTON_WIDTH "0" #define DEF_MENUBUTTON_WRAP_LENGTH "0" /* * A data structure of the following type is kept for each * widget managed by this file: */ typedef struct { Tk_Window tkwin; /* Window that embodies the widget. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up.*/ Display *display; /* Display containing widget. Needed, among * other things, so that resources can bee * freed up even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with menubutton. */ Tcl_Command widgetCmd; /* Token for menubutton's widget command. */ char *menuName; /* Name of menu associated with widget. * Malloc-ed. */ /* * Information about what's displayed in the menu button: */ char *text; /* Text to display in button (malloc'ed) * or NULL. */ int numChars; /* # of characters in text. */ int underline; /* Index of character to underline. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. * If non-NULL, button displays the contents * of this variable. */ Pixmap bitmap; /* Bitmap to display or None. If not None * then text and textVar and underline * are ignored. */ char *imageString; /* Name of image to display (malloc'ed), or * NULL. If non-NULL, bitmap, text, and * textVarName are ignored. */ Tk_Image image; /* Image to display in window, or NULL if * none. */ /* * Information used when displaying widget: */ int state; /* State of button for display purposes: * normal, active, or disabled. */ Tk_3DBorder normalBorder; /* Structure used to draw 3-D * border and background when window * isn't active. NULL means no such * border exists. */ Tk_3DBorder activeBorder; /* Structure used to draw 3-D * border and background when window * is active. NULL means no such * border exists. */ int borderWidth; /* Width of border. */ int relief; /* 3-d effect: TK_RELIEF_RAISED, etc. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. * Indicates how much interior stuff must * be offset from outside edges to leave * room for borders. */ XFontStruct *fontPtr; /* Information about text font, or NULL. */ XColor *normalFg; /* Foreground color in normal mode. */ XColor *activeFg; /* Foreground color in active mode. NULL * means use normalFg instead. */ XColor *disabledFg; /* Foreground color when disabled. NULL * means use normalFg with a 50% stipple * instead. */ GC normalTextGC; /* GC for drawing text in normal mode. */ GC activeTextGC; /* GC for drawing text in active mode (NULL * means use normalTextGC). */ Pixmap gray; /* Pixmap for displaying disabled text/icon if * disabledFg is NULL. */ GC disabledGC; /* Used to produce disabled effect. If * disabledFg isn't NULL, this GC is used to * draw button text or icon. Otherwise * text or icon is drawn with normalGC and * this GC is used to stipple background * across it. */ int leftBearing; /* Distance from text origin to leftmost drawn * pixel (positive means to right). */ int rightBearing; /* Amount text sticks right from its origin. */ char *widthString; /* Value of -width option. Malloc'ed. */ char *heightString; /* Value of -height option. Malloc'ed. */ int width, height; /* If > 0, these specify dimensions to request * for window, in characters for text and in * pixels for bitmaps. In this case the actual * size of the text string or bitmap is * ignored in computing desired window size. */ int wrapLength; /* Line length (in pixels) at which to wrap * onto next line. <= 0 means don't wrap * except at newlines. */ int xPad, yPad; /* Extra space around text or bitmap (pixels * on each side). */ Tk_Anchor anchor; /* Where text/bitmap should be displayed * inside window region. */ Tk_Justify justify; /* Justification to use for multi-line text. */ int textWidth; /* Width needed to display text as requested, * in pixels. */ int textHeight; /* Height needed to display text as requested, * in pixels. */ int indicatorOn; /* Non-zero means display indicator; 0 means * don't display. */ int indicatorHeight; /* Height of indicator in pixels. This same * amount of extra space is also left on each * side of the indicator. 0 if no indicator. */ int indicatorWidth; /* Width of indicator in pixels, including * indicatorHeight in padding on each side. * 0 if no indicator. */ /* * Miscellaneous information: */ Tk_Cursor cursor; /* Current cursor for window, or None. */ char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ int flags; /* Various flags; see below for * definitions. */ } MenuButton; /* * Flag bits for buttons: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler * has already been queued to redraw * this window. * POSTED: Non-zero means that the menu associated * with this button has been posted (typically * because of an active button press). * GOT_FOCUS: Non-zero means this button currently * has the input focus. */ #define REDRAW_PENDING 1 #define POSTED 2 #define GOT_FOCUS 4 /* * The following constants define the dimensions of the cascade indicator, * which is displayed if the "-indicatoron" option is true. The units for * these options are 1/10 millimeters. */ #define INDICATOR_WIDTH 40 #define INDICATOR_HEIGHT 17 /* * Information used for parsing configuration specs: */ static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_MENUBUTTON_ACTIVE_BG, Blt_Offset(MenuButton, activeBorder), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", DEF_MENUBUTTON_ACTIVE_FG, Blt_Offset(MenuButton, activeFg), 0}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MENUBUTTON_ANCHOR, Blt_Offset(MenuButton, anchor), 0}, {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_MENUBUTTON_BG, Blt_Offset(MenuButton, normalBorder), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_MENUBUTTON_BITMAP, Blt_Offset(MenuButton, bitmap), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_MENUBUTTON_BORDERWIDTH, Blt_Offset(MenuButton, borderWidth), 0}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_MENUBUTTON_CURSOR, Blt_Offset(MenuButton, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_MENUBUTTON_DISABLED_FG, Blt_Offset(MenuButton, disabledFg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_MENUBUTTON_FONT, Blt_Offset(MenuButton, fontPtr), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_MENUBUTTON_FG, Blt_Offset(MenuButton, normalFg), 0}, {BLT_CONFIG_STRING, "-height", "height", "Height", DEF_MENUBUTTON_HEIGHT, Blt_Offset(MenuButton, heightString), 0}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG, Blt_Offset(MenuButton, highlightBgColorPtr), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_MENUBUTTON_HIGHLIGHT, Blt_Offset(MenuButton, highlightColorPtr), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH, Blt_Offset(MenuButton, highlightWidth), 0}, {BLT_CONFIG_STRING, "-image", "image", "Image", DEF_MENUBUTTON_IMAGE, Blt_Offset(MenuButton, imageString), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", DEF_MENUBUTTON_INDICATOR, Blt_Offset(MenuButton, indicatorOn), 0}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_MENUBUTTON_JUSTIFY, Blt_Offset(MenuButton, justify), 0}, {BLT_CONFIG_STRING, "-menu", "menu", "Menu", DEF_MENUBUTTON_MENU, Blt_Offset(MenuButton, menuName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-padx", "padX", "Pad", DEF_MENUBUTTON_PADX, Blt_Offset(MenuButton, xPad), 0}, {BLT_CONFIG_PIXELS_NNEG, "-pady", "padY", "Pad", DEF_MENUBUTTON_PADY, Blt_Offset(MenuButton, yPad), 0}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_MENUBUTTON_RELIEF, Blt_Offset(MenuButton, relief), 0}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MENUBUTTON_STATE, Blt_Offset(MenuButton, state), 0}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_MENUBUTTON_TAKE_FOCUS, Blt_Offset(MenuButton, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-text", "text", "Text", DEF_MENUBUTTON_TEXT, Blt_Offset(MenuButton, text), 0}, {BLT_CONFIG_STRING, "-textvariable", "textVariable", "Variable", DEF_MENUBUTTON_TEXT_VARIABLE, Blt_Offset(MenuButton, textVarName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_INT, "-underline", "underline", "Underline", DEF_MENUBUTTON_UNDERLINE, Blt_Offset(MenuButton, underline), 0}, {BLT_CONFIG_STRING, "-width", "width", "Width", DEF_MENUBUTTON_WIDTH, Blt_Offset(MenuButton, widthString), 0}, {BLT_CONFIG_PIXELS_NNEG, "-wraplength", "wrapLength", "WrapLength", DEF_MENUBUTTON_WRAP_LENGTH, Blt_Offset(MenuButton, wrapLength), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * Forward declarations for procedures defined later in this file: */ static Tcl_CmdDeleteProc MenuButtonCmdDeletedProc; static Tk_EventProc MenuButtonEventProc; static Tk_ImageChangedProc MenuButtonImageProc; static Tcl_VarTraceProc MenuButtonTextVarProc; static Tcl_ObjCmdProc MenuButtonWidgetCmd; static Tcl_FreeProc DestroyMenuButton; static Tcl_IdleProc DisplayMenuButton; static int ConfigureMenuButton (Tcl_Interp *interp, MenuButton *mbPtr, int objc, Tcl_Obj *const *objv, int flags); static void ComputeMenuButtonGeometry (MenuButton *mbPtr); /* *--------------------------------------------------------------------------- * * Tk_MenubuttonCmd -- * * This procedure is invoked to process the "button", "label", * "radiobutton", and "checkbutton" TCL commands. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int Tk_MenubuttonCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { register MenuButton *mbPtr; Tk_Window tkwin; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?options?\"", (char *)NULL); return TCL_ERROR; } /* * Create the new window. */ tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } /* * Initialize the data structure for the button. */ mbPtr = Blt_AssertCalloc(1, sizeof(MenuButton)); mbPtr->tkwin = tkwin; mbPtr->display = Tk_Display(tkwin); mbPtr->interp = interp; mbPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(mbPtr->tkwin), MenuButtonWidgetCmd, (ClientData)mbPtr, MenuButtonCmdDeletedProc); mbPtr->underline = -1; mbPtr->state = STATE_NORMAL; mbPtr->relief = TK_RELIEF_FLAT; mbPtr->anchor = TK_ANCHOR_CENTER; mbPtr->justify = TK_JUSTIFY_CENTER; Tk_SetClass(mbPtr->tkwin, "Menubutton"); Tk_CreateEventHandler(mbPtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, MenuButtonEventProc, (ClientData)mbPtr); if (ConfigureMenuButton(interp, mbPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MenuButtonWidgetCmd -- * * This procedure is invoked to process the TCL command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int MenuButtonWidgetCmd( ClientData clientData, /* Information about button widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { MenuButton *mbPtr = clientData; char *string; int c; int length; int result = TCL_OK; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } Tcl_Preserve(mbPtr); string = Tcl_GetString(objv[1], &length); c = string[0]; if ((c == 'c') && (length >= 2) && (strncmp(string, "cget", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " cget option\"", (char *)NULL); goto error; } result = Blt_ConfigureValueFromObj(interp, mbPtr->tkwin, configSpecs, (char *)mbPtr, objv[2], 0); } else if ((c == 'c') && (length >= 2) && (strncmp(string, "configure", length) == 0)) { if (objc == 2) { result = Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, configSpecs, (char *)mbPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { result = Blt_ConfigureInfoFromObj(interp, mbPtr->tkwin, configSpecs, (char *)mbPtr, objv[2], 0); } else { result = ConfigureMenuButton(interp, mbPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); } } else { Tcl_AppendResult(interp, "bad option \"", string, "\": must be cget or configure", (char *)NULL); goto error; } Tcl_Release(mbPtr); return result; error: Tcl_Release(mbPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DestroyMenuButton -- * * This procedure is invoked to recycle all of the resources * associated with a button widget. It is invoked as a * when-idle handler in order to make sure that there is no * other use of the button pending at the time of the deletion. * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyMenuButton(char *memPtr) /* Info about button widget. */ { register MenuButton *mbPtr = (MenuButton *)memPtr; /* * Free up all the stuff that requires special handling, then * let Blt_FreeOptions handle all the standard option-related * stuff. */ if (mbPtr->textVarName != NULL) { Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, MenuButtonTextVarProc, (ClientData)mbPtr); } if (mbPtr->image != NULL) { Tk_FreeImage(mbPtr->image); } if (mbPtr->normalTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC); } if (mbPtr->activeTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC); } if (mbPtr->gray != None) { Tk_FreeBitmap(mbPtr->display, mbPtr->gray); } if (mbPtr->disabledGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->disabledGC); } Blt_FreeOptions(configSpecs, (char *)mbPtr, mbPtr->display, 0); Blt_Free(mbPtr); } /* *--------------------------------------------------------------------------- * * ConfigureMenuButton -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or * reconfigure) a menubutton widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for mbPtr; old resources get freed, if there * were any. The menubutton is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureMenuButton( Tcl_Interp *interp, /* Used for error reporting. */ MenuButton *mbPtr, /* Information about widget; may or may * not already have values for some fields. */ int objc, /* Number of valid entries in objv. */ Tcl_Obj *const *objv, /* Arguments. */ int flags) /* Flags to pass to Blt_ConfigureWidget. */ { XGCValues gcValues; GC newGC; unsigned long mask; int result; Tk_Image image; /* * Eliminate any existing trace on variables monitored by the menubutton. */ if (mbPtr->textVarName != NULL) { Tcl_UntraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, MenuButtonTextVarProc, (ClientData)mbPtr); } result = Blt_ConfigureWidgetFromObj(interp, mbPtr->tkwin, configSpecs, objc, objv, (char *)mbPtr, flags); if (result != TCL_OK) { return TCL_ERROR; } /* * A few options need special processing, such as setting the * background from a 3-D border, or filling in complicated * defaults that couldn't be specified to Blt_ConfigureWidget. */ if ((mbPtr->state == STATE_ACTIVE) && !Tk_StrictMotif(mbPtr->tkwin)) { Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->activeBorder); } else { Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->normalBorder); if ((mbPtr->state != STATE_NORMAL) && (mbPtr->state != STATE_ACTIVE) && (mbPtr->state != STATE_DISABLED)) { Tcl_AppendResult(interp, "bad state value \"", Blt_Itoa(mbPtr->state), "\": must be normal, active, or disabled", (char *)NULL); mbPtr->state = STATE_NORMAL; return TCL_ERROR; } } if (mbPtr->highlightWidth < 0) { mbPtr->highlightWidth = 0; } gcValues.font = mbPtr->fontPtr->fid; gcValues.foreground = mbPtr->normalFg->pixel; gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel; /* * Note: GraphicsExpose events are disabled in GC's because they're * used to copy stuff from an off-screen pixmap onto the screen (we know * that there's no problem with obscured areas). */ gcValues.graphics_exposures = False; newGC = Tk_GetGC(mbPtr->tkwin, GCForeground | GCBackground | GCFont | GCGraphicsExposures, &gcValues); if (mbPtr->normalTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC); } mbPtr->normalTextGC = newGC; gcValues.font = mbPtr->fontPtr->fid; gcValues.foreground = mbPtr->activeFg->pixel; gcValues.background = Tk_3DBorderColor(mbPtr->activeBorder)->pixel; newGC = Tk_GetGC(mbPtr->tkwin, GCForeground | GCBackground | GCFont, &gcValues); if (mbPtr->activeTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC); } mbPtr->activeTextGC = newGC; gcValues.font = mbPtr->fontPtr->fid; gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel; if ((mbPtr->disabledFg != NULL) && (mbPtr->imageString == NULL)) { gcValues.foreground = mbPtr->disabledFg->pixel; mask = GCForeground | GCBackground | GCFont; } else { gcValues.foreground = gcValues.background; if (mbPtr->gray == None) { mbPtr->gray = Tk_GetBitmap(interp, mbPtr->tkwin, Tk_GetUid("gray50")); if (mbPtr->gray == None) { return TCL_ERROR; } } gcValues.fill_style = FillStippled; gcValues.stipple = mbPtr->gray; mask = GCForeground | GCFillStyle | GCStipple; } newGC = Tk_GetGC(mbPtr->tkwin, mask, &gcValues); if (mbPtr->disabledGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->disabledGC); } mbPtr->disabledGC = newGC; if (mbPtr->xPad < 0) { mbPtr->xPad = 0; } if (mbPtr->yPad < 0) { mbPtr->yPad = 0; } /* * Get the image for the widget, if there is one. Allocate the * new image before freeing the old one, so that the reference * count doesn't go to zero and cause image data to be discarded. */ if (mbPtr->imageString != NULL) { image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin, mbPtr->imageString, MenuButtonImageProc, (ClientData)mbPtr); if (image == NULL) { return TCL_ERROR; } } else { image = NULL; } if (mbPtr->image != NULL) { Tk_FreeImage(mbPtr->image); } mbPtr->image = image; if ((mbPtr->image == NULL) && (mbPtr->bitmap == None) && (mbPtr->textVarName != NULL)) { /* * The menubutton displays a variable. Set up a trace to watch * for any changes in it. */ char *value; value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); if (value == NULL) { Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, TCL_GLOBAL_ONLY); } else { if (mbPtr->text != NULL) { Blt_Free(mbPtr->text); } mbPtr->text = Blt_StrdupAsset(value); } Tcl_TraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, MenuButtonTextVarProc, (ClientData)mbPtr); } /* * Recompute the geometry for the button. */ if ((mbPtr->bitmap != None) || (mbPtr->image != NULL)) { if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->widthString, &mbPtr->width) != TCL_OK) { widthError: Tcl_AddErrorInfo(interp, "\n (processing -width option)"); return TCL_ERROR; } if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->heightString, &mbPtr->height) != TCL_OK) { heightError: Tcl_AddErrorInfo(interp, "\n (processing -height option)"); return TCL_ERROR; } } else { if (Tcl_GetInt(interp, mbPtr->widthString, &mbPtr->width) != TCL_OK) { goto widthError; } if (Tcl_GetInt(interp, mbPtr->heightString, &mbPtr->height) != TCL_OK) { goto heightError; } } ComputeMenuButtonGeometry(mbPtr); /* * Lastly, arrange for the button to be redisplayed. */ if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayMenuButton, (ClientData)mbPtr); mbPtr->flags |= REDRAW_PENDING; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DisplayMenuButton -- * * This procedure is invoked to display a menubutton widget. * * Results: * None. * * Side effects: * Commands are output to X to display the menubutton in its * current mode. * *--------------------------------------------------------------------------- */ static void DisplayMenuButton(ClientData clientData) /* Information about widget. */ { register MenuButton *mbPtr = clientData; GC gc; Tk_3DBorder border; Pixmap pixmap; int x = 0; /* Initialization needed only to stop * compiler warning. */ int y; register Tk_Window tkwin = mbPtr->tkwin; int width, height; mbPtr->flags &= ~REDRAW_PENDING; if ((mbPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } if ((mbPtr->state == STATE_DISABLED) && (mbPtr->disabledFg != NULL)) { gc = mbPtr->disabledGC; border = mbPtr->normalBorder; } else if ((mbPtr->state == STATE_ACTIVE) && !Tk_StrictMotif(mbPtr->tkwin)) { gc = mbPtr->activeTextGC; border = mbPtr->activeBorder; } else { gc = mbPtr->normalTextGC; border = mbPtr->normalBorder; } /* * In order to avoid screen flashes, this procedure redraws * the menu button in a pixmap, then copies the pixmap to the * screen in a single operation. This means that there's no * point in time where the on-sreen image has been cleared. */ pixmap = Tk_GetPixmap(mbPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); Blt_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); /* * Display image or bitmap or text for button. */ if (mbPtr->image != None) { Tk_SizeOfImage(mbPtr->image, &width, &height); imageOrBitmap: switch (mbPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: x += mbPtr->inset; break; case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S: x += ((int)(Tk_Width(tkwin) - width - mbPtr->indicatorWidth)) / 2; break; default: x += Tk_Width(tkwin) - mbPtr->inset - width - mbPtr->indicatorWidth; break; } switch (mbPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE: y = mbPtr->inset; break; case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E: y = ((int)(Tk_Height(tkwin) - height)) / 2; break; default: y = Tk_Height(tkwin) - mbPtr->inset - height; break; } if (mbPtr->image != NULL) { Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap, x, y); } else { XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap, gc, 0, 0, (unsigned)width, (unsigned)height, x, y, 1); } } else if (mbPtr->bitmap != None) { Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height); goto imageOrBitmap; } else { width = mbPtr->textWidth; height = mbPtr->textHeight; switch (mbPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW: x = mbPtr->inset + mbPtr->xPad; break; case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S: x = ((int)(Tk_Width(tkwin) - width - mbPtr->indicatorWidth)) / 2; break; default: x = Tk_Width(tkwin) - width - mbPtr->xPad - mbPtr->inset - mbPtr->indicatorWidth; break; } switch (mbPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE: y = mbPtr->inset + mbPtr->yPad; break; case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E: y = ((int)(Tk_Height(tkwin) - height)) / 2; break; default: y = Tk_Height(tkwin) - mbPtr->inset - mbPtr->yPad - height; break; } TkDisplayText(mbPtr->display, pixmap, mbPtr->fontPtr, mbPtr->text, mbPtr->numChars, x, y, mbPtr->textWidth, mbPtr->justify, mbPtr->underline, gc); } /* * If the menu button is disabled with a stipple rather than a special * foreground color, generate the stippled effect. */ if ((mbPtr->state == STATE_DISABLED) && ((mbPtr->disabledFg == NULL) || (mbPtr->image != NULL))) { XFillRectangle(mbPtr->display, pixmap, mbPtr->disabledGC, mbPtr->inset, mbPtr->inset, (unsigned)(Tk_Width(tkwin) - 2 * mbPtr->inset), (unsigned)(Tk_Height(tkwin) - 2 * mbPtr->inset)); } /* * Draw the cascade indicator for the menu button on the * right side of the window, if desired. */ if (mbPtr->indicatorOn) { int borderWidth; borderWidth = (mbPtr->indicatorHeight + 1) / 3; if (borderWidth < 1) { borderWidth = 1; } Blt_Fill3DRectangle(tkwin, pixmap, border, Tk_Width(tkwin) - mbPtr->inset - mbPtr->indicatorWidth + mbPtr->indicatorHeight, y + ((int)(height - mbPtr->indicatorHeight)) / 2, mbPtr->indicatorWidth - 2 * mbPtr->indicatorHeight, mbPtr->indicatorHeight, borderWidth, TK_RELIEF_RAISED); } /* * Draw the border and traversal highlight last. This way, if the * menu button's contents overflow onto the border they'll be covered * up by the border. */ if (mbPtr->relief != TK_RELIEF_FLAT) { Blt_Draw3DRectangle(tkwin, pixmap, border, mbPtr->highlightWidth, mbPtr->highlightWidth, Tk_Width(tkwin) - 2 * mbPtr->highlightWidth, Tk_Height(tkwin) - 2 * mbPtr->highlightWidth, mbPtr->borderWidth, mbPtr->relief); } if (mbPtr->highlightWidth != 0) { GC gc; if (mbPtr->flags & GOT_FOCUS) { gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap); } else { gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap); } Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap); } /* * Copy the information from the off-screen pixmap onto the screen, * then delete the pixmap. */ XCopyArea(mbPtr->display, pixmap, Tk_WindowId(tkwin), mbPtr->normalTextGC, 0, 0, (unsigned)Tk_Width(tkwin), (unsigned)Tk_Height(tkwin), 0, 0); Tk_FreePixmap(mbPtr->display, pixmap); } /* *--------------------------------------------------------------------------- * * MenuButtonEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on buttons. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void MenuButtonEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { MenuButton *mbPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; } else if (eventPtr->type == ConfigureNotify) { /* * Must redraw after size changes, since layout could have changed * and borders will need to be redrawn. */ goto redraw; } else if (eventPtr->type == DestroyNotify) { if (mbPtr->tkwin != NULL) { mbPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd); } if (mbPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayMenuButton, (ClientData)mbPtr); } Tcl_EventuallyFree((ClientData)mbPtr, DestroyMenuButton); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { mbPtr->flags |= GOT_FOCUS; if (mbPtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == FocusOut) { if (eventPtr->xfocus.detail != NotifyInferior) { mbPtr->flags &= ~GOT_FOCUS; if (mbPtr->highlightWidth > 0) { goto redraw; } } } return; redraw: if ((mbPtr->tkwin != NULL) && !(mbPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayMenuButton, (ClientData)mbPtr); mbPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * MenuButtonCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void MenuButtonCmdDeletedProc(ClientData clientData) /* Pointer to widget record for widget. */ { MenuButton *mbPtr = clientData; Tk_Window tkwin = mbPtr->tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tkwin != NULL) { mbPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ComputeMenuButtonGeometry -- * * After changes in a menu button's text or bitmap, this procedure * recomputes the menu button's geometry and passes this information * along to the geometry manager for the window. * * Results: * None. * * Side effects: * The menu button's window may change size. * *--------------------------------------------------------------------------- */ static void ComputeMenuButtonGeometry(MenuButton *mbPtr) { int width, height, mm, pixels; mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth; if (mbPtr->image != None) { Tk_SizeOfImage(mbPtr->image, &width, &height); if (mbPtr->width > 0) { width = mbPtr->width; } if (mbPtr->height > 0) { height = mbPtr->height; } } else if (mbPtr->bitmap != None) { Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height); if (mbPtr->width > 0) { width = mbPtr->width; } if (mbPtr->height > 0) { height = mbPtr->height; } } else { mbPtr->numChars = strlen(mbPtr->text); TkComputeTextGeometry(mbPtr->fontPtr, mbPtr->text, mbPtr->numChars, mbPtr->wrapLength, &mbPtr->textWidth, &mbPtr->textHeight); width = mbPtr->textWidth; height = mbPtr->textHeight; if (mbPtr->width > 0) { width = mbPtr->width * XTextWidth(mbPtr->fontPtr, "0", 1); } if (mbPtr->height > 0) { height = mbPtr->height * (mbPtr->fontPtr->ascent + mbPtr->fontPtr->descent); } width += 2 * mbPtr->xPad; height += 2 * mbPtr->yPad; } if (mbPtr->indicatorOn) { mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); mbPtr->indicatorHeight = (INDICATOR_HEIGHT * pixels) / (10 * mm); mbPtr->indicatorWidth = (INDICATOR_WIDTH * pixels) / (10 * mm) + 2 * mbPtr->indicatorHeight; width += mbPtr->indicatorWidth; } else { mbPtr->indicatorHeight = 0; mbPtr->indicatorWidth = 0; } Tk_GeometryRequest(mbPtr->tkwin, (int)(width + 2 * mbPtr->inset), (int)(height + 2 * mbPtr->inset)); Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset); } /* *--------------------------------------------------------------------------- * * MenuButtonTextVarProc -- * * This procedure is invoked when someone changes the variable * whose contents are to be displayed in a menu button. * * Results: * NULL is always returned. * * Side effects: * The text displayed in the menu button will change to match the * variable. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static char * MenuButtonTextVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ char *name1, /* Name of variable. */ char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { register MenuButton *mbPtr = clientData; char *value; /* * If the variable is unset, then immediately recreate it unless * the whole interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, MenuButtonTextVarProc, clientData); } return (char *) NULL; } value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } if (mbPtr->text != NULL) { Blt_Free(mbPtr->text); } mbPtr->text = Blt_AssertStrdup(value); ComputeMenuButtonGeometry(mbPtr); if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayMenuButton, (ClientData)mbPtr); mbPtr->flags |= REDRAW_PENDING; } return (char *) NULL; } /* *--------------------------------------------------------------------------- * * MenuButtonImageProc -- * * This procedure is invoked by the image code whenever the manager * for an image does something that affects the size of contents * of an image displayed in a button. * * Results: * None. * * Side effects: * Arranges for the button to get redisplayed. * *--------------------------------------------------------------------------- */ static void MenuButtonImageProc( ClientData clientData, /* Pointer to widget record. */ int x, int y, /* Upper left pixel (within image) * that must be redisplayed. */ int width, int height, /* Dimensions of area to redisplay * (may be <= 0). */ int imgWidth, int imgHeight) /* New dimensions of image. */ { register MenuButton *mbPtr = clientData; if (mbPtr->tkwin != NULL) { ComputeMenuButtonGeometry(mbPtr); if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayMenuButton, (ClientData)mbPtr); mbPtr->flags |= REDRAW_PENDING; } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictCmd.c������������������������������������������������������������������0000644�0001750�0001750�00000375240�11500247353�015237� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictCmd.c -- * * This module implements the Tk image interface for picture images. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include <bltHash.h> #include <bltImage.h> #include <bltDBuffer.h> #include "bltSwitch.h" #include "bltPicture.h" #include "bltPictInt.h" #include "bltPictFmts.h" #include "bltPainter.h" #include "bltPs.h" #include <X11/Xutil.h> #include <sys/types.h> #include <sys/stat.h> typedef struct _Blt_DBuffer DBuffer; typedef int (PictCmdProc)(Blt_Picture picture, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #if (_TCL_VERSION < _VERSION(8,2,0)) typedef struct _Tk_PostscriptInfo *Tk_PostscriptInfo; #endif /* * PictureCmdInterpData -- * * Structure containing global data, used on a interpreter by interpreter * basis. * * This structure holds the hash table of instances of datatable commands * associated with a particular interpreter. */ typedef struct { Tcl_Interp *interp; } PictureCmdInterpData; /* * Various external file/string formats handled by the picture image. */ enum PictureFormats { FMT_JPG, /* Joint Photographic Experts Group r/w */ FMT_PNG, /* Portable Network Graphics r/w */ FMT_TIF, /* Tagged Image File Format r/w */ FMT_XPM, /* X Pixmap r/w */ FMT_XBM, /* X Bitmap r/w */ FMT_GIF, /* Graphics Interchange Format r/w */ FMT_PS, /* PostScript r/w */ FMT_PDF, /* Portable Document Format r/TBA */ FMT_BMP, /* Device-independent bitmap r/w */ FMT_PBM, /* Portable Bitmap Format r/w */ #ifdef WIN32 FMT_EMF, /* Enhanced Metafile Format r/w (Windows only) TBA */ FMT_WMF, /* Windows Metafile Format r/w (Windows only) TBA */ #endif FMT_PHO, /* Tk Photo Image r/w */ NUMFMTS }; typedef struct { const char *name; /* Name of format. */ unsigned int flags; Blt_PictureIsFmtProc *isFmtProc; Blt_PictureReadDataProc *readProc; /* Used for -file and -data * configuration options. */ Blt_PictureWriteDataProc *writeProc; /* Used for cget -data. */ Blt_PictureImportProc *importProc; Blt_PictureExportProc *exportProc; } PictFormat; static PictFormat pictFormats[] = { { "jpg" }, { "png" }, { "tif" }, /* Multi-page */ { "xpm" }, { "xbm" }, { "gif" }, /* Multi-page */ { "ps" }, /* Multi-page */ { "pdf" }, /* Not implemented yet. */ { "photo" }, { "bmp" }, { "pbm" }, /* Multi-page */ #ifdef WIN32 { "emf" }, { "wmf" }, #endif }; static Blt_HashTable fmtTable; /* * Default configuration options for picture images. */ #define DEF_ANGLE "0.0" #define DEF_MAXPECT "0" #define DEF_AUTOSCALE "0" #define DEF_CACHE "0" #define DEF_DITHER "0" #define DEF_DATA (char *)NULL #define DEF_FILE (char *)NULL #define DEF_FILTER (char *)NULL #define DEF_GAMMA "1.0" #define DEF_HEIGHT "0" #define DEF_WIDTH "0" #define DEF_WINDOW (char *)NULL #define DEF_IMAGE (char *)NULL #define DEF_SHARPEN "no" #define DEF_OPAQUE "0" #define DEF_OPAQUE_BACKGROUND "white" #define IMPORTED_NONE 0 #define IMPORTED_FILE (1<<0) #define IMPORTED_IMAGE (1<<1) #define IMPORTED_WINDOW (1<<2) #define IMPORTED_DATA (1<<3) #define IMPORTED_MASK \ (IMPORTED_FILE|IMPORTED_IMAGE|IMPORTED_WINDOW|IMPORTED_DATA) #define NOTIFY_PENDING (1<<8) /* * A PictImage implements a Tk_ImageMaster for the "picture" image type. It * represents a set of bits (i.e. the picture), some options, and operations * (sub-commands) to manipulate the picture. * * The PictImage manages the TCL interface to a picture (using Tk's "image" * command). Pictures and the mechanics of drawing the picture to the display * (painters) are orthogonal. The PictImage knows nothing about the display * type (the display is stored only to free options when it's destroyed). * Information specific to the visual context (combination of display, visual, * depth, colormap, and gamma) is stored in each cache entry. The picture * image manages the various picture transformations: reading, writing, * scaling, rotation, etc. */ typedef struct _Blt_PictureImage { Tk_ImageMaster imgToken; /* Tk's token for image master. If * NULL, the image has been deleted. */ Tcl_Interp *interp; /* Interpreter associated with the * application using this image. */ Display *display; /* Display associated with this picture * image. This is used to free the * configuration options. */ Colormap colormap; Tcl_Command cmdToken; /* Token for image command (used to * delete the command when the image * goes away). NULL means the image * command has already been deleted. */ unsigned int flags; /* Various bit-field flags defined * below. */ Blt_Chain chain; /* List of pictures. (multi-page * formats) */ Blt_Picture picture; /* Current picture displayed. */ /* User-requested options. */ float angle; /* Angle in degrees to rotate the * image. */ int reqWidth, reqHeight; /* User-requested size of picture. The * picture is scaled accordingly. These * dimensions may or may not be used, * depending * upon the -maxpect * option. */ int maxpect; /* If non-zero, indicates to maintain * the aspect ratio while scaling. The * larger dimension is discarded. */ int dither; /* If non-zero, dither the picture * before drawing. */ int sharpen; /* If non-zero, indicates to sharpen the * image. */ int autoscale; /* Automatically scale the picture * from a saved original picture when * the size of the picture changes. */ Blt_Picture original; Blt_ResampleFilter filter; /* 1D Filter to use when the picture is * resampled (resized). The same filter * is applied both horizontally and * vertically. */ float gamma; /* Gamma correction value of the * monitor. In theory, the same picture * image may be displayed on two * monitors simultaneously (using * xinerama). Here we're assuming * (almost certainly wrong) that both * monitors will have the same gamma * value. */ const char *name; /* Name of the image, file, or window * read into the picture image. */ unsigned int index; /* Index of the picture in the above * list. */ Tcl_TimerToken timerToken; /* Token for timer handler which polls * for the exit status of each * sub-process. If zero, there's no * timer handler queued. */ int interval; PictFormat *fmtPtr; /* External format of last image read * into the picture image. We use this * to write back the same format if the * user doesn't specify the format. */ int doCache; /* If non-zero, indicates to generate a * pixmap of the picture. The pixmap is * cached * in the table below. */ Blt_HashTable cacheTable; /* Table of cache entries specific to * each visual context where this * picture is displayed. */ } PictImage; /* * A PictCacheKey represents the visual context of a cache entry. type. It * contains information specific to the visual context (combination of display, * visual, depth, colormap, and gamma). It is used as a hash table key for * cache entries of picture images. The same picture may be displayed in more * than one visual context. */ typedef struct { Display *display; /* Display where the picture will be * drawn. Used to free colors allocated * by the painter. */ Visual *visualPtr; /* Visual information of window * displaying the image. */ Colormap colormap; /* Colormap used. This may be the * default colormap, or an allocated * private map. */ int depth; /* Depth of the display. */ unsigned int index; /* Index of the picture in the list. */ float gamma; /* Gamma correction value */ } PictCacheKey; /* * PictInstances (image instances in the Tk parlance) represent a picture * image in some specific combination of visual, display, colormap, depth, and * output gamma. Cache entries are stored by each picture image. * * The purpose is to 1) allocate and hold the painter-specific to the visual * and 2) provide caching of XImage's (drawn pictures) into pixmaps. This * feature is enabled only for 100% opaque pictures. If the picture must be * blended with the current background, there is no guarantee (between * redraws) that the background will not have changed. This feature is widget * specific. There's no simple way to detect when the pixmap must be redrawn. * In general, we should rely on the widget itself to perform its own caching * of complex scenes. */ typedef struct { Blt_PictureImage image; /* The picture image represented by this * entry. */ Blt_Painter painter; /* The painter allocated for this * particular combination of visual, * display, colormap, depth, and * gamma. */ Display *display; /* Used to free the pixmap below when * the entry is destroyed. */ Blt_HashEntry *hashPtr; /* These two fields allow the cache */ Blt_HashTable *tablePtr; /* entry to be deleted from the picture * image's table of entries. */ Pixmap pixmap; /* If non-NULL, is a cached pixmap of * the picture. It's recreated each time * the * picture changes. */ int refCount; /* This entry may be shared by all * clients displaying this picture image * with the same painter. */ unsigned int flags; } PictInstance; static Blt_OptionParseProc ObjToFile; static Blt_OptionPrintProc FileToObj; static Blt_CustomOption fileOption = { ObjToFile, FileToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToData; static Blt_OptionPrintProc DataToObj; static Blt_CustomOption dataOption = { ObjToData, DataToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToFilter; static Blt_OptionPrintProc FilterToObj; Blt_CustomOption bltFilterOption = { ObjToFilter, FilterToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToImage; static Blt_OptionPrintProc ImageToObj; static Blt_CustomOption imageOption = { ObjToImage, ImageToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToWindow; static Blt_OptionPrintProc WindowToObj; static Blt_CustomOption windowOption = { ObjToWindow, WindowToObj, NULL, (ClientData)0 }; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BOOLEAN, "-autoscale", (char *)NULL, (char *)NULL, DEF_AUTOSCALE, Blt_Offset(PictImage, autoscale), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-data", (char *)NULL, (char *)NULL, DEF_DATA, Blt_Offset(PictImage, picture), 0, &dataOption}, {BLT_CONFIG_BOOLEAN, "-dither", (char *)NULL, (char *)NULL, DEF_DITHER, Blt_Offset(PictImage, dither), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-file", (char *)NULL, (char *)NULL, DEF_DATA, Blt_Offset(PictImage, picture), 0, &fileOption}, {BLT_CONFIG_CUSTOM, "-filter", (char *)NULL, (char *)NULL, DEF_FILTER, Blt_Offset(PictImage, filter), 0, &bltFilterOption}, {BLT_CONFIG_FLOAT, "-gamma", (char *)NULL, (char *)NULL, DEF_GAMMA, Blt_Offset(PictImage, gamma), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-height", (char *)NULL, (char *)NULL, DEF_HEIGHT, Blt_Offset(PictImage, reqHeight), 0}, {BLT_CONFIG_CUSTOM, "-image", (char *)NULL, (char *)NULL, DEF_IMAGE, Blt_Offset(PictImage, picture), 0, &imageOption}, {BLT_CONFIG_BOOLEAN, "-maxpect", (char *)NULL, (char *)NULL, DEF_MAXPECT, Blt_Offset(PictImage, maxpect),BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-rotate", (char *)NULL, (char *)NULL, DEF_ANGLE, Blt_Offset(PictImage, angle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-sharpen", (char *)NULL, (char *)NULL, DEF_SHARPEN, Blt_Offset(PictImage, sharpen), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-width", (char *)NULL, (char *)NULL, DEF_WIDTH, Blt_Offset(PictImage, reqWidth), 0}, {BLT_CONFIG_CUSTOM, "-window", (char *)NULL, (char *)NULL, DEF_WINDOW, Blt_Offset(PictImage, picture), 0, &windowOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc BBoxSwitch; static Blt_SwitchCustom bboxSwitch = { BBoxSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc FilterSwitch; static Blt_SwitchCustom filterSwitch = { FilterSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc BlendingModeSwitch; static Blt_SwitchCustom blendModeSwitch = { BlendingModeSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc ShapeSwitch; static Blt_SwitchCustom shapeSwitch = { ShapeSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc PathSwitch; static Blt_SwitchCustom pathSwitch = { PathSwitch, NULL, (ClientData)0, }; typedef struct { Blt_Pixel bg, fg; /* Fg and bg colors. */ Blt_Gradient gradient; } GradientSwitches; static Blt_SwitchSpec gradientSwitches[] = { {BLT_SWITCH_CUSTOM, "-direction", "direction", Blt_Offset(GradientSwitches, gradient.path), 0, 0, &pathSwitch}, {BLT_SWITCH_CUSTOM, "-shape", "shape", Blt_Offset(GradientSwitches, gradient.shape), 0, 0, &shapeSwitch}, {BLT_SWITCH_CUSTOM, "-high", "color", Blt_Offset(GradientSwitches, fg), 0, 0, &colorSwitch}, {BLT_SWITCH_CUSTOM, "-low", "color", Blt_Offset(GradientSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_BOOLEAN,"-logscale", "bool", Blt_Offset(GradientSwitches, gradient.logScale), 0}, {BLT_SWITCH_BOOLEAN, "-jitter", "bool", Blt_Offset(GradientSwitches, gradient.jitter), 0}, {BLT_SWITCH_END} }; typedef struct { PictRegion region; /* Area to tile. */ int xOrigin; int yOrigin; } TileSwitches; static Blt_SwitchSpec tileSwitches[] = { {BLT_SWITCH_CUSTOM, "-region", "bbox", Blt_Offset(TileSwitches, region), 0, 0, &bboxSwitch}, {BLT_SWITCH_INT, "-xorigin", "x", Blt_Offset(TileSwitches, xOrigin), 0}, {BLT_SWITCH_INT, "-yorigin", "y", Blt_Offset(TileSwitches, yOrigin), 0}, {BLT_SWITCH_END} }; typedef struct { int invert; /* Flag. */ Tcl_Obj *maskObjPtr; } ArithSwitches; static Blt_SwitchSpec arithSwitches[] = { {BLT_SWITCH_OBJ, "-mask", "mask", Blt_Offset(ArithSwitches, maskObjPtr), 0}, {BLT_SWITCH_BOOLEAN, "-invert", "bool", Blt_Offset(ArithSwitches, invert), 0}, {BLT_SWITCH_END} }; typedef struct { PictRegion region; /* Area to crop. */ int nocopy; /* If non-zero, don't copy the source * image. */ } DupSwitches; #define DUP_NOCOPY 1 static Blt_SwitchSpec dupSwitches[] = { {BLT_SWITCH_BITMASK,"-nocopy", "", Blt_Offset(DupSwitches, nocopy), 0, DUP_NOCOPY}, {BLT_SWITCH_CUSTOM, "-region", "bbox", Blt_Offset(DupSwitches, region), 0, 0, &bboxSwitch}, {BLT_SWITCH_END} }; typedef struct { PictRegion from, to; Blt_BlendingMode mode; /* Blending mode. */ } BlendSwitches; static Blt_SwitchSpec blendSwitches[] = { {BLT_SWITCH_CUSTOM, "-mode", "blendingmode", Blt_Offset(BlendSwitches, mode), 0, 0, &blendModeSwitch}, {BLT_SWITCH_CUSTOM, "-from", "bbox", Blt_Offset(BlendSwitches,from), 0, 0, &bboxSwitch}, {BLT_SWITCH_CUSTOM, "-to", "bbox", Blt_Offset(BlendSwitches, to), 0, 0, &bboxSwitch}, {BLT_SWITCH_END} }; typedef struct { Blt_ResampleFilter vFilter; /* Color of rectangle. */ Blt_ResampleFilter hFilter; /* Width of outline. */ Blt_ResampleFilter filter; } ConvolveSwitches; static Blt_SwitchSpec convolveSwitches[] = { {BLT_SWITCH_CUSTOM, "-filter", "filter", Blt_Offset(ConvolveSwitches, filter), 0, 0, &filterSwitch}, {BLT_SWITCH_CUSTOM, "-hfilter", "filter", Blt_Offset(ConvolveSwitches, hFilter), 0, 0, &filterSwitch}, {BLT_SWITCH_CUSTOM, "-vfilter", "filter", Blt_Offset(ConvolveSwitches, vFilter), 0, 0, &filterSwitch}, {BLT_SWITCH_END} }; typedef struct { PictRegion from, to; int blend; } CopySwitches; static Blt_SwitchSpec copySwitches[] = { {BLT_SWITCH_BOOLEAN,"-blend", "", Blt_Offset(CopySwitches, blend), 0, 0}, {BLT_SWITCH_CUSTOM, "-from", "bbox", Blt_Offset(CopySwitches,from), 0, 0, &bboxSwitch}, {BLT_SWITCH_CUSTOM, "-to", "bbox", Blt_Offset(CopySwitches, to), 0, 0, &bboxSwitch}, {BLT_SWITCH_END} }; typedef struct { Blt_ResampleFilter filter; PictRegion region; int width, height; } ResampleSwitches; static Blt_SwitchSpec resampleSwitches[] = { {BLT_SWITCH_CUSTOM, "-filter", "filter", Blt_Offset(ResampleSwitches, filter), 0, 0, &filterSwitch}, {BLT_SWITCH_CUSTOM, "-from", "bbox", Blt_Offset(ResampleSwitches, region), 0, 0, &bboxSwitch}, {BLT_SWITCH_INT, "-width", "int", Blt_Offset(ResampleSwitches, width), 0}, {BLT_SWITCH_INT, "-height", "int", Blt_Offset(ResampleSwitches, height), 0}, {BLT_SWITCH_END} }; typedef struct { PictRegion region; int raise; } SnapSwitches; static Blt_SwitchSpec snapSwitches[] = { {BLT_SWITCH_CUSTOM, "-region", "bbox", Blt_Offset(SnapSwitches, region), 0, 0, &bboxSwitch}, {BLT_SWITCH_BITMASK, "-raise", "", Blt_Offset(SnapSwitches, raise), 0, TRUE}, {BLT_SWITCH_END} }; /* * Forward references for TCL command callbacks used below. */ static Tcl_ObjCmdProc PictureInstCmdProc; static Tcl_CmdDeleteProc PictureInstCmdDeletedProc; Blt_Picture Blt_GetNthPicture(Blt_Chain chain, size_t index) { Blt_ChainLink link; link = Blt_Chain_GetNthLink(chain, index); if (link == NULL) { return NULL; } return Blt_Chain_GetValue(link); } static Blt_Picture PictureFromPictImage(PictImage *imgPtr) { imgPtr->picture = Blt_GetNthPicture(imgPtr->chain, imgPtr->index); return imgPtr->picture; } static void ReplacePicture(PictImage *imgPtr, Blt_Picture picture) { Blt_ChainLink link; if (imgPtr->chain == NULL) { imgPtr->chain = Blt_Chain_Create(); } link = Blt_Chain_GetNthLink(imgPtr->chain, imgPtr->index); if (link == NULL) { int n; n = Blt_Chain_GetLength(imgPtr->chain); link = Blt_Chain_Append(imgPtr->chain, picture); imgPtr->index = n; } else { Blt_Picture old; old = Blt_Chain_GetValue(link); Blt_FreePicture(old); } Blt_Chain_SetValue(link, picture); imgPtr->picture = picture; } static void FreePictures(PictImage *imgPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(imgPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Blt_Picture picture; picture = Blt_Chain_GetValue(link); Blt_FreePicture(picture); } Blt_Chain_Destroy(imgPtr->chain); imgPtr->chain = NULL; imgPtr->index = 0; imgPtr->picture = NULL; } Blt_Picture Blt_GetPictureFromPictureImage(Tcl_Interp *interp, Tk_Image tkImage) { PictInstance *instancePtr; if (!Blt_IsPicture(tkImage)) { Tcl_AppendResult(interp, "image is not a picture", (char *)NULL); return NULL; } instancePtr = Blt_Image_GetInstanceData(tkImage); return PictureFromPictImage(instancePtr->image); } Blt_Picture Blt_GetPictureFromPhotoImage(Tcl_Interp *interp, Tk_Image tkImage) { const char *name; Tk_PhotoHandle photo; name = Blt_Image_Name(tkImage); photo = Tk_FindPhoto(interp, name); if (photo == NULL) { return NULL; } return Blt_PhotoToPicture(photo); } void Blt_NotifyImageChanged(PictImage *imgPtr) { if (imgPtr->picture != NULL) { int w, h; w = Blt_PictureWidth(imgPtr->picture); h = Blt_PictureHeight(imgPtr->picture); Tk_ImageChanged(imgPtr->imgToken, 0, 0, w, h, w, h); } } Blt_Pixel Blt_XColorToPixel(XColor *colorPtr) { Blt_Pixel new; /* Convert X Color with 3 channel, 16-bit components to Blt_Pixel * (8-bit, with alpha component) */ new.Red = colorPtr->red / 257; new.Green = colorPtr->green / 257; new.Blue = colorPtr->blue / 257; new.Alpha = ALPHA_OPAQUE; return new; } int Blt_GetPixel(Tcl_Interp *interp, const char *string, Blt_Pixel *pixelPtr) { int length; length = strlen(string); if ((string[0] == '0') && (string[1] == 'x')) { unsigned int value; char *term; value = strtoul(string + 2, &term, 16); if ((term == (string + 1)) || (*term != '\0')) { Tcl_AppendResult(interp, "expected color value but got \"", string, "\"", (char *) NULL); return TCL_ERROR; } pixelPtr->u32 = value; } else { XColor color; Tk_Window tkwin; tkwin = Tk_MainWindow(interp); if (!XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), string, &color)) { Tcl_AppendResult(interp, "unknown color name \"", string, "\"", (char *) NULL); return TCL_ERROR; } *pixelPtr = Blt_XColorToPixel(&color); } return TCL_OK; } int Blt_GetPixelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Pixel *pixelPtr) { return Blt_GetPixel(interp, Tcl_GetString(objPtr), pixelPtr); } const char * Blt_NameOfPixel(Blt_Pixel *pixelPtr) { static char string[10]; sprintf_s(string, 10, "%02x%02x%02x%02x", pixelPtr->Alpha, pixelPtr->Red, pixelPtr->Green, pixelPtr->Blue); return string; } int Blt_GetBBoxFromObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, PictRegion *regionPtr) { double left, top, right, bottom; if ((objc != 2) && (objc != 4)) { Tcl_AppendResult(interp, "wrong # elements in bounding box ", (char *)NULL); return TCL_ERROR; } regionPtr->x = regionPtr->y = regionPtr->w = regionPtr->h = 0; if ((Tcl_GetDoubleFromObj(interp, objv[0], &left) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[1], &top) != TCL_OK)) { return TCL_ERROR; } if (objc == 2) { regionPtr->x = ROUND(left), regionPtr->y = ROUND(top); return TCL_OK; } if ((Tcl_GetDoubleFromObj(interp, objv[2], &right) != TCL_OK) || (Tcl_GetDoubleFromObj(interp, objv[3], &bottom) != TCL_OK)) { return TCL_ERROR; } /* Flip the coordinates of the bounding box if necessary so that its the * upper-left and lower-right corners */ if (left > right) { double tmp; tmp = left, left = right, right = tmp; } if (top > bottom) { double tmp; tmp = top, top = bottom, bottom = tmp; } top = floor(top), left = floor(left); bottom = ceil(bottom), right = ceil(right); regionPtr->x = (int)left, regionPtr->y = (int)top; regionPtr->w = (int)right - regionPtr->x + 1; regionPtr->h = (int)bottom - regionPtr->y + 1; return TCL_OK; } static int GetBBoxFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, PictRegion *regionPtr) { int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } return Blt_GetBBoxFromObjv(interp, objc, objv, regionPtr); } int Blt_AdjustRegionToPicture(Blt_Picture picture, PictRegion *regionPtr) { int w, h; w = Blt_PictureWidth(picture); h = Blt_PictureHeight(picture); if ((regionPtr->w == 0) || (regionPtr->w > w)) { regionPtr->w = w; } if ((regionPtr->h == 0) || (regionPtr->h > h)) { regionPtr->h = h; } /* Verify that some part of the bounding box is actually inside the * picture. */ if ((regionPtr->x >= w) || ((regionPtr->x + regionPtr->w) <= 0) || (regionPtr->y >= h) || ((regionPtr->y + regionPtr->h) <= 0)) { return FALSE; } /* If needed, adjust the bounding box so that it resides totally inside the * picture */ if (regionPtr->x < 0) { regionPtr->w += regionPtr->x; regionPtr->x = 0; } if (regionPtr->y < 0) { regionPtr->h += regionPtr->y; regionPtr->y = 0; } if ((regionPtr->x + regionPtr->w) > w) { regionPtr->w = w - regionPtr->x; } if ((regionPtr->y + regionPtr->h) > h) { regionPtr->h = h - regionPtr->y; } return TRUE; } int Blt_ResetPicture(Tcl_Interp *interp, const char *imageName, Blt_Picture picture) { Tcl_CmdInfo cmdInfo; if (Tcl_GetCommandInfo(interp, imageName, &cmdInfo)) { if (cmdInfo.objProc == PictureInstCmdProc) { PictImage *imgPtr; imgPtr = cmdInfo.objClientData; if (imgPtr->picture != picture) { ReplacePicture(imgPtr, picture); } Blt_NotifyImageChanged(imgPtr); return TCL_OK; } } Tcl_AppendResult(interp, "can't find picture \"", imageName, "\"", (char *)NULL); return TCL_ERROR; } #ifdef notdef int Blt_ResetPictureFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Picture picture) { return Blt_ResetPicture(interp, Tcl_GetString(objPtr), picture); } #endif int Blt_GetPicture(Tcl_Interp *interp, const char *string, Blt_Picture *picturePtr) { Tcl_CmdInfo cmdInfo; if (Tcl_GetCommandInfo(interp, string, &cmdInfo)) { if (cmdInfo.objProc == PictureInstCmdProc) { PictImage *imgPtr; imgPtr = cmdInfo.objClientData; *picturePtr = imgPtr->picture; return TCL_OK; } } Tcl_AppendResult(interp, "can't find picture \"", string, "\"", (char *)NULL); return TCL_ERROR; } int Blt_GetPictureFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Picture *pictPtr) { return Blt_GetPicture(interp, Tcl_GetString(objPtr), pictPtr); } static int LoadFormat(Tcl_Interp *interp, const char *name) { Tcl_DString ds; const char *result; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "blt_picture_", 12); Tcl_DStringAppend(&ds, name, -1); strtolower(Tcl_DStringValue(&ds)); #define EXACT 1 result = Tcl_PkgRequire(interp, Tcl_DStringValue(&ds), BLT_VERSION, EXACT); Tcl_DStringFree(&ds); return (result != NULL); } static PictFormat * QueryExternalFormat( Tcl_Interp *interp, /* Interpreter to load new format * into. */ Blt_DBuffer dbuffer, /* Data to be tested. */ const char *ext) /* Extension of file name read in. Will * be NULL if read from data/base64 * string. */ { Blt_HashEntry *hPtr; Blt_HashSearch iter; /* * Step 1. Try to match the format to the extension, if there is * one. We're trying to minimize the number of formats * loaded using a blind query (.i.e. -file fileName). */ if (ext != NULL) { hPtr = Blt_FindHashEntry(&fmtTable, ext); if (hPtr != NULL) { PictFormat *fmtPtr; fmtPtr = Blt_GetHashValue(hPtr); #ifdef notdef fprintf(stderr, "trying %s\n", fmtPtr->name); #endif if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { LoadFormat(interp, ext); } if (((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) || (fmtPtr->isFmtProc == NULL)) { fprintf(stderr, "can't load format %s\n", fmtPtr->name); if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { fprintf(stderr, "not loaded: format %s\n", fmtPtr->name); } else if (fmtPtr->isFmtProc == NULL) { fprintf(stderr, "no isFmtProc: format %s\n", fmtPtr->name); } return NULL; /* Could not load the format or the * format doesn't have a discovery * procedure. */ } if ((*fmtPtr->isFmtProc)(dbuffer)) { return fmtPtr; } #ifdef notdef fprintf(stderr, "failed to match %s\n", fmtPtr->name); #endif /* If the image doesn't match, even though the extension matches, * fall through and try all the other formats available. */ } } /* * Step 2. Try to match the image against all the previously * loaded formats. */ for (hPtr = Blt_FirstHashEntry(&fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { PictFormat *fmtPtr; fmtPtr = Blt_GetHashValue(hPtr); #ifdef notdef fprintf(stderr, "pass2 trying %s\n", fmtPtr->name); #endif if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { continue; /* Format isn't already loaded. */ } if (fmtPtr->isFmtProc == NULL) { continue; /* No discover procedure. */ } if ((*fmtPtr->isFmtProc)(dbuffer)) { return fmtPtr; } } /* * Step 3. Try to match the image against any format not previously loaded. */ for (hPtr = Blt_FirstHashEntry(&fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { PictFormat *fmtPtr; fmtPtr = Blt_GetHashValue(hPtr); #ifdef notdef fprintf(stderr, "pass3 trying %s\n", fmtPtr->name); #endif if (fmtPtr->flags & BLT_PIC_FMT_LOADED) { continue; /* Format is already loaded. */ } if (!LoadFormat(interp, fmtPtr->name)) { continue; /* Can't load format. */ } if (((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) || (fmtPtr->isFmtProc == NULL)) { fprintf(stderr, "can't load format %s\n", fmtPtr->name); if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { fprintf(stderr, "not loaded: format %s\n", fmtPtr->name); } else if (fmtPtr->isFmtProc == NULL) { fprintf(stderr, "no isFmtProc: format %s\n", fmtPtr->name); } return NULL; /* Could not load the format or the * format doesn't have a discovery * procedure. */ } if ((*fmtPtr->isFmtProc)(dbuffer)) { return fmtPtr; } } return NULL; } static int ImageToPicture(Tcl_Interp *interp, PictImage *imgPtr, const char *imageName) { Blt_Picture picture; Tk_PhotoHandle photo; photo = Tk_FindPhoto(interp, imageName); if (photo != NULL) { picture = Blt_PhotoToPicture(photo); } else if (Blt_GetPicture(interp, imageName, &picture) == TCL_OK) { picture = Blt_ClonePicture(picture); } else { return TCL_ERROR; } ReplacePicture(imgPtr, picture); if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } imgPtr->name = Blt_AssertStrdup(imageName); imgPtr->flags &= ~IMPORTED_MASK; imgPtr->flags |= IMPORTED_IMAGE; return TCL_OK; } static int WindowToPicture(Tcl_Interp *interp, PictImage *imgPtr, Tcl_Obj *objPtr) { Blt_Picture picture; Window window; int w, h; if (Blt_GetWindowFromObj(interp, objPtr, &window) != TCL_OK) { return TCL_ERROR; } if (Blt_GetWindowRegion(imgPtr->display, window, (int *)NULL, (int *)NULL, &w, &h) != TCL_OK) { Tcl_AppendResult(interp, "can't get dimensions of window \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } /* Depth, visual, colormap */ picture = Blt_WindowToPicture(imgPtr->display, window, 0, 0, w, h, imgPtr->gamma); if (picture == NULL) { Tcl_AppendResult(interp, "can't obtain snapshot of window \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } ReplacePicture(imgPtr, picture); if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } imgPtr->name = Blt_AssertStrdup(Tcl_GetString(objPtr)); imgPtr->flags &= ~IMPORTED_MASK; imgPtr->flags |= IMPORTED_WINDOW; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToFile -- * * Given a file name, determine the image type and convert into a * picture. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToFile( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Chain chain; Blt_DBuffer dbuffer; Blt_Picture *picturePtr = (Blt_Picture *)(widgRec + offset); Blt_Picture picture; PictImage *imgPtr = (PictImage *)widgRec; const char *fileName; PictFormat *fmtPtr; char *ext; fileName = Tcl_GetString(objPtr); if (fileName[0] == '\0') { FreePictures(imgPtr); if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } imgPtr->fmtPtr = NULL; imgPtr->flags &= ~IMPORTED_MASK; return TCL_OK; } dbuffer = Blt_DBuffer_Create(); if (Blt_DBuffer_LoadFile(interp, fileName, dbuffer) != TCL_OK) { goto error; } ext = NULL; if (fileName[0] != '@') { ext = strrchr(fileName, '.'); if (ext != NULL) { ext++; if (*ext == '\0') { ext = NULL; } strtolower(ext); } } fmtPtr = QueryExternalFormat(interp, dbuffer, ext); if (fmtPtr == NULL) { Tcl_AppendResult(interp, "\nunknown image file format in \"", fileName, "\"", (char *)NULL); goto error; } if (fmtPtr->readProc == NULL) { Tcl_AppendResult(interp, "no reader for format \"", fmtPtr->name, "\".", (char *)NULL); goto error; } chain = (*fmtPtr->readProc)(interp, fileName, dbuffer); if (chain == NULL) { goto error; } FreePictures(imgPtr); imgPtr->chain = chain; imgPtr->index = 0; imgPtr->picture = Blt_Chain_FirstValue(chain); if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } imgPtr->fmtPtr = fmtPtr; imgPtr->name = Blt_AssertStrdup(fileName); imgPtr->flags &= ~IMPORTED_MASK; imgPtr->flags |= IMPORTED_FILE; imgPtr->interval = 0; /* 100 microseconds */ *picturePtr = picture; Blt_DBuffer_Destroy(dbuffer); return TCL_OK; error: Blt_DBuffer_Destroy(dbuffer); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * FileToObj -- * * Convert the picture into a TCL list of pixels. * * Results: * The string representation of the picture is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * FileToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)widgRec; if (((imgPtr->flags & IMPORTED_FILE) == 0) || (imgPtr->name == NULL)) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(imgPtr->name, -1); } /* *--------------------------------------------------------------------------- * * ObjToFilter -- * * Given a string name, get the resample filter associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToFilter( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_ResampleFilter *filterPtr = (Blt_ResampleFilter *)(widgRec + offset); const char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *filterPtr = NULL; return TCL_OK; } return Blt_GetResampleFilterFromObj(interp, objPtr, filterPtr); } /* *--------------------------------------------------------------------------- * * FilterToObj -- * * Convert the picture filter into a string Tcl_Obj. * * Results: * The string representation of the filter is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * FilterToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_ResampleFilter filter = *(Blt_ResampleFilter *)(widgRec + offset); if (filter == NULL) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(Blt_NameOfResampleFilter(filter), -1); } /* *--------------------------------------------------------------------------- * * ObjToData -- * * Given a string of data or binary Tcl_Obj, determine the image * type and convert into a picture. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToData( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_Picture *picturePtr = (Blt_Picture *)(widgRec + offset); PictImage *imgPtr = (PictImage *)widgRec; const unsigned char *bytes; int length, result; bytes = Tcl_GetByteArrayFromObj(objPtr, &length); result = TCL_ERROR; if (length == 0) { imgPtr->flags &= ~IMPORTED_MASK; FreePictures(imgPtr); result = TCL_OK; } else { Blt_DBuffer dbuffer; size_t nBytes; PictFormat *fmtPtr; Blt_Chain chain; nBytes = (size_t)length; dbuffer = Blt_DBuffer_Create(); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, (const char *)bytes, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } #ifdef notdef { FILE *f; f = fopen("junk.unk", "w"); fwrite(Blt_DBuffer_Bytes(dbuffer), 1, Blt_DBuffer_Length(dbuffer), f); fclose(f); } #endif fmtPtr = QueryExternalFormat(interp, dbuffer, NULL); if (fmtPtr == NULL) { Tcl_AppendResult(interp, "unknown image file format in \"", Tcl_GetString(objPtr), "\"", (char *)NULL); goto error; } if (fmtPtr->readProc == NULL) { Tcl_AppendResult(interp, "no reader for format \"", fmtPtr->name, "\".", (char *)NULL); goto error; } chain = (*fmtPtr->readProc)(interp, "-data", dbuffer); if (chain == NULL) { goto error; } result = TCL_OK; error: imgPtr->flags &= ~IMPORTED_MASK; FreePictures(imgPtr); if (result == TCL_OK) { imgPtr->chain = chain; imgPtr->fmtPtr = fmtPtr; imgPtr->picture = Blt_Chain_FirstValue(chain); imgPtr->flags |= IMPORTED_DATA; } Blt_DBuffer_Destroy(dbuffer); } *picturePtr = imgPtr->picture; return result; } /* *--------------------------------------------------------------------------- * * DataToObj -- * * Convert the picture into a TCL list of pixels. * * Results: * The string representation of the picture is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * DataToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)(widgRec); PictFormat *fmtPtr; if (((imgPtr->flags & IMPORTED_DATA) == 0) || (imgPtr->picture == NULL)) { return Tcl_NewStringObj("", -1); } fmtPtr = imgPtr->fmtPtr; if (fmtPtr == NULL) { Tcl_AppendResult(interp, "image \"", imgPtr->name, "\" has no assigned format.", (char *)NULL); Tcl_BackgroundError(interp); return Tcl_NewStringObj("", -1); } if (fmtPtr->writeProc == NULL) { Tcl_AppendResult(interp, "no write procedure for format \"", fmtPtr->name, "\".", (char *)NULL); Tcl_BackgroundError(interp); return Tcl_NewStringObj("", -1); } return (*fmtPtr->writeProc)(interp, imgPtr->picture); } /* *--------------------------------------------------------------------------- * * ObjToImage -- * * Convert a named image into a picture. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToImage( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)(widgRec); return ImageToPicture(interp, imgPtr, Tcl_GetString(objPtr)); } /* *--------------------------------------------------------------------------- * * ImageToObj -- * * Convert the named image into a picture. * * Results: * The string representation of the picture is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ImageToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)widgRec; if (((imgPtr->flags & IMPORTED_IMAGE) == 0) || (imgPtr->name == NULL)) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(imgPtr->name, -1); } /* *--------------------------------------------------------------------------- * * ObjToWindow -- * * Given a file name, determine the image type and convert * into a picture. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToWindow( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)(widgRec); return WindowToPicture(interp, imgPtr, objPtr); } /* *--------------------------------------------------------------------------- * * WindowToObj -- * * Convert the picture into a TCL list of pixels. * * Results: * The string representation of the picture is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * WindowToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Not used. */ int flags) /* Not used. */ { PictImage *imgPtr = (PictImage *)widgRec; if (((imgPtr->flags & IMPORTED_WINDOW) == 0) || (imgPtr->name == NULL)) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(imgPtr->name, -1); } /* *--------------------------------------------------------------------------- * * CacheKey -- * * Returns a key representing a specific visual context for a PictImage. * Keys are used to create/find cache entries stored in the hash table of * each PictImage. * * Results: * A pointer to a static cache key. * * Side effects: * The key is overwritten on each call. Care must be taken by the caller * to save the key before making additional calls. * *--------------------------------------------------------------------------- */ static PictCacheKey * CacheKey(Tk_Window tkwin, unsigned int index) { static PictCacheKey key; key.display = Tk_Display(tkwin); key.visualPtr = Tk_Visual(tkwin); key.colormap = Tk_Colormap(tkwin); key.depth = Tk_Depth(tkwin); key.index = index; return &key; } /* *--------------------------------------------------------------------------- * * DestroyCache -- * * This procedure is a callback for Tcl_EventuallyFree to release the * resources and memory used by a PictInstance entry. The entry is * destroyed only if noone else is currently using the entry (using * reference counting). * * Results: * None. * * Side effects: * The cache entry is possibly deallocated. * *--------------------------------------------------------------------------- */ static void DestroyCache(DestroyData data) { PictInstance *cachePtr = (PictInstance *)data; if (cachePtr->refCount <= 0) { if (cachePtr->pixmap != None) { Tk_FreePixmap(cachePtr->display, cachePtr->pixmap); } if (cachePtr->painter != NULL) { Blt_FreePainter(cachePtr->painter); } if (cachePtr->hashPtr != NULL) { Blt_DeleteHashEntry(cachePtr->tablePtr, cachePtr->hashPtr); } Blt_Free(cachePtr); } } /* *--------------------------------------------------------------------------- * * GetPictInstance -- * * This procedure is called for each use of a picture image in a widget. * * Results: * The return value is an entry for the visual context, which will be * passed back to us on calls to DisplayPictureImage and * FreePictInstance. * * Side effects: * A new entry is possibly allocated (or shared if one already exists). * *--------------------------------------------------------------------------- */ static ClientData GetPictInstance( Tk_Window tkwin, /* Window in which the picture will be * displayed. */ ClientData clientData) /* Pointer to picture image for the * image. */ { Blt_HashEntry *hPtr; PictCacheKey *keyPtr; PictImage *imgPtr = clientData; PictInstance *cachePtr; int isNew; keyPtr = CacheKey(tkwin, imgPtr->index); hPtr = Blt_CreateHashEntry(&imgPtr->cacheTable, (char *)keyPtr, &isNew); if (isNew) { cachePtr = Blt_Malloc(sizeof(PictInstance)); if (cachePtr == NULL) { return NULL; /* Can't allocate memory. */ } cachePtr->painter = Blt_GetPainter(tkwin, imgPtr->gamma); cachePtr->image = imgPtr; cachePtr->display = Tk_Display(tkwin); cachePtr->pixmap = None; cachePtr->hashPtr = hPtr; cachePtr->tablePtr = &imgPtr->cacheTable; cachePtr->refCount = 0; cachePtr->flags = 0; Blt_SetHashValue(hPtr, cachePtr); if (imgPtr->picture != NULL) { Blt_NotifyImageChanged(imgPtr); } } cachePtr = Blt_GetHashValue(hPtr); cachePtr->refCount++; return cachePtr; } /* *--------------------------------------------------------------------------- * * FreePictInstance -- * * This procedure is called when a widget ceases to use a particular * instance of a picture image. We don't actually get rid of the entry * until later because we may be about to re-get this instance again. * * Results: * None. * * Side effects: * Internal data structures get freed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreePictInstance( ClientData clientData, /* Pointer to cache structure */ Display *display) /* Not used. */ { PictInstance *cachePtr = clientData; cachePtr->refCount--; if (cachePtr->refCount <= 0) { /* * Right now no one is using the entry. But delay the removal of the * cache entry in case it's reused shortly afterwards. */ Tcl_EventuallyFree(cachePtr, DestroyCache); } } /* *--------------------------------------------------------------------------- * * DeletePictureImage -- * * This procedure is called by the Tk image code to delete the master * structure (PictureImage) for a picture image. * * Results: * None. * * Side effects: * Resources associated with the picture image are freed. * *--------------------------------------------------------------------------- */ static void DeletePictureImage( ClientData clientData) /* Pointer to picture image master * structure for image. Must not have * any more instances. */ { Blt_HashEntry *hPtr; Blt_HashSearch iter; PictImage *imgPtr = clientData; for (hPtr = Blt_FirstHashEntry(&imgPtr->cacheTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { PictInstance *cachePtr; cachePtr = Blt_GetHashValue(hPtr); cachePtr->hashPtr = NULL; /* Flag for FreePictInstance. */ DestroyCache((DestroyData)cachePtr); } imgPtr->imgToken = NULL; if (imgPtr->cmdToken != NULL) { Tcl_DeleteCommandFromToken(imgPtr->interp, imgPtr->cmdToken); } Blt_DeleteHashTable(&imgPtr->cacheTable); Blt_FreeOptions(configSpecs, (char *)imgPtr, imgPtr->display, 0); if (imgPtr->chain != NULL) { FreePictures(imgPtr); } if (imgPtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(imgPtr->timerToken); imgPtr->timerToken = 0; } Blt_Free(imgPtr); } static int ConfigurePictureImage(Tcl_Interp *interp, PictImage *imgPtr, int objc, Tcl_Obj *const *objv, int flags) { int w, h; if (Blt_ConfigureWidgetFromObj(interp, Tk_MainWindow(interp), configSpecs, objc, objv, (char *)imgPtr, flags) != TCL_OK) { return TCL_ERROR; } imgPtr->picture = PictureFromPictImage(imgPtr); if (imgPtr->picture == NULL) { w = (imgPtr->reqWidth == 0) ? 16 : imgPtr->reqWidth; h = (imgPtr->reqHeight == 0) ? 16 : imgPtr->reqHeight; ReplacePicture(imgPtr, Blt_CreatePicture(w, h)); } if (Blt_ConfigModified(configSpecs, "-autoscale", (char *)NULL)) { if (imgPtr->original != NULL) { Blt_FreePicture(imgPtr->original); imgPtr->original = NULL; } if ((imgPtr->autoscale) && (imgPtr->picture != NULL)) { imgPtr->original = Blt_ClonePicture(imgPtr->picture); } } if (imgPtr->angle != 0.0) { Blt_Picture rotate; /* Rotate the picture */ rotate = Blt_RotatePicture(imgPtr->picture, imgPtr->angle); ReplacePicture(imgPtr, rotate); } w = (imgPtr->reqWidth == 0) ? Blt_PictureWidth(imgPtr->picture) : imgPtr->reqWidth; h = (imgPtr->reqHeight == 0) ? Blt_PictureHeight(imgPtr->picture) : imgPtr->reqHeight; if (imgPtr->maxpect) { double sx, sy, scale; sx = (double)w / (double)Blt_PictureWidth(imgPtr->picture); sy = (double)h / (double)Blt_PictureHeight(imgPtr->picture); scale = MIN(sx, sy); w = (int)(Blt_PictureWidth(imgPtr->picture) * scale + 0.5); h = (int)(Blt_PictureHeight(imgPtr->picture) * scale + 0.5); } if ((Blt_PictureWidth(imgPtr->picture) != w) || (Blt_PictureHeight(imgPtr->picture) != h)) { if (imgPtr->autoscale) { Blt_Picture resize; /* Scale the picture */ if (imgPtr->filter == NULL) { resize = Blt_ScalePicture(imgPtr->original, 0, 0, Blt_PictureWidth(imgPtr->original), Blt_PictureHeight(imgPtr->original), w, h); } else { resize = Blt_CreatePicture(w, h); Blt_ResamplePicture(resize, imgPtr->original, imgPtr->filter, imgPtr->filter); } ReplacePicture(imgPtr, resize); } else { Blt_ResizePicture(imgPtr->picture, w, h); } } if (imgPtr->sharpen > 0) { Blt_SharpenPicture(imgPtr->picture, imgPtr->picture); } Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreatePictureImage -- * * This procedure is called by the Tk image code to create a new picture * image. * * Results: * A standard TCL result. * * Side effects: * The data structure for a new picture image is allocated and initialized. * *--------------------------------------------------------------------------- */ static int CreatePictureImage( Tcl_Interp *interp, /* Interpreter to report errors back * to. */ char *name, /* Name to use for image command. */ int objc, /* # of option arguments. */ Tcl_Obj *const *objv, /* Option arguments (doesn't include * image name or type). */ Tk_ImageType *typePtr, /* Not used. */ Tk_ImageMaster imgToken, /* Token for image, to be used by us in * later callbacks. */ ClientData *clientDataPtr) /* Store manager's token for image here; * it will be returned in later * callbacks. */ { PictImage *imgPtr; Tk_Window tkwin; /* * Allocate and initialize the picture image master record. */ imgPtr = Blt_AssertCalloc(1, sizeof(PictImage)); imgPtr->imgToken = imgToken; imgPtr->interp = interp; imgPtr->gamma = 1.0f; imgPtr->cmdToken = Tcl_CreateObjCommand(interp, name, PictureInstCmdProc, imgPtr, PictureInstCmdDeletedProc); imgPtr->maxpect = FALSE; imgPtr->dither = 2; tkwin = Tk_MainWindow(interp); imgPtr->display = Tk_Display(tkwin); imgPtr->colormap = Tk_Colormap(tkwin); #ifdef notdef imgPtr->typePtr = typePtr; #endif Blt_InitHashTable(&imgPtr->cacheTable, sizeof(PictCacheKey)/sizeof(int)); /* * Process configuration options given in the image create command. */ if (ConfigurePictureImage(interp, imgPtr, objc, objv, 0) != TCL_OK) { DeletePictureImage(imgPtr); return TCL_ERROR; } *clientDataPtr = imgPtr; Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DisplayPictureImage -- * * This procedure is invoked to draw a picture image. * * Results: * None. * * Side effects: * A portion of the image gets rendered in a pixmap or window. * *--------------------------------------------------------------------------- */ static void DisplayPictureImage( ClientData clientData, /* Pointer to token structure for the * picture to be displayed. */ Display *display, /* Display on which to draw * picture. */ Drawable drawable, /* Pixmap or window in which to draw * image. */ int x, int y, /* Upper-left corner of region within * image to draw. */ int w, int h, /* Dimension of region within image to * draw. */ int dx, int dy) /* Coordinates within destination * drawable that correspond to imageX * and imageY. */ { PictInstance *instPtr = clientData; PictImage *imgPtr; Blt_Picture picture; imgPtr = instPtr->image; picture = PictureFromPictImage(imgPtr); if (picture == NULL) { return; } if ((instPtr->pixmap != None) && (Blt_PictureIsDirty(picture))) { Tk_FreePixmap(display, instPtr->pixmap); instPtr->pixmap = None; } if ((imgPtr->doCache) && (Blt_PictureIsOpaque(picture))) { if (instPtr->pixmap == None) { Pixmap pixmap; /* Save the entire picture in the pixmap. */ pixmap = Tk_GetPixmap(display, drawable, Blt_PictureWidth(picture), Blt_PictureHeight(picture), Blt_PainterDepth(instPtr->painter)); Blt_PaintPicture(instPtr->painter, drawable, picture, 0, 0, Blt_PictureWidth(picture), Blt_PictureHeight(picture), 0, 0, imgPtr->dither); instPtr->pixmap = pixmap; } /* Draw only the area that need to be repaired. */ XCopyArea(display, instPtr->pixmap, drawable, Blt_PainterGC(instPtr->painter), x, y, (unsigned int)w, (unsigned int)h, dx, dy); } else { unsigned int flags; if (instPtr->pixmap != None) { /* Kill the cached pixmap. */ Tk_FreePixmap(display, instPtr->pixmap); instPtr->pixmap = None; } flags = 0; if ((imgPtr->dither == 1) || ((imgPtr->dither == 2) && (Blt_PainterDepth(instPtr->painter) < 15))) { flags |= BLT_PAINTER_DITHER; } Blt_PaintPicture(instPtr->painter, drawable, picture, x, y, w, h, dx, dy, flags); } } /* *--------------------------------------------------------------------------- * * PictureImageToPostScript -- * * This procedure is called to output the contents of a picture image in * PostScript by calling the Tk_PostscriptPhoto function. * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int PictureImageToPostScript( ClientData clientData, /* Master picture image. */ Tcl_Interp *interp, /* Interpreter to return generated * PostScript. */ Tk_Window tkwin, Tk_PostscriptInfo psInfo, /* Not used. Only useful for Tk * internal Photo and Bitmap image * types. */ int x, int y, /* First pixel to output */ int w, int h, /* Width and height of picture area */ int prepass) { PictImage *imgPtr = clientData; if (prepass) { return TCL_OK; } if (Blt_PictureIsOpaque(imgPtr->picture)) { Blt_Ps ps; PageSetup setup; memset(&setup, 0, sizeof(setup)); ps = Blt_Ps_Create(interp, &setup); Blt_Ps_DrawPicture(ps, imgPtr->picture, (double)x, (double)y); Blt_Ps_SetInterp(ps, interp); Blt_Ps_Free(ps); } else { Blt_HashEntry *hPtr; Blt_Picture bg; Blt_Ps ps; Drawable drawable; PageSetup setup; PictInstance *instPtr; PictCacheKey *keyPtr; instPtr = NULL; keyPtr = CacheKey(tkwin, imgPtr->index); hPtr = Blt_FindHashEntry(&imgPtr->cacheTable,(char *)keyPtr); if (hPtr != NULL) { instPtr = Blt_GetHashValue(hPtr); } if ((instPtr != NULL) && (instPtr->pixmap != None)) { drawable = instPtr->pixmap; } else { drawable = Tk_WindowId(tkwin); } bg = Blt_DrawableToPicture(tkwin, drawable, x, y, w, h, imgPtr->gamma); if (bg == NULL) { return TCL_ERROR; } Blt_BlendPictures(bg, imgPtr->picture, 0, 0, w, h, 0, 0); memset(&setup, 0, sizeof(setup)); ps = Blt_Ps_Create(interp, &setup); Blt_Ps_DrawPicture(ps, bg, (double)x, (double)y); Blt_Ps_SetInterp(ps, interp); Blt_Ps_Free(ps); Blt_FreePicture(bg); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BBoxSwitch -- * * Convert a Tcl_Obj list of 2 or 4 numbers into representing a bounding * box structure. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BBoxSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { PictRegion *regionPtr = (PictRegion *)(record + offset); if (GetBBoxFromObj(interp, objPtr, regionPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FilterSwitch -- * * Convert a Tcl_Obj representing a 1D image filter. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FilterSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_ResampleFilter *filterPtr = (Blt_ResampleFilter *)(record + offset); return Blt_GetResampleFilterFromObj(interp, objPtr, filterPtr); } /* *--------------------------------------------------------------------------- * * BlendingModeSwitch -- * * Convert a Tcl_Obj representing a blending mode. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BlendingModeSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_BlendingMode *modePtr = (Blt_BlendingMode *)(record + offset); const char *string; int length; char c; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "normal", length) == 0)) { *modePtr = BLT_BLEND_NORMAL; } else if ((c == 'm') && (strncmp(string, "multiply", length) == 0)) { *modePtr = BLT_BLEND_MULTIPLY; } else if ((c == 's') && (strncmp(string, "screen", length) == 0)) { *modePtr = BLT_BLEND_SCREEN; } else if ((c == 'd') && (length > 1) && (strncmp(string, "darken", length) == 0)) { *modePtr = BLT_BLEND_DARKEN; } else if ((c == 'l') && (strncmp(string, "lighten", length) == 0)) { *modePtr = BLT_BLEND_LIGHTEN; } else if ((c == 'd') && (length > 1) && (strncmp(string, "difference", length) == 0)) { *modePtr = BLT_BLEND_DIFFERENCE; } else if ((c == 'h') && (strncmp(string, "hardlight", length) == 0)) { *modePtr = BLT_BLEND_HARDLIGHT; } else if ((c == 's') && (strncmp(string, "softlight", length) == 0)) { *modePtr = BLT_BLEND_SOFTLIGHT; } else if ((c == 'c') && (length > 5) && (strncmp(string, "colordodge", length) == 0)) { *modePtr = BLT_BLEND_COLORDODGE; } else if ((c == 'c') && (length > 5) && (strncmp(string, "colorburn", length) == 0)) { *modePtr = BLT_BLEND_COLORBURN; } else if ((c == 'o') && (strncmp(string, "overlay", length) == 0)) { *modePtr = BLT_BLEND_OVERLAY; } else { Tcl_AppendResult(interp, "unknown blending mode \"", string, "\": ", "should be normal, mulitply, screen, darken, lighten, ", "or difference", (char *) NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShapeSwitch -- * * Convert a Tcl_Obj representing a gradient shape. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ShapeSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_GradientShape *shapePtr = (Blt_GradientShape *)(record + offset); const char *string, **p; int shape; static const char *gradientShapes[] = { "linear", "bilinear", "radial", "rectangular", NULL }; string = Tcl_GetString(objPtr); for (shape = 0, p = gradientShapes; *p != NULL; p++, shape++) { if (strcmp(string, *p) == 0) { *shapePtr = (Blt_GradientShape)shape; return TCL_OK; } } Tcl_AppendResult(interp, "unknown gradient type \"", string, "\"", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * PathSwitch -- * * Convert a Tcl_Obj representing a gradient path. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PathSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Blt_GradientPath *pathPtr = (Blt_GradientPath *)(record + offset); const char *string, **p; int path; static const char *gradientPaths[] = { "x", "y", "xy", "yx", NULL }; string = Tcl_GetString(objPtr); for (path = 0, p = gradientPaths; *p != NULL; p++, path++) { if (strcmp(string, *p) == 0) { *pathPtr = (Blt_GradientPath)path; return TCL_OK; } } Tcl_AppendResult(interp, "unknown gradient type \"", string, "\"", (char *)NULL); return TCL_ERROR; } static Blt_Picture NextImage(PictImage *imgPtr) { Blt_Picture picture; imgPtr->index++; if (imgPtr->index >= Blt_Chain_GetLength(imgPtr->chain)) { imgPtr->index = 0; } picture = PictureFromPictImage(imgPtr); Blt_NotifyImageChanged(imgPtr); return picture; } static void TimerProc(ClientData clientData) { PictImage *imgPtr = clientData; Blt_Picture picture; int delay; picture = NextImage(imgPtr); delay = Blt_PictureDelay(imgPtr->picture); if (imgPtr->interval > 0) { delay = imgPtr->interval; } imgPtr->timerToken = Tcl_CreateTimerHandler(delay, TimerProc, imgPtr); } /* *--------------------------------------------------------------------------- * * ArithOp -- * * $image arith op $src -from { 0 0 100 100 } -to { 0 0 } * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ArithOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, mask; Blt_PictureArithOps op; PictImage *imgPtr = clientData; Blt_Pixel scalar; const char *string; char c; int len; ArithSwitches switches; src = NULL; string = Tcl_GetString(objv[2]); if ((string[0] == '0') && (string[1] == 'x')) { if (Blt_GetPixel(interp, string, &scalar) != TCL_OK) { return TCL_ERROR; } } else if (Blt_GetPicture(interp, string, &src) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[1], &len); op = 0; c = string[0]; if ((c == 'a') && (len > 1) && (strncmp(string, "add", len) == 0)) { op = PIC_ARITH_ADD; } else if ((c == 's') && (strncmp(string, "subtract", len) == 0)) { op = PIC_ARITH_SUB; } else if ((c == 'a') && (len > 1) && (strncmp(string, "and", len) == 0)) { op = PIC_ARITH_AND; } else if ((c == 'o') && (strncmp(string, "or", len) == 0)) { op = PIC_ARITH_OR; } else if ((c == 'n') && (len > 1) && (strncmp(string, "nand", len) == 0)) { op = PIC_ARITH_NAND; } else if ((c == 'n') && (len > 1) && (strncmp(string, "nor", len) == 0)) { op = PIC_ARITH_NOR; } else if ((c == 'x') && (strncmp(string, "xor", len) == 0)) { op = PIC_ARITH_XOR; } else if ((c == 'm') && (len > 1) && (strncmp(string, "max", len) == 0)) { op = PIC_ARITH_MAX; } else if ((c == 'm') && (len > 1) && (strncmp(string, "min", len) == 0)) { op = PIC_ARITH_MIN; } memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, arithSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } mask = NULL; if (switches.maskObjPtr != NULL) { if (Blt_GetPictureFromObj(interp, switches.maskObjPtr, &mask)!=TCL_OK) { return TCL_ERROR; } } if (mask == NULL) { if (src == NULL) { Blt_ApplyScalarToPicture(imgPtr->picture, &scalar, op); } else { Blt_ApplyPictureToPicture(imgPtr->picture, src, 0, 0, Blt_PictureWidth(src), Blt_PictureHeight(src), 0, 0, op); } } else { if (src == NULL) { Blt_ApplyScalarToPictureWithMask(imgPtr->picture, &scalar, mask, switches.invert, op); } else { Blt_ApplyPictureToPictureWithMask(imgPtr->picture, src, mask, 0, 0, Blt_PictureWidth(src), Blt_PictureHeight(src), 0, 0, switches.invert, op); } } Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BlankOp -- * * Resets the picture at its current size to blank (by default * white, fully opaque) pixels. * * $image blank -color #000000 -region { 0 0 20 20 } * Results: * Returns a standard TCL return value. If an error occured parsing * the pixel. * * * Side effects: * A Tk_ImageChanged notification is triggered. * *--------------------------------------------------------------------------- */ static int BlankOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; Blt_Pixel bg; bg.u32 = 0x00000000; if ((objc == 3) && (Blt_GetPixelFromObj(interp, objv[2], &bg)!= TCL_OK)) { return TCL_ERROR; } Blt_BlankPicture(imgPtr->picture, &bg); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BlendOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BlendOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { BlendSwitches switches; Blt_Picture fg, bg, tmp; PictImage *imgPtr = clientData; Blt_Picture dest; fprintf(stderr, "calling BlendOp\n"); if ((Blt_GetPictureFromObj(interp, objv[2], &bg) != TCL_OK) || (Blt_GetPictureFromObj(interp, objv[3], &fg) != TCL_OK)) { return TCL_ERROR; } switches.mode = BLT_BLEND_NORMAL; switches.from.x = switches.from.y = 0; switches.from.w = Blt_PictureWidth(bg); switches.from.h = Blt_PictureHeight(bg); switches.to.x = switches.to.y = 0; switches.to.w = Blt_PictureWidth(bg); switches.to.h = Blt_PictureHeight(bg); if (Blt_ParseSwitches(interp, blendSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } dest = PictureFromPictImage(imgPtr); tmp = NULL; if (dest == fg) { fg = tmp = Blt_ClonePicture(fg); } if (dest != bg) { Blt_ResizePicture(dest, Blt_PictureWidth(bg), Blt_PictureHeight(bg)); Blt_CopyPictureBits(dest, bg, 0, 0, Blt_PictureWidth(bg), Blt_PictureHeight(bg), 0, 0); } fprintf(stderr, "from=%d,%d %dx%d to=%d,%d\n", switches.from.x, switches.from.y, switches.from.w, switches.from.h, switches.to.x, switches.to.y); Blt_BlendPictures(dest, fg, switches.from.x, switches.from.y, switches.from.w, switches.from.h, switches.to.x, switches.to.y); if (tmp != NULL) { Blt_FreePicture(bg); } Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blend2Op -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int Blend2Op( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture fg, bg, dest; BlendSwitches switches; PictImage *imgPtr = clientData; if ((Blt_GetPictureFromObj(interp, objv[2], &bg) != TCL_OK) || (Blt_GetPictureFromObj(interp, objv[3], &fg) != TCL_OK)) { return TCL_ERROR; } switches.mode = BLT_BLEND_NORMAL; if (Blt_ParseSwitches(interp, blendSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } dest = PictureFromPictImage(imgPtr); Blt_ResizePicture(dest, Blt_PictureWidth(bg), Blt_PictureHeight(bg)); Blt_CopyPictureBits(dest, bg, 0, 0, Blt_PictureWidth(bg), Blt_PictureHeight(bg), 0, 0); Blt_BlendPicturesByMode(dest, fg, switches.mode); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BlurOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BlurOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, dest; PictImage *imgPtr; int r; /* Radius of the blur. */ if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[3], &r) != TCL_OK) { return TCL_ERROR; } if (r < 1) { Tcl_AppendResult(interp, "radius of blur must be > 1 pixel wide", (char *)NULL); return TCL_ERROR; } imgPtr = clientData; dest = PictureFromPictImage(imgPtr); Blt_BlurPicture(dest, src, r); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Returns the value of the configuration option specified. * * Results: * Returns a standard TCL return value. If TCL_OK, the value of the * picture configuration option specified is returned in the interpreter * result. Otherwise an error message is returned. * *--------------------------------------------------------------------------- */ static int CgetOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; return Blt_ConfigureValueFromObj(interp, Tk_MainWindow(interp), configSpecs, (char *)imgPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ConfigureOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr; Tk_Window tkwin; unsigned int flags; flags = BLT_CONFIG_OBJV_ONLY; tkwin = Tk_MainWindow(interp); imgPtr = clientData; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, tkwin, configSpecs, (char *)imgPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, tkwin, configSpecs, (char *)imgPtr, objv[2], flags); } else { if (ConfigurePictureImage(interp, imgPtr, objc - 2, objv + 2, flags) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConvolveOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConvolveOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src; ConvolveSwitches switches; PictImage *imgPtr = clientData; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } switches.vFilter = bltBoxFilter; switches.hFilter = bltBoxFilter; switches.filter = NULL; if (Blt_ParseSwitches(interp, convolveSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.filter != NULL) { switches.hFilter = switches.vFilter = switches.filter; } #ifdef notdef dest = PictureFromPictImage(imgPtr); Blt_ConvolvePicture(dest, src, switches.vFilter, switches.hFilter); #endif Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CopyOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int CopyOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Blt_Picture src, dest; CopySwitches switches; PictImage *imgPtr; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } switches.from.x = switches.from.y = 0; switches.from.w = Blt_PictureWidth(src); switches.from.h = Blt_PictureHeight(src); switches.to.x = switches.to.y = 0; switches.to.w = Blt_PictureWidth(src); switches.to.h = Blt_PictureHeight(src); switches.blend = FALSE; if (Blt_ParseSwitches(interp, copySwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (!Blt_AdjustRegionToPicture(src, &switches.from)) { return TCL_OK; /* Region is not inside of source. */ } imgPtr = clientData; dest = PictureFromPictImage(imgPtr); if (!Blt_AdjustRegionToPicture(dest, &switches.to)) { return TCL_OK; /* Region is not inside of * destination. */ } if (switches.blend) { Blt_BlendPictures(dest, src, switches.from.x, switches.from.y, switches.from.w, switches.from.h, switches.to.x, switches.to.y); } else { Blt_CopyPictureBits(dest, src, switches.from.x, switches.from.y, switches.from.w, switches.from.h, switches.to.x, switches.to.y); } Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CropOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int CropOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictRegion region; Blt_Picture src, dest; PictImage *imgPtr; if (Blt_GetBBoxFromObjv(interp, objc - 2, objv + 2, &region) != TCL_OK) { return TCL_ERROR; } imgPtr = clientData; src = PictureFromPictImage(imgPtr); if (!Blt_AdjustRegionToPicture(src, &region)) { Tcl_AppendResult(interp, "impossible coordinates for region", (char *)NULL); return TCL_ERROR; } dest = Blt_CreatePicture(region.w, region.h); Blt_CopyPictureBits(dest, src, region.x, region.y, region.w, region.h, 0,0); ReplacePicture(imgPtr, dest); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } BLT_EXTERN Blt_OpSpec bltPictDrawOps[]; BLT_EXTERN int bltPictDrawNOps; /* *--------------------------------------------------------------------------- * * DrawOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DrawOp( ClientData clientData, /* Contains reference to picture * object. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; Blt_Picture picture; PictCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, bltPictDrawNOps, bltPictDrawOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } picture = PictureFromPictImage(imgPtr); result = (*proc) (picture, interp, objc, objv); if (result == TCL_OK) { Blt_NotifyImageChanged(imgPtr); } return result; } /* *--------------------------------------------------------------------------- * * DupOp -- * * Creates a duplicate of the current picture in a new picture image. The * name of the new image is returned. * * Results: * Returns a standard TCL return value. If TCL_OK, The name of * the new image command is returned via the interpreter result. * Otherwise an error message is returned. * * Side effects: * A new image command is created. * *--------------------------------------------------------------------------- */ static int DupOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Blt_Picture picture; DupSwitches switches; PictImage *imgPtr = clientData; Tcl_Obj *objPtr; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, dupSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (!Blt_AdjustRegionToPicture(imgPtr->picture, &switches.region)) { Tcl_AppendResult(interp, "impossible coordinates for region", (char *)NULL); return TCL_ERROR; } /* * Create a new picture image. Let Tk automatically generate the command * name. */ if (Tcl_Eval(interp, "image create picture") != TCL_OK) { return TCL_ERROR; } /* The interpreter result now contains the name of the image. */ objPtr = Tcl_GetObjResult(interp); Tcl_IncrRefCount(objPtr); /* * Reset the result just in case Blt_ResetPicture returns an error. */ Tcl_ResetResult(interp); picture = Blt_CreatePicture(switches.region.w, switches.region.h); if (switches.nocopy) { /* Set the picture to a blank image. */ Blt_BlankPicture(picture, 0x00000000); } else { /* Copy region into new picture. */ Blt_CopyPictureBits(picture, imgPtr->picture, switches.region.x, switches.region.y, switches.region.w, switches.region.h, 0, 0); } if (Blt_ResetPicture(interp, Tcl_GetString(objPtr), picture) != TCL_OK) { Tcl_DecrRefCount(objPtr); Blt_FreePicture(picture); return TCL_ERROR; } Tcl_SetObjResult(interp, objPtr); Tcl_DecrRefCount(objPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExportOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ExportOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Blt_HashEntry *hPtr; PictFormat *fmtPtr; PictImage *imgPtr = clientData; int result; const char *fmt; if (objc == 2) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&fmtTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { PictFormat *fmtPtr; fmtPtr = Blt_GetHashValue(hPtr); if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { continue; } if (fmtPtr->exportProc == NULL) { continue; } Tcl_AppendElement(interp, fmtPtr->name); } return TCL_OK; } fmt = Tcl_GetString(objv[2]); hPtr = Blt_FindHashEntry(&fmtTable, fmt); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't export \"", fmt, "\": format not registered", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { LoadFormat(interp, fmt); } if (fmtPtr->exportProc == NULL) { Tcl_AppendResult(interp, "no export procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } result = (*fmtPtr->exportProc)(interp, imgPtr->index, imgPtr->chain, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * FadeOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FadeOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src; PictImage *imgPtr = clientData; int alpha; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[3], &alpha) != TCL_OK) { return TCL_ERROR; } Blt_FadePicture(imgPtr->picture, src, 0, 0, Blt_PictureWidth(src), Blt_PictureHeight(src), 0, 0, alpha); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FlipOp -- * * Flips the picture either horizontally or vertically. * * Results: * Returns a standard TCL return value. If TCL_OK, the components of the * pixel are returned as a list in the interpreter result. Otherwise an * error message is returned. * *--------------------------------------------------------------------------- */ static int FlipOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; const char *string; int isVertical; string = Tcl_GetString(objv[2]); if ((string[0] == 'x') && (string[1] == '\0')) { isVertical = FALSE; } else if ((string[0] == 'y') && (string[1] == '\0')) { isVertical = TRUE; } else { Tcl_AppendResult(interp, "bad flip argument \"", string, "\": should be x or y", (char *)NULL); return TCL_ERROR; } Blt_FlipPicture(imgPtr->picture, isVertical); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GammaOp -- * * $image gamma value * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GammaOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; double gamma; if (Tcl_GetDoubleFromObj(interp, objv[2], &gamma) != TCL_OK) { return TCL_ERROR; } Blt_GammaCorrectPicture(imgPtr->picture, imgPtr->picture, (float)gamma); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Returns the RGBA components of the pixel at the specified coordinate. * * Results: * Returns a standard TCL return value. If TCL_OK, the components of the * pixel are returned as a list in the interpreter result. Otherwise an * error message is returned. * *--------------------------------------------------------------------------- */ static int GetOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; Blt_Pixel *sp, pixel; int x, y; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if ((x < 0) || (x >= Blt_PictureWidth(imgPtr->picture))) { Tcl_AppendResult(interp, "x-coordinate \"", Tcl_GetString(objv[2]), "\" is out of range", (char *)NULL); return TCL_ERROR; } if ((y < 0) || (y >= Blt_PictureHeight(imgPtr->picture))) { Tcl_AppendResult(interp, "y-coordinate \"", Tcl_GetString(objv[3]), "\" is out of range", (char *)NULL); return TCL_ERROR; } sp = Blt_PicturePixel(imgPtr->picture, x, y); pixel = *sp; if ((Blt_PictureFlags(imgPtr->picture) & BLT_PIC_ASSOCIATED_COLORS) && ((sp->Alpha != 0xFF) && (sp->Alpha != 0x00))) { int bias = sp->Alpha >> 1; pixel.Red = (mul255(sp->Red) + bias) / sp->Alpha; pixel.Green = (mul255(sp->Green) + bias) / sp->Alpha; pixel.Blue = (mul255(sp->Blue) + bias) / sp->Alpha; } { char string[11]; sprintf_s(string, 11, "0x%02x%02x%02x%02x", pixel.Alpha, pixel.Red, pixel.Green, pixel.Blue); Tcl_SetObjResult(interp, Tcl_NewStringObj(string, 10)); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GradientOp -- * * Flips the picture either horizontally or vertically. * * Results: * Returns a standard TCL return value. If TCL_OK, the components of the * pixel are returned as a list in the interpreter result. Otherwise an * error message is returned. * *--------------------------------------------------------------------------- */ static int GradientOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; GradientSwitches switches; memset(&switches, 0, sizeof(switches)); colorSwitch.clientData = imgPtr; switches.fg.u32 = 0xFFFFFFFF; switches.bg.u32 = 0xFF000000; switches.gradient.shape = BLT_GRADIENT_SHAPE_LINEAR; switches.gradient.path = BLT_GRADIENT_PATH_X; switches.gradient.logScale = TRUE; switches.gradient.jitter = FALSE; if (Blt_ParseSwitches(interp, gradientSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } Blt_GradientPicture(imgPtr->picture, &switches.fg, &switches.bg, &switches.gradient); if ((switches.bg.Alpha != 0xFF) || (switches.fg.Alpha != 0xFF)) { imgPtr->picture->flags |= BLT_PIC_BLEND; } Blt_AssociateColors(imgPtr->picture); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GreyscaleOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GreyscaleOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, dest; PictImage *imgPtr = clientData; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } dest = Blt_GreyscalePicture(src); ReplacePicture(imgPtr, dest); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HeightOp -- * Returns the current height of the picture. * *--------------------------------------------------------------------------- */ static int HeightOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { PictImage *imgPtr = clientData; int h; h = 0; if (objc == 3) { int w; if (Tcl_GetIntFromObj(interp, objv[2], &h) != TCL_OK) { return TCL_ERROR; } w = Blt_PictureWidth(imgPtr->picture); Blt_AdjustPicture(imgPtr->picture, w, h); Blt_NotifyImageChanged(imgPtr); } if (imgPtr->picture != NULL) { h = Blt_PictureHeight(imgPtr->picture); } Tcl_SetIntObj(Tcl_GetObjResult(interp), h); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImportOp -- * * Imports an image source into a picture. The image source can be a file, * base64 string, or binary Tcl_Obj. This performs basically the same * function as "configure". Any extra functionality this command has is * based upon the ability to pass extra flags to the various converters, * something that can't be done really be done with * * $image configure -file file.jpg * * Results: * Returns a standard TCL return value. If no error, the interpreter * result will contain the number of images successfully read. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ImportOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Blt_Chain chain; Blt_HashEntry *hPtr; PictFormat *fmtPtr; PictImage *imgPtr = clientData; const char *fileName; const char *fmt; if (objc == 2) { PictFormat *fp, *fend; for (fp = pictFormats, fend = fp + NUMFMTS; fp < fend; fp++) { if ((fp->flags & BLT_PIC_FMT_LOADED) == 0) { continue; } if (fp->importProc == NULL) { continue; } Tcl_AppendElement(interp, fp->name); } return TCL_OK; } fmt = Tcl_GetString(objv[2]); hPtr = Blt_FindHashEntry(&fmtTable, fmt); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown picture format \"", fmt, "\"", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); if ((fmtPtr->flags & BLT_PIC_FMT_LOADED) == 0) { LoadFormat(interp, fmt); } if (fmtPtr->importProc == NULL) { Tcl_AppendResult(interp, "no import procedure registered for \"", fmtPtr->name, "\"", (char *)NULL); return TCL_ERROR; } chain = (*fmtPtr->importProc)(interp, objc, objv, &fileName); if (chain == NULL) { return TCL_ERROR; } FreePictures(imgPtr); imgPtr->chain = chain; imgPtr->index = 0; imgPtr->picture = Blt_Chain_FirstValue(chain); /* * Save the format type and file name in the image record. The file name * is used when querying image options -file or -data via configure. The * type is used by the "-data" operation to establish a default format to * output. */ imgPtr->fmtPtr = fmtPtr; imgPtr->flags &= ~IMPORTED_MASK; if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } if (fileName == NULL) { imgPtr->name = NULL; imgPtr->flags |= IMPORTED_DATA; } else { imgPtr->name = Blt_AssertStrdup(fileName); imgPtr->flags |= IMPORTED_FILE; } Blt_NotifyImageChanged(imgPtr); /* Return the number of separates images read. */ Tcl_SetIntObj(Tcl_GetObjResult(interp), Blt_Chain_GetLength(imgPtr->chain)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InfoOp -- * * Reports the basic information about a picture. * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int InfoOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { PictImage *imgPtr = clientData; int nColors; const char *string; Tcl_Obj *listObjPtr, *objPtr; nColors = Blt_QueryColors(imgPtr->picture, (Blt_HashTable *)NULL); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); objPtr = Tcl_NewStringObj("colors", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(nColors); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("type", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); string = Blt_PictureIsColor(imgPtr->picture) ? "color" : "greyscale"; objPtr = Tcl_NewStringObj(string, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("opacity", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (Blt_PictureIsBlended(imgPtr->picture)) { string = "blended"; } else if (Blt_PictureIsMasked(imgPtr->picture)) { string = "masked"; } else { string = "full"; } objPtr = Tcl_NewStringObj(string, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("width", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(Blt_PictureWidth(imgPtr->picture)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("height", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(Blt_PictureHeight(imgPtr->picture)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("count", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(Blt_Chain_GetLength(imgPtr->chain)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("index", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewIntObj(imgPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj("read-format", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewStringObj((imgPtr->fmtPtr != NULL) ? imgPtr->fmtPtr->name : "???", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MultiplyOp -- * * $image multiply scalar * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MultiplyOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; double scalar; if (Tcl_GetDoubleFromObj(interp, objv[2], &scalar) != TCL_OK) { return TCL_ERROR; } Blt_MultiplyPixels(imgPtr->picture, (float)scalar); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } static int GetImageIndex(Tcl_Interp *interp, PictImage *imgPtr, Tcl_Obj *objPtr, int *indexPtr) { int index; const char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "end") == 0) { index = Blt_Chain_GetLength(imgPtr->chain) - 1; } else if (Tcl_GetIntFromObj(interp, objPtr, &index) != TCL_OK) { return TCL_ERROR; } if ((index < 0) || (index >= Blt_Chain_GetLength(imgPtr->chain))) { Tcl_AppendResult(interp, "invalid image index \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } *indexPtr = index; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListAnimateOp -- * * $im list animate $delay * $im list animate stop * $im list animate start * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListAnimateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; const char *string; int interval; string = Tcl_GetString(objv[2]); if (strcmp(string, "stop") == 0) { if (imgPtr->timerToken != 0) { Tcl_DeleteTimerHandler(imgPtr->timerToken); imgPtr->timerToken = 0; } } else if (strcmp(string, "start") == 0) { if (imgPtr->timerToken == 0) { int delay; delay = Blt_PictureDelay(imgPtr->picture); imgPtr->timerToken = Tcl_CreateTimerHandler(delay, TimerProc, imgPtr); } } else if (Tcl_GetIntFromObj(interp, objv[2], &interval) == TCL_OK) { imgPtr->interval = interval; if (imgPtr->timerToken != 0) { Tcl_DeleteTimerHandler(imgPtr->timerToken); } imgPtr->timerToken = Tcl_CreateTimerHandler(imgPtr->interval, TimerProc, imgPtr); } else { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListAppendOp -- * * $im list append $img... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListAppendOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; int i; for (i = 3; i < objc; i++) { Blt_Picture src, dest; if (Blt_GetPictureFromObj(interp, objv[i], &src) != TCL_OK) { return TCL_ERROR; } dest = Blt_ClonePicture(src); Blt_Chain_Append(imgPtr->chain, dest); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListCurrentOp -- * * $im list current index * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListCurrentOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; if (objc == 4) { int index; if (GetImageIndex(interp, imgPtr, objv[3], &index) != TCL_OK) { return TCL_ERROR; } imgPtr->picture = Blt_GetNthPicture(imgPtr->chain, index); imgPtr->index = index; } Tcl_SetIntObj(Tcl_GetObjResult(interp), imgPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListDeleteOp -- * * $im list delete index * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; int i; int first, last; Blt_ChainLink link, next; if (GetImageIndex(interp, imgPtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (GetImageIndex(interp, imgPtr, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if (first > last) { return TCL_OK; } for (i = 0, link = Blt_Chain_FirstLink(imgPtr->chain); link != NULL; link = next, i++) { next = Blt_Chain_NextLink(link); if ((i >= first) && (i <= last)) { Blt_Picture picture; picture = Blt_Chain_GetValue(link); Blt_FreePicture(picture); Blt_Chain_DeleteLink(imgPtr->chain, link); } } imgPtr->index = 0; imgPtr->picture = Blt_Chain_FirstValue(imgPtr->chain); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListLengthOp -- * * $im list length * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListLengthOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; int count; count = Blt_Chain_GetLength(imgPtr->chain); Tcl_SetIntObj(Tcl_GetObjResult(interp), count); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListNextOp -- * * $im list next * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListNextOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; NextImage(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListPreviousOp -- * * $im list previous * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListPreviousOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; Blt_Picture picture; imgPtr->index--; if (imgPtr->index < 0) { imgPtr->index = Blt_Chain_GetLength(imgPtr->chain) - 1; } if (imgPtr->index < 0) { imgPtr->index = 0; } picture = PictureFromPictImage(imgPtr); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ListReplaceOp -- * * $im list replace first last $img... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListReplaceOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictImage *imgPtr = clientData; int i; int first, last; Blt_ChainLink link, next, head, tail; if (GetImageIndex(interp, imgPtr, objv[3], &first) != TCL_OK) { return TCL_ERROR; } if (GetImageIndex(interp, imgPtr, objv[4], &last) != TCL_OK) { return TCL_ERROR; } if (first > last) { return TCL_OK; } head = tail = link; for (i = 0, link = Blt_Chain_FirstLink(imgPtr->chain); link != NULL; link = next, i++) { next = Blt_Chain_NextLink(link); if ((i >= first) && (i <= last)) { Blt_Picture picture; picture = Blt_Chain_GetValue(link); Blt_FreePicture(picture); Blt_Chain_DeleteLink(imgPtr->chain, link); } else if (head == NULL) { head = link; } else if (tail == NULL) { tail = link; } } if (head != NULL) { for (i = 5; i < objc; i++) { Blt_Picture src, dest; if (Blt_GetPictureFromObj(interp, objv[i], &src) != TCL_OK) { return TCL_ERROR; } dest = Blt_ClonePicture(src); link = Blt_Chain_NewLink(); Blt_Chain_SetValue(link, dest); Blt_Chain_LinkAfter(imgPtr->chain, link, head); head = link; } } else if (tail != NULL) { for (i = 5; i < objc; i++) { Blt_Picture src, dest; if (Blt_GetPictureFromObj(interp, objv[i], &src) != TCL_OK) { return TCL_ERROR; } dest = Blt_ClonePicture(src); link = Blt_Chain_NewLink(); Blt_Chain_SetValue(link, dest); Blt_Chain_LinkBefore(imgPtr->chain, link, tail); } } else { assert(Blt_Chain_GetLength(imgPtr->chain) == 0); for (i = 5; i < objc; i++) { Blt_Picture src, dest; if (Blt_GetPictureFromObj(interp, objv[i], &src) != TCL_OK) { return TCL_ERROR; } dest = Blt_ClonePicture(src); Blt_Chain_Append(imgPtr->chain, dest); } } imgPtr->index = 0; imgPtr->picture = Blt_Chain_FirstValue(imgPtr->chain); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } static Blt_OpSpec listOps[] = { {"animate", 2, ListAnimateOp, 3, 3, "oper",}, {"append", 2, ListAppendOp, 3, 0, "?image...?",}, {"current", 1, ListCurrentOp, 3, 4, "?index?",}, {"delete", 1, ListDeleteOp, 3, 4, "first ?last?",}, {"length", 1, ListLengthOp, 3, 3, "",}, {"next", 1, ListNextOp, 3, 3, "",}, {"previous", 1, ListPreviousOp, 3, 3, "",}, {"replace", 1, ListReplaceOp, 5, 0, "first last ?image...?",}, }; static int nListOps = sizeof(listOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * ListOp -- * * $img list animate * $img list append image image image * $img list current ?index? * $img list delete 0 end * $img list length * $img list next * $img list previous * $img list replace 0 end image image image image * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ListOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PictCmdProc *proc; proc = Blt_GetOpFromObj(interp, nListOps, listOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * PutOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int PutOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return TCL_OK; } /* *--------------------------------------------------------------------------- * * QuantizeOp -- * * $dest quantize $src 256 * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int QuantizeOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, dest; PictImage *imgPtr = clientData; int nColors; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[3], &nColors) != TCL_OK) { return TCL_ERROR; } dest = Blt_QuantizePicture(src, nColors); if (dest == NULL) { return TCL_ERROR; } ReplacePicture(imgPtr, dest); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ResampleOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ResampleOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, tmp; Blt_ResampleFilter hFilter, vFilter; PictImage *imgPtr = clientData; ResampleSwitches switches; int destWidth, destHeight; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } switches.region.x = switches.region.y = 0; switches.region.w = Blt_PictureWidth(src); switches.region.h = Blt_PictureHeight(src); switches.width = Blt_PictureWidth(imgPtr->picture); switches.height = Blt_PictureHeight(imgPtr->picture); switches.filter = NULL; if (Blt_ParseSwitches(interp, resampleSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (!Blt_AdjustRegionToPicture(src, &switches.region)) { Tcl_AppendResult(interp, "impossible coordinates for region", (char *)NULL); return TCL_ERROR; } if ((Blt_PictureWidth(imgPtr->picture) != switches.width) || (Blt_PictureHeight(imgPtr->picture) != switches.height)) { Blt_AdjustPicture(imgPtr->picture, switches.width, switches.height); } destWidth = Blt_PictureWidth(imgPtr->picture); destHeight = Blt_PictureHeight(imgPtr->picture); if (switches.filter == NULL) { if (switches.region.w < destWidth) { hFilter = bltMitchellFilter; } else { hFilter = bltBoxFilter; } if (switches.region.h < destHeight) { vFilter = bltMitchellFilter; } else { vFilter = bltBoxFilter; } } else { hFilter = vFilter = switches.filter; } tmp = Blt_CreatePicture(switches.region.w, switches.region.h); Blt_CopyPictureBits(tmp, src, switches.region.x, switches.region.y, switches.region.w, switches.region.h, 0, 0); Blt_ResamplePicture(imgPtr->picture, tmp, vFilter, hFilter); Blt_FreePicture(tmp); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RotateOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RotateOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_Picture src, dest; PictImage *imgPtr = clientData; double angle; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, objv[3], &angle) != TCL_OK) { const char *string; string = Tcl_GetString(objv[3]); if (Tcl_ExprDouble(interp, string, &angle) != TCL_OK) { return TCL_ERROR; } } dest = Blt_RotatePicture(src, angle); ReplacePicture(imgPtr, dest); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int SelectOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Blt_Picture src; PictImage *imgPtr = clientData; Blt_Pixel lower, upper; unsigned char tmp; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } if (Blt_GetPixelFromObj(interp, objv[3], &lower) != TCL_OK) { return TCL_ERROR; } if (objc == 5) { if (Blt_GetPixelFromObj(interp, objv[4], &upper) != TCL_OK) { return TCL_ERROR; } } else { upper.u32 = lower.u32; } if (lower.Red > upper.Red) { tmp = lower.Red, lower.Red = upper.Red, upper.Red = tmp; } if (lower.Green > upper.Green) { tmp = lower.Green, lower.Green = upper.Green, upper.Green = tmp; } if (lower.Blue > upper.Blue) { tmp = lower.Blue, lower.Blue = upper.Blue, upper.Blue = tmp; } if (lower.Alpha > upper.Alpha) { tmp = lower.Alpha, lower.Alpha = upper.Alpha, upper.Alpha = tmp; } Blt_SelectPixels(imgPtr->picture, src, &lower, &upper); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SharpenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SharpenOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Not used. */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { PictImage *imgPtr = clientData; Blt_SharpenPicture(imgPtr->picture, imgPtr->picture); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SnapOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * * $pict snap window -region {x y w h} -raise * *--------------------------------------------------------------------------- */ static int SnapOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; Blt_Picture picture; Window window; int w, h; SnapSwitches switches; if (Blt_GetWindowFromObj(interp, objv[2], &window) != TCL_OK) { return TCL_ERROR; } if (Blt_GetWindowRegion(imgPtr->display, window, (int *)NULL, (int *)NULL, &w, &h) != TCL_OK) { Tcl_AppendResult(interp, "can't get dimensions of window \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); switches.region.x = switches.region.y = 0; switches.region.w = w; switches.region.h = h; if (Blt_ParseSwitches(interp, snapSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if ((switches.region.w + switches.region.x) > w) { switches.region.w = (w - switches.region.x); } if ((switches.region.h + switches.region.y) > h) { switches.region.h = (h - switches.region.y); } if (switches.raise) { XRaiseWindow(imgPtr->display, window); } /* Depth, visual, colormap */ picture = Blt_WindowToPicture(imgPtr->display, window, switches.region.x, switches.region.y, switches.region.w, switches.region.h, imgPtr->gamma); if (picture == NULL) { Tcl_AppendResult(interp, "can't obtain snapshot of window \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } ReplacePicture(imgPtr, picture); if (imgPtr->name != NULL) { Blt_Free(imgPtr->name); } Blt_NotifyImageChanged(imgPtr); imgPtr->flags &= ~IMPORTED_MASK; Blt_FreeSwitches(snapSwitches, &switches, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TileOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int TileOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PictImage *imgPtr = clientData; Blt_Picture src; TileSwitches switches; if (Blt_GetPictureFromObj(interp, objv[2], &src) != TCL_OK) { return TCL_ERROR; } switches.xOrigin = switches.yOrigin = 0; switches.region.x = switches.region.y = 0; switches.region.w = Blt_PictureWidth(imgPtr->picture); switches.region.h = Blt_PictureHeight(imgPtr->picture); if (Blt_ParseSwitches(interp, tileSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (!Blt_AdjustRegionToPicture(imgPtr->picture, &switches.region)) { Tcl_AppendResult(interp, "impossible coordinates for region", (char *)NULL); return TCL_ERROR; } Blt_TilePicture(imgPtr->picture, src, switches.xOrigin, switches.yOrigin, switches.region.x, switches.region.y, switches.region.w, switches.region.h); Blt_NotifyImageChanged(imgPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * WidthOp -- * Returns the current width of the picture. * *--------------------------------------------------------------------------- */ static int WidthOp( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { PictImage *imgPtr = clientData; int w; if (objc == 3) { int h; if (Tcl_GetIntFromObj(interp, objv[2], &w) != TCL_OK) { return TCL_ERROR; } if (w < 0) { Tcl_AppendResult(interp, "bad width \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } h = Blt_PictureHeight(imgPtr->picture); Blt_AdjustPicture(imgPtr->picture, w, h); Blt_NotifyImageChanged(imgPtr); } w = Blt_PictureWidth(imgPtr->picture); Tcl_SetIntObj(Tcl_GetObjResult(interp), w); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Picture instance sub-command specification: * * - Name of the sub-command. * - Minimum number of characters needed to unambiguously * recognize the sub-command. * - Pointer to the function to be called for the sub-command. * - Minimum number of arguments accepted. * - Maximum number of arguments accepted. * - String to be displayed for usage (arguments only). * *--------------------------------------------------------------------------- */ static Blt_OpSpec pictInstOps[] = { {"add", 2, ArithOp, 3, 0, "image|color",}, {"and", 3, ArithOp, 3, 0, "image|color",}, {"blank", 3, BlankOp, 2, 3, "?color?",}, {"ble2nd", 4, Blend2Op, 4, 0, "bg fg ?switches?",}, {"blend", 4, BlendOp, 4, 0, "bg fg ?switches?",}, {"blur", 3, BlurOp, 4, 4, "src width",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 4, ConfigureOp, 2, 0, "?option value?...",}, {"convolve", 4, ConvolveOp, 3, 0, "src ?switches?",}, {"copy", 3, CopyOp, 3, 0, "srcPict ?switches?",}, {"crop", 3, CropOp, 2, 0, "?switches?",}, {"draw", 2, DrawOp, 2, 0, "?args?",}, {"dup", 2, DupOp, 2, 0, "?switches?",}, {"export", 1, ExportOp, 2, 0, "format ?switches?...",}, {"fade", 2, FadeOp, 4, 4, "src factor",}, {"flip", 2, FlipOp, 3, 0, "x|y",}, {"gamma", 2, GammaOp, 3, 3, "value",}, {"get", 2, GetOp, 4, 4, "x y",}, {"gradient", 3, GradientOp, 2, 0, "?switches?",}, {"greyscale", 3, GreyscaleOp, 3, 3, "src",}, {"height", 1, HeightOp, 2, 3, "?newHeight?",}, {"import", 2, ImportOp, 2, 0, "format ?switches?...",}, {"info", 2, InfoOp, 2, 2, "info",}, {"list", 1, ListOp, 2, 0, "args...",}, {"max", 2, ArithOp, 3, 0, "image|color",}, {"min", 2, ArithOp, 3, 0, "image|color",}, {"multiply", 2, MultiplyOp, 3, 3, "float",}, {"nand", 2, ArithOp, 3, 0, "image|color",}, {"nor", 2, ArithOp, 3, 0, "image|color",}, {"or", 1, ArithOp, 3, 0, "image|color ?switches?",}, {"put", 1, PutOp, 2, 0, "color ?window?...",}, {"quantize", 1, QuantizeOp, 4, 4, "src numColors",}, {"resample", 2, ResampleOp, 3, 0, "src ?switches?",}, {"rotate", 2, RotateOp, 4, 4, "src angle",}, {"select", 2, SelectOp, 4, 5, "src color ?color?",}, {"sharpen", 2, SharpenOp, 2, 0, "",}, {"snap", 2, SnapOp, 3, 0, "window ?switches?",}, {"subtract", 2, ArithOp, 3, 0, "image|color",}, {"tile", 2, TileOp, 3, 0, "image ?switches?",}, {"width", 1, WidthOp, 2, 3, "?newWidth?",}, {"xor", 1, ArithOp, 3, 0, "image|color ?switches?",}, }; static int nPictInstOps = sizeof(pictInstOps) / sizeof(Blt_OpSpec); static int PictureInstCmdProc( ClientData clientData, /* Information about picture cmd. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nPictInstOps, pictInstOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * PictureInstCmdDeleteProc -- * * This procedure is invoked when a picture command is deleted. * * Results: * None. * *--------------------------------------------------------------------------- */ static void PictureInstCmdDeletedProc(ClientData clientData) /* Pointer to record. */ { PictImage *imgPtr = clientData; imgPtr->cmdToken = NULL; if (imgPtr->imgToken != NULL) { Tk_DeleteImage(imgPtr->interp, Tk_NameOfImage(imgPtr->imgToken)); } } /* *--------------------------------------------------------------------------- * * PictureLoadOp -- * * Loads the dynamic library representing the converters for the named * format. Designed to be called by "package require", not directly by the * user. * * Results: * A standard TCL result. Return TCL_OK is the converter was successfully * loaded, TCL_ERROR otherwise. * * blt::datatable load fmt libpath lib * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PictureLoadOp( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Tcl_DString lib; char *fmt; char *safeProcName, *initProcName; int result; int length; fmt = Tcl_GetStringFromObj(objv[2], &length); hPtr = Blt_FindHashEntry(&fmtTable, fmt); if (hPtr != NULL) { PictFormat *fmtPtr; fmtPtr = Blt_GetHashValue(hPtr); if (fmtPtr->flags & BLT_PIC_FMT_LOADED) { return TCL_OK; /* Converter is already loaded. */ } } Tcl_DStringInit(&lib); { Tcl_DString ds; const char *pathName; Tcl_DStringInit(&ds); pathName = Tcl_TranslateFileName(interp, Tcl_GetString(objv[3]), &ds); if (pathName == NULL) { Tcl_DStringFree(&ds); return TCL_ERROR; } Tcl_DStringAppend(&lib, pathName, -1); Tcl_DStringFree(&ds); } Tcl_DStringAppend(&lib, "/", -1); Tcl_UtfToTitle(fmt); Tcl_DStringAppend(&lib, "Picture", 7); Tcl_DStringAppend(&lib, fmt, -1); Tcl_DStringAppend(&lib, Blt_Itoa(BLT_MAJOR_VERSION), 1); Tcl_DStringAppend(&lib, Blt_Itoa(BLT_MINOR_VERSION), 1); Tcl_DStringAppend(&lib, BLT_LIB_SUFFIX, -1); Tcl_DStringAppend(&lib, BLT_SO_EXT, -1); initProcName = Blt_AssertMalloc(11 + length + 4 + 1); sprintf_s(initProcName, 11 + length + 4 + 1, "Blt_Picture%sInit", fmt); safeProcName = Blt_AssertMalloc(11 + length + 8 + 1); sprintf_s(safeProcName, 11 + length + 8 + 1, "Blt_Picture%sSafeInit", fmt); result = Blt_LoadLibrary(interp, Tcl_DStringValue(&lib), initProcName, safeProcName); Tcl_DStringFree(&lib); if (safeProcName != NULL) { Blt_Free(safeProcName); } if (initProcName != NULL) { Blt_Free(initProcName); } return result; } /* *--------------------------------------------------------------------------- * * Picture instance sub-command specification: * * - Name of the sub-command. * - Minimum number of characters needed to unambiguously * recognize the sub-command. * - Pointer to the function to be called for the sub-command. * - Minimum number of arguments accepted. * - Maximum number of arguments accepted. * - String to be displayed for usage (arguments only). * *--------------------------------------------------------------------------- */ static Blt_OpSpec pictureOps[] = { {"load", 1, PictureLoadOp, 4, 0, "fmt lib",}, #ifdef notdef {"blur", 1, BlurOp, 4, 0, "src dest ?switches?",}, {"brighten" 1, BrightenOp, 4, 0, "src dest ?switches?",}, {"darken" 1, BrightenOp, 4, 0, "src dest ?switches?",}, {"medianf" 1, MedianOp, 4, 0, "src dest ?switches?",}, {"translate", 1, TranslateOp, 4, 0, "src dest ?switches?",}, #endif }; static int nPictureOps = sizeof(pictureOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * PictureImageCmdProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PictureImageCmdProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nPictureOps, pictureOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc)(clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * Blt_PictureCmdInitProc -- * * This procedure is invoked to initialize the "tree" command. * * Results: * None. * * Side effects: * Creates the new command and adds a new entry into a global Tcl * associative array. * *--------------------------------------------------------------------------- */ int Blt_PictureCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "picture", PictureImageCmdProc, }; /* cmdSpec.clientData = GetPictureCmdInterpData(interp); */ if (Blt_InitCmd(interp, "::blt", &cmdSpec) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } static Tk_ImageType pictureImageType = { (char *)"picture", CreatePictureImage, GetPictInstance, DisplayPictureImage, FreePictInstance, DeletePictureImage, PictureImageToPostScript, (Tk_ImageType *)NULL /* nextPtr */ }; int Blt_IsPicture(Tk_Image tkImage) { const char *type; type = Blt_Image_NameOfType(tkImage); return (strcmp(type, pictureImageType.name) == 0); } /* *--------------------------------------------------------------------------- * * Blt_RegisterPictureImageType -- * * Registers the "picture" image type with Tk. * *--------------------------------------------------------------------------- void Blt_RegisterPictureImageType(Tcl_Interp *interp) { PictFormat *fp, *fend; Tk_CreateImageType(&pictureImageType); Blt_CpuFeatures(interp, NULL); Blt_InitHashTable(&fmtTable, BLT_STRING_KEYS); for (fp = pictFormats, fend = fp + NUMFMTS; fp < fend; fp++) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&fmtTable, fp->name, &isNew); Blt_SetHashValue(hPtr, fp); } } */ int Blt_PictureRegisterFormat( Tcl_Interp *interp, const char *fmt, Blt_PictureIsFmtProc *isProc, Blt_PictureReadDataProc *readProc, Blt_PictureWriteDataProc *writeProc, Blt_PictureImportProc *importProc, Blt_PictureExportProc *exportProc) { PictFormat *fmtPtr; Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&fmtTable, fmt); if (hPtr == NULL) { Tcl_AppendResult(interp, "unknown format \"", fmt, "\"", (char *)NULL); return TCL_ERROR; } fmtPtr = Blt_GetHashValue(hPtr); fmtPtr->flags = BLT_PIC_FMT_LOADED; fmtPtr->isFmtProc = isProc; fmtPtr->readProc = readProc; fmtPtr->writeProc = writeProc; fmtPtr->importProc = importProc; fmtPtr->exportProc = exportProc; return TCL_OK; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinFont.c������������������������������������������������������������������0000644�0001750�0001750�00000142501�11506673502�015275� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltWinFont.c -- * * This module implements rotated fonts for the BLT toolkit. * * Copyright 2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include "tkDisplay.h" #include "tkFont.h" #include "bltFont.h" #define WINDEBUG 0 #define DEBUG_FONT_SELECTION 0 #define DEBUG_FONT_SELECTION2 0 typedef struct _Blt_Font _Blt_Font; enum FontTypes { FONT_UNKNOWN, /* Unknown font type. */ FONT_TK, /* Normal Tk font. */ FONT_WIN /* Windows font. */ }; #ifndef HAVE_LIBXFT #define FC_WEIGHT_THIN 0 #define FC_WEIGHT_EXTRALIGHT 40 #define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT #define FC_WEIGHT_LIGHT 50 #define FC_WEIGHT_BOOK 75 #define FC_WEIGHT_REGULAR 80 #define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR #define FC_WEIGHT_MEDIUM 100 #define FC_WEIGHT_DEMIBOLD 180 #define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD #define FC_WEIGHT_BOLD 200 #define FC_WEIGHT_EXTRABOLD 205 #define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD #define FC_WEIGHT_BLACK 210 #define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK #define FC_WEIGHT_EXTRABLACK 215 #define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK #define FC_SLANT_ROMAN 0 #define FC_SLANT_ITALIC 100 #define FC_SLANT_OBLIQUE 110 #define FC_WIDTH_ULTRACONDENSED 50 #define FC_WIDTH_EXTRACONDENSED 63 #define FC_WIDTH_CONDENSED 75 #define FC_WIDTH_SEMICONDENSED 87 #define FC_WIDTH_NORMAL 100 #define FC_WIDTH_SEMIEXPANDED 113 #define FC_WIDTH_EXPANDED 125 #define FC_WIDTH_EXTRAEXPANDED 150 #define FC_WIDTH_ULTRAEXPANDED 200 #define FC_PROPORTIONAL 0 #define FC_DUAL 90 #define FC_MONO 100 #define FC_CHARCELL 110 #define FC_ANTIALIAS "antialias" /* Bool (depends) */ #define FC_AUTOHINT "autohint" /* Bool (false) */ #define FC_DECORATIVE "decorative" /* Bool */ #define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool */ #define FC_EMBOLDEN "embolden" /* Bool */ #define FC_FAMILY "family" /* String */ #define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */ #define FC_HINTING "hinting" /* Bool (true) */ #define FC_MINSPACE "minspace" /* Bool */ #define FC_OUTLINE "outline" /* Bool */ #define FC_SCALABLE "scalable" /* Bool */ #define FC_SIZE "size" /* Double */ #define FC_SLANT "slant" /* Int */ #define FC_SPACING "spacing" /* Int */ #define FC_STYLE "style" /* String */ #define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */ #define FC_WEIGHT "weight" /* Int */ #define FC_WIDTH "width" /* Int */ #endif #ifndef FC_WEIGHT_EXTRABLACK #define FC_WEIGHT_EXTRABLACK 215 #define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK #endif typedef struct { char *family; const char *weight; const char *slant; const char *width; const char *spacing; int size; /* If negative, pixels, else points */ } FontPattern; typedef struct { const char *name; int minChars; const char *key; int value; const char *oldvalue; } FontSpec; static FontSpec fontSpecs[] = { { "black", 2, FC_WEIGHT, FC_WEIGHT_BLACK, "*"}, { "bold", 3, FC_WEIGHT, FC_WEIGHT_BOLD, "bold"}, { "book", 3, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "charcell", 2, FC_SPACING, FC_CHARCELL, "c"}, { "condensed", 2, FC_WIDTH, FC_WIDTH_CONDENSED, "condensed"}, { "demi", 4, FC_WEIGHT, FC_WEIGHT_BOLD, "semi"}, { "demibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "semibold"}, { "dual", 2, FC_SPACING, FC_DUAL, "*"}, { "i", 1, FC_SLANT, FC_SLANT_ITALIC, "i"}, { "italic", 2, FC_SLANT, FC_SLANT_ITALIC, "italic"}, { "light", 1, FC_WEIGHT, FC_WEIGHT_LIGHT, "light"}, { "medium", 2, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "mono", 2, FC_SPACING, FC_MONO, "m"}, { "normal", 1, FC_WEIGHT, FC_WEIGHT_MEDIUM, "normal"}, { "o", 1, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "obilque", 2, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "overstrike", 2, NULL, 0, "*"}, { "proportional", 1, FC_SPACING, FC_PROPORTIONAL, "p"}, { "r", 1, FC_SLANT, FC_SLANT_ROMAN, "r"}, { "roman", 2, FC_SLANT, FC_SLANT_ROMAN, "roman"}, { "semibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "semibold"}, { "semicondensed",5, FC_WIDTH, FC_WIDTH_SEMICONDENSED, "semicondensed"}, { "underline", 1, NULL, 0, "*"}, }; static int nFontSpecs = sizeof(fontSpecs) / sizeof(FontSpec); static FontSpec weightSpecs[] ={ { "black", 2, FC_WEIGHT, FC_WEIGHT_BLACK, "bold"}, { "bold", 3, FC_WEIGHT, FC_WEIGHT_BOLD, "bold"}, { "book", 3, FC_WEIGHT, FC_WEIGHT_MEDIUM, "*"}, { "demi", 4, FC_WEIGHT, FC_WEIGHT_BOLD, "*"}, { "demibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "*"}, { "extrablack", 6, FC_WEIGHT, FC_WEIGHT_EXTRABLACK, "*"}, { "extralight", 6, FC_WEIGHT, FC_WEIGHT_EXTRALIGHT, "*"}, { "heavy", 1, FC_WEIGHT, FC_WEIGHT_HEAVY, "*"}, { "light", 1, FC_WEIGHT, FC_WEIGHT_LIGHT, "light"}, { "medium", 1, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "normal", 1, FC_WEIGHT, FC_WEIGHT_MEDIUM, "normal"}, { "regular", 1, FC_WEIGHT, FC_WEIGHT_REGULAR, "medium"}, { "semibold", 1, FC_WEIGHT, FC_WEIGHT_SEMIBOLD, "semibold"}, { "thin", 1, FC_WEIGHT, FC_WEIGHT_THIN, "thin"}, { "ultrablack", 7, FC_WEIGHT, FC_WEIGHT_ULTRABLACK, "*"}, { "ultrabold", 7, FC_WEIGHT, FC_WEIGHT_ULTRABOLD, "*"}, { "ultralight", 6, FC_WEIGHT, FC_WEIGHT_ULTRALIGHT, "*"}, }; static int nWeightSpecs = sizeof(weightSpecs) / sizeof(FontSpec); static FontSpec slantSpecs[] ={ { "i", 1, FC_SLANT, FC_SLANT_ITALIC, "italic"}, { "italic", 2, FC_SLANT, FC_SLANT_ITALIC, "italic"}, { "o", 1, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "obilque", 3, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "r", 1, FC_SLANT, FC_SLANT_ROMAN, "roman"}, { "roman", 2, FC_SLANT, FC_SLANT_ROMAN, "roman"}, }; static int nSlantSpecs = sizeof(slantSpecs) / sizeof(FontSpec); static FontSpec spacingSpecs[] = { { "charcell", 2, FC_SPACING, FC_CHARCELL, "c"}, { "dual", 2, FC_SPACING, FC_DUAL, "*"}, { "mono", 2, FC_SPACING, FC_MONO, "m"}, { "proportional", 1, FC_SPACING, FC_PROPORTIONAL, "p"}, }; static int nSpacingSpecs = sizeof(spacingSpecs) / sizeof(FontSpec); #ifdef notdef static FontSpec widthSpecs[] ={ { "condensed", 1, FC_WIDTH, FC_WIDTH_CONDENSED, "condensed"}, { "expanded", 3, FC_WIDTH, FC_WIDTH_EXPANDED, "*"}, { "extracondensed", 6, FC_WIDTH, FC_WIDTH_EXTRACONDENSED, "*"}, { "extraexpanded", 6, FC_WIDTH, FC_WIDTH_EXTRAEXPANDED, "*"}, { "normal", 1, FC_WIDTH, FC_WIDTH_NORMAL, "normal"}, { "semicondensed", 5, FC_WIDTH, FC_WIDTH_SEMICONDENSED, "semicondensed"}, { "semiexpanded", 5, FC_WIDTH, FC_WIDTH_SEMIEXPANDED, "*"}, { "ultracondensed", 6, FC_WIDTH, FC_WIDTH_ULTRACONDENSED, "*"}, { "ultraexpanded", 6, FC_WIDTH, FC_WIDTH_ULTRAEXPANDED, "*"}, }; static int nWidthSpecs = sizeof(widthSpecs) / sizeof(FontSpec); static FontSpec boolSpecs[] ={ { "antialias", 1, FC_ANTIALIAS, }, { "decorative", 1, FC_DECORATIVE, }, { "embeddedbitmap", 4, FC_EMBEDDED_BITMAP, }, { "embolden", 4, FC_EMBOLDEN, }, { "globaladvance", 1, FC_GLOBAL_ADVANCE, }, { "hinting", 1, FC_HINTING, }, { "minspace", 1, FC_MINSPACE, }, { "outline", 1, FC_OUTLINE, }, { "scalable", 1, FC_SCALABLE, }, { "verticallayout", 1, FC_VERTICAL_LAYOUT, }, }; static int nBoolSpecs = sizeof(boolSpecs) / sizeof(FontSpec); #endif static Blt_HashTable fontTable; static Blt_HashTable aliasTable; static int initialized = 0; static void GetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr); enum XLFDFields { XLFD_FOUNDRY, XLFD_FAMILY, XLFD_WEIGHT, XLFD_SLANT, XLFD_SETWIDTH, XLFD_ADD_STYLE, XLFD_PIXEL_SIZE, XLFD_POINT_SIZE, XLFD_RESOLUTION_X, XLFD_RESOLUTION_Y, XLFD_SPACING, XLFD_AVERAGE_WIDTH, XLFD_CHARSET, XLFD_NUMFIELDS }; /* * Freetype font container. */ typedef struct { char *name; /* Name of the font (malloc-ed). */ int refCount; /* Reference count for this structure. When * refCount reaches zero, it means to free the * resources associated with this * structure. */ Blt_HashEntry *hashPtr; /* Pointer to this entry in global font hash * table. Used to remove the entry from the * table. */ Blt_HashTable fontTable; /* Hash table containing an Xft font for each * angle it's used at. Will always contain a 0 * degree entry. */ Tk_Font tkfont; } RotatedFont; static double PointsToPixels(Tk_Window tkwin, int size) { double d; if (size < 0) { return -size; } d = size * 25.4 / 72.0; d *= WidthOfScreen(Tk_Screen(tkwin)); d /= WidthMMOfScreen(Tk_Screen(tkwin)); return d; } static double PixelsToPoints(Tk_Window tkwin, int size) { double d; if (size >= 0) { return size; } d = -size * 72.0 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); d /= WidthOfScreen(Tk_Screen(tkwin)); return d; } static void ParseXLFD(const char *fontName, int *argcPtr, char ***argvPtr) { char *p, *pend, *desc, *buf; size_t arrayLen, stringLen; int count; char **field; arrayLen = (sizeof(char *) * (XLFD_NUMFIELDS + 1)); stringLen = strlen(fontName); buf = Blt_AssertCalloc(1, arrayLen + stringLen + 1); desc = buf + arrayLen; strcpy(desc, fontName); field = (char **)buf; count = 0; for (p = desc, pend = p + stringLen; p < pend; p++, count++) { char *word; field[count] = NULL; /* Get the next word, separated by dashes (-). */ word = p; while ((*p != '\0') && (*p != '-')) { if (((*p & 0x80) == 0) && Tcl_UniCharIsUpper(UCHAR(*p))) { *p = (char)Tcl_UniCharToLower(UCHAR(*p)); } p++; } if (*p != '\0') { *p = '\0'; } if ((word[0] == '\0') || (((word[0] == '*') || (word[0] == '?')) && (word[1] == '\0'))) { continue; /* Field not specified. -- -*- -?- */ } field[count] = word; } /* * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common, * but it is (strictly) malformed, because the first * is eliding both the * Setwidth and the Addstyle fields. If the Addstyle field is a number, * then assume the above incorrect form was used and shift all the rest of * the fields right by one, so the number gets interpreted as a pixelsize. * This fix is so that we don't get a million reports that "it works under * X (as a native font name), but gives a syntax error under Windows (as a * parsed set of attributes)". */ if ((count > XLFD_ADD_STYLE) && (field[XLFD_ADD_STYLE] != NULL)) { int dummy; if (Tcl_GetInt(NULL, field[XLFD_ADD_STYLE], &dummy) == TCL_OK) { int j; for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) { field[j + 1] = field[j]; } field[XLFD_ADD_STYLE] = NULL; count++; } } *argcPtr = count; *argvPtr = field; field[XLFD_NUMFIELDS] = NULL; } /* *--------------------------------------------------------------------------- * * SearchForFontSpec -- * * Performs a binary search on the array of font specification to find a * partial, anchored match for the given option string. * * Results: * If the string matches unambiguously the index of the specification in * the array is returned. If the string does not match, even as an * abbreviation, any operation, -1 is returned. If the string matches, * but ambiguously -2 is returned. * *--------------------------------------------------------------------------- */ static int SearchForFontSpec(FontSpec *table, int nSpecs, const char *string, int length) { char c; int high, low; low = 0; high = nSpecs - 1; c = tolower((unsigned char)string[0]); while (low <= high) { FontSpec *sp; int compare; int median; median = (low + high) >> 1; sp = table + median; /* Test the first character */ compare = c - sp->name[0]; if (compare == 0) { /* Now test the entire string */ compare = strncasecmp(string, sp->name, length); if (compare == 0) { if ((int)length < sp->minChars) { return -2; /* Ambiguous spec name */ } } } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return median; /* Spec found. */ } } return -1; /* Can't find spec */ } static FontSpec * FindSpec(FontSpec *tablePtr, int nSpecs, const char *string, int length) { int n; n = SearchForFontSpec(tablePtr, nSpecs, string, length); if (n < 0) { if (n == -1) { fprintf(stderr, "unknown %s specification \"%s\"\n", tablePtr[n].key, string); } if (n == -2) { fprintf(stderr, "ambiguous %s specification \"%s\"\n", tablePtr[n].key, string); } return NULL; } return tablePtr + n; } typedef struct { const char *name, *aliases[10]; } FontAlias; static FontAlias xlfdFontAliases[] = { { "math", {"mathematica1", "courier"}}, { "serif", {"times"}}, { "sans serif", { "arial" }}, { "monospace", { "courier new" }}, { NULL } }; static void MakeAliasTable(Tk_Window tkwin) { Blt_HashTable familyTable; FontAlias *fp; FontAlias *table; Blt_InitHashTable(&familyTable, TCL_STRING_KEYS); GetFontFamilies(tkwin, &familyTable); Blt_InitHashTable(&aliasTable, TCL_STRING_KEYS); table = xlfdFontAliases; for(fp = table; fp->name != NULL; fp++) { Blt_HashEntry *hPtr; const char **alias; for (alias = fp->aliases; *alias != NULL; alias++) { hPtr = Blt_FindHashEntry(&familyTable, *alias); if (hPtr != NULL) { int isNew; hPtr = Blt_CreateHashEntry(&aliasTable, fp->name, &isNew); Blt_SetHashValue(hPtr, *alias); break; } } } Blt_DeleteHashTable(&familyTable); } static const char * GetAlias(const char *family) { Blt_HashEntry *hPtr; strtolower((char *)family); hPtr = Blt_FindHashEntry(&aliasTable, family); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return family; } static Blt_NameOfFontProc TkNameOfFontProc; static Blt_GetFontMetricsProc TkGetFontMetricsProc; static Blt_FontIdProc TkFontIdProc; static Blt_MeasureCharsProc TkMeasureCharsProc; static Blt_TextStringWidthProc TkTextStringWidthProc; static Blt_FreeFontProc TkFreeFontProc; static Blt_DrawCharsProc TkDrawCharsProc; static Blt_PostscriptFontNameProc TkPostscriptFontNameProc; static Blt_FamilyOfFontProc TkFamilyOfFontProc; static Blt_CanRotateFontProc TkCanRotateFontProc; static Blt_UnderlineCharsProc TkUnderlineCharsProc; static Blt_FontClass tkFontClass = { FONT_TK, TkNameOfFontProc, /* Blt_NameOfFontProc */ TkFamilyOfFontProc, /* Blt_FamilyOfFontProc */ TkFontIdProc, /* Blt_FontIdProc */ TkGetFontMetricsProc, /* Blt_GetFontMetricsProc */ TkMeasureCharsProc, /* Blt_MeasureCharsProc */ TkTextStringWidthProc, /* Blt_TexStringtWidthProc */ TkCanRotateFontProc, /* Blt_CanRotateFontProc */ TkDrawCharsProc, /* Blt_DrawCharsProc */ TkPostscriptFontNameProc, /* Blt_PostscriptFontNameProc */ TkFreeFontProc, /* Blt_FreeFontProc */ TkUnderlineCharsProc, /* Blt_UnderlineCharsProc */ }; static FontPattern * NewFontPattern(void) { FontPattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(FontPattern)); return patternPtr; } static void FreeFontPattern(FontPattern *patternPtr) { if (patternPtr->family != NULL) { Blt_Free((char *)patternPtr->family); } Blt_Free(patternPtr); } static int CALLBACK FontFamilyEnumProc( ENUMLOGFONT *lfPtr, /* Logical-font data. */ NEWTEXTMETRIC *tmPtr, /* Physical-font data (not used). */ int fontType, /* Type of font (not used). */ LPARAM lParam) /* Result object to hold result. */ { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; Tcl_DString ds; const char *faceName; Tcl_Encoding encoding; int isNew; tablePtr = (Blt_HashTable *)lParam; faceName = lfPtr->elfLogFont.lfFaceName; encoding = Tcl_GetEncoding(NULL, "Unicode"); Tcl_ExternalToUtfDString(encoding, faceName, -1, &ds); faceName = Tcl_DStringValue(&ds); strtolower((char *)faceName); hPtr = Blt_CreateHashEntry(tablePtr, faceName, &isNew); Blt_SetHashValue(hPtr, NULL); Tcl_DStringFree(&ds); return 1; } static void GetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr) { HDC hDC; HWND hWnd; Window window; window = Tk_WindowId(tkwin); hWnd = (window == None) ? (HWND)NULL : Tk_GetHWND(window); hDC = GetDC(hWnd); /* * On any version NT, there may fonts with international names. * Use the NT-only Unicode version of EnumFontFamilies to get the * font names. If we used the ANSI version on a non-internationalized * version of NT, we would get font names with '?' replacing all * the international characters. * * On a non-internationalized verson of 95, fonts with international * names are not allowed, so the ANSI version of EnumFontFamilies will * work. On an internationalized version of 95, there may be fonts with * international names; the ANSI version will work, fetching the * name in the system code page. Can't use the Unicode version of * EnumFontFamilies because it only exists under NT. */ if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { EnumFontFamiliesW(hDC, NULL, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)tablePtr); } else { EnumFontFamiliesA(hDC, NULL, (FONTENUMPROCA)FontFamilyEnumProc, (LPARAM)tablePtr); } ReleaseDC(hWnd, hDC); } /* *--------------------------------------------------------------------------- * * ParseTkDesc -- * * Parses an array of Tcl_Objs as a Tk style font description . * * "family [size] [optionList]" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a Tk font description. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static FontPattern * ParseTkDesc(int objc, Tcl_Obj **objv) { FontPattern *patternPtr; Tcl_Obj **aobjv; int aobjc; int i; patternPtr = NewFontPattern(); /* Font family. */ { char *family, *dash; family = Tcl_GetString(objv[0]); dash = strchr(family, '-'); if (dash != NULL) { int size; if (Tcl_GetInt(NULL, dash + 1, &size) != TCL_OK) { goto error; } patternPtr->size = size; } if (dash != NULL) { *dash = '\0'; } patternPtr->family = Blt_AssertStrdup(GetAlias(family)); if (dash != NULL) { *dash = '-'; i = 1; } objv++, objc--; } if (objc > 0) { int size; if (Tcl_GetIntFromObj(NULL, objv[0], &size) == TCL_OK) { patternPtr->size = size; objv++, objc--; } } aobjc = objc, aobjv = objv; if (objc > 0) { if (Tcl_ListObjGetElements(NULL, objv[0], &aobjc, &aobjv) != TCL_OK) { goto error; } } for (i = 0; i < aobjc; i++) { FontSpec *specPtr; const char *key; int length; key = Tcl_GetStringFromObj(aobjv[i], &length); specPtr = FindSpec(fontSpecs, nFontSpecs, key, length); if (specPtr == NULL) { goto error; } if (specPtr->key == NULL) { continue; } if (strcmp(specPtr->key, FC_WEIGHT) == 0) { patternPtr->weight = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_SLANT) == 0) { patternPtr->slant = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_SPACING) == 0) { patternPtr->spacing = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_WIDTH) == 0) { patternPtr->width = specPtr->oldvalue; } } return patternPtr; error: FreeFontPattern(patternPtr); return NULL; } /* *--------------------------------------------------------------------------- * * ParseNameValuePairs -- * * Given Tcl_Obj list of name value pairs, parse the list saving in the * values in a font pattern structure. * * "-family family -size size -weight weight" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a valid name-value list * describing a font. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static FontPattern * ParseNameValuePairs(Tcl_Interp *interp, Tcl_Obj *objPtr) { FontPattern *patternPtr; Tcl_Obj **objv; int objc; int i; if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split list or list is empty. */ } if (objc & 0x1) { return NULL; /* Odd number of elements in list. */ } patternPtr = NewFontPattern(); for (i = 0; i < objc; i += 2) { const char *key, *value; int length; key = Tcl_GetString(objv[i]); value = Tcl_GetStringFromObj(objv[i+1], &length); if (strcmp(key, "-family") == 0) { if (patternPtr->family != NULL) { Blt_Free(patternPtr->family); } patternPtr->family = Blt_AssertStrdup(GetAlias(value)); } else if (strcmp(key, "-size") == 0) { int size; if (Tcl_GetIntFromObj(interp, objv[i+1], &size) != TCL_OK) { goto error; } patternPtr->size = size; } else if (strcmp(key, "-weight") == 0) { FontSpec *specPtr; specPtr = FindSpec(weightSpecs, nWeightSpecs, value, length); if (specPtr == NULL) { goto error; } patternPtr->weight = specPtr->oldvalue; } else if (strcmp(key, "-slant") == 0) { FontSpec *specPtr; specPtr = FindSpec(slantSpecs, nSlantSpecs, value, length); if (specPtr == NULL) { goto error; } patternPtr->slant = specPtr->oldvalue; } else if (strcmp(key, "-spacing") == 0) { FontSpec *specPtr; specPtr = FindSpec(spacingSpecs, nSpacingSpecs, value, length); if (specPtr == NULL) { goto error; } patternPtr->spacing = specPtr->oldvalue; } else if (strcmp(key, "-hint") == 0) { /* Ignore */ } else if (strcmp(key, "-rgba") == 0) { /* Ignore */ } else if (strcmp(key, "-underline") == 0) { /* Ignore */ } else if (strcmp(key, "-overstrike") == 0) { /* Ignore */ } else { /* Ignore */ } } #if DEBUG_FONT_SELECTION fprintf(stderr, "found TkAttrList => Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif return patternPtr; error: FreeFontPattern(patternPtr); return NULL; } /* *--------------------------------------------------------------------------- * * ParseFontObj -- * * Given the name of a Tk font object, get its configuration values * save the data in a font pattern structure. * * "-family family -size size -weight weight" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a valid name-value list * describing a font. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static FontPattern * ParseFontObj(Tcl_Interp *interp, Tcl_Obj *objPtr) { FontPattern *patternPtr; Tcl_Obj *cmd[3]; int result; patternPtr = NULL; cmd[0] = Tcl_NewStringObj("font", -1); cmd[1] = Tcl_NewStringObj("configure", -1); cmd[2] = objPtr; Tcl_IncrRefCount(cmd[0]); Tcl_IncrRefCount(cmd[1]); Tcl_IncrRefCount(cmd[2]); result = Tcl_EvalObjv(interp, 3, cmd, 0); Tcl_DecrRefCount(cmd[2]); Tcl_DecrRefCount(cmd[1]); Tcl_DecrRefCount(cmd[0]); if (result == TCL_OK) { patternPtr = ParseNameValuePairs(interp, Tcl_GetObjResult(interp)); } Tcl_ResetResult(interp); #if DEBUG_FONT_SELECTION if (patternPtr != NULL) { fprintf(stderr, "found FontObject => Tk font \"%s\"\n", Tcl_GetString(objPtr)); } #endif return patternPtr; } /* *--------------------------------------------------------------------------- * * GetPattern -- * * Parses the font description so that the font can rewritten with an * aliased font name. This allows us to use * * "Sans Serif", "Serif", "Math", "Monospace" * * font names that correspond to the proper font regardless if the * standard X fonts or XFT fonts are being used. * * Leave XLFD font descriptions alone. Let users describe exactly the * font they wish. * *--------------------------------------------------------------------------- */ static FontPattern * GetPattern(Tcl_Interp *interp, Tcl_Obj *objPtr) { FontPattern *patternPtr; const char *desc; desc = Tcl_GetString(objPtr); while (isspace(UCHAR(*desc))) { desc++; /* Skip leading blanks. */ } if (*desc == '-') { /* * Case 1: XLFD font description or Tk attribute list. * * If the font description starts with a '-', it could be either an * old fashion XLFD font description or a Tk font attribute * option-value list. */ patternPtr = ParseNameValuePairs(interp, objPtr); if (patternPtr == NULL) { return NULL; /* XLFD font description */ } } else if (*desc == '*') { return NULL; /* XLFD font description */ } else if (strpbrk(desc, "::") != NULL) { patternPtr = ParseFontObj(interp, objPtr); } else { int objc; Tcl_Obj **objv; /* * Case 3: Tk-style description. */ if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split into a list or * list is empty. */ } patternPtr = NULL; if (objc == 1) { /* * Case 3a: Tk font object name. * * Assuming that Tk font object names won't contain whitespace, * see if its a font object. */ patternPtr = ParseFontObj(interp, objv[0]); } if (patternPtr == NULL) { /* * Case 3b: List of font attributes in the form "family size * ?attrs?" */ patternPtr = ParseTkDesc(objc, objv); } } return patternPtr; } static void WriteXLFDDescription(Tk_Window tkwin, FontPattern *patternPtr, Tcl_DString *resultPtr) { int size; /* Rewrite the font description using the aliased family. */ Tcl_DStringInit(resultPtr); /* Family */ if (patternPtr->family != NULL) { Tcl_DStringAppendElement(resultPtr, "-family"); Tcl_DStringAppendElement(resultPtr, patternPtr->family); } /* Weight */ if (patternPtr->weight != NULL) { Tcl_DStringAppendElement(resultPtr, "-weight"); Tcl_DStringAppendElement(resultPtr, patternPtr->weight); } /* Slant */ if (patternPtr->slant != NULL) { Tcl_DStringAppendElement(resultPtr, "-slant"); Tcl_DStringAppendElement(resultPtr, patternPtr->slant); } /* Width */ if (patternPtr->width != NULL) { Tcl_DStringAppendElement(resultPtr, "-width"); Tcl_DStringAppendElement(resultPtr, patternPtr->width); } /* Size */ Tcl_DStringAppendElement(resultPtr, "-size"); size = (int)(PointsToPixels(tkwin, patternPtr->size) + 0.5); size = patternPtr->size; Tcl_DStringAppendElement(resultPtr, Blt_Itoa(size)); } static Tk_Font OpenTkFont(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { Tk_Font tkFont; FontPattern *patternPtr; Blt_HashEntry *hPtr; const char *desc; desc = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&fontTable, desc); patternPtr = GetPattern(interp, objPtr); if (patternPtr == NULL) { tkFont = Tk_GetFont(interp, tkwin, Tcl_GetString(objPtr)); } else { Tcl_DString ds; /* Rewrite the font description using the aliased family. */ WriteXLFDDescription(tkwin, patternPtr, &ds); tkFont = Tk_GetFont(interp, tkwin, Tcl_DStringValue(&ds)); #if DEBUG_FONT_SELECTION fprintf(stderr, "Tkfont: %s => %s\n", Tcl_GetString(objPtr), Tcl_DStringValue(&ds)); #endif Tcl_DStringFree(&ds); FreeFontPattern(patternPtr); } return tkFont; } static const char * TkNameOfFontProc(_Blt_Font *fontPtr) { return Tk_NameOfFont(fontPtr->clientData); } static const char * TkFamilyOfFontProc(_Blt_Font *fontPtr) { return ((TkFont *)fontPtr->clientData)->fa.family; } static Font TkFontIdProc(_Blt_Font *fontPtr) { return Tk_FontId(fontPtr->clientData); } static void TkGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr) { TkFont *tkFontPtr = fontPtr->clientData; Tk_FontMetrics fm; Tk_GetFontMetrics(fontPtr->clientData, &fm); fmPtr->ascent = fm.ascent; fmPtr->descent = fm.descent; fmPtr->linespace = fm.linespace; fmPtr->tabWidth = tkFontPtr->tabWidth; fmPtr->underlinePos = tkFontPtr->underlinePos; fmPtr->underlineHeight = tkFontPtr->underlineHeight; } static int TkMeasureCharsProc(_Blt_Font *fontPtr, const char *text, int nBytes, int max, int flags, int *lengthPtr) { return Tk_MeasureChars(fontPtr->clientData, text, nBytes, max, flags, lengthPtr); } static int TkTextStringWidthProc(_Blt_Font *fontPtr, const char *string, int nBytes) { return Tk_TextWidth(fontPtr->clientData, string, nBytes); } static void TkDrawCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing characters. */ _Blt_Font *fontPtr, /* Font in which characters will be drawn; * must be the same as font used in GC. */ int depth, /* Not used. */ float angle, /* Not used. */ const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int nBytes, /* Number of bytes in string. */ int x, int y) /* Coordinates at which to place origin of * string when drawing. */ { Tk_DrawChars(display, drawable, gc, fontPtr->clientData, text, nBytes, x, y); } static int TkPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr) { return Tk_PostscriptFontName(fontPtr->clientData, resultPtr); } static int TkCanRotateFontProc(_Blt_Font *fontPtr, float angle) { return FALSE; } static void TkFreeFontProc(_Blt_Font *fontPtr) { Tk_FreeFont(fontPtr->clientData); Blt_Free(fontPtr); } /* *--------------------------------------------------------------------------- * * TkUnderlineCharsProc -- * * This procedure draws an underline for a given range of characters in a * given string. It doesn't draw the characters (which are assumed to * have been displayed previously); it just draws the underline. This * procedure would mainly be used to quickly underline a few characters * without having to construct an underlined font. To produce properly * underlined text, the appropriate underlined font should be constructed * and used. * * Results: * None. * * Side effects: * Information gets displayed in "drawable". * *--------------------------------------------------------------------------- */ static void TkUnderlineCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for actually drawing * line. */ _Blt_Font *fontPtr, /* Font used in GC; must have been * allocated by Tk_GetFont(). Used for * character dimensions, etc. */ const char *string, /* String containing characters to be * underlined or overstruck. */ int textLen, /* Unused. */ int x, int y, /* Coordinates at which first character of * string is drawn. */ int first, /* Byte offset of the first character. */ int last, /* Byte offset after the last character. */ int xMax) { Tk_UnderlineChars(display, drawable, gc, fontPtr->clientData, string, x, y, first, last); } static Blt_NameOfFontProc WinNameOfFontProc; static Blt_GetFontMetricsProc WinGetFontMetricsProc; static Blt_FontIdProc WinFontIdProc; static Blt_MeasureCharsProc WinMeasureCharsProc; static Blt_TextStringWidthProc WinTextStringWidthProc; static Blt_FreeFontProc WinFreeFontProc; static Blt_DrawCharsProc WinDrawCharsProc; static Blt_PostscriptFontNameProc WinPostscriptFontNameProc; static Blt_FamilyOfFontProc WinFamilyOfFontProc; static Blt_CanRotateFontProc WinCanRotateFontProc; static Blt_UnderlineCharsProc WinUnderlineCharsProc; static Blt_FontClass winFontClass = { FONT_WIN, WinNameOfFontProc, /* Blt_NameOfFontProc */ WinFamilyOfFontProc, /* Blt_FamilyOfFontProc */ WinFontIdProc, /* Blt_FontIdProc */ WinGetFontMetricsProc, /* Blt_GetFontMetricsProc */ WinMeasureCharsProc, /* Blt_MeasureCharsProc */ WinTextStringWidthProc, /* Blt_TextStringWidthProc */ WinCanRotateFontProc, /* Blt_CanRotateFontProc */ WinDrawCharsProc, /* Blt_DrawCharsProc */ WinPostscriptFontNameProc, /* Blt_PostscriptFontNameProc */ WinFreeFontProc, /* Blt_FreeFontProc */ WinUnderlineCharsProc, /* Blt_UnderlineCharsProc */ }; /* *--------------------------------------------------------------------------- * * CreateRotatedFont -- * * Creates a rotated copy of the given font. This only works for * TrueType fonts. * * Results: * Returns the newly create font or NULL if the font could not be * created. * *--------------------------------------------------------------------------- */ static HFONT CreateRotatedFont( TkFont *fontPtr, /* Font identifier (actually a Tk_Font) */ long angle10) { /* Number of degrees to rotate font */ TkFontAttributes *faPtr; /* Set of attributes to match. */ HFONT hfont; LOGFONTW lf; faPtr = &fontPtr->fa; ZeroMemory(&lf, sizeof(LOGFONT)); lf.lfHeight = -faPtr->size; if (lf.lfHeight < 0) { HDC dc; dc = GetDC(NULL); lf.lfHeight = -MulDiv(faPtr->size, GetDeviceCaps(dc, LOGPIXELSY), 72); ReleaseDC(NULL, dc); } lf.lfWidth = 0; lf.lfEscapement = lf.lfOrientation = angle10; #define TK_FW_NORMAL 0 lf.lfWeight = (faPtr->weight == TK_FW_NORMAL) ? FW_NORMAL : FW_BOLD; lf.lfItalic = faPtr->slant; lf.lfUnderline = faPtr->underline; lf.lfStrikeOut = faPtr->overstrike; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfQuality = ANTIALIASED_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; hfont = NULL; if (faPtr->family == NULL) { lf.lfFaceName[0] = '\0'; } else { #if (_TCL_VERSION >= _VERSION(8,1,0)) Tcl_DString dString; Tcl_Encoding encoding; encoding = Tcl_GetEncoding(NULL, "unicode"); Tcl_UtfToExternalDString(encoding, faPtr->family, -1, &dString); if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { Tcl_UniChar *src, *dst; /* * We can only store up to LF_FACESIZE wide characters */ if (Tcl_DStringLength(&dString) >= (LF_FACESIZE * sizeof(WCHAR))) { Tcl_DStringSetLength(&dString, LF_FACESIZE); } src = (Tcl_UniChar *)Tcl_DStringValue(&dString); dst = (Tcl_UniChar *)lf.lfFaceName; while (*src != '\0') { *dst++ = *src++; } *dst = '\0'; hfont = CreateFontIndirectW((LOGFONTW *)&lf); } else { /* * We can only store up to LF_FACESIZE characters */ if (Tcl_DStringLength(&dString) >= LF_FACESIZE) { Tcl_DStringSetLength(&dString, LF_FACESIZE); } strcpy((char *)lf.lfFaceName, Tcl_DStringValue(&dString)); hfont = CreateFontIndirectA((LOGFONTA *)&lf); } Tcl_DStringFree(&dString); #else strncpy((char *)lf.lfFaceName, faPtr->family, LF_FACESIZE - 1); lf.lfFaceName[LF_FACESIZE] = '\0'; #endif /* _TCL_VERSION >= 8.1.0 */ } if (hfont == NULL) { #if WINDEBUG PurifyPrintf("can't create font: %s\n", Blt_LastError()); #endif } else { HFONT oldFont; TEXTMETRIC tm; HDC hdc; int result; /* Check if the rotated font is really a TrueType font. */ hdc = GetDC(NULL); /* Get the desktop device context */ oldFont = SelectFont(hdc, hfont); result = ((GetTextMetrics(hdc, &tm)) && (tm.tmPitchAndFamily & TMPF_TRUETYPE)); SelectFont(hdc, oldFont); ReleaseDC(NULL, hdc); if (!result) { #if WINDEBUG PurifyPrintf("not a true type font\n"); #endif DeleteFont(hfont); return NULL; } } return hfont; } static void DestroyFont(RotatedFont *rotFontPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&rotFontPtr->fontTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { HFONT hfont; hfont = Blt_GetHashValue(hPtr); DeleteFont(hfont); } Tk_FreeFont(rotFontPtr->tkfont); Blt_DeleteHashTable(&rotFontPtr->fontTable); Blt_DeleteHashEntry(&fontTable, rotFontPtr->hashPtr); Blt_Free(rotFontPtr); } /* *--------------------------------------------------------------------------- * * GetRotatedFontFromObj -- * * Opens a Tk font based on the description in the Tcl_Obj. We first * parse the description and if necessary rewrite it using the proper * font aliases. The font names * * "Sans Serif", "Serif", "Math", "Monospace" * * correspond to the proper font regardless if the standard X fonts or * XFT fonts are being used. * * Leave XLFD font descriptions alone. Let users describe exactly the * font they wish. * * Outside of reimplementing the Tk font mechanism, rewriting the * font allows use to better handle programs that must work with * X servers with and without the XRender extension. It means * that the widget's default font settings do not have to use * XLFD fonts even if XRender is available. * *--------------------------------------------------------------------------- */ static RotatedFont * GetRotatedFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { Blt_HashEntry *hPtr; RotatedFont *rotFontPtr; const char *desc; int isNew; desc = Tcl_GetString(objPtr); while (isspace(UCHAR(*desc))) { desc++; /* Skip leading blanks. */ } /* Is the font already in the cache? */ hPtr = Blt_CreateHashEntry(&fontTable, desc, &isNew); if (isNew) { Tk_Font tkFont; tkFont = OpenTkFont(interp, tkwin, objPtr); if (tkFont == NULL) { Blt_DeleteHashEntry(&fontTable, hPtr); return NULL; } rotFontPtr = Blt_AssertMalloc(sizeof(RotatedFont)); rotFontPtr->refCount = 1; rotFontPtr->tkfont = tkFont; rotFontPtr->name = Blt_AssertStrdup(desc); Blt_SetHashValue(hPtr, rotFontPtr); Blt_InitHashTable(&rotFontPtr->fontTable, BLT_ONE_WORD_KEYS); } else { rotFontPtr = Tcl_GetHashValue(hPtr); rotFontPtr->refCount++; } return rotFontPtr; } static const char * WinNameOfFontProc(_Blt_Font *fontPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; return Tk_NameOfFont(rotFontPtr->tkfont); } static const char * WinFamilyOfFontProc(_Blt_Font *fontPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; return ((TkFont *)rotFontPtr->tkfont)->fa.family; } static Font WinFontIdProc(_Blt_Font *fontPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; return Tk_FontId(rotFontPtr->tkfont); } static void WinGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; TkFont *tkFontPtr = (TkFont *)rotFontPtr->tkfont; Tk_FontMetrics fm; Tk_GetFontMetrics(rotFontPtr->tkfont, &fm); fmPtr->ascent = fm.ascent; fmPtr->descent = fm.descent; fmPtr->linespace = fm.linespace; fmPtr->tabWidth = tkFontPtr->tabWidth; fmPtr->underlinePos = tkFontPtr->underlinePos; fmPtr->underlineHeight = tkFontPtr->underlineHeight; } static int WinMeasureCharsProc(_Blt_Font *fontPtr, const char *text, int nBytes, int max, int flags, int *lengthPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; return Tk_MeasureChars(rotFontPtr->tkfont, text, nBytes, max, flags, lengthPtr); } static int WinTextStringWidthProc(_Blt_Font *fontPtr, const char *text, int nBytes) { RotatedFont *rotFontPtr = fontPtr->clientData; return Tk_TextWidth(rotFontPtr->tkfont, text, nBytes); } static void WinDrawCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing characters. */ _Blt_Font *fontPtr, /* Font in which characters will be drawn; * must be the same as font used in GC. */ int depth, /* Not used. */ float angle, /* Not used. */ const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int nBytes, /* Number of bytes in string. */ int x, int y) /* Coordinates at which to place origin of * string when drawing. */ { RotatedFont *rotFontPtr = fontPtr->clientData; if (angle != 0.0) { long angle10; Blt_HashEntry *hPtr; angle *= 10.0f; angle10 = ROUND(angle); hPtr = Blt_FindHashEntry(&rotFontPtr->fontTable, (char *)angle10); if (hPtr == NULL) { fprintf(stderr, "can't find font %s at %g rotated\n", rotFontPtr->name, angle); return; /* Can't find instance at requested angle. */ } display->request++; if (drawable != None) { HDC hdc; HFONT hfont; TkWinDCState state; hfont = Blt_GetHashValue(hPtr); hdc = TkWinGetDrawableDC(display, drawable, &state); Blt_TextOut(hdc, gc, hfont, text, nBytes, x, y); TkWinReleaseDrawableDC(drawable, hdc, &state); } } else { Tk_DrawChars(display, drawable, gc, rotFontPtr->tkfont, text, nBytes, x, y); } } static int WinPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; return Tk_PostscriptFontName(rotFontPtr->tkfont, resultPtr); } static int WinCanRotateFontProc(_Blt_Font *fontPtr, float angle) { Blt_HashEntry *hPtr; HFONT hfont; RotatedFont *rotFontPtr = fontPtr->clientData; int isNew; long angle10; angle *= 10.0f; angle10 = ROUND(angle); if (angle == 0L) { return TRUE; } hPtr = Blt_CreateHashEntry(&rotFontPtr->fontTable, (char *)angle10, &isNew); if (!isNew) { return TRUE; /* Rotated font already exists. */ } hfont = CreateRotatedFont((TkFont *)Blt_FontId(fontPtr), angle10); if (hfont == NULL) { Blt_DeleteHashEntry(&rotFontPtr->fontTable, hPtr); return FALSE; } Blt_SetHashValue(hPtr, hfont); return TRUE; } static void WinFreeFontProc(_Blt_Font *fontPtr) { RotatedFont *rotFontPtr = fontPtr->clientData; rotFontPtr->refCount--; if (rotFontPtr->refCount <= 0) { DestroyFont(rotFontPtr); } } /* *--------------------------------------------------------------------------- * * WinUnderlineCharsProc -- * * This procedure draws an underline for a given range of characters in a * given string. It doesn't draw the characters (which are assumed to * have been displayed previously); it just draws the underline. This * procedure would mainly be used to quickly underline a few characters * without having to construct an underlined font. To produce properly * underlined text, the appropriate underlined font should be constructed * and used. * * Results: * None. * * Side effects: * Information gets displayed in "drawable". * *--------------------------------------------------------------------------- */ static void WinUnderlineCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for actually drawing * line. */ _Blt_Font *fontPtr, /* Font used in GC; must have been * allocated by Tk_GetFont(). Used for * character dimensions, etc. */ const char *string, /* String containing characters to be * underlined or overstruck. */ int textLen, /* Unused. */ int x, int y, /* Coordinates at which first character of * string is drawn. */ int first, /* Byte offset of the first character. */ int last, /* Byte offset after the last character. */ int xMax) { RotatedFont *rotFontPtr = fontPtr->clientData; Tk_UnderlineChars(display, drawable, gc, rotFontPtr->tkfont, string, x, y, first, last); } /* *--------------------------------------------------------------------------- * * Blt_GetFontFromObj -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: * The return value is token for the font, or NULL if an error prevented * the font from being created. If NULL is returned, an error message * will be left in the interp's result. * * Side effects: * The font is added to an internal database with a reference count. For * each call to this procedure, there should eventually be a call to * Tk_FreeFont() or Tk_FreeFontFromObj() so that the database is cleaned * up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ Blt_Font Blt_GetFontFromObj( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For display on which font will be used. */ Tcl_Obj *objPtr) /* String describing font, as: named font, * native format, or parseable string. */ { _Blt_Font *fontPtr; fontPtr = Blt_Calloc(1, sizeof(_Blt_Font)); if (fontPtr == NULL) { return NULL; /* Out of memory. */ } if (!initialized) { Blt_InitHashTable(&fontTable, BLT_STRING_KEYS); MakeAliasTable(tkwin); initialized++; } fontPtr->clientData = OpenTkFont(interp, tkwin, objPtr); if (fontPtr->clientData == NULL) { Blt_Free(fontPtr); #if DEBUG_FONT_SELECTION fprintf(stderr, "FAILED to find either Xft or Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif return NULL; /* Failed to find either Xft or Tk fonts. */ } fontPtr->classPtr = &tkFontClass; #ifdef notdef fontPtr->clientData = GetRotatedFontFromObj(interp, tkwin, objPtr); #if DEBUG_FONT_SELECTION fprintf(stderr, "SUCCESS: Found Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif fontPtr->classPtr = &winFontClass; #endif fontPtr->interp = interp; fontPtr->display = Tk_Display(tkwin); return fontPtr; /* Found Tk font. */ } Blt_Font Blt_AllocFontFromObj( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For screen on which font will be used. */ Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { return Blt_GetFontFromObj(interp, tkwin, objPtr); } /* *--------------------------------------------------------------------------- * * Blt_GetFont -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: * The return value is token for the font, or NULL if an error prevented * the font from being created. If NULL is returned, an error message * will be left in interp's result object. * * Side effects: * The font is added to an internal database with a reference count. For * each call to this procedure, there should eventually be a call to * Blt_FreeFont so that the database is cleaned up when fonts aren't in * use anymore. * *--------------------------------------------------------------------------- */ Blt_Font Blt_GetFont( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For screen on which font will be used. */ const char *string) /* Object describing font, as: named font, * native format, or parseable string. */ { Blt_Font font; Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, strlen(string)); Tcl_IncrRefCount(objPtr); font = Blt_GetFontFromObj(interp, tkwin, objPtr); Tcl_DecrRefCount(objPtr); return font; } Tcl_Interp * Blt_GetFontInterp(_Blt_Font *fontPtr) { return fontPtr->interp; } int Blt_TextWidth(_Blt_Font *fontPtr, const char *string, int length) { if (Blt_Ps_IsPrinting()) { int width; width = Blt_Ps_TextWidth(fontPtr, string, length); if (width >= 0) { return width; } } return (*fontPtr->classPtr->textWidth)(fontPtr, string, length); } void Blt_GetFontMetrics(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr) { if (Blt_Ps_IsPrinting()) { if (Blt_Ps_GetFontMetrics(fontPtr, fmPtr) == TCL_OK) { return; } } return (*fontPtr->classPtr->getFontMetrics)(fontPtr, fmPtr); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVecInt.h�������������������������������������������������������������������0000644�0001750�0001750�00000020350�11462120063�015071� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVecInt.h -- * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include <bltChain.h> #include <bltVector.h> #define VECTOR_THREAD_KEY "BLT Vector Data" #define VECTOR_MAGIC ((unsigned int) 0x46170277) /* These defines allow parsing of different types of indices */ #define INDEX_SPECIAL (1<<0) /* Recognize "min", "max", and "++end" as * valid indices */ #define INDEX_COLON (1<<1) /* Also recognize a range of indices separated * by a colon */ #define INDEX_CHECK (1<<2) /* Verify that the specified index or range of * indices are within limits */ #define INDEX_ALL_FLAGS (INDEX_SPECIAL | INDEX_COLON | INDEX_CHECK) #define SPECIAL_INDEX -2 #define FFT_NO_CONSTANT (1<<0) #define FFT_BARTLETT (1<<1) #define FFT_SPECTRUM (1<<2) typedef struct { Blt_HashTable vectorTable; /* Table of vectors */ Blt_HashTable mathProcTable; /* Table of vector math functions */ Blt_HashTable indexProcTable; Tcl_Interp *interp; unsigned int nextId; } VectorInterpData; /* * Vector -- * * A vector is an array of double precision values. It can be accessed * through a TCL command, a TCL array variable, or C API. The storage for * the array points initially to a statically allocated buffer, but to * malloc-ed memory if more is necessary. * * Vectors can be shared by several clients (for example, two different * graph widgets). The data is shared. When a client wants to use a * vector, it allocates a vector identifier, which identifies the client. * Clients use this ID to specify a callback routine to be invoked * whenever the vector is modified or destroyed. Whenever the vector is * updated or destroyed, each client is notified of the change by their * callback routine. */ typedef struct { /* * If you change these fields, make sure you change the definition of * Blt_Vector in bltInt.h and blt.h too. */ double *valueArr; /* Array of values (malloc-ed) */ int length; /* Current number of values in the array. */ int size; /* Maximum number of values that can be stored * in the value array. */ double min, max; /* Minimum and maximum values in the vector */ int dirty; /* Indicates if the vector has been updated */ int reserved; /* The following fields are local to this module */ const char *name; /* The namespace-qualified name of the vector. * It points to the hash key allocated for the * entry in the vector hash table. */ VectorInterpData *dataPtr; Tcl_Interp *interp; /* Interpreter associated with the * vector */ Blt_HashEntry *hashPtr; /* If non-NULL, pointer in a hash table to * track the vectors in use. */ Tcl_FreeProc *freeProc; /* Address of procedure to call to release * storage for the value array, Optionally can * be one of the following: TCL_STATIC, * TCL_DYNAMIC, or TCL_VOLATILE. */ const char *arrayName; /* The name of the TCL array variable mapped * to the vector (malloc'ed). If NULL, * indicates that the vector isn't mapped to * any variable */ Tcl_Namespace *nsPtr; /* Namespace context of the vector itself. */ int offset; /* Offset from zero of the vector's starting * index */ Tcl_Command cmdToken; /* Token for vector's TCL command. */ Blt_Chain chain; /* List of clients using this vector */ int notifyFlags; /* Notification flags. See definitions * below */ int varFlags; /* Indicate if the variable is global, * namespace, or local */ int freeOnUnset; /* For backward compatibility only: If * non-zero, free the vector when its variable * is unset. */ int flush; int first, last; /* Selected region of vector. This is used * mostly for the math routines */ } Vector; #define NOTIFY_UPDATED ((int)BLT_VECTOR_NOTIFY_UPDATE) #define NOTIFY_DESTROYED ((int)BLT_VECTOR_NOTIFY_DESTROY) #define NOTIFY_NEVER (1<<3) /* Never notify clients of updates to * the vector */ #define NOTIFY_ALWAYS (1<<4) /* Notify clients after each update * of the vector is made */ #define NOTIFY_WHENIDLE (1<<5) /* Notify clients at the next idle point * that the vector has been updated. */ #define NOTIFY_PENDING (1<<6) /* A do-when-idle notification of the * vector's clients is pending. */ #define NOTIFY_NOW (1<<7) /* Notify clients of changes once * immediately */ #define NOTIFY_WHEN_MASK (NOTIFY_NEVER|NOTIFY_ALWAYS|NOTIFY_WHENIDLE) #define UPDATE_RANGE (1<<9) /* The data of the vector has changed. * Update the min and max limits when * they are needed */ #define FindRange(array, first, last, min, max) \ { \ min = max = 0.0; \ if (first <= last) { \ register int i; \ min = max = array[first]; \ for (i = first + 1; i <= last; i++) { \ if (min > array[i]) { \ min = array[i]; \ } else if (max < array[i]) { \ max = array[i]; \ } \ } \ } \ } BLT_EXTERN void Blt_Vec_InstallSpecialIndices(Blt_HashTable *tablePtr); BLT_EXTERN void Blt_Vec_InstallMathFunctions(Blt_HashTable *tablePtr); BLT_EXTERN void Blt_Vec_UninstallMathFunctions(Blt_HashTable *tablePtr); BLT_EXTERN VectorInterpData *Blt_Vec_GetInterpData (Tcl_Interp *interp); BLT_EXTERN double Blt_Vec_Max(Vector *vecObjPtr); BLT_EXTERN double Blt_Vec_Min(Vector *vecObjPtr); BLT_EXTERN Vector *Blt_Vec_New(VectorInterpData *dataPtr); BLT_EXTERN int Blt_Vec_Duplicate(Vector *destPtr, Vector *srcPtr); BLT_EXTERN int Blt_Vec_SetLength(Tcl_Interp *interp, Vector *vPtr, int length); BLT_EXTERN int Blt_Vec_SetSize(Tcl_Interp *interp, Vector *vPtr, int size); BLT_EXTERN int Blt_Vec_ChangeLength(Tcl_Interp *interp, Vector *vPtr, int length); BLT_EXTERN Vector *Blt_Vec_ParseElement(Tcl_Interp *interp, VectorInterpData *dataPtr, const char *start, const char **endPtr, int flags); BLT_EXTERN void Blt_Vec_Free(Vector *vPtr); BLT_EXTERN size_t *Blt_Vec_SortMap(Vector **vectors, int nVectors); BLT_EXTERN int Blt_Vec_LookupName(VectorInterpData *dataPtr, const char *vecName, Vector **vPtrPtr); BLT_EXTERN Vector *Blt_Vec_Create(VectorInterpData *dataPtr, const char *name, const char *cmdName, const char *varName, int *newPtr); BLT_EXTERN void Blt_Vec_UpdateRange(Vector *vPtr); BLT_EXTERN void Blt_Vec_UpdateClients(Vector *vPtr); BLT_EXTERN void Blt_Vec_FlushCache(Vector *vPtr); BLT_EXTERN int Blt_Vec_Reset(Vector *vPtr, double *dataArr, int nValues, int arraySize, Tcl_FreeProc *freeProc); BLT_EXTERN int Blt_Vec_GetIndex(Tcl_Interp *interp, Vector *vPtr, const char *string, int *indexPtr, int flags, Blt_VectorIndexProc **procPtrPtr); BLT_EXTERN int Blt_Vec_GetIndexRange(Tcl_Interp *interp, Vector *vPtr, const char *string, int flags, Blt_VectorIndexProc **procPtrPtr); BLT_EXTERN int Blt_Vec_MapVariable(Tcl_Interp *interp, Vector *vPtr, const char *name); BLT_EXTERN int Blt_Vec_FFT(Tcl_Interp *interp, Vector *realPtr, Vector *phasesPtr, Vector *freqPtr, double delta, int flags, Vector *srcPtr); BLT_EXTERN int Blt_Vec_InverseFFT(Tcl_Interp *interp, Vector *iSrcPtr, Vector *rDestPtr, Vector *iDestPtr, Vector *srcPtr); BLT_EXTERN Tcl_ObjCmdProc Blt_Vec_InstCmd; BLT_EXTERN Tcl_VarTraceProc Blt_Vec_VarTrace; BLT_EXTERN Tcl_IdleProc Blt_Vec_NotifyClients; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictPbm.c������������������������������������������������������������������0000644�0001750�0001750�00000060707�11462120062�015243� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictPbm.c -- * * This module implements PBM file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #include <tcl.h> #include <stdlib.h> #include <limits.h> #include <ctype.h> #include <bltAlloc.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include "bltPicture.h" #include "bltPictFmts.h" #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifdef _MSC_VER #define vsnprintf _vsnprintf #endif #include <setjmp.h> typedef struct _Blt_Picture Picture; #define TRUE 1 #define FALSE 0 #define div257(t) (((t)+((t)>>8))>>8) #define SetBit(x) destRowPtr[(x>>3)] |= (0x80 >>(x&7)) #define GetBit(x) srcRowPtr[(x>>3)] & (0x80 >> (x&7)) typedef struct { jmp_buf jmpbuf; Tcl_DString errors; Tcl_DString warnings; int nWarnings, nErrors; } PbmMessage; typedef struct { unsigned int version; /* Version of PBM file */ unsigned int maxval; /* Maximum intensity allowed. */ unsigned int width, height; /* Dimensions of the image. */ unsigned int bitsPerPixel; /* # bits per pixel. */ unsigned int isRaw; /* Indicates if the image format is raw or * plain. */ Blt_DBuffer dbuffer; /* */ unsigned char *data; /* Start of raw data */ unsigned int bytesPerRow; Blt_Picture picture; } Pbm; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int imageIndex; float gamma; } PbmImportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; Blt_Pixel bg; int index; } PbmExportSwitches; #define MAXCOLORS 256 enum PbmVersions { PBM_UNKNOWN, PBM_PLAIN, /* Monochrome: 1-bit per pixel */ PGM_PLAIN, /* 8-bits per pixel */ PPM_PLAIN, /* 24-bits per pixel */ PBM_RAW, /* 1-bit per pixel */ PGM_RAW, /* 8/16-bits per pixel */ PPM_RAW /* 24/48 bits per pixel */ }; static const char *pbmFormat[] = { "???", "pbmplain", "pgmplain", "ppmplain", "pbmraw", "pgmraw", "ppmraw", }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PbmImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PbmImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PbmImportSwitches, imageIndex), 0}, {BLT_SWITCH_FLOAT, "-gamma", "number", Blt_Offset(PbmImportSwitches, gamma), 0}, {BLT_SWITCH_END} }; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PbmExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PbmExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(PbmExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PbmExportSwitches, index), 0}, {BLT_SWITCH_END} }; static PbmMessage *pbmMessagePtr; DLLEXPORT extern Tcl_AppInitProc Blt_PicturePbmInit; /*ARGSUSED*/ static void PbmError TCL_VARARGS_DEF(const char *, arg1) { char string[BUFSIZ+4]; const char *fmt; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&pbmMessagePtr->errors, string, -1); va_end(args); longjmp(pbmMessagePtr->jmpbuf, 0); } /*ARGSUSED*/ static void PbmWarning TCL_VARARGS_DEF(const char *, arg1) { char string[BUFSIZ+4]; const char *fmt; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&pbmMessagePtr->warnings, string, -1); va_end(args); pbmMessagePtr->nWarnings++; } static char * PbmComment(char *bp) { char *p; p = bp; if (*p == '#') { /* Comment: file end of line */ while((*p != '\n') && (p != '\0')) { p++; } PbmWarning("comment: %.*s\n", p-bp, bp); } return p; } static unsigned int PbmNextValue(Pbm *pbmPtr) { char *p, *endp; unsigned int value; p = (char *)Blt_DBuffer_Pointer(pbmPtr->dbuffer); while(isspace(*p)) { p++; } if (*p == '#') { p = PbmComment(p); } while(isspace(*p)) { p++; } value = strtoul(p, &endp, 10); if (endp == p) { PbmError("bad value in %s image data", pbmFormat[pbmPtr->version]); } if (value > pbmPtr->maxval) { PbmError("value (%d) greater than %s image max value %d", value, pbmFormat[pbmPtr->version], pbmPtr->maxval); } while (isspace(*p)) { p++; } Blt_DBuffer_SetPointer(pbmPtr->dbuffer, (unsigned char*)p); return value; } static inline int PbmGetShort(unsigned char *bp) { return (bp[0] << 8) + bp[1]; } static Picture * PbmPlainData(Pbm *pbmPtr) { Picture *destPtr; pbmPtr->picture = destPtr = Blt_CreatePicture(pbmPtr->width, pbmPtr->height); switch (pbmPtr->bitsPerPixel) { case 1: /* Monochrome */ case 8: /* Greyscale */ { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { dp->Red = dp->Green = dp->Blue = PbmNextValue(pbmPtr); dp->Alpha = ALPHA_OPAQUE; } destRowPtr += destPtr->pixelsPerRow; } } break; case 16: /* Greyscale (2 bytes) */ { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { unsigned int value; value = PbmNextValue(pbmPtr); dp->Red = dp->Green = dp->Blue = div257(value); dp->Alpha = ALPHA_OPAQUE; } destRowPtr += destPtr->pixelsPerRow; } } break; case 24: /* Color (1 byte per color component) */ { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { dp->Red = PbmNextValue(pbmPtr); dp->Green = PbmNextValue(pbmPtr); dp->Blue = PbmNextValue(pbmPtr); dp->Alpha = ALPHA_OPAQUE; } destRowPtr += destPtr->pixelsPerRow; } } break; case 48: /* Color (2 bytes per color component) */ { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { int r, g, b; r = PbmNextValue(pbmPtr); g = PbmNextValue(pbmPtr); b = PbmNextValue(pbmPtr); dp->Red = div257(r); dp->Green = div257(g); dp->Blue = div257(b); dp->Alpha = ALPHA_OPAQUE; } destRowPtr += destPtr->pixelsPerRow; } } break; } return destPtr; } static Picture * PbmRawData(Pbm *pbmPtr) { Picture *destPtr; pbmPtr->picture = destPtr = Blt_CreatePicture(pbmPtr->width, pbmPtr->height); switch (pbmPtr->bitsPerPixel) { case 1: { /* Monochrome */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { int x; Blt_Pixel *dp; dp = destRowPtr; for (x = 0; x < pbmPtr->width; x++) { dp->Red = dp->Green = dp->Blue = (GetBit(x)) ? 0xFF : 0; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 8: { /* Greyscale (1 byte) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp++, dp++) { dp->Red = dp->Green = dp->Blue = *sp; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 16: { /* Greyscale (2 bytes) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 2, dp++) { unsigned int value; value = PbmGetShort(sp); dp->Red = dp->Green = dp->Blue = div257(value); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 24: { /* Color (1 byte per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 3, dp++) { dp->Red = sp[0]; dp->Green = sp[1]; dp->Blue = sp[2]; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 48: { /* Color (2 bytes per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 6, dp++) { unsigned int r, g, b; r = PbmGetShort(sp); g = PbmGetShort(sp+2); b = PbmGetShort(sp+4); dp->Red = div257(r); dp->Green = div257(g); dp->Blue = div257(b); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } } return destPtr; } static Blt_Picture PbmImage(Pbm *pbmPtr) { char *bp, *p; const char *type; size_t size, want; unsigned char *start; Blt_Picture picture; size = Blt_DBuffer_BytesLeft(pbmPtr->dbuffer); start = Blt_DBuffer_Pointer(pbmPtr->dbuffer); if (size < 14) { PbmError("can't read PBM image: short file %d bytes", size); } bp = (char *)start; if ((bp[0] != 'P') || (bp[1] < '1') || (bp[1] > '6')) { PbmError("unknown PBM image header (%c%c).", bp[0], bp[1]); } pbmPtr->version = bp[1] - '0'; pbmPtr->isRaw = (pbmPtr->version > 2); switch(pbmPtr->version) { case PBM_PLAIN: /* P2 */ case PBM_RAW: /* P5 */ pbmPtr->bitsPerPixel = 8; break; case PGM_PLAIN: /* P1 */ case PGM_RAW: /* P4 */ pbmPtr->bitsPerPixel = 1; break; case PPM_PLAIN: /* P3 */ case PPM_RAW: /* P6 */ pbmPtr->bitsPerPixel = 24; break; } type = pbmFormat[pbmPtr->version]; if (!isspace(bp[2])) { PbmError("no white space after version in %s header.", type); } p = bp + 3; if (*p == '#') { p = PbmComment(p); } pbmPtr->width = strtoul(p, &p, 10); if (pbmPtr->width == 0) { PbmError("bad %s width specification %s", type, bp+3); } if (!isspace(*p)) { PbmError("no white space after width in %s header.", type); } p++; if (*p == '#') { p = PbmComment(p); } pbmPtr->height = strtoul(p, &p, 10); if (pbmPtr->height == 0) { PbmError("bad %s height specification", type); } if (!isspace(*p)) { PbmError("no white space after height in %s header.", type); } p++; if (*p == '#') { p = PbmComment(p); } if (pbmPtr->bitsPerPixel != 1) { pbmPtr->maxval = strtoul(p, &p, 10); if (pbmPtr->maxval == 0) { PbmError("bad %s maxval specification", type); } if (!isspace(*p)) { PbmError("no white space after maxval in %s header.", type); } p++; if (*p == '#') { p = PbmComment(p); } if (pbmPtr->maxval >= USHRT_MAX) { PbmError("invalid %s maxval specification", type); } if (pbmPtr->maxval > 255) { pbmPtr->bitsPerPixel <<= 1; /* 16-bit greyscale or 48 bit color. */ } } pbmPtr->data = (unsigned char *)p; pbmPtr->bytesPerRow = ((pbmPtr->bitsPerPixel * pbmPtr->width) + 7) / 8; want = (pbmPtr->data - start) + pbmPtr->height * pbmPtr->bytesPerRow; if ((pbmPtr->isRaw) && (want > Blt_DBuffer_BytesLeft(pbmPtr->dbuffer))) { PbmError("short %s file: expected %d bytes, got %d", type, want, Blt_DBuffer_BytesLeft(pbmPtr->dbuffer)); } if (pbmPtr->isRaw) { picture = PbmRawData(pbmPtr); Blt_DBuffer_SetPointer(pbmPtr->dbuffer, pbmPtr->data + (pbmPtr->height * pbmPtr->bytesPerRow)); } else { picture = PbmPlainData(pbmPtr); } return picture; } /* *--------------------------------------------------------------------------- * * IsPbm -- * * Attempts to parse a PBM file header. * * Results: * Returns 1 is the header is PBM and 0 otherwise. Note that * the validity of the header contents is not checked here. That's * done in PbmToPictures. * *--------------------------------------------------------------------------- */ static int IsPbm(Blt_DBuffer dbuffer) { unsigned char *bp; Blt_DBuffer_ResetCursor(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < 2) { return FALSE; } bp = Blt_DBuffer_Pointer(dbuffer); if ((bp[0] != 'P') || (bp[1] < '1') || (bp[1] > '6')) { return FALSE; } return TRUE; } /* *--------------------------------------------------------------------------- * * PbmToPictures -- * * Reads a PBM file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such * as the designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain PbmToPictures(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PbmImportSwitches *switchesPtr) { Blt_Chain chain; Blt_Picture picture; Pbm pbm; PbmMessage message; pbmMessagePtr = &message; message.nWarnings = 0; memset(&pbm, 0, sizeof(pbm)); /* Clear the structure. */ pbm.dbuffer = dbuffer; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); Tcl_DStringAppend(&message.errors, "error reading \"", -1); Tcl_DStringAppend(&message.errors, fileName, -1); Tcl_DStringAppend(&message.errors, "\": ", -1); Tcl_DStringAppend(&message.warnings, "\"", -1); Tcl_DStringAppend(&message.warnings, fileName, -1); Tcl_DStringAppend(&message.warnings, "\": ", -1); if (setjmp(message.jmpbuf)) { Tcl_DStringResult(interp, &message.errors); Tcl_DStringFree(&message.warnings); if (pbm.picture != NULL) { Blt_FreePicture(pbm.picture); } return NULL; } chain = NULL; if (!IsPbm(pbm.dbuffer)) { PbmError("bad PBM header"); } Blt_DBuffer_ResetCursor(pbm.dbuffer); chain = Blt_Chain_Create(); while (Blt_DBuffer_BytesLeft(pbm.dbuffer) > 0) { picture = PbmImage(&pbm); Blt_Chain_Append(chain, picture); } if (switchesPtr->gamma != 1.0) { Blt_GammaCorrectPicture(picture, picture, switchesPtr->gamma); } if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "PBM_READ_WARNINGS", Tcl_DStringValue(&message.warnings), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); Tcl_DStringFree(&message.errors); return chain; } /* *--------------------------------------------------------------------------- * * PicturesToPbm -- * * Reads an PBM file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such as the designated * file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static int PictureToPbm(Tcl_Interp *interp, Blt_Picture original, Blt_DBuffer dbuffer, PbmExportSwitches *switchesPtr) { Picture *srcPtr; srcPtr = original; if (srcPtr->flags & BLT_PIC_MASK) { Blt_Picture background; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(srcPtr); } if (srcPtr->flags & BLT_PIC_COLOR) { /* Color */ Blt_Pixel *srcRowPtr; int bytesPerRow; int y; unsigned char *destRowPtr; Blt_DBuffer_Print(dbuffer, "P%d\n%d\n%d\n255\n", PPM_RAW, srcPtr->width, srcPtr->height); bytesPerRow = srcPtr->width * 3; Blt_DBuffer_Extend(dbuffer, srcPtr->height * bytesPerRow); destRowPtr = Blt_DBuffer_End(dbuffer); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp += 3; } destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } } else { /* Greyscale */ Blt_Pixel *srcRowPtr; int bytesPerRow; int y; unsigned char *destRowPtr; Blt_DBuffer_Print(dbuffer, "P%d\n%d\n%d\n255\n", PGM_RAW, srcPtr->width, srcPtr->height); bytesPerRow = srcPtr->width; Blt_DBuffer_Extend(dbuffer, srcPtr->height * bytesPerRow); destRowPtr = Blt_DBuffer_End(dbuffer); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { dp[0] = sp->Red; dp++; } destRowPtr += bytesPerRow; srcRowPtr += srcPtr->pixelsPerRow; } } Blt_DBuffer_SetLength(dbuffer, Blt_DBuffer_Size(dbuffer)); if (srcPtr != original) { Blt_FreePicture(srcPtr); } return TCL_OK; } static Blt_Chain ReadPbm(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { PbmImportSwitches switches; memset(&switches, 0, sizeof(switches)); switches.imageIndex = 1; switches.gamma = 1.0; return PbmToPictures(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WritePbm(Tcl_Interp *interp, Blt_Picture picture) { Blt_ChainLink link; Blt_DBuffer dbuffer; PbmExportSwitches switches; Tcl_Obj *objPtr; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* white */ dbuffer = Blt_DBuffer_Create(); objPtr = NULL; picture = Blt_Chain_GetValue(link); if (PictureToPbm(interp, picture, dbuffer, &switches) == TCL_OK) { char *bytes; bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } } Blt_DBuffer_Destroy(dbuffer); return objPtr; } static Blt_Chain ImportPbm(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_DBuffer dbuffer; Blt_Chain chain; PbmImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); switches.imageIndex = 1; switches.gamma = 1.0; if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_LoadFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = PbmToPictures(interp, string, dbuffer, &switches); error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportPbm(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer dbuffer; Blt_Picture picture; PbmExportSwitches switches; int result; memset(&switches, 0, sizeof(switches)); switches.index = index; switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data switch.", (char *)NULL); return TCL_ERROR; } /* FIXME: handle -all option. */ picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "bad picture index.", (char *)NULL); return TCL_ERROR; } dbuffer = Blt_DBuffer_Create(); if (PictureToPbm(interp, picture, dbuffer, &switches) != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } /* Write the PBM data to file or convert it to a base64 string. */ if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; result = TCL_ERROR; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); result = TCL_OK; } } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PicturePbmInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_pbm", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "pbm", /* Name of format. */ IsPbm, /* Discovery routine. */ ReadPbm, /* Read format procedure. */ WritePbm, /* Write format procedure. */ ImportPbm, /* Import format procedure. */ ExportPbm); /* Export format switches. */ } ���������������������������������������������������������./saods9/blt3.0.1/src/bltDtMysql.c������������������������������������������������������������������0000644�0001750�0001750�00000027724�11462120062�015304� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtMysql.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #ifndef NO_DATATABLE #include "config.h" #ifdef HAVE_LIBMYSQL #include <tcl.h> #include <bltDataTable.h> #include <bltAlloc.h> #include <bltSwitch.h> #include <mysql/mysql.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ DLLEXPORT extern Tcl_AppInitProc Blt_Table_MysqlInit; /* * Format Import Export * csv file/data file/data * tree data data * vector data data * xml file/data file/data * mysql data data * * $table import csv -file fileName -data dataString * $table export csv -file defaultFileName * $table import tree $treeName $node ?switches? * $table export tree $treeName $node "label" "label" "label" * $table import vector $vecName label $vecName label... * $table export vector label $vecName label $vecName... * $table import xml -file fileName -data dataString ?switches? * $table export xml -file fileName -data dataString ?switches? * $table import mysql -host $host -password $pw -db $db -port $port */ /* * ImportSwitches -- */ typedef struct { char *host; /* If non-NULL, name of remote host of * MySql server. Otherwise "localhost" * is used. */ char *user; /* If non-NULL, name of user account * to access MySql server. Otherwise * the current username is used. */ char *pw; /* If non-NULL, is password to use to * access MySql server. */ char *db; /* If non-NULL, name of MySql database * to access. */ Tcl_Obj *query; /* If non-NULL, query to make. */ int port; /* Port number to use. */ /* Private data. */ Tcl_Interp *interp; unsigned int flags; char *buffer; /* Buffer to read data into. */ int nBytes; /* # of bytes in the buffer. */ } ImportSwitches; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_STRING, "-db", "dbName", Blt_Offset(ImportSwitches, db), 0, 0}, {BLT_SWITCH_STRING, "-host", "hostName", Blt_Offset(ImportSwitches, host), 0, 0}, {BLT_SWITCH_STRING, "-user", "userName", Blt_Offset(ImportSwitches, user), 0, 0}, {BLT_SWITCH_STRING, "-password", "password", Blt_Offset(ImportSwitches, pw), 0, 0}, {BLT_SWITCH_INT_NNEG, "-port", "number", Blt_Offset(ImportSwitches, port), 0, 0}, {BLT_SWITCH_OBJ, "-query", "string", Blt_Offset(ImportSwitches, query), 0, 0}, {BLT_SWITCH_END} }; #ifdef EXPORT_MYSQL /* * ExportSwitches -- */ typedef struct { Blt_Chain rowChain; Blt_Chain colChain; Tcl_Obj *rows, *cols; /* Selected rows and columns to export. */ unsigned int flags; Tcl_Obj *fileObj; Tcl_Channel channel; /* If non-NULL, channel to write output to. */ Tcl_DString *dsPtr; int length; /* Length of dynamic string. */ int count; /* Number of fields in current record. */ Tcl_Interp *interp; char *quote; /* Quoted string delimiter. */ char *sep; /* Separator character. */ } ExportSwitches; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-columns", "columns", Blt_Offset(ExportSwitches, cols), 0, 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(ExportSwitches, fileObj), 0, 0}, {BLT_SWITCH_STRING, "-quote", "char", Blt_Offset(ExportSwitches, quote), 0, 0}, {BLT_SWITCH_OBJ, "-rows", "rows", Blt_Offset(ExportSwitches, rows), 0, 0}, {BLT_SWITCH_STRING, "-separator", "char", Blt_Offset(ExportSwitches, sep), 0, 0}, {BLT_SWITCH_END} }; static Blt_TableExportProc ExportMysqlProc; #endif #define DEF_CLIENT_FLAGS (CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS) static Blt_TableImportProc ImportMysqlProc; static Blt_TableColumnType MySqlFieldToColumnType(int type) { switch (type) { case FIELD_TYPE_LONG: case FIELD_TYPE_LONGLONG: return TABLE_COLUMN_TYPE_LONG; case FIELD_TYPE_DECIMAL: case FIELD_TYPE_TINY: case FIELD_TYPE_SHORT: case FIELD_TYPE_INT24: return TABLE_COLUMN_TYPE_INT; case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: return TABLE_COLUMN_TYPE_DOUBLE; case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_BLOB: return TABLE_COLUMN_TYPE_UNKNOWN; case FIELD_TYPE_NULL: case FIELD_TYPE_TIMESTAMP: case FIELD_TYPE_DATE: case FIELD_TYPE_TIME: case FIELD_TYPE_DATETIME: case FIELD_TYPE_YEAR: case FIELD_TYPE_NEWDATE: case FIELD_TYPE_ENUM: case FIELD_TYPE_SET: case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: default: return TABLE_COLUMN_TYPE_STRING; } } static int MySqlImportLabels(Tcl_Interp *interp, Blt_Table table, MYSQL_RES *myResults, size_t nCols, Blt_TableColumn *cols) { size_t i; for (i = 0; i < nCols; i++) { MYSQL_FIELD *fp; Blt_TableColumnType type; fp = mysql_fetch_field(myResults); if (Blt_Table_SetColumnLabel(interp, table, cols[i], fp->name) != TCL_OK) { return TCL_ERROR; } type = MySqlFieldToColumnType(fp->type); if (Blt_Table_SetColumnType(table, cols[i], type) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int MySqlImportRows(Tcl_Interp *interp, Blt_Table table, MYSQL_RES *myResults, size_t nCols, Blt_TableColumn *cols) { size_t nRows; size_t i; nRows = mysql_num_rows(myResults); if (nRows > Blt_Table_NumRows(table)) { size_t needed; /* Add the number of rows needed */ needed = nRows - Blt_Table_NumRows(table); if (Blt_Table_ExtendRows(interp, table, needed, NULL) != TCL_OK) { return TCL_ERROR; } } for (i = 1; /*empty*/; i++) { Blt_TableRow row; size_t j; MYSQL_ROW myRow; unsigned long *fieldLengths; myRow = mysql_fetch_row(myResults); if (myRow == NULL) { if (i < nRows) { Tcl_AppendResult(interp, "didn't complete fetching all rows", (char *)NULL); return TCL_ERROR; } break; } fieldLengths = mysql_fetch_lengths(myResults); row = Blt_Table_FindRowByIndex(table, i); for (j = 0; j < nCols; j++) { int result; Tcl_Obj *objPtr; if (myRow[j] == NULL) { continue; /* Empty value. */ } objPtr = Tcl_NewByteArrayObj((unsigned char *)myRow[j], (int)fieldLengths[j]); Tcl_IncrRefCount(objPtr); result = Blt_Table_SetObj(table, row, cols[j], objPtr); Tcl_DecrRefCount(objPtr); if (result != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } static void MySqlDisconnect(MYSQL *cp) { mysql_close(cp); } static int MySqlQueryFromObj(Tcl_Interp *interp, MYSQL *cp, Tcl_Obj *objPtr) { int nBytes; const char *query; query = Tcl_GetStringFromObj(objPtr, &nBytes); if (mysql_real_query(cp, query, (unsigned long)nBytes) != 0) { Tcl_AppendResult(interp, "error in query \"", query, "\": ", mysql_error(cp), (char *)NULL); return TCL_ERROR; } return TCL_OK; } static void MySqlFreeResults(MYSQL_RES *myResults) { mysql_free_result (myResults); } static int MySqlResults(Tcl_Interp *interp, MYSQL *cp, MYSQL_RES **resultsPtr, long *nFieldsPtr) { MYSQL_RES *results; results = mysql_store_result(cp); if (results != NULL) { *nFieldsPtr = mysql_num_fields(results); } else if (mysql_field_count(cp) == 0) { *nFieldsPtr = 0; } else { Tcl_AppendResult(interp, "error collecting results: ", mysql_error(cp), (char *)NULL); return TCL_ERROR; } *resultsPtr = results; return TCL_OK; } static int MySqlConnect(Tcl_Interp *interp, const char *host, const char *user, const char *pw, const char *db, unsigned int port, unsigned long flags, MYSQL **cpPtr) { MYSQL *cp; /* Connection handler. */ cp = mysql_init(NULL); if (cp == NULL) { Tcl_AppendResult(interp, "can't initialize mysql connection.", (char *)NULL); return TCL_ERROR; } if (host == NULL) { host = "localhost"; } cp->reconnect = 1; #if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 32200 /* 3.22 and up */ if (mysql_real_connect(cp, host, user, pw, db, port, NULL, flags) == NULL) { Tcl_AppendResult(interp, "can't connect to mysql server on \"", host, "\": ", mysql_error(cp), (char *)NULL); return TCL_ERROR; } #else /* pre-3.22 */ if (mysql_real_connect (cp, host, user, pw, port, NULL, flags) == NULL) { Tcl_AppendResult(interp, "can't connect to mysql server on \"", host, "\": ", mysql_error(cp), (char *)NULL); return TCL_ERROR; } if (db != NULL) { if (mysql_select_db(cp, db) != 0) { Tcl_AppendResult(interp, "can't select database \"", db, "\": ", mysql_error(cp), (char *)NULL); mysql_close(cp); cp = NULL; return TCL_ERROR; } } #endif *cpPtr = cp; return TCL_OK; } static int ImportMysqlProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ImportSwitches switches; MYSQL *cp; MYSQL_RES *myResults; long nCols; Blt_TableColumn *cols; myResults = NULL; cp = NULL; cols = NULL; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (MySqlConnect(interp, switches.host, switches.user, switches.pw, switches.db, switches.port, DEF_CLIENT_FLAGS, &cp) != TCL_OK) { goto error; } if (switches.query == NULL) { goto done; } if (MySqlQueryFromObj(interp, cp, switches.query) != TCL_OK) { goto error; } if (MySqlResults(interp, cp, &myResults, &nCols) != TCL_OK) { goto error; } /* Step 1. Create columns to hold the new values. Label * the columns using the title. */ cols = Blt_AssertMalloc(nCols * sizeof(Blt_TableColumn)); if (Blt_Table_ExtendColumns(interp, table, nCols, cols) != TCL_OK) { goto error; } if (MySqlImportLabels(interp, table, myResults, nCols, cols) != TCL_OK) { goto error; } if (MySqlImportRows(interp, table, myResults, nCols, cols) != TCL_OK) { goto error; } Blt_Free(cols); MySqlFreeResults(myResults); done: MySqlDisconnect(cp); Blt_FreeSwitches(importSwitches, &switches, 0); return TCL_OK; error: if (myResults != NULL) { MySqlFreeResults(myResults); } if (cols != NULL) { Blt_Free(cols); } if (cp != NULL) { MySqlDisconnect(cp); } Blt_FreeSwitches(importSwitches, &switches, 0); return TCL_ERROR; } #ifdef EXPORT_MYSQL static int ExportMysqlProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return TCL_OK; } #endif int Blt_Table_MysqlInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_datatable_mysql", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_Table_RegisterFormat(interp, "mysql", /* Name of format. */ ImportMysqlProc, /* Import procedure. */ NULL); /* Export procedure. */ } #endif /* HAVE_LIBMYSQL */ #endif /* NO_DATATABLE */ ��������������������������������������������./saods9/blt3.0.1/src/bltUnixPainter.c��������������������������������������������������������������0000644�0001750�0001750�00000151553�11462120063�016154� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixPainter.c -- * * This module implements X11-specific image processing procedures for the BLT * toolkit. * * Copyright (c) 1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the Tk library * distrubution. The photo image type was designed and implemented by Paul * Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #include "bltInt.h" #include "bltHash.h" #include "bltPicture.h" #include "bltUnixPainter.h" #include "bltPainter.h" #include <X11/Xutil.h> #include <X11/Xproto.h> typedef struct _Blt_Picture Pict; #define CFRAC(i, n) ((i) * 65535 / (n)) /* As for CFRAC, but apply exponent of g. */ #define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) #define MAXIMAGESIZE(dpy) (XMaxRequestSize(dpy) << 2) - 24 #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) static Blt_HashTable painterTable; static int initialized = 0; #define COLOR_WINDOW (1<<0) #define BLACK_AND_WHITE (1<<1) #define MAP_COLORS (1<<2) /* * PainterKey -- * * This structure represents the key used to uniquely identify painters. A * painter is specified by a combination of display, visual, colormap, depth, * and monitor gamma value. */ typedef struct { Display *display; /* Display of painter. Used to free * colors allocated. */ Visual *visualPtr; /* Visual information for the class of * windows displaying the image. */ Colormap colormap; /* Colormap used. This may be the * default colormap, or an allocated * private map. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value for the * monitor. */ } PainterKey; #define GC_PRIVATE 1 /* Indicates if the GC in the painter * was shared (allocated by Tk_GetGC) or * private (by XCreateGC). */ static Tcl_FreeProc FreePainter; /* *--------------------------------------------------------------------------- * * FindShift -- * * Returns the position of the least significant (low) bit in the given * mask. * * For TrueColor and DirectColor visuals, a pixel value is formed by * OR-ing the red, green, and blue colormap indices into a single 32-bit * word. The visual's color masks tell you where in the word the indices * are supposed to be. The masks contain bits only where the index is * found. By counting the leading zeros in the mask, we know how many * bits to shift to the individual red, green, and blue values to form a * pixel. * * Results: * The number of the least significant bit. * *--------------------------------------------------------------------------- */ static int FindShift(unsigned int mask) /* 32-bit word */ { int bit; for (bit = 0; bit < 32; bit++) { if (mask & (1 << bit)) { break; } } return bit; } /* *--------------------------------------------------------------------------- * * CountBits -- * * Returns the number of bits set in the given 32-bit mask. * * Reference: Graphics Gems Volume II. * * Results: * The number of bits to set in the mask. * *--------------------------------------------------------------------------- */ static int CountBits(unsigned long mask) /* 32 1-bit tallies */ { /* 16 2-bit tallies */ mask = (mask & 0x55555555) + ((mask >> 1) & (0x55555555)); /* 8 4-bit tallies */ mask = (mask & 0x33333333) + ((mask >> 2) & (0x33333333)); /* 4 8-bit tallies */ mask = (mask & 0x07070707) + ((mask >> 4) & (0x07070707)); /* 2 16-bit tallies */ mask = (mask & 0x000F000F) + ((mask >> 8) & (0x000F000F)); /* 1 32-bit tally */ mask = (mask & 0x0000001F) + ((mask >> 16) & (0x0000001F)); return mask; } /* *--------------------------------------------------------------------------- * * ComputeGammaTables -- * * Initializes both the power and inverse power tables for the painter with * a given gamma value. These tables are used to/from map linear RGB * values to/from non-linear monitor intensities. * * Results: * The *gammaTable* and *igammaTable* arrays are filled out to * contain the mapped values. * *--------------------------------------------------------------------------- */ static void ComputeGammaTables(Painter *p) { int i; double igamma, gamma; gamma = (double)p->gamma; igamma = 1.0 / gamma; for (i = 0; i < 256; i++) { double value, y; y = i / 255.0; value = pow(y, gamma) * 255.0 + 0.5; p->gammaTable[i] = (unsigned char)CLAMP(value); value = pow(y, igamma) * 255.0 + 0.5; p->igammaTable[i] = (unsigned char)CLAMP(value); } } /* *--------------------------------------------------------------------------- * * QueryPalette -- * * Queries the X display server for the colors currently used in the * colormap. These values will then be used to map screen pixels back to * RGB values (see Blt_DrawableToPicture). The queried non-linear color * intensities are reverse mapped back to to linear RGB values. * * Results: * The *palette* array is filled in with the RGB color values of the * colors allocated. * *--------------------------------------------------------------------------- */ static void QueryPalette(Painter *p, Blt_Pixel *palette) { Visual *visualPtr; XColor colors[256]; visualPtr = p->visualPtr; assert(visualPtr->map_entries <= 256); if ((visualPtr->class == DirectColor) || (visualPtr->class == TrueColor)) { XColor *cp, *cend; int nRed, nGreen, nBlue; unsigned int r, g, b; r = g = b = 0; nRed = (p->rMask >> p->rShift) + 1; nGreen = (p->gMask >> p->gShift) + 1; nBlue = (p->bMask >> p->bShift) + 1; for (cp = colors, cend = cp + visualPtr->map_entries; cp < cend; cp++) { cp->pixel = ((r << p->rShift)|(g << p->gShift) | (b << p->bShift)); cp->pad = 0; r++, b++, g++; if (r >= nRed) { r = 0; } if (g >= nGreen) { g = 0; } if (b >= nBlue) { b = 0; } } } else { XColor *cp; int i; for (cp = colors, i = 0; i < visualPtr->map_entries; i++, cp++) { cp->pixel = i; cp->pad = 0; } } XQueryColors(p->display, p->colormap, colors, visualPtr->map_entries); /* Scale to convert XColor component value (0..65535) to unsigned * char (0..255). */ if (p->gamma == 1.0f) { Blt_Pixel *dp; XColor *cp; int i; double a; a = 1.0 / 257.0; cp = colors, dp = palette; for (i = 0; i < visualPtr->map_entries; i++) { dp->Red = (unsigned char)(cp->red * a + 0.5); dp->Green = (unsigned char)(cp->green * a + 0.5); dp->Blue = (unsigned char)(cp->blue * a + 0.5); cp++, dp++; } } else { Blt_Pixel *dp; XColor *cp; int i; double a; a = 1.0 / 257.0; cp = colors, dp = palette; for (i = 0; i < visualPtr->map_entries; i++) { dp->Red = p->gammaTable[(int)(cp->red * a + 0.5)]; dp->Green = p->gammaTable[(int)(cp->green * a + 0.5)]; dp->Blue = p->gammaTable[(int)(cp->blue * a + 0.5)]; cp++, dp++; } } } /* *--------------------------------------------------------------------------- * * ColorRamp -- * * Computes a smooth color ramp based upon the number of colors available * for each color component. It returns an array of the desired colors * (XColor structures). The screen gamma is factored into the desired * colors. * * Results: * Returns the number of colors desired. The *colors* array is filled * out to contain the component values. * *--------------------------------------------------------------------------- */ static int ColorRamp(Painter *p, XColor *colors) { int nColors; XColor *cp; double rScale, gScale, bScale; double igamma; int i; nColors = 0; /* Suppress compiler warning. */ /* * Calculate the RGB coordinates of the colors we want to allocate and * store them in *colors. */ igamma = 1.0 / (double)p->gamma; rScale = 255.0 / (p->nRed - 1); gScale = 255.0 / (p->nGreen - 1); bScale = 255.0 / (p->nBlue - 1); switch (p->visualPtr->class) { case TrueColor: case DirectColor: nColors = MAX3(p->nRed, p->nGreen, p->nBlue); if (p->isMonochrome) { nColors = p->nBlue = p->nGreen = p->nRed; } /* Compute the 16-bit RGB values from each possible 8-bit value. */ cp = colors; for (i = 0; i < nColors; i++) { int r, g, b; r = (int)(i * rScale + 0.5); g = (int)(i * gScale + 0.5); b = (int)(i * bScale + 0.5); r = p->igammaTable[r]; g = p->igammaTable[g]; b = p->igammaTable[b]; cp->red = (r << 8) + r; cp->green = (g << 8) + g; cp->blue = (b << 8) + b; cp++; } break; case PseudoColor: case StaticColor: case GrayScale: case StaticGray: nColors = (p->nRed * p->nGreen * p->nBlue); if (p->isMonochrome) { nColors = p->nRed; } if (!p->isMonochrome) { XColor *cp; int i; cp = colors; for (i = 0; i < p->nRed; i++) { int j; unsigned char r; r = (unsigned char)(i * rScale + 0.5); r = p->igammaTable[r]; for (j = 0; j < p->nGreen; j++) { int k; unsigned int g; g = (unsigned char)(j * gScale + 0.5); g = p->igammaTable[g]; for (k = 0; k < p->nBlue; k++) { unsigned int b; b = (unsigned char)(k * bScale + 0.5); b = p->igammaTable[b]; cp->red = (r << 8) | r; cp->green = (g << 8) | g; cp->blue = (b << 8) | b; cp++; } } } } break; default: /* Monochrome */ { XColor *cp; double scale; int i; scale = 255.0 / (nColors - 1); cp = colors; for (i = 0; i < nColors; ++i) { int c; c = (int)(i * scale + 0.5); c = p->igammaTable[c]; cp->red = cp->green = cp->blue = (c << 8) | c; cp++; } } } /* end switch */ return nColors; } /* *--------------------------------------------------------------------------- * * AllocateColors -- * * Individually allocates each of the desired colors (as specified by the * *colors* array). If a color can't be allocated the desired colors * allocated to that point as released, the number of component * intensities is reduced, and 0 is returned. * * For TrueColor visuals, we don't need to allocate colors at all, since * we can compute them directly. * * Results: * Returns 1 if all desired colors were allocated successfully. If * unsuccessful, returns 0. All colors allocated up to that point are * freed and a smaller color palette size is computed and reset in the * painter structure. * *--------------------------------------------------------------------------- */ static int AllocateColors(Painter *p, XColor *colors, int nColors) { if (p->visualPtr->class == TrueColor) { XColor *cp, *cend; /* * For TrueColor visuals, don't call XAllocColor, compute the pixel * value directly. */ for (cp = colors, cend = cp + nColors; cp < cend; cp++) { unsigned int r, g, b; r = ((cp->red >> 8) >> p->rAdjust); g = ((cp->green >> 8) >> p->gAdjust); b = ((cp->blue >> 8) >> p->bAdjust); /* Shift each color into the proper location of the pixel index. */ r = (r << p->rShift) & p->rMask; g = (g << p->gShift) & p->gMask; b = (b << p->bShift) & p->bMask; cp->pixel = (r | g | b); } p->nPixels = 0; /* This will indicate that we didn't use * XAllocColor to obtain pixel * values. */ return TRUE; } else { int i; XColor *cp; cp = colors; for (i = 0; i < nColors; i++) { if (!XAllocColor(p->display, p->colormap, cp)){ #ifdef notdef fprintf(stderr, "can't allocate color #%d: r=%x g=%x b=%x\n", i, cp->red, cp->green, cp->blue); #endif break; } #ifdef notdef fprintf(stderr, "picture: allocated r=%x g=%x b=%x\n", colors[i].red, colors[i].green, colors[i].blue); #endif p->pixels[i] = cp->pixel; cp++; } p->nPixels = i; /* # of pixels in array */ if (i == nColors) { fprintf(stderr, "painter palette %d/%d/%d colors okay\n", p->nRed, p->nGreen, p->nBlue); return TRUE; /* Success. */ } } /* * If we didn't get all of the colors, free the current palette, reduce * the palette RGB component sizes. */ #ifdef notdef fprintf(stderr, "can't allocate %d/%d/%d colors\n", p->nRed, p->nGreen, p->nBlue); #endif XFreeColors(p->display, p->colormap, p->pixels, p->nPixels, 0); return FALSE; } /* *--------------------------------------------------------------------------- * * FillPalette -- * * Base upon the colors allocated, generate two mappings from the * picture's 8-bit RGB components. * * 1) Map 8-bit RGB values to the bits of the pixel. Each component * contains a portion of the pixel value. For mapped visuals * (pseudocolor, staticcolor, grayscale, and staticgray) this pixel * value will be translated to the actual pixel used by the display. * * 2) Map 8-bit RGB values to the actual color values used. The * color ramp generated may be only a subset of the possible * color values. The resulting palette is used in dithering the * image, using the error between the desired picture RGB value * and the actual value used. * * Results: * Color palette and pixel maps are filled in. * *--------------------------------------------------------------------------- */ static void FillPalette(Painter *p, XColor *colors, int nColors) { p->nColors = nColors; if (!p->isMonochrome) { p->flags |= COLOR_WINDOW; if ((p->visualPtr->class != DirectColor) && (p->visualPtr->class != TrueColor)) { p->flags |= MAP_COLORS; } } if (p->isMonochrome) { int i; for (i = 0; i < 256; i++) { int c; c = (i + 127) / 255; p->rBits[i] = colors[c].pixel; p->palette[i].Blue = p->palette[i].Green = p->palette[i].Red = (unsigned char)(c * 255 + 0.5); } } else { int i, rMult; double rScale, gScale, bScale; rMult = p->nGreen * p->nBlue; rScale = 255.0 / (p->nRed - 1); gScale = 255.0 / (p->nGreen - 1); bScale = 255.0 / (p->nBlue - 1); for (i = 0; i < 256; i++) { int r, g, b; r = (i * (p->nRed - 1) + 127) / 255; g = (i * (p->nGreen - 1) + 127) / 255; b = (i * (p->nBlue - 1) + 127) / 255; if ((p->visualPtr->class == DirectColor) || (p->visualPtr->class == TrueColor)) { p->rBits[i] = colors[r].pixel & p->rMask; p->gBits[i] = colors[g].pixel & p->gMask; p->bBits[i] = colors[b].pixel & p->bMask; } else { p->rBits[i] = r * rMult; p->gBits[i] = g * p->nBlue; p->bBits[i] = b; } p->palette[i].Red = (unsigned char)(r * rScale + 0.5); p->palette[i].Green = (unsigned char)(g * gScale + 0.5); p->palette[i].Blue = (unsigned char)(b * bScale + 0.5); } } } /* *--------------------------------------------------------------------------- * * AllocatePalette -- * * This procedure allocates the colors required by a color table, and * sets up the fields in the color table data structure which are used in * dithering. * * This routine essentially mimics what is done in tkImgPhoto.c. It's * purpose is to allocate exactly the same color ramp as the photo * image. That way both image types can co-exist without fighting over * available colors. * * Results: * None. * * Side effects: * Colors are allocated from the X server. The color palette and pixel * indices are updated. * *--------------------------------------------------------------------------- */ static void AllocatePalette(Painter *p) /* Pointer to the color table requiring * colors to be allocated. */ { XColor colors[256]; int nColors; static int stdPalettes[13][3] = { /* nRed, nGreen, nBlue */ { 2, 2, 2 }, /* 3 bits, 8 colors */ { 2, 3, 2 }, /* 4 bits, 12 colors */ { 3, 4, 2 }, /* 5 bits, 24 colors */ { 4, 5, 3 }, /* 6 bits, 60 colors */ { 5, 6, 4 }, /* 7 bits, 120 colors */ { 7, 7, 4 }, /* 8 bits, 198 colors */ { 8, 10, 6 }, /* 9 bits, 480 colors */ { 10, 12, 8 }, /* 10 bits, 960 colors */ { 14, 15, 9 }, /* 11 bits, 1890 colors */ { 16, 20, 12 }, /* 12 bits, 3840 colors */ { 20, 24, 16 }, /* 13 bits, 7680 colors */ { 26, 30, 20 }, /* 14 bits, 15600 colors */ { 32, 32, 30 }, /* 15 bits, 30720 colors */ }; p->isMonochrome = FALSE; switch (p->visualPtr->class) { case TrueColor: case DirectColor: p->nRed = 1 << CountBits(p->rMask); p->nGreen = 1 << CountBits(p->gMask); p->nBlue = 1 << CountBits(p->bMask); break; case GrayScale: case StaticGray: case PseudoColor: case StaticColor: if (p->depth > 15) { p->nRed = p->nGreen = p->nBlue = 32; } else if (p->depth >= 3) { int *ip = stdPalettes[p->depth - 3]; p->nRed = ip[0]; p->nGreen = ip[1]; p->nBlue = ip[2]; } break; default: p->nGreen = p->nBlue = 0; p->nRed = 1 << p->depth; p->isMonochrome = TRUE; break; } /* * Each time around this loop, we reduce the number of colors we're trying * to allocate until we succeed in allocating all of the colors we need. */ for (;;) { /* * If we are using 1 bit/pixel, we don't need to allocate any colors (we * just use the foreground and background colors in the GC). */ if ((p->isMonochrome) && (p->nRed <= 2)) { p->flags |= BLACK_AND_WHITE; /* return; */ } /* * Calculate the RGB values of a color ramp, given the some number of * red, green, blue intensities available. */ nColors = ColorRamp(p, colors); /* Now try to allocate the colors we've calculated. */ if (AllocateColors(p, colors, nColors)) { break; /* Success. */ } if (!p->isMonochrome) { if ((p->nRed == 2) && (p->nGreen == 2) && (p->nBlue == 2)) { break; /* Fall back to 1-bit monochrome display. */ /* p->mono = TRUE; */ } else { /* * Reduce the number of shades of each primary to about 3/4 of * the previous value. This will reduce the total number of * colors required to less than half (27/64) the previous value * for PseudoColor displays. */ p->nRed = (p->nRed * 3 + 2) / 4; p->nGreen = (p->nGreen * 3 + 2) / 4; p->nBlue = (p->nBlue * 3 + 2) / 4; } } else { p->nRed /= 2; } } FillPalette(p, colors, nColors); } /* *--------------------------------------------------------------------------- * * NewPainter -- * * Creates a new painter to be used to paint pictures. Painters are keyed * by the combination of display, colormap, visual, depth, and gamma value * used. * * Results: * A pointer to the new painter is returned. * * Side Effects: * A color ramp is allocated (not true for TrueColor visuals). Gamma * tables are computed and filled. * *--------------------------------------------------------------------------- */ static Painter * NewPainter(PainterKey *keyPtr) { Painter *p; p = Blt_AssertCalloc(1, sizeof(Painter)); p->colormap = keyPtr->colormap; p->depth = keyPtr->depth; p->display = keyPtr->display; p->gamma = keyPtr->gamma; p->visualPtr = keyPtr->visualPtr; p->refCount = 0; p->rMask = (unsigned int)p->visualPtr->red_mask; p->gMask = (unsigned int)p->visualPtr->green_mask; p->bMask = (unsigned int)p->visualPtr->blue_mask; p->rShift = FindShift(p->rMask); p->gShift = FindShift(p->gMask); p->bShift = FindShift(p->bMask); p->rAdjust = p->gAdjust = p->bAdjust = 0; { int nRedBits, nGreenBits, nBlueBits; nRedBits = CountBits(p->rMask); nGreenBits = CountBits(p->gMask); nBlueBits = CountBits(p->bMask); if (nRedBits < 8) { p->rAdjust = 8 - nRedBits; } if (nGreenBits < 8) { p->gAdjust = 8 - nGreenBits; } if (nBlueBits < 8) { p->bAdjust = 8 - nBlueBits; } } ComputeGammaTables(p); AllocatePalette(p); return p; } /* *--------------------------------------------------------------------------- * * FreePainter -- * * Called when the TCL interpreter is idle, this routine frees the * painter. Painters are reference counted. Only when no clients are using * the painter (the count is zero) is the painter actually freed. By * deferring its deletion, this allows client code to call Blt_GetPainter * after Blt_FreePainter without incurring a performance penalty. * *--------------------------------------------------------------------------- */ static void FreePainter(DestroyData data) { Painter *p = (Painter *)data; if (p->refCount <= 0) { if (p->nColors > 0) { XFreeColors(p->display, p->colormap, p->pixels, p->nPixels, 0); } Blt_DeleteHashEntry(&painterTable, p->hashPtr); if (p->gc != NULL) { if (p->flags & GC_PRIVATE) { XFreeGC(p->display, p->gc); } else { Tk_FreeGC(p->display, p->gc); } p->gc = NULL; } Blt_Free(p); } } /* *--------------------------------------------------------------------------- * * GetPainter -- * * Attempts to retrieve a painter for a particular combination of display, * colormap, visual, depth, and gamma value. If no specific painter * exists, then one is created. * * Results: * A pointer to the new painter is returned. * * Side Effects: * If no current painter exists, a new painter is added to the hash table * of painters. Otherwise, the current painter's reference count is * incremented indicated how many clients are using the painter. * *--------------------------------------------------------------------------- */ static Painter * GetPainter( Display *display, Colormap colormap, Visual *visualPtr, int depth, float gamma) { Painter *p; PainterKey key; int isNew; Blt_HashEntry *hPtr; if (!initialized) { Blt_InitHashTable(&painterTable, sizeof(PainterKey) / sizeof(int)); initialized = TRUE; } key.display = display; key.colormap = colormap; key.visualPtr = visualPtr; key.depth = depth; key.gamma = gamma; hPtr = Blt_CreateHashEntry(&painterTable, (char *)&key, &isNew); if (isNew) { p = NewPainter(&key); p->hashPtr = hPtr; Blt_SetHashValue(hPtr, p); } else { p = Blt_GetHashValue(hPtr); } p->refCount++; return p; } /* *--------------------------------------------------------------------------- * * PaintXImage -- * * Draw the given XImage. If the size of the image exceeds the maximum * request size of the X11 protocol, the image is drawn using XPutImage in * multiples of rows that fit within the limit. * *--------------------------------------------------------------------------- */ static void PaintXImage(Painter *p, Drawable drawable, XImage *imgPtr, int sx, int sy, int w, int h, int dx, int dy) { int y; int n; long maxPixels; maxPixels = Blt_MaxRequestSize(p->display, sizeof(Blt_Pixel)); n = (maxPixels + w - 1) / w; if (n < 1) { n = 1; } if (n > h ) { n = h; } for (y = 0; y < h; y += n) { if ((y + n) > h) { n = h - y; } XPutImage(p->display, drawable, p->gc, imgPtr, sx, sy+y, dx, dy+y, w, n); } } /* *--------------------------------------------------------------------------- * * XGetImageErrorProc -- * * Error handling routine for the XGetImage request below. Sets the flag * passed via *clientData* to TCL_ERROR indicating an error occurred. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int XGetImageErrorProc( ClientData clientData, XErrorEvent *errEventPtr) /* Not used. */ { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } /* *--------------------------------------------------------------------------- * * DrawableToXImage -- * * Attempts to snap the image from the drawable into an XImage structure * (using XGetImage). This may fail is the coordinates of the region in * the drawable are obscured. * * Results: * Returns a pointer to the XImage if successful. Otherwise NULL is * returned. * *--------------------------------------------------------------------------- */ static XImage * DrawableToXImage( Display *display, Drawable drawable, int x, int y, int w, int h) { XImage *imgPtr; Tk_ErrorHandler errHandler; int result; result = TCL_OK; errHandler = Tk_CreateErrorHandler(display, BadMatch, X_GetImage, -1, XGetImageErrorProc, &result); imgPtr = XGetImage(display, drawable, x, y, w, h, AllPlanes, ZPixmap); Tk_DeleteErrorHandler(errHandler); XSync(display, False); if (result != TCL_OK) { #ifdef notdef fprintf(stderr, "can't snap picture of drawable\n"); #endif return NULL; } return imgPtr; } /* *--------------------------------------------------------------------------- * * DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and converts it * to a picture. * * Results: * Returns a picture of the drawable. If an error occurred (a portion of * the region specified is obscured), then NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Picture DrawableToPicture( Painter *p, Drawable drawable, int x, int y, /* Coordinates of region in source * drawable. */ int w, int h) /* Dimension of the region in the source * drawable. Region must be completely * contained by the drawable. */ { Pict *destPtr; Blt_Pixel *destRowPtr; Blt_Pixel palette[256]; XImage *imgPtr; int shift[4]; unsigned char *srcRowPtr; imgPtr = DrawableToXImage(p->display, drawable, x, y, w, h); if (imgPtr == NULL) { int dw, dh; /* * Failed to acquire an XImage from the drawable. The drawable may be * partially obscured or too small for the requested area. Try it * again, after fixing the area with the dimensions of the drawable. */ if (Blt_GetWindowRegion(p->display, drawable, (int *)NULL, (int *)NULL, &dw, &dh) == TCL_OK) { if ((x + w) > dw) { w = dw - x; } if ((y + h) > dh) { h = dh - y; } imgPtr = DrawableToXImage(p->display, drawable, x, y, w, h); } } if (imgPtr == NULL) { return NULL; } /* Allocate a picture to hold the screen snapshot. */ destPtr = Blt_CreatePicture(w, h); /* Get the palette of the current painter/window */ QueryPalette(p, palette); /* Suppress compiler warnings. */ shift[0] = shift[1] = shift[2] = shift[3] = 0; switch (p->visualPtr->class) { case TrueColor: case DirectColor: if (imgPtr->byte_order == MSBFirst) { shift[0] = 24, shift[1] = 16, shift[2] = 8, shift[3] = 0; } else { switch (imgPtr->bits_per_pixel) { case 32: shift[0] = 0, shift[1] = 8, shift[2] = 16, shift[3] = 24; break; case 24: shift[1] = 0, shift[2] = 8, shift[3] = 16; break; case 16: shift[2] = 0, shift[3] = 8; break; case 8: shift[3] = 0; break; } } srcRowPtr = (unsigned char *)imgPtr->data; destRowPtr = destPtr->bits; switch (imgPtr->bits_per_pixel) { case 32: for (y = 0; y < h; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { int r, g, b; unsigned long pixel; /* Get the next pixel from the image. */ pixel = ((sp[0] << shift[0]) | (sp[1] << shift[1]) | (sp[2] << shift[2]) | (sp[3] << shift[3])); /* Convert the pixel to RGB, correcting for input gamma. */ r = ((pixel & p->rMask) >> p->rShift); g = ((pixel & p->gMask) >> p->gShift); b = ((pixel & p->bMask) >> p->bShift); dp->Red = palette[r].Red; dp->Green = palette[g].Green; dp->Blue = palette[b].Blue; dp->Alpha = ALPHA_OPAQUE; sp += 4; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += imgPtr->bytes_per_line; } break; case 24: for (y = 0; y < h; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { int r, g, b; unsigned long pixel; /* Get the next pixel from the image. */ pixel = ((sp[0] << shift[1]) | (sp[1] << shift[2]) | (sp[2] << shift[3])); /* Convert the pixel to RGB, correcting for input gamma. */ r = ((pixel & p->rMask) >> p->rShift); g = ((pixel & p->gMask) >> p->gShift); b = ((pixel & p->bMask) >> p->bShift); dp->Red = palette[r].Red; dp->Green = palette[g].Green; dp->Blue = palette[b].Blue; dp->Alpha = ALPHA_OPAQUE; sp += 3; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += imgPtr->bytes_per_line; } break; case 16: for (y = 0; y < h; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { int r, g, b; unsigned long pixel; /* Get the next pixel from the image. */ pixel = ((sp[0] << shift[2]) | (sp[1] << shift[3])); /* Convert the pixel to RGB, correcting for input gamma. */ r = ((pixel & p->rMask) >> p->rShift); g = ((pixel & p->gMask) >> p->gShift); b = ((pixel & p->bMask) >> p->bShift); dp->Red = palette[r].Red; dp->Green = palette[g].Green; dp->Blue = palette[b].Blue; dp->Alpha = ALPHA_OPAQUE; sp += 2; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += imgPtr->bytes_per_line; } break; case 8: for (y = 0; y < h; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { int r, g, b; unsigned long pixel; /* Get the next pixel from the image. */ pixel = (*sp << shift[3]); /* Convert the pixel to RGB, correcting for input gamma. */ r = ((pixel & p->rMask) >> p->rShift); g = ((pixel & p->gMask) >> p->gShift); b = ((pixel & p->bMask) >> p->bShift); dp->Red = palette[r].Red; dp->Green = palette[g].Green; dp->Blue = palette[b].Blue; dp->Alpha = ALPHA_OPAQUE; sp++; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += imgPtr->bytes_per_line; } break; } break; case PseudoColor: case StaticColor: case GrayScale: case StaticGray: if ((imgPtr->bits_per_pixel != 8) && (imgPtr->bits_per_pixel != 4)) { return NULL; /* Can only handle 4 or 8 bit pixels. */ } srcRowPtr = (unsigned char *)imgPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < h; y++) { unsigned char *sp; Blt_Pixel *dp; sp = srcRowPtr, dp = destRowPtr; for (x = 0; x < w; x++) { unsigned long pixel; if (imgPtr->bits_per_pixel == 8) { pixel = *sp++; } else { if (x & 1) { /* Odd: pixel is high nybble. */ pixel = (*sp & 0xF0) >> 4; sp++; } else { /* Even: pixel is low nybble. */ pixel = (*sp & 0x0F); } } /* Convert the pixel to RGB, correcting for input gamma. */ dp->Red = palette[pixel].Red; dp->Green = palette[pixel].Green; dp->Blue = palette[pixel].Blue; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += imgPtr->bytes_per_line; destRowPtr += destPtr->pixelsPerRow; } break; default: break; } XDestroyImage(imgPtr); return destPtr; } /* *--------------------------------------------------------------------------- * * PaintPicture -- * * Paints the picture to the given drawable. The region of the picture is * specified and the coordinates where in the destination drawable is the * image to be displayed. * * The image may be dithered depending upon the bit set in the flags * parameter: 0 no dithering, 1 for dithering. * * Results: * Returns TRUE is the picture was successfully displayed. Otherwise FALSE * is returned if the particular combination visual and image depth is not * handled. * *--------------------------------------------------------------------------- */ static int PaintPicture( Painter *p, Drawable drawable, Pict *srcPtr, int sx, int sy, /* Coordinates of region in the * picture. */ int w, int h, /* Dimension of the source region. * Area cannot extend beyond the end * of the picture. */ int dx, int dy, /* Coordinates of destination region * in the drawable. */ unsigned int flags) { #ifdef WORD_BIGENDIAN static int nativeByteOrder = MSBFirst; #else static int nativeByteOrder = LSBFirst; #endif int dw, dh; Pict *ditherPtr; Blt_Pixel *srcRowPtr; XImage *imgPtr; int y; unsigned char *destRowPtr; #ifdef notdef fprintf(stderr, "PaintPicture: x=%d,y=%d,w=%d,h=%d,dx=%d,dy=%d\n", sx, sy, w, h, dx, dy); #endif ditherPtr = NULL; if (flags & BLT_PAINTER_DITHER) { ditherPtr = Blt_DitherPicture(srcPtr, p->palette); if (ditherPtr != NULL) { srcPtr = ditherPtr; } } imgPtr = XCreateImage(p->display, p->visualPtr, p->depth, ZPixmap, 0, (char *)NULL, w, h, 32, 0); assert(imgPtr); /* * Set the byte order to the platform's native byte order. We'll let Xlib * handle byte swapping. */ imgPtr->byte_order = nativeByteOrder; imgPtr->data = Blt_AssertMalloc(sizeof(Blt_Pixel) * w * h); srcRowPtr = srcPtr->bits + ((sy * srcPtr->pixelsPerRow) + sx); destRowPtr = (unsigned char *)imgPtr->data; dw = MIN(w, srcPtr->width); dh = MIN(h, srcPtr->height); switch (p->visualPtr->class) { case TrueColor: /* Directly compute the pixel 8, 16, 24, or 32 bit values from the RGB * components. */ switch (imgPtr->bits_per_pixel) { case 32: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned int *dp; dp = (unsigned int *)destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned int r, g, b; r = (p->igammaTable[sp->Red] >> p->rAdjust) << p->rShift; g = (p->igammaTable[sp->Green] >> p->gAdjust) << p->gShift; b = (p->igammaTable[sp->Blue] >> p->bAdjust) << p->bShift; *dp = r | g | b; dp++; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 24: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; unsigned int r, g, b; r = (p->igammaTable[sp->Red] >> p->rAdjust) << p->rShift; g = (p->igammaTable[sp->Green] >> p->gAdjust) << p->gShift; b = (p->igammaTable[sp->Blue] >> p->bAdjust) << p->bShift; pixel = r | g | b; *dp++ = pixel & 0xFF; *dp++ = (pixel >> 8) & 0xFF; *dp++ = (pixel >> 16) & 0xFF; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 16: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned short *dp; dp = (unsigned short *)destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; unsigned int r, g, b; r = (p->igammaTable[sp->Red] >> p->rAdjust) << p->rShift; g = (p->igammaTable[sp->Green] >> p->gAdjust) << p->gShift; b = (p->igammaTable[sp->Blue] >> p->bAdjust) << p->bShift; pixel = r | g | b; *dp = pixel; dp++; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 8: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; unsigned int r, g, b; r = (p->igammaTable[sp->Red] >> p->rAdjust) << p->rShift; g = (p->igammaTable[sp->Green] >> p->gAdjust) << p->gShift; b = (p->igammaTable[sp->Blue] >> p->bAdjust) << p->bShift; pixel = r | g | b; *dp++ = pixel & 0xFF; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; } break; case DirectColor: /* Translate the RGB components to 8, 16, 24, or 32-bit pixel * values. */ switch (imgPtr->bits_per_pixel) { case 32: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] | p->gBits[sp->Green] | p->bBits[sp->Blue]); *(unsigned int *)dp = pixel; dp += 4; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 24: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] | p->gBits[sp->Green] | p->bBits[sp->Blue]); *dp++ = pixel & 0xFF; *dp++ = (pixel >> 8) & 0xFF; *dp++ = (pixel >> 16) & 0xFF; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 16: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] | p->gBits[sp->Green] | p->bBits[sp->Blue]); *(unsigned short *)dp = pixel; dp += 2; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case 8: for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] | p->gBits[sp->Green] | p->bBits[sp->Blue]); *dp++ = pixel & 0xFF; } break; } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } break; case PseudoColor: case StaticColor: case GrayScale: case StaticGray: /* Translate RGB components to the correct 8-bit or 4-bit * pixel values. */ if (imgPtr->bits_per_pixel == 8) { for (y = 0; y < dh; y++) { Blt_Pixel *sp, *send; unsigned char *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + dw; sp < send; sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] + p->gBits[sp->Green] + p->bBits[sp->Blue]); pixel = p->pixels[pixel]; *dp++ = (pixel & 0xFF); } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } } else { for (y = 0; y < dh; y++) { Blt_Pixel *sp; int x; unsigned char *dp; dp = destRowPtr, sp = srcRowPtr; for (x = 0; x < dw; x++, sp++) { unsigned long pixel; pixel = (p->rBits[sp->Red] + p->gBits[sp->Green] + p->bBits[sp->Blue]); pixel = p->pixels[pixel]; if (x & 1) { *dp |= (pixel & 0x0F) << 4; /* Move to the next address after odd nybbles. */ dp++; } else { *dp = (pixel & 0x0F); } } destRowPtr += imgPtr->bytes_per_line; srcRowPtr += srcPtr->pixelsPerRow; } } break; default: if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } XDestroyImage(imgPtr); return FALSE; } PaintXImage(p, drawable, imgPtr, 0, 0, w, h, dx, dy); if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } XDestroyImage(imgPtr); return TRUE; } /* *--------------------------------------------------------------------------- * * PaintPictureWithBlend -- * * Blends and paints the picture in the given drawable. The region of the * picture is specified and the coordinates where in the destination * drawable is the image to be displayed. * * The background is snapped from the drawable and converted into a * picture. This picture is then blended with the current picture (the * background always assumed to be 100% opaque). * * Results: * Returns TRUE is the picture was successfully display, Otherwise FALSE is * returned. This may happen if the background can not be obtained from * the drawable. * *--------------------------------------------------------------------------- */ static int PaintPictureWithBlend( Painter *p, Drawable drawable, Blt_Picture fg, int x, int y, /* Coordinates of source region in the * picture. */ int w, int h, /* Dimension of the source region. * Region cannot extend beyond the end * of the picture. */ int dx, int dy, /* Coordinates of destination region in * the drawable. */ unsigned int flags, int alpha) { Pict *bgPtr; #ifdef notdef fprintf(stderr, "PaintPictureWithBlend: x=%d,y=%d,w=%d,h=%d,dx=%d,dy=%d\n", x, y, w, h, dx, dy); #endif if (dx < 0) { w -= -dx; /* Shrink the width. */ x += -dx; /* Change the left of the source * region. */ dx = 0; /* Start at the left of the * destination. */ } if (dy < 0) { h -= -dy; /* Shrink the height. */ y += -dy; /* Change the top of the source * region. */ dy = 0; /* Start at the top of the * destination. */ } if ((w < 0) || (h < 0)) { return FALSE; } bgPtr = DrawableToPicture(p, drawable, dx, dy, w, h); if (bgPtr == NULL) { return FALSE; } /* Dimension of source region may be adjusted by the actual size of the * drawable. This is reflected in the size of the background picture. */ Blt_BlendPictures(bgPtr, fg, x, y, bgPtr->width, bgPtr->height, 0, 0); PaintPicture(p, drawable, bgPtr, 0, 0, bgPtr->width, bgPtr->height, dx, dy, flags); Blt_FreePicture(bgPtr); return TRUE; } /* *--------------------------------------------------------------------------- * * Blt_DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and converts it * to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, NULL is * returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_DrawableToPicture( Tk_Window tkwin, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int w, int h, /* Dimension of the image. Image must * be completely contained by the * drawable. */ float gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainter(tkwin, gamma); picture = DrawableToPicture(painter, drawable, x, y, w, h); Blt_FreePainter(painter); return picture; } /* *--------------------------------------------------------------------------- * * Blt_WindowToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and converts it * to a picture. * * This routine is used to snap foreign (non-Tk) windows. For pixmaps and * Tk windows, Blt_DrawableToPicture is preferred. * * Results: * Returns a picture of the drawable. If an error occurred, NULL is * returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_WindowToPicture( Display *display, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int w, int h, /* Dimension of the image. Image must * be completely contained by the * drawable. */ float gamma) { Blt_Painter painter; Blt_Picture picture; painter = Blt_GetPainterFromDrawable(display, drawable, gamma); picture = DrawableToPicture(painter, drawable, x, y, w, h); Blt_FreePainter(painter); return picture; } int Blt_PaintPicture( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Starting coordinates of subregion in * the picture to be painted. */ int w, int h, /* Dimension of the subregion. */ int dx, int dy, /* Coordinates of region in the * drawable. */ unsigned int flags) { int x1, y1, x2, y2; /* * Nothing to draw. The selected region is outside of the picture. * * 0,0 * +---------+ * | | * | Picture | * | | * +---------+ * x,y * +-------+ * | | * | | h * +-------+ * w */ x1 = x, y1 = y, x2 = x + w, y2 = y1 + h; if ((picture == NULL) || (x1 >= Blt_PictureWidth(picture)) || (x2 <= 0) || (y1 >= Blt_PictureHeight(picture)) || (y2 <= 0)) { return TRUE; } if (dx < 0) { x1 -= dx; /* Add offset */ dx = 0; } if (dy < 0) { y1 -= dy; /* Add offset */ dy = 0; } /* * Correct the dimensions if the origin starts before the picture * (i.e. coordinate is negative). Reset the coordinate the 0. * * x,y * +---------+ 0,0 * | +------|--------+ +------+--------+ * h | |0,0 | | | | | * | | | | | | | * +--|------+ | +------+ | * w | | | | * | | | | * +---------------+ +---------------+ * */ if (x1 < 0) { x2 += x1; x1 = 0; } if (y1 < 0) { y2 += y1; y1 = 0; } /* * Check that the given area does not extend beyond the end of the * picture. * * 0,0 0,0 * +-----------------+ +-----------------+ * | | | | * | x,y | | x,y | * | +---------+ | +-------+ * | | | | | | | * | | | | w | | | * +---------|-------+ | +---------+-------+ * +---------+ * h * * Clip the end of the area if it's too big. */ if ((x2 - x1) > Blt_PictureWidth(picture)) { x2 = x1 + Blt_PictureWidth(picture); } if ((y2 - y1) > Blt_PictureHeight(picture)) { y2 = y1 + Blt_PictureHeight(picture); } /* Check that there's still something to paint. */ if (((x2 - x1) <= 0) || ((y2 - y1) <= 0)) { return TRUE; } if (Blt_PictureIsOpaque(picture)) { return PaintPicture(painter, drawable, picture, x1, y1, x2 - x1, y2 - y1, dx, dy, flags); } else { int alpha = 128; return PaintPictureWithBlend(painter, drawable, picture, x1, y1, x2 - x1, y2 - y1, dx, dy, flags, alpha); } } int Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the * picture. */ int w, int h, /* Dimension of the region. Area * cannot extend beyond the end of the * picture. */ int dx, int dy, /* Coordinates of region in the * drawable. */ unsigned int flags, /* Indicates whether to dither the * picture before displaying. */ double falpha) { int alpha; int x1, y1, x2, y2; alpha = (int)(falpha * 255.0 + 0.5); /* * Nothing to draw. The selected region is outside of the picture. * * 0,0 * +---------+ * | | * | Picture | * | | * +---------+ * x,y * +-------+ * | | * | | h * +-------+ * w */ x1 = x, y1 = y, x2 = x + w, y2 = y1 + h; if ((picture == NULL) || (x1 >= Blt_PictureWidth(picture)) || (x2 <= 0) || (y1 >= Blt_PictureHeight(picture)) || (y2 <= 0)) { return TRUE; } if (dx < 0) { x1 -= dx; dx = 0; /* Add offset */ } if (dy < 0) { y1 -= dy; /* Add offset */ dy = 0; } /* * Correct the dimensions if the origin starts before the picture * (i.e. coordinate is negative). Reset the coordinate the 0. * * x,y * +---------+ 0,0 * | +------|--------+ +------+--------+ * h | |0,0 | | | | | * | | | | | | | * +--|------+ | +------+ | * w | | | | * | | | | * +---------------+ +---------------+ * */ if (x1 < 0) { x2 += x1; x1 = 0; } if (y1 < 0) { y2 += y2; y1 = 0; } /* * Check that the given area does not extend beyond the end of the * picture. * * 0,0 0,0 * +-----------------+ +-----------------+ * | | | | * | x,y | | x,y | * | +---------+ | +-------+ * | | | | | | | * | | | | w | | | * +---------|-------+ | +---------+-------+ * +---------+ * h * * Clip the end of the area if it's too big. */ if ((x2 - x1) > Blt_PictureWidth(picture)) { x2 = x1 + Blt_PictureWidth(picture); } if ((y2 - y1) > Blt_PictureHeight(picture)) { y2 = y1 + Blt_PictureHeight(picture); } /* Check that there's still something to paint. */ if (((x2 - x1) <= 0) || ((y2 - y1) <= 0)) { return TRUE; } return PaintPictureWithBlend(painter, drawable, picture, x1, y1, x2 - x1, y2 - y1, dx, dy, flags, alpha); } /* *--------------------------------------------------------------------------- * * Blt_GetPainterFromDrawable -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information is retrieved from * the drawable which is assumed to be a window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainterFromDrawable(Display *display, Drawable drawable, float gamma) { XGCValues gcValues; unsigned long gcMask; Painter *p; { Blt_DrawableAttributes *attrPtr; attrPtr = Blt_GetDrawableAttribs(display, drawable); if ((attrPtr != NULL) && (attrPtr->visual != NULL)) { p = GetPainter(display, attrPtr->colormap, attrPtr->visual, attrPtr->depth, gamma); } else { XWindowAttributes a; XGetWindowAttributes(display, drawable, &a); p = GetPainter(display, a.colormap, a.visual, a.depth, gamma); } } /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = XCreateGC(display, drawable, gcMask, &gcValues); p->flags |= GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_GetPainter -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information (except for the * monitor's gamma value) is retrieved from the given Tk window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainter(Tk_Window tkwin, float gamma) { Painter *p; XGCValues gcValues; unsigned long gcMask; p = GetPainter(Tk_Display(tkwin), Tk_Colormap(tkwin), Tk_Visual(tkwin), Tk_Depth(tkwin), gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = Tk_GetGC(tkwin, gcMask, &gcValues); p->flags &= ~GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_FreePainter -- * * Frees the painter. Painters are reference counted. Only when no clients * are using the painter (the count is zero) is the painter actually freed. * *--------------------------------------------------------------------------- */ void Blt_FreePainter(Painter *p) { p->refCount--; if (p->refCount <= 0) { Tcl_EventuallyFree(p, FreePainter); } } GC Blt_PainterGC(Painter *p) { return p->gc; } int Blt_PainterDepth(Painter *p) { return p->depth; } Visual * Blt_PainterVisual(Painter *p) { return p->visualPtr; } Colormap Blt_PainterColormap(Painter *p) { return p->colormap; } �����������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictPdf.c������������������������������������������������������������������0000644�0001750�0001750�00000100505�11462120062�015225� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictPdf.c -- * * This module implements Portable Document Format (PDF) file conversion * routines for the picture image type in the BLT toolkit. * * Copyright 2003-2007 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #include <stdlib.h> #include <unistd.h> #include <limits.h> #include <tcl.h> #include <limits.h> #include <stdlib.h> #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) # define __WIN32__ # ifndef WIN32 # define WIN32 # endif # endif #endif /*__WIN32__*/ #ifdef _MSC_VER # define _CRT_SECURE_NO_DEPRECATE # define _CRT_NONSTDC_NO_DEPRECATE #endif /*MSC_VER*/ #ifdef WIN32 # define STRICT # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef STRICT # undef WIN32_LEAN_AND_MEAN # include <windowsx.h> #endif /*WIN32*/ #include <bltSwitch.h> #include <bltDBuffer.h> #include "bltTypes.h" #include "bltPicture.h" #include "bltPictFmts.h" #include "bltPs.h" #include "bltAlloc.h" #include "bltWait.h" #include <tk.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef WIN32 #include "bltWin.h" #endif /*WIN32*/ #define UCHAR(c) ((unsigned char) (c)) #define ISASCII(c) (UCHAR(c)<=0177) #define MIN(a,b) (((a)<(b))?(a):(b)) #define TRUE 1 #define FALSE 0 #define div257(t) (((t)+((t)>>8))>>8) #define SetBit(x) destRowPtr[(x>>3)] |= (0x80 >>(x&7)) #define GetBit(x) srcRowPtr[(x>>3)] & (0x80 >> (x&7)) #define MAXCOLORS 256 #define BUFFER_SIZE (1<<16) enum PbmVersions { PBM_UNKNOWN, PBM_PLAIN, /* Monochrome: 1-bit per pixel */ PGM_PLAIN, /* 8-bits per pixel */ PPM_PLAIN, /* 24-bits per pixel */ PBM_RAW, /* 1-bit per pixel */ PGM_RAW, /* 8/16-bits per pixel */ PPM_RAW /* 24/48 bits per pixel */ }; static const char *pbmFormat[] = { "???", "pbmplain", "pgmplain", "ppmplain", "pbmraw", "pgmraw", "ppmraw", }; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int flags; /* Flag. */ Blt_Pixel bg; PageSetup setup; int index; } PdfExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int dpi; /* Dots per inch. */ const char *paperSize; /* Papersize. */ int crop; } PdfImportSwitches; #define PDF_CROP (1<<0) typedef struct { unsigned int width, height; /* Dimensions of the image. */ unsigned int bitsPerPixel; /* # bits per pixel. */ unsigned char *data; /* Start of raw data */ unsigned int bytesPerRow; Blt_DBuffer dbuffer; } Pbm; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc PicaSwitchProc; static Blt_SwitchCustom picaSwitch = { PicaSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc PadSwitchProc; static Blt_SwitchCustom padSwitch = { PadSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(PdfExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PdfExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PdfExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_BITMASK, "-center", "", Blt_Offset(PdfExportSwitches, setup.flags), 0, PS_CENTER}, {BLT_SWITCH_BITMASK, "-greyscale", "", Blt_Offset(PdfExportSwitches, setup.flags), 0, PS_GREYSCALE}, {BLT_SWITCH_BITMASK, "-landscape", "", Blt_Offset(PdfExportSwitches, setup.flags), 0, PS_LANDSCAPE}, {BLT_SWITCH_INT_POS, "-level", "pdflevel", Blt_Offset(PdfExportSwitches, setup.level), 0}, {BLT_SWITCH_BITMASK, "-maxpect", "", Blt_Offset(PdfExportSwitches, setup.flags), 0, PS_MAXPECT}, {BLT_SWITCH_CUSTOM, "-padx", "pad", Blt_Offset(PdfExportSwitches, setup.xPad), 0, 0, &padSwitch}, {BLT_SWITCH_CUSTOM, "-pady", "pad", Blt_Offset(PdfExportSwitches, setup.yPad), 0, 0, &padSwitch}, {BLT_SWITCH_CUSTOM, "-paperheight","pica", Blt_Offset(PdfExportSwitches, setup.reqPaperHeight), 0, 0, &picaSwitch}, {BLT_SWITCH_CUSTOM, "-paperwidth", "pica", Blt_Offset(PdfExportSwitches, setup.reqPaperWidth), 0, 0, &picaSwitch}, {BLT_SWITCH_LIST, "-comments", "{key value...}", Blt_Offset(PdfExportSwitches, setup.comments), BLT_SWITCH_NULL_OK}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PdfExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_BOOLEAN, "-crop", "bool", Blt_Offset(PdfImportSwitches, crop), 0}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PdfImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_INT, "-dpi", "number", Blt_Offset(PdfImportSwitches, dpi), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PdfImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_STRING, "-papersize", "string", Blt_Offset(PdfImportSwitches, paperSize), 0}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_PicturePdfInit; extern const char *Blt_Itoa(int); #ifdef WIN32 typedef struct { DWORD pid; HANDLE hProcess; } ProcessId; #else typedef pid_t ProcessId; #endif #ifdef WIN32 #define close(fd) CloseHandle((HANDLE)fd) #define kill KillProcess #define waitpid WaitProcess #endif BLT_EXTERN int Blt_CreatePipeline(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ProcessId **pidArrayPtr, int *stdinPipePtr, int *stdoutPipePtr, int *stderrPipePtr); BLT_EXTERN void Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, unsigned int *yPtr); #define TRUE 1 #define FALSE 0 typedef struct _Blt_Picture Picture; #include <ctype.h> static void AddComments(Blt_Ps ps, const char **comments) { const char **p; for (p = comments; *p != NULL; p += 2) { if (*(p+1) == NULL) { break; } Blt_Ps_Format(ps, "%% %s: %s\n", *p, *(p+1)); } } /* * Parse the lines that define the dimensions of the bitmap, plus the first * line that defines the bitmap data (it declares the name of a data variable * but doesn't include any actual data). These lines look something like the * following: * * #define foo_width 16 * #define foo_height 16 * #define foo_x_hot 3 * #define foo_y_hot 3 * static char foo_bits[] = { * * The x_hot and y_hot lines may or may not be present. It's important to * check for "char" in the last line, in order to reject old X10-style bitmaps * that used shorts. */ #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #endif /* TIME_WITH_SYS_TIME */ /* *-------------------------------------------------------------------------- * * PicaSwitchProc -- * * Convert a Tcl_Obj list of 2 or 4 numbers into representing a bounding * box structure. * * Results: * The return value is a standard TCL result. * *-------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PicaSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { int *picaPtr = (int *)(record + offset); return Blt_Ps_GetPicaFromObj(interp, objPtr, picaPtr); } /* *-------------------------------------------------------------------------- * * PadSwitchProc -- * * Convert a Tcl_Obj list of 2 or 4 numbers into representing a bounding * box structure. * * Results: * The return value is a standard TCL result. * *-------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PadSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Blt_Pad *padPtr = (Blt_Pad *)(record + offset); return Blt_Ps_GetPadFromObj(interp, objPtr, padPtr); } /* * -------------------------------------------------------------------------- * * PostScriptPreamble -- * * The PostScript preamble calculates the needed translation and scaling * to make image coordinates compatible with PostScript. * * -------------------------------------------------------------------------- */ static int PostScriptPreamble( Tcl_Interp *interp, Picture *srcPtr, PdfExportSwitches *switchesPtr, Blt_Ps ps) { PageSetup *setupPtr = &switchesPtr->setup; time_t ticks; char date[200]; /* Hold the date string from ctime() */ const char *version; char *newline; Blt_Ps_Append(ps, "%!PS-Adobe-3.0 EPSF-3.0\n"); /* The "BoundingBox" comment is required for EPS files. */ Blt_Ps_Format(ps, "%%%%BoundingBox: %d %d %d %d\n", setupPtr->left, setupPtr->paperHeight - setupPtr->top, setupPtr->right, setupPtr->paperHeight - setupPtr->bottom); Blt_Ps_Append(ps, "%%Pages: 0\n"); version = Tcl_GetVar(interp, "blt_version", TCL_GLOBAL_ONLY); if (version == NULL) { version = "???"; } Blt_Ps_Format(ps, "%%%%Creator: (BLT %s Picture)\n", version); ticks = time((time_t *) NULL); strcpy(date, ctime(&ticks)); newline = date + strlen(date) - 1; if (*newline == '\n') { *newline = '\0'; } Blt_Ps_Format(ps, "%%%%CreationDate: (%s)\n", date); Blt_Ps_Append(ps, "%%DocumentData: Clean7Bit\n"); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Append(ps, "%%Orientation: Landscape\n"); } else { Blt_Ps_Append(ps, "%%Orientation: Portrait\n"); } AddComments(ps, setupPtr->comments); Blt_Ps_Append(ps, "%%EndComments\n\n"); Blt_Ps_Append(ps, "%%BeginProlog\n"); Blt_Ps_Append(ps, "%%EndProlog\n"); Blt_Ps_Append(ps, "%%BeginSetup\n"); Blt_Ps_Append(ps, "gsave\n"); /* * Set the conversion from PostScript to X11 coordinates. Scale pica to * pixels and flip the y-axis (the origin is the upperleft corner). */ Blt_Ps_VarAppend(ps, "% Transform coordinate system to use X11 coordinates\n" "% 1. Flip y-axis over by reversing the scale,\n", (char *)NULL); Blt_Ps_Append(ps, "1 -1 scale\n"); Blt_Ps_VarAppend(ps, "% 2. Translate the origin to the other side of the page,\n" "% making the origin the upper left corner\n", (char *)NULL); Blt_Ps_Format(ps, "0 %d translate\n\n", -setupPtr->paperHeight); Blt_Ps_VarAppend(ps, "% User defined page layout\n\n", "% Set color level\n", (char *)NULL); Blt_Ps_Format(ps, "%% Set origin\n%d %d translate\n\n", setupPtr->left, setupPtr->bottom); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Format(ps, "%% Landscape orientation\n0 %g translate\n-90 rotate\n", ((double)srcPtr->width * setupPtr->scale)); } if (setupPtr->scale != 1.0f) { Blt_Ps_Append(ps, "\n% Setting picture scale factor\n"); Blt_Ps_Format(ps, " %g %g scale\n", setupPtr->scale, setupPtr->scale); } Blt_Ps_Append(ps, "\n%%EndSetup\n\n"); return TCL_OK; } static char * PbmComment(char *bp) { char *p; p = bp; if (*p == '#') { /* Comment: file end of line */ while((*p != '\n') && (p != '\0')) { p++; } } return p; } static inline int PbmGetShort(unsigned char *bp) { return (bp[0] << 8) + bp[1]; } static Picture * PbmRawData(Pbm *pbmPtr) { Picture *destPtr; destPtr = Blt_CreatePicture(pbmPtr->width, pbmPtr->height); switch (pbmPtr->bitsPerPixel) { case 1: { /* Monochrome */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { int x; Blt_Pixel *dp; dp = destRowPtr; for (x = 0; x < pbmPtr->width; x++) { dp->Red = dp->Green = dp->Blue = (GetBit(x)) ? 0xFF : 0; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 8: { /* Greyscale (1 byte) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp++, dp++) { dp->Red = dp->Green = dp->Blue = *sp; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 16: { /* Greyscale (2 bytes) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 2, dp++) { unsigned int value; value = PbmGetShort(sp); dp->Red = dp->Green = dp->Blue = div257(value); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 24: { /* Color (1 byte per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 3, dp++) { dp->Red = sp[0]; dp->Green = sp[1]; dp->Blue = sp[2]; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 48: { /* Color (2 bytes per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 6, dp++) { unsigned int r, g, b; r = PbmGetShort(sp); g = PbmGetShort(sp+2); b = PbmGetShort(sp+4); dp->Red = div257(r); dp->Green = div257(g); dp->Blue = div257(b); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } } Blt_DBuffer_SetPointer(pbmPtr->dbuffer, pbmPtr->data + (pbmPtr->height * pbmPtr->bytesPerRow)); return destPtr; } static Blt_Picture PbmToPicture(Tcl_Interp *interp, Blt_DBuffer dbuffer) { char *bp, *p; const char *type; int isRaw; int version; size_t size, want; unsigned char *start; Pbm pbm; size = Blt_DBuffer_BytesLeft(dbuffer); start = Blt_DBuffer_Pointer(dbuffer); if (size < 14) { Tcl_AppendResult(interp, "can't read PBM bitmap: short file", (char *)NULL); return NULL; } bp = (char *)start; if ((bp[0] != 'P') || (bp[1] < '1') || (bp[1] > '6')) { Tcl_AppendResult(interp, "unknown PBM bitmap header", (char *)NULL); return NULL; } version = bp[1] - '0'; isRaw = (version > 2); switch(version) { case PBM_PLAIN: /* P2 */ case PBM_RAW: /* P5 */ pbm.bitsPerPixel = 8; break; case PGM_PLAIN: /* P1 */ case PGM_RAW: /* P4 */ pbm.bitsPerPixel = 1; break; case PPM_PLAIN: /* P3 */ case PPM_RAW: /* P6 */ pbm.bitsPerPixel = 24; break; } if (!isspace(bp[2])) { type = pbmFormat[version]; Tcl_AppendResult(interp, "no white space after version in pbm header.", (char *)NULL); return NULL; } p = bp + 3; if (*p == '#') { p = PbmComment(p); } pbm.width = strtoul(p, &p, 10); if (pbm.width == 0) { Tcl_AppendResult(interp, "bad width specification ", bp+3, ".", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after width in pbm header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } pbm.height = strtoul(p, &p, 10); if (pbm.height == 0) { Tcl_AppendResult(interp, "bad height specification", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after height in header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } if (pbm.bitsPerPixel != 1) { unsigned int maxval; /* Maximum intensity allowed. */ maxval = strtoul(p, &p, 10); if (maxval == 0) { Tcl_AppendResult(interp, "bad maxval specification", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after maxval pbm header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } if (maxval >= USHRT_MAX) { Tcl_AppendResult(interp, "invalid maxval specification", (char *)NULL); return NULL; } if (maxval > 255) { pbm.bitsPerPixel <<= 1; /* 16-bit greyscale or 48 bit color. */ } } pbm.data = (unsigned char *)p; pbm.dbuffer = dbuffer; pbm.bytesPerRow = ((pbm.bitsPerPixel * pbm.width) + 7) / 8; want = (pbm.data - start) + pbm.height * pbm.bytesPerRow; if ((isRaw) && (want > Blt_DBuffer_BytesLeft(dbuffer))) { Tcl_AppendResult(interp, "short pbm file", (char *)NULL); return NULL; } if (!isRaw) { Tcl_AppendResult(interp, "expected raw pbm file", (char *)NULL); return NULL; } return PbmRawData(&pbm); } #ifdef WIN32 typedef struct { int fd; Blt_DBuffer dbuffer; int lastError; } PdfWriter; /* *--------------------------------------------------------------------------- * * WriteBufferProc -- * * This function runs in a separate thread and write the data buffer as * input to the ghostscript process. * * Results: * None. * * Side effects: * Writes the buffer (PDF file) to the ghostscript standard input * file descriptor. * *--------------------------------------------------------------------------- */ static DWORD WINAPI WriteBufferProc(void *clientData) { PdfWriter *writerPtr = clientData; const unsigned char *bp; int bytesLeft; HANDLE hFile; DWORD count; hFile = (HANDLE)writerPtr->fd; bp = Blt_DBuffer_Bytes(writerPtr->dbuffer); for (bytesLeft = Blt_DBuffer_Length(writerPtr->dbuffer); bytesLeft > 0; bytesLeft -= count) { if (!WriteFile(hFile, bp, bytesLeft, &count, NULL)) { writerPtr->lastError = GetLastError(); break; } bp += count; } Blt_DBuffer_Destroy(writerPtr->dbuffer); CloseHandle(hFile); if (bytesLeft > 0) { ExitThread(1); } ExitThread(0); /* NOTREACHED */ return 0; } static PdfWriter writer; static int WriteToGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { HANDLE hThread; ClientData clientData; DWORD id; writer.dbuffer = Blt_DBuffer_Create(); Blt_DBuffer_Init(writer.dbuffer); /* Copy the input to a new buffer. */ Blt_DBuffer_AppendData(writer.dbuffer, Blt_DBuffer_Bytes(dbuffer), Blt_DBuffer_Length(dbuffer)); writer.fd = fd; writer.lastError = 0; clientData = &writer; hThread = CreateThread( NULL, /* Security attributes */ 8000, /* Initial stack size. */ WriteBufferProc, /* Address of thread routine */ clientData, /* One-word of data passed to * routine. */ 0, /* Creation flags */ &id); /* (out) Will contain Id of new * thread. */ return (int)hThread; } static int ReadFromGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { DWORD nBytes; HANDLE hFile; int result; Blt_DBuffer_Free(dbuffer); hFile = (HANDLE)fd; nBytes = 0; for (;;) { DWORD nRead; char *bp; bp = Blt_DBuffer_Extend(dbuffer, BUFFER_SIZE); if (!ReadFile(hFile, bp, BUFFER_SIZE, &nRead, NULL)) { DWORD err; err = GetLastError(); if ((err != ERROR_BROKEN_PIPE) && (err != ERROR_HANDLE_EOF)) { Tcl_AppendResult(interp, "error reading from ghostscript: ", Blt_PrintError(err), (char *)NULL); result = TCL_ERROR; break; } } if (nRead == 0) { result = TCL_OK; break; /* EOF */ } nBytes += nRead; Blt_DBuffer_SetLength(dbuffer, nBytes); } Blt_DBuffer_SetLength(dbuffer, nBytes); CloseHandle(hFile); return result; } #else /* WIN32 */ static int WriteToGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { pid_t child; child = fork(); if (child == -1) { Tcl_AppendResult(interp, "can't fork process: ", Tcl_PosixError(interp), (char *)NULL); return 0; } else if (child > 0) { close(fd); return child; } else { const char *bytes; int nWritten, nBytes; bytes = (const char *)Blt_DBuffer_Bytes(dbuffer); nBytes = Blt_DBuffer_Length(dbuffer); nWritten = write(fd, bytes, nBytes); close(fd); if (nWritten != nBytes) { exit(1); } exit(0); } } static int ReadFromGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { int nBytes; Blt_DBuffer_Free(dbuffer); nBytes = 0; for (;;) { char *bp; int nRead; bp = (char *)Blt_DBuffer_Extend(dbuffer, BUFFER_SIZE); nRead = read(fd, bp, BUFFER_SIZE); if (nRead == 0) { break; /* EOF */ } else if (nRead < 0) { Tcl_AppendResult(interp, "error reading from ghostscript: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } nBytes += nRead; Blt_DBuffer_SetLength(dbuffer, nBytes); } Blt_DBuffer_SetLength(dbuffer, nBytes); close(fd); return TCL_OK; } #endif /* WIN32 */ static int PdfToPbm( Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PdfImportSwitches *switchesPtr) { int in, out; /* File descriptors for ghostscript * subprocess. */ char string1[200]; char string2[200]; int nPids; ProcessId *pidPtr; int result; pid_t child; const char **p; const char *args[] = { "gs", /* Ghostscript command */ "-dEPSCrop", /* (optional) crop page to bbox */ "-dSAFER", /* */ "-q", /* Quiet mode. No GS messages. */ "-sDEVICE=ppmraw", /* Format is PPM raw */ "-dBATCH", /* Batch mode. No "quit" necessary. */ "-sPAPERSIZE=letter", /* (optional) Specify paper size. */ "-r100x100", /* (optional) Specify DPI of screen */ "-dNOPAUSE", /* */ "-sOutputFile=-", /* Output file is stdout. */ "-", NULL }; args[1] = (switchesPtr->crop) ? "-dEPSCrop" : "-dSAFER"; { Tk_Window tkwin; unsigned int xdpi, ydpi; tkwin = Tk_MainWindow(interp); if (switchesPtr->dpi > 0) { xdpi = ydpi = switchesPtr->dpi; } else { Blt_ScreenDPI(tkwin, &xdpi, &ydpi); } sprintf(string1, "-r%dx%d", xdpi, ydpi); args[7] = string1; } if (switchesPtr->paperSize != NULL) { sprintf(string2, "-sPAPERSIZE=%s", switchesPtr->paperSize); args[6] = string2; } { int i; Tcl_Obj *objv[11]; int objc = 11; for (i = 0, p = args; *p != NULL; p++, i++) { objv[i] = Tcl_NewStringObj(*p, -1); Tcl_IncrRefCount(objv[i]); } nPids = Blt_CreatePipeline(interp, objc, objv, &pidPtr, &in, &out, (int *)NULL); for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objv[i]); } } if (nPids < 0) { return TCL_ERROR; } Tcl_DetachPids(nPids, (Tcl_Pid *)pidPtr); child = WriteToGhostscript(interp, in, dbuffer); if (child == 0) { return TCL_ERROR; } result = ReadFromGhostscript(interp, out, dbuffer); #ifdef WIN32 CloseHandle((HANDLE)child); #endif Tcl_ReapDetachedProcs(); #ifdef notdef Blt_DBuffer_SaveFile(interp, "junk.ppm", dbuffer); #endif if (result != TCL_OK) { Blt_DBuffer_Free(dbuffer); return TCL_ERROR; } return TCL_OK; } static Blt_Chain PdfToPicture(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PdfImportSwitches *switchesPtr) { Blt_Chain chain; if (PdfToPbm(interp, fileName, dbuffer, switchesPtr) != TCL_OK) { return NULL; } /* Can be more than one image in buffer. Save each picture in a list. */ chain = Blt_Chain_Create(); while (Blt_DBuffer_BytesLeft(dbuffer) > 0) { Blt_Picture picture; picture = PbmToPicture(interp, dbuffer); if (picture == NULL) { Blt_Chain_Destroy(chain); return NULL; } Blt_Chain_Append(chain, picture); } return chain; } static int PictureToPdf(Tcl_Interp *interp, Blt_Picture original, Blt_Ps ps, PdfExportSwitches *switchesPtr) { Picture *srcPtr; int w, h; srcPtr = original; w = srcPtr->width, h = srcPtr->height; Blt_Ps_ComputeBoundingBox(&switchesPtr->setup, w, h); if (PostScriptPreamble(interp, srcPtr, switchesPtr, ps) != TCL_OK) { return TCL_ERROR; } Blt_ClassifyPicture(srcPtr); if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); srcPtr = background; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(srcPtr); } Blt_Ps_Rectangle(ps, 0, 0, srcPtr->width, srcPtr->height); Blt_Ps_Append(ps, "gsave clip\n\n"); Blt_Ps_DrawPicture(ps, srcPtr, 0, 0); Blt_Ps_VarAppend(ps, "\n", "% Unset clipping\n", "grestore\n\n", (char *)NULL); Blt_Ps_VarAppend(ps, "showpage\n", "%Trailer\n", "grestore\n", "end\n", "%EOF\n", (char *)NULL); if (srcPtr != original) { Blt_Free(srcPtr); } return TCL_OK; } static int IsPdf(Blt_DBuffer dbuffer) { unsigned char *bp; Blt_DBuffer_ResetCursor(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < 4) { return FALSE; } bp = Blt_DBuffer_Pointer(dbuffer); return (strncmp("%PDF", (char *)bp, 4) == 0); } static Blt_Chain ReadPdf(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { Blt_Chain chain; PdfImportSwitches switches; memset(&switches, 0, sizeof(switches)); switches.crop = TRUE; chain = PdfToPicture(interp, fileName, dbuffer, &switches); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return chain; } static Tcl_Obj * WritePdf(Tcl_Interp *interp, Blt_Picture picture) { Blt_Ps ps; PdfExportSwitches switches; Tcl_Obj *objPtr; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.setup.reqPaperHeight = 792; /* 11 inches */ switches.setup.reqPaperWidth = 612; /* 8.5 inches */ switches.setup.level = 1; switches.setup.xPad.side1 = 72; switches.setup.xPad.side2 = 72; switches.setup.yPad.side1 = 72; switches.setup.yPad.side2 = 72; switches.setup.flags = 0; ps = Blt_Ps_Create(interp, &switches.setup); result = PictureToPdf(interp, picture, ps, &switches); objPtr = NULL; if (result == TCL_OK) { const char *string; int length; string = Blt_Ps_GetValue(ps, &length); objPtr = Tcl_NewStringObj(string, length); } Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_Ps_Free(ps); return objPtr; } static Blt_Chain ImportPdf(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer dbuffer; PdfImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); switches.crop = TRUE; if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); return NULL; } chain = NULL; dbuffer = Blt_DBuffer_Create(); if (switches.dataObjPtr != NULL) { int nBytes; string = Tcl_GetStringFromObj(switches.dataObjPtr, &nBytes); Blt_DBuffer_AppendData(dbuffer, (unsigned char *)string, nBytes); string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); if (Blt_DBuffer_LoadFile(interp, string, dbuffer) != TCL_OK) { Blt_DBuffer_Destroy(dbuffer); return NULL; } *fileNamePtr = string; } chain = PdfToPicture(interp, string, dbuffer, &switches); Blt_DBuffer_Destroy(dbuffer); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return chain; } static int ExportPdf(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { PdfExportSwitches switches; Blt_Ps pdf; int result; Blt_Picture picture; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.setup.reqPaperHeight = 792; /* 11 inches */ switches.setup.reqPaperWidth = 612; /* 8.5 inches */ switches.setup.level = 1; switches.setup.xPad.side1 = 72; switches.setup.xPad.side2 = 72; switches.setup.yPad.side1 = 72; switches.setup.yPad.side2 = 72; switches.setup.flags = 0; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data switch.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } pdf = Blt_Ps_Create(interp, &switches.setup); result = PictureToPdf(interp, picture, pdf, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_Ps_SaveFile(interp, pdf, fileName); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; int length; const char *string; string = Blt_Ps_GetValue(pdf, &length); objPtr = Tcl_NewStringObj(string, length); objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, objPtr, 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { const char *string; int length; string = Blt_Ps_GetValue(pdf, &length); Tcl_SetStringObj(Tcl_GetObjResult(interp), string, length); } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_Ps_Free(pdf); return result; } int Blt_PicturePdfInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_pdf", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "pdf", /* Name of format. */ IsPdf, /* Discovery routine. */ ReadPdf, /* Import format procedure. */ NULL, /* Export format procedure. */ ImportPdf, /* Import format procedure. */ NULL); /* Export format procedure. */ } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltList.h���������������������������������������������������������������������0000644�0001750�0001750�00000010765�11462120062�014624� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltList.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_LIST_H #define _BLT_LIST_H /* * Acceptable key types for hash tables: */ #ifndef BLT_STRING_KEYS #define BLT_STRING_KEYS 0 #endif #ifndef BLT_ONE_WORD_KEYS #define BLT_ONE_WORD_KEYS ((size_t)-1) #endif typedef struct _Blt_List *Blt_List; typedef struct _Blt_ListNode *Blt_ListNode; typedef union { /* Key has one of these forms: */ const void *oneWordValue; /* One-word value for key. */ unsigned int words[1]; /* Multiple integer words for key. The actual * size will be as large as necessary for this * table's keys. */ char string[4]; /* String for key. The actual size will be as * large as needed to hold the key. */ } Blt_ListKey; /* * A Blt_ListNode is the container structure for the Blt_List. */ struct _Blt_ListNode { Blt_ListNode prev; /* Link to the previous node */ Blt_ListNode next; /* Link to the next node */ Blt_List list; /* List to eventually insert node */ ClientData clientData; /* Pointer to the data object */ Blt_ListKey key; /* MUST BE LAST FIELD IN RECORD!! */ }; typedef int (Blt_ListCompareProc)(Blt_ListNode *node1Ptr, Blt_ListNode *node2Ptr); /* * A Blt_List is a doubly chained list structure. */ struct _Blt_List { Blt_ListNode head; /* Pointer to first element in list */ Blt_ListNode tail; /* Pointer to last element in list */ size_t nNodes; /* Number of node currently in the list. */ size_t type; /* Type of keys in list. */ }; BLT_EXTERN void Blt_List_Init(Blt_List list, size_t type); BLT_EXTERN void Blt_List_Reset(Blt_List list); BLT_EXTERN Blt_List Blt_List_Create(size_t type); BLT_EXTERN void Blt_List_Destroy(Blt_List list); BLT_EXTERN Blt_ListNode Blt_List_CreateNode(Blt_List list, const char *key); BLT_EXTERN void Blt_List_DeleteNode(Blt_ListNode node); BLT_EXTERN Blt_ListNode Blt_List_Append(Blt_List list, const char *key, ClientData clientData); BLT_EXTERN Blt_ListNode Blt_List_Prepend(Blt_List list, const char *key, ClientData clientData); BLT_EXTERN void Blt_List_LinkAfter(Blt_List list, Blt_ListNode node, Blt_ListNode afterNode); BLT_EXTERN void Blt_List_LinkBefore(Blt_List list, Blt_ListNode node, Blt_ListNode beforeNode); BLT_EXTERN void Blt_List_UnlinkNode(Blt_ListNode node); BLT_EXTERN Blt_ListNode Blt_List_GetNode(Blt_List list, const char *key); BLT_EXTERN void Blt_List_DeleteNodeByKey(Blt_List list, const char *key); BLT_EXTERN Blt_ListNode Blt_List_GetNthNode(Blt_List list, long position, int direction); BLT_EXTERN void Blt_List_Sort(Blt_List list, Blt_ListCompareProc *proc); #define Blt_List_GetLength(list) \ (((list) == NULL) ? 0 : ((struct _Blt_List *)list)->nNodes) #define Blt_List_FirstNode(list) \ (((list) == NULL) ? NULL : ((struct _Blt_List *)list)->head) #define Blt_List_LastNode(list) \ (((list) == NULL) ? NULL : ((struct _Blt_List *)list)->tail) #define Blt_List_PrevNode(node) ((node)->prev) #define Blt_List_NextNode(node) ((node)->next) #define Blt_List_GetKey(node) \ (((node)->list->type == BLT_STRING_KEYS) \ ? (node)->key.string : (node)->key.oneWordValue) #define Blt_List_GetValue(node) ((node)->clientData) #define Blt_List_SetValue(node, value) \ ((node)->clientData = (ClientData)(value)) #define Blt_List_AppendNode(list, node) \ (Blt_List_LinkBefore((list), (node), (Blt_ListNode)NULL)) #define Blt_List_PrependNode(list, node) \ (Blt_List_LinkAfter((list), (node), (Blt_ListNode)NULL)) #endif /* _BLT_LIST_H */ �����������./saods9/blt3.0.1/src/bltTable.h��������������������������������������������������������������������0000644�0001750�0001750�00000030024�11462120062�014726� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTable.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_TABLE_H #define _BLT_TABLE_H #include "bltChain.h" #include "bltHash.h" #include "bltList.h" typedef struct { Blt_HashTable tableTable; /* Hash table of table structures keyed by * the address of the reference Tk window */ Tk_Window tkMain; } TableInterpData; typedef struct _Editor Editor; typedef void (EditorDrawProc)(Editor *editor); typedef void (EditorDestroyProc)(DestroyData destroyData); struct _Editor { int gridLineWidth; int buttonHeight; int entryPad; int min; /* Minimum size to allow any partition */ EditorDrawProc *drawProc; EditorDestroyProc *destroyProc; }; #define nRows rows.chain->nLinks #define nColumns cols.chain->nLinks /* * Limits -- * * Defines the bounding of a size (width or height) in the table. It may * be related to the partition, entry, or table size. The widget * pointers are used to associate sizes with the requested size of other * widgets. */ typedef struct { int flags; /* Flags indicate whether using default * values for limits or not. See flags * below. */ int max, min; /* Values for respective limits. */ int nom; /* Nominal starting value. */ Tk_Window wMax, wMin; /* If non-NULL, represents widgets whose * requested sizes will be set as limits. */ Tk_Window wNom; /* If non-NULL represents widget whose * requested size will be the nominal * size. */ } Limits; #define LIMITS_SET_BIT 1 #define LIMITS_SET_MIN (LIMITS_SET_BIT<<0) #define LIMITS_SET_MAX (LIMITS_SET_BIT<<1) #define LIMITS_SET_NOM (LIMITS_SET_BIT<<2) #define LIMITS_MIN 0 /* Default minimum limit */ #define LIMITS_MAX SHRT_MAX/* Default maximum limit */ #define LIMITS_NOM -1000 /* Default nomimal value. Indicates if a * partition has received any space yet */ typedef int (LimitsProc)(int value, Limits *limitsPtr); /* * Resize -- * * These flags indicate in what ways each partition in a table can be * resized from its default dimensions. The normal size of a row/column * is the minimum amount of space needed to hold the widgets that span * it. The table may then be stretched or shrunk depending if the * container is larger or smaller than the table. This can occur if 1) * the user resizes the toplevel widget, or 2) the container is in turn * packed into a larger widget and the "fill" option is set. * * RESIZE_NONE - No resizing from normal size. * RESIZE_EXPAND - Do not allow the size to decrease. * The size may increase however. * RESIZE_SHRINK - Do not allow the size to increase. * The size may decrease however. * RESIZE_BOTH - Allow the size to increase or * decrease from the normal size. * RESIZE_VIRGIN - Special case of the resize flag. Used to * indicate the initial state of the flag. * Empty rows/columns are treated differently * if this row/column is set. */ #define RESIZE_NONE 0 #define RESIZE_EXPAND (1<<0) #define RESIZE_SHRINK (1<<1) #define RESIZE_BOTH (RESIZE_EXPAND | RESIZE_SHRINK) #define RESIZE_VIRGIN (1<<2) /* * Control -- */ #define CONTROL_NORMAL 1.0 /* Consider the widget when calculating the * row heights and column widths. */ #define CONTROL_NONE 0.0 /* Ignore the widget. The height and width of * the rows/columns spanned by this widget * will not affected by the size of the * widget. */ #define CONTROL_FULL -1.0 /* Consider only this widget when determining * the column widths and row heights of the * partitions it spans. */ #define EXCL_PAD 0 #define INCL_PAD 1 typedef struct _Table Table; typedef struct _RowColumn RowColumn; /* * TableEntry -- * * An entry holds a widget and describes how the widget should appear in * a range of cells. * 1. padding. * 2. how many rows/columns the entry spans. * 3. size bounds for the widget. * * Several entries may start at the same cell in the table, but a entry * can hold only one widget. */ typedef struct { Tk_Window tkwin; /* Widget to be managed. */ Table *tablePtr; /* Table managing this widget */ int borderWidth; /* The external border width of the * widget. This is needed to check if * Tk_Changes(tkwin)->border_width changes. */ int manageWhenNeeded; /* If non-zero, allow joint custody of the * widget. This is for cases where the same * widget may be shared between two different * tables (e.g. same graph on two different * notebook pages). Claim the widget only * when the table is mapped. Don't destroy the * entry if the table loses custody of the * widget. */ Limits reqWidth, reqHeight; /* Bounds for width and height requests made * by the widget. */ struct PositionInfo { RowColumn *rcPtr; /* Row or column where this entry starts. */ long span; /* Number of rows or columns spanned. */ float control; /* Weight of widget in the row or column. */ Blt_ChainLink link; /* Link to widget in the chain of spans */ Blt_Chain chain; /* Pointer to the chain of spans. */ } row, column; Tk_Anchor anchor; /* Anchor type: indicates how the widget is * positioned if extra space is available in * the entry */ Blt_Pad xPad; /* Extra padding placed left and right of the * widget. */ Blt_Pad yPad; /* Extra padding placed above and below the * widget */ int ixPad, iyPad; /* Extra padding added to the interior of the * widget (i.e. adds to the requested size of * the widget) */ int fill; /* Indicates how the widget should fill the * span of cells it occupies. */ int x, y; /* Origin of widget wrt container. */ Blt_ChainLink link; /* Pointer into list of entries. */ Blt_HashEntry *hashPtr; /* Pointer into table of entries. */ } TableEntry; /* * RowColumn -- * * Creates a definable space (row or column) in the table. It may have * both requested minimum or maximum values which constrain the size of * it. */ struct _RowColumn { int index; /* Index of row or column */ int size; /* Current size of the partition. This size * is bounded by min and max. */ /* * nom and size perform similar duties. I need to keep track of the * amount of space allocated to the partition (using size). But at the * same time, I need to indicate that space can be parcelled out to this * partition. If a nominal size was set for this partition, I don't want * to add space. */ int nom; /* The nominal size (neither expanded nor * shrunk) of the partition based upon the * requested sizes of the widgets spanning * this partition. */ int min, max; /* Size constraints on the partition */ int offset; /* Offset of the partition (in pixels) from * the origin of the container. */ int minSpan; /* Minimum spanning widget in partition. Used * for bookkeeping when growing a span of * partitions */ float weight; /* Weight of row or column */ TableEntry *control; /* Pointer to the entry that is determining * the size of this partition. This is used * to know when a partition is occupied. */ int resize; /* Indicates if the partition should shrink or * expand from its nominal size. */ Blt_Pad pad; /* Pads the partition beyond its nominal * size */ Limits reqSize; /* Requested bounds for the size of the * partition. The partition will not expand or * shrink beyond these limits, regardless of * how it was specified (max widget size). * This includes any extra padding which may * be specified. */ int maxSpan; /* Maximum spanning widget to consider when * growing a span of partitions. A value of * zero indicates that all spans should be * considered. */ int count; Blt_ChainLink link; }; #define DEF_TBL_RESIZE "both" #define DEF_TBL_PAD "0" #define DEF_TBL_MAXSPAN "0" /* * This is the default number of elements in the statically pre-allocated * column and row arrays. This number should reflect a useful number of row * and columns, which fit most applications. */ #define DEF_ARRAY_SIZE 32 typedef TableEntry *(EntrySearchProc)(Table *tablePtr, Tk_Window tkwin); /* * PartitionInfo -- * * Manages the rows or columns of the table. Contains a chain of * partitions (representing the individiual rows or columns). * */ typedef struct PartitionInfo { char *type; /* String identifying the type of partition: * "row" or "column". */ Blt_Chain chain; Blt_List list; /* Linked list of bins of widgets keyed by * increasing span. */ Blt_ConfigSpec *configSpecs; int reqLength; int ePad; /* Extra padding for row/column needed to * display editor marks */ } PartitionInfo; /* * Table structure */ struct _Table { int flags; /* See the flags definitions below. */ Tk_Window tkwin; /* The container widget into which other * widgets are arranged. */ Tcl_Interp *interp; /* Interpreter associated with all widgets */ Blt_Chain chain; /* Chain of entries in the table. */ Blt_HashTable entryTable; /* Table of entries. Serves as a directory to * look up entries from widget their names. */ Blt_Pad xPad, yPad; int propagate; /* If non-zero, the table will make a geometry * request on behalf of the container * widget. */ int eTablePad, eEntryPad; PartitionInfo cols; PartitionInfo rows; /* Manages row and column partitions */ Dim2D container; /* Last known dimenion of the container. */ Dim2D normal; /* Normal dimensions of the table */ Limits reqWidth, reqHeight; /* Constraints on the table's normal width and * height */ Editor *editPtr; /* If non-NULL, indicates that the table is * currently being edited */ Tcl_IdleProc *arrangeProc; EntrySearchProc *findEntryProc; Blt_HashEntry *hashPtr; /* Used to delete the table from its * hashtable. */ Blt_HashTable *tablePtr; }; /* * Table flags definitions */ #define ARRANGE_PENDING (1<<0) /* A call to ArrangeTable is pending. This * flag allows multiple layout changes to be * requested before the table is actually * reconfigured. */ #define REQUEST_LAYOUT (1<<1) /* Get the requested sizes of the widgets * before expanding/shrinking the size of the * container. It's necessary to recompute the * layout every time a partition or entry is * added, reconfigured, or deleted, but not * when the container is resized. */ #define NON_PARENT (1<<2) /* The table is managing widgets that arern't * children of the container. This requires * that they are manually moved when the * container is moved (a definite performance * hit). */ /* * Forward declarations */ BLT_EXTERN int Blt_GetTable(TableInterpData *dataPtr, Tcl_Interp *interp, const char *pathName, Table **tablePtrPtr); BLT_EXTERN int Blt_GetTableFromObj(TableInterpData *dataPtr, Tcl_Interp *interp, Tcl_Obj *objPtr, Table **tablePtrPtr); #endif /* _BLT_TABLE_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTvCmd.c��������������������������������������������������������������������0000644�0001750�0001750�00000402430�11462120063�014714� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTvCmd.c -- * * This module implements an hierarchy widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * * BUGS: * 1. "open" operation should change scroll offset so that as many * new entries (up to half a screen) can be seen. * 2. "open" needs to adjust the scrolloffset so that the same entry * is seen at the same place. */ #include "bltInt.h" #ifndef NO_TREEVIEW #include "bltOp.h" #include "bltTreeView.h" #include "bltList.h" #include "bltSwitch.h" #include <X11/Xutil.h> #include <X11/Xatom.h> #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define DEF_ICON_WIDTH 16 static TreeViewCompareProc ExactCompare, GlobCompare, RegexpCompare; static TreeViewApplyProc ShowEntryApplyProc, HideEntryApplyProc, MapAncestorsApplyProc, FixSelectionsApplyProc; static Tk_LostSelProc LostSelection; static TreeViewApplyProc SelectEntryApplyProc; BLT_EXTERN Blt_CustomOption bltTreeViewIconsOption; BLT_EXTERN Blt_CustomOption bltTreeViewUidOption; BLT_EXTERN Blt_CustomOption bltTreeViewTreeOption; BLT_EXTERN Blt_ConfigSpec bltTreeViewButtonSpecs[]; BLT_EXTERN Blt_ConfigSpec bltTreeViewSpecs[]; BLT_EXTERN Blt_ConfigSpec bltTreeViewEntrySpecs[]; typedef struct { int mask; } ChildrenSwitches; static Blt_SwitchSpec childrenSwitches[] = { {BLT_SWITCH_BITMASK, "-exposed", "", Blt_Offset(ChildrenSwitches, mask), 0, ENTRY_MASK}, {BLT_SWITCH_END} }; typedef int (TvCmdProc)(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #define TAG_UNKNOWN (1<<0) #define TAG_RESERVED (1<<1) #define TAG_USER_DEFINED (1<<2) #define TAG_SINGLE (1<<3) #define TAG_MULTIPLE (1<<4) #define TAG_ALL (1<<5) #define NodeToObj(n) Tcl_NewLongObj(Blt_Tree_NodeId(n)) /* *--------------------------------------------------------------------------- * * SkipSeparators -- * * Moves the character pointer past one of more separators. * * Results: * Returns the updates character pointer. * *--------------------------------------------------------------------------- */ static const char * SkipSeparators(const char *path, const char *separator, int length) { while ((path[0] == separator[0]) && (strncmp(path, separator, length) == 0)) { path += length; } return path; } /* *--------------------------------------------------------------------------- * * DeleteNode -- * * Delete the node and its descendants. Don't remove the root node, * though. If the root node is specified, simply remove all its * children. * *--------------------------------------------------------------------------- */ static void DeleteNode(TreeView *viewPtr, Blt_TreeNode node) { Blt_TreeNode root; if (!Blt_Tree_TagTableIsShared(viewPtr->tree)) { Blt_Tree_ClearTags(viewPtr->tree, node); } root = Blt_Tree_RootNode(viewPtr->tree); if (node == root) { Blt_TreeNode next; /* Don't delete the root node. Simply clean out the tree. */ for (node = Blt_Tree_FirstChild(node); node != NULL; node = next) { next = Blt_Tree_NextSibling(node); Blt_Tree_DeleteNode(viewPtr->tree, node); } } else if (Blt_Tree_IsAncestor(root, node)) { Blt_Tree_DeleteNode(viewPtr->tree, node); } } /* *--------------------------------------------------------------------------- * * SplitPath -- * * Returns the trailing component of the given path. Trailing separators * are ignored. * * Results: * Returns the string of the tail component. * *--------------------------------------------------------------------------- */ static int SplitPath(TreeView *viewPtr, const char *path, long *depthPtr, const char ***argvPtr) { int skipLen, pathLen; long depth; size_t listSize; char **argv; char *p; char *sep; if (viewPtr->pathSep == SEPARATOR_LIST) { int nElem; if (Tcl_SplitList(viewPtr->interp, path, &nElem, argvPtr) != TCL_OK) { return TCL_ERROR; } *depthPtr = (long)nElem; return TCL_OK; } pathLen = strlen(path); skipLen = strlen(viewPtr->pathSep); path = SkipSeparators(path, viewPtr->pathSep, skipLen); depth = pathLen / skipLen; listSize = (depth + 1) * sizeof(char *); argv = Blt_AssertMalloc(listSize + (pathLen + 1)); p = (char *)argv + listSize; strcpy(p, path); sep = strstr(p, viewPtr->pathSep); depth = 0; while ((*p != '\0') && (sep != NULL)) { *sep = '\0'; argv[depth++] = p; p = (char *)SkipSeparators(sep + skipLen, viewPtr->pathSep, skipLen); sep = strstr(p, viewPtr->pathSep); } if (*p != '\0') { argv[depth++] = p; } argv[depth] = NULL; *depthPtr = depth; *argvPtr = (const char **)argv; return TCL_OK; } static TreeViewEntry * LastEntry(TreeView *viewPtr, TreeViewEntry *entryPtr, unsigned int mask) { TreeViewEntry *nextPtr; nextPtr = Blt_TreeView_LastChild(entryPtr, mask); while (nextPtr != NULL) { entryPtr = nextPtr; nextPtr = Blt_TreeView_LastChild(entryPtr, mask); } return entryPtr; } /* *--------------------------------------------------------------------------- * * ShowEntryApplyProc -- * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ShowEntryApplyProc(TreeView *viewPtr, TreeViewEntry *entryPtr) { entryPtr->flags &= ~ENTRY_HIDE; return TCL_OK; } /* *--------------------------------------------------------------------------- * * HideEntryApplyProc -- * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HideEntryApplyProc(TreeView *viewPtr, TreeViewEntry *entryPtr) { entryPtr->flags |= ENTRY_HIDE; return TCL_OK; } static void MapAncestors(TreeView *viewPtr, TreeViewEntry *entryPtr) { while (entryPtr != viewPtr->rootPtr) { entryPtr = Blt_TreeView_ParentEntry(entryPtr); if (entryPtr->flags & (ENTRY_CLOSED | ENTRY_HIDE)) { viewPtr->flags |= LAYOUT_PENDING; entryPtr->flags &= ~(ENTRY_CLOSED | ENTRY_HIDE); } } } /* *--------------------------------------------------------------------------- * * MapAncestorsApplyProc -- * * If a node in mapped, then all its ancestors must be mapped also. This * routine traverses upwards and maps each unmapped ancestor. It's * assumed that for any mapped ancestor, all it's ancestors will already * be mapped too. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int MapAncestorsApplyProc(TreeView *viewPtr, TreeViewEntry *entryPtr) { /* * Make sure that all the ancestors of this entry are mapped too. */ while (entryPtr != viewPtr->rootPtr) { entryPtr = Blt_TreeView_ParentEntry(entryPtr); if ((entryPtr->flags & (ENTRY_HIDE | ENTRY_CLOSED)) == 0) { break; /* Assume ancestors are also mapped. */ } entryPtr->flags &= ~(ENTRY_HIDE | ENTRY_CLOSED); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindPath -- * * Finds the node designated by the given path. Each path component is * searched for as the tree is traversed. * * A leading character string is trimmed off the path if it matches the * one designated (see the -trimleft option). * * If no separator is designated (see the -separator configuration * option), the path is considered a TCL list. Otherwise the each * component of the path is separated by a character string. Leading and * trailing separators are ignored. Multiple separators are treated as * one. * * Results: * Returns the pointer to the designated node. If any component can't be * found, NULL is returned. * *--------------------------------------------------------------------------- */ static TreeViewEntry * FindPath(TreeView *viewPtr, TreeViewEntry *rootPtr, const char *path) { Blt_TreeNode child; const char **argv; const char *name; long nComp; const char **p; TreeViewEntry *entryPtr; /* Trim off characters that we don't want */ if (viewPtr->trimLeft != NULL) { const char *s1, *s2; /* Trim off leading character string if one exists. */ for (s1 = path, s2 = viewPtr->trimLeft; *s2 != '\0'; s2++, s1++) { if (*s1 != *s2) { break; } } if (*s2 == '\0') { path = s1; } } if (*path == '\0') { return rootPtr; } name = path; entryPtr = rootPtr; if (viewPtr->pathSep == SEPARATOR_NONE) { child = Blt_Tree_FindChild(entryPtr->node, name); if (child == NULL) { goto error; } return Blt_TreeView_NodeToEntry(viewPtr, child); } if (SplitPath(viewPtr, path, &nComp, &argv) != TCL_OK) { return NULL; } for (p = argv; *p != NULL; p++) { name = *p; child = Blt_Tree_FindChild(entryPtr->node, name); if (child == NULL) { Blt_Free(argv); goto error; } entryPtr = Blt_TreeView_NodeToEntry(viewPtr, child); } Blt_Free(argv); return entryPtr; error: { Tcl_DString dString; Blt_TreeView_GetFullName(viewPtr, entryPtr, FALSE, &dString); Tcl_AppendResult(viewPtr->interp, "can't find node \"", name, "\" in parent node \"", Tcl_DStringValue(&dString), "\"", (char *)NULL); Tcl_DStringFree(&dString); } return NULL; } static int GetEntryFromSpecialId(TreeView *viewPtr, const char *string, TreeViewEntry **entryPtrPtr) { Blt_TreeNode node; TreeViewEntry *fromPtr, *entryPtr; char c; entryPtr = NULL; fromPtr = viewPtr->fromPtr; if (fromPtr == NULL) { fromPtr = viewPtr->focusPtr; } if (fromPtr == NULL) { fromPtr = viewPtr->rootPtr; } c = string[0]; if (c == '@') { int x, y; if (Blt_GetXY(viewPtr->interp, viewPtr->tkwin, string, &x, &y) == TCL_OK) { *entryPtrPtr = Blt_TreeView_NearestEntry(viewPtr, x, y, TRUE); } } else if ((c == 'b') && (strcmp(string, "bottom") == 0)) { if (viewPtr->flatView) { entryPtr = viewPtr->flatArr[viewPtr->nEntries - 1]; } else { entryPtr = LastEntry(viewPtr, viewPtr->rootPtr, ENTRY_MASK); } } else if ((c == 't') && (strcmp(string, "top") == 0)) { if (viewPtr->flatView) { entryPtr = viewPtr->flatArr[0]; } else { entryPtr = viewPtr->rootPtr; if (viewPtr->flags & HIDE_ROOT) { entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK); } } } else if ((c == 'e') && (strcmp(string, "end") == 0)) { entryPtr = LastEntry(viewPtr, viewPtr->rootPtr, ENTRY_MASK); } else if ((c == 'a') && (strcmp(string, "anchor") == 0)) { entryPtr = viewPtr->selAnchorPtr; } else if ((c == 'f') && (strcmp(string, "focus") == 0)) { entryPtr = viewPtr->focusPtr; if ((entryPtr == viewPtr->rootPtr) && (viewPtr->flags & HIDE_ROOT)) { entryPtr = Blt_TreeView_NextEntry(viewPtr->rootPtr, ENTRY_MASK); } } else if ((c == 'r') && (strcmp(string, "root") == 0)) { entryPtr = viewPtr->rootPtr; } else if ((c == 'p') && (strcmp(string, "parent") == 0)) { if (fromPtr != viewPtr->rootPtr) { entryPtr = Blt_TreeView_ParentEntry(fromPtr); } } else if ((c == 'c') && (strcmp(string, "current") == 0)) { /* Can't trust picked item, if entries have been added or deleted. */ if (!(viewPtr->flags & DIRTY)) { ClientData context; context = Blt_GetCurrentContext(viewPtr->bindTable); if ((context == ITEM_ENTRY) || (context == ITEM_ENTRY_BUTTON) || (context >= ITEM_STYLE)) { entryPtr = Blt_GetCurrentItem(viewPtr->bindTable); } } } else if ((c == 'u') && (strcmp(string, "up") == 0)) { entryPtr = fromPtr; if (viewPtr->flatView) { int i; i = entryPtr->flatIndex - 1; if (i >= 0) { entryPtr = viewPtr->flatArr[i]; } } else { entryPtr = Blt_TreeView_PrevEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = fromPtr; } if ((entryPtr == viewPtr->rootPtr) && (viewPtr->flags & HIDE_ROOT)) { entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK); } } } else if ((c == 'd') && (strcmp(string, "down") == 0)) { entryPtr = fromPtr; if (viewPtr->flatView) { int i; i = entryPtr->flatIndex + 1; if (i < viewPtr->nEntries) { entryPtr = viewPtr->flatArr[i]; } } else { entryPtr = Blt_TreeView_NextEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = fromPtr; } if ((entryPtr == viewPtr->rootPtr) && (viewPtr->flags & HIDE_ROOT)) { entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK); } } } else if (((c == 'l') && (strcmp(string, "last") == 0)) || ((c == 'p') && (strcmp(string, "prev") == 0))) { entryPtr = fromPtr; if (viewPtr->flatView) { int i; i = entryPtr->flatIndex - 1; if (i < 0) { i = viewPtr->nEntries - 1; } entryPtr = viewPtr->flatArr[i]; } else { entryPtr = Blt_TreeView_PrevEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = LastEntry(viewPtr, viewPtr->rootPtr, ENTRY_MASK); } if ((entryPtr == viewPtr->rootPtr) && (viewPtr->flags & HIDE_ROOT)) { entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK); } } } else if ((c == 'n') && (strcmp(string, "next") == 0)) { entryPtr = fromPtr; if (viewPtr->flatView) { int i; i = entryPtr->flatIndex + 1; if (i >= viewPtr->nEntries) { i = 0; } entryPtr = viewPtr->flatArr[i]; } else { entryPtr = Blt_TreeView_NextEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { if (viewPtr->flags & HIDE_ROOT) { entryPtr = Blt_TreeView_NextEntry(viewPtr->rootPtr,ENTRY_MASK); } else { entryPtr = viewPtr->rootPtr; } } } } else if ((c == 'n') && (strcmp(string, "nextsibling") == 0)) { node = Blt_Tree_NextSibling(fromPtr->node); if (node != NULL) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); } } else if ((c == 'p') && (strcmp(string, "prevsibling") == 0)) { node = Blt_Tree_PrevSibling(fromPtr->node); if (node != NULL) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); } } else if ((c == 'v') && (strcmp(string, "view.top") == 0)) { if (viewPtr->nVisible > 0) { entryPtr = viewPtr->visibleArr[0]; } } else if ((c == 'v') && (strcmp(string, "view.bottom") == 0)) { if (viewPtr->nVisible > 0) { entryPtr = viewPtr->visibleArr[viewPtr->nVisible - 1]; } } else { return TCL_ERROR; } *entryPtrPtr = entryPtr; return TCL_OK; } static int GetTagIter(TreeView *viewPtr, char *tagName, TreeViewTagIter *iterPtr) { iterPtr->tagType = TAG_RESERVED | TAG_SINGLE; iterPtr->entryPtr = NULL; if (strcmp(tagName, "all") == 0) { iterPtr->entryPtr = viewPtr->rootPtr; iterPtr->tagType |= TAG_ALL; } else { Blt_HashTable *tablePtr; tablePtr = Blt_Tree_TagHashTable(viewPtr->tree, tagName); if (tablePtr != NULL) { Blt_HashEntry *hPtr; iterPtr->tagType = TAG_USER_DEFINED; /* Empty tags are not an * error. */ hPtr = Blt_FirstHashEntry(tablePtr, &iterPtr->cursor); if (hPtr != NULL) { Blt_TreeNode node; node = Blt_GetHashValue(hPtr); iterPtr->entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (tablePtr->numEntries > 1) { iterPtr->tagType |= TAG_MULTIPLE; } } } else { iterPtr->tagType = TAG_UNKNOWN; Tcl_AppendResult(viewPtr->interp, "can't find tag or id \"", tagName, "\" in \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } } return TCL_OK; } /*ARGSUSED*/ void Blt_TreeView_GetTags(Tcl_Interp *interp, TreeView *viewPtr, TreeViewEntry *entryPtr, Blt_List list) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Blt_TreeTagEntry *tPtr; for (hPtr = Blt_Tree_FirstTag(viewPtr->tree, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { tPtr = Blt_GetHashValue(hPtr); hPtr = Blt_FindHashEntry(&tPtr->nodeTable, (char *)entryPtr->node); if (hPtr != NULL) { Blt_List_Append(list, Blt_TreeView_GetUid(viewPtr, tPtr->tagName), 0); } } } /* *--------------------------------------------------------------------------- * * AddTag -- * *--------------------------------------------------------------------------- */ static int AddTag(TreeView *viewPtr, Blt_TreeNode node, const char *tagName) { TreeViewEntry *entryPtr; if (strcmp(tagName, "root") == 0) { Tcl_AppendResult(viewPtr->interp, "can't add reserved tag \"", tagName, "\"", (char *)NULL); return TCL_ERROR; } if (isdigit(UCHAR(tagName[0]))) { long inode; if (TclGetLong(NULL, tagName, &inode) == TCL_OK) { Tcl_AppendResult(viewPtr->interp, "invalid tag \"", tagName, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } } if (tagName[0] == '@') { Tcl_AppendResult(viewPtr->interp, "invalid tag \"", tagName, "\": can't start with \"@\"", (char *)NULL); return TCL_ERROR; } viewPtr->fromPtr = NULL; if (GetEntryFromSpecialId(viewPtr, tagName, &entryPtr) == TCL_OK) { Tcl_AppendResult(viewPtr->interp, "invalid tag \"", tagName, "\": is a special id", (char *)NULL); return TCL_ERROR; } /* Add the tag to the node. */ Blt_Tree_AddTag(viewPtr->tree, node, tagName); return TCL_OK; } TreeViewEntry * Blt_TreeView_FirstTaggedEntry(TreeViewTagIter *iterPtr) { return iterPtr->entryPtr; } int Blt_TreeView_FindTaggedEntries(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewTagIter *iterPtr) { char *tagName; TreeViewEntry *entryPtr; long inode; tagName = Tcl_GetString(objPtr); viewPtr->fromPtr = NULL; if ((isdigit(UCHAR(tagName[0]))) && (Tcl_GetLongFromObj(viewPtr->interp, objPtr, &inode) == TCL_OK)) { Blt_TreeNode node; node = Blt_Tree_GetNode(viewPtr->tree, inode); if (node == NULL) { Tcl_AppendResult(viewPtr->interp, "can't find node \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } iterPtr->entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); iterPtr->tagType = (TAG_RESERVED | TAG_SINGLE); } else if (GetEntryFromSpecialId(viewPtr, tagName, &entryPtr) == TCL_OK) { iterPtr->entryPtr = entryPtr; iterPtr->tagType = (TAG_RESERVED | TAG_SINGLE); } else { if (GetTagIter(viewPtr, tagName, iterPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } TreeViewEntry * Blt_TreeView_NextTaggedEntry(TreeViewTagIter *iterPtr) { TreeViewEntry *entryPtr; entryPtr = NULL; if (iterPtr->entryPtr != NULL) { TreeView *viewPtr = iterPtr->entryPtr->viewPtr; if (iterPtr->tagType & TAG_ALL) { entryPtr = Blt_TreeView_NextEntry(iterPtr->entryPtr, 0); } else if (iterPtr->tagType & TAG_MULTIPLE) { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { Blt_TreeNode node; node = Blt_GetHashValue(hPtr); entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); } } iterPtr->entryPtr = entryPtr; } return entryPtr; } /* *--------------------------------------------------------------------------- * * GetEntryFromObj2 -- * * Converts a string into node pointer. The string may be in one of the * following forms: * * NNN - inode. * "active" - Currently active node. * "anchor" - anchor of selected region. * "current" - Currently picked node in bindtable. * "focus" - The node currently with focus. * "root" - Root node. * "end" - Last open node in the entire hierarchy. * "next" - Next open node from the currently active * node. Wraps around back to top. * "last" - Previous open node from the currently active * node. Wraps around back to bottom. * "up" - Next open node from the currently active * node. Does not wrap around. * "down" - Previous open node from the currently active * node. Does not wrap around. * "nextsibling" - Next sibling of the current node. * "prevsibling" - Previous sibling of the current node. * "parent" - Parent of the current node. * "view.top" - Top of viewport. * "view.bottom" - Bottom of viewport. * @x,y - Closest node to the specified X-Y position. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via nodePtr. Otherwise, TCL_ERROR is * returned and an error message is left in interpreter's result field. * *--------------------------------------------------------------------------- */ static int GetEntryFromObj2(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewEntry **entryPtrPtr) { Tcl_Interp *interp; char *string; TreeViewTagIter iter; long inode; interp = viewPtr->interp; string = Tcl_GetString(objPtr); *entryPtrPtr = NULL; if ((isdigit(UCHAR(string[0]))) && (Tcl_GetLongFromObj(interp, objPtr, &inode) == TCL_OK)) { Blt_TreeNode node; node = Blt_Tree_GetNode(viewPtr->tree, inode); if (node != NULL) { *entryPtrPtr = Blt_TreeView_NodeToEntry(viewPtr, node); } return TCL_OK; /* Node Id. */ } if (GetEntryFromSpecialId(viewPtr, string, entryPtrPtr) == TCL_OK) { return TCL_OK; /* Special Id. */ } if (GetTagIter(viewPtr, string, &iter) != TCL_OK) { return TCL_ERROR; } if (iter.tagType & TAG_MULTIPLE) { Tcl_AppendResult(interp, "more than one entry tagged as \"", string, "\"", (char *)NULL); return TCL_ERROR; } *entryPtrPtr = iter.entryPtr; return TCL_OK; /* Singleton tag. */ } static int GetEntryFromObj(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewEntry **entryPtrPtr) { viewPtr->fromPtr = NULL; return GetEntryFromObj2(viewPtr, objPtr, entryPtrPtr); } /* *--------------------------------------------------------------------------- * * Blt_TreeView_GetEntry -- * * Returns an entry based upon its index. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via nodePtr. Otherwise, TCL_ERROR is * returned and an error message is left in interpreter's result field. * *--------------------------------------------------------------------------- */ int Blt_TreeView_GetEntry(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewEntry **entryPtrPtr) { TreeViewEntry *entryPtr; if (GetEntryFromObj(viewPtr, objPtr, &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { Tcl_ResetResult(viewPtr->interp); Tcl_AppendResult(viewPtr->interp, "can't find entry \"", Tcl_GetString(objPtr), "\" in \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } *entryPtrPtr = entryPtr; return TCL_OK; } static Blt_TreeNode GetNthNode(Blt_TreeNode parent, long position) { Blt_TreeNode node; long count; count = 0; for(node = Blt_Tree_FirstChild(parent); node != NULL; node = Blt_Tree_NextSibling(node)) { if (count == position) { return node; } } return Blt_Tree_LastChild(parent); } /* * Preprocess the command string for percent substitution. */ void Blt_TreeView_PercentSubst( TreeView *viewPtr, TreeViewEntry *entryPtr, const char *command, Tcl_DString *resultPtr) { const char *last, *p; const char *fullName; Tcl_DString dString; /* * Get the full path name of the node, in case we need to substitute for * it. */ Tcl_DStringInit(&dString); fullName = Blt_TreeView_GetFullName(viewPtr, entryPtr, TRUE, &dString); Tcl_DStringInit(resultPtr); /* Append the widget name and the node .t 0 */ for (last = p = command; *p != '\0'; p++) { if (*p == '%') { const char *string; char buf[3]; if (p > last) { Tcl_DStringAppend(resultPtr, last, p - last); } switch (*(p + 1)) { case '%': /* Percent sign */ string = "%"; break; case 'W': /* Widget name */ string = Tk_PathName(viewPtr->tkwin); break; case 'P': /* Full pathname */ string = fullName; break; case 'p': /* Name of the node */ string = GETLABEL(entryPtr); break; case '#': /* Node identifier */ string = Blt_Tree_NodeIdAscii(entryPtr->node); break; default: if (*(p + 1) == '\0') { p--; } buf[0] = *p, buf[1] = *(p + 1), buf[2] = '\0'; string = buf; break; } Tcl_DStringAppend(resultPtr, string, -1); p++; last = p + 1; } } if (p > last) { Tcl_DStringAppend(resultPtr, last, p-last); } Tcl_DStringFree(&dString); } /* *--------------------------------------------------------------------------- * * SelectEntryApplyProc -- * * Sets the selection flag for a node. The selection flag is * set/cleared/toggled based upon the flag set in the treeview widget. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int SelectEntryApplyProc(TreeView *viewPtr, TreeViewEntry *entryPtr) { Blt_HashEntry *hPtr; switch (viewPtr->flags & TV_SELECT_MASK) { case TV_SELECT_CLEAR: Blt_TreeView_DeselectEntry(viewPtr, entryPtr); break; case TV_SELECT_SET: Blt_TreeView_SelectEntry(viewPtr, entryPtr); break; case TV_SELECT_TOGGLE: hPtr = Blt_FindHashEntry(&viewPtr->selectTable, (char *)entryPtr); if (hPtr != NULL) { Blt_TreeView_DeselectEntry(viewPtr, entryPtr); } else { Blt_TreeView_SelectEntry(viewPtr, entryPtr); } break; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * EventuallyInvokeSelectCmd -- * * Queues a request to execute the -selectcommand code associated with * the widget at the next idle point. Invoked whenever the selection * changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ static void EventuallyInvokeSelectCmd(TreeView *viewPtr) { if (!(viewPtr->flags & TV_SELECT_PENDING)) { viewPtr->flags |= TV_SELECT_PENDING; Tcl_DoWhenIdle(Blt_TreeView_SelectCmdProc, viewPtr); } } /* *--------------------------------------------------------------------------- * * Blt_TreeView_PruneSelection -- * * The root entry being deleted or closed. Deselect any of its * descendants that are currently selected. * * Results: * None. * * Side effects: * If any of the entry's descendants are deselected the widget is * redrawn and the a selection command callback is invoked (if there's * one configured). * *--------------------------------------------------------------------------- */ void Blt_TreeView_PruneSelection(TreeView *viewPtr, TreeViewEntry *rootPtr) { Blt_ChainLink link, next; TreeViewEntry *entryPtr; int selectionChanged; /* * Check if any of the currently selected entries are a descendant of of * the current root entry. Deselect the entry and indicate that the * treeview widget needs to be redrawn. */ selectionChanged = FALSE; for (link = Blt_Chain_FirstLink(viewPtr->selected); link != NULL; link = next) { next = Blt_Chain_NextLink(link); entryPtr = Blt_Chain_GetValue(link); if (Blt_Tree_IsAncestor(rootPtr->node, entryPtr->node)) { Blt_TreeView_DeselectEntry(viewPtr, entryPtr); selectionChanged = TRUE; } } if (selectionChanged) { Blt_TreeView_EventuallyRedraw(viewPtr); if (viewPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(viewPtr); } } } /* *--------------------------------------------------------------------------- * * TreeView operations * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FocusOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { long inode; if (objc == 3) { TreeViewEntry *entryPtr; if (GetEntryFromObj(viewPtr, objv[2], &entryPtr) != TCL_OK) { return TCL_ERROR; } if ((entryPtr != NULL) && (entryPtr != viewPtr->focusPtr)) { if (entryPtr->flags & ENTRY_HIDE) { /* Doesn't make sense to set focus to a node you can't see. */ MapAncestors(viewPtr, entryPtr); } /* Changing focus can only affect the visible entries. The entry * layout stays the same. */ if (viewPtr->focusPtr != NULL) { viewPtr->focusPtr->flags |= ENTRY_REDRAW; } entryPtr->flags |= ENTRY_REDRAW; viewPtr->flags |= SCROLL_PENDING; viewPtr->focusPtr = entryPtr; } Blt_TreeView_EventuallyRedraw(viewPtr); } Blt_SetFocusItem(viewPtr->bindTable, viewPtr->focusPtr, ITEM_ENTRY); inode = -1; if (viewPtr->focusPtr != NULL) { inode = Blt_Tree_NodeId(viewPtr->focusPtr->node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BboxOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BboxOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; TreeViewEntry *entryPtr; int width, height, yBot; int left, top, right, bottom; int screen; int lWidth; char *string; if (viewPtr->flags & LAYOUT_PENDING) { /* * The layout is dirty. Recompute it now, before we use the world * dimensions. But remember, the "bbox" operation isn't valid for * hidden entries (since they're not visible, they don't have world * coordinates). */ Blt_TreeView_ComputeLayout(viewPtr); } left = viewPtr->worldWidth; top = viewPtr->worldHeight; right = bottom = 0; screen = FALSE; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-screen") == 0)) { screen = TRUE; objc--, objv++; } for (i = 2; i < objc; i++) { string = Tcl_GetString(objv[i]); if ((string[0] == 'a') && (strcmp(string, "all") == 0)) { left = top = 0; right = viewPtr->worldWidth; bottom = viewPtr->worldHeight; break; } if (GetEntryFromObj(viewPtr, objv[i], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { continue; } if (entryPtr->flags & ENTRY_HIDE) { continue; } yBot = entryPtr->worldY + entryPtr->height; height = VPORTHEIGHT(viewPtr); if ((yBot <= viewPtr->yOffset) && (entryPtr->worldY >= (viewPtr->yOffset + height))) { continue; } if (bottom < yBot) { bottom = yBot; } if (top > entryPtr->worldY) { top = entryPtr->worldY; } lWidth = ICONWIDTH(DEPTH(viewPtr, entryPtr->node)); if (right < (entryPtr->worldX + entryPtr->width + lWidth)) { right = (entryPtr->worldX + entryPtr->width + lWidth); } if (left > entryPtr->worldX) { left = entryPtr->worldX; } } if (screen) { width = VPORTWIDTH(viewPtr); height = VPORTHEIGHT(viewPtr); /* * Do a min-max text for the intersection of the viewport and the * computed bounding box. If there is no intersection, return the * empty string. */ if ((right < viewPtr->xOffset) || (bottom < viewPtr->yOffset) || (left >= (viewPtr->xOffset + width)) || (top >= (viewPtr->yOffset + height))) { return TCL_OK; } /* Otherwise clip the coordinates at the view port boundaries. */ if (left < viewPtr->xOffset) { left = viewPtr->xOffset; } else if (right > (viewPtr->xOffset + width)) { right = viewPtr->xOffset + width; } if (top < viewPtr->yOffset) { top = viewPtr->yOffset; } else if (bottom > (viewPtr->yOffset + height)) { bottom = viewPtr->yOffset + height; } left = SCREENX(viewPtr, left), top = SCREENY(viewPtr, top); right = SCREENX(viewPtr, right), bottom = SCREENY(viewPtr, bottom); } if ((left < right) && (top < bottom)) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(left)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(top)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(right - left)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(bottom - top)); Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } static void DrawButton(TreeView *viewPtr, TreeViewEntry *entryPtr) { Drawable drawable; int sx, sy, dx, dy; int width, height; int left, right, top, bottom; dx = SCREENX(viewPtr, entryPtr->worldX) + entryPtr->buttonX; dy = SCREENY(viewPtr, entryPtr->worldY) + entryPtr->buttonY; width = viewPtr->button.width; height = viewPtr->button.height; top = viewPtr->titleHeight + viewPtr->inset; bottom = Tk_Height(viewPtr->tkwin) - viewPtr->inset; left = viewPtr->inset; right = Tk_Width(viewPtr->tkwin) - viewPtr->inset; if (((dx + width) < left) || (dx > right) || ((dy + height) < top) || (dy > bottom)) { return; /* Value is clipped. */ } drawable = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), width, height, Tk_Depth(viewPtr->tkwin)); /* Draw the background of the value. */ Blt_TreeView_DrawButton(viewPtr, entryPtr, drawable, 0, 0); /* Clip the drawable if necessary */ sx = sy = 0; if (dx < left) { width -= left - dx; sx += left - dx; dx = left; } if ((dx + width) >= right) { width -= (dx + width) - right; } if (dy < top) { height -= top - dy; sy += top - dy; dy = top; } if ((dy + height) >= bottom) { height -= (dy + height) - bottom; } XCopyArea(viewPtr->display, drawable, Tk_WindowId(viewPtr->tkwin), viewPtr->lineGC, sx, sy, width, height, dx, dy); Tk_FreePixmap(viewPtr->display, drawable); } /* *--------------------------------------------------------------------------- * * ButtonActivateOp -- * * Selects the button to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonActivateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *oldPtr, *newPtr; char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { newPtr = NULL; } else if (GetEntryFromObj(viewPtr, objv[3], &newPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->treeColumn.flags & COLUMN_HIDDEN) { return TCL_OK; } if ((newPtr != NULL) && !(newPtr->flags & ENTRY_HAS_BUTTON)) { newPtr = NULL; } oldPtr = viewPtr->activeBtnPtr; viewPtr->activeBtnPtr = newPtr; if (!(viewPtr->flags & REDRAW_PENDING) && (newPtr != oldPtr)) { if ((oldPtr != NULL) && (oldPtr != viewPtr->rootPtr)) { DrawButton(viewPtr, oldPtr); } if ((newPtr != NULL) && (newPtr != viewPtr->rootPtr)) { DrawButton(viewPtr, newPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonBindOp -- * * .t bind tag sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonBindOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData object; char *string; string = Tcl_GetString(objv[3]); /* Assume that this is a binding tag. */ object = Blt_TreeView_ButtonTag(viewPtr, string); return Blt_ConfigureBindingsFromObj(interp, viewPtr->bindTable, object, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * ButtonCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonCgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewButtonSpecs, (char *)viewPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ButtonConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure the one of more entries in the * widget. * * .h button configure option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for viewPtr; old resources get freed, if there were any. The * hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int ButtonConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewButtonSpecs, (char *)viewPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewButtonSpecs, (char *)viewPtr, objv[3], 0); } bltTreeViewIconsOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(viewPtr->interp, viewPtr->tkwin, bltTreeViewButtonSpecs, objc - 3, objv + 3, (char *)viewPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } Blt_TreeView_ConfigureButtons(viewPtr); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonOp -- * * This procedure handles button operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec buttonOps[] = { {"activate", 1, ButtonActivateOp, 4, 4, "tagOrId",}, {"bind", 1, ButtonBindOp, 4, 6, "tagName ?sequence command?",}, {"cget", 2, ButtonCgetOp, 4, 4, "option",}, {"configure", 2, ButtonConfigureOp, 3, 0, "?option value?...",}, {"highlight", 1, ButtonActivateOp, 4, 4, "tagOrId",}, }; static int nButtonOps = sizeof(buttonOps) / sizeof(Blt_OpSpec); static int ButtonOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TvCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nButtonOps, buttonOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewSpecs, (char *)viewPtr, objv[2], 0); } /*ARGSUSED*/ static int CloseOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; TreeViewTagIter iter; int recurse, result; int i; recurse = FALSE; if (objc > 2) { char *string; int length; string = Tcl_GetStringFromObj(objv[2], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } } for (i = 2; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { /* * Clear the selections for any entries that may have become * hidden by closing the node. */ Blt_TreeView_PruneSelection(viewPtr, entryPtr); /* * Check if either the "focus" entry or selection anchor is in * this hierarchy. Must move it or disable it before we close * the node. Otherwise it may be deleted by a TCL "close" * script, and we'll be left pointing to a bogus memory location. */ if ((viewPtr->focusPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->focusPtr->node))){ viewPtr->focusPtr = entryPtr; Blt_SetFocusItem(viewPtr->bindTable, viewPtr->focusPtr, ITEM_ENTRY); } if ((viewPtr->selAnchorPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->selAnchorPtr->node))) { viewPtr->selMarkPtr = viewPtr->selAnchorPtr = NULL; } if ((viewPtr->activePtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node,viewPtr->activePtr->node))){ viewPtr->activePtr = entryPtr; } if (recurse) { result = Blt_TreeView_Apply(viewPtr, entryPtr, Blt_TreeView_CloseEntry, 0); } else { result = Blt_TreeView_CloseEntry(viewPtr, entryPtr); } if (result != TCL_OK) { return TCL_ERROR; } } } /* Closing a node may affect the visible entries and the the world layout * of the entries. */ viewPtr->flags |= (LAYOUT_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for viewPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewSpecs, (char *)viewPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewSpecs, (char *)viewPtr, objv[2], 0); } bltTreeViewIconsOption.clientData = viewPtr; bltTreeViewTreeOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, bltTreeViewSpecs, objc - 2, objv + 2, (char *)viewPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if (Blt_TreeView_UpdateWidget(interp, viewPtr) != TCL_OK) { return TCL_ERROR; } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /*ARGSUSED*/ static int CurselectionOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (viewPtr->flags & TV_SELECT_SORTED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(viewPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewEntry *entryPtr; Tcl_Obj *objPtr; entryPtr = Blt_Chain_GetValue(link); objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { TreeViewEntry *entryPtr; for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK)) { if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { Tcl_Obj *objPtr; objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BindOp -- * * .t bind tagOrId sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData object; TreeViewEntry *entryPtr; const char *string; long inode; /* * Entries are selected by id only. All other strings are interpreted as * a binding tag. */ string = Tcl_GetString(objv[2]); if ((isdigit(UCHAR(string[0]))) && (Tcl_GetLongFromObj(viewPtr->interp, objv[2], &inode) == TCL_OK)) { Blt_TreeNode node; node = Blt_Tree_GetNode(viewPtr->tree, inode); object = Blt_TreeView_NodeToEntry(viewPtr, node); } else if (GetEntryFromSpecialId(viewPtr, string, &entryPtr) == TCL_OK) { if (entryPtr != NULL) { return TCL_OK; /* Special id doesn't currently exist. */ } object = entryPtr; } else { /* Assume that this is a binding tag. */ object = Blt_TreeView_EntryTag(viewPtr, string); } return Blt_ConfigureBindingsFromObj(interp, viewPtr->bindTable, object, objc - 3, objv + 3); } /*ARGSUSED*/ static int EditOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; char *string; int isRoot, isTest; int x, y; isRoot = isTest = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } string = Tcl_GetString(objv[2]); if (strcmp("-test", string) == 0) { isTest = TRUE; objv++, objc--; } if (objc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(viewPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } entryPtr = Blt_TreeView_NearestEntry(viewPtr, x, y, FALSE); if (entryPtr != NULL) { Blt_ChainLink link; int worldX; worldX = WORLDX(viewPtr, x); for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *columnPtr; columnPtr = Blt_Chain_GetValue(link); if (columnPtr->flags & COLUMN_READONLY) { continue; /* Column isn't editable. */ } if ((worldX >= columnPtr->worldX) && (worldX < (columnPtr->worldX + columnPtr->width))) { TreeViewStyle *stylePtr; stylePtr = NULL; if (columnPtr != &viewPtr->treeColumn) { TreeViewValue *valuePtr; valuePtr = Blt_TreeView_FindValue(entryPtr, columnPtr); if (valuePtr == NULL) { continue; } stylePtr = valuePtr->stylePtr; } if (stylePtr == NULL) { stylePtr = columnPtr->stylePtr; } if ((columnPtr->flags & COLUMN_READONLY) || (stylePtr->classPtr->editProc == NULL)) { continue; } if (!isTest) { if ((*stylePtr->classPtr->editProc)(viewPtr, entryPtr, columnPtr, stylePtr) != TCL_OK) { return TCL_ERROR; } Blt_TreeView_EventuallyRedraw(viewPtr); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), TRUE); return TCL_OK; } } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), FALSE); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryActivateOp -- * * Selects the entry to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryActivateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *newPtr, *oldPtr; char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { newPtr = NULL; } else if (GetEntryFromObj(viewPtr, objv[3], &newPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->treeColumn.flags & COLUMN_HIDDEN) { return TCL_OK; } oldPtr = viewPtr->activePtr; viewPtr->activePtr = newPtr; if (!(viewPtr->flags & REDRAW_PENDING) && (newPtr != oldPtr)) { Drawable drawable; drawable = Tk_WindowId(viewPtr->tkwin); if (oldPtr != NULL) { Blt_TreeView_DrawLabel(viewPtr, oldPtr, drawable); } if (newPtr != NULL) { Blt_TreeView_DrawLabel(viewPtr, newPtr, drawable); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryCgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * EntryConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure the one of more entries in the * widget. * * .h entryconfigure node node node node option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for viewPtr; old resources get freed, if there were any. The * hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int EntryConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int nIds, configObjc; Tcl_Obj *const *configObjv; int i; TreeViewEntry *entryPtr; TreeViewTagIter iter; char *string; /* Figure out where the option value pairs begin */ objc -= 3, objv += 3; for (i = 0; i < objc; i++) { string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } } nIds = i; /* # of tags or ids specified */ configObjc = objc - i; /* # of options specified */ configObjv = objv + i; /* Start of options in objv */ bltTreeViewIconsOption.clientData = viewPtr; bltTreeViewUidOption.clientData = viewPtr; for (i = 0; i < nIds; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if (configObjc == 0) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, (Tcl_Obj *)NULL, 0); } else if (configObjc == 1) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, configObjv[0], 0); } if (Blt_TreeView_ConfigureEntry(viewPtr, entryPtr, configObjc, configObjv, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } } } viewPtr->flags |= (DIRTY | LAYOUT_PENDING | SCROLL_PENDING /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryIsOpenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryIsBeforeOp( TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *e1Ptr, *e2Ptr; int bool; if ((Blt_TreeView_GetEntry(viewPtr, objv[3], &e1Ptr) != TCL_OK) || (Blt_TreeView_GetEntry(viewPtr, objv[4], &e2Ptr) != TCL_OK)) { return TCL_ERROR; } bool = Blt_Tree_IsBefore(e1Ptr->node, e2Ptr->node); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryIsHiddenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryIsHiddenOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int bool; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } bool = (entryPtr->flags & ENTRY_HIDE); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryIsOpenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryIsOpenOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int bool; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } bool = ((entryPtr->flags & ENTRY_CLOSED) == 0); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryChildrenOp -- * * $treeview entry children $gid ?switches? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryChildrenOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *parentPtr; Tcl_Obj *listObjPtr; ChildrenSwitches switches; TreeViewEntry *entryPtr; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &parentPtr) != TCL_OK) { return TCL_ERROR; } switches.mask = 0; if (Blt_ParseSwitches(interp, childrenSwitches, objc - 4, objv + 4, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (entryPtr = Blt_TreeView_FirstChild(parentPtr, switches.mask); entryPtr != NULL; entryPtr = Blt_TreeView_NextSibling(entryPtr, switches.mask)) { Tcl_Obj *objPtr; objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryDeleteOp -- * * .tv entry degree $entry * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryDegreeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *parentPtr, *entryPtr; long count; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &parentPtr) != TCL_OK) { return TCL_ERROR; } count = 0; for (entryPtr = Blt_TreeView_FirstChild(parentPtr, ENTRY_HIDE); entryPtr != NULL; entryPtr = Blt_TreeView_NextSibling(entryPtr, ENTRY_HIDE)) { count++; } Tcl_SetLongObj(Tcl_GetObjResult(interp), count); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryDeleteOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryDeleteOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; if (Blt_TreeView_GetEntry(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 5) { long entryPos; Blt_TreeNode node; /* * Delete a single child node from a hierarchy specified by its * numeric position. */ if (Blt_GetPositionFromObj(interp, objv[3], &entryPos) != TCL_OK) { return TCL_ERROR; } if (entryPos >= (long)Blt_Tree_NodeDegree(entryPtr->node)) { return TCL_OK; /* Bad first index */ } if (entryPos == END) { node = Blt_Tree_LastChild(entryPtr->node); } else { node = GetNthNode(entryPtr->node, entryPos); } DeleteNode(viewPtr, node); } else { long firstPos, lastPos; Blt_TreeNode node, first, last, next; long nEntries; /* * Delete range of nodes in hierarchy specified by first/last * positions. */ if ((Blt_GetPositionFromObj(interp, objv[4], &firstPos) != TCL_OK) || (Blt_GetPositionFromObj(interp, objv[5], &lastPos) != TCL_OK)) { return TCL_ERROR; } nEntries = Blt_Tree_NodeDegree(entryPtr->node); if (nEntries == 0) { return TCL_OK; } if (firstPos == END) { firstPos = nEntries - 1; } if (firstPos >= nEntries) { Tcl_AppendResult(interp, "first position \"", Tcl_GetString(objv[4]), " is out of range", (char *)NULL); return TCL_ERROR; } if ((lastPos == END) || (lastPos >= nEntries)) { lastPos = nEntries - 1; } if (firstPos > lastPos) { Tcl_AppendResult(interp, "bad range: \"", Tcl_GetString(objv[4]), " > ", Tcl_GetString(objv[5]), "\"", (char *)NULL); return TCL_ERROR; } first = GetNthNode(entryPtr->node, firstPos); last = GetNthNode(entryPtr->node, lastPos); for (node = first; node != NULL; node = next) { next = Blt_Tree_NextSibling(node); DeleteNode(viewPtr, node); if (node == last) { break; } } } viewPtr->flags |= (LAYOUT_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntrySizeOp -- * * Counts the number of entries at this node. * * Results: * A standard TCL result. If an error occurred TCL_ERROR is returned and * interp->result will contain an error message. Otherwise, TCL_OK is * returned and interp->result contains the number of entries. * *--------------------------------------------------------------------------- */ static int EntrySizeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int length, recurse; long sum; char *string; recurse = FALSE; string = Tcl_GetStringFromObj(objv[3], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } if (objc == 3) { Tcl_AppendResult(interp, "missing node argument: should be \"", Tcl_GetString(objv[0]), " entry open node\"", (char *)NULL); return TCL_ERROR; } if (Blt_TreeView_GetEntry(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (recurse) { sum = Blt_Tree_Size(entryPtr->node); } else { sum = Blt_Tree_NodeDegree(entryPtr->node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), sum); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryOp -- * * This procedure handles entry operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec entryOps[] = { {"activate", 1, EntryActivateOp, 4, 4, "tagOrId",}, /*bbox*/ /*bind*/ {"cget", 2, EntryCgetOp, 5, 5, "tagOrId option",}, {"children", 2, EntryChildrenOp, 4, 0, "tagOrId ?switches?",}, /*close*/ {"configure", 2, EntryConfigureOp, 4, 0, "tagOrId ?tagOrId...? ?option value?...",}, {"degree", 3, EntryDegreeOp, 4, 4, "tagOrId",}, {"delete", 3, EntryDeleteOp, 5, 6, "tagOrId firstPos ?lastPos?",}, /*focus*/ /*hide*/ {"highlight", 1, EntryActivateOp, 4, 4, "tagOrId",}, /*index*/ {"isbefore", 3, EntryIsBeforeOp, 5, 5, "tagOrId tagOrId",}, {"ishidden", 3, EntryIsHiddenOp, 4, 4, "tagOrId",}, {"isopen", 3, EntryIsOpenOp, 4, 4, "tagOrId",}, /*move*/ /*nearest*/ /*open*/ /*see*/ /*show*/ {"size", 1, EntrySizeOp, 4, 5, "?-recurse? tagOrId",}, /*toggle*/ }; static int nEntryOps = sizeof(entryOps) / sizeof(Blt_OpSpec); static int EntryOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TvCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nEntryOps, entryOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int ExactCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return (strcmp(name, pattern) == 0); } /*ARGSUSED*/ static int GlobCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return Tcl_StringMatch(name, pattern); } static int RegexpCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return Tcl_RegExpMatch(interp, name, pattern); } /* *--------------------------------------------------------------------------- * * FindOp -- * * Find one or more nodes based upon the pattern provided. * * Results: * A standard TCL result. The interpreter result will contain a list of * the node serial identifiers. * *--------------------------------------------------------------------------- */ static int FindOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *firstPtr, *lastPtr; int nMatches, maxMatches; char c; int length; TreeViewCompareProc *compareProc; TreeViewIterProc *nextProc; int invertMatch; /* normal search mode (matching entries) */ char *namePattern, *fullPattern; char *execCmd; int i; int result; char *pattern, *option; Blt_List options; Blt_ListNode node; char *addTag, *withTag; TreeViewEntry *entryPtr; char *string; Tcl_Obj *listObjPtr, *objPtr; invertMatch = FALSE; maxMatches = 0; execCmd = namePattern = fullPattern = NULL; compareProc = ExactCompare; nextProc = Blt_TreeView_NextEntry; options = Blt_List_Create(BLT_ONE_WORD_KEYS); withTag = addTag = NULL; entryPtr = viewPtr->rootPtr; /* * Step 1: Process flags for find operation. */ for (i = 2; i < objc; i++) { string = Tcl_GetStringFromObj(objv[i], &length); if (string[0] != '-') { break; } option = string + 1; length--; c = option[0]; if ((c == 'e') && (length > 2) && (strncmp(option, "exact", length) == 0)) { compareProc = ExactCompare; } else if ((c == 'g') && (strncmp(option, "glob", length) == 0)) { compareProc = GlobCompare; } else if ((c == 'r') && (strncmp(option, "regexp", length) == 0)) { compareProc = RegexpCompare; } else if ((c == 'n') && (length > 1) && (strncmp(option, "nonmatching", length) == 0)) { invertMatch = TRUE; } else if ((c == 'n') && (length > 1) && (strncmp(option, "name", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; namePattern = Tcl_GetString(objv[i]); } else if ((c == 'f') && (strncmp(option, "full", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; fullPattern = Tcl_GetString(objv[i]); } else if ((c == 'e') && (length > 2) && (strncmp(option, "exec", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; execCmd = Tcl_GetString(objv[i]); } else if ((c == 'a') && (length > 1) && (strncmp(option, "addtag", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; addTag = Tcl_GetString(objv[i]); } else if ((c == 't') && (length > 1) && (strncmp(option, "tag", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; withTag = Tcl_GetString(objv[i]); } else if ((c == 'c') && (strncmp(option, "count", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; if (Tcl_GetIntFromObj(interp, objv[i], &maxMatches) != TCL_OK) { return TCL_ERROR; } if (maxMatches < 0) { Tcl_AppendResult(interp, "bad match count \"", objv[i], "\": should be a positive number", (char *)NULL); Blt_List_Destroy(options); return TCL_ERROR; } } else if ((option[0] == '-') && (option[1] == '\0')) { break; } else { /* * Verify that the switch is actually an entry configuration * option. */ if (Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, objv[i], 0) != TCL_OK) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad find switch \"", string, "\"", (char *)NULL); Blt_List_Destroy(options); return TCL_ERROR; } if ((i + 1) == objc) { goto missingArg; } /* Save the option in the list of configuration options */ node = Blt_List_GetNode(options, (char *)objv[i]); if (node == NULL) { node = Blt_List_CreateNode(options, (char *)objv[i]); Blt_List_AppendNode(options, node); } i++; Blt_List_SetValue(node, Tcl_GetString(objv[i])); } } if ((objc - i) > 2) { Blt_List_Destroy(options); Tcl_AppendResult(interp, "too many args", (char *)NULL); return TCL_ERROR; } /* * Step 2: Find the range of the search. Check the order of two * nodes and arrange the search accordingly. * * Note: Be careful to treat "end" as the end of all nodes, instead * of the end of visible nodes. That way, we can search the * entire tree, even if the last folder is closed. */ firstPtr = viewPtr->rootPtr; /* Default to root node */ lastPtr = LastEntry(viewPtr, firstPtr, 0); if (i < objc) { string = Tcl_GetString(objv[i]); if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { firstPtr = LastEntry(viewPtr, viewPtr->rootPtr, 0); } else if (Blt_TreeView_GetEntry(viewPtr, objv[i], &firstPtr) != TCL_OK) { return TCL_ERROR; } i++; } if (i < objc) { string = Tcl_GetString(objv[i]); if ((string[0] == 'e') && (strcmp(string, "end") == 0)) { lastPtr = LastEntry(viewPtr, viewPtr->rootPtr, 0); } else if (Blt_TreeView_GetEntry(viewPtr, objv[i], &lastPtr) != TCL_OK) { return TCL_ERROR; } } if (Blt_Tree_IsBefore(lastPtr->node, firstPtr->node)) { nextProc = Blt_TreeView_PrevEntry; } nMatches = 0; /* * Step 3: Search through the tree and look for nodes that match the * current pattern specifications. Save the name of each of * the matching nodes. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (entryPtr = firstPtr; entryPtr != NULL; entryPtr = (*nextProc) (entryPtr, 0)) { if (namePattern != NULL) { result = (*compareProc)(interp, Blt_Tree_NodeLabel(entryPtr->node), namePattern); if (result == invertMatch) { goto nextEntry; /* Failed to match */ } } if (fullPattern != NULL) { Tcl_DString fullName; Blt_TreeView_GetFullName(viewPtr, entryPtr, FALSE, &fullName); result = (*compareProc) (interp, Tcl_DStringValue(&fullName), fullPattern); Tcl_DStringFree(&fullName); if (result == invertMatch) { goto nextEntry; /* Failed to match */ } } if (withTag != NULL) { result = Blt_Tree_HasTag(viewPtr->tree, entryPtr->node, withTag); if (result == invertMatch) { goto nextEntry; /* Failed to match */ } } for (node = Blt_List_FirstNode(options); node != NULL; node = Blt_List_NextNode(node)) { objPtr = (Tcl_Obj *)Blt_List_GetKey(node); Tcl_ResetResult(interp); Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, objPtr, 0); pattern = Blt_List_GetValue(node); objPtr = Tcl_GetObjResult(interp); result = (*compareProc) (interp, Tcl_GetString(objPtr), pattern); if (result == invertMatch) { goto nextEntry; /* Failed to match */ } } /* * Someone may actually delete the current node in the "exec" * callback. Preserve the entry. */ Tcl_Preserve(entryPtr); if (execCmd != NULL) { Tcl_DString cmdString; Blt_TreeView_PercentSubst(viewPtr, entryPtr, execCmd, &cmdString); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&cmdString)); Tcl_DStringFree(&cmdString); if (result != TCL_OK) { Tcl_Release(entryPtr); goto error; } } /* A NULL node reference in an entry indicates that the entry * was deleted, but its memory not released yet. */ if (entryPtr->node != NULL) { /* Finally, save the matching node name. */ objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (addTag != NULL) { if (AddTag(viewPtr, entryPtr->node, addTag) != TCL_OK) { goto error; } } } Tcl_Release(entryPtr); nMatches++; if ((nMatches == maxMatches) && (maxMatches > 0)) { break; } nextEntry: if (entryPtr == lastPtr) { break; } } Tcl_ResetResult(interp); Blt_List_Destroy(options); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; missingArg: Tcl_AppendResult(interp, "missing argument for find option \"", objv[i], "\"", (char *)NULL); error: Blt_List_Destroy(options); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Converts one or more node identifiers to its path component. The path * may be either the single entry name or the full path of the entry. * * Results: * A standard TCL result. The interpreter result will contain a list of * the convert names. * *--------------------------------------------------------------------------- */ static int GetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewTagIter iter; TreeViewEntry *entryPtr; int useFullName; int i; Tcl_DString d1, d2; int count; useFullName = FALSE; if (objc > 2) { char *string; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-full") == 0)) { useFullName = TRUE; objv++, objc--; } } Tcl_DStringInit(&d1); /* Result. */ Tcl_DStringInit(&d2); /* Last element. */ count = 0; for (i = 2; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { Tcl_DStringSetLength(&d2, 0); count++; if (entryPtr->node != NULL) { if (useFullName) { Blt_TreeView_GetFullName(viewPtr, entryPtr, FALSE, &d2); } else { Tcl_DStringAppend(&d2,Blt_Tree_NodeLabel(entryPtr->node),-1); } Tcl_DStringAppendElement(&d1, Tcl_DStringValue(&d2)); } } } /* This handles the single element list problem. */ if (count == 1) { Tcl_DStringResult(interp, &d2); Tcl_DStringFree(&d1); } else { Tcl_DStringResult(interp, &d1); Tcl_DStringFree(&d2); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SearchAndApplyToTree -- * * Searches through the current tree and applies a procedure to matching * nodes. The search specification is taken from the following * command-line arguments: * * ?-exact? ?-glob? ?-regexp? ?-nonmatching? * ?-data string? * ?-name string? * ?-full string? * ?--? * ?inode...? * * Results: * A standard TCL result. If the result is valid, and if the nonmatchPtr * is specified, it returns a boolean value indicating whether or not the * search was inverted. This is needed to fix things properly for the * "hide nonmatching" case. * *--------------------------------------------------------------------------- */ static int SearchAndApplyToTree(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, TreeViewApplyProc *proc, int *nonMatchPtr) { TreeViewCompareProc *compareProc; int invertMatch; /* Normal search mode (matching * entries) */ char *namePattern, *fullPattern; int i; int length; int result; char *option, *pattern; char c; Blt_List options; TreeViewEntry *entryPtr; Blt_ListNode node; char *string; char *withTag; Tcl_Obj *objPtr; TreeViewTagIter iter; options = Blt_List_Create(BLT_ONE_WORD_KEYS); invertMatch = FALSE; namePattern = fullPattern = NULL; compareProc = ExactCompare; withTag = NULL; entryPtr = viewPtr->rootPtr; for (i = 2; i < objc; i++) { string = Tcl_GetStringFromObj(objv[i], &length); if (string[0] != '-') { break; } option = string + 1; length--; c = option[0]; if ((c == 'e') && (strncmp(option, "exact", length) == 0)) { compareProc = ExactCompare; } else if ((c == 'g') && (strncmp(option, "glob", length) == 0)) { compareProc = GlobCompare; } else if ((c == 'r') && (strncmp(option, "regexp", length) == 0)) { compareProc = RegexpCompare; } else if ((c == 'n') && (length > 1) && (strncmp(option, "nonmatching", length) == 0)) { invertMatch = TRUE; } else if ((c == 'f') && (strncmp(option, "full", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; fullPattern = Tcl_GetString(objv[i]); } else if ((c == 'n') && (length > 1) && (strncmp(option, "name", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; namePattern = Tcl_GetString(objv[i]); } else if ((c == 't') && (length > 1) && (strncmp(option, "tag", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; withTag = Tcl_GetString(objv[i]); } else if ((option[0] == '-') && (option[1] == '\0')) { break; } else { /* * Verify that the switch is actually an entry configuration * option. */ if (Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, objv[i], 0) != TCL_OK) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad switch \"", string, "\": must be -exact, -glob, -regexp, -name, -full, or -nonmatching", (char *)NULL); return TCL_ERROR; } if ((i + 1) == objc) { goto missingArg; } /* Save the option in the list of configuration options */ node = Blt_List_GetNode(options, (char *)objv[i]); if (node == NULL) { node = Blt_List_CreateNode(options, (char *)objv[i]); Blt_List_AppendNode(options, node); } i++; Blt_List_SetValue(node, Tcl_GetString(objv[i])); } } if ((namePattern != NULL) || (fullPattern != NULL) || (Blt_List_GetLength(options) > 0)) { /* * Search through the tree and look for nodes that match the current * spec. Apply the input procedure to each of the matching nodes. */ for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, 0)) { if (namePattern != NULL) { result = (*compareProc) (interp, Blt_Tree_NodeLabel(entryPtr->node), namePattern); if (result == invertMatch) { continue; /* Failed to match */ } } if (fullPattern != NULL) { Tcl_DString dString; Blt_TreeView_GetFullName(viewPtr, entryPtr, FALSE, &dString); result = (*compareProc) (interp, Tcl_DStringValue(&dString), fullPattern); Tcl_DStringFree(&dString); if (result == invertMatch) { continue; /* Failed to match */ } } if (withTag != NULL) { result = Blt_Tree_HasTag(viewPtr->tree, entryPtr->node, withTag); if (result == invertMatch) { continue; /* Failed to match */ } } for (node = Blt_List_FirstNode(options); node != NULL; node = Blt_List_NextNode(node)) { objPtr = (Tcl_Obj *)Blt_List_GetKey(node); Tcl_ResetResult(interp); if (Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, bltTreeViewEntrySpecs, (char *)entryPtr, objPtr, 0) != TCL_OK) { return TCL_ERROR; /* This shouldn't happen. */ } pattern = Blt_List_GetValue(node); objPtr = Tcl_GetObjResult(interp); result = (*compareProc)(interp, Tcl_GetString(objPtr), pattern); if (result == invertMatch) { continue; /* Failed to match */ } } /* Finally, apply the procedure to the node */ (*proc) (viewPtr, entryPtr); } Tcl_ResetResult(interp); Blt_List_Destroy(options); } /* * Apply the procedure to nodes that have been specified individually. */ for ( /*empty*/ ; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if ((*proc) (viewPtr, entryPtr) != TCL_OK) { return TCL_ERROR; } } } if (nonMatchPtr != NULL) { *nonMatchPtr = invertMatch; /* return "inverted search" status */ } return TCL_OK; missingArg: Blt_List_Destroy(options); Tcl_AppendResult(interp, "missing pattern for search option \"", objv[i], "\"", (char *)NULL); return TCL_ERROR; } static int FixSelectionsApplyProc(TreeView *viewPtr, TreeViewEntry *entryPtr) { if (entryPtr->flags & ENTRY_HIDE) { Blt_TreeView_DeselectEntry(viewPtr, entryPtr); if ((viewPtr->focusPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->focusPtr->node))) { if (entryPtr != viewPtr->rootPtr) { entryPtr = Blt_TreeView_ParentEntry(entryPtr); viewPtr->focusPtr = (entryPtr == NULL) ? viewPtr->focusPtr : entryPtr; Blt_SetFocusItem(viewPtr->bindTable, viewPtr->focusPtr, ITEM_ENTRY); } } if ((viewPtr->selAnchorPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->selAnchorPtr->node))) { viewPtr->selMarkPtr = viewPtr->selAnchorPtr = NULL; } if ((viewPtr->activePtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->activePtr->node))) { viewPtr->activePtr = NULL; } Blt_TreeView_PruneSelection(viewPtr, entryPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * HideOp -- * * Hides one or more nodes. Nodes can be specified by their inode, or by * matching a name or data value pattern. By default, the patterns are * matched exactly. They can also be matched using glob-style and * regular expression rules. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int HideOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int status, nonmatching; status = SearchAndApplyToTree(viewPtr, interp, objc, objv, HideEntryApplyProc, &nonmatching); if (status != TCL_OK) { return TCL_ERROR; } /* * If this was an inverted search, scan back through the tree and make * sure that the parents for all visible nodes are also visible. After * all, if a node is supposed to be visible, its parent can't be hidden. */ if (nonmatching) { Blt_TreeView_Apply(viewPtr, viewPtr->rootPtr, MapAncestorsApplyProc, 0); } /* * Make sure that selections are cleared from any hidden nodes. This * wasn't done earlier--we had to delay it until we fixed the visibility * status for the parents. */ Blt_TreeView_Apply(viewPtr, viewPtr->rootPtr, FixSelectionsApplyProc, 0); /* Hiding an entry only effects the visible nodes. */ viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShowOp -- * * Mark one or more nodes to be exposed. Nodes can be specified by their * inode, or by matching a name or data value pattern. By default, the * patterns are matched exactly. They can also be matched using * glob-style and regular expression rules. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int ShowOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (SearchAndApplyToTree(viewPtr, interp, objc, objv, ShowEntryApplyProc, (int *)NULL) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Converts one of more words representing indices of the entries in the * treeview widget to their respective serial identifiers. * * Results: * A standard TCL result. Interp->result will contain the identifier of * each inode found. If an inode could not be found, then the serial * identifier will be the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; char *string; TreeViewEntry *fromPtr; int usePath; long inode; usePath = FALSE; fromPtr = NULL; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-path") == 0)) { usePath = TRUE; objv++, objc--; } if ((string[0] == '-') && (strcmp(string, "-at") == 0)) { if (Blt_TreeView_GetEntry(viewPtr, objv[3], &fromPtr) != TCL_OK) { return TCL_ERROR; } objv += 2, objc -= 2; } if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " index ?-at tagOrId? ?-path? tagOrId\"", (char *)NULL); return TCL_ERROR; } viewPtr->fromPtr = fromPtr; if (viewPtr->fromPtr == NULL) { viewPtr->fromPtr = viewPtr->focusPtr; } if (viewPtr->fromPtr == NULL) { viewPtr->fromPtr = viewPtr->rootPtr; } inode = -1; if (usePath) { if (fromPtr == NULL) { fromPtr = viewPtr->rootPtr; } string = Tcl_GetString(objv[2]); entryPtr = FindPath(viewPtr, fromPtr, string); if (entryPtr != NULL) { inode = Blt_Tree_NodeId(entryPtr->node); } } else { if ((GetEntryFromObj2(viewPtr, objv[2], &entryPtr) == TCL_OK) && (entryPtr != NULL)) { inode = Blt_Tree_NodeId(entryPtr->node); } } Tcl_SetLongObj(Tcl_GetObjResult(interp), inode); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Add new entries into a hierarchy. If no node is specified, new * entries will be added to the root of the hierarchy. * *--------------------------------------------------------------------------- */ static int InsertOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node, parent; Tcl_Obj *const *options; Tcl_Obj *listObjPtr; TreeViewEntry *rootPtr; const char **argv; const char **p; const char *path; char *string; int count; int n; long depth; long insertPos; rootPtr = viewPtr->rootPtr; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-at") == 0)) { if (objc > 2) { if (Blt_TreeView_GetEntry(viewPtr, objv[3], &rootPtr) != TCL_OK) { return TCL_ERROR; } objv += 2, objc -= 2; } else { Tcl_AppendResult(interp, "missing argument for \"-at\" flag", (char *)NULL); return TCL_ERROR; } } if (objc == 2) { Tcl_AppendResult(interp, "missing position argument", (char *)NULL); return TCL_ERROR; } if (Blt_GetPositionFromObj(interp, objv[2], &insertPos) != TCL_OK) { return TCL_ERROR; } node = NULL; objc -= 3, objv += 3; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); while (objc > 0) { path = Tcl_GetString(objv[0]); objv++, objc--; /* * Count the option-value pairs that follow. Count until we spot one * that looks like an entry name (i.e. doesn't start with a minus * "-"). */ for (count = 0; count < objc; count += 2) { string = Tcl_GetString(objv[count]); if (string[0] != '-') { break; } } if (count > objc) { count = objc; } options = objv; objc -= count, objv += count; if (viewPtr->trimLeft != NULL) { const char *s1, *s2; /* Trim off leading character string if one exists. */ for (s1 = path, s2 = viewPtr->trimLeft; *s2 != '\0'; s2++, s1++) { if (*s1 != *s2) { break; } } if (*s2 == '\0') { path = s1; } } /* Split the path and find the parent node of the path. */ argv = &path; depth = 1; if (viewPtr->pathSep != SEPARATOR_NONE) { if (SplitPath(viewPtr, path, &depth, &argv) != TCL_OK) { goto error; } if (depth == 0) { Blt_Free(argv); continue; /* Root already exists. */ } } parent = rootPtr->node; depth--; /* Verify each component in the path preceding the tail. */ for (n = 0, p = argv; n < depth; n++, p++) { node = Blt_Tree_FindChild(parent, *p); if (node == NULL) { if ((viewPtr->flags & TV_FILL_ANCESTORS) == 0) { Tcl_AppendResult(interp, "can't find path component \"", *p, "\" in \"", path, "\"", (char *)NULL); goto error; } node = Blt_Tree_CreateNode(viewPtr->tree, parent, *p, END); if (node == NULL) { goto error; } } parent = node; } node = NULL; if (((viewPtr->flags & TV_ALLOW_DUPLICATES) == 0) && (Blt_Tree_FindChild(parent, *p) != NULL)) { Tcl_AppendResult(interp, "entry \"", *p, "\" already exists in \"", path, "\"", (char *)NULL); goto error; } node = Blt_Tree_CreateNode(viewPtr->tree, parent, *p, insertPos); if (node == NULL) { goto error; } if (Blt_TreeView_CreateEntry(viewPtr, node, count, options, 0) != TCL_OK) { goto error; } if (argv != &path) { Blt_Free(argv); } Tcl_ListObjAppendElement(interp, listObjPtr, NodeToObj(node)); } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: if (argv != &path) { Blt_Free(argv); } Tcl_DecrRefCount(listObjPtr); if (node != NULL) { DeleteNode(viewPtr, node); } return TCL_ERROR; } #ifdef notdef /* *--------------------------------------------------------------------------- * * AddOp -- * * Add new entries into a hierarchy. If no node is specified, * new entries will be added to the root of the hierarchy. * *--------------------------------------------------------------------------- */ static Blt_SwitchParseProc StringToChild; #define INSERT_BEFORE (ClientData)0 #define INSERT_AFTER (ClientData)1 static Blt_SwitchCustom beforeSwitch = { ObjToChild, NULL, INSERT_BEFORE, }; static Blt_SwitchCustom afterSwitch = { ObjToChild, NULL, INSERT_AFTER, }; typedef struct { long insertPos; Blt_TreeNode parent; } InsertData; static Blt_SwitchSpec insertSwitches[] = { {BLT_SWITCH_CUSTOM, "-after", "position", Blt_Offset(InsertData, insertPos), 0, 0, &afterSwitch}, {BLT_SWITCH_LONG_NNEG, "-at", "position", Blt_Offset(InsertData, insertPos), 0}, {BLT_SWITCH_CUSTOM, "-before", "position", Blt_Offset(InsertData, insertPos), 0, 0, &beforeSwitch}, {BLT_SWITCH_END} }; static int AddOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode node, parent; Tcl_Obj *const *options; Tcl_Obj *listObjPtr; TreeViewEntry *rootPtr; const char **argv; const char **p; char *path; char *string; int count; int n; long depth; long insertPos; memset(&data, 0, sizeof(data)); data.maxDepth = -1; data.cmdPtr = cmdPtr; /* Process any leading switches */ i = Blt_ProcessObjSwitches(interp, addSwitches, objc - 2, objv + 2, (char *)&data, BLT_CONFIG_OBJV_PARTIAL); if (i < 0) { return TCL_ERROR; } i += 2; /* Should have at the starting node */ if (i >= objc) { Tcl_AppendResult(interp, "starting node argument is missing", (char *)NULL); return TCL_ERROR; } if (Blt_TreeView_GetEntry(viewPtr, objv[i], &rootPtr) != TCL_OK) { return TCL_ERROR; } objv += i, objc -= i; node = NULL; /* Process sections of path ?options? */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); while (objc > 0) { path = Tcl_GetString(objv[0]); objv++, objc--; /* * Count the option-value pairs that follow. Count until we spot one * that looks like an entry name (i.e. doesn't start with a minus * "-"). */ for (count = 0; count < objc; count += 2) { if (!Blt_ObjIsOption(bltTreeViewEntrySpecs, objv[count], 0)) { break; } } if (count > objc) { count = objc; } options = objv; objc -= count, objv += count; if (viewPtr->trimLeft != NULL) { char *s1, *s2; /* Trim off leading character string if one exists. */ for (s1 = path, s2 = viewPtr->trimLeft; *s2 != '\0'; s2++, s1++) { if (*s1 != *s2) { break; } } if (*s2 == '\0') { path = s1; } } /* Split the path and find the parent node of the path. */ argv = &path; depth = 1; if (viewPtr->pathSep != SEPARATOR_NONE) { if (SplitPath(viewPtr, path, &depth, &argv) != TCL_OK) { goto error; } if (depth == 0) { Blt_Free(argv); continue; /* Root already exists. */ } } parent = rootPtr->node; depth--; /* Verify each component in the path preceding the tail. */ for (n = 0, p = argv; n < depth; n++, p++) { node = Blt_Tree_FindChild(parent, *p); if (node == NULL) { if ((viewPtr->flags & TV_FILL_ANCESTORS) == 0) { Tcl_AppendResult(interp, "can't find path component \"", *p, "\" in \"", path, "\"", (char *)NULL); goto error; } node = Blt_Tree_CreateNode(viewPtr->tree, parent, *p, END); if (node == NULL) { goto error; } } parent = node; } node = NULL; if (((viewPtr->flags & TV_ALLOW_DUPLICATES) == 0) && (Blt_Tree_FindChild(parent, *p) != NULL)) { Tcl_AppendResult(interp, "entry \"", *p, "\" already exists in \"", path, "\"", (char *)NULL); goto error; } node = Blt_Tree_CreateNode(viewPtr->tree, parent, *p, insertPos); if (node == NULL) { goto error; } if (Blt_TreeView_CreateEntry(viewPtr, node, count, options, 0) != TCL_OK) { goto error; } if (argv != &path) { Blt_Free(argv); } Tcl_ListObjAppendElement(interp, listObjPtr, NodeToObj(node)); } viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: if (argv != &path) { Blt_Free(argv); } Tcl_DecrRefCount(listObjPtr); if (node != NULL) { DeleteNode(viewPtr, node); } return TCL_ERROR; } #endif /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes nodes from the hierarchy. Deletes one or more entries (except * root). In all cases, nodes are removed recursively. * * Note: There's no need to explicitly clean up Entry structures * or request a redraw of the widget. When a node is * deleted in the tree, all of the Tcl_Objs representing * the various data fields are also removed. The treeview * widget store the Entry structure in a data field. So it's * automatically cleaned up when FreeEntryInternalRep is * called. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewTagIter iter; TreeViewEntry *entryPtr; int i; for (i = 2; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if (entryPtr == viewPtr->rootPtr) { Blt_TreeNode next, node; /* * Don't delete the root node. We implicitly assume that * even an empty tree has at a root. Instead delete all the * children regardless if they're closed or hidden. */ for (node = Blt_Tree_FirstChild(entryPtr->node); node != NULL; node = next) { next = Blt_Tree_NextSibling(node); DeleteNode(viewPtr, node); } } else { DeleteNode(viewPtr, entryPtr->node); } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * MoveOp -- * * Move an entry into a new location in the hierarchy. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MoveOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeNode parent; TreeViewEntry *srcPtr, *destPtr; char c; int action; char *string; TreeViewTagIter iter; #define MOVE_INTO (1<<0) #define MOVE_BEFORE (1<<1) #define MOVE_AFTER (1<<2) if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetString(objv[3]); c = string[0]; if ((c == 'i') && (strcmp(string, "into") == 0)) { action = MOVE_INTO; } else if ((c == 'b') && (strcmp(string, "before") == 0)) { action = MOVE_BEFORE; } else if ((c == 'a') && (strcmp(string, "after") == 0)) { action = MOVE_AFTER; } else { Tcl_AppendResult(interp, "bad position \"", string, "\": should be into, before, or after", (char *)NULL); return TCL_ERROR; } if (Blt_TreeView_GetEntry(viewPtr, objv[4], &destPtr) != TCL_OK) { return TCL_ERROR; } for (srcPtr = Blt_TreeView_FirstTaggedEntry(&iter); srcPtr != NULL; srcPtr = Blt_TreeView_NextTaggedEntry(&iter)) { /* Verify they aren't ancestors. */ if (Blt_Tree_IsAncestor(srcPtr->node, destPtr->node)) { Tcl_DString dString; const char *path; path = Blt_TreeView_GetFullName(viewPtr, srcPtr, 1, &dString); Tcl_AppendResult(interp, "can't move node: \"", path, "\" is an ancestor of \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); Tcl_DStringFree(&dString); return TCL_ERROR; } parent = Blt_Tree_ParentNode(destPtr->node); if (parent == NULL) { action = MOVE_INTO; } switch (action) { case MOVE_INTO: Blt_Tree_MoveNode(viewPtr->tree, srcPtr->node, destPtr->node, (Blt_TreeNode)NULL); break; case MOVE_BEFORE: Blt_Tree_MoveNode(viewPtr->tree, srcPtr->node, parent, destPtr->node); break; case MOVE_AFTER: Blt_Tree_MoveNode(viewPtr->tree, srcPtr->node, parent, Blt_Tree_NextSibling(destPtr->node)); break; } } viewPtr->flags |= (LAYOUT_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /*ARGSUSED*/ static int NearestOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewButton *buttonPtr = &viewPtr->button; int x, y; /* Screen coordinates of the test point. */ TreeViewEntry *entryPtr; int isRoot; char *string; isRoot = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (viewPtr->nVisible == 0) { return TCL_OK; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(viewPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } entryPtr = Blt_TreeView_NearestEntry(viewPtr, x, y, TRUE); if (entryPtr == NULL) { return TCL_OK; } x = WORLDX(viewPtr, x); y = WORLDY(viewPtr, y); if (objc > 4) { const char *where; int labelX, labelY, depth; TreeViewIcon icon; where = ""; if (entryPtr->flags & ENTRY_HAS_BUTTON) { int buttonX, buttonY; buttonX = entryPtr->worldX + entryPtr->buttonX; buttonY = entryPtr->worldY + entryPtr->buttonY; if ((x >= buttonX) && (x < (buttonX + buttonPtr->width)) && (y >= buttonY) && (y < (buttonY + buttonPtr->height))) { where = "button"; goto done; } } depth = DEPTH(viewPtr, entryPtr->node); icon = Blt_TreeView_GetEntryIcon(viewPtr, entryPtr); if (icon != NULL) { int iconWidth, iconHeight, entryHeight; int iconX, iconY; entryHeight = MAX(entryPtr->iconHeight, viewPtr->button.height); iconHeight = TreeView_IconHeight(icon); iconWidth = TreeView_IconWidth(icon); iconX = entryPtr->worldX + ICONWIDTH(depth); iconY = entryPtr->worldY; if (viewPtr->flatView) { iconX += (ICONWIDTH(0) - iconWidth) / 2; } else { iconX += (ICONWIDTH(depth + 1) - iconWidth) / 2; } iconY += (entryHeight - iconHeight) / 2; if ((x >= iconX) && (x <= (iconX + iconWidth)) && (y >= iconY) && (y < (iconY + iconHeight))) { where = "icon"; goto done; } } labelX = entryPtr->worldX + ICONWIDTH(depth); labelY = entryPtr->worldY; if (!viewPtr->flatView) { labelX += ICONWIDTH(depth + 1) + 4; } if ((x >= labelX) && (x < (labelX + entryPtr->labelWidth)) && (y >= labelY) && (y < (labelY + entryPtr->labelHeight))) { where = "label"; } done: if (Tcl_SetVar(interp, Tcl_GetString(objv[4]), where, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } Tcl_SetObjResult(interp, NodeToObj(entryPtr->node)); return TCL_OK; } /*ARGSUSED*/ static int OpenOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; TreeViewTagIter iter; int recurse, result; int i; recurse = FALSE; if (objc > 2) { int length; char *string; string = Tcl_GetStringFromObj(objv[2], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } } for (i = 2; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if (recurse) { result = Blt_TreeView_Apply(viewPtr, entryPtr, Blt_TreeView_OpenEntry, 0); } else { result = Blt_TreeView_OpenEntry(viewPtr, entryPtr); } if (result != TCL_OK) { return TCL_ERROR; } /* Make sure ancestors of this node aren't hidden. */ MapAncestors(viewPtr, entryPtr); } } /*FIXME: This is only for flattened entries. */ viewPtr->flags |= (LAYOUT_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RangeOp -- * * Returns the node identifiers in a given range. * *--------------------------------------------------------------------------- */ static int RangeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr, *firstPtr, *lastPtr; unsigned int mask; int length; Tcl_Obj *listObjPtr, *objPtr; char *string; mask = 0; string = Tcl_GetStringFromObj(objv[2], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-open", length) == 0)) { objv++, objc--; mask |= ENTRY_CLOSED; } if (Blt_TreeView_GetEntry(viewPtr, objv[2], &firstPtr) != TCL_OK) { return TCL_ERROR; } if (objc > 3) { if (Blt_TreeView_GetEntry(viewPtr, objv[3], &lastPtr) != TCL_OK) { return TCL_ERROR; } } else { lastPtr = LastEntry(viewPtr, firstPtr, mask); } if (mask & ENTRY_CLOSED) { if (firstPtr->flags & ENTRY_HIDE) { Tcl_AppendResult(interp, "first node \"", Tcl_GetString(objv[2]), "\" is hidden.", (char *)NULL); return TCL_ERROR; } if (lastPtr->flags & ENTRY_HIDE) { Tcl_AppendResult(interp, "last node \"", Tcl_GetString(objv[3]), "\" is hidden.", (char *)NULL); return TCL_ERROR; } } /* * The relative order of the first/last markers determines the * direction. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (Blt_Tree_IsBefore(lastPtr->node, firstPtr->node)) { for (entryPtr = lastPtr; entryPtr != NULL; entryPtr = Blt_TreeView_PrevEntry(entryPtr, mask)) { objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (entryPtr == firstPtr) { break; } } } else { for (entryPtr = firstPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, mask)) { objPtr = NodeToObj(entryPtr->node); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (entryPtr == lastPtr) { break; } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; char c; int length; int oper; char *string; Tk_Window tkwin; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; tkwin = viewPtr->tkwin; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } if ((Blt_GetPixelsFromObj(interp, tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) || (Blt_GetPixelsFromObj(interp, tkwin, objv[4], PIXELS_ANY, &y) != TCL_OK)) { return TCL_ERROR; } if (oper == SCAN_MARK) { viewPtr->scanAnchorX = x; viewPtr->scanAnchorY = y; viewPtr->scanX = viewPtr->xOffset; viewPtr->scanY = viewPtr->yOffset; } else { int worldX, worldY; int dx, dy; dx = viewPtr->scanAnchorX - x; dy = viewPtr->scanAnchorY - y; worldX = viewPtr->scanX + (10 * dx); worldY = viewPtr->scanY + (10 * dy); if (worldX < 0) { worldX = 0; } else if (worldX >= viewPtr->worldWidth) { worldX = viewPtr->worldWidth - viewPtr->xScrollUnits; } if (worldY < 0) { worldY = 0; } else if (worldY >= viewPtr->worldHeight) { worldY = viewPtr->worldHeight - viewPtr->yScrollUnits; } viewPtr->xOffset = worldX; viewPtr->yOffset = worldY; viewPtr->flags |= SCROLL_PENDING; Blt_TreeView_EventuallyRedraw(viewPtr); } return TCL_OK; } /*ARGSUSED*/ static int SeeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int width, height; int x, y; Tk_Anchor anchor; int left, right, top, bottom; char *string; string = Tcl_GetString(objv[2]); anchor = TK_ANCHOR_W; /* Default anchor is West */ if ((string[0] == '-') && (strcmp(string, "-anchor") == 0)) { if (objc == 3) { Tcl_AppendResult(interp, "missing \"-anchor\" argument", (char *)NULL); return TCL_ERROR; } if (Tk_GetAnchorFromObj(interp, objv[3], &anchor) != TCL_OK) { return TCL_ERROR; } objc -= 2, objv += 2; } if (objc == 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", objv[0], "see ?-anchor anchor? tagOrId\"", (char *)NULL); return TCL_ERROR; } if (GetEntryFromObj(viewPtr, objv[2], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { return TCL_OK; } if (entryPtr->flags & ENTRY_HIDE) { MapAncestors(viewPtr, entryPtr); viewPtr->flags |= SCROLL_PENDING; /* * If the entry wasn't previously exposed, its world coordinates * aren't likely to be valid. So re-compute the layout before we try * to see the viewport to the entry's location. */ Blt_TreeView_ComputeLayout(viewPtr); } width = VPORTWIDTH(viewPtr); height = VPORTHEIGHT(viewPtr); /* * XVIEW: If the entry is left or right of the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ left = viewPtr->xOffset; right = viewPtr->xOffset + width; switch (anchor) { case TK_ANCHOR_W: case TK_ANCHOR_NW: case TK_ANCHOR_SW: x = 0; break; case TK_ANCHOR_E: case TK_ANCHOR_NE: case TK_ANCHOR_SE: x = entryPtr->worldX + entryPtr->width + ICONWIDTH(DEPTH(viewPtr, entryPtr->node)) - width; break; default: if (entryPtr->worldX < left) { x = entryPtr->worldX; } else if ((entryPtr->worldX + entryPtr->width) > right) { x = entryPtr->worldX + entryPtr->width - width; } else { x = viewPtr->xOffset; } break; } /* * YVIEW: If the entry is above or below the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ top = viewPtr->yOffset; bottom = viewPtr->yOffset + height; switch (anchor) { case TK_ANCHOR_N: y = viewPtr->yOffset; break; case TK_ANCHOR_NE: case TK_ANCHOR_NW: y = entryPtr->worldY - (height / 2); break; case TK_ANCHOR_S: case TK_ANCHOR_SE: case TK_ANCHOR_SW: y = entryPtr->worldY + entryPtr->height - height; break; default: if (entryPtr->worldY < top) { y = entryPtr->worldY; } else if ((entryPtr->worldY + entryPtr->height) > bottom) { y = entryPtr->worldY + entryPtr->height - height; } else { y = viewPtr->yOffset; } break; } if ((y != viewPtr->yOffset) || (x != viewPtr->xOffset)) { /* viewPtr->xOffset = x; */ viewPtr->yOffset = y; viewPtr->flags |= SCROLL_PENDING; } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } void Blt_TreeView_ClearSelection(TreeView *viewPtr) { Blt_DeleteHashTable(&viewPtr->selectTable); Blt_InitHashTable(&viewPtr->selectTable, BLT_ONE_WORD_KEYS); Blt_Chain_Reset(viewPtr->selected); Blt_TreeView_EventuallyRedraw(viewPtr); if (viewPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(viewPtr); } } /* *--------------------------------------------------------------------------- * * LostSelection -- * * This procedure is called back by Tk when the selection is grabbed * away. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *--------------------------------------------------------------------------- */ static void LostSelection(ClientData clientData) { TreeView *viewPtr = clientData; if ((viewPtr->flags & TV_SELECT_EXPORT) == 0) { return; } Blt_TreeView_ClearSelection(viewPtr); } /* *--------------------------------------------------------------------------- * * SelectRange -- * * Sets the selection flag for a range of nodes. The range is * determined by two pointers which designate the first/last * nodes of the range. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int SelectRange(TreeView *viewPtr, TreeViewEntry *fromPtr, TreeViewEntry *toPtr) { if (viewPtr->flatView) { int i; if (fromPtr->flatIndex > toPtr->flatIndex) { for (i = fromPtr->flatIndex; i >= toPtr->flatIndex; i--) { SelectEntryApplyProc(viewPtr, viewPtr->flatArr[i]); } } else { for (i = fromPtr->flatIndex; i <= toPtr->flatIndex; i++) { SelectEntryApplyProc(viewPtr, viewPtr->flatArr[i]); } } } else { TreeViewEntry *entryPtr, *nextPtr; TreeViewIterProc *proc; /* From the range determine the direction to select entries. */ proc = (Blt_Tree_IsBefore(toPtr->node, fromPtr->node)) ? Blt_TreeView_PrevEntry : Blt_TreeView_NextEntry; for (entryPtr = fromPtr; entryPtr != NULL; entryPtr = nextPtr) { nextPtr = (*proc)(entryPtr, ENTRY_MASK); SelectEntryApplyProc(viewPtr, entryPtr); if (entryPtr == toPtr) { break; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionAnchorOp -- * * Sets the selection anchor to the element given by a index. The * selection anchor is the end of the selection that is fixed while * dragging out a selection with the mouse. The index "anchor" may be * used to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionAnchorOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; if (GetEntryFromObj(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } /* Set both the anchor and the mark. Indicates that a single entry * is selected. */ viewPtr->selAnchorPtr = entryPtr; viewPtr->selMarkPtr = NULL; if (entryPtr != NULL) { Tcl_SetObjResult(interp, NodeToObj(entryPtr->node)); } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionClearallOp * * Clears the entire selection. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionClearallOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_TreeView_ClearSelection(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionIncludesOp * * Returns 1 if the element indicated by index is currently * selected, 0 if it isn't. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionIncludesOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int bool; if (GetEntryFromObj(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } bool = FALSE; if (entryPtr == NULL) { bool = Blt_TreeView_EntryIsSelected(viewPtr, entryPtr); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionMarkOp -- * * Sets the selection mark to the element given by a index. The * selection anchor is the end of the selection that is movable while * dragging out a selection with the mouse. The index "mark" may be used * to refer to the anchor element. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionMarkOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; if (GetEntryFromObj(viewPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->selAnchorPtr == NULL) { Tcl_AppendResult(interp, "selection anchor must be set first", (char *)NULL); return TCL_ERROR; } if (viewPtr->selMarkPtr != entryPtr) { Blt_ChainLink link, next; /* Deselect entry from the list all the way back to the anchor. */ for (link = Blt_Chain_LastLink(viewPtr->selected); link != NULL; link = next) { TreeViewEntry *selectPtr; next = Blt_Chain_PrevLink(link); selectPtr = Blt_Chain_GetValue(link); if (selectPtr == viewPtr->selAnchorPtr) { break; } Blt_TreeView_DeselectEntry(viewPtr, selectPtr); } viewPtr->flags &= ~TV_SELECT_MASK; viewPtr->flags |= TV_SELECT_SET; SelectRange(viewPtr, viewPtr->selAnchorPtr, entryPtr); Tcl_SetObjResult(interp, NodeToObj(entryPtr->node)); viewPtr->selMarkPtr = entryPtr; Blt_TreeView_EventuallyRedraw(viewPtr); if (viewPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(viewPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionPresentOp * * Returns 1 if there is a selection and 0 if it isn't. * * Results: * A standard TCL result. interp->result will contain a boolean string * indicating if there is a selection. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionPresentOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int bool; bool = (Blt_Chain_GetLength(viewPtr->selected) > 0); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionSetOp * * Selects, deselects, or toggles all of the elements in the range * between first and last, inclusive, without affecting the selection * state of elements outside that range. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectionSetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *string; viewPtr->flags &= ~TV_SELECT_MASK; if (viewPtr->flags & LAYOUT_PENDING) { /* * The layout is dirty. Recompute it now so that we can use * view.top and view.bottom for nodes. */ Blt_TreeView_ComputeLayout(viewPtr); } string = Tcl_GetString(objv[2]); switch (string[0]) { case 's': viewPtr->flags |= TV_SELECT_SET; break; case 'c': viewPtr->flags |= TV_SELECT_CLEAR; break; case 't': viewPtr->flags |= TV_SELECT_TOGGLE; break; } if (objc > 4) { TreeViewEntry *firstPtr, *lastPtr; if (GetEntryFromObj(viewPtr, objv[3], &firstPtr) != TCL_OK) { return TCL_ERROR; } if (firstPtr == NULL) { return TCL_OK; /* Didn't pick an entry. */ } if ((firstPtr->flags & ENTRY_HIDE) && (!(viewPtr->flags & TV_SELECT_CLEAR))) { if (objc > 4) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } else { return TCL_OK; } } lastPtr = firstPtr; if (objc > 4) { if (Blt_TreeView_GetEntry(viewPtr, objv[4], &lastPtr) != TCL_OK) { return TCL_ERROR; } if ((lastPtr->flags & ENTRY_HIDE) && (!(viewPtr->flags & TV_SELECT_CLEAR))) { Tcl_AppendResult(interp, "can't select hidden node \"", Tcl_GetString(objv[4]), "\"", (char *)NULL); return TCL_ERROR; } } if (firstPtr == lastPtr) { SelectEntryApplyProc(viewPtr, firstPtr); } else { SelectRange(viewPtr, firstPtr, lastPtr); } /* Set both the anchor and the mark. Indicates that a single entry is * selected. */ if (viewPtr->selAnchorPtr == NULL) { viewPtr->selAnchorPtr = firstPtr; } } else { TreeViewEntry *entryPtr; TreeViewTagIter iter; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if ((entryPtr->flags & ENTRY_HIDE) && ((viewPtr->flags & TV_SELECT_CLEAR) == 0)) { continue; } SelectEntryApplyProc(viewPtr, entryPtr); } /* Set both the anchor and the mark. Indicates that a single entry is * selected. */ if (viewPtr->selAnchorPtr == NULL) { viewPtr->selAnchorPtr = entryPtr; } } if (viewPtr->flags & TV_SELECT_EXPORT) { Tk_OwnSelection(viewPtr->tkwin, XA_PRIMARY, LostSelection, viewPtr); } Blt_TreeView_EventuallyRedraw(viewPtr); if (viewPtr->selectCmd != NULL) { EventuallyInvokeSelectCmd(viewPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectionOp -- * * This procedure handles the individual options for text selections. * The selected text is designated by start and end indices into the text * pool. The selected segment has both a anchored and unanchored ends. * * Results: * None. * * Side effects: * The selection changes. * *--------------------------------------------------------------------------- */ static Blt_OpSpec selectionOps[] = { {"anchor", 1, SelectionAnchorOp, 4, 4, "tagOrId",}, {"clear", 5, SelectionSetOp, 4, 5, "first ?last?",}, {"clearall", 6, SelectionClearallOp, 3, 3, "",}, {"includes", 1, SelectionIncludesOp, 4, 4, "tagOrId",}, {"mark", 1, SelectionMarkOp, 4, 4, "tagOrId",}, {"present", 1, SelectionPresentOp, 3, 3, "",}, {"set", 1, SelectionSetOp, 4, 5, "first ?last?",}, {"toggle", 1, SelectionSetOp, 4, 5, "first ?last?",}, }; static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); static int SelectionOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TvCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSelectionOps, selectionOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * TagForgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagForgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Blt_Tree_ForgetTag(viewPtr->tree, Tcl_GetString(objv[i])); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagNamesOp -- * *--------------------------------------------------------------------------- */ static int TagNamesOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr, *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); objPtr = Tcl_NewStringObj("all", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Blt_TreeTagEntry *tPtr; objPtr = Tcl_NewStringObj("root", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); for (hPtr = Blt_Tree_FirstTag(viewPtr->tree, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { tPtr = Blt_GetHashValue(hPtr); objPtr = Tcl_NewStringObj(tPtr->tagName, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { int i; for (i = 3; i < objc; i++) { Blt_List list; Blt_ListNode listNode; TreeViewEntry *entryPtr; if (Blt_TreeView_GetEntry(viewPtr, objv[i], &entryPtr) != TCL_OK) { return TCL_ERROR; } list = Blt_List_Create(BLT_ONE_WORD_KEYS); Blt_TreeView_GetTags(interp, viewPtr, entryPtr, list); for (listNode = Blt_List_FirstNode(list); listNode != NULL; listNode = Blt_List_NextNode(listNode)) { objPtr = Tcl_NewStringObj((char *)Blt_List_GetKey(listNode), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Blt_List_Destroy(list); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagNodesOp -- * *--------------------------------------------------------------------------- */ static int TagNodesOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable nodeTable; int i; Blt_InitHashTable(&nodeTable, BLT_ONE_WORD_KEYS); for (i = 3; i < objc; i++) { TreeViewTagIter iter; TreeViewEntry *entryPtr; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { int isNew; Blt_CreateHashEntry(&nodeTable, (char *)entryPtr->node, &isNew); } } { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&nodeTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_TreeNode node; Tcl_Obj *objPtr; node = (Blt_TreeNode)Blt_GetHashKey(&nodeTable, hPtr); objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(node)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_DeleteHashTable(&nodeTable); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagAddOp -- * *--------------------------------------------------------------------------- */ static int TagAddOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; int i; char *tagName; TreeViewTagIter iter; tagName = Tcl_GetString(objv[3]); viewPtr->fromPtr = NULL; if (strcmp(tagName, "root") == 0) { Tcl_AppendResult(interp, "can't add reserved tag \"", tagName, "\"", (char *)NULL); return TCL_ERROR; } if (isdigit(UCHAR(tagName[0]))) { long nodeId; if (Tcl_GetLongFromObj(NULL, objv[3], &nodeId) == TCL_OK) { Tcl_AppendResult(viewPtr->interp, "invalid tag \"", tagName, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } } if (tagName[0] == '@') { Tcl_AppendResult(viewPtr->interp, "invalid tag \"", tagName, "\": can't start with \"@\"", (char *)NULL); return TCL_ERROR; } if (GetEntryFromSpecialId(viewPtr, tagName, &entryPtr) == TCL_OK) { Tcl_AppendResult(interp, "invalid tag \"", tagName, "\": is a special id", (char *)NULL); return TCL_ERROR; } for (i = 4; i < objc; i++) { if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if (AddTag(viewPtr, entryPtr->node, tagName) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagDeleteOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagDeleteOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { char *tagName; Blt_HashTable *tablePtr; tagName = Tcl_GetString(objv[3]); tablePtr = Blt_Tree_TagHashTable(viewPtr->tree, tagName); if (tablePtr != NULL) { int i; for (i = 4; i < objc; i++) { TreeViewEntry *entryPtr; TreeViewTagIter iter; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[i], &iter)!= TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)entryPtr->node); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagOp -- * *--------------------------------------------------------------------------- */ static Blt_OpSpec tagOps[] = { {"add", 1, TagAddOp, 5, 0, "tag id...",}, {"delete", 2, TagDeleteOp, 5, 0, "tag id...",}, {"forget", 1, TagForgetOp, 4, 0, "tag...",}, {"names", 2, TagNamesOp, 3, 0, "?id...?",}, {"nodes", 2, TagNodesOp, 4, 0, "tag ?tag...?",}, }; static int nTagOps = sizeof(tagOps) / sizeof(Blt_OpSpec); static int TagOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TvCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTagOps, tagOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(viewPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int ToggleOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewEntry *entryPtr; TreeViewTagIter iter; int result; if (Blt_TreeView_FindTaggedEntries(viewPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = Blt_TreeView_FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = Blt_TreeView_NextTaggedEntry(&iter)) { if (entryPtr == NULL) { return TCL_OK; } if (entryPtr->flags & ENTRY_CLOSED) { result = Blt_TreeView_OpenEntry(viewPtr, entryPtr); } else { Blt_TreeView_PruneSelection(viewPtr, viewPtr->focusPtr); if ((viewPtr->focusPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->focusPtr->node))){ viewPtr->focusPtr = entryPtr; Blt_SetFocusItem(viewPtr->bindTable, entryPtr, ITEM_ENTRY); } if ((viewPtr->selAnchorPtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, viewPtr->selAnchorPtr->node))) { viewPtr->selAnchorPtr = NULL; } result = Blt_TreeView_CloseEntry(viewPtr, entryPtr); } } viewPtr->flags |= SCROLL_PENDING; Blt_TreeView_EventuallyRedraw(viewPtr); return result; } /* *--------------------------------------------------------------------------- * * UpdateOp -- * * .tv update false * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int UpdateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int state; if (objc == 3) { if (Tcl_GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) { return TCL_ERROR; } if (state) { viewPtr->flags &= ~DONT_UPDATE; viewPtr->flags |= LAYOUT_PENDING | DIRTY; Blt_TreeView_EventuallyRedraw(viewPtr); fprintf(stderr, "Turning on updates %d\n", viewPtr->flags & DONT_UPDATE); } else { viewPtr->flags |= DONT_UPDATE; fprintf(stderr, "Turning off updates %d\n", viewPtr->flags & DONT_UPDATE); } } else { state = (viewPtr->flags & DONT_UPDATE) ? FALSE : TRUE; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), state); return TCL_OK; } static int XViewOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width, worldWidth; width = VPORTWIDTH(viewPtr); worldWidth = viewPtr->worldWidth; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; /* * Note that we are bounding the fractions between 0.0 and 1.0 * to support the "canvas"-style of scrolling. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); fract = (double)viewPtr->xOffset / worldWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); fract = (double)(viewPtr->xOffset + width) / worldWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &viewPtr->xOffset, worldWidth, width, viewPtr->xScrollUnits, viewPtr->scrollMode) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= SCROLLX; Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } static int YViewOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int height, worldHeight; height = VPORTHEIGHT(viewPtr); worldHeight = viewPtr->worldHeight; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* Report first and last fractions */ fract = (double)viewPtr->yOffset / worldHeight; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); fract = (double)(viewPtr->yOffset + height) / worldHeight; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &viewPtr->yOffset, worldHeight, height, viewPtr->yScrollUnits, viewPtr->scrollMode) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= SCROLL_PENDING; Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_WidgetInstCmd -- * * This procedure is invoked to process commands on behalf of the * treeview widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec tvOps[] = { {"bbox", 2, BboxOp, 3, 0, "tagOrId...",}, {"bind", 2, BindOp, 3, 5, "tagName ?sequence command?",}, {"button", 2, ButtonOp, 2, 0, "args",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"close", 2, CloseOp, 2, 0, "?-recurse? tagOrId...",}, {"column", 3, Blt_TreeView_ColumnOp, 2, 0, "oper args",}, {"configure", 3, ConfigureOp, 2, 0, "?option value?...",}, {"curselection", 2, CurselectionOp, 2, 2, "",}, {"delete", 1, DeleteOp, 2, 0, "tagOrId ?tagOrId...?",}, {"edit", 2, EditOp, 4, 6, "?-root|-test? x y",}, {"entry", 2, EntryOp, 2, 0, "oper args",}, {"find", 2, FindOp, 2, 0, "?flags...? ?first last?",}, {"focus", 2, FocusOp, 3, 3, "tagOrId",}, {"get", 1, GetOp, 2, 0, "?-full? tagOrId ?tagOrId...?",}, {"hide", 1, HideOp, 2, 0, "?-exact? ?-glob? ?-regexp? ?-nonmatching? ?-name string? ?-full string? ?-data string? ?--? ?tagOrId...?",}, {"index", 3, IndexOp, 3, 6, "?-at tagOrId? ?-path? string",}, {"insert", 3, InsertOp, 3, 0, "?-at tagOrId? position label ?label...? ?option value?",}, {"move", 1, MoveOp, 5, 5, "tagOrId into|before|after tagOrId",}, {"nearest", 1, NearestOp, 4, 5, "x y ?varName?",}, {"open", 1, OpenOp, 2, 0, "?-recurse? tagOrId...",}, {"range", 1, RangeOp, 4, 5, "?-open? tagOrId tagOrId",}, {"scan", 2, ScanOp, 5, 5, "dragto|mark x y",}, {"see", 3, SeeOp, 3, 0, "?-anchor anchor? tagOrId",}, {"selection", 3, SelectionOp, 2, 0, "oper args",}, {"show", 2, ShowOp, 2, 0, "?-exact? ?-glob? ?-regexp? ?-nonmatching? ?-name string? ?-full string? ?-data string? ?--? ?tagOrId...?",}, {"sort", 2, Blt_TreeView_SortOp, 2, 0, "args",}, {"style", 2, Blt_TreeView_StyleOp, 2, 0, "args",}, {"tag", 2, TagOp, 2, 0, "oper args",}, {"toggle", 2, ToggleOp, 3, 3, "tagOrId",}, {"update", 1, UpdateOp, 2, 3, "?bool?",}, {"xview", 1, XViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yview", 1, YViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nTvOps = sizeof(tvOps) / sizeof(Blt_OpSpec); int Blt_TreeView_WidgetInstCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TvCmdProc *proc; TreeView *viewPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nTvOps, tvOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(viewPtr); result = (*proc) (viewPtr, interp, objc, objv); Tcl_Release(viewPtr); return result; } #endif /* NO_TREEVIEW */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltImage.h��������������������������������������������������������������������0000644�0001750�0001750�00000003375�11462120062�014732� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltImage.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_IMAGE_H #define _BLT_IMAGE_H #define ROTATE_0 0 #define ROTATE_90 1 #define ROTATE_180 2 #define ROTATE_270 3 BLT_EXTERN int Blt_IsPicture(Tk_Image tkImage); /* Routines that really should be in the Tk image C API. */ BLT_EXTERN int Blt_Image_IsDeleted(Tk_Image tkImage); BLT_EXTERN Tk_ImageMaster Blt_Image_GetMaster(Tk_Image tkImage); BLT_EXTERN Tk_ImageType *Blt_Image_GetType(Tk_Image tkImage); BLT_EXTERN ClientData Blt_Image_GetInstanceData(Tk_Image tkImage); BLT_EXTERN const char *Blt_Image_Name(Tk_Image tkImage); BLT_EXTERN const char *Blt_Image_NameOfType(Tk_Image tkImage); #endif /*_BLT_IMAGE_H*/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGraph.h��������������������������������������������������������������������0000644�0001750�0001750�00000057062�11462120062�014753� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGraph.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_GRAPH_H #define _BLT_GRAPH_H #include "bltInt.h" #include "bltHash.h" #include "bltBind.h" #include "bltChain.h" #include "bltPs.h" #include "bltBgStyle.h" typedef struct _Graph Graph; typedef struct _Element Element; typedef struct _Legend Legend; typedef enum { CID_NONE, CID_AXIS_X, CID_AXIS_Y, CID_ELEM_BAR, CID_ELEM_CONTOUR, CID_ELEM_LINE, CID_ELEM_STRIP, CID_MARKER_BITMAP, CID_MARKER_IMAGE, CID_MARKER_LINE, CID_MARKER_POLYGON, CID_MARKER_TEXT, CID_MARKER_WINDOW, CID_LEGEND_ENTRY, } ClassId; typedef struct { /* Generic fields common to all graph objects. */ ClassId classId; /* Class type of object. */ const char *name; /* Identifier to refer the object. */ const char *className; /* Class name of object. */ Graph *graphPtr; /* Graph containing of the object. */ const char **tags; /* Binding tags for the object. */ } GraphObj; #include "bltGrAxis.h" #include "bltGrLegd.h" #define MARKER_UNDER 1 /* Draw markers designated to lie underneath * elements, grids, legend, etc. */ #define MARKER_ABOVE 0 /* Draw markers designated to rest above * elements, grids, legend, etc. */ #define PADX 2 /* Padding between labels/titles */ #define PADY 2 /* Padding between labels */ #define MINIMUM_MARGIN 20 /* Minimum margin size */ #define BOUND(x, lo, hi) \ (((x) > (hi)) ? (hi) : ((x) < (lo)) ? (lo) : (x)) /* *--------------------------------------------------------------------------- * * Graph component structure definitions * *--------------------------------------------------------------------------- */ #define PointInGraph(g,x,y) \ (((x) <= (g)->right) && ((x) >= (g)->left) && \ ((y) <= (g)->bottom) && ((y) >= (g)->top)) /* * Mask values used to selectively enable GRAPH or BARCHART entries in the * various configuration specs. */ #define GRAPH (BLT_CONFIG_USER_BIT << 1) #define STRIPCHART (BLT_CONFIG_USER_BIT << 2) #define BARCHART (BLT_CONFIG_USER_BIT << 3) #define LINE_GRAPHS (GRAPH | STRIPCHART) #define ALL_GRAPHS (GRAPH | BARCHART | STRIPCHART) #define ACTIVE_PEN (BLT_CONFIG_USER_BIT << 16) #define NORMAL_PEN (BLT_CONFIG_USER_BIT << 17) #define ALL_PENS (NORMAL_PEN | ACTIVE_PEN) typedef struct { Segment2d *segments; int length; int *map; } GraphSegments; typedef struct { Point2d *points; int length; int *map; } GraphPoints; /* *--------------------------------------------------------------------------- * * BarGroup -- * * Represents a sets of bars with the same abscissa. This structure is * used to track the display of the bars in the group. * * Each unique abscissa has at least one group. Groups can be * defined by the bar element's -group option. Multiple groups are * needed when you are displaying/comparing similar sets of data (same * abscissas) but belong to a separate group. * *--------------------------------------------------------------------------- */ typedef struct { int nSegments; /* Number of occurrences of * x-coordinate */ Axis2d axes; /* The axes associated with this * group. (mapped to the x-value) */ float sum; /* Sum of the ordinates (y-coorinate) of * each duplicate abscissa. Used to * determine height of stacked bars. */ int count; /* Current number of bars seen. Used to * position of the next bar in the * group. */ float lastY; /* y-cooridinate position of the * last bar seen. */ size_t index; /* Order of group in set (an unique * abscissa may have more than one * group). */ } BarGroup; /* *--------------------------------------------------------------------------- * * BarSetKey -- * * Key for hash table of set of bars. The bar set is defined by * coordinates with the same abscissa (x-coordinate). * *--------------------------------------------------------------------------- */ typedef struct { float value; /* Duplicated abscissa */ Axis2d axes; /* Axis mapping of element */ } BarSetKey; /* * BarModes -- * * Bar elements are displayed according to their x-y coordinates. If two * bars have the same abscissa (x-coordinate), the bar segments will be * drawn according to one of the following modes: */ typedef enum BarModes { BARS_INFRONT, /* Each successive bar in a group is * drawn in front of the previous. */ BARS_STACKED, /* Each successive bar in a group is * drawn stacked on top of the previous * bar. */ BARS_ALIGNED, /* Each successive bar in a group is * drawn aligned side-by-side to the * previous from right-to-left. */ BARS_OVERLAP /* Like "aligned", each successive bar * in a group is drawn from * right-to-left. The bars will overlap * each other by ~50%. */ } BarMode; typedef struct _Pen Pen; typedef struct _Marker Marker; typedef Pen *(PenCreateProc)(void); typedef int (PenConfigureProc)(Graph *graphPtr, Pen *penPtr); typedef void (PenDestroyProc)(Graph *graphPtr, Pen *penPtr); struct _Pen { const char *name; /* Pen style identifier. If NULL pen * was statically allocated. */ ClassId classId; /* Type element using this pen. */ const char *typeId; /* String token identifying the type of * pen. */ unsigned int flags; /* Indicates if the pen element is * active or normal. */ int refCount; /* Reference count for elements using * this pen. */ Blt_HashEntry *hashPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications */ PenConfigureProc *configProc; PenDestroyProc *destroyProc; Graph *graphPtr; /* Graph that the pen is associated * with. */ }; /* *--------------------------------------------------------------------------- * * Crosshairs * * Contains the line segments positions and graphics context used to * simulate crosshairs (by XOR-ing) on the graph. * *--------------------------------------------------------------------------- */ typedef struct _Crosshairs Crosshairs; typedef struct { short int width, height; /* Dimensions of the margin */ short int axesOffset; short int axesTitleLength; /* Width of the widest title to be * shown. Multiple titles are displayed * in another margin. This is the * minimum space requirement. */ short int maxTickWidth; short int maxTickHeight; unsigned int nAxes; /* # of axes to be displayed */ Blt_Chain axes; /* Axes associated with this margin */ const char *varName; /* If non-NULL, name of variable to be * updated when the margin size * changes */ int reqSize; /* Requested size of margin */ int site; /* Indicates where margin is located: * left, right, top, or bottom. */ } Margin; #define MARGIN_NONE -1 #define MARGIN_BOTTOM 0 /* x */ #define MARGIN_LEFT 1 /* y */ #define MARGIN_TOP 2 /* x2 */ #define MARGIN_RIGHT 3 /* y2 */ #define rightMargin margins[MARGIN_RIGHT] #define leftMargin margins[MARGIN_LEFT] #define topMargin margins[MARGIN_TOP] #define bottomMargin margins[MARGIN_BOTTOM] /* *--------------------------------------------------------------------------- * * Graph -- * * Top level structure containing everything pertaining to the graph. * *--------------------------------------------------------------------------- */ struct _Graph { unsigned int flags; /* Flags; see below for definitions. */ Tcl_Interp *interp; /* Interpreter associated with graph */ Tk_Window tkwin; /* Window that embodies the graph. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up. */ Display *display; /* Display containing widget; used to * release resources after tkwin has * already gone away. */ Tcl_Command cmdToken; /* Token for graph's widget command. */ const char *data; /* This value isn't used in C code. * It may be used in TCL bindings to * associate extra data. */ Tk_Cursor cursor; int inset; /* Sum of focus highlight and 3-D * border. Indicates how far to * offset the graph from outside edge * of the window. */ int borderWidth; /* Width of the exterior border */ int relief; /* Relief of the exterior border. */ Blt_Background normalBg; /* 3-D border used to delineate the * plot surface and outer edge of * window. */ int highlightWidth; /* Width in pixels of highlight to * draw around widget when it has the * focus. <= 0 means don't draw a * highlight. */ XColor *highlightBgColor; /* Color for drawing traversal * highlight area when highlight is * off. */ XColor *highlightColor; /* Color for drawing traversal * highlight. */ const char *title; /* Graph title */ short int titleX, titleY; /* Position of title on graph. */ short int titleWidth, titleHeight; /* Dimensions of title. */ TextStyle titleTextStyle; /* Title attributes: font, color, * etc.*/ const char *takeFocus; /* Not used in C code, indicates if * widget should be included in focus * traversal. */ Axis *focusPtr; /* The axis that currently has focus. */ int reqWidth, reqHeight; /* Requested size of graph window */ int reqPlotWidth, reqPlotHeight; /* Requested size of plot area. Zero * means to adjust the dimension * according to the available space * left in the window. */ int width, height; /* Actual size (in pixels) of graph * window or PostScript page. */ Blt_HashTable penTable; /* Table of pens */ struct Component { Blt_HashTable table; /* Hash table of ids. */ Blt_Chain displayList; /* Display list. */ Blt_HashTable tagTable; /* Table of bind tags. */ } elements, markers, axes; Blt_HashTable dataTables; /* Hash table of datatable clients. */ ClassId classId; /* Default element type */ Blt_BindTable bindTable; int nextMarkerId; /* Tracks next marker identifier * available */ Blt_Chain axisChain[4]; /* Chain of axes for each of the * margins. They're separate from the * margin structures to make it easier * to invert the X-Y axes by simply * switching chain pointers. */ Margin margins[4]; PageSetup *pageSetup; /* Page layout options: see bltGrPS.c */ Legend *legend; /* Legend information: see * bltGrLegd.c */ Crosshairs *crosshairs; /* Crosshairs information: see * bltGrHairs.c */ int halo; /* Maximum distance allowed between * points when searching for a point */ int inverted; /* If non-zero, indicates the x and y * axis positions should be inverted. */ int stackAxes; /* If non-zero, indicates to stack * mulitple axes in a margin, rather * than layering them one on top of * another. */ GC drawGC; /* GC for drawing on the margins. This * includes the axis lines */ int plotBW; /* Width of interior 3-D border. */ int plotRelief; /* 3-d effect: TK_RELIEF_RAISED etc. */ Blt_Background plotBg; /* Color of plotting surface */ /* If non-zero, force plot to conform to aspect ratio W/H */ float aspect; short int left, right; /* Coordinates of plot bbox */ short int top, bottom; Blt_Pad xPad; /* Vertical padding for plotarea */ int vRange, vOffset; /* Vertical axis range and offset from * the left side of the graph * window. Used to transform coordinates * to vertical axes. */ Blt_Pad yPad; /* Horizontal padding for plotarea */ int hRange, hOffset; /* Horizontal axis range and offset from * the top of the graph window. Used to * transform horizontal axes */ float vScale, hScale; int doubleBuffer; /* If non-zero, draw the graph into a * pixmap first to reduce flashing. */ int backingStore; /* If non-zero, cache elements by * drawing them into a pixmap */ Pixmap cache; /* Pixmap used to cache elements * displayed. If *backingStore* is * non-zero, each element is drawn into * this pixmap before it is copied onto * the screen. The pixmap then acts as * a cache (only the pixmap is * redisplayed if the none of elements * have changed). This is done so that * markers can be redrawn quickly over * elements without redrawing each * element. */ short int cacheWidth, cacheHeight; /* Size of element backing store * pixmap. */ /* * barchart specific information */ float baseline; /* Baseline from bar chart. */ float barWidth; /* Default width of each bar in graph * units. The default width is 1.0 * units. */ BarMode mode; /* Mode describing how to display bars * with the same x-coordinates. Mode can * be "stacked", "aligned", "overlap", * or "infront" */ BarGroup *barGroups; /* Contains information about duplicate * x-values in bar elements (malloc-ed). * This information can also be accessed * by the group hash table */ int nBarGroups; /* # of entries in barGroups array. If * zero, indicates nothing special * needs to be * done for "stack" or * "align" modes */ Blt_HashTable setTable; /* Table managing sets of bars with * the same abscissas. The bars in a * set may be displayed is various * ways: aligned, overlap, infront, or * stacked. */ int maxBarSetSize; const char *dataCmd; /* New data callback? */ }; /* * Bit flags definitions: * * All kinds of state information kept here. All these things happen * when the window is available to draw into (DisplayGraph). Need the * window width and height before we can calculate graph layout (i.e. the * screen coordinates of the axes, elements, titles, etc). But we want to * do this only when we have to, not every time the graph is redrawn. * * Same goes for maintaining a pixmap to double buffer graph elements. * Need to mark when the pixmap needs to updated. * * * MAP_ITEM Indicates that the element/marker/axis * configuration has changed such that * its layout of the item (i.e. its * position in the graph window) needs * to be recalculated. * * MAP_ALL Indicates that the layout of the axes and * all elements and markers and the graph need * to be recalculated. Otherwise, the layout * of only those markers and elements that * have changed will be reset. * * GET_AXIS_GEOMETRY Indicates that the size of the axes needs * to be recalculated. * * RESET_AXES Flag to call to Blt_ResetAxes routine. * This routine recalculates the scale offset * (used for mapping coordinates) of each axis. * If an axis limit has changed, then it sets * flags to re-layout and redraw the entire * graph. This needs to happend before the axis * can compute transformations between graph and * screen coordinates. * * LAYOUT_NEEDED * * CACHE_DIRTY If set, redraw all elements into the pixmap * used for buffering elements. * * REDRAW_PENDING Non-zero means a DoWhenIdle handler has * already been queued to redraw this window. * * DRAW_LEGEND Non-zero means redraw the legend. If this is * the only DRAW_* flag, the legend display * routine is called instead of the graph * display routine. * * DRAW_MARGINS Indicates that the margins bordering * the plotting area need to be redrawn. * The possible reasons are: * * 1) an axis configuration changed * 2) an axis limit changed * 3) titles have changed * 4) window was resized. * * GRAPH_FOCUS */ #define HIDE (1<<0) /* 0x0001 */ #define DELETE_PENDING (1<<1) /* 0x0002 */ #define REDRAW_PENDING (1<<2) /* 0x0004 */ #define ACTIVE_PENDING (1<<3) /* 0x0008 */ #define MAP_ITEM (1<<4) /* 0x0010 */ #define DIRTY (1<<5) /* 0x0020 */ #define ACTIVE (1<<6) /* 0x0040 */ #define FOCUS (1<<7) /* 0x0080 */ #define MAP_ALL (1<<8) /* 0x0100 */ #define LAYOUT_NEEDED (1<<9) /* 0x0200 */ #define RESET_AXES (1<<10)/* 0x0400 */ #define GET_AXIS_GEOMETRY (1<<11)/* 0x0800 */ #define DRAW_LEGEND (1<<12)/* 0x1000 */ #define DRAW_MARGINS (1<<13)/* 0x2000 */ #define CACHE_DIRTY (1<<14)/* 0x4000 */ #define REQ_BACKING_STORE (1<<15)/* 0x8000 */ #define UNMAP_HIDDEN (1<<16) #define MAP_WORLD (MAP_ALL|RESET_AXES|GET_AXIS_GEOMETRY) #define REDRAW_WORLD (DRAW_LEGEND) #define RESET_WORLD (REDRAW_WORLD | MAP_WORLD) /* * ---------------------- Forward declarations ------------------------ */ BLT_EXTERN int Blt_CreatePageSetup(Graph *graphPtr); BLT_EXTERN int Blt_CreateCrosshairs(Graph *graphPtr); BLT_EXTERN double Blt_InvHMap(Axis *axisPtr, double x); BLT_EXTERN double Blt_InvVMap(Axis *axisPtr, double x); BLT_EXTERN double Blt_HMap(Axis *axisPtr, double x); BLT_EXTERN double Blt_VMap(Axis *axisPtr, double y); BLT_EXTERN Point2d Blt_InvMap2D(Graph *graphPtr, double x, double y, Axis2d *pairPtr); BLT_EXTERN Point2d Blt_Map2D(Graph *graphPtr, double x, double y, Axis2d *pairPtr); BLT_EXTERN Graph *Blt_GetGraphFromWindowData(Tk_Window tkwin); BLT_EXTERN void Blt_AdjustAxisPointers(Graph *graphPtr); BLT_EXTERN int Blt_PolyRectClip(Region2d *extsPtr, Point2d *inputPts, int nInputPts, Point2d *outputPts); BLT_EXTERN void Blt_ComputeBarStacks(Graph *graphPtr); BLT_EXTERN void Blt_ConfigureCrosshairs(Graph *graphPtr); BLT_EXTERN void Blt_ConfigureLegend(Graph *graphPtr); BLT_EXTERN void Blt_ConfigureElements(Graph *graphPtr); BLT_EXTERN void Blt_ConfigureAxes(Graph *graphPtr); BLT_EXTERN void Blt_ConfigureMarkers(Graph *graphPtr); BLT_EXTERN void Blt_ReconfigureGraph(Graph *graphPtr); BLT_EXTERN void Blt_DestroyAxes(Graph *graphPtr); BLT_EXTERN void Blt_DestroyCrosshairs(Graph *graphPtr); BLT_EXTERN void Blt_DestroyElements(Graph *graphPtr); BLT_EXTERN void Blt_DestroyMarkers(Graph *graphPtr); BLT_EXTERN void Blt_DestroyPageSetup(Graph *graphPtr); BLT_EXTERN void Blt_DrawAxes(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_DrawAxisLimits(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_DrawElements(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_DrawGraph(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_DrawMarkers(Graph *graphPtr, Drawable drawable, int under); BLT_EXTERN void Blt_Draw2DSegments(Display *display, Drawable drawable, GC gc, Segment2d *segments, int nSegments); BLT_EXTERN int Blt_GetCoordinate(Tcl_Interp *interp, const char *string, double *valuePtr); BLT_EXTERN void Blt_InitBarSetTable(Graph *graphPtr); BLT_EXTERN void Blt_LayoutGraph(Graph *graphPtr); BLT_EXTERN void Blt_EventuallyRedrawGraph(Graph *graphPtr); BLT_EXTERN void Blt_ResetAxes(Graph *graphPtr); BLT_EXTERN void Blt_ResetBarGroups(Graph *graphPtr); BLT_EXTERN void Blt_GraphExtents(Graph *graphPtr, Region2d *extsPtr); BLT_EXTERN void Blt_DisableCrosshairs(Graph *graphPtr); BLT_EXTERN void Blt_EnableCrosshairs(Graph *graphPtr); BLT_EXTERN void Blt_MapGraph(Graph *graphPtr); BLT_EXTERN void Blt_MapAxes(Graph *graphPtr); BLT_EXTERN void Blt_MapElements(Graph *graphPtr); BLT_EXTERN void Blt_MapMarkers(Graph *graphPtr); BLT_EXTERN void Blt_UpdateCrosshairs(Graph *graphPtr); BLT_EXTERN void Blt_DestroyPens(Graph *graphPtr); BLT_EXTERN int Blt_GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, Pen **penPtrPtr); BLT_EXTERN Pen *Blt_BarPen(const char *penName); BLT_EXTERN Pen *Blt_LinePen(const char *penName); BLT_EXTERN Pen *Blt_CreatePen(Graph *graphPtr, const char *penName, ClassId classId, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_InitLinePens(Graph *graphPtr); BLT_EXTERN int Blt_InitBarPens(Graph *graphPtr); BLT_EXTERN void Blt_FreePen(Pen *penPtr); BLT_EXTERN int Blt_VirtualAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_AxisOp(Tcl_Interp *interp, Graph *graphPtr, int margin, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_ElementOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId); BLT_EXTERN int Blt_CrosshairsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_MarkerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_PenOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_PointInPolygon(Point2d *samplePtr, Point2d *screenPts, int nScreenPts); BLT_EXTERN int Blt_RegionInPolygon(Region2d *extsPtr, Point2d *points, int nPoints, int enclosed); BLT_EXTERN int Blt_PointInSegments(Point2d *samplePtr, Segment2d *segments, int nSegments, double halo); BLT_EXTERN int Blt_PostScriptOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_GraphUpdateNeeded(Graph *graphPtr); BLT_EXTERN int Blt_DefaultAxes(Graph *graphPtr); BLT_EXTERN Axis *Blt_GetFirstAxis(Blt_Chain chain); BLT_EXTERN void Blt_UpdateAxisBackgrounds(Graph *graphPtr); BLT_EXTERN Marker *Blt_NearestMarker(Graph *graphPtr, int x, int y, int under); BLT_EXTERN Axis *Blt_NearestAxis(Graph *graphPtr, int x, int y); typedef ClientData (MakeTagProc)(Graph *graphPtr, const char *tagName); BLT_EXTERN MakeTagProc Blt_MakeElementTag; BLT_EXTERN MakeTagProc Blt_MakeMarkerTag; BLT_EXTERN MakeTagProc Blt_MakeAxisTag; BLT_EXTERN Blt_BindTagProc Blt_GraphTags; BLT_EXTERN Blt_BindTagProc Blt_AxisTags; BLT_EXTERN int Blt_GraphType(Graph *graphPtr); BLT_EXTERN void Blt_UpdateGraph(ClientData clientData); BLT_EXTERN void Blt_GraphSetObjectClass(GraphObj *graphObjPtr,ClassId classId); BLT_EXTERN void Blt_MarkersToPostScript(Graph *graphPtr, Blt_Ps ps, int under); BLT_EXTERN void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN void Blt_ActiveElementsToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN void Blt_LegendToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN void Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN void Blt_AxisLimitsToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN Element *Blt_LineElement(Graph *graphPtr, const char *name, ClassId classId); BLT_EXTERN Element *Blt_BarElement(Graph *graphPtr, const char *name, ClassId classId); BLT_EXTERN void Blt_DrawGrids(Graph *graphPtr, Drawable drawable); BLT_EXTERN void Blt_GridsToPostScript(Graph *graphPtr, Blt_Ps ps); BLT_EXTERN void Blt_InitBarSetTable(Graph *graphPtr); BLT_EXTERN void Blt_DestroyBarSets(Graph *graphPtr); /* ---------------------- Global declarations ------------------------ */ BLT_EXTERN const char *Blt_GraphClassName(ClassId classId); #endif /* _BLT_GRAPH_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/missing.h���������������������������������������������������������������������0000644�0001750�0001750�00000002350�11462120063�014650� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _MISSING_H #define _MISSING_H #include <winspool.h> #ifndef DeleteBitmap #define DeleteBitmap(hbm) DeleteObject((HGDIOBJ)(HBITMAP)(hbm)) #endif #ifndef DeleteBrush #define DeleteBrush(hbr) DeleteObject((HGDIOBJ)(HBRUSH)(hbr)) #endif #ifndef DeleteFont #define DeleteFont(hfont) DeleteObject((HGDIOBJ)(HFONT)(hfont)) #endif #ifndef DeletePalette #define DeletePalette(hpal) DeleteObject((HGDIOBJ)(HPALETTE)(hpal)) #endif #ifndef DeletePen #define DeletePen(hpen) DeleteObject((HGDIOBJ)(HPEN)(hpen)) #endif #ifndef SelectBitmap #define SelectBitmap(hdc, hbm) ((HBITMAP)SelectObject((hdc), (HGDIOBJ)(HBITMAP)(hbm))) #endif #ifndef SelectBrush #define SelectBrush(hdc, hbr) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbr))) #endif #ifndef SelectFont #define SelectFont(hdc, hfont) ((HFONT)SelectObject((hdc), (HGDIOBJ)(HFONT)(hfont))) #endif #ifndef SelectPen #define SelectPen(hdc, hpen) ((HPEN)SelectObject((hdc), (HGDIOBJ)(HPEN)(hpen))) #endif #ifndef GetNextWindow #define GetNextWindow(hWnd,wCmd) GetWindow((hWnd),(wCmd)) #endif #ifndef GetStockBrush #define GetStockBrush(i) ((HBRUSH)GetStockObject(i)) #endif #ifndef GetStockPen #define GetStockPen(i) ((HPEN)GetStockObject(i)) #endif #endif /* _MISSING_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPainterInt.h���������������������������������������������������������������0000644�0001750�0001750�00000011412�11462120062�015754� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixPainter.h -- * * This header contains the private definitions for a painter in * the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the * Tk library distrubution. The photo image type was designed and * implemented by Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #ifndef _BLT_UNIX_PAINTER_H #define _BLT_UNIX_PAINTER_H #ifdef notdef #define PAINTER_COLOR_WINDOW (1<<0) #define PAINTER_BW (1<<1) #define PAINTER_MAP_COLORS (1<<2) #endif /* * Painter -- * * This structure represents a painter used to display picture images. A * painter is specified by a combination of display, visual, colormap, depth, * and monitor gamma value. Painters contain information necessary to display * a picture. This includes both an RGB to pixel map, and a RGB to allocated * color map. * * Painters may be shared by more than one client and are reference counted. * When no clients are using the painter, it is freed. */ struct _Blt_Painter { Display *display; /* Display of painter. Used to free colors * allocated. */ Visual *visualPtr; /* Visual information for the class of windows * displaying the image. */ Colormap colormap; /* Colormap used. This may be the default * colormap, or an allocated private map. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value of monitor. */ unsigned int flags; /* Flags listed below. */ int refCount; /* # of clients using this painter. If zero, * # the painter is freed. */ Blt_HashEntry *hashPtr; /* Used to delete the painter entry from the * hash table of painters. */ int nColors; /* # of colors allocated. */ int nRed, nGreen, nBlue; /* # of intensities for each RGB component. */ unsigned long pixels[256]; /* Array of pixel values. Needed to deallocate * the color palette. Also contains the * mapping between linear pixel values (rBits, * gBits, bBits) and the actual pixel for * PsuedoColor, StaticColor, Greyscale, and * StaticGrey visuals. */ int nPixels; /* # of pixels allocated in above array. */ GC gc; /* GC used to draw the image. */ /* * The following arrays are used for DirectColor, PsuedoColor, * StaticColor, Greyscale, and StaticGrey visuals to convert RGB triplets * to a parts of a pixel index. */ unsigned int rBits[256], gBits[256], bBits[256]; /* * This following as used for TrueColor and DirectColor visuals only. * They are used to directly compute of pixel values from picture RGB * components. */ unsigned int rAdjust, gAdjust, bAdjust; unsigned int rShift, gShift, bShift; unsigned int rMask, gMask, bMask; unsigned char gammaTable[256]; /* Input gamma lookup table. Used to map * non-linear monitor values back to RGB * values. This is used whenever we take a * snapshot of the screen (e.g. alpha * blending). Computes the power mapping. D * = I^gamma. */ unsigned char igammaTable[256]; /* Output gamma lookup table. Used to map * RGB values to non-linear monitor * values. Computes the inverse power mapping. * I~ = D^1/gamma. */ int isMonochrome; /* Indicates if the display uses a single * color component (e.g. 4-bit grayscale). */ Blt_Pixel palette[256]; /* Maps the picture's 8-bit RGB values to the * RGB values of the colors actually * allocated. This is used for dithering the * picture. */ }; typedef struct _Blt_Painter Painter; #endif /* _BLT_UNIX_PAINTER_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixPainter.h��������������������������������������������������������������0000644�0001750�0001750�00000011412�11462120063�016146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixPainter.h -- * * This header contains the private definitions for a painter in * the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the * Tk library distrubution. The photo image type was designed and * implemented by Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #ifndef _BLT_UNIX_PAINTER_H #define _BLT_UNIX_PAINTER_H #ifdef notdef #define PAINTER_COLOR_WINDOW (1<<0) #define PAINTER_BW (1<<1) #define PAINTER_MAP_COLORS (1<<2) #endif /* * Painter -- * * This structure represents a painter used to display picture images. A * painter is specified by a combination of display, visual, colormap, depth, * and monitor gamma value. Painters contain information necessary to display * a picture. This includes both an RGB to pixel map, and a RGB to allocated * color map. * * Painters may be shared by more than one client and are reference counted. * When no clients are using the painter, it is freed. */ struct _Blt_Painter { Display *display; /* Display of painter. Used to free colors * allocated. */ Visual *visualPtr; /* Visual information for the class of windows * displaying the image. */ Colormap colormap; /* Colormap used. This may be the default * colormap, or an allocated private map. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value of monitor. */ unsigned int flags; /* Flags listed below. */ int refCount; /* # of clients using this painter. If zero, * # the painter is freed. */ Blt_HashEntry *hashPtr; /* Used to delete the painter entry from the * hash table of painters. */ int nColors; /* # of colors allocated. */ int nRed, nGreen, nBlue; /* # of intensities for each RGB component. */ unsigned long pixels[256]; /* Array of pixel values. Needed to deallocate * the color palette. Also contains the * mapping between linear pixel values (rBits, * gBits, bBits) and the actual pixel for * PsuedoColor, StaticColor, Greyscale, and * StaticGrey visuals. */ int nPixels; /* # of pixels allocated in above array. */ GC gc; /* GC used to draw the image. */ /* * The following arrays are used for DirectColor, PsuedoColor, * StaticColor, Greyscale, and StaticGrey visuals to convert RGB triplets * to a parts of a pixel index. */ unsigned int rBits[256], gBits[256], bBits[256]; /* * This following as used for TrueColor and DirectColor visuals only. * They are used to directly compute of pixel values from picture RGB * components. */ unsigned int rAdjust, gAdjust, bAdjust; unsigned int rShift, gShift, bShift; unsigned int rMask, gMask, bMask; unsigned char gammaTable[256]; /* Input gamma lookup table. Used to map * non-linear monitor values back to RGB * values. This is used whenever we take a * snapshot of the screen (e.g. alpha * blending). Computes the power mapping. D * = I^gamma. */ unsigned char igammaTable[256]; /* Output gamma lookup table. Used to map * RGB values to non-linear monitor * values. Computes the inverse power mapping. * I~ = D^1/gamma. */ int isMonochrome; /* Indicates if the display uses a single * color component (e.g. 4-bit grayscale). */ Blt_Pixel palette[256]; /* Maps the picture's 8-bit RGB values to the * RGB values of the colors actually * allocated. This is used for dithering the * picture. */ }; typedef struct _Blt_Painter Painter; #endif /* _BLT_UNIX_PAINTER_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkUnixFont.h������������������������������������������������������������������0000644�0001750�0001750�00000010636�11462120063�015316� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkUnixFont.h -- * * * The Font structure used internally by the Tk_3D* routines. * The following is a copy of it from tk3d.c. * * Contains copies of internal Tk structures. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _TK_UNIXFONT_H #define _TK_UNIXFONT_H /* * The following structure represents a font family. It is assumed that all * screen fonts constructed from the same "font family" share certain * properties; all screen fonts with the same "font family" point to a shared * instance of this structure. The most important shared property is the * character existence metrics, used to determine if a screen font can display * a given Unicode character. * * Under Unix, there are three attributes that uniquely identify a "font * family": the foundry, face name, and charset. */ #define FONTMAP_SHIFT 10 #define FONTMAP_PAGES (1 << (sizeof(Tcl_UniChar)*8 - FONTMAP_SHIFT)) #define FONTMAP_BITSPERPAGE (1 << FONTMAP_SHIFT) typedef struct _FontFamily { struct _FontFamily *nextPtr; /* Next in list of all known font families. */ int refCount; /* How many SubFonts are referring to this * FontFamily. When the refCount drops to * zero, this FontFamily may be freed. */ /* * Key. */ Tk_Uid foundry; /* Foundry key for this FontFamily. */ Tk_Uid faceName; /* Face name key for this FontFamily. */ Tcl_Encoding encoding; /* Encoding key for this FontFamily. */ /* * Derived properties. */ int isTwoByteFont; /* 1 if this is a double-byte font, 0 * otherwise. */ char *fontMap[FONTMAP_PAGES]; /* Two-level sparse table used to determine * quickly if the specified character exists. * As characters are encountered, more pages * in this table are dynamically alloced. The * contents of each page is a bitmask * consisting of FONTMAP_BITSPERPAGE bits, * representing whether this font can be used * to display the given character at the * corresponding bit position. The high bits * of the character are used to pick which * page of the table is used. */ } FontFamily; /* * The following structure encapsulates an individual screen font. A font * object is made up of however many SubFonts are necessary to display a * stream of multilingual characters. */ typedef struct _SubFont { char **fontMap; /* Pointer to font map from the FontFamily, * cached here to save a dereference. */ XFontStruct *fontStructPtr; /* The specific screen font that will be * used when displaying/measuring chars * belonging to the FontFamily. */ FontFamily *familyPtr; /* The FontFamily for this SubFont. */ } SubFont; /* * The following structure represents Unix's implementation of a font * object. */ #define SUBFONT_SPACE 3 #define BASE_CHARS 256 typedef struct _UnixFont { TkFont font; /* Stuff used by generic font package. Must * be first in structure. */ SubFont staticSubFonts[SUBFONT_SPACE]; /* Builtin space for a limited number of * SubFonts. */ int numSubFonts; /* Length of following array. */ SubFont *subFontArray; /* Array of SubFonts that have been loaded * in order to draw/measure all the characters * encountered by this font so far. All fonts * start off with one SubFont initialized by * AllocFont() from the original set of font * attributes. Usually points to * staticSubFonts, but may point to malloced * space if there are lots of SubFonts. */ SubFont controlSubFont; /* Font to use to display control-character * expansions. */ Display *display; /* Display that owns font. */ int pixelSize; /* Original pixel size used when font was * constructed. */ TkXLFDAttributes xa; /* Additional attributes that specify the * preferred foundry and encoding to use when * constructing additional SubFonts. */ int widths[BASE_CHARS]; /* Widths of first 256 chars in the base * font, for handling common case. */ int underlinePos; /* Offset from baseline to origin of * underline bar (used when drawing underlined * font) (pixels). */ int barHeight; /* Height of underline or overstrike bar * (used when drawing underlined or strikeout * font) (pixels). */ } UnixFont; #endif /* _TK_UNIXFONT_H */ ��������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltComboMenu.c����������������������������������������������������������������0000755�0001750�0001750�00000567253�11462120062�015604� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltComboMenu.c -- * * This module implements a combomenu widget for the BLT toolkit. * * Copyright 2006 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltBind.h" #include "bltImage.h" #include "bltPicture.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltHash.h" #include "bltBgStyle.h" #include "bltPainter.h" #include "bltSwitch.h" static const char emptyString[] = ""; #define MAXSCROLLBARTHICKNESS 100 #define REDRAW_PENDING (1<<0) #define LAYOUT_PENDING (1<<1) #define UPDATE_PENDING (1<<2) #define FOCUS (1<<3) #define SCROLLX (1<<4) #define SCROLLY (1<<5) #define SCROLL_PENDING (SCROLLX|SCROLLY) #define INSTALL_XSCROLLBAR (1<<8) #define INSTALL_YSCROLLBAR (1<<9) #define RESTRICT_MIN (1<<10) #define RESTRICT_MAX (1<<11) #define RESTRICT_NONE (0) #define VAR_FLAGS (TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS) #define PIXMAPX(cm, wx) ((wx) - (cm)->xOffset) #define PIXMAPY(cm, wy) ((wy) - (cm)->yOffset) #define SCREENX(cm, wx) ((wx) - (cm)->xOffset + (cm)->borderWidth) #define SCREENY(cm, wy) ((wy) - (cm)->yOffset + (cm)->borderWidth) #define WORLDX(cm, sx) ((sx) - (cm)->borderWidth + (cm)->xOffset) #define WORLDY(cm, sy) ((sy) - (cm)->borderWidth + (cm)->yOffset) #define VPORTWIDTH(cm) \ (Tk_Width((cm)->tkwin) - 2 * (cm)->borderWidth - (cm)->yScrollbarWidth) #define VPORTHEIGHT(cm) \ (Tk_Height((cm)->tkwin) - 2 * (cm)->borderWidth - (cm)->xScrollbarHeight) #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define CLAMP(x,min,max) ((((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x))) #define ITEM_IPAD 3 #define ITEM_XPAD 2 #define ITEM_YPAD 1 #define ITEM_SEP_HEIGHT 6 #define ITEM_L_IND_WIDTH 19 #define ITEM_L_IND_HEIGHT 19 #define ITEM_R_IND_WIDTH 13 #define ITEM_R_IND_HEIGHT 13 #define ITEM_MAP (1<<1) /* Item needs to be remapped */ #define ITEM_REDRAW (1<<2) /* Item needs to be redrawn. */ #define ITEM_SELECTED (1<<4) /* Radiobutton/checkbutton is * selected. */ /* Item state. */ #define ITEM_NORMAL (1<<5) /* Draw item normally. */ #define ITEM_DISABLED (1<<6) /* Item is disabled. */ #define ITEM_STATE_MASK ((ITEM_DISABLED)|(ITEM_NORMAL)) /* Item type. */ #define ITEM_BUTTON (1<<9) /* Item is command button. */ #define ITEM_RADIOBUTTON (1<<10) /* Item is radiobutton. */ #define ITEM_CHECKBUTTON (1<<11) /* Item is checkbutton. */ #define ITEM_CASCADE (1<<12) /* Item is cascade. */ #define ITEM_SEPARATOR (1<<13) /* Item is separator. */ #define ITEM_TYPE_MASK ((ITEM_BUTTON)|(ITEM_RADIOBUTTON)|(ITEM_CHECKBUTTON)|\ (ITEM_CASCADE)|(ITEM_SEPARATOR)) #define DEF_COMBO_BORDERWIDTH "1" #define DEF_COMBO_CURSOR ((char *)NULL) #define DEF_COMBO_HEIGHT "0" #define DEF_COMBO_ICON_VARIABLE ((char *)NULL) #define DEF_COMBO_POSTCOMMAND ((char *)NULL) #define DEF_COMBO_RELIEF "solid" #define DEF_COMBO_SCROLLBAR ((char *)NULL) #define DEF_COMBO_SCROLL_CMD ((char *)NULL) #define DEF_COMBO_SCROLL_INCR "2" #define DEF_COMBO_TAKE_FOCUS "1" #define DEF_COMBO_TEXT_VARIABLE ((char *)NULL) #define DEF_COMBO_UNPOSTCOMMAND ((char *)NULL) #define DEF_COMBO_WIDTH "0" #define DEF_COMBO_CHECKBUTTON_FILL_COLOR (char *)NULL #define DEF_COMBO_CHECKBUTTON_OUTLINE_COLOR (char *)NULL #define DEF_COMBO_CHECKBUTTON_COLOR STD_INDICATOR_COLOR #define DEF_COMBO_CHECKBUTTON_SIZE "12" #define DEF_COMBO_RADIOBUTTON_FILL_COLOR RGB_WHITE #define DEF_COMBO_RADIOBUTTON_OUTLINE_COLOR RGB_BLACK #define DEF_COMBO_RADIOBUTTON_COLOR STD_INDICATOR_COLOR #define DEF_COMBO_RADIOBUTTON_SIZE "12" #define DEF_ITEM_ACCELERATOR ((char *)NULL) #define DEF_ITEM_BITMAP ((char *)NULL) #define DEF_ITEM_COMMAND ((char *)NULL) #define DEF_ITEM_DATA ((char *)NULL) #define DEF_ITEM_ICON ((char *)NULL) #define DEF_ITEM_IMAGE ((char *)NULL) #define DEF_ITEM_INDENT "0" #define DEF_ITEM_MENU ((char *)NULL) #define DEF_ITEM_OFF_VALUE "0" #define DEF_ITEM_ON_VALUE "1" #define DEF_ITEM_STATE "normal" #define DEF_ITEM_STYLE "default" #define DEF_ITEM_TAGS ((char *)NULL) #define DEF_ITEM_TEXT ((char *)NULL) #define DEF_ITEM_TIP ((char *)NULL) #define DEF_ITEM_TYPE "command" #define DEF_ITEM_UNDERLINE "-1" #define DEF_ITEM_VALUE ((char *)NULL) #define DEF_ITEM_VARIABLE ((char *)NULL) #define DEF_STYLE_ACCEL_ACTIVE_FG RGB_WHITE #define DEF_STYLE_ACCEL_FG RGB_BLACK #define DEF_STYLE_ACCEL_FONT STD_FONT_SMALL #define DEF_STYLE_ACTIVE_BG RGB_SKYBLUE4 #define DEF_STYLE_ACTIVE_FG RGB_WHITE #define DEF_STYLE_ACTIVE_RELIEF "flat" #define DEF_STYLE_BG RGB_WHITE #define DEF_STYLE_BORDERWIDTH "0" #define DEF_STYLE_DISABLED_ACCEL_FG STD_DISABLED_FOREGROUND #define DEF_STYLE_DISABLED_BG DISABLED_BACKGROUND #define DEF_STYLE_DISABLED_FG DISABLED_FOREGROUND #define DEF_STYLE_FG RGB_BLACK #define DEF_STYLE_FONT STD_FONT_SMALL #define DEF_STYLE_IND_FILL_COLOR (char *)NULL #define DEF_STYLE_IND_OUTLINE_COLOR (char *)NULL #define DEF_STYLE_IND_COLOR (char *)NULL #define DEF_STYLE_IND_SIZE "12" #define DEF_STYLE_RELIEF "flat" #define DISABLED_BACKGROUND RGB_GREY90 #define DISABLED_FOREGROUND RGB_GREY70 static Blt_OptionFreeProc FreeStyleProc; static Blt_OptionParseProc ObjToStyleProc; static Blt_OptionPrintProc StyleToObjProc; static Blt_CustomOption styleOption = { ObjToStyleProc, StyleToObjProc, FreeStyleProc, (ClientData)0 }; static Blt_OptionFreeProc FreeTagsProc; static Blt_OptionParseProc ObjToTagsProc; static Blt_OptionPrintProc TagsToObjProc; static Blt_CustomOption tagsOption = { ObjToTagsProc, TagsToObjProc, FreeTagsProc, (ClientData)0 }; static Blt_OptionParseProc ObjToTypeProc; static Blt_OptionPrintProc TypeToObjProc; static Blt_CustomOption typeOption = { ObjToTypeProc, TypeToObjProc, NULL, (ClientData)0 }; static Blt_OptionFreeProc FreeLabelProc; static Blt_OptionParseProc ObjToLabelProc; static Blt_OptionPrintProc LabelToObjProc; static Blt_CustomOption labelOption = { ObjToLabelProc, LabelToObjProc, FreeLabelProc, (ClientData)0 }; static Blt_OptionFreeProc FreeIconProc; static Blt_OptionParseProc ObjToIconProc; static Blt_OptionPrintProc IconToObjProc; static Blt_CustomOption iconOption = { ObjToIconProc, IconToObjProc, FreeIconProc, (ClientData)0 }; static Blt_OptionFreeProc FreeTraceVarProc; static Blt_OptionParseProc ObjToTraceVarProc; static Blt_OptionPrintProc TraceVarToObjProc; static Blt_CustomOption traceVarOption = { ObjToTraceVarProc, TraceVarToObjProc, FreeTraceVarProc, (ClientData)0 }; static Blt_OptionParseProc ObjToStateProc; static Blt_OptionPrintProc StateToObjProc; static Blt_CustomOption stateOption = { ObjToStateProc, StateToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToRestrictProc; static Blt_OptionPrintProc RestrictToObjProc; static Blt_CustomOption restrictOption = { ObjToRestrictProc, RestrictToObjProc, NULL, (ClientData)0 }; extern Blt_CustomOption bltLimitsOption; typedef struct _ComboMenu ComboMenu; /* * Icon -- * * Since instances of the same Tk image can be displayed in different * windows with possibly different color palettes, Tk internally stores * each instance in a linked list. But if the instances are used in the * same widget and therefore use the same color palette, this adds a lot * of overhead, especially when deleting instances from the linked list. * * For the combomenu widget, we never need more than a single instance of * an image, regardless of how many times it's used. Cache the image, * maintaining a reference count for each image used in the widget. It's * likely that the combomenu widget will use many instances of the same * image. */ typedef struct _Icon { Tk_Image tkImage; /* The Tk image being cached. */ Blt_HashEntry *hPtr; /* Hash table pointer to the image. */ int refCount; /* Reference count for this image. */ short int width, height; /* Dimensions of the cached image. */ } *Icon; #define IconHeight(i) ((i)->height) #define IconWidth(i) ((i)->width) #define IconImage(i) ((i)->tkImage) #define IconName(i) (Blt_Image_Name(IconImage(i))) typedef struct { const char *name; Blt_HashEntry *hPtr; ComboMenu *comboPtr; int refCount; /* Indicates if the style is currently * in use in the combomenu. */ int borderWidth; int relief; int activeRelief; int reqIndWidth; Blt_Background normalBg; Blt_Background activeBg; Blt_Background disabledBg; XColor *normalFgColor; XColor *activeFgColor; XColor *disabledFgColor; Blt_Font accelFont; /* Font of accelerator text. */ XColor *accelNormalColor; /* Color of accelerator text. */ XColor *accelDisabledColor; /* Color of accelerator text. */ XColor *accelActiveColor; /* Color of accelerator background. */ Blt_Font labelFont; /* Font of the label */ XColor *labelNormalColor; /* Color of label text. */ XColor *labelDisabledColor; /* Color of label background. */ XColor *labelActiveColor; /* Color of label background. */ /* Radiobuttons, checkbuttons, and cascades. */ Blt_Picture radiobutton[3]; Blt_Picture checkbutton[3]; XColor *indOutlineColor; XColor *indFillColor; XColor *indColor; GC accelActiveGC; GC accelDisabledGC; GC accelNormalGC; GC labelActiveGC; GC labelDisabledGC; GC labelNormalGC; } Style; static Blt_ConfigSpec styleConfigSpecs[] = { {BLT_CONFIG_FONT, "-acceleratorfont", (char *)NULL, (char *)NULL, DEF_STYLE_ACCEL_FONT, Blt_Offset(Style, accelFont), 0}, {BLT_CONFIG_COLOR, "-acceleratorforeground", (char *)NULL, (char *)NULL, DEF_STYLE_ACCEL_FG, Blt_Offset(Style, accelNormalColor), 0}, {BLT_CONFIG_COLOR, "-activeacceleratorforeground", (char *)NULL, (char *)NULL, DEF_STYLE_ACCEL_ACTIVE_FG, Blt_Offset(Style, accelActiveColor), 0}, {BLT_CONFIG_BACKGROUND, "-activebackground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_BG, Blt_Offset(Style, activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_FG, Blt_Offset(Style, labelActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(Style, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", (char *)NULL, (char *)NULL, DEF_STYLE_BG, Blt_Offset(Style, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", (char *)NULL, (char *)NULL, DEF_STYLE_BORDERWIDTH, Blt_Offset(Style, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-disabledacceleratorforeground", (char *)NULL, (char *)NULL, DEF_STYLE_DISABLED_ACCEL_FG, Blt_Offset(Style, accelDisabledColor), 0}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", (char *)NULL, (char *)NULL, DEF_STYLE_DISABLED_BG, Blt_Offset(Style, disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", (char *)NULL, (char *)NULL, DEF_STYLE_DISABLED_FG, Blt_Offset(Style, labelDisabledColor), 0}, {BLT_CONFIG_SYNONYM, "-fg", (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", (char *)NULL, (char *)NULL, DEF_STYLE_FG, Blt_Offset(Style, labelNormalColor), 0}, {BLT_CONFIG_FONT, "-font", (char *)NULL, (char *)NULL, DEF_STYLE_FONT, Blt_Offset(Style, labelFont), 0}, {BLT_CONFIG_COLOR, "-indicatorfillcolor", (char *)NULL, (char *)NULL, DEF_STYLE_IND_FILL_COLOR, Blt_Offset(Style, indFillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-indicatoroutlinecolor", (char *)NULL, (char *)NULL, DEF_STYLE_IND_OUTLINE_COLOR, Blt_Offset(Style, indOutlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-indicatorcolor", (char *)NULL, (char *)NULL, DEF_STYLE_IND_COLOR, Blt_Offset(Style, indColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-indicatorsize", (char *)NULL, (char *)NULL, DEF_STYLE_IND_SIZE, Blt_Offset(Style, reqIndWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", (char *)NULL, (char *)NULL, DEF_STYLE_RELIEF, Blt_Offset(Style, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * * [left indicator] [icon] [label] [right indicator/accel] [scrollbar] * * left indicator: checkbutton or radiobutton entries. * icon: all entries. * label: all entries. * accel: checkbutton, radiobutton, or button entries. * right indicator: cascade item only. */ typedef struct { ComboMenu *comboPtr; /* Combomenu containing this item. */ long index; /* Index of the item (numbered from 0)*/ int xWorld, yWorld; /* Upper left world-coordinate of item * in menu. */ Style *stylePtr; /* Style used by this item. */ unsigned int flags; /* Contains various bits of * information about the item, such as * type, state. */ Blt_ChainLink link; int relief; int underline; /* Underlined character. */ int indent; /* # of pixels to indent the icon. */ Icon image; /* If non-NULL, image to be displayed * instead of text label. */ Icon icon; /* Button, RadioButton, and * CheckButton entries. */ const char *label; /* Label to be displayed. */ const char *accel; /* Accelerator text. May be NULL.*/ Tcl_Obj *cmdObjPtr; /* Command to be invoked when item is * clicked. */ Tcl_Obj *dataObjPtr; /* User-data associated with this * item. */ Tcl_Obj *variableObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * value string of the selected * item. */ Tcl_Obj *valueObjPtr; /* Radiobutton value. */ /* Checkbutton on and off values. */ Tcl_Obj *onValueObjPtr; /* Checkbutton on-value. */ Tcl_Obj *offValueObjPtr; /* Checkbutton off-value. */ /* Cascade menu. */ Tcl_Obj *menuObjPtr; /* Name of the sub-menu. */ Tcl_Obj *tagsObjPtr; Tcl_Obj *tipObjPtr; short int labelWidth, labelHeight; short int iconWidth, iconHeight; short int leftIndWidth, leftIndHeight; short int rightIndWidth, rightIndHeight; short int width, height; } Item; static Blt_ConfigSpec itemConfigSpecs[] = { {BLT_CONFIG_STRING, "-accelerator", (char *)NULL, (char *)NULL, DEF_ITEM_ACCELERATOR, Blt_Offset(Item, accel), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-command", (char *)NULL, (char *)NULL, DEF_ITEM_COMMAND, Blt_Offset(Item, cmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-data", (char *)NULL, (char *)NULL, DEF_ITEM_DATA, Blt_Offset(Item, dataObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-icon", (char *)NULL, (char *)NULL, DEF_ITEM_ICON, Blt_Offset(Item, icon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-image", (char *)NULL, (char *)NULL, DEF_ITEM_IMAGE, Blt_Offset(Item, image), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_PIXELS_NNEG, "-indent", (char *)NULL, (char *)NULL, DEF_ITEM_INDENT, Blt_Offset(Item, indent), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-menu", (char *)NULL, (char *)NULL, DEF_ITEM_MENU, Blt_Offset(Item, menuObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-offvalue", (char *)NULL, (char *)NULL, DEF_ITEM_OFF_VALUE, Blt_Offset(Item, offValueObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-onvalue", (char *)NULL, (char *)NULL, DEF_ITEM_ON_VALUE, Blt_Offset(Item, onValueObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-state", (char *)NULL, (char *)NULL, DEF_ITEM_STATE, Blt_Offset(Item, flags), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, {BLT_CONFIG_CUSTOM, "-style", (char *)NULL, (char *)NULL, DEF_ITEM_STYLE, Blt_Offset(Item, stylePtr), 0, &styleOption}, {BLT_CONFIG_CUSTOM, "-tags", (char *)NULL, (char *)NULL, DEF_ITEM_TAGS, 0, BLT_CONFIG_NULL_OK, &tagsOption}, {BLT_CONFIG_CUSTOM, "-text", (char *)NULL, (char *)NULL, DEF_ITEM_TEXT, Blt_Offset(Item, label), BLT_CONFIG_NULL_OK, &labelOption}, {BLT_CONFIG_OBJ, "-tooltip", (char *)NULL, (char *)NULL, DEF_ITEM_TIP, Blt_Offset(Item, tipObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-type", (char *)NULL, (char *)NULL, DEF_ITEM_TYPE, Blt_Offset(Item, flags), BLT_CONFIG_DONT_SET_DEFAULT, &typeOption}, {BLT_CONFIG_INT, "-underline", (char *)NULL, (char *)NULL, DEF_ITEM_UNDERLINE, Blt_Offset(Item, underline), BLT_CONFIG_DONT_SET_DEFAULT }, {BLT_CONFIG_OBJ, "-value", (char *)NULL, (char *)NULL, DEF_ITEM_VALUE, Blt_Offset(Item, valueObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-variable", (char *)NULL, (char *)NULL, DEF_ITEM_VARIABLE, Blt_Offset(Item, variableObjPtr), BLT_CONFIG_NULL_OK, &traceVarOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; struct _ComboMenu { /* * This works around a bug in the Tk API. Under Win32, Tk tries to * read the widget record of toplevel windows (TopLevel or Frame widget), * to get its menu name field. What this means is that we must carefully * arrange the fields of this widget so that the menuName field is at the * same offset in the structure. */ Tk_Window tkwin; /* Window that embodies the frame. * NULL means that the window has been * destroyed but the data structures * haven't yet been cleaned up. */ Display *display; /* Display containing widget. Used, * among other things, so that * resources can be freed even after * tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. * Used to delete widget command. */ Tcl_Command cmdToken; /* Token for widget's command. */ Tcl_Obj *postCmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ Tcl_Obj *unpostCmdObjPtr; /* If non-NULL, command to be executed * when this menu is posted. */ unsigned int flags; Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * name of the Tk image representing * the icon of the selected item. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * text string of the label of the * selected item. */ Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not * used in the C code, but used by * keyboard * traversal scripts. */ char *menuName; /* Textual description of menu to use * for menubar. Malloc-ed, may be * NULL. */ Tk_Cursor cursor; /* Current cursor for window or None. */ Tk_Anchor anchor; Blt_Limits reqWidth, reqHeight; int relief; int borderWidth; Style defStyle; /* Default style. */ int parentWidth; int normalWidth, normalHeight; int xScrollUnits, yScrollUnits; /* Names of scrollbars to embed into the widget window. */ Tcl_Obj *xScrollbarObjPtr, *yScrollbarObjPtr; /* Commands to control horizontal and vertical scrollbars. */ Tcl_Obj *xScrollCmdObjPtr, *yScrollCmdObjPtr; Blt_HashTable tagTable; /* Table of tags. */ Blt_HashTable labelTable; /* Table of labels (hashtables). */ Blt_HashTable iconTable; /* Table of icons. */ Blt_Chain chain; Item *activePtr; /* If non-NULL, item that is currently * active. If a cascade item, a * submenu may be posted. */ Item *postedPtr; Item *firstPtr, *lastPtr; /* Defines the range of visible * items. */ int xOffset, yOffset; /* Scroll offsets of viewport in * world. */ int worldWidth, worldHeight; /* Dimension of entire menu. */ Tk_Window xScrollbar; /* Horizontal scrollbar to be used if * necessary. If NULL, no x-scrollbar * is used. */ Tk_Window yScrollbar; /* Vertical scrollbar to be used if * necessary. If NULL, no y-scrollbar * is used. */ short int yScrollbarWidth, xScrollbarHeight; short int leftIndWidth, rightIndWidth; short int labelWidth, iconWidth; Blt_HashTable styleTable; /* Table of styles used. */ Icon rbIcon; Icon cbIcon; Icon casIcon; XColor *checkButtonFillColor; XColor *checkButtonOutlineColor; XColor *checkButtonColor; int checkButtonReqSize; XColor *radioButtonFillColor; XColor *radioButtonOutlineColor; XColor *radioButtonColor; int radioButtonReqSize; /* * Scanning Information: */ int scanAnchorX; /* Horizontal scan anchor in screen * x-coordinates. */ int scanX; /* x-offset of the start of the * horizontal scan in world * coordinates.*/ int scanAnchorY; /* Vertical scan anchor in screen * y-coordinates. */ int scanY; /* y-offset of the start of the * vertical scan in world * coordinates.*/ short int width, height; Blt_Painter painter; }; static Blt_ConfigSpec comboConfigSpecs[] = { {BLT_CONFIG_FONT, "-acceleratorfont", "acceleratorFont", "AcceleratorFont", DEF_STYLE_ACCEL_FONT, Blt_Offset(ComboMenu, defStyle.accelFont), 0}, {BLT_CONFIG_COLOR, "-acceleratorforeground", "acceleratorForeground", "AcceleratorForeground", DEF_STYLE_ACCEL_FG, Blt_Offset(ComboMenu, defStyle.accelNormalColor), 0}, {BLT_CONFIG_COLOR, "-activeacceleratorforeground", "activeAcceleratorForeground", "ActiveAcceleratorForeground", DEF_STYLE_ACCEL_ACTIVE_FG, Blt_Offset(ComboMenu, defStyle.accelActiveColor), 0}, {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BG, Blt_Offset(ComboMenu, defStyle.activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FG, Blt_Offset(ComboMenu, defStyle.labelActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "ActiveRelief", DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(ComboMenu, defStyle.activeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_STYLE_BG, Blt_Offset(ComboMenu, defStyle.normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_COMBO_BORDERWIDTH, Blt_Offset(ComboMenu, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_COMBO_CURSOR, Blt_Offset(ComboMenu, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-disabledacceleratorforeground", "disabledAcceleratorForeground", "DisabledAcceleratorForeground", DEF_STYLE_DISABLED_ACCEL_FG, Blt_Offset(ComboMenu, defStyle.accelDisabledColor), 0}, {BLT_CONFIG_BACKGROUND, "-disabledbackground", "disabledBackground", "DisabledBackground", DEF_STYLE_DISABLED_BG, Blt_Offset(ComboMenu, defStyle.disabledBg), 0}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_STYLE_DISABLED_FG, Blt_Offset(ComboMenu, defStyle.labelDisabledColor), 0}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_STYLE_FG, Blt_Offset(ComboMenu, defStyle.labelNormalColor), 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_STYLE_FONT, Blt_Offset(ComboMenu, defStyle.labelFont), 0}, {BLT_CONFIG_CUSTOM, "-height", "height", "Height", DEF_COMBO_HEIGHT, Blt_Offset(ComboMenu, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT, &bltLimitsOption}, {BLT_CONFIG_OBJ, "-iconvariable", "iconVariable", "IconVariable", DEF_COMBO_ICON_VARIABLE, Blt_Offset(ComboMenu, iconVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-itemborderwidth", "itemBorderWidth", "ItemBorderWidth", DEF_STYLE_BORDERWIDTH, Blt_Offset(ComboMenu, defStyle.borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-postcommand", "postCommand", "PostCommand", DEF_COMBO_POSTCOMMAND, Blt_Offset(ComboMenu, postCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_COMBO_RELIEF, Blt_Offset(ComboMenu, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-restrictwidth", "restrictWidth", "RestrictWidth", (char *)NULL, Blt_Offset(ComboMenu, flags), BLT_CONFIG_DONT_SET_DEFAULT, &restrictOption}, {BLT_CONFIG_OBJ, "-textvariable", "textVariable", "TextVariable", DEF_COMBO_TEXT_VARIABLE, Blt_Offset(ComboMenu, textVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-xscrollbar", "xScrollbar", "Scrollbar", DEF_COMBO_SCROLLBAR, Blt_Offset(ComboMenu, xScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_COMBO_SCROLL_CMD, Blt_Offset(ComboMenu, xScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_COMBO_SCROLL_INCR, Blt_Offset(ComboMenu, xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yscrollbar", "yScrollbar", "Scrollbar", DEF_COMBO_SCROLLBAR, Blt_Offset(ComboMenu, yScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", DEF_COMBO_SCROLL_CMD, Blt_Offset(ComboMenu, yScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_COMBO_SCROLL_INCR, Blt_Offset(ComboMenu, yScrollUnits),BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_COMBO_TAKE_FOCUS, Blt_Offset(ComboMenu, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-unpostcommand", "unpostCommand", "UnpostCommand", DEF_COMBO_UNPOSTCOMMAND, Blt_Offset(ComboMenu, unpostCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-width", "width", "Width", DEF_COMBO_WIDTH, Blt_Offset(ComboMenu, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT, &bltLimitsOption}, #ifdef notdef {BLT_CONFIG_CUSTOM, "-radioimage", (char *)NULL, (char *)NULL, DEF_ITEM_IMAGE, Blt_Offset(ComboMenu, rbIcon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-checkimage", (char *)NULL, (char *)NULL, DEF_ITEM_IMAGE, Blt_Offset(ComboMenu, cbIcon), BLT_CONFIG_NULL_OK, &iconOption}, {BLT_CONFIG_CUSTOM, "-cascadeimage", (char *)NULL, (char *)NULL, DEF_ITEM_IMAGE, Blt_Offset(ComboMenu, casIcon), BLT_CONFIG_NULL_OK, &iconOption}, #endif {BLT_CONFIG_COLOR, "-checkbuttonfillcolor", (char *)NULL, (char *)NULL, DEF_COMBO_CHECKBUTTON_FILL_COLOR, Blt_Offset(ComboMenu, checkButtonFillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-checkbuttonoutlinecolor", (char *)NULL, (char *)NULL, DEF_COMBO_CHECKBUTTON_OUTLINE_COLOR, Blt_Offset(ComboMenu, checkButtonOutlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-checkbuttoncolor", (char *)NULL, (char *)NULL, DEF_COMBO_CHECKBUTTON_COLOR, Blt_Offset(ComboMenu, checkButtonColor),0}, {BLT_CONFIG_PIXELS_NNEG, "-checkbuttonsize", (char *)NULL, (char *)NULL, DEF_COMBO_CHECKBUTTON_SIZE, Blt_Offset(ComboMenu, checkButtonReqSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_COLOR, "-radiobuttonfillcolor", (char *)NULL, (char *)NULL, DEF_COMBO_RADIOBUTTON_FILL_COLOR, Blt_Offset(ComboMenu, radioButtonFillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-radiobuttonoutlinecolor", (char *)NULL, (char *)NULL, DEF_COMBO_RADIOBUTTON_OUTLINE_COLOR, Blt_Offset(ComboMenu, radioButtonOutlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-radiobuttoncolor", (char *)NULL, (char *)NULL, DEF_COMBO_RADIOBUTTON_COLOR, Blt_Offset(ComboMenu, radioButtonColor),0}, {BLT_CONFIG_PIXELS_NNEG, "-radiobuttonsize", (char *)NULL, (char *)NULL, DEF_COMBO_RADIOBUTTON_SIZE, Blt_Offset(ComboMenu, radioButtonReqSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * ItemIterator -- * * Items may be tagged with strings. An item may have many tags. The * same tag may be used for many items. * */ typedef enum { ITER_SINGLE, ITER_ALL, ITER_TAG, ITER_TYPE, ITER_PATTERN } IteratorType; typedef struct _Iterator { ComboMenu *comboPtr; /* ComboMenu that we're iterating * over. */ IteratorType type; /* Type of iteration: * ITER_TAG By item tag. * ITER_ALL By every item. * ITER_SINGLE Single item: either * tag or index. * ITER_TYPE Over a single item * type. */ Item *startPtr, *last; /* Starting and ending item. Starting * point of search, saved if iterator * is reused. Used for ITER_ALL and * ITER_SINGLE searches. */ Item *endPtr; /* Ending item (inclusive). */ Item *nextPtr; /* Next item. */ int itemType; /* For tag-based searches. */ char *tagName; /* If non-NULL, is the tag that we are * currently iterating over. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Search iterator for tag hash * table. */ Blt_ChainLink link; } ItemIterator; static Tk_GeomRequestProc ScrollbarGeometryProc; static Tk_GeomLostSlaveProc ScrollbarCustodyProc; static Tk_GeomMgr comboMgrInfo = { (char *)"combomenu", /* Name of geometry manager used by * winfo. */ ScrollbarGeometryProc, /* Procedure to for new geometry * requests. */ ScrollbarCustodyProc, /* Procedure when scrollbar is taken * away. */ }; static Blt_SwitchParseProc TypeSwitch; static Blt_SwitchCustom typeSwitch = { TypeSwitch, NULL, NULL, }; static Blt_SwitchParseProc ItemSwitch; static Blt_SwitchCustom itemSwitch = { ItemSwitch, NULL, NULL, }; #define FIND_DECREASING (1<<0) #define FIND_UNDERLINE (1<<1) #define FIND_GLOB 1 #define FIND_REGEXP 2 typedef struct { unsigned int mask; int search; int type; Item *fromPtr; } FindSwitches; static Blt_SwitchSpec findSwitches[] = { {BLT_SWITCH_CUSTOM, "-from", "item", Blt_Offset(FindSwitches, fromPtr), 0, 0, &itemSwitch}, {BLT_SWITCH_BITMASK, "-decreasing", "", Blt_Offset(FindSwitches, mask), 0, FIND_DECREASING}, {BLT_SWITCH_VALUE, "-glob", "", Blt_Offset(FindSwitches, search), 0, FIND_GLOB}, {BLT_SWITCH_VALUE, "-regexp", "", Blt_Offset(FindSwitches, search), 0, FIND_REGEXP}, {BLT_SWITCH_CUSTOM, "-type", "type", Blt_Offset(FindSwitches, type), 0, 0, &typeSwitch}, {BLT_SWITCH_BITMASK, "-underline", "", Blt_Offset(FindSwitches, mask), 0, FIND_UNDERLINE}, {BLT_SWITCH_END} }; typedef int (ComboMenuCmdProc)(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int GetItemIterator(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, ItemIterator *iterPtr); static int GetItemFromObj(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, Item **itemPtrPtr); static Tcl_IdleProc ConfigureScrollbarsProc; static Tcl_IdleProc DisplayItem; static Tcl_IdleProc DisplayComboMenu; static Tcl_FreeProc DestroyComboMenu; static Tk_EventProc ScrollbarEventProc; static Tk_EventProc ComboMenuEventProc; static Tcl_ObjCmdProc ComboMenuInstCmdProc; static Tcl_CmdDeleteProc ComboMenuInstCmdDeletedProc; static Tcl_VarTraceProc ItemVarTraceProc; static Tk_ImageChangedProc IconChangedProc; /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the combomenu display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(ComboMenu *comboPtr) { if ((comboPtr->tkwin != NULL) && !(comboPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayComboMenu, comboPtr); comboPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * EventuallyRedrawItem -- * * Tells the Tk dispatcher to call the combomenu display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawItem(Item *itemPtr) { ComboMenu *comboPtr; comboPtr = itemPtr->comboPtr; if ((comboPtr->tkwin != NULL) && ((comboPtr->flags & REDRAW_PENDING) == 0) && ((itemPtr->flags & ITEM_REDRAW) == 0)) { Tcl_DoWhenIdle(DisplayItem, itemPtr); itemPtr->flags |= ITEM_REDRAW; } } static void ConfigureScrollbarsProc(ClientData clientData) { ComboMenu *comboPtr = clientData; Tcl_Interp *interp; interp = comboPtr->interp; /* * Execute the initialization procedure on this widget. */ comboPtr->flags &= ~UPDATE_PENDING; if (Tcl_VarEval(interp, "::blt::ComboMenu::ConfigureScrollbars ", Tk_PathName(comboPtr->tkwin), (char *)NULL) != TCL_OK) { Tcl_BackgroundError(interp); } } /* *--------------------------------------------------------------------------- * * ReleaseTags -- * * Releases the tags used by this item. * *--------------------------------------------------------------------------- */ static void ReleaseTags(ComboMenu *comboPtr, Item *itemPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&comboPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tagTablePtr; Blt_HashEntry *h2Ptr; tagTablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tagTablePtr, (char *)itemPtr->index); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tagTablePtr, h2Ptr); } } } static void DestroyItem(Item *itemPtr) { ComboMenu *comboPtr = itemPtr->comboPtr; ReleaseTags(comboPtr, itemPtr); iconOption.clientData = comboPtr; Blt_FreeOptions(itemConfigSpecs, (char *)itemPtr, comboPtr->display, 0); if (comboPtr->activePtr == itemPtr) { comboPtr->activePtr = NULL; } if (comboPtr->postedPtr == itemPtr) { comboPtr->postedPtr = NULL; } Blt_Chain_DeleteLink(comboPtr->chain, itemPtr->link); } static void DestroyItems(ComboMenu *comboPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(comboPtr->chain); link != NULL; link = next) { Item *itemPtr; next = Blt_Chain_NextLink(link); itemPtr = Blt_Chain_GetValue(link); DestroyItem(itemPtr); } Blt_Chain_Destroy(comboPtr->chain); } static Item * NewItem(ComboMenu *comboPtr) { Item *itemPtr; Blt_ChainLink link; link = Blt_Chain_AllocLink(sizeof(Item)); itemPtr = Blt_Chain_GetValue(link); itemPtr->comboPtr = comboPtr; itemPtr->flags |= (ITEM_BUTTON | ITEM_NORMAL); itemPtr->link = link; itemPtr->index = Blt_Chain_GetLength(comboPtr->chain); Blt_Chain_LinkAfter(comboPtr->chain, link, NULL); itemPtr->label = emptyString; itemPtr->underline = -1; return itemPtr; } static INLINE Item * FindItemByIndex(ComboMenu *comboPtr, long index) { Blt_ChainLink link; if ((index < 1) || (index > Blt_Chain_GetLength(comboPtr->chain))) { return NULL; } link = Blt_Chain_GetNthLink(comboPtr->chain, index - 1); return Blt_Chain_GetValue(link); } static INLINE Item * FirstItem(ComboMenu *comboPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(comboPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & ITEM_DISABLED) == 0) { return itemPtr; } } return NULL; } static INLINE Item * LastItem(ComboMenu *comboPtr) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(comboPtr->chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & ITEM_DISABLED) == 0) { return itemPtr; } } return NULL; } static Item * NextItem(Item *itemPtr) { if (itemPtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_NextLink(itemPtr->link); link != NULL; link = Blt_Chain_NextLink(link)) { itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_SEPARATOR|ITEM_DISABLED)) == 0) { return itemPtr; } } } return NULL; } static INLINE Item * PrevItem(Item *itemPtr) { if (itemPtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_PrevLink(itemPtr->link); link != NULL; link = Blt_Chain_PrevLink(link)) { itemPtr = Blt_Chain_GetValue(link); if ((itemPtr->flags & (ITEM_SEPARATOR|ITEM_DISABLED)) == 0) { return itemPtr; } } } return NULL; } static INLINE Item * BeginItem(ComboMenu *comboPtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(comboPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static INLINE Item * EndItem(ComboMenu *comboPtr) { Blt_ChainLink link; link = Blt_Chain_LastLink(comboPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static Item * StepItem(Item *itemPtr) { if (itemPtr != NULL) { Blt_ChainLink link; link = Blt_Chain_NextLink(itemPtr->link); if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } static int SelectItem(Tcl_Interp *interp, ComboMenu *comboPtr, Item *itemPtr, int newState) { int result; if (itemPtr->flags & (ITEM_CASCADE|ITEM_SEPARATOR)) { return TCL_OK; } result = TCL_OK; if (newState == -1) { newState = (itemPtr->flags & ITEM_SELECTED) == 0; } if ((comboPtr->iconVarObjPtr != NULL) && (itemPtr->icon != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(IconName(itemPtr->icon), -1); if (Tcl_ObjSetVar2(interp, comboPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } if ((comboPtr->textVarObjPtr != NULL) && (itemPtr->label != emptyString)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(itemPtr->label, -1); if (Tcl_ObjSetVar2(interp, comboPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } if (itemPtr->variableObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = NULL; if (itemPtr->flags & ITEM_CHECKBUTTON) { objPtr = (newState) ? itemPtr->onValueObjPtr : itemPtr->offValueObjPtr; } else { objPtr = itemPtr->valueObjPtr; if (objPtr == NULL) { objPtr = Tcl_NewStringObj(itemPtr->label, -1); } } if (objPtr != NULL) { Tcl_IncrRefCount(objPtr); if (Tcl_ObjSetVar2(interp, itemPtr->variableObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; } Tcl_DecrRefCount(objPtr); } } return result; } /* *--------------------------------------------------------------------------- * * ActivateItem -- * * Marks the designated item as active. The item is redrawn with its * active colors. The previously active item is deactivated. If the new * item is NULL, then this means that no new item is to be activated. * * Results: * None. * * Side effects: * Menu items may be scheduled to be drawn. * *--------------------------------------------------------------------------- */ static void ActivateItem(ComboMenu *comboPtr, Item *itemPtr) { if ((comboPtr->activePtr == itemPtr) && (itemPtr != NULL)) { return; /* Item is already active. */ } if (comboPtr->activePtr != NULL) { EventuallyRedrawItem(comboPtr->activePtr); } comboPtr->activePtr = itemPtr; if (itemPtr != NULL) { EventuallyRedrawItem(itemPtr); } } /* *--------------------------------------------------------------------------- * * GetBoundedWidth -- * * Bounds a given width value to the limits described in the limit * structure. The initial starting value may be overridden by the nominal * value in the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedWidth(ComboMenu *comboPtr, int w) { /* * Check widgets for requested width values; */ if (comboPtr->reqWidth.flags & LIMITS_NOM_SET) { w = comboPtr->reqWidth.nom; /* Override initial value */ } if (w < comboPtr->reqWidth.min) { w = comboPtr->reqWidth.min; /* Bounded by minimum value */ } if (w > comboPtr->reqWidth.max) { w = comboPtr->reqWidth.max; /* Bounded by maximum value */ } if (comboPtr->flags & (RESTRICT_MIN|RESTRICT_MAX)) { Tk_Window parent; parent = Tk_Parent(comboPtr->tkwin); if ((comboPtr->flags & RESTRICT_MIN) && (w < Tk_Width(parent))) { w = Tk_Width(parent); } if ((comboPtr->flags & RESTRICT_MAX) && (w > Tk_Width(parent))) { w = Tk_Width(parent); } } { int screenWidth, screenHeight; Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); if (w > screenWidth) { w = screenWidth; } } return w; } /* *--------------------------------------------------------------------------- * * GetBoundedHeight -- * * Bounds a given value to the limits described in the limit structure. * The initial starting value may be overridden by the nominal value in * the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int GetBoundedHeight(ComboMenu *comboPtr, int h) { /* * Check widgets for requested height values; */ if (comboPtr->reqHeight.flags & LIMITS_NOM_SET) { h = comboPtr->reqHeight.nom; /* Override initial value */ } if (h < comboPtr->reqHeight.min) { h = comboPtr->reqHeight.min; /* Bounded by minimum value */ } if (h > comboPtr->reqHeight.max) { h = comboPtr->reqHeight.max; /* Bounded by maximum value */ } if (h > HeightOfScreen(Tk_Screen(comboPtr->tkwin))) { h = HeightOfScreen(Tk_Screen(comboPtr->tkwin)); } return h; } static void FixMenuCoords(ComboMenu *comboPtr, Tk_Window parent, int *xPtr, int *yPtr) { int x, y, w, h, pw, ph; int screenWidth, screenHeight; Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); x = *xPtr, y = *yPtr; /* Determine the size of the menu. */ w = Tk_ReqWidth(comboPtr->tkwin); h = Tk_ReqHeight(comboPtr->tkwin); if (parent == comboPtr->tkwin) { /* This is a popup. */ pw = w; ph = h; } else { pw = Tk_Width(parent); ph = Tk_Height(parent); } if ((y + h) > screenHeight) { y -= (ph + h); /* Flip to show menu above. */ if (y < 0) { y = 0; } } if ((x + w) > screenWidth) { x -= pw; /* Flip to show menu on left side. */ if (x < 0) { x = 0; } } *xPtr = x; *yPtr = y; } static void ComputeItemGeometry(ComboMenu *comboPtr, Item *itemPtr) { /* Determine the height of the item. It's the maximum height of all it's * components: left gadget (radiobutton or checkbutton), icon, label, * right gadget (cascade), and accelerator. */ itemPtr->labelWidth = itemPtr->labelHeight = 0; itemPtr->leftIndWidth = itemPtr->leftIndHeight = 0; itemPtr->rightIndWidth = itemPtr->rightIndHeight = 0; itemPtr->iconWidth = itemPtr->iconHeight = 0; itemPtr->width = itemPtr->height = 0; if (itemPtr->flags & ITEM_SEPARATOR) { itemPtr->height = ITEM_SEP_HEIGHT; itemPtr->width = 0; if (itemPtr->image != NULL) { itemPtr->labelWidth = IconWidth(itemPtr->image); itemPtr->labelHeight = IconHeight(itemPtr->image); if (itemPtr->height < itemPtr->labelHeight) { itemPtr->height = itemPtr->labelHeight; } } else if (itemPtr->label != emptyString) { unsigned int w, h; Blt_GetTextExtents(itemPtr->stylePtr->labelFont, 0, itemPtr->label, -1, &w, &h); itemPtr->labelWidth = w; itemPtr->labelHeight = h; if (itemPtr->height < itemPtr->labelHeight) { itemPtr->height = itemPtr->labelHeight; } } if (itemPtr->labelWidth > 0) { itemPtr->width += itemPtr->labelWidth + ITEM_IPAD; } } else { if (itemPtr->flags & (ITEM_RADIOBUTTON | ITEM_CHECKBUTTON)) { Blt_FontMetrics fm; size_t reqSize; Blt_GetFontMetrics(itemPtr->stylePtr->labelFont, &fm); itemPtr->leftIndWidth = itemPtr->leftIndHeight = (fm.linespace) + 4 * ITEM_YPAD; #ifdef notdef itemPtr->leftIndWidth = ITEM_L_IND_WIDTH; itemPtr->leftIndHeight = ITEM_L_IND_HEIGHT; #endif reqSize = itemPtr->stylePtr->reqIndWidth; if (reqSize == 0) { reqSize = (itemPtr->flags & ITEM_RADIOBUTTON) ? comboPtr->radioButtonReqSize : comboPtr->checkButtonReqSize; } if (reqSize > 0) { itemPtr->leftIndWidth = itemPtr->leftIndHeight = reqSize + 2*ITEM_YPAD; } if (itemPtr->height < itemPtr->leftIndHeight) { itemPtr->height = itemPtr->leftIndHeight; } itemPtr->width += itemPtr->leftIndWidth + 2 * ITEM_IPAD; } if (itemPtr->icon != NULL) { itemPtr->iconWidth = IconWidth(itemPtr->icon); itemPtr->iconHeight = IconHeight(itemPtr->icon); if (itemPtr->height < IconHeight(itemPtr->icon)) { itemPtr->height = IconHeight(itemPtr->icon); } itemPtr->width += itemPtr->iconWidth + ITEM_IPAD; } if (itemPtr->image != NULL) { itemPtr->labelWidth = IconWidth(itemPtr->image); itemPtr->labelHeight = IconHeight(itemPtr->image); if (itemPtr->height < itemPtr->labelHeight) { itemPtr->height = itemPtr->labelHeight; } } else if (itemPtr->label != emptyString) { unsigned int w, h; Blt_GetTextExtents(itemPtr->stylePtr->labelFont, 0, itemPtr->label, -1, &w, &h); itemPtr->labelWidth = w; itemPtr->labelHeight = h; if (itemPtr->height < itemPtr->labelHeight) { itemPtr->height = itemPtr->labelHeight; } } if (itemPtr->labelWidth > 0) { itemPtr->width += itemPtr->labelWidth + ITEM_IPAD; } if (itemPtr->flags & ITEM_CASCADE) { itemPtr->rightIndWidth = ITEM_R_IND_WIDTH; itemPtr->rightIndHeight = ITEM_R_IND_HEIGHT; } else if (itemPtr->accel != NULL) { unsigned int w, h; Blt_GetTextExtents(itemPtr->stylePtr->accelFont, 0, itemPtr->accel, -1, &w, &h); itemPtr->rightIndWidth = w; itemPtr->rightIndHeight = h; } if (itemPtr->height < itemPtr->rightIndHeight) { itemPtr->height = itemPtr->rightIndHeight; } } itemPtr->width += 2 * itemPtr->stylePtr->borderWidth; itemPtr->height += 2 * (ITEM_XPAD + itemPtr->stylePtr->borderWidth); #ifdef notdef fprintf(stderr, "%s= w=%d,h=%d leftInd w=%d,h=%d icon w=%d,h=%d label w=%d,h=%d rightInd w=%d,h=%d\n", itemPtr->label, itemPtr->width, itemPtr->height, itemPtr->leftIndWidth, itemPtr->leftIndHeight, itemPtr->iconWidth, itemPtr->iconHeight, itemPtr->labelWidth, itemPtr->labelHeight, itemPtr->rightIndWidth, itemPtr->rightIndHeight); #endif } /* *--------------------------------------------------------------------------- * * SearchForItem -- * * Performs a binary search for the item at the given y-offset in world * coordinates. The range of items is specified by menu indices (high * and low). The item must be (visible) in the viewport. * * Results: * Returns 0 if no item is found, other the index of the item (menu * indices start from 1). * *--------------------------------------------------------------------------- */ static Item * SearchForItem(ComboMenu *comboPtr, Item *firstPtr, Item *lastPtr, int yOffset) { Blt_ChainLink first, last, link, next; first = (firstPtr == NULL) ? Blt_Chain_FirstLink(comboPtr->chain): firstPtr->link; last = (lastPtr == NULL) ? Blt_Chain_LastLink(comboPtr->chain) : lastPtr->link; for (link = first; link != NULL; link = next) { Item *itemPtr; next = Blt_Chain_NextLink(link); itemPtr = Blt_Chain_GetValue(link); if ((yOffset >= itemPtr->yWorld) && (yOffset < (itemPtr->yWorld + itemPtr->height))) { return itemPtr; } if (link == last) { break; } } return NULL; } static void ComputeVisibleItems(ComboMenu *comboPtr) { Item *itemPtr; int cavityWidth, cavityHeight; if (Blt_Chain_GetLength(comboPtr->chain) == 0) { comboPtr->firstPtr = comboPtr->lastPtr = NULL; return; } cavityWidth = Tk_Width(comboPtr->tkwin); cavityHeight = Tk_Height(comboPtr->tkwin); comboPtr->xScrollbarHeight = comboPtr->yScrollbarWidth = 0; if ((comboPtr->xScrollbar != NULL) && (comboPtr->worldWidth > cavityWidth)){ comboPtr->xScrollbarHeight = Tk_ReqHeight(comboPtr->xScrollbar); if (comboPtr->xScrollbarHeight > MAXSCROLLBARTHICKNESS) { comboPtr->xScrollbarHeight = MAXSCROLLBARTHICKNESS; } cavityHeight -= comboPtr->xScrollbarHeight; } if ((comboPtr->yScrollbar != NULL) && (comboPtr->worldHeight>cavityHeight)){ comboPtr->yScrollbarWidth = Tk_ReqWidth(comboPtr->yScrollbar); if (comboPtr->yScrollbarWidth > MAXSCROLLBARTHICKNESS) { comboPtr->yScrollbarWidth = MAXSCROLLBARTHICKNESS; } cavityWidth -= comboPtr->yScrollbarWidth; } if ((comboPtr->xScrollbar != NULL) && (comboPtr->xScrollbarHeight == 0) && (comboPtr->worldWidth > cavityWidth)) { comboPtr->xScrollbarHeight = Tk_ReqHeight(comboPtr->xScrollbar); if (comboPtr->xScrollbarHeight > MAXSCROLLBARTHICKNESS) { comboPtr->xScrollbarHeight = MAXSCROLLBARTHICKNESS; } cavityHeight -= comboPtr->xScrollbarHeight; } if ((comboPtr->yScrollbar != NULL) && (comboPtr->yScrollbarWidth == 0) && (comboPtr->worldHeight > cavityHeight)) { comboPtr->yScrollbarWidth = Tk_ReqWidth(comboPtr->yScrollbar); if (comboPtr->yScrollbarWidth > MAXSCROLLBARTHICKNESS) { comboPtr->yScrollbarWidth = MAXSCROLLBARTHICKNESS; } cavityWidth -= comboPtr->yScrollbarWidth; } comboPtr->width = cavityWidth; comboPtr->height = cavityHeight; itemPtr = SearchForItem(comboPtr, NULL, NULL, comboPtr->yOffset); if (itemPtr == NULL) { Blt_ChainLink link; link = Blt_Chain_LastLink(comboPtr->chain); comboPtr->firstPtr = comboPtr->lastPtr = Blt_Chain_GetValue(link); return; } comboPtr->firstPtr = itemPtr; itemPtr = SearchForItem(comboPtr, comboPtr->firstPtr, NULL, comboPtr->yOffset + VPORTHEIGHT(comboPtr)); if (itemPtr == NULL) { Blt_ChainLink link; link = Blt_Chain_LastLink(comboPtr->chain); comboPtr->lastPtr = Blt_Chain_GetValue(link); return; } comboPtr->lastPtr = itemPtr; } /* *--------------------------------------------------------------------------- * * NearestItem -- * * Find the item closest to the x-y screen coordinate given. The item * must be (visible) in the viewport. * * Results: * Returns the closest item. If selectOne is set, then always returns an * item (unless the menu is empty). Otherwise, NULL is returned is the * pointer is not over an item. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Item * NearestItem(ComboMenu *comboPtr, int x, int y, int selectOne) { Item *itemPtr; if (comboPtr->firstPtr == NULL) { return NULL; /* No visible entries. */ } if ((x < 0) || (x >= Tk_Width(comboPtr->tkwin)) || (y < 0) || (y >= Tk_Height(comboPtr->tkwin))) { return NULL; /* Screen coordinates are outside of * menu. */ } /* * Item positions are saved in world coordinates. Convert the text point * screen y-coordinate to a world coordinate. */ itemPtr = SearchForItem(comboPtr, comboPtr->firstPtr, comboPtr->lastPtr, WORLDY(comboPtr, y)); if (itemPtr == NULL) { if (!selectOne) { return NULL; } if (y < comboPtr->borderWidth) { return FirstItem(comboPtr); } return LastItem(comboPtr); } return itemPtr; } static void ComputeCascadeMenuCoords(ComboMenu *comboPtr, Item *itemPtr, Tk_Window menuWin, int *xPtr, int *yPtr) { int rootX, rootY, x, y; int screenWidth, screenHeight; x = Tk_Width(comboPtr->tkwin); y = SCREENY(comboPtr, itemPtr->yWorld); Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); if (rootX < 0) { rootX = 0; } if (rootY < 0) { rootY = 0; } x += rootX, y += rootY; if ((y + Tk_ReqHeight(menuWin)) > screenHeight) { /* If we go offscreen on the bottom, raised the menu. */ y = screenHeight - Tk_ReqHeight(menuWin) - 10; if (y < 0) { y = 0; } } if ((x + Tk_ReqWidth(menuWin)) > screenWidth) { /* If we go offscreen on the bottom, try the menu on the other side. */ x = rootX - Tk_ReqWidth(menuWin); if (x < 0) { x = 0; } } *xPtr = x; *yPtr = y; } /* *--------------------------------------------------------------------------- * * UnpostCascade -- * * This procedure arranges for the currently active item's cascade menu * to be unposted (i.e. the submenu is unmapped). Only the active item * can have it's submenu unposted. * * Results: * A standard TCL return result. Errors may occur in the TCL commands * generated to unpost submenus. * * Side effects: * The currently active item's submenu is unposted. * *--------------------------------------------------------------------------- */ static int UnpostCascade( Tcl_Interp *interp, /* Used for invoking "unpost" commands * and reporting errors. */ ComboMenu *comboPtr) /* Information about the menu. */ { Item *itemPtr = comboPtr->postedPtr; char *menuName; Tk_Window menuWin; if ((itemPtr == NULL) || (itemPtr->menuObjPtr == NULL)) { return TCL_OK; /* No item currenly posted or no menu * designated for cascade item. */ } comboPtr->postedPtr = NULL; assert((itemPtr != NULL) && (itemPtr->flags & ITEM_CASCADE)); menuName = Tcl_GetString(itemPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { if (interp != NULL) { Tcl_AppendResult(interp, "can't unpost \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); } return TCL_ERROR; } Blt_UnmapToplevelWindow(menuWin); /* * Note: when unposting a submenu, we have to redraw the entire * parent menu. This is because of a combination of the following * things: * (a) the submenu partially overlaps the parent. * (b) the submenu specifies "save under", which causes the X * server to make a copy of the information under it when it * is posted. When the submenu is unposted, the X server * copies this data back and doesn't generate any Expose * events for the parent. * (c) the parent may have redisplayed itself after the submenu * was posted, in which case the saved information is no * longer correct. * The simplest solution is just force a complete redisplay of * the parent. */ EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostCascade -- * * This procedure arranges for the currently active item's cascade menu * to be posted. Only the active item can have it's submenu posted. * * Results: * A standard TCL return result. Errors may occur in the TCL commands * generated to post submenus. * * Side effects: * The new submenu is posted. * *--------------------------------------------------------------------------- */ static int PostCascade( Tcl_Interp *interp, /* Used for invoking "post" command * and reporting errors. */ ComboMenu *comboPtr, /* Information about the menu. */ Item *itemPtr) /* Cascade item */ { char *menuName; Tk_Window menuWin; assert((itemPtr != NULL) && (itemPtr->flags & ITEM_CASCADE)); if (itemPtr->menuObjPtr == NULL) { return TCL_OK; /* No menu was designated for this * cascade item. */ } if (comboPtr->postedPtr == itemPtr) { #ifdef notdef fprintf(stderr, "postcascade: %s is already posted\n", Tcl_GetString(itemPtr->menuObjPtr)); #endif return TCL_OK; /* Item is already posted. */ } menuName = Tcl_GetString(itemPtr->menuObjPtr); menuWin = Tk_NameToWindow(interp, menuName, comboPtr->tkwin); if (menuWin == NULL) { return TCL_ERROR; } if (Tk_Parent(menuWin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "can't post \"", Tk_PathName(menuWin), "\": it isn't a descendant of ", Tk_PathName(comboPtr->tkwin), (char *)NULL); return TCL_ERROR; } if (Tk_IsMapped(comboPtr->tkwin)) { Tcl_Obj *objv[4]; int result, x, y; /* * Position the cascade with its upper left corner slightly below and * to the left of the upper right corner of the menu entry (this is an * attempt to match Motif behavior). * * The menu has to redrawn so that the entry can change relief. */ ComputeCascadeMenuCoords(comboPtr, itemPtr, menuWin, &x, &y); objv[0] = itemPtr->menuObjPtr; objv[1] = Tcl_NewStringObj("post", 4); objv[2] = Tcl_NewIntObj(x); objv[3] = Tcl_NewIntObj(y); result = Blt_GlobalEvalObjv(interp, 4, objv); if (result != TCL_OK) { return result; } EventuallyRedrawItem(itemPtr); } comboPtr->postedPtr = itemPtr; return TCL_OK; } static void ComputeComboGeometry(ComboMenu *comboPtr) { int xWorld, yWorld; Blt_ChainLink link; int w, h; int reqWidth, reqHeight; /* * Step 1. Collect the maximum widths of the items in their individual * columns. */ comboPtr->worldHeight = 0; comboPtr->width = comboPtr->height = 0; comboPtr->leftIndWidth = comboPtr->rightIndWidth = 0; comboPtr->iconWidth = comboPtr->labelWidth = 0; xWorld = yWorld = 0; for (link = Blt_Chain_FirstLink(comboPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); ComputeItemGeometry(comboPtr, itemPtr); if (itemPtr->leftIndWidth > comboPtr->leftIndWidth) { comboPtr->leftIndWidth = itemPtr->leftIndWidth; } if (itemPtr->iconWidth > comboPtr->iconWidth) { comboPtr->iconWidth = itemPtr->iconWidth; } if (itemPtr->labelWidth > comboPtr->labelWidth) { comboPtr->labelWidth = itemPtr->labelWidth; } if (itemPtr->rightIndWidth > comboPtr->rightIndWidth) { comboPtr->rightIndWidth = itemPtr->rightIndWidth; } comboPtr->worldHeight += itemPtr->height; itemPtr->xWorld = xWorld, itemPtr->yWorld = yWorld; yWorld += itemPtr->height; } comboPtr->worldWidth = comboPtr->leftIndWidth + comboPtr->iconWidth + comboPtr->labelWidth + comboPtr->rightIndWidth; if (comboPtr->leftIndWidth > 0) { comboPtr->worldWidth += ITEM_IPAD; } if (comboPtr->iconWidth > 0) { comboPtr->worldWidth += ITEM_IPAD; } if (comboPtr->labelWidth > 0) { comboPtr->worldWidth += ITEM_IPAD; } if (comboPtr->rightIndWidth > 0) { comboPtr->worldWidth += 4 * ITEM_IPAD; } comboPtr->worldWidth += ITEM_IPAD; comboPtr->xScrollbarHeight = comboPtr->yScrollbarWidth = 0; /* Figure out the requested size of the widget. This will also tell us if * we need scrollbars. */ reqWidth = comboPtr->worldWidth + 2 * comboPtr->borderWidth; reqHeight = comboPtr->worldHeight + 2 * comboPtr->borderWidth; w = GetBoundedWidth(comboPtr, reqWidth); h = GetBoundedHeight(comboPtr, reqHeight); if ((reqWidth > w) && (comboPtr->xScrollbar != NULL)) { comboPtr->xScrollbarHeight = Tk_ReqHeight(comboPtr->xScrollbar); h = GetBoundedHeight(comboPtr, reqHeight + comboPtr->xScrollbarHeight); } if ((reqHeight > h) && (comboPtr->yScrollbar != NULL)) { comboPtr->yScrollbarWidth = Tk_ReqWidth(comboPtr->yScrollbar); w = GetBoundedWidth(comboPtr, reqWidth + comboPtr->yScrollbarWidth); } /* Save the computed width so that we only override the menu width if the * parent (combobutton/comboentry) width is greater than the normal size * of the menu. */ comboPtr->normalWidth = w; comboPtr->normalHeight = h; if (h < 20) { h = 20; } if (w < comboPtr->parentWidth) { w = comboPtr->parentWidth; } comboPtr->width = w; comboPtr->height = h; #ifdef notdef fprintf(stderr, "%s= w=%d leftInd w=%d icon w=%d label w=%d rightInd w=%d\n", Tk_PathName(comboPtr->tkwin), comboPtr->width, comboPtr->leftIndWidth, comboPtr->iconWidth, comboPtr->labelWidth, comboPtr->rightIndWidth); #endif if (w != Tk_ReqWidth(comboPtr->tkwin)) { comboPtr->xOffset = 0; } if (h != Tk_ReqHeight(comboPtr->tkwin)) { comboPtr->yOffset = 0; } if ((w != Tk_ReqWidth(comboPtr->tkwin)) || (h != Tk_ReqHeight(comboPtr->tkwin))) { Tk_GeometryRequest(comboPtr->tkwin, w, h); } comboPtr->flags |= SCROLL_PENDING | LAYOUT_PENDING; } static void DestroyStyle(Style *stylePtr) { ComboMenu *comboPtr; int i; stylePtr->refCount--; if (stylePtr->refCount > 0) { return; } comboPtr = stylePtr->comboPtr; iconOption.clientData = comboPtr; Blt_FreeOptions(styleConfigSpecs, (char *)stylePtr, comboPtr->display, 0); if (stylePtr->labelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelActiveGC); } if (stylePtr->labelDisabledGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelDisabledGC); } if (stylePtr->labelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelNormalGC); } if (stylePtr->accelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelActiveGC); } if (stylePtr->accelDisabledGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelDisabledGC); } if (stylePtr->accelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelNormalGC); } if (stylePtr->hPtr != NULL) { Blt_DeleteHashEntry(&stylePtr->comboPtr->styleTable, stylePtr->hPtr); } for (i = 0; i < 3; i++) { if (stylePtr->radiobutton[i] != NULL) { Blt_FreePicture(stylePtr->radiobutton[i]); } if (stylePtr->checkbutton[i] != NULL) { Blt_FreePicture(stylePtr->checkbutton[i]); } } if (stylePtr != &stylePtr->comboPtr->defStyle) { Blt_Free(stylePtr); } } static Style * AddDefaultStyle(Tcl_Interp *interp, ComboMenu *comboPtr) { Blt_HashEntry *hPtr; int isNew; Style *stylePtr; hPtr = Blt_CreateHashEntry(&comboPtr->styleTable, "default", &isNew); if (!isNew) { Tcl_AppendResult(interp, "combomenu style \"", "default", "\" already exists.", (char *)NULL); return NULL; } stylePtr = &comboPtr->defStyle; assert(stylePtr); stylePtr->refCount = 1; stylePtr->name = Blt_GetHashKey(&comboPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->comboPtr = comboPtr; stylePtr->borderWidth = 0; stylePtr->activeRelief = TK_RELIEF_FLAT; Blt_SetHashValue(hPtr, stylePtr); return TCL_OK; } static void DestroyStyles(ComboMenu *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&comboPtr->styleTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Style *stylePtr; stylePtr = Blt_GetHashValue(hPtr); stylePtr->hPtr = NULL; stylePtr->refCount = 0; DestroyStyle(stylePtr); } Blt_DeleteHashTable(&comboPtr->styleTable); } /* *--------------------------------------------------------------------------- * * GetStyleFromObj -- * * Gets the style associated with the given name. * *--------------------------------------------------------------------------- */ static int GetStyleFromObj(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, Style **stylePtrPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->styleTable, Tcl_GetString(objPtr)); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find style \"", Tcl_GetString(objPtr), "\" in combomenu \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *stylePtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetTag -- * * Associates a tag with a given row. Individual row tags are * stored in hash tables keyed by the tag name. Each table is in * turn stored in a hash table keyed by the row location. * * Results: * None. * * Side Effects: * A tag is stored for a particular row. * *--------------------------------------------------------------------------- */ static int SetTag(Tcl_Interp *interp, Item *itemPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; ComboMenu *comboPtr; int isNew; long dummy; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Don't need to create reserved * tags. */ } if (tagName[0] == '\0') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be empty.", (char *)NULL); } return TCL_ERROR; } if (tagName[0] == '-') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't start with a '-'.", (char *)NULL); } return TCL_ERROR; } if (Tcl_GetLong(NULL, (char *)tagName, &dummy) == TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be a number.", (char *)NULL); } return TCL_ERROR; } comboPtr = itemPtr->comboPtr; hPtr = Blt_CreateHashEntry(&comboPtr->tagTable, tagName, &isNew); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't add tag \"", tagName, "\": out of memory", (char *)NULL); } return TCL_ERROR; } if (isNew) { tagTablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tagTablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tagTablePtr); } else { tagTablePtr = Blt_GetHashValue(hPtr); } hPtr = Blt_CreateHashEntry(tagTablePtr, (char *)itemPtr->index, &isNew); if (isNew) { Blt_SetHashValue(hPtr, itemPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetTagTable -- * * Returns the hash table containing row indices for a tag. * * Results: * Returns a pointer to the hash table containing indices for the * given tag. If the row has no tags, then NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_HashTable * GetTagTable(ComboMenu *comboPtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->tagTable, tagName); if (hPtr == NULL) { return NULL; /* No tag by that name. */ } return Blt_GetHashValue(hPtr); } static void UnmanageScrollbar(ComboMenu *comboPtr, Tk_Window scrollbar) { if (scrollbar != NULL) { Tk_DeleteEventHandler(scrollbar, StructureNotifyMask, ScrollbarEventProc, comboPtr); Tk_ManageGeometry(scrollbar, (Tk_GeomMgr *)NULL, comboPtr); if (Tk_IsMapped(scrollbar)) { Tk_UnmapWindow(scrollbar); } } } static void ManageScrollbar(ComboMenu *comboPtr, Tk_Window scrollbar) { if (scrollbar != NULL) { Tk_CreateEventHandler(scrollbar, StructureNotifyMask, ScrollbarEventProc, comboPtr); Tk_ManageGeometry(scrollbar, &comboMgrInfo, comboPtr); } } /* *--------------------------------------------------------------------------- * * InstallScrollbar -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void InstallScrollbar( Tcl_Interp *interp, /* Interpreter to send results back * to */ ComboMenu *comboPtr, Tcl_Obj *objPtr, /* String representing scrollbar * window. */ Tk_Window *tkwinPtr) { Tk_Window tkwin; if (objPtr == NULL) { *tkwinPtr = NULL; return; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objPtr), comboPtr->tkwin); if (tkwin == NULL) { Tcl_BackgroundError(interp); return; } if (Tk_Parent(tkwin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "scrollbar \"", Tk_PathName(tkwin), "\" must be a child of combomenu.", (char *)NULL); Tcl_BackgroundError(interp); return; } ManageScrollbar(comboPtr, tkwin); *tkwinPtr = tkwin; return; } static void InstallXScrollbar(ClientData clientData) { ComboMenu *comboPtr = clientData; comboPtr->flags &= ~INSTALL_XSCROLLBAR; InstallScrollbar(comboPtr->interp, comboPtr, comboPtr->xScrollbarObjPtr, &comboPtr->xScrollbar); } static void InstallYScrollbar(ClientData clientData) { ComboMenu *comboPtr = clientData; comboPtr->flags &= ~INSTALL_YSCROLLBAR; InstallScrollbar(comboPtr->interp, comboPtr, comboPtr->yScrollbarObjPtr, &comboPtr->yScrollbar); } static int GetIconFromObj(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, Icon *iconPtr) { Blt_HashEntry *hPtr; struct _Icon *iPtr; int isNew; const char *iconName; iconName = Tcl_GetString(objPtr); if (iconName[0] == '\0') { *iconPtr = NULL; return TCL_OK; } hPtr = Blt_CreateHashEntry(&comboPtr->iconTable, iconName, &isNew); if (isNew) { Tk_Image tkImage; int w, h; tkImage = Tk_GetImage(interp, comboPtr->tkwin, (char *)iconName, IconChangedProc, comboPtr); if (tkImage == NULL) { Blt_DeleteHashEntry(&comboPtr->iconTable, hPtr); return TCL_ERROR; } Tk_SizeOfImage(tkImage, &w, &h); iPtr = Blt_AssertMalloc(sizeof(struct _Icon )); iPtr->tkImage = tkImage; iPtr->hPtr = hPtr; iPtr->refCount = 1; iPtr->width = w; iPtr->height = h; Blt_SetHashValue(hPtr, iPtr); } else { iPtr = Blt_GetHashValue(hPtr); iPtr->refCount++; } *iconPtr = iPtr; return TCL_OK; } static void FreeIcon(ComboMenu *comboPtr, struct _Icon *iPtr) { iPtr->refCount--; if (iPtr->refCount == 0) { Blt_DeleteHashEntry(&comboPtr->iconTable, iPtr->hPtr); Tk_FreeImage(iPtr->tkImage); Blt_Free(iPtr); } } static void DestroyIcons(ComboMenu *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&comboPtr->iconTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Icon icon; icon = Blt_GetHashValue(hPtr); Tk_FreeImage(IconImage(icon)); Blt_Free(icon); } Blt_DeleteHashTable(&comboPtr->iconTable); } static INLINE Item * FindItemByLabel(ComboMenu *comboPtr, const char *label) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->labelTable, label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; Blt_HashSearch iter; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FirstHashEntry(tablePtr, &iter); if (h2Ptr != NULL) { return Blt_GetHashValue(h2Ptr); } } return NULL; } static char * NewLabel(Item *itemPtr, const char *label) { Blt_HashEntry *hPtr, *h2Ptr; Blt_HashTable *tablePtr; int isNew; ComboMenu *comboPtr; comboPtr = itemPtr->comboPtr; hPtr = Blt_CreateHashEntry(&comboPtr->labelTable, label, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } h2Ptr = Blt_CreateHashEntry(tablePtr, (char *)itemPtr, &isNew); Blt_SetHashValue(h2Ptr, itemPtr); return Blt_GetHashKey(&comboPtr->labelTable, hPtr); } static void RemoveLabel(ComboMenu *comboPtr, Item *itemPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->labelTable, itemPtr->label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)itemPtr); if (h2Ptr != NULL) { itemPtr->label = emptyString; Blt_DeleteHashEntry(tablePtr, h2Ptr); if (tablePtr->numEntries == 0) { Blt_DeleteHashEntry(&comboPtr->labelTable, hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } } } } static void DestroyLabels(ComboMenu *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&comboPtr->labelTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&comboPtr->labelTable); } static void MoveItem(ComboMenu *comboPtr, Item *itemPtr, int dir, Item *wherePtr) { if (Blt_Chain_GetLength(comboPtr->chain) == 1) { return; /* Can't rearrange one item. */ } Blt_Chain_UnlinkLink(comboPtr->chain, itemPtr->link); switch(dir) { case 0: /* After */ Blt_Chain_LinkAfter(comboPtr->chain, itemPtr->link, wherePtr->link); break; case 1: /* At */ Blt_Chain_LinkAfter(comboPtr->chain, itemPtr->link, wherePtr->link); break; default: case 2: /* Before */ Blt_Chain_LinkBefore(comboPtr->chain, itemPtr->link, wherePtr->link); break; } { Blt_ChainLink link; long count; for (count = 0, link = Blt_Chain_FirstLink(comboPtr->chain); link != NULL; link = Blt_Chain_NextLink(link), count++) { itemPtr = Blt_Chain_GetValue(link); itemPtr->index = count; } } } static int GetTypeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *typePtr) { char *string; int length, flag; char c; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'r') && (length > 1) && (strncmp(string, "radiobutton", length) == 0)) { flag = ITEM_RADIOBUTTON; } else if ((c == 'c') && (length > 1) && (strncmp(string, "command", length) == 0)) { flag = ITEM_BUTTON; } else if ((c == 'c') && (length > 1) && (strncmp(string, "cascade", length) == 0)) { flag = ITEM_CASCADE; } else if ((c == 'c') && (length > 1) && (strncmp(string, "checkbutton", length) == 0)) { flag = ITEM_CHECKBUTTON; } else if ((c == 's') && (length > 1) && (strncmp(string, "separator", length) == 0)) { flag = ITEM_SEPARATOR; } else { if (interp != NULL) { Tcl_AppendResult(interp, "unknown item type \"", string, "\": should be command, checkbutton, cascade, ", "radiobutton, or separator.", (char *)NULL); } return TCL_ERROR; } *typePtr = flag; return TCL_OK; } static const char * NameOfType(unsigned int flags) { if (flags & ITEM_BUTTON) { return "command"; } if (flags & ITEM_RADIOBUTTON) { return "radiobutton"; } if (flags & ITEM_CHECKBUTTON) { return "checkbutton"; } if (flags & ITEM_CASCADE) { return "cascade"; } if (flags & ITEM_SEPARATOR) { return "separator"; } return "???"; } /* *--------------------------------------------------------------------------- * * NextTaggedItem -- * * Returns the next item derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows can be * found, then NULL is returned. * *--------------------------------------------------------------------------- */ static Item * NextTaggedItem(ItemIterator *iterPtr) { Item *itemPtr; switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } break; case ITER_TYPE: itemPtr = iterPtr->nextPtr; if (itemPtr == NULL) { return itemPtr; } while (itemPtr != iterPtr->endPtr) { if (itemPtr->flags & iterPtr->itemType) { break; } itemPtr = StepItem(itemPtr); } if (itemPtr == iterPtr->endPtr) { iterPtr->nextPtr = NULL; } else { iterPtr->nextPtr = StepItem(itemPtr); } return itemPtr; case ITER_ALL: if (iterPtr->link != NULL) { itemPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return itemPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(itemPtr->label, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return itemPtr; } } break; } default: break; } return NULL; } /* *--------------------------------------------------------------------------- * * FirstTaggedItem -- * * Returns the first item derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows can be * found, then -1 is returned. * *--------------------------------------------------------------------------- */ static Item * FirstTaggedItem(ItemIterator *iterPtr) { Item *itemPtr; switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } break; case ITER_ALL: if (iterPtr->link != NULL) { itemPtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return itemPtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; itemPtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(itemPtr->label, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return itemPtr; } } } break; case ITER_TYPE: itemPtr = iterPtr->startPtr; if (itemPtr == NULL) { return itemPtr; } while (itemPtr != iterPtr->endPtr) { if (itemPtr->flags & iterPtr->itemType) { break; } itemPtr = StepItem(itemPtr); } if (itemPtr == iterPtr->endPtr) { iterPtr->nextPtr = NULL; } else { iterPtr->nextPtr = StepItem(itemPtr); } return itemPtr; case ITER_SINGLE: itemPtr = iterPtr->startPtr; iterPtr->nextPtr = NextTaggedItem(iterPtr); return itemPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * GetItemFromObj -- * * Get the item associated the given index, tag, or label. This routine * is used when you want only one item. It's an error if more than one * item is specified (e.g. "all" tag). It's also an error if the tag is * empty (no items are currently tagged). * *--------------------------------------------------------------------------- */ static int GetItemFromObj(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, Item **itemPtrPtr) { ItemIterator iter; Item *firstPtr; if (GetItemIterator(interp, comboPtr, objPtr, &iter) != TCL_OK) { return TCL_ERROR; } firstPtr = FirstTaggedItem(&iter); if (firstPtr != NULL) { Item *nextPtr; nextPtr = NextTaggedItem(&iter); if (nextPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple items specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } *itemPtrPtr = firstPtr; return TCL_OK; } static int GetItemByIndex(Tcl_Interp *interp, ComboMenu *comboPtr, const char *string, int length, Item **itemPtrPtr) { Item *itemPtr; char c; long pos; itemPtr = NULL; c = string[0]; if ((isdigit(c)) && (TclGetLong(NULL, string, &pos) == TCL_OK)) { Blt_ChainLink link; link = Blt_Chain_GetNthLink(comboPtr->chain, pos); if (link != NULL) { itemPtr = Blt_Chain_GetValue(link); } if (itemPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item: bad index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } } else if ((c == 'n') && (strcmp(string, "next") == 0)) { itemPtr = NextItem(comboPtr->activePtr); if (itemPtr == NULL) { itemPtr = comboPtr->activePtr; } } else if ((c == 'p') && (strcmp(string, "previous") == 0)) { itemPtr = PrevItem(comboPtr->activePtr); if (itemPtr == NULL) { itemPtr = comboPtr->activePtr; } } else if ((c == 'e') && (strcmp(string, "end") == 0)) { itemPtr = LastItem(comboPtr); } else if ((c == 'f') && (strcmp(string, "first") == 0)) { itemPtr = FirstItem(comboPtr); } else if ((c == 'l') && (strcmp(string, "last") == 0)) { itemPtr = LastItem(comboPtr); } else if ((c == 'v') && (strcmp(string, "view.top") == 0)) { itemPtr = comboPtr->firstPtr; } else if ((c == 'v') && (strcmp(string, "view.bottom") == 0)) { itemPtr = comboPtr->lastPtr; } else if ((c == 'n') && (strcmp(string, "none") == 0)) { itemPtr = NULL; } else if ((c == 'a') && (strcmp(string, "active") == 0)) { itemPtr = comboPtr->activePtr; #ifdef notdef } else if ((c == 'f') && (strcmp(string, "focus") == 0)) { itemPtr = comboPtr->focusPtr; #endif } else if (c == '@') { int x, y; if (Blt_GetXY(comboPtr->interp, comboPtr->tkwin, string, &x, &y) != TCL_OK) { return TCL_ERROR; } itemPtr = NearestItem(comboPtr, x, y, TRUE); #ifdef notdef if ((itemPtr != NULL) && (itemPtr->flags & ITEM_DISABLED)) { itemPtr = NextItem(itemPtr); } #endif } else { return TCL_CONTINUE; } *itemPtrPtr = itemPtr; return TCL_OK; } static Item * GetItemByLabel(ComboMenu *comboPtr, const char *string) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->labelTable, string); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; Blt_HashSearch iter; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FirstHashEntry(tablePtr, &iter); if (h2Ptr != NULL) { return Blt_GetHashValue(h2Ptr); } } return NULL; } /* *--------------------------------------------------------------------------- * * GetItemIterator -- * * Converts a string representing a item index into an item pointer. The * index may be in one of the following forms: * * number Item at index in the list of items. * @x,y Item closest to the specified X-Y screen coordinates. * "active" Item where mouse pointer is located. * "posted" Item is the currently posted cascade item. * "next" Next item from the focus item. * "previous" Previous item from the focus item. * "end" Last item. * "none" No item. * * number Item at position in the list of items. * @x,y Item closest to the specified X-Y screen coordinates. * "active" Item mouse is located over. * "focus" Item is the widget's focus. * "select" Currently selected item. * "right" Next item from the focus item. * "left" Previous item from the focus item. * "up" Next item from the focus item. * "down" Previous item from the focus item. * "end" Last item in list. * "index:number" Item at index number in list of items. * "tag:string" Item(s) tagged by "string". * "label:pattern" Item(s) with label matching "pattern". * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via itemPtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetItemIterator(Tcl_Interp *interp, ComboMenu *comboPtr, Tcl_Obj *objPtr, ItemIterator *iterPtr) { Item *itemPtr, *startPtr, *endPtr; Blt_HashTable *tablePtr; char *string; char c; int nBytes; int length; int result; iterPtr->comboPtr = comboPtr; iterPtr->type = ITER_SINGLE; iterPtr->tagName = Tcl_GetStringFromObj(objPtr, &nBytes); iterPtr->nextPtr = NULL; iterPtr->startPtr = iterPtr->endPtr = NULL; if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } if (comboPtr->flags & SCROLL_PENDING) { ComputeVisibleItems(comboPtr); } string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; iterPtr->startPtr = iterPtr->endPtr = comboPtr->activePtr; startPtr = endPtr = itemPtr = NULL; if (c == '\0') { startPtr = endPtr = NULL; } iterPtr->type = ITER_SINGLE; result = GetItemByIndex(interp, comboPtr, string, length, &itemPtr); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_OK) { iterPtr->startPtr = iterPtr->endPtr = itemPtr; return TCL_OK; } if ((c == 'a') && (strcmp(iterPtr->tagName, "all") == 0)) { iterPtr->type = ITER_ALL; iterPtr->link = Blt_Chain_FirstLink(comboPtr->chain); } else if ((c == 'i') && (length > 6) && (strncmp(string, "index:", 6) == 0)) { if (GetItemByIndex(interp, comboPtr, string + 6, length - 6, &itemPtr) != TCL_OK) { return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = itemPtr; } else if ((c == 't') && (length > 4) && (strncmp(string, "tag:", 4) == 0)) { Blt_HashTable *tablePtr; tablePtr = GetTagTable(comboPtr, string + 4); if (tablePtr == NULL) { Tcl_AppendResult(interp, "can't find a tag \"", string + 5, "\" in \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } iterPtr->tagName = string + 4; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else if ((c == 'l') && (length > 6) && (strncmp(string, "label:", 6) == 0)) { iterPtr->link = Blt_Chain_FirstLink(comboPtr->chain); iterPtr->tagName = string + 6; iterPtr->type = ITER_PATTERN; } else if ((itemPtr = GetItemByLabel(comboPtr, string)) != NULL) { iterPtr->startPtr = iterPtr->endPtr = itemPtr; } else if ((tablePtr = GetTagTable(comboPtr, string)) != NULL) { iterPtr->tagName = string; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else { if (interp != NULL) { Tcl_AppendResult(interp, "can't find item index, label, or tag \"", string, "\" in \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } return TCL_OK; } static int ConfigureItem( Tcl_Interp *interp, Item *itemPtr, int objc, Tcl_Obj *const *objv, int flags) { ComboMenu *comboPtr; comboPtr = itemPtr->comboPtr; iconOption.clientData = comboPtr; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, itemConfigSpecs, objc, objv, (char *)itemPtr, flags) != TCL_OK) { return TCL_ERROR; } ComputeItemGeometry(comboPtr, itemPtr); return TCL_OK; } static int ConfigureStyle(Tcl_Interp *interp, Style *stylePtr, int objc, Tcl_Obj *const *objv, int flags) { ComboMenu *comboPtr = stylePtr->comboPtr; unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, styleConfigSpecs, objc, objv, (char *)stylePtr, flags) != TCL_OK) { return TCL_ERROR; } /* Normal label */ gcMask = GCForeground | GCFont | GCLineWidth; gcValues.line_width = 0; gcValues.foreground = stylePtr->labelNormalColor->pixel; gcValues.font = Blt_FontId(stylePtr->labelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->labelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelNormalGC); } stylePtr->labelNormalGC = newGC; /* Disabled label */ gcMask = GCForeground | GCFont; gcValues.foreground = stylePtr->labelDisabledColor->pixel; gcValues.font = Blt_FontId(stylePtr->labelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->labelDisabledGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelDisabledGC); } stylePtr->labelDisabledGC = newGC; /* Active label */ gcMask = GCForeground | GCFont; gcValues.foreground = stylePtr->labelActiveColor->pixel; gcValues.font = Blt_FontId(stylePtr->labelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->labelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelActiveGC); } stylePtr->labelActiveGC = newGC; /* Normal accelerator */ gcMask = GCForeground | GCFont; gcValues.foreground = stylePtr->accelNormalColor->pixel; gcValues.font = Blt_FontId(stylePtr->accelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->accelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelNormalGC); } stylePtr->accelNormalGC = newGC; /* Disabled accelerator */ gcMask = GCForeground | GCFont; gcValues.foreground = stylePtr->accelDisabledColor->pixel; gcValues.font = Blt_FontId(stylePtr->accelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->accelDisabledGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelDisabledGC); } stylePtr->accelDisabledGC = newGC; /* Active accelerator */ gcMask = GCForeground | GCFont; gcValues.foreground = stylePtr->accelActiveColor->pixel; gcValues.font = Blt_FontId(stylePtr->accelFont); newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->accelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->accelActiveGC); } stylePtr->accelActiveGC = newGC; #ifdef notdef if (itemPtr->flags & (ITEM_RADIOBUTTON | ITEM_CHECKBUTTON)) { itemPtr->leftIndWidth = ITEM_L_IND_WIDTH + 2 * ITEM_IPAD; itemPtr->leftIndHeight = ITEM_L_IND_HEIGHT; } #endif return TCL_OK; } static int ConfigureComboMenu(Tcl_Interp *interp, ComboMenu *comboPtr, int objc, Tcl_Obj *const *objv, int flags) { int updateNeeded; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, comboConfigSpecs, objc, objv, (char *)comboPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureStyle(interp, &comboPtr->defStyle, 0, NULL, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } updateNeeded = FALSE; /* Install the embedded scrollbars as needed. We defer installing the * scrollbars so the scrollbar widgets don't have to exist when they are * specified by the -xscrollbar and -yscrollbar options respectively. The * down-side is that errors found in the scrollbar name will be * backgrounded. */ if (Blt_ConfigModified(comboConfigSpecs, "-xscrollbar", (char *)NULL)) { if (comboPtr->xScrollbar != NULL) { UnmanageScrollbar(comboPtr, comboPtr->xScrollbar); comboPtr->xScrollbar = NULL; } if ((comboPtr->flags & INSTALL_XSCROLLBAR) == 0) { Tcl_DoWhenIdle(InstallXScrollbar, comboPtr); comboPtr->flags |= INSTALL_XSCROLLBAR; } updateNeeded = TRUE; } if (Blt_ConfigModified(comboConfigSpecs, "-yscrollbar", (char *)NULL)) { if (comboPtr->yScrollbar != NULL) { UnmanageScrollbar(comboPtr, comboPtr->yScrollbar); comboPtr->yScrollbar = NULL; } if ((comboPtr->flags & INSTALL_YSCROLLBAR) == 0) { Tcl_DoWhenIdle(InstallYScrollbar, comboPtr); comboPtr->flags |= INSTALL_YSCROLLBAR; } updateNeeded = TRUE; } if (updateNeeded) { if ((comboPtr->flags & UPDATE_PENDING) == 0) { Tcl_DoWhenIdle(ConfigureScrollbarsProc, comboPtr); comboPtr->flags |= UPDATE_PENDING; } } return TCL_OK; } /* Widget Callbacks */ /* *--------------------------------------------------------------------------- * * ComboMenuEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * comboentry widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ComboMenuEventProc(ClientData clientData, XEvent *eventPtr) { ComboMenu *comboPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(comboPtr); } } else if (eventPtr->type == UnmapNotify) { if (comboPtr->lastPtr != NULL) { UnpostCascade((Tcl_Interp *)NULL, comboPtr); EventuallyRedraw(comboPtr); } } else if (eventPtr->type == ConfigureNotify) { comboPtr->flags |= (SCROLL_PENDING | LAYOUT_PENDING); EventuallyRedraw(comboPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } if (eventPtr->type == FocusIn) { comboPtr->flags |= FOCUS; } else { comboPtr->flags &= ~FOCUS; } EventuallyRedraw(comboPtr); } else if (eventPtr->type == DestroyNotify) { if (comboPtr->tkwin != NULL) { comboPtr->tkwin = NULL; } if (comboPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayComboMenu, comboPtr); } Tcl_EventuallyFree(comboPtr, DestroyComboMenu); } } /* *--------------------------------------------------------------------------- * * ScrollbarEventProc -- * * This procedure is invoked by the Tk event handler when StructureNotify * events occur in a scrollbar managed by the widget. * * Results: * None. * *--------------------------------------------------------------------------- */ static void ScrollbarEventProc( ClientData clientData, /* Pointer to Entry structure for * widget referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { ComboMenu *comboPtr = clientData; if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(comboPtr); } else if (eventPtr->type == DestroyNotify) { if (eventPtr->xany.window == Tk_WindowId(comboPtr->yScrollbar)) { comboPtr->yScrollbar = NULL; } else if (eventPtr->xany.window == Tk_WindowId(comboPtr->xScrollbar)) { comboPtr->xScrollbar = NULL; } comboPtr->flags |= LAYOUT_PENDING;; EventuallyRedraw(comboPtr); } } /* *--------------------------------------------------------------------------- * * ScrollbarCustodyProc -- * * This procedure is invoked when a scrollbar has been stolen by another * geometry manager. * * Results: * None. * * Side effects: * Arranges for the combomenu to have its layout re-arranged at the next * idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollbarCustodyProc( ClientData clientData, /* Information about the combomenu. */ Tk_Window tkwin) /* Scrollbar stolen by another geometry * manager. */ { ComboMenu *comboPtr = (ComboMenu *)clientData; if (tkwin == comboPtr->yScrollbar) { comboPtr->yScrollbar = NULL; comboPtr->yScrollbarWidth = 0; } else if (tkwin == comboPtr->xScrollbar) { comboPtr->xScrollbar = NULL; comboPtr->xScrollbarHeight = 0; } else { return; } Tk_UnmaintainGeometry(tkwin, comboPtr->tkwin); comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ScrollbarGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for scrollbars managed * by the combomenu. * * Results: * None. * * Side effects: * Arranges for the combomenu to have its layout re-computed and * re-arranged at the next idle point. * * -------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollbarGeometryProc( ClientData clientData, /* ComboMenu widget record. */ Tk_Window tkwin) /* Scrollbar whose geometry has * changed. */ { ComboMenu *comboPtr = (ComboMenu *)clientData; comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ItemVarTraceProc -- * * This procedure is invoked when someone changes the state variable * associated with a radiobutton or checkbutton entry. The entry's * selected state is set to match the value of the variable. * * Results: * NULL is always returned. * * Side effects: * The combobox entry may become selected or deselected. * *--------------------------------------------------------------------------- */ static char * ItemVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { Item *itemPtr = clientData; Tcl_Obj *objPtr; int bool; assert(itemPtr->variableObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { itemPtr->flags &= ~ITEM_SELECTED; if (flags & TCL_TRACE_DESTROYED) { char *varName; varName = Tcl_GetString(itemPtr->variableObjPtr); Tcl_TraceVar(interp, varName, VAR_FLAGS, ItemVarTraceProc, clientData); } goto done; } if ((itemPtr->flags & (ITEM_RADIOBUTTON|ITEM_CHECKBUTTON|ITEM_BUTTON))==0) { return NULL; /* Not a radiobutton or checkbutton. */ } /* * Use the value of the variable to update the selected status of the * item. */ objPtr = Tcl_ObjGetVar2(interp, itemPtr->variableObjPtr, NULL, TCL_GLOBAL_ONLY); if (objPtr == NULL) { return NULL; /* Can't get value of variable. */ } bool = 0; if (itemPtr->flags & (ITEM_BUTTON|ITEM_RADIOBUTTON)) { const char *string; if (itemPtr->valueObjPtr == NULL) { string = itemPtr->label; } else { string = Tcl_GetString(itemPtr->valueObjPtr); } if (string == NULL) { return NULL; } bool = (strcmp(string, Tcl_GetString(objPtr)) == 0); } else if (itemPtr->flags & ITEM_CHECKBUTTON) { if (itemPtr->onValueObjPtr == NULL) { if (Tcl_GetBooleanFromObj(NULL, objPtr, &bool) != TCL_OK) { return NULL; } } else { bool = (strcmp(Tcl_GetString(objPtr), Tcl_GetString(itemPtr->onValueObjPtr)) == 0); } } if (bool) { ComboMenu *comboPtr; if (itemPtr->flags & ITEM_SELECTED) { return NULL; /* Already selected. */ } comboPtr = itemPtr->comboPtr; if ((comboPtr->textVarObjPtr != NULL) && (itemPtr->label != emptyString)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(itemPtr->label, -1); if (Tcl_ObjSetVar2(interp, comboPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } itemPtr->flags |= ITEM_SELECTED; } else if (itemPtr->flags & ITEM_SELECTED) { itemPtr->flags &= ~ITEM_SELECTED; } else { return NULL; /* Already deselected. */ } done: EventuallyRedraw(itemPtr->comboPtr); return NULL; /* Done. */ } /*ARGSUSED*/ static void FreeTraceVarProc(ClientData clientData, Display *display, char *widgRec, int offset) { Item *itemPtr = (Item *)(widgRec); if (itemPtr->variableObjPtr != NULL) { const char *varName; ComboMenu *comboPtr; comboPtr = itemPtr->comboPtr; varName = Tcl_GetString(itemPtr->variableObjPtr); Tcl_UntraceVar(comboPtr->interp, varName, VAR_FLAGS, ItemVarTraceProc, itemPtr); Tcl_DecrRefCount(itemPtr->variableObjPtr); itemPtr->variableObjPtr = NULL; } } /* *--------------------------------------------------------------------------- * ObjToTraceVarProc -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTraceVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); const char *varName; /* Remove the current trace on the variable. */ if (itemPtr->variableObjPtr != NULL) { varName = Tcl_GetString(itemPtr->variableObjPtr); Tcl_UntraceVar(interp, varName, VAR_FLAGS, ItemVarTraceProc, itemPtr); Tcl_DecrRefCount(itemPtr->variableObjPtr); itemPtr->variableObjPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } itemPtr->variableObjPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, VAR_FLAGS, ItemVarTraceProc, itemPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceVarToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TraceVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); Tcl_Obj *objPtr; if (itemPtr->variableObjPtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = itemPtr->variableObjPtr; } return objPtr; } /*ARGSUSED*/ static void FreeStyleProc(ClientData clientData, Display *display, char *widgRec, int offset) { Style *stylePtr = *(Style **)(widgRec + offset); if ((stylePtr != NULL) && (stylePtr != &stylePtr->comboPtr->defStyle)) { DestroyStyle(stylePtr); } } /* *--------------------------------------------------------------------------- * * ObjToStyleProc -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyleProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboMenu *comboPtr; Item *itemPtr = (Item *)widgRec; Style **stylePtrPtr = (Style **)(widgRec + offset); Style *stylePtr; char *string; string = Tcl_GetString(objPtr); comboPtr = itemPtr->comboPtr; if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { stylePtr = NULL; } else if (GetStyleFromObj(interp, comboPtr, objPtr, &stylePtr) != TCL_OK) { return TCL_ERROR; } /* Release the old style. */ if ((*stylePtrPtr != NULL) && (*stylePtrPtr != &comboPtr->defStyle)) { DestroyStyle(*stylePtrPtr); } stylePtr->refCount++; *stylePtrPtr = stylePtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StyleToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Style *stylePtr = *(Style **)(widgRec + offset); Tcl_Obj *objPtr; if (stylePtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(stylePtr->name, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToRestrictProc -- * * Convert the string representation of an item state into a flag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToRestrictProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "min") == 0) { flag = RESTRICT_MIN; } else if (strcmp(string, "max") == 0) { flag = RESTRICT_MAX; } else if (strcmp(string, "both") == 0) { flag = RESTRICT_MIN|RESTRICT_MAX; } else if (strcmp(string, "none") == 0) { flag = 0; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~(RESTRICT_MIN|RESTRICT_MAX); *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * RestrictToObjProc -- * * Return the string representation of the restrict flags. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * RestrictToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); int restrict; restrict = *flagsPtr & (RESTRICT_MIN|RESTRICT_MAX); switch (restrict) { case RESTRICT_MIN: return Tcl_NewStringObj("min", -1); case RESTRICT_MAX: return Tcl_NewStringObj("max", -1); case (RESTRICT_MIN|RESTRICT_MAX): return Tcl_NewStringObj("both", -1); case RESTRICT_NONE: return Tcl_NewStringObj("none", -1); } return NULL; } /* *--------------------------------------------------------------------------- * * ObjToStateProc -- * * Convert the string representation of an item state into a flag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStateProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); char *string; ComboMenu *comboPtr; int flag; string = Tcl_GetString(objPtr); if (strcmp(string, "disabled") == 0) { flag = ITEM_DISABLED; } else if (strcmp(string, "normal") == 0) { flag = ITEM_NORMAL; } else { Tcl_AppendResult(interp, "unknown state \"", string, "\": should be active, disabled, or normal.", (char *)NULL); return TCL_ERROR; } if (itemPtr->flags & flag) { return TCL_OK; /* State is already set to value. */ } comboPtr = itemPtr->comboPtr; if (comboPtr->activePtr != itemPtr) { ActivateItem(comboPtr, NULL); comboPtr->activePtr = NULL; } *flagsPtr &= ~ITEM_STATE_MASK; *flagsPtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StateToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StateToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int state = *(unsigned int *)(widgRec + offset); Tcl_Obj *objPtr; if (state & ITEM_NORMAL) { objPtr = Tcl_NewStringObj("normal", -1); } else if (state & ITEM_DISABLED) { objPtr = Tcl_NewStringObj("disabled", -1); } else { objPtr = Tcl_NewStringObj("???", -1); } return objPtr; } /*ARGSUSED*/ static void FreeTagsProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { ComboMenu *comboPtr; Item *itemPtr = (Item *)widgRec; comboPtr = itemPtr->comboPtr; ReleaseTags(comboPtr, itemPtr); } /* *--------------------------------------------------------------------------- * * ObjToTagsProc -- * * Convert the string representation of a list of tags. * * Results: * The return value is a standard TCL result. The tags are * save in the widget. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTagsProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboMenu *comboPtr; Item *itemPtr = (Item *)widgRec; int i; char *string; int objc; Tcl_Obj **objv; comboPtr = itemPtr->comboPtr; ReleaseTags(comboPtr, itemPtr); string = Tcl_GetString(objPtr); if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < objc; i++) { SetTag(interp, itemPtr, Tcl_GetString(objv[i])); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagsToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TagsToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Blt_HashEntry *hPtr; Blt_HashSearch iter; ComboMenu *comboPtr; Item *itemPtr = (Item *)widgRec; Tcl_Obj *listObjPtr; comboPtr = itemPtr->comboPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&comboPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tagTablePtr; Blt_HashEntry *h2Ptr; tagTablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tagTablePtr, (char *)itemPtr->index); if (h2Ptr != NULL) { Tcl_Obj *objPtr; const char *name; name = Tcl_GetHashKey(&comboPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { ComboMenu *comboPtr = clientData; comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ObjToIconProc -- * * Convert a image into a hashed icon. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ComboMenu *comboPtr = clientData; Icon *iconPtr = (Icon *)(widgRec + offset); Icon icon; if (GetIconFromObj(interp, comboPtr, objPtr, &icon) != TCL_OK) { return TCL_ERROR; } if (*iconPtr != NULL) { FreeIcon(comboPtr, *iconPtr); } *iconPtr = icon; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon icon = *(Icon *)(widgRec + offset); Tcl_Obj *objPtr; if (icon == NULL) { objPtr = Tcl_NewStringObj("", 0); } else { objPtr =Tcl_NewStringObj(Blt_Image_Name(IconImage(icon)), -1); } return objPtr; } /*ARGSUSED*/ static void FreeIconProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Icon *iconPtr = (Icon *)(widgRec + offset); if (*iconPtr != NULL) { ComboMenu *comboPtr = clientData; FreeIcon(comboPtr, *iconPtr); *iconPtr = NULL; } } /*ARGSUSED*/ static void FreeLabelProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Item *itemPtr = (Item *)widgRec; if (itemPtr->label != emptyString) { RemoveLabel(itemPtr->comboPtr, itemPtr); } } /* *--------------------------------------------------------------------------- * * ObjToLabelProc -- * * Save the label and add the item to the label hashtable. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLabelProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); char *string; if (itemPtr->label != emptyString) { RemoveLabel(itemPtr->comboPtr, itemPtr); } string = Tcl_GetString(objPtr); if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } itemPtr->label = NewLabel(itemPtr, string); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LabelToObjProc -- * * Return the label of the item. * * Results: * The label is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LabelToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Item *itemPtr = (Item *)(widgRec); Tcl_Obj *objPtr; if (itemPtr->label == emptyString) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(itemPtr->label, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToTypeProc -- * * Convert the string representation of an item into a value. * * Results: * A standard TCL result. The type pointer is written into the * widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTypeProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing type. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { unsigned int *typePtr = (unsigned int *)(widgRec + offset); int flag; if (GetTypeFromObj(interp, objPtr, &flag) != TCL_OK) { return TCL_ERROR; } *typePtr &= ~ITEM_TYPE_MASK; *typePtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeToObjProc -- * * Return the name of the type. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TypeToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { int type = *(int *)(widgRec + offset); return Tcl_NewStringObj(NameOfType(type), -1); } /* *--------------------------------------------------------------------------- * * TypeSwitch -- * * Convert a string representing an item type into its integer value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { unsigned int *typePtr = (unsigned int *)(record + offset); int flag; if (GetTypeFromObj(interp, objPtr, &flag) != TCL_OK) { return TCL_ERROR; } *typePtr &= ~ITEM_TYPE_MASK; *typePtr |= flag; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemSwitch -- * * Convert a string representing an item into its pointer. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ItemSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Item **itemPtrPtr = (Item **)(record + offset); ComboMenu *comboPtr = clientData; Item *itemPtr; if (GetItemFromObj(NULL, comboPtr, objPtr, &itemPtr) != TCL_OK) { return TCL_ERROR; } *itemPtrPtr = itemPtr; return TCL_OK; } /* Widget Operations */ /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm activate item * *--------------------------------------------------------------------------- */ static int ActivateOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(NULL, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (comboPtr->activePtr == itemPtr) { return TCL_OK; /* Item is already active. */ } ActivateItem(comboPtr, NULL); comboPtr->activePtr = NULL; if ((itemPtr != NULL) && ((itemPtr->flags & (ITEM_DISABLED|ITEM_SEPARATOR)) == 0)) { ActivateItem(comboPtr, itemPtr); comboPtr->activePtr = itemPtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Appends a new item to the combomenu. * * Results: * NULL is always returned. * * Side effects: * The combomenu entry may become selected or deselected. * * .cm add radiobutton -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int AddOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; itemPtr = NewItem(comboPtr); if (ConfigureItem(interp, itemPtr, objc - 2, objv + 2, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } EventuallyRedraw(comboPtr); Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * AddListOp -- * * Appends a list of items to the combomenu. * * Results: * A standard TCL result. * * Side effects: * New items are added to the combomenu. * * .cm add labelList -type radiobutton -text "fred" -tags "" * *--------------------------------------------------------------------------- */ static int AddListOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; int iobjc; Tcl_Obj **iobjv; Tcl_Obj *listObjPtr; if (Tcl_ListObjGetElements(interp, objv[2], &iobjc, &iobjv) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 0; i < iobjc; i++) { Tcl_Obj *objPtr; Item *itemPtr; itemPtr = NewItem(comboPtr); if (ConfigureItem(interp, itemPtr, objc - 3, objv + 3, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; } itemPtr->label = NewLabel(itemPtr, Tcl_GetString(iobjv[i])); objPtr = Tcl_NewLongObj(itemPtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } EventuallyRedraw(comboPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm configure ?option value?... * *--------------------------------------------------------------------------- */ static int ConfigureOp( ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; iconOption.clientData = comboPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, comboConfigSpecs, (char *)comboPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, comboConfigSpecs, (char *)comboPtr, objv[2], 0); } Tcl_Preserve(comboPtr); result = ConfigureComboMenu(interp, comboPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY); Tcl_Release(comboPtr); if (result == TCL_ERROR) { return TCL_ERROR; } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm cget option * *--------------------------------------------------------------------------- */ static int CgetOp( ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, comboConfigSpecs, (char *)comboPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm delete item... * *--------------------------------------------------------------------------- */ static int DeleteOp( ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { ItemIterator iter; Item *itemPtr, *nextPtr; if (GetItemIterator(interp, comboPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (itemPtr = FirstTaggedItem(&iter); itemPtr != NULL; itemPtr = nextPtr) { nextPtr = NextTaggedItem(&iter); DestroyItem(itemPtr); } } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExistsOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm exists item * *--------------------------------------------------------------------------- */ static int ExistsOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int bool; bool = FALSE; if (GetItemFromObj(NULL, comboPtr, objv[2], &itemPtr) == TCL_OK) { if (itemPtr != NULL) { bool = TRUE; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindOp -- * * Search for an item according to the string given. * * Results: * The index of the found item is returned. If no item is found * -1 is returned. * * .cm find string -from active -previous -underline -type separator * *--------------------------------------------------------------------------- */ static int FindOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { long index; FindSwitches switches; const char *pattern; /* Process switches */ pattern = Tcl_GetString(objv[2]); switches.mask = 0; switches.type = 0; itemSwitch.clientData = comboPtr; switches.fromPtr = comboPtr->activePtr; if (Blt_ParseSwitches(interp, findSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } index = -1; if (switches.mask & FIND_UNDERLINE) { Tcl_UniChar want; Item *itemPtr; itemPtr = switches.fromPtr; itemPtr = (itemPtr == NULL) ? FirstItem(comboPtr) : NextItem(itemPtr); want = Tcl_UniCharAtIndex(pattern, 0); want = Tcl_UniCharToLower(want); for (/*empty*/; itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->underline >= 0) { Tcl_UniChar have; have = Tcl_UniCharAtIndex(itemPtr->label, itemPtr->underline); have = Tcl_UniCharToLower(have); if (want == have) { index = itemPtr->index; break; } } } if (itemPtr == NULL) { for (itemPtr = FirstItem(comboPtr); itemPtr != NULL; itemPtr = NextItem(itemPtr)) { if (itemPtr->underline >= 0) { Tcl_UniChar have; have = Tcl_UniCharAtIndex(itemPtr->label, itemPtr->underline); have = Tcl_UniCharToLower(have); if (want == have) { index = itemPtr->index; break; } } if (itemPtr == comboPtr->activePtr) { break; } } } } else if (switches.mask & FIND_DECREASING) { Item *itemPtr; itemPtr = switches.fromPtr; itemPtr = (itemPtr == NULL) ? LastItem(comboPtr) : PrevItem(itemPtr); for (/*empty*/; itemPtr != NULL; itemPtr = PrevItem(itemPtr)) { int found; if ((switches.type > 0) && ((switches.type & itemPtr->flags)==0)) { continue; } if (switches.mask & FIND_GLOB) { found = Tcl_StringMatch(itemPtr->label, pattern); } else if (switches.mask & FIND_REGEXP) { found = Tcl_RegExpMatch(NULL, itemPtr->label, pattern); } else { found = (strcmp(itemPtr->label, pattern) == 0); } if (found) { index = itemPtr->index; break; } } } else { Blt_ChainLink link; Item *itemPtr; itemPtr = switches.fromPtr; itemPtr = (itemPtr == NULL) ? FirstItem(comboPtr) : NextItem(itemPtr); for (link = itemPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { int found; itemPtr = Blt_Chain_GetValue(link); if ((switches.type > 0) && ((switches.type & itemPtr->flags)==0)) { continue; } if (switches.search == FIND_GLOB) { found = Tcl_StringMatch(itemPtr->label, pattern); } else if (switches.search == FIND_REGEXP) { found = Tcl_RegExpMatch(NULL, itemPtr->label, pattern); } else { found = (strcmp(itemPtr->label, pattern) == 0); } if (found) { index = itemPtr->index; break; } } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm index item * *--------------------------------------------------------------------------- */ static int IndexOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, comboPtr, objv[2], &itemPtr) == TCL_OK) { if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm invoke item * *--------------------------------------------------------------------------- */ static int InvokeOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Item *itemPtr; if (GetItemFromObj(interp, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if ((itemPtr == NULL) || (itemPtr->flags & ITEM_DISABLED)) { return TCL_OK; /* Item is currently disabled. */ } result = TCL_OK; Tcl_Preserve(itemPtr); result = SelectItem(interp, comboPtr, itemPtr, -1); /* * We check nItems in addition to whether the item has a command because * that goes to zero if the combomenu is deleted (e.g., during command * evaluation). */ if ((Blt_Chain_GetLength(comboPtr->chain) > 0) && (result == TCL_OK) && (itemPtr->cmdObjPtr != NULL)) { Tcl_IncrRefCount(itemPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, itemPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(itemPtr->cmdObjPtr); } Tcl_Release(itemPtr); return result; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Inserts a new item into the combomenu at the given index. * * Results: * NULL is always returned. * * Side effects: * The combomenu gets a new item. * * .cm insert before 0 after 1 -text label * *--------------------------------------------------------------------------- */ static int InsertOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr, *wherePtr; int dir; static const char *dirs[] = { "after", "at", "before" , NULL}; if (Tcl_GetIndexFromObj(interp, objv[2], dirs, "key", 0, &dir) != TCL_OK) { return TCL_ERROR; } if (GetItemFromObj(interp, comboPtr, objv[3], &wherePtr) != TCL_OK) { return TCL_ERROR; } if (wherePtr == NULL) { Tcl_AppendResult(interp, "can't insert item: no index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; /* No item. */ } itemPtr = NewItem(comboPtr); if (ConfigureItem(interp, itemPtr, objc - 4, objv + 4, 0) != TCL_OK) { DestroyItem(itemPtr); return TCL_ERROR; /* Error configuring the entry. */ } MoveItem(comboPtr, itemPtr, dir, wherePtr); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemConfigureOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * * .cm item configure item ?option value?... * *--------------------------------------------------------------------------- */ static int ItemConfigureOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; ItemIterator iter; if (GetItemIterator(interp, comboPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = comboPtr; for (itemPtr = FirstTaggedItem(&iter); itemPtr != NULL; itemPtr = NextTaggedItem(&iter)) { int result; unsigned int flags; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, itemConfigSpecs, (char *)itemPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, itemConfigSpecs, (char *)itemPtr, objv[4], flags); } Tcl_Preserve(itemPtr); result = ConfigureItem(interp, itemPtr, objc - 4, objv + 4, flags); Tcl_Release(itemPtr); if (result == TCL_ERROR) { return TCL_ERROR; } } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ItemCgetOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * * .cm item cget item option * *--------------------------------------------------------------------------- */ static int ItemCgetOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, comboPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't retrieve item \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, itemConfigSpecs, (char *)itemPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * ItemOp -- * * This procedure handles item operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec itemOps[] = { {"cget", 2, ItemCgetOp, 5, 5, "item option",}, {"configure", 2, ItemConfigureOp, 4, 0, "item ?option value?...",}, }; static int nItemOps = sizeof(itemOps) / sizeof(Blt_OpSpec); static int ItemOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboMenuCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nItemOps, itemOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * .cm names pattern... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; int i; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (i = 2; i < objc; i++) { const char *pattern; Blt_ChainLink link; pattern = Tcl_GetString(objv[i]); for (link = Blt_Chain_FirstLink(comboPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Item *itemPtr; Tcl_Obj *objPtr; itemPtr = Blt_Chain_GetValue(link); if (Tcl_StringMatch(itemPtr->label, pattern)) { if (itemPtr->label == emptyString) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(itemPtr->label, -1); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int NearestOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; int wx, wy; Item *itemPtr; int isRoot; char *string; isRoot = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } itemPtr = NearestItem(comboPtr, x, y, TRUE); if (itemPtr == NULL) { return TCL_OK; } x = WORLDX(comboPtr, x); y = WORLDY(comboPtr, y); wx = itemPtr->xWorld + ITEM_XPAD; wy = itemPtr->xWorld + ITEM_XPAD; if (objc > 4) { const char *where; where = ""; if (itemPtr->flags & (ITEM_RADIOBUTTON | ITEM_CHECKBUTTON)) { int bx, by, bw, bh; bx = wx; by = wy; if (itemPtr->flags & ITEM_RADIOBUTTON) { bw = IconWidth(comboPtr->rbIcon); bh = IconHeight(comboPtr->rbIcon); } else { bw = IconWidth(comboPtr->cbIcon); bh = IconHeight(comboPtr->cbIcon); } wx += comboPtr->leftIndWidth + ITEM_IPAD; if ((x >= bx) && (x < (bx + bw)) && (y >= by) && (y < (by + bh))) { if (itemPtr->flags & ITEM_RADIOBUTTON) { where = "radiobutton"; } else { where = "checkbutton"; } goto done; } } if (itemPtr->icon != NULL) { int ix, iy, iw, ih; ih = IconHeight(itemPtr->icon); iw = IconWidth(itemPtr->icon); ix = wx; iy = wy; wx += comboPtr->iconWidth + ITEM_IPAD; if ((x >= ix) && (x <= (ix + iw)) && (y >= iy) && (y < (iy + ih))) { where = "icon"; goto done; } } if ((itemPtr->label != emptyString) || (itemPtr->image != NULL)) { int lx, ly; lx = wx; ly = wy; wx += comboPtr->labelWidth + ITEM_IPAD; if ((x >= lx) && (x < (lx + itemPtr->labelWidth)) && (y >= ly) && (y < (ly + itemPtr->labelHeight))) { where = "label"; goto done; } } if ((itemPtr->accel != NULL) || (itemPtr->flags & ITEM_CASCADE)) { int ax, ay, aw, ah; ax = wx; ay = wy; aw = itemPtr->rightIndWidth; ah = itemPtr->rightIndHeight; if ((x >= ax) && (x < (ax + aw)) && (y >= ay) && (y < (ay + ah))) { if (itemPtr->flags & ITEM_CASCADE) { where = "cascade"; } else { where = "accelerator"; } goto done; } } done: if (Tcl_SetVar(interp, Tcl_GetString(objv[4]), where, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), itemPtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm next item * *--------------------------------------------------------------------------- */ static int NextOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, comboPtr, objv[2], &itemPtr) == TCL_OK) { itemPtr = NextItem(itemPtr); if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostOp -- * * Posts this menu at the given root screen coordinates. * * .cm post ?switches? * * -anchor ne -fill yes -width 80 -x -y * .cm post -x 0 -y 0 -reqwidth -reqheight -anchor -fill yes *--------------------------------------------------------------------------- */ static int PostOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; Tk_Window parent; int menuWidth; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } parent = Tk_Parent(comboPtr->tkwin); comboPtr->parentWidth = 0; menuWidth = comboPtr->normalWidth; if (menuWidth < Tk_Width(parent)) { menuWidth = Tk_Width(parent); } if (objc == 5) { const char *string; string = Tcl_GetString(objv[4]); if (strcmp(string, "left") == 0) { /* Do nothing. */ } else if (strcmp(string, "right") == 0) { x -= menuWidth; } else if (strcmp(string, "center") == 0) { x -= menuWidth / 2; } else if (strcmp(string, "popup") == 0) { /* Do nothing. */ parent = comboPtr->tkwin; } else { Tcl_AppendResult(interp, "bad alignment value \"", string, "\": should be left, right, or center.", (char *)NULL); return TCL_ERROR; } comboPtr->parentWidth = Tk_Width(parent); } if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } FixMenuCoords(comboPtr, parent, &x, &y); /* * If there is a post command for the menu, execute it. This may change * the size of the menu, so be sure to recompute the menu's geometry if * needed. */ if (comboPtr->postCmdObjPtr != NULL) { int result; Tcl_IncrRefCount(comboPtr->postCmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->postCmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->postCmdObjPtr); if (result != TCL_OK) { return result; } /* * The post commands could have deleted the menu, which means we are * dead and should go away. */ if (comboPtr->tkwin == NULL) { return TCL_OK; } if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } } /* * Adjust the position of the menu if necessary to keep it visible on the * screen. There are two special tricks to make this work right: * * 1. If a virtual root window manager is being used then * the coordinates are in the virtual root window of * menuPtr's parent; since the menu uses override-redirect * mode it will be in the *real* root window for the screen, * so we have to map the coordinates from the virtual root * (if any) to the real root. Can't get the virtual root * from the menu itself (it will never be seen by the wm) * so use its parent instead (it would be better to have an * an option that names a window to use for this...). * 2. The menu may not have been mapped yet, so its current size * might be the default 1x1. To compute how much space it * needs, use its requested size, not its actual size. * * Note that this code assumes square screen regions and all positive * coordinates. This does not work on a Mac with multiple monitors. But * then again, Tk has other problems with this. */ { int vx, vy, vw, vh; int tmp; int screenWidth, screenHeight; Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); Tk_GetVRootGeometry(parent, &vx, &vy, &vw, &vh); x += vx; y += vy; tmp = screenWidth - Tk_Width(comboPtr->tkwin); if (x > tmp) { x = tmp; } if (x < 0) { x = 0; } tmp = screenHeight - Tk_Height(comboPtr->tkwin); if (y > tmp) { y = tmp; } if (y < 0) { y = 0; } Tk_MoveToplevelWindow(comboPtr->tkwin, x, y); if (!Tk_IsMapped(comboPtr->tkwin)) { Tk_MapWindow(comboPtr->tkwin); } Blt_MapToplevelWindow(comboPtr->tkwin); Blt_RaiseToplevelWindow(comboPtr->tkwin); #ifdef notdef TkWmRestackToplevel(comboPtr->tkwin, Above, NULL); #endif } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostCascadeOp -- * * Posts the menu of a cascade item. If the item is a cascade menu, then * the submenu is requested to be posted. * * Results: * A standard TCL result. * * Side effects: * The item's submenu may be posted. * * .cm postcascade item * *--------------------------------------------------------------------------- */ static int PostCascadeOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; char *string; string = Tcl_GetString(objv[2]); if (GetItemFromObj(interp, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == comboPtr->postedPtr) { return TCL_OK; /* Nothing to do, submenu is already * posted. */ } if (UnpostCascade(interp, comboPtr) != TCL_OK) { return TCL_ERROR; /* Error unposting submenu. */ } if ((itemPtr != NULL) && (itemPtr->menuObjPtr != NULL) && ((itemPtr->flags & (ITEM_CASCADE|ITEM_DISABLED)) == ITEM_CASCADE)) { return PostCascade(interp, comboPtr, itemPtr); } return TCL_OK; /* No menu to post. */ } /* *--------------------------------------------------------------------------- * * PreviousOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm previous item * *--------------------------------------------------------------------------- */ static int PreviousOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int index; index = -1; if (GetItemFromObj(NULL, comboPtr, objv[2], &itemPtr) == TCL_OK) { itemPtr = PrevItem(itemPtr); if (itemPtr != NULL) { index = itemPtr->index; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int oper; int x, y; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 { char *string; char c; int length; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } } if ((Blt_GetPixelsFromObj(interp, comboPtr->tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) || (Blt_GetPixelsFromObj(interp, comboPtr->tkwin, objv[4], PIXELS_ANY, &y) != TCL_OK)) { return TCL_ERROR; } if (oper == SCAN_MARK) { comboPtr->scanAnchorX = x; comboPtr->scanAnchorY = y; comboPtr->scanX = comboPtr->xOffset; comboPtr->scanY = comboPtr->yOffset; } else { int xWorld, yWorld; int viewWidth, viewHeight; int dx, dy; dx = comboPtr->scanAnchorX - x; dy = comboPtr->scanAnchorY - y; xWorld = comboPtr->scanX + (10 * dx); yWorld = comboPtr->scanY + (10 * dy); viewWidth = VPORTWIDTH(comboPtr); if (xWorld > (comboPtr->worldWidth - viewWidth)) { xWorld = comboPtr->worldWidth - viewWidth; } if (xWorld < 0) { xWorld = 0; } viewHeight = VPORTHEIGHT(comboPtr); if (yWorld > (comboPtr->worldHeight - viewHeight)) { yWorld = comboPtr->worldHeight - viewHeight; } if (yWorld < 0) { yWorld = 0; } comboPtr->xOffset = xWorld; comboPtr->yOffset = yWorld; comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); } return TCL_OK; } /*ARGSUSED*/ static int SeeOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; int x, y, w, h; Tk_Anchor anchor; int left, right, top, bottom; char *string; string = Tcl_GetString(objv[2]); anchor = TK_ANCHOR_W; /* Default anchor is West */ if ((string[0] == '-') && (strcmp(string, "-anchor") == 0)) { if (objc == 3) { Tcl_AppendResult(interp, "missing \"-anchor\" argument", (char *)NULL); return TCL_ERROR; } if (Tk_GetAnchorFromObj(interp, objv[3], &anchor) != TCL_OK) { return TCL_ERROR; } objc -= 2, objv += 2; } if (objc == 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", objv[0], "see ?-anchor anchor? item\"", (char *)NULL); return TCL_ERROR; } if (GetItemFromObj(interp, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { return TCL_OK; } w = VPORTWIDTH(comboPtr); h = VPORTHEIGHT(comboPtr); /* * XVIEW: If the entry is left or right of the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ left = comboPtr->xOffset; right = comboPtr->xOffset + w; switch (anchor) { case TK_ANCHOR_W: case TK_ANCHOR_NW: case TK_ANCHOR_SW: x = 0; break; case TK_ANCHOR_E: case TK_ANCHOR_NE: case TK_ANCHOR_SE: x = itemPtr->xWorld + itemPtr->width - w; break; default: if (itemPtr->xWorld < left) { x = itemPtr->xWorld; } else if ((itemPtr->xWorld + itemPtr->width) > right) { x = itemPtr->xWorld + itemPtr->width - w; } else { x = comboPtr->xOffset; } break; } /* * YVIEW: If the entry is above or below the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ top = comboPtr->yOffset; bottom = comboPtr->yOffset + h; switch (anchor) { case TK_ANCHOR_N: y = comboPtr->yOffset; break; case TK_ANCHOR_NE: case TK_ANCHOR_NW: y = itemPtr->yWorld - (h / 2); break; case TK_ANCHOR_S: case TK_ANCHOR_SE: case TK_ANCHOR_SW: y = itemPtr->yWorld + itemPtr->height - h; break; default: if (itemPtr->yWorld < top) { y = itemPtr->yWorld; } else if ((itemPtr->yWorld + itemPtr->height) > bottom) { y = itemPtr->yWorld + itemPtr->height - h; } else { y = comboPtr->yOffset; } break; } if ((y != comboPtr->yOffset) || (x != comboPtr->xOffset)) { comboPtr->xOffset = x; comboPtr->yOffset = y; comboPtr->flags |= SCROLL_PENDING; } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set; sub-menus may * get posted. * * .cm select item * *--------------------------------------------------------------------------- */ static int SelectOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; const char *cmd; int result; if (GetItemFromObj(interp, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if ((itemPtr == NULL) || (itemPtr->flags & ITEM_DISABLED)) { return TCL_OK; /* Item is currently disabled. */ } cmd = Tcl_GetString(objv[1]); Tcl_Preserve(itemPtr); result = SelectItem(interp, comboPtr, itemPtr, cmd[0] == 's'); Tcl_Release(itemPtr); return result; } /*ARGSUSED*/ static int SizeOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Chain_GetLength(comboPtr->chain)); return TCL_OK; } /* .m style create name option value option value */ static int StyleCreateOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&comboPtr->styleTable, Tcl_GetString(objv[3]), &isNew); if (!isNew) { Tcl_AppendResult(interp, "combomenu style \"", Tcl_GetString(objv[3]), "\" already exists.", (char *)NULL); return TCL_ERROR; } stylePtr = Blt_AssertCalloc(1, sizeof(Style)); stylePtr->name = Blt_GetHashKey(&comboPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->comboPtr = comboPtr; stylePtr->borderWidth = 0; stylePtr->activeRelief = TK_RELIEF_RAISED; Blt_SetHashValue(hPtr, stylePtr); iconOption.clientData = comboPtr; if (ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, 0) != TCL_OK) { DestroyStyle(stylePtr); return TCL_ERROR; } return TCL_OK; } static int StyleCgetOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, styleConfigSpecs, (char *)stylePtr, objv[4], 0); } static int StyleConfigureOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result, flags; Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconOption.clientData = comboPtr; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, styleConfigSpecs, (char *)stylePtr, (Tcl_Obj *)NULL, flags); } else if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, styleConfigSpecs, (char *)stylePtr, objv[2], flags); } Tcl_Preserve(stylePtr); result = ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, flags); Tcl_Release(stylePtr); if (result == TCL_ERROR) { return TCL_ERROR; } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } static int StyleDeleteOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } if (stylePtr->refCount > 0) { Tcl_AppendResult(interp, "can't destroy combomenu style \"", stylePtr->name, "\": style in use.", (char *)NULL); return TCL_ERROR; } DestroyStyle(stylePtr); return TCL_OK; } static int StyleNamesOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&comboPtr->styleTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Style *stylePtr; int found; int i; found = TRUE; stylePtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); found = Tcl_StringMatch(stylePtr->name, pattern); if (found) { break; } } if (found) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(stylePtr->name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static Blt_OpSpec styleOps[] = { {"cget", 2, StyleCgetOp, 5, 5, "name option",}, {"configure", 2, StyleConfigureOp, 4, 0, "name ?option value?...",}, {"create", 2, StyleCreateOp, 4, 0, "name ?option value?...",}, {"delete", 1, StyleDeleteOp, 3, 0, "?name...?",}, {"names", 1, StyleNamesOp, 3, 0, "?pattern...?",}, }; static int nStyleOps = sizeof(styleOps) / sizeof(Blt_OpSpec); static int StyleOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboMenuCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nStyleOps, styleOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } static int TypeOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, comboPtr, objv[2], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr != NULL) { const char *name; name = NameOfType(itemPtr->flags); Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnpostOp -- * * Unposts this menu. * * .cm post * *--------------------------------------------------------------------------- */ static int UnpostOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (!Tk_IsMapped(comboPtr->tkwin)) { return TCL_OK; /* This menu is already unposted. */ } /* Deactivate the current item. */ if (comboPtr->postedPtr != NULL) { if (UnpostCascade(interp, comboPtr) != TCL_OK) { return TCL_ERROR; } comboPtr->postedPtr = NULL; } if (Tk_IsMapped(comboPtr->tkwin)) { Tk_UnmapWindow(comboPtr->tkwin); } /* * If there is a post command for the menu, execute it. This may change * the size of the menu, so be sure to recompute the menu's geometry if * needed. */ if (comboPtr->unpostCmdObjPtr != NULL) { int result; Tcl_IncrRefCount(comboPtr->unpostCmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->unpostCmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->unpostCmdObjPtr); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } static int XpositionOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, comboPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't get x-position of item: no item \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), itemPtr->xWorld-comboPtr->xOffset); return TCL_OK; } static int XviewOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int w; w = VPORTWIDTH(comboPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)comboPtr->xOffset / (comboPtr->worldWidth+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(comboPtr->xOffset + w) / (comboPtr->worldWidth+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &comboPtr->xOffset, comboPtr->worldWidth, w, comboPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } static int YpositionOp(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Item *itemPtr; if (GetItemFromObj(interp, comboPtr, objv[3], &itemPtr) != TCL_OK) { return TCL_ERROR; } if (itemPtr == NULL) { Tcl_AppendResult(interp, "can't get y-position of item: such index \"", Tcl_GetString(objv[3]), "\"", (char *)NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), itemPtr->yWorld-comboPtr->yOffset); return TCL_OK; } static int YviewOp( ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int height; height = VPORTHEIGHT(comboPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)comboPtr->yOffset / (comboPtr->worldHeight+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(comboPtr->yOffset + height) /(comboPtr->worldHeight+1); objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &comboPtr->yOffset, comboPtr->worldHeight, height, comboPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyComboMenu -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of the widget at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side Effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyComboMenu(DestroyData dataPtr) /* Pointer to the widget record. */ { ComboMenu *comboPtr = (ComboMenu *)dataPtr; if (comboPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayComboMenu, comboPtr); } if (comboPtr->flags & INSTALL_XSCROLLBAR) { Tcl_CancelIdleCall(InstallXScrollbar, comboPtr); } if (comboPtr->flags & INSTALL_YSCROLLBAR) { Tcl_CancelIdleCall(InstallYScrollbar, comboPtr); } if (comboPtr->flags & UPDATE_PENDING) { Tcl_CancelIdleCall(ConfigureScrollbarsProc, comboPtr); } DestroyItems(comboPtr); DestroyStyles(comboPtr); DestroyLabels(comboPtr); Blt_DeleteHashTable(&comboPtr->tagTable); DestroyIcons(comboPtr); if (comboPtr->painter != NULL) { Blt_FreePainter(comboPtr->painter); } iconOption.clientData = comboPtr; Blt_FreeOptions(comboConfigSpecs, (char *)comboPtr, comboPtr->display, 0); Tcl_DeleteCommandFromToken(comboPtr->interp, comboPtr->cmdToken); Blt_Free(comboPtr); } /* *--------------------------------------------------------------------------- * * NewComboMenu -- * *--------------------------------------------------------------------------- */ static ComboMenu * NewComboMenu(Tcl_Interp *interp, Tk_Window tkwin) { ComboMenu *comboPtr; comboPtr = Blt_AssertCalloc(1, sizeof(ComboMenu)); Tk_SetClass(tkwin, "ComboMenu"); comboPtr->tkwin = tkwin; comboPtr->display = Tk_Display(tkwin); comboPtr->interp = interp; comboPtr->flags |= LAYOUT_PENDING | SCROLL_PENDING; comboPtr->relief = TK_RELIEF_SOLID; comboPtr->xScrollUnits = 2; comboPtr->yScrollUnits = 2; comboPtr->borderWidth = 1; comboPtr->chain = Blt_Chain_Create(); comboPtr->painter = Blt_GetPainter(tkwin, 1.0); Blt_ResetLimits(&comboPtr->reqWidth); Blt_ResetLimits(&comboPtr->reqHeight); Blt_InitHashTable(&comboPtr->iconTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->labelTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->styleTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->tagTable, BLT_STRING_KEYS); AddDefaultStyle(interp, comboPtr); Blt_SetWindowInstanceData(tkwin, comboPtr); return comboPtr; } /* *--------------------------------------------------------------------------- * * ComboMenuCmd -- * * This procedure is invoked to process the "combomenu" command. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec menuOps[] = { {"activate", 2, ActivateOp, 3, 3, "item",}, {"add", 2, AddOp, 2, 0, "?option value?",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"delete", 3, DeleteOp, 2, 0, "items...",}, {"deselect", 3, SelectOp, 3, 3, "item",}, {"exists", 3, ExistsOp, 3, 3, "item",}, {"find", 1, FindOp, 3, 0, "string ?switches?",}, {"index", 3, IndexOp, 3, 3, "item",}, {"insert", 3, InsertOp, 3, 0, "after|at|before index ?option value?",}, {"invoke", 3, InvokeOp, 3, 3, "item",}, {"item", 2, ItemOp, 2, 0, "oper args",}, {"listadd", 1, AddListOp, 3, 0, "labelList ?option value?",}, {"names", 2, NamesOp, 2, 0, "?pattern...?",}, {"nearest", 3, NearestOp, 4, 4, "x y",}, {"next", 3, NextOp, 3, 3, "item",}, {"post", 4, PostOp, 4, 5, "x y ?align?",}, {"postcascade", 5, PostCascadeOp, 3, 3, "item",}, {"previous", 2, PreviousOp, 3, 3, "item",}, {"scan", 2, ScanOp, 5, 5, "dragto|mark x y",}, {"see", 3, SeeOp, 3, 5, "item",}, {"select", 3, SelectOp, 3, 3, "item",}, {"size", 2, SizeOp, 2, 2, "",}, {"style", 2, StyleOp, 2, 0, "op ?args...?",}, {"type", 1, TypeOp, 3, 3, "item",}, {"unpost", 1, UnpostOp, 2, 2, "",}, {"xposition", 2, XpositionOp, 3, 3, "item",}, {"xview", 2, XviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yposition", 2, YpositionOp, 3, 3, "item",}, {"yview", 2, YviewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nMenuOps = sizeof(menuOps) / sizeof(Blt_OpSpec); typedef int (ComboInstOp)(ComboMenu *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int ComboMenuInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back * to. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument vector. */ { ComboInstOp *proc; ComboMenu *comboPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nMenuOps, menuOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(comboPtr); result = (*proc) (comboPtr, interp, objc, objv); Tcl_Release(comboPtr); return result; } /* *--------------------------------------------------------------------------- * * ComboMenuInstCmdDeletedProc -- * * This procedure can be called if the window was destroyed (tkwin will * be NULL) and the command was deleted automatically. In this case, we * need to do nothing. * * Otherwise this routine was called because the command was deleted. * Then we need to clean-up and destroy the widget. * * Results: * None. * * Side Effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ComboMenuInstCmdDeletedProc(ClientData clientData) { ComboMenu *comboPtr = clientData; /* Pointer to widget record. */ if (comboPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = comboPtr->tkwin; comboPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ComboMenuCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ComboMenuCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { ComboMenu *comboPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; XSetWindowAttributes attrs; char *path; unsigned int mask; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, invoke a procedure to initialize * various bindings on the combomenu widget. If the procedure doesn't * already exist, source it from "$blt_library/combomenu.tcl". We * deferred sourcing the file until now so that the variable $blt_library * could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ComboMenu::PostMenu", &cmdInfo)) { if (Tcl_GlobalEval(interp, "source [file join $blt_library combomenu.tcl]") != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); #define TOP_LEVEL_SCREEN "" tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, TOP_LEVEL_SCREEN); if (tkwin == NULL) { return TCL_ERROR; } comboPtr = NewComboMenu(interp, tkwin); if (ConfigureComboMenu(interp, comboPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(comboPtr->tkwin); return TCL_ERROR; } mask = (ExposureMask | StructureNotifyMask | FocusChangeMask); Tk_CreateEventHandler(tkwin, mask, ComboMenuEventProc, comboPtr); comboPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ComboMenuInstCmdProc, comboPtr, ComboMenuInstCmdDeletedProc); attrs.override_redirect = True; attrs.backing_store = WhenMapped; attrs.save_under = True; mask = (CWOverrideRedirect | CWSaveUnder | CWBackingStore); Tk_ChangeWindowAttributes(tkwin, mask, &attrs); Tk_MakeWindowExist(tkwin); Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ComboViewCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ComboViewCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { ComboMenu *comboPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; unsigned int mask; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, invoke a procedure to initialize * various bindings on the combomenu widget. If the procedure doesn't * already exist, source it from "$blt_library/combomenu.tcl". We * deferred sourcing the file until now so that the variable $blt_library * could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ComboMenu::PostMenu", &cmdInfo)) { if (Tcl_GlobalEval(interp, "source [file join $blt_library combomenu.tcl]") != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, NULL); if (tkwin == NULL) { return TCL_ERROR; } comboPtr = NewComboMenu(interp, tkwin); if (ConfigureComboMenu(interp, comboPtr, objc - 2, objv + 2, 0) != TCL_OK) { Tk_DestroyWindow(comboPtr->tkwin); return TCL_ERROR; } mask = (ExposureMask | StructureNotifyMask | FocusChangeMask); Tk_CreateEventHandler(tkwin, mask, ComboMenuEventProc, comboPtr); comboPtr->cmdToken = Tcl_CreateObjCommand(interp, path, ComboMenuInstCmdProc, comboPtr, ComboMenuInstCmdDeletedProc); Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } int Blt_ComboMenuInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec[2] = { { "combomenu", ComboMenuCmd }, { "comboview", ComboViewCmd }, }; return Blt_InitCmds(interp, "::blt", cmdSpec, 2); } static void DrawItemBackground(Item *itemPtr, Drawable drawable, int x, int y) { Blt_Background bg; Style *stylePtr; ComboMenu *comboPtr; int relief; int w, h; stylePtr = itemPtr->stylePtr; comboPtr = itemPtr->comboPtr; relief = itemPtr->relief; if ((itemPtr->flags & (ITEM_DISABLED|ITEM_SEPARATOR)) == ITEM_DISABLED) { bg = stylePtr->disabledBg; } else if (comboPtr->activePtr == itemPtr) { bg = stylePtr->activeBg; relief = stylePtr->activeRelief; } else { bg = stylePtr->normalBg; } w = VPORTWIDTH(comboPtr); w = MAX(comboPtr->worldWidth, w); h = itemPtr->height; #ifndef notdef if (y == 0) { int xOrigin, yOrigin; int px, py; px = PIXMAPX(comboPtr, itemPtr->xWorld); py = PIXMAPY(comboPtr, itemPtr->yWorld); Blt_GetBackgroundOrigin(bg, &xOrigin, &yOrigin); Blt_SetBackgroundOrigin(comboPtr->tkwin, bg, px, py); Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); Blt_SetBackgroundOrigin(comboPtr->tkwin, bg, xOrigin, yOrigin); } else { Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); } #else Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); #endif } static void DrawSeparator(Item *itemPtr, Drawable drawable, int x, int y, int w, int h) { XPoint points[2]; Tk_3DBorder border; ComboMenu *comboPtr; Style *stylePtr; comboPtr = itemPtr->comboPtr; stylePtr = itemPtr->stylePtr; border = Blt_BackgroundBorder(stylePtr->normalBg); points[0].x = x + ITEM_XPAD; points[0].y = y + h / 2; points[1].x = w - 2 * ITEM_XPAD; points[1].y = points[0].y; Tk_Draw3DPolygon(comboPtr->tkwin, drawable, border, points, 2, 1, TK_RELIEF_SUNKEN); } static void DrawCheckButton(Item *itemPtr, Drawable drawable, int x, int y, int w, int h) { Style *stylePtr; Display *display; ComboMenu *comboPtr; XColor *outlineColor, *fillColor, *checkColor; comboPtr = itemPtr->comboPtr; Blt_Picture picture; int on; stylePtr = itemPtr->stylePtr; display = itemPtr->comboPtr->display; on = (itemPtr->flags & ITEM_SELECTED); fillColor = (stylePtr->indFillColor) ? stylePtr->indFillColor : comboPtr->checkButtonFillColor; outlineColor = (stylePtr->indOutlineColor) ? stylePtr->indOutlineColor : comboPtr->checkButtonOutlineColor; checkColor = (stylePtr->indColor) ? stylePtr->indColor : comboPtr->checkButtonColor; if (itemPtr->flags & ITEM_DISABLED) { if (stylePtr->checkbutton[0] == NULL) { if (fillColor != NULL) { fillColor = Blt_BackgroundBorderColor(stylePtr->disabledBg); } if (outlineColor != NULL) { outlineColor = stylePtr->labelDisabledColor; } stylePtr->checkbutton[0] = Blt_PaintCheckbox(w, h, fillColor, outlineColor, Blt_BackgroundBorderColor(stylePtr->disabledBg), FALSE); } picture = stylePtr->checkbutton[0]; } else { Blt_Picture *picturePtr; picturePtr = (on) ? stylePtr->checkbutton + 1 : stylePtr->checkbutton + 2; if (*picturePtr == NULL) { *picturePtr = Blt_PaintCheckbox(w, h, fillColor, outlineColor, checkColor, on); } picture = *picturePtr; } Blt_PaintPicture(comboPtr->painter, drawable, picture, 0, 0, w, h, x, y, 0); } static void DrawRadioButton(Item *itemPtr, Drawable drawable, int x, int y, int w, int h) { Style *stylePtr; Display *display; ComboMenu *comboPtr; Blt_Picture picture; int on; comboPtr = itemPtr->comboPtr; stylePtr = itemPtr->stylePtr; display = itemPtr->comboPtr->display; on = (itemPtr->flags & ITEM_SELECTED); if (itemPtr->flags & ITEM_DISABLED) { picture = stylePtr->radiobutton[0]; if (picture == NULL) { picture = Blt_PaintRadioButton(w, h, Blt_BackgroundBorderColor(stylePtr->disabledBg), stylePtr->labelDisabledColor, stylePtr->labelDisabledColor, FALSE); stylePtr->radiobutton[0] = picture; } } else { Blt_Picture *picturePtr; picturePtr = (on) ? stylePtr->radiobutton + 1 : stylePtr->radiobutton + 2; if (*picturePtr == NULL) { XColor *fillColor, *circleColor, *outlineColor; fillColor = (stylePtr->indFillColor) ? stylePtr->indFillColor : comboPtr->radioButtonFillColor; outlineColor = (stylePtr->indOutlineColor) ? stylePtr->indOutlineColor : comboPtr->radioButtonOutlineColor; circleColor = (stylePtr->indColor) ? stylePtr->indColor : comboPtr->radioButtonColor; *picturePtr = Blt_PaintRadioButton(w, h, fillColor, outlineColor, circleColor, on); } picture = *picturePtr; } Blt_PaintPicture(comboPtr->painter, drawable, picture, 0, 0, w, h, x, y, 0); } static void DrawItem(Item *itemPtr, Drawable drawable, int x, int y) { ComboMenu *comboPtr; Style *stylePtr; int x0, w, h; itemPtr->flags &= ~ITEM_REDRAW; stylePtr = itemPtr->stylePtr; comboPtr = itemPtr->comboPtr; x0 = x; w = VPORTWIDTH(comboPtr) - 2 * stylePtr->borderWidth; x += stylePtr->borderWidth + comboPtr->borderWidth; h = itemPtr->height - 2 * stylePtr->borderWidth; y += stylePtr->borderWidth; if (itemPtr->flags & ITEM_SEPARATOR) { DrawSeparator(itemPtr, drawable, x, y, w, h); y += ITEM_SEP_HEIGHT; } else { x += ITEM_IPAD; /* Radiobutton or checkbutton. */ if (itemPtr->flags & (ITEM_RADIOBUTTON | ITEM_CHECKBUTTON)) { if (itemPtr->flags & ITEM_RADIOBUTTON) { DrawRadioButton(itemPtr, drawable, x, y + (h - itemPtr->leftIndHeight) / 2, itemPtr->leftIndWidth, itemPtr->leftIndHeight); } else if (itemPtr->flags & ITEM_CHECKBUTTON) { DrawCheckButton(itemPtr, drawable, x, y + (h - itemPtr->leftIndHeight) / 2, itemPtr->leftIndWidth, itemPtr->leftIndHeight); } } x += itemPtr->indent; if (comboPtr->leftIndWidth > 0) { x += comboPtr->leftIndWidth + ITEM_IPAD; } /* Icon. */ if (itemPtr->icon != NULL) { if ((Blt_IsPicture(IconImage(itemPtr->icon))) && (itemPtr->flags & ITEM_DISABLED)) { Blt_Picture picture; Blt_Painter painter; painter = Blt_GetPainter(comboPtr->tkwin, 1.0); picture = Blt_GetPictureFromPictureImage(comboPtr->interp, IconImage(itemPtr->icon)); picture = Blt_GreyscalePicture(picture); Blt_PaintPicture(painter, drawable, picture, 0, 0, IconWidth(itemPtr->icon), IconHeight(itemPtr->icon), x + (comboPtr->iconWidth - itemPtr->iconWidth) / 2, y + (h - IconHeight(itemPtr->icon)) / 2, 0); Blt_FreePicture(picture); } else { Tk_RedrawImage(IconImage(itemPtr->icon), 0, 0, IconWidth(itemPtr->icon), IconHeight(itemPtr->icon), drawable, x + (comboPtr->iconWidth - itemPtr->iconWidth) / 2, y + (h - IconHeight(itemPtr->icon)) / 2); } if (comboPtr->iconWidth > 0) { x += comboPtr->iconWidth + ITEM_IPAD; } } /* Image or label. */ if (itemPtr->image != NULL) { Tk_RedrawImage(IconImage(itemPtr->image), 0, 0, IconWidth(itemPtr->image), IconHeight(itemPtr->image), drawable, x, y + (h - IconHeight(itemPtr->image)) / 2); } else if (itemPtr->label != emptyString) { TextStyle ts; XColor *fg; if (itemPtr->flags & ITEM_DISABLED) { fg = stylePtr->labelDisabledColor; } else if (comboPtr->activePtr == itemPtr) { fg = stylePtr->labelActiveColor; } else { fg = stylePtr->labelNormalColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, stylePtr->labelFont); Blt_Ts_SetForeground(ts, fg); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetUnderline(ts, itemPtr->underline); Blt_Ts_SetJustify(ts, TK_JUSTIFY_LEFT); Blt_DrawText(comboPtr->tkwin, drawable, (char *)itemPtr->label, &ts, x, y + (h - itemPtr->labelHeight) / 2); } x = x0 + MAX(comboPtr->worldWidth, VPORTWIDTH(comboPtr)) - 2*ITEM_IPAD; /* Accelerator or submenu arrow. */ if (itemPtr->flags & ITEM_CASCADE) { XColor *color; if (itemPtr->flags & ITEM_DISABLED) { color = stylePtr->labelDisabledColor; } else if (comboPtr->activePtr == itemPtr) { color = stylePtr->labelActiveColor; } else { color = stylePtr->labelNormalColor; } x -= ITEM_R_IND_WIDTH; Blt_DrawArrow(comboPtr->display, drawable, color, x + ITEM_IPAD, y, ITEM_R_IND_WIDTH, h, 1, ARROW_RIGHT); } else if (itemPtr->accel != NULL) { TextStyle ts; XColor *fg; if (itemPtr->flags & ITEM_DISABLED) { fg = stylePtr->accelDisabledColor; } else if (comboPtr->activePtr == itemPtr) { fg = stylePtr->accelActiveColor; } else { fg = stylePtr->accelNormalColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetForeground(ts, fg); Blt_Ts_SetFont(ts, stylePtr->accelFont); Blt_Ts_SetAnchor(ts, TK_ANCHOR_NW); Blt_Ts_SetJustify(ts, TK_JUSTIFY_LEFT); x -= itemPtr->rightIndWidth; Blt_DrawText(comboPtr->tkwin, drawable, (char *)itemPtr->accel, &ts, x, y + (h - itemPtr->rightIndHeight) / 2); } } } static void DrawComboMenu(ComboMenu *comboPtr, Drawable drawable) { /* Draw each visible item. */ if (comboPtr->firstPtr != NULL) { Blt_ChainLink first, last, link; first = comboPtr->firstPtr->link; last = comboPtr->lastPtr->link; for (link = first; link != NULL; link = Blt_Chain_NextLink(link)) { int x, y; Item *itemPtr; itemPtr = Blt_Chain_GetValue(link); x = PIXMAPX(comboPtr, itemPtr->xWorld); y = PIXMAPY(comboPtr, itemPtr->yWorld); DrawItemBackground(itemPtr, drawable, x, y); DrawItem(itemPtr, drawable, x, y); if (link == last) { break; } } } /* Manage the geometry of the scrollbars. */ if (comboPtr->yScrollbarWidth > 0) { int x, y; int yScrollbarHeight; x = Tk_Width(comboPtr->tkwin) - comboPtr->borderWidth - comboPtr->yScrollbarWidth; y = comboPtr->borderWidth; yScrollbarHeight = Tk_Height(comboPtr->tkwin) - comboPtr->xScrollbarHeight - 2 * comboPtr->borderWidth; if ((Tk_Width(comboPtr->yScrollbar) != comboPtr->yScrollbarWidth) || (Tk_Height(comboPtr->yScrollbar) != yScrollbarHeight) || (x != Tk_X(comboPtr->yScrollbar)) || (y != Tk_Y(comboPtr->yScrollbar))) { Tk_MoveResizeWindow(comboPtr->yScrollbar, x, y, comboPtr->yScrollbarWidth, yScrollbarHeight); } if (!Tk_IsMapped(comboPtr->yScrollbar)) { Tk_MapWindow(comboPtr->yScrollbar); } } else if ((comboPtr->yScrollbar != NULL) && (Tk_IsMapped(comboPtr->yScrollbar))) { Tk_UnmapWindow(comboPtr->yScrollbar); } if (comboPtr->xScrollbarHeight > 0) { int x, y; int xScrollbarWidth; x = comboPtr->borderWidth; y = Tk_Height(comboPtr->tkwin) - comboPtr->xScrollbarHeight - comboPtr->borderWidth; xScrollbarWidth = Tk_Width(comboPtr->tkwin) - comboPtr->yScrollbarWidth - 2 * comboPtr->borderWidth; if ((Tk_Width(comboPtr->xScrollbar) != xScrollbarWidth) || (Tk_Height(comboPtr->xScrollbar) != comboPtr->xScrollbarHeight) || (x != Tk_X(comboPtr->xScrollbar)) || (y != Tk_Y(comboPtr->xScrollbar))) { Tk_MoveResizeWindow(comboPtr->xScrollbar, x, y, xScrollbarWidth, comboPtr->xScrollbarHeight); } if (!Tk_IsMapped(comboPtr->xScrollbar)) { Tk_MapWindow(comboPtr->xScrollbar); } } else if ((comboPtr->xScrollbar != NULL) && (Tk_IsMapped(comboPtr->xScrollbar))) { Tk_UnmapWindow(comboPtr->xScrollbar); } } /* *--------------------------------------------------------------------------- * * DisplayItem -- * * This procedure is invoked to display an item in the combomenu widget. * * Results: * None. * * Side effects: * Commands are output to X to display the item. * *--------------------------------------------------------------------------- */ static void DisplayItem(ClientData clientData) { Item *itemPtr = clientData; int x, y, w, h, d, sy; Pixmap drawable; ComboMenu *comboPtr; /* * Create a pixmap the size of the item for double buffering. */ comboPtr = itemPtr->comboPtr; h = itemPtr->height; w = VPORTWIDTH(comboPtr); drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif DrawItemBackground(itemPtr, drawable, -comboPtr->xOffset, 0); DrawItem(itemPtr, drawable, -comboPtr->xOffset, 0); x = PIXMAPX(comboPtr, itemPtr->xWorld) + comboPtr->borderWidth; y = PIXMAPY(comboPtr, itemPtr->yWorld) + comboPtr->borderWidth; sy = 0; d = comboPtr->borderWidth - y; if (d > 0) { h -= d; sy = d; y += d; } d = (y + h) - (Tk_Height(comboPtr->tkwin) - comboPtr->borderWidth); if (d > 0) { h -= d; } XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->defStyle.labelNormalGC, 0, sy, w, h, comboPtr->borderWidth,y); Tk_FreePixmap(comboPtr->display, drawable); } /* *--------------------------------------------------------------------------- * * DisplayComboMenu -- * * This procedure is invoked to display a combomenu widget. * * Results: * None. * * Side effects: * Commands are output to X to display the menu. * *--------------------------------------------------------------------------- */ static void DisplayComboMenu(ClientData clientData) { ComboMenu *comboPtr = clientData; Pixmap drawable; int w, h; /* Window width and height. */ int screenWidth, screenHeight; comboPtr->flags &= ~REDRAW_PENDING; if (comboPtr->tkwin == NULL) { return; /* Window destroyed (should not get * here) */ } #ifdef notdef fprintf(stderr, "Calling DisplayComboMenu(%s) w=%d h=%d\n", Tk_PathName(comboPtr->tkwin), Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin)); #endif if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } if ((Tk_Width(comboPtr->tkwin) <= 1) || (Tk_Height(comboPtr->tkwin) <= 1)){ /* Don't bother computing the layout until the window size is * something reasonable. */ return; } if (!Tk_IsMapped(comboPtr->tkwin)) { /* The menu's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the combomenu's new layout. */ return; } if (comboPtr->flags & SCROLL_PENDING) { int vw, vh; /* Viewport width and height. */ /* * The view port has changed. The visible items need to be recomputed * and the scrollbars updated. */ ComputeVisibleItems(comboPtr); vw = VPORTWIDTH(comboPtr); vh = VPORTHEIGHT(comboPtr); if ((comboPtr->xScrollCmdObjPtr != NULL) && (comboPtr->flags & SCROLLX)) { Blt_UpdateScrollbar(comboPtr->interp, comboPtr->xScrollCmdObjPtr, comboPtr->xOffset, comboPtr->xOffset + vw, comboPtr->worldWidth); } if ((comboPtr->yScrollCmdObjPtr != NULL) && (comboPtr->flags & SCROLLY)) { Blt_UpdateScrollbar(comboPtr->interp, comboPtr->yScrollCmdObjPtr, comboPtr->yOffset, comboPtr->yOffset+vh, comboPtr->worldHeight); } comboPtr->flags &= ~SCROLL_PENDING; } /* * Create a pixmap the size of the window for double buffering. */ w = Tk_Width(comboPtr->tkwin) - 2 * comboPtr->borderWidth - comboPtr->yScrollbarWidth; h = Tk_Height(comboPtr->tkwin) - 2 * comboPtr->borderWidth - comboPtr->xScrollbarHeight; Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); w = CLAMP(w, 1, screenWidth); h = CLAMP(h, 1, screenHeight); drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif if (comboPtr->activePtr == NULL) { ActivateItem(comboPtr, comboPtr->firstPtr); } /* * Shadowed menu. Request window size slightly bigger than menu. Get * snapshot of background from root menu. */ /* Background */ Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, comboPtr->defStyle.normalBg, 0, 0, w, h, 0, TK_RELIEF_FLAT); DrawComboMenu(comboPtr, drawable); XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->defStyle.labelNormalGC, 0, 0, w, h, comboPtr->borderWidth, comboPtr->borderWidth); Tk_FreePixmap(comboPtr->display, drawable); if ((comboPtr->xScrollbarHeight > 0) && (comboPtr->yScrollbarWidth > 0)) { /* Draw the empty corner. */ Blt_FillBackgroundRectangle(comboPtr->tkwin, Tk_WindowId(comboPtr->tkwin), comboPtr->defStyle.disabledBg, w + comboPtr->borderWidth, h + comboPtr->borderWidth, comboPtr->yScrollbarWidth, comboPtr->xScrollbarHeight, 0, TK_RELIEF_FLAT); } Blt_DrawBackgroundRectangle(comboPtr->tkwin, Tk_WindowId(comboPtr->tkwin), comboPtr->defStyle.normalBg, 0, 0, Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin), comboPtr->borderWidth, comboPtr->relief); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictPs.c�������������������������������������������������������������������0000644�0001750�0001750�00000100365�11462120062�015102� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictPs.c -- * * This module implements Encapsulated PostScript file format conversion * routines for the picture image type in the BLT toolkit. * * Copyright 2003-2007 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #include <stdlib.h> #include <unistd.h> #include <limits.h> #include <tcl.h> #include <limits.h> #include <stdlib.h> #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) # define __WIN32__ # ifndef WIN32 # define WIN32 # endif # endif #endif /*__WIN32__*/ #ifdef _MSC_VER # define _CRT_SECURE_NO_DEPRECATE # define _CRT_NONSTDC_NO_DEPRECATE #endif /*MSC_VER*/ #ifdef WIN32 # define STRICT # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef STRICT # undef WIN32_LEAN_AND_MEAN # include <windowsx.h> #endif /*WIN32*/ #include <bltSwitch.h> #include <bltDBuffer.h> #include "bltTypes.h" #include "bltPicture.h" #include "bltPictFmts.h" #include "bltPs.h" #include "bltAlloc.h" #include "bltWait.h" #include <tk.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef WIN32 #include "bltWin.h" #endif /*WIN32*/ #define UCHAR(c) ((unsigned char) (c)) #define ISASCII(c) (UCHAR(c)<=0177) #define MIN(a,b) (((a)<(b))?(a):(b)) #define TRUE 1 #define FALSE 0 #define div257(t) (((t)+((t)>>8))>>8) #define SetBit(x) destRowPtr[(x>>3)] |= (0x80 >>(x&7)) #define GetBit(x) srcRowPtr[(x>>3)] & (0x80 >> (x&7)) #define MAXCOLORS 256 #define BUFFER_SIZE (1<<16) enum PbmVersions { PBM_UNKNOWN, PBM_PLAIN, /* Monochrome: 1-bit per pixel */ PGM_PLAIN, /* 8-bits per pixel */ PPM_PLAIN, /* 24-bits per pixel */ PBM_RAW, /* 1-bit per pixel */ PGM_RAW, /* 8/16-bits per pixel */ PPM_RAW /* 24/48 bits per pixel */ }; static const char *pbmFormat[] = { "???", "pbmplain", "pgmplain", "ppmplain", "pbmraw", "pgmraw", "ppmraw", }; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int flags; /* Flag. */ Blt_Pixel bg; PageSetup setup; int index; } PsExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int dpi; /* Dots per inch. */ const char *paperSize; /* Papersize. */ int crop; } PsImportSwitches; #define PS_CROP (1<<0) typedef struct { unsigned int width, height; /* Dimensions of the image. */ unsigned int bitsPerPixel; /* # bits per pixel. */ unsigned char *data; /* Start of raw data */ unsigned int bytesPerRow; Blt_DBuffer dbuffer; } Pbm; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc PicaSwitchProc; static Blt_SwitchCustom picaSwitch = { PicaSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc PadSwitchProc; static Blt_SwitchCustom padSwitch = { PadSwitchProc, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(PsExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PsExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PsExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_BITMASK, "-center", "", Blt_Offset(PsExportSwitches, setup.flags), 0, PS_CENTER}, {BLT_SWITCH_BITMASK, "-greyscale", "", Blt_Offset(PsExportSwitches, setup.flags), 0, PS_GREYSCALE}, {BLT_SWITCH_BITMASK, "-landscape", "", Blt_Offset(PsExportSwitches, setup.flags), 0, PS_LANDSCAPE}, {BLT_SWITCH_INT_POS, "-level", "pslevel", Blt_Offset(PsExportSwitches, setup.level), 0}, {BLT_SWITCH_BITMASK, "-maxpect", "", Blt_Offset(PsExportSwitches, setup.flags), 0, PS_MAXPECT}, {BLT_SWITCH_CUSTOM, "-padx", "pad", Blt_Offset(PsExportSwitches, setup.xPad), 0, 0, &padSwitch}, {BLT_SWITCH_CUSTOM, "-pady", "pad", Blt_Offset(PsExportSwitches, setup.yPad), 0, 0, &padSwitch}, {BLT_SWITCH_CUSTOM, "-paperheight","pica", Blt_Offset(PsExportSwitches, setup.reqPaperHeight), 0, 0, &picaSwitch}, {BLT_SWITCH_CUSTOM, "-paperwidth", "pica", Blt_Offset(PsExportSwitches, setup.reqPaperWidth), 0, 0, &picaSwitch}, {BLT_SWITCH_LIST, "-comments", "{key value...}", Blt_Offset(PsExportSwitches, setup.comments), BLT_SWITCH_NULL_OK}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PsExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_BOOLEAN, "-crop", "bool", Blt_Offset(PsImportSwitches, crop), 0}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(PsImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_INT, "-dpi", "number", Blt_Offset(PsImportSwitches, dpi), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(PsImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_STRING, "-papersize", "string", Blt_Offset(PsImportSwitches, paperSize), 0}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_PicturePsInit; extern const char *Blt_Itoa(int); #ifdef WIN32 typedef struct { DWORD pid; HANDLE hProcess; } ProcessId; #else typedef pid_t ProcessId; #endif #ifdef WIN32 #define close(fd) CloseHandle((HANDLE)fd) #define kill KillProcess #define waitpid WaitProcess #endif BLT_EXTERN int Blt_CreatePipeline(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ProcessId **pidArrayPtr, int *stdinPipePtr, int *stdoutPipePtr, int *stderrPipePtr); BLT_EXTERN void Blt_ScreenDPI(Tk_Window tkwin, unsigned int *xPtr, unsigned int *yPtr); #define TRUE 1 #define FALSE 0 typedef struct _Blt_Picture Picture; #include <ctype.h> static void AddComments(Blt_Ps ps, const char **comments) { const char **p; for (p = comments; *p != NULL; p += 2) { if (*(p+1) == NULL) { break; } Blt_Ps_Format(ps, "%% %s: %s\n", *p, *(p+1)); } } /* * Parse the lines that define the dimensions of the bitmap, plus the first * line that defines the bitmap data (it declares the name of a data variable * but doesn't include any actual data). These lines look something like the * following: * * #define foo_width 16 * #define foo_height 16 * #define foo_x_hot 3 * #define foo_y_hot 3 * static char foo_bits[] = { * * The x_hot and y_hot lines may or may not be present. It's important to * check for "char" in the last line, in order to reject old X10-style bitmaps * that used shorts. */ #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #endif /* TIME_WITH_SYS_TIME */ /* *-------------------------------------------------------------------------- * * PicaSwitchProc -- * * Convert a Tcl_Obj list of 2 or 4 numbers into representing a bounding * box structure. * * Results: * The return value is a standard TCL result. * *-------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PicaSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { int *picaPtr = (int *)(record + offset); return Blt_Ps_GetPicaFromObj(interp, objPtr, picaPtr); } /* *-------------------------------------------------------------------------- * * PadSwitchProc -- * * Convert a Tcl_Obj list of 2 or 4 numbers into representing a bounding * box structure. * * Results: * The return value is a standard TCL result. * *-------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PadSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Blt_Pad *padPtr = (Blt_Pad *)(record + offset); return Blt_Ps_GetPadFromObj(interp, objPtr, padPtr); } /* * -------------------------------------------------------------------------- * * PostScriptPreamble -- * * The PostScript preamble calculates the needed translation and scaling * to make image coordinates compatible with PostScript. * * -------------------------------------------------------------------------- */ static int PostScriptPreamble(Tcl_Interp *interp, Picture *srcPtr, PsExportSwitches *switchesPtr, Blt_Ps ps) { PageSetup *setupPtr = &switchesPtr->setup; time_t ticks; char date[200]; /* Hold the date string from ctime() */ const char *version; char *newline; Blt_Ps_Append(ps, "%!PS-Adobe-3.0 EPSF-3.0\n"); /* The "BoundingBox" comment is required for EPS files. */ Blt_Ps_Format(ps, "%%%%BoundingBox: %d %d %d %d\n", setupPtr->left, setupPtr->paperHeight - setupPtr->top, setupPtr->right, setupPtr->paperHeight - setupPtr->bottom); Blt_Ps_Append(ps, "%%Pages: 0\n"); version = Tcl_GetVar(interp, "blt_version", TCL_GLOBAL_ONLY); if (version == NULL) { version = "???"; } Blt_Ps_Format(ps, "%%%%Creator: (BLT %s Picture)\n", version); ticks = time((time_t *) NULL); strcpy(date, ctime(&ticks)); newline = date + strlen(date) - 1; if (*newline == '\n') { *newline = '\0'; } Blt_Ps_Format(ps, "%%%%CreationDate: (%s)\n", date); Blt_Ps_Append(ps, "%%DocumentData: Clean7Bit\n"); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Append(ps, "%%Orientation: Landscape\n"); } else { Blt_Ps_Append(ps, "%%Orientation: Portrait\n"); } AddComments(ps, setupPtr->comments); Blt_Ps_Append(ps, "%%EndComments\n\n"); Blt_Ps_Append(ps, "%%BeginProlog\n"); Blt_Ps_Append(ps, "%%EndProlog\n"); Blt_Ps_Append(ps, "%%BeginSetup\n"); Blt_Ps_Append(ps, "gsave\n"); /* * Set the conversion from PostScript to X11 coordinates. Scale pica to * pixels and flip the y-axis (the origin is the upperleft corner). */ Blt_Ps_VarAppend(ps, "% Transform coordinate system to use X11 coordinates\n" "% 1. Flip y-axis over by reversing the scale,\n", (char *)NULL); Blt_Ps_Append(ps, "1 -1 scale\n"); Blt_Ps_VarAppend(ps, "% 2. Translate the origin to the other side of the page,\n" "% making the origin the upper left corner\n", (char *)NULL); Blt_Ps_Format(ps, "0 %d translate\n\n", -setupPtr->paperHeight); Blt_Ps_VarAppend(ps, "% User defined page layout\n\n", "% Set color level\n", (char *)NULL); Blt_Ps_Format(ps, "%% Set origin\n%d %d translate\n\n", setupPtr->left, setupPtr->bottom); if (setupPtr->flags & PS_LANDSCAPE) { Blt_Ps_Format(ps, "%% Landscape orientation\n0 %g translate\n-90 rotate\n", ((double)srcPtr->width * setupPtr->scale)); } if (setupPtr->scale != 1.0f) { Blt_Ps_Append(ps, "\n% Setting picture scale factor\n"); Blt_Ps_Format(ps, " %g %g scale\n", setupPtr->scale, setupPtr->scale); } Blt_Ps_Append(ps, "\n%%EndSetup\n\n"); return TCL_OK; } static char * PbmComment(char *bp) { char *p; p = bp; if (*p == '#') { /* Comment: file end of line */ while((*p != '\n') && (p != '\0')) { p++; } } return p; } static inline int PbmGetShort(unsigned char *bp) { return (bp[0] << 8) + bp[1]; } static Picture * PbmRawData(Pbm *pbmPtr) { Picture *destPtr; destPtr = Blt_CreatePicture(pbmPtr->width, pbmPtr->height); switch (pbmPtr->bitsPerPixel) { case 1: { /* Monochrome */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { int x; Blt_Pixel *dp; dp = destRowPtr; for (x = 0; x < pbmPtr->width; x++) { dp->Red = dp->Green = dp->Blue = (GetBit(x)) ? 0xFF : 0; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 8: { /* Greyscale (1 byte) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp++, dp++) { dp->Red = dp->Green = dp->Blue = *sp; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 16: { /* Greyscale (2 bytes) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 2, dp++) { unsigned int value; value = PbmGetShort(sp); dp->Red = dp->Green = dp->Blue = div257(value); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 24: { /* Color (1 byte per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 3, dp++) { dp->Red = sp[0]; dp->Green = sp[1]; dp->Blue = sp[2]; dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } case 48: { /* Color (2 bytes per color component) */ Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = pbmPtr->data; destRowPtr = destPtr->bits; for (y = 0; y < pbmPtr->height; y++) { unsigned char *sp; Blt_Pixel *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; sp += 6, dp++) { unsigned int r, g, b; r = PbmGetShort(sp); g = PbmGetShort(sp+2); b = PbmGetShort(sp+4); dp->Red = div257(r); dp->Green = div257(g); dp->Blue = div257(b); dp->Alpha = ALPHA_OPAQUE; } srcRowPtr += pbmPtr->bytesPerRow; destRowPtr += destPtr->pixelsPerRow; } break; } } Blt_DBuffer_SetPointer(pbmPtr->dbuffer, pbmPtr->data + (pbmPtr->height * pbmPtr->bytesPerRow)); return destPtr; } static Blt_Picture PbmToPicture(Tcl_Interp *interp, Blt_DBuffer dbuffer) { char *bp, *p; const char *type; int isRaw; int version; size_t size, want; unsigned char *start; Pbm pbm; size = Blt_DBuffer_BytesLeft(dbuffer); start = Blt_DBuffer_Pointer(dbuffer); if (size < 14) { Tcl_AppendResult(interp, "can't read PBM bitmap: short file", (char *)NULL); return NULL; } bp = (char *)start; if ((bp[0] != 'P') || (bp[1] < '1') || (bp[1] > '6')) { Tcl_AppendResult(interp, "unknown PBM bitmap header", (char *)NULL); return NULL; } version = bp[1] - '0'; isRaw = (version > 2); switch(version) { case PBM_PLAIN: /* P2 */ case PBM_RAW: /* P5 */ pbm.bitsPerPixel = 8; break; case PGM_PLAIN: /* P1 */ case PGM_RAW: /* P4 */ pbm.bitsPerPixel = 1; break; case PPM_PLAIN: /* P3 */ case PPM_RAW: /* P6 */ pbm.bitsPerPixel = 24; break; } if (!isspace(bp[2])) { type = pbmFormat[version]; Tcl_AppendResult(interp, "no white space after version in pbm header.", (char *)NULL); return NULL; } p = bp + 3; if (*p == '#') { p = PbmComment(p); } pbm.width = strtoul(p, &p, 10); if (pbm.width == 0) { Tcl_AppendResult(interp, "bad width specification ", bp+3, ".", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after width in pbm header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } pbm.height = strtoul(p, &p, 10); if (pbm.height == 0) { Tcl_AppendResult(interp, "bad height specification", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after height in header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } if (pbm.bitsPerPixel != 1) { unsigned int maxval; /* Maximum intensity allowed. */ maxval = strtoul(p, &p, 10); if (maxval == 0) { Tcl_AppendResult(interp, "bad maxval specification", (char *)NULL); return NULL; } if (!isspace(*p)) { Tcl_AppendResult(interp, "no white space after maxval pbm header.", (char *)NULL); return NULL; } p++; if (*p == '#') { p = PbmComment(p); } if (maxval >= USHRT_MAX) { Tcl_AppendResult(interp, "invalid maxval specification", (char *)NULL); return NULL; } if (maxval > 255) { pbm.bitsPerPixel <<= 1; /* 16-bit greyscale or 48 bit color. */ } } pbm.data = (unsigned char *)p; pbm.dbuffer = dbuffer; pbm.bytesPerRow = ((pbm.bitsPerPixel * pbm.width) + 7) / 8; want = (pbm.data - start) + pbm.height * pbm.bytesPerRow; if ((isRaw) && (want > Blt_DBuffer_BytesLeft(dbuffer))) { Tcl_AppendResult(interp, "short pbm file", (char *)NULL); return NULL; } if (!isRaw) { Tcl_AppendResult(interp, "expected raw pbm file", (char *)NULL); return NULL; } return PbmRawData(&pbm); } #ifdef WIN32 typedef struct { int fd; Blt_DBuffer dbuffer; int lastError; } PsWriter; /* *--------------------------------------------------------------------------- * * WriteBufferProc -- * * This function runs in a separate thread and write the data * buffer as input to the ghostscript process. * * Results: * None. * * Side effects: * Writes the buffer (PostScript file) to the ghostscript standard * input file descriptor. * *--------------------------------------------------------------------------- */ static DWORD WINAPI WriteBufferProc(void *clientData) { PsWriter *writerPtr = clientData; const unsigned char *bp; int bytesLeft; HANDLE hFile; DWORD count; hFile = (HANDLE)writerPtr->fd; bp = Blt_DBuffer_Bytes(writerPtr->dbuffer); for (bytesLeft = Blt_DBuffer_Length(writerPtr->dbuffer); bytesLeft > 0; bytesLeft -= count) { if (!WriteFile(hFile, bp, bytesLeft, &count, NULL)) { writerPtr->lastError = GetLastError(); break; } bp += count; } Blt_DBuffer_Destroy(writerPtr->dbuffer); CloseHandle(hFile); if (bytesLeft > 0) { ExitThread(1); } ExitThread(0); /* NOTREACHED */ return 0; } static PsWriter writer; static int WriteToGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { HANDLE hThread; ClientData clientData; DWORD id; writer.dbuffer = Blt_DBuffer_Create(); Blt_DBuffer_Init(writer.dbuffer); /* Copy the input to a new buffer. */ Blt_DBuffer_AppendData(writer.dbuffer, Blt_DBuffer_Bytes(dbuffer), Blt_DBuffer_Length(dbuffer)); writer.fd = fd; writer.lastError = 0; clientData = &writer; hThread = CreateThread( NULL, /* Security attributes */ 8000, /* Initial stack size. */ WriteBufferProc, /* Address of thread routine */ clientData, /* One-word of data passed to routine. */ 0, /* Creation flags */ &id); /* (out) Will contain Id of new thread. */ return (int)hThread; } static int ReadFromGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { DWORD nBytes; HANDLE hFile; int result; Blt_DBuffer_Free(dbuffer); hFile = (HANDLE)fd; nBytes = 0; for (;;) { DWORD nRead; char *bp; bp = Blt_DBuffer_Extend(dbuffer, BUFFER_SIZE); if (!ReadFile(hFile, bp, BUFFER_SIZE, &nRead, NULL)) { DWORD err; err = GetLastError(); if ((err != ERROR_BROKEN_PIPE) && (err != ERROR_HANDLE_EOF)) { Tcl_AppendResult(interp, "error reading from ghostscript: ", Blt_PrintError(err), (char *)NULL); result = TCL_ERROR; break; } } if (nRead == 0) { result = TCL_OK; break; /* EOF */ } nBytes += nRead; Blt_DBuffer_SetLength(dbuffer, nBytes); } Blt_DBuffer_SetLength(dbuffer, nBytes); CloseHandle(hFile); return result; } #else /* WIN32 */ static int WriteToGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { pid_t child; child = fork(); if (child == -1) { Tcl_AppendResult(interp, "can't fork process: ", Tcl_PosixError(interp), (char *)NULL); return 0; } else if (child > 0) { close(fd); return child; } else { const char *bytes; int nWritten, nBytes; bytes = (const char *)Blt_DBuffer_Bytes(dbuffer); nBytes = Blt_DBuffer_Length(dbuffer); nWritten = write(fd, bytes, nBytes); close(fd); if (nWritten != nBytes) { exit(1); } exit(0); } } static int ReadFromGhostscript(Tcl_Interp *interp, int fd, Blt_DBuffer dbuffer) { int nBytes; Blt_DBuffer_Free(dbuffer); nBytes = 0; for (;;) { char *bp; int nRead; bp = (char *)Blt_DBuffer_Extend(dbuffer, BUFFER_SIZE); nRead = read(fd, bp, BUFFER_SIZE); if (nRead == 0) { break; /* EOF */ } else if (nRead < 0) { Tcl_AppendResult(interp, "error reading from ghostscript: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } nBytes += nRead; Blt_DBuffer_SetLength(dbuffer, nBytes); } Blt_DBuffer_SetLength(dbuffer, nBytes); close(fd); return TCL_OK; } #endif /* WIN32 */ static int PsToPbm( Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PsImportSwitches *switchesPtr) { int in, out; /* File descriptors for ghostscript * subprocess. */ char string1[200]; char string2[200]; int nPids; ProcessId *pidPtr; int result; pid_t child; const char **p; const char *args[] = { "gs", /* Ghostscript command */ "-dEPSCrop", /* (optional) crop page to bbox */ "-dSAFER", /* */ "-q", /* Quiet mode. No GS messages. */ "-sDEVICE=ppmraw", /* Format is PPM raw */ "-dBATCH", /* Batch mode. No "quit" necessary. */ "-sPAPERSIZE=letter", /* (optional) Specify paper size. */ "-r100x100", /* (optional) Specify DPI of X screen */ "-dNOPAUSE", /* */ "-sOutputFile=-", /* Output file is stdout. */ "-", NULL }; args[1] = (switchesPtr->crop) ? "-dEPSCrop" : "-dSAFER"; { Tk_Window tkwin; unsigned int xdpi, ydpi; tkwin = Tk_MainWindow(interp); if (switchesPtr->dpi > 0) { xdpi = ydpi = switchesPtr->dpi; } else { Blt_ScreenDPI(tkwin, &xdpi, &ydpi); } sprintf(string1, "-r%dx%d", xdpi, ydpi); args[7] = string1; } if (switchesPtr->paperSize != NULL) { sprintf(string2, "-sPAPERSIZE=%s", switchesPtr->paperSize); args[6] = string2; } { int i; Tcl_Obj *objv[11]; int objc = 11; for (i = 0, p = args; *p != NULL; p++, i++) { objv[i] = Tcl_NewStringObj(*p, -1); Tcl_IncrRefCount(objv[i]); } nPids = Blt_CreatePipeline(interp, objc, objv, &pidPtr, &in, &out, (int *)NULL); for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objv[i]); } } if (nPids < 0) { return TCL_ERROR; } Tcl_DetachPids(nPids, (Tcl_Pid *)pidPtr); child = WriteToGhostscript(interp, in, dbuffer); if (child == 0) { return TCL_ERROR; } result = ReadFromGhostscript(interp, out, dbuffer); #ifdef WIN32 CloseHandle((HANDLE)child); #endif Tcl_ReapDetachedProcs(); #ifdef notdef Blt_DBuffer_SaveFile(interp, "junk.ppm", dbuffer); #endif if (result != TCL_OK) { Blt_DBuffer_Free(dbuffer); return TCL_ERROR; } return TCL_OK; } static Blt_Chain PsToPicture( Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, PsImportSwitches *switchesPtr) { Blt_Chain chain; if (PsToPbm(interp, fileName, dbuffer, switchesPtr) != TCL_OK) { return NULL; } /* Can be more than one image in buffer. Save each picture in a list. */ chain = Blt_Chain_Create(); while (Blt_DBuffer_BytesLeft(dbuffer) > 0) { Blt_Picture picture; picture = PbmToPicture(interp, dbuffer); if (picture == NULL) { Blt_Chain_Destroy(chain); return NULL; } Blt_Chain_Append(chain, picture); } return chain; } static int PictureToPs(Tcl_Interp *interp, Blt_Picture original, Blt_Ps ps, PsExportSwitches *switchesPtr) { Picture *srcPtr; int w, h; srcPtr = original; w = srcPtr->width, h = srcPtr->height; Blt_Ps_ComputeBoundingBox(&switchesPtr->setup, w, h); if (PostScriptPreamble(interp, srcPtr, switchesPtr, ps) != TCL_OK) { return TCL_ERROR; } Blt_ClassifyPicture(srcPtr); if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); srcPtr = background; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(srcPtr); } Blt_Ps_Rectangle(ps, 0, 0, srcPtr->width, srcPtr->height); Blt_Ps_Append(ps, "gsave clip\n\n"); Blt_Ps_DrawPicture(ps, srcPtr, 0, 0); Blt_Ps_VarAppend(ps, "\n", "% Unset clipping\n", "grestore\n\n", (char *)NULL); Blt_Ps_VarAppend(ps, "showpage\n", "%Trailer\n", "grestore\n", "end\n", "%EOF\n", (char *)NULL); if (srcPtr != original) { Blt_Free(srcPtr); } return TCL_OK; } static int IsPs(Blt_DBuffer dbuffer) { unsigned char *bp; Blt_DBuffer_ResetCursor(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < 4) { return FALSE; } bp = Blt_DBuffer_Pointer(dbuffer); return (strncmp("%!PS", (char *)bp, 4) == 0); } static Blt_Chain ReadPs(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { Blt_Chain chain; PsImportSwitches switches; memset(&switches, 0, sizeof(switches)); switches.crop = TRUE; chain = PsToPicture(interp, fileName, dbuffer, &switches); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return chain; } static Tcl_Obj * WritePs(Tcl_Interp *interp, Blt_Picture picture) { Blt_Ps ps; PsExportSwitches switches; Tcl_Obj *objPtr; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.setup.reqPaperHeight = 792; /* 11 inches */ switches.setup.reqPaperWidth = 612; /* 8.5 inches */ switches.setup.level = 1; switches.setup.xPad.side1 = 72; switches.setup.xPad.side2 = 72; switches.setup.yPad.side1 = 72; switches.setup.yPad.side2 = 72; switches.setup.flags = 0; ps = Blt_Ps_Create(interp, &switches.setup); result = PictureToPs(interp, picture, ps, &switches); objPtr = NULL; if (result == TCL_OK) { const char *string; int length; string = Blt_Ps_GetValue(ps, &length); objPtr = Tcl_NewStringObj(string, length); } Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_Ps_Free(ps); return objPtr; } static Blt_Chain ImportPs( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer dbuffer; PsImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); switches.crop = TRUE; if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); return NULL; } chain = NULL; dbuffer = Blt_DBuffer_Create(); if (switches.dataObjPtr != NULL) { int nBytes; string = Tcl_GetStringFromObj(switches.dataObjPtr, &nBytes); Blt_DBuffer_AppendData(dbuffer, (unsigned char *)string, nBytes); string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); if (Blt_DBuffer_LoadFile(interp, string, dbuffer) != TCL_OK) { Blt_DBuffer_Destroy(dbuffer); return NULL; } *fileNamePtr = string; } chain = PsToPicture(interp, string, dbuffer, &switches); Blt_DBuffer_Destroy(dbuffer); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return chain; } static int ExportPs(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { PsExportSwitches switches; Blt_Ps ps; int result; Blt_Picture picture; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; /* Default bgcolor is white. */ switches.setup.reqPaperHeight = 792; /* 11 inches */ switches.setup.reqPaperWidth = 612; /* 8.5 inches */ switches.setup.level = 1; switches.setup.xPad.side1 = 72; switches.setup.xPad.side2 = 72; switches.setup.yPad.side1 = 72; switches.setup.yPad.side2 = 72; switches.setup.flags = 0; switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data switch.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } ps = Blt_Ps_Create(interp, &switches.setup); result = PictureToPs(interp, picture, ps, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_Ps_SaveFile(interp, ps, fileName); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; int length; const char *string; string = Blt_Ps_GetValue(ps, &length); objPtr = Tcl_NewStringObj(string, length); objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, objPtr, 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { const char *string; int length; string = Blt_Ps_GetValue(ps, &length); Tcl_SetStringObj(Tcl_GetObjResult(interp), string, length); } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_Ps_Free(ps); return result; } int Blt_PicturePsInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_ps", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "ps", /* Name of format. */ IsPs, /* Discovery routine. */ ReadPs, /* Import format procedure. */ WritePs, /* Export format procedure. */ ImportPs, /* Import format procedure. */ ExportPs); /* Export format procedure. */ } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMath.h���������������������������������������������������������������������0000644�0001750�0001750�00000012116�11462120062�014572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMath.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_MATH_H #define _BLT_MATH_H #include <math.h> #ifdef HAVE_FLOAT_H #include <float.h> #endif /* HAVE_FLOAT_H */ #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif /* HAVE_IEEEFP_H */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* M_PI */ #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif /* M_PI_2 */ #ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880 #endif /* M_SQRT2 */ #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440 #endif /* M_SQRT1_2 */ #ifndef SHRT_MAX #define SHRT_MAX 0x7FFF #endif /* SHRT_MAX */ #ifndef SHRT_MIN #define SHRT_MIN -(SHRT_MAX) #endif /* SHRT_MAX */ #ifndef USHRT_MAX #define USHRT_MAX 0xFFFF #endif /* USHRT_MAX */ #ifndef INT_MAX #define INT_MAX 2147483647 #endif /* INT_MAX */ #ifndef HAVE_FLOAT_H /* *--------------------------------------------------------------------------- * * DBL_MIN, DBL_MAX -- * * DBL_MAX and DBL_MIN are the largest and smaller double * precision numbers that can be represented by the floating * point hardware. If the compiler is ANSI, they can be found in * float.h. Otherwise, we use HUGE_VAL or HUGE to determine * them. * *--------------------------------------------------------------------------- */ /* * Don't want to include __infinity (definition of HUGE_VAL (SC1.x)) */ #ifdef sun #define DBL_MAX 1.7976931348623157E+308 #define DBL_MIN 2.2250738585072014E-308 #define DBL_EPSILON 2.2204460492503131e-16 #else #ifndef DBL_EPSILON #define DBL_EPSILON BLT_DBL_EPSILON #endif #ifdef HUGE_VAL #define DBL_MAX HUGE_VAL #define DBL_MIN (1/HUGE_VAL) #else #ifdef HUGE #define DBL_MAX HUGE #define DBL_MIN (1/HUGE) #else /* * Punt: Assume relatively small values */ #define DBL_MAX 3.40282347E+38 #define DBL_MIN 1.17549435E-38 #endif /*HUGE*/ #endif /*HUGE_VAL*/ #endif /*sun*/ #endif /*!HAVE_FLOAT_H*/ /* *--------------------------------------------------------------------------- * * The following are macros replacing math library functions: * "fabs", "fmod", "abs", "rint", and "exp10". * * Although many of these routines may exist in your math * library, they aren't used in libtcl.a or libtk.a. This makes * it difficult to dynamically load the BLT library as a shared * object unless the math library is also shared (which isn't * true on several systems). We can avoid the problem by * replacing the "exotic" math routines with macros. * *--------------------------------------------------------------------------- */ #undef ABS #define ABS(x) (((x)<0)?(-(x)):(x)) #undef EXP10 #define EXP10(x) (pow(10.0,(x))) #undef FABS #define FABS(x) (((x)<0.0)?(-(x)):(x)) #undef SIGN #define SIGN(x) (((x) < 0.0) ? -1 : 1) /* * Be careful when using the next two macros. They both assume the floating * point number is less than the size of an int. That means, for example, you * can't use these macros with numbers bigger than than 2^31-1. */ #undef FMOD #define FMOD(x,y) ((x)-(((int)((x)/(y)))*y)) #undef ROUND #define ROUND(x) ((int)((x) + (((x)<0.0) ? -0.5 : 0.5))) #ifdef HAVE_FINITE #define FINITE(x) finite(x) #else #ifdef HAVE_ISFINITE #define FINITE(x) isfinite(x) #else #ifdef HAVE_ISNAN #define FINITE(x) (!isnan(x)) #else #define FINITE(x) (TRUE) #endif /* HAVE_ISNAN */ #endif /* HAVE_ISFINITE */ #endif /* HAVE_FINITE */ #define DEFINED(x) (!isnan(x)) #define UNDEFINED(x) (isnan(x)) #if !HAVE_DECL_DRAND48 BLT_EXTERN double drand48(void); #endif /* !HAVE_DECL_DRAND48 */ #if !HAVE_DECL_SRAND48 BLT_EXTERN void srand48(long seed); #endif /* !HAVE_DECL_SRAND48 */ #if !HAVE_DECL_J1 BLT_EXTERN double j1(double x); #endif /* !HAVE_DECL_J1 */ #if !HAVE_DECL_HYPOT BLT_EXTERN double hypot(double x, double y); #endif /* !HAVE_DECL_HYPOT */ #ifdef HAVE_ISNAN #if !HAVE_DECL_ISNAN BLT_EXTERN int isnan(double x); #endif /* !HAVE_DECL_ISNAN */ #endif /* HAVE_ISNAN */ #ifdef HAVE_FINITE #if !HAVE_DECL_FINITE BLT_EXTERN int finite(double x); #endif /* !HAVE_DECL_FINITE */ #endif /* HAVE_FINITE */ #endif /* BLT_MATH_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVar.c����������������������������������������������������������������������0000644�0001750�0001750�00000002637�11462120063�014434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVar.c -- * * This module implements TCL variable handler procedures for the BLT * toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include "bltNsUtil.h" #include "bltVar.h" #include <bltList.h> #if (_TK_VERSION > _VERSION(8,5,0)) #include "bltVar85.c" #else #include "bltVar84.c" #endif �������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGraph.c��������������������������������������������������������������������0000644�0001750�0001750�00000222427�11462120062�014745� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGraph.c -- * * This module implements a graph widget for the BLT toolkit. * * The graph widget was created by Sani Nassif and George Howlett. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * To do: * * 2) Update manual pages. * * 3) Update comments. * * 5) Surface, contour, and flow graphs * * 7) Arrows for line markers * */ #include "bltGraph.h" #include "bltOp.h" #include "bltBind.h" #include "bltGrElem.h" #include "bltGrLegd.h" #include "bltSwitch.h" #include <X11/Xutil.h> #include "tkDisplay.h" #include "bltPicture.h" typedef int (GraphCmdProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* * Objects in the graph have their own class names. These class names are * used for the resource database and bindings. Example. * * option add *X.title "X Axis Title" widgetDefault * .g marker bind BitmapMarker <Enter> { ... } * * The option database trick is performed by creating a temporary window when * an object is initially configured. The class name of the temporary window * will be from the list below. */ static const char *objectClassNames[] = { "unknown", "XAxis", "YAxis", "BarElement", "ContourElement", "LineElement", "StripElement", "BitmapMarker", "ImageMarker", "LineMarker", "PolygonMarker", "TextMarker", "WindowMarker", }; BLT_EXTERN Blt_CustomOption bltLinePenOption; BLT_EXTERN Blt_CustomOption bltBarPenOption; BLT_EXTERN Blt_CustomOption bltBarModeOption; #define DEF_GRAPH_ASPECT_RATIO "0.0" #define DEF_GRAPH_BAR_BASELINE "0.0" #define DEF_GRAPH_BAR_MODE "normal" #define DEF_GRAPH_BAR_WIDTH "0.9" #define DEF_GRAPH_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_GRAPH_BORDERWIDTH STD_BORDERWIDTH #define DEF_GRAPH_BUFFER_ELEMENTS "yes" #define DEF_GRAPH_BUFFER_GRAPH "1" #define DEF_GRAPH_CURSOR "crosshair" #define DEF_GRAPH_FONT "{Sans Serif} 12" #define DEF_GRAPH_HALO "2m" #define DEF_GRAPH_HALO_BAR "0.1i" #define DEF_GRAPH_HEIGHT "4i" #define DEF_GRAPH_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_GRAPH_HIGHLIGHT_COLOR RGB_BLACK #define DEF_GRAPH_HIGHLIGHT_WIDTH "2" #define DEF_GRAPH_INVERT_XY "0" #define DEF_GRAPH_JUSTIFY "center" #define DEF_GRAPH_MARGIN "0" #define DEF_GRAPH_MARGIN_VAR (char *)NULL #define DEF_GRAPH_PLOT_BACKGROUND RGB_WHITE #define DEF_GRAPH_PLOT_BORDERWIDTH "1" #define DEF_GRAPH_PLOT_PADX "0" #define DEF_GRAPH_PLOT_PADY "0" #define DEF_GRAPH_PLOT_RELIEF "solid" #define DEF_GRAPH_RELIEF "flat" #define DEF_GRAPH_SHOW_VALUES "no" #define DEF_GRAPH_STACK_AXES "no" #define DEF_GRAPH_TAKE_FOCUS "" #define DEF_GRAPH_TITLE (char *)NULL #define DEF_GRAPH_TITLE_COLOR STD_NORMAL_FOREGROUND #define DEF_GRAPH_WIDTH "5i" #define DEF_GRAPH_DATA (char *)NULL #define DEF_GRAPH_DATA_COMMAND (char *)NULL #define DEF_GRAPH_UNMAP_HIDDEN_ELEMENTS "0" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_FLOAT, "-aspect", "aspect", "Aspect", DEF_GRAPH_ASPECT_RATIO, Blt_Offset(Graph, aspect), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_GRAPH_BACKGROUND, Blt_Offset(Graph, normalBg), 0}, {BLT_CONFIG_CUSTOM, "-barmode", "barMode", "BarMode", DEF_GRAPH_BAR_MODE, Blt_Offset(Graph, mode), BLT_CONFIG_DONT_SET_DEFAULT, &bltBarModeOption}, {BLT_CONFIG_FLOAT, "-barwidth", "barWidth", "BarWidth", DEF_GRAPH_BAR_WIDTH, Blt_Offset(Graph, barWidth), 0}, {BLT_CONFIG_FLOAT, "-baseline", "baseline", "Baseline", DEF_GRAPH_BAR_BASELINE, Blt_Offset(Graph, baseline), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL,0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bm", "bottomMargin", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_GRAPH_BORDERWIDTH, Blt_Offset(Graph, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-bottommargin", "bottomMargin", "Margin", DEF_GRAPH_MARGIN, Blt_Offset(Graph, bottomMargin.reqSize), 0}, {BLT_CONFIG_STRING, "-bottomvariable", "bottomVariable", "BottomVariable", DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, bottomMargin.varName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-bufferelements", "bufferElements", "BufferElements", DEF_GRAPH_BUFFER_ELEMENTS, Blt_Offset(Graph, backingStore), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-buffergraph", "bufferGraph", "BufferGraph", DEF_GRAPH_BUFFER_GRAPH, Blt_Offset(Graph, doubleBuffer), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_GRAPH_CURSOR, Blt_Offset(Graph, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-data", "data", "Data", (char *)NULL, Blt_Offset(Graph, data), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-datacommand", "dataCommand", "DataCommand", (char *)NULL, Blt_Offset(Graph, dataCmd), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_GRAPH_FONT, Blt_Offset(Graph, titleTextStyle.font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_GRAPH_TITLE_COLOR, Blt_Offset(Graph, titleTextStyle.color), 0}, {BLT_CONFIG_PIXELS_NNEG, "-halo", "halo", "Halo", DEF_GRAPH_HALO, Blt_Offset(Graph, halo), 0}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_GRAPH_HEIGHT, Blt_Offset(Graph, reqHeight), 0}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_GRAPH_HIGHLIGHT_BACKGROUND, Blt_Offset(Graph, highlightBgColor), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_GRAPH_HIGHLIGHT_COLOR, Blt_Offset(Graph, highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_GRAPH_HIGHLIGHT_WIDTH, Blt_Offset(Graph, highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-unmaphiddenelements", "unmapHiddenElements", "UnmapHiddenElements", DEF_GRAPH_UNMAP_HIDDEN_ELEMENTS, Blt_Offset(Graph, flags), ALL_GRAPHS | BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)UNMAP_HIDDEN}, {BLT_CONFIG_BOOLEAN, "-invertxy", "invertXY", "InvertXY", DEF_GRAPH_INVERT_XY, Blt_Offset(Graph, inverted), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_GRAPH_JUSTIFY, Blt_Offset(Graph, titleTextStyle.justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-leftmargin", "leftMargin", "Margin", DEF_GRAPH_MARGIN, Blt_Offset(Graph, leftMargin.reqSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-leftvariable", "leftVariable", "LeftVariable", DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, leftMargin.varName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-lm", "leftMargin", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BACKGROUND, "-plotbackground", "plotBackground", "Background", DEF_GRAPH_PLOT_BACKGROUND, Blt_Offset(Graph, plotBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-plotborderwidth", "plotBorderWidth", "PlotBorderWidth", DEF_GRAPH_PLOT_BORDERWIDTH, Blt_Offset(Graph, plotBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-plotpadx", "plotPadX", "PlotPad", DEF_GRAPH_PLOT_PADX, Blt_Offset(Graph, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-plotpady", "plotPadY", "PlotPad", DEF_GRAPH_PLOT_PADY, Blt_Offset(Graph, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-plotrelief", "plotRelief", "Relief", DEF_GRAPH_PLOT_RELIEF, Blt_Offset(Graph, plotRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_GRAPH_RELIEF, Blt_Offset(Graph, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-rightmargin", "rightMargin", "Margin", DEF_GRAPH_MARGIN, Blt_Offset(Graph, rightMargin.reqSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-rightvariable", "rightVariable", "RightVariable", DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, rightMargin.varName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-rm", "rightMargin", (char *)NULL, (char *)NULL, 0,0}, {BLT_CONFIG_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes", DEF_GRAPH_STACK_AXES, Blt_Offset(Graph, stackAxes), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_GRAPH_TAKE_FOCUS, Blt_Offset(Graph, takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-title", "title", "Title", DEF_GRAPH_TITLE, Blt_Offset(Graph, title), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-tm", "topMargin", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-topmargin", "topMargin", "Margin", DEF_GRAPH_MARGIN, Blt_Offset(Graph, topMargin.reqSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-topvariable", "topVariable", "TopVariable", DEF_GRAPH_MARGIN_VAR, Blt_Offset(Graph, topMargin.varName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_GRAPH_WIDTH, Blt_Offset(Graph, reqWidth), 0}, {BLT_CONFIG_PIXELS_NNEG, "-plotwidth", "plotWidth", "PlotWidth", (char *)NULL, Blt_Offset(Graph, reqPlotWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-plotheight", "plotHeight", "PlotHeight", (char *)NULL, Blt_Offset(Graph, reqPlotHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_SwitchParseProc ObjToFormat; static Blt_SwitchCustom formatSwitch = { ObjToFormat, NULL, (ClientData)0, }; typedef struct { const char *name; int width, height; int format; } SnapSwitches; enum SnapFormats { FORMAT_PICTURE, FORMAT_PHOTO, FORMAT_EMF, FORMAT_WMF }; static Blt_SwitchSpec snapSwitches[] = { {BLT_SWITCH_INT_POS, "-width", "width", Blt_Offset(SnapSwitches, width), 0}, {BLT_SWITCH_INT_POS, "-height", "height", Blt_Offset(SnapSwitches, height), 0}, {BLT_SWITCH_CUSTOM, "-format", "format", Blt_Offset(SnapSwitches, format), 0, 0, &formatSwitch}, {BLT_SWITCH_END} }; static Tcl_IdleProc DisplayGraph; static Tcl_FreeProc DestroyGraph; static Tk_EventProc GraphEventProc; Tcl_ObjCmdProc Blt_GraphInstCmdProc; static Blt_BindPickProc PickEntry; static Tcl_ObjCmdProc StripchartCmd; static Tcl_ObjCmdProc BarchartCmd; static Tcl_ObjCmdProc GraphCmd; static Tcl_CmdDeleteProc GraphInstCmdDeleteProc; /* *--------------------------------------------------------------------------- * * Blt_UpdateGraph -- * * Tells the Tk dispatcher to call the graph display routine at the next * idle point. This request is made only if the window is displayed and * no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ void Blt_UpdateGraph(ClientData clientData) { Graph *graphPtr = clientData; graphPtr->flags |= REDRAW_WORLD; if ((graphPtr->tkwin != NULL) && !(graphPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayGraph, graphPtr); graphPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * Blt_EventuallyRedrawGraph -- * * Tells the Tk dispatcher to call the graph display routine at the next * idle point. This request is made only if the window is displayed and * no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ void Blt_EventuallyRedrawGraph(Graph *graphPtr) { if ((graphPtr->tkwin != NULL) && !(graphPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayGraph, graphPtr); graphPtr->flags |= REDRAW_PENDING; } } const char * Blt_GraphClassName(ClassId classId) { if ((classId >= CID_NONE) && (classId <= CID_MARKER_WINDOW)) { return objectClassNames[classId]; } return NULL; } void Blt_GraphSetObjectClass(GraphObj *graphObjPtr, ClassId classId) { graphObjPtr->classId = classId; graphObjPtr->className = Blt_GraphClassName(classId); } /* *--------------------------------------------------------------------------- * * GraphEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * graphs. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, the graph is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void GraphEventProc(ClientData clientData, XEvent *eventPtr) { Graph *graphPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { graphPtr->flags |= REDRAW_WORLD; Blt_EventuallyRedrawGraph(graphPtr); } } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { graphPtr->flags |= FOCUS; } else { graphPtr->flags &= ~FOCUS; } graphPtr->flags |= REDRAW_WORLD; Blt_EventuallyRedrawGraph(graphPtr); } } else if (eventPtr->type == DestroyNotify) { if (graphPtr->tkwin != NULL) { Blt_DeleteWindowInstanceData(graphPtr->tkwin); graphPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(graphPtr->interp, graphPtr->cmdToken); } if (graphPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayGraph, graphPtr); } Tcl_EventuallyFree(graphPtr, DestroyGraph); } else if (eventPtr->type == ConfigureNotify) { graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); Blt_EventuallyRedrawGraph(graphPtr); } } /* *--------------------------------------------------------------------------- * * GraphInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void GraphInstCmdDeleteProc(ClientData clientData) /* Pointer to widget record. */ { Graph *graphPtr = clientData; if (graphPtr->tkwin != NULL) { /* NULL indicates window has already * been destroyed. */ Tk_Window tkwin; tkwin = graphPtr->tkwin; graphPtr->tkwin = NULL; Blt_DeleteWindowInstanceData(tkwin); Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * AdjustAxisPointers -- * * Sets the axis pointers according to whether the axis is inverted on * not. The axis sites are also reset. * * Results: * None. * *--------------------------------------------------------------------------- */ static void AdjustAxisPointers(Graph *graphPtr) { if (graphPtr->inverted) { graphPtr->leftMargin.axes = graphPtr->axisChain[0]; graphPtr->bottomMargin.axes = graphPtr->axisChain[1]; graphPtr->rightMargin.axes = graphPtr->axisChain[2]; graphPtr->topMargin.axes = graphPtr->axisChain[3]; } else { graphPtr->leftMargin.axes = graphPtr->axisChain[1]; graphPtr->bottomMargin.axes = graphPtr->axisChain[0]; graphPtr->rightMargin.axes = graphPtr->axisChain[3]; graphPtr->topMargin.axes = graphPtr->axisChain[2]; } } static int InitPens(Graph *graphPtr) { Blt_InitHashTable(&graphPtr->penTable, BLT_STRING_KEYS); if (Blt_CreatePen(graphPtr, "activeLine", CID_ELEM_LINE, 0, NULL) == NULL) { return TCL_ERROR; } if (Blt_CreatePen(graphPtr, "activeBar", CID_ELEM_BAR, 0, NULL) == NULL) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GraphTags -- * * Sets the binding tags for a graph obj. This routine is called by Tk * when an event occurs in the graph. It fills an array of pointers with * bind tag addresses. * * The object addresses are strings hashed in one of two tag tables: one * for elements and the another for markers. Note that there's only one * binding table for elements and markers. [We don't want to trigger * both a marker and element bind command for the same event.] But we * don't want a marker and element with the same tag name to activate the * others bindings. A tag "all" for markers should mean all markers, not * all markers and elements. As a result, element and marker tags are * stored in separate hash tables, which means we can't generate the same * tag address for both an elements and marker, even if they have the * same name. * * Results: * None. * * Side effects: * This information will be used by the binding code in bltUtil.c to * determine what graph objects match the current event. The tags are * placed in tagArr and *nTagsPtr is set with the number of tags found. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ void Blt_GraphTags( Blt_BindTable table, ClientData object, ClientData context, /* Not used. */ Blt_List list) { GraphObj *graphObjPtr; MakeTagProc *tagProc; Graph *graphPtr; graphPtr = (Graph *)Blt_GetBindingData(table); /* * All graph objects (markers, elements, axes, etc) have the same starting * fields in their structures, such as "classId", "name", "className", and * "tags". */ graphObjPtr = (GraphObj *)object; switch (graphObjPtr->classId) { case CID_ELEM_BAR: case CID_ELEM_CONTOUR: case CID_ELEM_LINE: case CID_ELEM_STRIP: tagProc = Blt_MakeElementTag; break; case CID_AXIS_X: case CID_AXIS_Y: tagProc = Blt_MakeAxisTag; break; case CID_MARKER_BITMAP: case CID_MARKER_IMAGE: case CID_MARKER_LINE: case CID_MARKER_POLYGON: case CID_MARKER_TEXT: case CID_MARKER_WINDOW: tagProc = Blt_MakeMarkerTag; break; case CID_NONE: panic("unknown object type"); tagProc = NULL; break; default: panic("bogus object type"); tagProc = NULL; break; } assert(graphObjPtr->name != NULL); /* Always add the name of the object to the tag array. */ Blt_List_Append(list, (*tagProc)(graphPtr, graphObjPtr->name), 0); Blt_List_Append(list, (*tagProc)(graphPtr, graphObjPtr->className), 0); if (graphObjPtr->tags != NULL) { const char **p; for (p = graphObjPtr->tags; *p != NULL; p++) { Blt_List_Append(list, (*tagProc) (graphPtr, *p), 0); } } } /* * Find the closest point from the set of displayed elements, searching * the display list from back to front. That way, if the points from * two different elements overlay each other exactly, the one that's on * top (visible) is picked. */ /*ARGSUSED*/ static ClientData PickEntry(ClientData clientData, int x, int y, ClientData *contextPtr) { Graph *graphPtr = clientData; Blt_ChainLink link; Element *elemPtr; Marker *markerPtr; Region2d exts; if (graphPtr->flags & MAP_ALL) { return NULL; /* Don't pick anything until the next * redraw occurs. */ } Blt_GraphExtents(graphPtr, &exts); if ((x >= exts.right) || (x < exts.left) || (y >= exts.bottom) || (y < exts.top)) { /* * Sample coordinate is in one of the graph margins. Can only pick an * axis. */ return Blt_NearestAxis(graphPtr, x, y); } /* * From top-to-bottom check: * 1. markers drawn on top (-under false). * 2. elements using its display list back to front. * 3. markers drawn under element (-under true). */ markerPtr = Blt_NearestMarker(graphPtr, x, y, FALSE); if (markerPtr != NULL) { return markerPtr; /* Found a marker (-under false). */ } { ClosestSearch search; search.along = SEARCH_BOTH; search.halo = graphPtr->halo; search.index = -1; search.x = x; search.y = y; search.dist = (double)(search.halo + 1); search.mode = SEARCH_AUTO; for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { elemPtr = Blt_Chain_GetValue(link); if (elemPtr->flags & (HIDE|MAP_ITEM)) { continue; } if (elemPtr->state == STATE_NORMAL) { (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search); } } if (search.dist <= (double)search.halo) { return search.elemPtr; /* Found an element within the minimum * halo distance. */ } } markerPtr = Blt_NearestMarker(graphPtr, x, y, TRUE); if (markerPtr != NULL) { return markerPtr; /* Found a marker (-under true) */ } return NULL; /* Nothing found. */ } /* *--------------------------------------------------------------------------- * * ConfigureGraph -- * * Allocates resources for the graph. * * Results: * None. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for graphPtr; old resources get freed, if there were any. The * graph is redisplayed. * *--------------------------------------------------------------------------- */ static void ConfigureGraph(Graph *graphPtr) { XColor *colorPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; /* Don't allow negative bar widths. Reset to an arbitrary value (0.1) */ if (graphPtr->barWidth <= 0.0f) { graphPtr->barWidth = 0.8f; } graphPtr->inset = graphPtr->borderWidth + graphPtr->highlightWidth; if ((graphPtr->reqHeight != Tk_ReqHeight(graphPtr->tkwin)) || (graphPtr->reqWidth != Tk_ReqWidth(graphPtr->tkwin))) { Tk_GeometryRequest(graphPtr->tkwin, graphPtr->reqWidth, graphPtr->reqHeight); } Tk_SetInternalBorder(graphPtr->tkwin, graphPtr->borderWidth); colorPtr = Blt_BackgroundBorderColor(graphPtr->normalBg); graphPtr->titleWidth = graphPtr->titleHeight = 0; if (graphPtr->title != NULL) { unsigned int w, h; Blt_Ts_GetExtents(&graphPtr->titleTextStyle, graphPtr->title, &w, &h); graphPtr->titleHeight = h; } /* * Create GCs for interior and exterior regions, and a background GC for * clearing the margins with XFillRectangle */ /* Margin GC */ gcValues.foreground = Blt_Ts_GetForeground(graphPtr->titleTextStyle)->pixel; gcValues.background = colorPtr->pixel; gcMask = (GCForeground | GCBackground); newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (graphPtr->drawGC != NULL) { Tk_FreeGC(graphPtr->display, graphPtr->drawGC); } graphPtr->drawGC = newGC; if (graphPtr->plotBg != NULL) { Blt_SetBackgroundChangedProc(graphPtr->plotBg, Blt_UpdateGraph, graphPtr); } if (graphPtr->normalBg != NULL) { Blt_SetBackgroundChangedProc(graphPtr->normalBg, Blt_UpdateGraph, graphPtr); } if (Blt_ConfigModified(configSpecs, "-invertxy", (char *)NULL)) { /* * If the -inverted option changed, we need to readjust the pointers * to the axes and recompute the their scales. */ AdjustAxisPointers(graphPtr); graphPtr->flags |= RESET_AXES; } if ((!graphPtr->backingStore) && (graphPtr->cache != None)) { /* * Free the pixmap if we're not buffering the display of elements * anymore. */ Tk_FreePixmap(graphPtr->display, graphPtr->cache); graphPtr->cache = None; } /* * Reconfigure the crosshairs, just in case the background color of the * plotarea has been changed. */ Blt_ConfigureCrosshairs(graphPtr); /* * Update the layout of the graph (and redraw the elements) if any of the * following graph options which affect the size of * the plotting area * has changed. * * -aspect * -borderwidth, -plotborderwidth * -font, -title * -width, -height * -invertxy * -bottommargin, -leftmargin, -rightmargin, -topmargin, * -barmode, -barwidth */ if (Blt_ConfigModified(configSpecs, "-invertxy", "-title", "-font", "-*margin", "-*width", "-height", "-barmode", "-*pad*", "-aspect", "-*borderwidth", "-plot*", "-*width", "-*height", "-unmaphiddenelements", (char *)NULL)) { graphPtr->flags |= RESET_WORLD | CACHE_DIRTY; } if (Blt_ConfigModified(configSpecs, "-plot*", "-*background", (char *)NULL)) { graphPtr->flags |= CACHE_DIRTY; } graphPtr->flags |= REDRAW_WORLD; } /* *--------------------------------------------------------------------------- * * DestroyGraph -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of a graph at a safe time (when no-one * is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyGraph(DestroyData dataPtr) { Graph *graphPtr = (Graph *)dataPtr; Blt_FreeOptions(configSpecs, (char *)graphPtr, graphPtr->display, 0); /* * Destroy the individual components of the graph: elements, markers, * axes, legend, display lists etc. Be careful to remove them in * order. For example, axes are used by elements and markers, so they have * to be removed after the markers and elements. Same it true with the * legend and pens (they use elements), so can't be removed until the * elements are destroyed. */ Blt_DestroyMarkers(graphPtr); Blt_DestroyElements(graphPtr); Blt_DestroyLegend(graphPtr); Blt_DestroyAxes(graphPtr); Blt_DestroyPens(graphPtr); Blt_DestroyCrosshairs(graphPtr); Blt_DestroyPageSetup(graphPtr); Blt_DestroyBarSets(graphPtr); /* Destroy table clients after elements are destroyed. */ Blt_DestroyTableClients(graphPtr); if (graphPtr->bindTable != NULL) { Blt_DestroyBindingTable(graphPtr->bindTable); } /* Release allocated X resources and memory. */ if (graphPtr->drawGC != NULL) { Tk_FreeGC(graphPtr->display, graphPtr->drawGC); } Blt_Ts_FreeStyle(graphPtr->display, &graphPtr->titleTextStyle); if (graphPtr->cache != None) { Tk_FreePixmap(graphPtr->display, graphPtr->cache); } Blt_Free(graphPtr); } /* *--------------------------------------------------------------------------- * * CreateGraph -- * * This procedure creates and initializes a new widget. * * Results: * The return value is a pointer to a structure describing the new * widget. If an error occurred, then the return value is NULL and an * error message is left in interp->result. * * Side effects: * Memory is allocated, a Tk_Window is created, etc. * *--------------------------------------------------------------------------- */ static Graph * CreateGraph(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId) { Graph *graphPtr; Tk_Window tkwin; tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *)NULL); if (tkwin == NULL) { return NULL; } graphPtr = Blt_AssertCalloc(1, sizeof(Graph)); /* Initialize the graph data structure. */ graphPtr->tkwin = tkwin; graphPtr->display = Tk_Display(tkwin); graphPtr->interp = interp; graphPtr->classId = classId; graphPtr->backingStore = TRUE; graphPtr->doubleBuffer = TRUE; graphPtr->borderWidth = 2; graphPtr->plotBW = 1; graphPtr->highlightWidth = 2; graphPtr->plotRelief = TK_RELIEF_SOLID; graphPtr->relief = TK_RELIEF_FLAT; graphPtr->flags = RESET_WORLD; graphPtr->nextMarkerId = 1; graphPtr->padLeft = graphPtr->padRight = 0; graphPtr->padTop = graphPtr->padBottom = 0; graphPtr->bottomMargin.site = MARGIN_BOTTOM; graphPtr->leftMargin.site = MARGIN_LEFT; graphPtr->topMargin.site = MARGIN_TOP; graphPtr->rightMargin.site = MARGIN_RIGHT; Blt_Ts_InitStyle(graphPtr->titleTextStyle); Blt_Ts_SetAnchor(graphPtr->titleTextStyle, TK_ANCHOR_N); Blt_InitHashTable(&graphPtr->axes.table, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->axes.tagTable, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->elements.table, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->elements.tagTable, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->markers.table, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->markers.tagTable, BLT_STRING_KEYS); Blt_InitHashTable(&graphPtr->dataTables, BLT_STRING_KEYS); graphPtr->elements.displayList = Blt_Chain_Create(); graphPtr->markers.displayList = Blt_Chain_Create(); graphPtr->axes.displayList = Blt_Chain_Create(); switch (classId) { case CID_ELEM_LINE: Tk_SetClass(tkwin, "Graph"); break; case CID_ELEM_BAR: Tk_SetClass(tkwin, "Barchart"); break; case CID_ELEM_STRIP: Tk_SetClass(tkwin, "Stripchart"); default: Tk_SetClass(tkwin, "???"); break; } Blt_SetWindowInstanceData(tkwin, graphPtr); if (InitPens(graphPtr) != TCL_OK) { goto error; } if (Blt_ConfigureWidgetFromObj(interp, tkwin, configSpecs, objc - 2, objv + 2, (char *)graphPtr, 0) != TCL_OK) { goto error; } if (Blt_DefaultAxes(graphPtr) != TCL_OK) { goto error; } AdjustAxisPointers(graphPtr); if (Blt_CreatePageSetup(graphPtr) != TCL_OK) { goto error; } if (Blt_CreateCrosshairs(graphPtr) != TCL_OK) { goto error; } if (Blt_CreateLegend(graphPtr) != TCL_OK) { goto error; } Tk_CreateEventHandler(graphPtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, GraphEventProc, graphPtr); graphPtr->cmdToken = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), Blt_GraphInstCmdProc, graphPtr, GraphInstCmdDeleteProc); ConfigureGraph(graphPtr); graphPtr->bindTable = Blt_CreateBindingTable(interp, tkwin, graphPtr, PickEntry, Blt_GraphTags); Tcl_SetObjResult(interp, objv[1]); return graphPtr; error: DestroyGraph((DestroyData)graphPtr); return NULL; } /* Widget sub-commands */ /*ARGSUSED*/ static int XAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int margin; margin = (graphPtr->inverted) ? MARGIN_LEFT : MARGIN_BOTTOM; return Blt_AxisOp(interp, graphPtr, margin, objc, objv); } static int X2AxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int margin; margin = (graphPtr->inverted) ? MARGIN_RIGHT : MARGIN_TOP; return Blt_AxisOp(interp, graphPtr, margin, objc, objv); } static int YAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int margin; margin = (graphPtr->inverted) ? MARGIN_BOTTOM : MARGIN_LEFT; return Blt_AxisOp(interp, graphPtr, margin, objc, objv); } static int Y2AxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int margin; margin = (graphPtr->inverted) ? MARGIN_TOP : MARGIN_RIGHT; return Blt_AxisOp(interp, graphPtr, margin, objc, objv); } static int BarOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ElementOp(graphPtr, interp, objc, objv, CID_ELEM_BAR); } /*ARGSUSED*/ static int LineOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ElementOp(graphPtr, interp, objc, objv, CID_ELEM_LINE); } static int ElementOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ElementOp(graphPtr, interp, objc, objv, graphPtr->classId); } static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int flags; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)graphPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, (char *)graphPtr, objv[2], flags); } else { if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, objc - 2, objv + 2, (char *)graphPtr, flags) != TCL_OK) { return TCL_ERROR; } ConfigureGraph(graphPtr); Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } } /* ARGSUSED*/ static int CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, (char *)graphPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * ExtentsOp -- * * Reports the size of one of several items within the graph. The * following are valid items: * * "bottommargin" Height of the bottom margin * "leftmargin" Width of the left margin * "legend" x y w h of the legend * "plotarea" x y w h of the plotarea * "plotheight" Height of the plot area * "rightmargin" Width of the right margin * "topmargin" Height of the top margin * "plotwidth" Width of the plot area * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /* ARGSUSED*/ static int ExtentsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *string; char c; int length; string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; if ((c == 'p') && (length > 4) && (strncmp("plotheight", string, length) == 0)) { int height; height = graphPtr->bottom - graphPtr->top + 1; Tcl_SetIntObj(Tcl_GetObjResult(interp), height); } else if ((c == 'p') && (length > 4) && (strncmp("plotwidth", string, length) == 0)) { int width; width = graphPtr->right - graphPtr->left + 1; Tcl_SetIntObj(Tcl_GetObjResult(interp), width); } else if ((c == 'p') && (length > 4) && (strncmp("plotarea", string, length) == 0)) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(graphPtr->left)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(graphPtr->top)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(graphPtr->right - graphPtr->left + 1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(graphPtr->bottom - graphPtr->top + 1)); Tcl_SetObjResult(interp, listObjPtr); } else if ((c == 'l') && (length > 2) && (strncmp("legend", string, length) == 0)) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(Blt_Legend_X(graphPtr))); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(Blt_Legend_Y(graphPtr))); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(Blt_Legend_Width(graphPtr))); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(Blt_Legend_Height(graphPtr))); Tcl_SetObjResult(interp, listObjPtr); } else if ((c == 'l') && (length > 2) && (strncmp("leftmargin", string, length) == 0)) { Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->leftMargin.width); } else if ((c == 'r') && (length > 1) && (strncmp("rightmargin", string, length) == 0)) { Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->rightMargin.width); } else if ((c == 't') && (length > 1) && (strncmp("topmargin", string, length) == 0)) { Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->topMargin.height); } else if ((c == 'b') && (length > 1) && (strncmp("bottommargin", string, length) == 0)) { Tcl_SetIntObj(Tcl_GetObjResult(interp), graphPtr->bottomMargin.height); } else { Tcl_AppendResult(interp, "bad extent item \"", objv[2], "\": should be plotheight, plotwidth, leftmargin, rightmargin, \ topmargin, bottommargin, plotarea, or legend", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsideOp -- * * Returns true of false whether the given point is inside the plotting * area (defined by left,bottom right, top). * * Results: * Always returns TCL_OK. interp->result will contain the boolean string * representation. * *--------------------------------------------------------------------------- */ /* ARGSUSED*/ static int InsideOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; Region2d exts; int result; if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) { return TCL_ERROR; } Blt_GraphExtents(graphPtr, &exts); result = PointInRegion(&exts, x, y); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvtransformOp -- * * This procedure returns a list of the graph coordinate values * corresponding with the given window X and Y coordinate positions. * * Results: * Returns a standard TCL result. If an error occurred while parsing the * window positions, TCL_ERROR is returned, and interp->result will * contain the error message. Otherwise interp->result will contain a * Tcl list of the x and y coordinates. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InvtransformOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { double x, y; Point2d point; Axis2d axes; Tcl_Obj *listObjPtr; if ((Blt_ExprDoubleFromObj(interp, objv[2], &x) != TCL_OK) || (Blt_ExprDoubleFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } /* Perform the reverse transformation, converting from window coordinates * to graph data coordinates. Note that the point is always mapped to the * bottom and left axes (which may not be what the user wants). */ /* Pick the first pair of axes */ axes.x = Blt_GetFirstAxis(graphPtr->axisChain[0]); axes.y = Blt_GetFirstAxis(graphPtr->axisChain[1]); point = Blt_InvMap2D(graphPtr, x, y, &axes); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(point.x)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(point.y)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TransformOp -- * * This procedure returns a list of the window coordinates corresponding * with the given graph x and y coordinates. * * Results: * Returns a standard TCL result. interp->result contains the list of * the graph coordinates. If an error occurred while parsing the window * positions, TCL_ERROR is returned, then interp->result will contain an * error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TransformOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { double x, y; Point2d point; Axis2d axes; Tcl_Obj *listObjPtr; if ((Blt_ExprDoubleFromObj(interp, objv[2], &x) != TCL_OK) || (Blt_ExprDoubleFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } /* * Perform the transformation from window to graph coordinates. Note that * the points are always mapped onto the bottom and left axes (which may * not be the what the user wants). */ axes.x = Blt_GetFirstAxis(graphPtr->axisChain[0]); axes.y = Blt_GetFirstAxis(graphPtr->axisChain[1]); point = Blt_Map2D(graphPtr, x, y, &axes); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(ROUND(point.x))); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(ROUND(point.y))); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } #ifndef NO_PRINTER /* *--------------------------------------------------------------------------- * * Print1Op -- * * Prints the equivalent of a screen snapshot of the graph to the * designated printer. * * Results: * Returns a standard TCL result. If an error occurred TCL_ERROR is * returned and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int Print1Op(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BITMAPINFO info; void *data; TkWinDCState state; TkWinBitmap bd; DIBSECTION ds; Drawable drawable; HBITMAP hBitmap; HDC hDC; DOCINFO di; double pageWidth, pageHeight; int result; double scale, sx, sy; int jobId; graphPtr->width = Tk_Width(graphPtr->tkwin); graphPtr->height = Tk_Height(graphPtr->tkwin); if ((graphPtr->width < 2) && (graphPtr->reqWidth > 0)) { graphPtr->width = graphPtr->reqWidth; } if ((graphPtr->height < 2) && (graphPtr->reqHeight > 0)) { graphPtr->height = graphPtr->reqHeight; } if (objc == 2) { result = Blt_PrintDialog(interp, &drawable); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_RETURN) { return TCL_OK; } } else { if (Blt_GetOpenPrinter(interp, Tcl_GetString(objv[2]), &drawable) != TCL_OK) { return TCL_ERROR; } } /* * This is a taken from Blt_SnapPhoto. The difference is that here we're * using the DIBSection directly, without converting the section into a * Picture. */ ZeroMemory(&info, sizeof(info)); info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = graphPtr->width; info.bmiHeader.biHeight = graphPtr->height; info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 32; info.bmiHeader.biCompression = BI_RGB; hDC = TkWinGetDrawableDC(graphPtr->display, Tk_WindowId(graphPtr->tkwin), &state); hBitmap = CreateDIBSection(hDC, &info, DIB_RGB_COLORS, &data, NULL, 0); TkWinReleaseDrawableDC(Tk_WindowId(graphPtr->tkwin), hDC, &state); /* * Create our own drawable by hand using the DIB we just created. We'll * then draw into it using the standard drawing functions. */ bd.type = TWD_BITMAP; bd.handle = hBitmap; bd.colormap = DefaultColormap(graphPtr->display, DefaultScreen(graphPtr->display)); bd.depth = Tk_Depth(graphPtr->tkwin); graphPtr->flags |= RESET_WORLD; Blt_DrawGraph(graphPtr, (Drawable)&bd); /* * Now that the DIB contains the image of the graph, get the the data bits * and write them to the printer device, stretching the image to the fit * the printer's resolution. */ result = TCL_ERROR; if (GetObject(hBitmap, sizeof(DIBSECTION), &ds) == 0) { Tcl_AppendResult(interp, "can't get object: ", Blt_LastError(), (char *)NULL); goto done; } hDC = ((TkWinDC *) drawable)->hdc; /* Get the resolution of the printer device. */ sx = (double)GetDeviceCaps(hDC, HORZRES) / (double)graphPtr->width; sy = (double)GetDeviceCaps(hDC, VERTRES) / (double)graphPtr->height; scale = MIN(sx, sy); pageWidth = scale * graphPtr->width; pageHeight = scale * graphPtr->height; ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = "Graph Contents"; jobId = StartDoc(hDC, &di); if (jobId <= 0) { Tcl_AppendResult(interp, "can't start document: ", Blt_LastError(), (char *)NULL); goto done; } if (StartPage(hDC) <= 0) { Tcl_AppendResult(interp, "error starting page: ", Blt_LastError(), (char *)NULL); goto done; } StretchDIBits(hDC, 0, 0, ROUND(pageWidth), ROUND(pageHeight), 0, 0, graphPtr->width, graphPtr->height, ds.dsBm.bmBits, (LPBITMAPINFO)&ds.dsBmih, DIB_RGB_COLORS, SRCCOPY); EndPage(hDC); EndDoc(hDC); result = TCL_OK; done: DeleteBitmap(hBitmap); return result; } /* *--------------------------------------------------------------------------- * * Print2Op -- * * Prints directly to the designated printer device. * * Results: * Returns a standard TCL result. If an error occurred, TCL_ERROR is * returned and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ static int Print2Op(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Drawable drawable; int result; graphPtr->width = Tk_Width(graphPtr->tkwin); graphPtr->height = Tk_Height(graphPtr->tkwin); if ((graphPtr->width < 2) && (graphPtr->reqWidth > 0)) { graphPtr->width = graphPtr->reqWidth; } if ((graphPtr->height < 2) && (graphPtr->reqHeight > 0)) { graphPtr->height = graphPtr->reqHeight; } if (objc == 2) { result = Blt_PrintDialog(interp, &drawable); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_RETURN) { return TCL_OK; } } else { result = Blt_GetOpenPrinter(interp, Tcl_GetString(objv[2]), &drawable); } if (result == TCL_OK) { int oldMode; HDC hDC; double xRatio, yRatio; TkWinDC *drawPtr; int w, h; drawPtr = (TkWinDC *) drawable; hDC = drawPtr->hdc; Blt_GetPrinterScale(hDC, &xRatio, &yRatio); oldMode = SetMapMode(hDC, MM_ISOTROPIC); if (oldMode == 0) { Tcl_AppendResult(interp, "can't set mode for printer DC: ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } w = (int)round(graphPtr->width * xRatio); h = (int)round(graphPtr->height * yRatio); SetViewportExtEx(hDC, w, h, NULL); SetWindowExtEx(hDC, graphPtr->width, graphPtr->height, NULL); Blt_StartPrintJob(interp, drawable); graphPtr->flags |= RESET_WORLD; Blt_DrawGraph(graphPtr, drawable); Blt_EndPrintJob(interp, drawable); } return result; } #endif /* NO_PRINTER */ /* *--------------------------------------------------------------------------- * * ObjToFormat -- * * Convert a string represent a node number into its integer value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToFormat( ClientData clientData, /* Not used.*/ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *formatPtr = (int *)(record + offset); char c; const char *string; string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'p') && (strcmp(string, "picture") == 0)) { *formatPtr = FORMAT_PHOTO; } else if ((c == 'p') && (strcmp(string, "photo") == 0)) { *formatPtr = FORMAT_PHOTO; #ifdef WIN32 } else if ((c == 'e') && (strcmp(string, "emf") == 0)) { *formatPtr = FORMAT_EMF; } else if ((c == 'w') && (strcmp(string, "wmf") == 0)) { *formatPtr = FORMAT_WMF; #endif /* WIN32 */ } else { #ifdef WIN32 Tcl_AppendResult(interp, "bad format \"", string, "\": should be picture, photo, emf, or wmf.", (char *)NULL); #else Tcl_AppendResult(interp, "bad format \"", string, "\": should be picture or photo.", (char *)NULL); #endif /* WIN32 */ return TCL_ERROR; } return TCL_OK; } #ifdef WIN32 static int InitMetaFileHeader( Tk_Window tkwin, int width, int height, APMHEADER *mfhPtr) { unsigned int *p; unsigned int sum; #define MM_INCH 25.4 int xdpi, ydpi; mfhPtr->key = 0x9ac6cdd7L; mfhPtr->hmf = 0; mfhPtr->inch = 1440; Blt_ScreenDPI(tkwin, &xdpi, &ydpi); mfhPtr->bbox.Left = mfhPtr->bbox.Top = 0; mfhPtr->bbox.Bottom = (SHORT)((width * 1440)/ (float)xdpi); mfhPtr->bbox.Right = (SHORT)((height * 1440) / (float)ydpi); mfhPtr->reserved = 0; sum = 0; for (p = (unsigned int *)mfhPtr; p < (unsigned int *)&(mfhPtr->checksum); p++) { sum ^= *p; } mfhPtr->checksum = sum; return TCL_OK; } static int CreateAPMetaFile(Tcl_Interp *interp, HANDLE hMetaFile, HDC hDC, APMHEADER *mfhPtr, const char *fileName) { HANDLE hFile; HANDLE hMem; LPVOID buffer; int result; DWORD count, nBytes; result = TCL_ERROR; hMem = NULL; hFile = CreateFile( fileName, /* File path */ GENERIC_WRITE, /* Access mode */ 0, /* No sharing. */ NULL, /* Security attributes */ CREATE_ALWAYS, /* Overwrite any existing file */ FILE_ATTRIBUTE_NORMAL, NULL); /* No template file */ if (hFile == INVALID_HANDLE_VALUE) { Tcl_AppendResult(interp, "can't create metafile \"", fileName, "\":", Blt_LastError(), (char *)NULL); return TCL_ERROR; } if ((!WriteFile(hFile, (LPVOID)mfhPtr, sizeof(APMHEADER), &count, NULL)) || (count != sizeof(APMHEADER))) { Tcl_AppendResult(interp, "can't create metafile header to \"", fileName, "\":", Blt_LastError(), (char *)NULL); goto error; } nBytes = GetWinMetaFileBits(hMetaFile, 0, NULL, MM_ANISOTROPIC, hDC); hMem = GlobalAlloc(GHND, nBytes); if (hMem == NULL) { Tcl_AppendResult(interp, "can't create allocate global memory:", Blt_LastError(), (char *)NULL); goto error; } buffer = (LPVOID)GlobalLock(hMem); if (!GetWinMetaFileBits(hMetaFile, nBytes, buffer, MM_ANISOTROPIC, hDC)) { Tcl_AppendResult(interp, "can't get metafile bits:", Blt_LastError(), (char *)NULL); goto error; } if ((!WriteFile(hFile, buffer, nBytes, &count, NULL)) || (count != nBytes)) { Tcl_AppendResult(interp, "can't write metafile bits:", Blt_LastError(), (char *)NULL); goto error; } result = TCL_OK; error: CloseHandle(hFile); if (hMem != NULL) { GlobalUnlock(hMem); GlobalFree(hMem); } return result; } #endif /*WIN32*/ /* *--------------------------------------------------------------------------- * * SnapOp -- * * Snaps a picture of the graph and stores it in the specified image. * * Results: * Returns a standard TCL result. interp->result contains * the list of the graph coordinates. If an error occurred * while parsing the window positions, TCL_ERROR is returned, * then interp->result will contain an error message. * *--------------------------------------------------------------------------- */ static int SnapOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Pixmap drawable; int i; SnapSwitches switches; /* .g snap ?switches? name */ switches.height = Tk_Height(graphPtr->tkwin); if ((switches.height < 2) && (graphPtr->reqHeight > 0)) { switches.height = graphPtr->reqHeight; } switches.width = Tk_Width(graphPtr->tkwin); if ((switches.width < 2) && (graphPtr->reqWidth > 0)) { switches.width = graphPtr->reqWidth; } switches.format = FORMAT_PICTURE; /* Process switches */ i = Blt_ParseSwitches(interp, snapSwitches, objc - 2, objv + 2, &switches, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { return TCL_ERROR; } i += 2; if (i >= objc) { Tcl_AppendResult(interp, "missing name argument: should be \"", Tcl_GetString(objv[0]), "snap ?switches? name\"", (char *)NULL); return TCL_ERROR; } switches.name = Tcl_GetString(objv[i]); if (switches.width < 2) { switches.width = Tk_ReqWidth(graphPtr->tkwin); } if (switches.height < 2) { switches.width = Tk_ReqHeight(graphPtr->tkwin); } /* Always re-compute the layout of the graph before snapping the picture. */ graphPtr->width = switches.width; graphPtr->height = switches.height; Blt_MapGraph(graphPtr); drawable = Tk_WindowId(graphPtr->tkwin); switch (switches.format) { case FORMAT_PICTURE: case FORMAT_PHOTO: drawable = Tk_GetPixmap(graphPtr->display, drawable, graphPtr->width, graphPtr->height, Tk_Depth(graphPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif graphPtr->flags |= RESET_WORLD; Blt_DrawGraph(graphPtr, drawable); if (switches.format == FORMAT_PICTURE) { result = Blt_SnapPicture(interp, graphPtr->tkwin, drawable, 0, 0, switches.width, switches.height, switches.width, switches.height, switches.name, 1.0); } else { result = Blt_SnapPhoto(interp, graphPtr->tkwin, drawable, 0, 0, switches.width, switches.height, switches.width, switches.height, switches.name, 1.0); } Tk_FreePixmap(graphPtr->display, drawable); break; #ifdef WIN32 case FORMAT_WMF: case FORMAT_EMF: { TkWinDC drawableDC; TkWinDCState state; HDC hRefDC, hDC; HENHMETAFILE hMetaFile; Tcl_DString dString; const char *title; hRefDC = TkWinGetDrawableDC(graphPtr->display, drawable, &state); Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "BLT Graph ", -1); Tcl_DStringAppend(&dString, BLT_VERSION, -1); Tcl_DStringAppend(&dString, "\0", -1); Tcl_DStringAppend(&dString, Tk_PathName(graphPtr->tkwin), -1); Tcl_DStringAppend(&dString, "\0", -1); title = Tcl_DStringValue(&dString); hDC = CreateEnhMetaFile(hRefDC, NULL, NULL, title); Tcl_DStringFree(&dString); if (hDC == NULL) { Tcl_AppendResult(interp, "can't create metafile: ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } drawableDC.hdc = hDC; drawableDC.type = TWD_WINDC; graphPtr->width = switches.width; graphPtr->height = switches.height; Blt_MapGraph(graphPtr); graphPtr->flags |= RESET_WORLD; Blt_DrawGraph(graphPtr, (Drawable)&drawableDC); hMetaFile = CloseEnhMetaFile(hDC); if (strcmp(switches.name, "CLIPBOARD") == 0) { HWND hWnd; hWnd = Tk_GetHWND(drawable); OpenClipboard(hWnd); EmptyClipboard(); SetClipboardData(CF_ENHMETAFILE, hMetaFile); CloseClipboard(); result = TCL_OK; } else { result = TCL_ERROR; if (switches.format == FORMAT_WMF) { APMHEADER mfh; assert(sizeof(mfh) == 22); InitMetaFileHeader(graphPtr->tkwin, switches.width, switches.height, &mfh); result = CreateAPMetaFile(interp, hMetaFile, hRefDC, &mfh, switches.name); } else { HENHMETAFILE hMetaFile2; hMetaFile2 = CopyEnhMetaFile(hMetaFile, switches.name); if (hMetaFile2 != NULL) { result = TCL_OK; DeleteEnhMetaFile(hMetaFile2); } } DeleteEnhMetaFile(hMetaFile); } TkWinReleaseDrawableDC(drawable, hRefDC, &state); } break; #endif /*WIN32*/ default: Tcl_AppendResult(interp, "bad snapshot format", (char *)NULL); return TCL_ERROR; } graphPtr->flags |= MAP_WORLD; Blt_EventuallyRedrawGraph(graphPtr); return result; } /* *--------------------------------------------------------------------------- * * GraphWidgetCmd -- * * This procedure is invoked to process the TCL command that * corresponds to a widget managed by this module. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec graphOps[] = { {"axis", 1, Blt_VirtualAxisOp, 2, 0, "oper ?args?",}, {"bar", 2, BarOp, 2, 0, "oper ?args?",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?...",}, {"crosshairs", 2, Blt_CrosshairsOp, 2, 0, "oper ?args?",}, {"element", 2, ElementOp, 2, 0, "oper ?args?",}, {"extents", 2, ExtentsOp, 3, 3, "item",}, {"inside", 3, InsideOp, 4, 4, "winX winY",}, {"invtransform", 3, InvtransformOp, 4, 4, "winX winY",}, {"legend", 2, Blt_LegendOp, 2, 0, "oper ?args?",}, {"line", 2, LineOp, 2, 0, "oper ?args?",}, {"marker", 2, Blt_MarkerOp, 2, 0, "oper ?args?",}, {"pen", 2, Blt_PenOp, 2, 0, "oper ?args?",}, {"postscript", 2, Blt_PostScriptOp, 2, 0, "oper ?args?",}, #ifndef NO_PRINTER {"print1", 2, Print1Op, 2, 3, "?printerName?",}, {"print2", 2, Print2Op, 2, 3, "?printerName?",}, #endif /*NO_PRINTER*/ {"snap", 1, SnapOp, 3, 0, "?switches? name",}, {"transform", 1, TransformOp, 4, 4, "x y",}, {"x2axis", 2, X2AxisOp, 2, 0, "oper ?args?",}, {"xaxis", 2, XAxisOp, 2, 0, "oper ?args?",}, {"y2axis", 2, Y2AxisOp, 2, 0, "oper ?args?",}, {"yaxis", 2, YAxisOp, 2, 0, "oper ?args?",}, }; static int nGraphOps = sizeof(graphOps) / sizeof(Blt_OpSpec); int Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphCmdProc *proc; int result; Graph *graphPtr = clientData; proc = Blt_GetOpFromObj(interp, nGraphOps, graphOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(graphPtr); result = (*proc) (graphPtr, interp, objc, objv); Tcl_Release(graphPtr); return result; } /* *--------------------------------------------------------------------------- * * NewGraph -- * * Creates a new window and TCL command representing an instance of a * graph widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int NewGraph(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ClassId classId) { Graph *graphPtr; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } graphPtr = CreateGraph(interp, objc, objv, classId); if (graphPtr == NULL) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GraphCmd -- * * Creates a new window and TCL command representing an instance of a * graph widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GraphCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return NewGraph(interp, objc, objv, CID_ELEM_LINE); } /* *--------------------------------------------------------------------------- * * BarchartCmd -- * * Creates a new window and TCL command representing an instance of a * barchart widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BarchartCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return NewGraph(interp, objc, objv, CID_ELEM_BAR); } /* *--------------------------------------------------------------------------- * * StripchartCmd -- * * Creates a new window and TCL command representing an instance of a * barchart widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StripchartCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return NewGraph(interp, objc, objv, CID_ELEM_STRIP); } /* *--------------------------------------------------------------------------- * * DrawMargins -- * * Draws the exterior region of the graph (axes, ticks, titles, etc) * onto a pixmap. The interior region is defined by the given rectangle * structure. * * --------------------------------- * | | * | rectArr[0] | * | | * --------------------------------- * | |top right| | * | | | | * | | | | * | [1] | | [2] | * | | | | * | | | | * | | | | * | | | | * | | | | * | |left bottom| | * --------------------------------- * | | * | rectArr[3] | * | | * --------------------------------- * * X coordinate axis * Y coordinate axis * legend * interior border * exterior border * titles (X and Y axis, graph) * * Returns: * None. * * Side Effects: * Exterior of graph is displayed in its window. * *--------------------------------------------------------------------------- */ static void DrawMargins(Graph *graphPtr, Drawable drawable) { XRectangle rects[4]; int site; /* * Draw the four outer rectangles which encompass the plotting * surface. This clears the surrounding area and clips the plot. */ rects[0].x = rects[0].y = rects[3].x = rects[1].x = 0; rects[0].width = rects[3].width = (short int)graphPtr->width; rects[0].height = (short int)graphPtr->top; rects[3].y = graphPtr->bottom; rects[3].height = graphPtr->height - graphPtr->bottom; rects[2].y = rects[1].y = graphPtr->top; rects[1].width = graphPtr->left; rects[2].height = rects[1].height = graphPtr->bottom - graphPtr->top; rects[2].x = graphPtr->right; rects[2].width = graphPtr->width - graphPtr->right; Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, rects[0].x, rects[0].y, rects[0].width, rects[0].height, 0, TK_RELIEF_FLAT); Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, rects[1].x, rects[1].y, rects[1].width, rects[1].height, 0, TK_RELIEF_FLAT); Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, rects[2].x, rects[2].y, rects[2].width, rects[2].height, 0, TK_RELIEF_FLAT); Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, rects[3].x, rects[3].y, rects[3].width, rects[3].height, 0, TK_RELIEF_FLAT); /* Draw 3D border around the plotting area */ if (graphPtr->plotBW > 0) { int x, y, w, h; x = graphPtr->left - graphPtr->plotBW; y = graphPtr->top - graphPtr->plotBW; w = (graphPtr->right - graphPtr->left) + (2*graphPtr->plotBW); h = (graphPtr->bottom - graphPtr->top) + (2*graphPtr->plotBW); Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, x, y, w, h, graphPtr->plotBW, graphPtr->plotRelief); } site = Blt_Legend_Site(graphPtr); if (site & LEGEND_MARGIN_MASK) { /* Legend is drawn on one of the graph margins */ Blt_DrawLegend(graphPtr, drawable); } else if (site == LEGEND_WINDOW) { Blt_Legend_EventuallyRedraw(graphPtr); } if (graphPtr->title != NULL) { Blt_DrawText(graphPtr->tkwin, drawable, graphPtr->title, &graphPtr->titleTextStyle, graphPtr->titleX, graphPtr->titleY); } Blt_DrawAxes(graphPtr, drawable); graphPtr->flags &= ~DRAW_MARGINS; } #ifdef notdef /* *--------------------------------------------------------------------------- * * DrawPlotRegion -- * * Draws the contents of the plotting area. This consists of the * elements, markers (draw under elements), axis limits, and possibly the * legend. Typically, the output will be cached into a backing store * pixmap, so that redraws can occur quickly. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawPlotRegion(Graph *graphPtr, Drawable drawable) { int site; /* Clear the background of the plotting area. */ Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->plotBg, graphPtr->left, graphPtr->top, graphPtr->right - graphPtr->left + 1, graphPtr->bottom - graphPtr->top + 1, TK_RELIEF_FLAT, 0); /* Draw the elements, markers, legend, and axis limits. */ Blt_DrawGrids(graphPtr, drawable); Blt_DrawMarkers(graphPtr, drawable, MARKER_UNDER); site = Blt_Legend_Site(graphPtr); if ((site & LEGEND_PLOTAREA_MASK) && (!Blt_Legend_IsRaised(graphPtr))) { Blt_DrawLegend(graphPtr, drawable); } else if (site == LEGEND_WINDOW) { Blt_Legend_EventuallyRedraw(graphPtr); } Blt_DrawAxisLimits(graphPtr, drawable); DrawMargins(graphPtr, drawable); Blt_DrawElements(graphPtr, drawable); Blt_DrawAxes(graphPtr, drawable); } #endif /* *--------------------------------------------------------------------------- * * DrawPlot -- * * Draws the contents of the plotting area. This consists of the * elements, markers (draw under elements), axis limits, and possibly the * legend. Typically, the output will be cached into a backing store * pixmap, so that redraws can occur quickly. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawPlot(Graph *graphPtr, Drawable drawable) { int site; DrawMargins(graphPtr, drawable); /* Draw the background of the plotting area with 3D border. */ Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->plotBg, graphPtr->left - graphPtr->plotBW, graphPtr->top - graphPtr->plotBW, graphPtr->right - graphPtr->left + 1 + 2 * graphPtr->plotBW, graphPtr->bottom - graphPtr->top + 1 + 2 * graphPtr->plotBW, graphPtr->plotBW, graphPtr->plotRelief); /* Draw the elements, markers, legend, and axis limits. */ Blt_DrawAxes(graphPtr, drawable); Blt_DrawGrids(graphPtr, drawable); Blt_DrawMarkers(graphPtr, drawable, MARKER_UNDER); site = Blt_Legend_Site(graphPtr); if ((site & LEGEND_PLOTAREA_MASK) && (!Blt_Legend_IsRaised(graphPtr))) { Blt_DrawLegend(graphPtr, drawable); } else if (site == LEGEND_WINDOW) { Blt_Legend_EventuallyRedraw(graphPtr); } Blt_DrawAxisLimits(graphPtr, drawable); Blt_DrawElements(graphPtr, drawable); /* Blt_DrawAxes(graphPtr, drawable); */ } void Blt_MapGraph(Graph *graphPtr) { if (graphPtr->flags & RESET_AXES) { Blt_ResetAxes(graphPtr); } if (graphPtr->flags & LAYOUT_NEEDED) { Blt_LayoutGraph(graphPtr); graphPtr->flags &= ~LAYOUT_NEEDED; } /* Compute coordinate transformations for graph components */ if ((graphPtr->vRange > 1) && (graphPtr->hRange > 1)) { if (graphPtr->flags & MAP_WORLD) { Blt_MapAxes(graphPtr); } Blt_MapElements(graphPtr); Blt_MapMarkers(graphPtr); graphPtr->flags &= ~(MAP_ALL); } } void Blt_DrawGraph(Graph *graphPtr, Drawable drawable) { DrawPlot(graphPtr, drawable); /* Draw markers above elements */ Blt_DrawMarkers(graphPtr, drawable, MARKER_ABOVE); Blt_DrawActiveElements(graphPtr, drawable); /* Don't draw legend in the plot area. */ if ((Blt_Legend_Site(graphPtr) & LEGEND_PLOTAREA_MASK) && (Blt_Legend_IsRaised(graphPtr))) { Blt_DrawLegend(graphPtr, drawable); } /* Draw 3D border just inside of the focus highlight ring. */ if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) { Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, graphPtr->highlightWidth, graphPtr->highlightWidth, graphPtr->width - 2 * graphPtr->highlightWidth, graphPtr->height - 2 * graphPtr->highlightWidth, graphPtr->borderWidth, graphPtr->relief); } /* Draw focus highlight ring. */ if ((graphPtr->highlightWidth > 0) && (graphPtr->flags & FOCUS)) { GC gc; gc = Tk_GCForColor(graphPtr->highlightColor, drawable); Tk_DrawFocusHighlight(graphPtr->tkwin, gc, graphPtr->highlightWidth, drawable); } } static void UpdateMarginTraces(Graph *graphPtr) { Margin *marginPtr, *endPtr; for (marginPtr = graphPtr->margins, endPtr = marginPtr + 4; marginPtr < endPtr; marginPtr++) { if (marginPtr->varName != NULL) { /* Trigger variable traces */ int size; if ((marginPtr->site == MARGIN_LEFT) || (marginPtr->site == MARGIN_RIGHT)) { size = marginPtr->width; } else { size = marginPtr->height; } Tcl_SetVar(graphPtr->interp, marginPtr->varName, Blt_Itoa(size), TCL_GLOBAL_ONLY); } } } /* *--------------------------------------------------------------------------- * * DisplayGraph -- * * This procedure is invoked to display a graph widget. * * Results: * None. * * Side effects: * Commands are output to X to display the graph in its current mode. * *--------------------------------------------------------------------------- */ static void DisplayGraph(ClientData clientData) { Graph *graphPtr = clientData; Pixmap drawable; Tk_Window tkwin; int site; graphPtr->flags &= ~REDRAW_PENDING; if (graphPtr->tkwin == NULL) { return; /* Window has been destroyed (we * should not get here) */ } tkwin = graphPtr->tkwin; #ifdef notdef fprintf(stderr, "Calling DisplayGraph(%s)\n", Tk_PathName(tkwin)); #endif if ((Tk_Width(tkwin) <= 1) || (Tk_Height(tkwin) <= 1)) { /* Don't bother computing the layout until the size of the window is * something reasonable. */ return; } graphPtr->width = Tk_Width(tkwin); graphPtr->height = Tk_Height(tkwin); Blt_MapGraph(graphPtr); if (!Tk_IsMapped(tkwin)) { /* The graph's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the graph's new layout. */ return; } /* Create a pixmap the size of the window for double buffering. */ if (graphPtr->doubleBuffer) { drawable = Tk_GetPixmap(graphPtr->display, Tk_WindowId(tkwin), graphPtr->width, graphPtr->height, Tk_Depth(tkwin)); } else { drawable = Tk_WindowId(tkwin); } if (graphPtr->backingStore) { if ((graphPtr->cache == None) || (graphPtr->cacheWidth != graphPtr->width) || (graphPtr->cacheHeight != graphPtr->height)) { if (graphPtr->cache != None) { Tk_FreePixmap(graphPtr->display, graphPtr->cache); } graphPtr->cache = Tk_GetPixmap(graphPtr->display, Tk_WindowId(tkwin), graphPtr->width, graphPtr->height, Tk_Depth(tkwin)); graphPtr->cacheWidth = graphPtr->width; graphPtr->cacheHeight = graphPtr->height; graphPtr->flags |= CACHE_DIRTY; } } #ifdef WIN32 assert(drawable != None); #endif if (graphPtr->backingStore) { if (graphPtr->flags & CACHE_DIRTY) { /* The backing store is new or out-of-date. */ DrawPlot(graphPtr, graphPtr->cache); graphPtr->flags &= ~CACHE_DIRTY; } /* Copy the pixmap to the one used for drawing the entire graph. */ XCopyArea(graphPtr->display, graphPtr->cache, drawable, graphPtr->drawGC, 0, 0, Tk_Width(graphPtr->tkwin), Tk_Height(graphPtr->tkwin), 0, 0); } else { DrawPlot(graphPtr, drawable); } /* Draw markers above elements */ Blt_DrawMarkers(graphPtr, drawable, MARKER_ABOVE); Blt_DrawActiveElements(graphPtr, drawable); /* Don't draw legend in the plot area. */ site = Blt_Legend_Site(graphPtr); if ((site & LEGEND_PLOTAREA_MASK) && (Blt_Legend_IsRaised(graphPtr))) { Blt_DrawLegend(graphPtr, drawable); } if (site == LEGEND_WINDOW) { Blt_Legend_EventuallyRedraw(graphPtr); } /* Draw 3D border just inside of the focus highlight ring. */ if ((graphPtr->borderWidth > 0) && (graphPtr->relief != TK_RELIEF_FLAT)) { Blt_DrawBackgroundRectangle(graphPtr->tkwin, drawable, graphPtr->normalBg, graphPtr->highlightWidth, graphPtr->highlightWidth, graphPtr->width - 2 * graphPtr->highlightWidth, graphPtr->height - 2 * graphPtr->highlightWidth, graphPtr->borderWidth, graphPtr->relief); } /* Draw focus highlight ring. */ if ((graphPtr->highlightWidth > 0) && (graphPtr->flags & FOCUS)) { GC gc; gc = Tk_GCForColor(graphPtr->highlightColor, drawable); Tk_DrawFocusHighlight(graphPtr->tkwin, gc, graphPtr->highlightWidth, drawable); } /* Disable crosshairs before redisplaying to the screen */ Blt_DisableCrosshairs(graphPtr); XCopyArea(graphPtr->display, drawable, Tk_WindowId(tkwin), graphPtr->drawGC, 0, 0, graphPtr->width, graphPtr->height, 0, 0); Blt_EnableCrosshairs(graphPtr); if (graphPtr->doubleBuffer) { Tk_FreePixmap(graphPtr->display, drawable); } graphPtr->flags &= ~RESET_WORLD; UpdateMarginTraces(graphPtr); } /*LINTLIBRARY*/ int Blt_GraphCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[] = { {"graph", GraphCmd,}, {"barchart", BarchartCmd,}, {"stripchart", StripchartCmd,}, }; return Blt_InitCmds(interp, "::blt", cmdSpecs, 3); } Graph * Blt_GetGraphFromWindowData(Tk_Window tkwin) { Graph *graphPtr; while (tkwin != NULL) { graphPtr = (Graph *)Blt_GetWindowInstanceData(tkwin); if (graphPtr != NULL) { return graphPtr; } tkwin = Tk_Parent(tkwin); } return NULL; } int Blt_GraphType(Graph *graphPtr) { switch (graphPtr->classId) { case CID_ELEM_LINE: return GRAPH; case CID_ELEM_BAR: return BARCHART; case CID_ELEM_STRIP: return STRIPCHART; default: return 0; } return 0; } /* *--------------------------------------------------------------------------- * * Blt_ReconfigureGraph -- * * Allocates resources for the graph. * *--------------------------------------------------------------------------- */ void Blt_ReconfigureGraph(Graph *graphPtr) { ConfigureGraph(graphPtr); Blt_ConfigureLegend(graphPtr); Blt_ConfigureElements(graphPtr); Blt_ConfigureAxes(graphPtr); Blt_ConfigureMarkers(graphPtr); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTile.h���������������������������������������������������������������������0000644�0001750�0001750�00000004604�11462120063�014602� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTile.h -- * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef BLT_TILE_H #define BLT_TILE_H #define TILE_THREAD_KEY "BLT Tile Data" #define TILE_MAGIC ((unsigned int) 0x46170277) typedef struct _Blt_TileClient *Blt_Tile; /* Opaque type for tiles */ typedef void (Blt_TileChangedProc)(ClientData clientData, Blt_Tile tile); BLT_EXTERN int Blt_GetTile(Tcl_Interp *interp, Tk_Window tkwin, char *imageName, Blt_Tile *tilePtr); BLT_EXTERN void Blt_FreeTile(Blt_Tile tile); BLT_EXTERN const char *Blt_NameOfTile(Blt_Tile tile); BLT_EXTERN void Blt_SetTileChangedProc(Blt_Tile tile, Blt_TileChangedProc *changeProc, ClientData clientData); BLT_EXTERN void Blt_TileRectangle(Tk_Window tkwin, Drawable drawable, Blt_Tile tile, int x, int y, unsigned int width, unsigned int height); BLT_EXTERN void Blt_TileRectangles(Tk_Window tkwin, Drawable drawable, Blt_Tile tile, XRectangle *rectArr, int nRects); BLT_EXTERN void Blt_TilePolygon(Tk_Window tkwin, Drawable drawable, Blt_Tile tile, XPoint *pointArr, int nPoints); BLT_EXTERN Pixmap Blt_PixmapOfTile(Blt_Tile tile); BLT_EXTERN void Blt_SizeOfTile(Blt_Tile tile, int *widthPtr, int *heightPtr); BLT_EXTERN void Blt_SetTileOrigin(Tk_Window tkwin, Blt_Tile tile, int x, int y); BLT_EXTERN void Blt_SetTSOrigin(Tk_Window tkwin, Blt_Tile tile, int x, int y); #endif /* BLT_TILE_H */ ����������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltComboTree.c����������������������������������������������������������������0000644�0001750�0001750�00000616036�11462120062�015566� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltComboTree.c -- * * This module implements a combotree widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * * BUGS: * 1. "open" operation should change scroll offset so that as many * new entries (up to half a screen) can be seen. * 2. "open" needs to adjust the scrolloffset so that the same entry * is seen at the same place. */ #include "bltInt.h" #ifndef NO_COMBOTREE #include "bltOp.h" #include "bltImage.h" #include "bltHash.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltTree.h" #include "bltBind.h" #include "bltBgStyle.h" #define PICK_ENTRY (ClientData)0 #define PICK_BUTTON (ClientData)1 #if HAVE_UTF #else #define Tcl_NumUtfChars(s,n) (((n) == -1) ? strlen((s)) : (n)) #define Tcl_UtfAtIndex(s,i) ((s) + (i)) #endif #define ODD(x) ((x) | 0x01) #define END (-1) #define SEPARATOR_LIST ((char *)NULL) #define SEPARATOR_NONE ((char *)-1) #define SEARCH_Y 1 #define ARROW_WIDTH 17 #define ARROW_HEIGHT 17 typedef const char *UID; #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define CHOOSE(default, override) \ (((override) == NULL) ? (default) : (override)) #define GETLABEL(e) \ (((e)->labelUid != NULL) ? (e)->labelUid : Blt_Tree_NodeLabel((e)->node)) /* * The macro below is used to modify a "char" value (e.g. by casting it to an * unsigned character) so that it can be used safely with macros such as * isspace. */ #define UCHAR(c) ((unsigned char) (c)) #define SCREENX(c, wx) ((wx) - (c)->xOffset + (c)->borderWidth) #define SCREENY(c, wy) ((wy) - (c)->yOffset + (c)->borderWidth) #define PIXMAPX(c, wx) ((wx) - (c)->xOffset) #define PIXMAPY(c, wy) ((wy) - (c)->yOffset) #define WORLDX(c, sx) ((sx) - (c)->borderWidth + (c)->xOffset) #define WORLDY(c, sy) ((sy) - (c)->borderWidth + (c)->yOffset) #define VPORTWIDTH(c) \ (Tk_Width((c)->tkwin) - 2 * (c)->borderWidth - (c)->yScrollbarWidth) #define VPORTHEIGHT(c) \ (Tk_Height((c)->tkwin) - 2 * (c)->borderWidth - (c)->xScrollbarHeight) #define ICONWIDTH(d) (comboPtr->levelInfo[(d)].iconWidth) #define LEVELX(d) (comboPtr->levelInfo[(d)].x) #define DEPTH(h, n) Blt_Tree_NodeDepth(n) /* *--------------------------------------------------------------------------- * * Internal combotree widget flags: * * LAYOUT_PENDING The layout of the hierarchy needs to be recomputed. * * REDRAW_PENDING A redraw request is pending for the widget. * * XSCROLL X-scroll request is pending. * * SCROLLY Y-scroll request is pending. * * SCROLL_PENDING Both X-scroll and Y-scroll requests are pending. * * FOCUS The widget is receiving keyboard events. * Draw the focus highlight border around the widget. * * DIRTY The hierarchy has changed. It may invalidate * the locations and pointers to entries. The widget * will need to recompute its layout. * * VIEWPORT Indicates that the viewport has changed in some * way: the size of the viewport, the location of * the viewport, or the contents of the viewport. * */ #define LAYOUT_PENDING (1<<0) #define REDRAW_PENDING (1<<1) #define UPDATE_PENDING (1<<2) #define SCROLLX (1<<3) #define SCROLLY (1<<4) #define SCROLL_PENDING (SCROLLX | SCROLLY) #define FOCUS (1<<5) #define DIRTY (1<<6) #define VIEWPORT (1<<7) #define REPOPULATE (1<<8) #define INSTALL_SCROLLBAR_X (1<<9) #define INSTALL_SCROLLBAR_Y (1<<10) /* * Miscellaneous flags: * * HIDE_ROOT Don't display the root entry. * * HIDE_LEAVES Don't display entries that are leaves. * * NEW_TAGS */ #define HIDE_ROOT (1<<23) #define HIDE_LEAVES (1<<24) #define NEW_TAGS (1<<27) /* *--------------------------------------------------------------------------- * * Internal entry flags: * * ENTRY_BUTTON Indicates that a button is needed * for this entry. * * ENTRY_CLOSED Indicates that the entry is closed and * its subentries are not displayed. * * ENTRY_HIDE Indicates that the entry is hidden (i.e. * can not be viewed by opening or scrolling). * * ENTRY_BTN_AUTO * ENTRY_BTN_SHOW * ENTRY_BTN_MASK * *--------------------------------------------------------------------------- */ #define ENTRY_CLOSED (1<<0) #define ENTRY_HIDE (1<<1) #define ENTRY_MASK (ENTRY_CLOSED | ENTRY_HIDE) #define ENTRY_NOT_LEAF (1<<2) #define ENTRY_BUTTON (1<<3) #define ENTRY_ICON (1<<4) #define ENTRY_REDRAW (1<<5) #define ENTRY_LAYOUT_PENDING (1<<6) #define ENTRY_DATA_CHANGED (1<<7) #define ENTRY_DIRTY (ENTRY_DATA_CHANGED | ENTRY_LAYOUT_PENDING) #define ENTRY_BTN_AUTO (1<<8) #define ENTRY_BTN_SHOW (1<<9) #define ENTRY_BTN_MASK (ENTRY_BTN_AUTO | ENTRY_BTN_SHOW) #define ENTRY_EDITABLE (1<<10) #define COLUMN_RULE_PICKED (1<<1) #define COLUMN_DIRTY (1<<2) #define STYLE_TEXTBOX (0) #define STYLE_COMBOBOX (1) #define STYLE_CHECKBOX (2) #define STYLE_TYPE 0x3 #define STYLE_LAYOUT (1<<3) #define STYLE_DIRTY (1<<4) #define STYLE_HIGHLIGHT (1<<5) #define STYLE_USER (1<<6) #define STYLE_EDITABLE (1<<10) typedef struct _Entry Entry; typedef struct _ComboTree ComboTree; typedef struct _Style Style; typedef int (CompareProc)(Tcl_Interp *interp, const char *name, const char *pattern); typedef Entry *(IterProc)(Entry *entryPtr, unsigned int mask); /* * Icon -- * * Since instances of the same Tk image can be displayed in * different windows with possibly different color palettes, Tk * internally stores each instance in a linked list. But if * the instances are used in the same widget and therefore use * the same color palette, this adds a lot of overhead, * especially when deleting instances from the linked list. * * For the combotree widget, we never need more than a single * instance of an image, regardless of how many times it's used. * Cache the image, maintaining a reference count for each * image used in the widget. It's likely that the combotree * widget will use many instances of the same image (for example * the open/close icons). */ typedef struct _Icon { Tk_Image tkImage; /* The Tk image being cached. */ int refCount; /* Reference count for this image. */ short int width, height; /* Dimensions of the cached image. */ Blt_HashEntry *hashPtr; /* Hash table pointer to the image. */ } *Icon; #define IconHeight(icon) ((icon)->height) #define IconWidth(icon) ((icon)->width) #define IconImage(icon) ((icon)->tkImage) #define IconName(icon) (Blt_Image_Name((icon)->tkImage)) struct _Style { const char *name; /* Instance name. */ Blt_HashEntry *hPtr; ComboTree *comboPtr; int refCount; /* Indicates if the style is currently * in use in the combotree. */ unsigned int flags; /* Bit field containing both the style * type and various flags. */ /* General style fields. */ int borderWidth; /* Width of 3D border. */ int activeRelief; int relief; int gap; /* # pixels gap between icon and * text. */ Blt_Font labelFont; XColor *labelNormalColor; /* Normal foreground color of cell. */ XColor *labelActiveColor; /* Foreground color of cell when * active. */ Blt_Background normalBg; /* Normal background color. */ Blt_Background altBg; /* Alternate normal background * color. */ Blt_Background activeBg; /* Active entry background color. */ Blt_Background disabledBg; /* Disabled entry background color. */ GC labelNormalGC; GC labelActiveGC; GC labelDisabledGC; Icon *icons; /* Tk images displayed for the entry. * The first image is the icon * displayed to the left of the * entry's label. The second is icon * displayed when entry is "open". */ }; /* * Entry -- * * Contains data-specific information how to represent the data * of a node of the hierarchy. * */ struct _Entry { Blt_TreeNode node; /* Node containing entry */ int worldX, worldY; /* X-Y position in world coordinates where the * entry is positioned. */ Blt_HashEntry *hPtr; short int width, height; /* Dimensions of the entry. This includes the * size of its columns. */ int reqHeight; /* Requested height of the entry. Overrides * computed height. */ int vertLineLength; /* Length of the vertical line segment. */ short int lineHeight; /* Height of first line of text. */ unsigned short int flags; /* Flags for this entry. For the definitions * of the various bit fields see below. */ Tcl_Obj *tagsObjPtr; /* List of binding tags for this entry. */ ComboTree *comboPtr; Tcl_Obj *cmdObjPtr; /* List of binding tags for this entry. */ UID openCmd, closeCmd; /* TCL commands to invoke when entries are * opened or closed. They override those * specified globally. */ /* * Button information: */ short int buttonX, buttonY; /* X-Y coordinate offsets from to upper left * corner of the entry to the upper-left * corner of the button. Used to pick the * button quickly */ short int iconWidth, iconHeight; /* Maximum dimensions for icons and buttons * for this entry. This is used to align the * button, icon, and text. */ /* * Label information: */ TextLayout *textPtr; short int labelWidth, labelHeight; UID labelUid; /* Text displayed right of the icon. */ int seqNum; /* Used to navigate to next/last entry when * the view is flat. */ Style *stylePtr; /* Default style for entry. */ }; /* * Button -- * * A button is the open/close indicator at the far left of the entry. It * is displayed as a plus or minus in a solid colored box with optionally * an border. It has both "active" and "normal" colors. */ typedef struct { XColor *fgColor; /* Foreground color. */ XColor *activeFgColor; /* Active foreground color. */ Blt_Background normalBg; /* Normal button background. */ Blt_Background activeBg; /* Active background color. */ GC normalGC; GC activeGC; int reqSize; int borderWidth; int openRelief, closeRelief; int width, height; Icon *icons; } Button; /* * LevelInfo -- * */ typedef struct { int x; int iconWidth; int labelWidth; } LevelInfo; /* * ComboTree -- * * A ComboTree is a widget that displays an hierarchical table of one or * more entries. * * Entries are positioned in "world" coordinates, referring to the * virtual combotree. Coordinate 0,0 is the upper-left corner of the root * entry and the bottom is the end of the last entry. The widget's Tk * window acts as view port into this virtual space. The combotree's * xOffset and yOffset fields specify the location of the view port in * the virtual world. Scrolling the viewport is therefore simply * changing the xOffset and/or yOffset fields and redrawing. * * Note that world coordinates are integers, not signed short integers * like X11 screen coordinates. It's very easy to create a hierarchy * taller than 0x7FFF pixels. */ struct _ComboTree { /* * This works around a bug in the Tk API. Under under Win32, Tk tries to * read the widget record of toplevel windows (TopLevel or Frame widget), * to get its menu name field. What this means is that we must carefully * arrange the fields of this widget so that the menuName field is at the * same offset in the structure. */ Tk_Window tkwin; /* Window that embodies the frame. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up. */ Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tcl_Command cmdToken; /* Token for widget's command. */ Tcl_Obj *postCmdObjPtr; /* If non-NULL, command to be executed when * this menu is posted. */ unsigned int flags; /* For bitfield definitions, see below */ Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, this * variable will be set to the name of the Tk * image representing the icon of the selected * item. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, this * variable will be set to the text string of * the label of the selected item. */ Tcl_Obj *takeFocusObjPtr; /* Value of -takefocus option; not used in the * C code, but used by keyboard traversal * scripts. */ const char *menuName; /* Textual description of menu to use for * menubar. Malloc-ed, may be NULL. */ Tk_Cursor cursor; /* Current cursor for window or None. */ /*------*/ Blt_Tree tree; /* Handle representing the tree. */ const char *treeName; Blt_HashEntry *hPtr; /* ComboTree_ specific fields. */ Blt_HashTable entryTable; /* Table of entry information, keyed by the * node pointer. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. * Indicates how much interior stuff must be * offset from outside edges to leave room for * borders. */ Style defStyle; int borderWidth; /* Width of 3D border. */ int relief; /* 3D border relief. */ /* * Entries are connected by horizontal and vertical lines. They may be * drawn dashed or solid. */ int lineWidth; /* Width of lines connecting entries */ int dashes; /* Dash on-off value. */ XColor *lineColor; /* Color of connecting lines. */ /* * Button Information: * * The button is the open/close indicator at the far left of the entry. * It is usually displayed as a plus or minus in a solid colored box with * optionally an border. It has both "active" and "normal" colors. */ Button button; int leader; /* Number of pixels padding between * entries. */ int reqWidth, reqHeight; /* Requested dimensions of the combotree * widget's window. */ GC lineGC; /* GC for drawing dotted line between * entries. */ Entry *activePtr; /* Last active entry. */ Entry *activeBtnPtr; /* Pointer to last active button */ Entry *fromPtr; /* Names of scrollbars to embed into the widget window. */ Tcl_Obj *xScrollbarObjPtr, *yScrollbarObjPtr; /* Command strings to control horizontal and vertical scrollbars. */ Tcl_Obj *xScrollCmdObjPtr, *yScrollCmdObjPtr; int xScrollUnits, yScrollUnits; /* # of pixels per scroll unit. */ /* * Total size of all "open" entries. This represents the range of world * coordinates. */ int worldWidth, worldHeight; int xOffset, yOffset; /* Translation between view port and world * origin. */ LevelInfo *levelInfo; /* Scanning information: */ int scanAnchorX, scanAnchorY; /* Scan anchor in screen coordinates. */ int scanX, scanY; /* X-Y world coordinate where the scan * started. */ Blt_HashTable iconTable; /* Table of Tk images */ Blt_HashTable uidTable; /* Table of strings. */ Blt_HashTable styleTable; /* Table of cell styles. */ Entry *rootPtr; /* Root entry of tree. */ Entry **visibleEntries; /* Array of visible entries */ int nVisible; /* Number of entries in the above array */ int nEntries; /* Number of entries in tree. */ int buttonFlags; /* Global button indicator for all entries. * This may be overridden by the entry's * -button option. */ const char *openCmd; const char *closeCmd; /* TCL commands to invoke when entries are * opened or closed. */ const char *pathSep; /* Pathname separators */ ClientData clientData; Blt_BindTable bindTable; /* Binding information for entries. */ Blt_HashTable entryBindTagTable; Blt_HashTable buttonBindTagTable; size_t depth; int flatView; /* Indicates if the view of the tree has been * flattened. */ Blt_Pool entryPool; Tk_Window xScrollbar; /* Horizontal scrollbar to be used if * necessary. If NULL, no x-scrollbar is * used. */ Tk_Window yScrollbar; /* Vertical scrollbar to be used if * necessary. If NULL, no y-scrollbar is * used. */ short int yScrollbarWidth, xScrollbarHeight; short int maxWidth; /* Width of the widest entry. */ short int minHeight; /* Minimum entry height. Used to to compute * what the y-scroll unit should be. */ }; /* * EntryIterator -- * * Entries may be tagged with strings. An entry may have many tags. The * same tag may be used for many entries. * */ typedef enum { ITER_INDEX, ITER_ALL, ITER_TAG, } IteratorType; typedef struct _Iterator { ComboTree *comboPtr; /* ComboTree that we're iterating over. */ IteratorType type; /* Type of iteration: * ITER_TAG By entry tag. * ITER_ALL By every entry. * ITER_INDEX Single entry: either * tag or index. */ Entry *first; /* Starting point of search, saved if iterator * is reused. Used for ITER_ALL and * ITER_INDEX searches. */ Entry *next; /* Next entry. */ /* For tag-based searches. */ const char *tagName; /* If non-NULL, is the tag that we are * currently iterating over. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Search iterator for tag hash table. */ } EntryIterator; #define BUTTON_IPAD 1 #define BUTTON_PAD 2 #define BUTTON_SIZE 7 #define COLUMN_PAD 2 #define FOCUS_WIDTH 1 #define ICON_HEIGHT 16 #define ICON_PADX 2 #define ICON_PADY 1 #define ICON_WIDTH 16 #define INSET_PAD 0 #define LABEL_PADX 3 #define LABEL_PADY 0 #include <X11/Xutil.h> #include <X11/Xatom.h> typedef ClientData (TagProc)(ComboTree *comboPtr, const char *string); typedef int (ApplyProc) (ComboTree *comboPtr, Entry *entryPtr); #define DEF_BTN_ACTIVE_BG RGB_WHITE #define DEF_BTN_ACTIVE_FG STD_ACTIVE_FOREGROUND #define DEF_BTN_BORDERWIDTH "1" #define DEF_BTN_CLOSE_RELIEF "solid" #define DEF_BTN_NORMAL_BG RGB_WHITE #define DEF_BTN_NORMAL_FG STD_NORMAL_FOREGROUND #define DEF_BTN_OPEN_RELIEF "solid" #define DEF_BTN_SIZE "7" #define DEF_COMBO_ACTIVE_STIPPLE "gray25" #define DEF_COMBO_BORDERWIDTH "1" #define DEF_COMBO_BUTTON "auto" #define DEF_COMBO_DASHES "dot" #define DEF_COMBO_HEIGHT "400" #define DEF_COMBO_HIDE_LEAVES "no" #define DEF_COMBO_HIDE_ROOT "yes" #define DEF_COMBO_ICON_VARIABLE ((char *)NULL) #define DEF_COMBO_LINESPACING "0" #define DEF_COMBO_LINEWIDTH "1" #define DEF_COMBO_MAKE_PATH "no" #define DEF_COMBO_NEWTAGS "no" #define DEF_COMBO_RELIEF "solid" #define DEF_COMBO_SCROLLBAR ((char *)NULL) #define DEF_COMBO_SCROLLINCREMENT "20" #define DEF_COMBO_SHOW_ROOT "yes" #define DEF_COMBO_TAKE_FOCUS "1" #define DEF_COMBO_TEXT_VARIABLE ((char *)NULL) #define DEF_COMBO_LINECOLOR RGB_GREY50 #define DEF_COMBO_WIDTH "0" #ifdef WIN32 #define DEF_COMBO_SEPARATOR "\\" #else #define DEF_COMBO_SEPARATOR "/" #endif #define DEF_ENTRY_STYLE "default" #define DEF_STYLE_ACTIVE_BG RGB_SKYBLUE4 #define DEF_STYLE_ACTIVE_FG RGB_WHITE #define DEF_STYLE_ACTIVE_RELIEF "flat" #define DEF_STYLE_ALT_BG ((char *)NULL) #define DEF_STYLE_BG "white" #define DEF_STYLE_BORDERWIDTH STD_BORDERWIDTH #define DEF_STYLE_FG STD_NORMAL_FOREGROUND #define DEF_STYLE_FONT "Courier 12" #define DEF_STYLE_ICONS "::blt::ComboTree::openIcon ::blt::ComboTree::closeIcon" #define DEF_STYLE_NORMAL_BG STD_NORMAL_BACKGROUND #define DEF_STYLE_RELIEF "flat" static Blt_TreeApplyProc CreateApplyProc; static Blt_OptionParseProc ObjToIconsProc; static Blt_OptionPrintProc IconsToObjProc; static Blt_OptionFreeProc FreeIconsProc; static Blt_CustomOption iconsOption = { ObjToIconsProc, IconsToObjProc, FreeIconsProc, NULL, }; static Blt_OptionParseProc ObjToButtonProc; static Blt_OptionPrintProc ButtonToObjProc; static Blt_CustomOption buttonOption = { ObjToButtonProc, ButtonToObjProc, NULL, NULL, }; static Blt_OptionParseProc ObjToUidProc; static Blt_OptionPrintProc UidToObjProc; static Blt_OptionFreeProc FreeUidProc; static Blt_CustomOption uidOption = { ObjToUidProc, UidToObjProc, FreeUidProc, NULL, }; static Blt_OptionParseProc ObjToLabelProc; static Blt_OptionPrintProc LabelToObjProc; static Blt_OptionFreeProc FreeLabelProc; static Blt_CustomOption labelOption = { ObjToLabelProc, LabelToObjProc, FreeLabelProc, NULL, }; static Blt_OptionParseProc ObjToStyleProc; static Blt_OptionPrintProc StyleToObjProc; static Blt_OptionFreeProc FreeStyleProc; static Blt_CustomOption styleOption = { ObjToStyleProc, StyleToObjProc, FreeStyleProc, NULL, }; static Blt_ConfigSpec buttonSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Background", DEF_BTN_ACTIVE_BG, Blt_Offset(ComboTree, button.activeBg), 0}, {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-activefg", "activeForeground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "Foreground", DEF_BTN_ACTIVE_FG, Blt_Offset(ComboTree, button.activeFgColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BTN_NORMAL_BG, Blt_Offset(ComboTree, button.normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BTN_BORDERWIDTH, Blt_Offset(ComboTree, button.borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-closerelief", "closeRelief", "Relief", DEF_BTN_CLOSE_RELIEF, Blt_Offset(ComboTree, button.closeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_BTN_NORMAL_FG, Blt_Offset(ComboTree, button.fgColor), 0}, {BLT_CONFIG_CUSTOM, "-images", "images", "Icons", (char *)NULL, Blt_Offset(ComboTree, button.icons), BLT_CONFIG_NULL_OK, &iconsOption}, {BLT_CONFIG_RELIEF, "-openrelief", "openRelief", "Relief", DEF_BTN_OPEN_RELIEF, Blt_Offset(ComboTree, button.openRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-size", "size", "Size", DEF_BTN_SIZE, Blt_Offset(ComboTree, button.reqSize), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec entrySpecs[] = { {BLT_CONFIG_CUSTOM, "-bindtags", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Entry, tagsObjPtr), BLT_CONFIG_NULL_OK, &uidOption}, {BLT_CONFIG_CUSTOM, "-button", (char *)NULL, (char *)NULL, DEF_COMBO_BUTTON, Blt_Offset(Entry, flags), BLT_CONFIG_DONT_SET_DEFAULT, &buttonOption}, {BLT_CONFIG_CUSTOM, "-closecommand", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Entry, closeCmd), BLT_CONFIG_NULL_OK, &uidOption}, {BLT_CONFIG_PIXELS_NNEG, "-height", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Entry, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-label", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Entry, labelUid), 0, &labelOption}, {BLT_CONFIG_CUSTOM, "-opencommand", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Entry, openCmd), BLT_CONFIG_NULL_OK, &uidOption}, {BLT_CONFIG_CUSTOM, "-style", (char *)NULL, (char *)NULL, DEF_ENTRY_STYLE, Blt_Offset(Entry, stylePtr), 0, &styleOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec styleSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_BG, Blt_Offset(Style, activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", (char *)NULL, (char *)NULL, DEF_STYLE_ACTIVE_FG, Blt_Offset(Style, labelActiveColor), 0}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", DEF_STYLE_ACTIVE_RELIEF, Blt_Offset(Style, activeRelief), 0}, {BLT_CONFIG_BACKGROUND, "-alternatebackground", "alternateBackground", "Background", DEF_STYLE_ALT_BG, Blt_Offset(Style, altBg), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_STYLE_BG, Blt_Offset(Style, normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_STYLE_BORDERWIDTH, Blt_Offset(Style, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_STYLE_FONT, Blt_Offset(Style, labelFont), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_STYLE_FG, Blt_Offset(Style, labelNormalColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_CUSTOM, "-icons", (char *)NULL, (char *)NULL, DEF_STYLE_ICONS, Blt_Offset(Style, icons), BLT_CONFIG_NULL_OK, &iconsOption}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_STYLE_RELIEF, Blt_Offset(Style, relief), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec comboSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "ActiveBackground", DEF_STYLE_ACTIVE_BG, Blt_Offset(ComboTree, defStyle.activeBg), 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", DEF_STYLE_ACTIVE_FG, Blt_Offset(ComboTree, defStyle.labelActiveColor), 0}, {BLT_CONFIG_BACKGROUND, "-alternatebackground", "alternateBackground", "Background", DEF_STYLE_ALT_BG, Blt_Offset(ComboTree, defStyle.altBg), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_STYLE_BG, Blt_Offset(ComboTree, defStyle.normalBg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_COMBO_BORDERWIDTH, Blt_Offset(ComboTree, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-button", "button", "Button", DEF_COMBO_BUTTON, Blt_Offset(ComboTree, buttonFlags), BLT_CONFIG_DONT_SET_DEFAULT, &buttonOption}, {BLT_CONFIG_STRING, "-closecommand", "closeCommand", "CloseCommand", (char *)NULL, Blt_Offset(ComboTree, closeCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", (char *)NULL, Blt_Offset(ComboTree, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_COMBO_DASHES, Blt_Offset(ComboTree, dashes), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_STYLE_FONT, Blt_Offset(ComboTree, defStyle.labelFont), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_STYLE_FG, Blt_Offset(ComboTree, defStyle.labelNormalColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_PIXELS, "-height", "height", "Height", DEF_COMBO_HEIGHT, Blt_Offset(ComboTree, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hideleaves", "hideLeaves", "HideLeaves", DEF_COMBO_HIDE_LEAVES, Blt_Offset(ComboTree, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE_LEAVES}, {BLT_CONFIG_BITMASK, "-hideroot", "hideRoot", "HideRoot", DEF_COMBO_HIDE_ROOT, Blt_Offset(ComboTree, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE_ROOT}, {BLT_CONFIG_OBJ, "-iconvariable", "iconVariable", "IconVariable", DEF_COMBO_ICON_VARIABLE, Blt_Offset(ComboTree, iconVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-icons", "icons", "Icons", DEF_STYLE_ICONS, Blt_Offset(ComboTree, defStyle.icons), BLT_CONFIG_NULL_OK, &iconsOption}, {BLT_CONFIG_COLOR, "-linecolor", "lineColor", "LineColor", DEF_COMBO_LINECOLOR, Blt_Offset(ComboTree, lineColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_PIXELS_NNEG, "-linespacing", "lineSpacing", "LineSpacing", DEF_COMBO_LINESPACING, Blt_Offset(ComboTree, leader), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_COMBO_LINEWIDTH, Blt_Offset(ComboTree, lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-newtags", "newTags", "NewTags", DEF_COMBO_NEWTAGS, Blt_Offset(ComboTree, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)NEW_TAGS}, {BLT_CONFIG_STRING, "-opencommand", "openCommand", "OpenCommand", (char *)NULL, Blt_Offset(ComboTree, openCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_COMBO_RELIEF, Blt_Offset(ComboTree, relief), 0}, {BLT_CONFIG_STRING, "-separator", "separator", "Separator", DEF_COMBO_SEPARATOR, Blt_Offset(ComboTree, pathSep), BLT_CONFIG_NULL_OK, 0}, {BLT_CONFIG_OBJ, "-takefocus", "takeFocus", "TakeFocus", DEF_COMBO_TAKE_FOCUS, Blt_Offset(ComboTree, takeFocusObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-textvariable", "textVariable", "TextVariable", DEF_COMBO_TEXT_VARIABLE, Blt_Offset(ComboTree, textVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-tree", "tree", "Tree", (char *)NULL, Blt_Offset(ComboTree, treeName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS, "-width", "width", "Width", DEF_COMBO_WIDTH, Blt_Offset(ComboTree, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-xscrollbar", "xScrollbar", "Scrollbar", DEF_COMBO_SCROLLBAR, Blt_Offset(ComboTree, xScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(ComboTree, xScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_COMBO_SCROLLINCREMENT, Blt_Offset(ComboTree, xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yscrollbar", "yScrollbar", "Scrollbar", DEF_COMBO_SCROLLBAR, Blt_Offset(ComboTree, yScrollbarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(ComboTree, yScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_COMBO_SCROLLINCREMENT, Blt_Offset(ComboTree, yScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Forward Declarations */ static Tcl_IdleProc ConfigureScrollbarsProc; static Blt_BindPickProc PickEntry; static Blt_BindTagProc GetTags; static Blt_TreeNotifyEventProc TreeEventProc; static Tcl_CmdDeleteProc ComboTreeInstCmdDeleteProc; static Tcl_FreeProc DestroyComboTree; static Tcl_FreeProc DestroyEntry; static Tcl_IdleProc DisplayComboTree; static Tcl_IdleProc DisplayEntry; static Tcl_ObjCmdProc ComboTreeInstCmdProc; static Tcl_ObjCmdProc ComboTreeObjCmdProc; static Tk_EventProc ComboTreeEventProc; static Tk_EventProc ScrollbarEventProc; static Tk_ImageChangedProc IconChangedProc; static Tk_GeomRequestProc ScrollbarGeometryProc; static Tk_GeomLostSlaveProc ScrollbarCustodyProc; static Tk_GeomMgr comboMgrInfo = { (char *)"combomenu", /* Name of geometry manager used by winfo */ ScrollbarGeometryProc, /* Procedure to for new geometry requests */ ScrollbarCustodyProc, /* Procedure when scrollbar is taken away */ }; static int ComputeVisibleEntries(ComboTree *comboPtr); typedef int (ComboTreeCmdProc)(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(ComboTree *comboPtr) { if ((comboPtr->tkwin != NULL) && ((comboPtr->flags & REDRAW_PENDING)==0)) { comboPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayComboTree, comboPtr); } } /* *--------------------------------------------------------------------------- * * EventuallyRedrawEntry -- * * Tells the Tk dispatcher to call the combomenu display routine at the * next idle point. This request is made only if the window is displayed * and no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawEntry(Entry *entryPtr) { ComboTree *comboPtr; comboPtr = entryPtr->comboPtr; if ((comboPtr->tkwin != NULL) && ((comboPtr->flags & REDRAW_PENDING)==0) && ((entryPtr->flags & ENTRY_REDRAW) == 0)) { Tcl_DoWhenIdle(DisplayEntry, entryPtr); entryPtr->flags |= ENTRY_REDRAW; } } static void ConfigureScrollbarsProc(ClientData clientData) { ComboTree *comboPtr = clientData; Tcl_Interp *interp; interp = comboPtr->interp; /* * Execute the initialization procedure on this widget. */ comboPtr->flags &= ~UPDATE_PENDING; if (Tcl_VarEval(interp, "::blt::ComboTree::ConfigureScrollbars ", Tk_PathName(comboPtr->tkwin), (char *)NULL) != TCL_OK) { Tcl_BackgroundError(interp); } } static void UnmanageScrollbar(ComboTree *comboPtr, Tk_Window tkwin) { if (tkwin != NULL) { Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ScrollbarEventProc, comboPtr); Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL, comboPtr); if (Tk_IsMapped(tkwin)) { Tk_UnmapWindow(tkwin); } } } static void ManageScrollbar(ComboTree *comboPtr, Tk_Window tkwin) { if (tkwin != NULL) { Tk_CreateEventHandler(tkwin, StructureNotifyMask, ScrollbarEventProc, comboPtr); Tk_ManageGeometry(tkwin, &comboMgrInfo, comboPtr); } } /* *--------------------------------------------------------------------------- * * InstallScrollbar -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void InstallScrollbar( Tcl_Interp *interp, /* Interpreter to send results back to */ ComboTree *comboPtr, Tcl_Obj *objPtr, /* String representing scrollbar window. */ Tk_Window *tkwinPtr) { Tk_Window tkwin; if (objPtr == NULL) { *tkwinPtr = NULL; return; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objPtr), comboPtr->tkwin); if (tkwin == NULL) { Tcl_BackgroundError(interp); return; } if (Tk_Parent(tkwin) != comboPtr->tkwin) { Tcl_AppendResult(interp, "scrollbar \"", Tk_PathName(tkwin), "\" must be a child of combomenu.", (char *)NULL); Tcl_BackgroundError(interp); return; } ManageScrollbar(comboPtr, tkwin); *tkwinPtr = tkwin; return; } static void InstallXScrollbar(ClientData clientData) { ComboTree *comboPtr = clientData; comboPtr->flags &= ~INSTALL_SCROLLBAR_X; InstallScrollbar(comboPtr->interp, comboPtr, comboPtr->xScrollbarObjPtr, &comboPtr->xScrollbar); } static void InstallYScrollbar(ClientData clientData) { ComboTree *comboPtr = clientData; comboPtr->flags &= ~INSTALL_SCROLLBAR_Y; InstallScrollbar(comboPtr->interp, comboPtr, comboPtr->yScrollbarObjPtr, &comboPtr->yScrollbar); } static Entry * NodeToEntry(ComboTree *comboPtr, Blt_TreeNode node) { Blt_HashEntry *hPtr; if (node == NULL) { return NULL; } hPtr = Blt_FindHashEntry(&comboPtr->entryTable, (char *)node); if (hPtr == NULL) { fprintf(stderr, "NodeToEntry: can't find node %s\n", Blt_Tree_NodeLabel(node)); abort(); return NULL; } return Blt_GetHashValue(hPtr); } static Entry * ParentEntry(Entry *entryPtr) { ComboTree *comboPtr = entryPtr->comboPtr; Blt_TreeNode node; if (entryPtr->node == Blt_Tree_RootNode(comboPtr->tree)) { return NULL; } node = Blt_Tree_ParentNode(entryPtr->node); if (node == NULL) { return NULL; } return NodeToEntry(comboPtr, node); } static int EntryIsHidden(Entry *entryPtr) { ComboTree *comboPtr = entryPtr->comboPtr; if ((comboPtr->flags & HIDE_LEAVES) && (Blt_Tree_IsLeaf(entryPtr->node))) { return TRUE; } return (entryPtr->flags & ENTRY_HIDE) ? TRUE : FALSE; } static Entry * GetEntryFromNode(ComboTree *comboPtr, Blt_TreeNode node) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->entryTable, (char *)node); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } static Entry * FirstChild(Entry *entryPtr, unsigned int mask) { Blt_TreeNode node; ComboTree *comboPtr = entryPtr->comboPtr; for (node = Blt_Tree_FirstChild(entryPtr->node); node != NULL; node = Blt_Tree_NextSibling(node)) { entryPtr = NodeToEntry(comboPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } static Entry * LastChild(Entry *entryPtr, unsigned int mask) { Blt_TreeNode node; ComboTree *comboPtr = entryPtr->comboPtr; for (node = Blt_Tree_LastChild(entryPtr->node); node != NULL; node = Blt_Tree_PrevSibling(node)) { entryPtr = NodeToEntry(comboPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } static Entry * NextSibling(Entry *entryPtr, unsigned int mask) { Blt_TreeNode node; ComboTree *comboPtr = entryPtr->comboPtr; for (node = Blt_Tree_NextSibling(entryPtr->node); node != NULL; node = Blt_Tree_NextSibling(node)) { entryPtr = NodeToEntry(comboPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } static Entry * PrevSibling(Entry *entryPtr, unsigned int mask) { Blt_TreeNode node; ComboTree *comboPtr = entryPtr->comboPtr; for (node = Blt_Tree_PrevSibling(entryPtr->node); node != NULL; node = Blt_Tree_PrevSibling(node)) { entryPtr = NodeToEntry(comboPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * PrevEntry -- * * Returns the "previous" node in the tree. This node (in * depth-first order) is its parent if the node has no siblings * that are previous to it. Otherwise it is the last descendant * of the last sibling. In this case, descend the sibling's * hierarchy, using the last child at any ancestor, until we * we find a leaf. * *--------------------------------------------------------------------------- */ static Entry * PrevEntry(Entry *entryPtr, unsigned int mask) { ComboTree *comboPtr = entryPtr->comboPtr; Entry *prevPtr; if (entryPtr->node == Blt_Tree_RootNode(comboPtr->tree)) { return NULL; /* The root is the first node. */ } prevPtr = PrevSibling(entryPtr, mask); if (prevPtr == NULL) { /* There are no siblings previous to this one, so pick the parent. */ prevPtr = ParentEntry(entryPtr); } else { /* * Traverse down the right-most thread in order to select the * last entry. Stop if we find a "closed" entry or reach a leaf. */ entryPtr = prevPtr; while ((entryPtr->flags & mask) == 0) { entryPtr = LastChild(entryPtr, mask); if (entryPtr == NULL) { break; /* Found a leaf. */ } prevPtr = entryPtr; } } if (prevPtr == NULL) { return NULL; } return prevPtr; } /* *--------------------------------------------------------------------------- * * NextEntry -- * * Returns the "next" node in relation to the given node. * The next node (in depth-first order) is either the first * child of the given node the next sibling if the node has * no children (the node is a leaf). If the given node is the * last sibling, then try it's parent next sibling. Continue * until we either find a next sibling for some ancestor or * we reach the root node. In this case the current node is * the last node in the tree. * *--------------------------------------------------------------------------- */ static Entry * NextEntry(Entry *entryPtr, unsigned int mask) { ComboTree *comboPtr = entryPtr->comboPtr; Entry *nextPtr; int ignoreLeaf; ignoreLeaf = ((comboPtr->flags & HIDE_LEAVES) && (Blt_Tree_IsLeaf(entryPtr->node))); if ((!ignoreLeaf) && ((entryPtr->flags & mask) == 0)) { nextPtr = FirstChild(entryPtr, mask); if (nextPtr != NULL) { return nextPtr; /* Pick the first sub-node. */ } } /* * Back up until to a level where we can pick a "next sibling". * For the last entry we'll thread our way back to the root. */ while (entryPtr != comboPtr->rootPtr) { nextPtr = NextSibling(entryPtr, mask); if (nextPtr != NULL) { return nextPtr; } entryPtr = ParentEntry(entryPtr); } return NULL; /* At root, no next node. */ } static Entry * LastEntry(ComboTree *comboPtr, Entry *entryPtr, unsigned int mask) { Blt_TreeNode next; Entry *nextPtr; next = Blt_Tree_LastChild(entryPtr->node); while (next != NULL) { nextPtr = NodeToEntry(comboPtr, next); if ((nextPtr->flags & mask) != mask) { break; } entryPtr = nextPtr; next = Blt_Tree_LastChild(next); } return entryPtr; } /* *--------------------------------------------------------------------------- * * NearestEntry -- * * Finds the entry closest to the given screen X-Y coordinates * in the viewport. * * Results: * Returns the pointer to the closest node. If no node is * visible (nodes may be hidden), NULL is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Entry * NearestEntry(ComboTree *comboPtr, int x, int y, int selectOne) { Entry *lastPtr; Entry **p; /* * We implicitly can pick only visible entries. So make sure that * the tree exists. */ if (comboPtr->nVisible == 0) { return NULL; } if (y < 0) { return (selectOne) ? comboPtr->visibleEntries[0] : NULL; } /* * Since the entry positions were previously computed in world * coordinates, convert Y-coordinate from screen to world * coordinates too. */ y = WORLDY(comboPtr, y); lastPtr = comboPtr->visibleEntries[0]; for (p = comboPtr->visibleEntries; *p != NULL; p++) { Entry *entryPtr; entryPtr = *p; /* * If the start of the next entry starts beyond the point, * use the last entry. */ if (entryPtr->worldY > y) { return (selectOne) ? entryPtr : NULL; } if (y < (entryPtr->worldY + entryPtr->height)) { return entryPtr; /* Found it. */ } lastPtr = entryPtr; } return (selectOne) ? lastPtr : NULL; } static Entry * FindEntryByLabel(ComboTree *comboPtr, const char *string) { Entry *entryPtr; entryPtr = comboPtr->rootPtr; if (comboPtr->activePtr != NULL) { entryPtr = comboPtr->activePtr; } for (/*empty*/; entryPtr != NULL; entryPtr = NextEntry(entryPtr, ENTRY_MASK)){ if (strcmp(GETLABEL(entryPtr), string) == 0) { return entryPtr; } } return NULL; } static void DestroyEntry(DestroyData data) { Entry *entryPtr = (Entry *)data; ComboTree *comboPtr; comboPtr = entryPtr->comboPtr; iconsOption.clientData = comboPtr; uidOption.clientData = comboPtr; labelOption.clientData = comboPtr; Blt_FreeOptions(entrySpecs, (char *)entryPtr, comboPtr->display, 0); if (!Blt_Tree_TagTableIsShared(comboPtr->tree)) { /* Don't clear tags unless this client is the only one using * the tag table.*/ Blt_Tree_ClearTags(comboPtr->tree, entryPtr->node); } if (entryPtr->textPtr != NULL) { Blt_Free(entryPtr->textPtr); } Blt_PoolFreeItem(comboPtr->entryPool, entryPtr); } static void FreeEntry(ComboTree *comboPtr, Entry *entryPtr) { if (entryPtr == comboPtr->activePtr) { comboPtr->activePtr = ParentEntry(entryPtr); } if (entryPtr == comboPtr->activeBtnPtr) { comboPtr->activeBtnPtr = NULL; } Blt_DeleteBindings(comboPtr->bindTable, entryPtr); if (entryPtr->hPtr != NULL) { Blt_DeleteHashEntry(&comboPtr->entryTable, entryPtr->hPtr); } entryPtr->node = NULL; Tcl_EventuallyFree(entryPtr, DestroyEntry); /* * Indicate that the screen layout of the hierarchy may have changed * because this node was deleted. The screen positions of the nodes * in comboPtr->visibleEntries are invalidated. */ comboPtr->flags |= (LAYOUT_PENDING | DIRTY); EventuallyRedraw(comboPtr); } static void DestroyEntries(ComboTree *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; /* Release the current tree, removing any entry fields. */ for (hPtr = Blt_FirstHashEntry(&comboPtr->entryTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Entry *entryPtr; entryPtr = Blt_GetHashValue(hPtr); entryPtr->hPtr = NULL; FreeEntry(comboPtr, entryPtr); } Blt_DeleteHashTable(&comboPtr->entryTable); } static const char * GetFullName( ComboTree *comboPtr, Entry *entryPtr, Tcl_DString *resultPtr) { const char **names; /* Used the stack the component names. */ const char *staticSpace[64+2]; int level; int i; level = Blt_Tree_NodeDepth(entryPtr->node); if (GETLABEL(comboPtr->rootPtr) == NULL) { level--; } if (level > 64) { names = Blt_AssertMalloc((level + 2) * sizeof(char *)); } else { names = staticSpace; } for (i = level; i >= 0; i--) { Blt_TreeNode node; /* Save the name of each ancestor in the name array. */ names[i] = GETLABEL(entryPtr); node = Blt_Tree_ParentNode(entryPtr->node); if (node != NULL) { entryPtr = NodeToEntry(comboPtr, node); } } if (level >= 0) { if (comboPtr->pathSep == NULL) { for (i = 0; i <= level; i++) { Tcl_DStringAppendElement(resultPtr, names[i]); } } else { Tcl_DStringAppend(resultPtr, names[0], -1); for (i = 1; i <= level; i++) { Tcl_DStringAppend(resultPtr, comboPtr->pathSep, -1); Tcl_DStringAppend(resultPtr, names[i], -1); } } } else { if (comboPtr->pathSep != NULL) { Tcl_DStringAppend(resultPtr, comboPtr->pathSep, -1); } } if (names != staticSpace) { Blt_Free(names); } return Tcl_DStringValue(resultPtr); } /* * Preprocess the command string for percent substitution. */ static void PercentSubst( ComboTree *comboPtr, Entry *entryPtr, const char *command, Tcl_DString *resultPtr) { const char *last, *p; const char *fullName; Tcl_DString ds; /* * Get the full path name of the node, in case we need to substitute for * it. */ Tcl_DStringInit(&ds); fullName = GetFullName(comboPtr, entryPtr, &ds); Tcl_DStringInit(resultPtr); /* Append the widget name and the node .t 0 */ for (last = p = command; *p != '\0'; p++) { if (*p == '%') { const char *string; char buf[3]; if (p > last) { Tcl_DStringAppend(resultPtr, last, p - last); } switch (*(p + 1)) { case '%': /* Percent sign */ string = "%"; break; case 'W': /* Widget name */ string = Tk_PathName(comboPtr->tkwin); break; case 'P': /* Full pathname */ string = fullName; break; case 'p': /* Name of the node */ string = GETLABEL(entryPtr); break; case '#': /* Node identifier */ string = Blt_Tree_NodeIdAscii(entryPtr->node); break; default: if (*(p + 1) == '\0') { p--; } buf[0] = *p, buf[1] = *(p + 1), buf[2] = '\0'; string = buf; break; } Tcl_DStringAppend(resultPtr, string, -1); p++; last = p + 1; } } if (p > last) { Tcl_DStringAppend(resultPtr, last, p-last); } Tcl_DStringFree(&ds); } static int CloseEntry(ComboTree *comboPtr, Entry *entryPtr) { const char *cmd; if (entryPtr->flags & ENTRY_CLOSED) { return TCL_OK; /* Entry is already closed. */ } entryPtr->flags |= ENTRY_CLOSED; /* * Invoke the entry's "close" command, if there is one. Otherwise * try the treeview's global "close" command. */ cmd = CHOOSE(comboPtr->closeCmd, entryPtr->closeCmd); if (cmd != NULL) { Tcl_DString ds; int result; PercentSubst(comboPtr, entryPtr, cmd, &ds); Tcl_Preserve(entryPtr); result = Tcl_GlobalEval(comboPtr->interp, Tcl_DStringValue(&ds)); Tcl_Release(entryPtr); Tcl_DStringFree(&ds); if (result != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= LAYOUT_PENDING; return TCL_OK; } static int OpenEntry(ComboTree *comboPtr, Entry *entryPtr) { const char *cmd; if ((entryPtr->flags & ENTRY_CLOSED) == 0) { return TCL_OK; /* Entry is already open. */ } entryPtr->flags &= ~ENTRY_CLOSED; /* * If there's a "open" command proc specified for the entry, use that * instead of the more general "open" proc for the entire treeview. */ cmd = CHOOSE(comboPtr->openCmd, entryPtr->openCmd); if (cmd != NULL) { Tcl_DString ds; int result; PercentSubst(comboPtr, entryPtr, cmd, &ds); Tcl_Preserve(entryPtr); result = Tcl_GlobalEval(comboPtr->interp, Tcl_DStringValue(&ds)); Tcl_Release(entryPtr); Tcl_DStringFree(&ds); if (result != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= LAYOUT_PENDING; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ActivateEntry -- * * Marks the designated entry as active. The entry is redrawn with its * active colors. The previously active entry is deactivated. If the * new entry is NULL, then this means that no new entry is to be * activated. * * Results: * None. * * Side effects: * Individual entries entries may be scheduled to be drawn. * *--------------------------------------------------------------------------- */ static void ActivateEntry(ComboTree *comboPtr, Entry *entryPtr) { if ((comboPtr->activePtr == entryPtr) && (entryPtr != NULL)) { return; /* Entry is already active. */ } if (comboPtr->activePtr != NULL) { EventuallyRedrawEntry(comboPtr->activePtr); } comboPtr->activePtr = entryPtr; if (entryPtr != NULL) { EventuallyRedrawEntry(entryPtr); } } static int ConfigureEntry( ComboTree *comboPtr, Entry *entryPtr, int objc, Tcl_Obj *const *objv, int flags) { iconsOption.clientData = comboPtr; uidOption.clientData = comboPtr; labelOption.clientData = comboPtr; if (Blt_ConfigureWidgetFromObj(comboPtr->interp, comboPtr->tkwin, entrySpecs, objc, objv, (char *)entryPtr, flags) != TCL_OK) { return TCL_ERROR; } /* Assume all changes require a new layout. */ entryPtr->flags |= ENTRY_LAYOUT_PENDING; comboPtr->flags |= (LAYOUT_PENDING | DIRTY); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NewEntry -- * * Allocates and initializes a new entry. * * Results: * Returns the entry. * *--------------------------------------------------------------------------- */ static Entry * NewEntry(ComboTree *comboPtr, Blt_TreeNode node) { Entry *entryPtr; entryPtr = Blt_PoolAllocItem(comboPtr->entryPool, sizeof(Entry)); memset(entryPtr, 0, sizeof(Entry)); entryPtr->flags = (unsigned short)(comboPtr->buttonFlags | ENTRY_CLOSED); entryPtr->comboPtr = comboPtr; entryPtr->labelUid = NULL; entryPtr->node = node; return entryPtr; } /* *--------------------------------------------------------------------------- * * CreateEntry -- * * This procedure is called by the Tree object when a node is created and * inserted into the tree. It adds a new treeview entry field to the * node. * * Results: * Returns the entry. * *--------------------------------------------------------------------------- */ static int CreateEntry( ComboTree *comboPtr, Blt_TreeNode node, /* Node that has just been created. */ int objc, Tcl_Obj *const *objv, int flags) { Entry *entryPtr; int isNew; Blt_HashEntry *hPtr; hPtr = Blt_CreateHashEntry(&comboPtr->entryTable, (char *)node, &isNew); if (isNew) { entryPtr = NewEntry(comboPtr, node); Blt_SetHashValue(hPtr, entryPtr); entryPtr->hPtr = hPtr; } else { entryPtr = Blt_GetHashValue(hPtr); } if (ConfigureEntry(comboPtr, entryPtr, objc, objv, flags) != TCL_OK) { FreeEntry(comboPtr, entryPtr); return TCL_ERROR; /* Error configuring the entry. */ } comboPtr->flags |= (LAYOUT_PENDING | DIRTY); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetTagTable -- * * Returns the hash table containing row indices for a tag. * * Results: * Returns a pointer to the hash table containing indices for the given * tag. If the row has no tags, then NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_HashTable * GetTagTable(ComboTree *comboPtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->entryBindTagTable, tagName); if (hPtr == NULL) { return NULL; /* No tag by that name. */ } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * GetEntryIterator -- * * Converts a string into node pointer. The string may be in one of the * following forms: * * NNN - inode. * "active" - Currently active node. * "anchor" - anchor of selected region. * "current" - Currently picked node in bindtable. * "focus" - The node currently with focus. * "root" - Root node. * "end" - Last open node in the entire hierarchy. * "next" - Next open node from the currently active * node. Wraps around back to top. * "last" - Previous open node from the currently active * node. Wraps around back to bottom. * "up" - Next open node from the currently active * node. Does not wrap around. * "down" - Previous open node from the currently active * node. Does not wrap around. * "nextsibling" - Next sibling of the current node. * "prevsibling" - Previous sibling of the current node. * "parent" - Parent of the current node. * "view.top" - Top of viewport. * "view.bottom" - Bottom of viewport. * @x,y - Closest node to the specified X-Y position. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via nodePtr. Otherwise, TCL_ERROR is * returned and an error message is left in interpreter's result field. * *--------------------------------------------------------------------------- */ static int GetEntryIterator( Tcl_Interp *interp, ComboTree *comboPtr, Tcl_Obj *objPtr, EntryIterator *iterPtr) { Entry *entryPtr, *fromPtr; char c; const char *string; iterPtr->first = NULL; iterPtr->type = ITER_INDEX; string = Tcl_GetString(objPtr); iterPtr->tagName = Tcl_GetString(objPtr); entryPtr = NULL; fromPtr = comboPtr->activePtr; if (fromPtr == NULL) { fromPtr = comboPtr->rootPtr; } c = string[0]; if (isdigit(UCHAR(string[0]))) { Blt_TreeNode node; long inode; if (Tcl_GetLongFromObj(interp, objPtr, &inode) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_GetNode(comboPtr->tree, inode); if (node != NULL) { iterPtr->first = NodeToEntry(comboPtr, node); } return TCL_OK; /* Node Id. */ } if (c == '@') { int x, y; if (Blt_GetXY(interp, comboPtr->tkwin, string, &x, &y) == TCL_OK) { iterPtr->first = NearestEntry(comboPtr, x, y, TRUE); } } else if ((c == 'a') && (strcmp(string, "all") == 0)) { iterPtr->first = comboPtr->rootPtr; iterPtr->type = ITER_ALL; } else if ((c == 'a') && (strcmp(string, "active") == 0)) { iterPtr->first = comboPtr->activePtr; } else if ((c == 'b') && (strcmp(string, "bottom") == 0)) { iterPtr->first = LastEntry(comboPtr, comboPtr->rootPtr, ENTRY_MASK); } else if ((c == 't') && (strcmp(string, "top") == 0)) { entryPtr = comboPtr->rootPtr; if (comboPtr->flags & HIDE_ROOT) { entryPtr = NextEntry(entryPtr, ENTRY_MASK); } iterPtr->first = entryPtr; } else if ((c == 'e') && (strcmp(string, "end") == 0)) { iterPtr->first = LastEntry(comboPtr, comboPtr->rootPtr, ENTRY_MASK); } else if ((c == 'r') && (strcmp(string, "root") == 0)) { iterPtr->first = comboPtr->rootPtr; } else if ((c == 'p') && (strcmp(string, "parent") == 0)) { if (fromPtr != comboPtr->rootPtr) { iterPtr->first = ParentEntry(fromPtr); } } else if ((c == 'c') && (strcmp(string, "current") == 0)) { /* Can't trust picked entry, if entries have been added or deleted. */ if (!(comboPtr->flags & DIRTY)) { ClientData context; context = Blt_GetCurrentContext(comboPtr->bindTable); if ((context == PICK_ENTRY) || (context == PICK_BUTTON)) { iterPtr->first = Blt_GetCurrentItem(comboPtr->bindTable); } } } else if ((c == 'u') && (strcmp(string, "up") == 0)) { entryPtr = PrevEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = fromPtr; } if ((entryPtr == comboPtr->rootPtr) && (comboPtr->flags & HIDE_ROOT)) { entryPtr = NextEntry(entryPtr, ENTRY_MASK); } iterPtr->first = entryPtr; } else if ((c == 'd') && (strcmp(string, "down") == 0)) { entryPtr = NextEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = fromPtr; } if ((entryPtr == comboPtr->rootPtr) && (comboPtr->flags & HIDE_ROOT)) { entryPtr = NextEntry(entryPtr, ENTRY_MASK); } iterPtr->first = entryPtr; } else if (((c == 'l') && (strcmp(string, "last") == 0)) || ((c == 'p') && (strcmp(string, "prev") == 0))) { entryPtr = PrevEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { entryPtr = LastEntry(comboPtr, comboPtr->rootPtr, ENTRY_MASK); } if ((entryPtr == comboPtr->rootPtr) && (comboPtr->flags & HIDE_ROOT)) { entryPtr = NextEntry(entryPtr, ENTRY_MASK); } iterPtr->first = entryPtr; } else if ((c == 'n') && (strcmp(string, "next") == 0)) { entryPtr = NextEntry(fromPtr, ENTRY_MASK); if (entryPtr == NULL) { if (comboPtr->flags & HIDE_ROOT) { entryPtr = NextEntry(comboPtr->rootPtr,ENTRY_MASK); } else { entryPtr = comboPtr->rootPtr; } } iterPtr->first = entryPtr; } else if ((c == 'n') && (strcmp(string, "nextsibling") == 0)) { iterPtr->first = NextSibling(fromPtr, ENTRY_MASK); } else if ((c == 'n') && (strcmp(string, "none") == 0)) { iterPtr->first = NULL; } else if ((c == 'p') && (strcmp(string, "prevsibling") == 0)) { iterPtr->first = PrevSibling(fromPtr, ENTRY_MASK); } else if ((c == 'v') && (strcmp(string, "view.top") == 0)) { if (comboPtr->nVisible > 0) { iterPtr->first = comboPtr->visibleEntries[0]; } } else if ((c == 'v') && (strcmp(string, "view.bottom") == 0)) { if (comboPtr->nVisible > 0) { iterPtr->first = comboPtr->visibleEntries[comboPtr->nVisible - 1]; } } else { entryPtr = FindEntryByLabel(comboPtr, iterPtr->tagName); if (entryPtr != NULL) { iterPtr->first = entryPtr; } else { iterPtr->tablePtr = GetTagTable(comboPtr, iterPtr->tagName); if (iterPtr->tablePtr != NULL) { iterPtr->type = ITER_TAG; return TCL_OK; } if (interp != NULL) { Tcl_AppendResult(interp, "can't find tag or entry \"", string, "\" in \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NextTaggedEntry -- * * Returns the next entry derived from the given tag. * * Results: * Returns the row location of the first entry. If no more rows can be * found, then -1 is returned. * *--------------------------------------------------------------------------- */ static Entry * NextTaggedEntry(EntryIterator *iterPtr) { if (iterPtr->type == ITER_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } else if (iterPtr->type == ITER_ALL) { Entry *entryPtr; entryPtr = iterPtr->next; if (entryPtr != NULL) { iterPtr->next = NextEntry(entryPtr, ENTRY_MASK); } return entryPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * FirstTaggedEntry -- * * Returns the first entry derived from the given tag. * * Results: * Returns the row location of the first entry. If no more rows can be * found, then -1 is returned. * *--------------------------------------------------------------------------- */ static Entry * FirstTaggedEntry(EntryIterator *iterPtr) { if (iterPtr->type == ITER_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } else { Entry *entryPtr; entryPtr = iterPtr->first; iterPtr->next = NextTaggedEntry(iterPtr); return entryPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * GetEntryFromObj -- * * Gets the entry associated the given index, tag, or label. This * routine is used when you want only one entry. It's an error if more * than one entry is specified (e.g. "all" tag or range "1:4"). It's * also an error if the tag is empty (no entries are currently tagged). * *--------------------------------------------------------------------------- */ static int GetEntryFromObj( Tcl_Interp *interp, ComboTree *comboPtr, Tcl_Obj *objPtr, Entry **entryPtrPtr) { EntryIterator iter; Entry *firstPtr; if (GetEntryIterator(interp, comboPtr, objPtr, &iter) != TCL_OK) { return TCL_ERROR; } firstPtr = FirstTaggedEntry(&iter); if (firstPtr != NULL) { Entry *nextPtr; nextPtr = NextTaggedEntry(&iter); if (nextPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple entries specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } *entryPtrPtr = firstPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetEntry -- * * Returns an entry based upon its index. This differs from * GetEntryFromObj in that an non-existant entry (NULL) is treated * an error. * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via nodePtr. Otherwise, TCL_ERROR is * returned and an error message is left in interpreter's result field. * *--------------------------------------------------------------------------- */ static int GetEntry(ComboTree *comboPtr, Tcl_Obj *objPtr, Entry **entryPtrPtr) { Entry *entryPtr; if (GetEntryFromObj(comboPtr->interp, comboPtr, objPtr, &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { Tcl_ResetResult(comboPtr->interp); Tcl_AppendResult(comboPtr->interp, "can't find entry \"", Tcl_GetString(objPtr), "\" in \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } *entryPtrPtr = entryPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetUid -- * * Gets or creates a unique string identifier. Strings are reference * counted. The string is placed into a hashed table local to the * treeview. * * Results: * Returns the pointer to the hashed string. * *--------------------------------------------------------------------------- */ static UID GetUid(ComboTree *comboPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; size_t refCount; hPtr = Blt_CreateHashEntry(&comboPtr->uidTable, string, &isNew); if (isNew) { refCount = 1; } else { refCount = (size_t)Blt_GetHashValue(hPtr); refCount++; } Blt_SetHashValue(hPtr, refCount); return Blt_GetHashKey(&comboPtr->uidTable, hPtr); } /* *--------------------------------------------------------------------------- * * FreeUid -- * * Releases the uid. Uids are reference counted, so only when the * reference count is zero (i.e. no one else is using the string) is the * entry removed from the hash table. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeUid(ComboTree *comboPtr, UID uid) { Blt_HashEntry *hPtr; size_t refCount; hPtr = Blt_FindHashEntry(&comboPtr->uidTable, uid); assert(hPtr != NULL); refCount = (size_t)Blt_GetHashValue(hPtr); refCount--; if (refCount > 0) { Blt_SetHashValue(hPtr, refCount); } else { Blt_DeleteHashEntry(&comboPtr->uidTable, hPtr); } } static Icon GetIcon(ComboTree *comboPtr, const char *iconName) { Blt_HashEntry *hPtr; int isNew; struct _Icon *iconPtr; hPtr = Blt_CreateHashEntry(&comboPtr->iconTable, iconName, &isNew); if (isNew) { Tk_Image tkImage; int width, height; tkImage = Tk_GetImage(comboPtr->interp, comboPtr->tkwin, (char *)iconName, IconChangedProc, comboPtr); if (tkImage == NULL) { Blt_DeleteHashEntry(&comboPtr->iconTable, hPtr); return NULL; } Tk_SizeOfImage(tkImage, &width, &height); iconPtr = Blt_AssertMalloc(sizeof(struct _Icon)); iconPtr->tkImage = tkImage; iconPtr->hashPtr = hPtr; iconPtr->refCount = 1; iconPtr->width = width; iconPtr->height = height; Blt_SetHashValue(hPtr, iconPtr); } else { iconPtr = Blt_GetHashValue(hPtr); iconPtr->refCount++; } return iconPtr; } static void FreeIcon(ComboTree *comboPtr, struct _Icon *iconPtr) { iconPtr->refCount--; if (iconPtr->refCount == 0) { Blt_DeleteHashEntry(&comboPtr->iconTable, iconPtr->hashPtr); Tk_FreeImage(iconPtr->tkImage); Blt_Free(iconPtr); } } static void DestroyIcons(ComboTree *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; struct _Icon *iconPtr; for (hPtr = Blt_FirstHashEntry(&comboPtr->iconTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { iconPtr = Blt_GetHashValue(hPtr); Tk_FreeImage(iconPtr->tkImage); Blt_Free(iconPtr); } Blt_DeleteHashTable(&comboPtr->iconTable); } static void DestroyStyle(Style *stylePtr) { ComboTree *comboPtr; stylePtr->refCount--; if (stylePtr->refCount > 0) { return; } comboPtr = stylePtr->comboPtr; iconsOption.clientData = comboPtr; Blt_FreeOptions(styleSpecs, (char *)stylePtr, comboPtr->display, 0); if (stylePtr->labelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelActiveGC); } if (stylePtr->labelDisabledGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelDisabledGC); } if (stylePtr->labelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelNormalGC); } if (stylePtr->hPtr != NULL) { Blt_DeleteHashEntry(&stylePtr->comboPtr->styleTable, stylePtr->hPtr); } if (stylePtr != &stylePtr->comboPtr->defStyle) { Blt_Free(stylePtr); } } static int AddDefaultStyle(Tcl_Interp *interp, ComboTree *comboPtr) { Blt_HashEntry *hPtr; int isNew; Style *stylePtr; hPtr = Blt_CreateHashEntry(&comboPtr->styleTable, "default", &isNew); if (!isNew) { Tcl_AppendResult(interp, "combotree style \"", "default", "\" already exists.", (char *)NULL); return TCL_ERROR; } stylePtr = &comboPtr->defStyle; assert(stylePtr); stylePtr->refCount = 1; stylePtr->name = Blt_GetHashKey(&comboPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->comboPtr = comboPtr; stylePtr->relief = TK_RELIEF_FLAT; stylePtr->activeRelief = TK_RELIEF_FLAT; Blt_SetHashValue(hPtr, stylePtr); return TCL_OK; } static void DestroyStyles(ComboTree *comboPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&comboPtr->styleTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Style *stylePtr; stylePtr = Blt_GetHashValue(hPtr); stylePtr->hPtr = NULL; stylePtr->refCount = 0; DestroyStyle(stylePtr); } Blt_DeleteHashTable(&comboPtr->styleTable); } /* *--------------------------------------------------------------------------- * * GetStyleFromObj -- * * Gets the style associated with the given name. * *--------------------------------------------------------------------------- */ static int GetStyleFromObj( Tcl_Interp *interp, ComboTree *comboPtr, Tcl_Obj *objPtr, Style **stylePtrPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&comboPtr->styleTable, Tcl_GetString(objPtr)); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find style \"", Tcl_GetString(objPtr), "\" in combomenu \"", Tk_PathName(comboPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *stylePtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } static void MapEntry(Entry *entryPtr) { ComboTree *comboPtr; int entryWidth, entryHeight; comboPtr = entryPtr->comboPtr; /* * FIXME: Use of DIRTY flag inconsistent. When does it * mean "dirty entry"? When does it mean "dirty column"? * Does it matter? probably */ if (entryPtr->flags & ENTRY_DIRTY) { Blt_FontMetrics fontMetrics; Style *stylePtr; const char *label; int textWidth, textHeight; stylePtr = entryPtr->stylePtr; entryPtr->iconWidth = entryPtr->iconHeight = 0; if (stylePtr->icons != NULL) { int i; for (i = 0; i < 2; i++) { if (stylePtr->icons[i] == NULL) { break; } if (entryPtr->iconWidth < IconWidth(stylePtr->icons[i])) { entryPtr->iconWidth = IconWidth(stylePtr->icons[i]); } if (entryPtr->iconHeight < IconHeight(stylePtr->icons[i])) { entryPtr->iconHeight = IconHeight(stylePtr->icons[i]); } } } if ((stylePtr->icons == NULL) || (stylePtr->icons[0] == NULL)) { entryPtr->iconWidth = ICON_WIDTH; entryPtr->iconHeight = ICON_HEIGHT; } entryPtr->iconWidth += 2 * ICON_PADX; entryPtr->iconHeight += 2 * ICON_PADY; entryHeight = MAX(entryPtr->iconHeight, comboPtr->button.height); if (entryPtr->textPtr != NULL) { Blt_Free(entryPtr->textPtr); entryPtr->textPtr = NULL; } Blt_GetFontMetrics(stylePtr->labelFont, &fontMetrics); entryPtr->lineHeight = fontMetrics.linespace; entryPtr->lineHeight += 2 * LABEL_PADY + comboPtr->leader; label = GETLABEL(entryPtr); if (label[0] == '\0') { textWidth = textHeight = entryPtr->lineHeight; } else { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, stylePtr->labelFont); entryPtr->textPtr = Blt_Ts_CreateLayout(label, -1, &ts); textWidth = entryPtr->textPtr->width; textHeight = entryPtr->textPtr->height; } textWidth += 2 * LABEL_PADX; textHeight += 2 * LABEL_PADY; textWidth = ODD(textWidth); if (entryPtr->reqHeight > textHeight) { textHeight = entryPtr->reqHeight; } textHeight = ODD(textHeight); entryWidth = textWidth; if (entryHeight < textHeight) { entryHeight = textHeight; } entryPtr->labelWidth = textWidth; entryPtr->labelHeight = textHeight; } else { entryHeight = entryPtr->labelHeight; entryWidth = entryPtr->labelWidth; } /* * Find the maximum height of the data value entries. This also has the * side effect of contributing the maximum width of the column. */ entryPtr->width = entryWidth + COLUMN_PAD; entryPtr->height = entryHeight + comboPtr->leader; /* * Force the height of the entry to an even number. This is to make the * dots or the vertical line segments coincide with the start of the * horizontal lines. */ if (entryPtr->height & 0x01) { entryPtr->height++; } entryPtr->flags &= ~ENTRY_DIRTY; } /* *--------------------------------------------------------------------------- * * ResetCoordinates -- * * Determines the maximum height of all visible entries. * * 1. Sets the worldY coordinate for all mapped/open entries. * 2. Determines if entry needs a button. * 3. Collects the minimum height of open/mapped entries. (Do for all * entries upon insert). * 4. Figures out horizontal extent of each entry (will be width of * tree view column). * 5. Collects maximum icon size for each level. * 6. The height of its vertical line * * Results: * Returns 1 if beyond the last visible entry, 0 otherwise. * * Side effects: * The array of visible nodes is filled. * *--------------------------------------------------------------------------- */ static void ResetCoordinates(ComboTree *comboPtr, Entry *entryPtr, int *yPtr, int *numPtr) { if ((entryPtr != comboPtr->rootPtr) && (EntryIsHidden(entryPtr))) { entryPtr->worldY = -1; entryPtr->vertLineLength = -1; return; /* If the entry is hidden, then do nothing. */ } /* Set the world y-coordinate of the entry. Initialize the length of the * dotted vertical line that runs from the entry downward with the current * y-offset. */ entryPtr->worldY = *yPtr; entryPtr->vertLineLength = -(*yPtr); *yPtr += entryPtr->height; entryPtr->seqNum = *numPtr; (*numPtr)++; { int depth; LevelInfo *infoPtr; depth = Blt_Tree_NodeDepth(entryPtr->node) + 1; infoPtr = comboPtr->levelInfo + depth; if (infoPtr->labelWidth < entryPtr->labelWidth) { infoPtr->labelWidth = entryPtr->labelWidth; } if (infoPtr->iconWidth < entryPtr->iconWidth) { infoPtr->iconWidth = entryPtr->iconWidth; } infoPtr->iconWidth |= 0x01; } if ((entryPtr->flags & ENTRY_CLOSED) == 0) { Entry *bottomPtr, *nextPtr; bottomPtr = entryPtr; for (nextPtr = FirstChild(entryPtr, ENTRY_HIDE); nextPtr != NULL; nextPtr = NextSibling(nextPtr, ENTRY_HIDE)) { ResetCoordinates(comboPtr, nextPtr, yPtr, numPtr); bottomPtr = nextPtr; } entryPtr->vertLineLength += bottomPtr->worldY; } } /* *--------------------------------------------------------------------------- * * MapTree -- * * Compute the layout when entries are opened/closed, inserted/deleted, * or when text attributes change (such as font, linespacing). * * Results: * None. * * Side effects: * The world coordinates are set for all the opened entries. * *--------------------------------------------------------------------------- */ static void MapTree(ComboTree *comboPtr) { int y; int index; /* * Pass 1: Reinitialize column sizes and loop through all nodes. * * 1. Recalculate the size of each entry as needed. * 2. The maximum depth of the tree. * 3. Minimum height of an entry. Dividing this by the * height of the widget gives a rough estimate of the * maximum number of visible entries. * 4. Build an array to hold level information to be filled * in on pass 2. */ if (comboPtr->flags & DIRTY) { Entry *entryPtr; comboPtr->minHeight = SHRT_MAX; comboPtr->depth = 0; for (entryPtr = comboPtr->rootPtr; entryPtr != NULL; entryPtr = NextEntry(entryPtr, 0)){ MapEntry(entryPtr); /* Get the height of the shortest entry. */ if (comboPtr->minHeight > entryPtr->height) { comboPtr->minHeight = entryPtr->height; } /* * Determine if the entry should display a button (indicating that * it has children) and mark the entry accordingly. */ entryPtr->flags &= ~ENTRY_BUTTON; if (entryPtr->flags & ENTRY_BTN_SHOW) { entryPtr->flags |= ENTRY_BUTTON; } else if (entryPtr->flags & ENTRY_BTN_AUTO) { if (comboPtr->flags & HIDE_LEAVES) { /* Check that a non-leaf child exists */ if (FirstChild(entryPtr, ENTRY_HIDE) != NULL) { entryPtr->flags |= ENTRY_BUTTON; } } else if (!Blt_Tree_IsLeaf(entryPtr->node)) { entryPtr->flags |= ENTRY_BUTTON; } } /* Save the maximum depth of the tree. */ if (comboPtr->depth < Blt_Tree_NodeDepth(entryPtr->node)) { comboPtr->depth = Blt_Tree_NodeDepth(entryPtr->node); } } /* Create bookkeeping for each level of the tree. */ if (comboPtr->levelInfo != NULL) { Blt_Free(comboPtr->levelInfo); } comboPtr->levelInfo = Blt_AssertCalloc(comboPtr->depth + 2, sizeof(LevelInfo)); comboPtr->flags &= ~DIRTY; } { size_t i; /* Reset the level bookkeeping. */ for (i = 0; i <= (comboPtr->depth + 1); i++) { comboPtr->levelInfo[i].labelWidth = comboPtr->levelInfo[i].x = comboPtr->levelInfo[i].iconWidth = 0; } } /* * Pass 2: Loop through all open/mapped nodes. * * 1. Set world y-coordinates for entries. We must defer setting * the x-coordinates until we know the maximum icon sizes at * each level. * 2. Compute the maximum depth of the tree. * 3. Build an array to hold level information. */ y = 0; if (comboPtr->flags & HIDE_ROOT) { /* If the root entry is to be hidden, cheat by offsetting the * y-coordinates by the height of the entry. */ y = -(comboPtr->rootPtr->height); } index = 0; ResetCoordinates(comboPtr, comboPtr->rootPtr, &y, &index); comboPtr->worldHeight = y; /* Set the scroll height of the hierarchy. */ if (comboPtr->worldHeight < 1) { comboPtr->worldHeight = 1; } { int maxX; int sum; size_t i; sum = maxX = 0; for (i = 0; i <= (comboPtr->depth + 1); i++) { int x; sum += comboPtr->levelInfo[i].iconWidth; if (i <= comboPtr->depth) { comboPtr->levelInfo[i + 1].x = sum; } x = sum + comboPtr->levelInfo[i].labelWidth; if (x > maxX) { maxX = x; } } comboPtr->worldWidth = maxX; } } /* *--------------------------------------------------------------------------- * * ComputeComboGeometry -- * * Recompute the layout when entries are opened/closed, inserted/deleted, * or when text attributes change (such as font, linespacing). * * Results: * None. * * Side effects: * The world coordinates are set for all the opened entries. * *--------------------------------------------------------------------------- */ static void ComputeComboGeometry(ComboTree *comboPtr) { int w, h; int screenWidth, screenHeight; MapTree(comboPtr); Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); comboPtr->xScrollbarHeight = comboPtr->yScrollbarWidth = 0; if (comboPtr->reqWidth > 0) { w = comboPtr->reqWidth; fprintf(stderr, "%s rw=%d\n", Tk_PathName(comboPtr->tkwin), w); } else if (comboPtr->reqWidth < 0) { w = MIN(-comboPtr->reqWidth, comboPtr->worldWidth); fprintf(stderr, "%s min(%d,%d)=%d\n", Tk_PathName(comboPtr->tkwin), -comboPtr->reqWidth, comboPtr->worldWidth, w); } else { w = Tk_Width(Tk_Parent(comboPtr->tkwin)); if (w <= 1) { w = Tk_ReqWidth(Tk_Parent(comboPtr->tkwin)); } fprintf(stderr, "%s min(%d,%d)=%d\n", Tk_PathName(comboPtr->tkwin), screenWidth, comboPtr->worldWidth, w); } if ((comboPtr->worldWidth > w) && (comboPtr->xScrollbar != NULL)) { comboPtr->xScrollbarHeight = Tk_ReqHeight(comboPtr->xScrollbar); } if (comboPtr->reqHeight > 0) { h = comboPtr->reqHeight; } else if (comboPtr->reqHeight < 0) { h = MIN(-comboPtr->reqHeight, comboPtr->worldHeight); } else { h=MIN(screenHeight, comboPtr->worldHeight); } if ((comboPtr->worldHeight > h) && (comboPtr->yScrollbar != NULL)) { comboPtr->yScrollbarWidth = Tk_ReqWidth(comboPtr->yScrollbar); } if (comboPtr->reqWidth == 0) { #ifdef notdef w += 2 * (comboPtr->borderWidth + 2 * ITEM_IPAD); w += comboPtr->yScrollbarWidth; #endif } if (comboPtr->reqHeight == 0) { h += comboPtr->xScrollbarHeight; h += 2 * comboPtr->borderWidth; } #ifdef notdef comboPtr->width = w; comboPtr->height = h; fprintf(stderr, "%s= w=%d leftInd w=%d icon w=%d label w=%d rightInd w=%d\n", Tk_PathName(comboPtr->tkwin), comboPtr->width, comboPtr->leftIndWidth, comboPtr->iconWidth, comboPtr->labelWidth, comboPtr->rightIndWidth); #endif if ((w != Tk_ReqWidth(comboPtr->tkwin)) || (h != Tk_ReqHeight(comboPtr->tkwin))) { Tk_GeometryRequest(comboPtr->tkwin, w, h); } comboPtr->flags |= SCROLL_PENDING | LAYOUT_PENDING; } /* Converters for configuration options. */ /* *--------------------------------------------------------------------------- * * ObjToButtonProc -- * * Convert a string to one of three values. * 0 - false, no, off * 1 - true, yes, on * 2 - auto * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToButtonProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { const char *string; int *flagsPtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); if ((string[0] == 'a') && (strcmp(string, "auto") == 0)) { *flagsPtr &= ~ENTRY_BTN_MASK; *flagsPtr |= ENTRY_BTN_AUTO; } else { int bool; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } *flagsPtr &= ~ENTRY_BTN_MASK; if (bool) { *flagsPtr |= ENTRY_BTN_SHOW; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonToObjProc -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ButtonToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int bool; unsigned int buttonFlags = *(int *)(widgRec + offset); bool = (buttonFlags & ENTRY_BTN_MASK); if (bool == ENTRY_BTN_AUTO) { return Tcl_NewStringObj("auto", 4); } else { return Tcl_NewBooleanObj(bool); } } /* *--------------------------------------------------------------------------- * * ObjToLabelProc -- * * Convert the string representing the label. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLabelProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID *labelPtr = (UID *)(widgRec + offset); const char *string; string = Tcl_GetString(objPtr); if (string[0] != '\0') { ComboTree *comboPtr = clientData; *labelPtr = GetUid(comboPtr, string); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LabelToObjProc -- * * Results: * The string of the entry's label is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LabelToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID labelUid = *(UID *)(widgRec + offset); const char *string; if (labelUid == NULL) { Entry *entryPtr = (Entry *)widgRec; string = Blt_Tree_NodeLabel(entryPtr->node); } else { string = labelUid; } return Tcl_NewStringObj(string, -1); } /*ARGSUSED*/ static void FreeLabelProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { UID *labelPtr = (UID *)(widgRec + offset); if (*labelPtr != NULL) { ComboTree *comboPtr = clientData; FreeUid(comboPtr, *labelPtr); *labelPtr = NULL; } } /*ARGSUSED*/ static void FreeStyleProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Style *stylePtr = *(Style **)(widgRec + offset); if ((stylePtr != NULL) && (stylePtr != &stylePtr->comboPtr->defStyle)) { DestroyStyle(stylePtr); } } /* *--------------------------------------------------------------------------- * * ObjToStyleProc -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyleProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ComboTree *comboPtr; Entry *entryPtr = (Entry *)widgRec; Style **stylePtrPtr = (Style **)(widgRec + offset); Style *stylePtr; const char *string; string = Tcl_GetString(objPtr); comboPtr = entryPtr->comboPtr; if ((string[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { stylePtr = NULL; } else if (GetStyleFromObj(interp, comboPtr, objPtr, &stylePtr) != TCL_OK) { return TCL_ERROR; } /* Release the old style. */ if ((*stylePtrPtr != NULL) && (*stylePtrPtr != &comboPtr->defStyle)) { DestroyStyle(*stylePtrPtr); } stylePtr->refCount++; *stylePtrPtr = stylePtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * StyleToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StyleToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Style *stylePtr = *(Style **)(widgRec + offset); Tcl_Obj *objPtr; if (stylePtr == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(stylePtr->name, -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToUidProc -- * * Converts the string to a Uid. Uid's are hashed, reference * counted strings. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToUidProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { ComboTree *comboPtr = clientData; UID *uidPtr = (UID *)(widgRec + offset); *uidPtr = GetUid(comboPtr, Tcl_GetString(objPtr)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * UidToObjProc -- * * Returns the uid as a string. * * Results: * The fill style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * UidToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID uid = *(UID *)(widgRec + offset); if (uid == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(uid, -1); } } /* *--------------------------------------------------------------------------- * * FreeUid -- * * Free the UID from the widget record, setting it to NULL. * * Results: * The UID in the widget record is set to NULL. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeUidProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { UID *uidPtr = (UID *)(widgRec + offset); if (*uidPtr != NULL) { ComboTree *comboPtr = clientData; FreeUid(comboPtr, *uidPtr); *uidPtr = NULL; } } /* *--------------------------------------------------------------------------- * * IconChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, /* Not used. */ int y, /* Not used. */ int width, /* Not used. */ int height, /* Not used. */ int imageWidth, /* Not used. */ int imageHeight) /* Not used. */ { ComboTree *comboPtr = clientData; comboPtr->flags |= (DIRTY | LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ObjToIconsProc -- * * Convert a list of image names into Tk images. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIconsProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Tcl_Obj **objv; ComboTree *comboPtr = clientData; Icon **iconPtrPtr = (Icon **)(widgRec + offset); Icon *icons; int objc; int result; result = TCL_OK; icons = NULL; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 0) { int i; icons = Blt_AssertMalloc(sizeof(Icon *) * (objc + 1)); for (i = 0; i < objc; i++) { icons[i] = GetIcon(comboPtr, Tcl_GetString(objv[i])); if (icons[i] == NULL) { result = TCL_ERROR; break; } } icons[i] = NULL; } *iconPtrPtr = icons; return result; } /* *--------------------------------------------------------------------------- * * IconsToObjProc -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconsToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Icon *icons = *(Icon **)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (icons != NULL) { Icon *iconPtr; for (iconPtr = icons; *iconPtr != NULL; iconPtr++) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_Image_Name((*iconPtr)->tkImage), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } /*ARGSUSED*/ static void FreeIconsProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Icon **iconsPtr = (Icon **)(widgRec + offset); if (*iconsPtr != NULL) { Icon *ip; ComboTree *comboPtr = clientData; for (ip = *iconsPtr; *ip != NULL; ip++) { FreeIcon(comboPtr, *ip); } Blt_Free(*iconsPtr); *iconsPtr = NULL; } } static int Apply( ComboTree *comboPtr, Entry *entryPtr, /* Root entry of subtree. */ ApplyProc *proc, /* Procedure to call for each entry. */ unsigned int flags) { if ((flags & ENTRY_HIDE) && (EntryIsHidden(entryPtr))) { return TCL_OK; /* Hidden node. */ } if ((flags & ENTRY_HIDE) && (entryPtr->flags & ENTRY_HIDE)) { return TCL_OK; /* Hidden node. */ } if (((flags & ENTRY_CLOSED) == 0) || ((entryPtr->flags & ENTRY_CLOSED) == 0)) { Entry *childPtr; Blt_TreeNode node, next; for (node = Blt_Tree_FirstChild(entryPtr->node); node != NULL; node = next) { next = Blt_Tree_NextSibling(node); /* * Get the next child before calling Apply * recursively. This is because the apply callback may * delete the node and its link. */ childPtr = NodeToEntry(comboPtr, node); if (Apply(comboPtr, childPtr, proc, flags) != TCL_OK) { return TCL_ERROR; } } } if ((*proc) (comboPtr, entryPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #ifdef notdef int EntryIsMapped(Entry *entryPtr) { ComboTree *comboPtr = entryPtr->comboPtr; /* Don't check if the entry itself is open, only that its * ancestors are. */ if (EntryIsHidden(entryPtr)) { return FALSE; } if (entryPtr == comboPtr->rootPtr) { return TRUE; } entryPtr = ParentEntry(entryPtr); while (entryPtr != comboPtr->rootPtr) { if (entryPtr->flags & (ENTRY_CLOSED | ENTRY_HIDE)) { return FALSE; } entryPtr = ParentEntry(entryPtr); } return TRUE; } #endif static void ConfigureButtons(ComboTree *comboPtr) { Button *btnPtr = &comboPtr->button; GC newGC; XGCValues gcValues; unsigned long gcMask; gcMask = GCForeground; gcValues.foreground = btnPtr->fgColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (btnPtr->normalGC != NULL) { Tk_FreeGC(comboPtr->display, btnPtr->normalGC); } btnPtr->normalGC = newGC; gcMask = GCForeground; gcValues.foreground = btnPtr->activeFgColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (btnPtr->activeGC != NULL) { Tk_FreeGC(comboPtr->display, btnPtr->activeGC); } btnPtr->activeGC = newGC; btnPtr->width = btnPtr->height = ODD(btnPtr->reqSize); if (btnPtr->icons != NULL) { int i; for (i = 0; i < 2; i++) { int width, height; if (btnPtr->icons[i] == NULL) { break; } width = IconWidth(btnPtr->icons[i]); height = IconWidth(btnPtr->icons[i]); if (btnPtr->width < width) { btnPtr->width = width; } if (btnPtr->height < height) { btnPtr->height = height; } } } btnPtr->width += 2 * btnPtr->borderWidth; btnPtr->height += 2 * btnPtr->borderWidth; } static int ConfigureStyle( Tcl_Interp *interp, Style *stylePtr, int objc, Tcl_Obj *const *objv, int flags) { ComboTree *comboPtr = stylePtr->comboPtr; unsigned int gcMask; XGCValues gcValues; GC newGC; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, styleSpecs, objc, objv, (char *)stylePtr, flags) != TCL_OK) { return TCL_ERROR; } gcMask = GCForeground | GCFont | GCLineWidth; gcValues.font = Blt_FontId(stylePtr->labelFont); gcValues.line_width = comboPtr->lineWidth; if (comboPtr->dashes > 0) { gcMask |= (GCLineStyle | GCDashList); gcValues.line_style = LineOnOffDash; gcValues.dashes = comboPtr->dashes; } /* Normal label */ gcValues.foreground = stylePtr->labelNormalColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->labelNormalGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelNormalGC); } stylePtr->labelNormalGC = newGC; /* Active label */ gcValues.foreground = stylePtr->labelActiveColor->pixel; newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (stylePtr->labelActiveGC != NULL) { Tk_FreeGC(comboPtr->display, stylePtr->labelActiveGC); } stylePtr->labelActiveGC = newGC; return TCL_OK; } /*ARGSUSED*/ static int CreateApplyProc( Blt_TreeNode node, /* Node that has just been created. */ ClientData clientData, int order) /* Not used. */ { ComboTree *comboPtr = clientData; return CreateEntry(comboPtr, node, 0, NULL, 0); } static int TreeEventProc(ClientData clientData, Blt_TreeNotifyEvent *eventPtr) { Blt_TreeNode node; ComboTree *comboPtr = clientData; node = Blt_Tree_GetNode(eventPtr->tree, eventPtr->inode); switch (eventPtr->type) { case TREE_NOTIFY_CREATE: return CreateEntry(comboPtr, node, 0, NULL, 0); case TREE_NOTIFY_DELETE: /* * Deleting the tree node triggers a call back to free the * treeview entry that is associated with it. */ if (node != NULL) { Entry *entryPtr; entryPtr = GetEntryFromNode(comboPtr, node); if (entryPtr != NULL) { FreeEntry(comboPtr, entryPtr); } } break; case TREE_NOTIFY_RELABEL: if (node != NULL) { Entry *entryPtr; entryPtr = NodeToEntry(comboPtr, node); entryPtr->flags |= ENTRY_DIRTY; } /*FALLTHRU*/ case TREE_NOTIFY_MOVE: case TREE_NOTIFY_SORT: EventuallyRedraw(comboPtr); comboPtr->flags |= (LAYOUT_PENDING | DIRTY); break; default: /* empty */ break; } return TCL_OK; } static ClientData EntryTag(ComboTree *comboPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&comboPtr->entryBindTagTable, string, &isNew); return Blt_GetHashKey(&comboPtr->entryBindTagTable, hPtr); } static ClientData ButtonTag(ComboTree *comboPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&comboPtr->buttonBindTagTable, string, &isNew); return Blt_GetHashKey(&comboPtr->buttonBindTagTable, hPtr); } static void AddIdsToList(ComboTree *comboPtr, Blt_List ids, Tcl_Obj *objPtr, TagProc *tagProc) { int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(comboPtr->interp, objPtr, &objc, &objv) == TCL_OK) { int i; for (i = 0; i < objc; i++) { ClientData clientData; clientData = (*tagProc)(comboPtr, Tcl_GetString(objv[i])); Blt_List_Append(ids, clientData, 0); } } } static void GetTags( Blt_BindTable table, ClientData object, /* Object picked. */ ClientData context, /* Context of object. */ Blt_List ids) /* (out) List of binding ids to be * applied for this object. */ { ComboTree *comboPtr; comboPtr = Blt_GetBindingData(table); if (context == (ClientData)PICK_BUTTON) { Entry *entryPtr = object; Blt_List_Append(ids, ButtonTag(comboPtr, "Button"), 0); if (entryPtr->tagsObjPtr != NULL) { AddIdsToList(comboPtr, ids, entryPtr->tagsObjPtr, ButtonTag); } else { Blt_List_Append(ids, ButtonTag(comboPtr, "Entry"), 0); Blt_List_Append(ids, ButtonTag(comboPtr, "all"), 0); } } else { Entry *entryPtr = object; Blt_List_Append(ids, (char *)entryPtr, 0); if (entryPtr->tagsObjPtr != NULL) { AddIdsToList(comboPtr, ids, entryPtr->tagsObjPtr, EntryTag); } else if (context == PICK_ENTRY){ Blt_List_Append(ids, EntryTag(comboPtr, "Entry"), 0); Blt_List_Append(ids, EntryTag(comboPtr, "all"), 0); } } } /*ARGSUSED*/ static ClientData PickEntry( ClientData clientData, int x, int y, /* Screen coordinates of the test point. */ ClientData *contextPtr) /* (out) Context of entry selected: should * be PICK_ENTRY or PICK_BUTTON. */ { ComboTree *comboPtr = clientData; Entry *entryPtr; if (contextPtr != NULL) { *contextPtr = NULL; } if (comboPtr->flags & DIRTY) { /* Can't trust the selected entry if nodes have been added or * deleted. So recompute the layout. */ if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } ComputeVisibleEntries(comboPtr); } if (comboPtr->nVisible == 0) { return NULL; } entryPtr = NearestEntry(comboPtr, x, y, FALSE); if (entryPtr == NULL) { return NULL; } x = WORLDX(comboPtr, x); y = WORLDY(comboPtr, y); if (contextPtr != NULL) { *contextPtr = PICK_ENTRY; if (entryPtr->flags & ENTRY_BUTTON) { Button *btnPtr = &comboPtr->button; int left, right, top, bottom; left = entryPtr->worldX + entryPtr->buttonX - BUTTON_PAD; right = left + btnPtr->width + 2 * BUTTON_PAD; top = entryPtr->worldY + entryPtr->buttonY - BUTTON_PAD; bottom = top + btnPtr->height + 2 * BUTTON_PAD; if ((x >= left) && (x < right) && (y >= top) && (y < bottom)) { *contextPtr = (ClientData)PICK_BUTTON; } } } return entryPtr; } /* * TreeView Procedures */ /* *--------------------------------------------------------------------------- * * NewComboTree -- * *--------------------------------------------------------------------------- */ static ComboTree * NewComboTree(Tcl_Interp *interp, Tcl_Obj *objPtr) { Tk_Window tkwin; ComboTree *comboPtr; const char *name; name = Tcl_GetString(objPtr); #define TOP_LEVEL_SCREEN "" tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), name, TOP_LEVEL_SCREEN); if (tkwin == NULL) { return NULL; } Tk_SetClass(tkwin, "ComboTree"); comboPtr = Blt_AssertCalloc(1, sizeof(ComboTree)); comboPtr->tkwin = tkwin; comboPtr->display = Tk_Display(tkwin); comboPtr->interp = interp; comboPtr->flags = (HIDE_ROOT | DIRTY | LAYOUT_PENDING | REPOPULATE); comboPtr->leader = 0; comboPtr->dashes = 1; comboPtr->borderWidth = 1; comboPtr->relief = TK_RELIEF_SUNKEN; comboPtr->button.closeRelief = comboPtr->button.openRelief = TK_RELIEF_SOLID; comboPtr->reqWidth = 0; comboPtr->reqHeight = 0; comboPtr->xScrollUnits = comboPtr->yScrollUnits = 20; comboPtr->lineWidth = 1; comboPtr->button.borderWidth = 1; comboPtr->buttonFlags = ENTRY_BTN_AUTO; Blt_InitHashTableWithPool(&comboPtr->entryTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&comboPtr->iconTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->uidTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->styleTable, BLT_STRING_KEYS); comboPtr->bindTable = Blt_CreateBindingTable(interp, tkwin, comboPtr, PickEntry, GetTags); Blt_InitHashTable(&comboPtr->entryBindTagTable, BLT_STRING_KEYS); Blt_InitHashTable(&comboPtr->buttonBindTagTable, BLT_STRING_KEYS); comboPtr->entryPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); Blt_SetWindowInstanceData(tkwin, comboPtr); comboPtr->cmdToken = Tcl_CreateObjCommand(interp, Tk_PathName(comboPtr->tkwin), ComboTreeInstCmdProc, comboPtr, ComboTreeInstCmdDeleteProc); /* * By default create a tree. The name will be the same as the widget * pathname. */ comboPtr->tree = Blt_Tree_Open(interp, Tk_PathName(comboPtr->tkwin), TREE_CREATE); if (comboPtr->tree == NULL) { return NULL; } Tk_CreateEventHandler(comboPtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, ComboTreeEventProc, comboPtr); if (AddDefaultStyle(interp, comboPtr) != TCL_OK) { return NULL; } return comboPtr; } /* *--------------------------------------------------------------------------- * * DestroyComboTree -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a TreeView at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyComboTree(DestroyData dataPtr) /* Pointer to the widget record. */ { ComboTree *comboPtr = (ComboTree *)dataPtr; Button *btnPtr; if (comboPtr->tree != NULL) { Blt_Tree_Close(comboPtr->tree); } iconsOption.clientData = comboPtr; Blt_FreeOptions(comboSpecs, (char *)comboPtr, comboPtr->display, 0); Tcl_DeleteCommandFromToken(comboPtr->interp, comboPtr->cmdToken); if (comboPtr->tkwin != NULL) { Tk_DeleteSelHandler(comboPtr->tkwin, XA_PRIMARY, XA_STRING); } if (comboPtr->lineGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->lineGC); } if (comboPtr->visibleEntries != NULL) { Blt_Free(comboPtr->visibleEntries); } if (comboPtr->levelInfo != NULL) { Blt_Free(comboPtr->levelInfo); } btnPtr = &comboPtr->button; if (btnPtr->activeGC != NULL) { Tk_FreeGC(comboPtr->display, btnPtr->activeGC); } if (btnPtr->normalGC != NULL) { Tk_FreeGC(comboPtr->display, btnPtr->normalGC); } Blt_DestroyBindingTable(comboPtr->bindTable); Blt_DeleteHashTable(&comboPtr->entryBindTagTable); Blt_DeleteHashTable(&comboPtr->buttonBindTagTable); Blt_DeleteHashTable(&comboPtr->uidTable); Blt_DeleteHashTable(&comboPtr->entryTable); Blt_PoolDestroy(comboPtr->entryPool); DestroyIcons(comboPtr); DestroyStyles(comboPtr); Blt_Free(comboPtr); } /* *--------------------------------------------------------------------------- * * ScrollbarEventProc -- * * This procedure is invoked by the Tk event handler when StructureNotify * events occur in a scrollbar managed by the widget. * * Results: * None. * *--------------------------------------------------------------------------- */ static void ScrollbarEventProc( ClientData clientData, /* Pointer to Entry structure for widget * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { ComboTree *comboPtr = clientData; if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(comboPtr); } else if (eventPtr->type == DestroyNotify) { if (eventPtr->xany.window == Tk_WindowId(comboPtr->yScrollbar)) { comboPtr->yScrollbar = NULL; } else if (eventPtr->xany.window == Tk_WindowId(comboPtr->xScrollbar)) { comboPtr->xScrollbar = NULL; } comboPtr->flags |= LAYOUT_PENDING;; EventuallyRedraw(comboPtr); } } /* *--------------------------------------------------------------------------- * * ScrollbarCustodyProc -- * * This procedure is invoked when a scrollbar has been stolen by another * geometry manager. * * Results: * None. * * Side effects: * Arranges for the combomenu to have its layout re-arranged at the next * idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollbarCustodyProc( ClientData clientData, /* Information about the combomenu. */ Tk_Window tkwin) /* Scrollbar stolen by another geometry * manager. */ { ComboTree *comboPtr = (ComboTree *)clientData; if (tkwin == comboPtr->yScrollbar) { comboPtr->yScrollbar = NULL; comboPtr->yScrollbarWidth = 0; } else if (tkwin == comboPtr->xScrollbar) { comboPtr->xScrollbar = NULL; comboPtr->xScrollbarHeight = 0; } else { return; } Tk_UnmaintainGeometry(tkwin, comboPtr->tkwin); comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ScrollbarGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for scrollbars managed * by the combomenu. * * Results: * None. * * Side effects: * Arranges for the combomenu to have its layout re-computed and * re-arranged at the next idle point. * * -------------------------------------------------------------------------- */ /* ARGSUSED */ static void ScrollbarGeometryProc( ClientData clientData, /* ComboTree widget record. */ Tk_Window tkwin) /* Scrollbar whose geometry has changed. */ { ComboTree *comboPtr = (ComboTree *)clientData; comboPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(comboPtr); } /* *--------------------------------------------------------------------------- * * ComboTreeEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on treeview widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ComboTreeEventProc(ClientData clientData, XEvent *eventPtr) { ComboTree *comboPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(comboPtr); Blt_PickCurrentItem(comboPtr->bindTable); } } else if (eventPtr->type == ConfigureNotify) { comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { comboPtr->flags |= FOCUS; } else { comboPtr->flags &= ~FOCUS; } EventuallyRedraw(comboPtr); } } else if (eventPtr->type == DestroyNotify) { if (comboPtr->tkwin != NULL) { comboPtr->tkwin = NULL; } if (comboPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayComboTree, comboPtr); } Tcl_EventuallyFree(comboPtr, DestroyComboTree); } } /* *--------------------------------------------------------------------------- * * ComboTreeInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ComboTreeInstCmdDeleteProc(ClientData clientData) { ComboTree *comboPtr = clientData; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this * procedure destroys the widget. */ if (comboPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = comboPtr->tkwin; comboPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * ConfigureComboTree -- * * Updates the GCs and other information associated with the * treeview widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for comboPtr; old resources get freed, if there * were any. The widget is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureComboTree(Tcl_Interp *interp, ComboTree *comboPtr, int objc, Tcl_Obj *const *objv, int flags) { int updateNeeded; GC newGC; XGCValues gcValues; unsigned long gcMask; if (Blt_ConfigureWidgetFromObj(interp, comboPtr->tkwin, comboSpecs, objc, objv, (char *)comboPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureStyle(interp, &comboPtr->defStyle, 0, NULL, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } /* * GC for dotted vertical line. */ gcMask = (GCForeground | GCLineWidth); gcValues.foreground = comboPtr->lineColor->pixel; gcValues.line_width = comboPtr->lineWidth; if (comboPtr->dashes > 0) { gcMask |= (GCLineStyle | GCDashList); gcValues.line_style = LineOnOffDash; gcValues.dashes = comboPtr->dashes; } newGC = Tk_GetGC(comboPtr->tkwin, gcMask, &gcValues); if (comboPtr->lineGC != NULL) { Tk_FreeGC(comboPtr->display, comboPtr->lineGC); } comboPtr->lineGC = newGC; ConfigureButtons(comboPtr); comboPtr->inset = comboPtr->borderWidth + INSET_PAD; /* * These options change the layout of the box. Mark the widget for update. */ if (Blt_ConfigModified(comboSpecs, "-font", "-linespacing", "-*width", "-height", "-hide*", "-tree", (char *)NULL)) { comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); } /* * If the tree view was changed, mark all the nodes dirty (we'll be * switching back to either the full path name or the label) and free the * array representing the flattened view of the tree. */ if (Blt_ConfigModified(comboSpecs, "-hideleaves", (char *)NULL)) { Entry *ep; comboPtr->flags |= DIRTY; /* Mark all entries dirty. */ for (ep = comboPtr->rootPtr; ep != NULL; ep = NextEntry(ep, 0)) { ep->flags |= ENTRY_DIRTY; } } if ((comboPtr->reqHeight != Tk_ReqHeight(comboPtr->tkwin)) || (comboPtr->reqWidth != Tk_ReqWidth(comboPtr->tkwin))) { Tk_GeometryRequest(comboPtr->tkwin, comboPtr->reqWidth, comboPtr->reqHeight); } if (Blt_ConfigModified(comboSpecs, "-tree", (char *)NULL)) { DestroyEntries(comboPtr); Blt_InitHashTableWithPool(&comboPtr->entryTable, BLT_ONE_WORD_KEYS); if (Blt_Tree_Attach(interp, comboPtr->tree, comboPtr->treeName) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= REPOPULATE; } /* If the tree object was changed, we need to setup the new one. */ if (comboPtr->flags & REPOPULATE) { Blt_TreeNode root; Blt_Tree_CreateEventHandler(comboPtr->tree, TREE_NOTIFY_ALL, TreeEventProc, comboPtr); root = Blt_Tree_RootNode(comboPtr->tree); /* Automatically add view-entry values to the new tree. */ Blt_Tree_Apply(root, CreateApplyProc, comboPtr); comboPtr->rootPtr = NodeToEntry(comboPtr, root); /* Automatically open the root node. */ if (OpenEntry(comboPtr, comboPtr->rootPtr) != TCL_OK) { return TCL_ERROR; } if (comboPtr->flags & NEW_TAGS) { Blt_Tree_NewTagTable(comboPtr->tree); } comboPtr->flags &= ~REPOPULATE; } updateNeeded = FALSE; /* Install the embedded scrollbars as needed. We defer installing the * scrollbars so the scrollbar widgets don't have to exist when they are * specified by the -xscrollbar and -yscrollbar options respectively. The * down-side is that errors found in the scrollbar name will be * backgrounded. */ if (Blt_ConfigModified(comboSpecs, "-xscrollbar", (char *)NULL)) { if (comboPtr->xScrollbar != NULL) { UnmanageScrollbar(comboPtr, comboPtr->xScrollbar); comboPtr->xScrollbar = NULL; } if ((comboPtr->flags & INSTALL_SCROLLBAR_X) == 0) { Tcl_DoWhenIdle(InstallXScrollbar, comboPtr); comboPtr->flags |= INSTALL_SCROLLBAR_X; } updateNeeded = TRUE; } if (Blt_ConfigModified(comboSpecs, "-yscrollbar", (char *)NULL)) { if (comboPtr->yScrollbar != NULL) { UnmanageScrollbar(comboPtr, comboPtr->yScrollbar); comboPtr->yScrollbar = NULL; } if ((comboPtr->flags & INSTALL_SCROLLBAR_Y) == 0) { Tcl_DoWhenIdle(InstallYScrollbar, comboPtr); comboPtr->flags |= INSTALL_SCROLLBAR_Y; } updateNeeded = TRUE; } if (updateNeeded) { if ((comboPtr->flags & UPDATE_PENDING) == 0) { Tcl_DoWhenIdle(ConfigureScrollbarsProc, comboPtr); comboPtr->flags |= UPDATE_PENDING; } } EventuallyRedraw(comboPtr); return TCL_OK; } #ifdef notdef static void PrintFlags(ComboTree *comboPtr, char *string) { fprintf(stderr, "%s: flags=", string); if (comboPtr->flags & LAYOUT_PENDING) { fprintf(stderr, "layout "); } if (comboPtr->flags & REDRAW_PENDING) { fprintf(stderr, "redraw "); } if (comboPtr->flags & SCROLLX) { fprintf(stderr, "xscroll "); } if (comboPtr->flags & SCROLLY) { fprintf(stderr, "yscroll "); } if (comboPtr->flags & FOCUS) { fprintf(stderr, "focus "); } if (comboPtr->flags & DIRTY) { fprintf(stderr, "dirty "); } if (comboPtr->flags & REDRAW_BORDERS) { fprintf(stderr, "borders "); } if (comboPtr->flags & VIEWPORT) { fprintf(stderr, "viewport "); } fprintf(stderr, "\n"); } #endif static void FixMenuCoords(ComboTree *comboPtr, int *xPtr, int *yPtr) { int x, y, w, h; int screenWidth, screenHeight; Tk_Window parent; parent = Tk_Parent(comboPtr->tkwin); Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); x = *xPtr, y = *yPtr; /* Determine the size of the menu. */ w = Tk_Width(comboPtr->tkwin); if (w <= 1) { w = Tk_ReqWidth(comboPtr->tkwin); } h = Tk_Height(comboPtr->tkwin); if (h <= 1) { h = Tk_Height(comboPtr->tkwin); } if ((y + h) > screenHeight) { y -= (Tk_Height(parent) + h); /* Flip to show menu above. */ if (y < 0) { y = 0; } } if ((x + w) > screenWidth) { x -= (Tk_Width(parent)); /* Flip to show menu on left side. */ if (x < 0) { x = 0; } } *xPtr = x; *yPtr = y; } /* *--------------------------------------------------------------------------- * * ComputeVisibleEntries -- * * The entries visible in the viewport (the widget's window) are * inserted into the array of visible nodes. * * Results: * Returns 1 if beyond the last visible entry, 0 otherwise. * * Side effects: * The array of visible nodes is filled. * *--------------------------------------------------------------------------- */ static int ComputeVisibleEntries(ComboTree *comboPtr) { int nSlots; int maxX, maxY; int xOffset, yOffset; Entry *entryPtr; xOffset = Blt_AdjustViewport(comboPtr->xOffset, comboPtr->worldWidth, VPORTWIDTH(comboPtr), comboPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX); yOffset = Blt_AdjustViewport(comboPtr->yOffset, comboPtr->worldHeight, VPORTHEIGHT(comboPtr), comboPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX); if ((xOffset != comboPtr->xOffset) || (yOffset != comboPtr->yOffset)) { comboPtr->yOffset = yOffset; comboPtr->xOffset = xOffset; comboPtr->flags |= VIEWPORT; } /* Allocate worst case number of slots for entry array. */ nSlots = (VPORTHEIGHT(comboPtr) / comboPtr->minHeight) + 3; if (nSlots != comboPtr->nVisible) { if (comboPtr->visibleEntries != NULL) { Blt_Free(comboPtr->visibleEntries); } comboPtr->visibleEntries = Blt_AssertCalloc(nSlots, sizeof(Entry *)); } comboPtr->nVisible = 0; comboPtr->visibleEntries[0] = NULL; if (comboPtr->rootPtr->flags & ENTRY_HIDE) { return TCL_OK; /* Root node is hidden. */ } /* Find the first node in the viewport. */ entryPtr = comboPtr->rootPtr; while ((entryPtr->worldY + entryPtr->height) <= comboPtr->yOffset) { for (entryPtr = LastChild(entryPtr, ENTRY_HIDE); entryPtr != NULL; entryPtr = PrevSibling(entryPtr, ENTRY_HIDE)) { if (entryPtr->worldY <= comboPtr->yOffset) { break; } } /* * If we can't find the starting node, then the view must be * scrolled down, but some nodes were deleted. Reset the view * back to the top and try again. */ if (entryPtr == NULL) { if (comboPtr->yOffset == 0) { return TCL_OK; /* All entries are hidden. */ } comboPtr->yOffset = 0; continue; } } maxY = comboPtr->yOffset + VPORTHEIGHT(comboPtr); maxX = 0; while (entryPtr != NULL) { int x; int level; /* * Compute and save the entry's X-coordinate now that we know * the maximum level offset for the entire widget. */ level = Blt_Tree_NodeDepth(entryPtr->node); entryPtr->worldX = LEVELX(level); x = entryPtr->worldX + ICONWIDTH(level) + ICONWIDTH(level+1) + entryPtr->width; if (x > maxX) { maxX = x; } if (entryPtr->worldY >= maxY) { break; /* Entry starts after viewport. */ } comboPtr->visibleEntries[comboPtr->nVisible] = entryPtr; comboPtr->nVisible++; entryPtr = NextEntry(entryPtr, ENTRY_MASK); } comboPtr->visibleEntries[comboPtr->nVisible] = NULL; /* *------------------------------------------------------------------------------- * * Note: It's assumed that the view port always starts at or over an * entry. Check that a change in the hierarchy (e.g. closing a * node) hasn't left the viewport beyond the last entry. If so, * adjust the viewport to start on the last entry. * *------------------------------------------------------------------------------- */ if (comboPtr->xOffset > (comboPtr->worldWidth - comboPtr->xScrollUnits)) { comboPtr->xOffset = comboPtr->worldWidth - comboPtr->xScrollUnits; } if (comboPtr->yOffset > (comboPtr->worldHeight - comboPtr->yScrollUnits)) { comboPtr->yOffset = comboPtr->worldHeight - comboPtr->yScrollUnits; } comboPtr->xOffset = Blt_AdjustViewport(comboPtr->xOffset, comboPtr->worldWidth, VPORTWIDTH(comboPtr), comboPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX); comboPtr->yOffset = Blt_AdjustViewport(comboPtr->yOffset, comboPtr->worldHeight, VPORTHEIGHT(comboPtr), comboPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX); comboPtr->flags &= ~DIRTY; Blt_PickCurrentItem(comboPtr->bindTable); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetEntryIcon -- * * Selects the correct image for the entry's icon depending upon * the current state of the entry: active/inactive normal/selected. * * active - normal * active - selected * inactive - normal * inactive - selected * * Results: * Returns the image for the icon. * *--------------------------------------------------------------------------- */ static Icon GetEntryIcon(ComboTree *comboPtr, Entry *entryPtr) { Icon *icons; Icon icon; icons = entryPtr->stylePtr->icons; icon = NULL; if (icons != NULL) { icon = icons[0]; /* Open icon. */ if ((entryPtr->flags & ENTRY_CLOSED) && (icons[1] != NULL)) { icon = icons[1]; /* Closed icon. */ } } return icon; } /* *--------------------------------------------------------------------------- * * DrawButton -- * * Draws a button for the given entry. The button is drawn * centered in the region immediately to the left of the origin * of the entry (computed in the layout routines). The height * and width of the button were previously calculated from the * average row height. * * button height = entry height - (2 * some arbitrary padding). * button width = button height. * * The button may have a border. The symbol (either a plus or * minus) is slight smaller than the width or height minus the * border. * * x,y origin of entry * * +---+ * | + | icon label * +---+ * closed * * |----|----| horizontal offset * * +---+ * | - | icon label * +---+ * open * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ static void DrawButton( ComboTree *comboPtr, /* Widget record containing the * attribute information for * buttons. */ Entry *entryPtr, /* Entry. */ Drawable drawable, /* Pixmap or window to draw into. */ int x, int y) { Blt_Background bg; Button *btnPtr = &comboPtr->button; Icon icon; int relief; int width, height; bg = (entryPtr == comboPtr->activeBtnPtr) ? btnPtr->activeBg : btnPtr->normalBg; relief = (entryPtr->flags & ENTRY_CLOSED) ? btnPtr->closeRelief : btnPtr->openRelief; if (relief == TK_RELIEF_SOLID) { relief = TK_RELIEF_FLAT; } Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, btnPtr->width, btnPtr->height, btnPtr->borderWidth, relief); x += btnPtr->borderWidth; y += btnPtr->borderWidth; width = btnPtr->width - (2 * btnPtr->borderWidth); height = btnPtr->height - (2 * btnPtr->borderWidth); icon = NULL; if (btnPtr->icons != NULL) { /* Open or close button icon? */ icon = btnPtr->icons[0]; if (((entryPtr->flags & ENTRY_CLOSED) == 0) && (btnPtr->icons[1] != NULL)) { icon = btnPtr->icons[1]; } } if (icon != NULL) { /* Icon or rectangle? */ Tk_RedrawImage(IconImage(icon), 0, 0, width, height, drawable, x, y); } else { int top, bottom, left, right; XSegment segments[6]; int count; GC gc; gc = (entryPtr == comboPtr->activeBtnPtr) ? btnPtr->activeGC : btnPtr->normalGC; if (relief == TK_RELIEF_FLAT) { /* Draw the box outline */ left = x - btnPtr->borderWidth; top = y - btnPtr->borderWidth; right = left + btnPtr->width - 1; bottom = top + btnPtr->height - 1; segments[0].x1 = left; segments[0].x2 = right; segments[0].y2 = segments[0].y1 = top; segments[1].x2 = segments[1].x1 = right; segments[1].y1 = top; segments[1].y2 = bottom; segments[2].x2 = segments[2].x1 = left; segments[2].y1 = top; segments[2].y2 = bottom; #ifdef WIN32 segments[2].y2++; #endif segments[3].x1 = left; segments[3].x2 = right; segments[3].y2 = segments[3].y1 = bottom; #ifdef WIN32 segments[3].x2++; #endif } top = y + height / 2; left = x + BUTTON_IPAD; right = x + width - BUTTON_IPAD; segments[4].y1 = segments[4].y2 = top; segments[4].x1 = left; segments[4].x2 = right - 1; #ifdef WIN32 segments[4].x2++; #endif count = 5; if (entryPtr->flags & ENTRY_CLOSED) { /* Draw the vertical * line for the plus. */ top = y + BUTTON_IPAD; bottom = y + height - BUTTON_IPAD; segments[5].y1 = top; segments[5].y2 = bottom - 1; segments[5].x1 = segments[5].x2 = x + width / 2; #ifdef WIN32 segments[5].y2++; #endif count = 6; } XDrawSegments(comboPtr->display, drawable, gc, segments, count); } } static int DrawComboIcon(ComboTree *comboPtr, Entry *entryPtr, Drawable drawable, int x, int y) { Icon icon; icon = GetEntryIcon(comboPtr, entryPtr); if (icon != NULL) { /* Icon or default icon bitmap? */ int entryHeight; int level; int maxY; int top, bottom; int topInset, botInset; int width, height; level = Blt_Tree_NodeDepth(entryPtr->node); entryHeight = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, comboPtr->button.height); height = IconHeight(icon); width = IconWidth(icon); if (comboPtr->flatView) { x += (ICONWIDTH(0) - width) / 2; } else { x += (ICONWIDTH(level + 1) - width) / 2; } y += (entryHeight - height) / 2; botInset = comboPtr->inset - INSET_PAD; topInset = comboPtr->inset; maxY = Tk_Height(comboPtr->tkwin) - botInset; top = 0; bottom = y + height; if (y < topInset) { height += y - topInset; top = -y + topInset; y = topInset; } else if (bottom >= maxY) { height = maxY - y; } Tk_RedrawImage(IconImage(icon), 0, top, width, height, drawable, x, y); } return (icon != NULL); } static int DrawLabel(ComboTree *comboPtr, Entry *entryPtr, Drawable drawable, int x, int y, int maxLength) { const char *label; int entryHeight; int width, height; /* Width and height of label. */ entryHeight = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, comboPtr->button.height); /* Includes padding, selection 3-D border, and focus outline. */ width = entryPtr->labelWidth; height = entryPtr->labelHeight; /* Center the label, if necessary, vertically along the entry row. */ if (height < entryHeight) { y += (entryHeight - height) / 2; } x += LABEL_PADX; y += LABEL_PADY; label = GETLABEL(entryPtr); if (label[0] != '\0') { Style *stylePtr; TextStyle ts; XColor *color; stylePtr = entryPtr->stylePtr; if (entryPtr == comboPtr->activePtr) { color = stylePtr->labelActiveColor; } else { color = stylePtr->labelNormalColor; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, stylePtr->labelFont); Blt_Ts_SetForeground(ts, color); Blt_Ts_SetMaxLength(ts, maxLength); Blt_Ts_DrawLayout(comboPtr->tkwin, drawable, entryPtr->textPtr, &ts, x, y); if (entryPtr == comboPtr->activePtr) { Blt_Ts_UnderlineLayout(comboPtr->tkwin, drawable, entryPtr->textPtr, &ts, x, y); } } return entryHeight; } static void DrawEntryBackground( ComboTree *comboPtr, Entry *entryPtr, Drawable drawable, int x, int y, int w, int h) { Blt_Background bg; Style *stylePtr; int relief; stylePtr = entryPtr->stylePtr; if (entryPtr == comboPtr->activePtr) { bg = stylePtr->activeBg; relief = stylePtr->activeRelief; } else if ((stylePtr->altBg != NULL) && (entryPtr->seqNum & 0x1)) { bg = stylePtr->altBg; relief = stylePtr->relief; } else { bg = stylePtr->normalBg; relief = stylePtr->relief; } /* This also fills the background where there are no entries. */ Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, w, h, stylePtr->borderWidth, relief); } /* *--------------------------------------------------------------------------- * * DrawEntry -- * * Draws a button for the given entry. Note that buttons should only be * drawn if the entry has sub-entries to be opened or closed. It's the * responsibility of the calling routine to ensure this. * * The button is drawn centered in the region immediately to the left of * the origin of the entry (computed in the layout routines). The height * and width of the button were previously calculated from the average * row height. * * button height = entry height - (2 * some arbitrary padding). * button width = button height. * * The button has a border. The symbol (either a plus or minus) is * slight smaller than the width or height minus the border. * * x,y origin of entry * * +---+ * | + | icon label * +---+ * closed * * |----|----| horizontal offset * * +---+ * | - | icon label * +---+ * open * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ static void DrawEntry(ComboTree *comboPtr, Entry *entryPtr, Drawable drawable, int x, int y, int w, int h) { Button *btnPtr = &comboPtr->button; int buttonY; int level; int xMax; int x1, y1, x2, y2; GC gc; entryPtr->flags &= ~ENTRY_REDRAW; if ((comboPtr->activePtr == entryPtr) && (y == 0)) { gc = comboPtr->defStyle.labelActiveGC; } else { gc = comboPtr->lineGC; } level = Blt_Tree_NodeDepth(entryPtr->node); w = ICONWIDTH(level); h = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, btnPtr->height); entryPtr->buttonX = (w - btnPtr->width) / 2; entryPtr->buttonY = (h - btnPtr->height) / 2; buttonY = y + entryPtr->buttonY; x1 = x + (w / 2); y1 = y2 = buttonY + (btnPtr->height / 2); x2 = x1 + (ICONWIDTH(level) + ICONWIDTH(level + 1)) / 2; if ((Blt_Tree_ParentNode(entryPtr->node) != NULL) && (comboPtr->lineWidth > 0)) { /* * For every node except root, draw a horizontal line from the * vertical bar to the middle of the icon. */ XDrawLine(comboPtr->display, drawable, gc, x1, y1, x2, y2); } if (((entryPtr->flags & ENTRY_CLOSED) == 0) && (comboPtr->lineWidth > 0) && (entryPtr->vertLineLength > 0)) { /* * Entry is open, draw vertical line. */ y2 = y1 + entryPtr->vertLineLength; if (y2 > Tk_Height(comboPtr->tkwin)) { y2 = Tk_Height(comboPtr->tkwin); /* Clip line at window border. */ } XDrawLine(comboPtr->display, drawable, gc, x2, y1, x2, y2); } if ((entryPtr->flags & ENTRY_BUTTON) && (entryPtr != comboPtr->rootPtr)) { /* * Except for the root, draw a button for every entry that needs one. * The displayed button can be either an icon (Tk image) or a line * drawing (rectangle with plus or minus sign). */ DrawButton(comboPtr, entryPtr, drawable, x + entryPtr->buttonX, y + entryPtr->buttonY); } x += ICONWIDTH(level); if (!DrawComboIcon(comboPtr, entryPtr, drawable, x, y)) { x -= (ICON_WIDTH * 2) / 3; } x += ICONWIDTH(level + 1) + 4; /* Entry label. */ xMax = comboPtr->worldWidth; DrawLabel(comboPtr, entryPtr, drawable, x, y, xMax - x); } static void DrawEntryBackgrounds(ComboTree *comboPtr, Drawable drawable) { int x; int width; Entry **entryPtrPtr; width = Tk_Width(comboPtr->tkwin); x = comboPtr->inset; /* This also fills the background where there are no entries. */ Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, comboPtr->defStyle.normalBg, x, 0, width, Tk_Height(comboPtr->tkwin), 0, TK_RELIEF_FLAT); for (entryPtrPtr = comboPtr->visibleEntries; *entryPtrPtr != NULL; entryPtrPtr++) { Blt_Background bg; Style *stylePtr; Entry *entryPtr; int relief; int y; entryPtr = *entryPtrPtr; stylePtr = entryPtr->stylePtr; if (entryPtr == comboPtr->activePtr) { bg = stylePtr->activeBg; relief = stylePtr->activeRelief; } else if ((stylePtr->altBg != NULL) && (entryPtr->seqNum & 0x1)) { bg = stylePtr->altBg; relief = stylePtr->relief; } else { bg = stylePtr->normalBg; relief = stylePtr->relief; } y = SCREENY(comboPtr, entryPtr->worldY) - 1; Blt_FillBackgroundRectangle(comboPtr->tkwin, drawable, bg, x, y, width, entryPtr->height + 1, stylePtr->borderWidth, relief); } } /* *--------------------------------------------------------------------------- * * DrawVerticals -- * * Draws vertical lines for the ancestor nodes. While the entry * of the ancestor may not be visible, its vertical line segment * does extent into the viewport. So walk back up the hierarchy * drawing lines until we get to the root. * * Results: * None. * * Side Effects: * Vertical lines are drawn for the ancestor nodes. * *--------------------------------------------------------------------------- */ static void DrawVerticals(ComboTree *comboPtr, Entry *entryPtr, Drawable drawable, int xOffset, int yOffset) { GC gc; if ((comboPtr->activePtr == entryPtr) && (yOffset > 0)) { gc = comboPtr->defStyle.labelActiveGC; } else { gc = comboPtr->lineGC; } while (entryPtr != comboPtr->rootPtr) { entryPtr = ParentEntry(entryPtr); if (entryPtr == NULL) { break; } if (entryPtr->vertLineLength > 0) { int level; int ax, ay, bx, by; int x, y; int height; /* * World X-coordinates aren't computed for entries that are * outside the view port. So for each off-screen ancestor node * compute it here too. */ level = Blt_Tree_NodeDepth(entryPtr->node); entryPtr->worldX = LEVELX(level); x = SCREENX(comboPtr, entryPtr->worldX) - xOffset; y = SCREENY(comboPtr, entryPtr->worldY) - yOffset; height = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, comboPtr->button.height); y += (height - comboPtr->button.height) / 2; ax = bx = x + ICONWIDTH(level) + ICONWIDTH(level + 1) / 2; ay = y + comboPtr->button.height / 2; by = ay + entryPtr->vertLineLength; if ((entryPtr == comboPtr->rootPtr) && (comboPtr->flags & HIDE_ROOT)) { ay += entryPtr->height; } /* * Clip the line's Y-coordinates at the viewport's borders. */ if (ay < 0) { ay = (ay & 0x1); /* Make sure the dotted line starts on * the same even/odd pixel. */ } if (by > Tk_Height(comboPtr->tkwin)) { by = Tk_Height(comboPtr->tkwin); } if ((ay < Tk_Height(comboPtr->tkwin)) && (by > 0)) { XDrawLine(comboPtr->display, drawable, gc, ax, ay, bx, by); } } } } static void DrawComboTree(ComboTree *comboPtr, Drawable drawable) { Entry **entryPtrPtr; DrawEntryBackgrounds(comboPtr, drawable); if ((comboPtr->lineWidth > 0) && (comboPtr->nVisible > 0)) { /* Draw all the vertical lines from topmost node. */ DrawVerticals(comboPtr, comboPtr->visibleEntries[0], drawable, 0, 0); } for (entryPtrPtr = comboPtr->visibleEntries; *entryPtrPtr != NULL; entryPtrPtr++) { int x, y, w, h; Entry *entryPtr; entryPtr = *entryPtrPtr; x = SCREENX(comboPtr, entryPtr->worldX); y = SCREENY(comboPtr, entryPtr->worldY); w = ICONWIDTH(Blt_Tree_NodeDepth(entryPtr->node)); h = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, comboPtr->button.height); DrawEntry(comboPtr, entryPtr, drawable, x, y, w, h); } /* Manage the geometry of the embedded scrollbars. */ if (comboPtr->yScrollbarWidth > 0) { int x, y; int yScrollbarHeight; x = Tk_Width(comboPtr->tkwin) - comboPtr->borderWidth - comboPtr->yScrollbarWidth; y = comboPtr->borderWidth; yScrollbarHeight = Tk_Height(comboPtr->tkwin) - comboPtr->xScrollbarHeight - 2 * comboPtr->borderWidth; if ((Tk_Width(comboPtr->yScrollbar) != comboPtr->yScrollbarWidth) || (Tk_Height(comboPtr->yScrollbar) != yScrollbarHeight) || (x != Tk_X(comboPtr->yScrollbar)) || (y != Tk_Y(comboPtr->yScrollbar))) { Tk_MoveResizeWindow(comboPtr->yScrollbar, x, y, comboPtr->yScrollbarWidth, yScrollbarHeight); } if (!Tk_IsMapped(comboPtr->yScrollbar)) { Tk_MapWindow(comboPtr->yScrollbar); } } else if ((comboPtr->yScrollbar != NULL) && (Tk_IsMapped(comboPtr->yScrollbar))) { Tk_UnmapWindow(comboPtr->yScrollbar); } if (comboPtr->xScrollbarHeight > 0) { int x, y; int xScrollbarWidth; x = comboPtr->borderWidth; y = Tk_Height(comboPtr->tkwin) - comboPtr->xScrollbarHeight - comboPtr->borderWidth; xScrollbarWidth = Tk_Width(comboPtr->tkwin) - comboPtr->yScrollbarWidth - 2 * comboPtr->borderWidth; if ((Tk_Width(comboPtr->xScrollbar) != xScrollbarWidth) || (Tk_Height(comboPtr->xScrollbar) != comboPtr->xScrollbarHeight) || (x != Tk_X(comboPtr->xScrollbar)) || (y != Tk_Y(comboPtr->xScrollbar))) { Tk_MoveResizeWindow(comboPtr->xScrollbar, x, y, xScrollbarWidth, comboPtr->xScrollbarHeight); } if (!Tk_IsMapped(comboPtr->xScrollbar)) { Tk_MapWindow(comboPtr->xScrollbar); } } else if ((comboPtr->xScrollbar != NULL) && (Tk_IsMapped(comboPtr->xScrollbar))) { Tk_UnmapWindow(comboPtr->xScrollbar); } } static void DrawOuterBorders(ComboTree *comboPtr, Drawable drawable) { /* Draw 3D border just inside of the focus highlight ring. */ if ((comboPtr->borderWidth > 0) && (comboPtr->relief != TK_RELIEF_FLAT)) { Blt_DrawBackgroundRectangle(comboPtr->tkwin, drawable, comboPtr->defStyle.normalBg, 0, 0, Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin), comboPtr->borderWidth, comboPtr->relief); } } /* *--------------------------------------------------------------------------- * * DisplayEntry -- * * This procedure is invoked to display an entry in the combotree widget. * * Results: * None. * * Side effects: * Commands are output to X to display the entry. * *--------------------------------------------------------------------------- */ static void DisplayEntry(ClientData clientData) { Entry *entryPtr = clientData; ComboTree *comboPtr; Pixmap drawable; int x, y, w, h, d, sy; #ifdef notdef fprintf(stderr, "DisplayEntry (%s)\n", GETLABEL(entryPtr)); #endif comboPtr = entryPtr->comboPtr; /* Create a pixmap the size of the window for double buffering. */ comboPtr = entryPtr->comboPtr; w = VPORTWIDTH(comboPtr); h = entryPtr->height; drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), w, h, Tk_Depth(comboPtr->tkwin)); #ifdef WIN32 assert(drawable != None); #endif x = PIXMAPX(comboPtr, entryPtr->worldX); y = PIXMAPY(comboPtr, entryPtr->worldY) + comboPtr->borderWidth; DrawEntryBackground(comboPtr, entryPtr, drawable, 0, 0, w, h); if ((comboPtr->lineWidth > 0) && (comboPtr->nVisible > 0)) { /* Draw all the vertical lines from topmost node. */ DrawVerticals(comboPtr, entryPtr, drawable, comboPtr->borderWidth, SCREENY(comboPtr, entryPtr->worldY)); } DrawEntry(comboPtr, entryPtr, drawable, x, 0, w, h); sy = 0; d = comboPtr->borderWidth - y; if (d > 0) { h -= d; sy = d; y += d; } d = (y + h) - (Tk_Height(comboPtr->tkwin) - comboPtr->borderWidth); if (d > 0) { h -= d; } XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->defStyle.labelNormalGC, 0, sy, w, h, comboPtr->borderWidth, y); Tk_FreePixmap(comboPtr->display, drawable); } /* *--------------------------------------------------------------------------- * * ActivateOp -- * * Activate the specified entry (draw with active foreground/background). * Only one entry may be active at one time, so the previously active * entry is deactivated. * * Results: * Standard TCL result. * * Side effects: * The widget is eventually redraw. * * .cm activate entry * *--------------------------------------------------------------------------- */ static int ActivateOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; if (GetEntryFromObj(NULL, comboPtr, objv[2], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (comboPtr->activePtr == entryPtr) { return TCL_OK; /* Entry is already active. */ } ActivateEntry(comboPtr, NULL); /* Deactive the current active. */ if (entryPtr != NULL) { ActivateEntry(comboPtr, entryPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BindOp -- * * .t bind entry sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData object; Entry *entryPtr; const char *string; /* * Entries are selected by id only. All other strings are interpreted as * a binding tag. */ string = Tcl_GetString(objv[2]); if (isdigit(UCHAR(string[0]))) { Blt_TreeNode node; long inode; if (Tcl_GetLongFromObj(comboPtr->interp, objv[2], &inode) != TCL_OK) { return TCL_ERROR; } node = Blt_Tree_GetNode(comboPtr->tree, inode); object = NodeToEntry(comboPtr, node); } else if (GetEntryFromObj(interp, comboPtr, objv[2], &entryPtr)==TCL_OK) { if (entryPtr != NULL) { return TCL_OK; /* Special id doesn't currently * exist. */ } object = entryPtr; } else { /* Assume that this is a binding tag. */ object = EntryTag(comboPtr, string); } return Blt_ConfigureBindingsFromObj(interp, comboPtr->bindTable, object, objc - 3, objv + 3); } /* *--------------------------------------------------------------------------- * * ButtonActivateOp -- * * Selects the button to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonActivateOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *oldPtr, *entryPtr; const char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { entryPtr = NULL; } else if (GetEntryFromObj(interp, comboPtr, objv[3], &entryPtr) != TCL_OK){ return TCL_ERROR; } if ((entryPtr != NULL) && !(entryPtr->flags & ENTRY_BUTTON)) { entryPtr = NULL; } oldPtr = comboPtr->activeBtnPtr; comboPtr->activeBtnPtr = entryPtr; if (!(comboPtr->flags & REDRAW_PENDING) && (entryPtr != oldPtr)) { if ((oldPtr != NULL) && (oldPtr != comboPtr->rootPtr)) { #ifdef notdef DrawButton(comboPtr, oldPtr); #endif } if ((entryPtr != NULL) && (entryPtr != comboPtr->rootPtr)) { #ifdef notdef DrawButton(comboPtr, entryPtr); #endif } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonBindOp -- * * .ct bind tag sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonBindOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { ClientData object; /* Assume that this is a binding tag. */ object = ButtonTag(comboPtr, Tcl_GetString(objv[3])); return Blt_ConfigureBindingsFromObj(interp, comboPtr->bindTable, object, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * ButtonCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonCgetOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)comboPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ButtonConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure the one of more entries in the * widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for comboPtr; old resources get freed, if there were any. * * .ct button configure option value * *--------------------------------------------------------------------------- */ static int ButtonConfigureOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)comboPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, buttonSpecs, (char *)comboPtr, objv[3], 0); } iconsOption.clientData = comboPtr; if (Blt_ConfigureWidgetFromObj(comboPtr->interp, comboPtr->tkwin, buttonSpecs, objc - 3, objv + 3, (char *)comboPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } ConfigureButtons(comboPtr); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonOp -- * * This procedure handles button operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec buttonOps[] = { {"activate", 1, ButtonActivateOp, 4, 4, "entry",}, {"bind", 1, ButtonBindOp, 4, 6, "tagName ?sequence command?",}, {"cget", 2, ButtonCgetOp, 4, 4, "option",}, {"configure", 2, ButtonConfigureOp, 3, 0, "?option value?...",}, {"highlight", 1, ButtonActivateOp, 4, 4, "entry",}, }; static int nButtonOps = sizeof(buttonOps) / sizeof(Blt_OpSpec); static int ButtonOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboTreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nButtonOps, buttonOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, comboSpecs, (char *)comboPtr, objv[2], 0); } /*ARGSUSED*/ static int CloseOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int recurse, result; Entry *entryPtr; EntryIterator iter; recurse = FALSE; if (objc > 2) { const char *string; int length; string = Tcl_GetStringFromObj(objv[2], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } } if (GetEntryIterator(interp, comboPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { /* * Check if either the active entry is in this hierarchy. Must move * it or disable it before we close the node. Otherwise it may be * deleted by a TCL "close" script, and we'll be left pointing to a * bogus memory location. */ if ((comboPtr->activePtr != NULL) && (Blt_Tree_IsAncestor(entryPtr->node, comboPtr->activePtr->node))) { comboPtr->activePtr = entryPtr; } if (recurse) { result = Apply(comboPtr, entryPtr, CloseEntry, 0); } else { result = CloseEntry(comboPtr, entryPtr); } if (result != TCL_OK) { return TCL_ERROR; } } /* Closing a node may affect the visible entries and the the world layout * of the entries. */ comboPtr->flags |= (LAYOUT_PENDING | DIRTY); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) the widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for comboPtr; old resources get freed, if there were any. The * widget is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, comboSpecs, (char *)comboPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, comboSpecs, (char *)comboPtr, objv[2], 0); } iconsOption.clientData = comboPtr; if (ConfigureComboTree(interp, comboPtr, objc - 2, objv + 2, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryActivateOp -- * * Selects the entry to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryActivateOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *newPtr, *oldPtr; const char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { newPtr = NULL; } else if (GetEntry(comboPtr, objv[3], &newPtr) != TCL_OK) { return TCL_ERROR; } oldPtr = comboPtr->activePtr; comboPtr->activePtr = newPtr; if (((comboPtr->flags & REDRAW_PENDING) == 0) && (newPtr != oldPtr)) { Drawable drawable; int x, y; drawable = Tk_WindowId(comboPtr->tkwin); if (oldPtr != NULL) { x = SCREENX(comboPtr, oldPtr->worldX) + ICONWIDTH(Blt_Tree_NodeDepth(oldPtr->node)); y = SCREENY(comboPtr, oldPtr->worldY); oldPtr->flags |= ENTRY_ICON; DrawComboIcon(comboPtr, oldPtr, drawable, x, y); } if (newPtr != NULL) { x = SCREENX(comboPtr, newPtr->worldX) + ICONWIDTH(Blt_Tree_NodeDepth(newPtr->node)); y = SCREENY(comboPtr, newPtr->worldY); newPtr->flags |= ENTRY_ICON; DrawComboIcon(comboPtr, newPtr, drawable, x, y); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryCgetOp -- * * .ct entry cget entry option * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryCgetOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; if (GetEntry(comboPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, entrySpecs, (char *)entryPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * EntryConfigureOp -- * * This procedure is called to process a list of configuration options * database, in order to reconfigure the one of more entries in the * widget. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for comboPtr; old resources get freed, if there were any. The * hypertext is redisplayed. * * .ct entry configure entry option value * *--------------------------------------------------------------------------- */ static int EntryConfigureOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { EntryIterator iter; Entry *entryPtr; iconsOption.clientData = comboPtr; uidOption.clientData = comboPtr; if (GetEntryIterator(interp, comboPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, entrySpecs, (char *)entryPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, entrySpecs, (char *)entryPtr, objv[4], 0); } if (ConfigureEntry(comboPtr, entryPtr, objc, objv, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } } comboPtr->flags |= (DIRTY | LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryIsHiddenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryIsHiddenOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; int bool; if (GetEntry(comboPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } bool = (entryPtr->flags & ENTRY_HIDE); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryIsOpenOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EntryIsOpenOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; int bool; if (GetEntry(comboPtr, objv[3], &entryPtr) != TCL_OK) { return TCL_ERROR; } bool = ((entryPtr->flags & ENTRY_CLOSED) == 0); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), bool); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EntryOp -- * * This procedure handles entry operations. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static Blt_OpSpec entryOps[] = { {"activate", 1, EntryActivateOp, 4, 4, "entry",}, {"cget", 2, EntryCgetOp, 5, 5, "entry option",}, {"configure", 2, EntryConfigureOp, 4, 0, "entry ?entry...? ?option value?...",}, {"highlight", 1, EntryActivateOp, 4, 4, "entry",}, {"ishidden", 3, EntryIsHiddenOp, 4, 4, "entry",}, {"isopen", 3, EntryIsOpenOp, 4, 4, "entry",}, }; static int nEntryOps = sizeof(entryOps) / sizeof(Blt_OpSpec); static int EntryOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboTreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nEntryOps, entryOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int ExactCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return (strcmp(name, pattern) == 0); } /*ARGSUSED*/ static int GlobCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return Tcl_StringMatch(name, pattern); } static int RegexpCompare(Tcl_Interp *interp, const char *name, const char *pattern) { return Tcl_RegExpMatch(interp, name, pattern); } /* *--------------------------------------------------------------------------- * * GetOp -- * * Converts one or more node identifiers to its path component. The path * may be either the single entry name or the full path of the entry. * * Results: * A standard TCL result. The interpreter result will contain a list of * the convert names. * *--------------------------------------------------------------------------- */ static int GetOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int useFullName; int i; Tcl_DString d1, d2; int count; useFullName = FALSE; if (objc > 2) { const char *string; string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-full") == 0)) { useFullName = TRUE; objv++, objc--; } } Tcl_DStringInit(&d1); /* Result. */ Tcl_DStringInit(&d2); /* Last element. */ count = 0; for (i = 2; i < objc; i++) { EntryIterator iter; Entry *entryPtr; if (GetEntryIterator(interp, comboPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { Tcl_DStringSetLength(&d2, 0); count++; if (entryPtr->node != NULL) { if (useFullName) { GetFullName(comboPtr, entryPtr, &d2); } else { Tcl_DStringAppend(&d2, Blt_Tree_NodeLabel(entryPtr->node),-1); } Tcl_DStringAppendElement(&d1, Tcl_DStringValue(&d2)); } } } /* This handles the single element list problem. */ if (count == 1) { Tcl_DStringResult(interp, &d2); Tcl_DStringFree(&d1); } else { Tcl_DStringResult(interp, &d1); Tcl_DStringFree(&d2); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShowEntryApplyProc -- * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ShowEntryApplyProc(ComboTree *comboPtr, Entry *entryPtr) { entryPtr->flags &= ~ENTRY_HIDE; return TCL_OK; } /* *--------------------------------------------------------------------------- * * HideEntryApplyProc -- * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HideEntryApplyProc(ComboTree *comboPtr, Entry *entryPtr) { entryPtr->flags |= ENTRY_HIDE; return TCL_OK; } static void MapAncestors(ComboTree *comboPtr, Entry *entryPtr) { while (entryPtr != comboPtr->rootPtr) { entryPtr = ParentEntry(entryPtr); if (entryPtr->flags & (ENTRY_CLOSED | ENTRY_HIDE)) { comboPtr->flags |= LAYOUT_PENDING; entryPtr->flags &= ~(ENTRY_CLOSED | ENTRY_HIDE); } } } /* *--------------------------------------------------------------------------- * * MapAncestorsApplyProc -- * * If a node in mapped, then all its ancestors must be mapped also. This * routine traverses upwards and maps each unmapped ancestor. It's * assumed that for any mapped ancestor, all it's ancestors will already * be mapped too. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ static int MapAncestorsApplyProc(ComboTree *comboPtr, Entry *entryPtr) { /* * Make sure that all the ancestors of this entry are mapped too. */ while (entryPtr != comboPtr->rootPtr) { entryPtr = ParentEntry(entryPtr); if ((entryPtr->flags & (ENTRY_HIDE | ENTRY_CLOSED)) == 0) { break; /* Assume ancestors are also mapped. */ } entryPtr->flags &= ~(ENTRY_HIDE | ENTRY_CLOSED); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SearchAndApplyToTree -- * * Searches through the current tree and applies a procedure to matching * nodes. The search specification is taken from the following * command-line arguments: * * ?-exact? ?-glob? ?-regexp? ?-nonmatching? * ?-data string? * ?-name string? * ?-full string? * ?--? * ?inode...? * * Results: * A standard TCL result. If the result is valid, and if the nonmatchPtr * is specified, it returns a boolean value indicating whether or not the * search was inverted. This is needed to fix things properly for the * "hide nonmatching" case. * *--------------------------------------------------------------------------- */ static int SearchAndApplyToTree(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, ApplyProc *proc, int *nonMatchPtr) { CompareProc *compareProc; int invertMatch; /* normal search mode (matching entries) */ const char *namePattern, *fullPattern; int i; int length; int result; const char *option, *pattern; char c; Blt_List options; Entry *entryPtr; Blt_ListNode node; const char *string; const char *withTag; Tcl_Obj *objPtr; options = Blt_List_Create(BLT_ONE_WORD_KEYS); invertMatch = FALSE; namePattern = fullPattern = NULL; compareProc = ExactCompare; withTag = NULL; entryPtr = comboPtr->rootPtr; for (i = 2; i < objc; i++) { string = Tcl_GetStringFromObj(objv[i], &length); if (string[0] != '-') { break; } option = string + 1; length--; c = option[0]; if ((c == 'e') && (strncmp(option, "exact", length) == 0)) { compareProc = ExactCompare; } else if ((c == 'g') && (strncmp(option, "glob", length) == 0)) { compareProc = GlobCompare; } else if ((c == 'r') && (strncmp(option, "regexp", length) == 0)) { compareProc = RegexpCompare; } else if ((c == 'n') && (length > 1) && (strncmp(option, "nonmatching", length) == 0)) { invertMatch = TRUE; } else if ((c == 'f') && (strncmp(option, "full", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; fullPattern = Tcl_GetString(objv[i]); } else if ((c == 'n') && (length > 1) && (strncmp(option, "name", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; namePattern = Tcl_GetString(objv[i]); } else if ((c == 't') && (length > 1) && (strncmp(option, "tag", length) == 0)) { if ((i + 1) == objc) { goto missingArg; } i++; withTag = Tcl_GetString(objv[i]); } else if ((option[0] == '-') && (option[1] == '\0')) { break; } else { /* * Verify that the switch is actually an entry configuration * option. */ if (Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, entrySpecs, (char *)entryPtr, objv[i], 0) != TCL_OK) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad switch \"", string, "\": must be -exact, -glob, -regexp, -name, -full, or -nonmatching", (char *)NULL); return TCL_ERROR; } if ((i + 1) == objc) { goto missingArg; } /* Save the option in the list of configuration options */ node = Blt_List_GetNode(options, (char *)objv[i]); if (node == NULL) { node = Blt_List_CreateNode(options, (char *)objv[i]); Blt_List_AppendNode(options, node); } i++; Blt_List_SetValue(node, Tcl_GetString(objv[i])); } } if ((namePattern != NULL) || (fullPattern != NULL) || (Blt_List_GetLength(options) > 0)) { /* * Search through the tree and look for nodes that match the current * spec. Apply the input procedure to each of the matching nodes. */ for (entryPtr = comboPtr->rootPtr; entryPtr != NULL; entryPtr = NextEntry(entryPtr, 0)) { if (namePattern != NULL) { result = (*compareProc) (interp, Blt_Tree_NodeLabel(entryPtr->node), namePattern); if (result == invertMatch) { continue; /* Failed to match */ } } if (fullPattern != NULL) { Tcl_DString ds; GetFullName(comboPtr, entryPtr, &ds); result = (*compareProc)(interp, Tcl_DStringValue(&ds), fullPattern); Tcl_DStringFree(&ds); if (result == invertMatch) { continue; /* Failed to match */ } } if (withTag != NULL) { result = Blt_Tree_HasTag(comboPtr->tree, entryPtr->node, withTag); if (result == invertMatch) { continue; /* Failed to match */ } } for (node = Blt_List_FirstNode(options); node != NULL; node = Blt_List_NextNode(node)) { objPtr = (Tcl_Obj *)Blt_List_GetKey(node); Tcl_ResetResult(interp); if (Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, entrySpecs, (char *)entryPtr, objPtr, 0) != TCL_OK) { return TCL_ERROR; /* This shouldn't happen. */ } pattern = Blt_List_GetValue(node); objPtr = Tcl_GetObjResult(interp); result = (*compareProc)(interp, Tcl_GetString(objPtr), pattern); if (result == invertMatch) { continue; /* Failed to match */ } } /* Finally, apply the procedure to the node */ (*proc)(comboPtr, entryPtr); } Tcl_ResetResult(interp); Blt_List_Destroy(options); } /* * Apply the procedure to nodes that have been specified individually. */ for ( /*empty*/ ; i < objc; i++) { EntryIterator iter; if (GetEntryIterator(interp, comboPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { if ((*proc) (comboPtr, entryPtr) != TCL_OK) { return TCL_ERROR; } } } if (nonMatchPtr != NULL) { *nonMatchPtr = invertMatch; /* return "inverted search" status */ } return TCL_OK; missingArg: Blt_List_Destroy(options); Tcl_AppendResult(interp, "missing pattern for search option \"", objv[i], "\"", (char *)NULL); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * HideOp -- * * Hides one or more nodes. Nodes can be specified by their inode, or by * matching a name or data value pattern. By default, the patterns are * matched exactly. They can also be matched using glob-style and * regular expression rules. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int HideOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int status, nonmatching; status = SearchAndApplyToTree(comboPtr, interp, objc, objv, HideEntryApplyProc, &nonmatching); if (status != TCL_OK) { return TCL_ERROR; } /* * If this was an inverted search, scan back through the tree and make * sure that the parents for all visible nodes are also visible. After * all, if a node is supposed to be visible, its parent can't be hidden. */ if (nonmatching) { Apply(comboPtr, comboPtr->rootPtr, MapAncestorsApplyProc, 0); } /* Hiding an entry only effects the visible nodes. */ comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Converts one of more words representing indices of the entries in the * treeview widget to their respective serial identifiers. * * Results: * A standard TCL result. Interp->result will contain the identifier of * each inode found. If an inode could not be found, then the serial * identifier will be the empty string. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; long nodeId; nodeId = -1; if ((GetEntryFromObj(NULL, comboPtr, objv[2], &entryPtr) == TCL_OK) && (entryPtr != NULL)) { nodeId = Blt_Tree_NodeId(entryPtr->node); } Tcl_SetLongObj(Tcl_GetObjResult(interp), nodeId); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * Results: * Standard TCL result. * * Side effects: * Commands may get excecuted; variables may get set. * * .ct invoke entry * *--------------------------------------------------------------------------- */ static int InvokeOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result; Entry *entryPtr; if (GetEntryFromObj(interp, comboPtr, objv[2], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { return TCL_OK; /* Entry is currently disabled. */ } result = TCL_OK; Tcl_Preserve((ClientData)entryPtr); if (comboPtr->iconVarObjPtr != NULL) { Tcl_Obj *objPtr; Icon icon; icon = GetEntryIcon(comboPtr, entryPtr); objPtr = Tcl_NewStringObj(IconName(icon), -1); if (Tcl_ObjSetVar2(interp, comboPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } if (comboPtr->textVarObjPtr != NULL) { Tcl_Obj *objPtr; Tcl_DString ds; Tcl_DStringInit(&ds); GetFullName(comboPtr, entryPtr, &ds); objPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); Tcl_DStringFree(&ds); if (Tcl_ObjSetVar2(interp, comboPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } if (entryPtr->cmdObjPtr != NULL) { Tcl_IncrRefCount(entryPtr->cmdObjPtr); result = Tcl_EvalObjEx(interp, entryPtr->cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(entryPtr->cmdObjPtr); } Tcl_Release((ClientData)entryPtr); return result; } /*ARGSUSED*/ static int NearestOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Button *buttonPtr = &comboPtr->button; int x, y; /* Screen coordinates of the test point. */ Entry *entryPtr; int isRoot; const char *string; isRoot = FALSE; string = Tcl_GetString(objv[2]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } if ((Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, comboPtr->tkwin, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (comboPtr->nVisible == 0) { return TCL_OK; } if (isRoot) { int rootX, rootY; Tk_GetRootCoords(comboPtr->tkwin, &rootX, &rootY); x -= rootX; y -= rootY; } entryPtr = NearestEntry(comboPtr, x, y, TRUE); if (entryPtr == NULL) { return TCL_OK; } x = WORLDX(comboPtr, x); y = WORLDY(comboPtr, y); if (objc > 4) { const char *where; int labelX, labelY, depth; Icon icon; where = ""; if (entryPtr->flags & ENTRY_BUTTON) { int buttonX, buttonY; buttonX = entryPtr->worldX + entryPtr->buttonX; buttonY = entryPtr->worldY + entryPtr->buttonY; if ((x >= buttonX) && (x < (buttonX + buttonPtr->width)) && (y >= buttonY) && (y < (buttonY + buttonPtr->height))) { where = "button"; goto done; } } depth = Blt_Tree_NodeDepth(entryPtr->node); icon = GetEntryIcon(comboPtr, entryPtr); if (icon != NULL) { int iconWidth, iconHeight, entryHeight; int iconX, iconY; entryHeight = MAX(entryPtr->iconHeight, comboPtr->button.height); iconHeight = IconHeight(icon); iconWidth = IconWidth(icon); iconX = entryPtr->worldX + ICONWIDTH(depth); iconY = entryPtr->worldY; iconX += (ICONWIDTH(depth + 1) - iconWidth) / 2; iconY += (entryHeight - iconHeight) / 2; if ((x >= iconX) && (x <= (iconX + iconWidth)) && (y >= iconY) && (y < (iconY + iconHeight))) { where = "icon"; goto done; } } labelX = entryPtr->worldX + ICONWIDTH(depth); labelY = entryPtr->worldY; if (!comboPtr->flatView) { labelX += ICONWIDTH(depth + 1) + 4; } if ((x >= labelX) && (x < (labelX + entryPtr->labelWidth)) && (y >= labelY) && (y < (labelY + entryPtr->labelHeight))) { where = "label"; } done: if (Tcl_SetVar(interp, Tcl_GetString(objv[4]), where, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } Tcl_SetLongObj(Tcl_GetObjResult(interp), Blt_Tree_NodeId(entryPtr->node)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * OpenOp -- * * Returns the node identifiers in a given range. * * .ct open ?-recurse? $entry *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OpenOp( ComboTree *comboPtr, Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { int recurse, result; Entry *entryPtr; EntryIterator iter; recurse = FALSE; if (objc > 2) { int length; const char *string; string = Tcl_GetStringFromObj(objv[2], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } } if (GetEntryIterator(interp, comboPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { if (recurse) { result = Apply(comboPtr, entryPtr, OpenEntry, 0); } else { result = OpenEntry(comboPtr, entryPtr); } if (result != TCL_OK) { return TCL_ERROR; } /* Make sure ancestors of this node aren't hidden. */ MapAncestors(comboPtr, entryPtr); } /*FIXME: This is only for flattened entries. */ comboPtr->flags |= (LAYOUT_PENDING | DIRTY | SCROLL_PENDING); /* Can't trust the selected entry if nodes have been added or deleted. So * recompute the layout. */ if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } ComputeVisibleEntries(comboPtr); EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PostOp -- * * Posts this menu at the given root screen coordinates. * * .cm post ?x y? * *--------------------------------------------------------------------------- */ static int PostOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; Tk_Window parent; int menuWidth; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } menuWidth = Tk_ReqWidth(comboPtr->tkwin); parent = Tk_Parent(comboPtr->tkwin); if (Tk_Width(parent) > menuWidth) { menuWidth = Tk_Width(parent); } if (objc == 5) { const char *string; string = Tcl_GetString(objv[4]); if (strcmp(string, "left") == 0) { /* Do nothing. */ } else if (strcmp(string, "right") == 0) { x -= menuWidth; } else if (strcmp(string, "center") == 0) { x -= menuWidth / 2; } else { Tcl_AppendResult(interp, "bad alignment value \"", string, "\": should be left, right, or center.", (char *)NULL); return TCL_ERROR; } } FixMenuCoords(comboPtr, &x, &y); #ifdef notdef int x, y; if (objc == 4) { if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } } else if (objc == 2) { if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } ComputeMenuCoords(comboPtr, TK_ANCHOR_SE, &x, &y); } else { Tcl_AppendResult(interp, "wrong # of args: should be \"", Tcl_GetString(objv[0]), " post ?x y?\"", (char *)NULL); return TCL_ERROR; } if (Tk_IsMapped(comboPtr->tkwin)) { return TCL_OK; /* This menu is already posted. */ } #endif /* * If there is a post command for the menu, execute it. This may change * the size of the menu, so be sure to recompute the menu's geometry if * needed. */ if (comboPtr->postCmdObjPtr != NULL) { int result; Tcl_IncrRefCount(comboPtr->postCmdObjPtr); result = Tcl_EvalObjEx(interp, comboPtr->postCmdObjPtr,TCL_EVAL_GLOBAL); Tcl_DecrRefCount(comboPtr->postCmdObjPtr); if (result != TCL_OK) { return result; } /* * The post commands could have deleted the menu, which means we are * dead and should go away. */ if (comboPtr->tkwin == NULL) { return TCL_OK; } if (comboPtr->flags & LAYOUT_PENDING) { ComputeComboGeometry(comboPtr); } } /* * Adjust the position of the menu if necessary to keep it visible on the * screen. There are two special tricks to make this work right: * * 1. If a virtual root window manager is being used then * the coordinates are in the virtual root window of * menuPtr's parent; since the menu uses override-redirect * mode it will be in the *real* root window for the screen, * so we have to map the coordinates from the virtual root * (if any) to the real root. Can't get the virtual root * from the menu itself (it will never be seen by the wm) * so use its parent instead (it would be better to have an * an option that names a window to use for this...). * 2. The menu may not have been mapped yet, so its current size * might be the default 1x1. To compute how much space it * needs, use its requested size, not its actual size. * * Note that this code assumes square screen regions and all positive * coordinates. This does not work on a Mac with multiple monitors. But * then again, Tk has other problems with this. */ { int vx, vy, vw, vh; int tmp; int screenWidth, screenHeight; Blt_SizeOfScreen(comboPtr->tkwin, &screenWidth, &screenHeight); Tk_GetVRootGeometry(Tk_Parent(comboPtr->tkwin), &vx, &vy, &vw, &vh); x += vx; y += vy; tmp = screenWidth - Tk_ReqWidth(comboPtr->tkwin); if (x > tmp) { x = tmp; } if (x < 0) { x = 0; } tmp = screenHeight - Tk_ReqHeight(comboPtr->tkwin); if (y > tmp) { y = tmp; } if (y < 0) { y = 0; } Tk_MoveToplevelWindow(comboPtr->tkwin, x, y); Blt_MapToplevelWindow(comboPtr->tkwin); if (!Tk_IsMapped(comboPtr->tkwin)) { Tk_MapWindow(comboPtr->tkwin); } Blt_MapToplevelWindow(comboPtr->tkwin); Blt_RaiseToplevelWindow(comboPtr->tkwin); #ifdef notdef TkWmRestackToplevel(comboPtr->tkwin, Above, NULL); #endif } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScanOp -- * * Implements the quick scan. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ScanOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; char c; int length; int oper; const char *string; Tk_Window tkwin; #define SCAN_MARK 1 #define SCAN_DRAGTO 2 string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; tkwin = comboPtr->tkwin; if ((c == 'm') && (strncmp(string, "mark", length) == 0)) { oper = SCAN_MARK; } else if ((c == 'd') && (strncmp(string, "dragto", length) == 0)) { oper = SCAN_DRAGTO; } else { Tcl_AppendResult(interp, "bad scan operation \"", string, "\": should be either \"mark\" or \"dragto\"", (char *)NULL); return TCL_ERROR; } if ((Blt_GetPixelsFromObj(interp, tkwin, objv[3], PIXELS_ANY, &x) != TCL_OK) || (Blt_GetPixelsFromObj(interp, tkwin, objv[4], PIXELS_ANY, &y) != TCL_OK)) { return TCL_ERROR; } if (oper == SCAN_MARK) { comboPtr->scanAnchorX = x; comboPtr->scanAnchorY = y; comboPtr->scanX = comboPtr->xOffset; comboPtr->scanY = comboPtr->yOffset; } else { int worldX, worldY; int viewWidth, viewHeight; int dx, dy; dx = comboPtr->scanAnchorX - x; dy = comboPtr->scanAnchorY - y; worldX = comboPtr->scanX + (10 * dx); worldY = comboPtr->scanY + (10 * dy); viewWidth = VPORTWIDTH(comboPtr); if (worldX > (comboPtr->worldWidth - viewWidth)) { worldX = comboPtr->worldWidth - viewWidth; } if (worldX < 0) { worldX = 0; } viewHeight = VPORTHEIGHT(comboPtr); if (worldY > (comboPtr->worldHeight - viewHeight)) { worldY = comboPtr->worldHeight - viewHeight; } if (worldY < 0) { worldY = 0; } comboPtr->xOffset = worldX; comboPtr->yOffset = worldY; comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); } return TCL_OK; } /*ARGSUSED*/ static int SeeOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; int width, height; int x, y; Tk_Anchor anchor; int left, right, top, bottom; const char *string; string = Tcl_GetString(objv[2]); anchor = TK_ANCHOR_W; /* Default anchor is West */ if ((string[0] == '-') && (strcmp(string, "-anchor") == 0)) { if (objc == 3) { Tcl_AppendResult(interp, "missing \"-anchor\" argument", (char *)NULL); return TCL_ERROR; } if (Tk_GetAnchorFromObj(interp, objv[3], &anchor) != TCL_OK) { return TCL_ERROR; } objc -= 2, objv += 2; } if (objc == 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", objv[0], "see ?-anchor anchor? entry\"", (char *)NULL); return TCL_ERROR; } if (GetEntryFromObj(interp, comboPtr, objv[2], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (entryPtr == NULL) { return TCL_OK; } if (entryPtr->flags & ENTRY_HIDE) { MapAncestors(comboPtr, entryPtr); comboPtr->flags |= SCROLL_PENDING; /* * If the entry wasn't previously exposed, its world coordinates * aren't likely to be valid. So re-compute the layout before we try * to see the viewport to the entry's location. */ ComputeComboGeometry(comboPtr); } width = VPORTWIDTH(comboPtr); height = VPORTHEIGHT(comboPtr); /* * XVIEW: If the entry is left or right of the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ left = comboPtr->xOffset; right = comboPtr->xOffset + width; switch (anchor) { case TK_ANCHOR_W: case TK_ANCHOR_NW: case TK_ANCHOR_SW: x = 0; break; case TK_ANCHOR_E: case TK_ANCHOR_NE: case TK_ANCHOR_SE: x = entryPtr->worldX + entryPtr->width + ICONWIDTH(Blt_Tree_NodeDepth(entryPtr->node)) - width; break; default: if (entryPtr->worldX < left) { x = entryPtr->worldX; } else if ((entryPtr->worldX + entryPtr->width) > right) { x = entryPtr->worldX + entryPtr->width - width; } else { x = comboPtr->xOffset; } break; } /* * YVIEW: If the entry is above or below the current view, adjust * the offset. If the entry is nearby, adjust the view just * a bit. Otherwise, center the entry. */ top = comboPtr->yOffset; bottom = comboPtr->yOffset + height; switch (anchor) { case TK_ANCHOR_N: y = comboPtr->yOffset; break; case TK_ANCHOR_NE: case TK_ANCHOR_NW: y = entryPtr->worldY - (height / 2); break; case TK_ANCHOR_S: case TK_ANCHOR_SE: case TK_ANCHOR_SW: y = entryPtr->worldY + entryPtr->height - height; break; default: if (entryPtr->worldY < top) { y = entryPtr->worldY; } else if ((entryPtr->worldY + entryPtr->height) > bottom) { y = entryPtr->worldY + entryPtr->height - height; } else { y = comboPtr->yOffset; } break; } if ((y != comboPtr->yOffset) || (x != comboPtr->xOffset)) { /* comboPtr->xOffset = x; */ comboPtr->yOffset = y; comboPtr->flags |= SCROLL_PENDING; } EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShowOp -- * * Mark one or more nodes to be exposed. Nodes can be specified by their * inode, or by matching a name or data value pattern. By default, the * patterns are matched exactly. They can also be matched using * glob-style and regular expression rules. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int ShowOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (SearchAndApplyToTree(comboPtr, interp, objc, objv, ShowEntryApplyProc, (int *)NULL) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } /* .m style create name option value option value */ static int StyleCreateOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&comboPtr->styleTable, Tcl_GetString(objv[3]), &isNew); if (!isNew) { Tcl_AppendResult(interp, "combomenu style \"", Tcl_GetString(objv[3]), "\" already exists.", (char *)NULL); return TCL_ERROR; } stylePtr = Blt_AssertCalloc(1, sizeof(Style)); stylePtr->name = Blt_GetHashKey(&comboPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; stylePtr->comboPtr = comboPtr; stylePtr->activeRelief = TK_RELIEF_RAISED; Blt_SetHashValue(hPtr, stylePtr); iconsOption.clientData = comboPtr; if (ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, 0) != TCL_OK) { DestroyStyle(stylePtr); return TCL_ERROR; } return TCL_OK; } static int StyleCgetOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconsOption.clientData = comboPtr; return Blt_ConfigureValueFromObj(interp, comboPtr->tkwin, styleSpecs, (char *)stylePtr, objv[4], 0); } static int StyleConfigureOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int result, flags; Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } iconsOption.clientData = comboPtr; flags = BLT_CONFIG_OBJV_ONLY; if (objc == 1) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, styleSpecs, (char *)stylePtr, (Tcl_Obj *)NULL, flags); } else if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, comboPtr->tkwin, styleSpecs, (char *)stylePtr, objv[2], flags); } Tcl_Preserve(stylePtr); result = ConfigureStyle(interp, stylePtr, objc - 4, objv + 4, flags); Tcl_Release(stylePtr); if (result == TCL_ERROR) { return TCL_ERROR; } comboPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); EventuallyRedraw(comboPtr); return TCL_OK; } static int StyleDeleteOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Style *stylePtr; if (GetStyleFromObj(interp, comboPtr, objv[3], &stylePtr) != TCL_OK) { return TCL_ERROR; } if (stylePtr->refCount > 0) { Tcl_AppendResult(interp, "can't destroy combotree style \"", stylePtr->name, "\": style in use.", (char *)NULL); return TCL_ERROR; } DestroyStyle(stylePtr); return TCL_OK; } static int StyleNamesOp( ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&comboPtr->styleTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Style *stylePtr; int found; int i; found = TRUE; stylePtr = Blt_GetHashValue(hPtr); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); found = Tcl_StringMatch(stylePtr->name, pattern); if (found) { break; } } if (found) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(stylePtr->name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static Blt_OpSpec styleOps[] = { {"cget", 2, StyleCgetOp, 5, 5, "name option",}, {"configure", 2, StyleConfigureOp, 4, 0, "name ?option value?...",}, {"create", 2, StyleCreateOp, 4, 0, "name ?option value?...",}, {"delete", 1, StyleDeleteOp, 3, 0, "?name...?",}, {"names", 1, StyleNamesOp, 3, 0, "?pattern...?",}, }; static int nStyleOps = sizeof(styleOps) / sizeof(Blt_OpSpec); static int StyleOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ComboTreeCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nStyleOps, styleOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (comboPtr, interp, objc, objv); return result; } /*ARGSUSED*/ static int ToggleOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Entry *entryPtr; EntryIterator iter; if (GetEntryIterator(interp, comboPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (entryPtr = FirstTaggedEntry(&iter); entryPtr != NULL; entryPtr = NextTaggedEntry(&iter)) { if (entryPtr->flags & ENTRY_CLOSED) { OpenEntry(comboPtr, entryPtr); } else { CloseEntry(comboPtr, entryPtr); } } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * UnpostOp -- * * Unposts this menu. * * .cm unpost * *--------------------------------------------------------------------------- */ static int UnpostOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (!Tk_IsMapped(comboPtr->tkwin)) { return TCL_OK; /* This menu is already unposted. */ } if (Tk_IsMapped(comboPtr->tkwin)) { Tk_UnmapWindow(comboPtr->tkwin); } return TCL_OK; } static int XViewOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int w, worldWidth; w = VPORTWIDTH(comboPtr); worldWidth = comboPtr->worldWidth; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); fract = (double)comboPtr->xOffset / worldWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); fract = (double)(comboPtr->xOffset + w) / worldWidth; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &comboPtr->xOffset, worldWidth, w, comboPtr->xScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= SCROLLX; EventuallyRedraw(comboPtr); return TCL_OK; } static int YViewOp(ComboTree *comboPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int h, worldHeight; h = VPORTHEIGHT(comboPtr); worldHeight = comboPtr->worldHeight; if (objc == 2) { double fract; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* Report first and last fractions */ fract = (double)comboPtr->yOffset / worldHeight; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); fract = (double)(comboPtr->yOffset + h) / worldHeight; fract = FCLAMP(fract); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(fract)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &comboPtr->yOffset, worldHeight, h, comboPtr->yScrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } comboPtr->flags |= SCROLL_PENDING; EventuallyRedraw(comboPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ComboTreeInstCmdProc -- * * This procedure is invoked to process commands on behalf of the * treeview widget. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec comboOps[] = { {"activate", 1, ActivateOp, 3, 3, "entry",}, {"bind", 2, BindOp, 3, 5, "tagName ?sequence command?",}, {"button", 2, ButtonOp, 2, 0, "args",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"close", 2, CloseOp, 2, 4, "?-recurse? entry",}, {"configure", 3, ConfigureOp, 2, 0, "?option value?...",}, {"entry", 2, EntryOp, 2, 0, "oper args",}, {"get", 1, GetOp, 2, 0, "?-full? entry ?entry...?",}, {"hide", 1, HideOp, 2, 0, "?-exact|-glob|-regexp? ?-nonmatching? ?-name string? ?-full string? ?-data string? ?--? ?entry...?",}, {"index", 3, IndexOp, 3, 3, "entry",}, {"invoke", 3, InvokeOp, 3, 3, "entry",}, {"nearest", 1, NearestOp, 4, 5, "x y ?varName?",}, {"open", 1, OpenOp, 2, 4, "?-recurse? entry",}, {"post", 1, PostOp, 4, 5, "x y ?align?",}, {"scan", 2, ScanOp, 5, 5, "dragto|mark x y",}, {"see", 2, SeeOp, 3, 0, "?-anchor anchor? entry",}, {"show", 2, ShowOp, 2, 0, "?-exact? ?-glob? ?-regexp? ?-nonmatching? ?-name string? ?-full string? ?-data string? ?--? ?entry...?",}, {"style", 2, StyleOp, 2, 0, "args",}, {"toggle", 2, ToggleOp, 3, 3, "entry",}, {"unpost", 1, UnpostOp, 2, 2, "",}, {"xview", 1, XViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, {"yview", 1, YViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nComboOps = sizeof(comboOps) / sizeof(Blt_OpSpec); static int ComboTreeInstCmdProc( ClientData clientData, /* Information about the widget. */ Tcl_Interp *interp, /* Interpreter to report errors back to. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Vector of argument strings. */ { ComboTreeCmdProc *proc; ComboTree *comboPtr = clientData; int result; proc = Blt_GetOpFromObj(interp, nComboOps, comboOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } Tcl_Preserve(comboPtr); result = (*proc) (comboPtr, interp, objc, objv); Tcl_Release(comboPtr); return result; } /* *--------------------------------------------------------------------------- * * DisplayComboTree -- * * This procedure is invoked to display the widget. * * Recompute the layout of the text if necessary. This is * necessary if the world coordinate system has changed. * Specifically, the following may have occurred: * * 1. a text attribute has changed (font, linespacing, etc.). * 2. an entry's option changed, possibly resizing the entry. * * This is deferred to the display routine since potentially * many of these may occur. * * Set the vertical and horizontal scrollbars. This is done * here since the window width and height are needed for the * scrollbar calculations. * * Results: * None. * * Side effects: * The widget is redisplayed. * *--------------------------------------------------------------------------- */ static void DisplayComboTree(ClientData clientData) /* Information about widget. */ { ComboTree *comboPtr = clientData; Pixmap drawable; comboPtr->flags &= ~REDRAW_PENDING; if (comboPtr->tkwin == NULL) { return; /* Window has been destroyed. */ } if (comboPtr->rootPtr == NULL) { fprintf(stderr, "no root to tree \n"); return; } if (comboPtr->flags & LAYOUT_PENDING) { /* * Recompute the layout when entries are opened/closed, * inserted/deleted, or when text attributes change (such as * font, linespacing). */ ComputeComboGeometry(comboPtr); } if (comboPtr->flags & (SCROLL_PENDING | DIRTY)) { /* * Scrolling means that the view port has changed and that the * visible entries need to be recomputed. */ ComputeVisibleEntries(comboPtr); if ((comboPtr->flags & SCROLLX) && (comboPtr->xScrollCmdObjPtr!=NULL)) { int w; w = VPORTWIDTH(comboPtr); Blt_UpdateScrollbar(comboPtr->interp, comboPtr->xScrollCmdObjPtr, comboPtr->xOffset, comboPtr->xOffset + w, comboPtr->worldWidth); } if ((comboPtr->flags & SCROLLY) && (comboPtr->yScrollCmdObjPtr!=NULL)) { int h; h = VPORTHEIGHT(comboPtr); Blt_UpdateScrollbar(comboPtr->interp, comboPtr->yScrollCmdObjPtr, comboPtr->yOffset, comboPtr->yOffset + h, comboPtr->worldHeight); } comboPtr->flags &= ~SCROLL_PENDING; } #ifdef notdef if (comboPtr->reqWidth == 0) { /* * The first time through this routine, set the requested * width to the computed width. All we want is to * automatically set the width of the widget, not dynamically * grow/shrink it as attributes change. */ comboPtr->reqWidth = comboPtr->worldWidth + 2 * comboPtr->inset; Tk_GeometryRequest(comboPtr->tkwin, comboPtr->reqWidth, comboPtr->reqHeight); } #endif if (!Tk_IsMapped(comboPtr->tkwin)) { return; } drawable = Tk_GetPixmap(comboPtr->display, Tk_WindowId(comboPtr->tkwin), Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin), Tk_Depth(comboPtr->tkwin)); comboPtr->flags |= VIEWPORT; /* Clear the column background. */ DrawComboTree(comboPtr, drawable); DrawOuterBorders(comboPtr, drawable); /* Now copy the new view to the window. */ XCopyArea(comboPtr->display, drawable, Tk_WindowId(comboPtr->tkwin), comboPtr->lineGC, 0, 0, Tk_Width(comboPtr->tkwin), Tk_Height(comboPtr->tkwin), 0, 0); Tk_FreePixmap(comboPtr->display, drawable); comboPtr->flags &= ~VIEWPORT; } /* *--------------------------------------------------------------------------- * * ComboTreeObjCmdProc -- * * This procedure is invoked to process the TCL command that * corresponds to a widget managed by this module. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ComboTreeObjCmdProc( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { ComboTree *comboPtr; Tcl_CmdInfo cmdInfo; XSetWindowAttributes attrs; unsigned int mask; int result; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } comboPtr = NewComboTree(interp, objv[1]); if (comboPtr == NULL) { goto error; } /* * Source in the initialization script for treeview entries from * "$blt_library/treeview.tcl". We deferred sourcing the file until now * so that the variable $blt_library could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::ComboTree::Initialize", &cmdInfo)) { static char cmd[] = { "source [file join $blt_library combotree.tcl]" }; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); goto error; } } /* * Initialize the widget's configuration options here. The options need to * be set first, so that entry, column, and style components can use them * for their own GCs. */ iconsOption.clientData = comboPtr; if (Blt_ConfigureComponentFromObj(interp, comboPtr->tkwin, "button", "Button", buttonSpecs, 0, (Tcl_Obj **)NULL, (char *)comboPtr, 0) != TCL_OK) { goto error; } /* * Rebuild the widget's GC and other resources that are predicated by the * widget's configuration options. Do the same for the default column. */ if (ConfigureComboTree(interp, comboPtr, objc - 2, objv + 2, 0) != TCL_OK) { goto error; } /* * Invoke a procedure to initialize various bindings on treeview entries. */ { Tcl_Obj *cmd[2]; cmd[0] = Tcl_NewStringObj("::blt::ComboTree::Initialize", -1); cmd[1] = objv[1]; Tcl_IncrRefCount(cmd[0]); Tcl_IncrRefCount(cmd[1]); result = Tcl_EvalObjv(interp, 2, cmd, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmd[1]); Tcl_DecrRefCount(cmd[0]); if (result != TCL_OK) { goto error; } } attrs.override_redirect = True; attrs.backing_store = WhenMapped; attrs.save_under = True; mask = (CWOverrideRedirect | CWSaveUnder | CWBackingStore); Tk_ChangeWindowAttributes(comboPtr->tkwin, mask, &attrs); Tk_MakeWindowExist(comboPtr->tkwin); Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(comboPtr->tkwin),-1); return TCL_OK; error: if (comboPtr != NULL) { Tk_DestroyWindow(comboPtr->tkwin); } return TCL_ERROR; } int Blt_ComboTreeInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "combotree", ComboTreeObjCmdProc, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_COMBOTREE */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixWindow.c���������������������������������������������������������������0000644�0001750�0001750�00000032520�11462120063�016011� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixWindow.c -- * * This module implements additional window functionality for the BLT * toolkit, such as transparent Tk windows, and reparenting Tk * windows. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <X11/Xlib.h> #ifndef WIN32 #include <X11/Xproto.h> #endif #include "tkDisplay.h" /* *--------------------------------------------------------------------------- * * DoConfigureNotify -- * * Generate a ConfigureNotify event describing the current * configuration of a window. * * Results: * None. * * Side effects: * An event is generated and processed by Tk_HandleEvent. * *--------------------------------------------------------------------------- */ static void DoConfigureNotify(Tk_FakeWin *winPtr) { XEvent event; event.type = ConfigureNotify; event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); event.xconfigure.send_event = False; event.xconfigure.display = winPtr->display; event.xconfigure.event = winPtr->window; event.xconfigure.window = winPtr->window; event.xconfigure.x = winPtr->changes.x; event.xconfigure.y = winPtr->changes.y; event.xconfigure.width = winPtr->changes.width; event.xconfigure.height = winPtr->changes.height; event.xconfigure.border_width = winPtr->changes.border_width; if (winPtr->changes.stack_mode == Above) { event.xconfigure.above = winPtr->changes.sibling; } else { event.xconfigure.above = None; } event.xconfigure.override_redirect = winPtr->atts.override_redirect; Tk_HandleEvent(&event); } /* *--------------------------------------------------------------------------- * * Blt_MakeTransparentWindowExist -- * * Similar to Tk_MakeWindowExist but instead creates a * transparent window to block for user events from sibling * windows. * * Differences from Tk_MakeWindowExist. * * 1. This is always a "busy" window. There's never a * platform-specific class procedure to execute instead. * 2. The window is transparent and never will contain children, * so colormap information is irrelevant. * * Results: * None. * * Side effects: * When the procedure returns, the internal window associated * with tkwin is guaranteed to exist. This may require the * window's ancestors to be created too. * *--------------------------------------------------------------------------- */ void Blt_MakeTransparentWindowExist(Tk_Window tkwin, Window parent, int isBusy) { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *winPtr2; Tcl_HashEntry *hPtr; int notUsed; TkDisplay *dispPtr; long int mask; if (winPtr->window != None) { return; /* Window already exists. */ } /* Create a transparent window and put it on top. */ mask = (!isBusy) ? 0 : (CWDontPropagate | CWEventMask); /* Ignore the important events while the window is mapped. */ #define USER_EVENTS (EnterWindowMask | LeaveWindowMask | KeyPressMask | \ KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ PointerMotionMask) #define PROP_EVENTS (KeyPressMask | KeyReleaseMask | ButtonPressMask | \ ButtonReleaseMask | PointerMotionMask) winPtr->atts.do_not_propagate_mask = PROP_EVENTS; winPtr->atts.event_mask = USER_EVENTS; winPtr->changes.border_width = 0; winPtr->depth = 0; winPtr->window = XCreateWindow(winPtr->display, parent, winPtr->changes.x, winPtr->changes.y, (unsigned)winPtr->changes.width, /* width */ (unsigned)winPtr->changes.height, /* height */ (unsigned)winPtr->changes.border_width, /* border_width */ winPtr->depth, /* depth */ InputOnly, /* class */ winPtr->visual, /* visual */ mask, /* valuemask */ &winPtr->atts /* attributes */ ); dispPtr = winPtr->dispPtr; hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *)winPtr->window, &notUsed); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; #ifdef TK_USE_INPUT_METHODS winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (!(winPtr->flags & TK_TOP_LEVEL)) { /* * If any siblings higher up in the stacking order have already * been created then move this window to its rightful position * in the stacking order. * * NOTE: this code ignores any changes anyone might have made * to the sibling and stack_mode field of the window's attributes, * so it really isn't safe for these to be manipulated except * by calling Tk_RestackWindow. */ for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; winPtr2 = winPtr2->nextPtr) { if ((winPtr2->window != None) && !(winPtr2->flags & TK_TOP_LEVEL)) { XWindowChanges changes; changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, CWSibling | CWStackMode, &changes); break; } } } /* * Issue a ConfigureNotify event if there were deferred configuration * changes (but skip it if the window is being deleted; the * ConfigureNotify event could cause problems if we're being called * from Tk_DestroyWindow under some conditions). */ if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) && !(winPtr->flags & TK_ALREADY_DEAD)) { winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; DoConfigureNotify((Tk_FakeWin *) tkwin); } } Window Blt_GetParentWindow(Display *display, Window window) { Window root, parent; Window *dummy; unsigned int count; if (XQueryTree(display, window, &root, &parent, &dummy, &count) > 0) { XFree(dummy); return parent; } return None; } /* *--------------------------------------------------------------------------- * * Blt_GetWindowId -- * * Returns the XID for the Tk_Window given. Starting in Tk 8.0, * the toplevel widgets are wrapped by another window. Currently * there's no way to get at that window, other than what is done * here: query the X window hierarchy and retrieve the parent. * * Results: * Returns the X Window ID of the widget. If it's a toplevel, then * the XID of the wrapper is returned. * *--------------------------------------------------------------------------- */ Window Blt_GetWindowId(Tk_Window tkwin) { Window window; Tk_MakeWindowExist(tkwin); window = Tk_WindowId(tkwin); if (Tk_IsTopLevel(tkwin)) { Window parent; parent = Blt_GetParentWindow(Tk_Display(tkwin), window); if (parent != None) { window = parent; } window = parent; } return window; } /* *--------------------------------------------------------------------------- * * XGeometryErrorProc -- * * Flags errors generated from XGetGeometry calls to the X server. * * Results: * Always returns 0. * * Side Effects: * Sets a flag, indicating an error occurred. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int XGeometryErrorProc(ClientData clientData, XErrorEvent *errEventPtr) { int *errorPtr = clientData; *errorPtr = FALSE; return 0; } int Blt_GetWindowRegion(Display *display, Window window, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr) { Tk_ErrorHandler handler; Window root; int any = -1; int result; int x, y; unsigned int w, h, bw, depth; handler = Tk_CreateErrorHandler(display, any, X_GetGeometry, any, XGeometryErrorProc, &result); result = XGetGeometry(display, window, &root, &x, &y, &w, &h, &bw, &depth); if (!result) { goto error; } if (widthPtr != NULL) { *widthPtr = (int)w; } if (heightPtr != NULL) { *heightPtr = (int)h; } if ((xPtr != NULL) || (yPtr != NULL)) { int rootX, rootY; rootX = rootY = 0; do { Window *children, parent; unsigned int n; parent = -1; fprintf(stderr, "before geomtry window=%x, root=%x parent=%x\n", window, root, parent); result = XGetGeometry(display, window, &root, &x, &y, &w, &h, &bw, &depth); if (!result) { goto error; } rootX += x + bw; rootY += y + bw; fprintf(stderr, "before window=%x, root=%x parent=%x\n", window, root, parent); result = XQueryTree(display, window, &root, &parent, &children, &n); fprintf(stderr, "after window=%x, root=%x parent=%x\n", window, root, parent); XFree(children); if (!result) { goto error; } window = parent; } while (window != root); if (xPtr != NULL) { *xPtr = rootX; } if (yPtr != NULL) { *yPtr = rootY; } } Tk_DeleteErrorHandler(handler); XSync(display, False); return TCL_OK; error: Tk_DeleteErrorHandler(handler); XSync(display, False); fprintf(stderr, "failed to get window region\n"); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * Blt_RaiseToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_RaiseToplevelWindow(Tk_Window tkwin) { XRaiseWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_LowerToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_LowerToplevelWindow(Tk_Window tkwin) { XLowerWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_ResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_ResizeToplevelWindow(Tk_Window tkwin, int width, int height) { XResizeWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), width, height); } /* *--------------------------------------------------------------------------- * * Blt_MoveResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MoveResizeToplevelWindow(Tk_Window tkwin, int x, int y, int w, int h) { XMoveResizeWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), x, y, w, h); } /* *--------------------------------------------------------------------------- * * Blt_ResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MoveToplevelWindow(Tk_Window tkwin, int x, int y) { XMoveWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), x, y); } /* *--------------------------------------------------------------------------- * * Blt_MapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MapToplevelWindow(Tk_Window tkwin) { XMapWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_UnmapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_UnmapToplevelWindow(Tk_Window tkwin) { XUnmapWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* ARGSUSED */ static int XReparentWindowErrorProc(ClientData clientData, XErrorEvent *errEventPtr) { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } int Blt_ReparentWindow( Display *display, Window window, Window newParent, int x, int y) { Tk_ErrorHandler handler; int result; int any = -1; result = TCL_OK; handler = Tk_CreateErrorHandler(display, any, X_ReparentWindow, any, XReparentWindowErrorProc, &result); XReparentWindow(display, window, newParent, x, y); Tk_DeleteErrorHandler(handler); XSync(display, False); return result; } int Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr) { const char *string; string = Tcl_GetString(objPtr); if (string[0] == '.') { Tk_Window tkwin; tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } *windowPtr = (Tk_IsTopLevel(tkwin)) ? Blt_GetWindowId(tkwin) : Tk_WindowId(tkwin); } else if (strcmp(string, "root") == 0) { *windowPtr = Tk_RootWindow(Tk_MainWindow(interp)); } else { int id; if (Tcl_GetIntFromObj(interp, objPtr, &id) != TCL_OK) { return TCL_ERROR; } *windowPtr = (Window)id; } return TCL_OK; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPaintDraw.c����������������������������������������������������������������0000644�0001750�0001750�00000106557�11462120062�015602� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #ifdef notdef typedef struct { int type; union { Blt_Gradient *gradientPtr; Blt_Picture picture; /* Picture used to tile background. */ } background; Blt_Pixel color1, color2; /* Gradient colors. */ } Paint; #endif typedef struct { int left, right; } ScanLine; static ScanLine * MakeScanLines(size_t nLines) { ScanLine *coords; int i; coords = Blt_AssertMalloc(sizeof(ScanLine) * nLines); for(i = 0; i < nLines; i++) { coords[i].left = INT_MAX; coords[i].right = -INT_MAX; } return coords; } static void AddEllipseCoord(ScanLine *coords, int x, int y) { if (x < coords[y].left) { coords[y].left = x; } if (x > coords[y].right) { coords[y].right = x; } } static ScanLine * ComputeEllipseQuadrant(int a, int b) { ScanLine *coords; double t; int dx, dy; double a2, b2; double p, px, py; a2 = a * a; b2 = b * b; dx = 0; dy = b; px = 0; /* b2 * (dx + 1) */ py = (double)(a2 + a2) * dy; /* a2 * (dy - 0.5) */ coords = MakeScanLines(b + 1); if (coords == NULL) { return NULL; } AddEllipseCoord(coords, dx, dy); t = (b2 - (a2 * b) + (0.25 * a2)); p = (int)ROUND(t); while (py > px) { dx++; px += b2 + b2; if (dy <= 0) { continue; } if (p < 0) { p += b2 + px; } else { dy--; py -= a2 + a2; p += b2 + px - py; } AddEllipseCoord(coords, dx, dy); } { double dx2, dy2; dx2 = (dx + 0.5) * (dx + 0.5); dy2 = (dy - 1) * (dy - 1); t = (b2 * dx2 + a2 * dy2 - (a2 * b2)); p = (int)ROUND(t); } while (dy > 0) { dy--; py -= a2 + a2; if (p > 0) { p += a2 - py; } else { dx++; px += b2 + b2; p += a2 - py + px; } AddEllipseCoord(coords, dx, dy); } AddEllipseCoord(coords, dx, dy); return coords; } static INLINE void MixColors(Blt_Pixel *bp, Blt_Pixel *colorPtr) { if ((bp->Alpha == 0x00) || (colorPtr->Alpha == 0xFF)) { bp->u32 = colorPtr->u32; } else if (colorPtr->Alpha != 0x00) { unsigned char beta; int a, r, g, b, t; /* beta = 1 - alpha */ beta = colorPtr->Alpha ^ 0xFF; r = colorPtr->Red + imul8x8(beta, bp->Red, t); g = colorPtr->Green + imul8x8(beta, bp->Green, t); b = colorPtr->Blue + imul8x8(beta, bp->Blue, t); a = colorPtr->Alpha + imul8x8(beta, bp->Alpha, t); bp->Red = (r > 255) ? 255 : ((r < 0) ? 0 : r); bp->Green = (g > 255) ? 255 : ((g < 0) ? 0 : g); bp->Blue = (b > 255) ? 255 : ((b < 0) ? 0 : b); bp->Alpha = 0xFF; } } static void INLINE PaintPixel(Pict *destPtr, int x, int y, Blt_Pixel *colorPtr) { if ((x >= 0) && (x < destPtr->width) && (y >= 0) && (y < destPtr->height)) { MixColors(Blt_PicturePixel(destPtr, x, y), colorPtr); } } static void INLINE FillHorizontalLine(Pict *destPtr, int x1, int x2, int y, Blt_Pixel *colorPtr, int blend) { if ((y >= 0) && (y < destPtr->height)) { Blt_Pixel *dp, *dend; if (x1 > x2) { int tmp; tmp = x1, x1 = x2, x2 = tmp; } x1 = MAX(x1, 0); x2 = MIN(x2, destPtr->width - 1); dp = destPtr->bits + (y * destPtr->pixelsPerRow) + x1; dend = destPtr->bits + (y * destPtr->pixelsPerRow) + x2; if (blend) { for (/*empty*/; dp <= dend; dp++) { MixColors(dp, colorPtr); } } else { for (/*empty*/; dp < dend; dp++) { dp->u32 = colorPtr->u32; } } } } static void INLINE FillVerticalLine(Pict *destPtr, int x, int y1, int y2, Blt_Pixel *colorPtr, int blend) { if ((x >= 0) && (x < destPtr->width)) { Blt_Pixel *dp, *dend; if (y1 > y2) { int tmp; tmp = y1, y1 = y2, y2 = tmp; } y1 = MAX(y1, 0); y2 = MIN(y2, destPtr->height - 1); dp = destPtr->bits + (y1 * destPtr->pixelsPerRow) + x; dend = destPtr->bits + (y2 * destPtr->pixelsPerRow) + x; if (blend) { for (/*empty*/; dp <= dend; dp += destPtr->pixelsPerRow) { MixColors(dp, colorPtr); } } else { for (/*empty*/; dp <= dend; dp += destPtr->pixelsPerRow) { dp->u32 = colorPtr->u32; } } } } static void PaintThickRoundedRectangle( Blt_Picture picture, int xOrigin, int yOrigin, /* Upper left corner of rectangle. */ int w, int h, int r, int lineWidth, Blt_Pixel *colorPtr) { Blt_Pixel fill, edge; int x1, x2, y1, y2; int blend = 1; fill = PremultiplyAlpha(colorPtr, 255); edge.u32 = 0xFF000000; { int d; d = MIN(w, h) / 2; if (r > d) { r = d; } if ((r > 0) && (r < lineWidth)) { r = lineWidth; } } #ifdef notdef fprintf(stderr, "Paint Thick Rounded Rectangle\n"); #endif /* Compute the coordinates of the four corner radii. */ x1 = xOrigin + r; y1 = yOrigin + r; x2 = xOrigin + w - r - 1; y2 = yOrigin + h - r - 1; if (lineWidth > r) { int left, right; int dy; /* Draw the extra width (not including the radius). */ left = xOrigin; right = xOrigin + w - 1; for (dy = 0; dy < (lineWidth - r); dy++) { FillHorizontalLine(picture, left, right, y1 + dy, &fill, blend); FillHorizontalLine(picture, left, right, y2 - dy, &fill, blend); } } { int y; int left, right, midleft, midright, midtop, midbottom; int mid; left = xOrigin; midleft = xOrigin + (lineWidth - 1); right = xOrigin + w - 1; midright = right - (lineWidth - 1); mid = MAX(r, lineWidth - 1); /* Draw the left/right edges of the interior rectangle */ if (lineWidth > r) { midtop = yOrigin + mid + 1; midbottom = yOrigin + h - mid - 1; } else { midtop = yOrigin + mid; midbottom = yOrigin + h - mid; } for (y = midtop; y < midbottom; y++) { FillHorizontalLine(picture, left, midleft, y, &fill, blend); FillHorizontalLine(picture, midright, right, y, &fill, blend); } } if (r > 0) { ScanLine *outer, *inner; int dy; int dx1, dx2; lineWidth--; outer = ComputeEllipseQuadrant(r, r); inner = ComputeEllipseQuadrant(r - lineWidth, r - lineWidth); dy = 1; if (lineWidth <= r) { /* Draw the bend from the left/right edge to each radius. */ for (dy = 1; dy < (r - lineWidth); dy++) { dx1 = outer[dy].right, dx2 = inner[dy].left; FillHorizontalLine(picture, x1-dx1, x1-dx2, y1-dy, &fill,blend); FillHorizontalLine(picture, x2+dx2, x2+dx1, y1-dy, &fill,blend); FillHorizontalLine(picture, x1-dx1, x1-dx2, y2+dy, &fill,blend); FillHorizontalLine(picture, x2+dx2, x2+dx1, y2+dy, &fill,blend); } } /* Draw the top/bottom bend from the line width to the radius */ for (/* empty */; dy <= r; dy++) { int dx; dx = outer[dy].right; #ifdef notdef fprintf(stderr, "r=%d, dx=%d w=%d x1=%d x2=%d\n", r, dx, w, x1, x2); fprintf(stderr, "x0=%d\n", xOrigin); #endif FillHorizontalLine(picture, x1 - dx, x2 + dx, y1 - dy, &fill,blend); FillHorizontalLine(picture, x1 - dx, x2 + dx, y2 + dy, &fill,blend); } Blt_Free(outer); Blt_Free(inner); } } static void PaintRoundedRectangle( Blt_Picture picture, int xOrigin, int yOrigin, int width, int height, int r, Blt_Pixel *colorPtr) { Blt_Pixel fill; int x1, x2, y1, y2; /* Centers of each corner */ int blend = 1; { int w2, h2; /* Radius of each rounded corner can't be bigger than half the width * or height of the rectangle. */ w2 = width / 2; h2 = height / 2; if (r > w2) { r = w2; } if (r > h2) { r = h2; } } x1 = xOrigin + r; y1 = yOrigin + r; x2 = xOrigin + width - r - 1; y2 = yOrigin + height - r - 1; fill = PremultiplyAlpha(colorPtr, 255); { /* Rectangular interior. */ int left, right; int y; left = xOrigin; right = xOrigin + width - 1; for (y = y1; y <= y2; y++) { FillHorizontalLine(picture, left, right, y, &fill, blend); } } if (r > 0) { ScanLine *outer; int dy; outer = ComputeEllipseQuadrant(r, r); for (dy = 1; dy <= r; dy++) { int dx; dx = outer[dy].right; FillHorizontalLine(picture, x1 - dx, x2 + dx, y1 - dy, &fill, blend); FillHorizontalLine(picture, x1 - dx, x2 + dx, y2 + dy, &fill, blend); } Blt_Free(outer); } } #ifdef notdef static Pict * FilledCircle(int diam, Blt_Pixel *colorPtr) { Pict *destPtr; Blt_Pixel edge, interior; double t; int r, r2; int x, y; int y1, y2; diam |= 0x01; r = diam / 2; r2 = r * r; destPtr = Blt_CreatePicture(diam, diam); t = 0.0; x = r; interior = PremultiplyAlpha(color, 255); HorizLine(destPtr, x - r, x + r, r, interior); /* Center line */ y = 0; while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(color, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, r - x - 1, r + y, edge); HorizLine(destPtr, r - x, r + x, r + y, interior); PutPixel(destPtr, r + x + 1, r + y, edge); PutPixel(destPtr, r - x - 1, r - y, edge); HorizLine(destPtr, r - x, r + x, r - y, interior); PutPixel(destPtr, r + x + 1, r - y, edge); t = d; } y1 = r - y; y2 = r + y; x = 0; y = r; t = 0; VertLine(destPtr, r, 0, y1, interior); /* Center line */ VertLine(destPtr, r, y2, r + r, interior); /* Center line */ while (y > x) { double z; double d, q; x++; z = sqrt(r2 - (x * x)); d = floor(z) - z; if (d < t) { y--; } q = FABS(d * 255.0); edge = PremultiplyAlpha(color, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, r - x, r - y - 1, edge); VertLine(destPtr, r - x, r - y, y1, interior); VertLine(destPtr, r - x, y2, r + y, interior); PutPixel(destPtr, r - x, r + y + 1, edge); PutPixel(destPtr, r + x, r - y - 1, edge); VertLine(destPtr, r + x, r - y, y1, interior); VertLine(destPtr, r + x, y2, r + y, interior); PutPixel(destPtr, r + x, r + y + 1, edge); t = d; } return destPtr; } static Pict * FilledOval(int width, int height, Color color) { Pict *destPtr; Color edge, interior; double t; int r, r2; int x, y; int diam, offset; int x1, x2, y1, y2; t = 0.0; interior = PremultiplyAlpha(color, 255); if (width < height) { diam = width; diam |= 0x1; r = diam / 2; r2 = r * r; width = diam; offset = height - width; destPtr = Blt_CreatePicture(width, height); /* Fill the center rectangle */ y1 = r, y2 = height - r - 1; for (y = y1; y <= y2; y++) { HorizLine(destPtr, 0, width - 1, y, interior); } x1 = x2 = r; } else { diam = height; diam |= 0x1; r = diam / 2; r2 = r * r; height = diam; offset = width - height; destPtr = Blt_CreatePicture(width, height); y1 = y2 = r; x1 = r, x2 = width - r - 1; HorizLine(destPtr, 0, width - 1, r, interior); /* Center line */ for (y = 0; y < y1; y++) { HorizLine(destPtr, x1, x2, y, interior); } for (y = y2; y < height; y++) { HorizLine(destPtr, x1, x2, y, interior); } } y = 0; x = r; while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(color, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, x1 - x - 1, y2 + y, edge); HorizLine(destPtr, x1 - x, x2 + x, y2 + y, interior); PutPixel(destPtr, x2 + x + 1, y2 + y, edge); PutPixel(destPtr, x1 - x - 1, y1 - y, edge); HorizLine(destPtr, x1 - x, x2 + x, y1 - y, interior); PutPixel(destPtr, x2 + x + 1, y1 - y, edge); t = d; } x = 0; y = r; t = 0; VertLine(destPtr, r, 0, y1, interior); /* Center line */ VertLine(destPtr, r, y2, height - 1, interior); /* Center line */ while (y > x) { double z; double d, q; x++; z = sqrt(r2 - (x * x)); d = floor(z) - z; if (d < t) { y--; } q = FABS(d * 255.0); edge = PremultiplyAlpha(color, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, x1 - x, y1 - y - 1, edge); VertLine(destPtr, x1 - x, y1 - y, y1, interior); VertLine(destPtr, x1 - x, y2, y2 + y, interior); PutPixel(destPtr, x1 - x, y2 + y + 1, edge); PutPixel(destPtr, x2 + x, y1 - y - 1, edge); VertLine(destPtr, x2 + x, y1 - y, y1, interior); VertLine(destPtr, x2 + x, y2, y2 + y, interior); PutPixel(destPtr, x2 + x, y2 + y + 1, edge); t = d; } return destPtr; } #endif static void PaintCircle3(Blt_Picture src, int x, int y, int r, Blt_Pixel *colorPtr) { Blt_Pixel edge, interior; double t; int r2; int y1, y2; r2 = r * r; t = 0.0; x = r; interior.u32 = edge.u32 = colorPtr->u32; /* Center line */ PutPixel(src, r - x, r, &edge); PutPixel(src, r + x, r, &edge); y = 0; while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } q = FABS(d * 255.0); a = (unsigned char)CLAMP(q); edge.Alpha = a; interior.Alpha = ~a; /* By symmetry we can fill upper and lower scan lines. */ PaintPixel(src, r - x - 1, r + y, &interior); PaintPixel(src, r + x + 1, r + y, &edge); PaintPixel(src, r - x - 1, r - y, &edge); PaintPixel(src, r + x + 1, r - y, &interior); t = d; } y1 = r - y; y2 = r + y; x = 0; y = r; t = 0; interior.u32 = edge.u32 = colorPtr->u32; VertLine(src, r, 0, y1, &edge); /* Center line */ VertLine(src, r, y2, r + r, &edge); while (y > x) { unsigned char a; double z; double d, q; x++; z = sqrt(r2 - (x * x)); d = floor(z) - z; if (d < t) { y--; } q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge.Alpha = a; interior.Alpha = ~a; /* By symmetry we can fill upper and lower scan lines. */ PaintPixel(src, r - x, r - y - 1, &edge); PaintPixel(src, r - x, r + y + 1, &interior); PaintPixel(src, r + x, r - y - 1, &interior); PaintPixel(src, r + x, r + y + 1, &edge); t = d; } } static INLINE float sqr(float x) { return x * x; } static void PaintCircle4(Pict *srcPtr, int x, int y, int r, Blt_Pixel *colorPtr) { int cx, cy; int x1, x2, y1, y2; int Fact; float RPF2, RMF2; float sqY, sqDist; float *sqX; float feather = 4.0; Blt_Pixel *srcRowPtr; cx = x, cy = y; // Determine some helpful values (singles) RPF2 = sqr(r + feather/2); RMF2 = sqr(r - feather/2); // Determine bounds: x1 = MAX(floor(cx - RPF2), 0); x2 = MIN(ceil (cx + RPF2), srcPtr->width - 1); y1 = MAX(floor(cy - RPF2), 0); y2 = MIN(ceil (cy + RPF2), srcPtr->height - 1); // Optimization run: find squares of X first sqX = Blt_AssertMalloc(sizeof(float) * (x2 - x1 + 1)); for (x = x1; x <= x2; x++) { sqX[x - x1] = sqr(x - cx); } // Loop through Y values srcRowPtr = srcPtr->bits + (y1 * srcPtr->pixelsPerRow) + x1; for (y = y1; y <= y2; y++) { Blt_Pixel *sp; sqY = sqr(y - cy); // Loop through X values sp = srcRowPtr; for (x = x1; x <= x2; x++, sp++) { // determine squared distance from center for this pixel sqDist = sqY + sqX[x - x1]; // inside inner circle? Most often.. if (sqDist < RMF2) { // inside the inner circle.. just give the scanline the // new color sp->u32 = colorPtr->u32; } else if (sqDist < RPF2) { // inside outer circle? unsigned int a; // We are inbetween the inner and outer bound, now // mix the color Fact = ROUND(((r - sqrt(sqDist)) * 2 / feather)*127.5 + 127.5); // just in case limit to [0, 255] a = MAX(0, MIN(Fact, 255)); #ifndef notdef BlendPixel(sp, colorPtr, a); #else sp->u32 = colorPtr->u32; sp->Alpha = a; #endif } else { /* do nothing */ } } srcRowPtr += srcPtr->pixelsPerRow; } srcPtr->flags &= ~BLT_PIC_ASSOCIATED_COLORS; Blt_Free(sqX); } static Pict * xFilledCircle(int diam, Blt_Pixel *colorPtr) { Pict *destPtr; Blt_Pixel edge, interior; double t; int r, r2; int x, y; int y1, y2; diam |= 0x01; r = diam / 2; r2 = r * r; destPtr = Blt_CreatePicture(diam, diam); t = 0.0; x = r; interior = PremultiplyAlpha(colorPtr, 255); HorizLine(destPtr, x - r, x + r, r, &interior); /* Center line */ y = 0; while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(colorPtr, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, r - x - 1, r + y, &edge); HorizLine(destPtr, r - x, r + x, r + y, &interior); PutPixel(destPtr, r + x + 1, r + y, &edge); PutPixel(destPtr, r - x - 1, r - y, &edge); HorizLine(destPtr, r - x, r + x, r - y, &interior); PutPixel(destPtr, r + x + 1, r - y, &edge); t = d; } y1 = r - y; y2 = r + y; x = 0; y = r; t = 0; VertLine(destPtr, r, 0, y1, &interior); /* Center line */ VertLine(destPtr, r, y2, r + r, &interior); /* Center line */ while (y > x) { double z; double d, q; x++; z = sqrt(r2 - (x * x)); d = floor(z) - z; if (d < t) { y--; } q = FABS(d * 255.0); edge = PremultiplyAlpha(colorPtr, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PutPixel(destPtr, r - x, r - y - 1, &edge); VertLine(destPtr, r - x, r - y, y1, &interior); VertLine(destPtr, r - x, y2, r + y, &interior); PutPixel(destPtr, r - x, r + y + 1, &edge); PutPixel(destPtr, r + x, r - y - 1, &edge); VertLine(destPtr, r + x, r - y, y1, &interior); VertLine(destPtr, r + x, y2, r + y, &interior); PutPixel(destPtr, r + x, r + y + 1, &edge); t = d; } return destPtr; } static void FilledOval(Pict *destPtr, int destX, int destY, int ovalWidth, int ovalHeight, Blt_Pixel *colorPtr) { Blt_Pixel edge, interior; double t; int r, r2; int x, y; int diam, offset; int x1, x2, y1, y2; int blend = 1; t = 0.0; interior = PremultiplyAlpha(colorPtr, 255); if (ovalWidth < ovalHeight) { diam = ovalWidth; diam |= 0x1; r = diam / 2; r2 = r * r; ovalWidth = diam; offset = ovalHeight - ovalWidth; /* Fill the center rectangle */ x1 = destX; x2 = destX + ovalWidth - 1; y1 = destY + r; y2 = destY + ovalHeight - r - 1; for (y = y1; y <= y2; y++) { FillHorizontalLine(destPtr, x1, x2, y, &interior, blend); } x1 = x2 = r; } else if (ovalWidth > ovalHeight) { diam = ovalHeight; diam |= 0x1; r = diam / 2; r2 = r * r; ovalHeight = diam; offset = ovalWidth - ovalHeight; y1 = y2 = destY + r; x1 = destX + r, x2 = destY + ovalWidth - r - 1; FillHorizontalLine(destPtr, destX, destX + ovalWidth - 1, y1, &interior, blend); for (y = destY; y < y1; y++) { FillHorizontalLine(destPtr, x1, x2, y, &interior, blend); } for (y = y2; y < destY + ovalHeight; y++) { FillHorizontalLine(destPtr, x1, x2, y, &interior, blend); } } else { diam = ovalWidth; diam |= 0x1; ovalHeight = ovalWidth = diam; r = diam / 2; r2 = r * r; /* Fill the center rectangle */ x1 = destX; x2 = destX + ovalWidth - 1; y1 = destY + r; y2 = destY + ovalHeight - r - 1; } y = 0; x = r; while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(colorPtr, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PaintPixel(destPtr, x1 - x - 1, y2 + y, &edge); FillHorizontalLine(destPtr, x1 - x, x2 + x, y2 + y, &interior, blend); PaintPixel(destPtr, x2 + x + 1, y2 + y, &edge); PaintPixel(destPtr, x1 - x - 1, y1 - y, &edge); FillHorizontalLine(destPtr, x1 - x, x2 + x, y1 - y, &interior, blend); PaintPixel(destPtr, x2 + x + 1, y1 - y, &edge); t = d; } x = 0; y = r; t = 0; FillVerticalLine(destPtr, destX + r, destY, y1, &interior, blend); FillVerticalLine(destPtr, destX + r, y2, destY + ovalHeight - 1, &interior, blend); while (y > x) { double z; double d, q; x++; z = sqrt(r2 - (x * x)); d = floor(z) - z; if (d < t) { y--; } q = FABS(d * 255.0); edge = PremultiplyAlpha(colorPtr, (unsigned int)CLAMP(q)); /* By symmetry we can fill upper and lower scan lines. */ PaintPixel(destPtr, x1 - x, y1 - y - 1, &edge); FillVerticalLine(destPtr, x1 - x, y1 - y, y1, &interior, blend); FillVerticalLine(destPtr, x1 - x, y2, y2 + y, &interior, blend); PaintPixel(destPtr, x1 - x, y2 + y + 1, &edge); PaintPixel(destPtr, x2 + x, y1 - y - 1, &edge); FillVerticalLine(destPtr, x2 + x, y1 - y, y1, &interior, blend); FillVerticalLine(destPtr, x2 + x, y2, y2 + y, &interior, blend); PaintPixel(destPtr, x2 + x, y2 + y + 1, &edge); t = d; } } static void PaintArc(Pict *destPtr, int x1, int y1, int x2, int y2, int lineWidth, Blt_Pixel *colorPtr) { Blt_Pixel *dp; double t; int r2; int radius; int dx, dy; int x, y; int xoff, yoff; int fill = 1; t = 0.0; dx = x2 - x1; dy = y2 - y1; radius = MIN(dx, dy) / 2; xoff = x1; yoff = y1; x = radius; y = 0; dp = Blt_PicturePixel(destPtr, x + xoff - 1, y + yoff); dp->u32 = colorPtr->u32; r2 = radius * radius; if (fill) { PaintLineSegment(destPtr, x1, y + yoff, x + xoff - 2, y + yoff, 1, colorPtr); } while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } dp = Blt_PicturePixel(destPtr, x + xoff, y + yoff); q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); BlendPixel(dp, colorPtr, a); dp--; /* x - 1 */ a = (unsigned int)CLAMP(255.0 - q); BlendPixel(dp, colorPtr, a); t = d; x1++; if (fill) { PaintLineSegment(destPtr, x1, y + yoff, x + xoff - 1, y + yoff, 1, colorPtr); } } } static void PaintFilledCircle(Pict *destPtr, int x, int y, int r, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; Blt_Pixel fill; int dy, d2; int inner, outer; int count; count = 0; inner = (r - 1) * (r - 1); outer = (r + 1) * (r + 1); fill = PremultiplyAlpha(colorPtr, 255); destRowPtr = destPtr->bits + ((y - r) * destPtr->pixelsPerRow) + (x - r); for (y = -r; y <= r; y++) { Blt_Pixel *dp, *dend; int dy2; dy2 = y * y; for (dp = destRowPtr, dend = dp + destPtr->width, x = -r; (x <= r) && (dp < dend); x++, dp++) { double d, z; int d2; d2 = dy2 + x * x; if (d2 > outer) { continue; } if (d2 < inner) { MixColors(dp, &fill); /* Interior */ continue; } z = (double)r - sqrt((double)d2); count++; if (z > 1.0) { MixColors(dp, &fill); /* Interior */ } else if (z > 0.0) { double q; unsigned char a; Blt_Pixel edge; q = z * 255.0; a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(colorPtr, a); MixColors(dp, &edge); /* Edge */ } } destRowPtr += destPtr->pixelsPerRow; } #ifdef notdef fprintf(stderr, "%d pixels %d sqrts\n", (r + r + 1) * (r + r + 1), count); #endif } static void PaintThinCircle(Pict *destPtr, int x, int y, int r, Blt_Pixel *colorPtr) { Blt_Pixel edge, fill; double r2; double t; int dx, dy; fill = PremultiplyAlpha(colorPtr, 255); PaintPixel(destPtr, x, y + r - 1, &fill); PaintPixel(destPtr, x, y - r + 1, &fill); PaintPixel(destPtr, x + r - 1, y, &fill); PaintPixel(destPtr, x - r + 1, y, &fill); r2 = r * r; dx = r, dy = 0; t = 0.0; while (dx > dy) { double z; double dist; double d, q; unsigned char a; dy++; z = sqrt(r2 - (dy * dy)); d = floor(z) - z; if (d < t) { dx--; } dist = sqrt((dx * dx) + (dy * dy)); q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); edge = PremultiplyAlpha(colorPtr, a); fill = PremultiplyAlpha(colorPtr, ~a); /* By symmetry we can add pixels in 4 octants. */ PaintPixel(destPtr, x + dx, y + dy, &edge); PaintPixel(destPtr, x + dx - 1, y + dy, &fill); PaintPixel(destPtr, x + dx, y - dy, &edge); PaintPixel(destPtr, x + dx - 1, y - dy, &fill); PaintPixel(destPtr, x - dx, y + dy, &edge); PaintPixel(destPtr, x - dx + 1, y + dy, &fill); PaintPixel(destPtr, x - dx, y - dy, &edge); PaintPixel(destPtr, x - dx + 1, y - dy, &fill); t = d; } dx = 0, dy = r; t = 0.0; while (dy > dx) { double z; double d, q; unsigned char a; dx++; z = sqrt(r2 - (dx * dx)); d = floor(z) - z; if (d < t) { dy--; } q = FABS(d * 255.0); a = (unsigned char)CLAMP(q); edge = PremultiplyAlpha(colorPtr, a); fill = PremultiplyAlpha(colorPtr, ~a); PaintPixel(destPtr, x + dx, y + dy, &edge); PaintPixel(destPtr, x + dx, y + dy - 1, &fill); PaintPixel(destPtr, x - dx, y + dy, &edge); PaintPixel(destPtr, x - dx, y + dy - 1, &fill); PaintPixel(destPtr, x + dx, y - dy, &edge); PaintPixel(destPtr, x + dx, y - dy + 1, &fill); PaintPixel(destPtr, x - dx, y - dy, &edge); PaintPixel(destPtr, x - dx, y - dy + 1, &fill); t = d; } } static void PaintThinEllipse( Pict *destPtr, int x, int y, int a, int b, Blt_Pixel *colorPtr, int blend) { ScanLine *coords; Blt_Pixel fill; int dy; int dx1, dx2; coords = ComputeEllipseQuadrant(a, b); if (blend) { fill = PremultiplyAlpha(colorPtr, 255); } else { fill.u32 = colorPtr->u32; } if (coords == NULL) { return; } dx1 = coords[0].right; dx2 = coords[0].left; FillHorizontalLine(destPtr, x + dx2, x + dx1, y, &fill, blend); FillHorizontalLine(destPtr, x - dx1, x - dx2, y, &fill, blend); dx1 = coords[b].right; FillHorizontalLine(destPtr, x - dx1, x + dx1, y - b, &fill, blend); FillHorizontalLine(destPtr, x - dx1, x + dx1, y + b, &fill, blend); for (dy = 1; dy < b; dy++) { dx1 = coords[dy].right; dx2 = coords[dy].left; FillHorizontalLine(destPtr, x + dx2, x + dx1, y - dy, &fill, blend); FillHorizontalLine(destPtr, x + dx2, x + dx1, y + dy, &fill, blend); FillHorizontalLine(destPtr, x - dx1, x - dx2, y - dy, &fill, blend); FillHorizontalLine(destPtr, x - dx1, x - dx2, y + dy, &fill, blend); } Blt_Free(coords); } static void PaintThickEllipse( Blt_Picture picture, int x, int y, /* Center of the ellipse. */ int a, /* Half the width of the ellipse. */ int b, /* Half the height of the ellipse. */ int lineWidth, /* Line width of the ellipse. Must be 1 or * greater. */ Blt_Pixel *colorPtr, int blend) { ScanLine *outer, *inner; Blt_Pixel fill; int dy; int dx1, dx2; lineWidth--; outer = ComputeEllipseQuadrant(a, b); if (outer == NULL) { return; } inner = ComputeEllipseQuadrant(a - lineWidth, b - lineWidth); if (blend) { fill = PremultiplyAlpha(colorPtr, 255); } else { fill.u32 = colorPtr->u32; } dx1 = outer[0].right; dx2 = inner[0].left; FillHorizontalLine(picture, x + dx2, x + dx1, y, &fill, blend); FillHorizontalLine(picture, x - dx1, x - dx2, y, &fill, blend); for (dy = 1; dy < (b - lineWidth); dy++) { dx1 = outer[dy].right; dx2 = inner[dy].left; FillHorizontalLine(picture, x + dx2, x + dx1, y - dy, &fill, blend); FillHorizontalLine(picture, x + dx2, x + dx1, y + dy, &fill, blend); FillHorizontalLine(picture, x - dx1, x - dx2, y - dy, &fill, blend); FillHorizontalLine(picture, x - dx1, x - dx2, y + dy, &fill, blend); } for (/* empty */; dy <= b; dy++) { int dx; dx = outer[dy].right; FillHorizontalLine(picture, x - dx, x + dx, y + dy, &fill, blend); FillHorizontalLine(picture, x - dx, x + dx, y - dy, &fill, blend); } Blt_Free(outer); Blt_Free(inner); } static void PaintFilledEllipse( Blt_Picture picture, int x, int y, /* Center of the ellipse. */ int a, /* Half the width of the ellipse. */ int b, /* Half the height of the ellipse. */ Blt_Pixel *colorPtr, int blend) { ScanLine *coords; Blt_Pixel fill; int dx, dy; coords = ComputeEllipseQuadrant(a, b); if (blend) { fill = PremultiplyAlpha(colorPtr, 255); } else { fill.u32 = colorPtr->u32; } if (coords == NULL) { return; } FillHorizontalLine(picture, x - a, x + a, y, &fill, blend); for (dy = 1; dy <= b; dy++) { dx = coords[dy].right; FillHorizontalLine(picture, x - dx, x + dx, y + dy, &fill, blend); FillHorizontalLine(picture, x - dx, x + dx, y - dy, &fill, blend); } Blt_Free(coords); } static void PaintEllipse( Blt_Picture picture, int x, int y, /* Center of the ellipse. */ int a, /* Half the width of the ellipse. */ int b, /* Half the height of the ellipse. */ int lineWidth, /* Line width of the ellipse. If zero, * then draw a solid filled ellipse. */ Blt_Pixel *colorPtr, int blend) { if ((lineWidth >= a) || (lineWidth >= b)) { lineWidth = 0; } if (lineWidth < 1) { PaintFilledEllipse(picture, x, y, a, b, colorPtr, blend); } else { PaintThickEllipse(picture, x, y, a, b, lineWidth, colorPtr, blend); } } static void PaintEllipseAA( Blt_Picture picture, int x, int y, /* Center of the ellipse. */ int a, /* Half the width of the ellipse. */ int b, /* Half the height of the ellipse. */ int lineWidth, /* Line thickness of the ellipse. If zero, * then draw a solid filled ellipse. */ Blt_Pixel *colorPtr) { PictRegion region; Blt_Picture big; int nSamples = 3; int ellipseWidth, ellipseHeight; int blend = 1; if ((lineWidth >= a) || (lineWidth >= b)) { lineWidth = 0; } ellipseWidth = a + a + 3; ellipseHeight = b + b + 3; region.x = x - (a + 1); region.y = y - (b + 1); region.w = ellipseWidth; region.h = ellipseHeight; if (!Blt_AdjustRegionToPicture(picture, &region)) { return; /* Ellipse is totally clipped. */ } /* Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ big = Blt_CreatePicture(ellipseWidth * nSamples, ellipseHeight * nSamples); if (big != NULL) { Blt_Picture tmp; int cx, cy; Blt_Pixel color; cx = a + 1; cy = b + 1; /* Now draw an ellipse scaled by the same amount. The center of the * ellipse is the center of the picture. */ color.u32 = 0x00000000; Blt_BlankPicture(big, &color); color.u32 = 0xFF000000; PaintEllipse(big, cx * nSamples, /* Center of ellipse. */ cy * nSamples, a * nSamples, b * nSamples, lineWidth * nSamples, /* Scaled line width. */ &color, blend); /* Reduce the picture back to the original size using a simple box * filter for smoothing. */ tmp = Blt_CreatePicture(ellipseWidth, ellipseHeight); Blt_ResamplePicture(tmp, big, bltBoxFilter, bltBoxFilter); Blt_FreePicture(big); Blt_ApplyColorToPicture(tmp, colorPtr); /* Replace the bounding box in the original with the new. */ Blt_BlendPictures(picture, tmp, 0, 0, region.w, region.h, region.x, region.y); Blt_FreePicture(tmp); } } static void PaintCircle( Blt_Picture picture, int x, int y, /* Center of the circle in picture. */ int r, /* Radius of the circle. */ int lineWidth, /* Line width of the circle. */ Blt_Pixel *colorPtr) { int blend = 1; if (lineWidth >= r) { lineWidth = 0; } if (lineWidth < 1) { PaintFilledEllipse(picture, x, y, r, r, colorPtr, blend); } else if (lineWidth == 1) { PaintThinEllipse(picture, x, y, r, r, colorPtr, blend); } else { PaintThickEllipse(picture, x, y, r, r, lineWidth, colorPtr, blend); } } static void PaintRectangle( Blt_Picture picture, int x, int y, /* Upper left corner of rectangle. */ int width, int height, /* Dimension of rectangle. */ int r, /* Radius of rounded corner. If zero, draw * square corners. */ int lineWidth, /* Line width of the rectangle. If zero, then * draw a solid fill rectangle. */ Blt_Pixel *colorPtr) { if (((lineWidth*2) >= width) || ((lineWidth*2) >= height)) { lineWidth = 0; /* Paint solid rectangle instead.*/ } if (lineWidth == 0) { PaintRoundedRectangle(picture, x, y, width, height, r, colorPtr); } else { PaintThickRoundedRectangle(picture, x, y, width, height, r, lineWidth, colorPtr); } } static void PaintRectangleAA( Blt_Picture picture, int x, int y, /* Upper left corner of rectangle. */ int w, int h, /* Dimension of rectangle. */ int r, /* Radius of rounded corner. If zero, * draw square corners. */ int lineWidth, /* Line width of the rectangle. If * zero, then draw a solid fill * rectangle. */ Blt_Pixel *colorPtr) { Blt_Picture big; /* Super-sampled background. */ int nSamples = 4; Blt_Picture tmp; int offset = 4; Blt_Pixel color; if (((lineWidth*2) >= w) || ((lineWidth*2) >= h)) { lineWidth = 0; /* Paint solid rectangle instead.*/ } if (r < 0) { PaintRectangle(picture, x, y, w, h, r, lineWidth, colorPtr); return; } /* * Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ big = Blt_CreatePicture((w+2*offset) * nSamples, (h+2*offset) * nSamples); color.u32 = 0x00; Blt_BlankPicture(big, &color); if (big == NULL) { return; } PaintRectangle(big, /* Contains super-sampled original * background. */ 0, 0, w * nSamples, /* Scaled width */ h * nSamples, /* Scaled height */ r * nSamples, /* Scaled radius. */ lineWidth * nSamples, /* Scaled line width. */ colorPtr); /* Reduce the picture back to its original size using a simple box * filter for smoothing. */ tmp = Blt_CreatePicture(w+2*offset, h+2*offset); Blt_ResamplePicture(tmp, big, bltBoxFilter, bltBoxFilter); /* Replace the bounding box in the original with the new. */ Blt_BlendPictures(picture, tmp, 0, 0, w+offset, h+offset, x, y); Blt_FreePicture(big); Blt_FreePicture(tmp); } static void PaintRectangleShadow( Blt_Picture picture, int x, int y, /* Upper left corner of rectangle. */ int w, int h, /* Dimension of rectangle. */ int r, /* Radius of rounded corner. If zero, draw * square corners. */ int lineWidth, Shadow *shadowPtr) { int dw, dh; Blt_Picture blur, tmp; Blt_Pixel color; dw = (w + shadowPtr->offset*2); dh = (h + shadowPtr->offset*2); blur = Blt_CreatePicture(dw, dh); color.u32 = 0x00; Blt_BlankPicture(blur, &color); color.Alpha = shadowPtr->alpha; #ifdef notdef /* * draw the rectangle. * blur into a slightly bigger picture (for blur width). * mask off original rectangle, leaving fringe blur. * blend into destination. */ tmp = Blt_CreatePicture(dw, dh); color.u32 = 0x00; Blt_BlankPicture(tmp, &color); color.Alpha = 0xFF; PaintRectangle(tmp, 0, 0, w, h, r, lineWidth, &color); Blt_CopyPictureBits(blur, tmp, 0, 0, w, h, shadowPtr->offset*2, shadowPtr->offset*2); Blt_BlurPicture(blur, blur, shadowPtr->offset); color.u32 = 0x00; Blt_MaskPicture(blur, tmp, 0, 0, w, h, 0, 0, &color); Blt_BlendPictures(picture, blur, 0, 0, dw, dh, x, y); Blt_FreePicture(blur); #else PaintRectangle(blur, shadowPtr->offset, shadowPtr->offset, w, h, r, lineWidth, &color); Blt_BlurPicture(blur, blur, shadowPtr->offset/2); Blt_BlendPictures(picture, blur, 0, 0, dw, dh, x, y); Blt_FreePicture(blur); #endif } void Blt_PaintRectangle( Blt_Picture picture, int x, int y, /* Upper left corner of rectangle. */ int w, int h, /* Dimension of rectangle. */ int r, /* Radius of rounded corner. If zero, draw * square corners. */ int lineWidth, /* Line width of the rectangle. If zero, then * draw a solid fill rectangle. */ Blt_Pixel *colorPtr) { PaintRectangle(picture, x, y, w, h, r, lineWidth, colorPtr); } �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixBitmap.c���������������������������������������������������������������0000644�0001750�0001750�00000043374�11462120063�015767� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixBitmap.c -- * * This module implements X11-specific bitmap processing procedures for the * BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the Tk * library distrubution. The photo image type was designed and implemented by * Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #include "bltInt.h" #include "bltHash.h" #ifdef notdef #include "bltPicture.h" #endif #include <X11/Xutil.h> #include <X11/Xproto.h> #include "bltBitmap.h" #define ROTATE_0 0 #define ROTATE_90 1 #define ROTATE_180 2 #define ROTATE_270 3 Pixmap Blt_PhotoImageMask(Tk_Window tkwin, Tk_PhotoImageBlock src) { Pixmap bitmap; int arraySize, bytes_per_line; int offset, count; int y; unsigned char *bits; unsigned char *dp; bytes_per_line = (src.width + 7) / 8; arraySize = src.height * bytes_per_line; bits = Blt_AssertMalloc(sizeof(unsigned char) * arraySize); dp = bits; offset = count = 0; for (y = 0; y < src.height; y++) { int value, bitMask; int x; unsigned char *sp; value = 0, bitMask = 1; sp = src.pixelPtr + offset; for (x = 0; x < src.width; /*empty*/ ) { unsigned long pixel; pixel = (sp[src.offset[3]] != 0x00); if (pixel) { value |= bitMask; } else { count++; /* Count the number of transparent pixels. */ } bitMask <<= 1; x++; if (!(x & 7)) { *dp++ = (unsigned char)value; value = 0, bitMask = 1; } sp += src.pixelSize; } if (x & 7) { *dp++ = (unsigned char)value; } offset += src.pitch; } if (count > 0) { Tk_MakeWindowExist(tkwin); bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin), (char *)bits, (unsigned int)src.width, (unsigned int)src.height); } else { bitmap = None; /* Image is opaque. */ } Blt_Free(bits); return bitmap; } #ifdef notdef Pixmap Blt_PictureMask(Tk_Window tkwin, Picture *srcPtr) { Blt_Pixel *srcRowPtr; Pixmap bitmap; int bytesPerLine; int count; int x, y; unsigned char *bits; unsigned char *destRowPtr; bytesPerLine = (srcPtr->width + 7) / 8; bits = Blt_AssertMalloc(sizeof(unsigned char)*srcPtr->height*bytesPerLine); count = 0; srcRowPtr = srcPtr->bits; destRowPtr = bits; for (y = 0; y < srcPtr->height; y++) { int value, bitMask; Blt_Pixel *sp; unsigned char *dp; sp = srcRowPtr, dp = destRowPtr; value = 0, bitMask = 1; for (x = 0; x < srcPtr->width; /*empty*/ ) { unsigned long pixel; pixel = (sp->Alpha != ALPHA_TRANSPARENT); if (pixel) { value |= bitMask; } else { count++; /* Count the number of transparent pixels. */ } bitMask <<= 1; x++; if (!(x & 7)) { *dp++ = (unsigned char)value; value = 0, bitMask = 1; } sp++; } if (x & 7) { *dp++ = (unsigned char)value; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += bytesPerLine; } if (count > 0) { Tk_MakeWindowExist(tkwin); bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin), (char *)bits, (unsigned int)srcPtr->width, (unsigned int)srcPtr->height); } else { bitmap = None; /* Image is opaque. */ } Blt_Free(bits); return bitmap; } #endif /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given bitmap. * We also need a special GC of depth 1, so that we do not need to rotate * more than one plane of the bitmap. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* # of degrees to rotate the bitmap. */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ GC bitmapGC; Pixmap destBitmap; Window root; /* Root window drawable */ XImage *srcImgPtr, *destImgPtr; double rotWidth, rotHeight; int destWidth, destHeight; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = ROUND(rotWidth); destHeight = ROUND(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); bitmapGC = Blt_GetBitmapGC(tkwin); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, destWidth, destHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, destWidth, destHeight, 1, ZPixmap); angle = FMOD(angle, 360.0); if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { int x, sx; sx = y; for (x = 0; x < destWidth; x++) { int sy; unsigned long pixel; sy = destWidth - x - 1; pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { int x, sy; sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { int sx; unsigned long pixel; sx = destWidth - x - 1, pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { int x, sx; sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { int sy; unsigned long pixel; sy = x; pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { int x; for (x = 0; x < destWidth; x++) { unsigned long pixel; pixel = XGetPixel(srcImgPtr, x, y); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double sox, soy; /* Offset from the center of the source * rectangle. */ double destCX, destCY; /* Offset to the center of the destination * rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* Coordinates of the centers of source and destination rectangles */ sox = srcWidth * 0.5; soy = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < destHeight; y++) { double ty; int x; ty = y - destCY; for (x = 0; x < destWidth; x++) { double tx, rx, ry, sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = x - destCX; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += sox; ry += soy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } } /* Write the rotated image into the destination bitmap. */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, destWidth, destHeight); /* Clean up the temporary resources used. */ XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); *destWidthPtr = destWidth; *destHeightPtr = destHeight; return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. The new bitmap is * bounded by a specified region. Only this portion of the bitmap is * scaled from the original bitmap. * * By bounding scaling to a region we can generate a new bitmap which is * no bigger than the specified viewport. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { Display *display; GC bitmapGC; Pixmap destBitmap; Window root; XImage *srcImgPtr, *destImgPtr; double xScale, yScale; int y; /* Destination bitmap coordinates */ /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); bitmapGC = Blt_GetBitmapGC(tkwin); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, destWidth, destHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, destWidth, destHeight, 1, ZPixmap); /* * Scale each pixel of destination image from results of source * image. Verify the coordinates, since the destination image can be * bigger than the source */ xScale = (double)srcWidth / (double)destWidth; yScale = (double)srcHeight / (double)destHeight; /* Map each pixel in the destination image back to the source. */ for (y = 0; y < destHeight; y++) { int x, sy; sy = (int)(yScale * (double)y); for (x = 0; x < destWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)x); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } /* Write the scaled image into the destination bitmap */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, destWidth, destHeight); XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_RotateScaleBitmapArea -- * * Creates a scaled and rotated bitmap from a given bitmap. The caller * also provides (offsets and dimensions) the region of interest in the * destination bitmap. This saves having to process the entire * destination bitmap is only part of it is showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the destination * image. For each pixel, the corresponding pixel in the source bitmap * is used. This means that destination coordinates are first scaled to * the size of the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapArea( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual destination * bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int destWidth, unsigned int destHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; XImage *srcImgPtr, *destImgPtr; double xScale, yScale; double rotWidth, rotHeight; GC bitmapGC; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); /* Create a bitmap and image big enough to contain the rotated text */ bitmapGC = Blt_GetBitmapGC(tkwin); destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, regionWidth, regionHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, regionWidth, regionHeight, 1, ZPixmap); angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); xScale = rotWidth / (double)destWidth; yScale = rotHeight / (double)destHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int x, y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < regionHeight; y++) { int sx; sx = (int)(yScale * (double)(y + regionY)); for (x = 0; x < regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale *(double)(destWidth - (x + regionX) - 1)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < regionHeight; y++) { int sy; sy = (int)(yScale * (double)(destHeight - (y + regionY) - 1)); for (x = 0; x < regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale *(double)(destWidth - (x + regionX) - 1)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < regionHeight; y++) { int sx; sx = (int)(yScale * (double)(destHeight - (y + regionY) - 1)); for (x = 0; x < regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < regionHeight; y++) { int sy; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double sox, soy; /* Offset from the center of the source * rectangle. */ double rox, roy; /* Offset to the center of the rotated * rectangle. */ int x, y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ sox = srcWidth * 0.5; soy = srcHeight * 0.5; rox = rotWidth * 0.5; roy = rotHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < regionHeight; y++) { double ty; ty = (yScale * (double)(y + regionY)) - roy; for (x = 0; x < regionWidth; x++) { double tx, rx, ry; int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rox; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += sox; ry += soy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } } /* Write the rotated image into the destination bitmap. */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, regionWidth, regionHeight); /* Clean up the temporary resources used. */ XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); return destBitmap; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltSpline.c�������������������������������������������������������������������0000644�0001750�0001750�00000114351�11462120062�015132� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #include "bltInt.h" #include "bltOp.h" #include <bltVector.h> typedef int (SplineProc)(Point2d origPts[], int nOrigPts, Point2d intpPts[], int nIntpPts); typedef double TriDiagonalMatrix[3]; typedef struct { double b, c, d; } Cubic2D; typedef struct { double b, c, d, e, f; } Quint2D; /* * Quadratic spline parameters */ #define E1 param[0] #define E2 param[1] #define V1 param[2] #define V2 param[3] #define W1 param[4] #define W2 param[5] #define Z1 param[6] #define Z2 param[7] #define Y1 param[8] #define Y2 param[9] static Tcl_ObjCmdProc SplineCmd; /* *--------------------------------------------------------------------------- * * Search -- * * Conducts a binary search for a value. This routine is called * only if key is between x(0) and x(len - 1). * * Results: * Returns the index of the largest value in xtab for which * x[i] < key. * *--------------------------------------------------------------------------- */ static int Search( Point2d points[], /* Contains the abscissas of the data * points of interpolation. */ int nPoints, /* Dimension of x. */ double key, /* Value whose relative position in * x is to be located. */ int *foundPtr) /* (out) Returns 1 if s is found in * x and 0 otherwise. */ { int high, low, mid; low = 0; high = nPoints - 1; while (high >= low) { mid = (high + low) / 2; if (key > points[mid].x) { low = mid + 1; } else if (key < points[mid].x) { high = mid - 1; } else { *foundPtr = 1; return mid; } } *foundPtr = 0; return low; } /* *--------------------------------------------------------------------------- * * QuadChoose -- * * Determines the case needed for the computation of the parame- * ters of the quadratic spline. * * Results: * Returns a case number (1-4) which controls how the parameters * of the quadratic spline are evaluated. * *--------------------------------------------------------------------------- */ static int QuadChoose( Point2d *p, /* Coordinates of one of the points of * interpolation */ Point2d *q, /* Coordinates of one of the points of * interpolation */ double m1, /* Derivative condition at point P */ double m2, /* Derivative condition at point Q */ double epsilon) /* Error tolerance used to distinguish * cases when m1 or m2 is relatively * close to the slope or twice the * slope of the line segment joining * the points P and Q. If * epsilon is not 0.0, then epsilon * should be greater than or equal to * machine epsilon. */ { double slope; /* Calculate the slope of the line joining P and Q. */ slope = (q->y - p->y) / (q->x - p->x); if (slope != 0.0) { double relerr; double mref, mref1, mref2, prod1, prod2; prod1 = slope * m1; prod2 = slope * m2; /* Find the absolute values of the slopes slope, m1, and m2. */ mref = FABS(slope); mref1 = FABS(m1); mref2 = FABS(m2); /* * If the relative deviation of m1 or m2 from slope is less than * epsilon, then choose case 2 or case 3. */ relerr = epsilon * mref; if ((FABS(slope - m1) > relerr) && (FABS(slope - m2) > relerr) && (prod1 >= 0.0) && (prod2 >= 0.0)) { double prod; prod = (mref - mref1) * (mref - mref2); if (prod < 0.0) { /* * l1, the line through (x1,y1) with slope m1, and l2, * the line through (x2,y2) with slope m2, intersect * at a point whose abscissa is between x1 and x2. * The abscissa becomes a knot of the spline. */ return 1; } if (mref1 > (mref * 2.0)) { if (mref2 <= ((2.0 - epsilon) * mref)) { return 3; } } else if (mref2 <= (mref * 2.0)) { /* * Both l1 and l2 cross the line through * (x1+x2)/2.0,y1 and (x1+x2)/2.0,y2, which is the * midline of the rectangle formed by P and Q or both * m1 and m2 have signs different than the sign of * slope, or one of m1 and m2 has opposite sign from * slope and l1 and l2 intersect to the left of x1 or * to the right of x2. The point (x1+x2)/2. is a knot * of the spline. */ return 2; } else if (mref1 <= ((2.0 - epsilon) * mref)) { /* * In cases 3 and 4, sign(m1)=sign(m2)=sign(slope). * Either l1 or l2 crosses the midline, but not both. * Choose case 4 if mref1 is greater than * (2.-epsilon)*mref; otherwise, choose case 3. */ return 3; } /* * If neither l1 nor l2 crosses the midline, the spline * requires two knots between x1 and x2. */ return 4; } else { /* * The sign of at least one of the slopes m1 or m2 does not * agree with the sign of *slope*. */ if ((prod1 < 0.0) && (prod2 < 0.0)) { return 2; } else if (prod1 < 0.0) { if (mref2 > ((epsilon + 1.0) * mref)) { return 1; } else { return 2; } } else if (mref1 > ((epsilon + 1.0) * mref)) { return 1; } else { return 2; } } } else if ((m1 * m2) >= 0.0) { return 2; } else { return 1; } } /* *--------------------------------------------------------------------------- * * QuadCases -- * * Computes the knots and other parameters of the spline on the * interval PQ. * * * On input-- * * P and Q are the coordinates of the points of interpolation. * * m1 is the slope at P. * * m2 is the slope at Q. * * ncase controls the number and location of the knots. * * * On output-- * * (v1,v2),(w1,w2),(z1,z2), and (e1,e2) are the coordinates of * the knots and other parameters of the spline on P. * (e1,e2) and Q are used only if ncase=4. * *--------------------------------------------------------------------------- */ static void QuadCases(Point2d *p, Point2d *q, double m1, double m2, double param[], int which) { if ((which == 3) || (which == 4)) { /* Parameters used in both 3 and 4 */ double mbar1, mbar2, mbar3, c1, d1, h1, j1, k1; c1 = p->x + (q->y - p->y) / m1; d1 = q->x + (p->y - q->y) / m2; h1 = c1 * 2.0 - p->x; j1 = d1 * 2.0 - q->x; mbar1 = (q->y - p->y) / (h1 - p->x); mbar2 = (p->y - q->y) / (j1 - q->x); if (which == 4) { /* Case 4. */ Y1 = (p->x + c1) / 2.0; V1 = (p->x + Y1) / 2.0; V2 = m1 * (V1 - p->x) + p->y; Z1 = (d1 + q->x) / 2.0; W1 = (q->x + Z1) / 2.0; W2 = m2 * (W1 - q->x) + q->y; mbar3 = (W2 - V2) / (W1 - V1); Y2 = mbar3 * (Y1 - V1) + V2; Z2 = mbar3 * (Z1 - V1) + V2; E1 = (Y1 + Z1) / 2.0; E2 = mbar3 * (E1 - V1) + V2; } else { /* Case 3. */ k1 = (p->y - q->y + q->x * mbar2 - p->x * mbar1) / (mbar2 - mbar1); if (FABS(m1) > FABS(m2)) { Z1 = (k1 + p->x) / 2.0; } else { Z1 = (k1 + q->x) / 2.0; } V1 = (p->x + Z1) / 2.0; V2 = p->y + m1 * (V1 - p->x); W1 = (q->x + Z1) / 2.0; W2 = q->y + m2 * (W1 - q->x); Z2 = V2 + (W2 - V2) / (W1 - V1) * (Z1 - V1); } } else if (which == 2) { /* Case 2. */ Z1 = (p->x + q->x) / 2.0; V1 = (p->x + Z1) / 2.0; V2 = p->y + m1 * (V1 - p->x); W1 = (Z1 + q->x) / 2.0; W2 = q->y + m2 * (W1 - q->x); Z2 = (V2 + W2) / 2.0; } else { /* Case 1. */ double ztwo; Z1 = (p->y - q->y + m2 * q->x - m1 * p->x) / (m2 - m1); ztwo = p->y + m1 * (Z1 - p->x); V1 = (p->x + Z1) / 2.0; V2 = (p->y + ztwo) / 2.0; W1 = (Z1 + q->x) / 2.0; W2 = (ztwo + q->y) / 2.0; Z2 = V2 + (W2 - V2) / (W1 - V1) * (Z1 - V1); } } static int QuadSelect(Point2d *p, Point2d *q, double m1, double m2, double epsilon, double param[]) { int ncase; ncase = QuadChoose(p, q, m1, m2, epsilon); QuadCases(p, q, m1, m2, param, ncase); return ncase; } /* *--------------------------------------------------------------------------- * * QuadGetImage -- * *--------------------------------------------------------------------------- */ INLINE static double QuadGetImage(double p1, double p2, double p3, double x1, double x2, double x3) { double A, B, C; double y; A = x1 - x2; B = x2 - x3; C = x1 - x3; y = (p1 * (A * A) + p2 * 2.0 * B * A + p3 * (B * B)) / (C * C); return y; } /* *--------------------------------------------------------------------------- * * QuadSpline -- * * Finds the image of a point in x. * * On input * * x Contains the value at which the spline is evaluated. * leftX, leftY * Coordinates of the left-hand data point used in the * evaluation of x values. * rightX, rightY * Coordinates of the right-hand data point used in the * evaluation of x values. * Z1, Z2, Y1, Y2, E2, W2, V2 * Parameters of the spline. * ncase Controls the evaluation of the spline by indicating * whether one or two knots were placed in the interval * (xtabs,xtabs1). * * Results: * The image of the spline at x. * *--------------------------------------------------------------------------- */ static void QuadSpline( Point2d *intp, /* Value at which spline is evaluated */ Point2d *left, /* Point to the left of the data point to * be evaluated */ Point2d *right, /* Point to the right of the data point to * be evaluated */ double param[], /* Parameters of the spline */ int ncase) /* Controls the evaluation of the * spline by indicating whether one or * two knots were placed in the * interval (leftX,rightX) */ { double y; if (ncase == 4) { /* * Case 4: More than one knot was placed in the interval. */ /* * Determine the location of data point relative to the 1st knot. */ if (Y1 > intp->x) { y = QuadGetImage(left->y, V2, Y2, Y1, intp->x, left->x); } else if (Y1 < intp->x) { /* * Determine the location of the data point relative to * the 2nd knot. */ if (Z1 > intp->x) { y = QuadGetImage(Y2, E2, Z2, Z1, intp->x, Y1); } else if (Z1 < intp->x) { y = QuadGetImage(Z2, W2, right->y, right->x, intp->x, Z1); } else { y = Z2; } } else { y = Y2; } } else { /* * Cases 1, 2, or 3: * * Determine the location of the data point relative to the * knot. */ if (Z1 < intp->x) { y = QuadGetImage(Z2, W2, right->y, right->x, intp->x, Z1); } else if (Z1 > intp->x) { y = QuadGetImage(left->y, V2, Z2, Z1, intp->x, left->x); } else { y = Z2; } } intp->y = y; } /* *--------------------------------------------------------------------------- * * QuadSlopes -- * * Calculates the derivative at each of the data points. The * slopes computed will insure that an osculatory quadratic * spline will have one additional knot between two adjacent * points of interpolation. Convexity and monotonicity are * preserved wherever these conditions are compatible with the * data. * * Results: * The output array "m" is filled with the derivates at each * data point. * *--------------------------------------------------------------------------- */ static void QuadSlopes(Point2d *points, double *m, int nPoints) { double xbar, xmid, xhat, ydif1, ydif2; double yxmid; double m1, m2; double m1s, m2s; int i, n, l; m1s = m2s = m1 = m2 = 0; for (l = 0, i = 1, n = 2; i < (nPoints - 1); l++, i++, n++) { /* * Calculate the slopes of the two lines joining three * consecutive data points. */ ydif1 = points[i].y - points[l].y; ydif2 = points[n].y - points[i].y; m1 = ydif1 / (points[i].x - points[l].x); m2 = ydif2 / (points[n].x - points[i].x); if (i == 1) { m1s = m1, m2s = m2; /* Save slopes of starting point */ } /* * If one of the preceding slopes is zero or if they have opposite * sign, assign the value zero to the derivative at the middle * point. */ if ((m1 == 0.0) || (m2 == 0.0) || ((m1 * m2) <= 0.0)) { m[i] = 0.0; } else if (FABS(m1) > FABS(m2)) { /* * Calculate the slope by extending the line with slope m1. */ xbar = ydif2 / m1 + points[i].x; xhat = (xbar + points[n].x) / 2.0; m[i] = ydif2 / (xhat - points[i].x); } else { /* * Calculate the slope by extending the line with slope m2. */ xbar = -ydif1 / m2 + points[i].x; xhat = (points[l].x + xbar) / 2.0; m[i] = ydif1 / (points[i].x - xhat); } } /* Calculate the slope at the last point, x(n). */ i = nPoints - 2; n = nPoints - 1; if ((m1 * m2) < 0.0) { m[n] = m2 * 2.0; } else { xmid = (points[i].x + points[n].x) / 2.0; yxmid = m[i] * (xmid - points[i].x) + points[i].y; m[n] = (points[n].y - yxmid) / (points[n].x - xmid); if ((m[n] * m2) < 0.0) { m[n] = 0.0; } } /* Calculate the slope at the first point, x(0). */ if ((m1s * m2s) < 0.0) { m[0] = m1s * 2.0; } else { xmid = (points[0].x + points[1].x) / 2.0; yxmid = m[1] * (xmid - points[1].x) + points[1].y; m[0] = (yxmid - points[0].y) / (xmid - points[0].x); if ((m[0] * m1s) < 0.0) { m[0] = 0.0; } } } /* *--------------------------------------------------------------------------- * * QuadEval -- * * QuadEval controls the evaluation of an osculatory quadratic * spline. The user may provide his own slopes at the points of * interpolation or use the subroutine 'QuadSlopes' to calculate * slopes which are consistent with the shape of the data. * * ON INPUT-- * intpPts must be a nondecreasing vector of points at which the * spline will be evaluated. * origPts contains the abscissas of the data points to be * interpolated. xtab must be increasing. * y contains the ordinates of the data points to be * interpolated. * m contains the slope of the spline at each point of * interpolation. * nPoints number of data points (dimension of xtab and y). * numEval is the number of points of evaluation (dimension of * xval and yval). * epsilon is a relative error tolerance used in subroutine * 'QuadChoose' to distinguish the situation m(i) or * m(i+1) is relatively close to the slope or twice * the slope of the linear segment between xtab(i) and * xtab(i+1). If this situation occurs, roundoff may * cause a change in convexity or monotonicity of the * resulting spline and a change in the case number * provided by 'QuadChoose'. If epsilon is not equal to zero, * then epsilon should be greater than or equal to machine * epsilon. * ON OUTPUT-- * yval contains the images of the points in xval. * err is one of the following error codes: * 0 - QuadEval ran normally. * 1 - xval(i) is less than xtab(1) for at least one * i or xval(i) is greater than xtab(num) for at * least one i. QuadEval will extrapolate to provide * function values for these abscissas. * 2 - xval(i+1) < xval(i) for some i. * * * QuadEval calls the following subroutines or functions: * Search * QuadCases * QuadChoose * QuadSpline *--------------------------------------------------------------------------- */ static int QuadEval( Point2d origPts[], int nOrigPts, Point2d intpPts[], int nIntpPts, double *m, /* Slope of the spline at each point * of interpolation. */ double epsilon) /* Relative error tolerance (see choose) */ { int error; int i, j; double param[10]; int ncase; int start, end; int l, p; int n; int found; /* Initialize indices and set error result */ error = 0; l = nOrigPts - 1; p = l - 1; ncase = 1; /* * Determine if abscissas of new vector are non-decreasing. */ for (j = 1; j < nIntpPts; j++) { if (intpPts[j].x < intpPts[j - 1].x) { return 2; } } /* * Determine if any of the points in xval are LESS than the * abscissa of the first data point. */ for (start = 0; start < nIntpPts; start++) { if (intpPts[start].x >= origPts[0].x) { break; } } /* * Determine if any of the points in xval are GREATER than the * abscissa of the l data point. */ for (end = nIntpPts - 1; end >= 0; end--) { if (intpPts[end].x <= origPts[l].x) { break; } } if (start > 0) { error = 1; /* Set error value to indicate that * extrapolation has occurred. */ /* * Calculate the images of points of evaluation whose abscissas * are less than the abscissa of the first data point. */ ncase = QuadSelect(origPts, origPts + 1, m[0], m[1], epsilon, param); for (j = 0; j < (start - 1); j++) { QuadSpline(intpPts + j, origPts, origPts + 1, param, ncase); } if (nIntpPts == 1) { return error; } } if ((nIntpPts == 1) && (end != (nIntpPts - 1))) { goto noExtrapolation; } /* * Search locates the interval in which the first in-range * point of evaluation lies. */ i = Search(origPts, nOrigPts, intpPts[start].x, &found); n = i + 1; if (n >= nOrigPts) { n = nOrigPts - 1; i = nOrigPts - 2; } /* * If the first in-range point of evaluation is equal to one * of the data points, assign the appropriate value from y. * Continue until a point of evaluation is found which is not * equal to a data point. */ if (found) { do { intpPts[start].y = origPts[i].y; start++; if (start >= nIntpPts) { return error; } } while (intpPts[start - 1].x == intpPts[start].x); for (;;) { if (intpPts[start].x < origPts[n].x) { break; /* Break out of for-loop */ } if (intpPts[start].x == origPts[n].x) { do { intpPts[start].y = origPts[n].y; start++; if (start >= nIntpPts) { return error; } } while (intpPts[start].x == intpPts[start - 1].x); } i++; n++; } } /* * Calculate the images of all the points which lie within * range of the data. */ if ((i > 0) || (error != 1)) { ncase = QuadSelect(origPts + i, origPts + n, m[i], m[n], epsilon, param); } for (j = start; j <= end; j++) { /* * If xx(j) - x(n) is negative, do not recalculate * the parameters for this section of the spline since * they are already known. */ if (intpPts[j].x == origPts[n].x) { intpPts[j].y = origPts[n].y; continue; } else if (intpPts[j].x > origPts[n].x) { double delta; /* Determine that the routine is in the correct part of the spline. */ do { i++, n++; delta = intpPts[j].x - origPts[n].x; } while (delta > 0.0); if (delta < 0.0) { ncase = QuadSelect(origPts + i, origPts + n, m[i], m[n], epsilon, param); } else if (delta == 0.0) { intpPts[j].y = origPts[n].y; continue; } } QuadSpline(intpPts + j, origPts + i, origPts + n, param, ncase); } if (end == (nIntpPts - 1)) { return error; } if ((n == l) && (intpPts[end].x != origPts[l].x)) { goto noExtrapolation; } error = 1; /* Set error value to indicate that * extrapolation has occurred. */ ncase = QuadSelect(origPts + p, origPts + l, m[p], m[l], epsilon, param); noExtrapolation: /* * Calculate the images of the points of evaluation whose * abscissas are greater than the abscissa of the last data point. */ for (j = (end + 1); j < nIntpPts; j++) { QuadSpline(intpPts + j, origPts + p, origPts + l, param, ncase); } return error; } /* *--------------------------------------------------------------------------- * * Shape preserving quadratic splines * by D.F.Mcallister & J.A.Roulier * Coded by S.L.Dodd & M.Roulier * N.C.State University * *--------------------------------------------------------------------------- */ /* * Driver routine for quadratic spline package * On input-- * X,Y Contain n-long arrays of data (x is increasing) * XM Contains m-long array of x values (increasing) * eps Relative error tolerance * n Number of input data points * m Number of output data points * On output-- * work Contains the value of the first derivative at each data point * ym Contains the interpolated spline value at each data point */ int Blt_QuadraticSpline(Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts) { double epsilon; double *work; int result; work = Blt_AssertMalloc(nOrigPts * sizeof(double)); epsilon = 0.0; /* TBA: adjust error via command-line option */ /* allocate space for vectors used in calculation */ QuadSlopes(origPts, work, nOrigPts); result = QuadEval(origPts, nOrigPts, intpPts, nIntpPts, work, epsilon); Blt_Free(work); if (result > 1) { return FALSE; } return TRUE; } /* *--------------------------------------------------------------------------- * * Reference: * Numerical Analysis, R. Burden, J. Faires and A. Reynolds. * Prindle, Weber & Schmidt 1981 pp 112 * * Parameters: * origPts - vector of points, assumed to be sorted along x. * intpPts - vector of new points. * *--------------------------------------------------------------------------- */ int Blt_NaturalSpline(Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts) { Cubic2D *eq; Point2d *ip, *iend; TriDiagonalMatrix *A; double *dx; /* vector of deltas in x */ double x, dy, alpha; int isKnot; int i, j, n; dx = Blt_AssertMalloc(sizeof(double) * nOrigPts); /* Calculate vector of differences */ for (i = 0, j = 1; j < nOrigPts; i++, j++) { dx[i] = origPts[j].x - origPts[i].x; if (dx[i] < 0.0) { return 0; } } n = nOrigPts - 1; /* Number of intervals. */ A = Blt_AssertMalloc(sizeof(TriDiagonalMatrix) * nOrigPts); if (A == NULL) { Blt_Free(dx); return 0; } /* Vectors to solve the tridiagonal matrix */ A[0][0] = A[n][0] = 1.0; A[0][1] = A[n][1] = 0.0; A[0][2] = A[n][2] = 0.0; /* Calculate the intermediate results */ for (i = 0, j = 1; j < n; j++, i++) { alpha = 3.0 * ((origPts[j + 1].y / dx[j]) - (origPts[j].y / dx[i]) - (origPts[j].y / dx[j]) + (origPts[i].y / dx[i])); A[j][0] = 2 * (dx[j] + dx[i]) - dx[i] * A[i][1]; A[j][1] = dx[j] / A[j][0]; A[j][2] = (alpha - dx[i] * A[i][2]) / A[j][0]; } eq = Blt_Malloc(sizeof(Cubic2D) * nOrigPts); if (eq == NULL) { Blt_Free(A); Blt_Free(dx); return FALSE; } eq[0].c = eq[n].c = 0.0; for (j = n, i = n - 1; i >= 0; i--, j--) { eq[i].c = A[i][2] - A[i][1] * eq[j].c; dy = origPts[i+1].y - origPts[i].y; eq[i].b = (dy) / dx[i] - dx[i] * (eq[j].c + 2.0 * eq[i].c) / 3.0; eq[i].d = (eq[j].c - eq[i].c) / (3.0 * dx[i]); } Blt_Free(A); Blt_Free(dx); /* Now calculate the new values */ for (ip = intpPts, iend = ip + nIntpPts; ip < iend; ip++) { ip->y = 0.0; x = ip->x; /* Is it outside the interval? */ if ((x < origPts[0].x) || (x > origPts[n].x)) { continue; } /* Search for the interval containing x in the point array */ i = Search(origPts, nOrigPts, x, &isKnot); if (isKnot) { ip->y = origPts[i].y; } else { i--; x -= origPts[i].x; ip->y = origPts[i].y + x * (eq[i].b + x * (eq[i].c + x * eq[i].d)); } } Blt_Free(eq); return TRUE; } static Blt_OpSpec splineOps[] = { {"natural", 1, Blt_NaturalSpline, 6, 6, "x y splx sply",}, {"quadratic", 1, Blt_QuadraticSpline, 6, 6, "x y splx sply",}, }; static int nSplineOps = sizeof(splineOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int SplineCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { SplineProc *proc; Blt_Vector *x, *y, *splX, *splY; double *xArr, *yArr; int i; Point2d *origPts, *intpPts; int nOrigPts, nIntpPts; proc = Blt_GetOpFromObj(interp, nSplineOps, splineOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } if ((Blt_GetVectorFromObj(interp, objv[2], &x) != TCL_OK) || (Blt_GetVectorFromObj(interp, objv[3], &y) != TCL_OK) || (Blt_GetVectorFromObj(interp, objv[4], &splX) != TCL_OK)) { return TCL_ERROR; } nOrigPts = Blt_VecLength(x); if (nOrigPts < 3) { Tcl_AppendResult(interp, "length of vector \"", Tcl_GetString(objv[2]), "\" is < 3", (char *)NULL); return TCL_ERROR; } for (i = 1; i < nOrigPts; i++) { if (Blt_VecData(x)[i] < Blt_VecData(x)[i - 1]) { Tcl_AppendResult(interp, "x vector \"", Tcl_GetString(objv[2]), "\" must be monotonically increasing", (char *)NULL); return TCL_ERROR; } } /* Check that all the data points aren't the same. */ if (Blt_VecData(x)[i - 1] <= Blt_VecData(x)[0]) { Tcl_AppendResult(interp, "x vector \"", Tcl_GetString(objv[2]), "\" must be monotonically increasing", (char *)NULL); return TCL_ERROR; } if (nOrigPts != Blt_VecLength(y)) { Tcl_AppendResult(interp, "vectors \"", Tcl_GetString(objv[2]), "\" and \"", Tcl_GetString(objv[3]), " have different lengths", (char *)NULL); return TCL_ERROR; } nIntpPts = Blt_VecLength(splX); if (Blt_GetVectorFromObj(interp, objv[5], &splY) != TCL_OK) { /* * If the named vector to hold the ordinates of the spline * doesn't exist, create one the same size as the vector * containing the abscissas. */ if (Blt_CreateVector(interp, Tcl_GetString(objv[5]), nIntpPts, &splY) != TCL_OK) { return TCL_ERROR; } } else if (nIntpPts != Blt_VecLength(splY)) { /* * The x and y vectors differ in size. Make the number of ordinates * the same as the number of abscissas. */ if (Blt_ResizeVector(splY, nIntpPts) != TCL_OK) { return TCL_ERROR; } } origPts = Blt_Malloc(sizeof(Point2d) * nOrigPts); if (origPts == NULL) { Tcl_AppendResult(interp, "can't allocate \"", Blt_Itoa(nOrigPts), "\" points", (char *)NULL); return TCL_ERROR; } intpPts = Blt_Malloc(sizeof(Point2d) * nIntpPts); if (intpPts == NULL) { Tcl_AppendResult(interp, "can't allocate \"", Blt_Itoa(nIntpPts), "\" points", (char *)NULL); Blt_Free(origPts); return TCL_ERROR; } xArr = Blt_VecData(x); yArr = Blt_VecData(y); for (i = 0; i < nOrigPts; i++) { origPts[i].x = xArr[i]; origPts[i].y = yArr[i]; } xArr = Blt_VecData(splX); yArr = Blt_VecData(splY); for (i = 0; i < nIntpPts; i++) { intpPts[i].x = xArr[i]; intpPts[i].y = yArr[i]; } if (!(*proc) (origPts, nOrigPts, intpPts, nIntpPts)) { Tcl_AppendResult(interp, "error generating spline for \"", Blt_NameOfVector(splY), "\"", (char *)NULL); Blt_Free(origPts); Blt_Free(intpPts); return TCL_ERROR; } yArr = Blt_VecData(splY); for (i = 0; i < nIntpPts; i++) { yArr[i] = intpPts[i].y; } Blt_Free(origPts); Blt_Free(intpPts); /* Finally update the vector. The size of the vector hasn't * changed, just the data. Reset the vector using TCL_STATIC to * indicate this. */ if (Blt_ResetVector(splY, Blt_VecData(splY), Blt_VecLength(splY), Blt_VecSize(splY), TCL_STATIC) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } int Blt_SplineCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"spline", SplineCmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #define SQR(x) ((x)*(x)) typedef struct { double t; /* Arc length of interval. */ double x; /* 2nd derivative of X with respect to T */ double y; /* 2nd derivative of Y with respect to T */ } CubicSpline; /* * The following two procedures solve the special linear system which arise * in cubic spline interpolation. If x is assumed cyclic ( x[i]=x[n+i] ) the * equations can be written as (i=0,1,...,n-1): * m[i][0] * x[i-1] + m[i][1] * x[i] + m[i][2] * x[i+1] = b[i] . * In matrix notation one gets A * x = b, where the matrix A is tridiagonal * with additional elements in the upper right and lower left position: * A[i][0] = A_{i,i-1} for i=1,2,...,n-1 and m[0][0] = A_{0,n-1} , * A[i][1] = A_{i, i } for i=0,1,...,n-1 * A[i][2] = A_{i,i+1} for i=0,1,...,n-2 and m[n-1][2] = A_{n-1,0}. * A should be symmetric (A[i+1][0] == A[i][2]) and positive definite. * The size of the system is given in n (n>=1). * * In the first procedure the Cholesky decomposition A = C^T * D * C * (C is upper triangle with unit diagonal, D is diagonal) is calculated. * Return TRUE if decomposition exist. */ static int SolveCubic1(TriDiagonalMatrix A[], int n) { int i; double m_ij, m_n, m_nn, d; if (n < 1) { return FALSE; /* Dimension should be at least 1 */ } d = A[0][1]; /* D_{0,0} = A_{0,0} */ if (d <= 0.0) { return FALSE; /* A (or D) should be positive definite */ } m_n = A[0][0]; /* A_{0,n-1} */ m_nn = A[n - 1][1]; /* A_{n-1,n-1} */ for (i = 0; i < n - 2; i++) { m_ij = A[i][2]; /* A_{i,1} */ A[i][2] = m_ij / d; /* C_{i,i+1} */ A[i][0] = m_n / d; /* C_{i,n-1} */ m_nn -= A[i][0] * m_n; /* to get C_{n-1,n-1} */ m_n = -A[i][2] * m_n; /* to get C_{i+1,n-1} */ d = A[i + 1][1] - A[i][2] * m_ij; /* D_{i+1,i+1} */ if (d <= 0.0) { return FALSE; /* Elements of D should be positive */ } A[i + 1][1] = d; } if (n >= 2) { /* Complete last column */ m_n += A[n - 2][2]; /* add A_{n-2,n-1} */ A[n - 2][0] = m_n / d; /* C_{n-2,n-1} */ A[n - 1][1] = d = m_nn - A[n - 2][0] * m_n; /* D_{n-1,n-1} */ if (d <= 0.0) { return FALSE; } } return TRUE; } /* * The second procedure solves the linear system, with the Cholesky * decomposition calculated above (in m[][]) and the right side b given * in x[]. The solution x overwrites the right side in x[]. */ static void SolveCubic2(TriDiagonalMatrix A[], CubicSpline spline[], int nIntervals) { int i; double x, y; int n, m; n = nIntervals - 2; m = nIntervals - 1; /* Division by transpose of C : b = C^{-T} * b */ x = spline[m].x; y = spline[m].y; for (i = 0; i < n; i++) { spline[i + 1].x -= A[i][2] * spline[i].x; /* C_{i,i+1} * x(i) */ spline[i + 1].y -= A[i][2] * spline[i].y; /* C_{i,i+1} * x(i) */ x -= A[i][0] * spline[i].x; /* C_{i,n-1} * x(i) */ y -= A[i][0] * spline[i].y; /* C_{i,n-1} * x(i) */ } if (n >= 0) { /* C_{n-2,n-1} * x_{n-1} */ spline[m].x = x - A[n][0] * spline[n].x; spline[m].y = y - A[n][0] * spline[n].y; } /* Division by D: b = D^{-1} * b */ for (i = 0; i < nIntervals; i++) { spline[i].x /= A[i][1]; spline[i].y /= A[i][1]; } /* Division by C: b = C^{-1} * b */ x = spline[m].x; y = spline[m].y; if (n >= 0) { /* C_{n-2,n-1} * x_{n-1} */ spline[n].x -= A[n][0] * x; spline[n].y -= A[n][0] * y; } for (i = (n - 1); i >= 0; i--) { /* C_{i,i+1} * x_{i+1} + C_{i,n-1} * x_{n-1} */ spline[i].x -= A[i][2] * spline[i + 1].x + A[i][0] * x; spline[i].y -= A[i][2] * spline[i + 1].y + A[i][0] * y; } } /* * Find second derivatives (x''(t_i),y''(t_i)) of cubic spline interpolation * through list of points (x_i,y_i). The parameter t is calculated as the * length of the linear stroke. The number of points must be at least 3. * Note: For CLOSED_CONTOURs the first and last point must be equal. */ static CubicSpline * CubicSlopes( Point2d points[], int nPoints, /* Number of points (nPoints>=3) */ int isClosed, /* CLOSED_CONTOUR or OPEN_CONTOUR */ double unitX, double unitY) /* Unit length in x and y (norm=1) */ { CubicSpline *spline; CubicSpline *s1, *s2; int n, i; double norm, dx, dy; TriDiagonalMatrix *A; /* The tri-diagonal matrix is saved here. */ spline = Blt_Malloc(sizeof(CubicSpline) * nPoints); if (spline == NULL) { return NULL; } A = Blt_Malloc(sizeof(TriDiagonalMatrix) * nPoints); if (A == NULL) { Blt_Free(spline); return NULL; } /* * Calculate first differences in (dxdt2[i], y[i]) and interval lengths * in dist[i]: */ s1 = spline; for (i = 0; i < nPoints - 1; i++) { s1->x = points[i+1].x - points[i].x; s1->y = points[i+1].y - points[i].y; /* * The Norm of a linear stroke is calculated in "normal coordinates" * and used as interval length: */ dx = s1->x / unitX; dy = s1->y / unitY; s1->t = sqrt(dx * dx + dy * dy); s1->x /= s1->t; /* first difference, with unit norm: */ s1->y /= s1->t; /* || (dxdt2[i], y[i]) || = 1 */ s1++; } /* * Setup linear System: Ax = b */ n = nPoints - 2; /* Without first and last point */ if (isClosed) { /* First and last points must be equal for CLOSED_CONTOURs */ spline[nPoints - 1].t = spline[0].t; spline[nPoints - 1].x = spline[0].x; spline[nPoints - 1].y = spline[0].y; n++; /* Add last point (= first point) */ } s1 = spline, s2 = s1 + 1; for (i = 0; i < n; i++) { /* Matrix A, mainly tridiagonal with cyclic second index ("j = j+n mod n") */ A[i][0] = s1->t; /* Off-diagonal element A_{i,i-1} */ A[i][1] = 2.0 * (s1->t + s2->t); /* A_{i,i} */ A[i][2] = s2->t; /* Off-diagonal element A_{i,i+1} */ /* Right side b_x and b_y */ s1->x = (s2->x - s1->x) * 6.0; s1->y = (s2->y - s1->y) * 6.0; /* * If the linear stroke shows a cusp of more than 90 degree, * the right side is reduced to avoid oscillations in the * spline: */ /* * The Norm of a linear stroke is calculated in "normal coordinates" * and used as interval length: */ dx = s1->x / unitX; dy = s1->y / unitY; norm = sqrt(dx * dx + dy * dy) / 8.5; if (norm > 1.0) { /* The first derivative will not be continuous */ s1->x /= norm; s1->y /= norm; } s1++, s2++; } if (!isClosed) { /* Third derivative is set to zero at both ends */ A[0][1] += A[0][0]; /* A_{0,0} */ A[0][0] = 0.0; /* A_{0,n-1} */ A[n-1][1] += A[n-1][2]; /* A_{n-1,n-1} */ A[n-1][2] = 0.0; /* A_{n-1,0} */ } /* Solve linear systems for dxdt2[] and y[] */ if (SolveCubic1(A, n)) { /* Cholesky decomposition */ SolveCubic2(A, spline, n); /* A * dxdt2 = b_x */ } else { /* Should not happen, but who knows ... */ Blt_Free(A); Blt_Free(spline); return NULL; } /* Shift all second derivatives one place right and update the ends. */ s2 = spline + n, s1 = s2 - 1; for (/* empty */; s2 > spline; s2--, s1--) { s2->x = s1->x; s2->y = s1->y; } if (isClosed) { spline[0].x = spline[n].x; spline[0].y = spline[n].y; } else { /* Third derivative is 0.0 for the first and last interval. */ spline[0].x = spline[1].x; spline[0].y = spline[1].y; spline[n + 1].x = spline[n].x; spline[n + 1].y = spline[n].y; } Blt_Free( A); return spline; } /* * Calculate interpolated values of the spline function (defined via p_cntr * and the second derivatives dxdt2[] and dydt2[]). The number of tabulated * values is n. On an equidistant grid n_intpol values are calculated. */ static int CubicEval(Point2d *origPts, int nOrigPts, Point2d *intpPts, int nIntpPts, CubicSpline *spline) { double t, tSkip, tMax; Point2d q; int i, j, count; /* Sum the lengths of all the segments (intervals). */ tMax = 0.0; for (i = 0; i < nOrigPts - 1; i++) { tMax += spline[i].t; } /* Need a better way of doing this... */ /* The distance between interpolated points */ tSkip = (1. - 1e-7) * tMax / (nIntpPts - 1); t = 0.0; /* Spline parameter value. */ q = origPts[0]; count = 0; intpPts[count++] = q; /* First point. */ t += tSkip; for (i = 0, j = 1; j < nOrigPts; i++, j++) { Point2d p; double d, hx, dx0, dx01, hy, dy0, dy01; d = spline[i].t; /* Interval length */ p = q; q = origPts[i+1]; hx = (q.x - p.x) / d; hy = (q.y - p.y) / d; dx0 = (spline[j].x + 2 * spline[i].x) / 6.0; dy0 = (spline[j].y + 2 * spline[i].y) / 6.0; dx01 = (spline[j].x - spline[i].x) / (6.0 * d); dy01 = (spline[j].y - spline[i].y) / (6.0 * d); while (t <= spline[i].t) { /* t in current interval ? */ p.x += t * (hx + (t - d) * (dx0 + t * dx01)); p.y += t * (hy + (t - d) * (dy0 + t * dy01)); intpPts[count++] = p; t += tSkip; } /* Parameter t relative to start of next interval */ t -= spline[i].t; } return count; } /* * Generate a cubic spline curve through the points (x_i,y_i) which are * stored in the linked list p_cntr. * The spline is defined as a 2d-function s(t) = (x(t),y(t)), where the * parameter t is the length of the linear stroke. */ int Blt_NaturalParametricSpline(Point2d *origPts, int nOrigPts, Region2d *extsPtr, int isClosed, Point2d *intpPts, int nIntpPts) { double unitX, unitY; /* To define norm (x,y)-plane */ CubicSpline *spline; int result; if (nOrigPts < 3) { return 0; } if (isClosed) { origPts[nOrigPts].x = origPts[0].x; origPts[nOrigPts].y = origPts[0].y; nOrigPts++; } /* Width and height of the grid is used at unit length (2d-norm) */ unitX = extsPtr->right - extsPtr->left; unitY = extsPtr->bottom - extsPtr->top; if (unitX < FLT_EPSILON) { unitX = FLT_EPSILON; } if (unitY < FLT_EPSILON) { unitY = FLT_EPSILON; } /* Calculate parameters for cubic spline: * t = arc length of interval. * dxdt2 = second derivatives of x with respect to t, * dydt2 = second derivatives of y with respect to t, */ spline = CubicSlopes(origPts, nOrigPts, isClosed, unitX, unitY); if (spline == NULL) { return 0; } result= CubicEval(origPts, nOrigPts, intpPts, nIntpPts, spline); Blt_Free(spline); return result; } static INLINE void CatromCoeffs(Point2d *p, Point2d *a, Point2d *b, Point2d *c, Point2d *d) { a->x = -p[0].x + 3.0 * p[1].x - 3.0 * p[2].x + p[3].x; b->x = 2.0 * p[0].x - 5.0 * p[1].x + 4.0 * p[2].x - p[3].x; c->x = -p[0].x + p[2].x; d->x = 2.0 * p[1].x; a->y = -p[0].y + 3.0 * p[1].y - 3.0 * p[2].y + p[3].y; b->y = 2.0 * p[0].y - 5.0 * p[1].y + 4.0 * p[2].y - p[3].y; c->y = -p[0].y + p[2].y; d->y = 2.0 * p[1].y; } /* *--------------------------------------------------------------------------- * * Blt_ParametricCatromSpline -- * * Computes a spline based upon the data points, returning a new (larger) * coordinate array of points. * * Results: * None. * *--------------------------------------------------------------------------- */ int Blt_CatromParametricSpline(Point2d *points, int nPoints, Point2d *intpPts, int nIntpPts) { int i; Point2d *origPts; double t; int interval; Point2d a, b, c, d; assert(nPoints > 0); /* * The spline is computed in screen coordinates instead of data points so * that we can select the abscissas of the interpolated points from each * pixel horizontally across the plotting area. */ origPts = Blt_AssertMalloc((nPoints + 4) * sizeof(Point2d)); memcpy(origPts + 1, points, sizeof(Point2d) * nPoints); origPts[0] = origPts[1]; origPts[nPoints + 2] = origPts[nPoints + 1] = origPts[nPoints]; for (i = 0; i < nIntpPts; i++) { interval = (int)intpPts[i].x; t = intpPts[i].y; assert(interval < nPoints); CatromCoeffs(origPts + interval, &a, &b, &c, &d); intpPts[i].x = (d.x + t * (c.x + t * (b.x + t * a.x))) / 2.0; intpPts[i].y = (d.y + t * (c.y + t * (b.y + t * a.y))) / 2.0; } Blt_Free(origPts); return 1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictInt.h������������������������������������������������������������������0000644�0001750�0001750�00000017072�11462120062�015261� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictInt.h -- * * Copyright 2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_PIC_INT_H #define _BLT_PIC_INT_H /* * Scaled integers are fixed point values. The upper 18 bits is the integer * portion, the lower 14 bits the fractional remainder. Must be careful * not to overflow the values (especially during multiplication). * * The following operations are defined: * * S * n Scaled integer times an integer. * S1 + S2 Scaled integer plus another scaled integer. * */ #define float2si(f) (int)((f) * 16383.0 + ((f < 0) ? -0.5 : 0.5)) #define uchar2si(b) (((int)(b)) << 14) #define si2int(s) (((s) + 8192) >> 14) #define int2si(i) (((i) << 14) - 8192) /* * The following macro converts a fixed-point scaled integer to a * byte, clamping the value between 0 and 255. */ #define SICLAMP(s) \ (unsigned char)(((s) < 0) ? 0 : ((s) > 4177920) ? 255 : (si2int(s))) #define div255(i) ((((int)(i) + 1) + (((int)(i) + 1) >> 8) ) >> 8) #define div257(t) (((t)+((t)>>8))>>8) #define mul255(i) (((int)(i) << 8) - ((int)(i))) #define RGBIndex(r,g,b) (((r)<<10) + ((r)<<6) + (r) + ((g) << 5) + (g) + (b)) #define ROTATE_0 0 #define ROTATE_90 1 #define ROTATE_180 2 #define ROTATE_270 3 #define UCLAMP(s) (unsigned char)(((s) < 0) ? 0 : ((s) > 255) ? 255 : (s)) /* *--------------------------------------------------------------------------- * * ResampleFilterProc -- * * A function implementing a 1-D filter. * *--------------------------------------------------------------------------- */ typedef double (Blt_ResampleFilterProc) (double value); /* *--------------------------------------------------------------------------- * * ResampleFilter -- * * Contains information about a 1-D filter (its support and * the procedure implementing the filter). * *--------------------------------------------------------------------------- */ struct _Blt_ResampleFilter { const char *name; /* Name of the filter */ Blt_ResampleFilterProc *proc; /* 1-D filter procedure. */ double support; /* Width of 1-D filter */ }; /* *--------------------------------------------------------------------------- * * TableFilter -- * * Contains information about a 1-D filter (its support and * the procedure implementing the filter). * *--------------------------------------------------------------------------- */ struct _Blt_TableFilter { float scale; int nWeights; /* Width of 1-D filter */ int weights[1]; }; #define RESAMPLE_FILTER 0 #define TABLE_FILTER 1 struct _Blt_ConvolveFilter { int type; void *filter; }; /* *--------------------------------------------------------------------------- * * Filter2D -- * * Defines a convolution mask for a 2-D filter. Used to smooth or * enhance images. * *--------------------------------------------------------------------------- */ typedef struct { double support; /* Radius of filter */ double sum, scale; /* Sum of kernel */ double *kernel; /* Array of values (malloc-ed) representing * the discrete 2-D filter. */ } Filter2D; /* * We can use scaled integers (20-bit fraction) to compute the * luminosity with reasonable accuracy considering it's stored * in an 8-bit result. */ #define YR 223002 /* 0.212671 */ #define YG 749900 /* 0.715160 */ #define YB 75675 /* 0.072169 */ #define YMAX 267386880 /* 255.0 */ #define YCLAMP(s) \ (unsigned char)((s) > YMAX) ? 255 : ((((s) + 524288) >> 20)) #define JITTER(x) ((x) * (0.05 - drand48() * 0.10)) #define JCLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 1.0) ? 1.0 : (c))) typedef union { int i32; /* Fixed point (scaled * integer). 14-bit fraction. */ float f32; } PixelWeight; typedef struct { int start; PixelWeight *wend; /* Points to just beyond the last * weight. Tracks the number of * weights in array below. */ PixelWeight weights[1]; /* Array of weights. */ } Sample; typedef struct _Blt_Picture Pict; typedef struct _Blt_ResampleFilter ResampleFilter; typedef struct _Blt_TableFilter TableFilter; BLT_EXTERN unsigned int Blt_ComputeWeights(unsigned int sw, unsigned int dw, ResampleFilter *filterPtr, Sample **samplePtrPtr); typedef void (Blt_ApplyPictureToPictureProc)(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy, Blt_PictureArithOps op); typedef void (Blt_ApplyScalarToPictureProc)(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_PictureArithOps op); typedef void (Blt_ApplyPictureToPictureWithMaskProc)(Blt_Picture dest, Blt_Picture src, Blt_Picture mask, int x, int y, int w, int h, int dx, int dy, int invert, Blt_PictureArithOps op); typedef void (Blt_ApplyScalarToPictureWithMaskProc)(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_Picture mask, int invert, Blt_PictureArithOps op); typedef void (Blt_TentHorizontallyProc)(Blt_Picture dest, Blt_Picture src); typedef void (Blt_TentVerticallyProc)(Blt_Picture dest, Blt_Picture src); typedef void (Blt_ZoomHorizontallyProc)(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter); typedef void (Blt_ZoomVerticallyProc)(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter); typedef void (Blt_BlendPicturesProc)(Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy); typedef void (Blt_SelectPixelsProc)(Blt_Picture dest, Blt_Picture src, Blt_Pixel *lowPtr , Blt_Pixel *highPtr); typedef void (Blt_AssociateColorsProc)(Blt_Picture picture); typedef void (Blt_UnassociateColorsProc)(Blt_Picture picture); typedef void (Blt_FadePictureProc) (Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy, int alpha); typedef void (Blt_CopyPictureBitsProc)(Blt_Picture dest, Blt_Picture src, int sx, int sy, int w, int h, int dx, int dy); typedef struct { Blt_ApplyPictureToPictureProc *applyPictureToPictureProc; Blt_ApplyScalarToPictureProc *applyScalarToPictureProc; Blt_ApplyPictureToPictureWithMaskProc *applyPictureToPictureWithMaskProc; Blt_ApplyScalarToPictureWithMaskProc *applyScalarToPictureWithMaskProc; Blt_TentHorizontallyProc *tentHorizontallyProc; Blt_TentVerticallyProc *tentVerticallyProc; Blt_ZoomHorizontallyProc *zoomHorizontallyProc; Blt_ZoomVerticallyProc *zoomVerticallyProc; Blt_BlendPicturesProc *blendPicturesProc; Blt_SelectPixelsProc *selectPixelsProc; Blt_AssociateColorsProc *associateColorsProc; Blt_UnassociateColorsProc *unassociateColorsProc; Blt_FadePictureProc *fadePictureProc; Blt_CopyPictureBitsProc *copyPictureBitsProc; } Blt_PictureProcs; BLT_EXTERN Blt_PictureProcs *bltPictProcsPtr; #endif /*_BLT_PIC_INT_H*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrAxis.h�������������������������������������������������������������������0000644�0001750�0001750�00000023740�11462120062�015103� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrAxis.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_GR_AXIS_H #define _BLT_GR_AXIS_H #include "bltList.h" /* *--------------------------------------------------------------------------- * * Grid -- * * Contains attributes of describing how to draw grids (at major ticks) * in the graph. Grids may be mapped to either/both X and Y axis. * *--------------------------------------------------------------------------- */ typedef struct { Blt_Dashes dashes; /* Dash style of the grid. This represents an * array of alternatingly drawn pixel * values. */ int lineWidth; /* Width of the grid lines */ XColor *color; /* Color of the grid lines */ GC gc; /* Graphics context for the grid. */ Segment2d *segments; /* Array of line segments representing the * grid lines */ int nUsed; /* # of axis segments in use. */ int nAllocated; /* # of axis segments allocated. */ } Grid; /* *--------------------------------------------------------------------------- * * AxisRange -- * * Designates a range of values by a minimum and maximum limit. * *--------------------------------------------------------------------------- */ typedef struct { double min, max, range, scale; } AxisRange; /* *--------------------------------------------------------------------------- * * TickLabel -- * * Structure containing the X-Y screen coordinates of the tick * label (anchored at its center). * *--------------------------------------------------------------------------- */ typedef struct { Point2d anchorPos; unsigned int width, height; char string[1]; } TickLabel; /* *--------------------------------------------------------------------------- * * Ticks -- * * Structure containing information where the ticks (major or * minor) will be displayed on the graph. * *--------------------------------------------------------------------------- */ typedef struct { unsigned int nTicks; /* # of ticks on axis */ double values[1]; /* Array of tick values (malloc-ed). */ } Ticks; /* *--------------------------------------------------------------------------- * * TickSweep -- * * Structure containing information where the ticks (major or * minor) will be displayed on the graph. * *--------------------------------------------------------------------------- */ typedef struct { double initial; /* Initial value */ double step; /* Size of interval */ unsigned int nSteps; /* Number of intervals. */ } TickSweep; /* *--------------------------------------------------------------------------- * * Axis -- * * Structure contains options controlling how the axis will be * displayed. * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in axis. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to axes. */ const char *detail; int refCount; /* Number of elements referencing this * axis. */ int logScale; /* If non-zero, generate log scale * ticks for the axis. */ int timeScale; /* If non-zero, generate time scale * ticks for the axis. This option is * overridden by -logscale. */ int descending; /* If non-zero, display the range of * values on the axis in descending * order, from high to low. */ int looseMin, looseMax; /* If non-zero, axis range extends to * the outer major ticks, otherwise at * the limits of the data values. This * is overriddened by setting the -min * and -max options. */ const char *title; /* Title of the axis. */ int titleAlternate; /* Indicates whether to position the * title above/left of the axis. */ Point2d titlePos; /* Position of the title */ unsigned short int titleWidth, titleHeight; int lineWidth; /* Width of lines representing axis * (including ticks). If zero, then * no axis lines or ticks are * drawn. */ const char **limitsFormats; /* One or two strings of sprintf-like * formats describing how to display * virtual axis limits. If NULL, * display no limits. */ int nFormats; TextStyle limitsTextStyle; /* Text attributes (color, font, * rotation, etc.) of the limits. */ double windowSize; /* Size of a sliding window of values * used to scale the axis * automatically as new data values * are added. The axis will always * display the latest values in this * range. */ double shiftBy; /* Shift maximum by this interval. */ int tickLength; /* Length of major ticks in pixels */ const char *formatCmd; /* Specifies a TCL command, to be * invoked by the axis whenever it has * to generate tick labels. */ Tcl_Obj *scrollCmdObjPtr; int scrollUnits; double min, max; /* The actual axis range. */ double reqMin, reqMax; /* Requested axis bounds. Consult the * axisPtr->flags field for * AXIS_CONFIG_MIN and AXIS_CONFIG_MAX * to see if the requested bound have * been set. They override the * computed range of the axis * (determined by auto-scaling). */ double reqScrollMin, reqScrollMax; double scrollMin, scrollMax; /* Defines the scrolling reqion of the * axis. Normally the region is * determined from the data limits. If * specified, these values override * the data-range. */ AxisRange valueRange; /* Range of data values of elements * mapped to this axis. This is used * to auto-scale the axis in "tight" * mode. */ AxisRange axisRange; /* Smallest and largest major tick * values for the axis. The tick * values lie outside the range of * data values. This is used to * auto-scale the axis in "loose" * mode. */ double prevMin, prevMax; double reqStep; /* If > 0.0, overrides the computed major * tick interval. Otherwise a stepsize * is automatically calculated, based * upon the range of elements mapped to the * axis. The default value is 0.0. */ Ticks *t1Ptr; /* Array of major tick positions. May be * set by the user or generated from the * major sweep below. */ Ticks *t2Ptr; /* Array of minor tick positions. May be * set by the user or generated from the * minor sweep below. */ TickSweep minorSweep, majorSweep; int reqNumMajorTicks; /* Default number of ticks to be displayed. */ int reqNumMinorTicks; /* If non-zero, represents the * requested the number of minor ticks * to be uniformally displayed along * each major tick. */ int labelOffset; /* If non-zero, indicates that the tick * label should be offset to sit in the * middle of the next interval. */ /* The following fields are specific to logical axes */ int margin; /* Margin that contains this axis. */ Blt_ChainLink link; /* Axis link in margin list. */ Blt_Chain chain; Segment2d *segments; /* Array of line segments representing * the major and minor ticks, but also * the * axis line itself. The segment * coordinates * are relative to the * axis. */ int nSegments; /* Number of segments in the above * array. */ Blt_Chain tickLabels; /* Contains major tick label strings * and their offsets along the * axis. */ short int left, right, top, bottom; /* Region occupied by the of axis. */ short int width, height; /* Extents of axis */ short int maxTickWidth, maxTickHeight; Blt_Background normalBg; Blt_Background activeBg; XColor *activeFgColor; int relief; int borderWidth; int activeRelief; float tickAngle; Blt_Font tickFont; Tk_Anchor tickAnchor; Tk_Anchor reqTickAnchor; XColor *tickColor; GC tickGC; /* Graphics context for axis and tick * labels */ GC activeTickGC; double titleAngle; Blt_Font titleFont; Tk_Anchor titleAnchor; Tk_Justify titleJustify; XColor *titleColor; Grid major, minor; /* Axis grid information. */ double screenScale; int screenMin, screenRange; } Axis; /* *--------------------------------------------------------------------------- * * Axis2d -- * * The pair of axes mapping a point onto the graph. * *--------------------------------------------------------------------------- */ typedef struct { Axis *x, *y; } Axis2d; /* Axis flags: */ #define AXIS_AUTO_MAJOR (1<<16) /* Auto-generate major ticks. */ #define AXIS_AUTO_MINOR (1<<17) /* Auto-generate minor ticks. */ #define AXIS_ONSCREEN (1<<18) /* Axis is displayed on the screen via * the "use" operation */ #define AXIS_GRID (1<<19) #define AXIS_GRID_MINOR (1<<20) #define AXIS_TICKS (1<<21) #define AXIS_TICKS_INTERIOR (1<<22) #define AXIS_CHECK_LIMITS (1<<23) #define AXIS_LOGSCALE (1<<24) #define AXIS_DECREASING (1<<25) #endif /* _BLT_GR_AXIS_H */ ��������������������������������./saods9/blt3.0.1/src/tkButton.c��������������������������������������������������������������������0000644�0001750�0001750�00000214742�11462120063�015016� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkButton.c -- * * This module implements a collection of button-like * widgets for the Tk toolkit. The widgets implemented * include labels, buttons, check buttons, and radio * buttons. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkButton.c 1.128 96/03/01 17:34:49 */ #include "bltInt.h" #ifndef NO_TKBUTTON #include "bltBgStyle.h" #include "bltFont.h" #include "bltText.h" #include "bltImage.h" #include "bltPicture.h" #include "bltPainter.h" #define GAP 4 /* * The definitions below provide symbolic names for the default colors. * NORMAL_BG - Normal background color. * ACTIVE_BG - Background color when widget is active. * SELECT_BG - Background color for selected text. * TROUGH - Background color for troughs in scales and scrollbars. * INDICATOR - Color for indicator when button is selected. * DISABLED - Foreground color when widget is disabled. */ #define NORMAL_BG "#d9d9d9" #define ACTIVE_BG "#ececec" #define SELECT_BG "#c3c3c3" #define TROUGH "#c3c3c3" #define INDICATOR "#b03060" #define DISABLED "#a3a3a3" #define DEF_BUTTON_ANCHOR "center" #define DEF_BUTTON_ACTIVE_BACKGROUND STD_ACTIVE_BACKGROUND #define DEF_BUTTON_ACTIVE_BG_MONO RGB_BLACK #define DEF_BUTTON_ACTIVE_FOREGROUND RGB_BLACK #define DEF_BUTTON_ACTIVE_FG_MONO RGB_WHITE #define DEF_BUTTON_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_BUTTON_BG_MONO RGB_WHITE #define DEF_BUTTON_BITMAP "" #define DEF_BUTTON_BORDERWIDTH "2" #define DEF_PUSHBUTTON_BORDERWIDTH "1" #define DEF_BUTTON_CURSOR "" #define DEF_BUTTON_COMMAND "" #define DEF_BUTTON_COMPOUND "none" #define DEF_BUTTON_DEFAULT "disabled" #define DEF_BUTTON_DISABLED_FOREGROUND STD_DISABLED_FOREGROUND #define DEF_BUTTON_DISABLED_FG_MONO "" #define DEF_BUTTON_FG RGB_BLACK #define DEF_BUTTON_FONT STD_FONT #define DEF_BUTTON_HEIGHT "0" #define DEF_BUTTON_HIGHLIGHT_BG STD_NORMAL_BACKGROUND #define DEF_BUTTON_HIGHLIGHT RGB_BLACK #define DEF_LABEL_HIGHLIGHT_WIDTH "0" #define DEF_PUSHBUTTON_HIGHLIGHT_WIDTH "0" #define DEF_BUTTON_HIGHLIGHT_WIDTH "2" #define DEF_BUTTON_IMAGE (char *) NULL #define DEF_BUTTON_INDICATOR "1" #define DEF_BUTTON_JUSTIFY "center" #define DEF_BUTTON_OFF_VALUE "0" #define DEF_BUTTON_ON_VALUE "1" #define DEF_BUTTON_ONIMAGE (char *)NULL #define DEF_BUTTON_OFFIMAGE (char *)NULL #define DEF_BUTTON_OVER_RELIEF "raised" #define DEF_BUTTON_PADX "3m" #define DEF_LABCHKRAD_PADX "1" #define DEF_BUTTON_PADY "1m" #define DEF_LABCHKRAD_PADY "1" #define DEF_PUSHBUTTON_PADX "2" #define DEF_PUSHBUTTON_PADY "2" #define DEF_BUTTON_RELIEF "raised" #define DEF_BUTTON_REPEAT_DELAY "0" #define DEF_LABCHKRAD_RELIEF "flat" #define DEF_LABCHKRAD_OVER_RELIEF "flat" #define DEF_BUTTON_SELECT_BACKGROUND RGB_WHITE #define DEF_BUTTON_SELECT_FOREGROUND STD_INDICATOR_COLOR #define DEF_BUTTON_SELECT_MONO RGB_BLACK #define DEF_BUTTON_SELECT_IMAGE (char *)NULL #define DEF_BUTTON_STATE "normal" #define DEF_LABEL_TAKE_FOCUS "0" #define DEF_BUTTON_TAKE_FOCUS (char *) NULL #define DEF_BUTTON_TEXT "" #define DEF_BUTTON_TEXT_VARIABLE "" #define DEF_BUTTON_UNDERLINE "-1" #define DEF_BUTTON_VALUE "" #define DEF_BUTTON_WIDTH "0" #define DEF_BUTTON_WRAP_LENGTH "0" #define DEF_RADIOBUTTON_VARIABLE "selectedButton" #define DEF_CHECKBUTTON_VARIABLE "" /* * A data structure of the following type is kept for each * widget managed by this file: */ typedef struct { Tk_Window tkwin; /* Window that embodies the button. NULL * means that the window has been destroyed. */ Display *display; /* Display containing widget. Needed to * free up resources after tkwin is gone. */ Tcl_Interp *interp; /* Interpreter associated with button. */ Tcl_Command widgetCmd; /* Token for button's widget command. */ int type; /* Type of widget: restricts operations * that may be performed on widget. See * below for possible values. */ /* * Information about what's in the button. */ const char *text; /* Text to display in button (malloc'ed) * or NULL. */ int numChars; /* # of characters in text. */ int underline; /* Index of character to underline. < 0 means * don't underline anything. */ const char *textVarName; /* Name of variable (malloc'ed) or NULL. * If non-NULL, button displays the contents * of this variable. */ Pixmap bitmap; /* Bitmap to display or None. If not None * then text and textVar are ignored. */ Tk_Image image; /* Image to display in window, or NULL if * none. */ Tk_Image selectImage; /* Image to display in window when selected, * or NULL if none. Ignored if image is * NULL. */ /* * Information used when displaying widget: */ int state; /* State of button for display purposes: * normal, active, or disabled. */ Blt_Background normalBg; /* Structure used to draw 3-D * border and background when window * isn't active. NULL means no such * border exists. */ Blt_Background activeBg; /* Structure used to draw 3-D * border and background when window * is active. NULL means no such * border exists. */ int borderWidth; /* Width of border. */ int relief; /* 3-d effect: TK_RELIEF_RAISED, etc. */ int overRelief; /* Value of -overrelief option: specifies a 3-d * effect for the border, such as * TK_RELIEF_RAISED, to be used when the mouse * is over the button. */ int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ XColor *highlightBgColorPtr; /* Color for drawing traversal highlight * area when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. * Indicates how much interior stuff must * be offset from outside edges to leave * room for borders. */ Blt_Font font; /* Information about text font, or NULL. */ XColor *normalFg; /* Foreground color in normal mode. */ XColor *activeFg; /* Foreground color in active mode. NULL * means use normalFg instead. */ XColor *disabledFg; /* Foreground color when disabled. NULL * means use normalFg with a 50% stipple * instead. */ GC normalTextGC; /* GC for drawing text in normal mode. Also * used to copy from off-screen pixmap onto * screen. */ GC activeTextGC; /* GC for drawing text in active mode (NULL * means use normalTextGC). */ Pixmap gray; /* Pixmap for displaying disabled text if * disabledFg is NULL. */ GC disabledGC; /* Used to produce disabled effect. If * disabledFg isn't NULL, this GC is used to * draw button text or icon. Otherwise * text or icon is drawn with normalGC and * this GC is used to stipple background * across it. For labels this is None. */ GC copyGC; /* Used for copying information from an * off-screen pixmap to the screen. */ const char *widthString; /* Value of -width option. Malloc'ed. */ const char *heightString; /* Value of -height option. Malloc'ed. */ int width, height; /* If > 0, these specify dimensions to request * for window, in characters for text and in * pixels for bitmaps. In this case the actual * size of the text string or bitmap is * ignored in computing desired window size. */ int wrapLength; /* Line length (in pixels) at which to wrap * onto next line. <= 0 means don't wrap * except at newlines. */ int xPad, yPad; /* Extra space around text (pixels to leave * on each side). Ignored for bitmaps and * images. */ Tk_Anchor anchor; /* Where text/bitmap should be displayed * inside button region. */ Tk_Justify justify; /* Justification to use for multi-line text. */ int indicatorOn; /* True means draw indicator, false means * don't draw it. */ Blt_Background selectBg; /* For drawing indicator background, or perhaps * widget background, when selected. */ XColor *selectFg; /* For drawing indicator background, or perhaps * widget background, when selected. */ int textWidth; /* Width needed to display text as requested, * in pixels. */ int textHeight; /* Height needed to display text as requested, * in pixels. */ Tk_TextLayout textLayout; /* Saved text layout information. */ int indicatorSpace; /* Horizontal space (in pixels) allocated for * display of indicator. */ int indicatorDiameter; /* Diameter of indicator, in pixels. */ int defaultState; /* Used in 8.0 (not here) */ /* * For check and radio buttons, the fields below are used * to manage the variable indicating the button's state. */ const char *selVarName; /* Name of variable used to control selected * state of button. Malloc'ed (if * not NULL). */ const char *onValue; /* Value to store in variable when * this button is selected. Malloc'ed (if * not NULL). */ const char *offValue; /* Value to store in variable when this * button isn't selected. Malloc'ed * (if not NULL). Valid only for check * buttons. */ /* * Miscellaneous information: */ Tk_Cursor cursor; /* Current cursor for window, or None. */ const char *takeFocus; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ const char *command; /* Command to execute when button is * invoked; valid for buttons only. * If not NULL, it's malloc-ed. */ const char *compound; /* Value of -compound option; specifies whether * the button should show both an image and * text, and, if so, how. */ int repeatDelay; /* Value of -repeatdelay option; specifies * the number of ms after which the button will * start to auto-repeat its command. */ int repeatInterval; /* Value of -repeatinterval option; specifies * the number of ms between auto-repeat * invocataions of the button command. */ int flags; /* Various flags; see below for * definitions. */ Blt_Picture selectedPicture; Blt_Picture normalPicture; Blt_Picture disabledPicture; } Button; /* * Possible "type" values for buttons. These are the kinds of * widgets supported by this file. The ordering of the type * numbers is significant: greater means more features and is * used in the code. */ #define TYPE_LABEL 0 #define TYPE_BUTTON 1 #define TYPE_PUSH_BUTTON 2 #define TYPE_CHECK_BUTTON 3 #define TYPE_RADIO_BUTTON 4 /* * Class names for buttons, indexed by one of the type values above. */ static const char *classNames[] = { "TkLabel", "TkButton", "TkPushbutton", "TkCheckbutton", "TkRadiobutton", }; /* * Flag bits for buttons: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler * has already been queued to redraw * this window. * SELECTED: Non-zero means this button is selected, * so special highlight should be drawn. * GOT_FOCUS: Non-zero means this button currently * has the input focus. */ #define REDRAW_PENDING 1 #define SELECTED 2 #define GOT_FOCUS 4 /* * Mask values used to selectively enable entries in the * configuration specs: */ #define LABEL_MASK BLT_CONFIG_USER_BIT #define BUTTON_MASK BLT_CONFIG_USER_BIT << 1 #define PUSH_BUTTON_MASK BLT_CONFIG_USER_BIT << 2 #define CHECK_BUTTON_MASK BLT_CONFIG_USER_BIT << 3 #define RADIO_BUTTON_MASK BLT_CONFIG_USER_BIT << 4 #define ALL_MASK (LABEL_MASK | BUTTON_MASK \ | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK) #define ALL_BUTTONS (BUTTON_MASK | CHECK_BUTTON_MASK | \ RADIO_BUTTON_MASK | PUSH_BUTTON_MASK) static int configFlags[] = { LABEL_MASK, BUTTON_MASK, PUSH_BUTTON_MASK, CHECK_BUTTON_MASK, RADIO_BUTTON_MASK }; static Blt_OptionParseProc ObjToImageProc; static Blt_OptionPrintProc ImageToObjProc; static Blt_OptionFreeProc FreeImageProc; static Blt_CustomOption imageOption = { ObjToImageProc, ImageToObjProc, FreeImageProc, (ClientData)0 }; /* * Information used for parsing configuration specs: */ static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BACKGROUND, Blt_Offset(Button, activeBg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BG_MONO, Blt_Offset(Button, activeBg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", DEF_BUTTON_ACTIVE_FOREGROUND, Blt_Offset(Button, activeFg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", DEF_BUTTON_ACTIVE_FG_MONO, Blt_Offset(Button, activeFg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_BUTTON_ANCHOR, Blt_Offset(Button, anchor), ALL_MASK}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BUTTON_BACKGROUND, Blt_Offset(Button, normalBg), ALL_MASK | BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BUTTON_BG_MONO, Blt_Offset(Button, normalBg), ALL_MASK | BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, ALL_MASK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, ALL_MASK}, {BLT_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_BUTTON_BITMAP, Blt_Offset(Button, bitmap), ALL_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BUTTON_BORDERWIDTH, Blt_Offset(Button, borderWidth), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | LABEL_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_PUSHBUTTON_BORDERWIDTH, Blt_Offset(Button, borderWidth), PUSH_BUTTON_MASK}, {BLT_CONFIG_STRING, "-command", "command", "Command", DEF_BUTTON_COMMAND, Blt_Offset(Button, command), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, Blt_Offset(Button, compound), ALL_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUTTON_CURSOR, Blt_Offset(Button, cursor), ALL_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STATE, "-default", "default", "Default", DEF_BUTTON_DEFAULT, Blt_Offset(Button, defaultState), BUTTON_MASK}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_BUTTON_DISABLED_FOREGROUND, Blt_Offset(Button, disabledFg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_COLOR_ONLY | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_BUTTON_DISABLED_FG_MONO, Blt_Offset(Button, disabledFg), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | BLT_CONFIG_MONO_ONLY | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, ALL_MASK}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_BUTTON_FONT, Blt_Offset(Button, font), ALL_MASK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_BUTTON_FG, Blt_Offset(Button, normalFg), ALL_MASK}, {BLT_CONFIG_STRING, "-height", "height", "Height", DEF_BUTTON_HEIGHT, Blt_Offset(Button, heightString), ALL_MASK}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG, Blt_Offset(Button, highlightBgColorPtr), ALL_MASK}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_BUTTON_HIGHLIGHT, Blt_Offset(Button, highlightColorPtr), ALL_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_LABEL_HIGHLIGHT_WIDTH, Blt_Offset(Button, highlightWidth), PUSH_BUTTON_MASK | LABEL_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH, Blt_Offset(Button, highlightWidth), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", DEF_BUTTON_IMAGE, Blt_Offset(Button, image), ALL_MASK | BLT_CONFIG_NULL_OK, &imageOption}, {BLT_CONFIG_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", DEF_BUTTON_INDICATOR, Blt_Offset(Button, indicatorOn), CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_BUTTON_JUSTIFY, Blt_Offset(Button, justify), ALL_MASK}, {BLT_CONFIG_SYNONYM, "-offimage", "image", (char *)NULL, (char *)NULL, 0, CHECK_BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_STRING, "-offvalue", "offValue", "Value", DEF_BUTTON_OFF_VALUE, Blt_Offset(Button, offValue), CHECK_BUTTON_MASK | PUSH_BUTTON_MASK }, {BLT_CONFIG_STRING, "-onvalue", "onValue", "Value", DEF_BUTTON_ON_VALUE, Blt_Offset(Button, onValue), CHECK_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK }, {BLT_CONFIG_SYNONYM, "-onimage", "selectImage", (char *)NULL, (char *)NULL, 0, CHECK_BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_RELIEF, "-overrelief", "overRelief", "OverRelief", DEF_BUTTON_OVER_RELIEF, Blt_Offset(Button, overRelief), BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_RELIEF, "-overrelief", "overRelief", "OverRelief", DEF_LABCHKRAD_OVER_RELIEF, Blt_Offset(Button, overRelief), LABEL_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-padx", "padX", "Pad", DEF_BUTTON_PADX, Blt_Offset(Button, xPad), BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-padx", "padX", "Pad", DEF_LABCHKRAD_PADX, Blt_Offset(Button, xPad), LABEL_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-padx", "padX", "Pad", DEF_PUSHBUTTON_PADX, Blt_Offset(Button, xPad), PUSH_BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-pady", "padY", "Pad", DEF_BUTTON_PADY, Blt_Offset(Button, yPad), BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-pady", "padY", "Pad", DEF_LABCHKRAD_PADY, Blt_Offset(Button, yPad), LABEL_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-pady", "padY", "Pad", DEF_PUSHBUTTON_PADY, Blt_Offset(Button, yPad), PUSH_BUTTON_MASK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_BUTTON_RELIEF, Blt_Offset(Button, relief), BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_LABCHKRAD_RELIEF, Blt_Offset(Button, relief), LABEL_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK}, {BLT_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", DEF_BUTTON_REPEAT_DELAY, Blt_Offset(Button, repeatDelay), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "SelectForeground", DEF_BUTTON_SELECT_FOREGROUND, Blt_Offset(Button, selectFg), CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "SelectBackground", DEF_BUTTON_SELECT_BACKGROUND, Blt_Offset(Button, selectBg), CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-selectcolor", "selectBackground", (char *)NULL, (char *)NULL, 0, CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-selectimage", "selectImage", "SelectImage", DEF_BUTTON_SELECT_IMAGE, Blt_Offset(Button, selectImage), CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK, &imageOption}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_BUTTON_STATE, Blt_Offset(Button, state), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_LABEL_TAKE_FOCUS, Blt_Offset(Button, takeFocus), LABEL_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_BUTTON_TAKE_FOCUS, Blt_Offset(Button, takeFocus), BUTTON_MASK | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-text", "text", "Text", DEF_BUTTON_TEXT, Blt_Offset(Button, text), ALL_MASK}, {BLT_CONFIG_STRING, "-textvariable", "textVariable", "Variable", DEF_BUTTON_TEXT_VARIABLE, Blt_Offset(Button, textVarName), ALL_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_INT, "-underline", "underline", "Underline", DEF_BUTTON_UNDERLINE, Blt_Offset(Button, underline), ALL_MASK}, {BLT_CONFIG_STRING, "-value", "value", "Value", DEF_BUTTON_VALUE, Blt_Offset(Button, onValue), RADIO_BUTTON_MASK}, {BLT_CONFIG_STRING, "-variable", "variable", "Variable", DEF_RADIOBUTTON_VARIABLE, Blt_Offset(Button, selVarName), RADIO_BUTTON_MASK}, {BLT_CONFIG_STRING, "-variable", "variable", "Variable", DEF_CHECKBUTTON_VARIABLE, Blt_Offset(Button, selVarName), CHECK_BUTTON_MASK | PUSH_BUTTON_MASK | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-width", "width", "Width", DEF_BUTTON_WIDTH, Blt_Offset(Button, widthString), ALL_MASK}, {BLT_CONFIG_PIXELS_NNEG, "-wraplength", "wrapLength", "WrapLength", DEF_BUTTON_WRAP_LENGTH, Blt_Offset(Button, wrapLength), ALL_MASK}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* * String to print out in error messages, identifying options for * widget commands for different types of labels or buttons: */ static const char *optionStrings[] = { "cget or configure", "cget, configure, flash, or invoke", "cget, configure, deselect, flash, invoke, select, or toggle", "cget, configure, deselect, flash, invoke, or select" }; /* * Forward declarations for procedures defined later in this file: */ static void ButtonCmdDeletedProc _ANSI_ARGS_((ClientData clientData)); static int ButtonCreate _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int type)); static void ButtonEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static char *ButtonTextVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags)); static char *ButtonVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags)); static int ButtonWidgetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)); static void ComputeButtonGeometry _ANSI_ARGS_((Button *butPtr)); static int ConfigureButton _ANSI_ARGS_((Tcl_Interp *interp, Button *butPtr, int objc, Tcl_Obj *const *objv, int flags)); static void DestroyButton _ANSI_ARGS_((Button *butPtr)); static void DisplayButton _ANSI_ARGS_((ClientData clientData)); static int InvokeButton _ANSI_ARGS_((Button *butPtr)); static Tcl_ObjCmdProc ButtonCmd, LabelCmd, CheckbuttonCmd, RadiobuttonCmd; #ifndef USE_TK_STUBS BLT_EXTERN int TkCopyAndGlobalEval _ANSI_ARGS_((Tcl_Interp *interp, char *script)); BLT_EXTERN void TkComputeAnchor _ANSI_ARGS_((Tk_Anchor anchor, Tk_Window tkwin, int xPad, int yPad, int innerWidth, int innerHeight, int *xPtr, int *yPtr)); #endif /* *--------------------------------------------------------------------------- * * ImageChangedProc * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { Button *butPtr = clientData; if (butPtr->tkwin != NULL) { ComputeButtonGeometry(butPtr); if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayButton, (ClientData)butPtr); butPtr->flags |= REDRAW_PENDING; } } } /*ARGSUSED*/ static void FreeImageProc(ClientData clientData, Display *display, char *widgRec, int offset) { Tk_Image *imagePtr = (Tk_Image *)(widgRec + offset); if (*imagePtr != NULL) { Tk_FreeImage(*imagePtr); *imagePtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToImageProc -- * * Given an image name, get the Tk image associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToImageProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Button *butPtr = (Button *)(widgRec); Tk_Image *imagePtr = (Tk_Image *)(widgRec + offset); Tk_Image image; image = Tk_GetImage(interp, butPtr->tkwin, Tcl_GetString(objPtr), ImageChangedProc, butPtr); if (image == NULL) { return TCL_ERROR; } *imagePtr = image; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImageToObjProc -- * * Convert the image name into a string Tcl_Obj. * * Results: * The string representation of the image is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ImageToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tk_Image image = *(Tk_Image *)(widgRec + offset); if (image == NULL) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(Blt_Image_Name(image), -1); } /* *--------------------------------------------------------------------------- * * ButtonCmd, CheckbuttonCmd, LabelCmd, RadiobuttonCmd, PushbuttonCmd -- * * These procedures are invoked to process the "button", "label", * "radiobutton", "checkbutton", and "pushbutton" TCL commands. * See the user documentation for details on what they do. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. These procedures are just wrappers; * they call ButtonCreate to do all of the real work. * *--------------------------------------------------------------------------- */ static int ButtonCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON); } static int CheckbuttonCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON); } static int LabelCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL); } static int RadiobuttonCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON); } static int PushbuttonCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return ButtonCreate(clientData, interp, objc, objv, TYPE_PUSH_BUTTON); } /* *--------------------------------------------------------------------------- * * ButtonCreate -- * * This procedure does all the real work of implementing the * "button", "label", "radiobutton", and "checkbutton" Tcl * commands. See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ButtonCreate( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv, /* Argument strings. */ int type) /* Type of button to create: TYPE_LABEL, * TYPE_BUTTON, TYPE_CHECK_BUTTON, or * TYPE_RADIO_BUTTON. */ { Button *butPtr; Tcl_CmdInfo cmdInfo; Tk_Window tkwin; char *path; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?options?\"", (char *)NULL); return TCL_ERROR; } /* * First time in this interpreter, set up procs and initialize various * bindings for the widget. If the proc doesn't already exist, source it * from "$blt_library/comboentry.tcl". We've deferred sourcing this file * until now so that the user could reset the variable $blt_library from * within her script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Button::Up", &cmdInfo)) { static char cmd[] = "source [file join $blt_library pushbutton.tcl]"; if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } /* * Create the new window. */ path = Tcl_GetString(objv[1]); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), path, (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } /* * Initialize the data structure for the button. */ butPtr = Blt_AssertCalloc(1, sizeof(Button)); butPtr->tkwin = tkwin; butPtr->display = Tk_Display(tkwin); butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(butPtr->tkwin), ButtonWidgetCmd, butPtr, ButtonCmdDeletedProc); butPtr->interp = interp; butPtr->type = type; butPtr->underline = -1; butPtr->state = STATE_NORMAL; butPtr->relief = TK_RELIEF_FLAT; butPtr->anchor = TK_ANCHOR_CENTER; butPtr->justify = TK_JUSTIFY_CENTER; butPtr->defaultState = STATE_DISABLED; butPtr->overRelief = TK_RELIEF_RAISED; Tk_SetClass(tkwin, classNames[type]); Tk_CreateEventHandler(butPtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, ButtonEventProc, butPtr); if (ConfigureButton(interp, butPtr, objc - 2, objv + 2, configFlags[type]) != TCL_OK) { Tk_DestroyWindow(butPtr->tkwin); return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(butPtr->tkwin), -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonWidgetCmd -- * * This procedure is invoked to process the TCL command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int ButtonWidgetCmd( ClientData clientData, /* Information about button widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Button *butPtr = clientData; char *string; int c; int length; int result = TCL_OK; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } Tcl_Preserve(butPtr); string = Tcl_GetStringFromObj(objv[1], &length); c = string[0]; if ((c == 'c') && (length >= 2) && (strncmp(string, "cget", length) == 0)) { if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " cget option\"", (char *)NULL); goto error; } result = Blt_ConfigureValueFromObj(interp, butPtr->tkwin, configSpecs, (char *)butPtr, objv[2], configFlags[butPtr->type]); } else if ((c == 'c') && (length >= 2) && (strncmp(string, "configure", length) == 0)) { if (objc == 2) { result = Blt_ConfigureInfoFromObj(interp, butPtr->tkwin, configSpecs, (char *)butPtr, (Tcl_Obj *)NULL, configFlags[butPtr->type]); } else if (objc == 3) { result = Blt_ConfigureInfoFromObj(interp, butPtr->tkwin, configSpecs, (char *)butPtr, objv[2], configFlags[butPtr->type]); } else { result = ConfigureButton(interp, butPtr, objc - 2, objv + 2, configFlags[butPtr->type] | BLT_CONFIG_OBJV_ONLY); } } else if ((c == 'd') && (strncmp(string, "deselect", length) == 0) && (butPtr->type >= TYPE_PUSH_BUTTON)) { if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " deselect\"", (char *)NULL); goto error; } if ((butPtr->type == TYPE_CHECK_BUTTON) || (butPtr->type == TYPE_PUSH_BUTTON)) { if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->offValue, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; } } else if (butPtr->flags & SELECTED) { if (Tcl_SetVar(interp, butPtr->selVarName, "", TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; }; } } else if ((c == 'f') && (strncmp(string, "flash", length) == 0) && (butPtr->type != TYPE_LABEL)) { int i; if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " flash\"", (char *)NULL); goto error; } if (butPtr->state != STATE_DISABLED) { for (i = 0; i < 4; i++) { butPtr->state = (butPtr->state == STATE_NORMAL) ? STATE_ACTIVE : STATE_NORMAL; Blt_SetBackgroundFromBackground(butPtr->tkwin, (butPtr->state == STATE_ACTIVE) ? butPtr->activeBg : butPtr->normalBg); DisplayButton(butPtr); /* * Special note: must cancel any existing idle handler * for DisplayButton; it's no longer needed, and DisplayButton * cleared the REDRAW_PENDING flag. */ Tcl_CancelIdleCall(DisplayButton, butPtr); #if !defined(WIN32) && !defined(MACOSX) XFlush(butPtr->display); #endif Tcl_Sleep(50); } } } else if ((c == 'i') && (strncmp(string, "invoke", length) == 0) && (butPtr->type > TYPE_LABEL)) { if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " invoke\"", (char *)NULL); goto error; } if (butPtr->state != STATE_DISABLED) { result = InvokeButton(butPtr); } } else if ((c == 's') && (strncmp(string, "select", length) == 0) && (butPtr->type >= TYPE_PUSH_BUTTON)) { if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " select\"", (char *)NULL); goto error; } if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->onValue, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; } } else if ((c == 't') && (strncmp(string, "toggle", length) == 0) && (length >= 2) && (butPtr->type == TYPE_PUSH_BUTTON)) { if (objc > 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " toggle\"", (char *)NULL); goto error; } if (butPtr->flags & SELECTED) { if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->offValue, TCL_GLOBAL_ONLY) == NULL) { result = TCL_ERROR; } } else { if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->onValue, TCL_GLOBAL_ONLY) == NULL) { result = TCL_ERROR; } } } else { Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be ", optionStrings[butPtr->type], (char *)NULL); goto error; } Tcl_Release(butPtr); return result; error: Tcl_Release(butPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DestroyButton -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a button at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyButton(Button *butPtr) { /* * Free up all the stuff that requires special handling, then * let Blt_FreeOptions handle all the standard option-related * stuff. */ if (butPtr->textVarName != NULL) { Tcl_UntraceVar(butPtr->interp, butPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonTextVarProc, butPtr); } if (butPtr->normalTextGC != None) { Tk_FreeGC(butPtr->display, butPtr->normalTextGC); } if (butPtr->activeTextGC != None) { Tk_FreeGC(butPtr->display, butPtr->activeTextGC); } if (butPtr->gray != None) { Tk_FreeBitmap(butPtr->display, butPtr->gray); } if (butPtr->disabledGC != None) { Tk_FreeGC(butPtr->display, butPtr->disabledGC); } if (butPtr->copyGC != None) { Tk_FreeGC(butPtr->display, butPtr->copyGC); } if (butPtr->selVarName != NULL) { Tcl_UntraceVar(butPtr->interp, butPtr->selVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonVarProc, (ClientData)butPtr); } Tk_FreeTextLayout(butPtr->textLayout); Blt_FreeOptions(configSpecs, (char *)butPtr, butPtr->display, configFlags[butPtr->type]); Tcl_EventuallyFree((ClientData)butPtr, TCL_DYNAMIC); } /* *--------------------------------------------------------------------------- * * ConfigureButton -- * * This procedure is called to process an objv/objc list, plus * the Tk option database, in order to configure (or * reconfigure) a button widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for butPtr; old resources get freed, if there * were any. The button is redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureButton( Tcl_Interp *interp, /* Used for error reporting. */ Button *butPtr, /* Information about widget; may or may * not already have values for some fields. */ int objc, /* Number of valid entries in objv. */ Tcl_Obj *const *objv, /* Arguments. */ int flags) /* Flags to pass to Blt_ConfigureWidget. */ { XGCValues gcValues; GC newGC; unsigned long mask; /* * Eliminate any existing trace on variables monitored by the button. */ if (butPtr->textVarName != NULL) { Tcl_UntraceVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonTextVarProc, butPtr); } if (butPtr->selVarName != NULL) { Tcl_UntraceVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonVarProc, butPtr); } if (Blt_ConfigureWidgetFromObj(interp, butPtr->tkwin, configSpecs, objc, objv, (char *)butPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few options need special processing, such as setting the * background from a 3-D border, or filling in complicated * defaults that couldn't be specified to Blt_ConfigureWidget. */ if ((butPtr->state == STATE_ACTIVE) && !Tk_StrictMotif(butPtr->tkwin)) { Blt_SetBackgroundFromBackground(butPtr->tkwin, butPtr->activeBg); } else { Blt_SetBackgroundFromBackground(butPtr->tkwin, butPtr->normalBg); if ((butPtr->state != STATE_NORMAL) && (butPtr->state != STATE_ACTIVE) && (butPtr->state != STATE_DISABLED)) { Tcl_AppendResult(interp, "bad state value \"", Blt_Itoa(butPtr->state), "\": must be normal, active, or disabled", (char *)NULL); butPtr->state = STATE_NORMAL; return TCL_ERROR; } } if ((butPtr->defaultState != STATE_ACTIVE) && (butPtr->defaultState != STATE_DISABLED) && (butPtr->defaultState != STATE_NORMAL)) { Tcl_AppendResult(interp, "bad -default value \"", butPtr->defaultState, "\": must be normal, active, or disabled", (char *)NULL); butPtr->defaultState = STATE_DISABLED; return TCL_ERROR; } if (butPtr->highlightWidth < 0) { butPtr->highlightWidth = 0; } gcValues.font = Blt_FontId(butPtr->font); gcValues.foreground = butPtr->normalFg->pixel; gcValues.background = Blt_BackgroundBorderColor(butPtr->normalBg)->pixel; /* * Note: GraphicsExpose events are disabled in normalTextGC because it's * used to copy stuff from an off-screen pixmap onto the screen (we know * that there's no problem with obscured areas). */ gcValues.graphics_exposures = False; newGC = Tk_GetGC(butPtr->tkwin, GCForeground | GCBackground | GCFont | GCGraphicsExposures, &gcValues); if (butPtr->normalTextGC != None) { Tk_FreeGC(butPtr->display, butPtr->normalTextGC); } butPtr->normalTextGC = newGC; if (butPtr->activeFg != NULL) { gcValues.font = Blt_FontId(butPtr->font); gcValues.foreground = butPtr->activeFg->pixel; gcValues.background = Blt_BackgroundBorderColor(butPtr->activeBg)->pixel; newGC = Tk_GetGC(butPtr->tkwin, GCForeground | GCBackground | GCFont, &gcValues); if (butPtr->activeTextGC != None) { Tk_FreeGC(butPtr->display, butPtr->activeTextGC); } butPtr->activeTextGC = newGC; } if (butPtr->type != TYPE_LABEL) { gcValues.font = Blt_FontId(butPtr->font); gcValues.background = Blt_BackgroundBorderColor(butPtr->normalBg)->pixel; if ((butPtr->disabledFg != NULL) && (butPtr->image == NULL)) { gcValues.foreground = butPtr->disabledFg->pixel; mask = GCForeground | GCBackground | GCFont; } else { gcValues.foreground = gcValues.background; if (butPtr->gray == None) { butPtr->gray = Tk_GetBitmap(interp, butPtr->tkwin, Tk_GetUid("gray50")); if (butPtr->gray == None) { return TCL_ERROR; } } gcValues.fill_style = FillStippled; gcValues.stipple = butPtr->gray; mask = GCForeground | GCFillStyle | GCStipple; } newGC = Tk_GetGC(butPtr->tkwin, mask, &gcValues); if (butPtr->disabledGC != None) { Tk_FreeGC(butPtr->display, butPtr->disabledGC); } butPtr->disabledGC = newGC; } if (butPtr->copyGC == None) { butPtr->copyGC = Tk_GetGC(butPtr->tkwin, 0, &gcValues); } if (butPtr->xPad < 0) { butPtr->xPad = 0; } if (butPtr->yPad < 0) { butPtr->yPad = 0; } if (butPtr->type >= TYPE_PUSH_BUTTON) { const char *value; if (butPtr->selVarName == NULL) { butPtr->selVarName = Blt_AssertStrdup(Tk_Name(butPtr->tkwin)); } /* * Select the button if the associated variable has the * appropriate value, initialize the variable if it doesn't * exist, then set a trace on the variable to monitor future * changes to its value. */ value = Tcl_GetVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY); butPtr->flags &= ~SELECTED; if (value != NULL) { if (strcmp(value, butPtr->onValue) == 0) { butPtr->flags |= SELECTED; } } else { const char *value; value = ((butPtr->type == TYPE_CHECK_BUTTON) || (butPtr->type == TYPE_PUSH_BUTTON)) ? butPtr->offValue : ""; if (Tcl_SetVar(interp, butPtr->selVarName, value, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } Tcl_TraceVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonVarProc, (ClientData)butPtr); } /* * Get the images for the widget, if there are any. Allocate the * new images before freeing the old ones, so that the reference * counts don't go to zero and cause image data to be discarded. */ if ((butPtr->image == NULL) && (butPtr->bitmap == None) && (butPtr->textVarName != NULL)) { /* * The button must display the value of a variable: set up a trace * on the variable's value, create the variable if it doesn't * exist, and fetch its current value. */ const char *value; value = Tcl_GetVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY); if (value == NULL) { if (Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } else { if (butPtr->text != NULL) { Blt_Free(butPtr->text); } butPtr->text = Blt_AssertStrdup(value); } Tcl_TraceVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonTextVarProc, (ClientData)butPtr); } if ((butPtr->bitmap != None) || (butPtr->image != NULL)) { if (Tk_GetPixels(interp, butPtr->tkwin, butPtr->widthString, &butPtr->width) != TCL_OK) { widthError: Tcl_AddErrorInfo(interp, "\n (processing -width option)"); return TCL_ERROR; } if (Tk_GetPixels(interp, butPtr->tkwin, butPtr->heightString, &butPtr->height) != TCL_OK) { heightError: Tcl_AddErrorInfo(interp, "\n (processing -height option)"); return TCL_ERROR; } } else { if (Tcl_GetInt(interp, butPtr->widthString, &butPtr->width) != TCL_OK) { goto widthError; } if (Tcl_GetInt(interp, butPtr->heightString, &butPtr->height) != TCL_OK) { goto heightError; } } ComputeButtonGeometry(butPtr); /* * Lastly, arrange for the button to be redisplayed. */ if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayButton, (ClientData)butPtr); butPtr->flags |= REDRAW_PENDING; } return TCL_OK; } static void DrawCheckButton(Tk_Window tkwin, Drawable drawable, Button *butPtr, int x, int y) { #ifdef notdef Blt_Background bg; GC fillGC, boxGC, checkGC; int boxWidth, boxHeight; int dim; int xBox, yBox; dim = butPtr->indicatorDiameter - 2 * butPtr->borderWidth; dim |= 0x1; boxWidth = boxHeight = dim; xBox = butPtr->borderWidth + GAP; yBox = (Tk_Height(tkwin) - boxHeight) / 2; bg = butPtr->normalBg; if (butPtr->state & STATE_DISABLED) { fillGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_FLAT_GC); } else { fillGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_LIGHT_GC); } boxGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_DARK_GC); checkGC = butPtr->normalTextGC; XFillRectangle(butPtr->display, drawable, fillGC, xBox, yBox, boxWidth, boxHeight); XDrawRectangle(butPtr->display, drawable, boxGC, xBox, yBox, boxWidth, boxHeight); if (butPtr->flags & SELECTED) { int ax, ay, bx, by, cx, cy; int i; ax = xBox + 2, ay = yBox + 2 + (boxHeight / 3); bx = xBox + (boxWidth / 2) - 1; by = yBox + boxHeight - 4; cx = xBox + boxWidth; cy = yBox; for (i = 0; i < 3; i++) { XDrawLine(butPtr->display, drawable, checkGC, ax, ay, bx, by); XDrawLine(butPtr->display, drawable, checkGC, bx, by, cx, cy); ay++, by++, cy++; } } #else Blt_Picture picture; Blt_Painter painter; int on, dim; int w, h; dim = butPtr->indicatorDiameter; x -= butPtr->indicatorSpace + butPtr->borderWidth; y -= dim / 2 + butPtr->borderWidth; w = h = butPtr->indicatorSpace /* - 2 * butPtr->borderWidth; */; on = (butPtr->flags & SELECTED); picture = NULL; if (butPtr->state & STATE_DISABLED) { if (butPtr->disabledPicture == NULL) { butPtr->disabledPicture = Blt_PaintCheckbox(w, h, Blt_BackgroundBorderColor(butPtr->normalBg), butPtr->disabledFg, butPtr->disabledFg, on); } picture = butPtr->disabledPicture; } else if (butPtr->flags & SELECTED) { if (butPtr->selectedPicture == NULL) { butPtr->selectedPicture = Blt_PaintCheckbox(w, h, Blt_BackgroundBorderColor(butPtr->selectBg), butPtr->activeFg, butPtr->selectFg, TRUE); } picture = butPtr->selectedPicture; } else { if (butPtr->normalPicture == NULL) { butPtr->normalPicture = Blt_PaintCheckbox(w, h, Blt_BackgroundBorderColor(butPtr->selectBg), butPtr->normalFg, butPtr->selectFg, FALSE); } picture = butPtr->normalPicture; } painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x, y, 0); #endif } static void DrawRadioButton(Tk_Window tkwin, Drawable drawable, Button *butPtr, int x, int y) { #ifdef notdef Blt_Background bg; GC fillGC, boxGC, checkGC; int boxWidth, boxHeight; int dim; int xBox, yBox; dim = butPtr->indicatorDiameter - 2 * butPtr->borderWidth; dim |= 0x1; boxWidth = boxHeight = dim; xBox = butPtr->borderWidth + GAP; yBox = (Tk_Height(tkwin) - boxHeight) / 2; bg = butPtr->normalBg; if (butPtr->state & STATE_DISABLED) { fillGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_FLAT_GC); } else { fillGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_LIGHT_GC); } boxGC = Blt_BackgroundBorderGC(tkwin, bg, TK_3D_DARK_GC); checkGC = butPtr->normalTextGC; XFillRectangle(butPtr->display, drawable, fillGC, xBox, yBox, boxWidth, boxHeight); XDrawRectangle(butPtr->display, drawable, boxGC, xBox, yBox, boxWidth, boxHeight); if (butPtr->flags & SELECTED) { int ax, ay, bx, by, cx, cy; int i; ax = xBox + 2, ay = yBox + 2 + (boxHeight / 3); bx = xBox + (boxWidth / 2) - 1; by = yBox + boxHeight - 4; cx = xBox + boxWidth; cy = yBox; for (i = 0; i < 3; i++) { XDrawLine(butPtr->display, drawable, checkGC, ax, ay, bx, by); XDrawLine(butPtr->display, drawable, checkGC, bx, by, cx, cy); ay++, by++, cy++; } } #else Blt_Picture picture; Blt_Painter painter; int on, dim; int w, h; dim = butPtr->indicatorDiameter; x -= butPtr->indicatorSpace + butPtr->borderWidth; y -= dim / 2 + butPtr->borderWidth; w = h = butPtr->indicatorSpace - 2 * butPtr->borderWidth; on = (butPtr->flags & SELECTED); picture = NULL; if (butPtr->state & STATE_DISABLED) { if (butPtr->disabledPicture == NULL) { butPtr->disabledPicture = Blt_PaintRadioButton(w, h, Blt_BackgroundBorderColor(butPtr->normalBg), butPtr->disabledFg, butPtr->disabledFg, on); } picture = butPtr->disabledPicture; } else if (butPtr->flags & SELECTED) { if (butPtr->selectedPicture == NULL) { butPtr->selectedPicture = Blt_PaintRadioButton(w, h, Blt_BackgroundBorderColor(butPtr->selectBg), butPtr->activeFg, butPtr->selectFg, TRUE); } picture = butPtr->selectedPicture; } else { if (butPtr->normalPicture == NULL) { butPtr->normalPicture = Blt_PaintRadioButton(w, h, Blt_BackgroundBorderColor(butPtr->selectBg), butPtr->normalFg, butPtr->selectFg, FALSE); } picture = butPtr->normalPicture; } painter = Blt_GetPainter(tkwin, 1.0); Blt_PaintPicture(painter, drawable, picture, 0, 0, w, h, x, y, 0); #endif } /* *--------------------------------------------------------------------------- * * DisplayButton -- * * This procedure is invoked to display a button widget. It is * normally invoked as an idle handler. * * Results: * None. * * Side effects: * Commands are output to X to display the button in its * current mode. The REDRAW_PENDING flag is cleared. * *--------------------------------------------------------------------------- */ static void DisplayButton(ClientData clientData) { Button *butPtr = clientData; GC gc; Blt_Background bg; Pixmap pixmap; int x = 0; /* Initialization only needed to stop * compiler warning. */ int y, relief; Tk_Window tkwin = butPtr->tkwin; int width, height; int offset; /* 0 means this is a label widget. 1 means * it is a flavor of button, so we offset * the text to make the button appear to * move up and down as the relief changes. */ butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } if ((Tk_Width(butPtr->tkwin) < 2) || (Tk_Height(butPtr->tkwin) < 2)) { return; } bg = butPtr->normalBg; if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) { gc = butPtr->disabledGC; } else if ((butPtr->state == STATE_ACTIVE) && !Tk_StrictMotif(butPtr->tkwin)) { gc = butPtr->activeTextGC; bg = butPtr->activeBg; } else { gc = butPtr->normalTextGC; } if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE) && (butPtr->selectBg != NULL) && (!butPtr->indicatorOn)) { bg = butPtr->selectBg; } if ((butPtr->type == TYPE_PUSH_BUTTON) && (butPtr->flags & SELECTED) && (butPtr->state == STATE_ACTIVE) && (butPtr->selectBg != NULL) && (!butPtr->indicatorOn)) { bg = butPtr->selectBg; } /* * Override the relief specified for the button if this is a * checkbutton or radiobutton and there's no indicator. */ relief = butPtr->relief; if ((butPtr->type >= TYPE_PUSH_BUTTON) && (!butPtr->indicatorOn)) { relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN : butPtr->relief; } offset = (butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin); /* * In order to avoid screen flashes, this procedure redraws * the button in a pixmap, then copies the pixmap to the * screen in a single operation. This means that there's no * point in time where the on-sreen image has been cleared. */ pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); Blt_FillBackgroundRectangle(tkwin, pixmap, bg, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); /* * Display image or bitmap or text for button. */ if (butPtr->image != None) { Tk_SizeOfImage(butPtr->image, &width, &height); imageOrBitmap: TkComputeAnchor(butPtr->anchor, tkwin, butPtr->xPad, butPtr->yPad, butPtr->indicatorSpace + width, height, &x, &y); x += butPtr->indicatorSpace; x += offset; y += offset; if (relief == TK_RELIEF_RAISED) { x -= offset; y -= offset; } else if (relief == TK_RELIEF_SUNKEN) { x += offset; y += offset; } if (butPtr->image != NULL) { if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, x, y); } else { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, x, y); } } else { XSetClipOrigin(butPtr->display, gc, x, y); XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, (unsigned int)width, (unsigned int)height, x, y, 1); XSetClipOrigin(butPtr->display, gc, 0, 0); } y += height / 2; } else if (butPtr->bitmap != None) { Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); goto imageOrBitmap; } else { TkComputeAnchor(butPtr->anchor, tkwin, butPtr->xPad, butPtr->yPad, butPtr->indicatorSpace + butPtr->textWidth, butPtr->textHeight, &x, &y); x += butPtr->indicatorSpace; x += offset; y += offset; if (relief == TK_RELIEF_RAISED) { x -= offset; y -= offset; } else if (relief == TK_RELIEF_SUNKEN) { x += offset; y += offset; } Blt_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x, y, 0, -1); Blt_UnderlineTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x, y, butPtr->underline); y += butPtr->textHeight / 2; } /* * Draw the indicator for check buttons and radio buttons. At this * point x and y refer to the top-left corner of the text or image * or bitmap. */ if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { #ifdef notdef int dim; dim = butPtr->indicatorDiameter; x -= butPtr->indicatorSpace; y -= dim / 2; if (dim > 2 * butPtr->borderWidth) { Blt_DrawBackgroundRectangle(tkwin, pixmap, bg, x, y, dim, dim, butPtr->borderWidth, (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); x += butPtr->borderWidth; y += butPtr->borderWidth; dim -= 2 * butPtr->borderWidth; if (butPtr->flags & SELECTED) { GC borderGC; borderGC = Blt_BackgroundBorderGC(tkwin, (butPtr->selectBg != NULL) ? butPtr->selectBg : butPtr->normalBg, TK_3D_FLAT_GC); XFillRectangle(butPtr->display, pixmap, borderGC, x, y, (unsigned int)dim, (unsigned int)dim); } else { Blt_FillBackgroundRectangle(tkwin, pixmap, butPtr->normalBg, x, y, dim, dim, butPtr->borderWidth, TK_RELIEF_FLAT); } } #else DrawCheckButton(tkwin, pixmap, butPtr, x, y); x -= GAP; #endif } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) { #ifdef notdef XPoint points[4]; int radius; radius = butPtr->indicatorDiameter / 2; points[0].x = x - butPtr->indicatorSpace; points[0].y = y; points[1].x = points[0].x + radius; points[1].y = points[0].y + radius; points[2].x = points[1].x + radius; points[2].y = points[0].y; points[3].x = points[1].x; points[3].y = points[0].y - radius; if (butPtr->flags & SELECTED) { GC borderGC; borderGC = Blt_BackgroundBorderGC(tkwin, (butPtr->selectBg != NULL) ? butPtr->selectBg : butPtr->normalBg, TK_3D_FLAT_GC); XFillPolygon(butPtr->display, pixmap, borderGC, points, 4, Convex, CoordModeOrigin); } else { Tk_Fill3DPolygon(tkwin, pixmap, Blt_BackgroundBorder(butPtr->normalBg), points, 4, butPtr->borderWidth, TK_RELIEF_FLAT); } Tk_Draw3DPolygon(tkwin, pixmap, Blt_BackgroundBorder(bg), points, 4, butPtr->borderWidth, (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); #else DrawRadioButton(tkwin, pixmap, butPtr, x, y); #endif } /* * If the button is disabled with a stipple rather than a special * foreground color, generate the stippled effect. If the widget * is selected and we use a different background color when selected, * must temporarily modify the GC. */ if ((butPtr->state == STATE_DISABLED) && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) { if ((butPtr->flags & SELECTED) && (!butPtr->indicatorOn) && (butPtr->selectBg != NULL)) { XSetForeground(butPtr->display, butPtr->disabledGC, Blt_BackgroundBorderColor(butPtr->selectBg)->pixel); } XFillRectangle(butPtr->display, pixmap, butPtr->disabledGC, butPtr->inset, butPtr->inset, (unsigned)(Tk_Width(tkwin) - 2 * butPtr->inset), (unsigned)(Tk_Height(tkwin) - 2 * butPtr->inset)); if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn && (butPtr->selectBg != NULL)) { XSetForeground(butPtr->display, butPtr->disabledGC, Blt_BackgroundBorderColor(butPtr->normalBg)->pixel); } } /* * Draw the border and traversal highlight last. This way, if the * button's contents overflow they'll be covered up by the border. */ if (relief != TK_RELIEF_FLAT) { int inset = butPtr->highlightWidth; if (butPtr->defaultState == STATE_ACTIVE) { inset += 2; Blt_DrawBackgroundRectangle(tkwin, pixmap, bg, inset, inset, Tk_Width(tkwin) - 2 * inset, Tk_Height(tkwin) - 2 * inset, 1, TK_RELIEF_SUNKEN); inset += 3; } Blt_DrawBackgroundRectangle(tkwin, pixmap, bg, inset, inset, Tk_Width(tkwin) - 2 * inset, Tk_Height(tkwin) - 2 * inset, butPtr->borderWidth, relief); } if (butPtr->highlightWidth != 0) { GC highlightGC; if (butPtr->flags & GOT_FOCUS) { highlightGC = Tk_GCForColor(butPtr->highlightColorPtr, pixmap); } else { highlightGC = Tk_GCForColor(butPtr->highlightBgColorPtr, pixmap); } Tk_DrawFocusHighlight(tkwin, highlightGC, butPtr->highlightWidth, pixmap); } /* * Copy the information from the off-screen pixmap onto the screen, * then delete the pixmap. */ XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin), butPtr->copyGC, 0, 0, (unsigned)Tk_Width(tkwin), (unsigned)Tk_Height(tkwin), 0, 0); Tk_FreePixmap(butPtr->display, pixmap); } /* *--------------------------------------------------------------------------- * * ComputeButtonGeometry -- * * After changes in a button's text or bitmap, this procedure * recomputes the button's geometry and passes this information * along to the geometry manager for the window. * * Results: * None. * * Side effects: * The button's window may change size. * *--------------------------------------------------------------------------- */ static void ComputeButtonGeometry(Button *butPtr) { int width, height; if (butPtr->highlightWidth < 0) { butPtr->highlightWidth = 0; } butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth; /* * Leave room for the default ring if needed. */ if (butPtr->defaultState == STATE_ACTIVE) { butPtr->inset += 5; } butPtr->indicatorSpace = 0; if (butPtr->image != NULL) { Tk_SizeOfImage(butPtr->image, &width, &height); imageOrBitmap: if (butPtr->width > 0) { width = butPtr->width; } if (butPtr->height > 0) { height = butPtr->height; } if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { butPtr->indicatorSpace = height; if (butPtr->type == TYPE_CHECK_BUTTON) { butPtr->indicatorDiameter = (65 * height) / 100; } else { butPtr->indicatorDiameter = (75 * height) / 100; } } } else if (butPtr->bitmap != None) { Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); goto imageOrBitmap; } else { int avgWidth; Blt_FontMetrics fm; if (butPtr->textLayout != NULL) { Tk_FreeTextLayout(butPtr->textLayout); } butPtr->textLayout = Blt_ComputeTextLayout(butPtr->font, butPtr->text, -1, butPtr->wrapLength, butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); width = butPtr->textWidth; height = butPtr->textHeight; avgWidth = Blt_TextWidth(butPtr->font, "0", 1); Blt_GetFontMetrics(butPtr->font, &fm); if (butPtr->width > 0) { width = butPtr->width * avgWidth; } if (butPtr->height > 0) { height = butPtr->height * fm.linespace; } if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { butPtr->indicatorDiameter = fm.linespace; if (butPtr->type == TYPE_CHECK_BUTTON) { butPtr->indicatorDiameter = (70 * butPtr->indicatorDiameter) / 100; } butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth; } } /* * When issuing the geometry request, add extra space for the indicator, * if any, and for the border and padding, plus two extra pixels so the * display can be offset by 1 pixel in either direction for the raised * or lowered effect. */ #ifdef notdef if ((butPtr->image == NULL) && (butPtr->bitmap == None)) { width += 2 * butPtr->xPad; height += 2 * butPtr->yPad; } #else width += 2 * butPtr->xPad; height += 2 * butPtr->yPad; #endif if ((butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin)) { width += 2; height += 2; } Tk_GeometryRequest(butPtr->tkwin, (int)(width + butPtr->indicatorSpace + 2 * butPtr->inset), (int)(height + 2 * butPtr->inset)); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); } /* *--------------------------------------------------------------------------- * * ButtonEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on buttons. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void ButtonEventProc(ClientData clientData, XEvent *eventPtr) { Button *butPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; } else if (eventPtr->type == ConfigureNotify) { /* * Must redraw after size changes, since layout could have changed * and borders will need to be redrawn. */ goto redraw; } else if (eventPtr->type == DestroyNotify) { if (butPtr->tkwin != NULL) { butPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd); } if (butPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayButton, (ClientData)butPtr); } /* This is a hack to workaround a bug in 8.3.3. */ DestroyButton((ClientData)butPtr); /* Tcl_EventuallyFree((ClientData)butPtr, (Tcl_FreeProc *)Blt_Free); */ } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { butPtr->flags |= GOT_FOCUS; if (butPtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == FocusOut) { if (eventPtr->xfocus.detail != NotifyInferior) { butPtr->flags &= ~GOT_FOCUS; if (butPtr->highlightWidth > 0) { goto redraw; } } } return; redraw: if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayButton, (ClientData)butPtr); butPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * ButtonCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void ButtonCmdDeletedProc(ClientData clientData) { Button *butPtr = clientData; Tk_Window tkwin = butPtr->tkwin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tkwin != NULL) { butPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * InvokeButton -- * * This procedure is called to carry out the actions associated * with a button, such as invoking a TCL command or setting a * variable. This procedure is invoked, for example, when the * button is invoked via the mouse. * * Results: * A standard TCL return value. Information is also left in * interp->result. * * Side effects: * Depends on the button and its associated command. * *--------------------------------------------------------------------------- */ static int InvokeButton(Button *butPtr) { if ((butPtr->type == TYPE_CHECK_BUTTON) || (butPtr->type == TYPE_PUSH_BUTTON)) { if (butPtr->flags & SELECTED) { if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->offValue, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } else { if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->onValue, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } } else if (butPtr->type == TYPE_RADIO_BUTTON) { if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->onValue, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } } if ((butPtr->type != TYPE_LABEL) && (butPtr->command != NULL)) { return TkCopyAndGlobalEval(butPtr->interp, (char *)butPtr->command); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonVarProc -- * * This procedure is invoked when someone changes the * state variable associated with a radio button. Depending * on the new value of the button's variable, the button * may be selected or deselected. * * Results: * NULL is always returned. * * Side effects: * The button may become selected or deselected. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static char * ButtonVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* Name of variable. */ const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Button *butPtr = clientData; const char *value; /* * If the variable is being unset, then just re-establish the * trace unless the whole interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { butPtr->flags &= ~SELECTED; if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_TraceVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonVarProc, clientData); } goto redisplay; } /* * Use the value of the variable to update the selected status of * the button. */ value = Tcl_GetVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } if (strcmp(value, butPtr->onValue) == 0) { if (butPtr->flags & SELECTED) { return (char *) NULL; } butPtr->flags |= SELECTED; } else if (butPtr->flags & SELECTED) { butPtr->flags &= ~SELECTED; } else { return (char *) NULL; } redisplay: if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayButton, (ClientData)butPtr); butPtr->flags |= REDRAW_PENDING; } return (char *) NULL; } /* *--------------------------------------------------------------------------- * * ButtonTextVarProc -- * * This procedure is invoked when someone changes the variable * whose contents are to be displayed in a button. * * Results: * NULL is always returned. * * Side effects: * The text displayed in the button will change to match the * variable. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static char * ButtonTextVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* Not used. */ const char *name2, /* Not used. */ int flags) /* Information about what happened. */ { Button *butPtr = clientData; const char *value; /* * If the variable is unset, then immediately recreate it unless * the whole interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, ButtonTextVarProc, clientData); } return (char *) NULL; } value = Tcl_GetVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } if (butPtr->text != NULL) { Blt_Free(butPtr->text); } butPtr->text = Blt_AssertStrdup(value); ComputeButtonGeometry(butPtr); if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayButton, (ClientData)butPtr); butPtr->flags |= REDRAW_PENDING; } return (char *) NULL; } int Blt_ButtonCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[] = { {"button", ButtonCmd,}, {"pushbutton", PushbuttonCmd,}, {"checkbutton", CheckbuttonCmd,}, {"radiobutton", RadiobuttonCmd,}, {"label", LabelCmd,}, }; return Blt_InitCmds(interp, "::blt::tk", cmdSpecs, 5); } #endif /* NO_TKBUTTON */ ������������������������������./saods9/blt3.0.1/src/bltVector.c�������������������������������������������������������������������0000644�0001750�0001750�00000223275�11462120063�015151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVector.c -- * * This module implements vector data objects. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * o Add H. Kirsch's vector binary read operation * x binread file0 * x binread -file file0 * * o Add ASCII/binary file reader * x read fileName * * o Allow Tcl-based client notifications. * vector x * x notify call Display * x notify delete Display * x notify reorder #1 #2 */ #include "bltVecInt.h" #include "bltOp.h" #include "bltNsUtil.h" #include "bltSwitch.h" #include <bltMath.h> #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #endif /* TIME_WITH_SYS_TIME */ #ifndef TCL_NAMESPACE_ONLY #define TCL_NAMESPACE_ONLY TCL_GLOBAL_ONLY #endif #define DEF_ARRAY_SIZE 64 #define TRACE_ALL (TCL_TRACE_WRITES | TCL_TRACE_READS | TCL_TRACE_UNSETS) #define VECTOR_CHAR(c) ((isalnum(UCHAR(c))) || \ (c == '_') || (c == ':') || (c == '@') || (c == '.')) /* * VectorClient -- * * A vector can be shared by several clients. Each client allocates this * structure that acts as its key for using the vector. Clients can also * designate a callback routine that is executed whenever the vector is * updated or destroyed. * */ typedef struct { unsigned int magic; /* Magic value designating whether this really * is a vector token or not */ Vector *serverPtr; /* Pointer to the master record of the vector. * If NULL, indicates that the vector has been * destroyed but as of yet, this client hasn't * recognized it. */ Blt_VectorChangedProc *proc;/* Routine to call when the contents of the * vector change or the vector is deleted. */ ClientData clientData; /* Data passed whenever the vector change * procedure is called. */ Blt_ChainLink link; /* Used to quickly remove this entry from its * server's client chain. */ } VectorClient; static Tcl_CmdDeleteProc VectorInstDeleteProc; static Tcl_ObjCmdProc VectorCmd; static Tcl_InterpDeleteProc VectorInterpDeleteProc; typedef struct { char *varName; /* Requested variable name. */ char *cmdName; /* Requested command name. */ int flush; /* Flush */ int watchUnset; /* Watch when variable is unset. */ } CreateSwitches; static Blt_SwitchSpec createSwitches[] = { {BLT_SWITCH_STRING, "-variable", "varName", Blt_Offset(CreateSwitches, varName), BLT_SWITCH_NULL_OK}, {BLT_SWITCH_STRING, "-command", "command", Blt_Offset(CreateSwitches, cmdName), BLT_SWITCH_NULL_OK}, {BLT_SWITCH_BOOLEAN, "-watchunset", "bool", Blt_Offset(CreateSwitches, watchUnset), 0}, {BLT_SWITCH_BOOLEAN, "-flush", "bool", Blt_Offset(CreateSwitches, flush), 0}, {BLT_SWITCH_END} }; typedef int (VectorCmdProc)(Vector *vecObjPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static Vector * FindVectorInNamespace( VectorInterpData *dataPtr, /* Interpreter-specific data. */ Blt_ObjectName *objNamePtr) { Tcl_DString dString; const char *name; Blt_HashEntry *hPtr; name = Blt_MakeQualifiedName(objNamePtr, &dString); hPtr = Blt_FindHashEntry(&dataPtr->vectorTable, name); Tcl_DStringFree(&dString); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return NULL; } /* *--------------------------------------------------------------------------- * * GetVectorObject -- * * Searches for the vector associated with the name given. Allow for a * range specification. * * Results: * Returns a pointer to the vector if found, otherwise NULL. * *--------------------------------------------------------------------------- */ static Vector * GetVectorObject( VectorInterpData *dataPtr, /* Interpreter-specific data. */ const char *name, int flags) { Blt_ObjectName objName; Vector *vPtr; Tcl_Interp *interp; interp = dataPtr->interp; if (!Blt_ParseObjectName(interp, name, &objName, BLT_NO_ERROR_MSG | BLT_NO_DEFAULT_NS)) { return NULL; /* Can't find namespace. */ } vPtr = NULL; if (objName.nsPtr != NULL) { vPtr = FindVectorInNamespace(dataPtr, &objName); } else { if (flags & NS_SEARCH_CURRENT) { objName.nsPtr = Tcl_GetCurrentNamespace(interp); vPtr = FindVectorInNamespace(dataPtr, &objName); } if ((vPtr == NULL) && (flags & NS_SEARCH_GLOBAL)) { objName.nsPtr = Tcl_GetGlobalNamespace(interp); vPtr = FindVectorInNamespace(dataPtr, &objName); } } return vPtr; } void Blt_Vec_UpdateRange(Vector *vPtr) { double min, max; double *vp, *vend; vp = vPtr->valueArr + vPtr->first; vend = vPtr->valueArr + vPtr->last; min = max = *vp++; for (/* empty */; vp <= vend; vp++) { if (min > *vp) { min = *vp; } else if (max < *vp) { max = *vp; } } vPtr->min = min; vPtr->max = max; vPtr->notifyFlags &= ~UPDATE_RANGE; } /* *--------------------------------------------------------------------------- * * Blt_Vec_GetIndex -- * * Converts the string representing an index in the vector, to its * numeric value. A valid index may be an numeric string of the string * "end" (indicating the last element in the string). * * Results: * A standard TCL result. If the string is a valid index, TCL_OK is * returned. Otherwise TCL_ERROR is returned and interp->result will * contain an error message. * *--------------------------------------------------------------------------- */ int Blt_Vec_GetIndex( Tcl_Interp *interp, Vector *vPtr, const char *string, int *indexPtr, int flags, Blt_VectorIndexProc **procPtrPtr) { char c; int value; c = string[0]; /* Treat the index "end" like a numeric index. */ if ((c == 'e') && (strcmp(string, "end") == 0)) { if (vPtr->length < 1) { if (interp != NULL) { Tcl_AppendResult(interp, "bad index \"end\": vector is empty", (char *)NULL); } return TCL_ERROR; } *indexPtr = vPtr->length - 1; return TCL_OK; } else if ((c == '+') && (strcmp(string, "++end") == 0)) { *indexPtr = vPtr->length; return TCL_OK; } if (procPtrPtr != NULL) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&vPtr->dataPtr->indexProcTable, string); if (hPtr != NULL) { *indexPtr = SPECIAL_INDEX; *procPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } } if (Tcl_GetInt(interp, (char *)string, &value) != TCL_OK) { long int lvalue; /* * Unlike Tcl_GetInt, Tcl_ExprLong needs a valid interpreter, but the * interp passed in may be NULL. So we have to use vPtr->interp and * then reset the result. */ if (Tcl_ExprLong(vPtr->interp, (char *)string, &lvalue) != TCL_OK) { Tcl_ResetResult(vPtr->interp); if (interp != NULL) { Tcl_AppendResult(interp, "bad index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } value = (int)lvalue; } /* * Correct the index by the current value of the offset. This makes all * the numeric indices non-negative, which is how we distinguish the * special non-numeric indices. */ value -= vPtr->offset; if ((value < 0) || ((flags & INDEX_CHECK) && (value >= vPtr->length))) { if (interp != NULL) { Tcl_AppendResult(interp, "index \"", string, "\" is out of range", (char *)NULL); } return TCL_ERROR; } *indexPtr = (int)value; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Vec_GetIndexRange -- * * Converts the string representing an index in the vector, to its * numeric value. A valid index may be an numeric string of the string * "end" (indicating the last element in the string). * * Results: * A standard TCL result. If the string is a valid index, TCL_OK is * returned. Otherwise TCL_ERROR is returned and interp->result will * contain an error message. * *--------------------------------------------------------------------------- */ int Blt_Vec_GetIndexRange( Tcl_Interp *interp, Vector *vPtr, const char *string, int flags, Blt_VectorIndexProc **procPtrPtr) { int ielem; char *colon; colon = NULL; if (flags & INDEX_COLON) { colon = strchr(string, ':'); } if (colon != NULL) { if (string == colon) { vPtr->first = 0; /* Default to the first index */ } else { int result; *colon = '\0'; result = Blt_Vec_GetIndex(interp, vPtr, string, &ielem, flags, (Blt_VectorIndexProc **) NULL); *colon = ':'; if (result != TCL_OK) { return TCL_ERROR; } vPtr->first = ielem; } if (*(colon + 1) == '\0') { /* Default to the last index */ vPtr->last = (vPtr->length > 0) ? vPtr->length - 1 : 0; } else { if (Blt_Vec_GetIndex(interp, vPtr, colon + 1, &ielem, flags, (Blt_VectorIndexProc **) NULL) != TCL_OK) { return TCL_ERROR; } vPtr->last = ielem; } if (vPtr->first > vPtr->last) { if (interp != NULL) { Tcl_AppendResult(interp, "bad range \"", string, "\" (first > last)", (char *)NULL); } return TCL_ERROR; } } else { if (Blt_Vec_GetIndex(interp, vPtr, string, &ielem, flags, procPtrPtr) != TCL_OK) { return TCL_ERROR; } vPtr->last = vPtr->first = ielem; } return TCL_OK; } Vector * Blt_Vec_ParseElement( Tcl_Interp *interp, VectorInterpData *dataPtr, /* Interpreter-specific data. */ const char *start, const char **endPtr, int flags) { char *p; char saved; Vector *vPtr; p = (char *)start; /* Find the end of the vector name */ while (VECTOR_CHAR(*p)) { p++; } saved = *p; *p = '\0'; vPtr = GetVectorObject(dataPtr, start, flags); if (vPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find vector \"", start, "\"", (char *)NULL); } *p = saved; return NULL; } *p = saved; vPtr->first = 0; vPtr->last = vPtr->length - 1; if (*p == '(') { int count, result; start = p + 1; p++; /* Find the matching right parenthesis */ count = 1; while (*p != '\0') { if (*p == ')') { count--; if (count == 0) { break; } } else if (*p == '(') { count++; } p++; } if (count > 0) { if (interp != NULL) { Tcl_AppendResult(interp, "unbalanced parentheses \"", start, "\"", (char *)NULL); } return NULL; } *p = '\0'; result = Blt_Vec_GetIndexRange(interp, vPtr, start, (INDEX_COLON | INDEX_CHECK), (Blt_VectorIndexProc **) NULL); *p = ')'; if (result != TCL_OK) { return NULL; } p++; } if (endPtr != NULL) { *endPtr = p; } return vPtr; } /* *--------------------------------------------------------------------------- * * Blt_Vec_NotifyClients -- * * Notifies each client of the vector that the vector has changed * (updated or destroyed) by calling the provided function back. The * function pointer may be NULL, in that case the client is not notified. * * Results: * None. * * Side effects: * The results depend upon what actions the client callbacks * take. * *--------------------------------------------------------------------------- */ void Blt_Vec_NotifyClients(ClientData clientData) { Vector *vPtr = clientData; Blt_ChainLink link, next; Blt_VectorNotify notify; notify = (vPtr->notifyFlags & NOTIFY_DESTROYED) ? BLT_VECTOR_NOTIFY_DESTROY : BLT_VECTOR_NOTIFY_UPDATE; vPtr->notifyFlags &= ~(NOTIFY_UPDATED | NOTIFY_DESTROYED | NOTIFY_PENDING); for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL; link = next) { VectorClient *clientPtr; next = Blt_Chain_NextLink(link); clientPtr = Blt_Chain_GetValue(link); if ((clientPtr->proc != NULL) && (clientPtr->serverPtr != NULL)) { (*clientPtr->proc) (vPtr->interp, clientPtr->clientData, notify); } } /* * Some clients may not handle the "destroy" callback properly (they * should call Blt_FreeVectorId to release the client identifier), so mark * any remaining clients to indicate that vector's server has gone away. */ if (notify == BLT_VECTOR_NOTIFY_DESTROY) { for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { VectorClient *clientPtr; clientPtr = Blt_Chain_GetValue(link); clientPtr->serverPtr = NULL; } } } /* *--------------------------------------------------------------------------- * * Blt_Vec_UpdateClients -- * * Notifies each client of the vector that the vector has changed * (updated or destroyed) by calling the provided function back. * * Results: * None. * * Side effects: * The individual client callbacks are eventually invoked. * *--------------------------------------------------------------------------- */ void Blt_Vec_UpdateClients(Vector *vPtr) { vPtr->dirty++; vPtr->max = vPtr->min = Blt_NaN(); if (vPtr->notifyFlags & NOTIFY_NEVER) { return; } vPtr->notifyFlags |= NOTIFY_UPDATED; if (vPtr->notifyFlags & NOTIFY_ALWAYS) { Blt_Vec_NotifyClients(vPtr); return; } if (!(vPtr->notifyFlags & NOTIFY_PENDING)) { vPtr->notifyFlags |= NOTIFY_PENDING; Tcl_DoWhenIdle(Blt_Vec_NotifyClients, vPtr); } } /* *--------------------------------------------------------------------------- * * Blt_Vec_FlushCache -- * * Unsets all the elements of the TCL array variable associated with the * vector, freeing memory associated with the variable. This includes * both the hash table and the hash keys. The down side is that this * effectively flushes the caching of vector elements in the array. This * means that the subsequent reads of the array will require a decimal to * string conversion. * * This is needed when the vector changes its values, making the array * variable out-of-sync. * * Results: * None. * * Side effects: * All elements of array variable (except one) are unset, freeing * the memory associated with the variable. * *--------------------------------------------------------------------------- */ void Blt_Vec_FlushCache(Vector *vPtr) { Tcl_Interp *interp = vPtr->interp; if (vPtr->arrayName == NULL) { return; /* Doesn't use the variable API */ } /* Turn off the trace temporarily so that we can unset all the * elements in the array. */ Tcl_UntraceVar2(interp, vPtr->arrayName, (char *)NULL, TRACE_ALL | vPtr->varFlags, Blt_Vec_VarTrace, vPtr); /* Clear all the element entries from the entire array */ Tcl_UnsetVar2(interp, vPtr->arrayName, (char *)NULL, vPtr->varFlags); /* Restore the "end" index by default and the trace on the entire array */ Tcl_SetVar2(interp, vPtr->arrayName, "end", "", vPtr->varFlags); Tcl_TraceVar2(interp, vPtr->arrayName, (char *)NULL, TRACE_ALL | vPtr->varFlags, Blt_Vec_VarTrace, vPtr); } /* *--------------------------------------------------------------------------- * * Blt_Vec_LookupName -- * * Searches for the vector associated with the name given. Allow for a * range specification. * * Results: * Returns a pointer to the vector if found, otherwise NULL. If the name * is not associated with a vector and the TCL_LEAVE_ERR_MSG flag is set, * and interp->result will contain an error message. * *--------------------------------------------------------------------------- */ int Blt_Vec_LookupName( VectorInterpData *dataPtr, /* Interpreter-specific data. */ const char *vecName, Vector **vPtrPtr) { Vector *vPtr; const char *endPtr; vPtr = Blt_Vec_ParseElement(dataPtr->interp, dataPtr, vecName, &endPtr, NS_SEARCH_BOTH); if (vPtr == NULL) { return TCL_ERROR; } if (*endPtr != '\0') { Tcl_AppendResult(dataPtr->interp, "extra characters after vector name", (char *)NULL); return TCL_ERROR; } *vPtrPtr = vPtr; return TCL_OK; } double Blt_Vec_Min(Vector *vecObjPtr) { double *vp, *vend; double min; vp = vecObjPtr->valueArr + vecObjPtr->first; vend = vecObjPtr->valueArr + vecObjPtr->last; min = *vp++; for (/* empty */; vp <= vend; vp++) { if (min > *vp) { min = *vp; } } vecObjPtr->min = min; return vecObjPtr->min; } double Blt_Vec_Max(Vector *vecObjPtr) { double max; double *vp, *vend; max = Blt_NaN(); vp = vecObjPtr->valueArr + vecObjPtr->first; vend = vecObjPtr->valueArr + vecObjPtr->last; max = *vp++; for (/* empty */; vp <= vend; vp++) { if (max < *vp) { max = *vp; } } vecObjPtr->max = max; return vecObjPtr->max; } /* *--------------------------------------------------------------------------- * * DeleteCommand -- * * Deletes the TCL command associated with the vector, without triggering * a callback to "VectorInstDeleteProc". * * Results: * None. * *--------------------------------------------------------------------------- */ static void DeleteCommand(Vector *vPtr) /* Vector associated with the TCL command. */ { Tcl_Interp *interp = vPtr->interp; char *qualName; /* Name of TCL command. */ Tcl_CmdInfo cmdInfo; Tcl_DString dString; Blt_ObjectName objName; Tcl_DStringInit(&dString); objName.name = Tcl_GetCommandName(interp, vPtr->cmdToken); objName.nsPtr = Blt_GetCommandNamespace(vPtr->cmdToken); qualName = Blt_MakeQualifiedName(&objName, &dString); if (Tcl_GetCommandInfo(interp, qualName, &cmdInfo)) { /* Disable the callback before deleting the TCL command.*/ cmdInfo.deleteProc = NULL; Tcl_SetCommandInfo(interp, qualName, &cmdInfo); Tcl_DeleteCommandFromToken(interp, vPtr->cmdToken); } Tcl_DStringFree(&dString); vPtr->cmdToken = 0; } /* *--------------------------------------------------------------------------- * * UnmapVariable -- * * Destroys the trace on the current TCL variable designated to access * the vector. * * Results: * None. * *--------------------------------------------------------------------------- */ static void UnmapVariable(Vector *vPtr) { Tcl_Interp *interp = vPtr->interp; /* Unset the entire array */ Tcl_UntraceVar2(interp, vPtr->arrayName, (char *)NULL, (TRACE_ALL | vPtr->varFlags), Blt_Vec_VarTrace, vPtr); Tcl_UnsetVar2(interp, vPtr->arrayName, (char *)NULL, vPtr->varFlags); if (vPtr->arrayName != NULL) { Blt_Free(vPtr->arrayName); vPtr->arrayName = NULL; } } /* *--------------------------------------------------------------------------- * * Blt_Vec_MapVariable -- * * Sets up traces on a TCL variable to access the vector. * * If another variable is already mapped, it's first untraced and * removed. Don't do anything else for variables named "" (even though * Tcl allows this pathology). Saves the name of the new array variable. * * Results: * A standard TCL result. If an error occurs setting the variable * TCL_ERROR is returned and an error message is left in the interpreter. * * Side effects: * Traces are set for the new variable. The new variable name is saved in * a malloc'ed string in vPtr->arrayName. If this variable is non-NULL, * it indicates that a TCL variable has been mapped to this vector. * *--------------------------------------------------------------------------- */ int Blt_Vec_MapVariable( Tcl_Interp *interp, Vector *vPtr, const char *path) { Blt_ObjectName objName; char *newPath; const char *result; Tcl_DString dString; if (vPtr->arrayName != NULL) { UnmapVariable(vPtr); } if ((path == NULL) || (path[0] == '\0')) { return TCL_OK; /* If the variable pathname is the empty * string, simply return after removing any * existing variable. */ } /* Get the variable name (without the namespace qualifier). */ if (!Blt_ParseObjectName(interp, path, &objName, BLT_NO_DEFAULT_NS)) { return TCL_ERROR; } if (objName.nsPtr == NULL) { /* * If there was no namespace qualifier, try harder to see if the * variable is non-local. */ objName.nsPtr = Blt_GetVariableNamespace(interp, objName.name); } Tcl_DStringInit(&dString); vPtr->varFlags = 0; if (objName.nsPtr != NULL) { /* Global or namespace variable. */ newPath = Blt_MakeQualifiedName(&objName, &dString); vPtr->varFlags |= (TCL_NAMESPACE_ONLY | TCL_GLOBAL_ONLY); } else { /* Local variable. */ newPath = (char *)objName.name; } /* * To play it safe, delete the variable first. This has the benefical * side-effect of unmapping the variable from another vector that may be * currently associated with it. */ Tcl_UnsetVar2(interp, newPath, (char *)NULL, 0); /* * Set the index "end" in the array. This will create the variable * immediately so that we can check its namespace context. */ result = Tcl_SetVar2(interp, newPath, "end", "", TCL_LEAVE_ERR_MSG); if (result == NULL) { Tcl_DStringFree(&dString); return TCL_ERROR; } /* Create a full-array trace on reads, writes, and unsets. */ Tcl_TraceVar2(interp, newPath, (char *)NULL, TRACE_ALL, Blt_Vec_VarTrace, vPtr); vPtr->arrayName = Blt_AssertStrdup(newPath); Tcl_DStringFree(&dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Vec_SetSize -- * * Resizes the vector to the designated new size. * * If the new size is the same as the old, simply return. Otherwise * we're copying the data from one memory location to another. * * If the storage changed memory locations, free up the old location if * it was dynamically allocated. * * Results: * A standard TCL result. If the reallocation is successful, * TCL_OK is returned, otherwise TCL_ERROR. * * Side effects: * Memory for the array is reallocated. * *--------------------------------------------------------------------------- */ int Blt_Vec_SetSize( Tcl_Interp *interp, Vector *vPtr, int newSize) /* Size of array in elements */ { if (newSize <= 0) { newSize = DEF_ARRAY_SIZE; } if (newSize == vPtr->size) { /* Same size, use the current array. */ return TCL_OK; } if (vPtr->freeProc == TCL_DYNAMIC) { double *newArr; /* Old memory was dynamically allocated, so use realloc. */ newArr = Blt_Realloc(vPtr->valueArr, newSize * sizeof(double)); if (newArr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't reallocate ", Blt_Itoa(newSize), " elements for vector \"", vPtr->name, "\"", (char *)NULL); } return TCL_ERROR; } vPtr->size = newSize; vPtr->valueArr = newArr; return TCL_OK; } { double *newArr; /* Old memory was created specially (static or special allocator). * Replace with dynamically allocated memory (malloc-ed). */ newArr = Blt_Calloc(newSize, sizeof(double)); if (newArr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(newSize), " elements for vector \"", vPtr->name, "\"", (char *)NULL); } return TCL_ERROR; } { int used, wanted; /* Copy the contents of the old memory into the new. */ used = vPtr->length; wanted = newSize; if (used > wanted) { used = wanted; } /* Copy any previous data */ if (used > 0) { memcpy(newArr, vPtr->valueArr, used * sizeof(double)); } } assert(vPtr->valueArr != NULL); /* * We're not using the old storage anymore, so free it if it's not * TCL_STATIC. It's static because the user previously reset the * vector with a statically allocated array (setting freeProc to * TCL_STATIC). */ if (vPtr->freeProc != TCL_STATIC) { if (vPtr->freeProc == TCL_DYNAMIC) { Blt_Free(vPtr->valueArr); } else { (*vPtr->freeProc) ((char *)vPtr->valueArr); } } vPtr->freeProc = TCL_DYNAMIC; /* Set the type of the new storage */ vPtr->valueArr = newArr; vPtr->size = newSize; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Vec_SetSize -- * * Set the length (the number of elements currently in use) of the * vector. If the new length is greater than the size (total number of * slots), then the vector is grown. * * Results: * A standard TCL result. If the reallocation is successful, TCL_OK is * returned, otherwise TCL_ERROR. * * Side effects: * Memory for the array is possibly reallocated. * *--------------------------------------------------------------------------- */ int Blt_Vec_SetLength( Tcl_Interp *interp, Vector *vPtr, int newLength) /* Size of array in elements */ { if (vPtr->size < newLength) { if (Blt_Vec_SetSize(interp, vPtr, newLength) != TCL_OK) { return TCL_ERROR; } } vPtr->length = newLength; vPtr->first = 0; vPtr->last = newLength - 1; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Vec_ChangeLength -- * * Resizes the vector to the new size. * * The new size of the vector is computed by doubling the size of the * vector until it fits the number of slots needed (designated by * *length*). * * If the new size is the same as the old, simply adjust the length of * the vector. Otherwise we're copying the data from one memory location * to another. The trailing elements of the vector need to be reset to * zero. * * If the storage changed memory locations, free up the old location if * it was dynamically allocated. * * Results: * A standard TCL result. If the reallocation is successful, * TCL_OK is returned, otherwise TCL_ERROR. * * Side effects: * Memory for the array is reallocated. * *--------------------------------------------------------------------------- */ int Blt_Vec_ChangeLength( Tcl_Interp *interp, Vector *vPtr, int newLength) { if (newLength < 0) { newLength = 0; } if (newLength > vPtr->size) { int newSize; /* Size of array in elements */ /* Compute the new size of the array. It's a multiple of * DEF_ARRAY_SIZE. */ newSize = DEF_ARRAY_SIZE; while (newSize < newLength) { newSize += newSize; } if (newSize != vPtr->size) { if (Blt_Vec_SetSize(interp, vPtr, newSize) != TCL_OK) { return TCL_ERROR; } } } vPtr->length = newLength; vPtr->first = 0; vPtr->last = newLength - 1; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Vec_Reset -- * * Resets the vector data. This is called by a client to indicate that * the vector data has changed. The vector does not need to point to * different memory. Any clients of the vector will be notified of the * change. * * Results: * A standard TCL result. If the new array size is invalid, TCL_ERROR is * returned. Otherwise TCL_OK is returned and the new vector data is * recorded. * * Side Effects: * Any client designated callbacks will be posted. Memory may be changed * for the vector array. * *--------------------------------------------------------------------------- */ int Blt_Vec_Reset( Vector *vPtr, double *valueArr, /* Array containing the elements of the * vector. If NULL, indicates to reset the * vector size to the default. */ int length, /* The number of elements that the vector * currently holds. */ int size, /* The maximum number of elements that the * array can hold. */ Tcl_FreeProc *freeProc) /* Address of memory deallocation routine * for the array of values. Can also be * TCL_STATIC, TCL_DYNAMIC, or TCL_VOLATILE. */ { if (vPtr->valueArr != valueArr) { /* New array of values resides * in different memory than * the current vector. */ if ((valueArr == NULL) || (size == 0)) { /* Empty array. Set up default values */ valueArr = Blt_Malloc(sizeof(double) * DEF_ARRAY_SIZE); size = DEF_ARRAY_SIZE; if (valueArr == NULL) { Tcl_AppendResult(vPtr->interp, "can't allocate ", Blt_Itoa(size), " elements for vector \"", vPtr->name, "\"", (char *)NULL); return TCL_ERROR; } freeProc = TCL_DYNAMIC; length = 0; } else if (freeProc == TCL_VOLATILE) { double *newArr; /* Data is volatile. Make a copy of the value array. */ newArr = Blt_Malloc(size * sizeof(double)); if (newArr == NULL) { Tcl_AppendResult(vPtr->interp, "can't allocate ", Blt_Itoa(size), " elements for vector \"", vPtr->name, "\"", (char *)NULL); return TCL_ERROR; } memcpy((char *)newArr, (char *)valueArr, sizeof(double) * length); valueArr = newArr; freeProc = TCL_DYNAMIC; } if (vPtr->freeProc != TCL_STATIC) { /* Old data was dynamically allocated. Free it before attaching * new data. */ if (vPtr->freeProc == TCL_DYNAMIC) { Blt_Free(vPtr->valueArr); } else { (*freeProc) ((char *)vPtr->valueArr); } } vPtr->freeProc = freeProc; vPtr->valueArr = valueArr; vPtr->size = size; } vPtr->length = length; if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } Vector * Blt_Vec_New(VectorInterpData *dataPtr) /* Interpreter-specific data. */ { Vector *vPtr; vPtr = Blt_AssertCalloc(1, sizeof(Vector)); vPtr->valueArr = Blt_Malloc(sizeof(double) * DEF_ARRAY_SIZE); if (vPtr->valueArr == NULL) { Blt_Free(vPtr); return NULL; } vPtr->size = DEF_ARRAY_SIZE; vPtr->freeProc = TCL_DYNAMIC; vPtr->length = 0; vPtr->interp = dataPtr->interp; vPtr->hashPtr = NULL; vPtr->chain = Blt_Chain_Create(); vPtr->flush = FALSE; vPtr->min = vPtr->max = Blt_NaN(); vPtr->notifyFlags = NOTIFY_WHENIDLE; vPtr->dataPtr = dataPtr; return vPtr; } /* *--------------------------------------------------------------------------- * * Blt_Vec_Free -- * * Removes the memory and frees resources associated with the vector. * * o Removes the trace and the TCL array variable and unsets * the variable. * o Notifies clients of the vector that the vector is being * destroyed. * o Removes any clients that are left after notification. * o Frees the memory (if necessary) allocated for the array. * o Removes the entry from the hash table of vectors. * o Frees the memory allocated for the name. * * Results: * None. * * Side effects: * *--------------------------------------------------------------------------- */ void Blt_Vec_Free(Vector *vPtr) { Blt_ChainLink link; if (vPtr->cmdToken != 0) { DeleteCommand(vPtr); } if (vPtr->arrayName != NULL) { UnmapVariable(vPtr); } vPtr->length = 0; /* Immediately notify clients that vector is going away */ if (vPtr->notifyFlags & NOTIFY_PENDING) { vPtr->notifyFlags &= ~NOTIFY_PENDING; Tcl_CancelIdleCall(Blt_Vec_NotifyClients, vPtr); } vPtr->notifyFlags |= NOTIFY_DESTROYED; Blt_Vec_NotifyClients(vPtr); for (link = Blt_Chain_FirstLink(vPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { VectorClient *clientPtr; clientPtr = Blt_Chain_GetValue(link); Blt_Free(clientPtr); } Blt_Chain_Destroy(vPtr->chain); if ((vPtr->valueArr != NULL) && (vPtr->freeProc != TCL_STATIC)) { if (vPtr->freeProc == TCL_DYNAMIC) { Blt_Free(vPtr->valueArr); } else { (*vPtr->freeProc) ((char *)vPtr->valueArr); } } if (vPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&vPtr->dataPtr->vectorTable, vPtr->hashPtr); } #ifdef NAMESPACE_DELETE_NOTIFY if (vPtr->nsPtr != NULL) { Blt_DestroyNsDeleteNotify(vPtr->interp, vPtr->nsPtr, vPtr); } #endif /* NAMESPACE_DELETE_NOTIFY */ Blt_Free(vPtr); } /* *--------------------------------------------------------------------------- * * VectorInstDeleteProc -- * * Deletes the command associated with the vector. This is called only * when the command associated with the vector is destroyed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void VectorInstDeleteProc(ClientData clientData) { Vector *vPtr = clientData; vPtr->cmdToken = 0; Blt_Vec_Free(vPtr); } /* *--------------------------------------------------------------------------- * * Blt_Vec_Create -- * * Creates a vector structure and the following items: * * o TCL command * o TCL array variable and establishes traces on the variable * o Adds a new entry in the vector hash table * * Results: * A pointer to the new vector structure. If an error occurred NULL is * returned and an error message is left in interp->result. * * Side effects: * A new TCL command and array variable is added to the interpreter. * * ---------------------------------------------------------------------- */ Vector * Blt_Vec_Create( VectorInterpData *dataPtr, /* Interpreter-specific data. */ const char *vecName, /* Namespace-qualified name of the vector */ const char *cmdName, /* Name of the TCL command mapped to * the vector */ const char *varName, /* Name of the TCL array mapped to the * vector */ int *isNewPtr) { Tcl_DString dString; Vector *vPtr; int isNew; Blt_ObjectName objName; char *qualName; Blt_HashEntry *hPtr; Tcl_Interp *interp = dataPtr->interp; isNew = 0; vPtr = NULL; if (!Blt_ParseObjectName(interp, vecName, &objName, 0)) { return NULL; } Tcl_DStringInit(&dString); if ((objName.name[0] == '#') && (strcmp(objName.name, "#auto") == 0)) { do { /* Generate a unique vector name. */ char string[200]; sprintf_s(string, 200, "vector%d", dataPtr->nextId++); objName.name = string; qualName = Blt_MakeQualifiedName(&objName, &dString); hPtr = Blt_FindHashEntry(&dataPtr->vectorTable, qualName); } while (hPtr != NULL); } else { const char *p; for (p = objName.name; *p != '\0'; p++) { if (!VECTOR_CHAR(*p)) { Tcl_AppendResult(interp, "bad vector name \"", objName.name, "\": must contain digits, letters, underscore, or period", (char *)NULL); goto error; } } qualName = Blt_MakeQualifiedName(&objName, &dString); vPtr = Blt_Vec_ParseElement((Tcl_Interp *)NULL, dataPtr, qualName, NULL, NS_SEARCH_CURRENT); } if (vPtr == NULL) { hPtr = Blt_CreateHashEntry(&dataPtr->vectorTable, qualName, &isNew); vPtr = Blt_Vec_New(dataPtr); vPtr->hashPtr = hPtr; vPtr->nsPtr = objName.nsPtr; vPtr->name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr); #ifdef NAMESPACE_DELETE_NOTIFY Blt_CreateNsDeleteNotify(interp, objName.nsPtr, vPtr, VectorInstDeleteProc); #endif /* NAMESPACE_DELETE_NOTIFY */ Blt_SetHashValue(hPtr, vPtr); } if (cmdName != NULL) { Tcl_CmdInfo cmdInfo; if ((cmdName == vecName) || ((cmdName[0] == '#') && (strcmp(cmdName, "#auto")==0))) { cmdName = qualName; } if (Tcl_GetCommandInfo(interp, (char *)cmdName, &cmdInfo)) { if (vPtr != cmdInfo.objClientData) { Tcl_AppendResult(interp, "command \"", cmdName, "\" already exists", (char *)NULL); goto error; } /* We get here only if the old name is the same as the new. */ goto checkVariable; } } if (vPtr->cmdToken != 0) { DeleteCommand(vPtr); /* Command already exists, delete old first */ } if (cmdName != NULL) { Tcl_DString dString2; Tcl_DStringInit(&dString2); if (cmdName != qualName) { if (!Blt_ParseObjectName(interp, cmdName, &objName, 0)) { goto error; } cmdName = Blt_MakeQualifiedName(&objName, &dString2); } vPtr->cmdToken = Tcl_CreateObjCommand(interp, (char *)cmdName, Blt_Vec_InstCmd, vPtr, VectorInstDeleteProc); Tcl_DStringFree(&dString2); } checkVariable: if (varName != NULL) { if ((varName[0] == '#') && (strcmp(varName, "#auto") == 0)) { varName = qualName; } if (Blt_Vec_MapVariable(interp, vPtr, varName) != TCL_OK) { goto error; } } Tcl_DStringFree(&dString); *isNewPtr = isNew; return vPtr; error: Tcl_DStringFree(&dString); if (vPtr != NULL) { Blt_Vec_Free(vPtr); } return NULL; } int Blt_Vec_Duplicate(Vector *destPtr, Vector *srcPtr) { size_t nBytes; size_t length; if (destPtr == srcPtr) { /* Copying the same vector. */ } length = srcPtr->last - srcPtr->first + 1; if (Blt_Vec_ChangeLength(destPtr->interp, destPtr, length) != TCL_OK) { return TCL_ERROR; } nBytes = length * sizeof(double); memcpy(destPtr->valueArr, srcPtr->valueArr + srcPtr->first, nBytes); destPtr->offset = srcPtr->offset; return TCL_OK; } /* *--------------------------------------------------------------------------- * * VectorNamesOp -- * * Reports the names of all the current vectors in the interpreter. * * Results: * A standard TCL result. interp->result will contain a list of * all the names of the vector instances. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int VectorNamesOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { VectorInterpData *dataPtr = clientData; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (objc == 2) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { char *name; name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(name, -1)); } } else { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { char *name; int i; name = Blt_GetHashKey(&dataPtr->vectorTable, hPtr); for (i = 2; i < objc; i++) { char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(name, pattern)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(name, -1)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * VectorCreateOp -- * * Creates a TCL command, and array variable representing an instance of * a vector. * * vector a * vector b(20) * vector c(-5:14) * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int VectorCreate2( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int argStart, int objc, Tcl_Obj *const *objv) { VectorInterpData *dataPtr = clientData; Vector *vPtr; int count, i; CreateSwitches switches; /* * Handle switches to the vector command and collect the vector name * arguments into an array. */ count = 0; vPtr = NULL; for (i = argStart; i < objc; i++) { char *string; string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } } count = i - argStart; if (count == 0) { Tcl_AppendResult(interp, "no vector names supplied", (char *)NULL); return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, createSwitches, objc - i, objv + i, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (count > 1) { if (switches.cmdName != NULL) { Tcl_AppendResult(interp, "can't specify more than one vector with \"-command\" switch", (char *)NULL); goto error; } if (switches.varName != NULL) { Tcl_AppendResult(interp, "can't specify more than one vector with \"-variable\" switch", (char *)NULL); goto error; } } for (i = 0; i < count; i++) { char *leftParen, *rightParen; char *string; int isNew; int size, first, last; size = first = last = 0; string = Tcl_GetString(objv[i + argStart]); leftParen = strchr(string, '('); rightParen = strchr(string, ')'); if (((leftParen != NULL) && (rightParen == NULL)) || ((leftParen == NULL) && (rightParen != NULL)) || (leftParen > rightParen)) { Tcl_AppendResult(interp, "bad vector specification \"", string, "\"", (char *)NULL); goto error; } if (leftParen != NULL) { int result; char *colon; *rightParen = '\0'; colon = strchr(leftParen + 1, ':'); if (colon != NULL) { /* Specification is in the form vecName(first:last) */ *colon = '\0'; result = Tcl_GetInt(interp, leftParen + 1, &first); if ((*(colon + 1) != '\0') && (result == TCL_OK)) { result = Tcl_GetInt(interp, colon + 1, &last); if (first > last) { Tcl_AppendResult(interp, "bad vector range \"", string, "\"", (char *)NULL); result = TCL_ERROR; } size = (last - first) + 1; } *colon = ':'; } else { /* Specification is in the form vecName(size) */ result = Tcl_GetInt(interp, leftParen + 1, &size); } *rightParen = ')'; if (result != TCL_OK) { goto error; } if (size < 0) { Tcl_AppendResult(interp, "bad vector size \"", string, "\"", (char *)NULL); goto error; } } if (leftParen != NULL) { *leftParen = '\0'; } /* * By default, we create a TCL command by the name of the vector. */ vPtr = Blt_Vec_Create(dataPtr, string, (switches.cmdName == NULL) ? string : switches.cmdName, (switches.varName == NULL) ? string : switches.varName, &isNew); if (leftParen != NULL) { *leftParen = '('; } if (vPtr == NULL) { goto error; } vPtr->freeOnUnset = switches.watchUnset; vPtr->flush = switches.flush; vPtr->offset = first; if (size > 0) { if (Blt_Vec_ChangeLength(interp, vPtr, size) != TCL_OK) { goto error; } } if (!isNew) { if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); } } Blt_FreeSwitches(createSwitches, (char *)&switches, 0); if (vPtr != NULL) { /* Return the name of the last vector created */ Tcl_SetStringObj(Tcl_GetObjResult(interp), vPtr->name, -1); } return TCL_OK; error: Blt_FreeSwitches(createSwitches, (char *)&switches, 0); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * VectorCreateOp -- * * Creates a TCL command, and array variable representing an instance of * a vector. * * vector a * vector b(20) * vector c(-5:14) * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int VectorCreateOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return VectorCreate2(clientData, interp, 2, objc, objv); } /* *--------------------------------------------------------------------------- * * VectorDestroyOp -- * * Destroys the vector and its related TCL command and array variable (if * they exist). * * Results: * A standard TCL result. * * Side effects: * Deletes the vector. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int VectorDestroyOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { VectorInterpData *dataPtr = clientData; Vector *vPtr; int i; for (i = 2; i < objc; i++) { if (Blt_Vec_LookupName(dataPtr, Tcl_GetString(objv[i]), &vPtr) != TCL_OK) { return TCL_ERROR; } Blt_Vec_Free(vPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * VectorExprOp -- * * Computes the result of the expression which may be either a scalar * (single value) or vector (list of values). * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int VectorExprOp( ClientData clientData, /* Not Used. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { return Blt_ExprVector(interp, Tcl_GetString(objv[2]), (Blt_Vector *)NULL); } static Blt_OpSpec vectorCmdOps[] = { {"create", 1, VectorCreateOp, 3, 0, "vecName ?vecName...? ?switches...?",}, {"destroy", 1, VectorDestroyOp, 3, 0, "vecName ?vecName...?",}, {"expr", 1, VectorExprOp, 3, 3, "expression",}, {"names", 1, VectorNamesOp, 2, 3, "?pattern?...",}, }; static int nCmdOps = sizeof(vectorCmdOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ static int VectorCmd( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { VectorCmdProc *proc; /* * Try to replicate the old vector command's behavior: */ if (objc > 1) { char *string; char c; int i; Blt_OpSpec *specPtr; string = Tcl_GetString(objv[1]); c = string[0]; for (specPtr = vectorCmdOps, i = 0; i < nCmdOps; i++, specPtr++) { if ((c == specPtr->name[0]) && (strcmp(string, specPtr->name) == 0)) { goto doOp; } } /* * The first argument is not an operation, so assume that its * actually the name of a vector to be created */ return VectorCreate2(clientData, interp, 1, objc, objv); } doOp: /* Do the usual vector operation lookup now. */ proc = Blt_GetOpFromObj(interp, nCmdOps, vectorCmdOps, BLT_OP_ARG1, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } return (*proc) (clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * VectorInterpDeleteProc -- * * This is called when the interpreter hosting the "vector" command * is deleted. * * Results: * None. * * Side effects: * Destroys the math and index hash tables. In addition removes * the hash table managing all vector names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void VectorInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { VectorInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->vectorTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Vector *vPtr; vPtr = Blt_GetHashValue(hPtr); vPtr->hashPtr = NULL; Blt_Vec_Free(vPtr); } Blt_DeleteHashTable(&dataPtr->vectorTable); /* If any user-defined math functions were installed, remove them. */ Blt_Vec_UninstallMathFunctions(&dataPtr->mathProcTable); Blt_DeleteHashTable(&dataPtr->mathProcTable); Blt_DeleteHashTable(&dataPtr->indexProcTable); Tcl_DeleteAssocData(interp, VECTOR_THREAD_KEY); Blt_Free(dataPtr); } VectorInterpData * Blt_Vec_GetInterpData(Tcl_Interp *interp) { VectorInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (VectorInterpData *) Tcl_GetAssocData(interp, VECTOR_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(VectorInterpData)); dataPtr->interp = interp; dataPtr->nextId = 0; Tcl_SetAssocData(interp, VECTOR_THREAD_KEY, VectorInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->vectorTable, BLT_STRING_KEYS); Blt_InitHashTable(&dataPtr->mathProcTable, BLT_STRING_KEYS); Blt_InitHashTable(&dataPtr->indexProcTable, BLT_STRING_KEYS); Blt_Vec_InstallMathFunctions(&dataPtr->mathProcTable); Blt_Vec_InstallSpecialIndices(&dataPtr->indexProcTable); #ifdef HAVE_SRAND48 srand48(time((time_t *) NULL)); #endif } return dataPtr; } /* *--------------------------------------------------------------------------- * * Blt_VectorCmdInitProc -- * * This procedure is invoked to initialize the "vector" command. * * Results: * None. * * Side effects: * Creates the new command and adds a new entry into a global Tcl * associative array. * *--------------------------------------------------------------------------- */ int Blt_VectorCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"vector", VectorCmd, }; cmdSpec.clientData = Blt_Vec_GetInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* C Application interface to vectors */ /* *--------------------------------------------------------------------------- * * Blt_CreateVector -- * * Creates a new vector by the name and size. * * Results: * A standard TCL result. If the new array size is invalid or a vector * already exists by that name, TCL_ERROR is returned. Otherwise TCL_OK * is returned and the new vector is created. * * Side Effects: * Memory will be allocated for the new vector. A new TCL command and * Tcl array variable will be created. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_CreateVector2( Tcl_Interp *interp, const char *vecName, const char *cmdName, const char *varName, int initialSize, Blt_Vector **vecPtrPtr) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr; int isNew; char *nameCopy; if (initialSize < 0) { Tcl_AppendResult(interp, "bad vector size \"", Blt_Itoa(initialSize), "\"", (char *)NULL); return TCL_ERROR; } dataPtr = Blt_Vec_GetInterpData(interp); nameCopy = Blt_AssertStrdup(vecName); vPtr = Blt_Vec_Create(dataPtr, nameCopy, cmdName, varName, &isNew); Blt_Free(nameCopy); if (vPtr == NULL) { return TCL_ERROR; } if (initialSize > 0) { if (Blt_Vec_ChangeLength(interp, vPtr, initialSize) != TCL_OK) { return TCL_ERROR; } } if (vecPtrPtr != NULL) { *vecPtrPtr = (Blt_Vector *) vPtr; } return TCL_OK; } int Blt_CreateVector( Tcl_Interp *interp, const char *name, int size, Blt_Vector **vecPtrPtr) { return Blt_CreateVector2(interp, name, name, name, size, vecPtrPtr); } /* *--------------------------------------------------------------------------- * * Blt_DeleteVector -- * * Deletes the vector of the given name. All clients with designated * callback routines will be notified. * * Results: * A standard TCL result. If no vector exists by that name, TCL_ERROR is * returned. Otherwise TCL_OK is returned and vector is deleted. * * Side Effects: * Memory will be released for the new vector. Both the TCL command and * array variable will be deleted. All clients which set call back * procedures will be notified. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_DeleteVector(Blt_Vector *vecPtr) { Vector *vPtr = (Vector *)vecPtr; Blt_Vec_Free(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_DeleteVectorByName -- * * Deletes the vector of the given name. All clients with designated * callback routines will be notified. * * Results: * A standard TCL result. If no vector exists by that name, TCL_ERROR is * returned. Otherwise TCL_OK is returned and vector is deleted. * * Side Effects: * Memory will be released for the new vector. Both the TCL command and * array variable will be deleted. All clients which set call back * procedures will be notified. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_DeleteVectorByName(Tcl_Interp *interp, const char *name) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr; char *nameCopy; int result; /* * If the vector name was passed via a read-only string (e.g. "x"), the * Blt_Vec_ParseElement routine will segfault when it tries to write into * the string. Therefore make a writable copy and free it when we're * done. */ nameCopy = Blt_AssertStrdup(name); dataPtr = Blt_Vec_GetInterpData(interp); result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr); Blt_Free(nameCopy); if (result != TCL_OK) { return TCL_ERROR; } Blt_Vec_Free(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_VectorExists2 -- * * Returns whether the vector associated with the client token still * exists. * * Results: * Returns 1 is the vector still exists, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_VectorExists2(Tcl_Interp *interp, const char *vecName) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ dataPtr = Blt_Vec_GetInterpData(interp); if (GetVectorObject(dataPtr, vecName, NS_SEARCH_BOTH) != NULL) { return TRUE; } return FALSE; } /* *--------------------------------------------------------------------------- * * Blt_VectorExists -- * * Returns whether the vector associated with the client token * still exists. * * Results: * Returns 1 is the vector still exists, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_VectorExists(Tcl_Interp *interp, const char *vecName) { char *nameCopy; int result; /* * If the vector name was passed via a read-only string (e.g. "x"), the * Blt_VectorParseName routine will segfault when it tries to write into * the string. Therefore make a writable copy and free it when we're * done. */ nameCopy = Blt_AssertStrdup(vecName); result = Blt_VectorExists2(interp, nameCopy); Blt_Free(nameCopy); return result; } /* *--------------------------------------------------------------------------- * * Blt_GetVector -- * * Returns a pointer to the vector associated with the given name. * * Results: * A standard TCL result. If there is no vector "name", TCL_ERROR is * returned. Otherwise TCL_OK is returned and vecPtrPtr will point to * the vector. * *--------------------------------------------------------------------------- */ int Blt_GetVector(Tcl_Interp *interp, const char *name, Blt_Vector **vecPtrPtr) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr; char *nameCopy; int result; dataPtr = Blt_Vec_GetInterpData(interp); /* * If the vector name was passed via a read-only string (e.g. "x"), the * Blt_VectorParseName routine will segfault when it tries to write into * the string. Therefore make a writable copy and free it when we're * done. */ nameCopy = Blt_AssertStrdup(name); result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr); Blt_Free(nameCopy); if (result != TCL_OK) { return TCL_ERROR; } Blt_Vec_UpdateRange(vPtr); *vecPtrPtr = (Blt_Vector *) vPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_GetVectorFromObj -- * * Returns a pointer to the vector associated with the given name. * * Results: * A standard TCL result. If there is no vector "name", TCL_ERROR * is returned. Otherwise TCL_OK is returned and vecPtrPtr will * point to the vector. * *--------------------------------------------------------------------------- */ int Blt_GetVectorFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Vector **vecPtrPtr) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr; dataPtr = Blt_Vec_GetInterpData(interp); if (Blt_Vec_LookupName(dataPtr, Tcl_GetString(objPtr), &vPtr) != TCL_OK) { return TCL_ERROR; } Blt_Vec_UpdateRange(vPtr); *vecPtrPtr = (Blt_Vector *) vPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ResetVector -- * * Resets the vector data. This is called by a client to indicate that * the vector data has changed. The vector does not need to point to * different memory. Any clients of the vector will be notified of the * change. * * Results: * A standard TCL result. If the new array size is invalid, * TCL_ERROR is returned. Otherwise TCL_OK is returned and the * new vector data is recorded. * * Side Effects: * Any client designated callbacks will be posted. Memory may * be changed for the vector array. * *--------------------------------------------------------------------------- */ int Blt_ResetVector( Blt_Vector *vecPtr, double *valueArr, /* Array containing the elements of the * vector. If NULL, indicates to reset the * vector.*/ int length, /* The number of elements that the vector * currently holds. */ int size, /* The maximum number of elements that the * array can hold. */ Tcl_FreeProc *freeProc) /* Address of memory deallocation routine * for the array of values. Can also be * TCL_STATIC, TCL_DYNAMIC, or TCL_VOLATILE. */ { Vector *vPtr = (Vector *)vecPtr; if (size < 0) { Tcl_AppendResult(vPtr->interp, "bad array size", (char *)NULL); return TCL_ERROR; } return Blt_Vec_Reset(vPtr, valueArr, length, size, freeProc); } /* *--------------------------------------------------------------------------- * * Blt_ResizeVector -- * * Changes the size of the vector. All clients with designated callback * routines will be notified of the size change. * * Results: * A standard TCL result. If no vector exists by that name, TCL_ERROR is * returned. Otherwise TCL_OK is returned and vector is resized. * * Side Effects: * Memory may be reallocated for the new vector size. All clients which * set call back procedures will be notified. * *--------------------------------------------------------------------------- */ int Blt_ResizeVector(Blt_Vector *vecPtr, int length) { Vector *vPtr = (Vector *)vecPtr; if (Blt_Vec_ChangeLength((Tcl_Interp *)NULL, vPtr, length) != TCL_OK) { Tcl_AppendResult(vPtr->interp, "can't resize vector \"", vPtr->name, "\"", (char *)NULL); return TCL_ERROR; } if (vPtr->flush) { Blt_Vec_FlushCache(vPtr); } Blt_Vec_UpdateClients(vPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_AllocVectorId -- * * Creates an identifier token for an existing vector. The identifier is * used by the client routines to get call backs when (and if) the vector * changes. * * Results: * A standard TCL result. If "vecName" is not associated with a vector, * TCL_ERROR is returned and interp->result is filled with an error * message. * *--------------------------------------------------------------------------- */ Blt_VectorId Blt_AllocVectorId(Tcl_Interp *interp, const char *name) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Vector *vPtr; VectorClient *clientPtr; Blt_VectorId clientId; int result; char *nameCopy; dataPtr = Blt_Vec_GetInterpData(interp); /* * If the vector name was passed via a read-only string (e.g. "x"), the * Blt_VectorParseName routine will segfault when it tries to write into * the string. Therefore make a writable copy and free it when we're * done. */ nameCopy = Blt_AssertStrdup(name); result = Blt_Vec_LookupName(dataPtr, nameCopy, &vPtr); Blt_Free(nameCopy); if (result != TCL_OK) { return (Blt_VectorId) 0; } /* Allocate a new client structure */ clientPtr = Blt_AssertCalloc(1, sizeof(VectorClient)); clientPtr->magic = VECTOR_MAGIC; /* Add the new client to the server's list of clients */ clientPtr->link = Blt_Chain_Append(vPtr->chain, clientPtr); clientPtr->serverPtr = vPtr; clientId = (Blt_VectorId) clientPtr; return clientId; } /* *--------------------------------------------------------------------------- * * Blt_SetVectorChangedProc -- * * Sets the routine to be called back when the vector is changed or * deleted. *clientData* will be provided as an argument. If *proc* is * NULL, no callback will be made. * * Results: * None. * * Side Effects: * The designated routine will be called when the vector is changed * or deleted. * *--------------------------------------------------------------------------- */ void Blt_SetVectorChangedProc( Blt_VectorId clientId, /* Client token identifying the vector */ Blt_VectorChangedProc *proc,/* Address of routine to call when the contents * of the vector change. If NULL, no routine * will be called */ ClientData clientData) /* One word of information to pass along when * the above routine is called */ { VectorClient *clientPtr = (VectorClient *)clientId; if (clientPtr->magic != VECTOR_MAGIC) { return; /* Not a valid token */ } clientPtr->clientData = clientData; clientPtr->proc = proc; } /* *--------------------------------------------------------------------------- * * Blt_FreeVectorId -- * * Releases the token for an existing vector. This indicates that the * client is no longer interested the vector. Any previously specified * callback routine will no longer be invoked when (and if) the vector * changes. * * Results: * None. * * Side Effects: * Any previously specified callback routine will no longer be * invoked when (and if) the vector changes. * *--------------------------------------------------------------------------- */ void Blt_FreeVectorId(Blt_VectorId clientId) { VectorClient *clientPtr = (VectorClient *)clientId; if (clientPtr->magic != VECTOR_MAGIC) { return; /* Not a valid token */ } if (clientPtr->serverPtr != NULL) { /* Remove the client from the server's list */ Blt_Chain_DeleteLink(clientPtr->serverPtr->chain, clientPtr->link); } Blt_Free(clientPtr); } /* *--------------------------------------------------------------------------- * * Blt_NameOfVectorId -- * * Returns the name of the vector (and array variable). * * Results: * The name of the array variable is returned. * *--------------------------------------------------------------------------- */ const char * Blt_NameOfVectorId(Blt_VectorId clientId) { VectorClient *clientPtr = (VectorClient *)clientId; if ((clientPtr->magic != VECTOR_MAGIC) || (clientPtr->serverPtr == NULL)) { return NULL; } return clientPtr->serverPtr->name; } const char * Blt_NameOfVector(Blt_Vector *vecPtr) /* Vector to query. */ { Vector *vPtr = (Vector *)vecPtr; return vPtr->name; } /* *--------------------------------------------------------------------------- * * Blt_VectorNotifyPending -- * * Returns the name of the vector (and array variable). * * Results: * The name of the array variable is returned. * *--------------------------------------------------------------------------- */ int Blt_VectorNotifyPending(Blt_VectorId clientId) { VectorClient *clientPtr = (VectorClient *)clientId; if ((clientPtr == NULL) || (clientPtr->magic != VECTOR_MAGIC) || (clientPtr->serverPtr == NULL)) { return 0; } return (clientPtr->serverPtr->notifyFlags & NOTIFY_PENDING); } /* *--------------------------------------------------------------------------- * * Blt_GetVectorById -- * * Returns a pointer to the vector associated with the client * token. * * Results: * A standard TCL result. If the client token is not associated * with a vector any longer, TCL_ERROR is returned. Otherwise, * TCL_OK is returned and vecPtrPtr will point to vector. * *--------------------------------------------------------------------------- */ int Blt_GetVectorById( Tcl_Interp *interp, Blt_VectorId clientId, /* Client token identifying the vector */ Blt_Vector **vecPtrPtr) { VectorClient *clientPtr = (VectorClient *)clientId; if (clientPtr->magic != VECTOR_MAGIC) { Tcl_AppendResult(interp, "bad vector token", (char *)NULL); return TCL_ERROR; } if (clientPtr->serverPtr == NULL) { Tcl_AppendResult(interp, "vector no longer exists", (char *)NULL); return TCL_ERROR; } Blt_Vec_UpdateRange(clientPtr->serverPtr); *vecPtrPtr = (Blt_Vector *) clientPtr->serverPtr; return TCL_OK; } /*LINTLIBRARY*/ void Blt_InstallIndexProc(Tcl_Interp *interp, const char *string, Blt_VectorIndexProc *procPtr) { VectorInterpData *dataPtr; /* Interpreter-specific data. */ Blt_HashEntry *hPtr; int isNew; dataPtr = Blt_Vec_GetInterpData(interp); hPtr = Blt_CreateHashEntry(&dataPtr->indexProcTable, string, &isNew); if (procPtr == NULL) { Blt_DeleteHashEntry(&dataPtr->indexProcTable, hPtr); } else { Blt_SetHashValue(hPtr, procPtr); } } /* spinellia@acm.org START */ #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr /* routine by Brenner * data is the array of complex data points, perversely * starting at 1 * nn is the number of complex points, i.e. half the length of data * isign is 1 for forward, -1 for inverse */ static void four1(double *data, unsigned long nn, int isign) { unsigned long n,mmax,m,j,istep,i; double wtemp,wr,wpr,wpi,wi,theta; double tempr,tempi; n=nn << 1; j=1; for (i = 1;i<n;i+=2) { if (j > i) { SWAP(data[j],data[i]); SWAP(data[j+1],data[i+1]); } m=n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } mmax=2; while (n > mmax) { istep=mmax << 1; theta=isign*(6.28318530717959/mmax); wtemp=sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi=sin(theta); wr=1.0; wi=0.0; for (m=1;m<mmax;m+=2) { for (i=m;i<=n;i+=istep) { j=i+mmax; tempr=wr*data[j]-wi*data[j+1]; tempi=wr*data[j+1]+wi*data[j]; data[j]=data[i]-tempr; data[j+1]=data[i+1]-tempi; data[i] += tempr; data[i+1] += tempi; } wr=(wtemp=wr)*wpr-wi*wpi+wr; wi=wi*wpr+wtemp*wpi+wi; } mmax=istep; } } #undef SWAP static int smallest_power_of_2_not_less_than(int x) { int pow2 = 1; while (pow2 < x){ pow2 <<= 1; } return pow2; } int Blt_Vec_FFT( Tcl_Interp *interp, /* Interpreter to report errors to */ Vector *realPtr, /* If non-NULL, indicates to compute and store the real values in this vector. */ Vector *phasesPtr, /* If non-NULL, indicates to compute * and store the imaginary values in * this vector. */ Vector *freqPtr, /* If non-NULL, indicates to compute * and store the frequency values in * this vector. */ double delta, /* */ int flags, /* Bit mask representing various * flags: FFT_NO_constANT, * FFT_SPECTRUM, and FFT_BARTLETT. */ Vector *srcPtr) { int length; int pow2len; double *paddedData; int i; double Wss = 0.0; /* TENTATIVE */ int middle = 1; int noconstant; noconstant = (flags & FFT_NO_CONSTANT) ? 1 : 0; /* Length of the original vector. */ length = srcPtr->last - srcPtr->first + 1; /* new length */ pow2len = smallest_power_of_2_not_less_than( length ); /* We do not do in-place FFTs */ if (realPtr == srcPtr) { Tcl_AppendResult(interp, "real vector \"", realPtr->name, "\" can't be the same as the source", (char *)NULL); return TCL_ERROR; } if (phasesPtr != NULL) { if (phasesPtr == srcPtr) { Tcl_AppendResult(interp, "imaginary vector \"", phasesPtr->name, "\" can't be the same as the source", (char *)NULL); return TCL_ERROR; } if (Blt_Vec_ChangeLength(interp, phasesPtr, pow2len/2-noconstant+middle) != TCL_OK) { return TCL_ERROR; } } if (freqPtr != NULL) { if (freqPtr == srcPtr) { Tcl_AppendResult(interp, "frequency vector \"", freqPtr->name, "\" can't be the same as the source", (char *)NULL); return TCL_ERROR; } if (Blt_Vec_ChangeLength(interp, freqPtr, pow2len/2-noconstant+middle) != TCL_OK) { return TCL_ERROR; } } /* Allocate memory zero-filled array. */ paddedData = Blt_Calloc(pow2len * 2, sizeof(double)); if (paddedData == NULL) { Tcl_AppendResult(interp, "can't allocate memory for padded data", (char *)NULL); return TCL_ERROR; } /* * Since we just do real transforms, only even locations will be * filled with data. */ if (flags & FFT_BARTLETT) { /* Bartlett window 1 - ( (x - N/2) / (N/2) ) */ double Nhalf = pow2len*0.5; double Nhalf_1 = 1.0 / Nhalf; double w; for (i = 0; i < length; i++) { w = 1.0 - fabs( (i-Nhalf) * Nhalf_1 ); Wss += w; paddedData[2*i] = w * srcPtr->valueArr[i]; } for(/*empty*/; i < pow2len; i++) { w = 1.0 - fabs((i-Nhalf) * Nhalf_1); Wss += w; } } else { /* Squared window, i.e. no data windowing. */ for (i = 0; i < length; i++) { paddedData[2*i] = srcPtr->valueArr[i]; } Wss = pow2len; } /* Fourier */ four1(paddedData-1, pow2len, 1); /* for(i=0;i<pow2len;i++){ printf( "(%f %f) ", paddedData[2*i], paddedData[2*i+1] ); } */ /* the spectrum is the modulus of the transforms, scaled by 1/N^2 */ /* or 1/(N * Wss) for windowed data */ if (flags & FFT_SPECTRUM) { double re, im, reS, imS; double factor = 1.0 / (pow2len*Wss); double *v = realPtr->valueArr; for (i = 0 + noconstant; i < pow2len / 2; i++) { re = paddedData[2*i]; im = paddedData[2*i+1]; reS = paddedData[2*pow2len-2*i-2]; imS = paddedData[2*pow2len-2*i-1]; v[i - noconstant] = factor * ( # if 0 hypot( paddedData[2*i], paddedData[2*i+1] ) + hypot( paddedData[pow2len*2-2*i-2], paddedData[pow2len*2-2*i-1] ) # else sqrt( re*re + im* im ) + sqrt( reS*reS + imS*imS ) # endif ); } } else { for(i = 0 + noconstant; i < pow2len / 2 + middle; i++) { realPtr->valueArr[i - noconstant] = paddedData[2*i]; } } if( phasesPtr != NULL ){ for (i = 0 + noconstant; i < pow2len / 2 + middle; i++) { phasesPtr->valueArr[i-noconstant] = paddedData[2*i+1]; } } /* Compute frequencies */ if (freqPtr != NULL) { double N = pow2len; double denom = 1.0 / N / delta; for( i=0+noconstant; i<pow2len/2+middle; i++ ){ freqPtr->valueArr[i-noconstant] = ((double) i) * denom; } } /* Memory is necessarily dynamic, because nobody touched it ! */ Blt_Free(paddedData); realPtr->offset = 0; return TCL_OK; } int Blt_Vec_InverseFFT(Tcl_Interp *interp, Vector *srcImagPtr, Vector *destRealPtr, Vector *destImagPtr, Vector *srcPtr) { int length; int pow2len; double *paddedData; int i; double oneOverN; if ((destRealPtr == srcPtr) || (destImagPtr == srcPtr )){ /* we do not do in-place FFTs */ return TCL_ERROR; } length = srcPtr->last - srcPtr->first + 1; /* minus one because of the magical middle element! */ pow2len = smallest_power_of_2_not_less_than( (length-1)*2 ); oneOverN = 1.0 / pow2len; if (Blt_Vec_ChangeLength(interp, destRealPtr, pow2len) != TCL_OK) { return TCL_ERROR; } if (Blt_Vec_ChangeLength(interp, destImagPtr, pow2len) != TCL_OK) { return TCL_ERROR; } if( length != (srcImagPtr->last - srcImagPtr->first + 1) ){ Tcl_AppendResult(srcPtr->interp, "the length of the imagPart vector must ", "be the same as the real one", (char *)NULL); return TCL_ERROR; } paddedData = Blt_AssertMalloc( pow2len*2*sizeof(double) ); if( paddedData == NULL ){ if (interp != NULL) { Tcl_AppendResult(interp, "memory allocation failed", (char *)NULL); } return TCL_ERROR; } for(i=0;i<pow2len*2;i++) { paddedData[i] = 0.0; } for(i=0;i<length-1;i++){ paddedData[2*i] = srcPtr->valueArr[i]; paddedData[2*i+1] = srcImagPtr->valueArr[i]; paddedData[pow2len*2 - 2*i - 2 ] = srcPtr->valueArr[i+1]; paddedData[pow2len*2 - 2*i - 1 ] = - srcImagPtr->valueArr[i+1]; } /* mythical middle element */ paddedData[(length-1)*2] = srcPtr->valueArr[length-1]; paddedData[(length-1)*2+1] = srcImagPtr->valueArr[length-1]; /* for(i=0;i<pow2len;i++){ printf( "(%f %f) ", paddedData[2*i], paddedData[2*i+1] ); } */ /* fourier */ four1( paddedData-1, pow2len, -1 ); /* put values in their places, normalising by 1/N */ for(i=0;i<pow2len;i++){ destRealPtr->valueArr[i] = paddedData[2*i] * oneOverN; destImagPtr->valueArr[i] = paddedData[2*i+1] * oneOverN; } /* memory is necessarily dynamic, because nobody touched it ! */ Blt_Free( paddedData ); return TCL_OK; } /* spinellia@acm.org STOP */ static double FindSplit(Point2d *points, int i, int j, int *split) { double maxDist2; maxDist2 = -1.0; if ((i + 1) < j) { int k; double a, b, c; /* * * dist2 P(k) = | 1 P(i).x P(i).y | * | 1 P(j).x P(j).y | * | 1 P(k).x P(k).y | * ------------------------------------------ * (P(i).x - P(j).x)^2 + (P(i).y - P(j).y)^2 */ a = points[i].y - points[j].y; b = points[j].x - points[i].x; c = (points[i].x * points[j].y) - (points[i].y * points[j].x); for (k = (i + 1); k < j; k++) { double dist2; dist2 = (points[k].x * a) + (points[k].y * b) + c; if (dist2 < 0.0) { dist2 = -dist2; } if (dist2 > maxDist2) { maxDist2 = dist2; /* Track the maximum. */ *split = k; } } /* Correction for segment length---should be redone if can == 0 */ maxDist2 *= maxDist2 / (a * a + b * b); } return maxDist2; } /* Douglas-Peucker line simplification algorithm */ int Blt_SimplifyLine(Point2d *inputPts, int low, int high, double tolerance, int *indices) { #define StackPush(a) s++, stack[s] = (a) #define StackPop(a) (a) = stack[s], s-- #define StackEmpty() (s < 0) #define StackTop() stack[s] int *stack; int split = -1; double dist2, tolerance2; int s = -1; /* Points to top stack item. */ int count; stack = Blt_AssertMalloc(sizeof(int) * (high - low + 1)); StackPush(high); count = 0; indices[count++] = 0; tolerance2 = tolerance * tolerance; while (!StackEmpty()) { dist2 = FindSplit(inputPts, low, StackTop(), &split); if (dist2 > tolerance2) { StackPush(split); } else { indices[count++] = StackTop(); StackPop(low); } } Blt_Free(stack); return count; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrElem.h�������������������������������������������������������������������0000644�0001750�0001750�00000021532�11462120062�015056� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrElem.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_GR_ELEM_H #define _BLT_GR_ELEM_H #include <bltVector.h> #include <bltDataTable.h> #define ELEM_SOURCE_VALUES 0 #define ELEM_SOURCE_VECTOR 1 #define ELEM_SOURCE_TABLE 2 #define SEARCH_X 0 #define SEARCH_Y 1 #define SEARCH_BOTH 2 #define SHOW_NONE 0 #define SHOW_X 1 #define SHOW_Y 2 #define SHOW_BOTH 3 #define SEARCH_POINTS 0 /* Search for closest data point. */ #define SEARCH_TRACES 1 /* Search for closest point on trace. * Interpolate the connecting line segments if * necessary. */ #define SEARCH_AUTO 2 /* Automatically determine whether to search * for data points or traces. Look for traces * if the linewidth is > 0 and if there is * more than one data point. */ #define LABEL_ACTIVE (1<<9) /* Non-zero indicates that the element's entry * in the legend should be drawn in its active * foreground and background colors. */ #define SCALE_SYMBOL (1<<10) #define NUMBEROFPOINTS(e) MIN((e)->x.nValues, (e)->y.nValues) #define NORMALPEN(e) ((((e)->normalPenPtr == NULL) ? \ (e)->builtinPenPtr : \ (e)->normalPenPtr)) /* *--------------------------------------------------------------------------- * * Weight -- * * Designates a range of values by a minimum and maximum limit. * *--------------------------------------------------------------------------- */ typedef struct { double min, max, range; } Weight; #define SetRange(l) \ ((l).range = ((l).max > (l).min) ? ((l).max - (l).min) : DBL_EPSILON) #define SetScale(l) \ ((l).scale = 1.0 / (l).range) #define SetWeight(l, lo, hi) \ ((l).min = (lo), (l).max = (hi), SetRange(l)) typedef struct { Segment2d *segments; /* Point to start of this pen's X-error bar * segments in the element's array. */ int nSegments; } ErrorBarSegments; /* * An element has one or more vectors plus several attributes, such as line * style, thickness, color, and symbol type. It has an identifier which * distinguishes it among the list of all elements. */ typedef struct { Weight weight; /* Weight range where this pen is valid. */ Pen *penPtr; /* Pen to use. */ } PenStyle; typedef struct { XColor *color; /* Color of error bar */ int lineWidth; /* Width of the error bar segments. */ GC gc; int show; /* Flags for errorbars: none, x, y, or both */ } ErrorBarAttributes; typedef struct { /* Inputs */ int halo; /* Maximal screen distance a candidate point * can be from the sample window coordinate */ int mode; /* Indicates whether to find the closest data * point or the closest point on the trace by * interpolating the line segments. Can also * be SEARCH_AUTO, indicating to choose how to * search.*/ int x, y; /* Screen coordinates of test point */ int along; /* Indicates to let search run along a * particular axis: x, y, or both. */ /* Outputs */ Element *elemPtr; /* Name of the closest element */ Point2d point; /* Graph coordinates of closest point */ int index; /* Index of closest data point */ double dist; /* Distance in screen coordinates */ } ClosestSearch; typedef void (ElementDrawProc) (Graph *graphPtr, Drawable drawable, Element *elemPtr); typedef void (ElementToPostScriptProc) (Graph *graphPtr, Blt_Ps ps, Element *elemPtr); typedef void (ElementDestroyProc) (Graph *graphPtr, Element *elemPtr); typedef int (ElementConfigProc) (Graph *graphPtr, Element *elemPtr); typedef void (ElementMapProc) (Graph *graphPtr, Element *elemPtr); typedef void (ElementExtentsProc) (Element *elemPtr, Region2d *extsPtr); typedef void (ElementClosestProc) (Graph *graphPtr, Element *elemPtr, ClosestSearch *searchPtr); typedef void (ElementDrawSymbolProc) (Graph *graphPtr, Drawable drawable, Element *elemPtr, int x, int y, int symbolSize); typedef void (ElementSymbolToPostScriptProc) (Graph *graphPtr, Blt_Ps ps, Element *elemPtr, double x, double y, int symSize); typedef struct { ElementClosestProc *closestProc; ElementConfigProc *configProc; ElementDestroyProc *destroyProc; ElementDrawProc *drawActiveProc; ElementDrawProc *drawNormalProc; ElementDrawSymbolProc *drawSymbolProc; ElementExtentsProc *extentsProc; ElementToPostScriptProc *printActiveProc; ElementToPostScriptProc *printNormalProc; ElementSymbolToPostScriptProc *printSymbolProc; ElementMapProc *mapProc; } ElementProcs; typedef struct { Blt_VectorId vector; } VectorDataSource; typedef struct { Blt_Table table; /* Data table. */ Blt_TableColumn column; /* Column of data used. */ Blt_TableNotifier notifier; /* Notifier used for column destroy * event. */ Blt_TableTrace trace; /* Trace used for column * (set/get/unset). */ Blt_HashEntry *hashPtr; /* Pointer to the entry of the data * source in graph's hash table of * datatables. One graph may use * multiple columns from the same data * table. */ } TableDataSource; /* * The data structure below contains information pertaining to a line vector. * It consists of an array of floating point data values and for convenience, * the number and minimum/maximum values. */ typedef struct { int type; /* Selects the type of data populating this * vector: ELEM_SOURCE_VECTOR, * ELEM_SOURCE_TABLE, or ELEM_SOURCE_VALUES */ Element *elemPtr; /* Element associated with vector. */ union { TableDataSource tableSource; VectorDataSource vectorSource; }; double *values; int nValues; int arraySize; double min, max; } ElemValues; struct _Element { GraphObj obj; /* Must be first field in element. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to elements. */ const char *label; /* Label displayed in legend */ unsigned short row, col; /* Position of the entry in the * legend. */ int legendRelief; /* Relief of label in legend. */ Axis2d axes; /* X-axis and Y-axis mapping the * element */ ElemValues x, y, w; /* Contains array of floating point * graph coordinate values. Also holds * min/max and the number of * coordinates */ int *activeIndices; /* Array of indices (malloc-ed) which * indicate which data points are * active (drawn with "active" * colors). */ int nActiveIndices; /* Number of active data points. * Special case: if nActiveIndices < 0 * and the active bit is set in * "flags", then all data points are * drawn active. */ ElementProcs *procsPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications. */ Pen *activePenPtr; /* Standard Pens */ Pen *normalPenPtr; Pen *builtinPenPtr; Blt_Chain stylePalette; /* Palette of pens. */ /* Symbol scaling */ int scaleSymbols; /* If non-zero, the symbols will scale * in size as the graph is zoomed * in/out. */ double xRange, yRange; /* Initial X-axis and Y-axis ranges: * used to scale the size of element's * symbol. */ int state; Blt_ChainLink link; /* Element's link in display list. */ }; BLT_EXTERN double Blt_FindElemValuesMinimum(ElemValues *vecPtr, double minLimit); BLT_EXTERN void Blt_ResizeStatusArray(Element *elemPtr, int nPoints); BLT_EXTERN int Blt_GetPenStyle(Graph *graphPtr, char *name, size_t classId, PenStyle *stylePtr); BLT_EXTERN void Blt_FreeStylePalette (Blt_Chain stylePalette); BLT_EXTERN PenStyle **Blt_StyleMap (Element *elemPtr); BLT_EXTERN void Blt_MapErrorBars(Graph *graphPtr, Element *elemPtr, PenStyle **dataToStyle); BLT_EXTERN void Blt_FreeDataValues(ElemValues *evPtr); BLT_EXTERN int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Element **elemPtrPtr); BLT_EXTERN void Blt_DestroyTableClients(Graph *graphPtr); #endif /* _BLT_GR_ELEM_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkConsole.c�������������������������������������������������������������������0000644�0001750�0001750�00000042325�11462120063�015141� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkConsole.c -- * * This file implements a TCL console for systems that may not * otherwise have access to a console. It uses the Text widget * and provides special access via a console command. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkConsole.c 1.55 98/01/02 17:40:37 */ #include "config.h" #undef USE_TK_STUBS #undef USE_TCL_STUBS #include "blt.h" #include <tcl.h> #include <tk.h> #include <locale.h> #include <stdio.h> #ifdef HAVE_STRING_H #include <string.h> #endif #define _VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #define _TCL_VERSION _VERSION(TCL_MAJOR_VERSION, TCL_MINOR_VERSION, TCL_RELEASE_SERIAL) #define _TK_VERSION _VERSION(TK_MAJOR_VERSION, TK_MINOR_VERSION, TK_RELEASE_SERIAL) #if (_TCL_VERSION < _VERSION(8,2,0)) /* * A data structure of the following type holds information for each console * which a handler (i.e. a TCL command) has been defined for a particular * top-level window. */ typedef struct { Tcl_Interp *consoleInterp; /* Interpreter for the console. */ Tcl_Interp *interp; /* Interpreter to send console commands. */ } ConsoleInfo; static Tcl_Interp *gStdoutInterp = NULL; #if (_TCL_VERSION < _VERSION(8,1,0)) #define HAVE_BROKEN_LIB_PATH 1 #undef HAVE_UTF #endif #if (_TCL_VERSION >= _VERSION(8,1,1)) #define HAVE_UTF 1 extern void TclInitSubsystems _ANSI_ARGS_((const char *argv0)); #else #endif /* * Forward declarations for procedures defined later in this file: * * The first three will be used in the tk app shells... */ extern Tcl_AppInitProc Blt_ConsoleInit; extern void Blt_ConsoleCreate _ANSI_ARGS_((void)); static Tcl_CmdDeleteProc ConsoleDeleteProc; static Tcl_CmdProc ConsoleCmd; static Tcl_CmdProc InterpreterCmd; static Tk_EventProc ConsoleEventProc; static void ConsolePrint _ANSI_ARGS_((Tcl_Interp *interp, int devId, const char *buffer, long size)); static int ConsoleInput _ANSI_ARGS_((ClientData instanceData, char *buf, int toRead, int *errorCode)); static int ConsoleOutput _ANSI_ARGS_((ClientData instanceData, char *buf, int toWrite, int *errorCode)); static int ConsoleClose _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp)); static void ConsoleWatch _ANSI_ARGS_((ClientData instanceData, int mask)); static int ConsoleHandle _ANSI_ARGS_((ClientData instanceData, int direction, ClientData *handlePtr)); /* * This structure describes the channel type structure for file based IO: */ static Tcl_ChannelType consoleChannelType = { "console", /* Type name. */ NULL, /* Always non-blocking.*/ ConsoleClose, /* Close proc. */ ConsoleInput, /* Input proc. */ ConsoleOutput, /* Output proc. */ NULL, /* Seek proc. */ NULL, /* Set option proc. */ NULL, /* Get option proc. */ ConsoleWatch, /* Watch for events on console. */ ConsoleHandle, /* Get a handle from the device. */ }; /* *--------------------------------------------------------------------------- * * Blt_ConsoleCreate -- * * Create the console channels and install them as the standard * channels. All I/O will be discarded until Blt_ConsoleInit is * called to attach the console to a text widget. * * Results: * None. * * Side effects: * Creates the console channel and installs it as the standard * channels. * *--------------------------------------------------------------------------- */ void Blt_ConsoleCreate() { Tcl_Channel channel; #ifdef HAVE_UTF TclInitSubsystems(NULL); #endif channel = Tcl_CreateChannel(&consoleChannelType, "console0", (ClientData)TCL_STDIN, TCL_READABLE); if (channel != NULL) { Tcl_SetChannelOption(NULL, channel, "-translation", "lf"); Tcl_SetChannelOption(NULL, channel, "-buffering", "none"); #ifdef HAVE_UTF Tcl_SetChannelOption(NULL, channel, "-encoding", "utf-8"); #endif } Tcl_SetStdChannel(channel, TCL_STDIN); channel = Tcl_CreateChannel(&consoleChannelType, "console1", (ClientData)TCL_STDOUT, TCL_WRITABLE); if (channel != NULL) { Tcl_SetChannelOption(NULL, channel, "-translation", "lf"); Tcl_SetChannelOption(NULL, channel, "-buffering", "none"); #ifdef HAVE_UTF Tcl_SetChannelOption(NULL, channel, "-encoding", "utf-8"); #endif } Tcl_SetStdChannel(channel, TCL_STDOUT); channel = Tcl_CreateChannel(&consoleChannelType, "console2", (ClientData)TCL_STDERR, TCL_WRITABLE); if (channel != NULL) { Tcl_SetChannelOption(NULL, channel, "-translation", "lf"); Tcl_SetChannelOption(NULL, channel, "-buffering", "none"); #ifdef HAVE_UTF Tcl_SetChannelOption(NULL, channel, "-encoding", "utf-8"); #endif } Tcl_SetStdChannel(channel, TCL_STDERR); } /* *--------------------------------------------------------------------------- * * Blt_ConsoleInit -- * * Initialize the console. This code actually creates a new * application and associated interpreter. This effectivly hides * the implementation from the main application. * * Results: * None. * * Side effects: * A new console it created. * *--------------------------------------------------------------------------- */ int Blt_ConsoleInit(interp) Tcl_Interp *interp; /* Interpreter to use for prompting. */ { Tcl_Interp *consoleInterp; ConsoleInfo *info; Tk_Window tkMain = Tk_MainWindow(interp); #ifdef MAC_TCL static char initCmd[] = "source -rsrc {Console}"; #else static char initCmd[] = "source $tk_library/console.tcl"; #endif consoleInterp = Tcl_CreateInterp(); if (consoleInterp == NULL) { goto error; } #if defined(HAVE_BROKEN_LIB_PATH) && defined(TCLLIBPATH) Tcl_SetVar(consoleInterp, "tclDefaultLibrary", TCLLIBPATH, TCL_GLOBAL_ONLY); #endif /* * Initialized TCL and Tk. */ if (Tcl_Init(consoleInterp) != TCL_OK) { goto error; } if (Tk_Init(consoleInterp) != TCL_OK) { goto error; } gStdoutInterp = interp; /* * Add console commands to the interp */ info = Tcl_Alloc(sizeof(ConsoleInfo)); info->interp = interp; info->consoleInterp = consoleInterp; Tcl_CreateCommand(interp, "console", ConsoleCmd, info, (Tcl_CmdDeleteProc *)ConsoleDeleteProc); Tcl_CreateCommand(consoleInterp, "consoleinterp", InterpreterCmd, info, (Tcl_CmdDeleteProc *)NULL); Tk_CreateEventHandler(tkMain, StructureNotifyMask, ConsoleEventProc, info); Tcl_Preserve(consoleInterp); if (Tcl_Eval(consoleInterp, initCmd) == TCL_ERROR) { /* goto error; -- no problem for now... */ printf("Eval error: %s", consoleInterp->result); } Tcl_Release((ClientData)consoleInterp); return TCL_OK; error: if (consoleInterp != NULL) { Tcl_DeleteInterp(consoleInterp); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ConsolePrint -- * * Prints to the give text to the console. Given the main interp * this functions find the appropiate console interp and forwards * the text to be added to that console. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static void ConsolePrint(interp, devId, buffer, size) Tcl_Interp *interp; /* Main interpreter. */ int devId; /* TCL_STDOUT for stdout, TCL_STDERR for * stderr. */ const char *buffer; /* Text buffer. */ long size; /* Size of text buffer. */ { Tcl_DString command, output; Tcl_CmdInfo cmdInfo; char *cmd; ConsoleInfo *info; Tcl_Interp *consoleInterp; int result; if (interp == NULL) { return; } if (devId == TCL_STDERR) { cmd = "tkConsoleOutput stderr "; } else { cmd = "tkConsoleOutput stdout "; } result = Tcl_GetCommandInfo(interp, "console", &cmdInfo); if (result == 0) { return; } info = (ConsoleInfo *) cmdInfo.clientData; Tcl_DStringInit(&output); Tcl_DStringAppend(&output, buffer, size); Tcl_DStringInit(&command); Tcl_DStringAppend(&command, cmd, strlen(cmd)); Tcl_DStringAppendElement(&command, output.string); consoleInterp = info->consoleInterp; Tcl_Preserve((ClientData)consoleInterp); Tcl_Eval(consoleInterp, command.string); Tcl_Release((ClientData)consoleInterp); Tcl_DStringFree(&command); Tcl_DStringFree(&output); } /* *--------------------------------------------------------------------------- * * ConsoleOutput-- * * Writes the given output on the IO channel. Returns count of how * many characters were actually written, and an error indication. * * Results: * A count of how many characters were written is returned and an * error indication is returned in an output argument. * * Side effects: * Writes output on the actual channel. * *--------------------------------------------------------------------------- */ static int ConsoleOutput(instanceData, buf, toWrite, errorCode) ClientData instanceData; /* Indicates which device to use. */ char *buf; /* The data buffer. */ int toWrite; /* How many bytes to write? */ int *errorCode; /* Where to store error code. */ { *errorCode = 0; Tcl_SetErrno(0); if (gStdoutInterp != NULL) { ConsolePrint(gStdoutInterp, (int)instanceData, buf, toWrite); } return toWrite; } /* *--------------------------------------------------------------------------- * * ConsoleInput -- * * Read input from the console. Not currently implemented. * * Results: * Always returns EOF. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ConsoleInput(instanceData, buf, bufSize, errorCode) ClientData instanceData; /* Not Used.. */ char *buf; /* Where to store data read. */ int bufSize; /* How much space is available * in the buffer? */ int *errorCode; /* Where to store error code. */ { return 0; /* Always return EOF. */ } /* *--------------------------------------------------------------------------- * * ConsoleClose -- * * Closes the IO channel. * * Results: * Always returns 0 (success). * * Side effects: * Frees the dummy file associated with the channel. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ConsoleClose(instanceData, interp) ClientData instanceData; /* Not Used.. */ Tcl_Interp *interp; /* Not Used.. */ { return 0; } /* *--------------------------------------------------------------------------- * * ConsoleWatch -- * * Called by the notifier to set up the console device so that * events will be noticed. Since there are no events on the * console, this routine just returns without doing anything. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ConsoleWatch(instanceData, mask) ClientData instanceData; /* Device ID for the channel. */ int mask; /* OR-ed combination of * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION, for the events * we are interested in. */ { } /* *--------------------------------------------------------------------------- * * ConsoleHandle -- * * Invoked by the generic IO layer to get a handle from a channel. * Because console channels are not devices, this function always * fails. * * Results: * Always returns TCL_ERROR. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ConsoleHandle(instanceData, direction, handlePtr) ClientData instanceData; /* Device ID for the channel. */ int direction; /* TCL_READABLE or TCL_WRITABLE to indicate * which direction of the channel is being * requested. */ ClientData *handlePtr; /* Where to store handle */ { return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ConsoleCmd -- * * The console command implements a TCL interface to the various console * options. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int ConsoleCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { ConsoleInfo *info = (ConsoleInfo *) clientData; char c; int length; int result; Tcl_Interp *consoleInterp; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); result = TCL_OK; consoleInterp = info->consoleInterp; Tcl_Preserve(consoleInterp); if ((c == 't') && (strncmp(argv[1], "title", length)) == 0) { Tcl_DString dString; Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "wm title . ", -1); if (argc == 3) { Tcl_DStringAppendElement(&dString, argv[2]); } Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); } else if ((c == 'h') && (strncmp(argv[1], "hide", length)) == 0) { Tcl_Eval(info->consoleInterp, "wm withdraw ."); } else if ((c == 's') && (strncmp(argv[1], "show", length)) == 0) { Tcl_Eval(info->consoleInterp, "wm deiconify ."); } else if ((c == 'e') && (strncmp(argv[1], "eval", length)) == 0) { if (argc == 3) { Tcl_Eval(info->consoleInterp, argv[2]); } else { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " eval command\"", (char *)NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": should be hide, show, or title", (char *)NULL); result = TCL_ERROR; } Tcl_Release(consoleInterp); return result; } /* *--------------------------------------------------------------------------- * * InterpreterCmd -- * * This command allows the console interp to communicate with the * main interpreter. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int InterpreterCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { ConsoleInfo *info = (ConsoleInfo *) clientData; char c; int length; int result; Tcl_Interp *otherInterp; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", (char *)NULL); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); otherInterp = info->interp; Tcl_Preserve(otherInterp); if ((c == 'e') && (strncmp(argv[1], "eval", length)) == 0) { result = Tcl_GlobalEval(otherInterp, argv[2]); Tcl_AppendResult(interp, otherInterp->result, (char *)NULL); } else if ((c == 'r') && (strncmp(argv[1], "record", length)) == 0) { Tcl_RecordAndEval(otherInterp, argv[2], TCL_EVAL_GLOBAL); result = TCL_OK; Tcl_AppendResult(interp, otherInterp->result, (char *)NULL); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": should be eval or record", (char *)NULL); result = TCL_ERROR; } Tcl_Release(otherInterp); return result; } /* *--------------------------------------------------------------------------- * * ConsoleDeleteProc -- * * If the console command is deleted we destroy the console window * and all associated data structures. * * Results: * None. * * Side effects: * A new console it created. * *--------------------------------------------------------------------------- */ void ConsoleDeleteProc(clientData) ClientData clientData; { ConsoleInfo *info = (ConsoleInfo *) clientData; Tcl_DeleteInterp(info->consoleInterp); info->consoleInterp = NULL; } /* *--------------------------------------------------------------------------- * * ConsoleEventProc -- * * This event procedure is registered on the main window of the * slave interpreter. If the user or a running script causes the * main window to be destroyed, then we need to inform the console * interpreter by invoking "tkConsoleExit". * * Results: * None. * * Side effects: * Invokes the "tkConsoleExit" procedure in the console interp. * *--------------------------------------------------------------------------- */ static void ConsoleEventProc(ClientData clientData, XEvent *eventPtr) { ConsoleInfo *info = clientData; Tcl_Interp *consoleInterp; if (eventPtr->type == DestroyNotify) { consoleInterp = info->consoleInterp; /* * It is possible that the console interpreter itself has * already been deleted. In that case the consoleInterp * field will be set to NULL. If the interpreter is already * gone, we do not have to do any work here. */ if (consoleInterp == (Tcl_Interp *)NULL) { return; } Tcl_Preserve(consoleInterp); Tcl_Eval(consoleInterp, "tkConsoleExit"); Tcl_Release(consoleInterp); } } #endif /* _TCL_VERSION >= 8.2.0 */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/Makefile.in�������������������������������������������������������������������0000644�0001750�0001750�00000036574�11502726613�015122� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # ------------------------------------------------------------------------ # Makefile for static version of BLT library # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # C Compiler options # ------------------------------------------------------------------------ BLT_LIBRARY = @BLT_LIBRARY@ CC = @CC@ CFLAGS = @CFLAGS@ DEFINES = @DEFINES@ EXTRA_CFLAGS = @GCCFLAGS@ $(SO_CFLAGS) LDFLAGS = @LDFLAGS@ @LD_RUN_PATH@ LIB_PREFIX = @LIB_PREFIX@ TCLLIBPATH = @TCL_LIB_DIR@/tcl@TCL_VERSION@ TCL_DBG = @TCL_DBGX@ SO_CFLAGS = @BLT_SO_CFLAGS@ LIB_SUFFIX = @BLT_LIB_SUFFIX@ SO_EXT = @BLT_SO_EXT@ SO_PREFIX = @BLT_SO_PREFIX@ SO_LD = @BLT_SO_LD@ SO_LDFLAGS = @BLT_SO_LDFLAGS@ @LD_RUN_PATH@ EXPAT_INC_SPEC = @EXPAT_INC_SPEC@ EXPAT_LIB_SPEC = @EXPAT_LIB_SPEC@ FT2_INC_SPEC = @FT2_INC_SPEC@ FT2_LIB_SPEC = @FT2_LIB_SPEC@ JPG_INC_SPEC = @JPG_INC_SPEC@ JPG_LIB_SPEC = @JPG_LIB_SPEC@ MYSQL_INC_SPEC = @MYSQL_INC_SPEC@ MYSQL_LIB_SPEC = @MYSQL_LIB_SPEC@ PNG_INC_SPEC = @PNG_INC_SPEC@ PNG_LIB_SPEC = @PNG_LIB_SPEC@ $(Z_LIB_SPEC) TCL_INC_SPEC = @TCL_INC_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUBS_SPEC = @TCL_STUBS_SPEC@ TIF_INC_SPEC = @TIF_INC_SPEC@ TIF_LIB_SPEC = @TIF_LIB_SPEC@ TK_INC_SPEC = @TK_INC_SPEC@ TK_LIB_SPEC = @TK_LIB_SPEC@ TK_STUBS_SPEC = @TK_STUBS_SPEC@ X11_INC_SPEC = @X11_INC_SPEC@ X11_LIB_SPEC = @X11_LIB_SPEC@ XFT_INC_SPEC = @XFT_INC_SPEC@ XFT_LIB_SPEC = @XFT_LIB_SPEC@ XPM_INC_SPEC = @XPM_INC_SPEC@ XPM_LIB_SPEC = @XPM_LIB_SPEC@ XAU_LIB_SPEC = @XAU_LIB_SPEC@ XRANDR_LIB_SPEC = @XRANDR_LIB_SPEC@ XRENDER_LIB_SPEC = @XRENDER_LIB_SPEC@ FTCFG_LIB_SPEC = @FTCFG_LIB_SPEC@ XDMCP_LIB_SPEC = @XDMCP_LIB_SPEC@ Z_LIB_SPEC = @Z_LIB_SPEC@ version = @BLT_MAJOR_VERSION@@BLT_MINOR_VERSION@ # ------------------------------------------------------------------------ # Source and targer installation directories # ------------------------------------------------------------------------ bindir = $(exec_prefix)/bin datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ incdir = $(prefix)/include includedir = @includedir@ libdir = @libdir@ prefix = @prefix@ scriptdir = $(exec_prefix)/lib srcdir = @srcdir@ pkgdir = @BLT_LIBRARY@ instdirs = $(prefix) \ $(exec_prefix) \ $(bindir) \ $(libdir) \ $(incdir) \ $(pkgdir) \ $(scriptdir) # ------------------------------------------------------------------------ # Directories containing Tcl and Tk include files and libraries # ------------------------------------------------------------------------ INCLUDES = -I. -I$(srcdir) \ @INCLUDES@ # ------------------------------------------------------------------------ # Libraries directives for Tcl, Tk, X11, and BLT # ------------------------------------------------------------------------ EXTRA_CORE_LIBS = @LIBS@ @EXTRA_LIBS@ EXTRA_X_LIBS = @TK_XLIBSW@ \ $(X11_LIB_SPEC) \ $(XAU_LIB_SPEC) \ $(XDMCP_LIB_SPEC) \ $(XRANDR_LIB_SPEC) \ $(XRENDER_LIB_SPEC) \ $(EXTRA_CORE_LIBS) BLT_X_SO_LIBS = $(XFT_LIB_SPEC) \ $(FTCFG_LIB_SPEC) \ $(XRANDR_LIB_SPEC) \ $(FT2_LIB_SPEC) BLT_X_A_LIBS = $(BLT_X_SO_LIBS) \ $(JPG_LIB_SPEC) \ $(PNG_LIB_SPEC) \ $(TIF_LIB_SPEC) \ $(XPM_LIB_SPEC) BLT_CORE_SO_LIBS = BLT_CORE_A_LIBS = $(BLT_CORE_SO_LIBS) \ $(MYSQL_LIB_SPEC) \ $(EXPAT_LIB_SPEC) blt_core_name = BLTCore$(version)$(LIB_SUFFIX) blt_x_name = BLTX$(version)$(LIB_SUFFIX) blt_core_so = lib$(blt_core_name)$(SO_EXT) blt_core_a = lib$(blt_core_name).a blt_x_so = lib$(blt_x_name)$(SO_EXT) blt_x_a = lib$(blt_x_name).a blt_dt_csv_name = TableCsv$(version)$(LIB_SUFFIX) blt_dt_mysql_name = TableMysql$(version)$(LIB_SUFFIX) blt_dt_tree_name = TableTree$(version)$(LIB_SUFFIX) blt_dt_vec_name = TableVector$(version)$(LIB_SUFFIX) blt_dt_xml_name = TableXml$(version)$(LIB_SUFFIX) blt_dt_csv_so = $(blt_dt_csv_name)$(SO_EXT) blt_dt_mysql_so = $(blt_dt_mysql_name)$(SO_EXT) blt_dt_tree_so = $(blt_dt_tree_name)$(SO_EXT) blt_dt_vec_so = $(blt_dt_vec_name)$(SO_EXT) blt_dt_xml_so = $(blt_dt_xml_name)$(SO_EXT) blt_pict_bmp_name = PictureBmp$(version)$(LIB_SUFFIX) blt_pict_gif_name = PictureGif$(version)$(LIB_SUFFIX) blt_pict_jpg_name = PictureJpg$(version)$(LIB_SUFFIX) blt_pict_pbm_name = PicturePbm$(version)$(LIB_SUFFIX) blt_pict_pdf_name = PicturePdf$(version)$(LIB_SUFFIX) blt_pict_photo_name = PicturePhoto$(version)$(LIB_SUFFIX) blt_pict_png_name = PicturePng$(version)$(LIB_SUFFIX) blt_pict_ps_name = PicturePs$(version)$(LIB_SUFFIX) blt_pict_tif_name = PictureTif$(version)$(LIB_SUFFIX) blt_pict_xbm_name = PictureXbm$(version)$(LIB_SUFFIX) blt_pict_xpm_name = PictureXpm$(version)$(LIB_SUFFIX) blt_pict_bmp_so = $(blt_pict_bmp_name)$(SO_EXT) blt_pict_gif_so = $(blt_pict_gif_name)$(SO_EXT) blt_pict_jpg_so = $(blt_pict_jpg_name)$(SO_EXT) blt_pict_pbm_so = $(blt_pict_pbm_name)$(SO_EXT) blt_pict_pdf_so = $(blt_pict_pdf_name)$(SO_EXT) blt_pict_photo_so = $(blt_pict_photo_name)$(SO_EXT) blt_pict_png_so = $(blt_pict_png_name)$(SO_EXT) blt_pict_ps_so = $(blt_pict_ps_name)$(SO_EXT) blt_pict_tif_so = $(blt_pict_tif_name)$(SO_EXT) blt_pict_xbm_so = $(blt_pict_xbm_name)$(SO_EXT) blt_pict_xpm_so = $(blt_pict_xpm_name)$(SO_EXT) blt_tree_xml_name = TreeXml$(version)$(LIB_SUFFIX) blt_tree_xml_so = $(blt_tree_xml_name)$(SO_EXT) blt_core_pkgs_so = $(blt_dt_csv_so) \ $(blt_dt_tree_so) \ $(blt_dt_vec_so) ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif ifneq ("$(MYSQL_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_mysql_so) endif blt_x_pkgs_so = $(blt_pict_gif_so) \ $(blt_pict_xbm_so) \ $(blt_pict_bmp_so) \ $(blt_pict_pbm_so) \ $(blt_pict_pdf_so) \ $(blt_pict_ps_so) \ $(blt_pict_photo_so) ifneq ("$(JPG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_jpg_so) endif ifneq ("$(PNG_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_png_so) endif ifneq ("$(XPM_LIB_SPEC)", "") blt_x_pkgs_so += $(blt_pict_xpm_so) endif ifneq ("$(XPM_TIF_SPEC)", "") blt_x_pkgs_so += $(blt_pict_tif_so) endif ifneq ("$(TCL_STUBS_SPEC)", "") tcl_lib_spec=$(TCL_STUBS_SPEC) else tcl_lib_spec=$(TCL_LIB_SPEC) endif ifneq ("$(TK_STUBS_SPEC)", "") tk_lib_spec=$(TK_STUBS_SPEC) else tk_lib_spec=$(TK_LIB_SPEC) endif ifneq ("$(EXPAT_LIB_SPEC)", "") blt_core_pkgs_so += $(blt_dt_xml_so) $(blt_tree_xml_so) endif # ------------------------------------------------------------------------ # You don't need to edit anything beyond this point # ------------------------------------------------------------------------ #N_OBJS = bltTed.o #V3_OBJS = bltTri.o bltGrMt.o #TK_OBJS = tkButton.o tkFrame.o bltScrollbar.o GRAPH_OBJS = bltGrAxis.o \ bltGrBar.o \ bltGrElem.o \ bltGrHairs.o \ bltGrLegd.o \ bltGrLine.o \ bltGrMarker.o \ bltGrMisc.o \ bltGrPen.o \ bltGrPs.o \ bltGraph.o #TREEVIEW_OBJS = bltTreeView.o \ bltTvCmd.o \ bltTvCol.o \ bltTvEdit.o \ bltTvStyle.o PICTURE_OBJS = bltPicture.o \ bltPictCmd.o \ bltPictDraw.o # bltPictMmx.o \ #PICTURE_PKG_OBJS = bltPictBmp.o \ bltPictGif.o \ bltPictJpg.o \ bltPictPbm.o \ bltPictPdf.o \ bltPictPhoto.o \ bltPictPng.o \ bltPictPs.o \ bltPictTif.o \ bltPictXbm.o \ bltPictXpm.o #TREE_OBJS = bltTree.o \ bltTreeCmd.o \ #TREE_PKG_OBJS = bltTreeXml.o DATATABLE_OBJS = bltDataTable.o \ # bltDtCmd.o \ #DATATABLE_PKG_OBJS = bltDtCsv.o \ bltDtMysql.o \ bltDtTree.o \ bltDtVec.o \ bltDtXml.o BLT_CORE_SO_OBJS = bltAlloc.o \ bltArrayObj.o \ bltBase64.o \ bltChain.o \ bltDBuffer.o \ $(DATATABLE_OBJS) \ bltHash.o \ bltInit.o \ bltList.o \ bltNsUtil.o \ bltParse.o \ bltPool.o \ bltSpline.o \ bltSwitch.o \ $(TREE_OBJS) \ bltUtil.o \ bltVar.o \ bltVecCmd.o \ bltVecMath.o \ bltVector.o \ bltCoreInit.o # bltBgexec.o \ bltCrc32.o \ bltCsv.o \ bltDebug.o \ bltTri.o \ bltUnixBgexec.o \ bltUnixPipe.o \ bltWatch.o \ BLT_CORE_A_OBJS = $(BLT_CORE_SO_OBJS) \ $(TREE_PKG_OBJS) \ $(DATATABLE_PKG_OBJS) BLT_X_SO_OBJS = $(GRAPH_OBJS) \ $(PICTURE_OBJS) \ $(TREEVIEW_OBJS) \ bltBgStyle.o \ bltBind.o \ bltBusy.o \ bltConfig.o \ bltImage.o \ bltPs.o \ bltPsAfm.o \ bltText.o \ bltUnixBitmap.o \ bltUnixFont.o \ bltUnixPainter.o \ bltUnixWindow.o \ bltWindow.o \ bltExtInit.o \ $(TK_OBJS) $(N_OBJS) # bltBeep.o \ bltBitmap.o \ bltCanvEps.o \ bltComboBtn.o \ bltComboEntry.o \ bltComboMenu.o \ bltComboTree.o \ bltContainer.o \ bltCutbuffer.o \ bltDragdrop.o \ bltHtext.o \ bltListView.o \ bltMenubar.o \ bltOldConfig.o \ bltPaneset.o \ bltScrollset.o \ bltTable.o \ bltTabset.o \ bltUnixDnd.o \ bltWinop.o \ BLT_X_A_OBJS = $(BLT_X_SO_OBJS) \ $(PICTURE_PKG_OBJS) BLT_SO_OBJS = $(BLT_CORE_SO_OBJS) \ $(BLT_X_SO_OBJS) BLT_A_OBJS = $(BLT_CORE_A_OBJS) \ $(BLT_X_A_OBJS) # GNU Make-specific macro SRCS = $(patsubst %.o,$(srcdir)/%.c,$(BLT_A_OBJS)) bltwish = bltwish$(version) bltsh = bltsh$(version) # Public headers to be installed headers = $(srcdir)/blt.h \ $(srcdir)/bltBind.h \ $(srcdir)/bltChain.h \ bltHash.h \ $(srcdir)/bltList.h \ $(srcdir)/bltPool.h \ $(srcdir)/bltTree.h \ $(srcdir)/bltVector.h CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) MAIN_CC_OPTS = $(EXTRA_CFLAGS) $(CFLAGS) $(DEFINES) $(INCLUDES) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_ROOT = RANLIB = @RANLIB@ SHELL = /bin/sh AR = ar rc RM = rm -f LINT = splint LINTFLAGS = #-axhbns XREF = cxref XREFFLAGS = -dltR LN_S = @LN_S@ VPATH = $(srcdir) all: build_libs build_demos build_demos: $(bltsh) $(bltwish) build_libs: build_@BLT_TARGET@ build_shared: $(blt_core_so) $(blt_x_so) build_core_pkgs build_x_pkgs build_static: $(blt_core_a) $(blt_x_a) build_core_pkgs: $(blt_core_so) $(blt_core_pkgs_so) build_x_pkgs: $(blt_x_so) $(blt_x_pkgs_so) $(bltwish): $(blt_core_a) $(blt_x_a) $(srcdir)/bltUnixMain.c $(RM) $(bltwish) $(CC) $(MAIN_CC_OPTS) $(LDFLAGS) -o $(bltwish) \ -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltUnixMain.c \ $(blt_x_a) $(blt_core_a) $(TK_LIB_SPEC) $(TCL_LIB_SPEC) \ $(BLT_X_A_LIBS) $(BLT_CORE_A_LIBS) $(EXTRA_X_LIBS) $(bltsh): $(blt_core_a) $(srcdir)/bltUnixMain.c $(RM) $(bltsh) $(CC) $(CC_OPTS) $(LDFLAGS) -o $(bltsh) \ -DTCL_ONLY -DTCLLIBPATH=\"$(TCLLIBPATH)\" \ $(srcdir)/bltUnixMain.c \ $(blt_core_a) $(TCL_STUBS_SPEC) $(TCL_LIB_SPEC) \ $(BLT_CORE_A_LIBS) $(EXTRA_CORE_LIBS) $(blt_core_a): $(BLT_CORE_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_CORE_A_OBJS) $(RANLIB) $@ $(blt_x_a): $(BLT_X_A_OBJS) $(RM) $@ $(AR) $@ $(BLT_X_A_OBJS) $(RANLIB) $@ $(blt_core_so): $(BLT_CORE_SO_OBJS) $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ $(BLT_CORE_SO_OBJS) $(BLT_CORE_SO_LIBS) \ $(core_lib_spec) $(blt_x_so): $(BLT_X_SO_OBJS) $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ $(BLT_X_SO_OBJS) $(BLT_X_SO_LIBS) \ $(BLT_CORE_SO_LIBS) $(tcl_lib_spec) $(blt_dt_mysql_so): bltDtMysql.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtMysql.o $(MYSQL_LIB_SPEC) $(blt_dt_xml_so): bltDtXml.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtXml.o $(EXPAT_LIB_SPEC) $(blt_dt_csv_so): bltDtCsv.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtCsv.o $(blt_dt_vec_so): bltDtVec.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtVec.o $(blt_dt_tree_so): bltDtTree.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltDtTree.o $(blt_pict_bmp_so): bltPictBmp.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictBmp.o $(blt_pict_gif_so): bltPictGif.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictGif.o $(blt_pict_jpg_so): bltPictJpg.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictJpg.o $(JPG_LIB_SPEC) $(blt_pict_png_so): bltPictPng.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPng.o $(PNG_LIB_SPEC) $(blt_pict_pbm_so): bltPictPbm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPbm.o $(blt_pict_tif_so): bltPictTif.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictTif.o $(TIF_LIB_SPEC) $(blt_pict_xbm_so): bltPictXbm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictXbm.o $(blt_pict_xpm_so): bltPictXpm.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictXpm.o \ $(X11_LIB_SPEC) $(XPM_LIB_SPEC) $(blt_pict_pdf_so): bltPictPdf.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPdf.o $(blt_pict_ps_so): bltPictPs.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPs.o $(blt_pict_photo_so): bltPictPhoto.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltPictPhoto.o $(blt_tree_xml_so): bltTreeXml.o $(RM) $@ $(SO_LD) $(SO_LDFLAGS) -o $@ bltTreeXml.o $(EXPAT_LIB_SPEC) install: mkdirs install-demos install-libs install-headers install-libs: install-@BLT_TARGET@ install-demos: $(bltwish) $(bltsh) $(INSTALL) -m 0755 $(bltwish) $(DESTDIR)$(bindir) $(INSTALL) -m 0755 $(bltsh) $(DESTDIR)$(bindir) install-shared: $(blt_core_so) $(blt_x_so) install-pkgs install-static $(INSTALL) -m 0755 $(blt_core_so) $(DESTDIR)$(libdir) $(INSTALL) -m 0755 $(blt_x_so) $(DESTDIR)$(libdir) install-static: $(blt_core_a) $(blt_x_a) $(INSTALL_DATA) $(blt_core_a) $(DESTDIR)$(libdir) $(RANLIB) $(DESTDIR)$(libdir)/$(blt_core_a) $(INSTALL_DATA) $(blt_x_a) $(DESTDIR)$(libdir) $(RANLIB) $(DESTDIR)$(libdir)/$(blt_x_a) install-pkgs: $(blt_core_pkgs_so) $(blt_x_pkgs_so) for i in $(blt_core_pkgs_so) $(blt_x_pkgs_so) ; do \ echo $(RM) $(DESTDIR)$(libdir)/$$i ; \ $(RM) $(DESTDIR)$(libdir)/$$i ; \ echo $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ $(INSTALL) -m 0755 $$i $(DESTDIR)$(pkgdir) ; \ done install-headers: @for i in $(headers) ; do \ echo "installing $$i..." ; \ $(INSTALL_DATA) -m 0444 $$i $(DESTDIR)$(incdir) ; \ done mkdirs: @for i in $(instdirs) ; do \ if test -d $(DESTDIR)$$i ; then \ : ; \ else \ echo " mkdir $(DESTDIR)$$i" ; \ $(INSTALL) -d $(DESTDIR)$$i ; \ fi ; \ done lint: $(LINT) $(LINTFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) xref: $(XREF) $(XREFFLAGS) $(DEFINES) $(INCLUDES) $(SRCS) clean: clean-objs clean-libs clean-demos clean-libs: clean-@BLT_TARGET@ clean-objs: $(RM) $(BLT_A_OBJS) clean-demos: $(RM) $(bltsh)* $(bltwish)* *pure* .pure* clean-static: $(RM) $(blt_core_a) $(blt_x_a) clean-pkgs: $(RM) $(blt_core_pkgs_so) $(blt_x_pkgs_so) clean-shared: clean-pkgs clean-static $(RM) $(blt_core_so) $(blt_x_so) distclean: clean $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* Makefile $(RM) config.h bltHash.h Makefile TAGS bltDtMysql.o: $(srcdir)/bltDtMysql.c $(CC) -c $(CC_OPTS) $(MYSQL_INC_SPEC) $? bltDtXml.o: $(srcdir)/bltDtXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTree.o: $(srcdir)/bltTree.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltTreeXml.o: $(srcdir)/bltTreeXml.c $(CC) -c $(CC_OPTS) $(EXPAT_INC_SPEC) $? bltUnixFont.o: $(srcdir)/bltUnixFont.c $(CC) -c $(CC_OPTS) $(FT2_INC_SPEC) $? bltPictDraw.o: $(srcdir)/bltPictDraw.c $(srcdir)/bltPaintDraw.c $(CC) -c $(CC_OPTS) $(FT2_INC_SPEC) $< bltPictJpg.o: $(srcdir)/bltPictJpg.c $(CC) -c $(CC_OPTS) $(JPG_INC_SPEC) $? bltPictTif.o: $(srcdir)/bltPictTif.c $(CC) -c $(CC_OPTS) $(TIF_INC_SPEC) $? bltPictPng.o: $(srcdir)/bltPictPng.c $(CC) -c $(CC_OPTS) $(PNG_INC_SPEC) $? bltPictXpm.o: $(srcdir)/bltPictXpm.c $(CC) -c $(CC_OPTS) $(XPM_INC_SPEC) $? bltCoreInit.o: $(srcdir)/bltCoreInit.c $(CC) -c $(CC_OPTS) -DTCL_ONLY -DBLT_LIBRARY=\"$(BLT_LIBRARY)\" \ $(srcdir)/bltCoreInit.c .c.o: $(CC) -c $(CC_OPTS) $< ������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltCsv.c����������������������������������������������������������������������0000644�0001750�0001750�00000024521�11462120062�014432� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltCsv.c -- * * This module implements a CSV reader procedure for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" static int ParseCsvChannel(Tcl_Interp *interp, Tcl_Channel channel) { int inQuotes, isQuoted, isPath; char *fp, *field; Tcl_DString dString; Tcl_Obj *listObjPtr, *recordObjPtr; int fieldSize; isPath = isQuoted = inQuotes = FALSE; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); recordObjPtr = NULL; Tcl_DStringInit(&dString); fieldSize = 128; Tcl_DStringSetLength(&dString, fieldSize + 1); fp = field = Tcl_DStringValue(&dString); for (;;) { char *bp, *bend; #define BUFFSIZE 8191 char buffer[BUFFSIZE+1]; int nBytes; nBytes = Tcl_Read(channel, buffer, sizeof(char) * BUFFSIZE); for (bp = buffer, bend = bp + nBytes; bp < bend; bp++) { switch (*bp) { case '\t': case ' ': /* * Add whitespace only if it's not leading or we're inside of * quotes or a path. */ if ((fp != field) || (inQuotes) || (isPath)) { *fp++ = *bp; } break; case '\\': /* * Handle special case CSV files that allow unquoted paths. * Example: ...,\this\path " should\have been\quoted\,... */ if (fp == field) { isPath = TRUE; } *fp++ = *bp; break; case '"': if (inQuotes) { if (*(bp+1) == '"') { *fp++ = '"'; bp++; } else { inQuotes = FALSE; } } else { /* * If the quote doesn't start a field, then treat all * quotes in the field as ordinary characters. */ if (fp == field) { isQuoted = inQuotes = TRUE; } else { *fp++ = *bp; } } break; case ',': case '\n': if (inQuotes) { *fp++ = *bp; /* Copy the comma or newline. */ } else { char *last; Tcl_Obj *objPtr; if ((isPath) && (*bp == ',') && (fp != field) && (*(fp - 1) != '\\')) { *fp++ = *bp; /* Copy the comma or newline. */ break; } /* "last" points to the character after the last character * in the field. */ last = fp; /* Remove trailing spaces only if the field wasn't * quoted. */ if ((!isQuoted) && (!isPath)) { while ((last > field) && (isspace(*(last - 1)))) { last--; } } if (recordObjPtr == NULL) { if (*bp == '\n') { break; /* Ignore empty lines. */ } recordObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); } /* End of field. Append field to record. */ objPtr = Tcl_NewStringObj(field, last - field); Tcl_ListObjAppendElement(interp, recordObjPtr, objPtr); if (*bp == '\n') { /* On newlines append the record to the list. */ Tcl_ListObjAppendElement(interp, listObjPtr, recordObjPtr); recordObjPtr = NULL; } fp = field; isPath = isQuoted = FALSE; } break; default: *fp++ = *bp; /* Copy the character. */ } if ((fp - field) >= fieldSize) { int offset; /* * We've exceeded the current maximum size of the field. * Double the size of the field, but make sure to reset the * pointers (fp and field) to the (possibly) new memory * location. */ offset = fp - field; fieldSize += fieldSize; Tcl_DStringSetLength(&dString, fieldSize + 1); field = Tcl_DStringValue(&dString); fp = field + offset; } } if (nBytes < 1) { /* * We're reached the end of input. But there may not have been a * final newline to trigger the final appends. So check if 1) a * last field is still needs appending the the last record and if * 2) a last record is still needs appending to the list. */ if (fp != field) { char *last; Tcl_Obj *objPtr; last = fp; /* Remove trailing spaces */ while (isspace(*(last - 1))) { last--; } objPtr = Tcl_NewStringObj(field, last - field); if (recordObjPtr == NULL) { recordObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); } } if (recordObjPtr != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, recordObjPtr); } break; } } Tcl_DStringFree(&dString); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static int ParseCsvData(Tcl_Interp *interp, Tcl_Obj *objPtr) { int inQuotes, isQuoted, isPath; char *fp, *field; Tcl_DString dString; Tcl_Obj *listObjPtr, *recordObjPtr; int fieldSize; isPath = isQuoted = inQuotes = FALSE; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); recordObjPtr = NULL; Tcl_DStringInit(&dString); fieldSize = 128; Tcl_DStringSetLength(&dString, fieldSize + 1); fp = field = Tcl_DStringValue(&dString); { char *bp, *bend; char *buffer; int nBytes; buffer = Tcl_GetStringFromObj(objPtr, &nBytes); for (bp = buffer, bend = bp + nBytes; bp < bend; bp++) { switch (*bp) { case '\t': case ' ': /* * Add whitespace only if it's not leading or we're inside of * quotes or a path. */ if ((fp != field) || (inQuotes) || (isPath)) { *fp++ = *bp; } break; case '\\': if (fp == field) { isPath = TRUE; } *fp++ = *bp; break; case '"': if (inQuotes) { if (*(bp+1) == '"') { *fp++ = '"'; bp++; } else { inQuotes = FALSE; } } else { /* * If the quote doesn't start a field, then treat all * quotes in the field as ordinary characters. */ if (fp == field) { isQuoted = inQuotes = TRUE; } else { *fp++ = *bp; } } break; case ',': case '\n': if (inQuotes) { *fp++ = *bp; /* Copy the comma or newline. */ } else { char *last; Tcl_Obj *objPtr; if ((isPath) && (*bp == ',') && (fp != field) && (*(fp - 1) != '\\')) { *fp++ = *bp; /* Copy the comma or newline. */ break; } /* "last" points to the character after the last character * in the field. */ last = fp; /* Remove trailing spaces only if the field wasn't * quoted. */ if ((!isQuoted) && (!isPath)) { while ((last > field) && (isspace(*(last - 1)))) { last--; } } if (recordObjPtr == NULL) { if (*bp == '\n') { break; /* Ignore empty lines. */ } recordObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); } /* End of field. Append field to record. */ objPtr = Tcl_NewStringObj(field, last - field); Tcl_ListObjAppendElement(interp, recordObjPtr, objPtr); if (*bp == '\n') { /* On newlines append the record to the list. */ Tcl_ListObjAppendElement(interp, listObjPtr, recordObjPtr); recordObjPtr = NULL; } fp = field; isPath = isQuoted = FALSE; } break; default: *fp++ = *bp; /* Copy the character. */ } if ((fp - field) >= fieldSize) { int offset; /* * We've exceeded the current maximum size of the field. * Double the size of the field, but make sure to reset the * pointers to the (possibly) new memory location. */ offset = fp - field; fieldSize += fieldSize; Tcl_DStringSetLength(&dString, fieldSize + 1); field = Tcl_DStringValue(&dString); fp = field + offset; } } /* * We're reached the end of input. But there may not have been a final * newline to trigger the final appends. So check if 1) a last field * is still needs appending the the last record and if 2) a last * record is still needs appending to the list. */ if (fp != field) { char *last; Tcl_Obj *objPtr; last = fp; /* Remove trailing spaces */ while (isspace(*(last - 1))) { last--; } objPtr = Tcl_NewStringObj(field, last - field); if (recordObjPtr == NULL) { recordObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); } } if (recordObjPtr != NULL) { Tcl_ListObjAppendElement(interp, listObjPtr, recordObjPtr); } } Tcl_DStringFree(&dString); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } static int ParseCsvFile(Tcl_Interp *interp, const char *fileName) { int result; int closeChannel; Tcl_Channel channel; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); return TCL_ERROR; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return TCL_ERROR; /* Can't open dump file. */ } } result = ParseCsvChannel(interp, channel); if (closeChannel) { Tcl_Close(interp, channel); } return result; } static int CsvCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 2) { return ParseCsvFile(interp, Tcl_GetString(objv[1])); } if (objc == 3) { char *string; string = Tcl_GetString(objv[1]); if (strcmp(string, "-data") == 0) { return ParseCsvData(interp, objv[2]); } } Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ?fileName? ?-data dataString?", (char *)NULL); return TCL_ERROR; } int Blt_CsvCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"csv", CsvCmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tclIntDecls.h�����������������������������������������������������������������0000644�0001750�0001750�00000031071�11462120063�015411� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tclIntDecls.h -- * * This file contains the declarations for all unsupported functions * that are exported by the TCL library. These interfaces are not * guaranteed to remain the same between versions. Use at your own * risk. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from TclIntDecls.h of the TCL library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #ifndef _TCL_INT_DECLS_H #define _TCL_INT_DECLS_H /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tclInt.decls script. */ typedef struct _Tcl_ResolvedVarInfo Tcl_ResolvedVarInfo; typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp, const char *name, int length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr); typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Var *rPtr); typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Command *rPtr); /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 36 */ extern int TclGetLong(Tcl_Interp * interp, char *str, long *longPtr); /* 69 */ extern char * TclpAlloc(unsigned int size); /* 74 */ extern void TclpFree(char * ptr); /* 81 */ extern char * TclpRealloc(char * ptr, unsigned int size); /* 113 */ extern Tcl_Namespace * Tcl_CreateNamespace(Tcl_Interp * interp, char * name, ClientData clientData, Tcl_NamespaceDeleteProc * deleteProc); /* 114 */ extern void Tcl_DeleteNamespace(Tcl_Namespace * nsPtr); /* 115 */ extern int Tcl_Export(Tcl_Interp * interp, Tcl_Namespace * nsPtr, char * pattern, int resetListFirst); /* 116 */ extern Tcl_Command Tcl_FindCommand(Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags); /* 117 */ extern Tcl_Namespace * Tcl_FindNamespace(Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags); /* 120 */ extern Tcl_Var Tcl_FindNamespaceVar(Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags); /* 124 */ extern Tcl_Namespace * Tcl_GetCurrentNamespace(Tcl_Interp * interp); /* 125 */ extern Tcl_Namespace * Tcl_GetGlobalNamespace(Tcl_Interp * interp); /* 128 */ extern void Tcl_PopCallFrame(Tcl_Interp* interp); /* 129 */ extern int Tcl_PushCallFrame(Tcl_Interp* interp, Tcl_CallFrame * framePtr, Tcl_Namespace * nsPtr, int isProcCallFrame); /* 131 */ extern void Tcl_SetNamespaceResolvers( Tcl_Namespace *nsPtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); typedef struct TclIntStubs { int magic; struct TclIntStubHooks *hooks; void *tclAccess; /* 0 */ void *tclAccessDeleteProc; /* 1 */ void *tclAccessInsertProc; /* 2 */ void *tclAllocateFreeObjects; /* 3 */ void *reserved4; void *tclCleanupChildren; /* 5 */ void *tclCleanupCommand; /* 6 */ void *tclCopyAndCollapse; /* 7 */ void *tclCopyChannel; /* 8 */ void *tclCreatePipeline; /* 9 */ void *tclCreateProc; /* 10 */ void *tclDeleteCompiledLocalVars; /* 11 */ void *tclDeleteVars; /* 12 */ void *tclDoGlob; /* 13 */ void *tclDumpMemoryInfo; /* 14 */ void *reserved15; void *tclExprFloatError; /* 16 */ void *tclFileAttrsCmd; /* 17 */ void *tclFileCopyCmd; /* 18 */ void *tclFileDeleteCmd; /* 19 */ void *tclFileMakeDirsCmd; /* 20 */ void *tclFileRenameCmd; /* 21 */ void *tclFindElement; /* 22 */ void *tclFindProc; /* 23 */ void *tclFormatInt; /* 24 */ void *tclFreePackageInfo; /* 25 */ void *reserved26; void *tclGetDate; /* 27 */ void *tclpGetDefaultStdChannel; /* 28 */ void *tclGetElementOfIndexedArray; /* 29 */ void *reserved30; void *tclGetExtension; /* 31 */ void *tclGetFrame; /* 32 */ void *tclGetInterpProc; /* 33 */ void *tclGetIntForIndex; /* 34 */ void *tclGetIndexedScalar; /* 35 */ int (*tclGetLong)(Tcl_Interp *interp, char *string, long *longPtr); /* 36 */ void *tclGetLoadedPackages; /* 37 */ void *tclGetNamespaceForQualName; /* 38 */ void *tclGetObjInterpProc; /* 39 */ void *tclGetOpenMode; /* 40 */ void *tclGetOriginalCommand; /* 41 */ void *tclpGetUserHome; /* 42 */ void *tclGlobalInvoke; /* 43 */ void *tclGuessPackageName; /* 44 */ void *tclHideUnsafeCommands; /* 45 */ void *tclInExit; /* 46 */ void *tclIncrElementOfIndexedArray; /* 47 */ void *tclIncrIndexedScalar; /* 48 */ void *tclIncrVar2; /* 49 */ void *tclInitCompiledLocals; /* 50 */ void *tclInterpInit; /* 51 */ void *tclInvoke; /* 52 */ void *tclInvokeObjectCommand; /* 53 */ void *tclInvokeStringCommand; /* 54 */ void *tclIsProc; /* 55 */ void *reserved56; void *reserved57; void *tclLookupVar; /* 58 */ void *tclpMatchFiles; /* 59 */ void *tclNeedSpace; /* 60 */ void *tclNewProcBodyObj; /* 61 */ void *tclObjCommandComplete; /* 62 */ void *tclObjInterpProc; /* 63 */ void *tclObjInvoke; /* 64 */ void *tclObjInvokeGlobal; /* 65 */ void *tclOpenFileChannelDeleteProc; /* 66 */ void *tclOpenFileChannelInsertProc; /* 67 */ void *tclpAccess; /* 68 */ void *tclpAlloc; /* 69 */ void *tclpCopyFile; /* 70 */ void *tclpCopyDirectory; /* 71 */ void *tclpCreateDirectory; /* 72 */ void *tclpDeleteFile; /* 73 */ void (*tclpFree)(char * ptr); /* 74 */ void *tclpGetClicks; /* 75 */ void *tclpGetSeconds; /* 76 */ void *tclpGetTime; /* 77 */ void *tclpGetTimeZone; /* 78 */ void *tclpListVolumes; /* 79 */ void *tclpOpenFileChannel; /* 80 */ char *(*tclpRealloc)(char * ptr, unsigned int size); /* 81 */ void *tclpRemoveDirectory; /* 82 */ void *tclpRenameFile; /* 83 */ void *reserved84; void *reserved85; void *reserved86; void *reserved87; void *tclPrecTraceProc; /* 88 */ void *tclPreventAliasLoop; /* 89 */ void *reserved90; void *tclProcCleanupProc; /* 91 */ void *tclProcCompileProc; /* 92 */ void *tclProcDeleteProc; /* 93 */ void *tclProcInterpProc; /* 94 */ void *tclpStat; /* 95 */ void *tclRenameCommand; /* 96 */ void *tclResetShadowedCmdRefs; /* 97 */ void *tclServiceIdle; /* 98 */ void *tclSetElementOfIndexedArray; /* 99 */ void *tclSetIndexedScalar; /* 100 */ void *tclSetPreInitScript; /* 101 */ void *tclSetupEnv; /* 102 */ void *tclSockGetPort; /* 103 */ void *tclSockMinimumBuffers; /* 104 */ void *tclStat; /* 105 */ void *tclStatDeleteProc; /* 106 */ void *tclStatInsertProc; /* 107 */ void *tclTeardownNamespace; /* 108 */ void *tclUpdateReturnInfo; /* 109 */ void *reserved110; void *tcl_AddInterpResolvers; /* 111 */ void *tcl_AppendExportList; /* 112 */ Tcl_Namespace * (*tcl_CreateNamespace)(Tcl_Interp *interp, char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */ void (*tcl_DeleteNamespace) (Tcl_Namespace * nsPtr); /* 114 */ int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, char *pattern, int resetListFirst); /* 115 */ Tcl_Command (*tcl_FindCommand) (Tcl_Interp *interp, char *name, Tcl_Namespace *contextNsPtr, int flags); /* 116 */ Tcl_Namespace *(*tcl_FindNamespace)(Tcl_Interp *interp, char *name, Tcl_Namespace *contextNsPtr, int flags); /* 117 */ void *tcl_GetInterpResolvers; /* 118 */ void *tcl_GetNamespaceResolvers; /* 119 */ Tcl_Var (*tcl_FindNamespaceVar)(Tcl_Interp *interp, char *name, Tcl_Namespace *contextNsPtr, int flags); /* 120 */ void *tcl_ForgetImport; /* 121 */ void *tcl_GetCommandFromObj; /* 122 */ void *tcl_GetCommandFullName; /* 123 */ Tcl_Namespace *(*tcl_GetCurrentNamespace)(Tcl_Interp *interp); /* 124 */ Tcl_Namespace *(*tcl_GetGlobalNamespace)(Tcl_Interp *interp); /* 125 */ void *tcl_GetVariableFullName; /* 126 */ void *tcl_Import; /* 127 */ void (*tcl_PopCallFrame)(Tcl_Interp *interp); /* 128 */ int (*tcl_PushCallFrame)(Tcl_Interp *interp, Tcl_CallFrame *framePtr, Tcl_Namespace *nsPtr, int isProcCallFrame); /* 129 */ void *tcl_RemoveInterpResolvers; /* 130 */ void (*tcl_SetNamespaceResolvers) (Tcl_Namespace *nsPtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 131 */ void *tclpHasSockets; /* 132 */ void *tclpGetDate; /* 133 */ void *tclpStrftime; /* 134 */ void *tclpCheckStackSpace; /* 135 */ void *reserved136; void *tclpChdir; /* 137 */ void *tclGetEnv; /* 138 */ void *tclpLoadFile; /* 139 */ void *tclLooksLikeInt; /* 140 */ void *tclpGetCwd; /* 141 */ void *tclSetByteCodeFromAny; /* 142 */ void *tclAddLiteralObj; /* 143 */ void *tclHideLiteral; /* 144 */ void *tclGetAuxDataType; /* 145 */ void *tclHandleCreate; /* 146 */ void *tclHandleFree; /* 147 */ void *tclHandlePreserve; /* 148 */ void *tclHandleRelease; /* 149 */ void *tclRegAbout; /* 150 */ void *tclRegExpRangeUniChar; /* 151 */ void *tclSetLibraryPath; /* 152 */ void *tclGetLibraryPath; /* 153 */ void *reserved154; void *reserved155; void *tclRegError; /* 156 */ void *tclVarTraceExists; /* 157 */ void *tclSetStartupScriptFileName; /* 158 */ void *tclGetStartupScriptFileName; /* 159 */ void *tclpMatchFilesTypes; /* 160 */ void *tclChannelTransform; /* 161 */ void *tclChannelEventScriptInvoker; /* 162 */ void *tclGetInstructionTable; /* 163 */ void *tclExpandCodeArray; /* 164 */ } TclIntStubs; extern TclIntStubs *tclIntStubsPtr; #if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) /* * Inline function declarations: */ #ifndef TclGetLong #define TclGetLong \ (tclIntStubsPtr->tclGetLong) /* 36 */ #endif #ifndef TclpAlloc #define TclpAlloc \ (tclIntStubsPtr->tclpAlloc) /* 69 */ #endif #ifndef TclpFree #define TclpFree \ (tclIntStubsPtr->tclpFree) /* 74 */ #endif #ifndef TclpRealloc #define TclpRealloc \ (tclIntStubsPtr->tclpRealloc) /* 81 */ #endif #ifndef Tcl_CreateNamespace #define Tcl_CreateNamespace \ (tclIntStubsPtr->tcl_CreateNamespace) /* 113 */ #endif #ifndef Tcl_DeleteNamespace #define Tcl_DeleteNamespace \ (tclIntStubsPtr->tcl_DeleteNamespace) /* 114 */ #endif #ifndef Tcl_Export #define Tcl_Export \ (tclIntStubsPtr->tcl_Export) /* 115 */ #endif #ifndef Tcl_FindCommand #define Tcl_FindCommand \ (tclIntStubsPtr->tcl_FindCommand) /* 116 */ #endif #ifndef Tcl_FindNamespace #define Tcl_FindNamespace \ (tclIntStubsPtr->tcl_FindNamespace) /* 117 */ #endif #ifndef Tcl_FindNamespaceVar #define Tcl_FindNamespaceVar \ (tclIntStubsPtr->tcl_FindNamespaceVar) /* 120 */ #endif #ifndef Tcl_GetCurrentNamespace #define Tcl_GetCurrentNamespace \ (tclIntStubsPtr->tcl_GetCurrentNamespace) /* 124 */ #endif #ifndef Tcl_GetGlobalNamespace #define Tcl_GetGlobalNamespace \ (tclIntStubsPtr->tcl_GetGlobalNamespace) /* 125 */ #endif #ifndef Tcl_PopCallFrame #define Tcl_PopCallFrame \ (tclIntStubsPtr->tcl_PopCallFrame) /* 128 */ #endif #ifndef Tcl_PushCallFrame #define Tcl_PushCallFrame \ (tclIntStubsPtr->tcl_PushCallFrame) /* 129 */ #endif #ifndef Tcl_SetNamespaceResolvers #define Tcl_SetNamespaceResolvers \ (tclIntStubsPtr->tcl_SetNamespaceResolvers) /* 131 */ #endif #endif #endif /* _TCL_INT_DECLS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkIntDecls.h������������������������������������������������������������������0000644�0001750�0001750�00000026002�11462120063�015243� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tkIntDecls.h -- * * This file contains the declarations for all unsupported functions * that are exported by the Tk library. These interfaces are not * guaranteed to remain the same between versions. Use at your own * risk. * * Copyright 2003-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file was adapted from tkIntDecls.h of the Tk library distribution. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. */ #ifndef _TKINTDECLS #define _TKINTDECLS #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tkInt.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 9 */ extern void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, int xPad, int yPad, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 10 */ extern int TkCopyAndGlobalEval(Tcl_Interp *interp, char * script); /* 14 */ extern Tk_Window TkCreateMainWindow(Tcl_Interp *interp, char * screenName, char *baseName); /* 64 */ extern void TkpMakeContainer(Tk_Window tkwin); /* 74 */ extern void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, char *menuName); /* 75 */ extern int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, char *string); /* 84 */ extern void TkSetClassProcs(Tk_Window tkwin, void *procs, ClientData instanceData); /* 85 */ extern void TkSetWindowMenuBar(Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName); /* 95 */ extern void TkWmRestackToplevel(Tk_Window tkwin, int aboveBelow, Tk_Window otherPtr); #if defined (WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TCL) /* 114 */ extern TkRegion TkCreateRegion(void); /* 115 */ extern void TkDestroyRegion (TkRegion rgn); /* 116 */ extern void TkIntersectRegion (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 117 */ extern int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 118 */ extern void TkSetRegion(Display* display, GC gc, TkRegion rgn); /* 119 */ extern void TkUnionRectWithRegion(XRectangle* rect, TkRegion src, TkRegion dr_return); #endif typedef struct TkIntStubs { int magic; struct TkIntStubHooks *hooks; void *tkAllocWindow; /* 0 */ void *tkBezierPoints; /* 1 */ void *tkBezierScreenPoints; /* 2 */ void *tkBindDeadWindow; /* 3 */ void *tkBindEventProc; /* 4 */ void *tkBindFree; /* 5 */ void *tkBindInit; /* 6 */ void *tkChangeEventWindow; /* 7 */ void *tkClipInit; /* 8 */ void (*tkComputeAnchor)(Tk_Anchor anchor, Tk_Window tkwin, int xPad, int yPad, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */ int (*tkCopyAndGlobalEval)(Tcl_Interp *interp, char *script); /* 10 */ void *tkCreateBindingProcedure; /* 11 */ void *tkCreateCursorFromData; /* 12 */ void *tkCreateFrame; /* 13 */ Tk_Window (*tkCreateMainWindow)(Tcl_Interp *interp, char *screenName, char * baseName); /* 14 */ void *tkCurrentTime; /* 15 */ void *tkDeleteAllImages; /* 16 */ void *tkDoConfigureNotify; /* 17 */ void *tkDrawInsetFocusHighlight; /* 18 */ void *tkEventDeadWindow; /* 19 */ void *tkFillPolygon; /* 20 */ void *tkFindStateNum; /* 21 */ void *tkFindStateString; /* 22 */ void *tkFocusDeadWindow; /* 23 */ void *tkFocusFilterEvent; /* 24 */ void *tkFocusKeyEvent; /* 25 */ void *tkFontPkgInit; /* 26 */ void *tkFontPkgFree; /* 27 */ void *tkFreeBindingTags; /* 28 */ void *tkpFreeCursor; /* 29 */ void *tkGetBitmapData; /* 30 */ void *tkGetButtPoints; /* 31 */ void *tkGetCursorByName; /* 32 */ void *tkGetDefaultScreenName; /* 33 */ void *tkGetDisplay; /* 34 */ void *tkGetDisplayOf; /* 35 */ void *tkGetFocusWin; /* 36 */ void *tkGetInterpNames; /* 37 */ void *tkGetMiterPoints; /* 38 */ void *tkGetPointerCoords; /* 39 */ void *tkGetServerInfo; /* 40 */ void *tkGrabDeadWindow; /* 41 */ void *tkGrabState; /* 42 */ void *tkIncludePoint; /* 43 */ void *tkInOutEvents; /* 44 */ void *tkInstallFrameMenu; /* 45 */ void *tkKeysymToString; /* 46 */ void *tkLineToArea; /* 47 */ void *tkLineToPoint; /* 48 */ void *tkMakeBezierCurve; /* 49 */ void *tkMakeBezierPostscript; /* 50 */ void *tkOptionClassChanged; /* 51 */ void *tkOptionDeadWindow; /* 52 */ void *tkOvalToArea; /* 53 */ void *tkOvalToPoint; /* 54 */ void *tkpChangeFocus; /* 55 */ void *tkpCloseDisplay; /* 56 */ void *tkpClaimFocus; /* 57 */ void *tkpDisplayWarning; /* 58 */ void *tkpGetAppName; /* 59 */ void *tkpGetOtherWindow; /* 60 */ void *tkpGetWrapperWindow; /* 61 */ void *tkpInit; /* 62 */ void *tkpInitializeMenuBindings; /* 63 */ void (*tkpMakeContainer)(Tk_Window tkwin); /* 64 */ void *tkpMakeMenuWindow; /* 65 */ void *tkpMakeWindow; /* 66 */ void *tkpMenuNotifyToplevelCreate; /* 67 */ void *tkpOpenDisplay; /* 68 */ void *tkPointerEvent; /* 69 */ void *tkPolygonToArea; /* 70 */ void *tkPolygonToPoint; /* 71 */ void *tkPositionInTree; /* 72 */ void *tkpRedirectKeyEvent; /* 73 */ void (*tkpSetMainMenubar)(Tcl_Interp *interp, Tk_Window tkwin, char *menuName); /* 74 */ int (*tkpUseWindow)(Tcl_Interp *interp, Tk_Window tkwin, char *string); /* 75 */ void *tkpWindowWasRecentlyDeleted; /* 76 */ void *tkQueueEventForAllChildren; /* 77 */ void *tkReadBitmapFile; /* 78 */ void *tkScrollWindow; /* 79 */ void *tkSelDeadWindow; /* 80 */ void *tkSelEventProc; /* 81 */ void *tkSelInit; /* 82 */ void *tkSelPropProc; /* 83 */ void (*tkSetClassProcs)(Tk_Window tkwin, void *procs, ClientData instanceData); /* 84 */ void (*tkSetWindowMenuBar)(Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName); /* 85 */ void *tkStringToKeysym; /* 86 */ void *tkThickPolyLineToArea; /* 87 */ void *tkWmAddToColormapWindows; /* 88 */ void *tkWmDeadWindow; /* 89 */ void *tkWmFocusToplevel; /* 90 */ void *tkWmMapWindow; /* 91 */ void *tkWmNewWindow; /* 92 */ void *tkWmProtocolEventProc; /* 93 */ void *tkWmRemoveFromColormapWindows; /* 94 */ void (*tkWmRestackToplevel)(Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 95 */ void *tkWmSetClass; /* 96 */ void *tkWmUnmapWindow; /* 97 */ void *tkDebugBitmap; /* 98 */ void *tkDebugBorder; /* 99 */ void *tkDebugCursor; /* 100 */ void *tkDebugColor; /* 101 */ void *tkDebugConfig; /* 102 */ void *tkDebugFont; /* 103 */ void *tkFindStateNumObj; /* 104 */ void *tkGetBitmapPredefTable; /* 105 */ void *tkGetDisplayList; /* 106 */ void *tkGetMainInfoList; /* 107 */ void *tkGetWindowFromObj; /* 108 */ void *tkpGetString; /* 109 */ void *tkpGetSubFonts; /* 110 */ void *tkpGetSystemDefault; /* 111 */ void *tkpMenuThreadInit; /* 112 */ void *tkClipBox; /* 113 */ void *tkCreateRegion; /* 114 */ void *tkDestroyRegion; /* 115 */ void *tkIntersectRegion; /* 116 */ void *tkRectInRegion; /* 117 */ void *tkSetRegion; /* 118 */ void *tkUnionRectWithRegion; /* 119 */ void *reserved120; void *tkpCreateNativeBitmap; /* 121 */ void *tkpDefineNativeBitmaps; /* 122 */ void *reserved123; void *tkpGetNativeAppBitmap; /* 124 */ void *reserved125; void *reserved126; void *reserved127; void *reserved128; void *reserved129; void *reserved130; void *reserved131; void *reserved132; void *reserved133; void *reserved134; void *tkpDrawHighlightBorder; /* 135 */ void *tkSetFocusWin; /* 136 */ void *tkpSetKeycodeAndState; /* 137 */ void *tkpGetKeySym; /* 138 */ void *tkpInitKeymapInfo; /* 139 */ } TkIntStubs; #ifdef __cplusplus extern "C" { #endif extern TkIntStubs *tkIntStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) /* * Inline function declarations: */ #ifndef TkComputeAnchor #define TkComputeAnchor \ (tkIntStubsPtr->tkComputeAnchor) /* 9 */ #endif #ifndef TkCopyAndGlobalEval #define TkCopyAndGlobalEval \ (tkIntStubsPtr->tkCopyAndGlobalEval) /* 10 */ #endif #ifndef TkCreateMainWindow #define TkCreateMainWindow \ (tkIntStubsPtr->tkCreateMainWindow) /* 14 */ #endif #ifndef TkpMakeContainer #define TkpMakeContainer \ (tkIntStubsPtr->tkpMakeContainer) /* 64 */ #endif #ifndef TkpSetMainMenubar #define TkpSetMainMenubar \ (tkIntStubsPtr->tkpSetMainMenubar) /* 74 */ #endif #ifndef TkpUseWindow #define TkpUseWindow \ (tkIntStubsPtr->tkpUseWindow) /* 75 */ #endif #ifndef TkSetClassProcs #define TkSetClassProcs \ (tkIntStubsPtr->tkSetClassProcs) /* 84 */ #endif #ifndef TkSetWindowMenuBar #define TkSetWindowMenuBar \ (tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */ #endif #ifndef TkWmRestackToplevel #define TkWmRestackToplevel \ (tkIntStubsPtr->tkWmRestackToplevel) /* 95 */ #endif #endif #if defined(WIN32) || defined(MAC_TCL) || defined(MAC_OSX_TCL) #ifndef TkClipBox #define TkClipBox \ (tkIntStubsPtr->tkClipBox) /* 113 */ #endif #ifndef TkCreateRegion #define TkCreateRegion \ (tkIntStubsPtr->tkCreateRegion) /* 114 */ #endif #ifndef TkDestroyRegion #define TkDestroyRegion \ (tkIntStubsPtr->tkDestroyRegion) /* 115 */ #endif #ifndef TkIntersectRegion #define TkIntersectRegion \ (tkIntStubsPtr->tkIntersectRegion) /* 116 */ #endif #ifndef TkRectInRegion #define TkRectInRegion \ (tkIntStubsPtr->tkRectInRegion) /* 117 */ #endif #ifndef TkSetRegion #define TkSetRegion \ (tkIntStubsPtr->tkSetRegion) /* 118 */ #endif #ifndef TkUnionRectWithRegion #define TkUnionRectWithRegion \ (tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */ #endif #endif /* WIN32 */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKINTDECLS */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltOp.h�����������������������������������������������������������������������0000644�0001750�0001750�00000002222�11462120062�014254� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* *--------------------------------------------------------------------------- * * Blt_OpSpec -- * * Structure to specify a set of operations for a TCL command. * This is passed to the Blt_GetOp procedure to look * for a function pointer associated with the operation name. * *--------------------------------------------------------------------------- */ typedef struct { const char *name; /* Name of operation */ int minChars; /* Minimum # characters to disambiguate */ void *proc; int minArgs; /* Minimum # args required */ int maxArgs; /* Maximum # args required */ const char *usage; /* Usage message */ } Blt_OpSpec; typedef enum { BLT_OP_ARG0, /* Op is the first argument. */ BLT_OP_ARG1, /* Op is the second argument. */ BLT_OP_ARG2, /* Op is the third argument. */ BLT_OP_ARG3, /* Op is the fourth argument. */ BLT_OP_ARG4 /* Op is the fifth argument. */ } Blt_OpIndex; #define BLT_OP_BINARY_SEARCH 0 #define BLT_OP_LINEAR_SEARCH 1 BLT_EXTERN void *Blt_GetOpFromObj(Tcl_Interp *interp, int nSpecs, Blt_OpSpec *specs, int operPos, int objc, Tcl_Obj *const *objv, int flags); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltCutbuffer.c����������������������������������������������������������������0000644�0001750�0001750�00000014763�11462120062�015633� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltCutbuffer.c -- * * Copyright 1993-1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_CUTBUFFER #include "bltOp.h" #ifndef WIN32 #include <X11/Xproto.h> #endif static int GetCutNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *bufferPtr) { int number; if (Tcl_GetIntFromObj(interp, objPtr, &number) != TCL_OK) { return TCL_ERROR; } if ((number < 0) || (number > 7)) { Tcl_AppendResult(interp, "bad buffer # \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } *bufferPtr = number; return TCL_OK; } /* ARGSUSED */ static int RotateErrorProc(ClientData clientData, XErrorEvent *errEventPtr) { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } static int GetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_Window tkwin = clientData; char *string; int buffer; int nBytes; buffer = 0; if (objc == 3) { if (GetCutNumberFromObj(interp, objv[2], &buffer) != TCL_OK) { return TCL_ERROR; } } string = XFetchBuffer(Tk_Display(tkwin), &nBytes, buffer); if (string != NULL) { int limit; char *p; int i; if (string[nBytes - 1] == '\0') { limit = nBytes - 1; } else { limit = nBytes; } for (p = string, i = 0; i < limit; i++, p++) { int c; c = (unsigned char)*p; if (c == 0) { *p = ' '; /* Convert embedded NUL bytes */ } } if (limit == nBytes) { char *newPtr; /* * Need to copy the string into a bigger buffer so we can * add a NUL byte on the end. */ newPtr = Blt_AssertMalloc(nBytes + 1); memcpy(newPtr, string, nBytes); newPtr[nBytes] = '\0'; Blt_Free(string); string = newPtr; } Tcl_SetStringObj(Tcl_GetObjResult(interp), string, nBytes); } return TCL_OK; } static int RotateOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_Window tkwin = clientData; int count; int result; Tk_ErrorHandler handler; count = 1; /* Default: rotate one position */ if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &count) != TCL_OK) { return TCL_ERROR; } if ((count < 0) || (count > 8)) { Tcl_AppendResult(interp, "bad rotate count \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); return TCL_ERROR; } } result = TCL_OK; handler = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch, X_RotateProperties, -1, RotateErrorProc, &result); XRotateBuffers(Tk_Display(tkwin), count); Tk_DeleteErrorHandler(handler); XSync(Tk_Display(tkwin), False); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't rotate cutbuffers unless all are set", (char *)NULL); return TCL_ERROR; } return TCL_OK; } static int SetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_Window tkwin = clientData; int buffer; char *string; int length; buffer = 0; if (objc == 4) { if (GetCutNumberFromObj(interp, objv[3], &buffer) != TCL_OK) { return TCL_ERROR; } } string = Tcl_GetStringFromObj(objv[2], &length); XStoreBuffer(Tk_Display(tkwin), string, length + 1, buffer); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BLT Sub-command specification: * * - Name of the sub-command. * - Minimum number of characters needed to unambiguously * recognize the sub-command. * - Pointer to the function to be called for the sub-command. * - Minimum number of arguments accepted. * - Maximum number of arguments accepted. * - String to be displayed for usage. * *--------------------------------------------------------------------------- */ static Blt_OpSpec cbOps[] = { {"get", 1, GetOp, 2, 3, "?buffer?",}, {"rotate", 1, RotateOp, 2, 3, "?count?",}, {"set", 1, SetOp, 3, 4, "value ?buffer?",}, }; static int numCbOps = sizeof(cbOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * CutBufferCmd -- * * This procedure is invoked to process the "cutbuffer" Tcl * command. See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int CutbufferCmd( ClientData clientData, /* Main window associated with * interpreter.*/ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tk_Window tkwin; Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, numCbOps, cbOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } tkwin = Tk_MainWindow(interp); result = (*proc) (tkwin, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * Blt_CutbufferCmdInitProc -- * * This procedure is invoked to initialize the "cutbuffer" Tcl * command. See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ int Blt_CutbufferCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"cutbuffer", CutbufferCmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_CUTBUFFER */ �������������./saods9/blt3.0.1/src/bltCanvEps.c������������������������������������������������������������������0000644�0001750�0001750�00000152166�11462120062�015245� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltCanvEps.c -- * * This file implements an Encapsulated PostScript item for canvas * widgets. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * To do: * * 1. Add -rotate option. Allow arbitrary rotation of image and EPS. * 2. Draw pictures instead of photos. This will eliminate the need * to create hidden photo images. * 3. Create a spiffy demo that lets you edit your page description. */ #define USE_OLD_CANVAS 1 #include "bltInt.h" #include "bltPs.h" #include "bltImage.h" #include "bltPicture.h" #include "bltPainter.h" #ifdef HAVE_TIFF_H #include "tiff.h" #endif #include <fcntl.h> #if defined(_MSC_VER) || defined(__BORLANDC__) #include <io.h> #define open _open #define close _close #define write _write #define unlink _unlink #define lseek _lseek #define fdopen _fdopen #define fcntl _fcntl #ifdef _MSC_VER #define O_RDWR _O_RDWR #define O_CREAT _O_CREAT #define O_TRUNC _O_TRUNC #define O_EXCL _O_EXCL #endif /* _MSC_VER */ #endif /* _MSC_VER || __BORLANDC__ */ #define DEBUG_READER 0 #ifndef WIN32 #define PurifyPrintf printf #endif #define PS_PREVIEW_EPSI 0 #define PS_PREVIEW_WMF 1 #define PS_PREVIEW_TIFF 2 #define MAX_EPS_LINE_LENGTH 255 /* Maximum line length for a EPS * file */ /* * ParseInfo -- * * This structure is used to pass PostScript file information around to * various routines while parsing the EPS file. */ typedef struct { int maxBytes; /* Maximum length of PostScript * code. */ int lineNumber; /* Current line number of EPS file */ char line[MAX_EPS_LINE_LENGTH + 1]; /* Buffer to contain a single line * from the PostScript file. */ unsigned char hexTable[256]; /* Table for converting ASCII hex * digits to values */ char *nextPtr; /* Pointer to the next character to * process on the current line. If * NULL (or if nextPtr points a NULL * byte), this indicates the the next * line needs to be read. */ FILE *f; /* */ } ParseInfo; #define DEF_EPS_ANCHOR "nw" #define DEF_EPS_OUTLINE_COLOR RGB_BLACK #define DEF_EPS_BORDERWIDTH STD_BORDERWIDTH #define DEF_EPS_FILE_NAME (char *)NULL #define DEF_EPS_FONT STD_FONT #define DEF_EPS_FILL_COLOR STD_NORMAL_FOREGROUND #define DEF_EPS_HEIGHT "0" #define DEF_EPS_IMAGE_NAME (char *)NULL #define DEF_EPS_JUSTIFY "center" #define DEF_EPS_QUICK_RESIZE "no" #define DEF_EPS_RELIEF "sunken" #define DEF_EPS_SHOW_IMAGE "yes" #define DEF_EPS_STIPPLE (char *)NULL #define DEF_EPS_TAGS (char *)NULL #define DEF_EPS_TITLE (char *)NULL #define DEF_EPS_TITLE_ANCHOR "center" #define DEF_EPS_TITLE_COLOR RGB_BLACK #define DEF_EPS_WIDTH "0" /* * Information used for parsing configuration specs: */ static Tk_CustomOption tagsOption; BLT_EXTERN Tk_CustomOption bltDistanceOption; /* * The structure below defines the record for each EPS item. */ typedef struct { Tk_Item item; /* Generic stuff that's the same for * all types. MUST BE FIRST IN * STRUCTURE. */ Tk_Canvas canvas; /* Canvas containing the EPS item. */ int lastWidth, lastHeight; /* Last known dimensions of the EPS * item. This is used to know if the * picture preview needs to be * resized. */ Tcl_Interp *interp; FILE *psFile; /* File pointer to Encapsulated * PostScript file. We'll hold this as * long as the EPS item is using this * file. */ unsigned int psStart; /* File offset of PostScript code. */ unsigned int psLength; /* Length of PostScript code. If zero, * indicates to read to EOF. */ unsigned int wmfStart; /* File offset of Windows Metafile * preview. */ unsigned int wmfLength; /* Length of WMF portion in bytes. If * zero, indicates there is no WMF * preview. */ unsigned int tiffStart; /* File offset of TIFF preview. */ unsigned int tiffLength; /* Length of TIFF portion in bytes. If * zero, indicates there is no TIFF * * preview. */ const char *previewImageName; int previewFormat; Tk_Image preview; /* A Tk photo image provided as a * preview of the EPS contents. This * image supersedes any EPS preview * embedded PostScript preview * (EPSI). */ Blt_Painter painter; Blt_Picture original; /* The original photo or PostScript * preview image converted to a * picture. */ int origFromPicture; Blt_Picture picture; /* Holds resized preview image. * Created and deleted internally. */ int firstLine, lastLine; /* First and last line numbers of the * PostScript preview. They are used * to skip over the preview when * encapsulating PostScript for the * canvas item. */ GC fillGC; /* Graphics context to fill background * of image outline if no preview * image was present. */ int llx, lly, urx, ury; /* Lower left and upper right * coordinates of PostScript bounding * box, retrieved from file's * "BoundingBox:" field. */ const char *title; /* Title, retrieved from the file's * "Title:" field, to be displayed * over the top of the EPS preview * (malloc-ed). */ Tcl_DString dString; /* Contains the encapsulated * PostScript. */ /* User configurable fields */ double x, y; /* Requested anchor in canvas * coordinates of the item */ Tk_Anchor anchor; Region2d bb; const char *fileName; /* Name of the encapsulated PostScript * file. If NULL, indicates that no * EPS file has be successfully * loaded yet. */ const char *reqTitle; /* Title to be displayed in the EPS * item. Supersedes the title found * in the EPS file. If NULL, indicates * that the title found in the EPS * file should be used. */ int width, height; /* Requested dimension of EPS item in * canvas coordinates. If non-zero, * this overrides the dimension * computed from the "%%BoundingBox:" * specification in the EPS file * used. */ int showImage; /* Indicates if the image or the * outline rectangle should be * displayed */ int quick; unsigned int flags; XColor *fillColor; /* Fill color of the image outline. */ Tk_3DBorder border; /* Outline color */ int borderWidth; int relief; TextStyle titleStyle; /* Font, color, etc. for title */ Blt_Font font; Pixmap stipple; /* Stipple for image fill */ ClientData tiffPtr; #ifdef WIN32 HENHMETAFILE *hMetaFile; /* Windows metafile. */ #endif } Eps; static int StringToFont(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *string, char *widgRec, int offset); static char *FontToString (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **proc); static Tk_CustomOption bltFontOption = { StringToFont, FontToString, (ClientData)0 }; static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_ANCHOR, (char *)"-anchor", (char *)NULL, (char *)NULL, DEF_EPS_ANCHOR, Blt_Offset(Eps, anchor), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_SYNONYM, (char *)"-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {TK_CONFIG_CUSTOM, (char *)"-borderwidth", "borderWidth", (char *)NULL, DEF_EPS_BORDERWIDTH, Blt_Offset(Eps, borderWidth), TK_CONFIG_DONT_SET_DEFAULT, &bltDistanceOption}, {TK_CONFIG_STRING, (char *)"-file", (char *)NULL, (char *)NULL, DEF_EPS_FILE_NAME, Blt_Offset(Eps, fileName), TK_CONFIG_NULL_OK}, {TK_CONFIG_CUSTOM, (char *)"-font", "font", "Font", DEF_EPS_FONT, Blt_Offset(Eps, font), 0, &bltFontOption}, {TK_CONFIG_COLOR, (char *)"-fill", "fill", (char *)NULL, DEF_EPS_FILL_COLOR, Blt_Offset(Eps, fillColor), 0}, {TK_CONFIG_CUSTOM, (char *)"-height", (char *)NULL, (char *)NULL, DEF_EPS_HEIGHT, Blt_Offset(Eps, height), TK_CONFIG_DONT_SET_DEFAULT, &bltDistanceOption}, {TK_CONFIG_STRING, (char *)"-image", (char *)NULL, (char *)NULL, DEF_EPS_IMAGE_NAME, Blt_Offset(Eps, previewImageName), TK_CONFIG_NULL_OK}, {TK_CONFIG_JUSTIFY, (char *)"-justify", "justify", "Justify", DEF_EPS_JUSTIFY, Blt_Offset(Eps, titleStyle.justify), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_BORDER, (char *)"-outline", "outline", (char *)NULL, DEF_EPS_OUTLINE_COLOR, Blt_Offset(Eps, border), TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, (char *)"-quick", "quick", "Quick", DEF_EPS_QUICK_RESIZE, Blt_Offset(Eps, quick), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_RELIEF, (char *)"-relief", (char *)NULL, (char *)NULL, DEF_EPS_RELIEF, Blt_Offset(Eps, relief), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_BOOLEAN, (char *)"-showimage", "showImage", "ShowImage", DEF_EPS_SHOW_IMAGE, Blt_Offset(Eps, showImage), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_BITMAP, (char *)"-stipple", (char *)NULL, (char *)NULL, DEF_EPS_STIPPLE, Blt_Offset(Eps, stipple), TK_CONFIG_NULL_OK}, {TK_CONFIG_CUSTOM, (char *)"-tags", (char *)NULL, (char *)NULL, DEF_EPS_TAGS, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, (char *)"-title", (char *)NULL, (char *)NULL, DEF_EPS_TITLE, Blt_Offset(Eps, reqTitle), TK_CONFIG_NULL_OK}, {TK_CONFIG_ANCHOR, (char *)"-titleanchor", (char *)NULL, (char *)NULL, DEF_EPS_TITLE_ANCHOR, Blt_Offset(Eps, titleStyle.anchor), 0}, {TK_CONFIG_COLOR, (char *)"-titlecolor", (char *)NULL, (char *)NULL, DEF_EPS_TITLE_COLOR, Blt_Offset(Eps, titleStyle.color), 0}, {TK_CONFIG_CUSTOM, (char *)"-width", (char *)NULL, (char *)NULL, DEF_EPS_WIDTH, Blt_Offset(Eps, width), TK_CONFIG_DONT_SET_DEFAULT, &bltDistanceOption}, {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Prototypes for procedures defined in this file: */ static Tk_ImageChangedProc ImageChangedProc; static Tk_ItemCoordProc EpsCoords; static Tk_ItemAreaProc EpsToArea; static Tk_ItemPointProc EpsToPoint; static Tk_ItemConfigureProc ConfigureEps; static Tk_ItemCreateProc CreateEps; static Tk_ItemDeleteProc DeleteEps; static Tk_ItemDisplayProc DisplayEps; static Tk_ItemScaleProc ScaleEps; static Tk_ItemTranslateProc TranslateEps; static Tk_ItemPostscriptProc EpsToPostScript; static void ComputeEpsBbox(Tk_Canvas canvas, Eps *imgPtr); static int ReadPostScript(Tcl_Interp *interp, Eps *epsPtr); /* *--------------------------------------------------------------------------- * * StringToFont -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StringToFont( ClientData clientData, /* Indicated how to check distance */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Window */ const char *string, /* Pixel value string */ char *widgRec, /* Widget record */ int offset) /* Offset of pixel size in record */ { Blt_Font *fontPtr = (Blt_Font *)(widgRec + offset); Blt_Font font; font = Blt_GetFont(interp, tkwin, string); if (font == NULL) { return TCL_ERROR; } *fontPtr = font; return TCL_OK; } /* *--------------------------------------------------------------------------- * * FontToString -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static char * FontToString( ClientData clientData, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget structure record */ int offset, /* Offset in widget record */ Tcl_FreeProc **freeProcPtr) /* Not used. */ { Blt_Font font = *(Blt_Font *)(widgRec + offset); const char *string; string = Blt_NameOfFont(font); *freeProcPtr = (Tcl_FreeProc *)TCL_STATIC; return (char *)string; } static char * SkipBlanks(ParseInfo *piPtr) { char *s; for (s = piPtr->line; isspace(UCHAR(*s)); s++) { /*empty*/ } return s; } static int ReadPsLine(ParseInfo *piPtr) { int nBytes; nBytes = 0; if (ftell(piPtr->f) < piPtr->maxBytes) { char *cp; cp = piPtr->line; while ((*cp = fgetc(piPtr->f)) != EOF) { if (*cp == '\r') { continue; } nBytes++; if ((*cp == '\n') || (nBytes >= MAX_EPS_LINE_LENGTH)) { break; } cp++; } if (*cp == '\n') { piPtr->lineNumber++; } *cp = '\0'; } return nBytes; } /* *--------------------------------------------------------------------------- * * ReverseBits -- * * Convert a byte from a X image into PostScript image order. This * requires not only the nybbles to be reversed but also their bit * values. * * Results: * The converted byte is returned. * *--------------------------------------------------------------------------- */ INLINE static unsigned char ReverseBits(unsigned char byte) { byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xaa); byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xcc); byte = ((byte >> 4) & 0x0f) | ((byte << 4) & 0xf0); return byte; } /* *--------------------------------------------------------------------------- * * GetHexValue -- * * Reads the next ASCII hex value from EPS preview image and converts it. * * Results: * One of three TCL return values is possible. * * TCL_OK the next byte was successfully parsed. * TCL_ERROR an error occurred processing the next hex value. * TCL_RETURN "%%EndPreview" line was detected. * * The converted hex value is returned via "bytePtr". * *--------------------------------------------------------------------------- */ static int GetHexValue(ParseInfo *piPtr, unsigned char *bytePtr) { char *p; unsigned int byte; unsigned char a, b; p = piPtr->nextPtr; if (p == NULL) { nextLine: if (!ReadPsLine(piPtr)) { #if DEBUG_READER PurifyPrintf("short file\n"); #endif return TCL_ERROR; /* Short file */ } if (piPtr->line[0] != '%') { #if DEBUG_READER PurifyPrintf("line doesn't start with %% (%s)\n", piPtr->line); #endif return TCL_ERROR; } if ((piPtr->line[1] == '%') && (strncmp(piPtr->line + 2, "EndPreview", 10) == 0)) { #if DEBUG_READER PurifyPrintf("end of preview (%s)\n", piPtr->line); #endif return TCL_RETURN; } p = piPtr->line + 1; } while (isspace((int)*p)) { p++; /* Skip spaces */ } if (*p == '\0') { goto nextLine; } a = piPtr->hexTable[(int)p[0]]; b = piPtr->hexTable[(int)p[1]]; if ((a == 0xFF) || (b == 0xFF)) { #if DEBUG_READER PurifyPrintf("not a hex digit (%s)\n", piPtr->line); #endif return TCL_ERROR; } byte = (a << 4) | b; p += 2; piPtr->nextPtr = p; *bytePtr = byte; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ReadEPSI -- * * Reads the EPS preview image from the PostScript file, converting it * into a picture. If an error occurs when parsing the preview, the * preview is silently ignored. * * Results: * None. * *--------------------------------------------------------------------------- */ static void ReadEPSI(Eps *epsPtr, ParseInfo *piPtr) { Blt_Picture picture; int width, height, bitsPerPixel, nLines; char *dscBeginPreview; dscBeginPreview = piPtr->line + 16; if (sscanf(dscBeginPreview, "%d %d %d %d", &width, &height, &bitsPerPixel, &nLines) != 4) { #if DEBUG_READER PurifyPrintf("bad %%BeginPreview (%s) format\n", dscBeginPreview); #endif return; } if (((bitsPerPixel != 1) && (bitsPerPixel != 8)) || (width < 1) || (width > SHRT_MAX) || (height < 1) || (height > SHRT_MAX)) { #if DEBUG_READER PurifyPrintf("Bad %%BeginPreview (%s) values\n", dscBeginPreview); #endif return; /* Bad "%%BeginPreview:" information */ } epsPtr->firstLine = piPtr->lineNumber; Blt_InitHexTable(piPtr->hexTable); piPtr->nextPtr = NULL; picture = Blt_CreatePicture(width, height); if (bitsPerPixel == 8) { Blt_Pixel *destRowPtr; int y; destRowPtr = Blt_PictureBits(picture) + (height - 1) * Blt_PictureStride(picture); for (y = height - 1; y >= 0; y--) { Blt_Pixel *dp; int x; dp = destRowPtr; for (x = 0; x < width; x++, dp++) { int result; unsigned char byte; result = GetHexValue(piPtr, &byte); if (result == TCL_ERROR) { goto error; } if (result == TCL_RETURN) { goto done; } dp->Red = dp->Green = dp->Blue = ~byte; dp->Alpha = ALPHA_OPAQUE; } destRowPtr -= Blt_PictureStride(picture); } } else if (bitsPerPixel == 1) { Blt_Pixel *destRowPtr; int y; destRowPtr = Blt_PictureBits(picture); for (y = 0; y < height; y++) { Blt_Pixel *dp, *dend; int bit; unsigned char byte; bit = 8; byte = 0; /* Suppress compiler warning. */ for (dp = destRowPtr, dend = dp + width; dp < dend; dp++) { if (bit == 8) { int result; result = GetHexValue(piPtr, &byte); if (result == TCL_ERROR) { goto error; } if (result == TCL_RETURN) { goto done; } byte = ReverseBits(byte); bit = 0; } if (((byte >> bit) & 0x01) == 0) { dp->u32 = 0xFFFFFFFF; } bit++; } destRowPtr += Blt_PictureStride(picture); } } else { fprintf(stderr, "unknown EPSI bitsPerPixel (%d)\n", bitsPerPixel); } done: epsPtr->original = picture; epsPtr->origFromPicture = FALSE; epsPtr->lastWidth = Blt_PictureWidth(picture); epsPtr->lastHeight = Blt_PictureHeight(picture); epsPtr->lastLine = piPtr->lineNumber + 1; return; error: epsPtr->firstLine = epsPtr->lastLine = -1; if (picture != NULL) { Blt_FreePicture(picture); } } /* *--------------------------------------------------------------------------- * * ReadPostScript -- * * This routine reads and parses the few fields we need out of an EPS * file. * * The EPS standards are outlined from Appendix H of the "PostScript * Language Reference Manual" pp. 709-736. * * Mandatory fields: * * - Starts with "%!PS*" * - Contains "%%BoundingBox: llx lly urx ury" * * Optional fields for EPS item: * - "%%BeginPreview: w h bpp #lines" * Preview is in hexadecimal. Each line must start with "%" * - "%%EndPreview" * - "%%Title: (string)" * *--------------------------------------------------------------------------- */ static int ReadPostScript(Tcl_Interp *interp, Eps *epsPtr) { char *field; char *dscTitle, *dscBoundingBox; char *dscEndComments; ParseInfo pi; pi.line[0] = '\0'; pi.maxBytes = epsPtr->psLength; pi.lineNumber = 0; pi.f = epsPtr->psFile; Tcl_DStringInit(&epsPtr->dString); if (pi.maxBytes == 0) { pi.maxBytes = INT_MAX; } if (epsPtr->psStart > 0) { if (fseek(epsPtr->psFile, epsPtr->psStart, 0) != 0) { Tcl_AppendResult(interp, "can't seek to start of PostScript code in \"", epsPtr->fileName, "\"", (char *)NULL); return TCL_ERROR; } } if (!ReadPsLine(&pi)) { Tcl_AppendResult(interp, "file \"", epsPtr->fileName, "\" is empty?", (char *)NULL); return TCL_ERROR; } if (strncmp(pi.line, "%!PS", 4) != 0) { Tcl_AppendResult(interp, "file \"", epsPtr->fileName, "\" doesn't start with \"%!PS\"", (char *)NULL); return TCL_ERROR; } /* * Initialize field flags to NULL. We want to look only at the first * appearance of these comment fields. The file itself may have another * EPS file embedded into it. */ dscBoundingBox = dscTitle = dscEndComments = NULL; pi.lineNumber = 1; while (ReadPsLine(&pi)) { pi.lineNumber++; if ((pi.line[0] == '%') && (pi.line[1] == '%')) { /* Header comment */ field = pi.line + 2; if (field[0] == 'B') { if (strncmp(field, "BeginSetup", 8) == 0) { break; /* Done */ } if (strncmp(field, "BeginProlog", 8) == 0) { break; /* Done */ } if ((strncmp(field, "BoundingBox:", 12) == 0) && (dscBoundingBox == NULL)) { int nFields; dscBoundingBox = field + 12; nFields = sscanf(dscBoundingBox, "%d %d %d %d", &epsPtr->llx, &epsPtr->lly, &epsPtr->urx, &epsPtr->ury); if (nFields != 4) { Tcl_AppendResult(interp, "bad \"%%BoundingBox\" values: \"", dscBoundingBox, "\"", (char *)NULL); goto error; } } } else if ((field[0] == 'T') && (strncmp(field, "Title:", 6) == 0)) { if (dscTitle == NULL) { char *lp, *rp; lp = strchr(field + 6, '('); if (lp != NULL) { rp = strrchr(field + 6, ')'); if (rp != NULL) { *rp = '\0'; } dscTitle = Blt_AssertStrdup(lp + 1); } else { dscTitle = Blt_AssertStrdup(field + 6); } } } else if (field[0] == 'E') { if (strncmp(field, "EndComments", 11) == 0) { dscEndComments = field; break; /* Done */ } } } /* %% */ } if (dscBoundingBox == NULL) { Tcl_AppendResult(interp, "no \"%%BoundingBox:\" found in \"", epsPtr->fileName, "\"", (char *)NULL); goto error; } if (dscEndComments != NULL) { /* Check if a "%%BeginPreview" immediately follows */ while (ReadPsLine(&pi)) { field = SkipBlanks(&pi); if (field[0] != '\0') { break; } } if (strncmp(pi.line, "%%BeginPreview:", 15) == 0) { ReadEPSI(epsPtr, &pi); } } if (dscTitle != NULL) { epsPtr->title = dscTitle; } /* Finally save the PostScript into a dynamic string. */ while (ReadPsLine(&pi)) { Tcl_DStringAppend(&epsPtr->dString, pi.line, -1); Tcl_DStringAppend(&epsPtr->dString, "\n", 1); } return TCL_OK; error: if (dscTitle != NULL) { Blt_Free(dscTitle); } return TCL_ERROR; /* BoundingBox: is required. */ } static int OpenEpsFile(Tcl_Interp *interp, Eps *epsPtr) { FILE *f; #ifdef WIN32 DOSEPSHEADER dosHeader; int nBytes; #endif f = Blt_OpenFile(interp, epsPtr->fileName, "rb"); if (f == NULL) { Tcl_AppendResult(epsPtr->interp, "can't open \"", epsPtr->fileName, "\": ", Tcl_PosixError(epsPtr->interp), (char *)NULL); return TCL_ERROR; } epsPtr->psFile = f; epsPtr->psStart = epsPtr->psLength = 0L; epsPtr->wmfStart = epsPtr->wmfLength = 0L; epsPtr->tiffStart = epsPtr->tiffLength = 0L; #ifdef WIN32 nBytes = fread(&dosHeader, sizeof(DOSEPSHEADER), 1, f); if ((nBytes == sizeof(DOSEPSHEADER)) && (dosHeader.magic[0] == 0xC5) && (dosHeader.magic[1] == 0xD0) && (dosHeader.magic[2] == 0xD3) && (dosHeader.magic[3] == 0xC6)) { /* DOS EPS file */ epsPtr->psStart = dosHeader.psStart; epsPtr->wmfStart = dosHeader.wmfStart; epsPtr->wmfLength = dosHeader.wmfLength; epsPtr->tiffStart = dosHeader.tiffStart; epsPtr->tiffLength = dosHeader.tiffLength; epsPtr->previewFormat = PS_PREVIEW_EPSI; #ifdef HAVE_TIFF_H if (epsPtr->tiffLength > 0) { epsPtr->previewFormat = PS_PREVIEW_TIFF; } #endif /* HAVE_TIFF_H */ if (epsPtr->wmfLength > 0) { epsPtr->previewFormat = PS_PREVIEW_WMF; } } fseek(f, 0, 0); #endif /* WIN32 */ return ReadPostScript(interp, epsPtr); } static void CloseEpsFile(Eps *epsPtr) { if (epsPtr->psFile != NULL) { fclose(epsPtr->psFile); epsPtr->psFile = NULL; } } #ifdef WIN32 #ifdef HAVE_TIFF_H static void ReadTiffPreview(Eps *epsPtr) { unsigned int width, height; Blt_Picture picture; Blt_Pixel *dataPtr; FILE *f; int n; TIFFGetField(epsPtr->tiffPtr, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(epsPtr->tiffPtr, TIFFTAG_IMAGELENGTH, &height); picture = Blt_CreatePicture(width, height); dataPtr = Blt_PictureBits(picture); if (!TIFFReadRGBAImage(epsPtr->tiffPtr, width, height, dataPtr, 0)) { Blt_FreePicture(picture); return; } /* Reverse the order of the components for each pixel. */ /* ... */ epsPtr->origFromPicture = FALSE; epsPtr->picture = picture; } #endif #ifdef notdef ReadWMF(f, epsPtr, headerPtr) FILE *f; { HANDLE hMem; Tk_Window tkwin; if (fseek(f, headerPtr->wmfStart, 0) != 0) { Tcl_AppendResult(interp, "can't seek in \"", epsPtr->fileName, "\"", (char *)NULL); return TCL_ERROR; } hMem = GlobalAlloc(GHND, size); if (hMem == NULL) { Tcl_AppendResult(graphPtr->interp, "can't allocate global memory:", Blt_LastError(), (char *)NULL); return TCL_ERROR; } buffer = (LPVOID)GlobalLock(hMem); /* Read the header and see what kind of meta file it is. */ fread(buffer, sizeof(unsigned char), headerPtr->wmfLength, f); mfp.mm = 0; mfp.xExt = epsPtr->width; mfp.yExt = epsPtr->height; mfp.hMF = hMetaFile; tkwin = Tk_CanvasTkwin(epsPtr->canvas); hRefDC = TkWinGetDrawableDC(Tk_Display(tkwin), Tk_WindowId(tkwin), &state); hDC = CreateEnhMetaFile(hRefDC, NULL, NULL, NULL); mfp.hMF = CloseEnhMetaFile(hDC); hMetaFile = SetWinMetaFileBits(size, buffer, MM_ANISOTROPIC, &picture); Tcl_AppendResult(graphPtr->interp, "can't get metafile data:", Blt_LastError(), (char *)NULL); goto error; } #endif #endif /* WIN32 */ /* *--------------------------------------------------------------------------- * * DeleteEps -- * * This procedure is called to clean up the data structure associated * with a EPS item. * * Results: * None. * * Side effects: * Resources associated with itemPtr are released. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void DeleteEps( Tk_Canvas canvas, /* Info about overall canvas * widget. */ Tk_Item *itemPtr, /* Item that is being deleted. */ Display *display) /* Display containing window for * canvas. */ { Eps *epsPtr = (Eps *)itemPtr; Tk_FreeOptions(configSpecs, (char *)epsPtr, display, 0); CloseEpsFile(epsPtr); if ((!epsPtr->origFromPicture) && (epsPtr->original != NULL)) { Blt_FreePicture(epsPtr->original); } if (epsPtr->picture != NULL) { Blt_FreePicture(epsPtr->picture); } if (epsPtr->painter != NULL) { Blt_FreePainter(epsPtr->painter); } if (epsPtr->preview != NULL) { Tk_FreeImage(epsPtr->preview); } if (epsPtr->previewImageName != NULL) { Blt_Free(epsPtr->previewImageName); } if (epsPtr->stipple != None) { Tk_FreePixmap(display, epsPtr->stipple); } if (epsPtr->fillGC != NULL) { Tk_FreeGC(display, epsPtr->fillGC); } Blt_Ts_FreeStyle(display, &epsPtr->titleStyle); if (epsPtr->title != NULL) { Blt_Free(epsPtr->title); } } /* *--------------------------------------------------------------------------- * * CreateEps -- * * This procedure is invoked to create a new EPS item in a canvas. * * Results: * A standard TCL return value. If an error occurred in creating the * item, then an error message is left in interp->result; in this case * itemPtr is left uninitialized, so it can be safely freed by the * caller. * * Side effects: * A new EPS item is created. * *--------------------------------------------------------------------------- */ static int CreateEps( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Canvas canvas, /* Canvas to hold new item. */ Tk_Item *itemPtr, /* Record to hold new item; header has * been initialized by caller. */ int argc, /* Number of arguments in argv. */ char **argv) /* Arguments describing rectangle. */ { Eps *epsPtr = (Eps *)itemPtr; Tk_Window tkwin; double x, y; tkwin = Tk_CanvasTkwin(canvas); if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tk_PathName(tkwin), " create ", itemPtr->typePtr->name, " x1 y1 ?options?\"", (char *)NULL); return TCL_ERROR; } /* Initialize the item's record by hand (bleah). */ epsPtr->anchor = TK_ANCHOR_NW; epsPtr->border = NULL; epsPtr->borderWidth = 0; epsPtr->canvas = canvas; epsPtr->fileName = NULL; epsPtr->psFile = NULL; epsPtr->fillGC = NULL; epsPtr->fillColor = NULL; epsPtr->painter = NULL; epsPtr->original = NULL; epsPtr->origFromPicture = FALSE; epsPtr->previewImageName = NULL; epsPtr->preview = NULL; epsPtr->interp = interp; epsPtr->picture = NULL; epsPtr->firstLine = epsPtr->lastLine = -1; epsPtr->relief = TK_RELIEF_SUNKEN; epsPtr->reqTitle = NULL; epsPtr->stipple = None; epsPtr->showImage = TRUE; epsPtr->quick = FALSE; epsPtr->title = NULL; epsPtr->lastWidth = epsPtr->lastHeight = 0; epsPtr->width = epsPtr->height = 0; epsPtr->x = epsPtr->y = 0.0; epsPtr->llx = epsPtr->lly = epsPtr->urx = epsPtr->ury = 0; epsPtr->bb.left = epsPtr->bb.right = epsPtr->bb.top = epsPtr->bb.bottom = 0; Tcl_DStringInit(&epsPtr->dString); Blt_Ts_InitStyle(epsPtr->titleStyle); #define PAD 8 Blt_Ts_SetPadding(epsPtr->titleStyle, PAD, PAD, PAD, PAD); /* Process the arguments to fill in the item record. */ if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &x) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &y) != TCL_OK)) { return TCL_ERROR; } epsPtr->x = x; epsPtr->y = y; if (ConfigureEps(interp, canvas, itemPtr, argc - 2, argv + 2, 0) != TCL_OK) { DeleteEps(canvas, itemPtr, Tk_Display(tkwin)); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImageChangedProc * * The image is over-written each time the EPS item is resized. So we * only worry if the image is deleted. * * We always resample from the picture we saved when the photo image was * specified (-image option). * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, int width, int height, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Eps *epsPtr = clientData; if ((epsPtr->preview == NULL) || (Blt_Image_IsDeleted(epsPtr->preview))) { epsPtr->preview = NULL; if (epsPtr->previewImageName != NULL) { Blt_Free(epsPtr->previewImageName); epsPtr->previewImageName = NULL; } Tk_CanvasEventuallyRedraw(epsPtr->canvas, epsPtr->item.x1, epsPtr->item.y1, epsPtr->item.x2, epsPtr->item.y2); } if (epsPtr->preview != NULL) { int result; if ((!epsPtr->origFromPicture) && (epsPtr->original != NULL)) { Blt_FreePicture(epsPtr->original); } result = Blt_GetPicture(epsPtr->interp, epsPtr->previewImageName, &epsPtr->original); if (result == TCL_OK) { epsPtr->origFromPicture = TRUE; } else { Tk_PhotoHandle photo; /* Photo handle to Tk image. */ photo = Tk_FindPhoto(epsPtr->interp, epsPtr->previewImageName); if (photo == NULL) { fprintf(stderr, "image \"%s\" isn't a picture or photo image\n", epsPtr->previewImageName); return; } epsPtr->original = Blt_PhotoToPicture(photo); epsPtr->origFromPicture = FALSE; } } } /* *--------------------------------------------------------------------------- * * ConfigureEps -- * * This procedure is invoked to configure various aspects of an EPS item, * such as its background color. * * Results: * A standard TCL result code. If an error occurs, then an error message * is left in interp->result. * * Side effects: * Configuration information may be set for itemPtr. * *--------------------------------------------------------------------------- */ static int ConfigureEps( Tcl_Interp *interp, /* Used for error reporting. */ Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* EPS item to reconfigure. */ int argc, /* Number of elements in argv. */ char **argv, /* Arguments describing things to * configure. */ int flags) /* Flags to pass to * Tk_ConfigureWidget. */ { Eps *epsPtr = (Eps *)itemPtr; Tk_Window tkwin; XGCValues gcValues; unsigned long gcMask; GC newGC; int width, height; Blt_Painter painter; tkwin = Tk_CanvasTkwin(canvas); if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (const char**)argv, (char *)epsPtr, flags) != TCL_OK) { return TCL_ERROR; } painter = Blt_GetPainter(tkwin, 1.0); if (epsPtr->painter != NULL) { Blt_FreePainter(epsPtr->painter); } epsPtr->painter = painter; /* Determine the size of the EPS item */ /* * Check for a "-image" option specifying an image to be displayed * representing the EPS canvas item. */ if (Blt_OldConfigModified(configSpecs, "-image", (char *)NULL)) { if (epsPtr->preview != NULL) { Tk_FreeImage(epsPtr->preview); /* Release old Tk image */ if ((!epsPtr->origFromPicture) && (epsPtr->original != NULL)) { Blt_FreePicture(epsPtr->original); } epsPtr->original = NULL; if (epsPtr->picture != NULL) { Blt_FreePicture(epsPtr->picture); } epsPtr->picture = NULL; epsPtr->preview = NULL; epsPtr->origFromPicture = FALSE; } if (epsPtr->previewImageName != NULL) { int result; /* Allocate a new image, if one was named. */ epsPtr->preview = Tk_GetImage(interp, tkwin, epsPtr->previewImageName, ImageChangedProc, epsPtr); if (epsPtr->preview == NULL) { Tcl_AppendResult(interp, "can't find an image \"", epsPtr->previewImageName, "\"", (char *)NULL); Blt_Free(epsPtr->previewImageName); epsPtr->previewImageName = NULL; return TCL_ERROR; } result = Blt_GetPicture(interp, epsPtr->previewImageName, &epsPtr->original); if (result == TCL_OK) { epsPtr->origFromPicture = TRUE; } else { Tk_PhotoHandle photo; /* Photo handle to Tk image. */ photo = Tk_FindPhoto(interp, epsPtr->previewImageName); if (photo == NULL) { Tcl_AppendResult(interp, "image \"", epsPtr->previewImageName, "\" is not a picture or photo image", (char *)NULL); return TCL_ERROR; } epsPtr->original = Blt_PhotoToPicture(photo); epsPtr->origFromPicture = FALSE; } } } if (Blt_OldConfigModified(configSpecs, "-file", (char *)NULL)) { CloseEpsFile(epsPtr); if ((!epsPtr->origFromPicture) && (epsPtr->original != NULL)) { Blt_FreePicture(epsPtr->original); epsPtr->original = NULL; } if (epsPtr->picture != NULL) { Blt_FreePicture(epsPtr->picture); epsPtr->picture = NULL; } epsPtr->firstLine = epsPtr->lastLine = -1; if (epsPtr->fileName != NULL) { if (OpenEpsFile(interp, epsPtr) != TCL_OK) { return TCL_ERROR; } } } /* Compute the normal width and height of the item, but let the * user-requested dimensions override them. */ width = height = 0; if (epsPtr->preview != NULL) { /* Default dimension is the size of the image. */ Tk_SizeOfImage(epsPtr->preview, &width, &height); } if (epsPtr->fileName != NULL) { /* Use dimensions provided by the BoundingBox. */ width = (epsPtr->urx - epsPtr->llx); height = (epsPtr->ury - epsPtr->lly); } if (epsPtr->width == 0) { epsPtr->width = width; } if (epsPtr->height == 0) { epsPtr->height = height; } if (Blt_OldConfigModified(configSpecs, "-quick", (char *)NULL)) { epsPtr->lastWidth = epsPtr->lastHeight = 0; } /* Fill color GC */ newGC = NULL; if (epsPtr->fillColor != NULL) { gcMask = GCForeground; gcValues.foreground = epsPtr->fillColor->pixel; if (epsPtr->stipple != None) { gcMask |= (GCStipple | GCFillStyle); gcValues.stipple = epsPtr->stipple; if (epsPtr->border != NULL) { gcValues.foreground = Tk_3DBorderColor(epsPtr->border)->pixel; gcValues.background = epsPtr->fillColor->pixel; gcMask |= GCBackground; gcValues.fill_style = FillOpaqueStippled; } else { gcValues.fill_style = FillStippled; } } newGC = Tk_GetGC(tkwin, gcMask, &gcValues); } if (epsPtr->fillGC != NULL) { Tk_FreeGC(Tk_Display(tkwin), epsPtr->fillGC); } epsPtr->fillGC = newGC; CloseEpsFile(epsPtr); ComputeEpsBbox(canvas, epsPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EpsCoords -- * * This procedure is invoked to process the "coords" widget command on * EPS items. See the user documentation for details on what it does. * * Results: * Returns TCL_OK or TCL_ERROR, and sets interp->result. * * Side effects: * The coordinates for the given item may be changed. * *--------------------------------------------------------------------------- */ static int EpsCoords( Tcl_Interp *interp, /* Used for error reporting. */ Tk_Canvas canvas, /* Canvas containing item. */ Tk_Item *itemPtr, /* Item whose coordinates are to be * read or modified. */ int argc, /* Number of coordinates supplied in * argv. */ char **argv) /* Array of coordinates: x1, y1, x2, * y2, ... */ { Eps *epsPtr = (Eps *)itemPtr; if ((argc != 0) && (argc != 2)) { Tcl_AppendResult(interp, "wrong # coordinates: expected 0 or 2, got ", Blt_Itoa(argc), (char *)NULL); return TCL_ERROR; } if (argc == 2) { double x, y; /* Don't overwrite old coordinates on * errors */ if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &x) != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1], &y) != TCL_OK)) { return TCL_ERROR; } epsPtr->x = x; epsPtr->y = y; ComputeEpsBbox(canvas, epsPtr); return TCL_OK; } Tcl_AppendElement(interp, Blt_Dtoa(interp, epsPtr->x)); Tcl_AppendElement(interp, Blt_Dtoa(interp, epsPtr->y)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ComputeEpsBbox -- * * This procedure is invoked to compute the bounding box of all the * pixels that may be drawn as part of a EPS item. This procedure is * where the preview image's placement is computed. * * Results: * None. * * Side effects: * The fields x1, y1, x2, and y2 are updated in the item for itemPtr. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ComputeEpsBbox( Tk_Canvas canvas, /* Canvas that contains item. */ Eps *epsPtr) /* Item whose bbox is to be * recomputed. */ { Point2d anchorPos; /* Translate the coordinates wrt the anchor. */ anchorPos = Blt_AnchorPoint(epsPtr->x, epsPtr->y, (double)epsPtr->width, (double)epsPtr->height, epsPtr->anchor); /* * Note: The right and bottom are exterior to the item. */ epsPtr->bb.left = anchorPos.x; epsPtr->bb.top = anchorPos.y; epsPtr->bb.right = epsPtr->bb.left + epsPtr->width; epsPtr->bb.bottom = epsPtr->bb.top + epsPtr->height; epsPtr->item.x1 = ROUND(epsPtr->bb.left); epsPtr->item.y1 = ROUND(epsPtr->bb.top); epsPtr->item.x2 = ROUND(epsPtr->bb.right); epsPtr->item.y2 = ROUND(epsPtr->bb.bottom); } /* *--------------------------------------------------------------------------- * * DisplayEps -- * * This procedure is invoked to draw the EPS item in a given drawable. * The EPS item may be drawn as either a solid rectangle or a pixmap of * the preview image. * * Results: * None. * * Side effects: * ItemPtr is drawn in drawable using the transformation information in * canvas. * *--------------------------------------------------------------------------- */ static void DisplayEps( Tk_Canvas canvas, /* Canvas that contains item. */ Tk_Item *itemPtr, /* Item to be displayed. */ Display *display, /* Display on which to draw item. */ Drawable drawable, /* Pixmap or window in which to draw * item. */ int rx, int ry, int rw, int rh) /* Describes region of canvas that * must be redisplayed (not used). */ { Blt_Picture picture; Eps *epsPtr = (Eps *)itemPtr; Tk_Window tkwin; const char *title; int w, h; short int dx, dy; w = (int)(epsPtr->bb.right - epsPtr->bb.left); h = (int)(epsPtr->bb.bottom - epsPtr->bb.top); if ((w < 1) || (h < 1)) { return; } tkwin = Tk_CanvasTkwin(canvas); if (epsPtr->original != NULL) { if ((epsPtr->lastWidth != w) || (epsPtr->lastHeight != h)) { if (epsPtr->quick) { picture = Blt_ScalePicture(epsPtr->original, 0, 0, Blt_PictureWidth(epsPtr->original), Blt_PictureHeight(epsPtr->original), w, h); } else { fprintf(stderr, "orig=%dx%d new=width=%dx%d last=%dx%d\n", Blt_PictureWidth(epsPtr->original), Blt_PictureHeight(epsPtr->original), w, h, epsPtr->lastWidth, epsPtr->lastHeight); picture = Blt_CreatePicture(w, h); Blt_ResamplePicture(picture, epsPtr->original, bltBoxFilter, bltBoxFilter); } if (epsPtr->picture != NULL) { Blt_FreePicture(epsPtr->picture); } epsPtr->picture = picture; epsPtr->lastHeight = h; epsPtr->lastWidth = w; } } picture = epsPtr->picture; if (picture == NULL) { picture = epsPtr->original; } /* * Translate the coordinates to those of the EPS item, then redisplay it. */ Tk_CanvasDrawableCoords(canvas, epsPtr->bb.left, epsPtr->bb.top, &dx, &dy); title = epsPtr->title; if (epsPtr->reqTitle != NULL) { title = epsPtr->reqTitle; } if ((epsPtr->showImage) && (picture != NULL)) { struct region { short int left, right, top, bottom; } p, r; short int destX, destY; /* The eps item may only partially exposed. Be careful to clip the * unexposed portions. */ /* Convert everything to screen coordinates since the origin of the * item is only available in */ p.left = dx, p.top = dy; Tk_CanvasDrawableCoords(canvas, epsPtr->bb.right, epsPtr->bb.bottom, &p.right, &p.bottom); Tk_CanvasDrawableCoords(canvas, (double)rx, (double)ry, &r.left, &r.top); Tk_CanvasDrawableCoords(canvas,(double)(rx+rw), (double)(ry+rh), &r.right, &r.bottom); destX = (int)dx, destY = (int)dy; if (p.left < r.left) { p.left = r.left; } if (p.top < r.top) { p.top = r.top; } if (p.right > r.right) { p.right = r.right; } if (p.bottom > r.bottom) { p.bottom = r.bottom; } if (destX < r.left) { destX = r.left; } if (destY < r.top) { destY = r.top; } p.left -= dx, p.right -= dx; p.top -= dy, p.bottom -= dy;; if (0 /* epsPtr->quick */) { Blt_Picture fade; fade = Blt_CreatePicture(Blt_PictureWidth(picture), Blt_PictureHeight(picture)); Blt_FadePicture(fade, picture, 0, 0, Blt_PictureWidth(picture), Blt_PictureHeight(picture), 0, 0, 150); Blt_PaintPicture(epsPtr->painter, drawable, fade, (int)p.left, (int)p.top, (int)(p.right - p.left), (int)(p.bottom - p.top), destX, destY, FALSE); Blt_FreePicture(fade); } else { Blt_PaintPicture(epsPtr->painter, drawable, picture, (int)p.left, (int)p.top, (int)(p.right - p.left), (int)(p.bottom - p.top), destX, destY, FALSE); } } else { if (epsPtr->fillGC != NULL) { XSetTSOrigin(display, epsPtr->fillGC, dx, dy); XFillRectangle(display, drawable, epsPtr->fillGC, dx, dy, epsPtr->width, epsPtr->height); XSetTSOrigin(display, epsPtr->fillGC, 0, 0); } } if (title != NULL) { TextLayout *textPtr; double rw, rh; int dw, dh; /* Translate the title to an anchor position within the EPS item */ epsPtr->titleStyle.font = epsPtr->font; textPtr = Blt_Ts_CreateLayout(title, -1, &epsPtr->titleStyle); Blt_GetBoundingBox(textPtr->width, textPtr->height, epsPtr->titleStyle.angle, &rw, &rh, (Point2d *)NULL); dw = (int)ceil(rw); dh = (int)ceil(rh); if ((dw <= w) && (dh <= h)) { int tx, ty; Blt_TranslateAnchor(dx, dy, w, h, epsPtr->titleStyle.anchor, &tx, &ty); if (picture == NULL) { tx += epsPtr->borderWidth; ty += epsPtr->borderWidth; } Blt_Ts_DrawLayout(tkwin, drawable, textPtr, &epsPtr->titleStyle, tx, ty); } Blt_Free(textPtr); } if ((picture == NULL) && (epsPtr->border != NULL) && (epsPtr->borderWidth > 0)) { Blt_Draw3DRectangle(tkwin, drawable, epsPtr->border, dx, dy, epsPtr->width, epsPtr->height, epsPtr->borderWidth, epsPtr->relief); } } /* *--------------------------------------------------------------------------- * * EpsToPoint -- * * Computes the distance from a given point to a given rectangle, in * canvas units. * * Results: * The return value is 0 if the point whose x and y coordinates are * coordPtr[0] and coordPtr[1] is inside the EPS item. If the point * isn't inside the item then the return value is the distance from the * point to the EPS item. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static double EpsToPoint( Tk_Canvas canvas, /* Canvas containing item. */ Tk_Item *itemPtr, /* Item to check against point. */ double *pts) /* Array of x and y coordinates. */ { Eps *epsPtr = (Eps *)itemPtr; double x, y, dx, dy; x = pts[0], y = pts[1]; /* * Check if point is outside the bounding rectangle and compute the * distance to the closest side. */ dx = dy = 0; if (x < epsPtr->item.x1) { dx = epsPtr->item.x1 - x; } else if (x > epsPtr->item.x2) { dx = x - epsPtr->item.x2; } if (y < epsPtr->item.y1) { dy = epsPtr->item.y1 - y; } else if (y > epsPtr->item.y2) { dy = y - epsPtr->item.y2; } return hypot(dx, dy); } /* *--------------------------------------------------------------------------- * * EpsToArea -- * * This procedure is called to determine whether an item lies entirely * inside, entirely outside, or overlapping a given rectangle. * * Results: * -1 is returned if the item is entirely outside the area given by * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given * area. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int EpsToArea( Tk_Canvas canvas, /* Canvas containing the item. */ Tk_Item *itemPtr, /* Item to check against bounding * rectangle. */ double pts[]) /* Array of four coordinates (x1, y1, * x2, y2) describing area. */ { Eps *epsPtr = (Eps *)itemPtr; if ((pts[2] <= epsPtr->bb.left) || (pts[0] >= epsPtr->bb.right) || (pts[3] <= epsPtr->bb.top) || (pts[1] >= epsPtr->bb.bottom)) { return -1; /* Outside. */ } if ((pts[0] <= epsPtr->bb.left) && (pts[1] <= epsPtr->bb.top) && (pts[2] >= epsPtr->bb.right) && (pts[3] >= epsPtr->bb.bottom)) { return 1; /* Inside. */ } return 0; /* Overlap. */ } /* *--------------------------------------------------------------------------- * * ScaleEps -- * * This procedure is invoked to rescale an item. * * Results: * None. * * Side effects: * The item referred to by itemPtr is rescaled so that the * following transformation is applied to all point coordinates: * x' = xOrigin + xScale*(x-xOrigin) * y' = yOrigin + yScale*(y-yOrigin) * *--------------------------------------------------------------------------- */ static void ScaleEps( Tk_Canvas canvas, /* Canvas containing rectangle. */ Tk_Item *itemPtr, /* Rectangle to be scaled. */ double xOrigin, double yOrigin, /* Origin wrt scale rect. */ double xScale, double yScale) { Eps *epsPtr = (Eps *)itemPtr; epsPtr->bb.left = xOrigin + xScale * (epsPtr->bb.left - xOrigin); epsPtr->bb.right = xOrigin + xScale * (epsPtr->bb.right - xOrigin); epsPtr->bb.top = yOrigin + yScale * (epsPtr->bb.top - yOrigin); epsPtr->bb.bottom = yOrigin + yScale *(epsPtr->bb.bottom - yOrigin); /* Reset the user-requested values to the newly scaled values. */ epsPtr->width = ROUND(epsPtr->bb.right - epsPtr->bb.left); epsPtr->height = ROUND(epsPtr->bb.bottom - epsPtr->bb.top); epsPtr->x = ROUND(epsPtr->bb.left); epsPtr->y = ROUND(epsPtr->bb.top); epsPtr->item.x1 = ROUND(epsPtr->bb.left); epsPtr->item.y1 = ROUND(epsPtr->bb.top); epsPtr->item.x2 = ROUND(epsPtr->bb.right); epsPtr->item.y2 = ROUND(epsPtr->bb.bottom); } /* *--------------------------------------------------------------------------- * * TranslateEps -- * * This procedure is called to move an item by a given amount. * * Results: * None. * * Side effects: * The position of the item is offset by (dx, dy), and the bounding box * is updated in the generic part of the item structure. * *--------------------------------------------------------------------------- */ static void TranslateEps( Tk_Canvas canvas, /* Canvas containing item. */ Tk_Item *itemPtr, /* Item that is being moved. */ double dx, double dy) /* Amount by which item is to be * moved. */ { Eps *epsPtr = (Eps *)itemPtr; epsPtr->bb.left += dx; epsPtr->bb.right += dx; epsPtr->bb.top += dy; epsPtr->bb.bottom += dy; epsPtr->x = epsPtr->bb.left; epsPtr->y = epsPtr->bb.top; epsPtr->item.x1 = ROUND(epsPtr->bb.left); epsPtr->item.x2 = ROUND(epsPtr->bb.right); epsPtr->item.y1 = ROUND(epsPtr->bb.top); epsPtr->item.y2 = ROUND(epsPtr->bb.bottom); } /* *--------------------------------------------------------------------------- * * EpsToPostScript -- * * This procedure is called to generate PostScript for EPS canvas items. * * Results: * The return value is a standard TCL result. If an error occurs in * generating PostScript then an error message is left in interp->result, * replacing whatever used to be there. If no errors occur, then * PostScript output for the item is appended to the interpreter result. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int EpsToPostScript( Tcl_Interp *interp, /* Interpreter to hold generated * PostScript or reports errors back * to. */ Tk_Canvas canvas, /* Information about overall * canvas. */ Tk_Item *itemPtr, /* eps item. */ int prepass) /* If 1, this is a prepass to collect * font information; 0 means final * * PostScript is being created. */ { Eps *epsPtr = (Eps *)itemPtr; Blt_Ps ps; double xScale, yScale; double x, y, w, h; PageSetup setup; if (prepass) { return TCL_OK; /* Don't worry about fonts. */ } memset(&setup, 0, sizeof(setup)); ps = Blt_Ps_Create(interp, &setup); /* Lower left corner of item on page. */ x = epsPtr->bb.left; y = Tk_CanvasPsY(canvas, epsPtr->bb.bottom); w = epsPtr->bb.right - epsPtr->bb.left; h = epsPtr->bb.bottom - epsPtr->bb.top; if (epsPtr->fileName == NULL) { /* No PostScript file, generate PostScript of resized image instead. */ if (epsPtr->picture != NULL) { Blt_Ps_Format(ps, "gsave\n"); /* * First flip the PostScript y-coordinate axis so that the origin * is the upper-left corner like our picture. */ Blt_Ps_Format(ps, " %g %g translate\n", x, y + h); Blt_Ps_Format(ps, " 1 -1 scale\n"); Blt_Ps_DrawPicture(ps, epsPtr->picture, 0.0, 0.0); Blt_Ps_Format(ps, "grestore\n"); Blt_Ps_SetInterp(ps, interp); Blt_Ps_Free(ps); } return TCL_OK; } /* Copy in the PostScript prolog for EPS encapsulation. */ if (Blt_Ps_IncludeFile(interp, ps, "bltCanvEps.pro") != TCL_OK) { goto error; } Blt_Ps_Append(ps, "BeginEPSF\n"); xScale = w / (double)(epsPtr->urx - epsPtr->llx); yScale = h / (double)(epsPtr->ury - epsPtr->lly); /* Set up scaling and translation transformations for the EPS item */ Blt_Ps_Format(ps, "%g %g translate\n", x, y); Blt_Ps_Format(ps, "%g %g scale\n", xScale, yScale); Blt_Ps_Format(ps, "%d %d translate\n", -(epsPtr->llx), -(epsPtr->lly)); /* FIXME: Why clip against the old bounding box? */ Blt_Ps_Format(ps, "%d %d %d %d SetClipRegion\n", epsPtr->llx, epsPtr->lly, epsPtr->urx, epsPtr->ury); Blt_Ps_VarAppend(ps, "%% including \"", epsPtr->fileName, "\"\n\n", (char *)NULL); Blt_Ps_AppendBytes(ps, Tcl_DStringValue(&epsPtr->dString), Tcl_DStringLength(&epsPtr->dString)); Blt_Ps_Append(ps, "EndEPSF\n"); Blt_Ps_SetInterp(ps, interp); Blt_Ps_Free(ps); return TCL_OK; error: Blt_Ps_Free(ps); return TCL_ERROR; } /* * The structures below defines the EPS item type in terms of procedures that * can be invoked by generic item code. */ static Tk_ItemType itemType = { (char *)"eps", /* name */ sizeof(Eps), /* itemSize */ CreateEps, /* createProc */ configSpecs, /* configSpecs */ ConfigureEps, /* configureProc */ EpsCoords, /* coordProc */ DeleteEps, /* deleteProc */ DisplayEps, /* displayProc */ 0, /* alwaysRedraw */ EpsToPoint, /* pointProc */ EpsToArea, /* areaProc */ EpsToPostScript, /* postscriptProc */ ScaleEps, /* scaleProc */ TranslateEps, /* translateProc */ (Tk_ItemIndexProc *)NULL, /* indexProc */ (Tk_ItemCursorProc *)NULL, /* icursorProc */ (Tk_ItemSelectionProc *)NULL, /* selectionProc */ (Tk_ItemInsertProc *)NULL, /* insertProc */ (Tk_ItemDCharsProc *)NULL, /* dTextProc */ (Tk_ItemType *)NULL /* nextPtr */ }; /*ARGSUSED*/ void Blt_RegisterEpsCanvasItem(void) { Tk_CreateItemType(&itemType); /* Initialize custom canvas option routines. */ tagsOption.parseProc = Tk_CanvasTagsParseProc; tagsOption.printProc = Tk_CanvasTagsPrintProc; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinPrnt.c������������������������������������������������������������������0000644�0001750�0001750�00000136520�11462120063�015304� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinPrnt.c -- * * This module implements Win32 printer access. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <bltInt.h> #include "bltOp.h" #include <bltHash.h> #ifndef NO_PRINTER #include <X11/Xutil.h> #undef Status #if defined(_MSC_VER) || defined(__BORLANDC__) #include <winspool.h> #endif /* _MSC_VER || __BORLANDC__ */ #include "tkDisplay.h" /* set pid [printer open name] printer close $pid printer write $pid $data printer snap $pid .window printer names printer enum things printer getattr $pid printer setattr $pid set pid [open ] blt::printer open {\\alprint\2a211} p1 p1 getattr varName p1 setattr varName p1 write $data .graph print p1 p1 snap .window p1 close blt::printer names blt::printer emum things */ #define PRINTER_THREAD_KEY "BLT Printer Data" #ifdef notdef #define DM_SPECVERSION 0x0401 #define DMPAPER_ISO_B4 42 /* B4 (ISO) 250 x 353 mm */ #define DMPAPER_JAPANESE_POSTCARD 43 /* Japanese Postcard 100 x 148 mm */ #define DMPAPER_9X11 44 /* 9 x 11 in */ #define DMPAPER_10X11 45 /* 10 x 11 in */ #define DMPAPER_15X11 46 /* 15 x 11 in */ #define DMPAPER_ENV_INVITE 47 /* Envelope Invite 220 x 220 mm */ #define DMPAPER_RESERVED_48 48 /* RESERVED--DO NOT USE */ #define DMPAPER_RESERVED_49 49 /* RESERVED--DO NOT USE */ #define DMPAPER_LETTER_EXTRA 50 /* Letter Extra 9 \275 x 12 in */ #define DMPAPER_LEGAL_EXTRA 51 /* Legal Extra 9 \275 x 15 in */ #define DMPAPER_TABLOID_EXTRA 52 /* Tabloid Extra 11.69 x 18 in */ #define DMPAPER_A4_EXTRA 53 /* A4 Extra 9.27 x 12.69 in */ #define DMPAPER_LETTER_TRANSVERSE 54 /* Letter Transverse 8 \275 x 11 in */ #define DMPAPER_A4_TRANSVERSE 55 /* A4 Transverse 210 x 297 mm */ #define DMPAPER_LETTER_EXTRA_TRANSVERSE 56 /* Letter Extra Transverse 9\275 x 12 in */ #define DMPAPER_A_PLUS 57 /* SuperA/SuperA/A4 227 x 356 mm */ #define DMPAPER_B_PLUS 58 /* SuperB/SuperB/A3 305 x 487 mm */ #define DMPAPER_LETTER_PLUS 59 /* Letter Plus 8.5 x 12.69 in */ #define DMPAPER_A4_PLUS 60 /* A4 Plus 210 x 330 mm */ #define DMPAPER_A5_TRANSVERSE 61 /* A5 Transverse 148 x 210 mm */ #define DMPAPER_B5_TRANSVERSE 62 /* B5 (JIS) Transverse 182 x 257 mm */ #define DMPAPER_A3_EXTRA 63 /* A3 Extra 322 x 445 mm */ #define DMPAPER_A5_EXTRA 64 /* A5 Extra 174 x 235 mm */ #define DMPAPER_B5_EXTRA 65 /* B5 (ISO) Extra 201 x 276 mm */ #define DMPAPER_A2 66 /* A2 420 x 594 mm */ #define DMPAPER_A3_TRANSVERSE 67 /* A3 Transverse 297 x 420 mm */ #define DMPAPER_A3_EXTRA_TRANSVERSE 68 /* A3 Extra Transverse 322 x 445 mm */ #ifndef DMPAPER_LAST #define DMPAPER_LAST DMPAPER_A3_EXTRA_TRANSVERSE #endif /*DMPAPER_LAST */ #define DMPAPER_USER 256 /* bin selections */ #ifndef DMPAPER_FIRST #define DMBIN_FIRST DMBIN_UPPER #endif /*DMPAPER_FIRST*/ #define DMBIN_UPPER 1 #define DMBIN_ONLYONE 1 #define DMBIN_LOWER 2 #define DMBIN_MIDDLE 3 #define DMBIN_MANUAL 4 #define DMBIN_ENVELOPE 5 #define DMBIN_ENVMANUAL 6 #define DMBIN_AUTO 7 #define DMBIN_TRACTOR 8 #define DMBIN_SMALLFMT 9 #define DMBIN_LARGEFMT 10 #define DMBIN_LARGECAPACITY 11 #define DMBIN_CASSETTE 14 #define DMBIN_FORMSOURCE 15 #ifndef DMBIN_LAST #define DMBIN_LAST DMBIN_FORMSOURCE #endif /*DMBIN_LAST*/ #define DMBIN_USER 256 /* device specific bins start here */ /* print qualities */ #define DMRES_DRAFT (-1) #define DMRES_LOW (-2) #define DMRES_MEDIUM (-3) #define DMRES_HIGH (-4) #define DMTT_DOWNLOAD_OUTLINE 4 /* download TT fonts as outline soft fonts */ #endif /* DM */ typedef struct { Blt_HashTable printerTable; /* Hash table of printer structures keyed by * the name of the printer. */ int nextId; } PrinterInterpData; typedef struct { int type; HDC hDC; } PrintDrawable; typedef struct { Tcl_Interp *interp; Tcl_Command cmdToken; /* Token for vector's TCL command. */ char *name; char *fileName; PrintDrawable drawable; HANDLE hPrinter; Blt_HashEntry *hashPtr; Blt_HashTable *tablePtr; char *driverName; char *deviceName; char *printerName; char *docName; char *portName; DEVMODE *dmPtr; int dmSize; } PrinterQueue; typedef struct { DWORD token; const char *string; } TokenString; static TokenString sizeTable[] = { /* Letter 8 1/2 x 11 in */ { DMPAPER_LETTER, "Letter" }, /* Letter Small 8 1/2 x 11 in */ { DMPAPER_LETTERSMALL, "Letter Small" }, /* Tabloid 11 x 17 in */ { DMPAPER_TABLOID, "Tabloid" }, /* Ledger 17 x 11 in */ { DMPAPER_LEDGER, "Ledger" }, /* Legal 8 1/2 x 14 in */ { DMPAPER_LEGAL, "Legal" }, /* Statement 5 1/2 x 8 1/2 in */ { DMPAPER_STATEMENT, "Statement" }, /* Executive 7 1/4 x 10 1/2 in */ { DMPAPER_EXECUTIVE, "Executive" }, /* A3 297 x 420 mm */ { DMPAPER_A3, "A3" }, /* A4 210 x 297 mm */ { DMPAPER_A4, "A4" }, /* A4 Small 210 x 297 mm */ { DMPAPER_A4SMALL, "A4 Small" }, /* A5 148 x 210 mm */ { DMPAPER_A5, "A5" }, /* B4 (JIS) 250 x 354 */ { DMPAPER_B4, "B4 (JIS)" }, /* B5 (JIS) 182 x 257 mm */ { DMPAPER_B5, "B5 (JIS)" }, /* Folio 8 1/2 x 13 in */ { DMPAPER_FOLIO, "Folio" }, /* Quarto 215 x 275 mm */ { DMPAPER_QUARTO, "Quarto" }, /* 10x14 in */ { DMPAPER_10X14, "10x14" }, /* 11x17 in */ { DMPAPER_11X17, "11x17" }, /* Note 8 1/2 x 11 in */ { DMPAPER_NOTE, "Note" }, /* Envelope #9 3 7/8 x 8 7/8 */ { DMPAPER_ENV_9, "Envelope #9" }, /* Envelope #10 4 1/8 x 9 1/2 */ { DMPAPER_ENV_10, "Envelope #10" }, /* Envelope #11 4 1/2 x 10 3/8 */ { DMPAPER_ENV_11, "Envelope #11" }, /* Envelope #12 4 \276 x 11 */ { DMPAPER_ENV_12, "Envelope #12" }, /* Envelope #14 5 x 11 1/2 */ { DMPAPER_ENV_14, "Envelope #14" }, /* C size sheet */ { DMPAPER_CSHEET, "C size sheet" }, /* D size sheet */ { DMPAPER_DSHEET, "D size sheet" }, /* E size sheet */ { DMPAPER_ESHEET, "E size sheet" }, /* Envelope DL 110 x 220mm */ { DMPAPER_ENV_DL, "Envelope DL" }, /* Envelope C5 162 x 229 mm */ { DMPAPER_ENV_C5, "Envelope C5" }, /* Envelope C3 324 x 458 mm */ { DMPAPER_ENV_C3, "Envelope C3" }, /* Envelope C4 229 x 324 mm */ { DMPAPER_ENV_C4, "Envelope C4" }, /* Envelope C6 114 x 162 mm */ { DMPAPER_ENV_C6, "Envelope C6" }, /* Envelope C65 114 x 229 mm */ { DMPAPER_ENV_C65, "Envelope C65" }, /* Envelope B4 250 x 353 mm */ { DMPAPER_ENV_B4, "Envelope B4" }, /* Envelope B5 176 x 250 mm */ { DMPAPER_ENV_B5, "Envelope B5" }, /* Envelope B6 176 x 125 mm */ { DMPAPER_ENV_B6, "Envelope B6" }, /* Envelope 110 x 230 mm */ { DMPAPER_ENV_ITALY, "Envelope Italy" }, /* Env Monarch 3 7/8 x 7 1/2 in */ { DMPAPER_ENV_MONARCH, "Envelope Monarch" }, /* 6 3/4 Envelope 3 5/8 x 6 1/2 in */ { DMPAPER_ENV_PERSONAL, "6 3/4 Envelope" }, /* US Std Fanfold 14 7/8 x 11 in */ { DMPAPER_FANFOLD_US, "US Std Fanfold" }, /* German Std Fanfold 8 1/2 x 12 in */ { DMPAPER_FANFOLD_STD_GERMAN, "German Std Fanfold" }, /* German Legal Fanfold 8 1/2 x 13 in */ { DMPAPER_FANFOLD_LGL_GERMAN, "German Legal Fanfold" }, /* B4 (ISO) 250 x 353 mm */ { DMPAPER_ISO_B4, "ISOB4" }, /* Japanese Postcard 100 x 148 mm */ { DMPAPER_JAPANESE_POSTCARD, "Postcard (JIS)" }, /* 9 x 11 in */ { DMPAPER_9X11, "9x11" }, /* 10 x 11 in */ { DMPAPER_10X11, "10x11" }, /* 15 x 11 in */ { DMPAPER_15X11, "15x11" }, /* Envelope Invite 220 x 220 mm */ { DMPAPER_ENV_INVITE, "Envelope Invite" }, /* Letter Extra 9 \275 x 12 in */ { DMPAPER_LETTER_EXTRA, "Letter Extra" }, /* Legal Extra 9 \275 x 15 in */ { DMPAPER_LEGAL_EXTRA, "Legal Extra" }, /* Tabloid Extra 11.69 x 18 in */ { DMPAPER_TABLOID_EXTRA, "Tabloid Extra" }, /* A4 Extra 9.27 x 12.69 in */ { DMPAPER_A4_EXTRA, "A4 Extra" }, /* Letter Transverse 8 \275 x 11 in */ { DMPAPER_LETTER_TRANSVERSE, "Letter Transverse" }, /* A4 Transverse 210 x 297 mm */ { DMPAPER_A4_TRANSVERSE, "A4 Transverse" }, /* Letter Extra Transverse 9\275 x 12 in */ { DMPAPER_LETTER_EXTRA_TRANSVERSE, "Letter Extra Transverse" }, /* SuperA/SuperA/A4 227 x 356 mm */ { DMPAPER_A_PLUS, "Super A Plus" }, /* SuperB/SuperB/A3 305 x 487 mm */ { DMPAPER_B_PLUS, "Super B Plus" }, /* Letter Plus 8.5 x 12.69 in */ { DMPAPER_LETTER_PLUS, "Letter Plus" }, /* A4 Plus 210 x 330 mm */ { DMPAPER_A4_PLUS, "A4 Plus" }, /* A5 Transverse 148 x 210 mm */ { DMPAPER_A5_TRANSVERSE, "A5 Transverse" }, /* B5 (JIS) Transverse 182 x 257 mm */ { DMPAPER_B5_TRANSVERSE, "B5 Transverse" }, /* A3 Extra 322 x 445 mm */ { DMPAPER_A3_EXTRA, "A3 Extra" }, /* A5 Extra 174 x 235 mm */ { DMPAPER_A5_EXTRA, "A5 Extra" }, /* B5 (ISO) Extra 201 x 276 mm */ { DMPAPER_B5_EXTRA, "B5 Extra" }, /* A2 420 x 594 mm */ { DMPAPER_A2, "A2" }, /* A3 Transverse 297 x 420 mm */ { DMPAPER_A3_TRANSVERSE, "A3 Transverse" }, /* A3 Extra Transverse 322 x 445 mm */ { DMPAPER_A3_EXTRA_TRANSVERSE, "A3 Extra Transverse" }, { 0, NULL } }; static TokenString statusTable[] = { { PRINTER_STATUS_BUSY, "Busy" }, { PRINTER_STATUS_DOOR_OPEN, "Door Open" }, { PRINTER_STATUS_ERROR, "Error" }, { PRINTER_STATUS_INITIALIZING, "Initializing" }, { PRINTER_STATUS_IO_ACTIVE, "IO Active" }, { PRINTER_STATUS_MANUAL_FEED, "Manual Feed" }, { PRINTER_STATUS_NOT_AVAILABLE, "Not Available" }, { PRINTER_STATUS_NO_TONER, "No Toner" }, { PRINTER_STATUS_OFFLINE, "Offline" }, { PRINTER_STATUS_OUTPUT_BIN_FULL, "Bin Full" }, { PRINTER_STATUS_OUT_OF_MEMORY, "Out Of Memory" }, { PRINTER_STATUS_PAGE_PUNT, "Page Punt" }, { PRINTER_STATUS_PAPER_JAM, "Paper Jam" }, { PRINTER_STATUS_PAPER_OUT, "Paper Out" }, { PRINTER_STATUS_PAPER_PROBLEM, "Paper Problem" }, { PRINTER_STATUS_PAUSED, "Paused" }, { PRINTER_STATUS_PENDING_DELETION, "Pending Deletion" }, { PRINTER_STATUS_POWER_SAVE, "Power Save" }, { PRINTER_STATUS_PRINTING, "Printing" }, { PRINTER_STATUS_PROCESSING, "Processing" }, { PRINTER_STATUS_SERVER_UNKNOWN, "Server Unknown" }, { PRINTER_STATUS_TONER_LOW, "Toner Low" }, { PRINTER_STATUS_USER_INTERVENTION, "User Intervention" }, { PRINTER_STATUS_WAITING, "Waiting" }, { PRINTER_STATUS_WARMING_UP, "Warming Up" }, { 0, NULL } }; static TokenString attributeTable[] = { { PRINTER_ATTRIBUTE_DEFAULT, "Default" }, { PRINTER_ATTRIBUTE_DIRECT, "Direct" }, { PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST, "Do Complete First" }, { PRINTER_ATTRIBUTE_ENABLE_BIDI, "Enable BIDI" }, { PRINTER_ATTRIBUTE_ENABLE_DEVQ, "Enable Devq" }, { PRINTER_ATTRIBUTE_HIDDEN, "Hidden" }, { PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS, "Keep Printed Jobs" }, { PRINTER_ATTRIBUTE_LOCAL, "Local" }, { PRINTER_ATTRIBUTE_NETWORK, "Network" }, { PRINTER_ATTRIBUTE_QUEUED, "Queued" }, { PRINTER_ATTRIBUTE_RAW_ONLY, "Raw Only" }, { PRINTER_ATTRIBUTE_SHARED, "Shared" }, { PRINTER_ATTRIBUTE_WORK_OFFLINE, "Offline" }, { 0, NULL } }; static TokenString binTable[] = { { DMBIN_UPPER, "Upper" }, { DMBIN_LOWER, "Lower" }, { DMBIN_MIDDLE, "Middle" }, { DMBIN_MANUAL, "Manual" }, { DMBIN_ENVELOPE, "Envelope" }, { DMBIN_ENVMANUAL, "Envelope Manual" }, { DMBIN_AUTO, "Automatic" }, { DMBIN_TRACTOR, "Tractor" }, { DMBIN_SMALLFMT, "Small Format" }, { DMBIN_LARGEFMT, "Large Format" }, { DMBIN_LARGECAPACITY, "Large Capacity" }, { DMBIN_CASSETTE, "Cassette" }, { DMBIN_FORMSOURCE, "Form Source" }, { 0, NULL } }; static TokenString orientationTable[] = { { DMORIENT_PORTRAIT, "Portrait" }, { DMORIENT_LANDSCAPE, "Landscape" }, { 0, NULL } }; static TokenString qualityTable[] = { { DMRES_HIGH, "High" }, { DMRES_MEDIUM, "Medium" }, { DMRES_LOW, "Low" }, { DMRES_DRAFT, "Draft" }, { 0, NULL } }; static TokenString colorTable[] = { { DMCOLOR_COLOR, "Color" }, { DMCOLOR_MONOCHROME, "Monochrome" }, { 0, NULL } }; static TokenString duplexTable[] = { { DMDUP_SIMPLEX, "Simplex" }, { DMDUP_HORIZONTAL, "Horizontal" }, { DMDUP_VERTICAL, "Vertical" }, { 0, NULL } }; static TokenString ttOptionTable[] = { { DMTT_BITMAP, "Bitmap" }, { DMTT_DOWNLOAD, "Download" }, { DMTT_SUBDEV, "Substitute Device" }, { DMTT_DOWNLOAD_OUTLINE, "Download Outline" }, { 0, NULL } }; static Tcl_ObjCmdProc PrinterCmd; static Tcl_InterpDeleteProc PrinterInterpDeleteProc; void Blt_GetPrinterScale(HDC printerDC, double *xRatioPtr, double *yRatioPtr) { double xScreen, yScreen; double xPrinter, yPrinter; HDC screenDC; xPrinter = (double)GetDeviceCaps(printerDC, LOGPIXELSX); yPrinter = (double)GetDeviceCaps(printerDC, LOGPIXELSY); screenDC = GetDC(NULL); xScreen = (double)GetDeviceCaps(screenDC, LOGPIXELSX); yScreen = (double)GetDeviceCaps(screenDC, LOGPIXELSY); ReleaseDC(NULL, screenDC); *xRatioPtr = (xPrinter / xScreen); *yRatioPtr = (yPrinter / yScreen); } static PrinterInterpData * GetPrinterInterpData(Tcl_Interp *interp) { PrinterInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (PrinterInterpData *) Tcl_GetAssocData(interp, PRINTER_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(PrinterInterpData)); dataPtr->nextId = 0; Tcl_SetAssocData(interp, PRINTER_THREAD_KEY, PrinterInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->printerTable, BLT_STRING_KEYS); } return dataPtr; } static int GetQueue( Tcl_Interp *interp, const char *name, PrinterQueue **queuePtrPtr) { Blt_HashEntry *hPtr; PrinterInterpData *dataPtr; dataPtr = GetPrinterInterpData(interp); hPtr = Blt_FindHashEntry(&dataPtr->printerTable, name); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find printer \"", name, "\"", (char *)NULL); return TCL_ERROR; } *queuePtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } static int GetQueueFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, PrinterQueue **queuePtrPtr) { return GetQueue(interp, Tcl_GetString(objPtr), queuePtrPtr); } static void CloseQueue( PrinterQueue *queuePtr) { ClosePrinter(queuePtr->hPrinter); queuePtr->hPrinter = NULL; } static int OpenQueue( Tcl_Interp *interp, PrinterQueue *queuePtr) { PRINTER_DEFAULTS pd; HANDLE hPrinter; ZeroMemory(&pd, sizeof(pd)); pd.DesiredAccess = PRINTER_ALL_ACCESS; if (!OpenPrinter(queuePtr->printerName, &hPrinter, &pd)) { Tcl_AppendResult(interp, "can't open printer \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); queuePtr->hPrinter = NULL; return TCL_ERROR; } queuePtr->hPrinter = hPrinter; return TCL_OK; } static HGLOBAL GetQueueProperties( PrinterQueue *queuePtr, DEVMODE **dmPtrPtr) { HWND hWnd; unsigned int dmSize; HGLOBAL hMem; DEVMODE *dmPtr; hWnd = GetDesktopWindow(); dmSize = DocumentProperties(hWnd, queuePtr->hPrinter, queuePtr->printerName, NULL, NULL, 0); if (dmSize == 0) { Tcl_AppendResult(queuePtr->interp, "can't get document properties for \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); return NULL; } hMem = GlobalAlloc(GHND, dmSize); dmPtr = (DEVMODE *)GlobalLock(hMem); if (!DocumentProperties(hWnd, queuePtr->hPrinter, queuePtr->printerName, dmPtr, NULL, DM_OUT_BUFFER)) { Tcl_AppendResult(queuePtr->interp, "can't allocate document properties for \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); GlobalUnlock(hMem); GlobalFree(hMem); return NULL; } *dmPtrPtr = dmPtr; queuePtr->dmSize = dmSize; return hMem; } static int SetQueueProperties( Tcl_Interp *interp, PrinterQueue *queuePtr, DEVMODE *dmPtr) { HWND hWnd; int result; hWnd = GetDesktopWindow(); result = DocumentProperties(hWnd, queuePtr->hPrinter, queuePtr->printerName, dmPtr, dmPtr, DM_IN_BUFFER | DM_OUT_BUFFER); if (result == 0) { Tcl_AppendResult(interp, "can't set document properties for \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } if (queuePtr->dmPtr != NULL) { Blt_Free(queuePtr->dmPtr); } queuePtr->dmPtr = Blt_AssertMalloc(queuePtr->dmSize); *queuePtr->dmPtr = *dmPtr; return TCL_OK; } static void DestroyQueue(PrinterQueue *queuePtr) { if (queuePtr->drawable.hDC != NULL) { DeleteDC(queuePtr->drawable.hDC); } if (queuePtr->printerName != NULL) { Blt_Free(queuePtr->printerName); } if (queuePtr->deviceName != NULL) { Blt_Free(queuePtr->deviceName); } if (queuePtr->portName != NULL) { Blt_Free(queuePtr->portName); } if (queuePtr->driverName != NULL) { Blt_Free(queuePtr->driverName); } if (queuePtr->hashPtr != NULL) { Blt_DeleteHashEntry(queuePtr->tablePtr, queuePtr->hashPtr); } if (queuePtr->dmPtr != NULL) { Blt_Free(queuePtr->dmPtr); } Blt_Free(queuePtr); } static char * AttributesToString(DWORD attributes, Tcl_DString * resultPtr) { TokenString *p; Tcl_DStringInit(resultPtr); for (p = attributeTable; p->string != NULL; p++) { if (attributes & p->token) { Tcl_DStringAppendElement(resultPtr, p->string); } } return Tcl_DStringValue(resultPtr); } static char * StatusToString(DWORD status, Tcl_DString * resultPtr) { TokenString *p; Tcl_DStringInit(resultPtr); for (p = statusTable; p->string != NULL; p++) { if (status & p->token) { Tcl_DStringAppendElement(resultPtr, p->string); } } return Tcl_DStringValue(resultPtr); } static const char * TokenToString(TokenString *table, DWORD token) { TokenString *p; for (p = table; p->string != NULL; p++) { if (token == p->token) { return p->string; } } return "???"; } static DWORD StringToToken(TokenString * table, char *string) { TokenString *p; char c; c = toupper(string[0]); for (p = table; p->string != NULL; p++) { if ((c == toupper(p->string[0])) && (strcasecmp(string, p->string) == 0)) { return p->token; } } return 0; } static void GetFormInfo( Tcl_Interp *interp, FORM_INFO_1 * infoArr, int nForms, const char *varName) { Tcl_DString dString; int i; Tcl_DStringInit(&dString); for (i = 0; i < nForms; i++) { Tcl_DStringAppendElement(&dString, infoArr[i].pName); } Tcl_SetVar2(interp, varName, "EnumForms", Tcl_DStringValue(&dString), TCL_LEAVE_ERR_MSG); Tcl_DStringFree(&dString); } static int GetPrinterAttributes( Tcl_Interp *interp, /* Interpreter context. */ PrinterQueue *queuePtr, Tcl_Obj *objPtr) /* Name of array variable to contain * printer device information. */ { const char *string; Tcl_DString dString; DEVMODE *dmPtr; DWORD bytesNeeded; HGLOBAL hMem1, hMem2; PRINTER_INFO_2* pi2Ptr; LPVOID buffer; int result = TCL_ERROR; const char *varName; if (OpenQueue(interp, queuePtr) != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&dString); hMem2 = NULL; GetPrinter(queuePtr->hPrinter, 2, NULL, 0, &bytesNeeded); /* Windows 95/98 seems to only want locked memory. Allocating * unlocked memory will sometimes crash the printer driver and * therefore Windows itself. */ hMem1 = GlobalAlloc(GHND, bytesNeeded); if (hMem1 == NULL) { Tcl_AppendResult(interp, "can't allocate memory for printer \"", queuePtr->name, "\": ", Blt_LastError(), (char *)NULL); goto error; } buffer = (LPVOID)GlobalLock(hMem1); if (!GetPrinter(queuePtr->hPrinter, 2, buffer, bytesNeeded, &bytesNeeded)) { Tcl_AppendResult(interp, "can't get printer \"", queuePtr->name, "\": ", Blt_LastError(), (char *)NULL); goto error; } hMem2 = GetQueueProperties(queuePtr, &dmPtr); if (hMem2 == NULL) { Tcl_AppendResult(interp, "can't allocate memory for printer \"", queuePtr->name, "\" properties: ", Blt_LastError(), (char *)NULL); goto error; } pi2Ptr = (PRINTER_INFO_2 *)buffer; varName = Tcl_GetString(objPtr); Tcl_SetVar2(interp, varName, "ServerName", pi2Ptr->pServerName, 0); Tcl_SetVar2(interp, varName, "PrinterName", pi2Ptr->pPrinterName, 0); Tcl_SetVar2(interp, varName, "PortName", pi2Ptr->pPortName, 0); Tcl_SetVar2(interp, varName, "DriverName", pi2Ptr->pDriverName, 0); Tcl_SetVar2(interp, varName, "Comment", pi2Ptr->pComment, 0); Tcl_SetVar2(interp, varName, "Location", pi2Ptr->pLocation, 0); Tcl_SetVar2(interp, varName, "SepFile", pi2Ptr->pSepFile, 0); Tcl_SetVar2(interp, varName, "PrintProcessor", pi2Ptr->pPrintProcessor, 0); Tcl_SetVar2(interp, varName, "Datatype", pi2Ptr->pDatatype, 0); Tcl_SetVar2(interp, varName, "Parameters", pi2Ptr->pParameters, 0); Tcl_SetVar2(interp, varName, "Attributes", AttributesToString(pi2Ptr->Attributes, &dString), 0); Tcl_SetVar2(interp, varName, "Priority", Blt_Itoa(pi2Ptr->Priority), 0); Tcl_SetVar2(interp, varName, "DefaultPriority", Blt_Itoa(pi2Ptr->DefaultPriority), 0); Tcl_SetVar2(interp, varName, "StartTime", Blt_Itoa(pi2Ptr->StartTime), 0); Tcl_SetVar2(interp, varName, "UntilTime", Blt_Itoa(pi2Ptr->UntilTime), 0); Tcl_SetVar2(interp, varName, "Status", StatusToString(pi2Ptr->Status, &dString), 0); Tcl_SetVar2(interp, varName, "Jobs", Blt_Itoa(pi2Ptr->cJobs), 0); Tcl_SetVar2(interp, varName, "AveragePPM", Blt_Itoa(pi2Ptr->AveragePPM), 0); if (dmPtr->dmFields & DM_ORIENTATION) { Tcl_SetVar2(interp, varName, "Orientation", TokenToString(orientationTable, dmPtr->dmOrientation), 0); } if (dmPtr->dmFields & DM_PAPERSIZE) { Tcl_SetVar2(interp, varName, "PaperSize", TokenToString(sizeTable, dmPtr->dmPaperSize), 0); } if (dmPtr->dmFields & DM_PAPERWIDTH) { Tcl_SetVar2(interp, varName, "PaperWidth", Blt_Itoa(dmPtr->dmPaperWidth), 0); } if (dmPtr->dmFields & DM_PAPERLENGTH) { Tcl_SetVar2(interp, varName, "PaperLength", Blt_Itoa(dmPtr->dmPaperLength), 0); } if (dmPtr->dmFields & DM_SCALE) { Tcl_SetVar2(interp, varName, "Scale", Blt_Itoa(dmPtr->dmScale), 0); } if (dmPtr->dmFields & DM_COPIES) { Tcl_SetVar2(interp, varName, "Copies", Blt_Itoa(dmPtr->dmCopies), 0); } if (dmPtr->dmFields & DM_DEFAULTSOURCE) { Tcl_SetVar2(interp, varName, "DefaultSource", TokenToString(binTable, dmPtr->dmDefaultSource), 0); } if (dmPtr->dmFields & DM_PRINTQUALITY) { if (dmPtr->dmPrintQuality < 0) { string = TokenToString(qualityTable, dmPtr->dmPrintQuality); } else { string = Blt_Itoa(dmPtr->dmPrintQuality); } Tcl_SetVar2(interp, varName, "PrintQuality", string, 0); } if (dmPtr->dmFields & DM_COLOR) { Tcl_SetVar2(interp, varName, "Color", TokenToString(colorTable, dmPtr->dmColor), 0); } if (dmPtr->dmFields & DM_DUPLEX) { Tcl_SetVar2(interp, varName, "Duplex", TokenToString(duplexTable, dmPtr->dmDuplex), 0); } if (dmPtr->dmFields & DM_YRESOLUTION) { Tcl_SetVar2(interp, varName, "YResolution", Blt_Itoa(dmPtr->dmYResolution), 0); } if (dmPtr->dmFields & DM_TTOPTION) { Tcl_SetVar2(interp, varName, "TTOption", TokenToString(ttOptionTable, dmPtr->dmTTOption), 0); } if (dmPtr->dmFields & DM_COLLATE) { if (dmPtr->dmCollate == DMCOLLATE_TRUE) { string = "true"; } else if (dmPtr->dmCollate == DMCOLLATE_FALSE) { string = "false"; } else { string = "???"; } Tcl_SetVar2(interp, varName, "Collate", string, 0); } if (dmPtr->dmFields & DM_FORMNAME) { Tcl_SetVar2(interp, varName, "FormName", dmPtr->dmFormName, 0); } Tcl_SetVar2(interp, varName, "OutputFile", dmPtr->dmDeviceName, 0); result = TCL_OK; error: Tcl_DStringFree(&dString); CloseQueue(queuePtr); if (hMem1 != NULL) { GlobalUnlock(hMem1); GlobalFree(hMem1); } if (hMem2 != NULL) { GlobalUnlock(hMem2); GlobalFree(hMem2); } return result; } static int SetQueueAttributes( Tcl_Interp *interp, PrinterQueue *queuePtr, Tcl_Obj *objPtr) { char *string; DEVMODE *dmPtr; int value; HGLOBAL hMem; int result; char *varName; if (OpenQueue(interp, queuePtr) != TCL_OK) { return TCL_ERROR; } hMem = GetQueueProperties(queuePtr, &dmPtr); CloseQueue(queuePtr); if (hMem == NULL) { return TCL_ERROR; } dmPtr->dmFields = 0; varName = Tcl_GetString(objPtr); string = (char *)Tcl_GetVar2(interp, varName, "Orientation", 0); if (string != NULL) { value = StringToToken(orientationTable, string); if (value > 0) { dmPtr->dmFields |= DM_ORIENTATION; dmPtr->dmOrientation = value; } } string = (char *)Tcl_GetVar2(interp, varName, "PaperSize", 0); if (string != NULL) { value = StringToToken(sizeTable, string); if (value > 0) { dmPtr->dmFields |= DM_PAPERSIZE; dmPtr->dmPaperSize = value; } } string = (char *)Tcl_GetVar2(interp, varName, "PaperWidth", 0); if (string != NULL) { if (Tcl_GetInt(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_PAPERWIDTH; dmPtr->dmPaperWidth = value; } } string = (char *)Tcl_GetVar2(interp, varName, "PaperLength", 0); if (string != NULL) { if (Tcl_GetInt(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_PAPERLENGTH; dmPtr->dmPaperLength = value; } } string = (char *)Tcl_GetVar2(interp, varName, "Scale", 0); if (string != NULL) { if (Tcl_GetInt(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_SCALE; dmPtr->dmScale = value; } } string = (char *)Tcl_GetVar2(interp, varName, "Copies", 0); if (string != NULL) { if (Tcl_GetInt(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_COPIES; dmPtr->dmCopies = value; } } string = (char *)Tcl_GetVar2(interp, varName, "DefaultSource", 0); if (string != NULL) { value = StringToToken(binTable, string); if (value > 0) { dmPtr->dmFields |= DM_DEFAULTSOURCE; dmPtr->dmDefaultSource = value; } } string = (char *)Tcl_GetVar2(interp, varName, "PrintQuality", 0); if (string != NULL) { value = StringToToken(qualityTable, string); if (value > 0) { dmPtr->dmFields |= DM_PRINTQUALITY; dmPtr->dmPrintQuality = value; } } string = (char *)Tcl_GetVar2(interp, varName, "Color", 0); if (string != NULL) { value = StringToToken(colorTable, string); if (value > 0) { dmPtr->dmFields |= DM_COLOR; dmPtr->dmColor = value; } } string = (char *)Tcl_GetVar2(interp, varName, "Duplex", 0); if (string != NULL) { value = StringToToken(duplexTable, string); if (value > 0) { dmPtr->dmFields |= DM_DUPLEX; dmPtr->dmDuplex = value; } } string = (char *)Tcl_GetVar2(interp, varName, "YResolution", 0); if (string != NULL) { if (Tcl_GetInt(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_YRESOLUTION; dmPtr->dmYResolution = value; } } string = (char *)Tcl_GetVar2(interp, varName, "TTOption", 0); if (string != NULL) { value = StringToToken(ttOptionTable, string); if (value > 0) { dmPtr->dmFields |= DM_TTOPTION; dmPtr->dmTTOption = value; } } string = (char *)Tcl_GetVar2(interp, varName, "Collate", 0); if (string != NULL) { if (Tcl_GetBoolean(interp, string, &value) == TCL_OK) { dmPtr->dmFields |= DM_COLLATE; dmPtr->dmCollate = value; } } string = (char *)Tcl_GetVar2(interp, varName, "OutputFile", 0); if (string != NULL) { if (queuePtr->fileName != NULL) { Blt_Free(queuePtr->fileName); } queuePtr->fileName = Blt_AssertStrdup(string); } if (queuePtr->dmPtr != NULL) { Blt_Free(queuePtr->dmPtr); } string = (char *)Tcl_GetVar2(interp, varName, "DocumentName", 0); if (string != NULL) { if (queuePtr->docName != NULL) { Blt_Free(queuePtr->docName); } queuePtr->docName = Blt_AssertStrdup(string); } result = SetQueueProperties(interp, queuePtr, dmPtr); GlobalUnlock(hMem); GlobalFree(hMem); CloseQueue(queuePtr); return result; } /*ARGSUSED*/ static int EnumOp( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TokenString *p; char c; unsigned int length; char *attr; attr = Tcl_GetStringFromObj(objv[2], &length); c = attr[0]; if ((c == 'p') && (strncmp(attr, "paper", length) == 0)) { p = sizeTable; } else if ((c == 'q') && (strncmp(attr, "quality", length) == 0)) { p = qualityTable; } else if ((c == 'b') && (strncmp(attr, "bin", length) == 0)) { p = binTable; } else if ((c == 'o') && (strncmp(attr, "orientation", length) == 0)) { p = orientationTable; } else if ((c == 'c') && (strncmp(attr, "color", length) == 0)) { p = colorTable; } else if ((c == 'd') && (strncmp(attr, "duplex", length) == 0)) { p = duplexTable; } else if ((c == 't') && (strncmp(attr, "ttoption", length) == 0)) { p = ttOptionTable; } else { Tcl_AppendResult(interp, "bad enumeration field \"", attr, "\": should be \"paper\", \"quality\", \"bin\", \"orientation\", \"color\", \"duplex\", or \"ttoption\"", (char *)NULL); return TCL_ERROR; } for ( /*empty*/ ; p->string != NULL; p++) { Tcl_AppendElement(interp, p->string); } return TCL_OK; } /*ARGSUSED*/ static int OpenOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PrinterInterpData *dataPtr = clientData; PrinterQueue *queuePtr; LPVOID buffer; PRINTER_INFO_2* pi2Ptr; DWORD bytesNeeded; int isNew; Blt_HashEntry *hPtr; HANDLE hMem; char *name; name = Tcl_GetString(objv[2]); hPtr = Blt_CreateHashEntry(&dataPtr->printerTable, name, &isNew); if (isNew) { queuePtr = Blt_AssertCalloc(1, sizeof(PrinterQueue)); queuePtr->name = Blt_GetHashKey(&dataPtr->printerTable, hPtr); queuePtr->interp = interp; Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); Blt_SetHashValue(hPtr, queuePtr); queuePtr->hashPtr = hPtr; queuePtr->tablePtr = &dataPtr->printerTable; queuePtr->printerName = Blt_AssertStrdup(name); } else { Tcl_AppendResult(interp, "printer \"", name, "\" is already open", (char *)NULL); return TCL_ERROR; } if (OpenQueue(interp, queuePtr) != TCL_OK) { DestroyQueue(queuePtr); return TCL_ERROR; } /* Call the first time to determine the amount of memory needed. */ GetPrinter(queuePtr->hPrinter, 2, NULL, 0, &bytesNeeded); if ((bytesNeeded == 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { Tcl_AppendResult(interp, "can't get size of attribute buffer for \"", name, "\": ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } /* Allocate a buffer to contain all printer information. */ hMem = GlobalAlloc(GHND, bytesNeeded); if (hMem == NULL) { return TCL_ERROR; } buffer = (LPVOID)GlobalLock(hMem); /* And call the again to actually get the printer. */ if (!GetPrinter(queuePtr->hPrinter, 2, buffer, bytesNeeded, &bytesNeeded)) { Tcl_AppendResult(interp, "can't get printer attributes for \"", name, "\": ", Blt_LastError(), (char *)NULL); GlobalUnlock(hMem); GlobalFree(hMem); return TCL_ERROR; } pi2Ptr = (PRINTER_INFO_2 *)buffer; if (pi2Ptr->pDevMode != NULL) { queuePtr->deviceName = Blt_AssertStrdup(pi2Ptr->pDevMode->dmDeviceName); } queuePtr->driverName = Blt_AssertStrdup(pi2Ptr->pDriverName); /* queuePtr->printerName = Blt_AssertStrdup(pi2Ptr->pPrinterName); */ queuePtr->portName = Blt_AssertStrdup(pi2Ptr->pPortName); GlobalUnlock(hMem); GlobalFree(hMem); return TCL_OK; } /*ARGSUSED*/ static int NamesOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) /* Not used. */ { DWORD nPrinters, bytesNeeded; int elemSize, level; unsigned char *buffer; int result, flags; HANDLE hMem; if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { level = 4; elemSize = sizeof(PRINTER_INFO_4); flags = PRINTER_ENUM_NAME; } else { level = 5; elemSize = sizeof(PRINTER_INFO_5); flags = PRINTER_ENUM_LOCAL; } result = EnumPrinters( flags, /* Flags */ NULL, /* Printer name */ level, /* Information level: 1, 2, 4, or 5 */ NULL, /* Array of returned information */ 0, /* Size of array */ &bytesNeeded, /* Size needed for array */ &nPrinters); /* Number of structures returned */ if ((!result) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { Tcl_AppendResult(interp, "can't enumerate printers (memory alloc): ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } hMem = GlobalAlloc(GHND, bytesNeeded); buffer = (unsigned char *)GlobalLock(hMem); result = EnumPrinters( flags, /* Flags */ NULL, /* Printer name */ level, /* Information level: 1, 2, 4, or 5 */ buffer, /* Array of returned information */ bytesNeeded, /* Size of array */ &bytesNeeded, /* Size needed for array */ &nPrinters); /* Number of structures returned */ if (!result) { Tcl_AppendResult(interp, "can't enumerate printers: ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } if (objc > 2) { unsigned int i; char *pattern; char *p; p = buffer; pattern = Tcl_GetString(objv[2]); for (i = 0; i < nPrinters; i++) { if (Tcl_StringMatch(p, pattern)) { Tcl_AppendElement(interp, *(char **)p); } p += elemSize; } } else { unsigned int i; char *p; p = buffer; for (i = 0; i < nPrinters; i++) { Tcl_AppendElement(interp, *(char **)p); p += elemSize; } } GlobalUnlock(hMem); GlobalFree(hMem); return TCL_OK; } /*ARGSUSED*/ static int CloseOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { PrinterQueue *queuePtr; if (GetQueueFromObj(interp, objv[2], &queuePtr) != TCL_OK) { return TCL_ERROR; } DestroyQueue(queuePtr); return TCL_OK; } /*ARGSUSED*/ static int GetAttrOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { PrinterQueue *queuePtr; if (GetQueueFromObj(interp, objv[2], &queuePtr) != TCL_OK) { return TCL_ERROR; } return GetPrinterAttributes(interp, queuePtr, objv[3]); } /*ARGSUSED*/ static int SetAttrOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { PrinterQueue *queuePtr; if (GetQueueFromObj(interp, objv[2], &queuePtr) != TCL_OK) { return TCL_ERROR; } return SetQueueAttributes(interp, queuePtr, objv[3]); } /* *--------------------------------------------------------------------------- * * SnapOp -- * * Prints a snapshot of a Tk_Window to the designated printer. * * Results: * Returns a standard TCL result. If an error occurred * TCL_ERROR is returned and interp->result will contain an * error message. * *--------------------------------------------------------------------------- */ static int SnapOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { BITMAPINFO bi; DIBSECTION ds; HBITMAP hBitmap; HPALETTE hPalette; HDC hDC, printDC, memDC; void *data; Tk_Window tkwin; TkWinDCState state; int result; PrinterQueue *queuePtr; DOCINFO di; double pageWidth, pageHeight; int jobId; char *driverName; DEVMODE *dmPtr; HGLOBAL hMem; Tcl_DString dString; char *path; Tcl_DStringInit(&dString); if (GetQueueFromObj(interp, objv[2], &queuePtr) != TCL_OK) { return TCL_ERROR; } path = Tcl_GetString(objv[3]); tkwin = Tk_NameToWindow(interp, path, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } result = TCL_ERROR; hDC = TkWinGetDrawableDC(Tk_Display(tkwin), Tk_WindowId(tkwin), &state); ZeroMemory(&bi, sizeof(bi)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = Tk_Width(tkwin); bi.bmiHeader.biHeight = Tk_Height(tkwin); bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; hBitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, &data, NULL, 0); memDC = CreateCompatibleDC(hDC); SelectBitmap(memDC, hBitmap); hPalette = Blt_GetSystemPalette(); if (hPalette != NULL) { SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); SelectPalette(memDC, hPalette, FALSE); RealizePalette(memDC); } /* Copy the window contents to the memory surface. */ if (!BitBlt(memDC, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), hDC, 0, 0, SRCCOPY)) { Tcl_AppendResult(interp, "can't blit \"", Tk_PathName(tkwin), "\": ", Blt_LastError(), (char *)NULL); goto done; } /* Now that the DIB contains the image of the window, get the * databits and write them to the printer device, stretching the * image to the fit the printer's resolution. */ if (GetObject(hBitmap, sizeof(DIBSECTION), &ds) == 0) { Tcl_AppendResult(interp, "can't get DIB object: ", Blt_LastError(), (char *)NULL); goto done; } driverName = NULL; if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { driverName = queuePtr->driverName; } if (OpenQueue(interp, queuePtr) != TCL_OK) { goto done; } hMem = GetQueueProperties(queuePtr, &dmPtr); if (hMem == NULL) { goto done; } printDC = CreateDC(driverName, queuePtr->deviceName, NULL, dmPtr); GlobalUnlock(hMem); GlobalFree(hMem); if (printDC == NULL) { Tcl_AppendResult(interp, "can't allocate printer DC for \"", queuePtr->name, "\": ", Blt_LastError(), (char *)NULL); goto done; } { double scale, sx, sy; /* Get the resolution of the printer device. */ sx = (double)GetDeviceCaps(printDC, HORZRES)/(double)Tk_Width(tkwin); sy = (double)GetDeviceCaps(printDC, VERTRES)/(double)Tk_Height(tkwin); scale = MIN(sx, sy); pageWidth = scale * Tk_Width(tkwin); pageHeight = scale * Tk_Height(tkwin); } ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(di); Tcl_DStringAppend(&dString, "Snapshot of \"", -1); Tcl_DStringAppend(&dString, Tk_PathName(tkwin), -1); Tcl_DStringAppend(&dString, "\"", -1); di.lpszDocName = Tcl_DStringValue(&dString); jobId = StartDoc(printDC, &di); if (jobId <= 0) { Tcl_AppendResult(interp, "can't start document: ", Blt_LastError(), (char *)NULL); goto done; } if (StartPage(printDC) <= 0) { Tcl_AppendResult(interp, "error starting page: ", Blt_LastError(), (char *)NULL); goto done; } StretchDIBits(printDC, 0, 0, ROUND(pageWidth), ROUND(pageHeight), 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), ds.dsBm.bmBits, (LPBITMAPINFO)&ds.dsBmih, DIB_RGB_COLORS, SRCCOPY); EndPage(printDC); EndDoc(printDC); DeleteDC(printDC); Tcl_SetIntObj(Tcl_GetObjResult(interp), jobId); result = TCL_OK; done: Tcl_DStringFree(&dString); if (queuePtr->hPrinter != NULL) { CloseQueue(queuePtr); } DeleteBitmap(hBitmap); DeleteDC(memDC); TkWinReleaseDrawableDC(Tk_WindowId(tkwin), hDC, &state); if (hPalette != NULL) { DeletePalette(hPalette); } return result; } /*ARGSUSED*/ static int WriteOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { DWORD bytesLeft, nBytes; DOC_INFO_1 di1; DWORD jobId; char *title; char *data; static int nextJob = 0; char string[200]; PrinterQueue *queuePtr; int result; int size; if (GetQueueFromObj(interp, objv[2], &queuePtr) != TCL_OK) { return TCL_ERROR; } if (OpenQueue(interp, queuePtr) != TCL_OK) { return TCL_ERROR; } if (objc == 5) { title = Tcl_GetString(objv[3]); data = Tcl_GetStringFromObj(objv[4], &size); } else { sprintf_s(string, 200, "Print Job #%d", nextJob++); title = string; data = Tcl_GetStringFromObj(objv[3], &size); } ZeroMemory(&di1, sizeof(DOC_INFO_1)); di1.pDocName = title; if (queuePtr->fileName != NULL) { di1.pOutputFile = queuePtr->fileName; } else { di1.pOutputFile = NULL; } di1.pDatatype = (char *)"RAW"; result = TCL_ERROR; /* Start new document */ jobId = StartDocPrinter(queuePtr->hPrinter, 1, (unsigned char *)&di1); if (jobId == 0) { Tcl_AppendResult(interp, "error starting document on \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); goto error; } /* Start new page */ if (!StartPagePrinter(queuePtr->hPrinter)) { Tcl_AppendResult(interp, "error starting page on \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); goto error; } bytesLeft = size; do { if (!WritePrinter(queuePtr->hPrinter, data, bytesLeft, &nBytes)) { Tcl_AppendResult(interp, "can't write data to \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); EndDocPrinter(queuePtr->hPrinter); goto error; } data += nBytes; bytesLeft -= nBytes; } while (bytesLeft > 0); /* End last page */ if (!EndPagePrinter(queuePtr->hPrinter)) { Tcl_AppendResult(interp, "error ending page on \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); goto error; } /* End document */ if (!EndDocPrinter(queuePtr->hPrinter)) { Tcl_AppendResult(interp, "error ending document on \"", queuePtr->printerName, "\": ", Blt_LastError(), (char *)NULL); goto error; } result = TCL_OK; error: CloseQueue(queuePtr); return result; } static Blt_OpSpec printerOps[] = { {"close", 1, CloseOp, 3, 3, "pid",}, {"enum", 1, EnumOp, 3, 3, "attribute",}, {"getattrs", 1, GetAttrOp, 4, 4, "pid varName",}, {"names", 1, NamesOp, 2, 3, "?pattern?",}, {"open", 1, OpenOp, 3, 3, "printerName",}, {"setattrs", 1, SetAttrOp, 4, 4, "pid varName",}, {"snap", 1, SnapOp, 4, 4, "pid window",}, {"write", 1, WriteOp, 4, 5, "pid ?title? string",}, }; static int nPrinterOps = sizeof(printerOps) / sizeof(Blt_OpSpec); /* ARGSUSED */ static int PrinterCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nPrinterOps, printerOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * PrinterInterpDeleteProc -- * * This is called when the interpreter hosting one or more printer * commands is destroyed. * * Results: * None. * * Side effects: * Closes and removes all open printers. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void PrinterInterpDeleteProc(clientData, interp) ClientData clientData; /* Interpreter-specific data. */ Tcl_Interp *interp; { PrinterInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->printerTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { PrinterQueue *queuePtr; queuePtr = Blt_GetHashValue(hPtr); queuePtr->hashPtr = NULL; DestroyQueue(queuePtr); } Blt_DeleteHashTable(&dataPtr->printerTable); Tcl_DeleteAssocData(interp, PRINTER_THREAD_KEY); Blt_Free(dataPtr); } int Blt_PrinterCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "printer", PrinterCmd }; cmdSpec.clientData = GetPrinterInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } /* Public routines */ int Blt_GetOpenPrinter( Tcl_Interp *interp, const char *name, Drawable *drawablePtr) { PrinterQueue *queuePtr; if (GetQueue(interp, name, &queuePtr) != TCL_OK) { return TCL_ERROR; } if (queuePtr->drawable.hDC == NULL) { char *driverName; HGLOBAL hMem; DEVMODE *dmPtr; HDC hDC; driverName = NULL; if (Blt_GetPlatformId() == VER_PLATFORM_WIN32_NT) { driverName = queuePtr->driverName; } if (OpenQueue(interp, queuePtr) != TCL_OK) { return TCL_ERROR; } hMem = GetQueueProperties(queuePtr, &dmPtr); if (hMem == NULL) { CloseQueue(queuePtr); return TCL_ERROR; } if (queuePtr->dmPtr != NULL) { *dmPtr = *queuePtr->dmPtr; } hDC = CreateDC(driverName, queuePtr->deviceName, NULL, dmPtr); GlobalUnlock(hMem); GlobalFree(hMem); CloseQueue(queuePtr); if (hDC == NULL) { Tcl_AppendResult(interp, "can't allocate printer DC for \"", queuePtr->name, "\": ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } queuePtr->drawable.hDC = hDC; queuePtr->drawable.type = TWD_WINDC; } *drawablePtr = (Drawable)(&queuePtr->drawable); return TCL_OK; } #include <commdlg.h> int Blt_PrintDialog( Tcl_Interp *interp, Drawable *drawablePtr) { PRINTDLG dlg; static PrintDrawable drawable; int mode, result; ZeroMemory(&dlg, sizeof(PRINTDLG)); dlg.lStructSize = sizeof(PRINTDLG); dlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION; mode = Tcl_SetServiceMode(TCL_SERVICE_NONE); result = PrintDlg(&dlg); Tcl_SetServiceMode(mode); if (!result) { if (!CommDlgExtendedError()) { return TCL_RETURN; /* Canceled by user. */ } Tcl_AppendResult(interp, "can't access printer:", Blt_LastError(), (char *)NULL); return TCL_ERROR; } *drawablePtr = (Drawable)&drawable; drawable.type = TWD_WINDC; drawable.hDC = dlg.hDC; return TCL_OK; } int Blt_StartPrintJob( Tcl_Interp *interp, Drawable drawable) { DOCINFO di; PrintDrawable *drawPtr = (PrintDrawable *)drawable; int jobId; ZeroMemory((char *)&di, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "Unknown"; jobId = StartDoc(drawPtr->hDC, &di); if (jobId == 0) { Tcl_AppendResult(interp, "error starting document: ", Blt_LastError(), (char *)NULL); return TCL_ERROR; } return TCL_OK; } int Blt_EndPrintJob( Tcl_Interp *interp, Drawable drawable) { PrintDrawable *drawPtr = (PrintDrawable *)drawable; EndPage(drawPtr->hDC); EndDoc(drawPtr->hDC); return TCL_OK; } #endif /*NO_PRINTER*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/tkDisplay.h�������������������������������������������������������������������0000644�0001750�0001750�00000073102�11462120063�015146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * tkDisplay.h -- * * Excerpts from tkInt.h. Used to examine window internals. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * This file contains excerpts from tkInt.h of the TCL library distribution. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ #ifndef _TK_DISPLAY_H #define _TK_DISPLAY_H typedef struct _TkIdStack TkIdStack; typedef struct _TkErrorHandler TkErrorHandler; typedef struct _TkSelectionInfo TkSelectionInfo; typedef struct _TkClipboardTarget TkClipboardTarget; typedef struct _TkWindow TkWindow; typedef struct _TkWindowEvent TkWindowEvent; typedef struct _TkEventHandler TkEventHandler; typedef struct _TkSelHandler TkSelHandler; typedef struct _TkWinInfo TkWinInfo; typedef struct _TkClassProcs TkClassProcs; typedef struct _TkWindowPrivate TkWindowPrivate; typedef struct _TkGrabEvent TkGrabEvent; typedef struct _TkColormap TkColormap; typedef struct _TkStressedCmap TkStressedCmap; typedef struct _TkWmInfo TkWmInfo; typedef struct _TkBindInfo *TkBindInfo; #ifdef notdef typedef struct _TkRegion *TkRegion; #endif typedef struct _TkpCursor *TkpCursor; #ifdef XNQueryInputStyle #define TK_USE_INPUT_METHODS #endif /* XNQueryInputStyle */ /* * This defines whether we should try to use XIM over-the-spot style * input. Allow users to override it. It is a much more elegant use * of XIM, but uses a bit more memory. */ #ifndef TK_XIM_SPOT # define TK_XIM_SPOT 1 #endif /* TK_XIM_SPOT */ #ifndef TK_REPARENTED #define TK_REPARENTED 0 #endif /* TK_REPARENTED */ /* * Tk keeps one of the following data structures for each main * window (created by a call to TkCreateMainWindow). It stores * information that is shared by all of the windows associated * with a particular main window. */ typedef struct TkMainInfo { int refCount; /* Number of windows whose "mainPtr" fields * point here. When this becomes zero, can * free up the structure (the reference * count is zero because windows can get * deleted in almost any order; the main * window isn't necessarily the last one * deleted). */ struct TkWindow *winPtr; /* Pointer to main window. */ Tcl_Interp *interp; /* Interpreter associated with application. */ Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow * structs for all windows related to this * main window. Managed by tkWindow.c. */ long deletionEpoch; /* Incremented by window deletions */ Tk_BindingTable bindingTable; /* Used in conjunction with "bind" command * to bind events to TCL commands. */ TkBindInfo bindInfo; /* Information used by tkBind.c on a per * application basis. */ struct TkFontInfo *fontInfoPtr; /* Information used by tkFont.c on a per * application basis. */ /* * Information used only by tkFocus.c and tk*Embed.c: */ struct TkToplevelFocusInfo *tlFocusPtr; /* First in list of records containing focus * information for each top-level in the * application. Used only by tkFocus.c. */ struct TkDisplayFocusInfo *displayFocusPtr; /* First in list of records containing focus * information for each display that this * application has ever used. Used only * by tkFocus.c. */ struct ElArray *optionRootPtr; /* Top level of option hierarchy for this * main window. NULL means uninitialized. * Managed by tkOption.c. */ Tcl_HashTable imageTable; /* Maps from image names to Tk_ImageMaster * structures. Managed by tkImage.c. */ int strictMotif; /* This is linked to the tk_strictMotif * global variable. */ #if (_TK_VERSION >= _VERSION(8,5,0)) int alwaysShowSelection; /* This is linked to the * ::tk::AlwaysShowSelection variable. */ #endif /* TK_VERSION >= 8.5.0 */ struct TkMainInfo *nextPtr; /* Next in list of all main windows managed by * this process. */ } TkMainInfo; #if (_TK_VERSION >= _VERSION(8,1,0)) typedef struct TkCaret { struct TkWindow *winPtr; /* the window on which we requested caret * placement */ int x; /* relative x coord of the caret */ int y; /* relative y coord of the caret */ int height; /* specified height of the window */ } TkCaret; /* * One of the following structures is maintained for each display * containing a window managed by Tk. In part, the structure is * used to store thread-specific data, since each thread will have * its own TkDisplay structure. */ typedef struct _TkDisplay { Display *display; /* Xlib's info about display. */ struct _TkDisplay *nextPtr; /* Next in list of all displays. */ char *name; /* Name of display (with any screen * identifier removed). Malloc-ed. */ Time lastEventTime; /* Time of last event received for this * display. */ /* * Information used primarily by tk3d.c: */ int borderInit; /* 0 means borderTable needs initializing. */ Tcl_HashTable borderTable; /* Maps from color name to TkBorder * structure. */ /* * Information used by tkAtom.c only: */ int atomInit; /* 0 means stuff below hasn't been * initialized yet. */ Tcl_HashTable nameTable; /* Maps from names to Atom's. */ Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ /* * Information used primarily by tkBind.c: */ int bindInfoStale; /* Non-zero means the variables in this * part of the structure are potentially * incorrect and should be recomputed. */ unsigned int modeModMask; /* Has one bit set to indicate the modifier * corresponding to "mode shift". If no * such modifier, than this is zero. */ unsigned int metaModMask; /* Has one bit set to indicate the modifier * corresponding to the "Meta" key. If no * such modifier, then this is zero. */ unsigned int altModMask; /* Has one bit set to indicate the modifier * corresponding to the "Meta" key. If no * such modifier, then this is zero. */ enum { LU_IGNORE, LU_CAPS, LU_SHIFT } lockUsage; /* Indicates how to interpret lock modifier. */ int numModKeyCodes; /* Number of entries in modKeyCodes array * below. */ KeyCode *modKeyCodes; /* Pointer to an array giving keycodes for * all of the keys that have modifiers * associated with them. Malloc'ed, but * may be NULL. */ /* * Information used by tkBitmap.c only: */ int bitmapInit; /* 0 means tables above need initializing. */ int bitmapAutoNumber; /* Used to number bitmaps. */ Tcl_HashTable bitmapNameTable; /* Maps from name of bitmap to the first * TkBitmap record for that name. */ Tcl_HashTable bitmapIdTable;/* Maps from bitmap id to the TkBitmap * structure for the bitmap. */ Tcl_HashTable bitmapDataTable; /* Used by Tk_GetBitmapFromData to map from * a collection of in-core data about a * bitmap to a reference giving an auto- * matically-generated name for the bitmap. */ /* * Information used by tkCanvas.c only: */ int numIdSearches; int numSlowSearches; /* * Used by tkColor.c only: */ int colorInit; /* 0 means color module needs initializing. */ TkStressedCmap *stressPtr; /* First in list of colormaps that have * filled up, so we have to pick an * approximate color. */ Tcl_HashTable colorNameTable; /* Maps from color name to TkColor structure * for that color. */ Tcl_HashTable colorValueTable; /* Maps from integer RGB values to TkColor * structures. */ /* * Used by tkCursor.c only: */ int cursorInit; /* 0 means cursor module need initializing. */ Tcl_HashTable cursorNameTable; /* Maps from a string name to a cursor to the * TkCursor record for the cursor. */ Tcl_HashTable cursorDataTable; /* Maps from a collection of in-core data * about a cursor to a TkCursor structure. */ Tcl_HashTable cursorIdTable; /* Maps from a cursor id to the TkCursor * structure for the cursor. */ char cursorString[20]; /* Used to store a cursor id string. */ Font cursorFont; /* Font to use for standard cursors. * None means font not loaded yet. */ /* * Information used by tkError.c only: */ struct TkErrorHandler *errorPtr; /* First in list of error handlers * for this display. NULL means * no handlers exist at present. */ int deleteCount; /* Counts # of handlers deleted since * last time inactive handlers were * garbage-collected. When this number * gets big, handlers get cleaned up. */ /* * Used by tkEvent.c only: */ struct TkWindowEvent *delayedMotionPtr; /* Points to a malloc-ed motion event * whose processing has been delayed in * the hopes that another motion event * will come along right away and we can * merge the two of them together. NULL * means that there is no delayed motion * event. */ /* * Information used by tkFocus.c only: */ int focusDebug; /* 1 means collect focus debugging * statistics. */ struct TkWindow *implicitWinPtr; /* If the focus arrived at a toplevel window * implicitly via an Enter event (rather * than via a FocusIn event), this points * to the toplevel window. Otherwise it is * NULL. */ struct TkWindow *focusPtr; /* Points to the window on this display that * should be receiving keyboard events. When * multiple applications on the display have * the focus, this will refer to the * innermost window in the innermost * application. This information isn't used * under Unix or Windows, but it's needed on * the Macintosh. */ /* * Information used by tkGC.c only: */ Tcl_HashTable gcValueTable; /* Maps from a GC's values to a TkGC structure * describing a GC with those values. */ Tcl_HashTable gcIdTable; /* Maps from a GC to a TkGC. */ int gcInit; /* 0 means the tables below need * initializing. */ /* * Information used by tkGeometry.c only: */ Tcl_HashTable maintainHashTable; /* Hash table that maps from a master's * Tk_Window token to a list of slaves * managed by that master. */ int geomInit; /* * Information used by tkGet.c only: */ Tcl_HashTable uidTable; /* Stores all Tk_Uids used in a thread. */ int uidInit; /* 0 means uidTable needs initializing. */ /* * Information used by tkGrab.c only: */ struct TkWindow *grabWinPtr; /* Window in which the pointer is currently * grabbed, or NULL if none. */ struct TkWindow *eventualGrabWinPtr; /* Value that grabWinPtr will have once the * grab event queue (below) has been * completely emptied. */ struct TkWindow *buttonWinPtr; /* Window in which first mouse button was * pressed while grab was in effect, or NULL * if no such press in effect. */ struct TkWindow *serverWinPtr; /* If no application contains the pointer then * this is NULL. Otherwise it contains the * last window for which we've gotten an * Enter or Leave event from the server (i.e. * the last window known to have contained * the pointer). Doesn't reflect events * that were synthesized in tkGrab.c. */ TkGrabEvent *firstGrabEventPtr; /* First in list of enter/leave events * synthesized by grab code. These events * must be processed in order before any other * events are processed. NULL means no such * events. */ TkGrabEvent *lastGrabEventPtr; /* Last in list of synthesized events, or NULL * if list is empty. */ int grabFlags; /* Miscellaneous flag values. See definitions * in tkGrab.c. */ /* * Information used by tkGrid.c only: */ int gridInit; /* 0 means table below needs initializing. */ Tcl_HashTable gridHashTable;/* Maps from Tk_Window tokens to * corresponding Grid structures. */ /* * Information used by tkImage.c only: */ int imageId; /* Value used to number image ids. */ /* * Information used by tkMacWinMenu.c only: */ int postCommandGeneration; /* * Information used by tkOption.c only. */ /* * Information used by tkPack.c only. */ int packInit; /* 0 means table below needs initializing. */ Tcl_HashTable packerHashTable; /* Maps from Tk_Window tokens to * corresponding Packer structures. */ /* * Information used by tkPlace.c only. */ int placeInit; /* 0 means tables below need initializing. */ Tcl_HashTable masterTable; /* Maps from Tk_Window toke to the Master * structure for the window, if it exists. */ Tcl_HashTable slaveTable; /* Maps from Tk_Window toke to the Slave * structure for the window, if it exists. */ /* * Information used by tkSelect.c and tkClipboard.c only: */ struct TkSelectionInfo *selectionInfoPtr; /* First in list of selection information * records. Each entry contains information * about the current owner of a particular * selection on this display. */ Atom multipleAtom; /* Atom for MULTIPLE. None means * selection stuff isn't initialized. */ Atom incrAtom; /* Atom for INCR. */ Atom targetsAtom; /* Atom for TARGETS. */ Atom timestampAtom; /* Atom for TIMESTAMP. */ Atom textAtom; /* Atom for TEXT. */ Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ Atom applicationAtom; /* Atom for TK_APPLICATION. */ Atom windowAtom; /* Atom for TK_WINDOW. */ Atom clipboardAtom; /* Atom for CLIPBOARD. */ #if (_TK_VERSION >= _VERSION(8,4,0)) Atom utf8Atom; #endif /* TK_VERSION >= 8.4.0 */ Tk_Window clipWindow; /* Window used for clipboard ownership and to * retrieve selections between processes. NULL * means clipboard info hasn't been * initialized. */ int clipboardActive; /* 1 means we currently own the clipboard * selection, 0 means we don't. */ struct TkMainInfo *clipboardAppPtr; /* Last application that owned clipboard. */ struct TkClipboardTarget *clipTargetPtr; /* First in list of clipboard type information * records. Each entry contains information * about the buffers for a given selection * target. */ /* * Information used by tkSend.c only: */ Tk_Window commTkwin; /* Window used for communication * between interpreters during "send" * commands. NULL means send info hasn't * been initialized yet. */ Atom commProperty; /* X's name for comm property. */ Atom registryProperty; /* X's name for property containing * registry of interpreter names. */ Atom appNameProperty; /* X's name for property used to hold the * application name on each comm window. */ /* * Information used by tkXId.c only: */ struct TkIdStack *idStackPtr; /* First in list of chunks of free resource * identifiers, or NULL if there are no free * resources. */ XID(*defaultAllocProc)(Display *display); /* Default resource allocator for display. */ struct TkIdStack *windowStackPtr; /* First in list of chunks of window * identifers that can't be reused right * now. */ #if (_TK_VERSION < _VERSION(8,4,0)) int idCleanupScheduled; /* 1 means a call to WindowIdCleanup has * already been scheduled, 0 means it * hasn't. */ #else Tcl_TimerToken idCleanupScheduled; /* If set, it means a call to WindowIdCleanup * has already been scheduled, 0 means it * hasn't. */ #endif /* TK_VERSION < 8.4.0 */ /* * Information used by tkUnixWm.c and tkWinWm.c only: */ #if (_TK_VERSION < _VERSION(8,4,0)) int wmTracing; /* Used to enable or disable tracing in * this module. If tracing is enabled, * then information is printed on * standard output about interesting * interactions with the window manager. */ #endif /* TK_VERSION < 8.4.0 */ struct TkWmInfo *firstWmPtr; /* Points to first top-level window. */ struct TkWmInfo *foregroundWmPtr; /* Points to the foreground window. */ /* * Information maintained by tkWindow.c for use later on by tkXId.c: */ int destroyCount; /* Number of Tk_DestroyWindow operations * in progress. */ unsigned long lastDestroyRequest; /* Id of most recent XDestroyWindow request; * can re-use ids in windowStackPtr when * server has seen this request and event * queue is empty. */ /* * Information used by tkVisual.c only: */ TkColormap *cmapPtr; /* First in list of all non-default colormaps * allocated for this display. */ /* * Miscellaneous information: */ #ifdef TK_USE_INPUT_METHODS XIM inputMethod; /* Input method for this display */ # if (_TK_VERSION >= _VERSION(8,5,0)) XIMStyle inputStyle; /* Input style selected for this display. */ # endif /* TK_VERSION >= 8.5.0 */ # if (_TK_VERSION >= _VERSION(8,4,0)) # if TK_XIM_SPOT XFontSet inputXfs; /* XFontSet cached for over-the-spot XIM. */ # endif /* TK_XIM_SPOT */ # endif /* _TK_VERSION >= 8.4 */ #endif /* TK_USE_INPUT_METHODS */ Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */ int refCount; /* Reference count of how many Tk applications * are using this display. Used to clean up * the display when we no longer have any * Tk applications using it. */ /* * The following field were all added for Tk8.3 */ int mouseButtonState; /* current mouse button state for this * display */ #if (_TK_VERSION < _VERSION(8,4,0)) int warpInProgress; #else Window mouseButtonWindow; /* Window the button state was set in, added * in Tk 8.4. */ #endif /* TK_VERSION < 8.4.0 */ Window warpWindow; int warpX; int warpY; #if (_TK_VERSION < _VERSION(8,4,0)) int useInputMethods; /* Whether to use input methods */ long deletionEpoch; /* Incremented by window deletions */ #endif /* TK_VERSION < 8.4.0 */ /* * The following field(s) were all added for Tk8.4 */ unsigned int flags; /* Various flag values: these are all * defined in below. */ TkCaret caret; /* information about the caret for this * display. This is not a pointer. */ #if (_TK_VERSION >= _VERSION(8,4,0)) int iconDataSize; /* Size of default iconphoto image data. */ unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */ #endif /* TK_VERSION > 8.4.0 */ } TkDisplay; #else /* * One of the following structures is maintained for each display * containing a window managed by Tk: */ typedef struct _TkDisplay { Display *display; /* Xlib's info about display. */ struct _TkDisplay *nextPtr; /* Next in list of all displays. */ char *name; /* Name of display (with any screen * identifier removed). Malloc-ed. */ Time lastEventTime; /* Time of last event received for this * display. */ /* * Information used primarily by tkBind.c: */ int bindInfoStale; /* Non-zero means the variables in this * part of the structure are potentially * incorrect and should be recomputed. */ unsigned int modeModMask; /* Has one bit set to indicate the modifier * corresponding to "mode shift". If no * such modifier, than this is zero. */ unsigned int metaModMask; /* Has one bit set to indicate the modifier * corresponding to the "Meta" key. If no * such modifier, then this is zero. */ unsigned int altModMask; /* Has one bit set to indicate the modifier * corresponding to the "Meta" key. If no * such modifier, then this is zero. */ enum { LU_IGNORE, LU_CAPS, LU_SHIFT } lockUsage; /* Indicates how to interpret lock modifier. */ int numModKeyCodes; /* Number of entries in modKeyCodes array * below. */ KeyCode *modKeyCodes; /* Pointer to an array giving keycodes for * all of the keys that have modifiers * associated with them. Malloc'ed, but * may be NULL. */ /* * Information used by tkError.c only: */ TkErrorHandler *errorPtr; /* First in list of error handlers * for this display. NULL means * no handlers exist at present. */ int deleteCount; /* Counts # of handlers deleted since * last time inactive handlers were * garbage-collected. When this number * gets big, handlers get cleaned up. */ /* * Information used by tkSend.c only: */ Tk_Window commTkwin; /* Window used for communication * between interpreters during "send" * commands. NULL means send info hasn't * been initialized yet. */ Atom commProperty; /* X's name for comm property. */ Atom registryProperty; /* X's name for property containing * registry of interpreter names. */ Atom appNameProperty; /* X's name for property used to hold the * application name on each comm window. */ /* * Information used by tkSelect.c and tkClipboard.c only: */ TkSelectionInfo *selectionInfoPtr; /* First in list of selection information * records. Each entry contains information * about the current owner of a particular * selection on this display. */ Atom multipleAtom; /* Atom for MULTIPLE. None means * selection stuff isn't initialized. */ Atom incrAtom; /* Atom for INCR. */ Atom targetsAtom; /* Atom for TARGETS. */ Atom timestampAtom; /* Atom for TIMESTAMP. */ Atom textAtom; /* Atom for TEXT. */ Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ Atom applicationAtom; /* Atom for TK_APPLICATION. */ Atom windowAtom; /* Atom for TK_WINDOW. */ Atom clipboardAtom; /* Atom for CLIPBOARD. */ Tk_Window clipWindow; /* Window used for clipboard ownership and to * retrieve selections between processes. NULL * means clipboard info hasn't been * initialized. */ int clipboardActive; /* 1 means we currently own the clipboard * selection, 0 means we don't. */ TkMainInfo *clipboardAppPtr; /* Last application that owned clipboard. */ TkClipboardTarget *clipTargetPtr; /* First in list of clipboard type information * records. Each entry contains information * about the buffers for a given selection * target. */ /* * Information used by tkAtom.c only: */ int atomInit; /* 0 means stuff below hasn't been * initialized yet. */ Tcl_HashTable nameTable; /* Maps from names to Atom's. */ Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ /* * Information used by tkCursor.c only: */ Font cursorFont; /* Font to use for standard cursors. * None means font not loaded yet. */ /* * Information used by tkGrab.c only: */ TkWindow *grabWinPtr; /* Window in which the pointer is currently * grabbed, or NULL if none. */ TkWindow *eventualGrabWinPtr; /* Value that grabWinPtr will have once the * grab event queue (below) has been * completely emptied. */ TkWindow *buttonWinPtr; /* Window in which first mouse button was * pressed while grab was in effect, or NULL * if no such press in effect. */ TkWindow *serverWinPtr; /* If no application contains the pointer then * this is NULL. Otherwise it contains the * last window for which we've gotten an * Enter or Leave event from the server (i.e. * the last window known to have contained * the pointer). Doesn't reflect events * that were synthesized in tkGrab.c. */ TkGrabEvent *firstGrabEventPtr; /* First in list of enter/leave events * synthesized by grab code. These events * must be processed in order before any other * events are processed. NULL means no such * events. */ TkGrabEvent *lastGrabEventPtr; /* Last in list of synthesized events, or NULL * if list is empty. */ int grabFlags; /* Miscellaneous flag values. See definitions * in tkGrab.c. */ /* * Information used by tkXId.c only: */ TkIdStack *idStackPtr; /* First in list of chunks of free resource * identifiers, or NULL if there are no free * resources. */ XID(*defaultAllocProc)(Display *display); /* Default resource allocator for display. */ TkIdStack *windowStackPtr; /* First in list of chunks of window * identifers that can't be reused right * now. */ int idCleanupScheduled; /* 1 means a call to WindowIdCleanup has * already been scheduled, 0 means it * hasn't. */ /* * Information maintained by tkWindow.c for use later on by tkXId.c: */ int destroyCount; /* Number of Tk_DestroyWindow operations * in progress. */ unsigned long lastDestroyRequest; /* Id of most recent XDestroyWindow request; * can re-use ids in windowStackPtr when * server has seen this request and event * queue is empty. */ /* * Information used by tkVisual.c only: */ TkColormap *cmapPtr; /* First in list of all non-default colormaps * allocated for this display. */ /* * Information used by tkFocus.c only: */ TkWindow *implicitWinPtr; /* If the focus arrived at a toplevel window * implicitly via an Enter event (rather * than via a FocusIn event), this points * to the toplevel window. Otherwise it is * NULL. */ TkWindow *focusPtr; /* Points to the window on this display that * should be receiving keyboard events. When * multiple applications on the display have * the focus, this will refer to the * innermost window in the innermost * application. This information isn't used * under Unix or Windows, but it's needed on * the Macintosh. */ /* * Used by tkColor.c only: */ TkStressedCmap *stressPtr; /* First in list of colormaps that have * filled up, so we have to pick an * approximate color. */ /* * Used by tkEvent.c only: */ TkWindowEvent *delayedMotionPtr; /* Points to a malloc-ed motion event * whose processing has been delayed in * the hopes that another motion event * will come along right away and we can * merge the two of them together. NULL * means that there is no delayed motion * event. */ /* * Miscellaneous information: */ #ifdef TK_USE_INPUT_METHODS XIM inputMethod; /* Input method for this display */ #endif /* TK_USE_INPUT_METHODS */ Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */ int refCount; /* Reference count of how many Tk applications * are using this display. Used to clean up * the display when we no longer have any * Tk applications using it. */ } TkDisplay; #endif /* _TK_VERSION >= _VERSION(8,1,0) */ struct _TkWindow { Display *display; TkDisplay *dispPtr; int screenNum; Visual *visual; int depth; Window window; TkWindow *childList; TkWindow *lastChildPtr; TkWindow *parentPtr; TkWindow *nextPtr; TkMainInfo *mainPtr; char *pathName; Tk_Uid nameUid; Tk_Uid classUid; XWindowChanges changes; unsigned int dirtyChanges; XSetWindowAttributes atts; unsigned long dirtyAtts; unsigned int flags; TkEventHandler *handlerList; #ifdef TK_USE_INPUT_METHODS XIC inputContext; #endif /* TK_USE_INPUT_METHODS */ ClientData *tagPtr; int nTags; int optionLevel; TkSelHandler *selHandlerList; Tk_GeomMgr *geomMgrPtr; ClientData geomData; int reqWidth, reqHeight; int internalBW; TkWinInfo *wmInfoPtr; TkClassProcs *classProcsPtr; ClientData instanceData; TkWindowPrivate *privatePtr; #if (_TK_VERSION >= _VERSION(8,4,0)) /* The remaining fields of internal border. */ int internalBorderRight; int internalBorderTop; int internalBorderBottom; int minReqWidth; /* Minimum requested width. */ int minReqHeight; /* Minimum requested height. */ #endif }; /* * This structure is used by the Mac and Window porting layers as * the internal representation of a clip_mask in a GC. */ typedef struct { int type; /* One of TKP_CLIP_PIXMAP or TKP_CLIP_REGION */ union { Pixmap pixmap; TkRegion region; } value; } TkpClipMask; #define TKP_CLIP_PIXMAP 0 #define TKP_CLIP_REGION 1 #ifdef WIN32 #include "tkWinDisplay.h" #endif #endif /* _TK_DISPLAY_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictGif.c������������������������������������������������������������������0000644�0001750�0001750�00000202234�11462120062�015223� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictGif.c -- * * This module implements GIF file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The GIF reader is from converters/other/giftopnm.c in the netpbm * (version 10.19) distribution. * * Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. This software is provided "as is" without * express or implied warranty. * * The GIF writer is in part derived from converters/other/pamtogif.c in * the netpbm (version 10.19) distribution. * * Original version, named 'ppmgif' was by Jef Poskanzer in 1989, based * on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>.A Lempel-Zim * compression based on "compress". * * Switched to use libnetpbm PAM facilities (ergo process PAM images) and * renamed 'pamtogif' by Bryan Henderson November 2006. * * * Copyright (C) 1989 by Jef Poskanzer. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. This software is provided "as is" without * express or implied warranty. * * The Graphics Interchange Format(c) is the Copyright property of * CompuServe Incorporated. GIF(sm) is a Service Mark property of * CompuServe Incorporated. * * The compression routines also use the following * * GIFCOMPR.C - GIF Image compression routines * * Lempel-Ziv compression based on 'compress'. GIF modifications by * * David Rowley (mgardi@watdcsu.waterloo.edu) * * GIF Image compression - modified 'compress' * * Based on: compress.c - File compression ala IEEE Computer, June 1984. * * By Authors: * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) * Jim McKie (decvax!mcvax!jim) * Steve Davies (decvax!vax135!petsd!peora!srd) * Ken Turkowski (decvax!decwrl!turtlevax!ken) * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * */ #include "blt.h" #include "config.h" #include <ctype.h> #ifdef HAVE_STRING_H # include <string.h> #endif /* HAVE_STRING_H */ #include <tcl.h> #include <bltAlloc.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include "bltPicture.h" #include "bltPictFmts.h" #ifdef _MSC_VER #define vsnprintf _vsnprintf #endif #include <setjmp.h> typedef struct _Blt_Picture Pict; typedef struct { Blt_Picture original; Blt_Picture current; int delay; int nColors; } Frame; #define TRUE 1 #define FALSE 0 #define LZW_MAX_BITS 12 #define LZW_MAX_CODE (1 << LZW_MAX_BITS) #define GIF87A 1 #define GIF89A 2 typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; } GifImportSwitches; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(GifImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(GifImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; Blt_Pixel bg; const char **comments; /* Comments */ unsigned int flags; int index; int delay; } GifExportSwitches; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; #define EXPORT_BLEND (1<<0) #define EXPORT_ANIMATE (1<<1) static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_BITMASK, "-animate", "", Blt_Offset(GifExportSwitches, flags), 0, EXPORT_ANIMATE}, {BLT_SWITCH_CUSTOM, "-bg", "color", Blt_Offset(GifExportSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_BITMASK, "-blend", "", Blt_Offset(GifExportSwitches, flags), 0, EXPORT_BLEND}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(GifExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(GifExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_LIST, "-comments", "{string...}", Blt_Offset(GifExportSwitches, comments), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(GifExportSwitches, index), 0}, {BLT_SWITCH_INT_NNEG, "-delay", "int", Blt_Offset(GifExportSwitches, delay), 0}, {BLT_SWITCH_END} }; typedef struct { jmp_buf jmpbuf; Tcl_DString errors; Tcl_DString warnings; int nWarnings, nErrors; } GifMessage; typedef struct { int version; /* Eithe GIF87A or GIF89A */ Blt_Pixel globalColorTable[256]; Blt_Pixel localColorTable[256]; /* Data to be parsed */ Blt_DBuffer dbuffer; /* Global parameters. */ int logicalScreenWidth, logicalScreenHeight; int globalColorTableFlag; int colorResolution; int sortFlag; unsigned int globalColorTableSize; int bgColorIndex; int pixelAspectRatio; /* Local parameters. */ int imageLeftPosition, imageTopPosition; int imageWidth, imageHeight; int localColorTableFlag; int interlaceFlag; int imageSortFlag; unsigned int localColorTableSize; /* Graphic control extension. */ int disposalMethod; int userInputFlag; int transparentColorFlag; int delayTime; int transparentColorIndex; int lzwMinimumCodeSize; } Gif; static GifMessage *gifMessagePtr; DLLEXPORT extern Tcl_AppInitProc Blt_PictureGifInit; static unsigned short GifGetShort(unsigned char *buf) { #ifdef WORDS_BIGENDIAN return (buf[0] << 8) | buf[1]; #else return buf[0] | (buf[1] << 8); #endif } static unsigned char * GifSetShort(unsigned char *buf, unsigned int value) { #ifdef WORDS_BIGENDIAN buf[0] = (value >> 8) & 0xFF; buf[1] = (value) & 0xFF; #else buf[0] = (value) & 0xFF; buf[1] = (value >> 8) & 0xFF; #endif return buf + 2; } /*ARGSUSED*/ static void GifError TCL_VARARGS_DEF(const char *, arg1) { const char *fmt; char string[BUFSIZ+4]; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&gifMessagePtr->errors, string, -1); va_end(args); longjmp(gifMessagePtr->jmpbuf, 0); } /*ARGSUSED*/ static void GifWarning TCL_VARARGS_DEF(const char *, arg1) { const char *fmt; char string[BUFSIZ+4]; int length; va_list args; fmt = TCL_VARARGS_START(const char *, arg1, args); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&gifMessagePtr->warnings, string, -1); va_end(args); gifMessagePtr->nWarnings++; } /* * 0 3 Signature "GIF" * 3 3 Version "89a" */ static int GifHeader(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char *bp; Blt_DBuffer_ResetCursor(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < 6) { return FALSE; } bp = Blt_DBuffer_Pointer(dbuffer); if ((bp[0] != 'G') || (bp[1] != 'I') || (bp[2] != 'F') || (bp[3] != '8') || (bp[5] != 'a')) { return FALSE; } if (bp[4] == '7') { gifPtr->version = GIF87A; } else if (bp[4] == '9') { gifPtr->version = GIF89A; } Blt_DBuffer_IncrCursor(dbuffer, 6); return TRUE; } /* * 0 2 Logical Screen Width * 2 2 Logical Screen Height * 4 1 Flags * bit 7 = Global color table flag. * bits 4-6 = Color resolution. * bit 3 = Sort flag. * bits 0-2 = Size of global color table. * 5 1 Background Color Index * 6 1 Pixel Aspect Ratio */ static void GifReadLogicalScreenDescriptor(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char *bp; if (Blt_DBuffer_BytesLeft(dbuffer) < 7) { GifError("short file: expected 7 bytes for GIF logical screen descriptor"); } bp = Blt_DBuffer_Pointer(dbuffer); /* Logical Screen Descriptor. */ gifPtr->logicalScreenWidth = GifGetShort(bp + 0); gifPtr->logicalScreenHeight = GifGetShort(bp + 2); gifPtr->globalColorTableFlag = (bp[4] & 0x80); gifPtr->colorResolution = ((bp[4] & 0x70) >> 4); gifPtr->sortFlag = (bp[4] & 0x08) >> 3; gifPtr->globalColorTableSize = 1 << ((bp[4] & 0x07) + 1); gifPtr->bgColorIndex = bp[5]; /* Index of bgcolor color */ gifPtr->pixelAspectRatio = bp[6]; Blt_DBuffer_IncrCursor(dbuffer, 7); #ifdef notdef fprintf(stderr, "screen width = %d\n", gifPtr->logicalScreenWidth); fprintf(stderr, "screen height = %d\n", gifPtr->logicalScreenHeight); fprintf(stderr, "global color table flag = %d\n", gifPtr->globalColorTableFlag); fprintf(stderr, "color resolution = %d\n", gifPtr->colorResolution); fprintf(stderr, "sort flag = %d\n", gifPtr->sortFlag); fprintf(stderr, "global color table size = %d\n", gifPtr->globalColorTableSize); fprintf(stderr, "bg color index = %d\n", gifPtr->bgColorIndex); fprintf(stderr, "pixel aspect ratio = %d\n", gifPtr->pixelAspectRatio); #endif } /* * 7 6 5 4 3 2 1 0 Field Name Type * +================+ * 0 | | Red 0 Byte * 1 | | Green 0 Byte * 2 | | Blue 0 Byte * 3 | | Red 1 Byte * | | Green 1 Byte * up | | * to | | * | | Green 255 Byte * 767 | | Blue 255 Byte * +================+ */ static void GifReadGlobalColorTable(Blt_DBuffer dbuffer, Gif *gifPtr) { Blt_Pixel *dp; unsigned int i; unsigned char *bp; if (Blt_DBuffer_BytesLeft(dbuffer) < (gifPtr->globalColorTableSize*3)) { GifError("short file: expected %d bytes for GIF global color table", gifPtr->globalColorTableSize * 3); } bp = Blt_DBuffer_Pointer(dbuffer); dp = gifPtr->globalColorTable; for (i = 0; i < gifPtr->globalColorTableSize; i++) { dp->Red = bp[0]; dp->Green = bp[1]; dp->Blue = bp[2]; dp->Alpha = ALPHA_OPAQUE; dp++; bp += 3; } Blt_DBuffer_SetPointer(dbuffer, bp); } /* * 7 6 5 4 3 2 1 0 Field Name Type * +----------------+ * 0 | | Image Separator Byte * +----------------+ * 1 | | Image Left Position Unsigned * 2 | | * +----------------+ * 3 | | Image Top Position Unsigned * 4 | | * +----------------+ * 5 | | Image Width Unsigned * 6 | | * +----------------+ * 7 | | Image Height Unsigned * 8 | | * +----------------+ * 9 | | | | | | See below * +----------------+ * * = Local Color Table Flag 1 Bit * Interlace Flag 1 Bit * Sort Flag 1 Bit * Reserved 2 Bits * Size of Local Color Table 3 Bits */ static void GifReadImageDescriptor(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char *bp; int size; if (Blt_DBuffer_BytesLeft(dbuffer) < 9) { GifError("short file: expected 9 bytes for GIF image descriptor"); } bp = Blt_DBuffer_Pointer(dbuffer); gifPtr->imageLeftPosition = GifGetShort(bp + 0); gifPtr->imageTopPosition = GifGetShort(bp + 2); gifPtr->imageWidth = GifGetShort(bp + 4); gifPtr->imageHeight = GifGetShort(bp + 6); gifPtr->localColorTableFlag = (bp[8] & 0x80) >> 7; gifPtr->interlaceFlag = (bp[8] & 0x40) >> 6; gifPtr->imageSortFlag = (bp[8] & 0x20) >> 5; size = (bp[8] & 0x07); if (size > 0) { size = 1 << (size + 1); } gifPtr->localColorTableSize = size; Blt_DBuffer_IncrCursor(dbuffer, 9); } /* * 7 6 5 4 3 2 1 0 Field Name Type * +================+ * 0 | | Red 0 Byte * 1 | | Green 0 Byte * 2 | | Blue 0 Byte * 3 | | Red 1 Byte * | | Green 1 Byte * up | | * to | | * | | Green 255 Byte * 767 | | Blue 255 Byte * +================+ */ static void GifReadLocalColorTable(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char *bp; Blt_Pixel *dp; unsigned int i; if (Blt_DBuffer_BytesLeft(dbuffer) < (gifPtr->localColorTableSize*3)) { GifError("short file: expected %d bytes for GIF local color table", gifPtr->localColorTableSize * 3); } bp = Blt_DBuffer_Pointer(dbuffer); dp = gifPtr->localColorTable; for (i = 0; i < gifPtr->localColorTableSize; i++) { dp->Red = bp[0]; dp->Green = bp[1]; dp->Blue = bp[2]; dp->Alpha = ALPHA_OPAQUE; dp++; bp += 3; } Blt_DBuffer_SetPointer(dbuffer, bp); } /* * 7 6 5 4 3 2 1 0 Field Name Type * +----------------+ * 0 | | Extension Introducer Byte * +----------------+ * 1 | | Graphic Control Label Byte * +----------------+ * * +----------------+ * 0 | | Block Size Byte * +----------------+ * 1 | | | | | See below * +----------------+ * 2 | | Delay Time Unsigned * 3 | | * +----------------+ * 4 | | Transparent Color Index Byte * +----------------+ * * +----------------+ * 0 | | Block Terminator Byte * +----------------+ * * * = Reserved 3 Bits * Disposal Method 3 Bits * User Input Flag 1 Bit * Transparent Color Flag 1 Bit */ static void GifReadGraphicControlExtension(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned int length; while ((length = Blt_DBuffer_NextByte(dbuffer)) > 0) { unsigned char *bp; bp = Blt_DBuffer_Pointer(dbuffer); gifPtr->disposalMethod = (bp[0] & 0x1C) >> 2; gifPtr->userInputFlag = bp[0] & 0x02; gifPtr->transparentColorFlag = bp[0] & 0x01; gifPtr->delayTime = GifGetShort(bp + 1); gifPtr->transparentColorIndex = bp[3]; Blt_DBuffer_IncrCursor(dbuffer, length); } } /* * Optional comment block */ static void GifReadCommentExtension(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char length; while ((length = Blt_DBuffer_NextByte(dbuffer)) > 0) { unsigned char *bp; if (Blt_DBuffer_BytesLeft(dbuffer) < length) { GifError("short file: expected %d bytes for GIF comment block", length); } bp = Blt_DBuffer_Pointer(dbuffer); #ifdef notdef { int i; fprintf(stderr, "comment %d bytes follows\n", length); for (i = 0; i < length; i++) { if (isprint(bp[i]) || isspace(bp[i])) { fprintf(stderr, "%c", bp[i]); } else { fprintf(stderr, "{%.2x}", bp[i]); } } fprintf(stderr, "\n"); } #endif Blt_DBuffer_IncrCursor(dbuffer, length); } assert(length == 0); } static void GifReadUnknownExtension(Blt_DBuffer dbuffer, int ident, Gif *gifPtr) { unsigned char length; const char *ext; if (ident == 0x01) { ext = "plain text"; } else if (ident == 0xFF) { ext = "application"; } else { ext = "???"; } #ifdef notdef fprintf(stderr, "read %s extension\n", ext); #endif /* Skip the data sub-blocks */ while ((length = Blt_DBuffer_NextByte(dbuffer)) > 0) { if (Blt_DBuffer_BytesLeft(dbuffer) < length) { GifError("short file: expected %d bytes for %s extension block", length, ext); } Blt_DBuffer_IncrCursor(dbuffer, length); } #ifdef notdef fprintf(stderr, "down reading %s extension\n", ext); #endif } static void GifReadExtensions(Blt_DBuffer dbuffer, Gif *gifPtr) { unsigned char byte; /* * Handle only the "Graphic control extension" block, ignoring all others * (text, comment, and application). */ byte = Blt_DBuffer_NextByte(dbuffer); switch (byte) { case 0xF9: /* Graphic control extension. */ GifReadGraphicControlExtension(dbuffer, gifPtr); break; case 0xFE: /* Comment extension. */ GifReadCommentExtension(dbuffer, gifPtr); break; default: case 0x01: /* Plain text extension. */ case 0xFF: /* Application extension */ GifReadUnknownExtension(dbuffer, byte, gifPtr); break; } #ifdef notdef assert(byte == 0); byte = Blt_DBuffer_NextByte(dbuffer); #endif } static int GifReadDataBlock(Blt_DBuffer dbuffer, unsigned char *out) { unsigned int length; length = Blt_DBuffer_NextByte(dbuffer); if (Blt_DBuffer_BytesLeft(dbuffer) < length) { return -1; } if (length > 0) { memcpy(out, Blt_DBuffer_Pointer(dbuffer), length); Blt_DBuffer_IncrCursor(dbuffer, length); } return (int)length; } /* Stack grows from low addresses to high addresses */ typedef struct { int *stack; /* Malloc'ed array */ int *sp; /* Stack pointer */ int *top; /* Next word above top of stack */ } LzwStack; typedef struct { unsigned char buf[280]; /* This is the buffer through which we read * the data from the stream. We must buffer * it because we have to read whole data * blocks at a time, but our client wants one * code at a time. The buffer typically * contains the contents of one data block * plus two bytes from the previous data * block. */ int bufCount; /* # of bytes of contents in buf[]. */ int curbit; /* The bit number (starting at 0) within buf[] * of the next bit to be returned. If the * next bit to be returned is not yet in buf[] * (we've already returned everything in * there), this points one beyond the end of * the buffer contents. */ int streamExhausted; /* The last time we read from the input * stream, we got an EOD marker or EOF */ } LzwCodeState; /*------------------------------------------------------------------------------- Some notes on LZW. LZW is an extension of Limpel-Ziv. The two extensions are: 1) in Limpel-Ziv, codes are all the same number of bits. In LZW, they start out small and increase as the stream progresses. 2) LZW has a clear code that resets the string table and code size. The LZW code space is allocated as follows: The true data elements are dataWidth bits wide, so the maximum value of a true data element is 2**dataWidth-1. We call that max_dataVal. The first byte in the stream tells you what dataWidth is. LZW codes 0 - max_dataVal are direct codes. Each on represents the true data element whose value is that of the LZW code itself. No decompression is required. max_dataVal + 1 and up are compression codes. They encode true data elements: max_dataVal + 1 is the clear code. max_dataVal + 2 is the end code. max_dataVal + 3 and up are string codes. Each string code represents a string of true data elements. The translation from a string code to the string of true data elements varies as the stream progresses. In the beginning and after every clear code, the translation table is empty, so no string codes are valid. As the stream progresses, the table gets filled and more string codes become valid. --------------------------------------------------------------------------*/ typedef struct { LzwStack stack; int fresh; /* The stream is right after a clear code or at the very beginning */ int codeSize; /* Current code size -- each LZW code in this * part of the image is this many bits. Ergo, * we read this many bits at a time from the * stream. */ int maxnum_code; /* Maximum number of LZW codes that can be * represented with the current code size. (1 * << codeSize) */ int next_tableSlot; /* Index in the code translation table of the * next free entry */ int firstcode; /* This is always a true data element code */ int prevcode; /* The code just before, in the image, the one * we're processing now */ int table[2][(1 << LZW_MAX_BITS)]; /* The following are constant for the life of the decompressor */ int init_codeSize; int max_dataVal; int clear_code; int end_code; Blt_DBuffer dbuffer; } LzwDecompressor; static int zeroDataBlock = 0; static void LzwInitCodeState(LzwCodeState *statePtr) { /* Fake a previous data block */ statePtr->buf[0] = statePtr->buf[1] = 0; statePtr->bufCount = 2; statePtr->curbit = statePtr->bufCount * 8; statePtr->streamExhausted = 0; } static void LzwGetAnotherBlock(Blt_DBuffer dbuffer, LzwCodeState *statePtr) { int count; unsigned int assumed_count; /* * Shift buffer down so last two bytes are now the first two bytes. Shift * 'curbit' cursor, which must be somewhere in or immediately after those * two bytes, accordingly. */ statePtr->buf[0] = statePtr->buf[statePtr->bufCount-2]; statePtr->buf[1] = statePtr->buf[statePtr->bufCount-1]; statePtr->curbit -= (statePtr->bufCount-2)*8; statePtr->bufCount = 2; /* Add the next block to the buffer */ count = GifReadDataBlock(dbuffer, statePtr->buf + statePtr->bufCount); if (count == -1) { GifWarning("EOF encountered in image before EOD marker. The GIF file is malformed, but we are proceeding anyway as if an EOD marker were at the end of the file."); assumed_count = 0; } else { assumed_count = count; } statePtr->streamExhausted = (assumed_count == 0); statePtr->bufCount += assumed_count; } static int LzwNextCode(Blt_DBuffer dbuffer, int codeSize, LzwCodeState *statePtr) { int result; if (((statePtr->curbit + codeSize) > (statePtr->bufCount * 8)) && (!statePtr->streamExhausted)) { /* * Not enough left in buffer to satisfy request. Get the next * data block into the buffer. */ LzwGetAnotherBlock(dbuffer, statePtr); } if ((statePtr->curbit + codeSize) > (statePtr->bufCount * 8)) { /* * If the buffer still doesn't have enough bits in it, that means * there were no data blocks left to read. */ result = -1; /* EOF */ { int const bitsUnused = (statePtr->bufCount * 8) - statePtr->curbit; if (bitsUnused > 0) { GifWarning("Stream ends with a partial code (%d bits left in file; expected a %d bit code). Ignoring.", bitsUnused, codeSize); } } } else { int i, j; int code; unsigned char *bp; bp = statePtr->buf; code = 0; /* Initial value */ for (i = statePtr->curbit, j = 0; j < codeSize; ++i, ++j) { code |= ((bp[ i / 8 ] & (1 << (i % 8))) != 0) << j; } statePtr->curbit += codeSize; result = code; } return result; } /*--------------------------------------------------------------------------- * * LzwGetCode -- * * If 'init', initialize the code getter. Otherwise, read and return the * next LZW code from the buffer. * * Results: * Retunes the retrieved code. Otherwise -1 if we encounter the * end of the file. * *--------------------------------------------------------------------------- */ static int LzwGetCode( Blt_DBuffer dbuffer, /* Buffer to read from. */ int codeSize, /* # of bits in the code we are to get. */ int init) /* Indicates to initial the code reader. */ { static LzwCodeState state; if (init) { LzwInitCodeState(&state); return 0; } return LzwNextCode(dbuffer, codeSize, &state); } static void LzwInitStack( LzwDecompressor *lzwPtr, size_t size) { lzwPtr->stack.stack = Blt_Malloc(size * sizeof(int)); if (lzwPtr->stack.stack == NULL) { GifError("Unable to allocate %d -word stack.", size); } lzwPtr->stack.sp = lzwPtr->stack.stack; lzwPtr->stack.top = lzwPtr->stack.stack + size; } static void LzwPushStack(LzwDecompressor *lzwPtr, int const value) { if (lzwPtr->stack.sp >= lzwPtr->stack.top) { GifError("stack overflow"); } *(lzwPtr->stack.sp++) = value; } static int LzwStackIsEmpty(LzwDecompressor *lzwPtr) { return (lzwPtr->stack.sp == lzwPtr->stack.stack); } static int LzwPopStack(LzwDecompressor *lzwPtr) { if (lzwPtr->stack.sp <= lzwPtr->stack.stack) { GifError("stack underflow"); } return *(--lzwPtr->stack.sp); } static void LzwTermStack(LzwDecompressor *lzwPtr) { Blt_Free(lzwPtr->stack.stack); lzwPtr->stack.stack = NULL; } static void LzwResetDecompressor(LzwDecompressor *lzwPtr) { lzwPtr->codeSize = lzwPtr->init_codeSize + 1; lzwPtr->maxnum_code = 1 << lzwPtr->codeSize; lzwPtr->next_tableSlot = lzwPtr->max_dataVal + 3; lzwPtr->fresh = 1; } static void LzwInitDecompressor(Blt_DBuffer dbuffer, int codeSize, LzwDecompressor *lzwPtr) { lzwPtr->init_codeSize = codeSize; lzwPtr->max_dataVal = (1 << codeSize) - 1; lzwPtr->clear_code = lzwPtr->max_dataVal + 1; lzwPtr->end_code = lzwPtr->max_dataVal + 2; /* * The entries in the translation table for true data codes are constant * throughout the stream. We set them now and they never change. */ { int i; for (i = 0; i <= lzwPtr->max_dataVal; ++i) { lzwPtr->table[0][i] = 0; lzwPtr->table[1][i] = i; } } LzwResetDecompressor(lzwPtr); LzwGetCode(dbuffer, 0, TRUE); lzwPtr->dbuffer = dbuffer; lzwPtr->fresh = TRUE; LzwInitStack(lzwPtr, LZW_MAX_CODE * 2); } static void LzwTermDecompressor(LzwDecompressor *lzwPtr) { LzwTermStack(lzwPtr); } /* *--------------------------------------------------------------------------- * * LzwExpandCodeOntoStack -- * * 'incode' is an LZW string code. It represents a string of true data * elements, as defined by the string translation table in *decompP. * * Expand the code to a string of LZW direct codes and push them onto the * stack such that the leftmost code is on top. * * Also add to the translation table where appropriate. * * Results: * If successful, return TRUE. Iff the translation table contains a cycle * (which means the LZW stream from which it was built is invalid), * return FALSE. * *--------------------------------------------------------------------------- */ static int LzwExpandCodeOntoStack(LzwDecompressor *lzwPtr, int incode) { int code; int error; error = FALSE; if (incode < lzwPtr->next_tableSlot) { code = incode; } else { /* It's a code that isn't in our translation table yet */ LzwPushStack(lzwPtr, lzwPtr->firstcode); code = lzwPtr->prevcode; } { /* * Get the whole string that this compression code represents and push * it onto the code stack so the leftmost code is on top. Set * lzwPtr->firstcode to the first (leftmost) code in that string. */ unsigned int stringCount; stringCount = 0; while ((code > lzwPtr->max_dataVal) && (!error)) { if (stringCount > LZW_MAX_CODE) { GifError("contains LZW string loop"); } ++stringCount; LzwPushStack(lzwPtr, lzwPtr->table[1][code]); code = lzwPtr->table[0][code]; } lzwPtr->firstcode = lzwPtr->table[1][code]; LzwPushStack(lzwPtr, lzwPtr->firstcode); } if (lzwPtr->next_tableSlot < LZW_MAX_CODE) { lzwPtr->table[0][lzwPtr->next_tableSlot] = lzwPtr->prevcode; lzwPtr->table[1][lzwPtr->next_tableSlot] = lzwPtr->firstcode; ++lzwPtr->next_tableSlot; if (lzwPtr->next_tableSlot >= lzwPtr->maxnum_code) { /* * We've used up all the codes of the current code size. Future * codes in the stream will have codes one bit longer. But * there's an exception if we're already at the LZW maximum, in * which case the codes will simply continue the same size. */ if (lzwPtr->codeSize < LZW_MAX_BITS) { ++lzwPtr->codeSize; lzwPtr->maxnum_code = 1 << lzwPtr->codeSize; } } } lzwPtr->prevcode = incode; return error == 0; } /* *--------------------------------------------------------------------------- * * LzwReadByte -- * * Returns the next data element of the decompressed image. In the * context of a GIF, a data element is the color table index of one * pixel. * * We read and return the next byte of the decompressed image: * * Results: * Returns -1, if we hit EOF prematurely (i.e. before an "end" code. We * forgive the case that the "end" code is followed by EOF instead of an * EOD marker (zero length DataBlock)). * * Returns -2 if there are no more bytes in the image. * * Returns -3 if we encounter errors in the LZW stream. * *--------------------------------------------------------------------------- */ static int LzwReadByte(LzwDecompressor *lzwPtr) { int code; if (!LzwStackIsEmpty(lzwPtr)) { return LzwPopStack(lzwPtr); } if (lzwPtr->fresh) { lzwPtr->fresh = FALSE; /* * Read off all initial clear codes, read the first non-clear code, * and return it. There are no strings in the table yet, so the next * code must be a direct true data code. */ do { lzwPtr->firstcode = LzwGetCode(lzwPtr->dbuffer, lzwPtr->codeSize, FALSE); lzwPtr->prevcode = lzwPtr->firstcode; } while (lzwPtr->firstcode == lzwPtr->clear_code); return lzwPtr->firstcode; } code = LzwGetCode(lzwPtr->dbuffer, lzwPtr->codeSize, FALSE); if (code < 0) { return code; } if (code == lzwPtr->clear_code) { LzwResetDecompressor(lzwPtr); return LzwReadByte(lzwPtr); } if (code == lzwPtr->end_code) { if (!zeroDataBlock) { /* readThroughEod(lzwPtr->ifP); */ } return -2; } if (!LzwExpandCodeOntoStack(lzwPtr, code)) { return -3; } return LzwPopStack(lzwPtr); } static Blt_Picture GifCreatePictureFromData(Blt_DBuffer dbuffer, Gif *gifPtr) { Pict *destPtr; Blt_Pixel *colormap; LzwDecompressor lzw; int v; int xOffset, yOffset; colormap = (gifPtr->localColorTableFlag) ? gifPtr->localColorTable : gifPtr->globalColorTable; LzwInitDecompressor(dbuffer, gifPtr->lzwMinimumCodeSize, &lzw); destPtr = Blt_CreatePicture(gifPtr->logicalScreenWidth, gifPtr->logicalScreenHeight); if (!gifPtr->transparentColorFlag) { gifPtr->transparentColorIndex = -1; } xOffset = gifPtr->imageLeftPosition; yOffset = gifPtr->imageTopPosition; if ((xOffset > 0) || (yOffset > 0) || (gifPtr->transparentColorFlag)) { Blt_Pixel color; color.u32 = 0x00000000; Blt_BlankPicture(destPtr, &color); } destPtr->delay = gifPtr->delayTime * 10; /* Convert to milliseconds. */ if (destPtr->delay == 0) { destPtr->delay = 100; } if (gifPtr->interlaceFlag) { static int istart[] = { 0, 4, 2, 1 }; static int istep[] = { 8, 8, 4, 2 }; int x, y, pass; pass = 0; x = y = 0; while ((v = LzwReadByte(&lzw)) >= 0) { Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x + xOffset, y + yOffset); dp->u32 = colormap[v].u32; if (v == gifPtr->transparentColorIndex) { dp->Alpha = 0x0; destPtr->flags |= BLT_PIC_MASK; } ++x; if (x == gifPtr->imageWidth) { x = 0; y += istep[pass]; /* 8, 8, 4, 2 */ if (y >= gifPtr->imageHeight) { ++pass; y = istart[pass]; /* 0, 4, 2, 1 */ if (y == 0) { goto done; } } } if (y >= gifPtr->imageHeight) { break; } } } else { Blt_Pixel *destRowPtr; int y; v = 0; /* Suppress compiler warning. */ destRowPtr = destPtr->bits + (yOffset*destPtr->pixelsPerRow) + xOffset; for (y = 0; y < gifPtr->imageHeight; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + gifPtr->imageWidth; dp < dend; dp++) { v = LzwReadByte(&lzw); if (v < 0) { goto done; } dp->u32 = colormap[v].u32; if (v == gifPtr->transparentColorIndex) { dp->Alpha = 0x0; destPtr->flags |= BLT_PIC_MASK; } } destRowPtr += destPtr->pixelsPerRow; } } done: if (v == -3) { GifError("Error in GIF input stream"); } if (LzwReadByte(&lzw) >= 0) { GifWarning("too much input data, ignoring extra..."); } LzwTermDecompressor(&lzw); return destPtr; } static Blt_Picture GifImageDescriptor(Blt_DBuffer dbuffer, Gif *gifPtr) { Blt_Picture picture; GifReadImageDescriptor(dbuffer, gifPtr); if (gifPtr->localColorTableFlag) { GifReadLocalColorTable(dbuffer, gifPtr); } /* Get LZW minimum code size. */ gifPtr->lzwMinimumCodeSize = Blt_DBuffer_NextByte(dbuffer); /* Get Image data */ picture = GifCreatePictureFromData(dbuffer, gifPtr); /* The image block may or may not end in a 0 byte. Skip it if it * exists. */ if (*Blt_DBuffer_Pointer(dbuffer) == 0) { Blt_DBuffer_IncrCursor(dbuffer, 1); } return picture; } /* *--------------------------------------------------------------------------- * * GifToPictures -- * * Reads a GIF file and converts it into a one or more pictures * returned in a list. * * Results: * The picture is returned. If an error occured, such as the * designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain GifToPictures(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, GifImportSwitches *switchesPtr) { Blt_Chain chain; Blt_Picture composite, next; Gif gif; GifMessage message; gifMessagePtr = &message; memset(&gif, 0, sizeof(gif)); /* Clear the structure. */ message.nWarnings = 0; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); Tcl_DStringAppend(&message.errors, "error reading \"", -1); Tcl_DStringAppend(&message.errors, fileName, -1); Tcl_DStringAppend(&message.errors, "\": ", -1); if (setjmp(message.jmpbuf)) { Tcl_DStringResult(interp, &message.errors); Tcl_DStringFree(&message.warnings); return NULL; } if (!GifHeader(dbuffer, &gif)) { GifError("bad GIF header"); } GifReadLogicalScreenDescriptor(dbuffer, &gif); if (gif.globalColorTableFlag) { GifReadGlobalColorTable(dbuffer, &gif); } chain = Blt_Chain_Create(); next = composite = NULL; while (Blt_DBuffer_Cursor(dbuffer) < Blt_DBuffer_Length(dbuffer)) { int byte; Pict *srcPtr; byte = Blt_DBuffer_NextByte(dbuffer); switch (byte) { case '!': /* GIF extension */ GifReadExtensions(dbuffer, &gif); break; case ',': /* Image descriptor. */ srcPtr = GifImageDescriptor(dbuffer, &gif); if (composite == NULL) { next = Blt_ClonePicture(srcPtr); } else { switch (gif.disposalMethod) { case 0: /* Do nothing, blend with background */ case 1: { /* Blend with background */ int delay; delay = srcPtr->delay; /* Blend in the next frame into the current composite. */ Blt_BlendPictures(composite, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); Blt_FreePicture(srcPtr); srcPtr = composite; /* Save a copy of the new composite for the next frame. */ next = Blt_ClonePicture(composite); srcPtr->delay = delay; break; } case 2: { /* Restore background. Don't blend. */ Blt_Pixel pixel; int delay; delay = srcPtr->delay; Blt_BlendPictures(composite, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); Blt_FreePicture(srcPtr); srcPtr = composite; /* Make a copy of the new composite. */ next = Blt_ClonePicture(composite); srcPtr->delay = delay; /* Clear the current region for the next frame. */ pixel.u32 = 0x0; Blt_BlankRegion(next, gif.imageLeftPosition, gif.imageTopPosition, gif.imageWidth, gif.imageHeight, &pixel); break; } case 3: { /* Restore to previous. */ int delay; delay = srcPtr->delay; /* Save a copy of the current composite for the next * frame. */ next = Blt_ClonePicture(composite); /* Blend in the next frame. */ Blt_BlendPictures(composite, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); Blt_FreePicture(srcPtr); srcPtr = composite; srcPtr->delay = delay; break; } default: fprintf(stderr, "unknown disposal method %d\n", gif.disposalMethod); break; } } Blt_Chain_Append(chain, srcPtr); composite = next; break; case ';': /* File terminator */ goto done; default: fprintf(stderr, "ignoring %x at %d of %d\n", byte, (int)Blt_DBuffer_Cursor(dbuffer), (int)Blt_DBuffer_Length(dbuffer)); } } done: if (composite != NULL) { Blt_FreePicture(composite); } if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "GIF_READ_WARNINGS", Tcl_DStringValue(&message.warnings), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); Tcl_DStringFree(&message.errors); return chain; } static int GetLog2(int n) { int i; if (n < 3) { return 1; } for (i = 0; (n >> i) != 0; i++) { /*empty*/ } return i; } /* * Logical Screen Descriptor * * 6 0 2 Logical Screen Width * 8 2 2 Logical Screen Height * 10 4 1 Flags * bit 7 = Global color table flag. * bits 4-6 = Color resolution. * bit 3 = Sort flag. * bits 0-2 = Size of global color table. * 11 5 1 Background Color Index * 12 6 1 Pixel Aspect Ratio */ static void GifWriteLogicalScreenDescriptor(int w, int h, int bitsPerPixel, unsigned char *bp) { unsigned char flags; #define MAXSIZE (1<<16) if ((w >= MAXSIZE) || (h >= MAXSIZE)) { GifError("picture is too big for GIF format"); } if ((bitsPerPixel > 8) || (bitsPerPixel < 1)) { GifError("#bits per pixel is %d for GIF format", bitsPerPixel); } GifSetShort(bp + 0, w); GifSetShort(bp + 2, h); flags = 0; flags |= (1<<7); /* Global color map flag.*/ flags |= (bitsPerPixel - 1) << 4; /* Color resolution. */ flags |= (bitsPerPixel - 1); /* Size of global color table. */ bp[4] = flags; bp[5] = 0; /* Background color index. */ bp[6] = 0; /* Pixel aspect ratio. */ } /* * Image Descriptor * * 0 1 Image Separator * 1 2 Image Left Position * 3 2 Image Top Position * 5 2 Image Width * 7 2 Image Height * 9 1 Image flags: * = Local Color Table Flag 1 Bit * Interlace Flag 1 Bit * Sort Flag 1 Bit * Reserved 2 Bits * Size of Local Color Table 3 Bits */ static void GifWriteImageDescriptor(int w, int h, unsigned char *bp) { bp[0] = ','; /* Image separator */ bp[1] = bp[2] = 0; /* Left offset of image. */ bp[3] = bp[4] = 0; /* Top offset of image. */ GifSetShort(bp + 5, w); /* Width of image. */ GifSetShort(bp + 7, h); /* Height of image. */ bp[9] = 0; /* Flags: no local table, not interlaced, * and unsorted. */ } /* * Graphic Control Extension * * 0 1 Extension Introducer * 1 2 Graphic Control Label * 2 1 Block size * 3 1 Flags. * bits 5-7 Reserved 3 Bits * bits 2-4 Disposal Method 3 Bits * bit 1 User Input Flag 1 Bit * bit 0 Transparent Color Flag 1 Bit * 4 2 Delay time. * 6 1 Transparent Color Index * 7 1 Block terminator */ static void GifWriteGraphicControlExtension(int colorIndex, int delay, unsigned char *bp) { bp[0] = '!'; /* Extension introducer */ bp[1] = 0xF9; /* Graphic control label */ bp[2] = 4; /* Block size. */ bp[3] = (colorIndex != -1); /* Transparent flag. */ GifSetShort(bp + 4, delay); bp[6] = colorIndex; /* Transparent color index */ bp[7] = 0; /* Block terminator */ } /* * Write optional comment block */ static void GifWriteCommentExtension(Blt_DBuffer dbuffer, const char *comment) { int n, length; unsigned char *bp; /* Comment extension and label */ length = strlen(comment); if (length > 255) { length = 255; } n = 3 + length + 1; bp = Blt_DBuffer_Extend(dbuffer, n); bp[0] = '!'; bp[1] = 0xFE; bp[2] = length; memcpy(bp + 3, comment, length); bp[n - 1] = '\0'; } /* * Graphic Control Extension * * 0 1 Extension Introducer * 1 2 Graphic Control Label * 2 1 Block size * 3 1 Flags. * bits 5-7 Reserved 3 Bits * bits 2-4 Disposal Method 3 Bits * bit 1 User Input Flag 1 Bit * bit 0 Transparent Color Flag 1 Bit * 4 2 Delay time. * 6 1 Transparent Color Index * 7 1 Block terminator */ static void GifWriteNetscapeAppExtension(int nLoop, unsigned char *bp) { bp[0] = '!'; /* Extension introducer */ bp[1] = 0xFF; /* Application extension label */ bp[2] = 11; /* Block size. */ memcpy(bp + 3, "NETSCAPE2.0", 11); bp[14] = 0x3; /* Length of data sub-block */ bp[15] = 0x1; bp[16] = 0xFF; bp[17] = 0xFF; bp[18] = 0; /* Block terminator */ } #define DICTSIZE 5003 /* 80% occupancy */ #define MAXCODE(n) ((1 << (n)) - 1) typedef struct { int fcode; unsigned int ent; } LzwDictEntry; typedef struct { int nBits; int maxCode; int codeLimit; LzwDictEntry dict[DICTSIZE]; int ent; int hshift; int nextUnusedCode; int codeCount; int initBits; int clearCode; int eofCode; unsigned int curAccum; int curBits; unsigned char accum[256]; int a_count; Blt_DBuffer dbuffer; } LzwCompressor; static void LzwDictShift(LzwCompressor *lzwPtr) { int hshift; int fcode; hshift = 0; for (fcode = DICTSIZE; fcode < 65536L; fcode += fcode) { hshift++; } lzwPtr->hshift = 8 - hshift; /* set hash code range bound */ } static void LzwDictInit(LzwCompressor *lzwPtr) { LzwDictEntry *hp, *hend; for (hp = lzwPtr->dict, hend = hp + DICTSIZE; hp < hend; hp++) { hp->fcode = -1; hp->ent = 0; } lzwPtr->nextUnusedCode = lzwPtr->clearCode + 2; } /* * Flush the packet to disk, and reset the accumulator */ INLINE static void LzwFlush(LzwCompressor *lzwPtr) { if(lzwPtr->a_count > 0) { unsigned char *bp; bp = Blt_DBuffer_Extend(lzwPtr->dbuffer, lzwPtr->a_count + 1); bp[0] = lzwPtr->a_count; memcpy(bp + 1, lzwPtr->accum, lzwPtr->a_count); lzwPtr->a_count = 0; } } /* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ INLINE static void LzwAccum(LzwCompressor *lzwPtr, unsigned char byte) { lzwPtr->accum[lzwPtr->a_count] = byte; lzwPtr->a_count++; if(lzwPtr->a_count >= 254) { LzwFlush(lzwPtr); } } INLINE static void LzwSetCodeSize(LzwCompressor *lzwPtr, int nBits) { lzwPtr->nBits = nBits; assert(nBits <= LZW_MAX_BITS); lzwPtr->maxCode = MAXCODE(nBits); } INLINE static void LzwIncrCodeSize(LzwCompressor *lzwPtr) { assert((lzwPtr->nBits + 1) <= LZW_MAX_BITS); LzwSetCodeSize(lzwPtr, lzwPtr->nBits + 1); } INLINE static void LzwAdjustCodeSize(LzwCompressor *lzwPtr) { assert(lzwPtr->nextUnusedCode <= lzwPtr->codeLimit); if (lzwPtr->nextUnusedCode == lzwPtr->codeLimit) { lzwPtr->codeLimit += lzwPtr->codeLimit; LzwIncrCodeSize(lzwPtr); } lzwPtr->nextUnusedCode++; assert(lzwPtr->codeLimit <= LZW_MAX_CODE); } static int LzwDictSearch(LzwCompressor *lzwPtr, int pixel) { int hval; int fcode; int disp; LzwDictEntry *hPtr; fcode = (int) ((pixel << LZW_MAX_BITS) + lzwPtr->ent); hval = ((pixel << lzwPtr->hshift) ^ lzwPtr->ent); /* XOR hashing */ /* Secondary hash (after G. Knott) */ disp = (hval == 0) ? 1 : DICTSIZE - hval; while ((lzwPtr->dict[hval].fcode != fcode) && (lzwPtr->dict[hval].fcode >= 0)) { hval -= disp; if (hval < 0) { hval += DICTSIZE; } } hPtr = lzwPtr->dict + hval; if (hPtr->fcode == fcode ) { lzwPtr->ent = hPtr->ent; return TRUE; } else { hPtr->ent = lzwPtr->nextUnusedCode; hPtr->fcode = fcode; return FALSE; } } static void LzwPutCode(LzwCompressor *lzwPtr, int code) { assert(code <= lzwPtr->maxCode); lzwPtr->curAccum &= (1 << lzwPtr->curBits) - 1; if (lzwPtr->curBits > 0) { lzwPtr->curAccum |= ((unsigned long)code << lzwPtr->curBits); } else { lzwPtr->curAccum = code; } lzwPtr->curBits += lzwPtr->nBits; while (lzwPtr->curBits >= 8) { LzwAccum(lzwPtr, (unsigned int)lzwPtr->curAccum & 0xff); lzwPtr->curAccum >>= 8; lzwPtr->curBits -= 8; } lzwPtr->codeCount++; } static void LzwResetCompressor(LzwCompressor *lzwPtr) { LzwDictInit(lzwPtr); /* Clear out the hash table */ LzwPutCode(lzwPtr, lzwPtr->clearCode); LzwSetCodeSize(lzwPtr, lzwPtr->initBits); lzwPtr->codeLimit = (1 << lzwPtr->initBits); } static void LzwOutputCurrent(LzwCompressor *lzwPtr) { LzwPutCode(lzwPtr, lzwPtr->ent); /* * If the next entry is going to be too big for the code size, then * increase it, if possible. */ if (lzwPtr->nextUnusedCode < LZW_MAX_CODE) { LzwAdjustCodeSize(lzwPtr); } else { LzwResetCompressor(lzwPtr); } if (lzwPtr->ent == lzwPtr->eofCode) { /* At EOF, write the rest of the buffer. */ while (lzwPtr->curBits > 0) { LzwAccum(lzwPtr, (unsigned int)lzwPtr->curAccum & 0xff); lzwPtr->curAccum >>= 8; lzwPtr->curBits -= 8; } LzwFlush(lzwPtr); } } static void GifWriteGlobalColorTable(Blt_HashTable *colorTablePtr, unsigned char *bp) { unsigned long index; Blt_HashEntry *hPtr; Blt_HashSearch cursor; index = 0; for (hPtr = Blt_FirstHashEntry(colorTablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { union { unsigned long index; char *key; } value; Blt_Pixel pixel; Blt_SetHashValue(hPtr, index); value.key = Blt_GetHashKey(colorTablePtr, hPtr); pixel.u32 = (unsigned int)value.index; bp[0] = pixel.Red; bp[1] = pixel.Green; bp[2] = pixel.Blue; bp += 3; index++; } } static int GetColorIndex(Blt_HashTable *colorTablePtr, Blt_Pixel *colorPtr) { Blt_HashEntry *hPtr; Blt_Pixel pixel; int index; int nColors; union { unsigned long pixel; char *key; } value; nColors = colorTablePtr->numEntries; pixel.u32 = colorPtr->u32; pixel.Alpha = 0xFF; value.pixel = pixel.u32; hPtr = Blt_FindHashEntry(colorTablePtr, value.key); if (hPtr == NULL) { GifError("can't find color %x,%x,%x in color table\n", colorPtr->Red, colorPtr->Blue, colorPtr->Green); } if (colorPtr->Alpha == 0x00) { index = (int)nColors; } else { index = (unsigned long)Blt_GetHashValue(hPtr); } return index; } static void GifAddText(Blt_DBuffer dbuffer, const char **comments) { const char **p; for (p = comments; *p != NULL; p++) { GifWriteCommentExtension(dbuffer, *p); } } static void GifWriteImageData(Blt_DBuffer dbuffer, Pict *srcPtr, Blt_HashTable *colorTablePtr) { LzwCompressor lzw; int initBits; int initCodeSize; int bitsPerPixel; bitsPerPixel = GetLog2(colorTablePtr->numEntries - 1); assert((bitsPerPixel > 0) && (bitsPerPixel <= 8)); /* bitsPerPixel = (colorMapSize == 1) ? 1 : ns(colorMapSize - 1); initCodeSize = bitsPerPixel <= 1 ? 2 : bitsPerPixel; initBits = initCodeSize + 1; clearCode = 1 << (initBits - 1); */ initCodeSize = (bitsPerPixel <= 1) ? 2 : bitsPerPixel; initBits = bitsPerPixel + 1; memset(&lzw, 0, sizeof(lzw)); /* * Set up the globals: initBits - initial number of bits */ lzw.initBits = initBits; lzw.curAccum = 0; lzw.curBits = 0; lzw.dbuffer = dbuffer; /* Set up the necessary values */ lzw.codeCount = 0; lzw.nBits = lzw.initBits; lzw.maxCode = MAXCODE(lzw.nBits); lzw.clearCode = (1 << (initBits - 1)); lzw.eofCode = lzw.clearCode + 1; lzw.nextUnusedCode = lzw.clearCode + 2; lzw.codeLimit = (1 << initBits); lzw.a_count = 0; LzwDictShift(&lzw); Blt_DBuffer_AppendByte(dbuffer, initCodeSize); LzwResetCompressor(&lzw); /* Add compressed image data. */ { Blt_Pixel *srcRowPtr, *sp; int y; sp = srcRowPtr = srcPtr->bits; lzw.ent = GetColorIndex(colorTablePtr, sp); sp++; for(y = 0; y < srcPtr->height; y++) { Blt_Pixel *send; for (send = srcRowPtr + srcPtr->width; sp < send; sp++) { unsigned long index; index = GetColorIndex(colorTablePtr, sp); if (!LzwDictSearch(&lzw, index)) { LzwOutputCurrent(&lzw); lzw.ent = index; } } srcRowPtr += srcPtr->pixelsPerRow; sp = srcRowPtr; } } /* Put out the final code and sub-block terminator. */ LzwOutputCurrent(&lzw); lzw.ent = lzw.eofCode; LzwOutputCurrent(&lzw); Blt_DBuffer_AppendByte(dbuffer, '\0'); /* Mark end of data sub-blocks. */ } /* *--------------------------------------------------------------------------- * * PictureToGif -- * * Converts a picture to the GIF format. Since the GIF format doesn't * handle semi-transparent pixels we have to blend the image with a given * background color, while still retaining any 100% transparent pixels. * * Results: * A standard TCL result is returned. If an error occured, * such as the designated file could not be opened, TCL_ERROR is returned. * * Side Effects: * The dynamic buffer is filled with the GIF image. * *--------------------------------------------------------------------------- */ static int PictureToGif(Tcl_Interp *interp, Blt_Picture original, Blt_DBuffer dbuffer, GifExportSwitches *switchesPtr) { Blt_HashTable colorTable; Pict *srcPtr; int bitsPerPixel; int isMasked; int n; int nColors, maxColors; unsigned char *bp; srcPtr = original; if ((srcPtr->width < 1) || (srcPtr->height < 1)) { return TCL_OK; } nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); maxColors = 256; if (Blt_PictureIsMasked(srcPtr)) { if (switchesPtr->flags & EXPORT_BLEND) { Blt_Picture background; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlankPicture(background, &switchesPtr->bg); Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = background; nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); } else if (nColors >= 256) { maxColors--; } } if (nColors > maxColors) { Blt_Picture quant; quant = Blt_QuantizePicture(srcPtr, maxColors); if (srcPtr != original) { Blt_FreePicture(srcPtr); } srcPtr = quant; } Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); nColors = Blt_QueryColors(srcPtr, &colorTable); isMasked = Blt_PictureIsMasked(srcPtr); bitsPerPixel = GetLog2(nColors - 1); /* * 6 Header * 7 Logical Screen Descriptor * 3 * (1<<bitPerPixel) Global Color Table * 8 Graphic Control Extension * 10 Image Descriptor */ n = 6 + 7 + (3 * (1<<bitsPerPixel)) + 10; if (isMasked) { n += 8; } bp = Blt_DBuffer_Extend(dbuffer, n); /* Header */ if (isMasked) { memcpy(bp, "GIF89a", 6); } else { memcpy(bp, "GIF87a", 6); } bp += 6; /* Size of header */ GifWriteLogicalScreenDescriptor(srcPtr->width, srcPtr->height, bitsPerPixel, bp); bp += 7; /* Size of logical screen * descriptor. */ GifWriteGlobalColorTable(&colorTable, bp); bp += 3 * (1<<bitsPerPixel); /* Size of global color table. */ if (isMasked) { GifWriteGraphicControlExtension(nColors, 0, bp); bp += 8; /* size of graphic control * extension. */ } GifWriteImageDescriptor(srcPtr->width, srcPtr->height, bp); bp += 10; /* Size of image descriptor. */ GifWriteImageData(dbuffer, srcPtr, &colorTable); if (switchesPtr->comments != NULL) { GifAddText(dbuffer, switchesPtr->comments); } Blt_DBuffer_AppendByte(dbuffer, ';'); /* File terminator */ if (srcPtr != original) { Blt_FreePicture(srcPtr); } return TCL_OK; } #ifndef notdef /* *--------------------------------------------------------------------------- * * PicturesToAnimatedGif -- * * Converts a one or more pictures to into the animates GIF format. * Since the GIF format doesn't handle semi-transparent pixels we have to * blend the image with a given background color, while still retaining * any 100% transparent pixels. * * Results: * A standard TCL result is returned. If an error occured, such as the * designated file could not be opened, TCL_ERROR is returned. * * Side Effects: * The dynamic buffer is filled with the GIF image. * *--------------------------------------------------------------------------- */ static int PicturesToAnimatedGif(Tcl_Interp *interp, Blt_Chain chain, Blt_DBuffer dbuffer, GifExportSwitches *switchesPtr) { Blt_ChainLink link; Blt_HashTable colorTable; Frame *fp, *fend, *frames; int bitsPerPixel; int n; int nColors, maxColors, nFrames; int screenWidth, screenHeight; unsigned char *bp; /* For each frame quantize if needed, accumulate the colors used. try to * assemble */ maxColors = 255; nFrames = Blt_Chain_GetLength(chain); if (nFrames == 0) { return TCL_ERROR; } frames = Blt_AssertCalloc(nFrames, sizeof(Frame)); link = Blt_Chain_FirstLink(chain); fp = frames; fp->original = Blt_Chain_GetValue(link); /* * Step 1: Load the pictures into the array. Determine what the * maximum picture width and height are. */ screenWidth = Blt_PictureWidth(fp->original); screenHeight = Blt_PictureHeight(fp->original); for (fp = frames, link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link), fp++) { Pict *srcPtr; srcPtr = fp->current = fp->original = Blt_Chain_GetValue(link); fp->delay = srcPtr->delay; if (srcPtr->width > screenWidth) { screenWidth = srcPtr->width; } if (srcPtr->height > screenHeight) { screenHeight = srcPtr->height; } } /* * Step 2: Convert the pictures into the same maximum size. Automatically * handle blended pictures by blending into a known background. */ Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); for (fp = frames, fend = fp + nFrames; fp < fend; fp++) { Pict *srcPtr; srcPtr = fp->current; if ((srcPtr->flags & BLT_PIC_BLEND) || (srcPtr->width != screenWidth) || (srcPtr->height != screenHeight)) { Pict *bg; /* Blend picture with solid color background. */ bg = Blt_CreatePicture(screenWidth, screenHeight); Blt_BlankPicture(bg, &switchesPtr->bg); Blt_BlendPictures(bg, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); srcPtr = fp->current = bg; } Blt_QueryColors(srcPtr, &colorTable); } /* * Step 3: If there are more that 256 colors, compute color lookup * table by quantizing all the pictures in the sequence. */ if (colorTable.numEntries > maxColors) { Blt_Chain sequence; Blt_ColorLookupTable clut; sequence = Blt_Chain_Create(); for (fp = frames, fend = fp + nFrames; fp < fend; fp++) { Blt_Chain_Append(sequence, fp->current); } clut = Blt_GetColorLookupTable(sequence, maxColors); Blt_Chain_Destroy(sequence); /* Dump the old color table and build a new old. */ Blt_DeleteHashTable(&colorTable); Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); for (fp = frames, fend = fp + nFrames; fp < fend; fp++) { Pict *srcPtr, *destPtr; srcPtr = fp->current; destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_MapColors(destPtr, srcPtr, clut); if (fp->current != fp->original) { Blt_FreePicture(fp->current); } fp->current = destPtr; Blt_QueryColors(destPtr, &colorTable); } Blt_Free(clut); } /* * Step 4: Write the animated GIF output. */ nColors = colorTable.numEntries; bitsPerPixel = GetLog2(nColors - 1); /* * 6 Header * 7 Logical Screen Descriptor * 3 * (1<<bitPerPixel) Global Color Table * 8 Graphic Control Extension * 10 Image Descriptor */ n = 6 + 7 + (3 * (1<<bitsPerPixel)) + 19; bp = Blt_DBuffer_Extend(dbuffer, n); /* Header */ memcpy(bp, "GIF89a", 6); bp += 6; /* Size of header */ GifWriteLogicalScreenDescriptor(screenWidth, screenHeight, bitsPerPixel, bp); bp += 7; /* Size of logical screen * descriptor. */ GifWriteGlobalColorTable(&colorTable, bp); bp += 3 * (1<<bitsPerPixel); /* Size of global color table. */ GifWriteNetscapeAppExtension(10, bp); bp += 19; for (fp = frames, fend = fp + nFrames; fp < fend; fp++) { Pict *srcPtr; bp = Blt_DBuffer_Extend(dbuffer, 18); srcPtr = fp->current; GifWriteGraphicControlExtension(-1, switchesPtr->delay, bp); bp += 8; /* Size of graphic control * extension. */ GifWriteImageDescriptor(srcPtr->width, srcPtr->height, bp); bp += 10; /* Size of image descriptor. */ GifWriteImageData(dbuffer, srcPtr, &colorTable); if (fp->current != fp->original) { Blt_FreePicture(fp->current); } } Blt_Free(frames); Blt_DeleteHashTable(&colorTable); if (switchesPtr->comments != NULL) { GifAddText(dbuffer, switchesPtr->comments); } Blt_DBuffer_AppendByte(dbuffer, ';'); /* File terminator */ return TCL_OK; } #endif /* *--------------------------------------------------------------------------- * * IsGif -- * * Attempts to parse a GIF file header. * * Results: * Returns 1 is the header is GIF and 0 otherwise. Note that the * validity of the header contents is not checked here. That's done in * GifToPictures. * *--------------------------------------------------------------------------- */ static int IsGif(Blt_DBuffer dbuffer) { Gif gif; int bool; bool = GifHeader(dbuffer, &gif); return bool; } static Blt_Chain ReadGif(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { GifImportSwitches switches; memset(&switches, 0, sizeof(switches)); return GifToPictures(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WriteGif(Tcl_Interp *interp, Blt_Picture picture) { Blt_DBuffer dbuffer; GifExportSwitches switches; Tcl_Obj *objPtr; char *bytes; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); dbuffer = Blt_DBuffer_Create(); objPtr = NULL; if (PictureToGif(interp, picture, dbuffer, &switches) != TCL_OK) { Blt_DBuffer_Destroy(dbuffer); return NULL; } bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } Blt_DBuffer_Destroy(dbuffer); return objPtr; } static Blt_Chain ImportGif(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_DBuffer dbuffer; Blt_Chain chain; const char *string; GifImportSwitches switches; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_SaveFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = GifToPictures(interp, string, dbuffer, &switches); if (chain == NULL) { fprintf(stderr, "import gif: can't read buffer\n"); } error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportGif(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer dbuffer; GifExportSwitches switches; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.index = index; switches.delay = 20; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } dbuffer = Blt_DBuffer_Create(); if (switches.flags & EXPORT_ANIMATE) { if (PicturesToAnimatedGif(interp, chain, dbuffer, &switches) != TCL_OK){ Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } } else { Blt_Picture picture; picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "bad picture index.", (char *)NULL); goto error; } if (PictureToGif(interp, picture, dbuffer, &switches) != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } } if (switches.fileObjPtr != NULL) { const char *fileName; /* Write the image into the designated file. */ fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; /* Write the image into the designated TCL variable. */ objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; /* Return the image as a base64 string in the interpreter result. */ result = TCL_ERROR; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); result = TCL_OK; } } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PictureGifInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_gif", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "gif", /* Name of format. */ IsGif, /* Discovery routine. */ ReadGif, /* Read format procedure. */ WriteGif, /* Write format procedure. */ ImportGif, /* Import format procedure. */ ExportGif); /* Export format switches. */ } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacWindow.c����������������������������������������������������������������0000644�0001750�0001750�00000031017�11462120062�015565� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSXWindow.c -- * * This module implements additional window functionality for the BLT * toolkit, such as transparent Tk windows, and reparenting Tk * windows. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <X11/Xlib.h> #include "tkDisplay.h" /* *--------------------------------------------------------------------------- * * DoConfigureNotify -- * * Generate a ConfigureNotify event describing the current * configuration of a window. * * Results: * None. * * Side effects: * An event is generated and processed by Tk_HandleEvent. * *--------------------------------------------------------------------------- */ static void DoConfigureNotify(winPtr) Tk_FakeWin *winPtr; /* Window whose configuration was just * changed. */ { XEvent event; event.type = ConfigureNotify; event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); event.xconfigure.send_event = False; event.xconfigure.display = winPtr->display; event.xconfigure.event = winPtr->window; event.xconfigure.window = winPtr->window; event.xconfigure.x = winPtr->changes.x; event.xconfigure.y = winPtr->changes.y; event.xconfigure.width = winPtr->changes.width; event.xconfigure.height = winPtr->changes.height; event.xconfigure.border_width = winPtr->changes.border_width; if (winPtr->changes.stack_mode == Above) { event.xconfigure.above = winPtr->changes.sibling; } else { event.xconfigure.above = None; } event.xconfigure.override_redirect = winPtr->atts.override_redirect; Tk_HandleEvent(&event); } /* *--------------------------------------------------------------------------- * * Blt_MakeTransparentWindowExist -- * * Similar to Tk_MakeWindowExist but instead creates a * transparent window to block for user events from sibling * windows. * * Differences from Tk_MakeWindowExist. * * 1. This is always a "busy" window. There's never a * platform-specific class procedure to execute instead. * 2. The window is transparent and never will contain children, * so colormap information is irrelevant. * * Results: * None. * * Side effects: * When the procedure returns, the internal window associated * with tkwin is guaranteed to exist. This may require the * window's ancestors to be created too. * *--------------------------------------------------------------------------- */ void Blt_MakeTransparentWindowExist(Tk_Window tkwin, Window parent, int isBusy) { TkWindow *winPtr = (TkWindow *)tkwin; TkWindow *winPtr2; Tcl_HashEntry *hPtr; int notUsed; TkDisplay *dispPtr; long int mask; if (winPtr->window != None) { return; /* Window already exists. */ } /* Create a transparent window and put it on top. */ mask = (!isBusy) ? 0 : (CWDontPropagate | CWEventMask); /* Ignore the important events while the window is mapped. */ #define USER_EVENTS (EnterWindowMask | LeaveWindowMask | KeyPressMask | \ KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ PointerMotionMask) #define PROP_EVENTS (KeyPressMask | KeyReleaseMask | ButtonPressMask | \ ButtonReleaseMask | PointerMotionMask) winPtr->atts.do_not_propagate_mask = PROP_EVENTS; winPtr->atts.event_mask = USER_EVENTS; winPtr->changes.border_width = 0; winPtr->depth = 0; #ifdef notdef winPtr->window = XCreateWindow(winPtr->display, parent, winPtr->changes.x, winPtr->changes.y, (unsigned)winPtr->changes.width, /* width */ (unsigned)winPtr->changes.height, /* height */ (unsigned)winPtr->changes.border_width, /* border_width */ winPtr->depth, /* depth */ InputOnly, /* class */ winPtr->visual, /* visual */ mask, /* valuemask */ &winPtr->atts /* attributes */ ); #endif dispPtr = winPtr->dispPtr; hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *)winPtr->window, &notUsed); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; #ifdef TK_USE_INPUT_METHODS winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (!(winPtr->flags & TK_TOP_LEVEL)) { /* * If any siblings higher up in the stacking order have already * been created then move this window to its rightful position * in the stacking order. * * NOTE: this code ignores any changes anyone might have made * to the sibling and stack_mode field of the window's attributes, * so it really isn't safe for these to be manipulated except * by calling Tk_RestackWindow. */ for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; winPtr2 = winPtr2->nextPtr) { if ((winPtr2->window != None) && !(winPtr2->flags & TK_TOP_LEVEL)) { XWindowChanges changes; changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, CWSibling | CWStackMode, &changes); break; } } } /* * Issue a ConfigureNotify event if there were deferred configuration * changes (but skip it if the window is being deleted; the * ConfigureNotify event could cause problems if we're being called * from Tk_DestroyWindow under some conditions). */ if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) && !(winPtr->flags & TK_ALREADY_DEAD)) { winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; DoConfigureNotify((Tk_FakeWin *) tkwin); } } Window Blt_GetParentWindow(Display *display, Window window) { Window root, parent; Window *dummy; unsigned int count; if (XQueryTree(display, window, &root, &parent, &dummy, &count) > 0) { XFree(dummy); return parent; } return None; } /* *--------------------------------------------------------------------------- * * Blt_GetWindowId -- * * Returns the XID for the Tk_Window given. Starting in Tk 8.0, * the toplevel widgets are wrapped by another window. Currently * there's no way to get at that window, other than what is done * here: query the X window hierarchy and retrieve the parent. * * Results: * Returns the X Window ID of the widget. If it's a toplevel, then * the XID of the wrapper is returned. * *--------------------------------------------------------------------------- */ Window Blt_GetWindowId(Tk_Window tkwin) { Window window; Tk_MakeWindowExist(tkwin); window = Tk_WindowId(tkwin); if (Tk_IsTopLevel(tkwin)) { Window parent; parent = Blt_GetParentWindow(Tk_Display(tkwin), window); if (parent != None) { window = parent; } window = parent; } return window; } /* *--------------------------------------------------------------------------- * * XGeometryErrorProc -- * * Flags errors generated from XGetGeometry calls to the X server. * * Results: * Always returns 0. * * Side Effects: * Sets a flag, indicating an error occurred. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int XGeometryErrorProc(clientData, errEventPtr) ClientData clientData; XErrorEvent *errEventPtr; { int *errorPtr = clientData; *errorPtr = FALSE; return 0; } int Blt_GetWindowRegion( Display *display, Window window, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr) { Tk_ErrorHandler handler; Window root; int any = -1; int result; int x, y; unsigned int width, height, borderWidth, depth; #ifdef notdef handler = Tk_CreateErrorHandler(display, any, X_GetGeometry, any, XGeometryErrorProc, &result); #endif result = XGetGeometry(display, window, &root, &x, &y, &width, &height, &borderWidth, &depth); Tk_DeleteErrorHandler(handler); XSync(display, False); if (!result) { return TCL_ERROR; } if (xPtr != NULL) { *xPtr = x; } if (yPtr != NULL) { *yPtr = y; } if (widthPtr != NULL) { *widthPtr = (int)width; } if (heightPtr != NULL) { *heightPtr = (int)height; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_RaiseToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_RaiseToplevelWindow(Tk_Window tkwin) { XRaiseWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_LowerToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_LowerToplevelWindow(Tk_Window tkwin) { XLowerWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_ResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_ResizeToplevelWindow(Tk_Window tkwin, int width, int height) { XResizeWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), width, height); } /* *--------------------------------------------------------------------------- * * Blt_MoveResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MoveResizeToplevelWindow(Tk_Window tkwin, int x, int y, int w, int h) { XMoveResizeWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), x, y, w, h); } /* *--------------------------------------------------------------------------- * * Blt_ResizeToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MoveToplevelWindow(Tk_Window tkwin, int x, int y) { XMoveWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin), x, y); } /* *--------------------------------------------------------------------------- * * Blt_MapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_MapToplevelWindow(Tk_Window tkwin) { XMapWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* *--------------------------------------------------------------------------- * * Blt_UnmapToplevelWindow -- * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_UnmapToplevelWindow(Tk_Window tkwin) { XUnmapWindow(Tk_Display(tkwin), Blt_GetWindowId(tkwin)); } /* ARGSUSED */ static int XReparentWindowErrorProc(clientData, errEventPtr) ClientData clientData; XErrorEvent *errEventPtr; { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } int Blt_ReparentWindow( Display *display, Window window, Window newParent, int x, int y) { Tk_ErrorHandler handler; int result; int any = -1; result = TCL_OK; #ifdef notdef handler = Tk_CreateErrorHandler(display, any, X_ReparentWindow, any, XReparentWindowErrorProc, &result); #endif XReparentWindow(display, window, newParent, x, y); Tk_DeleteErrorHandler(handler); XSync(display, False); return result; } int Blt_GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr) { char *string; string = Tcl_GetString(objPtr); if (string[0] == '.') { Tk_Window tkwin; tkwin = Tk_NameToWindow(Tcl_GetString(objPtr), interp, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } *windowPtr = (Tk_IsTopLevel(tkwin)) ? Blt_GetWindowId(tkwin) : Tk_WindowId(tkwin); } else { int id; if (Tcl_GetIntFromObj(interp, objPtr, &id) != TCL_OK) { return TCL_ERROR; } *windowPtr = (Window)id; } return TCL_OK; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictMmx.c������������������������������������������������������������������0000644�0001750�0001750�00000201342�11462120062�015256� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictMMX.c -- * * This module implements image processing procedures for the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltPicture.h" #include "bltPictInt.h" #ifdef HAVE_X86_ASM static Blt_ApplyPictureToPictureProc ApplyPictureToPicture; static Blt_ApplyScalarToPictureProc ApplyScalarToPicture; #ifdef notdef static Blt_ApplyPictureToPictureWithMaskProc ApplyPictureToPictureWithMask; static Blt_ApplyScalarToPictureWithMaskProc ApplyScalarToPictureWithMask; #endif static Blt_TentHorizontallyProc TentHorizontally; static Blt_TentVerticallyProc TentVertically; static Blt_ZoomHorizontallyProc ZoomHorizontally; static Blt_ZoomVerticallyProc ZoomVertically; static Blt_BlendPicturesProc BlendPictures; static Blt_SelectPixelsProc SelectPixels; static Blt_AssociateColorsProc AssociateColors; static Blt_UnassociateColorsProc UnassociateColors; static Blt_FadePictureProc FadePicture; static Blt_CopyPictureBitsProc CopyPictureBits; static Blt_PictureProcs mmxPictureProcs = { ApplyPictureToPicture, ApplyScalarToPicture, NULL, /* ApplyPictureToPictureWithMask, */ NULL, /* ApplyScalarToPictureWithMask, */ TentHorizontally, TentVertically, ZoomHorizontally, ZoomVertically, BlendPictures, SelectPixels, AssociateColors, UnassociateColors, NULL, /*FadePicture*, */ CopyPictureBits }; static void SelectPixels( Pict *destPtr, Pict *srcPtr, Blt_Pixel *lowerPtr, Blt_Pixel *upperPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if (srcPtr != destPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); } asm volatile ( /* Put lower and upper pixels in registers. */ "movd %0, %%mm4 # mm4 = L\n\t" "movd %1, %%mm5 # mm5 = H\n\t" "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "punpckldq %%mm4, %%mm4 # mm4 = L,L\n\t" "punpckldq %%mm5, %%mm5 # mm5 = H,H\n\t" : /* output registers */ : /* input registers */ "r" (lowerPtr->u32), "r" (upperPtr->u32)); destRowPtr = destPtr->bits, srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp, *sp, *send; dp = destRowPtr; for(sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp += 2) { asm volatile ( /* Compare two pixels at a time */ "movq (%1), %%mm3 # mm3 = S1,S2\n\t" "movq %%mm4, %%mm0 # mm0 = L,L\n\t" /* We want to test (S >= L) && (S <= H). Since the operands * are all unsigned, pcmp* ops are out. Instead use * saturated, unsigned subtraction. ((L psub S) == 0) is the * same as (S >= L) */ "psubusb %%mm3, %%mm0 # mm0 = L - S\n\t" "movq %%mm3, %%mm1 # mm1 = S\n\t" "psubusb %%mm5, %%mm1 # mm1 = S - H\n\t" /* "or" the two results and compare 32-bit values to 0 * (inverting the logic). */ "por %%mm1, %%mm0 # mm0 = (S >= L)|(H >= S)\n\t" "pcmpeqd %%mm6, %%mm0 # invert logic\n\t" "movq %%mm0, (%0) # dp = new value\n" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); dp += 2; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } asm volatile ("emms"); destPtr->flags &= ~BLT_PIC_BLEND; destPtr->flags |= BLT_PIC_MASK; } static void AddPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "paddusb (%1), %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void SubPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "psubusb (%1), %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void RSubPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%1), %%mm1\n\t" "psubusb (%0), %%mm1\n\t" "movq %%mm1, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void AndPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "pand (%1), %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void OrPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "por (%1), %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void NandPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "pand (%1), %%mm0\n\t" "pxor %%mm7, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (dp) : /* input registers */ "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void NorPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "por (%1), %%mm0\n\t" "pxor %%mm7, %%mm0\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (dp) /* input registers */ : "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void XorPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0\n\t" "pxor (%1), %%mm0\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (dp) /* input registers */ : "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void MinPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0 # mm0 = A\n\t" "movq (%1), %%mm1 # mm1 = B\n\t" "movq %%mm0, %%mm2 # mm2 = A\n\t" "psubusb %%mm1, %%mm2 # mm2 = A - B\n\t" "pcmpeqb %%mm6, %%mm2 # mm2 = 0s A>B 1s A<=B\n\t" "pand %%mm2, %%mm0 # mm2 = mask & A\n\t" "pxor %%mm7, %%mm2 # mm2 = ~mask\n\t" "pand %%mm2, %%mm1 # mm0 = ~mask & B\n\t" "por %%mm1, %%mm0 # mm0 = R1 | R2\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (dp) /* input registers */ : "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void MaxPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm7, %mm7 # mm5 = -1 \n"); destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp += 2, sp += 2) { asm volatile ( "movq (%0), %%mm0 # mm0 = A\n\t" "movq (%1), %%mm1 # mm1 = B\n\t" "movq %%mm0, %%mm2 # mm2 = A\n\t" "psubusb %%mm1, %%mm2 # mm2 = A - B\n\t" "pcmpeqb %%mm6, %%mm2 # mm2 = 0s A>B 1s A<=B\n\t" "pand %%mm2, %%mm1 # mm1 = mask & B\n\t" "pxor %%mm7, %%mm2 # mm2 = ~mask\n\t" "pand %%mm2, %%mm0 # mm0 = ~mask & A\n\t" "por %%mm1, %%mm0 # mm3 = R1 | R2\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (dp) /* input registers */ : "r" (sp)); } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void ApplyPictureToPicture( Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy, Blt_PictureArithOps op) { if ((x + w) > srcPtr->width) { w -= srcPtr->width - x; } if ((y + h) > srcPtr->height) { h -= srcPtr->height - y; } if ((dx + w) > destPtr->width) { w -= destPtr->width - dx; } if ((dy + h) > destPtr->height) { h -= destPtr->height - dy; } switch(op) { case PIC_ARITH_ADD: AddPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_SUB: SubPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_RSUB: RSubPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_AND: AndPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_OR: OrPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_NAND: NandPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_NOR: NorPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_XOR: XorPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_MIN: MinPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; case PIC_ARITH_MAX: MaxPictureToPicture(destPtr, srcPtr, x, y, w, h, dx, dy); break; } } static void ApplyScalarToPicture( Pict *srcPtr, Blt_Pixel *colorPtr, Blt_PictureArithOps op) { Blt_Pixel *srcRowPtr; int y; /* * mm7 = -1 * mm6 = 0x0 * mm4 = scalar,scalar */ asm volatile ( /* Generate constants needed below. */ "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "pcmpeqw %%mm7, %%mm7 # mm5 = -1 \n\t" /* Put the scalar into hi/lo 32-bit words.*/ "movd %0, %%mm4 # mm4 = scalar\n\t" "punpckldq %%mm4, %%mm4 # mm2 = S,S\n" /* output registers */ : /* input registers */ : "r" (colorPtr->u32)); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; sp = srcRowPtr; send = sp + srcPtr->width; switch(op) { case PIC_ARITH_ADD: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "paddusb %%mm4, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_SUB: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "psubusb %%mm4, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_RSUB: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "movq %%mm4, %%mm1\n\t" "psubusb %%mm0, %%mm1\n\t" "movq %%mm1, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_AND: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "pand %%mm4, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_OR: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "por %%mm4, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_NAND: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "pand %%mm4, %%mm0\n\t" "pxor %%mm7, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_NOR: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "por %%mm4, %%mm0\n\t" "pxor %%mm7, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_XOR: while (sp < send) { asm volatile ( "movq (%0), %%mm0\n\t" "pxor %%mm4, %%mm0\n\t" "movq %%mm0, (%0)" : /* output registers */ "+r" (sp)); sp += 2; } break; case PIC_ARITH_MIN: while (sp < send) { asm volatile ( "movq (%0), %%mm0 # mm0 = Color\n\t" "movq %%mm0, %%mm1 # mm1 = Color\n\t" "psubusb %%mm4, %%mm1 # mm1 = C - S\n\t" "pcmpeqb %%mm6, %%mm1 # mm2 = mask: 0s C>S 1s C<=S\n\t" "pand %%mm1, %%mm0 # mm0 = mask & C\n\t" "pxor %%mm7, %%mm1 # mm1 = ~mask\n\t" "pand %%mm4, %%mm1 # mm1 = S & ~mask\n\t" "por %%mm1, %%mm0 # mm0 = (S&~mask)|(mask&C)\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (sp)); sp += 2; } break; case PIC_ARITH_MAX: while (sp < send) { asm volatile ( "movq (%0), %%mm0 # mm0 = Color\n\t" "movq %%mm4, %%mm1 # mm1 = Scalar\n\t" "psubusb %%mm0, %%mm1 # mm1 = S - C\n\t" "pcmpeqb %%mm6, %%mm1 # mm1 = mask: 0s S>C 1s S<=C\n\t" "pand %%mm1, %%mm0 # mm0 = mask & C\n\t" "pxor %%mm7, %%mm1 # mm1 = ~mask\n\t" "pand %%mm4, %%mm1 # mm1 = S & ~mask\n\t" "por %%mm1, %%mm0 # mm0 = (S&~mask)|(mask&C)\n\t" "movq %%mm0, (%0)" /* output registers */ : "+r" (sp)); sp += 2; } break; } srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); } static void ZoomVertically(Pict *destPtr, Pict *srcPtr, ResampleFilter *filterPtr) { Sample *samples, *send; int x; int bytesPerSample; /* Size of sample. */ long bytesPerRow; /* Pre-calculate filter contributions for each row. */ bytesPerSample = Blt_ComputeWeights(srcPtr->height, destPtr->height, filterPtr, &samples); bytesPerRow = sizeof(Blt_Pixel) * srcPtr->pixelsPerRow; send = (Sample *)((char *)samples + (destPtr->height * bytesPerSample)); asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm2, %mm2 # mm2 = -1 \n\t" "psubw %mm6, %mm2 # mm2 = 1,1,1,1\n\t" "psllw $4, %mm2 # mm2 = BIAS\n"); /* Apply filter to each row. */ for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColumnPtr; Sample *splPtr; srcColumnPtr = srcPtr->bits + x; dp = destPtr->bits + x; for (splPtr = samples; splPtr < send; splPtr = (Sample *)((char *)splPtr + bytesPerSample)) { Blt_Pixel *sp; sp = srcColumnPtr + (splPtr->start * srcPtr->pixelsPerRow); asm volatile ( /* Clear the accumulator mm5. */ "pxor %%mm5, %%mm5 # mm5 = 0\n\n" ".Lasm%=:\n\t" /* Load the weighting factor into mm1. */ "movd (%1), %%mm1 # mm1 = 0,0,0,W\n\t" /* Load the source pixel into mm0. */ "movd (%3), %%mm0 # mm0 = S\n\t" /* Unpack the weighting factor into mm1. */ "punpcklwd %%mm1, %%mm1 # mm1 = 0,0,W,W\n\t" /* Unpack the pixel components into 16-bit words.*/ "punpcklbw %%mm6, %%mm0 # mm0 = Sa,Sb,Sg,Sr\n\t" /* */ "punpcklwd %%mm1, %%mm1 # mm1 = W,W,W,W\n\t" /* Scale the 8-bit components to 14 bits. (S * 257) >> 2 */ "movq %%mm0, %%mm3 # mm3 = S8\n\t" "psllw $8, %%mm3 # mm3 = S8 * 256\n\t" "paddw %%mm3, %%mm0 # mm0 = S16\n\t" "psrlw $1, %%mm0 # mm0 = S15\n\t" /* Multiple each pixel component by the weight. Note that * the lower 16-bits of the product are truncated (bad) * creating round-off error in the sum. */ "pmulhw %%mm1, %%mm0 # mm0 = S15 * W14\n\t" "add $4, %1 # wp++\n\t" "add %4, %3 # sp++\n\t" /* Accumulate upper 16-bit results of product in mm5. */ "paddsw %%mm0, %%mm5 # mm5 = prod + mm5\n\t" /* Move the pointers to the next weight and pixel */ "cmp %2, %1 # wend == wp\n\t" "jnz .Lasm%=\n\t" /* end loop */ /* Add a rounding bias to the pixel sum */ "paddw %%mm2, %%mm5 # mm5 = A13 + BIAS\n\t" /* Shift off fractional part */ "psraw $5, %%mm5 # mm5 = A8\n\t" /* Pack 16-bit components into lower 4 bytes. */ "packuswb %%mm5, %%mm5 # Pack 4 low-order bytes.\n\t" /* Save the word (pixel) in the destination. */ "movd %%mm5,(%0) # dp = word\n" /* output registers */ : "+r" (dp) /* input registers */ : "r" (splPtr->weights), "r" (splPtr->wend), "r" (sp), "r" (bytesPerRow)); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "mmx v-alpha=0x%x\n", dp->Alpha); } #endif dp += destPtr->pixelsPerRow; } } asm volatile ("emms"); /* Free the memory allocated for filter weights. */ Blt_Free(samples); } static void ZoomHorizontally( Pict *destPtr, Pict *srcPtr, ResampleFilter *filterPtr) { Sample *samples, *send; int y; Blt_Pixel *srcRowPtr, *destRowPtr; int bytesPerSample; /* Size of sample. */ /* Pre-calculate filter contributions for each column. */ bytesPerSample = Blt_ComputeWeights(srcPtr->width, destPtr->width, filterPtr, &samples); send = (Sample *)((char *)samples + (destPtr->width * bytesPerSample)); /* Apply filter to each column. */ srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; asm volatile ( "pxor %mm6, %mm6 # mm6 = 0\n\t" "pxor %mm3, %mm3 # mm3 = 0\n\t" "pcmpeqw %mm2, %mm2 # mm2 = -1\n\t" "psubw %mm3, %mm2 # mm2 = 1,1,1,1\n\t" "psllw $4, %mm2 # mm2 = BIAS\n"); for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; Sample *splPtr; dp = destRowPtr; for (splPtr = samples; splPtr < send; splPtr = (Sample *)((char *)splPtr + bytesPerSample)) { Blt_Pixel *sp; sp = srcRowPtr + splPtr->start; asm volatile ( /* Clear the accumulator mm5. */ "pxor %%mm5, %%mm5 # mm5 = 0\n\n" ".Lasm%=:\n\t" /* Load the weighting factor into mm1. */ "movd (%1), %%mm1 # mm1 = W\n\t" /* Get the source RGBA pixel. */ "movd (%3), %%mm0 # mm0 = sp\n\t" /* Unpack the weighting factor into mm1. */ "punpcklwd %%mm1, %%mm1 # mm1 = 0,0,W,W\n\t" /* Unpack the pixel into mm0. */ "punpcklbw %%mm6, %%mm0 # mm0 = Sa,Sr,Sg,Sb\n\t" /* */ "punpcklwd %%mm1, %%mm1 # mm1 = W,W,W,W\n\t" /* Scale the 8-bit components to 14 bits: (S * 257) >> 2 */ "movq %%mm0, %%mm3 # mm3 = S8\n\t" "psllw $8, %%mm3 # mm3 = S8 * 256\n\t" "paddw %%mm3, %%mm0 # mm0 = S16\n\t" "psrlw $1, %%mm0 # mm0 = S15\n\t" /* Multiple each pixel component by the weight. Note * that the lower 16-bits of the product are * truncated (bad) creating round-off error in the * sum. */ "pmulhw %%mm1, %%mm0 # mm0 = S15 * W14\n\t" "add $4, %1 # wp++\n\t" "add $4, %3 # sp++\n\t" /* Add the 16-bit components to mm5. */ "paddsw %%mm0, %%mm5 # mm5 = A13 + mm5\n\t" /* Move the pointers to the next weight and pixel */ "cmp %2, %1 # wend == wp\n\t" "jnz .Lasm%=\n\t" /* end loop */ /* Add a rounding bias to the pixel sum. */ "paddw %%mm2, %%mm5 # mm5 = A13 + BIAS\n\t" /* Shift off fractional portion. */ "psraw $5, %%mm5 # mm5 = A8\n\t" /* Pack 16-bit components into lower 4 bytes. */ "packuswb %%mm5, %%mm5 # Pack A8 into low 4 bytes.\n\t" /* Store the word (pixel) in the destination. */ "movd %%mm5,(%0) # dp = word\n" /* output registers */ : "+r" (dp) /* input registers */ : "r" (splPtr->weights), "r" (splPtr->wend), "r" (sp)); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "mmx h-alpha=0x%x\n", dp->Alpha); } #endif dp++; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } asm volatile ("emms"); /* Free the memory allocated for horizontal filter weights. */ Blt_Free(samples); } static void TentVertically(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcColumnPtr, *destColumnPtr; int x; size_t nPixels; asm volatile ( /* Establish constants used below. */ "pxor %mm6, %mm6 # mm6 = 0\n"); nPixels = srcPtr->height * srcPtr->pixelsPerRow; srcColumnPtr = srcPtr->bits; destColumnPtr = destPtr->bits; for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *rp, *rend; /* * mm0 = * mm1 = unpacked center pixel * mm2 = unpacked left pixel * mm3 = unpacked right pixel * mm4 = * mm5 = * mm6 = 0 * mm7 = */ dp = destColumnPtr; rp = srcColumnPtr + srcPtr->pixelsPerRow; asm volatile ( "movd (%2), %%mm1 # mm1 = cp\n\t" "movd (%1), %%mm3 # mm3 = rp\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = S8\n\t" "movq %%mm1, %%mm2 # mm2 = lp = S8\n\t" "punpcklbw %%mm6, %%mm3 # mm3 = S8\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp << 1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n\t" "movq %%mm3, %%mm1 # cp = rp\n" : /* output registers */ "+r" (dp), "+r" (rp) : /* input registers */ "r" (srcColumnPtr)); dp += destPtr->pixelsPerRow; rp += srcPtr->pixelsPerRow; for (rend = srcColumnPtr + nPixels; rp < rend; /*empty*/) { asm volatile ( "movd (%1), %%mm3 # mm3 = rp\n\t" "punpcklbw %%mm6, %%mm3 # mm3 = S8\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp<<1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n\t" "movq %%mm1, %%mm2 # lp = cp\n\t" "movq %%mm3, %%mm1 # cp = rp\n" /* output registers */ : "+r" (dp), "+r" (rp)); dp += destPtr->pixelsPerRow; rp += srcPtr->pixelsPerRow; } asm volatile ( "movq %%mm1, %%mm3 # rp = cp\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp << 1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n" /* output registers */ : "+r" (dp)); srcColumnPtr++, destColumnPtr++; } asm volatile ("emms"); } static void TentHorizontally(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; asm volatile ( /* Establish constants used below. */ "pxor %mm6, %mm6 # mm6 = 0\n"); srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; Blt_Pixel *rp, *rend; /* * mm0 = * mm1 = unpacked center pixel * mm2 = unpacked left pixel * mm3 = unpacked right pixel * mm4 = * mm5 = * mm6 = 0 * mm7 = */ dp = destRowPtr; rp = srcRowPtr + 1; asm volatile ( "movd (%2), %%mm1 # mm1 = cp\n\t" "movq %%mm1, %%mm2 # mm2 = lp\n\t" "movd (%1), %%mm3 # mm3 = rp\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = S8\n\t" "punpcklbw %%mm6, %%mm2 # mm2 = S8\n\t" "punpcklbw %%mm6, %%mm3 # mm3 = S8\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp << 1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n\t" "movq %%mm3, %%mm1 # cp = rp\n" : /* output registers */ "+r" (dp), "+r" (rp) : /* input registers */ "r" (srcRowPtr)); dp++, rp++; for (rend = srcRowPtr + srcPtr->width; rp < rend; /*empty*/) { asm volatile ( "movd (%1), %%mm3 # mm3 = rp\n\t" "punpcklbw %%mm6, %%mm3 # mm3 = S8\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp<<1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n\t" "movq %%mm1, %%mm2 # lp = cp\n\t" "movq %%mm3, %%mm1 # cp = rp\n" /* output registers */ : "+r" (dp), "+r" (rp)); dp++, rp++; } asm volatile ( "movq %%mm1, %%mm3 # rp = cp\n\t" "movq %%mm1, %%mm0 # mm0 = cp\n\t" "psllw $1, %%mm0 # mm0 = cp << 1\n\t" "paddw %%mm2, %%mm0 # mm0 = lp + (cp << 1)\n\t" "paddw %%mm3, %%mm0 # mm0 = lp + (cp << 1) + rp\n\t" "psraw $2, %%mm0 # mm0 = (lp + (cp << 1) + rp) >> 2\n\t" "packuswb %%mm0, %%mm0 # Pack into low 4 bytes.\n\t" "movd %%mm0,(%0) # dp = word\n" /* output registers */ : "+r" (dp)); srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } asm volatile ("emms"); } static void BlendPictures( Pict *destPtr, /* (in/out) Background picture. Composite * overwrites region in background. */ Pict *srcPtr, /* Foreground picture. */ int sx, int sy, /* Origin of foreground region in source. */ int w, int h, /* Dimension of area to be blended. */ int dx, int dy) /* Origin of background region in * destination. */ { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if ((srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(srcPtr); } if ((destPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(destPtr); } destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((sy * srcPtr->pixelsPerRow) + sx); asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm5, %mm5 # mm5 = -1 \n\t" "psubw %mm6, %mm5 # mm5 = 1,1,1,1\n\t" "psllw $7, %mm5 # mm5 = ROUND = 128\n"); for (y = 0; y < h; y++) { Blt_Pixel *sp, *send, *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + w; sp < send; sp++, dp++) { /* Blend the foreground and background together. */ if (sp->Alpha == 0xFF) { *dp = *sp; } else if (sp->Alpha != 0x00) { unsigned long beta; beta = sp->Alpha ^ 0xFF; /* beta = 1 - alpha */ /* * Small wins: * * We can compute * dest = (fg * alpha) + (beta * bg); * for all RGBA components at once. * * Packing unsigned with saturation performs the * necessary clamping without the branch misprediction * penalty. * * FIXME: * Check if it's faster to do the blend calcution * all the time (even when alpha is 0 or * 255). There's a good probability that the * majority of pixels are opaque (interior) or * completely transparent (exterior). Only the * edge pixels would require blending. */ asm volatile ( /* * mm0 = dp * mm1 = sp * mm2 = beta = 1 - alpha * mm3 = temp * mm4 = * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = */ "movd (%0), %%mm0 # mm0 = dp\n\t" "movd (%1), %%mm1 # mm1 = sp\n\t" "movd %2, %%mm2 # mm2 = beta\n\t" "punpcklbw %%mm6, %%mm0 # mm0 = Da,Dr,Dg,Db\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = 0,0,B,B\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = B,B,B,B\n\t" "pmullw %%mm0, %%mm2 # mm2 = D*B\n\t" "paddw %%mm5, %%mm2 # mm2 = (D*B)+ROUND\n\t" "movq %%mm2, %%mm3 # mm3 = P16\n\t" "psrlw $8, %%mm3 # mm3 = P16 / 256\n\t" "paddw %%mm2, %%mm3 # mm3 = (P16 / 256) + P16\n\t" "psrlw $8, %%mm3 # mm3 = P8 ~= P16 / 257\n\t" "paddw %%mm1, %%mm3 # mm3 = S + P\n\t" "packuswb %%mm3, %%mm3 # Pack 4 low bytes.\n\t" "movd %%mm3, (%0) # *dp = word\n" : "+r" (dp) : "r" (sp), "r" (beta)); } } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } asm volatile ("emms"); } static void FadePicture( Pict *destPtr, Pict *srcPtr, int sx, int sy, int w, int h, int dx, int dy, int alpha) { Blt_Pixel *srcRowPtr, *destRowPtr; int beta; beta = alpha ^ 0xFF; destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((sy * srcPtr->pixelsPerRow) + sx); if (alpha == 0xFF) { int y; for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp; int x; sp = srcRowPtr, dp = destRowPtr; for (x = 0; x < w; x++) { *dp++ = *sp++; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } else if (alpha != 0x00) { int y; asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm5, %mm5 # mm5 = -1 \n\t" "psubw %mm6, %mm5 # mm5 = 1,1,1,1\n\t" "psllw $7, %mm5 # mm5 = BIAS = 128\n"); for (y = 0; y < h; y++) { Blt_Pixel *sp, *send, *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + w; sp < send; sp++, dp++) { asm volatile ( /* * mm0 = dp * mm1 = sp * mm2 = beta = 1 - alpha * mm3 = temp * mm4 = * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = */ "movd (%0), %%mm0 # mm0 = dp\n\t" "movd (%1), %%mm1 # mm1 = sp\n\t" "movd %2, %%mm2 # mm2 = beta\n\t" "punpcklbw %%mm6, %%mm0 # mm0 = Da,Dr,Dg,Db\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = 0,0,beta,beta\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = beta,beta,beta,beta\n\t" "pmullw %%mm0, %%mm2 # mm2 = prod = D*beta\n\t" "paddw %%mm5, %%mm2 # mm2 = t = (D*beta)+ROUND\n\t" "movq %%mm2, %%mm3 # mm3 = t\n\t" "psrlw $8, %%mm3 # mm3 = t >> 8\n\t" "paddw %%mm2, %%mm3 # mm3 = t + (t>>8)\n\t" "psrlw $8, %%mm3 # mm3 = ((t+(t>>8)) >> 8)\n\t" "paddw %%mm1, %%mm3 # mm3 = S + ((t+(t>>8))>>8)\n\t" "packuswb %%mm3, %%mm3 # Pack 4 low bytes.\n\t" "movd %%mm3,(%0) # *dp = word\n" : "+r" (dp) : "r" (dp), "r" (beta)); } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } asm volatile ("emms"); } #ifdef notdef static void ConvolvePictureVertically(Pict *destPtr, Pict *srcPtr, ResampleFilter *filterPtr) { Sample *samples, *send; int x; int bytesPerSample; /* Size of sample. */ long bytesPerRow; /* Pre-calculate filter contributions for each row. */ bytesPerSample = Blt_ComputeWeights(srcPtr->height, destPtr->height, filterPtr, &samples); bytesPerRow = sizeof(Blt_Pixel) * srcPtr->pixelsPerRow; send = (Sample *)((char *)samples + (destPtr->height * bytesPerSample)); asm volatile ( /* Generate constants needed below. */ "pxor %mm6, %mm6 # mm6 = 0\n\t" "pcmpeqw %mm2, %mm2 # mm2 = -1 \n\t" "psubw %mm6, %mm2 # mm2 = 1,1,1,1\n\t" "psllw $4, %mm2 # mm2 = BIAS\n"); /* Apply filter to each row. */ for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColumnPtr; Sample *splPtr; srcColumnPtr = srcPtr->bits + x; dp = destPtr->bits + x; for (splPtr = samples; splPtr < send; splPtr = (Sample *)((char *)splPtr + bytesPerSample)) { Blt_Pixel *sp; sp = srcColumnPtr + (splPtr->start * srcPtr->pixelsPerRow); asm volatile ( /* Clear the accumulator mm5. */ "pxor %%mm5, %%mm5 # mm5 = 0\n\n" ".Lasm%=:\n\t" /* Load the weighting factor into mm1. */ "movd (%1), %%mm1 # mm1 = 0,0,0,W\n\t" /* Load the source pixel into mm0. */ "movd (%3), %%mm0 # mm0 = S\n\t" /* Unpack the weighting factor into mm1. */ "punpcklwd %%mm1, %%mm1 # mm1 = 0,0,W,W\n\t" "punpcklwd %%mm1, %%mm1 # mm1 = W,W,W,W\n\t" /* Unpack the pixel components into 16-bit words.*/ "punpcklbw %%mm6, %%mm0 # mm0 = Sa,Sb,Sg,Sr\n\t" /* Scale the 8-bit components to 14 bits. (S * 257) >> 2 */ "movq %%mm0, %%mm3 # mm3 = S8\n\t" "psllw $8, %%mm3 # mm3 = S8 * 256\n\t" "paddw %%mm3, %%mm0 # mm0 = S16\n\t" "psrlw $1, %%mm0 # mm0 = S15\n\t" /* Multiple each pixel component by the weight. Note that * the lower 16-bits of the product are truncated (bad) * creating round-off error in the sum. */ "pmulhw %%mm1, %%mm0 # mm0 = S15 * W14\n\t" /* Move the pointers to the next weight and pixel */ "add $4, %1 # wp++\n\t" "add %4, %3 # sp++\n\t" /* Accumulate upper 16-bit results of product in mm5. */ "paddsw %%mm0, %%mm5 # mm5 = prod + mm5\n\t" "cmp %2, %1 # wend == wp\n\t" "jnz .Lasm%=\n\t" /* end loop */ /* Add a rounding bias to the pixel sum */ "paddw %%mm2, %%mm5 # mm5 = A13 + BIAS\n\t" /* Shift off fractional part */ "psraw $5, %%mm5 # mm5 = A8\n\t" /* Pack 16-bit components into lower 4 bytes. */ "packuswb %%mm5, %%mm5 # Pack 4 low-order bytes.\n\t" /* Save the word (pixel) in the destination. */ "movd %%mm5,(%0) # dp = word\n" /* output registers */ : "+r" (dp) /* input registers */ : "r" (splPtr->weights), "r" (splPtr->wend), "r" (sp), "r" (bytesPerRow)); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "mmx v-alpha=0x%x\n", dp->Alpha); } #endif dp += destPtr->pixelsPerRow; } } asm volatile ("emms"); /* Free the memory allocated for filter weights. */ Blt_Free(samples); } static void ConvolvePictureHorizontally(Pict *destPtr, Pict *srcPtr, ResampleFilter *filterPtr) { Sample *samples, *send; int y; Blt_Pixel *srcRowPtr, *destRowPtr; int bytesPerSample; /* Size of sample. */ /* Pre-calculate filter contributions for each column. */ bytesPerSample = Blt_ComputeWeights(srcPtr->width, destPtr->width, filterPtr, &samples); send = (Sample *)((char *)samples + (destPtr->width * bytesPerSample)); /* Apply filter to each column. */ srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; asm volatile ( "pxor %mm6, %mm6 # mm6 = 0\n\t" "pxor %mm3, %mm3 # mm3 = 0\n\t" "pcmpeqw %mm2, %mm2 # mm2 = -1\n\t" "psubw %mm3, %mm2 # mm2 = 1,1,1,1\n\t" "psllw $4, %mm2 # mm2 = BIAS\n"); for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; Sample *splPtr; dp = destRowPtr; for (splPtr = samples; splPtr < send; splPtr = (Sample *)((char *)splPtr + bytesPerSample)) { Blt_Pixel *sp; sp = srcRowPtr + splPtr->start; asm volatile ( /* Clear the accumulator mm5. */ "pxor %%mm5, %%mm5 # mm5 = 0\n\n" ".Lasm%=:\n\t" /* Load the weighting factor into mm1. */ "movd (%1), %%mm1 # mm1 = W\n\t" /* Get the source RGBA pixel. */ "movd (%3), %%mm0 # mm0 = sp\n\t" /* Unpack the weighting factor into mm1. */ "punpcklwd %%mm1, %%mm1 # mm1 = 0,0,W,W\n\t" "punpcklwd %%mm1, %%mm1 # mm1 = W,W,W,W\n\t" /* Unpack the pixel into mm0. */ "punpcklbw %%mm6, %%mm0 # mm0 = Sa,Sr,Sg,Sb\n\t" /* Scale the 8-bit components to 14 bits: (S * 257) >> 2 */ "movq %%mm0, %%mm3 # mm3 = S8\n\t" "psllw $8, %%mm3 # mm3 = S8 * 256\n\t" "paddw %%mm3, %%mm0 # mm0 = S16\n\t" "psrlw $1, %%mm0 # mm0 = S15\n\t" /* Multiple each pixel component by the weight. Note that * the lower 16-bits of the product are truncated (bad) * creating round-off error in the sum. */ "movq %%mm0, %%mm7 # mm5 = S15\n\t" "pmulhw %%mm1, %%mm0 # mm0 = S15 * W14\n\t" "pmullw %%mm1, %%mm7 # mm0 = S15 * W14\n\t" "psrlw $15, %%mm7 # mm0 = S1\n\t" "paddsw %%mm7, %%mm0 # mm5 = A13 + mm5\n\t" /* Add the 16-bit components to mm5. */ "paddsw %%mm0, %%mm5 # mm5 = A13 + mm5\n\t" /* Move the pointers to the next weight and pixel */ "add $4, %1 # wp++\n\t" "add $4, %3 # sp++\n\t" "cmp %2, %1 # wend == wp\n\t" "jnz .Lasm%=\n\t" /* end loop */ /* Add a rounding bias to the pixel sum. */ "paddw %%mm2, %%mm5 # mm5 = A13 + BIAS\n\t" /* Shift off fractional portion. */ "psraw $5, %%mm5 # mm5 = A8\n\t" /* Pack 16-bit components into lower 4 bytes. */ "packuswb %%mm5, %%mm5 # Pack A8 into low 4 bytes.\n\t" /* Store the word (pixel) in the destination. */ "movd %%mm5,(%0) # dp = word\n" /* output registers */ : "+r" (dp) /* input registers */ : "r" (splPtr->weights), "r" (splPtr->wend), "r" (sp)); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "mmx h-alpha=0x%x\n", dp->Alpha); } #endif dp++; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } asm volatile ("emms"); /* Free the memory allocated for horizontal filter weights. */ Blt_Free(samples); } #endif static void AssociateColors(Pict *srcPtr) /* (in/out) picture */ { Blt_Pixel *srcRowPtr; int y; Blt_Pixel mask; /* Create mask for alpha component. We'll use this mask to make sure we * don't change the alpha component of a pixel. */ mask.u32 = 0; mask.Alpha = 0xFF; asm volatile ( /* Generate constants needed below. */ "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "pcmpeqw %%mm5, %%mm5 # mm5 = -1 \n\t" "psubw %%mm6, %%mm5 # mm5 = 1,1,1,1\n\t" "movd %0, %%mm4 # mm4 = mask\n\t" "psllw $7, %%mm5 # mm5 = ROUND = 128\n" "punpcklbw %%mm6, %%mm4 # mm4 = 0,0,0,FF\n\t" /* outputs */ : /* inputs */ : "r" (mask.u32)); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; #ifdef notdef for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp += 2) { Blt_Pixel *p, *q; /* * Small wins: * * We can compute * dest = (fg * alpha) + (beta * bg); * for all RGBA components at once. * * Packing unsigned with saturation performs the necessary * clamping without the branch misprediction penalty. */ p = sp, q = sp+1; asm volatile ( /* * mm0 = P * mm1 = Q * mm2 = Pa * mm3 = Qa * mm4 = temp * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = 0,0,0,FF */ "movd (%0), %%mm0 # mm0 = P\n\t" "movd (%1), %%mm1 # mm1 = Q\n\t" "movd %2, %%mm2 # mm2 = 0,0,0,Pa\n\t" "movd %3, %%mm3 # mm2 = 0,0,0,Qa\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = 0,0,Pa,Pa\n\t" "punpcklwd %%mm3, %%mm3 # mm3 = 0,0,Qa,Qa\n\t" "punpcklbw %%mm6, %%mm0 # mm0 = Pa,Pr,Pg,Pb\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = Pa,Pa,Pa,Pa\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Qa,Qr,Qg,Qb\n\t" "por %%mm7, %%mm2 # mm2 = 0xff,Pa,Pa,Pa\n\t" "punpcklwd %%mm3, %%mm3 # mm3 = Qa,Qa,Qa,Qa\n\t" "por %%mm7, %%mm3 # mm2 = 0xff,Qa,Qa,Qa\n\t" "pmullw %%mm0, %%mm2 # mm2 = P*Pa\n\t" "pmullw %%mm1, %%mm3 # mm3 = Q*Qa\n\t" "paddw %%mm5, %%mm2 # mm2 = (P*Pa)+ROUND\n\t" "paddw %%mm5, %%mm3 # mm3 = (Q*Qa)+ROUND\n\t" "movq %%mm2, %%mm0 # mm0 = P16\n\t" "movq %%mm3, %%mm1 # mm1 = Q16\n\t" "psrlw $8, %%mm0 # mm0 = P16 / 256\n\t" "psrlw $8, %%mm1 # mm1 = Q16 / 256\n\t" "paddw %%mm2, %%mm0 # mm0 = (P16 / 256) + P16\n\t" "paddw %%mm3, %%mm1 # mm1 = (Q16 / 256) + Q16\n\t" "psrlw $8, %%mm0 # mm0 = P8 ~= P16 / 257\n\t" "psrlw $8, %%mm1 # mm1 = Q8 ~= Q16 / 257\n\t" "packuswb %%mm0, %%mm0 # Pack 4 low bytes.\n\t" "packuswb %%mm1, %%mm1 # Pack 4 low bytes.\n\t" "movd %%mm0, (%0) # *P = word\n" "movd %%mm1, (%1) # *Q = word\n" /* outputs */ : "+r" (p), "+r" (q) /* inputs */ : "r" ((unsigned int)(p->Alpha)), "r" ((unsigned int)(q->Alpha))); } srcRowPtr += srcPtr->pixelsPerRow; } #else for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { unsigned int alpha; /* * Small wins: * * We can compute * dest = (fg * alpha) + (beta * bg); * for all RGBA components at once. * * Packing unsigned with saturation performs the necessary * clamping without the branch misprediction penalty. */ alpha = sp->Alpha; asm volatile ( /* * mm0 = * mm1 = sp * mm2 = alpha * mm3 = temp * mm4 = 0,0,0,FF * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = */ "movd %1, %%mm2 # mm2 = 0,0,0,A\n\t" "movd (%0), %%mm1 # mm1 = sp\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = 0,0,A,A\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = A,A,A,A\n\t" "por %%mm4, %%mm2 # mm2 = 0xff,A,A,A\n\t" "pmullw %%mm1, %%mm2 # mm2 = S*A\n\t" "paddw %%mm5, %%mm2 # mm2 = (S*A)+ROUND\n\t" "movq %%mm2, %%mm3 # mm3 = P16\n\t" "psrlw $8, %%mm3 # mm3 = P16 / 256\n\t" "paddw %%mm2, %%mm3 # mm3 = (P16 / 256) + P16\n\t" "psrlw $8, %%mm3 # mm3 = P8 ~= P16 / 257\n\t" "packuswb %%mm3, %%mm3 # Pack 4 low bytes.\n\t" "movd %%mm3, (%0) # *sp = word\n" : "+r" (sp) : "r" (alpha)); } srcRowPtr += srcPtr->pixelsPerRow; } #endif asm volatile ("emms"); srcPtr->flags |= BLT_PIC_ASSOCIATED_COLORS; } static void UnassociateColors(Pict *srcPtr) /* (in/out) picture */ { Blt_Pixel *srcRowPtr; int y; Blt_Pixel mask; /* Create mask for alpha component. We'll use this mask to make sure we * don't change the alpha component of a pixel. */ mask.u32 = 0; mask.Alpha = 0xFF; asm volatile ( /* Generate constants needed below. */ "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "pcmpeqw %%mm5, %%mm5 # mm5 = -1 \n\t" "psubw %%mm6, %%mm5 # mm5 = 1,1,1,1\n\t" "movd %0, %%mm4 # mm4 = mask\n\t" "psllw $7, %%mm5 # mm5 = ROUND = 128\n" "punpcklbw %%mm6, %%mm4 # mm4 = 0,0,0,FF\n\t" : /* inputs */ : "r" (mask.u32)); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { unsigned int alpha; /* * Small wins: * * We can compute * dest = (fg * alpha) + (beta * bg); * for all RGBA components at once. * * C = (Ca * ia) + bias >> 16 * Packing unsigned with saturation performs the * necessary clamping without the branch misprediction * penalty. */ alpha = sp->Alpha; asm volatile ( /* * mm0 = * mm1 = sp * mm2 = alpha * mm3 = temp * mm4 = 0,0,0,FF * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = */ "movd %1, %%mm2 # mm2 = 0,0,0,IA\n\t" "movd (%0), %%mm1 # mm1 = sp\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = 0,0,IA,IA\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "punpcklwd %%mm2, %%mm2 # mm2 = IA,IA,IA,IA\n\t" "por %%mm4, %%mm2 # mm2 = 0xff,IA,IA,IA\n\t" "pmullw %%mm1, %%mm2 # mm2 = S*IA\n\t" "paddw %%mm5, %%mm2 # mm2 = (S*A)+ROUND\n\t" "movq %%mm2, %%mm3 # mm3 = P16\n\t" "psrlw $8, %%mm3 # mm3 = P16 / 256\n\t" "paddw %%mm2, %%mm3 # mm3 = (P16 / 256) + P16\n\t" "psrlw $8, %%mm3 # mm3 = P8 ~= P16 / 257\n\t" "packuswb %%mm3, %%mm3 # Pack 4 low bytes.\n\t" "movd %%mm3, (%0) # *sp = word\n" : "+r" (sp) : "r" (alpha)); } srcRowPtr += srcPtr->pixelsPerRow; } asm volatile ("emms"); srcPtr->flags &= ~BLT_PIC_ASSOCIATED_COLORS; } /* *--------------------------------------------------------------------------- * * CopyPictureBits -- * * Creates a copy of the given picture using SSE xmm registers. * * FIXME: This is broken since it uses an double-world aligned quad word * move instruction. * * Results: * None. * * Side effects: * The area specified in the source picture is copied to the * destination picture. * * -------------------------------------------------------------------------- */ static void CopyPictureBits(Pict *destPtr, Pict *srcPtr, int sx, int sy, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; int dw, dh, width, height; dw = destPtr->width - dx; dh = destPtr->height - dy; width = MIN(dw, w); height = MIN(dh, h); srcRowPtr = srcPtr->bits + (srcPtr->pixelsPerRow * sy) + sx; destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * dy) + dx; for (y = 0; y < height; y++) { Blt_Pixel *sp, *send, *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + (width & ~3); sp < send; sp += 4, dp += 4) { asm volatile ( "movdqa (%1), %%xmm1\n\t" "movdqa %%xmm1, (%0)\n\t" : "+r" (dp) : "r" (sp)); } switch (width & 3) { case 3: dp->u32 = sp->u32; sp++; dp++; case 2: dp->u32 = sp->u32; sp++; dp++; case 1: dp->u32 = sp->u32; sp++; dp++; case 0: break; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); asm volatile ("emms"); } #ifdef notdef static void BoxCarVertically(Pict *destPtr, Pict *srcPtr, size_t r) { unsigned int x; size_t *map; int fscale; size_t fwidth; /* Filter width */ float s; Blt_Pixel mask; map = CreateNeighborhoodMap(srcPtr->height, r); fwidth = r + r + 1; s = 1.0f / fwidth; fscale = float2si(s); fwidth--; /* * mm3 = r16 g16 b16 a16 accumulators */ /* Apply filter to each row. */ /* Create mask for alpha component. We'll use this mask to make sure we * don't change the alpha component of a pixel. */ mask.u32 = 0; mask.Alpha = 0xFF; asm volatile ( /* Generate constants needed below. */ "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "pcmpeqw %%mm5, %%mm5 # mm5 = -1 \n\t" "psubw %%mm6, %%mm5 # mm5 = 1,1,1,1\n\t" "movd %0, %%mm4 # mm4 = mask\n\t" "psllw $7, %%mm5 # mm5 = ROUND = 128\n" "punpcklbw %%mm6, %%mm4 # mm4 = 0,0,0,FF\n\t" : /* inputs */ : "r" (mask.u32)); for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColPtr; int r, g, b, a; unsigned int y; srcColPtr = srcPtr->bits + x; asm volatile ( /* Initialize 16 bit accumulators. */ "pxor %%mm4, %%mm4 # mm4 = 0\n\t"); /* Prime the pump. */ for (y = 0; y < fwidth; y++) { Blt_Pixel *sp; sp = srcColPtr + (srcPtr->pixelsPerRow * map[y]); asm volatile ( /* * mm0 = * mm1 = sp * mm4 = accumulator * mm6 = 0 * mm7 = */ "movd (%0), %%mm1 # mm1 = sp\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "paddw %%mm1, %%mm4 # mm4 = accumulator\n\t" : "+r" (sp)); } dp = destPtr->bits + x; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *s1, s2; int fr, fg, fb, fa; s1 = srcColPtr + (srcPtr->pixelsPerRow * map[y + fwidth]); s2 = srcColPtr + (srcPtr->pixelsPerRow * map[y]); asm volatile ( /* * mm0 = * mm1 = sp * mm2 = alpha * mm3 = temp * mm4 = 0,0,0,FF * mm5 = ROUND = 128,128,128,128 * mm6 = 0 * mm7 = */ "movd (%0), %%mm1 # mm1 = next\n\t" "movd (%1), %%mm2 # mm2 = prev\n\t" "punpcklbw %%mm6, %%mm1 # mm1 = Sa,Sr,Sg,Sb\n\t" "punpcklbw %%mm6, %%mm2 # mm2 = Sa,Sr,Sg,Sb\n\t" "paddw %%mm1, %%mm4 # mm4 = accumulator\n\t" "movq %%mm4, %%mm5 # mm3 = P16\n\t" "pmulhw %%mm3, %%mm5 # mm0 = S15 * W14\n\t" "psrlw $8, %%mm3 # mm3 = P16 / 256\n\t" "paddw %%mm2, %%mm3 # mm3 = (P16 / 256) + P16\n\t" "psrlw $8, %%mm3 # mm3 = P8 ~= P16 / 257\n\t" "packuswb %%mm3, %%mm3 # Pack 4 low bytes.\n\t" "movd %%mm3, (%0) # *sp = word\n" : "+r" (s1) "+r" (s2) : "r" (alpha)); } r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; fr = r * fscale; fg = g * fscale; fb = b * fscale; fa = a * fscale; dp->Red = (unsigned char)SICLAMP(fr); dp->Green = (unsigned char)SICLAMP(fg); dp->Blue = (unsigned char)SICLAMP(fb); dp->Alpha = (unsigned char)SICLAMP(fa); sp = srcColPtr + (srcPtr->pixelsPerRow * map[y]); r -= sp->Red; g -= sp->Green; b -= sp->Blue; a -= sp->Alpha; dp += destPtr->pixelsPerRow; } } /* Free the memory allocated for filter weights. */ Blt_Free(map); } static void BoxCarHorizontally(Pict *destPtr, Pict *srcPtr, size_t r) { Blt_Pixel *srcRowPtr, *destRowPtr; float s; size_t *map; int fscale; unsigned int y; size_t fwidth; /* Filter width */ fwidth = r + r + 1; map = CreateNeighborhoodMap(srcPtr->width, r); s = 1.0f / fwidth; fscale = float2si(s); destRowPtr = destPtr->bits; srcRowPtr = srcPtr->bits; fwidth--; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; unsigned int x; int r, g, b, a; /* Prime the pump. Get sums for each component for the first (fwidth) * pixels in the column. */ r = g = b = a = 0; for (x = 0; x < fwidth; x++) { Blt_Pixel *sp; sp = srcRowPtr + map[x]; r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; } dp = destRowPtr; for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *sp; int fr, fg, fb, fa; sp = srcRowPtr + map[x + fwidth]; r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; fr = r * fscale; fg = g * fscale; fb = b * fscale; fa = a * fscale; dp->Red = (unsigned char)SICLAMP(fr); dp->Green = (unsigned char)SICLAMP(fg); dp->Blue = (unsigned char)SICLAMP(fb); dp->Alpha = (unsigned char)SICLAMP(fa); sp = srcRowPtr + map[x]; r -= sp->Red; g -= sp->Green; b -= sp->Blue; a -= sp->Alpha; dp++; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } /* Free the memory allocated for map. */ Blt_Free(map); } #endif #ifdef notdef /* *--------------------------------------------------------------------------- * * BlankPicture -- * * Creates a copy of the given picture using SSE xmm registers. * * Results: * None. * * Side effects: * The area specified in the source picture is copied to the * destination picture. * * -------------------------------------------------------------------------- */ static void BlankPicture(Pict *destPtr, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; int y; asm volatile ( /* How do you load a xmm register? */ /* Generate constants needed below. */ "pxor %%mm6, %%mm6 # mm6 = 0\n\t" "pcmpeqw %%mm5, %%mm5 # mm5 = -1 \n\t" "psubw %%mm6, %%mm5 # mm5 = 1,1,1,1\n\t" "movd %0, %%mm4 # mm4 = C\n\t" "psllw $7, %%mm5 # mm5 = ROUND = 128\n" "punpcklbw %%mm6, %%mm4 # mm4 = 0,0,0,FF\n\t" : /* inputs */ : "r" (colorPtr->u32)); destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + (destPtr->width & ~3); dp < dend; dp += 4) asm volatile ( "movdqa %%xmm1, (%0)\n\t" : "+r" (dp)); } switch (width & 3) { case 3: dp->u32 = colorPtr->u32; dp++; case 2: dp->u32 = colorPtr->u32; dp++; case 1: dp->u32 = colorPtr->u32; dp++; case 0: break; } destRowPtr += destPtr->pixelsPerRow; } destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); asm volatile ("emms"); } #endif static int x86HaveCpuId(void) { unsigned int ecx; asm volatile ( /* See if ID instruction is supported. Save a copy of * EFLAGS in eax and ecx */ #ifdef __amd64__ "pushq %%rbx\n\t" #else "push %%ebx\n\t" #endif "pushf\n\t" #ifdef __amd64__ "popq %%rax\n\t" #else "pop %%eax\n\t" #endif "mov %%eax, %%ecx\n\t" /* Toggle the CPUID bit in one copy and store to the EFLAGS * reg */ "xorl $0x200000, %%eax\n\t" #ifdef __amd64__ "pushq %%rax\n\t" #else "push %%eax\n\t" #endif "popf\n\t" /* Get the (hopefully modified) EFLAGS */ "pushf\n\t" #ifdef __amd64__ "popq %%rax\n\t" #else "pop %%eax\n\t" #endif /* Compare the result with the previous. */ "xor %%eax, %%ecx\n\t" "movl %%ecx, %0\n\t" #ifdef __amd64__ "popq %%rbx\n\t" #else "pop %%ebx\n\t" #endif : "=c" (ecx)); if (ecx & 0x200000) { return 1; } return 0; } static int x86GetCpuVersion(char *version) { unsigned int ebx, ecx, edx; if (!x86HaveCpuId()) { return 0; } asm volatile ( /* See if ID instruction is supported. Save a copy of * EFLAGS in eax and ecx */ /* Get standard CPUID information, and go to a specific vendor * section */ #ifdef __amd64__ "pushq %%rbx\n\t" #else "push %%ebx\n\t" #endif "xor %%eax, %%eax\n\t" "cpuid\n\t" "movl %%ebx, %0\n\n\t" #ifdef __amd64__ "popq %%rbx\n\n\t" #else "pop %%ebx\n\n\t" #endif : "=a" (ebx), "=d" (edx), "=c" (ecx) : /* no input */ ); memcpy (version, &ebx, 4); memcpy (version+4, &edx, 4); memcpy (version+8, &ecx, 4); version[12] = '\0'; #ifdef notdef fprintf(stderr, "version=%s\n", version); #endif return 1; } static unsigned int x86GetCpuFlags(void) { unsigned int edx; asm volatile ( /* Get the CPUID flags (eax=1). */ #ifdef __amd64__ "pushq %%rbx\n\t" #else "push %%ebx\n\t" #endif "movl $1, %%eax\n\t" "cpuid\n\t" #ifdef __amd64__ "popq %%rbx\n\t" #else "pop %%ebx\n\t" #endif : "=d" (edx)); return edx; } #define CPU_FEATURE_NONE (0) #define CPU_FEATURE_MMX (1<<0) #define CPU_FEATURE_SSE (1<<1) #define CPU_FEATURE_SSE2 (1<<2) #define CPU_FEATURE_3DNOW (1<<3) #define CPU_FEATURE_AMD_MMXEXT (1 << 22) #define CPU_FEATURE_AMD_3DNOW (1 << 31) #define CPU_FEATURE_CENTAUR_3DNOW (1 << 31) #define CPU_FEATURE_CENTAUR_MMX (1 << 23) #define CPU_FEATURE_CENTAUR_MMXEXT (1 << 24) #define CPU_FEATURE_CYRIX_MMX (1 << 23) #define CPU_FEATURE_CYRIX_MMXEXT (1 << 24) #define CPU_FEATURE_INTEL_MMX (1 << 23) #define CPU_FEATURE_INTEL_SSE (1 << 25) #define CPU_FEATURE_INTEL_SSE2 (1 << 26) #define CPU_FEATURE_AMD_MMX (1 << 23) #define CPU_FEATURE_AMD_SSE (1 << 25) #define CPU_FEATURE_AMD_SSE2 (1 << 26) static void PrintFeatures(Tcl_Interp *interp, unsigned int features) { if (features & CPU_FEATURE_MMX) { Tcl_AppendElement(interp, "mmx"); } if (features & CPU_FEATURE_SSE) { Tcl_AppendElement(interp, "sse"); } if (features & CPU_FEATURE_SSE2) { Tcl_AppendElement(interp, "sse2"); } if (features & CPU_FEATURE_3DNOW) { Tcl_AppendElement(interp, "3dnow"); } if (features & CPU_FEATURE_AMD_MMXEXT) { Tcl_AppendElement(interp, "amd_mmxext"); } if (features & CPU_FEATURE_AMD_3DNOW) { Tcl_AppendElement(interp, "amd_mmxext"); } if (features & CPU_FEATURE_CENTAUR_3DNOW) { Tcl_AppendElement(interp, "amd_mmxext"); } if (features & CPU_FEATURE_CENTAUR_MMX) { Tcl_AppendElement(interp, "amd_mmxext"); } if (features & CPU_FEATURE_CENTAUR_MMXEXT) { Tcl_AppendElement(interp, "amd_mmxext"); } if (features & CPU_FEATURE_CYRIX_MMX) { Tcl_AppendElement(interp, "cyrix_mmx"); } if (features & CPU_FEATURE_CYRIX_MMXEXT) { Tcl_AppendElement(interp, "cyrix_mmxext"); } if (features & CPU_FEATURE_INTEL_MMX) { Tcl_AppendElement(interp, "intel_mmx"); } if (features & CPU_FEATURE_INTEL_SSE) { Tcl_AppendElement(interp, "intel_sse"); } if (features & CPU_FEATURE_INTEL_SSE2) { Tcl_AppendElement(interp, "intel_sse2"); } if (features & CPU_FEATURE_AMD_MMX) { Tcl_AppendElement(interp, "amd_mmax"); } if (features & CPU_FEATURE_AMD_SSE) { Tcl_AppendElement(interp, "amd_sse"); } if (features & CPU_FEATURE_AMD_SSE2) { Tcl_AppendElement(interp, "amd_sse2"); } } static int x86CpuFeatures(void) { char version[13]; unsigned int flags, featureFlags; featureFlags = CPU_FEATURE_NONE; if (!x86GetCpuVersion(version)) { return featureFlags; } if (strcmp(version, "GenuineIntel") == 0) { flags = x86GetCpuFlags(); if (flags & CPU_FEATURE_INTEL_MMX) { featureFlags |= CPU_FEATURE_MMX; } if (flags & CPU_FEATURE_INTEL_SSE) { featureFlags |= CPU_FEATURE_SSE; } if (flags & CPU_FEATURE_INTEL_SSE2) { featureFlags |= CPU_FEATURE_SSE2; } } else if (strcmp(version, "AuthenticAMD") == 0) { flags = x86GetCpuFlags(); if (flags & CPU_FEATURE_AMD_MMX) { featureFlags |= CPU_FEATURE_MMX; } if (flags & CPU_FEATURE_AMD_SSE) { featureFlags |= CPU_FEATURE_SSE; } if (flags & CPU_FEATURE_AMD_SSE2) { featureFlags |= CPU_FEATURE_SSE2; } if (flags & CPU_FEATURE_AMD_3DNOW) { featureFlags |= CPU_FEATURE_3DNOW; } } else if (strcmp(version, "CyrixInstead") == 0) { flags = x86GetCpuFlags(); if (flags & CPU_FEATURE_CYRIX_MMX) { featureFlags |= CPU_FEATURE_MMX; } } return featureFlags; } int Blt_CpuFeatures(Tcl_Interp *interp, int *featuresPtr) { unsigned int features; features = x86CpuFeatures(); if (features & CPU_FEATURE_MMX) { #ifdef notdef bltPictProcsPtr = &mmxPictureProcs; #else bltPictProcsPtr->applyPictureToPictureProc = ApplyPictureToPicture; bltPictProcsPtr->applyScalarToPictureProc = ApplyScalarToPicture; bltPictProcsPtr->tentHorizontallyProc = TentHorizontally; bltPictProcsPtr->tentVerticallyProc = TentVertically; bltPictProcsPtr->zoomHorizontallyProc = ZoomHorizontally; bltPictProcsPtr->zoomVerticallyProc = ZoomVertically; #ifdef notdef bltPictProcsPtr->blendPicturesProc = BlendPictures; #endif bltPictProcsPtr->associateColorsProc = AssociateColors; bltPictProcsPtr->selectPixelsProc = SelectPixels; bltPictProcsPtr->fadePictureProc = FadePicture; #ifdef notdef if (features & CPU_FEATURE_SSE) { /* bltPictProcsPtr->copyPictureBitsProc = CopyPictureBits; */ } #endif #endif } if (featuresPtr != NULL) { *featuresPtr = features; } if (interp != NULL) { PrintFeatures(interp, features); fprintf(stderr, "%s\n", Tcl_GetStringResult(interp)); } return TCL_OK; } #else int Blt_CpuFeatures(Tcl_Interp *interp, int *featuresPtr) { if (featuresPtr != NULL) { *featuresPtr = 0; } return TCL_OK; } #endif /* HAVE_X86_ASM */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPicture.c������������������������������������������������������������������0000644�0001750�0001750�00000523163�11462120062�015320� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPicture.c -- * * This module implements basic picture processing routines for the BLT * toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltHash.h" #include <bltDBuffer.h> #include "bltChain.h" #include "bltPicture.h" #include "bltPictInt.h" #include "bltImage.h" #include <X11/Xutil.h> #include <bltRound.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #endif /* HAVE_MALLOC_H */ #ifndef ALIGN #define ALIGN(a) \ (((size_t)a + (sizeof(void *) - 1)) & (~(sizeof(void *) - 1))) #endif /* ALIGN */ #define ALIGNMENT 16 #define JITTER(x) ((x) * (0.05 - drand48() * 0.10)) #define JCLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 1.0) ? 1.0 : (c))) #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) #define imul8x8(a,b,t) ((t) = (a)*(b)+128,(((t)+((t)>>8))>>8)) static Blt_ResampleFilterProc DefaultFilter; static Blt_ResampleFilterProc BellFilter; static Blt_ResampleFilterProc BesselFilter; static Blt_ResampleFilterProc BoxFilter; static Blt_ResampleFilterProc BSplineFilter; static Blt_ResampleFilterProc CatRomFilter; static Blt_ResampleFilterProc DummyFilter; static Blt_ResampleFilterProc GaussianFilter; static Blt_ResampleFilterProc GiFilter; static Blt_ResampleFilterProc Lanczos3Filter; static Blt_ResampleFilterProc MitchellFilter; static Blt_ResampleFilterProc SincFilter; static Blt_ResampleFilterProc TriangleFilter; static Blt_ApplyPictureToPictureProc ApplyPictureToPicture; static Blt_ApplyScalarToPictureProc ApplyScalarToPicture; static Blt_ApplyPictureToPictureWithMaskProc ApplyPictureToPictureWithMask; static Blt_ApplyScalarToPictureWithMaskProc ApplyScalarToPictureWithMask; static Blt_TentHorizontallyProc TentHorizontally; static Blt_TentVerticallyProc TentVertically; static Blt_ZoomHorizontallyProc ZoomHorizontally; static Blt_ZoomVerticallyProc ZoomVertically; static Blt_BlendPicturesProc BlendPictures; static Blt_SelectPixelsProc SelectPixels; static Blt_AssociateColorsProc AssociateColors; static Blt_UnassociateColorsProc UnassociateColors; static Blt_FadePictureProc FadePicture; static Blt_CopyPictureBitsProc CopyPictureBits; static Blt_PictureProcs stdPictureProcs = { ApplyPictureToPicture, ApplyScalarToPicture, ApplyPictureToPictureWithMask, ApplyScalarToPictureWithMask, TentHorizontally, TentVertically, ZoomHorizontally, ZoomVertically, BlendPictures, SelectPixels, AssociateColors, UnassociateColors, FadePicture, CopyPictureBits }; Blt_PictureProcs *bltPictProcsPtr = &stdPictureProcs; void Blt_ApplyPictureToPicture(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy, Blt_PictureArithOps op) { (*bltPictProcsPtr->applyPictureToPictureProc)(dest, src, x, y, w, h, dx, dy, op); } void Blt_ApplyScalarToPicture(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_PictureArithOps op) { (*bltPictProcsPtr->applyScalarToPictureProc)(dest, colorPtr, op); } void Blt_ApplyPictureToPictureWithMask(Blt_Picture dest, Blt_Picture src, Blt_Picture mask, int x, int y, int w, int h, int dx, int dy, int invert, Blt_PictureArithOps op) { (*bltPictProcsPtr->applyPictureToPictureWithMaskProc)(dest, src, mask, x, y, w, h, dx, dy, invert, op); } void Blt_ApplyScalarToPictureWithMask(Blt_Picture dest, Blt_Pixel *colorPtr, Blt_Picture mask, int invert, Blt_PictureArithOps op) { (*bltPictProcsPtr->applyScalarToPictureWithMaskProc)(dest, colorPtr, mask, invert, op); } void Blt_TentHorizontally(Blt_Picture dest, Blt_Picture src) { (*bltPictProcsPtr->tentHorizontallyProc)(dest, src); } void Blt_TentVertically(Blt_Picture dest, Blt_Picture src) { (*bltPictProcsPtr->tentVerticallyProc)(dest, src); } void Blt_ZoomHorizontally(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter) { (*bltPictProcsPtr->zoomHorizontallyProc)(dest, src, filter); } void Blt_ZoomVertically(Blt_Picture dest, Blt_Picture src, Blt_ResampleFilter filter) { (*bltPictProcsPtr->zoomVerticallyProc)(dest, src, filter); } void Blt_BlendPictures(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy) { (*bltPictProcsPtr->blendPicturesProc)(dest, src, x, y, w, h, dx, dy); } void Blt_SelectPixels(Blt_Picture dest, Blt_Picture src, Blt_Pixel *lowPtr , Blt_Pixel *highPtr) { (*bltPictProcsPtr->selectPixelsProc)(dest, src, lowPtr, highPtr); } void Blt_AssociateColors(Blt_Picture picture) { (*bltPictProcsPtr->associateColorsProc)(picture); } void Blt_UnassociateColors(Blt_Picture picture) { (*bltPictProcsPtr->unassociateColorsProc)(picture); } void Blt_FadePicture(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy, int alpha) { (*bltPictProcsPtr->fadePictureProc)(dest, src, x, y, w, h, dx, dy, alpha); } void Blt_CopyPictureBits(Blt_Picture dest, Blt_Picture src, int x, int y, int w, int h, int dx, int dy) { (*bltPictProcsPtr->copyPictureBitsProc)(dest, src, x, y, w, h, dx, dy); } /* *--------------------------------------------------------------------------- * * Blt_CreatePicture -- * * Allocates a picture of a designated height and width. * * This routine will be augmented with other types of information such as * a color table, etc. * * Results: * Returns the new color pict. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_CreatePicture(int w, int h) { Pict *destPtr; int pixelsPerRow; size_t size; unsigned char *buffer; ptrdiff_t ptr; assert((w > 0) && (w <= SHRT_MAX)); assert((h > 0) && (h <= SHRT_MAX)); /* * Be careful. There's a bunch of picture routines that assume an even * number of pixels per row. */ pixelsPerRow = (w + 3) & ~3; /* Align each row on a 16-byte boundary. */ destPtr = Blt_AssertMalloc(sizeof(Pict)); destPtr->pixelsPerRow = pixelsPerRow; destPtr->width = w; destPtr->height = h; destPtr->flags = BLT_PIC_DIRTY; destPtr->delay = 0; /* Over-allocate a buffer so that we can align it (if needed) to a 16-byte * boundary. */ size = (pixelsPerRow * h * sizeof(Blt_Pixel)) + ALIGNMENT; buffer = Blt_AssertCalloc(1, size); ptr = (ptrdiff_t)buffer; destPtr->bits = (Blt_Pixel *)(ptr + (ptr & (ALIGNMENT-1))); destPtr->buffer = buffer; return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_FreePicture -- * * Deallocates the given picture. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_FreePicture(Pict *pictPtr) { Blt_Free(pictPtr->buffer); Blt_Free(pictPtr); } void Blt_SizeOfPicture(Pict *pictPtr, int *widthPtr , int *heightPtr) { *widthPtr = pictPtr->width; *heightPtr = pictPtr->height; } void Blt_ResizePicture(Pict *srcPtr, int w, int h) { assert((w > 0) && (w <= SHRT_MAX)); assert((h > 0) && (h <= SHRT_MAX)); if ((w != srcPtr->width) || (h != srcPtr->height)) { int pixelsPerRow; size_t size; ptrdiff_t ptr; void *buffer; pixelsPerRow = (w + 3) & ~3; /* Align each row on a 16-byte * boundary. */ size = (pixelsPerRow * h * sizeof(Blt_Pixel)) + ALIGNMENT; buffer = Blt_Realloc(srcPtr->buffer, size); assert(buffer != NULL); srcPtr->pixelsPerRow = pixelsPerRow; srcPtr->width = w; srcPtr->height = h; ptr = (ptrdiff_t)buffer; srcPtr->bits = (Blt_Pixel *)(ptr + (ptr & (ALIGNMENT-1))); srcPtr->flags = BLT_PIC_DIRTY; srcPtr->buffer = buffer; } } void Blt_AdjustPicture(Pict *srcPtr, int w, int h) { assert((w > 0) && (w <= SHRT_MAX)); assert((h > 0) && (h <= SHRT_MAX)); if ((w != srcPtr->width) || (h != srcPtr->height)) { int pixelsPerRow; int bytesPerRow; size_t size; void *buffer; ptrdiff_t ptr; Blt_Pixel *bits; /* * Be careful. There's a bunch of picture routines that assume an even * number of pixels per row. */ pixelsPerRow = (w + 3) & ~3; /* Align each row on a 16-byte * boundary. */ size = (pixelsPerRow * h * sizeof(Blt_Pixel)) + ALIGNMENT; buffer = Blt_AssertMalloc(size); ptr = (ptrdiff_t)buffer; bits = (Blt_Pixel *)(ptr + (ptr & (ALIGNMENT-1))); if (srcPtr->bits != NULL && (srcPtr->pixelsPerRow > 0)) { Blt_Pixel *srcRowPtr, *destRowPtr; int y, nRows; bytesPerRow = sizeof(Blt_Pixel) * MIN(pixelsPerRow, srcPtr->pixelsPerRow); nRows = MIN(srcPtr->height, h); srcRowPtr = srcPtr->bits, destRowPtr = bits; for (y = 0; y < nRows; y++) { memcpy(destRowPtr, srcRowPtr, bytesPerRow); destRowPtr += pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } Blt_Free(srcPtr->buffer); } srcPtr->pixelsPerRow = pixelsPerRow; srcPtr->width = w; srcPtr->height = h; srcPtr->bits = bits; srcPtr->buffer = buffer; srcPtr->flags = BLT_PIC_DIRTY; } } void Blt_BlankPicture(Pict *destPtr, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { int n; Blt_Pixel *dp; dp = destRowPtr; n = (destPtr->width + 7) / 8; /* width > 0 assumed */ switch (destPtr->width & 0x7) { case 0: do { dp->u32 = colorPtr->u32, dp++; case 7: dp->u32 = colorPtr->u32, dp++; case 6: dp->u32 = colorPtr->u32, dp++; case 5: dp->u32 = colorPtr->u32, dp++; case 4: dp->u32 = colorPtr->u32, dp++; case 3: dp->u32 = colorPtr->u32, dp++; case 2: dp->u32 = colorPtr->u32, dp++; case 1: dp->u32 = colorPtr->u32, dp++; } while (--n > 0); } destRowPtr += destPtr->pixelsPerRow; } destPtr->flags |= BLT_PIC_DIRTY; destPtr->flags &= ~(BLT_PIC_BLEND | BLT_PIC_MASK); if (colorPtr->Alpha == 0x00) { destPtr->flags |= BLT_PIC_MASK; } else if (colorPtr->Alpha != 0xFF) { destPtr->flags |= BLT_PIC_BLEND; } } void Blt_BlankRegion(Pict *destPtr, int x, int y, int w, int h, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; int y1, x1; assert ((x >= 0) && (y >= 0)); if ((x >= destPtr->width) || (y >= destPtr->height)) { return; } x1 = x + w; y1 = y + h; if (x1 > destPtr->width) { x1 = destPtr->width; } if (y1 > destPtr->height) { y1 = destPtr->height; } w = x1 - x; h = y1 - y; destRowPtr = destPtr->bits + (y * destPtr->pixelsPerRow) + x; for (y = 0; y < h; y++) { int n; Blt_Pixel *dp; dp = destRowPtr; n = (w + 7) / 8; /* width > 0 assumed */ switch (w & 0x7) { case 0: do { dp->u32 = colorPtr->u32, dp++; case 7: dp->u32 = colorPtr->u32, dp++; case 6: dp->u32 = colorPtr->u32, dp++; case 5: dp->u32 = colorPtr->u32, dp++; case 4: dp->u32 = colorPtr->u32, dp++; case 3: dp->u32 = colorPtr->u32, dp++; case 2: dp->u32 = colorPtr->u32, dp++; case 1: dp->u32 = colorPtr->u32, dp++; } while (--n > 0); } destRowPtr += destPtr->pixelsPerRow; } destPtr->flags |= BLT_PIC_DIRTY; destPtr->flags &= ~(BLT_PIC_BLEND | BLT_PIC_MASK); if (colorPtr->Alpha == 0x00) { destPtr->flags |= BLT_PIC_MASK; } else if (colorPtr->Alpha != 0xFF) { destPtr->flags |= BLT_PIC_BLEND; } } #ifdef notdef static void ComputeGammaTable(float gamma, unsigned char lut[]) { int i; double iGamma; iGamma = 1.0 / (double)gamma; for (i = 0; i < 256; i++) { double value; value = 255.0 * pow((double)i / 255.0, iGamma); lut[i] = (unsigned char)CLAMP(value); } } #endif static void ComputeGammaTable2(float gamma, unsigned char lut[]) { int i; double iGamma; double cutoff, exp; iGamma = 1.0 / (double)gamma; cutoff = 0.018; exp = (1.099 * pow(cutoff, iGamma) - 0.099) / cutoff; for (i = 0; i < 256; i++) { double value, intensity; intensity = (double)i / 255.0; if (intensity < cutoff) { intensity *= exp; } else { intensity = (1.099 * pow(intensity, iGamma) - 0.099); } value = 255.0 * intensity; lut[i] = (unsigned char)CLAMP(value); } } void Blt_GammaCorrectPicture(Pict *destPtr, Pict *srcPtr, float gamma) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; unsigned char lut[256]; ComputeGammaTable2(gamma, lut); srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *dp, *send; sp = srcRowPtr, dp = destRowPtr; for (send = sp + srcPtr->width; sp < send; sp++, dp++) { dp->Red = lut[(unsigned int)sp->Red]; dp->Green = lut[(unsigned int)sp->Green]; dp->Blue = lut[(unsigned int)sp->Blue]; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } /* *--------------------------------------------------------------------------- * * Blt_GreyscalePicture -- * * Returns a new picture converted to grey scale. All three picture * color components will have the same value. * * Luminosity is computed using the formula, * * Y = 0.212671 * Red + 0.715160 * Green + 0.072169 * Blue * * which is supposed to better represent contemporary monitors. * * Results: * Returns a new greyscale picture. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_GreyscalePicture(Pict *srcPtr) { Pict *destPtr; Blt_Pixel *srcRowPtr, *destRowPtr; int y; /* * We can use scaled integers (20-bit fraction) to compute the luminosity * with reasonable accuracy considering it's stored in an 8-bit result. */ #define YR 223002 /* 0.212671 */ #define YG 749900 /* 0.715160 */ #define YB 75675 /* 0.072169 */ #define YMAX 267386880 /* 255.0 */ #define YCLAMP(s) \ (unsigned char)((s) > YMAX) ? 255 : ((((s) + 524288) >> 20)) destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *dp, *send; sp = srcRowPtr, dp = destRowPtr; for (send = sp + srcPtr->width; sp < send; sp++, dp++) { unsigned int Y; Y = YR * sp->Red + YG * sp->Green + YB * sp->Blue; dp->Red = dp->Green = dp->Blue = YCLAMP(Y); dp->Alpha = sp->Alpha; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } destPtr->flags = srcPtr->flags; destPtr->flags |= BLT_PIC_DIRTY; destPtr->flags &= ~BLT_PIC_COLOR; return destPtr; } static void FadePicture(Pict *destPtr, Pict *srcPtr, int sx, int sy, int w, int h, int dx, int dy, int alpha) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if (srcPtr != destPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); } destRowPtr = destPtr->bits; srcRowPtr = srcPtr->bits; if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(srcPtr); } for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *dp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++, dp++) { dp->Alpha -= alpha; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } destPtr->flags |= BLT_PIC_BLEND; } static void AssociateColors(Pict *srcPtr) { if ((srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; sp = srcRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { /* No conversion necessary if 100% transparent or opaque. */ if ((sp->Alpha != 0xFF) && (sp->Alpha != 0x00)) { int t; sp->Red = imul8x8(sp->Alpha, sp->Red, t); sp->Green = imul8x8(sp->Alpha, sp->Green, t); sp->Blue = imul8x8(sp->Alpha, sp->Blue, t); } } srcRowPtr += srcPtr->pixelsPerRow; } srcPtr->flags |= BLT_PIC_ASSOCIATED_COLORS; } } static void UnassociateColors(Pict *srcPtr) { if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; sp = srcRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { /* No conversion necessary if 100% transparent or opaque. */ if ((sp->Alpha != 0xFF) && (sp->Alpha != 0x00)) { int bias; bias = sp->Alpha >> 1; sp->Red = (mul255(sp->Red) + bias) / sp->Alpha; sp->Green = (mul255(sp->Green) + bias) / sp->Alpha; sp->Blue = (mul255(sp->Blue) + bias) / sp->Alpha; } } srcRowPtr += srcPtr->pixelsPerRow; } srcPtr->flags &= ~BLT_PIC_ASSOCIATED_COLORS; } } /* * * x,y------+ * | | * | *----+------------+ * | | | | * | | | | */ static void BlendPictures(Pict *destPtr, Pict *srcPtr, int sx, int sy, int w, int h, int dx, int dy) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if (((dx + w) < 0) || ((dy + h) < 0)) { return; } if (dx < 0) { w += dx; dx = 0; } if (dy < 0) { h += dy; dy = 0; } if (destPtr->width < (dx + w)) { w = destPtr->width - dx; } if (destPtr->height < (dy + h)) { h = destPtr->height - dy; } if (srcPtr->width < w) { w = srcPtr->width; } if (srcPtr->height < h) { h = srcPtr->height; } if ((srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(srcPtr); } if ((destPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(destPtr); } destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((sy * srcPtr->pixelsPerRow) + sx); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++, sp++) { /* Blend the foreground and background together. */ if (sp->Alpha == 0xFF) { *dp = *sp; } else if (sp->Alpha != 0x00) { int beta, t; int r, g, b, a; beta = sp->Alpha ^ 0xFF; /* beta = 1 - alpha */ r = sp->Red + imul8x8(beta, dp->Red, t); g = sp->Green + imul8x8(beta, dp->Green, t); b = sp->Blue + imul8x8(beta, dp->Blue, t); a = sp->Alpha + imul8x8(beta, dp->Alpha, t); dp->Red = (r > 255) ? 255 : ((r < 0) ? 0 : r); dp->Green = (g > 255) ? 255 : ((g < 0) ? 0 : g); dp->Blue = (b > 255) ? 255 : ((b < 0) ? 0 : b); dp->Alpha = (a > 255) ? 255 : ((a < 0) ? 0 : a); } } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } static void BlendPictureArea2( Pict *destPtr, /* (in/out) Background picture. * Composite overwrites region in * background. */ Pict *srcPtr, /* Foreground picture. */ Blt_BlendingMode mode, /* Blend mode. */ int sx, int sy, /* Origin of foreground region in * source. */ int w, int h, /* Dimension of region to be blended. */ int dx, int dy) /* Origin of background region in * destination. */ { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if ((srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(srcPtr); } if ((destPtr->flags & BLT_PIC_ASSOCIATED_COLORS) == 0) { Blt_AssociateColors(destPtr); } destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((sy * srcPtr->pixelsPerRow) + sx); for (y = 0; y < h; y++) { Blt_Pixel *sp, *send, *dp; dp = destRowPtr; for (sp = srcRowPtr, send = sp + w; sp < send; sp++, dp++) { int r, g, b, a; double fa, z; /* * C = ((1 - Fa) * B) + ((1 - Ba) * F) + (Fa * Ba * BLEND(F,B)); */ { int fgBeta, bgBeta; bgBeta = dp->Alpha ^ 0xFF; fgBeta = sp->Alpha ^ 0xFF; r = (fgBeta * dp->Red) + (bgBeta * sp->Red); g = (fgBeta * dp->Green) + (bgBeta * sp->Green); b = (fgBeta * dp->Blue) + (bgBeta * sp->Blue); a = (fgBeta * dp->Alpha) + (bgBeta * sp->Alpha); } switch (mode) { case BLT_BLEND_NORMAL: /* C = F */ r += dp->Alpha * sp->Red; g += dp->Alpha * sp->Green; b += dp->Alpha * sp->Blue; a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_MULTIPLY: /* C = F * B */ r += dp->Red * sp->Red; g += dp->Green * sp->Green; b += dp->Blue * sp->Blue; a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_COLORDODGE: /* C = B / (1 - F) */ if (sp->Alpha > 0) { fa = 1.0 / sp->Alpha; z = (sp->Alpha * dp->Red) / (1.0 - (sp->Red * fa)); r += (int)(z + 0.5); z = (sp->Alpha * dp->Green) / (1.0 - (sp->Green * fa)); g += (int)(z + 0.5) ; z = (sp->Alpha * dp->Blue) / (1.0 - (sp->Blue * fa)); b += (int)(z + 0.5); a += dp->Alpha * sp->Alpha; } else { r += dp->Alpha * sp->Red; g += dp->Alpha * sp->Green; b += dp->Alpha * sp->Blue; a += dp->Alpha * sp->Alpha; } break; case BLT_BLEND_COLORBURN: /* C = B / F; */ if (sp->Alpha > 0) { fa = 1.0 / sp->Alpha; z = 511.0 * ((dp->Alpha * sp->Red * fa) - ((sp->Alpha * dp->Red) / (sp->Red + 1))); r += (int)(z + 0.5); z = 511.0 * ((dp->Alpha * sp->Green * fa) - ((sp->Alpha * dp->Green) / (sp->Green + 1))); g += (int)(z + 0.5); z = 511.0 * ((dp->Alpha * sp->Blue * fa) - ((sp->Alpha * dp->Blue) / (sp->Blue + 1))); b += (int)(z + 0.5); a += dp->Alpha * sp->Alpha; } else { r += dp->Alpha * sp->Red; g += dp->Alpha * sp->Green; b += dp->Alpha * sp->Blue; a += dp->Alpha * sp->Alpha; } break; case BLT_BLEND_OVERLAY: /* Multiplies or screens depending upon * background color. */ if (dp->Red < 128) { r += dp->Red * sp->Red; } else { r += ((sp->Alpha * dp->Red) + (dp->Alpha * sp->Red) - (sp->Red * dp->Red)); } if (dp->Green < 128) { g += dp->Green * sp->Green; } else { g += ((sp->Alpha * dp->Green) + (dp->Alpha * sp->Green) - (sp->Green * dp->Green)); } if (dp->Blue < 128) { b += dp->Blue * sp->Blue; } else { b += ((sp->Alpha * dp->Blue) + (dp->Alpha * sp->Blue) - (sp->Blue * dp->Blue)); } a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_SCREEN: /* C = 1 - ((1 - F) * B) */ r += ((sp->Alpha * dp->Red) + (dp->Alpha * sp->Red) - (sp->Red * dp->Red)); g += ((sp->Alpha * dp->Green) + (dp->Alpha * sp->Green) - (sp->Green * dp->Green)); b += ((sp->Alpha * dp->Blue) + (dp->Alpha * sp->Blue) - (sp->Blue * dp->Blue)); a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_DARKEN: /* C = min(F,B) */ r += MIN(dp->Alpha * sp->Red, sp->Alpha * dp->Red); g += MIN(dp->Alpha * sp->Green, sp->Alpha * dp->Green); b += MIN(dp->Alpha * sp->Blue, sp->Alpha * dp->Blue); a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_LIGHTEN: /* C = max(F,B) */ r += MAX(dp->Alpha * sp->Red, sp->Alpha * dp->Red); g += MAX(dp->Alpha * sp->Green, sp->Alpha * dp->Green); b += MAX(dp->Alpha * sp->Blue, sp->Alpha * dp->Blue); a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_DIFFERENCE: /* C = |F - B| */ /* C = |(F * Ba) - (B * Fa)| */ r += ABS((dp->Alpha * sp->Red) - (sp->Alpha * dp->Red)); g += ABS((dp->Alpha * sp->Green) - (sp->Alpha * dp->Green)); b += ABS((dp->Alpha * sp->Blue) - (sp->Alpha * dp->Blue)); a += dp->Alpha * sp->Alpha; break; case BLT_BLEND_HARDLIGHT: if (sp->Red > 127) { r += ((sp->Alpha * dp->Red) + (dp->Alpha * sp->Red) - (sp->Red * dp->Red)); } else { r += dp->Red * sp->Red; } if (sp->Green > 127) { g += ((sp->Alpha * dp->Green) + (dp->Alpha * sp->Green) - (sp->Green * dp->Green)); } else { g += dp->Green * sp->Green; } if (sp->Blue > 127) { b += ((sp->Alpha * dp->Blue) + (dp->Alpha * sp->Blue) - (sp->Blue * dp->Blue)); } else { b += dp->Blue * sp->Blue; } a += MIN(sp->Alpha, dp->Alpha); break; case BLT_BLEND_SOFTLIGHT: fa = 1.0 / sp->Alpha; if (sp->Red > 127) { z = (sp->Alpha * dp->Red) / (1.0 - (sp->Red * fa)); } else { z = 511.0 * ((dp->Alpha * sp->Red * fa) - ((sp->Alpha * dp->Red) / (sp->Red + 1))); } r += (int)(z + 0.5); if (sp->Green > 127) { z = (sp->Alpha * dp->Green) / (1.0 - (sp->Green * fa)); } else { z = 511.0 * ((dp->Alpha * sp->Green * fa) - ((sp->Alpha * dp->Green) / (sp->Green + 1))); } g += (int)(z + 0.5); if (sp->Blue > 127) { z = (sp->Alpha * dp->Blue) / (1.0 - (sp->Blue * fa)); } else { z = 511.0 * ((dp->Alpha * sp->Blue * fa) - ((sp->Alpha * dp->Blue) / (sp->Blue + 1))); } b += (int)(z + 0.5); a += sp->Alpha * dp->Alpha; break; } dp->Red = (r >= 65025) ? 255 : ((r < 0) ? 0 : div255(r)); dp->Green = (g >= 65025) ? 255 : ((g < 0) ? 0 : div255(g)); dp->Blue = (b >= 65025) ? 255 : ((b < 0) ? 0 : div255(b)); dp->Alpha = (a >= 65025) ? 255 : ((a < 0) ? 0 : div255(a)); } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } void Blt_BlendPicturesByMode(Pict *destPtr, Pict *srcPtr, Blt_BlendingMode mode) { BlendPictureArea2(destPtr, srcPtr, mode, 0, 0, srcPtr->width, srcPtr->height, 0, 0); } /* *--------------------------------------------------------------------------- * * Blt_BitmapToPicture -- * * Converts the given bitmap into a picture. * * Results: * Returns a new picture containing the bitmap image. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_BitmapToPicture( Display *display, Pixmap bitmap, /* Source bitmap. */ int w, int h, /* Width and height of the bitmap */ Blt_Pixel *fg, /* Foreground pixel color */ Blt_Pixel *bg) /* Background pixel color */ { XImage *imagePtr; Blt_Pixel *destRowPtr; Pict *destPtr; int y; unsigned int flags; imagePtr = XGetImage(display, bitmap, 0, 0, w, h, 1, ZPixmap); destPtr = Blt_CreatePicture(w, h); destRowPtr = destPtr->bits; for (y = 0; y < h; y++) { Blt_Pixel *dp; int x; /* * The slow but robust brute force method of converting an X image: * FIXME: update to avoid XGetPixel calls. */ dp = destRowPtr; for (x = 0; x < w; x++, dp++) { unsigned int pixel; pixel = XGetPixel(imagePtr, x, y); dp->u32 = (pixel) ? fg->u32 : bg->u32; } destRowPtr += destPtr->pixelsPerRow; } XDestroyImage(imagePtr); flags = 0; if (bg->Alpha == 0x00) { flags |= BLT_PIC_MASK; } else if (bg->Alpha != 0xFF) { flags |= BLT_PIC_BLEND; } if (fg->Alpha == 0x00) { flags |= BLT_PIC_MASK; } else if (fg->Alpha != 0xFF) { flags |= BLT_PIC_BLEND; } destPtr->flags |= flags; return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_PictureToPhoto -- * * Translates a picture into a Tk photo. * * Results: * The photo is re-written with the new picture. * *--------------------------------------------------------------------------- */ void Blt_PictureToPhoto(Pict *srcPtr, Tk_PhotoHandle photo) { Tk_PhotoImageBlock dib; /* Destination image block. */ Tk_PhotoGetImage(photo, &dib); dib.pixelSize = sizeof(Blt_Pixel); dib.pitch = sizeof(Blt_Pixel) * srcPtr->pixelsPerRow; dib.width = srcPtr->width; dib.height = srcPtr->height; dib.offset[0] = Blt_Offset(Blt_Pixel, Red); dib.offset[1] = Blt_Offset(Blt_Pixel, Green); dib.offset[2] = Blt_Offset(Blt_Pixel, Blue); dib.offset[3] = Blt_Offset(Blt_Pixel, Alpha); Tk_PhotoSetSize(photo, srcPtr->width, srcPtr->height); if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Pict *tmpPtr; /* Divide out the alphas from picture's pre-multipled RGB values. */ tmpPtr = Blt_ClonePicture(srcPtr); Blt_UnassociateColors(tmpPtr); dib.pixelPtr = (unsigned char *)tmpPtr->bits; Tk_PhotoSetSize(photo, tmpPtr->width, tmpPtr->height); Tk_PhotoPutBlock(photo, &dib, 0, 0, tmpPtr->width, tmpPtr->height); Blt_FreePicture(tmpPtr); } else { dib.pixelPtr = (unsigned char *)srcPtr->bits; Tk_PhotoPutBlock(photo, &dib, 0, 0, srcPtr->width, srcPtr->height); } } /* *--------------------------------------------------------------------------- * * Blt_PhotoAreaToPicture -- * * Create a picture from a region in a photo image. * * Results: * The new picture is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_PhotoAreaToPicture(Tk_PhotoHandle photo, int x, int y, int w, int h) { Tk_PhotoImageBlock sib; /* Source image block. */ Pict *destPtr; int offset; int ir, ib, ig, ia; if (x < 0) { x = 0; } if (y < 0) { y = 0; } Tk_PhotoGetImage(photo, &sib); if (w < 0) { w = sib.width; } if (h < 0) { h = sib.height; } if ((x + w) > sib.width) { w = sib.width - x; } if ((h + y) > sib.height) { h = sib.width - y; } offset = (x * sib.pixelSize) + (y * sib.pitch); destPtr = Blt_CreatePicture(w, h); ir = sib.offset[0]; ig = sib.offset[1]; ib = sib.offset[2]; ia = sib.offset[3]; if (sib.pixelSize == 4) { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < h; y++) { Blt_Pixel *dp; unsigned char *bits; dp = destRowPtr; bits = sib.pixelPtr + offset; for (x = 0; x < w; x++) { dp->Alpha = bits[ia]; if (dp->Alpha == 0xFF) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; } else if (dp->Alpha == 0x00) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; destPtr->flags |= BLT_PIC_MASK; } else { int t; /* * Premultiple the alpha into each component. * (0..255 * 0..255) / 255.0 */ dp->Red = imul8x8(dp->Alpha, bits[ir], t); dp->Green = imul8x8(dp->Alpha, bits[ig], t); dp->Blue = imul8x8(dp->Alpha, bits[ib], t); destPtr->flags |= (BLT_PIC_BLEND | BLT_PIC_ASSOCIATED_COLORS); } bits += sib.pixelSize; dp++; } offset += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } else if (sib.pixelSize == 3) { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < h; y++) { Blt_Pixel *dp; unsigned char *bits; dp = destRowPtr; bits = sib.pixelPtr + offset; for (x = 0; x < w; x++) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; dp->Alpha = ALPHA_OPAQUE; bits += sib.pixelSize; dp++; } offset += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } else { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < h; y++) { Blt_Pixel *dp; unsigned char *bits; dp = destRowPtr; bits = sib.pixelPtr + offset; for (x = 0; x < w; x++) { dp->Red = dp->Green = dp->Blue = bits[ir]; dp->Alpha = ALPHA_OPAQUE; bits += sib.pixelSize; dp++; } offset += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_PhotoToPicture -- * * Create a picture from a photo image. * * Results: * The new picture is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_PhotoToPicture(Tk_PhotoHandle photo) /* Source photo to convert. */ { Pict *destPtr; Tk_PhotoImageBlock sib; /* Source image block. */ int bytesPerRow; int sw, sh; int ir, ib, ig, ia; Tk_PhotoGetImage(photo, &sib); sw = sib.width; sh = sib.height; bytesPerRow = sib.pixelSize * sw; ir = sib.offset[0]; ig = sib.offset[1]; ib = sib.offset[2]; ia = sib.offset[3]; destPtr = Blt_CreatePicture(sw, sh); if (sib.pixelSize == 4) { Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = sib.pixelPtr; destRowPtr = destPtr->bits; for (y = 0; y < sh; y++) { Blt_Pixel *dp; unsigned char *bits, *bend; dp = destRowPtr; for (bits = srcRowPtr, bend = bits + bytesPerRow; bits < bend; bits += sib.pixelSize) { dp->Alpha = bits[ia]; if (dp->Alpha == 0xFF) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; } else if (dp->Alpha == 0x00) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; destPtr->flags |= BLT_PIC_MASK; } else { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; destPtr->flags |= BLT_PIC_BLEND; } dp++; } srcRowPtr += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } else if (sib.pixelSize == 3) { Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = sib.pixelPtr; destRowPtr = destPtr->bits; for (y = 0; y < sh; y++) { Blt_Pixel *dp; unsigned char *bits, *bend; dp = destRowPtr; for (bits = srcRowPtr, bend = bits + bytesPerRow; bits < bend; bits += sib.pixelSize) { dp->Red = bits[ir]; dp->Green = bits[ig]; dp->Blue = bits[ib]; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } else { Blt_Pixel *destRowPtr; int y; unsigned char *srcRowPtr; srcRowPtr = sib.pixelPtr; destRowPtr = destPtr->bits; for (y = 0; y < sh; y++) { Blt_Pixel *dp; unsigned char *bits, *bend; dp = destRowPtr; for (bits = srcRowPtr, bend = bits + bytesPerRow; bits < bend; bits += sib.pixelSize) { dp->Red = dp->Green = dp->Blue = bits[ir]; dp->Alpha = ALPHA_OPAQUE; dp++; } srcRowPtr += sib.pitch; destRowPtr += destPtr->pixelsPerRow; } } return destPtr; } /* * filter function definitions */ /* *--------------------------------------------------------------------------- * * ByteToAsciiHex -- * * Convert a byte to its ASCII hexidecimal equivalent. * * Results: * The converted 2 ASCII character string is returned. * *--------------------------------------------------------------------------- */ INLINE static void ByteToAsciiHex(unsigned char byte, char *string) { static char hexDigits[] = "0123456789ABCDEF"; string[0] = hexDigits[byte >> 4]; string[1] = hexDigits[byte & 0x0F]; } /* *--------------------------------------------------------------------------- * * Blt_PictureToDBuffer -- * * Converts a picture to PostScript RGB (3 components) or Greyscale (1 * component) output. With 3 components, we assume the "colorimage" * operator is available. * * Note: The picture is converted from bottom to top, to conform * with the PostScript coordinate system. * * Results: * The PostScript data comprising the picture is written into the dynamic * string. * *--------------------------------------------------------------------------- */ Blt_DBuffer Blt_PictureToDBuffer(Pict *srcPtr, int nComponents) { Blt_DBuffer dBuffer; int length; dBuffer = Blt_DBuffer_Create(); length = srcPtr->width * srcPtr->height * nComponents; Blt_DBuffer_Resize(dBuffer, length); if (nComponents == 3) { Blt_Pixel *srcRowPtr; int y; unsigned char *bp; bp = Blt_DBuffer_Pointer(dBuffer); srcRowPtr = srcPtr->bits + ((srcPtr->height-1) * srcPtr->pixelsPerRow); for (y = (srcPtr->height - 1); y >= 0; y--) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { bp[0] = sp->Red; bp[1] = sp->Green; bp[2] = sp->Blue; bp += 3; } srcRowPtr -= srcPtr->pixelsPerRow; } } else if (nComponents == 1) { Blt_Pixel *srcRowPtr; int y; unsigned char *bp; bp = Blt_DBuffer_Pointer(dBuffer); srcRowPtr = srcPtr->bits + ((srcPtr->height-1) * srcPtr->pixelsPerRow); for (y = (srcPtr->height - 1); y >= 0; y--) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { *bp++ = sp->Red; } srcRowPtr -= srcPtr->pixelsPerRow; } } Blt_DBuffer_SetLength(dBuffer, length); return dBuffer; } /* *--------------------------------------------------------------------------- * * Blt_PictureToPsData -- * * Converts a picture to PostScript RGB (3 components) or Greyscale (1 * component) output. With 3 components, we assume the "colorimage" * operator is available. * * Note: The picture is converted from bottom to top, to conform * with the PostScript coordinate system. * * Results: * The PostScript data comprising the picture is written * into the dynamic string. * *--------------------------------------------------------------------------- */ int Blt_PictureToPsData( Pict *srcPtr, /* Picture to be represented in * PostScript. */ int nComponents, /* # of color components (1 or 3). If * it's 1, we only look at red for * color information. */ Tcl_DString *resultPtr, /* (out) Holds the generated * postscript */ const char *prefix) /* Indicates how to prefix the start of * each line of output. This is normally * used for PostScript previews, where * each line is * comment "% ". */ { int count, nLines; nLines = count = 0; if (nComponents == 3) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits + ((srcPtr->height-1) * srcPtr->pixelsPerRow); for (y = (srcPtr->height - 1); y >= 0; y--) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { char string[10]; if (count == 0) { Tcl_DStringAppend(resultPtr, prefix, -1); Tcl_DStringAppend(resultPtr, " ", -1); } count += 6; ByteToAsciiHex(sp->Red, string); ByteToAsciiHex(sp->Green, string + 2); ByteToAsciiHex(sp->Blue, string + 4); string[6] = '\0'; if (count >= 60) { string[6] = '\n'; string[7] = '\0'; count = 0; nLines++; } Tcl_DStringAppend(resultPtr, string, -1); } srcRowPtr -= srcPtr->pixelsPerRow; } } else if (nComponents == 1) { int y; Blt_Pixel *srcRowPtr; srcRowPtr = srcPtr->bits + ((srcPtr->height-1) * srcPtr->pixelsPerRow); for (y = (srcPtr->height - 1); y >= 0; y--) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { char string[10]; char byte; if (count == 0) { Tcl_DStringAppend(resultPtr, prefix, -1); Tcl_DStringAppend(resultPtr, " ", -1); } count += 2; byte = ~(sp->Red); ByteToAsciiHex(byte, string); string[2] = '\0'; if (count >= 60) { string[2] = '\n'; string[3] = '\0'; count = 0; nLines++; } Tcl_DStringAppend(resultPtr, string, -1); } srcRowPtr -= srcPtr->pixelsPerRow; } } if (count != 0) { Tcl_DStringAppend(resultPtr, "\n", -1); nLines++; } return nLines; } static double DefaultFilter(double x) { if (x < 0.0) { x = -x; } if (x < 1.0) { /* f(x) = 2x^3 - 3x^2 + 1, -1 <= x <= 1 */ return (2.0 * x - 3.0) * x * x + 1.0; } return 0.0; } /* Just for testing */ static double DummyFilter(double x) { return FABS(x); } /* * * Finite filters in increasing order: * Box (constant) * Triangle (linear) * Bell * BSpline (cubic) * */ static double BoxFilter(double x) { if ((x < -0.5) || (x > 0.5)) { return 0.0; } return 1.0; } static double TriangleFilter(double x) { if (x < 0.0) { x = -x; } if (x < 1.0) { return (1.0 - x); } return 0.0; } static double BellFilter(double x) { if (x < 0.0) { x = -x; } if (x < 0.5) { return (0.75 - (x * x)); } if (x < 1.5) { x = (x - 1.5); return (0.5 * (x * x)); } return 0.0; } static double BSplineFilter(double x) { double x2; if (x < 0.0) { x = -x; } if (x < 1) { x2 = x * x; return ((.5 * x2 * x) - x2 + (2.0 / 3.0)); } else if (x < 2) { x = 2 - x; return ((x * x * x) / 6.0); } return 0.0; } /* * * Infinite Filters: * Sinc perfect lowpass filter * Bessel circularly symmetric 2-D filter * Gaussian * Lanczos3 * Mitchell */ static double SincFilter(double x) { x *= M_PI; if (x == 0.0) { return 1.0; } return (sin(x) / x); } static double BesselFilter(double x) { /* * See Pratt "Digital Image Processing" p. 97 for Bessel functions * zeros are at approx x=1.2197, 2.2331, 3.2383, 4.2411, 5.2428, 6.2439, * 7.2448, 8.2454 */ #ifdef __BORLANDC__ return 0.0; #else return (x == 0.0) ? M_PI / 4.0 : j1(M_PI * x) / (x + x); #endif } #define SQRT_2PI 0.79788456080286541 /* sqrt(2.0 / M_PI) */ static double GaussianFilter(double x) { return exp(-2.0 * x * x) * SQRT_2PI; } static double Lanczos3Filter(double x) { if (x < 0) { x = -x; } if (x < 3.0) { return (SincFilter(x) * SincFilter(x / 3.0)); } return 0.0; } #define B 0.3333333333333333 /* (1.0 / 3.0) */ #define C 0.3333333333333333 /* (1.0 / 3.0) */ static double MitchellFilter(double x) { double x2; x2 = x * x; if (x < 0) { x = -x; } if (x < 1.0) { x = (((12.0 - 9.0 * B - 6.0 * C) * (x * x2)) + ((-18.0 + 12.0 * B + 6.0 * C) * x2) + (6.0 - 2 * B)); return (x / 6.0); } else if (x < 2.0) { x = (((-1.0 * B - 6.0 * C) * (x * x2)) + ((6.0 * B + 30.0 * C) * x2) + ((-12.0 * B - 48.0 * C) * x) + (8.0 * B + 24 * C)); return (x / 6.0); } return 0.0; } /* * Catmull-Rom spline */ static double CatRomFilter(double x) { if (x < -2.) { return 0.0; } if (x < -1.0) { return 0.5 * (4.0 + x * (8.0 + x * (5.0 + x))); } if (x < 0.0) { return 0.5 * (2.0 + x * x * (-5.0 + x * -3.0)); } if (x < 1.0) { return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0)); } if (x < 2.0) { return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x))); } return 0.0; } /* approximation to the gaussian integral [x, inf) */ static double GiFilter(double x) { if (x > 1.5) { return 0.0; } else if (x < -1.5) { return 1.0; } else { #define I6 0.166666666666667 #define I4 0.25 #define I3 0.333333333333333 double x2 = x * x; double x3 = x2 * x; if (x > 0.5) { return .5625 - ( x3 * I6 - 3 * x2 * I4 + 1.125 * x); } else if (x > -0.5) { return 0.5 - (0.75 * x - x3 * I3); } else { return 0.4375 + (-x3 * I6 - 3 * x2 * I4 - 1.125 * x); } } } static ResampleFilter resampleFilters[] = { /* Name, Function, Support */ {"bell", BellFilter, 1.5 }, {"bessel", BesselFilter, 3.2383 }, {"box", BoxFilter, 0.5 }, {"bspline", BSplineFilter, 2.0 }, {"catrom", CatRomFilter, 2.0 }, {"default", DefaultFilter, 1.0 }, {"dummy", DummyFilter, 0.5 }, {"gauss8", GaussianFilter, 8.0 }, {"gaussian", GaussianFilter, 1.25 }, {"gi", GiFilter, 4.0 }, {"gi8", GiFilter, 8.0 }, {"lanczos3", Lanczos3Filter, 3.0 }, {"mitchell", MitchellFilter, 2.0 }, {"none", (Blt_ResampleFilterProc *)NULL, 0.0 }, {"sinc", SincFilter, 4.0 }, {"sinc8", SincFilter, 8.0 }, {"sinc12", SincFilter, 12.0 }, {"tent", TriangleFilter, 1.0 }, {"triangle", TriangleFilter, 1.0 }, }; static int nFilters = sizeof(resampleFilters) / sizeof(ResampleFilter); Blt_ResampleFilter bltBoxFilter = &(resampleFilters[2]); Blt_ResampleFilter bltMitchellFilter = &(resampleFilters[11]); Blt_ResampleFilter bltBellFilter = &(resampleFilters[0]); Blt_ResampleFilter bltTentFilter = &(resampleFilters[16]); const char * Blt_NameOfResampleFilter(ResampleFilter *filterPtr) { return filterPtr->name; } /* *--------------------------------------------------------------------------- * * Blt_GetResampleFilterFromObj -- * * Finds a 1-D filter associated by the given filter name. * * Results: * A standard TCL result. Returns TCL_OK is the filter was found. The * filter information (proc and support) is returned via * filterPtrPtr. Otherwise TCL_ERROR is returned and an error message is * left in interp->result. * *--------------------------------------------------------------------------- */ int Blt_GetResampleFilterFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ResampleFilter **filterPtrPtr) { ResampleFilter *fp, *fend; const char *string; string = Tcl_GetString(objPtr); for (fp = resampleFilters, fend = fp + nFilters; fp < fend; fp++) { if (strcmp(string, fp->name) == 0) { *filterPtrPtr = (fp->proc == NULL) ? NULL : fp; return TCL_OK; } } if (interp != NULL) { Tcl_AppendResult(interp, "can't find filter \"", string, "\"", (char *)NULL); } return TCL_ERROR; } #ifdef notdef int Blt_GetTableFilterFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, TableFilter **filterPtrPtr) { TableFilter *filterPtr; Tcl_Obj **objv; double scale; int objc; /* Next see if it's a table (list of numbers) */ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; /* Can't split object. */ } if (Tcl_GetDoubleFromObj(interp, objv[0], &scale) != TCL_OK) { return TCL_ERROR; } objc--, objv++; if ((objc & 0x1) == 0) { Tcl_AppendResult(interp, "# of values in 1-D filter \"", string, "\" must be odd", (char *)NULL); return TCL_ERROR; } filterPtr = Blt_AssertMalloc(sizeof(TableFilter) + (sizeof(int) * objc)); filterPtr->nWeights = objc; filterPtr->scale = (float)scale; { int *tp, *tend, i; i = 0; for (tp = filterPtr->table, tend < tp + objc; tp < tend; tp++, i++) { if (Tcl_GetIntFromObj(interp, objv[i], tp) != TCL_OK) { Blt_Free(filterPtr); return TCL_ERROR; } } } *filterPtrPtr = filterPtr; return TCL_OK; } #endif unsigned int Blt_ComputeWeights(unsigned int sw, unsigned int dw, ResampleFilter *filterPtr, Sample **samplePtrPtr) { Sample *samples; double scale; size_t bytesPerSample; /* Pre-calculate filter contributions for a row or column. */ scale = (double)dw / (double)sw; if (scale < 1.0) { Sample *samplePtr; double r, fscale; int filterSize, x; /* Downsample */ r = filterPtr->support / scale; fscale = 1.0 / scale; filterSize = (int)(r * 2 + 2); bytesPerSample = sizeof(Sample) + ((filterSize - 1) * sizeof(PixelWeight)); samples = Blt_AssertCalloc(dw, bytesPerSample); samplePtr = samples; #define DEBUG 0 #if DEBUG fprintf(stderr, "downscale=%g, fscale=%g, radius=%g\n", scale, fscale, r); #endif for (x = 0; x < dw; x++) { PixelWeight *wp; double sum, center, factor; int i, left, right; /* filter bounds */ center = ((double)x) * fscale; /* Determine bounds of filter and its density */ #ifndef notdef left = (int)/*floor*/(center - r); #else left = CRoundToInt(center - r); #endif if (left < 0) { left = 0; } #ifndef notdef right = (int)/*floor*/(center + r); #else right = CRoundToInt(center + r); #endif if (right >= sw) { right = sw - 1; } samplePtr->start = left; samplePtr->wend = samplePtr->weights + (right - left + 1); sum = 0.0; for (wp = samplePtr->weights, i = left; i <= right; i++, wp++) { double val = ((double)i - center) * scale; wp->f32 = (float)(*filterPtr->proc)(val); sum += wp->f32; } factor = (sum == 0.0) ? 1.0 : (1.0 / sum); for (wp = samplePtr->weights; wp < samplePtr->wend; wp++) { wp->f32 = (float)(wp->f32 * factor); wp->i32 = float2si(wp->f32); } samplePtr = (Sample *)((char *)samplePtr + bytesPerSample); } } else { Sample *samplePtr; double fscale; int filterSize, x; /* Upsample */ filterSize = (int)(filterPtr->support * 2 + 2); bytesPerSample = sizeof(Sample) + ((filterSize - 1) * sizeof(PixelWeight)); samples = Blt_AssertCalloc(dw, bytesPerSample); fscale = 1.0 / scale; samplePtr = samples; #if DEBUG fprintf(stderr, "upscale=%g, fscale=%g, radius=%g\n", scale, fscale, filterPtr->support); #endif for (x = 0; x < dw; x++) { PixelWeight *wp; double sum, center, factor; int i, left, right; /* filter bounds */ center = ((double)x) * fscale; #ifndef notdef left = (int)(center - filterPtr->support); #else left = CRoundToInt(center - filterPtr->support); #endif if (left < 0) { left = 0; } #ifndef notdef right = (int)(center + filterPtr->support); #else right = CRoundToInt(center + filterPtr->support); #endif if (right >= sw) { right = sw - 1; } samplePtr->start = left; samplePtr->wend = samplePtr->weights + (right - left + 1); /* Sum the contributions for each pixel in the filter. */ sum = 0.0; for (wp = samplePtr->weights, i = left; i <= right;i++, wp++) { wp->f32 = (float) (*filterPtr->proc) ((double)i - center); sum += wp->f32; } /* The sum of the contributions should not be greater than 1.0 */ factor = (sum == 0.0) ? 1.0 : (1.0 / sum); for (wp = samplePtr->weights; wp < samplePtr->wend; wp++) { #ifdef notdef fprintf(stderr, "w[%d]=%g, %g sum=%g\n", wp - samplePtr->weights, wp->f32, wp->f32 * factor, sum); #endif wp->f32 = (float)(wp->f32 * factor); /* Convert each weight into a fixed-point scaled integer */ wp->i32 = float2si(wp->f32); } /* Go to the next sample. */ samplePtr = (Sample *)((char *)samplePtr + bytesPerSample); } } *samplePtrPtr = samples; return bytesPerSample; } static void ZoomVertically(Pict *destPtr, Pict *srcPtr, Blt_ResampleFilter filter) { Sample *samples, *send; int x; int bytesPerSample; /* Size of sample. */ /* Pre-calculate filter contributions for each row. */ bytesPerSample = Blt_ComputeWeights(srcPtr->height, destPtr->height, filter, &samples); send = (Sample *)((char *)samples + (destPtr->height * bytesPerSample)); /* Apply filter to each row. */ for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColPtr; Sample *samplePtr; int dummy; srcColPtr = srcPtr->bits + x; dp = destPtr->bits + x; for (samplePtr = samples; samplePtr < send; samplePtr = (Sample *)((char *)samplePtr + bytesPerSample)) { Blt_Pixel *sp; int r, g, b, a; PixelWeight *wp; r = g = b = a = 0; sp = srcColPtr + (samplePtr->start * srcPtr->pixelsPerRow); for (wp = samplePtr->weights; wp < samplePtr->wend; wp++) { a += wp->i32 * sp->Alpha; r += wp->i32 * sp->Red; g += wp->i32 * sp->Green; b += wp->i32 * sp->Blue; sp += srcPtr->pixelsPerRow; } dummy = 0; dp->Alpha = SICLAMP(a); dp->Red = SICLAMP(r); dp->Green = SICLAMP(g); dp->Blue = SICLAMP(b); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "v1: alpha=0x%x\n", dp->Alpha); } #endif dp += destPtr->pixelsPerRow; } } /* Free the memory allocated for filter weights. */ Blt_Free(samples); } static void ZoomHorizontally(Pict *destPtr, Pict *srcPtr, Blt_ResampleFilter filter) { Sample *samples, *send; int y; Blt_Pixel *srcRowPtr, *destRowPtr; int bytesPerSample; /* Size of sample. */ /* Pre-calculate filter contributions for each column. */ bytesPerSample = Blt_ComputeWeights(srcPtr->width, destPtr->width, filter, &samples); send = (Sample *)((char *)samples + (destPtr->width * bytesPerSample)); /* Apply filter to each column. */ srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; Sample *samplePtr; dp = destRowPtr; for (samplePtr = samples; samplePtr < send; samplePtr = (Sample *)((char *)samplePtr + bytesPerSample)) { Blt_Pixel *sp; int r, g, b, a; PixelWeight *wp; r = g = b = a = 0; sp = srcRowPtr + samplePtr->start; for (wp = samplePtr->weights; wp < samplePtr->wend; wp++) { a += wp->i32 * sp->Alpha; r += wp->i32 * sp->Red; g += wp->i32 * sp->Green; b += wp->i32 * sp->Blue; sp++; } dp->Alpha = SICLAMP(a); dp->Red = SICLAMP(r); dp->Green = SICLAMP(g); dp->Blue = SICLAMP(b); #ifdef notdef if (dp->Alpha != 0xFF) { fprintf(stdout, "h1: alpha=0x%x\n", dp->Alpha); } #endif dp++; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } /* Free the memory allocated for horizontal filter weights. */ Blt_Free(samples); } /* *--------------------------------------------------------------------------- * * Blt_ResamplePicture -- * * Resamples a given picture using 1-D filters and returns a new picture * of the designated size. * * Results: * Returns the resampled picture. The original picture * is left intact. * *--------------------------------------------------------------------------- */ void Blt_ResamplePicture(Pict *destPtr, Pict *srcPtr, Blt_ResampleFilter hFilter, Blt_ResampleFilter vFilter) { Pict *tmpPtr; tmpPtr = Blt_CreatePicture(destPtr->width, srcPtr->height); /* * It's usually faster to zoom vertically last. This has to do with the * fact that pictures are stored in contiguous rows. */ Blt_ZoomHorizontally(tmpPtr, srcPtr, hFilter); Blt_ZoomVertically(destPtr, tmpPtr, vFilter); Blt_FreePicture(tmpPtr); destPtr->flags = srcPtr->flags; destPtr->flags |= BLT_PIC_DIRTY; } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_ResamplePhoto -- * * Resamples a Tk photo image using 1-D filters and writes the image into * another Tk photo. It is possible for the source and destination to be * the same photo. * * Results: * The designated destination photo will contain the resampled * picture. The original photo is left intact. * *--------------------------------------------------------------------------- */ void Blt_ResamplePhoto( Tk_PhotoHandle srcPhoto, /* Source photo image to scale */ int x, int y, int width, int height, Tk_PhotoHandle destPhoto, /* Resulting scaled photo image */ Blt_ResampleFilter hFilter, Blt_ResampleFilter vFilter) { Blt_Picture src, dest; Tk_PhotoImageBlock dib; Tk_PhotoGetImage(destPhoto, &dib); src = Blt_PhotoAreaToPicture(srcPhoto, x, y, width, height); dest = Blt_CreatePicture(dib.width, dib.height); Blt_ResamplePicture(dest, src, hFilter, vFilter); Blt_FreePicture(src); Blt_PictureToPhoto(dest, destPhoto); Blt_FreePicture(dest); } #endif static void FillScaleTables( int sw, int sh, /* Dimension of source. */ int ax, int ay, /* Origin of requested area. */ int aw, int ah, /* Dimension of requested area. */ int dw, int destHeight, /* Desired new dimension. */ int *mapX, int *mapY) /* (out) Resulting mapping tables. */ { int left, right, top, bottom; double xScale, yScale; int x, y; left = ax; top = ay; right = MIN(sw, ax + aw) - 1; bottom = MIN(sh, ay + ah) - 1; xScale = (double)aw / (double)dw; for (x = 0; x < dw; x++) { int sx; sx = (int)(xScale * (double)x); sx += left; if (sx > right) { sx = right; } mapX[x] = sx; } yScale = (double)ah / (double)destHeight; for (y = 0; y < destHeight; y++) { int sy; sy = (int)(yScale * (double)y); sy += top; if (sy > bottom) { sy = bottom; } mapY[y] = sy; } } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_ResizePhoto -- * * Scales the region of the source image to the size of the destination * image. This routine performs raw scaling of the image and unlike * Blt_ResamplePhoto does not handle aliasing effects from subpixel * sampling. It is possible for the source and destination to be the same * photo. * * Results: * The designated destination photo will contain the resampled * picture. The original photo is left intact. * *--------------------------------------------------------------------------- */ void Blt_ResizePhoto( Tk_PhotoHandle srcPhoto, /* Source photo image to scaled. */ int srcX, int srcY, /* Area of source photo to be scaled. */ int sw, int sh, Tk_PhotoHandle destPhoto) /* (out) Resulting scaled photo image. * Scaling factors are derived from the * destination photo's dimensions. */ { Pict *destPtr; Tk_PhotoImageBlock sib, dib; /* Source and destination image * blocks. */ int *mapX, *mapY; int ir, ib, ig, ia; Tk_PhotoGetImage(srcPhoto, &sib); Tk_PhotoGetImage(destPhoto, &dib); mapX = (int *)Blt_AssertMalloc(sizeof(int) * dib.width); mapY = (int *)Blt_AssertMalloc(sizeof(int) * dib.height); FillScaleTables(sib.width, sib.height, srcX, srcY, sw, sh, dib.width, dib.height, mapX, mapY); destPtr = Blt_CreatePicture(dib.width, dib.height); ir = sib.offset[0]; ig = sib.offset[1]; ib = sib.offset[2]; ia = sib.offset[3]; if (sib.pixelSize == 4) { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < dib.height; y++) { Blt_Pixel *dp; unsigned char *srcRowPtr; dp = destRowPtr; srcRowPtr = sib.pixelPtr + (mapY[y] * sib.pitch); for (x = 0; x < dib.width; x++) { unsigned char *sp; sp = srcRowPtr + (mapX[x] * sib.pixelSize); dp->Red = sp[ir]; dp->Green = sp[ig]; dp->Blue = sp[ib]; dp->Alpha = sp[ia]; dp++; } destRowPtr += destPtr->pixelsPerRow; } } else if (sib.pixelSize == 3) { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < dib.height; y++) { Blt_Pixel *dp; unsigned char *srcRowPtr; dp = destRowPtr; srcRowPtr = sib.pixelPtr + (mapY[y] * sib.pitch); for (x = 0; x < dib.width; x++) { unsigned char *sp; sp = srcRowPtr + (mapX[x] * sib.pixelSize); dp->Red = sp[ir]; dp->Green = sp[ig]; dp->Blue = sp[ib]; dp->Alpha = ALPHA_OPAQUE; dp++; } destRowPtr += destPtr->pixelsPerRow; } } else { Blt_Pixel *destRowPtr; int x, y; destRowPtr = destPtr->bits; for (y = 0; y < dib.height; y++) { Blt_Pixel *dp; unsigned char *srcRowPtr; dp = destRowPtr; srcRowPtr = sib.pixelPtr + (mapY[y] * sib.pitch); for (x = 0; x < dib.width; x++) { unsigned char *sp; sp = srcRowPtr + (mapX[x] * sib.pixelSize); dp->Red = dp->Green = dp->Blue = sp[ir]; dp->Alpha = ALPHA_OPAQUE; dp++; } destRowPtr += destPtr->pixelsPerRow; } } Blt_Free(mapX); Blt_Free(mapY); Blt_PictureToPhoto(destPtr, destPhoto); Blt_FreePicture(destPtr); } #endif /* *--------------------------------------------------------------------------- * * Blt_ScalePicture -- * * Scales the region of the source picture to the size requested. This * routine performs raw scaling of the image and unlike Blt_ResamplePhoto * does not do any filtering. * * src picture * +===================+ * | | dest picture * | | +==============+ * | x,y | | | * | *-------* | | | * | | area | | | | * | | | | | | * | | | height | | | * | | | | | | * | *-------* | | | * | width | | | * | | +==============+ * | | * +===================+ * * x ratio = dest width / area width * y ratio = dest height / area height * * * Results: * Returns the new resized picture. The original picture is left intact. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_ScalePicture( Pict *srcPtr, /* Source picture to be scaled. */ int sx, int sy, /* Area of source picture to scaled. */ int sw, int sh, int reqWidth, int reqHeight) /* Requested dimensions of the scaled * picture. */ { Pict *destPtr; Blt_Pixel *destRowPtr; int *mapX, *mapY; int y; mapX = (int *)Blt_AssertMalloc(sizeof(int) * reqWidth); mapY = (int *)Blt_AssertMalloc(sizeof(int) * reqHeight); FillScaleTables(srcPtr->width, srcPtr->height, sx, sy, sw, sh, reqWidth, reqHeight, mapX, mapY); destPtr = Blt_CreatePicture(reqWidth, reqHeight); destRowPtr = destPtr->bits; for (y = 0; y < reqHeight; y++) { Blt_Pixel *dp; Blt_Pixel *srcRowPtr; int x; dp = destRowPtr; srcRowPtr = srcPtr->bits + (srcPtr->pixelsPerRow * mapY[y]); for (x = 0; x < reqWidth; x++) { Blt_Pixel *sp; sp = srcRowPtr + mapX[x]; dp->u32 = sp->u32; /* Copy the pixel. */ dp++; } destRowPtr += destPtr->pixelsPerRow; } Blt_Free(mapX), Blt_Free(mapY); destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_ScalePictureArea -- * * Scales the region of the source picture to the size of the destination * image. This routine performs raw scaling of the image and unlike * Blt_ResamplePhoto does not perform any antialiasing. * * Results: * Returns the new resized picture. The original picture is left intact. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_ScalePictureArea( Pict *srcPtr, /* Source picture to be scaled. */ int ax, int ay, /* Origin of area in source picture. */ int aw, int ah, /* Dimension of area to be scaled. */ int dw, int dh) /* Dimensions of the destination scaled image. */ { Pict *destPtr; Blt_Pixel *srcRowPtr, *destRowPtr; double xScale, yScale; int *mapX, *mapY; int x, y; xScale = (double)srcPtr->width / (double)dw; yScale = (double)srcPtr->height / (double)dh; mapX = Blt_AssertMalloc(sizeof(int) * aw); mapY = Blt_AssertMalloc(sizeof(int) * ah); /* Precompute scaling factors for each row and column. */ for (x = 0; x < aw; x++) { int sx; sx = (int)(xScale * (double)(x + ax)); if (sx >= srcPtr->width) { sx = srcPtr->width - 1; } mapX[x] = sx; } for (y = 0; y < ah; y++) { int sy; sy = (int)(yScale * (double)(y + ay)); if (sy > srcPtr->height) { sy = srcPtr->height - 1; } mapY[y] = sy; } destPtr = Blt_CreatePicture(aw, ah); destRowPtr = destPtr->bits; for (y = 0; y < ah; y++) { Blt_Pixel *dp; dp = destRowPtr; srcRowPtr = srcPtr->bits + (srcPtr->pixelsPerRow * mapY[y]); for (x = 0; x < aw; x++) { Blt_Pixel *sp; sp = srcRowPtr + mapX[x]; dp->u32 = sp->u32; /* Copy the pixel. */ dp++; } destRowPtr += destPtr->pixelsPerRow; } Blt_Free(mapX), Blt_Free(mapY); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_SnapPhoto -- * * Takes a snapshot of an X drawable (pixmap or window) and writes it to * an existing Tk photo image. * * Results: * A standard TCL result. * * Side Effects: * The named Tk photo is updated with the snapshot. * *--------------------------------------------------------------------------- */ int Blt_SnapPhoto( Tcl_Interp *interp, /* Interpreter to report errors back * to */ Tk_Window tkwin, Drawable drawable, /* Window or pixmap to be snapped */ int x, int y, /* Offset of image from drawable * origin. */ int width, int height, /* Dimension of the drawable */ int dw, int dh, /* Desired size of the destination Tk * photo. */ const char *photoName, /* Name of a current Tk photo image. */ float gamma) { Tk_PhotoHandle photo; /* The photo image to write into. */ Blt_Picture pict; photo = Tk_FindPhoto(interp, photoName); if (photo == NULL) { Tcl_AppendResult(interp, "can't find photo \"", photoName, "\"", (char *)NULL); return TCL_ERROR; } pict = Blt_DrawableToPicture(tkwin, drawable, x, y, width, height, gamma); if (pict == NULL) { Tcl_AppendResult(interp, "can't grab window or pixmap (possibly obscured?)", (char *)NULL); return TCL_ERROR; /* Can't grab window image */ } if ((dw != width) || (dh != height)) { Blt_Picture dest; /* * The requested size for the destination image is different than that * of the source snapshot. Resample the image as necessary. We'll * use a cheap box filter. I'm assuming that the destination image * will typically be smaller than the original. */ dest = Blt_CreatePicture(dw, dh); Blt_ResamplePicture(dest, pict, bltBoxFilter, bltBoxFilter); Blt_FreePicture(pict); pict = dest; } Blt_PictureToPhoto(pict, photo); Blt_FreePicture(pict); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_SnapPhoto -- * * Takes a snapshot of an X drawable (pixmap or window) and writes it to * an existing Tk photo image. * * Results: * A standard TCL result. * * Side Effects: * The named Tk photo is updated with the snapshot. * *--------------------------------------------------------------------------- */ int Blt_SnapPicture( Tcl_Interp *interp, /* Interpreter to return results. */ Tk_Window tkwin, Drawable drawable, /* Window or pixmap to be snapped */ int x, int y, /* Offset of image in drawable * origin. */ int width, int height, /* Dimension of the drawable. */ int dw, int dh, /* Desired size of the destination * picture. */ const char *imageName, /* Name of a current picture image. */ float gamma) { Blt_Picture pict; pict = Blt_DrawableToPicture(tkwin, drawable, x, y, width, height, gamma); if (pict == NULL) { Tcl_AppendResult(interp, "can't grab window or pixmap (possibly obscured?)", (char *)NULL); return TCL_ERROR; /* Can't grab window image */ } if ((dw != width) || (dh != height)) { Blt_Picture dest; /* * The requested size for the destination image is different than that * of the source snapshot. Resample the image as necessary. We'll * use a cheap box filter. I'm assuming that the destination image * will typically be smaller than the original. */ dest = Blt_CreatePicture(dw, dh); Blt_ResamplePicture(dest, pict, bltBoxFilter, bltBoxFilter); Blt_FreePicture(pict); pict = dest; } if (Blt_ResetPicture(interp, imageName, pict) == TCL_OK) { return TCL_OK; } Blt_FreePicture(pict); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ShearY -- * * Shears a row horizontally. Antialiasing limited to filtering two * adjacent pixels. So the shear angle must be between +-45 degrees. * * Results: * None. * * Side Effects: * The sheared image is drawn into the destination picture. * *--------------------------------------------------------------------------- */ static void ShearY( Pict *destPtr, Pict *srcPtr, int y, /* Designates the row to be sheared */ int offset, /* Difference between of. Note: don't * assume that offset is always * positive. */ double frac, Blt_Pixel *bg) { Blt_Pixel *sp, *dp; Blt_Pixel *srcRowPtr, *destRowPtr; int x, dx; Blt_Pixel left; unsigned char alpha; int t; assert(frac >= 0.0 && frac <= 1.0); destRowPtr = destPtr->bits + (y * destPtr->pixelsPerRow); srcRowPtr = srcPtr->bits + (y * srcPtr->pixelsPerRow); for (dp = destRowPtr, x = 0; x < offset; x++, dp++) { dp->u32 = bg->u32; } dp = destRowPtr + offset; sp = srcRowPtr; dx = offset; alpha = (unsigned char)(frac * 255.0 + 0.5); left.Red = imul8x8(alpha, bg->Red, t); left.Green = imul8x8(alpha, bg->Green, t); left.Blue = imul8x8(alpha, bg->Blue, t); left.Alpha = imul8x8(alpha, bg->Alpha, t); for (x = 0; x < srcPtr->width; x++, dx++) { /* Loop through row pixels */ Blt_Pixel right; int t; right.Red = imul8x8(alpha, sp->Red, t); right.Green = imul8x8(alpha, sp->Green, t); right.Blue = imul8x8(alpha, sp->Blue, t); right.Alpha = imul8x8(alpha, sp->Alpha, t); if ((dx >= 0) && (dx < destPtr->width)) { int r, b, g, a; r = sp->Red - (right.Red - left.Red); g = sp->Green - (right.Green - left.Green); b = sp->Blue - (right.Blue - left.Blue); a = sp->Alpha - (right.Alpha - left.Alpha); if (sp->Alpha == 0) { a = 0; } dp->Red = UCLAMP(r); dp->Green = UCLAMP(g); dp->Blue = UCLAMP(b); dp->Alpha = UCLAMP(a); } left.u32 = right.u32; sp++, dp++; } x = srcPtr->width + offset; dp = destPtr->bits + (y * destPtr->pixelsPerRow) + x; if (x < destPtr->width) { dp->u32 = left.u32; dp++; } for (x++; x < destPtr->width; x++, dp++) { dp->u32 = bg->u32; } } /* *--------------------------------------------------------------------------- * * ShearX -- * * Shears a column. Antialiasing is limited to filtering two adjacent * pixels. So the shear angle must be between +-45 degrees. * * Results: * None. * * Side Effects: * The sheared image is drawn into the destination picture. * * -------------------------------------------------------------------------- */ static void ShearX( Pict *destPtr, Pict *srcPtr, int x, /* Column in source image to be * sheared. */ int offset, /* Offset of */ double frac, /* Fraction of subpixel. */ Blt_Pixel *bg) { Blt_Pixel *sp, *dp; int y, dy; unsigned char alpha; Blt_Pixel left; /* Old left values of shear. */ int t; assert(frac >= 0.0 && frac <= 1.0); dp = destPtr->bits + x; for (y = 0; y < offset; y++) { dp->u32 = bg->u32; dp += destPtr->pixelsPerRow; } dp = destPtr->bits + (offset * destPtr->pixelsPerRow) + x; sp = srcPtr->bits + x; alpha = (unsigned char)(frac * 255.0 + 0.5); left.Red = imul8x8(alpha, bg->Red, t); left.Green = imul8x8(alpha, bg->Green, t); left.Blue = imul8x8(alpha, bg->Blue, t); left.Alpha = imul8x8(alpha, bg->Alpha, t); for (dy = offset, y = 0; y < srcPtr->height; y++, dy++) { Blt_Pixel right; int t; right.Red = imul8x8(alpha, sp->Red, t); right.Green = imul8x8(alpha, sp->Green, t); right.Blue = imul8x8(alpha, sp->Blue, t); right.Alpha = imul8x8(alpha, sp->Alpha, t); if ((dy >= 0) && (dy < destPtr->height)) { int r, g, b, a; r = sp->Red - (right.Red - left.Red); g = sp->Green - (right.Green - left.Green); b = sp->Blue - (right.Blue - left.Blue); a = sp->Alpha - (right.Alpha - left.Alpha); if (sp->Alpha == 0) { a = 0; } dp->Red = UCLAMP(r); dp->Green = UCLAMP(g); dp->Blue = UCLAMP(b); dp->Alpha = UCLAMP(a); } left.u32 = right.u32; sp += srcPtr->pixelsPerRow; dp += destPtr->pixelsPerRow; } y = srcPtr->height + offset; dp = destPtr->bits + (y * destPtr->pixelsPerRow) + x; if (y < destPtr->height) { dp->u32 = left.u32; dp += destPtr->pixelsPerRow; } for (y++; y < destPtr->height; y++) { dp->u32 = bg->u32; dp += destPtr->pixelsPerRow; } } /* *--------------------------------------------------------------------------- * * Rotate45 -- * * Rotates an image by a given angle. The angle must be in the range * -45.0 to 45.0 inclusive. Anti-aliasing filtering is performed on two * adjacent pixels, so the angle can't be so great as to force a sheared * pixel to occupy 3 destination pixels. Performs a three shear rotation * described below. * * Reference: Alan W. Paeth, "A Fast Algorithm for General Raster * Rotation", Graphics Gems, pp 179-195. * * * Results: * Returns a newly allocated rotated image. * * -------------------------------------------------------------------------- */ static Blt_Picture Rotate45(Pict *srcPtr, float angle, Blt_Pixel *bg) { Pict *shear1Ptr, *shear2Ptr, *destPtr; double skewf; double sinTheta, cosTheta, tanTheta; int skewi; int shearWidth, shearHeight; int x, y; sinTheta = sin(angle); cosTheta = cos(angle); tanTheta = tan(angle * 0.5); shearWidth = srcPtr->width + (int)(srcPtr->height * FABS(tanTheta)); shearHeight = srcPtr->height; /* 1st shear */ shear1Ptr = Blt_CreatePicture(shearWidth, shearHeight); if (tanTheta >= 0.0) { /* Positive angle */ for (y = 0; y < shearHeight; y++) { skewf = (y + 0.5) * tanTheta; skewi = (int)floor(skewf); ShearY(shear1Ptr, srcPtr, y, skewi, skewf - skewi, bg); } } else { /* Negative angle */ for (y = 0; y < shearHeight; y++) { skewf = ((y - srcPtr->height) + 0.5) * tanTheta; skewi = (int)floor(skewf); ShearY(shear1Ptr, srcPtr, y, skewi, skewf - skewi, bg); } } shearHeight = (int)(srcPtr->width * FABS(sinTheta) + srcPtr->height * cosTheta) + 1; shear2Ptr = Blt_CreatePicture(shearWidth, shearHeight); /* 2nd shear */ if (sinTheta > 0.0) { /* Positive angle */ skewf = (srcPtr->width - 1) * sinTheta; } else { /* Negative angle */ skewf = (srcPtr->width - shearWidth) * -sinTheta; } for (x = 0; x < shearWidth; x++) { skewi = (int)floor(skewf); ShearX(shear2Ptr, shear1Ptr, x, skewi, skewf - skewi, bg); skewf -= sinTheta; } Blt_FreePicture(shear1Ptr); /* 3rd shear */ shearWidth = (int)(srcPtr->height * FABS(sinTheta) + srcPtr->width * cosTheta) + 1; destPtr = Blt_CreatePicture(shearWidth, shearHeight); if (sinTheta >= 0.0) { /* Positive angle */ skewf = (srcPtr->width - 1) * sinTheta * -tanTheta; } else { /* Negative angle */ skewf = tanTheta * ((srcPtr->width - 1) * -sinTheta - (shearHeight-1)); } for (y = 0; y < shearHeight; y++) { skewi = (int)floor(skewf); ShearY(destPtr, shear2Ptr, y, skewi, skewf - skewi, bg); skewf += tanTheta; } Blt_FreePicture(shear2Ptr); destPtr->flags |= BLT_PIC_BLEND; return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_ClonePicture -- * * Creates a copy of the given picture. * * Results: * Returns the new copy. * * -------------------------------------------------------------------------- */ Blt_Picture Blt_ClonePicture(Pict *srcPtr) { Pict *destPtr; destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_CopyPictureBits(destPtr, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); destPtr->delay = srcPtr->delay; return destPtr; } /* *--------------------------------------------------------------------------- * * Rotate90 -- * * Rotates the given picture by 90 degrees. This is part of the special * case right-angle rotations that do not create subpixel aliasing. * * Results: * Returns a newly allocated, rotated picture. * * -------------------------------------------------------------------------- */ static Blt_Picture Rotate90(Pict *srcPtr) { Pict *destPtr; Blt_Pixel *srcRowPtr; int offset; int x, y; destPtr = Blt_CreatePicture(srcPtr->height, srcPtr->width); offset = (destPtr->height - 1) * destPtr->pixelsPerRow; srcRowPtr = srcPtr->bits; for (x = 0; x < destPtr->width; x++) { Blt_Pixel *dp, *sp; sp = srcRowPtr; dp = destPtr->bits + offset + x; for (y = 0; y < destPtr->height; y++) { *dp = *sp++; dp -= destPtr->pixelsPerRow; } srcRowPtr += srcPtr->pixelsPerRow; } destPtr->flags = srcPtr->flags; return destPtr; } /* *--------------------------------------------------------------------------- * * Rotate180 -- * * Rotates the given picture by 180 degrees. This is one of the special * case orthogonal rotations that do not create subpixel aliasing. * * Results: * Returns a newly allocated, rotated picture. * * -------------------------------------------------------------------------- */ static Blt_Picture Rotate180(Pict *srcPtr) { Pict *destPtr; Blt_Pixel *srcRowPtr; int offset; int x, y; destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); offset = (destPtr->height - 1) * destPtr->pixelsPerRow; srcRowPtr = srcPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *sp; sp = srcRowPtr; dp = destPtr->bits + offset + destPtr->width - 1; for (x = 0; x < destPtr->width; x++) { *dp-- = *sp++; } offset -= destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } destPtr->flags = srcPtr->flags; return destPtr; } /* *--------------------------------------------------------------------------- * * Rotate270 -- * * Rotates the given picture by 270 degrees. This is part of the special * case right-angle rotations that do not create subpixel aliasing. * * Results: * Returns a newly allocated, rotated picture. * * -------------------------------------------------------------------------- */ static Blt_Picture Rotate270(Pict *srcPtr) { Pict *destPtr; Blt_Pixel *srcRowPtr; int x, y; destPtr = Blt_CreatePicture(srcPtr->height, srcPtr->width); srcRowPtr = srcPtr->bits; for (x = destPtr->width - 1; x >= 0; x--) { Blt_Pixel *sp, *dp; sp = srcRowPtr; dp = destPtr->bits + x; for (y = 0; y < destPtr->height; y++) { *dp = *sp++; dp += destPtr->pixelsPerRow; } srcRowPtr += srcPtr->pixelsPerRow; } destPtr->flags = srcPtr->flags; return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_RotatePicture -- * * Rotates a picture by a given # of degrees. * * Results: * Returns a newly allocated, rotated picture. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_RotatePicture(Pict *srcPtr, float angle) { Pict *destPtr, *tmpPtr; int quadrant; tmpPtr = srcPtr; /* Suppress compiler warning. */ /* Make the angle positive between 0 and 360 degrees. */ angle = FMOD(angle, 360.0); if (angle < 0.0) { angle += 360.0; } quadrant = ROTATE_0; if ((angle > 45.0) && (angle <= 135.0)) { quadrant = ROTATE_90; angle -= 90.0; } else if ((angle > 135.0) && (angle <= 225.0)) { quadrant = ROTATE_180; angle -= 180.0; } else if ((angle > 225.0) && (angle <= 315.0)) { quadrant = ROTATE_270; angle -= 270.0; } else if (angle > 315.0) { angle -= 360.0; } /* * If necessary, create a temporary image that's rotated by a right-angle. * We'll then rotate this picture between -45 to 45 degrees to arrive at * its final angle. */ switch (quadrant) { case ROTATE_270: /* 270 degrees */ tmpPtr = Rotate270(srcPtr); break; case ROTATE_90: /* 90 degrees */ tmpPtr = Rotate90(srcPtr); break; case ROTATE_180: /* 180 degrees */ tmpPtr = Rotate180(srcPtr); break; case ROTATE_0: /* 0 degrees */ if (angle == 0.0) { tmpPtr = Blt_ClonePicture(srcPtr); /* Make a copy of the source. */ } break; } assert((angle >= -45.0) && (angle <= 45.0)); destPtr = tmpPtr; if (angle != 0.0) { Blt_Pixel bg; bg.u32 = 0x00000000; angle = (angle / 180.0) * M_PI; destPtr = Rotate45(tmpPtr, angle, &bg); if (tmpPtr != srcPtr) { Blt_FreePicture(tmpPtr); } } return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_FlipPicture -- * * Flips a picture vertically or horizonally. * *--------------------------------------------------------------------------- */ void Blt_FlipPicture(Pict *srcPtr, int vertically) { if (vertically) { Blt_Pixel *s1RowPtr, *s2RowPtr; int y; s1RowPtr = srcPtr->bits; s2RowPtr = srcPtr->bits + ((srcPtr->height - 1) * srcPtr->pixelsPerRow); for (y = 0; y < srcPtr->height / 2; y++) { Blt_Pixel *s1, *s2, *send; s1 = s1RowPtr, s2 = s2RowPtr; for (send = s1 + srcPtr->width; s1 < send; s1++, s2++) { Blt_Pixel tmp; tmp.u32 = s1->u32; s1->u32 = s2->u32; s2->u32 = tmp.u32; } s1RowPtr += srcPtr->pixelsPerRow; s2RowPtr -= srcPtr->pixelsPerRow; } } else { Blt_Pixel *s1ColumnPtr, *s2ColumnPtr; int x; s1ColumnPtr = srcPtr->bits; s2ColumnPtr = srcPtr->bits + (srcPtr->width - 1); for (x = 0; x < srcPtr->width / 2; x++) { Blt_Pixel *s1, *s2, *send; s1 = s1ColumnPtr, s2 = s2ColumnPtr; for (send = s1 + (srcPtr->height * srcPtr->pixelsPerRow); s1 < send; s1 += srcPtr->pixelsPerRow, s2 += srcPtr->pixelsPerRow) { Blt_Pixel tmp; tmp.u32 = s1->u32; s1->u32 = s2->u32; s2->u32 = tmp.u32; } s1ColumnPtr++; s2ColumnPtr--; } } srcPtr->flags |= BLT_PIC_DIRTY; } #define NC 256 enum ColorDirections { RED, GREEN, BLUE }; #define R0 (cubePtr->r0) #define R1 (cubePtr->r1) #define G0 (cubePtr->g0) #define G1 (cubePtr->g1) #define B0 (cubePtr->b0) #define B1 (cubePtr->b1) typedef struct { int r0, r1; /* min, max values: min exclusive max * inclusive */ int g0, g1; int b0, b1; int vol; } Cube; /* *--------------------------------------------------------------------------- * * Histogram is in elements 1..HISTSIZE along each axis, element 0 is for base * or marginal value NB: these must start out 0! * *--------------------------------------------------------------------------- */ typedef struct { long int wt[33][33][33]; /* # pixels in voxel */ long int mR[33][33][33]; /* Sum over voxel of red pixel values */ long int mG[33][33][33]; /* Sum over voxel of green pixel * values */ long int mB[33][33][33]; /* Sum over voxel of blue pixel * values */ float gm2[33][33][33]; /* Variance */ } PictStats; /* * Build 3-D color histogram of counts, R/G/B, c^2 */ static void Hist3d(PictStats *s, Pict *srcPtr) { #define MAX_INTENSITIES 256 Blt_Pixel *srcRowPtr; int y; float tab[MAX_INTENSITIES]; { int i; /* Precompute table of squares. */ for (i = 0; i < MAX_INTENSITIES; i++) { tab[i] = (float)(i * i); } } srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int x; for (sp = srcRowPtr, x = 0; x < srcPtr->width; x++, sp++) { int r, g, b; /* * Reduce the number of bits (5) per color component. This will * keep the table size (2^15) reasonable without perceptually * affecting the final image. */ r = (sp->Red >> 3) + 1; g = (sp->Green >> 3) + 1; b = (sp->Blue >> 3) + 1; s->wt[r][g][b] += 1; s->mR[r][g][b] += sp->Red; s->mG[r][g][b] += sp->Green; s->mB[r][g][b] += sp->Blue; s->gm2[r][g][b] += tab[sp->Red] + tab[sp->Green] + tab[sp->Blue]; } srcRowPtr += srcPtr->pixelsPerRow; } } /* *--------------------------------------------------------------------------- * * At conclusion of the histogram step, we can interpret * wt[r][g][b] = sum over voxel of P(c) * mR[r][g][b] = sum over voxel of r*P(c) , similarly for mG, mB * m2[r][g][b] = sum over voxel of c^2*P(c) * * Actually each of these should be divided by 'size' to give the usual * interpretation of P() as ranging from 0 to 1, but we needn't do that here. * *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * We now convert histogram into moments so that we can rapidly calculate * the sums of the above quantities over any desired box. * *--------------------------------------------------------------------------- */ /* Compute cumulative moments. */ static void M3d(PictStats *s) { unsigned char i, r, g, b, r0; long int area[33], rArea[33], gArea[33], bArea[33]; float area2[33]; for (r = 1, r0 = 0; r <= 32; r++, r0++) { for (i = 0; i <= 32; ++i) { area2[i] = 0.0f; area[i] = rArea[i] = gArea[i] = bArea[i] = 0; } for (g = 1; g <= 32; g++) { long int line, rLine, gLine, bLine; float line2; line2 = 0.0f; line = rLine = gLine = bLine = 0; for (b = 1; b <= 32; b++) { /* ind1 = RGBIndex(r, g, b); */ line += s->wt[r][g][b]; rLine += s->mR[r][g][b]; gLine += s->mG[r][g][b]; bLine += s->mB[r][g][b]; line2 += s->gm2[r][g][b]; area[b] += line; rArea[b] += rLine; gArea[b] += gLine; bArea[b] += bLine; area2[b] += line2; /* ind2 = ind1 - 1089; [r0][g][b] */ s->wt[r][g][b] = s->wt[r0][g][b] + area[b]; s->mR[r][g][b] = s->mR[r0][g][b] + rArea[b]; s->mG[r][g][b] = s->mG[r0][g][b] + gArea[b]; s->mB[r][g][b] = s->mB[r0][g][b] + bArea[b]; s->gm2[r][g][b] = s->gm2[r0][g][b] + area2[b]; } } } } /* *--------------------------------------------------------------------------- * * Vol -- * * Compute sum over a box of any given statistic * *--------------------------------------------------------------------------- */ static INLINE long int Vol(Cube *cubePtr, long int m[33][33][33]) { return (m[R1][G1][B1] - m[R1][G1][B0] - m[R1][G0][B1] + m[R1][G0][B0] - m[R0][G1][B1] + m[R0][G1][B0] + m[R0][G0][B1] - m[R0][G0][B0]); } /* *--------------------------------------------------------------------------- * * Bottom -- * * The next two routines allow a slightly more efficient calculation of * Vol() for a proposed subbox of a given box. The sum of Top() and * Bottom() is the Vol() of a subbox split in the given direction and * with the specified new upper bound. * *--------------------------------------------------------------------------- */ /* Compute part of Vol(cubePtr, mmt) that doesn't depend on r1, g1, or b1 */ /* (depending on dir) */ static long int Bottom( Cube *cubePtr, enum ColorDirections dir, long int m[33][33][33]) /* Moment */ { switch (dir) { case RED: return -m[R0][G1][B1] + m[R0][G1][B0] + m[R0][G0][B1] - m[R0][G0][B0]; case GREEN: return -m[R1][G0][B1] + m[R1][G0][B0] + m[R0][G0][B1] - m[R0][G0][B0]; case BLUE: return -m[R1][G1][B0] + m[R1][G0][B0] + m[R0][G1][B0] - m[R0][G0][B0]; } return 0; } /* *--------------------------------------------------------------------------- * * Top -- * * Compute remainder of Vol(cubePtr, mmt), substituting pos for r1, g1, * or b1 (depending on dir). * *--------------------------------------------------------------------------- */ static long int Top(Cube *cubePtr, enum ColorDirections dir, int pos, long int m[33][33][33]) { switch (dir) { case RED: return (m[pos][G1][B1] - m[pos][G1][B0] - m[pos][G0][B1] + m[pos][G0][B0]); case GREEN: return (m[R1][pos][B1] - m[R1][pos][B0] - m[R0][pos][B1] + m[R0][pos][B0]); case BLUE: return (m[R1][G1][pos] - m[R1][G0][pos] - m[R0][G1][pos] + m[R0][G0][pos]); } return 0; } /* *--------------------------------------------------------------------------- * * Var -- * * Compute the weighted variance of a box NB: as with the raw statistics, * this is really the (variance * size) * *--------------------------------------------------------------------------- */ static float Var(Cube *cubePtr, PictStats *s) { long int dR, dG, dB; float xx; dR = Vol(cubePtr, s->mR); dG = Vol(cubePtr, s->mG); dB = Vol(cubePtr, s->mB); xx = (s->gm2[R1][G1][B1] - s->gm2[R1][G1][B0] - s->gm2[R1][G0][B1] + s->gm2[R1][G0][B0] - s->gm2[R0][G1][B1] + s->gm2[R0][G1][B0] + s->gm2[R0][G0][B1] - s->gm2[R0][G0][B0]); return (xx - (float)(dR * dR + dG * dG + dB * dB) / (float)Vol(cubePtr, s->wt)); } /* *--------------------------------------------------------------------------- * * Maximize -- * * We want to minimize the sum of the variances of two subboxes. The * sum(c^2) terms can be ignored since their sum over both subboxes is * the same (the sum for the whole box) no matter where we split. The * remaining terms have a minus sign in the variance formula, so we drop * the minus sign and MAXIMIZE the sum of the two terms. * *--------------------------------------------------------------------------- */ static float Maximize( Cube *cubePtr, enum ColorDirections dir, int first, int last, int *cut, long rWhole, long gWhole, long bWhole, long wWhole, PictStats *s) { long int rHalf, gHalf, bHalf, wHalf; long int rBase, gBase, bBase, wBase; int i; float temp, max; rBase = Bottom(cubePtr, dir, s->mR); gBase = Bottom(cubePtr, dir, s->mG); bBase = Bottom(cubePtr, dir, s->mB); wBase = Bottom(cubePtr, dir, s->wt); max = 0.0; *cut = -1; for (i = first; i < last; i++) { rHalf = rBase + Top(cubePtr, dir, i, s->mR); gHalf = gBase + Top(cubePtr, dir, i, s->mG); bHalf = bBase + Top(cubePtr, dir, i, s->mB); wHalf = wBase + Top(cubePtr, dir, i, s->wt); /* Now half_x is sum over lower half of box, if split at i */ if (wHalf == 0) { /* subbox could be empty of pixels! */ continue; /* never split into an empty box */ } else { temp = ((float)rHalf * rHalf + (float)gHalf * gHalf + (float)bHalf * bHalf) / wHalf; } rHalf = rWhole - rHalf; gHalf = gWhole - gHalf; bHalf = bWhole - bHalf; wHalf = wWhole - wHalf; if (wHalf == 0) { /* Subbox could be empty of pixels! */ continue; /* never split into an empty box */ } else { temp += ((float)rHalf * rHalf + (float)gHalf * gHalf + (float)bHalf * bHalf) / wHalf; } if (temp > max) { max = temp; *cut = i; } } return max; } /* *--------------------------------------------------------------------------- * * Cut -- * *--------------------------------------------------------------------------- */ static int Cut(Cube *set1, Cube *set2, PictStats *s) { enum ColorDirections dir; int rCut, gCut, bCut; float rMax, gMax, bMax; long int rWhole, gWhole, bWhole, wWhole; rWhole = Vol(set1, s->mR); gWhole = Vol(set1, s->mG); bWhole = Vol(set1, s->mB); wWhole = Vol(set1, s->wt); rMax = Maximize(set1, RED, set1->r0 + 1, set1->r1, &rCut, rWhole, gWhole, bWhole, wWhole, s); gMax = Maximize(set1, GREEN, set1->g0 + 1, set1->g1, &gCut, rWhole, gWhole, bWhole, wWhole, s); bMax = Maximize(set1, BLUE, set1->b0 + 1, set1->b1, &bCut, rWhole, gWhole, bWhole, wWhole, s); if ((rMax >= gMax) && (rMax >= bMax)) { dir = RED; if (rCut < 0) { return 0; /* can't split the box */ } } else { dir = ((gMax >= rMax) && (gMax >= bMax)) ? GREEN : BLUE; } set2->r1 = set1->r1; set2->g1 = set1->g1; set2->b1 = set1->b1; switch (dir) { case RED: set2->r0 = set1->r1 = rCut; set2->g0 = set1->g0; set2->b0 = set1->b0; break; case GREEN: set2->g0 = set1->g1 = gCut; set2->r0 = set1->r0; set2->b0 = set1->b0; break; case BLUE: set2->b0 = set1->b1 = bCut; set2->r0 = set1->r0; set2->g0 = set1->g0; break; } set1->vol = (set1->r1 - set1->r0) * (set1->g1 - set1->g0) * (set1->b1 - set1->b0); set2->vol = (set2->r1 - set2->r0) * (set2->g1 - set2->g0) * (set2->b1 - set2->b0); return 1; } /* *--------------------------------------------------------------------------- * * SplitCS -- * *--------------------------------------------------------------------------- */ static int SplitCS(PictStats *s, Cube *cubes, int nReqColors) { float *vv, temp; int i; int next, k; int nc; vv = Blt_AssertMalloc(sizeof(float) * nReqColors); nc = nReqColors; cubes[0].r0 = cubes[0].g0 = cubes[0].b0 = 0; cubes[0].r1 = cubes[0].g1 = cubes[0].b1 = 32; next = 0; for (i = 1; i < nReqColors; i++) { if (Cut(cubes + next, cubes + i, s)) { /* Volume test ensures we won't try to cut one-cell box */ vv[next] = (cubes[next].vol > 1) ? Var(cubes + next, s) : 0.0f; vv[i] = (cubes[i].vol > 1) ? Var(cubes + i, s) : 0.0f; } else { vv[next] = 0.0f; /* don't try to split this box again */ i--; /* didn't create box i */ } next = 0; temp = vv[0]; for (k = 1; k <= i; k++) { if (vv[k] > temp) { temp = vv[k]; next = k; } } if (temp <= 0.0) { nc = i + 1; fprintf(stderr, "Only got %d boxes\n", nc); break; } } Blt_Free(vv); return nc; } /* *--------------------------------------------------------------------------- * * Mark -- * *--------------------------------------------------------------------------- */ static void Mark(Cube *cubePtr, int label, Blt_ColorLookupTable tag) { int r, g, b; for (r = R0 + 1; r <= R1; r++) { for (g = G0 + 1; g <= G1; g++) { for (b = B0 + 1; b <= B1; b++) { tag[r][g][b] = label; } } } } static Blt_ColorLookupTable MakeCLuT(PictStats *s, Cube *cubes, int nColors) { Blt_ColorLookupTable clut; Cube *cp, *cend; clut = Blt_AssertCalloc(sizeof(unsigned int), 33 * 33 * 33); for (cp = cubes, cend = cp + nColors; cp < cend; cp++) { unsigned int r, g, b; long int weight; Blt_Pixel pixel; weight = Vol(cp, s->wt); if (weight) { r = (unsigned int)((Vol(cp, s->mR) / (float)weight) * (NC + 1)); g = (unsigned int)((Vol(cp, s->mG) / (float)weight) * (NC + 1)); b = (unsigned int)((Vol(cp, s->mB) / (float)weight) * (NC + 1)); } else { #ifdef notdef fprintf(stderr, "bogus box %d\n", cp - cubes); #endif r = g = b = 0; } pixel.Red = r / 257; pixel.Green = g / 257; pixel.Blue = b / 257; pixel.Alpha = ALPHA_OPAQUE; Mark(cp, pixel.u32, clut); } return clut; } void Blt_MapColors(Pict *destPtr, Pict *srcPtr, Blt_ColorLookupTable clut) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; /* Apply the color lookup table against the original image */ srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp, *sp, *send; sp = srcRowPtr, dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { int r, g, b, a; r = (sp->Red >> 3) + 1; g = (sp->Green >> 3) + 1; b = (sp->Blue >> 3) + 1; a = sp->Alpha; dp->u32 = clut[r][g][b]; dp->Alpha = a; dp++; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } /* *--------------------------------------------------------------------------- * * Blt_QuantizePicture -- * * C Implementation of Wu's Color Quantizer (v. 2) (see Graphics Gems * vol. II, pp. 126-133) * * Author: Xiaolin Wu * Dept. of Computer Science Univ. of Western * Ontario London, Ontario * N6A 5B7 * wu@csd.uwo.ca * * Greedy orthogonal bipartition of RGB space for variance * minimization aided by inclusion-exclusion tricks. For speed * no nearest neighbor search is done. Slightly better * performance can be expected by more sophisticated but more * expensive versions. * * The author thanks Tom Lane at Tom_Lane@G.GP.CS.CMU.EDU for * much of additional documentation and a cure to a previous bug. * * Free to distribute, comments and suggestions are appreciated. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_QuantizePicture(Pict *srcPtr, int nReqColors) { Cube *cubes; PictStats *statsPtr; int nc; Blt_ColorLookupTable clut; Pict *destPtr; /* * Allocated a structure to hold color statistics. */ statsPtr = Blt_AssertCalloc(1, sizeof(PictStats)); Hist3d(statsPtr, srcPtr); M3d(statsPtr); cubes = Blt_AssertMalloc(sizeof(Cube) * nReqColors); nc = SplitCS(statsPtr, cubes, nReqColors); assert(nc <= nReqColors); clut = MakeCLuT(statsPtr, cubes, nc); Blt_Free(statsPtr); Blt_Free(cubes); destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_MapColors(destPtr, srcPtr, clut); Blt_Free(clut); return destPtr; } /* *--------------------------------------------------------------------------- * * Blt_QuantizePicture -- * * C Implementation of Wu's Color Quantizer (v. 2) (see Graphics Gems * vol. II, pp. 126-133) * * Author: Xiaolin Wu * Dept. of Computer Science Univ. of Western * Ontario London, Ontario * N6A 5B7 * wu@csd.uwo.ca * * Greedy orthogonal bipartition of RGB space for variance * minimization aided by inclusion-exclusion tricks. For speed * no nearest neighbor search is done. Slightly better * performance can be expected by more sophisticated but more * expensive versions. * * The author thanks Tom Lane at Tom_Lane@G.GP.CS.CMU.EDU for * much of additional documentation and a cure to a previous bug. * * Free to distribute, comments and suggestions are appreciated. * *--------------------------------------------------------------------------- */ Blt_ColorLookupTable Blt_GetColorLookupTable(Blt_Chain chain, int nReqColors) { Cube *cubes; PictStats *statsPtr; int nc; Blt_ColorLookupTable clut; Blt_ChainLink link; /* * Allocated a structure to hold color statistics. */ statsPtr = Blt_AssertCalloc(1, sizeof(PictStats)); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pict *srcPtr; srcPtr = Blt_Chain_GetValue(link); Hist3d(statsPtr, srcPtr); } M3d(statsPtr); cubes = Blt_AssertMalloc(sizeof(Cube) * nReqColors); nc = SplitCS(statsPtr, cubes, nReqColors); assert(nc <= nReqColors); clut = MakeCLuT(statsPtr, cubes, nc); Blt_Free(statsPtr); Blt_Free(cubes); return clut; } /* *--------------------------------------------------------------------------- * * CopyPictureBits -- * * Creates a copy of the given picture. * * Results: * Returns the new copy. * * -------------------------------------------------------------------------- */ static void CopyPictureBits(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy) { int *srcRowPtr, *destRowPtr; int right, bottom; int dw, dh; int width, height; if (((dx + w) < 0) || ((dy + h) < 0)) { return; } if (dx < 0) { w += dx; dx = 0; } if (dy < 0) { h += dy; dy = 0; } if (destPtr->width < (dx + w)) { w = destPtr->width - dx; } if (destPtr->height < (dy + h)) { h = destPtr->height - dy; } if (srcPtr->width < w) { w = srcPtr->width; } if (srcPtr->height < h) { h = srcPtr->height; } dw = destPtr->width - dx; dh = destPtr->height - dy; width = MIN(dw, w); height = MIN(dh, h); bottom = height + y; right = width + x; srcRowPtr = (int *)(srcPtr->bits + ((srcPtr->pixelsPerRow * y) + x)); destRowPtr = (int *)(destPtr->bits + ((destPtr->pixelsPerRow * dy) + dx)); for (/*empty*/; y < bottom; y++) { int n; int *sp, *dp; sp = srcRowPtr, dp = destRowPtr; n = (width + 7) / 8; /* count > 0 assumed */ switch (width & 0x07) { case 0: do { *dp++ = *sp++; case 7: *dp++ = *sp++; case 6: *dp++ = *sp++; case 5: *dp++ = *sp++; case 4: *dp++ = *sp++; case 3: *dp++ = *sp++; case 2: *dp++ = *sp++; case 1: *dp++ = *sp++; } while (--n > 0); } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); } /* * Image dithering routines. * * Reference: * Victor Ostromoukhov http://www.iro.umontreal.ca/~ostrom/. * * Victor Ostromoukhov, "A Simple and Efficient Error-Diffusion * Algorithm" SIGGRAPH'01 * * University of Montreal, http://www.iro.umontreal.ca/~ostrom/ * */ typedef struct { short int r; /* Right */ short int dl; /* Down-left */ short int d; /* Down */ short int sum; /* Sum */ } VarCoefs; static VarCoefs coefTable[256] = { { 13, 0, 5, 18, }, /* 0 */ { 13, 0, 5, 18, }, /* 1 */ { 21, 0, 10, 31, }, /* 2 */ { 7, 0, 4, 11, }, /* 3 */ { 8, 0, 5, 13, }, /* 4 */ { 47, 3, 28, 78, }, /* 5 */ { 23, 3, 13, 39, }, /* 6 */ { 15, 3, 8, 26, }, /* 7 */ { 22, 6, 11, 39, }, /* 8 */ { 43, 15, 20, 78, }, /* 9 */ { 7, 3, 3, 13, }, /* 10 */ { 501, 224, 211, 936, }, /* 11 */ { 249, 116, 103, 468, }, /* 12 */ { 165, 80, 67, 312, }, /* 13 */ { 123, 62, 49, 234, }, /* 14 */ { 489, 256, 191, 936, }, /* 15 */ { 81, 44, 31, 156, }, /* 16 */ { 483, 272, 181, 936, }, /* 17 */ { 60, 35, 22, 117, }, /* 18 */ { 53, 32, 19, 104, }, /* 19 */ { 237, 148, 83, 468, }, /* 20 */ { 471, 304, 161, 936, }, /* 21 */ { 3, 2, 1, 6, }, /* 22 */ { 459, 304, 161, 924, }, /* 23 */ { 38, 25, 14, 77, }, /* 24 */ { 453, 296, 175, 924, }, /* 25 */ { 225, 146, 91, 462, }, /* 26 */ { 149, 96, 63, 308, }, /* 27 */ { 111, 71, 49, 231, }, /* 28 */ { 63, 40, 29, 132, }, /* 29 */ { 73, 46, 35, 154, }, /* 30 */ { 435, 272, 217, 924, }, /* 31 */ { 108, 67, 56, 231, }, /* 32 */ { 13, 8, 7, 28, }, /* 33 */ { 213, 130, 119, 462, }, /* 34 */ { 423, 256, 245, 924, }, /* 35 */ { 5, 3, 3, 11, }, /* 36 */ { 281, 173, 162, 616, }, /* 37 */ { 141, 89, 78, 308, }, /* 38 */ { 283, 183, 150, 616, }, /* 39 */ { 71, 47, 36, 154, }, /* 40 */ { 285, 193, 138, 616, }, /* 41 */ { 13, 9, 6, 28, }, /* 42 */ { 41, 29, 18, 88, }, /* 43 */ { 36, 26, 15, 77, }, /* 44 */ { 289, 213, 114, 616, }, /* 45 */ { 145, 109, 54, 308, }, /* 46 */ { 291, 223, 102, 616, }, /* 47 */ { 73, 57, 24, 154, }, /* 48 */ { 293, 233, 90, 616, }, /* 49 */ { 21, 17, 6, 44, }, /* 50 */ { 295, 243, 78, 616, }, /* 51 */ { 37, 31, 9, 77, }, /* 52 */ { 27, 23, 6, 56, }, /* 53 */ { 149, 129, 30, 308, }, /* 54 */ { 299, 263, 54, 616, }, /* 55 */ { 75, 67, 12, 154, }, /* 56 */ { 43, 39, 6, 88, }, /* 57 */ { 151, 139, 18, 308, }, /* 58 */ { 303, 283, 30, 616, }, /* 59 */ { 38, 36, 3, 77, }, /* 60 */ { 305, 293, 18, 616, }, /* 61 */ { 153, 149, 6, 308, }, /* 62 */ { 307, 303, 6, 616, }, /* 63 */ { 1, 1, 0, 2, }, /* 64 */ { 101, 105, 2, 208, }, /* 65 */ { 49, 53, 2, 104, }, /* 66 */ { 95, 107, 6, 208, }, /* 67 */ { 23, 27, 2, 52, }, /* 68 */ { 89, 109, 10, 208, }, /* 69 */ { 43, 55, 6, 104, }, /* 70 */ { 83, 111, 14, 208, }, /* 71 */ { 5, 7, 1, 13, }, /* 72 */ { 172, 181, 37, 390, }, /* 73 */ { 97, 76, 22, 195, }, /* 74 */ { 72, 41, 17, 130, }, /* 75 */ { 119, 47, 29, 195, }, /* 76 */ { 4, 1, 1, 6, }, /* 77 */ { 4, 1, 1, 6, }, /* 78 */ { 4, 1, 1, 6, }, /* 79 */ { 4, 1, 1, 6, }, /* 80 */ { 4, 1, 1, 6, }, /* 81 */ { 4, 1, 1, 6, }, /* 82 */ { 4, 1, 1, 6, }, /* 83 */ { 4, 1, 1, 6, }, /* 84 */ { 4, 1, 1, 6, }, /* 85 */ { 65, 18, 17, 100, }, /* 86 */ { 95, 29, 26, 150, }, /* 87 */ { 185, 62, 53, 300, }, /* 88 */ { 30, 11, 9, 50, }, /* 89 */ { 35, 14, 11, 60, }, /* 90 */ { 85, 37, 28, 150, }, /* 91 */ { 55, 26, 19, 100, }, /* 92 */ { 80, 41, 29, 150, }, /* 93 */ { 155, 86, 59, 300, }, /* 94 */ { 5, 3, 2, 10, }, /* 95 */ { 5, 3, 2, 10, }, /* 96 */ { 5, 3, 2, 10, }, /* 97 */ { 5, 3, 2, 10, }, /* 98 */ { 5, 3, 2, 10, }, /* 99 */ { 5, 3, 2, 10, }, /* 100 */ { 5, 3, 2, 10, }, /* 101 */ { 5, 3, 2, 10, }, /* 102 */ { 5, 3, 2, 10, }, /* 103 */ { 5, 3, 2, 10, }, /* 104 */ { 5, 3, 2, 10, }, /* 105 */ { 5, 3, 2, 10, }, /* 106 */ { 5, 3, 2, 10, }, /* 107 */ { 305, 176, 119, 600, }, /* 108 */ { 155, 86, 59, 300, }, /* 109 */ { 105, 56, 39, 200, }, /* 110 */ { 80, 41, 29, 150, }, /* 111 */ { 65, 32, 23, 120, }, /* 112 */ { 55, 26, 19, 100, }, /* 113 */ { 335, 152, 113, 600, }, /* 114 */ { 85, 37, 28, 150, }, /* 115 */ { 115, 48, 37, 200, }, /* 116 */ { 35, 14, 11, 60, }, /* 117 */ { 355, 136, 109, 600, }, /* 118 */ { 30, 11, 9, 50, }, /* 119 */ { 365, 128, 107, 600, }, /* 120 */ { 185, 62, 53, 300, }, /* 121 */ { 25, 8, 7, 40, }, /* 122 */ { 95, 29, 26, 150, }, /* 123 */ { 385, 112, 103, 600, }, /* 124 */ { 65, 18, 17, 100, }, /* 125 */ { 395, 104, 101, 600, }, /* 126 */ { 4, 1, 1, 6, }, /* 127 */ { 4, 1, 1, 6, }, /* 128 */ { 395, 104, 101, 600, }, /* 129 */ { 65, 18, 17, 100, }, /* 130 */ { 385, 112, 103, 600, }, /* 131 */ { 95, 29, 26, 150, }, /* 132 */ { 25, 8, 7, 40, }, /* 133 */ { 185, 62, 53, 300, }, /* 134 */ { 365, 128, 107, 600, }, /* 135 */ { 30, 11, 9, 50, }, /* 136 */ { 355, 136, 109, 600, }, /* 137 */ { 35, 14, 11, 60, }, /* 138 */ { 115, 48, 37, 200, }, /* 139 */ { 85, 37, 28, 150, }, /* 140 */ { 335, 152, 113, 600, }, /* 141 */ { 55, 26, 19, 100, }, /* 142 */ { 65, 32, 23, 120, }, /* 143 */ { 80, 41, 29, 150, }, /* 144 */ { 105, 56, 39, 200, }, /* 145 */ { 155, 86, 59, 300, }, /* 146 */ { 305, 176, 119, 600, }, /* 147 */ { 5, 3, 2, 10, }, /* 148 */ { 5, 3, 2, 10, }, /* 149 */ { 5, 3, 2, 10, }, /* 150 */ { 5, 3, 2, 10, }, /* 151 */ { 5, 3, 2, 10, }, /* 152 */ { 5, 3, 2, 10, }, /* 153 */ { 5, 3, 2, 10, }, /* 154 */ { 5, 3, 2, 10, }, /* 155 */ { 5, 3, 2, 10, }, /* 156 */ { 5, 3, 2, 10, }, /* 157 */ { 5, 3, 2, 10, }, /* 158 */ { 5, 3, 2, 10, }, /* 159 */ { 5, 3, 2, 10, }, /* 160 */ { 155, 86, 59, 300, }, /* 161 */ { 80, 41, 29, 150, }, /* 162 */ { 55, 26, 19, 100, }, /* 163 */ { 85, 37, 28, 150, }, /* 164 */ { 35, 14, 11, 60, }, /* 165 */ { 30, 11, 9, 50, }, /* 166 */ { 185, 62, 53, 300, }, /* 167 */ { 95, 29, 26, 150, }, /* 168 */ { 65, 18, 17, 100, }, /* 169 */ { 4, 1, 1, 6, }, /* 170 */ { 4, 1, 1, 6, }, /* 171 */ { 4, 1, 1, 6, }, /* 172 */ { 4, 1, 1, 6, }, /* 173 */ { 4, 1, 1, 6, }, /* 174 */ { 4, 1, 1, 6, }, /* 175 */ { 4, 1, 1, 6, }, /* 176 */ { 4, 1, 1, 6, }, /* 177 */ { 4, 1, 1, 6, }, /* 178 */ { 119, 47, 29, 195, }, /* 179 */ { 72, 41, 17, 130, }, /* 180 */ { 97, 76, 22, 195, }, /* 181 */ { 172, 181, 37, 390, }, /* 182 */ { 5, 7, 1, 13, }, /* 183 */ { 83, 111, 14, 208, }, /* 184 */ { 43, 55, 6, 104, }, /* 185 */ { 89, 109, 10, 208, }, /* 186 */ { 23, 27, 2, 52, }, /* 187 */ { 95, 107, 6, 208, }, /* 188 */ { 49, 53, 2, 104, }, /* 189 */ { 101, 105, 2, 208, }, /* 190 */ { 1, 1, 0, 2, }, /* 191 */ { 307, 303, 6, 616, }, /* 192 */ { 153, 149, 6, 308, }, /* 193 */ { 305, 293, 18, 616, }, /* 194 */ { 38, 36, 3, 77, }, /* 195 */ { 303, 283, 30, 616, }, /* 196 */ { 151, 139, 18, 308, }, /* 197 */ { 43, 39, 6, 88, }, /* 198 */ { 75, 67, 12, 154, }, /* 199 */ { 299, 263, 54, 616, }, /* 200 */ { 149, 129, 30, 308, }, /* 201 */ { 27, 23, 6, 56, }, /* 202 */ { 37, 31, 9, 77, }, /* 203 */ { 295, 243, 78, 616, }, /* 204 */ { 21, 17, 6, 44, }, /* 205 */ { 293, 233, 90, 616, }, /* 206 */ { 73, 57, 24, 154, }, /* 207 */ { 291, 223, 102, 616, }, /* 208 */ { 145, 109, 54, 308, }, /* 209 */ { 289, 213, 114, 616, }, /* 210 */ { 36, 26, 15, 77, }, /* 211 */ { 41, 29, 18, 88, }, /* 212 */ { 13, 9, 6, 28, }, /* 213 */ { 285, 193, 138, 616, }, /* 214 */ { 71, 47, 36, 154, }, /* 215 */ { 283, 183, 150, 616, }, /* 216 */ { 141, 89, 78, 308, }, /* 217 */ { 281, 173, 162, 616, }, /* 218 */ { 5, 3, 3, 11, }, /* 219 */ { 423, 256, 245, 924, }, /* 220 */ { 213, 130, 119, 462, }, /* 221 */ { 13, 8, 7, 28, }, /* 222 */ { 108, 67, 56, 231, }, /* 223 */ { 435, 272, 217, 924, }, /* 224 */ { 73, 46, 35, 154, }, /* 225 */ { 63, 40, 29, 132, }, /* 226 */ { 111, 71, 49, 231, }, /* 227 */ { 149, 96, 63, 308, }, /* 228 */ { 225, 146, 91, 462, }, /* 229 */ { 453, 296, 175, 924, }, /* 230 */ { 38, 25, 14, 77, }, /* 231 */ { 459, 304, 161, 924, }, /* 232 */ { 3, 2, 1, 6, }, /* 233 */ { 471, 304, 161, 936, }, /* 234 */ { 237, 148, 83, 468, }, /* 235 */ { 53, 32, 19, 104, }, /* 236 */ { 60, 35, 22, 117, }, /* 237 */ { 483, 272, 181, 936, }, /* 238 */ { 81, 44, 31, 156, }, /* 239 */ { 489, 256, 191, 936, }, /* 240 */ { 123, 62, 49, 234, }, /* 241 */ { 165, 80, 67, 312, }, /* 242 */ { 249, 116, 103, 468, }, /* 243 */ { 501, 224, 211, 936, }, /* 244 */ { 7, 3, 3, 13, }, /* 245 */ { 43, 15, 20, 78, }, /* 246 */ { 22, 6, 11, 39, }, /* 247 */ { 15, 3, 8, 26, }, /* 248 */ { 23, 3, 13, 39, }, /* 249 */ { 47, 3, 28, 78, }, /* 250 */ { 8, 0, 5, 13, }, /* 251 */ { 7, 0, 4, 11, }, /* 252 */ { 21, 0, 10, 31, }, /* 253 */ { 13, 0, 5, 18, }, /* 254 */ { 13, 0, 5, 18, }, /* 255 */ }; static void DistributeError( double (*cl0)[3], double (*cl1)[3], int x, double rDiff, double gDiff, double bDiff, int dir, Blt_Pixel *sp) { VarCoefs *coefsPtr; double sum, r, dl, d; coefsPtr = coefTable + sp->Red; sum = coefsPtr->sum; r = coefsPtr->r * rDiff / sum; dl = coefsPtr->dl * rDiff / sum; d = rDiff - (r + dl); cl0[x + dir][0] += r; cl1[x - dir][0] += dl; cl1[x][0] += d; coefsPtr = coefTable + sp->Green; sum = coefsPtr->sum; r = coefsPtr->r * gDiff / sum; dl = coefsPtr->dl * gDiff / sum; d = gDiff - (r + dl); cl0[x + dir][1] += r; cl1[x - dir][1] += dl; cl1[x][1] += d; coefsPtr = coefTable + sp->Blue; sum = coefsPtr->sum; r = coefsPtr->r * bDiff / sum; dl = coefsPtr->dl * bDiff / sum; d = bDiff - (r + dl); cl0[x + dir][2] += r; cl1[x - dir][2] += dl; cl1[x][2] += d; } #ifdef notdef static void DistributeErrorFS( double (*cl0)[3], double (*cl1)[3], int x, double rDiff, double gDiff, double bDiff, int dir, Blt_Pixel *sp) { double d2, d3, d5, d7; d2 = rDiff + rDiff; d3 = rDiff + d2; d5 = d3 + d2; d7 = d5 + d2; cl0[x + dir][0] += (d7 / 16); cl1[x - dir][0] += (d3 / 16); cl1[x][0] += (d5 / 16); cl1[x + dir][0] += (rDiff / 16); d2 = gDiff + gDiff; d3 = gDiff + d2; d5 = d3 + d2; d7 = d5 + d2; cl0[x + dir][1] += (d7 / 16); cl1[x - dir][1] += (d3 / 16); cl1[x][1] += (d5 / 16); cl1[x + dir][1] += (gDiff / 16); d2 = bDiff + bDiff; d3 = bDiff + d2; d5 = d3 + d2; d7 = d5 + d2; cl0[x + dir][2] += (d7 / 16); cl1[x - dir][2] += (d3 / 16); cl1[x][2] += (d5 / 16); cl1[x + dir][2] += (bDiff / 16); } #endif static void ShiftCarryBuffers(double (**cl0)[3], double (**cl1)[3], int width) { double (*tmp)[3]; int i; /* Swap cl0 and cl1 */ tmp = *cl0, *cl0 = *cl1, *cl1 = tmp; /* Clear c11 */ for (i = 0; i < width; ++i) { (*cl1)[i][0] = (*cl1)[i][1] = (*cl1)[i][2] = 0.0; } } /* *--------------------------------------------------------------------------- * * Blt_DitherPicture -- * * Dithers a 24-bit picture using a given reduced-color palette. * * Reference: * Victor Ostromoukhov http://www.iro.umontreal.ca/~ostrom/. * * Victor Ostromoukhov, "A Simple and Efficient * Error-Diffusion Algorithm" SIGGRAPH'01 * * University of Montreal, http://www.iro.umontreal.ca/~ostrom/ * * Results: * A new picture is allocated, dithered and returned. Returns NULL only * if memory can't be allocated for the dithered picture. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_DitherPicture(Pict *srcPtr, Blt_Pixel *palette) { Pict *destPtr; Blt_Pixel *srcRowPtr, *destRowPtr; double (*cl0)[3]; double (*cl1)[3]; int y; /* allocate carry_line_0 and carry_line_1 */ cl0 = Blt_Calloc(srcPtr->width + 2, sizeof(*cl0)); if (cl0 == NULL) { return NULL; } cl1 = Blt_Calloc(srcPtr->width + 2, sizeof(*cl1)); if (cl1 == NULL) { Blt_Free(cl0); return NULL; } ++cl0; ++cl1; destPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); srcRowPtr = srcPtr->bits, destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; ++y) { Blt_Pixel *sp, *dp; int start, finish, step; int x; if (y & 1) { start = srcPtr->width - 1; finish = -1; step = -1; } else { start = 0; finish = srcPtr->width; step = 1; } sp = srcRowPtr + start, dp = destRowPtr + start; for (x = start; x != finish; x += step) { double rCorrected, gCorrected, bCorrected; double rDiff, gDiff, bDiff; int rIntensity, gIntensity, bIntensity; rCorrected = sp->Red + cl0[x][0]; gCorrected = sp->Green + cl0[x][1]; bCorrected = sp->Blue + cl0[x][2]; rIntensity = palette[(int)CLAMP(rCorrected)].Red; gIntensity = palette[(int)CLAMP(gCorrected)].Green; bIntensity = palette[(int)CLAMP(bCorrected)].Blue; rDiff = rCorrected - rIntensity; gDiff = gCorrected - gIntensity; bDiff = bCorrected - bIntensity; DistributeError(cl0, cl1, x, rDiff, gDiff, bDiff, step, sp); dp->Red = rIntensity; dp->Green = gIntensity; dp->Blue = bIntensity; dp += step, sp += step; } ShiftCarryBuffers(&cl0, &cl1, srcPtr->width); srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } Blt_Free(cl0 - 1); Blt_Free(cl1 - 1); return destPtr; } #ifdef notdef static void BoxX(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp, *send; Blt_Pixel *lp, *cp, *rp; /* Pointers to left, center, and right * pixels. */ Blt_Pixel hold; double r, g, b, a; dp = destRowPtr; cp = lp = srcRowPtr, rp = srcRowPtr + 1; r = (double)(lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (double)(lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (double)(lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (double)(lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; hold = *lp; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); dp++, cp++, rp++; for (send = srcRowPtr + srcPtr->width; rp < send; rp++, cp++, lp++) { r = (double)(lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (double)(lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (double)(lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (double)(lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); hold = *lp; dp++; } rp = cp; r = (double)(lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (double)(lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (double)(lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (double)(lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } static void BoxY(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcColPtr, *destColumnPtr; int x; srcColPtr = srcPtr->bits; destColumnPtr = destPtr->bits; for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *rp, *lp, *cp, *send; double r, g, b, a; Blt_Pixel hold; dp = destColumnPtr; cp = lp = srcColPtr, rp = srcColPtr + srcPtr->pixelsPerRow; r = (lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; hold = *lp; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); dp += destPtr->pixelsPerRow; cp += srcPtr->pixelsPerRow; rp += srcPtr->pixelsPerRow; for (send = srcColPtr + (srcPtr->height * srcPtr->pixelsPerRow); rp < send; /* empty */) { r = (lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; hold = *lp; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); dp += destPtr->pixelsPerRow; rp += srcPtr->pixelsPerRow; lp += srcPtr->pixelsPerRow; cp += srcPtr->pixelsPerRow; } rp = cp; r = (lp->Red + cp->Red + rp->Red) * 0.333333333333333; g = (lp->Green + cp->Green + rp->Green) * 0.333333333333333; b = (lp->Blue + cp->Blue + rp->Blue) * 0.333333333333333; a = (lp->Alpha + cp->Alpha + rp->Alpha) * 0.333333333333333; dp->Red = (unsigned char)CLAMP(r); dp->Green = (unsigned char)CLAMP(g); dp->Blue = (unsigned char)CLAMP(b); dp->Alpha = (unsigned char)CLAMP(a); srcColPtr++, destColumnPtr++; } } #endif static void TentHorizontally(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; srcRowPtr = srcPtr->bits; destRowPtr = destPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel left, center, right; Blt_Pixel *dp, *sp, *send; dp = destRowPtr; sp = srcRowPtr + 1; left = *srcRowPtr, center = left, right = *sp; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; center = right; dp++, sp++; for (send = srcRowPtr + srcPtr->width; sp < send; /*empty*/) { right = *sp; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; left = center; center = right; dp++, sp++; } right = center; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } return; } static void TentVertically(Pict *destPtr, Pict *srcPtr) { Blt_Pixel *srcColPtr, *destColumnPtr; int x; srcColPtr = srcPtr->bits; destColumnPtr = destPtr->bits; for (x = 0; x < srcPtr->width; x++) { Blt_Pixel left, center, right; Blt_Pixel *dp, *sp, *send; dp = destColumnPtr; sp = srcColPtr + srcPtr->pixelsPerRow; left = *srcColPtr, center = left, right = *sp; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; center = right; dp += destPtr->pixelsPerRow; sp += srcPtr->pixelsPerRow; for (send = srcColPtr + (srcPtr->height * srcPtr->pixelsPerRow); sp < send; /* empty */) { right = *sp; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; left = center; center = right; dp += destPtr->pixelsPerRow; sp += srcPtr->pixelsPerRow; } right = center; dp->Red = (left.Red + (center.Red << 1) + right.Red) >> 2; dp->Green = (left.Green + (center.Green << 1) + right.Green) >> 2; dp->Blue = (left.Blue + (center.Blue << 1) + right.Blue) >> 2; dp->Alpha = (left.Alpha + (center.Alpha << 1) + right.Alpha) >> 2; srcColPtr++, destColumnPtr++; } } static void ApplyPictureToPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy, Blt_PictureArithOps op) { Blt_Pixel *srcRowPtr, *destRowPtr; if ((x + w) > srcPtr->width) { w -= srcPtr->width - x; } if ((y + h) > srcPtr->height) { h -= srcPtr->height - y; } if ((dx + w) > destPtr->width) { w -= destPtr->width - dx; } if ((dy + h) > destPtr->height) { h -= destPtr->height - dy; } srcRowPtr = srcPtr->bits + (srcPtr->pixelsPerRow * y) + x; destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * dy) + dx; for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *dend; sp = srcRowPtr; dp = destRowPtr, dend = dp + w; switch(op) { case PIC_ARITH_ADD: while (dp < dend) { int i; i = dp->Red + sp->Red; dp->Red = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Green + sp->Green; dp->Green = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Blue + sp->Blue; dp->Blue = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Alpha + sp->Alpha; dp->Alpha = (i > MAXINTENSITY) ? MAXINTENSITY : i; sp++, dp++; } break; case PIC_ARITH_SUB: while (dp < dend) { int i; i = dp->Red - sp->Red; dp->Red = (i < 0) ? 0 : i; i = dp->Green - sp->Green; dp->Green = (i < 0) ? 0 : i; i = dp->Blue - sp->Blue; dp->Blue = (i < 0) ? 0 : i; i = dp->Alpha - sp->Alpha; dp->Alpha = (i < 0) ? 0 : i; sp++, dp++; } break; case PIC_ARITH_RSUB: while (dp < dend) { int i; i = sp->Red - dp->Red; dp->Red = (i < 0) ? 0 : i; i = sp->Green - dp->Green; dp->Green = (i < 0) ? 0 : i; i = sp->Blue - dp->Blue; dp->Blue = (i < 0) ? 0 : i; i = sp->Alpha - dp->Alpha; dp->Alpha = (i < 0) ? 0 : i; sp++, dp++; } break; case PIC_ARITH_AND: while (dp < dend) { dp->u32 &= sp->u32; sp++, dp++; } break; case PIC_ARITH_OR: while (dp < dend) { dp->u32 |= sp->u32; sp++, dp++; } break; case PIC_ARITH_XOR: while (dp < dend) { dp->u32 ^= sp->u32; sp++, dp++; } break; case PIC_ARITH_NAND: while (dp < dend) { dp->u32 = ~(dp->u32 & sp->u32); sp++, dp++; } break; case PIC_ARITH_NOR: while (dp < dend) { dp->u32 = ~(dp->u32 | sp->u32); sp++, dp++; } break; case PIC_ARITH_MIN: while (dp < dend) { dp->Red = MIN(dp->Red, sp->Red); dp->Green = MIN(dp->Green, sp->Green); dp->Blue = MIN(dp->Blue, sp->Blue); dp->Alpha = MIN(dp->Alpha, sp->Alpha); sp++, dp++; } break; case PIC_ARITH_MAX: while (dp < dend) { dp->Red = MAX(dp->Red, sp->Red); dp->Green = MAX(dp->Green, sp->Green); dp->Blue = MAX(dp->Blue, sp->Blue); dp->Alpha = MAX(dp->Alpha, sp->Alpha); sp++, dp++; } break; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } } void Blt_ApplyColorToPicture(Pict *srcPtr, Blt_Pixel *colorPtr) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { if (sp->Alpha != 0x0) { sp->Red = colorPtr->Red; sp->Green = colorPtr->Green; sp->Blue = colorPtr->Blue; } } srcRowPtr += srcPtr->pixelsPerRow; } } static void ApplyScalarToPicture(Pict *srcPtr, Blt_Pixel *colorPtr, Blt_PictureArithOps op) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; sp = srcRowPtr; send = sp + srcPtr->width; switch(op) { case PIC_ARITH_ADD: while (sp < send) { int i; i = sp->Red + colorPtr->Red; sp->Red = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Green + colorPtr->Green; sp->Green = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Blue + colorPtr->Blue; sp->Blue = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Alpha + colorPtr->Alpha; sp->Alpha = (i > MAXINTENSITY) ? MAXINTENSITY : i; sp++; } break; case PIC_ARITH_SUB: while (sp < send) { int i; i = sp->Red - colorPtr->Red; sp->Red = (i < 0) ? 0 : i; i = sp->Green - colorPtr->Green; sp->Green = (i < 0) ? 0 : i; i = sp->Blue - colorPtr->Blue; sp->Blue = (i < 0) ? 0 : i; i = sp->Alpha - colorPtr->Alpha; sp->Alpha = (i < 0) ? 0 : i; sp++; } break; case PIC_ARITH_RSUB: while (sp < send) { int i; i = colorPtr->Red - sp->Red; sp->Red = (i < 0) ? 0 : i; i = colorPtr->Green - sp->Green; sp->Green = (i < 0) ? 0 : i; i = colorPtr->Blue - sp->Blue; sp->Blue = (i < 0) ? 0 : i; i = colorPtr->Alpha - sp->Alpha; sp->Alpha = (i < 0) ? 0 : i; sp++; } break; case PIC_ARITH_AND: while (sp < send) { sp->u32 &= colorPtr->u32; sp++; } break; case PIC_ARITH_OR: while (sp < send) { sp->u32 |= colorPtr->u32; sp++; } break; case PIC_ARITH_XOR: while (sp < send) { sp->u32 ^= colorPtr->u32; sp++; } break; case PIC_ARITH_NAND: while (sp < send) { sp->u32 = ~(sp->u32 & colorPtr->u32); sp++; } break; case PIC_ARITH_NOR: while (sp < send) { sp->u32 = ~(sp->u32 | colorPtr->u32); sp++; } break; case PIC_ARITH_MIN: while (sp < send) { sp->Red = MIN(sp->Red, colorPtr->Red); sp->Green = MIN(sp->Green, colorPtr->Green); sp->Blue = MIN(sp->Blue, colorPtr->Blue); sp->Alpha = MIN(sp->Alpha, colorPtr->Alpha); sp++; } break; case PIC_ARITH_MAX: while (sp < send) { sp->Red = MAX(sp->Red, colorPtr->Red); sp->Green = MAX(sp->Green, colorPtr->Green); sp->Blue = MAX(sp->Blue, colorPtr->Blue); sp->Alpha = MAX(sp->Alpha, colorPtr->Alpha); sp++; } break; } srcRowPtr += srcPtr->pixelsPerRow; } } static void ApplyPictureToPictureWithMask(Pict *destPtr, Pict *srcPtr, Pict *maskPtr, int x, int y, int w, int h, int dx, int dy, int invert, Blt_PictureArithOps op) { Blt_Pixel *srcRowPtr, *destRowPtr, *maskRowPtr; unsigned int off; if ((x + w) > srcPtr->width) { w -= srcPtr->width - x; } if ((y + h) > srcPtr->height) { h -= srcPtr->height - y; } if ((dx + w) > destPtr->width) { w -= destPtr->width - dx; } if ((dy + h) > destPtr->height) { h -= destPtr->height - dy; } off = (invert) ? (unsigned int)-1 : 0; maskRowPtr = maskPtr->bits; srcRowPtr = srcPtr->bits + (srcPtr->pixelsPerRow * y) + x; destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * dy) + dx; for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *mp, *mend; sp = srcRowPtr, dp = destRowPtr; mp = maskRowPtr, mend = mp + w; switch(op) { case PIC_ARITH_ADD: while (mp < mend) { if (mp->u32 != off) { int i; i = dp->Red + sp->Red; dp->Red = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Green + sp->Green; dp->Green = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Blue + sp->Blue; dp->Blue = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = dp->Alpha + sp->Alpha; dp->Alpha = (i > MAXINTENSITY) ? MAXINTENSITY : i; } sp++, dp++, mp++; } break; case PIC_ARITH_SUB: while (mp < mend) { if (mp->u32 != off) { int i; i = dp->Red - sp->Red; dp->Red = (i < 0) ? 0 : i; i = dp->Green - sp->Green; dp->Green = (i < 0) ? 0 : i; i = dp->Blue - sp->Blue; dp->Blue = (i < 0) ? 0 : i; i = dp->Alpha - sp->Alpha; dp->Alpha = (i < 0) ? 0 : i; } sp++, dp++, mp++; } break; case PIC_ARITH_RSUB: while (mp < mend) { if (mp->u32 != off) { int i; i = sp->Red - dp->Red; dp->Red = (i < 0) ? 0 : i; i = sp->Green - dp->Green; dp->Green = (i < 0) ? 0 : i; i = sp->Blue - dp->Blue; dp->Blue = (i < 0) ? 0 : i; i = sp->Alpha - dp->Alpha; dp->Alpha = (i < 0) ? 0 : i; } sp++, dp++, mp++; } break; case PIC_ARITH_AND: while (mp < mend) { if (mp->u32 != off) { dp->u32 &= sp->u32; } sp++, dp++, mp++; } break; case PIC_ARITH_OR: while (mp < mend) { if (mp->u32 != off) { dp->u32 |= sp->u32; } sp++, dp++, mp++; } break; case PIC_ARITH_XOR: while (mp < mend) { if (mp->u32 != off) { dp->u32 ^= sp->u32; } sp++, dp++, mp++; } break; case PIC_ARITH_NAND: while (mp < mend) { if (mp->u32 != off) { dp->u32 = ~(dp->u32 & sp->u32); } sp++, dp++, mp++; } break; case PIC_ARITH_NOR: while (mp < mend) { if (mp->u32 != off) { dp->u32 = ~(dp->u32 | sp->u32); } sp++, dp++, mp++; } break; case PIC_ARITH_MIN: while (mp < mend) { if (mp->u32 != off) { dp->Red = MIN(dp->Red, sp->Red); dp->Green = MIN(dp->Green, sp->Green); dp->Blue = MIN(dp->Blue, sp->Blue); dp->Alpha = MIN(dp->Alpha, sp->Alpha); } sp++, dp++, mp++; } break; case PIC_ARITH_MAX: while (mp < mend) { if (mp->u32 != off) { dp->Red = MAX(dp->Red, sp->Red); dp->Green = MAX(dp->Green, sp->Green); dp->Blue = MAX(dp->Blue, sp->Blue); dp->Alpha = MAX(dp->Alpha, sp->Alpha); } sp++, dp++, mp++; } break; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; maskRowPtr += maskPtr->pixelsPerRow; } } static void ApplyScalarToPictureWithMask(Pict *srcPtr, Blt_Pixel *colorPtr, Pict *maskPtr, int invert, Blt_PictureArithOps op) { Blt_Pixel *srcRowPtr, *maskRowPtr; int width, height; int y; unsigned int off; width = MIN(srcPtr->width, maskPtr->width); height = MIN(srcPtr->height, maskPtr->height); srcRowPtr = srcPtr->bits; maskRowPtr = maskPtr->bits; off = (invert) ? (unsigned int)-1 : 0; for (y = 0; y < height; y++) { Blt_Pixel *sp, *mp, *mend; sp = srcRowPtr; mp = maskRowPtr, mend = mp + width; switch(op) { case PIC_ARITH_ADD: while (mp < mend) { if (mp->u32 != off) { int i; i = sp->Red + colorPtr->Red; sp->Red = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Green + colorPtr->Green; sp->Green = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Blue + colorPtr->Blue; sp->Blue = (i > MAXINTENSITY) ? MAXINTENSITY : i; i = sp->Alpha + colorPtr->Alpha; sp->Alpha = (i > MAXINTENSITY) ? MAXINTENSITY : i; } sp++, mp++; } break; case PIC_ARITH_SUB: while (mp < mend) { if (mp->u32 != off) { int i; i = sp->Red - colorPtr->Red; sp->Red = (i < 0) ? 0 : i; i = sp->Green - colorPtr->Green; sp->Green = (i < 0) ? 0 : i; i = sp->Blue - colorPtr->Blue; sp->Blue = (i < 0) ? 0 : i; i = sp->Alpha - colorPtr->Alpha; sp->Alpha = (i < 0) ? 0 : i; } sp++, mp++; } break; case PIC_ARITH_RSUB: while (mp < mend) { if (mp->u32 != off) { int i; i = colorPtr->Red - sp->Red; sp->Red = (i < 0) ? 0 : i; i = colorPtr->Green - sp->Green; sp->Green = (i < 0) ? 0 : i; i = colorPtr->Blue - sp->Blue; sp->Blue = (i < 0) ? 0 : i; i = colorPtr->Alpha - sp->Alpha; sp->Alpha = (i < 0) ? 0 : i; } sp++, mp++; } break; case PIC_ARITH_AND: while (mp < mend) { if (mp->u32 != off) { sp->u32 &= colorPtr->u32; } sp++, mp++; } break; case PIC_ARITH_OR: while (mp < mend) { if (mp->u32 != off) { sp->u32 |= colorPtr->u32; } sp++, mp++; } break; case PIC_ARITH_XOR: while (mp < mend) { if (mp->u32 != off) { sp->u32 ^= colorPtr->u32; } sp++, mp++; } break; case PIC_ARITH_NAND: while (mp < mend) { if (mp->u32 != off) { sp->u32 = ~(sp->u32 & colorPtr->u32); } sp++, mp++; } break; case PIC_ARITH_NOR: while (mp < mend) { if (mp->u32 != off) { sp->u32 = ~(sp->u32 | colorPtr->u32); } sp++, mp++; } break; case PIC_ARITH_MIN: while (mp < mend) { if (mp->u32 != off) { sp->Red = MIN(sp->Red, colorPtr->Red); sp->Green = MIN(sp->Green, colorPtr->Green); sp->Blue = MIN(sp->Blue, colorPtr->Blue); sp->Alpha = MIN(sp->Alpha, colorPtr->Alpha); } sp++, mp++; } break; case PIC_ARITH_MAX: while (mp < mend) { if (mp->u32 != off) { sp->Red = MAX(sp->Red, colorPtr->Red); sp->Green = MAX(sp->Green, colorPtr->Green); sp->Blue = MAX(sp->Blue, colorPtr->Blue); sp->Alpha = MAX(sp->Alpha, colorPtr->Alpha); } sp++, mp++; } break; } srcRowPtr += srcPtr->pixelsPerRow; maskRowPtr += maskPtr->pixelsPerRow; } } void Blt_MultiplyPixels(Pict *srcPtr, float scalar) { Blt_Pixel *srcRowPtr; short int s15; int y; float x; int nBits, bias; x = FABS(scalar); if (FABS(x) > 127.0) { return; } /* Figure out how many bits we need. */ nBits = 0; while ((1 << nBits) < x) { nBits++; } nBits = 15 - nBits; bias = (1 << nBits) / 2; if (scalar < 0) { bias = -bias; } s15 = (short int)((scalar * (float)(1 << nBits)) + 0.5); srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; sp = srcRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { short int r15, g15, b15, a15; int i31; short int i15; r15 = ((sp->Red << 8) + sp->Red) >> 1; g15 = ((sp->Green << 8) + sp->Green) >> 1; b15 = ((sp->Blue << 8) + sp->Blue) >> 1; a15 = ((sp->Alpha << 8) + sp->Alpha) >> 1; i31 = r15 * s15; i15 = i31 >> 16; /* Truncate lower 16 bits */ i15 =+ bias; i15 >>= nBits; sp->Red = (i15 > 255) ? 255 : i15; i31 = g15 * s15; i15 = i31 >> 16; /* Truncate lower 16 bits */ i15 =+ bias; i15 >>= nBits; sp->Green = (i15 > 255) ? 255 : i15; i31 = b15 * s15; i15 = i31 >> 16; /* Truncate lower 16 bits */ i15 =+ bias; i15 >>= nBits; sp->Green = (i15 > 255) ? 255 : i15; i31 = a15 * s15; i15 = i31 >> 16; /* Truncate lower 16 bits */ i15 =+ bias; i15 >>= nBits; sp->Alpha = (i15 > 255) ? 255 : i15; } srcRowPtr += srcPtr->pixelsPerRow; } } static void SelectPixels(Pict *destPtr, Pict *srcPtr, Blt_Pixel *lowPtr, Blt_Pixel *highPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; int y; if (srcPtr != destPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); } destRowPtr = destPtr->bits, srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp, *sp, *send; dp = destRowPtr; for(sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++, dp++) { if ((sp->Red >= lowPtr->Red) && (sp->Red <= highPtr->Red) && (sp->Green >= lowPtr->Green) && (sp->Green <= highPtr->Green) && (sp->Blue >= lowPtr->Blue) && (sp->Blue <= highPtr->Blue) && (sp->Alpha >= lowPtr->Alpha) && (sp->Alpha <= highPtr->Alpha)) { dp->u32 = 0xFFFFFFFF; } else { dp->u32 = 0; } } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } destPtr->flags &= ~BLT_PIC_BLEND; destPtr->flags |= BLT_PIC_MASK; } #ifdef nodtdef void Blt_BoxFilterPicture(Pict *destPtr, Pict *srcPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); BoxY(destPtr, srcPtr); BoxX(destPtr, destPtr); } void Blt_TentFilterPicture(Pict *destPtr, Pict *srcPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); Blt_TentVertically(destPtr, srcPtr); Blt_TentHorizontally(destPtr, destPtr); } static unsigned int ComputeWeights( unsigned int sw, unsigned int dw, /* Source and destination widths. */ ResampleFilter *filterPtr, Sample **samplePtrPtr) { Sample *samples; double scale; int bytesPerSample; /* Pre-calculate filter contributions for a row */ scale = (double)dw / (double)sw; if (scale < 1.0) { Sample *samplePtr; double radius, fscale; int filterSize, x; /* Downsample */ radius = filterPtr->support / scale; fscale = 1.0 / scale; filterSize = (int)(radius * 2 + 2); bytesPerSample = sizeof(Sample) + ((filterSize - 1) * sizeof(PixelWeight)); samples = Blt_AssertCalloc(dw, bytesPerSample); samplePtr = samples; #define DEBUG 0 #if DEBUG fprintf(stderr, "downscale=%g, fscale=%g, radius=%g\n", scale, fscale, radius); #endif for (x = 0; x < dw; x++) { PixelWeight *wp; double center; int i, left, right; /* Filter bounds. */ center = ((double)x + 0.5) * fscale; /* Determine bounds of filter and its density. */ left = (int)/*floor*/(center - radius); if (left < 0) { left = 0; } right = (int)/*floor*/(center + radius); if (right >= sw) { right = sw - 1; } samplePtr->start = left; samplePtr->wend = samplePtr->weights + (right - left + 1); for (wp = samplePtr->weights, i = left; i <= right; i++, wp++) { wp->f32 = (float) (*filterPtr->proc)(((double)i - center) * scale); wp->i32 = float2si(wp->f32); } samplePtr = (Sample *)((char *)samplePtr + bytesPerSample); } } else { Sample *samplePtr; double fscale; int filterSize, x; /* Upsample */ filterSize = (int)(filterPtr->support * 2 + 2); bytesPerSample = sizeof(Sample) + ((filterSize - 1) * sizeof(PixelWeight)); samples = Blt_AssertCalloc(dw, bytesPerSample); fscale = 1.0 / scale; samplePtr = samples; #if DEBUG fprintf(stderr, "upscale=%g, fscale=%g, radius=%g\n", scale, fscale, filterPtr->support); #endif for (x = 0; x < dw; x++) { PixelWeight *wp; double center; int i, left, right; /* Filter bounds. */ center = ((double)x + 0.5) * fscale; left = (int)(center - filterPtr->support); if (left < 0) { left = 0; } right = (int)(center + filterPtr->support); if (right >= sw) { right = sw - 1; } samplePtr->start = left; samplePtr->wend = samplePtr->weights + (right - left + 1); /* Sum the contributions for each pixel in the filter. */ for (wp = samplePtr->weights, i = left; i <= right;i++, wp++) { wp->f32 = (float) (*filterPtr->proc)((double)i - center); wp->i32 = float2si(wp->f32); } /* Go get the next sample. */ samplePtr = (Sample *)((char *)samplePtr + bytesPerSample); } } *samplePtrPtr = samples; return bytesPerSample; } #endif static unsigned int * CreateNeighborhoodMap(unsigned int size, unsigned int radius) { unsigned int newSize; unsigned int *map, *p; unsigned int i; newSize = size + radius + radius; map = Blt_AssertMalloc(sizeof(unsigned int) * newSize); p = map; for (i = 0; i < radius; i++, p++) { *p = 0; /* Before the picture. Replicate the first * pixel. */ } for (i = 0; i < size; i++, p++) { *p = i; } for (i = 0; i < radius; i++, p++) { *p = size - 1; /* After the picture. Replicate the last * pixel */ } return map; } static void ConvolveVertically(Pict *destPtr, Pict *srcPtr, TableFilter *filterPtr) { int x; unsigned *map, mapSize; int fscale; map = CreateNeighborhoodMap(srcPtr->height, filterPtr->nWeights / 2); mapSize = srcPtr->height + filterPtr->nWeights; fscale = float2si(filterPtr->scale); /* Apply filter to each row. */ for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColPtr; srcColPtr = srcPtr->bits + x; dp = destPtr->bits + x; for (x = 0; x < mapSize; x++) { int i; int r, g, b, a; r = g = b = a = 0; for (i = 0; i < filterPtr->nWeights; i++) { int sx; Blt_Pixel *sp; sx = map[x + i]; sp = srcColPtr + (srcPtr->pixelsPerRow * sx); r += sp->Red * filterPtr->weights[i]; g += sp->Green * filterPtr->weights[i]; b += sp->Blue * filterPtr->weights[i]; a += sp->Alpha * filterPtr->weights[i]; } r *= fscale; g *= fscale; b *= fscale; a *= fscale; dp->Red = (unsigned char)SICLAMP(r); dp->Green = (unsigned char)SICLAMP(g); dp->Blue = (unsigned char)SICLAMP(b); dp->Alpha = (unsigned char)SICLAMP(a); dp += destPtr->pixelsPerRow; } } /* Free the memory allocated for filter weights. */ Blt_Free(map); } static void ConvolveHorizontally(Pict *destPtr, Pict *srcPtr, TableFilter *filterPtr) { int y; Blt_Pixel *srcRowPtr, *destRowPtr; unsigned int *map, mapSize; int fscale; map = CreateNeighborhoodMap(srcPtr->width, filterPtr->nWeights / 2); mapSize = srcPtr->width + filterPtr->nWeights; fscale = float2si(filterPtr->scale); destRowPtr = destPtr->bits; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; int x; dp = destRowPtr; for (x = 0; x < mapSize; x++) { int i; int r, g, b, a; r = g = b = a = 0; for (i = 0; i < filterPtr->nWeights; i++) { Blt_Pixel *sp; sp = srcRowPtr + map[x + i]; r += sp->Red * filterPtr->weights[i]; g += sp->Green * filterPtr->weights[i]; b += sp->Blue * filterPtr->weights[i]; a += sp->Alpha * filterPtr->weights[i]; } r *= fscale; g *= fscale; b *= fscale; a *= fscale; dp->Red = (unsigned char)SICLAMP(r); dp->Green = (unsigned char)SICLAMP(g); dp->Blue = (unsigned char)SICLAMP(b); dp->Alpha = (unsigned char)SICLAMP(a); dp++; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } /* Free the memory allocated for map. */ Blt_Free(map); } /* *--------------------------------------------------------------------------- * * Blt_ConvolvePicture -- * * Resamples a given picture using 1-D filters and returns a new picture * of the designated size. * * Results: * Returns the resampled picture. The original picture is left intact. * *--------------------------------------------------------------------------- */ void Blt_ConvolvePicture(Pict *destPtr, Pict *srcPtr, struct _Blt_ConvolveFilter *xFilterPtr, struct _Blt_ConvolveFilter *yFilterPtr) { Pict *tmpPtr; tmpPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); if (xFilterPtr->type == RESAMPLE_FILTER) { Blt_ZoomHorizontally(tmpPtr, srcPtr, xFilterPtr->filter); } else { ConvolveHorizontally(tmpPtr, srcPtr, xFilterPtr->filter); } if (yFilterPtr->type == RESAMPLE_FILTER) { Blt_ZoomVertically(destPtr, tmpPtr, yFilterPtr->filter); } else { ConvolveVertically(destPtr, tmpPtr, yFilterPtr->filter); } Blt_FreePicture(tmpPtr); destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); } static void BoxCarVertically(Pict *destPtr, Pict *srcPtr, unsigned int r) { unsigned int x; unsigned int *map; int fscale; unsigned int fwidth; /* Filter width */ float s; map = CreateNeighborhoodMap(srcPtr->height, r); fwidth = r + r + 1; s = 1.0f / fwidth; fscale = float2si(s); fwidth--; /* Apply filter to each row. */ for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *dp, *srcColPtr; int r, g, b, a; unsigned int y; srcColPtr = srcPtr->bits + x; r = g = b = a = 0; /* Prime the pump. */ for (y = 0; y < fwidth; y++) { Blt_Pixel *sp; sp = srcColPtr + (srcPtr->pixelsPerRow * map[y]); r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; } dp = destPtr->bits + x; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int fr, fg, fb, fa; sp = srcColPtr + (srcPtr->pixelsPerRow * map[y + fwidth]); r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; fr = r * fscale; fg = g * fscale; fb = b * fscale; fa = a * fscale; dp->Red = (unsigned char)SICLAMP(fr); dp->Green = (unsigned char)SICLAMP(fg); dp->Blue = (unsigned char)SICLAMP(fb); dp->Alpha = (unsigned char)SICLAMP(fa); sp = srcColPtr + (srcPtr->pixelsPerRow * map[y]); r -= sp->Red; g -= sp->Green; b -= sp->Blue; a -= sp->Alpha; dp += destPtr->pixelsPerRow; } } /* Free the memory allocated for filter weights. */ Blt_Free(map); } static void BoxCarHorizontally(Pict *destPtr, Pict *srcPtr, unsigned int r) { Blt_Pixel *srcRowPtr, *destRowPtr; float s; unsigned int *map; int fscale; unsigned int y; unsigned int fwidth; /* Filter width */ fwidth = r + r + 1; map = CreateNeighborhoodMap(srcPtr->width, r); s = 1.0f / fwidth; fscale = float2si(s); destRowPtr = destPtr->bits; srcRowPtr = srcPtr->bits; fwidth--; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *dp; unsigned int x; int r, g, b, a; /* Prime the pump. Get sums for each component for the first (fwidth) * pixels in the column. */ r = g = b = a = 0; for (x = 0; x < fwidth; x++) { Blt_Pixel *sp; sp = srcRowPtr + map[x]; r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; } dp = destRowPtr; for (x = 0; x < srcPtr->width; x++) { Blt_Pixel *sp; int fr, fg, fb, fa; sp = srcRowPtr + map[x + fwidth]; r += sp->Red; g += sp->Green; b += sp->Blue; a += sp->Alpha; fr = r * fscale; fg = g * fscale; fb = b * fscale; fa = a * fscale; dp->Red = (unsigned char)SICLAMP(fr); dp->Green = (unsigned char)SICLAMP(fg); dp->Blue = (unsigned char)SICLAMP(fb); dp->Alpha = (unsigned char)SICLAMP(fa); sp = srcRowPtr + map[x]; r -= sp->Red; g -= sp->Green; b -= sp->Blue; a -= sp->Alpha; dp++; } destRowPtr += destPtr->pixelsPerRow; srcRowPtr += srcPtr->pixelsPerRow; } /* Free the memory allocated for map. */ Blt_Free(map); } /* *--------------------------------------------------------------------------- * * Blt_BlurPicture -- * * Blurs a picture using a series of 1-D box filters. The width of the * box filter is a parameter. The source picture is blurred and stored in * the destination picture. * * Results: * None. * Side Effects: * The original picture is left intact. The destination picture contains * the blurred image. * *--------------------------------------------------------------------------- */ void Blt_BlurPicture(Pict *destPtr, Pict *srcPtr, unsigned int r) { Pict *tmpPtr; if (srcPtr != destPtr) { Blt_ResizePicture(destPtr, srcPtr->width, srcPtr->height); } tmpPtr = Blt_CreatePicture(srcPtr->width, srcPtr->height); BoxCarHorizontally(tmpPtr, srcPtr, r); BoxCarVertically(destPtr, tmpPtr, r); BoxCarHorizontally(tmpPtr, destPtr, r); BoxCarVertically(destPtr, tmpPtr, r); BoxCarHorizontally(tmpPtr, destPtr, r); BoxCarVertically(destPtr, tmpPtr, r); #ifdef notdef BoxCarHorizontally(tmpPtr, destPtr, r); BoxCarVertically(destPtr, tmpPtr, r); #endif Blt_FreePicture(tmpPtr); destPtr->flags = (srcPtr->flags | BLT_PIC_DIRTY); } #ifdef notdef void Blt_BlurPictureOld(Blt_Picture pict) { Blt_Picture tmp; tmp = Blt_CreatePicture(Blt_PictureWidth(pict), Blt_PictureHeight(pict)); BoxX(tmp, pict), BoxY(pict, tmp); BoxX(tmp, pict), BoxY(pict, tmp); BoxX(tmp, pict), BoxY(pict, tmp); BoxX(tmp, pict), BoxY(pict, tmp); Blt_FreePicture(tmp); } #endif void Blt_SharpenPicture(Pict *destPtr, Pict *srcPtr) { Blt_Picture blur, tmp; blur = Blt_CreatePicture(srcPtr->width, srcPtr->height); Blt_BlurPicture(blur, srcPtr, 4); /* * tmp = src - blur; * dest = src + tmp */ tmp = Blt_ClonePicture(srcPtr); Blt_SubtractPictures(tmp, blur); Blt_AddPictures(tmp, srcPtr); Blt_FreePicture(blur); Blt_CopyPictureBits(destPtr, tmp, 0, 0, Blt_PictureWidth(tmp), Blt_PictureHeight(tmp), 0, 0); Blt_FreePicture(tmp); } /* *--------------------------------------------------------------------------- * * Blt_TilePicture -- * * Tiles the designated region in the destination picture with the source * picture. * * Please note that it is the responsibility of the caller to verify the * region is valid (i.e. wholly contained by the destination picture). * * Results: * The destination picture is tiled. The original picture * is left * intact. * *--------------------------------------------------------------------------- */ void Blt_TilePicture( Pict *destPtr, /* Picture to be tiled. */ Pict *srcPtr, /* Picture used as the tile. */ int xOrigin, int yOrigin, /* Tile origin. */ int x, int y, int w, int h) /* Region of destination picture to be * tiled. */ { int startX, startY; /* Starting upper left corner of * region. */ int delta; /* Compute the starting x and y offsets of the tile from the coordinates * of the origin. */ startX = x; if (x < xOrigin) { delta = (xOrigin - x) % srcPtr->width; if (delta > 0) { startX -= (srcPtr->width - delta); } } else if (x > xOrigin) { delta = (x - xOrigin) % srcPtr->width; if (delta > 0) { startX -= delta; } } startY = y; if (y < yOrigin) { delta = (yOrigin - y) % srcPtr->height; if (delta > 0) { startY -= (srcPtr->height - delta); } } else if (y >= yOrigin) { delta = (y - yOrigin) % srcPtr->height; if (delta > 0) { startY -= delta; } } #ifdef notdef fprintf(stderr, "tile is (%d,%d,%d,%d)\n", xOrigin, yOrigin, srcPtr->width, srcPtr->height); fprintf(stderr, "region is (%d,%d,%d,%d)\n", x, y, w, h); fprintf(stderr, "starting at %d,%d\n", startX, startY); #endif { int left, top, right, bottom; /* The region to be tiled. */ left = x; right = x + w; top = y; bottom = y + h; for (y = startY; y < bottom; y += srcPtr->height) { int sy, dy; int th; /* Current tile height. */ sy = 0; dy = y; th = srcPtr->height; if (y < top) { sy = (top - y); th = srcPtr->height - sy; dy = top; } if ((dy + th) > bottom) { th = (bottom - dy); } for (x = startX; x < right; x += srcPtr->width) { int sx, dx; int tw; /* Current tile width. */ sx = 0; dx = x; tw = srcPtr->width; if (x < left) { sx = (left - x); tw = srcPtr->width - sx; dx = left; } if ((dx + tw) > right) { tw = (right - dx); } #ifdef notdef fprintf(stder, "drawing pattern (%d,%d,%d,%d) at %d,%d\n", sx, sy, tw, th, dx, dy); #endif Blt_BlendPictures(destPtr, srcPtr, sx, sy, tw, th, dx, dy); } } } } void Blt_GradientPicture( Pict *destPtr, /* (out) Picture to contain the new * gradient. */ Blt_Pixel *maxPtr, /* Color to represent 1.0 */ Blt_Pixel *minPtr, /* Color to represent 0.0 */ Blt_Gradient *gradientPtr) { double rRange, gRange, bRange, aRange; /* Compute the ranges for each color component. */ rRange = (double)(maxPtr->Red - minPtr->Red); gRange = (double)(maxPtr->Green - minPtr->Green); bRange = (double)(maxPtr->Blue - minPtr->Blue); aRange = (double)(maxPtr->Alpha - minPtr->Alpha); switch (gradientPtr->shape) { case BLT_GRADIENT_SHAPE_LINEAR: switch (gradientPtr->path) { case BLT_GRADIENT_PATH_X: { Blt_Pixel *copyRowPtr, *destRowPtr, *dp; int x, y; /* Draw the gradient on the first row, then copy the row to * each subsequent row. */ destRowPtr = destPtr->bits; for (dp = destRowPtr, x = 0; x < destPtr->width; x++, dp++) { double t; t = (double)x / (double)(destPtr->width - 1); if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow;; copyRowPtr = destPtr->bits; for (y = 1; y < destPtr->height; y++) { Blt_Pixel *dp, *sp, *send; for (dp = destRowPtr, sp = copyRowPtr, send = sp + destPtr->width; sp < send; dp++, sp++) { dp->u32 = sp->u32; } copyRowPtr += destPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_Y: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *dend; double t; Blt_Pixel color; /* Compute the color value for the row and then replicate * it in every pixel in the row. */ dp = destRowPtr; t = (double)y / (double)(destPtr->height - 1); if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } color.Red = (unsigned char)(minPtr->Red + t * rRange); color.Green = (unsigned char)(minPtr->Green + t * gRange); color.Blue = (unsigned char)(minPtr->Blue + t * bRange); color.Alpha = (unsigned char)(minPtr->Alpha + t * aRange); for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { dp->u32 = color.u32; } destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_YX: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp; int x; double ty; ty = (double)y / (double)(destPtr->height - 1); ty = 1.0 - ty; for (dp = destRowPtr, x=0; x < destPtr->width; x++, dp++) { double t; double tx; tx = (double)x / (double)(destPtr->width - 1); t = (tx + ty) * 0.5; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_XY: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp; int x; double ty; ty = (double)y / (double)(destPtr->height - 1); for (dp = destRowPtr, x=0; x < destPtr->width; x++, dp++) { double t, tx; tx = (double)x / (double)(destPtr->width - 1); t = (tx + ty) * 0.5; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow; } } break; } break; case BLT_GRADIENT_SHAPE_BILINEAR: switch (gradientPtr->path) { case BLT_GRADIENT_PATH_X: { Blt_Pixel *copyRowPtr, *destRowPtr, *dp; int x, y; /* Draw the gradient on the first row, then copy the row to * each subsequent row. */ destRowPtr = destPtr->bits; for (dp = destRowPtr, x = 0; x < destPtr->width; x++, dp++) { double t; t = (double)x / (double)(destPtr->width - 1); if (t > 0.5) { t = 1.0 - t; } t += t; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow;; copyRowPtr = destPtr->bits; for (y = 1; y < destPtr->height; y++) { Blt_Pixel *dp, *sp, *send; for (dp = destRowPtr, sp = copyRowPtr, send = sp + destPtr->width; sp < send; dp++, sp++) { dp->u32 = sp->u32; } copyRowPtr += destPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_Y: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *dend; double t; Blt_Pixel color; /* Compute the color value for the row and then replicate * it in every pixel in the row. */ dp = destRowPtr; t = (double)y / (double)(destPtr->height - 1); if (t > 0.5) { t = 1.0 - t; } t += t; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } color.Red = (unsigned char)(minPtr->Red + t * rRange); color.Green = (unsigned char)(minPtr->Green + t * gRange); color.Blue = (unsigned char)(minPtr->Blue + t * bRange); color.Alpha = (unsigned char)(minPtr->Alpha + t * aRange); for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { dp->u32 = color.u32; } destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_YX: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp; int x; double ty; ty = (double)y / (double)(destPtr->height - 1); for (dp = destRowPtr, x = 0; x < destPtr->width; x++, dp++) { double t, tx; tx = (double)x / (double)(destPtr->width - 1); t = 1.0 - ABS(tx - ty); if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_PATH_XY: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp; int x; double ty; ty = (double)y / (double)(destPtr->height - 1); ty = 1.0 - ty; for (dp = destRowPtr, x=0; x < destPtr->width; x++, dp++) { double t, tx; tx = (double)x / (double)(destPtr->width - 1); t = 1.0 - ABS(tx - ty); if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(minPtr->Alpha + t * aRange); } destRowPtr += destPtr->pixelsPerRow; } } break; } break; case BLT_GRADIENT_SHAPE_RADIAL: { Blt_Pixel *destRowPtr; int y; int cx, cy; int range; destRowPtr = destPtr->bits; /* Center coordinates. */ cx = destPtr->width / 2, cy = destPtr->height / 2; range = cx * cx + cy * cy; for (y = 0; y < destPtr->height; y++) { int x; double dy, dy2; Blt_Pixel *dp; dy = ABS(cy - y); dy2 = dy * dy; dp = destRowPtr; for (x = 0; x < destPtr->width; x++) { double dx; double t; dx = ABS(cx - x); t = sqrt(dx * dx + dy2) / range; t = 1.0 - t; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(t * aRange); dp++; } destRowPtr += destPtr->pixelsPerRow; } } break; case BLT_GRADIENT_SHAPE_RECTANGULAR: { Blt_Pixel *destRowPtr; int y; int midX, midY; midX = destPtr->width / 2, midY = destPtr->height / 2; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp; int x; double ty; ty = (double)y / (double)(destPtr->height - 1); if (ty > 0.5) { ty = 1.0 - ty; } dp = destRowPtr; for (x = 0; x < destPtr->width; x++) { double t; double tx; tx = (double)x / (double)(destPtr->width - 1); if (tx > 0.5) { tx = 1.0 - tx; } t = MIN(tx, ty); t += t; if (gradientPtr->jitter) { t += JITTER(t); t = JCLAMP(t); } if (gradientPtr->logScale) { t = log10(9.0 * t + 1.0); } dp->Red = (unsigned char)(minPtr->Red + t * rRange); dp->Green = (unsigned char)(minPtr->Green + t * gRange); dp->Blue = (unsigned char)(minPtr->Blue + t * bRange); dp->Alpha = (unsigned char)(t * aRange); dp++; } destRowPtr += destPtr->pixelsPerRow; } } break; } } void Blt_TexturePicture(Pict *destPtr, Blt_Pixel *lowPtr, Blt_Pixel *highPtr, int type) { #define TEXTURE_CHECKERED 1 #define TEXTURE_STRIPED 0 switch (type) { case TEXTURE_STRIPED: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *dend; Blt_Pixel color; color = ((y / 2) & 0x1) ? *lowPtr : *highPtr; if (0) { double t; t = 0.8; t += JITTER(t); t = JCLAMP(t); color.Blue = (unsigned char)(color.Blue + t * 255.0); color.Red = (unsigned char)(color.Red + t * 255.0); color.Green = (unsigned char)(color.Green + t * 255.0); } for (dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++) { dp->u32 = color.u32; } destRowPtr += destPtr->pixelsPerRow; } } break; case TEXTURE_CHECKERED: { Blt_Pixel *destRowPtr; int y; destRowPtr = destPtr->bits; for (y = 0; y < destPtr->height; y++) { Blt_Pixel *dp, *dend; Blt_Pixel color; int x; if (0) { double t; t = 0.8; t += JITTER(t); t = JCLAMP(t); color.Blue = (unsigned char)(color.Blue + t * 255.0); color.Red = (unsigned char)(color.Red + t * 255.0); color.Green = (unsigned char)(color.Green + t * 255.0); } for (x = 0, dp = destRowPtr, dend = dp + destPtr->width; dp < dend; dp++, x++) { color = (((x / 8) & 1) && (((y / 8) & 1) == 0)) ? *lowPtr : *highPtr; dp->u32 = color.u32; } destRowPtr += destPtr->pixelsPerRow; } } break; } } int Blt_QueryColors(Pict *srcPtr, Blt_HashTable *tablePtr) { Blt_HashTable colorTable; Blt_Pixel *srcRowPtr; int y; int nColors; unsigned int flags; flags = 0; if (tablePtr == NULL) { Blt_InitHashTable(&colorTable, BLT_ONE_WORD_KEYS); tablePtr = &colorTable; } if (srcPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(srcPtr); } srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { int isNew; Blt_Pixel color; unsigned long key; if ((sp->Red != sp->Green) || (sp->Green != sp->Blue)) { flags |= BLT_PIC_COLOR; } if (sp->Alpha != 0xFF) { #ifdef notdef fprintf(stderr, "Alpha at [%d,%d] = %x\n", sp - srcRowPtr, y, sp->Alpha); #endif if (sp->Alpha == 0x00) { flags |= BLT_PIC_MASK; } else { flags |= BLT_PIC_BLEND; } } color.u32 = sp->u32; color.Alpha = 0xFF; key = (unsigned long)color.u32; Blt_CreateHashEntry(tablePtr, (char *)key, &isNew); } srcRowPtr += srcPtr->pixelsPerRow; } nColors = tablePtr->numEntries; if (tablePtr == &colorTable) { Blt_DeleteHashTable(&colorTable); } srcPtr->flags |= flags; return nColors; } void Blt_ClassifyPicture(Pict *srcPtr) { Blt_Pixel *srcRowPtr; int y; unsigned int flags; int opaque, transparent; flags = 0; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { if ((sp->Red != sp->Green) || (sp->Green != sp->Blue)) { flags |= BLT_PIC_COLOR; goto checkOpacity; } } srcRowPtr += srcPtr->pixelsPerRow; } checkOpacity: srcRowPtr = srcPtr->bits; opaque = transparent = FALSE; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { if (sp->Alpha == 0xFF) { opaque = TRUE; } else if (sp->Alpha == 0x00) { transparent = TRUE; } else { flags |= BLT_PIC_BLEND; goto setFlags; } } if (opaque && transparent) { flags |= BLT_PIC_MASK; goto setFlags; } srcRowPtr += srcPtr->pixelsPerRow; } setFlags: srcPtr->flags |= flags; } void Blt_MaskPicture(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy, Blt_Pixel *colorPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++, dp++) { if (sp->u32 != 0) { dp->u32 = colorPtr->u32; } } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } void Blt_MaskPicture2(Pict *destPtr, Pict *srcPtr, int x, int y, int w, int h, int dx, int dy, Blt_Pixel *colorPtr) { Blt_Pixel *srcRowPtr, *destRowPtr; destRowPtr = destPtr->bits + ((dy * destPtr->pixelsPerRow) + dx); srcRowPtr = srcPtr->bits + ((y * srcPtr->pixelsPerRow) + x); for (y = 0; y < h; y++) { Blt_Pixel *sp, *dp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++, dp++) { if (sp->Alpha == 0xFF) { dp->u32 = colorPtr->u32; } } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += destPtr->pixelsPerRow; } } Blt_Picture Blt_GetPictureFromImage(Tcl_Interp *interp, Tk_Image tkImage, int *isPhotoPtr) { const char *type; Blt_Picture picture; int isPhoto; type = Blt_Image_NameOfType(tkImage); if (strcmp(type, "picture") == 0) { picture = Blt_GetPictureFromPictureImage(interp, tkImage); isPhoto = FALSE; } else if (strcmp(type, "photo") == 0) { picture = Blt_GetPictureFromPhotoImage(interp, tkImage); isPhoto = TRUE; } else { isPhoto = FALSE; if (interp != NULL) { Tcl_AppendResult(interp, "image is not a photo or picture", (char *)NULL); } return NULL; } if (isPhotoPtr != NULL) { *isPhotoPtr = isPhoto; } return picture; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVector.h�������������������������������������������������������������������0000644�0001750�0001750�00000011704�11462120063�015146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVector.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_VECTOR_H #define _BLT_VECTOR_H typedef enum { BLT_VECTOR_NOTIFY_UPDATE = 1, /* The vector's values has been updated */ BLT_VECTOR_NOTIFY_DESTROY /* The vector has been destroyed and the client * should no longer use its data (calling * Blt_FreeVectorId) */ } Blt_VectorNotify; typedef struct _Blt_VectorId *Blt_VectorId; typedef void (Blt_VectorChangedProc)(Tcl_Interp *interp, ClientData clientData, Blt_VectorNotify notify); typedef struct { double *valueArr; /* Array of values (possibly malloc-ed) */ int numValues; /* Number of values in the array */ int arraySize; /* Size of the allocated space */ double min, max; /* Minimum and maximum values in the vector */ int dirty; /* Indicates if the vector has been updated */ int reserved; /* Reserved for future use */ } Blt_Vector; typedef double (Blt_VectorIndexProc)(Blt_Vector * vecPtr); typedef enum { BLT_MATH_FUNC_SCALAR = 1, /* The function returns a single double * precision value. */ BLT_MATH_FUNC_VECTOR /* The function processes the entire vector. */ } Blt_MathFuncType; /* * To be safe, use the macros below, rather than the fields of the * structure directly. * * The Blt_Vector is basically an opaque type. But it's also the * actual memory address of the vector itself. I wanted to make the * API as unobtrusive as possible. So instead of giving you a copy of * the vector, providing various functions to access and update the * vector, you get your hands on the actual memory (array of doubles) * shared by all the vector's clients. * * The trade-off for speed and convenience is safety. You can easily * break things by writing into the vector when other clients are * using it. Use Blt_ResetVector to get around this. At least the * macros are a reminder it isn't really safe to reset the data * fields, except by the API routines. */ #define Blt_VecData(v) ((v)->valueArr) #define Blt_VecLength(v) ((v)->numValues) #define Blt_VecSize(v) ((v)->arraySize) #define Blt_VecDirty(v) ((v)->dirty) BLT_EXTERN double Blt_VecMin(Blt_Vector *vPtr); BLT_EXTERN double Blt_VecMax(Blt_Vector *vPtr); BLT_EXTERN Blt_VectorId Blt_AllocVectorId(Tcl_Interp *interp, const char *vecName); BLT_EXTERN void Blt_SetVectorChangedProc(Blt_VectorId clientId, Blt_VectorChangedProc *proc, ClientData clientData); BLT_EXTERN void Blt_FreeVectorId(Blt_VectorId clientId); BLT_EXTERN int Blt_GetVectorById(Tcl_Interp *interp, Blt_VectorId clientId, Blt_Vector **vecPtrPtr); BLT_EXTERN const char *Blt_NameOfVectorId(Blt_VectorId clientId); BLT_EXTERN const char *Blt_NameOfVector(Blt_Vector *vecPtr); BLT_EXTERN int Blt_VectorNotifyPending(Blt_VectorId clientId); BLT_EXTERN int Blt_CreateVector(Tcl_Interp *interp, const char *vecName, int size, Blt_Vector ** vecPtrPtr); BLT_EXTERN int Blt_CreateVector2(Tcl_Interp *interp, const char *vecName, const char *cmdName, const char *varName, int initialSize, Blt_Vector **vecPtrPtr); BLT_EXTERN int Blt_GetVector(Tcl_Interp *interp, const char *vecName, Blt_Vector **vecPtrPtr); BLT_EXTERN int Blt_GetVectorFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_Vector **vecPtrPtr); BLT_EXTERN int Blt_VectorExists(Tcl_Interp *interp, const char *vecName); BLT_EXTERN int Blt_ResetVector(Blt_Vector *vecPtr, double *dataArr, int n, int arraySize, Tcl_FreeProc *freeProc); BLT_EXTERN int Blt_ResizeVector(Blt_Vector *vecPtr, int n); BLT_EXTERN int Blt_DeleteVectorByName(Tcl_Interp *interp, const char *vecName); BLT_EXTERN int Blt_DeleteVector(Blt_Vector *vecPtr); BLT_EXTERN int Blt_ExprVector(Tcl_Interp *interp, char *expr, Blt_Vector *vecPtr); BLT_EXTERN void Blt_InstallIndexProc(Tcl_Interp *interp, const char *indexName, Blt_VectorIndexProc * procPtr); BLT_EXTERN int Blt_VectorExists2(Tcl_Interp *interp, const char *vecName); #endif /* _BLT_VECTOR_H */ ������������������������������������������������������������./saods9/blt3.0.1/src/bltGrBar.c��������������������������������������������������������������������0000644�0001750�0001750�00000226446�11462120062�014706� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrBar.c -- * * This module implements barchart elements for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include <X11/Xutil.h> #include "bltGrElem.h" #define CLAMP(x,l,h) ((x) = (((x)<(l))? (l) : ((x)>(h)) ? (h) : (x))) typedef struct { float x1, y1, x2, y2; } BarRegion; typedef struct { Point2f ul, lr; Segment2d segments[4]; int nSegments; } Bar; typedef struct { const char *name; /* Pen style identifier. If NULL, pen * was statically allocated. */ ClassId classId; /* Type of pen */ const char *typeId; /* String token identifying the type of * pen */ unsigned int flags; /* Indicates if the pen element is * active or normal */ int refCount; /* Reference count for elements using * this pen. */ Blt_HashEntry *hashPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications */ PenConfigureProc *configProc; PenDestroyProc *destroyProc; Graph *graphPtr; /* Graph that the pen is associated * with. */ /* Barchart specific pen fields start here. */ XColor *outlineColor; /* Outline (foreground) color of bar */ Blt_Background fill; /* 3D border and fill (background) * color */ int borderWidth; /* 3D border width of bar */ int relief; /* Relief of the bar */ Pixmap stipple; /* Stipple */ GC fillGC; /* Graphics context */ GC outlineGC; /* GC for outline of bar. */ /* Error bar attributes. */ int errorBarShow; /* Describes which error bars to * display: none, x, y, or * both. */ int errorBarLineWidth; /* Width of the error bar segments. */ int errorBarCapWidth; XColor *errorBarColor; /* Color of the error bar. */ GC errorBarGC; /* Error bar graphics context. */ /* Show value attributes. */ int valueShow; /* Indicates whether to display data * value. Values are x, y, or none. */ const char *valueFormat; /* A printf format string. */ TextStyle valueStyle; /* Text attributes (color, font, * rotation, etc.) of the value. */ } BarPen; typedef struct { Weight weight; /* Weight range where this pen is * valid. */ BarPen *penPtr; /* Pen to use. */ XRectangle *bars; /* Indicates starting location in bar * array for this pen. */ int nBars; /* # of bar segments for this pen. */ GraphSegments xeb, yeb; /* X and Y error bars. */ int symbolSize; /* Size of the pen's symbol scaled to * the current graph size. */ int errorBarCapWidth; /* Length of the cap ends on each error * bar. */ } BarStyle; typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; Blt_HashEntry *hashPtr; /* Fields specific to elements. */ const char *label; /* Label displayed in legend */ unsigned short row, col; /* Position of the entry in the * legend. */ int legendRelief; /* Relief of label in legend. */ Axis2d axes; /* X-axis and Y-axis mapping the * element */ ElemValues x, y, w; /* Contains array of floating point * graph coordinate values. Also holds * min/max and the number of * coordinates */ int *activeIndices; /* Array of indices (malloc-ed) which * indicate which data points are active * (drawn * with "active" colors). */ int nActiveIndices; /* Number of active data points. * Special case: if nActiveIndices < 0 * and the active bit is set in "flags", * then all data * points are drawn * active. */ ElementProcs *procsPtr; Blt_ConfigSpec *configSpecs; /* Configuration specifications. */ BarPen *activePenPtr; /* Standard Pens */ BarPen *normalPenPtr; BarPen *builtinPenPtr; Blt_Chain stylePalette; /* Palette of pens. */ /* Symbol scaling */ int scaleSymbols; /* If non-zero, the symbols will scale * in size as the graph is zoomed * in/out. */ double xRange, yRange; /* Initial X-axis and Y-axis ranges: * used to scale the size of element's * symbol. */ int state; Blt_ChainLink link; /* Fields specific to the barchart element */ float barWidth; const char *groupName; int *barToData; XRectangle *bars; /* Array of rectangles comprising the bar * segments of the element. */ int *activeToData; XRectangle *activeRects; int nBars; /* # of visible bar segments for * element */ int nActive; int xPad; /* Spacing on either side of bar */ ElemValues xError; /* Relative/symmetric X error values. */ ElemValues yError; /* Relative/symmetric Y error values. */ ElemValues xHigh, xLow; /* Absolute/asymmetric X-coordinate * high/low error values. */ ElemValues yHigh, yLow; /* Absolute/asymmetric Y-coordinate * high/low error values. */ BarPen builtinPen; GraphSegments xeb, yeb; int errorBarCapWidth; /* Length of cap on error bars */ } BarElement; BLT_EXTERN Blt_CustomOption bltBarPenOption; BLT_EXTERN Blt_CustomOption bltValuesOption; BLT_EXTERN Blt_CustomOption bltValuePairsOption; BLT_EXTERN Blt_CustomOption bltXAxisOption; BLT_EXTERN Blt_CustomOption bltYAxisOption; BLT_EXTERN Blt_CustomOption bltColorOption; BLT_EXTERN Blt_CustomOption bltBarStylesOption; static Blt_OptionParseProc ObjToBarMode; static Blt_OptionPrintProc BarModeToObj; Blt_CustomOption bltBarModeOption = { ObjToBarMode, BarModeToObj, NULL, (ClientData)0 }; #define DEF_BAR_ACTIVE_PEN "activeBar" #define DEF_BAR_AXIS_X "x" #define DEF_BAR_AXIS_Y "y" #define DEF_BAR_BACKGROUND "navyblue" #define DEF_BAR_BORDERWIDTH "2" #define DEF_BAR_ERRORBAR_COLOR "defcolor" #define DEF_BAR_ERRORBAR_LINE_WIDTH "1" #define DEF_BAR_ERRORBAR_CAP_WIDTH "1" #define DEF_BAR_FOREGROUND "blue" #define DEF_BAR_HIDE "no" #define DEF_BAR_LABEL_RELIEF "flat" #define DEF_BAR_NORMAL_STIPPLE "" #define DEF_BAR_RELIEF "raised" #define DEF_BAR_SHOW_ERRORBARS "both" #define DEF_BAR_STATE "normal" #define DEF_BAR_STACK (char *)NULL #define DEF_BAR_STYLES "" #define DEF_BAR_TAGS "all" #define DEF_BAR_WIDTH "0.0" #define DEF_PEN_ACTIVE_BACKGROUND "red" #define DEF_PEN_ACTIVE_FOREGROUND "pink" #define DEF_PEN_BORDERWIDTH "2" #define DEF_PEN_NORMAL_BACKGROUND "navyblue" #define DEF_PEN_NORMAL_FOREGROUND "blue" #define DEF_PEN_RELIEF "raised" #define DEF_PEN_STIPPLE "" #define DEF_PEN_TYPE "bar" #define DEF_PEN_VALUE_ANCHOR "s" #define DEF_PEN_VALUE_COLOR RGB_BLACK #define DEF_PEN_VALUE_FONT STD_FONT_SMALL #define DEF_PEN_VALUE_FORMAT "%g" #define DEF_PEN_SHOW_VALUES "no" static Blt_ConfigSpec barPenConfigSpecs[] = { {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_PEN_ACTIVE_BACKGROUND, Blt_Offset(BarPen, fill), BLT_CONFIG_NULL_OK | ACTIVE_PEN}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_PEN_NORMAL_BACKGROUND, Blt_Offset(BarPen, fill), BLT_CONFIG_NULL_OK | NORMAL_PEN}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_PEN_BORDERWIDTH, Blt_Offset(BarPen, borderWidth), ALL_PENS}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_BAR_ERRORBAR_COLOR, Blt_Offset(BarPen, errorBarColor), ALL_PENS, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarwidth", "errorBarWidth","ErrorBarWidth", DEF_BAR_ERRORBAR_LINE_WIDTH, Blt_Offset(BarPen, errorBarLineWidth), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_BAR_ERRORBAR_CAP_WIDTH, Blt_Offset(BarPen, errorBarCapWidth), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_PEN_ACTIVE_FOREGROUND, Blt_Offset(BarPen, outlineColor), ACTIVE_PEN | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_PEN_NORMAL_FOREGROUND, Blt_Offset(BarPen, outlineColor), NORMAL_PEN | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 0, ALL_PENS}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_PEN_RELIEF, Blt_Offset(BarPen, relief), ALL_PENS}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_BAR_SHOW_ERRORBARS, Blt_Offset(BarPen, errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(BarPen, valueShow), ALL_PENS | BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_PEN_STIPPLE, Blt_Offset(BarPen, stipple), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-type", (char *)NULL, (char *)NULL, DEF_PEN_TYPE, Blt_Offset(BarPen, typeId), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(BarPen, valueStyle.anchor), ALL_PENS}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(BarPen, valueStyle.color), ALL_PENS}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(BarPen, valueStyle.font), ALL_PENS}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(BarPen, valueFormat), ALL_PENS | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", (char *)NULL, Blt_Offset(BarPen, valueStyle.angle), ALL_PENS}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Blt_ConfigSpec barElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", DEF_BAR_ACTIVE_PEN, Blt_Offset(BarElement, activePenPtr), BLT_CONFIG_NULL_OK, &bltBarPenOption}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BAR_BACKGROUND, Blt_Offset(BarElement, builtinPen.fill), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-barwidth", "barWidth", "BarWidth", DEF_BAR_WIDTH, Blt_Offset(BarElement, barWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_BAR_TAGS, Blt_Offset(BarElement, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BAR_BORDERWIDTH, Blt_Offset(BarElement, builtinPen.borderWidth), 0}, {BLT_CONFIG_SYNONYM, "-color", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-errorbarcolor", "errorBarColor", "ErrorBarColor", DEF_BAR_ERRORBAR_COLOR, Blt_Offset(BarElement, builtinPen.errorBarColor), 0, &bltColorOption}, {BLT_CONFIG_PIXELS_NNEG,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth", DEF_BAR_ERRORBAR_LINE_WIDTH, Blt_Offset(BarElement, builtinPen.errorBarLineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-errorbarcap", "errorBarCap", "ErrorBarCap", DEF_BAR_ERRORBAR_CAP_WIDTH, Blt_Offset(BarElement, builtinPen.errorBarCapWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-data", "data", "Data", (char *)NULL, 0, 0, &bltValuePairsOption}, {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_BAR_FOREGROUND, Blt_Offset(BarElement, builtinPen.outlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-label", "label", "Label", (char *)NULL, Blt_Offset(BarElement, label), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-legendrelief", "legendRelief", "LegendRelief", DEF_BAR_LABEL_RELIEF, Blt_Offset(BarElement, legendRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_BAR_HIDE, Blt_Offset(BarElement, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_BAR_AXIS_X, Blt_Offset(BarElement, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_BAR_AXIS_Y, Blt_Offset(BarElement, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-pen", "pen", "Pen", (char *)NULL, Blt_Offset(BarElement, normalPenPtr), BLT_CONFIG_NULL_OK, &bltBarPenOption}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_BAR_RELIEF, Blt_Offset(BarElement, builtinPen.relief), 0}, {BLT_CONFIG_FILL, "-showerrorbars", "showErrorBars", "ShowErrorBars", DEF_BAR_SHOW_ERRORBARS, Blt_Offset(BarElement, builtinPen.errorBarShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FILL, "-showvalues", "showValues", "ShowValues", DEF_PEN_SHOW_VALUES, Blt_Offset(BarElement, builtinPen.valueShow), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-stack", "stack", "Stack", DEF_BAR_STACK, Blt_Offset(BarElement, groupName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_BAR_STATE, Blt_Offset(BarElement, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_BAR_NORMAL_STIPPLE, Blt_Offset(BarElement, builtinPen.stipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-styles", "styles", "Styles", DEF_BAR_STYLES, Blt_Offset(BarElement, stylePalette), 0, &bltBarStylesOption}, {BLT_CONFIG_ANCHOR, "-valueanchor", "valueAnchor", "ValueAnchor", DEF_PEN_VALUE_ANCHOR, Blt_Offset(BarElement, builtinPen.valueStyle.anchor), 0}, {BLT_CONFIG_COLOR, "-valuecolor", "valueColor", "ValueColor", DEF_PEN_VALUE_COLOR, Blt_Offset(BarElement, builtinPen.valueStyle.color), 0}, {BLT_CONFIG_FONT, "-valuefont", "valueFont", "ValueFont", DEF_PEN_VALUE_FONT, Blt_Offset(BarElement, builtinPen.valueStyle.font), 0}, {BLT_CONFIG_STRING, "-valueformat", "valueFormat", "ValueFormat", DEF_PEN_VALUE_FORMAT, Blt_Offset(BarElement, builtinPen.valueFormat), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FLOAT, "-valuerotate", "valueRotate", "ValueRotate", (char *)NULL, Blt_Offset(BarElement, builtinPen.valueStyle.angle), 0}, {BLT_CONFIG_CUSTOM, "-weights", "weights", "Weights", (char *)NULL, Blt_Offset(BarElement, w), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-x", "xdata", "Xdata", (char *)NULL, Blt_Offset(BarElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-y", "ydata", "Ydata", (char *)NULL, Blt_Offset(BarElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xdata", "xdata", "Xdata", (char *)NULL, Blt_Offset(BarElement, x), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ydata", "ydata", "Ydata", (char *)NULL, Blt_Offset(BarElement, y), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xerror", "xError", "XError", (char *)NULL, Blt_Offset(BarElement, xError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xhigh", "xHigh", "XHigh", (char *)NULL, Blt_Offset(BarElement, xHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-xlow", "xLow", "XLow", (char *)NULL, Blt_Offset(BarElement, xLow), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yerror", "yError", "YError", (char *)NULL, Blt_Offset(BarElement, yError), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-yhigh", "yHigh", "YHigh", (char *)NULL, Blt_Offset(BarElement, yHigh), 0, &bltValuesOption}, {BLT_CONFIG_CUSTOM, "-ylow", "yLow", "YLow", (char *)NULL, Blt_Offset(BarElement, yLow), 0, &bltValuesOption}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* Forward declarations */ static PenConfigureProc ConfigureBarPenProc; static PenDestroyProc DestroyBarPenProc; static ElementClosestProc ClosestBarProc; static ElementConfigProc ConfigureBarProc; static ElementDestroyProc DestroyBarProc; static ElementDrawProc DrawActiveBarProc; static ElementDrawProc DrawNormalBarProc; static ElementDrawSymbolProc DrawSymbolProc; static ElementExtentsProc GetBarExtentsProc; static ElementToPostScriptProc ActiveBarToPostScriptProc; static ElementToPostScriptProc NormalBarToPostScriptProc; static ElementSymbolToPostScriptProc SymbolToPostScriptProc; static ElementMapProc MapBarProc; INLINE static int Round(double x) { return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); } /* *--------------------------------------------------------------------------- * Custom option parse and print procedures *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * NameOfBarMode -- * * Converts the integer representing the mode style into a string. * *--------------------------------------------------------------------------- */ static const char * NameOfBarMode(BarMode mode) { switch (mode) { case BARS_INFRONT: return "infront"; case BARS_OVERLAP: return "overlap"; case BARS_STACKED: return "stacked"; case BARS_ALIGNED: return "aligned"; default: return "unknown mode value"; } } /* *--------------------------------------------------------------------------- * * ObjToMode -- * * Converts the mode string into its numeric representation. * * Valid mode strings are: * * "infront" Draw a full bar at each point in the element. * * "stacked" Stack bar segments vertically. Each stack is defined * by each ordinate at a particular abscissa. The height * of each segment is represented by the sum the previous * ordinates. * * "aligned" Align bar segments as smaller slices one next to * the other. Like "stacks", aligned segments are * defined by each ordinate at a particular abscissa. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToBarMode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Mode style string */ char *widgRec, /* Cubicle structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { BarMode *modePtr = (BarMode *)(widgRec + offset); int length; char c; char *string; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; if ((c == 'n') && (strncmp(string, "normal", length) == 0)) { *modePtr = BARS_INFRONT; } else if ((c == 'i') && (strncmp(string, "infront", length) == 0)) { *modePtr = BARS_INFRONT; } else if ((c == 's') && (strncmp(string, "stacked", length) == 0)) { *modePtr = BARS_STACKED; } else if ((c == 'a') && (strncmp(string, "aligned", length) == 0)) { *modePtr = BARS_ALIGNED; } else if ((c == 'o') && (strncmp(string, "overlap", length) == 0)) { *modePtr = BARS_OVERLAP; } else { Tcl_AppendResult(interp, "bad mode argument \"", string, "\": should" "be \"infront\", \"stacked\", \"overlap\", or \"aligned\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BarModeToObj -- * * Returns the mode style string based upon the mode flags. * * Results: * The mode style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * BarModeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Not used. */ Tk_Window tkwin, /* Not used. */ char *widgRec, /* Row/column structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { BarMode mode = *(BarMode *)(widgRec + offset); return Tcl_NewStringObj(NameOfBarMode(mode), -1); } /* * Zero out the style's number of bars and errorbars. */ static void ResetStylePalette(Blt_Chain stylePalette) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); stylePtr->xeb.length = stylePtr->yeb.length = 0; stylePtr->nBars = 0; } } static int ConfigureBarPen(Graph *graphPtr, BarPen *penPtr) { XGCValues gcValues; unsigned long gcMask; GC newGC; long defColor; int screenNum; screenNum = Tk_ScreenNumber(graphPtr->tkwin); gcMask = GCForeground | GCLineWidth; gcValues.line_width = LineWidth(penPtr->errorBarLineWidth); if (penPtr->outlineColor != NULL) { defColor = penPtr->outlineColor->pixel; gcValues.foreground = penPtr->outlineColor->pixel; } else if (penPtr->fill != NULL) { defColor = Blt_BackgroundBorderColor(penPtr->fill)->pixel; gcValues.foreground = defColor; } else { defColor = BlackPixel(graphPtr->display, screenNum); } newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (penPtr->outlineGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->outlineGC); } penPtr->outlineGC = newGC; newGC = NULL; if (penPtr->stipple != None) { /* Handle old-style -stipple specially. */ gcMask = GCForeground | GCBackground | GCFillStyle | GCStipple; gcValues.foreground = BlackPixel(graphPtr->display, screenNum); gcValues.background = WhitePixel(graphPtr->display, screenNum); if (penPtr->fill != NULL) { gcValues.foreground = Blt_BackgroundBorderColor(penPtr->fill)->pixel; } else if (penPtr->outlineColor != NULL) { gcValues.foreground = penPtr->outlineColor->pixel; } gcValues.stipple = penPtr->stipple; gcValues.fill_style = FillStippled; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); } if (penPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->fillGC); } penPtr->fillGC = newGC; gcMask = GCForeground | GCLineWidth; if (penPtr->errorBarColor == COLOR_DEFAULT) { gcValues.foreground = defColor; } else { gcValues.foreground = penPtr->errorBarColor->pixel; } gcValues.line_width = LineWidth(penPtr->errorBarLineWidth); newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (penPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->errorBarGC); } penPtr->errorBarGC = newGC; return TCL_OK; } static void DestroyBarPen(Graph *graphPtr, BarPen *penPtr) { Blt_Ts_FreeStyle(graphPtr->display, &penPtr->valueStyle); if (penPtr->outlineGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->outlineGC); } if (penPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->fillGC); } if (penPtr->errorBarGC != NULL) { Tk_FreeGC(graphPtr->display, penPtr->errorBarGC); } } static int ConfigureBarPenProc(Graph *graphPtr, Pen *basePtr) { return ConfigureBarPen(graphPtr, (BarPen *)basePtr); } static void DestroyBarPenProc(Graph *graphPtr, Pen *basePtr) { DestroyBarPen(graphPtr, (BarPen *)basePtr); } static void InitializeBarPen(BarPen *penPtr) { /* Generic fields common to all pen types. */ penPtr->configProc = ConfigureBarPenProc; penPtr->destroyProc = DestroyBarPenProc; penPtr->flags = NORMAL_PEN; penPtr->configSpecs = barPenConfigSpecs; /* Initialize fields specific to bar pens. */ Blt_Ts_InitStyle(penPtr->valueStyle); penPtr->relief = TK_RELIEF_RAISED; penPtr->valueShow = SHOW_NONE; penPtr->borderWidth = 2; penPtr->errorBarShow = SHOW_BOTH; } Pen * Blt_BarPen(const char *penName) { BarPen *penPtr; penPtr = Blt_AssertCalloc(1, sizeof(BarPen)); InitializeBarPen(penPtr); penPtr->name = Blt_AssertStrdup(penName); if (strcmp(penName, "activeBar") == 0) { penPtr->flags = ACTIVE_PEN; } return (Pen *)penPtr; } /* *--------------------------------------------------------------------------- * * CheckBarStacks -- * * Check that the data limits are not superseded by the heights of * stacked bar segments. The heights are calculated by * Blt_ComputeStacks. * * Results: * If the y-axis limits need to be adjusted for stacked segments, * *minPtr* or *maxPtr* are updated. * * Side effects: * Autoscaling of the y-axis is affected. * *--------------------------------------------------------------------------- */ static void CheckBarStacks(Graph *graphPtr, Axis2d *pairPtr, double *minPtr, double *maxPtr) { BarGroup *gp, *gend; if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0)) { return; } for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend; gp++) { if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) { /* * Check if any of the y-values (because of stacking) are greater * than the current limits of the graph. */ if (gp->sum < 0.0f) { if (*minPtr > gp->sum) { *minPtr = gp->sum; } } else { if (*maxPtr < gp->sum) { *maxPtr = gp->sum; } } } } } /* *--------------------------------------------------------------------------- * * ConfigureBarProc -- * * Sets up the appropriate configuration parameters in the GC. It is * assumed the parameters have been previously set by a call to * Blt_ConfigureWidget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information such as bar foreground/background color and * stipple etc. get set in a new GC. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureBarProc(Graph *graphPtr, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; Blt_ChainLink link; BarStyle *stylePtr; if (ConfigureBarPen(graphPtr, elemPtr->builtinPenPtr)!= TCL_OK) { return TCL_ERROR; } /* * Point to the static normal pen if no external pens have been selected. */ link = Blt_Chain_FirstLink(elemPtr->stylePalette); if (link == NULL) { link = Blt_Chain_AllocLink(sizeof(BarStyle)); Blt_Chain_LinkAfter(elemPtr->stylePalette, link, NULL); } stylePtr = Blt_Chain_GetValue(link); stylePtr->penPtr = NORMALPEN(elemPtr); if (Blt_ConfigModified(elemPtr->configSpecs, "-barwidth", "-*data", "-map*", "-label", "-hide", "-x", "-y", (char *)NULL)) { elemPtr->flags |= MAP_ITEM; } return TCL_OK; } static void GetBarExtentsProc(Element *basePtr, Region2d *regPtr) { BarElement *elemPtr = (BarElement *)basePtr; Graph *graphPtr; double middle, barWidth; int nPoints; graphPtr = elemPtr->obj.graphPtr; regPtr->top = regPtr->left = DBL_MAX; regPtr->bottom = regPtr->right = -DBL_MAX; nPoints = NUMBEROFPOINTS(elemPtr); if (nPoints < 1) { return; /* No data points */ } barWidth = graphPtr->barWidth; if (elemPtr->barWidth > 0.0f) { barWidth = elemPtr->barWidth; } middle = 0.5; regPtr->left = elemPtr->x.min - middle; regPtr->right = elemPtr->x.max + middle; regPtr->top = elemPtr->y.min; regPtr->bottom = elemPtr->y.max; if (regPtr->bottom < graphPtr->baseline) { regPtr->bottom = graphPtr->baseline; } /* * Handle stacked bar elements specially. * * If element is stacked, the sum of its ordinates may be outside the * minimum/maximum limits of the element's data points. */ if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) { CheckBarStacks(graphPtr, &elemPtr->axes, &regPtr->top, &regPtr->bottom); } /* Warning: You get what you deserve if the x-axis is logScale */ if (elemPtr->axes.x->logScale) { regPtr->left = Blt_FindElemValuesMinimum(&elemPtr->x, DBL_MIN) + middle; } /* Fix y-min limits for barchart */ if (elemPtr->axes.y->logScale) { if ((regPtr->top <= 0.0) || (regPtr->top > 1.0)) { regPtr->top = 1.0; } } else { if (regPtr->top > 0.0) { regPtr->top = 0.0; } } /* Correct the extents for error bars if they exist. */ if (elemPtr->xError.nValues > 0) { int i; /* Correct the data limits for error bars */ nPoints = MIN(elemPtr->xError.nValues, nPoints); for (i = 0; i < nPoints; i++) { double x; x = elemPtr->x.values[i] + elemPtr->xError.values[i]; if (x > regPtr->right) { regPtr->right = x; } x = elemPtr->x.values[i] - elemPtr->xError.values[i]; if (elemPtr->axes.x->logScale) { if (x < 0.0) { x = -x; /* Mirror negative values, instead of * ignoring them. */ } if ((x > DBL_MIN) && (x < regPtr->left)) { regPtr->left = x; } } else if (x < regPtr->left) { regPtr->left = x; } } } else { if ((elemPtr->xHigh.nValues > 0) && (elemPtr->xHigh.max > regPtr->right)) { regPtr->right = elemPtr->xHigh.max; } if (elemPtr->xLow.nValues > 0) { double left; if ((elemPtr->xLow.min <= 0.0) && (elemPtr->axes.x->logScale)) { left = Blt_FindElemValuesMinimum(&elemPtr->xLow, DBL_MIN); } else { left = elemPtr->xLow.min; } if (left < regPtr->left) { regPtr->left = left; } } } if (elemPtr->yError.nValues > 0) { int i; nPoints = MIN(elemPtr->yError.nValues, nPoints); for (i = 0; i < nPoints; i++) { double y; y = elemPtr->y.values[i] + elemPtr->yError.values[i]; if (y > regPtr->bottom) { regPtr->bottom = y; } y = elemPtr->y.values[i] - elemPtr->yError.values[i]; if (elemPtr->axes.y->logScale) { if (y < 0.0) { y = -y; /* Mirror negative values, instead of * ignoring them. */ } if ((y > DBL_MIN) && (y < regPtr->left)) { regPtr->top = y; } } else if (y < regPtr->top) { regPtr->top = y; } } } else { if ((elemPtr->yHigh.nValues > 0) && (elemPtr->yHigh.max > regPtr->bottom)) { regPtr->bottom = elemPtr->yHigh.max; } if (elemPtr->yLow.nValues > 0) { double top; if ((elemPtr->yLow.min <= 0.0) && (elemPtr->axes.y->logScale)) { top = Blt_FindElemValuesMinimum(&elemPtr->yLow, DBL_MIN); } else { top = elemPtr->yLow.min; } if (top < regPtr->top) { regPtr->top = top; } } } } /* *--------------------------------------------------------------------------- * * ClosestBar -- * * Find the bar segment closest to the window coordinates point * specified. * * Note: This does not return the height of the stacked segment * (in graph coordinates) properly. * * Results: * Returns 1 if the point is width any bar segment, otherwise 0. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void ClosestBarProc( Graph *graphPtr, /* Not used. */ Element *basePtr, /* Bar element */ ClosestSearch *searchPtr) /* Information about closest point in * element */ { BarElement *elemPtr = (BarElement *)basePtr; XRectangle *bp; double minDist; int imin; int i; minDist = searchPtr->dist; imin = 0; for (bp = elemPtr->bars, i = 0; i < elemPtr->nBars; i++, bp++) { Point2d *pp, *pend; Point2d outline[5]; double left, right, top, bottom; if (PointInRectangle(bp, searchPtr->x, searchPtr->y)) { imin = elemPtr->barToData[i]; minDist = 0.0; break; } left = bp->x, top = bp->y; right = (double)(bp->x + bp->width); bottom = (double)(bp->y + bp->height); outline[4].x = outline[3].x = outline[0].x = left; outline[4].y = outline[1].y = outline[0].y = top; outline[2].x = outline[1].x = right; outline[3].y = outline[2].y = bottom; for (pp = outline, pend = outline + 4; pp < pend; pp++) { Point2d t; double dist; t = Blt_GetProjection(searchPtr->x, searchPtr->y, pp, pp + 1); if (t.x > right) { t.x = right; } else if (t.x < left) { t.x = left; } if (t.y > bottom) { t.y = bottom; } else if (t.y < top) { t.y = top; } dist = hypot((t.x - searchPtr->x), (t.y - searchPtr->y)); if (dist < minDist) { minDist = dist; imin = elemPtr->barToData[i]; } } } if (minDist < searchPtr->dist) { searchPtr->elemPtr = (Element *)elemPtr; searchPtr->dist = minDist; searchPtr->index = imin; searchPtr->point.x = (double)elemPtr->x.values[imin]; searchPtr->point.y = (double)elemPtr->y.values[imin]; } } /* *--------------------------------------------------------------------------- * * MergePens -- * * Reorders the both arrays of points and errorbars to merge pens. * * Results: * None. * * Side effects: * The old arrays are freed and new ones allocated containing * the reordered points and errorbars. * *--------------------------------------------------------------------------- */ static void MergePens(BarElement *elemPtr, BarStyle **dataToStyle) { if (Blt_Chain_GetLength(elemPtr->stylePalette) < 2) { Blt_ChainLink link; BarStyle *stylePtr; link = Blt_Chain_FirstLink(elemPtr->stylePalette); stylePtr = Blt_Chain_GetValue(link); stylePtr->nBars = elemPtr->nBars; stylePtr->bars = elemPtr->bars; stylePtr->symbolSize = elemPtr->bars->width / 2; stylePtr->xeb.length = elemPtr->xeb.length; stylePtr->xeb.segments = elemPtr->xeb.segments; stylePtr->yeb.length = elemPtr->yeb.length; stylePtr->yeb.segments = elemPtr->yeb.segments; return; } /* We have more than one style. Group bar segments of like pen styles * together. */ if (elemPtr->nBars > 0) { Blt_ChainLink link; XRectangle *bars, *bp; int *ip, *barToData; bars = Blt_AssertMalloc(elemPtr->nBars * sizeof(XRectangle)); barToData = Blt_AssertMalloc(elemPtr->nBars * sizeof(int)); bp = bars, ip = barToData; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->symbolSize = bp->width / 2; stylePtr->bars = bp; for (i = 0; i < elemPtr->nBars; i++) { int iData; iData = elemPtr->barToData[i]; if (dataToStyle[iData] == stylePtr) { *bp++ = elemPtr->bars[i]; *ip++ = iData; } } stylePtr->nBars = bp - stylePtr->bars; } Blt_Free(elemPtr->bars); Blt_Free(elemPtr->barToData); elemPtr->bars = bars; elemPtr->barToData = barToData; } if (elemPtr->xeb.length > 0) { Blt_ChainLink link; Segment2d *bars, *sp; int *map, *ip; bars = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->xeb.length * sizeof(int)); sp = bars, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->xeb.segments = sp; for (i = 0; i < elemPtr->xeb.length; i++) { int iData; iData = elemPtr->xeb.map[i]; if (dataToStyle[iData] == stylePtr) { *sp++ = elemPtr->xeb.segments[i]; *ip++ = iData; } } stylePtr->xeb.length = sp - stylePtr->xeb.segments; } Blt_Free(elemPtr->xeb.segments); elemPtr->xeb.segments = bars; Blt_Free(elemPtr->xeb.map); elemPtr->xeb.map = map; } if (elemPtr->yeb.length > 0) { Blt_ChainLink link; Segment2d *bars, *sp; int *map, *ip; bars = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(Segment2d)); map = Blt_AssertMalloc(elemPtr->yeb.length * sizeof(int)); sp = bars, ip = map; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; int i; stylePtr = Blt_Chain_GetValue(link); stylePtr->yeb.segments = sp; for (i = 0; i < elemPtr->yeb.length; i++) { int iData; iData = elemPtr->yeb.map[i]; if (dataToStyle[iData] == stylePtr) { *sp++ = elemPtr->yeb.segments[i]; *ip++ = iData; } } stylePtr->yeb.length = sp - stylePtr->yeb.segments; } Blt_Free(elemPtr->yeb.segments); elemPtr->yeb.segments = bars; Blt_Free(elemPtr->yeb.map); elemPtr->yeb.map = map; } } /* *--------------------------------------------------------------------------- * * MapActiveBars -- * * Creates an array of points of the active graph coordinates. * * Results: * None. * * Side effects: * Memory is freed and allocated for the active point array. * *--------------------------------------------------------------------------- */ static void MapActiveBars(BarElement *elemPtr) { if (elemPtr->activeRects != NULL) { Blt_Free(elemPtr->activeRects); elemPtr->activeRects = NULL; } if (elemPtr->activeToData != NULL) { Blt_Free(elemPtr->activeToData); elemPtr->activeToData = NULL; } elemPtr->nActive = 0; if (elemPtr->nActiveIndices > 0) { XRectangle *activeRects; int *activeToData; int i; int count; activeRects = Blt_AssertMalloc(sizeof(XRectangle) * elemPtr->nActiveIndices); activeToData = Blt_AssertMalloc(sizeof(int) * elemPtr->nActiveIndices); count = 0; for (i = 0; i < elemPtr->nBars; i++) { int *ip, *iend; for (ip = elemPtr->activeIndices, iend = ip + elemPtr->nActiveIndices; ip < iend; ip++) { if (elemPtr->barToData[i] == *ip) { activeRects[count] = elemPtr->bars[i]; activeToData[count] = i; count++; } } } elemPtr->nActive = count; elemPtr->activeRects = activeRects; elemPtr->activeToData = activeToData; } elemPtr->flags &= ~ACTIVE_PENDING; } static void ResetBar(BarElement *elemPtr) { /* Release any storage associated with the display of the bar */ ResetStylePalette(elemPtr->stylePalette); if (elemPtr->activeRects != NULL) { Blt_Free(elemPtr->activeRects); } if (elemPtr->activeToData != NULL) { Blt_Free(elemPtr->activeToData); } if (elemPtr->xeb.segments != NULL) { Blt_Free(elemPtr->xeb.segments); } if (elemPtr->xeb.map != NULL) { Blt_Free(elemPtr->xeb.map); } if (elemPtr->yeb.segments != NULL) { Blt_Free(elemPtr->yeb.segments); } if (elemPtr->yeb.map != NULL) { Blt_Free(elemPtr->yeb.map); } if (elemPtr->bars != NULL) { Blt_Free(elemPtr->bars); } if (elemPtr->barToData != NULL) { Blt_Free(elemPtr->barToData); } elemPtr->activeToData = elemPtr->xeb.map = elemPtr->yeb.map = elemPtr->barToData = NULL; elemPtr->activeRects = elemPtr->bars = NULL; elemPtr->xeb.segments = elemPtr->yeb.segments = NULL; elemPtr->nActive = elemPtr->xeb.length = elemPtr->yeb.length = elemPtr->nBars = 0; } /* *--------------------------------------------------------------------------- * * Blt_MapErrorBars -- * * Creates two arrays of points and pen indices, filled with the screen * coordinates of the visible * * Results: * None. * * Side effects: * Memory is freed and allocated for the index array. * *--------------------------------------------------------------------------- */ static void MapErrorBars(Graph *graphPtr, BarElement *elemPtr, BarStyle **dataToStyle) { int n, nPoints; Region2d reg; Blt_GraphExtents(graphPtr, &reg); nPoints = NUMBEROFPOINTS(elemPtr); if (elemPtr->xError.nValues > 0) { n = MIN(elemPtr->xError.nValues, nPoints); } else { n = MIN3(elemPtr->xHigh.nValues, elemPtr->xLow.nValues, nPoints); } if (n > 0) { Segment2d *bars; Segment2d *segPtr; int *map; int *indexPtr; int i; segPtr = bars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = map = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; BarStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = dataToStyle[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->xError.nValues > 0) { high = x + elemPtr->xError.values[i]; low = x - elemPtr->xError.values[i]; } else { high = elemPtr->xHigh.values[i]; low = elemPtr->xLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, high, y, &elemPtr->axes); q = Blt_Map2D(graphPtr, low, y, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Left cap */ segPtr->p.x = segPtr->q.x = p.x; segPtr->p.y = p.y - stylePtr->errorBarCapWidth; segPtr->q.y = p.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Right cap */ segPtr->p.x = segPtr->q.x = q.x; segPtr->p.y = q.y - stylePtr->errorBarCapWidth; segPtr->q.y = q.y + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->xeb.segments = bars; elemPtr->xeb.length = segPtr - bars; elemPtr->xeb.map = map; } if (elemPtr->yError.nValues > 0) { n = MIN(elemPtr->yError.nValues, nPoints); } else { n = MIN3(elemPtr->yHigh.nValues, elemPtr->yLow.nValues, nPoints); } if (n > 0) { Segment2d *bars; Segment2d *segPtr; int *map; int *indexPtr; int i; segPtr = bars = Blt_AssertMalloc(n * 3 * sizeof(Segment2d)); indexPtr = map = Blt_AssertMalloc(n * 3 * sizeof(int)); for (i = 0; i < n; i++) { double x, y; double high, low; BarStyle *stylePtr; x = elemPtr->x.values[i]; y = elemPtr->y.values[i]; stylePtr = dataToStyle[i]; if ((FINITE(x)) && (FINITE(y))) { if (elemPtr->yError.nValues > 0) { high = y + elemPtr->yError.values[i]; low = y - elemPtr->yError.values[i]; } else { high = elemPtr->yHigh.values[i]; low = elemPtr->yLow.values[i]; } if ((FINITE(high)) && (FINITE(low))) { Point2d p, q; p = Blt_Map2D(graphPtr, x, high, &elemPtr->axes); q = Blt_Map2D(graphPtr, x, low, &elemPtr->axes); segPtr->p = p; segPtr->q = q; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Top cap. */ segPtr->p.y = segPtr->q.y = p.y; segPtr->p.x = p.x - stylePtr->errorBarCapWidth; segPtr->q.x = p.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } /* Bottom cap. */ segPtr->p.y = segPtr->q.y = q.y; segPtr->p.x = q.x - stylePtr->errorBarCapWidth; segPtr->q.x = q.x + stylePtr->errorBarCapWidth; if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) { segPtr++; *indexPtr++ = i; } } } } elemPtr->yeb.segments = bars; elemPtr->yeb.length = segPtr - bars; elemPtr->yeb.map = map; } } /* *--------------------------------------------------------------------------- * * MapBarProc -- * * Calculates the actual window coordinates of the bar element. The * window coordinates are saved in the bar element structure. * * Results: * None. * * Notes: * A bar can have multiple segments (more than one x,y pairs). In this * case, the bar can be represented as either a set of non-contiguous * bars or a single multi-segmented (stacked) bar. * * The x-axis layout for a barchart may be presented in one of two ways. * If abscissas are used, the bars are placed at those coordinates. * Otherwise, the range will represent the number of values. * *--------------------------------------------------------------------------- */ static void MapBarProc(Graph *graphPtr, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; BarStyle **dataToStyle; double *x, *y; double barWidth, barOffset; double baseline, ybot; int *barToData; /* Maps bars to data point indices */ int invertBar; int nPoints, count; XRectangle *rp, *bars; int i; int size; ResetBar(elemPtr); nPoints = NUMBEROFPOINTS(elemPtr); if (nPoints < 1) { return; /* No data points */ } barWidth = graphPtr->barWidth; barWidth = (elemPtr->barWidth > 0.0f) ? elemPtr->barWidth : graphPtr->barWidth; baseline = (elemPtr->axes.y->logScale) ? 0.0 : graphPtr->baseline; barOffset = barWidth * 0.5; /* * Create an array of bars representing the screen coordinates of all the * segments in the bar. */ bars = Blt_AssertCalloc(nPoints, sizeof(XRectangle)); barToData = Blt_AssertCalloc(nPoints, sizeof(int)); x = elemPtr->x.values, y = elemPtr->y.values; count = 0; for (rp = bars, i = 0; i < nPoints; i++) { Point2d c1, c2; /* Two opposite corners of the rectangle * in graph coordinates. */ double dx, dy; int height; double right, left, top, bottom; if (((x[i] - barWidth) > elemPtr->axes.x->axisRange.max) || ((x[i] + barWidth) < elemPtr->axes.x->axisRange.min)) { continue; /* Abscissa is out of range of the * x-axis */ } c1.x = x[i] - barOffset; c1.y = y[i]; c2.x = c1.x + barWidth; c2.y = baseline; /* * If the mode is "aligned" or "stacked" we need to adjust the x or y * coordinates of the two corners. */ if ((graphPtr->nBarGroups > 0) && (graphPtr->mode != BARS_INFRONT) && (!graphPtr->stackAxes)) { Blt_HashEntry *hPtr; BarSetKey key; key.value = (float)x[i]; key.axes = elemPtr->axes; key.axes.y = NULL; hPtr = Blt_FindHashEntry(&graphPtr->setTable, (char *)&key); if (hPtr != NULL) { Blt_HashTable *tablePtr; const char *name; tablePtr = Blt_GetHashValue(hPtr); name = (elemPtr->groupName != NULL) ? elemPtr->groupName : elemPtr->axes.y->obj.name; hPtr = Blt_FindHashEntry(tablePtr, name); if (hPtr != NULL) { BarGroup *groupPtr; double slice, width, offset; groupPtr = Blt_GetHashValue(hPtr); slice = barWidth / (double)graphPtr->maxBarSetSize; offset = (slice * groupPtr->index); if (graphPtr->maxBarSetSize > 1) { offset += slice * 0.05; slice *= 0.90; } switch (graphPtr->mode) { case BARS_STACKED: groupPtr->count++; c2.y = groupPtr->lastY; c1.y += c2.y; groupPtr->lastY = c1.y; c1.x += offset; c2.x = c1.x + slice; break; case BARS_ALIGNED: slice /= groupPtr->nSegments; c1.x += offset + (slice * groupPtr->count); c2.x = c1.x + slice; groupPtr->count++; break; case BARS_OVERLAP: slice /= (groupPtr->nSegments + 1); width = slice + slice; groupPtr->count++; c1.x += offset + (slice * (groupPtr->nSegments - groupPtr->count)); c2.x = c1.x + width; break; case BARS_INFRONT: break; } } } } invertBar = FALSE; if (c1.y < c2.y) { double temp; /* Handle negative bar values by swapping ordinates */ temp = c1.y, c1.y = c2.y, c2.y = temp; invertBar = TRUE; } /* * Get the two corners of the bar segment and compute the rectangle */ ybot = c2.y; c1 = Blt_Map2D(graphPtr, c1.x, c1.y, &elemPtr->axes); c2 = Blt_Map2D(graphPtr, c2.x, c2.y, &elemPtr->axes); if ((ybot == 0.0) && (elemPtr->axes.y->logScale)) { c2.y = graphPtr->bottom; } if (c2.y < c1.y) { double t; t = c1.y, c1.y = c2.y, c2.y = t; } if (c2.x < c1.x) { double t; t = c1.x, c1.x = c2.x, c2.x = t; } if ((c1.x > graphPtr->right) || (c2.x < graphPtr->left) || (c1.y > graphPtr->bottom) || (c2.y < graphPtr->top)) { continue; } /* Bound the bars horizontally by the width of the graph window */ /* Bound the bars vertically by the position of the axis. */ if (graphPtr->stackAxes) { top = elemPtr->axes.y->screenMin; bottom = elemPtr->axes.y->screenMin + elemPtr->axes.y->screenRange; left = graphPtr->left; right = graphPtr->right; } else { left = top = 0; bottom = right = 10000; /* Shouldn't really have a call to Tk_Width or Tk_Height in * mapping routine. We only want to clamp the bar segment to the * size of the window if we're actually mapped onscreen. */ if (Tk_Height(graphPtr->tkwin) > 1) { bottom = Tk_Height(graphPtr->tkwin); } if (Tk_Width(graphPtr->tkwin) > 1) { right = Tk_Width(graphPtr->tkwin); } } CLAMP(c1.y, top, bottom); CLAMP(c2.y, top, bottom); CLAMP(c1.x, left, right); CLAMP(c2.x, left, right); dx = FABS(c1.x - c2.x); dy = FABS(c1.y - c2.y); if ((dx == 0) || (dy == 0)) { continue; } height = (int)dy; if (invertBar) { rp->y = (short int)MIN(c1.y, c2.y); } else { rp->y = (short int)(MAX(c1.y, c2.y)) - height; } rp->x = (short int)MIN(c1.x, c2.x); rp->width = (short int)dx + 1; rp->width |= 0x1; if (rp->width < 1) { rp->width = 1; } rp->height = height + 1; if (rp->height < 1) { rp->height = 1; } barToData[count] = i; /* Save the data index corresponding to * the rectangle */ count++; rp++; } elemPtr->nBars = count; elemPtr->bars = bars; elemPtr->barToData = barToData; if (elemPtr->nActiveIndices > 0) { MapActiveBars(elemPtr); } size = 20; if (count > 0) { size = bars->width; } { Blt_ChainLink link; /* Set the symbol size of all the pen styles. */ for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; stylePtr = Blt_Chain_GetValue(link); stylePtr->symbolSize = size; stylePtr->errorBarCapWidth = (stylePtr->penPtr->errorBarCapWidth > 0) ? stylePtr->penPtr->errorBarCapWidth : (size * 66666) / 100000; stylePtr->errorBarCapWidth /= 2; } } dataToStyle = (BarStyle **)Blt_StyleMap((Element *)elemPtr); if (((elemPtr->yHigh.nValues > 0) && (elemPtr->yLow.nValues > 0)) || ((elemPtr->xHigh.nValues > 0) && (elemPtr->xLow.nValues > 0)) || (elemPtr->xError.nValues > 0) || (elemPtr->yError.nValues > 0)) { MapErrorBars(graphPtr, elemPtr, dataToStyle); } MergePens(elemPtr, dataToStyle); Blt_Free(dataToStyle); } /* *--------------------------------------------------------------------------- * * DrawSymbolProc -- * * Draw a symbol centered at the given x,y window coordinate based upon * the element symbol type and size. * * Results: * None. * * Problems: * Most notable is the round-off errors generated when calculating the * centered position of the symbol. *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void DrawSymbolProc(Graph *graphPtr, Drawable drawable, Element *basePtr, int x, int y, int size) { BarElement *elemPtr = (BarElement *)basePtr; BarPen *penPtr; int radius; penPtr = NORMALPEN(elemPtr); if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) { return; } radius = (size / 2); size--; x -= radius; y -= radius; if (penPtr->fillGC != NULL) { XSetTSOrigin(graphPtr->display, penPtr->fillGC, x, y); } if (penPtr->stipple != None) { XFillRectangle(graphPtr->display, drawable, penPtr->fillGC, x, y, size, size); } else { Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, penPtr->fill, x, y, size, size, penPtr->borderWidth, penPtr->relief); } XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC, x, y, size, size); if (penPtr->fillGC != NULL) { XSetTSOrigin(graphPtr->display, penPtr->fillGC, 0, 0); } } /* *--------------------------------------------------------------------------- * * DrawBarSegments -- * * Draws each of the rectangular segments for the element. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawBarSegments(Graph *graphPtr, Drawable drawable, BarPen *penPtr, XRectangle *bars, int nBars) { TkRegion rgn; { XRectangle clip; clip.x = graphPtr->left; clip.y = graphPtr->top; clip.width = graphPtr->right - graphPtr->left + 1; clip.height = graphPtr->bottom - graphPtr->top + 1; rgn = TkCreateRegion(); TkUnionRectWithRegion(&clip, rgn, rgn); } if (penPtr->fill != NULL) { XRectangle *rp, *rend; int hasOutline; int relief; relief = (penPtr->relief == TK_RELIEF_SOLID) ? TK_RELIEF_FLAT: penPtr->relief; hasOutline = ((relief == TK_RELIEF_FLAT) && (penPtr->outlineColor != NULL)); if (penPtr->stipple != None) { TkSetRegion(graphPtr->display, penPtr->fillGC, rgn); } Blt_SetBackgroundClipRegion(graphPtr->tkwin, penPtr->fill, rgn); if (hasOutline) { TkSetRegion(graphPtr->display, penPtr->outlineGC, rgn); } for (rp = bars, rend = rp + nBars; rp < rend; rp++) { if (penPtr->stipple != None) { XFillRectangle(graphPtr->display, drawable, penPtr->fillGC, rp->x, rp->y, rp->width, rp->height); } else { Blt_FillBackgroundRectangle(graphPtr->tkwin, drawable, penPtr->fill, rp->x, rp->y, rp->width, rp->height, penPtr->borderWidth, relief); } if (hasOutline) { XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC, rp->x, rp->y, rp->width, rp->height); } } Blt_UnsetBackgroundClipRegion(graphPtr->tkwin, penPtr->fill); if (hasOutline) { XSetClipMask(graphPtr->display, penPtr->outlineGC, None); } if (penPtr->stipple != None) { XSetClipMask(graphPtr->display, penPtr->fillGC, None); } } else if (penPtr->outlineColor != NULL) { TkSetRegion(graphPtr->display, penPtr->outlineGC, rgn); XDrawRectangles(graphPtr->display, drawable, penPtr->outlineGC, bars, nBars); XSetClipMask(graphPtr->display, penPtr->outlineGC, None); } TkDestroyRegion(rgn); } /* *--------------------------------------------------------------------------- * * DrawBarValues -- * * Draws the numeric value of the bar. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DrawBarValues(Graph *graphPtr, Drawable drawable, BarElement *elemPtr, BarPen *penPtr, XRectangle *bars, int nBars, int *barToData) { XRectangle *rp, *rend; int count; const char *fmt; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } count = 0; for (rp = bars, rend = rp + nBars; rp < rend; rp++) { Point2d anchorPos; double x, y; char string[TCL_DOUBLE_SPACE * 2 + 2]; x = elemPtr->x.values[barToData[count]]; y = elemPtr->y.values[barToData[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } if (graphPtr->inverted) { anchorPos.y = rp->y + rp->height * 0.5; anchorPos.x = rp->x + rp->width; if (x < graphPtr->baseline) { anchorPos.x -= rp->width; } } else { anchorPos.x = rp->x + rp->width * 0.5; anchorPos.y = rp->y; if (y < graphPtr->baseline) { anchorPos.y += rp->height; } } Blt_DrawText(graphPtr->tkwin, drawable, string, &penPtr->valueStyle, (int)anchorPos.x, (int)anchorPos.y); } } /* *--------------------------------------------------------------------------- * * DrawNormalBar -- * * Draws the rectangle representing the bar element. If the relief * option is set to "raised" or "sunken" and the bar borderwidth is set * (borderwidth > 0), a 3D border is drawn around the bar. * * Don't draw bars that aren't visible (i.e. within the limits of the * axis). * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawNormalBarProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; int count; Blt_ChainLink link; count = 0; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; BarPen *penPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = stylePtr->penPtr; if (stylePtr->nBars > 0) { DrawBarSegments(graphPtr, drawable, penPtr, stylePtr->bars, stylePtr->nBars); } if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC, stylePtr->yeb.segments, stylePtr->yeb.length); } if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, stylePtr->bars, stylePtr->nBars, elemPtr->barToData + count); } count += stylePtr->nBars; } } /* *--------------------------------------------------------------------------- * * DrawActiveBar -- * * Draws bars representing the active segments of the bar element. If * the -relief option is set (other than "flat") and the borderwidth is * greater than 0, a 3D border is drawn around the each bar segment. * * Results: * None. * * Side effects: * X drawing commands are output. * *--------------------------------------------------------------------------- */ static void DrawActiveBarProc(Graph *graphPtr, Drawable drawable, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; if (elemPtr->activePenPtr != NULL) { BarPen *penPtr = elemPtr->activePenPtr; if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveBars(elemPtr); } DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->activeRects, elemPtr->nActive); if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->activeRects, elemPtr->nActive, elemPtr->activeToData); } } else if (elemPtr->nActiveIndices < 0) { DrawBarSegments(graphPtr, drawable, penPtr, elemPtr->bars, elemPtr->nBars); if (penPtr->valueShow != SHOW_NONE) { DrawBarValues(graphPtr, drawable, elemPtr, penPtr, elemPtr->bars, elemPtr->nBars, elemPtr->barToData); } } } } /* *--------------------------------------------------------------------------- * * SymbolToPostScript -- * * Draw a symbol centered at the given x,y window coordinate based upon * the element symbol type and size. * * Results: * None. * * Problems: * Most notable is the round-off errors generated when calculating the * centered position of the symbol. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void SymbolToPostScriptProc( Graph *graphPtr, Blt_Ps ps, Element *basePtr, double x, double y, int size) { BarElement *elemPtr = (BarElement *)basePtr; BarPen *penPtr; penPtr = NORMALPEN(elemPtr); if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) { return; } /* * Build a PostScript procedure to draw the fill and outline of the symbol * after the path of the symbol shape has been formed */ Blt_Ps_Append(ps, "\n" "/DrawSymbolProc {\n" "gsave\n "); if (penPtr->stipple != None) { if (penPtr->fill != NULL) { Blt_Ps_XSetBackground(ps, Blt_BackgroundBorderColor(penPtr->fill)); Blt_Ps_Append(ps, " gsave fill grestore\n "); } if (penPtr->outlineColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->outlineColor); } else { Blt_Ps_XSetForeground(ps, Blt_BackgroundBorderColor(penPtr->fill)); } Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple); } else if (penPtr->outlineColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->outlineColor); Blt_Ps_Append(ps, " fill\n"); } Blt_Ps_Append(ps, " grestore\n"); Blt_Ps_Append(ps, "} def\n\n"); Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size); } static void SegmentsToPostScript(Graph *graphPtr, Blt_Ps ps, BarPen *penPtr, XRectangle *bars, int nBars) { XRectangle *rp, *rend; if ((penPtr->fill == NULL) && (penPtr->outlineColor == NULL)) { return; } for (rp = bars, rend = rp + nBars; rp < rend; rp++) { if ((rp->width < 1) || (rp->height < 1)) { continue; } if (penPtr->stipple != None) { Blt_Ps_Rectangle(ps, rp->x, rp->y, rp->width - 1, rp->height - 1); if (penPtr->fill != NULL) { Blt_Ps_XSetBackground(ps,Blt_BackgroundBorderColor(penPtr->fill)); Blt_Ps_Append(ps, "gsave fill grestore\n"); } if (penPtr->outlineColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->outlineColor); } else { Blt_Ps_XSetForeground(ps,Blt_BackgroundBorderColor(penPtr->fill)); } Blt_Ps_XSetStipple(ps, graphPtr->display, penPtr->stipple); } else if (penPtr->outlineColor != NULL) { Blt_Ps_XSetForeground(ps, penPtr->outlineColor); Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y, (int)rp->width - 1, (int)rp->height - 1); } if ((penPtr->fill != NULL) && (penPtr->borderWidth > 0) && (penPtr->relief != TK_RELIEF_FLAT)) { Blt_Ps_Draw3DRectangle(ps, Blt_BackgroundBorder(penPtr->fill), (double)rp->x, (double)rp->y, (int)rp->width, (int)rp->height, penPtr->borderWidth, penPtr->relief); } } } static void BarValuesToPostScript(Graph *graphPtr, Blt_Ps ps, BarElement *elemPtr, BarPen *penPtr, XRectangle *bars, int nBars, int *barToData) { XRectangle *rp, *rend; int count; const char *fmt; char string[TCL_DOUBLE_SPACE * 2 + 2]; double x, y; Point2d anchorPos; count = 0; fmt = penPtr->valueFormat; if (fmt == NULL) { fmt = "%g"; } for (rp = bars, rend = rp + nBars; rp < rend; rp++) { x = elemPtr->x.values[barToData[count]]; y = elemPtr->y.values[barToData[count]]; count++; if (penPtr->valueShow == SHOW_X) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); } else if (penPtr->valueShow == SHOW_Y) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y); } else if (penPtr->valueShow == SHOW_BOTH) { sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x); strcat(string, ","); sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y); } if (graphPtr->inverted) { anchorPos.y = rp->y + rp->height * 0.5; anchorPos.x = rp->x + rp->width; if (x < graphPtr->baseline) { anchorPos.x -= rp->width; } } else { anchorPos.x = rp->x + rp->width * 0.5; anchorPos.y = rp->y; if (y < graphPtr->baseline) { anchorPos.y += rp->height; } } Blt_Ps_DrawText(ps, string, &penPtr->valueStyle, anchorPos.x, anchorPos.y); } } /* *--------------------------------------------------------------------------- * * ActiveBarToPostScript -- * * Similar to the NormalBarToPostScript procedure, generates PostScript * commands to display the bars representing the active bar segments of * the element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void ActiveBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; if (elemPtr->activePenPtr != NULL) { BarPen *penPtr = elemPtr->activePenPtr; if (elemPtr->nActiveIndices > 0) { if (elemPtr->flags & ACTIVE_PENDING) { MapActiveBars(elemPtr); } SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->activeRects, elemPtr->nActive); if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, elemPtr->activeRects, elemPtr->nActive, elemPtr->activeToData); } } else if (elemPtr->nActiveIndices < 0) { SegmentsToPostScript(graphPtr, ps, penPtr, elemPtr->bars, elemPtr->nBars); if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, elemPtr->bars, elemPtr->nBars, elemPtr->barToData); } } } } /* *--------------------------------------------------------------------------- * * NormalBarToPostScript -- * * Generates PostScript commands to form the bars representing the * segments of the bar element. * * Results: * None. * * Side effects: * PostScript pen width, dashes, and color settings are changed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void NormalBarToPostScriptProc(Graph *graphPtr, Blt_Ps ps, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; Blt_ChainLink link; int count; count = 0; for (link = Blt_Chain_FirstLink(elemPtr->stylePalette); link != NULL; link = Blt_Chain_NextLink(link)) { BarStyle *stylePtr; BarPen *penPtr; XColor *colorPtr; stylePtr = Blt_Chain_GetValue(link); penPtr = stylePtr->penPtr; if (stylePtr->nBars > 0) { SegmentsToPostScript(graphPtr, ps, penPtr, stylePtr->bars, stylePtr->nBars); } colorPtr = penPtr->errorBarColor; if (colorPtr == COLOR_DEFAULT) { colorPtr = penPtr->outlineColor; } if ((stylePtr->xeb.length > 0) && (penPtr->errorBarShow & SHOW_X)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments, stylePtr->xeb.length); } if ((stylePtr->yeb.length > 0) && (penPtr->errorBarShow & SHOW_Y)) { Blt_Ps_XSetLineAttributes(ps, colorPtr, penPtr->errorBarLineWidth, NULL, CapButt, JoinMiter); Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments, stylePtr->yeb.length); } if (penPtr->valueShow != SHOW_NONE) { BarValuesToPostScript(graphPtr, ps, elemPtr, penPtr, stylePtr->bars, stylePtr->nBars, elemPtr->barToData + count); } count += stylePtr->nBars; } } /* *--------------------------------------------------------------------------- * * DestroyBar -- * * Release memory and resources allocated for the bar element. * * Results: * None. * * Side effects: * Everything associated with the bar element is freed up. * *--------------------------------------------------------------------------- */ static void DestroyBarProc(Graph *graphPtr, Element *basePtr) { BarElement *elemPtr = (BarElement *)basePtr; DestroyBarPen(graphPtr, elemPtr->builtinPenPtr); if (elemPtr->activePenPtr != NULL) { Blt_FreePen((Pen *)elemPtr->activePenPtr); } ResetBar(elemPtr); if (elemPtr->stylePalette != NULL) { Blt_FreeStylePalette(elemPtr->stylePalette); Blt_Chain_Destroy(elemPtr->stylePalette); } if (elemPtr->activeIndices != NULL) { Blt_Free(elemPtr->activeIndices); } } /* *--------------------------------------------------------------------------- * * Blt_BarElement -- * * Allocate memory and initialize methods for the new bar element. * * Results: * The pointer to the newly allocated element structure is returned. * * Side effects: * Memory is allocated for the bar element structure. * *--------------------------------------------------------------------------- */ static ElementProcs barProcs = { ClosestBarProc, ConfigureBarProc, DestroyBarProc, DrawActiveBarProc, DrawNormalBarProc, DrawSymbolProc, GetBarExtentsProc, ActiveBarToPostScriptProc, NormalBarToPostScriptProc, SymbolToPostScriptProc, MapBarProc, }; Element * Blt_BarElement(Graph *graphPtr, const char *name, ClassId classId) { BarElement *elemPtr; elemPtr = Blt_AssertCalloc(1, sizeof(BarElement)); elemPtr->procsPtr = &barProcs; elemPtr->configSpecs = barElemConfigSpecs; elemPtr->legendRelief = TK_RELIEF_FLAT; Blt_GraphSetObjectClass(&elemPtr->obj, classId); elemPtr->obj.name = Blt_AssertStrdup(name); elemPtr->obj.graphPtr = graphPtr; /* By default, an element's name and label are the same. */ elemPtr->label = Blt_AssertStrdup(name); elemPtr->builtinPenPtr = &elemPtr->builtinPen; InitializeBarPen(elemPtr->builtinPenPtr); elemPtr->stylePalette = Blt_Chain_Create(); bltBarStylesOption.clientData = (ClientData)sizeof(BarStyle); return (Element *)elemPtr; } /* *--------------------------------------------------------------------------- * * Blt_InitBarSetTable -- * * Generate a table of abscissa frequencies. Duplicate x-coordinates * (depending upon the bar drawing mode) indicate that something special * should be done with each bar segment mapped to the same abscissa * (i.e. it should be stacked, aligned, or overlay-ed with other segments) * * Results: * None. * * Side effects: * Memory is allocated for the bar element structure. * *--------------------------------------------------------------------------- */ void Blt_InitBarSetTable(Graph *graphPtr) { Blt_ChainLink link; int nStacks, nSegs; Blt_HashTable setTable; int sum, max; Blt_HashEntry *hPtr; Blt_HashSearch iter; /* * Free resources associated with a previous frequency table. This includes * the array of frequency information and the table itself */ Blt_DestroyBarSets(graphPtr); if (graphPtr->mode == BARS_INFRONT) { return; /* No set table is needed for * "infront" mode */ } Blt_InitHashTable(&graphPtr->setTable, sizeof(BarSetKey) / sizeof(int)); /* * Initialize a hash table and fill it with unique abscissas. Keep track * of the frequency of each x-coordinate and how many abscissas have * duplicate mappings. */ Blt_InitHashTable(&setTable, sizeof(BarSetKey) / sizeof(int)); nSegs = nStacks = 0; for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { BarElement *elemPtr; double *x, *xend; int nPoints; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) { continue; } nSegs++; nPoints = NUMBEROFPOINTS(elemPtr); for (x = elemPtr->x.values, xend = x + nPoints; x < xend; x++) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; BarSetKey key; int isNew; size_t count; const char *name; key.value = *x; key.axes = elemPtr->axes; key.axes.y = NULL; hPtr = Blt_CreateHashEntry(&setTable, (char *)&key, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_STRING_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } name = (elemPtr->groupName != NULL) ? elemPtr->groupName : elemPtr->axes.y->obj.name; hPtr = Blt_CreateHashEntry(tablePtr, name, &isNew); if (isNew) { count = 1; } else { count = (size_t)Blt_GetHashValue(hPtr); count++; } Blt_SetHashValue(hPtr, (ClientData)count); } } if (setTable.numEntries == 0) { return; /* No bar elements to be displayed */ } sum = max = 0; for (hPtr = Blt_FirstHashEntry(&setTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; Blt_HashEntry *hPtr2; BarSetKey *keyPtr; int isNew; keyPtr = (BarSetKey *)Blt_GetHashKey(&setTable, hPtr); hPtr2 = Blt_CreateHashEntry(&graphPtr->setTable, (char *)keyPtr,&isNew); tablePtr = Blt_GetHashValue(hPtr); Blt_SetHashValue(hPtr2, tablePtr); if (max < tablePtr->numEntries) { max = tablePtr->numEntries; /* # of stacks in group. */ } sum += tablePtr->numEntries; } Blt_DeleteHashTable(&setTable); if (sum > 0) { BarGroup *groupPtr; Blt_HashEntry *hPtr; Blt_HashSearch iter; graphPtr->barGroups = Blt_AssertCalloc(sum, sizeof(BarGroup)); groupPtr = graphPtr->barGroups; for (hPtr = Blt_FirstHashEntry(&graphPtr->setTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { BarSetKey *keyPtr; Blt_HashTable *tablePtr; Blt_HashEntry *hPtr2; Blt_HashSearch iter2; size_t xcount; tablePtr = Blt_GetHashValue(hPtr); keyPtr = (BarSetKey *)Blt_GetHashKey(&setTable, hPtr); xcount = 0; for (hPtr2 = Blt_FirstHashEntry(tablePtr, &iter2); hPtr2!=NULL; hPtr2 = Blt_NextHashEntry(&iter2)) { size_t count; count = (size_t)Blt_GetHashValue(hPtr2); groupPtr->nSegments = count; groupPtr->axes = keyPtr->axes; Blt_SetHashValue(hPtr2, groupPtr); groupPtr->index = xcount++; groupPtr++; } } } graphPtr->maxBarSetSize = max; graphPtr->nBarGroups = sum; } /* *--------------------------------------------------------------------------- * * Blt_ComputeStacks -- * * Determine the height of each stack of bar segments. A stack is created * by designating two or more points with the same abscissa. Each ordinate * defines the height of a segment in the stack. This procedure simply * looks at all the data points summing the heights of each stacked * segment. The sum is saved in the frequency information table. This * value will be used to calculate the y-axis limits (data limits aren't * sufficient). * * Results: * None. * * Side effects: * The heights of each stack is computed. CheckBarGroups will use this * information to adjust the y-axis limits if necessary. * *--------------------------------------------------------------------------- */ void Blt_ComputeBarStacks(Graph *graphPtr) { Blt_ChainLink link; if ((graphPtr->mode != BARS_STACKED) || (graphPtr->nBarGroups == 0)) { return; } /* Initialize the stack sums to zero. */ { BarGroup *gp, *gend; for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend; gp++) { gp->sum = 0.0; } } /* Consider each bar x-y coordinate. Add the ordinates of duplicate * abscissas. */ for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { BarElement *elemPtr; double *x, *y, *xend; elemPtr = Blt_Chain_GetValue(link); if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) { continue; } for (x = elemPtr->x.values, y = elemPtr->y.values, xend = x + NUMBEROFPOINTS(elemPtr); x < xend; x++, y++) { BarSetKey key; BarGroup *groupPtr; Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; const char *name; key.value = *x; key.axes = elemPtr->axes; key.axes.y = NULL; hPtr = Blt_FindHashEntry(&graphPtr->setTable, (char *)&key); if (hPtr == NULL) { continue; } tablePtr = Blt_GetHashValue(hPtr); name = (elemPtr->groupName != NULL) ? elemPtr->groupName : elemPtr->axes.y->obj.name; hPtr = Blt_FindHashEntry(tablePtr, name); if (hPtr == NULL) { continue; } groupPtr = Blt_GetHashValue(hPtr); groupPtr->sum += *y; } } } void Blt_ResetBarGroups(Graph *graphPtr) { BarGroup *gp, *gend; for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend; gp++) { gp->lastY = 0.0; gp->count = 0; } } void Blt_DestroyBarSets(Graph *graphPtr) { Blt_HashSearch iter; Blt_HashEntry *hPtr; if (graphPtr->barGroups != NULL) { Blt_Free(graphPtr->barGroups); graphPtr->barGroups = NULL; } graphPtr->nBarGroups = 0; for (hPtr = Blt_FirstHashEntry(&graphPtr->setTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&graphPtr->setTable); Blt_InitHashTable(&graphPtr->setTable, sizeof(BarSetKey) / sizeof(int)); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVar85.c��������������������������������������������������������������������0000644�0001750�0001750�00000035245�11462120063�014612� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVar85.c -- * * This module implements TCL 8.5 variable handler procedures for the BLT * toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include "bltNsUtil.h" #include "bltVar.h" #include <bltList.h> /* * Variable resolver routines. * * The following bit of magic is from [incr Tcl]. The following * routine are taken from [incr Tcl] to roughly duplicate how Tcl * internally creates variables. * * Note: There is no API for the variable resolver routines in the Tcl * library. The resolver callback is supposed to return a Tcl_Var * back. But the definition of Tcl_Var in tcl.h is opaque. */ typedef struct TclVarHashTable { Tcl_HashTable table; Tcl_Namespace *nsPtr; } TclVarHashTable; /* * The structure below defines a variable, which associates a string name with * a Tcl_Obj value. These structures are kept in procedure call frames (for * local variables recognized by the compiler) or in the heap (for global * variables and any variable not known to the compiler). For each Var * structure in the heap, a hash table entry holds the variable name and a * pointer to the Var structure. */ typedef struct Var { int flags; /* Miscellaneous bits of information about * variable. See below for definitions. */ union { Tcl_Obj *objPtr; /* The variable's object value. Used for * scalar variables and array elements. */ TclVarHashTable *tablePtr;/* For array variables, this points to * information about the hash table used to * implement the associative array. Points to * ckalloc-ed data. */ struct Var *linkPtr; /* If this is a global variable being referred * to in a procedure, or a variable created by * "upvar", this field points to the * referenced variable's Var struct. */ } value; } Var; typedef struct VarInHash { Var var; int refCount; /* Counts number of active uses of this * variable: 1 for the entry in the hash * table, 1 for each additional variable whose * linkPtr points here, 1 for each nested * trace active on variable, and 1 if the * variable is a namespace variable. This * record can't be deleted until refCount * becomes 0. */ Tcl_HashEntry entry; /* The hash table entry that refers to this * variable. This is used to find the name of * the variable and to delete it from its * hashtable if it is no longer needed. It * also holds the variable's name. */ } VarInHash; /* * Flag bits for variables. The first two (VAR_ARRAY and VAR_LINK) are * mutually exclusive and give the "type" of the variable. If none is set, * this is a scalar variable. * * VAR_ARRAY - 1 means this is an array variable rather than * a scalar variable or link. The "tablePtr" * field points to the array's hashtable for its * elements. * VAR_LINK - 1 means this Var structure contains a pointer * to another Var structure that either has the * real value or is itself another VAR_LINK * pointer. Variables like this come about * through "upvar" and "global" commands, or * through references to variables in enclosing * namespaces. * * Flags that indicate the type and status of storage; none is set for * compiled local variables (Var structs). * * VAR_IN_HASHTABLE - 1 means this variable is in a hashtable and * the Var structure is malloced. 0 if it is a * local variable that was assigned a slot in a * procedure frame by the compiler so the Var * storage is part of the call frame. * VAR_DEAD_HASH 1 means that this var's entry in the hashtable * has already been deleted. * VAR_ARRAY_ELEMENT - 1 means that this variable is an array * element, so it is not legal for it to be an * array itself (the VAR_ARRAY flag had better * not be set). * VAR_NAMESPACE_VAR - 1 means that this variable was declared as a * namespace variable. This flag ensures it * persists until its namespace is destroyed or * until the variable is unset; it will persist * even if it has not been initialized and is * marked undefined. The variable's refCount is * incremented to reflect the "reference" from * its namespace. * * Flag values relating to the variable's trace and search status. * * VAR_TRACED_READ * VAR_TRACED_WRITE * VAR_TRACED_UNSET * VAR_TRACED_ARRAY * VAR_TRACE_ACTIVE - 1 means that trace processing is currently * underway for a read or write access, so new * read or write accesses should not cause trace * procedures to be called and the variable can't * be deleted. * VAR_SEARCH_ACTIVE * * The following additional flags are used with the CompiledLocal type defined * below: * * VAR_ARGUMENT - 1 means that this variable holds a procedure * argument. * VAR_TEMPORARY - 1 if the local variable is an anonymous * temporary variable. Temporaries have a NULL * name. * VAR_RESOLVED - 1 if name resolution has been done for this * variable. * VAR_IS_ARGS 1 if this variable is the last argument and is * named "args". */ /* * FLAGS RENUMBERED: everything breaks already, make things simpler. * * IMPORTANT: skip the values 0x10, 0x20, 0x40, 0x800 corresponding to * TCL_TRACE_(READS/WRITES/UNSETS/ARRAY): makes code simpler in tclTrace.c * * Keep the flag values for VAR_ARGUMENT and VAR_TEMPORARY so that old values * in precompiled scripts keep working. */ /* Type of value (0 is scalar) */ #define VAR_ARRAY 0x1 #define VAR_LINK 0x2 /* Type of storage (0 is compiled local) */ #define VAR_IN_HASHTABLE 0x4 #define VAR_DEAD_HASH 0x8 #define VAR_ARRAY_ELEMENT 0x1000 #define VAR_NAMESPACE_VAR 0x80 /* KEEP OLD VALUE for Itcl */ #define VAR_ALL_HASH \ (VAR_IN_HASHTABLE|VAR_DEAD_HASH|VAR_NAMESPACE_VAR|VAR_ARRAY_ELEMENT) /* Trace and search state */ #define VAR_TRACED_READ 0x10 /* TCL_TRACE_READS */ #define VAR_TRACED_WRITE 0x20 /* TCL_TRACE_WRITES */ #define VAR_TRACED_UNSET 0x40 /* TCL_TRACE_UNSETS */ #define VAR_TRACED_ARRAY 0x800 /* TCL_TRACE_ARRAY */ #define VAR_TRACE_ACTIVE 0x2000 #define VAR_SEARCH_ACTIVE 0x4000 #define VAR_ALL_TRACES \ (VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_ARRAY|VAR_TRACED_UNSET) /* Special handling on initialisation (only CompiledLocal) */ #define VAR_ARGUMENT 0x100 /* KEEP OLD VALUE! See tclProc.c */ #define VAR_TEMPORARY 0x200 /* KEEP OLD VALUE! See tclProc.c */ #define VAR_IS_ARGS 0x400 #define VAR_RESOLVED 0x8000 /* * Macros to ensure that various flag bits are set properly for variables. * The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE void TclSetVarScalar(Var *varPtr); * MODULE_SCOPE void TclSetVarArray(Var *varPtr); * MODULE_SCOPE void TclSetVarLink(Var *varPtr); * MODULE_SCOPE void TclSetVarArrayElement(Var *varPtr); * MODULE_SCOPE void TclSetVarUndefined(Var *varPtr); * MODULE_SCOPE void TclClearVarUndefined(Var *varPtr); */ #define TclSetVarScalar(varPtr) \ (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK) #define TclSetVarArray(varPtr) \ (varPtr)->flags = ((varPtr)->flags & ~VAR_LINK) | VAR_ARRAY #define TclSetVarLink(varPtr) \ (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_LINK #define TclSetVarArrayElement(varPtr) \ (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT #define TclSetVarUndefined(varPtr) \ (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK);\ (varPtr)->value.objPtr = NULL #define TclClearVarUndefined(varPtr) #define TclSetVarTraceActive(varPtr) \ (varPtr)->flags |= VAR_TRACE_ACTIVE #define TclClearVarTraceActive(varPtr) \ (varPtr)->flags &= ~VAR_TRACE_ACTIVE #define TclSetVarNamespaceVar(varPtr) \ if (!TclIsVarNamespaceVar(varPtr)) {\ (varPtr)->flags |= VAR_NAMESPACE_VAR;\ ((VarInHash *)(varPtr))->refCount++;\ } #define TclClearVarNamespaceVar(varPtr) \ if (TclIsVarNamespaceVar(varPtr)) {\ (varPtr)->flags &= ~VAR_NAMESPACE_VAR;\ ((VarInHash *)(varPtr))->refCount--;\ } /* * Macros to read various flag bits of variables. * The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE int TclIsVarScalar(Var *varPtr); * MODULE_SCOPE int TclIsVarLink(Var *varPtr); * MODULE_SCOPE int TclIsVarArray(Var *varPtr); * MODULE_SCOPE int TclIsVarUndefined(Var *varPtr); * MODULE_SCOPE int TclIsVarArrayElement(Var *varPtr); * MODULE_SCOPE int TclIsVarTemporary(Var *varPtr); * MODULE_SCOPE int TclIsVarArgument(Var *varPtr); * MODULE_SCOPE int TclIsVarResolved(Var *varPtr); */ #define TclIsVarScalar(varPtr) \ !((varPtr)->flags & (VAR_ARRAY|VAR_LINK)) #define TclIsVarLink(varPtr) \ ((varPtr)->flags & VAR_LINK) #define TclIsVarArray(varPtr) \ ((varPtr)->flags & VAR_ARRAY) #define TclIsVarUndefined(varPtr) \ ((varPtr)->value.objPtr == NULL) #define TclIsVarArrayElement(varPtr) \ ((varPtr)->flags & VAR_ARRAY_ELEMENT) #define TclIsVarNamespaceVar(varPtr) \ ((varPtr)->flags & VAR_NAMESPACE_VAR) #define TclIsVarTemporary(varPtr) \ ((varPtr)->flags & VAR_TEMPORARY) #define TclIsVarArgument(varPtr) \ ((varPtr)->flags & VAR_ARGUMENT) #define TclIsVarResolved(varPtr) \ ((varPtr)->flags & VAR_RESOLVED) #define TclIsVarTraceActive(varPtr) \ ((varPtr)->flags & VAR_TRACE_ACTIVE) #define TclIsVarTraced(varPtr) \ ((varPtr)->flags & VAR_ALL_TRACES) #define TclIsVarInHash(varPtr) \ ((varPtr)->flags & VAR_IN_HASHTABLE) #define TclIsVarDeadHash(varPtr) \ ((varPtr)->flags & VAR_DEAD_HASH) #define TclGetVarNsPtr(varPtr) \ (TclIsVarInHash(varPtr) \ ? ((TclVarHashTable *) ((((VarInHash *) (varPtr))->entry.tablePtr)))->nsPtr \ : NULL) #define VarHashRefCount(varPtr) \ ((VarInHash *) (varPtr))->refCount /* * Macros for direct variable access by TEBC */ #define TclIsVarDirectReadable(varPtr) \ ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ)) \ && (varPtr)->value.objPtr) #define TclIsVarDirectWritable(varPtr) \ !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_WRITE|VAR_DEAD_HASH)) #define TclIsVarDirectModifyable(varPtr) \ ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE)) \ && (varPtr)->value.objPtr) #define TclIsVarDirectReadable2(varPtr, arrayPtr) \ (TclIsVarDirectReadable(varPtr) &&\ (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_READ))) #define TclIsVarDirectWritable2(varPtr, arrayPtr) \ (TclIsVarDirectWritable(varPtr) &&\ (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_WRITE))) #define TclIsVarDirectModifyable2(varPtr, arrayPtr) \ (TclIsVarDirectModifyable(varPtr) &&\ (!(arrayPtr) || !((arrayPtr)->flags & (VAR_TRACED_READ|VAR_TRACED_WRITE)))) #define VarHashGetValue(hPtr) \ ((Var *) ((char *)hPtr - Blt_Offset(VarInHash, entry))) static INLINE Tcl_Namespace * NamespaceOfVariable(Var *varPtr) { if (varPtr->flags & VAR_IN_HASHTABLE) { VarInHash *vhashPtr = (VarInHash *)varPtr; TclVarHashTable *vtablePtr; vtablePtr = (TclVarHashTable *)vhashPtr->entry.tablePtr; return vtablePtr->nsPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * NewVar -- * * Create a new heap-allocated variable that will eventually be * entered into a hashtable. * * Results: * The return value is a pointer to the new variable structure. It is * marked as a scalar variable (and not a link or array variable). Its * value initially is NULL. The variable is not part of any hash table * yet. Since it will be in a hashtable and not in a call frame, its * name field is set NULL. It is initially marked as undefined. * * Side effects: * Storage gets allocated. * *--------------------------------------------------------------------------- */ static Var * NewVar(Tcl_Obj *objPtr) { Var *varPtr; varPtr = Blt_AssertMalloc(sizeof(Var)); varPtr->value.objPtr = objPtr; varPtr->flags = 0; return varPtr; } /* *--------------------------------------------------------------------------- * * Blt_GetVariableNamespace -- * * Returns the namespace context of the variable. If NULL, this * indicates that the variable is local to the call frame. * * Results: * Returns the context of the namespace in an opaque type. * *--------------------------------------------------------------------------- */ Tcl_Namespace * Blt_GetVariableNamespace(Tcl_Interp *interp, const char *path) { Blt_ObjectName objName; if (!Blt_ParseObjectName(interp, path, &objName, BLT_NO_DEFAULT_NS)) { return NULL; } if (objName.nsPtr == NULL) { Var *varPtr; varPtr = (Var *)Tcl_FindNamespaceVar(interp, (char *)path, (Tcl_Namespace *)NULL, TCL_NAMESPACE_ONLY); if (varPtr != NULL) { return NamespaceOfVariable(varPtr); } varPtr = (Var *)Tcl_FindNamespaceVar(interp, (char *)path, (Tcl_Namespace *)NULL, TCL_GLOBAL_ONLY); if (varPtr != NULL) { return NamespaceOfVariable(varPtr); } } return objName.nsPtr; } Tcl_Var Blt_GetCachedVar(Blt_HashTable *cacheTablePtr, const char *label, Tcl_Obj *objPtr) { Blt_HashEntry *hPtr; int isNew; Var *varPtr; /* Check if the variable has been cached already. */ hPtr = Blt_CreateHashEntry(cacheTablePtr, label, &isNew); if (isNew) { varPtr = NewVar(objPtr); Blt_SetHashValue(hPtr, varPtr); } else { varPtr = Blt_GetHashValue(hPtr); varPtr->value.objPtr = objPtr; } return (Tcl_Var)varPtr; } void Blt_FreeCachedVars(Blt_HashTable *tablePtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Var *varPtr; varPtr = Blt_GetHashValue(hPtr); Blt_Free(varPtr); } Blt_DeleteHashTable(tablePtr); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltChain.c��������������������������������������������������������������������0000644�0001750�0001750�00000030756�11462120062�014730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltChain.c -- * * The module implements a generic linked list package. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltChain.h" #ifndef ALIGN #define ALIGN(a) \ (((size_t)a + (sizeof(double) - 1)) & (~(sizeof(double) - 1))) #endif /* ALIGN */ typedef struct _Blt_ChainLink ChainLink; typedef struct _Blt_Chain Chain; /* *--------------------------------------------------------------------------- * * Blt_Chain_Create -- * * Creates a new linked list (chain) structure and initializes its * pointers; * * Results: * Returns a pointer to the newly created chain structure. * *--------------------------------------------------------------------------- */ Blt_Chain Blt_Chain_Create(void) { Chain *chainPtr; chainPtr = Blt_Malloc(sizeof(Chain)); if (chainPtr != NULL) { Blt_Chain_Init(chainPtr); } return chainPtr; } /* *--------------------------------------------------------------------------- * * Blt_Chain_AllocLink -- * * Creates a new chain link. Unlink Blt_Chain_NewLink, this routine also * allocates extra memory in the node for data. * * Results: * The return value is the pointer to the newly created entry. * *--------------------------------------------------------------------------- */ Blt_ChainLink Blt_Chain_AllocLink(size_t extraSize) { ChainLink *linkPtr; size_t linkSize; linkSize = ALIGN(sizeof(ChainLink)); linkPtr = Blt_AssertCalloc(1, linkSize + extraSize); if (extraSize > 0) { /* Point clientData at the memory beyond the normal structure. */ linkPtr->clientData = (ClientData)((char *)linkPtr + linkSize); } return linkPtr; } /* *--------------------------------------------------------------------------- * * Blt_Chain_InitLink -- * * Initializes the new link. This routine is for applications that use * their own memory allocation procedures to allocate links. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_InitLink(ChainLink *linkPtr) { linkPtr->clientData = NULL; linkPtr->next = linkPtr->prev = NULL; } /* *--------------------------------------------------------------------------- * * Blt_Chain_NewLink -- * * Creates a new link. * * Results: * The return value is the pointer to the newly created link. * *--------------------------------------------------------------------------- */ Blt_ChainLink Blt_Chain_NewLink(void) { ChainLink *linkPtr; linkPtr = Blt_AssertMalloc(sizeof(ChainLink)); linkPtr->clientData = NULL; linkPtr->next = linkPtr->prev = NULL; return linkPtr; } /* *--------------------------------------------------------------------------- * * Blt_Chain_Reset -- * * Removes all the links in the chain, freeing the memory used for each * link. Memory pointed to by the link (clientData) is not freed. It's * the caller's responsibility to deallocate it. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_Reset(Chain *chainPtr) /* Chain to clear */ { if (chainPtr != NULL) { ChainLink *oldPtr; ChainLink *linkPtr = chainPtr->head; while (linkPtr != NULL) { oldPtr = linkPtr; linkPtr = linkPtr->next; Blt_Free(oldPtr); } Blt_Chain_Init(chainPtr); } } /* *--------------------------------------------------------------------------- * * Blt_Chain_Destroy * * Frees all the nodes in the chain and deallocates the memory used for * the chain structure itself. It's assumed that the chain was previously * allocated by Blt_Chain_Create. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_Destroy(Chain *chainPtr) { if (chainPtr != NULL) { Blt_Chain_Reset(chainPtr); Blt_Free(chainPtr); } } /* *--------------------------------------------------------------------------- * * Blt_Chain_Init -- * * Initializes a linked list. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_Init(Chain *chainPtr) { chainPtr->nLinks = 0; chainPtr->head = chainPtr->tail = NULL; } /* *--------------------------------------------------------------------------- * * Blt_Chain_LinkAfter -- * * Inserts a link after another link. If afterPtr is NULL, then the new * link is prepended to the beginning of the chain. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_LinkAfter(Chain *chainPtr, ChainLink *linkPtr, ChainLink *afterPtr) { if (chainPtr->head == NULL) { chainPtr->tail = chainPtr->head = linkPtr; } else { if (afterPtr == NULL) { /* Append to the end of the chain. */ linkPtr->next = NULL; linkPtr->prev = chainPtr->tail; chainPtr->tail->next = linkPtr; chainPtr->tail = linkPtr; } else { linkPtr->next = afterPtr->next; linkPtr->prev = afterPtr; if (afterPtr == chainPtr->tail) { chainPtr->tail = linkPtr; } else { afterPtr->next->prev = linkPtr; } afterPtr->next = linkPtr; } } chainPtr->nLinks++; } /* *--------------------------------------------------------------------------- * * Blt_Chain_LinkBefore -- * * Inserts a new link preceding a given link in a chain. If beforePtr is * NULL, then the new link is placed at the beginning of the list. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_LinkBefore(Chain *chainPtr, ChainLink *linkPtr, ChainLink *beforePtr) { if (chainPtr->head == NULL) { chainPtr->tail = chainPtr->head = linkPtr; } else { if (beforePtr == NULL) { /* Prepend to the front of the chain */ linkPtr->next = chainPtr->head; linkPtr->prev = NULL; chainPtr->head->prev = linkPtr; chainPtr->head = linkPtr; } else { linkPtr->prev = beforePtr->prev; linkPtr->next = beforePtr; if (beforePtr == chainPtr->head) { chainPtr->head = linkPtr; } else { beforePtr->prev->next = linkPtr; } beforePtr->prev = linkPtr; } } chainPtr->nLinks++; } /* *--------------------------------------------------------------------------- * * Blt_Chain_UnlinkLink -- * * Unlinks a link from the chain. The link is not deallocated, but only * removed from the chain. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_UnlinkLink(Chain *chainPtr, ChainLink *linkPtr) { int unlinked; /* Indicates if the link is actually removed * from the chain. */ unlinked = FALSE; if (chainPtr->head == linkPtr) { chainPtr->head = linkPtr->next; unlinked = TRUE; } if (chainPtr->tail == linkPtr) { chainPtr->tail = linkPtr->prev; unlinked = TRUE; } if (linkPtr->next != NULL) { linkPtr->next->prev = linkPtr->prev; unlinked = TRUE; } if (linkPtr->prev != NULL) { linkPtr->prev->next = linkPtr->next; unlinked = TRUE; } if (unlinked) { chainPtr->nLinks--; } linkPtr->prev = linkPtr->next = NULL; } /* *--------------------------------------------------------------------------- * * Blt_Chain_DeleteLink -- * * Unlinks and frees the given link from the chain. It's assumed that * the link belong to the chain. No error checking is performed to verify * this. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_Chain_DeleteLink(Blt_Chain chain, Blt_ChainLink link) { Blt_Chain_UnlinkLink(chain, link); Blt_Free(link); } /* *--------------------------------------------------------------------------- * * Blt_Chain_Append * * Creates and new link with the given data and appends it to the end of * the chain. * * Results: * Returns a pointer to the link created. * *--------------------------------------------------------------------------- */ Blt_ChainLink Blt_Chain_Append(Blt_Chain chain, ClientData clientData) { Blt_ChainLink link; link = Blt_Chain_NewLink(); Blt_Chain_LinkAfter(chain, link, (Blt_ChainLink)NULL); Blt_Chain_SetValue(link, clientData); return link; } /* *--------------------------------------------------------------------------- * * Blt_Chain_Prepend * * Creates and new link with the given data and prepends it to beginning * of the chain. * * Results: * Returns a pointer to the link created. * *--------------------------------------------------------------------------- */ Blt_ChainLink Blt_Chain_Prepend(Blt_Chain chain, ClientData clientData) { Blt_ChainLink link; link = Blt_Chain_NewLink(); Blt_Chain_LinkBefore(chain, link, (Blt_ChainLink)NULL); Blt_Chain_SetValue(link, clientData); return link; } /* *--------------------------------------------------------------------------- * * Blt_Chain_GetNthLink -- * * Find the link at the given position in the chain. The position * is number from 0. If position is negative is returns the nth * link from the back of the chain. * * Results: * Returns the pointer to the link, if that numbered link * exists. Otherwise NULL. * *--------------------------------------------------------------------------- */ Blt_ChainLink Blt_Chain_GetNthLink(Chain *chainPtr, long position) { if (chainPtr != NULL) { if (position < 0) { ChainLink *linkPtr; int i; position = -position; for (i = 0, linkPtr = chainPtr->tail; linkPtr != NULL; linkPtr = linkPtr->prev, i++) { if (i == position) { return linkPtr; } } } else { ChainLink *linkPtr; int i; linkPtr = chainPtr->head; for (i = 0, linkPtr = chainPtr->head; linkPtr != NULL; linkPtr = linkPtr->next, i++) { if (i == position) { return linkPtr; } } } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Chain_Sort -- * * Sorts the chain according to the given comparison routine. * * Results: * None. * * Side Effects: * The chain is reordered. * *--------------------------------------------------------------------------- */ void Blt_Chain_Sort(Chain *chainPtr, Blt_ChainCompareProc *proc) { ChainLink **linkArr; ChainLink *linkPtr; long i; if (chainPtr->nLinks < 2) { return; } linkArr = Blt_Malloc(sizeof(Blt_ChainLink) * (chainPtr->nLinks + 1)); if (linkArr == NULL) { return; /* Out of memory. */ } i = 0; for (linkPtr = chainPtr->head; linkPtr != NULL; linkPtr = linkPtr->next) { linkArr[i++] = linkPtr; } qsort((char *)linkArr, chainPtr->nLinks, sizeof(Blt_ChainLink), (QSortCompareProc *)proc); /* Rethread the chain. */ linkPtr = linkArr[0]; chainPtr->head = linkPtr; linkPtr->prev = NULL; for (i = 1; i < chainPtr->nLinks; i++) { linkPtr->next = linkArr[i]; linkPtr->next->prev = linkPtr; linkPtr = linkPtr->next; } chainPtr->tail = linkPtr; linkPtr->next = NULL; Blt_Free(linkArr); } /* *--------------------------------------------------------------------------- * * Blt_Chain_IsBefore -- * * * Results: * Return boolean value if the first link comes before the second. * *--------------------------------------------------------------------------- */ int Blt_Chain_IsBefore(ChainLink *firstPtr, ChainLink *lastPtr) { ChainLink *linkPtr; for (linkPtr = firstPtr; linkPtr != NULL; linkPtr = linkPtr->next) { if (linkPtr == lastPtr) { return TRUE; } } return FALSE; } ������������������./saods9/blt3.0.1/src/bltDtVec.c��������������������������������������������������������������������0000644�0001750�0001750�00000014773�11462120062�014714� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDtVec.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <blt.h> #include "config.h" #include <assert.h> #include <tcl.h> #include <bltSwitch.h> #include <bltDataTable.h> #include <bltVector.h> extern double Blt_NaN(void); extern int Blt_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *valuePtr); DLLEXPORT extern Tcl_AppInitProc Blt_Table_VectorInit; /* * Format Import Export * csv file/data file/data * tree data data * vector data data * xml file/data file/data * sql data data * * $table import csv -file fileName -data dataString * $table export csv -file defaultFileName * $table import tree $treeName $node ?switches? * $table export tree $treeName $node "label" "label" "label" * $table import vector $vecName label $vecName label... * $table export vector label $vecName label $vecName... * $table import xml -file fileName -data dataString ?switches? * $table export xml -file fileName -data dataString ?switches? * $table import sql -host $host -password $pw -db $db -port $port */ static Blt_TableImportProc ImportVecProc; static Blt_TableExportProc ExportVecProc; /* * $table export vector -file fileName ?switches...? * $table export vector ?switches...? */ static int ExportVecProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; long nRows; if ((objc - 3) & 1) { Tcl_AppendResult(interp, "odd # of column/vector pairs: should be \"", Tcl_GetString(objv[0]), " export vector col vecName ?col vecName?...", (char *)NULL); return TCL_ERROR; } nRows = Blt_Table_NumRows(table); for (i = 3; i < objc; i += 2) { Blt_Vector *vector; size_t size; double *array; int k; Blt_TableColumn col; col = Blt_Table_FindColumn(interp, table, objv[i]); if (col == NULL) { return TCL_ERROR; } if (Blt_GetVectorFromObj(interp, objv[i+1], &vector) != TCL_OK) { return TCL_ERROR; } if (Blt_VecLength(vector) != nRows) { if (Blt_ResizeVector(vector, nRows) != TCL_OK) { return TCL_ERROR; } } array = Blt_VecData(vector); size = Blt_VecSize(vector); for (k = 1; k <= Blt_VecLength(vector); k++) { Blt_TableRow row; Tcl_Obj *objPtr; row = Blt_Table_FindRowByIndex(table, k); assert(row != NULL); objPtr = Blt_Table_GetObj(table, row, col); if (objPtr == NULL) { array[k-1] = Blt_NaN(); } else { double value; if (Blt_GetDoubleFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } array[k-1] = value; } } if (Blt_ResetVector(vector, array, nRows, size, TCL_STATIC) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ImportVecProc -- * * Parses the given command line and calls one of several * export-specific operations. * * Results: * Returns a standard TCL result. It is the result of * operation called. * * $table import vector v1 col v2 col v3 col * *--------------------------------------------------------------------------- */ static int ImportVecProc(Blt_Table table, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int maxLen; int i; if ((objc - 3) & 1) { Tcl_AppendResult(interp, "odd # of vector/column pairs: should be \"", Tcl_GetString(objv[0]), " import vector vecName col vecName col...", (char *)NULL); return TCL_ERROR; } maxLen = 0; for (i = 3; i < objc; i += 2) { Blt_TableColumn col; Blt_Vector *vector; if (Blt_GetVectorFromObj(interp, objv[i], &vector) != TCL_OK) { return TCL_ERROR; } col = Blt_Table_FindColumn(NULL, table, objv[i+1]); if (col == NULL) { const char *label; label = Tcl_GetString(objv[i+1]); col = Blt_Table_CreateColumn(interp, table, label); if (col == NULL) { return TCL_ERROR; } Blt_Table_SetColumnType(table, col, TABLE_COLUMN_TYPE_DOUBLE); } if (Blt_VecLength(vector) > maxLen) { maxLen = Blt_VecLength(vector); } } if (maxLen > Blt_Table_NumRows(table)) { size_t needed; needed = maxLen - Blt_Table_NumRows(table); if (Blt_Table_ExtendRows(interp, table, needed, NULL) != TCL_OK) { return TCL_ERROR; } } for (i = 3; i < objc; i += 2) { Blt_TableColumn col; Blt_Vector *vector; double *array; size_t j, k; size_t nElems; if (Blt_GetVectorFromObj(interp, objv[i], &vector) != TCL_OK) { return TCL_ERROR; } col = Blt_Table_FindColumn(interp, table, objv[i+1]); if (col == NULL) { return TCL_ERROR; } array = Blt_VecData(vector); nElems = Blt_VecLength(vector); for (j = 0, k = 1; j < nElems; j++, k++) { Blt_TableRow row; row = Blt_Table_FindRowByIndex(table, k); if (array[j] == Blt_NaN()) { if (Blt_Table_UnsetValue(table, row, col) != TCL_OK) { return TCL_ERROR; } } else { if (Blt_Table_SetObj(table, row, col, Tcl_NewDoubleObj(array[j])) != TCL_OK) { return TCL_ERROR; } } } } return TCL_OK; } int Blt_Table_VectorInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_datatable_vector", BLT_VERSION) != TCL_OK){ return TCL_ERROR; } return Blt_Table_RegisterFormat(interp, "vector", /* Name of format. */ ImportVecProc, /* Import procedure. */ ExportVecProc); /* Export procedure. */ } �����./saods9/blt3.0.1/src/bltFont.h���������������������������������������������������������������������0000644�0001750�0001750�00000012670�11462120062�014614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltFont.h -- * * Copyright 1993-2004 George A Howlett.v * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_FONT_H #define _BLT_FONT_H #define FONT_ITALIC (1<<0) #define FONT_BOLD (1<<1) typedef struct { int ascent; /* The amount in pixels that the tallest * letter sticks up above the baseline, plus * any extra blank space added by the designer * of the font. */ int descent; /* The largest amount in pixels that any * letter sticks below the baseline, plus any * extra blank space added by the designer of * the font. */ int linespace; /* The sum of the ascent and descent. How * far apart two lines of text in the same * font should be placed so that none of the * characters in one line overlap any of the * characters in the other line. */ int tabWidth; /* Width of tabs in this font (pixels). */ int underlinePos; /* Offset from baseline to origin of * underline bar (used for drawing underlines * on a non-underlined font). */ int underlineHeight; /* Height of underline bar (used for drawing * underlines on a non-underlined font). */ } Blt_FontMetrics; typedef struct _Blt_Font *Blt_Font; typedef struct Blt_FontClass Blt_FontClass; typedef const char *(Blt_NameOfFontProc)(Blt_Font font); typedef void (Blt_GetFontMetricsProc)(Blt_Font font, Blt_FontMetrics *metricsPtr); typedef Font (Blt_FontIdProc)(Blt_Font font); typedef int (Blt_TextStringWidthProc)(Blt_Font font, const char *string, int nBytes); typedef void (Blt_FreeFontProc)(Blt_Font font); typedef int (Blt_MeasureCharsProc)(Blt_Font font, const char *text, int nBytes, int maxLength, int flags, int *lengthPtr); typedef void (Blt_DrawCharsProc)(Display *display, Drawable drawable, GC gc, Blt_Font font, int depth, float angle, const char *text, int length, int x, int y); typedef int (Blt_PostscriptFontNameProc)(Blt_Font font, Tcl_DString *resultPtr); typedef const char *(Blt_FamilyOfFontProc)(Blt_Font font); typedef int (Blt_CanRotateFontProc)(Blt_Font font, float angle); typedef void (Blt_UnderlineCharsProc)(Display *display, Drawable drawable, GC gc, Blt_Font font, const char *text, int textLen, int x, int y, int first, int last, int xMax); struct Blt_FontClass { int type; /* Indicates the type of font used. */ Blt_NameOfFontProc *nameOfFont; Blt_FamilyOfFontProc *familyOfFont; Blt_FontIdProc *fontId; Blt_GetFontMetricsProc *getFontMetrics; Blt_MeasureCharsProc *measureChars; Blt_TextStringWidthProc *textWidth; Blt_CanRotateFontProc *canRotateFont; Blt_DrawCharsProc *drawChars; Blt_PostscriptFontNameProc *postscriptFontName; Blt_FreeFontProc *freeFont; Blt_UnderlineCharsProc *underlineChars; }; struct _Blt_Font { void *clientData; Tcl_Interp *interp; Display *display; Blt_FontClass *classPtr; }; #define Blt_NameOfFont(f) (*(f)->classPtr->nameOfFont)(f) #define Blt_FontId(f) (*(f)->classPtr->fontId)(f) #define Blt_MeasureChars(f,s,l,ml,fl,lp) \ (*(f)->classPtr->measureChars)(f,s,l,ml,fl,lp) #define Blt_DrawChars(d,w,gc,f,dp,a,t,l,x,y) \ (*(f)->classPtr->drawChars)(d,w,gc,f,dp,a,t,l,x,y) #define Blt_PostscriptFontName(f,rp) (*(f)->classPtr->postscriptFontName)(f,rp) #define Blt_FamilyOfFont(f) (*(f)->classPtr->familyOfFont)(f) #define Blt_CanRotateFont(f,a) (*(f)->classPtr->canRotateFont)(f,a) #define Blt_FreeFont(f) (*(f)->classPtr->freeFont)(f) #define Blt_UnderlineChars(d,w,g,f,s,l,x,y,a,b,m) \ (*(f)->classPtr->underlineChars)(d,w,g,f,s,l,x,y,a,b,m) BLT_EXTERN Blt_Font Blt_GetFont(Tcl_Interp *interp, Tk_Window tkwin, const char *string); BLT_EXTERN Blt_Font Blt_AllocFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN void Blt_DrawCharsWithEllipsis(Tk_Window tkwin, Drawable drawable, GC gc, Blt_Font font, int depth, float angle, const char *string, int nBytes, int x, int y, int maxLength); BLT_EXTERN Blt_Font Blt_GetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); BLT_EXTERN void Blt_GetFontMetrics(Blt_Font font, Blt_FontMetrics *fmPtr); BLT_EXTERN int Blt_TextWidth(Blt_Font font, const char *string, int length); BLT_EXTERN Tcl_Interp *Blt_GetFontInterp(Blt_Font font); #ifdef _XFT_H_ BLT_EXTERN const char *Blt_GetFontFileFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *sizePtr); BLT_EXTERN const char *Blt_GetFontFile(Tcl_Interp *interp, const char *spec, double *sizePtr); #endif /*_XFT_H_*/ #endif /* _BLT_FONT_H */ ������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacOSX.h�������������������������������������������������������������������0000644�0001750�0001750�00000003634�11462120062�015000� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSX.h -- * * Copyright 2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_MACOSX_H #define _BLT_MACOSX_H #ifdef MACOSX #define NO_CUTBUFFER 1 #define NO_DND 1 #define NO_BUSY 1 #define NO_CONTAINER 1 #endif /* #define NO_TED */ #define XFlush(display) #define XFree(data) Blt_Free(data) #include <sys/cdefs.h> #ifdef __BIG_ENDIAN__ #define WORDS_BIGENDIAN 1 #else /* !__BIG_ENDIAN__ */ /* #undef WORDS_BIGENDIAN */ #endif /* __BIG_ENDIAN__ */ #ifdef __LP64__ #define SIZEOF_FLOAT 8 #define SIZEOF_LONG 8 #define SIZEOF_INT 4 #define SIZEOF_LONG_LONG 8 #define SIZEOF_VOID_P 8 #else /* !__LP64__ */ #define SIZEOF_FLOAT 4 #define SIZEOF_LONG 4 #define SIZEOF_INT 4 #define SIZEOF_LONG_LONG 8 #define SIZEOF_VOID_P 4 #endif /* __LP64__ */ #if defined (__i386__) || defined(__x86_64__) #define HAVE_X86 1 #endif #endif /*_BLT_MACOSX_H*/ ����������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVar.h����������������������������������������������������������������������0000644�0001750�0001750�00000004265�11462120063�014440� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVar.h -- * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_VAR_H #define _BLT_VAR_H /* * The following procedures are helper routines to build TCL variables * for special variable resolvers. */ BLT_EXTERN Tcl_Var Blt_GetCachedVar(Blt_HashTable *tablePtr, const char *label, Tcl_Obj *objPtr); BLT_EXTERN void Blt_FreeCachedVars(Blt_HashTable *tablePtr); /* * The following declarations are missing from the TCL public API. */ #ifndef USE_TCL_STUBS typedef struct _Tcl_ResolvedVarInfo Tcl_ResolvedVarInfo; typedef int (Tcl_ResolveCmdProc)(Tcl_Interp* interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Command *rPtr); typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Var *rPtr); typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp* interp, const char *name, int length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr); BLT_EXTERN void Tcl_SetNamespaceResolvers(Tcl_Namespace *nsPtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); #endif #endif /* _BLT_VAR_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltGrMarker.c�����������������������������������������������������������������0000644�0001750�0001750�00000456356�11462120062�015430� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltGrMarker.c -- * * This module implements markers for the BLT graph widget. * * Copyright 1993-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltGraph.h" #include "bltOp.h" #include "bltImage.h" #include "bltPicture.h" #include "bltPainter.h" #include "bltChain.h" #include "bltGrElem.h" #include "bltBitmap.h" typedef int (GraphMarkerProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); #define GETBITMAP(b) \ (((b)->destBitmap == None) ? (b)->srcBitmap : (b)->destBitmap) #define MAX_OUTLINE_POINTS 12 #define IMAGE_PHOTO (1<<7) /* Map graph coordinates to normalized coordinates [0..1] */ #define NORMALIZE(A,x) (((x) - (A)->axisRange.min) * (A)->axisRange.scale) #define DEF_MARKER_ANCHOR "center" #define DEF_MARKER_BACKGROUND RGB_WHITE #define DEF_MARKER_BITMAP (char *)NULL #define DEF_MARKER_CAP_STYLE "butt" #define DEF_MARKER_COORDS (char *)NULL #define DEF_MARKER_DASHES (char *)NULL #define DEF_MARKER_DASH_OFFSET "0" #define DEF_MARKER_ELEMENT (char *)NULL #define DEF_MARKER_FOREGROUND RGB_BLACK #define DEF_MARKER_FILL_COLOR RGB_RED #define DEF_MARKER_FONT STD_FONT #define DEF_MARKER_GAP_COLOR RGB_PINK #define DEF_MARKER_HEIGHT "0" #define DEF_MARKER_HIDE "no" #define DEF_MARKER_JOIN_STYLE "miter" #define DEF_MARKER_JUSTIFY "left" #define DEF_MARKER_LINE_WIDTH "1" #define DEF_MARKER_MAP_X "x" #define DEF_MARKER_MAP_Y "y" #define DEF_MARKER_NAME (char *)NULL #define DEF_MARKER_OUTLINE_COLOR RGB_BLACK #define DEF_MARKER_PAD "4" #define DEF_MARKER_ANGLE "0.0" #define DEF_MARKER_SCALE "1.0" #define DEF_MARKER_STATE "normal" #define DEF_MARKER_STIPPLE (char *)NULL #define DEF_MARKER_TEXT (char *)NULL #define DEF_MARKER_UNDER "no" #define DEF_MARKER_WIDTH "0" #define DEF_MARKER_WINDOW (char *)NULL #define DEF_MARKER_XOR "no" #define DEF_MARKER_X_OFFSET "0" #define DEF_MARKER_Y_OFFSET "0" #define DEF_MARKER_FILTER "box" #define DEF_TEXT_TAGS "Text all" #define DEF_IMAGE_TAGS "Image all" #define DEF_BITMAP_TAGS "Bitmap all" #define DEF_WINDOW_TAGS "Window all" #define DEF_POLYGON_TAGS "Polygon all" #define DEF_LINE_TAGS "Line all" static Blt_OptionParseProc ObjToCoordsProc; static Blt_OptionPrintProc CoordsToObjProc; static Blt_OptionFreeProc FreeCoordsProc; static Blt_CustomOption coordsOption = { ObjToCoordsProc, CoordsToObjProc, FreeCoordsProc, (ClientData)0 }; static Blt_OptionFreeProc FreeColorPairProc; static Blt_OptionParseProc ObjToColorPairProc; static Blt_OptionPrintProc ColorPairToObjProc; static Blt_CustomOption colorPairOption = { ObjToColorPairProc, ColorPairToObjProc, FreeColorPairProc, (ClientData)0 }; static Blt_OptionParseProc ObjToPictImageProc; static Blt_OptionPrintProc PictImageToObjProc; static Blt_OptionFreeProc FreePictImageProc; static Blt_CustomOption pictImageOption = { ObjToPictImageProc, PictImageToObjProc, FreePictImageProc, (ClientData)0 }; BLT_EXTERN Blt_CustomOption bltXAxisOption; BLT_EXTERN Blt_CustomOption bltYAxisOption; BLT_EXTERN Blt_CustomOption bltFilterOption; typedef Marker *(MarkerCreateProc)(void); typedef void (MarkerDrawProc)(Marker *markerPtr, Drawable drawable); typedef void (MarkerFreeProc)(Marker *markerPtr); typedef int (MarkerConfigProc)(Marker *markerPtr); typedef void (MarkerMapProc)(Marker *markerPtr); typedef void (MarkerPostscriptProc)(Marker *markerPtr, Blt_Ps ps); typedef int (MarkerPointProc)(Marker *markerPtr, Point2d *samplePtr); typedef int (MarkerRegionProc)(Marker *markerPtr, Region2d *extsPtr, int enclosed); static Tcl_FreeProc FreeMarker; typedef struct { Blt_ConfigSpec *configSpecs; /* Marker configuration * specifications */ MarkerConfigProc *configProc; MarkerDrawProc *drawProc; MarkerFreeProc *freeProc; MarkerMapProc *mapProc; MarkerPointProc *pointProc; MarkerRegionProc *regionProc; MarkerPostscriptProc *postscriptProc; } MarkerClass; /* *--------------------------------------------------------------------------- * * Marker -- * * Structure defining the generic marker. In C++ parlance this would be * the base class from which all markers are derived. * * This structure corresponds with the specific types of markers. Don't * change this structure without changing the individual marker * structures of each type below. * * -------------------------------------------------------------------------- */ struct _Marker { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker */ int nWorldPts; /* Number of points in above array */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; }; /* *--------------------------------------------------------------------------- * * BitmapMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker. */ int nWorldPts; /* # of points in above array. */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; /* Fields specific to bitmap markers. */ Pixmap srcBitmap; /* Original bitmap. May be further * scaled or rotated. */ float reqAngle; /* Requested rotation of the bitmap */ float angle; /* Normalized rotation (0..360 * degrees) */ Tk_Anchor anchor; /* If only one X-Y coordinate is given, * indicates how to translate the given * marker position. Otherwise, if there * are two X-Y coordinates, then this * value is ignored. */ Point2d anchorPt; /* Translated anchor point. */ XColor *outlineColor; /* Foreground color */ XColor *fillColor; /* Background color */ GC gc; /* Private graphic context */ GC fillGC; /* Shared graphic context */ Pixmap destBitmap; /* Bitmap to be drawn. */ int destWidth, destHeight; /* Dimensions of the final bitmap */ Point2d outline[MAX_OUTLINE_POINTS];/* Polygon representing the background * of the bitmap. */ int nOutlinePts; } BitmapMarker; static Blt_ConfigSpec bitmapConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, Blt_Offset(BitmapMarker, anchor), 0}, {BLT_CONFIG_COLOR, "-background", "background", "Background", DEF_MARKER_BACKGROUND, Blt_Offset(BitmapMarker, fillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_BITMAP_TAGS, Blt_Offset(BitmapMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_MARKER_BITMAP, Blt_Offset(BitmapMarker, srcBitmap), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(BitmapMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(BitmapMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_MARKER_FOREGROUND, Blt_Offset(BitmapMarker, outlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(BitmapMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(BitmapMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(BitmapMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(BitmapMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_MARKER_ANGLE, Blt_Offset(BitmapMarker, reqAngle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(BitmapMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(BitmapMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(BitmapMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(BitmapMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigureBitmapProc; static MarkerCreateProc CreateBitmapProc; static MarkerDrawProc DrawBitmapProc; static MarkerFreeProc FreeBitmapProc; static MarkerMapProc MapBitmapProc; static MarkerPointProc PointInBitmapProc; static MarkerPostscriptProc BitmapToPostscriptProc; static MarkerRegionProc RegionInBitmapProc; static MarkerClass bitmapMarkerClass = { bitmapConfigSpecs, ConfigureBitmapProc, DrawBitmapProc, FreeBitmapProc, MapBitmapProc, PointInBitmapProc, RegionInBitmapProc, BitmapToPostscriptProc, }; /* *--------------------------------------------------------------------------- * * ImageMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker. */ int nWorldPts; /* # of points in above array. */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; Tk_Image tkImage; /* Tk image to be displayed. */ Tk_Anchor anchor; /* Indicates how to translate the given * marker position. */ Point2d anchorPt; /* Translated anchor point. */ int width, height; /* Dimensions of the possibly scaled * image. */ Blt_Painter painter; Blt_Picture picture; Blt_ResampleFilter filter; int pictX, pictY; /* */ Blt_Picture scaled; /* Pixmap containing the scaled image */ GC gc; } ImageMarker; static Blt_ConfigSpec imageConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, Blt_Offset(ImageMarker, anchor), 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_IMAGE_TAGS, Blt_Offset(ImageMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(ImageMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(ImageMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(ImageMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", (char *)NULL, Blt_Offset(ImageMarker, picture), BLT_CONFIG_NULL_OK, &pictImageOption}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(ImageMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(ImageMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(ImageMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-resamplefilter", "resampleFilter", "ResampleFilter", DEF_MARKER_FILTER, Blt_Offset(ImageMarker, filter), BLT_CONFIG_NULL_OK | BLT_CONFIG_DONT_SET_DEFAULT, &bltFilterOption}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(ImageMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(ImageMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(ImageMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(ImageMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigureImageProc; static MarkerCreateProc CreateImageProc; static MarkerDrawProc DrawImageProc; static MarkerFreeProc FreeImageProc; static MarkerMapProc MapImageProc; static MarkerPointProc PointInImageProc; static MarkerPostscriptProc ImageToPostscriptProc; static MarkerRegionProc RegionInImageProc; static MarkerClass imageMarkerClass = { imageConfigSpecs, ConfigureImageProc, DrawImageProc, FreeImageProc, MapImageProc, PointInImageProc, RegionInImageProc, ImageToPostscriptProc, }; /* *--------------------------------------------------------------------------- * * LineMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker. */ int nWorldPts; /* Number of points in above array */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; XColor *fillColor; XColor *outlineColor; /* Foreground and background colors */ int lineWidth; /* Line width. */ int capStyle; /* Cap style. */ int joinStyle; /* Join style.*/ Blt_Dashes dashes; /* Dash list values (max 11) */ GC gc; /* Private graphic context */ Segment2d *segments; /* Malloc'ed array of points. * Represents individual line segments * (2 points per segment) comprising the * mapped line. The segments may not * necessarily be connected after * clipping. */ int nSegments; /* # segments in the above array. */ int xor; int xorState; /* State of the XOR drawing. Indicates * if the marker is currently drawn. */ } LineMarker; static Blt_ConfigSpec lineConfigSpecs[] = { {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_LINE_TAGS, Blt_Offset(LineMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", DEF_MARKER_CAP_STYLE, Blt_Offset(LineMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(LineMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_MARKER_DASHES, Blt_Offset(LineMarker, dashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-dashoffset", "dashOffset", "DashOffset", DEF_MARKER_DASH_OFFSET, Blt_Offset(LineMarker, dashes.offset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(LineMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", (char *)NULL, Blt_Offset(LineMarker, fillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", DEF_MARKER_JOIN_STYLE, Blt_Offset(LineMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_MARKER_LINE_WIDTH, Blt_Offset(LineMarker, lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(LineMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(LineMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(LineMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(LineMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", DEF_MARKER_OUTLINE_COLOR, Blt_Offset(LineMarker, outlineColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(LineMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(LineMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(LineMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", DEF_MARKER_XOR, Blt_Offset(LineMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(LineMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigureLineProc; static MarkerCreateProc CreateLineProc; static MarkerDrawProc DrawLineProc; static MarkerFreeProc FreeLineProc; static MarkerMapProc MapLineProc; static MarkerPointProc PointInLineProc; static MarkerPostscriptProc LineToPostscriptProc; static MarkerRegionProc RegionInLineProc; static MarkerClass lineMarkerClass = { lineConfigSpecs, ConfigureLineProc, DrawLineProc, FreeLineProc, MapLineProc, PointInLineProc, RegionInLineProc, LineToPostscriptProc, }; /* *--------------------------------------------------------------------------- * * PolygonMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker. */ int nWorldPts; /* Number of points in above array */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; Point2d *screenPts; /* Array of points representing the * polygon in screen coordinates. It's * not used for drawing, but to generate * the outlinePts and fillPts arrays * that are the coordinates of the * possibly clipped outline and filled * polygon. */ ColorPair outline; ColorPair fill; Pixmap stipple; /* Stipple pattern to fill the * polygon. */ int lineWidth; /* Width of polygon outline. */ int capStyle; int joinStyle; Blt_Dashes dashes; /* List of dash values. Indicates how * to draw the dashed line. If no dash * values are provided, or the first * value is zero, then the line is drawn * solid. */ GC outlineGC; /* Graphics context to draw the outline * of the polygon. */ GC fillGC; /* Graphics context to draw the filled * polygon. */ Point2d *fillPts; /* Malloc'ed array of points used to * draw the filled polygon. These points * may form a degenerate polygon after * clipping. */ int nFillPts; /* # points in the above array. */ Segment2d *outlinePts; /* Malloc'ed array of points. * Represents individual line segments * (2 points per segment) comprising the * outline of the polygon. The segments * may not necessarily be closed or * connected after clipping. */ int nOutlinePts; /* # points in the above array. */ int xor; int xorState; /* State of the XOR drawing. Indicates * if the marker is visible. We have to * drawn it again to erase it. */ } PolygonMarker; static Blt_ConfigSpec polygonConfigSpecs[] = { {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_POLYGON_TAGS, Blt_Offset(PolygonMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", DEF_MARKER_CAP_STYLE, Blt_Offset(PolygonMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(PolygonMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_MARKER_DASHES, Blt_Offset(PolygonMarker, dashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(PolygonMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-fill", "fill", "Fill", DEF_MARKER_FILL_COLOR, Blt_Offset(PolygonMarker, fill), BLT_CONFIG_NULL_OK, &colorPairOption}, {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", DEF_MARKER_JOIN_STYLE, Blt_Offset(PolygonMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_MARKER_LINE_WIDTH, Blt_Offset(PolygonMarker, lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(PolygonMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(PolygonMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(PolygonMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(PolygonMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-outline", "outline", "Outline", DEF_MARKER_OUTLINE_COLOR, Blt_Offset(PolygonMarker, outline), BLT_CONFIG_NULL_OK, &colorPairOption}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(PolygonMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", DEF_MARKER_STIPPLE, Blt_Offset(PolygonMarker, stipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(PolygonMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(PolygonMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", DEF_MARKER_XOR, Blt_Offset(PolygonMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(PolygonMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigurePolygonProc; static MarkerCreateProc CreatePolygonProc; static MarkerDrawProc DrawPolygonProc; static MarkerFreeProc FreePolygonProc; static MarkerMapProc MapPolygonProc; static MarkerPointProc PointInPolygonProc; static MarkerPostscriptProc PolygonToPostscriptProc; static MarkerRegionProc RegionInPolygonProc; static MarkerClass polygonMarkerClass = { polygonConfigSpecs, ConfigurePolygonProc, DrawPolygonProc, FreePolygonProc, MapPolygonProc, PointInPolygonProc, RegionInPolygonProc, PolygonToPostscriptProc, }; /* *--------------------------------------------------------------------------- * * TextMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker. */ int nWorldPts; /* # of points in above array */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; /* Fields specific to text markers. */ #ifdef notdef const char *textVarName; /* Name of variable (malloc'ed) or * NULL. If non-NULL, graph displays the * contents of this variable. */ #endif const char *string; /* Text string to be display. The * string make contain newlines. */ Tk_Anchor anchor; /* Indicates how to translate the given * marker position. */ Point2d anchorPt; /* Translated anchor point. */ int width, height; /* Dimension of bounding box. */ TextStyle style; /* Text attributes (font, fg, anchor, * etc) */ Point2d outline[5]; XColor *fillColor; GC fillGC; } TextMarker; static Blt_ConfigSpec textConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, Blt_Offset(TextMarker, anchor), 0}, {BLT_CONFIG_COLOR, "-background", "background", "MarkerBackground", (char *)NULL, Blt_Offset(TextMarker, fillColor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bg", "background", "Background", (char *)NULL, 0, 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_TEXT_TAGS, Blt_Offset(TextMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(TextMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(TextMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", "Foreground", (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-fill", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_MARKER_FONT, Blt_Offset(TextMarker, style.font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_MARKER_FOREGROUND, Blt_Offset(TextMarker, style.color), 0}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_MARKER_JUSTIFY, Blt_Offset(TextMarker, style.justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(TextMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(TextMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(TextMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(TextMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PAD, "-padx", "padX", "PadX", DEF_MARKER_PAD, Blt_Offset(TextMarker, style.xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", "padY", "PadY", DEF_MARKER_PAD, Blt_Offset(TextMarker, style.yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-rotate", "rotate", "Rotate", DEF_MARKER_ANGLE, Blt_Offset(TextMarker, style.angle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(TextMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-text", "text", "Text", DEF_MARKER_TEXT, Blt_Offset(TextMarker, string), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(TextMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(TextMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(TextMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigureTextProc; static MarkerCreateProc CreateTextProc; static MarkerDrawProc DrawTextProc; static MarkerFreeProc FreeTextProc; static MarkerMapProc MapTextProc; static MarkerPointProc PointInTextProc; static MarkerPostscriptProc TextToPostscriptProc; static MarkerRegionProc RegionInTextProc; static MarkerClass textMarkerClass = { textConfigSpecs, ConfigureTextProc, DrawTextProc, FreeTextProc, MapTextProc, PointInTextProc, RegionInTextProc, TextToPostscriptProc, }; /* *--------------------------------------------------------------------------- * * WindowMarker -- * *--------------------------------------------------------------------------- */ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; Blt_HashEntry *hashPtr; Blt_ChainLink link; const char *elemName; /* Element associated with marker. Let's * you link a marker to an element. The * marker is drawn only if the element * is also visible. */ Axis2d axes; Point2d *worldPts; /* Coordinate array to position * marker */ int nWorldPts; /* # of points in above array */ int drawUnder; /* If non-zero, draw the marker * underneath any elements. This can be * a performance penalty because the * graph must be redraw entirely each * time the marker is redrawn. */ int clipped; /* Indicates if the marker is totally * clipped by the plotting area. */ unsigned int flags; int xOffset, yOffset; /* Pixel offset from graph position */ int state; /* Fields specific to window markers. */ const char *childName; /* Name of child widget. */ Tk_Window child; /* Window to display. */ int reqWidth, reqHeight; /* If non-zero, this overrides the size * requested by the child widget. */ Tk_Anchor anchor; /* Indicates how to translate the given * marker position. */ Point2d anchorPt; /* Translated anchor point. */ int width, height; /* Current size of the child window. */ } WindowMarker; static Blt_ConfigSpec windowConfigSpecs[] = { {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MARKER_ANCHOR, Blt_Offset(WindowMarker, anchor), 0}, {BLT_CONFIG_LIST, "-bindtags", "bindTags", "BindTags", DEF_WINDOW_TAGS, Blt_Offset(WindowMarker, obj.tags), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", DEF_MARKER_COORDS, Blt_Offset(WindowMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, {BLT_CONFIG_STRING, "-element", "element", "Element", DEF_MARKER_ELEMENT, Blt_Offset(WindowMarker, elemName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_POS, "-height", "height", "Height", DEF_MARKER_HEIGHT, Blt_Offset(WindowMarker, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_MARKER_HIDE, Blt_Offset(WindowMarker, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE}, {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", DEF_MARKER_MAP_X, Blt_Offset(WindowMarker, axes.x), 0, &bltXAxisOption}, {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", DEF_MARKER_MAP_Y, Blt_Offset(WindowMarker, axes.y), 0, &bltYAxisOption}, {BLT_CONFIG_STRING, "-name", (char *)NULL, (char *)NULL, DEF_MARKER_NAME, Blt_Offset(WindowMarker, obj.name), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_MARKER_STATE, Blt_Offset(WindowMarker, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", DEF_MARKER_UNDER, Blt_Offset(WindowMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_POS, "-width", "width", "Width", DEF_MARKER_WIDTH, Blt_Offset(WindowMarker, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-window", "window", "Window", DEF_MARKER_WINDOW, Blt_Offset(WindowMarker, childName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", DEF_MARKER_X_OFFSET, Blt_Offset(WindowMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", DEF_MARKER_Y_OFFSET, Blt_Offset(WindowMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static MarkerConfigProc ConfigureWindowProc; static MarkerCreateProc CreateWindowProc; static MarkerDrawProc DrawWindowProc; static MarkerFreeProc FreeWindowProc; static MarkerMapProc MapWindowProc; static MarkerPointProc PointInWindowProc; static MarkerPostscriptProc WindowToPostscriptProc; static MarkerRegionProc RegionInWindowProc; static MarkerClass windowMarkerClass = { windowConfigSpecs, ConfigureWindowProc, DrawWindowProc, FreeWindowProc, MapWindowProc, PointInWindowProc, RegionInWindowProc, WindowToPostscriptProc, }; static Tk_ImageChangedProc ImageChangedProc; #ifdef notdef static MarkerClass rectangleMarkerClass = { rectangleConfigSpecs, ConfigureRectangleProc, DrawRectangleProc, FreeRectangleProc, MapRectangleProc, PointInRectangleProc, RegionInRectangleProc, RectangleToPostscriptProc, }; static MarkerClass ovalMarkerClass = { ovalConfigSpecs, ConfigureOvalProc, DrawOvalProc, FreeOvalProc, MapOvalProc, PointInOvalProc, RegionInOvalProc, OvalToPostscriptProc, }; #endif /* *--------------------------------------------------------------------------- * * BoxesDontOverlap -- * * Tests if the bounding box of a marker overlaps the plotting area in * any way. If so, the marker will be drawn. Just do a min/max test on * the extents of both boxes. * * Note: It's assumed that the extents of the bounding box lie * within the area. So for a 10x10 rectangle, bottom and * left would be 9. * * Results: * Returns 0 is the marker is visible in the plotting area, and 1 * otherwise (marker is clipped). * *--------------------------------------------------------------------------- */ static int BoxesDontOverlap(Graph *graphPtr, Region2d *extsPtr) { assert(extsPtr->right >= extsPtr->left); assert(extsPtr->bottom >= extsPtr->top); assert(graphPtr->right >= graphPtr->left); assert(graphPtr->bottom >= graphPtr->top); return (((double)graphPtr->right < extsPtr->left) || ((double)graphPtr->bottom < extsPtr->top) || (extsPtr->right < (double)graphPtr->left) || (extsPtr->bottom < (double)graphPtr->top)); } /* *--------------------------------------------------------------------------- * * GetCoordinate -- * * Convert the expression string into a floating point value. The * only * reason we use this routine instead of Blt_ExprDouble is to * handle * "elastic" bounds. That is, convert the strings "-Inf", * "Inf" into * -(DBL_MAX) and DBL_MAX respectively. * * Results: * The return value is a standard TCL result. The value of the * expression is passed back via valuePtr. * *--------------------------------------------------------------------------- */ static int GetCoordinate( Tcl_Interp *interp, /* Interpreter to return results */ Tcl_Obj *objPtr, /* Numeric expression string to * parse */ double *valuePtr) /* Real-valued result of expression */ { char c; const char *expr; expr = Tcl_GetString(objPtr); c = expr[0]; if ((c == 'I') && (strcmp(expr, "Inf") == 0)) { *valuePtr = DBL_MAX; /* Elastic upper bound */ } else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0)) { *valuePtr = -DBL_MAX; /* Elastic lower bound */ } else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0)) { *valuePtr = DBL_MAX; /* Elastic upper bound */ } else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PrintCoordinate -- * * Convert the floating point value into its string representation. The * only reason this routine is used in instead of sprintf, is to handle * the "elastic" bounds. That is, convert the values DBL_MAX and * -(DBL_MAX) into "+Inf" and "-Inf" respectively. * * Results: * The return value is a standard TCL result. The string of the * * expression is passed back via string. * * -------------------------------------------------------------------------- */ static Tcl_Obj * PrintCoordinate(double x) { if (x == DBL_MAX) { return Tcl_NewStringObj("+Inf", -1); } else if (x == -DBL_MAX) { return Tcl_NewStringObj("-Inf", -1); } else { return Tcl_NewDoubleObj(x); } } /* *--------------------------------------------------------------------------- * * ParseCoordinates -- * * The TCL coordinate list is converted to their floating point * values. It will then replace the current marker coordinates. * * Since different marker types require different number of coordinates * this must be checked here. * * Results: * The return value is a standard TCL result. * * Side effects: * If the marker coordinates are reset, the graph is eventually redrawn * with at the new marker coordinates. * *--------------------------------------------------------------------------- */ static int ParseCoordinates( Tcl_Interp *interp, Marker *markerPtr, int objc, Tcl_Obj *const *objv) { int nWorldPts; int minArgs, maxArgs; Point2d *worldPts; int i; if (objc == 0) { return TCL_OK; } if (objc & 1) { Tcl_AppendResult(interp, "odd number of marker coordinates specified", (char *)NULL); return TCL_ERROR; } switch (markerPtr->obj.classId) { case CID_MARKER_LINE: minArgs = 4, maxArgs = 0; break; case CID_MARKER_POLYGON: minArgs = 6, maxArgs = 0; break; case CID_MARKER_WINDOW: case CID_MARKER_TEXT: minArgs = 2, maxArgs = 2; break; case CID_MARKER_IMAGE: case CID_MARKER_BITMAP: minArgs = 2, maxArgs = 4; break; default: Tcl_AppendResult(interp, "unknown marker type", (char *)NULL); return TCL_ERROR; } if (objc < minArgs) { Tcl_AppendResult(interp, "too few marker coordinates specified", (char *)NULL); return TCL_ERROR; } if ((maxArgs > 0) && (objc > maxArgs)) { Tcl_AppendResult(interp, "too many marker coordinates specified", (char *)NULL); return TCL_ERROR; } nWorldPts = objc / 2; worldPts = Blt_Malloc(nWorldPts * sizeof(Point2d)); if (worldPts == NULL) { Tcl_AppendResult(interp, "can't allocate new coordinate array", (char *)NULL); return TCL_ERROR; } { Point2d *pp; pp = worldPts; for (i = 0; i < objc; i += 2) { double x, y; if ((GetCoordinate(interp, objv[i], &x) != TCL_OK) || (GetCoordinate(interp, objv[i + 1], &y) != TCL_OK)) { Blt_Free(worldPts); return TCL_ERROR; } pp->x = x, pp->y = y, pp++; } } /* Don't free the old coordinate array until we've parsed the new * coordinates without errors. */ if (markerPtr->worldPts != NULL) { Blt_Free(markerPtr->worldPts); } markerPtr->worldPts = worldPts; markerPtr->nWorldPts = nWorldPts; markerPtr->flags |= MAP_ITEM; return TCL_OK; } /*ARGSUSED*/ static void FreeCoordsProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { Marker *markerPtr = (Marker *)widgRec; Point2d **pointsPtr = (Point2d **)(widgRec + offset); if (*pointsPtr != NULL) { Blt_Free(*pointsPtr); *pointsPtr = NULL; } markerPtr->nWorldPts = 0; } /* *--------------------------------------------------------------------------- * * ObjToCoordsProc -- * * Given a TCL list of numeric expression representing the element * values, convert into an array of floating point values. In addition, * the minimum and maximum values are saved. Since elastic values are * allow (values which translate to the min/max of the graph), we must * try to get the non-elastic minimum and maximum. * * Results: * The return value is a standard TCL result. The vector is * passed back via the vecPtr. * * -------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToCoordsProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to return results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* TCL list of numeric expressions */ char *widgRec, /* Marker record */ int offset, /* Not used. */ int flags) /* Not used. */ { Marker *markerPtr = (Marker *)widgRec; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc == 0) { return TCL_OK; } return ParseCoordinates(interp, markerPtr, objc, objv); } /* *--------------------------------------------------------------------------- * * CoordsToObjProc -- * * Convert the vector of floating point values into a TCL list. * * Results: * The string representation of the vector is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * CoordsToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Marker record */ int offset, /* Not used. */ int flags) /* Not used. */ { Marker *markerPtr = (Marker *)widgRec; Tcl_Obj *listObjPtr; Point2d *pp, *pend; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; pp < pend; pp++) { Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->x)); Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->y)); } return listObjPtr; } /*LINTLIBRARY*/ static int GetColorPair( Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *fgObjPtr, Tcl_Obj *bgObjPtr, ColorPair *pairPtr, int allowDefault) { XColor *fgColor, *bgColor; const char *string; fgColor = bgColor = NULL; if (fgObjPtr != NULL) { int length; string = Tcl_GetStringFromObj(fgObjPtr, &length); if (string[0] == '\0') { fgColor = NULL; } else if ((allowDefault) && (string[0] == 'd') && (strncmp(string, "defcolor", length) == 0)) { fgColor = COLOR_DEFAULT; } else { fgColor = Tk_AllocColorFromObj(interp, tkwin, fgObjPtr); if (fgColor == NULL) { return TCL_ERROR; } } } if (bgObjPtr != NULL) { int length; string = Tcl_GetStringFromObj(bgObjPtr, &length); if (string[0] == '\0') { bgColor = NULL; } else if ((allowDefault) && (string[0] == 'd') && (strncmp(string, "defcolor", length) == 0)) { bgColor = COLOR_DEFAULT; } else { bgColor = Tk_AllocColorFromObj(interp, tkwin, bgObjPtr); if (bgColor == NULL) { return TCL_ERROR; } } } if (pairPtr->fgColor != NULL) { Tk_FreeColor(pairPtr->fgColor); } if (pairPtr->bgColor != NULL) { Tk_FreeColor(pairPtr->bgColor); } pairPtr->fgColor = fgColor; pairPtr->bgColor = bgColor; return TCL_OK; } void Blt_FreeColorPair(ColorPair *pairPtr) { if ((pairPtr->bgColor != NULL) && (pairPtr->bgColor != COLOR_DEFAULT)) { Tk_FreeColor(pairPtr->bgColor); } if ((pairPtr->fgColor != NULL) && (pairPtr->fgColor != COLOR_DEFAULT)) { Tk_FreeColor(pairPtr->fgColor); } pairPtr->bgColor = pairPtr->fgColor = NULL; } static void FreeColorPairProc( ClientData clientData, /* Not used. */ Display *display, /* Not used. */ char *widgRec, int offset) { ColorPair *pairPtr = (ColorPair *)(widgRec + offset); Blt_FreeColorPair(pairPtr); } /* *--------------------------------------------------------------------------- * * ObjToColorPairProc -- * * Convert the color names into pair of XColor pointers. * * Results: * A standard TCL result. The color pointer is written into the * widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToColorPairProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to return results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing color */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { ColorPair *pairPtr = (ColorPair *)(widgRec + offset); long longValue = (long)clientData; int bool; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 2) { Tcl_AppendResult(interp, "too many names in colors list", (char *)NULL); return TCL_ERROR; } if (objc == 0) { Blt_FreeColorPair(pairPtr); return TCL_OK; } bool = (int)longValue; if (objc == 1) { if (GetColorPair(interp, tkwin, objv[0], NULL, pairPtr, bool) != TCL_OK) { return TCL_ERROR; } } else { if (GetColorPair(interp, tkwin, objv[0], objv[1], pairPtr, bool) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NameOfColor -- * * Convert the color option value into a string. * * Results: * The static string representing the color option is returned. * *--------------------------------------------------------------------------- */ static const char * NameOfColor(XColor *colorPtr) { if (colorPtr == NULL) { return ""; } else if (colorPtr == COLOR_DEFAULT) { return "defcolor"; } else { return Tk_NameOfColor(colorPtr); } } /* *--------------------------------------------------------------------------- * * ColorPairToObjProc -- * * Convert the color pairs into color names. * * Results: * The string representing the symbol color is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ColorPairToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Element information record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { ColorPair *pairPtr = (ColorPair *)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(NameOfColor(pairPtr->fgColor), -1)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(NameOfColor(pairPtr->bgColor), -1)); return listObjPtr; } /* *--------------------------------------------------------------------------- * * ImageChangedProc * * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Graph *graphPtr; ImageMarker *imPtr = clientData; int isPhoto; graphPtr = imPtr->obj.graphPtr; if ((imPtr->picture != NULL) && (imPtr->flags & IMAGE_PHOTO)) { Blt_FreePicture(imPtr->picture); } imPtr->picture = NULL; imPtr->flags &= ~IMAGE_PHOTO; if (Blt_Image_IsDeleted(imPtr->tkImage)) { Tk_FreeImage(imPtr->tkImage); imPtr->tkImage = NULL; return; } imPtr->picture = Blt_GetPictureFromImage(graphPtr->interp, imPtr->tkImage, &isPhoto); if (isPhoto) { imPtr->flags |= IMAGE_PHOTO; } graphPtr->flags |= CACHE_DIRTY; imPtr->flags |= MAP_ITEM; Blt_EventuallyRedrawGraph(graphPtr); } /*ARGSUSED*/ static void FreePictImageProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { ImageMarker *imPtr = (ImageMarker *)widgRec; if ((imPtr->picture != NULL) && (imPtr->flags & IMAGE_PHOTO)) { Blt_FreePicture(imPtr->picture); } imPtr->picture = NULL; if (imPtr->tkImage != NULL) { Tk_FreeImage(imPtr->tkImage); } imPtr->tkImage = NULL; imPtr->flags &= ~IMAGE_PHOTO; } /* *--------------------------------------------------------------------------- * * ObjToPictImageProc -- * * Given an image name, get the Tk image associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPictImageProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to return results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Blt_Picture *picturePtr = (Blt_Picture *)(widgRec + offset); Graph *graphPtr; ImageMarker *imPtr = (ImageMarker *)widgRec; Tk_Image tkImage; const char *name; int isPhoto; name = Tcl_GetString(objPtr); tkImage = Tk_GetImage(interp, tkwin, name, ImageChangedProc, imPtr); if (tkImage == NULL) { return TCL_ERROR; } if (imPtr->tkImage != NULL) { Tk_FreeImage(imPtr->tkImage); } imPtr->flags &= ~IMAGE_PHOTO; if (*picturePtr != NULL) { Blt_FreePicture(*picturePtr); } *picturePtr = NULL; imPtr->tkImage = tkImage; graphPtr = imPtr->obj.graphPtr; *picturePtr = Blt_GetPictureFromImage(graphPtr->interp, tkImage, &isPhoto); if (isPhoto) { imPtr->flags |= IMAGE_PHOTO; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PictImageToObjProc -- * * Convert the image name into a string Tcl_Obj. * * Results: * The string representation of the image is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PictImageToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { ImageMarker *imPtr = (ImageMarker *)(widgRec); if (imPtr->tkImage == NULL) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(Blt_Image_Name(imPtr->tkImage), -1); } static INLINE int IsElementHidden(Marker *markerPtr) { Blt_HashEntry *hPtr; Graph *graphPtr = markerPtr->obj.graphPtr; /* Look up the named element and see if it's hidden */ hPtr = Blt_FindHashEntry(&graphPtr->elements.table, markerPtr->elemName); if (hPtr != NULL) { Element *elemPtr; elemPtr = Blt_GetHashValue(hPtr); if ((elemPtr->link == NULL) || (elemPtr->flags & HIDE)) { return TRUE; } } return FALSE; } /* *--------------------------------------------------------------------------- * * HMap -- * * Maps the given graph coordinate value to its axis, returning a window * position. This is a slight variation on the normal Blt_HMap routine. * It treats -Inf as the minimum axis value and Inf as the maximum. * * Results: * Returns a floating point number representing the window coordinate * position on the given axis. * * -------------------------------------------------------------------------- */ static double HMap(Axis *axisPtr, double x) { if (x == DBL_MAX) { x = 1.0; } else if (x == -DBL_MAX) { x = 0.0; } else { if (axisPtr->logScale) { if (x > 0.0) { x = log10(x); } else if (x < 0.0) { x = 0.0; } } x = NORMALIZE(axisPtr, x); } if (axisPtr->descending) { x = 1.0 - x; } /* Horizontal transformation */ return (x * axisPtr->screenRange + axisPtr->screenMin); } /* *--------------------------------------------------------------------------- * * VMap -- * * Map the given graph coordinate value to its axis, returning a window * position. This is a slight variation on the normal Blt_VMap routine. * It treats -Inf as the minimum axis value and Inf as the maximum. * * Results: * Returns a double precision number representing the window coordinate * position on the given axis. * *--------------------------------------------------------------------------- */ static double VMap(Axis *axisPtr, double y) { if (y == DBL_MAX) { y = 1.0; } else if (y == -DBL_MAX) { y = 0.0; } else { if (axisPtr->logScale) { if (y > 0.0) { y = log10(y); } else if (y < 0.0) { y = 0.0; } } y = NORMALIZE(axisPtr, y); } if (axisPtr->descending) { y = 1.0 - y; } /* Vertical transformation. */ return (((1.0 - y) * axisPtr->screenRange) + axisPtr->screenMin); } /* *--------------------------------------------------------------------------- * * MapPoint -- * * Maps the given graph x,y coordinate values to a window position. * * Results: * Returns a XPoint structure containing the window coordinates of the * given graph x,y coordinate. * *--------------------------------------------------------------------------- */ static Point2d MapPoint( Point2d *pointPtr, /* Graph X-Y coordinate. */ Axis2d *axesPtr) /* Specifies which axes to use */ { Point2d result; Graph *graphPtr = axesPtr->y->obj.graphPtr; if (graphPtr->inverted) { result.x = HMap(axesPtr->y, pointPtr->y); result.y = VMap(axesPtr->x, pointPtr->x); } else { result.x = HMap(axesPtr->x, pointPtr->x); result.y = VMap(axesPtr->y, pointPtr->y); } return result; /* Result is screen coordinate. */ } static Marker * CreateMarker( Graph *graphPtr, const char *name, ClassId classId) { Marker *markerPtr; /* Create the new marker based upon the given type */ switch (classId) { case CID_MARKER_BITMAP: markerPtr = CreateBitmapProc(); /* bitmap */ break; case CID_MARKER_LINE: markerPtr = CreateLineProc(); /* line */ break; case CID_MARKER_IMAGE: markerPtr = CreateImageProc(); /* image */ break; case CID_MARKER_TEXT: markerPtr = CreateTextProc(); /* text */ break; case CID_MARKER_POLYGON: markerPtr = CreatePolygonProc(); /* polygon */ break; case CID_MARKER_WINDOW: markerPtr = CreateWindowProc(); /* window */ break; default: return NULL; } markerPtr->obj.graphPtr = graphPtr; markerPtr->drawUnder = FALSE; markerPtr->flags |= MAP_ITEM; markerPtr->obj.name = Blt_AssertStrdup(name); Blt_GraphSetObjectClass(&markerPtr->obj, classId); return markerPtr; } static void DestroyMarker(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; if (markerPtr->drawUnder) { /* If the marker to be deleted is currently displayed below the * elements, then backing store needs to be repaired. */ graphPtr->flags |= CACHE_DIRTY; } /* * Call the marker's type-specific deallocation routine. We do it first * while all the marker fields are still valid. */ (*markerPtr->classPtr->freeProc)(markerPtr); /* Dump any bindings that might be registered for the marker. */ Blt_DeleteBindings(graphPtr->bindTable, markerPtr); /* Release all the X resources associated with the marker. */ Blt_FreeOptions(markerPtr->classPtr->configSpecs, (char *)markerPtr, graphPtr->display, 0); if (markerPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&graphPtr->markers.table, markerPtr->hashPtr); } if (markerPtr->link != NULL) { Blt_Chain_DeleteLink(graphPtr->markers.displayList, markerPtr->link); } if (markerPtr->obj.name != NULL) { Blt_Free(markerPtr->obj.name); } Blt_Free(markerPtr); } static void FreeMarker(DestroyData dataPtr) { Marker *markerPtr = (Marker *)dataPtr; DestroyMarker(markerPtr); } /* *--------------------------------------------------------------------------- * * ConfigureBitmapProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a bitmap * marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as bitmap pixmap, colors, rotation, * etc. get set for markerPtr; old resources get freed, if there were * any. The marker is eventually redisplayed. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ConfigureBitmapProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; if (bmPtr->srcBitmap == None) { return TCL_OK; } bmPtr->angle = FMOD(bmPtr->reqAngle, 360.0); if (bmPtr->angle < 0.0) { bmPtr->angle += 360.0; } gcMask = 0; if (bmPtr->outlineColor != NULL) { gcMask |= GCForeground; gcValues.foreground = bmPtr->outlineColor->pixel; } if (bmPtr->fillColor != NULL) { /* Opaque bitmap: both foreground and background (fill) colors * are used. */ gcValues.background = bmPtr->fillColor->pixel; gcMask |= GCBackground; } else { /* Transparent bitmap: set the clip mask to the current bitmap. */ gcValues.clip_mask = bmPtr->srcBitmap; gcMask |= GCClipMask; } /* * This is technically a shared GC, but we're going to set/change the clip * origin anyways before we draw the bitmap. This relies on the fact that * no other client will be allocated this GC with the GCClipMask set to * this particular bitmap. */ newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (bmPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, bmPtr->gc); } bmPtr->gc = newGC; /* Create the background GC containing the fill color. */ if (bmPtr->fillColor != NULL) { gcValues.foreground = bmPtr->fillColor->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (bmPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, bmPtr->fillGC); } bmPtr->fillGC = newGC; } markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } #ifdef notdef static void PrintPolyPoint(char *mesg, Point2d *points, int nPoints) { int i; fprintf(stderr, "%s:\t\tpoint[0]=%g,%g\n", mesg, points[0].x, points[0].y); for (i = 1; i < nPoints; i++) { fprintf(stderr, "\t\tpoint[%d]=%g,%g\n", i, points[i].x, points[i].y); } } #endif /* *--------------------------------------------------------------------------- * * MapBitmapProc -- * * This procedure gets called each time the layout of the graph changes. * The x, y window coordinates of the bitmap marker are saved in the * marker structure. * * Additionly, if no background color was specified, the * GCTileStipXOrigin and GCTileStipYOrigin attributes are set in the * private GC. * * Results: * None. * * Side effects: * Window coordinates are saved and if no background color was set, the * GC stipple origins are changed to calculated window coordinates. * *--------------------------------------------------------------------------- */ static void MapBitmapProc(Marker *markerPtr) { BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; Region2d extents; Graph *graphPtr = markerPtr->obj.graphPtr; Point2d anchorPt; Point2d corner1, corner2; int destWidth, destHeight; int srcWidth, srcHeight; int i; if (bmPtr->srcBitmap == None) { return; } if (bmPtr->destBitmap != None) { Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap); bmPtr->destBitmap = None; } /* * Collect the coordinates. The number of coordinates will determine the * calculations to be made. * * x1 y1 A single pair of X-Y coordinates. They represent * the anchor position of the bitmap. * * x1 y1 x2 y2 Two pairs of X-Y coordinates. They represent * two opposite corners of a bounding rectangle. The * bitmap is possibly rotated and scaled to fit into * this box. * */ Tk_SizeOfBitmap(graphPtr->display, bmPtr->srcBitmap, &srcWidth, &srcHeight); corner1 = MapPoint(markerPtr->worldPts, &markerPtr->axes); if (markerPtr->nWorldPts > 1) { double hold; corner2 = MapPoint(markerPtr->worldPts + 1, &markerPtr->axes); /* Flip the corners if necessary */ if (corner1.x > corner2.x) { hold = corner1.x, corner1.x = corner2.x, corner2.x = hold; } if (corner1.y > corner2.y) { hold = corner1.y, corner1.y = corner2.y, corner2.y = hold; } } else { corner2.x = corner1.x + srcWidth - 1; corner2.y = corner1.y + srcHeight - 1; } destWidth = (int)(corner2.x - corner1.x) + 1; destHeight = (int)(corner2.y - corner1.y) + 1; if (markerPtr->nWorldPts == 1) { anchorPt = Blt_AnchorPoint(corner1.x, corner1.y, (double)destWidth, (double)destHeight, bmPtr->anchor); } else { anchorPt = corner1; } anchorPt.x += markerPtr->xOffset; anchorPt.y += markerPtr->yOffset; /* Check if the bitmap sits at least partially in the plot area. */ extents.left = anchorPt.x; extents.top = anchorPt.y; extents.right = anchorPt.x + destWidth - 1; extents.bottom = anchorPt.y + destHeight - 1; markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents); if (markerPtr->clipped) { return; /* Bitmap is offscreen. Don't generate * rotated or scaled bitmaps. */ } /* * Scale the bitmap if necessary. It's a little tricky because we only * want to scale what's visible on the screen, not the entire bitmap. */ if ((bmPtr->angle != 0.0f) || (destWidth != srcWidth) || (destHeight != srcHeight)) { int regionX, regionY, regionWidth, regionHeight; double left, right, top, bottom; /* Ignore parts of the bitmap outside of the plot area. */ left = MAX(graphPtr->left, extents.left); right = MIN(graphPtr->right, extents.right); top = MAX(graphPtr->top, extents.top); bottom = MIN(graphPtr->bottom, extents.bottom); /* Determine the portion of the scaled bitmap to display. */ regionX = regionY = 0; if (graphPtr->left > extents.left) { regionX = (int)(graphPtr->left - extents.left); } if (graphPtr->top > extents.top) { regionY = (int)(graphPtr->top - extents.top); } regionWidth = (int)(right - left) + 1; regionHeight = (int)(bottom - top) + 1; anchorPt.x = left; anchorPt.y = top; bmPtr->destBitmap = Blt_ScaleRotateBitmapArea(graphPtr->tkwin, bmPtr->srcBitmap, srcWidth, srcHeight, regionX, regionY, regionWidth, regionHeight, destWidth, destHeight, bmPtr->angle); bmPtr->destWidth = regionWidth; bmPtr->destHeight = regionHeight; } else { bmPtr->destWidth = srcWidth; bmPtr->destHeight = srcHeight; bmPtr->destBitmap = None; } bmPtr->anchorPt = anchorPt; { double xScale, yScale; double tx, ty; double rotWidth, rotHeight; Point2d polygon[5]; int n; /* * Compute a polygon to represent the background area of the bitmap. * This is needed for backgrounds of arbitrarily rotated bitmaps. We * also use it to print a background in PostScript. */ Blt_GetBoundingBox(srcWidth, srcHeight, bmPtr->angle, &rotWidth, &rotHeight, polygon); xScale = (double)destWidth / rotWidth; yScale = (double)destHeight / rotHeight; /* * Adjust each point of the polygon. Both scale it to the new size and * translate it to the actual screen position of the bitmap. */ tx = extents.left + destWidth * 0.5; ty = extents.top + destHeight * 0.5; for (i = 0; i < 4; i++) { polygon[i].x = (polygon[i].x * xScale) + tx; polygon[i].y = (polygon[i].y * yScale) + ty; } Blt_GraphExtents(graphPtr, &extents); n = Blt_PolyRectClip(&extents, polygon, 4, bmPtr->outline); assert(n <= MAX_OUTLINE_POINTS); if (n < 3) { memcpy(&bmPtr->outline, polygon, sizeof(Point2d) * 4); bmPtr->nOutlinePts = 4; } else { bmPtr->nOutlinePts = n; } } } /* *--------------------------------------------------------------------------- * * PointInBitmapProc -- * * Indicates if the given point is over the bitmap marker. The area of * the bitmap is the rectangle. * * Results: * Returns 1 is the point is over the bitmap marker, 0 otherwise. * *--------------------------------------------------------------------------- */ static int PointInBitmapProc(Marker *markerPtr, Point2d *samplePtr) { BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; if (bmPtr->srcBitmap == None) { return 0; } if (bmPtr->angle != 0.0f) { Point2d points[MAX_OUTLINE_POINTS]; int i; /* * Generate the bounding polygon (isolateral) for the bitmap and see * if the point is inside of it. */ for (i = 0; i < bmPtr->nOutlinePts; i++) { points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x; points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y; } return Blt_PointInPolygon(samplePtr, points, bmPtr->nOutlinePts); } return ((samplePtr->x >= bmPtr->anchorPt.x) && (samplePtr->x < (bmPtr->anchorPt.x + bmPtr->destWidth)) && (samplePtr->y >= bmPtr->anchorPt.y) && (samplePtr->y < (bmPtr->anchorPt.y + bmPtr->destHeight))); } /* *--------------------------------------------------------------------------- * * RegionInBitmapProc -- * *--------------------------------------------------------------------------- */ static int RegionInBitmapProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) { BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; if (markerPtr->nWorldPts < 1) { return FALSE; } if (bmPtr->angle != 0.0f) { Point2d points[MAX_OUTLINE_POINTS]; int i; /* * Generate the bounding polygon (isolateral) for the bitmap and see * if the point is inside of it. */ for (i = 0; i < bmPtr->nOutlinePts; i++) { points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x; points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y; } return Blt_RegionInPolygon(extsPtr, points, bmPtr->nOutlinePts, enclosed); } if (enclosed) { return ((bmPtr->anchorPt.x >= extsPtr->left) && (bmPtr->anchorPt.y >= extsPtr->top) && ((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->right) && ((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->bottom)); } return !((bmPtr->anchorPt.x >= extsPtr->right) || (bmPtr->anchorPt.y >= extsPtr->bottom) || ((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->left) || ((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->top)); } /* *--------------------------------------------------------------------------- * * DrawBitmapProc -- * * Draws the bitmap marker that have a transparent of filled background. * * Results: * None. * * Side effects: * GC stipple origins are changed to current window coordinates. * Commands are output to X to draw the marker in its current mode. * *--------------------------------------------------------------------------- */ static void DrawBitmapProc(Marker *markerPtr, Drawable drawable) { Graph *graphPtr = markerPtr->obj.graphPtr; BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; double rangle; Pixmap bitmap; bitmap = GETBITMAP(bmPtr); if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1)) { return; } rangle = FMOD(bmPtr->angle, 90.0); if ((bmPtr->fillColor == NULL) || (rangle != 0.0)) { /* * If the bitmap is rotated and a filled background is required, then * a filled polygon is drawn before the bitmap. */ if (bmPtr->fillColor != NULL) { int i; XPoint polygon[MAX_OUTLINE_POINTS]; for (i = 0; i < bmPtr->nOutlinePts; i++) { polygon[i].x = (short int)bmPtr->outline[i].x; polygon[i].y = (short int)bmPtr->outline[i].y; } XFillPolygon(graphPtr->display, drawable, bmPtr->fillGC, polygon, bmPtr->nOutlinePts, Convex, CoordModeOrigin); } XSetClipMask(graphPtr->display, bmPtr->gc, bitmap); XSetClipOrigin(graphPtr->display, bmPtr->gc, (int)bmPtr->anchorPt.x, (int)bmPtr->anchorPt.y); } else { XSetClipMask(graphPtr->display, bmPtr->gc, None); XSetClipOrigin(graphPtr->display, bmPtr->gc, 0, 0); } XCopyPlane(graphPtr->display, bitmap, drawable, bmPtr->gc, 0, 0, bmPtr->destWidth, bmPtr->destHeight, (int)bmPtr->anchorPt.x, (int)bmPtr->anchorPt.y, 1); } /* *--------------------------------------------------------------------------- * * BitmapToPostscriptProc -- * * Generates PostScript to print a bitmap marker. * * Results: * None. * *--------------------------------------------------------------------------- */ static void BitmapToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { Graph *graphPtr = markerPtr->obj.graphPtr; BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; Pixmap bitmap; bitmap = GETBITMAP(bmPtr); if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1)) { return; /* No bitmap to display. */ } if (bmPtr->fillColor != NULL) { Blt_Ps_XSetBackground(ps, bmPtr->fillColor); Blt_Ps_XFillPolygon(ps, bmPtr->outline, 4); } Blt_Ps_XSetForeground(ps, bmPtr->outlineColor); Blt_Ps_Format(ps, " gsave\n %g %g translate\n %d %d scale\n", bmPtr->anchorPt.x, bmPtr->anchorPt.y + bmPtr->destHeight, bmPtr->destWidth, -bmPtr->destHeight); Blt_Ps_Format(ps, " %d %d true [%d 0 0 %d 0 %d] {", bmPtr->destWidth, bmPtr->destHeight, bmPtr->destWidth, -bmPtr->destHeight, bmPtr->destHeight); Blt_Ps_XSetBitmapData(ps, graphPtr->display, bitmap, bmPtr->destWidth, bmPtr->destHeight); Blt_Ps_VarAppend(ps, " } imagemask\n", "grestore\n", (char *)NULL); } /* *--------------------------------------------------------------------------- * * FreeBitmapProc -- * * Releases the memory and attributes of the bitmap marker. * * Results: * None. * * Side effects: * Bitmap attributes (GCs, colors, bitmap, etc) get destroyed. Memory is * released, X resources are freed, and the graph is redrawn. * *--------------------------------------------------------------------------- */ static void FreeBitmapProc(Marker *markerPtr) { BitmapMarker *bmPtr = (BitmapMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; if (bmPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, bmPtr->gc); } if (bmPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, bmPtr->fillGC); } if (bmPtr->destBitmap != None) { Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap); } } /* *--------------------------------------------------------------------------- * * CreateBitmapProc -- * * Allocate memory and initialize methods for the new bitmap marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the bitmap marker structure. * *--------------------------------------------------------------------------- */ static Marker * CreateBitmapProc(void) { BitmapMarker *bmPtr; bmPtr = Blt_AssertCalloc(1, sizeof(BitmapMarker)); bmPtr->classPtr = &bitmapMarkerClass; return (Marker *)bmPtr; } /* *--------------------------------------------------------------------------- * * ConfigureImageProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a image * marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as image pixmap, colors, rotation, * etc. get set for markerPtr; old resources get freed, if there were * any. The marker is eventually redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureImageProc(Marker *markerPtr) { ImageMarker *imPtr = (ImageMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; Blt_Painter painter; GC newGC; newGC = Tk_GetGC(graphPtr->tkwin, 0L, (XGCValues *)NULL); if (imPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, imPtr->gc); } imPtr->gc = newGC; painter = Blt_GetPainter(graphPtr->tkwin, 1.0); if (imPtr->painter != NULL) { Blt_FreePainter(painter); } imPtr->painter = painter; markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MapImageProc -- * * This procedure gets called each time the layout of the graph changes. * The x, y window coordinates of the image marker are saved in the * marker structure. * * In addition, if no background color was specified, the * GCTileStipXOrigin and GCTileStipYOrigin attributes will not set in the * private GC. * * Results: * None. * * Side effects: * Window coordinates are saved and if no background color was set, the * GC stipple origins are changed to calculated window coordinates. * *--------------------------------------------------------------------------- */ static void MapImageProc(Marker *markerPtr) { Region2d extents; Graph *graphPtr; ImageMarker *imPtr; Point2d anchorPt; Point2d c1, c2; int newWidth, newHeight; int srcWidth, srcHeight; int x, y, w, h; int left, right, top, bottom; imPtr = (ImageMarker *)markerPtr; if (imPtr->picture == NULL) { return; } if (imPtr->scaled != NULL) { Blt_FreePicture(imPtr->scaled); imPtr->scaled = NULL; } graphPtr = markerPtr->obj.graphPtr; c1 = MapPoint(markerPtr->worldPts, &markerPtr->axes); imPtr->width = srcWidth = Blt_PictureWidth(imPtr->picture); imPtr->height = srcHeight = Blt_PictureHeight(imPtr->picture); if ((srcWidth == 0) || (srcHeight == 0)) { markerPtr->clipped = TRUE; return; /* Empty image. */ } if (markerPtr->nWorldPts > 1) { double hold; c2 = MapPoint(markerPtr->worldPts + 1, &markerPtr->axes); /* Flip the corners if necessary */ if (c1.x > c2.x) { hold = c1.x, c1.x = c2.x, c2.x = hold; } if (c1.y > c2.y) { hold = c1.y, c1.y = c2.y, c2.y = hold; } } else { c2.x = c1.x + srcWidth - 1; c2.y = c1.y + srcHeight - 1; } newWidth = (int)(c2.x - c1.x) + 1; newHeight = (int)(c2.y - c1.y) + 1; if (markerPtr->nWorldPts == 1) { anchorPt = Blt_AnchorPoint(c1.x, c1.y, (double)newWidth, (double)newHeight, imPtr->anchor); } else { anchorPt = c1; } anchorPt.x += markerPtr->xOffset; anchorPt.y += markerPtr->yOffset; /* Check if the image sits at least partially in the plot area. */ extents.left = anchorPt.x; extents.top = anchorPt.y; extents.right = anchorPt.x + newWidth - 1; extents.bottom = anchorPt.y + newHeight - 1; markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents); if (markerPtr->clipped) { return; /* Image is offscreen. Don't generate * rotated or scaled images. */ } /* Determine the extents of the subimage inside of the destination * image. */ left = MAX((int)extents.left, graphPtr->left); top = MAX((int)extents.top, graphPtr->top); right = MIN((int)extents.right, graphPtr->right); bottom = MIN((int)extents.bottom, graphPtr->bottom); /* Reset image location and coordinates to that of the region */ anchorPt.x = left; anchorPt.y = top; x = y = 0; if (graphPtr->left > (int)extents.left) { x = graphPtr->left - (int)extents.left; } if (graphPtr->top > (int)extents.top) { y = graphPtr->top - (int)extents.top; } w = (int)(right - left + 1); h = (int)(bottom - top + 1); if (markerPtr->nWorldPts > 1) { Blt_Picture scaled; scaled = Blt_ScalePictureArea(imPtr->picture, x, y, w, h, newWidth, newHeight); imPtr->scaled = scaled; imPtr->pictX = 0; imPtr->pictY = 0; } else { imPtr->pictX = x; imPtr->pictY = y; } imPtr->width = newWidth; imPtr->height = newHeight; imPtr->anchorPt = anchorPt; } /* *--------------------------------------------------------------------------- * * PointInWindowProc -- * * Indicates if the given point is over the window marker. The area of * the window is the rectangle. * * Results: * Returns 1 is the point is over the window marker, 0 otherwise. * *--------------------------------------------------------------------------- */ static int PointInImageProc(Marker *markerPtr, Point2d *samplePtr) { ImageMarker *imPtr = (ImageMarker *)markerPtr; double left, right, top, bottom; left = imPtr->anchorPt.x; right = imPtr->anchorPt.x + imPtr->width; top = imPtr->anchorPt.y; bottom = imPtr->anchorPt.y + imPtr->height; return ((samplePtr->x >= left) && (samplePtr->x < right) && (samplePtr->y >= top) && (samplePtr->y < bottom)); } /* *--------------------------------------------------------------------------- * * RegionInImageProc -- * *--------------------------------------------------------------------------- */ static int RegionInImageProc(Marker *markerPtr, Region2d *regPtr, int enclosed) { ImageMarker *imPtr = (ImageMarker *)markerPtr; if (markerPtr->nWorldPts > 0) { double left, right, top, bottom; left = imPtr->anchorPt.x; right = imPtr->anchorPt.x + imPtr->width; top = imPtr->anchorPt.y; bottom = imPtr->anchorPt.y + imPtr->height; if (enclosed) { return ((left >= regPtr->left) && (top >= regPtr->top) && (right <= regPtr->right) && (bottom <= regPtr->bottom)); } return !((left >= regPtr->right) || (top >= regPtr->bottom) || (right <= regPtr->left) || (bottom <= regPtr->top)); } return FALSE; } /* *--------------------------------------------------------------------------- * * DrawImageProc -- * * This procedure is invoked to draw a image marker. * * Results: * None. * * Side effects: * GC stipple origins are changed to current window coordinates. * Commands are output to X to draw the marker in its current mode. * *--------------------------------------------------------------------------- */ static void DrawImageProc(Marker *markerPtr, Drawable drawable) { ImageMarker *imPtr = (ImageMarker *)markerPtr; Blt_Picture picture; picture = (imPtr->scaled != NULL) ? imPtr->scaled : imPtr->picture; if (picture != NULL) { Blt_PaintPictureWithBlend(imPtr->painter, drawable, picture, imPtr->pictX, imPtr->pictY, imPtr->width, imPtr->height, (int)imPtr->anchorPt.x, (int)imPtr->anchorPt.y, 0, 0.4); } } /* *--------------------------------------------------------------------------- * * ImageToPostscriptProc -- * * This procedure is invoked to print a image marker. * * Results: * None. * *--------------------------------------------------------------------------- */ static void ImageToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { ImageMarker *imPtr = (ImageMarker *)markerPtr; Blt_Picture picture; picture = (imPtr->scaled != NULL) ? imPtr->scaled : imPtr->picture; if (picture != NULL) { Blt_Ps_DrawPicture(ps, picture, imPtr->anchorPt.x, imPtr->anchorPt.y); } } /* *--------------------------------------------------------------------------- * * FreeImageProc -- * * Destroys the structure containing the attributes of the image marker. * * Results: * None. * * Side effects: * Image attributes (GCs, colors, image, etc) get destroyed. Memory is * released, X resources are freed, and the graph is redrawn. * *--------------------------------------------------------------------------- */ static void FreeImageProc(Marker *markerPtr) { ImageMarker *imPtr = (ImageMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; if (imPtr->painter != NULL) { Blt_FreePainter(imPtr->painter); } if (imPtr->scaled != NULL) { Blt_FreePicture(imPtr->scaled); } if (imPtr->gc != NULL) { Tk_FreeGC(graphPtr->display, imPtr->gc); } } /* *--------------------------------------------------------------------------- * * CreateImageProc -- * * Allocate memory and initialize methods for the new image marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the image marker structure. * *--------------------------------------------------------------------------- */ static Marker * CreateImageProc(void) { ImageMarker *imPtr; imPtr = Blt_AssertCalloc(1, sizeof(ImageMarker)); imPtr->classPtr = &imageMarkerClass; return (Marker *)imPtr; } /* *--------------------------------------------------------------------------- * * ConfigureTextProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a text marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for markerPtr; old resources get freed, if there were any. The * marker is eventually redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureTextProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; TextMarker *tmPtr = (TextMarker *)markerPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; tmPtr->style.angle = (float)FMOD(tmPtr->style.angle, 360.0); if (tmPtr->style.angle < 0.0f) { tmPtr->style.angle += 360.0f; } newGC = NULL; if (tmPtr->fillColor != NULL) { gcMask = GCForeground; gcValues.foreground = tmPtr->fillColor->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); } if (tmPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, tmPtr->fillGC); } tmPtr->fillGC = newGC; markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MapTextProc -- * * Calculate the layout position for a text marker. Positional information * is saved in the marker. If the text is rotated, a bitmap containing the * text is created. * * Results: * None. * * Side effects: * If no background color has been specified, the GC stipple origins are * changed to current window coordinates. For both rotated and * non-rotated text, if any old bitmap is leftover, it is freed. * *--------------------------------------------------------------------------- */ static void MapTextProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; TextMarker *tmPtr = (TextMarker *)markerPtr; Region2d extents; Point2d anchorPt; int i; unsigned int w, h; double rw, rh; tmPtr->width = tmPtr->height = 0; if (tmPtr->string == NULL) { return; } Blt_Ts_GetExtents(&tmPtr->style, tmPtr->string, &w, &h); Blt_GetBoundingBox(w, h, tmPtr->style.angle, &rw, &rh, tmPtr->outline); tmPtr->width = ROUND(rw); tmPtr->height = ROUND(rh); for (i = 0; i < 4; i++) { tmPtr->outline[i].x += ROUND(rw * 0.5); tmPtr->outline[i].y += ROUND(rh * 0.5); } tmPtr->outline[4].x = tmPtr->outline[0].x; tmPtr->outline[4].y = tmPtr->outline[0].y; anchorPt = MapPoint(markerPtr->worldPts, &markerPtr->axes); anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, (double)(tmPtr->width), (double)(tmPtr->height), tmPtr->anchor); anchorPt.x += markerPtr->xOffset; anchorPt.y += markerPtr->yOffset; /* * Determine the bounding box of the text and test to see if it is at * least partially contained within the plotting area. */ extents.left = anchorPt.x; extents.top = anchorPt.y; extents.right = anchorPt.x + tmPtr->width - 1; extents.bottom = anchorPt.y + tmPtr->height - 1; markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents); tmPtr->anchorPt = anchorPt; } static int PointInTextProc(Marker *markerPtr, Point2d *samplePtr) { TextMarker *tmPtr = (TextMarker *)markerPtr; if (tmPtr->string == NULL) { return 0; } if (tmPtr->style.angle != 0.0f) { Point2d points[5]; int i; /* * Figure out the bounding polygon (isolateral) for the text and see * if the point is inside of it. */ for (i = 0; i < 5; i++) { points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x; points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y; } return Blt_PointInPolygon(samplePtr, points, 5); } return ((samplePtr->x >= tmPtr->anchorPt.x) && (samplePtr->x < (tmPtr->anchorPt.x + tmPtr->width)) && (samplePtr->y >= tmPtr->anchorPt.y) && (samplePtr->y < (tmPtr->anchorPt.y + tmPtr->height))); } /* *--------------------------------------------------------------------------- * * RegionInTextProc -- * *--------------------------------------------------------------------------- */ static int RegionInTextProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) { TextMarker *tmPtr = (TextMarker *)markerPtr; if (markerPtr->nWorldPts < 1) { return FALSE; } if (tmPtr->style.angle != 0.0f) { Point2d points[5]; int i; /* * Generate the bounding polygon (isolateral) for the bitmap and see * if the point is inside of it. */ for (i = 0; i < 4; i++) { points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x; points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y; } return Blt_RegionInPolygon(extsPtr, points, 4, enclosed); } if (enclosed) { return ((tmPtr->anchorPt.x >= extsPtr->left) && (tmPtr->anchorPt.y >= extsPtr->top) && ((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->right) && ((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->bottom)); } return !((tmPtr->anchorPt.x >= extsPtr->right) || (tmPtr->anchorPt.y >= extsPtr->bottom) || ((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->left) || ((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->top)); } /* *--------------------------------------------------------------------------- * * DrawTextProc -- * * Draws the text marker on the graph. * * Results: * None. * * Side effects: * Commands are output to X to draw the marker in its current mode. * *--------------------------------------------------------------------------- */ static void DrawTextProc(Marker *markerPtr, Drawable drawable) { TextMarker *tmPtr = (TextMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; if (tmPtr->string == NULL) { return; } if (tmPtr->fillGC != NULL) { XPoint points[4]; int i; /* * Simulate the rotated background of the bitmap by filling a bounding * polygon with the background color. */ for (i = 0; i < 4; i++) { points[i].x = (short int)(tmPtr->outline[i].x + tmPtr->anchorPt.x); points[i].y = (short int)(tmPtr->outline[i].y + tmPtr->anchorPt.y); } XFillPolygon(graphPtr->display, drawable, tmPtr->fillGC, points, 4, Convex, CoordModeOrigin); } if (tmPtr->style.color != NULL) { Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1, &tmPtr->style, (int)tmPtr->anchorPt.x, (int)tmPtr->anchorPt.y); } } /* *--------------------------------------------------------------------------- * * TextToPostscriptProc -- * * Outputs PostScript commands to draw a text marker at a given x,y * coordinate, rotation, anchor, and font. * * Results: * None. * * Side effects: * PostScript font and color settings are changed. * *--------------------------------------------------------------------------- */ static void TextToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { TextMarker *tmPtr = (TextMarker *)markerPtr; if (tmPtr->string == NULL) { return; } if (tmPtr->fillGC != NULL) { Point2d points[4]; int i; /* * Simulate the rotated background of the bitmap by filling a bounding * polygon with the background color. */ for (i = 0; i < 4; i++) { points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x; points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y; } Blt_Ps_XSetBackground(ps, tmPtr->fillColor); Blt_Ps_XFillPolygon(ps, points, 4); } Blt_Ps_DrawText(ps, tmPtr->string, &tmPtr->style, tmPtr->anchorPt.x, tmPtr->anchorPt.y); } /* *--------------------------------------------------------------------------- * * FreeTextProc -- * * Destroys the structure containing the attributes of the text marker. * * Results: * None. * * Side effects: * Text attributes (GCs, colors, stipple, font, etc) get destroyed. * Memory is released, X resources are freed, and the graph is redrawn. * *--------------------------------------------------------------------------- */ static void FreeTextProc(Marker *markerPtr) { TextMarker *tmPtr = (TextMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; Blt_Ts_FreeStyle(graphPtr->display, &tmPtr->style); } /* *--------------------------------------------------------------------------- * CreateTextProc -- * * Allocate memory and initialize methods for the new text marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the text marker structure. * *--------------------------------------------------------------------------- */ static Marker * CreateTextProc(void) { TextMarker *tmPtr; tmPtr = Blt_AssertCalloc(1, sizeof(TextMarker)); tmPtr->classPtr = &textMarkerClass; Blt_Ts_InitStyle(tmPtr->style); tmPtr->style.anchor = TK_ANCHOR_NW; tmPtr->style.padLeft = tmPtr->style.padRight = 4; tmPtr->style.padTop = tmPtr->style.padBottom = 4; return (Marker *)tmPtr; } static Tk_EventProc ChildEventProc; static Tk_GeomRequestProc ChildGeometryProc; static Tk_GeomLostSlaveProc ChildCustodyProc; static Tk_GeomMgr winMarkerMgrInfo = { (char *)"graph", /* Name of geometry manager used by * winfo */ ChildGeometryProc, /* Procedure to for new geometry * requests. */ ChildCustodyProc, /* Procedure when window is taken * away. */ }; /* *--------------------------------------------------------------------------- * * ConfigureWindowProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a window * marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as window pathname, placement, * etc. get set for markerPtr; old resources get freed, if there were * any. The marker is eventually redisplayed. * *--------------------------------------------------------------------------- */ static int ConfigureWindowProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; WindowMarker *wmPtr = (WindowMarker *)markerPtr; Tk_Window tkwin; if (wmPtr->childName == NULL) { return TCL_OK; } tkwin = Tk_NameToWindow(graphPtr->interp, wmPtr->childName, graphPtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_Parent(tkwin) != graphPtr->tkwin) { Tcl_AppendResult(graphPtr->interp, "\"", wmPtr->childName, "\" is not a child of \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (tkwin != wmPtr->child) { if (wmPtr->child != NULL) { Tk_DeleteEventHandler(wmPtr->child, StructureNotifyMask, ChildEventProc, wmPtr); Tk_ManageGeometry(wmPtr->child, (Tk_GeomMgr *) 0, (ClientData)0); Tk_UnmapWindow(wmPtr->child); } Tk_CreateEventHandler(tkwin, StructureNotifyMask, ChildEventProc, wmPtr); Tk_ManageGeometry(tkwin, &winMarkerMgrInfo, wmPtr); } wmPtr->child = tkwin; markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MapWindowProc -- * * Calculate the layout position for a window marker. Positional * information is saved in the marker. * * Results: * None. * *--------------------------------------------------------------------------- */ static void MapWindowProc(Marker *markerPtr) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; Point2d anchorPt; Region2d extents; int width, height; if (wmPtr->child == (Tk_Window)NULL) { return; } anchorPt = MapPoint(markerPtr->worldPts, &markerPtr->axes); width = Tk_ReqWidth(wmPtr->child); height = Tk_ReqHeight(wmPtr->child); if (wmPtr->reqWidth > 0) { width = wmPtr->reqWidth; } if (wmPtr->reqHeight > 0) { height = wmPtr->reqHeight; } wmPtr->anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, (double)width, (double)height, wmPtr->anchor); wmPtr->anchorPt.x += markerPtr->xOffset; wmPtr->anchorPt.y += markerPtr->yOffset; wmPtr->width = width; wmPtr->height = height; /* * Determine the bounding box of the window and test to see if it is at * least partially contained within the plotting area. */ extents.left = wmPtr->anchorPt.x; extents.top = wmPtr->anchorPt.y; extents.right = wmPtr->anchorPt.x + wmPtr->width - 1; extents.bottom = wmPtr->anchorPt.y + wmPtr->height - 1; markerPtr->clipped = BoxesDontOverlap(graphPtr, &extents); } /* *--------------------------------------------------------------------------- * * PointInWindowProc -- * *--------------------------------------------------------------------------- */ static int PointInWindowProc(Marker *markerPtr, Point2d *samplePtr) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; return ((samplePtr->x >= wmPtr->anchorPt.x) && (samplePtr->x < (wmPtr->anchorPt.x + wmPtr->width)) && (samplePtr->y >= wmPtr->anchorPt.y) && (samplePtr->y < (wmPtr->anchorPt.y + wmPtr->height))); } /* *--------------------------------------------------------------------------- * * RegionInWindowProc -- * *--------------------------------------------------------------------------- */ static int RegionInWindowProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; if (markerPtr->nWorldPts < 1) { return FALSE; } if (enclosed) { return ((wmPtr->anchorPt.x >= extsPtr->left) && (wmPtr->anchorPt.y >= extsPtr->top) && ((wmPtr->anchorPt.x + wmPtr->width) <= extsPtr->right) && ((wmPtr->anchorPt.y + wmPtr->height) <= extsPtr->bottom)); } return !((wmPtr->anchorPt.x >= extsPtr->right) || (wmPtr->anchorPt.y >= extsPtr->bottom) || ((wmPtr->anchorPt.x + wmPtr->width) <= extsPtr->left) || ((wmPtr->anchorPt.y + wmPtr->height) <= extsPtr->top)); } /* *--------------------------------------------------------------------------- * * DrawWindowProc -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void DrawWindowProc(Marker *markerPtr, Drawable drawable) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; if (wmPtr->child == NULL) { return; } if ((wmPtr->height != Tk_Height(wmPtr->child)) || (wmPtr->width != Tk_Width(wmPtr->child)) || ((int)wmPtr->anchorPt.x != Tk_X(wmPtr->child)) || ((int)wmPtr->anchorPt.y != Tk_Y(wmPtr->child))) { Tk_MoveResizeWindow(wmPtr->child, (int)wmPtr->anchorPt.x, (int)wmPtr->anchorPt.y, wmPtr->width, wmPtr->height); } if (!Tk_IsMapped(wmPtr->child)) { Tk_MapWindow(wmPtr->child); } } /* *--------------------------------------------------------------------------- * * WindowToPostscriptProc -- * *--------------------------------------------------------------------------- */ static void WindowToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; if (wmPtr->child == NULL) { return; } if (Tk_IsMapped(wmPtr->child)) { Blt_Ps_XDrawWindow(ps, wmPtr->child, wmPtr->anchorPt.x, wmPtr->anchorPt.y); } } /* *--------------------------------------------------------------------------- * * FreeWindowProc -- * * Destroys the structure containing the attributes of the window * * marker. * * Results: * None. * * Side effects: * Window is destroyed and removed from the screen. * *--------------------------------------------------------------------------- */ static void FreeWindowProc(Marker *markerPtr) { WindowMarker *wmPtr = (WindowMarker *)markerPtr; if (wmPtr->child != NULL) { Tk_DeleteEventHandler(wmPtr->child, StructureNotifyMask, ChildEventProc, wmPtr); Tk_ManageGeometry(wmPtr->child, (Tk_GeomMgr *) 0, (ClientData)0); Tk_DestroyWindow(wmPtr->child); } } /* *--------------------------------------------------------------------------- * * CreateWindowProc -- * * Allocate memory and initialize methods for the new window marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the window marker structure. * *--------------------------------------------------------------------------- */ static Marker * CreateWindowProc(void) { WindowMarker *wmPtr; wmPtr = Blt_AssertCalloc(1, sizeof(WindowMarker)); wmPtr->classPtr = &windowMarkerClass; return (Marker *)wmPtr; } /* *--------------------------------------------------------------------------- * * ChildEventProc -- * * This procedure is invoked whenever StructureNotify events occur for a * window that's managed as part of a graph window marker. This * procedure's only purpose is to clean up when windows are deleted. * * Results: * None. * * Side effects: * The window is disassociated from the window item when it is * deleted. * *--------------------------------------------------------------------------- */ static void ChildEventProc(ClientData clientData, XEvent *eventPtr) { WindowMarker *wmPtr = clientData; if (eventPtr->type == DestroyNotify) { wmPtr->child = NULL; } } /* *--------------------------------------------------------------------------- * * ChildGeometryProc -- * * This procedure is invoked whenever a window that's associated with a * window item changes its requested dimensions. * * Results: * None. * * Side effects: * The size and location on the window of the window may change, * depending on the options specified for the window item. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ChildGeometryProc(ClientData clientData, Tk_Window tkwin) { WindowMarker *wmPtr = clientData; if (wmPtr->reqWidth == 0) { wmPtr->width = Tk_ReqWidth(tkwin); } if (wmPtr->reqHeight == 0) { wmPtr->height = Tk_ReqHeight(tkwin); } } /* *--------------------------------------------------------------------------- * * ChildCustodyProc -- * * This procedure is invoked when an embedded window has been stolen by * another geometry manager. The information and memory associated with * the widget is released. * * Results: * None. * * Side effects: * Arranges for the graph to be redrawn without the embedded widget at * the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ChildCustodyProc(ClientData clientData, Tk_Window tkwin) { Marker *markerPtr = clientData; Graph *graphPtr; graphPtr = markerPtr->obj.graphPtr; markerPtr->flags |= DELETE_PENDING; Tcl_EventuallyFree(markerPtr, FreeMarker); /* * Not really needed. We should get an Expose event when the child window * is unmapped. */ Blt_EventuallyRedrawGraph(graphPtr); } /* *--------------------------------------------------------------------------- * * MapLineProc -- * * Calculate the layout position for a line marker. Positional * information is saved in the marker. The line positions are stored in * an array of points (malloc'ed). * * Results: * None. * *--------------------------------------------------------------------------- */ static void MapLineProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; LineMarker *lmPtr = (LineMarker *)markerPtr; Point2d *srcPtr, *pend; Segment2d *segments, *segPtr; Point2d p, q; Region2d extents; lmPtr->nSegments = 0; if (lmPtr->segments != NULL) { Blt_Free(lmPtr->segments); } if (markerPtr->nWorldPts < 2) { return; /* Too few points */ } Blt_GraphExtents(graphPtr, &extents); /* * Allow twice the number of world coordinates. The line will represented * as series of line segments, not one continous polyline. This is * because clipping against the plot area may chop the line into several * disconnected segments. */ segments = Blt_AssertMalloc(markerPtr->nWorldPts * sizeof(Segment2d)); srcPtr = markerPtr->worldPts; p = MapPoint(srcPtr, &markerPtr->axes); p.x += markerPtr->xOffset; p.y += markerPtr->yOffset; segPtr = segments; for (srcPtr++, pend = markerPtr->worldPts + markerPtr->nWorldPts; srcPtr < pend; srcPtr++) { Point2d next; next = MapPoint(srcPtr, &markerPtr->axes); next.x += markerPtr->xOffset; next.y += markerPtr->yOffset; q = next; if (Blt_LineRectClip(&extents, &p, &q)) { segPtr->p = p; segPtr->q = q; segPtr++; } p = next; } lmPtr->nSegments = segPtr - segments; lmPtr->segments = segments; markerPtr->clipped = (lmPtr->nSegments == 0); } static int PointInLineProc(Marker *markerPtr, Point2d *samplePtr) { LineMarker *lmPtr = (LineMarker *)markerPtr; return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments, (double)markerPtr->obj.graphPtr->halo); } /* *--------------------------------------------------------------------------- * * RegionInLineProc -- * *--------------------------------------------------------------------------- */ static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) { if (markerPtr->nWorldPts < 2) { return FALSE; } if (enclosed) { Point2d *pp, *pend; for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; pp < pend; pp++) { Point2d p; p = MapPoint(pp, &markerPtr->axes); if ((p.x < extsPtr->left) && (p.x > extsPtr->right) && (p.y < extsPtr->top) && (p.y > extsPtr->bottom)) { return FALSE; } } return TRUE; /* All points inside bounding box. */ } else { int count; Point2d *pp, *pend; count = 0; for (pp = markerPtr->worldPts, pend = pp + (markerPtr->nWorldPts - 1); pp < pend; pp++) { Point2d p, q; p = MapPoint(pp, &markerPtr->axes); q = MapPoint(pp + 1, &markerPtr->axes); if (Blt_LineRectClip(extsPtr, &p, &q)) { count++; } } return (count > 0); /* At least 1 segment passes through * region. */ } } /* *--------------------------------------------------------------------------- * * DrawLineProc -- * *--------------------------------------------------------------------------- */ static void DrawLineProc(Marker *markerPtr, Drawable drawable) { LineMarker *lmPtr = (LineMarker *)markerPtr; if (lmPtr->nSegments > 0) { Graph *graphPtr = markerPtr->obj.graphPtr; Blt_Draw2DSegments(graphPtr->display, drawable, lmPtr->gc, lmPtr->segments, lmPtr->nSegments); if (lmPtr->xor) { /* Toggle the drawing state */ lmPtr->xorState = (lmPtr->xorState == 0); } } } /* *--------------------------------------------------------------------------- * * ConfigureLineProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a line marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as line width, colors, dashes, * etc. get set for markerPtr; old resources get freed, if there were * any. The marker is eventually redisplayed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureLineProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; LineMarker *lmPtr = (LineMarker *)markerPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; Drawable drawable; drawable = Tk_WindowId(graphPtr->tkwin); gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle); if (lmPtr->outlineColor != NULL) { gcMask |= GCForeground; gcValues.foreground = lmPtr->outlineColor->pixel; } if (lmPtr->fillColor != NULL) { gcMask |= GCBackground; gcValues.background = lmPtr->fillColor->pixel; } gcValues.cap_style = lmPtr->capStyle; gcValues.join_style = lmPtr->joinStyle; gcValues.line_width = LineWidth(lmPtr->lineWidth); gcValues.line_style = LineSolid; if (LineIsDashed(lmPtr->dashes)) { gcValues.line_style = (gcMask & GCBackground) ? LineDoubleDash : LineOnOffDash; } if (lmPtr->xor) { unsigned long pixel; gcValues.function = GXxor; gcMask |= GCFunction; if (graphPtr->plotBg == NULL) { pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin)); } else { pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel; } if (gcMask & GCBackground) { gcValues.background ^= pixel; } gcValues.foreground ^= pixel; if (drawable != None) { DrawLineProc(markerPtr, drawable); } } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (lmPtr->gc != NULL) { Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); } if (LineIsDashed(lmPtr->dashes)) { Blt_SetDashes(graphPtr->display, newGC, &lmPtr->dashes); } lmPtr->gc = newGC; if (lmPtr->xor) { if (drawable != None) { MapLineProc(markerPtr); DrawLineProc(markerPtr, drawable); } return TCL_OK; } markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LineToPostscriptProc -- * * Prints postscript commands to display the connect line. Dashed lines * need to be handled specially, especially if a background color is * designated. * * Results: * None. * * Side effects: * PostScript output commands are saved in the interpreter * (infoPtr->interp) result field. * *--------------------------------------------------------------------------- */ static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { LineMarker *lmPtr = (LineMarker *)markerPtr; if (lmPtr->nSegments > 0) { Blt_Ps_XSetLineAttributes(ps, lmPtr->outlineColor, lmPtr->lineWidth, &lmPtr->dashes, lmPtr->capStyle, lmPtr->joinStyle); if ((LineIsDashed(lmPtr->dashes)) && (lmPtr->fillColor != NULL)) { Blt_Ps_Append(ps, "/DashesProc {\n gsave\n "); Blt_Ps_XSetBackground(ps, lmPtr->fillColor); Blt_Ps_Append(ps, " "); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); Blt_Ps_VarAppend(ps, "stroke\n", " grestore\n", "} def\n", (char *)NULL); } else { Blt_Ps_Append(ps, "/DashesProc {} def\n"); } Blt_Ps_Draw2DSegments(ps, lmPtr->segments, lmPtr->nSegments); } } /* *--------------------------------------------------------------------------- * * FreeLineProc -- * * Destroys the structure and attributes of a line marker. * * Results: * None. * * Side effects: * Line attributes (GCs, colors, stipple, etc) get released. Memory is * deallocated, X resources are freed. * *--------------------------------------------------------------------------- */ static void FreeLineProc(Marker *markerPtr) { LineMarker *lmPtr = (LineMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; if (lmPtr->gc != NULL) { Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); } if (lmPtr->segments != NULL) { Blt_Free(lmPtr->segments); } } /* *--------------------------------------------------------------------------- * * CreateLineProc -- * * Allocate memory and initialize methods for a new line marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the line marker structure. * *--------------------------------------------------------------------------- */ static Marker * CreateLineProc(void) { LineMarker *lmPtr; lmPtr = Blt_AssertCalloc(1, sizeof(LineMarker)); lmPtr->classPtr = &lineMarkerClass; lmPtr->xor = FALSE; lmPtr->capStyle = CapButt; lmPtr->joinStyle = JoinMiter; return (Marker *)lmPtr; } /* *--------------------------------------------------------------------------- * * MapPolygonProc -- * * Calculate the layout position for a polygon marker. Positional * information is saved in the polygon in an array of points (malloc'ed). * * Results: * None. * *--------------------------------------------------------------------------- */ static void MapPolygonProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; Point2d *screenPts; Region2d extents; int nScreenPts; if (pmPtr->outlinePts != NULL) { Blt_Free(pmPtr->outlinePts); pmPtr->outlinePts = NULL; pmPtr->nOutlinePts = 0; } if (pmPtr->fillPts != NULL) { Blt_Free(pmPtr->fillPts); pmPtr->fillPts = NULL; pmPtr->nFillPts = 0; } if (pmPtr->screenPts != NULL) { Blt_Free(pmPtr->screenPts); pmPtr->screenPts = NULL; } if (markerPtr->nWorldPts < 3) { return; /* Too few points */ } /* * Allocate and fill a temporary array to hold the screen coordinates of * the polygon. */ nScreenPts = markerPtr->nWorldPts + 1; screenPts = Blt_AssertMalloc((nScreenPts + 1) * sizeof(Point2d)); { Point2d *sp, *dp, *send; dp = screenPts; for (sp = markerPtr->worldPts, send = sp + markerPtr->nWorldPts; sp < send; sp++) { *dp = MapPoint(sp, &markerPtr->axes); dp->x += markerPtr->xOffset; dp->y += markerPtr->yOffset; dp++; } *dp = screenPts[0]; } Blt_GraphExtents(graphPtr, &extents); markerPtr->clipped = TRUE; if (pmPtr->fill.fgColor != NULL) { /* Polygon fill required. */ Point2d *fillPts; int n; fillPts = Blt_AssertMalloc(sizeof(Point2d) * nScreenPts * 3); n = Blt_PolyRectClip(&extents, screenPts, markerPtr->nWorldPts,fillPts); if (n < 3) { Blt_Free(fillPts); } else { pmPtr->nFillPts = n; pmPtr->fillPts = fillPts; markerPtr->clipped = FALSE; } } if ((pmPtr->outline.fgColor != NULL) && (pmPtr->lineWidth > 0)) { Segment2d *outlinePts; Segment2d *segPtr; Point2d *sp, *send; /* * Generate line segments representing the polygon outline. The * resulting outline may or may not be closed from viewport clipping. */ outlinePts = Blt_Malloc(nScreenPts * sizeof(Segment2d)); if (outlinePts == NULL) { return; /* Can't allocate point array */ } /* * Note that this assumes that the point array contains an extra point * that closes the polygon. */ segPtr = outlinePts; for (sp = screenPts, send = sp + (nScreenPts - 1); sp < send; sp++) { segPtr->p = sp[0]; segPtr->q = sp[1]; if (Blt_LineRectClip(&extents, &segPtr->p, &segPtr->q)) { segPtr++; } } pmPtr->nOutlinePts = segPtr - outlinePts; pmPtr->outlinePts = outlinePts; if (pmPtr->nOutlinePts > 0) { markerPtr->clipped = FALSE; } } pmPtr->screenPts = screenPts; } static int PointInPolygonProc(Marker *markerPtr, Point2d *samplePtr) { PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts != NULL)) { return Blt_PointInPolygon(samplePtr, pmPtr->screenPts, markerPtr->nWorldPts + 1); } return FALSE; } /* *--------------------------------------------------------------------------- * * RegionInPolygonProc -- * *--------------------------------------------------------------------------- */ static int RegionInPolygonProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) { PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts != NULL)) { return Blt_RegionInPolygon(extsPtr, pmPtr->screenPts, markerPtr->nWorldPts, enclosed); } return FALSE; } static void DrawPolygonProc(Marker *markerPtr, Drawable drawable) { Graph *graphPtr = markerPtr->obj.graphPtr; PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; /* Draw polygon fill region */ if ((pmPtr->nFillPts > 0) && (pmPtr->fill.fgColor != NULL)) { XPoint *dp, *points; Point2d *sp, *send; points = Blt_Malloc(pmPtr->nFillPts * sizeof(XPoint)); if (points == NULL) { return; } dp = points; for (sp = pmPtr->fillPts, send = sp + pmPtr->nFillPts; sp < send; sp++) { dp->x = (short int)sp->x; dp->y = (short int)sp->y; dp++; } XFillPolygon(graphPtr->display, drawable, pmPtr->fillGC, points, pmPtr->nFillPts, Complex, CoordModeOrigin); Blt_Free(points); } /* and then the outline */ if ((pmPtr->nOutlinePts > 0) && (pmPtr->lineWidth > 0) && (pmPtr->outline.fgColor != NULL)) { Blt_Draw2DSegments(graphPtr->display, drawable, pmPtr->outlineGC, pmPtr->outlinePts, pmPtr->nOutlinePts); } } static void PolygonToPostscriptProc(Marker *markerPtr, Blt_Ps ps) { Graph *graphPtr = markerPtr->obj.graphPtr; PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; if (pmPtr->fill.fgColor != NULL) { /* * Options: fg bg * Draw outline only. * x Draw solid or stipple. * x x Draw solid or stipple. */ /* Create a path to use for both the polygon and its outline. */ Blt_Ps_Polyline(ps, pmPtr->fillPts, pmPtr->nFillPts); /* If the background fill color was specified, draw the polygon in a * solid fashion with that color. */ if (pmPtr->fill.bgColor != NULL) { /* Draw the solid background as the background layer of the opaque * stipple */ Blt_Ps_XSetBackground(ps, pmPtr->fill.bgColor); /* Retain the path. We'll need it for the foreground layer. */ Blt_Ps_Append(ps, "gsave fill grestore\n"); } Blt_Ps_XSetForeground(ps, pmPtr->fill.fgColor); if (pmPtr->stipple != None) { /* Draw the stipple in the foreground color. */ Blt_Ps_XSetStipple(ps, graphPtr->display, pmPtr->stipple); } else { Blt_Ps_Append(ps, "fill\n"); } } /* Draw the outline in the foreground color. */ if ((pmPtr->lineWidth > 0) && (pmPtr->outline.fgColor != NULL)) { /* Set up the line attributes. */ Blt_Ps_XSetLineAttributes(ps, pmPtr->outline.fgColor, pmPtr->lineWidth, &pmPtr->dashes, pmPtr->capStyle, pmPtr->joinStyle); /* * Define on-the-fly a PostScript macro "DashesProc" that will be * executed for each call to the Polygon drawing routine. If the line * isn't dashed, simply make this an empty definition. */ if ((pmPtr->outline.bgColor != NULL) && (LineIsDashed(pmPtr->dashes))) { Blt_Ps_Append(ps, "/DashesProc {\ngsave\n "); Blt_Ps_XSetBackground(ps, pmPtr->outline.bgColor); Blt_Ps_Append(ps, " "); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); Blt_Ps_Append(ps, "stroke\n grestore\n} def\n"); } else { Blt_Ps_Append(ps, "/DashesProc {} def\n"); } Blt_Ps_Draw2DSegments(ps, pmPtr->outlinePts, pmPtr->nOutlinePts); } } /* *--------------------------------------------------------------------------- * * ConfigurePolygonProc -- * * This procedure is called to process an objv/objc list, plus the Tk * option database, in order to configure (or reconfigure) a polygon * marker. * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side effects: * Configuration information, such as polygon color, dashes, fillstyle, * etc. get set for markerPtr; old resources get freed, if there were * any. The marker is eventually redisplayed. * * -------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigurePolygonProc(Marker *markerPtr) { Graph *graphPtr = markerPtr->obj.graphPtr; PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; GC newGC; XGCValues gcValues; unsigned long gcMask; Drawable drawable; drawable = Tk_WindowId(graphPtr->tkwin); gcMask = (GCLineWidth | GCLineStyle); if (pmPtr->outline.fgColor != NULL) { gcMask |= GCForeground; gcValues.foreground = pmPtr->outline.fgColor->pixel; } if (pmPtr->outline.bgColor != NULL) { gcMask |= GCBackground; gcValues.background = pmPtr->outline.bgColor->pixel; } gcMask |= (GCCapStyle | GCJoinStyle); gcValues.cap_style = pmPtr->capStyle; gcValues.join_style = pmPtr->joinStyle; gcValues.line_style = LineSolid; gcValues.dash_offset = 0; gcValues.line_width = LineWidth(pmPtr->lineWidth); if (LineIsDashed(pmPtr->dashes)) { gcValues.line_style = (pmPtr->outline.bgColor == NULL) ? LineOnOffDash : LineDoubleDash; } if (pmPtr->xor) { unsigned long pixel; gcValues.function = GXxor; gcMask |= GCFunction; if (graphPtr->plotBg == NULL) { /* The graph's color option may not have been set yet */ pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin)); } else { pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel; } if (gcMask & GCBackground) { gcValues.background ^= pixel; } gcValues.foreground ^= pixel; if (drawable != None) { DrawPolygonProc(markerPtr, drawable); } } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(pmPtr->dashes)) { Blt_SetDashes(graphPtr->display, newGC, &pmPtr->dashes); } if (pmPtr->outlineGC != NULL) { Blt_FreePrivateGC(graphPtr->display, pmPtr->outlineGC); } pmPtr->outlineGC = newGC; gcMask = 0; if (pmPtr->fill.fgColor != NULL) { gcMask |= GCForeground; gcValues.foreground = pmPtr->fill.fgColor->pixel; } if (pmPtr->fill.bgColor != NULL) { gcMask |= GCBackground; gcValues.background = pmPtr->fill.bgColor->pixel; } if (pmPtr->stipple != None) { gcValues.stipple = pmPtr->stipple; gcValues.fill_style = (pmPtr->fill.bgColor != NULL) ? FillOpaqueStippled : FillStippled; gcMask |= (GCStipple | GCFillStyle); } newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (pmPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, pmPtr->fillGC); } pmPtr->fillGC = newGC; if ((gcMask == 0) && !(graphPtr->flags & RESET_AXES) && (pmPtr->xor)) { if (drawable != None) { MapPolygonProc(markerPtr); DrawPolygonProc(markerPtr, drawable); } return TCL_OK; } markerPtr->flags |= MAP_ITEM; if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } graphPtr->flags |= RESET_WORLD; Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreePolygonProc -- * * Release memory and resources allocated for the polygon element. * * Results: * None. * * Side effects: * Everything associated with the polygon element is freed up. * *--------------------------------------------------------------------------- */ static void FreePolygonProc(Marker *markerPtr) { PolygonMarker *pmPtr = (PolygonMarker *)markerPtr; Graph *graphPtr = markerPtr->obj.graphPtr; if (pmPtr->fillGC != NULL) { Tk_FreeGC(graphPtr->display, pmPtr->fillGC); } if (pmPtr->outlineGC != NULL) { Blt_FreePrivateGC(graphPtr->display, pmPtr->outlineGC); } if (pmPtr->fillPts != NULL) { Blt_Free(pmPtr->fillPts); } if (pmPtr->outlinePts != NULL) { Blt_Free(pmPtr->outlinePts); } if (pmPtr->screenPts != NULL) { Blt_Free(pmPtr->screenPts); } } /* *--------------------------------------------------------------------------- * * CreatePolygonProc -- * * Allocate memory and initialize methods for the new polygon marker. * * Results: * The pointer to the newly allocated marker structure is returned. * * Side effects: * Memory is allocated for the polygon marker structure. * * -------------------------------------------------------------------------- */ static Marker * CreatePolygonProc(void) { PolygonMarker *pmPtr; pmPtr = Blt_AssertCalloc(1, sizeof(PolygonMarker)); pmPtr->classPtr = &polygonMarkerClass; pmPtr->capStyle = CapButt; pmPtr->joinStyle = JoinMiter; return (Marker *)pmPtr; } static int GetMarkerFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Marker **markerPtrPtr) { Blt_HashEntry *hPtr; const char *string; string = Tcl_GetString(objPtr); hPtr = Blt_FindHashEntry(&graphPtr->markers.table, string); if (hPtr != NULL) { *markerPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } if (interp != NULL) { Tcl_AppendResult(interp, "can't find marker \"", string, "\" in \"", Tk_PathName(graphPtr->tkwin), (char *)NULL); } return TCL_ERROR; } static int RenameMarker(Graph *graphPtr, Marker *markerPtr, const char *oldName, const char *newName) { int isNew; Blt_HashEntry *hPtr; /* Rename the marker only if no marker already exists by that name */ hPtr = Blt_CreateHashEntry(&graphPtr->markers.table, newName, &isNew); if (!isNew) { Tcl_AppendResult(graphPtr->interp, "can't rename marker: \"", newName, "\" already exists", (char *)NULL); return TCL_ERROR; } markerPtr->obj.name = Blt_AssertStrdup(newName); markerPtr->hashPtr = hPtr; Blt_SetHashValue(hPtr, (char *)markerPtr); /* Delete the old hash entry */ hPtr = Blt_FindHashEntry(&graphPtr->markers.table, oldName); Blt_DeleteHashEntry(&graphPtr->markers.table, hPtr); if (oldName != NULL) { Blt_Free(oldName); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns a list of marker identifiers in interp->result; * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static int NamesOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 3) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(markerPtr->obj.name, -1)); } } else { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; int i; markerPtr = Blt_Chain_GetValue(link); for (i = 3; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch(markerPtr->obj.name, pattern)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(markerPtr->obj.name, -1)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BindOp -- * * .g element bind elemName sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Blt_HashEntry *hp; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hp = Blt_FirstHashEntry(&graphPtr->markers.tagTable, &iter); hp != NULL; hp = Blt_NextHashEntry(&iter)) { const char *tag; Tcl_Obj *objPtr; tag = Blt_GetHashKey(&graphPtr->markers.tagTable, hp); objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeMarkerTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * CgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Marker *markerPtr; if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { return TCL_ERROR; } if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, markerPtr->classPtr->configSpecs, (char *)markerPtr, objv[4], 0) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Results: * The return value is a standard TCL result. * * Side Effects: * *--------------------------------------------------------------------------- */ static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Marker *markerPtr; Tcl_Obj *const *options; const char *oldName; const char *string; int flags = BLT_CONFIG_OBJV_ONLY; int nNames, nOpts; int i; int under; markerPtr = NULL; /* Suppress compiler warning. */ /* Figure out where the option value pairs begin */ objc -= 3; objv += 3; for (i = 0; i < objc; i++) { string = Tcl_GetString(objv[i]); if (string[0] == '-') { break; } if (GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr) != TCL_OK) { return TCL_ERROR; } } nNames = i; /* # of element names specified */ nOpts = objc - i; /* # of options specified */ options = objv + nNames; /* Start of options in objv */ for (i = 0; i < nNames; i++) { GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr); if (nOpts == 0) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, markerPtr->classPtr->configSpecs, (char *)markerPtr, (Tcl_Obj *)NULL, flags); } else if (nOpts == 1) { return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, markerPtr->classPtr->configSpecs, (char *)markerPtr, options[0], flags); } /* Save the old marker name. */ oldName = markerPtr->obj.name; under = markerPtr->drawUnder; if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, markerPtr->classPtr->configSpecs, nOpts, options, (char *)markerPtr, flags) != TCL_OK) { return TCL_ERROR; } if (oldName != markerPtr->obj.name) { if (RenameMarker(graphPtr, markerPtr, oldName, markerPtr->obj.name) != TCL_OK) { markerPtr->obj.name = oldName; return TCL_ERROR; } } if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) { return TCL_ERROR; } if (markerPtr->drawUnder != under) { graphPtr->flags |= CACHE_DIRTY; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateOp -- * * This procedure creates and initializes a new marker. * * Results: * The return value is a pointer to a structure describing the new * element. If an error occurred, then the return value is NULL and an * error message is left in interp->result. * * Side effects: * Memory is allocated, etc. * *--------------------------------------------------------------------------- */ static int CreateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Marker *markerPtr; Blt_HashEntry *hPtr; int isNew; ClassId classId; int i; const char *name; char ident[200]; const char *string; char c; string = Tcl_GetString(objv[3]); c = string[0]; /* Create the new marker based upon the given type */ if ((c == 't') && (strcmp(string, "text") == 0)) { classId = CID_MARKER_TEXT; } else if ((c == 'l') && (strcmp(string, "line") == 0)) { classId = CID_MARKER_LINE; } else if ((c == 'p') && (strcmp(string, "polygon") == 0)) { classId = CID_MARKER_POLYGON; } else if ((c == 'i') && (strcmp(string, "image") == 0)) { classId = CID_MARKER_IMAGE; } else if ((c == 'b') && (strcmp(string, "bitmap") == 0)) { classId = CID_MARKER_BITMAP; } else if ((c == 'w') && (strcmp(string, "window") == 0)) { classId = CID_MARKER_WINDOW; } else { Tcl_AppendResult(interp, "unknown marker type \"", string, "\": should be \"text\", \"line\", \"polygon\", \"bitmap\", \"image\", or \ \"window\"", (char *)NULL); return TCL_ERROR; } /* Scan for "-name" option. We need it for the component name */ name = NULL; for (i = 4; i < objc; i += 2) { int length; string = Tcl_GetStringFromObj(objv[i], &length); if ((length > 1) && (strncmp(string, "-name", length) == 0)) { name = Tcl_GetString(objv[i + 1]); break; } } /* If no name was given for the marker, make up one. */ if (name == NULL) { sprintf_s(ident, 200, "marker%d", graphPtr->nextMarkerId++); name = ident; } else if (name[0] == '-') { Tcl_AppendResult(interp, "name of marker \"", name, "\" can't start with a '-'", (char *)NULL); return TCL_ERROR; } markerPtr = CreateMarker(graphPtr, name, classId); if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, name, markerPtr->obj.className, markerPtr->classPtr->configSpecs, objc - 4, objv + 4, (char *)markerPtr, 0) != TCL_OK) { DestroyMarker(markerPtr); return TCL_ERROR; } if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) { DestroyMarker(markerPtr); return TCL_ERROR; } hPtr = Blt_CreateHashEntry(&graphPtr->markers.table, name, &isNew); if (!isNew) { Marker *oldPtr; /* * Marker by the same name already exists. Delete the old marker and * it's list entry. But save the hash entry. */ oldPtr = Blt_GetHashValue(hPtr); oldPtr->hashPtr = NULL; DestroyMarker(oldPtr); } Blt_SetHashValue(hPtr, markerPtr); markerPtr->hashPtr = hPtr; /* Unlike elements, new markers are drawn on top of old markers. */ markerPtr->link = Blt_Chain_Prepend(graphPtr->markers.displayList,markerPtr); if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the marker given by markerId. * * Results: * The return value is a standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new display list. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { Marker *markerPtr; if (GetMarkerFromObj(NULL, graphPtr, objv[i], &markerPtr) == TCL_OK) { markerPtr->flags |= DELETE_PENDING; Tcl_EventuallyFree(markerPtr, FreeMarker); } } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetOp -- * * Find the legend entry from the given argument. The argument can be * either a screen position "@x,y" or the name of an element. * * I don't know how useful it is to test with the name of an element. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new legend attributes. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int GetOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Marker *markerPtr; const char *string; string = Tcl_GetString(objv[3]); if ((string[0] == 'c') && (strcmp(string, "current") == 0)) { markerPtr = (Marker *)Blt_GetCurrentItem(graphPtr->bindTable); if (markerPtr == NULL) { return TCL_OK; /* Report only on markers. */ } if ((markerPtr->obj.classId >= CID_MARKER_BITMAP) && (markerPtr->obj.classId <= CID_MARKER_WINDOW)) { Tcl_SetStringObj(Tcl_GetObjResult(interp), markerPtr->obj.name, -1); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RelinkOp -- * * Reorders the marker (given by the first name) before/after the another * marker (given by the second name) in the marker display list. If no * second name is given, the marker is placed at the beginning/end of the * list. * * Results: * A standard TCL result. * * Side Effects: * Graph will be redrawn to reflect the new display list. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RelinkOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link, place; Marker *markerPtr; const char *string; /* Find the marker to be raised or lowered. */ if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { return TCL_ERROR; } /* Right now it's assumed that all markers are always in the display list. */ link = markerPtr->link; Blt_Chain_UnlinkLink(graphPtr->markers.displayList, markerPtr->link); place = NULL; if (objc == 5) { if (GetMarkerFromObj(interp, graphPtr, objv[4], &markerPtr) != TCL_OK) { return TCL_ERROR; } place = markerPtr->link; } /* Link the marker at its new position. */ string = Tcl_GetString(objv[2]); if (string[0] == 'l') { Blt_Chain_LinkAfter(graphPtr->markers.displayList, link, place); } else { Blt_Chain_LinkBefore(graphPtr->markers.displayList, link, place); } if (markerPtr->drawUnder) { graphPtr->flags |= CACHE_DIRTY; } Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FindOp -- * * Returns if marker by a given ID currently exists. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int FindOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link; Region2d extents; const char *string; int enclosed; int left, right, top, bottom; int mode; #define FIND_ENCLOSED (1<<0) #define FIND_OVERLAPPING (1<<1) string = Tcl_GetString(objv[3]); if (strcmp(string, "enclosed") == 0) { mode = FIND_ENCLOSED; } else if (strcmp(string, "overlapping") == 0) { mode = FIND_OVERLAPPING; } else { Tcl_AppendResult(interp, "bad search type \"", string, ": should be \"enclosed\", or \"overlapping\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[4], &left) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[5], &top) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[6], &right) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[7], &bottom) != TCL_OK)) { return TCL_ERROR; } if (left < right) { extents.left = (double)left; extents.right = (double)right; } else { extents.left = (double)right; extents.right = (double)left; } if (top < bottom) { extents.top = (double)top; extents.bottom = (double)bottom; } else { extents.top = (double)bottom; extents.bottom = (double)top; } enclosed = (mode == FIND_ENCLOSED); for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if (markerPtr->flags & (HIDE|DELETE_PENDING)) { continue; } if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { continue; } if ((*markerPtr->classPtr->regionProc)(markerPtr, &extents, enclosed)) { Tcl_Obj *objPtr; objPtr = Tcl_GetObjResult(interp); Tcl_SetStringObj(objPtr, markerPtr->obj.name, -1); return TCL_OK; } } Tcl_SetStringObj(Tcl_GetObjResult(interp), "", -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ExistsOp -- * * Returns if marker by a given ID currently exists. * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExistsOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&graphPtr->markers.table, Tcl_GetString(objv[3])); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr != NULL)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TypeOp -- * * Returns a symbolic name for the type of the marker whose ID is given. * * Results: * A standard TCL result. interp->result will contain the symbolic type * of the marker. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TypeOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Marker *markerPtr; const char *type; if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { return TCL_ERROR; } switch (markerPtr->obj.classId) { case CID_MARKER_BITMAP: type = "bitmap"; break; case CID_MARKER_IMAGE: type = "image"; break; case CID_MARKER_LINE: type = "line"; break; case CID_MARKER_POLYGON: type = "polygon"; break; case CID_MARKER_TEXT: type = "text"; break; case CID_MARKER_WINDOW: type = "window"; break; default: type = "???"; break; } Tcl_SetStringObj(Tcl_GetObjResult(interp), type, -1); return TCL_OK; } /* Public routines */ /* *--------------------------------------------------------------------------- * * Blt_MarkerOp -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec markerOps[] = { {"bind", 1, BindOp, 3, 6, "marker sequence command",}, {"cget", 2, CgetOp, 5, 5, "marker option",}, {"configure", 2, ConfigureOp, 4, 0,"marker ?marker?... ?option value?...",}, {"create", 2, CreateOp, 4, 0, "type ?option value?...",}, {"delete", 1, DeleteOp, 3, 0, "?marker?...",}, {"exists", 1, ExistsOp, 4, 4, "marker",}, {"find", 1, FindOp, 8, 8, "enclosed|overlapping x1 y1 x2 y2",}, {"get", 1, GetOp, 4, 4, "name",}, {"lower", 1, RelinkOp, 4, 5, "marker ?afterMarker?",}, {"names", 1, NamesOp, 3, 0, "?pattern?...",}, {"raise", 1, RelinkOp, 4, 5, "marker ?beforeMarker?",}, {"type", 1, TypeOp, 4, 4, "marker",}, }; static int nMarkerOps = sizeof(markerOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ int Blt_MarkerOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { GraphMarkerProc *proc; int result; proc = Blt_GetOpFromObj(interp, nMarkerOps, markerOps, BLT_OP_ARG2, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (graphPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * Blt_MarkersToPostScript -- * *--------------------------------------------------------------------------- */ void Blt_MarkersToPostScript(Graph *graphPtr, Blt_Ps ps, int under) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->classPtr->postscriptProc == NULL) || (markerPtr->nWorldPts == 0)) { continue; } if (markerPtr->drawUnder != under) { continue; } if (markerPtr->flags & (HIDE|DELETE_PENDING)) { continue; } if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { continue; } Blt_Ps_VarAppend(ps, "\n% Marker \"", markerPtr->obj.name, "\" is a ", markerPtr->obj.className, ".\n", (char *)NULL); (*markerPtr->classPtr->postscriptProc) (markerPtr, ps); } } /* *--------------------------------------------------------------------------- * * Blt_DrawMarkers -- * * Calls the individual drawing routines (based on marker type) for each * marker in the display list. * * A marker will not be drawn if * * 1) An element linked to the marker (indicated by elemName) is * currently hidden. * * 2) No coordinates have been specified for the marker. * * 3) The marker is requesting to be drawn at a different level * (above/below the elements) from the current mode. * * 4) The marker is configured as hidden (-hide option). * * 5) The marker isn't visible in the current viewport (i.e. clipped). * * Results: * None * * Side Effects: * Markers are drawn into the drawable (pixmap) which will eventually * be displayed in the graph window. * *--------------------------------------------------------------------------- */ void Blt_DrawMarkers(Graph *graphPtr, Drawable drawable, int under) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->nWorldPts == 0) || (markerPtr->drawUnder != under) || (markerPtr->clipped) || (markerPtr->flags & (DELETE_PENDING|HIDE))) { continue; } if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { continue; } (*markerPtr->classPtr->drawProc) (markerPtr, drawable); } } void Blt_ConfigureMarkers(Graph *graphPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); (*markerPtr->classPtr->configProc) (markerPtr); } } void Blt_MapMarkers(Graph *graphPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if (markerPtr->nWorldPts == 0) { continue; } if (markerPtr->flags & (HIDE|DELETE_PENDING)) { continue; } if ((graphPtr->flags & MAP_ALL) || (markerPtr->flags & MAP_ITEM)) { (*markerPtr->classPtr->mapProc) (markerPtr); markerPtr->flags &= ~MAP_ITEM; } } } void Blt_DestroyMarkers(Graph *graphPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&graphPtr->markers.table, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Marker *markerPtr; markerPtr = Blt_GetHashValue(hPtr); /* * Dereferencing the pointer to the hash table prevents the hash table * entry from being automatically deleted. */ markerPtr->hashPtr = NULL; DestroyMarker(markerPtr); } Blt_DeleteHashTable(&graphPtr->markers.table); Blt_DeleteHashTable(&graphPtr->markers.tagTable); Blt_Chain_Destroy(graphPtr->markers.displayList); } Marker * Blt_NearestMarker( Graph *graphPtr, int x, int y, /* Screen coordinates */ int under) { Blt_ChainLink link; Point2d point; point.x = (double)x; point.y = (double)y; for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); link != NULL; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->nWorldPts == 0) || (markerPtr->flags & (HIDE|DELETE_PENDING|MAP_ITEM))) { continue; /* Don't consider markers that are * pending to be mapped. Even if the * marker has already been mapped, the * coordinates could be invalid now. * Better to pick no marker than the * wrong marker. */ } if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { continue; } if ((markerPtr->drawUnder == under) && (markerPtr->state == STATE_NORMAL)) { if ((*markerPtr->classPtr->pointProc) (markerPtr, &point)) { return markerPtr; } } } return NULL; } ClientData Blt_MakeMarkerTag(Graph *graphPtr, const char *tagName) { Blt_HashEntry *hPtr; int isNew; assert(tagName != NULL); hPtr = Blt_CreateHashEntry(&graphPtr->markers.tagTable, tagName, &isNew); return Blt_GetHashKey(&graphPtr->markers.tagTable, hPtr); } #ifdef notdef /* *--------------------------------------------------------------------------- * * ConfigureArrows -- * * If arrowheads have been requested for a line, this procedure makes * arrangements for the arrowheads. * * Results: * Always returns TCL_OK. * * Side effects: * Information in linePtr is set up for one or two arrowheads. the * firstArrowPtr and lastArrowPtr polygons are allocated and initialized, * if need be, and the end points of the line are adjusted so that a * thick line doesn't stick out past the arrowheads. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int ConfigureArrows(canvas, linePtr) Tk_Canvas canvas; /* Canvas in which arrows will be * displayed (interp and tkwin fields * are needed). */ LineItem *linePtr; /* Item to configure for arrows. */ { double *poly, *coordPtr; double dx, dy, length, sinTheta, cosTheta, temp; double fracHeight; /* Line width as fraction of arrowhead * width. */ double backup; /* Distance to backup end points so * the line ends in the middle of the * arrowhead. */ double vertX, vertY; /* Position of arrowhead vertex. */ double shapeA, shapeB, shapeC; /* Adjusted coordinates (see * explanation below). */ double width; Tk_State state = linePtr->header.state; if (linePtr->numPoints <2) { return TCL_OK; } if(state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } width = linePtr->outline.width; if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { if (linePtr->outline.activeWidth>width) { width = linePtr->outline.activeWidth; } } else if (state==TK_STATE_DISABLED) { if (linePtr->outline.disabledWidth>0) { width = linePtr->outline.disabledWidth; } } /* * The code below makes a tiny increase in the shape parameters for the * line. This is a bit of a hack, but it seems to result in displays that * more closely approximate the specified parameters. Without the * adjustment, the arrows come out smaller than expected. */ shapeA = linePtr->arrowShapeA + 0.001; shapeB = linePtr->arrowShapeB + 0.001; shapeC = linePtr->arrowShapeC + width/2.0 + 0.001; /* * If there's an arrowhead on the first point of the line, compute its * polygon and adjust the first point of the line so that the line doesn't * stick out past the leading edge of the arrowhead. */ fracHeight = (width/2.0)/shapeC; backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0; if (linePtr->arrow != ARROWS_LAST) { poly = linePtr->firstArrowPtr; if (poly == NULL) { poly = (double *) ckalloc((unsigned) (2*PTS_IN_ARROW*sizeof(double))); poly[0] = poly[10] = linePtr->coordPtr[0]; poly[1] = poly[11] = linePtr->coordPtr[1]; linePtr->firstArrowPtr = poly; } dx = poly[0] - linePtr->coordPtr[2]; dy = poly[1] - linePtr->coordPtr[3]; length = hypot(dx, dy); if (length == 0) { sinTheta = cosTheta = 0.0; } else { sinTheta = dy/length; cosTheta = dx/length; } vertX = poly[0] - shapeA*cosTheta; vertY = poly[1] - shapeA*sinTheta; temp = shapeC*sinTheta; poly[2] = poly[0] - shapeB*cosTheta + temp; poly[8] = poly[2] - 2*temp; temp = shapeC*cosTheta; poly[3] = poly[1] - shapeB*sinTheta - temp; poly[9] = poly[3] + 2*temp; poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); /* * Polygon done. Now move the first point towards the second so that * the corners at the end of the line are inside the arrowhead. */ linePtr->coordPtr[0] = poly[0] - backup*cosTheta; linePtr->coordPtr[1] = poly[1] - backup*sinTheta; } /* * Similar arrowhead calculation for the last point of the line. */ if (linePtr->arrow != ARROWS_FIRST) { coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2); poly = linePtr->lastArrowPtr; if (poly == NULL) { poly = (double *) ckalloc((unsigned) (2*PTS_IN_ARROW*sizeof(double))); poly[0] = poly[10] = coordPtr[2]; poly[1] = poly[11] = coordPtr[3]; linePtr->lastArrowPtr = poly; } dx = poly[0] - coordPtr[0]; dy = poly[1] - coordPtr[1]; length = hypot(dx, dy); if (length == 0) { sinTheta = cosTheta = 0.0; } else { sinTheta = dy/length; cosTheta = dx/length; } vertX = poly[0] - shapeA*cosTheta; vertY = poly[1] - shapeA*sinTheta; temp = shapeC*sinTheta; poly[2] = poly[0] - shapeB*cosTheta + temp; poly[8] = poly[2] - 2*temp; temp = shapeC*cosTheta; poly[3] = poly[1] - shapeB*sinTheta - temp; poly[9] = poly[3] + 2*temp; poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); coordPtr[2] = poly[0] - backup*cosTheta; coordPtr[3] = poly[1] - backup*sinTheta; } return TCL_OK; } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictPhoto.c����������������������������������������������������������������0000644�0001750�0001750�00000012730�11462120062�015607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #include "blt.h" #include "config.h" #include <tcl.h> #include <tk.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include "bltPicture.h" #include "bltPictFmts.h" #define FALSE 0 #define TRUE 1 #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ typedef struct { Tcl_Obj *imageObjPtr; int index; } PhotoExportSwitches; typedef struct { Tcl_Obj *imageObjPtr; } PhotoImportSwitches; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_OBJ, "-image", "imageName", Blt_Offset(PhotoExportSwitches, imageObjPtr), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(PhotoExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-image", "imageName", Blt_Offset(PhotoImportSwitches, imageObjPtr), 0}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_PicturePhotoInit; #ifdef notdef void Blt_SizeOfPhoto(Tk_PhotoHandle photo, int *widthPtr, int *heightPtr) { Tk_PhotoImageBlock ib; Tk_PhotoGetImage(photo, &ib); *widthPtr = ib.width; *heightPtr = ib.height; } #endif /* *--------------------------------------------------------------------------- * * PhotoToPicture -- * * Converts a Tk Photo image to a picture. * * Results: * The picture is returned. If an error occured, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain PhotoToPicture( Tcl_Interp *interp, /* Interpreter to report errors back to. */ PhotoImportSwitches *importPtr) { Tk_PhotoHandle photo; Blt_Picture picture; Blt_Chain chain; photo = Tk_FindPhoto(interp, Tcl_GetString(importPtr->imageObjPtr)); if (photo == NULL) { Tcl_AppendResult(interp, "can't find photo \"", Tcl_GetString(importPtr->imageObjPtr), "\"", (char *)NULL); return NULL; } picture = Blt_PhotoToPicture(photo); chain = Blt_Chain_Create(); Blt_Chain_Append(chain, picture); return chain; } /* *--------------------------------------------------------------------------- * * PictureToPhoto -- * * Writes to an existing Tk Photo to contents of the picture. * * Results: * A standard TCL result. If an error occured, TCL_ERROR is * returned and an error message will be place in the interpreter * result. * * Side Effects: * Memory is allocated for the photo. * *--------------------------------------------------------------------------- */ static int PictureToPhoto( Tcl_Interp *interp, /* Interpreter to report errors back to. */ Blt_Picture picture, /* Picture source. */ PhotoExportSwitches *switchesPtr) { Tk_PhotoHandle photo; photo = Tk_FindPhoto(interp, Tcl_GetString(switchesPtr->imageObjPtr)); if (photo == NULL) { Tcl_AppendResult(interp, "can't find photo \"", Tcl_GetString(switchesPtr->imageObjPtr), "\"", (char *)NULL); return TCL_ERROR; } Blt_PictureToPhoto(picture, photo); return TCL_OK; } static int IsPhoto(Blt_DBuffer buffer) { return FALSE; } static Blt_Chain ImportPhoto( Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; PhotoImportSwitches switches; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if (switches.imageObjPtr != NULL) { Tcl_AppendResult(interp, "no photo specified: use -image switch.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } chain = PhotoToPicture(interp, &switches); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return chain; } static int ExportPhoto(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { int result; PhotoExportSwitches switches; Blt_Picture picture; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.index = index; result = TCL_ERROR; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { goto error; } if (switches.imageObjPtr != NULL) { Tcl_AppendResult(interp, "no photo specified: use -image switch.", (char *)NULL); goto error; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "bad picture index.", (char *)NULL); goto error; } result = PictureToPhoto(interp, picture, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return result; } int Blt_PicturePhotoInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; if (Tk_InitStubs(interp, TK_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_photo", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "photo", /* Name of format. */ IsPhoto, /* Discovery routine. */ NULL, /* Read format procedure. */ NULL, /* Write format procedure. */ ImportPhoto, /* Import format procedure. */ ExportPhoto); /* Export format procedure. */ } ����������������������������������������./saods9/blt3.0.1/src/TODO��������������������������������������������������������������������������0000644�0001750�0001750�00000012331�11462120063�013516� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� To do: bgexec (Windows) 1. (BUG) Convert collected data to UTF before passing to the interpreter. container (Unix) 1. (done) Add timeout option to control how long to search for application window. debug 1. (done) Recent versions of Tcl swamp Tcl_CommandTrace. Add line cutoff option (default is 6). dnd (Unix) 1. (DOC) Create manual page for "dnd" command. 2. (Feature) Add Motif drag-and-drop capabilities. eps 1. (DOC) Update manual page for eps canvas item. 2. (FEATURE) Read Windows EPS files with embedded TIFF images. graph 1. (done) Fix zooming graph procedure to handle multiple axes. 2. (BUG) Windows printing commands "print1" and "print2" need to use postscript options like -maxpect, -pad, etc. to control graph size. 3. (BUG) No PostScript generated for polygon tiling. 4. (BUG) Clip background polygon for text/bitmap markers. 5. (FEATURE) Add -mask option for bitmap marker. 6. (FEATURE) Allow rotated image markers. 7. (FEATURE) Add oval and rectangle markers. 8. (FEATURE) Add arrowheads to line markers. 9. (BUG) Finish adding error bars. 10. (DOC) Review and update documentation for new typos, new features. 11. (BUG) Store converted screen coordinates in floating point. Can't use integer coordinates for higher resolution PostScript devices. How do Windows' print devices handle this? hierbox 1. (CHANGE) Hierbox to use tree object for data. The -data option will be a field in the tree. 2. (FEATURE) Add edit bindings for entries. 3. (DOCUMENTATION) Create real hierbox manual page. hiertable 1. (done) -tree option dumps core. 2. (done) Sorting tree view affects all other hiertables using the tree. Is separate data structure needed for non-flattened sorts? What about moves? 3. (done) Call tree update procedure when tree object is sorted. This is only when a tree is shared between more than one hiertable. It goes out-of-sync with actual tree positions. 4. (CHANGE) "column resize set" should change the width of the active column automatically. 5a.(FEATURE) XOR outline for entry move operation. 5b.(FEATURE) XOR outline for entry resize operation. 6a.(done) XOR outline for column resize operation. 6b.(FEATURE) XOR outline for column move operation. 7. (???) Update procedure isn't called for moved nodes. Call global update routine (like sort) or selected node update procedures? 8. (DOC) Explain selection modes ("single" and "multiple") in manual page. 9. (BUG) Multi-line entry editting is broken. 10. (BUG) Add default bindings for entry editting. Need to set grab on edit window. 11. (BUG) Add standard keyboard bindings. 12. (FEATURE) Images in column title. 13. (PERFORMANCE) Don't redraw entire widget for scrolling. Copy portions of pixmap and redraw only changed areas. This will affect lots of code. 14. (PERFORMANCE) Don't redraw entire widget for selections. Draw only changed entries. 15. (???) Add checkbox column entries. 16. (BUG) "column resize" reports incorrect width of column. printer (Windows) 1. (DOC) Create manual page for "printer" command. 2. (FEATURE) Add operation to print text and canvas widgets. 3. (FEATURE) Create sample print dialog. 4. (BUG) Needs print job abort handler. tabset 1. (done) Add perforation gizmo for tearoffs. 2. (FEATURE) Allow alternatative tearout styles. tree 1. (done) Create Tcl interface. 2. (DOC) Create manuals for both Tcl and C APIs. vector 1. (FEATURE) Add Tcl-based notification callbacks. gradient 1. (FEATURE) Create gradient command that interfaces with tiling. all (Mac) --------------------- barchart - Anti-aliased lines for bars? barchart - Clip bars properly. barchart - Store bars with floating point coordinates barchart - Fix PostScript, fix translucent bars. graph - Fix PostScript, fix translucent symbols graph - Fix PostScript font stringwidth using AFM files graph - Simple markup (subscript/superscript, font size color, greek symbols) graph - PDF output. picture - Add gradient paint operations picture - Wide lines picture - shadows. picture - Fix text operations. Single glyph picture - PDF output picture - convolve bgpattern - tile and gradient polygons table widget - contour widget - macosx - build - busy, ? dataarray: 1. Reference counted vectors. Don't require master to delete. Can attach like trees and tables. 2. No variable interface. 3. Tcl notifier interface. 4. Connect to table columns. 5. Use Blt_Objs 6. No #auto. 7. Test harness. 8. Use Tcl_Objs instead of double array. Allow strings, images, arrays, etc. --------------------------------------------- Paneset -- Fix modes. Leave room for sash when shrinking window. Graph -- Constrain size of symbols. Fix axis line with solid plot lines. Barchart -- Clip bar segments against plot area. Scrollset -- Fix manual. Treeview -- Fix combobox style to support combomenus. Add automatic scrollbars. Change scrolling to use XCopyArea. Combomenu -- Better icon for radiobuttons. Comboentry -- Combotree -- Fix background. Combobutton -- Menubar -- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltAlloc.h��������������������������������������������������������������������0000644�0001750�0001750�00000002637�11462120062�014742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * Memory allocation/deallocation in BLT is performed via the * global variables bltMallocPtr, bltFreePtr, and bltReallocPtr. * By default, they point to the same routines that TCL uses. * The routine Blt_AllocInit allows you to specify your own * memory allocation/deallocation routines for BLT on a * library-wide basis. */ #ifndef _BLT_ALLOC_H #define _BLT_ALLOC_H #include <assert.h> typedef void *(Blt_MallocProc) (size_t size); typedef void *(Blt_ReallocProc) (void *ptr, size_t size); typedef void (Blt_FreeProc) (const void *ptr); BLT_EXTERN void Blt_AllocInit(Blt_MallocProc *mallocProc, Blt_ReallocProc *reallocProc, Blt_FreeProc *freeProc); BLT_EXTERN void *Blt_Malloc(size_t size); BLT_EXTERN void *Blt_Realloc(void *ptr, size_t size); BLT_EXTERN void Blt_Free(const void *ptr); BLT_EXTERN void *Blt_Calloc(size_t nElem, size_t size); BLT_EXTERN char *Blt_Strdup(const char *string); BLT_EXTERN void *Blt_MallocAbortOnError(size_t size, const char *file,int line); BLT_EXTERN void *Blt_CallocAbortOnError(size_t nElem, size_t size, const char *file, int line); BLT_EXTERN char *Blt_StrdupAbortOnError(const char *ptr, const char *file, int line); #define Blt_AssertCalloc(n,s) (Blt_CallocAbortOnError(n,s,__FILE__, __LINE__)) #define Blt_AssertMalloc(s) (Blt_MallocAbortOnError(s,__FILE__, __LINE__)) #define Blt_AssertStrdup(s) (Blt_StrdupAbortOnError(s,__FILE__, __LINE__)) #endif /* _BLT_ALLOC_H */ �������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBusy.c���������������������������������������������������������������������0000644�0001750�0001750�00000150775�11462120062�014634� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBusy.c -- * * This module implements busy windows for the BLT toolkit. * * Copyright 1993-2009 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_BUSY #include "bltOp.h" #include "bltHash.h" #include "tkDisplay.h" #include "bltBgStyle.h" #include "bltPicture.h" #include "bltPainter.h" #include "bltImage.h" #define BUSYDEBUG 0 #ifndef TK_REPARENTED #define TK_REPARENTED 0 #endif #define BUSY_THREAD_KEY "BLT Busy Data" typedef struct { unsigned int flags; Display *display; /* Display of busy window */ Tcl_Interp *interp; /* Interpreter where "busy" command * was created. It's used to key the * searches in the window * hierarchy. See the "windows" * command. */ Tk_Window tkBusy; /* Busy window: Transparent window * used to block delivery of events to * windows underneath it. */ Tk_Window tkParent; /* Parent window of the busy * window. It may be the reference * window (if the reference is a * toplevel) or a mutual ancestor of * the reference window */ Tk_Window tkRef; /* Reference window of the busy * window. It's is used to manage the * size and position of the busy * window. */ int x, y; /* Position of the reference window */ int width, height; /* Size of the reference * window. Retained to know if the * reference window has been * reconfigured to a new size. */ int menuBar; /* Menu bar flag. */ Tk_Cursor cursor; /* Cursor for the busy window. */ Blt_HashEntry *hashPtr; /* Used the delete the busy window * entry out of the global hash * table. */ Blt_HashTable *tablePtr; const char *text; /* Text to be displayed in the opaque * window. */ Blt_Picture snapshot; /* Snapshot of reference window * used as background of opaque * busy window. */ Blt_Background bg; /* Default background to use if 1) * busy window is opaque and 2) a * snapshot of the reference window * can't be obtained (possibly because * the reference window was * obscurred. */ GC gc; int darken; Blt_Picture picture; /* Image to be displayed in the * center of the busy window. */ Tk_Image tkImage; } Busy; #define REDRAW_PENDING (1<<0) /* Indicates a DoWhenIdle handler has * already been queued to redraw this * window. */ #define ACTIVE (1<<1) /* Indicates whether the busy window * should be displayed. This can be * different from what Tk_IsMapped * says because the a sibling * reference window may be unmapped, * forcing the busy window to be also * hidden. */ #define OPAQUE (1<<2) /* Indicates whether the busy window * is opaque. */ #define IMAGE_PHOTO (1<<3) /* Indicates that the image was * a photo. */ #ifdef WIN32 #define DEF_BUSY_CURSOR "wait" #else #define DEF_BUSY_CURSOR "watch" #endif #define DEF_BUSY_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_BUSY_OPAQUE "0" #define DEF_BUSY_DARKEN "30" static Blt_OptionParseProc ObjToPictImageProc; static Blt_OptionPrintProc PictImageToObjProc; static Blt_OptionFreeProc FreePictImageProc; static Blt_CustomOption pictImageOption = { ObjToPictImageProc, PictImageToObjProc, FreePictImageProc, (ClientData)0 }; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BUSY_BACKGROUND, Blt_Offset(Busy, bg), 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CURSOR, "-cursor", "busyCursor", "BusyCursor", DEF_BUSY_CURSOR, Blt_Offset(Busy, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_INT, "-darken", "darken", "Darken", DEF_BUSY_DARKEN, Blt_Offset(Busy, darken), 0}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", (char *)NULL, Blt_Offset(Busy, picture), BLT_CONFIG_NULL_OK, &pictImageOption}, {BLT_CONFIG_BITMASK, "-opaque", "opaque", "Opaque", DEF_BUSY_OPAQUE, Blt_Offset(Busy, flags), 0, (Blt_CustomOption *)OPAQUE}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; typedef struct { Blt_HashTable busyTable; /* Hash table of busy window * structures keyed by the address of * thereference Tk window */ Tk_Window tkMain; Tcl_Interp *interp; } BusyInterpData; static Tk_GeomRequestProc BusyGeometryProc; static Tk_GeomLostSlaveProc BusyCustodyProc; static Tk_GeomMgr busyMgrInfo = { (char *)"busy", /* Name of geometry manager used by * winfo */ BusyGeometryProc, /* Procedure to for new geometry * requests */ BusyCustodyProc, /* Procedure when window is taken * away */ }; /* Forward declarations */ static Tcl_IdleProc DisplayBusy; static Tcl_FreeProc DestroyBusy; static Tk_EventProc BusyEventProc; static Tk_EventProc RefWinEventProc; static Tcl_ObjCmdProc BusyCmd; static Tcl_InterpDeleteProc BusyInterpDeleteProc; /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Tells the Tk dispatcher to call the busy display routine at the next * idle point. This request is made only if the window is displayed and * no other redraw request is pending. * * Results: None. * * Side effects: * The window is eventually redisplayed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(Busy *busyPtr) { if ((busyPtr->tkBusy != NULL) && ((busyPtr->flags & (REDRAW_PENDING|OPAQUE)) == OPAQUE)) { Tcl_DoWhenIdle(DisplayBusy, busyPtr); busyPtr->flags |= REDRAW_PENDING; } } /* *--------------------------------------------------------------------------- * * ImageChangedProc -- * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, int w, int h, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Busy *busyPtr = clientData; int isPhoto; if ((busyPtr->picture != NULL) && (busyPtr->flags & IMAGE_PHOTO)) { Blt_FreePicture(busyPtr->picture); } busyPtr->picture = NULL; busyPtr->flags &= ~IMAGE_PHOTO; if (Blt_Image_IsDeleted(busyPtr->tkImage)) { Tk_FreeImage(busyPtr->tkImage); busyPtr->tkImage = NULL; return; } busyPtr->picture = Blt_GetPictureFromImage(busyPtr->interp, busyPtr->tkImage, &isPhoto); if (isPhoto) { busyPtr->flags |= IMAGE_PHOTO; } EventuallyRedraw(busyPtr); } /*ARGSUSED*/ static void FreePictImageProc( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Busy *busyPtr = (Busy *)widgRec; if ((busyPtr->picture != NULL) && (busyPtr->flags & IMAGE_PHOTO)) { Blt_FreePicture(busyPtr->picture); } busyPtr->picture = NULL; if (busyPtr->tkImage != NULL) { Tk_FreeImage(busyPtr->tkImage); } busyPtr->tkImage = NULL; busyPtr->flags &= ~IMAGE_PHOTO; } /* *--------------------------------------------------------------------------- * * ObjToPictImageProc -- * * Given an image name, get the Tk image associated with it. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToPictImageProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to return results */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representation of value. */ char *widgRec, /* Widget record. */ int offset, /* Offset to field in structure */ int flags) { Busy *busyPtr = (Busy *)widgRec; Tk_Image tkImage; const char *name; int isPhoto; name = Tcl_GetString(objPtr); tkImage = Tk_GetImage(interp, tkwin, name, ImageChangedProc, busyPtr); if (tkImage == NULL) { return TCL_ERROR; } if (busyPtr->tkImage != NULL) { Tk_FreeImage(busyPtr->tkImage); } busyPtr->flags &= ~IMAGE_PHOTO; if (busyPtr->picture != NULL) { Blt_FreePicture(busyPtr->picture); } busyPtr->tkImage = tkImage; busyPtr->picture = Blt_GetPictureFromImage(busyPtr->interp, tkImage, &isPhoto); if (isPhoto) { busyPtr->flags |= IMAGE_PHOTO; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * PictImageToObjProc -- * * Convert the image name into a string Tcl_Obj. * * Results: * The string representation of the image is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * PictImageToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Busy *busyPtr = (Busy *)(widgRec); if (busyPtr->tkImage == NULL) { return Tcl_NewStringObj("", -1); } return Tcl_NewStringObj(Blt_Image_Name(busyPtr->tkImage), -1); } static void ShowBusyWindow(Busy *busyPtr) { /* * If the busy window is opaque, take a snapshot of the reference * window and use that as the contents of the window. */ if (busyPtr->flags & OPAQUE) { Tk_Window tkwin; Blt_Picture picture; Blt_Pixel color; int rx, ry; int delta; tkwin = Blt_Toplevel(busyPtr->tkRef); Blt_RaiseToplevelWindow(tkwin); Blt_RootCoordinates(busyPtr->tkRef, busyPtr->x, busyPtr->y, &rx, &ry); picture = Blt_DrawableToPicture(busyPtr->tkRef, Tk_RootWindow(busyPtr->tkRef), rx, ry, busyPtr->width, busyPtr->height, 1.0); if (picture == NULL) { fprintf(stderr, "can't grab window (possibly obscured?)\n"); return; } delta = (int)((busyPtr->darken / 100.0) * 255); color.u32 = 0x0; color.Red = color.Blue = color.Green = delta; Blt_ApplyScalarToPicture(picture, &color, PIC_ARITH_SUB); if (busyPtr->snapshot != NULL) { Blt_FreePicture(busyPtr->snapshot); } busyPtr->snapshot = picture; EventuallyRedraw(busyPtr); } if (busyPtr->tkBusy != NULL) { Tk_MapWindow(busyPtr->tkBusy); /* * Always raise the busy window just in case new sibling windows have * been created in the meantime. Can't use Tk_RestackWindow because it * doesn't work under Win32. */ XRaiseWindow(busyPtr->display, Tk_WindowId(busyPtr->tkBusy)); } #ifdef WIN32 { POINT point; /* * In Win32 cursors aren't associated with windows. Tk fakes this by * watching <Motion> events on its windows. Tk will automatically * change the cursor when the pointer enters the Busy window. But * Windows doesn't immediately change the cursor; it waits for the * cursor position to change or a system call. We need to change the * cursor before the application starts processing, so set the cursor * position redundantly back to the current position. */ GetCursorPos(&point); SetCursorPos(point.x, point.y); } #else XFlush(busyPtr->display); #endif /* WIN32 */ } static void HideBusyWindow(Busy *busyPtr) { if (busyPtr->tkBusy != NULL) { Tk_UnmapWindow(busyPtr->tkBusy); } #ifdef WIN32 { POINT point; /* * Under Win32, cursors aren't associated with windows. Tk fakes this * by watching Motion events on its windows. So Tk will automatically * change the cursor when the pointer enters the Busy window. But * Windows doesn't immediately change the cursor: it waits for the * cursor position to change or a system call. We need to change the * cursor before the application starts processing, so set the cursor * position redundantly back to the current position. */ GetCursorPos(&point); SetCursorPos(point.x, point.y); } #else XFlush(busyPtr->display); #endif /* WIN32 */ } /* *--------------------------------------------------------------------------- * * BusyEventProc -- * * This procedure is invoked by the Tk dispatcher for events on the busy * window itself. We're only concerned with destroy events. * * It might be necessary (someday) to watch resize events. Right now, I * don't think there's any point in it. * * Results: * None. * * Side effects: * When a busy window is destroyed, all internal structures associated * with it released at the next idle point. * *--------------------------------------------------------------------------- */ static void BusyEventProc( ClientData clientData, /* Busy window record */ XEvent *eventPtr) /* Event which triggered call to * routine */ { Busy *busyPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(busyPtr); } } else if (eventPtr->type == DestroyNotify) { busyPtr->tkBusy = NULL; if (busyPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayBusy, busyPtr); } Tcl_EventuallyFree(busyPtr, DestroyBusy); } else if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(busyPtr); } } /* *--------------------------------------------------------------------------- * * BusyCustodyProc -- * * This procedure is invoked when the busy window has been stolen by * another geometry manager. The information and memory associated with * the busy window is released. I don't know why anyone would try to pack * a busy window, but this should keep everything sane, if it is. * * Results: * None. * * Side effects: * The Busy structure is freed at the next idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void BusyCustodyProc( ClientData clientData, /* Information about the busy window. */ Tk_Window tkwin) /* Not used. */ { Busy *busyPtr = clientData; Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc, busyPtr); HideBusyWindow(busyPtr); busyPtr->tkBusy = NULL; Tcl_EventuallyFree(busyPtr, DestroyBusy); } /* *--------------------------------------------------------------------------- * * BusyGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for busy windows. * Busy windows never request geometry, so it's unlikely that this * routine will ever be called. The routine exists simply as a place * holder for the GeomProc in the Geometry Manager structure. * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void BusyGeometryProc( ClientData clientData, /* Information about window that got new * preferred geometry. */ Tk_Window tkwin) /* Other Tk-related information about * the window. */ { /* Should never get here */ } /* *--------------------------------------------------------------------------- * * RefWinEventProc -- * * This procedure is invoked by the Tk dispatcher for the following events * on the reference window. If the reference and parent windows are the * same, only the first event is important. * * 1) ConfigureNotify - The reference window has been resized or * moved. Move and resize the busy window * to be the same size and position of the * reference window. * * 2) DestroyNotify - The reference window was destroyed. Destroy * the busy window and the free resources * used. * * 3) MapNotify - The reference window was (re)shown. Map the * busy window again. * * 4) UnmapNotify - The reference window was hidden. Unmap the * busy window. * * Results: * None. * * Side effects: * When the reference window gets deleted, internal structures get cleaned * up. When it gets resized, the busy window is resized accordingly. If * it's displayed, the busy window is displayed. And when it's hidden, the * busy window is unmapped. * *--------------------------------------------------------------------------- */ static void RefWinEventProc( ClientData clientData, /* Busy window record */ XEvent *eventPtr) /* Event that triggered the call to this * routine */ { Busy *busyPtr = clientData; switch (eventPtr->type) { case ReparentNotify: case DestroyNotify: /* * Arrange for the busy structure to be removed at a proper time. */ Tcl_EventuallyFree(busyPtr, DestroyBusy); break; case ConfigureNotify: if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) || (busyPtr->height != Tk_Height(busyPtr->tkRef)) || (busyPtr->x != Tk_X(busyPtr->tkRef)) || (busyPtr->y != Tk_Y(busyPtr->tkRef))) { int x, y; busyPtr->width = Tk_Width(busyPtr->tkRef); busyPtr->height = Tk_Height(busyPtr->tkRef); busyPtr->x = Tk_X(busyPtr->tkRef); busyPtr->y = Tk_Y(busyPtr->tkRef); x = y = 0; if (busyPtr->tkParent != busyPtr->tkRef) { Tk_Window tkwin; for (tkwin = busyPtr->tkRef; (tkwin != NULL) && (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { if (tkwin == busyPtr->tkParent) { break; } x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; } } #if BUSYDEBUG PurifyPrintf("menubar2: width=%d, height=%d\n", busyPtr->width, busyPtr->height); #endif if (busyPtr->tkBusy != NULL) { #if BUSYDEBUG fprintf(stderr, "busy window %s is at %d,%d %dx%d\n", Tk_PathName(busyPtr->tkBusy), x, y, busyPtr->width, busyPtr->height); #endif Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width, busyPtr->height); if (busyPtr->flags & ACTIVE) { ShowBusyWindow(busyPtr); } } } break; case MapNotify: if ((busyPtr->tkParent != busyPtr->tkRef) && (busyPtr->flags & ACTIVE)) { ShowBusyWindow(busyPtr); } break; case UnmapNotify: if (busyPtr->tkParent != busyPtr->tkRef) { HideBusyWindow(busyPtr); } break; } } /* *--------------------------------------------------------------------------- * * ConfigureBusy -- * * This procedure is called from the Tk event dispatcher. It releases X * resources and memory used by the busy window and updates the internal * hash table. * * Results: * None. * * Side effects: * Memory and resources are released and the Tk event handler is removed. * *--------------------------------------------------------------------------- */ static int ConfigureBusy( Tcl_Interp *interp, Busy *busyPtr, int objc, Tcl_Obj *const *objv) { Tk_Cursor oldCursor; oldCursor = busyPtr->cursor; if (Blt_ConfigureWidgetFromObj(interp, busyPtr->tkRef, configSpecs, objc, objv, (char *)busyPtr, 0) != TCL_OK) { return TCL_ERROR; } if (busyPtr->cursor != oldCursor) { if (busyPtr->cursor == None) { Tk_UndefineCursor(busyPtr->tkBusy); } else { Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateBusy -- * * Creates a child transparent window that obscures its parent window * thereby effectively blocking device events. The size and position of * the busy window is exactly that of the reference window. * * We want to create sibling to the window to be blocked. If the busy * window is a child of the window to be blocked, Enter/Leave events can * sneak through. Futhermore under WIN32, messages of transparent * windows are sent directly to the parent. The only exception to this * are toplevels, since we can't make a sibling. Fortunately, toplevel * windows rarely receive events that need blocking. * * Results: * Returns a pointer to the new busy window structure. * * Side effects: * When the busy window is eventually displayed, it will screen device * events (in the area of the reference window) from reaching its parent * window and its children. User feed back can be achieved by changing * the cursor. * *--------------------------------------------------------------------------- */ static Busy * CreateBusy2( Tcl_Interp *interp, /* Interpreter to report error to */ Tk_Window tkRef) /* Window hosting the busy window */ { Busy *busyPtr; Tk_FakeWin *winPtr; Tk_Window tkBusy, tkParent; Window parent; char *name; const char *fmt; int length; int x, y; unsigned int mask; busyPtr = Blt_AssertCalloc(1, sizeof(Busy)); x = y = 0; length = strlen(Tk_Name(tkRef)); name = Blt_AssertMalloc(length + 6); if (Tk_IsTopLevel(tkRef)) { fmt = "_Busy"; /* Child */ tkParent = tkRef; } else { Tk_Window tkwin; fmt = "%s_Busy"; /* Sibling */ tkParent = Tk_Parent(tkRef); for (tkwin = tkRef; (tkwin != NULL) && (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { if (tkwin == tkParent) { break; } x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; } } { Tk_Window tkwin; for (tkwin = Blt_FirstChild(tkParent); tkwin != NULL; tkwin = Blt_NextChild(tkwin)) { Tk_MakeWindowExist(tkwin); } } sprintf_s(name, length + 6, fmt, Tk_Name(tkRef)); tkBusy = Tk_CreateWindow(interp, tkParent, name, (char *)NULL); Blt_Free(name); if (tkBusy == NULL) { return NULL; } Tk_MakeWindowExist(tkRef); busyPtr->display = Tk_Display(tkRef); busyPtr->interp = interp; busyPtr->tkRef = tkRef; busyPtr->tkParent = tkParent; busyPtr->tkBusy = tkBusy; busyPtr->width = Tk_Width(tkRef); busyPtr->height = Tk_Height(tkRef); busyPtr->x = Tk_X(tkRef); busyPtr->y = Tk_Y(tkRef); busyPtr->cursor = None; busyPtr->flags = 0; Tk_SetClass(tkBusy, "Busy"); Blt_SetWindowInstanceData(tkBusy, busyPtr); winPtr = (Tk_FakeWin *)tkRef; if (winPtr->flags & TK_REPARENTED) { /* * This works around a bug in the implementation of menubars for * non-MacIntosh window systems (Win32 and X11). Tk doesn't reset the * pointers to the parent window when the menu is reparented * (winPtr->parentPtr points to the wrong window). We get around this * by determining the parent via the native API calls. */ #ifdef WIN32 { HWND hWnd; RECT rect; hWnd = Tk_GetHWND(Tk_WindowId(tkRef)); hWnd = GetParent(hWnd); parent = (Window) hWnd; if (GetWindowRect(hWnd, &rect)) { busyPtr->width = rect.right - rect.left; busyPtr->height = rect.bottom - rect.top; #if BUSYDEBUG PurifyPrintf("menubar: width=%d, height=%d\n", busyPtr->width, busyPtr->height); #endif } } #else parent = Blt_GetParentWindow(busyPtr->display, Tk_WindowId(tkRef)); #endif } else { parent = Tk_WindowId(tkParent); #ifdef WIN32 parent = (Window) Tk_GetHWND(parent); #endif } mask = StructureNotifyMask; if (busyPtr->flags & OPAQUE) { mask |= ExposureMask; } else { Blt_MakeTransparentWindowExist(tkBusy, parent, TRUE); } #if BUSYDEBUG PurifyPrintf("menubar1: width=%d, height=%d\n", busyPtr->width, busyPtr->height); fprintf(stderr, "busy window %s is at %d,%d %dx%d\n", Tk_PathName(tkBusy), x, y, busyPtr->width, busyPtr->height); #endif Tk_MoveResizeWindow(tkBusy, x, y, busyPtr->width, busyPtr->height); /* Only worry if the busy window is destroyed. */ Tk_CreateEventHandler(tkBusy, StructureNotifyMask, BusyEventProc, busyPtr); /* * Indicate that the busy window's geometry is being managed. This will * also notify us if the busy window is ever packed. */ Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr); if (busyPtr->cursor != None) { Tk_DefineCursor(tkBusy, busyPtr->cursor); } /* Track the reference window to see if it is resized or destroyed. */ Tk_CreateEventHandler(tkRef, StructureNotifyMask, RefWinEventProc, busyPtr); return busyPtr; } /* *--------------------------------------------------------------------------- * * NewBusy -- * * Creates a child transparent window that obscures its parent window * thereby effectively blocking device events. The size and position of * the busy window is exactly that of the reference window. * * We want to create sibling to the window to be blocked. If the busy * window is a child of the window to be blocked, Enter/Leave events can * sneak through. Futhermore under WIN32, messages of transparent * windows are sent directly to the parent. The only exception to this * are toplevels, since we can't make a sibling. Fortunately, toplevel * windows rarely receive events that need blocking. * * Results: * Returns a pointer to the new busy window structure. * * Side effects: * When the busy window is eventually displayed, it will screen device * events (in the area of the reference window) from reaching its parent * window and its children. User feed back can be achieved by changing * the cursor. * *--------------------------------------------------------------------------- */ static Busy * NewBusy( Tcl_Interp *interp, /* Interpreter to report error to */ Tk_Window tkRef) /* Window hosting the busy window */ { Busy *busyPtr; Tk_Window tkBusy; Tk_Window tkParent; char *name; const char *fmt; int length; int x, y; busyPtr = Blt_AssertCalloc(1, sizeof(Busy)); x = y = 0; if (Tk_IsTopLevel(tkRef)) { fmt = "_Busy"; /* Child */ tkParent = tkRef; } else { Tk_Window tkwin; fmt = "%s_Busy"; /* Sibling */ tkParent = Tk_Parent(tkRef); for (tkwin = tkRef; (tkwin != NULL) && (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { if (tkwin == tkParent) { break; } x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; } } { Tk_Window tkwin; for (tkwin = Blt_FirstChild(tkParent); tkwin != NULL; tkwin = Blt_NextChild(tkwin)) { Tk_MakeWindowExist(tkwin); } } length = strlen(Tk_Name(tkRef)); name = Blt_AssertMalloc(length + 6); sprintf_s(name, length + 6, fmt, Tk_Name(tkRef)); tkBusy = Tk_CreateWindow(interp, tkParent, name, (char *)NULL); Blt_Free(name); if (tkBusy == NULL) { return NULL; } Tk_MakeWindowExist(tkRef); busyPtr->display = Tk_Display(tkRef); busyPtr->interp = interp; busyPtr->tkRef = tkRef; busyPtr->tkParent = tkParent; busyPtr->tkBusy = tkBusy; busyPtr->width = Tk_Width(tkRef); busyPtr->height = Tk_Height(tkRef); busyPtr->x = Tk_X(tkRef); busyPtr->y = Tk_Y(tkRef); busyPtr->cursor = None; busyPtr->darken = 30; busyPtr->flags = 0; Tk_SetClass(tkBusy, "Busy"); Blt_SetWindowInstanceData(tkBusy, busyPtr); return busyPtr; } /* *--------------------------------------------------------------------------- * * CreateBusy -- * * Creates a child transparent window that obscures its parent window * thereby effectively blocking device events. The size and position of * the busy window is exactly that of the reference window. * * We want to create sibling to the window to be blocked. If the busy * window is a child of the window to be blocked, Enter/Leave events can * sneak through. Futhermore under WIN32, messages of transparent * windows are sent directly to the parent. The only exception to this * are toplevels, since we can't make a sibling. Fortunately, toplevel * windows rarely receive events that need blocking. * * Results: * Returns a pointer to the new busy window structure. * * Side effects: * When the busy window is eventually displayed, it will screen device * events (in the area of the reference window) from reaching its parent * window and its children. User feed back can be achieved by changing * the cursor. * *--------------------------------------------------------------------------- */ static void InitializeBusy(Busy *busyPtr) { Tk_FakeWin *winPtr; Window parent; unsigned int mask; winPtr = (Tk_FakeWin *) busyPtr->tkRef; if (winPtr->flags & TK_REPARENTED) { /* * This works around a bug in the implementation of menubars for * non-MacIntosh window systems (Win32 and X11). Tk doesn't reset the * pointers to the parent window when the menu is reparented * (winPtr->parentPtr points to the wrong window). We get around this * by determining the parent via the native API calls. */ #ifdef WIN32 { HWND hWnd; RECT rect; hWnd = Tk_GetHWND(Tk_WindowId(busyPtr->tkRef)); hWnd = GetParent(hWnd); parent = (Window) hWnd; if (GetWindowRect(hWnd, &rect)) { busyPtr->width = rect.right - rect.left; busyPtr->height = rect.bottom - rect.top; #if BUSYDEBUG PurifyPrintf("menubar: width=%d, height=%d\n", busyPtr->width, busyPtr->height); #endif } } #else parent = Blt_GetParentWindow(busyPtr->display, Tk_WindowId(busyPtr->tkRef)); #endif } else { parent = Tk_WindowId(busyPtr->tkParent); #ifdef WIN32 parent = (Window) Tk_GetHWND(parent); #endif } mask = StructureNotifyMask; if (busyPtr->flags & OPAQUE) { Tk_MakeWindowExist(busyPtr->tkBusy); mask |= ExposureMask; } else { Blt_MakeTransparentWindowExist(busyPtr->tkBusy, parent, TRUE); } #if BUSYDEBUG PurifyPrintf("menubar1: width=%d, height=%d\n", busyPtr->width, busyPtr->height); fprintf(stderr, "busy window %s is at %d,%d %dx%d\n", Tk_PathName(busyPtr->tkBusy), busyPtr->x, busyPtr->y, busyPtr->width, busyPtr->height); #endif Tk_MoveResizeWindow(busyPtr->tkBusy, busyPtr->x, busyPtr->y, busyPtr->width, busyPtr->height); /* Only worry if the busy window is destroyed. */ Tk_CreateEventHandler(busyPtr->tkBusy, mask, BusyEventProc, busyPtr); /* * Indicate that the busy window's geometry is being managed. This will * also notify us if the busy window is ever packed. */ Tk_ManageGeometry(busyPtr->tkBusy, &busyMgrInfo, busyPtr); if (busyPtr->cursor != None) { Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor); } /* Track the reference window to see if it is resized or destroyed. */ Tk_CreateEventHandler(busyPtr->tkRef, StructureNotifyMask, RefWinEventProc, busyPtr); } /* *--------------------------------------------------------------------------- * * DestroyBusy -- * * This procedure is called from the Tk event dispatcher. It releases X * resources and memory used by the busy window and updates the internal * hash table. * * Results: * None. * * Side effects: * Memory and resources are released and the Tk event handler is removed. * *--------------------------------------------------------------------------- */ static void DestroyBusy(DestroyData data) /* Busy window structure record */ { Busy *busyPtr = (Busy *)data; Blt_FreeOptions(configSpecs, (char *)busyPtr, busyPtr->display, 0); if (busyPtr->hashPtr != NULL) { Blt_DeleteHashEntry(busyPtr->tablePtr, busyPtr->hashPtr); } if (busyPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayBusy, busyPtr); } Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask, RefWinEventProc, busyPtr); if (busyPtr->snapshot != NULL) { Blt_FreePicture(busyPtr->snapshot); } if (busyPtr->tkBusy != NULL) { Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc, busyPtr); Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr); Tk_DestroyWindow(busyPtr->tkBusy); } Blt_Free(busyPtr); } /* *--------------------------------------------------------------------------- * * GetBusy -- * * Returns the busy window structure associated with the reference * window, keyed by its path name. The clientData argument is the main * window of the interpreter, used to search for the reference window in * its own window hierarchy. * * Results: * If path name represents a reference window with a busy window, a * pointer to the busy window structure is returned. Otherwise, NULL is * returned and an error message is left in interp->result. * *--------------------------------------------------------------------------- */ static int GetBusy( BusyInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to. If * NULL, indicates not to generate error * message. */ Tcl_Obj *objPtr, Busy **busyPtrPtr) /* Will contain address of busy window * if found. */ { Blt_HashEntry *hPtr; Tk_Window tkwin; const char *pathName; /* Path name of parent window */ pathName = Tcl_GetString(objPtr); tkwin = Tk_NameToWindow(dataPtr->interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(&dataPtr->busyTable, (char *)tkwin); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find busy window \"", pathName, "\"", (char *)NULL); } return TCL_ERROR; } *busyPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HoldBusy -- * * Creates (if necessary) and maps a busy window, thereby preventing * device events from being be received by the parent window and its * children. * * Results: * Returns a standard TCL result. If path name represents a busy window, * it is unmapped and TCL_OK is returned. Otherwise, TCL_ERROR is * returned and an error message is left in interp->result. * * Side effects: * The busy window is created and displayed, blocking events from the * parent window and its children. * *--------------------------------------------------------------------------- */ static int HoldBusy( BusyInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) /* Window name and option pairs */ { Tk_Window tkwin; Blt_HashEntry *hPtr; Busy *busyPtr; int isNew; int result; tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[0]), dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_CreateHashEntry(&dataPtr->busyTable, (char *)tkwin, &isNew); if (isNew) { busyPtr = NewBusy(interp, tkwin); if (busyPtr == NULL) { return TCL_ERROR; } Blt_SetHashValue(hPtr, busyPtr); busyPtr->hashPtr = hPtr; busyPtr->tablePtr = &dataPtr->busyTable; result = ConfigureBusy(interp, busyPtr, objc - 1, objv + 1); InitializeBusy(busyPtr); } else { busyPtr = Blt_GetHashValue(hPtr); result = ConfigureBusy(interp, busyPtr, objc - 1, objv + 1); } /* * Don't map the busy window unless the reference window is also currently * displayed. */ if (Tk_IsMapped(busyPtr->tkRef)) { ShowBusyWindow(busyPtr); } else { HideBusyWindow(busyPtr); } busyPtr->flags |= ACTIVE; return result; } /* *--------------------------------------------------------------------------- * * StatusOp -- * * Returns the status of the busy window; whether it's blocking events or * not. * * Results: * Returns a standard TCL result. If path name represents a busy window, * the status is returned via interp->result and TCL_OK is * returned. Otherwise, TCL_ERROR is returned and an error message is * left in interp->result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int StatusOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report error to */ int objc, /* Not used. */ Tcl_Obj *const *objv) { BusyInterpData *dataPtr = clientData; Busy *busyPtr; if (GetBusy(dataPtr, interp, objv[2], &busyPtr) != TCL_OK) { return TCL_ERROR; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), busyPtr->flags & ACTIVE); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ForgetOp -- * * Destroys the busy window associated with the reference window and * arranges for internal resources to the released when they're not being * used anymore. * * Results: * Returns a standard TCL result. If path name represents a busy window, * it is destroyed and TCL_OK is returned. Otherwise, TCL_ERROR is * returned and an error message is left in interp->result. * * Side effects: * The busy window is removed. Other related memory and resources are * eventually released by the Tk dispatcher. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ForgetOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { BusyInterpData *dataPtr = clientData; int i; for (i = 2; i < objc; i++) { Busy *busyPtr; if (GetBusy(dataPtr, (Tcl_Interp *)NULL, objv[i], &busyPtr) == TCL_OK) { /* Unmap the window even though it will be soon destroyed */ HideBusyWindow(busyPtr); Tcl_EventuallyFree(busyPtr, DestroyBusy); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ReleaseOp -- * * Unmaps the busy window, thereby permitting device events to be * received by the parent window and its children. * * Results: * Returns a standard TCL result. If path name represents a busy window, * it is unmapped and TCL_OK is returned. Otherwise, TCL_ERROR is * returned and an error message is left in interp->result. * * Side effects: * The busy window is hidden, allowing the parent window and its children * to receive events again. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ReleaseOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Not used. */ int objc, Tcl_Obj *const *objv) { BusyInterpData *dataPtr = clientData; Busy *busyPtr; int i; for (i = 2; i < objc; i++) { if (GetBusy(dataPtr, (Tcl_Interp *)NULL, objv[i], &busyPtr) == TCL_OK) { HideBusyWindow(busyPtr); busyPtr->flags &= ~ACTIVE; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Reports the names of all widgets with busy windows attached to them, * matching a given pattern. If no pattern is given, all busy widgets * are listed. * * Results: * Returns a TCL list of the names of the widget with busy windows * attached to them, regardless if the widget is currently busy or not. * *--------------------------------------------------------------------------- */ static int NamesOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; Blt_HashSearch iter; BusyInterpData *dataPtr = clientData; Tcl_Obj *listObjPtr; const char *pattern; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); pattern = (objc > 2) ? Tcl_GetString(objv[2]) : NULL; for (hPtr = Blt_FirstHashEntry(&dataPtr->busyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Busy *busyPtr; busyPtr = Blt_GetHashValue(hPtr); if ((pattern == NULL) || (Tcl_StringMatch(Tk_PathName(busyPtr->tkRef), pattern))) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Tk_PathName(busyPtr->tkRef), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BusyOp -- * * Reports the names of all widgets with busy windows attached to them, * matching a given pattern. If no pattern is given, all busy widgets * are listed. * * Results: * Returns a TCL list of the names of the widget with busy windows * attached to them, regardless if the widget is currently busy or not. * *--------------------------------------------------------------------------- */ static int BusyOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) { BusyInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; const char *pattern; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); pattern = (objc > 2) ? Tcl_GetString(objv[2]) : NULL; for (hPtr = Blt_FirstHashEntry(&dataPtr->busyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Busy *busyPtr; busyPtr = Blt_GetHashValue(hPtr); if ((busyPtr->flags & ACTIVE) == 0) { continue; } if ((pattern == NULL) || (Tcl_StringMatch(Tk_PathName(busyPtr->tkRef), pattern))) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Tk_PathName(busyPtr->tkRef), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CheckOp -- * * Checks if the named window is currently busy. This also includes * windows whose ancestors are currently busy. * * Results: * Returns 1 a TCL list of the names of the widget with busy windows * attached to them, regardless if the widget is currently busy or not. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CheckOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Blt_HashEntry *hPtr; BusyInterpData *dataPtr = clientData; Tk_Window tkwin; const char *pathName; pathName = Tcl_GetString(objv[2]); tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); do { hPtr = Blt_FindHashEntry(&dataPtr->busyTable, (char *)tkwin); if (hPtr != NULL) { Busy *busyPtr; /* Found a busy window, is it on? */ busyPtr = Blt_GetHashValue(hPtr); if (busyPtr->flags & ACTIVE) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); return TCL_OK; } } tkwin = Tk_Parent(tkwin); } while(tkwin != NULL); Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HoldOp -- * * Creates (if necessary) and maps a busy window, thereby preventing * device events from being be received by the parent window and its * children. The argument vector may contain option-value pairs of * configuration options to be set. * * Results: * Returns a standard TCL result. * * Side effects: * The busy window is created and displayed, blocking events from the * parent window and its children. * *--------------------------------------------------------------------------- */ static int HoldOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) /* Window name and option pairs */ { BusyInterpData *dataPtr = clientData; int i; const char *string; string = Tcl_GetString(objv[1]); if ((string[0] == 'h') && (strcmp(string, "hold") == 0)) { objc--, objv++; /* Command used "hold" keyword */ } for (i = 1; i < objc; i++) { int count; /* * Find the end of the option-value pairs for this window. */ for (count = i + 1; count < objc; count += 2) { string = Tcl_GetString(objv[count]); if (string[0] != '-') { break; } } if (count > objc) { count = objc; } if (HoldBusy(dataPtr, interp, count - i, objv + i) != TCL_OK) { return TCL_ERROR; } i = count; } return TCL_OK; } /* ARGSUSED*/ static int CgetOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) /* Widget pathname and option switch */ { BusyInterpData *dataPtr = clientData; Busy *busyPtr; int result; if (GetBusy(dataPtr, interp, objv[2], &busyPtr) != TCL_OK) { return TCL_ERROR; } Tcl_Preserve(busyPtr); result = Blt_ConfigureValueFromObj(interp, busyPtr->tkRef, configSpecs, (char *)busyPtr, objv[3], 0); Tcl_Release(busyPtr); return result; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * This procedure is called to process an objv/objc list in order to * configure (or reconfigure) a busy window. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information get set for busyPtr; old resources get * freed, if there were any. The busy window destroyed and recreated in * a new parent window. * *--------------------------------------------------------------------------- */ static int ConfigureOp( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report errors to */ int objc, Tcl_Obj *const *objv) /* Reference window path name and * options */ { BusyInterpData *dataPtr = clientData; Busy *busyPtr; int result; if (GetBusy(dataPtr, interp, objv[2], &busyPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { result = Blt_ConfigureInfoFromObj(interp, busyPtr->tkRef, configSpecs, (char *)busyPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { result = Blt_ConfigureInfoFromObj(interp, busyPtr->tkRef, configSpecs, (char *)busyPtr, objv[3], 0); } else { Tcl_Preserve(busyPtr); result = ConfigureBusy(interp, busyPtr, objc - 3, objv + 3); Tcl_Release(busyPtr); } return result; } /* *--------------------------------------------------------------------------- * * BusyInterpDeleteProc -- * * This is called when the interpreter hosting the "busy" command is * destroyed. * * Results: * None. * * Side effects: * Destroys all the hash table managing the busy windows. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void BusyInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { BusyInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->busyTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Busy *busyPtr; busyPtr = Blt_GetHashValue(hPtr); busyPtr->hashPtr = NULL; DestroyBusy((DestroyData)busyPtr); } Blt_DeleteHashTable(&dataPtr->busyTable); Tcl_DeleteAssocData(interp, BUSY_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * Busy Sub-command specification: * * - Name of the sub-command. * - Minimum number of characters needed to unambiguously * recognize the sub-command. * - Pointer to the function to be called for the sub-command. * - Minimum number of arguments accepted. * - Maximum number of arguments accepted. * - String to be displayed for usage (arguments only). * *--------------------------------------------------------------------------- */ static Blt_OpSpec busyOps[] = { {"cget", 2, CgetOp, 4, 4, "window option",}, {"check", 1, CheckOp, 3, 3, "window",}, {"configure", 2, ConfigureOp, 3, 0, "window ?options?...",}, {"forget", 1, ForgetOp, 2, 0, "?window?...",}, {"hold", 3, HoldOp, 3, 0, "window ?options?... ?window options?...",}, {"isbusy", 1, BusyOp, 2, 3, "?pattern?",}, {"names", 1, NamesOp, 2, 3, "?pattern?",}, {"release", 1, ReleaseOp, 2, 0, "?window?...",}, {"status", 1, StatusOp, 3, 3, "window",}, {"windows", 1, NamesOp, 2, 3, "?pattern?",}, }; static int nBusyOps = sizeof(busyOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * BusyCmd -- * * This procedure is invoked to process the "busy" TCL command. See the * user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int BusyCmd( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter associated with * command */ int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; if (objc > 1) { const char *string; string = Tcl_GetString(objv[1]); if (string[0] == '.') { return HoldOp(clientData, interp, objc, objv); } } proc = Blt_GetOpFromObj(interp, nBusyOps, busyOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } static BusyInterpData * GetBusyInterpData(Tcl_Interp *interp) { BusyInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (BusyInterpData *) Tcl_GetAssocData(interp, BUSY_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(BusyInterpData)); Tcl_SetAssocData(interp, BUSY_THREAD_KEY, BusyInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->busyTable, BLT_ONE_WORD_KEYS); dataPtr->interp = interp; dataPtr->tkMain = Tk_MainWindow(interp); } return dataPtr; } int Blt_BusyCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"busy", BusyCmd, }; cmdSpec.clientData = GetBusyInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } static void DisplayBusy(ClientData clientData) { Busy *busyPtr = clientData; Pixmap drawable; Tk_Window tkwin; Blt_Painter painter; busyPtr->flags &= ~REDRAW_PENDING; if (busyPtr->tkBusy == NULL) { return; /* Window has been destroyed (we * should not get here) */ } tkwin = busyPtr->tkBusy; #ifndef notdef fprintf(stderr, "Calling DisplayBusy(%s)\n", Tk_PathName(tkwin)); #endif if ((Tk_Width(tkwin) <= 1) || (Tk_Height(tkwin) <= 1)) { /* Don't bother computing the layout until the size of the window is * something reasonable. */ return; } busyPtr->width = Tk_Width(tkwin); busyPtr->height = Tk_Height(tkwin); if (!Tk_IsMapped(tkwin)) { /* The busy window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the graph's new layout. */ return; } /* Create a pixmap the size of the window for double buffering. */ drawable = Tk_GetPixmap(busyPtr->display, Tk_WindowId(tkwin), busyPtr->width, busyPtr->height, Tk_Depth(tkwin)); #ifdef WIN32 assert(drawable != None); #endif painter = Blt_GetPainter(busyPtr->tkBusy, 1.0); if (busyPtr->snapshot == NULL) { Blt_FillBackgroundRectangle(busyPtr->tkBusy, drawable, busyPtr->bg, busyPtr->x, busyPtr->y, busyPtr->width, busyPtr->height, 0, TK_RELIEF_FLAT); if (busyPtr->picture != NULL) { int x, y; x = (busyPtr->width - Blt_PictureWidth(busyPtr->picture)) / 2; y = (busyPtr->height - Blt_PictureHeight(busyPtr->picture)) / 2; Blt_PaintPicture(painter, drawable, busyPtr->picture, 0, 0, busyPtr->width, busyPtr->height, x, y, 0); } } else { Blt_Picture copy; copy = busyPtr->snapshot; if (busyPtr->picture != NULL) { int x, y, w, h; w = Blt_PictureWidth(busyPtr->picture); h = Blt_PictureHeight(busyPtr->picture); x = (busyPtr->width - w) / 2; y = (busyPtr->height - h) / 2; fprintf(stderr, "Drawing picture at %d %d w=%d h=%d\n", x, y, w, h); copy = Blt_ClonePicture(busyPtr->snapshot); Blt_BlendPictures(copy, busyPtr->picture, 0, 0, w, h, x, y); } Blt_PaintPicture(painter, drawable, copy, 0, 0, busyPtr->width, busyPtr->height, busyPtr->x, busyPtr->y, 0); if (copy != busyPtr->snapshot) { Blt_FreePicture(copy); } } #ifdef notdef if (busyPtr->text != NULL) { Blt_DrawText(drawable); } if (busyPtr->picture != NULL) { int x, y; Blt_BlendPicture(painter, drawable, busyPtr->picture, 0, 0, busyPtr->width, busyPtr->height, busyPtr->x, busyPtr->y, 0); Tk_RedrawImage(drawable, busyPtr->text); } #endif XCopyArea(busyPtr->display, drawable, Tk_WindowId(tkwin), DefaultGC(busyPtr->display, Tk_ScreenNumber(tkwin)), 0, 0, busyPtr->width, busyPtr->height, 0, 0); Tk_FreePixmap(busyPtr->display, drawable); } #endif /* NO_BUSY */ ���./saods9/blt3.0.1/src/bltWinop.c��������������������������������������������������������������������0000644�0001750�0001750�00000024732�11462120063�015000� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinop.c -- * * This module implements simple window commands for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_WINOP #include "bltOp.h" #include "bltPicture.h" #include "bltImage.h" #include <X11/Xutil.h> #include "tkDisplay.h" #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) static Tcl_ObjCmdProc WinopCmd; static int GetRealizedWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Window *tkwinPtr) { const char *string; Tk_Window tkwin; string = Tcl_GetString(objPtr); assert(interp != NULL); tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } if (Tk_WindowId(tkwin) == None) { Tk_MakeWindowExist(tkwin); } *tkwinPtr = tkwin; return TCL_OK; } static int GetWindowFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Window *windowPtr) { const char *string; string = Tcl_GetString(objPtr); if (string[0] == '.') { Tk_Window tkwin; if (GetRealizedWindowFromObj(interp, objPtr, &tkwin) != TCL_OK) { return TCL_ERROR; } if (Tk_IsTopLevel(tkwin)) { *windowPtr = Blt_GetWindowId(tkwin); } else { *windowPtr = Tk_WindowId(tkwin); } } else if (strcmp(string, "root") == 0) { *windowPtr = Tk_RootWindow(Tk_MainWindow(interp)); } else { int xid; if (Tcl_GetIntFromObj(interp, objPtr, &xid) != TCL_OK) { return TCL_ERROR; } #ifdef WIN32 { static TkWinWindow tkWinWindow; tkWinWindow.handle = (HWND)xid; tkWinWindow.winPtr = NULL; tkWinWindow.type = TWD_WINDOW; *windowPtr = (Window)&tkWinWindow; } #else *windowPtr = (Window)xid; #endif } return TCL_OK; } /*ARGSUSED*/ static int LowerOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { Window window; if (GetWindowFromObj(interp, objv[i], &window) != TCL_OK) { return TCL_ERROR; } XLowerWindow(Tk_Display(tkMain), window); } return TCL_OK; } /*ARGSUSED*/ static int RaiseOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { Window window; if (GetWindowFromObj(interp, objv[i], &window) != TCL_OK) { return TCL_ERROR; } XRaiseWindow(Tk_Display(tkMain), window); } return TCL_OK; } /*ARGSUSED*/ static int MapOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { const char *string; Window window; string = Tcl_GetString(objv[i]); if (string[0] == '.') { Tk_Window tkwin; Tk_FakeWin *fakePtr; if (GetRealizedWindowFromObj(interp, objv[i], &tkwin) != TCL_OK) { return TCL_ERROR; } #ifdef WIN32 Tk_MapWindow(tkwin); #endif fakePtr = (Tk_FakeWin *) tkwin; fakePtr->flags |= TK_MAPPED; window = Tk_WindowId(tkwin); } else { int xid; if (Tcl_GetIntFromObj(interp, objv[i], &xid) != TCL_OK) { return TCL_ERROR; } window = (Window)xid; } XMapWindow(Tk_Display(tkMain), window); } return TCL_OK; } /*ARGSUSED*/ static int MoveOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; Window window; if (GetWindowFromObj(interp, objv[2], &window) != TCL_OK) { return TCL_ERROR; } if (Tk_GetPixelsFromObj(interp, tkMain, objv[3], &x) != TCL_OK) { return TCL_ERROR; } if (Tk_GetPixelsFromObj(interp, tkMain, objv[4], &y) != TCL_OK) { return TCL_ERROR; } XMoveWindow(Tk_Display(tkMain), window, x, y); return TCL_OK; } /*ARGSUSED*/ static int UnmapOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 2; i < objc; i++) { const char *string; Window window; string = Tcl_GetString(objv[i]); if (string[0] == '.') { Tk_Window tkwin; Tk_FakeWin *fakePtr; if (GetRealizedWindowFromObj(interp, objv[i], &tkwin) != TCL_OK) { return TCL_ERROR; } fakePtr = (Tk_FakeWin *) tkwin; fakePtr->flags &= ~TK_MAPPED; window = Tk_WindowId(tkwin); } else { int xid; if (Tcl_GetIntFromObj(interp, objv[i], &xid) != TCL_OK) { return TCL_ERROR; } window = (Window)xid; } XMapWindow(Tk_Display(tkMain), window); } return TCL_OK; } /* ARGSUSED */ static int ChangesOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_Window tkwin; if (GetRealizedWindowFromObj(interp, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } if (Tk_IsTopLevel(tkwin)) { XSetWindowAttributes attrs; Window window; unsigned int mask; window = Blt_GetWindowId(tkwin); attrs.backing_store = WhenMapped; attrs.save_under = True; mask = CWBackingStore | CWSaveUnder; XChangeWindowAttributes(Tk_Display(tkwin), window, mask, &attrs); } return TCL_OK; } /* ARGSUSED */ static int GeometryOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Window d; int x, y, w, h; Tcl_Obj *listObjPtr; if (GetWindowFromObj(interp, objv[2], &d) != TCL_OK) { return TCL_ERROR; } Blt_GetWindowRegion(Tk_Display(tkMain), d, &x, &y, &w, &h); listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(x)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(y)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(w)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(h)); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* ARGSUSED */ static int QueryOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int rootX, rootY, childX, childY; Window root, child; unsigned int mask; /* GetCursorPos */ if (XQueryPointer(Tk_Display(tkMain), Tk_WindowId(tkMain), &root, &child, &rootX, &rootY, &childX, &childY, &mask)) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(rootX)); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(rootY)); Tcl_SetObjResult(interp, listObjPtr); } return TCL_OK; } /* ARGSUSED */ static int TreeOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Window *ancestors, window, root, parent; unsigned int nAncestors; if (GetWindowFromObj(interp, objv[2], &window) != TCL_OK) { return TCL_ERROR; } if ((XQueryTree(Tk_Display(tkMain), window, &root, &parent, &ancestors, &nAncestors)) && (nAncestors > 0)) { unsigned int i; Tcl_Obj *listObjPtr; char string[200]; Tcl_Obj *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); sprintf(string, "0x%x", (unsigned int)root); objPtr = Tcl_NewStringObj(string , -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); sprintf(string, "0x%x", (unsigned int)parent); objPtr = Tcl_NewStringObj(string , -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); sprintf(string, "0x%x", (unsigned int)window); objPtr = Tcl_NewStringObj(string , -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); for (i = 0; i < nAncestors; i++) { sprintf(string, "0x%x", (unsigned int)ancestors[i]); objPtr = Tcl_NewStringObj(string , -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); if (ancestors != NULL) { XFree((char *)ancestors); } } return TCL_OK; } /*ARGSUSED*/ static int WarpToOp(Tk_Window tkMain, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 3) { Tk_Window tkwin; if (GetRealizedWindowFromObj(interp, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } if (!Tk_IsMapped(tkwin)) { Tcl_AppendResult(interp, "can't warp to unmapped window \"", Tk_PathName(tkwin), "\"", (char *)NULL); return TCL_ERROR; } XWarpPointer(Tk_Display(tkwin), None, Tk_WindowId(tkwin), 0, 0, 0, 0, Tk_Width(tkwin) / 2, Tk_Height(tkwin) / 2); } else if (objc == 4) { int x, y; Window root; if ((Tk_GetPixelsFromObj(interp, tkMain, objv[2], &x) != TCL_OK) || (Tk_GetPixelsFromObj(interp, tkMain, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } root = Tk_RootWindow(tkMain); XWarpPointer(Tk_Display(tkMain), None, root, 0, 0, 0, 0, x, y); } return QueryOp(tkMain, interp, 0, (Tcl_Obj **)NULL); } static Blt_OpSpec winOps[] = { {"changes", 1, ChangesOp, 3, 3, "window",}, {"geometry",1, GeometryOp, 3, 3, "window",}, {"lower", 1, LowerOp, 2, 0, "window ?window?...",}, {"map", 2, MapOp, 2, 0, "window ?window?...",}, {"move", 2, MoveOp, 5, 5, "window x y",}, {"query", 1, QueryOp, 2, 2, "",}, {"raise", 1, RaiseOp, 2, 0, "window ?window?...",}, {"tree", 1, TreeOp, 3, 3, "window",}, {"unmap", 1, UnmapOp, 2, 0, "window ?window?...",}, {"warpto", 1, WarpToOp, 2, 5, "?window?",}, }; static int nWinOps = sizeof(winOps) / sizeof(Blt_OpSpec); /* ARGSUSED */ static int WinopCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; Tk_Window tkwin; proc = Blt_GetOpFromObj(interp, nWinOps, winOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } tkwin = Tk_MainWindow(interp); result = (*proc) (tkwin, interp, objc, objv); return result; } int Blt_WinopCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"winop", WinopCmd,}; return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_WINOP */ ��������������������������������������./saods9/blt3.0.1/src/bltBitmap.c�������������������������������������������������������������������0000644�0001750�0001750�00000124166�11462120062�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBitmap.c -- * * This module implements TCL bitmaps for the Tk toolkit. * * Copyright 1993-1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Much of the code is taken from XRdBitF.c and XWrBitF.c from the MIT * X11R5 distribution. * * Copyright, 1987, Massachusetts Institute of Technology * Permission to use, copy, modify, distribute, and sell this * software and its documentation for any purpose is hereby * granted without fee, provided that the above copyright notice * appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and * that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without * specific, written prior permission. M.I.T. makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. */ /* Predefined table holds bitmap info (source width, height) Name table holds bitmap names Id table hold bitmap ids Both id and name tables get you the actual bitmap. */ #include "bltInt.h" #ifndef NO_BITMAP #include "bltOp.h" #include "bltHash.h" #include "bltFont.h" #include "bltText.h" #include <X11/Xutil.h> #define BITMAP_THREAD_KEY "BLT Bitmap Data" /* * BitmapInterpData -- * * Tk's routine to create a bitmap, Tk_DefineBitmap, assumes that * the source (bit array) is always statically allocated. This * isn't true here (we dynamically allocate the arrays), so we have * to save them in a hashtable and cleanup after the interpreter * is deleted. */ typedef struct { Blt_HashTable bitmapTable; /* Hash table of bitmap data keyed by * the name of the bitmap. */ Tcl_Interp *interp; Display *display; /* Display of interpreter. */ Tk_Window tkMain; /* Main window of interpreter. */ } BitmapInterpData; #define MAX_SIZE 255 /* * BitmapInfo -- */ typedef struct { float angle; /* Rotation of text string */ float scale; /* Scaling factor */ Blt_Font font; /* Font pointer */ Tk_Justify justify; /* Justify text */ Blt_Pad xPad, yPad; /* Padding around the text */ } BitmapInfo; /* * BitmapData -- */ typedef struct { int width, height; /* Dimension of image */ unsigned char *bits; /* Data array for bitmap image */ } BitmapData; #define DEF_BITMAP_FONT STD_FONT #define DEF_BITMAP_PAD "4" #define DEF_BITMAP_ANGLE "0.0" #define DEF_BITMAP_SCALE "1.0" #define DEF_BITMAP_JUSTIFY "center" #define ROTATE_0 0 #define ROTATE_90 1 #define ROTATE_180 2 #define ROTATE_270 3 static Blt_ConfigSpec composeConfigSpecs[] = { {BLT_CONFIG_FONT, "-font", (char *)NULL, (char *)NULL, DEF_BITMAP_FONT, Blt_Offset(BitmapInfo, font), 0}, {BLT_CONFIG_JUSTIFY, "-justify", (char *)NULL, (char *)NULL, DEF_BITMAP_JUSTIFY, Blt_Offset(BitmapInfo, justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-padx", (char *)NULL, (char *)NULL, DEF_BITMAP_PAD, Blt_Offset(BitmapInfo, xPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pady", (char *)NULL, (char *)NULL, DEF_BITMAP_PAD, Blt_Offset(BitmapInfo, yPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-rotate", (char *)NULL, (char *)NULL, DEF_BITMAP_ANGLE, Blt_Offset(BitmapInfo, angle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-scale", (char *)NULL, (char *)NULL, DEF_BITMAP_SCALE, Blt_Offset(BitmapInfo, scale), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec defineConfigSpecs[] = { {BLT_CONFIG_FLOAT, "-rotate", (char *)NULL, (char *)NULL, DEF_BITMAP_ANGLE, Blt_Offset(BitmapInfo, angle), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FLOAT, "-scale", (char *)NULL, (char *)NULL, DEF_BITMAP_SCALE, Blt_Offset(BitmapInfo, scale), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Shared data for the image read/parse logic */ static unsigned char hexTable[256]; /* conversion value */ static int initialized = 0; /* easier to fill in at run time */ #define blt_width 40 #define blt_height 40 static unsigned char blt_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x03, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0xe4, 0x33, 0x3f, 0x01, 0x00, 0x64, 0x36, 0x0c, 0x01, 0x00, 0x64, 0x36, 0x8c, 0x00, 0x00, 0xe4, 0x33, 0x8c, 0x00, 0x00, 0x64, 0x36, 0x8c, 0x00, 0x00, 0x64, 0x36, 0x0c, 0x01, 0x00, 0xe4, 0xf3, 0x0d, 0x01, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0xfc, 0xff, 0xff, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf8, 0xff, 0x03, 0x80, 0xed, 0x07, 0x00, 0x04, 0xe0, 0x0c, 0x00, 0x20, 0x09, 0x10, 0x0c, 0x00, 0x00, 0x12, 0x10, 0x0c, 0x00, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x19, 0xd0, 0x03, 0x00, 0x00, 0x14, 0xb0, 0xfe, 0xff, 0xff, 0x1b, 0x50, 0x55, 0x55, 0x55, 0x0d, 0xe8, 0xaa, 0xaa, 0xaa, 0x16, 0xe4, 0xff, 0xff, 0xff, 0x2f, 0xf4, 0xff, 0xff, 0xff, 0x27, 0xd8, 0xae, 0xaa, 0xbd, 0x2d, 0x6c, 0x5f, 0xd5, 0x67, 0x1b, 0xbc, 0xf3, 0x7f, 0xd0, 0x36, 0xf8, 0x01, 0x10, 0xcc, 0x1f, 0xe0, 0x45, 0x8e, 0x92, 0x0f, 0xb0, 0x32, 0x41, 0x43, 0x0b, 0xd0, 0xcf, 0x3c, 0x7c, 0x0d, 0xb0, 0xaa, 0xc2, 0xab, 0x0a, 0x60, 0x55, 0x55, 0x55, 0x05, 0xc0, 0xff, 0xab, 0xaa, 0x03, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define bigblt_width 64 #define bigblt_height 64 static unsigned char bigblt_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe2, 0x0f, 0xc7, 0xff, 0x10, 0x00, 0x00, 0x00, 0xe2, 0x1f, 0xc7, 0xff, 0x10, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x1f, 0x07, 0x1c, 0x04, 0x00, 0x00, 0x00, 0xe2, 0x1f, 0x07, 0x1c, 0x04, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x38, 0x07, 0x1c, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x1f, 0xff, 0x1c, 0x10, 0x00, 0x00, 0x00, 0xe2, 0x0f, 0xff, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xc0, 0xff, 0xff, 0x07, 0x00, 0x00, 0xe0, 0xf6, 0x3f, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x06, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x80, 0x03, 0x06, 0x00, 0x00, 0xc0, 0x08, 0x03, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x04, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x40, 0x55, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x06, 0x80, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x03, 0x40, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x01, 0x70, 0x57, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x04, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0xd8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0xd0, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xf0, 0xda, 0xbf, 0xaa, 0xba, 0xfd, 0xd6, 0x0b, 0x70, 0xed, 0x77, 0x55, 0x57, 0xe5, 0xad, 0x07, 0xb8, 0xf7, 0xab, 0xaa, 0xaa, 0xd2, 0x5b, 0x0f, 0xf8, 0xfb, 0x54, 0x55, 0x75, 0x94, 0xf7, 0x1e, 0xf0, 0x7b, 0xfa, 0xff, 0x9f, 0xa9, 0xef, 0x1f, 0xc0, 0xbf, 0x00, 0x20, 0x40, 0x54, 0xfe, 0x0f, 0x00, 0x1f, 0x92, 0x00, 0x04, 0xa9, 0xfc, 0x01, 0xc0, 0x5f, 0x41, 0xf9, 0x04, 0x21, 0xfd, 0x00, 0xc0, 0x9b, 0x28, 0x04, 0xd8, 0x0a, 0x9a, 0x03, 0x40, 0x5d, 0x08, 0x40, 0x44, 0x44, 0x62, 0x03, 0xc0, 0xaa, 0x67, 0xe2, 0x03, 0x64, 0xba, 0x02, 0x40, 0x55, 0xd5, 0x55, 0xfd, 0xdb, 0x55, 0x03, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x01, 0x00, 0x57, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x00, 0x00, 0xac, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0xf0, 0xff, 0x57, 0x55, 0x55, 0x1d, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static Tcl_ObjCmdProc BitmapCmd; static Tcl_InterpDeleteProc BitmapInterpDeleteProc; /* *--------------------------------------------------------------------------- * * GetHexValue -- * * Converts the hexadecimal string into an unsigned integer * value. The hexadecimal string need not have a leading "0x". * * Results: * Returns a standard TCL result. If the conversion was * successful, TCL_OK is returned, otherwise TCL_ERROR. * * Side Effects: * If the conversion fails, interp->result is filled with an * error message. * *--------------------------------------------------------------------------- */ static int GetHexValue(Tcl_Interp *interp, const char *string, int *valuePtr) { const char *s; int value; s = string; if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) { s += 2; } if (s[0] == '\0') { Tcl_AppendResult(interp, "expecting hex value: got \"", string, "\"", (char *)NULL); return TCL_ERROR; /* Only found "0x" */ } value = 0; for ( /*empty*/ ; *s != '\0'; s++) { unsigned char byte; /* Trim high bits, check type and accumulate */ byte = hexTable[(int)*s]; if (byte == 0xFF) { Tcl_AppendResult(interp, "expecting hex value: got \"", string, "\"", (char *)NULL); return TCL_ERROR; /* Not a hexadecimal number */ } value = (value << 4) | byte; } *valuePtr = value; return TCL_OK; } #ifdef WIN32 /* *--------------------------------------------------------------------------- * * BitmapToData -- * * Converts a bitmap into an data array. * * Results: * Returns the number of bytes in an data array representing the bitmap. * * Side Effects: * Memory is allocated for the data array. Caller must free * array later. * *--------------------------------------------------------------------------- */ static int BitmapToData( Tk_Window tkwin, /* Main window of interpreter */ Pixmap bitmap, /* Bitmap to be queried */ int width, int height, /* Dimensions of the bitmap */ unsigned char **bitsPtr) /* Pointer to converted array of data */ { int y; int count; int nBytes, bytes_per_line; unsigned char *bits; unsigned char *srcBits; int bytesPerRow; *bitsPtr = NULL; srcBits = Blt_GetBitmapData(Tk_Display(tkwin), bitmap, width, height, &bytesPerRow); if (srcBits == NULL) { OutputDebugString("BitmapToData: Can't get bitmap data"); return 0; } bytes_per_line = (width + 7) / 8; nBytes = height * bytes_per_line; bits = Blt_AssertMalloc(sizeof(unsigned char) * nBytes); count = 0; for (y = height - 1; y >= 0; y--) { unsigned char *srcPtr; int value, bitMask; int x; srcPtr = srcBits + (bytesPerRow * y); value = 0, bitMask = 1; for (x = 0; x < width; /* empty */ ) { unsigned long pixel; pixel = (*srcPtr & (0x80 >> (x % 8))); if (pixel) { value |= bitMask; } bitMask <<= 1; x++; if (!(x & 7)) { bits[count++] = (unsigned char)value; value = 0, bitMask = 1; srcPtr++; } } if (x & 7) { bits[count++] = (unsigned char)value; } } *bitsPtr = bits; return count; } #else /* *--------------------------------------------------------------------------- * * BitmapToData -- * * Converts a bitmap into an data array. * * Results: * Returns the number of bytes in an data array representing the bitmap. * * Side Effects: * Memory is allocated for the data array. Caller must free * array later. * *--------------------------------------------------------------------------- */ static int BitmapToData( Tk_Window tkwin, /* Main window of interpreter */ Pixmap bitmap, /* Bitmap to be queried */ int width, int height, /* Dimensions of the bitmap */ unsigned char **bitsPtr) /* Pointer to converted array of data */ { int y; int count; int nBytes, bytes_per_line; Display *display; XImage *imagePtr; unsigned char *bits; display = Tk_Display(tkwin); /* Convert the bitmap to an X image */ imagePtr = XGetImage(display, bitmap, 0, 0, width, height, 1L, XYPixmap); /* * The slow but robust brute force method of converting an X image: */ bytes_per_line = (width + 7) / 8; nBytes = height * bytes_per_line; bits = Blt_AssertMalloc(sizeof(unsigned char) * nBytes); count = 0; for (y = 0; y < height; y++) { int value, bitMask; int x; value = 0, bitMask = 1; for (x = 0; x < width; /*empty*/ ) { unsigned long pixel; pixel = XGetPixel(imagePtr, x, y); if (pixel) { value |= bitMask; } bitMask <<= 1; x++; if (!(x & 7)) { bits[count++] = (unsigned char)value; value = 0, bitMask = 1; } } if (x & 7) { bits[count++] = (unsigned char)value; } } XDestroyImage(imagePtr); *bitsPtr = bits; return count; } #endif /* *--------------------------------------------------------------------------- * * AsciiToData -- * * Converts a TCL list of ASCII values into a data array. * * Results: * A standard TCL result. * * Side Effects: * If an error occurs while processing the data, interp->result * is filled with a corresponding error message. * *--------------------------------------------------------------------------- */ static int AsciiToData( Tcl_Interp *interp, /* Interpreter to report results to */ char *elemList, /* List of of hex numbers representing * bitmap data */ int width, int height, /* Dimension of bitmap. */ unsigned char **bitsPtr) /* data array (output) */ { int nBytes; /* Number of bytes of data */ int value; /* from an input line */ int padding; /* to handle alignment */ int bytesPerLine; /* per scanline of data */ unsigned char *bits; int count; enum Formats { V10, V11 } format; int i; /* */ const char **valueArr; int nValues; /* First time through initialize the ascii->hex translation table */ if (!initialized) { Blt_InitHexTable(hexTable); initialized = 1; } if (Tcl_SplitList(interp, elemList, &nValues, &valueArr) != TCL_OK) { return TCL_ERROR; } bytesPerLine = (width + 7) / 8; nBytes = bytesPerLine * height; if (nValues == nBytes) { format = V11; } else if (nValues == (nBytes / 2)) { format = V10; } else { Tcl_AppendResult(interp, "bitmap has wrong # of data values", (char *)NULL); goto error; } padding = 0; if (format == V10) { padding = ((width % 16) && ((width % 16) < 9)); if (padding) { bytesPerLine = (width + 7) / 8 + padding; nBytes = bytesPerLine * height; } } bits = Blt_Calloc(nBytes, sizeof(unsigned char)); if (bits == NULL) { Tcl_AppendResult(interp, "can't allocate memory for bitmap", (char *)NULL); goto error; } count = 0; for (i = 0; i < nValues; i++) { if (GetHexValue(interp, valueArr[i], &value) != TCL_OK) { Blt_Free(bits); goto error; } bits[count++] = (unsigned char)value; if (format == V10) { if ((!padding) || (((i * 2) + 2) % bytesPerLine)) { bits[count++] = value >> 8; } } } Blt_Free(valueArr); *bitsPtr = bits; return TCL_OK; error: Blt_Free(valueArr); return TCL_ERROR; } static int ParseListData( Tcl_Interp *interp, Tcl_Obj *objPtr, int *widthPtr, int *heightPtr, unsigned char **bitsPtr) { char *p; int width, height; char *string; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc == 2) { Tcl_Obj **dims; int nDims; if (Tcl_ListObjGetElements(interp, objv[0], &nDims, &dims) != TCL_OK) { return TCL_ERROR; } if (nDims != 2) { Tcl_AppendResult(interp, "wrong # of bitmap dimensions: ", "should be \"width height\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, dims[0], &width) != TCL_OK) || (Tcl_GetIntFromObj(interp, dims[1], &height) != TCL_OK)) { return TCL_ERROR; } string = Tcl_GetString(objv[1]); } else if (objc == 3) { if ((Tcl_GetIntFromObj(interp, objv[0], &width) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[1], &height) != TCL_OK)) { return TCL_ERROR; } string = Tcl_GetString(objv[2]); } else { Tcl_AppendResult(interp, "wrong # of bitmap data components: ", "should be \"dimensions sourceData\"", (char *)NULL); return TCL_ERROR;; } if ((width < 1) || (height < 1)) { Tcl_AppendResult(interp, "bad bitmap dimensions", (char *)NULL); return TCL_ERROR; } /* Convert commas to blank spaces */ string = Blt_AssertStrdup(string); for (p = string; *p != '\0'; p++) { if (*p == ',') { *p = ' '; } } if (AsciiToData(interp, string, width, height, bitsPtr) != TCL_OK) { Blt_Free(string); return TCL_ERROR; } *widthPtr = width; *heightPtr = height; return TCL_OK; } /* * Parse the lines that define the dimensions of the bitmap, * plus the first line that defines the bitmap data (it declares * the name of a data variable but doesn't include any actual * data). These lines look something like the following: * * #define foo_width 16 * #define foo_height 16 * #define foo_x_hot 3 * #define foo_y_hot 3 * static char foo_bits[] = { * * The x_hot and y_hot lines may or may not be present. It's * important to check for "char" in the last line, in order to * reject old X10-style bitmaps that used shorts. */ static int ParseStructData(Tcl_Interp *interp, Tcl_Obj *objPtr, int *widthPtr, int *heightPtr, unsigned char **bitsPtr) { int width, height; int hotX, hotY; char *line, *nextline; char *data; char *string; width = height = 0; hotX = hotY = -1; data = NULL; { char *p; /* Skip leading spaces. */ for (p = Tcl_GetString(objPtr); isspace(UCHAR(*p)); p++) { /*empty*/ } string = Blt_AssertStrdup(p); } nextline = string; for (line = string; nextline != NULL; line = nextline + 1) { Tcl_RegExp re; nextline = strchr(line, '\n'); if ((nextline == NULL) || (line == nextline)) { continue; /* Empty line */ } *nextline = '\0'; re = Tcl_RegExpCompile(interp, " *# *define +"); if (Tcl_RegExpExec(interp, re, line, line)) { const char *start, *end; const char *name, *value; size_t len; Tcl_RegExpRange(re, 0, &start, &end); name = strtok((char *)end, " \t"); value = strtok(NULL, " \t"); if ((name == NULL) || (value == NULL)) { Tcl_AppendResult(interp, "what's the error?", (char *)NULL); goto error; } len = strlen(name); if ((len >= 6) && (name[len-6] == '_') && (strcmp(name+len-6, "_width") == 0)) { if (Tcl_GetInt(interp, value, &width) != TCL_OK) { goto error; } } else if ((len >= 7) && (name[len-7] == '_') && (strcmp(name+len-7, "_height") == 0)) { if (Tcl_GetInt(interp, value, &height) != TCL_OK) { goto error; } } else if ((len >= 6) && (name[len-6] == '_') && (strcmp(name+len-6, "_x_hot") == 0)) { if (Tcl_GetInt(interp, value, &hotX) != TCL_OK) { goto error; } } else if ((len >= 6) && (name[len-6] == '_') && (strcmp(name+len-6, "_y_hot") == 0)) { if (Tcl_GetInt(interp, value, &hotY) != TCL_OK) { goto error; } } } else { re = Tcl_RegExpCompile(interp, " *static +.*char +"); if (Tcl_RegExpExec(interp, re, line, line)) { char *p; /* Find the { */ /* Repair the string so we can search the entire string. */ *nextline = ' '; p = strchr(line, '{'); if (p == NULL) { goto error; } data = p + 1; break; } else { Tcl_AppendResult(interp, "unknown bitmap format \"", line, "\": obsolete X10 bitmap file?", (char *)NULL); goto error; } } } /* * Now we've read everything but the data. Allocate an array * and read in the data. */ if ((width <= 0) || (height <= 0)) { Tcl_AppendResult(interp, "invalid bitmap dimensions \"", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(width), " x ", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(height), "\"", (char *)NULL); goto error; } { char *p; for (p = data; *p != '\0'; p++) { if ((*p == ',') || (*p == ';') || (*p == '}')) { *p = ' '; } } } if (AsciiToData(interp, data, width, height, bitsPtr) != TCL_OK) { goto error; } *widthPtr = width; *heightPtr = height; Blt_Free(string); return TCL_OK; error: Blt_Free(string); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * ScaleRotateData -- * * Creates a new data array of the rotated and scaled bitmap. * * Results: * A standard TCL result. If the bitmap data is rotated * successfully, TCL_OK is returned. But if memory could not be * allocated for the new data array, TCL_ERROR is returned and an * error message is left in interp->result. * * Side Effects: * Memory is allocated for rotated, scaled data array. Caller * must free array later. * *--------------------------------------------------------------------------- */ static int ScaleRotateData( Tcl_Interp *interp, /* Interpreter to report results to */ BitmapData *srcPtr, /* Source bitmap to transform. */ float angle, /* Number of degrees to rotate the bitmap. */ float scale, /* Factor to scale the bitmap. */ BitmapData *destPtr) /* Destination bitmap. */ { int x, y; double srcX, srcY, destX, destY; /* Origins of source and destination * bitmaps */ double sinTheta, cosTheta; double rotWidth, rotHeight; double radians; unsigned char *bits; int nBytes; int srcBytesPerLine, destBytesPerLine; srcBytesPerLine = (srcPtr->width + 7) / 8; Blt_GetBoundingBox(srcPtr->width, srcPtr->height, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destPtr->width = (int)(rotWidth * scale + 0.5) ; destPtr->height = (int)(rotHeight * scale + 0.5); destBytesPerLine = (destPtr->width + 7) / 8; nBytes = destPtr->height * destBytesPerLine; bits = Blt_Calloc(nBytes, sizeof(unsigned char)); if (bits == NULL) { Tcl_AppendResult(interp, "can't allocate bitmap data array", (char *)NULL); return TCL_ERROR; } scale = 1.0 / scale; destPtr->bits = bits; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians); cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ srcX = srcPtr->width * 0.5; srcY = srcPtr->height * 0.5; destX = rotWidth * 0.5; destY = rotHeight * 0.5; /* * Rotate each pixel of dest image, placing results in source X image */ for (y = 0; y < destPtr->height; y++) { for (x = 0; x < destPtr->width; x++) { double sxd, syd; int sx, sy; int pixel, ipixel; sxd = scale * (double)x; syd = scale * (double)y; if (angle == 270.0) { sx = (int)syd, sy = (int)(rotWidth - sxd) - 1; } else if (angle == 180.0) { sx = (int)(rotWidth - sxd) - 1, sy = (int)(rotHeight - syd) - 1; } else if (angle == 90.0) { sx = (int)(rotHeight - syd) - 1, sy = (int)sxd; } else if (angle == 0.0) { sx = (int)sxd, sy = (int)syd; } else { double tx, ty, rx, ry; /* Translate origin to center of destination X image */ tx = sxd - destX; ty = syd - destY; /* Rotate the coordinates about the origin */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source X image */ rx += srcX; ry += srcY; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination X image * can be bigger than the source. */ if ((sx >= srcPtr->width) || (sx < 0) || (sy >= srcPtr->height) || (sy < 0)) { continue; } } ipixel = (srcBytesPerLine * sy) + (sx / 8); pixel = srcPtr->bits[ipixel] & (1 << (sx % 8)); if (pixel) { ipixel = (destBytesPerLine * y) + (x / 8); bits[ipixel] |= (1 << (x % 8)); } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * BitmapDataToString -- * * Returns a list of hex values corresponding to the data * bits of the bitmap given. * * Converts the unsigned character value into a two character * hexadecimal string. A separator is also added, which may * either a newline or space according the the number of bytes * already output. * * Results: * Returns TCL_ERROR if a data array can't be generated * from the bitmap (memory allocation failure), otherwise TCL_OK. * *--------------------------------------------------------------------------- */ static void BitmapDataToString( Tk_Window tkwin, /* Main window of interpreter */ Pixmap bitmap, /* Bitmap to be queried */ Tcl_DString *resultPtr) /* Dynamic string to output results to */ { unsigned char *bits; int nBytes; int i; int width, height; /* Get the dimensions of the bitmap */ Tk_SizeOfBitmap(Tk_Display(tkwin), bitmap, &width, &height); nBytes = BitmapToData(tkwin, bitmap, width, height, &bits); #define BYTES_PER_OUTPUT_LINE 24 for (i = 0; i < nBytes; i++) { const char *separator; char string[200]; separator = (i % BYTES_PER_OUTPUT_LINE) ? " " : "\n "; sprintf_s(string, 200, "%s%02x", separator, bits[i]); Tcl_DStringAppend(resultPtr, string, -1); } if (bits != NULL) { Blt_Free(bits); } } /* *--------------------------------------------------------------------------- * * ComposeOp -- * * Converts the text string into an internal bitmap. * * There's a lot of extra (read unnecessary) work going on here, * but I don't (right now) think that it matters much. The * rotated bitmap (formerly an X image) is converted back to an * image just so we can convert it to a data array for * Tk_DefineBitmap. * * Results: * A standard TCL result. * * Side Effects: * If an error occurs while processing the data, interp->result * is filled with a corresponding error message. * *--------------------------------------------------------------------------- */ static int ComposeOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Number of arguments */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInfo bi; /* Text rotation and font information */ BitmapInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Pixmap bitmap; /* Text bitmap */ TextLayout *textPtr; TextStyle ts; char *string; float angle; int nBytes; int isNew; int result; int width, height; /* Dimensions of bitmap */ unsigned char *bits; /* Data array derived from text bitmap */ bitmap = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, dataPtr->tkMain, objv[2]); if (bitmap != None) { Tk_FreeBitmap(dataPtr->display, bitmap); return TCL_OK; } /* Initialize info and process flags */ bi.justify = TK_JUSTIFY_CENTER; bi.angle = 0.0f; /* No rotation or scaling by default */ bi.scale = 1.0f; bi.padLeft = bi.padRight = 0; bi.padTop = bi.padBottom = 0; bi.font = (Blt_Font)NULL; /* Initialized by Blt_ConfigureWidget */ if (Blt_ConfigureWidgetFromObj(interp, dataPtr->tkMain, composeConfigSpecs, objc - 4, objv + 4, (char *)&bi, 0) != TCL_OK) { return TCL_ERROR; } angle = FMOD(bi.angle, 360.0); if (angle < 0.0) { angle += 360.0; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, bi.font); Blt_Ts_SetJustify(ts, bi.justify); Blt_Ts_SetPadding(ts, bi.xPad.side1, bi.yPad.side2, bi.yPad.side1, bi.yPad.side2); string = Tcl_GetStringFromObj(objv[3], &nBytes); textPtr = Blt_Ts_CreateLayout(string, nBytes, &ts); bitmap = Blt_Ts_Bitmap(dataPtr->tkMain, textPtr, &ts, &width, &height); Blt_Free(textPtr); if (bitmap == None) { Tcl_AppendResult(interp, "can't create bitmap", (char *)NULL); return TCL_ERROR; } /* Free the font structure, since we don't need it anymore */ Blt_FreeOptions(composeConfigSpecs, (char *)&bi, dataPtr->display, 0); /* Convert bitmap back to a data array */ nBytes = BitmapToData(dataPtr->tkMain, bitmap, width, height, &bits); Tk_FreePixmap(dataPtr->display, bitmap); if (nBytes == 0) { Tcl_AppendResult(interp, "can't get bitmap data", (char *)NULL); return TCL_ERROR; } /* If bitmap is to be rotated or scaled, do it here */ if ((angle != 0.0) || (bi.scale != 1.0f)) { BitmapData srcData, destData; srcData.bits = bits; srcData.width = width; srcData.height = height; result = ScaleRotateData(interp, &srcData, angle, bi.scale, &destData); Blt_Free(bits); /* Free the un-transformed data array. */ if (result != TCL_OK) { return TCL_ERROR; } bits = destData.bits; width = destData.width; height = destData.height; } /* Create the bitmap again, this time using Tk's bitmap facilities */ string = Tcl_GetString(objv[2]); result = Tk_DefineBitmap(interp, Tk_GetUid(string), (char *)bits, width, height); if (result != TCL_OK) { Blt_Free(bits); } hPtr = Blt_CreateHashEntry(&dataPtr->bitmapTable, string, &isNew); Blt_SetHashValue(hPtr, bits); return result; } /* *--------------------------------------------------------------------------- * * DefineOp -- * * Converts the dataList into an internal bitmap. * * Results: * A standard TCL result. * * Side Effects: * If an error occurs while processing the data, interp->result * is filled with a corresponding error message. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int DefineOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Number of arguments */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; int width, height; /* Dimensions of bitmap */ unsigned char *bits; /* working variable */ char *p; BitmapInfo bi; int result; float angle; Pixmap bitmap; Blt_HashEntry *hPtr; int isNew; char *string; bitmap = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, dataPtr->tkMain, objv[2]); if (bitmap != None) { Tk_FreeBitmap(dataPtr->display, bitmap); return TCL_OK; } /* Initialize info and then process flags */ bi.angle = 0.0f; /* No rotation by default */ bi.scale = 1.0f; /* No scaling by default */ if (Blt_ConfigureWidgetFromObj(interp, dataPtr->tkMain, defineConfigSpecs, objc - 4, objv + 4, (char *)&bi, 0) != TCL_OK) { return TCL_ERROR; } bits = NULL; /* Skip leading spaces. */ for (p = Tcl_GetString(objv[3]); isspace(UCHAR(*p)); p++) { /*empty*/ } width = height = 0; /* Suppress compiler warning. */ if (*p == '#') { result = ParseStructData(interp, objv[3], &width, &height, &bits); } else { result = ParseListData(interp, objv[3], &width, &height, &bits); } if (result != TCL_OK) { return TCL_ERROR; } angle = FMOD(bi.angle, 360.0); if (angle < 0.0) { angle += 360.0; } /* If bitmap is to be rotated or scale, do it here */ if ((angle != 0.0) || (bi.scale != 1.0f)) { BitmapData srcData, destData; srcData.bits = bits; srcData.width = width; srcData.height = height; result = ScaleRotateData(interp, &srcData, angle, bi.scale, &destData); Blt_Free(bits); /* Free the array of un-transformed data. */ if (result != TCL_OK) { return TCL_ERROR; } bits = destData.bits; width = destData.width; height = destData.height; } string = Tcl_GetString(objv[2]); result = Tk_DefineBitmap(interp, Tk_GetUid(string), (char *)bits, width, height); if (result != TCL_OK) { Blt_Free(bits); } hPtr = Blt_CreateHashEntry(&dataPtr->bitmapTable, string, &isNew); Blt_SetHashValue(hPtr, bits); return result; } /* *--------------------------------------------------------------------------- * * ExistOp -- * * Indicates if the named bitmap exists. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExistsOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; Pixmap bitmap; bitmap = Tk_AllocBitmapFromObj((Tcl_Interp *)NULL, dataPtr->tkMain, objv[2]); if (bitmap != None) { Tk_FreeBitmap(dataPtr->display, bitmap); } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (bitmap != None)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HeightOp -- * * Returns the height of the named bitmap. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HeightOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; int width, height; Pixmap bitmap; bitmap = Tk_AllocBitmapFromObj(interp, dataPtr->tkMain, objv[2]); if (bitmap == None) { return TCL_ERROR; } Tk_SizeOfBitmap(dataPtr->display, bitmap, &width, &height); Tk_FreeBitmap(dataPtr->display, bitmap); Tcl_SetIntObj(Tcl_GetObjResult(interp), height); return TCL_OK; } /* *--------------------------------------------------------------------------- * * WidthOp -- * * Returns the width of the named bitmap. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int WidthOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; int width, height; Pixmap bitmap; bitmap = Tk_AllocBitmapFromObj(interp, dataPtr->tkMain, objv[2]); if (bitmap == None) { return TCL_ERROR; } Tk_SizeOfBitmap(dataPtr->display, bitmap, &width, &height); Tk_FreeBitmap(dataPtr->display, bitmap); Tcl_SetIntObj(Tcl_GetObjResult(interp), width); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SourceOp -- * * Returns the data array (excluding width and height) * of the named bitmap. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SourceOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; Pixmap bitmap; Tcl_DString dString; bitmap = Tk_AllocBitmapFromObj(interp, dataPtr->tkMain, objv[2]); if (bitmap == None) { return TCL_ERROR; } Tcl_DStringInit(&dString); BitmapDataToString(dataPtr->tkMain, bitmap, &dString); Tk_FreeBitmap(dataPtr->display, bitmap); Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DataOp -- * * Returns the data array, including width and height, * of the named bitmap. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DataOp( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Argument list */ { BitmapInterpData *dataPtr = clientData; Pixmap bitmap; int width, height; Tcl_DString dString; bitmap = Tk_AllocBitmapFromObj(interp, dataPtr->tkMain, objv[2]); if (bitmap == None) { return TCL_ERROR; } Tk_SizeOfBitmap(dataPtr->display, bitmap, &width, &height); Tcl_DStringInit(&dString); Tcl_DStringAppendElement(&dString, Blt_Itoa(width)); Tcl_DStringAppendElement(&dString, Blt_Itoa(height)); Tcl_DStringStartSublist(&dString); BitmapDataToString(dataPtr->tkMain, bitmap, &dString); Tcl_DStringEndSublist(&dString); Tk_FreeBitmap(dataPtr->display, bitmap); Tcl_DStringResult(interp, &dString); return TCL_OK; } /* *--------------------------------------------------------------------------- * * BLT Sub-command specification: * * - Name of the sub-command. * - Minimum number of characters needed to unambiguously * recognize the sub-command. * - Pointer to the function to be called for the sub-command. * - Minimum number of arguments accepted. * - Maximum number of arguments accepted. * - String to be displayed for usage. * *--------------------------------------------------------------------------- */ static Blt_OpSpec bitmapOps[] = { {"compose", 1, ComposeOp, 4, 0, "bitmapName text ?flags?",}, {"data", 2, DataOp, 3, 3, "bitmapName",}, {"define", 2, DefineOp, 4, 0, "bitmapName data ?flags?",}, {"exists", 1, ExistsOp, 3, 3, "bitmapName",}, {"height", 1, HeightOp, 3, 3, "bitmapName",}, {"source", 1, SourceOp, 3, 3, "bitmapName",}, {"width", 1, WidthOp, 3, 3, "bitmapName",}, }; static int nBitmapOps = sizeof(bitmapOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * BitmapCmd -- * * This procedure is invoked to process the TCL command * that corresponds to bitmaps managed by this module. * See the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int BitmapCmd( ClientData clientData, /* Thread-specific data for bitmaps. */ Tcl_Interp *interp, /* Interpreter to report results to */ int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nBitmapOps, bitmapOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * BitmapInterpDeleteProc -- * * This is called when the interpreter is deleted. All the bitmaps * specific to that interpreter are destroyed. * * Results: * None. * * Side effects: * Destroys the bitmap table. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void BitmapInterpDeleteProc( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp) { BitmapInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&dataPtr->bitmapTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { unsigned char *bits; bits = Blt_GetHashValue(hPtr); Blt_Free(bits); } Blt_DeleteHashTable(&dataPtr->bitmapTable); Tcl_DeleteAssocData(interp, BITMAP_THREAD_KEY); Blt_Free(dataPtr); } static BitmapInterpData * GetBitmapInterpData(Tcl_Interp *interp) { BitmapInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (BitmapInterpData *) Tcl_GetAssocData(interp, BITMAP_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(BitmapInterpData)); dataPtr->interp = interp; dataPtr->tkMain = Tk_MainWindow(interp); dataPtr->display = Tk_Display(dataPtr->tkMain); Tcl_SetAssocData(interp, BITMAP_THREAD_KEY, BitmapInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->bitmapTable, BLT_STRING_KEYS); } return dataPtr; } /* *--------------------------------------------------------------------------- * * Blt_BitmapCmdInitProc -- * * This procedure is invoked to initialize the bitmap command. * * Results: * None. * * Side effects: * Adds the command to the interpreter and sets an array variable * which its version number. * *--------------------------------------------------------------------------- */ int Blt_BitmapCmdInitProc(Tcl_Interp *interp) { BitmapInterpData *dataPtr; static Blt_InitCmdSpec cmdSpec = {"bitmap", BitmapCmd }; /* Define the BLT logo bitmaps */ dataPtr = GetBitmapInterpData(interp); cmdSpec.clientData = dataPtr; Tk_DefineBitmap(interp, Tk_GetUid("bigBLT"), (char *)bigblt_bits, bigblt_width, bigblt_height); Tk_DefineBitmap(interp, Tk_GetUid("BLT"), (char *)blt_bits, blt_width, blt_height); Tcl_ResetResult(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_BITMAP */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/config.h.in�������������������������������������������������������������������0000644�0001750�0001750�00000021373�11462120063�015057� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* src/config.h.in. Generated from configure.in by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define the smallest machine value DBL_EPILSON. */ #undef BLT_DBL_EPSILON /* Define 'suffix' as the suffix for library names. */ #undef BLT_LIB_SUFFIX /* Define 'soext' as the extension for shared libraries. */ #undef BLT_SO_EXT /* Define 'prefix' as the prefix for shared library names. */ #undef BLT_SO_PREFIX /* Define to 1 if you have the <ctype.h> header file. */ #undef HAVE_CTYPE_H /* Define to 1 if you have the declaration of `drand48', and to 0 if you don't. */ #undef HAVE_DECL_DRAND48 /* Define to 1 if you have the declaration of `finite', and to 0 if you don't. */ #undef HAVE_DECL_FINITE /* Define to 1 if you have the declaration of `free', and to 0 if you don't. */ #undef HAVE_DECL_FREE /* Define to 1 if you have the declaration of `hypot', and to 0 if you don't. */ #undef HAVE_DECL_HYPOT /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #undef HAVE_DECL_ISFINITE /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ #undef HAVE_DECL_ISNAN /* Define to 1 if you have the declaration of `j1', and to 0 if you don't. */ #undef HAVE_DECL_J1 /* Define to 1 if you have the declaration of `srand48', and to 0 if you don't. */ #undef HAVE_DECL_SRAND48 /* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRCASECMP /* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRNCASECMP /* Define to 1 if you have the declaration of `strtolower', and to 0 if you don't. */ #undef HAVE_DECL_STRTOLOWER /* Define to 1 if you have the `drand48' function. */ #undef HAVE_DRAND48 /* Define to 1 if you have the <errno.h> header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the <expat.h> header file. */ #undef HAVE_EXPAT_H /* Define to 1 if you have the `finite' function. */ #undef HAVE_FINITE /* Define to 1 if you have the <float.h> header file. */ #undef HAVE_FLOAT_H /* Define to 1 if you have the <ft2build.h> header file. */ #undef HAVE_FT2BUILD_H /* Define to 1 if you have the `getpt' function. */ #undef HAVE_GETPT /* Define to 1 if you have the `grantpt' function. */ #undef HAVE_GRANTPT /* Define to 1 if you have the <ieeefp.h> header file. */ #undef HAVE_IEEEFP_H /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `isastream' function. */ #undef HAVE_ISASTREAM /* Define if we have a working 'isinfinite'. */ #undef HAVE_ISFINITE /* Define to 1 if you have the `isnan' function. */ #undef HAVE_ISNAN /* Define to 1 if you have the <jpeglib.h> header file. */ #undef HAVE_JPEGLIB_H /* Define to 1 if you have the `EXPAT' library (-lexpat). */ #undef HAVE_LIBEXPAT /* Define to 1 if you have the `FT2' library (-lfreetype). */ #undef HAVE_LIBFT2 /* Define to 1 if you have the `FTCFG' library (-lfontconfig). */ #undef HAVE_LIBFTCFG /* Define to 1 if you have the `JPG' library (-ljpeg). */ #undef HAVE_LIBJPG /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `MYSQL' library (-lmysqlclient). */ #undef HAVE_LIBMYSQL /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `PNG' library (-lpng). */ #undef HAVE_LIBPNG /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `TIF' library (-ltiff). */ #undef HAVE_LIBTIF /* Define to 1 if you have the `XAU' library (-lXau). */ #undef HAVE_LIBXAU /* Define to 1 if you have the `XDMCP' library (-lXdmcp). */ #undef HAVE_LIBXDMCP /* Define to 1 if you have the `XFT' library (-lXft -lexpat). */ #undef HAVE_LIBXFT /* Define to 1 if you have the `XPM' library (-lXpm). */ #undef HAVE_LIBXPM /* Define to 1 if you have the `XRANDR' library (-lXrandr). */ #undef HAVE_LIBXRANDR /* Define to 1 if you have the `XRENDER' library (-lXrender). */ #undef HAVE_LIBXRENDER /* Define to 1 if you have the `Z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the <limits.h> header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the <malloc.h> header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the <math.h> header file. */ #undef HAVE_MATH_H /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the <mysql/mysql.h> header file. */ #undef HAVE_MYSQL_MYSQL_H /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY /* Define to 1 if you have the `open_controlling_pty' function. */ #undef HAVE_OPEN_CONTROLLING_PTY /* Define to 1 if you have the <png.h> header file. */ #undef HAVE_PNG_H /* Define to 1 if you have the `posix_openpt' function. */ #undef HAVE_POSIX_OPENPT /* Define to 1 if you have the `ptsname' function. */ #undef HAVE_PTSNAME /* Define to 1 if you have the <setjmp.h> header file. */ #undef HAVE_SETJMP_H /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `srand48' function. */ #undef HAVE_SRAND48 /* Define to 1 if you have the <stddef.h> header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the <stropts.h> header file. */ #undef HAVE_STROPTS_H /* Define to 1 if you have the `strtolower' function. */ #undef HAVE_STRTOLOWER /* Define to 1 if you have the <sys/param.h> header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the <sys/time.h> header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the <sys/wait.h> header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the `tcflush' function. */ #undef HAVE_TCFLUSH /* Define to 1 if you have the <termios.h> header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the <tiff.h> header file. */ #undef HAVE_TIFF_H /* Define if 'wait' is a union. */ #undef HAVE_UNION_WAIT /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unlockpt' function. */ #undef HAVE_UNLOCKPT /* Define to 1 if you have the <waitflags.h> header file. */ #undef HAVE_WAITFLAGS_H /* Define to 1 if you have the <X11/extensions/randr.h> header file. */ #undef HAVE_X11_EXTENSIONS_RANDR_H /* Define to 1 if you have the <X11/Xft/Xft.h> header file. */ #undef HAVE_X11_XFT_XFT_H /* Define to 1 if you have the <X11/xpm.h> header file. */ #undef HAVE_X11_XPM_H /* Define if we're compiling for an X86. */ #undef HAVE_X86 /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `float', as computed by sizeof. */ #undef SIZEOF_FLOAT /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #undef TIME_WITH_SYS_TIME /* Define if Tcl stubs are used. */ #undef USE_TCL_STUBS /* Define if Tk stubs are used. */ #undef USE_TK_STUBS /* Define if building for Win32. */ #undef WIN32 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to `int' if <sys/types.h> does not define. */ #undef pid_t /* Define to `unsigned int' if <sys/types.h> does not define. */ #undef size_t ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTed.c����������������������������������������������������������������������0000644�0001750�0001750�00000156436�11462120063�014427� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTed.c -- * * This module implements an editor for the table geometry manager in the BLT * toolkit. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltSwitch.h" #include "bltTable.h" #include "bltFont.h" #include "bltText.h" typedef struct _TableEditor TableEditor; #define TABLE_THREAD_KEY "BLT Table Data" typedef struct { Blt_HashTable tableTable; /* Hash table of table structures keyed by * the address of the reference Tk window */ } TableData; typedef struct { int flags; Tcl_Interp *interp; Tk_Window tkwin; /* Entry window */ TableEntry *tePtr; /* Entry it represents */ Table *tablePtr; /* Table where it can be found */ TableEditor *tedPtr; /* Table editor */ int mapped; /* Indicates if the debugging windows are * mapped */ } EntryRep; typedef struct { Blt_Font font; XColor *widgetColor; XColor *cntlColor; XColor *normalFg, *normalBg; XColor *activeFg, *activeBg; Tk_Cursor cursor; /* Cursor to display inside of this window */ Pixmap stipple; GC drawGC; /* GC to draw grid, outlines */ GC fillGC; /* GC to fill entry area */ GC widgetFillGC; /* GC to fill widget area */ GC cntlGC; /* GC to fill rectangles */ } EntryAttributes; typedef struct { int count; XRectangle *array; } Rectangles; struct _TableEditor { int gridLineWidth; /* Width of grid lines */ int buttonHeight; /* Height of row/column buttons */ int cavityPad; /* Extra padding to add to entry cavity */ int min; /* Minimum size for partitions */ EditorDrawProc *drawProc; EditorDestroyProc *destroyProc; Display *display; Blt_Font font; Table *tablePtr; /* Pointer to table being debugged */ Tcl_Interp *interp; int flags; Tk_Window tkwin; /* Grid window */ Tk_Window input; /* InputOnly window to receive events */ int inputIsSibling; /* Form the grid */ XSegment *segArr; int nSegs; XRectangle *padRectArr; int nPadRects; XRectangle *widgetPadRectArr; int nWidgetPadRects; XRectangle *cntlRectArr; int nCntlRects; XRectangle *rects; int nRects; XRectangle activeRectArr[5]; int spanActive; GC rectGC; /* GC to fill rectangles */ GC drawGC; /* GC to draw grid, outlines */ GC fillGC; /* GC to fill window */ GC spanGC; /* GC to fill spans */ GC padRectGC; /* GC to draw padding */ Tk_3DBorder border; /* Border to use with buttons */ int relief; int borderWidth; /* Border width of buttons */ XColor *normalBg; XColor *padColor; XColor *gridColor; XColor *buttonColor; XColor *spanColor; Pixmap padStipple; Pixmap spanStipple; Blt_Dashes dashes; char *fileName; /* If non-NULL, indicates name of file * to write final table output to */ int mapped; /* Indicates if the debugging windows are * mapped */ int gripSize; int doubleBuffer; Tk_Cursor cursor; Blt_Chain chain; int nextWindowId; EntryAttributes attributes; /* Entry attributes */ }; #define REDRAW_PENDING (1<<0) /* A DoWhenIdle handler has already * been queued to redraw the window */ #define LAYOUT_PENDING (1<<1) /* * * * |Cavity|1|2| * * */ #define DEF_ENTRY_ACTIVE_BG_MONO RGB_BLACK #define DEF_ENTRY_ACTIVE_FG_MONO RGB_WHITE #define DEF_ENTRY_ACTIVE_BACKGROUND RGB_BLACK #define DEF_ENTRY_ACTIVE_FOREGROUND RGB_WHITE #define DEF_ENTRY_CURSOR (char *)NULL #define DEF_ENTRY_FONT "Helvetica 10 Bold" #define DEF_ENTRY_NORMAL_BACKGROUND RGB_BLUE #define DEF_ENTRY_NORMAL_BG_MONO RGB_BLACK #define DEF_ENTRY_NORMAL_FOREGROUND RGB_WHITE #define DEF_ENTRY_NORMAL_FG_MONO RGB_WHITE #define DEF_ENTRY_WIDGET_BACKGROUND RGB_GREEN #define DEF_ENTRY_CONTROL_BACKGROUND RGB_YELLOW #define DEF_ENTRY_WIDGET_BG_MONO RGB_BLACK #define DEF_ENTRY_STIPPLE "gray50" #define DEF_GRID_BACKGROUND RGB_WHITE #define DEF_GRID_BG_MONO RGB_WHITE #define DEF_GRID_CURSOR "crosshair" #define DEF_GRID_DASHES (char *)NULL #define DEF_GRID_FOREGROUND RGB_BLACK #define DEF_GRID_FG_MONO RGB_BLACK #define DEF_GRID_FONT "Helvetica 10 Bold" #define DEF_GRID_LINE_WIDTH "1" #define DEF_GRID_PAD_COLOR RGB_RED #define DEF_GRID_PAD_MONO RGB_BLACK #define DEF_GRID_PAD_STIPPLE "gray25" #define DEF_GRID_PAD_CAVITY "0" #define DEF_GRID_PAD_MIN "8" #define DEF_ROWCOL_BACKGROUND RGB_RED #define DEF_ROWCOL_BG_MONO RGB_BLACK #define DEF_ROWCOL_BORDER_COLOR RGB_RED #define DEF_ROWCOL_BORDER_MONO RGB_BLACK #define DEF_ROWCOL_BORDERWIDTH "2" #define DEF_ROWCOL_HEIGHT "8" #define DEF_ROWCOL_RELIEF "raised" #define DEF_SPAN_STIPPLE "gray50" #define DEF_SPAN_COLOR RGB_BLACK #define DEF_SPAN_MONO RGB_BLACK #define DEF_SPAN_GRIP_SIZE "5" #define DEF_GRID_DOUBLE_BUFFER "1" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BORDER, "-bg", "tedBorder", (char *)NULL, DEF_ROWCOL_BORDER_COLOR, Blt_Offset(TableEditor, border), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BORDER, "-bg", "tedBorder", (char *)NULL, DEF_ROWCOL_BORDER_MONO, Blt_Offset(TableEditor, border), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-background", "tedBackground", (char *)NULL, DEF_GRID_BACKGROUND, Blt_Offset(TableEditor, normalBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-background", "tedBackground", (char *)NULL, DEF_GRID_BG_MONO, Blt_Offset(TableEditor, normalBg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_CURSOR, "-cursor", "cursor", (char *)NULL, DEF_GRID_CURSOR, Blt_Offset(TableEditor, cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-gridcolor", "gridColor", (char *)NULL, DEF_GRID_FOREGROUND, Blt_Offset(TableEditor, gridColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-gridcolor", "gridColor", (char *)NULL, DEF_GRID_FG_MONO, Blt_Offset(TableEditor, gridColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-buttoncolor", "buttonColor", (char *)NULL, DEF_ROWCOL_BACKGROUND, Blt_Offset(TableEditor, buttonColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-buttoncolor", "buttonColor", (char *)NULL, DEF_ROWCOL_BG_MONO, Blt_Offset(TableEditor, buttonColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-padcolor", "padColor", (char *)NULL, DEF_GRID_PAD_COLOR, Blt_Offset(TableEditor, padColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-padcolor", "padColor", (char *)NULL, DEF_GRID_PAD_MONO, Blt_Offset(TableEditor, padColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_BITMAP, "-padstipple", "padStipple", (char *)NULL, DEF_GRID_PAD_STIPPLE, Blt_Offset(TableEditor, padStipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FONT, "-font", "font", (char *)NULL, DEF_GRID_FONT, Blt_Offset(TableEditor, font), 0}, {BLT_CONFIG_PIXELS_NNEG, "-gridlinewidth", "gridLineWidth", (char *)NULL, DEF_GRID_LINE_WIDTH, Blt_Offset(TableEditor, gridLineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-buttonheight", "buttonHeight", (char *)NULL, DEF_ROWCOL_HEIGHT, Blt_Offset(TableEditor, buttonHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-cavitypad", "cavityPad", (char *)NULL, DEF_GRID_PAD_CAVITY, Blt_Offset(TableEditor, cavityPad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-minsize", "minSize", (char *)NULL, DEF_GRID_PAD_MIN, Blt_Offset(TableEditor, min), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DASHES, "-dashes", "dashes", (char *)NULL, DEF_GRID_DASHES, Blt_Offset(TableEditor, dashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", (char *)NULL, DEF_ROWCOL_RELIEF, Blt_Offset(TableEditor, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", (char *)NULL, DEF_ROWCOL_BORDERWIDTH, Blt_Offset(TableEditor, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CURSOR, "-entrycursor", "entryCursor", (char *)NULL, DEF_ENTRY_CURSOR, Blt_Offset(TableEditor, attributes.cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_FONT, "-entryfont", "entryFont", (char *)NULL, DEF_ENTRY_FONT, Blt_Offset(TableEditor, attributes.font), 0}, {BLT_CONFIG_BITMAP, "-entrystipple", "entryStipple", (char *)NULL, DEF_ENTRY_STIPPLE, Blt_Offset(TableEditor, attributes.stipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-widgetbackground", "widgetBackground", (char *)NULL, DEF_ENTRY_WIDGET_BACKGROUND, Blt_Offset(TableEditor, attributes.widgetColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-widgetbackground", "widgetBackground", (char *)NULL, DEF_ENTRY_WIDGET_BG_MONO, Blt_Offset(TableEditor, attributes.widgetColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-controlbackground", "controlBackground", (char *)NULL, DEF_ENTRY_CONTROL_BACKGROUND, Blt_Offset(TableEditor, attributes.cntlColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-controlbackground", "controlBackground", (char *)NULL, DEF_ENTRY_WIDGET_BG_MONO, Blt_Offset(TableEditor, attributes.cntlColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-entrybackground", "entryBackground", (char *)NULL, DEF_ENTRY_NORMAL_BACKGROUND, Blt_Offset(TableEditor, attributes.normalBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-entrybackground", "entryBackground", (char *)NULL, DEF_ENTRY_NORMAL_BG_MONO, Blt_Offset(TableEditor, attributes.normalBg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-entryactivebackground", "entryActiveBackground", (char *)NULL, DEF_ENTRY_ACTIVE_BACKGROUND, Blt_Offset(TableEditor, attributes.activeBg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-entryactivebackground", "entryActiveBackground", (char *)NULL, DEF_ENTRY_ACTIVE_BG_MONO, Blt_Offset(TableEditor, attributes.activeBg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-entryactiveforeground", "entryActiveForeground", (char *)NULL, DEF_ENTRY_ACTIVE_FOREGROUND, Blt_Offset(TableEditor, attributes.activeFg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-entryactiveforeground", "entryActiveForeground", (char *)NULL, DEF_ENTRY_ACTIVE_FG_MONO, Blt_Offset(TableEditor, attributes.activeFg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-entryforeground", "entryForeground", (char *)NULL, DEF_ENTRY_NORMAL_FOREGROUND, Blt_Offset(TableEditor, attributes.normalFg), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-entryforeground", "entryForeground", (char *)NULL, DEF_ENTRY_NORMAL_FG_MONO, Blt_Offset(TableEditor, attributes.normalFg), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-spancolor", "spanColor", (char *)NULL, DEF_SPAN_COLOR, Blt_Offset(TableEditor, spanColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-spancolor", "spanColor", (char *)NULL, DEF_SPAN_MONO, Blt_Offset(TableEditor, spanColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_BITMAP, "-spanstipple", "spanStipple", (char *)NULL, DEF_SPAN_STIPPLE, Blt_Offset(TableEditor, spanStipple), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-gripsize", "gripSize", (char *)NULL, DEF_SPAN_GRIP_SIZE, Blt_Offset(TableEditor, gripSize), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BOOLEAN, "-dbl", "doubleBuffer", (char *)NULL, DEF_GRID_DOUBLE_BUFFER, Blt_Offset(TableEditor, doubleBuffer), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; static Tcl_FreeProc DestroyEditor; static Tcl_FreeProc DestroyEntry; static Tcl_FreeProc DestroyTableEditor; static Tcl_IdleProc DisplayEntry; static Tcl_IdleProc DisplayTableEditor; static Tcl_ObjCmdProc TedCmd; static Tk_EventProc EntryEventProc; static Tk_EventProc TableEditorEventProc; static void DrawEditor(Editor *editor); /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the text window at the next idle * point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. This doesn't * seem to hurt performance noticeably, but if it does then this * could be changed. * *--------------------------------------------------------------------------- */ static void EventuallyRedraw(TableEditor *tedPtr) { if ((tedPtr->tkwin != NULL) && !(tedPtr->flags & REDRAW_PENDING)) { tedPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayTableEditor, tedPtr); } } /* *--------------------------------------------------------------------------- * * EventuallyRedraw -- * * Queues a request to redraw the text window at the next idle * point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. This doesn't * seem to hurt performance noticeably, but if it does then this * could be changed. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawEntry(EntryRep *repPtr) { if ((repPtr->tkwin != NULL) && !(repPtr->flags & REDRAW_PENDING)) { repPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayEntry, repPtr); } } /* *--------------------------------------------------------------------------- * * EntryEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on the editing grid for the table. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void EntryEventProc(ClientData clientData, XEvent *eventPtr) { EntryRep *repPtr = (EntryRep *)clientData; if (eventPtr->type == ConfigureNotify) { EventuallyRedrawEntry(repPtr); } else if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedrawEntry(repPtr); } } else if (eventPtr->type == DestroyNotify) { repPtr->tkwin = NULL; if (repPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayEntry, repPtr); } Tcl_EventuallyFree(repPtr, DestroyEntry); } } /* *--------------------------------------------------------------------------- * * TableEditorEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on the editing grid for the table. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void TableEditorEventProc(ClientData clientData, XEvent *eventPtr) { TableEditor *tedPtr = (TableEditor *) clientData; if (eventPtr->type == ConfigureNotify) { EventuallyRedraw(tedPtr); } else if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(tedPtr); } } else if (eventPtr->type == DestroyNotify) { tedPtr->tkwin = NULL; if (tedPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTableEditor, tedPtr); } Tcl_EventuallyFree(tedPtr, DestroyTableEditor); } } /* *--------------------------------------------------------------------------- * * CreateGrid -- * *--------------------------------------------------------------------------- */ static int CreateGrid(TableEditor *tedPtr) { Tcl_Interp *interp; Tk_Window tkwin; Tk_Window master; /* * Create a sibling window to cover the master window. It will * be stacked just above the master window. */ interp = tedPtr->tablePtr->interp; master = tedPtr->tablePtr->tkwin; tkwin = Tk_CreateWindow(interp, master, "ted_%output%", (char *)NULL); if (tkwin == NULL) { return TCL_ERROR; } Tk_SetClass(tkwin, "BltTableEditor"); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, TableEditorEventProc, tedPtr); Tk_MoveResizeWindow(tkwin, 0, 0, Tk_Width(master), Tk_Height(master)); Tk_RestackWindow(tkwin, Below, (Tk_Window)NULL); Tk_MapWindow(tkwin); tedPtr->tkwin = tkwin; return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateEventWindow -- * *--------------------------------------------------------------------------- */ static int CreateEventWindow(TableEditor *tedPtr) { Tcl_Interp *interp; Tk_Window tkwin; Tk_Window master; Tk_Window parent; interp = tedPtr->tablePtr->interp; master = tedPtr->tablePtr->tkwin; /* * Create an InputOnly window which sits above the table to * collect and dispatch user events. */ if (Tk_IsTopLevel(master)) { /* * If master is a top-level window, it's also the parent of * the widgets (it can't have a sibling). * In this case, the InputOnly window is a child of the * master instead of a sibling. */ parent = master; tkwin = Tk_CreateWindow(interp, parent, "ted_%input%", (char *)NULL); if (tkwin != NULL) { Tk_ResizeWindow(tkwin, Tk_Width(parent), Tk_Height(parent)); } tedPtr->inputIsSibling = 0; } else { char *namePtr; /* Name of InputOnly window. */ parent = Tk_Parent(master); namePtr = Blt_AssertMalloc(strlen(Tk_Name(master)) + 5); sprintf_s(namePtr, strlen(Tk_Name(master)) + 5, "ted_%s", Tk_Name(master)); tkwin = Tk_CreateWindow(interp, parent, namePtr, (char *)NULL); Blt_Free(namePtr); if (tkwin != NULL) { Tk_MoveResizeWindow(tkwin, Tk_X(master), Tk_Y(master), Tk_Width(master), Tk_Height(master)); } tedPtr->inputIsSibling = 1; } if (tkwin == NULL) { return TCL_ERROR; } Blt_MakeTransparentWindowExist(tkwin, Tk_WindowId(parent), TRUE); Tk_RestackWindow(tkwin, Above, (Tk_Window)NULL); Tk_MapWindow(tkwin); tedPtr->input = tkwin; return TCL_OK; } #ifdef notdef /* *--------------------------------------------------------------------------- * * CreateEntry -- * *--------------------------------------------------------------------------- */ static int CreateEntry(TableEditor *tedPtr, TableEntry *tePtr) { Tk_Window tkwin, master; char string[200]; EntryRep *repPtr; repPtr = Blt_AssertCalloc(1, sizeof(EntryRep)); repPtr->tablePtr = tedPtr->tablePtr; repPtr->tedPtr = tedPtr; repPtr->interp = tedPtr->interp; repPtr->tePtr = tePtr; repPtr->mapped = 0; /* * Create a sibling window to cover the master window. It will * be stacked just above the master window. */ master = tedPtr->tablePtr->tkwin; sprintf_s(string, 200, "bltTableEditor%d", tedPtr->nextWindowId); tedPtr->nextWindowId++; tkwin = Tk_CreateWindow(tedPtr->interp, master, string, (char *)NULL); if (tkwin == NULL) { Blt_Free(repPtr); return TCL_ERROR; } Tk_SetClass(tkwin, "BltTableEditor"); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, EntryEventProc, repPtr); repPtr->tkwin = tkwin; Blt_Chain_Append(tedPtr->chain, repPtr); return TCL_OK; } #endif /* *--------------------------------------------------------------------------- * * DestroyEntry -- * *--------------------------------------------------------------------------- */ static void DestroyEntry(DestroyData data) { EntryRep *repPtr = (EntryRep *)data; Blt_ChainLink link; TableEntry *tePtr; for (link = Blt_Chain_FirstLink(repPtr->tedPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); if (tePtr == repPtr->tePtr) { Blt_Chain_DeleteLink(repPtr->tedPtr->chain, link); Blt_Free(repPtr); return; } } } /* *--------------------------------------------------------------------------- * * DisplayEntry -- * *--------------------------------------------------------------------------- */ static void DisplayEntry(ClientData clientData) { EntryRep *repPtr = (EntryRep *) clientData; TableEditor *tedPtr; TableEntry *tePtr; Tk_Window tkwin; int x, y, width, height; repPtr->flags &= ~REDRAW_PENDING; if ((repPtr->tkwin == NULL) || (repPtr->tePtr == NULL)) { return; } if (!Tk_IsMapped(repPtr->tkwin)) { return; } tedPtr = repPtr->tedPtr; tePtr = repPtr->tePtr; tkwin = repPtr->tkwin; /* * Check if the entry size and position. * Move and resize the window accordingly. */ x = Tk_X(tePtr->tkwin) - (tePtr->padLeft + tedPtr->cavityPad); y = Tk_Y(tePtr->tkwin) - (tePtr->padTop + tedPtr->cavityPad); width = Tk_Width(tePtr->tkwin) + PADDING(tePtr->xPad) + (2 * tedPtr->cavityPad); height = Tk_Height(tePtr->tkwin) + PADDING(tePtr->yPad) + (2 * tedPtr->cavityPad); if ((Tk_X(tkwin) != x) || (Tk_Y(tkwin) != y) || (Tk_Width(tkwin) != width) || (Tk_Height(tkwin) != height)) { Tk_MoveResizeWindow(tkwin, x, y, width, height); Tk_RestackWindow(tkwin, Above, (Tk_Window)NULL); } /* Clear the background of the entry */ XFillRectangle(Tk_Display(tkwin), Tk_WindowId(tkwin), tedPtr->attributes.fillGC, 0, 0, width, height); /* Draw the window */ x = tePtr->padLeft + tedPtr->cavityPad; y = tePtr->padTop + tedPtr->cavityPad; XFillRectangle(Tk_Display(tkwin), Tk_WindowId(tkwin), tedPtr->attributes.widgetFillGC, x, y, Tk_Width(tePtr->tkwin), Tk_Height(tePtr->tkwin)); XDrawRectangle(Tk_Display(tkwin), Tk_WindowId(tkwin), tedPtr->attributes.drawGC, x, y, Tk_Width(tePtr->tkwin), Tk_Height(tePtr->tkwin)); } /* *--------------------------------------------------------------------------- * * FindEditor -- * * Searches for a table associated with the window given by its * pathname. This window represents the master window of the table. * * Errors may occur because * 1) pathName does not represent a valid Tk window or * 2) the window is not associated with any table as its master. * * Results: * If a table entry exists, a pointer to the Table structure is * returned. Otherwise NULL is returned. * *--------------------------------------------------------------------------- */ static TableEditor * FindEditor(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *objPtr) { Table *tablePtr; if (Blt_GetTableFromObj(clientData, interp, objPtr, &tablePtr) != TCL_OK) { return NULL; } if (tablePtr->editPtr == NULL) { Tcl_AppendResult(interp, "no editor exists for table \"", Tk_PathName(tablePtr->tkwin), "\"", (char *)NULL); return NULL; } return (TableEditor *) tablePtr->editPtr; } /* *--------------------------------------------------------------------------- * * CreateTableEditor -- * *--------------------------------------------------------------------------- */ static TableEditor * CreateTableEditor(Table *tablePtr, Tcl_Interp *interp) { TableEditor *tedPtr; tedPtr = Blt_AssertCalloc(1, sizeof(TableEditor)); tedPtr->nextWindowId = 0; tedPtr->interp = interp; tedPtr->tablePtr = tablePtr; tedPtr->gridLineWidth = 1; tedPtr->buttonHeight = 0; tedPtr->cavityPad = 0; tedPtr->min = 3; tedPtr->gripSize = 5; tedPtr->drawProc = DrawEditor; tedPtr->destroyProc = DestroyEditor; tedPtr->display = Tk_Display(tablePtr->tkwin); tedPtr->relief = TK_RELIEF_RAISED; tedPtr->borderWidth = 2; tedPtr->doubleBuffer = 1; tedPtr->chain = Blt_Chain_Create(); /* Create the grid window */ if (CreateGrid(tedPtr) != TCL_OK) { return NULL; } /* Create an InputOnly window to collect user events */ if (CreateEventWindow(tedPtr) != TCL_OK) { return NULL; } tablePtr->editPtr = (Editor *)tedPtr; return tedPtr; } /* *--------------------------------------------------------------------------- * * DestroyTableEditor -- * *--------------------------------------------------------------------------- */ static void DestroyTableEditor(DestroyData freeProcData) { TableEditor *tedPtr = (TableEditor *) freeProcData; if (tedPtr->rects != NULL) { Blt_Free(tedPtr->rects); } if (tedPtr->segArr != NULL) { Blt_Free(tedPtr->segArr); } if (tedPtr->fillGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->fillGC); } if (tedPtr->drawGC != NULL) { Blt_FreePrivateGC(tedPtr->display, tedPtr->drawGC); } if (tedPtr->rectGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->rectGC); } if (tedPtr->padRectGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->padRectGC); } /* Is this save ? */ tedPtr->tablePtr->editPtr = NULL; Blt_Free(tedPtr); } /* *--------------------------------------------------------------------------- * * ConfigureTableEditor -- * * This procedure is called to process an objv/objc list in order to * configure the table geometry manager. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Table configuration options (padx, pady, rows, columns, etc) get * set. The table is recalculated and arranged at the next idle * point. * *--------------------------------------------------------------------------- */ static int ConfigureTableEditor(TableEditor *tedPtr, int objc, Tcl_Obj *const *objv, int flags) { XGCValues gcValues; GC newGC; unsigned long gcMask; if (Blt_ConfigureWidgetFromObj(tedPtr->interp, tedPtr->tkwin, configSpecs, objc, objv, (char *)tedPtr, flags) != TCL_OK) { return TCL_ERROR; } /* GC for filling background of edit window */ gcMask = GCForeground; gcValues.foreground = tedPtr->normalBg->pixel; newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->fillGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->fillGC); } tedPtr->fillGC = newGC; /* GC for drawing grid lines */ gcMask = (GCForeground | GCBackground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFont); gcValues.font = Blt_FontId(tedPtr->font); gcValues.foreground = tedPtr->gridColor->pixel; gcValues.background = tedPtr->normalBg->pixel; gcValues.line_width = LineWidth(tedPtr->gridLineWidth); gcValues.cap_style = CapRound; gcValues.join_style = JoinRound; gcValues.line_style = LineSolid; if (LineIsDashed(tedPtr->dashes)) { gcValues.line_style = LineOnOffDash; } newGC = Blt_GetPrivateGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->drawGC != NULL) { Blt_FreePrivateGC(tedPtr->display, tedPtr->drawGC); } if (LineIsDashed(tedPtr->dashes)) { XSetDashes(tedPtr->display, newGC, 0, (const char *)tedPtr->dashes.values, strlen((char *)tedPtr->dashes.values)); } tedPtr->drawGC = newGC; /* GC for button rectangles */ gcMask = GCForeground; gcValues.foreground = tedPtr->buttonColor->pixel; newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->rectGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->rectGC); } tedPtr->rectGC = newGC; /* GC for button rectangles */ gcMask = GCForeground; gcValues.foreground = tedPtr->padColor->pixel; if (tedPtr->padStipple != None) { gcMask |= GCStipple | GCFillStyle; gcValues.stipple = tedPtr->padStipple; gcValues.fill_style = FillStippled; } newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->padRectGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->padRectGC); } tedPtr->padRectGC = newGC; /* GC for filling entrys */ gcMask = GCForeground; gcValues.foreground = tedPtr->attributes.normalBg->pixel; if (tedPtr->attributes.stipple != None) { gcMask |= GCStipple | GCFillStyle; gcValues.stipple = tedPtr->attributes.stipple; gcValues.fill_style = FillStippled; } newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->attributes.fillGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->attributes.fillGC); } tedPtr->attributes.fillGC = newGC; /* GC for drawing entrys */ gcMask = GCForeground | GCBackground | GCFont; gcValues.foreground = tedPtr->attributes.normalFg->pixel; gcValues.background = tedPtr->attributes.normalBg->pixel; gcValues.font = Blt_FontId(tedPtr->attributes.font); newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->attributes.drawGC != NULL) { Blt_FreePrivateGC(tedPtr->display, tedPtr->attributes.drawGC); } tedPtr->attributes.drawGC = newGC; /* GC for filling widget rectangles */ gcMask = GCForeground; gcValues.foreground = tedPtr->attributes.widgetColor->pixel; newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->attributes.widgetFillGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->attributes.widgetFillGC); } tedPtr->attributes.widgetFillGC = newGC; gcMask = GCForeground; gcValues.foreground = tedPtr->attributes.cntlColor->pixel; newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->attributes.cntlGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->attributes.cntlGC); } tedPtr->attributes.cntlGC = newGC; /* GC for filling span rectangle */ gcMask = GCForeground; gcValues.foreground = tedPtr->spanColor->pixel; if (tedPtr->spanStipple != None) { gcMask |= GCStipple | GCFillStyle; gcValues.stipple = tedPtr->spanStipple; gcValues.fill_style = FillStippled; } newGC = Tk_GetGC(tedPtr->tkwin, gcMask, &gcValues); if (tedPtr->spanGC != NULL) { Tk_FreeGC(tedPtr->display, tedPtr->spanGC); } tedPtr->spanGC = newGC; /* Define cursor for grid events */ if (tedPtr->cursor != None) { Tk_DefineCursor(tedPtr->input, tedPtr->cursor); } else { Tk_UndefineCursor(tedPtr->input); } return TCL_OK; } static void LayoutGrid(TableEditor *tedPtr) { int needed; XSegment *segArr; Table *tablePtr; Blt_ChainLink link; RowColumn *rcPtr; int startX, endX; int startY, endY; int count; tablePtr = tedPtr->tablePtr; if (tedPtr->segArr != NULL) { Blt_Free(tedPtr->segArr); tedPtr->segArr = NULL; } tedPtr->nSegs = 0; if ((tablePtr->nRows == 0) || (tablePtr->nColumns == 0)) { return; } needed = tablePtr->nRows + tablePtr->nColumns + 2; segArr = Blt_Calloc(needed, sizeof(XSegment)); if (segArr == NULL) { return; } link = Blt_Chain_FirstLink(tablePtr->cols.chain); rcPtr = Blt_Chain_GetValue(link); startX = rcPtr->offset - tedPtr->gridLineWidth; link = Blt_Chain_LastLink(tablePtr->cols.chain); rcPtr = Blt_Chain_GetValue(link); endX = rcPtr->offset + rcPtr->size - 1; link = Blt_Chain_FirstLink(tablePtr->rows.chain); rcPtr = Blt_Chain_GetValue(link); startY = rcPtr->offset - tedPtr->gridLineWidth; link = Blt_Chain_LastLink(tablePtr->rows.chain); rcPtr = Blt_Chain_GetValue(link); endY = rcPtr->offset + rcPtr->size - 1; count = 0; /* Reset segment counter */ for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); segArr[count].x1 = startX; segArr[count].x2 = endX; segArr[count].y1 = segArr[count].y2 = rcPtr->offset - tedPtr->gridLineWidth; count++; } segArr[count].x1 = startX; segArr[count].x2 = endX; segArr[count].y1 = segArr[count].y2 = endY; count++; for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); segArr[count].y1 = startY; segArr[count].y2 = endY; segArr[count].x1 = segArr[count].x2 = rcPtr->offset - tedPtr->gridLineWidth; count++; } segArr[count].x1 = segArr[count].x2 = endX; segArr[count].y1 = startY; segArr[count].y2 = endY; count++; assert(count == needed); if (tedPtr->segArr != NULL) { Blt_Free(tedPtr->segArr); } tedPtr->segArr = segArr; tedPtr->nSegs = count; } static void LayoutPads(TableEditor *tedPtr) { int needed; XRectangle *rects, *rectPtr; Table *tablePtr; Blt_ChainLink link; RowColumn *rcPtr; int startX, endX; int startY, endY; int count; tablePtr = tedPtr->tablePtr; if (tedPtr->padRectArr != NULL) { Blt_Free(tedPtr->padRectArr); tedPtr->padRectArr = NULL; } tedPtr->nPadRects = 0; if ((tablePtr->nRows == 0) || (tablePtr->nColumns == 0)) { return; } needed = 2 * (tablePtr->nRows + tablePtr->nColumns); rects = Blt_Calloc(needed, sizeof(XRectangle)); if (rects == NULL) { return; } link = Blt_Chain_FirstLink(tablePtr->cols.chain); rcPtr = Blt_Chain_GetValue(link); startX = rcPtr->offset; link = Blt_Chain_LastLink(tablePtr->cols.chain); rcPtr = Blt_Chain_GetValue(link); endX = (rcPtr->offset + rcPtr->size); link = Blt_Chain_FirstLink(tablePtr->rows.chain); rcPtr = Blt_Chain_GetValue(link); startY = rcPtr->offset; link = Blt_Chain_LastLink(tablePtr->rows.chain); rcPtr = Blt_Chain_GetValue(link); endY = (rcPtr->offset + rcPtr->size); count = 0; /* Reset segment counter */ rectPtr = rects; for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); if (rcPtr->pad.side1 > 0) { rectPtr->x = startX; rectPtr->y = rcPtr->offset; rectPtr->height = rcPtr->pad.side1; rectPtr->width = endX - startX - 1; rectPtr++, count++; } if (rcPtr->pad.side2 > 0) { rectPtr->x = startX; rectPtr->y = rcPtr->offset + rcPtr->size - rcPtr->pad.side2 - 1; rectPtr->height = rcPtr->pad.side2; rectPtr->width = endX - startX - 1; rectPtr++, count++; } } for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); if (rcPtr->pad.side1 > 0) { rectPtr->x = rcPtr->offset; rectPtr->y = startY; rectPtr->height = endY - startY - 1; rectPtr->width = rcPtr->pad.side1; rectPtr++, count++; } if (rcPtr->pad.side2 > 0) { rectPtr->x = rcPtr->offset + rcPtr->size - rcPtr->pad.side2; rectPtr->y = startY; rectPtr->height = endY - startY - 1; rectPtr->width = rcPtr->pad.side2; rectPtr++, count++; } } if (count == 0) { Blt_Free(rects); return; } tedPtr->padRectArr = rects; tedPtr->nPadRects = count; } static void LayoutEntries(TableEditor *tedPtr) { TableEntry *tePtr; XRectangle *rects; int needed; int count; Blt_ChainLink link; if (tedPtr->widgetPadRectArr != NULL) { Blt_Free(tedPtr->widgetPadRectArr); tedPtr->widgetPadRectArr = NULL; } tedPtr->nWidgetPadRects = 0; needed = Blt_Chain_GetLength(tedPtr->tablePtr->chain); rects = Blt_Calloc(needed, sizeof(XRectangle)); if (rects == NULL) { return; } /* Draw any entry windows */ count = 0; for (link = Blt_Chain_FirstLink(tedPtr->tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); if ((PADDING(tePtr->xPad) + PADDING(tePtr->yPad)) == 0) { continue; } rects[count].x = Tk_X(tePtr->tkwin) - tePtr->padLeft; rects[count].y = Tk_Y(tePtr->tkwin) - tePtr->padTop; rects[count].width = Tk_Width(tePtr->tkwin) + PADDING(tePtr->xPad); rects[count].height = Tk_Height(tePtr->tkwin) + PADDING(tePtr->yPad); count++; } if (count == 0) { Blt_Free(rects); return; } tedPtr->widgetPadRectArr = rects; tedPtr->nWidgetPadRects = count; } static void LayoutControlEntries(TableEditor *tedPtr) { TableEntry *tePtr; XRectangle *rects; int needed; int count; Table *tablePtr = tedPtr->tablePtr; Blt_ChainLink link; RowColumn *rcPtr; if (tedPtr->cntlRectArr != NULL) { Blt_Free(tedPtr->cntlRectArr); tedPtr->cntlRectArr = NULL; } tedPtr->nCntlRects = 0; needed = (tablePtr->nRows + tablePtr->nColumns); rects = Blt_Calloc(needed, sizeof(XRectangle)); if (rects == NULL) { return; } /* Draw any entry windows */ count = 0; for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); tePtr = rcPtr->control; if (tePtr != NULL) { rects[count].x = Tk_X(tePtr->tkwin) - tePtr->padLeft; rects[count].y = Tk_Y(tePtr->tkwin) - tePtr->padTop; rects[count].width = Tk_Width(tePtr->tkwin) + PADDING(tePtr->xPad); rects[count].height = Tk_Height(tePtr->tkwin) + PADDING(tePtr->yPad); count++; } } for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); tePtr = rcPtr->control; if (tePtr != NULL) { rects[count].x = Tk_X(tePtr->tkwin) - tePtr->padLeft; rects[count].y = Tk_Y(tePtr->tkwin) - tePtr->padTop; rects[count].width = Tk_Width(tePtr->tkwin) + PADDING(tePtr->xPad); rects[count].height = Tk_Height(tePtr->tkwin) + PADDING(tePtr->yPad); count++; } } if (count == 0) { Blt_Free(rects); return; } tedPtr->cntlRectArr = rects; tedPtr->nCntlRects = count; } static void LayoutButtons(TableEditor *tedPtr) { int needed; XRectangle *rects; Table *tablePtr; Blt_ChainLink link; RowColumn *rcPtr; int count; tablePtr = tedPtr->tablePtr; if ((tablePtr->nRows == 0) || (tablePtr->nColumns == 0)) { if (tedPtr->rects != NULL) { Blt_Free(tedPtr->rects); } tedPtr->rects = NULL; tedPtr->nRects = 0; return; /* Nothing to display, empty table */ } needed = 2 * (tablePtr->nRows + tablePtr->nColumns); rects = Blt_Calloc(needed, sizeof(XRectangle)); if (rects == NULL) { return; /* Can't allocate rectangles */ } count = 0; for (link = Blt_Chain_FirstLink(tablePtr->rows.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); rects[count].x = 0; rects[count].y = rcPtr->offset - rcPtr->pad.side1; rects[count].width = tedPtr->buttonHeight; rects[count].height = rcPtr->size - 2; count++; rects[count].x = Tk_Width(tedPtr->tkwin) - tedPtr->buttonHeight; rects[count].y = rcPtr->offset - rcPtr->pad.side1; rects[count].width = tedPtr->buttonHeight; rects[count].height = rcPtr->size - 2; count++; } for (link = Blt_Chain_FirstLink(tablePtr->cols.chain); link != NULL; link = Blt_Chain_NextLink(link)) { rcPtr = Blt_Chain_GetValue(link); rects[count].x = rcPtr->offset - rcPtr->pad.side1; rects[count].y = 0; rects[count].width = rcPtr->size - 2; rects[count].height = tedPtr->buttonHeight; count++; rects[count].x = rcPtr->offset - rcPtr->pad.side1; rects[count].y = Tk_Height(tedPtr->tkwin) - tedPtr->buttonHeight; rects[count].width = rcPtr->size - 2; rects[count].height = tedPtr->buttonHeight; count++; } assert(count == needed); if (tedPtr->rects != NULL) { Blt_Free(tedPtr->rects); } tedPtr->rects = rects; tedPtr->nRects = count; } static void DisplayTableEditor(ClientData clientData) { TableEditor *tedPtr = (TableEditor *) clientData; Tk_Window master; Tk_Window tkwin; Blt_ChainLink link; EntryRep *repPtr; Drawable drawable; Pixmap pixmap; #ifdef notdef fprintf(stderr, "display grid\n"); #endif tedPtr->flags &= ~REDRAW_PENDING; if (!Tk_IsMapped(tedPtr->tkwin)) { return; } /* * Check if the master window has changed size and resize the * grid and input windows accordingly. */ master = tedPtr->tablePtr->tkwin; if ((Tk_Width(master) != Tk_Width(tedPtr->tkwin)) || (Tk_Height(master) != Tk_Height(tedPtr->tkwin))) { #ifdef notdef fprintf(stderr, "resizing windows\n"); #endif Tk_ResizeWindow(tedPtr->tkwin, Tk_Width(master), Tk_Height(master)); Tk_ResizeWindow(tedPtr->input, Tk_Width(master), Tk_Height(master)); if (tedPtr->inputIsSibling) { Tk_MoveWindow(tedPtr->input, Tk_X(master), Tk_X(master)); } tedPtr->flags |= LAYOUT_PENDING; } if (tedPtr->flags & LAYOUT_PENDING) { #ifdef notdef fprintf(stderr, "layout of grid\n"); #endif LayoutPads(tedPtr); LayoutEntries(tedPtr); LayoutControlEntries(tedPtr); LayoutGrid(tedPtr); LayoutButtons(tedPtr); tedPtr->flags &= ~LAYOUT_PENDING; } tkwin = tedPtr->tkwin; pixmap = None; /* Suppress compiler warning. */ drawable = Tk_WindowId(tkwin); if (tedPtr->doubleBuffer) { /* Create an off-screen pixmap for semi-smooth scrolling. */ pixmap = Tk_GetPixmap(tedPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); drawable = pixmap; } /* Clear the background of the grid */ XFillRectangle(Tk_Display(tkwin), drawable, tedPtr->fillGC, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin)); /* Draw the row and column buttons */ if (tedPtr->nRects > 0) { int i; for (i = 0; i < tedPtr->nRects; i++) { Blt_Fill3DRectangle(tkwin, drawable, tedPtr->border, tedPtr->rects[i].x, tedPtr->rects[i].y, tedPtr->rects[i].width, tedPtr->rects[i].height, tedPtr->borderWidth, tedPtr->relief); } #ifdef notdef XFillRectangles(tedPtr->display, drawable, tedPtr->rectGC, tedPtr->rects, tedPtr->nRects); XDrawRectangles(tedPtr->display, drawable, tedPtr->drawGC, tedPtr->rects, tedPtr->nRects); #endif } if (tedPtr->nPadRects > 0) { XFillRectangles(tedPtr->display, drawable, tedPtr->padRectGC, tedPtr->padRectArr, tedPtr->nPadRects); } if (tedPtr->spanActive) { XFillRectangles(tedPtr->display, drawable, tedPtr->spanGC, tedPtr->activeRectArr, 1); XFillRectangles(tedPtr->display, drawable, tedPtr->drawGC, tedPtr->activeRectArr + 1, 4); } if (tedPtr->nWidgetPadRects > 0) { XFillRectangles(tedPtr->display, drawable, tedPtr->attributes.fillGC, tedPtr->widgetPadRectArr, tedPtr->nWidgetPadRects); } if (tedPtr->nCntlRects > 0) { XFillRectangles(tedPtr->display, drawable, tedPtr->attributes.cntlGC, tedPtr->cntlRectArr, tedPtr->nCntlRects); } /* Draw the grid lines */ if (tedPtr->nSegs > 0) { XDrawSegments(tedPtr->display, drawable, tedPtr->drawGC, tedPtr->segArr, tedPtr->nSegs); } #ifndef notdef /* Draw any entry windows */ for (link = Blt_Chain_FirstLink(tedPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { repPtr = Blt_Chain_GetValue(link); if (repPtr->mapped) { DisplayEntry(repPtr); } } #endif if (tedPtr->doubleBuffer) { XCopyArea(tedPtr->display, drawable, Tk_WindowId(tkwin), tedPtr->fillGC, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, 0); Tk_FreePixmap(tedPtr->display, pixmap); } } static void DrawEditor(Editor *editPtr) { TableEditor *tedPtr = (TableEditor *) editPtr; tedPtr->flags |= LAYOUT_PENDING; if ((tedPtr->tkwin != NULL) && !(tedPtr->flags & REDRAW_PENDING)) { tedPtr->flags |= REDRAW_PENDING; #ifdef notdef fprintf(stderr, "from draw editor\n"); #endif Tcl_DoWhenIdle(DisplayTableEditor, tedPtr); } } static void DestroyEditor(DestroyData destroyData) { TableEditor *tedPtr = (TableEditor *) destroyData; tedPtr->tkwin = NULL; if (tedPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTableEditor, tedPtr); } Tcl_EventuallyFree(tedPtr, DestroyTableEditor); } /* *--------------------------------------------------------------------------- * * EditOp -- * * Processes an objv/objc list of table entries to add and configure * new widgets into the table. A table entry consists of the * window path name, table index, and optional configuration options. * The first argument in the objv list is the name of the table. If * no table exists for the given window, a new one is created. * * Results: * Returns a standard TCL result. If an error occurred, TCL_ERROR is * returned and an error message is left in interp->result. * * Side Effects: * Memory is allocated, a new master table is possibly created, etc. * The table is re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int EditOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return list of names to */ int objc, /* Number of arguments */ Tcl_Obj *const *objv) { Table *tablePtr; TableEditor *tedPtr; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } if (tablePtr->editPtr != NULL) { /* Already editing this table */ tedPtr = (TableEditor *) tablePtr->editPtr; } else { tedPtr = CreateTableEditor(tablePtr, interp); if (tedPtr == NULL) { return TCL_ERROR; } } if (ConfigureTableEditor(tedPtr, objc - 3, objv + 3, 0) != TCL_OK) { tedPtr->tkwin = NULL; if (tedPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTableEditor, tedPtr); } Tcl_EventuallyFree(tedPtr, DestroyTableEditor); return TCL_ERROR; } /* Rearrange the table */ if (!(tablePtr->flags & ARRANGE_PENDING)) { tablePtr->flags |= ARRANGE_PENDING; Tcl_DoWhenIdle(tablePtr->arrangeProc, tablePtr); } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tedPtr->tkwin), -1); tedPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(tedPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetCmd -- * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report results back to */ int objc, /* Not used. */ Tcl_Obj *const *objv) /* Option-value pairs */ { TableEditor *tedPtr; tedPtr = FindEditor(dataPtr, interp, objv[2]); if (tedPtr == NULL) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, tedPtr->tkwin, configSpecs, (char *)tedPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ConfigureCmd -- * * This procedure is called to process an objv/objc list in order to * configure the table geometry manager. * * Results: * The return value is a standard TCL result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Table configuration options (padx, pady, rows, columns, etc) get * set. The table is recalculated and arranged at the next idle * point. * *--------------------------------------------------------------------------- */ static int ConfigureOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to report results back to */ int objc, Tcl_Obj *const *objv) /* Option-value pairs */ { TableEditor *tedPtr; tedPtr = FindEditor(dataPtr, interp, objv[2]); if (tedPtr == NULL) { return TCL_ERROR; } if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, tedPtr->tkwin, configSpecs, (char *)tedPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, tedPtr->tkwin, configSpecs, (char *)tedPtr, objv[3], 0); } if (ConfigureTableEditor(tedPtr, objc - 3, objv + 3, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } EventuallyRedraw(tedPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return list of names to */ int objc, /* Not used. */ Tcl_Obj *const *objv) { Table *tablePtr; TableEditor *tedPtr; TableEntry *tePtr; int active; int x, y, width, height; int ix, iy; Blt_ChainLink link; Tk_Window tkwin; /* ted select master @x,y */ tkwin = dataPtr->tkMain; tedPtr = FindEditor(dataPtr, interp, objv[2]); if (tedPtr == NULL) { return TCL_ERROR; } if (Blt_GetXY(interp, tkwin, Tcl_GetString(objv[3]), &ix, &iy) != TCL_OK) { return TCL_ERROR; } tablePtr = tedPtr->tablePtr; active = 0; for (link = Blt_Chain_FirstLink(tablePtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { tePtr = Blt_Chain_GetValue(link); x = tePtr->x - tePtr->xPad.side1; y = tePtr->y - tePtr->yPad.side1; width = Tk_Width(tePtr->tkwin) + PADDING(tePtr->xPad); height = Tk_Height(tePtr->tkwin) + PADDING(tePtr->yPad); if ((ix >= x) && (ix <= (x + width)) && (iy >= y) && (iy <= (y + height))) { int left, right, top, bottom; int last; int grip; RowColumn *rcPtr; last = tePtr->column.rcPtr->index + tePtr->column.span - 1; link = Blt_Chain_GetNthLink(tablePtr->cols.chain, last); rcPtr = Blt_Chain_GetValue(link); /* Calculate the span rectangle */ left = (tePtr->column.rcPtr->offset - tePtr->column.rcPtr->pad.side1); right = (rcPtr->offset - rcPtr->pad.side1) + rcPtr->size; top = (tePtr->row.rcPtr->offset - tePtr->row.rcPtr->pad.side1); last = tePtr->row.rcPtr->index + tePtr->row.span - 1; link = Blt_Chain_GetNthLink(tablePtr->rows.chain, last); rcPtr = Blt_Chain_GetValue(link); bottom = (rcPtr->offset - rcPtr->pad.side1) + rcPtr->size; tedPtr->activeRectArr[0].x = left; tedPtr->activeRectArr[0].y = top; tedPtr->activeRectArr[0].width = (right - left); tedPtr->activeRectArr[0].height = (bottom - top); grip = tedPtr->gripSize; tedPtr->activeRectArr[1].x = (left + right - grip) / 2; tedPtr->activeRectArr[1].y = top; tedPtr->activeRectArr[1].width = grip - 1; tedPtr->activeRectArr[1].height = grip - 1; tedPtr->activeRectArr[2].x = left; tedPtr->activeRectArr[2].y = (top + bottom - grip) / 2; tedPtr->activeRectArr[2].width = grip - 1; tedPtr->activeRectArr[2].height = grip - 1; tedPtr->activeRectArr[3].x = (left + right - grip) / 2; tedPtr->activeRectArr[3].y = bottom - grip; tedPtr->activeRectArr[3].width = grip - 1; tedPtr->activeRectArr[3].height = grip - 1; tedPtr->activeRectArr[4].x = right - grip; tedPtr->activeRectArr[4].y = (top + bottom - grip) / 2; tedPtr->activeRectArr[4].width = grip - 1; tedPtr->activeRectArr[4].height = grip - 1; interp->result = Tk_PathName(tePtr->tkwin); active = 1; break; } } if ((active) || (active != tedPtr->spanActive)) { tedPtr->spanActive = active; EventuallyRedraw(tedPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * EditOp -- * * Processes an objv/objc list of table entries to add and configure * new widgets into the table. A table entry consists of the * window path name, table index, and optional configuration options. * The first argument in the objv list is the name of the table. If * no table exists for the given window, a new one is created. * * Results: * Returns a standard TCL result. If an error occurred, TCL_ERROR is * returned and an error message is left in interp->result. * * Side Effects: * Memory is allocated, a new master table is possibly created, etc. * The table is re-computed and arranged at the next idle point. * *--------------------------------------------------------------------------- */ static int RepOp( TableInterpData *dataPtr, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Interpreter to return list of names to */ int objc, /* Number of arguments */ Tcl_Obj *const *objv) { Tk_Window tkwin; Table *tablePtr; TableEditor *tedPtr; if (Blt_GetTableFromObj(dataPtr, interp, objv[2], &tablePtr) != TCL_OK) { return TCL_ERROR; } /* ted rep master index */ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[3]), dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } if (tablePtr->editPtr != NULL) { /* Already editing this table */ tedPtr = (TableEditor *) tablePtr->editPtr; } else { tedPtr = CreateTableEditor(tablePtr, interp); if (tedPtr == NULL) { return TCL_ERROR; } } if (ConfigureTableEditor(tedPtr, objc - 3, objv + 3, 0) != TCL_OK) { tedPtr->tkwin = NULL; if (tedPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTableEditor, tedPtr); } Tcl_EventuallyFree(tedPtr, DestroyTableEditor); return TCL_ERROR; } /* Rearrange the table */ if (!(tablePtr->flags & ARRANGE_PENDING)) { tablePtr->flags |= ARRANGE_PENDING; Tcl_DoWhenIdle(tablePtr->arrangeProc, tablePtr); } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(tedPtr->tkwin), -1); tedPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(tedPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Command options for the table editor. * * The fields for Blt_OperSpec are as follows: * * - option name * - minimum number of characters required to disambiguate the option name. * - function associated with command option. * - minimum number of arguments required. * - maximum number of arguments allowed (0 indicates no limit). * - usage string * *--------------------------------------------------------------------------- */ static Blt_OpSpec tedOps[] = { {"cget", 2, CgetOp, 4, 4, "master option",}, {"configure", 2, ConfigureOp, 3, 0, "master ?option...?",}, {"edit", 1, EditOp, 3, 0, "master ?options...?",}, {"rep", 1, RepOp, 2, 0, "master index ?options...?",}, {"select", 1, SelectOp, 4, 0, "master @x,y",}, /* {"forget", 1, ForgetOp, 3, 0, "master ?master...?",}, {"index", 1, IndexOp, 3, 0, "master ?item...?",}, */ }; static int nTedOps = sizeof(tedOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * TedCmd -- * * This procedure is invoked to process the TCL command that * corresponds to the table geometry manager. See the user * documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int TedCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTedOps, tedOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } static TableData * GetTableInterpData(Tcl_Interp *interp) { TableData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (TableData *)Tcl_GetAssocData(interp, TABLE_THREAD_KEY, &proc); assert(dataPtr); return dataPtr; } /* *--------------------------------------------------------------------------- * * Blt_TedCmdInitProc -- * * This procedure is invoked to initialize the TCL command that * corresponds to the table geometry manager. * * Results: * None. * * Side effects: * Creates the new command and adds an entry into a global Tcl * associative array. * *--------------------------------------------------------------------------- */ int Blt_TedCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"ted", TedCmd, }; cmdSpec.clientData = GetTableInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltMacBitmap.c����������������������������������������������������������������0000644�0001750�0001750�00000043474�11462120062�015544� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltMacOSXBitmap.c -- * * This module implements MacOSX-specific bitmap processing procedures * for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * The color allocation routines are adapted from tkImgPhoto.c of the * Tk library distrubution. The photo image type was designed and * implemented by Paul Mackerras. * * Copyright (c) 1987-1993 The Regents of the University of * California. * * Copyright (c) 19941998 Sun Microsystems, Inc. * */ #include "bltInt.h" #include "bltHash.h" #ifdef notdef #include "bltPicture.h" #endif #include <X11/Xutil.h> #define ROTATE_0 0 #define ROTATE_90 1 #define ROTATE_180 2 #define ROTATE_270 3 Pixmap Blt_PhotoImageMask(Tk_Window tkwin, Tk_PhotoImageBlock src) { Pixmap bitmap; int arraySize, bytes_per_line; int offset, count; int y; unsigned char *bits; unsigned char *dp; #ifdef notdef bytes_per_line = (src.width + 7) / 8; arraySize = src.height * bytes_per_line; bits = Blt_AssertMalloc(sizeof(unsigned char) * arraySize); dp = bits; offset = count = 0; for (y = 0; y < src.height; y++) { int value, bitMask; int x; unsigned char *sp; value = 0, bitMask = 1; sp = src.pixelPtr + offset; for (x = 0; x < src.width; /*empty*/ ) { unsigned long pixel; pixel = (sp[src.offset[3]] != 0x00); if (pixel) { value |= bitMask; } else { count++; /* Count the number of transparent pixels. */ } bitMask <<= 1; x++; if (!(x & 7)) { *dp++ = (unsigned char)value; value = 0, bitMask = 1; } sp += src.pixelSize; } if (x & 7) { *dp++ = (unsigned char)value; } offset += src.pitch; } if (count > 0) { Tk_MakeWindowExist(tkwin); bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin), (char *)bits, (unsigned int)src.width, (unsigned int)src.height); } else { bitmap = None; /* Image is opaque. */ } Blt_Free(bits); #endif return bitmap; } #ifdef notdef Pixmap Blt_PictureMask(Tk_Window tkwin, Picture *srcPtr) { Blt_Pixel *srcRowPtr; Pixmap bitmap; int bytesPerLine; int count; int x, y; unsigned char *bits; unsigned char *destRowPtr; bytesPerLine = (srcPtr->width + 7) / 8; bits = Blt_AssertMalloc(sizeof(unsigned char)*srcPtr->height*bytesPerLine); count = 0; srcRowPtr = srcPtr->bits; destRowPtr = bits; for (y = 0; y < srcPtr->height; y++) { int value, bitMask; Blt_Pixel *sp; unsigned char *dp; sp = srcRowPtr, dp = destRowPtr; value = 0, bitMask = 1; for (x = 0; x < srcPtr->width; /*empty*/ ) { unsigned long pixel; pixel = (sp->Alpha != ALPHA_TRANSPARENT); if (pixel) { value |= bitMask; } else { count++; /* Count the number of transparent pixels. */ } bitMask <<= 1; x++; if (!(x & 7)) { *dp++ = (unsigned char)value; value = 0, bitMask = 1; } sp++; } if (x & 7) { *dp++ = (unsigned char)value; } srcRowPtr += srcPtr->pixelsPerRow; destRowPtr += bytesPerLine; } if (count > 0) { Tk_MakeWindowExist(tkwin); bitmap = XCreateBitmapFromData(Tk_Display(tkwin), Tk_WindowId(tkwin), (char *)bits, (unsigned int)srcPtr->width, (unsigned int)srcPtr->height); } else { bitmap = None; /* Image is opaque. */ } Blt_Free(bits); return bitmap; } #endif /* *--------------------------------------------------------------------------- * * Blt_RotateBitmap -- * * Creates a new bitmap containing the rotated image of the given * bitmap. We also need a special GC of depth 1, so that we do * not need to rotate more than one plane of the bitmap. * * Results: * Returns a new bitmap containing the rotated image. * *--------------------------------------------------------------------------- */ Pixmap Blt_RotateBitmap( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap to be rotated */ int srcWidth, int srcHeight, /* Width and height of the source bitmap */ float angle, /* # of degrees to rotate the bitmap. */ int *destWidthPtr, int *destHeightPtr) { Display *display; /* X display */ GC bitmapGC; Pixmap destBitmap; Window root; /* Root window drawable */ XImage *srcImgPtr, *destImgPtr; double rotWidth, rotHeight; int destWidth, destHeight; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); #ifdef notdef /* Create a bitmap and image big enough to contain the rotated text */ Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); destWidth = ROUND(rotWidth); destHeight = ROUND(rotHeight); destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); bitmapGC = Blt_GetBitmapGC(tkwin); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, destWidth, destHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, destWidth, destHeight, 1, ZPixmap); angle = FMOD(angle, 360.0); if (FMOD(angle, 90.0) == 0.0) { int quadrant; int y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < destHeight; y++) { int x, sx; sx = y; for (x = 0; x < destWidth; x++) { int sy; unsigned long pixel; sy = destWidth - x - 1; pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < destHeight; y++) { int x, sy; sy = destHeight - y - 1; for (x = 0; x < destWidth; x++) { int sx; unsigned long pixel; sx = destWidth - x - 1, pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < destHeight; y++) { int x, sx; sx = destHeight - y - 1; for (x = 0; x < destWidth; x++) { int sy; unsigned long pixel; sy = x; pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < destHeight; y++) { int x; for (x = 0; x < destWidth; x++) { unsigned long pixel; pixel = XGetPixel(srcImgPtr, x, y); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double sox, soy; /* Offset from the center of * the source rectangle. */ double destCX, destCY; /* Offset to the center of the destination * rectangle. */ int y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ sox = srcWidth * 0.5; soy = srcHeight * 0.5; destCX = destWidth * 0.5; destCY = destHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < destHeight; y++) { double ty; int x; ty = y - destCY; for (x = 0; x < destWidth; x++) { double tx, rx, ry, sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = x - destCX; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += sox; ry += soy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } } /* Write the rotated image into the destination bitmap. */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, destWidth, destHeight); /* Clean up the temporary resources used. */ XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); *destWidthPtr = destWidth; *destHeightPtr = destHeight; #endif return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_ScaleBitmap -- * * Creates a new scaled bitmap from another bitmap. The new bitmap * is bounded by a specified region. Only this portion of the bitmap * is scaled from the original bitmap. * * By bounding scaling to a region we can generate a new bitmap * which is no bigger than the specified viewport. * * Results: * The new scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleBitmap( Tk_Window tkwin, Pixmap srcBitmap, int srcWidth, int srcHeight, int destWidth, int destHeight) { Display *display; GC bitmapGC; Pixmap destBitmap; Window root; XImage *srcImgPtr, *destImgPtr; double xScale, yScale; int y; /* Destination bitmap coordinates */ /* Create a new bitmap the size of the region and clear it */ display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); #ifdef notdef destBitmap = Tk_GetPixmap(display, root, destWidth, destHeight, 1); bitmapGC = Blt_GetBitmapGC(tkwin); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, destWidth, destHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, destWidth, destHeight, 1, ZPixmap); /* * Scale each pixel of destination image from results of source * image. Verify the coordinates, since the destination image can * be bigger than the source */ xScale = (double)srcWidth / (double)destWidth; yScale = (double)srcHeight / (double)destHeight; /* Map each pixel in the destination image back to the source. */ for (y = 0; y < destHeight; y++) { int x, sy; sy = (int)(yScale * (double)y); for (x = 0; x < destWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)x); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } /* Write the scaled image into the destination bitmap */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, destWidth, destHeight); XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); #endif return destBitmap; } /* *--------------------------------------------------------------------------- * * Blt_RotateScaleBitmapArea -- * * Creates a scaled and rotated bitmap from a given bitmap. The * caller also provides (offsets and dimensions) the region of * interest in the destination bitmap. This saves having to * process the entire destination bitmap is only part of it is * showing in the viewport. * * This uses a simple rotation/scaling of each pixel in the * destination image. For each pixel, the corresponding * pixel in the source bitmap is used. This means that * destination coordinates are first scaled to the size of * the rotated source bitmap. These coordinates are then * rotated back to their original orientation in the source. * * Results: * The new rotated and scaled bitmap is returned. * * Side Effects: * A new pixmap is allocated. The caller must release this. * *--------------------------------------------------------------------------- */ Pixmap Blt_ScaleRotateBitmapArea( Tk_Window tkwin, Pixmap srcBitmap, /* Source bitmap. */ unsigned int srcWidth, unsigned int srcHeight, /* Size of source bitmap */ int regionX, int regionY, /* Offset of region in virtual * destination bitmap. */ unsigned int regionWidth, unsigned int regionHeight, /* Desire size of bitmap region. */ unsigned int destWidth, unsigned int destHeight, /* Virtual size of destination bitmap. */ float angle) /* Angle to rotate bitmap. */ { Display *display; /* X display */ Window root; /* Root window drawable */ Pixmap destBitmap; XImage *srcImgPtr, *destImgPtr; double xScale, yScale; double rotWidth, rotHeight; GC bitmapGC; display = Tk_Display(tkwin); root = Tk_RootWindow(tkwin); #ifdef notdef /* Create a bitmap and image big enough to contain the rotated text */ bitmapGC = Blt_GetBitmapGC(tkwin); destBitmap = Tk_GetPixmap(display, root, regionWidth, regionHeight, 1); XSetForeground(display, bitmapGC, 0x0); XFillRectangle(display, destBitmap, bitmapGC, 0, 0, regionWidth, regionHeight); srcImgPtr = XGetImage(display, srcBitmap, 0, 0, srcWidth, srcHeight, 1, ZPixmap); destImgPtr = XGetImage(display, destBitmap, 0, 0, regionWidth, regionHeight, 1, ZPixmap); angle = FMOD(angle, 360.0); Blt_GetBoundingBox(srcWidth, srcHeight, angle, &rotWidth, &rotHeight, (Point2d *)NULL); xScale = rotWidth / (double)destWidth; yScale = rotHeight / (double)destHeight; if (FMOD(angle, (double)90.0) == 0.0) { int quadrant; int x, y; /* Handle right-angle rotations specifically */ quadrant = (int)(angle / 90.0); switch (quadrant) { case ROTATE_270: /* 270 degrees */ for (y = 0; y < regionHeight; y++) { int sx; sx = (int)(yScale * (double)(y + regionY)); for (x = 0; x < regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale *(double)(destWidth - (x + regionX) - 1)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_180: /* 180 degrees */ for (y = 0; y < regionHeight; y++) { int sy; sy = (int)(yScale * (double)(destHeight - (y + regionY) - 1)); for (x = 0; x < regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale *(double)(destWidth - (x + regionX) - 1)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_90: /* 90 degrees */ for (y = 0; y < regionHeight; y++) { int sx; sx = (int)(yScale * (double)(destHeight - (y + regionY) - 1)); for (x = 0; x < regionWidth; x++) { int sy; unsigned long pixel; sy = (int)(xScale * (double)(x + regionX)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; case ROTATE_0: /* 0 degrees */ for (y = 0; y < regionHeight; y++) { int sy; sy = (int)(yScale * (double)(y + regionY)); for (x = 0; x < regionWidth; x++) { int sx; unsigned long pixel; sx = (int)(xScale * (double)(x + regionX)); pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } break; default: /* The calling routine should never let this happen. */ break; } } else { double radians, sinTheta, cosTheta; double sox, soy; /* Offset from the center of the * source rectangle. */ double rox, roy; /* Offset to the center of the * rotated rectangle. */ int x, y; radians = (angle / 180.0) * M_PI; sinTheta = sin(radians), cosTheta = cos(radians); /* * Coordinates of the centers of the source and destination rectangles */ sox = srcWidth * 0.5; soy = srcHeight * 0.5; rox = rotWidth * 0.5; roy = rotHeight * 0.5; /* For each pixel of the destination image, transform back to the * associated pixel in the source image. */ for (y = 0; y < regionHeight; y++) { double ty; ty = (yScale * (double)(y + regionY)) - roy; for (x = 0; x < regionWidth; x++) { double tx, rx, ry; int sx, sy; unsigned long pixel; /* Translate origin to center of destination image. */ tx = (xScale * (double)(x + regionX)) - rox; /* Rotate the coordinates about the origin. */ rx = (tx * cosTheta) - (ty * sinTheta); ry = (tx * sinTheta) + (ty * cosTheta); /* Translate back to the center of the source image. */ rx += sox; ry += soy; sx = ROUND(rx); sy = ROUND(ry); /* * Verify the coordinates, since the destination image can be * bigger than the source. */ if ((sx >= srcWidth) || (sx < 0) || (sy >= srcHeight) || (sy < 0)) { continue; } pixel = XGetPixel(srcImgPtr, sx, sy); if (pixel) { XPutPixel(destImgPtr, x, y, pixel); } } } } /* Write the rotated image into the destination bitmap. */ XPutImage(display, destBitmap, bitmapGC, destImgPtr, 0, 0, 0, 0, regionWidth, regionHeight); /* Clean up the temporary resources used. */ XDestroyImage(srcImgPtr), XDestroyImage(destImgPtr); #endif return destBitmap; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltArrayObj.h�����������������������������������������������������������������0000644�0001750�0001750�00000003043�11462120062�015411� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltArrayObj.h -- * * This file implements an array-based Tcl_Obj. * * Copyright (c) 2000 George A. Howlett * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_ARRAY_OBJ_H #define _BLT_ARRAY_OBJ_H #include "bltHash.h" BLT_EXTERN int Blt_GetArrayFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Blt_HashTable **tablePtrPtr); BLT_EXTERN Tcl_Obj *Blt_NewArrayObj(int objc, Tcl_Obj *objv[]); BLT_EXTERN void Blt_RegisterArrayObj(void); BLT_EXTERN int Blt_IsArrayObj(Tcl_Obj *obj); #endif /* _BLT_ARRAY_OBJ_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictTif.c������������������������������������������������������������������0000644�0001750�0001750�00000056765�11462120062�015260� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictTif.c -- * * This module implements TIF file format conversion routines for the picture * image type in the BLT toolkit. * * Copyright 2003-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "blt.h" #include "config.h" #ifdef HAVE_LIBTIF #include <tcl.h> #include <bltSwitch.h> #include <bltDBuffer.h> #include <bltHash.h> #include <bltChain.h> #include "bltPicture.h" #include "bltPictFmts.h" #include <bltAlloc.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif /* HAVE_MEMORY_H */ #if defined(WIN32) || defined(MACOSX) #include <setjmp.h> #endif typedef struct _Blt_Picture Picture; #include <tiffio.h> typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; int compress; int index; } TifExportSwitches; typedef struct { Tcl_Obj *dataObjPtr; Tcl_Obj *fileObjPtr; } TifImportSwitches; static Blt_SwitchParseProc CompressSwitch; static Blt_SwitchCustom compressSwitch = { CompressSwitch, NULL, (ClientData)0, }; static Blt_SwitchSpec exportSwitches[] = { {BLT_SWITCH_CUSTOM, "-compress", "type", Blt_Offset(TifExportSwitches, compress), 0, 0, &compressSwitch}, {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(TifExportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(TifExportSwitches, fileObjPtr), 0}, {BLT_SWITCH_INT_NNEG, "-index", "int", Blt_Offset(TifExportSwitches, index), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec importSwitches[] = { {BLT_SWITCH_OBJ, "-data", "data", Blt_Offset(TifImportSwitches, dataObjPtr), 0}, {BLT_SWITCH_OBJ, "-file", "fileName", Blt_Offset(TifImportSwitches, fileObjPtr), 0}, {BLT_SWITCH_END} }; DLLEXPORT extern Tcl_AppInitProc Blt_PictureTifInit; extern const char *Blt_Itoa(int); /* *--------------------------------------------------------------------------- * * CompressSwitch -- * * Convert a Tcl_Obj representing a TIFF compression name. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ static const char *compressNames[] = { "lzw", /* Lempel-Ziv & Welch */ "ojpeg", /* !6.0 JPEG */ "jpeg", /* %JPEG DCT compression */ "next", /* NeXT 2-bit RLE */ "packbits", /* Macintosh RLE */ "thunderscan", /* ThunderScan RLE */ "pixarfilm", /* Pixar companded 10bit LZW */ "pixarlog", /* Pixar companded 11bit ZIP */ "deflate", /* Deflate compression */ "adobe_deflate", /* Adobe's deflate */ "dcs", /* Kodak DCS encoding */ "sgilog", /* SGI Log Luminance RLE */ "sgilog24", /* SGI Log 24-bit packed */ NULL }; static int nCompressNames = sizeof(compressNames) / sizeof(char *); /*ARGSUSED*/ static int CompressSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to return results. */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { int *compressPtr = (int *)(record + offset); int i; char *string; char c; string = Tcl_GetString(objPtr); c = string[0]; if (c == '\0') { *compressPtr = 0; return TCL_OK; } for (i = 0; i < nCompressNames; i++) { if ((c == compressNames[i][0]) && (strcasecmp(string, compressNames[i]) == 0)) { *compressPtr = i + 1; return TCL_OK; } } Tcl_AppendResult(interp, "unknown TIFF compression mode \"", string, "\"", (char *) NULL); return TCL_ERROR; } static tsize_t TifRead(thandle_t handle, tdata_t out, tsize_t nWanted) { Blt_DBuffer dbuffer = (Blt_DBuffer)handle; if (Blt_DBuffer_BytesLeft(dbuffer) < nWanted) { nWanted = Blt_DBuffer_BytesLeft(dbuffer); } if (nWanted > 0) { memcpy(out, Blt_DBuffer_Pointer(dbuffer), nWanted); Blt_DBuffer_IncrCursor(dbuffer, nWanted); } return nWanted; } static toff_t TifSeek(thandle_t handle, toff_t offset, int whence) { Blt_DBuffer dbuffer = (Blt_DBuffer)handle; if (whence == SEEK_CUR) { offset += Blt_DBuffer_Cursor(dbuffer); } else if (whence == SEEK_END) { offset += Blt_DBuffer_Length(dbuffer); } if (offset < 0) { return -1; } if (offset > Blt_DBuffer_Size(dbuffer)) { /* Attempting to seek past the end of the current * buffer. Resize the buffer */ Blt_DBuffer_Resize(dbuffer, offset); } Blt_DBuffer_SetCursor(dbuffer, offset); return (toff_t) Blt_DBuffer_Cursor(dbuffer); } static toff_t TifSize(thandle_t handle) { Blt_DBuffer dbuffer = (Blt_DBuffer)handle; return Blt_DBuffer_Length(dbuffer); } static int TifMapFile(thandle_t handle, tdata_t *data, toff_t *offsetPtr) { return 0; } static void TifUnmapFile(thandle_t handle, tdata_t data, toff_t offset) { } static int TifClose(thandle_t handle) { return 0; } static tsize_t TifWrite(thandle_t handle, tdata_t out, tsize_t nBytes) { Blt_DBuffer dbuffer = (Blt_DBuffer)handle; unsigned int needed; needed = Blt_DBuffer_Cursor(dbuffer) + nBytes; if (needed > Blt_DBuffer_Size(dbuffer)) { if (!Blt_DBuffer_Resize(dbuffer, needed)) { return -1; } } memcpy(Blt_DBuffer_Pointer(dbuffer), out, nBytes); Blt_DBuffer_IncrCursor(dbuffer, nBytes); if (Blt_DBuffer_Cursor(dbuffer) > Blt_DBuffer_Length(dbuffer)) { Blt_DBuffer_SetLength(dbuffer, Blt_DBuffer_Cursor(dbuffer)); } return nBytes; } typedef struct { Tcl_DString errors; Tcl_DString warnings; int nWarnings, nErrors; } TifMessage; static TifMessage *tifMessagePtr; static void TifError(const char *routine, const char *fmt, va_list ap) { char string[BUFSIZ+4]; int length; length = vsnprintf(string, BUFSIZ, fmt, ap); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&tifMessagePtr->errors, string, -1); tifMessagePtr->nErrors++; } /* warnings are not processed in TCL */ static void TifWarning(const char *routine, const char *fmt, va_list ap) { char string[BUFSIZ+4]; int length; length = vsnprintf(string, BUFSIZ, fmt, ap); if (length > BUFSIZ) { strcat(string, "..."); } Tcl_DStringAppend(&tifMessagePtr->warnings, string, -1); Tcl_DStringAppend(&tifMessagePtr->warnings, "\n", -1); tifMessagePtr->nWarnings++; } static int TifReadImage(Tcl_Interp *interp, TIFF *tifPtr, Blt_Chain chain) { int w, h, nPixels; uint32 *srcBits, *sp; Picture *destPtr; Blt_Pixel *destRowPtr; int y; TIFFGetField(tifPtr, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tifPtr, TIFFTAG_IMAGELENGTH, &h); nPixels = w * h; srcBits = _TIFFmalloc(sizeof(uint32) * nPixels); if (srcBits == NULL) { Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(nPixels), " buffer for TIF image", (char *)NULL); return TCL_ERROR; } if (!TIFFReadRGBAImage(tifPtr, w, h, srcBits, /*stopOnError*/0)) { Tcl_AppendResult(interp, "can't read image in directory", (char *)NULL); _TIFFfree(srcBits); return TCL_ERROR; } destPtr = Blt_CreatePicture(w, h); destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * (h - 1)); sp = srcBits; for (y = h - 1; y >= 0; y--) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { dp->Red = TIFFGetR(*sp); dp->Green = TIFFGetG(*sp); dp->Blue = TIFFGetB(*sp); dp->Alpha = TIFFGetA(*sp); sp++; } destRowPtr -= destPtr->pixelsPerRow; } Blt_Chain_Append(chain, destPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsTif -- * * Attempts to parse a TIF file header. * * Results: * Returns 1 is the header is TIF and 0 otherwise. Note that the * validity of the header contents is not checked here. That's done in * TifToPicture. * *--------------------------------------------------------------------------- */ static int IsTif(Blt_DBuffer dbuffer) { unsigned char *bp; int bool; Blt_DBuffer_ResetCursor(dbuffer); bp = Blt_DBuffer_Pointer(dbuffer); bool = (((bp[0] == 'M') && (bp[1] == 'M')) || ((bp[0] == 'I') && (bp[1] == 'I'))); return bool; } /* *--------------------------------------------------------------------------- * * TifToPicture -- * * Reads a TIFF file and converts it into a picture. * * Results: * The picture is returned. If an error occured, such as the * designated file could not be opened, NULL is returned. * *--------------------------------------------------------------------------- */ static Blt_Chain TifToPicture( Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer, TifImportSwitches *switchesPtr) { Blt_Chain chain; TIFF *tifPtr; TIFFErrorHandler oldErrorHandler, oldWarningHandler; TifMessage message; message.nWarnings = message.nErrors = 0; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); Tcl_DStringAppend(&message.errors, "error reading \"", -1); Tcl_DStringAppend(&message.errors, fileName, -1); Tcl_DStringAppend(&message.errors, "\": ", -1); tifMessagePtr = &message; oldErrorHandler = TIFFSetErrorHandler(TifError); oldWarningHandler = TIFFSetWarningHandler(TifWarning); chain = NULL; tifPtr = TIFFClientOpen(fileName, "r", (thandle_t)dbuffer, TifRead, /* TIFFReadProc */ TifWrite, /* TIFFWriteProc */ TifSeek, /* TIFFSeekProc */ TifClose, /* TIFFCloseProc */ TifSize, /* TIFFSizeProc */ TifMapFile, /* TIFFMapFileProc */ TifUnmapFile); /* TIFFUnmapFileProc */ if (tifPtr == NULL) { goto bad; } chain = Blt_Chain_Create(); do { if (TifReadImage(interp, tifPtr, chain) != TCL_OK) { goto bad; } } while (TIFFReadDirectory(tifPtr)); bad: if (tifPtr != NULL) { TIFFClose(tifPtr); } TIFFSetErrorHandler(oldErrorHandler); TIFFSetWarningHandler(oldWarningHandler); if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "TIF_READ_WARNINGS", Tcl_DStringValue(&message.warnings), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); if (message.nErrors > 0) { Tcl_AppendResult(interp, Tcl_DStringValue(&message.errors), (char *)NULL); } Tcl_DStringFree(&message.errors); return chain; } static int tifCompressionSchemes[] = { COMPRESSION_NONE, #ifdef LZW_SUPPORT COMPRESSION_LZW, /* Lempel-Ziv & Welch */ #else COMPRESSION_NONE, #endif #ifdef OJPEG_SUPPORT COMPRESSION_OJPEG, /* !6.0 JPEG */ #else COMPRESSION_NONE, #endif /* OJPEG_SUPPORT */ #ifdef JPEG_SUPPORT COMPRESSION_JPEG, /* %JPEG DCT compression */ #else COMPRESSION_NONE, #endif /* JPEG_SUPPORT */ #ifdef NEXT_SUPPORT COMPRESSION_NEXT, /* NeXT 2-bit RLE */ #else COMPRESSION_NONE, #endif /* NEXT_SUPPORT */ #ifdef PACKBITS_SUPPORT COMPRESSION_PACKBITS, /* Macintosh RLE */ #else COMPRESSION_NONE, #endif /* PACKBITS_SUPPORT */ #ifdef THUNDER_SUPPORT COMPRESSION_THUNDERSCAN, /* ThunderScan RLE */ #else COMPRESSION_NONE, #endif /* THUNDER_SUPPORT */ COMPRESSION_PIXARFILM, /* Pixar 10-bit LZW */ #ifdef PIXARLOG_SUPPORT COMPRESSION_PIXARLOG, /* Pixar 11-bit ZIP */ #else COMPRESSION_NONE, #endif /* PIXARLOG_SUPPORT */ #ifdef ZIP_SUPPORT COMPRESSION_DEFLATE, /* Deflate compression */ #else COMPRESSION_NONE, #endif /* ZIP_SUPPORT */ #ifdef ADOBE_SUPPORT COMPRESSION_ADOBE_DEFLATE, /* Adobe's deflate */ #else COMPRESSION_NONE, #endif /* ADOBE_SUPPORT */ COMPRESSION_DCS, /* Kodak DCS encoding */ #ifdef SGILOG_SUPPORT COMPRESSION_SGILOG, /* SGI Log Luminance RLE */ COMPRESSION_SGILOG24, /* SGI Log 24-bit packed */ #else COMPRESSION_NONE, COMPRESSION_NONE, #endif /* SGILOG_SUPPORT */ }; /* *--------------------------------------------------------------------------- * * PictureToTif -- * * Writes a TIFF format image to the provided data buffer. * * Results: * A standard TCL result. If an error occured, TCL_ERROR is * returned and an error message will be place in the interpreter * result. Otherwise, the data sink will contain the binary * output of the image. * * Side Effects: * Memory is allocated for the data sink. * *--------------------------------------------------------------------------- */ static int PictureToTif(Tcl_Interp *interp, Blt_Picture picture, Blt_DBuffer dbuffer, TifExportSwitches *switchesPtr) { TIFF *tifPtr; TIFFErrorHandler oldErrorHandler, oldWarningHandler; TifMessage message; int photometric, samplesPerPixel; int compress, result, nColors; Picture *srcPtr; compress = tifCompressionSchemes[switchesPtr->compress]; if (compress == COMPRESSION_NONE) { fprintf(stderr, "not compressing TIFF output\n"); } #ifdef notdef if (!TIFFIsCODECConfigured((unsigned short int)compress)) { compress = COMPRESSION_NONE; } #endif srcPtr = picture; Tcl_DStringInit(&message.errors); Tcl_DStringInit(&message.warnings); Tcl_DStringAppend(&message.errors, "error writing TIF output: ", -1); tifMessagePtr = &message; message.nErrors = message.nWarnings = 0; oldErrorHandler = TIFFSetErrorHandler(TifError); oldWarningHandler = TIFFSetWarningHandler(TifWarning); tifPtr = TIFFClientOpen("data buffer", "w", (thandle_t)dbuffer, TifRead, /* TIFFReadWriteProc */ TifWrite, /* TIFFReadWriteProc */ TifSeek, /* TIFFSeekProc */ TifClose, /* TIFFCloseProc */ TifSize, /* TIFFSizeProc */ TifMapFile, /* TIFFMapFileProc */ TifUnmapFile); /* TIFFUnmapFileProc */ if (tifPtr == NULL) { Tcl_AppendResult(interp, "can't register TIF procs: ", (char *)NULL); return TCL_ERROR; } nColors = Blt_QueryColors(srcPtr, (Blt_HashTable *)NULL); if (Blt_PictureIsColor(srcPtr)) { samplesPerPixel = (Blt_PictureIsOpaque(srcPtr)) ? 3 : 4; photometric = PHOTOMETRIC_RGB; } else { if (!Blt_PictureIsOpaque(srcPtr)) { Blt_Picture background; Blt_Pixel white; /* Blend picture with solid color background. */ background = Blt_CreatePicture(srcPtr->width, srcPtr->height); white.u32 = 0xFFFFFFFF; Blt_BlankPicture(background, &white); /* White background. */ Blt_BlendPictures(background, srcPtr, 0, 0, srcPtr->width, srcPtr->height, 0, 0); srcPtr = background; } samplesPerPixel = 1; photometric = PHOTOMETRIC_MINISBLACK; } TIFFSetField(tifPtr, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(tifPtr, TIFFTAG_COMPRESSION, (unsigned short int)compress); TIFFSetField(tifPtr, TIFFTAG_IMAGELENGTH, srcPtr->height); TIFFSetField(tifPtr, TIFFTAG_IMAGEWIDTH, srcPtr->width); TIFFSetField(tifPtr, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(tifPtr, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(tifPtr, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tifPtr, TIFFTAG_RESOLUTIONUNIT, 2); TIFFSetField(tifPtr, TIFFTAG_ROWSPERSTRIP, srcPtr->height); TIFFSetField(tifPtr, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel); TIFFSetField(tifPtr, TIFFTAG_SOFTWARE, TIFFGetVersion()); TIFFSetField(tifPtr, TIFFTAG_XRESOLUTION, 300.0f); TIFFSetField(tifPtr, TIFFTAG_YRESOLUTION, 300.0f); #ifdef WORD_BIGENDIAN TIFFSetField(tifPtr, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); #else TIFFSetField(tifPtr, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); #endif result = -1; { Blt_Pixel *srcRowPtr; int destBitsSize; int y; unsigned char *destBits; unsigned char *dp; destBitsSize = srcPtr->width * srcPtr->height * sizeof(uint32); destBits = (unsigned char *)_TIFFmalloc(destBitsSize); if (destBits == NULL) { TIFFError("tiff", "can't allocate space for TIF buffer"); TIFFClose(tifPtr); return TCL_ERROR; } dp = destBits; srcRowPtr = srcPtr->bits; switch (samplesPerPixel) { case 4: for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int x; sp = srcRowPtr; for (x = 0; x < srcPtr->width; x++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp[3] = sp->Alpha; dp += 4, sp++; } srcRowPtr += srcPtr->pixelsPerRow; } break; case 3: /* RGB, 100% opaque image. */ for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int x; sp = srcRowPtr; for (x = 0; x < srcPtr->width; x++) { dp[0] = sp->Red; dp[1] = sp->Green; dp[2] = sp->Blue; dp += 3, sp++; } srcRowPtr += srcPtr->pixelsPerRow; } break; case 1: for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp; int x; sp = srcRowPtr; for (x = 0; x < srcPtr->width; x++) { *dp++ = sp->Red; sp++; } srcRowPtr += srcPtr->pixelsPerRow; } break; } result = TIFFWriteEncodedStrip(tifPtr, 0, destBits, destBitsSize); if (result < 0) { Tcl_AppendResult(interp, "error writing TIFF encoded strip", (char *)NULL); } _TIFFfree(destBits); } TIFFClose(tifPtr); if (result == -1) { Blt_DBuffer_Free(dbuffer); } TIFFSetErrorHandler(oldErrorHandler); TIFFSetWarningHandler(oldWarningHandler); if (message.nWarnings > 0) { Tcl_SetErrorCode(interp, "PICTURE", "TIF_WRITE_WARNINGS", Tcl_DStringValue(&message.warnings), (char *)NULL); } else { Tcl_SetErrorCode(interp, "NONE", (char *)NULL); } Tcl_DStringFree(&message.warnings); if (message.nErrors > 0) { Tcl_DStringResult(interp, &message.errors); } Tcl_DStringFree(&message.errors); if (srcPtr != picture) { Blt_FreePicture(srcPtr); } return (result == -1) ? TCL_ERROR : TCL_OK; } static Blt_Chain ReadTif(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dbuffer) { TifImportSwitches switches; memset(&switches, 0, sizeof(switches)); return TifToPicture(interp, fileName, dbuffer, &switches); } static Tcl_Obj * WriteTif(Tcl_Interp *interp, Blt_Picture picture) { Tcl_Obj *objPtr; Blt_DBuffer dbuffer; TifExportSwitches switches; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); dbuffer = Blt_DBuffer_Create(); objPtr = NULL; if (PictureToTif(interp, picture, dbuffer, &switches) == TCL_OK) { char *bytes; bytes = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (bytes != NULL) { objPtr = Tcl_NewStringObj(bytes, -1); Blt_Free(bytes); } } Blt_DBuffer_Destroy(dbuffer); return objPtr; } static Blt_Chain ImportTif(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, const char **fileNamePtr) { Blt_Chain chain; Blt_DBuffer dbuffer; TifImportSwitches switches; const char *string; memset(&switches, 0, sizeof(switches)); if (Blt_ParseSwitches(interp, importSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one import source: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(importSwitches, (char *)&switches, 0); return NULL; } dbuffer = Blt_DBuffer_Create(); chain = NULL; if (switches.dataObjPtr != NULL) { unsigned char *bytes; int nBytes; bytes = Tcl_GetByteArrayFromObj(switches.dataObjPtr, &nBytes); if (Blt_IsBase64(bytes, nBytes)) { if (Blt_DBuffer_DecodeBase64(interp, string, nBytes, dbuffer) != TCL_OK) { goto error; } } else { Blt_DBuffer_AppendData(dbuffer, bytes, nBytes); } string = "data buffer"; *fileNamePtr = NULL; } else { string = Tcl_GetString(switches.fileObjPtr); *fileNamePtr = string; if (Blt_DBuffer_SaveFile(interp, string, dbuffer) != TCL_OK) { goto error; } } chain = TifToPicture(interp, string, dbuffer, &switches); error: Blt_FreeSwitches(importSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return chain; } static int ExportTif(Tcl_Interp *interp, unsigned int index, Blt_Chain chain, int objc, Tcl_Obj *const *objv) { Blt_DBuffer dbuffer; Blt_Picture picture; TifExportSwitches switches; int result; /* Default export switch settings. */ memset(&switches, 0, sizeof(switches)); switches.index = index; if (Blt_ParseSwitches(interp, exportSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } if ((switches.dataObjPtr != NULL) && (switches.fileObjPtr != NULL)) { Tcl_AppendResult(interp, "more than one export destination: ", "use only one -file or -data flag.", (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } picture = Blt_GetNthPicture(chain, switches.index); if (picture == NULL) { Tcl_AppendResult(interp, "no picture at index ", Blt_Itoa(switches.index), (char *)NULL); Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); return TCL_ERROR; } dbuffer = Blt_DBuffer_Create(); result = PictureToTif(interp, picture, dbuffer, &switches); if (result != TCL_OK) { Tcl_AppendResult(interp, "can't convert \"", Tcl_GetString(objv[2]), "\"", (char *)NULL); goto error; } /* Write the TIF data to file or convert it to a base64 string. */ if (switches.fileObjPtr != NULL) { char *fileName; fileName = Tcl_GetString(switches.fileObjPtr); result = Blt_DBuffer_SaveFile(interp, fileName, dbuffer); } else if (switches.dataObjPtr != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_ObjSetVar2(interp, switches.dataObjPtr, NULL, Blt_DBuffer_ByteArrayObj(dbuffer), 0); result = (objPtr == NULL) ? TCL_ERROR : TCL_OK; } else { char *string; string = Blt_DBuffer_EncodeBase64(interp, dbuffer); if (string != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, -1); Blt_Free(string); Tcl_SetObjResult(interp, objPtr); } result = (string == NULL) ? TCL_ERROR : TCL_OK; } error: Blt_FreeSwitches(exportSwitches, (char *)&switches, 0); Blt_DBuffer_Destroy(dbuffer); return result; } int Blt_PictureTifInit(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_extra", BLT_VERSION, /*Exact*/1) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "blt_picture_tif", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return Blt_PictureRegisterFormat(interp, "tif", /* Name of format. */ IsTif, /* Discovery routine. */ ReadTif, /* Read format procedure. */ WriteTif, /* Write format procedure. */ ImportTif, /* Import format procedure. */ ExportTif); /* Export format procedure. */ } #endif /* HAVE_LIBTIF */ �����������./saods9/blt3.0.1/src/bltWinPainter.c���������������������������������������������������������������0000644�0001750�0001750�00000064051�11462120063�015762� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltWinPainter.c -- * * This module implements Win32-specific image processing procedures for the * BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltPicture.h" #include "bltPainter.h" #include "bltWinPainter.h" #include <X11/Xutil.h> #include "tkDisplay.h" #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) #define CFRAC(i, n) ((i) * 65535 / (n)) /* As for CFRAC, but apply exponent of g. */ #define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) typedef struct _Blt_Picture Pict; /* * The following structure is used to encapsulate palette information. */ typedef struct { HPALETTE palette; /* Palette handle used when drawing. */ UINT size; /* Number of entries in the palette. */ int stale; /* 1 if palette needs to be realized, * otherwise 0. If the palette is stale, * then an idle handler is scheduled to * realize the palette. */ Tcl_HashTable refCounts; /* Hash table of palette entry reference counts * indexed by pixel value. */ } TkWinColormap; /* * PainterKey -- * * This structure represents the key used to uniquely identify painters. A * painter is specified by a combination of display, visual, colormap, depth, * and monitor gamma value. */ typedef struct { Display *display; /* Display of painter. Used to free colors * allocated. */ Colormap colormap; /* Colormap used. This may be the default * colormap, or an allocated private map. */ int depth; /* Pixel depth of the display. */ float gamma; /* Gamma correction value of monitor. */ } PainterKey; #define GC_PRIVATE 1 /* Indicates if the GC in the painter was * shared (allocated by Tk_GetGC) or private * (by XCreateGC). */ static Tcl_FreeProc FreePainter; static Blt_HashTable painterTable; static int initialized = 0; static void GetPaletteColors(HDC hDC, Painter *p, Blt_Pixel *colors) { DWORD flags; flags = GetDeviceCaps(hDC, RASTERCAPS); if (flags & RC_PALETTE) { LOGPALETTE *logPalPtr; PALETTEENTRY *pePtr; Blt_Pixel *dp, *dend; TkWinColormap *cmap; logPalPtr = (LOGPALETTE *) GlobalAlloc(GPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)); logPalPtr->palVersion = 0x300; cmap = (TkWinColormap *)p->colormap; logPalPtr->palNumEntries = GetPaletteEntries(cmap->palette, 0, 256, logPalPtr->palPalEntry); pePtr = logPalPtr->palPalEntry; for (dp = colors, dend = dp + logPalPtr->palNumEntries; dp < dend; dp++, pePtr++) { #ifdef notdef int r, g, b; r = p->igammaTable[r]; g = p->igammaTable[g]; b = p->igammaTable[b]; #endif dp->Red = pePtr->peRed; dp->Green = pePtr->peGreen; dp->Blue = pePtr->peBlue; dp->Alpha = 0xFF; } GlobalFree(logPalPtr); } else { Blt_Pixel *dp, *dend; double rScale, gScale, bScale; double igamma; int i; int nRed, nGreen, nBlue; /* * Calculate the RGB coordinates of the colors we want to allocate and * store them in *colors. */ igamma = 1.0 / (double)p->gamma; nRed = nGreen = 8, nBlue = 4; rScale = 255.0 / (nRed - 1); gScale = 255.0 / (nGreen - 1); bScale = 255.0 / (nBlue - 1); for (i = 0, dp = colors, dend = dp + 256; dp < dend; dp++, i++) { int r, g, b; r = (int)(i * rScale + 0.5); g = (int)(i * gScale + 0.5); b = (int)(i * bScale + 0.5); r = p->igammaTable[r]; g = p->igammaTable[g]; b = p->igammaTable[b]; dp->Red = (r << 8) + r; dp->Green = (g << 8) + g; dp->Blue = (b << 8) + b; dp->Alpha = 0xFF; } } ReleaseDC(NULL, hDC); } /* *--------------------------------------------------------------------------- * * ComputeGammaTables -- * * Initializes both the power and inverse power tables for the painter * with a given gamma value. These tables are used to/from map linear * RGB values to/from non-linear monitor intensities. * * Results: * The *gammaTable* and *igammaTable* arrays are filled out to contain * the mapped values. * *--------------------------------------------------------------------------- */ static void ComputeGammaTables(Painter *p) { int i; double igamma, gamma; gamma = (double)p->gamma; igamma = 1.0 / gamma; for (i = 0; i < 256; i++) { double value, y; y = i / 255.0; value = pow(y, gamma) * 255.0 + 0.5; p->gammaTable[i] = (unsigned char)CLAMP(value); value = pow(y, igamma) * 255.0 + 0.5; p->igammaTable[i] = (unsigned char)CLAMP(value); } } /* *--------------------------------------------------------------------------- * * NewPainter -- * * Creates a new painter to be used to paint pictures. Painters are keyed * by the combination of display, colormap, visual, depth, and gamma * value used. * * Results: * A pointer to the new painter is returned. * * Side Effects: * A color ramp is allocated (not true for TrueColor visuals). Gamma * tables are computed and filled. * *--------------------------------------------------------------------------- */ static Painter * NewPainter(PainterKey *keyPtr) { Painter *p; p = Blt_AssertCalloc(1, sizeof(Painter)); p->colormap = keyPtr->colormap; p->depth = keyPtr->depth; p->display = keyPtr->display; p->gamma = keyPtr->gamma; p->refCount = 0; ComputeGammaTables(p); return p; } /* *--------------------------------------------------------------------------- * * FreePainter -- * * Called when the TCL interpreter is idle, this routine frees the * painter. Painters are reference counted. Only when no clients are using * the painter (the count is zero) is the painter actually freed. By * deferring its deletion, this allows client code to call Blt_GetPainter * after Blt_FreePainter without incurring a performance penalty. * *--------------------------------------------------------------------------- */ static void FreePainter(DestroyData data) { Painter *p = (Painter *)data; if (p->refCount <= 0) { Blt_DeleteHashEntry(&painterTable, p->hashPtr); if (p->gc != NULL) { if (p->flags & GC_PRIVATE) { XFreeGC(p->display, p->gc); } else { Tk_FreeGC(p->display, p->gc); } p->gc = NULL; } Blt_Free(p); } } /* *--------------------------------------------------------------------------- * * GetPainter -- * * Attempts to retrieve a painter for a particular combination of * display, colormap, visual, depth, and gamma value. If no specific * painter exists, then one is created. * * Results: * A pointer to the new painter is returned. * * Side Effects: * If no current painter exists, a new painter is added to the hash table * of painters. Otherwise, the current painter's reference count is * incremented indicated how many clients are using the painter. * *--------------------------------------------------------------------------- */ static Painter * GetPainter(Display *display, Colormap colormap, int depth, float gamma) { Painter *p; PainterKey key; int isNew; Blt_HashEntry *hPtr; if (!initialized) { Blt_InitHashTable(&painterTable, sizeof(PainterKey) / sizeof(int)); initialized = TRUE; } key.display = display; key.colormap = colormap; key.depth = depth; key.gamma = gamma; hPtr = Blt_CreateHashEntry(&painterTable, (char *)&key, &isNew); if (isNew) { p = NewPainter(&key); p->hashPtr = hPtr; Blt_SetHashValue(hPtr, p); } else { p = Blt_GetHashValue(hPtr); } p->refCount++; return p; } /* *--------------------------------------------------------------------------- * * DrawableToPicture -- * * Takes a snapshot of a DC and converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, NULL is * returned. * *--------------------------------------------------------------------------- */ static Blt_Picture DrawableToPicture( Painter *painterPtr, Drawable drawable, int x, int y, int width, int height) /* Dimension of the drawable. */ { BITMAPINFO bmi; DIBSECTION ds; HBITMAP hBitmap, oldBitmap; HDC hDC; HDC memDC; Pict *destPtr; TkWinDCState state; void *data; hDC = TkWinGetDrawableDC(painterPtr->display, drawable, &state); /* Create the intermediate drawing surface at window resolution. */ ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; hBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, &data, NULL, 0); memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, hBitmap); if (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE) { TkWinColormap *cmap; cmap = (TkWinColormap *)painterPtr->colormap; SelectPalette(hDC, cmap->palette, FALSE); RealizePalette(hDC); SelectPalette(memDC, cmap->palette, FALSE); RealizePalette(memDC); } destPtr = NULL; /* Copy the window contents to the memory surface. */ if (!BitBlt(memDC, 0, 0, width, height, hDC, x, y, SRCCOPY)) { #ifdef notdef PurifyPrintf("can't blit: %s\n", Blt_LastError()); #endif goto done; } if (GetObject(hBitmap, sizeof(DIBSECTION), &ds) == 0) { #ifdef notdef PurifyPrintf("can't get object: %s\n", Blt_LastError()); #endif } else { Blt_Pixel *destRowPtr; unsigned char *bits, *sp; bits = (unsigned char *)ds.dsBm.bmBits; destPtr = Blt_CreatePicture(width, height); destRowPtr = destPtr->bits; /* * Copy the DIB RGB data into the picture. The DIB origin is the * bottom-left corner, so the scanlines are stored in reverse order * from that of a picture. */ destRowPtr = destPtr->bits + ((height - 1) * destPtr->pixelsPerRow); sp = bits; for (y = 0; y < height; y++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + width; dp < dend; dp++) { dp->Blue = painterPtr->gammaTable[sp[0]]; dp->Green = painterPtr->gammaTable[sp[1]]; dp->Red = painterPtr->gammaTable[sp[2]]; dp->Alpha = ALPHA_OPAQUE; sp += 4; } destRowPtr -= destPtr->pixelsPerRow; } } done: DeleteBitmap(hBitmap); DeleteDC(memDC); TkWinReleaseDrawableDC(drawable, hDC, &state); return destPtr; } /* *--------------------------------------------------------------------------- * * PaintPicture -- * * Paints the picture to the given drawable. The region of the picture is * specified and the coordinates where in the destination drawable is the * image to be displayed. * * The image may be dithered depending upon the bit set in the flags * parameter: 0 no dithering, 1 for dithering. * * Results: * Returns TRUE is the picture was successfully display, Otherwise FALSE * is returned if the particular combination visual and image depth is * not handled. * *--------------------------------------------------------------------------- */ static int PaintPicture( Painter *painterPtr, Drawable drawable, Pict *srcPtr, int x, int y, /* Coordinates of region in the picture. */ int w, int h, /* Dimension of the region. Area cannot * extend beyond the end of the picture. */ int dx, int dy, /* Coordinates of region in the drawable. */ unsigned int flags) { HDC hDC, memDC; Pict *ditherPtr; TkWinDCState state; ditherPtr = NULL; hDC = TkWinGetDrawableDC(painterPtr->display, drawable, &state); memDC = CreateCompatibleDC(hDC); if (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE) { TkWinColormap *cmap; cmap = (TkWinColormap *)painterPtr->colormap; SelectPalette(hDC, cmap->palette, FALSE); RealizePalette(hDC); } if (flags & BLT_PAINTER_DITHER) { Blt_Pixel colors[256]; GetPaletteColors(hDC, painterPtr, colors); ditherPtr = Blt_DitherPicture(srcPtr, colors); if (ditherPtr != NULL) { srcPtr = ditherPtr; } } assert((x + w) <= srcPtr->width); assert((y + h) <= srcPtr->height); { BITMAPINFO bmi; Blt_Pixel *srcRowPtr; int sy; unsigned char *dp, *bits; bits = Blt_AssertMalloc(w * h * sizeof(Blt_Pixel)); /* * Copy the DIB RGB data into the picture. The DIB scanlines are * stored bottom-to-top and the order of the color components is BGRA. */ srcRowPtr = srcPtr->bits + ((y + h - 1) * srcPtr->pixelsPerRow) + x; dp = bits; for (sy = 0; sy < h; sy++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + w; sp < send; sp++) { dp[0] = sp->Blue; dp[1] = sp->Green; dp[2] = sp->Red; dp[3] = ALPHA_OPAQUE; dp += 4; } srcRowPtr -= srcPtr->pixelsPerRow; } /* Create the intermediate drawing surface at window resolution. */ ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; SetDIBitsToDevice(hDC, dx, dy, w, h, 0, 0, 0, h, bits, &bmi, DIB_RGB_COLORS); Blt_Free(bits); } TkWinReleaseDrawableDC(drawable, hDC, &state); if (ditherPtr != NULL) { Blt_FreePicture(ditherPtr); } return TRUE; } /* *--------------------------------------------------------------------------- * * PaintPictureWithBlend -- * * Blends and paints the picture in the given drawable. The region of the * picture is specified and the coordinates where in the destination * drawable is the image to be displayed. * * The background is snapped from the drawable and converted into a * picture. This picture is then blended with the current picture (the * background always assumed to be 100% opaque). * * Results: * Returns TRUE is the picture was successfully display, Otherwise FALSE * is returned. This may happen if the background can not be obtained * from the drawable. * *--------------------------------------------------------------------------- */ static int PaintPictureWithBlend( Painter *p, Drawable drawable, Blt_Picture fg, int x, int y, /* Coordinates of source region in the * picture. */ int w, int h, /* Dimension of the source region. Region * cannot extend beyond the end of the * picture. */ int dx, int dy, /* Coordinates of destination region in the * drawable. */ unsigned int flags, int alpha) { Blt_Picture bg; #ifdef notdef fprintf(stderr, "PaintPictureWithBlend: x=%d,y=%d,w=%d,h=%d,dx=%d,dy=%d\n", x, y, w, h, dx, dy); #endif if (dx < 0) { w += dx; x -= dx; dx = 0; } if (dy < 0) { h += dy; y -= dy; dy = 0; } if (dx < 0) { dx = 0; } if (dy < 0) { dy = 0; } if ((w < 0) || (h < 0)) { return FALSE; } bg = DrawableToPicture(p, drawable, dx, dy, w, h); if (bg == NULL) { return FALSE; } Blt_BlendPictures(bg, fg, x, y, w, h, 0, 0); PaintPicture(p, drawable, bg, 0, 0, w, h, dx, dy, flags); Blt_FreePicture(bg); return TRUE; } /* *--------------------------------------------------------------------------- * * Blt_GetPainterFromDrawable -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information is retrieved from * the drawable which is assumed to be a window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainterFromDrawable(Display *display, Drawable drawable, float gamma) { XGCValues gcValues; unsigned long gcMask; Painter *p; TkWinBitmap *bmPtr; bmPtr = (TkWinBitmap *)drawable; assert(bmPtr->type != TWD_BITMAP); p = GetPainter(display, bmPtr->colormap, bmPtr->depth, gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = XCreateGC(display, drawable, gcMask, &gcValues); p->flags |= GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_GetPainter -- * * Gets a painter for a particular combination of display, colormap, * visual, depth, and gamma value. This information (except for the * monitor's gamma value) is retrieved from the given Tk window. * * Results: * A pointer to the new painter is returned. * *--------------------------------------------------------------------------- */ Painter * Blt_GetPainter(Tk_Window tkwin, float gamma) { Painter *p; XGCValues gcValues; unsigned long gcMask; p = GetPainter(Tk_Display(tkwin), Tk_Colormap(tkwin), Tk_Depth(tkwin), gamma); /* * Make a GC with background = black and foreground = white. */ gcMask = GCGraphicsExposures; gcValues.graphics_exposures = False; p->gc = Tk_GetGC(tkwin, gcMask, &gcValues); p->flags &= ~GC_PRIVATE; return p; } /* *--------------------------------------------------------------------------- * * Blt_FreePainter -- * * Frees the painter. Painters are reference counted. Only when no * clients are using the painter (the count is zero) is the painter * actually freed. * *--------------------------------------------------------------------------- */ void Blt_FreePainter(Painter *p) { p->refCount--; if (p->refCount <= 0) { Tcl_EventuallyFree(p, FreePainter); } } GC Blt_PainterGC(Painter *p) { return p->gc; } int Blt_PainterDepth(Painter *p) { return p->depth; } /* *--------------------------------------------------------------------------- * * Blt_WindowToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * This routine is used to snap foreign (non-Tk) windows. For * pixmaps and Tk windows, Blt_DrawableToPicture is preferred. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_WindowToPicture( Display *display, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ float gamma) { Blt_Painter painter; Blt_Picture dump; /* Picture containing dump of window. */ painter = Blt_GetPainterFromDrawable(display, drawable, gamma); dump = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return dump; } /* *--------------------------------------------------------------------------- * * Blt_DrawableToPicture -- * * Takes a snapshot of an X drawable (pixmap or window) and * converts it to a picture. * * Results: * Returns a picture of the drawable. If an error occurred, * NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Picture Blt_DrawableToPicture( Tk_Window tkwin, Drawable drawable, int x, int y, /* Offset of image from the drawable's * origin. */ int width, int height, /* Dimension of the image. Image must * be completely contained by the * drawable. */ float gamma) { Blt_Painter painter; Blt_Picture dump; /* Picture containing dump of drawable. */ painter = Blt_GetPainter(tkwin, gamma); dump = DrawableToPicture(painter, drawable, x, y, width, height); Blt_FreePainter(painter); return dump; } int Blt_PaintPicture( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int ax, int ay, /* Starting coordinates of subregion in the * picture to be painted. */ int aw, int ah, /* Dimension of the subregion. */ int x, int y, /* Coordinates of region in the drawable. */ unsigned int flags) { /* * Nothing to draw. The region offset starts beyond the end of the * picture. * * +---------------+ * | | * | | * | | ax,ay * | | +---------+ * | | | | * +---------------+ | | * | | * +---------+ */ if ((picture == NULL) || (ax >= Blt_PictureWidth(picture)) || (ay >= Blt_PictureHeight(picture))) { return TRUE; } /* * Correct the dimensions if the origin starts before the picture * (i.e. coordinate is negative). Reset the coordinate the 0. * * ax,ay * +---------+ ax,ay * | +------|--------+ +------+--------+ * | | | | | | | * | | | | | | | * +--|------+ | +------+ | * | | | | * | | | | * +---------------+ +---------------+ * */ if (ax < 0) { aw += ax; ax = 0; } if (ay < 0) { ah += ay; ay = 0; } /* * Check that the given area does not extend beyond the end of the * picture. * * +-----------------+ +-----------------+ * | | | | * | ax,ay | | ax,ay | * | +---------+ | +-------+ * | | | | | | | * | | | | | | | * +---------|-------+ | +---------+-------+ * +---------+ * * Clip the end of the area if it's too big. */ if ((aw + ax) > Blt_PictureWidth(picture)) { aw = Blt_PictureWidth(picture) - ax; } if ((ah + ay) > Blt_PictureHeight(picture)) { ah = Blt_PictureHeight(picture) - ay; } /* Check that there's still something to paint. */ if ((aw <= 0) || (ah <= 0)) { return TRUE; } #ifdef notdef if (x < 0) { x = 0; } if (y < 0) { y = 0; } #endif if (Blt_PictureIsOpaque(picture)) { return PaintPicture(painter, drawable, picture, ax, ay, aw, ah, x, y, flags); } else { int alpha = 128; return PaintPictureWithBlend(painter, drawable, picture, ax, ay, aw, ah, x, y, flags, alpha); } } int Blt_PaintPictureWithBlend( Blt_Painter painter, Drawable drawable, Blt_Picture picture, int x, int y, /* Coordinates of region in the picture. */ int w, int h, /* Dimension of the region. Area cannot * extend beyond the end of the picture. */ int dx, int dy, /* Coordinates of region in the drawable. */ unsigned int flags, /* Indicates whether to dither the picture * before displaying. */ double falpha) { int alpha; alpha = (int)(falpha * 255.0 + 0.5); /* * Nothing to draw. The selected region is outside of the picture. * * 0,0 * +---------+ * | | * | Picture | * | | * +---------+ * x,y * +-------+ * | | * | | h * +-------+ * w */ if ((picture == NULL) || (x >= Blt_PictureWidth(picture)) || (y >= Blt_PictureHeight(picture)) || ((x + w) <= 0) || ((y + h) <= 0)) { return TRUE; } /* * Correct the dimensions if the origin starts before the picture * (i.e. coordinate is negative). Reset the coordinate the 0. * * x,y * +---------+ x,y = 0,0 * | +------|--------+ +------+--------+ * h | |0,0 | | | | | * | | | | | | | * +--|------+ | +------+ | * w | | | | * | | | | * +---------------+ +---------------+ * */ if (x < 0) { w += x; x = 0; } if (y < 0) { h += y; y = 0; } /* * Check that the given area does not extend beyond the end of the * picture. * * 0,0 0,0 * +-----------------+ +-----------------+ * | | | | * | x,y | | x,y | * | +---------+ | +-------+ * | | | | | | | * | | | | w | | | * +---------|-------+ | +---------+-------+ * +---------+ * h * * Clip the end of the area if it's too big. */ if ((x + w) > Blt_PictureWidth(picture)) { w = Blt_PictureWidth(picture) - x; } if ((y + h) > Blt_PictureHeight(picture)) { h = Blt_PictureHeight(picture) - y; } if (dx < 0) { dx = 0; } if (dy < 0) { dy = 0; } /* Check that there's still something to paint. */ if ((w <= 0) || (h <= 0)) { return TRUE; } return PaintPictureWithBlend(painter, drawable, picture, x, y, w, h, dx, dy, flags, alpha); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/blt.h�������������������������������������������������������������������������0000644�0001750�0001750�00000003162�11462120062�013761� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * blt.h -- * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BLT_H #define _BLT_H #define BLT_MAJOR_VERSION 3 #define BLT_MINOR_VERSION 0 #define BLT_VERSION "3.0" #define BLT_PATCH_LEVEL "3.0a" #define BLT_RELEASE_SERIAL 0 #define BLT_STORAGE_CLASS #ifdef __cplusplus # define BLT_EXTERN BLT_STORAGE_CLASS extern "C" #else # define BLT_EXTERN BLT_STORAGE_CLASS extern #endif /* __cplusplus */ #define _VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #ifndef _ANSI_ARGS_ # define _ANSI_ARGS_(x) () #endif #endif /*_BLT_H*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixDnd.c������������������������������������������������������������������0000644�0001750�0001750�00000453424�11462120063�015261� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixDnd.c -- * * This module implements a drag-and-drop manager for the BLT Toolkit. * Allows widgets to be registered as drag&drop sources and targets * for handling "drag-and-drop" operations between Tcl/Tk * applications. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_DRAGDROP #include "bltOp.h" #include <bltHash.h> #include <bltChain.h> #include <X11/Xatom.h> #include <X11/Xproto.h> #define DND_THREAD_KEY "BLT Dnd Data" #define DND_SELECTED (1<<0) #define DND_INITIATED (1<<1) #define DND_ACTIVE (DND_SELECTED | DND_INITIATED) #define DND_IN_PACKAGE (1<<2) /* Indicates if a token package command is * currently active. The user may invoke * "update" or "tkwait" commands from within * the package command script. This allows the * "drag" operation to preempt itself. */ #define DND_VOIDED (1<<3) #define DND_DELETED (1<<4) #define PACK(lo,hi) (((hi) << 16) | ((lo) & 0x0000FFFF)) #define UNPACK(x,lo,hi) ((lo) = (x & 0x0000FFFF), (hi) = (x >> 16)) #define WATCH_ENTER (1<<0) #define WATCH_LEAVE (1<<1) #define WATCH_MOTION (1<<2) #define WATCH_MASK (WATCH_ENTER | WATCH_LEAVE | WATCH_MOTION) /* Source-to-Target Message Types */ #define ST_DRAG_ENTER 0x1001 #define ST_DRAG_LEAVE 0x1002 #define ST_DRAG_MOTION 0x1003 #define ST_DROP 0x1004 /* Target-to-Source Message Types */ #define TS_DRAG_STATUS 0x1005 #define TS_START_DROP 0x1006 #define TS_DROP_RESULT 0x1007 /* Indices of information fields in ClientMessage array. */ #define MESG_TYPE 0 /* Message type. */ #define MESG_WINDOW 1 /* Window id of remote. */ #define MESG_TIMESTAMP 2 /* Transaction timestamp. */ #define MESG_POINT 3 /* Root X-Y coordinate. */ #define MESG_STATE 4 /* Button and key state. */ #define MESG_RESPONSE 3 /* Response to drag/drop message. */ #define MESG_FORMAT 3 /* Format atom. */ #define MESG_PROPERTY 4 /* Index of button #/key state. */ /* Drop Status Values (actions included) */ #define DROP_CONTINUE -2 #define DROP_FAIL -1 #define DROP_CANCEL 0 #define DROP_OK 1 #define DROP_COPY 1 #define DROP_LINK 2 #define DROP_MOVE 3 #define PROP_WATCH_FLAGS 0 #define PROP_DATA_FORMATS 1 #define PROP_MAX_SIZE 1000 /* Maximum size of property. */ #define PROTO_BLT 0 #define PROTO_XDND 1 #define TOKEN_OFFSET 0 #define TOKEN_REDRAW (1<<0) #define TOKEN_NORMAL 0 #define TOKEN_REJECT -1 #define TOKEN_ACTIVE 1 #define TOKEN_TIMEOUT 5000 /* 5 second timeout for drop requests. */ /* * Each widget representing a drag & drop target is tagged with * a "BltDndTarget" property in XA_STRING format. This property * identifies the window as a target. It's formated as a TCL list * and contains the following information: * * "flags DATA_TYPE DATA_TYPE ..." * * "INTERP_NAME TARGET_NAME WINDOW_ID DATA_TYPE DATA_TYPE ..." * * INTERP_NAME Name of the target application's interpreter. * TARGET_NAME Path name of widget registered as the drop target. * WINDOW_ID Window Id of the target's communication window. * Used to forward Enter/Leave/Motion event information * to the target. * DATA_TYPE One or more "types" handled by the target. * * When the user invokes the "drag" operation, the window hierarchy * is progressively examined. Window information is cached during * the operation, to minimize X server traffic. Windows carrying a * "BltDndTarget" property are identified. When the token is dropped * over a valid site, the drop information is sent to the application * via the usual "send" command. If communication fails, the drag&drop * facility automatically posts a rejection symbol on the token window. */ /* * Drop Protocol: * * Source Target * ------ ------ * ButtonRelease-? event. * Invokes blt::dnd drop * + * Send "drop" message to target (via * ClientMessage). Contains X-Y, key/ --> Gets "drop" message. * button state, source window XID. Invokes LeaveCmd proc. * Gets property from source of * ordered matching formats. * + * Invokes DropCmd proc. Arguments * are X-Y coordinate, key/button * state, transaction timestamp, * list of matching formats. * + * Target selects format and invokes * blt::dnd pull to transfer the data * in the selected format. * + * Sends "drop start" message to * source. Contains selected format * Gets "drop start" message. <-- (as atom), ?action?, target window * Invokes data handler for the ID, transaction timestamp. * selected format. + * + Waits for property to change on * Places first packet of data in its window. Time out set for * property on target window. --> no response. * + + * Waits for response property After each packet, sets zero-length * change. Time out set for no resp. <-- property on source window. * If non-zero length packet, error + * occurred, packet is error message. Sends "drop finished" message. * Contains transaction timestamp, * Gets "drop finished" message. <-- status, ?action?. * Invokes FinishCmd proc. */ /* Configuration Parameters */ #define DEF_DND_BUTTON_BACKGROUND RGB_YELLOW #define DEF_DND_BUTTON_BG_MONO STD_NORMAL_BG_MONO #define DEF_DND_BUTTON_NUMBER "3" #define DEF_DND_ENTER_COMMAND (char *)NULL #define DEF_DND_LEAVE_COMMAND (char *)NULL #define DEF_DND_MOTION_COMMAND (char *)NULL #define DEF_DND_DROP_COMMAND (char *)NULL #define DEF_DND_RESULT_COMMAND (char *)NULL #define DEF_DND_PACKAGE_COMMAND (char *)NULL #define DEF_DND_SELF_TARGET "no" #define DEF_DND_SEND (char *)NULL #define DEF_DND_IS_TARGET "no" #define DEF_DND_IS_SOURCE "no" #define DEF_DND_SITE_COMMAND (char *)NULL #define DEF_DND_DRAG_THRESHOLD "0" #define DEF_TOKEN_ACTIVE_BACKGROUND STD_ACTIVE_BACKGROUND #define DEF_TOKEN_ACTIVE_BG_MONO STD_ACTIVE_BG_MONO #define DEF_TOKEN_ACTIVE_BORDERWIDTH "3" #define DEF_TOKEN_ACTIVE_RELIEF "sunken" #define DEF_TOKEN_ANCHOR "se" #define DEF_TOKEN_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_TOKEN_BG_MONO STD_NORMAL_BG_MONO #define DEF_TOKEN_BORDERWIDTH "3" #define DEF_TOKEN_CURSOR "top_left_arrow" #define DEF_TOKEN_REJECT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_TOKEN_REJECT_BG_MONO RGB_WHITE #define DEF_TOKEN_REJECT_FOREGROUND RGB_RED #define DEF_TOKEN_REJECT_FG_MONO RGB_BLACK #define DEF_TOKEN_REJECT_STIPPLE_COLOR (char *)NULL #define DEF_TOKEN_REJECT_STIPPLE_MONO RGB_GREY50 #define DEF_TOKEN_RELIEF "raised" static Blt_OptionFreeProc FreeCursors; static Blt_OptionParseProc ObjToCursors; static Blt_OptionPrintProc CursorsToObj; static Blt_CustomOption cursorsOption = { ObjToCursors, CursorsToObj, FreeCursors, (ClientData)0 }; typedef struct { Blt_HashTable dndTable; /* Hash table of dnd structures keyed by * the address of the reference Tk window */ Tk_Window tkMain; Display *display; Atom mesgAtom; /* Atom signifying a drag-and-drop message. */ Atom formatsAtom; /* Source formats property atom. */ Atom targetAtom; /* Target property atom. */ Atom commAtom; /* Communication property atom. */ #ifdef HAVE_XDND Blt_HashTable handlerTable; /* Table of toplevel windows with XdndAware * properties attached to them. */ Atom XdndActionListAtom; Atom XdndAwareAtom; Atom XdndEnterAtom; Atom XdndFinishedAtom; Atom XdndLeaveAtom; Atom XdndPositionAtom; Atom XdndSelectionAtom; Atom XdndStatusAtom; Atom XdndTypeListAtom; Atom XdndActionCopyAtom; Atom XdndActionMoveAtom; Atom XdndActionLinkAtom; Atom XdndActionAskAtom; Atom XdndActionPrivateAtom; Atom XdndActionDescriptionAtom; #endif } DndInterpData; typedef struct { Tcl_DString dString; Window window; /* Source/Target window */ Display *display; Atom commAtom; /* Data communication property atom. */ int packetSize; Tcl_TimerToken timerToken; int status; /* Status of transaction: CONTINUE, OK, FAIL, * or TIMEOUT. */ int timestamp; /* Timestamp of the transaction. */ int offset; int protocol; /* Drag-and-drop protocol used by the source: * either PROTO_BLT or PROTO_XDND. */ } DropPending; /* * SubstDescriptors -- * * Structure to hold letter-value pairs for percent substitutions. */ typedef struct { char letter; /* character like 'x' in "%x" */ const char *value; /* value to be substituted in place of "%x" */ } SubstDescriptors; /* * Drag&Drop Registration Data */ typedef struct { Tk_Window tkwin; /* Window that embodies the token. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up. */ Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tk_3DBorder border; /* Structure used to draw 3-D border and * background. NULL means no background * or border. */ int borderWidth; /* Width of 3-D border (if any). */ int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ int flags; /* Various flags; see below for * definitions. */ /* Token specific fields */ int x, y; /* Last position of token window */ int startX, startY; int status; /* Indicates the current status of the token: * 0 is normal, 1 is active. */ int lastStatus; /* Indicates the last status of the token. */ Tcl_TimerToken timerToken; /* Token for routine to hide tokenwin */ GC fillGC; /* GC used to draw rejection fg: (\) */ GC outlineGC; /* GC used to draw rejection bg: (\) */ int width, height; /* User-configurable fields */ Tk_Anchor anchor; /* Position of token win relative to mouse */ Tk_3DBorder normalBorder; /* Border/background for token window */ Tk_3DBorder activeBorder; /* Border/background for token window */ int activeRelief; int activeBW; /* Border width in pixels */ XColor *fillColor; /* Color used to draw rejection fg: (\) */ XColor *outlineColor; /* Color used to draw rejection bg: (\) */ Pixmap rejectStipple; /* Stipple used to draw rejection: (\) */ int reqWidth, reqHeight; int nSteps; } Token; /* * Winfo -- * * This structure represents a window hierarchy examined during a single * "drag" operation. It's used to cache information to reduce the round * trip calls to the server needed to query window geometry information * and grab the target property. */ typedef struct _Winfo { Window window; /* Window in hierarchy. */ int initialized; /* If zero, the rest of this structure's * information hasn't been set. */ int x1, y1, x2, y2; /* Extents of the window (upper-left and * lower-right corners). */ struct _Winfo *parentPtr; /* Parent node. NULL if root. Used to * compute offset for X11 windows. */ Blt_Chain chain; /* List of this window's children. If NULL, * there are no children. */ int isTarget; /* Indicates if this window is a drag&drop * target. */ int lookedForProperty; /* Indicates if this window */ int eventFlags; /* Retrieved from the target's drag&drop * property, indicates what kinds of pointer * events should be relayed to the target via * ClientMessages. Possible values are OR-ed * combinations of the following bits: * 001 Enter events. * 010 Motion events. * 100 Leave events. */ const char *matches; } Winfo; /* * Dnd -- * * This structure represents the drag&drop manager. It is associated * with a widget as a drag&drop source, target, or both. It contains * both the source and target components, since a widget can be both * a drag source and a drop target. */ typedef struct { Tcl_Interp *interp; /* Interpreter associated with the drag&drop * manager. */ Tk_Window tkwin; /* Tk window representing the drag&drop * manager (can be source and/or target). */ Display *display; /* Display for drag&drop widget. Saved to free * resources after window has been destroyed. */ int isSource; /* Indicates if this drag&drop manager can act * as a drag source. */ int isTarget; /* Indicates if this drag&drop manager can act * as a drop target. */ int targetPropertyExists; /* Indicates is the drop target property has * been set. */ unsigned int flags; /* Various flags; see below for * definitions. */ int timestamp; /* Id of the current drag&drop transaction. */ int x, y; /* Last known location of the mouse pointer. */ Blt_HashEntry *hashPtr; DndInterpData *dataPtr; /* Source component. */ Blt_HashTable getDataTable; /* Table of data handlers (converters) * registered for this source. */ int reqButton; /* Button used to invoke drag operation. */ int button; /* Last button press detected. */ int keyState; /* Last key state. */ Tk_Cursor cursor; /* Cursor restored after dragging */ int selfTarget; /* Indicated if the source should drop onto * itself. */ const char **reqFormats; /* List of requested data formats. The * list should be ordered with the more * desireable formats first. You can also * temporarily turn off a source by setting * the value to the empty string. */ Winfo *rootPtr; /* Cached window information: Gathered * and used during the "drag" operation * to see if the mouse pointer is over a * valid target. */ Winfo *windowPtr; /* Points to information about the last * target the pointer was over. If NULL, * the pointer was not over a valid target. */ const char **packageCmd; /* TCL command executed at start of the drag * operation to initialize token. */ const char **resultCmd; /* TCL command executed at the end of the * "drop" operation to indicate its status. */ const char **siteCmd; /* TCL command executed to update token * window. */ Token *tokenPtr; /* Token used to provide special cursor. */ Tcl_TimerToken timerToken; Tk_Cursor *cursors; /* Array of drag-and-drop cursors. */ int cursorPos; int dragStart; /* Minimum number of pixels movement * before B1-Motion is considered to * start dragging. */ /* Target component. */ Blt_HashTable setDataTable; /* Table of data handlers (converters) * registered for this target. */ const char **enterCmd; /* TCL proc called when the mouse enters the * target. */ const char **leaveCmd; /* TCL proc called when the mouse leaves the * target. */ const char **motionCmd; /* TCL proc called when the mouse is moved * over the target. */ const char **dropCmd; /* TCL proc called when the mouse button * is released over the target. */ const char *matchingFormats; /* */ int lastId; /* The last transaction id used. This is used * to cache the above formats string. */ DropPending *pendingPtr; /* Points to structure containing information * about a current drop in progress. If NULL, * no drop is in progress. */ short int dropX, dropY; /* Location of the current drop. */ short int dragX, dragY; /* Starting position of token window */ } Dnd; typedef struct { Tk_Window tkwin; /* Toplevel window of the drop target. */ int refCount; /* # of targets referencing this structure. */ Dnd *dndPtr; /* Last drop target selected. Used the * implement Enter/Leave events for targets. * If NULL, indicates that no drop target was * previously selected. */ int lastRepsonse; /* Indicates what the last response was. */ Window window; /* Window id of the top-level window (ie. * the wrapper). */ const char **formatArr; /* List of formats available from source. * Must be pruned down to matching list. */ DndInterpData *dataPtr; int x, y; } XDndHandler; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_LIST, "-allowformats", "allowFormats", "AllowFormats", DEF_DND_SEND, Blt_Offset(Dnd, reqFormats), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_INT, "-button", "buttonNumber", "ButtonNumber", DEF_DND_BUTTON_NUMBER, Blt_Offset(Dnd, reqButton), 0}, {BLT_CONFIG_PIXELS_NNEG, "-dragthreshold", "dragThreshold", "DragThreshold", DEF_DND_DRAG_THRESHOLD, Blt_Offset(Dnd, dragStart), 0}, {BLT_CONFIG_CUSTOM, "-cursors", "cursors", "cursors", DEF_TOKEN_CURSOR, Blt_Offset(Dnd, cursors), BLT_CONFIG_NULL_OK, &cursorsOption }, {BLT_CONFIG_LIST, "-onenter", "onEnter", "OnEnter", DEF_DND_ENTER_COMMAND, Blt_Offset(Dnd, enterCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-onmotion", "onMotion", "OnMotion", DEF_DND_MOTION_COMMAND, Blt_Offset(Dnd, motionCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-onleave", "onLeave", "OnLeave", DEF_DND_LEAVE_COMMAND, Blt_Offset(Dnd, leaveCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-ondrop", "onDrop", "OnDrop", DEF_DND_DROP_COMMAND, Blt_Offset(Dnd, dropCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-package", "packageCommand", "PackageCommand", DEF_DND_PACKAGE_COMMAND, Blt_Offset(Dnd, packageCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_LIST, "-result", "result", "Result", DEF_DND_RESULT_COMMAND, Blt_Offset(Dnd, resultCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-selftarget", "selfTarget", "SelfTarget", DEF_DND_SELF_TARGET, Blt_Offset(Dnd, selfTarget), 0}, {BLT_CONFIG_LIST, "-site", "siteCommand", "Command", DEF_DND_SITE_COMMAND, Blt_Offset(Dnd, siteCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BOOLEAN, "-source", "source", "Source", DEF_DND_IS_SOURCE, Blt_Offset(Dnd, isSource), 0}, {BLT_CONFIG_BOOLEAN, "-target", "target", "Target", DEF_DND_IS_TARGET, Blt_Offset(Dnd, isTarget), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, }; static Blt_ConfigSpec tokenConfigSpecs[] = { {BLT_CONFIG_BORDER, "-activebackground", "activeBackground", "ActiveBackground", DEF_TOKEN_ACTIVE_BACKGROUND, Blt_Offset(Token, activeBorder), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BORDER, "-activebackground", "activeBackground", "ActiveBackground", DEF_TOKEN_ACTIVE_BG_MONO, Blt_Offset(Token, activeBorder), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_RELIEF, "-activerelief", "activeRelief", "activeRelief", DEF_TOKEN_ACTIVE_RELIEF, Blt_Offset(Token, activeRelief), 0}, {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", DEF_TOKEN_ANCHOR, Blt_Offset(Token, anchor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-activeborderwidth", "activeBorderWidth", "ActiveBorderWidth", DEF_TOKEN_ACTIVE_BORDERWIDTH, Blt_Offset(Token, activeBW), 0}, {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_TOKEN_BACKGROUND, Blt_Offset(Token, normalBorder), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_TOKEN_BG_MONO, Blt_Offset(Token, normalBorder), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_TOKEN_BORDERWIDTH, Blt_Offset(Token, borderWidth), 0}, {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", DEF_TOKEN_REJECT_BACKGROUND, Blt_Offset(Token, outlineColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", DEF_TOKEN_REJECT_BG_MONO, Blt_Offset(Token, outlineColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", DEF_TOKEN_REJECT_FOREGROUND, Blt_Offset(Token, fillColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", DEF_TOKEN_REJECT_BACKGROUND, Blt_Offset(Token, fillColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_BITMAP, "-rejectstipple", "rejectStipple", "Stipple", DEF_TOKEN_REJECT_STIPPLE_COLOR, Blt_Offset(Token, rejectStipple), BLT_CONFIG_COLOR_ONLY | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMAP, "-rejectstipple", "rejectStipple", "Stipple", DEF_TOKEN_REJECT_STIPPLE_MONO, Blt_Offset(Token, rejectStipple), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_TOKEN_RELIEF, Blt_Offset(Token, relief), 0}, {BLT_CONFIG_INT, "-width", "width", "Width", (char *)NULL, Blt_Offset(Token, reqWidth), 0}, {BLT_CONFIG_INT, "-height", "height", "Height", (char *)NULL, Blt_Offset(Token, reqHeight), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0}, }; /* * Forward Declarations */ static Tcl_ObjCmdProc DndCmd; static Tcl_FreeProc DestroyDnd; static Tk_GenericProc DndEventProc; static Tk_EventProc TokenEventProc; static Tcl_IdleProc DisplayToken; static Winfo *InitRoot (Dnd *dndPtr); static Winfo *OverTarget (Dnd *dndPtr); static int ConfigureToken (Tcl_Interp *interp, Dnd *dndPtr, int objc, Tcl_Obj *const *objv, int flags); static int GetDndFromObj (ClientData clientData, Tcl_Interp *interp, Tcl_Obj *objPtr, Dnd **dndPtrPtr); static void AddTargetProperty (Dnd *dndPtr); static void CancelDrag (Dnd *dndPtr); static void DrawRejectSymbol (Dnd *dndPtr); static void FreeWinfo (Winfo *wr); static void GetWinfo (Display *display, Winfo * windowPtr); static void HideToken (Dnd *dndPtr); static void MoveToken (Dnd *dndPtr); static Dnd *CreateDnd (Tcl_Interp *interp, Tk_Window tkwin); /*ARGSUSED*/ static void FreeCursors( ClientData clientData, /* Not used. */ Display *display, char *widgRec, int offset) { Tk_Cursor **cursorsPtr = (Tk_Cursor **)(widgRec + offset); if (*cursorsPtr != NULL) { Tk_Cursor *cp; for (cp = *cursorsPtr; *cp != None; cp++) { Tk_FreeCursor(display, *cp); } Blt_Free(*cursorsPtr); *cursorsPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToCursors -- * * Converts the resize mode into its numeric representation. Valid * mode strings are "none", "expand", "shrink", or "both". * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToCursors( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing cursors. */ char *widgRec, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 0) { Tk_Cursor **cursorsPtr = (Tk_Cursor **)(widgRec + offset); Tk_Cursor *cursors; int i; cursors = Blt_AssertCalloc(objc + 1, sizeof(Tk_Cursor)); for (i = 0; i < objc; i++) { cursors[i] = Tk_AllocCursorFromObj(interp, tkwin, objv[i]); if (cursors[i] == None) { Tk_Cursor *cp; for (cp = cursors; *cp != None; cp++) { Tk_FreeCursor(Tk_Display(tkwin), *cp); } return TCL_ERROR; } } *cursorsPtr = cursors; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * CursorsToObj -- * * Returns resize mode string based upon the resize flags. * * Results: * The resize mode string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * CursorsToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Cursor record */ int offset, /* Offset to field in structure */ int flags) { Tk_Cursor *cursors = *(Tk_Cursor **)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (cursors != NULL) { Tcl_Obj *objPtr; Tk_Cursor *cp; for (cp = cursors; *cp != NULL; cp++) { objPtr = Tcl_NewStringObj(Tk_NameOfCursor(Tk_Display(tkwin), *cp), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } static Tcl_Obj * PrintList(Tcl_Interp *interp, const char **list) { Tcl_Obj *listObjPtr; const char **p; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for(p = list; *p != NULL; p++) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(*p, -1)); } return listObjPtr; } /* ARGSUSED */ static int XSendEventErrorProc( ClientData clientData, XErrorEvent *errEventPtr) { int *errorPtr = clientData; *errorPtr = TCL_ERROR; return 0; } static void SendClientMsg( Display *display, Window window, Atom mesgAtom, int data0, int data1, int data2, int data3, int data4) { XEvent event; Tk_ErrorHandler handler; int result; int any = -1; event.xclient.type = ClientMessage; event.xclient.serial = 0; event.xclient.send_event = True; event.xclient.display = display; event.xclient.window = window; event.xclient.message_type = mesgAtom; event.xclient.format = 32; event.xclient.data.l[0] = data0; event.xclient.data.l[1] = data1; event.xclient.data.l[2] = data2; event.xclient.data.l[3] = data3; event.xclient.data.l[4] = data4; result = TCL_OK; handler = Tk_CreateErrorHandler(display, any, X_SendEvent, any, XSendEventErrorProc, &result); if (!XSendEvent(display, window, False, ClientMessage, &event)) { result = TCL_ERROR; } Tk_DeleteErrorHandler(handler); XSync(display, False); if (result != TCL_OK) { fprintf(stderr, "XSendEvent response to drop: Protocol failed\n"); } } /* *--------------------------------------------------------------------------- * * GetWindowZOrder -- * * Returns a chain of the child windows according to their stacking * order. The window ids are ordered from top to bottom. * * ------------------------------------------------------------------------ */ static Blt_Chain GetWindowZOrder(Display *display, Window window) { Blt_Chain chain; Window *winv; unsigned int winc; Window dummy; chain = NULL; if ((XQueryTree(display, window, &dummy, &dummy, &winv, &winc)) && (winc > 0)) { unsigned int i; chain = Blt_Chain_Create(); for (i = 0; i < winc; i++) { /* * XQuery returns windows in bottom to top order. We only care * about the top window. */ Blt_Chain_Prepend(chain, (ClientData)winv[i]); } if (winv != NULL) { XFree((char *)winv); /* done with list of kids */ } } return chain; } static int GetMaxPropertySize(Display *display) { int size; size = Blt_MaxRequestSize(display, sizeof(char)); size -= 32; return size; } /* *--------------------------------------------------------------------------- * * GetProperty -- * * Returns the data associated with the named property on the * given window. All data is assumed to be 8-bit string data. * * ------------------------------------------------------------------------ */ static unsigned char * GetProperty(Display *display, Window window, Atom atom) { unsigned char *data; int result, format; Atom typeAtom; unsigned long nItems, bytesAfter; if (window == None) { return NULL; } data = NULL; result = XGetWindowProperty( display, /* Display of window. */ window, /* Window holding the property. */ atom, /* Name of property. */ 0, /* Offset of data (for multiple reads). */ GetMaxPropertySize(display), /* Maximum number of items to read. */ False, /* If true, delete the property. */ XA_STRING, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the property. */ &nItems, /* (out) # of items in specified format. */ &bytesAfter, /* (out) # of bytes remaining to be read. */ &data); if ((result != Success) || (format != 8) || (typeAtom != XA_STRING)) { if (data != NULL) { XFree((char *)data); data = NULL; } } return data; } /* *--------------------------------------------------------------------------- * * SetProperty -- * * Associates the given data with the a property on a given window. * All data is assumed to be 8-bit string data. * * ------------------------------------------------------------------------ */ static void SetProperty(Tk_Window tkwin, Atom atom, const char *data) { XChangeProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), atom, XA_STRING, 8, PropModeReplace, (unsigned char *)data, strlen(data) + 1); } /* *--------------------------------------------------------------------------- * * GetWindowArea -- * * Queries for the upper-left and lower-right corners of the * given window. * * Results: * Returns if the window is currently viewable. The coordinates * of the window are returned via parameters. * * ------------------------------------------------------------------------ */ static int GetWindowArea(Display *display, Winfo *windowPtr) { XWindowAttributes winAttrs; if (XGetWindowAttributes(display, windowPtr->window, &winAttrs)) { windowPtr->x1 = winAttrs.x; windowPtr->y1 = winAttrs.y; windowPtr->x2 = winAttrs.x + winAttrs.width - 1; windowPtr->y2 = winAttrs.y + winAttrs.height - 1; } return (winAttrs.map_state == IsViewable); } /* *--------------------------------------------------------------------------- * * FindTopWindow -- * * Searches for the topmost window at a given pair of X-Y coordinates. * * Results: * Returns a pointer to the node representing the window containing * the point. If one can't be found, NULL is returned. * *--------------------------------------------------------------------------- */ static Winfo * FindTopWindow(Dnd *dndPtr, int x, int y) { Winfo *rootPtr; Blt_ChainLink link; Winfo *windowPtr; rootPtr = dndPtr->rootPtr; if (!rootPtr->initialized) { GetWinfo(dndPtr->display, rootPtr); } if ((x < rootPtr->x1) || (x > rootPtr->x2) || (y < rootPtr->y1) || (y > rootPtr->y2)) { return NULL; /* Point is not over window */ } windowPtr = rootPtr; /* * The window list is ordered top to bottom, so stop when we find the * first child that contains the X-Y coordinate. It will be the topmost * window in that hierarchy. If none exists, then we already have the * topmost window. */ descend: for (link = Blt_Chain_FirstLink(rootPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { rootPtr = Blt_Chain_GetValue(link); if (!rootPtr->initialized) { GetWinfo(dndPtr->display, rootPtr); } if (rootPtr->window == Blt_GetWindowId(dndPtr->tokenPtr->tkwin)) { continue; /* Don't examine the token window. */ } if ((x >= rootPtr->x1) && (x <= rootPtr->x2) && (y >= rootPtr->y1) && (y <= rootPtr->y2)) { /* * Remember the last window containing the pointer and descend * into its window hierarchy. We'll look for a child that also * contains the pointer. */ windowPtr = rootPtr; goto descend; } } return windowPtr; } /* *--------------------------------------------------------------------------- * * GetWidgetCursor -- * * Queries a widget for its current cursor. The given window * may or may not be a Tk widget that has a -cursor option. * * Results: * Returns the current cursor of the widget. * * ------------------------------------------------------------------------ */ static Tk_Cursor GetWidgetCursor( Tcl_Interp *interp, /* Interpreter to evaluate widget command. */ Tk_Window tkwin) /* Window of drag&drop source. */ { Tk_Cursor cursor; Tcl_DString dString, savedResult; cursor = None; Tcl_DStringInit(&dString); Blt_DStringAppendElements(&dString, Tk_PathName(tkwin), "cget", "-cursor", (char *)NULL); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)) == TCL_OK) { const char *name; name = Tcl_GetStringResult(interp); if ((name != NULL) && (name[0] != '\0')) { cursor = Tk_GetCursor(interp, tkwin, Tk_GetUid(name)); } } Tcl_DStringResult(interp, &savedResult); Tcl_DStringFree(&dString); return cursor; } /* *--------------------------------------------------------------------------- * * NameOfStatus -- * * Converts a numeric drop result into its string representation. * * Results: * Returns a static string representing the drop result. * *--------------------------------------------------------------------------- */ static const char * NameOfStatus(int status) { switch (status) { case DROP_OK: return "active"; case DROP_CONTINUE: return "normal"; case DROP_FAIL: return "reject"; case DROP_CANCEL: return "cancel"; default: return "unknown status value"; } } /* *--------------------------------------------------------------------------- * * NameOfAction -- * * Converts a numeric drop result into its string representation. * * Results: * Returns a static string representing the drop result. * *--------------------------------------------------------------------------- */ static const char * NameOfAction(int action) { switch (action) { case DROP_COPY: return "copy"; case DROP_CANCEL: return "cancel"; case DROP_MOVE: return "move"; break; case DROP_LINK: return "link"; case DROP_FAIL: return "fail"; default: return "unknown action"; } } /* *--------------------------------------------------------------------------- * * GetAction -- * * Converts a string to its numeric drop result value. * * Results: * Returns the drop result. * *--------------------------------------------------------------------------- */ static int GetAction(const char *string) { char c; c = string[0]; if ((c == 'c') && (strcmp(string, "cancel") == 0)) { return DROP_CANCEL; } else if ((c == 'f') && (strcmp(string, "fail") == 0)) { return DROP_FAIL; } else if ((c == 'm') && (strcmp(string, "move") == 0)) { return DROP_MOVE; } else if ((c == 'l') && (strcmp(string, "link") == 0)) { return DROP_LINK; } else if ((c == 'c') && (strcmp(string, "copy") == 0)) { return DROP_COPY; } else { return DROP_COPY; } } /* *--------------------------------------------------------------------------- * * GetDragResult -- * * Converts a string to its numeric drag result value. * * Results: * Returns the drag result. * *--------------------------------------------------------------------------- */ static int GetDragResult(Tcl_Interp *interp, const char *string) { char c; int bool; c = string[0]; if ((c == 'c') && (strcmp(string, "cancel") == 0)) { return DROP_CANCEL; } else if (Tcl_GetBoolean(interp, string, &bool) != TCL_OK) { Tcl_BackgroundError(interp); return DROP_CANCEL; } return bool; } static void AnimateActiveCursor(ClientData clientData) { Dnd *dndPtr = clientData; Tk_Cursor cursor; dndPtr->cursorPos++; cursor = dndPtr->cursors[dndPtr->cursorPos]; if (cursor == None) { cursor = dndPtr->cursors[1]; dndPtr->cursorPos = 1; } Tk_DefineCursor(dndPtr->tkwin, cursor); dndPtr->timerToken = Tcl_CreateTimerHandler(100, AnimateActiveCursor, dndPtr); } static void StartActiveCursor(Dnd *dndPtr) { if (dndPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(dndPtr->timerToken); } if (dndPtr->cursors != NULL) { Tk_Cursor cursor; dndPtr->cursorPos = 1; cursor = dndPtr->cursors[1]; if (cursor != None) { Tk_DefineCursor(dndPtr->tkwin, cursor); dndPtr->timerToken = Tcl_CreateTimerHandler(125, AnimateActiveCursor, dndPtr); } } } static void StopActiveCursor(Dnd *dndPtr) { if (dndPtr->cursorPos > 0) { dndPtr->cursorPos = 0; } if (dndPtr->cursors != NULL) { Tk_DefineCursor(dndPtr->tkwin, dndPtr->cursors[0]); } if (dndPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(dndPtr->timerToken); dndPtr->timerToken = NULL; } } /* *--------------------------------------------------------------------------- * * EventuallyRedrawToken -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ static void EventuallyRedrawToken(Dnd *dndPtr) { Token *tokenPtr; if (dndPtr->tokenPtr == NULL) { return; } tokenPtr = dndPtr->tokenPtr; if ((tokenPtr->tkwin != NULL) && (tokenPtr->tkwin != NULL) && !(tokenPtr->flags & TOKEN_REDRAW)) { tokenPtr->flags |= TOKEN_REDRAW; Tcl_DoWhenIdle(DisplayToken, dndPtr); } } /* *--------------------------------------------------------------------------- * * RaiseToken -- * *--------------------------------------------------------------------------- */ static void RaiseToken(Dnd *dndPtr) { Token *tokenPtr = dndPtr->tokenPtr; if (dndPtr->flags & DND_INITIATED) { if ((Tk_Width(tokenPtr->tkwin) != Tk_ReqWidth(tokenPtr->tkwin)) || (Tk_Height(tokenPtr->tkwin) != Tk_ReqHeight(tokenPtr->tkwin))) { Blt_ResizeToplevelWindow(tokenPtr->tkwin, Tk_ReqWidth(tokenPtr->tkwin), Tk_ReqHeight(tokenPtr->tkwin)); } Blt_MapToplevelWindow(tokenPtr->tkwin); Blt_RaiseToplevelWindow(tokenPtr->tkwin); } } /* *--------------------------------------------------------------------------- * * DisplayToken -- * *--------------------------------------------------------------------------- */ static void DisplayToken(ClientData clientData) { Dnd *dndPtr = clientData; Token *tokenPtr = dndPtr->tokenPtr; int relief; Tk_3DBorder border; int borderWidth; tokenPtr->flags &= ~TOKEN_REDRAW; if (tokenPtr->status == DROP_OK) { relief = tokenPtr->activeRelief; border = tokenPtr->activeBorder; borderWidth = tokenPtr->activeBW; if ((dndPtr->cursors != NULL) && (dndPtr->cursorPos == 0)) { StartActiveCursor(dndPtr); } } else { relief = tokenPtr->relief; border = tokenPtr->normalBorder; borderWidth = tokenPtr->borderWidth; StopActiveCursor(dndPtr); } Blt_Fill3DRectangle(tokenPtr->tkwin, Tk_WindowId(tokenPtr->tkwin), border, 0, 0, Tk_Width(tokenPtr->tkwin), Tk_Height(tokenPtr->tkwin), borderWidth, relief); tokenPtr->lastStatus = tokenPtr->status; if (tokenPtr->status == DROP_FAIL) { DrawRejectSymbol(dndPtr); } } /* *--------------------------------------------------------------------------- * * FadeToken -- * * Fades the token into the target. * *--------------------------------------------------------------------------- */ static void FadeToken(Dnd *dndPtr) /* Drag-and-drop manager (source). */ { Token *tokenPtr = dndPtr->tokenPtr; int w, h; int dx, dy; Window window; if (tokenPtr->status == DROP_FAIL) { tokenPtr->nSteps = 1; return; } if (tokenPtr->nSteps == 1) { HideToken(dndPtr); dndPtr->flags &= ~(DND_ACTIVE | DND_VOIDED); return; } if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } tokenPtr->timerToken = Tcl_CreateTimerHandler(10, (Tcl_TimerProc *)FadeToken, dndPtr); tokenPtr->nSteps--; w = Tk_ReqWidth(tokenPtr->tkwin) * tokenPtr->nSteps / 10; h = Tk_ReqHeight(tokenPtr->tkwin) * tokenPtr->nSteps / 10; if (w < 1) { w = 1; } if (h < 1) { h = 1; } dx = (Tk_ReqWidth(tokenPtr->tkwin) - w) / 2; dy = (Tk_ReqHeight(tokenPtr->tkwin) - h) / 2; window = Blt_GetWindowId(tokenPtr->tkwin); XMoveResizeWindow(dndPtr->display, window, tokenPtr->x + dx, tokenPtr->y + dy, (unsigned int)w, (unsigned int)h); tokenPtr->width = w, tokenPtr->height = h; } /* *--------------------------------------------------------------------------- * * SnapToken -- * * Snaps the token back to the source. * *--------------------------------------------------------------------------- */ static void SnapToken(Dnd *dndPtr) { Token *tokenPtr = dndPtr->tokenPtr; if (tokenPtr->nSteps == 1) { HideToken(dndPtr); return; } if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } tokenPtr->timerToken = Tcl_CreateTimerHandler(10, (Tcl_TimerProc *)SnapToken, dndPtr); tokenPtr->nSteps--; tokenPtr->x -= (tokenPtr->x - tokenPtr->startX) / tokenPtr->nSteps; tokenPtr->y -= (tokenPtr->y - tokenPtr->startY) / tokenPtr->nSteps; if ((tokenPtr->x != Tk_X(tokenPtr->tkwin)) || (tokenPtr->y != Tk_Y(tokenPtr->tkwin))) { Tk_MoveToplevelWindow(tokenPtr->tkwin, tokenPtr->x, tokenPtr->y); } RaiseToken(dndPtr); } /* *--------------------------------------------------------------------------- * * HideToken -- * * Unmaps the drag&drop token. Invoked directly at the end of a * successful communication, or after a delay if the communication * fails (allowing the user to see a graphical picture of failure). * *--------------------------------------------------------------------------- */ static void HideToken(Dnd *dndPtr) { Token *tokenPtr = dndPtr->tokenPtr; if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); tokenPtr->timerToken = NULL; } if (dndPtr->flags & DND_INITIATED) { /* Reset the cursor back to its normal state. */ StopActiveCursor(dndPtr); if (dndPtr->cursor == None) { Tk_UndefineCursor(dndPtr->tkwin); } else { Tk_DefineCursor(dndPtr->tkwin, dndPtr->cursor); } if (tokenPtr->tkwin != NULL) { Tk_UnmapWindow(tokenPtr->tkwin); Blt_ResizeToplevelWindow(tokenPtr->tkwin, Tk_ReqWidth(tokenPtr->tkwin), Tk_ReqHeight(tokenPtr->tkwin)); } } if (dndPtr->rootPtr != NULL) { FreeWinfo(dndPtr->rootPtr); dndPtr->rootPtr = NULL; } dndPtr->flags &= ~(DND_ACTIVE | DND_VOIDED); tokenPtr->status = DROP_CONTINUE; } #ifdef notdef /* *--------------------------------------------------------------------------- * * MorphToken -- * * Fades the token into the target. * *--------------------------------------------------------------------------- */ static void MorphToken(Dnd *dndPtr) /* Drag-and-drop manager (source). */ { Token *tokenPtr = dndPtr->tokenPtr; if (tokenPtr->status == DROP_FAIL) { tokenPtr->nSteps = 1; return; } if (tokenPtr->nSteps == 1) { HideToken(dndPtr); dndPtr->flags &= ~(DND_ACTIVE | DND_VOIDED); return; } if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } tokenPtr->timerToken = Tcl_CreateTimerHandler(10, (Tcl_TimerProc *)MorphToken, dndPtr); tokenPtr->nSteps--; if (dndPtr->flags & DROP_CANCEL) { tokenPtr->nSteps--; tokenPtr->x -= (tokenPtr->x - tokenPtr->startX) / tokenPtr->nSteps; tokenPtr->y -= (tokenPtr->y - tokenPtr->startY) / tokenPtr->nSteps; if ((tokenPtr->x != Tk_X(tokenPtr->tkwin)) || (tokenPtr->y != Tk_Y(tokenPtr->tkwin))) { Tk_MoveToplevelWindow(tokenPtr->tkwin, tokenPtr->x, tokenPtr->y); } } else { int w, h; int dx, dy; Window window; w = Tk_ReqWidth(tokenPtr->tkwin) * tokenPtr->nSteps / 10; h = Tk_ReqHeight(tokenPtr->tkwin) * tokenPtr->nSteps / 10; if (w < 1) { w = 1; } if (h < 1) { h = 1; } dx = (Tk_ReqWidth(tokenPtr->tkwin) - w) / 2; dy = (Tk_ReqHeight(tokenPtr->tkwin) - h) / 2; window = Blt_GetWindowId(tokenPtr->tkwin); XMoveResizeWindow(dndPtr->display, window, tokenPtr->x + dx, tokenPtr->y + dy, (unsigned int)w, (unsigned int)h); tokenPtr->width = w, tokenPtr->height = h; } RaiseToken(dndPtr); } #endif static void GetTokenPosition(Dnd *dndPtr, int x, int y) { Token *tokenPtr = dndPtr->tokenPtr; int maxX, maxY; int vx, vy, dummy; int screenWidth, screenHeight; /* Adjust current location for virtual root windows. */ Tk_GetVRootGeometry(dndPtr->tkwin, &vx, &vy, &dummy, &dummy); x += vx - TOKEN_OFFSET; y += vy - TOKEN_OFFSET; Blt_SizeOfScreen(tokenPtr->tkwin, &screenWidth, &screenHeight); maxX = screenWidth - Tk_Width(tokenPtr->tkwin); maxY = screenHeight - Tk_Height(tokenPtr->tkwin); Blt_TranslateAnchor(x, y, Tk_Width(tokenPtr->tkwin), Tk_Height(tokenPtr->tkwin), tokenPtr->anchor, &x, &y); if (x > maxX) { x = maxX; } else if (x < 0) { x = 0; } if (y > maxY) { y = maxY; } else if (y < 0) { y = 0; } tokenPtr->x = x, tokenPtr->y = y; } /* *--------------------------------------------------------------------------- * * MoveToken -- * * Invoked during "drag" operations to move a token window to its * current "drag" coordinate. * *--------------------------------------------------------------------------- */ static void MoveToken(Dnd *dndPtr) /* drag&drop source window data */ { Token *tokenPtr = dndPtr->tokenPtr; GetTokenPosition(dndPtr, dndPtr->x, dndPtr->y); if ((tokenPtr->x != Tk_X(tokenPtr->tkwin)) || (tokenPtr->y != Tk_Y(tokenPtr->tkwin))) { Tk_MoveToplevelWindow(tokenPtr->tkwin, tokenPtr->x, tokenPtr->y); } } /* *--------------------------------------------------------------------------- * * ChangeToken -- * * Invoked when the event loop is idle to determine whether or not * the current drag&drop token position is over another drag&drop * target. * *--------------------------------------------------------------------------- */ static void ChangeToken(Dnd *dndPtr, int status) { Token *tokenPtr = dndPtr->tokenPtr; tokenPtr->status = status; EventuallyRedrawToken(dndPtr); /* * If the source has a site command, then invoke it to * modify the appearance of the token window. Pass any * errors onto the drag&drop error handler. */ if (dndPtr->siteCmd) { Tcl_Interp *interp = dndPtr->interp; Tcl_DString dString, savedResult; const char **p; Tcl_DStringInit(&dString); for (p = dndPtr->siteCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(dndPtr->timestamp)); Tcl_DStringAppendElement(&dString, "status"); Tcl_DStringAppendElement(&dString, NameOfStatus(status)); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)) != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DStringFree(&dString); Tcl_DStringResult(interp, &savedResult); } } /* *--------------------------------------------------------------------------- * * DrawRejectSymbol -- * * Draws a rejection mark on the current drag&drop token, and arranges * for the token to be unmapped after a small delay. * *--------------------------------------------------------------------------- */ static void DrawRejectSymbol(Dnd *dndPtr) { Token *tokenPtr = dndPtr->tokenPtr; int divisor = 6; /* controls size of rejection symbol */ int w, h, lineWidth, x, y, margin; margin = 2 * tokenPtr->borderWidth; w = Tk_Width(tokenPtr->tkwin) - 2 * margin; h = Tk_Height(tokenPtr->tkwin) - 2 * margin; lineWidth = (w < h) ? w / divisor : h / divisor; lineWidth = (lineWidth < 1) ? 1 : lineWidth; w = h = lineWidth * (divisor - 1); x = (Tk_Width(tokenPtr->tkwin) - w) / 2; y = (Tk_Height(tokenPtr->tkwin) - h) / 2; /* * Draw the rejection symbol background (\) on the token window... */ XSetLineAttributes(Tk_Display(tokenPtr->tkwin), tokenPtr->outlineGC, lineWidth + 2, LineSolid, CapButt, JoinBevel); XDrawArc(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->outlineGC, x, y, w, h, 0, 23040); XDrawLine(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->outlineGC, x + lineWidth, y + lineWidth, x + w - lineWidth, y + h - lineWidth); /* * Draw the rejection symbol foreground (\) on the token window... */ XSetLineAttributes(Tk_Display(tokenPtr->tkwin), tokenPtr->fillGC, lineWidth, LineSolid, CapButt, JoinBevel); XDrawArc(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->fillGC, x, y, w, h, 0, 23040); XDrawLine(Tk_Display(tokenPtr->tkwin), Tk_WindowId(tokenPtr->tkwin), tokenPtr->fillGC, x + lineWidth, y + lineWidth, x + w - lineWidth, y + h - lineWidth); tokenPtr->status = DROP_FAIL; /* * Arrange for token window to disappear eventually. */ if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } tokenPtr->timerToken = Tcl_CreateTimerHandler(1000, (Tcl_TimerProc *)HideToken, dndPtr); RaiseToken(dndPtr); dndPtr->flags &= ~(DND_ACTIVE | DND_VOIDED); } /* *--------------------------------------------------------------------------- * * CreateToken -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Creates a new record if the widget name is not already * registered. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static void DestroyToken(DestroyData data) { Dnd *dndPtr = (Dnd *)data; Token *tokenPtr = dndPtr->tokenPtr; dndPtr->tokenPtr = NULL; if (tokenPtr == NULL) { return; } if (tokenPtr->flags & TOKEN_REDRAW) { Tcl_CancelIdleCall(DisplayToken, dndPtr); } Blt_FreeOptions(tokenConfigSpecs, (char *)tokenPtr, dndPtr->display, 0); if (tokenPtr->timerToken) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } if (tokenPtr->fillGC != NULL) { Tk_FreeGC(dndPtr->display, tokenPtr->fillGC); } if (tokenPtr->outlineGC != NULL) { Tk_FreeGC(dndPtr->display, tokenPtr->outlineGC); } if (tokenPtr->tkwin != NULL) { Tk_DeleteEventHandler(tokenPtr->tkwin, ExposureMask | StructureNotifyMask, TokenEventProc, dndPtr); Tk_DestroyWindow(tokenPtr->tkwin); } Blt_Free(tokenPtr); } /* *--------------------------------------------------------------------------- * * TokenEventProc -- * * Invoked by the Tk dispatcher to handle widget events. * Manages redraws for the drag&drop token window. * *--------------------------------------------------------------------------- */ static void TokenEventProc(ClientData clientData, XEvent *eventPtr) { Dnd *dndPtr = clientData; Token *tokenPtr = dndPtr->tokenPtr; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { if (tokenPtr->tkwin != NULL) { EventuallyRedrawToken(dndPtr); } } else if (eventPtr->type == DestroyNotify) { tokenPtr->tkwin = NULL; if (tokenPtr->flags & TOKEN_REDRAW) { tokenPtr->flags &= ~TOKEN_REDRAW; Tcl_CancelIdleCall(DisplayToken, dndPtr); } Tcl_EventuallyFree(dndPtr, DestroyToken); } } /* *--------------------------------------------------------------------------- * * CreateToken -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Creates a new record if the widget name is not already * registered. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static int CreateToken( Tcl_Interp *interp, Dnd *dndPtr) { XSetWindowAttributes attrs; Tk_Window tkwin; unsigned int mask; Token *tokenPtr; tokenPtr = Blt_AssertCalloc(1, sizeof(Token)); tokenPtr->anchor = TK_ANCHOR_SE; tokenPtr->relief = TK_RELIEF_RAISED; tokenPtr->activeRelief = TK_RELIEF_SUNKEN; tokenPtr->borderWidth = tokenPtr->activeBW = 3; /* Create toplevel on parent's screen. */ tkwin = Tk_CreateWindow(interp, dndPtr->tkwin, "dndtoken", ""); if (tkwin == NULL) { Blt_Free(tokenPtr); return TCL_ERROR; } tokenPtr->tkwin = tkwin; Tk_SetClass(tkwin, "DndToken"); Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, TokenEventProc, dndPtr); attrs.override_redirect = True; attrs.backing_store = WhenMapped; attrs.save_under = True; mask = CWOverrideRedirect | CWSaveUnder | CWBackingStore; Tk_ChangeWindowAttributes(tkwin, mask, &attrs); Tk_SetInternalBorder(tkwin, tokenPtr->borderWidth + 2); Tk_MakeWindowExist(tkwin); dndPtr->tokenPtr = tokenPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureToken -- * * Called to process an (objc,objv) list to configure (or * reconfigure) a drag&drop source widget. * *--------------------------------------------------------------------------- */ static int ConfigureToken( Tcl_Interp *interp, /* current interpreter */ Dnd *dndPtr, /* Drag&drop source widget record */ int objc, /* number of arguments */ Tcl_Obj *const *objv, /* argument strings */ int flags) /* flags controlling interpretation */ { GC newGC; Token *tokenPtr = dndPtr->tokenPtr; XGCValues gcValues; unsigned long gcMask; Tk_MakeWindowExist(tokenPtr->tkwin); if (Blt_ConfigureWidgetFromObj(interp, tokenPtr->tkwin, tokenConfigSpecs, objc, objv, (char *)tokenPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Set up the rejection outline GC for the token window... */ gcValues.foreground = tokenPtr->outlineColor->pixel; gcValues.subwindow_mode = IncludeInferiors; gcValues.graphics_exposures = False; gcValues.line_style = LineSolid; gcValues.cap_style = CapButt; gcValues.join_style = JoinBevel; gcMask = GCForeground | GCSubwindowMode | GCLineStyle | GCCapStyle | GCJoinStyle | GCGraphicsExposures; newGC = Tk_GetGC(dndPtr->tkwin, gcMask, &gcValues); if (tokenPtr->outlineGC != NULL) { Tk_FreeGC(dndPtr->display, tokenPtr->outlineGC); } tokenPtr->outlineGC = newGC; /* * Set up the rejection fill GC for the token window... */ gcValues.foreground = tokenPtr->fillColor->pixel; if (tokenPtr->rejectStipple != None) { gcValues.stipple = tokenPtr->rejectStipple; gcValues.fill_style = FillStippled; gcMask |= GCStipple | GCFillStyle; } newGC = Tk_GetGC(dndPtr->tkwin, gcMask, &gcValues); if (tokenPtr->fillGC != NULL) { Tk_FreeGC(dndPtr->display, tokenPtr->fillGC); } tokenPtr->fillGC = newGC; if ((tokenPtr->reqWidth > 0) && (tokenPtr->reqHeight > 0)) { Tk_GeometryRequest(tokenPtr->tkwin, tokenPtr->reqWidth, tokenPtr->reqHeight); } /* * Reset the border width in case it has changed... */ Tk_SetInternalBorder(tokenPtr->tkwin, tokenPtr->borderWidth + 2); return TCL_OK; } static int GetFormattedData( Dnd *dndPtr, char *format, int timestamp, Tcl_DString *resultPtr) { Tcl_Interp *interp = dndPtr->interp; Blt_HashEntry *hPtr; char **formatCmd; Tcl_DString savedResult; Tcl_DString dString; char **p; int x, y; /* Find the data converter for the prescribed format. */ hPtr = Blt_FindHashEntry(&dndPtr->getDataTable, format); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find format \"", format, "\" in source \"", Tk_PathName(dndPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } formatCmd = Blt_GetHashValue(hPtr); Tcl_DStringInit(&dString); for (p = formatCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } x = dndPtr->dragX - Blt_RootX(dndPtr->tkwin); y = dndPtr->dragY - Blt_RootY(dndPtr->tkwin); Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); Tcl_DStringAppendElement(&dString, "x"); Tcl_DStringAppendElement(&dString, Blt_Itoa(x)); Tcl_DStringAppendElement(&dString, "y"); Tcl_DStringAppendElement(&dString, Blt_Itoa(y)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(timestamp)); Tcl_DStringAppendElement(&dString, "format"); Tcl_DStringAppendElement(&dString, format); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)) != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DStringFree(&dString); Tcl_DStringInit(resultPtr); Tcl_DStringGetResult(interp, resultPtr); /* Restore the interpreter result. */ Tcl_DStringResult(interp, &savedResult); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DestroyDnd -- * * Free resources allocated for the drag&drop window. * *--------------------------------------------------------------------------- */ static void DestroyDnd(DestroyData data) { Dnd *dndPtr = (Dnd *)data; Blt_HashEntry *hPtr; Blt_HashSearch cursor; char **cmd; Blt_FreeOptions(configSpecs, (char *)dndPtr, dndPtr->display, 0); Tk_DeleteGenericHandler(DndEventProc, dndPtr); for (hPtr = Blt_FirstHashEntry(&dndPtr->getDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { cmd = Blt_GetHashValue(hPtr); if (cmd != NULL) { Blt_Free(cmd); } } Blt_DeleteHashTable(&dndPtr->getDataTable); for (hPtr = Blt_FirstHashEntry(&dndPtr->setDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { cmd = Blt_GetHashValue(hPtr); if (cmd != NULL) { Blt_Free(cmd); } } Blt_DeleteHashTable(&dndPtr->setDataTable); if (dndPtr->rootPtr != NULL) { FreeWinfo(dndPtr->rootPtr); } if (dndPtr->cursor != None) { Tk_FreeCursor(dndPtr->display, dndPtr->cursor); } if (dndPtr->reqFormats != NULL) { Blt_Free(dndPtr->reqFormats); } if (dndPtr->matchingFormats != NULL) { Blt_Free(dndPtr->matchingFormats); } /* Now that the various commands are custom list options, we need * to explicitly free them. */ if (dndPtr->motionCmd != NULL) { Blt_Free(dndPtr->motionCmd); } if (dndPtr->leaveCmd != NULL) { Blt_Free(dndPtr->leaveCmd); } if (dndPtr->enterCmd != NULL) { Blt_Free(dndPtr->enterCmd); } if (dndPtr->dropCmd != NULL) { Blt_Free(dndPtr->dropCmd); } if (dndPtr->resultCmd != NULL) { Blt_Free(dndPtr->resultCmd); } if (dndPtr->packageCmd != NULL) { Blt_Free(dndPtr->packageCmd); } if (dndPtr->siteCmd != NULL) { Blt_Free(dndPtr->siteCmd); } if (dndPtr->hashPtr != NULL) { Blt_DeleteHashEntry(&dndPtr->dataPtr->dndTable, dndPtr->hashPtr); } if (dndPtr->tokenPtr != NULL) { DestroyToken((DestroyData)dndPtr); } if (dndPtr->tkwin != NULL) { XDeleteProperty(dndPtr->display, Tk_WindowId(dndPtr->tkwin), dndPtr->dataPtr->targetAtom); XDeleteProperty(dndPtr->display, Tk_WindowId(dndPtr->tkwin), dndPtr->dataPtr->commAtom); } Blt_Free(dndPtr); } /* *--------------------------------------------------------------------------- * * GetDnd -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static int GetDndFromObj( ClientData clientData, Tcl_Interp *interp, Tcl_Obj *objPtr, /* widget pathname for desired record */ Dnd **dndPtrPtr) { DndInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Tk_Window tkwin; char *pathName; pathName = Tcl_GetString(objPtr); assert(interp != NULL); tkwin = Tk_NameToWindow(interp, pathName, dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_FindHashEntry(&dataPtr->dndTable, (char *)tkwin); if (hPtr == NULL) { Tcl_AppendResult(interp, "window \"", pathName, "\" is not a drag&drop source/target", (char *)NULL); return TCL_ERROR; } *dndPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CreateDnd -- * * Looks for a Source record in the hash table for drag&drop source * widgets. Creates a new record if the widget name is not already * registered. Returns a pointer to the desired record. * *--------------------------------------------------------------------------- */ static Dnd * CreateDnd( Tcl_Interp *interp, Tk_Window tkwin) /* Widget for desired record */ { Dnd *dndPtr; dndPtr = Blt_AssertCalloc(1, sizeof(Dnd)); dndPtr->interp = interp; dndPtr->display = Tk_Display(tkwin); dndPtr->tkwin = tkwin; Tk_MakeWindowExist(tkwin); Blt_InitHashTable(&dndPtr->setDataTable, BLT_STRING_KEYS); Blt_InitHashTable(&dndPtr->getDataTable, BLT_STRING_KEYS); Tk_CreateGenericHandler(DndEventProc, dndPtr); return dndPtr; } static int ConfigureDnd(Tcl_Interp *interp, Dnd *dndPtr) { Tcl_CmdInfo cmdInfo; Tcl_DString dString; int button, result; if (!Tcl_GetCommandInfo(interp, "::blt::DndInit", &cmdInfo)) { static char cmd[] = "source [file join $blt_library dnd.tcl]"; /* * If the "DndInit" routine hasn't been sourced, do it now. */ if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (while loading bindings for blt::drag&drop)"); return TCL_ERROR; } } /* * Reset the target property if it's changed state or * added/subtracted one of its callback procedures. */ if (Blt_ConfigModified(configSpecs, "-target", "-onenter", "-onmotion", "-onleave", (char *)NULL)) { if (dndPtr->targetPropertyExists) { XDeleteProperty(dndPtr->display, Tk_WindowId(dndPtr->tkwin), dndPtr->dataPtr->targetAtom); dndPtr->targetPropertyExists = FALSE; } if (dndPtr->isTarget) { AddTargetProperty(dndPtr); dndPtr->targetPropertyExists = TRUE; } } if (dndPtr->isSource) { /* Check the button binding for valid range (0 or 1-5) */ if ((dndPtr->reqButton < 0) || (dndPtr->reqButton > 5)) { Tcl_AppendResult(interp, "button must be 1-5, or 0 for no bindings", (char *)NULL); return TCL_ERROR; } button = dndPtr->reqButton; } else { button = 0; } Tcl_DStringInit(&dString); Blt_DStringAppendElements(&dString, "::blt::DndInit", Tk_PathName(dndPtr->tkwin), Blt_Itoa(button), (char *)NULL); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (result != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SendRestrictProc -- * * This procedure filters incoming events when a "send" command * is outstanding. It defers all events except those containing * send commands and results. * * Results: * False is returned except for property-change events on a * commWindow. * * Side effects: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static Tk_RestrictAction SendRestrictProc( ClientData clientData, /* Drag-and-drop manager. */ XEvent *eventPtr) /* Event that just arrived. */ { Dnd *dndPtr = clientData; if (eventPtr->xproperty.window != Tk_WindowId(dndPtr->tkwin)) { return TK_PROCESS_EVENT; /* Event not in our window. */ } if ((eventPtr->type == PropertyNotify) && (eventPtr->xproperty.state == PropertyNewValue)) { return TK_PROCESS_EVENT; /* This is the one we want to process. */ } if (eventPtr->type == Expose) { return TK_PROCESS_EVENT; /* Let expose events also get * handled. */ } return TK_DEFER_EVENT; /* Defer everything else. */ } /* *--------------------------------------------------------------------------- * * SendTimerProc -- * * Procedure called when the timer event elapses. Used to wait * between attempts checking for the designated window. * * Results: * None. * * Side Effects: * Sets a flag, indicating the timeout occurred. * *--------------------------------------------------------------------------- */ static void SendTimerProc(ClientData clientData) { int *statusPtr = clientData; /* * An unusually long amount of time has elapsed since the drag * start message was sent. Assume that the other party has died * and abort the operation. */ *statusPtr = DROP_FAIL; } #define WAIT_INTERVAL 2000 /* Twenty seconds. */ /* *--------------------------------------------------------------------------- * * TargetPropertyEventProc -- * * Invoked by the Tk dispatcher to handle widget events. Manages redraws * for the drag&drop token window. * *--------------------------------------------------------------------------- */ static void TargetPropertyEventProc( ClientData clientData, /* Data associated with transaction. */ XEvent *eventPtr) /* information about event */ { DropPending *pendingPtr = clientData; unsigned char *data; int result, format; Atom typeAtom; unsigned long nItems, bytesAfter; #ifdef notdef fprintf(stderr, "TargetPropertyEventProc\n"); #endif if ((eventPtr->type != PropertyNotify) || (eventPtr->xproperty.atom != pendingPtr->commAtom) || (eventPtr->xproperty.state != PropertyNewValue)) { return; } Tcl_DeleteTimerHandler(pendingPtr->timerToken); data = NULL; result = XGetWindowProperty( eventPtr->xproperty.display, /* Display of window. */ eventPtr->xproperty.window, /* Window holding the property. */ eventPtr->xproperty.atom, /* Name of property. */ 0, /* Offset of data (for multiple * reads). */ pendingPtr->packetSize, /* Maximum number of items to read. */ False, /* If true, delete the property. */ XA_STRING, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the * property. */ &nItems, /* (out) # of items in specified * format. */ &bytesAfter, /* (out) # of bytes remaining to be * read. */ &data); #ifdef notdef fprintf(stderr, "TargetPropertyEventProc: result=%d, typeAtom=%d, format=%d, nItems=%d\n", result, typeAtom, format, nItems); #endif pendingPtr->status = DROP_FAIL; if ((result == Success) && (typeAtom == XA_STRING) && (format == 8)) { pendingPtr->status = DROP_OK; #ifdef notdef fprintf(stderr, "data found is (%s)\n", data); #endif Tcl_DStringAppend(&pendingPtr->dString, (char *)data, -1); XFree(data); if (nItems == pendingPtr->packetSize) { /* Normally, we'll receive the data in one chunk. But if more are * required, reset the timer and go back into the wait loop * again. */ pendingPtr->timerToken = Tcl_CreateTimerHandler(WAIT_INTERVAL, SendTimerProc, &pendingPtr->status); pendingPtr->status = DROP_CONTINUE; } } /* Set an empty, zero-length value on the source's property. This acts as a * handshake, indicating that the target received the latest chunk. */ #ifdef notdef fprintf(stderr, "TargetPropertyEventProc: set response property\n"); #endif XChangeProperty(pendingPtr->display, pendingPtr->window, pendingPtr->commAtom, XA_STRING, 8, PropModeReplace, (unsigned char *)"", 0); } #ifdef HAVE_XDND static int XDndSelectionProc(clientData, interp, portion) ClientData clientData; Tcl_Interp *interp; char *portion; { DropPending *pendingPtr = clientData; Tcl_DStringAppend(&pendingPtr->dString, portion, -1); #ifdef notdef fprintf(stderr, "-> XDndGetSelectionProc\n"); #endif return TCL_OK; } #endif /* HAVE_XDND */ static void CompleteDataTransaction(Dnd *dndPtr, char *format, DropPending *pendingPtr) { DndInterpData *dataPtr = dndPtr->dataPtr; Tk_Window tkwin; Atom formatAtom; #ifdef notdef fprintf(stderr, "-> CompleteDataTransaction\n"); #endif /* Check if the source is local to the application. */ tkwin = Tk_IdToWindow(dndPtr->display, pendingPtr->window); if (tkwin != NULL) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&dndPtr->dataPtr->dndTable, (char *)tkwin); if (hPtr != NULL) { Dnd *srcPtr; srcPtr = Blt_GetHashValue(hPtr); GetFormattedData(srcPtr, format, pendingPtr->timestamp, &pendingPtr->dString); } return; } formatAtom = XInternAtom(pendingPtr->display, format, False); if (pendingPtr->protocol == PROTO_XDND) { #ifdef HAVE_XDND if (Tk_GetSelection(dndPtr->interp, dndPtr->tkwin, dataPtr->XdndSelectionAtom, formatAtom, XDndSelectionProc, pendingPtr) != TCL_OK) { pendingPtr->status = DROP_FAIL; } #endif pendingPtr->status = DROP_OK; } else { Tk_RestrictProc *proc; ClientData arg; SendClientMsg(pendingPtr->display, pendingPtr->window, dataPtr->mesgAtom, TS_START_DROP, (int)Tk_WindowId(dndPtr->tkwin), pendingPtr->timestamp, (int)formatAtom, (int)pendingPtr->commAtom); pendingPtr->commAtom = dndPtr->dataPtr->commAtom; pendingPtr->status = DROP_CONTINUE; pendingPtr->display = dndPtr->display; proc = Tk_RestrictEvents(SendRestrictProc, dndPtr, &arg); Tk_CreateEventHandler(dndPtr->tkwin, PropertyChangeMask, TargetPropertyEventProc, pendingPtr); pendingPtr->timerToken = Tcl_CreateTimerHandler(WAIT_INTERVAL, SendTimerProc, &pendingPtr->status); /* * Enter a loop processing X events until the all the data is received * or the source is declared to be dead (i.e. we timeout). While * waiting for a result, restrict handling to just property-related * events so that the transfer is synchronous with respect to other * events in the widget. */ while (pendingPtr->status == DROP_CONTINUE) { Tcl_DoOneEvent(TCL_ALL_EVENTS); /* Wait for property event. */ } Tk_RestrictEvents(proc, arg, &arg); Tcl_DeleteTimerHandler(pendingPtr->timerToken); Tk_DeleteEventHandler(dndPtr->tkwin, PropertyChangeMask, TargetPropertyEventProc, pendingPtr); } #ifdef notdef fprintf(stderr, "<- CompleteDataTransaction\n"); #endif } /* *--------------------------------------------------------------------------- * * SourcePropertyEventProc -- * * Invoked by the Tk dispatcher when a PropertyNotify event occurs on the * source window. The event acts as a handshake between the target and the * source. The source acknowledges the target has received the last packet * of data and sends the next packet. * * Note a special case. If the data is divisible by the packetsize, then * an extra zero-length packet is sent to mark the end of the data. A * packetsize length packet indicates more is to follow. * * Normally the property is empty (zero-length). But if an errored * occurred on the target, it will contain the error message. * * ------------------------------------------------------------------------ */ static void SourcePropertyEventProc( ClientData clientData, /* data associated with widget */ XEvent *eventPtr) /* information about event */ { DropPending *pendingPtr = clientData; unsigned char *data; int result, format; Atom typeAtom; unsigned long nItems, bytesAfter; int size, bytesLeft; unsigned char *p; #ifdef notdef fprintf(stderr, "-> SourcePropertyEventProc\n"); #endif if ((eventPtr->xproperty.atom != pendingPtr->commAtom) || (eventPtr->xproperty.state != PropertyNewValue)) { return; } Tcl_DeleteTimerHandler(pendingPtr->timerToken); data = NULL; result = XGetWindowProperty( eventPtr->xproperty.display, /* Display of window. */ eventPtr->xproperty.window, /* Window holding the property. */ eventPtr->xproperty.atom, /* Name of property. */ 0, /* Offset of data (for multiple * reads). */ pendingPtr->packetSize, /* Maximum number of items to read. */ True, /* If true, delete the property. */ XA_STRING, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the * property. */ &nItems, /* (out) # of items in specified * format. */ &bytesAfter, /* (out) # of bytes remaining to be * read. */ &data); if ((result != Success) || (typeAtom != XA_STRING) || (format != 8)) { pendingPtr->status = DROP_FAIL; #ifdef notdef fprintf(stderr, "<- SourcePropertyEventProc: wrong format\n"); #endif return; /* Wrong data format. */ } if (nItems > 0) { pendingPtr->status = DROP_FAIL; Tcl_DStringFree(&pendingPtr->dString); Tcl_DStringAppend(&pendingPtr->dString, (char *)data, -1); XFree(data); #ifdef notdef fprintf(stderr, "<- SourcePropertyEventProc: error\n"); #endif return; /* Error occurred on target. */ } bytesLeft = Tcl_DStringLength(&pendingPtr->dString) - pendingPtr->offset; if (bytesLeft <= 0) { #ifdef notdef fprintf(stderr, "<- SourcePropertyEventProc: done\n"); #endif pendingPtr->status = DROP_OK; size = 0; } else { size = MIN(bytesLeft, pendingPtr->packetSize); pendingPtr->status = DROP_CONTINUE; } p = (unsigned char *)Tcl_DStringValue(&pendingPtr->dString) + pendingPtr->offset; XChangeProperty(pendingPtr->display, pendingPtr->window, pendingPtr->commAtom, XA_STRING, 8, PropModeReplace, p, size); pendingPtr->offset += size; pendingPtr->timerToken = Tcl_CreateTimerHandler(WAIT_INTERVAL, SendTimerProc, &pendingPtr->status); #ifdef notdef fprintf(stderr, "<- SourcePropertyEventProc\n"); #endif } static void SendDataToTarget(Dnd *dndPtr, DropPending *pendingPtr) { int size; Tk_RestrictProc *proc; ClientData arg; #ifdef notdef fprintf(stderr, "-> SendDataToTarget\n"); #endif Tk_CreateEventHandler(dndPtr->tkwin, PropertyChangeMask, SourcePropertyEventProc, pendingPtr); pendingPtr->timerToken = Tcl_CreateTimerHandler(WAIT_INTERVAL, SendTimerProc, &pendingPtr->status); size = MIN(Tcl_DStringLength(&pendingPtr->dString), pendingPtr->packetSize); proc = Tk_RestrictEvents(SendRestrictProc, dndPtr, &arg); /* * Setting the property starts the process. The target will see the * PropertyChange event and respond accordingly. */ XChangeProperty(dndPtr->display, pendingPtr->window, pendingPtr->commAtom, XA_STRING, 8, PropModeReplace, (unsigned char *)Tcl_DStringValue(&pendingPtr->dString), size); pendingPtr->offset += size; /* * Enter a loop processing X events until the result comes in or the target * is declared to be dead. While waiting for a result, look only at * property-related events so that the handshake is synchronous with respect * to other events in the application. */ pendingPtr->status = DROP_CONTINUE; while (pendingPtr->status == DROP_CONTINUE) { /* Wait for the property change event. */ Tcl_DoOneEvent(TCL_ALL_EVENTS); } Tk_RestrictEvents(proc, arg, &arg); Tcl_DeleteTimerHandler(pendingPtr->timerToken); Tk_DeleteEventHandler(dndPtr->tkwin, PropertyChangeMask, SourcePropertyEventProc, pendingPtr); #ifdef notdef fprintf(stderr, "<- SendDataToTarget\n"); #endif } static void DoDrop(Dnd *dndPtr, XEvent *eventPtr) { DndInterpData *dataPtr = dndPtr->dataPtr; Token *tokenPtr = dndPtr->tokenPtr; Tcl_Interp *interp = dndPtr->interp; struct DropRequest { int mesg; /* TS_DROP_RESULT message. */ Window window; /* Target window. */ int timestamp; /* Transaction timestamp. */ Atom formatAtom; /* Format requested. */ } *dropPtr; char *format; DropPending pending; if (tokenPtr->timerToken != NULL) { Tcl_DeleteTimerHandler(tokenPtr->timerToken); } dropPtr = (struct DropRequest *)eventPtr->xclient.data.l; format = XGetAtomName(dndPtr->display, dropPtr->formatAtom); #ifdef notdef fprintf(stderr, "DoDrop %s 0x%x\n", Tk_PathName(dndPtr->tkwin), dropPtr->window); #endif if (GetFormattedData(dndPtr, format, dropPtr->timestamp, &pending.dString) != TCL_OK) { Tcl_BackgroundError(interp); /* Send empty string to break target's wait loop. */ XChangeProperty(dndPtr->display, dropPtr->window, dataPtr->commAtom, XA_STRING, 8, PropModeReplace, (unsigned char *)"", 0); return; } pending.window = dropPtr->window; pending.display = dndPtr->display; pending.commAtom = dataPtr->commAtom; pending.offset = 0; pending.packetSize = GetMaxPropertySize(dndPtr->display); SendDataToTarget(dndPtr, &pending); Tcl_DStringFree(&pending.dString); #ifdef notdef fprintf(stderr, "<- DoDrop\n"); #endif } static void DropFinished(Dnd *dndPtr, XEvent *eventPtr) { Tcl_Interp *interp = dndPtr->interp; Tcl_DString dString, savedResult; int result; const char **p; struct DropResult { int mesg; /* TS_DROP_RESULT message. */ Window window; /* Target window. */ int timestamp; /* Transaction timestamp. */ int result; /* Result of transaction. */ } *dropPtr; #ifdef notdef fprintf(stderr, "DropFinished\n"); #endif dropPtr = (struct DropResult *)eventPtr->xclient.data.l; Tcl_DStringInit(&dString); for (p = dndPtr->resultCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); Tcl_DStringAppendElement(&dString, "action"); Tcl_DStringAppendElement(&dString, NameOfAction(dropPtr->result)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(dropPtr->timestamp)); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (result != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DStringResult(interp, &savedResult); } static void FreeFormats(Dnd *dndPtr) { if (dndPtr->matchingFormats != NULL) { Blt_Free(dndPtr->matchingFormats); dndPtr->matchingFormats = NULL; } dndPtr->lastId = None; } static const char * GetSourceFormats(Dnd *dndPtr, Window window, int timestamp) { if (dndPtr->lastId != timestamp) { unsigned char *data; FreeFormats(dndPtr); data = GetProperty(dndPtr->display, window, dndPtr->dataPtr->formatsAtom); if (data != NULL) { dndPtr->matchingFormats = Blt_AssertStrdup((char *)data); XFree(data); } dndPtr->lastId = timestamp; } if (dndPtr->matchingFormats == NULL) { return ""; } return dndPtr->matchingFormats; } static int InvokeCallback(Dnd *dndPtr, const char **cmd, int x, int y, const char *formats, int button, int keyState, int timestamp) { Tcl_DString dString, savedResult; Tcl_Interp *interp = dndPtr->interp; int result; const char **p; Tcl_DStringInit(&dString); for (p = cmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); /* Send coordinates relative to target. */ x -= Blt_RootX(dndPtr->tkwin); y -= Blt_RootY(dndPtr->tkwin); Tcl_DStringAppendElement(&dString, "x"); Tcl_DStringAppendElement(&dString, Blt_Itoa(x)); Tcl_DStringAppendElement(&dString, "y"); Tcl_DStringAppendElement(&dString, Blt_Itoa(y)); Tcl_DStringAppendElement(&dString, "formats"); if (formats == NULL) { formats = ""; } Tcl_DStringAppendElement(&dString, formats); Tcl_DStringAppendElement(&dString, "button"); Tcl_DStringAppendElement(&dString, Blt_Itoa(button)); Tcl_DStringAppendElement(&dString, "state"); Tcl_DStringAppendElement(&dString, Blt_Itoa(keyState)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(timestamp)); Tcl_Preserve(interp); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (result == TCL_OK) { result = GetDragResult(interp, Tcl_GetStringResult(interp)); } else { result = DROP_CANCEL; Tcl_BackgroundError(interp); } Tcl_DStringResult(interp, &savedResult); Tcl_Release(interp); return result; } /* *--------------------------------------------------------------------------- * * AcceptDrop -- * * Invokes a TCL procedure to handle the target's side of the drop. A Tcl * procedure is invoked, either one designated for this target by the user * (-ondrop) or a default TCL procedure. It is passed the following * arguments: * * widget The path name of the target. * x X-coordinate of the mouse relative to the * widget. * y Y-coordinate of the mouse relative to the * widget. * formats A list of data formats acceptable to both * the source and target. * button Button pressed. * state Key state. * timestamp Timestamp of transaction. * action Requested action from source. * * If the TCL procedure returns "cancel", this indicates that the drop was * not accepted by the target and the reject symbol should be displayed. * Otherwise one of the following strings may be recognized: * * "cancel" Drop was canceled. * "copy" Source data has been successfully copied. * "link" Target has made a link to the data. It's * Ok for the source to remove it's association * with the data, but not to delete the data * itself. * "move" Source data has been successfully copied, * it's Ok for the source to delete its * association with the data and the data itself. * * The result is relayed back to the source via another client message. * The source may or may not be waiting for the result. * * Results: * None. * * Side Effects: * A TCL procedure is invoked in the target to handle the drop event. * The result of the drop is sent (via another ClientMessage) to the * source. * *--------------------------------------------------------------------------- */ static int AcceptDrop( Dnd *dndPtr, /* Target where the drop event occurred. */ int x, int y, const char *formats, int button, int keyState, int timestamp) { Tcl_Interp *interp = dndPtr->interp; const char **cmd; Tcl_DString dString, savedResult; int result; if (dndPtr->motionCmd != NULL) { result = InvokeCallback(dndPtr, dndPtr->motionCmd, x, y, formats, button, keyState, timestamp); if (result != DROP_OK) { return result; } } if (dndPtr->leaveCmd != NULL) { InvokeCallback(dndPtr, dndPtr->leaveCmd, x, y, formats, button, keyState, timestamp); } Tcl_DStringInit(&dString); cmd = dndPtr->dropCmd; if (cmd != NULL) { const char **p; for (p = cmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } } else { Tcl_DStringAppendElement(&dString, "::blt::DndStdDrop"); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); dndPtr->dropX = x - Blt_RootX(dndPtr->tkwin); dndPtr->dropY = y - Blt_RootY(dndPtr->tkwin); Tcl_DStringAppendElement(&dString, "x"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->dropX)); Tcl_DStringAppendElement(&dString, "y"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->dropY)); Tcl_DStringAppendElement(&dString, "formats"); Tcl_DStringAppendElement(&dString, formats); Tcl_DStringAppendElement(&dString, "button"); Tcl_DStringAppendElement(&dString, Blt_Itoa(button)); Tcl_DStringAppendElement(&dString, "state"); Tcl_DStringAppendElement(&dString, Blt_Itoa(keyState)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(timestamp)); Tcl_Preserve(interp); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); result = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); if (result == TCL_OK) { result = GetAction(Tcl_GetStringResult(interp)); } else { result = DROP_CANCEL; Tcl_BackgroundError(interp); } Tcl_DStringResult(interp, &savedResult); Tcl_Release(interp); return result; } /* *--------------------------------------------------------------------------- * * HandleDropEvent -- * * Invokes a TCL procedure to handle the target's side of the drop. This * routine is triggered via a client message from the drag source * indicating that the token was dropped over this target. The fields of * the incoming message are: * * data.l[0] Message type. * data.l[1] Window Id of the source. * data.l[2] Screen X-coordinate of the pointer. * data.l[3] Screen Y-coordinate of the pointer. * data.l[4] Id of the drag&drop transaction. * * A TCL procedure is invoked, either one designated for this target by the * user (-ondrop) or a default TCL procedure. It is passed the following * arguments: * * widget The path name of the target. * x X-coordinate of the mouse relative to the * widget. * y Y-coordinate of the mouse relative to the * widget. * formats A list of data formats acceptable to both * the source and target. * * If the TCL procedure returns "cancel", this indicates that the drop was * not accepted by the target and the reject symbol should be displayed. * Otherwise one of the following strings may be recognized: * * "cancel" Drop was canceled. * "copy" Source data has been successfully copied. * "link" Target has made a link to the data. It's * Ok for the source to remove it's association * with the data, but not to delete the data * itself. * "move" Source data has been successfully copied, * it's Ok for the source to delete its * association with the data and the data itself. * * The result is relayed back to the source via another client message. * The source may or may not be waiting for the result. * * Results: * None. * * Side Effects: * A TCL procedure is invoked in the target to handle the drop event. * The result of the drop is sent (via another ClientMessage) to the * source. * *--------------------------------------------------------------------------- */ static void HandleDropEvent( Dnd *dndPtr, /* Target where the drop event * occurred. */ XEvent *eventPtr) /* Message sent from the drag source. */ { int button, keyState; int x, y; const char *formats; int result; struct DropInfo { int mesg; /* TS_DROP message. */ Window window; /* Source window. */ int timestamp; /* Transaction timestamp. */ int point; /* Root X-Y coordinate of pointer. */ int flags; /* Button/keystate information. */ } *dropPtr; DropPending pending; dropPtr = (struct DropInfo *)eventPtr->xclient.data.l; UNPACK(dropPtr->point, x, y); UNPACK(dropPtr->flags, button, keyState); /* Set up temporary bookkeeping for the drop transaction */ memset (&pending, 0, sizeof(pending)); pending.window = dropPtr->window; pending.display = eventPtr->xclient.display; pending.timestamp = dropPtr->timestamp; pending.protocol = PROTO_BLT; pending.packetSize = GetMaxPropertySize(pending.display); Tcl_DStringInit(&pending.dString); formats = GetSourceFormats(dndPtr, dropPtr->window, dropPtr->timestamp); dndPtr->pendingPtr = &pending; result = AcceptDrop(dndPtr, x, y, formats, button, keyState, dropPtr->timestamp); dndPtr->pendingPtr = NULL; /* Target-to-Source: Drop result message. */ SendClientMsg(dndPtr->display, dropPtr->window, dndPtr->dataPtr->mesgAtom, TS_DROP_RESULT, (int)Tk_WindowId(dndPtr->tkwin), dropPtr->timestamp, result, 0); FreeFormats(dndPtr); } /* *--------------------------------------------------------------------------- * * HandleDragEvent -- * * Invokes one of 3 TCL procedures to handle the target's side of the drag * operation. This routine is triggered via a ClientMessage from the drag * source indicating that the token as either entered, moved, or left this * target. The source sends messages only if TCL procedures on the target * have been defined to watch the events. The message_type field can be * either * * ST_DRAG_ENTER The mouse has entered the target. * ST_DRAG_MOTION The mouse has moved within the target. * ST_DRAG_LEAVE The mouse has left the target. * * The data fields are as follows: * data.l[0] Message type. * data.l[1] Window Id of the source. * data.l[2] Timestamp of the drag&drop transaction. * data.l[3] Root X-Y coordinate of the pointer. * data.l[4] Button and key state information. * * For any of the 3 TCL procedures, the following arguments are passed: * * widget The path name of the target. * x X-coordinate of the mouse in the widget. * y Y-coordinate of the mouse in the widget. * formats A list of data formats acceptable to both * the source and target. * * If the TCL procedure returns "cancel", this indicates that the drag * operation has been canceled and the reject symbol should be displayed. * Otherwise it should return a boolean: * * true Target will accept drop. * false Target will not accept the drop. * * The purpose of the Enter and Leave procedure is to allow the target to * provide visual feedback that the drop can occur or not. The Motion * procedure is for cases where the drop area is a smaller area within the * target, such as a canvas item on a canvas. The procedure can determine * (based upon the X-Y coordinates) whether the pointer is over the canvas * item and return a value accordingly. * * The result of the TCL procedure is then relayed back to the source by a * ClientMessage. * * Results: * None. * * Side Effects: * A TCL procedure is invoked in the target to handle the drag event. * The result of the drag is sent (via another ClientMessage) to the * source. * *--------------------------------------------------------------------------- */ static void HandleDragEvent( Dnd *dndPtr, /* Target where the drag event * occurred. */ XEvent *eventPtr) /* Message sent from the drag source. */ { const char **cmd; int resp; int x, y; int button, keyState; const char *formats; struct DragInfo { int mesg; /* Drag-and-drop message type. */ Window window; /* Source window. */ int timestamp; /* Transaction timestamp. */ int point; /* Root X-Y coordinate of pointer. */ int flags; /* Button/keystate information. */ } *dragPtr; dragPtr = (struct DragInfo *)eventPtr->xclient.data.l; cmd = NULL; switch (dragPtr->mesg) { case ST_DRAG_ENTER: cmd = dndPtr->enterCmd; break; case ST_DRAG_MOTION: cmd = dndPtr->motionCmd; break; case ST_DRAG_LEAVE: cmd = dndPtr->leaveCmd; break; } if (cmd == NULL) { return; /* Nothing to do. */ } UNPACK(dragPtr->point, x, y); UNPACK(dragPtr->flags, button, keyState); formats = GetSourceFormats(dndPtr, dragPtr->window, dragPtr->timestamp); resp = InvokeCallback(dndPtr, cmd, x, y, formats, button, keyState, dragPtr->timestamp); /* Target-to-Source: Drag result message. */ SendClientMsg(dndPtr->display, dragPtr->window, dndPtr->dataPtr->mesgAtom, TS_DRAG_STATUS, (int)Tk_WindowId(dndPtr->tkwin), dragPtr->timestamp, resp, 0); } /* *--------------------------------------------------------------------------- * * DndEventProc -- * * Invoked by Tk_HandleEvent whenever a DestroyNotify event is received * on a registered drag&drop source widget. * *--------------------------------------------------------------------------- */ static int DndEventProc( ClientData clientData, /* Drag&drop record. */ XEvent *eventPtr) /* Event description. */ { Dnd *dndPtr = clientData; if (eventPtr->xany.window != Tk_WindowId(dndPtr->tkwin)) { return 0; } if (eventPtr->type == DestroyNotify) { dndPtr->tkwin = NULL; dndPtr->flags |= DND_DELETED; Tcl_EventuallyFree(dndPtr, DestroyDnd); return 0; /* Other handlers have to see this event too.*/ } else if (eventPtr->type == ButtonPress) { dndPtr->keyState = eventPtr->xbutton.state; dndPtr->button = eventPtr->xbutton.button; return 0; } else if (eventPtr->type == ButtonRelease) { dndPtr->keyState = eventPtr->xbutton.state; dndPtr->button = eventPtr->xbutton.button; return 0; } else if (eventPtr->type == MotionNotify) { dndPtr->keyState = eventPtr->xmotion.state; return 0; } else if ((eventPtr->type == ClientMessage) && (eventPtr->xclient.message_type == dndPtr->dataPtr->mesgAtom)) { int result; switch((unsigned int)eventPtr->xclient.data.l[0]) { case TS_START_DROP: DoDrop(dndPtr, eventPtr); return 1; case TS_DROP_RESULT: result = eventPtr->xclient.data.l[MESG_RESPONSE]; dndPtr->tokenPtr->status = result; if (result == DROP_CANCEL) { CancelDrag(dndPtr); } else if (result == DROP_FAIL) { EventuallyRedrawToken(dndPtr); } else { dndPtr->tokenPtr->nSteps = 10; FadeToken(dndPtr); } if (dndPtr->resultCmd != NULL) { DropFinished(dndPtr, eventPtr); } return 1; case TS_DRAG_STATUS: result = eventPtr->xclient.data.l[MESG_RESPONSE]; ChangeToken(dndPtr, result); return 1; case ST_DROP: HandleDropEvent(dndPtr, eventPtr); return 1; case ST_DRAG_ENTER: case ST_DRAG_MOTION: case ST_DRAG_LEAVE: HandleDragEvent(dndPtr, eventPtr); return 1; } } return 0; } static void SendPointerMessage( Dnd *dndPtr, /* Source drag&drop manager. */ int eventType, /* Type of event to relay. */ Winfo *windowPtr, /* Generic window information. */ int x, int y) /* Root coordinates of mouse. */ { /* Source-to-Target: Pointer event messages. */ SendClientMsg( dndPtr->display, /* Display of recipient window. */ windowPtr->window, /* Recipient window. */ dndPtr->dataPtr->mesgAtom, /* Message type. */ eventType, /* Data 1 */ (int)Tk_WindowId(dndPtr->tkwin), /* Data 2 */ dndPtr->timestamp, /* Data 3 */ PACK(x, y), /* Data 4 */ PACK(dndPtr->button, dndPtr->keyState)); /* Data 5 */ /* Don't wait the response. */ } static void RelayEnterEvent(Dnd *dndPtr, Winfo *windowPtr, int x, int y) { if ((windowPtr != NULL) && (windowPtr->eventFlags & WATCH_ENTER)) { SendPointerMessage(dndPtr, ST_DRAG_ENTER, windowPtr, x, y); } } static void RelayLeaveEvent(Dnd *dndPtr, Winfo *windowPtr, int x, int y) { if ((windowPtr != NULL) && (windowPtr->eventFlags & WATCH_LEAVE)) { SendPointerMessage(dndPtr, ST_DRAG_LEAVE, windowPtr, x, y); } } static void RelayMotionEvent(Dnd *dndPtr, Winfo *windowPtr, int x, int y) { if ((windowPtr != NULL) && (windowPtr->eventFlags & WATCH_MOTION)) { SendPointerMessage(dndPtr, ST_DRAG_MOTION, windowPtr, x, y); } } static void RelayDropEvent(Dnd *dndPtr, Winfo *windowPtr, int x, int y) { SendPointerMessage(dndPtr, ST_DROP, windowPtr, x, y); } /* *--------------------------------------------------------------------------- * * FreeWinfo -- * *--------------------------------------------------------------------------- */ static void FreeWinfo(Winfo *windowPtr) /* Window rep to be freed */ { Winfo *childPtr; Blt_ChainLink link; for (link = Blt_Chain_FirstLink(windowPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { childPtr = Blt_Chain_GetValue(link); FreeWinfo(childPtr); /* Recursively free children. */ } if (windowPtr->matches != NULL) { Blt_Free(windowPtr->matches); } Blt_Chain_Destroy(windowPtr->chain); Blt_Free(windowPtr); } /* *--------------------------------------------------------------------------- * * GetWinfo -- * * Invoked during "drag" operations. Digs into the root window * hierarchy and caches the window-related information. * If the current point lies over an uninitialized window (i.e. * one that already has an allocated Winfo structure, but has * not been filled in yet), this routine is called to query * window coordinates. If the window has any children, more * uninitialized Winfo structures are allocated. Further queries * will cause these structures to be initialized in turn. * *--------------------------------------------------------------------------- */ static void GetWinfo(Display *display, Winfo *windowPtr) /* window rep to be initialized */ { int visible; if (windowPtr->initialized) { return; } /* Query for the window coordinates. */ visible = GetWindowArea(display, windowPtr); if (visible) { Blt_ChainLink link; Blt_Chain chain; Winfo *childPtr; /* Add offset from parent's origin to coordinates */ if (windowPtr->parentPtr != NULL) { windowPtr->x1 += windowPtr->parentPtr->x1; windowPtr->y1 += windowPtr->parentPtr->y1; windowPtr->x2 += windowPtr->parentPtr->x1; windowPtr->y2 += windowPtr->parentPtr->y1; } /* * Collect a list of child windows, sorted in z-order. The * topmost window will be first in the list. */ chain = GetWindowZOrder(display, windowPtr->window); /* Add and initialize extra slots if needed. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { childPtr = Blt_AssertCalloc(1, sizeof(Winfo)); childPtr->initialized = FALSE; childPtr->window = (Window)Blt_Chain_GetValue(link); childPtr->parentPtr = windowPtr; Blt_Chain_SetValue(link, childPtr); } windowPtr->chain = chain; } else { /* If it's not viewable don't bother doing anything else. */ windowPtr->x1 = windowPtr->y1 = windowPtr->x2 = windowPtr->y2 = -1; windowPtr->chain = NULL; } windowPtr->initialized = TRUE; } /* *--------------------------------------------------------------------------- * * InitRoot -- * * Invoked at the start of a "drag" operation to capture the * positions of all windows on the current root. Queries the * entire window hierarchy and determines the placement of each * window. Queries the "BltDndTarget" property info where * appropriate. This information is used during the drag * operation to determine when the drag&drop token is over a * valid drag&drop target. * * Results: * Returns the record for the root window, which contains records * for all other windows as children. * *--------------------------------------------------------------------------- */ static Winfo * InitRoot(Dnd *dndPtr) { Winfo *rootPtr; rootPtr = Blt_AssertCalloc(1, sizeof(Winfo)); rootPtr->window = DefaultRootWindow(dndPtr->display); dndPtr->windowPtr = NULL; GetWinfo(dndPtr->display, rootPtr); return rootPtr; } static int ParseProperty(Tcl_Interp *interp, Dnd *dndPtr, Winfo *windowPtr, char *data) { int argc; const char **argv; int eventFlags; Tcl_DString dString; int count; int i; if (Tcl_SplitList(interp, data, &argc, &argv) != TCL_OK) { return TCL_ERROR; /* Malformed property list. */ } if (argc < 1) { Tcl_AppendResult(interp, "Malformed property \"", data, "\"", (char *)NULL); goto error; } if (Tcl_GetInt(interp, argv[PROP_WATCH_FLAGS], &eventFlags) != TCL_OK) { goto error; } /* target flags, type1, type2, ... */ /* * The target property contains a list of possible formats. * Compare this with what formats the source is willing to * convert and compress the list down to just the matching * formats. It's up to the target to request the specific * type (or types) that it wants. */ count = 0; Tcl_DStringInit(&dString); if (dndPtr->reqFormats == NULL) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; char *fmt; for (i = 1; i < argc; i++) { for(hPtr = Blt_FirstHashEntry(&dndPtr->getDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { fmt = Blt_GetHashKey(&dndPtr->getDataTable, hPtr); if ((*fmt == argv[i][0]) && (strcmp(fmt, argv[i]) == 0)) { Tcl_DStringAppendElement(&dString, argv[i]); count++; break; } } } } else { const char **s; for (i = 1; i < argc; i++) { for (s = dndPtr->reqFormats; *s != NULL; s++) { if ((**s == argv[i][0]) && (strcmp(*s, argv[i]) == 0)) { Tcl_DStringAppendElement(&dString, argv[i]); count++; } } } } if (count == 0) { #ifdef notdef fprintf(stderr, "source/target mismatch: No matching types\n"); #endif return TCL_BREAK; } if (eventFlags != 0) { SetProperty(dndPtr->tkwin, dndPtr->dataPtr->formatsAtom, Tcl_DStringValue(&dString)); windowPtr->matches = NULL; } else { windowPtr->matches = Blt_AssertStrdup(Tcl_DStringValue(&dString)); } Tcl_DStringFree(&dString); windowPtr->eventFlags = eventFlags; return TCL_OK; error: Blt_Free(argv); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * OverTarget -- * * Checks to see if a compatible drag&drop target exists at the * given position. A target is "compatible" if it is a drag&drop * window, and if it has a handler that is compatible with the * current source window. * * Results: * Returns a pointer to a structure describing the target, or NULL * if no compatible target is found. * *--------------------------------------------------------------------------- */ static Winfo * OverTarget(Dnd *dndPtr) /* drag&drop source window */ { Tcl_Interp *interp = dndPtr->interp; int x, y; int vx, vy; int dummy; Winfo *windowPtr; /* * If no window info has been been gathered yet for this target, * then abort this call. This probably means that the token is * moved before it has been properly built. */ if (dndPtr->rootPtr == NULL) { fprintf(stderr, "rootPtr not initialized\n"); return NULL; } /* Adjust current location for virtual root windows. */ Tk_GetVRootGeometry(dndPtr->tkwin, &vx, &vy, &dummy, &dummy); x = dndPtr->x + vx; y = dndPtr->y + vy; windowPtr = FindTopWindow(dndPtr, x, y); if (windowPtr == NULL) { return NULL; /* Not over a window. */ } if ((!dndPtr->selfTarget) && (Tk_WindowId(dndPtr->tkwin) == windowPtr->window)) { return NULL; /* If the self-target flag isn't set, * don't allow the source window to * drop onto itself. */ } if (!windowPtr->lookedForProperty) { unsigned char *data; int result; windowPtr->lookedForProperty = TRUE; /* See if this window has a "BltDndTarget" property. */ data = GetProperty(dndPtr->display, windowPtr->window, dndPtr->dataPtr->targetAtom); if (data == NULL) { #ifdef notdef fprintf(stderr, "No property on 0x%x\n", windowPtr->window); #endif return NULL; /* No such property on window. */ } result = ParseProperty(interp, dndPtr, windowPtr, (char *)data); XFree(data); if (result == TCL_BREAK) { #ifdef notdef fprintf(stderr, "No matching formats\n"); #endif return NULL; } if (result != TCL_OK) { Tcl_BackgroundError(interp); return NULL; /* Malformed property list. */ } windowPtr->isTarget = TRUE; } if (!windowPtr->isTarget) { return NULL; } return windowPtr; } /* *--------------------------------------------------------------------------- * * AddTargetProperty -- * * Attaches a drag&drop property to the given target window. * This property allows us to recognize the window later as a * valid target. It also stores important information including * the interpreter managing the target and the pathname of the * target window. Usually this routine is called when the target * is first registered or first exposed (so that the X-window * really exists). * *--------------------------------------------------------------------------- */ static void AddTargetProperty(Dnd *dndPtr) /* drag&drop target window data */ { Tcl_DString dString; Blt_HashEntry *hPtr; unsigned int eventFlags; Blt_HashSearch cursor; char *fmt; char string[200]; Tcl_DStringInit(&dString); /* * Each target window's dnd property contains * * 1. Mouse event flags. * 2. List of all the data types that can be handled. If none * are listed, then all can be handled. */ eventFlags = 0; if (dndPtr->enterCmd != NULL) { eventFlags |= WATCH_ENTER; } if (dndPtr->leaveCmd != NULL) { eventFlags |= WATCH_LEAVE; } if (dndPtr->motionCmd != NULL) { eventFlags |= WATCH_MOTION; } sprintf_s(string, 200, "0x%x", eventFlags); Tcl_DStringAppendElement(&dString, string); for (hPtr = Blt_FirstHashEntry(&dndPtr->setDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { fmt = Blt_GetHashKey(&dndPtr->setDataTable, hPtr); Tcl_DStringAppendElement(&dString, fmt); } SetProperty(dndPtr->tkwin, dndPtr->dataPtr->targetAtom, Tcl_DStringValue(&dString)); dndPtr->targetPropertyExists = TRUE; Tcl_DStringFree(&dString); } static void CancelDrag(Dnd *dndPtr) { if (dndPtr->flags & DND_INITIATED) { dndPtr->tokenPtr->nSteps = 10; SnapToken(dndPtr); StopActiveCursor(dndPtr); if (dndPtr->cursor == None) { Tk_UndefineCursor(dndPtr->tkwin); } else { Tk_DefineCursor(dndPtr->tkwin, dndPtr->cursor); } } if (dndPtr->rootPtr != NULL) { FreeWinfo(dndPtr->rootPtr); dndPtr->rootPtr = NULL; } } static int DragInit(Dnd *dndPtr, int x, int y) { Token *tokenPtr = dndPtr->tokenPtr; int result; Winfo *newPtr; assert((dndPtr->flags & DND_ACTIVE) == DND_SELECTED); if (dndPtr->rootPtr != NULL) { FreeWinfo(dndPtr->rootPtr); } dndPtr->rootPtr = InitRoot(dndPtr); /* Reset information cache. */ dndPtr->flags &= ~DND_VOIDED; dndPtr->x = x; /* Save current location. */ dndPtr->y = y; result = TRUE; Tcl_Preserve(dndPtr); if (dndPtr->packageCmd != NULL) { Tcl_DString dString, savedResult; Tcl_Interp *interp = dndPtr->interp; int status; const char **p; int rx, ry; Tcl_DStringInit(&dString); for (p = dndPtr->packageCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); rx = dndPtr->dragX - Blt_RootX(dndPtr->tkwin); ry = dndPtr->dragY - Blt_RootY(dndPtr->tkwin); Tcl_DStringAppendElement(&dString, "x"); Tcl_DStringAppendElement(&dString, Blt_Itoa(rx)); Tcl_DStringAppendElement(&dString, "y"); Tcl_DStringAppendElement(&dString, Blt_Itoa(ry)); Tcl_DStringAppendElement(&dString, "button"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->button)); Tcl_DStringAppendElement(&dString, "state"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->keyState)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(dndPtr->timestamp)); Tcl_DStringAppendElement(&dString, "token"); Tcl_DStringAppendElement(&dString, Tk_PathName(tokenPtr->tkwin)); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); dndPtr->flags |= DND_IN_PACKAGE; status = Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)); dndPtr->flags &= ~DND_IN_PACKAGE; if (status == TCL_OK) { result = GetDragResult(interp, Tcl_GetStringResult(interp)); } else { Tcl_BackgroundError(interp); } Tcl_DStringFree(&dString); Tcl_DStringResult(interp, &savedResult); Tcl_DStringFree(&dString); if (status != TCL_OK) { HideToken(dndPtr); Tcl_Release(dndPtr); return TCL_ERROR; } } if (dndPtr->flags & DND_VOIDED) { HideToken(dndPtr); Tcl_Release(dndPtr); return TCL_RETURN; } if ((!result) || (dndPtr->flags & DND_DELETED)) { HideToken(dndPtr); Tcl_Release(dndPtr); return TCL_RETURN; } Tcl_Release(dndPtr); if (dndPtr->cursor != None) { Tk_Cursor cursor; /* Save the old cursor */ cursor = GetWidgetCursor(dndPtr->interp, dndPtr->tkwin); if (dndPtr->cursor != None) { Tk_FreeCursor(dndPtr->display, dndPtr->cursor); } dndPtr->cursor = cursor; if (dndPtr->cursors != NULL) { /* Temporarily install the drag-and-drop cursor. */ Tk_DefineCursor(dndPtr->tkwin, dndPtr->cursors[0]); } } if (Tk_WindowId(tokenPtr->tkwin) == None) { Tk_MakeWindowExist(tokenPtr->tkwin); } if (!Tk_IsMapped(tokenPtr->tkwin)) { Tk_MapWindow(tokenPtr->tkwin); } dndPtr->flags |= DND_INITIATED; newPtr = OverTarget(dndPtr); RelayEnterEvent(dndPtr, newPtr, x, y); dndPtr->windowPtr = newPtr; tokenPtr->status = (newPtr != NULL) ? DROP_OK : DROP_CONTINUE; if (tokenPtr->lastStatus != tokenPtr->status) { EventuallyRedrawToken(dndPtr); } MoveToken(dndPtr); /* Move token to current drag point. */ RaiseToken(dndPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CancelOp -- * * Cancels the current drag&drop operation for the source. Calling * this operation does not affect the transfer of data from the * source to the target, once the drop has been made. From the * source's point of view, the drag&drop operation is already over. * * Example: dnd cancel .widget * * Results: * A standard TCL result. * * Side Effects: * Hides the token and sets a flag indicating that further "drag" * and "drop" operations should be ignored. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CancelOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Dnd *dndPtr; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (!dndPtr->isSource) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(dndPtr->tkwin), "\" is not a registered drag&drop source.", (char *)NULL); return TCL_ERROR; } /* Send the target a Leave message so it can change back. */ RelayLeaveEvent(dndPtr, dndPtr->windowPtr, 0, 0); CancelDrag(dndPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Called to process an (objc,objv) list to configure (or * reconfigure) a drag&drop widget. * *--------------------------------------------------------------------------- */ /* ARGSUSED*/ static int CgetOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Dnd *dndPtr; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, dndPtr->tkwin, configSpecs, (char *)dndPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Called to process an (objc,objv) list to configure (or * reconfigure) a drag&drop widget. * *--------------------------------------------------------------------------- */ static int ConfigureOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, /* current interpreter */ int objc, /* number of arguments */ Tcl_Obj *const *objv) /* argument strings */ { Dnd *dndPtr; int flags; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } flags = BLT_CONFIG_OBJV_ONLY; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, dndPtr->tkwin, configSpecs, (char *)dndPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, dndPtr->tkwin, configSpecs, (char *)dndPtr, objv[3], flags); } if (Blt_ConfigureWidgetFromObj(interp, dndPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)dndPtr, flags) != TCL_OK) { return TCL_ERROR; } if (ConfigureDnd(interp, dndPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the drag&drop manager from the widget. If a "-source" * or "-target" switch is present, only that component of the * drag&drop manager is shutdown. The manager is not deleted * unless both the target and source components are shutdown. * * Example: dnd delete .widget * * Results: * A standard TCL result. * * Side Effects: * Deletes the drag&drop manager. Also the source and target window * properties are removed from the widget. * * ------------------------------------------------------------------------ */ static int DeleteOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for(i = 3; i < objc; i++) { Dnd *dndPtr; if (GetDndFromObj(clientData, interp, objv[i], &dndPtr) != TCL_OK) { return TCL_ERROR; } dndPtr->flags |= DND_DELETED; Tcl_EventuallyFree(dndPtr, DestroyDnd); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectOp -- * * Initializes a drag&drop transaction. Typically this operation * is called from a ButtonPress event on a source widget. The * window information cache is initialized, and the token is * initialized and displayed. * * Example: dnd pickup .widget x y * * Results: * A standard TCL result. * * Side Effects: * The token is initialized and displayed. This may require invoking * a user-defined package command. The window information cache is * also initialized. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SelectOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Dnd *dndPtr; int x, y, timestamp; Token *tokenPtr; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (!dndPtr->isSource) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(dndPtr->tkwin), "\" is not a registered drag&drop source.", (char *)NULL); return TCL_ERROR; } tokenPtr = dndPtr->tokenPtr; if (tokenPtr == NULL) { Tcl_AppendResult(interp, "no drag&drop token created for \"", objv[2], "\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[5], &timestamp) != TCL_OK) { return TCL_ERROR; } if (dndPtr->flags & (DND_IN_PACKAGE | DND_ACTIVE | DND_VOIDED)) { return TCL_OK; } if (tokenPtr->timerToken != NULL) { HideToken(dndPtr); /* If the user selected again before the * token snap/melt has completed, first * disable the token timer callback. */ } /* At this point, simply save the starting pointer location. */ dndPtr->dragX = x, dndPtr->dragY = y; GetTokenPosition(dndPtr, x, y); tokenPtr->startX = tokenPtr->x; tokenPtr->startY = tokenPtr->y; dndPtr->timestamp = timestamp; dndPtr->flags |= DND_SELECTED; if (dndPtr->dragStart == 0) { if (DragInit(dndPtr, x, y) == TCL_ERROR) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DragOp -- * * Continues the drag&drop transaction. Typically this operation * is called from a button Motion event on a source widget. Pointer * event messages are possibly sent to the target, indicating Enter, * Leave, and Motion events. * * Example: dnd drag .widget x y * * Results: * A standard TCL result. * * Side Effects: * Pointer events are relayed to the target (if the mouse is over * one). * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DragOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Winfo *newPtr, *oldPtr; Dnd *dndPtr; int x, y; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (!dndPtr->isSource) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(dndPtr->tkwin), "\" is not a registered drag&drop source.", (char *)NULL); return TCL_ERROR; } if (dndPtr->tokenPtr == NULL) { Tcl_AppendResult(interp, "no drag&drop token created for \"", objv[2], "\"", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } if ((dndPtr->flags & DND_SELECTED) == 0) { return TCL_OK; /* Re-entered this routine. */ } /* * The following code gets tricky because the package command may * call "update" or "tkwait". A motion event may then trigger * this routine, before the token has been initialized. Until the * package command finishes, no target messages are sent and drops * are silently ignored. Note that we do still track mouse * movements, so that when the package command completes, it will * have the latest pointer position. */ dndPtr->x = x; /* Save current location. */ dndPtr->y = y; if (dndPtr->flags & DND_IN_PACKAGE) { return TCL_OK; /* Re-entered this routine. */ } if ((dndPtr->flags & DND_INITIATED) == 0) { int dx, dy; int result; dx = dndPtr->dragX - x; dy = dndPtr->dragY - y; if ((ABS(dx) < dndPtr->dragStart) && (ABS(dy) < dndPtr->dragStart)) { return TCL_OK; } result = DragInit(dndPtr, x, y); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_RETURN) { return TCL_OK; } } if (dndPtr->flags & DND_VOIDED) { return TCL_OK; } oldPtr = dndPtr->windowPtr; newPtr = OverTarget(dndPtr); if (newPtr == oldPtr) { RelayMotionEvent(dndPtr, oldPtr, x, y); dndPtr->windowPtr = oldPtr; } else { RelayLeaveEvent(dndPtr, oldPtr, x, y); RelayEnterEvent(dndPtr, newPtr, x, y); dndPtr->windowPtr = newPtr; } dndPtr->tokenPtr->status = (newPtr != NULL) ? DROP_OK : DROP_CONTINUE; if (dndPtr->tokenPtr->lastStatus != dndPtr->tokenPtr->status) { EventuallyRedrawToken(dndPtr); } MoveToken(dndPtr); /* Move token to current drag point. */ RaiseToken(dndPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DropOp -- * * Finishes the drag&drop transaction by dropping the data on the * selected target. Typically this operation is called from a * ButtonRelease event on a source widget. Note that a Leave message * is always sent to the target so that is can un-highlight itself. * The token is hidden and a drop message is sent to the target. * * Example: dnd drop .widget x y * * Results: * A standard TCL result. * * Side Effects: * The token is hidden and a drop message is sent to the target. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DropOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Winfo *windowPtr; Dnd *dndPtr; int x, y; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (!dndPtr->isSource) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(dndPtr->tkwin), "\" is not a registered drag&drop source.", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } dndPtr->x = x; /* Save drag&drop location */ dndPtr->y = y; if ((dndPtr->flags & DND_INITIATED) == 0) { return TCL_OK; /* Never initiated any drag operation. */ } if (dndPtr->flags & DND_VOIDED) { HideToken(dndPtr); return TCL_OK; } windowPtr = OverTarget(dndPtr); if (windowPtr != NULL) { if (windowPtr->matches != NULL) { SetProperty(dndPtr->tkwin, dndPtr->dataPtr->formatsAtom, windowPtr->matches); } MoveToken(dndPtr); /* Move token to current drag point. */ RaiseToken(dndPtr); RelayDropEvent(dndPtr, windowPtr, x, y); #ifdef notdef tokenPtr->nSteps = 10; FadeToken(dndPtr); #endif } else { CancelDrag(dndPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * GetdataOp -- * * Registers one or more data formats with a drag&drop source. * Each format has a TCL command associated with it. This command * is automatically invoked whenever data is pulled from the source * to a target requesting the data in that particular format. The * purpose of the TCL command is to get the data from in the * application. When the TCL command is invoked, special percent * substitutions are made: * * %# Drag&drop transaction timestamp. * %W Source widget. * * If a converter (command) already exists for a format, it * overwrites the existing command. * * Example: dnd getdata .widget "color" { %W cget -bg } * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int GetdataOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Dnd *dndPtr; int i; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; /* Return list of source data formats */ for (hPtr = Blt_FirstHashEntry(&dndPtr->getDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_AppendElement(interp, Blt_GetHashKey(&dndPtr->getDataTable, hPtr)); } return TCL_OK; } if (objc == 4) { Blt_HashEntry *hPtr; const char *string; const char **argv; string = Tcl_GetString(objv[3]); hPtr = Blt_FindHashEntry(&dndPtr->getDataTable, string); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find handler for format \"", string, "\" for source \"", Tk_PathName(dndPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } argv = Blt_GetHashValue(hPtr); if (argv == NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "", -1); } else { Tcl_SetObjResult(interp, PrintList(interp, argv)); } return TCL_OK; } for (i = 3; i < objc; i += 2) { Blt_HashEntry *hPtr; const char **argv; int argc; int isNew; hPtr = Blt_CreateHashEntry(&dndPtr->getDataTable, Tcl_GetString(objv[i]), &isNew); if (!isNew) { argv = Blt_GetHashValue(hPtr); Blt_Free(argv); } if (Tcl_SplitList(interp, Tcl_GetString(objv[i + 1]), &argc, &argv) != TCL_OK) { Blt_DeleteHashEntry(&dndPtr->getDataTable, hPtr); return TCL_ERROR; } Blt_SetHashValue(hPtr, argv); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * Returns the names of all the drag&drop managers. If either * a "-source" or "-target" switch is present, only the names of * managers acting as sources or targets respectively are returned. * A pattern argument may also be given. Only those managers * matching the pattern are returned. * * Examples: dnd names * dnd names -source * dnd names -target * dnd names .*label * Results: * A standard TCL result. A TCL list of drag&drop manager * names is returned. * *--------------------------------------------------------------------------- */ static int NamesOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DndInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch cursor; Dnd *dndPtr; int findSources, findTargets; char *string; Tcl_Obj *listObjPtr; findSources = findTargets = TRUE; if (objc > 2) { string = Tcl_GetString(objv[2]); if ((string[0] == '-') && (strcmp(string, "-source") == 0)) { findTargets = FALSE; objc--, objv++; } else if ((string[0] == '-') && (strcmp(string, "-target") == 0)) { findSources = FALSE; objc--, objv++; } } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (hPtr = Blt_FirstHashEntry(&dataPtr->dndTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { dndPtr = Blt_GetHashValue(hPtr); if (objc > 3) { string = Tcl_GetString(objv[3]); if (!Tcl_StringMatch(Tk_PathName(dndPtr->tkwin), string)) { continue; } } if (((findSources) && (dndPtr->isSource)) || ((findTargets) && (dndPtr->isTarget))) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(Tk_PathName(dndPtr->tkwin), -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } #ifdef notdef RunCommand(Dnd *dndPtr, char **formatCmd) { Tcl_DString dString, savedResult; Tcl_Obj **objv; char **p; objc = 0; for (objc = 0, p = formatCmd; *p != NULL; p++) { objc++; } objc += 12; objv = Blt_AssertMalloc(sizeof(Tcl_Obj *) * (objc + 1)); for (i = 0; p = formatCmd; *p != NULL; p++, i++) { objv[i] = Tcl_NewStringObj(*p, -1); } objv[i++] = Tcl_NewStringObj(Tk_PathName(dndPtr->tkwin), -1); objv[i++] = Tcl_NewStringObj("x", 1); objv[i++] = Tcl_NewStringObj("x", 1); objv[i++] = Tcl_NewIntObj(dndPtr->dropX); objv[i++] = Tcl_NewStringObj("y", 1); objv[i++] = Tcl_NewIntObj(dndPtr->dropY); objv[i++] = Tcl_NewStringObj("timestamp", 9); objv[i++] = Tcl_NewStringObj(Blt_Utoa(dndPtr->pendingPtr->timestamp), -1); objv[i++] = Tcl_NewStringObj("format", 6); objv[i++] = Tcl_NewStringObj(fmt, -1); objv[i++] = Tcl_NewStringObj("value", 5); objv[i++] = Tcl_NewStringObj( Tcl_DStringValue(&dndPtr->pendingPtr->dString), Tcl_DStringLength(&dndPtr->pendingPtr->dString)); for (i = 0; i < objc; i++) { Tcl_IncrRefCount(objv[i]); } Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); if (Tcl_EvalObjv(interp, objc, objv, 0) != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DStringResult(interp, &savedResult); for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objv[i]); } } #endif /* *--------------------------------------------------------------------------- * * PullOp -- * * Pulls the current data from the source in the given format. * application. * * dnd pull .widget format data * * Results: * A standard TCL result. * * Side Effects: * Invokes the target's data converter to store the data. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PullOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Dnd *dndPtr; /* drag&drop source record */ int result; char **formatCmd; char *fmt; Blt_HashEntry *hPtr; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (!dndPtr->isTarget) { Tcl_AppendResult(interp, "widget \"", Tk_PathName(dndPtr->tkwin), "\" is not a registered drag&drop target.", (char *)NULL); return TCL_ERROR; } fmt = Tcl_GetString(objv[3]); hPtr = Blt_FindHashEntry(&dndPtr->setDataTable, fmt); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find format \"", fmt, "\" in target \"", Tk_PathName(dndPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } formatCmd = Blt_GetHashValue(hPtr); if (dndPtr->pendingPtr == NULL) { Tcl_AppendResult(interp, "no drop in progress", (char *)NULL); return TCL_ERROR; } CompleteDataTransaction(dndPtr, fmt, dndPtr->pendingPtr); result = TCL_OK; if (Tcl_DStringLength(&dndPtr->pendingPtr->dString) > 0) { Tcl_DString dString, savedResult; char **p; Tcl_DStringInit(&dString); for (p = formatCmd; *p != NULL; p++) { Tcl_DStringAppendElement(&dString, *p); } Tcl_DStringAppendElement(&dString, Tk_PathName(dndPtr->tkwin)); Tcl_DStringAppendElement(&dString, "x"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->dropX)); Tcl_DStringAppendElement(&dString, "y"); Tcl_DStringAppendElement(&dString, Blt_Itoa(dndPtr->dropY)); Tcl_DStringAppendElement(&dString, "timestamp"); Tcl_DStringAppendElement(&dString, Blt_Utoa(dndPtr->pendingPtr->timestamp)); Tcl_DStringAppendElement(&dString, "format"); Tcl_DStringAppendElement(&dString, Tcl_GetString(objv[3])); Tcl_DStringAppendElement(&dString, "value"); Tcl_DStringAppendElement(&dString, Tcl_DStringValue(&dndPtr->pendingPtr->dString)); Tcl_DStringInit(&savedResult); Tcl_DStringGetResult(interp, &savedResult); if (Tcl_GlobalEval(interp, Tcl_DStringValue(&dString)) != TCL_OK) { Tcl_BackgroundError(interp); } Tcl_DStringResult(interp, &savedResult); Tcl_DStringFree(&dString); } return result; } /* *--------------------------------------------------------------------------- * * SetdataOp -- * * Registers one or more data formats with a drag&drop target. * Each format has a TCL command associated with it. This command * is automatically invoked whenever data arrives from a source * to be converted to that particular format. The purpose of the * command is to set the data somewhere in the application (either * using a TCL command or variable). When the TCL command is invoked, * special percent substitutions are made: * * %# Drag&drop transaction timestamp. * %W Target widget. * %v Data value transfered from the source to * be converted into the correct format. * * If a converter (command) already exists for a format, it * overwrites the existing command. * * Example: dnd setdata .widget color { . configure -bg %v } * * Results: * A standard TCL result. * *--------------------------------------------------------------------------- */ static int SetdataOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Dnd *dndPtr; Blt_HashEntry *hPtr; Blt_HashSearch cursor; int i; if (GetDndFromObj(clientData, interp, objv[2], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { /* Show target handler data formats */ for (hPtr = Blt_FirstHashEntry(&dndPtr->setDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Tcl_AppendElement(interp, Blt_GetHashKey(&dndPtr->setDataTable, hPtr)); } return TCL_OK; } if (objc == 4) { const char **argv; hPtr = Blt_FindHashEntry(&dndPtr->setDataTable, objv[3]); if (hPtr == NULL) { Tcl_AppendResult(interp, "can't find handler for format \"", objv[3], "\" for target \"", Tk_PathName(dndPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } argv = Blt_GetHashValue(hPtr); if (argv == NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), "", -1); } else { Tcl_SetObjResult(interp, PrintList(interp, argv)); } return TCL_OK; } for (i = 3; i < objc; i += 2) { const char **argv; int isNew, argc; hPtr = Blt_CreateHashEntry(&dndPtr->setDataTable, Tcl_GetString(objv[i]), &isNew); if (!isNew) { argv = Blt_GetHashValue(hPtr); Blt_Free(argv); } if (Tcl_SplitList(interp, Tcl_GetString(objv[i + 1]), &argc, &argv) != TCL_OK) { Blt_DeleteHashEntry(&dndPtr->setDataTable, hPtr); return TCL_ERROR; } Blt_SetHashValue(hPtr, argv); } AddTargetProperty(dndPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RegisterOp -- * * dnd register .window *--------------------------------------------------------------------------- */ static int RegisterOp( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { DndInterpData *dataPtr = clientData; Tk_Window tkwin; Blt_HashEntry *hPtr; Dnd *dndPtr; int isNew; tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), dataPtr->tkMain); if (tkwin == NULL) { return TCL_ERROR; } hPtr = Blt_CreateHashEntry(&dataPtr->dndTable, (char *)tkwin, &isNew); if (!isNew) { Tcl_AppendResult(interp, "\"", Tk_PathName(tkwin), "\" is already registered as a drag&drop manager", (char *)NULL); return TCL_ERROR; } dndPtr = CreateDnd(interp, tkwin); dndPtr->hashPtr = hPtr; dndPtr->dataPtr = dataPtr; Blt_SetHashValue(hPtr, dndPtr); if (Blt_ConfigureWidgetFromObj(interp, dndPtr->tkwin, configSpecs, objc - 3, objv + 3, (char *)dndPtr, 0) != TCL_OK) { return TCL_ERROR; } if (ConfigureDnd(interp, dndPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TokenWindowOp -- * *--------------------------------------------------------------------------- */ static int TokenWindowOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Dnd *dndPtr; int flags; if (GetDndFromObj(clientData, interp, objv[3], &dndPtr) != TCL_OK) { return TCL_ERROR; } flags = 0; if (dndPtr->tokenPtr == NULL) { if (CreateToken(interp, dndPtr) != TCL_OK) { return TCL_ERROR; } } else { flags = BLT_CONFIG_OBJV_ONLY; } if (ConfigureToken(interp, dndPtr, objc - 4, objv + 4, flags) != TCL_OK) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(dndPtr->tokenPtr->tkwin), -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TokenCgetOp -- * * Called to process an (objc,objv) list to configure (or * reconfigure) a drag&drop widget. * *--------------------------------------------------------------------------- */ /* ARGSUSED*/ static int TokenCgetOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, /* Not used. */ Tcl_Obj *const *objv) { Dnd *dndPtr; if (GetDndFromObj(clientData, interp, objv[3], &dndPtr) != TCL_OK) { return TCL_ERROR; } if (dndPtr->tokenPtr == NULL) { Tcl_AppendResult(interp, "no token created for \"", objv[3], "\"", (char *)NULL); return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, dndPtr->tokenPtr->tkwin, tokenConfigSpecs, (char *)dndPtr->tokenPtr, objv[4], BLT_CONFIG_OBJV_ONLY); } /* *--------------------------------------------------------------------------- * * TokenConfigureOp -- * *--------------------------------------------------------------------------- */ static int TokenConfigureOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Token *tokenPtr; Dnd *dndPtr; int flags; if (GetDndFromObj(clientData, interp, objv[3], &dndPtr) != TCL_OK) { return TCL_ERROR; } flags = BLT_CONFIG_OBJV_ONLY; if (dndPtr->tokenPtr == NULL) { Tcl_AppendResult(interp, "no token created for \"", objv[3], "\"", (char *)NULL); return TCL_ERROR; } tokenPtr = dndPtr->tokenPtr; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, tokenPtr->tkwin, tokenConfigSpecs, (char *)tokenPtr, (Tcl_Obj *)NULL, flags); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, tokenPtr->tkwin, tokenConfigSpecs, (char *)tokenPtr, objv[3], flags); } return ConfigureToken(interp, dndPtr, objc - 4, objv + 4, flags); } static Blt_OpSpec tokenOps[] = { {"cget", 2, TokenCgetOp, 5, 5, "widget option",}, {"configure", 2, TokenConfigureOp, 4, 0, "widget ?option value?...",}, {"window", 5, TokenWindowOp, 4, 0, "widget ?option value?...",}, }; static int nTokenOps = sizeof(tokenOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * TokenOp -- * *--------------------------------------------------------------------------- */ static int TokenOp( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTokenOps, tokenOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } static Blt_OpSpec dndOps[] = { {"cancel", 2, CancelOp, 3, 3, "widget",}, {"cget", 2, CgetOp, 4, 4, "widget option",}, {"configure", 4, ConfigureOp, 3, 0, "widget ?option value?...",}, #ifdef notdef {"convert", 4, ConvertOp, 5, 5, "widget data format",}, #endif {"delete", 2, DeleteOp, 3, 0,"?-source|-target? widget...",}, {"drag", 3, DragOp, 3, 0, "widget x y ?token?",}, {"drop", 3, DropOp, 3, 0, "widget x y ?token?",}, {"getdata", 1, GetdataOp, 3, 0, "widget ?format command?",}, {"names", 1, NamesOp, 2, 4, "?-source|-target? ?pattern?",}, {"pull", 1, PullOp, 4, 4, "widget format",}, {"register", 1, RegisterOp, 3, 0, "widget ?option value?...",}, {"select", 3, SelectOp, 6, 6, "widget x y timestamp",}, {"setdata", 3, SetdataOp, 3, 0, "widget ?format command?",}, {"token", 5, TokenOp, 3, 0, "args...",}, }; static int nDndOps = sizeof(dndOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * DndCmd -- * * Invoked by TCL whenever the user issues a drag&drop command. * *--------------------------------------------------------------------------- */ static int DndCmd( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp, /* current interpreter */ int objc, /* number of arguments */ Tcl_Obj *const *objv) /* Argument strings */ { Tcl_ObjCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nDndOps, dndOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (clientData, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * DndInterpDeleteProc -- * * This is called when the interpreter hosting the "dnd" command is * destroyed. * * Results: * None. * * Side effects: * Destroys the hash table containing the drag&drop managers. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void DndInterpDeleteProc( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp) { DndInterpData *dataPtr = clientData; Dnd *dndPtr; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&dataPtr->dndTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { dndPtr = Blt_GetHashValue(hPtr); dndPtr->hashPtr = NULL; DestroyDnd((DestroyData)dndPtr); } Blt_DeleteHashTable(&dataPtr->dndTable); Tcl_DeleteAssocData(interp, DND_THREAD_KEY); Blt_Free(dataPtr); } static DndInterpData * GetDndInterpData(Tcl_Interp *interp) { DndInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (DndInterpData *)Tcl_GetAssocData(interp, DND_THREAD_KEY, &proc); if (dataPtr == NULL) { Display *display; Tk_Window tkwin; dataPtr = Blt_AssertMalloc(sizeof(DndInterpData)); tkwin = Tk_MainWindow(interp); display = Tk_Display(tkwin); dataPtr->tkMain = tkwin; dataPtr->display = display; Tcl_SetAssocData(interp, DND_THREAD_KEY, DndInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->dndTable, BLT_ONE_WORD_KEYS); dataPtr->mesgAtom = XInternAtom(display, "BLT Dnd Message", False); dataPtr->targetAtom = XInternAtom(display, "BLT Dnd Target", False); dataPtr->formatsAtom = XInternAtom(display, "BLT Dnd Formats",False); dataPtr->commAtom = XInternAtom(display, "BLT Dnd CommData", False); #ifdef HAVE_XDND dataPtr->XdndActionListAtom = XInternAtom(display, "XdndActionList", False); dataPtr->XdndAwareAtom = XInternAtom(display, "XdndAware", False); dataPtr->XdndEnterAtom = XInternAtom(display, "XdndEnter", False); dataPtr->XdndFinishedAtom = XInternAtom(display, "XdndFinished", False); dataPtr->XdndLeaveAtom = XInternAtom(display, "XdndLeave", False); dataPtr->XdndPositionAtom = XInternAtom(display, "XdndPosition", False); dataPtr->XdndSelectionAtom = XInternAtom(display, "XdndSelection", False); dataPtr->XdndStatusAtom = XInternAtom(display, "XdndStatus", False); dataPtr->XdndTypeListAtom = XInternAtom(display, "XdndTypeList", False); #endif /* HAVE_XDND */ } return dataPtr; } /* *--------------------------------------------------------------------------- * * Blt_DndCmdInitProc -- * * Adds the drag&drop command to the given interpreter. Should * be invoked to properly install the command whenever a new * interpreter is created. * *--------------------------------------------------------------------------- */ int Blt_DndCmdInitProc(Tcl_Interp *interp) /* Interpreter to be updated */ { static Blt_InitCmdSpec cmdSpec = { "dnd", DndCmd }; cmdSpec.clientData = GetDndInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } #ifdef notdef /* * Registers bitmap outline of dragged data, used to indicate * what is being dragged by source. Bitmap is XOR-ed as cursor/token * is moved around the screen. */ static void Blt_DndSetOutlineBitmap(Tk_Window tkwin, Pixmap bitmap, int x, int y) { } #endif #ifdef HAVE_XDND static void XDndFreeFormats(XDndHandler *handlerPtr) { if (handlerPtr->formatArr != NULL) { char **p; for (p = handlerPtr->formatArr; *p != NULL; p++) { XFree(*p); } Blt_Free(handlerPtr->formatArr); handlerPtr->formatArr = NULL; } } static char ** XDndGetFormats(XDndHandler *handlerPtr, XEvent *eventPtr) { int flags; Window window; unsigned char *data; Atom typeAtom; Atom format; int nItems, bytesAfter; Atom *atomArr; char *nameArr[XDND_MAX_TYPES + 1]; Display *display; XDndFreeFormats(handlerPtr); display = eventPtr->xclient.display; window = eventPtr->xclient.data.l[0]; flags = eventPtr->xclient.data.l[1]; data = NULL; if (flags & 0x01) { result = XGetWindowProperty( display, /* Display of window. */ window, /* Window holding the property. */ handlerPtr->dataPtr->XdndTypeListAtom, /* Name of property. */ 0, /* Offset of data (for multiple reads). */ XDND_MAX_TYPES, /* Maximum number of items to read. */ False, /* If true, delete the property. */ XA_ATOM, /* Desired type of property. */ &typeAtom, /* (out) Actual type of the property. */ &format, /* (out) Actual format of the property. */ &nItems, /* (out) # of items in specified format. */ &bytesAfter, /* (out) # of bytes remaining to be read. */ (unsigned char **)&data); if ((result != Success) || (format != 32) || (typeAtom != XA_ATOM)) { if (data != NULL) { XFree((char *)data); return (char **)NULL; } } atomArr = (Atom *)data; nAtoms = nItems; } else { atomArr = &(eventPtr->xclient.data.l[2]); nAtoms = 3; } formatArr = Blt_AssertCalloc(nAtoms + 1, sizeof(char *)); for (i = 0; (i < nAtoms) && (atomArr[i] != None); i++) { formatArr[i] = XGetAtomName(display, atomArr[i]); } if (data != NULL) { XFree((char *)data); } handlerPtr->formatArr = formatArr; } static char * GetMatchingFormats(Dnd *dndPtr, char **formatArr) { int nMatches; nMatches = 0; Tcl_DStringInit(&dString); for (p = formatArr; *p != NULL; p++) { for(hPtr = Blt_FirstHashEntry(&dndPtr->setDataTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { fmt = Blt_GetHashKey(&dndPtr->setDataTable, hPtr); if ((*fmt == **p) && (strcmp(fmt, *p) == 0)) { Tcl_DStringAppendElement(&dString, *p); nMatches++; break; } } } if (nMatches > 0) { char *string; string = Blt_AssertStrdup(Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); return string; } return NULL; } static void XDndPointerEvent(XDndHandler *handlerPtr, XEvent *eventPtr) { Tk_Window tkwin; int flags; Atom action; Window window; flags = 0; action = None; window = eventPtr->xclient.data.l[MESG_XDND_WINDOW]; /* * If the XDND source has no formats specified, don't process any * further. Simply send a "no accept" action with the message. */ if (handlerPtr->formatArr != NULL) { Dnd *newPtr, *oldPtr; int point; int button, keyState; int x, y; char *formats; point = (int)eventPtr->xclient.data.l[MESG_XDND_POINT]; UNPACK(point, x, y); /* * See if the mouse pointer currently over a drop target. We first * determine what Tk window is under the mouse, and then check if * that window is registered as a drop target. */ newPtr = NULL; tkwin = Tk_CoordsToWindow(x, y, handlerPtr->tkwin); if (tkwin != NULL) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&handlerPtr->dataPtr->dndTable, (char *)tkwin); if (hPtr != NULL) { newPtr = Blt_GetHashValue(hPtr); if (!newPtr->isTarget) { newPtr = NULL; /* Not a DND target. */ } formats = GetMatchingFormats(newPtr, handlerPtr->formatArr); if (formats == NULL) { newPtr = NULL; /* Source has no matching formats. */ } } } button = keyState = 0; oldPtr = handlerPtr->dndPtr; resp = DROP_CANCEL; if (newPtr == oldPtr) { if ((oldPtr != NULL) && (oldPtr->motionCmd != NULL)) { resp = InvokeCallback(oldPtr, oldPtr->motionCmd, x, y, formats, button, keyState, dndPtr->timestamp); } } else { if ((oldPtr != NULL) && (oldPtr->leaveCmd != NULL)) { InvokeCallback(oldPtr, oldPtr->leaveCmd, x, y, formats, button, keyState, dndPtr->timestamp); } if ((newPtr != NULL) && (newPtr->enterCmd != NULL)) { resp = InvokeCallback(newPtr, newPtr->enterCmd, x, y, formats, button, keyState, dndPtr->timestamp); } handlerPtr->dndPtr = newPtr; /* * Save the current mouse position, since we get them from the * drop message. */ newPtr->x = x; newPtr->y = y; } if (formats != NULL) { Blt_Free(formats); } flags = XDND_FLAGS_WANT_POSITION_MSGS; if (resp) { flags |= XDND_FLAGS_ACCEPT_DROP; action = handlerPtr->dataPtr->XdndActionCopyAtom; } } /* Target-to-Source: Drag result message. */ SendClientMsg(handlerPtr->display, window, handlerPtr->dataPtr->XdndStatusAtom, handlerPtr->window, flags, 0, 0, action); } static void XDndDropEvent(XDndHandler *handlerPtr, XEvent *eventPtr) { Tk_Window tkwin; int flags; Atom action; Window window; int timestamp; flags = 0; action = None; window = eventPtr->xclient.data.l[MESG_XDND_WINDOW]; timestamp = eventPtr->xclient.data.l[MESG_XDND_TIMESTAMP]; /* * If no formats were specified for the XDND source or if the last * motion event did not place the mouse over a valid drop target, * don't process any further. Simply send a "no accept" action with * the message. */ if ((handlerPtr->formatArr != NULL) && (handlerPtr->dndPtr != NULL)) { int button, keyState; Dnd *dndPtr = handlerPtr->dndPtr; DropPending pending; int resp; button = keyState = 0; /* Protocol doesn't supply this * information. */ /* Set up temporary bookkeeping for the drop transaction */ memset (&pending, 0, sizeof(pending)); pending.window = window; pending.display = eventPtr->xclient.display; pending.timestamp = timestamp; pending.protocol = PROTO_XDND; pending.packetSize = GetMaxPropertySize(pending.display); Tcl_DStringInit(&pending.dString); formats = GetMatchingFormats(handlerPtr->dndPtr, handlerPtr->formatArr); if (formats == NULL) { } dndPtr->pendingPtr = &pending; resp = AcceptDrop(dndPtr, dndPtr->x, dndPtr->y, formats, button, keyState, action, timestamp); dndPtr->pendingPtr = NULL; if (resp) { flags |= XDND_FLAGS_ACCEPT_DROP; action = handlerPtr->dataPtr->XdndActionCopyAtom; } } /* Target-to-Source: Drag result message. */ SendClientMsg(handlerPtr->display, window, handlerPtr->dataPtr->XdndStatusAtom, handlerPtr->window, flags, 0, 0, action); } /* *--------------------------------------------------------------------------- * * XDndProtoEventProc -- * * Invoked by Tk_HandleEvent whenever a DestroyNotify event is received * on a registered drag&drop source widget. * *--------------------------------------------------------------------------- */ static int XDndProtoEventProc( ClientData clientData, /* Drag&drop record. */ XEvent *eventPtr) /* Event description. */ { DndInterpData *dataPtr = clientData; Tk_Window tkwin; Blt_HashEntry *hPtr; XDndHandler *handlerPtr; int point; int x, y; Atom mesg; if (eventPtr->type != ClientMessage) { return 0; /* Not a ClientMessage event. */ } /* Was the recipient a registered toplevel window? */ hPtr = Blt_FindHashEntry(&dataPtr->handlerTable, (char *)eventPtr->xclient.window); if (hPtr == NULL) { return 0; /* No handler registered with window. */ } handlerPtr = Blt_GetHashValue(hPtr); mesg = eventPtr->xclient.message_type; if (mesg == dataPtr->XdndEnterAtom) { XDndGetFormats(handlerPtr, eventPtr); handlerPtr->dndPtr = NULL; } else if (mesg == dataPtr->XdndPositionAtom) { XDndPointerEvent(handlerPtr, eventPtr); } else if (mesg == dataPtr->XdndLeaveAtom) { XDndFreeFormats(handlerPtr); /* Free up any collected formats. */ if (handlerPtr->dndPtr != NULL) { InvokeCallback(handlerPtr->dndPtr, handlerPtr->dndPtr->leaveCmd, -1, -1, NULL, 0, 0); /* Send leave event to drop target. */ } } else if (mesg == dataPtr->XdndDropAtom) { XDndDropEvent(handlerPtr, eventPtr); } else { fprintf(stderr, "Unknown client message type = 0x%x\n", mesg); return 0; /* Unknown message type. */ } return 1; } static XDndHandler * XDndCreateHandler(Dnd *dndPtr) { Tk_Window tkwin; Window window; Blt_HashEntry *hPtr; int isNew; XDndHandler *handlerPtr; /* * Find the containing toplevel of this window. See if an XDND handler is * already registered for it. */ tkwin = Blt_GetToplevelWindow(dndPtr->tkwin); window = Blt_GetWindowId(tkwin); /* Use the wrapper window as * the real toplevel window. */ hPtr = Blt_CreateHashEntry(&dataPtr->XDndHandlerTable, (char *)window, &isNew); if (!isNew) { handlerPtr = (XDndHandler *)Blt_GetHashEntry(hPtr); handlerPtr->refCount++; } else { handlerPtr = Blt_AssertMalloc(sizeof(XDndHandler)); handlerPtr->tkwin = tkwin; handlerPtr->dndPtr = NULL; handlerPtr->refCount = 1; handlerPtr->dataPtr = dataPtr; /* FIXME */ SetProperty(window, dataPtr->XdndAwareAtom, "3"); Blt_SetHashValue(hPtr, handlerPtr); } return handlerPtr; } static void XDndDeleteHandler(Dnd *dndPtr) { Tk_Window tkwin; Window window; Blt_HashEntry *hPtr; tkwin = Blt_GetToplevelWindow(dndPtr->tkwin); window = Blt_GetWindowId(tkwin); /* Use the wrapper window as the real * toplevel window. */ hPtr = Blt_FindHashEntry(&dataPtr->XDndHandlerTable, (char *)window); if (hPtr != NULL) { XDndHandler *handlerPtr; handlerPtr = (XDndHandler *)Blt_GetHashEntry(hPtr); handlerPtr->refCount--; if (handlerPtr->refCount == 0) { XDndFreeFormats(handlerPtr); XDeleteProperty(dndPtr->display, window, dndPtr->dataPtr->XdndAwareAtom); Blt_DeleteHashEntry(&dataPtr->XDndHandlerTable, hPtr); Blt_Free(handlerPtr); } } } #endif /* HAVE_XDND */ #endif /* NO_DRAGDROP */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDataTable.c����������������������������������������������������������������0000644�0001750�0001750�00000475325�11462120062�015534� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * * bltDataTable.c -- * * Copyright 1998-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <bltInt.h> #include <bltHash.h> #include <bltPool.h> #include <bltNsUtil.h> #include <bltArrayObj.h> #include <bltDataTable.h> /* * Row and Column Information Structures * * Map: Array of pointers to headers, representing the logical * view of row/column. * * x = pointer to row/column header. * y = row/column header. * label * index: logical location of row/column. * offset: physical location of row/column in table storage. * type: column type. * flags: * * [x] [x] [x] [x] [x] [x] [x] [x] [ ] [ ] [ ] * | | | | | | | | * v v v v v v v v * [y] [y] [y] [y] [y] [y] [y] [y] * * * Free list: Chain of free locations. Holds the physical offset * of next free row or column. The offsets of deleted * rows/columns are prepended to this list. * * x = offset of free row/column in table storage. * * [x]->[x]->[x]->[x]->[x] * * Header pool: Pool of row/column headers. Act as smart pointers * to row/column locations. Will remain valid even if * the logical view is changed (i.e. sorting) or physical * storage is compacted. * * Data Vectors. * Vectors: array of Value arrays. * * x = pointer to Value array. * y = array of Values. * * Array of vectors: [x] [x] [x] [x] [x] [ ] [x] [x] [x] [ ] [ ] [ ] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [ ] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [ ] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [ ] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [y] [y] [y] [y] [y] [y] [y] [y] * [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] * [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] * [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] * [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] * [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] * */ #define NumColumnsAllocated(t) ((t)->corePtr->columns.nAllocated) #define NumRowsAllocated(t) ((t)->corePtr->rows.nAllocated) #define TABLE_THREAD_KEY "BLT DataTable Data" #define TABLE_MAGIC ((unsigned int) 0xfaceface) #define TABLE_DESTROYED (1<<0) #define TABLE_ALLOC_MAX_DOUBLE_SIZE (1<<16) #define TABLE_ALLOC_MAX_CHUNK (1<<16) #define TABLE_NOTIFY_ANY (NULL) #define TABLE_KEYS_DIRTY (1<<0) #define TABLE_KEYS_UNIQUE (1<<1) /* Column flag. */ #define TABLE_COLUMN_PRIMARY_KEY (1<<0) typedef struct _Blt_TableValue Value; typedef struct { long nRows, nCols; long mtime, ctime; const char *fileName; long nLines; unsigned int flags; int argc; const char **argv; Blt_HashTable rowIndices, colIndices; } RestoreData; typedef struct _Blt_Table Table; typedef struct _Blt_TableTags Tags; typedef struct _Blt_TableTrace Trace; typedef struct _Blt_TableNotifier Notifier; const char *valueTypes[] = { "string", "int", "double", "long", }; /* * _Blt_TableTags -- * * Structure representing tags used by a client of the table. * * Table rows and columns may be tagged with strings. A row may have * many tags. The same tag may be used for many rows. Tags are used and * stored by clients of a table. Tags can also be shared between clients * of the same table. * * Both rowTable and columnTable are hash tables keyed by the physical * row or column location in the table respectively. This is not the * same as the client's view (the order of rows or columns as seen by the * client). This is so that clients (which may have different views) can * share tags without sharing the same view. */ struct _Blt_TableTags { Blt_HashTable rowTable; /* Table of row indices. Each entry * is itself a hash table of tag * names. */ Blt_HashTable columnTable; /* Table of column indices. Each * entry is itself a hash table of tag * names. */ int refCount; /* Tracks the number of clients * currently using these tags. If * refCount goes to zero, this means * the table can safely be freed. */ }; typedef struct { Blt_HashTable clientTable; /* Tracks all table clients. */ unsigned int nextId; Tcl_Interp *interp; } InterpData; typedef struct _Blt_TableHeader Header; typedef struct _Blt_TableRow Row; typedef struct _Blt_TableColumn Column; typedef struct _Blt_TableCore TableObject; typedef struct _Blt_TableRowColumn RowColumn; typedef struct { Blt_TableRow row; Blt_TableColumn column; } RowColumnKey; static Blt_TableRowColumnClass rowClass = { "row", sizeof(struct _Blt_TableRow) }; static Blt_TableRowColumnClass columnClass = { "column", sizeof(struct _Blt_TableColumn) }; static Tcl_InterpDeleteProc TableInterpDeleteProc; static void DestroyTable(Table *tablePtr); static void FreeRowColumn(RowColumn *rcPtr) { Header **hpp, **hend; Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&rcPtr->labelTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&rcPtr->labelTable); Blt_Chain_Destroy(rcPtr->freeList); for (hpp = rcPtr->map, hend = hpp + rcPtr->nUsed; hpp < hend; hpp++) { Blt_PoolFreeItem(rcPtr->headerPool, *hpp); } Blt_PoolDestroy(rcPtr->headerPool); Blt_Free(rcPtr->map); } static void UnsetLabel(RowColumn *rcPtr, Header *headerPtr) { Blt_HashEntry *hPtr; if (headerPtr->label == NULL) { return; } hPtr = Blt_FindHashEntry(&rcPtr->labelTable, headerPtr->label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)headerPtr); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tablePtr, h2Ptr); } if (tablePtr->numEntries == 0) { Blt_DeleteHashEntry(&rcPtr->labelTable, hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } } headerPtr->label = NULL; } /* *--------------------------------------------------------------------------- * * SetLabel -- * * Changes the label for the row or column. Labels aren't necessarily * unique, it's not enforced. The rationale is that it is convenient * to be able to add rows/columns to a table, and then change the * labels. For example, when importing table data from a file, * you can't apriori change the labels. We could add #n to make the * label unique, but changing them is a pain. * * * Results: * Returns a pointer to the new object is successful, NULL otherwise. If * a table object can't be generated, interp->result will contain an * error message. * * -------------------------------------------------------------------------- */ static void SetLabel(RowColumn *rcPtr, Header *headerPtr, const char *newLabel) { Blt_HashEntry *hPtr; int isNew; Blt_HashTable *tablePtr; /* Secondary table. */ if (headerPtr->label != NULL) { UnsetLabel(rcPtr, headerPtr); } if (newLabel == NULL) { return; } /* Check the primary label table for the bucket. */ hPtr = Blt_CreateHashEntry(&rcPtr->labelTable, newLabel, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } /* Save the label as the hash entry key. */ headerPtr->label = Blt_GetHashKey(&rcPtr->labelTable, hPtr); /* Now look the header in the secondary table. */ hPtr = Blt_CreateHashEntry(tablePtr, (char *)headerPtr, &isNew); if (!isNew) { return; /* It's already there. */ } /* Add it to the secondary table. */ Blt_SetHashValue(hPtr, headerPtr); } static int CheckLabel(Tcl_Interp *interp, RowColumn *rcPtr, const char *label) { char c; c = label[0]; /* This is so we know where switches end. */ if (c == '-') { if (interp != NULL) { Tcl_AppendResult(interp, rcPtr->classPtr->name, " label \"", label, "\" can't start with a '-'.", (char *)NULL); } return TCL_ERROR; } if (isdigit(UCHAR(c))) { long index; if (TclGetLong(NULL, (char *)label, &index) == TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, rcPtr->classPtr->name, " label \"", label, "\" can't be a number.", (char *)NULL); } return TCL_ERROR; } } return TCL_OK; } static int SetHeaderLabel(Tcl_Interp *interp, RowColumn *rcPtr, Header *headerPtr, const char *newLabel) { if (CheckLabel(interp, rcPtr, newLabel) != TCL_OK) { return TCL_ERROR; } SetLabel(rcPtr, headerPtr, newLabel); return TCL_OK; } #if (SIZEOF_VOID_P == 8) #define LABEL_FMT "%c%ld" #else #define LABEL_FMT "%c%d" #endif static void GetNextLabel(RowColumn *rcPtr, Header *headerPtr) { char label[200]; for(;;) { Blt_HashEntry *hPtr; sprintf_s(label, 200, LABEL_FMT, rcPtr->classPtr->name[0], rcPtr->nextId++); hPtr = Blt_FindHashEntry(&rcPtr->labelTable, label); if (hPtr == NULL) { SetLabel(rcPtr, headerPtr, label); return; } } } static long GetMapSize(long oldLen, long extra) { long newLen, reqLen; reqLen = oldLen + extra; newLen = oldLen; if (newLen == 0) { newLen = 1; } if (reqLen < TABLE_ALLOC_MAX_DOUBLE_SIZE) { while (newLen < reqLen) { newLen += newLen; } } else { while (newLen < reqLen) { newLen += TABLE_ALLOC_MAX_CHUNK; } } return newLen; } static int GrowHeaders(RowColumn *rcPtr, long extra) { long newSize, oldSize; Header **map; newSize = GetMapSize(rcPtr->nAllocated, extra); oldSize = rcPtr->nAllocated; map = rcPtr->map; if (map == NULL) { map = Blt_Malloc(sizeof(Header *) * newSize); } else { map = Blt_Realloc(rcPtr->map, sizeof(Header *) * newSize); } if (map == NULL) { return FALSE; } { Header **mp; long i; /* Initialize the new extra header slots in the map to NULL and add * them the free list. */ for (i = oldSize, mp = map + oldSize; i < newSize; i++, mp++) { Blt_Chain_Append(rcPtr->freeList, (ClientData)i); *mp = NULL; /* Initialize new slots in the map. */ } } rcPtr->map = map; rcPtr->nAllocated = newSize; return TRUE; } static int GrowColumns(Table *tablePtr, long extraCols) { if (extraCols > 0) { long oldCols, newCols; Value **data, **vp, **vend; oldCols = NumColumnsAllocated(tablePtr); if (!GrowHeaders(&tablePtr->corePtr->columns, extraCols)) { return FALSE; } newCols = NumColumnsAllocated(tablePtr); /* Resize the vector array to have as many slots as columns. */ data = tablePtr->corePtr->data; if (data == NULL) { data = Blt_Malloc(newCols * sizeof(Value *)); } else { data = Blt_Realloc(data, newCols * sizeof(Value *)); } if (data == NULL) { return FALSE; } /* Initialize the new vector slots to NULL. */ for (vp = data + oldCols, vend = data + newCols; vp < vend; vp++) { *vp = NULL; } tablePtr->corePtr->data = data; } return TRUE; } static int GrowRows(Table *tablePtr, long extraRows) { if (extraRows > 0) { long oldRows, newRows; Value **vpp, **vpend; oldRows = NumRowsAllocated(tablePtr); if (!GrowHeaders(&tablePtr->corePtr->rows, extraRows)) { return FALSE; } newRows = NumRowsAllocated(tablePtr); /* Resize all the vectors. Leave the empty vectors alone. They are * allocated when data is added to them. */ for (vpp = tablePtr->corePtr->data, vpend = vpp + NumColumnsAllocated(tablePtr); vpp < vpend; vpp++) { if (*vpp != NULL) { Value *vector, *vp, *vend; vector = Blt_Realloc(*vpp, newRows * sizeof(Value)); for (vp = vector + oldRows, vend = vector + newRows; vp < vend; vp++) { vp->string = NULL; } *vpp = vector; } } } return TRUE; } static void ExtendHeaders(RowColumn *rcPtr, long n, Blt_Chain chain) { Blt_ChainLink link; long nextIndex; long i; /* * At this point we're guaranteed to have as many free rows/columns in * the table as requested. */ link = Blt_Chain_FirstLink(rcPtr->freeList); nextIndex = rcPtr->nUsed; for (i = 0; i < n; i++) { Blt_ChainLink next; Header *headerPtr; headerPtr = Blt_PoolAllocItem(rcPtr->headerPool, rcPtr->classPtr->headerSize); memset(headerPtr, 0, rcPtr->classPtr->headerSize); GetNextLabel(rcPtr, headerPtr); headerPtr->offset = (long)Blt_Chain_GetValue(link); rcPtr->map[nextIndex] = headerPtr; nextIndex++; headerPtr->index = nextIndex; /* Remove the link the freelist and append it to the output chain. */ next = Blt_Chain_NextLink(link); Blt_Chain_UnlinkLink(rcPtr->freeList, link); Blt_Chain_AppendLink(chain, link); Blt_Chain_SetValue(link, headerPtr); link = next; } rcPtr->nUsed += n; } static int ExtendRows(Table *tablePtr, long n, Blt_Chain chain) { long nFree; nFree = Blt_Chain_GetLength(tablePtr->corePtr->rows.freeList); if (n > nFree) { long needed; needed = n - nFree; if (!GrowRows(tablePtr, needed)) { return FALSE; } } ExtendHeaders(&tablePtr->corePtr->rows, n, chain); tablePtr->flags |= TABLE_KEYS_DIRTY; return TRUE; } static int ExtendColumns(Table *tablePtr, long n, Blt_Chain chain) { long nFree; nFree = Blt_Chain_GetLength(tablePtr->corePtr->columns.freeList); if (n > nFree) { if (!GrowColumns(tablePtr, n - nFree)) { return FALSE; } } ExtendHeaders(&tablePtr->corePtr->columns, n, chain); return TRUE; } Blt_TableColumnType Blt_Table_GetColumnType(const char *typeName) { if (strcmp(typeName, "string") == 0) { return TABLE_COLUMN_TYPE_STRING; } else if (strcmp(typeName, "integer") == 0) { return TABLE_COLUMN_TYPE_INT; } else if (strcmp(typeName, "double") == 0) { return TABLE_COLUMN_TYPE_DOUBLE; } else if (strcmp(typeName, "long") == 0) { return TABLE_COLUMN_TYPE_LONG; } else { return TABLE_COLUMN_TYPE_UNKNOWN; } } static INLINE int IsEmpty(Value *valuePtr) { return ((valuePtr == NULL) || (valuePtr->string == NULL)); } static INLINE void FreeValue(Value *valuePtr) { if (valuePtr->string != NULL) { Blt_Free(valuePtr->string); } valuePtr->string = NULL; } static void FreeVector(Value *vector, long length) { if (vector != NULL) { Value *vp, *vend; for (vp = vector, vend = vp + length; vp < vend; vp++) { FreeValue(vp); } Blt_Free(vector); } } static Value * AllocateVector(Table *tablePtr, long offset) { Value *vector; vector = tablePtr->corePtr->data[offset]; if (vector == NULL) { vector = Blt_Calloc(NumRowsAllocated(tablePtr), sizeof(Value)); if (vector == NULL) { return NULL; } tablePtr->corePtr->data[offset] = vector; } return vector; } static Value * GetValue(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *vector; vector = tablePtr->corePtr->data[colPtr->offset]; if (vector == NULL) { vector = AllocateVector(tablePtr, colPtr->offset); } return vector + rowPtr->offset; } static Tcl_Obj * GetObjFromValue(Tcl_Interp *interp, Blt_TableColumnType type, Value *valuePtr) { Tcl_Obj *objPtr; if (IsEmpty(valuePtr)) { return NULL; } switch (type) { case TABLE_COLUMN_TYPE_UNKNOWN: case TABLE_COLUMN_TYPE_STRING: /* string */ objPtr = Tcl_NewStringObj(valuePtr->string, -1); break; case TABLE_COLUMN_TYPE_DOUBLE: /* double */ objPtr = Tcl_NewDoubleObj(valuePtr->datum.d); break; case TABLE_COLUMN_TYPE_LONG: /* long */ objPtr = Tcl_NewLongObj(valuePtr->datum.l); break; case TABLE_COLUMN_TYPE_INT: /* int */ objPtr = Tcl_NewIntObj((int)valuePtr->datum.l); break; } return objPtr; } static int SetValueFromObj(Tcl_Interp *interp, Blt_TableColumnType type, Tcl_Obj *objPtr, Value *valuePtr) { int length; const char *s; FreeValue(valuePtr); if (objPtr == NULL) { return TCL_OK; } switch (type) { case TABLE_COLUMN_TYPE_DOUBLE: /* double */ if (Blt_GetDoubleFromObj(interp, objPtr, &valuePtr->datum.d)!=TCL_OK) { return TCL_ERROR; } break; case TABLE_COLUMN_TYPE_LONG: /* long */ case TABLE_COLUMN_TYPE_INT: /* int */ if (Tcl_GetLongFromObj(interp, objPtr, &valuePtr->datum.l) != TCL_OK) { return TCL_ERROR; } break; default: break; } s = Tcl_GetStringFromObj(objPtr, &length); valuePtr->string = Blt_AssertMalloc(length + 1); strcpy(valuePtr->string, s); return TCL_OK; } static int SetValueFromString(Tcl_Interp *interp, Blt_TableColumnType type, const char *s, int length, Value *valuePtr) { double d; long l; char *string; if (length < 0) { length = strlen(s); } /* Make a copy of the string, eventually used for string rep. */ string = Blt_AssertMalloc(length + 1); strncpy(string, s, length); string[length] = '\0'; switch (type) { case TABLE_COLUMN_TYPE_DOUBLE: /* double */ if (Blt_GetDoubleFromString(interp, string, &d) != TCL_OK) { Blt_Free(string); return TCL_ERROR; } valuePtr->datum.d = d; break; case TABLE_COLUMN_TYPE_LONG: /* long */ case TABLE_COLUMN_TYPE_INT: /* int */ if (TclGetLong(interp, string, &l) != TCL_OK) { Blt_Free(string); return TCL_ERROR; } valuePtr->datum.l = l; break; default: break; } FreeValue(valuePtr); valuePtr->string = string; return TCL_OK; } /* *--------------------------------------------------------------------------- * * NewTableObject -- * * Creates and initializes a new table object. * * Results: * Returns a pointer to the new object is successful, NULL otherwise. If * a table object can't be generated, interp->result will contain an * error message. * * -------------------------------------------------------------------------- */ static TableObject * NewTableObject(void) { TableObject *corePtr; corePtr = Blt_Calloc(1, sizeof(TableObject)); if (corePtr == NULL) { return NULL; } corePtr->clients = Blt_Chain_Create(); Blt_InitHashTableWithPool(&corePtr->columns.labelTable, BLT_STRING_KEYS); Blt_InitHashTableWithPool(&corePtr->rows.labelTable, BLT_STRING_KEYS); corePtr->columns.classPtr = &columnClass; corePtr->columns.freeList = Blt_Chain_Create(); corePtr->columns.headerPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); corePtr->columns.nextId = 1; corePtr->rows.classPtr = &rowClass; corePtr->rows.freeList = Blt_Chain_Create(); corePtr->rows.headerPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); corePtr->rows.nextId = 1; return corePtr; } static void DestroyTraces(Blt_Chain chain) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Trace *tp; tp = Blt_Chain_GetValue(link); tp->link = NULL; Blt_Table_DeleteTrace(tp); } Blt_Chain_Destroy(chain); } /* *--------------------------------------------------------------------------- * * NotifyIdleProc -- * * Used to invoke event handler routines at some idle point. This * routine is called from the TCL event loop. Errors generated by the * event handler routines are backgrounded. * * Results: * None. * *--------------------------------------------------------------------------- */ static void NotifyIdleProc(ClientData clientData) { Notifier *notifierPtr = clientData; int result; notifierPtr->flags &= ~TABLE_NOTIFY_PENDING; /* Protect the notifier in case it's deleted by the callback. */ Tcl_Preserve(notifierPtr); notifierPtr->flags |= TABLE_NOTIFY_ACTIVE; result = (*notifierPtr->proc)(notifierPtr->clientData, &notifierPtr->event); notifierPtr->flags &= ~TABLE_NOTIFY_ACTIVE; if (result == TCL_ERROR) { Tcl_BackgroundError(notifierPtr->interp); } Tcl_Release(notifierPtr); } static void FreeNotifier(Notifier *notifierPtr) { if (notifierPtr->tag != NULL) { Blt_Free(notifierPtr->tag); } if (notifierPtr->link != NULL){ Blt_Chain_DeleteLink(notifierPtr->chain, notifierPtr->link); } Blt_Free(notifierPtr); } static void DestroyNotifiers(Blt_Chain chain) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Notifier *notifierPtr; notifierPtr = Blt_Chain_GetValue(link); notifierPtr->link = NULL; Blt_Table_DeleteNotifier(notifierPtr); } Blt_Chain_Destroy(chain); } /* *--------------------------------------------------------------------------- * * DumpTags -- * * Retrieves all tags for a given row or column into a tcl list. * * Results: * Returns the number of tags in the list. * *--------------------------------------------------------------------------- */ static void DumpTags(Blt_HashTable *tagTablePtr, Header *headerPtr, Blt_Chain chain) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(tagTablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashEntry *h2Ptr; Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)headerPtr); if (h2Ptr != NULL) { Blt_Chain_Append(chain, Blt_GetHashKey(tagTablePtr, hPtr)); } } } /* *--------------------------------------------------------------------------- * * ClearTags -- * * Removes all tags for a given row or column. * * Results: * None. * * Side Effects: * All tags associcated with the row are freed. * *--------------------------------------------------------------------------- */ static void ClearTags(Blt_HashTable *tagTablePtr, Header *headerPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(tagTablePtr, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashEntry *h2Ptr; Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)headerPtr); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tablePtr, h2Ptr); } } } /* *--------------------------------------------------------------------------- * * DestroyTableObject -- * * Destroys the table object. This is the final clean up of the object. * The object's entry is removed from the hash table of tables. * * Results: * None. * * -------------------------------------------------------------------------- */ static void DestroyTableObject(TableObject *corePtr) { corePtr->flags |= TABLE_DESTROYED; assert(Blt_Chain_GetLength(corePtr->clients) == 0); Blt_Chain_Destroy(corePtr->clients); /* Free the headers containing row and column info. */ /* Free the data in each row. */ if (corePtr->data != NULL) { Value **vp, **vend; long i; for (i = 0, vp = corePtr->data, vend = vp + corePtr->columns.nAllocated; vp < vend; vp++, i++) { if (*vp != NULL) { Column *colPtr; colPtr = (Blt_TableColumn)corePtr->columns.map[i]; FreeVector(*vp, corePtr->rows.nAllocated); } } Blt_Free(corePtr->data); } FreeRowColumn(&corePtr->rows); FreeRowColumn(&corePtr->columns); Blt_Free(corePtr); } /* *--------------------------------------------------------------------------- * * TableInterpDeleteProc -- * * This is called when the interpreter hosting the table object is * deleted from the interpreter. * * Results: * None. * * Side effects: * Destroys all remaining tables and removes the hash table used to * register table names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TableInterpDeleteProc(ClientData clientData, Tcl_Interp *interp) { InterpData *dataPtr; Blt_HashEntry *hPtr; Blt_HashSearch cursor; dataPtr = clientData; for (hPtr = Blt_FirstHashEntry(&dataPtr->clientTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_Chain chain; Blt_ChainLink link, next; chain = Blt_GetHashValue(hPtr); for (link = Blt_Chain_FirstLink(chain); link != NULL; link = next) { Table *tablePtr; next = Blt_Chain_NextLink(link); tablePtr = Blt_Chain_GetValue(link); tablePtr->corePtr = NULL; tablePtr->link2 = NULL; DestroyTable(tablePtr); } Blt_Chain_Destroy(chain); } Blt_DeleteHashTable(&dataPtr->clientTable); Tcl_DeleteAssocData(interp, TABLE_THREAD_KEY); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * GetInterpData -- * * Creates or retrieves data associated with tuple data objects for a * particular interpreter. * * Results: * Returns a pointer to the tuple interpreter data. * * -------------------------------------------------------------------------- */ static InterpData * GetInterpData(Tcl_Interp *interp) { Tcl_InterpDeleteProc *proc; InterpData *dataPtr; dataPtr = (InterpData *) Tcl_GetAssocData(interp, TABLE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(InterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, TABLE_THREAD_KEY, TableInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->clientTable, BLT_STRING_KEYS); } return dataPtr; } const char * Blt_Table_NameOfType(Blt_TableColumnType type) { return valueTypes[type]; } /* *--------------------------------------------------------------------------- * * NewTags -- * *--------------------------------------------------------------------------- */ static Blt_TableTags NewTags(void) { Tags *tagsPtr; tagsPtr = Blt_Malloc(sizeof(Tags)); if (tagsPtr != NULL) { Blt_InitHashTable(&tagsPtr->rowTable, BLT_STRING_KEYS); Blt_InitHashTable(&tagsPtr->columnTable, BLT_STRING_KEYS); tagsPtr->refCount = 1; } return tagsPtr; } /* *--------------------------------------------------------------------------- * * FindClientInNamespace -- * * Searches for a table client in a given namespace. * * Results: * Returns a pointer to the table client if found, otherwise NULL. * *--------------------------------------------------------------------------- */ static Table * FindClientInNamespace(InterpData *dataPtr, Blt_ObjectName *namePtr) { Blt_Chain chain; Blt_ChainLink link; Blt_HashEntry *hPtr; Tcl_DString ds; const char *qualName; qualName = Blt_MakeQualifiedName(namePtr, &ds); hPtr = Blt_FindHashEntry(&dataPtr->clientTable, qualName); Tcl_DStringFree(&ds); if (hPtr == NULL) { return NULL; } chain = Blt_GetHashValue(hPtr); link = Blt_Chain_FirstLink(chain); return Blt_Chain_GetValue(link); } /* *--------------------------------------------------------------------------- * * GetTable -- * * Searches for the table client associated by the name given. * * Results: * Returns a pointer to the table client if found, otherwise NULL. * *--------------------------------------------------------------------------- */ static Blt_Table GetTable(InterpData *dataPtr, const char *name, unsigned int flags) { Blt_ObjectName objName; Blt_Table table; Tcl_Interp *interp; table = NULL; interp = dataPtr->interp; if (!Blt_ParseObjectName(interp, name, &objName, BLT_NO_DEFAULT_NS)) { return NULL; } if (objName.nsPtr != NULL) { table = FindClientInNamespace(dataPtr, &objName); } else { if (flags & NS_SEARCH_CURRENT) { /* Look first in the current namespace. */ objName.nsPtr = Tcl_GetCurrentNamespace(interp); table = FindClientInNamespace(dataPtr, &objName); } if ((table == NULL) && (flags & NS_SEARCH_GLOBAL)) { objName.nsPtr = Tcl_GetGlobalNamespace(interp); table = FindClientInNamespace(dataPtr, &objName); } } return table; } static void DestroyTable(Table *tablePtr) { if (tablePtr->magic != TABLE_MAGIC) { fprintf(stderr, "invalid table object token 0x%lx\n", (unsigned long)tablePtr); return; } /* Remove any traces that were set by this client. */ DestroyTraces(tablePtr->traces); /* Also remove all event handlers created by this client. */ DestroyNotifiers(tablePtr->rowNotifiers); DestroyNotifiers(tablePtr->columnNotifiers); Blt_Table_UnsetKeys(tablePtr); if (tablePtr->tags != NULL) { Blt_Table_ReleaseTags(tablePtr); } if ((tablePtr->corePtr != NULL) && (tablePtr->link != NULL)) { TableObject *corePtr; corePtr = tablePtr->corePtr; /* Remove the client from the server's list */ Blt_Chain_DeleteLink(corePtr->clients, tablePtr->link); if (Blt_Chain_GetLength(corePtr->clients) == 0) { DestroyTableObject(corePtr); } } tablePtr->magic = 0; Blt_Free(tablePtr); } /* *--------------------------------------------------------------------------- * * NewTable -- * * Creates a new table client. Clients shared a tuple data object. They * individually manage traces and events on tuple objects. Returns a * pointer to the malloc'ed structure. This is passed to the client as a * tuple token. * * Results: * A pointer to a Table is returned. If one can't be allocated, NULL * is returned. * *--------------------------------------------------------------------------- */ static Table * NewTable( InterpData *dataPtr, TableObject *corePtr, /* Table object serving this client. */ const char *qualName) /* Full namespace qualified name of table. */ { Blt_Chain chain; Table *tablePtr; int isNew; tablePtr = Blt_Calloc(1, sizeof(Table)); if (tablePtr == NULL) { return NULL; } tablePtr->magic = TABLE_MAGIC; tablePtr->interp = dataPtr->interp; /* Add client to table object's list of clients. */ tablePtr->link = Blt_Chain_Append(corePtr->clients, tablePtr); /* By default, use own sets of tags. */ tablePtr->tags = NewTags(); tablePtr->rowTags = &tablePtr->tags->rowTable; tablePtr->columnTags = &tablePtr->tags->columnTable; tablePtr->tablePtr = &dataPtr->clientTable; tablePtr->hPtr = Blt_CreateHashEntry(&dataPtr->clientTable, qualName, &isNew); if (isNew) { chain = Blt_Chain_Create(); Blt_SetHashValue(tablePtr->hPtr, chain); } else { chain = Blt_GetHashValue(tablePtr->hPtr); } tablePtr->name = Blt_GetHashKey(&dataPtr->clientTable, tablePtr->hPtr); tablePtr->link2 = Blt_Chain_Append(chain, tablePtr); tablePtr->rowNotifiers = Blt_Chain_Create(); tablePtr->columnNotifiers = Blt_Chain_Create(); tablePtr->traces = Blt_Chain_Create(); tablePtr->corePtr = corePtr; return tablePtr; } static Header * FindLabel(RowColumn *rcPtr, const char *label) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&rcPtr->labelTable, label); if (hPtr != NULL) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; Blt_HashSearch iter; tablePtr = Blt_GetHashValue(hPtr); assert(tablePtr != NULL); h2Ptr = Blt_FirstHashEntry(tablePtr, &iter); if (h2Ptr != NULL) { return Blt_GetHashValue(h2Ptr); } } return NULL; } static int SetType(Table *tablePtr, struct _Blt_TableColumn *colPtr, Blt_TableColumnType type) { int i; if (type == colPtr->type) { return TCL_OK; /* Already the requested type. */ } /* For each value in the column, try to convert it to the desired type. */ for (i = 1; i <= Blt_Table_NumRows(tablePtr); i++) { Row *rowPtr; Value *valuePtr; rowPtr = Blt_Table_Row(tablePtr, i); valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (!IsEmpty(valuePtr)) { Value value; memset(&value, 0, sizeof(Value)); if (SetValueFromString(tablePtr->interp, type, valuePtr->string, -1, &value) != TCL_OK) { return TCL_ERROR; } } } /* Now replace the column with the converted the values. */ for (i = 1; i <= Blt_Table_NumRows(tablePtr); i++) { Row *rowPtr; Value *valuePtr; rowPtr = Blt_Table_Row(tablePtr, i); valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (!IsEmpty(valuePtr)) { if (SetValueFromString(tablePtr->interp, type, valuePtr->string, -1, valuePtr) != TCL_OK) { return TCL_ERROR; } } } colPtr->type = type; return TCL_OK; } static void ResetMap(RowColumn *rcPtr) { long i, j; /* Reset the reverse lookup: from header to index. */ for (i = 0, j = 1; i < rcPtr->nUsed; i++, j++) { rcPtr->map[i]->index = j; } } static void DeleteHeader(RowColumn *rcPtr, Header *headerPtr) { /* If there is a label is associated with the column, free it. */ if (headerPtr->label != NULL) { UnsetLabel(rcPtr, headerPtr); } { long p, q; /* Compress the index-to-offset map. */ for (q = headerPtr->index, p = q - 1; q < rcPtr->nUsed; p++, q++) { /* Update the index as we slide down the headers in the map. */ rcPtr->map[p] = rcPtr->map[q]; rcPtr->map[p]->index = q; } rcPtr->map[p] = NULL; } /* Finally free the header. */ Blt_PoolFreeItem(rcPtr->headerPool, headerPtr); rcPtr->nUsed--; } /* *--------------------------------------------------------------------------- * * ClearRowNotifiers -- * * Removes all event handlers set for the designated row. Note that this * doesn't remove handlers triggered by row or column tags. Row and * column traces are stored in a chain. * *--------------------------------------------------------------------------- */ static void ClearRowNotifiers(Table *tablePtr, Row *rowPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->rowNotifiers); link != NULL; link = next) { Notifier *notifierPtr; next = Blt_Chain_NextLink(link); notifierPtr = Blt_Chain_GetValue(link); if (notifierPtr->header == (Header *)rowPtr) { Blt_Table_DeleteNotifier(notifierPtr); } } } /* *--------------------------------------------------------------------------- * * ClearColumnNotifiers -- * * Removes all event handlers set for the designated row. Note that this * doesn't remove handlers triggered by row or column tags. Row and * column traces are stored in a chain. * *--------------------------------------------------------------------------- */ static void ClearColumnNotifiers(Table *tablePtr, Column *colPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->columnNotifiers); link != NULL; link = next) { Notifier *notifierPtr; next = Blt_Chain_NextLink(link); notifierPtr = Blt_Chain_GetValue(link); if (notifierPtr->header == (Header *)colPtr) { Blt_Table_DeleteNotifier(notifierPtr); } } } /* *--------------------------------------------------------------------------- * * DoNotify -- * * Traverses the list of event callbacks for a client and checks if one * matches the given event. A client may trigger an action that causes * the itself to be notified again. This can be prevented by setting the * TABLE_NOTIFY_FOREIGN_ONLY bit in the event handler. * * If a matching handler is found, a callback may be called either * immediately or at the next idle time depending upon the * TABLE_NOTIFY_WHENIDLE bit. * * Since a handler routine may trigger yet another call to itself, * callbacks are ignored while the event handler is executing. * *--------------------------------------------------------------------------- */ static void DoNotify(Table *tablePtr, Blt_Chain chain, Blt_TableNotifyEvent *eventPtr) { Blt_ChainLink link; unsigned int eventMask; /* Check the client table for matching notifiers. Issue callbacks * indicating that the structure of the table has changed. */ eventMask = eventPtr->type & TABLE_NOTIFY_MASK; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Notifier *notifierPtr; int match; notifierPtr = Blt_Chain_GetValue(link); if ((notifierPtr->flags & eventMask) == 0) { continue; /* Event type doesn't match */ } if ((eventPtr->self) && (notifierPtr->flags&TABLE_NOTIFY_FOREIGN_ONLY)){ continue; /* Don't notify yourself. */ } if (notifierPtr->flags & TABLE_NOTIFY_ACTIVE) { continue; /* Ignore callbacks that are generated inside * of a notify handler routine. */ } match = FALSE; if (notifierPtr->tag != NULL) { if (notifierPtr->flags & TABLE_NOTIFY_ROW) { if (Blt_Table_HasRowTag(tablePtr, (Row *)eventPtr->header, notifierPtr->tag)) { match++; } } else { if (Blt_Table_HasColumnTag(tablePtr, (Column *)eventPtr->header, notifierPtr->tag)) { match++; } } } else if (notifierPtr->header == eventPtr->header) { match++; /* Offsets match. */ } else if (eventPtr->header == NULL) { match++; /* Event matches any notifier offset. */ } else if (notifierPtr->header == NULL) { match++; /* Notifier matches any event offset. */ } if (!match) { continue; /* Row or column doesn't match. */ } if (notifierPtr->flags & TABLE_NOTIFY_WHENIDLE) { if ((notifierPtr->flags & TABLE_NOTIFY_PENDING) == 0) { notifierPtr->flags |= TABLE_NOTIFY_PENDING; notifierPtr->event = *eventPtr; Tcl_DoWhenIdle(NotifyIdleProc, notifierPtr); } } else { NotifyIdleProc(notifierPtr); } } } /* *--------------------------------------------------------------------------- * * NotifyClients -- * * Traverses the list of event callbacks and checks if one matches the * given event. A client may trigger an action that causes the table * object to notify it. This can be prevented by setting the * TABLE_NOTIFY_FOREIGN_ONLY bit in the event handler. * * If a matching handler is found, a callback may be called either * immediately or at the next idle time depending upon the * TABLE_NOTIFY_WHENIDLE bit. * * Since a handler routine may trigger yet another call to itself, * callbacks are ignored while the event handler is executing. * *--------------------------------------------------------------------------- */ static void NotifyClients(Table *tablePtr, Blt_Chain chain, Header *header, unsigned int flags) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->corePtr->clients); link != NULL; link = next) { Blt_Table table; Blt_TableNotifyEvent event; next = Blt_Chain_NextLink(link); table = Blt_Chain_GetValue(link); event.type = flags; event.table = tablePtr; event.header = header; event.interp = tablePtr->interp; event.self = (table == tablePtr); DoNotify(table, chain, &event); } } /* *--------------------------------------------------------------------------- * * TriggerColumnNotifiers -- * * Traverses the list of event callbacks and checks if one matches the * given event. A client may trigger an action that causes the table * object to notify it. This can be prevented by setting the * TABLE_NOTIFY_FOREIGN_ONLY bit in the event handler. * * If a matching handler is found, a callback may be called either * immediately or at the next idle time depending upon the * TABLE_NOTIFY_WHENIDLE bit. * * Since a handler routine may trigger yet another call to itself, * callbacks are ignored while the event handler is executing. * *--------------------------------------------------------------------------- */ static void TriggerColumnNotifiers(Table *tablePtr, Column *colPtr, unsigned int flags) { if (Blt_Chain_GetLength(tablePtr->columnNotifiers) == 0) { return; /* No notifiers registered. */ } if (colPtr == NULL) { /* Indicates to trigger notifications * for all columns. */ long i; for (i = 1; i <= Blt_Table_NumColumns(tablePtr); i++) { colPtr = Blt_Table_Column(tablePtr, i); NotifyClients(tablePtr, tablePtr->columnNotifiers, (Header *)colPtr, flags | TABLE_NOTIFY_COLUMN); } } else { NotifyClients(tablePtr, tablePtr->columnNotifiers, (Header *)colPtr, flags | TABLE_NOTIFY_COLUMN); } } /* *--------------------------------------------------------------------------- * * TriggerRowNotifiers -- * * Traverses the list of event callbacks and checks if one matches the * given event. A client may trigger an action that causes the table * object to notify it. This can be prevented by setting the * TABLE_NOTIFY_FOREIGN_ONLY bit in the event handler. * * If a matching handler is found, a callback may be called either * immediately or at the next idle time depending upon the * TABLE_NOTIFY_WHENIDLE bit. * * Since a handler routine may trigger yet another call to itself, * callbacks are ignored while the event handler is executing. * *--------------------------------------------------------------------------- */ static void TriggerRowNotifiers(Table *tablePtr, Row *rowPtr, unsigned int flags) { if (Blt_Chain_GetLength(tablePtr->rowNotifiers) == 0) { return; /* No notifiers registered. */ } if (rowPtr == TABLE_NOTIFY_ALL) { long i; /* Trigger notifications for all rows. */ for (i = 1; i <= Blt_Table_NumRows(tablePtr); i++) { rowPtr = Blt_Table_Row(tablePtr, i); NotifyClients(tablePtr, tablePtr->rowNotifiers, (Header *)rowPtr, flags | TABLE_NOTIFY_ROW); } } else { NotifyClients(tablePtr, tablePtr->rowNotifiers, (Header *)rowPtr, flags | TABLE_NOTIFY_ROW); } } /* *--------------------------------------------------------------------------- * * Blt_Table_ClearRowTraces -- * * Removes all traces set for this row. Note that this doesn't remove * traces set for specific cells (row,column). Row traces are stored in * a chain, which in turn is held in a hash table, keyed by the row. * *--------------------------------------------------------------------------- */ void Blt_Table_ClearRowTraces(Table *tablePtr, Row *rowPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->traces); link != NULL; link = next) { Trace *tracePtr; next = Blt_Chain_NextLink(link); tracePtr = Blt_Chain_GetValue(link); if (tracePtr->row == rowPtr) { Blt_Table_DeleteTrace(tracePtr); } } } /* *--------------------------------------------------------------------------- * * Blt_Table_ClearColumnTraces -- * * Removes all traces set for this column. Note that this doesn't remove * traces set for specific cells (row,column). Column traces are stored * in a chain, which in turn is held in a hash table, keyed by the * column. * *--------------------------------------------------------------------------- */ void Blt_Table_ClearColumnTraces(Table *tablePtr, Blt_TableColumn column) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->traces); link != NULL; link = next) { Trace *tracePtr; next = Blt_Chain_NextLink(link); tracePtr = Blt_Chain_GetValue(link); if (tracePtr->column == column) { Blt_Table_DeleteTrace(tracePtr); } } } /* *--------------------------------------------------------------------------- * * DoTrace -- * * Fires a trace set by a client of the table object. Trace procedures * should return a standard TCL result. * * TCL_OK procedure executed successfully. * TCL_ERROR procedure failed. * TCL_BREAK don't execute any further trace procedures. * TCL_CONTINUE treat like TCL_OK. * * A trace procedure can in turn trigger more traces. Traces are * prohibited from recursively reentering their own trace procedures. A * hash table in the trace structure tracks the cells currently actively * traced. If a cell is already being traced, the trace procedure is not * called and TCL_OK is blindly returned. * * Results: * Returns the result of trace procedure. If the trace is already * active, then TCL_OK is returned. * * Side Effects: * Traces on the table location may be fired. * *--------------------------------------------------------------------------- */ static int DoTrace(Trace *tracePtr, Blt_TableTraceEvent *eventPtr) { int result; /* * Check for individual traces on a cell. Each trace has a hash table * that tracks what cells are actively being traced. This is to prevent * traces from triggering recursive callbacks. */ Tcl_Preserve(tracePtr); tracePtr->flags |= TABLE_TRACE_ACTIVE; result = (*tracePtr->proc)(tracePtr->clientData, eventPtr); tracePtr->flags &= ~TABLE_TRACE_ACTIVE; Tcl_Release(tracePtr); if (result == TCL_ERROR) { fprintf(stderr, "error in trace callback: %s\n", Tcl_GetStringResult(eventPtr->interp)); Tcl_BackgroundError(eventPtr->interp); } return result; } /* *--------------------------------------------------------------------------- * * CallTraces -- * * Examines the traces set for each client of the table object and fires * any matching traces. * * Traces match on row and column tag and indices and flags. * Traces can match on * flag type of trace (read, write, unset, create) * row index * column index * row tag * column tag * * If the TABLE_TRACE_FOREIGN_ONLY is set in the handler, it means to * ignore actions that are initiated by that client of the object. Only * actions by other clients are handled. * * Results: * Always returns TCL_OK. * * Side Effects: * Traces on the tuple table location may be fired. * *--------------------------------------------------------------------------- */ static void CallTraces(Table *tablePtr, Table *clientPtr, Row *rowPtr, Column *colPtr, unsigned int flags) { Blt_ChainLink link, next; Blt_TableTraceEvent event; /* Initialize trace event information. */ event.table = clientPtr; event.row = rowPtr; event.column = colPtr; event.interp = clientPtr->interp; if (tablePtr == clientPtr) { flags |= TABLE_TRACE_SELF; } event.mask = flags; for (link = Blt_Chain_FirstLink(clientPtr->traces); link != NULL; link = next) { Trace *tracePtr; int rowMatch, colMatch; next = Blt_Chain_NextLink(link); tracePtr = Blt_Chain_GetValue(link); if ((tracePtr->flags & flags) == 0) { continue; /* Doesn't match trace flags. */ } if (tracePtr->flags & TABLE_TRACE_ACTIVE) { continue; /* Ignore callbacks that were triggered from * the active trace handler routine. */ } rowMatch = colMatch = FALSE; if (tracePtr->colTag != NULL) { if (Blt_Table_HasColumnTag(clientPtr, colPtr, tracePtr->colTag)) { colMatch++; } } else if ((tracePtr->column == colPtr) || (tracePtr->column == NULL)) { colMatch++; } if (tracePtr->rowTag != NULL) { if (Blt_Table_HasRowTag(clientPtr, rowPtr, tracePtr->rowTag)) { rowMatch++; } } else if ((tracePtr->row == rowPtr) || (tracePtr->row == NULL)) { rowMatch++; } if (!rowMatch || !colMatch) { continue; } if (DoTrace(tracePtr, &event) == TCL_BREAK) { return; /* Don't complete traces on break. */ } } } /* *--------------------------------------------------------------------------- * * CallClientTraces -- * * Examines the traces set for each client of the table object and fires * any matching traces. * * Traces match on row and column indices and flags. * The order is * 1. column traces. * 2. row traces. * 3. cell (row,column) traces. * * If no matching criteria is specified (no tag, key, or tuple address) * then only the bit flag has to match. * * If the TABLE_TRACE_FOREIGN_ONLY is set in the handler, it means to * ignore actions that are initiated by that client of the object. Only * actions by other clients are handled. * * Results: * Always returns TCL_OK. * * Side Effects: * Traces on the tuple table location may be fired. * *--------------------------------------------------------------------------- */ static void CallClientTraces(Table *tablePtr, Row *rowPtr, Column *colPtr, unsigned int flags) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(tablePtr->corePtr->clients); link != NULL; link = next) { Table *clientPtr; next = Blt_Chain_NextLink(link); clientPtr = Blt_Chain_GetValue(link); CallTraces(tablePtr, clientPtr, rowPtr, colPtr, flags); } } /* *--------------------------------------------------------------------------- * * UnsetValue -- * * Removes the value from the selected row, column location in the table. * The row, column location must be within the actual table limits, but * it's okay if there isn't a value there to remove. * * Results: * None. * * Side Effects: * The objPtr representing the value is released. * *--------------------------------------------------------------------------- */ static void UnsetValue(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *valuePtr; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (!IsEmpty(valuePtr)) { /* Indicate the keytables need to be regenerated. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { tablePtr->flags |= TABLE_KEYS_DIRTY; } } FreeValue(valuePtr); } static void UnsetRowValues(Table *tablePtr, Row *rowPtr) { long i; for (i = 1; i <= Blt_Table_NumColumns(tablePtr); i++) { Column *colPtr; colPtr = Blt_Table_Column(tablePtr, i); UnsetValue(tablePtr, rowPtr, colPtr); } } static void UnsetColumnValues(Table *tablePtr, Column *colPtr) { Value *vector; long i; for (i = 1; i <= Blt_Table_NumRows(tablePtr); i++) { Row *rowPtr; rowPtr = Blt_Table_Row(tablePtr, i); UnsetValue(tablePtr, rowPtr, colPtr); } vector = tablePtr->corePtr->data[colPtr->offset]; if (vector != NULL) { FreeVector(vector, tablePtr->corePtr->rows.nAllocated); tablePtr->corePtr->data[colPtr->offset] = NULL; } } static int CompareDictionaryStrings(ClientData clientData, Value *valuePtr1, Value *valuePtr2) { if (IsEmpty(valuePtr1)) { if (IsEmpty(valuePtr2)) { return 0; } return 1; } else if (IsEmpty(valuePtr2)) { return -1; } return Blt_DictionaryCompare(valuePtr1->string, valuePtr2->string); } static int CompareAsciiStrings(ClientData clientData, Value *valuePtr1, Value *valuePtr2) { if (IsEmpty(valuePtr1)) { if (IsEmpty(valuePtr2)) { return 0; } return 1; } else if (IsEmpty(valuePtr2)) { return -1; } return strcmp(valuePtr1->string, valuePtr2->string); } static int CompareIntegers(ClientData clientData, Value *valuePtr1, Value *valuePtr2) { if (IsEmpty(valuePtr1)) { if (IsEmpty(valuePtr2)) { return 0; } return 1; } else if (IsEmpty(valuePtr2)) { return -1; } return valuePtr1->datum.l - valuePtr2->datum.l; } static int CompareDoubles(ClientData clientData, Value *valuePtr1, Value *valuePtr2) { if (IsEmpty(valuePtr1)) { if (IsEmpty(valuePtr2)) { return 0; } return 1; } else if (IsEmpty(valuePtr2)) { return -1; } if (valuePtr1->datum.d < valuePtr2->datum.d) { return -1; } else if (valuePtr1->datum.d > valuePtr2->datum.d) { return 1; } return 0; } typedef struct { Blt_Table table; Blt_TableSortOrder *order; long nColumns; unsigned int flags; } TableSortData; static TableSortData sortData; static int CompareRows(void *a, void *b) { Table *tablePtr; Blt_TableSortOrder *sp, *send; Row *rowPtr1, *rowPtr2; long result; tablePtr = sortData.table; rowPtr1 = *(Row **)a; rowPtr2 = *(Row **)b; for (sp = sortData.order, send = sp + sortData.nColumns; sp < send; sp++) { Column *colPtr; Value *valuePtr1, *valuePtr2, *vector; colPtr = sp->column; valuePtr1 = valuePtr2 = NULL; vector = tablePtr->corePtr->data[colPtr->offset]; if (vector != NULL) { valuePtr1 = vector + rowPtr1->offset; if (IsEmpty(valuePtr1)) { valuePtr1 = NULL; } valuePtr2 = vector + rowPtr2->offset; if (IsEmpty(valuePtr2)) { valuePtr2 = NULL; } } result = (*sp->sortProc)(sp->clientData, valuePtr1, valuePtr2); if (result != 0) { return (sortData.flags & SORT_DECREASING) ? -result : result; } } result = rowPtr1->index - rowPtr2->index; return (sortData.flags & SORT_DECREASING) ? -result : result; } static void InitSortProcs(Table *tablePtr, Blt_TableSortOrder *order, size_t n, int flags) { Blt_TableSortOrder *sp, *send; for (sp = order, send = sp + n; sp < send; sp++) { Column *colPtr; sp->clientData = tablePtr; colPtr = sp->column; switch (colPtr->type) { case TABLE_COLUMN_TYPE_INT: case TABLE_COLUMN_TYPE_LONG: sp->sortProc = CompareIntegers; break; case TABLE_COLUMN_TYPE_DOUBLE: sp->sortProc = CompareDoubles; break; case TABLE_COLUMN_TYPE_STRING: case TABLE_COLUMN_TYPE_UNKNOWN: default: if (flags & SORT_ASCII) { sp->sortProc = CompareAsciiStrings; } else { sp->sortProc = CompareDictionaryStrings; } break; } } } static Header ** SortHeaders(RowColumn *rcPtr, QSortCompareProc *proc) { long i; Header **map; /* Make a copy of the current row map. */ map = Blt_Malloc(sizeof(Header *) * rcPtr->nAllocated); if (map == NULL) { return NULL; } for (i = 0; i < rcPtr->nAllocated; i++) { map[i] = rcPtr->map[i]; } /* Sort the map and return it. */ qsort((char *)map, rcPtr->nUsed, sizeof(Header *), proc); return map; } static void ReplaceMap(RowColumn *rcPtr, Header **map) { Blt_Free(rcPtr->map); rcPtr->map = map; ResetMap(rcPtr); } static int MoveIndices( RowColumn *rcPtr, Header *srcPtr, /* Starting source index. */ Header *destPtr, /* Starting destination index. */ long count) /* # of rows or columns to move. */ { Header **newMap; /* Resulting reordered map. */ long src, dest; #ifdef notdef fprintf(stderr, "src=%ld, dest=%ld, count=%d\n", srcPtr->index, destPtr->index, count); fprintf(stderr, "%s nUsed=%d, nAllocated=%d\n", rcPtr->classPtr->name, rcPtr->nUsed, rcPtr->nAllocated); #endif if (srcPtr == destPtr) { return TRUE; } src = srcPtr->index, dest = destPtr->index; src--; dest--; newMap = Blt_Malloc(sizeof(Header *) * rcPtr->nAllocated); if (newMap == NULL) { return FALSE; } if (dest < src) { long i, j; /* * dest src * v v * | | | | | |x|x|x|x| | * A A B B B C C C C D * | | |x|x|x|x| | | | | * * Section C is the selected region to move. */ /* Section A: copy everything from 0 to "dest" */ for (i = 0; i < dest; i++) { newMap[i] = rcPtr->map[i]; } /* Section C: append the selected region. */ for (i = src, j = dest; i < (src + count); i++, j++) { newMap[j] = rcPtr->map[i]; } /* Section B: shift the preceding indices from "dest" to "src". */ for (i = dest; i < src; i++, j++) { newMap[j] = rcPtr->map[i]; } /* Section D: append trailing indices until the end. */ for (i = src + count; i < rcPtr->nUsed; i++, j++) { newMap[j] = rcPtr->map[i]; } } else if (src < dest) { long i, j; /* * src dest * v v * | | |x|x|x|x| | | | | * A A C C C C B B B D * | | | | | |x|x|x|x| | * * Section C is the selected region to move. */ /* Section A: copy everything from 0 to "src" */ for (j = 0; j < src; j++) { newMap[j] = rcPtr->map[j]; } /* Section B: shift the trailing indices from "src" to "dest". */ for (i = (src + count); j < dest; i++, j++) { newMap[j] = rcPtr->map[i]; } /* Section C: append the selected region. */ for (i = src; i < (src + count); i++, j++) { newMap[j] = rcPtr->map[i]; } /* Section D: append trailing indices until the end. */ for (i = dest + count; i < rcPtr->nUsed; i++, j++) { newMap[j] = rcPtr->map[i]; } } /* Reset the inverse offset-to-index map. */ ReplaceMap(rcPtr, newMap); return TRUE; } /* *--------------------------------------------------------------------------- * * ParseDumpRecord -- * * Gets the next full record in the dump string, returning the * record as a list. Blank lines and comments are ignored. * * Results: * TCL_RETURN The end of the string is reached. * TCL_ERROR An error occurred and an error message * is left in the interpreter result. * TCL_OK The next record has been successfully parsed. * *--------------------------------------------------------------------------- */ static int ParseDumpRecord( Tcl_Interp *interp, char **stringPtr, /* (in/out) points to current location * in in dump string. Updated after * parsing record. */ RestoreData *restorePtr) { char *entry, *eol; char saved; int result; entry = *stringPtr; /* Get first line, ignoring blank lines and comments. */ for (;;) { char *first; first = NULL; restorePtr->nLines++; /* Find the end of the first line. */ for (eol = entry; (*eol != '\n') && (*eol != '\0'); eol++) { if ((first == NULL) && (!isspace(UCHAR(*eol)))) { first = eol; /* Track first non-whitespace * character. */ } } if (first == NULL) { if (*eol == '\0') { return TCL_RETURN; } } else if (*first != '#') { break; /* Not a comment or blank line. */ } entry = eol + 1; } saved = *eol; *eol = '\0'; while (!Tcl_CommandComplete(entry)) { *eol = saved; if (*eol == '\0') { Tcl_AppendResult(interp, "incomplete dump record: \"", entry, "\"", (char *)NULL); return TCL_ERROR; /* Found EOF (incomplete * entry) or error. */ } /* Get the next line. */ for (eol = eol + 1; (*eol != '\n') && (*eol != '\0'); eol++) { /*empty*/ } restorePtr->nLines++; saved = *eol; *eol = '\0'; } if (entry == eol) { return TCL_RETURN; } result = Tcl_SplitList(interp, entry, &restorePtr->argc, &restorePtr->argv); *eol = saved; *stringPtr = eol + 1; return result; } /* *--------------------------------------------------------------------------- * * ReadDumpRecord -- * * Reads the next full record from the given channel, returning the * record as a list. Blank lines and comments are ignored. * * Results: * TCL_RETURN The end of the file has been reached. * TCL_ERROR A read error has occurred and an error message * is left in the interpreter result. * TCL_OK The next record has been successfully parsed. * *--------------------------------------------------------------------------- */ static int ReadDumpRecord(Tcl_Interp *interp, Tcl_Channel channel, RestoreData *restorePtr) { int result; Tcl_DString ds; Tcl_DStringInit(&ds); /* Get first line, ignoring blank lines and comments. */ for (;;) { const char *cp; int nBytes; Tcl_DStringSetLength(&ds, 0); nBytes = Tcl_Gets(channel, &ds); if (nBytes < 0) { if (Tcl_Eof(channel)) { return TCL_RETURN; } return TCL_ERROR; } restorePtr->nLines++; for (cp = Tcl_DStringValue(&ds); *cp != '\0'; cp++) { if (!isspace(UCHAR(*cp))) { break; } } if ((*cp != '\0') && (*cp != '#')) { break; /* Not a comment or blank line. */ } } Tcl_DStringAppend(&ds, "\n", 1); while (!Tcl_CommandComplete(Tcl_DStringValue(&ds))) { int nBytes; /* Process additional lines if needed */ nBytes = Tcl_Gets(channel, &ds); if (nBytes < 0) { Tcl_AppendResult(interp, "error reading file: ", Tcl_PosixError(interp), (char *)NULL); Tcl_DStringFree(&ds); return TCL_ERROR; /* Found EOF (incomplete * entry) or error. */ } restorePtr->nLines++; Tcl_DStringAppend(&ds, "\n", 1); } result = Tcl_SplitList(interp, Tcl_DStringValue(&ds), &restorePtr->argc, &restorePtr->argv); Tcl_DStringFree(&ds); return result; } static void RestoreError(Tcl_Interp *interp, RestoreData *restorePtr) { Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringGetResult(interp, &ds); Tcl_AppendResult(interp, restorePtr->fileName, ":", Blt_Ltoa(restorePtr->nLines), ": error: ", Tcl_DStringValue(&ds), (char *)NULL); Tcl_DStringFree(&ds); } static int RestoreHeader(Tcl_Interp *interp, Blt_Table table, RestoreData *restorePtr) { long nCols, nRows; long lval; /* i rows columns ctime mtime */ if (restorePtr->argc != 5) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "wrong # elements in restore header.", (char *)NULL); return TCL_ERROR; } if (Tcl_GetLong(interp, restorePtr->argv[1], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } if (lval < 1) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad # rows \"", restorePtr->argv[1], "\"", (char *)NULL); return TCL_ERROR; } nRows = lval; if (Tcl_GetLong(interp, restorePtr->argv[2], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } if (lval < 1) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad # columns \"", restorePtr->argv[2], "\"", (char *)NULL); return TCL_ERROR; } nCols = lval; if ((restorePtr->flags & TABLE_RESTORE_OVERWRITE) == 0) { nRows += restorePtr->nRows; nCols += restorePtr->nCols; } if (nCols > Blt_Table_NumColumns(table)) { long n; n = nCols - Blt_Table_NumColumns(table); if (!GrowColumns(table, n)) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "can't allocate \"", Blt_Ltoa(n), "\"", " extra columns.", (char *)NULL); return TCL_ERROR; } } if (nRows > Blt_Table_NumRows(table)) { long n; n = nRows - Blt_Table_NumRows(table); if (!GrowRows(table, n)) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "can't allocate \"", Blt_Ltoa(n), "\"", " extra rows.", (char *)NULL); return TCL_ERROR; } } if (Tcl_GetLong(interp, restorePtr->argv[3], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } restorePtr->ctime = (unsigned long)lval; if (Tcl_GetLong(interp, restorePtr->argv[4], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } restorePtr->mtime = (unsigned long)lval; return TCL_OK; } static int RestoreColumn(Tcl_Interp *interp, Blt_Table table, RestoreData *restorePtr) { long lval; long n; Column *colPtr; int type; const char *label; int isNew; Blt_HashEntry *hPtr; /* c index label type ?tagList? */ if ((restorePtr->argc < 4) || (restorePtr->argc > 5)) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "wrong # elements in restore column entry", (char *)NULL); return TCL_ERROR; } if (Tcl_GetLong(interp, restorePtr->argv[1], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } if (lval < 1) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad column index \"", restorePtr->argv[1], "\"", (char *)NULL); return TCL_ERROR; } n = lval; label = restorePtr->argv[2]; colPtr = Blt_Table_FindColumnByLabel(table, label); if ((colPtr == NULL) || ((restorePtr->flags & TABLE_RESTORE_OVERWRITE) == 0)) { colPtr = Blt_Table_CreateColumn(interp, table, label); if (colPtr == NULL) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "can't append column \"", label, "\"", (char *)NULL); return TCL_ERROR; } } hPtr = Blt_CreateHashEntry(&restorePtr->colIndices, (char *)n, &isNew); Blt_SetHashValue(hPtr, colPtr); type = Blt_Table_GetColumnType(restorePtr->argv[3]); if (type == TABLE_COLUMN_TYPE_UNKNOWN) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad column type \"", restorePtr->argv[3], "\"", (char *)NULL); return TCL_ERROR; } colPtr->type = type; if ((restorePtr->argc == 5) && ((restorePtr->flags & TABLE_RESTORE_NO_TAGS) == 0)) { int i, elc; const char **elv; if (Tcl_SplitList(interp, restorePtr->argv[4], &elc, &elv) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } for (i = 0; i < elc; i++) { if (Blt_Table_SetColumnTag(interp, table, colPtr, elv[i]) != TCL_OK) { Blt_Free(elv); return TCL_ERROR; } } Blt_Free(elv); } return TCL_OK; } static int RestoreRow(Tcl_Interp *interp, Blt_Table table, RestoreData *restorePtr) { Blt_TableRow row; Blt_HashEntry *hPtr; const char **elv; const char *label; int elc; int isNew; long lval; long n; /* r index label ?tagList? */ if ((restorePtr->argc < 3) || (restorePtr->argc > 4)) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "wrong # elements in restore row entry", (char *)NULL); return TCL_ERROR; } if (Tcl_GetLong(interp, restorePtr->argv[1], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } if (lval < 1) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad row index \"", restorePtr->argv[1], "\"", (char *)NULL); return TCL_ERROR; } n = lval; label = restorePtr->argv[2]; row = Blt_Table_FindRowByLabel(table, label); if ((row == NULL) || ((restorePtr->flags & TABLE_RESTORE_OVERWRITE) == 0)) { row = Blt_Table_CreateRow(interp, table, label); if (row == NULL) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "can't append row \"", label, "\"", (char *)NULL); return TCL_ERROR; } } hPtr = Blt_CreateHashEntry(&restorePtr->rowIndices, (char *)n, &isNew); Blt_SetHashValue(hPtr, row); if ((restorePtr->argc == 5) && ((restorePtr->flags & TABLE_RESTORE_NO_TAGS) == 0)) { int i; if (Tcl_SplitList(interp, restorePtr->argv[3], &elc, &elv) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } for (i = 0; i < elc; i++) { if (Blt_Table_SetRowTag(interp, table, row, elv[i]) != TCL_OK) { Blt_Free(elv); return TCL_ERROR; } } Blt_Free(elv); } return TCL_OK; } static int RestoreValue(Tcl_Interp *interp, Blt_Table table, RestoreData *restorePtr) { Blt_HashEntry *hPtr; int result; Blt_TableRow row; Blt_TableColumn col; long lval; /* d row column value */ if (restorePtr->argc != 4) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "wrong # elements in restore data entry", (char *)NULL); return TCL_ERROR; } if (Tcl_GetLong(interp, restorePtr->argv[1], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } hPtr = Blt_FindHashEntry(&restorePtr->rowIndices, (char *)lval); if (hPtr == NULL) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad row index \"", restorePtr->argv[1], "\"", (char *)NULL); return TCL_ERROR; } row = Blt_GetHashValue(hPtr); if (Tcl_GetLong(interp, restorePtr->argv[2], &lval) != TCL_OK) { RestoreError(interp, restorePtr); return TCL_ERROR; } hPtr = Blt_FindHashEntry(&restorePtr->colIndices, (char *)lval); if (hPtr == NULL) { RestoreError(interp, restorePtr); Tcl_AppendResult(interp, "bad column index \"", restorePtr->argv[2], "\"", (char *)NULL); return TCL_ERROR; } col = Blt_GetHashValue(hPtr); result = Blt_Table_SetString(table, row, col, restorePtr->argv[3], -1); if (result != TCL_OK) { RestoreError(interp, restorePtr); } return result; } Blt_TableRow * Blt_Table_RowMap(Table *tablePtr) { return (Blt_TableRow *)tablePtr->corePtr->rows.map; } Blt_TableColumn * Blt_Table_ColumnMap(Table *tablePtr) { return (Blt_TableColumn *)tablePtr->corePtr->columns.map; } Blt_HashEntry * Blt_Table_FirstRowTag(Table *tablePtr, Blt_HashSearch *cursorPtr) { return Blt_FirstHashEntry(tablePtr->rowTags, cursorPtr); } Blt_HashEntry * Blt_Table_FirstColumnTag(Table *tablePtr, Blt_HashSearch *cursorPtr) { return Blt_FirstHashEntry(tablePtr->columnTags, cursorPtr); } int Blt_Table_SameTableObject(Table *tablePtr1, Table *tablePtr2) { return tablePtr1->corePtr == tablePtr2->corePtr; } Blt_Chain Blt_Table_RowTags(Table *tablePtr, Row *rowPtr) { Blt_Chain chain; chain = Blt_Chain_Create(); DumpTags(tablePtr->rowTags, (Header *)rowPtr, chain); return chain; } Blt_TableRow Blt_Table_FindRowByIndex(Table *tablePtr, long index) { if ((index > 0) && (index <= Blt_Table_NumRows(tablePtr))) { return Blt_Table_Row(tablePtr, index); } return NULL; } Blt_TableColumn Blt_Table_FindColumnByIndex(Table *tablePtr, long index) { if ((index > 0) && (index <= Blt_Table_NumColumns(tablePtr))) { return Blt_Table_Column(tablePtr, index); } return NULL; } Blt_Chain Blt_Table_ColumnTags(Table *tablePtr, Blt_TableColumn col) { Blt_Chain chain; chain = Blt_Chain_Create(); DumpTags(tablePtr->columnTags, (Header *)col, chain); return chain; } Blt_TableRowColumnSpec Blt_Table_RowSpec(Blt_Table table, Tcl_Obj *objPtr, const char **stringPtr) { const char *string, *p; long lval; char c; string = Tcl_GetString(objPtr); *stringPtr = string; c = string[0]; if ((isdigit(UCHAR(c))) && (Tcl_GetLongFromObj((Tcl_Interp *)NULL, objPtr, &lval) == TCL_OK)) { return TABLE_SPEC_INDEX; } else if ((c == 'e') && (strcmp(string, "end") == 0)) { return TABLE_SPEC_TAG; } else if ((c == 'a') && (strcmp(string, "all") == 0)) { return TABLE_SPEC_TAG; } else if ((c == 'r') && (strncmp(string, "range=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_RANGE; } else if ((c == 'i') && (strncmp(string, "index=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_INDEX; } else if ((c == 'l') && (strncmp(string, "label=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_LABEL; } else if ((c == 't') && (strncmp(string, "tag=", 4) == 0)) { *stringPtr = string + 4; return TABLE_SPEC_TAG; } else if (Blt_Table_FindRowByLabel(table, string) != NULL) { return TABLE_SPEC_LABEL; } else if (Blt_Table_FindRowTagTable(table, string) != NULL) { return TABLE_SPEC_TAG; } p = strchr(string, '-'); if (p != NULL) { Tcl_Obj *rangeObjPtr; Blt_TableRow row; rangeObjPtr = Tcl_NewStringObj(string, p - string); row = Blt_Table_FindRow((Tcl_Interp *)NULL, table, rangeObjPtr); Tcl_DecrRefCount(rangeObjPtr); if (row != NULL) { rangeObjPtr = Tcl_NewStringObj(p + 1, -1); row = Blt_Table_FindRow((Tcl_Interp *)NULL, table, rangeObjPtr); Tcl_DecrRefCount(rangeObjPtr); if (row != NULL) { return TABLE_SPEC_RANGE; } } } return TABLE_SPEC_UNKNOWN; } Blt_TableColumn Blt_Table_FirstColumn(Table *tablePtr) { if (tablePtr->corePtr->columns.nUsed == 0) { return NULL; } return (Blt_TableColumn)tablePtr->corePtr->columns.map[0]; } Blt_TableColumn Blt_Table_NextColumn(Table *tablePtr, Column *colPtr) { long index; index = colPtr->index; if (index >= tablePtr->corePtr->columns.nUsed) { return NULL; } return (Blt_TableColumn)tablePtr->corePtr->columns.map[index]; } Blt_TableRow Blt_Table_FirstRow(Table *tablePtr) { if (tablePtr->corePtr->rows.nUsed == 0) { return NULL; } return (Blt_TableRow)tablePtr->corePtr->rows.map[0]; } Blt_TableRow Blt_Table_NextRow(Table *tablePtr, Row *rowPtr) { long index; index = rowPtr->index; if (index >= tablePtr->corePtr->rows.nUsed) { return NULL; } return (Blt_TableRow)tablePtr->corePtr->rows.map[index]; } /* *--------------------------------------------------------------------------- * * Blt_Table_IterateRows -- * * Returns the id of the first row derived from the given tag, * label or index represented in objPtr. * * Results: * Returns the row location of the first item. If no row * can be found, then -1 is returned and an error message is * left in the interpreter. * *--------------------------------------------------------------------------- */ int Blt_Table_IterateRows(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iterPtr) { Blt_TableRow row, from, to; const char *tagName, *p; int result; Tcl_Obj *rangeObjPtr; long lval; Blt_TableRowColumnSpec spec; memset(iterPtr, 0, sizeof(Blt_TableIterator)); iterPtr->table = table; iterPtr->type = TABLE_ITERATOR_INDEX; spec = Blt_Table_RowSpec(table, objPtr, &tagName); switch (spec) { case TABLE_SPEC_INDEX: p = Tcl_GetString(objPtr); if (p == tagName) { result = Tcl_GetLongFromObj((Tcl_Interp *)NULL, objPtr, &lval); } else { result = Tcl_GetLong((Tcl_Interp *)NULL, (char *)tagName, &lval); } if (result != TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "badly formed row index \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } if ((lval < 1) || (lval > Blt_Table_NumRows(table))) { if (interp != NULL) { Tcl_AppendResult(interp, "bad row index \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->start = iterPtr->end = lval; iterPtr->tagName = tagName; return TCL_OK; case TABLE_SPEC_LABEL: row = Blt_Table_FindRowByLabel(table, tagName); if (row == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find row label \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } return TCL_ERROR; } iterPtr->start = iterPtr->end = Blt_Table_RowIndex(row); return TCL_OK; case TABLE_SPEC_TAG: if (strcmp(tagName, "all") == 0) { iterPtr->type = TABLE_ITERATOR_ALL; iterPtr->start = 1; iterPtr->end = Blt_Table_NumRows(table); iterPtr->tagName = tagName; } else if (strcmp(tagName, "end") == 0) { iterPtr->tagName = tagName; iterPtr->start = iterPtr->end = Blt_Table_NumRows(table); } else { iterPtr->tablePtr = Blt_Table_FindRowTagTable(iterPtr->table, tagName); if (iterPtr->tablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find row tag \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } return TCL_ERROR; } iterPtr->type = TABLE_ITERATOR_TAG; iterPtr->tagName = tagName; } return TCL_OK; case TABLE_SPEC_RANGE: p = strchr(tagName, '-'); if (p == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "bad range specification \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } rangeObjPtr = Tcl_NewStringObj(tagName, p - tagName); from = Blt_Table_FindRow(interp, table, rangeObjPtr); Tcl_DecrRefCount(rangeObjPtr); if (from == NULL) { return TCL_ERROR; } rangeObjPtr = Tcl_NewStringObj(p + 1, -1); to = Blt_Table_FindRow(interp, table, rangeObjPtr); Tcl_DecrRefCount(rangeObjPtr); if (to == NULL) { return TCL_ERROR; } iterPtr->start = Blt_Table_RowIndex(from); iterPtr->end = Blt_Table_RowIndex(to); iterPtr->type = TABLE_ITERATOR_RANGE; iterPtr->tagName = tagName; return TCL_OK; default: if (interp != NULL) { Tcl_AppendResult(interp, "unknown row specification \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * Blt_Table_FirstTaggedRow -- * * Returns the id of the next row derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows * can be found, then -1 is returned. * *--------------------------------------------------------------------------- */ Blt_TableRow Blt_Table_FirstTaggedRow(Blt_TableIterator *iterPtr) { if (iterPtr->type == TABLE_ITERATOR_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } else if (iterPtr->type == TABLE_ITERATOR_CHAIN) { iterPtr->link = Blt_Chain_FirstLink(iterPtr->chain); if (iterPtr->link != NULL) { return Blt_Chain_GetValue(iterPtr->link); } } else if (iterPtr->start <= iterPtr->end) { Blt_TableRow row; row = Blt_Table_Row(iterPtr->table, iterPtr->start); iterPtr->next = iterPtr->start + 1; return row; } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Table_NextTaggedRow -- * * Returns the id of the next row derived from the given tag. * * Results: * Returns the row location of the first item. If no more rows * can be found, then -1 is returned. * *--------------------------------------------------------------------------- */ Blt_TableRow Blt_Table_NextTaggedRow(Blt_TableIterator *iterPtr) { if (iterPtr->type == TABLE_ITERATOR_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } else if (iterPtr->type == TABLE_ITERATOR_CHAIN) { iterPtr->link = Blt_Chain_NextLink(iterPtr->link); if (iterPtr->link != NULL) { return Blt_Chain_GetValue(iterPtr->link); } } else if (iterPtr->next <= iterPtr->end) { Blt_TableRow row; row = Blt_Table_Row(iterPtr->table, iterPtr->next); iterPtr->next++; return row; } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Table_FindRow -- * * Gets the row offset associated the given row index, tag, or * label. This routine is used when you want only one row index. * It's an error if more than one row is specified (e.g. "all" * tag or range "1:4"). It's also an error if the row tag is * empty (no rows are currently tagged). * *--------------------------------------------------------------------------- */ Blt_TableRow Blt_Table_FindRow(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr) { Blt_TableIterator iter; Blt_TableRow first, next; if (Blt_Table_IterateRows(interp, table, objPtr, &iter) != TCL_OK) { return NULL; } first = Blt_Table_FirstTaggedRow(&iter); if (first == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "no rows specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return NULL; } next = Blt_Table_NextTaggedRow(&iter); if (next != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple rows specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return NULL; } return first; } Blt_TableRowColumnSpec Blt_Table_ColumnSpec(Blt_Table table, Tcl_Obj *objPtr, const char **stringPtr) { const char *string, *p; long lval; char c; string = Tcl_GetString(objPtr); *stringPtr = string; c = string[0]; if ((isdigit(c)) && Tcl_GetLongFromObj((Tcl_Interp *)NULL, objPtr, &lval) == TCL_OK) { return TABLE_SPEC_INDEX; } else if ((c == 'e') && (strcmp(string, "end") == 0)) { return TABLE_SPEC_TAG; } else if ((c == 'a') && (strcmp(string, "all") == 0)) { return TABLE_SPEC_TAG; } else if ((c == 'r') && (strncmp(string, "range=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_RANGE; } else if ((c == 'i') && (strncmp(string, "index=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_INDEX; } else if ((c == 'l') && (strncmp(string, "label=", 6) == 0)) { *stringPtr = string + 6; return TABLE_SPEC_LABEL; } else if ((c == 't') && (strncmp(string, "tag=", 4) == 0)) { *stringPtr = string + 4; return TABLE_SPEC_TAG; } else if (Blt_Table_FindColumnTagTable(table, string) != NULL) { return TABLE_SPEC_TAG; } else if (Blt_Table_FindColumnByLabel(table, string) != NULL) { return TABLE_SPEC_LABEL; } p = strchr(string, '-'); if (p != NULL) { Tcl_Obj *objPtr; Blt_TableColumn col; objPtr = Tcl_NewStringObj(string, p - string); Tcl_IncrRefCount(objPtr); col = Blt_Table_FindColumn(NULL, table, objPtr); Tcl_DecrRefCount(objPtr); if (col != NULL) { objPtr = Tcl_NewStringObj(p + 1, -1); col = Blt_Table_FindColumn(NULL, table, objPtr); Tcl_DecrRefCount(objPtr); if (col != NULL) { return TABLE_SPEC_RANGE; } } } return TABLE_SPEC_UNKNOWN; } /* *--------------------------------------------------------------------------- * * Blt_Table_IterateColumns -- * * Returns the id of the first column derived from the given tag, * label or index represented in objPtr. * * Results: * Returns the column location of the first item. If no column * can be found, then -1 is returned and an error message is * left in the interpreter. * *--------------------------------------------------------------------------- */ int Blt_Table_IterateColumns(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iterPtr) { Blt_TableColumn col, from, to; const char *tagName, *p; int result; Tcl_Obj *fromObjPtr, *toObjPtr; long lval; Blt_TableRowColumnSpec spec; iterPtr->table = table; iterPtr->type = TABLE_ITERATOR_INDEX; spec = Blt_Table_ColumnSpec(table, objPtr, &tagName); switch (spec) { case TABLE_SPEC_INDEX: p = Tcl_GetString(objPtr); if (p == tagName) { result = Tcl_GetLongFromObj((Tcl_Interp *)NULL, objPtr, &lval); } else { result = Tcl_GetLong((Tcl_Interp *)NULL, (char *)tagName, &lval); } if (result != TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "badly formed column index \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } if ((lval < 1) || (lval > Blt_Table_NumColumns(table))) { if (interp != NULL) { Tcl_AppendResult(interp, "bad column index \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->start = iterPtr->end = lval; iterPtr->tagName = tagName; return TCL_OK; case TABLE_SPEC_LABEL: col = Blt_Table_FindColumnByLabel(table, tagName); if (col == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find column label \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } return TCL_ERROR; } iterPtr->start = iterPtr->end = Blt_Table_ColumnIndex(col); return TCL_OK; case TABLE_SPEC_TAG: if (strcmp(tagName, "all") == 0) { iterPtr->type = TABLE_ITERATOR_ALL; iterPtr->start = 1; iterPtr->end = Blt_Table_NumColumns(table); iterPtr->tagName = tagName; } else if (strcmp(tagName, "end") == 0) { iterPtr->tagName = tagName; iterPtr->start = iterPtr->end = Blt_Table_NumColumns(table); } else { iterPtr->tablePtr = Blt_Table_FindColumnTagTable(iterPtr->table, tagName); if (iterPtr->tablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find column tag \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } return TCL_ERROR; } iterPtr->type = TABLE_ITERATOR_TAG; iterPtr->tagName = tagName; } return TCL_OK; case TABLE_SPEC_RANGE: p = strchr(tagName, '-'); if (p == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "bad range specification \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } fromObjPtr = Tcl_NewStringObj(tagName, p - tagName); from = Blt_Table_FindColumn(interp, table, fromObjPtr); Tcl_DecrRefCount(fromObjPtr); if (from == NULL) { return TCL_ERROR; } toObjPtr = Tcl_NewStringObj(p + 1, -1); to = Blt_Table_FindColumn(interp, table, toObjPtr); Tcl_DecrRefCount(toObjPtr); if (to == NULL) { return TCL_ERROR; } iterPtr->start = Blt_Table_ColumnIndex(from); iterPtr->end = Blt_Table_ColumnIndex(to); iterPtr->type = TABLE_ITERATOR_RANGE; iterPtr->tagName = tagName; return TCL_OK; default: if (interp != NULL) { Tcl_AppendResult(interp, "unknown column specification \"", tagName, "\" in ", Blt_Table_TableName(table),(char *)NULL); } } return TCL_ERROR; } #ifdef notdef /* *--------------------------------------------------------------------------- * * Blt_Table_IterateColumns -- * * Initials the table iterator to walk through the columns tagged by the * given tag, label, or index, as represented in objPtr. * * Notes: * * 1) A tag doesn't need to point to any columns. It can be empty. This * routine does not check if a tag represents any columns, only that the * tag itself exists. * * 2) If a column label and tag are the same string, the label always * wins. * * 3) A range of columns can be represented by "from x to y" x:y x-y {x y} * * Results: * A standard TCL result. If there is an error parsing the index or tag, * then TCL_ERROR is returned and an error message is left in the * interpreter. * *--------------------------------------------------------------------------- */ int Blt_Table_IterateColumns(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr, Blt_TableIterator *iterPtr) { long lval; const char *p, *rp, *pend; const char *tagName; int nBytes; int badrange; iterPtr->table = table; iterPtr->type = TABLE_ITERATOR_INDEX; iterPtr->next = -1; tagName = Tcl_GetStringFromObj(objPtr, &nBytes); rp = NULL; for (p = tagName, pend = p + nBytes; p < pend; p++) { if (*p != '-') { continue; } if (rp != NULL) { /* Found more than one range specifier. We'll assume it's * not a range and try is as a regular index, tag, or * label. */ rp = NULL; break; } rp = p; } badrange = FALSE; if ((rp != NULL) && (rp != tagName) && (rp != (pend - 1))) { long length; Tcl_Obj *objPtr1, *objPtr2; Blt_TableColumn from, to; int result; length = rp - tagName; objPtr1 = Tcl_NewStringObj(tagName, length); rp++; objPtr2 = Tcl_NewStringObj(rp, pend - rp); from = Blt_Table_FindColumn(interp, table, objPtr1); if (from != NULL) { to = Blt_Table_FindColumn(interp, table, objPtr2); } Tcl_DecrRefCount(objPtr1); Tcl_DecrRefCount(objPtr2); if (to != NULL) { iterPtr->start = Blt_Table_ColumnIndex(from); iterPtr->end = Blt_Table_ColumnIndex(to); iterPtr->type = TABLE_ITERATOR_RANGE; return TCL_OK; } badrange = TRUE; } if (Tcl_GetLongFromObj((Tcl_Interp *)NULL, objPtr, &lval) == TCL_OK) { if ((lval < 1) || (lval > Blt_Table_NumColumns(table))) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find column: bad column index \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->start = iterPtr->end = lval; return TCL_OK; } else if (strcmp(tagName, "all") == 0) { iterPtr->type = TABLE_ITERATOR_ALL; iterPtr->start = 1; iterPtr->end = Blt_Table_NumColumns(table); return TCL_OK; } else if (strcmp(tagName, "end") == 0) { iterPtr->start = iterPtr->end = Blt_Table_NumColumns(table); return TCL_OK; } else { Column *colPtr; colPtr = Blt_Table_FindColumnByLabel(table, tagName); if (colPtr != NULL) { iterPtr->start = iterPtr->end = colPtr->index; return TCL_OK; } iterPtr->tablePtr = Blt_Table_FindColumnTagTable(iterPtr->table, tagName); if (iterPtr->tablePtr != NULL) { iterPtr->type = TABLE_ITERATOR_TAG; return TCL_OK; } } if ((interp != NULL) && (!badrange)) { Tcl_AppendResult(interp, "can't find column tag \"", tagName, "\" in ", Blt_Table_TableName(table), (char *)NULL); } return TCL_ERROR; } #endif /* *--------------------------------------------------------------------------- * * Blt_Table_FirstTaggedColumn -- * * Returns the first column based upon given iterator. * * Results: * Returns the column location of the first item. If no more columns * can be found, then -1 is returned. * *--------------------------------------------------------------------------- */ Blt_TableColumn Blt_Table_FirstTaggedColumn(Blt_TableIterator *iterPtr) { if (iterPtr->type == TABLE_ITERATOR_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } else if (iterPtr->type == TABLE_ITERATOR_CHAIN) { iterPtr->link = Blt_Chain_FirstLink(iterPtr->chain); if (iterPtr->link != NULL) { return Blt_Chain_GetValue(iterPtr->link); } } else if (iterPtr->start <= iterPtr->end) { Blt_TableColumn col; col = Blt_Table_Column(iterPtr->table, iterPtr->start); iterPtr->next = iterPtr->start + 1; return col; } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Table_NextTaggedColumn -- * * Returns the column location of the next column using the given * iterator. * * Results: * Returns the column location of the next item. If no more columns can * be found, then -1 is returned. * *--------------------------------------------------------------------------- */ Blt_TableColumn Blt_Table_NextTaggedColumn(Blt_TableIterator *iterPtr) { if (iterPtr->type == TABLE_ITERATOR_TAG) { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } else if (iterPtr->type == TABLE_ITERATOR_CHAIN) { iterPtr->link = Blt_Chain_NextLink(iterPtr->link); if (iterPtr->link != NULL) { return Blt_Chain_GetValue(iterPtr->link); } } else if (iterPtr->next <= iterPtr->end) { Blt_TableColumn col; col = Blt_Table_Column(iterPtr->table, iterPtr->next); iterPtr->next++; return col; } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_Table_FindColumn -- * *--------------------------------------------------------------------------- */ Blt_TableColumn Blt_Table_FindColumn(Tcl_Interp *interp, Blt_Table table, Tcl_Obj *objPtr) { Blt_TableIterator iter; Blt_TableColumn first, next; if (Blt_Table_IterateColumns(interp, table, objPtr, &iter) != TCL_OK) { return NULL; } first = Blt_Table_FirstTaggedColumn(&iter); if (first == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "no columns specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return NULL; } next = Blt_Table_NextTaggedColumn(&iter); if (next != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple columns specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return NULL; } return first; } int Blt_Table_ListColumns(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_Chain chain) { Blt_ChainLink link; Blt_HashTable cols; int i; Blt_InitHashTableWithPool(&cols, BLT_ONE_WORD_KEYS); /* Initialize the hash table with the existing entries. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { int isNew; Blt_TableColumn col; col = Blt_Chain_GetValue(link); Blt_CreateHashEntry(&cols, (char *)col, &isNew); } /* Collect the columns into a hash table. */ for (i = 0; i < objc; i++) { Blt_TableIterator iter; Blt_TableColumn col; if (Blt_Table_IterateColumns(interp, table, objv[i], &iter) != TCL_OK) { Blt_DeleteHashTable(&cols); return TCL_ERROR; } for (col = Blt_Table_FirstTaggedColumn(&iter); col != NULL; col = Blt_Table_NextTaggedColumn(&iter)) { int isNew; Blt_CreateHashEntry(&cols, (char *)col, &isNew); if (isNew) { Blt_Chain_Append(chain, col); } } } Blt_DeleteHashTable(&cols); return TCL_OK; } int Blt_Table_ListRows(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_Chain chain) { Blt_ChainLink link; Blt_HashTable rows; int i; Blt_InitHashTableWithPool(&rows, BLT_ONE_WORD_KEYS); /* Initialize the hash table with the existing entries. */ for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { int isNew; Blt_TableRow row; row = Blt_Chain_GetValue(link); Blt_CreateHashEntry(&rows, (char *)row, &isNew); } for (i = 0; i < objc; i++) { Blt_TableIterator iter; Blt_TableRow row; if (Blt_Table_IterateRows(interp, table, objv[i], &iter) != TCL_OK){ Blt_DeleteHashTable(&rows); return TCL_ERROR; } /* Append the new rows onto the chain. */ for (row = Blt_Table_FirstTaggedRow(&iter); row != NULL; row = Blt_Table_NextTaggedRow(&iter)) { int isNew; Blt_CreateHashEntry(&rows, (char *)row, &isNew); if (isNew) { Blt_Chain_Append(chain, row); } } } Blt_DeleteHashTable(&rows); return TCL_OK; } int Blt_Table_IterateRowsObjv(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_TableIterator *iterPtr) { Blt_Chain chain; chain = Blt_Chain_Create(); if (Blt_Table_ListRows(interp, table, objc, objv, chain) != TCL_OK) { Blt_Chain_Destroy(chain); return TCL_ERROR; } iterPtr->type = TABLE_ITERATOR_CHAIN; iterPtr->start = 1; iterPtr->end = 1; iterPtr->chain = chain; iterPtr->tagName = ""; return TCL_OK; } void Blt_Table_IterateAllRows(Blt_Table table, Blt_TableIterator *iterPtr) { iterPtr->table = table; iterPtr->type = TABLE_ITERATOR_ALL; iterPtr->start = 1; iterPtr->end = Blt_Table_NumRows(table); iterPtr->tagName = "all"; iterPtr->chain = NULL; } int Blt_Table_IterateColumnsObjv(Tcl_Interp *interp, Blt_Table table, int objc, Tcl_Obj *const *objv, Blt_TableIterator *iterPtr) { Blt_Chain chain; chain = Blt_Chain_Create(); if (Blt_Table_ListColumns(interp, table, objc, objv, chain) != TCL_OK) { Blt_Chain_Destroy(chain); return TCL_ERROR; } iterPtr->type = TABLE_ITERATOR_CHAIN; iterPtr->start = 1; iterPtr->end = 1; iterPtr->chain = chain; iterPtr->tagName = ""; return TCL_OK; } void Blt_Table_IterateAllColumns(Blt_Table table, Blt_TableIterator *iterPtr) { iterPtr->table = table; iterPtr->type = TABLE_ITERATOR_ALL; iterPtr->start = 1; iterPtr->end = Blt_Table_NumColumns(table); iterPtr->tagName = "all"; iterPtr->chain = NULL; } void Blt_Table_FreeIteratorObjv(Blt_TableIterator *iterPtr) { if ((iterPtr->type == TABLE_ITERATOR_CHAIN) && (iterPtr->chain != NULL)) { Blt_Chain_Destroy(iterPtr->chain); iterPtr->chain = NULL; } } /* *--------------------------------------------------------------------------- * * FreeTrace -- * * Memory is deallocated for the trace. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeTrace(Trace *tracePtr) { if (tracePtr->rowTag != NULL) { Blt_Free(tracePtr->rowTag); } if (tracePtr->colTag != NULL) { Blt_Free(tracePtr->colTag); } if (tracePtr->link != NULL) { Blt_Chain_DeleteLink(tracePtr->chain, tracePtr->link); } Blt_Free(tracePtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_DeleteTrace -- * * Deletes a trace. * * Results: * None. * * Side Effects: * Memory is deallocated for the trace. * *--------------------------------------------------------------------------- */ void Blt_Table_DeleteTrace(Trace *tracePtr) { if ((tracePtr->flags & TABLE_TRACE_DESTROYED) == 0) { if (tracePtr->deleteProc != NULL) { (*tracePtr->deleteProc)(tracePtr->clientData); } /* * This accomplishes two things. * 1) It doesn't let it anything match the trace and * 2) marks the trace as invalid. */ tracePtr->flags = TABLE_TRACE_DESTROYED; Tcl_EventuallyFree(tracePtr, (Tcl_FreeProc *)FreeTrace); } } /* *--------------------------------------------------------------------------- * * Blt_Table_Traces -- * * Returns the chain of traces for a particular client. * * Results: * Returns a pointer to the chain containing the traces for the * given row. If the row has no traces, then NULL is returned. * *--------------------------------------------------------------------------- */ Blt_Chain Blt_Table_Traces(Table *tablePtr) { return tablePtr->traces; } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateTrace -- * * Creates a trace for one or more tuples with one or more column keys. * Whenever a matching action occurs in the table object, the specified * procedure is executed. * * Results: * Returns a token for the trace. * * Side Effects: * Memory is allocated for the trace. * *--------------------------------------------------------------------------- */ Blt_TableTrace Blt_Table_CreateTrace( Table *tablePtr, /* Table to be traced. */ Row *rowPtr, Column *colPtr, /* Cell in table. */ const char *rowTag, const char *colTag, unsigned int flags, /* Bit mask indicating what actions to * trace. */ Blt_TableTraceProc *proc, /* Callback procedure for the trace. */ Blt_TableTraceDeleteProc *deleteProc, ClientData clientData) /* One-word of data passed along when * the callback is executed. */ { Trace *tracePtr; tracePtr = Blt_Calloc(1, sizeof (Trace)); if (tracePtr == NULL) { return NULL; } tracePtr->row = rowPtr; tracePtr->column = colPtr; if (rowTag != NULL) { tracePtr->rowTag = Blt_AssertStrdup(rowTag); } if (colTag != NULL) { tracePtr->colTag = Blt_AssertStrdup(colTag); } tracePtr->flags = flags; tracePtr->proc = proc; tracePtr->deleteProc = deleteProc; tracePtr->clientData = clientData; tracePtr->chain = tablePtr->traces; tracePtr->link = Blt_Chain_Append(tablePtr->traces, tracePtr); return tracePtr; } Blt_TableTrace Blt_Table_CreateColumnTrace( Table *tablePtr, /* Table to be traced. */ Column *colPtr, /* Cell in table. */ unsigned int flags, /* Bit mask indicating what actions to * trace. */ Blt_TableTraceProc *proc, /* Callback procedure for the trace. */ Blt_TableTraceDeleteProc *deleteProc, ClientData clientData) /* One-word of data passed along when * the callback is executed. */ { return Blt_Table_CreateTrace(tablePtr, NULL, colPtr, NULL, NULL, flags, proc, deleteProc, clientData); } Blt_TableTrace Blt_Table_CreateColumnTagTrace( Table *tablePtr, /* Table to be traced. */ const char *colTag, /* Cell in table. */ unsigned int flags, /* Bit mask indicating what actions to * trace. */ Blt_TableTraceProc *proc, /* Callback procedure for the trace. */ Blt_TableTraceDeleteProc *deleteProc, ClientData clientData) /* One-word of data passed along when * the callback is executed. */ { return Blt_Table_CreateTrace(tablePtr, NULL, NULL, NULL, colTag, flags, proc, deleteProc, clientData); } Blt_TableTrace Blt_Table_CreateRowTrace( Table *tablePtr, /* Table to be traced. */ Row *rowPtr, /* Cell in table. */ unsigned int flags, /* Bit mask indicating what actions to * trace. */ Blt_TableTraceProc *proc, /* Callback procedure for the trace. */ Blt_TableTraceDeleteProc *deleteProc, ClientData clientData) /* One-word of data passed along when * the callback is executed. */ { return Blt_Table_CreateTrace(tablePtr, rowPtr, NULL, NULL, NULL, flags, proc, deleteProc, clientData); } Blt_TableTrace Blt_Table_CreateRowTagTrace( Table *tablePtr, /* Table to be traced. */ const char *rowTag, /* Cell in table. */ unsigned int flags, /* Bit mask indicating what actions to * trace. */ Blt_TableTraceProc *proc, /* Callback procedure for the trace. */ Blt_TableTraceDeleteProc *deleteProc, ClientData clientData) /* One-word of data passed along when * the callback is executed. */ { return Blt_Table_CreateTrace(tablePtr, NULL, NULL, rowTag, NULL, flags, proc, deleteProc, clientData); } /* *--------------------------------------------------------------------------- * * Blt_Table_ReleaseTags -- * * Releases the tag table used by this client. * * Results: * None. * * Side Effects: * If no client is using the table, then it is freed. * *--------------------------------------------------------------------------- */ void Blt_Table_ReleaseTags(Table *tablePtr) { Tags *tagsPtr; tagsPtr = tablePtr->tags; tagsPtr->refCount--; if (tagsPtr->refCount <= 0) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&tagsPtr->rowTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&tagsPtr->rowTable); tablePtr->rowTags = NULL; for (hPtr = Blt_FirstHashEntry(&tagsPtr->columnTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); } Blt_DeleteHashTable(&tagsPtr->columnTable); Blt_Free(tagsPtr); tablePtr->columnTags = NULL; } } /* *--------------------------------------------------------------------------- * * Blt_TableTagsAreShared -- * * Returns whether the tag table is shared with another client. * * Results: * Returns TRUE if the current tag table is shared with another * client, FALSE otherwise. * *--------------------------------------------------------------------------- */ int Blt_Table_TagsAreShared(Table *tablePtr) { return (tablePtr->tags->refCount > 1); } /* *--------------------------------------------------------------------------- * * Blt_Table_FindRowTagTable -- * * Returns the hash table containing row indices for a tag. * * Results: * Returns a pointer to the hash table containing indices for the given * tag. If the row has no tags, then NULL is returned. * *--------------------------------------------------------------------------- */ Blt_HashTable * Blt_Table_FindRowTagTable(Table *tablePtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr->rowTags, tagName); if (hPtr == NULL) { return NULL; /* Row isn't tagged. */ } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_FindColumnTagTable -- * * Returns the hash table containing column indices for a tag. * * Results: * Returns a pointer to the hash table containing indices for the given * tag. If the tag has no indices, then NULL is returned. * *--------------------------------------------------------------------------- */ Blt_HashTable * Blt_Table_FindColumnTagTable(Table *tablePtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr->columnTags, tagName); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_ForgetRowTag -- * * Removes a tag from the row tag table. Row tags are contained in hash * tables keyed by the tag name. Each table is in turn hashed by the row * index in the row tag table. * * Results: * None. * * Side Effects: * Entries for the given tag in the corresponding row in hash tables may * be removed. * *--------------------------------------------------------------------------- */ int Blt_Table_ForgetRowTag(Tcl_Interp *interp, Table *tablePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Can't forget reserved tags. */ } hPtr = Blt_FindHashEntry(tablePtr->rowTags, tagName); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown row tag \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; /* No such row tag. */ } tagTablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tagTablePtr); Blt_Free(tagTablePtr); Blt_DeleteHashEntry(tablePtr->rowTags, hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_ForgetColumnTag -- * * Removes a tag from the column tag table. Column tags are contained in * hash tables keyed by the tag name. Each table is in turn hashed by * the column offset in the column tag table. * * Results: * None. * * Side Effects: * Entries for the given tag in the corresponding column in hash tables * may be removed. * *--------------------------------------------------------------------------- */ int Blt_Table_ForgetColumnTag(Tcl_Interp *interp, Table *tablePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Can't forget reserved tags. */ } hPtr = Blt_FindHashEntry(tablePtr->columnTags, tagName); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown column tag \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; /* No such column tag. */ } tagTablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tagTablePtr); Blt_Free(tagTablePtr); Blt_DeleteHashEntry(tablePtr->columnTags, hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_SetRowTag -- * * Associates a tag with a given row. Individual row tags are stored in * hash tables keyed by the tag name. Each table is in turn stored in a * hash table keyed by the row location. * * Results: * None. * * Side Effects: * A tag is stored for a particular row. * *--------------------------------------------------------------------------- */ int Blt_Table_SetRowTag(Tcl_Interp *interp, Table *tablePtr, Row *rowPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; int isNew; long dummy; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Don't need to create reserved tags. */ } if (tagName[0] == '\0') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be empty.", (char *)NULL); } return TCL_ERROR; } if (tagName[0] == '-') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't start with a '-'.", (char *)NULL); } return TCL_ERROR; } if (Tcl_GetLong(NULL, (char *)tagName, &dummy) == TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be a number.", (char *)NULL); } return TCL_ERROR; } hPtr = Blt_CreateHashEntry(tablePtr->rowTags, tagName, &isNew); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't add tag \"", tagName, "\": out of memory", (char *)NULL); } return TCL_ERROR; } if (isNew) { tagTablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tagTablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tagTablePtr); } else { tagTablePtr = Blt_GetHashValue(hPtr); } if (rowPtr != NULL) { hPtr = Blt_CreateHashEntry(tagTablePtr, (char *)rowPtr, &isNew); if (isNew) { Blt_SetHashValue(hPtr, rowPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_SetColumnTag -- * * Associates a tag with a given column. Individual column tags * are stored in hash tables keyed by the tag name. Each table * is in turn stored in a hash table keyed by the column * location. * * Results: * None. * * Side Effects: * A tag is stored for a particular column. * *--------------------------------------------------------------------------- */ int Blt_Table_SetColumnTag(Tcl_Interp *interp, Table *tablePtr, Column *columnPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; int isNew; long dummy; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Don't create reserved tags. */ } if (tagName[0] == '\0') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be empty.", (char *)NULL); } return TCL_ERROR; } if (tagName[0] == '-') { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't start with a '-'.", (char *)NULL); } return TCL_ERROR; } if (Tcl_GetLong(NULL, (char *)tagName, &dummy) == TCL_OK) { if (interp != NULL) { Tcl_AppendResult(interp, "tag \"", tagName, "\" can't be a number.", (char *)NULL); } return TCL_ERROR; } hPtr = Blt_CreateHashEntry(tablePtr->columnTags, tagName, &isNew); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't add tag \"", tagName, "\": out of memory", (char *)NULL); } return TCL_ERROR; } if (isNew) { tagTablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tagTablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tagTablePtr); } else { tagTablePtr = Blt_GetHashValue(hPtr); } if (columnPtr != NULL) { hPtr = Blt_CreateHashEntry(tagTablePtr, (char *)columnPtr, &isNew); if (isNew) { Blt_SetHashValue(hPtr, columnPtr); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_HasRowTag -- * * Checks if a tag is associated with the given row. * * Results: * Returns TRUE if the tag is found, FALSE otherwise. * *--------------------------------------------------------------------------- */ int Blt_Table_HasRowTag(Table *tablePtr, Row *rowPtr, const char *tagName) { Blt_HashTable *tagTablePtr; Blt_HashEntry *hPtr; if (strcmp(tagName, "all") == 0) { return TRUE; /* "all" tags matches every row. */ } if (strcmp(tagName, "end") == 0) { return (Blt_Table_RowIndex(rowPtr) == Blt_Table_NumRows(tablePtr)); } tagTablePtr = Blt_Table_FindRowTagTable(tablePtr, tagName); if (tagTablePtr == NULL) { return FALSE; } hPtr = Blt_FindHashEntry(tagTablePtr, (char *)rowPtr); if (hPtr != NULL) { return TRUE; /* Found tag in row tag table. */ } return FALSE; } /* *--------------------------------------------------------------------------- * * Blt_Table_HasColumnTag -- * * Checks if a tag is associated with the given column. * * Results: * Returns TRUE if the tag is found, FALSE otherwise. * *--------------------------------------------------------------------------- */ int Blt_Table_HasColumnTag(Table *tablePtr, Column *colPtr, const char *tagName) { Blt_HashTable *tagTablePtr; Blt_HashEntry *hPtr; if (strcmp(tagName, "all") == 0) { return TRUE; /* "all" tags matches every column. */ } if (strcmp(tagName, "end") == 0) { return (Blt_Table_ColumnIndex(colPtr) == Blt_Table_NumColumns(tablePtr)); } tagTablePtr = Blt_Table_FindColumnTagTable(tablePtr, tagName); if (tagTablePtr == NULL) { return FALSE; } hPtr = Blt_FindHashEntry(tagTablePtr, (char *)colPtr); if (hPtr != NULL) { return TRUE; /* Found tag in column tag table. */ } return FALSE; } /* *--------------------------------------------------------------------------- * * Blt_Table_UnsetRowTag -- * * Removes a tag from a given row. * * Results: * A standard TCL result. If an error occurred, TCL_ERROR * is returned and the interpreter result contains the error * message. * * Side Effects: * The tag associated with the row is freed. * *--------------------------------------------------------------------------- */ int Blt_Table_UnsetRowTag(Tcl_Interp *interp, Table *tablePtr, Row *rowPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Can't remove reserved tags. */ } tagTablePtr = Blt_Table_FindRowTagTable(tablePtr, tagName); if (tagTablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown row tag \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } hPtr = Blt_FindHashEntry(tagTablePtr, (char *)rowPtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tagTablePtr, hPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_UnsetColumnTag -- * * Removes a tag from a given column. * * Results: * A standard TCL result. If an error occurred, TCL_ERROR * is returned and the interpreter result contains the error * message. * * Side Effects: * The tag associated with the column is freed. * *--------------------------------------------------------------------------- */ int Blt_Table_UnsetColumnTag(Tcl_Interp *interp, Table *tablePtr, Column *colPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tagTablePtr; if ((strcmp(tagName, "all") == 0) || (strcmp(tagName, "end") == 0)) { return TCL_OK; /* Can't remove reserved tags. */ } tagTablePtr = Blt_Table_FindColumnTagTable(tablePtr, tagName); if (tagTablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown column tag \"", tagName, "\"", (char *)NULL); } return TCL_ERROR; } hPtr = Blt_FindHashEntry(tagTablePtr, (char *)colPtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tagTablePtr, hPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_ClearRowTags -- * * Removes all tags for a given row. * * Results: * None. * * Side Effects: * All tags associated with the row are freed. * *--------------------------------------------------------------------------- */ void Blt_Table_ClearRowTags(Table *tablePtr, Row *rowPtr) { ClearTags(tablePtr->rowTags, (Header *)rowPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_ClearColumnTags -- * * Removes all tags for a given column. * * Results: * None. * * Side Effects: * All tags associated with the column are freed. * *--------------------------------------------------------------------------- */ void Blt_Table_ClearColumnTags(Table *tablePtr, Column *colPtr) { ClearTags(tablePtr->columnTags, (Header *)colPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_GetValue -- * * Gets a scalar Tcl_Obj value from the table at the designated * row, column location. "Read" traces may be fired *before* the * value is retrieved. If no value exists at that location, * *objPtrPtr is set to NULL. * * Results: * A standard TCL result. Returns TCL_OK if successful accessing * the table location. If an error occurs, TCL_ERROR is returned * and an error message is left in the interpreter. * * -------------------------------------------------------------------------- */ Blt_TableValue Blt_Table_GetValue(Table *tablePtr, Row *rowPtr, Column *colPtr) { return GetValue(tablePtr, rowPtr, colPtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_SetValue -- * * Sets a scalar Tcl_Obj value in the table at the designated row and * column. "Write" and possibly "create" or "unset" traces may be fired * *after* the value is set. If valuePtr is NULL, this indicates to * unset the old value. * * Results: * A standard TCL result. Returns TCL_OK if successful setting the value * at the table location. If an error occurs, TCL_ERROR is returned and * an error message is left in the interpreter. * * -------------------------------------------------------------------------- */ int Blt_Table_SetValue(Table *tablePtr, Row *rowPtr, Column *colPtr, Value *newPtr) { Value *valuePtr; int flags; valuePtr = GetValue(tablePtr, rowPtr, colPtr); flags = TABLE_TRACE_WRITES; if (IsEmpty(newPtr)) { /* New value is empty. Effectively * unsetting the value. */ flags |= TABLE_TRACE_UNSETS; } else if (IsEmpty(valuePtr)) { flags |= TABLE_TRACE_CREATES; /* Old value was empty. */ } FreeValue(valuePtr); *valuePtr = *newPtr; /* Copy the value. */ if (newPtr->string != NULL) { valuePtr->string = Blt_AssertStrdup(newPtr->string); } CallClientTraces(tablePtr, rowPtr, colPtr, flags); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_GetObj -- * * Gets a scalar Tcl_Obj value from the table at the designated * row, column location. "Read" traces may be fired *before* the * value is retrieved. If no value exists at that location, * *objPtrPtr is set to NULL. * * Results: * A standard TCL result. Returns TCL_OK if successful accessing * the table location. If an error occurs, TCL_ERROR is returned * and an error message is left in the interpreter. * * -------------------------------------------------------------------------- */ Tcl_Obj * Blt_Table_GetObj(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *valuePtr; Tcl_Obj *objPtr; CallClientTraces(tablePtr, rowPtr, colPtr, TABLE_TRACE_READS); valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { return NULL; } objPtr = GetObjFromValue(tablePtr->interp, colPtr->type, valuePtr); return objPtr; } /* *--------------------------------------------------------------------------- * * Blt_Table_SetObj -- * * Sets a scalar Tcl_Obj value in the table at the designated row and * column. "Write" and possibly "create" or "unset" traces may be fired * *after* the value is set. If valueObjPtr is NULL, this indicates to * unset the old value. * * Results: * A standard TCL result. Returns TCL_OK if successful setting the value * at the table location. If an error occurs, TCL_ERROR is returned and * an error message is left in the interpreter. * * -------------------------------------------------------------------------- */ int Blt_Table_SetObj(Table *tablePtr, Row *rowPtr, Column *colPtr, Tcl_Obj *objPtr) { unsigned int flags; Value *valuePtr; valuePtr = GetValue(tablePtr, rowPtr, colPtr); flags = TABLE_TRACE_WRITES; if (objPtr == NULL) { /* New value is empty. Effectively * unsetting the value. */ flags |= TABLE_TRACE_UNSETS; } else if (IsEmpty(valuePtr)) { flags |= TABLE_TRACE_CREATES; } if (SetValueFromObj(tablePtr->interp, colPtr->type, objPtr, valuePtr) != TCL_OK) { return TCL_ERROR; } CallClientTraces(tablePtr, rowPtr, colPtr, flags); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_UnsetValue -- * * Unsets a scalar Tcl_Obj value in the table at the designated row, * column location. It's okay is there is presently no value at the * location. Unset traces may be fired *before* the value is unset. * * Results: * A standard TCL result. Returns TCL_OK if successful unsetting the * value at the table location. If an error occurs, TCL_ERROR is * returned and an error message is left in the interpreter. * * -------------------------------------------------------------------------- */ int Blt_Table_UnsetValue(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *valuePtr; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (!IsEmpty(valuePtr)) { CallClientTraces(tablePtr, rowPtr, colPtr, TABLE_TRACE_UNSETS); /* Indicate the keytables need to be regenerated. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { tablePtr->flags |= TABLE_KEYS_DIRTY; } FreeValue(valuePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateObject -- * * Creates a table object by the designated name. It's an error if a * table object already exists by that name. * * Results: * A standard TCL result. If successful, a new table object is created * and TCL_OK is returned. If an object already exists or the table * object can't be allocated, then TCL_ERROR is returned and an error * message is left in the interpreter. * * Side Effects: * A new table object is created. * *--------------------------------------------------------------------------- */ int Blt_Table_CreateTable( Tcl_Interp *interp, /* Interpreter to report errors back to. */ const char *name, /* Name of tuple in namespace. Object must * not already exist. */ Table **tablePtrPtr) /* (out) Client token of newly created table * object. Releasing the token will free the * tuple. If NULL, no token is generated. */ { InterpData *dataPtr; TableObject *corePtr; Blt_ObjectName objName; Table *newClientPtr; Tcl_DString ds; char *qualName; char string[200]; dataPtr = GetInterpData(interp); if (name != NULL) { /* Check if a client by this name already exist in the current * namespace. */ if (GetTable(dataPtr, name, NS_SEARCH_CURRENT) != NULL) { Tcl_AppendResult(interp, "a table object \"", name, "\" already exists", (char *)NULL); return TCL_ERROR; } } else { /* Generate a unique name in the current namespace. */ do { sprintf_s(string, 200, "datatable%d", dataPtr->nextId++); } while (GetTable(dataPtr, name, NS_SEARCH_CURRENT) != NULL); name = string; } /* * Tear apart and put back together the namespace-qualified name of the * object. This is to ensure that naming is consistent. */ if (!Blt_ParseObjectName(interp, name, &objName, 0)) { return TCL_ERROR; } corePtr = NewTableObject(); if (corePtr == NULL) { Tcl_AppendResult(interp, "can't allocate table object.", (char *)NULL); Tcl_DStringFree(&ds); return TCL_ERROR; } qualName = Blt_MakeQualifiedName(&objName, &ds); newClientPtr = NewTable(dataPtr, corePtr, qualName); Tcl_DStringFree(&ds); if (newClientPtr == NULL) { Tcl_AppendResult(interp, "can't allocate table token", (char *)NULL); return TCL_ERROR; } if (tablePtrPtr != NULL) { *tablePtrPtr = newClientPtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_Open -- * * Allocates a token for the table object designated by name. It's an * error if no table object exists by that name. The token returned is * passed to various routines to manipulate the object. Traces and event * notifications are also made through the token. * * Results: * A new token is returned representing the table object. * * Side Effects: * If this is the remaining client, then the table object itself is * freed. * *--------------------------------------------------------------------------- */ int Blt_Table_Open( Tcl_Interp *interp, /* Interpreter to report errors back to. */ const char *name, /* Name of table object in namespace. */ Table **tablePtrPtr) { Table *tablePtr, *newClientPtr; InterpData *dataPtr; dataPtr = GetInterpData(interp); tablePtr = GetTable(dataPtr, name, NS_SEARCH_BOTH); if ((tablePtr == NULL) || (tablePtr->corePtr == NULL)) { Tcl_AppendResult(interp, "can't find a table object \"", name, "\"", (char *)NULL); return TCL_ERROR; } newClientPtr = NewTable(dataPtr, tablePtr->corePtr, name); if (newClientPtr == NULL) { Tcl_AppendResult(interp, "can't allocate token for table \"", name, "\"", (char *)NULL); return TCL_ERROR; } *tablePtrPtr = newClientPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_Close -- * * Releases the tuple token, indicating this the client is no longer * using the object. The client is removed from the tuple object's client * list. If this is the last client, then the object itself is destroyed * and memory is freed. * * Results: * None. * * Side Effects: * If this is the remaining client, then the table object itself * is freed. * *--------------------------------------------------------------------------- */ void Blt_Table_Close(Table *tablePtr) { Blt_Chain chain; if (tablePtr->magic != TABLE_MAGIC) { fprintf(stderr, "invalid table object token 0x%lx\n", (unsigned long)tablePtr); return; } chain = Blt_GetHashValue(tablePtr->hPtr); Blt_Chain_DeleteLink(chain, tablePtr->link2); if (Blt_Chain_GetLength(chain) == 0) { Blt_DeleteHashEntry(tablePtr->tablePtr, tablePtr->hPtr); } DestroyTable(tablePtr); } /* *--------------------------------------------------------------------------- * * Blt_Table_TableExists -- * * Indicates if a table object by the given name exists in either the * current or global namespace. * * Results: * Returns 1 if a table object exists and 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_Table_TableExists(Tcl_Interp *interp, const char *name) { InterpData *dataPtr; dataPtr = GetInterpData(interp); return (GetTable(dataPtr, name, NS_SEARCH_BOTH) != NULL); } static Notifier * AppendNotifier(Tcl_Interp *interp, Blt_Chain chain, unsigned int mask, Header *headerPtr, const char *tag, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deleteProc, ClientData clientData) { Notifier *notifierPtr; notifierPtr = Blt_AssertMalloc(sizeof (Notifier)); notifierPtr->proc = proc; notifierPtr->deleteProc = deleteProc; notifierPtr->chain = chain; notifierPtr->clientData = clientData; notifierPtr->header = headerPtr; notifierPtr->tag = (tag != NULL) ? Blt_AssertStrdup(tag) : NULL; notifierPtr->flags = mask; notifierPtr->interp = interp; notifierPtr->link = Blt_Chain_Append(chain, notifierPtr); return notifierPtr; } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateColumnNotifier -- * * Creates an event handler using the following three pieces of * information: * 1. C function pointer, * 2. one-word of data passed on each call, and * 3. event mask indicating which events are of interest. * If an event already exists matching all of the above criteria, * it is repositioned on the end of the event handler list. This * means that it will be the last to fire. * * Results: * Returns a pointer to the event handler. * * Side Effects: * Memory for the event handler is possibly allocated. * *--------------------------------------------------------------------------- */ Blt_TableNotifier Blt_Table_CreateColumnNotifier(Tcl_Interp *interp, Table *tablePtr, Blt_TableColumn col, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deletedProc, ClientData clientData) { return AppendNotifier(interp, tablePtr->columnNotifiers, mask | TABLE_NOTIFY_COLUMN, (Header *)col, NULL, proc, deletedProc, clientData); } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateColumnTagNotifier -- * * Creates an event handler using the following three pieces of * information: * 1. C function pointer, * 2. one-word of data passed on each call, and * 3. event mask indicating which events are of interest. * If an event already exists matching all of the above criteria, * it is repositioned on the end of the event handler list. This * means that it will be the last to fire. * * Results: * Returns a pointer to the event handler. * * Side Effects: * Memory for the event handler is possibly allocated. * *--------------------------------------------------------------------------- */ Blt_TableNotifier Blt_Table_CreateColumnTagNotifier(Tcl_Interp *interp, Table *tablePtr, const char *tag, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deletedProc, ClientData clientData) { return AppendNotifier(interp, tablePtr->columnNotifiers, mask | TABLE_NOTIFY_COLUMN, (Header *)NULL, tag, proc, deletedProc, clientData); } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateRowNotifier -- * * Creates an event handler using the following three pieces of * information: * 1. C function pointer, * 2. one-word of data passed on each call, and * 3. event mask indicating which events are of interest. * If an event already exists matching all of the above criteria, * it is repositioned on the end of the event handler list. This * means that it will be the last to fire. * * Results: * Returns a pointer to the event handler. * * Side Effects: * Memory for the event handler is possibly allocated. * *--------------------------------------------------------------------------- */ Blt_TableNotifier Blt_Table_CreateRowNotifier(Tcl_Interp *interp, Table *tablePtr, Blt_TableRow row, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deletedProc, ClientData clientData) { return AppendNotifier(interp, tablePtr->rowNotifiers, mask | TABLE_NOTIFY_ROW, (Header *)row, NULL, proc, deletedProc, clientData); } /* *--------------------------------------------------------------------------- * * Blt_Table_CreateColumnTagNotifier -- * * Creates an event handler using the following three pieces of * information: * 1. C function pointer, * 2. one-word of data passed on each call, and * 3. event mask indicating which events are of interest. * If an event already exists matching all of the above criteria, * it is repositioned on the end of the event handler list. This * means that it will be the last to fire. * * Results: * Returns a pointer to the event handler. * * Side Effects: * Memory for the event handler is possibly allocated. * *--------------------------------------------------------------------------- */ Blt_TableNotifier Blt_Table_CreateRowTagNotifier(Tcl_Interp *interp, Table *tablePtr, const char *tag, unsigned int mask, Blt_TableNotifyEventProc *proc, Blt_TableNotifierDeleteProc *deletedProc, ClientData clientData) { return AppendNotifier(interp, tablePtr->rowNotifiers, mask | TABLE_NOTIFY_ROW, (Header *)NULL, tag, proc, deletedProc, clientData); } /* *--------------------------------------------------------------------------- * * Blt_Table_DeleteNotifier -- * * Removes the event handler designated by following three pieces * of information: * 1. C function pointer, * 2. one-word of data passed on each call, and * 3. event mask indicating which events are of interest. * * Results: * Nothing. * * Side Effects: * Memory for the event handler is freed. * *--------------------------------------------------------------------------- */ void Blt_Table_DeleteNotifier(Notifier *notifierPtr) { /* Check if notifier is already being deleted. */ if ((notifierPtr->flags & TABLE_NOTIFY_DESTROYED) == 0) { if (notifierPtr->deleteProc != NULL) { (*notifierPtr->deleteProc)(notifierPtr->clientData); } if (notifierPtr->flags & TABLE_NOTIFY_PENDING) { Tcl_CancelIdleCall(NotifyIdleProc, notifierPtr); } notifierPtr->flags = TABLE_NOTIFY_DESTROYED; Tcl_EventuallyFree(notifierPtr, (Tcl_FreeProc *)FreeNotifier); } } /* *--------------------------------------------------------------------------- * * Blt_Table_FindRowByLabel -- * * Returns the offset of the row given its label. If the row label is * invalid, then -1 is returned. * * Results: * Returns the offset of the row or -1 if not found. * *--------------------------------------------------------------------------- */ Blt_TableRow Blt_Table_FindRowByLabel(Table *tablePtr, const char *label) { return (Blt_TableRow)FindLabel(&tablePtr->corePtr->rows, label); } /* *--------------------------------------------------------------------------- * * Blt_Table_FindColumnByLabel -- * * Returns the offset of the column given its label. If the column label * is invalid, then -1 is returned. * * Results: * Returns the offset of the column or -1 if not found. * *--------------------------------------------------------------------------- */ Blt_TableColumn Blt_Table_FindColumnByLabel(Table *tablePtr, const char *label) { return (Blt_TableColumn)FindLabel(&tablePtr->corePtr->columns, label); } /* *--------------------------------------------------------------------------- * * Blt_Table_SetRowLabel -- * * Returns the label of the row. If the row offset is invalid or the row * has no label, then NULL is returned. * * Results: * Returns the label of the row. * *--------------------------------------------------------------------------- */ int Blt_Table_SetRowLabel(Tcl_Interp *interp, Table *tablePtr, Row *rowPtr, const char *label) { return SetHeaderLabel(interp, &tablePtr->corePtr->rows, (Header *)rowPtr, label); } /* *--------------------------------------------------------------------------- * * Blt_Table_SetColumnLabel -- * * Sets the label of the column. If the column offset is invalid, then * no label is set. * * Results: * None. * *--------------------------------------------------------------------------- */ int Blt_Table_SetColumnLabel(Tcl_Interp *interp, Table *tablePtr, Column *colPtr, const char *label) { return SetHeaderLabel(interp, &tablePtr->corePtr->columns, (Header *)colPtr, label); } /* *--------------------------------------------------------------------------- * * Blt_Table_SetColumnType -- * * Sets the type of the given column. * * Results: * None. * *--------------------------------------------------------------------------- */ int Blt_Table_SetColumnType(Table *tablePtr, Column *colPtr, Blt_TableColumnType type) { return SetType(tablePtr, colPtr, type); } /* *--------------------------------------------------------------------------- * * Blt_Table_ValueExists -- * * Indicates if a value exists for a given row,column offset in the * tuple. Note that this routine does not fire read traces. * * Results: * Returns 1 is a value exists, 0 otherwise. * *--------------------------------------------------------------------------- */ int Blt_Table_ValueExists(Table *tablePtr, Row *rowPtr, Column *colPtr) { return !IsEmpty(GetValue(tablePtr, rowPtr, colPtr)); } /* *--------------------------------------------------------------------------- * * Blt_Table_ExtendRows -- * * Adds new rows to the table. Rows are slots in an array of Rows. The * array grows by doubling its size, so there may be more slots than * needed (# rows). * * Results: * Returns TCL_OK is the tuple is resized and TCL_ERROR if an not enough * memory was available. * * Side Effects: * If more rows are needed, the array which holds the tuples is * reallocated by doubling its size. * *--------------------------------------------------------------------------- */ int Blt_Table_ExtendRows(Tcl_Interp *interp, Blt_Table table, size_t n, Row **rows) { size_t i; Blt_Chain chain; Blt_ChainLink link; if (n == 0) { return TCL_OK; } chain = Blt_Chain_Create(); if (!ExtendRows(table, n, chain)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't extend table by ", Blt_Ltoa(n), " rows: out of memory.", (char *)NULL); } Blt_Chain_Destroy(chain); return TCL_ERROR; } for (i = 0, link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link), i++) { Blt_TableRow row; row = Blt_Chain_GetValue(link); if (rows != NULL) { rows[i] = row; } } TriggerColumnNotifiers(table, TABLE_NOTIFY_ALL, TABLE_NOTIFY_ROW_CREATED); Blt_Chain_Destroy(chain); return TCL_OK; } int Blt_Table_DeleteRow(Table *tablePtr, Row *rowPtr) { DeleteHeader(&tablePtr->corePtr->rows, (Header *)rowPtr); UnsetRowValues(tablePtr, rowPtr); TriggerColumnNotifiers(tablePtr, TABLE_NOTIFY_ALL,TABLE_NOTIFY_ROW_DELETED); TriggerRowNotifiers(tablePtr, rowPtr, TABLE_NOTIFY_ROW_DELETED); Blt_Table_ClearRowTags(tablePtr, rowPtr); Blt_Table_ClearRowTraces(tablePtr, rowPtr); ClearRowNotifiers(tablePtr, rowPtr); tablePtr->flags |= TABLE_KEYS_DIRTY; return TCL_OK; } Blt_TableRow Blt_Table_CreateRow(Tcl_Interp *interp, Blt_Table table, const char *label) { Row *rowPtr; if (Blt_Table_ExtendRows(interp, table, 1, &rowPtr) != TCL_OK) { return NULL; } if (label != NULL) { if (Blt_Table_SetRowLabel(interp, table, rowPtr, label) != TCL_OK) { Blt_Table_DeleteRow(table, rowPtr); return NULL; } } return rowPtr; } /* *--------------------------------------------------------------------------- * * Blt_Table_MoveRows -- * * Move one of more rows to a new location in the tuple. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_Table_MoveRows(Tcl_Interp *interp, Table *tablePtr, Row *srcPtr, Row *destPtr, size_t count) { if (srcPtr == destPtr) { return TCL_OK; /* Move to the same location. */ } if (!MoveIndices(&tablePtr->corePtr->rows, (Header *)srcPtr, (Header *)destPtr, count)) { Tcl_AppendResult(interp, "can't allocate new map for \"", Blt_Table_TableName(tablePtr), "\"", (char *)NULL); return TCL_ERROR; } TriggerColumnNotifiers(tablePtr, TABLE_NOTIFY_ALL, TABLE_NOTIFY_ROW_MOVED); return TCL_OK; } void Blt_Table_SetRowMap(Table *tablePtr, Row **map) { TriggerColumnNotifiers(tablePtr, TABLE_NOTIFY_ALL, TABLE_NOTIFY_ROW_MOVED); ReplaceMap(&tablePtr->corePtr->rows, (Header **)map); } Blt_TableRow * Blt_Table_SortRows(Table *tablePtr, Blt_TableSortOrder *order, size_t nColumns, unsigned int flags) { sortData.table = tablePtr; sortData.order = order; sortData.nColumns = nColumns; sortData.flags = flags; InitSortProcs(tablePtr, order, nColumns, flags); return (Blt_TableRow *)SortHeaders(&tablePtr->corePtr->rows, (QSortCompareProc *)CompareRows); } /* *--------------------------------------------------------------------------- * * Blt_Table_DeleteColumn -- * * Remove the designated column from the table. The actual space * contained by the column isn't freed. The map is compressed. Tcl_Objs * stored as column values are released. Traces and tags associated with * the column are removed. * * Side Effects: * Traces may fire when column values are unset. Also notifier events * may be triggered, indicating the column has been deleted. * *--------------------------------------------------------------------------- */ int Blt_Table_DeleteColumn(Table *tablePtr, Column *colPtr) { /* If the deleted column is a primary key, the generated keytables * are now invalid. So remove them. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { Blt_Table_UnsetKeys(tablePtr); } UnsetColumnValues(tablePtr, colPtr); TriggerColumnNotifiers(tablePtr, colPtr, TABLE_NOTIFY_COLUMN_DELETED); TriggerRowNotifiers(tablePtr, TABLE_NOTIFY_ALL,TABLE_NOTIFY_COLUMN_DELETED); Blt_Table_ClearColumnTraces(tablePtr, colPtr); Blt_Table_ClearColumnTags(tablePtr, colPtr); ClearColumnNotifiers(tablePtr, colPtr); DeleteHeader(&tablePtr->corePtr->columns, (Header *)colPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_ExtendColumns -- * * Adds new columns to the table. Columns are slots in an array of * Columns. The array columns by doubling its size, so there may be more * slots than needed (# columns). * * Results: * Returns TCL_OK is the tuple is resized and TCL_ERROR if an * not enough memory was available. * * Side Effects: * If more columns are needed, the array which holds the tuples is * reallocated by doubling its size. * *--------------------------------------------------------------------------- */ int Blt_Table_ExtendColumns(Tcl_Interp *interp, Blt_Table table, size_t n, Column **cols) { size_t i; Blt_Chain chain; Blt_ChainLink link; chain = Blt_Chain_Create(); if (!ExtendColumns(table, n, chain)) { if (interp != NULL) { Tcl_AppendResult(interp, "can't extend table by ", Blt_Ltoa(n), " columns: out of memory.", (char *)NULL); } Blt_Chain_Destroy(chain); return TCL_ERROR; } for (i = 0, link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link), i++) { Column *colPtr; colPtr = Blt_Chain_GetValue(link); if (cols != NULL) { cols[i] = colPtr; } colPtr->type = TABLE_COLUMN_TYPE_STRING; } TriggerRowNotifiers(table, TABLE_NOTIFY_ALL, TABLE_NOTIFY_COLUMN_CREATED); Blt_Chain_Destroy(chain); return TCL_OK; } Blt_TableColumn Blt_Table_CreateColumn(Tcl_Interp *interp, Blt_Table table, const char *label) { Column *colPtr; if (Blt_Table_ExtendColumns(interp, table, 1, &colPtr) != TCL_OK) { return NULL; } if (label != NULL) { if (Blt_Table_SetColumnLabel(interp, table, colPtr, label) != TCL_OK) { Blt_Table_DeleteColumn(table, colPtr); return NULL; } } return colPtr; } void Blt_Table_SetColumnMap(Table *tablePtr, Column **map) { TriggerRowNotifiers(tablePtr, TABLE_NOTIFY_ALL, TABLE_NOTIFY_COLUMN_MOVED); ReplaceMap(&tablePtr->corePtr->columns, (Header **)map); } /* *--------------------------------------------------------------------------- * * Blt_Table_MoveColumns -- * * Move one of more rows to a new location in the tuple. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_Table_MoveColumns(Tcl_Interp *interp, Table *tablePtr, Column *srcPtr, Column *destPtr, size_t count) { if (srcPtr == destPtr) { return TCL_OK; /* Move to the same location. */ } if (!MoveIndices(&tablePtr->corePtr->columns, (Header *)srcPtr, (Header *)destPtr, count)) { Tcl_AppendResult(interp, "can't allocate new map for \"", Blt_Table_TableName(tablePtr), "\"", (char *)NULL); return TCL_ERROR; } TriggerRowNotifiers(tablePtr, TABLE_NOTIFY_ALL, TABLE_NOTIFY_COLUMN_MOVED); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_Restore -- * * Restores data to the given table based upon the dump string. * The dump string should have been generated by Blt_Table_Dump. * Two bit flags may be set. * * TABLE_RESTORE_NO_TAGS Don't restore tag information. * TABLE_RESTORE_OVERWRITE Look for row and columns with the * same label. Overwrite if necessary. * * Results: * A standard TCL result. If the restore was successful, TCL_OK * is returned. Otherwise, TCL_ERROR is returned and an error * message is left in the interpreter result. * * Side Effects: * New row and columns are created in the table and may possibly * generate event notifier or trace callbacks. * *--------------------------------------------------------------------------- */ int Blt_Table_Restore(Tcl_Interp *interp, Blt_Table table, char *data, unsigned int flags) { RestoreData restore; int result; restore.argc = 0; restore.mtime = restore.ctime = 0L; restore.argv = NULL; restore.fileName = "data string"; restore.nLines = 0; restore.flags = flags; restore.nCols = Blt_Table_NumColumns(table); restore.nRows = Blt_Table_NumRows(table); Blt_InitHashTableWithPool(&restore.rowIndices, BLT_ONE_WORD_KEYS); Blt_InitHashTableWithPool(&restore.colIndices, BLT_ONE_WORD_KEYS); result = TCL_ERROR; /* Read dump information */ for (;;) { char c1, c2; result = ParseDumpRecord(interp, &data, &restore); if (result != TCL_OK) { break; } if (restore.argc == 0) { continue; } c1 = restore.argv[0][0], c2 = restore.argv[0][1]; if ((c1 == 'i') && (c2 == '\0')) { result = RestoreHeader(interp, table, &restore); } else if ((c1 == 'r') && (c2 == '\0')) { result = RestoreRow(interp, table, &restore); } else if ((c1 == 'c') && (c2 == '\0')) { result = RestoreColumn(interp, table, &restore); } else if ((c1 == 'd') && (c2 == '\0')) { result = RestoreValue(interp, table, &restore); } else { Tcl_AppendResult(interp, restore.fileName, ":", Blt_Ltoa(restore.nLines), ": error: unknown entry \"", restore.argv[0], "\"", (char *)NULL); result = TCL_ERROR; } Blt_Free(restore.argv); if (result != TCL_OK) { break; } } Blt_DeleteHashTable(&restore.rowIndices); Blt_DeleteHashTable(&restore.colIndices); if (result == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_FileRestore -- * * Restores data to the given table based upon the dump file * provided. The dump file should have been generated by * Blt_Table_Dump or Blt_Table_FileDump. * * If the filename starts with an '@', then it is the name of an * already opened channel to be used. Two bit flags may be set. * * TABLE_RESTORE_NO_TAGS Don't restore tag information. * TABLE_RESTORE_OVERWRITE Look for row and columns with * the same label. Overwrite if necessary. * * Results: * A standard TCL result. If the restore was successful, TCL_OK * is returned. Otherwise, TCL_ERROR is returned and an error * message is left in the interpreter result. * * Side Effects: * Row and columns are created in the table and may possibly * generate trace or notifier event callbacks. * *--------------------------------------------------------------------------- */ int Blt_Table_FileRestore(Tcl_Interp *interp, Blt_Table table, const char *fileName, unsigned int flags) { RestoreData restore; Tcl_Channel channel; int closeChannel; int result; closeChannel = TRUE; if ((fileName[0] == '@') && (fileName[1] != '\0')) { int mode; channel = Tcl_GetChannel(interp, fileName+1, &mode); if (channel == NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", fileName, "\" not opened for reading", (char *)NULL); return TCL_ERROR; } closeChannel = FALSE; } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); if (channel == NULL) { return TCL_ERROR; /* Can't open dump file. */ } } restore.argc = 0; restore.mtime = restore.ctime = 0L; restore.argv = NULL; restore.fileName = fileName; restore.nLines = 0; restore.flags = flags; restore.nCols = Blt_Table_NumColumns(table); restore.nRows = Blt_Table_NumRows(table); Blt_InitHashTableWithPool(&restore.rowIndices, BLT_ONE_WORD_KEYS); Blt_InitHashTableWithPool(&restore.colIndices, BLT_ONE_WORD_KEYS); /* Process dump information record by record. */ result = TCL_ERROR; for (;;) { char c1, c2; result = ReadDumpRecord(interp, channel, &restore); if (result != TCL_OK) { break; } if (restore.argc == 0) { continue; } c1 = restore.argv[0][0], c2 = restore.argv[0][1]; if ((c1 == 'i') && (c2 == '\0')) { result = RestoreHeader(interp, table, &restore); } else if ((c1 == 'r') && (c2 == '\0')) { result = RestoreRow(interp, table, &restore); } else if ((c1 == 'c') && (c2 == '\0')) { result = RestoreColumn(interp, table, &restore); } else if ((c1 == 'd') && (c2 == '\0')) { result = RestoreValue(interp, table, &restore); } else { Tcl_AppendResult(interp, fileName, ":", Blt_Ltoa(restore.nLines), ": error: unknown entry \"", restore.argv[0], "\"", (char *)NULL); result = TCL_ERROR; } Blt_Free(restore.argv); if (result != TCL_OK) { break; } } Blt_DeleteHashTable(&restore.rowIndices); Blt_DeleteHashTable(&restore.colIndices); if (result == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } static void FreePrimaryKeys(Table *tablePtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(tablePtr->primaryKeys); link != NULL; link = Blt_Chain_NextLink(link)) { Column *columnPtr; columnPtr = Blt_Chain_GetValue(link); columnPtr->flags &= ~TABLE_COLUMN_PRIMARY_KEY; } Blt_Chain_Destroy(tablePtr->primaryKeys); tablePtr->primaryKeys = NULL; } static void FreeKeyTables(Table *tablePtr) { long i; for (i = 0; i < tablePtr->nKeys; i++) { Blt_DeleteHashTable(tablePtr->keyTables + i); } if (tablePtr->keyTables != NULL) { Blt_Free(tablePtr->keyTables); } if (tablePtr->masterKey != NULL) { Blt_Free(tablePtr->masterKey); Blt_DeleteHashTable(&tablePtr->masterKeyTable); } tablePtr->keyTables = NULL; tablePtr->nKeys = 0; tablePtr->masterKey = NULL; } void Blt_Table_UnsetKeys(Table *tablePtr) { FreeKeyTables(tablePtr); FreePrimaryKeys(tablePtr); tablePtr->flags &= ~(TABLE_KEYS_DIRTY | TABLE_KEYS_UNIQUE); } Blt_Chain Blt_Table_GetKeys(Table *tablePtr) { return tablePtr->primaryKeys; } int Blt_Table_SetKeys(Table *tablePtr, Blt_Chain primaryKeys, int unique) { Blt_ChainLink link; if (tablePtr->primaryKeys != NULL) { FreePrimaryKeys(tablePtr); } tablePtr->primaryKeys = primaryKeys; /* Mark the designated columns as primary keys. This flag is used to * check if a primary column is deleted, it's rows are added or changed, * or it's values set or unset. The generated keytables are invalid and * need to be regenerated. */ for (link = Blt_Chain_FirstLink(tablePtr->primaryKeys); link != NULL; link = Blt_Chain_NextLink(link)) { Column *columnPtr; columnPtr = Blt_Chain_GetValue(link); columnPtr->flags |= TABLE_COLUMN_PRIMARY_KEY; } tablePtr->flags |= TABLE_KEYS_DIRTY; if (unique) { tablePtr->flags |= TABLE_KEYS_UNIQUE; } return TCL_OK; } static int MakeKeyTables(Tcl_Interp *interp, Table *tablePtr) { size_t i; size_t masterKeySize; size_t nKeys; FreeKeyTables(tablePtr); tablePtr->flags &= ~TABLE_KEYS_DIRTY; nKeys = Blt_Chain_GetLength(tablePtr->primaryKeys); /* Create a hashtable for each key. */ tablePtr->keyTables = Blt_Malloc(sizeof(Blt_HashTable) * nKeys); if (tablePtr->keyTables == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't allocated keytables for ", Blt_Itoa(nKeys), " keys.", (char *)NULL); } return TCL_ERROR; } tablePtr->nKeys = nKeys; for (i = 0; i < nKeys; i++) { Blt_InitHashTable(tablePtr->keyTables + i, BLT_STRING_KEYS); } masterKeySize = sizeof(Blt_TableRow) * nKeys; tablePtr->masterKey = Blt_AssertMalloc(masterKeySize); Blt_InitHashTable(&tablePtr->masterKeyTable, masterKeySize / sizeof(int)); /* For each row, create hash entries the the individual key columns, but * also for the combined keys for the row. The hash of the combined keys * must be unique. */ for (i = 1; i <= Blt_Table_NumRows(tablePtr); i++) { Blt_ChainLink link; Row *rowPtr; size_t j; rowPtr = Blt_Table_Row(tablePtr, i); for (j = 0, link = Blt_Chain_FirstLink(tablePtr->primaryKeys); link != NULL; link = Blt_Chain_NextLink(link), j++) { Column *colPtr; Blt_HashEntry *hPtr; int isNew; Value *valuePtr; colPtr = Blt_Chain_GetValue(link); valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { break; /* Skip this row since one of the key values * is empty. */ } hPtr = Blt_CreateHashEntry(tablePtr->keyTables + j, valuePtr->string, &isNew); if (isNew) { Blt_SetHashValue(hPtr, rowPtr); } tablePtr->masterKey[j] = Blt_GetHashValue(hPtr); } if (j == nKeys) { Blt_HashEntry *hPtr; int isNew; /* If we created all the hashkeys necessary for this row, then * generate an entry for the row in the master key table. */ hPtr = Blt_CreateHashEntry(&tablePtr->masterKeyTable, (char *)tablePtr->masterKey, &isNew); if (isNew) { Blt_SetHashValue(hPtr, rowPtr); } else if (tablePtr->flags & TABLE_KEYS_UNIQUE) { Blt_TableRow dupRow; dupRow = Blt_GetHashValue(hPtr); if (interp != NULL) { dupRow = Blt_GetHashValue(hPtr); Tcl_AppendResult(interp, "primary keys are not unique:", "rows \"", Blt_Table_RowLabel(dupRow), "\" and \"", Blt_Table_RowLabel(rowPtr), "\" have the same keys.", (char *)NULL); } Blt_Table_UnsetKeys(tablePtr); return TCL_ERROR; /* Bail out. Keys aren't unique. */ } } } tablePtr->flags &= ~TABLE_KEYS_UNIQUE; return TCL_OK; } int Blt_Table_KeyLookup(Tcl_Interp *interp, Table *tablePtr, int objc, Tcl_Obj *const *objv, Row **rowPtrPtr) { long i; Blt_HashEntry *hPtr; *rowPtrPtr = NULL; if (objc != Blt_Chain_GetLength(tablePtr->primaryKeys)) { if (interp != NULL) { Blt_ChainLink link; Tcl_AppendResult(interp, "wrong # of values: should be ", Blt_Itoa(tablePtr->nKeys), " value(s) of ", (char *)NULL); for (link = Blt_Chain_FirstLink(tablePtr->primaryKeys); link != NULL; link = Blt_Chain_NextLink(link)) { Blt_TableColumn col; col = Blt_Chain_GetValue(link); Tcl_AppendResult(interp, Blt_Table_ColumnLabel(col), " ", (char *)NULL); } } return TCL_ERROR; /* Bad number of keys supplied. */ } if (tablePtr->primaryKeys == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "no primary keys designated", (char *)NULL); } return TCL_ERROR; } if ((tablePtr->flags & TABLE_KEYS_DIRTY) && (MakeKeyTables(interp, tablePtr) != TCL_OK)) { return TCL_ERROR; } if (tablePtr->nKeys == 0) { if (interp != NULL) { Tcl_AppendResult(interp, "failed to generate key tables", (char *)NULL); } return TCL_ERROR; } for (i = 0; i < tablePtr->nKeys; i++) { const char *string; string = Tcl_GetString(objv[i]); hPtr = Blt_FindHashEntry(tablePtr->keyTables + i, string); if (hPtr == NULL) { return TCL_OK; /* Can't find one of the keys, so * the whole search fails. */ } tablePtr->masterKey[i] = Blt_GetHashValue(hPtr); } hPtr = Blt_FindHashEntry(&tablePtr->masterKeyTable, (char *)tablePtr->masterKey); if (hPtr == NULL) { fprintf(stderr, "can't find master key\n"); return TCL_OK; } *rowPtrPtr = Blt_GetHashValue(hPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_SetLong -- * * Sets the value of the selected row, column location in the table. The * row, column location must be within the actual table limits. * * Results: * Returns the objPtr representing the old value. If no previous value * was present, the NULL is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ int Blt_Table_SetLong(Table *tablePtr, Row *rowPtr, Column *colPtr, long value) { Value *valuePtr; char string[200]; if (colPtr->type != TABLE_COLUMN_TYPE_LONG) { Tcl_AppendResult(tablePtr->interp, "wrong column type \"", Blt_Table_NameOfType(colPtr->type), "\": should be \"int\"", (char *)NULL); return TCL_ERROR; } valuePtr = GetValue(tablePtr, rowPtr, colPtr); FreeValue(valuePtr); valuePtr->datum.l = value; sprintf(string, "%ld", value); valuePtr->string = Blt_AssertStrdup(string); /* Indicate the keytables need to be regenerated. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { tablePtr->flags |= TABLE_KEYS_DIRTY; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_SetString -- * * Sets the value of the selected row, column location in the table. The * row, column location must be within the actual table limits. * * Results: * Returns the objPtr representing the old value. If no previous value * was present, the NULL is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ int Blt_Table_SetString(Table *tablePtr, Row *rowPtr, Column *colPtr, const char *string, int length) { Value *valuePtr; if (colPtr->type != TABLE_COLUMN_TYPE_STRING) { return TCL_ERROR; } valuePtr = GetValue(tablePtr, rowPtr, colPtr); FreeValue(valuePtr); if (SetValueFromString(tablePtr->interp, colPtr->type, string, length, valuePtr) != TCL_OK) { return TCL_ERROR; } /* Indicate the keytables need to be regenerated. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { tablePtr->flags |= TABLE_KEYS_DIRTY; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_AppendString -- * * Sets the value of the selected row, column location in the table. The * row, column location must be within the actual table limits. * * Results: * Returns the objPtr representing the old value. If no previous value * was present, the NULL is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ int Blt_Table_AppendString(Tcl_Interp *interp, Table *tablePtr, Row *rowPtr, Column *colPtr, const char *s, int length) { Value *valuePtr; char *string; long l; double d; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { string = Blt_AssertStrdup(s); } else { int oldLen; oldLen = strlen(valuePtr->string); string = Blt_AssertMalloc(oldLen + length + 1); strcpy(string, valuePtr->string); strncpy(string + oldLen, s, length); string[oldLen + length] = '\0'; } switch (colPtr->type) { case TABLE_COLUMN_TYPE_DOUBLE: /* double */ if (Blt_GetDoubleFromString(interp, string, &d) != TCL_OK) { Blt_Free(string); return TCL_ERROR; } valuePtr->datum.d = d; break; case TABLE_COLUMN_TYPE_LONG: /* long */ case TABLE_COLUMN_TYPE_INT: /* int */ if (Tcl_GetLong(interp, string, &l) != TCL_OK) { Blt_Free(string); return TCL_ERROR; } valuePtr->datum.l = l; break; default: break; } FreeValue(valuePtr); valuePtr->string = string; /* Indicate the keytables need to be regenerated. */ if (colPtr->flags & TABLE_COLUMN_PRIMARY_KEY) { tablePtr->flags |= TABLE_KEYS_DIRTY; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_Table_GetString -- * * Sets the value of the selected row, column location in the table. The * row, column location must be within the actual table limits. * * Results: * Returns the objPtr representing the old value. If no previous value * was present, the NULL is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ const char * Blt_Table_GetString(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *valuePtr; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { return NULL; } return valuePtr->string; } /* *--------------------------------------------------------------------------- * * Blt_Table_GetDouble -- * * Gets the double value of the selected row, column location in the * table. The row, column location must be within the actual table * limits. * * Results: * Returns the objPtr representing the old value. If no previous value * was present, the NULL is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ double Blt_Table_GetDouble(Table *tablePtr, Row *rowPtr, Column *colPtr) { Value *valuePtr; double d; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { return Blt_NaN(); } if (colPtr->type == TABLE_COLUMN_TYPE_DOUBLE) { return valuePtr->datum.d; } if (Blt_GetDoubleFromString(tablePtr->interp, valuePtr->string, &d) != TCL_OK) { return TCL_ERROR; } return d; } /* *--------------------------------------------------------------------------- * * Blt_Table_GetLong -- * * Gets the double value of the selected row, column location in the * table. The row, column location must be within the actual table * limits. * * Results: * Returns a long value. If the value is empty, the default value * is returned. * * Side Effects: * New tuples may be allocated created. * *--------------------------------------------------------------------------- */ long Blt_Table_GetLong(Table *tablePtr, Row *rowPtr, Column *colPtr, long defVal) { Value *valuePtr; long l; valuePtr = GetValue(tablePtr, rowPtr, colPtr); if (IsEmpty(valuePtr)) { return defVal; } if (colPtr->type == TABLE_COLUMN_TYPE_LONG) { return valuePtr->datum.l; } if (Tcl_GetLong(tablePtr->interp, valuePtr->string, &l) != TCL_OK) { return TCL_ERROR; } return l; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPaneset.c������������������������������������������������������������������0000644�0001750�0001750�00000623255�11462120062�015307� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPaneset.c -- * * Copyright 2009 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * Modes * * 1. enlarge/reduce: change only the panes touching the anchor. * 2. slinky: change all panes on both sides of the anchor. * 3. hybrid: one side slinky, the other enlarge/reduce * 4. locked minus 1 changed only the pane to the left of the anchor. * 5. filmstrip move the panes left or right. */ #include "bltInt.h" #include "bltChain.h" #include "bltList.h" #include "bltHash.h" #include "bltOp.h" #include "bltSwitch.h" #include "bltBgStyle.h" #define GETATTR(t,attr) \ (((t)->attr != NULL) ? (t)->attr : (t)->setPtr->attr) #define VPORTWIDTH(s) \ (ISVERT(s)) ? Tk_Height((s)->tkwin) : Tk_Width((s)->tkwin); #define TRACE 0 #define TRACE1 0 #define SCREEN(x) ((x) - setPtr->scrollOffset) #define ISVERT(s) ((s)->flags & VERTICAL) #define ISHORIZ(s) (((s)->flags & VERTICAL) == 0) /* * The following are the adjustment modes for the paneset widget. */ typedef enum AdjustModes { MODE_SLINKY, /* Adjust all panes when resizing */ MODE_GIVETAKE, /* Adjust panes to immediate left/right * or top/bottom of active handle. */ MODE_SPREADSHEET, /* Adjust only the left pane and the * last pane. */ } AdjustMode; typedef struct _Paneset Paneset; typedef struct _Pane Pane; typedef int (LimitsProc)(int value, Blt_Limits *limitsPtr); typedef int (SizeProc)(Pane *panePtr); typedef int (PanesetCmdProc)(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); typedef int (HandleCmdProc)(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); /* * Default values for widget attributes. */ #define DEF_ACTIVEHANDLECOLOR STD_ACTIVE_BACKGROUND #define DEF_ACTIVEHANDLERELIEF "flat" #define DEF_ANIMATE "0" #define DEF_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_BORDERWIDTH "0" #define DEF_HANDLEBORDERWIDTH "1" #define DEF_HANDLECOLOR STD_NORMAL_BACKGROUND #define DEF_HANDLEPAD "0" #define DEF_HANDLERELIEF "flat" #define DEF_HANDLETHICKNESS "2" #define DEF_HCURSOR "sb_h_double_arrow" #define DEF_HEIGHT "0" #define DEF_HIGHLIGHT_THICKNESS "1" #define DEF_MODE "givetake" #define DEF_ORIENT "horizontal" #define DEF_DRAWER_SHRINK "0" #define DEF_DRAWER_FILL "1" #define DEF_PAD "0" #define DEF_PANE_ANCHOR "nw" #define DEF_PANE_ANCHOR "nw" #define DEF_PANE_BORDERWIDTH "0" #define DEF_PANE_CURSOR (char *)NULL #define DEF_PANE_FILL "none" #define DEF_PANE_HIDE "0" #define DEF_PANE_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_PANE_HIGHLIGHT_COLOR RGB_BLACK #define DEF_PANE_PAD "0" #define DEF_PANE_PADX "0" #define DEF_PANE_PADY "0" #define DEF_PANE_RESIZE "shrink" #define DEF_PANE_SHOWHANDLE "1" #define DEF_PANE_WEIGHT "1.0" #define DEF_PANE_OPENVALUE "1" #define DEF_PANE_CLOSEVALUE "0" #define DEF_PANE_VARIABLE (char *)NULL #define DEF_SCROLLCOMMAND "0" #define DEF_SCROLLDELAY "30" #define DEF_SCROLLINCREMENT "10" #define DEF_SIDE "right" #define DEF_TAKEFOCUS "1" #define DEF_VCURSOR "sb_v_double_arrow" #define DEF_WEIGHT "0" #define DEF_WIDTH "0" #define PANE_DEF_ANCHOR TK_ANCHOR_NW #define PANE_DEF_FILL FILL_NONE #define PANE_DEF_IPAD 0 #define PANE_DEF_PAD 0 #define PANE_DEF_PAD 0 #define PANE_DEF_RESIZE RESIZE_BOTH #define PANE_DEF_WEIGHT 1.0 #define FCLAMP(x) ((((x) < 0.0) ? 0.0 : ((x) > 1.0) ? 1.0 : (x))) #define VAR_FLAGS (TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS) /* * Paneset structure * * The paneset is a set of windows (panes) that may be resized in one * dimension (horizontally or vertically). How the panes are resized is * dependent upon the paneset's bearing and the adjustment mode in place. * * The bearing is the position of the handle last moved. By default it's * the last handle. The position is the just outside of the handle. So * if the window starting at 100 has a width of 200 and the handle size * is 10, the bearing is 310. * * The bearing divides the panes into two. Each side is resized * according to the adjustment mode. * * givetake The panes immediately to the left and right of * the bearing are grown/shrunk. * slinky All the panes on either side of the bearing are * grown/shrunk. * spreadsheet The pane to the left of the bearing and the last * pane on the right side are grown/shrunk. Intervening * panes are unaffected. */ struct _Paneset { int flags; /* See the flags definitions below. */ int type; /* Type of widget: PANESET, DRAWER, or * FILMSTRIP. */ Display *display; /* Display of the widget. */ Tk_Window tkwin; /* The container window into which * other widgets are arranged. For the * paneset and filmstrip, this window * is created. For the drawer we use * an existing window. */ Tcl_Interp *interp; /* Interpreter associated with all * widgets and handles. */ Tcl_Command cmdToken; /* Command token associated with this * widget. For panesets and filmstrips * this is the path name of the window * created. For drawers, this is a * generated name. */ char *name; /* The generated name of the drawer * or the pathname of the window * created (panesets and * filmstrips). */ AdjustMode mode; /* Panesets only: Mode to use to resize panes when the user adjusts a handle. */ int highlightThickness; /* Width in pixels of highlight to * draw around the handle when it has * the focus. <= 0 means don't draw a * highlight. */ int normalWidth; /* Normal dimensions of the paneset */ int normalHeight; int reqWidth, reqHeight; /* Constraints on the paneset's normal * width and height. Overrides the * requested width of the window. */ Tk_Cursor defVertCursor; /* Default vertical X cursor */ Tk_Cursor defHorzCursor; /* Default horizontal X cursor */ short int width, height; /* Requested size of the widget. */ Blt_Background bg; /* 3D border surrounding the window * (viewport). */ /* * Scrolling information (filmstrip only): */ int worldWidth; int scrollOffset; /* Offset of viewport in world * coordinates. */ Tcl_Obj *scrollCmdObjPtr; /* Command strings to control * scrollbar.*/ /* * Automated scrolling information (filmstrip or drawer). */ int scrollUnits; /* Smallest unit of scrolling for * tabs. */ int scrollTarget; /* Target offset to scroll to. */ int scrollIncr; /* Current increment. */ int interval; /* Current increment. */ Tcl_TimerToken timerToken; /* Token for timer to automatically * scroll the pane or drawer. */ /* * Focus highlight ring */ XColor *highlightColor; /* Color for drawing traversal * highlight. */ int relief; int activeRelief; Blt_Pad handlePad; int handleBW; int handleThickness; /* */ int handleSize; Blt_Background handleBg; Blt_Background activeHandleBg; int handleAnchor; /* Last known location of handle * during a move. */ Blt_Chain chain; /* List of panes/drawers. In paneset * and filmstrip widgets, describes * the order of the panes in the * widget. In the drawer widget, * represents the stacking order of * the drawers. */ Blt_HashTable paneTable; /* Table of panes. Serves as a * directory to look up panes from * windows. */ Blt_HashTable tagTable; /* Table of tags. */ Pane *activePtr; /* Indicates the pane with the active * handle. */ Pane *anchorPtr; /* Pane that is currently anchored */ int bearing; /* Location of the split (paneset). * the drawer (drawer). */ Tcl_Obj *cmdObjPtr; /* Command to invoke when the "invoke" * operation is performed. */ size_t nVisible; /* # of visible panes. */ GC gc; size_t nextId; /* Counter to generate unique * pane/drawer names. */ size_t nextHandleId; /* Counter to generate unique * pane/drawer names. */ }; /* * Paneset flags definitions */ #define REDRAW_PENDING (1<<0) /* A redraw request is pending. */ #define LAYOUT_PENDING (1<<1) /* Get the requested sizes of the * widgets before expanding/shrinking * the size of the container. It's * necessary to recompute the layout * every time a pane is added, * reconfigured, or deleted, but not * when the container is resized. */ #define SCROLL_PENDING (1<<2) /* Get the requested sizes of the * widgets before expanding/shrinking * the size of the container. It's * necessary to recompute the layout * every time a pane is added, * reconfigured, or deleted, but not * when the container is resized. */ #define ANIMATE (1<<3) /* Animate pane moves and drawer * open/closes */ #define FOCUS (1<<6) #define VERTICAL (1<<7) #define PANESET (BLT_CONFIG_USER_BIT << 1) #define DRAWER (BLT_CONFIG_USER_BIT << 2) #define FILMSTRIP (BLT_CONFIG_USER_BIT << 3) #define ALL (PANESET|DRAWER|FILMSTRIP) /* * Pane -- * * A pane holds a window and a possibly a handle. It describes how the * window should appear in the pane. The handle is a rectangle on the * far edge of the pane (horizontal right, vertical bottom). Normally * the last pane does not have a handle. Handles may be hidden. * * Initially, the size of a pane consists of * 1. the requested size embedded window, * 2. any requested internal padding, and * 3. the size of the handle (if one is displayed). * * Note: There is no 3D border around the pane. This can be added * by embedding a frame. This simplifies the widget so that * there is only one window for the widget. Windows outside of * the boundary of the pane are occluded. */ struct _Pane { Tk_Window tkwin; /* Widget to be managed. */ Tk_Window handle; /* Handle subwindow. */ Tcl_Command cmdToken; Tk_Cursor cursor; /* X Cursor */ const char *name; /* Name of pane */ unsigned int side; /* The side of the widget where this * drawer is attached. */ unsigned int flags; Paneset *setPtr; /* Paneset widget managing this pane. */ int borderWidth; /* The external border width of the * widget. This is needed to check if * Tk_Changes(tkwin)->border_width * changes. */ XColor *highlightBgColor; /* Color for drawing traversal * highlight area when highlight is * off. */ XColor *highlightColor; /* Color for drawing traversal * highlight. */ const char *takeFocus; /* Says whether to select this widget * during tab traveral operations. * This value isn't used in C code, * but for the widget's TCL * bindings. */ Blt_Limits reqWidth, reqHeight; /* Bounds for width and height * requests made by the widget. */ Tk_Anchor anchor; /* Anchor type: indicates how the * widget is positioned if extra space * is available in the pane. */ Blt_Pad xPad; /* Extra padding placed left and right * of the widget. */ Blt_Pad yPad; /* Extra padding placed above and below * the widget */ int iPadX, iPadY; /* Extra padding added to the interior * of the widget (i.e. adds to the * requested size of the widget) */ int fill; /* Indicates how the widget should fill * the pane it occupies. */ int resize; /* Indicates if the pane should * expand/shrink. */ int x, y; /* Origin of pane wrt container. */ short int width, height; /* Size of pane, including handle. */ Blt_ChainLink link; /* Pointer of this pane into the list * of panes. */ Blt_HashEntry *hashPtr; /* Pointer of this pane into hashtable * of panes. */ int index; /* Index of the pane. */ int size; /* Current size of the pane. This size * is bounded by min and max. */ /* * nom and size perform similar duties. I need to keep track of the * amount of space allocated to the pane (using size). But at the same * time, I need to indicate that space can be parcelled out to this pane. * If a nominal size was set for this pane, I don't want to add space. */ int nom; /* The nominal size (neither expanded * nor shrunk) of the pane based upon * the requested size of the widget * embedded in this pane. */ int min, max; /* Size constraints on the pane */ float weight; /* Weight of pane. */ Blt_Limits reqSize; /* Requested bounds for the size of * the pane. The pane will not expand * or shrink beyond these limits, * regardless of how it was specified * (max widget size). This includes * any extra padding which may be * specified. */ Blt_Background handleBg; Blt_Background activeHandleBg; Blt_Background bg; /* 3D background border surrounding * the widget */ Tcl_Obj *cmdObjPtr; Tcl_TimerToken timerToken; int scrollTarget; /* Target offset to scroll to. */ int scrollIncr; /* Current increment. */ Tcl_Obj *variableObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * value string of the selected * item. */ /* Checkbutton on and off values. */ Tcl_Obj *openValueObjPtr; /* Drawer open-value. */ Tcl_Obj *closeValueObjPtr; /* Drawer close-value. */ }; /* Pane/handle flags. */ #define HIDE (1<<8) /* Do not display the pane. */ #define CLOSED (1<<8) /* Do not display the pane. */ #define DISABLED (1<<9) /* Handle is disabled. */ #define ONSCREEN (1<<10) /* Pane is on-screen. */ #define HANDLE_ACTIVE (1<<11) /* Handle is currently active. */ #define HANDLE (1<<12) /* The pane has a handle. */ #define SHOW_HANDLE (1<<13) /* Display the pane. */ #define SHRINK (1<<14) /* Shrink the window to fit the * drawer, instead of moving it. */ #define VIRGIN (1<<24) /* Orientation. */ #define SIDE_VERTICAL (SIDE_TOP|SIDE_BOTTOM) #define SIDE_HORIZONTAL (SIDE_LEFT|SIDE_RIGHT) /* Handle positions. */ #define HANDLE_LEFT SIDE_RIGHT #define HANDLE_RIGHT SIDE_LEFT #define HANDLE_TOP SIDE_BOTTOM #define HANDLE_BOTTOM SIDE_TOP #define HANDLE_FARSIDE (HANDLE_RIGHT|HANDLE_BOTTOM) #define HANDLE_NEARSIDE (HANDLE_LEFT|HANDLE_TOP) static Tk_GeomRequestProc PaneGeometryProc; static Tk_GeomLostSlaveProc PaneCustodyProc; static Tk_GeomMgr panesetMgrInfo = { (char *)"paneset", /* Name of geometry manager used by * winfo */ PaneGeometryProc, /* Procedure to for new geometry * requests */ PaneCustodyProc, /* Procedure when widget is taken * away */ }; static Blt_OptionParseProc ObjToChild; static Blt_OptionPrintProc ChildToObj; static Blt_CustomOption childOption = { ObjToChild, ChildToObj, NULL, (ClientData)0, }; extern Blt_CustomOption bltLimitsOption; static Blt_OptionParseProc ObjToOrientProc; static Blt_OptionPrintProc OrientToObjProc; static Blt_CustomOption orientOption = { ObjToOrientProc, OrientToObjProc, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToMode; static Blt_OptionPrintProc ModeToObj; static Blt_CustomOption adjustOption = { ObjToMode, ModeToObj, NULL, (ClientData)0, }; static Blt_OptionFreeProc FreeTraceVarProc; static Blt_OptionParseProc ObjToTraceVarProc; static Blt_OptionPrintProc TraceVarToObjProc; static Blt_CustomOption traceVarOption = { ObjToTraceVarProc, TraceVarToObjProc, FreeTraceVarProc, (ClientData)0 }; static Blt_ConfigSpec paneSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activehandlecolor", "activeHandleColor", "HandleColor", DEF_ACTIVEHANDLECOLOR, Blt_Offset(Pane, activeHandleBg), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | FILMSTRIP | DRAWER}, {BLT_CONFIG_BACKGROUND, "-activesashcolor", "activeSashColor", "SashColor", DEF_ACTIVEHANDLECOLOR, Blt_Offset(Pane, activeHandleBg), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | PANESET}, {BLT_CONFIG_ANCHOR, "-anchor", (char *)NULL, (char *)NULL, DEF_PANE_ANCHOR, Blt_Offset(Pane, anchor), BLT_CONFIG_DONT_SET_DEFAULT | PANESET}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", (char *)NULL, Blt_Offset(Pane, bg), BLT_CONFIG_NULL_OK | BLT_CONFIG_DONT_SET_DEFAULT | ALL}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, ALL}, {BLT_CONFIG_OBJ, "-closevalue", "closeValue", "CloseValue", DEF_PANE_CLOSEVALUE, Blt_Offset(Pane, closeValueObjPtr), BLT_CONFIG_NULL_OK | DRAWER }, {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor", DEF_PANE_CURSOR, Blt_Offset(Pane, cursor), BLT_CONFIG_NULL_OK | ALL}, {BLT_CONFIG_FILL, "-fill", "fill", "Fill", DEF_PANE_FILL, Blt_Offset(Pane, fill), BLT_CONFIG_DONT_SET_DEFAULT | PANESET | FILMSTRIP }, {BLT_CONFIG_BOOLEAN, "-fill", "fill", "Fill", DEF_DRAWER_FILL, Blt_Offset(Pane, fill), BLT_CONFIG_DONT_SET_DEFAULT | DRAWER }, {BLT_CONFIG_BACKGROUND, "-handlecolor", "handleColor", "HandleColor", DEF_HANDLECOLOR, Blt_Offset(Pane, handleBg), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | FILMSTRIP|DRAWER}, {BLT_CONFIG_SYNONYM, "-height", "reqHeight", (char *)NULL, (char *)NULL, Blt_Offset(Pane, reqHeight), 0}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_PANE_HIDE, Blt_Offset(Pane, flags), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | PANESET, (Blt_CustomOption *)HIDE }, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_PANE_HIGHLIGHT_BACKGROUND, Blt_Offset(Pane, highlightBgColor), ALL}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_PANE_HIGHLIGHT_COLOR, Blt_Offset(Pane, highlightColor), ALL}, {BLT_CONFIG_PIXELS_NNEG, "-ipadx", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Pane, iPadX), ALL}, {BLT_CONFIG_PIXELS_NNEG, "-ipady", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Pane, iPadY), ALL}, {BLT_CONFIG_OBJ, "-opennvalue", "openValue", "OpenValue", DEF_PANE_OPENVALUE, Blt_Offset(Pane, openValueObjPtr), BLT_CONFIG_NULL_OK | DRAWER }, {BLT_CONFIG_CUSTOM, "-reqheight", "reqHeight", (char *)NULL, (char *)NULL, Blt_Offset(Pane, reqHeight), ALL, &bltLimitsOption}, {BLT_CONFIG_CUSTOM, "-reqwidth", "reqWidth", (char *)NULL, (char *)NULL, Blt_Offset(Pane, reqWidth), ALL, &bltLimitsOption}, {BLT_CONFIG_RESIZE, "-resize", "resize", "Resize", DEF_PANE_RESIZE, Blt_Offset(Pane, resize), BLT_CONFIG_DONT_SET_DEFAULT | ALL}, {BLT_CONFIG_BACKGROUND, "-sashcolor", "sashColor", "SashColor", DEF_HANDLECOLOR, Blt_Offset(Pane, handleBg), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK | PANESET}, {BLT_CONFIG_BITMASK, "-showhandle", "showHandle", "showHandle", DEF_PANE_SHOWHANDLE, Blt_Offset(Pane, flags), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER, (Blt_CustomOption *)SHOW_HANDLE }, {BLT_CONFIG_BITMASK, "-showsash", "showSash", "showSash", DEF_PANE_SHOWHANDLE, Blt_Offset(Pane, flags), BLT_CONFIG_DONT_SET_DEFAULT | PANESET, (Blt_CustomOption *)SHOW_HANDLE}, {BLT_CONFIG_BITMASK, "-shrink", "shrink", "Shrink", DEF_DRAWER_SHRINK, Blt_Offset(Pane, flags), BLT_CONFIG_DONT_SET_DEFAULT | DRAWER, (Blt_CustomOption *)SHRINK }, {BLT_CONFIG_SIDE, "-side", (char *)NULL, (char *)NULL, DEF_SIDE, Blt_Offset(Pane, side), BLT_CONFIG_DONT_SET_DEFAULT | DRAWER}, {BLT_CONFIG_CUSTOM, "-size", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Pane, reqSize), ALL, &bltLimitsOption}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKEFOCUS, Blt_Offset(Pane, takeFocus), BLT_CONFIG_NULL_OK | ALL}, {BLT_CONFIG_CUSTOM, "-variable", (char *)NULL, (char *)NULL, DEF_PANE_VARIABLE, Blt_Offset(Pane, variableObjPtr), BLT_CONFIG_NULL_OK | DRAWER, &traceVarOption}, {BLT_CONFIG_FLOAT, "-weight", "weight", "Weight", DEF_PANE_WEIGHT, Blt_Offset(Pane, weight), BLT_CONFIG_DONT_SET_DEFAULT | PANESET}, {BLT_CONFIG_SYNONYM, "-width", "reqWidth", (char *)NULL, (char *)NULL, Blt_Offset(Pane, reqWidth), 0}, {BLT_CONFIG_CUSTOM, "-window", "window", "Window", (char *)NULL, Blt_Offset(Pane, tkwin), BLT_CONFIG_NULL_OK | ALL, &childOption }, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* * Hide the handle. * * .p configure -handlethickness 0 * .p pane configure -hide yes * Put all the drawers in the paneset widget, hidden by default. * Reveal/hide drawers to pop them out. * plotarea | sidebar | scroller */ static Blt_ConfigSpec panesetSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activehandlecolor", "activeHandleColor", "HandleColor", DEF_ACTIVEHANDLECOLOR, Blt_Offset(Paneset, activeHandleBg), DRAWER|FILMSTRIP}, {BLT_CONFIG_RELIEF, "-activehandlerelief", "activeHandleRelief", "HandleRelief", DEF_ACTIVEHANDLERELIEF, Blt_Offset(Paneset, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER }, {BLT_CONFIG_BACKGROUND, "-activesashcolor", "activeSashColor", "SashColor", DEF_ACTIVEHANDLECOLOR, Blt_Offset(Paneset, activeHandleBg), PANESET}, {BLT_CONFIG_RELIEF, "-activesashrelief", "activeSashRelief", "SashRelief", DEF_ACTIVEHANDLERELIEF, Blt_Offset(Paneset, activeRelief), BLT_CONFIG_DONT_SET_DEFAULT|PANESET}, {BLT_CONFIG_BITMASK, "-animate", "animate", "Animate", DEF_ANIMATE, Blt_Offset(Paneset, flags), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER, (Blt_CustomOption *)ANIMATE }, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BACKGROUND, Blt_Offset(Paneset, bg), ALL }, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, ALL}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, Blt_Offset(Paneset, reqHeight), BLT_CONFIG_DONT_SET_DEFAULT | ALL }, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_HIGHLIGHT_THICKNESS, Blt_Offset(Paneset, highlightThickness), BLT_CONFIG_DONT_SET_DEFAULT | ALL}, {BLT_CONFIG_CUSTOM, "-orient", "orient", "Orient", DEF_ORIENT, Blt_Offset(Paneset, flags), BLT_CONFIG_DONT_SET_DEFAULT | PANESET | FILMSTRIP, &orientOption}, {BLT_CONFIG_CUSTOM, "-mode", "mode", "Mode", DEF_MODE, Blt_Offset(Paneset, mode), BLT_CONFIG_DONT_SET_DEFAULT | PANESET, &adjustOption}, {BLT_CONFIG_CUSTOM, "-reqheight", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Paneset, reqHeight), ALL, &bltLimitsOption}, {BLT_CONFIG_CUSTOM, "-reqwidth", (char *)NULL, (char *)NULL, (char *)NULL, Blt_Offset(Paneset, reqWidth), ALL, &bltLimitsOption}, {BLT_CONFIG_PIXELS_NNEG, "-handleborderwidth", "handleBorderWidth", "HandleBorderWidth", DEF_HANDLEBORDERWIDTH, Blt_Offset(Paneset, handleBW), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER }, {BLT_CONFIG_BACKGROUND, "-handlecolor", "handleColor", "HandleColor", DEF_HANDLECOLOR, Blt_Offset(Paneset, handleBg), FILMSTRIP | DRAWER}, {BLT_CONFIG_PAD, "-handlepad", "handlePad", "HandlePad", DEF_HANDLEPAD, Blt_Offset(Paneset, handlePad), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER}, {BLT_CONFIG_RELIEF, "-handlerelief", "handleRelief", "HandleRelief", DEF_HANDLERELIEF, Blt_Offset(Paneset, relief), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER }, {BLT_CONFIG_PIXELS_NNEG, "-handlethickness", "handleThickness", "HandleThickness", DEF_HANDLETHICKNESS, Blt_Offset(Paneset, handleThickness), BLT_CONFIG_DONT_SET_DEFAULT| FILMSTRIP | DRAWER }, {BLT_CONFIG_PIXELS_NNEG, "-sashborderwidth", "sashBorderWidth", "SashBorderWidth", DEF_HANDLEBORDERWIDTH, Blt_Offset(Paneset, handleBW), BLT_CONFIG_DONT_SET_DEFAULT | PANESET}, {BLT_CONFIG_BACKGROUND, "-sashcolor", "sashColor", "SashColor", DEF_HANDLECOLOR, Blt_Offset(Paneset, handleBg), PANESET}, {BLT_CONFIG_PAD, "-sashpad", "sashPad", "SashPad", DEF_HANDLEPAD, Blt_Offset(Paneset, handlePad), BLT_CONFIG_DONT_SET_DEFAULT | PANESET}, {BLT_CONFIG_RELIEF, "-sashrelief", "sashRelief", "SashRelief", DEF_HANDLERELIEF, Blt_Offset(Paneset, relief), BLT_CONFIG_DONT_SET_DEFAULT | PANESET }, {BLT_CONFIG_PIXELS_NNEG, "-sashthickness", "sashThickness", "SashThickness", DEF_HANDLETHICKNESS, Blt_Offset(Paneset, handleThickness), BLT_CONFIG_DONT_SET_DEFAULT| PANESET }, {BLT_CONFIG_OBJ, "-scrollcommand", "scrollCommand", "ScrollCommand", (char *)NULL, Blt_Offset(Paneset, scrollCmdObjPtr), BLT_CONFIG_NULL_OK | FILMSTRIP }, {BLT_CONFIG_PIXELS_POS, "-scrollincrement", "scrollIncrement", "ScrollIncrement", DEF_SCROLLINCREMENT, Blt_Offset(Paneset,scrollUnits), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER }, {BLT_CONFIG_INT_NNEG, "-scrolldelay", "scrollDelay", "ScrollDelay", DEF_SCROLLDELAY, Blt_Offset(Paneset, interval), BLT_CONFIG_DONT_SET_DEFAULT | FILMSTRIP | DRAWER }, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, Blt_Offset(Paneset, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT | ALL}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* * PaneIterator -- * v * Panes may be tagged with strings. A pane may have many tags. The same * tag may be used for many panes. * */ typedef enum { ITER_SINGLE, ITER_ALL, ITER_TAG, ITER_PATTERN, } IteratorType; typedef struct _Iterator { Paneset *setPtr; /* Paneset that we're iterating over. */ IteratorType type; /* Type of iteration: * ITER_TAG By item tag. * ITER_ALL By every item. * ITER_SINGLE Single item: either * tag or index. * ITER_PATTERN Over a consecutive * range of indices. */ Pane *startPtr; /* Starting pane. Starting point of * search, saved if iterator is reused. * Used for ITER_ALL and ITER_SINGLE * searches. */ Pane *endPtr; /* Ending pend (inclusive). */ Pane *nextPtr; /* Next pane. */ /* For tag-based searches. */ char *tagName; /* If non-NULL, is the tag that we are * currently iterating over. */ Blt_HashTable *tablePtr; /* Pointer to tag hash table. */ Blt_HashSearch cursor; /* Search iterator for tag hash * table. */ Blt_ChainLink link; } PaneIterator; /* * Forward declarations */ static Tcl_FreeProc PanesetFreeProc; static Tcl_IdleProc DisplayPaneset; static Tcl_IdleProc DisplayHandle; static Tcl_ObjCmdProc PanesetCmd; static Tcl_ObjCmdProc DrawersetCmd; static Tcl_ObjCmdProc FilmstripCmd; static Tk_EventProc PanesetEventProc; static Tk_EventProc PaneEventProc; static Tk_EventProc HandleEventProc; static Tcl_FreeProc PaneFreeProc; static Tcl_ObjCmdProc PanesetInstCmdProc; static Tcl_ObjCmdProc DrawerInstCmdProc; static Tcl_ObjCmdProc HandleInstCmdProc; static Tcl_CmdDeleteProc PanesetInstCmdDeleteProc; static Tcl_CmdDeleteProc DrawerInstCmdDeleteProc; static Tcl_CmdDeleteProc HandleInstCmdDeleteProc; static Tcl_TimerProc MotionTimerProc; static Tcl_TimerProc DrawerTimerProc; static Tcl_VarTraceProc DrawerVarTraceProc; static int GetPaneIterator(Tcl_Interp *interp, Paneset *setPtr, Tcl_Obj *objPtr, PaneIterator *iterPtr); static int GetPaneFromObj(Tcl_Interp *interp, Paneset *setPtr, Tcl_Obj *objPtr, Pane **panePtrPtr); static int ScreenX(Pane *panePtr) { Paneset *setPtr; int x; x = panePtr->x; setPtr = panePtr->setPtr; if (setPtr->type == DRAWER) { if (panePtr->side & SIDE_RIGHT) { x = Tk_Width(setPtr->tkwin) - x; } else if (panePtr->side & SIDE_LEFT) { x -= panePtr->size; } } else if ((setPtr->type == FILMSTRIP) && (ISHORIZ(setPtr))) { x -= setPtr->scrollOffset; } return x; } static int ScreenY(Pane *panePtr) { Paneset *setPtr; int y; setPtr = panePtr->setPtr; y = panePtr->y; if (setPtr->type == DRAWER) { if (panePtr->side & SIDE_BOTTOM) { y = Tk_Height(setPtr->tkwin) - y; } else if (panePtr->side & SIDE_TOP) { y -= panePtr->size; } } else if ((setPtr->type == FILMSTRIP) && (ISVERT(setPtr))) { y -= setPtr->scrollOffset; } return y; } /* *--------------------------------------------------------------------------- * * RaiseDrawer -- * * Raises the drawer to the top of the stack of drawers. * * Results: * None. * * Side Effects: * Drawer is redrawn at the top of the stack. * *--------------------------------------------------------------------------- */ static void RaiseDrawer(Pane *panePtr) { if (panePtr->link != NULL) { Paneset *setPtr; setPtr = panePtr->setPtr; Blt_Chain_UnlinkLink(setPtr->chain, panePtr->link); Blt_Chain_AppendLink(setPtr->chain, panePtr->link); } } /* *--------------------------------------------------------------------------- * * LowerDrawer -- * * Lowers the drawer to the bottom of the stack of drawers. * * Results: * None. * * Side Effects: * Drawer is redraw at the bottom of the stack. * *--------------------------------------------------------------------------- */ static void LowerDrawer(Pane *panePtr) { if (panePtr->link != NULL) { Paneset *setPtr; setPtr = panePtr->setPtr; Blt_Chain_UnlinkLink(setPtr->chain, panePtr->link); Blt_Chain_PrependLink(setPtr->chain, panePtr->link); } } /* *--------------------------------------------------------------------------- * * BoundWidth -- * * Bounds a given width value to the limits described in the limit * structure. The initial starting value may be overridden by the * nominal value in the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int BoundWidth(int width, Blt_Limits *limitsPtr) { /* * Check widgets for requested width values; */ if (limitsPtr->flags & LIMITS_NOM_SET) { width = limitsPtr->nom; /* Override initial value */ } if (width < limitsPtr->min) { width = limitsPtr->min; /* Bounded by minimum value */ } if (width > limitsPtr->max) { width = limitsPtr->max; /* Bounded by maximum value */ } return width; } /* *--------------------------------------------------------------------------- * * BoundHeight -- * * Bounds a given value to the limits described in the limit structure. * The initial starting value may be overridden by the nominal value in * the limits. * * Results: * Returns the constrained value. * *--------------------------------------------------------------------------- */ static int BoundHeight(int height, Blt_Limits *limitsPtr) { /* * Check widgets for requested height values; */ if (limitsPtr->flags & LIMITS_NOM_SET) { height = limitsPtr->nom; /* Override initial value */ } if (height < limitsPtr->min) { height = limitsPtr->min; /* Bounded by minimum value */ } if (height > limitsPtr->max) { height = limitsPtr->max; /* Bounded by maximum value */ } return height; } /* *--------------------------------------------------------------------------- * * GetReqWidth -- * * Returns the width requested by the window embedded in the given pane. * The requested space also includes any internal padding which has been * designated for this widget. * * The requested width of the widget is always bounded by the limits set * in panePtr->reqWidth. * * Results: * Returns the requested width of the widget. * *--------------------------------------------------------------------------- */ static int GetReqWidth(Pane *panePtr) { int w; w = (2 * panePtr->iPadX); /* Start with any addition padding * requested for the pane. */ if (panePtr->tkwin != NULL) { /* Add in the requested width. */ w += Tk_ReqWidth(panePtr->tkwin); } return BoundWidth(w, &panePtr->reqWidth); } /* *--------------------------------------------------------------------------- * * GetReqHeight -- * * Returns the height requested by the widget starting in the given pane. * The requested space also includes any internal padding which has been * designated for this widget. * * The requested height of the widget is always bounded by the limits set * in panePtr->reqHeight. * * Results: * Returns the requested height of the widget. * *--------------------------------------------------------------------------- */ static int GetReqHeight(Pane *panePtr) { int h; h = 2 * panePtr->iPadY; if (panePtr->tkwin != NULL) { h += Tk_ReqHeight(panePtr->tkwin); } h = BoundHeight(h, &panePtr->reqHeight); return h; } static int GetReqDrawerWidth(Pane *panePtr) { int w; Paneset *setPtr; setPtr = panePtr->setPtr; w = GetReqWidth(panePtr); if ((panePtr->side & SIDE_HORIZONTAL) && (panePtr->flags & HANDLE)) { w += setPtr->handleSize; } if ((Tk_Width(setPtr->tkwin) > 1) && (Tk_Width(setPtr->tkwin) < w)) { w = Tk_Width(setPtr->tkwin); } return w; } static int GetReqDrawerHeight(Pane *panePtr) { int h; Paneset *setPtr; setPtr = panePtr->setPtr; h = GetReqHeight(panePtr); if ((panePtr->side & SIDE_VERTICAL) && (panePtr->flags & HANDLE)) { h += panePtr->setPtr->handleSize; } if ((Tk_Height(setPtr->tkwin) > 1) && (Tk_Height(setPtr->tkwin) < h)) { h = Tk_Height(setPtr->tkwin); } return h; } static void EventuallyRedraw(Paneset *setPtr) { if ((setPtr->flags & REDRAW_PENDING) == 0) { setPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayPaneset, setPtr); } } static int SetDrawerVariable(Pane *panePtr) { Paneset *setPtr; Tcl_Obj *objPtr; int state; int result; result = TCL_OK; state = (panePtr->flags & CLOSED) ? FALSE : TRUE; objPtr = (state) ? panePtr->openValueObjPtr : panePtr->closeValueObjPtr; if (objPtr == NULL) { objPtr = Tcl_NewBooleanObj(state); } setPtr = panePtr->setPtr; Tcl_IncrRefCount(objPtr); if (Tcl_ObjSetVar2(setPtr->interp, panePtr->variableObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; } Tcl_DecrRefCount(objPtr); return result; } static void ClearTags(Pane *panePtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; Paneset *setPtr; setPtr = panePtr->setPtr; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; Blt_HashEntry *h2Ptr; tablePtr = Blt_GetHashValue(hPtr); h2Ptr = Blt_FindHashEntry(tablePtr, (char *)panePtr); if (h2Ptr != NULL) { Blt_DeleteHashEntry(tablePtr, h2Ptr); } } } /* *--------------------------------------------------------------------------- * * DestroyPane -- * * Removes the Pane structure from the hash table and frees the memory * allocated by it. * * Results: * None. * * Side effects: * Everything associated with the pane is freed up. * *--------------------------------------------------------------------------- */ static void DestroyPane(Pane *panePtr) { Paneset *setPtr; ClearTags(panePtr); setPtr = panePtr->setPtr; Blt_FreeOptions(paneSpecs, (char *)panePtr, setPtr->display, 0); if (panePtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(panePtr->timerToken); panePtr->timerToken = 0; } if (panePtr->hashPtr != NULL) { Blt_DeleteHashEntry(&setPtr->paneTable, panePtr->hashPtr); panePtr->hashPtr = NULL; } if (panePtr->link != NULL) { Blt_Chain_DeleteLink(setPtr->chain, panePtr->link); panePtr->link = NULL; } if (panePtr->cmdToken != NULL) { Tcl_DeleteCommandFromToken(setPtr->interp, panePtr->cmdToken); } if (panePtr->tkwin != NULL) { Tk_Window tkwin; tkwin = panePtr->tkwin; Tk_DeleteEventHandler(tkwin, StructureNotifyMask, PaneEventProc, panePtr); Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL, panePtr); Tk_DestroyWindow(tkwin); } if (panePtr->handle != NULL) { Tk_Window tkwin; tkwin = panePtr->handle; Tk_DeleteEventHandler(tkwin, ExposureMask|FocusChangeMask|StructureNotifyMask, HandleEventProc, panePtr); Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL, panePtr); panePtr->handle = NULL; Tk_DestroyWindow(tkwin); } Blt_Free(panePtr); } static void CloseDrawer(Pane *panePtr) { Paneset *setPtr; if (panePtr->flags & (CLOSED|DISABLED)) { return; /* Already closed or disabled. */ } if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } setPtr = panePtr->setPtr; if (panePtr->side & SIDE_VERTICAL) { panePtr->y = -1; } else { panePtr->x = -1; } if (panePtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(panePtr->timerToken); panePtr->timerToken = 0; } panePtr->flags |= CLOSED; SetDrawerVariable(panePtr); } static void EventuallyOpenDrawer(Pane *panePtr) { Paneset *setPtr; if ((panePtr->flags & (CLOSED|DISABLED)) != HIDE) { return; /* Already open or disabled. */ } setPtr = panePtr->setPtr; panePtr->flags &= ~CLOSED; SetDrawerVariable(panePtr); if (setPtr->flags & ANIMATE) { int anchor; if (panePtr->side & SIDE_VERTICAL) { panePtr->scrollTarget = GetReqDrawerHeight(panePtr); if (panePtr->y < 0) { panePtr->y = 0; } anchor = panePtr->y; } else { panePtr->scrollTarget = GetReqDrawerWidth(panePtr); if (panePtr->x < 0) { panePtr->x = 0; } anchor = panePtr->x; } if (panePtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(panePtr->timerToken); panePtr->timerToken = 0; } panePtr->scrollIncr = (panePtr->nom > anchor) ? -setPtr->scrollUnits : setPtr->scrollUnits; panePtr->timerToken = Tcl_CreateTimerHandler(setPtr->interval, DrawerTimerProc, panePtr); } else { if (panePtr->side & SIDE_VERTICAL) { panePtr->size = panePtr->y = GetReqDrawerHeight(panePtr); } else { panePtr->size = panePtr->x = GetReqDrawerWidth(panePtr); } SetDrawerVariable(panePtr); } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } static void EventuallyCloseDrawer(Pane *panePtr) { Paneset *setPtr; if (panePtr->flags & (DISABLED|CLOSED)) { return; /* Already closed or disabled. */ } setPtr = panePtr->setPtr; if (setPtr->flags & ANIMATE) { panePtr->scrollTarget = -1; if (panePtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(panePtr->timerToken); panePtr->timerToken = 0; } panePtr->scrollIncr = -setPtr->scrollUnits; panePtr->timerToken = Tcl_CreateTimerHandler(setPtr->interval, DrawerTimerProc, panePtr); } else { CloseDrawer(panePtr); } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * DrawerTimerProc -- * *--------------------------------------------------------------------------- */ static void DrawerTimerProc(ClientData clientData) { Pane *panePtr = clientData; int *anchorPtr; Paneset *setPtr; assert((panePtr->flags & CLOSED) == 0); setPtr = panePtr->setPtr; anchorPtr = (panePtr->side & SIDE_VERTICAL) ? &panePtr->y : &panePtr->x; if (*anchorPtr != panePtr->scrollTarget) { *anchorPtr += panePtr->scrollIncr; if (((panePtr->scrollIncr > 0) && (*anchorPtr>panePtr->scrollTarget)) || ((panePtr->scrollIncr < 0) && (*anchorPtr<panePtr->scrollTarget))) { *anchorPtr = panePtr->scrollTarget; } } if (panePtr->scrollTarget == *anchorPtr) { if (panePtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(panePtr->timerToken); panePtr->timerToken = 0; } if (*anchorPtr < 0) { CloseDrawer(panePtr); } } else if (setPtr->flags & ANIMATE) { panePtr->scrollIncr += panePtr->scrollIncr; panePtr->timerToken = Tcl_CreateTimerHandler(setPtr->interval, DrawerTimerProc, panePtr); } EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * DrawerVarTraceProc -- * * This procedure is invoked when someone changes the state variable * associated with a radiobutton or checkbutton entry. The entry's * selected state is set to match the value of the variable. * * Results: * NULL is always returned. * * Side effects: * The drawer may become opened or closed. * *--------------------------------------------------------------------------- */ static char * DrawerVarTraceProc( ClientData clientData, /* Information about the item. */ Tcl_Interp *interp, /* Interpreter containing variable. */ const char *name1, /* First part of variable's name. */ const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { Pane *panePtr = clientData; Tcl_Obj *objPtr; int bool; assert(panePtr->variableObjPtr != NULL); if (flags & TCL_INTERP_DESTROYED) { return NULL; /* Interpreter is going away. */ } /* * If the variable is being unset, then re-establish the trace. */ if (flags & TCL_TRACE_UNSETS) { panePtr->flags &= ~CLOSED; if (flags & TCL_TRACE_DESTROYED) { char *varName; varName = Tcl_GetString(panePtr->variableObjPtr); Tcl_TraceVar(interp, varName, VAR_FLAGS, DrawerVarTraceProc, clientData); } goto done; } /* * Use the value of the variable to update the selected status of the * item. */ objPtr = Tcl_ObjGetVar2(interp, panePtr->variableObjPtr, NULL, TCL_GLOBAL_ONLY); if (objPtr == NULL) { return NULL; /* Can't get value of variable. */ } bool = 0; if (panePtr->openValueObjPtr == NULL) { if (Tcl_GetBooleanFromObj(NULL, objPtr, &bool) != TCL_OK) { return NULL; } } else { bool = (strcmp(Tcl_GetString(objPtr), Tcl_GetString(panePtr->openValueObjPtr)) == 0); } if (bool) { EventuallyOpenDrawer(panePtr); } else { EventuallyCloseDrawer(panePtr); } done: EventuallyRedraw(panePtr->setPtr); return NULL; /* Done. */ } /*ARGSUSED*/ static void FreeTraceVarProc(ClientData clientData, Display *display, char *widgRec, int offset) { Tcl_Obj **varObjPtrPtr = (Tcl_Obj **)(widgRec + offset); if (*varObjPtrPtr != NULL) { Pane *panePtr = (Pane *)(widgRec); Paneset *setPtr; const char *varName; setPtr = panePtr->setPtr; varName = Tcl_GetString(*varObjPtrPtr); Tcl_UntraceVar(setPtr->interp, varName, VAR_FLAGS, DrawerVarTraceProc, panePtr); Tcl_DecrRefCount(*varObjPtrPtr); *varObjPtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * ObjToTraceVarProc -- * * Convert the string representation of a color into a XColor pointer. * * Results: * The return value is a standard TCL result. The color pointer is * written into the widget record. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTraceVarProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing style. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj **varObjPtrPtr = (Tcl_Obj **)(widgRec + offset); Pane *panePtr = (Pane *)(widgRec); const char *varName; /* Remove the current trace on the variable. */ if (*varObjPtrPtr != NULL) { varName = Tcl_GetString(*varObjPtrPtr); Tcl_UntraceVar(interp, varName, VAR_FLAGS, DrawerVarTraceProc, panePtr); Tcl_DecrRefCount(*varObjPtrPtr); *varObjPtrPtr = NULL; } varName = Tcl_GetString(objPtr); if ((varName[0] == '\0') && (flags & BLT_CONFIG_NULL_OK)) { return TCL_OK; } *varObjPtrPtr = objPtr; Tcl_IncrRefCount(objPtr); Tcl_TraceVar(interp, varName, VAR_FLAGS, DrawerVarTraceProc, panePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TraceVarToObjProc -- * * Return the name of the trace variable. * * Results: * The name of the variable representing the drawer is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TraceVarToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *objPtr = *(Tcl_Obj **)(widgRec + offset); if (objPtr != NULL) { return objPtr; } return Tcl_NewStringObj("", -1); } /* *--------------------------------------------------------------------------- * * ObjToChild -- * * Converts a window name into Tk window. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToChild( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results */ Tk_Window parent, /* Parent window */ Tcl_Obj *objPtr, /* String representation. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Pane *panePtr = (Pane *)widgRec; Paneset *setPtr; Tk_Window *tkwinPtr = (Tk_Window *)(widgRec + offset); Tk_Window old, tkwin; char *string; old = *tkwinPtr; tkwin = NULL; setPtr = panePtr->setPtr; string = Tcl_GetString(objPtr); if (string[0] != '\0') { tkwin = Tk_NameToWindow(interp, string, setPtr->tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (tkwin == old) { return TCL_OK; } /* * Allow only widgets that are children of the paneset/drawer window * to be used. We are using the window as viewport to clip the * children are necessary. */ parent = Tk_Parent(tkwin); if (parent != setPtr->tkwin) { Tcl_AppendResult(interp, "can't manage \"", Tk_PathName(tkwin), "\" in paneset \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } Tk_ManageGeometry(tkwin, &panesetMgrInfo, panePtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, PaneEventProc, panePtr); /* * We need to make the window to exist immediately. If the window is * torn off (placed into another container window), the timing between * the container and the its new child (this window) gets tricky. * This should work for Tk 4.2. */ Tk_MakeWindowExist(tkwin); } if (old != NULL) { Tk_DeleteEventHandler(old, StructureNotifyMask, PaneEventProc, panePtr); Tk_ManageGeometry(old, (Tk_GeomMgr *)NULL, panePtr); Tk_UnmapWindow(old); } *tkwinPtr = tkwin; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ChildToObj -- * * Converts the Tk window back to a Tcl_Obj (i.e. its name). * * Results: * The name of the window is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ChildToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window parent, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Tk_Window tkwin = *(Tk_Window *)(widgRec + offset); Tcl_Obj *objPtr; if (tkwin == NULL) { objPtr = Tcl_NewStringObj("", -1); } else { objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); } return objPtr; } /* *--------------------------------------------------------------------------- * * ObjToMode -- * * Converts an adjust mode name into a enum. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToMode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to report results. */ Tk_Window parent, /* Parent window */ Tcl_Obj *objPtr, /* String representation. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { AdjustMode *modePtr = (AdjustMode *)(widgRec + offset); const char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "slinky") == 0) { *modePtr = MODE_SLINKY; } else if (strcmp(string, "givetake") == 0) { *modePtr = MODE_GIVETAKE; } else if (strcmp(string, "spreadsheet") == 0) { *modePtr = MODE_SPREADSHEET; } else { Tcl_AppendResult(interp, "unknown mode \"", string, "\": should be " "givetake, slinky, or spreadsheet\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ChildToObj -- * * Converts the enum back to a mode string (i.e. its name). * * Results: * The name of the mode is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ModeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window parent, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { AdjustMode mode = *(AdjustMode *)(widgRec + offset); const char *string; switch (mode) { case MODE_SLINKY: string = "slinky"; break; case MODE_GIVETAKE: string = "givetake"; break; case MODE_SPREADSHEET: string = "spreadsheet"; break; default: string = "???"; break; } return Tcl_NewStringObj(string, -1); } /* *--------------------------------------------------------------------------- * * ObjToOrientProc -- * * Converts the string representing a state into a bitflag. * * Results: * The return value is a standard TCL result. The state flags are * updated. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToOrientProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* String representing state. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { Paneset *setPtr = (Paneset *)(widgRec); unsigned int *flagsPtr = (unsigned int *)(widgRec + offset); const char *string; int orient; int length; string = Tcl_GetString(objPtr); length = strlen(string); if (strncmp(string, "vertical", length) == 0) { orient = VERTICAL; } else if (strncmp(string, "horizontal", length) == 0) { orient = 0; } else { Tcl_AppendResult(interp, "bad orientation \"", string, "\": must be vertical or horizontal", (char *)NULL); return TCL_ERROR; } *flagsPtr &= ~VERTICAL; *flagsPtr |= orient; setPtr->flags |= LAYOUT_PENDING; return TCL_OK; } /* *--------------------------------------------------------------------------- * * OrientToObjProc -- * * Return the name of the style. * * Results: * The name representing the style is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * OrientToObjProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget information record */ int offset, /* Offset to field in structure */ int flags) { unsigned int orient = *(unsigned int *)(widgRec + offset); const char *string; if (orient & VERTICAL) { string = "vertical"; } else { string = "horizontal"; } return Tcl_NewStringObj(string, -1); } static void EventuallyRedrawHandle(Pane *panePtr) { if ((panePtr->flags & REDRAW_PENDING) == 0) { panePtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayHandle, panePtr); } } static Pane * FirstPane(Paneset *setPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if ((panePtr->flags & (HIDE|DISABLED)) == 0) { return panePtr; } } return NULL; } static Pane * LastPane(Paneset *setPtr) { Blt_ChainLink link; for (link = Blt_Chain_LastLink(setPtr->chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if ((panePtr->flags & (HIDE|DISABLED)) == 0) { return panePtr; } } return NULL; } static Pane * NextPane(Pane *panePtr) { if (panePtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_NextLink(panePtr->link); link != NULL; link = Blt_Chain_NextLink(link)) { panePtr = Blt_Chain_GetValue(link); if ((panePtr->flags & (HIDE|DISABLED)) == 0) { return panePtr; } } } return NULL; } static Pane * PrevPane(Pane *panePtr) { if (panePtr != NULL) { Blt_ChainLink link; for (link = Blt_Chain_PrevLink(panePtr->link); link != NULL; link = Blt_Chain_PrevLink(link)) { panePtr = Blt_Chain_GetValue(link); if ((panePtr->flags & HIDE) == 0) { return panePtr; } } } return NULL; } /* *--------------------------------------------------------------------------- * * PanesetEventProc -- * * This procedure is invoked by the Tk event handler when the container * widget is reconfigured or destroyed. * * The paneset will be rearranged at the next idle point if the container * widget has been resized or moved. There's a distinction made between * parent and non-parent container arrangements. When the container is * the parent of the embedded widgets, the widgets will automatically * keep their positions relative to the container, even when the * container is moved. But if the container is not the parent, those * widgets have to be moved manually. This can be a performance hit in * rare cases where we're scrolling the container (by moving the window) * and there are lots of non-child widgets arranged inside. * * Results: * None. * * Side effects: * Arranges for the paneset associated with tkwin to have its layout * re-computed and drawn at the next idle point. * *--------------------------------------------------------------------------- */ static void PanesetEventProc(ClientData clientData, XEvent *eventPtr) { Paneset *setPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedraw(setPtr); } } else if (eventPtr->type == DestroyNotify) { if (setPtr->tkwin != NULL) { Blt_DeleteWindowInstanceData(setPtr->tkwin); setPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(setPtr->interp, setPtr->cmdToken); } if (setPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayPaneset, setPtr); } Tcl_EventuallyFree(setPtr, PanesetFreeProc); } else if (eventPtr->type == ConfigureNotify) { setPtr->anchorPtr = LastPane(setPtr); /* Reset anchor pane. */ setPtr->flags |= SCROLL_PENDING; setPtr->anchorPtr = LastPane(setPtr); EventuallyRedraw(setPtr); } } /* *--------------------------------------------------------------------------- * * PaneEventProc -- * * This procedure is invoked by the Tk event handler when StructureNotify * events occur in a widget managed by the paneset. * * For example, when a managed widget is destroyed, it frees the * corresponding pane structure and arranges for the paneset layout to be * re-computed at the next idle point. * * Results: * None. * * Side effects: * If the managed widget was deleted, the Pane structure gets cleaned up * and the paneset is rearranged. * *--------------------------------------------------------------------------- */ static void PaneEventProc( ClientData clientData, /* Pointer to Pane structure for * widget referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { Pane *panePtr = (Pane *)clientData; Paneset *setPtr = panePtr->setPtr; if (eventPtr->type == ConfigureNotify) { int borderWidth; if (panePtr->tkwin == NULL) { return; } borderWidth = Tk_Changes(panePtr->tkwin)->border_width; if (panePtr->borderWidth != borderWidth) { panePtr->borderWidth = borderWidth; EventuallyRedraw(setPtr); } } else if (eventPtr->type == DestroyNotify) { panePtr->tkwin = NULL; Tcl_EventuallyFree(panePtr, PaneFreeProc); setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } } /* *--------------------------------------------------------------------------- * * PaneCustodyProc -- * * This procedure is invoked when a widget has been stolen by another * geometry manager. The information and memory associated with the * widget is released. * * Results: * None. * * Side effects: * Arranges for the paneset to have its layout recomputed at the next * idle point. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void PaneCustodyProc(ClientData clientData, Tk_Window tkwin) { Pane *panePtr = (Pane *)clientData; Paneset *setPtr = panePtr->setPtr; if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } DestroyPane(panePtr); setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * PaneGeometryProc -- * * This procedure is invoked by Tk_GeometryRequest for widgets managed by * the paneset geometry manager. * * Results: * None. * * Side effects: * Arranges for the paneset to have its layout re-computed and re-arranged * at the next idle point. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ static void PaneGeometryProc(ClientData clientData, Tk_Window tkwin) { Pane *panePtr = (Pane *)clientData; panePtr->setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(panePtr->setPtr); } /* *--------------------------------------------------------------------------- * * HandleEventProc -- * * This procedure is invoked by the Tk event handler when various events * occur in the pane/drawer handle subwindow maintained by this widget. * * Results: * None. * *--------------------------------------------------------------------------- */ static void HandleEventProc( ClientData clientData, /* Pointer to Pane structure for * handle referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { Pane *panePtr = (Pane *)clientData; Paneset *setPtr = panePtr->setPtr; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { EventuallyRedrawHandle(panePtr); } } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { panePtr->flags |= FOCUS; } else { panePtr->flags &= ~FOCUS; } EventuallyRedrawHandle(panePtr); } } else if (eventPtr->type == ConfigureNotify) { if (panePtr->handle == NULL) { return; } EventuallyRedrawHandle(panePtr); } else if (eventPtr->type == DestroyNotify) { panePtr->handle = NULL; Tcl_DeleteCommandFromToken(setPtr->interp, panePtr->cmdToken); } } static Blt_HashTable * GetTagTable(Paneset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&setPtr->tagTable, tagName); if (hPtr == NULL) { return NULL; /* No tag by name. */ } return Blt_GetHashValue(hPtr); } static int HasTag(Pane *panePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; if (strcmp(tagName, "all") == 0) { return TRUE; } tablePtr = GetTagTable(panePtr->setPtr, tagName); if (tablePtr == NULL) { return FALSE; } hPtr = Blt_FindHashEntry(tablePtr, (char *)panePtr); if (hPtr == NULL) { return FALSE; } return TRUE; } static Blt_HashTable * AddTagTable(Paneset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; int isNew; hPtr = Blt_CreateHashEntry(&setPtr->tagTable, tagName, &isNew); if (isNew) { tablePtr = Blt_AssertMalloc(sizeof(Blt_HashTable)); Blt_InitHashTable(tablePtr, BLT_ONE_WORD_KEYS); Blt_SetHashValue(hPtr, tablePtr); } else { tablePtr = Blt_GetHashValue(hPtr); } return tablePtr; } static void AddTag(Paneset *setPtr, Pane *panePtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; int isNew; tablePtr = AddTagTable(setPtr, tagName); hPtr = Blt_CreateHashEntry(tablePtr, (char *)panePtr, &isNew); if (isNew) { Blt_SetHashValue(hPtr, panePtr); } } static void ForgetTag(Paneset *setPtr, const char *tagName) { Blt_HashEntry *hPtr; Blt_HashTable *tablePtr; if (strcmp(tagName, "all") == 0) { return; /* Can't remove tag "all". */ } hPtr = Blt_FindHashEntry(&setPtr->tagTable, tagName); if (hPtr == NULL) { return; /* No tag by name. */ } tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); Blt_Free(tablePtr); Blt_DeleteHashEntry(&setPtr->tagTable, hPtr); } static void DestroyTags(Paneset *setPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); Blt_DeleteHashTable(tablePtr); } } static void RemoveTag(Pane *panePtr, const char *tagName) { Blt_HashTable *tablePtr; Paneset *setPtr; setPtr = panePtr->setPtr; tablePtr = GetTagTable(setPtr, tagName); if (tablePtr != NULL) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)panePtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } static INLINE Pane * BeginPane(Paneset *setPtr) { Blt_ChainLink link; link = Blt_Chain_FirstLink(setPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static INLINE Pane * EndPane(Paneset *setPtr) { Blt_ChainLink link; link = Blt_Chain_LastLink(setPtr->chain); if (link != NULL) { return Blt_Chain_GetValue(link); } return NULL; } static Pane * StepPane(Pane *panePtr) { if (panePtr != NULL) { Blt_ChainLink link; link = Blt_Chain_NextLink(panePtr->link); if (link != NULL) { return Blt_Chain_GetValue(link); } } return NULL; } /* *--------------------------------------------------------------------------- * * NextTaggedPane -- * * Returns the next pane derived from the given tag. * * Results: * Returns the pointer to the next pane in the iterator. If no more panes * are available, then NULL is returned. * *--------------------------------------------------------------------------- */ static Pane * NextTaggedPane(PaneIterator *iterPtr) { switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_NextHashEntry(&iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } break; } case ITER_ALL: if (iterPtr->link != NULL) { Pane *panePtr; panePtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return panePtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(panePtr->name, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return panePtr; } } break; } default: break; } return NULL; } /* *--------------------------------------------------------------------------- * * FirstTaggedPane -- * * Returns the first pane derived from the given tag. * * Results: * Returns the first pane in the sequence. If no more panes are in the * list, then NULL is returned. * *--------------------------------------------------------------------------- */ static Pane * FirstTaggedPane(PaneIterator *iterPtr) { switch (iterPtr->type) { case ITER_TAG: { Blt_HashEntry *hPtr; hPtr = Blt_FirstHashEntry(iterPtr->tablePtr, &iterPtr->cursor); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } } break ; case ITER_ALL: if (iterPtr->link != NULL) { Pane *panePtr; panePtr = Blt_Chain_GetValue(iterPtr->link); iterPtr->link = Blt_Chain_NextLink(iterPtr->link); return panePtr; } break; case ITER_PATTERN: { Blt_ChainLink link; for (link = iterPtr->link; link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(iterPtr->link); if (Tcl_StringMatch(panePtr->name, iterPtr->tagName)) { iterPtr->link = Blt_Chain_NextLink(link); return panePtr; } } break; } case ITER_SINGLE: return iterPtr->startPtr; } return NULL; } /* *--------------------------------------------------------------------------- * * GetPaneFromObj -- * * Gets the pane associated the given index, tag, or label. This routine * is used when you want only one pane. It's an error if more than one * pane is specified (e.g. "all" tag or range "1:4"). It's also an error * if the tag is empty (no panes are currently tagged). * *--------------------------------------------------------------------------- */ static int GetPaneFromObj(Tcl_Interp *interp, Paneset *setPtr, Tcl_Obj *objPtr, Pane **panePtrPtr) { PaneIterator iter; Pane *firstPtr; if (GetPaneIterator(interp, setPtr, objPtr, &iter) != TCL_OK) { return TCL_ERROR; } firstPtr = FirstTaggedPane(&iter); if (firstPtr != NULL) { Pane *nextPtr; nextPtr = NextTaggedPane(&iter); if (nextPtr != NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "multiple panes specified by \"", Tcl_GetString(objPtr), "\"", (char *)NULL); } return TCL_ERROR; } } *panePtrPtr = firstPtr; return TCL_OK; } static int GetPaneByIndex(Tcl_Interp *interp, Paneset *setPtr, const char *string, int length, Pane **panePtrPtr) { Pane *panePtr; char c; long pos; panePtr = NULL; c = string[0]; if (Tcl_GetLong(NULL, string, &pos) == TCL_OK) { Blt_ChainLink link; link = Blt_Chain_GetNthLink(setPtr->chain, pos); if (link != NULL) { panePtr = Blt_Chain_GetValue(link); } if (panePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find pane: bad index \"", string, "\"", (char *)NULL); } return TCL_ERROR; } } else if ((c == 'a') && (strcmp(string, "active") == 0)) { panePtr = setPtr->activePtr; } else if ((c == 'f') && (strcmp(string, "first") == 0)) { panePtr = FirstPane(setPtr); } else if ((c == 'l') && (strcmp(string, "last") == 0)) { panePtr = LastPane(setPtr); } else if ((c == 'e') && (strcmp(string, "end") == 0)) { panePtr = LastPane(setPtr); } else if ((c == 'n') && (strcmp(string, "none") == 0)) { panePtr = NULL; } else { return TCL_CONTINUE; } *panePtrPtr = panePtr; return TCL_OK; } static Pane * GetPaneByName(Paneset *setPtr, const char *string) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&setPtr->paneTable, string); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } /* *--------------------------------------------------------------------------- * * GetPaneIterator -- * * Converts a string representing a pane index into an pane pointer. The * index may be in one of the following forms: * * number Pane at index in the list of panes. * @x,y Pane closest to the specified X-Y screen coordinates. * "active" Pane where mouse pointer is located. * "posted" Pane is the currently posted cascade pane. * "next" Next pane from the focus pane. * "previous" Previous pane from the focus pane. * "end" Last pane. * "none" No pane. * * number Pane at position in the list of panes. * @x,y Pane closest to the specified X-Y screen coordinates. * "active" Pane mouse is located over. * "focus" Pane is the widget's focus. * "select" Currently selected pane. * "right" Next pane from the focus pane. * "left" Previous pane from the focus pane. * "up" Next pane from the focus pane. * "down" Previous pane from the focus pane. * "end" Last pane in list. * "name:string" Pane named "string". * "index:number" Pane at index number in list of panes. * "tag:string" Pane(s) tagged by "string". * "label:pattern" Pane(s) with label matching "pattern". * * Results: * If the string is successfully converted, TCL_OK is returned. The * pointer to the node is returned via panePtrPtr. Otherwise, TCL_ERROR * is returned and an error message is left in interpreter's result * field. * *--------------------------------------------------------------------------- */ static int GetPaneIterator(Tcl_Interp *interp, Paneset *setPtr, Tcl_Obj *objPtr, PaneIterator *iterPtr) { Pane *panePtr, *startPtr, *endPtr; Blt_HashTable *tablePtr; char *string; char c; int nBytes; int length; int result; iterPtr->setPtr = setPtr; iterPtr->type = ITER_SINGLE; iterPtr->tagName = Tcl_GetStringFromObj(objPtr, &nBytes); iterPtr->nextPtr = NULL; iterPtr->startPtr = iterPtr->endPtr = NULL; string = Tcl_GetStringFromObj(objPtr, &length); c = string[0]; iterPtr->startPtr = iterPtr->endPtr = setPtr->activePtr; startPtr = endPtr = panePtr = NULL; if (c == '\0') { startPtr = endPtr = NULL; } iterPtr->type = ITER_SINGLE; result = GetPaneByIndex(interp, setPtr, string, length, &panePtr); if (result == TCL_ERROR) { return TCL_ERROR; } if (result == TCL_OK) { iterPtr->startPtr = iterPtr->endPtr = panePtr; return TCL_OK; } if ((c == 'a') && (strcmp(iterPtr->tagName, "all") == 0)) { iterPtr->type = ITER_ALL; iterPtr->link = Blt_Chain_FirstLink(setPtr->chain); } else if ((c == 'i') && (length > 6) && (strncmp(string, "index:", 6) == 0)) { if (GetPaneByIndex(interp, setPtr, string + 6, length - 6, &panePtr) != TCL_OK) { return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = panePtr; } else if ((c == 'n') && (length > 5) && (strncmp(string, "name:", 5) == 0)) { panePtr = GetPaneByName(setPtr, string + 5); if (panePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find a pane named \"", string + 5, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->startPtr = iterPtr->endPtr = panePtr; } else if ((c == 't') && (length > 4) && (strncmp(string, "tag:", 4) == 0)) { Blt_HashTable *tablePtr; tablePtr = GetTagTable(setPtr, string + 4); if (tablePtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find a tag \"", string + 5, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } iterPtr->tagName = string + 4; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else if ((c == 'l') && (length > 6) && (strncmp(string, "label:", 6) == 0)) { iterPtr->link = Blt_Chain_FirstLink(setPtr->chain); iterPtr->tagName = string + 6; iterPtr->type = ITER_PATTERN; } else if ((panePtr = GetPaneByName(setPtr, string)) != NULL) { iterPtr->startPtr = iterPtr->endPtr = panePtr; } else if ((tablePtr = GetTagTable(setPtr, string)) != NULL) { iterPtr->tagName = string; iterPtr->tablePtr = tablePtr; iterPtr->type = ITER_TAG; } else { if (interp != NULL) { Tcl_AppendResult(interp, "can't find pane index, name, or tag \"", string, "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * NewPane -- * * This procedure creates and initializes a new Pane structure to hold a * widget. A valid widget has a parent widget that is either a) the * container widget itself or b) a mutual ancestor of the container widget. * * Results: * Returns a pointer to the new structure describing the new widget pane. * If an error occurred, then the return value is NULL and an error message * is left in interp->result. * * Side effects: * Memory is allocated and initialized for the Pane structure. * * ---------------------------------------------------------------------------- */ static Pane * NewPane(Tcl_Interp *interp, Paneset *setPtr, const char *name) { Blt_HashEntry *hPtr; Pane *panePtr; int isNew; const char *object, *className; char *handleName; char string[200]; if (setPtr->type == DRAWER) { className = "DrawerHandle"; object = "drawer"; } else if (setPtr->type == PANESET) { className = "PanesetSash"; object = "pane"; } else if (setPtr->type == FILMSTRIP) { className = "FilmstripHandle"; object = "frame"; } { char *path; /* Generate an unique subwindow name. In theory you could have more * than one drawer widget assigned to the same window. */ path = Blt_AssertMalloc(strlen(Tk_PathName(setPtr->tkwin)) + 200); do { sprintf(string, "%s%lu", object, setPtr->nextId++); sprintf(path, "%s.%s", Tk_PathName(setPtr->tkwin), string); } while (Tk_NameToWindow(interp, path, setPtr->tkwin) != NULL); Blt_Free(path); handleName = string; } if (name == NULL) { name = handleName; } hPtr = Blt_CreateHashEntry(&setPtr->paneTable, name, &isNew); if (!isNew) { Tcl_AppendResult(interp, object, " \"", name, "\" already exists.", (char *)NULL); return NULL; } panePtr = Blt_AssertCalloc(1, sizeof(Pane)); Blt_ResetLimits(&panePtr->reqWidth); Blt_ResetLimits(&panePtr->reqHeight); Blt_ResetLimits(&panePtr->reqSize); panePtr->setPtr = setPtr; panePtr->name = Blt_GetHashKey(&setPtr->paneTable, hPtr); panePtr->hashPtr = hPtr; panePtr->anchor = TK_ANCHOR_CENTER; panePtr->fill = FILL_NONE; panePtr->nom = LIMITS_NOM; panePtr->size = panePtr->index = 0; panePtr->flags = VIRGIN | SHOW_HANDLE; if (setPtr->type == DRAWER) { panePtr->flags |= CLOSED | HANDLE; panePtr->resize = RESIZE_SHRINK; panePtr->fill = TRUE; } else { panePtr->resize = RESIZE_BOTH; panePtr->side = HANDLE_FARSIDE; } panePtr->weight = 1.0f; Blt_SetHashValue(hPtr, panePtr); panePtr->handle = Tk_CreateWindow(interp, setPtr->tkwin, handleName, (char *)NULL); if (panePtr->handle == NULL) { return NULL; } Tk_CreateEventHandler(panePtr->handle, ExposureMask|FocusChangeMask|StructureNotifyMask, HandleEventProc, panePtr); Tk_SetClass(panePtr->handle, className); panePtr->cmdToken = Tcl_CreateObjCommand(interp, Tk_PathName(panePtr->handle), HandleInstCmdProc, panePtr, HandleInstCmdDeleteProc); return panePtr; } /* *--------------------------------------------------------------------------- * * PaneFreeProc -- * * Removes the Pane structure from the hash table and frees the memory * allocated by it. * * Results: * None. * * Side effects: * Everything associated with the pane is freed up. * *--------------------------------------------------------------------------- */ static void PaneFreeProc(DestroyData dataPtr) { Pane *panePtr = (Pane *)dataPtr; DestroyPane(panePtr); } /* *--------------------------------------------------------------------------- * * NewPaneset -- * * This procedure creates and initializes a new Paneset structure with * tkwin as its container widget. The internal structures associated with * the paneset are initialized. * * Results: * Returns the pointer to the new Paneset structure describing the new * paneset geometry manager. If an error occurred, the return value will * be NULL and an error message is left in interp->result. * * Side effects: * Memory is allocated and initialized, an event handler is set up to * watch tkwin, etc. * *--------------------------------------------------------------------------- */ static Paneset * NewPaneset(Tcl_Interp *interp, Tcl_Obj *objPtr, int type) { Paneset *setPtr; Tk_Window tkwin; tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), Tcl_GetString(objPtr), (char *)NULL); if (tkwin == NULL) { return NULL; } if (type == PANESET) { Tk_SetClass(tkwin, (char *)"Paneset"); } else if (type == FILMSTRIP) { Tk_SetClass(tkwin, (char *)"Filmstrip"); } setPtr = Blt_AssertCalloc(1, sizeof(Paneset)); setPtr->type = type; setPtr->tkwin = tkwin; setPtr->interp = interp; setPtr->display = Tk_Display(tkwin); setPtr->chain = Blt_Chain_Create(); setPtr->handleThickness = 2; setPtr->handlePad.side1 = setPtr->handlePad.side2 = 2; setPtr->relief = TK_RELIEF_FLAT; setPtr->activeRelief = TK_RELIEF_RAISED; setPtr->handleBW = 1; setPtr->flags = LAYOUT_PENDING; setPtr->mode = MODE_GIVETAKE; setPtr->interval = 30; setPtr->scrollUnits = 10; setPtr->highlightThickness = 2; Blt_SetWindowInstanceData(tkwin, setPtr); Blt_InitHashTable(&setPtr->paneTable, BLT_STRING_KEYS); Blt_InitHashTable(&setPtr->tagTable, BLT_STRING_KEYS); Tk_CreateEventHandler(tkwin, ExposureMask|StructureNotifyMask, PanesetEventProc, setPtr); setPtr->chain = Blt_Chain_Create(); setPtr->cmdToken = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), PanesetInstCmdProc, setPtr, PanesetInstCmdDeleteProc); setPtr->defVertCursor = Tk_GetCursor(interp, tkwin, DEF_VCURSOR); setPtr->defHorzCursor = Tk_GetCursor(interp, tkwin, DEF_HCURSOR); return setPtr; } /* *--------------------------------------------------------------------------- * * NewDrawerset -- * * This procedure creates and initializes a new Paneset structure with * tkwin as its container widget. The internal structures associated with * the paneset are initialized. * * Results: * Returns the pointer to the new Paneset structure describing the new * paneset geometry manager. If an error occurred, the return value will * be NULL and an error message is left in interp->result. * * Side effects: * Memory is allocated and initialized, an event handler is set up to * watch tkwin, etc. * *--------------------------------------------------------------------------- */ static Paneset * NewDrawerset(Tcl_Interp *interp, Tcl_Obj *objPtr) { Paneset *setPtr; Tk_Window tkwin; const char *string; unsigned long count; string = Tcl_GetString(objPtr); tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return NULL; } setPtr = Blt_AssertCalloc(1, sizeof(Paneset)); setPtr->tkwin = tkwin; setPtr->type = DRAWER; setPtr->interp = interp; setPtr->display = Tk_Display(tkwin); setPtr->chain = Blt_Chain_Create(); setPtr->handleThickness = 2; setPtr->handlePad.side1 = setPtr->handlePad.side2 = 2; setPtr->relief = TK_RELIEF_FLAT; setPtr->activeRelief = TK_RELIEF_RAISED; setPtr->handleBW = 1; setPtr->flags = 0; setPtr->interval = 30; setPtr->scrollUnits = 10; setPtr->highlightThickness = 2; Blt_SetWindowInstanceData(tkwin, setPtr); Blt_InitHashTable(&setPtr->paneTable, BLT_STRING_KEYS); Blt_InitHashTable(&setPtr->tagTable, BLT_STRING_KEYS); Tk_CreateEventHandler(tkwin, ExposureMask|StructureNotifyMask, PanesetEventProc, setPtr); setPtr->chain = Blt_Chain_Create(); setPtr->name = Blt_AssertMalloc(strlen(string) + 200); count = 1; do { sprintf(setPtr->name, "%s_drawerset%lu", string, count++); } while (Tcl_FindCommand(interp, setPtr->name, (Tcl_Namespace *)NULL, 0) != NULL); setPtr->cmdToken = Tcl_CreateObjCommand(interp, setPtr->name, DrawerInstCmdProc, setPtr, DrawerInstCmdDeleteProc); setPtr->defVertCursor = Tk_GetCursor(interp, tkwin, DEF_VCURSOR); setPtr->defHorzCursor = Tk_GetCursor(interp, tkwin, DEF_HCURSOR); return setPtr; } static void RenumberPanes(Paneset *setPtr) { int count; Blt_ChainLink link; count = 0; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); panePtr->index = count; count++; } } /* *--------------------------------------------------------------------------- * * DestroyPaneset -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the Paneset structure at a safe time (when no-one is using it * anymore). * * Results: * None. * * Side effects: * Everything associated with the paneset geometry manager is freed up. * *--------------------------------------------------------------------------- */ static void DestroyPaneset(Paneset *setPtr) /* Paneset structure */ { Blt_ChainLink link; Blt_FreeOptions(panesetSpecs, (char *)setPtr, setPtr->display, 0); /* Release the chain of entries. */ for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); panePtr->link = NULL; /* Don't disrupt this chain of * entries. */ panePtr->hashPtr = NULL; DestroyPane(panePtr); } Tk_FreeCursor(setPtr->display, setPtr->defHorzCursor); Tk_FreeCursor(setPtr->display, setPtr->defVertCursor); DestroyTags(setPtr); Blt_Chain_Destroy(setPtr->chain); Blt_DeleteHashTable(&setPtr->paneTable); Blt_Free(setPtr); } /* *--------------------------------------------------------------------------- * * PanesetFreeProc -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the Paneset structure at a safe time (when no-one is using it * anymore). * * Results: * None. * * Side effects: * Everything associated with the paneset geometry manager is freed up. * *--------------------------------------------------------------------------- */ static void PanesetFreeProc(DestroyData dataPtr) /* Paneset structure */ { Paneset *setPtr = (Paneset *)dataPtr; DestroyPaneset(setPtr); } /* *--------------------------------------------------------------------------- * * TranslateAnchor -- * * Translate the coordinates of a given bounding box based upon the * anchor specified. The anchor indicates where the given xy position is * in relation to the bounding box. * * nw --- n --- ne * | | x,y ---+ * w center e | | * | | +-----+ * sw --- s --- se * * Results: * The translated coordinates of the bounding box are returned. * *--------------------------------------------------------------------------- */ static void TranslateAnchor( int dx, int dy, /* Difference between outer and inner * regions. */ Tk_Anchor anchor, /* Direction of the anchor */ int *xPtr, int *yPtr) { int x, y; x = y = 0; switch (anchor) { case TK_ANCHOR_NW: /* Upper left corner */ break; case TK_ANCHOR_W: /* Left center */ y = (dy / 2); break; case TK_ANCHOR_SW: /* Lower left corner */ y = dy; break; case TK_ANCHOR_N: /* Top center */ x = (dx / 2); break; case TK_ANCHOR_CENTER: /* Centered */ x = (dx / 2); y = (dy / 2); break; case TK_ANCHOR_S: /* Bottom center */ x = (dx / 2); y = dy; break; case TK_ANCHOR_NE: /* Upper right corner */ x = dx; break; case TK_ANCHOR_E: /* Right center */ x = dx; y = (dy / 2); break; case TK_ANCHOR_SE: /* Lower right corner */ x = dx; y = dy; break; } *xPtr = (*xPtr) + x; *yPtr = (*yPtr) + y; } /* *--------------------------------------------------------------------------- * * LeftSpan -- * * Sums the space requirements of all the panes. * * Results: * Returns the space currently used by the paneset widget. * *--------------------------------------------------------------------------- */ static int LeftSpan(Paneset *setPtr) { int total; Pane *panePtr; total = 0; /* The left span is every pane before and including) the anchor pane. */ for (panePtr = setPtr->anchorPtr; panePtr != NULL; panePtr = PrevPane(panePtr)) { total += panePtr->size; } return total; } /* *--------------------------------------------------------------------------- * * RightSpan -- * * Sums the space requirements of all the panes. * * Results: * Returns the space currently used by the paneset widget. * *--------------------------------------------------------------------------- */ static int RightSpan(Paneset *setPtr) { int total; Pane *panePtr; total = 0; for (panePtr = NextPane(setPtr->anchorPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { total += panePtr->size; } return total; } static int LeftSpanLimits(Paneset *setPtr, int *minPtr, int *maxPtr) { int total, min, max; Pane *panePtr; total = min = max = 0; /* The left span is every pane before and including) the anchor pane. */ for (panePtr = setPtr->anchorPtr; panePtr != NULL; panePtr = PrevPane(panePtr)) { total += panePtr->size; max += panePtr->max; min += panePtr->min; } *minPtr = min; *maxPtr = max; return total; } static int RightSpanLimits(Paneset *setPtr, int *minPtr, int *maxPtr) { int min, max, total; Pane *panePtr; total = min = max = 0; for (panePtr = NextPane(setPtr->anchorPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { total += panePtr->size; max += panePtr->max; min += panePtr->min; } *minPtr = min; *maxPtr = max; return total; } static int GetReqPaneWidth(Pane *panePtr) { int w; w = GetReqWidth(panePtr) + PADDING(panePtr->xPad); if ((ISHORIZ(panePtr->setPtr)) && (panePtr->flags & HANDLE)) { w += panePtr->setPtr->handleSize; } return w; } static int GetReqPaneHeight(Pane *panePtr) { int h; h = GetReqHeight(panePtr) + PADDING(panePtr->yPad); if ((ISVERT(panePtr->setPtr)) && (panePtr->flags & HANDLE)) { h += panePtr->setPtr->handleSize; } return h; } /* *--------------------------------------------------------------------------- * * GrowPane -- * * Expand the span by the amount of the extra space needed. This * procedure is used in Layout*Panes to grow the panes to their minimum * nominal size, starting from a zero width and height space. * * On the first pass we try to add space to panes which have not been * touched yet (i.e. have no nominal size). * * If there is still extra space after the first pass, this means that * there were no panes could be expanded. This pass will try to remedy * this by parcelling out the left over space evenly among the rest of * the panes. * * On each pass, we have to keep iterating over the list, evenly doling * out slices of extra space, because we may hit pane limits as space is * donated. In addition, if there are left over pixels because of * round-off, this will distribute them as evenly as possible. * * Results: * None. * * Side Effects: * The panes in the span may be expanded. * *--------------------------------------------------------------------------- */ static void GrowPane(Pane *panePtr, int extra) { if ((panePtr->nom == LIMITS_NOM) && (panePtr->max > panePtr->size)) { int avail; avail = panePtr->max - panePtr->size; if (avail > extra) { panePtr->size += extra; return; } else { extra -= avail; panePtr->size += avail; } } /* Find out how many panes still have space available */ if ((panePtr->resize & RESIZE_EXPAND) && (panePtr->max > panePtr->size)) { int avail; avail = panePtr->max - panePtr->size; if (avail > extra) { panePtr->size += extra; return; } else { extra -= avail; panePtr->size += avail; } } } /* *--------------------------------------------------------------------------- * * GrowSpan -- * * Grow the span by the designated amount. Size constraints on the panes * may prevent any or all of the spacing adjustments. * * This is very much like the GrowPane procedure, but in this case we are * expanding all the panes. It uses a two pass approach, first giving * space to panes which are smaller than their nominal sizes. This is * because constraints on the panes may cause resizing to be non-linear. * * If there is still extra space, this means that all panes are at least * to their nominal sizes. The second pass will try to add the left over * space evenly among all the panes which still have space available * (i.e. haven't reached their specified max sizes). * * Results: * None. * * Side Effects: * The size of the pane may be increased. * *--------------------------------------------------------------------------- */ static void GrowSpan(Blt_Chain chain, int adjustment) { int delta; /* Amount of space needed */ int nAdjust; /* Number of rows/columns that still can * be adjusted. */ Blt_ChainLink link; float totalWeight; /* * Pass 1: First adjust the size of panes that still haven't reached their * nominal size. */ delta = adjustment; nAdjust = 0; totalWeight = 0.0f; for (link = Blt_Chain_LastLink(chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if ((panePtr->weight > 0.0f) && (panePtr->nom > panePtr->size)) { nAdjust++; totalWeight += panePtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0f) && (delta > 0)) { Blt_ChainLink link; int ration; /* Amount of space to add to each * row/column. */ ration = (int)(delta / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_LastLink(chain); (link != NULL) && (delta > 0); link = Blt_Chain_PrevLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if (panePtr->weight > 0.0f) { int avail; /* Amount of space still available. */ avail = panePtr->nom - panePtr->size; if (avail > 0) { int size; /* Amount of space requested for a * particular row/column. */ size = (int)(ration * panePtr->weight); if (size > delta) { size = delta; } if (size < avail) { delta -= size; panePtr->size += size; } else { delta -= avail; panePtr->size += avail; nAdjust--; totalWeight -= panePtr->weight; } } } } } /* * Pass 2: Adjust the panes with space still available */ nAdjust = 0; totalWeight = 0.0f; for (link = Blt_Chain_LastLink(chain); link != NULL; link = Blt_Chain_PrevLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if ((panePtr->weight > 0.0f) && (panePtr->max > panePtr->size)) { nAdjust++; totalWeight += panePtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0f) && (delta > 0)) { Blt_ChainLink link; int ration; /* Amount of space to add to each * row/column. */ ration = (int)(delta / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_LastLink(chain); (link != NULL) && (delta > 0); link = Blt_Chain_PrevLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if (panePtr->weight > 0.0f) { int avail; /* Amount of space still available */ avail = (panePtr->max - panePtr->size); if (avail > 0) { int size; /* Amount of space requested for a * particular row/column. */ size = (int)(ration * panePtr->weight); if (size > delta) { size = delta; } if (size < avail) { delta -= size; panePtr->size += size; } else { delta -= avail; panePtr->size += avail; nAdjust--; totalWeight -= panePtr->weight; } } } } } } /* *--------------------------------------------------------------------------- * * ShrinkSpan -- * * Shrink the span by the amount specified. Size constraints on the * panes may prevent any or all of the spacing adjustments. * * This is very much like the GrowPane procedure, but in this case we are * shrinking the panes. It uses a two pass approach, first subtracting * space to panes which are larger than their nominal sizes. This is * because constraints on the panes may cause resizing to be non-linear. * * After pass 1, if there is still extra to be removed, this means that * all panes are at least to their nominal sizes. The second pass will * try to remove the extra space evenly among all the panes which still * have space available (i.e haven't reached their respective min sizes). * * Results: * None. * * Side Effects: * The size of the panes may be decreased. * *--------------------------------------------------------------------------- */ static void ShrinkSpan(Blt_Chain chain, int adjustment) { Blt_ChainLink link; int extra; /* Amount of space needed */ int nAdjust; /* Number of panes that still can be * adjusted. */ float totalWeight; extra = -adjustment; /* * Pass 1: First adjust the size of panes that still aren't at their * nominal size. */ nAdjust = 0; totalWeight = 0.0f; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if ((panePtr->weight > 0.0f) && (panePtr->nom < panePtr->size)) { nAdjust++; totalWeight += panePtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0f) && (extra > 0)) { Blt_ChainLink link; int ration; /* Amount of space to subtract from each * row/column. */ ration = (int)(extra / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (extra > 0); link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if (panePtr->weight > 0.0f) { int avail; /* Amount of space still available */ avail = panePtr->size - panePtr->nom; if (avail > 0) { int slice; /* Amount of space requested for a * particular row/column. */ slice = (int)(ration * panePtr->weight); if (slice > extra) { slice = extra; } if (avail > slice) { extra -= slice; panePtr->size -= slice; } else { extra -= avail; panePtr->size -= avail; nAdjust--; /* Goes to zero (nominal). */ totalWeight -= panePtr->weight; } } } } } /* * Pass 2: Now adjust the panes with space still available (i.e. * are bigger than their minimum size). */ nAdjust = 0; totalWeight = 0.0f; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; int avail; panePtr = Blt_Chain_GetValue(link); avail = panePtr->size - panePtr->min; if ((panePtr->weight > 0.0f) && (avail > 0)) { nAdjust++; totalWeight += panePtr->weight; } } while ((nAdjust > 0) && (totalWeight > 0.0f) && (extra > 0)) { Blt_ChainLink link; int ration; /* Amount of space to subtract from each * pane. */ ration = (int)(extra / totalWeight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(chain); (link != NULL) && (extra > 0); link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); if (panePtr->weight > 0.0f) { int avail; /* Amount of space still available */ avail = panePtr->size - panePtr->min; if (avail > 0) { int slice; /* Amount of space requested for a * particular pane. */ slice = (int)(ration * panePtr->weight); if (slice > extra) { slice = extra; } if (avail > slice) { extra -= slice; panePtr->size -= slice; } else { extra -= avail; panePtr->size -= avail; nAdjust--; totalWeight -= panePtr->weight; } } } } } } /* |pos anchor| */ static void ShrinkLeftGrowRight(Paneset *setPtr, Pane *leftPtr, Pane *rightPtr, int delta) { int extra; Pane *panePtr; extra = delta; for (panePtr = leftPtr; (panePtr != NULL) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to shrink */ avail = panePtr->size - panePtr->min; if (avail > 0) { if (avail > extra) { panePtr->size -= extra; extra = 0; } else { panePtr->size -= avail; extra -= avail; } } } extra = delta - extra; for (panePtr = rightPtr; (panePtr != NULL) && (extra > 0); panePtr = NextPane(panePtr)) { int avail; /* Space available to grow. */ avail = panePtr->max - panePtr->size; if (avail > 0) { if (avail > extra) { panePtr->size += extra; extra = 0; } else { panePtr->size += avail; extra -= avail; } } } } /* |anchor pos| */ static void GrowLeftShrinkRight(Paneset *setPtr, Pane *leftPtr, Pane *rightPtr, int delta) { int extra; Pane *panePtr; extra = delta; for (panePtr = rightPtr; (panePtr != NULL) && (extra > 0); panePtr = NextPane(panePtr)) { int avail; /* Space available to shrink */ avail = panePtr->size - panePtr->min; if (avail > 0) { if (avail > extra) { panePtr->size -= extra; extra = 0; } else { panePtr->size -= avail; extra -= avail; } } } extra = delta - extra; for (panePtr = leftPtr; (panePtr != NULL) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to grow. */ avail = panePtr->max - panePtr->size; if (avail > 0) { if (avail > extra) { panePtr->size += extra; extra = 0; } else { panePtr->size += avail; extra -= avail; } } } } /* |pos anchor| */ static void ShrinkLeftGrowLast(Paneset *setPtr, Pane *leftPtr, Pane *rightPtr, int delta) { int extra; Pane *panePtr; extra = delta; for (panePtr = leftPtr; (panePtr != NULL) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to shrink */ avail = panePtr->size - panePtr->min; if (avail > 0) { if (avail > extra) { panePtr->size -= extra; extra = 0; } else { panePtr->size -= avail; extra -= avail; } } } #ifdef notdef extra = delta - extra; for (panePtr = LastPane(setPtr);(panePtr != leftPtr) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to grow. */ avail = panePtr->max - panePtr->size; if (avail > 0) { if (avail > extra) { panePtr->size += extra; extra = 0; } else { panePtr->size += avail; extra -= avail; } } } #endif } /* |anchor pos| */ static void GrowLeftShrinkLast(Paneset *setPtr, Pane *leftPtr, Pane *rightPtr, int delta) { int extra; Pane *panePtr; extra = delta; #ifdef notdef for (panePtr = LastPane(setPtr);(panePtr != leftPtr) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to shrink */ avail = panePtr->size - panePtr->min; if (avail > 0) { if (avail > extra) { panePtr->size -= extra; extra = 0; } else { panePtr->size -= avail; extra -= avail; } } } extra = delta - extra; #endif for (panePtr = leftPtr; (panePtr != NULL) && (extra > 0); panePtr = PrevPane(panePtr)) { int avail; /* Space available to grow. */ avail = panePtr->max - panePtr->size; if (avail > 0) { if (avail > extra) { panePtr->size += extra; extra = 0; } else { panePtr->size += avail; extra -= avail; } } } } static Blt_Chain SortedSpan(Paneset *setPtr, Pane *firstPtr, Pane *lastPtr) { Blt_Chain chain; SizeProc *proc; Pane *panePtr; proc = ISVERT(setPtr) ? GetReqPaneHeight : GetReqPaneWidth; chain = Blt_Chain_Create(); for (panePtr = firstPtr; panePtr != lastPtr; panePtr = NextPane(panePtr)) { int d1; Blt_ChainLink link, before, newLink; d1 = (*proc)(panePtr) - panePtr->size; before = NULL; for (link = Blt_Chain_FirstLink(chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *pane2Ptr; int d2; pane2Ptr = Blt_Chain_GetValue(link); d2 = (*proc)(pane2Ptr) - pane2Ptr->size; if (d2 >= d1) { before = link; break; } } newLink = Blt_Chain_NewLink(); Blt_Chain_SetValue(newLink, panePtr); if (before != NULL) { Blt_Chain_LinkBefore(chain, newLink, before); } else { Blt_Chain_LinkAfter(chain, newLink, NULL); } } return chain; } /* *--------------------------------------------------------------------------- * * ResetDrawers -- * * Sets/resets the size of each pane to the minimum limit of the pane * (this is usually zero). This routine gets called when new widgets are * added, deleted, or resized. * * Results: * None. * * Side Effects: * The size of each pane is re-initialized to its minimum size. * *--------------------------------------------------------------------------- */ static void ResetDrawers(Paneset *setPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; int extra, size; panePtr = Blt_Chain_GetValue(link); /* * The constraint procedure below also has the desired side-effect of * setting the minimum, maximum, and nominal values to the requested * size of its associated widget (if one exists). */ extra = 0; if (panePtr->side & SIDE_VERTICAL) { size = BoundHeight(0, &panePtr->reqSize); } else { size = BoundWidth(0, &panePtr->reqSize); } if (panePtr->flags & HANDLE) { extra += setPtr->handleSize; } if (panePtr->reqSize.flags & LIMITS_NOM_SET) { /* * This could be done more cleanly. We want to ensure that the * requested nominal size is not overridden when determining the * normal sizes. So temporarily fix min and max to the nominal * size and reset them back later. */ panePtr->min = panePtr->max = panePtr->size = panePtr->nom = size + extra; } else { /* The range defaults to 0..MAXINT */ panePtr->min = panePtr->reqSize.min + extra; panePtr->max = panePtr->reqSize.max + extra; panePtr->nom = LIMITS_NOM; panePtr->size = size + extra; } } } /* *--------------------------------------------------------------------------- * * ResetPanes -- * * Sets/resets the size of each pane to the minimum limit of the pane * (this is usually zero). This routine gets called when new widgets are * added, deleted, or resized. * * Results: * None. * * Side Effects: * The size of each pane is re-initialized to its minimum size. * *--------------------------------------------------------------------------- */ static void ResetPanes(Paneset *setPtr) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; int extra, size; panePtr = Blt_Chain_GetValue(link); /* * The constraint procedure below also has the desired side-effect of * setting the minimum, maximum, and nominal values to the requested * size of its associated widget (if one exists). */ if (ISVERT(setPtr)) { size = BoundHeight(0, &panePtr->reqSize); extra = PADDING(panePtr->yPad); } else { size = BoundWidth(0, &panePtr->reqSize); extra = PADDING(panePtr->xPad); } if (panePtr->flags & HANDLE) { extra += setPtr->handleSize; } if (panePtr->reqSize.flags & LIMITS_NOM_SET) { /* * This could be done more cleanly. We want to ensure that the * requested nominal size is not overridden when determining the * normal sizes. So temporarily fix min and max to the nominal * size and reset them back later. */ panePtr->min = panePtr->max = panePtr->size = panePtr->nom = size + extra; } else { /* The range defaults to 0..MAXINT */ panePtr->min = panePtr->reqSize.min + extra; panePtr->max = panePtr->reqSize.max + extra; panePtr->nom = LIMITS_NOM; panePtr->size = size + extra; } } } /* *--------------------------------------------------------------------------- * * SetNominalSizes * * Sets the normal sizes for each pane. The pane size is the requested * widget size plus an amount of padding. In addition, adjust the * min/max bounds of the pane depending upon the resize flags (whether * the pane can be expanded or shrunk from its normal size). * * Results: * Returns the total space needed for the all the panes. * * Side Effects: * The nominal size of each pane is set. This is later used to determine * how to shrink or grow the table if the container can't be resized to * accommodate the exact size requirements of all the panes. * *--------------------------------------------------------------------------- */ static int SetNominalSizes(Paneset *setPtr) { Blt_ChainLink link; int total; total = 0; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; int extra; panePtr = Blt_Chain_GetValue(link); if (ISVERT(setPtr)) { extra = PADDING(panePtr->yPad); } else { extra = PADDING(panePtr->xPad); } if (panePtr->flags & HANDLE) { extra += setPtr->handleSize; } /* * Restore the real bounds after temporarily setting nominal size. * These values may have been set in ResetPanes to restrict the size * of the pane to the requested range. */ panePtr->min = panePtr->reqSize.min + extra; panePtr->max = panePtr->reqSize.max + extra; if (panePtr->size > panePtr->max) { panePtr->size = panePtr->max; } if (panePtr->size < panePtr->min) { panePtr->size = panePtr->min; } panePtr->nom = panePtr->size; /* * If a pane can't be resized (to either expand or shrink), hold its * respective limit at its normal size. */ if ((panePtr->resize & RESIZE_EXPAND) == 0) { panePtr->max = panePtr->nom; } if ((panePtr->resize & RESIZE_SHRINK) == 0) { panePtr->min = panePtr->nom; } total += panePtr->nom; } return total; } /* *--------------------------------------------------------------------------- * * LayoutHorizontalPanes -- * * Calculates the normal space requirements for panes. * * Results: * None. * * Side Effects: * The sum of normal sizes set here will be used as the normal size for * the container widget. * *--------------------------------------------------------------------------- */ static void LayoutHorizontalPanes(Paneset *setPtr) { Blt_ChainLink link, next; int total; int maxHeight; int x, y; maxHeight = 0; ResetPanes(setPtr); for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = next) { Pane *panePtr; int width, height; next = Blt_Chain_NextLink(link); panePtr = Blt_Chain_GetValue(link); panePtr->flags &= ~HANDLE; if (panePtr->flags & HIDE) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } continue; } if ((next != NULL) || (setPtr->mode == MODE_SPREADSHEET)) { /* Add the size of the handle to the pane. */ /* width += setPtr->handleSize; */ if (panePtr->flags & SHOW_HANDLE) { panePtr->flags |= HANDLE; } } width = GetReqPaneWidth(panePtr); if (width <= 0) { /* continue; */ } height = GetReqPaneHeight(panePtr); if (maxHeight < height) { maxHeight = height; } if (width > panePtr->size) { GrowPane(panePtr, width - panePtr->size); } } x = y = 0; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); panePtr->height = maxHeight; panePtr->width = panePtr->size; panePtr->x = x; panePtr->y = y; x += panePtr->size; } total = SetNominalSizes(setPtr); setPtr->worldWidth = total; setPtr->normalWidth = total + 2 * Tk_InternalBorderWidth(setPtr->tkwin); setPtr->normalHeight = maxHeight + 2*Tk_InternalBorderWidth(setPtr->tkwin); if (setPtr->normalWidth < 1) { setPtr->normalWidth = 1; } if (setPtr->normalHeight < 1) { setPtr->normalHeight = 1; } setPtr->flags &= ~LAYOUT_PENDING; setPtr->flags |= SCROLL_PENDING; } /* *--------------------------------------------------------------------------- * * LayoutVerticalPanes -- * * Calculates the normal space requirements for panes. * * Results: * None. * * Side Effects: * The sum of normal sizes set here will be used as the normal size for * the container widget. * *--------------------------------------------------------------------------- */ static void LayoutVerticalPanes(Paneset *setPtr) { Blt_ChainLink link, next; int total; int maxWidth; int x, y; maxWidth = 0; #if TRACE fprintf(stderr, "LayoutVerticalPanes\n"); #endif ResetPanes(setPtr); for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = next) { Pane *panePtr; int width, height; next = Blt_Chain_NextLink(link); panePtr = Blt_Chain_GetValue(link); if (panePtr->flags & HIDE) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } continue; } panePtr->flags &= ~HANDLE; if ((next != NULL) || (setPtr->mode == MODE_SPREADSHEET)) { /* height += setPtr->handleSize; */ if (panePtr->flags & SHOW_HANDLE) { panePtr->flags |= HANDLE; } } height = GetReqPaneHeight(panePtr); if (height <= 0) { continue; } width = GetReqPaneWidth(panePtr); if (maxWidth < width) { maxWidth = width; } if (height > panePtr->size) { GrowPane(panePtr, height - panePtr->size); } } x = y = 0; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); panePtr->width = maxWidth; panePtr->height = panePtr->size; panePtr->x = x; panePtr->y = y; y += panePtr->size; } total = SetNominalSizes(setPtr); setPtr->worldWidth = total; setPtr->normalHeight = total + 2*Tk_InternalBorderWidth(setPtr->tkwin); setPtr->normalWidth = maxWidth + 2*Tk_InternalBorderWidth(setPtr->tkwin); if (setPtr->normalWidth < 1) { setPtr->normalWidth = 1; } if (setPtr->normalHeight < 1) { setPtr->normalHeight = 1; } setPtr->flags &= ~LAYOUT_PENDING; setPtr->flags |= SCROLL_PENDING; } /* *--------------------------------------------------------------------------- * * LayoutDrawers -- * * Calculates the normal space requirements for panes. * * Results: * None. * * Side Effects: * The sum of normal sizes set here will be used as the normal size for * the container widget. * *--------------------------------------------------------------------------- */ static void LayoutDrawers(Paneset *setPtr) { Blt_ChainLink link, next; ResetDrawers(setPtr); for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = next) { Pane *panePtr; int anchor; next = Blt_Chain_NextLink(link); panePtr = Blt_Chain_GetValue(link); if (panePtr->side & SIDE_VERTICAL) { panePtr->size = GetReqDrawerHeight(panePtr); anchor = panePtr->y; } else { panePtr->size = GetReqDrawerWidth(panePtr); anchor = panePtr->x; } if (anchor < 0) { #ifdef notdef panePtr->flags |= CLOSED; /* Auto-close */ #endif } if (panePtr->flags & SHOW_HANDLE) { panePtr->flags |= HANDLE; } else { panePtr->flags &= ~HANDLE; } if (panePtr->flags & CLOSED) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } continue; } if (panePtr->flags & VIRGIN) { #ifdef notdef panePtr->x = panePtr->y = 0; if (panePtr->side & SIDE_VERTICAL) { panePtr->y = panePtr->size = GetReqDrawerHeight(panePtr); } else { panePtr->x = panePtr->size = GetReqDrawerWidth(panePtr); } #endif } if ((panePtr->resize & RESIZE_EXPAND) == 0) { panePtr->max = panePtr->size; } if ((panePtr->resize & RESIZE_SHRINK) == 0) { panePtr->min = panePtr->size; } } } static void ArrangeWindow(Pane *panePtr, int x, int y) { Paneset *setPtr; int cavityWidth, cavityHeight; setPtr = panePtr->setPtr; if (ISVERT(setPtr)) { panePtr->height = panePtr->size; panePtr->width = Tk_Width(setPtr->tkwin); } else { panePtr->width = panePtr->size; panePtr->height = Tk_Height(setPtr->tkwin); } cavityWidth = panePtr->width; cavityHeight = panePtr->height; if (panePtr->tkwin != NULL) { int w, h; int xMax, yMax; int dx, dy; xMax = x + panePtr->width; yMax = y + panePtr->height; x += Tk_Changes(panePtr->tkwin)->border_width; y += Tk_Changes(panePtr->tkwin)->border_width; if (panePtr->flags & HANDLE) { if (ISVERT(setPtr)) { cavityHeight -= setPtr->handleSize; if (panePtr->side & HANDLE_FARSIDE) { yMax -= setPtr->handleSize; } else { y += setPtr->handleSize; } } else { cavityWidth -= setPtr->handleSize; if (panePtr->side & HANDLE_FARSIDE) { xMax -= setPtr->handleSize; } else { x += setPtr->handleSize; } } } /* * Unmap any widgets that start beyond of the right edge of the * container. */ if ((x >= xMax) || (y >= yMax)) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } return; } w = GetReqWidth(panePtr); h = GetReqHeight(panePtr); /* * * Compare the widget's requested size to the size of the cavity. * * 1) If the widget is larger than the cavity or if the fill flag is * set, make the widget the size of the cavity. Check that the new size * is within the bounds set for the widget. * * 2) Otherwise, position the widget in the space according to its * anchor. * */ if ((cavityWidth <= w) || (panePtr->fill & FILL_X)) { w = cavityWidth; } if (w > panePtr->reqWidth.max) { w = panePtr->reqWidth.max; } if ((cavityHeight <= h) || (panePtr->fill & FILL_Y)) { h = cavityHeight; } if (h > panePtr->reqHeight.max) { h = panePtr->reqHeight.max; } /* * Clip the widget at the bottom and/or right edge of the container. */ if (h > (yMax - y)) { h = (yMax - y); } if (w > (xMax - x)) { w = (xMax - x); } dx = dy = 0; if (cavityWidth > w) { dx = (cavityWidth - w); } if (cavityHeight > h) { dy = (cavityHeight - h); } #ifdef notdef if ((dx > 0) || (dy > 0)) { TranslateAnchor(dx, dy, panePtr->anchor, &x, &y); } TranslateAnchor(w, h, panePtr->anchor, &x, &y); fprintf(stderr, "pane=%s x=%d,y=%d, w=%d h=%d\n", panePtr->name, x, y, w, h); #endif /* * If the widget is too small (i.e. it has only an external border) * then unmap it. */ if ((w < 1) || (h < 1)) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } return; } /* * Resize and/or move the widget as necessary. */ if ((x != Tk_X(panePtr->tkwin)) || (y != Tk_Y(panePtr->tkwin)) || (w != Tk_Width(panePtr->tkwin)) || (h != Tk_Height(panePtr->tkwin))) { Tk_MoveResizeWindow(panePtr->tkwin, x, y, w, h); } if (!Tk_IsMapped(panePtr->tkwin)) { Tk_MapWindow(panePtr->tkwin); } } } static void ArrangeHandle(Pane *panePtr, int x, int y) { Paneset *setPtr; setPtr = panePtr->setPtr; if (panePtr->flags & HANDLE) { int w, h; if (ISVERT(setPtr)) { x = 0; if (panePtr->side & HANDLE_FARSIDE) { y += panePtr->size - setPtr->handleSize; } w = Tk_Width(setPtr->tkwin); h = setPtr->handleSize; } else { y = 0; if (panePtr->side & HANDLE_FARSIDE) { x += panePtr->size - setPtr->handleSize; } h = Tk_Height(setPtr->tkwin); w = setPtr->handleSize; } if ((x != Tk_X(panePtr->tkwin)) || (y != Tk_Y(panePtr->tkwin)) || (w != Tk_Width(panePtr->tkwin)) || (h != Tk_Height(panePtr->tkwin))) { Tk_MoveResizeWindow(panePtr->handle, x, y, w, h); } if (!Tk_IsMapped(panePtr->handle)) { Tk_MapWindow(panePtr->handle); } XRaiseWindow(setPtr->display, Tk_WindowId(panePtr->handle)); } else if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } } static void ArrangeDrawer(Pane *panePtr) { Paneset *setPtr; int cavityWidth, cavityHeight; int x0, y0; int x, y; int w, h; int anchor; if ((panePtr->flags & CLOSED) || (panePtr->tkwin == NULL)) { if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } return; } setPtr = panePtr->setPtr; x0 = ScreenX(panePtr); y0 = ScreenY(panePtr); if (panePtr->side & SIDE_VERTICAL) { if (panePtr->y > Tk_Height(setPtr->tkwin)) { panePtr->y = Tk_Height(setPtr->tkwin); } cavityHeight = panePtr->y; cavityWidth = Tk_Width(setPtr->tkwin); panePtr->height = panePtr->size; panePtr->width = GetReqDrawerWidth(panePtr); } else { if (panePtr->x > Tk_Width(setPtr->tkwin)) { panePtr->x = Tk_Width(setPtr->tkwin); } cavityWidth = panePtr->x; cavityHeight = Tk_Height(setPtr->tkwin); panePtr->width = panePtr->size; panePtr->height = GetReqDrawerHeight(panePtr); } x = ScreenX(panePtr) + Tk_Changes(panePtr->tkwin)->border_width; y = ScreenY(panePtr) + Tk_Changes(panePtr->tkwin)->border_width; w = GetReqDrawerWidth(panePtr); h = GetReqDrawerHeight(panePtr); /* * * Compare the widget's requested size to the size of the cavity. * * 1) If the widget is larger than the cavity or if the fill flag is * set, make the widget the size of the cavity. Check that the new size * is within the bounds set for the widget. * * 2) Otherwise, position the widget in the space according to its * anchor. * */ anchor = (panePtr->side & SIDE_VERTICAL) ? panePtr->y : panePtr->x; if (panePtr->side & SIDE_VERTICAL) { if (cavityHeight > h) { h = cavityHeight; /* Automatically grow the window. */ } if ((cavityHeight < h) && (panePtr->flags & SHRINK)) { h = cavityHeight; } if (h > panePtr->reqHeight.max) { h = panePtr->reqHeight.max; } panePtr->size = h; if ((cavityWidth < w) || (panePtr->fill)) { w = cavityWidth; if (w > panePtr->reqWidth.max) { w = panePtr->reqWidth.max; } } } else { if (cavityWidth > w) { w = cavityWidth; /* Automatically grow the window. */ } if ((cavityWidth < w) && (panePtr->flags & SHRINK)) { w = cavityWidth; /* Allow window to be shrunk. */ } if (w > panePtr->reqWidth.max) { w = panePtr->reqWidth.max; } panePtr->size = w; if ((cavityHeight < h) || (panePtr->fill)) { h = cavityHeight; if (h > panePtr->reqHeight.max) { h = panePtr->reqHeight.max; } } } x = ScreenX(panePtr) + Tk_Changes(panePtr->tkwin)->border_width; y = ScreenY(panePtr) + Tk_Changes(panePtr->tkwin)->border_width; if ((panePtr->side & SIDE_VERTICAL) && (cavityWidth > w)) { x += (cavityWidth - w) / 2; } if ((panePtr->side & SIDE_HORIZONTAL) && (cavityHeight > h)) { y += (cavityHeight - h) / 2; } if (panePtr->flags & HANDLE) { /* Make room for the handle if one if needed. Adjust the window's * position if the handle is on the near side. */ if (panePtr->side & SIDE_VERTICAL) { h -= setPtr->handleSize; if (panePtr->side & HANDLE_NEARSIDE) { y += setPtr->handleSize; } } else { w -= setPtr->handleSize; if (panePtr->side & HANDLE_NEARSIDE) { x += setPtr->handleSize; } } } /* * If the widget is too small (i.e. it has only an external border) * then unmap it. */ if (anchor < 0) { CloseDrawer(panePtr); } if ((w < 1) || (h < 1)) { if (Tk_IsMapped(panePtr->tkwin)) { Tk_UnmapWindow(panePtr->tkwin); } } else { /* * Resize and/or move the widget as necessary. */ if ((x != Tk_X(panePtr->tkwin)) || (y != Tk_Y(panePtr->tkwin)) || (w != Tk_Width(panePtr->tkwin)) || (h != Tk_Height(panePtr->tkwin))) { Tk_MoveResizeWindow(panePtr->tkwin, x, y, w, h); } if (!Tk_IsMapped(panePtr->tkwin)) { Tk_MapWindow(panePtr->tkwin); } XRaiseWindow(setPtr->display, Tk_WindowId(panePtr->tkwin)); panePtr->flags &= ~VIRGIN; } if (panePtr->flags & HANDLE) { if (panePtr->side & SIDE_VERTICAL) { if (panePtr->side & HANDLE_FARSIDE) { y += h; } else { y -= setPtr->handleSize; } h = setPtr->handleSize; } else { if (panePtr->side & HANDLE_FARSIDE) { x += w; } else { x -= setPtr->handleSize; } w = setPtr->handleSize; } if ((x != Tk_X(panePtr->tkwin)) || (y != Tk_Y(panePtr->tkwin)) || (w != Tk_Width(panePtr->tkwin)) || (h != Tk_Height(panePtr->tkwin))) { Tk_MoveResizeWindow(panePtr->handle, x, y, w, h); } if (!Tk_IsMapped(panePtr->handle)) { Tk_MapWindow(panePtr->handle); } XRaiseWindow(setPtr->display, Tk_WindowId(panePtr->handle)); } else if (Tk_IsMapped(panePtr->handle)) { Tk_UnmapWindow(panePtr->handle); } } /* *--------------------------------------------------------------------------- * * ArrangePane * * Places each window at its proper location. First determines the size * and position of the each window. It then considers the following: * * 1. translation of widget position its parent widget. * 2. fill style * 3. anchor * 4. external and internal padding * 5. widget size must be greater than zero * * Results: * None. * * Side Effects: * The size of each pane is re-initialized its minimum size. * *--------------------------------------------------------------------------- */ static void ArrangePane(Pane *panePtr, int x, int y) { Paneset *setPtr; setPtr = panePtr->setPtr; if (ISVERT(setPtr)) { panePtr->height = panePtr->size; panePtr->width = Tk_Width(setPtr->tkwin); } else { panePtr->width = panePtr->size; panePtr->height = Tk_Height(setPtr->tkwin); } ArrangeWindow(panePtr, x, y); ArrangeHandle(panePtr, x, y); } /* *--------------------------------------------------------------------------- * * VerticalPanes -- * * * Results: * None. * * Side Effects: * The widgets in the paneset are possibly resized and redrawn. * *--------------------------------------------------------------------------- */ static void VerticalPanes(Paneset *setPtr) { int height; int top, bottom; int y; int xPad, yPad; Pane *panePtr; /* * If the paneset has no children anymore, then don't do anything at all: * just leave the container widget's size as-is. */ #if TRACE fprintf(stderr, "VerticalPanes\n"); #endif panePtr = LastPane(setPtr); if (panePtr == NULL) { fprintf(stderr, "VPanes: last pane is null\n"); return; } if (setPtr->anchorPtr == NULL) { setPtr->anchorPtr = panePtr; } if (setPtr->anchorPtr == panePtr) { setPtr->bearing = Tk_Height(setPtr->tkwin); #if TRACE fprintf(stderr, "VerticalPanes: bearing = %d\n", setPtr->bearing); #endif } if (setPtr->flags & LAYOUT_PENDING) { fprintf(stderr, "layout v panes\n"); LayoutVerticalPanes(setPtr); } /* * Save the width and height of the container so we know when its size has * changed during ConfigureNotify events. */ xPad = yPad = 2 * Tk_InternalBorderWidth(setPtr->tkwin); top = LeftSpan(setPtr); bottom = RightSpan(setPtr); setPtr->worldWidth = height = top + bottom; /* * If the previous geometry request was not fulfilled (i.e. the size of * the container is different from paneset space requirements), try to * adjust size of the panes to fit the widget. */ if (setPtr->type == PANESET) { Pane *firstPtr, *lastPtr; Blt_Chain span; int dy; dy = setPtr->bearing - top; firstPtr = FirstPane(setPtr); lastPtr = NextPane(setPtr->anchorPtr); if (firstPtr != lastPtr) { span = SortedSpan(setPtr, firstPtr, lastPtr); if (dy > 0) { GrowSpan(span, dy); } else if (dy < 0) { ShrinkSpan(span, dy); } top = LeftSpan(setPtr) + yPad; Blt_Chain_Destroy(span); } dy = (Tk_Height(setPtr->tkwin) - setPtr->bearing) - bottom; span = SortedSpan(setPtr, lastPtr, NULL); if (dy > 0) { GrowSpan(span, dy); } else if (dy < 0) { ShrinkSpan(span, dy); } Blt_Chain_Destroy(span); bottom = RightSpan(setPtr) + yPad; setPtr->worldWidth = height = top + bottom; } /* * If after adjusting the size of the panes the space required does not * equal the size of the widget, do one of the following: * * 1) If it's smaller, center the paneset in the widget. * 2) If it's bigger, clip the panes that extend beyond the edge of the * container. * * Set the row and column offsets (including the container's internal * border width). To be used later when positioning the widgets. */ #ifdef notdef if (height < setPtr->containerHeight) { y += (setPtr->containerHeight - height) / 2; } #endif y = 0; for (panePtr = FirstPane(setPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { panePtr->y = y; ArrangePane(panePtr, 0, SCREEN(y)); y += panePtr->size; } } /* *--------------------------------------------------------------------------- * * HorizontalPanes -- * * * Results: * None. * * Side Effects: * The widgets in the paneset are possibly resized and redrawn. * *--------------------------------------------------------------------------- */ static void HorizontalPanes(Paneset *setPtr) { int width; int left, right; int x; int xPad, yPad; Pane *panePtr; /* * If the paneset has no children anymore, then don't do anything at all: * just leave the container widget's size as-is. */ panePtr = LastPane(setPtr); if (panePtr == NULL) { fprintf(stderr, "HPanes: first pane is null\n"); return; } if (setPtr->anchorPtr == NULL) { setPtr->anchorPtr = panePtr; } if (setPtr->anchorPtr == panePtr) { setPtr->bearing = Tk_Width(setPtr->tkwin); #if TRACE fprintf(stderr, "HorizontalPanes: bearing = %d\n", setPtr->bearing); #endif } if (setPtr->flags & LAYOUT_PENDING) { fprintf(stderr, "layout h panes\n"); LayoutHorizontalPanes(setPtr); } /* * Save the width and height of the container so we know when its size has * changed during ConfigureNotify events. */ xPad = yPad = 2 * Tk_InternalBorderWidth(setPtr->tkwin); left = LeftSpan(setPtr); right = RightSpan(setPtr); setPtr->worldWidth = width = left + right; /* * If the previous geometry request was not fulfilled (i.e. the size of * the paneset is different from the total panes space requirements), try * to adjust size of the panes to fit the widget. */ if (setPtr->type == PANESET) { Pane *firstPtr, *lastPtr; Blt_Chain span; int dx; dx = setPtr->bearing - left; firstPtr = FirstPane(setPtr); lastPtr = NextPane(setPtr->anchorPtr); if (firstPtr != lastPtr) { span = SortedSpan(setPtr, firstPtr, lastPtr); if (dx > 0) { GrowSpan(span, dx); } else if (dx < 0) { ShrinkSpan(span, dx); } left = LeftSpan(setPtr) + xPad; Blt_Chain_Destroy(span); } dx = (Tk_Width(setPtr->tkwin) - setPtr->bearing) - right; span = SortedSpan(setPtr, lastPtr, NULL); if (dx > 0) { GrowSpan(span, dx); } else if (dx < 0) { ShrinkSpan(span, dx); } Blt_Chain_Destroy(span); right = RightSpan(setPtr) + xPad; setPtr->worldWidth = width = left + right; } /* * If after adjusting the size of the panes the space required does not * equal the size of the widget, do one of the following: * * 1) If it's smaller, center the paneset in the widget. * 2) If it's bigger, clip the panes that extend beyond the edge of the * container. * * Set the row and column offsets (including the container's internal * border width). To be used later when positioning the widgets. */ x = 0; for (panePtr = FirstPane(setPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { panePtr->x = x; ArrangePane(panePtr, SCREEN(x), 0); x += panePtr->size; } } /* *--------------------------------------------------------------------------- * * OpenDrawers -- * * * Results: * None. * * Side Effects: * The widgets in the paneset are possibly resized and redrawn. * *--------------------------------------------------------------------------- */ static void ArrangeDrawers(Paneset *setPtr) { Blt_ChainLink link, next; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = next) { Pane *panePtr; next = Blt_Chain_NextLink(link); panePtr = Blt_Chain_GetValue(link); ArrangeDrawer(panePtr); } } static void ComputeGeometry(Paneset *setPtr) { if (setPtr->type == DRAWER) { setPtr->normalWidth = setPtr->normalHeight = 0; if (setPtr->tkwin != NULL) { setPtr->normalWidth = Tk_ReqWidth(setPtr->tkwin) + 2 * Tk_InternalBorderWidth(setPtr->tkwin); setPtr->normalHeight = Tk_ReqHeight(setPtr->tkwin) + 2 * Tk_InternalBorderWidth(setPtr->tkwin); } if (setPtr->normalWidth < 1) { setPtr->normalWidth = 1; } if (setPtr->normalHeight < 1) { setPtr->normalHeight = 1; } LayoutDrawers(setPtr); } else { if (ISVERT(setPtr)) { LayoutVerticalPanes(setPtr); } else { LayoutHorizontalPanes(setPtr); } } setPtr->flags &= ~LAYOUT_PENDING; } static void ConfigurePaneset(Paneset *setPtr) { setPtr->handleSize = MAX(PADDING(setPtr->handlePad),setPtr->highlightThickness) + setPtr->handleThickness; } /* *--------------------------------------------------------------------------- * * AddOp -- * * Appends a pane into the widget. * * Results: * Returns a standard TCL result. The index of the pane is left in * interp->result. * * .p add ?name? ?option value...? * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AddOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; const char *name; name = NULL; if (objc > 2) { const char *string; string = Tcl_GetString(objv[2]); if (string[0] != '-') { if (GetPaneFromObj(NULL, setPtr, objv[2], &panePtr) == TCL_OK) { Tcl_AppendResult(interp, "pane \"", string, "\" already exists", (char *)NULL); return TCL_ERROR; } name = string; objc--, objv++; } } panePtr = NewPane(interp, setPtr, name); if (panePtr == NULL) { return TCL_ERROR; } if (Blt_ConfigureWidgetFromObj(interp, panePtr->handle, paneSpecs, objc - 2, objv + 2, (char *)panePtr, setPtr->type) != TCL_OK) { return TCL_ERROR; } panePtr->link = Blt_Chain_Append(setPtr->chain, panePtr); RenumberPanes(setPtr); EventuallyRedraw(setPtr); Tcl_SetIntObj(Tcl_GetObjResult(interp), panePtr->index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CgetOp -- * * Returns the name, position and options of a widget in the paneset. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * * .p cget option * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CgetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, panesetSpecs, (char *)setPtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * CloseOp -- * * Opens the specified pane. * * Results: * Returns a standard TCL result. * * .p open pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int CloseOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; PaneIterator iter; Paneset *setPtr = clientData; if (GetPaneIterator(interp, setPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { EventuallyCloseDrawer(panePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ConfigureOp -- * * Returns the name, position and options of a widget in the paneset. * * Results: * Returns a standard TCL result. A list of the paneset configuration * option information is left in interp->result. * * .p configure option value *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, panesetSpecs, (char *)setPtr, (Tcl_Obj *)NULL, setPtr->type); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, setPtr->tkwin, panesetSpecs, (char *)setPtr, objv[2], setPtr->type); } if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, panesetSpecs, objc - 2, objv + 2, (char *)setPtr, BLT_CONFIG_OBJV_ONLY|setPtr->type) != TCL_OK) { return TCL_ERROR; } ConfigurePaneset(setPtr); /* Arrange for the paneset layout to be computed at the next idle point. */ setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DeleteOp -- * * Deletes the specified panes from the widget. Note that the pane * indices can be fixed only after all the deletions have occurred. * * .p delete widget * * Results: * Returns a standard TCL result. * * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int DeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; PaneIterator iter; Pane *panePtr; if (GetPaneIterator(interp, setPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { Tcl_EventuallyFree(panePtr, PaneFreeProc); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Indicates if drawer is open or closed. * * Results: * Returns a standard TCL result. * * widget index pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExistsOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; int state; state = FALSE; if (GetPaneFromObj(NULL, setPtr, objv[2], &panePtr) == TCL_OK) { if (panePtr != NULL) { state = TRUE; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), state); return TCL_OK; } /* *--------------------------------------------------------------------------- * * IndexOp -- * * Indicates if drawer is open or closed. * * Results: * Returns a standard TCL result. * * widget index pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IndexOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; int index; index = -1; if (GetPaneFromObj(NULL, setPtr, objv[2], &panePtr) == TCL_OK) { if (panePtr != NULL) { index = panePtr->index; } } Tcl_SetIntObj(Tcl_GetObjResult(interp), index); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InsertOp -- * * Add new entries into a pane set. * * .t insert position ?label? option-value label option-value... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InsertOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; Blt_ChainLink link, before; char c; const char *string; const char *name; string = Tcl_GetString(objv[2]); c = string[0]; if ((c == 'e') && (strcmp(string, "end") == 0)) { before = NULL; } else if (isdigit(UCHAR(c))) { int pos; if (Tcl_GetIntFromObj(interp, objv[2], &pos) != TCL_OK) { return TCL_ERROR; } if (pos < 0) { before = Blt_Chain_FirstLink(setPtr->chain); } else if (pos > Blt_Chain_GetLength(setPtr->chain)) { before = NULL; } else { before = Blt_Chain_GetNthLink(setPtr->chain, pos); } } else { Pane *beforePtr; if (GetPaneFromObj(interp, setPtr, objv[2], &beforePtr) != TCL_OK) { return TCL_ERROR; } if (beforePtr == NULL) { Tcl_AppendResult(interp, "can't find a pane \"", Tcl_GetString(objv[2]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } before = beforePtr->link; } name = NULL; if (objc > 3) { string = Tcl_GetString(objv[3]); if (name[0] != '-') { name = string; objc--, objv++; } } panePtr = NewPane(interp, setPtr, name); if (panePtr == NULL) { return TCL_ERROR; } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); if (Blt_ConfigureWidgetFromObj(interp, panePtr->handle, paneSpecs, objc - 3, objv + 3, (char *)panePtr, setPtr->type) != TCL_OK) { DestroyPane(panePtr); return TCL_ERROR; } link = Blt_Chain_NewLink(); if (before != NULL) { Blt_Chain_LinkBefore(setPtr->chain, link, before); } else { Blt_Chain_AppendLink(setPtr->chain, link); } panePtr->link = link; Blt_Chain_SetValue(link, panePtr); RenumberPanes(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), panePtr->name, -1); return TCL_OK; } /* *--------------------------------------------------------------------------- * * InvokeOp -- * * This procedure is called to invoke a selection command. * * .ps invoke pane * * Results: * A standard TCL result. If TCL_ERROR is returned, then interp->result * contains an error message. * * Side Effects: * Configuration information, such as text string, colors, font, etc. get * set; old resources get freed, if there were any. The widget is * redisplayed if needed. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int InvokeOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; Tcl_Obj *cmdObjPtr; if (GetPaneFromObj(interp, setPtr, objv[2], &panePtr) != TCL_OK) { return TCL_ERROR; } if ((panePtr == NULL) || (panePtr->flags & (DISABLED|HIDE))) { return TCL_OK; } cmdObjPtr = GETATTR(panePtr, cmdObjPtr); if (cmdObjPtr != NULL) { Tcl_Obj **args; Tcl_Obj **cmdv; int cmdc; int i; int result; if (Tcl_ListObjGetElements(interp, cmdObjPtr, &cmdc, &cmdv) != TCL_OK) { return TCL_ERROR; } args = Blt_AssertMalloc(sizeof(Tcl_Obj *) * (cmdc + 1)); for (i = 0; i < cmdc; i++) { args[i] = cmdv[i]; } args[i] = Tcl_NewIntObj(panePtr->index); result = Blt_GlobalEvalObjv(interp, cmdc + 1, args); Blt_Free(args); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * IsOpenOp -- * * Indicates if drawer is open or closed. * * Results: * Returns a standard TCL result. * * widget isopen pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int IsOpenOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; int state; if (GetPaneFromObj(interp, setPtr, objv[2], &panePtr) != TCL_OK) { return TCL_ERROR; } state = FALSE; if (panePtr != NULL) { state = (panePtr->flags & CLOSED) ? 0 : 1; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), state); return TCL_OK; } /* *--------------------------------------------------------------------------- * * MoveOp -- * * Moves a pane to a new location. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int MoveOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr, *fromPtr; char c; const char *string; int isBefore; int length; if (GetPaneFromObj(interp, setPtr, objv[2], &panePtr) != TCL_OK) { return TCL_ERROR; } if ((panePtr == NULL) || (panePtr->flags & DISABLED)) { return TCL_OK; } string = Tcl_GetStringFromObj(objv[3], &length); c = string[0]; if ((c == 'b') && (strncmp(string, "before", length) == 0)) { isBefore = TRUE; } else if ((c == 'a') && (strncmp(string, "after", length) == 0)) { isBefore = FALSE; } else { Tcl_AppendResult(interp, "bad key word \"", string, "\": should be \"after\" or \"before\"", (char *)NULL); return TCL_ERROR; } if (GetPaneFromObj(interp, setPtr, objv[4], &fromPtr) != TCL_OK) { return TCL_ERROR; } if (fromPtr == NULL) { Tcl_AppendResult(interp, "can't find a pane \"", Tcl_GetString(objv[4]), "\" in \"", Tk_PathName(setPtr->tkwin), "\"", (char *)NULL); return TCL_ERROR; } if (panePtr == fromPtr) { return TCL_OK; } Blt_Chain_UnlinkLink(setPtr->chain, panePtr->link); if (isBefore) { Blt_Chain_LinkBefore(setPtr->chain, panePtr->link, fromPtr->link); } else { Blt_Chain_LinkAfter(setPtr->chain, panePtr->link, fromPtr->link); } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * NamesOp -- * * .ps names pattern * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int NamesOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (objc == 2) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; panePtr = Blt_Chain_GetValue(link); Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(panePtr->name, -1)); } } else { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(setPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Pane *panePtr; int i; panePtr = Blt_Chain_GetValue(link); for (i = 2; i < objc; i++) { if (Tcl_StringMatch(panePtr->name, Tcl_GetString(objv[i]))) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(panePtr->name, -1)); break; } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * OpenOp -- * * Opens the specified pane. * * Results: * Returns a standard TCL result. * * .p open pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int OpenOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { EventuallyOpenDrawer(panePtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * RaiseOp -- * * Raises the specified pane to the top of the stack of panes. * * Results: * Returns a standard TCL result. * * .p raise pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int RaiseOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { RaiseDrawer(panePtr); } EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * LowerOp -- * * Lowers the specified pane to bottom of the stack of panes. * * Results: * Returns a standard TCL result. * * .p raise pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int LowerOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[2], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { LowerDrawer(panePtr); } EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PaneCgetOp -- * * Returns the name, position and options of a widget in the paneset. * * Results: * Returns a standard TCL result. A list of the widget attributes is * left in interp->result. * * .p pane cget pane option *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PaneCgetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; if (GetPaneFromObj(interp, setPtr, objv[3], &panePtr) != TCL_OK) { return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, paneSpecs, (char *)panePtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * PaneConfigureOp -- * * Returns the name, position and options of a widget in the paneset. * * Results: * Returns a standard TCL result. A list of the paneset configuration * option information is left in interp->result. * * .p pane configure pane option value *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int PaneConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; if (GetPaneFromObj(interp, setPtr, objv[3], &panePtr) != TCL_OK) { return TCL_ERROR; } if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, panePtr->handle, paneSpecs, (char *)panePtr, (Tcl_Obj *)NULL, setPtr->type); } else if (objc == 5) { return Blt_ConfigureInfoFromObj(interp, panePtr->handle, paneSpecs, (char *)panePtr, objv[4], setPtr->type); } if (Blt_ConfigureWidgetFromObj(interp, panePtr->handle, paneSpecs, objc-4, objv+4, (char *)panePtr, BLT_CONFIG_OBJV_ONLY|setPtr->type) != TCL_OK) { return TCL_ERROR; } setPtr->anchorPtr = NULL; setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } static Blt_OpSpec paneOps[] = { {"cget", 2, PaneCgetOp, 5, 5, "pane option",}, {"configure", 2, PaneConfigureOp, 4, 0, "pane ?option value?",}, }; static int nPaneOps = sizeof(paneOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * PaneOp -- * * This procedure is invoked to process the TCL command that corresponds * to the paneset geometry manager. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int PaneOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_ObjCmdProc *proc; proc = Blt_GetOpFromObj(interp, nPaneOps, paneOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc)(clientData, interp, objc, objv); } /*ARGSUSED*/ static int SizeOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; int size; if (GetPaneFromObj(interp, setPtr, objv[3], &panePtr) != TCL_OK) { return TCL_ERROR; } if (objc == 3) { size = panePtr->size; } else { int newSize; Paneset *setPtr; setPtr = panePtr->setPtr; if (Blt_GetPixelsFromObj(interp, setPtr->tkwin, objv[3], PIXELS_NNEG, &newSize) != TCL_OK) { return TCL_ERROR; } panePtr->size = newSize; if (panePtr->side & SIDE_VERTICAL) { panePtr->y = newSize; } else { panePtr->x = newSize; } EventuallyRedraw(setPtr); } Tcl_SetIntObj(Tcl_GetObjResult(interp), size); return TCL_OK; } /* *--------------------------------------------------------------------------- * * CloseOp -- * * Opens the specified pane. * * Results: * Returns a standard TCL result. * * .p open pane * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ToggleOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr = clientData; Pane *panePtr; if (GetPaneFromObj(interp, setPtr, objv[2], &panePtr) != TCL_OK) { return TCL_ERROR; } if ((panePtr->tkwin == NULL) || (panePtr->flags & DISABLED)) { return TCL_OK; } if (panePtr->flags & CLOSED) { EventuallyOpenDrawer(panePtr); } else { EventuallyCloseDrawer(panePtr); } return TCL_OK; } static int AdjustDrawerDelta(Paneset *setPtr, int delta) { int oldBearing; int total, min, max, size; Pane *panePtr; total = min = max = 0; /* The left span is every pane before and including) the anchor pane. */ panePtr = setPtr->anchorPtr; size = (panePtr->side & SIDE_VERTICAL) ? Tk_Height(setPtr->tkwin) : Tk_Width(setPtr->tkwin); switch (panePtr->side) { case SIDE_BOTTOM: case SIDE_RIGHT: max = MIN(panePtr->max, size); min = size + panePtr->size - max; max = size + panePtr->size - panePtr->min; break; case SIDE_TOP: case SIDE_LEFT: min = panePtr->min; max = MIN(panePtr->max, size); break; } oldBearing = setPtr->bearing; setPtr->bearing += delta; if (setPtr->bearing < min) { setPtr->bearing = min; } else if (setPtr->bearing > max) { setPtr->bearing = max; } return setPtr->bearing - oldBearing; } static int AdjustPanesetDelta(Paneset *setPtr, int delta) { int total; int lmin, lmax, rmin, rmax; int oldBearing; Pane *panePtr; total = (ISVERT(setPtr)) ? Tk_Height(setPtr->tkwin) : Tk_Width(setPtr->tkwin); LeftSpanLimits(setPtr, &lmin, &lmax); RightSpanLimits(setPtr, &rmin, &rmax); rmin = total - rmin; rmax = total - rmax; oldBearing = setPtr->bearing; setPtr->bearing += delta; if (setPtr->bearing < lmin) { setPtr->bearing = lmin; } else if (setPtr->bearing > lmax) { setPtr->bearing = lmax; } if (setPtr->bearing >= rmin) { setPtr->bearing = rmin; } else if (setPtr->bearing < rmax) { setPtr->bearing = rmax; } for (panePtr = FirstPane(setPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { panePtr->nom = panePtr->size; } return setPtr->bearing - oldBearing; } static void AdjustHandle(Paneset *setPtr, int delta) { Pane *panePtr; if (setPtr->type != FILMSTRIP) { if (setPtr->type == DRAWER) { delta = AdjustDrawerDelta(setPtr, delta); } else { delta = AdjustPanesetDelta(setPtr, delta); } for (panePtr = FirstPane(setPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { panePtr->nom = panePtr->size; } } if (setPtr->type == DRAWER) { switch (setPtr->anchorPtr->side) { case SIDE_TOP: setPtr->anchorPtr->y += delta; break; case SIDE_BOTTOM: setPtr->anchorPtr->y -= delta; break; case SIDE_LEFT: setPtr->anchorPtr->x += delta; break; case SIDE_RIGHT: setPtr->anchorPtr->x -= delta; break; } } else if (setPtr->type == FILMSTRIP) { setPtr->scrollOffset -= delta; setPtr->flags |= SCROLL_PENDING; } else { switch (setPtr->mode) { case MODE_GIVETAKE: { Pane *leftPtr, *rightPtr; leftPtr = setPtr->anchorPtr; rightPtr = NextPane(leftPtr); if (delta > 0) { GrowLeftShrinkRight(setPtr, leftPtr, rightPtr, delta); } else if (delta < 0) { ShrinkLeftGrowRight(setPtr, leftPtr, rightPtr, -delta); } } break; case MODE_SPREADSHEET: { Pane *leftPtr, *rightPtr; leftPtr = setPtr->anchorPtr; rightPtr = NextPane(leftPtr); if (delta > 0) { GrowLeftShrinkLast(setPtr, leftPtr, rightPtr, delta); } else if (delta < 0) { ShrinkLeftGrowLast(setPtr, leftPtr, rightPtr, -delta); } } break; case MODE_SLINKY: break; } for (panePtr = FirstPane(setPtr); panePtr != NULL; panePtr = NextPane(panePtr)) { panePtr->nom = panePtr->size; } } EventuallyRedraw(setPtr); } /* *--------------------------------------------------------------------------- * * MotionTimerProc -- * *--------------------------------------------------------------------------- */ static void MotionTimerProc(ClientData clientData) { Paneset *setPtr = clientData; if (setPtr->scrollTarget > setPtr->scrollOffset) { setPtr->scrollOffset += setPtr->scrollIncr; if (setPtr->scrollOffset > setPtr->scrollTarget) { setPtr->scrollOffset = setPtr->scrollTarget; } } else if (setPtr->scrollTarget < setPtr->scrollOffset) { setPtr->scrollOffset -= setPtr->scrollIncr; if (setPtr->scrollOffset < setPtr->scrollTarget) { setPtr->scrollOffset = setPtr->scrollTarget; } } setPtr->scrollIncr += setPtr->scrollIncr; if (setPtr->scrollTarget == setPtr->scrollOffset) { if (setPtr->timerToken != (Tcl_TimerToken)0) { Tcl_DeleteTimerHandler(setPtr->timerToken); setPtr->timerToken = 0; setPtr->scrollIncr = setPtr->scrollUnits; } } else { setPtr->timerToken = Tcl_CreateTimerHandler(setPtr->interval, MotionTimerProc, setPtr); } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); } /*ARGSUSED*/ static int SeeOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; int left, right, width, margin; if (GetPaneFromObj(interp, setPtr, objv[2], &panePtr) != TCL_OK) { return TCL_ERROR; } if ((panePtr == NULL) || (panePtr->flags & (HIDE|DISABLED))) { return TCL_OK; } width = VPORTWIDTH(setPtr); left = setPtr->scrollOffset; right = setPtr->scrollOffset + width; margin = 20; /* If the pane is partially obscured, scroll so that it's entirely in * view. */ if (panePtr->x < left) { setPtr->scrollTarget = panePtr->x - (width - panePtr->size)/2; if ((panePtr->size + margin) < width) { setPtr->scrollTarget -= margin; } } else if ((panePtr->x + panePtr->size) >= right) { setPtr->scrollTarget = panePtr->x - (width - panePtr->size)/2; if ((panePtr->size + margin) < width) { setPtr->scrollTarget += margin; } } if (setPtr->flags & ANIMATE) { setPtr->scrollIncr = setPtr->scrollUnits; setPtr->timerToken = Tcl_CreateTimerHandler(setPtr->interval, MotionTimerProc, setPtr); } else { setPtr->scrollOffset = setPtr->scrollTarget; } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagAddOp -- * * .t tag add tagName pane1 pane2 pane2 pane4 * *--------------------------------------------------------------------------- */ static int TagAddOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *tag; long paneId; tag = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &paneId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't add reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } if (objc == 4) { /* No nodes specified. Just add the tag. */ AddTag(setPtr, NULL, tag); } else { int i; for (i = 4; i < objc; i++) { Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { AddTag(setPtr, panePtr, tag); } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagDeleteOp -- * * .t delete tagName pane1 pane2 pane3 * *--------------------------------------------------------------------------- */ static int TagDeleteOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { const char *tag; Blt_HashTable *tablePtr; long paneId; tag = Tcl_GetString(objv[3]); if (Tcl_GetLongFromObj(NULL, objv[3], &paneId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't delete reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } tablePtr = GetTagTable(setPtr, tag); if (tablePtr != NULL) { int i; for (i = 4; i < objc; i++) { Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[i], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(tablePtr, (char *)panePtr); if (hPtr != NULL) { Blt_DeleteHashEntry(tablePtr, hPtr); } } } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagExistsOp -- * * Returns the existence of the one or more tags in the given node. If * the node has any the tags, true is return in the interpreter. * * .t tag exists pane tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagExistsOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { const char *tag; Pane *panePtr; tag = Tcl_GetString(objv[i]); for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { if (HasTag(panePtr, tag)) { Tcl_SetBooleanObj(Tcl_GetObjResult(interp), TRUE); return TCL_OK; } } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), FALSE); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagForgetOp -- * * Removes the given tags from all panes. * * .ts tag forget tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TagForgetOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for (i = 3; i < objc; i++) { const char *tag; long paneId; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &paneId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } ForgetTag(setPtr, tag); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagGetOp -- * * Returns tag names for a given node. If one of more pattern arguments * are provided, then only those matching tags are returned. * * .t tag get pane pat1 pat2... * *--------------------------------------------------------------------------- */ static int TagGetOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; PaneIterator iter; Tcl_Obj *listObjPtr; if (GetPaneIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { if (objc == 4) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(tablePtr, (char *)panePtr) != NULL) { const char *tag; Tcl_Obj *objPtr; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj("all", 3)); } else { int i; /* Check if we need to add the special tags "all" */ for (i = 4; i < objc; i++) { const char *pattern; pattern = Tcl_GetString(objv[i]); if (Tcl_StringMatch("all", pattern)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj("all", 3); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); break; } } /* Now process any standard tags. */ for (i = 4; i < objc; i++) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; const char *pattern; pattern = Tcl_GetString(objv[i]); for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { const char *tag; Blt_HashTable *tablePtr; tablePtr = Blt_GetHashValue(hPtr); tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); if (!Tcl_StringMatch(tag, pattern)) { continue; } if (Blt_FindHashEntry(tablePtr, (char *)panePtr) != NULL) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr,objPtr); } } } } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagNamesOp -- * * Returns the names of all the tags in the paneset. If one of more node * arguments are provided, then only the tags found in those nodes are * returned. * * .t tag names pane pane pane... * *--------------------------------------------------------------------------- */ static int TagNamesOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *listObjPtr, *objPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); objPtr = Tcl_NewStringObj("all", -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (objc == 3) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { const char *tag; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); objPtr = Tcl_NewStringObj(tag, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } else { Blt_HashTable uniqTable; int i; Blt_InitHashTable(&uniqTable, BLT_STRING_KEYS); for (i = 3; i < objc; i++) { PaneIterator iter; Pane *panePtr; if (GetPaneIterator(interp, setPtr, objPtr, &iter) != TCL_OK) { goto error; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&setPtr->tagTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { const char *tag; Blt_HashTable *tablePtr; tag = Blt_GetHashKey(&setPtr->tagTable, hPtr); tablePtr = Blt_GetHashValue(hPtr); if (Blt_FindHashEntry(tablePtr, panePtr) != NULL) { int isNew; Blt_CreateHashEntry(&uniqTable, tag, &isNew); } } } } { Blt_HashEntry *hPtr; Blt_HashSearch hiter; for (hPtr = Blt_FirstHashEntry(&uniqTable, &hiter); hPtr != NULL; hPtr = Blt_NextHashEntry(&hiter)) { objPtr = Tcl_NewStringObj(Blt_GetHashKey(&uniqTable, hPtr), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } Blt_DeleteHashTable(&uniqTable); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; error: Tcl_DecrRefCount(listObjPtr); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagIndicesOp -- * * Returns the indices associated with the given tags. The indices * returned will represent the union of panes for all the given tags. * * .t tag indices tag1 tag2 tag3... * *--------------------------------------------------------------------------- */ static int TagIndicesOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_HashTable paneTable; int i; Blt_InitHashTable(&paneTable, BLT_ONE_WORD_KEYS); for (i = 3; i < objc; i++) { long paneId; const char *tag; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &paneId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); goto error; } if (strcmp(tag, "all") == 0) { break; } else { Blt_HashTable *tablePtr; tablePtr = GetTagTable(setPtr, tag); if (tablePtr != NULL) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pane *panePtr; int isNew; panePtr = Blt_GetHashValue(hPtr); if (panePtr != NULL) { Blt_CreateHashEntry(&paneTable, (char *)panePtr, &isNew); } } continue; } } Tcl_AppendResult(interp, "can't find a tag \"", tag, "\"", (char *)NULL); goto error; } { Blt_HashEntry *hPtr; Blt_HashSearch iter; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (hPtr = Blt_FirstHashEntry(&paneTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Pane *panePtr; Tcl_Obj *objPtr; panePtr = (Pane *)Blt_GetHashKey(&paneTable, hPtr); objPtr = Tcl_NewLongObj(panePtr->index); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); } Blt_DeleteHashTable(&paneTable); return TCL_OK; error: Blt_DeleteHashTable(&paneTable); return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * TagSetOp -- * * Sets one or more tags for a given pane. Tag names can't start with a * digit (to distinquish them from node ids) and can't be a reserved tag * ("all"). * * .t tag set pane tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagSetOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (i = 4; i < objc; i++) { const char *tag; Pane *panePtr; long paneId; tag = Tcl_GetString(objv[i]); if (Tcl_GetLongFromObj(NULL, objv[i], &paneId) == TCL_OK) { Tcl_AppendResult(interp, "bad tag \"", tag, "\": can't be a number.", (char *)NULL); return TCL_ERROR; } if (strcmp(tag, "all") == 0) { Tcl_AppendResult(interp, "can't add reserved tag \"", tag, "\"", (char *)NULL); return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { AddTag(setPtr, panePtr, tag); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagUnsetOp -- * * Removes one or more tags from a given pane. If a tag doesn't exist or * is a reserved tag ("all"), nothing will be done and no error * message will be returned. * * .t tag unset pane tag1 tag2... * *--------------------------------------------------------------------------- */ static int TagUnsetOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Pane *panePtr; PaneIterator iter; if (GetPaneIterator(interp, setPtr, objv[3], &iter) != TCL_OK) { return TCL_ERROR; } for (panePtr = FirstTaggedPane(&iter); panePtr != NULL; panePtr = NextTaggedPane(&iter)) { int i; for (i = 4; i < objc; i++) { RemoveTag(panePtr, Tcl_GetString(objv[i])); } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TagOp -- * * This procedure is invoked to process tag operations. * * Results: * A standard TCL result. * * Side Effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static Blt_OpSpec tagOps[] = { {"add", 1, TagAddOp, 2, 0, "?name? ?option value...?",}, {"delete", 1, TagDeleteOp, 2, 0, "?pane...?",}, {"exists", 1, TagExistsOp, 4, 0, "pane ?tag...?",}, {"forget", 1, TagForgetOp, 3, 0, "?tag...?",}, {"get", 1, TagGetOp, 4, 0, "pane ?pattern...?",}, {"indices", 1, TagIndicesOp, 3, 0, "?tag...?",}, {"names", 2, TagNamesOp, 3, 0, "?pane...?",}, {"set", 1, TagSetOp, 4, 0, "pane ?tag...",}, {"unset", 1, TagUnsetOp, 4, 0, "pane ?tag...",}, }; static int nTagOps = sizeof(tagOps) / sizeof(Blt_OpSpec); static int TagOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PanesetCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nTagOps, tagOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc)(setPtr, interp, objc, objv); return result; } static int ViewOp(Paneset *setPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width; width = VPORTWIDTH(setPtr); if (objc == 2) { double fract; Tcl_Obj *listObjPtr, *objPtr; /* Report first and last fractions */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); /* * Note: we are bounding the fractions between 0.0 and 1.0 to support * the "canvas"-style of scrolling. */ fract = (double)setPtr->scrollOffset / setPtr->worldWidth; objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); fract = (double)(setPtr->scrollOffset + width) / setPtr->worldWidth; objPtr = Tcl_NewDoubleObj(FCLAMP(fract)); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } if (Blt_GetScrollInfoFromObj(interp, objc - 2, objv + 2, &setPtr->scrollOffset, setPtr->worldWidth, width, setPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= SCROLL_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Paneset operations. * * The fields for Blt_OpSpec are as follows: * * - operation name * - minimum number of characters required to disambiguate the operation name. * - function associated with operation. * - minimum number of arguments required. * - maximum number of arguments allowed (0 indicates no limit). * - usage string * *--------------------------------------------------------------------------- */ static Blt_OpSpec panesetOps[] = { {"add", 1, AddOp, 2, 0, "?name? ?option value?...",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?",}, {"delete", 1, DeleteOp, 3, 3, "pane",}, {"exists", 1, ExistsOp, 3, 3, "pane",}, {"index", 3, IndexOp, 3, 3, "pane",}, {"insert", 3, InsertOp, 3, 0, "position ?name? ?option value?...",}, {"invoke", 3, InvokeOp, 3, 3, "pane",}, {"move", 1, MoveOp, 3, 0, "pane after|before pane",}, {"names", 1, NamesOp, 2, 0, "?pattern...?",}, {"pane", 1, PaneOp, 2, 0, "oper ?args?",}, {"see", 1, SeeOp, 3, 3, "pane",}, {"tag", 1, TagOp, 2, 0, "oper args",}, {"view", 1, ViewOp, 2, 5, "?moveto fract? ?scroll number what?",}, }; static int nPanesetOps = sizeof(panesetOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * PanesetInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void PanesetInstCmdDeleteProc(ClientData clientData) { Paneset *setPtr = clientData; /* * This procedure could be invoked either because the window was destroyed * and the command was then deleted (in which case tkwin is NULL) or * because the command was deleted, and then this procedure destroys the * widget. */ if (setPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = setPtr->tkwin; setPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * PanesetInstCmdProc -- * * This procedure is invoked to process the TCL command that corresponds * to the paneset geometry manager. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int PanesetInstCmdProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PanesetCmdProc *proc; proc = Blt_GetOpFromObj(interp, nPanesetOps, panesetOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc)(clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * DrawerInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void DrawerInstCmdDeleteProc(ClientData clientData) { Paneset *setPtr = clientData; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin is * NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (setPtr->tkwin != NULL) { DestroyPaneset(setPtr); } } /* *--------------------------------------------------------------------------- * * Drawer operations. * * The fields for Blt_OpSpec are as follows: * * - operation name * - minimum number of characters required to disambiguate the operation name. * - function associated with operation. * - minimum number of arguments required. * - maximum number of arguments allowed (0 indicates no limit). * - usage string * *--------------------------------------------------------------------------- */ static Blt_OpSpec drawerOps[] = { {"add", 1, AddOp, 2, 0, "?name? ?option value?...",}, {"cget", 2, CgetOp, 3, 3, "option",}, {"close", 2, CloseOp, 3, 3, "drawer",}, {"configure", 2, ConfigureOp, 2, 0, "?option value?",}, {"delete", 2, DeleteOp, 3, 3, "drawer",}, {"drawer", 2, PaneOp, 2, 0, "oper ?args?",}, {"insert", 3, InsertOp, 4, 0, "position ?name? ?option value?...",}, {"invoke", 3, InvokeOp, 3, 3, "drawer",}, {"isopen", 2, IsOpenOp, 3, 3, "drawer",}, {"lower", 1, LowerOp, 3, 3, "drawer",}, {"move", 1, MoveOp, 3, 0, "drawer before|after drawer",}, {"names", 1, NamesOp, 2, 0, "?pattern...?",}, {"open", 1, OpenOp, 3, 3, "drawer",}, {"raise", 1, RaiseOp, 3, 3, "drawer",}, {"size", 2, SizeOp, 2, 4, "?drawer? ?size?",}, {"tag", 2, TagOp, 2, 0, "oper args",}, {"toggle", 2, ToggleOp, 3, 3, "drawer",}, }; static int nDrawerOps = sizeof(drawerOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * DrawerInstCmdProc -- * * This procedure is invoked to process the TCL command that corresponds * to the paneset geometry manager. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int DrawerInstCmdProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { PanesetCmdProc *proc; proc = Blt_GetOpFromObj(interp, nDrawerOps, drawerOps, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } return (*proc)(clientData, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * HandleActivateOp -- * * Changes the cursor and schedules to redraw the handle in * its activate state (different relief, colors, etc). * * .s activate * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleActivateOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; setPtr = panePtr->setPtr; if (panePtr != setPtr->activePtr) { Tk_Cursor cursor; int vert; if (setPtr->activePtr != NULL) { EventuallyRedrawHandle(setPtr->activePtr); } if (panePtr != NULL) { EventuallyRedrawHandle(panePtr); } setPtr->activePtr = panePtr; if (setPtr->type == DRAWER) { vert = panePtr->side & SIDE_VERTICAL; } else { vert = ISVERT(setPtr); } if (panePtr->cursor != None) { cursor = panePtr->cursor; } else if (vert) { cursor = setPtr->defVertCursor; } else { cursor = setPtr->defHorzCursor; } Tk_DefineCursor(panePtr->handle, cursor); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleAnchorOp -- * * Set the anchor for the resize/moving the pane/drawer. Only one of the * x and y coordinates are used depending upon the orientation of the * drawer or pane. * * drawer anchor x y * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleAnchorOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; int x, y; int vert; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } setPtr = panePtr->setPtr; setPtr->anchorPtr = setPtr->activePtr = panePtr; setPtr->flags |= HANDLE_ACTIVE; if (setPtr->type == DRAWER) { vert = panePtr->side & SIDE_VERTICAL; } else { vert = ISVERT(setPtr); } if (vert) { setPtr->bearing = ScreenY(panePtr); setPtr->handleAnchor = y; } else { setPtr->bearing = ScreenX(panePtr); setPtr->handleAnchor = x; } setPtr->bearing += panePtr->size; AdjustHandle(setPtr, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleCgetOp -- * * Returns the value of the named option in the handle. * * Results: * Returns a standard TCL result. * * .p cget option *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleCgetOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; setPtr = panePtr->setPtr; return Blt_ConfigureValueFromObj(interp, setPtr->tkwin, paneSpecs, (char *)panePtr, objv[2], 0); } /* *--------------------------------------------------------------------------- * * HandleCloseOp -- * * Used only for drawers. Closes the specified drawer. * * Results: * Returns a standard TCL result. * * drawer open * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleCloseOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if ((panePtr->tkwin == NULL) || (panePtr->flags & (DISABLED|CLOSED))) { return TCL_OK; } EventuallyCloseDrawer(panePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleConfigureOp -- * * Returns the name, position and options of a widget in the paneset. * * Results: * Returns a standard TCL result. A list of the paneset configuration * option information is left in interp->result. * * drawer configure option value *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleConfigureOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; setPtr = panePtr->setPtr; if (objc == 2) { return Blt_ConfigureInfoFromObj(interp, panePtr->handle, paneSpecs, (char *)panePtr, (Tcl_Obj *)NULL, setPtr->type); } else if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, panePtr->handle, paneSpecs, (char *)panePtr, objv[2], setPtr->type); } if (Blt_ConfigureWidgetFromObj(interp, panePtr->handle, paneSpecs, objc-2, objv+2, (char *)panePtr, BLT_CONFIG_OBJV_ONLY|setPtr->type) != TCL_OK) { return TCL_ERROR; } setPtr->flags |= LAYOUT_PENDING; EventuallyRedraw(setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleDeactivateOp -- * * Changes the cursor and schedules to redraw the handle in its * inactivate state (different relief, colors, etc). * * drawer deactivate * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleDeactivateOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; setPtr = panePtr->setPtr; if (panePtr == setPtr->activePtr) { EventuallyRedrawHandle(panePtr); setPtr->activePtr = NULL; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleIsOpenOp -- * * Indicates if the drawer is open or closed. * * Results: * Returns a standard TCL result. * * drawer isopen * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleIsOpenOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int state; state = (panePtr->flags & CLOSED) ? FALSE : TRUE; Tcl_SetBooleanObj(Tcl_GetObjResult(interp), state); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleLowerOp -- * * Lowers the specified pane to bottom of the stack of panes. * * Results: * Returns a standard TCL result. * * .p lower * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleLowerOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { LowerDrawer(panePtr); EventuallyRedraw(panePtr->setPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleMarkOp -- * * Sets the current mark for moving the handle. The change between the * mark and the anchor is the amount to move the handle from its previous * location. * * drawer mark x y * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleMarkOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; int x, y; /* Root coordinates of the pointer * over the handle. */ int delta, mark, vert; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } setPtr = panePtr->setPtr; setPtr->anchorPtr = panePtr; if (setPtr->type == DRAWER) { vert = panePtr->side & SIDE_VERTICAL; } else { vert = ISVERT(setPtr); } mark = (vert) ? y : x; delta = mark - setPtr->handleAnchor; AdjustHandle(setPtr, delta); setPtr->handleAnchor = mark; return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleMoveOp -- * * Moves the handle. The handle is moved the given distance from its * previous location. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleMoveOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; int delta, x, y; int vert; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } setPtr = panePtr->setPtr; setPtr->anchorPtr = panePtr; if (setPtr->type == DRAWER) { vert = panePtr->side & SIDE_VERTICAL; } else { vert = ISVERT(setPtr); } if (vert) { delta = y; setPtr->bearing = ScreenY(panePtr); } else { delta = x; setPtr->bearing = ScreenX(panePtr); } setPtr->bearing += panePtr->size; AdjustHandle(setPtr, delta); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleOpenOp -- * * Used only for drawers. Opens the specified drawer. The drawer is * opened to the widget's requested size. * * Results: * Returns a standard TCL result. * * drawer open * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleOpenOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if ((panePtr->flags & (DISABLED|CLOSED)) != CLOSED) { return TCL_OK; /* Already open or disabled. */ } EventuallyOpenDrawer(panePtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleSetOp -- * * Sets the location of the handle to coordinate (x or y) specified. The * windows are move and/or arranged according to the mode. * * drawer set $x $y * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleSetOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Paneset *setPtr; int x, y; int delta, mark, vert; if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } setPtr = panePtr->setPtr; setPtr->flags &= ~HANDLE_ACTIVE; if (setPtr->type == DRAWER) { vert = panePtr->side & SIDE_VERTICAL; } else { vert = ISVERT(setPtr); } mark = (vert) ? y : x; delta = mark - setPtr->handleAnchor; AdjustHandle(setPtr, delta); setPtr->handleAnchor = mark; return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleSizeOp -- * * Only used for drawers, set and/or gets the size of the opening for the * drawer. This does not affect the size of the window. * * drawer size $size * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleSizeOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int size; if (objc == 2) { size = panePtr->size; } else { int newSize; Paneset *setPtr; setPtr = panePtr->setPtr; if (Blt_GetPixelsFromObj(interp, setPtr->tkwin, objv[2], PIXELS_NNEG, &newSize) != TCL_OK) { return TCL_ERROR; } panePtr->size = newSize; if (panePtr->side & SIDE_VERTICAL) { panePtr->y = newSize; } else { panePtr->x = newSize; } EventuallyRedraw(setPtr); } Tcl_SetIntObj(Tcl_GetObjResult(interp), size); return TCL_OK; } /* *--------------------------------------------------------------------------- * * HandleRaiseOp -- * * Raises the specified pane to the top of the stack of panes. * * Results: * Returns a standard TCL result. * * drawer raise * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int HandleRaiseOp(Pane *panePtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { RaiseDrawer(panePtr); EventuallyRedraw(panePtr->setPtr); return TCL_OK; } static Blt_OpSpec drawerHandleOps[] = { {"activate", 2, HandleActivateOp, 2, 2, ""}, {"anchor", 2, HandleAnchorOp, 4, 4, "x y"}, {"cget", 2, HandleCgetOp, 3, 3, "option",}, {"close", 2, HandleCloseOp, 3, 3, "",}, {"configure", 2, HandleConfigureOp, 2, 0, "?option value?",}, {"deactivate", 1, HandleDeactivateOp, 2, 2, ""}, {"isopen", 1, HandleIsOpenOp, 2, 2, "",}, {"lower", 1, HandleLowerOp, 2, 2, "",}, {"mark", 1, HandleMarkOp, 4, 4, "x y"}, {"move", 1, HandleMoveOp, 4, 4, "x y"}, {"open", 1, HandleOpenOp, 2, 2, "",}, {"raise", 1, HandleRaiseOp, 2, 2, "",}, {"set", 2, HandleSetOp, 4, 4, "x y"}, {"size", 2, HandleSizeOp, 2, 3, "?size?"}, }; static int nDrawerHandleOps = sizeof(drawerHandleOps) / sizeof(Blt_OpSpec); static Blt_OpSpec paneHandleOps[] = { {"activate", 2, HandleActivateOp, 2, 2, ""}, {"anchor", 2, HandleAnchorOp, 4, 4, "x y"}, {"cget", 2, HandleCgetOp, 3, 3, "option",}, {"configure", 2, HandleConfigureOp, 2, 0, "?option value?",}, {"deactivate", 1, HandleDeactivateOp, 2, 2, ""}, {"mark", 1, HandleMarkOp, 4, 4, "x y"}, {"move", 1, HandleMoveOp, 4, 4, "x y"}, {"set", 1, HandleSetOp, 4, 4, "x y"}, }; static int nPaneHandleOps = sizeof(paneHandleOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * HandleInstCmdProc -- * * This procedure is invoked to process the TCL command that corresponds * to the paneset geometry manager. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ static int HandleInstCmdProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_OpSpec *specs; HandleCmdProc *proc; Pane *panePtr = clientData; Paneset *setPtr; int nSpecs; setPtr = panePtr->setPtr; if (setPtr->type == DRAWER) { specs = drawerHandleOps; nSpecs = nDrawerHandleOps; } else { specs = paneHandleOps; nSpecs = nPaneHandleOps; } proc = Blt_GetOpFromObj(interp, nSpecs, specs, BLT_OP_ARG1, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } if (panePtr->flags & (DISABLED|HIDE)) { return TCL_OK; } return (*proc)(panePtr, interp, objc, objv); } /* *--------------------------------------------------------------------------- * * HandleInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void HandleInstCmdDeleteProc(ClientData clientData) { Pane *panePtr = clientData; /* * This procedure could be invoked either because the window was destroyed * and the command was then deleted (in which case tkwin is NULL) or * because the command was deleted, and then this procedure destroys the * widget. */ if (panePtr->handle != NULL) { Tk_Window tkwin; tkwin = panePtr->handle; panePtr->handle = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * PanesetCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int PanesetCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Paneset *setPtr; Tcl_CmdInfo cmdInfo; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * Invoke a procedure to initialize various bindings on treeview entries. * If the procedure doesn't already exist, source it from * "$blt_library/paneset.tcl". We deferred sourcing the file until now so * that the variable $blt_library could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::paneset::Initialize", &cmdInfo)) { char cmd[200]; sprintf_s(cmd, 200, "source [file join $blt_library paneset.tcl]\n"); if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } setPtr = NewPaneset(interp, objv[1], PANESET); if (setPtr == NULL) { goto error; } if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, panesetSpecs, objc - 2, objv + 2, (char *)setPtr, setPtr->type) != TCL_OK) { goto error; } ConfigurePaneset(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(setPtr->tkwin),-1); return TCL_OK; error: if (setPtr != NULL) { Tk_DestroyWindow(setPtr->tkwin); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * FilmstripCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int FilmstripCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Paneset *setPtr; Tcl_CmdInfo cmdInfo; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * Invoke a procedure to initialize various bindings on treeview entries. * If the procedure doesn't already exist, source it from * "$blt_library/paneset.tcl". We deferred sourcing the file until now so * that the variable $blt_library could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Filmstrip::Initialize", &cmdInfo)) { char cmd[200]; sprintf_s(cmd, 200, "source [file join $blt_library filmstrip.tcl]\n"); if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); goto error; } } setPtr = NewPaneset(interp, objv[1], FILMSTRIP); if (setPtr == NULL) { goto error; } if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, panesetSpecs, objc - 2, objv + 2, (char *)setPtr, setPtr->type) != TCL_OK) { goto error; } ConfigurePaneset(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(setPtr->tkwin),-1); return TCL_OK; error: if (setPtr != NULL) { Tk_DestroyWindow(setPtr->tkwin); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * DrawersetCmd -- * * This procedure is invoked to process the TCL command that corresponds * to a widget managed by this module. See the user documentation for * details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int DrawersetCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Paneset *setPtr; Tcl_CmdInfo cmdInfo; if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } /* * Invoke a procedure to initialize various bindings on treeview entries. * If the procedure doesn't already exist, source it from * "$blt_library/paneset.tcl". We deferred sourcing the file until now so * that the variable $blt_library could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::Drawer::Initialize", &cmdInfo)) { char cmd[200]; sprintf_s(cmd, 200, "source [file join $blt_library drawer.tcl]\n"); if (Tcl_GlobalEval(interp, cmd) != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); return TCL_ERROR; } } setPtr = NewDrawerset(interp, objv[1]); if (setPtr == NULL) { goto error; } if (Blt_ConfigureWidgetFromObj(interp, setPtr->tkwin, panesetSpecs, objc - 2, objv + 2, (char *)setPtr, setPtr->type) != TCL_OK) { goto error; } ConfigurePaneset(setPtr); Tcl_SetStringObj(Tcl_GetObjResult(interp), setPtr->name, -1); return TCL_OK; error: if (setPtr != NULL) { Tk_DestroyWindow(setPtr->tkwin); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * Blt_PanesetCmdInitProc -- * * This procedure is invoked to initialize the TCL command that * corresponds to the paneset geometry manager. * * Results: * None. * * Side effects: * Creates the new TCL command. * *--------------------------------------------------------------------------- */ int Blt_PanesetCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[] = { { "drawerset", DrawersetCmd }, { "filmstrip", FilmstripCmd }, { "paneset", PanesetCmd } }; return Blt_InitCmds(interp, "::blt", cmdSpecs, 3); } /* *--------------------------------------------------------------------------- * * DisplayPaneset -- * * * Results: * None. * * Side Effects: * The widgets in the paneset are possibly resized and redrawn. * *--------------------------------------------------------------------------- */ static void DisplayPaneset(ClientData clientData) { Paneset *setPtr = clientData; setPtr->flags &= ~REDRAW_PENDING; #if TRACE fprintf(stderr, "DisplayPaneset(%s)\n", Tk_PathName(setPtr->tkwin)); #endif if (setPtr->flags & LAYOUT_PENDING) { ComputeGeometry(setPtr); } if (setPtr->reqWidth > 0) { setPtr->normalWidth = setPtr->reqWidth; } if (setPtr->reqHeight > 0) { setPtr->normalHeight = setPtr->reqHeight; } if (setPtr->type & (FILMSTRIP|PANESET)) { if ((setPtr->normalWidth != Tk_ReqWidth(setPtr->tkwin)) || (setPtr->normalHeight != Tk_ReqHeight(setPtr->tkwin))) { Tk_GeometryRequest(setPtr->tkwin, setPtr->normalWidth, setPtr->normalHeight); EventuallyRedraw(setPtr); return; } } if ((Tk_Width(setPtr->tkwin) <= 1) || (Tk_Height(setPtr->tkwin) <=1)) { /* Don't bother computing the layout until the size of the window is * something reasonable. */ return; } if (!Tk_IsMapped(setPtr->tkwin)) { /* The paneset's window isn't displayed, so don't bother drawing * anything. By getting this far, we've at least computed the * coordinates of the new layout. */ return; } if ((setPtr->type == FILMSTRIP) && (setPtr->flags & SCROLL_PENDING)) { int width; width = VPORTWIDTH(setPtr); setPtr->scrollOffset = Blt_AdjustViewport(setPtr->scrollOffset, setPtr->worldWidth, width, setPtr->scrollUnits, BLT_SCROLL_MODE_HIERBOX); if (setPtr->scrollCmdObjPtr != NULL) { Blt_UpdateScrollbar(setPtr->interp, setPtr->scrollCmdObjPtr, setPtr->scrollOffset, setPtr->scrollOffset + width, setPtr->worldWidth); } setPtr->flags &= ~SCROLL_PENDING; } setPtr->nVisible = Blt_Chain_GetLength(setPtr->chain); if (setPtr->type & (FILMSTRIP|PANESET)) { #ifndef notdef Blt_FillBackgroundRectangle(setPtr->tkwin, Tk_WindowId(setPtr->tkwin), setPtr->bg, 0, 0, Tk_Width(setPtr->tkwin), Tk_Height(setPtr->tkwin), 0, TK_RELIEF_FLAT); #endif if (setPtr->nVisible > 0) { if (ISVERT(setPtr)) { VerticalPanes(setPtr); } else { HorizontalPanes(setPtr); } } } else { if (setPtr->nVisible > 0) { ArrangeDrawers(setPtr); } } } /* *--------------------------------------------------------------------------- * * DisplayHandle * * Draws the pane's handle at its proper location. First determines the * size and position of the each window. It then considers the * following: * * 1. translation of widget position its parent widget. * 2. fill style * 3. anchor * 4. external and internal padding * 5. widget size must be greater than zero * * Results: * None. * * Side Effects: * The size of each pane is re-initialized its minimum size. * *--------------------------------------------------------------------------- */ static void DisplayHandle(ClientData clientData) { Pane *panePtr = clientData; Blt_Background bg; int relief; Paneset *setPtr; Drawable drawable; panePtr->flags &= ~REDRAW_PENDING; if (panePtr->handle == NULL) { return; } setPtr = panePtr->setPtr; if (setPtr->activePtr == panePtr) { bg = GETATTR(panePtr, activeHandleBg); relief = setPtr->activeRelief; } else { bg = GETATTR(panePtr, handleBg); relief = setPtr->relief; } drawable = Tk_WindowId(panePtr->handle); Blt_FillBackgroundRectangle(panePtr->handle, drawable, bg, 0, 0, Tk_Width(panePtr->handle), Tk_Height(panePtr->handle), 0, TK_RELIEF_FLAT); Blt_DrawBackgroundRectangle(panePtr->handle, drawable, bg, setPtr->handlePad.side1, setPtr->handlePad.side1, Tk_Width(panePtr->handle) - PADDING(setPtr->handlePad), Tk_Height(panePtr->handle) - PADDING(setPtr->handlePad), setPtr->handleBW, relief); if ((setPtr->highlightThickness > 0) && (panePtr->flags & FOCUS)) { GC gc; gc = Tk_GCForColor(panePtr->highlightColor, drawable); Tk_DrawFocusHighlight(panePtr->handle, gc, setPtr->highlightThickness, drawable); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTreeView.h�����������������������������������������������������������������0000644�0001750�0001750�00000112444�11462120063�015441� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTreeView.h -- * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * * BUGS: * 1. "open" operation should change scroll offset so that as many * new entries (up to half a screen) can be seen. * 2. "open" needs to adjust the scrolloffset so that the same entry * is seen at the same place. */ #ifndef BLT_TREEVIEW_H #define BLT_TREEVIEW_H #include "bltImage.h" #include "bltHash.h" #include "bltFont.h" #include "bltText.h" #include "bltChain.h" #include "bltTree.h" #include "bltTile.h" #include "bltBind.h" #include "bltBgStyle.h" #define ITEM_ENTRY (ClientData)0 #define ITEM_ENTRY_BUTTON (ClientData)1 #define ITEM_COLUMN_TITLE (ClientData)2 #define ITEM_COLUMN_RULE (ClientData)3 #define ITEM_STYLE (ClientData)0x10004 #if HAVE_UTF #else #define Tcl_NumUtfChars(s,n) (((n) == -1) ? strlen((s)) : (n)) #define Tcl_UtfAtIndex(s,i) ((s) + (i)) #endif #define ODD(x) ((x) | 0x01) #define END (-1) #define SEPARATOR_LIST ((char *)NULL) #define SEPARATOR_NONE ((char *)-1) #define SEARCH_Y 1 #define TV_ARROW_WIDTH 17 #define TV_ARROW_HEIGHT 17 typedef const char *UID; /* * The macro below is used to modify a "char" value (e.g. by casting it to an * unsigned character) so that it can be used safely with macros such as * isspace. */ #define UCHAR(c) ((unsigned char) (c)) #define TOGGLE(x, mask) (((x) & (mask)) ? ((x) & ~(mask)) : ((x) | (mask))) #define SCREENX(h, wx) ((wx) - (h)->xOffset + (h)->inset) #define SCREENY(h, wy) ((wy) - (h)->yOffset + (h)->inset + (h)->titleHeight) #define WORLDX(h, sx) ((sx) - (h)->inset + (h)->xOffset) #define WORLDY(h, sy) ((sy) - ((h)->inset + (h)->titleHeight) + (h)->yOffset) #define VPORTWIDTH(h) (Tk_Width((h)->tkwin) - 2 * (h)->inset) #define VPORTHEIGHT(h) \ (Tk_Height((h)->tkwin) - (h)->titleHeight - 2 * (h)->inset) #define ICONWIDTH(d) (viewPtr->levelInfo[(d)].iconWidth) #define LEVELX(d) (viewPtr->levelInfo[(d)].x) #define DEPTH(h, n) (((h)->flatView) ? 0 : Blt_Tree_NodeDepth(n)) #define SELECT_MODE_SINGLE (1<<0) #define SELECT_MODE_MULTIPLE (1<<1) /* *--------------------------------------------------------------------------- * * Internal treeview widget flags: * * LAYOUT_PENDING The layout of the hierarchy needs to be recomputed. * * REDRAW_PENDING A redraw request is pending for the widget. * * SCROLLX X-scroll request is pending. * * SCROLLY Y-scroll request is pending. * * SCROLL_PENDING Both X-scroll and Y-scroll requests are pending. * * FOCUS The widget is receiving keyboard events. * Draw the focus highlight border around the widget. * * DIRTY The hierarchy has changed. It may invalidate * the locations and pointers to entries. The widget * will need to recompute its layout. * * RESORT The tree has changed such that the view needs to * be resorted. This can happen when an entry is * open or closed, it's label changes, a column value * changes, etc. * * REDRAW_BORDERS The borders of the widget (highlight ring and * 3-D border) need to be redrawn. * * VIEWPORT Indicates that the viewport has changed in some * way: the size of the viewport, the location of * the viewport, or the contents of the viewport. * */ #define LAYOUT_PENDING (1<<0) #define REDRAW_PENDING (1<<1) #define SCROLLX (1<<2) #define SCROLLY (1<<3) #define SCROLL_PENDING (SCROLLX | SCROLLY) #define FOCUS (1<<4) #define DIRTY (1<<5) #define SORTED (1<<8) #define UPDATE (1<<6) #define VIEWPORT (1<<11) #define RESORT (1<<7) #define SORT_PENDING (1<<9) #define REDRAW_BORDERS (1<<10) #define REPOPULATE (1<<12) #define COLUMN_HIDDEN (1<<13) #define COLUMN_READONLY (1<<14) /* * Rule related flags: Rules are XOR-ed lines. We need to track whether * they have been drawn or not. * * TV_RULE_ACTIVE Indicates that a rule is currently being drawn * for a column. * * * TV_RULE_NEEDED Indicates that a rule is needed (but not yet * drawn) for a column. */ #define TV_RULE_ACTIVE (1<<15) #define TV_RULE_NEEDED (1<<16) /* * Selection related flags: * * TV_SELECT_Blt_Export Export the selection to X11. * * TV_SELECT_PENDING A "selection" command idle task is pending. * * TV_SELECT_CLEAR Clear selection flag of entry. * * TV_SELECT_SET Set selection flag of entry. * * TV_SELECT_TOGGLE Toggle selection flag of entry. * * TV_SELECT_MASK Mask of selection set/clear/toggle flags. * * TV_SELECT_SORTED Indicates if the entries in the selection * should be sorted or displayed in the order * they were selected. * */ #define TV_SELECT_CLEAR (1<<16) #define TV_SELECT_EXPORT (1<<17) #define TV_SELECT_PENDING (1<<18) #define TV_SELECT_SET (1<<19) #define TV_SELECT_TOGGLE (TV_SELECT_SET | TV_SELECT_CLEAR) #define TV_SELECT_MASK (TV_SELECT_SET | TV_SELECT_CLEAR) #define TV_SELECT_SORTED (1<<20) /* * Miscellaneous flags: * * TV_ALLOW_DUPLICATES When inserting new entries, create * duplicate entries. * * TV_FILL_ANCESTORS Automatically create ancestor entries * as needed when inserting a new entry. * * HIDE_ROOT Don't display the root entry. * * TV_HIDE_LEAVES Don't display entries that are leaves. * * TV_SHOW_COLUMN_TITLES Indicates whether to draw titles over each * column. * */ #define TV_ALLOW_DUPLICATES (1<<21) #define TV_FILL_ANCESTORS (1<<22) #define HIDE_ROOT (1<<23) #define TV_HIDE_LEAVES (1<<24) #define TV_SHOW_COLUMN_TITLES (1<<25) #define TV_SORT_AUTO (1<<26) #define TV_NEW_TAGS (1<<27) #define TV_HIGHLIGHT_CELLS (1<<28) #define DONT_UPDATE (1<<29) #define TV_ITEM_COLUMN 1 #define TV_ITEM_RULE 2 /* *--------------------------------------------------------------------------- * * Internal entry flags: * * ENTRY_HAS_BUTTON Indicates that a button needs to be * drawn for this entry. * * ENTRY_CLOSED Indicates that the entry is closed and * its subentries are not displayed. * * ENTRY_HIDE Indicates that the entry is hidden (i.e. * can not be viewed by opening or scrolling). * * BUTTON_AUTO * BUTTON_SHOW * BUTTON_MASK * *--------------------------------------------------------------------------- */ #define ENTRY_CLOSED (1<<0) #define ENTRY_HIDE (1<<1) #define ENTRY_NOT_LEAF (1<<2) #define ENTRY_MASK (ENTRY_CLOSED | ENTRY_HIDE) #define ENTRY_HAS_BUTTON (1<<3) #define ENTRY_ICON (1<<4) #define ENTRY_REDRAW (1<<5) #define ENTRY_LAYOUT_PENDING (1<<6) #define ENTRY_DATA_CHANGED (1<<7) #define ENTRY_DIRTY (ENTRY_DATA_CHANGED | ENTRY_LAYOUT_PENDING) #define BUTTON_AUTO (1<<8) #define BUTTON_SHOW (1<<9) #define BUTTON_MASK (BUTTON_AUTO | BUTTON_SHOW) #define ENTRY_EDITABLE (1<<10) #define ENTRY_SELECTED (1<<11) #define COLUMN_RULE_PICKED (1<<1) #define COLUMN_DIRTY (1<<2) #define STYLE_TEXTBOX (0) #define STYLE_COMBOBOX (1) #define STYLE_CHECKBOX (2) #define STYLE_TYPE 0x3 #define STYLE_LAYOUT (1<<3) #define STYLE_DIRTY (1<<4) #define STYLE_HIGHLIGHT (1<<5) #define STYLE_USER (1<<6) #define STYLE_EDITABLE (1<<10) typedef struct _TreeViewColumn TreeViewColumn; typedef struct _TreeViewCombobox TreeView_Combobox; typedef struct _TreeViewEntry TreeViewEntry; typedef struct _TreeView TreeView; typedef struct _TreeViewStyleClass TreeViewStyleClass; typedef struct _TreeViewStyle TreeViewStyle; typedef int (TreeViewCompareProc)(Tcl_Interp *interp, const char *name, const char *pattern); typedef TreeViewEntry *(TreeViewIterProc)(TreeViewEntry *entryPtr, unsigned int mask); typedef struct { int tagType; TreeView *viewPtr; Blt_HashSearch cursor; TreeViewEntry *entryPtr; } TreeViewTagIter; /* * TreeViewIcon -- * * Since instances of the same Tk image can be displayed in * different windows with possibly different color palettes, Tk * internally stores each instance in a linked list. But if * the instances are used in the same widget and therefore use * the same color palette, this adds a lot of overhead, * especially when deleting instances from the linked list. * * For the treeview widget, we never need more than a single * instance of an image, regardless of how many times it's used. * Cache the image, maintaining a reference count for each * image used in the widget. It's likely that the treeview * widget will use many instances of the same image (for example * the open/close icons). */ typedef struct _TreeViewIcon { Tk_Image tkImage; /* The Tk image being cached. */ int refCount; /* Reference count for this image. */ short int width, height; /* Dimensions of the cached image. */ Blt_HashEntry *hashPtr; /* Hash table pointer to the image. */ } *TreeViewIcon; #define TreeView_IconHeight(icon) ((icon)->height) #define TreeView_IconWidth(icon) ((icon)->width) #define TreeView_IconBits(icon) ((icon)->tkImage) #define TreeView_IconName(icon) (Blt_Image_Name((icon)->tkImage)) /* * TreeViewColumn -- * * A column describes how to display a field of data in the tree. It may * display a title that you can bind to. It may display a rule for * resizing the column. Columns may be hidden, and have attributes * (foreground color, background color, font, etc) that override those * designated globally for the treeview widget. */ struct _TreeViewColumn { int type; /* Always TV_COLUMN */ Blt_TreeKey key; /* Data cell identifier for current * tree. */ int position; /* Position of column in list. Used * to indicate the first and last * columns. */ UID tagsUid; /* List of binding tags for this * entry. UID, not a string, because * in the typical case most columns * will have the same bindtags. */ TreeView *viewPtr; unsigned int flags; /* Title-related information */ const char *text; /* Text displayed in column heading as * its title. By default, this is the * same as the data cell name. */ short int textWidth, textHeight; /* Dimensions of title text. */ Blt_Font titleFont; /* Font to draw title in. */ XColor *titleFgColor; /* Foreground color of text displayed * in the heading */ Blt_Background titleBg; /* Background color of the heading. */ GC titleGC; XColor *activeTitleFgColor; /* Foreground color of the heading * when the column is activated.*/ Blt_Background activeTitleBg; int titleBW; int titleRelief; Tk_Justify titleJustify; /* Indicates how the text and/or icon * is justified within the column * title. */ GC activeTitleGC; short int titleWidth, titleHeight; TreeViewIcon titleIcon; /* Icon displayed in column heading */ const char *titleCmd; /* TCL script to be executed by the * column's "invoke" operation. */ Tcl_Obj *sortCmdPtr; /* TCL script used to compare two * columns. */ int reqArrowWidth; /* If > 0, this is the requested width * of the sort direction arrow * displayed in the title. */ int arrowWidth; /* Actual width of the arrow. */ /* General information. */ int state; /* Indicates if column title can * invoked. */ int max; /* Maximum space allowed for * column. */ int reqMin, reqMax; /* Requested bounds on the width of * column. Does not include any * padding or the borderwidth of * column. If non-zero, overrides the * computed width of the column. */ int reqWidth; /* User-requested width of * column. Does not include any * padding or the borderwidth of * column. If non-zero, overrides the * computed column width. */ int maxWidth; /* Width of the widest entry in the * column. */ int worldX; /* Starting world x-coordinate of the * column. */ double weight; /* Growth factor for column. Zero * indicates that the column can not * be resized. */ int width; /* Computed width of column. */ TreeViewStyle *stylePtr; /* Default style for column. */ Blt_Background bg; /* Background color. */ int borderWidth; /* Border width of the column. */ int relief; /* Relief of the column. */ Blt_Pad pad; /* Horizontal padding on either side * of the column. */ Tk_Justify justify; /* Indicates how the text or icon is * justified within the column. */ Blt_ChainLink link; int ruleLineWidth; Blt_Dashes ruleDashes; GC ruleGC; Tcl_Obj *fmtCmdPtr; }; struct _TreeViewStyle { int refCount; /* Usage reference count. A reference * count of zero indicates that the * style may be freed. */ unsigned int flags; /* Bit field containing both the style * type and various flags. */ const char *name; /* Instance name. */ TreeViewStyleClass *classPtr; /* Contains class-specific information * such as configuration * specifications and * configure, * draw, etc. routines. */ Blt_HashEntry *hashPtr; /* If non-NULL, points to the hash * table entry for the style. A style * that's been deleted, but still in * use (non-zero reference count) * will have no hash table entry. */ Blt_ChainLink link; /* If non-NULL, pointer of the * style in a list of all newly * created styles. */ /* General style fields. */ Tk_Cursor cursor; /* X Cursor */ TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be * drawn in the cell. */ int gap; /* # pixels gap between icon and * text. */ Blt_Font font; XColor *fgColor; /* Normal foreground color of cell. */ XColor *highlightFgColor; /* Foreground color of cell when * highlighted. */ XColor *activeFgColor; /* Foreground color of cell when * active. */ XColor *selFgColor; /* Foreground color of a selected * cell. If non-NULL, overrides * default foreground color * specification. */ Blt_Background bg; /* Normal background color of cell. */ Blt_Background highlightBg; /* Background color of cell when * highlighted. */ Blt_Background activeBg; /* Background color of cell when * active. */ Blt_Background selBg; /* Background color of a selected * cell. If non-NULL, overrides the * default background * color * specification. */ const char *validateCmd; }; typedef struct _TreeViewValue { TreeViewColumn *columnPtr; /* Column in which the value is * located. */ unsigned int width, height; /* Dimensions of value. */ TreeViewStyle *stylePtr; /* Style information for cell * displaying value. */ const char *fmtString; /* Raw text string. */ TextLayout *textPtr; /* Processes string to be displayed .*/ struct _TreeViewValue *nextPtr; } TreeViewValue; typedef void (StyleConfigProc)(TreeView *viewPtr, TreeViewStyle *stylePtr); typedef void (StyleDrawProc)(TreeView *viewPtr, Drawable drawable, TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int x, int y); typedef int (StyleEditProc)(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr, TreeViewStyle *stylePtr); typedef void (StyleFreeProc)(TreeView *viewPtr, TreeViewStyle *stylePtr); typedef void (StyleMeasureProc)(TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewValue *valuePtr); typedef int (StylePickProc)(TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr, int x, int y); struct _TreeViewStyleClass { const char *className; /* Class name of the style */ Blt_ConfigSpec *specsPtr; /* Style configuration * specifications */ StyleConfigProc *configProc; /* Sets the GCs for style. */ StyleMeasureProc *measProc; /* Measures the area needed for the * value with this style. */ StyleDrawProc *drawProc; /* Draw the value in it's style. */ StylePickProc *pickProc; /* Routine to pick the style's button. * Indicates if the mouse pointer is * over the style's button (if it has * one). */ StyleEditProc *editProc; /* Routine to edit the style's * value. */ StyleFreeProc *freeProc; /* Routine to free the style's * resources. */ }; /* * TreeViewEntry -- * * Contains data-specific information how to represent the data * of a node of the hierarchy. * */ struct _TreeViewEntry { Blt_TreeNode node; /* Node containing entry */ int worldX, worldY; /* X-Y position in world coordinates * where the entry is positioned. */ size_t width, height; /* Dimensions of the entry. This * includes the size of its columns. */ int reqHeight; /* Requested height of the entry. * Overrides computed height. */ int vertLineLength; /* Length of the vertical line * segment. */ short int lineHeight; /* Height of first line of text. */ unsigned short int flags; /* Flags for this entry. For the * definitions of the various bit * fields see below. */ UID tagsUid; /* List of binding tags for this * entry. UID, not a string, because * in the typical case most entries * will have the same bindtags. */ TreeView *viewPtr; UID openCmd, closeCmd; /* TCL commands to invoke when entries * are opened or closed. They override * those specified globally. */ /* * Button information: */ short int buttonX, buttonY; /* X-Y coordinate offsets from to * upper left corner of the entry to * the upper-left corner of the * button. Used to pick the button * quickly */ TreeViewIcon *icons; /* Tk images displayed for the entry. * The first image is the icon * displayed to the left of the * entry's label. The second is icon * displayed when entry is "open". */ TreeViewIcon *activeIcons; /* Tk images displayed for the entry. * The first image is the icon * displayed to the left of the * entry's label. The second * is icon * displayed when entry is "open". */ short int iconWidth; short int iconHeight; /* Maximum dimensions for icons and * buttons for this entry. This is * used to align the button, icon, and * text. */ /* * Label information: */ TextLayout *textPtr; short int labelWidth; short int labelHeight; UID labelUid; /* Text displayed right of the * icon. */ Blt_Font font; /* Font of label. Overrides global * font specification. */ const char *fullName; int flatIndex; /* Used to navigate to next/last entry * when the view is flat. */ Tcl_Obj *dataObjPtr; /* pre-fetched data for sorting */ XColor *color; /* Color of label. If non-NULL, * overrides default text color * specification. */ GC gc; TreeViewValue *values; /* List of column-related information * for each data value in the node. * Non-NULL only if there are value * entries. */ }; /* * TreeViewButton -- * * A button is the open/close indicator at the far left of the entry. It * is displayed as a plus or minus in a solid colored box with optionally * an border. It has both "active" and "normal" colors. */ typedef struct { XColor *fgColor; /* Foreground color. */ Blt_Background bg; /* Background color. */ XColor *activeFgColor; /* Active foreground color. */ Blt_Background activeBg; /* Active background color. */ GC normalGC; GC activeGC; int reqSize; int borderWidth; int openRelief, closeRelief; int width, height; TreeViewIcon *icons; } TreeViewButton; /* * LevelInfo -- * */ typedef struct { int x; int iconWidth; int labelWidth; } LevelInfo; /* * TreeView -- * * A TreeView is a widget that displays an hierarchical table of one * or more entries. * * Entries are positioned in "world" coordinates, referring to the * virtual treeview. Coordinate 0,0 is the upper-left corner of the root * entry and the bottom is the end of the last entry. The widget's Tk * window acts as view port into this virtual space. The treeview's * xOffset and yOffset fields specify the location of the view port in * the virtual world. Scrolling the viewport is therefore simply * changing the xOffset and/or yOffset fields and redrawing. * * Note that world coordinates are integers, not signed short integers * like X11 screen coordinates. It's very easy to create a hierarchy * taller than 0x7FFF pixels. */ struct _TreeView { Tcl_Interp *interp; Tcl_Command cmdToken; /* Token for widget's TCL command. */ Blt_Tree tree; /* Token holding internal tree. */ const char *treeName; /* In non-NULL, is the name of the tree we are * attached to */ Blt_HashEntry *hashPtr; /* TreeView_ specific fields. */ Tk_Window tkwin; /* Window that embodies the widget. NULL * means that the window has been destroyed * but the data structures haven't yet been * cleaned up.*/ Display *display; /* Display containing widget; needed, among * other things, to release resources after * tkwin has already gone away. */ Blt_HashTable entryTable; /* Table of entry information, keyed by the * node pointer. */ Blt_HashTable columnTable; /* Table of column information. */ Blt_Chain columns; /* Chain of columns. Same as the hash table * above but maintains the order in which * columns are displayed. */ unsigned int flags; /* For bitfield definitions, see below */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. * Indicates how much interior stuff must be * offset from outside edges to leave room for * borders. */ Blt_Font font; XColor *fgColor; Blt_Background bg; /* 3D border surrounding the window * (viewport). */ Blt_Background altBg; int borderWidth; /* Width of 3D border. */ int relief; /* 3D border relief. */ int highlightWidth; /* Width in pixels of highlight to draw around * widget when it has the focus. <= 0 means * don't draw a highlight. */ XColor *highlightBgColor; /* Color for drawing traversal highlight area * when highlight is off. */ XColor *highlightColor; /* Color for drawing traversal highlight. */ const char *pathSep; /* Pathname separators */ const char *trimLeft; /* Leading characters to trim from * pathnames */ /* * Entries are connected by horizontal and vertical lines. They may be * drawn dashed or solid. */ int lineWidth; /* Width of lines connecting entries */ int dashes; /* Dash on-off value. */ XColor *lineColor; /* Color of connecting lines. */ /* * Button Information: * * The button is the open/close indicator at the far left of the entry. * It is usually displayed as a plus or minus in a solid colored box with * optionally an border. It has both "active" and "normal" colors. */ TreeViewButton button; /* * Selection Information: * * The selection is the rectangle that contains a selected entry. There * may be many selected entries. It is displayed as a solid colored box * with optionally a 3D border. */ int selRelief; /* Relief of selected items. Currently is * always raised. */ int selBW; /* Border width of a selected entry.*/ XColor *selFgColor; /* Text color of a selected entry. */ Blt_Background selBg; TreeViewEntry *selAnchorPtr; /* Fixed end of selection (i.e. entry * at which selection was started.) */ TreeViewEntry *selMarkPtr; GC selGC; int selectMode; /* Selection style: "single" or * "multiple". */ const char *selectCmd; /* TCL script that's invoked whenever the * selection changes. */ Blt_HashTable selectTable; /* Hash table of currently selected * entries. */ Blt_Chain selected; /* Chain of currently selected entries. * Contains the same information as the * above hash table, but maintains the * order in which entries are * selected. */ int leader; /* Number of pixels padding between * entries. */ Tk_Cursor cursor; /* X Cursor */ Tk_Cursor resizeCursor; /* Resize Cursor */ int reqWidth, reqHeight; /* Requested dimensions of the treeview * widget's window. */ GC lineGC; /* GC for drawing dotted line between * entries. */ XColor *focusColor; Blt_Dashes focusDashes; /* Dash on-off value. */ GC focusGC; /* Graphics context for the active * label. */ Tk_Window comboWin; TreeViewEntry *activePtr; /* Last active entry. */ TreeViewEntry *focusPtr; /* Entry that currently has focus. */ TreeViewEntry *activeBtnPtr; /* Pointer to last active button */ TreeViewEntry *fromPtr; TreeViewValue *activeValuePtr; /* Last active value. */ int xScrollUnits, yScrollUnits; /* # of pixels per scroll unit. */ /* Command strings to control horizontal and vertical scrollbars. */ Tcl_Obj *xScrollCmdObjPtr, *yScrollCmdObjPtr; int scrollMode; /* Selects mode of scrolling: either * BLT_SCROLL_MODE_HIERBOX, * BLT_SCROLL_MODE_LISTBOX, or * BLT_SCROLL_MODE_CANVAS. */ /* * Total size of all "open" entries. This represents the range of world * coordinates. */ int worldWidth, worldHeight; int xOffset, yOffset; /* Translation between view port and * world origin. */ short int minHeight; /* Minimum entry height. Used to to * compute what the y-scroll unit * should * be. */ short int titleHeight; /* Height of column titles. */ LevelInfo *levelInfo; /* Scanning information: */ int scanAnchorX, scanAnchorY; /* Scan anchor in screen * coordinates. */ int scanX, scanY; /* X-Y world coordinate where the scan * started. */ Blt_HashTable iconTable; /* Table of Tk images */ Blt_HashTable uidTable; /* Table of strings. */ Blt_HashTable styleTable; /* Table of cell styles. */ Blt_Chain userStyles; /* List of user-created styles. */ TreeViewEntry *rootPtr; /* Root entry of tree. */ TreeViewEntry **visibleArr; /* Array of visible entries. */ int nVisible; /* # of entries in the visible array. */ int nEntries; /* # of entries in tree. */ int treeWidth; /* Computed width of the tree. */ int buttonFlags; /* Global button indicator for all * entries. This may be overridden by * the entry's -button option. */ const char *openCmd, *closeCmd; /* TCL commands to invoke when entries * are opened or closed. */ TreeViewIcon *icons; /* Tk images displayed for the entry. * The first image is the icon * displayed to the left of the * entry's label. The second is icon * displayed when entry is "open". */ TreeViewIcon *activeIcons; /* Tk images displayed for the entry. * The first image is the icon * displayed to the left of the * entry's label. The second is icon * displayed when entry is "open". */ const char *takeFocus; ClientData clientData; Blt_BindTable bindTable; /* Binding information for entries. */ Blt_HashTable entryTagTable; Blt_HashTable buttonTagTable; Blt_HashTable columnTagTable; Blt_HashTable styleTagTable; TreeViewStyle *stylePtr; /* Default style for text cells */ TreeViewColumn treeColumn; TreeViewColumn *activeColumnPtr; TreeViewColumn *activeTitleColumnPtr;/* Column title currently active. */ TreeViewColumn *resizeColumnPtr; /* Column that is being resized. */ size_t depth; int flatView; /* Indicates if the view of the tree * has been flattened. */ TreeViewEntry **flatArr; /* Flattened array of entries. */ const char *sortField; /* Field to be sorted. */ int sortType; /* Type of sorting to be * performed. See below for valid * values. */ Tcl_Obj *sortCmdPtr; /* Sort command. */ int sortDecreasing; /* Indicates entries should be sorted * in decreasing order. */ int viewIsDecreasing; /* Current sorting direction */ TreeViewColumn *sortColumnPtr; /* Column to use for sorting * criteria. */ Tcl_Obj *iconVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * name of the Tk image representing * the icon of the selected item. */ Tcl_Obj *textVarObjPtr; /* Name of TCL variable. If non-NULL, * this variable will be set to the * text string of the label of the * selected item. */ #ifdef notdef Pixmap drawable; /* Pixmap used to cache the entries * displayed. The pixmap is saved so * that only selected elements can be * drawn quicky. */ short int drawWidth, drawHeight; #endif short int ruleAnchor, ruleMark; Blt_Pool entryPool; Blt_Pool valuePool; }; BLT_EXTERN UID Blt_TreeView_GetUid(TreeView *viewPtr, const char *string); BLT_EXTERN void Blt_TreeView_FreeUid(TreeView *viewPtr, UID uid); BLT_EXTERN void Blt_TreeView_EventuallyRedraw(TreeView *viewPtr); BLT_EXTERN Tcl_ObjCmdProc Blt_TreeView_WidgetInstCmd; BLT_EXTERN TreeViewEntry *Blt_TreeView_NearestEntry(TreeView *viewPtr, int x, int y, int flags); BLT_EXTERN const char *Blt_TreeView_GetFullName(TreeView *viewPtr, TreeViewEntry *entryPtr, int checkEntryLabel, Tcl_DString *dsPtr); BLT_EXTERN void Blt_TreeView_SelectCmdProc(ClientData clientData); BLT_EXTERN void Blt_TreeView_InsertText(TreeView *viewPtr, TreeViewEntry *entryPtr, const char *string, int extra, int insertPos); BLT_EXTERN void Blt_TreeView_ComputeLayout(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_PercentSubst(TreeView *viewPtr, TreeViewEntry *entryPtr, const char *command, Tcl_DString *resultPtr); BLT_EXTERN void Blt_TreeView_DrawButton(TreeView *viewPtr, TreeViewEntry *entryPtr, Drawable drawable, int x, int y); BLT_EXTERN void Blt_TreeView_DrawValue(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewValue *valuePtr, Drawable drawable, int x, int y); BLT_EXTERN void Blt_TreeView_DrawOuterBorders(TreeView *viewPtr, Drawable drawable); BLT_EXTERN int Blt_TreeView_DrawLabel(TreeView *viewPtr, TreeViewEntry *entryPtr, Drawable drawable); BLT_EXTERN void Blt_TreeView_DrawHeadings(TreeView *viewPtr, Drawable drawable); BLT_EXTERN void Blt_TreeView_DrawRule(TreeView *viewPtr, TreeViewColumn *colPtr, Drawable drawable); BLT_EXTERN void Blt_TreeView_ConfigureButtons(TreeView *viewPtr); BLT_EXTERN int Blt_TreeView_UpdateWidget(Tcl_Interp *interp, TreeView *viewPtr); BLT_EXTERN int Blt_TreeView_ScreenToIndex(TreeView *viewPtr, int x, int y); BLT_EXTERN void Blt_TreeView_FreeIcon(TreeView *viewPtr, TreeViewIcon icon); BLT_EXTERN TreeViewIcon Blt_TreeView_GetIcon(TreeView *viewPtr, const char *iconName); BLT_EXTERN void Blt_TreeView_AddValue(TreeViewEntry *entryPtr, TreeViewColumn *colPtr); BLT_EXTERN int Blt_TreeView_CreateColumn(TreeView *viewPtr, TreeViewColumn *colPtr, const char *name, const char *defLabel); BLT_EXTERN void Blt_TreeView_DestroyValue(TreeView *viewPtr, TreeViewValue *valuePtr); BLT_EXTERN TreeViewValue *Blt_TreeView_FindValue(TreeViewEntry *entryPtr, TreeViewColumn *colPtr); BLT_EXTERN void Blt_TreeView_DestroyColumns(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_AllocateColumnUids(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_FreeColumnUids(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_ConfigureColumn(TreeView *viewPtr, TreeViewColumn *colPtr); BLT_EXTERN TreeViewColumn *Blt_TreeView_NearestColumn(TreeView *viewPtr, int x, int y, ClientData *contextPtr); BLT_EXTERN int Blt_TreeView_TextOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_TreeView_CreateCombobox(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr); BLT_EXTERN int Blt_TreeView_CreateEntry(TreeView *viewPtr, Blt_TreeNode node, int objc, Tcl_Obj *const *objv, int flags); BLT_EXTERN int Blt_TreeView_ConfigureEntry(TreeView *viewPtr, TreeViewEntry *entryPtr, int objc, Tcl_Obj *const *objv, int flags); BLT_EXTERN int Blt_TreeView_OpenEntry(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN int Blt_TreeView_CloseEntry(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN TreeViewEntry *Blt_TreeView_NextEntry(TreeViewEntry *entryPtr, unsigned int mask); BLT_EXTERN TreeViewEntry *Blt_TreeView_PrevEntry(TreeViewEntry *entryPtr, unsigned int mask); BLT_EXTERN int Blt_TreeView_GetEntry(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewEntry **entryPtrPtr); BLT_EXTERN int Blt_TreeView_EntryIsHidden(TreeViewEntry *entryPtr); BLT_EXTERN TreeViewEntry *Blt_TreeView_NextSibling(TreeViewEntry *entryPtr, unsigned int mask); BLT_EXTERN TreeViewEntry *Blt_TreeView_PrevSibling(TreeViewEntry *entryPtr, unsigned int mask); BLT_EXTERN TreeViewEntry *Blt_TreeView_FirstChild(TreeViewEntry *parentPtr, unsigned int mask); BLT_EXTERN TreeViewEntry *Blt_TreeView_LastChild(TreeViewEntry *entryPtr, unsigned int mask); BLT_EXTERN TreeViewEntry *Blt_TreeView_ParentEntry(TreeViewEntry *entryPtr); typedef int (TreeViewApplyProc)(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN int Blt_TreeView_Apply(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewApplyProc *proc, unsigned int mask); BLT_EXTERN int Blt_TreeView_ColumnOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_TreeView_SortOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN int Blt_TreeView_GetColumn(Tcl_Interp *interp, TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewColumn **colPtrPtr); BLT_EXTERN void Blt_TreeView_SortFlatView(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_SortView(TreeView *viewPtr); BLT_EXTERN int Blt_TreeView_EntryIsSelected(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN void Blt_TreeView_SelectEntry(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN void Blt_TreeView_DeselectEntry(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN void Blt_TreeView_PruneSelection(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN void Blt_TreeView_ClearSelection(TreeView *viewPtr); BLT_EXTERN void Blt_TreeView_ClearTags(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN int Blt_TreeView_FindTaggedEntries(TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewTagIter *iterPtr); BLT_EXTERN TreeViewEntry *Blt_TreeView_FirstTaggedEntry( TreeViewTagIter *iterPtr); BLT_EXTERN TreeViewEntry *Blt_TreeView_NextTaggedEntry( TreeViewTagIter *iterPtr); BLT_EXTERN ClientData Blt_TreeView_ButtonTag(TreeView *viewPtr, const char *string); BLT_EXTERN ClientData Blt_TreeView_EntryTag(TreeView *viewPtr, const char *string); BLT_EXTERN ClientData Blt_TreeView_ColumnTag(TreeView *viewPtr, const char *string); BLT_EXTERN void Blt_TreeView_GetTags(Tcl_Interp *interp, TreeView *viewPtr, TreeViewEntry *entryPtr, Blt_List list); BLT_EXTERN void Blt_TreeView_TraceColumn(TreeView *viewPtr, TreeViewColumn *colPtr); BLT_EXTERN TreeViewIcon Blt_TreeView_GetEntryIcon(TreeView *viewPtr, TreeViewEntry *entryPtr); BLT_EXTERN void Blt_TreeView_SetStyleIcon(TreeView *viewPtr, TreeViewStyle *stylePtr, TreeViewIcon icon); BLT_EXTERN int Blt_TreeView_GetStyle(Tcl_Interp *interp, TreeView *viewPtr, const char *styleName, TreeViewStyle **stylePtrPtr); BLT_EXTERN void Blt_TreeView_FreeStyle(TreeView *viewPtr, TreeViewStyle *stylePtr); BLT_EXTERN TreeViewStyle *Blt_TreeView_CreateStyle(Tcl_Interp *interp, TreeView *viewPtr, int type, const char *styleName); BLT_EXTERN void Blt_TreeView_UpdateStyleGCs(TreeView *viewPtr, TreeViewStyle *stylePtr); BLT_EXTERN Blt_Background Blt_TreeView_GetStyleBackground(TreeView *viewPtr, TreeViewStyle *stylePtr); BLT_EXTERN GC Blt_TreeView_GetStyleGC(TreeViewStyle *stylePtr); BLT_EXTERN Blt_Font Blt_TreeView_GetStyleFont(TreeView *viewPtr, TreeViewStyle *stylePtr); BLT_EXTERN XColor *Blt_TreeView_GetStyleFg(TreeView *viewPtr, TreeViewStyle *stylePtr); BLT_EXTERN TreeViewEntry *Blt_TreeView_NodeToEntry(TreeView *viewPtr, Blt_TreeNode node); BLT_EXTERN int Blt_TreeView_StyleOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); BLT_EXTERN TreeViewEntry *Blt_TreeView_FindEntry(TreeView *viewPtr, Blt_TreeNode node); BLT_EXTERN int Blt_TreeView_CreateTextbox(TreeView *viewPtr, TreeViewEntry *entryPtr, TreeViewColumn *colPtr); #define CHOOSE(default, override) \ (((override) == NULL) ? (default) : (override)) #define GETLABEL(e) \ (((e)->labelUid != NULL)? (e)->labelUid : Blt_Tree_NodeLabel((e)->node)) #define Blt_TreeView_GetData(entryPtr, key, objPtrPtr) \ Blt_Tree_GetValueByKey((Tcl_Interp *)NULL, (entryPtr)->viewPtr->tree, \ (entryPtr)->node, key, objPtrPtr) #endif /* BLT_TREEVIEW_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltVar84.c��������������������������������������������������������������������0000644�0001750�0001750�00000021761�11462120063�014607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltVar84.c -- * * This module implements TCL 8.4 variable handler procedures for the BLT * toolkit. * * Copyright 1997-2008 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltHash.h> #include "bltNsUtil.h" #include "bltVar.h" #include <bltList.h> /* * Variable resolver routines. * * The following bit of magic is from [incr Tcl]. The following routine are * taken from [incr Tcl] to roughly duplicate how TCL internally creates * variables. * * Note: There is no API for the variable resolver routines in the Tcl * library. The resolver callback is supposed to return a Tcl_Var * back. But the definition of Tcl_Var in tcl.h is opaque. */ #define VAR_SCALAR 0x1 #define VAR_ARRAY 0x2 #define VAR_LINK 0x4 #define VAR_UNDEFINED 0x8 #define VAR_IN_HASHTABLE 0x10 #define VAR_TRACE_ACTIVE 0x20 #define VAR_ARRAY_ELEMENT 0x40 #define VAR_NAMESPACE_VAR 0x80 #define VAR_ARGUMENT 0x100 #define VAR_TEMPORARY 0x200 #define VAR_RESOLVED 0x400 typedef struct ArraySearch ArraySearch; typedef struct VarTrace VarTrace; typedef struct Namespace Namespace; typedef struct Var { union { Tcl_Obj *objPtr; /* The variable's object value. Used for * scalar variables and array elements. */ Tcl_HashTable *tablePtr;/* For array variables, this points to * information about the hash table used to * implement the associative array. Points to * malloc-ed data. */ struct Var *linkPtr; /* If this is a global variable being referred * to in a procedure, or a variable created by * "upvar", this field points to the * referenced variable's Var struct. */ } value; char *name; /* NULL if the variable is in a hashtable, * otherwise points to the variable's name. It * is used, e.g., by TclLookupVar and "info * locals". The storage for the characters of * the name is not owned by the Var and must * not be freed when freeing the Var. */ Namespace *nsPtr; /* Points to the namespace that contains this * variable or NULL if the variable is a local * variable in a TCL procedure. */ Tcl_HashEntry *hPtr; /* If variable is in a hashtable, either the * hash table entry that refers to this * variable or NULL if the variable has been * detached from its hash table (e.g. an array * is deleted, but some of its elements are * still referred to in upvars). NULL if the * variable is not in a hashtable. This is * used to delete an variable from its * hashtable if it is no longer needed. */ int refCount; /* Counts number of active uses of this * variable, not including its entry in the * call frame or the hash table: 1 for each * additional variable whose linkPtr points * here, 1 for each nested trace active on * variable, and 1 if the variable is a * namespace variable. This record can't be * deleted until refCount becomes 0. */ VarTrace *tracePtr; /* First in list of all traces set for this * variable. */ ArraySearch *searchPtr; /* First in list of all searches active for * this variable, or NULL if none. */ int flags; /* Miscellaneous bits of information about * variable. See below for definitions. */ } Var; static INLINE Tcl_Namespace * NamespaceOfVariable(Tcl_Var var) { Var *varPtr = (Var *)var; return (Tcl_Namespace *)varPtr->nsPtr; } /* *--------------------------------------------------------------------------- * * NewVar -- * * Create a new heap-allocated variable that will eventually be entered * into a hashtable. * * Results: * The return value is a pointer to the new variable structure. It is * marked as a scalar variable (and not a link or array variable). Its * value initially is NULL. The variable is not part of any hash table * yet. Since it will be in a hashtable and not in a call frame, its name * field is set NULL. It is initially marked as undefined. * * Side effects: * Storage gets allocated. * *--------------------------------------------------------------------------- */ static Var * NewVar(const char *label, Tcl_Obj *objPtr) { Var *varPtr; varPtr = Blt_AssertMalloc(sizeof(Var)); varPtr->value.objPtr = objPtr; #ifdef notdef if (objPtr != NULL) { Tcl_IncrRefCount(objPtr); } #endif varPtr->name = (char *)label; varPtr->nsPtr = NULL; /* * NOTE: TCL reports a "dangling upvar" error for variables * with a null "hPtr" field. Put something non-zero * in here to keep Tcl_SetVar2() happy. The only time * this field is really used is it remove a variable * from the hash table that contains it in CleanupVar, * but since these variables are protected by their * higher refCount, they will not be deleted by CleanupVar * anyway. These variables are unset and removed in * FreeCachedVars. */ varPtr->hPtr = (Tcl_HashEntry *)0x01; varPtr->refCount = 1; /* protect from being deleted */ varPtr->tracePtr = NULL; varPtr->searchPtr = NULL; varPtr->flags = (VAR_SCALAR | VAR_IN_HASHTABLE); return varPtr; } /* *--------------------------------------------------------------------------- * * Blt_GetVariableNamespace -- * * Returns the namespace context of the named variable. The variable * named may be fully qualified or not. Variables in the current * namespace supersede the global namespace. * * Results: * Returns the context of the namespace in an opaque type. If return * value is NULL, this indicates that the variable is local to the call * frame. * *--------------------------------------------------------------------------- */ Tcl_Namespace * Blt_GetVariableNamespace(Tcl_Interp *interp, const char *path) { Blt_ObjectName objName; if (!Blt_ParseObjectName(interp, path, &objName, BLT_NO_DEFAULT_NS)) { return NULL; } if (objName.nsPtr == NULL) { Tcl_Var var; /* Search the current namespace and */ var = Tcl_FindNamespaceVar(interp, (char *)path, NULL, TCL_NAMESPACE_ONLY); if (var != NULL) { return NamespaceOfVariable(var); } /* then search the global namespace. */ var = Tcl_FindNamespaceVar(interp, (char *)path, NULL, TCL_GLOBAL_ONLY); if (var != NULL) { return NamespaceOfVariable(var); } } return objName.nsPtr; } /* *--------------------------------------------------------------------------- * * Blt_GetCachedVar -- * * Returns an opaque TCL variable reference by *name* with the value * pointed to by *objPtr*. The purpose of this routine is to return a * Tcl_Var for a NamespaceResolver callback and to set the value of that * variable. The variable is stored in a hash table associated with the * (temporary) namespace. * * Results: * Returns the opaque type of a Tcl_Var. * * Side Effects: * If the variable does not already exist in the hash table, it is * created. The value of the variable is set to *objPtr*. * *--------------------------------------------------------------------------- */ Tcl_Var Blt_GetCachedVar(Blt_HashTable *tablePtr, const char *label, Tcl_Obj *objPtr) { Blt_HashEntry *hPtr; int isNew; Var *varPtr; /* Check if the variable has been cached already. */ hPtr = Blt_CreateHashEntry(tablePtr, label, &isNew); if (isNew) { varPtr = NewVar(label, objPtr); Blt_SetHashValue(hPtr, varPtr); } else { varPtr = Blt_GetHashValue(hPtr); varPtr->value.objPtr = objPtr; #ifdef notdef if (objPtr != NULL) { Tcl_IncrRefCount(objPtr); } #endif } return (Tcl_Var)varPtr; } void Blt_FreeCachedVars(Blt_HashTable *tablePtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; for (hPtr = Blt_FirstHashEntry(tablePtr, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { Var *varPtr; varPtr = Blt_GetHashValue(hPtr); varPtr->refCount--; if (varPtr->refCount > 1) { #ifdef notdef if (varPtr->value.objPtr != NULL) { Tcl_DecrRefCount(varPtr->value.objPtr); } #endif Blt_Free(varPtr); } } Blt_DeleteHashTable(tablePtr); } ���������������./saods9/blt3.0.1/src/bltDebug.c��������������������������������������������������������������������0000644�0001750�0001750�00000026121�11462120062�014723� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltDebug.c -- * * Copyright 1993-1998 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #ifndef NO_BLTDEBUG #define DEBUG_THREAD_KEY "BLT Debug Command Data" #define MAX_STACK 2048 #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif /* HAVE_SYS_TIME_H */ #endif /* TIME_WITH_SYS_TIME */ #include "bltChain.h" static Tcl_CmdObjTraceProc DebugProc; static Tcl_ObjCmdProc DebugCmd; typedef struct { const char *pattern; Tcl_Obj *nameObjPtr; } Watch; typedef struct { Blt_Chain chain; /* Chain of watches. */ Tcl_Interp *interp; unsigned char *stack; } DebugCmdInterpData; #define SETBIT(i) \ dataPtr->stack[(i) >> 3] |= (1 << ((i) & 0x07)) #define GETBIT(i) \ (dataPtr->stack[(i) >> 3] & (1 << ((i) & 0x07))) #define UNSETBIT(i) \ dataPtr->stack[(i) >> 3] &= ~(1 << ((i) & 0x07)) /* *--------------------------------------------------------------------------- * * DebugInterpDeleteProc -- * * This is called when the interpreter hosting the "debug" command * is deleted. * * Results: * None. * * Side effects: * Removes the hash table managing all debug names. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void DebugInterpDeleteProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp) { DebugCmdInterpData *dataPtr = clientData; /* All debug instances should already have been destroyed when * their respective TCL commands were deleted. */ Blt_Chain_Destroy(dataPtr->chain); Tcl_DeleteAssocData(interp, DEBUG_THREAD_KEY); Blt_Free(dataPtr->stack); Blt_Free(dataPtr); } /* *--------------------------------------------------------------------------- * * GetDebugCmdInterpData -- * *--------------------------------------------------------------------------- */ static DebugCmdInterpData * GetDebugCmdInterpData(Tcl_Interp *interp) { DebugCmdInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (DebugCmdInterpData *) Tcl_GetAssocData(interp, DEBUG_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(DebugCmdInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, DEBUG_THREAD_KEY, DebugInterpDeleteProc, dataPtr); dataPtr->chain = Blt_Chain_Create(); dataPtr->stack = Blt_Malloc(MAX_STACK); } return dataPtr; } static Watch * GetWatch(DebugCmdInterpData *dataPtr, Tcl_Obj *objPtr) { Blt_ChainLink link; char c; Watch *watchPtr; char *name, *string; name = Tcl_GetString(objPtr); c = name[0]; for (link = Blt_Chain_FirstLink(dataPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { watchPtr = Blt_Chain_GetValue(link); string = Tcl_GetString(watchPtr->nameObjPtr); if ((string[0] == c) && (strcmp(name, string) == 0)) { return watchPtr; } } link = Blt_Chain_AllocLink(sizeof(Watch)); watchPtr = Blt_Chain_GetValue(link); watchPtr->nameObjPtr = objPtr; Tcl_IncrRefCount(objPtr); /* Prepend watch onto chain. */ Blt_Chain_LinkBefore(dataPtr->chain, link, (Blt_ChainLink)NULL); return watchPtr; } static void DeleteWatch(DebugCmdInterpData *dataPtr, Tcl_Obj *objPtr) { Blt_ChainLink link; char c; char *name; name = Tcl_GetString(objPtr); c = name[0]; for (link = Blt_Chain_FirstLink(dataPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Watch *watchPtr; char *string; watchPtr = Blt_Chain_GetValue(link); string = Tcl_GetString(watchPtr->nameObjPtr); if ((string[0] == c) && (strcmp(name, string) == 0)) { Tcl_DecrRefCount(watchPtr->nameObjPtr); Blt_Chain_DeleteLink(dataPtr->chain, link); return; } } } /*ARGSUSED*/ static int DebugProc( ClientData clientData, /* Interpreter-specific data. */ Tcl_Interp *interp, /* Not used. */ int level, /* Current level */ const char *command, /* Command before substitution */ Tcl_Command token, /* Not used. */ int objc, Tcl_Obj *const *objv) /* Command after parsing, but before * evaluation */ { DebugCmdInterpData *dataPtr = clientData; Tcl_Channel errChannel; Tcl_DString dString; const char *lineStart; const char *string; char prompt[200]; int count; const char *p; int i; Tcl_Obj *listObjPtr, *objPtr; /* This is pretty crappy, but there's no way to trigger stack pops */ for (i = level + 1; i < MAX_STACK; i++) { UNSETBIT(i); } if (Blt_Chain_GetLength(dataPtr->chain) > 0) { int found; Blt_ChainLink link; found = FALSE; for (link = Blt_Chain_FirstLink(dataPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { Watch *watchPtr; const char *cmd, *pattern; watchPtr = Blt_Chain_GetValue(link); cmd = Tcl_GetString(objv[0]); pattern = Tcl_GetString(watchPtr->nameObjPtr); if (Tcl_StringMatch(cmd, pattern)) { found = TRUE; break; } } if ((found) && (level < MAX_STACK)) { SETBIT(level), SETBIT(level + 1); } if ((level >= MAX_STACK) || (!GETBIT(level))) { return TCL_OK; } } /* * Use stderr channel, for compatibility with systems that don't have a * tty (like WIN32). In reality, it doesn't make a difference since Tk's * Win32 console can't handle large streams of data anyways. */ errChannel = Tcl_GetStdChannel(TCL_STDERR); if (errChannel == NULL) { Tcl_AppendResult(interp, "can't get stderr channel", (char *)NULL); Tcl_BackgroundError(interp); return TCL_ERROR; } Tcl_DStringInit(&dString); sprintf_s(prompt, 200, "%-2d-> ", level); p = command; /* Skip leading spaces in command line. */ while(isspace(UCHAR(*p))) { p++; } lineStart = p; count = 0; while (*p != '\0') { if (*p == '\n') { if (count > 0) { Tcl_DStringAppend(&dString, " ", -1); } else { Tcl_DStringAppend(&dString, prompt, -1); } Tcl_DStringAppend(&dString, lineStart, p - lineStart); Tcl_DStringAppend(&dString, "\n", -1); p++; lineStart = p; count++; if (count > 6) { break; /* Stop after 6 lines. */ } } else { p++; } } while (isspace(UCHAR(*lineStart))) { lineStart++; } if (lineStart < p) { if (count > 0) { Tcl_DStringAppend(&dString, " ", -1); } else { Tcl_DStringAppend(&dString, prompt, -1); } Tcl_DStringAppend(&dString, lineStart, p - lineStart); if (count <= 6) { Tcl_DStringAppend(&dString, "\n", -1); } } if (count > 6) { Tcl_DStringAppend(&dString, " ...\n", -1); } listObjPtr = Tcl_NewListObj(objc, objv); Tcl_IncrRefCount(listObjPtr); #ifdef notdef objPtr = Tcl_SubstObj(interp, listObjPtr, TCL_SUBST_VARIABLES); #else objPtr = NULL; #endif if (objPtr == NULL) { string = Tcl_GetString(listObjPtr); } else { Tcl_IncrRefCount(objPtr); string = Tcl_GetString(objPtr); } lineStart = string; sprintf_s(prompt, 200, " <- "); count = 0; for (p = string; *p != '\0'; /* empty */) { if (*p == '\n') { if (count > 0) { Tcl_DStringAppend(&dString, " ", -1); } else { Tcl_DStringAppend(&dString, prompt, -1); } count++; Tcl_DStringAppend(&dString, lineStart, p - lineStart); Tcl_DStringAppend(&dString, "\n", -1); p++; lineStart = p; if (count > 6) { break; } } else { p++; } } if (lineStart < p) { if (count > 0) { Tcl_DStringAppend(&dString, " ", -1); } else { Tcl_DStringAppend(&dString, prompt, -1); } Tcl_DStringAppend(&dString, lineStart, p - lineStart); if (count <= 6) { Tcl_DStringAppend(&dString, "\n", -1); } } if (count > 6) { Tcl_DStringAppend(&dString, " ...\n", -1); } Tcl_DStringAppend(&dString, "\n", -1); Tcl_DecrRefCount(listObjPtr); if (objPtr != NULL) { Tcl_DecrRefCount(objPtr); } Tcl_Write(errChannel, (char *)Tcl_DStringValue(&dString), -1); Tcl_Flush(errChannel); Tcl_DStringFree(&dString); return TCL_OK; } /*ARGSUSED*/ static int DebugCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link; DebugCmdInterpData *dataPtr = clientData; Tcl_Obj *listObjPtr; Watch *watchPtr; const char *string; char c; int newLevel; int i; int length; static Tcl_Trace token; static int level; if (objc == 1) { Tcl_SetIntObj(Tcl_GetObjResult(interp), level); return TCL_OK; } string = Tcl_GetStringFromObj(objv[1], &length); c = string[0]; if ((c == 'w') && (strncmp(string, "watch", length) == 0)) { /* Add patterns of command names to watch to the chain */ for (i = 2; i < objc; i++) { GetWatch(dataPtr, objv[i]); } } else if ((c == 'i') && (strncmp(string, "ignore", length) == 0)) { for (i = 2; i < objc; i++) { DeleteWatch(dataPtr, objv[i]); } } else { goto levelTest; } /* Return the current watch patterns */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (link = Blt_Chain_FirstLink(dataPtr->chain); link != NULL; link = Blt_Chain_NextLink(link)) { watchPtr = Blt_Chain_GetValue(link); Tcl_ListObjAppendElement(interp, listObjPtr, watchPtr->nameObjPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; levelTest: if (Tcl_GetBooleanFromObj(interp, objv[1], &newLevel) == TCL_OK) { if (newLevel > 0) { newLevel = 10000; /* Max out the level */ } } else if (Tcl_GetIntFromObj(interp, objv[1], &newLevel) == TCL_OK) { if (newLevel < 0) { newLevel = 0; } } else { return TCL_ERROR; } if (token != 0) { Tcl_DeleteTrace(interp, token); } if (newLevel > 0) { token = Tcl_CreateObjTrace(interp, newLevel, 0, DebugProc, dataPtr, NULL); } level = newLevel; Tcl_SetIntObj(Tcl_GetObjResult(interp), level); return TCL_OK; } int Blt_DebugCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = {"debug", DebugCmd,}; cmdSpec.clientData = GetDebugCmdInterpData(interp); return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_BLTDEBUG */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixBgexec.c���������������������������������������������������������������0000644�0001750�0001750�00000177411�11462120063�015750� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixBgexec.c -- * * This module implements a background "exec" command for the BLT toolkit. * * Copyright 2010 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define _GNU_SOURCE #define _XOPEN_SOURCE #include "bltInt.h" #ifndef NO_BGEXEC #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ #include <sys/ioctl.h> #include <fcntl.h> #include <signal.h> #include <sys/types.h> #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif #ifdef HAVE_STROPTS_H #include <stropts.h> #endif /* HAVE_STROPTS_H */ #ifdef HAVE_TERMIOS_H #include <termios.h> #include <unistd.h> #endif /* HAVE_TERMIOS_H */ #include "bltWait.h" #include "bltSwitch.h" #include "bltChain.h" static Tcl_ObjCmdProc BgexecCmd; #if (_TCL_VERSION < _VERSION(8,1,0)) typedef void *Tcl_Encoding; /* Make up dummy type for encoding. */ #endif #define ENCODING_ASCII ((Tcl_Encoding)NULL) #define ENCODING_BINARY ((Tcl_Encoding)1) #define BGEXEC_THREAD_KEY "BLT Bgexec Data" #define READ_AGAIN (0) #define READ_EOF (-1) #define READ_ERROR (-2) #define PTY_NAME_SIZE 32 /* The wait-related definitions are taken from tclUnix.h */ #define TRACE_FLAGS (TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY) #define BLOCK_SIZE 1024 /* Size of allocation blocks for * buffer */ #define DEF_BUFFER_SIZE (BLOCK_SIZE * 8) #define MAX_READS 100 /* Maximum # of successful reads * before stopping to let TCL catch up * on events */ #ifndef NSIG #define NSIG 32 /* # of signals available */ #endif /*NSIG*/ #ifndef SIGINT #define SIGINT 2 #endif /* SIGINT */ #ifndef SIGQUIT #define SIGQUIT 3 #endif /* SIGQUIT */ #ifndef SIGKILL #define SIGKILL 9 #endif /* SIGKILL */ #ifndef SIGTERM #define SIGTERM 14 #endif /* SIGTERM */ typedef struct { int number; const char *name; } SignalToken; static SignalToken signalTokens[] = { #ifdef SIGABRT {SIGABRT, "SIGABRT"}, #endif #ifdef SIGALRM {SIGALRM, "SIGALRM"}, #endif #ifdef SIGBUS {SIGBUS, "SIGBUS"}, #endif #ifdef SIGCHLD {SIGCHLD, "SIGCHLD"}, #endif #if defined(SIGCLD) && (!defined(SIGCHLD) || (SIGCLD != SIGCHLD)) {SIGCLD, "SIGCLD"}, #endif #ifdef SIGCONT {SIGCONT, "SIGCONT"}, #endif #if defined(SIGEMT) && (!defined(SIGXCPU) || (SIGEMT != SIGXCPU)) {SIGEMT, "SIGEMT"}, #endif #ifdef SIGFPE {SIGFPE, "SIGFPE"}, #endif #ifdef SIGHUP {SIGHUP, "SIGHUP"}, #endif #ifdef SIGILL {SIGILL, "SIGILL"}, #endif #ifdef SIGINT {SIGINT, "SIGINT"}, #endif #ifdef SIGIO {SIGIO, "SIGIO"}, #endif #if defined(SIGIOT) && (!defined(SIGABRT) || (SIGIOT != SIGABRT)) {SIGIOT, "SIGIOT"}, #endif #ifdef SIGKILL {SIGKILL, "SIGKILL"}, #endif #if defined(SIGLOST) && (!defined(SIGIOT) || (SIGLOST != SIGIOT)) && (!defined(SIGURG) || (SIGLOST != SIGURG)) {SIGLOST, "SIGLOST"}, #endif #ifdef SIGPIPE {SIGPIPE, "SIGPIPE"}, #endif #if defined(SIGPOLL) && (!defined(SIGIO) || (SIGPOLL != SIGIO)) {SIGPOLL, "SIGPOLL"}, #endif #ifdef SIGPROF {SIGPROF, "SIGPROF"}, #endif #if defined(SIGPWR) && (!defined(SIGXFSZ) || (SIGPWR != SIGXFSZ)) {SIGPWR, "SIGPWR"}, #endif #ifdef SIGQUIT {SIGQUIT, "SIGQUIT"}, #endif #ifdef SIGSEGV {SIGSEGV, "SIGSEGV"}, #endif #ifdef SIGSTOP {SIGSTOP, "SIGSTOP"}, #endif #ifdef SIGSYS {SIGSYS, "SIGSYS"}, #endif #ifdef SIGTERM {SIGTERM, "SIGTERM"}, #endif #ifdef SIGTRAP {SIGTRAP, "SIGTRAP"}, #endif #ifdef SIGTSTP {SIGTSTP, "SIGTSTP"}, #endif #ifdef SIGTTIN {SIGTTIN, "SIGTTIN"}, #endif #ifdef SIGTTOU {SIGTTOU, "SIGTTOU"}, #endif #if defined(SIGURG) && (!defined(SIGIO) || (SIGURG != SIGIO)) {SIGURG, "SIGURG"}, #endif #if defined(SIGUSR1) && (!defined(SIGIO) || (SIGUSR1 != SIGIO)) {SIGUSR1, "SIGUSR1"}, #endif #if defined(SIGUSR2) && (!defined(SIGURG) || (SIGUSR2 != SIGURG)) {SIGUSR2, "SIGUSR2"}, #endif #ifdef SIGVTALRM {SIGVTALRM, "SIGVTALRM"}, #endif #ifdef SIGWINCH {SIGWINCH, "SIGWINCH"}, #endif #ifdef SIGXCPU {SIGXCPU, "SIGXCPU"}, #endif #ifdef SIGXFSZ {SIGXFSZ, "SIGXFSZ"}, #endif {-1, "unknown signal"}, }; #ifdef TCL_THREADS static Tcl_Mutex *mutexPtr = NULL; #endif static Blt_Chain activePipelines; /* List of active pipelines and their * ptyexec structures. */ /* * Sink buffer: * ____________________ * | | "size" current allocated length of buffer. * | | * |--------------------| "fill" fill point (# characters in buffer). * | Raw | * |--------------------| "mark" Marks end of cooked characters. * | | * | Cooked | * | | * | | * |--------------------| "lastMark" Mark end of processed characters. * | | * | | * | Processed | * | | * |____________________| 0 */ typedef struct { const char *name; /* Name of the sink. */ const char *doneVar; /* Name of a TCL variable (malloc'ed) * set to the collected data of the * last UNIX * subprocess. */ const char *updateVar; /* Name of a TCL variable (malloc'ed) * updated as data is read from the * pipe. */ Tcl_Obj *cmdObjPtr; /* Start of a TCL command executed * whenever data is read from the * pipe. */ int flags; Tcl_Encoding encoding; /* Decoding scheme to use when * translating data. */ int fd; /* File descriptor of the pipe. */ int status; int echo; /* Indicates if the pipeline's stderr * stream should be echoed */ unsigned char *bytes; /* Stores pipeline output (malloc-ed): * Initially points to static * storage */ int size; /* Size of dynamically allocated * buffer. */ int fill; /* # of bytes read into the * buffer. Marks the current fill * point of the buffer. */ int mark; /* # of bytes translated (cooked). */ int lastMark; /* # of bytes as of the last read. This * indicates the start of the new data * in the buffer since the last time * the "update" variable was set. */ unsigned char staticSpace[DEF_BUFFER_SIZE]; /* Static space */ } Sink; #define SINK_BUFFERED (1<<0) #define SINK_KEEP_NL (1<<1) #define SINK_NOTIFY (1<<2) typedef struct { const char *statusVar; /* Name of a TCL variable set to the * exit status of the last * process. Setting this variable * triggers the termination of all * subprocesses (regardless whether * they have already completed) */ int signalNum; /* If non-zero, indicates the signal * to send subprocesses when cleaning * up.*/ unsigned int flags; /* Various bit flags: see below. */ int interval; /* Interval to poll for the exiting * processes */ /* Private */ Tcl_Interp *interp; /* Interpreter containing variables */ int nProcs; /* # of processes in pipeline */ ProcessId *procIds; /* Array of process tokens from * pipeline. Under Unix, tokens are * pid_t, while for Win32 they're * handles. */ Tcl_TimerToken timerToken; /* Token for timer handler which polls * for the exit status of each * sub-process. If zero, there's no * timer handler queued. */ int *exitCodePtr; /* Pointer to a memory location to * contain the last process' exit * code. */ int *donePtr; Sink err, out; /* Data sinks for pipeline's output * and error channels. */ Blt_ChainLink link; int master; /* File descriptor of master. */ int slave; /* File descriptor of slave. */ char masterName[PTY_NAME_SIZE+1]; char slaveName[PTY_NAME_SIZE+1]; pid_t sid; /* Pid of session leader. */ } Bgexec; #define KEEPNEWLINE (1<<0) /* Indicates to set TCL output * variables with trailing newlines * intact */ #define LINEBUFFERED (1<<1) /* Indicates to provide data to update * variable and update proc on a * line-by-line * basis. */ #define IGNOREEXITCODE (1<<2) /* Don't check for 0 exit status of * the pipeline. */ #define TRACED (1<<3) /* Indicates that the status variable * is currently being traced. */ #define DETACHED (1<<4) /* Indicates that the pipeline is * detached from standard I/O, running * in the background. */ #define KILLED (1<<5) /* The variable trace has been triggered * so ignore any errors from a broken * connection. */ static Blt_SwitchParseProc ObjToSignalProc; static Blt_SwitchCustom killSignalSwitch = { ObjToSignalProc, NULL, (ClientData)0, }; static Blt_SwitchParseProc ObjToEncodingProc; static Blt_SwitchFreeProc FreeEncodingProc; static Blt_SwitchCustom encodingSwitch = { ObjToEncodingProc, FreeEncodingProc, (ClientData)0, }; static Blt_SwitchSpec switchSpecs[] = { {BLT_SWITCH_CUSTOM, "-decodeoutput", "encoding", Blt_Offset(Bgexec, out.encoding), 0, 0, &encodingSwitch}, {BLT_SWITCH_CUSTOM, "-decodeerror", "encoding", Blt_Offset(Bgexec, err.encoding), 0, 0, &encodingSwitch}, {BLT_SWITCH_BOOLEAN, "-echo", "bool", Blt_Offset(Bgexec, err.echo), 0}, {BLT_SWITCH_STRING, "-error", "variable", Blt_Offset(Bgexec, err.doneVar), 0}, {BLT_SWITCH_STRING, "-update", "variable", Blt_Offset(Bgexec, out.updateVar), 0}, {BLT_SWITCH_STRING, "-output", "variable", Blt_Offset(Bgexec, out.doneVar), 0}, {BLT_SWITCH_STRING, "-lasterror", "variable", Blt_Offset(Bgexec, err.updateVar), 0}, {BLT_SWITCH_STRING, "-lastoutput", "variable", Blt_Offset(Bgexec, out.updateVar), 0}, {BLT_SWITCH_OBJ, "-onerror", "command", Blt_Offset(Bgexec, err.cmdObjPtr), 0}, {BLT_SWITCH_OBJ, "-onoutput", "command", Blt_Offset(Bgexec, out.cmdObjPtr), 0}, {BLT_SWITCH_BOOLEAN, "-keepnewline", "bool", Blt_Offset(Bgexec, flags), 0, KEEPNEWLINE}, {BLT_SWITCH_INT, "-check", "interval", Blt_Offset(Bgexec, interval), 0}, {BLT_SWITCH_CUSTOM, "-killsignal", "signal", Blt_Offset(Bgexec, signalNum), 0, 0, &killSignalSwitch}, {BLT_SWITCH_BOOLEAN, "-linebuffered", "bool", Blt_Offset(Bgexec, flags), 0, LINEBUFFERED}, {BLT_SWITCH_BOOLEAN, "-ignoreexitcode", "bool", Blt_Offset(Bgexec, flags), 0, IGNOREEXITCODE}, {BLT_SWITCH_STRING, "-variable", "variable", Blt_Offset(Bgexec, statusVar), 0}, {BLT_SWITCH_END} }; static Tcl_VarTraceProc VariableProc; static Tcl_TimerProc TimerProc; static Tcl_FileProc StdoutProc, StderrProc; static Tcl_ExitProc BgexecExitProc; /* *--------------------------------------------------------------------------- * * ObjToSignalProc -- * * Convert a Tcl_Obj representing a signal number into its integer * value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSignalProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Intrepreter to return results */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Value representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { char *string; int *signalPtr = (int *)(record + offset); int signalNum; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *signalPtr = 0; return TCL_OK; } if (isdigit(UCHAR(string[0]))) { if (Tcl_GetIntFromObj(interp, objPtr, &signalNum) != TCL_OK) { return TCL_ERROR; } } else { char *name; SignalToken *sp; name = string; /* Clip off any "SIG" prefix from the signal name */ if ((name[0] == 'S') && (name[1] == 'I') && (name[2] == 'G')) { name += 3; } signalNum = -1; for (sp = signalTokens; sp->number > 0; sp++) { if (strcmp(sp->name + 3, name) == 0) { signalNum = sp->number; break; } } if (signalNum < 0) { Tcl_AppendResult(interp, "unknown signal \"", string, "\"", (char *)NULL); return TCL_ERROR; } } if ((signalNum < 0) || (signalNum > NSIG)) { /* Outside range of signals */ Tcl_AppendResult(interp, "signal number \"", string, "\" is out of range", (char *)NULL); return TCL_ERROR; } *signalPtr = signalNum; return TCL_OK; } /* *--------------------------------------------------------------------------- * * ObjToEncodingProc -- * * Convert a Tcl_Obj representing a encoding into a Tcl_Encoding. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToEncodingProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Intrepreter to return results */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* Value representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Tcl_Encoding *encodingPtr = (Tcl_Encoding *)(record + offset); Tcl_Encoding encoding; const char *name; name = Tcl_GetString(objPtr); encoding = ENCODING_ASCII; if (name != NULL) { if (strcmp(name, "binary") == 0) { encoding = ENCODING_BINARY; } else { #if (_TCL_VERSION >= _VERSION(8,1,0)) encoding = Tcl_GetEncoding(interp, name); if (encoding == NULL) { return TCL_ERROR; } #endif } } if ((*encodingPtr != ENCODING_BINARY) && (*encodingPtr != ENCODING_ASCII)) { Tcl_FreeEncoding(*encodingPtr); } *encodingPtr = encoding; return TCL_OK; } /*ARGSUSED*/ static void FreeEncodingProc(char *record, int offset, int flags) { Tcl_Encoding *encodingPtr = (Tcl_Encoding *)(record + offset); if ((*encodingPtr != ENCODING_BINARY) && (*encodingPtr != ENCODING_ASCII)) { Tcl_FreeEncoding(*encodingPtr); } } /* *--------------------------------------------------------------------------- * * GetSinkData -- * * Returns the data currently saved in the buffer * *--------------------------------------------------------------------------- */ static void GetSinkData(Sink *sinkPtr, unsigned char **dataPtr, int *lengthPtr) { int length; sinkPtr->bytes[sinkPtr->mark] = '\0'; length = sinkPtr->mark; if ((sinkPtr->mark > 0) && (sinkPtr->encoding != ENCODING_BINARY)) { unsigned char *last; last = sinkPtr->bytes + (sinkPtr->mark - 1); if (((sinkPtr->flags & SINK_KEEP_NL) == 0) && (*last == '\n')) { length--; } } *dataPtr = sinkPtr->bytes; *lengthPtr = length; } /* *--------------------------------------------------------------------------- * * NextBlock -- * * Returns the next block of data since the last time this routine was * called. * *--------------------------------------------------------------------------- */ static unsigned char * NextBlock(Sink *sinkPtr, size_t *lengthPtr) { unsigned char *string; ptrdiff_t length; string = sinkPtr->bytes + sinkPtr->lastMark; length = sinkPtr->mark - sinkPtr->lastMark; sinkPtr->lastMark = sinkPtr->mark; if (length > 0) { if ((!(sinkPtr->flags & SINK_KEEP_NL)) && (string[length-1] == '\n')) { length--; } *lengthPtr = length; return string; } return NULL; } /* *--------------------------------------------------------------------------- * * NextLine -- * * Returns the next line of data. * *--------------------------------------------------------------------------- */ static unsigned char * NextLine(Sink *sinkPtr, size_t *lengthPtr) { if (sinkPtr->mark > sinkPtr->lastMark) { unsigned char *string; size_t newBytes; int i; string = sinkPtr->bytes + sinkPtr->lastMark; newBytes = sinkPtr->mark - sinkPtr->lastMark; for (i = 0; i < newBytes; i++) { if (string[i] == '\n') { int length; length = i + 1; sinkPtr->lastMark += length; if (!(sinkPtr->flags & SINK_KEEP_NL)) { length--; /* Backup over the newline. */ } *lengthPtr = length; return string; } } /* Newline not found. On errors or EOF, also return a partial line. */ if (sinkPtr->status < 0) { *lengthPtr = newBytes; sinkPtr->lastMark = sinkPtr->mark; return string; } } return NULL; } /* *--------------------------------------------------------------------------- * * ResetSink -- * * Removes the bytes already processed from the buffer, possibly * resetting it to empty. This used when we don't care about keeping all * the data collected from the channel (no -output flag and the process * is detached). * *--------------------------------------------------------------------------- */ static void ResetSink(Sink *sinkPtr) { if ((sinkPtr->flags & SINK_BUFFERED) && (sinkPtr->fill > sinkPtr->lastMark)) { int i, j; /* There may be bytes remaining in the buffer, awaiting another read * before we see the next newline. So move the bytes to the front of * the array. */ for (i = 0, j = sinkPtr->lastMark; j < sinkPtr->fill; i++, j++) { sinkPtr->bytes[i] = sinkPtr->bytes[j]; } /* Move back the fill point and processed point. */ sinkPtr->fill -= sinkPtr->lastMark; sinkPtr->mark -= sinkPtr->lastMark; } else { sinkPtr->mark = sinkPtr->fill = 0; } sinkPtr->lastMark = 0; } /* *--------------------------------------------------------------------------- * * InitSink -- * * Initializes the buffer's storage. * * Results: * None. * * Side effects: * Storage is cleared. * *--------------------------------------------------------------------------- */ static void InitSink(Bgexec *execPtr, Sink *sinkPtr, const char *name) { sinkPtr->name = name; sinkPtr->echo = FALSE; sinkPtr->fd = -1; sinkPtr->bytes = sinkPtr->staticSpace; sinkPtr->size = DEF_BUFFER_SIZE; if (execPtr->flags & KEEPNEWLINE) { sinkPtr->flags |= SINK_KEEP_NL; } if (execPtr->flags & LINEBUFFERED) { sinkPtr->flags |= SINK_BUFFERED; } if ((sinkPtr->cmdObjPtr != NULL) || (sinkPtr->updateVar != NULL) || (sinkPtr->echo)) { sinkPtr->flags |= SINK_NOTIFY; } ResetSink(sinkPtr); } /* *--------------------------------------------------------------------------- * * FreeSinkBuffer -- * * Frees the buffer's storage, freeing any malloc'ed space. * * Results: * None. * *--------------------------------------------------------------------------- */ static void FreeSinkBuffer(Sink *sinkPtr) { if (sinkPtr->bytes != sinkPtr->staticSpace) { Blt_Free(sinkPtr->bytes); } sinkPtr->fd = -1; } /* *--------------------------------------------------------------------------- * * ExtendSinkBuffer -- * * Doubles the size of the current buffer. * * Results: * None. * *--------------------------------------------------------------------------- */ static int ExtendSinkBuffer(Sink *sinkPtr) { unsigned char *bytes; /* * Allocate a new array, double the old size */ sinkPtr->size += sinkPtr->size; bytes = Blt_Malloc(sizeof(unsigned char) * sinkPtr->size); if (bytes != NULL) { unsigned char *sp, *dp, *send; dp = bytes; for (sp = sinkPtr->bytes, send = sp + sinkPtr->fill; sp < send; /*empty*/) { *dp++ = *sp++; } if (sinkPtr->bytes != sinkPtr->staticSpace) { Blt_Free(sinkPtr->bytes); } sinkPtr->bytes = bytes; return (sinkPtr->size - sinkPtr->fill); /* Return bytes left. */ } return -1; } /* *--------------------------------------------------------------------------- * * ReadBytes -- * * Reads and appends any available data from a given file descriptor * to the buffer. * * Results: * Returns TCL_OK when EOF is found, TCL_RETURN if reading data would * block, and TCL_ERROR if an error occurred. * *--------------------------------------------------------------------------- */ static void ReadBytes(Sink *sinkPtr) { int i; int nBytes; /* * Worry about indefinite postponement. * * Typically we want to stay in the read loop as long as it takes to * collect all the data that's currently available. But if it's coming * in at a constant high rate, we need to arbitrarily break out at some * point. This allows for both setting the update variable and the Tk * program to handle idle events. */ nBytes = 0; for (i = 0; i < MAX_READS; i++) { int bytesLeft; unsigned char *array; /* Allocate a larger buffer when the number of remaining bytes is * below the threshold BLOCK_SIZE. */ bytesLeft = sinkPtr->size - sinkPtr->fill; if (bytesLeft < BLOCK_SIZE) { bytesLeft = ExtendSinkBuffer(sinkPtr); if (bytesLeft < 0) { errno = ENOMEM; sinkPtr->status = READ_ERROR; return; } } array = sinkPtr->bytes + sinkPtr->fill; /* Read into a buffer but make sure we leave room for a trailing NUL * byte. */ nBytes = read(sinkPtr->fd, array, bytesLeft - 1); if (nBytes == 0) { /* EOF: break out of loop. */ sinkPtr->status = READ_EOF; return; } if (nBytes < 0) { #ifdef O_NONBLOCK #define BLOCKED EAGAIN #else #define BLOCKED EWOULDBLOCK #endif /*O_NONBLOCK*/ /* Either an error has occurred or no more data is currently * available to read. */ if (errno == BLOCKED) { sinkPtr->status = READ_AGAIN; return; } sinkPtr->bytes[0] = '\0'; sinkPtr->status = READ_ERROR; return; } sinkPtr->fill += nBytes; sinkPtr->bytes[sinkPtr->fill] = '\0'; } sinkPtr->status = nBytes; } #define SINKOPEN(sinkPtr) ((sinkPtr)->fd != -1) static void CloseSink(Tcl_Interp *interp, Sink *sinkPtr) { if (SINKOPEN(sinkPtr)) { close(sinkPtr->fd); Tcl_DeleteFileHandler(sinkPtr->fd); sinkPtr->fd = -1; if (sinkPtr->doneVar != NULL) { unsigned char *data; int length; /* * If data is to be collected, set the "done" variable with the * contents of the buffer. */ GetSinkData(sinkPtr, &data, &length); #if (_TCL_VERSION < _VERSION(8,1,0)) data[length] = '\0'; if (Tcl_SetVar(interp, sinkPtr->doneVar, data, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } #else if (Tcl_SetVar2Ex(interp, sinkPtr->doneVar, NULL, Tcl_NewByteArrayObj(data, (int)length), TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } #endif } } } /* *--------------------------------------------------------------------------- * * CookSink -- * * For Windows, translate CR/NL combinations to NL alone. * * Results: * None. * * Side Effects: * The size of the byte array may shrink and array contents shifted as * carriage returns are found and removed. * *--------------------------------------------------------------------------- */ static void CookSink(Tcl_Interp *interp, Sink *sinkPtr) { unsigned char *srcPtr, *endPtr; #ifdef WIN32 int oldMark; oldMark = sinkPtr->mark; #endif if (sinkPtr->encoding == ENCODING_BINARY) { /* binary */ /* No translation needed. */ sinkPtr->mark = sinkPtr->fill; } else if (sinkPtr->encoding == ENCODING_ASCII) { /* ascii */ #if (_TCL_VERSION < _VERSION(8,1,0)) /* Convert NUL bytes to question marks. */ srcPtr = sinkPtr->bytes + sinkPtr->mark; endPtr = sinkPtr->bytes + sinkPtr->fill; while (srcPtr < endPtr) { if (*srcPtr == '\0') { *srcPtr = '?'; } srcPtr++; } #endif /* < 8.1.0 */ /* One-to-one translation. mark == fill. */ sinkPtr->mark = sinkPtr->fill; #if (_TCL_VERSION >= _VERSION(8,1,0)) } else { /* unicode. */ int nSrcCooked, nCooked; int result; int cookedSize, spaceLeft, needed; int nRaw, nLeftOver; unsigned char *destPtr; unsigned char *raw, *cooked; unsigned char leftover[100]; raw = sinkPtr->bytes + sinkPtr->mark; nRaw = sinkPtr->fill - sinkPtr->mark; /* Ideally, the cooked buffer size should be smaller */ cookedSize = nRaw * TCL_UTF_MAX + 1; cooked = Blt_AssertMalloc(cookedSize); result = Tcl_ExternalToUtf(interp, sinkPtr->encoding, (char *)raw, nRaw, 0, NULL, (char *)cooked, cookedSize, &nSrcCooked, &nCooked, NULL); nLeftOver = 0; if (result == TCL_CONVERT_MULTIBYTE) { /* * Last multibyte sequence wasn't completed. Save the extra * characters in a temporary buffer. */ nLeftOver = (nRaw - nSrcCooked); srcPtr = sinkPtr->bytes + (sinkPtr->mark + nSrcCooked); endPtr = srcPtr + nLeftOver; destPtr = leftover; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } } /* * Create a bigger sink. */ needed = nLeftOver + nCooked; spaceLeft = sinkPtr->size - sinkPtr->mark; if (spaceLeft >= needed) { spaceLeft = ExtendSinkBuffer(sinkPtr); } assert(spaceLeft > needed); /* * Replace the characters from the mark with the translated * characters. */ srcPtr = cooked; endPtr = cooked + nCooked; destPtr = sinkPtr->bytes + sinkPtr->mark; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } /* Add the number of newly translated characters to the mark */ sinkPtr->mark += nCooked; srcPtr = leftover; endPtr = leftover + nLeftOver; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } sinkPtr->fill = sinkPtr->mark + nLeftOver; #endif /* >= 8.1.0 */ } #ifdef WIN32 /* * Translate CRLF character sequences to LF characters. We have to do * this after converting the string to UTF from UNICODE. */ if (sinkPtr->encoding != ENCODING_BINARY) { int count; unsigned char *destPtr; destPtr = srcPtr = sinkPtr->bytes + oldMark; endPtr = sinkPtr->bytes + sinkPtr->fill; *endPtr = '\0'; count = 0; for (endPtr--; srcPtr < endPtr; srcPtr++) { if ((*srcPtr == '\r') && (*(srcPtr + 1) == '\n')) { count++; continue; /* Skip the CR in CR/LF sequences. */ } if (srcPtr != destPtr) { *destPtr = *srcPtr; /* Collapse the string, overwriting * the \r's encountered. */ } destPtr++; } sinkPtr->mark -= count; sinkPtr->fill -= count; *destPtr = *srcPtr; /* Copy the last byte */ if (*destPtr == '\r') { sinkPtr->mark--; } } #endif /* WIN32 */ } #ifdef notdef /* *--------------------------------------------------------------------------- * * CookSink -- * * For Windows, translate CR/NL combinations to NL alone. * * Results: * None. * * Side Effects: * The size of the byte array may shrink and array contents shifted as * carriage returns are found and removed. * *--------------------------------------------------------------------------- */ static void CookSink(Tcl_Interp *interp, Sink *sinkPtr) { unsigned char *srcPtr, *endPtr; if (sinkPtr->encoding == ENCODING_BINARY) { /* binary */ /* No translation needed. */ sinkPtr->mark = sinkPtr->fill; } else if (sinkPtr->encoding == ENCODING_ASCII) { /* ascii */ #if (_TCL_VERSION < _VERSION(8,1,0)) /* Convert NUL bytes to question marks. */ srcPtr = sinkPtr->bytes + sinkPtr->mark; endPtr = sinkPtr->bytes + sinkPtr->fill; while (srcPtr < endPtr) { if (*srcPtr == '\0') { *srcPtr = '?'; } srcPtr++; } #endif /* < 8.1.0 */ /* One-to-one translation. mark == fill. */ sinkPtr->mark = sinkPtr->fill; #if (_TCL_VERSION >= _VERSION(8,1,0)) } else { /* unicode. */ int nSrcCooked, nCooked; int result; int cookedSize, spaceLeft, needed; int nRaw, nLeftOver; unsigned char *destPtr; unsigned char *raw, *cooked; unsigned char leftover[100]; raw = sinkPtr->bytes + sinkPtr->mark; nRaw = sinkPtr->fill - sinkPtr->mark; /* Ideally, the cooked buffer size should be smaller */ cookedSize = nRaw * TCL_UTF_MAX + 1; cooked = Blt_AssertMalloc(cookedSize); result = Tcl_ExternalToUtf(interp, sinkPtr->encoding, (char *)raw, nRaw, 0, NULL, (char *)cooked, cookedSize, &nSrcCooked, &nCooked, NULL); nLeftOver = 0; if (result == TCL_CONVERT_MULTIBYTE) { /* * Last multibyte sequence wasn't completed. Save the extra * characters in a temporary buffer. */ nLeftOver = (nRaw - nSrcCooked); srcPtr = sinkPtr->bytes + (sinkPtr->mark + nSrcCooked); endPtr = srcPtr + nLeftOver; destPtr = leftover; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } } /* * Create a bigger sink. */ needed = nLeftOver + nCooked; spaceLeft = sinkPtr->size - sinkPtr->mark; if (spaceLeft >= needed) { spaceLeft = ExtendSinkBuffer(sinkPtr); } assert(spaceLeft > needed); /* * Replace the characters from the mark with the translated * characters. */ srcPtr = cooked; endPtr = cooked + nCooked; destPtr = sinkPtr->bytes + sinkPtr->mark; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } /* Add the number of newly translated characters to the mark */ sinkPtr->mark += nCooked; srcPtr = leftover; endPtr = leftover + nLeftOver; while (srcPtr < endPtr) { *destPtr++ = *srcPtr++; } sinkPtr->fill = sinkPtr->mark + nLeftOver; #endif /* >= 8.1.0 */ } } #endif #if (_TCL_VERSION < _VERSION(8,1,0)) static void NotifyOnUpdate(Tcl_Interp *interp, Sink *sinkPtr, unsigned char *data, size_t nBytes) { char save; if (data[0] == '\0') { return; } save = data[nBytes]; data[nBytes] = '\0'; if (sinkPtr->echo) { Tcl_Channel channel; channel = Tcl_GetStdChannel(TCL_STDERR); if (channel == NULL) { Tcl_AppendResult(interp, "can't get stderr channel", (char *)NULL); Tcl_BackgroundError(interp); sinkPtr->echo = FALSE; } else { Tcl_Write(channel, data, nBytes); if (save == '\n') { Tcl_Write(channel, "\n", 1); } Tcl_Flush(channel); } } objPtr = Tcl_NewByteArrayObj(data, nBytes); Tcl_IncrRefCount(objPtr); if (sinkPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; int result; cmdObjPtr = Tcl_DuplicateObj(sinkPtr->cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(interp); } } if (sinkPtr->updateVar != NULL) { if (Tcl_SetVar2Ex(interp, sinkPtr->updateVar, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } } Tcl_DecrRefCount(objPtr); data[nBytes] = save; } #else static void NotifyOnUpdate(Tcl_Interp *interp, Sink *sinkPtr, unsigned char *data, size_t nBytes) { Tcl_Obj *objPtr; if ((nBytes == 0) || (data[0] == '\0')) { return; } if (sinkPtr->echo) { Tcl_Channel channel; channel = Tcl_GetStdChannel(TCL_STDERR); if (channel == NULL) { Tcl_AppendResult(interp, "can't get stderr channel", (char *)NULL); Tcl_BackgroundError(interp); sinkPtr->echo = FALSE; } else { if (data[nBytes] == '\n') { objPtr = Tcl_NewByteArrayObj(data, nBytes + 1); } else { objPtr = Tcl_NewByteArrayObj(data, nBytes); } Tcl_WriteObj(channel, objPtr); Tcl_Flush(channel); } } objPtr = Tcl_NewByteArrayObj(data, nBytes); Tcl_IncrRefCount(objPtr); if (sinkPtr->cmdObjPtr != NULL) { Tcl_Obj *cmdObjPtr; int result; cmdObjPtr = Tcl_DuplicateObj(sinkPtr->cmdObjPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(interp); } } if (sinkPtr->updateVar != NULL) { if (Tcl_SetVar2Ex(interp, sinkPtr->updateVar, NULL, objPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(interp); } } Tcl_DecrRefCount(objPtr); } #endif /* < 8.1.0 */ static int CollectData(Bgexec *execPtr, Sink *sinkPtr) { if ((execPtr->flags & DETACHED) && (sinkPtr->doneVar == NULL)) { ResetSink(sinkPtr); } ReadBytes(sinkPtr); CookSink(execPtr->interp, sinkPtr); if ((sinkPtr->mark > sinkPtr->lastMark) && (sinkPtr->flags & SINK_NOTIFY)) { if (sinkPtr->flags & SINK_BUFFERED) { size_t length; unsigned char *data; /* For line-by-line updates, call NotifyOnUpdate for each new * complete line. */ while ((data = NextLine(sinkPtr, &length)) != NULL) { NotifyOnUpdate(execPtr->interp, sinkPtr, data, length); } } else { size_t length; unsigned char *data; int count; #ifdef notdef int i; #endif length = 0; /* Suppress compiler warning. */ data = NextBlock(sinkPtr, &length); #ifdef notdef count = 0; for (i = 0; i < length; i++) { if (data[i] == '\r') { continue; } if (i > count) { data[count] = data[i]; } count++; } fprintf(stderr, "\n"); #else count = length; #endif NotifyOnUpdate(execPtr->interp, sinkPtr, data, count); } } if (sinkPtr->status >= 0) { return TCL_OK; } if (sinkPtr->status == READ_ERROR) { if ((execPtr->flags & KILLED) == 0) { Tcl_AppendResult(execPtr->interp, "can't read data from ", sinkPtr->name, ": ", Tcl_PosixError(execPtr->interp), (char *)NULL); Tcl_BackgroundError(execPtr->interp); } return TCL_RETURN; } return TCL_RETURN; } /* *--------------------------------------------------------------------------- * * CreateSinkHandler -- * * Creates a file handler for the given sink. The file descriptor is * also set for non-blocking I/O. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ static int CreateSinkHandler(Bgexec *execPtr, Sink *sinkPtr, Tcl_FileProc *proc) { int flags; flags = fcntl(sinkPtr->fd, F_GETFL); #ifdef O_NONBLOCK flags |= O_NONBLOCK; #else flags |= O_NDELAY; #endif if (fcntl(sinkPtr->fd, F_SETFL, flags) < 0) { Tcl_AppendResult(execPtr->interp, "can't set file descriptor ", Blt_Itoa(sinkPtr->fd), " to non-blocking:", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } Tcl_CreateFileHandler(sinkPtr->fd, TCL_READABLE, proc, execPtr); return TCL_OK; } static void DisableTriggers(Bgexec *execPtr) /* Background info record. */ { if (execPtr->flags & TRACED) { Tcl_UntraceVar(execPtr->interp, execPtr->statusVar, TRACE_FLAGS, VariableProc, execPtr); execPtr->flags &= ~TRACED; } if (SINKOPEN(&execPtr->out)) { CloseSink(execPtr->interp, &execPtr->out); } if (SINKOPEN(&execPtr->err)) { CloseSink(execPtr->interp, &execPtr->err); } if (execPtr->timerToken != (Tcl_TimerToken) 0) { Tcl_DeleteTimerHandler(execPtr->timerToken); execPtr->timerToken = 0; } if (execPtr->donePtr != NULL) { *execPtr->donePtr = TRUE; } } #ifdef notdef if ((Flags & DILLO_TTY) && tcgetattr(STDIN_FILENO, &tt) == -1) if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt) == -1) #endif /* *--------------------------------------------------------------------------- * * CreatePipe -- * * Creates a pipe by simply calling the pipe() function. * * Results: * Returns 1 on success, 0 on failure. * * Side effects: * Creates a pipe. * *--------------------------------------------------------------------------- */ static int CreatePipe( Tcl_Interp *interp, int *inPtr, /* (out) Descriptor for read side of * pipe. */ int *outPtr) /* (out) Descriptor for write side of * pipe. */ { int fd[2]; if (pipe(fd) < 0) { Tcl_AppendResult(interp, "can't create pipe: ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } fcntl(fd[0], F_SETFD, FD_CLOEXEC); fcntl(fd[1], F_SETFD, FD_CLOEXEC); *inPtr = fd[0]; *outPtr = fd[1]; return TCL_OK; } #ifdef HAVE_GETPT static int GetMaster(Bgexec *execPtr) { int f; f = getpt(); if (f < 0) { Tcl_AppendResult(execPtr->interp, "failed getpt: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } execPtr->masterName[0] = '\0'; execPtr->master = f; return TCL_OK; } #elif defined(HAVE_POSIX_OPENPT) static int GetMaster(Bgexec *execPtr) { int f; f = posix_openpt(O_RDWR | O_NOCTTY); if (f < 0) { Tcl_AppendResult(execPtr->interp, "failed openpt: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } execPtr->masterName[0] = '\0'; execPtr->master = f; return TCL_OK; } #else static int GetMaster(Bgexec *execPtr) { static const char ptyChars[] = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" }; int f; const char *p; char ptyName[11]; strcpy(execPtr->masterName, "/dev/ptmx"); f = open(execPtr->masterName, O_RDWR | O_NOCTTY); if (f >= 0) { execPtr->master = f; return TCL_OK; } strcpy(ptyName, "/dev/ptyXY"); for (p = ptyChars; *p != '\0'; p++) { const char *q; ptyName[8] = *p; ptyName[9] = *ptyChars; if (access(proto, F_OK) == -1) { if (errno == E_NOENT) { /* If there is no /dev/ptyX0, skip all Xs. */ continue; } Tcl_AppendResult(execPtr->interp, "can't access \"", ptyName, "\": ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } for (q = ptyChars; *q != '\0'; q++) { int f; ptyName[9] = *q; f = open(ptyName, O_RDWR); if (f >= 0) { execPtr->master = f; strcpy(execPtr->masterName, ptyName); return TCL_OK; } if (errno == E_NOENT) { break; } } } Tcl_AppendResult(execPtr->interp, "can't access any ptys", (char *)NULL); return TCL_ERROR; } #endif /* HAVE_POSIX_OPENPT */ typedef int Tcl_File; static int InitMaster(Bgexec *execPtr) { #ifdef HAVE_TCFLUSH if (tcflush(execPtr->master, TCIOFLUSH) < 0) { Tcl_AppendResult(execPtr->interp, "tcflush: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } #else #ifdef TIOCFLUSH if (ioctl(execPtr->master, TIOCFLUSH, NULL) < 0) { Tcl_AppendResult(execPtr->interp, "can't set TIOCFLUSH on master: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } #endif /* TIOCFLUSH */ #endif /* HAVE_TCFLUSH */ #ifdef TIOCEXCL if (ioctl(execPtr->master, TIOCEXCL, NULL) < 0) { Tcl_AppendResult(execPtr->interp, "can't set TIOCEXCL on descriptor: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } #endif /* TIOCEXCL */ return TCL_OK; } #ifdef HAVE_OPEN_CONTROLLING_PTY static int OpenMaster(Bgexec *execPtr) { const char *name; int f; f = open_controlling_pty(name); if (f < 0) { Tcl_AppendResult(execPtr->interp, "can't open controlling pty: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } execPtr->master = f; strcpy(execPtr->slaveName, name); if (InitMaster(execPtr) != TCL_OK) { return TCL_ERROR; } } #endif /* HAVE_OPEN_CONTROLLING_PTY */ #ifdef HAVE_GRANTPT static int OpenMaster(Bgexec *execPtr) { const char *name; if (GetMaster(execPtr) != TCL_OK) { return TCL_ERROR; } if (grantpt(execPtr->master) < 0) { Tcl_AppendResult(execPtr->interp, "grantpt: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (unlockpt(execPtr->master) < 0) { Tcl_AppendResult(execPtr->interp, "unlockpt: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } name = ptsname(execPtr->master); if (name == NULL) { Tcl_AppendResult(execPtr->interp, "ptsname: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } strcpy(execPtr->slaveName, name); if (InitMaster(execPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #else #ifdef HAVE_OPENPTY #include <util.h> static int OpenMaster(Bgexec *execPtr) { if (openpty(&execPtr->master, &execPtr->slave, NULL, NULL, NULL) < 0) { Tcl_AppendResult(execPtr->interp, "can't open pty: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (InitMaster(execPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #endif /* HAVE_OPENPT */ #endif /* HAVE_GRANTPT */ static int OpenSlave(Bgexec *execPtr) { int f; pid_t pid; struct termios tt; pid = getpid(); /* Get the pid of the session leader. */ if (setsid() < 0) { Tcl_AppendResult(execPtr->interp, "setsid: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (fork() > 0) { _exit(0); } if (setpgid(0, pid) < 0) { Tcl_AppendResult(execPtr->interp, "setpgid: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } f = open(execPtr->slaveName, O_RDWR); if (f < 0) { Tcl_AppendResult(execPtr->interp, "can't open \"", execPtr->slaveName, "\": ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } execPtr->slave = f; #ifdef TIOCSCTTY if (ioctl(f, TIOCSCTTY, (char *)TRUE) < 0) { Tcl_AppendResult(execPtr->interp, "can't set ioctl \"TIOCSCTTY\": ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } #endif /* TIOCSCTTY */ #ifdef I_PUSH if (isastream(f)) { if (ioctl(f, I_PUSH, "p_tem") < 0) { Tcl_AppendResult(execPtr->interp, "can't set ioctl \"p_tem\": ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (ioctl(f, I_PUSH, "ldterm") < 0) { Tcl_AppendResult(execPtr->interp, "can't set ioctl \"ldterm\": ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } } #endif if (tcgetattr(0, &tt) < 0) { Tcl_AppendResult(execPtr->interp, "can't get terminate attributes: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (tcsetattr(execPtr->slave, TCSAFLUSH, &tt) < 0) { Tcl_AppendResult(execPtr->interp, "can't set terminate attributes: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (dup2(execPtr->slave, 0) < 0) { Tcl_AppendResult(execPtr->interp, "can't dup stdin: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (dup2(execPtr->slave, 1) < 0) { Tcl_AppendResult(execPtr->interp, "can't dup stdout: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } if (dup2(execPtr->slave, 2) < 0) { Tcl_AppendResult(execPtr->interp, "can't dup stderr: ", Tcl_PosixError(execPtr->interp), (char *)NULL); return TCL_ERROR; } /* * Must clear the close-on-exec flag for the target FD, since some * systems (e.g. Ultrix) do not clear the CLOEXEC flag on the * target FD. */ fcntl(0, F_SETFD, 0); fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); return TCL_OK; } static int ExecutePipeline(Bgexec *execPtr, int objc, Tcl_Obj *const *objv) { WAIT_STATUS_TYPE waitStatus, lastStatus; int nProcs; /* # of processes. */ pid_t child; int mesgIn, mesgOut; int errIn, errOut; pid_t *pids; errIn = errOut = -1; mesgIn = mesgOut = -1; /* * Create a pipe that the child can use to return error information if * anything goes wrong in creating the pipeline. */ if (CreatePipe(execPtr->interp, &mesgIn, &mesgOut) != TCL_OK) { return TCL_ERROR; } /* Create a pseudo terminal for the pipeline. */ if (OpenMaster(execPtr) != TCL_OK) { goto error; } if (CreatePipe(execPtr->interp, &errIn, &errOut) != TCL_OK) { goto error; } execPtr->err.fd = execPtr->out.fd = execPtr->master; #ifdef notdef if ((execPtr->err.doneVar != NULL) || (execPtr->err.updateVar != NULL) || (execPtr->err.cmdObjPtr != NULL) || (!execPtr->err.echo)) { /* If we want stderr separately, create a pipe for the error * channel. */ execPtr->err.fd = errIn; } #endif child = fork(); if (child > 0) { char mesg[BUFSIZ+1]; ssize_t nRead; /* * Read back from the error pipe to see if the pipeline started up * properly. The info in the pipe (if any) if the Tcl error message * from the child process. */ close(mesgOut); nRead = read(mesgIn, mesg, BUFSIZ); if (nRead == 0) { execPtr->sid = child; return TCL_OK; } close(mesgIn); mesg[nRead] = '\0'; Tcl_AppendResult(execPtr->interp, mesg, (char *)NULL); error: if (mesgIn >= 0) { close(mesgIn); } if (mesgOut >= 0) { close(mesgOut); } if (errIn >= 0) { close(errIn); } if (errOut >= 0) { close(errOut); } return TCL_ERROR; } close(mesgIn); /* Open the slave side of the pseudo terminal for the pipeline. */ /* The default descriptor for 0, 1, and 2 are now the pseudo terminal. */ if (OpenSlave(execPtr) != TCL_OK) { fprintf(stderr, "OpenSlave: %s\n", Tcl_GetStringResult(execPtr->interp)); return TCL_ERROR; } /* Always collect characters from the sinks. Display to the screen or * not. */ nProcs = Blt_CreatePipeline(execPtr->interp, objc, objv, &pids, (int *)NULL, (int *)NULL, (int *)NULL); if (nProcs <= 0) { ssize_t nWritten; const char *mesg; int length; mesg = Tcl_GetStringFromObj(Tcl_GetObjResult(execPtr->interp), &length); fprintf(stderr, "child: %s\n", mesg); nWritten = write(mesgOut, mesg, length); _exit(1); } close(mesgOut); /* The pipeline has started. */ *((int *)&waitStatus) = 0; *((int *)&lastStatus) = 0; while (nProcs > 0) { int pid; pid = waitpid(-1, (int *)&waitStatus, 0); if (pid < 0) { fprintf(stderr, "waitpid: %s\n", Tcl_PosixError(execPtr->interp)); continue; } /* * Save the status information associated with the subprocess. * We'll use it only if this is the last subprocess to be reaped. */ lastStatus = waitStatus; --nProcs; } /* * All pipeline processes have completed. Exit the child replicating the * exit code. */ exit(WEXITSTATUS(lastStatus)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * FreeBgexec -- * * Releases the memory allocated for the backgrounded process. * *--------------------------------------------------------------------------- */ static void FreeBgexec(Bgexec *execPtr) { Blt_FreeSwitches(switchSpecs, (char *)execPtr, 0); if (execPtr->link != NULL) { Tcl_MutexLock(mutexPtr); Blt_Chain_DeleteLink(activePipelines, execPtr->link); Tcl_MutexUnlock(mutexPtr); } Blt_Free(execPtr); } /* *--------------------------------------------------------------------------- * * KillPipeline -- * * Cleans up background execution processes and memory. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void KillPipeline(Bgexec *execPtr) /* Background info record. */ { if (execPtr->sid > 0) { unsigned long pid; Tcl_Pid tclPid; if (execPtr->signalNum > 0) { kill(-execPtr->sid, execPtr->signalNum); } pid = (long)execPtr->sid; tclPid = (Tcl_Pid)pid; Tcl_DetachPids(1, &tclPid); } else if (execPtr->procIds != NULL) { int i; for (i = 0; i < execPtr->nProcs; i++) { Tcl_Pid tclPid; unsigned long pid; if (execPtr->signalNum > 0) { kill(execPtr->procIds[i], execPtr->signalNum); } pid = (long)execPtr->procIds[i]; tclPid = (Tcl_Pid)pid; Tcl_DetachPids(1, &tclPid); } } Tcl_ReapDetachedProcs(); } /* *--------------------------------------------------------------------------- * * DestroyBgexec -- * * Cleans up background execution processes and memory. * * Results: * None. * * Side effects: * The memory allocated to the Bgexec structure released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void DestroyBgexec(Bgexec *execPtr) /* Background info record. */ { DisableTriggers(execPtr); FreeSinkBuffer(&execPtr->err); FreeSinkBuffer(&execPtr->out); KillPipeline(execPtr); FreeBgexec(execPtr); } /* *--------------------------------------------------------------------------- * * VariableProc -- * * Kills all currently running subprocesses (given the specified * signal). This procedure is called when the user sets the status * variable associated with this group of child subprocesses. * * Results: * Always returns NULL. Only called from a variable trace. * * Side effects: * The subprocesses are signaled for termination using the specified kill * signal. Additionally, any resources allocated to track the * subprocesses is released. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static char * VariableProc( ClientData clientData, /* File output information. */ Tcl_Interp *interp, /* Not used. */ const char *part1, /* Not used. */ const char *part2, /* Not Used. */ int flags) { if (flags & TRACE_FLAGS) { Bgexec *execPtr = clientData; /* Kill all child processes that remain alive. */ KillPipeline(execPtr); execPtr->flags |= KILLED; } return NULL; } static int CheckPipeline(Bgexec *execPtr, Tcl_Obj **objPtrPtr) { enum PROCESS_STATUS { PROCESS_EXITED, PROCESS_STOPPED, PROCESS_KILLED, PROCESS_UNKNOWN } pcode; static const char *tokens[] = { "EXITED", "KILLED", "STOPPED", "UNKNOWN" }; Tcl_Obj *listObjPtr, *objPtr; Tcl_Interp *interp; WAIT_STATUS_TYPE waitStatus, lastStatus; char string[200]; const char *mesg; int code; int i; int nLeft; /* # of processes still not reaped */ unsigned int lastPid; interp = execPtr->interp; lastPid = (unsigned int)-1; *((int *)&waitStatus) = 0; *((int *)&lastStatus) = 0; nLeft = 0; for (i = 0; i < execPtr->nProcs; i++) { int pid; pid = waitpid(execPtr->procIds[i], (int *)&waitStatus, WNOHANG); if (pid == 0) { /* Process has not terminated yet */ if (nLeft < i) { execPtr->procIds[nLeft] = execPtr->procIds[i]; } nLeft++; /* Count the # of processes left */ } else if (pid != -1) { /* * Save the status information associated with the subprocess. * We'll use it only if this is the last subprocess to be reaped. */ lastStatus = waitStatus; lastPid = (unsigned int)pid; } } execPtr->nProcs = nLeft; if ((nLeft > 0) || (SINKOPEN(&execPtr->out)) || (SINKOPEN(&execPtr->err))) { /* Keep polling for the status of the children that are left */ execPtr->timerToken = Tcl_CreateTimerHandler(execPtr->interval, TimerProc, execPtr); return -1; } /* * All child processes have completed. Set the status variable with the * status of the last process reaped. The status is a list of an error * token, the exit status, and a message. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); code = WEXITSTATUS(lastStatus); if (WIFEXITED(lastStatus)) { pcode = PROCESS_EXITED; } else if (WIFSIGNALED(lastStatus)) { pcode = PROCESS_KILLED; code = -1; } else if (WIFSTOPPED(lastStatus)) { pcode = PROCESS_STOPPED; code = -1; } else { pcode = PROCESS_UNKNOWN; } objPtr = Tcl_NewStringObj(tokens[pcode], -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewLongObj(lastPid); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); switch(pcode) { case PROCESS_EXITED: mesg = "child completed normally"; break; case PROCESS_KILLED: mesg = Tcl_SignalMsg((int)(WTERMSIG(lastStatus))); break; case PROCESS_STOPPED: mesg = Tcl_SignalMsg((int)(WSTOPSIG(lastStatus))); break; case PROCESS_UNKNOWN: sprintf_s(string, 200, "child completed with unknown status 0x%x", *((int *)&lastStatus)); mesg = string; break; } objPtr = Tcl_NewStringObj(mesg, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (execPtr->exitCodePtr != NULL) { *execPtr->exitCodePtr = code; } *objPtrPtr = listObjPtr; return code; } static int CheckSession(Bgexec *execPtr, Tcl_Obj **objPtrPtr) { enum PROCESS_STATUS { PROCESS_EXITED, PROCESS_STOPPED, PROCESS_KILLED, PROCESS_UNKNOWN } pcode; static const char *tokens[] = { "EXITED", "KILLED", "STOPPED", "UNKNOWN" }; Tcl_Obj *listObjPtr, *objPtr; Tcl_Interp *interp; WAIT_STATUS_TYPE waitStatus; char string[200]; const char *mesg; int code; int pid; interp = execPtr->interp; *((int *)&waitStatus) = 0; pid = waitpid(execPtr->sid, (int *)&waitStatus, WNOHANG); if (pid == 0) { /* Process has not terminated yet */ /* Keep polling for the status of the children that are left */ execPtr->timerToken = Tcl_CreateTimerHandler(execPtr->interval, TimerProc, execPtr); return -1; } /* * All child processes have completed. Set the status variable with the * status of the last process reaped. The status is a list of an error * token, the exit status, and a message. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); code = WEXITSTATUS(waitStatus); if (WIFEXITED(waitStatus)) { pcode = PROCESS_EXITED; } else if (WIFSIGNALED(waitStatus)) { pcode = PROCESS_KILLED; code = -1; } else if (WIFSTOPPED(waitStatus)) { pcode = PROCESS_STOPPED; code = -1; } else { pcode = PROCESS_UNKNOWN; } objPtr = Tcl_NewStringObj(tokens[pcode], -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); objPtr = Tcl_NewLongObj(pid); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); switch(pcode) { case PROCESS_EXITED: mesg = "child completed normally"; break; case PROCESS_KILLED: mesg = Tcl_SignalMsg((int)(WTERMSIG(waitStatus))); break; case PROCESS_STOPPED: mesg = Tcl_SignalMsg((int)(WSTOPSIG(waitStatus))); break; case PROCESS_UNKNOWN: sprintf_s(string, 200, "child completed with unknown status 0x%x", *((int *)&waitStatus)); mesg = string; break; } objPtr = Tcl_NewStringObj(mesg, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); *objPtrPtr = listObjPtr; return code; } /* *--------------------------------------------------------------------------- * * TimerProc -- * * This is a timer handler procedure which gets called periodically to * reap any of the sub-processes if they have terminated. After the last * process has terminated, the contents of standard output are stored in * the output variable, which triggers the cleanup proc (using a variable * trace). The status the last process to exit is written to the status * variable. * * Results: * None. Called from the TCL event loop. * * Side effects: * Many. The contents of procIds is shifted, leaving only those * sub-processes which have not yet terminated. If there are still * subprocesses left, this procedure is placed in the timer queue * again. Otherwise the output and possibly the status variables are * updated. The former triggers the cleanup routine which will destroy * the information and resources associated with these background * processes. * *--------------------------------------------------------------------------- */ static void TimerProc(ClientData clientData) { Bgexec *execPtr = clientData; Tcl_Obj *resultObjPtr; int code; if (execPtr->sid > 0) { code = CheckSession(execPtr, &resultObjPtr); } else { code = CheckPipeline(execPtr, &resultObjPtr); } if (code < 0) { /* Keep polling for the status of the children that are left */ return; } if (execPtr->exitCodePtr != NULL) { *execPtr->exitCodePtr = code; } DisableTriggers(execPtr); if (Tcl_SetVar2Ex(execPtr->interp, execPtr->statusVar, NULL, resultObjPtr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { Tcl_BackgroundError(execPtr->interp); } if (execPtr->flags & DETACHED) { DestroyBgexec(execPtr); } } /* *--------------------------------------------------------------------------- * * Stdoutproc -- * * This procedure is called when output from the detached pipeline is * available. The output is read and saved in a buffer in the Bgexec * structure. * * Results: * None. * * Side effects: * Data is stored in the buffer. This character array may be increased * as more space is required to contain the output of the pipeline. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void StdoutProc(ClientData clientData, int mask) { Bgexec *execPtr = clientData; if (CollectData(execPtr, &execPtr->out) == TCL_OK) { return; } /* * Either EOF or an error has occurred. In either case, close the * sink. Note that closing the sink will also remove the file handler, so * this routine will not be called again. */ CloseSink(execPtr->interp, &execPtr->out); /* * If both sinks (stdout and stderr) are closed, this doesn't necessarily * mean that the process has terminated. Set up a timer handler to * periodically poll for the exit status of each process. Initially check * at the next idle interval. */ if (!SINKOPEN(&execPtr->err)) { execPtr->timerToken = Tcl_CreateTimerHandler(0, TimerProc, clientData); } } /* *--------------------------------------------------------------------------- * * StderrProc -- * * This procedure is called when error from the detached pipeline is * available. The error is read and saved in a buffer in the Bgexec * structure. * * Results: * None. * * Side effects: * Data is stored in the buffer. This character array may be increased * as more space is required to contain the stderr of the pipeline. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void StderrProc(ClientData clientData, int mask) { Bgexec *execPtr = clientData; if (CollectData(execPtr, &execPtr->err) == TCL_OK) { return; } /* * Either EOF or an error has occurred. In either case, close the * sink. Note that closing the sink will also remove the file handler, so * this routine will not be called again. */ CloseSink(execPtr->interp, &execPtr->err); /* * If both sinks (stdout and stderr) are closed, this doesn't necessarily * mean that the process has terminated. Set up a timer handler to * periodically poll for the exit status of each process. Initially check * at the next idle interval. */ if (!SINKOPEN(&execPtr->out)) { execPtr->timerToken = Tcl_CreateTimerHandler(0, TimerProc, clientData); } } /* *--------------------------------------------------------------------------- * * BgexecCmd -- * * This procedure is invoked to process the "ptyexec" TCL command. See * the user documentation for details on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int BgexecCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* # of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Bgexec *execPtr; ProcessId *pidPtr; char *lastArg; int *outFdPtr, *errFdPtr; int isDetached; int i; int nProcs; if (objc < 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " varName ?options? command ?arg...?\"", (char *)NULL); return TCL_ERROR; } /* Check if the command line is to be run detached (the last argument is * "&") */ lastArg = Tcl_GetString(objv[objc - 1]); isDetached = ((lastArg[0] == '&') && (lastArg[1] == '\0')); if (isDetached) { objc--; /* Remove the '&' argument */ } execPtr = Blt_AssertCalloc(1, sizeof(Bgexec)); /* Initialize the background information record */ execPtr->slave = execPtr->master = -1; execPtr->interp = interp; execPtr->signalNum = SIGHUP; execPtr->nProcs = -1; execPtr->interval = 1000; if (isDetached) { execPtr->flags |= DETACHED; } Tcl_MutexLock(mutexPtr); execPtr->link = Blt_Chain_Append(activePipelines, execPtr); Tcl_MutexUnlock(mutexPtr); execPtr->out.encoding = ENCODING_ASCII; execPtr->err.encoding = ENCODING_ASCII; /* Try to clean up any detached processes */ Tcl_ReapDetachedProcs(); i = Blt_ParseSwitches(interp, switchSpecs, objc - 1, objv + 1, execPtr, BLT_SWITCH_OBJV_PARTIAL); if (i < 0) { FreeBgexec(execPtr); return TCL_ERROR; } i += 1; /* Must be at least one argument left as the command to execute. */ if (objc <= i) { Tcl_AppendResult(interp, "missing command to execute: should be \"", Tcl_GetString(objv[0]), " varName ?options? command ?arg...?\"", (char *)NULL); FreeBgexec(execPtr); return TCL_ERROR; } InitSink(execPtr, &execPtr->out, "stdout"); InitSink(execPtr, &execPtr->err, "stderr"); if (execPtr->statusVar == NULL) { static int count = 0; char string[200]; count++; sprintf(string, "blt::ptyexecstatus%d", count); execPtr->statusVar = Blt_AssertStrdup(string); } /* Put a trace on the exit status variable. The will also allow the user * to terminate the pipeline by simply setting the variable. */ Tcl_TraceVar(interp, execPtr->statusVar, TRACE_FLAGS, VariableProc,execPtr); execPtr->flags |= TRACED; if (ExecutePipeline(execPtr, objc - i, objv + i) != TCL_OK) { goto error; } if (CreateSinkHandler(execPtr, &execPtr->out, StdoutProc) != TCL_OK) { goto error; } if (execPtr->err.fd != execPtr->master) { /* Only create a sink for stderr if a separation of stdout and stderr * is requested. */ if (CreateSinkHandler(execPtr, &execPtr->err, StderrProc) != TCL_OK) { goto error; } } if (isDetached) { /* If detached, return the process id of the session instead of the * output of the pipeline. */ Tcl_SetLongObj(Tcl_GetObjResult(interp), execPtr->sid); } else { int exitCode; int done; execPtr->exitCodePtr = &exitCode; execPtr->donePtr = &done; exitCode = done = 0; while (!done) { Tcl_DoOneEvent(0); } DisableTriggers(execPtr); if ((execPtr->flags & IGNOREEXITCODE) || (exitCode == 0)) { if (execPtr->out.doneVar == NULL) { unsigned char *data; int length; /* Return the output of the pipeline. */ GetSinkData(&execPtr->out, &data, &length); assert(length <= UINT_MAX); #if (_TCL_VERSION < _VERSION(8,1,0)) data[length] = '\0'; Tcl_SetObjResult(interp, Tcl_NewStringObj(data, length)); #else Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(data, length)); #endif } } else { DestroyBgexec(execPtr); Tcl_AppendResult(interp, "child process exited abnormally", (char *)NULL); return TCL_ERROR; } DestroyBgexec(execPtr); } return TCL_OK; error: DestroyBgexec(execPtr); return TCL_ERROR; } static void BgexecExitProc(ClientData clientData) { Blt_ChainLink link, next; Tcl_MutexLock(mutexPtr); for (link = Blt_Chain_FirstLink(activePipelines); link != NULL; link = next) { next = Blt_Chain_NextLink(link); Bgexec *execPtr; execPtr = Blt_Chain_GetValue(link); execPtr->link = NULL; KillPipeline(execPtr); } Blt_Chain_Destroy(activePipelines); Tcl_MutexUnlock(mutexPtr); } /* *--------------------------------------------------------------------------- * * Blt_BgexecCmdInitProc -- * * This procedure is invoked to initialize the "ptyexec" TCL command. See * the user documentation for details on what it does. * * Results: * None. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int Blt_PtyExecCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "ptyexec", BgexecCmd, }; if (activePipelines == NULL) { #ifdef TCL_THREADS mutexPtr = Tcl_GetAllocMutex(); #endif activePipelines = Blt_Chain_Create(); Tcl_CreateExitHandler(BgexecExitProc, activePipelines); } return Blt_InitCmd(interp, "::blt", &cmdSpec); } #endif /* NO_BGEXEC */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltExtInit.c������������������������������������������������������������������0000644�0001750�0001750�00000012101�11500220661�015251� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * BltExInit.c -- * * This module initials the Tk-related commands of BLT toolkit, registering * the commands with the TCL interpreter. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltNsUtil.h" #if (_TCL_VERSION >= _VERSION(8,5,0)) #define TCL_VERSION_LOADED TCL_PATCH_LEVEL #else #define TCL_VERSION_LOADED TCL_VERSION #endif #if (_TK_VERSION >= _VERSION(8,5,0)) #define TK_VERSION_LOADED TK_PATCH_LEVEL #else #define TK_VERSION_LOADED TK_VERSION #endif BLT_EXTERN Tcl_AppInitProc Blt_x_Init; BLT_EXTERN Tcl_AppInitProc Blt_x_SafeInit; BLT_EXTERN Tcl_AppInitProc Blt_core_Init; BLT_EXTERN Tcl_AppInitProc Blt_Init; static Tcl_AppInitProc *cmdProcs[] = { #ifndef NO_BGPATTERN Blt_BgPatternCmdInitProc, #endif #ifndef NO_GRAPH Blt_GraphCmdInitProc, #endif #ifndef NO_PICTURE Blt_PictureCmdInitProc, #endif #ifndef NO_TABLEMGR Blt_TableMgrCmdInitProc, #endif #ifndef NO_TABSET Blt_TabsetCmdInitProc, #endif #ifndef NO_HTEXT Blt_HtextCmdInitProc, #endif #ifndef NO_BUSY Blt_BusyCmdInitProc, #endif #ifndef NO_WINOP Blt_WinopCmdInitProc, #endif #ifndef NO_BITMAP Blt_BitmapCmdInitProc, #endif #ifndef NO_DRAGDROP Blt_DragDropCmdInitProc, #endif #ifndef NO_DND Blt_DndCmdInitProc, #endif #ifndef NO_CONTAINER Blt_ContainerCmdInitProc, #endif #ifndef NO_BEEP Blt_BeepCmdInitProc, #endif #ifndef NO_CUTBUFFER Blt_CutbufferCmdInitProc, #endif #ifndef NO_PRINTER Blt_PrinterCmdInitProc, #endif #ifndef NO_TKFRAME Blt_FrameCmdInitProc, #endif #ifndef NO_TKBUTTON Blt_ButtonCmdInitProc, #endif #ifndef NO_TKSCROLLBAR Blt_ScrollbarCmdInitProc, #endif #ifndef NO_SCROLLSET Blt_ScrollsetCmdInitProc, #endif #ifndef NO_PANESET Blt_PanesetCmdInitProc, #endif #ifndef NO_TREEVIEW Blt_TreeViewCmdInitProc, #endif #if (BLT_MAJOR_VERSION > 3) #ifndef NO_MOUNTAIN Blt_MountainCmdInitProc, #endif #endif #ifndef NO_TED Blt_TedCmdInitProc, #endif #ifndef NO_COMBOTREE Blt_ComboButtonInitProc, Blt_ComboEntryInitProc, Blt_ComboMenuInitProc, Blt_ComboTreeInitProc, Blt_ListViewInitProc, #endif #ifndef NO_AFM Blt_AfmCmdInitProc, #endif #ifndef NO_SENDEVENT Blt_SendEventCmdInitProc, #endif (Tcl_AppInitProc *) NULL }; /*LINTLIBRARY*/ int Blt_x_Init(Tcl_Interp *interp) /* Interpreter to add extra commands */ { Tcl_Namespace *nsPtr; Tcl_AppInitProc **p; const int isExact = 1; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION_LOADED, isExact) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgRequire(interp, "blt_core", BLT_VERSION, isExact) == NULL) { return TCL_ERROR; } #if (_TCL_VERSION >= _VERSION(8,1,0)) #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, TK_VERSION_LOADED, isExact) == NULL) { return TCL_ERROR; }; #endif if (Tcl_PkgPresent(interp, "Tk", TK_VERSION_LOADED, isExact) == NULL) { return TCL_OK; } #else if (Tcl_PkgRequire(interp, "Tk", TK_VERSION_LOADED, isExact) == NULL) { Tcl_ResetResult(interp); return TCL_OK; } #endif nsPtr = Tcl_CreateNamespace(interp, "::blt::tk", NULL, NULL); if (nsPtr == NULL) { return TCL_ERROR; } nsPtr = Tcl_FindNamespace(interp, "::blt", NULL, TCL_LEAVE_ERR_MSG); if (nsPtr == NULL) { return TCL_ERROR; } /* Blt_RegisterPictureImageType(interp); Blt_RegisterEpsCanvasItem(); Blt_InitXRandrConfig(interp); */ /* Initialize the BLT commands that only use Tk. */ for (p = cmdProcs; *p != NULL; p++) { if ((**p) (interp) != TCL_OK) { Tcl_DeleteNamespace(nsPtr); return TCL_ERROR; } } if (Tcl_PkgProvide(interp, "blt_extra", BLT_VERSION) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /*LINTLIBRARY*/ int Blt_x_SafeInit(Tcl_Interp *interp) /* Interpreter to add extra commands */ { return Blt_x_Init(interp); } int Blt_Init(Tcl_Interp *interp) { if (Blt_core_Init(interp) != TCL_OK) { return TCL_ERROR; } if (Blt_x_Init(interp) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #ifdef USE_DLL # include "bltWinDll.c" #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltWinUtil.c������������������������������������������������������������������0000644�0001750�0001750�00000004126�11462120063�015272� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * bltWinUtil.c -- * * This module contains WIN32 routines not included in the Tcl/Tk * libraries. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <bltInt.h> #ifdef notdef double drand48(void) { return (double) rand() / (double)RAND_MAX; } void srand48(long int seed) { srand(seed); } #endif int Blt_GetPlatformId(void) { static int platformId = 0; if (platformId == 0) { OSVERSIONINFO opsysInfo; opsysInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&opsysInfo)) { platformId = opsysInfo.dwPlatformId; } } return platformId; } const char * Blt_PrintError(int error) { static char buffer[1024]; int length; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ buffer, 1024, NULL); length = strlen(buffer); if (buffer[length - 2] == '\r') { buffer[length - 2] = '\0'; } return buffer; } const char * Blt_LastError(void) { return Blt_PrintError(GetLastError()); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltPictDraw.c�����������������������������������������������������������������0000644�0001750�0001750�00000263515�11462120062�015424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltPictDraw.c -- * * This module implements image drawing primitives (line, circle, rectangle, * text, etc.) for picture images in the BLT toolkit. * * Copyright 1997-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltOp.h" #include "bltHash.h" #include "bltSwitch.h" #include "bltPicture.h" #include "bltPictInt.h" #include "bltPainter.h" #include <X11/Xutil.h> #include "bltFont.h" #include "bltText.h" #include <string.h> #define imul8x8(a,b,t) ((t) = (a)*(b)+128,(((t)+((t)>>8))>>8)) #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 255.0) ? 255.0 : (c))) typedef struct { unsigned int alpha; unsigned int offset; } Shadow; #if defined (HAVE_FT2BUILD_H) && defined(HAVE_LIBXFT) #include <ft2build.h> #include FT_FREETYPE_H #include <X11/Xft/Xft.h> #define DRAWTEXT 1 #else #define DRAWTEXT 0 #endif #if DRAWTEXT static FT_Library ftLibrary; typedef struct { FT_Face face; FT_Matrix matrix; FT_Library lib; XftFont *xftFont; int fontSize; float angle; int height; int ascent, descent; } FtFont; #endif /*HAVE_FT2BUILD_H && HAVE_LIBXFT */ static Blt_SwitchParseProc ArraySwitchProc; static Blt_SwitchFreeProc ArrayFreeProc; static Blt_SwitchCustom arraySwitch = { ArraySwitchProc, ArrayFreeProc, (ClientData)0, }; static Blt_SwitchParseProc AnchorSwitch; static Blt_SwitchCustom anchorSwitch = { AnchorSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc AlphaSwitch; static Blt_SwitchCustom alphaSwitch = { AlphaSwitch, NULL, (ClientData)0, }; static Blt_SwitchParseProc ShadowSwitch; static Blt_SwitchCustom shadowSwitch = { ShadowSwitch, NULL, (ClientData)0, }; BLT_EXTERN Blt_SwitchParseProc Blt_ColorSwitchProc; static Blt_SwitchCustom colorSwitch = { Blt_ColorSwitchProc, NULL, (ClientData)0, }; typedef struct { int alpha; /* Overrides alpha value of color. */ Blt_Pixel outline, fill; /* Outline and fill colors for the circle. */ Shadow shadow; int antialiased; int lineWidth; /* Width of outline. If zero, indicates to * draw a solid circle. */ } CircleSwitches; static Blt_SwitchSpec circleSwitches[] = { {BLT_SWITCH_CUSTOM, "-alpha", "value", Blt_Offset(CircleSwitches, alpha), 0, 0, &alphaSwitch}, {BLT_SWITCH_CUSTOM, "-fill", "fill", Blt_Offset(CircleSwitches, fill), 0, 0, &colorSwitch}, {BLT_SWITCH_BOOLEAN, "-antialiased", "bool", Blt_Offset(CircleSwitches, antialiased), 0}, {BLT_SWITCH_INT_NNEG, "-linewidth", "value", Blt_Offset(CircleSwitches, lineWidth), 0}, {BLT_SWITCH_CUSTOM, "-outline", "outline", Blt_Offset(CircleSwitches, outline), 0, 0, &colorSwitch}, {BLT_SWITCH_CUSTOM, "-shadow", "offset", Blt_Offset(CircleSwitches, shadow), 0, 0, &shadowSwitch}, {BLT_SWITCH_END} }; typedef struct { int alpha; /* Overrides alpha value of color. */ Blt_Pixel bg; /* Color of line. */ int lineWidth; /* Width of outline. */ Array x, y; Array coords; } LineSwitches; typedef struct { int alpha; /* Overrides alpha value of color. */ Blt_Pixel bg; /* Fill color of polygon. */ int antialiased; Shadow shadow; int lineWidth; /* Width of outline. Default is 1, If zero, * indicates to draw a solid polygon. */ Array coords; Array x, y; } PolygonSwitches; static Blt_SwitchSpec polygonSwitches[] = { {BLT_SWITCH_CUSTOM, "-alpha", "int", Blt_Offset(PolygonSwitches, alpha), 0, 0, &alphaSwitch}, {BLT_SWITCH_BOOLEAN, "-antialiased", "bool", Blt_Offset(PolygonSwitches, antialiased), 0}, {BLT_SWITCH_CUSTOM, "-color", "color", Blt_Offset(PolygonSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_CUSTOM, "-coords", "{x0 y0 x1 y1 ... xn yn}", Blt_Offset(PolygonSwitches, coords), 0, 0, &arraySwitch}, {BLT_SWITCH_CUSTOM, "-x", "{x0 x1 ... xn}", Blt_Offset(PolygonSwitches, x), 0, 0, &arraySwitch}, {BLT_SWITCH_CUSTOM, "-y", "{x0 x1 ... xn}", Blt_Offset(PolygonSwitches, y), 0, 0, &arraySwitch}, {BLT_SWITCH_CUSTOM, "-shadow", "offset", Blt_Offset(PolygonSwitches, shadow), 0, 0, &shadowSwitch}, {BLT_SWITCH_INT_POS, "-linewidth", "int", Blt_Offset(PolygonSwitches, lineWidth), 0}, {BLT_SWITCH_END} }; static Blt_SwitchSpec lineSwitches[] = { {BLT_SWITCH_CUSTOM, "-alpha", "int", Blt_Offset(LineSwitches, alpha), 0, 0, &alphaSwitch}, {BLT_SWITCH_CUSTOM, "-color", "color", Blt_Offset(LineSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_CUSTOM, "-coords", "{x0 y0 x1 y1 ... xn yn}", Blt_Offset(LineSwitches, coords), 0, 0, &arraySwitch}, {BLT_SWITCH_INT_POS, "-linewidth", "int", Blt_Offset(LineSwitches, lineWidth), 0}, {BLT_SWITCH_CUSTOM, "-x", "{x0 x1 ... xn}", Blt_Offset(LineSwitches, x), 0, 0, &arraySwitch}, {BLT_SWITCH_CUSTOM, "-y", "{x0 x1 ... xn}", Blt_Offset(LineSwitches, y), 0, 0, &arraySwitch}, {BLT_SWITCH_END} }; typedef struct { int alpha; /* Overrides alpha value of color. */ Blt_Pixel bg; /* Color of rectangle. */ Shadow shadow; int lineWidth; /* Width of outline. If zero, indicates to * draw a solid rectangle. */ int radius; /* Radius of rounded corner. */ int antialiased; } RectangleSwitches; static Blt_SwitchSpec rectangleSwitches[] = { {BLT_SWITCH_CUSTOM, "-alpha", "int", Blt_Offset(RectangleSwitches, alpha), 0, 0, &alphaSwitch}, {BLT_SWITCH_CUSTOM, "-color", "color", Blt_Offset(RectangleSwitches, bg), 0, 0, &colorSwitch}, {BLT_SWITCH_BOOLEAN, "-antialiased", "bool", Blt_Offset(RectangleSwitches, antialiased), 0}, {BLT_SWITCH_INT_NNEG, "-radius", "number", Blt_Offset(RectangleSwitches, radius), 0}, {BLT_SWITCH_CUSTOM, "-shadow", "offset", Blt_Offset(RectangleSwitches, shadow), 0, 0, &shadowSwitch}, {BLT_SWITCH_INT_NNEG, "-linewidth", "number", Blt_Offset(RectangleSwitches, lineWidth), 0}, {BLT_SWITCH_END} }; typedef struct { int alpha; /* Overrides alpha value of color. */ int kerning; Blt_Pixel color; /* Color of text. */ Shadow shadow; int fontSize; Tcl_Obj *fontObjPtr; int justify; Tk_Anchor anchor; float angle; } TextSwitches; static Blt_SwitchSpec textSwitches[] = { {BLT_SWITCH_CUSTOM, "-alpha", "int", Blt_Offset(TextSwitches, alpha), 0, 0, &alphaSwitch}, {BLT_SWITCH_CUSTOM, "-anchor", "anchor", Blt_Offset(TextSwitches, anchor), 0, 0, &anchorSwitch}, {BLT_SWITCH_CUSTOM, "-color", "colorName", Blt_Offset(TextSwitches, color), 0, 0, &colorSwitch}, {BLT_SWITCH_OBJ, "-font", "fontName", Blt_Offset(TextSwitches, fontObjPtr), 0}, {BLT_SWITCH_BOOLEAN, "-kerning", "bool", Blt_Offset(TextSwitches, kerning), 0}, {BLT_SWITCH_FLOAT, "-rotate", "angle", Blt_Offset(TextSwitches, angle), 0}, {BLT_SWITCH_INT, "-size", "number", Blt_Offset(TextSwitches, fontSize), 0}, {BLT_SWITCH_CUSTOM, "-shadow", "offset", Blt_Offset(TextSwitches, shadow), 0, 0, &shadowSwitch}, {BLT_SWITCH_END} }; static Pict * BgPicture(Pict *srcPtr, int sx, int sy, int w, int h) { Pict *destPtr; Blt_Pixel *srcRowPtr, *destRowPtr; size_t nBytes; int y; w = MIN(w, srcPtr->width - sx); h = MIN(h, srcPtr->height - sy); destPtr = Blt_CreatePicture(w*4, h*4); srcRowPtr = srcPtr->bits + (sy * srcPtr->width) + sx; destRowPtr = destPtr->bits; nBytes = sizeof(Blt_Pixel) * destPtr->pixelsPerRow; for (y = 0; y < h; y++) { Blt_Pixel *dp, *sp, *send; Blt_Pixel *nextRowPtr; for (dp = destRowPtr, sp = srcRowPtr, send = sp + w; sp < send; sp++) { Blt_Pixel p; p.u32 = sp->u32; dp[0].u32 = dp[1].u32 = dp[2].u32 = dp[3].u32 = p.u32; dp += 4; } nextRowPtr = destRowPtr + destPtr->pixelsPerRow; memcpy(nextRowPtr, destRowPtr, nBytes); nextRowPtr += destPtr->pixelsPerRow; memcpy(nextRowPtr, destRowPtr, nBytes); nextRowPtr += destPtr->pixelsPerRow; memcpy(nextRowPtr, destRowPtr, nBytes); nextRowPtr += destPtr->pixelsPerRow; destRowPtr = nextRowPtr; srcRowPtr += srcPtr->pixelsPerRow; } return destPtr; } static void MarkPicture(Pict *srcPtr) { Blt_Pixel *srcRowPtr; int y; srcRowPtr = srcPtr->bits; for (y = 0; y < srcPtr->height; y++) { Blt_Pixel *sp, *send; for (sp = srcRowPtr, send = sp + srcPtr->width; sp < send; sp++) { if (sp->Alpha != 0x0) { sp->Alpha = 0xFF; } } srcRowPtr += srcPtr->pixelsPerRow; } } #if DRAWTEXT static void MeasureText(FtFont *fontPtr, const char *string, size_t length, size_t *widthPtr, size_t *heightPtr); static size_t GetTextWidth(FtFont *fontPtr, const char *string, size_t length, int kerning); #endif /*HAVE_FT2BUILD_H*/ /* *--------------------------------------------------------------------------- * * ArrayFreeProc -- * * Free the storage associated with the -table switch. * * Results: * None. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void ArrayFreeProc(char *record, int offset, int flags) { Array *arrayPtr = (Array *)(record + offset); if (arrayPtr->values != NULL) { Blt_Free(arrayPtr->values); } arrayPtr->values = NULL; arrayPtr->nValues = 0; } /* *--------------------------------------------------------------------------- * * ArraySwitchProc -- * * Convert a Tcl_Obj list of numbers into an array of floats. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ArraySwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Tcl_Obj **objv; Array *arrayPtr = (Array *)(record + offset); float *values; int i; int objc; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } values = Blt_Malloc(sizeof(float) * objc); if (values == NULL) { Tcl_AppendResult(interp, "can't allocated coordinate array of ", Blt_Itoa(objc), " elements", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i++) { double x; if (Tcl_GetDoubleFromObj(interp, objv[i], &x) != TCL_OK) { Blt_Free(values); return TCL_ERROR; } values[i] = (float)x; } arrayPtr->values = values; arrayPtr->nValues = objc; return TCL_OK; } /* *--------------------------------------------------------------------------- * * AlphaSwitch -- * * Convert a Tcl_Obj representing a number for the alpha value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AlphaSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { int *alphaPtr = (int *)(record + offset); int value; if (Tcl_GetIntFromObj(interp, objPtr, &value) != TCL_OK) { return TCL_ERROR; } if ((value < 0) || (value > 255)) { Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objPtr), "\" for alpha: must be 0..255", (char *)NULL); return TCL_ERROR; } *alphaPtr = value; return TCL_OK; } /* *--------------------------------------------------------------------------- * * AnchorSwitch -- * * Convert a Tcl_Obj representing an anchor. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int AnchorSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Tk_Anchor *anchorPtr = (Tk_Anchor *)(record + offset); if (Tk_GetAnchorFromObj(interp, objPtr, anchorPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ShadowSwitch -- * * Convert a Tcl_Obj representing a number for the alpha value. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ShadowSwitch( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) /* Not used. */ { Shadow *shadowPtr = (Shadow *)(record + offset); int value, alpha; int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if ((objc != 1) && (objc != 2)) { Tcl_AppendResult(interp, "bad shadow list \"", Tcl_GetString(objPtr), "\": should be \"offset ?alpha?\"", (char *)NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[0], &value) != TCL_OK) { return TCL_ERROR; } if ((value < 0) || (value > 20)) { Tcl_AppendResult(interp, "bad offset value \"", Tcl_GetString(objv[0]), "\": must be 0..20", (char *)NULL); return TCL_ERROR; } alpha = 0xA0; if (objc == 2) { if (Tcl_GetIntFromObj(interp, objv[1], &alpha) != TCL_OK) { return TCL_ERROR; } if ((alpha < 0) || (alpha > 255)) { Tcl_AppendResult(interp, "bad value \"", Tcl_GetString(objv[1]), "\" for alpha: must be 0..255", (char *)NULL); return TCL_ERROR; } } shadowPtr->offset = (unsigned int)value; shadowPtr->alpha = (unsigned int)alpha; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_ColorSwitchProc -- * * Convert a Tcl_Obj representing a Blt_Pixel color. * * Results: * The return value is a standard TCL result. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ int Blt_ColorSwitchProc( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ const char *switchName, /* Not used. */ Tcl_Obj *objPtr, /* String representation */ char *record, /* Structure record */ int offset, /* Offset to field in structure */ int flags) { Blt_Pixel *pixelPtr = (Blt_Pixel *)(record + offset); const char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { pixelPtr->u32 = 0x00; return TCL_OK; } if (Blt_GetPixelFromObj(interp, objPtr, pixelPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #if DRAWTEXT /* *--------------------------------------------------------------------------- * * CreateSimpleTextLayout -- * * Get the extents of a possibly multiple-lined text string. * * Results: * Returns via *widthPtr* and *heightPtr* the dimensions of the text * string. * *--------------------------------------------------------------------------- */ static TextLayout * CreateSimpleTextLayout(FtFont *fontPtr, const char *text, size_t textLen, TextStyle *tsPtr) { TextFragment *fp; TextLayout *layoutPtr; size_t count; /* Count # of characters on each line */ int lineHeight; int maxHeight, maxWidth; int nFrags; int width; /* Running dimensions of the text */ const char *p, *endp, *start; int i; size_t size; nFrags = 0; endp = text + ((textLen < 0) ? strlen(text) : textLen); for (p = text; p < endp; p++) { if (*p == '\n') { nFrags++; } } if ((p != text) && (*(p - 1) != '\n')) { nFrags++; } size = sizeof(TextLayout) + (sizeof(TextFragment) * (nFrags - 1)); layoutPtr = Blt_AssertCalloc(1, size); layoutPtr->nFrags = nFrags; nFrags = count = 0; width = maxWidth = 0; maxHeight = tsPtr->padTop; lineHeight = fontPtr->height; fp = layoutPtr->fragments; for (p = start = text; p < endp; p++) { if (*p == '\n') { size_t w; if (count > 0) { w = GetTextWidth(fontPtr, start, count, 1); if (w > maxWidth) { maxWidth = w; } } else { w = 0; } fp->width = w; fp->count = count; fp->sy = fp->y = maxHeight + fontPtr->ascent; fp->text = start; maxHeight += lineHeight; fp++; nFrags++; start = p + 1; /* Start the text on the next line */ count = 0; /* Reset to indicate the start of a new * line */ continue; } count++; } if (nFrags < layoutPtr->nFrags) { size_t w; w = GetTextWidth(fontPtr, start, count, 1); if (w > maxWidth) { maxWidth = w; } fp->width = w; fp->count = count; fp->sy = fp->y = maxHeight + fontPtr->ascent; fp->text = start; maxHeight += lineHeight; nFrags++; } maxHeight += tsPtr->padBottom; maxWidth += PADDING(tsPtr->xPad); fp = layoutPtr->fragments; for (i = 0; i < nFrags; i++, fp++) { switch (tsPtr->justify) { default: case TK_JUSTIFY_LEFT: /* No offset for left justified text strings */ fp->x = fp->sx = tsPtr->padLeft; break; case TK_JUSTIFY_RIGHT: fp->x = fp->sx = (maxWidth - fp->width) - tsPtr->padRight; break; case TK_JUSTIFY_CENTER: fp->x = fp->sx = (maxWidth - fp->width) / 2; break; } } if (tsPtr->underline >= 0) { fp = layoutPtr->fragments; for (i = 0; i < nFrags; i++, fp++) { int first, last; first = fp->text - text; last = first + fp->count; if ((tsPtr->underline >= first) && (tsPtr->underline < last)) { layoutPtr->underlinePtr = fp; layoutPtr->underline = tsPtr->underline - first; break; } } } layoutPtr->width = maxWidth; layoutPtr->height = maxHeight - tsPtr->leader; return layoutPtr; } #endif static void INLINE PutPixel(Pict *destPtr, int x, int y, Blt_Pixel *colorPtr) { if ((x >= 0) && (x < destPtr->width) && (y >= 0) && (y < destPtr->height)) { Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x, y); dp->u32 = colorPtr->u32; } } static INLINE Blt_Pixel PremultiplyAlpha(Blt_Pixel *colorPtr, unsigned int alpha) { Blt_Pixel new; int t; new.u32 = colorPtr->u32; alpha = imul8x8(alpha, colorPtr->Alpha, t); if ((alpha != 0xFF) && (alpha != 0x00)) { new.Red = imul8x8(alpha, colorPtr->Red, t); new.Green = imul8x8(alpha, colorPtr->Green, t); new.Blue = imul8x8(alpha, colorPtr->Blue, t); } new.Alpha = alpha; return new; } static void INLINE HorizLine(Pict *destPtr, int x1, int x2, int y, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; Blt_Pixel *dp, *dend; size_t length; if (x1 > x2) { int tmp; tmp = x1, x1 = x2, x2 = tmp; } destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * y) + x1; length = x2 - x1 + 1; for (dp = destRowPtr, dend = dp + length; dp < dend; dp++) { dp->u32 = colorPtr->u32; } } static void INLINE VertLine(Pict *destPtr, int x, int y1, int y2, Blt_Pixel *colorPtr) { Blt_Pixel *dp; int y; if (y1 > y2) { int tmp; tmp = y1, y1 = y2, y2 = tmp; } dp = destPtr->bits + (destPtr->pixelsPerRow * y1) + x; for (y = y1; y <= y2; y++) { dp->u32 = colorPtr->u32; dp += destPtr->pixelsPerRow; } } static INLINE void BlendPixel(Blt_Pixel *bgPtr, Blt_Pixel *colorPtr, unsigned char weight) { unsigned char alpha; int t1; alpha = imul8x8(colorPtr->Alpha, weight, t1); #ifdef notdef fprintf(stderr, "colorAlpha=%d weight=%d, alpha=%d, beta=%d\n", colorPtr->Alpha, weight, alpha, alpha ^ 0xFF); #endif if (alpha == 0xFF) { bgPtr->u32 = colorPtr->u32; } else if (alpha != 0x00) { unsigned char beta; int t2; beta = alpha ^ 0xFF; bgPtr->Red = imul8x8(alpha, colorPtr->Red, t1) + imul8x8(beta, bgPtr->Red, t2); bgPtr->Green = imul8x8(alpha, colorPtr->Green, t1) + imul8x8(beta, bgPtr->Green, t2); bgPtr->Blue = imul8x8(alpha, colorPtr->Blue, t1) + imul8x8(beta, bgPtr->Blue, t2); bgPtr->Alpha = alpha + imul8x8(beta, bgPtr->Alpha, t2); #ifdef notdef fprintf(stderr, "r=%d, g=%d, b=%d, a=%d, alpha=%d\n", bgPtr->Red, bgPtr->Green, bgPtr->Blue, bgPtr->Alpha, alpha); #endif } } static void INLINE PutPixel2(Pict *destPtr, int x, int y, Blt_Pixel *colorPtr, unsigned char weight) { if ((x >= 0) && (x < destPtr->width) && (y >= 0) && (y < destPtr->height)) { Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x, y); BlendPixel(dp, colorPtr, weight); } } static void PaintLineSegment( Pict *destPtr, int x1, int y1, int x2, int y2, int lineWidth, Blt_Pixel *colorPtr) { int dx, dy, xDir; unsigned long error; Blt_Pixel edge; if (y1 > y2) { int tmp; tmp = y1, y1 = y2, y2 = tmp; tmp = x1, x1 = x2, x2 = tmp; } edge = PremultiplyAlpha(colorPtr, 255); /* First and last Pixels always get Set: */ PutPixel2(destPtr, x1, y1, colorPtr, 255); PutPixel2(destPtr, x2, y2, colorPtr, 255); dx = x2 - x1; dy = y2 - y1; if (dx >= 0) { xDir = 1; } else { xDir = -1; dx = -dx; } if (dy == 0) { /* Horizontal line */ HorizLine(destPtr, x1, x2, y1, &edge); return; } if (dx == 0) { /* Vertical line */ VertLine(destPtr, x1, y1, y2, &edge); return; } if (dx == dy) { /* Diagonal line. */ Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x1, y1); while(dy-- > 0) { dp += destPtr->pixelsPerRow + xDir; dp->u32 = colorPtr->u32; } return; } /* use Wu Antialiasing: */ error = 0; if (dy > dx) { /* y-major line */ unsigned long adjust; /* x1 -= lineWidth / 2; */ adjust = (dx << 16) / dy; while(--dy) { unsigned int weight; error += adjust; ++y1; if (error & ~0xFFFF) { x1 += xDir; error &= 0xFFFF; } weight = (unsigned char)(error >> 8); PutPixel2(destPtr, x1, y1, colorPtr, ~weight); PutPixel2(destPtr, x1 + xDir, y1, colorPtr, weight); } } else { /* x-major line */ unsigned long adjust; /* y1 -= lineWidth / 2; */ adjust = (dy << 16) / dx; while (--dx) { unsigned int weight; error += adjust; x1 += xDir; if (error & ~0xFFFF) { y1++; error &= 0xFFFF; } weight = (error >> 8) & 0xFF; PutPixel2(destPtr, x1, y1, colorPtr, ~weight); PutPixel2(destPtr, x1, y1 + 1, colorPtr, weight); } } } #include "bltPaintDraw.c" static void PaintLineSegment2( Pict *destPtr, int x1, int y1, int x2, int y2, int cw, Blt_Pixel *colorPtr) { Blt_Pixel interior; int dx, dy, xDir; unsigned long error; if (y1 > y2) { int tmp; tmp = y1, y1 = y2, y2 = tmp; tmp = x1, x1 = x2, x2 = tmp; cw = !cw; } if (x1 > x2) { cw = !cw; } interior = PremultiplyAlpha(colorPtr, 255); /* First and last Pixels always get Set: */ PutPixel(destPtr, x1, y1, &interior); PutPixel(destPtr, x2, y2, &interior); dx = x2 - x1; dy = y2 - y1; if (dx >= 0) { xDir = 1; } else { xDir = -1; dx = -dx; } if (dx == 0) { /* Vertical line */ VertLine(destPtr, x1, y1, y2, &interior); return; } if (dy == 0) { /* Horizontal line */ HorizLine(destPtr, x1, x2, y1, &interior); return; } if (dx == dy) { /* Diagonal line. */ Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x1, y1); while(dy-- > 0) { dp += destPtr->pixelsPerRow + xDir; dp->u32 = interior.u32; } return; } /* use Wu Antialiasing: */ error = 0; if (dy > dx) { /* y-major line */ unsigned long adjust; /* x1 -= lineWidth / 2; */ adjust = (dx << 16) / dy; while(--dy) { Blt_Pixel *dp; int x; unsigned char weight; error += adjust; ++y1; if (error & ~0xFFFF) { x1 += xDir; error &= 0xFFFF; } dp = Blt_PicturePixel(destPtr, x1, y1); weight = (unsigned char)(error >> 8); x = x1; if (x >= 0) { if (cw) { *dp = PremultiplyAlpha(colorPtr, weight ^ 0xFF); } else { *dp = interior; } } x += xDir; dp += xDir; if (x >= 0) { if (!cw) { *dp = PremultiplyAlpha(colorPtr, weight); } else { *dp = interior; } } } } else { /* x-major line */ unsigned long adjust; /* y1 -= lineWidth / 2; */ adjust = (dy << 16) / dx; while (--dx) { Blt_Pixel *dp; int y; unsigned char weight; error += adjust; x1 += xDir; if (error & ~0xFFFF) { y1++; error &= 0xFFFF; } dp = Blt_PicturePixel(destPtr, x1, y1); weight = (unsigned char)(error >> 8); y = y1; if (y >= 0) { if (!cw) { *dp = PremultiplyAlpha(colorPtr, weight ^ 0xFF); } else { *dp = interior; } } dp += destPtr->pixelsPerRow; y++; if (y >= 0) { if (cw) { *dp = PremultiplyAlpha(colorPtr, weight); } else { *dp = interior; } } } } destPtr->flags |= (BLT_PIC_BLEND | BLT_PIC_ASSOCIATED_COLORS); } static void PaintPolyline( Pict *destPtr, int nPoints, Point2f *points, int lineWidth, Blt_Pixel *colorPtr) { int i; Region2d r; Point2f p; r.left = r.top = 0; r.right = destPtr->width - 1; r.bottom = destPtr->height - 1; p.x = points[0].x, p.y = points[0].y; for (i = 1; i < nPoints; i++) { Point2f q, next; q.x = points[i].x, q.y = points[i].y; next = q; PaintLineSegment(destPtr, ROUND(p.x), ROUND(p.y), ROUND(q.x), ROUND(q.y), 0, colorPtr); #ifdef notdef if (Blt_LineRectClip(&r, &p, &q)) { PaintLineSegment(destPtr, ROUND(p.x), ROUND(p.y), ROUND(q.x), ROUND(q.y), 1, colorPtr); } #endif p = next; } } #if DRAWTEXT #undef __FTERRORS_H__ #define FT_ERRORDEF( e, v, s ) { e, s }, #define FT_ERROR_START_LIST { #define FT_ERROR_END_LIST { -1, 0 } }; static const char * FtError(FT_Error ftError) { struct ft_errors { int code; const char* msg; }; static struct ft_errors ft_err_mesgs[] = #include FT_ERRORS_H struct ft_errors *fp; for (fp = ft_err_mesgs; fp->msg != NULL; fp++) { if (fp->code == ftError) { return fp->msg; } } return "unknown Freetype error"; } static void MeasureText(FtFont *fontPtr, const char *string, size_t length, size_t *widthPtr, size_t *heightPtr) { FT_Vector pen; /* Untransformed origin */ FT_GlyphSlot slot; FT_Matrix matrix; /* Transformation matrix. */ int maxX, maxY; const char *p, *pend; double radians; int x; FT_Face face; radians = 0.0; matrix.yy = matrix.xx = (FT_Fixed)(cos(radians) * 65536.0); matrix.yx = (FT_Fixed)(sin(radians) * 65536.0); matrix.xy = -matrix.yx; face = fontPtr->face; slot = face->glyph; maxY = maxX = 0; pen.y = 0; x = 0; #ifdef notdef fprintf(stderr, "face->height=%d, face->size->height=%d\n", face->height, (int)face->size->metrics.height); fprintf(stderr, "face->ascender=%d, face->descender=%d\n", face->ascender, face->descender); #endif for (p = string, pend = p + length; p < pend; p++) { maxY += face->size->metrics.height; pen.x = x << 6; for (/*empty*/; (*p != '\n') && (p < pend); p++) { FT_Error ftError; FT_Set_Transform(face, &matrix, &pen); /* Load glyph image into the slot (erase previous) */ ftError = FT_Load_Char(face, *p, FT_LOAD_RENDER); if (ftError != 0) { fprintf(stderr, "can't load character \"%c\": %s\n", *p, FtError(ftError)); continue; /* ignore errors */ } pen.x += slot->advance.x; pen.y += slot->advance.y; } if (pen.x > maxX) { maxX = pen.x; } } #ifdef notdef fprintf(stderr, "w=%d,h=%d\n", maxX >> 6, maxY >> 6); #endif *widthPtr = (size_t)(maxX >> 6); *heightPtr = (size_t)(maxY >> 6); #ifdef notdef fprintf(stderr, "w=%lu,h=%lu\n", (unsigned long)*widthPtr, (unsigned long)*heightPtr); #endif } static size_t GetTextWidth(FtFont *fontPtr, const char *string, size_t length, int kerning) { FT_Vector pen; /* Untransformed origin */ FT_GlyphSlot slot; FT_Matrix matrix; /* Transformation matrix. */ int maxX, maxY; const char *p, *pend; double radians; FT_Face face; int previous; FT_Error ftError; radians = 0.0; matrix.yy = matrix.xx = (FT_Fixed)(cos(radians) * 65536.0); matrix.yx = (FT_Fixed)(sin(radians) * 65536.0); matrix.xy = -matrix.yx; face = fontPtr->face; slot = face->glyph; maxY = maxX = 0; pen.y = pen.x = 0; #ifdef notdef fprintf(stderr, "face->height=%d, face->size->height=%d\n", face->height, (int)face->size->metrics.height); #endif for (p = string, pend = p + length; p < pend; p++) { int current; current = FT_Get_Char_Index(face, *p); if ((kerning) && (previous >= 0)) { FT_Vector delta; FT_Get_Kerning(face, previous, current, FT_KERNING_DEFAULT, &delta); pen.x += delta.x; } FT_Set_Transform(face, &matrix, &pen); previous = current; /* load glyph image into the slot (erase previous one) */ ftError = FT_Load_Glyph(face, current, FT_LOAD_DEFAULT); if (ftError) { fprintf(stderr, "can't load character \"%c\" (%d): %s\n", *p, current, FtError(ftError)); continue; /* ignore errors */ } pen.x += slot->advance.x; pen.y += slot->advance.y; if (pen.x > maxX) { maxX = pen.x; } } return maxX >> 6; } static void BlitGlyph(Pict *destPtr, FT_GlyphSlot slot, int dx, int dy, int xx, int yy, Blt_Pixel *colorPtr) { int gx, gy, gw, gh; #ifdef notdef fprintf(stderr, "dx=%d, dy=%d\n", dx, dy); fprintf(stderr, " slot.bitmap.width=%d\n", (int)slot->bitmap.width); fprintf(stderr, " slot.bitmap.rows=%d\n", slot->bitmap.rows); fprintf(stderr, " slot.bitmap_left=%d\n", (int)slot->bitmap_left); fprintf(stderr, " slot.bitmap_top=%d\n", (int)slot->bitmap_top); fprintf(stderr, " slot.bitmap.pixel_mode=%x\n", slot->bitmap.pixel_mode); fprintf(stderr, " slot.advance.x=%d\n", (int)slot->advance.x); fprintf(stderr, " slot.advance.y=%d\n", (int)slot->advance.y); fprintf(stderr, " slot.format=%c%c%c%c\n", (slot->format >> 24) & 0xFF, (slot->format >> 16) & 0xFF, (slot->format >> 8) & 0xFF, (slot->format & 0xFF)); #endif if ((dx >= destPtr->width) || ((dx + slot->bitmap.width) <= 0) || (dy >= destPtr->height) || ((dy + slot->bitmap.rows) <= 0)) { return; /* No portion of the glyph is visible in the * picture. */ } /* By default, set the region to cover the entire glyph */ gx = 0; gy = 0; gw = slot->bitmap.width; gh = slot->bitmap.rows; /* Determine the portion of the glyph inside the picture. */ if (dx < 0) { /* Left side of glyph overhangs. */ gx -= dx; gw += dx; dx = 0; } if (dy < 0) { /* Top of glyph overhangs. */ gy -= dy; gh += dy; dy = 0; } if ((dx + gw) > destPtr->width) { /* Right side of glyph overhangs. */ gw = destPtr->width - dx; } if ((dy + gh) > destPtr->height) { /* Bottom of glyph overhangs. */ gh = destPtr->height - dy; } if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { Blt_Pixel *destRowPtr; unsigned char *srcRowPtr; int y; srcRowPtr = slot->bitmap.buffer + (gy * slot->bitmap.pitch); destRowPtr = Blt_PicturePixel(destPtr, xx, yy); for (y = gy; y < gh; y++) { Blt_Pixel *dp, *dend; int x; for (dp = destRowPtr, dend = dp+gw, x = gx; dp < dend; x++, dp++) { int pixel; pixel = srcRowPtr[x >> 3] & (1 << (7 - (x & 0x7))); if (pixel != 0x0) { BlendPixel(dp, colorPtr, 0xFF); } } srcRowPtr += slot->bitmap.pitch; destRowPtr += destPtr->pixelsPerRow; } } else { Blt_Pixel *destRowPtr; unsigned char *srcRowPtr; int y; srcRowPtr = slot->bitmap.buffer + ((gy * slot->bitmap.pitch) + gx); destRowPtr = Blt_PicturePixel(destPtr, dx, dy); for (y = gy; y < gh; y++) { Blt_Pixel *dp; unsigned char *sp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + gw; sp < send; sp++, dp++) { if (*sp != 0x0) { BlendPixel(dp, colorPtr, *sp); } } srcRowPtr += slot->bitmap.pitch; destRowPtr += destPtr->pixelsPerRow; } } } static void CopyGrayGlyph(Pict *destPtr, FT_GlyphSlot slot, int x, int y, Blt_Pixel *colorPtr) { int gx, gy, gw, gh; #ifdef notdef fprintf(stderr, "x=%d, y=%d\n", x, y); fprintf(stderr, " slot.bitmap.width=%d\n", slot->bitmap.width); fprintf(stderr, " slot.bitmap.rows=%d\n", slot->bitmap.rows); fprintf(stderr, " slot.bitmap_left=%d\n", slot->bitmap_left); fprintf(stderr, " slot.bitmap_top=%d\n", slot->bitmap_top); fprintf(stderr, " slot.bitmap.pixel_mode=%x\n", slot->bitmap.pixel_mode); fprintf(stderr, " slot.advance.x=%d\n", slot->advance.x); fprintf(stderr, " slot.advance.y=%d\n", slot->advance.y); fprintf(stderr, " slot.format=%c%c%c%c\n", (slot->format >> 24) & 0xFF, (slot->format >> 16) & 0xFF, (slot->format >> 8) & 0xFF, (slot->format & 0xFF)); #endif if ((x >= destPtr->width) || ((x + slot->bitmap.width) <= 0) || (y >= destPtr->height) || ((y + slot->bitmap.rows) <= 0)) { return; /* No portion of the glyph is visible in the * picture. */ } /* By default, set the region to cover the entire glyph */ gx = 0; gy = 0; gw = slot->bitmap.width; gh = slot->bitmap.rows; #ifdef notdef fprintf(stderr, "before: x=%d,y=%d, gx=%d, gy=%d gw=%d gh=%d\n", x, y, gx, gy, gw, gh); #endif /* Determine the portion of the glyph inside the picture. */ if (x < 0) { /* Left side of glyph overhangs. */ gx -= x; gw += x; x = 0; } if (y < 0) { /* Top of glyph overhangs. */ gy -= y; gh += y; y = 0; } if ((x + gw) > destPtr->width) { /* Right side of glyph overhangs. */ gw = destPtr->width - x; } if ((y + gh) > destPtr->height) { /* Bottom of glyph overhangs. */ gh = destPtr->height - y; } #ifdef notdef fprintf(stderr, "after: x=%d,y=%d, gx=%d, gy=%d gw=%d gh=%d\n", x, y, gx, gy, gw, gh); #endif { Blt_Pixel *destRowPtr; unsigned char *srcRowPtr; srcRowPtr = slot->bitmap.buffer + ((gy * slot->bitmap.pitch) + gx); destRowPtr = Blt_PicturePixel(destPtr, x, y); for (y = gy; y < gh; y++) { Blt_Pixel *dp; unsigned char *sp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + gw; sp < send; sp++, dp++) { if (*sp != 0x0) { int t, a; a = imul8x8(*sp, colorPtr->Alpha, t); dp->u32 = colorPtr->u32; dp->Alpha = a; } } srcRowPtr += slot->bitmap.pitch; destRowPtr += destPtr->pixelsPerRow; } } } static void PaintGrayGlyph(Pict *destPtr, FT_GlyphSlot slot, int x, int y, Blt_Pixel *colorPtr) { int gx, gy, gw, gh; #ifdef notdef fprintf(stderr, "x=%d, y=%d\n", x, y); fprintf(stderr, " slot.bitmap.width=%d\n", slot->bitmap.width); fprintf(stderr, " slot.bitmap.rows=%d\n", slot->bitmap.rows); fprintf(stderr, " slot.bitmap_left=%d\n", slot->bitmap_left); fprintf(stderr, " slot.bitmap_top=%d\n", slot->bitmap_top); fprintf(stderr, " slot.bitmap.pixel_mode=%x\n", slot->bitmap.pixel_mode); fprintf(stderr, " slot.advance.x=%d\n", slot->advance.x); fprintf(stderr, " slot.advance.y=%d\n", slot->advance.y); fprintf(stderr, " slot.format=%c%c%c%c\n", (slot->format >> 24) & 0xFF, (slot->format >> 16) & 0xFF, (slot->format >> 8) & 0xFF, (slot->format & 0xFF)); #endif if ((x >= destPtr->width) || ((x + slot->bitmap.width) <= 0) || (y >= destPtr->height) || ((y + slot->bitmap.rows) <= 0)) { return; /* No portion of the glyph is visible in the * picture. */ } /* By default, set the region to cover the entire glyph */ gx = 0; gy = 0; gw = slot->bitmap.width; gh = slot->bitmap.rows; #ifdef notdef fprintf(stderr, "before: x=%d,y=%d, gx=%d, gy=%d gw=%d gh=%d\n", x, y, gx, gy, gw, gh); #endif /* Determine the portion of the glyph inside the picture. */ if (x < 0) { /* Left side of glyph overhangs. */ gx -= x; gw += x; x = 0; } if (y < 0) { /* Top of glyph overhangs. */ gy -= y; gh += y; y = 0; } if ((x + gw) > destPtr->width) { /* Right side of glyph overhangs. */ gw = destPtr->width - x; } if ((y + gh) > destPtr->height) { /* Bottom of glyph overhangs. */ gh = destPtr->height - y; } #ifdef notdef fprintf(stderr, "after: x=%d,y=%d, gx=%d, gy=%d gw=%d gh=%d\n", x, y, gx, gy, gw, gh); #endif { Blt_Pixel *destRowPtr; unsigned char *srcRowPtr; srcRowPtr = slot->bitmap.buffer + ((gy * slot->bitmap.pitch) + gx); destRowPtr = Blt_PicturePixel(destPtr, x, y); for (y = gy; y < gh; y++) { Blt_Pixel *dp; unsigned char *sp, *send; dp = destRowPtr; for (sp = srcRowPtr, send = sp + gw; sp < send; sp++, dp++) { if (*sp != 0x0) { BlendPixel(dp, colorPtr, *sp); } } srcRowPtr += slot->bitmap.pitch; destRowPtr += destPtr->pixelsPerRow; } } } static void CopyMonoGlyph(Pict *destPtr, FT_GlyphSlot slot, int dx, int dy, Blt_Pixel *colorPtr) { int gx, gy, gw, gh; #ifdef notdef fprintf(stderr, "dx=%d, dy=%d\n", dx, dy); fprintf(stderr, " slot.bitmap.width=%d\n", slot->bitmap.width); fprintf(stderr, " slot.bitmap.rows=%d\n", slot->bitmap.rows); fprintf(stderr, " slot.bitmap_left=%d\n", slot->bitmap_left); fprintf(stderr, " slot.bitmap_top=%d\n", slot->bitmap_top); fprintf(stderr, " slot.bitmap.pixel_mode=%x\n", slot->bitmap.pixel_mode); fprintf(stderr, " slot.advance.x=%d\n", slot->advance.x); fprintf(stderr, " slot.advance.y=%d\n", slot->advance.y); fprintf(stderr, " slot.format=%c%c%c%c\n", (slot->format >> 24) & 0xFF, (slot->format >> 16) & 0xFF, (slot->format >> 8) & 0xFF, (slot->format & 0xFF)); #endif if ((dx >= destPtr->width) || ((dx + slot->bitmap.width) <= 0) || (dy >= destPtr->height) || ((dy + slot->bitmap.rows) <= 0)) { return; /* No portion of the glyph is visible in the * picture. */ } /* By default, set the region to cover the entire glyph */ gx = 0; gy = 0; gw = slot->bitmap.width; gh = slot->bitmap.rows; /* Determine the portion of the glyph inside the picture. */ if (dx < 0) { /* Left side of glyph overhangs. */ gx -= dx; gw += dx; dx = 0; } if (dy < 0) { /* Top of glyph overhangs. */ gy -= dy; gh += dy; dy = 0; } if ((dx + gw) > destPtr->width) { /* Right side of glyph overhangs. */ gw = destPtr->width - dx; } if ((dy + gh) > destPtr->height) { /* Bottom of glyph overhangs. */ gh = destPtr->height - dy; } { Blt_Pixel *destRowPtr; unsigned char *srcRowPtr; int y; srcRowPtr = slot->bitmap.buffer + (gy * slot->bitmap.pitch); destRowPtr = Blt_PicturePixel(destPtr, dx, dy); for (y = gy; y < gh; y++) { Blt_Pixel *dp, *dend; int x; for (dp = destRowPtr, dend = dp+gw, x = gx; dp < dend; x++, dp++) { int pixel; pixel = srcRowPtr[x >> 3] & (1 << (7 - (x & 0x7))); if (pixel != 0x0) { dp->u32 = colorPtr->u32; /* BlendPixel(dp, colorPtr, 0xFF); */ } } srcRowPtr += slot->bitmap.pitch; destRowPtr += destPtr->pixelsPerRow; } } } static int ScaleFont(Tcl_Interp *interp, FtFont *fontPtr, FT_F26Dot6 size) { FT_Error ftError; unsigned int xdpi, ydpi; Blt_ScreenDPI(Tk_MainWindow(interp), &xdpi, &ydpi); ftError = FT_Set_Char_Size(fontPtr->face, size, size, xdpi, ydpi); if (ftError) { Tcl_AppendResult(interp, "can't set font size to \"", Blt_Itoa(size), "\": ", FtError(ftError), (char *)NULL); return TCL_ERROR; } fontPtr->height = fontPtr->face->size->metrics.height >> 6; fontPtr->ascent = fontPtr->face->size->metrics.ascender >> 6; fontPtr->descent = fontPtr->face->size->metrics.descender >> 6; return TCL_OK; } static void RotateFont(FtFont *fontPtr, float angle) { /* Set up the transformation matrix. */ double radians; radians = (angle / 180.0) * M_PI; fontPtr->matrix.yy = fontPtr->matrix.xx = (FT_Fixed)(cos(radians) * 65536.0); fontPtr->matrix.yx = (FT_Fixed)(sin(radians) * 65536.0); fontPtr->matrix.xy = -fontPtr->matrix.yx; } #if DRAWTEXT static FtFont * OpenFont(Tcl_Interp *interp, const char *fontName, size_t fontSize) { FtFont *fontPtr; FT_Error ftError; FT_Face face; const char *fileName; fontPtr = Blt_AssertCalloc(1, sizeof(FtFont)); if (ftLibrary == NULL) { ftError = FT_Init_FreeType(&ftLibrary); if (ftError) { Tcl_AppendResult(interp, "can't initialize freetype library: ", FtError(ftError), (char *)NULL); return NULL; } } fontPtr->face = NULL; if (fontName[0] == '@') { fileName = fontName + 1; fontSize <<= 6; } else { double size; fileName = Blt_GetFontFile(interp, fontName, &size); if (fontSize == 0) { fontSize = (int)(size * 64.0 + 0.5); } } ftError = FT_New_Face(ftLibrary, fileName, 0, &face); if (ftError) { Tcl_AppendResult(interp, "can't create face from font file \"", fileName, "\": ", FtError(ftError), (char *)NULL); return NULL; } if (!FT_IS_SCALABLE(face)) { Tcl_AppendResult(interp, "can't use font \"", fontName, "\": font isn't scalable.", (char *)NULL); return NULL; } fontPtr->face = face; if (ScaleFont(interp, fontPtr, fontSize) != TCL_OK) { return NULL; } RotateFont(fontPtr, 0.0f); /* Initializes the rotation matrix. */ return fontPtr; } #else static FtFont * OpenFont(Tcl_Interp *interp, const char *fontName, size_t fontSize) { Tcl_AppendResult(interp, "freetype library not available", (char *)NULL); return NULL; } #endif /*DRAWTEXT*/ static void CloseFont(FtFont *fontPtr) { #ifdef HAVE_LIBXFT if (fontPtr->xftFont != NULL) { XftUnlockFace(fontPtr->xftFont); } else { FT_Done_Face(fontPtr->face); } #else FT_Done_Face(fontPtr->face); #endif /* HAVE_LIBXFT */ Blt_Free(fontPtr); } static int PaintText( Pict *destPtr, FtFont *fontPtr, const char *string, size_t length, int x, int y, /* Anchor coordinates of text. */ int kerning, Blt_Pixel *colorPtr) { #if DRAWTEXT FT_Error ftError; int h; FT_Vector pen; /* Untransformed origin */ const char *p, *pend; FT_GlyphSlot slot; FT_Face face; /* Face object. */ h = destPtr->height; face = fontPtr->face; slot = face->glyph; int xx, yy; int previous; if (destPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(destPtr); } #ifdef notdef fprintf(stderr, "num_faces=%d\n" "face_flags=%x\n" "style_flags=%x\n" "num_glyphs=%d\n" "family_name=%s\n" "style_name=%s\n" "num_fixed_sizes=%d\n" "num_charmaps=%d\n" "units_per_EM=%d\n" "face->size->metrics.height=%d\n" "face->size->metrics.ascender=%d\n" "face->size->metrics.descender=%d\n" "ascender=%d\n" "descender=%d\n" "height=%d\n" "max_advance_width=%d\n" "max_advance_height=%d\n" "underline_position=%d\n" "underline_thickness=%d\n", face->num_faces, face->face_flags, face->style_flags, face->num_glyphs, face->family_name, face->style_name, face->num_fixed_sizes, face->num_charmaps, face->units_per_EM, face->size->metrics.height, face->size->metrics.ascender, face->size->metrics.descender, face->ascender, face->descender, face->height, face->max_advance_width, face->max_advance_height, face->underline_position, (int)face->underline_thickness); #endif xx = x, yy = y; previous = -1; FT_Set_Transform(face, &fontPtr->matrix, NULL); pen.y = (h - y) << 6; xx = x; pen.x = x << 6; for (p = string, pend = p + length; p < pend; p++) { int current; current = FT_Get_Char_Index(face, *p); if ((kerning) && (previous >= 0)) { FT_Vector delta; FT_Get_Kerning(face, previous, current, FT_KERNING_DEFAULT, &delta); pen.x += delta.x; } FT_Set_Transform(face, &fontPtr->matrix, &pen); previous = current; /* load glyph image into the slot (erase previous one) */ ftError = FT_Load_Glyph(face, current, FT_LOAD_DEFAULT); if (ftError) { fprintf(stderr, "can't load character \"%c\": %s\n", *p, FtError(ftError)); continue; /* ignore errors */ } ftError = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL); if (ftError) { fprintf(stderr, "can't render glyph \"%c\": %s\n", *p, FtError(ftError)); continue; /* ignore errors */ } switch(slot->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: CopyMonoGlyph(destPtr, slot, pen.x >> 6, yy - slot->bitmap_top, colorPtr); break; case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: case FT_PIXEL_MODE_GRAY: #ifdef notdef fprintf(stderr, "h=%d, slot->bitmap_top=%d\n", h, slot->bitmap_top); #endif PaintGrayGlyph(destPtr, slot, slot->bitmap_left, h - slot->bitmap_top, colorPtr); case FT_PIXEL_MODE_GRAY2: case FT_PIXEL_MODE_GRAY4: break; } pen.x += slot->advance.x; pen.y += slot->advance.y; previous = -1; } #endif /* HAVE_FT2BUILD_H */ return TCL_OK; } #ifdef notdef static void PaintTextShadow( Blt_Picture picture, Tcl_Interp *interp, const char *string, int x, int y, /* Anchor coordinates of text. */ TextSwitches *switchesPtr, int offset) { int w, h; Blt_Picture blur; Blt_Pixel color; MeasureText(FT_Face face, char *string, float angle, int *widthPtr, int *heightPtr) w = (width + offset*2); h = (height + offset*2); blur = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(blur, &color); color.u32 = 0xA0000000; PaintText(blur, fontPtr, string, x+offset/2, y+offset/2, 0, colorPtr); PaintText(blur, interp, string, x+offset/2, y+offset/2, switchesPtr); Blt_BlurPicture(blur, blur, offset); Blt_BlendPictures(picture, blur, 0, 0, w, h, x+offset/2, y+offset/2); Blt_FreePicture(blur); } #endif #endif /*HAVE_FT2BUILD_H*/ static void xPaintArc(Pict *destPtr, int x1, int y1, int x2, int y2, int lineWidth, Blt_Pixel *colorPtr) { Blt_Pixel *dp; double t; int r2; int radius; int dx, dy; int x, y; int xoff, yoff; int fill = 1; t = 0.0; dx = x2 - x1; dy = y2 - y1; radius = MIN(dx, dy) / 2; xoff = x1; yoff = y1; x = radius; y = 0; dp = Blt_PicturePixel(destPtr, x + xoff - 1, y + yoff); dp->u32 = colorPtr->u32; r2 = radius * radius; if (fill) { PaintLineSegment(destPtr, x1, y + yoff, x + xoff - 2, y + yoff, 1, colorPtr); } while (x > y) { double z; double d, q; unsigned char a; y++; z = sqrt(r2 - (y * y)); d = floor(z) - z; if (d < t) { x--; } dp = Blt_PicturePixel(destPtr, x + xoff, y + yoff); q = FABS(d * 255.0); a = (unsigned int)CLAMP(q); BlendPixel(dp, colorPtr, a); dp--; /* x - 1 */ a = (unsigned int)CLAMP(255.0 - q); BlendPixel(dp, colorPtr, a); t = d; x1++; if (fill) { PaintLineSegment(destPtr, x1, y + yoff, x + xoff - 1, y + yoff, 1, colorPtr); } } } static Point2d PolygonArea(int nPoints, Point2d *points, double *areaPtr) { Point2d *p, *pend; Point2d c; double area; int i; area = c.x = c.y = 0.0; for (p = points, pend = p + nPoints, i = 0; p < pend; p++, i++) { Point2d *q; double factor; int j; j = (i + 1) % nPoints; q = points + j; factor = (p->x * q->y) - (p->y * q->x); area += factor; c.x += (p->x + q->x) * factor; c.y += (p->y + q->y) * factor; } area *= 0.5; c.x /= 6.0 * area; c.y /= 6.0 * area; *areaPtr = area; return c; } static void BlendLine(Pict *destPtr, int x1, int x2, int y, Blt_Pixel *colorPtr) { Blt_Pixel *destRowPtr; Blt_Pixel *dp, *dend; size_t length; if (x1 > x2) { int tmp; tmp = x1, x1 = x2, x2 = tmp; } destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * y) + x1; length = x2 - x1 + 1; for (dp = destRowPtr, dend = dp + length; dp < dend; dp++) { BlendPixel(dp, colorPtr, 0xFF); } } /* * Concave Polygon Scan Conversion * by Paul Heckbert * from "Graphics Gems", Academic Press, 1990 */ /* * concave: scan convert nvert-sided concave non-simple polygon with vertices at * (point[i].x, point[i].y) for i in [0..nvert-1] within the window win by * calling spanproc for each visible span of pixels. * Polygon can be clockwise or counterclockwise. * Algorithm does uniform point sampling at pixel centers. * Inside-outside test done by Jordan's rule: a point is considered inside if * an emanating ray intersects the polygon an odd number of times. * drawproc should fill in pixels from xl to xr inclusive on scanline y, * e.g: * drawproc(y, xl, xr) * int y, xl, xr; * { * int x; * for (x=xl; x<=xr; x++) * pixel_write(x, y, pixelvalue); * } * * Paul Heckbert 30 June 81, 18 Dec 89 */ #include <stdio.h> #include <math.h> typedef struct { /* a polygon edge */ double x; /* x coordinate of edge's intersection with current scanline */ double dx; /* change in x with respect to y */ int i; /* edge number: edge i goes from pt[i] to pt[i+1] */ } ActiveEdge; typedef struct { int nActive; ActiveEdge *active; } AET; /* comparison routines for qsort */ static int n; /* number of vertices */ static Point2f *pt; /* vertices */ static int CompareIndices(const void *a, const void *b) { return (pt[*(int *)a].y <= pt[*(int *)b].y) ? -1 : 1; } static int CompareActive(const void *a, const void *b) { const ActiveEdge *u, *v; u = a, v = b; return (u->x <= v->x) ? -1 : 1; } static void cdelete(AET *tablePtr, int i) /* Remove edge i from active list */ { int j; for (j=0; (j < tablePtr->nActive) && (tablePtr->active[j].i != i); j++) { /*empty*/ } if (j >= tablePtr->nActive) { return; /* edge not in active list; happens at * win->y0*/ } tablePtr->nActive--; #ifdef notdef bcopy(&tablePtr->active[j+1], &tablePtr->active[j], (tablePtr->nActive-j) *sizeof tablePtr->active[0]); #else memmove(&tablePtr->active[j], &tablePtr->active[j+1], (tablePtr->nActive-j) *sizeof tablePtr->active[0]); #endif } /* append edge i to end of active list */ static void cinsert(AET *tablePtr, size_t n, Point2f *points, int i, int y) { int j; Point2f *p, *q; ActiveEdge *edgePtr; j = (i < (n - 1)) ? i + 1 : 0; if (points[i].y < points[j].y) { p = points + i, q = points + j; } else { p = points + j, q = points + i; } edgePtr = tablePtr->active + tablePtr->nActive; assert(tablePtr->nActive < n); /* initialize x position at intersection of edge with scanline y */ edgePtr->dx = (q->x - p->x) / (q->y - p->y); edgePtr->x = edgePtr->dx * (y + 0.5 - p->y) + p->x; edgePtr->i = i; tablePtr->nActive++; } void Blt_PaintPolygon(Pict *destPtr, int nVertices, Point2f *vertices, Blt_Pixel *colorPtr) { int y, k; int top, bot; int *map; /* list of vertex indices, sorted by pt[map[j]].y */ AET aet; n = nVertices; pt = vertices; if (n <= 0) { return; } if (destPtr->height == 0) { return; } map = Blt_AssertMalloc(nVertices * sizeof(unsigned int)); aet.active = Blt_AssertCalloc(nVertices, sizeof(ActiveEdge)); /* create y-sorted array of indices map[k] into vertex list */ for (k = 0; k < n; k++) { map[k] = k; } /* sort map by pt[map[k]].y */ qsort(map, n, sizeof(unsigned int), CompareIndices); aet.nActive = 0; /* start with empty active list */ k = 0; /* map[k] is next vertex to process */ top = MAX(0, ceil(vertices[map[0]].y-.5)); /* ymin of polygon */ bot = MIN(destPtr->height-1, floor(vertices[map[n-1]].y-.5)); /* ymax */ for (y = top; y <= bot; y++) { /* step through scanlines */ unsigned int i, j; /* Scanline y is at y+.5 in continuous coordinates */ /* Check vertices between previous scanline and current one, if any */ for (/*empty*/; (k < n) && (vertices[map[k]].y <= (y +.5)); k++) { /* to simplify, if pt.y=y+.5, pretend it's above */ /* invariant: y-.5 < pt[i].y <= y+.5 */ i = map[k]; /* * Insert or delete edges before and after vertex i (i-1 to i, and * i to i+1) from active list if they cross scanline y */ /* vertex previous to i */ j = (i > 0) ? (i - 1) : (n - 1); if (vertices[j].y <= (y - 0.5)) { /* old edge, remove from active list */ cdelete(&aet, j); } else if (vertices[j].y > (y + 0.5)) { /* new edge, add to active list */ cinsert(&aet, nVertices, vertices, j, y); } j = (i < (n - 1)) ? (i + 1) : 0; /* vertex next after i */ if (vertices[j].y <= (y-.5)) { /* old edge, remove from active list */ cdelete(&aet, i); } else if (vertices[j].y > (y+.5)){ /* new edge, add to active list */ cinsert(&aet, nVertices, vertices, i, y); } } /* Sort active edge list by active[j].x */ qsort(aet.active, aet.nActive, sizeof(ActiveEdge), CompareActive); /* Draw horizontal segments for scanline y */ for (j = 0; j < aet.nActive; j += 2) { /* draw horizontal segments */ int left, right; ActiveEdge *p, *q; p = aet.active + j; q = p+1; /* span 'tween j & j+1 is inside, span tween j+1 & j+2 is outside */ left = (int)ceil (p->x - 0.5); /* left end of span */ right = (int)floor(q->x - 0.5); /* right end of span */ if (left < 0) { left = 0; } if (right >= (int)destPtr->width) { right = destPtr->width - 1; } if (left <= right) { BlendLine(destPtr, left, right, y, colorPtr); } p->x += p->dx; /* increment edge coords */ q->x += q->dx; } } Blt_Free(aet.active); Blt_Free(map); } static void GetPolygonBoundingBox(size_t nVertices, Point2f *vertices, Region2f *regionPtr) { Point2f *pp, *pend; regionPtr->left = regionPtr->top = FLT_MAX; regionPtr->right = regionPtr->bottom = -FLT_MAX; for (pp = vertices, pend = pp + nVertices; pp < pend; pp++) { if (pp->x < regionPtr->left) { regionPtr->left = pp->x; } else if (pp->x > regionPtr->right) { regionPtr->right = pp->x; } if (pp->y < regionPtr->top) { regionPtr->top = pp->y; } else if (pp->y > regionPtr->bottom) { regionPtr->bottom = pp->y; } } } static void TranslatePolygon(size_t nVertices, Point2f *vertices, float x, float y, float scale) { Point2f *pp, *pend; for (pp = vertices, pend = pp + nVertices; pp < pend; pp++) { pp->x = (pp->x + x) * scale; pp->y = (pp->y + y) * scale; } } static void PaintPolygonAA(Pict *destPtr, size_t nVertices, Point2f *vertices, Region2f *regionPtr, Blt_Pixel *colorPtr) { Region2f r2; int w, h; Blt_Picture big, tmp; Blt_Pixel color; Point2f *v; int x1, x2, y1, y2; x1 = y1 = 0; x2 = destPtr->width, y2 = destPtr->height; if (regionPtr->left > 0) { x1 = (int)floor(regionPtr->left); } if (regionPtr->top > 0) { y1 = (int)floor(regionPtr->top); } if (regionPtr->right < x2) { double d; d = ceil(regionPtr->right); x2 = (int)ceil(regionPtr->right); } if (regionPtr->bottom < y2) { y2 = (int)ceil(regionPtr->bottom); } v = Blt_AssertMalloc(nVertices * sizeof(Point2f)); memcpy(v, vertices, sizeof(Point2f) * nVertices); TranslatePolygon(nVertices, v, -x1+1, -y1+1, 4.0f); GetPolygonBoundingBox(nVertices, v, &r2); w = (x2 - x1 + 2) * 4; h = (y2 - y1 + 2) * 4; big = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(big, &color); color.Alpha = colorPtr->Alpha; Blt_PaintPolygon(big, nVertices, v, &color); Blt_Free(v); w = (x2 - x1 + 2); h = (y2 - y1 + 2); tmp = Blt_CreatePicture(w, h); Blt_ResamplePicture(tmp, big, bltBoxFilter, bltBoxFilter); Blt_FreePicture(big); Blt_ApplyColorToPicture(tmp, colorPtr); /* Replace the bounding box in the original with the new. */ Blt_BlendPictures(destPtr, tmp, 0, 0, w, h, (int)floor(regionPtr->left)-1, (int)floor(regionPtr->top)-1); Blt_FreePicture(tmp); } static void PaintPolygonShadow(Pict *destPtr, size_t nVertices, Point2f *vertices, Region2f *regionPtr, Shadow *shadowPtr) { int w, h; Blt_Picture blur, tmp; Point2f *v; Blt_Pixel color; int x1, x2, y1, y2; Region2f r2; x1 = y1 = 0; x2 = destPtr->width, y2 = destPtr->height; if (regionPtr->left > 0) { x1 = (int)regionPtr->left; } if (regionPtr->top > 0) { y1 = (int)regionPtr->top; } if (regionPtr->right < x2) { x2 = (int)ceil(regionPtr->right); } if (regionPtr->bottom < y2) { y2 = (int)ceil(regionPtr->bottom); } if ((x1 > 0) || (y1 > 0)) { v = Blt_AssertMalloc(nVertices * sizeof(Point2f)); memcpy(v, vertices, sizeof(Point2f) * nVertices); TranslatePolygon(nVertices, v, -x1, -y1, 1.0f); } else { v = vertices; } w = (x2 - x1 + shadowPtr->offset*8); h = (y2 - y1 + shadowPtr->offset*8); tmp = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(tmp, &color); color.Alpha = shadowPtr->alpha; GetPolygonBoundingBox(nVertices, v, &r2); Blt_PaintPolygon(tmp, nVertices, v, &color); if (v != vertices) { Blt_Free(v); } blur = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(blur, &color); Blt_CopyPictureBits(blur, tmp, 0, 0, w, h, shadowPtr->offset*2, shadowPtr->offset*2); Blt_BlurPicture(blur, blur, shadowPtr->offset); Blt_MaskPicture(blur, tmp, 0, 0, w, h, 0, 0, &color); Blt_FreePicture(tmp); Blt_BlendPictures(destPtr, blur, 0, 0, w, h, x1, y1); Blt_FreePicture(blur); } static void PaintPolygonAA2(Pict *destPtr, size_t nVertices, Point2f *vertices, Region2f *regionPtr, Blt_Pixel *colorPtr, Shadow *shadowPtr) { Region2f r2; Blt_Picture big, tmp; Blt_Pixel color; /* * Get the minimum size region to draw both a supersized polygon and * shadow. * * Draw the shadow and then the polygon. Everything is 4x bigger including * the shadow offset. This is a much bigger blur. * * Resample the image back down to 1/4 the size and blend it into * the destination picture. */ big = Blt_CreatePicture(destPtr->width * 4, destPtr->height * 4); TranslatePolygon(nVertices, vertices, 0.0f, 0.0f, 4.0f); color.u32 = 0x00; Blt_BlankPicture(big, &color); GetPolygonBoundingBox(nVertices, vertices, &r2); PaintPolygonShadow(big, nVertices, vertices, &r2, shadowPtr); Blt_PaintPolygon(big, nVertices, vertices, colorPtr); tmp = Blt_CreatePicture(destPtr->width, destPtr->height); Blt_ResamplePicture(tmp, big, bltBoxFilter, bltBoxFilter); Blt_FreePicture(big); Blt_BlendPictures(destPtr, tmp, 0, 0, destPtr->width, destPtr->height, 0,0); Blt_FreePicture(tmp); } static void DrawCircle(Blt_Picture picture, int x, int y, int radius, CircleSwitches *switchesPtr) { int filled; filled = (switchesPtr->fill.u32 != 0x00); if (switchesPtr->antialiased) { int nSamples = 4; Pict *bigPtr, *tmpPtr; int w, h; Blt_Pixel color; int offset, r, lw; int cx, cy; r = radius * nSamples; w = h = r + r; offset = switchesPtr->shadow.offset * nSamples; /* Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ bigPtr = Blt_CreatePicture(w+(1+offset)*nSamples,h+(1+offset)*nSamples); cx = bigPtr->width / 2; cy = bigPtr->height / 2; color.u32 = 0x00; color.Alpha = 0x00; Blt_BlankPicture(bigPtr, &color); if (switchesPtr->shadow.offset > 0) { color.Alpha = switchesPtr->shadow.alpha; /* Either ring or full circle for blur stencil. */ lw = switchesPtr->lineWidth * nSamples; if (filled) { lw = 0; } PaintEllipse(bigPtr, cx, cy, r, r, lw, &color, 0); Blt_BlurPicture(bigPtr, bigPtr, offset/2); /* Offset the circle from the shadow. */ cx -= offset; cy -= offset; offset = switchesPtr->shadow.offset; w = h = radius + radius + (1 + offset) * 2; tmpPtr = Blt_CreatePicture(w, h); Blt_ResamplePicture(tmpPtr, bigPtr, bltBoxFilter, bltBoxFilter); Blt_BlendPictures(picture, tmpPtr, 0, 0, w, h, x-w/2+offset, y-h/2+offset); color.u32 = 0x00; color.Alpha = 0x00; Blt_BlankPicture(bigPtr, &color); Blt_FreePicture(tmpPtr); } lw = switchesPtr->lineWidth * nSamples; if ((lw > 0) && (r > lw) && (switchesPtr->outline.u32 != 0x00)) { /* Paint ring outline. */ PaintEllipse(bigPtr, cx, cy, r, r, lw, &switchesPtr->outline, 0); r -= lw; } if (filled) { /* Paint filled interior */ PaintEllipse(bigPtr, cx, cy, r, r, 0, &switchesPtr->fill, 0); } offset = switchesPtr->shadow.offset; w = h = radius + radius + (1 + offset) * 2; tmpPtr = Blt_CreatePicture(w, h); Blt_ResamplePicture(tmpPtr, bigPtr, bltBoxFilter, bltBoxFilter); #ifdef notdef fprintf(stderr, "big=%dx%d, blur=%d\n", bigPtr->width,bigPtr->height, (switchesPtr->shadow.offset * nSamples)/2); #endif Blt_FreePicture(bigPtr); /*Blt_ApplyColorToPicture(tmpPtr, &switchesPtr->fill); */ #ifdef notdef Blt_BlendPictures(picture, tmpPtr, 0, 0, w, h, x-w/2+offset, y-h/2+offset); #endif { int yy; Blt_Pixel *destRowPtr; destRowPtr = Blt_PictureBits(tmpPtr); for (yy = 0; yy < Blt_PictureHeight(tmpPtr); yy++) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + Blt_PictureWidth(tmpPtr); dp < dend; dp++) { if (dp->Alpha != 0x00) { dp->Red = switchesPtr->fill.Red; dp->Green = switchesPtr->fill.Green; dp->Blue = switchesPtr->fill.Blue; } } destRowPtr += Blt_PictureStride(tmpPtr); } } #ifndef notdef Blt_BlendPictures(picture, tmpPtr, 0, 0, w, h, x-w/2, y-h/2); #else Blt_CopyPictureBits(picture, tmpPtr, 0, 0, w, h, x-w/2, y-h/2); #endif Blt_FreePicture(tmpPtr); } else if (switchesPtr->shadow.offset > 0) { Pict *blurPtr; int w, h; Blt_Pixel color; int offset, r, lw; int cx, cy; w = h = (radius + radius); r = radius; offset = switchesPtr->shadow.offset; /* Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ blurPtr = Blt_CreatePicture(w+(offset*4), h+(offset*4)); cx = blurPtr->width / 2; cy = blurPtr->height / 2; color.u32 = 0x00; Blt_BlankPicture(blurPtr, &color); color.Alpha = switchesPtr->shadow.alpha; /* Either ring or full circle for blur stencil. */ lw = switchesPtr->lineWidth; if (filled) { lw = 0; } PaintEllipse(blurPtr, cx, cy, r, r, lw, &color, 0); Blt_BlurPicture(blurPtr, blurPtr, offset); /* Offset the circle from the shadow. */ cx -= offset; cy -= offset; lw = switchesPtr->lineWidth; if ((lw > 0) && (r > lw) && (switchesPtr->outline.u32 != 0x00)) { /* Paint ring outline. */ PaintEllipse(blurPtr, cx, cy, r, r, lw, &switchesPtr->outline, 0); r -= lw; } if (filled) { /* Paint filled interior */ PaintEllipse(blurPtr, cx, cy, r, r, 0, &switchesPtr->fill, 0); } x -= blurPtr->width/2 + offset; if (x < 0) { x = 0; } y -= blurPtr->height/2 + offset; if (y < 0) { y = 0; } Blt_BlendPictures(picture, blurPtr, 0, 0, blurPtr->width, blurPtr->height, x, y); Blt_FreePicture(blurPtr); } else { int r; r = radius; if ((switchesPtr->lineWidth > 0) && (r > switchesPtr->lineWidth)) { /* Paint ring outline. */ PaintEllipse(picture, x, y, r, r, switchesPtr->lineWidth, &switchesPtr->outline, 1); r -= switchesPtr->lineWidth; } if (filled) { /* Paint filled interior */ PaintEllipse(picture, x, y, r, r, 0, &switchesPtr->fill, 1); } } } static void DrawCircle2(Blt_Picture picture, int x, int y, int radius, CircleSwitches *switchesPtr) { int filled; filled = (switchesPtr->fill.u32 != 0x00); if (switchesPtr->antialiased) { int nSamples = 4; Pict *bigPtr, *tmpPtr; int w, h; Blt_Pixel color; int offset, r, lw; int cx, cy; Blt_Pixel *srcRowPtr, *sp, *send; r = radius; w = h = r + r; offset = switchesPtr->shadow.offset * nSamples; /* Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ bigPtr = BgPicture(picture, x, y, w, h); cx = bigPtr->width / 2; cy = bigPtr->height / 2; #ifdef notdef if (switchesPtr->shadow.offset > 0) { color.Alpha = switchesPtr->shadow.alpha; /* Either ring or full circle for blur stencil. */ lw = switchesPtr->lineWidth * nSamples; if (filled) { lw = 0; } PaintEllipse(bigPtr, cx, cy, r, r, lw, &color, 0); Blt_BlurPicture(bigPtr, bigPtr, offset/2); /* Offset the circle from the shadow. */ cx -= offset; cy -= offset; } lw = switchesPtr->lineWidth * nSamples; if ((lw > 0) && (r > lw) && (switchesPtr->outline.u32 != 0x00)) { /* Paint ring outline. */ PaintEllipse(bigPtr, cx, cy, r, r, lw, &switchesPtr->outline, 0); r -= lw; } #endif if (filled) { /* Paint filled interior */ PaintEllipse(bigPtr, cx, cy, r*3, r*3, 0, &switchesPtr->fill, 0); } offset = switchesPtr->shadow.offset; tmpPtr = Blt_CreatePicture(w, h); Blt_ResamplePicture(tmpPtr, bigPtr, bltBoxFilter, bltBoxFilter); #ifdef notdef MarkPicture(tmpPtr); fprintf(stderr, "big=%dx%d, blur=%d\n", bigPtr->width,bigPtr->height, (switchesPtr->shadow.offset * nSamples)/2); #endif Blt_FreePicture(bigPtr); /*Blt_ApplyColorToPicture(tmpPtr, &switchesPtr->fill); */ Blt_BlendPictures(picture, tmpPtr, 0, 0, w, h, x-w/2+offset, y-h/2+offset); Blt_FreePicture(tmpPtr); } else if (switchesPtr->shadow.offset > 0) { Pict *blurPtr; int w, h; Blt_Pixel color; int offset, r, lw; int cx, cy; w = h = (radius + radius); r = radius; offset = switchesPtr->shadow.offset; /* Scale the region forming the bounding box of the ellipse into a new * picture. The bounding box is scaled by *nSamples* times. */ blurPtr = Blt_CreatePicture(w+(offset*4), h+(offset*4)); cx = blurPtr->width / 2; cy = blurPtr->height / 2; color.u32 = 0x00; Blt_BlankPicture(blurPtr, &color); color.Alpha = switchesPtr->shadow.alpha; /* Either ring or full circle for blur stencil. */ lw = switchesPtr->lineWidth; if (filled) { lw = 0; } PaintEllipse(blurPtr, cx, cy, r, r, lw, &color, 0); Blt_BlurPicture(blurPtr, blurPtr, offset); /* Offset the circle from the shadow. */ cx -= offset; cy -= offset; lw = switchesPtr->lineWidth; if ((lw > 0) && (r > lw) && (switchesPtr->outline.u32 != 0x00)) { /* Paint ring outline. */ PaintEllipse(blurPtr, cx, cy, r, r, lw, &switchesPtr->outline, 0); r -= lw; } if (filled) { /* Paint filled interior */ PaintEllipse(blurPtr, cx, cy, r, r, 0, &switchesPtr->fill, 0); } x -= blurPtr->width/2 + offset; if (x < 0) { x = 0; } y -= blurPtr->height/2 + offset; if (y < 0) { y = 0; } Blt_BlendPictures(picture, blurPtr, 0, 0, blurPtr->width, blurPtr->height, x, y); Blt_FreePicture(blurPtr); } else { int r; r = radius; if ((switchesPtr->lineWidth > 0) && (r > switchesPtr->lineWidth)) { /* Paint ring outline. */ PaintEllipse(picture, x, y, r, r, switchesPtr->lineWidth, &switchesPtr->outline, 1); r -= switchesPtr->lineWidth; } if (filled) { /* Paint filled interior */ PaintEllipse(picture, x, y, r, r, 0, &switchesPtr->fill, 1); } } } /* *--------------------------------------------------------------------------- * * CircleOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int CircleOp( Blt_Picture picture, Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { CircleSwitches switches; int x, y, radius; if (objc < 5) { Tcl_AppendResult(interp, "wrong # of coordinates for circle", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[5], &radius) != TCL_OK)) { return TCL_ERROR; } /* Process switches */ switches.lineWidth = 1; switches.fill.u32 = 0xffffffff; switches.outline.u32 = 0xff000000; switches.alpha = -1; switches.antialiased = 0; switches.shadow.offset = 0; switches.shadow.alpha = 0xa0; if (Blt_ParseSwitches(interp, circleSwitches, objc - 6, objv + 6, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } #ifdef notdef if (switches.alpha != -1) { switches.fill.Alpha = switches.alpha; switches.outline.Alpha = switches.alpha; } #endif DrawCircle(picture, x, y, radius, &switches); return TCL_OK; } /* *--------------------------------------------------------------------------- * * EllipseOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int EllipseOp( Blt_Picture picture, Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { CircleSwitches switches; int x, y, a, b; if (objc < 7) { Tcl_AppendResult(interp, "wrong # of coordinates for circle", (char *)NULL); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[5], &a) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[6], &b) != TCL_OK)) { return TCL_ERROR; } /* Process switches */ switches.lineWidth = 0; switches.fill.u32 = 0xFFFFFFFF; switches.outline.u32 = 0xFF000000; switches.alpha = -1; switches.antialiased = FALSE; if (Blt_ParseSwitches(interp, circleSwitches, objc - 7, objv + 7, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.alpha != -1) { switches.fill.Alpha = switches.alpha; switches.outline.Alpha = switches.alpha; } if ((switches.lineWidth >= a) || (switches.lineWidth >= b)) { /* If the requested line width is greater than the radius then draw a * solid ellipse instead. */ switches.lineWidth = 0; } if (switches.antialiased) { PaintEllipseAA(picture, x, y, a, b, switches.lineWidth, &switches.fill); } else { PaintEllipse(picture, x, y, a, b, switches.lineWidth, &switches.fill, 1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * LineOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int LineOp( Blt_Picture picture, Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { LineSwitches switches; size_t nPoints; Point2f *points; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; switches.alpha = -1; if (Blt_ParseSwitches(interp, lineSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.alpha != -1) { switches.bg.Alpha = switches.alpha; } if (switches.x.nValues != switches.y.nValues) { Tcl_AppendResult(interp, "-x and -y coordinate lists must have the ", " same number of coordinates.",(char *)NULL); return TCL_ERROR; } points = NULL; if (switches.x.nValues > 0) { size_t i; float *x, *y; nPoints = switches.x.nValues; points = Blt_Malloc(sizeof(Point2f) * nPoints); if (points == NULL) { Tcl_AppendResult(interp, "can't allocate memory for ", Blt_Itoa(nPoints + 1), " points", (char *)NULL); return TCL_ERROR; } x = (float *)switches.x.values; y = (float *)switches.y.values; for (i = 0; i < nPoints; i++) { points[i].x = x[i]; points[i].y = y[i]; } Blt_Free(switches.x.values); Blt_Free(switches.y.values); switches.x.values = switches.y.values = NULL; } else if (switches.coords.nValues > 0) { size_t i, j; float *coords; if (switches.coords.nValues & 0x1) { Tcl_AppendResult(interp, "bad -coords list: ", "must have an even number of values", (char *)NULL); return TCL_ERROR; } nPoints = (switches.coords.nValues / 2); points = Blt_Malloc(sizeof(Point2f)* nPoints); if (points == NULL) { Tcl_AppendResult(interp, "can't allocate memory for ", Blt_Itoa(nPoints + 1), " points", (char *)NULL); return TCL_ERROR; } coords = (float *)switches.coords.values; for (i = 0, j = 0; i < switches.coords.nValues; i += 2, j++) { points[j].x = coords[i]; points[j].y = coords[i+1]; } Blt_Free(switches.coords.values); switches.coords.values = NULL; } if (points != NULL) { PaintPolyline(picture, nPoints, points, switches.lineWidth, &switches.bg); Blt_Free(points); } Blt_FreeSwitches(lineSwitches, (char *)&switches, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * PolygonOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * * $pict draw polygon -coords $coords -color $color *--------------------------------------------------------------------------- */ static int PolygonOp( Pict *destPtr, Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { PolygonSwitches switches; size_t nVertices; Point2f *vertices; Region2f r; memset(&switches, 0, sizeof(switches)); switches.bg.u32 = 0xFFFFFFFF; switches.alpha = -1; if (Blt_ParseSwitches(interp, polygonSwitches, objc - 3, objv + 3, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.alpha != -1) { switches.bg.Alpha = switches.alpha; } if (switches.x.nValues != switches.y.nValues) { Tcl_AppendResult(interp, "-x and -y coordinate lists must have the ", " same number of coordinates.",(char *)NULL); return TCL_ERROR; } vertices = NULL; r.top = r.left = FLT_MAX, r.bottom = r.right = -FLT_MAX; if (switches.x.nValues > 0) { size_t i; float *x, *y; nVertices = switches.x.nValues; vertices = Blt_Malloc(sizeof(Point2f) * (switches.x.nValues + 1)); if (vertices == NULL) { Tcl_AppendResult(interp, "can't allocate memory for ", Blt_Itoa(nVertices + 1), " vertices", (char *)NULL); return TCL_ERROR; } x = (float *)switches.x.values; y = (float *)switches.y.values; for (i = 0; i < switches.x.nValues; i++) { vertices[i].x = x[i]; vertices[i].y = y[i]; if (r.left > x[i]) { r.left = x[i]; } else if (r.right < x[i]) { r.right = x[i]; } if (r.top > y[i]) { r.top = y[i]; } else if (r.bottom < y[i]) { r.bottom = y[i]; } } if ((x[0] != x[i-1]) || (y[0] != y[i-1])) { vertices[i].x = x[0]; vertices[i].y = y[0]; nVertices++; } Blt_Free(switches.x.values); Blt_Free(switches.y.values); switches.x.values = switches.y.values = NULL; } else if (switches.coords.nValues > 0) { size_t i, j; float *coords; if (switches.coords.nValues & 0x1) { Tcl_AppendResult(interp, "bad -coords list: ", "must have an even number of values", (char *)NULL); return TCL_ERROR; } nVertices = (switches.coords.nValues / 2); vertices = Blt_Malloc(sizeof(Point2f)* (nVertices + 1)); if (vertices == NULL) { Tcl_AppendResult(interp, "can't allocate memory for ", Blt_Itoa(nVertices + 1), " vertices", (char *)NULL); return TCL_ERROR; } coords = (float *)switches.coords.values; for (i = 0, j = 0; i < switches.coords.nValues; i += 2, j++) { vertices[j].x = coords[i]; vertices[j].y = coords[i+1]; if (r.left > coords[i]) { r.left = coords[i]; } else if (r.right < coords[i]) { r.right = coords[i]; } if (r.top > coords[i+1]) { r.top = coords[i+1]; } else if (r.bottom < coords[i+1]) { r.bottom = coords[i+1]; } } if ((coords[0] != coords[i-2]) || (coords[1] != coords[i-1])) { vertices[j].x = coords[0]; vertices[j].y = coords[1]; nVertices++; } Blt_Free(switches.coords.values); switches.coords.values = NULL; } if (vertices != NULL) { if ((r.left < destPtr->width) && (r.right >= 0) && (r.top < destPtr->height) && (r.bottom >= 0)) { if (switches.antialiased) { PaintPolygonAA2(destPtr, nVertices, vertices, &r, &switches.bg, &switches.shadow); } else { if (switches.shadow.offset > 0) { PaintPolygonShadow(destPtr, nVertices, vertices, &r, &switches.shadow); } Blt_PaintPolygon(destPtr, nVertices, vertices, &switches.bg); } } Blt_Free(vertices); } Blt_FreeSwitches(polygonSwitches, (char *)&switches, 0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * RectangleOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int RectangleOp( Blt_Picture picture, Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { RectangleSwitches switches; PictRegion r; if (Blt_GetBBoxFromObjv(interp, 4, objv + 3, &r) != TCL_OK) { return TCL_ERROR; } memset(&switches, 0, sizeof(switches)); /* Process switches */ switches.lineWidth = 0; switches.bg.u32 = 0xFFFFFFFF; switches.alpha = -1; if (Blt_ParseSwitches(interp, rectangleSwitches, objc - 7, objv + 7, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.alpha != -1) { switches.bg.Alpha = switches.alpha; } if (switches.shadow.offset > 0) { PaintRectangleShadow(picture, r.x, r.y, r.w, r.h, switches.radius, switches.lineWidth, &switches.shadow); } if ((switches.antialiased) && (switches.radius > 0)) { PaintRectangleAA(picture, r.x, r.y, r.w, r.h, switches.radius, switches.lineWidth, &switches.bg); } else { PaintRectangle(picture, r.x, r.y, r.w, r.h, switches.radius, switches.lineWidth, &switches.bg); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TextOp -- * * Results: * Returns a standard TCL return value. * * Side effects: * None. * * image draw text string x y switches *--------------------------------------------------------------------------- */ static int TextOp( Pict *destPtr, /* Picture. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { #if DRAWTEXT FtFont *fontPtr; TextSwitches switches; const char *string; const char *fontName; int length; int result; int x, y; string = Tcl_GetStringFromObj(objv[3], &length); if ((Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK)) { return TCL_ERROR; } /* Process switches */ switches.alpha = -1; switches.anchor = TK_ANCHOR_NW; switches.angle = 0.0; switches.shadow.offset = 0; switches.color.u32 = 0xFF000000; /* black. */ switches.shadow.alpha = 0xA0; /* black. */ switches.fontObjPtr = Tcl_NewStringObj("Arial 12", -1); switches.fontSize = 0; switches.kerning = FALSE; switches.justify = TK_JUSTIFY_LEFT; if (Blt_ParseSwitches(interp, textSwitches, objc - 6, objv + 6, &switches, BLT_SWITCH_DEFAULTS) < 0) { return TCL_ERROR; } if (switches.alpha != -1) { switches.color.Alpha = switches.alpha; } fontName = Tcl_GetString(switches.fontObjPtr); fontPtr = OpenFont(interp, fontName, switches.fontSize); if (fontPtr == NULL) { fprintf(stderr, "can't open font %s\n", fontName); return TCL_ERROR; } if (destPtr->flags & BLT_PIC_ASSOCIATED_COLORS) { Blt_UnassociateColors(destPtr); } if (switches.angle != 0.0) { TextStyle ts; TextLayout *layoutPtr; Blt_Ts_InitStyle(ts); Blt_Ts_SetJustify(ts, switches.justify); layoutPtr = CreateSimpleTextLayout(fontPtr, string, length, &ts); if (fontPtr->face->face_flags & FT_FACE_FLAG_SCALABLE) { TextFragment *fp, *fend; double rw, rh; Blt_RotateStartingTextPositions(layoutPtr, switches.angle); Blt_GetBoundingBox(layoutPtr->width, layoutPtr->height, switches.angle, &rw, &rh, (Point2d *)NULL); Blt_TranslateAnchor(x, y, (int)(rw), (int)(rh), switches.anchor, &x, &y); RotateFont(fontPtr, switches.angle); for (fp = layoutPtr->fragments, fend = fp + layoutPtr->nFrags; fp < fend; fp++) { PaintText(destPtr, fontPtr, fp->text, fp->count, x + fp->sx, y + fp->sy, switches.kerning, &switches.color); } } else { Blt_Picture tmp; Blt_Pixel color; Pict *rotPtr; TextFragment *fp, *fend; tmp = Blt_CreatePicture(layoutPtr->width, layoutPtr->height); color.u32 = 0x00FF0000; Blt_BlankPicture(tmp, &color); color.Alpha = 0xFF; for (fp = layoutPtr->fragments, fend = fp + layoutPtr->nFrags; fp < fend; fp++) { PaintText(tmp, fontPtr, fp->text, fp->count, fp->sx, fp->sy, switches.kerning, &switches.color); } rotPtr = Blt_RotatePicture(tmp, switches.angle); Blt_FreePicture(tmp); Blt_TranslateAnchor(x, y, rotPtr->width, rotPtr->height, switches.anchor, &x, &y); Blt_BlendPictures(destPtr, rotPtr, 0, 0, rotPtr->width, rotPtr->height, x, y); Blt_FreePicture(rotPtr); } Blt_Free(layoutPtr); } else { size_t w, h; MeasureText(fontPtr, string, length, &w, &h); Blt_TranslateAnchor(x, y, w, h, switches.anchor, &x, &y); #ifdef notdef fprintf(stderr, "string=%s w=%d h=%d\n", string, w, h); #endif if (switches.shadow.offset > 0) { Blt_Pixel color; Pict *blurPtr, *tmpPtr; int offset = switches.shadow.offset; MeasureText(fontPtr, string, length, &w, &h); tmpPtr = Blt_CreatePicture(w, h); color.u32 = 0x00000000; Blt_BlankPicture(tmpPtr, &color); color.Alpha = switches.shadow.alpha; PaintText(tmpPtr, fontPtr, string, length, 0, fontPtr->ascent, switches.kerning, &color); blurPtr = Blt_CreatePicture(w+offset*4, h+offset*4); color.Alpha = 0; Blt_BlankPicture(blurPtr, &color); Blt_CopyPictureBits(blurPtr, tmpPtr, 0, 0, w, h, offset, offset); Blt_FreePicture(tmpPtr); Blt_BlurPicture(blurPtr, blurPtr, offset); Blt_BlendPictures(destPtr, blurPtr, 0, 0, blurPtr->width, blurPtr->height, x, y); Blt_FreePicture(blurPtr); } y += fontPtr->ascent; result = PaintText(destPtr, fontPtr, string, length, x, y, switches.kerning, &switches.color); } CloseFont(fontPtr); Blt_FreeSwitches(textSwitches, (char *)&switches, 0); #endif return TCL_OK; } Blt_OpSpec bltPictDrawOps[] = { {"circle", 1, CircleOp, 4, 0, "x y r ?switches?",}, {"ellipse", 1, EllipseOp, 5, 0, "x y a b ?switches?",}, {"line", 1, LineOp, 3, 0, "?switches?",}, {"polygon", 1, PolygonOp, 3, 0, "?switches?",}, {"rectangle", 1, RectangleOp, 7, 0, "x1 y1 x2 y2 ?switches?",}, {"text", 1, TextOp, 6, 0, "string x y ?switches?",}, }; int bltPictDrawNOps = sizeof(bltPictDrawOps) / sizeof(Blt_OpSpec); static void Polyline2(Pict *destPtr, int x1, int y1, int x2, int y2, Blt_Pixel *colorPtr) { Blt_Pixel *dp; int dx, dy, xDir; unsigned long error; if (y1 > y2) { int tmp; tmp = y1, y1 = y2, y2 = tmp; tmp = x1, x1 = x2, x2 = tmp; } /* First and last Pixels always get Set: */ dp = Blt_PicturePixel(destPtr, x1, y1); dp->u32 = colorPtr->u32; dp = Blt_PicturePixel(destPtr, x2, y2); dp->u32 = colorPtr->u32; dx = x2 - x1; dy = y2 - y1; if (dx >= 0) { xDir = 1; } else { xDir = -1; dx = -dx; } if (dx == 0) { /* Vertical line */ Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x1, y1); while (dy-- > 0) { dp += destPtr->pixelsPerRow; dp->u32 = colorPtr->u32; } return; } if (dy == 0) { /* Horizontal line */ Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x1, y1); while(dx-- > 0) { dp += xDir; dp->u32 = colorPtr->u32; } return; } if (dx == dy) { /* Diagonal line. */ Blt_Pixel *dp; dp = Blt_PicturePixel(destPtr, x1, y1); while(dy-- > 0) { dp += destPtr->pixelsPerRow + xDir; dp->u32 = colorPtr->u32; } return; } /* use Wu Antialiasing: */ error = 0; if (dy > dx) { /* y-major line */ unsigned long adjust; /* x1 -= lineWidth / 2; */ adjust = (dx << 16) / dy; while(--dy) { Blt_Pixel *dp; int x; unsigned char weight; error += adjust; ++y1; if (error & ~0xFFFF) { x1 += xDir; error &= 0xFFFF; } dp = Blt_PicturePixel(destPtr, x1, y1); weight = (unsigned char)(error >> 8); x = x1; if (x >= 0) { dp->u32 = colorPtr->u32; dp->Alpha = ~weight; } x += xDir; dp += xDir; if (x >= 0) { dp->u32 = colorPtr->u32; dp->Alpha = weight; } } } else { /* x-major line */ unsigned long adjust; /* y1 -= lineWidth / 2; */ adjust = (dy << 16) / dx; while (--dx) { Blt_Pixel *dp; int y; unsigned char weight; error += adjust; x1 += xDir; if (error & ~0xFFFF) { y1++; error &= 0xFFFF; } dp = Blt_PicturePixel(destPtr, x1, y1); weight = (unsigned char)(error >> 8); y = y1; if (y >= 0) { dp->u32 = colorPtr->u32; dp->Alpha = ~weight; } dp += destPtr->pixelsPerRow; y++; if (y >= 0) { dp->u32 = colorPtr->u32; dp->Alpha = weight; } } } } Blt_Picture Blt_PaintCheckbox(int w, int h, XColor *fillColor, XColor *outlineColor, XColor *checkColor, int on) { Shadow shadow; Blt_Pixel color; int x, y; Pict *destPtr; destPtr = Blt_CreatePicture(w, h); w -= 5, h -= 5; color.u32 = 0x00; Blt_BlankPicture(destPtr, &color); shadow.offset = 1; shadow.alpha = 0xA0; x = y = 2; if (fillColor != NULL) { PaintRectangleShadow(destPtr, x+1, y+1, w-2, h-2, 0, 0, &shadow); color = Blt_XColorToPixel(fillColor); PaintRectangle(destPtr, x+1, y+1, w-2, h-2, 0, 0, &color); } if (outlineColor != NULL) { color = Blt_XColorToPixel(outlineColor); PaintRectangle(destPtr, x, y, w, h, 0, 1, &color); } x += 2, y += 2; w -= 5, h -= 5; if (on) { Point2f points[7]; Region2f r; points[0].x = points[1].x = points[6].x = x; points[0].y = points[6].y = y + (0.4 * h); points[1].y = y + (0.6 * h); points[2].x = points[5].x = x + (0.4 * w); points[2].y = y + h; points[3].x = points[4].x = x + w; points[3].y = y + (0.2 * h); points[4].y = y; points[5].y = y + (0.7 * h); points[6].x = points[0].x; points[6].y = points[0].y; shadow.offset = 2; r.left = x, r.right = x + w; r.top = y, r.bottom = y + h; color = Blt_XColorToPixel(checkColor); PaintPolygonAA2(destPtr, 7, points, &r, &color, &shadow); } return destPtr; } Blt_Picture Blt_PaintRadioButton(int w, int h, XColor *fillColor, XColor *outlineColor, XColor *indicatorColor, int on) { Blt_Picture picture; CircleSwitches switches; int x, y, r; Blt_Pixel color; /* Process switches */ switches.lineWidth = 0; switches.fill = Blt_XColorToPixel(fillColor); switches.outline = Blt_XColorToPixel(outlineColor); switches.alpha = -1; switches.shadow.offset = 1; switches.shadow.alpha = 0xA0; switches.antialiased = 1; w &= ~1; picture = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(picture, &color); w -= 6, h -= 6; x = w / 2 + 1; y = h / 2 + 1; r = (w+1) / 2; DrawCircle(picture, x, y, r, &switches); if (on) { r -= 6; if (r < 1) { r = 2; } switches.fill = Blt_XColorToPixel(indicatorColor); switches.outline = switches.fill; switches.lineWidth = 0; switches.shadow.offset = 0; DrawCircle(picture, x, y, r, &switches); } return picture; } Blt_Picture Blt_PaintDelete(int w, int h, XColor *fillColor, XColor *symColor) { Blt_Picture picture; Blt_Pixel color; CircleSwitches switches; Point2f points[4]; Region2f reg; Shadow shadow; int x, y, r; shadow.offset = 1; shadow.alpha = 0xA0; /* Process switches */ switches.lineWidth = 1; switches.fill = Blt_XColorToPixel(fillColor); switches.outline.u32 = 0x0; switches.alpha = -1; switches.shadow.offset = 1; switches.shadow.alpha = 0x80; switches.antialiased = 1; shadow.offset = 0; reg.left = x, reg.right = x + w; reg.top = y, reg.bottom = y + h; picture = Blt_CreatePicture(w, h); color.u32 = 0x00; Blt_BlankPicture(picture, &color); x = y = w / 2 - 1; r = x - 1; DrawCircle(picture, x, y, r, &switches); points[0].x = x - 2; points[0].y = y - 3; points[1].x = x - 3; points[1].y = y - 2; points[2].x = x + 2; points[2].y = y + 3; points[3].x = x + 3; points[3].y = y + 2; color = Blt_XColorToPixel(symColor); PaintPolygonAA2(picture, 4, points, &reg, &color, &shadow); points[0].x = x + 3; points[0].y = y - 2; points[1].x = x + 2; points[1].y = y - 3; points[2].x = x - 3; points[2].y = y + 2; points[3].x = x - 2; points[3].y = y + 3; PaintPolygonAA2(picture, 4, points, &reg, &color, &shadow); return picture; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTvCol.c��������������������������������������������������������������������0000644�0001750�0001750�00000164437�11462120063�014742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTvCol.c -- * * This module implements an hierarchy widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * * BUGS: * 1. "open" operation should change scroll offset so that as many * new entries (up to half a screen) can be seen. * 2. "open" needs to adjust the scrolloffset so that the same entry * is seen at the same place. */ #include "bltInt.h" #ifndef NO_TREEVIEW #include "bltOp.h" #include "bltTreeView.h" #include <X11/Xutil.h> #define RULE_AREA (8) typedef int (TreeViewCmdProc)(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static const char *sortTypeStrings[] = { "dictionary", "ascii", "integer", "real", "command", "none", NULL }; enum SortTypeValues { SORT_DICTIONARY, SORT_ASCII, SORT_INTEGER, SORT_REAL, SORT_COMMAND, SORT_NONE }; #define DEF_SORT_COLUMN (char *)NULL #define DEF_SORT_COMMAND (char *)NULL #define DEF_SORT_DECREASING "no" #define DEF_SORT_TYPE "dictionary" #ifdef WIN32 #define DEF_COLUMN_ACTIVE_TITLE_BG RGB_GREY85 #else #define DEF_COLUMN_ACTIVE_TITLE_BG RGB_GREY90 #endif #define DEF_COLUMN_ACTIVE_TITLE_FG STD_ACTIVE_FOREGROUND #define DEF_COLUMN_ARROWWIDTH "0" #define DEF_COLUMN_BACKGROUND (char *)NULL #define DEF_COLUMN_BIND_TAGS "all" #define DEF_COLUMN_BORDERWIDTH STD_BORDERWIDTH #define DEF_COLUMN_COLOR RGB_BLACK #define DEF_COLUMN_EDIT "yes" #define DEF_COLUMN_FONT STD_FONT #define DEF_COLUMN_COMMAND (char *)NULL #define DEF_COLUMN_FORMATCOMMAND (char *)NULL #define DEF_COLUMN_HIDE "no" #define DEF_COLUMN_SHOW "yes" #define DEF_COLUMN_JUSTIFY "center" #define DEF_COLUMN_MAX "0" #define DEF_COLUMN_MIN "0" #define DEF_COLUMN_PAD "2" #define DEF_COLUMN_RELIEF "flat" #define DEF_COLUMN_STATE "normal" #define DEF_COLUMN_STYLE "text" #define DEF_COLUMN_TITLE_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_COLUMN_TITLE_BORDERWIDTH STD_BORDERWIDTH #define DEF_COLUMN_TITLE_FONT STD_FONT_SMALL #define DEF_COLUMN_TITLE_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_COLUMN_TITLE_RELIEF "raised" #define DEF_COLUMN_WEIGHT "1.0" #define DEF_COLUMN_WIDTH "0" #define DEF_COLUMN_RULE_DASHES "dot" static Blt_OptionParseProc ObjToEnum; static Blt_OptionPrintProc EnumToObj; static Blt_CustomOption typeOption = { ObjToEnum, EnumToObj, NULL, (ClientData)sortTypeStrings }; static Blt_OptionParseProc ObjToColumn; static Blt_OptionPrintProc ColumnToObj; static Blt_CustomOption columnOption = { ObjToColumn, ColumnToObj, NULL, (ClientData)0 }; static Blt_OptionParseProc ObjToData; static Blt_OptionPrintProc DataToObj; Blt_CustomOption bltTreeViewDataOption = { ObjToData, DataToObj, NULL, (ClientData)0, }; static Blt_OptionParseProc ObjToStyle; static Blt_OptionPrintProc StyleToObj; static Blt_OptionFreeProc FreeStyle; static Blt_CustomOption styleOption = { /* Contains a pointer to the widget that's currently being * configured. This is used in the custom configuration parse * routine for icons. */ ObjToStyle, StyleToObj, FreeStyle, NULL, }; BLT_EXTERN Blt_CustomOption bltTreeViewUidOption; BLT_EXTERN Blt_CustomOption bltTreeViewIconOption; static Blt_ConfigSpec columnSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activetitlebackground", "activeTitleBackground", "Background", DEF_COLUMN_ACTIVE_TITLE_BG, Blt_Offset(TreeViewColumn, activeTitleBg), 0}, {BLT_CONFIG_COLOR, "-activetitleforeground", "activeTitleForeground", "Foreground", DEF_COLUMN_ACTIVE_TITLE_FG, Blt_Offset(TreeViewColumn, activeTitleFgColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-arrowwidth", "arrowWidth","ArrowWidth", DEF_COLUMN_ARROWWIDTH, Blt_Offset(TreeViewColumn, reqArrowWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_COLUMN_BACKGROUND, Blt_Offset(TreeViewColumn, bg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", DEF_COLUMN_BIND_TAGS, Blt_Offset(TreeViewColumn, tagsUid), BLT_CONFIG_NULL_OK, &bltTreeViewUidOption}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_COLUMN_BORDERWIDTH, Blt_Offset(TreeViewColumn, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-command", "command", "Command", DEF_COLUMN_COMMAND, Blt_Offset(TreeViewColumn, titleCmd), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK_INVERT, "-edit", "edit", "Edit", DEF_COLUMN_STATE, Blt_Offset(TreeViewColumn, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)COLUMN_READONLY}, {BLT_CONFIG_OBJ, "-formatcommand", "formatCommand", "FormatCommand", (char *)NULL, Blt_Offset(TreeViewColumn, fmtCmdPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-hide", "hide", "Hide", DEF_COLUMN_HIDE, Blt_Offset(TreeViewColumn, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)COLUMN_HIDDEN}, {BLT_CONFIG_CUSTOM, "-icon", "icon", "icon", (char *)NULL, Blt_Offset(TreeViewColumn, titleIcon), BLT_CONFIG_NULL_OK | BLT_CONFIG_DONT_SET_DEFAULT, &bltTreeViewIconOption}, {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", DEF_COLUMN_JUSTIFY, Blt_Offset(TreeViewColumn, justify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-max", "max", "Max", DEF_COLUMN_MAX, Blt_Offset(TreeViewColumn, reqMax), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-min", "min", "Min", DEF_COLUMN_MIN, Blt_Offset(TreeViewColumn, reqMin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PAD, "-pad", "pad", "Pad", DEF_COLUMN_PAD, Blt_Offset(TreeViewColumn, pad), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_COLUMN_RELIEF, Blt_Offset(TreeViewColumn, relief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DASHES, "-ruledashes", "ruleDashes", "RuleDashes", DEF_COLUMN_RULE_DASHES, Blt_Offset(TreeViewColumn, ruleDashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK_INVERT, "-show", "show", "Show", DEF_COLUMN_SHOW, Blt_Offset(TreeViewColumn, flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)COLUMN_HIDDEN}, {BLT_CONFIG_OBJ, "-sortcommand", "sortCommand", "SortCommand", DEF_SORT_COMMAND, Blt_Offset(TreeViewColumn, sortCmdPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STATE, "-state", "state", "State", DEF_COLUMN_STATE, Blt_Offset(TreeViewColumn, state), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-style", "style", "Style", DEF_COLUMN_STYLE, Blt_Offset(TreeViewColumn, stylePtr), BLT_CONFIG_NULL_OK, &styleOption}, {BLT_CONFIG_STRING, "-text", "text", "Text", (char *)NULL, Blt_Offset(TreeViewColumn, text), 0}, {BLT_CONFIG_STRING, "-title", "title", "Title", (char *)NULL, Blt_Offset(TreeViewColumn, text), 0}, {BLT_CONFIG_BACKGROUND, "-titlebackground", "titleBackground", "TitleBackground", DEF_COLUMN_TITLE_BACKGROUND, Blt_Offset(TreeViewColumn, titleBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-titleborderwidth", "titleBorderWidth", "TitleBorderWidth", DEF_COLUMN_TITLE_BORDERWIDTH, Blt_Offset(TreeViewColumn, titleBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_FONT, "-titlefont", "titleFont", "Font", DEF_COLUMN_TITLE_FONT, Blt_Offset(TreeViewColumn, titleFont), 0}, {BLT_CONFIG_COLOR, "-titleforeground", "titleForeground", "TitleForeground", DEF_COLUMN_TITLE_FOREGROUND, Blt_Offset(TreeViewColumn, titleFgColor), 0}, {BLT_CONFIG_JUSTIFY, "-titlejustify", "titleJustify", "TitleJustify", DEF_COLUMN_JUSTIFY, Blt_Offset(TreeViewColumn, titleJustify), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-titlerelief", "titleRelief", "TitleRelief", DEF_COLUMN_TITLE_RELIEF, Blt_Offset(TreeViewColumn, titleRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DOUBLE, "-weight", (char *)NULL, (char *)NULL, DEF_COLUMN_WEIGHT, Blt_Offset(TreeViewColumn, weight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_COLUMN_WIDTH, Blt_Offset(TreeViewColumn, reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_ConfigSpec sortSpecs[] = { {BLT_CONFIG_OBJ, "-command", "command", "Command", DEF_SORT_COMMAND, Blt_Offset(TreeView, sortCmdPtr), BLT_CONFIG_DONT_SET_DEFAULT | BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-column", "column", "Column", DEF_SORT_COLUMN, Blt_Offset(TreeView, sortColumnPtr), BLT_CONFIG_NULL_OK | BLT_CONFIG_DONT_SET_DEFAULT, &columnOption}, {BLT_CONFIG_BOOLEAN, "-decreasing", "decreasing", "Decreasing", DEF_SORT_DECREASING, Blt_Offset(TreeView, sortDecreasing), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-mode", "mode", "Mode", DEF_SORT_TYPE, Blt_Offset(TreeView, sortType), 0, &typeOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; static Blt_TreeApplyProc SortApplyProc; static Blt_TreeCompareNodesProc CompareNodes; /* *--------------------------------------------------------------------------- * * ObjToEnum -- * * Converts the string into its enumerated type. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToEnum( ClientData clientData, /* Vectors of valid strings. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, char *widgRec, /* Widget record. */ int offset, /* Offset of field in record */ int flags) { int *enumPtr = (int *)(widgRec + offset); char c; char **p; int i; int count; char *string; string = Tcl_GetString(objPtr); c = string[0]; count = 0; for (p = (char **)clientData; *p != NULL; p++) { if ((c == p[0][0]) && (strcmp(string, *p) == 0)) { *enumPtr = count; return TCL_OK; } count++; } *enumPtr = -1; Tcl_AppendResult(interp, "bad value \"", string, "\": should be ", (char *)NULL); p = (char **)clientData; if (count > 0) { Tcl_AppendResult(interp, p[0], (char *)NULL); } for (i = 1; i < (count - 1); i++) { Tcl_AppendResult(interp, " ", p[i], ", ", (char *)NULL); } if (count > 1) { Tcl_AppendResult(interp, " or ", p[count - 1], ".", (char *)NULL); } return TCL_ERROR; } /* *--------------------------------------------------------------------------- * * EnumToObj -- * * Returns the string associated with the enumerated type. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * EnumToObj( ClientData clientData, /* List of strings. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, /* Widget record */ int offset, /* Offset to field in structure */ int flags) { int value = *(int *)(widgRec + offset); char **strings = (char **)clientData; char **p; int count; count = 0; for (p = strings; *p != NULL; p++) { if (value == count) { return Tcl_NewStringObj(*p, -1); } count++; } return Tcl_NewStringObj("unknown value", -1); } /* *--------------------------------------------------------------------------- * * ObjToColumn -- * * Convert the string reprsenting a column, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToColumn( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New legend position string */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeView *viewPtr = (TreeView *)widgRec; TreeViewColumn **columnPtrPtr = (TreeViewColumn **)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *columnPtrPtr = &viewPtr->treeColumn; } else { if (Blt_TreeView_GetColumn(interp, viewPtr, objPtr, columnPtrPtr) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnToString -- * * Results: * The string representation of the column is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ColumnToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewColumn *columnPtr = *(TreeViewColumn **)(widgRec + offset); if (columnPtr == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(columnPtr->key, -1); } } /* *--------------------------------------------------------------------------- * * ObjToData -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToData( ClientData clientData, /* Node of entry. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing new data. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Tcl_Obj **objv; TreeViewEntry *entryPtr = (TreeViewEntry *)widgRec; char *string; int objc; int i; string = Tcl_GetString(objPtr); if (*string == '\0') { return TCL_OK; } if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc == 0) { return TCL_OK; } if (objc & 0x1) { Tcl_AppendResult(interp, "data \"", string, "\" must be in even name-value pairs", (char *)NULL); return TCL_ERROR; } for (i = 0; i < objc; i += 2) { TreeViewColumn *columnPtr; TreeView *viewPtr = entryPtr->viewPtr; if (Blt_TreeView_GetColumn(interp, viewPtr, objv[i], &columnPtr) != TCL_OK) { return TCL_ERROR; } if (Blt_Tree_SetValueByKey(viewPtr->interp, viewPtr->tree, entryPtr->node, columnPtr->key, objv[i + 1]) != TCL_OK) { return TCL_ERROR; } Blt_TreeView_AddValue(entryPtr, columnPtr); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * DataToObj -- * * Results: * The string representation of the data is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * DataToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Tcl_Obj *listObjPtr, *objPtr; TreeViewEntry *entryPtr = (TreeViewEntry *)widgRec; TreeViewValue *valuePtr; /* Add the key-value pairs to a new Tcl_Obj */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = valuePtr->nextPtr) { objPtr = Tcl_NewStringObj(valuePtr->columnPtr->key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); if (Blt_TreeView_GetData(entryPtr, valuePtr->columnPtr->key, &objPtr) != TCL_OK) { objPtr = Tcl_NewStringObj("", -1); Tcl_IncrRefCount(objPtr); } Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } return listObjPtr; } int Blt_TreeView_GetColumn(Tcl_Interp *interp, TreeView *viewPtr, Tcl_Obj *objPtr, TreeViewColumn **columnPtrPtr) { char *string; string = Tcl_GetString(objPtr); if (strcmp(string, "treeView") == 0) { *columnPtrPtr = &viewPtr->treeColumn; } else { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->columnTable, Blt_Tree_GetKey(viewPtr->tree, string)); if (hPtr == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "can't find column \"", string, "\" in \"", Tk_PathName(viewPtr->tkwin), "\"", (char *)NULL); } return TCL_ERROR; } *columnPtrPtr = Blt_GetHashValue(hPtr); } return TCL_OK; } /*ARGSUSED*/ static void FreeStyle(ClientData clientData, Display *display, char *widgRec, int offset) { TreeView *viewPtr = clientData; TreeViewStyle **stylePtrPtr = (TreeViewStyle **)(widgRec + offset); if (*stylePtrPtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, *stylePtrPtr); *stylePtrPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToStyle -- * * Convert the name of an icon into a treeview style. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyle( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeView *viewPtr = clientData; TreeViewStyle **stylePtrPtr = (TreeViewStyle **)(widgRec + offset); TreeViewStyle *stylePtr; if (Blt_TreeView_GetStyle(interp, viewPtr, Tcl_GetString(objPtr), &stylePtr) != TCL_OK) { return TCL_ERROR; } stylePtr->flags |= STYLE_DIRTY; viewPtr->flags |= (LAYOUT_PENDING | DIRTY); if (*stylePtrPtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, *stylePtrPtr); } *stylePtrPtr = stylePtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * IconToObj -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StyleToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewStyle *stylePtr = *(TreeViewStyle **)(widgRec + offset); if (stylePtr == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(stylePtr->name, -1); } } void Blt_TreeView_ConfigureColumn(TreeView *viewPtr, TreeViewColumn *columnPtr) { Drawable drawable; GC newGC; Blt_Background bg; XGCValues gcValues; int ruleDrawn; unsigned long gcMask; int iconWidth, iconHeight; unsigned int textWidth, textHeight; gcMask = GCForeground | GCFont; gcValues.font = Blt_FontId(columnPtr->titleFont); /* Normal title text */ gcValues.foreground = columnPtr->titleFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (columnPtr->titleGC != NULL) { Tk_FreeGC(viewPtr->display, columnPtr->titleGC); } columnPtr->titleGC = newGC; /* Active title text */ gcValues.foreground = columnPtr->activeTitleFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (columnPtr->activeTitleGC != NULL) { Tk_FreeGC(viewPtr->display, columnPtr->activeTitleGC); } columnPtr->activeTitleGC = newGC; columnPtr->titleWidth = 2 * columnPtr->titleBW; iconWidth = iconHeight = 0; if (columnPtr->titleIcon != NULL) { iconWidth = TreeView_IconWidth(columnPtr->titleIcon); iconHeight = TreeView_IconHeight(columnPtr->titleIcon); columnPtr->titleWidth += iconWidth; } textWidth = textHeight = 0; if (columnPtr->text != NULL) { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, columnPtr->titleFont); Blt_Ts_GetExtents(&ts, columnPtr->text, &textWidth, &textHeight); columnPtr->textWidth = textWidth; columnPtr->textHeight = textHeight; columnPtr->titleWidth += textWidth; } if (columnPtr->reqArrowWidth > 0) { columnPtr->arrowWidth = columnPtr->reqArrowWidth; } else { columnPtr->arrowWidth = Blt_TextWidth(columnPtr->titleFont, "0", 1) + 4; } if ((iconWidth > 0) && (textWidth > 0)) { columnPtr->titleWidth += 8; } columnPtr->titleWidth += columnPtr->arrowWidth + 2; columnPtr->titleHeight = MAX(iconHeight, textHeight); gcMask = (GCFunction | GCLineWidth | GCLineStyle | GCForeground); /* * If the rule is active, turn it off (i.e. draw again to erase * it) before changing the GC. If the color changes, we won't be * able to erase the old line, since it will no longer be * correctly XOR-ed with the background. */ drawable = Tk_WindowId(viewPtr->tkwin); ruleDrawn = ((viewPtr->flags & TV_RULE_ACTIVE) && (viewPtr->activeTitleColumnPtr == columnPtr) && (drawable != None)); if (ruleDrawn) { Blt_TreeView_DrawRule(viewPtr, columnPtr, drawable); } /* XOR-ed rule column divider */ gcValues.line_width = LineWidth(columnPtr->ruleLineWidth); gcValues.foreground = Blt_TreeView_GetStyleFg(viewPtr, columnPtr->stylePtr)->pixel; if (LineIsDashed(columnPtr->ruleDashes)) { gcValues.line_style = LineOnOffDash; } else { gcValues.line_style = LineSolid; } gcValues.function = GXxor; bg = CHOOSE(viewPtr->bg, columnPtr->bg); gcValues.foreground ^= Blt_BackgroundBorderColor(bg)->pixel; newGC = Blt_GetPrivateGC(viewPtr->tkwin, gcMask, &gcValues); if (columnPtr->ruleGC != NULL) { Blt_FreePrivateGC(viewPtr->display, columnPtr->ruleGC); } if (LineIsDashed(columnPtr->ruleDashes)) { Blt_SetDashes(viewPtr->display, newGC, &columnPtr->ruleDashes); } columnPtr->ruleGC = newGC; if (ruleDrawn) { Blt_TreeView_DrawRule(viewPtr, columnPtr, drawable); } columnPtr->flags |= COLUMN_DIRTY; viewPtr->flags |= UPDATE; } static void DestroyColumn(TreeView *viewPtr, TreeViewColumn *columnPtr) { Blt_HashEntry *hPtr; bltTreeViewUidOption.clientData = viewPtr; bltTreeViewIconOption.clientData = viewPtr; styleOption.clientData = viewPtr; Blt_FreeOptions(columnSpecs, (char *)columnPtr, viewPtr->display, 0); if (columnPtr->titleGC != NULL) { Tk_FreeGC(viewPtr->display, columnPtr->titleGC); } if (columnPtr->ruleGC != NULL) { Blt_FreePrivateGC(viewPtr->display, columnPtr->ruleGC); } hPtr = Blt_FindHashEntry(&viewPtr->columnTable, columnPtr->key); if (hPtr != NULL) { Blt_DeleteHashEntry(&viewPtr->columnTable, hPtr); } if (columnPtr->link != NULL) { Blt_Chain_DeleteLink(viewPtr->columns, columnPtr->link); } if (columnPtr == &viewPtr->treeColumn) { columnPtr->link = NULL; } else { Blt_Free(columnPtr); } } void Blt_TreeView_DestroyColumns(TreeView *viewPtr) { if (viewPtr->columns != NULL) { Blt_ChainLink link; TreeViewColumn *columnPtr; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { columnPtr = Blt_Chain_GetValue(link); columnPtr->link = NULL; DestroyColumn(viewPtr, columnPtr); } Blt_Chain_Destroy(viewPtr->columns); viewPtr->columns = NULL; } Blt_DeleteHashTable(&viewPtr->columnTable); } int Blt_TreeView_CreateColumn(TreeView *viewPtr, TreeViewColumn *columnPtr, const char *name, const char *defTitle) { Blt_HashEntry *hPtr; int isNew; columnPtr->key = Blt_Tree_GetKeyFromInterp(viewPtr->interp, name); columnPtr->text = Blt_AssertStrdup(defTitle); columnPtr->justify = TK_JUSTIFY_CENTER; columnPtr->relief = TK_RELIEF_FLAT; columnPtr->borderWidth = 1; columnPtr->pad.side1 = columnPtr->pad.side2 = 2; columnPtr->state = STATE_NORMAL; columnPtr->weight = 1.0; columnPtr->ruleLineWidth = 1; columnPtr->titleBW = 2; columnPtr->titleRelief = TK_RELIEF_RAISED; columnPtr->titleIcon = NULL; hPtr = Blt_CreateHashEntry(&viewPtr->columnTable, columnPtr->key, &isNew); Blt_SetHashValue(hPtr, columnPtr); bltTreeViewUidOption.clientData = viewPtr; bltTreeViewIconOption.clientData = viewPtr; styleOption.clientData = viewPtr; if (Blt_ConfigureComponentFromObj(viewPtr->interp, viewPtr->tkwin, name, "Column", columnSpecs, 0, (Tcl_Obj **)NULL, (char *)columnPtr, 0) != TCL_OK) { DestroyColumn(viewPtr, columnPtr); return TCL_ERROR; } return TCL_OK; } static TreeViewColumn * CreateColumn(TreeView *viewPtr, Tcl_Obj *nameObjPtr, int objc, Tcl_Obj *const *objv) { TreeViewColumn *columnPtr; columnPtr = Blt_AssertCalloc(1, sizeof(TreeViewColumn)); if (Blt_TreeView_CreateColumn(viewPtr, columnPtr, Tcl_GetString(nameObjPtr), Tcl_GetString(nameObjPtr)) != TCL_OK) { return NULL; } bltTreeViewUidOption.clientData = viewPtr; bltTreeViewIconOption.clientData = viewPtr; styleOption.clientData = viewPtr; if (Blt_ConfigureComponentFromObj(viewPtr->interp, viewPtr->tkwin, columnPtr->key, "Column", columnSpecs, objc, objv, (char *)columnPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { DestroyColumn(viewPtr, columnPtr); return NULL; } Blt_TreeView_ConfigureColumn(viewPtr, columnPtr); return columnPtr; } TreeViewColumn * Blt_TreeView_NearestColumn(TreeView *viewPtr, int x, int y, ClientData *contextPtr) { if (viewPtr->nVisible > 0) { Blt_ChainLink link; TreeViewColumn *columnPtr; int right; /* * Determine if the pointer is over the rightmost portion of the * column. This activates the rule. */ x = WORLDX(viewPtr, x); for(link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { columnPtr = Blt_Chain_GetValue(link); right = columnPtr->worldX + columnPtr->width; if ((x >= columnPtr->worldX) && (x <= right)) { if (contextPtr != NULL) { *contextPtr = NULL; if ((viewPtr->flags & TV_SHOW_COLUMN_TITLES) && (y >= viewPtr->inset) && (y < (viewPtr->titleHeight + viewPtr->inset))) { *contextPtr = (x >= (right - RULE_AREA)) ? ITEM_COLUMN_RULE : ITEM_COLUMN_TITLE; } } return columnPtr; } } } return NULL; } /* *--------------------------------------------------------------------------- * * ColumnActivateOp -- * * Selects the button to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnActivateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 4) { Drawable drawable; TreeViewColumn *columnPtr; char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { columnPtr = NULL; } else { if (Blt_TreeView_GetColumn(interp, viewPtr, objv[3], &columnPtr) != TCL_OK) { return TCL_ERROR; } if (((viewPtr->flags & TV_SHOW_COLUMN_TITLES) == 0) || (columnPtr->flags & COLUMN_HIDDEN) || (columnPtr->state == STATE_DISABLED)) { columnPtr = NULL; } } viewPtr->activeTitleColumnPtr = viewPtr->activeColumnPtr = columnPtr; drawable = Tk_WindowId(viewPtr->tkwin); if (drawable != None) { Blt_TreeView_DrawHeadings(viewPtr, drawable); Blt_TreeView_DrawOuterBorders(viewPtr, drawable); } } if (viewPtr->activeTitleColumnPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), viewPtr->activeTitleColumnPtr->key, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnBindOp -- * * .t bind tag sequence command * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnBindOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData object; TreeViewColumn *columnPtr; if (Blt_TreeView_GetColumn(NULL, viewPtr, objv[3], &columnPtr) == TCL_OK) { object = Blt_TreeView_ColumnTag(viewPtr, columnPtr->key); } else { object = Blt_TreeView_ColumnTag(viewPtr, Tcl_GetString(objv[3])); } return Blt_ConfigureBindingsFromObj(interp, viewPtr->bindTable, object, objc - 4, objv + 4); } /* *--------------------------------------------------------------------------- * * ColumnCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnCgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewColumn *columnPtr; if (Blt_TreeView_GetColumn(interp, viewPtr, objv[3], &columnPtr) != TCL_OK){ return TCL_ERROR; } return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, columnSpecs, (char *)columnPtr, objv[4], 0); } /* *--------------------------------------------------------------------------- * * ColumnConfigureOp -- * * This procedure is called to process a list of configuration * options database, in order to reconfigure the one of more * entries in the widget. * * .h entryconfigure node node node node option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for viewPtr; old resources get freed, if there * were any. The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int ColumnConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int nOptions, start; int i; /* Figure out where the option value pairs begin */ for(i = 3; i < objc; i++) { TreeViewColumn *columnPtr; if (Blt_ObjIsOption(columnSpecs, objv[i], 0)) { break; } if (Blt_TreeView_GetColumn(interp, viewPtr, objv[i], &columnPtr) != TCL_OK) { return TCL_ERROR; } } start = i; nOptions = objc - start; bltTreeViewUidOption.clientData = viewPtr; bltTreeViewIconOption.clientData = viewPtr; styleOption.clientData = viewPtr; for (i = 3; i < start; i++) { TreeViewColumn *columnPtr; if (Blt_TreeView_GetColumn(interp, viewPtr, objv[i], &columnPtr) != TCL_OK) { return TCL_ERROR; } if (nOptions == 0) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, columnSpecs, (char *)columnPtr, (Tcl_Obj *)NULL, 0); } else if (nOptions == 1) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, columnSpecs, (char *)columnPtr, objv[start], 0); } if (Blt_ConfigureWidgetFromObj(viewPtr->interp, viewPtr->tkwin, columnSpecs, nOptions, objv + start, (char *)columnPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } Blt_TreeView_ConfigureColumn(viewPtr, columnPtr); } /*FIXME: Makes every change redo everything. */ viewPtr->flags |= (LAYOUT_PENDING | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnDeleteOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnDeleteOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int i; for(i = 3; i < objc; i++) { TreeViewColumn *columnPtr; TreeViewEntry *entryPtr; if (Blt_TreeView_GetColumn(interp, viewPtr, objv[i], &columnPtr) != TCL_OK) { return TCL_ERROR; } /* Traverse the tree deleting values associated with the column. */ for(entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, 0)) { if (entryPtr != NULL) { TreeViewValue *valuePtr, *lastPtr, *nextPtr; lastPtr = NULL; for (valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = nextPtr) { nextPtr = valuePtr->nextPtr; if (valuePtr->columnPtr == columnPtr) { Blt_TreeView_DestroyValue(viewPtr, valuePtr); if (lastPtr == NULL) { entryPtr->values = nextPtr; } else { lastPtr->nextPtr = nextPtr; } break; } lastPtr = valuePtr; } } } DestroyColumn(viewPtr, columnPtr); } /* Deleting a column may affect the height of an entry. */ viewPtr->flags |= (LAYOUT_PENDING | DIRTY /*| RESORT */); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnInsertOp -- * * Add new columns to the tree. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnInsertOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink before; Tcl_Obj *const *options; int i; int nOptions; int start; long insertPos; if (Blt_GetPositionFromObj(viewPtr->interp, objv[3], &insertPos) != TCL_OK){ return TCL_ERROR; } if ((insertPos == -1) || (insertPos >= Blt_Chain_GetLength(viewPtr->columns))) { before = NULL; /* Insert at end of list. */ } else { before = Blt_Chain_GetNthLink(viewPtr->columns, insertPos); } /* * Count the column names that follow. Count the arguments until we spot * one that looks like a configuration option (i.e. starts with a minus * ("-")). */ for (i = 4; i < objc; i++) { if (Blt_ObjIsOption(columnSpecs, objv[i], 0)) { break; } } start = i; nOptions = objc - i; options = objv + start; for (i = 4; i < start; i++) { TreeViewColumn *columnPtr; TreeViewEntry *entryPtr; if (Blt_TreeView_GetColumn(NULL, viewPtr, objv[i], &columnPtr) == TCL_OK) { Tcl_AppendResult(interp, "column \"", Tcl_GetString(objv[i]), "\" already exists", (char *)NULL); return TCL_ERROR; } columnPtr = CreateColumn(viewPtr, objv[i], nOptions, options); if (columnPtr == NULL) { return TCL_ERROR; } if (before == NULL) { columnPtr->link = Blt_Chain_Append(viewPtr->columns, columnPtr); } else { columnPtr->link = Blt_Chain_NewLink(); Blt_Chain_SetValue(columnPtr->link, columnPtr); Blt_Chain_LinkBefore(viewPtr->columns, columnPtr->link, before); } /* * Traverse the tree adding column entries where needed. */ for(entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, 0)) { Blt_TreeView_AddValue(entryPtr, columnPtr); } Blt_TreeView_TraceColumn(viewPtr, columnPtr); } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnCurrentOp -- * * Make the rule to appear active. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnCurrentOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { ClientData context; TreeViewColumn *columnPtr; columnPtr = NULL; context = Blt_GetCurrentContext(viewPtr->bindTable); if ((context == ITEM_COLUMN_TITLE) || (context == ITEM_COLUMN_RULE)) { columnPtr = Blt_GetCurrentItem(viewPtr->bindTable); } if (context >= ITEM_STYLE) { TreeViewValue *valuePtr = context; columnPtr = valuePtr->columnPtr; } if (columnPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), columnPtr->key, -1); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnInvokeOp -- * * This procedure is called to invoke a column command. * * .h column invoke columnName * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnInvokeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewColumn *columnPtr; char *string; string = Tcl_GetString(objv[3]); if (string[0] == '\0') { return TCL_OK; } if (Blt_TreeView_GetColumn(interp, viewPtr, objv[3], &columnPtr) != TCL_OK){ return TCL_ERROR; } if ((columnPtr->state == STATE_NORMAL) && (columnPtr->titleCmd != NULL)) { int result; Tcl_Preserve(viewPtr); Tcl_Preserve(columnPtr); result = Tcl_GlobalEval(interp, columnPtr->titleCmd); Tcl_Release(columnPtr); Tcl_Release(viewPtr); return result; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ColumnMoveOp -- * * Move a column. * * .h column move field1 position *--------------------------------------------------------------------------- */ /* *--------------------------------------------------------------------------- * * ColumnNamesOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ColumnNamesOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Blt_ChainLink link; Tcl_Obj *listObjPtr, *objPtr; TreeViewColumn *columnPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for(link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { columnPtr = Blt_Chain_GetValue(link); objPtr = Tcl_NewStringObj(columnPtr->key, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /*ARGSUSED*/ static int ColumnNearestOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x, y; /* Screen coordinates of the test point. */ TreeViewColumn *columnPtr; ClientData context; int checkTitle; #ifdef notdef int isRoot; isRoot = FALSE; string = Tcl_GetString(objv[3]); if (strcmp("-root", string) == 0) { isRoot = TRUE; objv++, objc--; } if (objc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]), Tcl_GetString(objv[2]), " ?-root? x y\"", (char *)NULL); return TCL_ERROR; } #endif if (Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[3], &x) != TCL_OK) { return TCL_ERROR; } y = 0; checkTitle = FALSE; if (objc == 5) { if (Tk_GetPixelsFromObj(interp, viewPtr->tkwin, objv[4], &y) != TCL_OK) { return TCL_ERROR; } checkTitle = TRUE; } columnPtr = Blt_TreeView_NearestColumn(viewPtr, x, y, &context); if ((checkTitle) && (context == NULL)) { columnPtr = NULL; } if (columnPtr != NULL) { Tcl_SetStringObj(Tcl_GetObjResult(interp), columnPtr->key, -1); } return TCL_OK; } static void UpdateMark(TreeView *viewPtr, int newMark) { Drawable drawable; TreeViewColumn *cp; int dx; int width; cp = viewPtr->resizeColumnPtr; if (cp == NULL) { return; } drawable = Tk_WindowId(viewPtr->tkwin); if (drawable == None) { return; } /* Erase any existing rule. */ if (viewPtr->flags & TV_RULE_ACTIVE) { Blt_TreeView_DrawRule(viewPtr, cp, drawable); } dx = newMark - viewPtr->ruleAnchor; width = cp->width - (PADDING(cp->pad) + 2 * cp->borderWidth); if ((cp->reqMin > 0) && ((width + dx) < cp->reqMin)) { dx = cp->reqMin - width; } if ((cp->reqMax > 0) && ((width + dx) > cp->reqMax)) { dx = cp->reqMax - width; } if ((width + dx) < 4) { dx = 4 - width; } viewPtr->ruleMark = viewPtr->ruleAnchor + dx; /* Redraw the rule if required. */ if (viewPtr->flags & TV_RULE_NEEDED) { Blt_TreeView_DrawRule(viewPtr, cp, drawable); } } /* *--------------------------------------------------------------------------- * * ResizeActivateOp -- * * Turns on/off the resize cursor. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ResizeActivateOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewColumn *columnPtr; char *string; string = Tcl_GetString(objv[4]); if (string[0] == '\0') { if (viewPtr->cursor != None) { Tk_DefineCursor(viewPtr->tkwin, viewPtr->cursor); } else { Tk_UndefineCursor(viewPtr->tkwin); } viewPtr->resizeColumnPtr = NULL; } else if (Blt_TreeView_GetColumn(interp, viewPtr, objv[4], &columnPtr) == TCL_OK) { if (viewPtr->resizeCursor != None) { Tk_DefineCursor(viewPtr->tkwin, viewPtr->resizeCursor); } viewPtr->resizeColumnPtr = columnPtr; } else { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ResizeAnchorOp -- * * Set the anchor for the resize. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ResizeAnchorOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x; if (Tcl_GetIntFromObj(NULL, objv[4], &x) != TCL_OK) { return TCL_ERROR; } viewPtr->ruleAnchor = x; viewPtr->flags |= TV_RULE_NEEDED; UpdateMark(viewPtr, x); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ResizeMarkOp -- * * Sets the resize mark. The distance between the mark and the anchor * is the delta to change the width of the active column. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ResizeMarkOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int x; if (Tcl_GetIntFromObj(NULL, objv[4], &x) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= TV_RULE_NEEDED; UpdateMark(viewPtr, x); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ResizeSetOp -- * * Returns the new width of the column including the resize delta. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ResizeSetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { viewPtr->flags &= ~TV_RULE_NEEDED; UpdateMark(viewPtr, viewPtr->ruleMark); if (viewPtr->resizeColumnPtr != NULL) { int width, delta; TreeViewColumn *columnPtr; columnPtr = viewPtr->resizeColumnPtr; delta = (viewPtr->ruleMark - viewPtr->ruleAnchor); width = viewPtr->resizeColumnPtr->width + delta - (PADDING(columnPtr->pad) + 2 * columnPtr->borderWidth) - 1; Tcl_SetIntObj(Tcl_GetObjResult(interp), width); } return TCL_OK; } static Blt_OpSpec resizeOps[] = { {"activate", 2, ResizeActivateOp, 5, 5, "column"}, {"anchor", 2, ResizeAnchorOp, 5, 5, "x"}, {"mark", 1, ResizeMarkOp, 5, 5, "x"}, {"set", 1, ResizeSetOp, 4, 4, "",}, }; static int nResizeOps = sizeof(resizeOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * ColumnResizeOp -- * *--------------------------------------------------------------------------- */ static int ColumnResizeOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nResizeOps, resizeOps, BLT_OP_ARG3, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } static Blt_OpSpec columnOps[] = { {"activate", 1, ColumnActivateOp, 3, 4, "?field?",}, {"bind", 1, ColumnBindOp, 4, 6, "tagName ?sequence command?",}, {"cget", 2, ColumnCgetOp, 5, 5, "field option",}, {"configure", 2, ColumnConfigureOp, 4, 0, "field ?option value?...",}, {"current", 2, ColumnCurrentOp, 3, 3, "",}, {"delete", 1, ColumnDeleteOp, 3, 0, "?field...?",}, {"highlight", 1, ColumnActivateOp, 3, 4, "?field?",}, {"insert", 3, ColumnInsertOp, 5, 0, "position field ?field...? ?option value?...",}, {"invoke", 3, ColumnInvokeOp, 4, 4, "field",}, {"names", 2, ColumnNamesOp, 3, 3, "",}, {"nearest", 2, ColumnNearestOp, 4, 5, "x ?y?",}, {"resize", 1, ColumnResizeOp, 3, 0, "arg",}, }; static int nColumnOps = sizeof(columnOps) / sizeof(Blt_OpSpec); /* *--------------------------------------------------------------------------- * * TreeViewColumnOp -- * *--------------------------------------------------------------------------- */ int Blt_TreeView_ColumnOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nColumnOps, columnOps, BLT_OP_ARG2, objc, objv,0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } static int InvokeCompare(TreeView *viewPtr, TreeViewEntry *e1Ptr, TreeViewEntry *e2Ptr, Tcl_Obj *cmdPtr) { int result; Tcl_Obj *objv[8]; int i; objv[0] = cmdPtr; objv[1] = Tcl_NewStringObj(Tk_PathName(viewPtr->tkwin), -1); objv[2] = Tcl_NewLongObj(Blt_Tree_NodeId(e1Ptr->node)); objv[3] = Tcl_NewLongObj(Blt_Tree_NodeId(e2Ptr->node)); objv[4] = Tcl_NewStringObj(viewPtr->sortColumnPtr->key, -1); if (viewPtr->flatView) { objv[5] = Tcl_NewStringObj(e1Ptr->fullName, -1); objv[6] = Tcl_NewStringObj(e2Ptr->fullName, -1); } else { objv[5] = Tcl_NewStringObj(GETLABEL(e1Ptr), -1); objv[6] = Tcl_NewStringObj(GETLABEL(e2Ptr), -1); } for(i = 0; i < 7; i++) { Tcl_IncrRefCount(objv[i]); } objv[7] = NULL; result = Tcl_EvalObjv(viewPtr->interp, 7, objv, TCL_EVAL_GLOBAL); if ((result != TCL_OK) || (Tcl_GetIntFromObj(viewPtr->interp, Tcl_GetObjResult(viewPtr->interp), &result) != TCL_OK)) { Tcl_BackgroundError(viewPtr->interp); } for(i = 0; i < 7; i++) { Tcl_DecrRefCount(objv[i]); } Tcl_ResetResult(viewPtr->interp); return result; } static TreeView *treeViewInstance; static int CompareEntries(const void *a, const void *b) { TreeView *viewPtr; TreeViewEntry **e1PtrPtr = (TreeViewEntry **)a; TreeViewEntry **e2PtrPtr = (TreeViewEntry **)b; Tcl_Obj *obj1, *obj2; const char *s1, *s2; int result; viewPtr = (*e1PtrPtr)->viewPtr; obj1 = (*e1PtrPtr)->dataObjPtr; obj2 = (*e2PtrPtr)->dataObjPtr; s1 = Tcl_GetString(obj1); s2 = Tcl_GetString(obj2); result = 0; switch (viewPtr->sortType) { case SORT_ASCII: result = strcmp(s1, s2); break; case SORT_COMMAND: { Tcl_Obj *cmdPtr; cmdPtr = viewPtr->sortColumnPtr->sortCmdPtr; if (cmdPtr == NULL) { cmdPtr = viewPtr->sortCmdPtr; } if (cmdPtr == NULL) { result = Blt_DictionaryCompare(s1, s2); } else { result = InvokeCompare(viewPtr, *e1PtrPtr, *e2PtrPtr, cmdPtr); } } break; case SORT_DICTIONARY: result = Blt_DictionaryCompare(s1, s2); break; case SORT_INTEGER: { int i1, i2; if (Tcl_GetIntFromObj(NULL, obj1, &i1)==TCL_OK) { if (Tcl_GetIntFromObj(NULL, obj2, &i2) == TCL_OK) { result = i1 - i2; } else { result = -1; } } else if (Tcl_GetIntFromObj(NULL, obj2, &i2) == TCL_OK) { result = 1; } else { result = Blt_DictionaryCompare(s1, s2); } } break; case SORT_REAL: { double r1, r2; if (Tcl_GetDoubleFromObj(NULL, obj1, &r1) == TCL_OK) { if (Tcl_GetDoubleFromObj(NULL, obj2, &r2) == TCL_OK) { result = (r1 < r2) ? -1 : (r1 > r2) ? 1 : 0; } else { result = -1; } } else if (Tcl_GetDoubleFromObj(NULL, obj2, &r2) == TCL_OK) { result = 1; } else { result = Blt_DictionaryCompare(s1, s2); } } break; } if (result == 0) { result = strcmp((*e1PtrPtr)->fullName, (*e2PtrPtr)->fullName); } if (viewPtr->sortDecreasing) { return -result; } return result; } /* *--------------------------------------------------------------------------- * * CompareNodes -- * * Comparison routine (used by qsort) to sort a chain of subnodes. * * Results: * 1 is the first is greater, -1 is the second is greater, 0 * if equal. * *--------------------------------------------------------------------------- */ static int CompareNodes(Blt_TreeNode *n1Ptr, Blt_TreeNode *n2Ptr) { TreeView *viewPtr = treeViewInstance; TreeViewEntry *e1Ptr, *e2Ptr; e1Ptr = Blt_TreeView_NodeToEntry(viewPtr, *n1Ptr); e2Ptr = Blt_TreeView_NodeToEntry(viewPtr, *n2Ptr); /* Fetch the data for sorting. */ if (viewPtr->sortType == SORT_COMMAND) { e1Ptr->dataObjPtr = Tcl_NewLongObj(Blt_Tree_NodeId(*n1Ptr)); e2Ptr->dataObjPtr = Tcl_NewLongObj(Blt_Tree_NodeId(*n2Ptr)); } else { Blt_TreeKey key; Tcl_Obj *objPtr; key = viewPtr->sortColumnPtr->key; if (Blt_TreeView_GetData(e1Ptr, key, &objPtr) != TCL_OK) { e1Ptr->dataObjPtr = Tcl_NewStringObj("", -1); } else { e1Ptr->dataObjPtr = objPtr; } if (Blt_TreeView_GetData(e2Ptr, key, &objPtr) != TCL_OK) { e2Ptr->dataObjPtr = Tcl_NewStringObj("", -1); } else { e2Ptr->dataObjPtr = objPtr; } } { Tcl_DString dString; Tcl_DStringInit(&dString); if (e1Ptr->fullName == NULL) { Blt_TreeView_GetFullName(viewPtr, e1Ptr, TRUE, &dString); e1Ptr->fullName = Blt_AssertStrdup(Tcl_DStringValue(&dString)); } e1Ptr->dataObjPtr = Tcl_NewStringObj(e1Ptr->fullName, -1); if (e2Ptr->fullName == NULL) { Blt_TreeView_GetFullName(viewPtr, e2Ptr, TRUE, &dString); e2Ptr->fullName = Blt_AssertStrdup(Tcl_DStringValue(&dString)); } e2Ptr->dataObjPtr = Tcl_NewStringObj(e2Ptr->fullName, -1); Tcl_DStringFree(&dString); } return CompareEntries(&e1Ptr, &e2Ptr); } static int SortAutoOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { if (objc == 4) { int bool; int isAuto; isAuto = ((viewPtr->flags & TV_SORT_AUTO) != 0); if (Tcl_GetBooleanFromObj(interp, objv[3], &bool) != TCL_OK) { return TCL_ERROR; } if (isAuto != bool) { viewPtr->flags |= (LAYOUT_PENDING | DIRTY | RESORT); Blt_TreeView_EventuallyRedraw(viewPtr); } if (bool) { viewPtr->flags |= TV_SORT_AUTO; } else { viewPtr->flags &= ~TV_SORT_AUTO; } } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (viewPtr->flags & TV_SORT_AUTO)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SortCgetOp -- * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SortCgetOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { return Blt_ConfigureValueFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, objv[3], 0); } /* *--------------------------------------------------------------------------- * * SortConfigureOp -- * * This procedure is called to process a list of configuration * options database, in order to reconfigure the one of more * entries in the widget. * * .h sort configure option value * * Results: * A standard TCL result. If TCL_ERROR is returned, then * interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for viewPtr; old resources get freed, if there * were any. The hypertext is redisplayed. * *--------------------------------------------------------------------------- */ static int SortConfigureOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int oldType; Tcl_Obj *oldCmdPtr; TreeViewColumn *oldColumn; if (objc == 3) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, (Tcl_Obj *)NULL, 0); } else if (objc == 4) { return Blt_ConfigureInfoFromObj(interp, viewPtr->tkwin, sortSpecs, (char *)viewPtr, objv[3], 0); } oldColumn = viewPtr->sortColumnPtr; oldType = viewPtr->sortType; oldCmdPtr = viewPtr->sortCmdPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, sortSpecs, objc - 3, objv + 3, (char *)viewPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { return TCL_ERROR; } if ((oldColumn != viewPtr->sortColumnPtr)||(oldType != viewPtr->sortType) || (oldCmdPtr != viewPtr->sortCmdPtr)) { viewPtr->flags &= ~SORTED; viewPtr->flags |= (DIRTY | RESORT); } if (viewPtr->flags & TV_SORT_AUTO) { viewPtr->flags |= SORT_PENDING; } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /*ARGSUSED*/ static int SortOnceOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int recurse; recurse = FALSE; if (objc > 3) { char *string; int length; string = Tcl_GetStringFromObj(objv[3], &length); if ((string[0] == '-') && (length > 1) && (strncmp(string, "-recurse", length) == 0)) { objv++, objc--; recurse = TRUE; } } #ifdef notdef { int i; treeViewInstance = viewPtr; for (i = 3; i < objc; i++) { TreeViewEntry *entryPtr; int result; if (Blt_TreeView_GetEntry(viewPtr, objv[i], &entryPtr) != TCL_OK) { return TCL_ERROR; } if (recurse) { result = Blt_Tree_Apply(entryPtr->node, SortApplyProc, viewPtr); } else { result = SortApplyProc(entryPtr->node, viewPtr, TREE_PREORDER); } if (result != TCL_OK) { return TCL_ERROR; } } } #endif viewPtr->flags |= (LAYOUT_PENDING | DIRTY | UPDATE | SORT_PENDING | RESORT); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_SortOp -- * * Comparison routine (used by qsort) to sort a chain of subnodes. * A simple string comparison is performed on each node name. * * .h sort auto * .h sort once -recurse root * * Results: * 1 is the first is greater, -1 is the second is greater, 0 * if equal. * *--------------------------------------------------------------------------- */ static Blt_OpSpec sortOps[] = { {"auto", 1, SortAutoOp, 3, 4, "?boolean?",}, {"cget", 2, SortCgetOp, 4, 4, "option",}, {"configure", 2, SortConfigureOp, 3, 0, "?option value?...",}, {"once", 1, SortOnceOp, 3, 0, "?-recurse? node...",}, }; static int nSortOps = sizeof(sortOps) / sizeof(Blt_OpSpec); /*ARGSUSED*/ int Blt_TreeView_SortOp(TreeView *viewPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { TreeViewCmdProc *proc; int result; proc = Blt_GetOpFromObj(interp, nSortOps, sortOps, BLT_OP_ARG2, objc, objv, 0); if (proc == NULL) { return TCL_ERROR; } result = (*proc) (viewPtr, interp, objc, objv); return result; } /* *--------------------------------------------------------------------------- * * SortApplyProc -- * * Sorts the subnodes at a given node. * * Results: * Always returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int SortApplyProc(Blt_TreeNode node, ClientData clientData, int order) { TreeView *viewPtr = clientData; if (!Blt_Tree_IsLeaf(node)) { Blt_Tree_SortNode(viewPtr->tree, node, CompareNodes); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_SortFlatView -- * * Sorts the flatten array of entries. * *--------------------------------------------------------------------------- */ void Blt_TreeView_SortFlatView(TreeView *viewPtr) { TreeViewEntry *entryPtr, **p; viewPtr->flags &= ~SORT_PENDING; if ((viewPtr->sortType == SORT_NONE) || (viewPtr->nEntries < 2)) { return; } if (viewPtr->flags & SORTED) { int first, last; TreeViewEntry *hold; if (viewPtr->sortDecreasing == viewPtr->viewIsDecreasing) { return; } /* * The view is already sorted but in the wrong direction. * Reverse the entries in the array. */ for (first = 0, last = viewPtr->nEntries - 1; last > first; first++, last--) { hold = viewPtr->flatArr[first]; viewPtr->flatArr[first] = viewPtr->flatArr[last]; viewPtr->flatArr[last] = hold; } viewPtr->viewIsDecreasing = viewPtr->sortDecreasing; viewPtr->flags |= SORTED | LAYOUT_PENDING; return; } /* Fetch each entry's data as Tcl_Objs for sorting. */ if (viewPtr->sortColumnPtr == &viewPtr->treeColumn) { for(p = viewPtr->flatArr; *p != NULL; p++) { entryPtr = *p; if (entryPtr->fullName == NULL) { Tcl_DString dString; Blt_TreeView_GetFullName(viewPtr, entryPtr, TRUE, &dString); entryPtr->fullName = Blt_AssertStrdup(Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); } entryPtr->dataObjPtr = Tcl_NewStringObj(entryPtr->fullName, -1); Tcl_IncrRefCount(entryPtr->dataObjPtr); } } else { Blt_TreeKey key; Tcl_Obj *objPtr; key = viewPtr->sortColumnPtr->key; for(p = viewPtr->flatArr; *p != NULL; p++) { entryPtr = *p; if (Blt_TreeView_GetData(entryPtr, key, &objPtr) != TCL_OK) { objPtr = Tcl_NewStringObj("", -1); } entryPtr->dataObjPtr = objPtr; Tcl_IncrRefCount(entryPtr->dataObjPtr); } } qsort((char *)viewPtr->flatArr, viewPtr->nEntries, sizeof(TreeViewEntry *), (QSortCompareProc *)CompareEntries); /* Free all the Tcl_Objs used for comparison data. */ for(p = viewPtr->flatArr; *p != NULL; p++) { Tcl_DecrRefCount((*p)->dataObjPtr); } viewPtr->viewIsDecreasing = viewPtr->sortDecreasing; viewPtr->flags |= SORTED; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_SortView -- * * Sorts the tree array of entries. * *--------------------------------------------------------------------------- */ void Blt_TreeView_SortView(TreeView *viewPtr) { viewPtr->flags &= ~SORT_PENDING; if (viewPtr->sortType != SORT_NONE) { treeViewInstance = viewPtr; Blt_Tree_Apply(viewPtr->rootPtr->node, SortApplyProc, viewPtr); } viewPtr->viewIsDecreasing = viewPtr->sortDecreasing; } #endif /* NO_TREEVIEW */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltBase64.c�������������������������������������������������������������������0000644�0001750�0001750�00000023047�11462120062�014725� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltBase64.c -- * * This module implements base64 processing procedures for the BLT toolkit. * * Copyright 1991-2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltDBuffer.h" /* * Table for encoding base64. */ static char encode64[64] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; /* * Table for decoding base64. * * Note that NUL and '=' also return 0. This is so we can blindly decode 4 * octets without requiring special handing of left-over bytes (i.e. when the * encoded buffer did not end on a 3-byte boundary). */ #define NA 127 static char decode64[256] = { 0 /* '\0' */, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62 /* + */, NA, NA, NA, 63 /* / */, 52 /* 0 */, 53 /* 1 */, 54 /* 2 */, 55 /* 3 */, 56 /* 4 */, 57 /* 5 */, 58 /* 6 */, 59 /* 7 */, 60 /* 8 */, 61 /* 9 */, NA, NA, NA, 0 /* = */, NA, NA, NA, 0 /* A */, 1 /* B */, 2 /* C */, 3 /* D */, 4 /* E */, 5 /* F */, 6 /* G */, 7 /* H */, 8 /* I */, 9 /* J */, 10 /* K */, 11 /* L */, 12 /* M */, 13 /* N */, 14 /* O */, 15 /* P */, 16 /* Q */, 17 /* R */, 18 /* S */, 19 /* T */, 20 /* U */, 21 /* V */, 22 /* W */, 23 /* X */, 24 /* Y */, 25 /* Z */, NA, NA, NA, NA, NA, NA, 26 /* a */, 27 /* b */, 28 /* c */, 29 /* d */, 30 /* e */, 31 /* f */, 32 /* g */, 33 /* h */, 34 /* i */, 35 /* j */, 36 /* k */, 37 /* l */, 38 /* m */, 39 /* n */, 40 /* o */, 41 /* p */, 42 /* q */, 43 /* r */, 44 /* s */, 45 /* t */, 46 /* u */, 47 /* v */, 48 /* w */, 49 /* x */, 50 /* y */, 51 /* z */, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA }; int Blt_IsBase64(const unsigned char *bytes, size_t nBytes) { const unsigned char *bp, *bend; for (bp = bytes, bend = bp + nBytes; bp < bend; bp++) { unsigned int byte; byte = *bp; if ((decode64[byte] == NA) && (!isspace(byte))) { return FALSE; } } return TRUE; } static INLINE unsigned char NextChar(const unsigned char **bp, const unsigned char *lastPtr) { char c; /* Skip whitespace and invalid characters. Let's see if being fault-tolerant * is better than erroring out here.*/ while (((*bp) < lastPtr) && (decode64[(**bp)] == NA)) { (*bp)++; } c = ((*bp) < lastPtr) ? **bp : 0; if ((c != '\0') && (c != '=')) { (*bp)++; } return c; /* Valid symbol */ } unsigned char * Blt_Base64_Decode(Tcl_Interp *interp, const char *string, size_t *lengthPtr) { size_t nBytes; unsigned char *bp; unsigned char *buffer; const unsigned char *p, *pend; nBytes = *lengthPtr; /* * Assuming that the string contains no padding or whitespace, allocate a * buffer with a worst-case length. */ nBytes = ((nBytes + 1) * 3) / 4; buffer = Blt_Malloc(nBytes); if (buffer == NULL) { Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(nBytes), " for buffer", (char *)NULL); return NULL; } bp = buffer; for (p = (unsigned char *)string, pend = p + *lengthPtr; p < pend; /*empty*/) { unsigned char a, b, c, d; unsigned int u1, u2, u3; a = NextChar(&p, pend); b = NextChar(&p, pend); c = NextChar(&p, pend); d = NextChar(&p, pend); if (d == '\0') { if (a != '\0') { Tcl_AppendResult(interp, "premature end of base64 data", (char *)NULL); Blt_Free(buffer); return NULL; } break; } /* * in: a b c d * ------.......-------...... * |54321054|32105432|10543210| * out: u1 u2 u3 */ /* a = [543210xx] | [xxxxxx54] >> 4 */ u1 = (decode64[a] << 2) | ((decode64[b] & 0x30) >> 4); /* b = [3210xxxx] | [xxxx5432] */ u2 = ((decode64[b] & 0x0F) << 4) |((decode64[c] & 0x3C) >> 2); /* c = [10xxxxxx] | [xx543210] */ u3 = ((decode64[c] & 0x03) << 6) | decode64[d]; if (d == '=') { if ((a == '=') || (b == '=')) { break; /* This should not be possible. */ } if (c == '=') { *bp++ = (unsigned char)u1; } else { *bp++ = (unsigned char)u1; *bp++ = (unsigned char)u2; } break; } bp[0] = (unsigned char)u1; bp[1] = (unsigned char)u2; bp[2] = (unsigned char)u3; bp += 3; } nBytes = bp - buffer; /* Reset the fill point to the number of bytes processed. */ *lengthPtr = nBytes; return buffer; } char * Blt_Base64_Encode(Tcl_Interp *interp, const unsigned char *buffer, size_t bufsize) { char *dest, *dp; int count, remainder; size_t length; const unsigned char *sp, *send; /* Compute worst-case length. */ length = (((bufsize + 1) * 4) + 2) / 3; length += (length + 59) / 60; /* Add space for newlines. */ length++; /* NUL byte */ dest = Blt_Malloc(sizeof(char) * length); if (dest == NULL) { Tcl_AppendResult(interp, "can't allocate \"", Blt_Itoa(length), "\" bytes for buffer", (char *)NULL); return NULL; } count = 0; remainder = bufsize % 3; send = buffer + (bufsize - remainder); dp = dest; for (sp = buffer; sp < send; sp += 3) { int a, b, c, d; /* * in: 0 1 2 * |76543210|76543210|76543210| * ------.......-------...... * out: a b c d */ /* a = [xx765432] */ a = sp[0] >> 2; /* b = [xx10xxxx] | [xxxx7654] */ b = ((sp[0] & 0x03) << 4) | ((sp[1] & 0xF0) >> 4); /* c = [xx3210xx] | [xxxxxx76] */ c = ((sp[1] & 0x0F) << 2) | ((sp[2] & 0xC0) >> 6); /* d = [xx543210] */ d = (sp[2] & 0x3F); dp[0] = encode64[a]; dp[1] = encode64[b]; dp[2] = encode64[c]; dp[3] = encode64[d]; dp += 4; count += 4; if (count > 60) { *dp++ = '\n'; count = 0; } } if (remainder > 0) { int a, b, c; /* * Handle the two cases where the input buffer doesn't end on a 3-byte * boundary. */ if (remainder == 2) { a = sp[0] >> 2; b = ((sp[0] & 0x03) << 4) | ((sp[1] & 0xF0) >> 4); c = ((sp[1] & 0x0F) << 2); dp[0] = encode64[a]; dp[1] = encode64[b]; dp[2] = encode64[c]; dp[3] = '='; } else if (remainder == 1) { a = sp[0] >> 2; b = ((sp[0] & 0x03) << 4); dp[0] = encode64[a]; dp[1] = encode64[b]; dp[2] = dp[3] = '='; } dp += 4; count += 4; if (count > 60) { *dp++ = '\n'; } } assert((size_t)(dp - dest) < length); *dp = '\0'; return dest; } /*ARGSUSED*/ static int Base64Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int option; static const char *args[] = { "decode", "encode", NULL, }; if (objc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), "encode|decode bytes\"", (char *)NULL); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], args, "qualifier", TCL_EXACT, &option) != TCL_OK) { return TCL_ERROR; } switch (option) { case 0: /* decode */ { int length; size_t nBytes; /* # bytes in decoded string. */ unsigned char *bp; const char *in; in = Tcl_GetStringFromObj(objv[2], &length); nBytes = (size_t)length; bp = Blt_Base64_Decode(interp, in, &nBytes); if (bp == NULL) { return TCL_ERROR; } Tcl_SetByteArrayObj(Tcl_GetObjResult(interp), bp, nBytes); } break; case 1: /* encode */ { int length; unsigned char *bp; const char *out; bp = Tcl_GetByteArrayFromObj(objv[2], &length); out = Blt_Base64_Encode(interp, bp, length); if (out == NULL) { return TCL_ERROR; } Tcl_SetStringObj(Tcl_GetObjResult(interp), out, -1); } break; default: Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": should be encode or decode", (char *)NULL); return TCL_ERROR; } return TCL_OK; } int Blt_Base64CmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpec = { "base64", Base64Cmd, }; return Blt_InitCmd(interp, "::blt", &cmdSpec); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTypes.h��������������������������������������������������������������������0000644�0001750�0001750�00000006403�11462120063�015010� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * ---------------------------------------------------------------------- * * Blt_Pad -- * * Specifies vertical and horizontal padding. * * Padding can be specified on a per side basis. The fields * side1 and side2 refer to the opposite sides, either * horizontally or vertically. * * side1 side2 * ----- ----- * x | left right * y | top bottom * * ---------------------------------------------------------------------- */ typedef struct { unsigned short int side1, side2; } Blt_Pad; #define padLeft xPad.side1 #define padRight xPad.side2 #define padTop yPad.side1 #define padBottom yPad.side2 #define PADDING(x) ((x).side1 + (x).side2) /* * ---------------------------------------------------------------------- * * The following enumerated values are used as bit flags. * FILL_NONE Neither coordinate plane is specified * FILL_X Horizontal plane. * FILL_Y Vertical plane. * FILL_BOTH Both vertical and horizontal planes. * * ---------------------------------------------------------------------- */ #define FILL_NONE 0 #define FILL_X 1 #define FILL_Y 2 #define FILL_BOTH 3 /* * ---------------------------------------------------------------------- * * Blt_Dashes -- * * List of dash values (maximum 11 based upon PostScript limit). * * ---------------------------------------------------------------------- */ typedef struct { unsigned char values[12]; int offset; } Blt_Dashes; #define LineIsDashed(d) ((d).values[0] != 0) /* * ------------------------------------------------------------------- * * Point2D -- * * 2-D coordinate. * * ------------------------------------------------------------------- */ typedef struct { double x, y; } Point2D; /* * ------------------------------------------------------------------- * * Point3D -- * * 3-D coordinate. * * ------------------------------------------------------------------- */ typedef struct { double x, y, z; } Point3D; /* * ------------------------------------------------------------------- * * Segment2D -- * * 2-D line segment. * * ------------------------------------------------------------------- */ typedef struct { Point2D p, q; /* The two end points of the segment. */ } Segment2D; /* * ------------------------------------------------------------------- * * Dim2D -- * * 2-D dimension. * * ------------------------------------------------------------------- */ typedef struct { short int width, height; } Dim2D; /* *---------------------------------------------------------------------- * * Region2D -- * * 2-D region. Used to copy parts of images. * *---------------------------------------------------------------------- */ typedef struct { double left, right, top, bottom; } Region2D; typedef struct { double left, right, top, bottom, front, back; } Region3D; #define RegionWidth(r) ((r)->right - (r)->left + 1) #define RegionHeight(r) ((r)->bottom - (r)->top + 1) #define PointInRegion(e,x,y) \ (((x) <= (e)->right) && ((x) >= (e)->left) && \ ((y) <= (e)->bottom) && ((y) >= (e)->top)) #define PointInRectangle(r,x0,y0) \ (((x0) <= (int)((r)->x + (r)->width - 1)) && ((x0) >= (int)(r)->x) && \ ((y0) <= (int)((r)->y + (r)->height - 1)) && ((y0) >= (int)(r)->y)) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltDBuffer.c������������������������������������������������������������������0000644�0001750�0001750�00000023762�11462120062�015222� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltDBuffer.c -- * * This module implements a dynamic buffer for the BLT toolkit. * * Copyright 1991-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include <bltDBuffer.h> typedef struct _Blt_DBuffer DBuffer; void Blt_DBuffer_Init(DBuffer *srcPtr) { srcPtr->bytes = NULL; srcPtr->cursor = srcPtr->count = srcPtr->nBytes = 0; srcPtr->chunk = 64; } void Blt_DBuffer_Free(DBuffer *srcPtr) { if ((srcPtr->bytes != NULL) && (srcPtr->nBytes > 0)) { Blt_Free(srcPtr->bytes); } Blt_DBuffer_Init(srcPtr); } Blt_DBuffer Blt_DBuffer_Create(void) { DBuffer *srcPtr; srcPtr = Blt_AssertMalloc(sizeof(DBuffer)); Blt_DBuffer_Init(srcPtr); return srcPtr; } void Blt_DBuffer_Destroy(DBuffer *srcPtr) { Blt_DBuffer_Free(srcPtr); Blt_Free(srcPtr); } int Blt_DBuffer_Resize(DBuffer *srcPtr, size_t nBytes) { if (srcPtr->nBytes <= nBytes) { size_t size, wanted; unsigned char *bytes; wanted = nBytes + 1; size = srcPtr->chunk; /* * Double the buffer size until we have enough room or hit 64K. After * 64K, increase by multiples of 64K. */ while ((size <= wanted) && (size < (1<<16))) { size += size; } srcPtr->chunk = size; while (size <= wanted) { size += srcPtr->chunk; } if (srcPtr->bytes == NULL) { bytes = Blt_Malloc(size); } else { bytes = Blt_Realloc(srcPtr->bytes, size); } if (bytes == NULL) { return FALSE; } srcPtr->bytes = bytes; srcPtr->nBytes = size; } return TRUE; } unsigned char * Blt_DBuffer_Extend(DBuffer *srcPtr, size_t nBytes) { unsigned char *bp; if (!Blt_DBuffer_Resize(srcPtr, srcPtr->count + nBytes)) { return NULL; } bp = srcPtr->bytes + srcPtr->count; srcPtr->count += nBytes; return bp; } void Blt_DBuffer_AppendByte(DBuffer *destPtr, unsigned char value) { if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) { destPtr->bytes[destPtr->count] = value; destPtr->count++; } } void Blt_DBuffer_AppendShort(DBuffer *destPtr, unsigned short value) { if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) { unsigned char *bp; bp = destPtr->bytes + destPtr->count; #ifdef WORDS_BIGENDIAN bp[0] = (value >> 8) & 0xFF; bp[1] = (value) & 0xFF; #else bp[0] = (value) & 0xFF; bp[1] = (value >> 8) & 0xFF; #endif destPtr->count += 2; } } void Blt_DBuffer_AppendLong(DBuffer *destPtr, unsigned int value) { if (Blt_DBuffer_Resize(destPtr, destPtr->count + sizeof(value))) { unsigned char *bp; bp = destPtr->bytes + destPtr->count; #ifdef WORDS_BIGENDIAN bp[0] = (value >> 24) & 0xFF; bp[1] = (value >> 16) & 0xFF; bp[2] = (value >> 8) & 0xFF; bp[3] = (value) & 0xFF; #else bp[0] = (value) & 0xFF; bp[1] = (value >> 8) & 0xFF; bp[2] = (value >> 16) & 0xFF; bp[3] = (value >> 24) & 0xFF; #endif destPtr->count += 4; } } Tcl_Obj * Blt_DBuffer_ByteArrayObj(DBuffer *srcPtr) { return Tcl_NewByteArrayObj(srcPtr->bytes, srcPtr->count); } Tcl_Obj * Blt_DBuffer_StringObj(DBuffer *srcPtr) { return Tcl_NewStringObj((char *)srcPtr->bytes, srcPtr->count); } int Blt_DBuffer_AppendData(DBuffer *srcPtr, const unsigned char *data, size_t nBytes) { unsigned char *bp; bp = Blt_DBuffer_Extend(srcPtr, nBytes); if (bp == NULL) { return FALSE; } memcpy(bp, data, nBytes); return TRUE; } void Blt_DBuffer_VarAppend TCL_VARARGS_DEF(DBuffer *, arg1) { DBuffer *srcPtr; va_list args; srcPtr = TCL_VARARGS_START(DBuffer, arg1, args); for (;;) { const unsigned char *string; string = va_arg(args, const unsigned char *); if (string == NULL) { break; } Blt_DBuffer_AppendData(srcPtr, string, strlen((const char *)string)); } } void Blt_DBuffer_Print TCL_VARARGS_DEF(DBuffer *, arg1) { DBuffer *srcPtr; char *fmt; char string[BUFSIZ+4]; int length; va_list args; srcPtr = TCL_VARARGS_START(DBuffer, arg1, args); fmt = va_arg(args, char *); length = vsnprintf(string, BUFSIZ, fmt, args); if (length > BUFSIZ) { strcat(string, "..."); } va_end(args); Blt_DBuffer_AppendData(srcPtr, (unsigned char *)string, strlen(string)); } #include <sys/types.h> #include <sys/stat.h> #ifdef notdef int Blt_DBuffer_LoadFile(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dBuffer) { FILE *f; size_t nBytes, nRead; struct stat sb; unsigned char *bytes; #ifdef WIN32 #define READ_MODE "rb" #else #define READ_MODE "r" #endif f = Blt_OpenFile(interp, fileName, READ_MODE); if (f == NULL) { return TCL_ERROR; } if (fstat(fileno(f), &sb)) { Tcl_AppendResult(interp, "can't stat \"", fileName, "\": ", Tcl_PosixError(interp), (char *)NULL); return TCL_ERROR; } Blt_DBuffer_Init(dBuffer); nBytes = sb.st_size; /* Size of buffer */ if (!Blt_DBuffer_Resize(dBuffer, nBytes)) { fclose(f); return TCL_ERROR; } bytes = Blt_DBuffer_Bytes(dBuffer); nRead = fread(bytes, sizeof(unsigned char), nBytes, f); Blt_DBuffer_SetLength(dBuffer, nRead); fclose(f); if (nRead != nBytes) { Tcl_AppendResult(interp, "short file \"", fileName, "\" : read ", Blt_Itoa(nBytes), " bytes.", (char *)NULL); Blt_DBuffer_Free(dBuffer); return TCL_ERROR; } return TCL_OK; } #else int Blt_DBuffer_LoadFile( Tcl_Interp *interp, const char *fileName, Blt_DBuffer dBuffer) { int nBytes; Tcl_Channel channel; if (fileName[0] == '@') { int mode; /* If the file name starts with a '@', then it represents the name of * a previously opened channel. Verify that the channel was opened * for reading. */ fileName++; channel = Tcl_GetChannel(interp, fileName, &mode); if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "can't read from \"", fileName, "\"", (char *)NULL); return TCL_ERROR; } } else { channel = Tcl_OpenFileChannel(interp, fileName, "r", 0); } if (channel == NULL) { return TCL_ERROR; } if (Tcl_SetChannelOption(interp, channel, "-encoding", "binary") != TCL_OK) { return TCL_ERROR; } if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") != TCL_OK) { return TCL_ERROR; } Blt_DBuffer_Init(dBuffer); nBytes = 0; while (!Tcl_Eof(channel)) { int nRead; #define BUFFER_SIZE (1<<16) char *bp; bp = (char *)Blt_DBuffer_Extend(dBuffer, BUFFER_SIZE); nRead = Tcl_ReadRaw(channel, bp, BUFFER_SIZE); if (nRead == -1) { Tcl_AppendResult(interp, "error reading ", fileName, ": ", Tcl_PosixError(interp), (char *)NULL); Blt_DBuffer_Free(dBuffer); return TCL_ERROR; } nBytes += nRead; Blt_DBuffer_SetLength(dBuffer, nBytes); } Tcl_Close(interp, channel); return TCL_OK; } #endif int Blt_DBuffer_SaveFile(Tcl_Interp *interp, const char *fileName, Blt_DBuffer dBuffer) { Tcl_Channel channel; size_t nWritten, nBytes; unsigned char *bytes; channel = Tcl_OpenFileChannel(interp, fileName, "w", 0660); if (channel == NULL) { return TCL_ERROR; } Tcl_SetChannelOption(interp, channel, "-translation", "binary"); Tcl_SetChannelOption(interp, channel, "-encoding", "binary"); nBytes = Blt_DBuffer_Length(dBuffer); bytes = Blt_DBuffer_Bytes(dBuffer); nWritten = Tcl_Write(channel, (char *)bytes, nBytes); Tcl_Close(interp, channel); if (nWritten != nBytes) { Tcl_AppendResult(interp, "short file \"", fileName, (char *)NULL); Tcl_AppendResult(interp, "\" : wrote ", Blt_Itoa(nWritten), " of ", (char *)NULL); Tcl_AppendResult(interp, Blt_Itoa(nBytes), " bytes.", (char *)NULL); return TCL_ERROR; } return TCL_OK; } #ifdef notdef static int ReadNextBlock(DBuffer *srcPtr) { if (srcPtr->channel == NULL) { return -1; } if (Tcl_Eof(srcPtr->channel)) { return 0; } nRead = Tcl_ReadRaw(srcPtr->channel, srcPtr->bytes, BUFFER_SIZE); if (nRead == -1) { Tcl_AppendResult(interp, "error reading channel: ", Tcl_PosixError(interp), (char *)NULL); return -1; } srcPtr->cursor = srcPtr->bytes; srcPtr->count = nRead; return 1; } int Blt_DBuffer_GetNext(DBuffer *srcPtr) { int byte; if ((srcPtr->cursor - srcPtr->bytes) >= srcPtr->count) { int result; result = 0; if (srcPtr->channel != NULL) { result = ReadNextBlock(srcPtr); } if (result <= 0) { return result; } } byte = *srcPtr->cursor; srcPtr->cursor++; return byte; } #endif int Blt_DBuffer_DecodeBase64(Tcl_Interp *interp, const char *string, size_t length, DBuffer *destPtr) { unsigned char *bp; bp = Blt_Base64_Decode(interp, string, &length); if (bp == NULL) { return TCL_ERROR; } if (destPtr->bytes != NULL) { Blt_Free(destPtr->bytes); } destPtr->bytes = bp; destPtr->nBytes = destPtr->count = length; destPtr->cursor = 0; destPtr->chunk = 64; return TCL_OK; } char * Blt_DBuffer_EncodeBase64( Tcl_Interp *interp, /* Interpreter to report errors to. */ DBuffer *srcPtr) /* Input binary buffer. */ { return Blt_Base64_Encode(interp, srcPtr->bytes, srcPtr->count); } ��������������./saods9/blt3.0.1/src/bltTreeView.c�����������������������������������������������������������������0000644�0001750�0001750�00000475165�11462120063�015450� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTreeView.c -- * * This module implements an hierarchy widget for the BLT toolkit. * * Copyright 1998-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * TODO: * * BUGS: * 1. "open" operation should change scroll offset so that as many * new entries (up to half a screen) can be seen. * 2. "open" needs to adjust the scrolloffset so that the same entry * is seen at the same place. */ #include "bltInt.h" #ifndef NO_TREEVIEW #include "bltTreeView.h" #define BUTTON_PAD 2 #define BUTTON_IPAD 1 #define BUTTON_SIZE 7 #define COLUMN_PAD 2 #define FOCUS_WIDTH 1 #define ICON_PADX 2 #define ICON_PADY 1 #define INSET_PAD 0 #define LABEL_PADX 0 #define LABEL_PADY 0 #include <X11/Xutil.h> #include <X11/Xatom.h> #define DEF_ICON_WIDTH 1 #define DEF_ICON_HEIGHT 16 typedef TreeViewColumn Column; typedef ClientData (TagProc)(TreeView *viewPtr, const char *string); static Blt_TreeApplyProc DeleteApplyProc; static Blt_TreeApplyProc CreateApplyProc; BLT_EXTERN Blt_CustomOption bltTreeViewDataOption; static Blt_OptionParseProc ObjToTree; static Blt_OptionPrintProc TreeToObj; static Blt_OptionFreeProc FreeTree; Blt_CustomOption bltTreeViewTreeOption = { ObjToTree, TreeToObj, FreeTree, NULL, }; static Blt_OptionParseProc ObjToIcons; static Blt_OptionPrintProc IconsToObj; static Blt_OptionFreeProc FreeIcons; Blt_CustomOption bltTreeViewIconsOption = { ObjToIcons, IconsToObj, FreeIcons, NULL, }; static Blt_OptionParseProc ObjToButton; static Blt_OptionPrintProc ButtonToObj; static Blt_CustomOption buttonOption = { ObjToButton, ButtonToObj, NULL, NULL, }; static Blt_OptionParseProc ObjToUid; static Blt_OptionPrintProc UidToObj; static Blt_OptionFreeProc FreeUid; Blt_CustomOption bltTreeViewUidOption = { ObjToUid, UidToObj, FreeUid, NULL, }; static Blt_OptionParseProc ObjToScrollmode; static Blt_OptionPrintProc ScrollmodeToObj; static Blt_CustomOption scrollmodeOption = { ObjToScrollmode, ScrollmodeToObj, NULL, NULL, }; static Blt_OptionParseProc ObjToSelectmode; static Blt_OptionPrintProc SelectmodeToObj; static Blt_CustomOption selectmodeOption = { ObjToSelectmode, SelectmodeToObj, NULL, NULL, }; static Blt_OptionParseProc ObjToSeparator; static Blt_OptionPrintProc SeparatorToObj; static Blt_OptionFreeProc FreeSeparator; static Blt_CustomOption separatorOption = { ObjToSeparator, SeparatorToObj, FreeSeparator, NULL, }; static Blt_OptionParseProc ObjToLabel; static Blt_OptionPrintProc LabelToObj; static Blt_OptionFreeProc FreeLabel; static Blt_CustomOption labelOption = { ObjToLabel, LabelToObj, FreeLabel, NULL, }; static Blt_OptionParseProc ObjToStyles; static Blt_OptionPrintProc StylesToObj; static Blt_CustomOption stylesOption = { ObjToStyles, StylesToObj, NULL, NULL, }; #define DEF_BUTTON_ACTIVE_BACKGROUND RGB_WHITE #define DEF_BUTTON_ACTIVE_BG_MONO STD_ACTIVE_BG_MONO #define DEF_BUTTON_ACTIVE_FOREGROUND STD_ACTIVE_FOREGROUND #define DEF_BUTTON_ACTIVE_FG_MONO STD_ACTIVE_FG_MONO #define DEF_BUTTON_BORDERWIDTH "1" #define DEF_BUTTON_CLOSE_RELIEF "solid" #define DEF_BUTTON_OPEN_RELIEF "solid" #define DEF_BUTTON_NORMAL_BACKGROUND RGB_WHITE #define DEF_BUTTON_NORMAL_BG_MONO STD_NORMAL_BG_MONO #define DEF_BUTTON_NORMAL_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_BUTTON_NORMAL_FG_MONO STD_NORMAL_FG_MONO #define DEF_BUTTON_SIZE "7" /* RGB_LIGHTBLUE1 */ #define DEF_ACTIVE_FOREGROUND RBG_BLACK #define DEF_ACTIVE_RELIEF "flat" #define DEF_ALLOW_DUPLICATES "yes" #define DEF_BACKGROUND RGB_WHITE #define DEF_ALT_BACKGROUND RGB_GREY97 #define DEF_BORDERWIDTH STD_BORDERWIDTH #define DEF_BUTTON "auto" #define DEF_DASHES "dot" #define DEF_EXPORT_SELECTION "no" #define DEF_FOREGROUND STD_NORMAL_FOREGROUND #define DEF_FG_MONO STD_NORMAL_FG_MONO #define DEF_FLAT "no" #define DEF_FOCUS_DASHES "dot" #define DEF_FOCUS_EDIT "no" #define DEF_FOCUS_FOREGROUND STD_ACTIVE_FOREGROUND #define DEF_FOCUS_FG_MONO STD_ACTIVE_FG_MONO #define DEF_FONT STD_FONT_SMALL #define DEF_HEIGHT "400" #define DEF_HIDE_LEAVES "no" #define DEF_HIDE_ROOT "yes" #define DEF_FOCUS_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_FOCUS_HIGHLIGHT_COLOR RGB_BLACK #define DEF_FOCUS_HIGHLIGHT_WIDTH "2" #define DEF_ICONVARIABLE ((char *)NULL) #define DEF_ICONS "::blt::TreeView::closeIcon ::blt::TreeView::openIcon" #define DEF_LINECOLOR RGB_GREY30 #define DEF_LINECOLOR_MONO STD_NORMAL_FG_MONO #define DEF_LINESPACING "0" #define DEF_LINEWIDTH "1" #define DEF_MAKE_PATH "no" #define DEF_NEW_TAGS "no" #define DEF_NORMAL_BACKGROUND STD_NORMAL_BACKGROUND #define DEF_NORMAL_FG_MONO STD_ACTIVE_FG_MONO #define DEF_RELIEF "sunken" #define DEF_RESIZE_CURSOR "arrow" #define DEF_SCROLL_INCREMENT "20" #define DEF_SCROLL_MODE "hierbox" #define DEF_SELECT_BACKGROUND STD_SELECT_BACKGROUND #define DEF_SELECT_BG_MONO STD_SELECT_BG_MONO #define DEF_SELECT_BORDERWIDTH "1" #define DEF_SELECT_FOREGROUND STD_SELECT_FOREGROUND #define DEF_SELECT_FG_MONO STD_SELECT_FG_MONO #define DEF_SELECT_MODE "single" #define DEF_SELECT_RELIEF "flat" #define DEF_SHOW_ROOT "yes" #define DEF_SHOW_TITLES "yes" #define DEF_SORT_SELECTION "no" #define DEF_TAKE_FOCUS "1" #define DEF_TEXT_COLOR STD_NORMAL_FOREGROUND #define DEF_TEXT_MONO STD_NORMAL_FG_MONO #define DEF_TEXTVARIABLE ((char *)NULL) #define DEF_TRIMLEFT "" #define DEF_WIDTH "200" #define TvOffset(x) Blt_Offset(TreeView, x) Blt_ConfigSpec bltTreeViewButtonSpecs[] = { {BLT_CONFIG_BACKGROUND, "-activebackground", "activeBackground", "Background", DEF_BUTTON_ACTIVE_BACKGROUND, TvOffset(button.activeBg), 0}, {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-activefg", "activeForeground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", "Foreground", DEF_BUTTON_ACTIVE_FOREGROUND, TvOffset(button.activeFgColor), 0}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BUTTON_NORMAL_BACKGROUND, TvOffset(button.bg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BUTTON_BORDERWIDTH, TvOffset(button.borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_RELIEF, "-closerelief", "closeRelief", "Relief", DEF_BUTTON_CLOSE_RELIEF, TvOffset(button.closeRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_BUTTON_NORMAL_FOREGROUND, TvOffset(button.fgColor), 0}, {BLT_CONFIG_CUSTOM, "-images", "images", "Icons", (char *)NULL, TvOffset(button.icons), BLT_CONFIG_NULL_OK, &bltTreeViewIconsOption}, {BLT_CONFIG_RELIEF, "-openrelief", "openRelief", "Relief", DEF_BUTTON_OPEN_RELIEF, TvOffset(button.openRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-size", "size", "Size", DEF_BUTTON_SIZE, TvOffset(button.reqSize), 0}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; #define EntryOffset(x) Blt_Offset(TreeViewEntry, x) Blt_ConfigSpec bltTreeViewEntrySpecs[] = { {BLT_CONFIG_CUSTOM, "-bindtags", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(tagsUid), BLT_CONFIG_NULL_OK, &bltTreeViewUidOption}, {BLT_CONFIG_CUSTOM, "-button", (char *)NULL, (char *)NULL, DEF_BUTTON, EntryOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, &buttonOption}, {BLT_CONFIG_CUSTOM, "-closecommand", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(closeCmd), BLT_CONFIG_NULL_OK, &bltTreeViewUidOption}, {BLT_CONFIG_CUSTOM, "-data", (char *)NULL, (char *)NULL, (char *)NULL, 0, BLT_CONFIG_NULL_OK, &bltTreeViewDataOption}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_FONT, "-font", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", (char *)NULL, (char *)NULL, EntryOffset(color), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-height", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-icons", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(icons), BLT_CONFIG_NULL_OK, &bltTreeViewIconsOption}, {BLT_CONFIG_CUSTOM, "-label", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(labelUid), 0, &labelOption}, {BLT_CONFIG_CUSTOM, "-opencommand", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(openCmd), BLT_CONFIG_NULL_OK, &bltTreeViewUidOption}, {BLT_CONFIG_CUSTOM, "-styles", (char *)NULL, (char *)NULL, (char *)NULL, EntryOffset(values), BLT_CONFIG_NULL_OK, &stylesOption}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; Blt_ConfigSpec bltTreeViewSpecs[] = { {BLT_CONFIG_BITMASK, "-allowduplicates", "allowDuplicates", "AllowDuplicates", DEF_ALLOW_DUPLICATES, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_ALLOW_DUPLICATES}, {BLT_CONFIG_SYNONYM, "-altbg", "alternateBackground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BACKGROUND, "-alternatebackground", "alternateBackground", "Background", DEF_ALT_BACKGROUND, TvOffset(altBg), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_BITMASK, "-autocreate", "autoCreate", "AutoCreate", DEF_MAKE_PATH, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_FILL_ANCESTORS}, {BLT_CONFIG_BACKGROUND, "-background", "background", "Background", DEF_BACKGROUND, TvOffset(bg), 0}, {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_BORDERWIDTH, TvOffset(borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-button", "button", "Button", DEF_BUTTON, TvOffset(buttonFlags), BLT_CONFIG_DONT_SET_DEFAULT, &buttonOption}, {BLT_CONFIG_STRING, "-closecommand", "closeCommand", "CloseCommand", (char *)NULL, TvOffset(closeCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", (char *)NULL, TvOffset(cursor), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_DASHES, "-dashes", "dashes", "Dashes", DEF_DASHES, TvOffset(dashes), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-exportselection", "exportSelection", "ExportSelection", DEF_EXPORT_SELECTION, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_SELECT_EXPORT}, {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL, 0, 0}, {BLT_CONFIG_BOOLEAN, "-flat", "flat", "Flat", DEF_FLAT, TvOffset(flatView), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_DASHES, "-focusdashes", "focusDashes", "FocusDashes", DEF_FOCUS_DASHES, TvOffset(focusDashes), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground", DEF_FOCUS_FOREGROUND, TvOffset(focusColor),BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-focusforeground", "focusForeground", "FocusForeground", DEF_FOCUS_FG_MONO, TvOffset(focusColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_FONT, "-font", "font", "Font", DEF_FONT, TvOffset(font), 0}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_TEXT_COLOR, TvOffset(fgColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", DEF_TEXT_MONO, TvOffset(fgColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_PIXELS_NNEG, "-height", "height", "Height", DEF_HEIGHT, TvOffset(reqHeight), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_BITMASK, "-hideleaves", "hideLeaves", "HideLeaves", DEF_HIDE_LEAVES, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_HIDE_LEAVES}, {BLT_CONFIG_BITMASK, "-hideroot", "hideRoot", "HideRoot", DEF_HIDE_ROOT, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)HIDE_ROOT}, {BLT_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_FOCUS_HIGHLIGHT_BACKGROUND, TvOffset(highlightBgColor), 0}, {BLT_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_FOCUS_HIGHLIGHT_COLOR, TvOffset(highlightColor), 0}, {BLT_CONFIG_PIXELS_NNEG, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_FOCUS_HIGHLIGHT_WIDTH, TvOffset(highlightWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-iconvariable", "iconVariable", "IconVariable", DEF_TEXTVARIABLE, Blt_Offset(TreeView, iconVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_CUSTOM, "-icons", "icons", "Icons", DEF_ICONS, TvOffset(icons), BLT_CONFIG_NULL_OK, &bltTreeViewIconsOption}, {BLT_CONFIG_COLOR, "-linecolor", "lineColor", "LineColor", DEF_LINECOLOR, TvOffset(lineColor), BLT_CONFIG_COLOR_ONLY}, {BLT_CONFIG_COLOR, "-linecolor", "lineColor", "LineColor", DEF_LINECOLOR_MONO, TvOffset(lineColor), BLT_CONFIG_MONO_ONLY}, {BLT_CONFIG_PIXELS_NNEG, "-linespacing", "lineSpacing", "LineSpacing", DEF_LINESPACING, TvOffset(leader), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_PIXELS_NNEG, "-linewidth", "lineWidth", "LineWidth", DEF_LINEWIDTH, TvOffset(lineWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-opencommand", "openCommand", "OpenCommand", (char *)NULL, TvOffset(openCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief", DEF_RELIEF, TvOffset(relief), 0}, {BLT_CONFIG_CURSOR, "-resizecursor", "resizeCursor", "ResizeCursor", DEF_RESIZE_CURSOR, TvOffset(resizeCursor), 0}, {BLT_CONFIG_CUSTOM, "-scrollmode", "scrollMode", "ScrollMode", DEF_SCROLL_MODE, TvOffset(scrollMode), BLT_CONFIG_DONT_SET_DEFAULT, &scrollmodeOption}, {BLT_CONFIG_BACKGROUND, "-selectbackground", "selectBackground", "Foreground", DEF_SELECT_BACKGROUND, TvOffset(selBg), 0}, {BLT_CONFIG_PIXELS_NNEG, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_SELECT_BORDERWIDTH, TvOffset(selBW), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_STRING, "-selectcommand", "selectCommand", "SelectCommand", (char *)NULL, TvOffset(selectCmd), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_SELECT_FOREGROUND, TvOffset(selFgColor), 0}, {BLT_CONFIG_CUSTOM, "-selectmode", "selectMode", "SelectMode", DEF_SELECT_MODE, TvOffset(selectMode), BLT_CONFIG_DONT_SET_DEFAULT, &selectmodeOption}, {BLT_CONFIG_RELIEF, "-selectrelief", "selectRelief", "Relief", DEF_SELECT_RELIEF, TvOffset(selRelief), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-separator", "separator", "Separator", (char *)NULL, TvOffset(pathSep), BLT_CONFIG_NULL_OK, &separatorOption}, {BLT_CONFIG_BITMASK, "-newtags", "newTags", "newTags", DEF_NEW_TAGS, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_NEW_TAGS}, {BLT_CONFIG_BITMASK, "-showtitles", "showTitles", "ShowTitles", DEF_SHOW_TITLES, TvOffset(flags), 0, (Blt_CustomOption *)TV_SHOW_COLUMN_TITLES}, {BLT_CONFIG_BITMASK, "-sortselection", "sortSelection", "SortSelection", DEF_SORT_SELECTION, TvOffset(flags), BLT_CONFIG_DONT_SET_DEFAULT, (Blt_CustomOption *)TV_SELECT_SORTED}, {BLT_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TAKE_FOCUS, TvOffset(takeFocus), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_OBJ, "-textvariable", "textVariable", "TextVariable", DEF_TEXTVARIABLE, Blt_Offset(TreeView, textVarObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-tree", "tree", "Tree", (char *)NULL, TvOffset(treeName), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_STRING, "-trim", "trim", "Trim", DEF_TRIMLEFT, TvOffset(trimLeft), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-width", "width", "Width", DEF_WIDTH, TvOffset(reqWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-xscrollcommand", "xScrollCommand", "ScrollCommand", (char *)NULL, TvOffset(xScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_SCROLL_INCREMENT, TvOffset(xScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_OBJ, "-yscrollcommand", "yScrollCommand", "ScrollCommand", (char *)NULL, TvOffset(yScrollCmdObjPtr), BLT_CONFIG_NULL_OK}, {BLT_CONFIG_PIXELS_NNEG, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_SCROLL_INCREMENT, TvOffset(yScrollUnits), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, 0, 0} }; /* Forward Declarations */ BLT_EXTERN Blt_TreeApplyProc TreeViewSortApplyProc; static Blt_BindPickProc PickItem; static Blt_BindTagProc GetTags; static Blt_TreeNotifyEventProc TreeEventProc; static Blt_TreeTraceProc TreeTraceProc; static Tcl_CmdDeleteProc WidgetInstCmdDeleteProc; static Tcl_FreeProc DestroyEntry; static Tcl_FreeProc DestroyTreeView; static Tcl_IdleProc DisplayTreeView; static Tcl_ObjCmdProc TreeViewObjCmd; static Tk_EventProc TreeViewEventProc; static Tk_ImageChangedProc IconChangedProc; static Tk_SelectionProc SelectionProc; static int ComputeVisibleEntries(TreeView *viewPtr); /* *--------------------------------------------------------------------------- * * Blt_TreeView_EventuallyRedraw -- * * Queues a request to redraw the widget at the next idle point. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. * *--------------------------------------------------------------------------- */ void Blt_TreeView_EventuallyRedraw(TreeView *viewPtr) { if ((viewPtr->tkwin != NULL) && ((viewPtr->flags & REDRAW_PENDING) == 0) && ((viewPtr->flags & DONT_UPDATE) == 0)) { viewPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayTreeView, viewPtr); } } void Blt_TreeView_TraceColumn(TreeView *viewPtr, TreeViewColumn *cp) { Blt_Tree_CreateTrace(viewPtr->tree, NULL /* Node */, cp->key, NULL, TREE_TRACE_FOREIGN_ONLY | TREE_TRACE_WRITE | TREE_TRACE_UNSET, TreeTraceProc, viewPtr); } static void TraceColumns(TreeView *viewPtr) { Blt_ChainLink link; for(link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; cp = Blt_Chain_GetValue(link); Blt_Tree_CreateTrace( viewPtr->tree, NULL /* Node */, cp->key /* Key pattern */, NULL /* Tag */, TREE_TRACE_FOREIGN_ONLY | TREE_TRACE_WRITE | TREE_TRACE_UNSET, TreeTraceProc /* Callback routine */, viewPtr /* Client data */); } } /* *--------------------------------------------------------------------------- * * ObjToTree -- * * Convert the string representing the name of a tree object * into a tree token. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToTree( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Blt_Tree tree = *(Blt_Tree *)(widgRec + offset); if (Blt_Tree_Attach(interp, tree, Tcl_GetString(objPtr)) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TreeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * TreeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Blt_Tree tree = *(Blt_Tree *)(widgRec + offset); if (tree == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(Blt_Tree_Name(tree), -1); } } /*ARGSUSED*/ static void FreeTree( ClientData clientData, Display *display, /* Not used. */ char *widgRec, int offset) { Blt_Tree *treePtr = (Blt_Tree *)(widgRec + offset); if (*treePtr != NULL) { Blt_TreeNode root; TreeView *viewPtr = clientData; /* * Release the current tree, removing any entry fields. */ root = Blt_Tree_RootNode(*treePtr); Blt_Tree_Apply(root, DeleteApplyProc, viewPtr); Blt_TreeView_ClearSelection(viewPtr); Blt_Tree_Close(*treePtr); *treePtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToScrollmode -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToScrollmode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* New legend position string */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; char c; int *modePtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 'l') && (strcmp(string, "listbox") == 0)) { *modePtr = BLT_SCROLL_MODE_LISTBOX; } else if ((c == 't') && (strcmp(string, "treeview") == 0)) { *modePtr = BLT_SCROLL_MODE_HIERBOX; } else if ((c == 'c') && (strcmp(string, "canvas") == 0)) { *modePtr = BLT_SCROLL_MODE_CANVAS; } else { Tcl_AppendResult(interp, "bad scroll mode \"", string, "\": should be \"treeview\", \"listbox\", or \"canvas\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ScrollmodeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ScrollmodeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mode = *(int *)(widgRec + offset); switch (mode) { case BLT_SCROLL_MODE_LISTBOX: return Tcl_NewStringObj("listbox", -1); case BLT_SCROLL_MODE_HIERBOX: return Tcl_NewStringObj("hierbox", -1); case BLT_SCROLL_MODE_CANVAS: return Tcl_NewStringObj("canvas", -1); default: return Tcl_NewStringObj("unknown scroll mode", -1); } } /* *--------------------------------------------------------------------------- * * ObjToSelectmode -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSelectmode( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; char c; int *modePtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); c = string[0]; if ((c == 's') && (strcmp(string, "single") == 0)) { *modePtr = SELECT_MODE_SINGLE; } else if ((c == 'm') && (strcmp(string, "multiple") == 0)) { *modePtr = SELECT_MODE_MULTIPLE; } else if ((c == 'a') && (strcmp(string, "active") == 0)) { *modePtr = SELECT_MODE_SINGLE; } else { Tcl_AppendResult(interp, "bad select mode \"", string, "\": should be \"single\" or \"multiple\"", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SelectmodeToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SelectmodeToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int mode = *(int *)(widgRec + offset); switch (mode) { case SELECT_MODE_SINGLE: return Tcl_NewStringObj("single", -1); case SELECT_MODE_MULTIPLE: return Tcl_NewStringObj("multiple", -1); default: return Tcl_NewStringObj("unknown scroll mode", -1); } } /* *--------------------------------------------------------------------------- * * ObjToButton -- * * Convert a string to one of three values. * 0 - false, no, off * 1 - true, yes, on * 2 - auto * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToButton( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *string; int *flagsPtr = (int *)(widgRec + offset); string = Tcl_GetString(objPtr); if ((string[0] == 'a') && (strcmp(string, "auto") == 0)) { *flagsPtr &= ~BUTTON_MASK; *flagsPtr |= BUTTON_AUTO; } else { int bool; if (Tcl_GetBooleanFromObj(interp, objPtr, &bool) != TCL_OK) { return TCL_ERROR; } *flagsPtr &= ~BUTTON_MASK; if (bool) { *flagsPtr |= BUTTON_SHOW; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * ButtonToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * ButtonToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { int bool; unsigned int buttonFlags = *(int *)(widgRec + offset); bool = (buttonFlags & BUTTON_MASK); if (bool == BUTTON_AUTO) { return Tcl_NewStringObj("auto", 4); } else { return Tcl_NewBooleanObj(bool); } } /* *--------------------------------------------------------------------------- * * ObjToScrollmode -- * * Convert the string reprsenting a scroll mode, to its numeric * form. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToSeparator( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char **sepPtr = (char **)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (string[0] == '\0') { *sepPtr = SEPARATOR_LIST; } else if (strcmp(string, "none") == 0) { *sepPtr = SEPARATOR_NONE; } else { *sepPtr = Blt_AssertStrdup(string); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * SeparatorToObj -- * * Results: * The string representation of the separator is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * SeparatorToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { char *separator = *(char **)(widgRec + offset); if (separator == SEPARATOR_NONE) { return Tcl_NewStringObj("", -1); } else if (separator == SEPARATOR_LIST) { return Tcl_NewStringObj("list", -1); } else { return Tcl_NewStringObj(separator, -1); } } /* *--------------------------------------------------------------------------- * * FreeSeparator -- * * Free the UID from the widget record, setting it to NULL. * * Results: * The UID in the widget record is set to NULL. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeSeparator(ClientData clientData, Display *display, char *widgRec, int offset) { char **sepPtr = (char **)(widgRec + offset); if ((*sepPtr != SEPARATOR_LIST) && (*sepPtr != SEPARATOR_NONE)) { Blt_Free(*sepPtr); *sepPtr = SEPARATOR_NONE; } } /* *--------------------------------------------------------------------------- * * ObjToLabel -- * * Convert the string representing the label. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left * in interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToLabel( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID *labelPtr = (UID *)(widgRec + offset); char *string; string = Tcl_GetString(objPtr); if (string[0] != '\0') { TreeView *viewPtr = clientData; *labelPtr = Blt_TreeView_GetUid(viewPtr, string); } return TCL_OK; } /* *--------------------------------------------------------------------------- * * TreeToObj -- * * Results: * The string of the entry's label is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * LabelToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID labelUid = *(UID *)(widgRec + offset); const char *string; if (labelUid == NULL) { TreeViewEntry *entryPtr = (TreeViewEntry *)widgRec; string = Blt_Tree_NodeLabel(entryPtr->node); } else { string = labelUid; } return Tcl_NewStringObj(string, -1); } /*ARGSUSED*/ static void FreeLabel(ClientData clientData, Display *display, char *widgRec, int offset) { UID *labelPtr = (UID *)(widgRec + offset); if (*labelPtr != NULL) { TreeView *viewPtr = clientData; Blt_TreeView_FreeUid(viewPtr, *labelPtr); *labelPtr = NULL; } } /* *--------------------------------------------------------------------------- * * ObjToStyles -- * * Convert the list representing the field-name style-name pairs into * stylePtr's. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToStyles( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewEntry *entryPtr = (TreeViewEntry *)widgRec; TreeView *viewPtr; Tcl_Obj **objv; int objc; int i; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc & 1) { Tcl_AppendResult(interp, "odd number of field/style pairs in \"", Tcl_GetString(objPtr), "\"", (char *)NULL); return TCL_ERROR; } viewPtr = entryPtr->viewPtr; for (i = 0; i < objc; i += 2) { TreeViewValue *valuePtr; TreeViewStyle *stylePtr; TreeViewColumn *cp; char *string; if (Blt_TreeView_GetColumn(interp, viewPtr, objv[i], &cp)!=TCL_OK) { return TCL_ERROR; } valuePtr = Blt_TreeView_FindValue(entryPtr, cp); if (valuePtr == NULL) { return TCL_ERROR; } string = Tcl_GetString(objv[i+1]); stylePtr = NULL; if ((*string != '\0') && (Blt_TreeView_GetStyle(interp, viewPtr, string, &stylePtr) != TCL_OK)) { return TCL_ERROR; /* No data ??? */ } if (valuePtr->stylePtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, valuePtr->stylePtr); } valuePtr->stylePtr = stylePtr; } return TCL_OK; } /* *--------------------------------------------------------------------------- * * StylesToObj -- * * Results: * The string representation of the button boolean is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * StylesToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewEntry *entryPtr = (TreeViewEntry *)widgRec; TreeViewValue *vp; Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); for (vp = entryPtr->values; vp != NULL; vp = vp->nextPtr) { const char *styleName; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(vp->columnPtr->key, -1)); styleName = (vp->stylePtr != NULL) ? vp->stylePtr->name : ""; Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(styleName, -1)); } return listObjPtr; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_GetUid -- * * Gets or creates a unique string identifier. Strings are reference * counted. The string is placed into a hashed table local to the * treeview. * * Results: * Returns the pointer to the hashed string. * *--------------------------------------------------------------------------- */ UID Blt_TreeView_GetUid(TreeView *viewPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; size_t refCount; hPtr = Blt_CreateHashEntry(&viewPtr->uidTable, string, &isNew); if (isNew) { refCount = 1; } else { refCount = (size_t)Blt_GetHashValue(hPtr); refCount++; } Blt_SetHashValue(hPtr, refCount); return Blt_GetHashKey(&viewPtr->uidTable, hPtr); } /* *--------------------------------------------------------------------------- * * Blt_TreeView_FreeUid -- * * Releases the uid. Uids are reference counted, so only when the * reference count is zero (i.e. no one else is using the string) is the * entry removed from the hash table. * * Results: * None. * *--------------------------------------------------------------------------- */ void Blt_TreeView_FreeUid(TreeView *viewPtr, UID uid) { Blt_HashEntry *hPtr; size_t refCount; hPtr = Blt_FindHashEntry(&viewPtr->uidTable, uid); assert(hPtr != NULL); refCount = (size_t)Blt_GetHashValue(hPtr); refCount--; if (refCount > 0) { Blt_SetHashValue(hPtr, refCount); } else { Blt_DeleteHashEntry(&viewPtr->uidTable, hPtr); } } /* *--------------------------------------------------------------------------- * * ObjToUid -- * * Converts the string to a Uid. Uid's are hashed, reference counted * strings. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToUid( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeView *viewPtr = clientData; UID *uidPtr = (UID *)(widgRec + offset); *uidPtr = Blt_TreeView_GetUid(viewPtr, Tcl_GetString(objPtr)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * UidToObj -- * * Returns the uid as a string. * * Results: * The fill style string is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * UidToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { UID uid = *(UID *)(widgRec + offset); if (uid == NULL) { return Tcl_NewStringObj("", -1); } else { return Tcl_NewStringObj(uid, -1); } } /* *--------------------------------------------------------------------------- * * FreeUid -- * * Free the UID from the widget record, setting it to NULL. * * Results: * The UID in the widget record is set to NULL. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static void FreeUid(ClientData clientData, Display *display, char *widgRec, int offset) { UID *uidPtr = (UID *)(widgRec + offset); if (*uidPtr != NULL) { TreeView *viewPtr = clientData; Blt_TreeView_FreeUid(viewPtr, *uidPtr); *uidPtr = NULL; } } /* *--------------------------------------------------------------------------- * * IconChangedProc * * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void IconChangedProc( ClientData clientData, int x, /* Not used. */ int y, /* Not used. */ int width, /* Not used. */ int height, /* Not used. */ int imageWidth, /* Not used. */ int imageHeight) /* Not used. */ { TreeView *viewPtr = clientData; viewPtr->flags |= (DIRTY | LAYOUT_PENDING | SCROLL_PENDING); Blt_TreeView_EventuallyRedraw(viewPtr); } TreeViewIcon Blt_TreeView_GetIcon(TreeView *viewPtr, const char *iconName) { Blt_HashEntry *hPtr; int isNew; struct _TreeViewIcon *iconPtr; hPtr = Blt_CreateHashEntry(&viewPtr->iconTable, iconName, &isNew); if (isNew) { Tk_Image tkImage; int width, height; tkImage = Tk_GetImage(viewPtr->interp, viewPtr->tkwin, (char *)iconName, IconChangedProc, viewPtr); if (tkImage == NULL) { Blt_DeleteHashEntry(&viewPtr->iconTable, hPtr); return NULL; } Tk_SizeOfImage(tkImage, &width, &height); iconPtr = Blt_AssertMalloc(sizeof(struct _TreeViewIcon)); iconPtr->tkImage = tkImage; iconPtr->hashPtr = hPtr; iconPtr->refCount = 1; iconPtr->width = width; iconPtr->height = height; Blt_SetHashValue(hPtr, iconPtr); } else { iconPtr = Blt_GetHashValue(hPtr); iconPtr->refCount++; } return iconPtr; } void Blt_TreeView_FreeIcon(TreeView *viewPtr, TreeViewIcon icon) { struct _TreeViewIcon *iconPtr = icon; iconPtr->refCount--; if (iconPtr->refCount == 0) { Blt_DeleteHashEntry(&viewPtr->iconTable, iconPtr->hashPtr); Tk_FreeImage(iconPtr->tkImage); Blt_Free(iconPtr); } } static void DumpIconTable(TreeView *viewPtr) { Blt_HashEntry *hPtr; Blt_HashSearch iter; struct _TreeViewIcon *iconPtr; for (hPtr = Blt_FirstHashEntry(&viewPtr->iconTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { iconPtr = Blt_GetHashValue(hPtr); Tk_FreeImage(iconPtr->tkImage); Blt_Free(iconPtr); } Blt_DeleteHashTable(&viewPtr->iconTable); } /* *--------------------------------------------------------------------------- * * ObjToIcons -- * * Convert a list of image names into Tk images. * * Results: * If the string is successfully converted, TCL_OK is returned. * Otherwise, TCL_ERROR is returned and an error message is left in * interpreter's result field. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int ObjToIcons( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter to send results back * to */ Tk_Window tkwin, /* Not used. */ Tcl_Obj *objPtr, /* Tcl_Obj representing the new * value. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { Tcl_Obj **objv; TreeView *viewPtr = clientData; TreeViewIcon **iconPtrPtr = (TreeViewIcon **)(widgRec + offset); TreeViewIcon *icons; int objc; int result; result = TCL_OK; icons = NULL; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc > 0) { int i; icons = Blt_AssertMalloc(sizeof(TreeViewIcon *) * (objc + 1)); for (i = 0; i < objc; i++) { icons[i] = Blt_TreeView_GetIcon(viewPtr, Tcl_GetString(objv[i])); if (icons[i] == NULL) { result = TCL_ERROR; break; } } icons[i] = NULL; } *iconPtrPtr = icons; return result; } /* *--------------------------------------------------------------------------- * * IconsToObj -- * * Converts the icon into its string representation (its name). * * Results: * The name of the icon is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static Tcl_Obj * IconsToObj( ClientData clientData, /* Not used. */ Tcl_Interp *interp, Tk_Window tkwin, /* Not used. */ char *widgRec, int offset, /* Offset to field in structure */ int flags) { TreeViewIcon *icons = *(TreeViewIcon **)(widgRec + offset); Tcl_Obj *listObjPtr; listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); if (icons != NULL) { TreeViewIcon *iconPtr; for (iconPtr = icons; *iconPtr != NULL; iconPtr++) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(Blt_Image_Name((*iconPtr)->tkImage), -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } } return listObjPtr; } /*ARGSUSED*/ static void FreeIcons(ClientData clientData, Display *display, char *widgRec, int offset) { TreeViewIcon **iconsPtr = (TreeViewIcon **)(widgRec + offset); if (*iconsPtr != NULL) { TreeViewIcon *ip; TreeView *viewPtr = clientData; for (ip = *iconsPtr; *ip != NULL; ip++) { Blt_TreeView_FreeIcon(viewPtr, *ip); } Blt_Free(*iconsPtr); *iconsPtr = NULL; } } TreeViewEntry * Blt_TreeView_NodeToEntry(TreeView *viewPtr, Blt_TreeNode node) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->entryTable, (char *)node); if (hPtr == NULL) { fprintf(stderr, "Blt_TreeView_NodeToEntry: can't find node %s\n", Blt_Tree_NodeLabel(node)); abort(); return NULL; } return Blt_GetHashValue(hPtr); } TreeViewEntry * Blt_TreeView_FindEntry(TreeView *viewPtr, Blt_TreeNode node) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->entryTable, (char *)node); if (hPtr == NULL) { return NULL; } return Blt_GetHashValue(hPtr); } int Blt_TreeView_Apply( TreeView *viewPtr, TreeViewEntry *entryPtr, /* Root entry of subtree. */ TreeViewApplyProc *proc, /* Procedure called for each entry. */ unsigned int flags) { if ((flags & ENTRY_HIDE) && (Blt_TreeView_EntryIsHidden(entryPtr))) { return TCL_OK; /* Hidden node. */ } if ((flags & entryPtr->flags) & ENTRY_HIDE) { return TCL_OK; /* Hidden node. */ } if ((flags | entryPtr->flags) & ENTRY_CLOSED) { TreeViewEntry *childPtr; Blt_TreeNode node, next; for (node = Blt_Tree_FirstChild(entryPtr->node); node != NULL; node = next) { next = Blt_Tree_NextSibling(node); /* * Get the next child before calling Blt_TreeView_Apply * recursively. This is because the apply callback may delete the * node and its link. */ childPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (Blt_TreeView_Apply(viewPtr, childPtr, proc, flags) != TCL_OK) { return TCL_ERROR; } } } if ((*proc) (viewPtr, entryPtr) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } int Blt_TreeView_EntryIsHidden(TreeViewEntry *entryPtr) { TreeView *viewPtr = entryPtr->viewPtr; if ((viewPtr->flags & TV_HIDE_LEAVES) && (Blt_Tree_IsLeaf(entryPtr->node))) { return TRUE; } return (entryPtr->flags & ENTRY_HIDE) ? TRUE : FALSE; } #ifdef notdef int TreeViewEntryIsMapped(TreeViewEntry *entryPtr) { TreeView *viewPtr = entryPtr->viewPtr; /* Don't check if the entry itself is open, only that its ancestors * are. */ if (TreeViewEntryIsHidden(entryPtr)) { return FALSE; } if (entryPtr == viewPtr->rootPtr) { return TRUE; } entryPtr = Blt_TreeView_ParentEntry(entryPtr); while (entryPtr != viewPtr->rootPtr) { if (entryPtr->flags & (ENTRY_CLOSED | ENTRY_HIDE)) { return FALSE; } entryPtr = Blt_TreeView_ParentEntry(entryPtr); } return TRUE; } #endif TreeViewEntry * Blt_TreeView_FirstChild(TreeViewEntry *entryPtr, unsigned int mask) { Blt_TreeNode node; TreeView *viewPtr = entryPtr->viewPtr; for (node = Blt_Tree_FirstChild(entryPtr->node); node != NULL; node = Blt_Tree_NextSibling(node)) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!Blt_TreeView_EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } TreeViewEntry * Blt_TreeView_LastChild(TreeViewEntry *entryPtr, unsigned int mask) { Blt_TreeNode node; TreeView *viewPtr = entryPtr->viewPtr; for (node = Blt_Tree_LastChild(entryPtr->node); node != NULL; node = Blt_Tree_PrevSibling(node)) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!Blt_TreeView_EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } TreeViewEntry * Blt_TreeView_NextSibling(TreeViewEntry *entryPtr, unsigned int mask) { Blt_TreeNode node; TreeView *viewPtr = entryPtr->viewPtr; for (node = Blt_Tree_NextSibling(entryPtr->node); node != NULL; node = Blt_Tree_NextSibling(node)) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!Blt_TreeView_EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } TreeViewEntry * Blt_TreeView_PrevSibling(TreeViewEntry *entryPtr, unsigned int mask) { Blt_TreeNode node; TreeView *viewPtr = entryPtr->viewPtr; for (node = Blt_Tree_PrevSibling(entryPtr->node); node != NULL; node = Blt_Tree_PrevSibling(node)) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); if (((mask & ENTRY_HIDE) == 0) || (!Blt_TreeView_EntryIsHidden(entryPtr))) { return entryPtr; } } return NULL; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_PrevEntry -- * * Returns the "previous" node in the tree. This node (in depth-first * order) is its parent if the node has no siblings that are previous to * it. Otherwise it is the last descendant of the last sibling. In this * case, descend the sibling's hierarchy, using the last child at any * ancestor, until we we find a leaf. * *--------------------------------------------------------------------------- */ TreeViewEntry * Blt_TreeView_PrevEntry(TreeViewEntry *entryPtr, unsigned int mask) { TreeView *viewPtr = entryPtr->viewPtr; TreeViewEntry *prevPtr; if (entryPtr->node == Blt_Tree_RootNode(viewPtr->tree)) { return NULL; /* The root is the first node. */ } prevPtr = Blt_TreeView_PrevSibling(entryPtr, mask); if (prevPtr == NULL) { /* There are no siblings previous to this one, so pick the parent. */ prevPtr = Blt_TreeView_ParentEntry(entryPtr); } else { /* * Traverse down the right-most thread in order to select the last * entry. Stop if we find a "closed" entry or reach a leaf. */ entryPtr = prevPtr; while ((entryPtr->flags & mask) == 0) { entryPtr = Blt_TreeView_LastChild(entryPtr, mask); if (entryPtr == NULL) { break; /* Found a leaf. */ } prevPtr = entryPtr; } } if (prevPtr == NULL) { return NULL; } return prevPtr; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_NextEntry -- * * Returns the "next" node in relation to the given node. The next node * (in depth-first order) is either the first child of the given node the * next sibling if the node has no children (the node is a leaf). If the * given node is the last sibling, then try it's parent next sibling. * Continue until we either find a next sibling for some ancestor or we * reach the root node. In this case the current node is the last node * in the tree. * *--------------------------------------------------------------------------- */ TreeViewEntry * Blt_TreeView_NextEntry(TreeViewEntry *entryPtr, unsigned int mask) { TreeView *viewPtr = entryPtr->viewPtr; TreeViewEntry *nextPtr; int ignoreLeaf; ignoreLeaf = ((viewPtr->flags & TV_HIDE_LEAVES) && (Blt_Tree_IsLeaf(entryPtr->node))); if ((!ignoreLeaf) && ((entryPtr->flags & mask) == 0)) { nextPtr = Blt_TreeView_FirstChild(entryPtr, mask); if (nextPtr != NULL) { return nextPtr; /* Pick the first sub-node. */ } } /* * Back up until to a level where we can pick a "next sibling". For the * last entry we'll thread our way back to the root. */ while (entryPtr != viewPtr->rootPtr) { nextPtr = Blt_TreeView_NextSibling(entryPtr, mask); if (nextPtr != NULL) { return nextPtr; } entryPtr = Blt_TreeView_ParentEntry(entryPtr); } return NULL; /* At root, no next node. */ } void Blt_TreeView_ConfigureButtons(TreeView *viewPtr) { GC newGC; TreeViewButton *buttonPtr = &viewPtr->button; XGCValues gcValues; unsigned long gcMask; gcMask = GCForeground; gcValues.foreground = buttonPtr->fgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (buttonPtr->normalGC != NULL) { Tk_FreeGC(viewPtr->display, buttonPtr->normalGC); } buttonPtr->normalGC = newGC; gcMask = GCForeground; gcValues.foreground = buttonPtr->activeFgColor->pixel; newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (buttonPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, buttonPtr->activeGC); } buttonPtr->activeGC = newGC; buttonPtr->width = buttonPtr->height = ODD(buttonPtr->reqSize); if (buttonPtr->icons != NULL) { int i; for (i = 0; i < 2; i++) { int width, height; if (buttonPtr->icons[i] == NULL) { break; } width = TreeView_IconWidth(buttonPtr->icons[i]); height = TreeView_IconWidth(buttonPtr->icons[i]); if (buttonPtr->width < width) { buttonPtr->width = width; } if (buttonPtr->height < height) { buttonPtr->height = height; } } } buttonPtr->width += 2 * buttonPtr->borderWidth; buttonPtr->height += 2 * buttonPtr->borderWidth; } int Blt_TreeView_ConfigureEntry(TreeView *viewPtr, TreeViewEntry *entryPtr, int objc, Tcl_Obj *const *objv, int flags) { GC newGC; Blt_ChainLink link; TreeViewColumn *cp; bltTreeViewIconsOption.clientData = viewPtr; bltTreeViewUidOption.clientData = viewPtr; labelOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(viewPtr->interp, viewPtr->tkwin, bltTreeViewEntrySpecs, objc, objv, (char *)entryPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Check if there are values that need to be added */ for(link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { cp = Blt_Chain_GetValue(link); Blt_TreeView_AddValue(entryPtr, cp); } newGC = NULL; if ((entryPtr->font != NULL) || (entryPtr->color != NULL)) { Blt_Font font; XColor *colorPtr; XGCValues gcValues; unsigned long gcMask; font = entryPtr->font; if (font == NULL) { font = Blt_TreeView_GetStyleFont(viewPtr, viewPtr->treeColumn.stylePtr); } colorPtr = CHOOSE(viewPtr->fgColor, entryPtr->color); gcMask = GCForeground | GCFont; gcValues.foreground = colorPtr->pixel; gcValues.font = Blt_FontId(font); newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); } if (entryPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, entryPtr->gc); } /* Assume all changes require a new layout. */ entryPtr->gc = newGC; entryPtr->flags |= ENTRY_LAYOUT_PENDING; if (Blt_ConfigModified(bltTreeViewEntrySpecs, "-font", (char *)NULL)) { viewPtr->flags |= UPDATE; } viewPtr->flags |= (LAYOUT_PENDING | DIRTY); return TCL_OK; } void Blt_TreeView_DestroyValue(TreeView *viewPtr, TreeViewValue *valuePtr) { if (valuePtr->stylePtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, valuePtr->stylePtr); } if (valuePtr->textPtr != NULL) { Blt_Free(valuePtr->textPtr); } } static void DestroyEntry(DestroyData data) { TreeViewEntry *entryPtr = (TreeViewEntry *)data; TreeView *viewPtr; viewPtr = entryPtr->viewPtr; bltTreeViewIconsOption.clientData = viewPtr; bltTreeViewUidOption.clientData = viewPtr; labelOption.clientData = viewPtr; Blt_FreeOptions(bltTreeViewEntrySpecs, (char *)entryPtr, viewPtr->display, 0); if (!Blt_Tree_TagTableIsShared(viewPtr->tree)) { /* Don't clear tags unless this client is the only one using * the tag table.*/ Blt_Tree_ClearTags(viewPtr->tree, entryPtr->node); } if (entryPtr->gc != NULL) { Tk_FreeGC(viewPtr->display, entryPtr->gc); } /* Delete the chain of data values from the entry. */ if (entryPtr->values != NULL) { TreeViewValue *valuePtr, *nextPtr; for (valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = nextPtr) { nextPtr = valuePtr->nextPtr; Blt_TreeView_DestroyValue(viewPtr, valuePtr); } entryPtr->values = NULL; } if (entryPtr->fullName != NULL) { Blt_Free(entryPtr->fullName); } if (entryPtr->textPtr != NULL) { Blt_Free(entryPtr->textPtr); } Blt_PoolFreeItem(viewPtr->entryPool, entryPtr); } TreeViewEntry * Blt_TreeView_ParentEntry(TreeViewEntry *entryPtr) { TreeView *viewPtr = entryPtr->viewPtr; Blt_TreeNode node; if (entryPtr->node == Blt_Tree_RootNode(viewPtr->tree)) { return NULL; } node = Blt_Tree_ParentNode(entryPtr->node); if (node == NULL) { return NULL; } return Blt_TreeView_NodeToEntry(viewPtr, node); } static void FreeEntry(TreeView *viewPtr, TreeViewEntry *entryPtr) { Blt_HashEntry *hPtr; if (entryPtr == viewPtr->activePtr) { viewPtr->activePtr = Blt_TreeView_ParentEntry(entryPtr); } if (entryPtr == viewPtr->activeBtnPtr) { viewPtr->activeBtnPtr = NULL; } if (entryPtr == viewPtr->focusPtr) { viewPtr->focusPtr = Blt_TreeView_ParentEntry(entryPtr); Blt_SetFocusItem(viewPtr->bindTable, viewPtr->focusPtr, ITEM_ENTRY); } if (entryPtr == viewPtr->selAnchorPtr) { viewPtr->selMarkPtr = viewPtr->selAnchorPtr = NULL; } Blt_TreeView_DeselectEntry(viewPtr, entryPtr); Blt_TreeView_PruneSelection(viewPtr, entryPtr); Blt_DeleteBindings(viewPtr->bindTable, entryPtr); hPtr = Blt_FindHashEntry(&viewPtr->entryTable, entryPtr->node); if (hPtr != NULL) { Blt_DeleteHashEntry(&viewPtr->entryTable, hPtr); } entryPtr->node = NULL; Tcl_EventuallyFree(entryPtr, DestroyEntry); /* * Indicate that the screen layout of the hierarchy may have changed * because this node was deleted. The screen positions of the nodes in * viewPtr->visibleArr are invalidated. */ viewPtr->flags |= (LAYOUT_PENDING | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); } int Blt_TreeView_EntryIsSelected(TreeView *viewPtr, TreeViewEntry *entryPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->selectTable, (char *)entryPtr); return (hPtr != NULL); } void Blt_TreeView_SelectEntry(TreeView *viewPtr, TreeViewEntry *entryPtr) { int isNew; Blt_HashEntry *hPtr; TreeViewIcon icon; const char *label; hPtr = Blt_CreateHashEntry(&viewPtr->selectTable, (char *)entryPtr, &isNew); if (isNew) { Blt_ChainLink link; link = Blt_Chain_Append(viewPtr->selected, entryPtr); Blt_SetHashValue(hPtr, link); } label = GETLABEL(entryPtr); if ((viewPtr->textVarObjPtr != NULL) && (label != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(label, -1); if (Tcl_ObjSetVar2(viewPtr->interp, viewPtr->textVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return; } } icon = Blt_TreeView_GetEntryIcon(viewPtr, entryPtr); if ((viewPtr->iconVarObjPtr != NULL) && (icon != NULL)) { Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(TreeView_IconName(icon), -1); if (Tcl_ObjSetVar2(viewPtr->interp, viewPtr->iconVarObjPtr, NULL, objPtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { return; } } } void Blt_TreeView_DeselectEntry(TreeView *viewPtr, TreeViewEntry *entryPtr) { Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&viewPtr->selectTable, (char *)entryPtr); if (hPtr != NULL) { Blt_ChainLink link; link = Blt_GetHashValue(hPtr); Blt_Chain_DeleteLink(viewPtr->selected, link); Blt_DeleteHashEntry(&viewPtr->selectTable, hPtr); } } const char * Blt_TreeView_GetFullName(TreeView *viewPtr, TreeViewEntry *entryPtr, int checkEntryLabel, Tcl_DString *resultPtr) { const char **names; /* Used the stack the component names. */ const char *staticSpace[64+2]; int level; int i; level = Blt_Tree_NodeDepth(entryPtr->node); if (viewPtr->rootPtr->labelUid == NULL) { level--; } if (level > 64) { names = Blt_AssertMalloc((level + 2) * sizeof(char *)); } else { names = staticSpace; } for (i = level; i >= 0; i--) { Blt_TreeNode node; /* Save the name of each ancestor in the name array. */ if (checkEntryLabel) { names[i] = GETLABEL(entryPtr); } else { names[i] = Blt_Tree_NodeLabel(entryPtr->node); } node = Blt_Tree_ParentNode(entryPtr->node); if (node != NULL) { entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); } } Tcl_DStringInit(resultPtr); if (level >= 0) { if ((viewPtr->pathSep == SEPARATOR_LIST) || (viewPtr->pathSep == SEPARATOR_NONE)) { for (i = 0; i <= level; i++) { Tcl_DStringAppendElement(resultPtr, names[i]); } } else { Tcl_DStringAppend(resultPtr, names[0], -1); for (i = 1; i <= level; i++) { Tcl_DStringAppend(resultPtr, viewPtr->pathSep, -1); Tcl_DStringAppend(resultPtr, names[i], -1); } } } else { if ((viewPtr->pathSep != SEPARATOR_LIST) && (viewPtr->pathSep != SEPARATOR_NONE)) { Tcl_DStringAppend(resultPtr, viewPtr->pathSep, -1); } } if (names != staticSpace) { Blt_Free(names); } return Tcl_DStringValue(resultPtr); } int Blt_TreeView_CloseEntry(TreeView *viewPtr, TreeViewEntry *entryPtr) { const char *cmd; if (entryPtr->flags & ENTRY_CLOSED) { return TCL_OK; /* Entry is already closed. */ } entryPtr->flags |= ENTRY_CLOSED; viewPtr->flags |= LAYOUT_PENDING; /* * Invoke the entry's "close" command, if there is one. Otherwise try the * treeview's global "close" command. */ cmd = CHOOSE(viewPtr->closeCmd, entryPtr->closeCmd); if (cmd != NULL) { Tcl_DString dString; int result; Blt_TreeView_PercentSubst(viewPtr, entryPtr, cmd, &dString); Tcl_Preserve(entryPtr); result = Tcl_GlobalEval(viewPtr->interp, Tcl_DStringValue(&dString)); Tcl_Release(entryPtr); Tcl_DStringFree(&dString); if (result != TCL_OK) { viewPtr->flags |= DIRTY; return TCL_ERROR; } } return TCL_OK; } int Blt_TreeView_OpenEntry(TreeView *viewPtr, TreeViewEntry *entryPtr) { const char *cmd; if ((entryPtr->flags & ENTRY_CLOSED) == 0) { return TCL_OK; /* Entry is already open. */ } entryPtr->flags &= ~ENTRY_CLOSED; viewPtr->flags |= LAYOUT_PENDING; /* * If there's a "open" command proc specified for the entry, use that * instead of the more general "open" proc for the entire treeview. * Be careful because the "open" command may perform an update. */ cmd = CHOOSE(viewPtr->openCmd, entryPtr->openCmd); if (cmd != NULL) { Tcl_DString dString; int result; Blt_TreeView_PercentSubst(viewPtr, entryPtr, cmd, &dString); Tcl_Preserve(entryPtr); result = Tcl_GlobalEval(viewPtr->interp, Tcl_DStringValue(&dString)); Tcl_Release(entryPtr); Tcl_DStringFree(&dString); if (result != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_CreateEntry -- * * This procedure is called by the Tree object when a node is created and * inserted into the tree. It adds a new treeview entry field to the node. * * Results: * Returns the entry. * *--------------------------------------------------------------------------- */ int Blt_TreeView_CreateEntry( TreeView *viewPtr, Blt_TreeNode node, /* Node that has just been created. */ int objc, Tcl_Obj *const *objv, int flags) { TreeViewEntry *entryPtr; int isNew; Blt_HashEntry *hPtr; hPtr = Blt_CreateHashEntry(&viewPtr->entryTable, (char *)node, &isNew); if (isNew) { /* Create the entry structure */ entryPtr = Blt_PoolAllocItem(viewPtr->entryPool, sizeof(TreeViewEntry)); memset(entryPtr, 0, sizeof(TreeViewEntry)); entryPtr->flags = (unsigned short)(viewPtr->buttonFlags | ENTRY_CLOSED); entryPtr->viewPtr = viewPtr; entryPtr->labelUid = NULL; entryPtr->node = node; Blt_SetHashValue(hPtr, entryPtr); } else { entryPtr = Blt_GetHashValue(hPtr); } if (Blt_TreeView_ConfigureEntry(viewPtr, entryPtr, objc, objv, flags) != TCL_OK) { FreeEntry(viewPtr, entryPtr); return TCL_ERROR; /* Error configuring the entry. */ } viewPtr->flags |= (LAYOUT_PENDING | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /*ARGSUSED*/ static int CreateApplyProc(Blt_TreeNode node, ClientData clientData, int order) { TreeView *viewPtr = clientData; return Blt_TreeView_CreateEntry(viewPtr, node, 0, NULL, 0); } /*ARGSUSED*/ static int DeleteApplyProc(Blt_TreeNode node, ClientData clientData, int order) { TreeView *viewPtr = clientData; /* * Unsetting the tree value triggers a call back to destroy the entry and * also releases the Tcl_Obj that contains it. */ return Blt_Tree_UnsetValueByKey(viewPtr->interp, viewPtr->tree, node, viewPtr->treeColumn.key); } static int TreeEventProc(ClientData clientData, Blt_TreeNotifyEvent *eventPtr) { Blt_TreeNode node; TreeView *viewPtr = clientData; node = Blt_Tree_GetNode(eventPtr->tree, eventPtr->inode); switch (eventPtr->type) { case TREE_NOTIFY_CREATE: return Blt_TreeView_CreateEntry(viewPtr, node, 0, NULL, 0); case TREE_NOTIFY_DELETE: /* * Deleting the tree node triggers a call back to free the treeview * entry that is associated with it. */ if (node != NULL) { TreeViewEntry *entryPtr; entryPtr = Blt_TreeView_FindEntry(viewPtr, node); if (entryPtr != NULL) { FreeEntry(viewPtr, entryPtr); } } break; case TREE_NOTIFY_RELABEL: if (node != NULL) { TreeViewEntry *entryPtr; entryPtr = Blt_TreeView_NodeToEntry(viewPtr, node); entryPtr->flags |= ENTRY_DIRTY; } /*FALLTHRU*/ case TREE_NOTIFY_MOVE: case TREE_NOTIFY_SORT: viewPtr->flags |= (LAYOUT_PENDING | RESORT | DIRTY); Blt_TreeView_EventuallyRedraw(viewPtr); break; default: /* empty */ break; } return TCL_OK; } TreeViewValue * Blt_TreeView_FindValue(TreeViewEntry *entryPtr, TreeViewColumn *cp) { TreeViewValue *vp; for (vp = entryPtr->values; vp != NULL; vp = vp->nextPtr) { if (vp->columnPtr == cp) { return vp; } } return NULL; } void Blt_TreeView_AddValue(TreeViewEntry *entryPtr, TreeViewColumn *cp) { if (Blt_TreeView_FindValue(entryPtr, cp) == NULL) { Tcl_Obj *objPtr; if (Blt_TreeView_GetData(entryPtr, cp->key, &objPtr) == TCL_OK) { TreeViewValue *valuePtr; /* Add a new value only if a data entry exists. */ valuePtr = Blt_PoolAllocItem(entryPtr->viewPtr->valuePool, sizeof(TreeViewValue)); valuePtr->columnPtr = cp; valuePtr->nextPtr = entryPtr->values; valuePtr->textPtr = NULL; valuePtr->width = valuePtr->height = 0; valuePtr->stylePtr = NULL; valuePtr->fmtString = NULL; entryPtr->values = valuePtr; } } entryPtr->viewPtr->flags |= (LAYOUT_PENDING | DIRTY); entryPtr->flags |= ENTRY_DIRTY; } /* *--------------------------------------------------------------------------- * * TreeTraceProc -- * * Mirrors the individual values of the tree object (they must also be * listed in the widget's columns chain). This is because it must track and * save the sizes of each individual data entry, rather than re-computing * all the sizes each time the widget is redrawn. * * This procedure is called by the Tree object when a node data value is * set unset. * * Results: * Returns TCL_OK. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ static int TreeTraceProc( ClientData clientData, Tcl_Interp *interp, Blt_TreeNode node, /* Node that has just been updated. */ Blt_TreeKey key, /* Key of value that's been updated. */ unsigned int flags) { Blt_HashEntry *hPtr; TreeView *viewPtr = clientData; TreeViewColumn *cp; TreeViewEntry *entryPtr; TreeViewValue *valuePtr, *nextPtr, *lastPtr; hPtr = Blt_FindHashEntry(&viewPtr->entryTable, (char *)node); if (hPtr == NULL) { return TCL_OK; /* Not a node that we're interested * in. */ } entryPtr = Blt_GetHashValue(hPtr); flags &= TREE_TRACE_WRITE | TREE_TRACE_READ | TREE_TRACE_UNSET; switch (flags) { case TREE_TRACE_WRITE: hPtr = Blt_FindHashEntry(&viewPtr->columnTable, key); if (hPtr == NULL) { return TCL_OK; /* Data value isn't used by widget. */ } cp = Blt_GetHashValue(hPtr); if (cp != &viewPtr->treeColumn) { Blt_TreeView_AddValue(entryPtr, cp); } entryPtr->flags |= ENTRY_DIRTY; Blt_TreeView_EventuallyRedraw(viewPtr); viewPtr->flags |= (LAYOUT_PENDING | DIRTY); break; case TREE_TRACE_UNSET: lastPtr = NULL; for(valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = nextPtr) { nextPtr = valuePtr->nextPtr; if (valuePtr->columnPtr->key == key) { Blt_TreeView_DestroyValue(viewPtr, valuePtr); if (lastPtr == NULL) { entryPtr->values = nextPtr; } else { lastPtr->nextPtr = nextPtr; } entryPtr->flags |= ENTRY_DIRTY; Blt_TreeView_EventuallyRedraw(viewPtr); viewPtr->flags |= (LAYOUT_PENDING | DIRTY); break; } lastPtr = valuePtr; } break; default: break; } return TCL_OK; } static void FormatValue(TreeViewEntry *entryPtr, TreeViewValue *valuePtr) { TreeViewColumn *colPtr; Tcl_Obj *resultObjPtr; Tcl_Obj *valueObjPtr; colPtr = valuePtr->columnPtr; if (Blt_TreeView_GetData(entryPtr, colPtr->key, &valueObjPtr) != TCL_OK) { return; /* No data ??? */ } if (valuePtr->fmtString != NULL) { Blt_Free(valuePtr->fmtString); } valuePtr->fmtString = NULL; if (valueObjPtr == NULL) { return; } if (colPtr->fmtCmdPtr != NULL) { Tcl_Interp *interp = entryPtr->viewPtr->interp; Tcl_Obj *cmdObjPtr, *objPtr; int result; cmdObjPtr = Tcl_DuplicateObj(colPtr->fmtCmdPtr); objPtr = Tcl_NewLongObj(Blt_Tree_NodeId(entryPtr->node)); Tcl_ListObjAppendElement(interp, cmdObjPtr, objPtr); Tcl_ListObjAppendElement(interp, cmdObjPtr, valueObjPtr); Tcl_IncrRefCount(cmdObjPtr); result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmdObjPtr); if (result != TCL_OK) { Tcl_BackgroundError(interp); return; } resultObjPtr = Tcl_GetObjResult(interp); } else { resultObjPtr = valueObjPtr; } valuePtr->fmtString = Blt_Strdup(Tcl_GetString(resultObjPtr)); } static void GetValueSize(TreeViewEntry *entryPtr, TreeViewValue *valuePtr, TreeViewStyle *stylePtr) { valuePtr->width = valuePtr->height = 0; FormatValue(entryPtr, valuePtr); stylePtr = CHOOSE(valuePtr->columnPtr->stylePtr, valuePtr->stylePtr); /* Measure the text string. */ (*stylePtr->classPtr->measProc)(entryPtr->viewPtr, stylePtr, valuePtr); } static void GetRowExtents(TreeViewEntry *entryPtr, int *widthPtr, int *heightPtr) { TreeViewValue *valuePtr; int width, height; /* Compute dimensions of row. */ width = height = 0; for (valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = valuePtr->nextPtr) { TreeViewStyle *stylePtr; int valueWidth; /* Width of individual value. */ stylePtr = valuePtr->stylePtr; if (stylePtr == NULL) { stylePtr = valuePtr->columnPtr->stylePtr; } if ((entryPtr->flags & ENTRY_DIRTY) || (stylePtr->flags & STYLE_DIRTY)){ GetValueSize(entryPtr, valuePtr, stylePtr); } if (valuePtr->height > height) { height = valuePtr->height; } valueWidth = valuePtr->width; width += valueWidth; } *widthPtr = width; *heightPtr = height; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_NearestEntry -- * * Finds the entry closest to the given screen X-Y coordinates in the * viewport. * * Results: * Returns the pointer to the closest node. If no node is visible (nodes * may be hidden), NULL is returned. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ TreeViewEntry * Blt_TreeView_NearestEntry(TreeView *viewPtr, int x, int y, int selectOne) { TreeViewEntry *lastPtr; TreeViewEntry **p; /* * We implicitly can pick only visible entries. So make sure that the * tree exists. */ if (viewPtr->nVisible == 0) { return NULL; } if (y < viewPtr->titleHeight) { return (selectOne) ? viewPtr->visibleArr[0] : NULL; } /* * Since the entry positions were previously computed in world * coordinates, convert Y-coordinate from screen to world coordinates too. */ y = WORLDY(viewPtr, y); lastPtr = viewPtr->visibleArr[0]; for (p = viewPtr->visibleArr; *p != NULL; p++) { TreeViewEntry *entryPtr; entryPtr = *p; /* * If the start of the next entry starts beyond the point, use the last * entry. */ if (entryPtr->worldY > y) { return (selectOne) ? entryPtr : NULL; } if (y < (entryPtr->worldY + entryPtr->height)) { return entryPtr; /* Found it. */ } lastPtr = entryPtr; } return (selectOne) ? lastPtr : NULL; } ClientData Blt_TreeView_EntryTag(TreeView *viewPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&viewPtr->entryTagTable, string, &isNew); return Blt_GetHashKey(&viewPtr->entryTagTable, hPtr); } ClientData Blt_TreeView_ButtonTag(TreeView *viewPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&viewPtr->buttonTagTable, string, &isNew); return Blt_GetHashKey(&viewPtr->buttonTagTable, hPtr); } ClientData Blt_TreeView_ColumnTag(TreeView *viewPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&viewPtr->columnTagTable, string, &isNew); return Blt_GetHashKey(&viewPtr->columnTagTable, hPtr); } #ifdef notdef ClientData TreeViewStyleTag(TreeView *viewPtr, const char *string) { Blt_HashEntry *hPtr; int isNew; /* Not used. */ hPtr = Blt_CreateHashEntry(&viewPtr->styleTagTable, string, &isNew); return Blt_GetHashKey(&viewPtr->styleTagTable, hPtr); } #endif static void AddIdsToList(TreeView *viewPtr, Blt_List ids, const char *string, TagProc *tagProc) { int argc; const char **argv; if (Tcl_SplitList((Tcl_Interp *)NULL, string, &argc, &argv) == TCL_OK) { const char **p; for (p = argv; *p != NULL; p++) { Blt_List_Append(ids, (*tagProc)(viewPtr, *p), 0); } Blt_Free(argv); } } static void GetTags( Blt_BindTable table, ClientData object, /* Object picked. */ ClientData context, /* Context of object. */ Blt_List ids) /* (out) List of binding ids to be * applied for this object. */ { TreeView *viewPtr; viewPtr = Blt_GetBindingData(table); if (context == (ClientData)ITEM_ENTRY_BUTTON) { TreeViewEntry *entryPtr = object; Blt_List_Append(ids, Blt_TreeView_ButtonTag(viewPtr, "Button"), 0); if (entryPtr->tagsUid != NULL) { AddIdsToList(viewPtr, ids, entryPtr->tagsUid, Blt_TreeView_ButtonTag); } else { Blt_List_Append(ids, Blt_TreeView_ButtonTag(viewPtr, "Entry"), 0); Blt_List_Append(ids, Blt_TreeView_ButtonTag(viewPtr, "all"), 0); } } else if (context == (ClientData)ITEM_COLUMN_TITLE) { TreeViewColumn *cp = object; Blt_List_Append(ids, (char *)cp, 0); if (cp->tagsUid != NULL) { AddIdsToList(viewPtr, ids, cp->tagsUid, Blt_TreeView_ColumnTag); } } else if (context == ITEM_COLUMN_RULE) { Blt_List_Append(ids, Blt_TreeView_ColumnTag(viewPtr, "Rule"), 0); } else { TreeViewEntry *entryPtr = object; Blt_List_Append(ids, (char *)entryPtr, 0); if (entryPtr->tagsUid != NULL) { AddIdsToList(viewPtr, ids, entryPtr->tagsUid, Blt_TreeView_EntryTag); } else if (context == ITEM_ENTRY){ Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, "Entry"), 0); Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, "all"), 0); } else { TreeViewValue *valuePtr = context; if (valuePtr != NULL) { TreeViewStyle *stylePtr = valuePtr->stylePtr; if (stylePtr == NULL) { stylePtr = valuePtr->columnPtr->stylePtr; } Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, stylePtr->name), 0); Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, valuePtr->columnPtr->key), 0); Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, stylePtr->classPtr->className), 0); #ifndef notdef Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, "Entry"), 0); Blt_List_Append(ids, Blt_TreeView_EntryTag(viewPtr, "all"), 0); #endif } } } } /*ARGSUSED*/ static ClientData PickItem( ClientData clientData, int x, int y, /* Screen coordinates of the test * point. */ ClientData *contextPtr) /* (out) Context of item selected: * should be ITEM_ENTRY, * ITEM_ENTRY_BUTTON, ITEM_COLUMN_TITLE, * ITEM_COLUMN_RULE, or ITEM_STYLE. */ { TreeView *viewPtr = clientData; TreeViewEntry *entryPtr; TreeViewColumn *cp; if (contextPtr != NULL) { *contextPtr = NULL; } if (viewPtr->flags & DIRTY) { /* Can't trust the selected entry if nodes have been added or * deleted. So recompute the layout. */ if (viewPtr->flags & LAYOUT_PENDING) { Blt_TreeView_ComputeLayout(viewPtr); } ComputeVisibleEntries(viewPtr); } cp = Blt_TreeView_NearestColumn(viewPtr, x, y, contextPtr); if ((*contextPtr != NULL) && (viewPtr->flags & TV_SHOW_COLUMN_TITLES)) { return cp; } if (viewPtr->nVisible == 0) { return NULL; } entryPtr = Blt_TreeView_NearestEntry(viewPtr, x, y, FALSE); if (entryPtr == NULL) { return NULL; } x = WORLDX(viewPtr, x); y = WORLDY(viewPtr, y); if (contextPtr != NULL) { *contextPtr = ITEM_ENTRY; if (cp != NULL) { TreeViewValue *valuePtr; valuePtr = Blt_TreeView_FindValue(entryPtr, cp); if (valuePtr != NULL) { TreeViewStyle *stylePtr; stylePtr = valuePtr->stylePtr; if (stylePtr == NULL) { stylePtr = valuePtr->columnPtr->stylePtr; } if ((stylePtr->classPtr->pickProc == NULL) || ((*stylePtr->classPtr->pickProc)(entryPtr, valuePtr, stylePtr, x, y))) { *contextPtr = valuePtr; } } } if (entryPtr->flags & ENTRY_HAS_BUTTON) { TreeViewButton *buttonPtr = &viewPtr->button; int left, right, top, bottom; left = entryPtr->worldX + entryPtr->buttonX - BUTTON_PAD; right = left + buttonPtr->width + 2 * BUTTON_PAD; top = entryPtr->worldY + entryPtr->buttonY - BUTTON_PAD; bottom = top + buttonPtr->height + 2 * BUTTON_PAD; if ((x >= left) && (x < right) && (y >= top) && (y < bottom)) { *contextPtr = (ClientData)ITEM_ENTRY_BUTTON; } } } return entryPtr; } static void GetEntryExtents(TreeView *viewPtr, TreeViewEntry *entryPtr) { int entryWidth, entryHeight; int width, height; /* * FIXME: Use of DIRTY flag inconsistent. When does it * mean "dirty entry"? When does it mean "dirty column"? * Does it matter? probably */ if ((entryPtr->flags & ENTRY_DIRTY) || (viewPtr->flags & UPDATE)) { Blt_Font font; Blt_FontMetrics fontMetrics; TreeViewIcon *icons; const char *label; entryPtr->iconWidth = entryPtr->iconHeight = 0; icons = CHOOSE(viewPtr->icons, entryPtr->icons); if (icons != NULL) { int i; for (i = 0; i < 2; i++) { if (icons[i] == NULL) { break; } if (entryPtr->iconWidth < TreeView_IconWidth(icons[i])) { entryPtr->iconWidth = TreeView_IconWidth(icons[i]); } if (entryPtr->iconHeight < TreeView_IconHeight(icons[i])) { entryPtr->iconHeight = TreeView_IconHeight(icons[i]); } } entryPtr->iconWidth += 2 * ICON_PADX; entryPtr->iconHeight += 2 * ICON_PADY; } else if ((icons == NULL) || (icons[0] == NULL)) { entryPtr->iconWidth = DEF_ICON_WIDTH; entryPtr->iconHeight = DEF_ICON_HEIGHT; } entryHeight = MAX(entryPtr->iconHeight, viewPtr->button.height); font = entryPtr->font; if (font == NULL) { font = Blt_TreeView_GetStyleFont(viewPtr, viewPtr->treeColumn.stylePtr); } if (entryPtr->fullName != NULL) { Blt_Free(entryPtr->fullName); entryPtr->fullName = NULL; } if (entryPtr->textPtr != NULL) { Blt_Free(entryPtr->textPtr); entryPtr->textPtr = NULL; } Blt_GetFontMetrics(font, &fontMetrics); entryPtr->lineHeight = fontMetrics.linespace; entryPtr->lineHeight += 2 * (FOCUS_WIDTH + LABEL_PADY + viewPtr->selBW) + viewPtr->leader; label = GETLABEL(entryPtr); if (label[0] == '\0') { width = height = entryPtr->lineHeight; } else { TextStyle ts; Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); if (viewPtr->flatView) { Tcl_DString dString; Blt_TreeView_GetFullName(viewPtr, entryPtr, TRUE, &dString); entryPtr->fullName = Blt_AssertStrdup(Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); entryPtr->textPtr = Blt_Ts_CreateLayout(entryPtr->fullName, -1, &ts); } else { entryPtr->textPtr = Blt_Ts_CreateLayout(label, -1, &ts); } width = entryPtr->textPtr->width; height = entryPtr->textPtr->height; } width += 2 * (FOCUS_WIDTH + LABEL_PADX + viewPtr->selBW); height += 2 * (FOCUS_WIDTH + LABEL_PADY + viewPtr->selBW); width = ODD(width); if (entryPtr->reqHeight > height) { height = entryPtr->reqHeight; } height = ODD(height); entryWidth = width; if (entryHeight < height) { entryHeight = height; } entryPtr->labelWidth = width; entryPtr->labelHeight = height; } else { entryHeight = entryPtr->labelHeight; entryWidth = entryPtr->labelWidth; } entryHeight = MAX3(entryPtr->iconHeight, entryPtr->lineHeight, entryPtr->labelHeight); /* * Find the maximum height of the data value entries. This also has the * side effect of contributing the maximum width of the column. */ GetRowExtents(entryPtr, &width, &height); if (entryHeight < height) { entryHeight = height; } entryPtr->width = entryWidth + COLUMN_PAD; entryPtr->height = entryHeight + viewPtr->leader; /* * Force the height of the entry to an even number. This is to make the * dots or the vertical line segments coincide with the start of the * horizontal lines. */ if (entryPtr->height & 0x01) { entryPtr->height++; } entryPtr->flags &= ~ENTRY_DIRTY; } /* * TreeView Procedures */ /* *--------------------------------------------------------------------------- * * CreateTreeView -- * *--------------------------------------------------------------------------- */ static TreeView * CreateTreeView(Tcl_Interp *interp, Tcl_Obj *objPtr) { Tk_Window tkwin; TreeView *viewPtr; char *name; Tcl_DString dString; int result; name = Tcl_GetString(objPtr); tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), name, (char *)NULL); if (tkwin == NULL) { return NULL; } Tk_SetClass(tkwin, "TreeView"); viewPtr = Blt_AssertCalloc(1, sizeof(TreeView)); viewPtr->tkwin = tkwin; viewPtr->display = Tk_Display(tkwin); viewPtr->interp = interp; viewPtr->flags = (HIDE_ROOT | TV_SHOW_COLUMN_TITLES | DIRTY | LAYOUT_PENDING | REPOPULATE); viewPtr->leader = 0; viewPtr->dashes = 1; viewPtr->highlightWidth = 2; viewPtr->selBW = 1; viewPtr->borderWidth = 2; viewPtr->relief = TK_RELIEF_SUNKEN; viewPtr->selRelief = TK_RELIEF_FLAT; viewPtr->scrollMode = BLT_SCROLL_MODE_HIERBOX; viewPtr->selectMode = SELECT_MODE_SINGLE; viewPtr->button.closeRelief = viewPtr->button.openRelief = TK_RELIEF_SOLID; viewPtr->reqWidth = 0; viewPtr->reqHeight = 0; viewPtr->xScrollUnits = viewPtr->yScrollUnits = 20; viewPtr->lineWidth = 1; viewPtr->button.borderWidth = 1; viewPtr->columns = Blt_Chain_Create(); viewPtr->buttonFlags = BUTTON_AUTO; viewPtr->selected = Blt_Chain_Create(); viewPtr->userStyles = Blt_Chain_Create(); viewPtr->sortColumnPtr = &viewPtr->treeColumn; Blt_InitHashTableWithPool(&viewPtr->entryTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&viewPtr->columnTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&viewPtr->iconTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->selectTable, BLT_ONE_WORD_KEYS); Blt_InitHashTable(&viewPtr->uidTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->styleTable, BLT_STRING_KEYS); viewPtr->bindTable = Blt_CreateBindingTable(interp, tkwin, viewPtr, PickItem, GetTags); Blt_InitHashTable(&viewPtr->entryTagTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->columnTagTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->buttonTagTable, BLT_STRING_KEYS); Blt_InitHashTable(&viewPtr->styleTagTable, BLT_STRING_KEYS); viewPtr->entryPool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); viewPtr->valuePool = Blt_PoolCreate(BLT_FIXED_SIZE_ITEMS); Blt_SetWindowInstanceData(tkwin, viewPtr); viewPtr->cmdToken = Tcl_CreateObjCommand(interp, Tk_PathName(viewPtr->tkwin), Blt_TreeView_WidgetInstCmd, viewPtr, WidgetInstCmdDeleteProc); Tk_CreateSelHandler(viewPtr->tkwin, XA_PRIMARY, XA_STRING, SelectionProc, viewPtr, XA_STRING); Tk_CreateEventHandler(viewPtr->tkwin, ExposureMask | StructureNotifyMask | FocusChangeMask, TreeViewEventProc, viewPtr); /* * Create a default style. This must exist before we can create the * treeview column. */ viewPtr->stylePtr = Blt_TreeView_CreateStyle(interp, viewPtr, STYLE_TEXTBOX, "text"); if (viewPtr->stylePtr == NULL) { return NULL; } /* * By default create a tree. The name will be the same as the widget * pathname. */ viewPtr->tree = Blt_Tree_Open(interp, Tk_PathName(viewPtr->tkwin), TREE_CREATE); if (viewPtr->tree == NULL) { return NULL; } /* Create a default column to display the view of the tree. */ Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "BLT TreeView ", -1); Tcl_DStringAppend(&dString, Tk_PathName(viewPtr->tkwin), -1); result = Blt_TreeView_CreateColumn(viewPtr, &viewPtr->treeColumn, Tcl_DStringValue(&dString), ""); Tcl_DStringFree(&dString); if (result != TCL_OK) { return NULL; } Blt_Chain_Append(viewPtr->columns, &viewPtr->treeColumn); return viewPtr; } static void TeardownEntries(TreeView *viewPtr) { Blt_HashSearch iter; Blt_HashEntry *hPtr; /* Release the current tree, removing any entry fields. */ for (hPtr = Blt_FirstHashEntry(&viewPtr->entryTable, &iter); hPtr != NULL; hPtr = Blt_NextHashEntry(&iter)) { TreeViewEntry *entryPtr; entryPtr = Blt_GetHashValue(hPtr); DestroyEntry((ClientData)entryPtr); } Blt_DeleteHashTable(&viewPtr->entryTable); } /* *--------------------------------------------------------------------------- * * DestroyTreeView -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to * clean up the internal structure of a TreeView at a safe time (when * no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the widget is freed up. * *--------------------------------------------------------------------------- */ static void DestroyTreeView(DestroyData dataPtr) /* Pointer to the widget record. */ { Blt_ChainLink link; TreeView *viewPtr = (TreeView *)dataPtr; TreeViewButton *buttonPtr; TreeViewStyle *stylePtr; TeardownEntries(viewPtr); if (viewPtr->tree != NULL) { Blt_Tree_Close(viewPtr->tree); viewPtr->tree = NULL; } bltTreeViewTreeOption.clientData = viewPtr; bltTreeViewIconsOption.clientData = viewPtr; Blt_FreeOptions(bltTreeViewSpecs, (char *)viewPtr, viewPtr->display, 0); if (viewPtr->tkwin != NULL) { Tk_DeleteSelHandler(viewPtr->tkwin, XA_PRIMARY, XA_STRING); } if (viewPtr->lineGC != NULL) { Tk_FreeGC(viewPtr->display, viewPtr->lineGC); } if (viewPtr->focusGC != NULL) { Blt_FreePrivateGC(viewPtr->display, viewPtr->focusGC); } if (viewPtr->selGC != NULL) { Blt_FreePrivateGC(viewPtr->display, viewPtr->selGC); } if (viewPtr->visibleArr != NULL) { Blt_Free(viewPtr->visibleArr); } if (viewPtr->flatArr != NULL) { Blt_Free(viewPtr->flatArr); } if (viewPtr->levelInfo != NULL) { Blt_Free(viewPtr->levelInfo); } buttonPtr = &viewPtr->button; if (buttonPtr->activeGC != NULL) { Tk_FreeGC(viewPtr->display, buttonPtr->activeGC); } if (buttonPtr->normalGC != NULL) { Tk_FreeGC(viewPtr->display, buttonPtr->normalGC); } if (viewPtr->stylePtr != NULL) { Blt_TreeView_FreeStyle(viewPtr, viewPtr->stylePtr); } Blt_TreeView_DestroyColumns(viewPtr); Blt_DestroyBindingTable(viewPtr->bindTable); Blt_Chain_Destroy(viewPtr->selected); Blt_DeleteHashTable(&viewPtr->entryTagTable); Blt_DeleteHashTable(&viewPtr->columnTagTable); Blt_DeleteHashTable(&viewPtr->buttonTagTable); Blt_DeleteHashTable(&viewPtr->styleTagTable); /* Remove any user-specified style that might remain. */ for (link = Blt_Chain_FirstLink(viewPtr->userStyles); link != NULL; link = Blt_Chain_NextLink(link)) { stylePtr = Blt_Chain_GetValue(link); stylePtr->link = NULL; Blt_TreeView_FreeStyle(viewPtr, stylePtr); } Blt_Chain_Destroy(viewPtr->userStyles); if (viewPtr->comboWin != NULL) { Tk_DestroyWindow(viewPtr->comboWin); } Blt_DeleteHashTable(&viewPtr->styleTable); Blt_DeleteHashTable(&viewPtr->selectTable); Blt_DeleteHashTable(&viewPtr->uidTable); Blt_PoolDestroy(viewPtr->entryPool); Blt_PoolDestroy(viewPtr->valuePool); DumpIconTable(viewPtr); Blt_Free(viewPtr); } /* *--------------------------------------------------------------------------- * * TreeViewEventProc -- * * This procedure is invoked by the Tk dispatcher for various events on * treeview widgets. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get cleaned up. * When it gets exposed, it is redisplayed. * *--------------------------------------------------------------------------- */ static void TreeViewEventProc(ClientData clientData, XEvent *eventPtr) { TreeView *viewPtr = clientData; if (eventPtr->type == Expose) { if (eventPtr->xexpose.count == 0) { Blt_TreeView_EventuallyRedraw(viewPtr); Blt_PickCurrentItem(viewPtr->bindTable); } } else if (eventPtr->type == ConfigureNotify) { viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); Blt_TreeView_EventuallyRedraw(viewPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail != NotifyInferior) { if (eventPtr->type == FocusIn) { viewPtr->flags |= FOCUS; } else { viewPtr->flags &= ~FOCUS; } Blt_TreeView_EventuallyRedraw(viewPtr); } } else if (eventPtr->type == DestroyNotify) { if (viewPtr->tkwin != NULL) { viewPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(viewPtr->interp, viewPtr->cmdToken); } if (viewPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayTreeView, viewPtr); } if (viewPtr->flags & TV_SELECT_PENDING) { Tcl_CancelIdleCall(Blt_TreeView_SelectCmdProc, viewPtr); } Tcl_EventuallyFree(viewPtr, DestroyTreeView); } } /* Selection Procedures */ /* *--------------------------------------------------------------------------- * * SelectionProc -- * * This procedure is called back by Tk when the selection is requested by * someone. It returns part or all of the selection in a buffer provided * by the caller. * * Results: * The return value is the number of non-NULL bytes stored at buffer. * Buffer is filled (or partially filled) with a NUL-terminated string * containing part or all of the selection, as given by offset and * maxBytes. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static int SelectionProc( ClientData clientData, /* Information about the widget. */ int offset, /* Offset within selection of first * character to be returned. */ char *buffer, /* Location in which to place * selection. */ int maxBytes) /* Maximum number of bytes to place at * buffer, not including terminating * NULL character. */ { Tcl_DString dString; TreeView *viewPtr = clientData; TreeViewEntry *entryPtr; int size; if ((viewPtr->flags & TV_SELECT_EXPORT) == 0) { return -1; } /* * Retrieve the names of the selected entries. */ Tcl_DStringInit(&dString); if (viewPtr->flags & TV_SELECT_SORTED) { Blt_ChainLink link; for (link = Blt_Chain_FirstLink(viewPtr->selected); link != NULL; link = Blt_Chain_NextLink(link)) { entryPtr = Blt_Chain_GetValue(link); Tcl_DStringAppend(&dString, GETLABEL(entryPtr), -1); Tcl_DStringAppend(&dString, "\n", -1); } } else { for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK)) { if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { Tcl_DStringAppend(&dString, GETLABEL(entryPtr), -1); Tcl_DStringAppend(&dString, "\n", -1); } } } size = Tcl_DStringLength(&dString) - offset; strncpy(buffer, Tcl_DStringValue(&dString) + offset, maxBytes); Tcl_DStringFree(&dString); buffer[maxBytes] = '\0'; return (size > maxBytes) ? maxBytes : size; } /* *--------------------------------------------------------------------------- * * WidgetInstCmdDeleteProc -- * * This procedure is invoked when a widget command is deleted. If the * widget isn't already in the process of being destroyed, this command * destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *--------------------------------------------------------------------------- */ static void WidgetInstCmdDeleteProc(ClientData clientData) { TreeView *viewPtr = clientData; /* * This procedure could be invoked either because the window was destroyed * and the command was then deleted (in which case tkwin is NULL) or * because the command was deleted, and then this procedure destroys the * widget. */ if (viewPtr->tkwin != NULL) { Tk_Window tkwin; tkwin = viewPtr->tkwin; viewPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } /* *--------------------------------------------------------------------------- * * Blt_TreeView_UpdateWidget -- * * Updates the GCs and other information associated with the treeview * widget. * * Results: * The return value is a standard TCL result. If TCL_ERROR is returned, * then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, etc. get * set for viewPtr; old resources get freed, if there were any. The widget * is redisplayed. * *--------------------------------------------------------------------------- */ int Blt_TreeView_UpdateWidget(Tcl_Interp *interp, TreeView *viewPtr) { GC newGC; XGCValues gcValues; unsigned long gcMask; /* * GC for dotted vertical line. */ gcMask = (GCForeground | GCLineWidth); gcValues.foreground = viewPtr->lineColor->pixel; gcValues.line_width = viewPtr->lineWidth; if (viewPtr->dashes > 0) { gcMask |= (GCLineStyle | GCDashList); gcValues.line_style = LineOnOffDash; gcValues.dashes = viewPtr->dashes; } newGC = Tk_GetGC(viewPtr->tkwin, gcMask, &gcValues); if (viewPtr->lineGC != NULL) { Tk_FreeGC(viewPtr->display, viewPtr->lineGC); } viewPtr->lineGC = newGC; /* * GC for active label. Dashed outline. */ gcMask = GCForeground | GCLineStyle; gcValues.foreground = viewPtr->focusColor->pixel; gcValues.line_style = (LineIsDashed(viewPtr->focusDashes)) ? LineOnOffDash : LineSolid; newGC = Blt_GetPrivateGC(viewPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(viewPtr->focusDashes)) { viewPtr->focusDashes.offset = 2; Blt_SetDashes(viewPtr->display, newGC, &viewPtr->focusDashes); } if (viewPtr->focusGC != NULL) { Blt_FreePrivateGC(viewPtr->display, viewPtr->focusGC); } viewPtr->focusGC = newGC; /* * GC for selection. Dashed outline. */ gcMask = GCForeground | GCLineStyle; gcValues.foreground = viewPtr->selFgColor->pixel; gcValues.line_style = (LineIsDashed(viewPtr->focusDashes)) ? LineOnOffDash : LineSolid; newGC = Blt_GetPrivateGC(viewPtr->tkwin, gcMask, &gcValues); if (LineIsDashed(viewPtr->focusDashes)) { viewPtr->focusDashes.offset = 2; Blt_SetDashes(viewPtr->display, newGC, &viewPtr->focusDashes); } if (viewPtr->selGC != NULL) { Blt_FreePrivateGC(viewPtr->display, viewPtr->selGC); } viewPtr->selGC = newGC; Blt_TreeView_ConfigureButtons(viewPtr); viewPtr->inset = viewPtr->highlightWidth + viewPtr->borderWidth + INSET_PAD; /* * If the tree object was changed, we need to setup the new one. */ if (Blt_ConfigModified(bltTreeViewSpecs, "-tree", (char *)NULL)) { TeardownEntries(viewPtr); Blt_InitHashTableWithPool(&viewPtr->entryTable, BLT_ONE_WORD_KEYS); Blt_TreeView_ClearSelection(viewPtr); if (Blt_Tree_Attach(interp, viewPtr->tree, viewPtr->treeName) != TCL_OK) { return TCL_ERROR; } viewPtr->flags |= REPOPULATE; } /* * These options change the layout of the box. Mark the widget for update. */ if (Blt_ConfigModified(bltTreeViewSpecs, "-font", "-linespacing", "-*width", "-height", "-hide*", "-tree", "-flat", (char *)NULL)) { viewPtr->flags |= (LAYOUT_PENDING | SCROLL_PENDING); } /* * If the tree view was changed, mark all the nodes dirty (we'll be * switching back to either the full path name or the label) and free the * array representing the flattened view of the tree. */ if (Blt_ConfigModified(bltTreeViewSpecs, "-hideleaves", "-flat", (char *)NULL)) { TreeViewEntry *entryPtr; viewPtr->flags |= DIRTY; /* Mark all entries dirty. */ for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, 0)) { entryPtr->flags |= ENTRY_DIRTY; } if ((!viewPtr->flatView) && (viewPtr->flatArr != NULL)) { Blt_Free(viewPtr->flatArr); viewPtr->flatArr = NULL; } } if (viewPtr->flags & REPOPULATE) { Blt_TreeNode root; Blt_Tree_CreateEventHandler(viewPtr->tree, TREE_NOTIFY_ALL, TreeEventProc, viewPtr); TraceColumns(viewPtr); root = Blt_Tree_RootNode(viewPtr->tree); /* Automatically add view-entry values to the new tree. */ Blt_Tree_Apply(root, CreateApplyProc, viewPtr); viewPtr->focusPtr = viewPtr->rootPtr = Blt_TreeView_NodeToEntry(viewPtr,root); viewPtr->selMarkPtr = viewPtr->selAnchorPtr = NULL; Blt_SetFocusItem(viewPtr->bindTable, viewPtr->rootPtr, ITEM_ENTRY); /* Automatically open the root node. */ if (Blt_TreeView_OpenEntry(viewPtr, viewPtr->rootPtr) != TCL_OK) { return TCL_ERROR; } if (viewPtr->flags & TV_NEW_TAGS) { Blt_Tree_NewTagTable(viewPtr->tree); } viewPtr->flags &= ~REPOPULATE; } if (Blt_ConfigModified(bltTreeViewSpecs, "-font", "-color", (char *)NULL)) { Blt_TreeView_ConfigureColumn(viewPtr, &viewPtr->treeColumn); } Blt_TreeView_EventuallyRedraw(viewPtr); return TCL_OK; } /* *--------------------------------------------------------------------------- * * ResetCoordinates -- * * Determines the maximum height of all visible entries. * * 1. Sets the worldY coordinate for all mapped/open entries. * 2. Determines if entry needs a button. * 3. Collects the minimum height of open/mapped entries. (Do for all * entries upon insert). * 4. Figures out horizontal extent of each entry (will be width of * tree view column). * 5. Collects maximum icon size for each level. * 6. The height of its vertical line * * Results: * Returns 1 if beyond the last visible entry, 0 otherwise. * * Side effects: * The array of visible nodes is filled. * *--------------------------------------------------------------------------- */ static void ResetCoordinates(TreeView *viewPtr, TreeViewEntry *entryPtr, int *yPtr, int *indexPtr) { int depth, height; entryPtr->worldY = -1; entryPtr->vertLineLength = -1; if ((entryPtr != viewPtr->rootPtr) && (Blt_TreeView_EntryIsHidden(entryPtr))) { return; /* If the entry is hidden, then do * nothing. */ } entryPtr->worldY = *yPtr; height = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, viewPtr->button.height); entryPtr->vertLineLength = -(*yPtr + height / 2); *yPtr += entryPtr->height; entryPtr->flatIndex = *indexPtr; (*indexPtr)++; depth = DEPTH(viewPtr, entryPtr->node) + 1; if (viewPtr->levelInfo[depth].labelWidth < entryPtr->labelWidth) { viewPtr->levelInfo[depth].labelWidth = entryPtr->labelWidth; } if (viewPtr->levelInfo[depth].iconWidth < entryPtr->iconWidth) { viewPtr->levelInfo[depth].iconWidth = entryPtr->iconWidth; } viewPtr->levelInfo[depth].iconWidth |= 0x01; if ((entryPtr->flags & ENTRY_CLOSED) == 0) { TreeViewEntry *bottomPtr, *childPtr; bottomPtr = entryPtr; for (childPtr = Blt_TreeView_FirstChild(entryPtr, ENTRY_HIDE); childPtr != NULL; childPtr = Blt_TreeView_NextSibling(childPtr, ENTRY_HIDE)){ ResetCoordinates(viewPtr, childPtr, yPtr, indexPtr); bottomPtr = childPtr; } height = MAX3(bottomPtr->lineHeight, bottomPtr->iconHeight, viewPtr->button.height); entryPtr->vertLineLength += bottomPtr->worldY + height / 2; } } static void AdjustColumns(TreeView *viewPtr) { Blt_ChainLink link; TreeViewColumn *lastPtr; double weight; int growth; int nOpen; growth = VPORTWIDTH(viewPtr) - viewPtr->worldWidth; lastPtr = NULL; nOpen = 0; weight = 0.0; /* Find out how many columns still have space available */ for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; cp = Blt_Chain_GetValue(link); if (cp->flags & COLUMN_HIDDEN) { continue; } lastPtr = cp; if ((cp->weight == 0.0) || (cp->width >= cp->max) || (cp->reqWidth > 0)) { continue; } nOpen++; weight += cp->weight; } while ((nOpen > 0) && (weight > 0.0) && (growth > 0)) { int ration; ration = (int)(growth / weight); if (ration == 0) { ration = 1; } for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; int size, avail; cp = Blt_Chain_GetValue(link); if (cp->flags & COLUMN_HIDDEN) { continue; } lastPtr = cp; if ((cp->weight == 0.0) || (cp->width >= cp->max) || (cp->reqWidth > 0)) { continue; } size = (int)(ration * cp->weight); if (size > growth) { size = growth; } avail = cp->max - cp->width; if (size > avail) { size = avail; nOpen--; weight -= cp->weight; } cp->width += size; growth -= size; ration -= size; } } if ((growth > 0) && (lastPtr != NULL)) { lastPtr->width += growth; } } /* *--------------------------------------------------------------------------- * * ComputeFlatLayout -- * * Recompute the layout when entries are opened/closed, inserted/deleted, * or when text attributes change (such as font, linespacing). * * Results: * None. * * Side effects: * The world coordinates are set for all the opened entries. * *--------------------------------------------------------------------------- */ static void ComputeFlatLayout(TreeView *viewPtr) { Blt_ChainLink link; TreeViewColumn *cp; TreeViewEntry **p; TreeViewEntry *entryPtr; int count; int maxX; int y; /* * Pass 1: Reinitialize column sizes and loop through all nodes. * * 1. Recalculate the size of each entry as needed. * 2. The maximum depth of the tree. * 3. Minimum height of an entry. Dividing this by the * height of the widget gives a rough estimate of the * maximum number of visible entries. * 4. Build an array to hold level information to be filled * in on pass 2. */ if (viewPtr->flags & (DIRTY | UPDATE)) { int position; /* Reset the positions of all the columns and initialize the column used * to track the widest value. */ position = 1; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { cp = Blt_Chain_GetValue(link); cp->maxWidth = 0; cp->max = SHRT_MAX; if (cp->reqMax > 0) { cp->max = cp->reqMax; } cp->position = position; position++; } /* If the view needs to be resorted, free the old view. */ if ((viewPtr->flags & (DIRTY|RESORT|SORT_PENDING|TV_SORT_AUTO)) && (viewPtr->flatArr != NULL)) { Blt_Free(viewPtr->flatArr); viewPtr->flatArr = NULL; } /* Recreate the flat view of all the open and not-hidden entries. */ if (viewPtr->flatArr == NULL) { count = 0; /* Count the number of open entries to allocate for the array. */ for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK)) { if ((viewPtr->flags & HIDE_ROOT) && (entryPtr == viewPtr->rootPtr)) { continue; } count++; } viewPtr->nEntries = count; /* Allocate an array for the flat view. */ viewPtr->flatArr = Blt_AssertCalloc((count + 1), sizeof(TreeViewEntry *)); /* Fill the array with open and not-hidden entries */ p = viewPtr->flatArr; for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK)) { if ((viewPtr->flags & HIDE_ROOT) && (entryPtr == viewPtr->rootPtr)) { continue; } *p++ = entryPtr; } *p = NULL; viewPtr->flags &= ~SORTED; /* Indicate the view isn't * sorted. */ } /* Collect the extents of the entries in the flat view. */ viewPtr->depth = 0; viewPtr->minHeight = SHRT_MAX; for (p = viewPtr->flatArr; *p != NULL; p++) { entryPtr = *p; GetEntryExtents(viewPtr, entryPtr); if (viewPtr->minHeight > entryPtr->height) { viewPtr->minHeight = entryPtr->height; } entryPtr->flags &= ~ENTRY_HAS_BUTTON; } if (viewPtr->levelInfo != NULL) { Blt_Free(viewPtr->levelInfo); } viewPtr->levelInfo = Blt_AssertCalloc(viewPtr->depth+2, sizeof(LevelInfo)); viewPtr->flags &= ~(DIRTY | UPDATE | RESORT); if (viewPtr->flags & TV_SORT_AUTO) { /* If we're auto-sorting, schedule the view to be resorted. */ viewPtr->flags |= SORT_PENDING; } } if (viewPtr->flags & SORT_PENDING) { Blt_TreeView_SortFlatView(viewPtr); } viewPtr->levelInfo[0].labelWidth = viewPtr->levelInfo[0].x = viewPtr->levelInfo[0].iconWidth = 0; /* * Pass 2: Loop through all open/mapped nodes. * * 1. Set world y-coordinates for entries. We must defer * setting the x-coordinates until we know the maximum * icon sizes at each level. * 2. Compute the maximum depth of the tree. * 3. Build an array to hold level information. */ y = 0; count = 0; for(p = viewPtr->flatArr; *p != NULL; p++) { entryPtr = *p; entryPtr->flatIndex = count++; entryPtr->worldY = y; entryPtr->vertLineLength = 0; y += entryPtr->height; if (viewPtr->levelInfo[0].labelWidth < entryPtr->labelWidth) { viewPtr->levelInfo[0].labelWidth = entryPtr->labelWidth; } if (viewPtr->levelInfo[0].iconWidth < entryPtr->iconWidth) { viewPtr->levelInfo[0].iconWidth = entryPtr->iconWidth; } } viewPtr->levelInfo[0].iconWidth |= 0x01; viewPtr->worldHeight = y; /* Set the scroll height of the * hierarchy. */ if (viewPtr->worldHeight < 1) { viewPtr->worldHeight = 1; } maxX = viewPtr->levelInfo[0].iconWidth + viewPtr->levelInfo[0].labelWidth; viewPtr->treeColumn.maxWidth = maxX; viewPtr->treeWidth = maxX; viewPtr->flags |= VIEWPORT; } /* *--------------------------------------------------------------------------- * * ComputeTreeLayout -- * * Recompute the layout when entries are opened/closed, inserted/deleted, * or when text attributes change (such as font, linespacing). * * Results: * None. * * Side effects: * The world coordinates are set for all the opened entries. * *--------------------------------------------------------------------------- */ static void ComputeTreeLayout(TreeView *viewPtr) { int y; int index; /* * Pass 1: Reinitialize column sizes and loop through all nodes. * * 1. Recalculate the size of each entry as needed. * 2. The maximum depth of the tree. * 3. Minimum height of an entry. Dividing this by the * height of the widget gives a rough estimate of the * maximum number of visible entries. * 4. Build an array to hold level information to be filled * in on pass 2. */ if (viewPtr->flags & DIRTY) { Blt_ChainLink link; TreeViewEntry *ep; int position; position = 1; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; cp = Blt_Chain_GetValue(link); cp->maxWidth = 0; cp->max = SHRT_MAX; if (cp->reqMax > 0) { cp->max = cp->reqMax; } cp->position = position; position++; } viewPtr->minHeight = SHRT_MAX; viewPtr->depth = 0; for (ep = viewPtr->rootPtr; ep != NULL; ep = Blt_TreeView_NextEntry(ep, 0)){ GetEntryExtents(viewPtr, ep); if (viewPtr->minHeight > ep->height) { viewPtr->minHeight = ep->height; } /* * Determine if the entry should display a button (indicating that * it has children) and mark the entry accordingly. */ ep->flags &= ~ENTRY_HAS_BUTTON; if (ep->flags & BUTTON_SHOW) { ep->flags |= ENTRY_HAS_BUTTON; } else if (ep->flags & BUTTON_AUTO) { if (Blt_TreeView_FirstChild(ep, ENTRY_HIDE) != NULL) { ep->flags |= ENTRY_HAS_BUTTON; } } /* Determine the depth of the tree. */ if (viewPtr->depth < DEPTH(viewPtr, ep->node)) { viewPtr->depth = DEPTH(viewPtr, ep->node); } } if (viewPtr->flags & SORT_PENDING) { Blt_TreeView_SortView(viewPtr); } if (viewPtr->levelInfo != NULL) { Blt_Free(viewPtr->levelInfo); } viewPtr->levelInfo = Blt_AssertCalloc(viewPtr->depth+2, sizeof(LevelInfo)); viewPtr->flags &= ~(DIRTY | RESORT); } { size_t i; for (i = 0; i <= (viewPtr->depth + 1); i++) { viewPtr->levelInfo[i].labelWidth = viewPtr->levelInfo[i].x = viewPtr->levelInfo[i].iconWidth = 0; } } /* * Pass 2: Loop through all open/mapped nodes. * * 1. Set world y-coordinates for entries. We must defer * setting the x-coordinates until we know the maximum * icon sizes at each level. * 2. Compute the maximum depth of the tree. * 3. Build an array to hold level information. */ y = 0; if (viewPtr->flags & HIDE_ROOT) { /* If the root entry is to be hidden, cheat by offsetting the * y-coordinates by the height of the entry. */ y = -(viewPtr->rootPtr->height); } index = 0; ResetCoordinates(viewPtr, viewPtr->rootPtr, &y, &index); viewPtr->worldHeight = y; /* Set the scroll height of the * hierarchy. */ if (viewPtr->worldHeight < 1) { viewPtr->worldHeight = 1; } { int maxX; int sum; size_t i; sum = maxX = 0; i = 0; for (/*empty*/; i <= (viewPtr->depth + 1); i++) { int x; sum += viewPtr->levelInfo[i].iconWidth; if (i <= viewPtr->depth) { viewPtr->levelInfo[i + 1].x = sum; } x = sum; if (((viewPtr->flags & HIDE_ROOT) == 0) || (i > 1)) { x += viewPtr->levelInfo[i].labelWidth; } if (x > maxX) { maxX = x; } } viewPtr->treeColumn.maxWidth = maxX; viewPtr->treeWidth = maxX; } } static void LayoutColumns(TreeView *viewPtr) { Blt_ChainLink link; int sum; /* The width of the widget (in world coordinates) is the sum of the column * widths. */ viewPtr->worldWidth = viewPtr->titleHeight = 0; sum = 0; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; cp = Blt_Chain_GetValue(link); cp->width = 0; if (cp->flags & COLUMN_HIDDEN) { continue; } if ((viewPtr->flags & TV_SHOW_COLUMN_TITLES) && (viewPtr->titleHeight < cp->titleHeight)) { viewPtr->titleHeight = cp->titleHeight; } if (cp->reqWidth > 0) { cp->width = cp->reqWidth; } else { /* The computed width of a column is the maximum of the title * width and the widest entry. */ cp->width = MAX(cp->titleWidth, cp->maxWidth); /* Check that the width stays within any constraints that have * been set. */ if ((cp->reqMin > 0) && (cp->reqMin > cp->width)) { cp->width = cp->reqMin; } if ((cp->reqMax > 0) && (cp->reqMax < cp->width)) { cp->width = cp->reqMax; } } cp->width += PADDING(cp->pad) + 2 * cp->borderWidth; cp->worldX = sum; sum += cp->width; } viewPtr->worldWidth = sum; if (VPORTWIDTH(viewPtr) > sum) { AdjustColumns(viewPtr); } sum = 0; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *cp; cp = Blt_Chain_GetValue(link); cp->worldX = sum; sum += cp->width; } if (viewPtr->titleHeight > 0) { /* If any headings are displayed, add some extra padding to the * height. */ viewPtr->titleHeight += 4; } /* viewPtr->worldWidth += 10; */ if (viewPtr->yScrollUnits < 1) { viewPtr->yScrollUnits = 1; } if (viewPtr->xScrollUnits < 1) { viewPtr->xScrollUnits = 1; } if (viewPtr->worldWidth < 1) { viewPtr->worldWidth = 1; } viewPtr->flags &= ~LAYOUT_PENDING; viewPtr->flags |= SCROLL_PENDING; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_ComputeLayout -- * * Recompute the layout when entries are opened/closed, inserted/deleted, * or when text attributes change (such as font, linespacing). * * Results: * None. * * Side effects: * The world coordinates are set for all the opened entries. * *--------------------------------------------------------------------------- */ void Blt_TreeView_ComputeLayout(TreeView *viewPtr) { Blt_ChainLink link; TreeViewColumn *cp; TreeViewEntry *entryPtr; TreeViewValue *valuePtr; if (viewPtr->flatView) { ComputeFlatLayout(viewPtr); } else { ComputeTreeLayout(viewPtr); } /* * Determine the width of each column based upon the entries that as open * (not hidden). The widest entry in a column determines the width of that * column. */ /* Initialize the columns. */ for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { cp = Blt_Chain_GetValue(link); cp->maxWidth = 0; cp->max = SHRT_MAX; if (cp->reqMax > 0) { cp->max = cp->reqMax; } } /* The treeview column width was computed earlier. */ viewPtr->treeColumn.maxWidth = viewPtr->treeWidth; /* * Look at all open entries and their values. Determine the column widths * by tracking the maximum width value in each column. */ for (entryPtr = viewPtr->rootPtr; entryPtr != NULL; entryPtr = Blt_TreeView_NextEntry(entryPtr, ENTRY_MASK)) { for (valuePtr = entryPtr->values; valuePtr != NULL; valuePtr = valuePtr->nextPtr) { if (valuePtr->columnPtr->maxWidth < valuePtr->width) { valuePtr->columnPtr->maxWidth = valuePtr->width; } } } /* Now layout the columns with the proper sizes. */ LayoutColumns(viewPtr); } #ifdef notdef static void PrintFlags(TreeView *viewPtr, char *string) { fprintf(stderr, "%s: flags=", string); if (viewPtr->flags & LAYOUT_PENDING) { fprintf(stderr, "layout "); } if (viewPtr->flags & REDRAW_PENDING) { fprintf(stderr, "redraw "); } if (viewPtr->flags & SCROLLX) { fprintf(stderr, "xscroll "); } if (viewPtr->flags & SCROLLY) { fprintf(stderr, "yscroll "); } if (viewPtr->flags & FOCUS) { fprintf(stderr, "focus "); } if (viewPtr->flags & DIRTY) { fprintf(stderr, "dirty "); } if (viewPtr->flags & UPDATE) { fprintf(stderr, "update "); } if (viewPtr->flags & RESORT) { fprintf(stderr, "resort "); } if (viewPtr->flags & SORTED) { fprintf(stderr, "sorted "); } if (viewPtr->flags & SORT_PENDING) { fprintf(stderr, "sort_pending "); } if (viewPtr->flags & REDRAW_BORDERS) { fprintf(stderr, "borders "); } if (viewPtr->flags & VIEWPORT) { fprintf(stderr, "viewport "); } fprintf(stderr, "\n"); } #endif /* *--------------------------------------------------------------------------- * * ComputeVisibleEntries -- * * The entries visible in the viewport (the widget's window) are inserted * into the array of visible nodes. * * Results: * Returns 1 if beyond the last visible entry, 0 otherwise. * * Side effects: * The array of visible nodes is filled. * *--------------------------------------------------------------------------- */ static int ComputeVisibleEntries(TreeView *viewPtr) { int height; int nSlots; int maxX; int xOffset, yOffset; xOffset = Blt_AdjustViewport(viewPtr->xOffset, viewPtr->worldWidth, VPORTWIDTH(viewPtr), viewPtr->xScrollUnits, viewPtr->scrollMode); yOffset = Blt_AdjustViewport(viewPtr->yOffset, viewPtr->worldHeight, VPORTHEIGHT(viewPtr), viewPtr->yScrollUnits, viewPtr->scrollMode); if ((xOffset != viewPtr->xOffset) || (yOffset != viewPtr->yOffset)) { viewPtr->yOffset = yOffset; viewPtr->xOffset = xOffset; viewPtr->flags |= VIEWPORT; } height = VPORTHEIGHT(viewPtr); /* Allocate worst case number of slots for entry array. */ nSlots = (height / viewPtr->minHeight) + 3; if (nSlots != viewPtr->nVisible) { if (viewPtr->visibleArr != NULL) { Blt_Free(viewPtr->visibleArr); } viewPtr->visibleArr = Blt_AssertCalloc(nSlots + 1, sizeof(TreeViewEntry *)); } viewPtr->nVisible = 0; viewPtr->visibleArr[nSlots] = viewPtr->visibleArr[0] = NULL; if (viewPtr->rootPtr->flags & ENTRY_HIDE) { return TCL_OK; /* Root node is hidden. */ } /* Find the node where the view port starts. */ if (viewPtr->flatView) { TreeViewEntry **epp; /* Find the starting entry visible in the viewport. It can't be hidden * or any of it's ancestors closed. */ again: for (epp = viewPtr->flatArr; *epp != NULL; epp++) { if (((*epp)->worldY + (*epp)->height) > viewPtr->yOffset) { break; } } /* * If we can't find the starting node, then the view must be scrolled * down, but some nodes were deleted. Reset the view back to the top * and try again. */ if (*epp == NULL) { if (viewPtr->yOffset == 0) { return TCL_OK; /* All entries are hidden. */ } viewPtr->yOffset = 0; goto again; } maxX = 0; height += viewPtr->yOffset; for (/*empty*/; *epp != NULL; epp++) { int x; (*epp)->worldX = LEVELX(0) + viewPtr->treeColumn.worldX; x = (*epp)->worldX + ICONWIDTH(0) + (*epp)->width; if (x > maxX) { maxX = x; } if ((*epp)->worldY >= height) { break; } viewPtr->visibleArr[viewPtr->nVisible] = *epp; viewPtr->nVisible++; } viewPtr->visibleArr[viewPtr->nVisible] = NULL; } else { TreeViewEntry *ep; ep = viewPtr->rootPtr; while ((ep->worldY + ep->height) <= viewPtr->yOffset) { for (ep = Blt_TreeView_LastChild(ep, ENTRY_HIDE); ep != NULL; ep = Blt_TreeView_PrevSibling(ep, ENTRY_HIDE)) { if (ep->worldY <= viewPtr->yOffset) { break; } } /* * If we can't find the starting node, then the view must be * scrolled down, but some nodes were deleted. Reset the view * back to the top and try again. */ if (ep == NULL) { if (viewPtr->yOffset == 0) { return TCL_OK; /* All entries are hidden. */ } viewPtr->yOffset = 0; continue; } } height += viewPtr->yOffset; maxX = 0; viewPtr->treeColumn.maxWidth = viewPtr->treeWidth; for (; ep != NULL; ep = Blt_TreeView_NextEntry(ep, ENTRY_MASK)){ int x; int level; /* * Compute and save the entry's X-coordinate now that we know the * maximum level offset for the entire widget. */ level = DEPTH(viewPtr, ep->node); ep->worldX = LEVELX(level) + viewPtr->treeColumn.worldX; x = ep->worldX + ICONWIDTH(level) + ICONWIDTH(level+1) + ep->width; if (x > maxX) { maxX = x; } if (ep->worldY >= height) { break; } viewPtr->visibleArr[viewPtr->nVisible] = ep; viewPtr->nVisible++; } viewPtr->visibleArr[viewPtr->nVisible] = NULL; } /* * Note: It's assumed that the view port always starts at or * over an entry. Check that a change in the hierarchy * (e.g. closing a node) hasn't left the viewport beyond * the last entry. If so, adjust the viewport to start * on the last entry. */ if (viewPtr->xOffset > (viewPtr->worldWidth - viewPtr->xScrollUnits)) { viewPtr->xOffset = viewPtr->worldWidth - viewPtr->xScrollUnits; } if (viewPtr->yOffset > (viewPtr->worldHeight - viewPtr->yScrollUnits)) { viewPtr->yOffset = viewPtr->worldHeight - viewPtr->yScrollUnits; } viewPtr->xOffset = Blt_AdjustViewport(viewPtr->xOffset, viewPtr->worldWidth, VPORTWIDTH(viewPtr), viewPtr->xScrollUnits, viewPtr->scrollMode); viewPtr->yOffset = Blt_AdjustViewport(viewPtr->yOffset, viewPtr->worldHeight, VPORTHEIGHT(viewPtr), viewPtr->yScrollUnits, viewPtr->scrollMode); viewPtr->flags &= ~DIRTY; Blt_PickCurrentItem(viewPtr->bindTable); return TCL_OK; } /* *--------------------------------------------------------------------------- * * DrawLines -- * * Draws vertical lines for the ancestor nodes. While the entry of the * ancestor may not be visible, its vertical line segment does extent * into the viewport. So walk back up the hierarchy drawing lines * until we get to the root. * * Results: * None. * * Side Effects: * Vertical lines are drawn for the ancestor nodes. * *--------------------------------------------------------------------------- */ static void DrawLines( TreeView *viewPtr, /* Widget record containing the * attribute information for buttons. */ GC gc, Drawable drawable) /* Pixmap or window to draw into. */ { TreeViewEntry **epp; TreeViewButton *buttonPtr; TreeViewEntry *entryPtr; /* Entry to be drawn. */ entryPtr = viewPtr->visibleArr[0]; while (entryPtr != viewPtr->rootPtr) { int level; entryPtr = Blt_TreeView_ParentEntry(entryPtr); if (entryPtr == NULL) { break; } level = DEPTH(viewPtr, entryPtr->node); if (entryPtr->vertLineLength > 0) { int ax, ay, by; int x, y; int height; /* * World X-coordinates aren't computed for entries that are * outside the viewport. So for each off-screen ancestor node * compute it here too. */ entryPtr->worldX = LEVELX(level) + viewPtr->treeColumn.worldX; x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); height = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, viewPtr->button.height); ax = x + ICONWIDTH(level) + ICONWIDTH(level + 1) / 2; ay = y + height / 2; by = ay + entryPtr->vertLineLength; if ((entryPtr == viewPtr->rootPtr) && (viewPtr->flags & HIDE_ROOT)){ TreeViewEntry *nextPtr; int h; /* If the root node is hidden, go to the next entry to start * the vertical line. */ nextPtr = Blt_TreeView_NextEntry(viewPtr->rootPtr, ENTRY_MASK); h = MAX3(nextPtr->lineHeight, nextPtr->iconHeight, viewPtr->button.height); ay = SCREENY(viewPtr, nextPtr->worldY) + h / 2; } /* * Clip the line's Y-coordinates at the viewport's borders. */ if (ay < 0) { ay &= 0x1; /* Make sure the dotted line starts on * the same even/odd pixel. */ } if (by > Tk_Height(viewPtr->tkwin)) { by = Tk_Height(viewPtr->tkwin); } if ((ay < Tk_Height(viewPtr->tkwin)) && (by > 0)) { ay |= 0x1; XDrawLine(viewPtr->display, drawable, gc, ax, ay, ax, by); } } } buttonPtr = &viewPtr->button; for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { int x, y, w, h; int buttonY, level; int x1, x2, y1, y2; entryPtr = *epp; /* Entry is open, draw vertical line. */ x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); level = DEPTH(viewPtr, entryPtr->node); w = ICONWIDTH(level); h = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, buttonPtr->height); entryPtr->buttonX = (w - buttonPtr->width) / 2; entryPtr->buttonY = (h - buttonPtr->height) / 2; buttonY = y + entryPtr->buttonY; x1 = x + (w / 2); y1 = buttonY + (buttonPtr->height / 2); x2 = x1 + (ICONWIDTH(level) + ICONWIDTH(level + 1)) / 2; if (Blt_Tree_ParentNode(entryPtr->node) != NULL) { /* * For every node except root, draw a horizontal line from the * vertical bar to the middle of the icon. */ y1 |= 0x1; XDrawLine(viewPtr->display, drawable, gc, x1, y1, x2, y1); } if (((entryPtr->flags & ENTRY_CLOSED) == 0) && (entryPtr->vertLineLength > 0)) { y2 = y1 + entryPtr->vertLineLength; if (y2 > Tk_Height(viewPtr->tkwin)) { y2 = Tk_Height(viewPtr->tkwin); /* Clip line at window border.*/ } XDrawLine(viewPtr->display, drawable, gc, x2, y1, x2, y2); } } } void Blt_TreeView_DrawRule( TreeView *viewPtr, /* Widget record containing the * attribute information for rules. */ TreeViewColumn *cp, Drawable drawable) /* Pixmap or window to draw into. */ { int x, y1, y2; x = SCREENX(viewPtr, cp->worldX) + cp->width + viewPtr->ruleMark - viewPtr->ruleAnchor - 1; y1 = viewPtr->titleHeight + viewPtr->inset; y2 = Tk_Height(viewPtr->tkwin) - viewPtr->inset; XDrawLine(viewPtr->display, drawable, cp->ruleGC, x, y1, x, y2); viewPtr->flags = TOGGLE(viewPtr->flags, TV_RULE_ACTIVE); } /* *--------------------------------------------------------------------------- * * Blt_TreeView_DrawButton -- * * Draws a button for the given entry. The button is drawn centered in the * region immediately to the left of the origin of the entry (computed in * the layout routines). The height and width of the button were previously * calculated from the average row height. * * button height = entry height - (2 * some arbitrary padding). * button width = button height. * * The button may have a border. The symbol (either a plus or minus) is * slight smaller than the width or height minus the border. * * x,y origin of entry * * +---+ * | + | icon label * +---+ * closed * * |----|----| horizontal offset * * +---+ * | - | icon label * +---+ * open * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ void Blt_TreeView_DrawButton( TreeView *viewPtr, /* Widget record containing the * attribute information for buttons. */ TreeViewEntry *entryPtr, /* Entry. */ Drawable drawable, /* Pixmap or window to draw into. */ int x, int y) { Blt_Background bg; TreeViewButton *buttonPtr = &viewPtr->button; TreeViewIcon icon; int relief; int width, height; bg = (entryPtr == viewPtr->activeBtnPtr) ? buttonPtr->activeBg : buttonPtr->bg; relief = (entryPtr->flags & ENTRY_CLOSED) ? buttonPtr->closeRelief : buttonPtr->openRelief; if (relief == TK_RELIEF_SOLID) { relief = TK_RELIEF_FLAT; } Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, buttonPtr->width, buttonPtr->height, buttonPtr->borderWidth, relief); x += buttonPtr->borderWidth; y += buttonPtr->borderWidth; width = buttonPtr->width - (2 * buttonPtr->borderWidth); height = buttonPtr->height - (2 * buttonPtr->borderWidth); icon = NULL; if (buttonPtr->icons != NULL) { /* Open or close button icon? */ icon = buttonPtr->icons[0]; if (((entryPtr->flags & ENTRY_CLOSED) == 0) && (buttonPtr->icons[1] != NULL)) { icon = buttonPtr->icons[1]; } } if (icon != NULL) { /* Icon or rectangle? */ Tk_RedrawImage(TreeView_IconBits(icon), 0, 0, width, height, drawable, x, y); } else { int top, bottom, left, right; XSegment segments[6]; int count; GC gc; gc = (entryPtr == viewPtr->activeBtnPtr) ? buttonPtr->activeGC : buttonPtr->normalGC; if (relief == TK_RELIEF_FLAT) { /* Draw the box outline */ left = x - buttonPtr->borderWidth; top = y - buttonPtr->borderWidth; right = left + buttonPtr->width - 1; bottom = top + buttonPtr->height - 1; segments[0].x1 = left; segments[0].x2 = right; segments[0].y2 = segments[0].y1 = top; segments[1].x2 = segments[1].x1 = right; segments[1].y1 = top; segments[1].y2 = bottom; segments[2].x2 = segments[2].x1 = left; segments[2].y1 = top; segments[2].y2 = bottom; #ifdef WIN32 segments[2].y2++; #endif segments[3].x1 = left; segments[3].x2 = right; segments[3].y2 = segments[3].y1 = bottom; #ifdef WIN32 segments[3].x2++; #endif } top = y + height / 2; left = x + BUTTON_IPAD; right = x + width - BUTTON_IPAD; segments[4].y1 = segments[4].y2 = top; segments[4].x1 = left; segments[4].x2 = right - 1; #ifdef WIN32 segments[4].x2++; #endif count = 5; if (entryPtr->flags & ENTRY_CLOSED) { /* Draw the vertical line for the * plus. */ top = y + BUTTON_IPAD; bottom = y + height - BUTTON_IPAD; segments[5].y1 = top; segments[5].y2 = bottom - 1; segments[5].x1 = segments[5].x2 = x + width / 2; #ifdef WIN32 segments[5].y2++; #endif count = 6; } XDrawSegments(viewPtr->display, drawable, gc, segments, count); } } /* *--------------------------------------------------------------------------- * * Blt_TreeView_GetEntryIcon -- * * Selects the correct image for the entry's icon depending upon the * current state of the entry: active/inactive normal/selected. * * active - normal * active - selected * inactive - normal * inactive - selected * * Results: * Returns the image for the icon. * *--------------------------------------------------------------------------- */ TreeViewIcon Blt_TreeView_GetEntryIcon(TreeView *viewPtr, TreeViewEntry *entryPtr) { TreeViewIcon *icons; TreeViewIcon icon; int hasFocus; hasFocus = (entryPtr == viewPtr->focusPtr); icons = CHOOSE(viewPtr->icons, entryPtr->icons); icon = NULL; if (icons != NULL) { /* Selected or normal icon? */ icon = icons[0]; if ((hasFocus) && (icons[1] != NULL)) { icon = icons[1]; } } return icon; } static int DrawImage( TreeView *viewPtr, /* Widget record containing the * attribute information for buttons. */ TreeViewEntry *entryPtr, /* Entry to display. */ Drawable drawable, /* Pixmap or window to draw into. */ int x, int y) { TreeViewIcon icon; icon = Blt_TreeView_GetEntryIcon(viewPtr, entryPtr); if (icon != NULL) { /* Icon or default icon bitmap? */ int entryHeight; int level; int maxY; int top, bottom; int topInset, botInset; int width, height; level = DEPTH(viewPtr, entryPtr->node); entryHeight = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, viewPtr->button.height); height = TreeView_IconHeight(icon); width = TreeView_IconWidth(icon); if (viewPtr->flatView) { x += (ICONWIDTH(0) - width) / 2; } else { x += (ICONWIDTH(level + 1) - width) / 2; } y += (entryHeight - height) / 2; botInset = viewPtr->inset - INSET_PAD; topInset = viewPtr->titleHeight + viewPtr->inset; maxY = Tk_Height(viewPtr->tkwin) - botInset; top = 0; bottom = y + height; if (y < topInset) { height += y - topInset; top = -y + topInset; y = topInset; } else if (bottom >= maxY) { height = maxY - y; } Tk_RedrawImage(TreeView_IconBits(icon), 0, top, width, height, drawable, x, y); } return (icon != NULL); } static int DrawLabel( TreeView *viewPtr, /* Widget record. */ TreeViewEntry *entryPtr, /* Entry attribute information. */ Drawable drawable, /* Pixmap or window to draw into. */ int x, int y, int maxLength) { const char *label; int entryHeight; int width, height; /* Width and height of label. */ int isFocused, isSelected, isActive; entryHeight = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, viewPtr->button.height); isFocused = ((entryPtr == viewPtr->focusPtr) && (viewPtr->flags & FOCUS)); isSelected = Blt_TreeView_EntryIsSelected(viewPtr, entryPtr); isActive = (entryPtr == viewPtr->activePtr); /* Includes padding, selection 3-D border, and focus outline. */ width = entryPtr->labelWidth; height = entryPtr->labelHeight; /* Center the label, if necessary, vertically along the entry row. */ if (height < entryHeight) { y += (entryHeight - height) / 2; } if (isFocused) { /* Focus outline */ if (isSelected) { XColor *color; color = viewPtr->selFgColor; XSetForeground(viewPtr->display, viewPtr->focusGC, color->pixel); } if (width > maxLength) { width = maxLength | 0x1; /* Width has to be odd for the dots in * the focus rectangle to align. */ } XDrawRectangle(viewPtr->display, drawable, viewPtr->focusGC, x, y+1, width - 1, height - 3); if (isSelected) { XSetForeground(viewPtr->display, viewPtr->focusGC, viewPtr->focusColor->pixel); } } x += FOCUS_WIDTH + LABEL_PADX + viewPtr->selBW; y += FOCUS_WIDTH + LABEL_PADY + viewPtr->selBW; label = GETLABEL(entryPtr); if (label[0] != '\0') { TreeViewStyle *stylePtr; TextStyle ts; Blt_Font font; XColor *color; stylePtr = viewPtr->treeColumn.stylePtr; font = entryPtr->font; if (font == NULL) { font = Blt_TreeView_GetStyleFont(viewPtr, stylePtr); } if (isSelected) { color = viewPtr->selFgColor; } else if (entryPtr->color != NULL) { color = entryPtr->color; } else { color = Blt_TreeView_GetStyleFg(viewPtr, stylePtr); } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, font); Blt_Ts_SetForeground(ts, color); Blt_Ts_SetMaxLength(ts, maxLength); Blt_Ts_DrawLayout(viewPtr->tkwin, drawable, entryPtr->textPtr, &ts, x, y); if (isActive) { Blt_Ts_UnderlineLayout(viewPtr->tkwin, drawable, entryPtr->textPtr, &ts, x, y); } } return entryHeight; } /* *--------------------------------------------------------------------------- * * DrawFlatEntry -- * * Draws a button for the given entry. Note that buttons should only be * drawn if the entry has sub-entries to be opened or closed. It's the * responsibility of the calling routine to ensure this. * * The button is drawn centered in the region immediately to the left of * the origin of the entry (computed in the layout routines). The height * and width of the button were previously calculated from the average row * height. * * button height = entry height - (2 * some arbitrary padding). * button width = button height. * * The button has a border. The symbol (either a plus or minus) is slight * smaller than the width or height minus the border. * * x,y origin of entry * * +---+ * | + | icon label * +---+ * closed * * |----|----| horizontal offset * * +---+ * | - | icon label * +---+ * open * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ static void DrawFlatEntry( TreeView *viewPtr, /* Widget record containing the * attribute information for * buttons. */ TreeViewEntry *entryPtr, /* Entry to be drawn. */ Drawable drawable) /* Pixmap or window to draw into. */ { int level; int x, y, xMax; entryPtr->flags &= ~ENTRY_REDRAW; x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); if (!DrawImage(viewPtr, entryPtr, drawable, x, y)) { x -= (DEF_ICON_WIDTH * 2) / 3; } level = 0; x += ICONWIDTH(level); /* Entry label. */ xMax = SCREENX(viewPtr, viewPtr->treeColumn.worldX) + viewPtr->treeColumn.width - viewPtr->treeColumn.titleBW - viewPtr->treeColumn.pad.side2; DrawLabel(viewPtr, entryPtr, drawable, x, y, xMax - x); } /* *--------------------------------------------------------------------------- * * DrawTreeEntry -- * * Draws a button for the given entry. Note that buttons should only be * drawn if the entry has sub-entries to be opened or closed. It's the * responsibility of the calling routine to ensure this. * * The button is drawn centered in the region immediately to the left of * the origin of the entry (computed in the layout routines). The height * and width of the button were previously calculated from the average * row height. * * button height = entry height - (2 * some arbitrary padding). * button width = button height. * * The button has a border. The symbol (either a plus or minus) is * slight smaller than the width or height minus the border. * * x,y origin of entry * * +---+ * | + | icon label * +---+ * closed * * |----|----| horizontal offset * * +---+ * | - | icon label * +---+ * open * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ static void DrawTreeEntry( TreeView *viewPtr, /* Widget record. */ TreeViewEntry *entryPtr, /* Entry to be drawn. */ Drawable drawable) /* Pixmap or window to draw into. */ { TreeViewButton *buttonPtr = &viewPtr->button; int buttonY; int level; int width, height; int x, y, xMax; int x1, y1, x2, y2; entryPtr->flags &= ~ENTRY_REDRAW; x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); level = DEPTH(viewPtr, entryPtr->node); width = ICONWIDTH(level); height = MAX3(entryPtr->lineHeight, entryPtr->iconHeight, buttonPtr->height); entryPtr->buttonX = (width - buttonPtr->width) / 2; entryPtr->buttonY = (height - buttonPtr->height) / 2; buttonY = y + entryPtr->buttonY; x1 = x + (width / 2); y1 = y2 = buttonY + (buttonPtr->height / 2); x2 = x1 + (ICONWIDTH(level) + ICONWIDTH(level + 1)) / 2; if ((entryPtr->flags & ENTRY_HAS_BUTTON) && (entryPtr != viewPtr->rootPtr)){ /* * Except for the root, draw a button for every entry that needs one. * The displayed button can be either an icon (Tk image) or a line * drawing (rectangle with plus or minus sign). */ Blt_TreeView_DrawButton(viewPtr, entryPtr, drawable, x + entryPtr->buttonX, y + entryPtr->buttonY); } x += ICONWIDTH(level); if (!DrawImage(viewPtr, entryPtr, drawable, x, y)) { x -= (DEF_ICON_WIDTH * 2) / 3; } x += ICONWIDTH(level + 1); /* Entry label. */ xMax = SCREENX(viewPtr, viewPtr->treeColumn.worldX) + viewPtr->treeColumn.width - viewPtr->treeColumn.titleBW - viewPtr->treeColumn.pad.side2; DrawLabel(viewPtr, entryPtr, drawable, x, y, xMax - x); } /* *--------------------------------------------------------------------------- * * Blt_TreeView_DrawValue -- * * Draws a column value for the given entry. * * Results: * None. * * Side Effects: * A button is drawn for the entry. * *--------------------------------------------------------------------------- */ void Blt_TreeView_DrawValue( TreeView *viewPtr, /* Widget record. */ TreeViewEntry *entryPtr, /* Node of entry to be drawn. */ TreeViewValue *valuePtr, Drawable drawable, /* Pixmap or window to draw into. */ int x, int y) { TreeViewStyle *stylePtr; stylePtr = CHOOSE(valuePtr->columnPtr->stylePtr, valuePtr->stylePtr); (*stylePtr->classPtr->drawProc)(viewPtr, drawable, entryPtr, valuePtr, stylePtr, x, y); } static void DrawTitle(TreeView *viewPtr, Column *columnPtr, Drawable drawable, int x) { Blt_Background bg; XColor *fgColor; int dw, dx; int avail, need; int startX, arrowX; int needArrow; if (viewPtr->titleHeight < 1) { return; } startX = dx = arrowX = x; dw = columnPtr->width; if (columnPtr->position == Blt_Chain_GetLength(viewPtr->columns)) { /* If there's any room left over, let the last column take it. */ dw = Tk_Width(viewPtr->tkwin) - x; } else if (columnPtr->position == 1) { dw += x; dx = 0; } if (columnPtr == viewPtr->activeColumnPtr) { bg = columnPtr->activeTitleBg; fgColor = columnPtr->activeTitleFgColor; } else { bg = columnPtr->titleBg; fgColor = columnPtr->titleFgColor; } /* Clear the title area by drawing the background. */ Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, dx, viewPtr->inset, dw, viewPtr->titleHeight, 0, TK_RELIEF_FLAT); x += columnPtr->pad.side1 + columnPtr->titleBW; startX = x; needArrow = ((columnPtr == viewPtr->sortColumnPtr) && (viewPtr->flatView)); needArrow = (columnPtr == viewPtr->sortColumnPtr); avail = columnPtr->width - (2*columnPtr->titleBW) - PADDING(columnPtr->pad); need = columnPtr->titleWidth - (2 * columnPtr->titleBW) - columnPtr->arrowWidth; if (avail > need) { switch (columnPtr->titleJustify) { case TK_JUSTIFY_RIGHT: x += avail - need; break; case TK_JUSTIFY_CENTER: x += (avail - need) / 2; break; case TK_JUSTIFY_LEFT: break; } } if (needArrow) { arrowX = x + need + columnPtr->pad.side2; if (arrowX > (startX + avail - columnPtr->arrowWidth)) { arrowX = startX + avail + columnPtr->pad.side1 + columnPtr->titleBW - columnPtr->arrowWidth - 1; avail -= columnPtr->arrowWidth + 1; x -= columnPtr->arrowWidth + 1; if (x < startX) { avail -= (startX - x); x = startX; } } } if (columnPtr->titleIcon != NULL) { int ix, iy, iw, ih; ih = TreeView_IconHeight(columnPtr->titleIcon); iw = TreeView_IconWidth(columnPtr->titleIcon); ix = x; /* Center the icon vertically. We already know the column title is at * least as tall as the icon. */ iy = viewPtr->inset + (viewPtr->titleHeight - ih) / 2; Tk_RedrawImage(TreeView_IconBits(columnPtr->titleIcon), 0, 0, iw, ih, drawable, ix, iy); x += iw + 6; avail -= iw + 6; } if (columnPtr->text != NULL) { TextStyle ts; int ty; ty = viewPtr->inset + 1; if (viewPtr->titleHeight > columnPtr->textHeight) { ty += (viewPtr->titleHeight - columnPtr->textHeight) / 2; } Blt_Ts_InitStyle(ts); Blt_Ts_SetFont(ts, columnPtr->titleFont); Blt_Ts_SetForeground(ts, fgColor); Blt_Ts_SetMaxLength(ts, avail); Blt_Ts_DrawText(viewPtr->tkwin, drawable, columnPtr->text, -1, &ts, x, ty); } if (needArrow) { Blt_DrawArrow(viewPtr->display, drawable, fgColor, arrowX, viewPtr->inset, columnPtr->arrowWidth, viewPtr->titleHeight, columnPtr->titleBW, (viewPtr->sortDecreasing) ? ARROW_UP : ARROW_DOWN); } Blt_DrawBackgroundRectangle(viewPtr->tkwin, drawable, bg, dx, viewPtr->inset, dw, viewPtr->titleHeight, columnPtr->titleBW, columnPtr->titleRelief); } void Blt_TreeView_DrawHeadings(TreeView *viewPtr, Drawable drawable) { Blt_ChainLink link; TreeViewColumn *columnPtr; int x; for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { columnPtr = Blt_Chain_GetValue(link); if (columnPtr->flags & COLUMN_HIDDEN) { continue; } x = SCREENX(viewPtr, columnPtr->worldX); if ((x + columnPtr->width) < 0) { continue; /* Don't draw columns before the left * edge. */ } if (x > Tk_Width(viewPtr->tkwin)) { break; /* Discontinue when a column starts * beyond the right edge. */ } DrawTitle(viewPtr, columnPtr, drawable, x); } } static void DrawNormalBackground(TreeView *viewPtr, Drawable drawable, int x, int w) { Blt_Background bg; bg = Blt_TreeView_GetStyleBackground(viewPtr, viewPtr->stylePtr); /* This also fills the background where there are no entries. */ Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, 0, w, Tk_Height(viewPtr->tkwin), 0, TK_RELIEF_FLAT); if (viewPtr->altBg != NULL) { TreeViewEntry **epp; int count; for (count = 0, epp = viewPtr->visibleArr; *epp != NULL; epp++, count++) { if ((*epp)->flatIndex & 0x1) { int y; y = SCREENY(viewPtr, (*epp)->worldY); Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, viewPtr->altBg, x, y, w, (*epp)->height, viewPtr->selBW, viewPtr->selRelief); } } } } static void DrawSelectionBackground(TreeView *viewPtr, Drawable drawable, int x, int w) { TreeViewEntry **epp; /* * Draw the backgrounds of selected entries first. The vertical lines * connecting child entries will be draw on top. */ for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { if (Blt_TreeView_EntryIsSelected(viewPtr, *epp)) { Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, viewPtr->selBg, x, SCREENY(viewPtr, (*epp)->worldY), w, (*epp)->height, viewPtr->selBW, viewPtr->selRelief); } } } static void DrawTreeView(TreeView *viewPtr, Drawable drawable, int x) { TreeViewEntry **epp; int count; count = 0; for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { (*epp)->flags &= ~ENTRY_SELECTED; if (Blt_TreeView_EntryIsSelected(viewPtr, *epp)) { (*epp)->flags |= ENTRY_SELECTED; count++; } } if ((viewPtr->lineWidth > 0) && (viewPtr->nVisible > 0)) { /* Draw all the vertical lines from topmost node. */ DrawLines(viewPtr, viewPtr->lineGC, drawable); if (count > 0) { TkRegion rgn; rgn = TkCreateRegion(); for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { if ((*epp)->flags & ENTRY_SELECTED) { XRectangle r; r.x = 0; r.y = SCREENY(viewPtr, (*epp)->worldY); r.width = Tk_Width(viewPtr->tkwin); r.height = (*epp)->height; TkUnionRectWithRegion(&r, rgn, rgn); } } TkSetRegion(viewPtr->display, viewPtr->selGC, rgn); DrawLines(viewPtr, viewPtr->selGC, drawable); XSetClipMask(viewPtr->display, viewPtr->selGC, None); TkDestroyRegion(rgn); } } for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { DrawTreeEntry(viewPtr, *epp, drawable); } } static void DrawFlatView(TreeView *viewPtr, Drawable drawable, int x) { TreeViewEntry **epp; for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { DrawFlatEntry(viewPtr, *epp, drawable); } } void Blt_TreeView_DrawOuterBorders(TreeView *viewPtr, Drawable drawable) { /* Draw 3D border just inside of the focus highlight ring. */ if (viewPtr->borderWidth > 0) { Blt_DrawBackgroundRectangle(viewPtr->tkwin, drawable, viewPtr->bg, viewPtr->highlightWidth, viewPtr->highlightWidth, Tk_Width(viewPtr->tkwin) - 2 * viewPtr->highlightWidth, Tk_Height(viewPtr->tkwin) - 2 * viewPtr->highlightWidth, viewPtr->borderWidth, viewPtr->relief); } /* Draw focus highlight ring. */ if (viewPtr->highlightWidth > 0) { XColor *color; GC gc; color = (viewPtr->flags & FOCUS) ? viewPtr->highlightColor : viewPtr->highlightBgColor; gc = Tk_GCForColor(color, drawable); Tk_DrawFocusHighlight(viewPtr->tkwin, gc, viewPtr->highlightWidth, drawable); } viewPtr->flags &= ~REDRAW_BORDERS; } /* *--------------------------------------------------------------------------- * * DisplayTreeView -- * * This procedure is invoked to display the widget. * * Recompute the layout of the text if necessary. This is necessary if the * world coordinate system has changed. Specifically, the following may * have occurred: * * 1. a text attribute has changed (font, linespacing, etc.). * 2. an entry's option changed, possibly resizing the entry. * * This is deferred to the display routine since potentially many of * these may occur. * * Set the vertical and horizontal scrollbars. This is done here since the * window width and height are needed for the scrollbar calculations. * * Results: * None. * * Side effects: * The widget is redisplayed. * *--------------------------------------------------------------------------- */ static void DisplayTreeView(ClientData clientData) /* Information about widget. */ { Blt_ChainLink link; Pixmap drawable; TreeView *viewPtr = clientData; int reqWidth, reqHeight; viewPtr->flags &= ~REDRAW_PENDING; if (viewPtr->tkwin == NULL) { return; /* Window has been destroyed. */ } fprintf(stderr, "DisplayTreeView %s\n", Tk_PathName(viewPtr->tkwin)); if (viewPtr->flags & LAYOUT_PENDING) { /* * Recompute the layout when entries are opened/closed, * inserted/deleted, or when text attributes change (such as font, * linespacing). */ Blt_TreeView_ComputeLayout(viewPtr); } if (viewPtr->flags & (SCROLL_PENDING | DIRTY)) { int width, height; /* * Scrolling means that the view port has changed and that the visible * entries need to be recomputed. */ ComputeVisibleEntries(viewPtr); width = VPORTWIDTH(viewPtr); height = VPORTHEIGHT(viewPtr); if ((viewPtr->flags & SCROLLX) && (viewPtr->xScrollCmdObjPtr != NULL)) { Blt_UpdateScrollbar(viewPtr->interp, viewPtr->xScrollCmdObjPtr, viewPtr->xOffset, viewPtr->xOffset + width, viewPtr->worldWidth); } if ((viewPtr->flags & SCROLLY) && (viewPtr->yScrollCmdObjPtr != NULL)) { Blt_UpdateScrollbar(viewPtr->interp, viewPtr->yScrollCmdObjPtr, viewPtr->yOffset, viewPtr->yOffset+height, viewPtr->worldHeight); } viewPtr->flags &= ~SCROLL_PENDING; } reqHeight = (viewPtr->reqHeight > 0) ? viewPtr->reqHeight : viewPtr->worldHeight + viewPtr->titleHeight + 2 * viewPtr->inset + 1; reqWidth = (viewPtr->reqWidth > 0) ? viewPtr->reqWidth : viewPtr->worldWidth + 2 * viewPtr->inset; if ((reqWidth != Tk_ReqWidth(viewPtr->tkwin)) || (reqHeight != Tk_ReqHeight(viewPtr->tkwin))) { Tk_GeometryRequest(viewPtr->tkwin, reqWidth, reqHeight); } #ifdef notdef if (viewPtr->reqWidth == 0) { int w; /* * The first time through this routine, set the requested width to the * computed width. All we want is to automatically set the width of * the widget, not dynamically grow/shrink it as attributes change. */ w = viewPtr->worldWidth + 2 * viewPtr->inset; Tk_GeometryRequest(viewPtr->tkwin, w, viewPtr->reqHeight); } #endif if (!Tk_IsMapped(viewPtr->tkwin)) { return; } drawable = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), Tk_Width(viewPtr->tkwin), Tk_Height(viewPtr->tkwin), Tk_Depth(viewPtr->tkwin)); if ((viewPtr->focusPtr == NULL) && (viewPtr->nVisible > 0)) { /* Re-establish the focus entry at the top entry. */ viewPtr->focusPtr = viewPtr->visibleArr[0]; } viewPtr->flags |= VIEWPORT; if ((viewPtr->flags & TV_RULE_ACTIVE) && (viewPtr->resizeColumnPtr!=NULL)) { Blt_TreeView_DrawRule(viewPtr, viewPtr->resizeColumnPtr, drawable); } for (link = Blt_Chain_FirstLink(viewPtr->columns); link != NULL; link = Blt_Chain_NextLink(link)) { TreeViewColumn *columnPtr; int x; columnPtr = Blt_Chain_GetValue(link); columnPtr->flags &= ~COLUMN_DIRTY; if (columnPtr->flags & COLUMN_HIDDEN) { continue; } x = SCREENX(viewPtr, columnPtr->worldX); if ((x + columnPtr->width) < 0) { continue; /* Don't draw columns before the left * edge. */ } if (x > Tk_Width(viewPtr->tkwin)) { break; /* Discontinue when a column starts * beyond the right edge. */ } /* Clear the column background. */ DrawNormalBackground(viewPtr, drawable, x, columnPtr->width); DrawSelectionBackground(viewPtr, drawable, x, columnPtr->width); if (columnPtr != &viewPtr->treeColumn) { TreeViewEntry **epp; for (epp = viewPtr->visibleArr; *epp != NULL; epp++) { TreeViewValue *vp; /* Check if there's a corresponding value in the entry. */ vp = Blt_TreeView_FindValue(*epp, columnPtr); if (vp != NULL) { Blt_TreeView_DrawValue(viewPtr, *epp, vp, drawable, x + columnPtr->pad.side1, SCREENY(viewPtr, (*epp)->worldY)); } } } else { if (viewPtr->flatView) { DrawFlatView(viewPtr, drawable, x); } else { DrawTreeView(viewPtr, drawable, x); } } if (columnPtr->relief != TK_RELIEF_FLAT) { Blt_Background bg; /* Draw a 3D border around the column. */ bg = Blt_TreeView_GetStyleBackground(viewPtr, viewPtr->stylePtr); Blt_DrawBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, 0, columnPtr->width, Tk_Height(viewPtr->tkwin), columnPtr->borderWidth, columnPtr->relief); } } if (viewPtr->flags & TV_SHOW_COLUMN_TITLES) { Blt_TreeView_DrawHeadings(viewPtr, drawable); } Blt_TreeView_DrawOuterBorders(viewPtr, drawable); if ((viewPtr->flags & TV_RULE_NEEDED) && (viewPtr->resizeColumnPtr != NULL)) { Blt_TreeView_DrawRule(viewPtr, viewPtr->resizeColumnPtr, drawable); } /* Now copy the new view to the window. */ XCopyArea(viewPtr->display, drawable, Tk_WindowId(viewPtr->tkwin), viewPtr->lineGC, 0, 0, Tk_Width(viewPtr->tkwin), Tk_Height(viewPtr->tkwin), 0, 0); Tk_FreePixmap(viewPtr->display, drawable); viewPtr->flags &= ~VIEWPORT; } /* *--------------------------------------------------------------------------- * * Blt_TreeView_SelectCmdProc -- * * Invoked at the next idle point whenever the current selection changes. * Executes some application-specific code in the -selectcommand option. * This provides a way for applications to handle selection changes. * * Results: * None. * * Side effects: * TCL code gets executed for some application-specific task. * *--------------------------------------------------------------------------- */ void Blt_TreeView_SelectCmdProc(ClientData clientData) { TreeView *viewPtr = clientData; viewPtr->flags &= ~TV_SELECT_PENDING; Tcl_Preserve(viewPtr); if (viewPtr->selectCmd != NULL) { if (Tcl_GlobalEval(viewPtr->interp, viewPtr->selectCmd) != TCL_OK) { Tcl_BackgroundError(viewPtr->interp); } } Tcl_Release(viewPtr); } /* *--------------------------------------------------------------------------- * * TreeViewObjCmd -- * * This procedure is invoked to process the TCL command that corresponds to * a widget managed by this module. See the user documentation for details * on what it does. * * Results: * A standard TCL result. * * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static int TreeViewObjCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { TreeView *viewPtr; Tcl_CmdInfo cmdInfo; Tcl_Obj *initObjv[2]; char *string; int result; string = Tcl_GetString(objv[0]); if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", string, " pathName ?option value?...\"", (char *)NULL); return TCL_ERROR; } viewPtr = CreateTreeView(interp, objv[1]); if (viewPtr == NULL) { goto error; } /* * Invoke a procedure to initialize various bindings on treeview entries. * If the procedure doesn't already exist, source it from * "$blt_library/treeview.tcl". We deferred sourcing the file until now so * that the variable $blt_library could be set within a script. */ if (!Tcl_GetCommandInfo(interp, "::blt::TreeView::Initialize", &cmdInfo)) { if (Tcl_GlobalEval(interp, "source [file join $blt_library treeview.tcl]") != TCL_OK) { char info[200]; sprintf_s(info, 200, "\n (while loading bindings for %.50s)", Tcl_GetString(objv[0])); Tcl_AddErrorInfo(interp, info); goto error; } } /* * Initialize the widget's configuration options here. The options need to * be set first, so that entry, column, and style components can use them * for their own GCs. */ bltTreeViewIconsOption.clientData = viewPtr; bltTreeViewTreeOption.clientData = viewPtr; if (Blt_ConfigureWidgetFromObj(interp, viewPtr->tkwin, bltTreeViewSpecs, objc - 2, objv + 2, (char *)viewPtr, 0) != TCL_OK) { goto error; } if (Blt_ConfigureComponentFromObj(interp, viewPtr->tkwin, "button", "Button", bltTreeViewButtonSpecs, 0, (Tcl_Obj **)NULL, (char *)viewPtr, 0) != TCL_OK) { goto error; } /* * Rebuild the widget's GC and other resources that are predicated by the * widget's configuration options. Do the same for the default column. */ if (Blt_TreeView_UpdateWidget(interp, viewPtr) != TCL_OK) { goto error; } Blt_TreeView_ConfigureColumn(viewPtr, &viewPtr->treeColumn); Blt_TreeView_UpdateStyleGCs(viewPtr, viewPtr->stylePtr); /* * Invoke a procedure to initialize various bindings on treeview entries. * If the procedure doesn't already exist, source it from * "$blt_library/treeview.tcl". We deferred sourcing the file until now * so that the variable $blt_library could be set within a script. */ initObjv[0] = Tcl_NewStringObj("::blt::TreeView::Initialize", -1); initObjv[1] = objv[1]; Tcl_IncrRefCount(initObjv[0]); Tcl_IncrRefCount(initObjv[1]); result = Tcl_EvalObjv(interp, 2, initObjv, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(initObjv[1]); Tcl_DecrRefCount(initObjv[0]); if (result != TCL_OK) { goto error; } Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(viewPtr->tkwin), -1); return TCL_OK; error: if (viewPtr != NULL) { Tk_DestroyWindow(viewPtr->tkwin); } return TCL_ERROR; } int Blt_TreeViewCmdInitProc(Tcl_Interp *interp) { static Blt_InitCmdSpec cmdSpecs[] = { { "treeview", TreeViewObjCmd, }, { "hiertable", TreeViewObjCmd, } }; return Blt_InitCmds(interp, "::blt", cmdSpecs, 2); } #endif /* NO_TREEVIEW */ int Blt_TreeView_DrawLabel(TreeView *viewPtr, TreeViewEntry *entryPtr, Drawable drawable) { Blt_Background bg; TreeViewIcon icon; int level; int overlap; int srcX, srcY, destX, destY, pmWidth, pmHeight; int y2, y1, x1, x2; int dx, dy; int x, y, xMax, w, h; x = SCREENX(viewPtr, entryPtr->worldX); y = SCREENY(viewPtr, entryPtr->worldY); h = entryPtr->height - 1; w = viewPtr->treeColumn.width - (entryPtr->worldX - viewPtr->treeColumn.worldX); xMax = SCREENX(viewPtr, viewPtr->treeColumn.worldX) + viewPtr->treeColumn.width - viewPtr->treeColumn.titleBW - viewPtr->treeColumn.pad.side2; icon = Blt_TreeView_GetEntryIcon(viewPtr, entryPtr); entryPtr->flags |= ENTRY_ICON; if (viewPtr->flatView) { x += ICONWIDTH(0); w -= ICONWIDTH(0); if (icon == NULL) { x -= (DEF_ICON_WIDTH * 2) / 3; } } else { level = DEPTH(viewPtr, entryPtr->node); if (!viewPtr->flatView) { x += ICONWIDTH(level); w -= ICONWIDTH(level); } if (icon != NULL) { x += ICONWIDTH(level + 1); w -= ICONWIDTH(level + 1); } } if (Blt_TreeView_EntryIsSelected(viewPtr, entryPtr)) { bg = viewPtr->selBg; } else { bg = Blt_TreeView_GetStyleBackground(viewPtr, viewPtr->stylePtr); if ((viewPtr->altBg != NULL) && (entryPtr->flatIndex & 0x1)) { bg = viewPtr->altBg; } } x1 = viewPtr->inset; x2 = Tk_Width(viewPtr->tkwin) - viewPtr->inset; y1 = viewPtr->titleHeight + viewPtr->inset; y2 = Tk_Height(viewPtr->tkwin) - viewPtr->inset - INSET_PAD; /* Verify that the label is currently visible on screen. */ if (((x + w) < x1) || (x > x2) || ((y + h) < y1) || (y > y2)) { return 0; } /* * sx, sy * +================+ * | +-------------|--------------+ * | | dx, dy | h | * +================+ | * |<---- w ----> | * | | * +----------------------------+ */ overlap = FALSE; destX = x; destY = y; srcX = srcY = 0; pmWidth = w, pmHeight = h; dy = y1 - y; if (dy > 0) { overlap = TRUE; pmHeight -= dy; /* Reduce the height of the pixmap. */ srcY = -dy; /* Offset from the origin of the * pixmap. */ destY = y1; } dy = (y + h) - y2; if (dy > 0) { overlap = TRUE; pmHeight -= dy; } dx = x1 - x; if (dx > 0) { overlap = TRUE; pmWidth -= dx; srcX = -dx; destX = x1; } dx = (x + w) - x2; if (dx > 0) { overlap = TRUE; pmWidth -= dx; } if ((overlap) && (pmWidth > 0) && (pmHeight)) { Pixmap pm; pm = Tk_GetPixmap(viewPtr->display, Tk_WindowId(viewPtr->tkwin), pmWidth, pmHeight, Tk_Depth(viewPtr->tkwin)); /* Clear the entry label background. */ Blt_FillBackgroundRectangle(viewPtr->tkwin, pm, bg, 0, 0, pmWidth, pmHeight, 0, TK_RELIEF_FLAT); DrawLabel(viewPtr, entryPtr, pm, srcX, srcY, xMax - x); XCopyArea(viewPtr->display, pm, drawable, viewPtr->lineGC, 0, 0, pmWidth, pmHeight, destX, destY); Tk_FreePixmap(viewPtr->display, pm); } else { /* Clear the entry label background. */ Blt_FillBackgroundRectangle(viewPtr->tkwin, drawable, bg, x, y, w, h, 0, TK_RELIEF_FLAT); DrawLabel(viewPtr, entryPtr, drawable, x, y, xMax - x); } return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltTile.c���������������������������������������������������������������������0000644�0001750�0001750�00000106461�11462120063�014601� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltTile.c -- * * This module manages images for tiled backgrounds for the BLT toolkit. * * Copyright 1995-2004 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "bltInt.h" #include "bltChain.h" #include "bltHash.h" #include "bltImage.h" #include <X11/Xutil.h> #include "tkDisplay.h" #include "bltTile.h" #include "bltBitmap.h" #define TILE_THREAD_KEY "BLT Tile Data" #define TILE_MAGIC ((unsigned int) 0x46170277) typedef struct { Blt_HashTable tileTable; /* Hash table of tile structures keyed by the * name of the image. */ Tcl_Interp *interp; } TileInterpData; typedef struct { char *name; /* Name of image used to generate the pixmap.*/ Display *display; /* Display where pixmap was created. */ int flags; /* See definitions below. */ Tcl_Interp *interp; Blt_HashEntry *hashPtr; /* Pointer to hash table location */ Blt_HashTable *tablePtr; Pixmap pixmap; /* Pixmap generated from image. */ Pixmap mask; /* Monochrome pixmap used as a transparency * mask. */ GC gc; /* GC */ Tk_Image tkImage; /* Tk image token. */ Blt_Chain clients; /* Chain of clients sharing this tile. */ int width, height; /* Dimensions of the tile itself. */ } Tile; #define NOTIFY_PENDING 1 /* If set, indicates that the image associated * with the tile has been updated or deleted. * The tile pixmap will be changed and the * clients of the tile will be notified (if * they supplied a TileChangedProc routine. */ typedef struct _Blt_TileClient { unsigned int magic; Tk_Window tkwin; /* Reference window. */ int xOrigin, yOrigin; /* Origin of tile relative to the reference * window. */ Blt_TileChangedProc *notifyProc; /* If non-NULL, routine to call to when * tile image changes. */ ClientData clientData; /* Data to pass to when calling the above * routine. */ Tile *tilePtr; /* Pointer to actual tile information */ Blt_ChainLink link; /* Pointer to client entry in the server's * client list. Used to delete the client */ } TileClient; typedef struct { Display *display; Tk_Uid nameId; int depth; } TileKey; #ifdef notdef #define DEF_TILE_BORDER STD_BACKGROUND #define DEF_TILE_BORDER_WIDTH "0" #define DEF_TILE_RESIZE "none" #define DEF_TILE_X_ORIGIN "0" #define DEF_TILE_Y_ORIGIN "0" static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_BORDER, "-background", "background", "Background", DEF_TILE_BORDER_COLOR, Blt_Offset(Tile, border), 0}, {BLT_CONFIG_PIXELS_NNEG, "-borderwidth", "borderWidth", "BorderWidth", DEF_TILE_BORDERWIDTH, Blt_Offset(Tile, borderWidth), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_CUSTOM, "-image", "image", "Image", (char *)NULL, Blt_Offset(Tile, image), BLT_CONFIG_DONT_SET_DEFAULT, &imageOption}, {BLT_CONFIG_CUSTOM, "-relativeto", "relativeTo", "RelativeTo", (char *)NULL, Blt_Offset(Tile, relative), BLT_CONFIG_DONT_SET_DEFAULT, &relativeOption}, {BLT_CONFIG_CUSTOM, "-resize", "resize", "Resize", (char *)NULL, Blt_Offset(Tile, resize), BLT_CONFIG_DONT_SET_DEFAULT, &resizeOption}, {BLT_CONFIG_INT, "-xorigin", "xOrigin", "Origin", DEF_TILE_X_ORIGIN, Blt_Offset(Tile, xOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_INT, "-yorigin", "yOrigin", "Origin", DEF_TILE_Y_ORIGIN, Blt_Offset(Tile, yOrigin), BLT_CONFIG_DONT_SET_DEFAULT}, {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; #endif static Tcl_IdleProc UpdateTile; static Tk_ImageChangedProc ImageChangedProc; static Tcl_InterpDeleteProc TileInterpDeleteProc; static TileInterpData *GetTileInterpData(Tcl_Interp *interp); static void DestroyClient(TileClient *clientPtr); static void DestroyTile(Tile *tilePtr); /* *--------------------------------------------------------------------------- * * RedrawTile -- * * Generates a pixmap and draws the tile image into it. Also a * tranparency mask is possibly generated from the image. * * Results: * None. * *--------------------------------------------------------------------------- */ static void RedrawTile(Tk_Window tkwin, Tile *tilePtr) { GC newGC; Tk_PhotoHandle photo; XGCValues gcValues; int width, height; unsigned int gcMask; Tk_SizeOfImage(tilePtr->tkImage, &width, &height); Tk_MakeWindowExist(tkwin); if ((width != tilePtr->width) || (height != tilePtr->height)) { Pixmap pixmap; /* * Create the new pixmap *before* destroying the old one. I don't why * this happens, but if you delete the old pixmap first, the old * pixmap sometimes gets used in the client's GCs. I suspect it has * something to do with the way Tk reallocates X resource identifiers. */ pixmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), width, height, Tk_Depth(tkwin)); if (tilePtr->pixmap != None) { Tk_FreePixmap(Tk_Display(tkwin), tilePtr->pixmap); } tilePtr->pixmap = pixmap; } Tk_RedrawImage(tilePtr->tkImage, 0, 0, width, height, tilePtr->pixmap, 0, 0); gcMask = (GCTile | GCFillStyle); gcValues.fill_style = FillTiled; gcValues.tile = tilePtr->pixmap; newGC = Tk_GetGC(tkwin, gcMask, &gcValues); if (tilePtr->gc != NULL) { Tk_FreeGC(Tk_Display(tkwin), tilePtr->gc); } tilePtr->gc = newGC; tilePtr->width = width; tilePtr->height = height; if (tilePtr->mask != None) { #if defined(WIN32) || defined(MACOSX) Tk_FreePixmap(Tk_Display(tkwin), tilePtr->mask); #else XFreePixmap(Tk_Display(tkwin), tilePtr->mask); #endif /* WIN32 or MACOSX */ tilePtr->mask = None; } photo = Tk_FindPhoto(tilePtr->interp, Blt_Image_Name(tilePtr->tkImage)); if (photo != NULL) { Tk_PhotoImageBlock src; Tk_PhotoGetImage(photo, &src); if ((src.offset[3] < src.pixelSize) && (src.offset[3] >= 0)) { tilePtr->mask = Blt_PhotoImageMask(tkwin, src); } } } /* *--------------------------------------------------------------------------- * * UpdateTile -- * * It would be better if Tk checked for NULL proc pointers. * * Results: * None. * *--------------------------------------------------------------------------- */ static void UpdateTile(ClientData clientData) { Tile *tilePtr = (Tile *)clientData; TileClient *clientPtr; Blt_ChainLink link; tilePtr->flags &= ~NOTIFY_PENDING; if (Blt_Image_IsDeleted(tilePtr->tkImage)) { if (tilePtr->pixmap != None) { Tk_FreePixmap(tilePtr->display, tilePtr->pixmap); } tilePtr->pixmap = None; } else { /* Pick any client window to generate the new pixmap. */ link = Blt_Chain_FirstLink(tilePtr->clients); clientPtr = Blt_Chain_GetValue(link); RedrawTile(clientPtr->tkwin, tilePtr); } /* Notify each of the tile's clients that the pixmap has changed. */ for (link = Blt_ChainFirstLink(tilePtr->clients); link != NULL; link = Blt_Chain_NextLink(link)) { clientPtr = Blt_Chain_GetValue(link); if (clientPtr->notifyProc != NULL) { (*clientPtr->notifyProc) (clientPtr->clientData, clientPtr); } } } /* *--------------------------------------------------------------------------- * * ImageChangedProc * * The Tk image has changed or been deleted, redraw the pixmap * tile. * * Note: As of Tk 4.2 (rechecked in 8.3), if you redraw Tk * images from a Tk_ImageChangedProc you'll get a coredump. As a * workaround, we have to simulate how the Tk widgets use images * and redraw within an idle event. * * Results: * None. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void ImageChangedProc( ClientData clientData, int x, int y, /* Not used. */ int width, int height, /* Not used. */ int imageWidth, int imageHeight) /* Not used. */ { Tile *tilePtr = (Tile *) clientData; if (!(tilePtr->flags & NOTIFY_PENDING)) { Tcl_DoWhenIdle(UpdateTile, tilePtr); tilePtr->flags |= NOTIFY_PENDING; } } /* *--------------------------------------------------------------------------- * * DestroyTile -- * * Deletes the core tile structure, including the pixmap representing the * tile. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyTile(Tile *tilePtr) { Blt_ChainLink link; TileClient *clientPtr; if (tilePtr->flags & NOTIFY_PENDING) { Tcl_CancelIdleCall(UpdateTile, tilePtr); } for (link = Blt_Chain_FirstLink(tilePtr->clients); link != NULL; link = Blt_Chain_NextLink(link)) { clientPtr = Blt_Chain_GetValue(link); Blt_Free(clientPtr); } Blt_Chain_Destroy(tilePtr->clients); if (tilePtr->hashPtr != NULL) { Blt_DeleteHashEntry(tilePtr->tablePtr, tilePtr->hashPtr); } if (tilePtr->pixmap != None) { Tk_FreePixmap(tilePtr->display, tilePtr->pixmap); } Tk_FreeImage(tilePtr->tkImage); if (tilePtr->gc != NULL) { Tk_FreeGC(tilePtr->display, tilePtr->gc); } if (tilePtr->name != NULL) { Blt_Free(tilePtr->name); } Blt_Free(tilePtr); } /* *--------------------------------------------------------------------------- * * CreateTile -- * * Creates a tile server. A tile server manages a single image, possibly * shared by several clients. Clients will be updated (if requested) by * the server if the image changes, so they know to redraw themselves. * For X11 the image is drawn into a pixmap that is used in a new GC as * its tile. For Windows we have to do the tiling ourselves by redrawing * the image across the drawing area (see Blt_TileRectangle and * Blt_TilePolygon). * * Results: * Returns a pointer to the new tile server. If the image name does not * represent a Tk image, NULL is returned. * *--------------------------------------------------------------------------- */ static Tile * CreateTile( Tcl_Interp *interp, Tk_Window tkwin, char *imageName) { Tile *tilePtr; Tk_Image tkImage; tilePtr = Blt_AssertCalloc(1, sizeof(Tile)); /* Get the image. Funnel all change notifications to a single routine. */ tkImage = Tk_GetImage(interp, tkwin, imageName, ImageChangedProc, tilePtr); if (tkImage == NULL) { Blt_Free(tilePtr); return NULL; } /* Initialize the tile server. */ tilePtr->display = Tk_Display(tkwin); tilePtr->interp = interp; tilePtr->name = Blt_AssertStrdup(imageName); tilePtr->clients = Blt_Chain_Create(); tilePtr->tkImage = tkImage; RedrawTile(tkwin, tilePtr); return tilePtr; } /* *--------------------------------------------------------------------------- * * DestroyClient -- * * Removes the client from the servers's list of clients and memory used * by the client token is released. When the last client is deleted, the * server is also removed. * * Results: * None. * *--------------------------------------------------------------------------- */ static void DestroyClient(TileClient *clientPtr) { Tile *tilePtr; tilePtr = clientPtr->tilePtr; /* Remove the client from the server's list */ if (clientPtr->link != NULL) { Blt_Chain_DeleteLink(tilePtr->clients, clientPtr->link); } if (Blt_Chain_GetLength(tilePtr->clients) == 0) { /* * If there are no more clients of the tile, then remove the pixmap, * image, and the server record. */ DestroyTile(tilePtr); } Blt_Free(clientPtr); } /* *--------------------------------------------------------------------------- * * CreateClient -- * * Returns a token to a tile (possibly shared by many clients). A client * uses the token to query or display the tile. Clients request tiles by * their image names. Each tile is known by its display, screen depth, * and image name. The tile server tracks what clients are using the * tile and notifies them (via a callback) whenever the tile changes. If * no server exists already, one is created on-the-fly. * * Results: * A pointer to the newly created client (i.e. tile). * *--------------------------------------------------------------------------- */ static TileClient * CreateClient( Tcl_Interp *interp, Tk_Window tkwin, char *name) { TileClient *clientPtr; Tile *tilePtr; TileInterpData *dataPtr; Blt_HashEntry *hPtr; int isNew; TileKey key; dataPtr = GetTileInterpData(interp); key.nameId = Tk_GetUid(name); key.display = Tk_Display(tkwin); key.depth = Tk_Depth(tkwin); hPtr = Blt_CreateHashEntry(&dataPtr->tileTable, (char *)&key, &isNew); if (isNew) { tilePtr = CreateTile(interp, tkwin, name); if (tilePtr == NULL) { Blt_DeleteHashEntry(&dataPtr->tileTable, hPtr); return NULL; } tilePtr->hashPtr = hPtr; tilePtr->tablePtr = &dataPtr->tileTable; Blt_SetHashValue(hPtr, tilePtr); } else { tilePtr = Blt_GetHashValue(hPtr); } clientPtr = Blt_AssertCalloc(1, sizeof(TileClient)); /* Initialize client information. */ clientPtr->magic = TILE_MAGIC; clientPtr->tkwin = tkwin; clientPtr->link = Blt_Chain_Append(tilePtr->clients, clientPtr); clientPtr->tilePtr = tilePtr; return clientPtr; } /* *--------------------------------------------------------------------------- * * TileInterpDeleteProc -- * * This is called when the interpreter is deleted. All the tiles are * specific to that interpreter are destroyed. * * Results: * None. * * Side effects: * Destroys the tile table. * *--------------------------------------------------------------------------- */ /* ARGSUSED */ static void TileInterpDeleteProc( ClientData clientData, /* Thread-specific data. */ Tcl_Interp *interp) { TileInterpData *dataPtr = clientData; Blt_HashEntry *hPtr; Blt_HashSearch cursor; Tile *tilePtr; for (hPtr = Blt_FirstHashEntry(&dataPtr->tileTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { tilePtr = Blt_GetHashValue(hPtr); tilePtr->hashPtr = NULL; DestroyTile(tilePtr); } Blt_DeleteHashTable(&dataPtr->tileTable); Tcl_DeleteAssocData(interp, TILE_THREAD_KEY); Blt_Free(dataPtr); } static TileInterpData * GetTileInterpData(Tcl_Interp *interp) { TileInterpData *dataPtr; Tcl_InterpDeleteProc *proc; dataPtr = (TileInterpData *) Tcl_GetAssocData(interp, TILE_THREAD_KEY, &proc); if (dataPtr == NULL) { dataPtr = Blt_AssertMalloc(sizeof(TileInterpData)); dataPtr->interp = interp; Tcl_SetAssocData(interp, TILE_THREAD_KEY, TileInterpDeleteProc, dataPtr); Blt_InitHashTable(&dataPtr->tileTable, sizeof(TileKey)/sizeof(int)); } return dataPtr; } /* Public API for tiles. */ /* *--------------------------------------------------------------------------- * * Blt_GetTile * * Convert the named image into a tile. * * Results: * If the image is valid, a new tile is returned. If the name does not * represent a proper image, an error message is left in interp->result. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ int Blt_GetTile( Tcl_Interp *interp, /* Interpreter to report results back to */ Tk_Window tkwin, /* Window on the same display as tile */ char *imageName, /* Name of image */ Blt_Tile *tokenPtr) /* (out) Returns the allocated tile token. */ { TileClient *clientPtr; clientPtr = CreateClient(interp, tkwin, imageName); if (clientPtr == NULL) { return TCL_ERROR; } *tokenPtr = clientPtr; return TCL_OK; } /* *--------------------------------------------------------------------------- * * Blt_FreeTile * * Release the resources associated with the tile. * * Results: * None. * * Side Effects: * Memory and X resources are freed. Bookkeeping information about the * tile (i.e. width, height, and name) is discarded. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_FreeTile(TileClient *clientPtr) /* Tile to be deleted */ { if ((clientPtr == NULL) || (clientPtr->magic != TILE_MAGIC)) { return; /* No tile */ } DestroyClient(clientPtr); } /* *--------------------------------------------------------------------------- * * Blt_NameOfTile * * Returns the name of the image from which the tile was generated. * * Results: * The name of the image is returned. The name is not unique. Many * tiles may use the same image. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ const char * Blt_NameOfTile(TileClient *clientPtr) /* Tile to query */ { if (clientPtr == NULL) { return ""; } if (clientPtr->magic != TILE_MAGIC) { return "not a tile"; } return clientPtr->tilePtr->name; } /* *--------------------------------------------------------------------------- * * Blt_PixmapOfTile * * Returns the pixmap of the tile. * * Results: * The X pixmap used as the tile is returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ Pixmap Blt_PixmapOfTile(TileClient *clientPtr) /* Tile to query */ { if ((clientPtr == NULL) || (clientPtr->magic != TILE_MAGIC)) { return None; } return clientPtr->tilePtr->pixmap; } /* *--------------------------------------------------------------------------- * * Blt_SizeOfTile * * Returns the width and height of the tile. * * Results: * The width and height of the tile are returned. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_SizeOfTile( TileClient *clientPtr, /* Tile to query */ int *widthPtr, int *heightPtr) /* Returned dimensions of the tile (out) */ { if ((clientPtr == NULL) || (clientPtr->magic != TILE_MAGIC)) { *widthPtr = *heightPtr = 0; return; /* No tile given. */ } *widthPtr = clientPtr->tilePtr->width; *heightPtr = clientPtr->tilePtr->height; } /* *--------------------------------------------------------------------------- * * Blt_SetTileChangedProc * * Sets the routine to called when an image changes. * * Results: * None. * * Side Effects: * The designated routine will be called the next time the image * associated with the tile changes. * *--------------------------------------------------------------------------- */ /*LINTLIBRARY*/ void Blt_SetTileChangedProc( TileClient *clientPtr, /* Tile to query */ Blt_TileChangedProc *notifyProc, ClientData clientData) { if ((clientPtr != NULL) && (clientPtr->magic == TILE_MAGIC)) { clientPtr->notifyProc = notifyProc; clientPtr->clientData = clientData; } } /* *--------------------------------------------------------------------------- * * Blt_SetTileOrigin -- * * Set the pattern origin of the tile to a common point (i.e. the origin * (0,0) of the top level window) so that tiles from two different * widgets will match up. This done by setting the GCTileStipOrigin * field is set to the translated origin of the toplevel window in the * hierarchy. * * Results: * None. * * Side Effects: * The GCTileStipOrigin is reset in the GC. This will cause the tile * origin to change when the GC is used for drawing. * *--------------------------------------------------------------------------- */ /*ARGSUSED*/ void Blt_SetTileOrigin( Tk_Window tkwin, TileClient *clientPtr, int x, int y) { while (!Tk_IsTopLevel(tkwin)) { x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; tkwin = Tk_Parent(tkwin); } XSetTSOrigin(Tk_Display(tkwin), clientPtr->tilePtr->gc, -x, -y); clientPtr->xOrigin = -x; clientPtr->yOrigin = -y; } void Blt_SetTSOrigin( Tk_Window tkwin, TileClient *clientPtr, int x, int y) { XSetTSOrigin(Tk_Display(tkwin), clientPtr->tilePtr->gc, x, y); clientPtr->xOrigin = x; clientPtr->yOrigin = y; } #ifdef WIN32 static int tkpWinRopModes[] = { R2_BLACK, /* GXclear */ R2_MASKPEN, /* GXand */ R2_MASKPENNOT, /* GXandReverse */ R2_COPYPEN, /* GXcopy */ R2_MASKNOTPEN, /* GXandInverted */ R2_NOT, /* GXnoop */ R2_XORPEN, /* GXxor */ R2_MERGEPEN, /* GXor */ R2_NOTMERGEPEN, /* GXnor */ R2_NOTXORPEN, /* GXequiv */ R2_NOT, /* GXinvert */ R2_MERGEPENNOT, /* GXorReverse */ R2_NOTCOPYPEN, /* GXcopyInverted */ R2_MERGENOTPEN, /* GXorInverted */ R2_NOTMASKPEN, /* GXnand */ R2_WHITE /* GXset */ }; #define MASKPAT 0x00E20746 /* dest = (src & pat) | (!src & dst) */ #define COPYFG 0x00CA0749 /* dest = (pat & src) | (!pat & dst) */ #define COPYBG 0x00AC0744 /* dest = (!pat & src) | (pat & dst) */ static void TileArea( HDC srcDC, /* Source device context. */ HDC destDC, /* Destination device context. */ HDC maskDC, /* If non-NULL, device context of the tile * mask. */ TileClient *clientPtr, int x, int y, int width, int height) { Tile *tilePtr = clientPtr->tilePtr; int destX, destY; int destWidth, destHeight; int srcX, srcY; int startX, startY; /* Starting upper left corner of region. */ int delta; int left, top, right, bottom; startX = x; if (x < clientPtr->xOrigin) { delta = (clientPtr->xOrigin - x) % tilePtr->width; if (delta > 0) { startX -= (tilePtr->width - delta); } } else if (x > clientPtr->xOrigin) { delta = (x - clientPtr->xOrigin) % tilePtr->width; if (delta > 0) { startX -= delta; } } startY = y; if (y < clientPtr->yOrigin) { delta = (clientPtr->yOrigin - y) % tilePtr->height; if (delta > 0) { startY -= (tilePtr->height - delta); } } else if (y >= clientPtr->yOrigin) { delta = (y - clientPtr->yOrigin) % tilePtr->height; if (delta > 0) { startY -= delta; } } #ifdef notdef PurifyPrintf("tile is (%d,%d,%d,%d)\n", clientPtr->xOrigin, clientPtr->yOrigin, tilePtr->width, tilePtr->height); PurifyPrintf("region is (%d,%d,%d,%d)\n", x, y, width, height); PurifyPrintf("starting at %d,%d\n", startX, startY); #endif left = x; right = x + width; top = y; bottom = y + height; for (y = startY; y < bottom; y += tilePtr->height) { srcY = 0; destY = y; destHeight = tilePtr->height; if (y < top) { srcY = (top - y); destHeight = tilePtr->height - srcY; destY = top; } if ((destY + destHeight) > bottom) { destHeight = (bottom - destY); } for (x = startX; x < right; x += tilePtr->width) { srcX = 0; destX = x; destWidth = tilePtr->width; if (x < left) { srcX = (left - x); destWidth = tilePtr->width - srcX; destX = left; } if ((destX + destWidth) > right) { destWidth = (right - destX); } #ifdef notdef PurifyPrintf("drawing pattern (%d,%d,%d,%d) at %d,%d\n", srcX , srcY, destWidth, destHeight, destX, destY); #endif if (tilePtr->mask != None) { /* With transparency. */ #ifdef notdef HDC maskDC; TkWinDCState maskState; maskDC = TkWinGetDrawableDC(tilePtr->display, tilePtr->mask, &maskState); SetBkColor(destDC, RGB(255, 255, 255)); SetTextColor(destDC, RGB(0, 0, 0)); #endif BitBlt(destDC, destX, destY, destWidth, destHeight, maskDC, 0, 0, SRCAND); BitBlt(destDC, destX, destY, destWidth, destHeight, srcDC, srcX, srcY, SRCPAINT); #ifdef notdef TkWinReleaseDrawableDC(tilePtr->mask, maskDC, &maskState); #endif } else { /* Opaque tile. */ BitBlt(destDC, destX, destY, destWidth, destHeight, srcDC, srcX, srcY, SRCCOPY); } } } } void Blt_TilePolygon( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, XPoint *points, int nPoints) { HBITMAP oldBitmap; HDC hDC, memDC; HRGN hRgn; POINT *wp, *winPts; int left, right, top, bottom; Tile *tilePtr; TkWinDCState state; TkWinDrawable *twdPtr; XPoint *pend, *p; int fillMode; int width, height; if (drawable == None) { return; } tilePtr = clientPtr->tilePtr; /* Determine the bounding box of the polygon. */ left = right = points[0].x; top = bottom = points[0].y; for (p = points, pend = p + nPoints; p < pend; p++) { if (p->x < left) { left = p->x; } if (p->x > right) { right = p->x; } if (p->y < top) { top = p->y; } if (p->y > bottom) { bottom = p->y; } } width = right - left + 1; height = bottom - top + 1; /* Allocate and fill an array of POINTS to create the polygon path. */ wp = winPts = Blt_AssertMalloc(sizeof(POINT) * nPoints); for (p = points; p < pend; p++) { wp->x = p->x - left; wp->y = p->y - top; wp++; } hDC = TkWinGetDrawableDC(Tk_Display(tkwin), drawable, &state); SetROP2(hDC, tkpWinRopModes[tilePtr->gc->function]); fillMode = (tilePtr->gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING; /* Use the polygon as a clip path. */ LPtoDP(hDC, winPts, nPoints); hRgn = CreatePolygonRgn(winPts, nPoints, fillMode); SelectClipRgn(hDC, hRgn); OffsetClipRgn(hDC, left, top); Blt_Free(winPts); twdPtr = (TkWinDrawable *)tilePtr->pixmap; memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); /* Tile the bounding box. */ if (tilePtr->mask != None) { TkWinDCState maskState; HDC maskDC; maskDC = TkWinGetDrawableDC(tilePtr->display, tilePtr->mask, &maskState); SetBkColor(hDC, RGB(255, 255, 255)); SetTextColor(hDC, RGB(0, 0, 0)); TileArea(memDC, hDC, maskDC, clientPtr, left, top, width, height); TkWinReleaseDrawableDC(tilePtr->mask, maskDC, &maskState); } else { TileArea(memDC, hDC, NULL, clientPtr, left, top, width, height); } SelectBitmap(memDC, oldBitmap); DeleteDC(memDC); SelectClipRgn(hDC, NULL); DeleteRgn(hRgn); TkWinReleaseDrawableDC(drawable, hDC, &state); } void Blt_TileRectangle( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, int x, int y, unsigned int width, unsigned int height) { HBITMAP oldBitmap; HDC hDC, memDC; Tile *tilePtr; TkWinDCState state; TkWinDrawable *twdPtr; if (drawable == None) { return; } tilePtr = clientPtr->tilePtr; hDC = TkWinGetDrawableDC(Tk_Display(tkwin), drawable, &state); SetROP2(hDC, tkpWinRopModes[tilePtr->gc->function]); twdPtr = (TkWinDrawable *)tilePtr->pixmap; memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); /* Tile the bounding box. */ if (tilePtr->mask != None) { TkWinDCState maskState; HDC maskDC; maskDC = TkWinGetDrawableDC(tilePtr->display, tilePtr->mask, &maskState); SetBkColor(hDC, RGB(255, 255, 255)); SetTextColor(hDC, RGB(0, 0, 0)); TileArea(memDC, hDC, maskDC, clientPtr, x, y, width, height); TkWinReleaseDrawableDC(tilePtr->mask, maskDC, &maskState); } else { TileArea(memDC, hDC, NULL, clientPtr, x, y, width, height); } SelectBitmap(memDC, oldBitmap); DeleteDC(memDC); TkWinReleaseDrawableDC(drawable, hDC, &state); } void Blt_TileRectangles( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, XRectangle *rectangles, int nRectangles) { HBITMAP oldBitmap; HDC hDC, memDC; Tile *tilePtr; TkWinDCState state; TkWinDrawable *twdPtr; if (drawable == None) { return; } tilePtr = clientPtr->tilePtr; hDC = TkWinGetDrawableDC(Tk_Display(tkwin), drawable, &state); SetROP2(hDC, tkpWinRopModes[tilePtr->gc->function]); twdPtr = (TkWinDrawable *)tilePtr->pixmap; memDC = CreateCompatibleDC(hDC); oldBitmap = SelectBitmap(memDC, twdPtr->bitmap.handle); /* Tile the bounding box. */ if (tilePtr->mask != None) { XRectangle *rp, *rend; TkWinDCState maskState; HDC maskDC; maskDC = TkWinGetDrawableDC(tilePtr->display, tilePtr->mask, &maskState); SetBkColor(hDC, RGB(255, 255, 255)); SetTextColor(hDC, RGB(0, 0, 0)); for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { TileArea(memDC, hDC, maskDC, clientPtr, (int)rp->x, (int)rp->y, (int)rp->width, (int)rp->height); } TkWinReleaseDrawableDC(tilePtr->mask, maskDC, &maskState); } else { XRectangle *rp, *rend; for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { TileArea(memDC, hDC, NULL, clientPtr, (int)rp->x, (int)rp->y, (int)rp->width, (int)rp->height); } } SelectBitmap(memDC, oldBitmap); DeleteDC(memDC); TkWinReleaseDrawableDC(drawable, hDC, &state); } #else /* *--------------------------------------------------------------------------- * * RectangleMask -- * * Creates a rectangular mask also stippled by the mask of the tile. * This is used to draw the tiled polygon images with transparent areas. * * Results: * A bitmap mask is returned. * *--------------------------------------------------------------------------- */ static Pixmap RectangleMask( Display *display, Drawable drawable, int x, int y, unsigned int width, unsigned int height, Pixmap mask, int xOrigin, int yOrigin) { GC gc; Pixmap bitmap; XGCValues gcValues; unsigned long gcMask; bitmap = Tk_GetPixmap(display, drawable, width, height, 1); gcMask = (GCForeground | GCBackground | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCStipple); gcValues.foreground = 0x1; gcValues.background = 0x0; gcValues.fill_style = FillOpaqueStippled; gcValues.ts_x_origin = xOrigin - x; gcValues.ts_y_origin = yOrigin - y; gcValues.stipple = mask; gc = XCreateGC(display, bitmap, gcMask, &gcValues); XFillRectangle(display, bitmap, gc, 0, 0, width, height); Blt_FreePrivateGC(display, gc); return bitmap; } /* *--------------------------------------------------------------------------- * * Blt_TileRectangle -- * * Draws a rectangle filled by a tiled image. This differs from the * normal XFillRectangle call in that we also try to handle a * transparency mask. * * Results: * None. * * Side Effects: * Draws the rectangle. * *--------------------------------------------------------------------------- */ void Blt_TileRectangle( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, int x, int y, unsigned int width, unsigned int height) { Tile *tilePtr; Display *display; display = Tk_Display(tkwin); tilePtr = clientPtr->tilePtr; if (clientPtr->tilePtr->mask != None) { Pixmap mask; mask = RectangleMask(display, drawable, x, y, width, height, tilePtr->mask, clientPtr->xOrigin, clientPtr->yOrigin); XSetClipMask(display, tilePtr->gc, mask); XSetClipOrigin(display, tilePtr->gc, x, y); XFillRectangle(display, drawable, tilePtr->gc, x, y, width, height); XSetClipMask(display, tilePtr->gc, None); XSetClipOrigin(display, tilePtr->gc, 0, 0); Tk_FreePixmap(display, mask); } else { XFillRectangle(display, drawable, tilePtr->gc, x, y, width, height); } } /* *--------------------------------------------------------------------------- * * Blt_TileRectangles -- * * Draws rectangles filled by a tiled image. This differs from the * normal XFillRectangles call in that we also try to handle a * transparency mask. * * Results: * None. * * Side Effects: * Draws the given rectangles. * *--------------------------------------------------------------------------- */ void Blt_TileRectangles( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, XRectangle rectangles[], int nRectangles) { Tile *tilePtr; tilePtr = clientPtr->tilePtr; if (tilePtr->mask != None) { XRectangle *rp, *rend; for (rp = rectangles, rend = rp + nRectangles; rp < rend; rp++) { Blt_TileRectangle(tkwin, drawable, clientPtr, rp->x, rp->y, rp->width, rp->height); } } else { XFillRectangles(Tk_Display(tkwin), drawable, tilePtr->gc, rectangles, nRectangles); } } /* *--------------------------------------------------------------------------- * * PolygonMask -- * * Creates a polygon shaped mask also stippled by the mask of the tile. * This is used to draw the tiled polygon images with transparent areas. * * Results: * A bitmap mask is returned. * *--------------------------------------------------------------------------- */ static Pixmap PolygonMask( Display *display, XPoint *points, int nPoints, int x, int y, int width, int height, Pixmap mask, int xOrigin, int yOrigin) { Pixmap bitmap; XPoint *maskPts; maskPts = Blt_Malloc(sizeof(XPoint) * nPoints); if (maskPts == NULL) { return None; } { XPoint *dp, *pp, *pend; dp = maskPts; for (pp = points, pend = pp + nPoints; pp < pend; pp++) { dp->x = pp->x - x; dp->y = pp->y - y; dp++; } } bitmap = Tk_GetPixmap(display, DefaultRootWindow(display), width, height,1); { GC gc; gc = XCreateGC(display, bitmap, 0, NULL); XFillRectangle(display, bitmap, gc, 0, 0, width, height); XSetForeground(display, gc, 0x01); XSetFillStyle(display, gc, FillStippled); XSetTSOrigin(display, gc, xOrigin - x, yOrigin - y); XSetStipple(display, gc, mask); XFillPolygon(display, bitmap, gc, maskPts, nPoints, Complex, CoordModeOrigin); XFreeGC(display, gc); } Blt_Free(maskPts); return bitmap; } /* *--------------------------------------------------------------------------- * * Blt_TilePolygon -- * * Draws a polygon filled by a tiled image. This differs from the normal * XFillPolygon call in that we also try to handle a transparency mask. * * Results: * None. * * Side Effects: * Draws the polygon. * *--------------------------------------------------------------------------- */ void Blt_TilePolygon( Tk_Window tkwin, Drawable drawable, TileClient *clientPtr, XPoint *points, int nPoints) { Tile *tilePtr; Display *display; display = Tk_Display(tkwin); tilePtr = clientPtr->tilePtr; if (tilePtr->mask != None) { XPoint *pp, *pend; int left, right, top, bottom; Pixmap mask; /* Determine the bounding box of the polygon. */ left = right = points[0].x; top = bottom = points[0].y; for (pp = points, pend = pp + nPoints; pp < pend; pp++) { if (left > pp->x) { left = pp->x; } else if (right < pp->x) { right = pp->x; } if (top > pp->y) { top = pp->y; } else if (bottom < pp->y) { bottom = pp->y; } } mask = PolygonMask(display, points, nPoints, left, top, right - left + 1, bottom - top + 1, tilePtr->mask, clientPtr->xOrigin, clientPtr->yOrigin); XSetClipMask(display, tilePtr->gc, mask); XSetClipOrigin(display, tilePtr->gc, left, top); XFillPolygon(display, drawable, tilePtr->gc, points, nPoints, Complex, CoordModeOrigin); XSetClipMask(display, tilePtr->gc, None); XSetClipOrigin(display, tilePtr->gc, 0, 0); Tk_FreePixmap(display, mask); } else { XFillPolygon(display, drawable, tilePtr->gc, points, nPoints, Complex, CoordModeOrigin); } } #endif /* WIN32 */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/src/bltUnixFont.c�����������������������������������������������������������������0000644�0001750�0001750�00000241232�11506674173�015471� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * bltUnixFont.c -- * * This module implements freetype (Xft) and Tk fonts for the BLT toolkit. * * The Blt_Font is a wrapper around the existing Tk font structure, adding * Freetype fonts (via the XRender extension). The original Tk font * procedures act as a fallback if a suitable Xft enabled server can't be * found. * * Copyright 2005 George A Howlett. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <ctype.h> #include "bltInt.h" #include <bltHash.h> #include "tkDisplay.h" #include "tkFont.h" #ifdef HAVE_LIBXFT #include <ft2build.h> #include FT_FREETYPE_H #include <X11/Xft/Xft.h> #endif #include "bltFont.h" #include "bltPs.h" #undef isspace /* * This module provides antialiased fonts via Freetype as now does Tk 8.5. * This version also includes rotated fonts. No subfont matching is done to * avoid rotating dozens of subfonts for every rotated font. It's possible * that glyphs may be missing that exist in the Tk version. The trade-off * seems fair when weighing the benefit of high-quality antialiased rotated * fonts. * * Font rotation is done via the freetype font matrix for outline fonts. For * bitmap fonts we fall back on drawing the text into a bitmap and rotate the * bitmap. This requires depth-aware versions of Tk_DrawChars, since Xft is * drawing into a drawable of a different depth (depth is 1). * * The best tactic is to 1) not use bitmapped fonts if better outline fonts * are available and 2) provide our own font handling routines that allow font * rotation and font aliasing. The font aliases allow us to use a font name * like "Sans Serif" that translates into a good font for that platform and * set of fonts available (Xft or Xlfd font). */ #define DEBUG_FONT_SELECTION 0 #define DEBUG_FONT_SELECTION2 0 typedef struct _Blt_Font _Blt_Font; enum FontTypes { FONT_UNKNOWN, /* Unknown font type. */ FONT_TK, /* Normal Tk font. */ FONT_FT /* Freetype font. */ }; #ifndef HAVE_LIBXFT #define FC_WEIGHT_THIN 0 #define FC_WEIGHT_EXTRALIGHT 40 #define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT #define FC_WEIGHT_LIGHT 50 #define FC_WEIGHT_BOOK 75 #define FC_WEIGHT_REGULAR 80 #define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR #define FC_WEIGHT_MEDIUM 100 #define FC_WEIGHT_DEMIBOLD 180 #define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD #define FC_WEIGHT_BOLD 200 #define FC_WEIGHT_EXTRABOLD 205 #define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD #define FC_WEIGHT_BLACK 210 #define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK #define FC_WEIGHT_EXTRABLACK 215 #define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK #define FC_SLANT_ROMAN 0 #define FC_SLANT_ITALIC 100 #define FC_SLANT_OBLIQUE 110 #define FC_WIDTH_ULTRACONDENSED 50 #define FC_WIDTH_EXTRACONDENSED 63 #define FC_WIDTH_CONDENSED 75 #define FC_WIDTH_SEMICONDENSED 87 #define FC_WIDTH_NORMAL 100 #define FC_WIDTH_SEMIEXPANDED 113 #define FC_WIDTH_EXPANDED 125 #define FC_WIDTH_EXTRAEXPANDED 150 #define FC_WIDTH_ULTRAEXPANDED 200 #define FC_PROPORTIONAL 0 #define FC_DUAL 90 #define FC_MONO 100 #define FC_CHARCELL 110 #define FC_ANTIALIAS "antialias" /* Bool (depends) */ #define FC_AUTOHINT "autohint" /* Bool (false) */ #define FC_DECORATIVE "decorative" /* Bool */ #define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool */ #define FC_EMBOLDEN "embolden" /* Bool */ #define FC_FAMILY "family" /* String */ #define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */ #define FC_HINTING "hinting" /* Bool (true) */ #define FC_MINSPACE "minspace" /* Bool */ #define FC_OUTLINE "outline" /* Bool */ #define FC_SCALABLE "scalable" /* Bool */ #define FC_SIZE "size" /* Double */ #define FC_SLANT "slant" /* Int */ #define FC_SPACING "spacing" /* Int */ #define FC_STYLE "style" /* String */ #define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */ #define FC_WEIGHT "weight" /* Int */ #define FC_WIDTH "width" /* Int */ #endif #ifndef FC_WEIGHT_EXTRABLACK #define FC_WEIGHT_EXTRABLACK 215 #define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK #endif typedef struct { char *family; const char *weight; const char *slant; const char *width; const char *spacing; int size; /* If negative, pixels, else points */ } TkFontPattern; typedef struct { const char *name; int minChars; const char *key; int value; const char *oldvalue; } FontSpec; static FontSpec fontSpecs[] = { { "black", 2, FC_WEIGHT, FC_WEIGHT_BLACK, "*"}, { "bold", 3, FC_WEIGHT, FC_WEIGHT_BOLD, "bold"}, { "book", 3, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "charcell", 2, FC_SPACING, FC_CHARCELL, "c"}, { "condensed", 2, FC_WIDTH, FC_WIDTH_CONDENSED, "condensed"}, { "demi", 4, FC_WEIGHT, FC_WEIGHT_BOLD, "semi"}, { "demibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "semibold"}, { "dual", 2, FC_SPACING, FC_DUAL, "*"}, { "i", 1, FC_SLANT, FC_SLANT_ITALIC, "i"}, { "italic", 2, FC_SLANT, FC_SLANT_ITALIC, "i"}, { "light", 1, FC_WEIGHT, FC_WEIGHT_LIGHT, "light"}, { "medium", 2, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "mono", 2, FC_SPACING, FC_MONO, "m"}, { "normal", 1, FC_WIDTH, FC_WIDTH_NORMAL, "normal"}, { "o", 1, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "obilque", 2, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "overstrike", 2, NULL, 0, "*"}, { "proportional", 1, FC_SPACING, FC_PROPORTIONAL, "p"}, { "r", 1, FC_SLANT, FC_SLANT_ROMAN, "r"}, { "roman", 2, FC_SLANT, FC_SLANT_ROMAN, "r"}, { "semibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "semibold"}, { "semicondensed",5, FC_WIDTH, FC_WIDTH_SEMICONDENSED, "semicondensed"}, { "underline", 1, NULL, 0, "*"}, }; static int nFontSpecs = sizeof(fontSpecs) / sizeof(FontSpec); static FontSpec weightSpecs[] ={ { "black", 2, FC_WEIGHT, FC_WEIGHT_BLACK, "bold"}, { "bold", 3, FC_WEIGHT, FC_WEIGHT_BOLD, "bold"}, { "book", 3, FC_WEIGHT, FC_WEIGHT_MEDIUM, "*"}, { "demi", 4, FC_WEIGHT, FC_WEIGHT_BOLD, "*"}, { "demibold", 5, FC_WEIGHT, FC_WEIGHT_DEMIBOLD, "*"}, { "extrablack", 6, FC_WEIGHT, FC_WEIGHT_EXTRABLACK, "*"}, { "extralight", 6, FC_WEIGHT, FC_WEIGHT_EXTRALIGHT, "*"}, { "heavy", 1, FC_WEIGHT, FC_WEIGHT_HEAVY, "*"}, { "light", 1, FC_WEIGHT, FC_WEIGHT_LIGHT, "light"}, { "medium", 1, FC_WEIGHT, FC_WEIGHT_MEDIUM, "medium"}, { "normal", 1, FC_WEIGHT, FC_WEIGHT_MEDIUM, "normal"}, { "regular", 1, FC_WEIGHT, FC_WEIGHT_REGULAR, "medium"}, { "semibold", 1, FC_WEIGHT, FC_WEIGHT_SEMIBOLD, "semibold"}, { "thin", 1, FC_WEIGHT, FC_WEIGHT_THIN, "thin"}, { "ultrablack", 7, FC_WEIGHT, FC_WEIGHT_ULTRABLACK, "*"}, { "ultrabold", 7, FC_WEIGHT, FC_WEIGHT_ULTRABOLD, "*"}, { "ultralight", 6, FC_WEIGHT, FC_WEIGHT_ULTRALIGHT, "*"}, }; static int nWeightSpecs = sizeof(weightSpecs) / sizeof(FontSpec); static FontSpec slantSpecs[] ={ { "i", 1, FC_SLANT, FC_SLANT_ITALIC, "i"}, { "italic", 2, FC_SLANT, FC_SLANT_ITALIC, "i"}, { "o", 1, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "obilque", 3, FC_SLANT, FC_SLANT_OBLIQUE, "o"}, { "r", 1, FC_SLANT, FC_SLANT_ROMAN, "r"}, { "roman", 2, FC_SLANT, FC_SLANT_ROMAN, "r"}, }; static int nSlantSpecs = sizeof(slantSpecs) / sizeof(FontSpec); static FontSpec widthSpecs[] ={ { "condensed", 1, FC_WIDTH, FC_WIDTH_CONDENSED, "condensed"}, { "expanded", 3, FC_WIDTH, FC_WIDTH_EXPANDED, "*"}, { "extracondensed", 6, FC_WIDTH, FC_WIDTH_EXTRACONDENSED, "*"}, { "extraexpanded", 6, FC_WIDTH, FC_WIDTH_EXTRAEXPANDED, "*"}, { "narrow", 2, FC_WIDTH, FC_WIDTH_CONDENSED, "narrow"}, { "normal", 2, FC_WIDTH, FC_WIDTH_NORMAL, "normal"}, { "semicondensed", 5, FC_WIDTH, FC_WIDTH_SEMICONDENSED, "semicondensed"}, { "semiexpanded", 5, FC_WIDTH, FC_WIDTH_SEMIEXPANDED, "*"}, { "ultracondensed", 6, FC_WIDTH, FC_WIDTH_ULTRACONDENSED, "*"}, { "ultraexpanded", 6, FC_WIDTH, FC_WIDTH_ULTRAEXPANDED, "*"}, }; static int nWidthSpecs = sizeof(widthSpecs) / sizeof(FontSpec); static FontSpec spacingSpecs[] = { { "charcell", 2, FC_SPACING, FC_CHARCELL, "c"}, { "dual", 2, FC_SPACING, FC_DUAL, "*"}, { "mono", 2, FC_SPACING, FC_MONO, "m"}, { "proportional", 1, FC_SPACING, FC_PROPORTIONAL, "p"}, }; static int nSpacingSpecs = sizeof(spacingSpecs) / sizeof(FontSpec); static FontSpec boolSpecs[] ={ { "antialias", 1, FC_ANTIALIAS, }, { "decorative", 1, FC_DECORATIVE, }, { "embeddedbitmap", 4, FC_EMBEDDED_BITMAP, }, { "embolden", 4, FC_EMBOLDEN, }, { "globaladvance", 1, FC_GLOBAL_ADVANCE, }, { "hinting", 1, FC_HINTING, }, { "minspace", 1, FC_MINSPACE, }, { "outline", 1, FC_OUTLINE, }, { "scalable", 1, FC_SCALABLE, }, { "verticallayout", 1, FC_VERTICAL_LAYOUT, }, }; static int nBoolSpecs = sizeof(boolSpecs) / sizeof(FontSpec); static Blt_HashTable fontTable; static void TkGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr); enum XLFDFields { XLFD_FOUNDRY, XLFD_FAMILY, XLFD_WEIGHT, XLFD_SLANT, XLFD_SETWIDTH, XLFD_ADD_STYLE, XLFD_PIXEL_SIZE, XLFD_POINT_SIZE, XLFD_RESOLUTION_X, XLFD_RESOLUTION_Y, XLFD_SPACING, XLFD_AVERAGE_WIDTH, XLFD_CHARSET, XLFD_NUMFIELDS }; #ifdef HAVE_LIBXFT static void FtGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr); static int initialized = FALSE; static int IsXRenderAvailable(Tk_Window tkwin) { static int isXRenderAvail = -1; if (isXRenderAvail < 0) { int eventBase, errorBase; isXRenderAvail = FALSE; Blt_InitHashTable(&fontTable, BLT_STRING_KEYS); initialized = TRUE; if (!XRenderQueryExtension(Tk_Display(tkwin), &eventBase, &errorBase)) { return FALSE; } if (XRenderFindVisualFormat(Tk_Display(tkwin), Tk_Visual(tkwin)) == 0) { return FALSE; } isXRenderAvail = TRUE; } return isXRenderAvail; } #endif static double PointsToPixels(Tk_Window tkwin, int size) { double d; if (size < 0) { return -size; } d = size * 25.4 / 72.0; d *= WidthOfScreen(Tk_Screen(tkwin)); d /= WidthMMOfScreen(Tk_Screen(tkwin)); return d; } static double PixelsToPoints(Tk_Window tkwin, int size) { double d; if (size >= 0) { return size; } d = -size * 72.0 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); d /= WidthOfScreen(Tk_Screen(tkwin)); return d; } static void ParseXLFD(const char *fontName, int *argcPtr, char ***argvPtr) { char *p, *pend, *desc, *buf; size_t arrayLen, stringLen; int count; char **field; arrayLen = (sizeof(char *) * (XLFD_NUMFIELDS + 1)); stringLen = strlen(fontName); buf = Blt_AssertCalloc(1, arrayLen + stringLen + 1); desc = buf + arrayLen; strcpy(desc, fontName); field = (char **)buf; count = 0; for (p = desc, pend = p + stringLen; p < pend; p++, count++) { char *word; field[count] = NULL; /* Get the next word, separated by dashes (-). */ word = p; while ((*p != '\0') && (*p != '-')) { if (((*p & 0x80) == 0) && Tcl_UniCharIsUpper(UCHAR(*p))) { *p = (char)Tcl_UniCharToLower(UCHAR(*p)); } p++; } if (*p != '\0') { *p = '\0'; } if ((word[0] == '\0') || (((word[0] == '*') || (word[0] == '?')) && (word[1] == '\0'))) { continue; /* Field not specified. -- -*- -?- */ } field[count] = word; } /* * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common, * but it is (strictly) malformed, because the first * is eliding both the * Setwidth and the Addstyle fields. If the Addstyle field is a number, * then assume the above incorrect form was used and shift all the rest of * the fields right by one, so the number gets interpreted as a pixelsize. * This fix is so that we don't get a million reports that "it works under * X (as a native font name), but gives a syntax error under Windows (as a * parsed set of attributes)". */ if ((count > XLFD_ADD_STYLE) && (field[XLFD_ADD_STYLE] != NULL)) { int dummy; if (Tcl_GetInt(NULL, field[XLFD_ADD_STYLE], &dummy) == TCL_OK) { int j; for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) { field[j + 1] = field[j]; } field[XLFD_ADD_STYLE] = NULL; count++; } } *argcPtr = count; *argvPtr = field; field[XLFD_NUMFIELDS] = NULL; } /* *--------------------------------------------------------------------------- * * SearchForFontSpec -- * * Performs a binary search on the array of font specification to find a * partial, anchored match for the given option string. * * Results: * If the string matches unambiguously the index of the specification in * the array is returned. If the string does not match, even as an * abbreviation, any operation, -1 is returned. If the string matches, * but ambiguously -2 is returned. * *--------------------------------------------------------------------------- */ static int SearchForFontSpec( FontSpec *table, /* Table of font options. */ int nSpecs, /* # specifications in font spec table. */ const char *string) /* Name of font option to search for. */ { char c; int high, low; size_t length; low = 0; high = nSpecs - 1; c = tolower((unsigned char)string[0]); length = strlen(string); while (low <= high) { FontSpec *sp; int compare; int median; median = (low + high) >> 1; sp = table + median; /* Test the first character */ compare = c - sp->name[0]; if (compare == 0) { /* Now test the entire string */ compare = strncasecmp(string, sp->name, length); if (compare == 0) { if ((int)length < sp->minChars) { return -2; /* Ambiguous spec name */ } } } if (compare < 0) { high = median - 1; } else if (compare > 0) { low = median + 1; } else { return median; /* Spec found. */ } } return -1; /* Can't find spec */ } static FontSpec * FindSpec(Tcl_Interp *interp, FontSpec *tablePtr, int nSpecs, const char *string) { int n; n = SearchForFontSpec(tablePtr, nSpecs, string); if (n < 0) { if (n == -1) { if (interp != NULL) { Tcl_AppendResult(interp, "unknown ", tablePtr[0].key, " specification \"", string, "\"", (char *)NULL); } } if (n == -2) { if (interp != NULL) { Tcl_AppendResult(interp, "ambiguous ", tablePtr[0].key, " specification \"", string, "\"", (char *)NULL); } } return NULL; } return tablePtr + n; } static Blt_HashTable aliasTable; static int alias_initialized = 0; typedef struct { const char *name, *aliases[10]; } FontAlias; #ifdef HAVE_LIBXFT static FontAlias xftFontAliases[] = { { "math", { "mathematica1", "nimbus sans l condensed", "courier"}}, { "serif", { "times new roman", "nimbus roman no9 l" "times" }}, { "sans serif", { "arial", "nimbus sans l", "helvetica" }}, { "monospace", { "courier new", "nimbus mono l", "courier" }}, { "symbol", { "standard symbols l", "symbol" }}, { NULL } }; #endif static FontAlias xlfdFontAliases[] = { { "math", {"courier"}}, { "serif", {"times"}}, { "sans serif", { "helvetica" }}, { "monospace", { "courier" }}, { NULL } }; static void MakeAliasTable(Tk_Window tkwin) { Blt_HashTable familyTable; FontAlias *fp; FontAlias *table; Blt_InitHashTable(&familyTable, TCL_STRING_KEYS); #ifdef HAVE_LIBXFT if (IsXRenderAvailable(tkwin)) { FtGetFontFamilies(tkwin, &familyTable); } else { TkGetFontFamilies(tkwin, &familyTable); } #else TkGetFontFamilies(tkwin, &familyTable); #endif Blt_InitHashTable(&aliasTable, TCL_STRING_KEYS); #ifdef HAVE_LIBXFT table = (IsXRenderAvailable(tkwin)) ? xftFontAliases : xlfdFontAliases; #else table = xlfdFontAliases; #endif for(fp = table; fp->name != NULL; fp++) { Blt_HashEntry *hPtr; const char **alias; for (alias = fp->aliases; *alias != NULL; alias++) { hPtr = Blt_FindHashEntry(&familyTable, *alias); if (hPtr != NULL) { int isNew; hPtr = Blt_CreateHashEntry(&aliasTable, fp->name, &isNew); Blt_SetHashValue(hPtr, *alias); break; } } } Blt_DeleteHashTable(&familyTable); } static const char * GetAlias(const char *family) { Blt_HashEntry *hPtr; strtolower((char *)family); hPtr = Blt_FindHashEntry(&aliasTable, family); if (hPtr != NULL) { return Blt_GetHashValue(hPtr); } return family; } static Blt_NameOfFontProc TkNameOfFontProc; static Blt_GetFontMetricsProc TkGetFontMetricsProc; static Blt_FontIdProc TkFontIdProc; static Blt_MeasureCharsProc TkMeasureCharsProc; static Blt_TextStringWidthProc TkTextStringWidthProc; static Blt_FreeFontProc TkFreeFontProc; static Blt_DrawCharsProc TkDrawCharsProc; static Blt_PostscriptFontNameProc TkPostscriptFontNameProc; static Blt_FamilyOfFontProc TkFamilyOfFontProc; static Blt_CanRotateFontProc TkCanRotateFontProc; static Blt_UnderlineCharsProc TkUnderlineCharsProc; static Blt_FontClass tkFontClass = { FONT_TK, TkNameOfFontProc, /* Blt_NameOfFontProc */ TkFamilyOfFontProc, /* Blt_FamilyOfFontProc */ TkFontIdProc, /* Blt_FontIdProc */ TkGetFontMetricsProc, /* Blt_GetFontMetricsProc */ TkMeasureCharsProc, /* Blt_MeasureCharsProc */ TkTextStringWidthProc, /* Blt_TextWidthProc */ TkCanRotateFontProc, /* Blt_CanRotateFontProc */ TkDrawCharsProc, /* Blt_DrawCharsProc */ TkPostscriptFontNameProc, /* Blt_PostscriptFontNameProc */ TkFreeFontProc, /* Blt_FreeFontProc */ TkUnderlineCharsProc, /* Blt_UnderlineCharsProc */ }; static TkFontPattern * TkNewFontPattern(void) { TkFontPattern *patternPtr; patternPtr = Blt_Calloc(1, sizeof(TkFontPattern)); return patternPtr; } static void TkFreeFontPattern(TkFontPattern *patternPtr) { if (patternPtr->family != NULL) { Blt_Free((char *)patternPtr->family); } Blt_Free(patternPtr); } static void TkGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr) { char **list, **np, **nend; const char *pat; int n; pat = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"; list = XListFonts(Tk_Display(tkwin), pat, 10000, &n); for (np = list, nend = np + n; np < nend; np++) { Blt_HashEntry *hPtr; int isNew; char *family, *dash; /* Parse out the family name. Assume the names are all lower case. */ dash = strchr(*np+1, '-'); if (dash == NULL) { continue; } family = dash+1; dash = strchr(family, '-'); if (dash != NULL) { *dash = '\0'; } hPtr = Blt_CreateHashEntry(tablePtr, family, &isNew); Blt_SetHashValue(hPtr, NULL); } XFreeFontNames(list); } /* *--------------------------------------------------------------------------- * * TkParseTkDesc -- * * Parses an array of Tcl_Objs as a Tk style font description . * * "family [size] [optionList]" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a Tk font description. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static TkFontPattern * TkParseTkDesc(Tcl_Interp *interp, int objc, Tcl_Obj **objv) { TkFontPattern *patternPtr; Tcl_Obj **aobjv; int aobjc; int i; patternPtr = TkNewFontPattern(); /* Font family. */ { char *family, *dash; family = Tcl_GetString(objv[0]); dash = strchr(family, '-'); if (dash != NULL) { int size; if (Tcl_GetInt(NULL, dash + 1, &size) != TCL_OK) { goto error; } patternPtr->size = size; } if (dash != NULL) { *dash = '\0'; } patternPtr->family = Blt_AssertStrdup(GetAlias(family)); if (dash != NULL) { *dash = '-'; i = 1; } objv++, objc--; } if (objc > 0) { int size; if (Tcl_GetIntFromObj(NULL, objv[0], &size) == TCL_OK) { patternPtr->size = size; objv++, objc--; } } aobjc = objc, aobjv = objv; if (objc > 0) { if (Tcl_ListObjGetElements(NULL, objv[0], &aobjc, &aobjv) != TCL_OK) { goto error; } } for (i = 0; i < aobjc; i++) { FontSpec *specPtr; const char *key; key = Tcl_GetString(aobjv[i]); specPtr = FindSpec(interp, fontSpecs, nFontSpecs, key); if (specPtr == NULL) { goto error; } if (specPtr->key == NULL) { continue; } if (strcmp(specPtr->key, FC_WEIGHT) == 0) { patternPtr->weight = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_SLANT) == 0) { patternPtr->slant = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_SPACING) == 0) { patternPtr->spacing = specPtr->oldvalue; } else if (strcmp(specPtr->key, FC_WIDTH) == 0) { patternPtr->width = specPtr->oldvalue; } } #if DEBUG_FONT_SELECTION fprintf(stderr, "found TkDesc => Tk font \"%s\"\n", patternPtr->family); #endif return patternPtr; error: TkFreeFontPattern(patternPtr); return NULL; } /* *--------------------------------------------------------------------------- * * TkParseNameValuePairs -- * * Given Tcl_Obj list of name value pairs, parse the list saving * in the values in a font pattern structure. * * "-family family -size size -weight weight" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a valid name-value list * describing a font. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static TkFontPattern * TkParseNameValuePairs(Tcl_Interp *interp, Tcl_Obj *objPtr) { TkFontPattern *patternPtr; Tcl_Obj **objv; int objc; int i; if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split list or list is empty. */ } if (objc & 0x1) { if (interp != NULL) { Tcl_AppendResult(interp, "odd number of elements, missing value", (char *)NULL); } return NULL; /* Odd number of elements in list. */ } patternPtr = TkNewFontPattern(); for (i = 0; i < objc; i += 2) { const char *key, *value; key = Tcl_GetString(objv[i]); value = Tcl_GetString(objv[i+1]); if (strcmp(key, "-family") == 0) { if (patternPtr->family != NULL) { Blt_Free(patternPtr->family); } patternPtr->family = Blt_AssertStrdup(GetAlias(value)); } else if (strcmp(key, "-size") == 0) { int size; if (Tcl_GetIntFromObj(interp, objv[i+1], &size) != TCL_OK) { goto error; } patternPtr->size = size; } else if (strcmp(key, "-weight") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, value); if (specPtr == NULL) { goto error; } patternPtr->weight = specPtr->oldvalue; } else if (strcmp(key, "-slant") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, value); if (specPtr == NULL) { goto error; } patternPtr->slant = specPtr->oldvalue; } else if (strcmp(key, "-spacing") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, spacingSpecs, nSpacingSpecs, value); if (specPtr == NULL) { goto error; } patternPtr->spacing = specPtr->oldvalue; } else if (strcmp(key, "-hint") == 0) { /* Ignore */ } else if (strcmp(key, "-rgba") == 0) { /* Ignore */ } else if (strcmp(key, "-underline") == 0) { /* Ignore */ } else if (strcmp(key, "-overstrike") == 0) { /* Ignore */ } else { /* Ignore */ } } #if DEBUG_FONT_SELECTION fprintf(stderr, "found TkAttrList => Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif return patternPtr; error: TkFreeFontPattern(patternPtr); return NULL; } /* *--------------------------------------------------------------------------- * * TkParseNameValuePairs -- * * Given the name of a Tk font object, get its configuration values * save the data in a font pattern structure. * * "-family family -size size -weight weight" * * Results: * Returns a pattern structure, filling in with the necessary fields. * Returns NULL if objv doesn't contain a valid name-value list * describing a font. * * Side effects: * Memory is allocated for the font pattern and the its strings. * *--------------------------------------------------------------------------- */ static TkFontPattern * TkParseFontObj(Tcl_Interp *interp, Tcl_Obj *objPtr) { TkFontPattern *patternPtr; Tcl_Obj *cmd[3]; int result; patternPtr = NULL; cmd[0] = Tcl_NewStringObj("font", -1); cmd[1] = Tcl_NewStringObj("configure", -1); cmd[2] = objPtr; Tcl_IncrRefCount(cmd[0]); Tcl_IncrRefCount(cmd[1]); Tcl_IncrRefCount(cmd[2]); result = Tcl_EvalObjv(interp, 3, cmd, 0); Tcl_DecrRefCount(cmd[2]); Tcl_DecrRefCount(cmd[1]); Tcl_DecrRefCount(cmd[0]); if (result == TCL_OK) { patternPtr = TkParseNameValuePairs(interp, Tcl_GetObjResult(interp)); } Tcl_ResetResult(interp); #if DEBUG_FONT_SELECTION if (patternPtr != NULL) { fprintf(stderr, "found FontObject => Tk font \"%s\"\n", Tcl_GetString(objPtr)); } #endif return patternPtr; } /* *--------------------------------------------------------------------------- * * TkGetPattern -- * * Parses the font description so that the font can rewritten with an * aliased font name. This allows us to use * * "Sans Serif", "Serif", "Math", "Monospace" * * font names that correspond to the proper font regardless if the * standard X fonts or XFT fonts are being used. * * Leave XLFD font descriptions alone. Let users describe exactly the * font they wish. * *--------------------------------------------------------------------------- */ static TkFontPattern * TkGetPattern(Tcl_Interp *interp, Tcl_Obj *objPtr) { TkFontPattern *patternPtr; char *desc; desc = Tcl_GetString(objPtr); while (isspace(*desc)) { desc++; /* Skip leading blanks. */ } if (*desc == '-') { /* * Case 1: XLFD font description or Tk attribute list. * * If the font description starts with a '-', it could be either an * old fashion XLFD font description or a Tk font attribute * option-value list. */ patternPtr = TkParseNameValuePairs(interp, objPtr); if (patternPtr == NULL) { return NULL; /* XLFD font description */ } } else if (*desc == '*') { return NULL; /* XLFD font description */ } else if (strpbrk(desc, "::") != NULL) { patternPtr = TkParseFontObj(interp, objPtr); } else { int objc; Tcl_Obj **objv; /* * Case 3: Tk-style description. */ if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split into a list or * list is empty. */ } patternPtr = NULL; if (objc == 1) { /* * Case 3a: Tk font object name. * * Assuming that Tk font object names won't contain whitespace, * see if its a font object. */ patternPtr = TkParseFontObj(interp, objv[0]); } if (patternPtr == NULL) { /* * Case 3b: List of font attributes in the form "family size * ?attrs?" */ patternPtr = TkParseTkDesc(interp, objc, objv); } } return patternPtr; } static void TkWriteXLFDDescription(Tk_Window tkwin, TkFontPattern *patternPtr, Tcl_DString *resultPtr) { const char *string; int size; /* Rewrite the font description using the aliased family. */ Tcl_DStringInit(resultPtr); /* Foundry */ Tcl_DStringAppend(resultPtr, "-*-", 3); /* Family */ string = (patternPtr->family != NULL) ? patternPtr->family : "*"; Tcl_DStringAppend(resultPtr, string, -1); Tcl_DStringAppend(resultPtr, "-", 1); /* Weight */ string = (patternPtr->weight == NULL) ? "*" : patternPtr->weight; Tcl_DStringAppend(resultPtr, string, -1); Tcl_DStringAppend(resultPtr, "-", 1); /* Slant */ string = (patternPtr->slant == NULL) ? "*" : patternPtr->slant; Tcl_DStringAppend(resultPtr, string, -1); Tcl_DStringAppend(resultPtr, "-", 1); /* Width */ string = (patternPtr->width == NULL) ? "*" : patternPtr->width; Tcl_DStringAppend(resultPtr, string, -1); /* Style */ Tcl_DStringAppend(resultPtr, "-*-", 3); /* Pixel size */ size = (int)(PointsToPixels(tkwin, patternPtr->size) + 0.5); string = (size == 0) ? "*" : Blt_Itoa(size); Tcl_DStringAppend(resultPtr, string, -1); /* Point size */ Tcl_DStringAppend(resultPtr, "-", 1); size = (int)(PixelsToPoints(tkwin, patternPtr->size) + 0.5); string = (size == 0) ? "*" : Blt_Itoa(size); Tcl_DStringAppend(resultPtr, string, -1); /* resx, resy */ Tcl_DStringAppend(resultPtr, "-*-*-", 5); /* Spacing */ string = (patternPtr->spacing == NULL) ? "*" : patternPtr->spacing; Tcl_DStringAppend(resultPtr, string, -1); /* Average Width, Registry, Encoding */ Tcl_DStringAppend(resultPtr, "-*-*-*-", 7); } /* *--------------------------------------------------------------------------- * * TkGetFontFromObj -- * * Opens a Tk font based on the description in the Tcl_Obj. We first * parse the description and if necessary rewrite it using the proper * font aliases. The font names * * "Sans Serif", "Serif", "Math", "Monospace" * * correspond to the proper font regardless if the standard X fonts or * XFT fonts are being used. * * Leave XLFD font descriptions alone. Let users describe exactly the * font they wish. * * Outside of reimplementing the Tk font mechanism, rewriting the * font allows use to better handle programs that must work with * X servers with and without the XRender extension. It means * that the widget's default font settings do not have to use * XLFD fonts even if XRender is available. * *--------------------------------------------------------------------------- */ static Tk_Font TkGetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { Tk_Font tkFont; TkFontPattern *patternPtr; if (!alias_initialized) { MakeAliasTable(tkwin); alias_initialized++; } patternPtr = TkGetPattern(interp, objPtr); if (patternPtr == NULL) { tkFont = Tk_GetFont(interp, tkwin, Tcl_GetString(objPtr)); } else { Tcl_DString ds; /* Rewrite the font description using the aliased family. */ TkWriteXLFDDescription(tkwin, patternPtr, &ds); tkFont = Tk_GetFont(interp, tkwin, Tcl_DStringValue(&ds)); #if DEBUG_FONT_SELECTION fprintf(stderr, "Tkfont: %s => %s\n", Tcl_GetString(objPtr), Tcl_DStringValue(&ds)); #endif Tcl_DStringFree(&ds); TkFreeFontPattern(patternPtr); } return tkFont; } static const char * TkNameOfFontProc(_Blt_Font *fontPtr) { return Tk_NameOfFont(fontPtr->clientData); } static const char * TkFamilyOfFontProc(_Blt_Font *fontPtr) { return ((TkFont *)fontPtr->clientData)->fa.family; } static Font TkFontIdProc(_Blt_Font *fontPtr) { return Tk_FontId(fontPtr->clientData); } static void TkGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr) { TkFont *tkFontPtr = fontPtr->clientData; Tk_FontMetrics fm; Tk_GetFontMetrics(fontPtr->clientData, &fm); fmPtr->ascent = fm.ascent; fmPtr->descent = fm.descent; fmPtr->linespace = fm.linespace; fmPtr->tabWidth = tkFontPtr->tabWidth; fmPtr->underlinePos = tkFontPtr->underlinePos; fmPtr->underlineHeight = tkFontPtr->underlineHeight; } static int TkMeasureCharsProc(_Blt_Font *fontPtr, const char *text, int nBytes, int max, int flags, int *lengthPtr) { return Tk_MeasureChars(fontPtr->clientData, text, nBytes, max, flags, lengthPtr); } static int TkTextStringWidthProc(_Blt_Font *fontPtr, const char *string, int nBytes) { return Tk_TextWidth(fontPtr->clientData, string, nBytes); } static void TkDrawCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing characters. */ _Blt_Font *fontPtr, /* Font in which characters will be drawn; * must be the same as font used in GC. */ int depth, /* Not used. */ float angle, /* Not used. */ const char *text, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that * is passed to this function. If they are * not stripped out, they will be displayed as * regular printing characters. */ int nBytes, /* Number of bytes in string. */ int x, int y) /* Coordinates at which to place origin of * string when drawing. */ { Tk_DrawChars(display, drawable, gc, fontPtr->clientData,text, nBytes, x, y); } static int TkPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr) { TkFont *tkFontPtr; unsigned int flags; tkFontPtr = (TkFont *)fontPtr->clientData; flags = 0; if (tkFontPtr->fa.slant != TK_FS_ROMAN) { flags |= FONT_ITALIC; } if (tkFontPtr->fa.weight != TK_FW_NORMAL) { flags |= FONT_BOLD; } Blt_Ps_FontName(tkFontPtr->fa.family, flags, resultPtr); return tkFontPtr->fa.size; } static int TkCanRotateFontProc(_Blt_Font *fontPtr, float angle) { return FALSE; } static void TkFreeFontProc(_Blt_Font *fontPtr) { Tk_FreeFont(fontPtr->clientData); Blt_Free(fontPtr); } /* *--------------------------------------------------------------------------- * * TkUnderlineCharsProc -- * * This procedure draws an underline for a given range of characters in a * given string. It doesn't draw the characters (which are assumed to * have been displayed previously); it just draws the underline. This * procedure would mainly be used to quickly underline a few characters * without having to construct an underlined font. To produce properly * underlined text, the appropriate underlined font should be constructed * and used. * * Results: * None. * * Side effects: * Information gets displayed in "drawable". * *--------------------------------------------------------------------------- */ static void TkUnderlineCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for actually drawing * line. */ _Blt_Font *fontPtr, /* Font used in GC; must have been * allocated by Tk_GetFont(). Used for * character dimensions, etc. */ const char *text, /* String containing characters to be * underlined or overstruck. */ int textLen, /* Unused. */ int x, int y, /* Coordinates at which first character of * string is drawn. */ int first, /* Byte offset of the first character. */ int last, /* Byte offset after the last character. */ int xMax) { Tk_UnderlineChars(display, drawable, gc, fontPtr->clientData, text, x, y, first, last); } #ifdef HAVE_LIBXFT #include <ft2build.h> #include FT_FREETYPE_H #include <X11/Xft/Xft.h> static Blt_NameOfFontProc FtNameOfFontProc; static Blt_FamilyOfFontProc FtFamilyOfFontProc; static Blt_FontIdProc FtFontIdProc; static Blt_GetFontMetricsProc FtGetFontMetricsProc; static Blt_MeasureCharsProc FtMeasureCharsProc; static Blt_TextStringWidthProc FtTextStringWidthProc; static Blt_FreeFontProc FtFreeFontProc; static Blt_DrawCharsProc FtDrawCharsProc; static Blt_PostscriptFontNameProc FtPostscriptFontNameProc; static Blt_CanRotateFontProc FtCanRotateFontProc; static Blt_UnderlineCharsProc FtUnderlineCharsProc; static Blt_FontClass ftFontClass = { FONT_FT, FtNameOfFontProc, /* Blt_NameOfFontProc */ FtFamilyOfFontProc, /* Blt_FamilyOfFontProc */ FtFontIdProc, /* Blt_FontIdProc */ FtGetFontMetricsProc, /* Blt_GetFontMetricsProc */ FtMeasureCharsProc, /* Blt_MeasureCharsProc */ FtTextStringWidthProc, /* Blt_TextStringWidthProc */ FtCanRotateFontProc, /* Blt_CanRotateFontProc */ FtDrawCharsProc, /* Blt_DrawCharsProc */ FtPostscriptFontNameProc, /* Blt_PostscriptFontNameProc */ FtFreeFontProc, /* Blt_FreeFontProc */ FtUnderlineCharsProc, /* Blt_UnderlineCharsProc */ }; /* * Freetype font container. */ typedef struct { char *name; /* Name of the font (malloc-ed). */ int refCount; /* Reference count for this structure. * When refCount reaches zero, it * means to free the resources * associated with this structure. */ Blt_HashEntry *hashPtr; /* Pointer to this entry in global * font hash table. Used to remove the * entry * from the table. */ Font fid; /* Font id used to fake out * Tk_FontId. */ FcPattern *pattern; /* Pattern matching the current * non-rotated font. Used to create * rotated fonts by duplicating the * pattern and adding a rotation * matrix. */ Blt_HashTable fontTable; /* Hash table containing an Xft font * for each angle it's used at. Will * always contain a 0 degree * entry. */ /* Information specific to the display/drawable being used. The drawables * are changed as the drawable changes for each drawing request. * Typically this will change for each pixmap. */ Drawable drawable; /* Drawable associated with draw. */ XftDraw *draw; /* Current Xft drawable. */ int drawDepth; /* Depth of current drawable. */ XftColor color; /* Color to be displayed. We don't * actually allocate this color, since * we assume it's been already * allocated by the standard Tk * procedures. */ /* Saved Information from the Tk_Window used to created the initial * font. */ Display *display; Visual *visual; int screenNum; Colormap colormap; int underlineHeight; /* Thickness of underline * rectangle. */ int underlinePos; /* Offset of underline. */ int tabWidth; } FtFont; static FontSpec rgbaSpecs[] = { { "bgr", 1, FC_RGBA, FC_RGBA_BGR, }, { "none", 1, FC_RGBA, FC_RGBA_NONE, }, { "rgb", 1, FC_RGBA, FC_RGBA_RGB, }, { "unknown", 1, FC_RGBA, FC_RGBA_UNKNOWN, }, { "vbgr", 2, FC_RGBA, FC_RGBA_VBGR, }, { "vrgb", 2, FC_RGBA, FC_RGBA_VRGB, }, }; static int nRgbaSpecs = sizeof(rgbaSpecs) / sizeof(FontSpec); static FontSpec hintSpecs[] = { { "full", 1, FC_HINT_STYLE, FC_HINT_FULL, }, { "medium", 1, FC_HINT_STYLE, FC_HINT_MEDIUM, }, { "none", 1, FC_HINT_STYLE, FC_HINT_NONE, }, { "slight", 1, FC_HINT_STYLE, FC_HINT_SLIGHT, }, }; static int nHintSpecs = sizeof(hintSpecs) / sizeof(FontSpec); static void FtGetFontFamilies(Tk_Window tkwin, Blt_HashTable *tablePtr) { XftFontSet *fsPtr; int i; fsPtr = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), (char*)NULL, /* pattern elements */ XFT_FAMILY, (char*)NULL); /* fields */ for (i = 0; i < fsPtr->nfont; i++) { FcResult result; FcChar8 *family; result = FcPatternGetString(fsPtr->fonts[i], FC_FAMILY, 0, &family); if (result == FcResultMatch) { int isNew; char *name; /* Family names must be all lower case in the hash table. */ name = Blt_AssertStrdup((const char *)family); strtolower(name); Blt_CreateHashEntry(tablePtr, name, &isNew); Blt_Free(name); } } XftFontSetDestroy(fsPtr); } /* *--------------------------------------------------------------------------- * * FtParseTkDesc -- * * Try to open a Xft font from an Tk style font description. * * Results: * Return value is TCL_ERROR if string was not a fully specified XLFD. * Otherwise, fills font attribute buffer with the values parsed from the * XLFD and returns TCL_OK. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static FcPattern * FtParseTkDesc(Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj **objv) { FcPattern *pattern; int i; const char *family; pattern = FcPatternCreate(); FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue); /* Font family. */ family = GetAlias(Tcl_GetString(objv[0])); FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)family); /* Size */ if (objc > 1) { int size; if (Tcl_GetIntFromObj(NULL, objv[1], &size) != TCL_OK) { goto error; } FcPatternAddDouble(pattern, FC_SIZE, PixelsToPoints(tkwin, size)); } i = 2; if (objc == 3) { if (Tcl_ListObjGetElements(interp, objv[2], &objc, &objv) != TCL_OK) { goto error; } i = 0; } for (/*empty*/; i < objc; i++) { FontSpec *specPtr; specPtr = FindSpec(interp, fontSpecs, nFontSpecs, Tcl_GetString(objv[i])); if (specPtr == NULL) { goto error; } if (specPtr->key != NULL) { FcPatternAddInteger(pattern, specPtr->key, specPtr->value); } } #if DEBUG_FONT_SELECTION fprintf(stderr, "parsed TkDesc-XFT font \"%s\"\n", Tcl_GetString(objv[0])); #endif return pattern; error: if (pattern != NULL) { FcPatternDestroy(pattern); } return NULL; } static FcPattern * FtParseTkFontAttributeList(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { FcPattern *pattern; Tcl_Obj **objv; int objc; int i; if ((Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split list or list is empty. */ } if (objc & 0x1) { if (interp != NULL) { Tcl_AppendResult(interp, "odd number of elements, missing value", (char *)NULL); } return NULL; /* Odd number of elements in list. */ } pattern = FcPatternCreate(); FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue); for (i = 0; i < objc; i += 2) { char *key, *value; key = Tcl_GetString(objv[i]); value = Tcl_GetString(objv[i+1]); if (strcmp(key, "-family") == 0) { const char *family; family = GetAlias(value); FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)family); } else if (strcmp(key, "-size") == 0) { int size; if (Tcl_GetIntFromObj(interp, objv[i+1], &size) != TCL_OK) { goto error; } FcPatternAddDouble(pattern, FC_SIZE, PixelsToPoints(tkwin, size)); } else if (strcmp(key, "-weight") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, value); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_WEIGHT, specPtr->value); } else if (strcmp(key, "-slant") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, value); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_SLANT, specPtr->value); } else if (strcmp(key, "-hint") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, hintSpecs, nHintSpecs, value); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_HINT_STYLE, specPtr->value); } else if (strcmp(key, "-rgba") == 0) { FontSpec *specPtr; specPtr = FindSpec(interp, rgbaSpecs, nRgbaSpecs, value); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_RGBA, specPtr->value); } else if (strcmp(key, "-underline") == 0) { /* Ignore */ } else if (strcmp(key, "-overstrike") == 0) { /* Ignore */ } else { if (interp != NULL) { Tcl_AppendResult(interp, "unknown switch \"", key, "\" in font description.", (char *)NULL); } goto error; } } #if DEBUG_FONT_SELECTION fprintf(stderr, "parsed TkAttrList-XFT font \"%s\"\n", Tcl_GetString(objPtr)); #endif return pattern; error: FcPatternDestroy(pattern); return NULL; } static FcPattern * FtGetAttributesFromFontObj(Tk_Window tkwin, Tcl_Interp *interp, Tcl_Obj *objPtr) { FcPattern *pattern; Tcl_Obj *cmd[3]; int result; cmd[0] = Tcl_NewStringObj("font", -1); cmd[1] = Tcl_NewStringObj("configure", -1); cmd[2] = objPtr; result = Blt_GlobalEvalObjv(interp, 3, cmd); if (result == TCL_OK) { pattern = FtParseTkFontAttributeList(interp, tkwin, Tcl_GetObjResult(interp)); } else { pattern = NULL; } Tcl_ResetResult(interp); #if DEBUG_FONT_SELECTION if (pattern != NULL) { fprintf(stderr, "found FontObject => XFT font \"%s\"\n", Tcl_GetString(objPtr)); } #endif return pattern; } /* *--------------------------------------------------------------------------- * * FtParseXLFD -- * * Try to open a Xft font from an XLFD description. * * Results: * Return value is TCL_ERROR if string was not a fully specified XLFD. * Otherwise, fills font attribute buffer with the values parsed from the * XLFD and returns TCL_OK. * * Side effects: * None. * *--------------------------------------------------------------------------- */ static FcPattern * FtParseXLFD(Tcl_Interp *interp, Tk_Window tkwin, char *fontName) { FcPattern *pattern; FontSpec *specPtr; int argc; char **argv; double size; if (fontName[0] == '-') { fontName++; } ParseXLFD(fontName, &argc, &argv); pattern = FcPatternCreate(); FcPatternAddBool(pattern, FC_ANTIALIAS, FcTrue); if (argv[XLFD_FOUNDRY] != NULL) { FcPatternAddString(pattern, FC_FOUNDRY, (const FcChar8 *)argv[XLFD_FOUNDRY]); } if (argv[XLFD_FAMILY] != NULL) { FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)argv[XLFD_FAMILY]); } if (argv[XLFD_WEIGHT] != NULL) { specPtr = FindSpec(interp, weightSpecs, nWeightSpecs, argv[XLFD_WEIGHT]); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_WEIGHT, specPtr->value); } if (argv[XLFD_SLANT] != NULL) { specPtr = FindSpec(interp, slantSpecs, nSlantSpecs, argv[XLFD_SLANT]); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_SLANT, specPtr->value); } if (argv[XLFD_SETWIDTH] != NULL) { specPtr = FindSpec(interp, widthSpecs, nWidthSpecs, argv[XLFD_SETWIDTH]); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_WIDTH, specPtr->value); } if (argv[XLFD_ADD_STYLE] != NULL) { FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *)argv[XLFD_ADD_STYLE]); } size = 12.0; if (argv[XLFD_PIXEL_SIZE] != NULL) { int value; if (argv[XLFD_PIXEL_SIZE][0] == '[') { /* * Some X fonts have the point size specified as follows: * * [ N1 N2 N3 N4 ] * * where N1 is the point size (in points, not decipoints!), and * N2, N3, and N4 are some additional numbers that I don't know * the purpose of, so I ignore them. */ value = atoi(argv[XLFD_PIXEL_SIZE]+1); } else if (Tcl_GetInt(NULL, argv[XLFD_PIXEL_SIZE], &value) == TCL_OK) { /* empty */ } else { goto error; } size = PixelsToPoints(tkwin, -value); } #ifndef notdef if (argv[XLFD_POINT_SIZE] != NULL) { int value; if (argv[XLFD_POINT_SIZE][0] == '[') { /* * Some X fonts have the point size specified as follows: * * [ N1 N2 N3 N4 ] * * where N1 is the point size (in points, not decipoints!), and * N2, N3, and N4 are some additional numbers that I don't know * the purpose of, so I ignore them. */ value = atoi(argv[XLFD_POINT_SIZE]+1); } else if (Tcl_GetInt(NULL, argv[XLFD_POINT_SIZE], &value) == TCL_OK) { /* empty */ } else { goto error; } size = PixelsToPoints(tkwin, -value) * 0.1; } #endif FcPatternAddDouble(pattern, FC_SIZE, (double)size); if (argv[XLFD_SPACING] != NULL) { specPtr = FindSpec(interp, spacingSpecs, nSpacingSpecs, argv[XLFD_SPACING]); if (specPtr == NULL) { goto error; } FcPatternAddInteger(pattern, FC_SPACING, specPtr->value); } #ifdef notdef if (argv[XLFD_CHARSET] != NULL) { FcPatternAddString(pattern, FC_CHARSET, (const FcChar8 *)argv[XLFD_CHARSET]); } else { FcPatternAddString(pattern, FC_CHARSET, (const FcChar8 *)"iso8859-1"); } #endif Blt_Free((char *)argv); #if DEBUG_FONT_SELECTION fprintf(stderr, "parsed Xlfd-XFT font \"%s\"\n", fontName); #endif return pattern; error: #if DEBUG_FONT_SELECTION fprintf(stderr, "can't open font \"%s\" as XLFD\n", fontName); #endif Blt_Free((char *)argv); FcPatternDestroy(pattern); return NULL; } static void FtDeleteFont(FtFont *ftPtr) { Blt_HashEntry *hPtr; Blt_HashSearch cursor; for (hPtr = Blt_FirstHashEntry(&ftPtr->fontTable, &cursor); hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) { XftFont *xftPtr; xftPtr = Blt_GetHashValue(hPtr); XftFontClose(ftPtr->display, xftPtr); } Blt_DeleteHashTable(&ftPtr->fontTable); if (ftPtr->name != NULL) { Blt_Free(ftPtr->name); } if (ftPtr->draw != 0) { XftDrawDestroy(ftPtr->draw); } if (ftPtr->fid) { XUnloadFont(ftPtr->display, ftPtr->fid); } Blt_DeleteHashEntry(&fontTable, ftPtr->hashPtr); Blt_Free(ftPtr); } static int FtMeasureChars(FtFont *ftPtr, const char *source, int nBytes, int maxLength, int flags, int *lengthPtr) { FcChar32 c; XGlyphInfo extents; int clen; int curX, newX; int termByte = 0, termX = 0; int curByte, newByte, sawNonSpace; #if 0 char string[256]; int len = 0; #endif XftFont *xftPtr; Blt_HashEntry *hPtr; hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)0L); if (hPtr == NULL) { return 0; } xftPtr = Blt_GetHashValue(hPtr); curX = 0; curByte = 0; sawNonSpace = 0; while (nBytes > 0) { Tcl_UniChar unichar; clen = Tcl_UtfToUniChar(source, &unichar); c = (FcChar32)unichar; if (clen <= 0) { /* This can't happen (but see #1185640) */ *lengthPtr = curX; return curByte; } source += clen; nBytes -= clen; if (c < 256 && isspace(c)) { /* I18N: ??? */ if (sawNonSpace) { termByte = curByte; termX = curX; sawNonSpace = 0; } } else { sawNonSpace = 1; } #if 0 string[len++] = (char) c; #endif XftTextExtents32(ftPtr->display, xftPtr, &c, 1, &extents); newX = curX + extents.xOff; newByte = curByte + clen; if (maxLength >= 0 && newX > maxLength) { if ((flags & TK_PARTIAL_OK) || ((flags & TK_AT_LEAST_ONE && curByte == 0))) { curX = newX; curByte = newByte; } else if ((flags & TK_WHOLE_WORDS) && (termX != 0)) { curX = termX; curByte = termByte; } break; } curX = newX; curByte = newByte; } #if 0 string[len] = '\0'; printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte); #endif *lengthPtr = curX; return curByte; } static void FtSetFontParams(Tk_Window tkwin, FtFont *ftPtr, XftFont *xftPtr) { FT_UInt glyph; XGlyphInfo metrics; double size; FcResult result; /* * Get information used for drawing underlines from the 0 angle font. */ glyph = XftCharIndex(ftPtr->display, xftPtr, '0'); XftGlyphExtents(ftPtr->display, xftPtr, &glyph, 1, &metrics); ftPtr->underlinePos = xftPtr->descent / 2; result = FcPatternGetDouble(xftPtr->pattern, FC_SIZE, 0, &size); if (result != FcResultMatch) { size = 12.0; } ftPtr->underlineHeight = (int)(PointsToPixels(tkwin,(int)size)/10.0 + 0.5); if (ftPtr->underlineHeight == 0) { ftPtr->underlineHeight = 1; } if ((ftPtr->underlinePos + ftPtr->underlineHeight) > xftPtr->descent) { /* * If this set of values would cause the bottom of the underline bar * to stick below the descent of the font, jack the underline up a bit * higher. */ ftPtr->underlineHeight = xftPtr->descent - ftPtr->underlinePos; if (ftPtr->underlineHeight == 0) { ftPtr->underlinePos--; ftPtr->underlineHeight = 1; } } FtMeasureChars(ftPtr, "0", 1, -1, 0, &ftPtr->tabWidth); if (ftPtr->tabWidth == 0) { ftPtr->tabWidth = xftPtr->max_advance_width; } ftPtr->tabWidth *= 8; /* * Make sure the tab width isn't zero (some fonts may not have enough * information to set a reasonable tab width). */ if (ftPtr->tabWidth == 0) { ftPtr->tabWidth = 1; } } static FtFont * FtNewFont(Tcl_Interp *interp, Tk_Window tkwin, const char *fontName, XftFont *xftPtr) { Blt_HashEntry *hPtr; FtFont *ftPtr; int isNew; ftPtr = Blt_AssertCalloc(1, sizeof(FtFont)); ftPtr->name = Blt_AssertStrdup(fontName); ftPtr->visual = Tk_Visual(tkwin); ftPtr->colormap = Tk_Colormap(tkwin); ftPtr->display = Tk_Display(tkwin); ftPtr->fid = XLoadFont(Tk_Display(tkwin), "fixed"); ftPtr->color.pixel = 0xFFFFFFFF; ftPtr->pattern = xftPtr->pattern; ftPtr->refCount = 1; /* * Initialize the Xft font table for this font. Add the initial Xft font * for the case of 0 degrees rotation. */ Blt_InitHashTable(&ftPtr->fontTable, BLT_ONE_WORD_KEYS); hPtr = Blt_CreateHashEntry(&ftPtr->fontTable, (char *)0L, &isNew); assert(isNew); Blt_SetHashValue(hPtr, xftPtr); #ifdef notdef /* Try to use the Freetype routine FT_Get_Postscript_Name. If this fails, * build a string from the various fields of the font. */ { FT_Face face; const char *string; face = XftLockFace(xftPtr); string = FT_Get_Postscript_Name(face); XftUnlockFace(xftPtr); if (string != NULL) { fprintf(stderr, "%s: psfont=(%s)\n", fontName, string); } } #endif /* Add the font information to the font table. */ hPtr = Blt_CreateHashEntry(&fontTable, fontName, &isNew); assert(isNew); Blt_SetHashValue(hPtr, ftPtr); ftPtr->hashPtr = hPtr; FtSetFontParams(tkwin, ftPtr, xftPtr); return ftPtr; } /* * FtGetPattern -- * * Generates an pattern based upon the font description provided. The * description is parsed base upon Tk's font selection rules (listed * below). * * Tk's Font Selection Rules: * * When font description font is used, the system attempts to parse the * description according to each of the above five rules, in the order * specified. Cases [1] and [2] must match the name of an existing named * font or of a system font. Cases [3], [4], and [5] are accepted on all * platforms and the closest available font will be used. In some * situations it may not be possible to find any close font (e.g., the * font family was a garbage value); in that case, some system-dependant * default font is chosen. If the font description does not match any of * the above patterns, an error is generated. * * [1] fontname * The name of a named font, created using the font create command. When * a widget uses a named font, it is guaranteed that this will never * cause an error, as long as the named font exists, no mat- ter what * potentially invalid or meaningless set of attributes the named font * has. If the named font cannot be displayed with exactly the specified * attributes, some other close font will be substituted automatically. * * [Query the named font (using "font configure") and generate an Xft * font with the same attributes. It's assumed that these names don't * start with a '*' or '-'.] * * [2] systemfont * The platform-specific name of a font, interpreted by the graphics * server. This also includes, under X, an XLFD (see [4]) for which a * single ``*'' character was used to elide more than one field in the * middle of the name. See PLATFORM-SPECIFIC issues for a list of the * system fonts. * * [Same as above. Query the named font (using "font configure") and * generate an Xft font with the same attributes.] * * [3] family ?size? ?style? ?style ...? * A properly formed list whose first element is the desired font family * and whose optional second element is the desired size. The * interpretation of the size attribute follows the same rules described * for -size in FONT OPTIONS below. Any additional optional arguments * following the size are font styles. Possible values for the style * arguments are as follows: * * normal, bold, roman, italic, underline, overstrike * * [Parse the list of attributes and generate a corresponding Xft font.] * * [4] X-font names (XLFD) * A Unix-centric font name of the form -foundry-family-weight * slant-setwidth-addstyle-pixel-point-resx-resy-spacing-width * charset-encoding. The ``*'' character may be used to skip indi vidual * fields that the user does not care about. There must be exactly one * ``*'' for each field skipped, except that a ``*'' at the end of the * XLFD skips any remaining fields; the shortest valid XLFD is simply * ``*'', signifying all fields as defaults. Any fields that were * skipped are given default values. For compatibility, an XLFD always * chooses a font of the specified pixel size (not point size); although * this interpretation is not strictly correct, all existing applications * using XLFDs assumed that one ``point'' was in fact one pixel and would * display incorrectly (generally larger) if the correct size font were * actually used. * * [Parse the font description and generate a corresponding Xft font.] * * [5] option value ?option value ...? * A properly formed list of option-value pairs that specify the desired * attributes of the font, in the same format used when defining a named * font. * * [Parse the option-value list and generate a corresponding Xft font.] * * Extra: * [6] Xft font description. * * [Handle the newer Xft font descriptions.] */ static FcPattern * FtGetPattern(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { FcPattern *pattern; char *desc; desc = Tcl_GetString(objPtr); while (isspace(*desc)) { desc++; /* Skip leading blanks. */ } if (*desc == '-') { /* * Case 1: XLFD font description or Tk attribute list. * * If the font description starts with a '-', it could be either an * old fashion XLFD font description or a Tk font attribute * option-value list. */ pattern = FtParseTkFontAttributeList(NULL, tkwin, objPtr); if (pattern == NULL) { /* Try parsing it as an XLFD font description. */ pattern = FtParseXLFD(interp, tkwin, desc); } } else if (*desc == '*') { pattern = FtParseXLFD(interp, tkwin, desc); } else if (strpbrk(desc, ":,=") != NULL) { /* * Case 2: XFT font description. * * If the font description contains a ':', '=', or ',' in it, we * assume it's a new XFT font description. We want to allow these * font descriptions too. */ pattern = NULL; if (strstr(desc, "::") != NULL) { pattern = FtGetAttributesFromFontObj(tkwin, interp, objPtr); } if (pattern == NULL) { pattern = FcNameParse((const FcChar8 *)desc); } #if DEBUG_FONT_SELECTION if (pattern != NULL) { fprintf(stderr, "found XFT => XFT font \"%s\"\n", desc); } #endif } else { int objc; Tcl_Obj **objv; /* * Case 3: Tk-style description. */ if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { return NULL; /* Can't split into a list or list is * empty. */ } if (objc == 1) { /* * Case 3a: Tk font object name. * * Assuming that Tk font object names won't contain whitespace, * see if its a font object. */ pattern = FtGetAttributesFromFontObj(tkwin, interp, objv[0]); if (pattern == NULL) { pattern = FcNameParse((const FcChar8 *)desc); #if DEBUG_FONT_SELECTION if (pattern != NULL) { fprintf(stderr, "found XFT => XFT font \"%s\"\n", desc); } #endif } } else { /* * Case 3b: List of font attributes in the form "family size * ?attrs?" */ pattern = FtParseTkDesc(interp, tkwin, objc, objv); } } return pattern; } static FcPattern * FtGetFontPattern(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { FcPattern *pattern; pattern = FtGetPattern(interp, tkwin, objPtr); if (pattern != NULL) { FcPattern *match; FcResult result; /* * XftFontMatch only sets *result* on complete match failures. So * initialize it here for a successful match. We'll accept partial * matches. */ result = FcResultMatch; match = XftFontMatch(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern, &result); #if DEBUG_FONT_SELECTION if (match != NULL) { FcChar8 *name; name = FcNameUnparse(pattern); fprintf(stderr, "\nfont=%s\n", Tcl_GetString(objPtr)); fprintf(stderr, "original spec was %s\n", name); free(name); name = FcNameUnparse(match); fprintf(stderr, "matching spec is %s\n", name); free(name); } #endif FcPatternDestroy(pattern); if ((match != NULL) && (result == FcResultMatch)) { return match; } } #if DEBUG_FONT_SELECTION fprintf(stderr, "can't open font pattern \"%s\"\n", Tcl_GetString(objPtr)); #endif return NULL; } static XftFont * FtOpenFont(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { FcPattern *pattern; pattern = FtGetFontPattern(interp, tkwin, objPtr); if (pattern != NULL) { return XftFontOpenPattern(Tk_Display(tkwin), pattern); } return NULL; } static FtFont * FtGetFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { Blt_HashEntry *hPtr; char *desc; desc = Tcl_GetString(objPtr); while (isspace(*desc)) { desc++; /* Skip leading blanks. */ } /* Is the font already in the cache? */ hPtr = Blt_FindHashEntry(&fontTable, desc); if (hPtr != NULL) { FtFont *ftPtr; ftPtr = Tcl_GetHashValue(hPtr); ftPtr->refCount++; return ftPtr; } else { XftFont *xftPtr; xftPtr = FtOpenFont(interp, tkwin, objPtr); if (xftPtr != NULL) { return FtNewFont(interp, tkwin, desc, xftPtr); } } return NULL; } const char * Blt_GetFontFileFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *sizePtr) { Tk_Window tkwin; FcResult result; FcChar8 *fileName; FcPattern *pattern; double size; tkwin = Tk_MainWindow(interp); if (!alias_initialized) { MakeAliasTable(tkwin); alias_initialized++; } if (!IsXRenderAvailable(tkwin)) { Tcl_AppendResult(interp, "can't open Xft font: ", "X server doesn't support XRENDER extension", (char *)NULL); return NULL; } pattern = FtGetFontPattern(interp, tkwin, objPtr); if (pattern == NULL) { return NULL; } result = FcPatternGetDouble(pattern, FC_SIZE, 0, &size); if (result != FcResultMatch) { size = 12.0; } result = FcPatternGetString(pattern, FC_FILE, 0, &fileName); FcPatternDestroy(pattern); if (result != FcResultMatch) { return NULL; } *sizePtr = size; return (const char *)fileName; } const char * Blt_GetFontFile(Tcl_Interp *interp, const char *fontName, double *sizePtr) { Tcl_Obj *objPtr; const char *fileName; objPtr = Tcl_NewStringObj(fontName, strlen(fontName)); Tcl_IncrRefCount(objPtr); fileName = Blt_GetFontFileFromObj(interp, objPtr, sizePtr); Tcl_DecrRefCount(objPtr); return fileName; } static const char * FtNameOfFontProc(_Blt_Font *fontPtr) { FtFont *ftPtr = fontPtr->clientData; return ftPtr->name; } static const char * FtFamilyOfFontProc(_Blt_Font *fontPtr) { FtFont *ftPtr = fontPtr->clientData; FcChar8 *string; FcResult result; result = FcPatternGetString(ftPtr->pattern, FC_FAMILY, 0, &string); if (result == FcResultMatch) { return (const char *)string; } return NULL; } static Font FtFontIdProc(_Blt_Font *fontPtr) { FtFont *ftPtr = fontPtr->clientData; return ftPtr->fid; } static void FtGetFontMetricsProc(_Blt_Font *fontPtr, Blt_FontMetrics *mPtr) { FtFont *ftPtr = fontPtr->clientData; Blt_HashEntry *hPtr; /* Always take font metrics from the non-rotated font. */ hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)0L); if (hPtr != NULL) { FT_UInt glyph; XGlyphInfo metrics; XftFont *xftPtr; xftPtr = Blt_GetHashValue(hPtr); glyph = XftCharIndex(ftPtr->display, xftPtr, '0'); XftGlyphExtents(ftPtr->display, xftPtr, &glyph, 1, &metrics); mPtr->ascent = xftPtr->ascent; mPtr->descent = xftPtr->descent; mPtr->linespace = mPtr->ascent + mPtr->descent; mPtr->tabWidth = ftPtr->tabWidth; mPtr->underlinePos = ftPtr->underlinePos; mPtr->underlineHeight = ftPtr->underlineHeight; } } static int FtMeasureCharsProc( _Blt_Font *fontPtr, const char *source, int nBytes, int maxLength, int flags, int *lengthPtr) { FtFont *ftPtr = fontPtr->clientData; return FtMeasureChars(ftPtr, source, nBytes, maxLength, flags, lengthPtr); } static int FtTextStringWidthProc(Blt_Font font, const char *string, int nBytes) { int width; FtMeasureCharsProc(font, string, nBytes, -1, 0, &width); return width; } /* *--------------------------------------------------------------------------- * * FtPostscriptFontNameProc -- * * Given a Xft font, return the name of the corresponding Postscript * font. * * Results: * The return value is the pointsize of the given Xft font. The name of * the Postscript font is appended to dsPtr. * * Side effects: * If the font does not exist on the printer, the print job will fail at * print time. Given a "reasonable" Postscript printer, the following * Tk_Font font families should print correctly: * * Avant Garde, Arial, Bookman, Courier, Courier New, Geneva, * Helvetica, Monaco, New Century Schoolbook, New York, Palatino, * Symbol, Times, Times New Roman, Zapf Chancery, and Zapf Dingbats. * * Any other Xft font families may not print correctly because the * computed Postscript font name may be incorrect. * *--------------------------------------------------------------------------- */ static int FtPostscriptFontNameProc(_Blt_Font *fontPtr, Tcl_DString *resultPtr) { FtFont *ftPtr = fontPtr->clientData; FcChar8 *string; const char *family; FcResult result; int weight, slant; double size; int flags; result = FcPatternGetString(ftPtr->pattern, FC_FAMILY, 0, &string); family = (result == FcResultMatch) ? (const char *)string : "Unknown"; result = FcPatternGetInteger(ftPtr->pattern, FC_WEIGHT, 0, &weight); if (result != FcResultMatch) { weight = FC_WEIGHT_MEDIUM; } result = FcPatternGetInteger(ftPtr->pattern, FC_SLANT, 0, &slant); if (result != FcResultMatch) { slant = FC_SLANT_ROMAN; } flags = 0; if (weight > FC_WEIGHT_MEDIUM) { flags |= FONT_BOLD; } if (slant > FC_SLANT_ROMAN) { flags |= FONT_ITALIC; } Blt_Ps_FontName(family, flags, resultPtr); result = FcPatternGetDouble(ftPtr->pattern, FC_SIZE, 0, &size); if (result != FcResultMatch) { size = 12.0; } return (int)size; } /* *--------------------------------------------------------------------------- * * FtUnderlineCharsProc -- * * This procedure draws an underline for a given range of characters in a * given string. It doesn't draw the characters (which are assumed to * have been displayed previously); it just draws the underline. This * procedure would mainly be used to quickly underline a few characters * without having to construct an underlined font. To produce properly * underlined text, the appropriate underlined font should be constructed * and used. * * Results: * None. * * Side effects: * Information gets displayed in "drawable". * *--------------------------------------------------------------------------- */ static void FtUnderlineCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to * draw. */ GC gc, /* Graphics context for actually * drawing line. */ _Blt_Font *fontPtr, const char *text, /* String containing characters to be * underlined or overstruck. */ int textLen, int x, int y, /* Coordinates at which first * character of string is drawn. */ int first, /* Index of first byte of first * character. */ int last, /* Index of first byte after the last * character. */ int maxLength) { int elWidth; const char *s, *send; FtFont *ftPtr = fontPtr->clientData; int firstX, lastX, clipX; int nBytes; int accum, threshold, index, next; int clipped; /* Compute the width of an ellipsis and verify that we're not bigger * than it. */ elWidth = Blt_TextWidth(fontPtr, "...", 3); if (maxLength < 0) { maxLength = threshold = 10000; } else { threshold = maxLength - elWidth; } #if !HAVE_UTF nBytes = 1; #endif /* !HAVE_UTF */ /* Compute the length of the string, stopping when we've surpassed our * threshold. Also save the first and last coordinates of the substring to * be underlined. */ clipX = lastX = -1, firstX = 0; accum = next = 0; clipped = FALSE; for (index = 0, s = text, send = s + textLen; s < send; s += nBytes, index++, accum += next) { #if HAVE_UTF Tcl_UniChar ch; #endif /* HAVE_UTF */ if (index == first) { firstX = accum; } if (index == last) { lastX = accum; break; } #if HAVE_UTF nBytes = Tcl_UtfToUniChar(s, &ch); #endif /* HAVE_UTF */ next = Blt_TextWidth(fontPtr, s, nBytes); if ((next + accum) <= threshold) { clipX = accum + next; /* Remember the last length where text * plus the ellipsis fit */ } if ((next + accum) > maxLength) { clipped = TRUE; break; } } if (lastX < 0) { lastX = accum; } if (clipped) { if ((s < send) && (accum < elWidth)) { return; /* Not enough room for "..." */ } lastX = clipX + elWidth; } x += firstX; y += ftPtr->underlinePos + 1; XFillRectangle(display, drawable, gc, x, y, (unsigned int)(lastX - firstX), (unsigned int)ftPtr->underlineHeight); } static int FtCanRotateFontProc(_Blt_Font *fontPtr, float angle) { FcPattern *pattern; FcResult result; FtFont *ftPtr = fontPtr->clientData; int boolean; long angle10; angle10 = (long)((double)angle * 10.0); if (Blt_FindHashEntry(&ftPtr->fontTable, (char *)angle10) != NULL) { return TRUE; /* Rotated font already exists. */ } /* * I don't know if this is correct. Some PCF fonts don't rotate properly. * The chararcter positions are rotated but the glyph itself is drawn with * no rotation. The standard Adobe Helvetica font is a good example of * this. So I need to bail on those fonts. I check if scalable=True in * the Xft font pattern to determine if the font will rotate properly. */ result = FcPatternGetBool(ftPtr->pattern, FC_SCALABLE, 0, &boolean); if ((result == FcResultMatch) && (!boolean)) { return FALSE; } { XftMatrix matrix; double cosTheta, sinTheta, theta; theta = ((double)angle / 180.0) * M_PI; sinTheta = sin(theta); cosTheta = cos(theta); XftMatrixInit(&matrix); XftMatrixRotate(&matrix, cosTheta, sinTheta); pattern = FcPatternDuplicate(ftPtr->pattern); FcPatternAddMatrix(pattern, FC_MATRIX, &matrix); } { FcResult result; FcPattern *match; /* * XftFontMatch only sets *result* on complete match failures. So * initialize it here for a successful match. We'll accept partial * matches. */ result = FcResultMatch; match = XftFontMatch(ftPtr->display, ftPtr->screenNum, pattern,&result); if ((match != NULL) && (result == FcResultMatch)) { XftFont *xftPtr; xftPtr = XftFontOpenPattern(ftPtr->display, match); /* Add the new rotated font to the hash table. */ if (xftPtr != NULL) { Blt_HashEntry *hPtr; int isNew; hPtr = Blt_CreateHashEntry(&ftPtr->fontTable, (char *)angle10, &isNew); assert(isNew); Blt_SetHashValue(hPtr, xftPtr); FcPatternDestroy(pattern); return TRUE; } } FcPatternDestroy(pattern); } return FALSE; } static void FtDrawCharsProc( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ GC gc, /* Graphics context for drawing * characters. */ _Blt_Font *fontPtr, /* Font in which characters will be * drawn; must be the same as font * used in *GC. */ int depth, float angle, const char *source, /* UTF-8 string to be displayed. Need * not be '\0' terminated. All Tk * meta-characters (tabs, control * characters, and newlines) should be * stripped out of the string that is * passed to this function. If they * are not stripped out, they will be * displayed as regular printing * characters. */ int nBytes, /* # of bytes in string. */ int x, int y) /* Coordinates at which to place * origin of string when drawing. */ { XftFont *xftPtr; FtFont *ftPtr = fontPtr->clientData; Blt_HashEntry *hPtr; long angle10; angle10 = (long)(angle * 10.0); hPtr = Blt_FindHashEntry(&ftPtr->fontTable, (char *)angle10); if (hPtr == NULL) { fprintf(stderr, "can't find font %s rotated at %g degrees\n", ftPtr->name, angle); return; /* Can't find instance at requested angle. */ } xftPtr = Blt_GetHashValue(hPtr); if ((ftPtr->draw == 0) || (ftPtr->drawDepth != depth)) { XftDraw *draw; if (depth == 1) { draw = XftDrawCreateBitmap(display, drawable); } else { draw = XftDrawCreate(display, drawable, ftPtr->visual, ftPtr->colormap); } if (ftPtr->draw != 0) { XftDrawDestroy(ftPtr->draw); } ftPtr->drawDepth = depth; ftPtr->draw = draw; ftPtr->drawable = drawable; } else { Tk_ErrorHandler handler; #if 0 printf("Switch to drawable 0x%x\n", drawable); #endif handler = Tk_CreateErrorHandler(display, -1, -1, -1, (Tk_ErrorProc *)NULL, (ClientData) NULL); XftDrawChange(ftPtr->draw, drawable); ftPtr->drawable = drawable; Tk_DeleteErrorHandler(handler); } { XGCValues values; XGetGCValues(display, gc, GCForeground, &values); if (values.foreground != ftPtr->color.pixel) { XColor xc; xc.pixel = values.foreground; XQueryColor(display, ftPtr->colormap, &xc); ftPtr->color.color.red = xc.red; ftPtr->color.color.green = xc.green; ftPtr->color.color.blue = xc.blue; ftPtr->color.color.alpha = 0xffff; /* Assume opaque. */ ftPtr->color.pixel = values.foreground; } } { #define NUM_SPEC 1024 XftGlyphFontSpec *specPtr; XftGlyphFontSpec specs[NUM_SPEC+1]; int nSpecs; const int maxCoord = 0x7FFF; /* Xft coordinates are 16 bit values */ nSpecs = 0; specPtr = specs; while ((nBytes > 0) && (x <= maxCoord) && (y <= maxCoord)) { XftChar32 c; int charLen; XGlyphInfo metrics; charLen = XftUtf8ToUcs4((XftChar8 *)source, &c, nBytes); if (charLen <= 0) { /* This should not happen, but it can. */ return; } source += charLen; nBytes -= charLen; specPtr = specs + nSpecs; specPtr->font = xftPtr; specPtr->glyph = XftCharIndex(display, xftPtr, c); specPtr->x = x; specPtr->y = y; XftGlyphExtents(display, xftPtr, &specPtr->glyph, 1, &metrics); x += metrics.xOff; y += metrics.yOff; nSpecs++, specPtr++; if (nSpecs == NUM_SPEC) { XftDrawGlyphFontSpec(ftPtr->draw, &ftPtr->color, specs, nSpecs); nSpecs = 0; specPtr = specs; } } if (nSpecs > 0) { XftDrawGlyphFontSpec(ftPtr->draw, &ftPtr->color, specs, nSpecs); } } } static void FtFreeFontProc(_Blt_Font *fontPtr) { FtFont *ftPtr = fontPtr->clientData; ftPtr->refCount--; if (ftPtr->refCount <= 0) { FtDeleteFont(ftPtr); } Blt_Free(fontPtr); } #endif /* HAVE_LIBXFT */ /* *--------------------------------------------------------------------------- * * Blt_GetFontFromObj -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: * The return value is token for the font, or NULL if an error prevented * the font from being created. If NULL is returned, an error message * will be left in the interp's result. * * Side effects: * The font is added to an internal database with a reference count. For * each call to this procedure, there should eventually be a call to * Tk_FreeFont() or Tk_FreeFontFromObj() so that the database is cleaned * up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ Blt_Font Blt_GetFontFromObj( Tcl_Interp *interp, /* Interp for database and error * return. */ Tk_Window tkwin, /* For display on which font will be * used. */ Tcl_Obj *objPtr) /* String describing font, as: named * font, native format, or parseable * string. */ { _Blt_Font *fontPtr; fontPtr = Blt_Calloc(1, sizeof(_Blt_Font)); if (fontPtr == NULL) { return NULL; /* Out of memory. */ } if (!alias_initialized) { MakeAliasTable(tkwin); alias_initialized++; } #ifdef HAVE_LIBXFT if (IsXRenderAvailable(tkwin)) { FtFont *ftPtr; /* Check first if we open the specified font as an XFT font. */ ftPtr = FtGetFontFromObj(interp, tkwin, objPtr); if (ftPtr != NULL) { fontPtr->classPtr = &ftFontClass; fontPtr->clientData = ftPtr; fontPtr->interp = interp; fontPtr->display = Tk_Display(tkwin); #if DEBUG_FONT_SELECTION2 fprintf(stderr, "SUCCESS: Found XFT font \"%s\"\n", Tcl_GetString(objPtr)); #endif return fontPtr; /* Found Xft font. */ } /* Otherwise fall thru and try to open font as a normal Tk font. */ } #endif /* HAVE_LIBXFT */ fontPtr->clientData = TkGetFontFromObj(interp, tkwin, objPtr); if (fontPtr->clientData == NULL) { Blt_Free(fontPtr); #if DEBUG_FONT_SELECTION fprintf(stderr, "FAILED to find either Xft or Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif return NULL; /* Failed to find either Xft or Tk * fonts. */ } #if DEBUG_FONT_SELECTION fprintf(stderr, "SUCCESS: Found Tk font \"%s\"\n", Tcl_GetString(objPtr)); #endif fontPtr->classPtr = &tkFontClass; fontPtr->interp = interp; fontPtr->display = Tk_Display(tkwin); return fontPtr; /* Found Tk font. */ } Blt_Font Blt_AllocFontFromObj( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For screen on which font will be used. */ Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { return Blt_GetFontFromObj(interp, tkwin, objPtr); } /* *--------------------------------------------------------------------------- * * Blt_GetFont -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: * The return value is token for the font, or NULL if an error prevented * the font from being created. If NULL is returned, an error message * will be left in interp's result object. * * Side effects: * The font is added to an internal database with a reference count. For * each call to this procedure, there should eventually be a call to * Blt_FreeFont so that the database is cleaned up when fonts aren't in * use anymore. * *--------------------------------------------------------------------------- */ Blt_Font Blt_GetFont( Tcl_Interp *interp, /* Interp for database and error return. */ Tk_Window tkwin, /* For screen on which font will be used. */ const char *string) /* Object describing font, as: named font, * native format, or parseable string. */ { Blt_Font font; Tcl_Obj *objPtr; objPtr = Tcl_NewStringObj(string, strlen(string)); Tcl_IncrRefCount(objPtr); font = Blt_GetFontFromObj(interp, tkwin, objPtr); Tcl_DecrRefCount(objPtr); return font; } Tcl_Interp * Blt_GetFontInterp(_Blt_Font *fontPtr) { return fontPtr->interp; } int Blt_TextWidth(_Blt_Font *fontPtr, const char *string, int length) { if (Blt_Ps_IsPrinting()) { int width; width = Blt_Ps_TextWidth(fontPtr, string, length); if (width >= 0) { return width; } } return (*fontPtr->classPtr->textWidth)(fontPtr, string, length); } void Blt_GetFontMetrics(_Blt_Font *fontPtr, Blt_FontMetrics *fmPtr) { if (Blt_Ps_IsPrinting()) { if (Blt_Ps_GetFontMetrics(fontPtr, fmPtr) == TCL_OK) { return; } } return (*fontPtr->classPtr->getFontMetrics)(fontPtr, fmPtr); } #ifdef notdef static Blt_FontClass psFontClass = { FONT_PS, PsNameOfFontProc, /* Blt_NameOfFontProc */ PsFamilyOfFontProc, /* Blt_FamilyOfFontProc */ NULL, /* Blt_FontIdProc */ PsGetFontMetricsProc, /* Blt_GetFontMetricsProc */ PsMeasureCharsProc, /* Blt_MeasureCharsProc */ PsTextWidthProc, /* Blt_TextWidthProc */ NULL, /* Blt_CanRotateFontProc */ NULL, /* Blt_DrawCharsProc */ PsPostscriptFontNameProc, /* Blt_PostscriptFontNameProc */ PsFreeFontProc, /* Blt_FreeFontProc */ NULL, /* Blt_UnderlineCharsProc */ }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/INSTALL���������������������������������������������������������������������������0000644�0001750�0001750�00000006357�11462120062�013302� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This file describes how to compile and install the BLT library for UNIX. [See the file ./win/README for details on how to build under Win32.] 1. Uncompress and untar the distribution file. zcat BLT3.0.tar.gz | tar -xvf - This will create a directory "blt3.0" with the following subdirectories: blt3.0 ______________|_____________________________ | | | | | | | demos examples html library man src win | | | scripts shared X11 2. Run ./configure Go into the "blt3.0" directory cd blt3.0 and run the auto-configuration script "./configure". Tell where to find the Tcl and Tk header files and libraries with the "--with-tcl" switch. ./configure --with-tcl=/util/lang/tcl Switches: --prefix=path Specifies the path where "bltwish", the BLT header files, libraries, scripts, and manual pages are installed. The default is "/usr/local/blt". This switch also indicates where to find the Tcl/Tk header files and libraries. You can use the --with-tcl and --with-tk switches to override this value if the location of the Tcl/Tk files is different. --with-tcl=dir Directory where Tcl and/or Tk is installed. --with-tk=dir Directory where Tk is installed if different from "--with-tcl". --with-cc=program Lets you specify the C compiler, such as "acc" or "gcc". The configure script creates a header file "src/bltConfig.h". It will also generate new Makefiles from their respective templates (Makefile.in). Makefile.in ==> Makefile src/Makefile.in ==> src/Makefile src/shared/Makefile.in ==> src/shared/Makefile man/Makefile.in ==> man/Makefile library/Makefile.in ==> library/Makefile 3. Compile the libraries and build the demonstration program "bltwish". make The program "bltwish" will be created in the ./src directory. 4. Test by running the demos. Go into the demos directory cd demos and run the test scripts. ./graph1.tcl If your system doesn't support "#!" in shell scripts, then it's ../src/bltwish ./graph1.tcl 5. Installing BLT make install The following directories will be created when BLT is installed. By default, the top directory is /usr/local/blt. ___________|__________ | | | | bin include lib man | blt3.0 ____|____ | | demos dd_protocols You can change the top directory by supplying the "--prefix=dir" switch to ./configure. *6. (Optional) Compiling BLT into your own custom "wish". [If your version of "wish" supports dynamic loading of packages you can simply add package require BLT to the start of your script.] Add the following lines to your program's Tcl_AppInit routine in tkAppInit.c if (Blt_Init(interp) != TCL_OK) { return TCL_ERROR; } then link with libBLT.a. And that's all there's to it. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/configure�������������������������������������������������������������������������0000755�0001750�0001750�00001720543�11504210773�014167� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 </dev/null 6>&1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/bltInit.c" # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef STDC_HEADERS # include <stdlib.h> # include <stddef.h> #else # ifdef HAVE_STDLIB_H # include <stdlib.h> # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include <memory.h> # endif # include <string.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os ac_prefix_program CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP AWK INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB LN_S GREP EGREP SIZEOF_INT SIZEOF_LONG SIZEOF_LONG_LONG SIZEOF_VOID_P SIZEOF_FLOAT XMKMF HAVE_INTTYPES_H BLT_SO_CFLAGS BLT_TARGET BLT_SO_LD BLT_SO_LDFLAGS BLT_SO_LIBS BLT_SO_EXT LD_RUN_PATH BLT_SO_PREFIX BLT_LIB_SUFFIX IMPLIB_PREFIX IMPLIB_EXT TCL_STUBS_SPEC TK_STUBS_SPEC WIN32 AUX_LIBS BLT_MAJOR_VERSION BLT_MINOR_VERSION BLT_VERSION DEFINES DLL_PREFIX EXPAT_INC_SPEC EXPAT_LIB_SPEC EXTRA_LIBS FT2_INC_SPEC FT2_LIB_SPEC FTCFG_LIB_SPEC GCCFLAGS INCLUDES JPG_INC_SPEC JPG_LIB_SPEC LIB_PREFIX LIB_SUFFIX MYSQL_INC_SPEC MYSQL_LIB_SPEC PNG_INC_SPEC PNG_LIB_SPEC TCL_DBGX TCL_INC_SPEC TCL_LIB_DIR TCL_LIB_SPEC TCL_VERSION TIF_INC_SPEC TIF_LIB_SPEC TK_INC_SPEC TK_LIB_SPEC TK_XLIBSW X11_INC_SPEC X11_LIB_SPEC XAU_LIB_SPEC XDMCP_LIB_SPEC XFT_INC_SPEC XFT_LIB_SPEC XPM_INC_SPEC XPM_LIB_SPEC XRANDR_LIB_SPEC XRENDER_LIB_SPEC Z_LIB_SPEC BLT_LIBRARY LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared created shared libraries --enable-symbols compile with debugging symbols --enable-stubs compile with stubbed version of Tcl library Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-blt=DIR install BLT scripts in DIR --with-tcl=DIR find tclConfig.sh in DIR --with-tk=DIR find tkConfig.sh in DIR --with-tclincdir=DIR find Tcl includes in DIR --with-tkincdir=DIR find Tk includes in DIR --with-tcllibdir=DIR find Tcl libraries in DIR --with-tklibdir=DIR find Tk libraries in DIR --with-jpegincdir=DIR find JPEG headers in DIR --with-jpeglibdir=DIR find JPEG libraries in DIR --with-tiffincdir=DIR find TIFF headers in DIR --with-tifflibdir=DIR find TIFF libraries in DIR --with-pngincdir=DIR find PNG headers in DIR --with-pnglibdir=DIR find PNG libraries in DIR --with-zlibdir=DIR find zlib libraries in DIR --with-xpmincdir=DIR find XPM headers in DIR --with-xpmlibdir=DIR find XPM libraries in DIR --with-freetype2incdir=DIR find freetype2 headers in DIR --with-freetype2libdir=DIR find freetype2 libraries in DIR --with-xftincdir=DIR find Xft headers in DIR --with-xftlibdir=DIR find Xft libraries in DIR --with-xrandrincdir=DIR find Xrandr headers in DIR --with-xrandrlibdir=DIR find Xrandr libraries in DIR --with-expatincdir=DIR find expat headers in DIR --with-expatlibdir=DIR find expat libraries in DIR --with-mysqlincdir=DIR find mysql headers in DIR --with-mysqllibdir=DIR find mysql libraries in DIR --with-gnu-ld use GNU linker --with-x use the X Window System Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" ac_aux_dir= for ac_dir in cf "$srcdir"/cf; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in cf \"$srcdir\"/cf" >&5 echo "$as_me: error: cannot find install-sh or install.sh in cf \"$srcdir\"/cf" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # ----------------------------------------------------------------------- # # Handle command line options # # --with-tcl=DIR # --with-tk=DIR # --with-cflags=flags This is probably for me only # --with-gnu-ld # # ----------------------------------------------------------------------- INC_SPECS="" loader_run_path="" DEFINES="" blt_enable_symbols="no" blt_enable_shared="yes" blt_with_expat_include_dir="yes" blt_with_expat_lib_dir="yes" blt_with_ft2_include_dir="yes" blt_with_ft2_lib_dir="yes" blt_with_gnu_ld="no" blt_with_jpeg_include_dir="yes" blt_with_jpeg_lib_dir="yes" blt_with_mysql_include_dir="yes" blt_with_mysql_lib_dir="yes" blt_with_png_include_dir="yes" blt_with_png_lib_dir="yes" blt_with_z_lib_dir="yes" blt_with_scriptdir="" blt_with_tcl="" blt_with_tcl_include_dir="yes" blt_with_tcl_lib_dir="yes" blt_with_tiff_include_dir="yes" blt_with_tiff_lib_dir="yes" blt_with_tk="" blt_with_tk_include_dir="yes" blt_with_tk_lib_dir="yes" blt_with_xft_include_dir="yes" blt_with_xft_lib_dir="yes" blt_with_xpm_include_dir="yes" blt_with_xpm_lib_dir="yes" blt_with_xrandr_include_dir="yes" blt_with_xrandr_lib_dir="yes" # Check whether --with-blt was given. if test "${with_blt+set}" = set; then withval=$with_blt; blt_with_scriptdir=$withval fi # Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then withval=$with_tcl; blt_with_tcl=$withval fi # Check whether --with-tk was given. if test "${with_tk+set}" = set; then withval=$with_tk; blt_with_tk=$withval fi # Check whether --with-tclincdir was given. if test "${with_tclincdir+set}" = set; then withval=$with_tclincdir; blt_with_tcl_include_dir=$withval fi # Check whether --with-tkincdir was given. if test "${with_tkincdir+set}" = set; then withval=$with_tkincdir; blt_with_tk_include_dir=$withval fi # Check whether --with-tcllibdir was given. if test "${with_tcllibdir+set}" = set; then withval=$with_tcllibdir; blt_with_tcl_lib_dir=$withval fi # Check whether --with-tklibdir was given. if test "${with_tklibdir+set}" = set; then withval=$with_tklibdir; blt_with_tk_lib_dir=$withval fi # Check whether --with-jpegincdir was given. if test "${with_jpegincdir+set}" = set; then withval=$with_jpegincdir; unset ac_cv_header_jpeglib_h; blt_with_jpeg_include_dir=$withval fi # Check whether --with-jpeglibdir was given. if test "${with_jpeglibdir+set}" = set; then withval=$with_jpeglibdir; unset ac_cv_lib_jpeg ac_cv_lib_jpeg_jpeg_read_header blt_with_jpeg_lib_dir=$withval fi # --with-tiffincdir # Check whether --with-tiffincdir was given. if test "${with_tiffincdir+set}" = set; then withval=$with_tiffincdir; blt_with_tiff_include_dir=$withval fi # --with-tifflibdir # Check whether --with-tifflibdir was given. if test "${with_tifflibdir+set}" = set; then withval=$with_tifflibdir; blt_with_tiff_lib_dir=$withval fi # --with-pngincdir # Check whether --with-pngincdir was given. if test "${with_pngincdir+set}" = set; then withval=$with_pngincdir; blt_with_png_include_dir=$withval fi # --with-pnglibdir # Check whether --with-pnglibdir was given. if test "${with_pnglibdir+set}" = set; then withval=$with_pnglibdir; blt_with_png_lib_dir=$withval fi # --with-zlibdir # Check whether --with-zlibdir was given. if test "${with_zlibdir+set}" = set; then withval=$with_zlibdir; blt_with_z_lib_dir=$withval fi # --with-xpmincdir # Check whether --with-xpmincdir was given. if test "${with_xpmincdir+set}" = set; then withval=$with_xpmincdir; blt_with_xpm_include_dir=$withval fi # --with-xpmlibdir # Check whether --with-xpmlibdir was given. if test "${with_xpmlibdir+set}" = set; then withval=$with_xpmlibdir; blt_with_xpm_lib_dir=$withval fi # --with-freetype2incdir # Check whether --with-freetype2incdir was given. if test "${with_freetype2incdir+set}" = set; then withval=$with_freetype2incdir; blt_with_ft2_include_dir=$withval fi # --with-freetype2libdir # Check whether --with-freetype2libdir was given. if test "${with_freetype2libdir+set}" = set; then withval=$with_freetype2libdir; blt_with_ft2_lib_dir=$withval fi # --with-xftincdir # Check whether --with-xftincdir was given. if test "${with_xftincdir+set}" = set; then withval=$with_xftincdir; blt_with_xft_include_dir=$withval fi # --with-xftlibdir # Check whether --with-xftlibdir was given. if test "${with_xftlibdir+set}" = set; then withval=$with_xftlibdir; blt_with_xft_lib_dir=$withval fi # --with-xrandrincdir # Check whether --with-xrandrincdir was given. if test "${with_xrandrincdir+set}" = set; then withval=$with_xrandrincdir; blt_with_xrandr_include_dir=$withval fi # --with-xrandrlibdir # Check whether --with-xrandrlibdir was given. if test "${with_xrandrlibdir+set}" = set; then withval=$with_xrandrlibdir; blt_with_xrandr_lib_dir=$withval fi # --with-expatincdir # Check whether --with-expatincdir was given. if test "${with_expatincdir+set}" = set; then withval=$with_expatincdir; blt_with_expat_include_dir=$withval fi # --with-expatlibdir # Check whether --with-expatlibdir was given. if test "${with_expatlibdir+set}" = set; then withval=$with_expatlibdir; blt_with_expat_lib_dir=$withval fi # --with-mysqlincdir # Check whether --with-mysqlincdir was given. if test "${with_mysqlincdir+set}" = set; then withval=$with_mysqlincdir; blt_with_mysql_include_dir=$withval fi # --with-mysqllibdir # Check whether --with-mysqllibdir was given. if test "${with_mysqllibdir+set}" = set; then withval=$with_mysqllibdir; blt_with_mysql_lib_dir=$withval fi # Check whether --with-gnu_ld was given. if test "${with_gnu_ld+set}" = set; then withval=$with_gnu_ld; blt_with_gnu_ld="yes" fi # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then enableval=$enable_shared; blt_enable_shared=$enableval fi # Check whether --enable-symbols was given. if test "${enable_symbols+set}" = set; then enableval=$enable_symbols; blt_enable_symbols=$enableval fi # Check whether --enable-stubs was given. if test "${enable_stubs+set}" = set; then enableval=$enable_stubs; blt_enable_stubs=$enableval fi EXPAT_INC_SPEC="" EXPAT_LIB_SPEC="" FTCFG_LIB_SPEC="" FT2_INC_SPEC="" FT2_LIB_SPEC="" XFT_INC_SPEC="" XFT_LIB_SPEC="" JPG_INC_SPEC="" JPG_LIB_SPEC="" MYSQL_INC_SPEC="" MYSQL_LIB_SPEC="" PNG_INC_SPEC="" PNG_LIB_SPEC="" TCL_INC_SPEC="" TCL_LIB_SPEC="" TIF_INC_SPEC="" TIF_LIB_SPEC="" TK_INC_SPEC="" TK_LIB_SPEC="" TK_XLIBSW="" XPM_INC_SPEC="" XPM_LIB_SPEC="" XRANDR_INC_SPEC="" XRANDR_LIB_SPEC="" XRENDER_LIB_SPEC="" XAU_LIB_SPEC="" XDMCP_LIB_SPEC="" Z_LIB_SPEC="" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6; } if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- if test "x$prefix" = xNONE; then echo $ECHO_N "checking for prefix by $ECHO_C" >&6 # Extract the first word of "wish", so it can be a program name with args. set dummy wish; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_ac_prefix_program+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $ac_prefix_program in [\\/]* | ?:[\\/]*) ac_cv_path_ac_prefix_program="$ac_prefix_program" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_prefix_program="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_prefix_program=$ac_cv_path_ac_prefix_program if test -n "$ac_prefix_program"; then { echo "$as_me:$LINENO: result: $ac_prefix_program" >&5 echo "${ECHO_T}$ac_prefix_program" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -n "$ac_prefix_program"; then prefix=`$as_dirname -- "$ac_prefix_program" || $as_expr X"$ac_prefix_program" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_prefix_program" : 'X\(//\)[^/]' \| \ X"$ac_prefix_program" : 'X\(//\)$' \| \ X"$ac_prefix_program" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_prefix_program" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` prefix=`$as_dirname -- "$prefix" || $as_expr X"$prefix" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$prefix" : 'X\(//\)[^/]' \| \ X"$prefix" : 'X\(//\)$' \| \ X"$prefix" : 'X\(/\)' \| . 2>/dev/null || echo X"$prefix" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` fi fi # ----------------------------------------------------------------------- # Set a variable containing current working directory if /bin/sh # doesn't do it already. # ----------------------------------------------------------------------- PWD=`pwd` # ----------------------------------------------------------------------- # Programs: Check for existence of ranlib and install programs # ----------------------------------------------------------------------- # ----------------------------------------------------------------------- # C compiler and debugging flags # ----------------------------------------------------------------------- if test "x${CC}" = "x" ; then CC=cc fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x${GCC}" != "x" ; then blt_have_gcc="yes" fi case $host_os in *cygwin* | *mingw*) blt_platform_win32="yes" { echo "$as_me:$LINENO: checking if using MinGW compiler" >&5 echo $ECHO_N "checking if using MinGW compiler... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __MINGW32__ _cc_is_not_mingw_ #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then blt_have_mingw=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 blt_have_mingw=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $blt_have_mingw" >&5 echo "${ECHO_T}$blt_have_mingw" >&6; } ;; * ) blt_platform_win32="no" ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x${GCC}" != "x" ; then blt_have_gcc="yes" else { echo "$as_me:$LINENO: checking if C compiler is really gcc" >&5 echo $ECHO_N "checking if C compiler is really gcc... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ _cc_is_not_gcc_ #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then blt_have_gcc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 blt_have_gcc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $blt_have_gcc" >&5 echo "${ECHO_T}$blt_have_gcc" >&6; } fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6; } fi { echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { echo "$as_me:$LINENO: result: $MKDIR_P" >&5 echo "${ECHO_T}$MKDIR_P" >&6; } { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ _ACEOF rm -f -r conftest* # # CFLAGS search order # # 1. command line (--with-cflags) # 2. cached variable ($blt_cv_prog_cflags) # 3. set to "-O3" if using gcc ($blt_have_gcc) # 4. otherwise, default to "-O" # # Setup default flags for the compiler. case $target:$blt_have_gcc:$blt_enable_symbols in *-solaris2*:no:yes) # CFLAGS="-g -xs -O" ;; *:yes:no) # CFLAGS="-O3" ;; *:yes:yes) # CFLAGS="-g -O3" ;; *:no:no) # CFLAGS="-O" ;; *) # CFLAGS="-g -O3" ;; esac CFLAGS="${CFLAGS}" GCCFLAGS="" if test "${blt_have_gcc}" = "yes" ; then GCCFLAGS="-Wall -Wpointer-arith -Wno-uninitialized -Wmissing-declarations -Wimplicit -Wwrite-strings -Wmissing-prototypes -Wundef" fi SO_PREFIX="" SO_EXT="" IMPLIB_SUFFIX="" IMPLIB_EXT="" case $target in *-*-cygwin*|*-*-mingw*) blt_platform="win" if test "${blt_have_mingw}" = "yes" ; then SO_PREFIX="" SO_EXT=".dll" IMPLIB_EXT=".lib" IMPLIB_PREFIX="" else SO_PREFIX="cyg" SO_EXT=".dll" IMPLIB_EXT=".dll.a" IMPLIB_PREFIX="lib" fi ;; *-hpux*) SO_EXT=".sl" blt_platform="unix" SO_PREFIX="lib" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; *-*-darwin*) blt_platform="unix" SO_EXT=".dylib" SO_PREFIX="lib" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; *) blt_platform="unix" SO_PREFIX="lib" SO_EXT=".so" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; esac build_shared="yes" if test $blt_enable_symbols = "yes" ; then LIB_SUFFIX=g fi # ----------------------------------------------------------------------- # Hardware characteristics: # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <string.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f -r conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <stdlib.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f -r conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ctype.h> #include <stdlib.h> #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <sys/types.h> #include <sys/param.h> int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <sys/types.h> #include <sys/param.h> int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac { echo "$as_me:$LINENO: checking for int" >&5 echo $ECHO_N "checking for int... $ECHO_C" >&6; } if test "${ac_cv_type_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 echo "${ECHO_T}$ac_cv_type_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_int=$ac_lo;; '') if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include <stdio.h> #include <stdlib.h> int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF { echo "$as_me:$LINENO: checking for long" >&5 echo $ECHO_N "checking for long... $ECHO_C" >&6; } if test "${ac_cv_type_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 echo "${ECHO_T}$ac_cv_type_long" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long=$ac_lo;; '') if test "$ac_cv_type_long" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include <stdio.h> #include <stdlib.h> int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_long" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF { echo "$as_me:$LINENO: checking for long long" >&5 echo $ECHO_N "checking for long long... $ECHO_C" >&6; } if test "${ac_cv_type_long_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5 echo "${ECHO_T}$ac_cv_type_long_long" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of long long" >&5 echo $ECHO_N "checking size of long long... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long_long=$ac_lo;; '') if test "$ac_cv_type_long_long" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_long=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long long ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include <stdio.h> #include <stdlib.h> int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_long_long" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long long) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_long=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF { echo "$as_me:$LINENO: checking for void *" >&5 echo $ECHO_N "checking for void *... $ECHO_C" >&6; } if test "${ac_cv_type_void_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_void_p=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_void_p=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_void_p" >&5 echo "${ECHO_T}$ac_cv_type_void_p" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of void *" >&5 echo $ECHO_N "checking size of void *... $ECHO_C" >&6; } if test "${ac_cv_sizeof_void_p+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_void_p=$ac_lo;; '') if test "$ac_cv_type_void_p" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (void *) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_void_p=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef void * ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include <stdio.h> #include <stdlib.h> int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_void_p=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_void_p" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (void *) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_void_p=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5 echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF { echo "$as_me:$LINENO: checking for float" >&5 echo $ECHO_N "checking for float... $ECHO_C" >&6; } if test "${ac_cv_type_float+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_float=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_float=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_float" >&5 echo "${ECHO_T}$ac_cv_type_float" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of float" >&5 echo $ECHO_N "checking size of float... $ECHO_C" >&6; } if test "${ac_cv_sizeof_float+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_float=$ac_lo;; '') if test "$ac_cv_type_float" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (float) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (float) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_float=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef float ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include <stdio.h> #include <stdlib.h> int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_float=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_float" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (float) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (float) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_float=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_float" >&5 echo "${ECHO_T}$ac_cv_sizeof_float" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_FLOAT $ac_cv_sizeof_float _ACEOF # Save the values as shell variables so that we can substitute them # into bltHash.h for situtations where there's no bltInt.h. SIZEOF_INT=${ac_cv_sizeof_int} SIZEOF_LONG=${ac_cv_sizeof_long} SIZEOF_LONG_LONG=${ac_cv_sizeof_long_long} SIZEOF_VOID_P=${ac_cv_sizeof_void_p} SIZEOF_FLOAT=${ac_cv_sizeof_float} # ----------------------------------------------------------------------- # Libraries: # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for main in -lm" >&5 echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6; } if test "${ac_cv_lib_m_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_m_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_m_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 echo "${ECHO_T}$ac_cv_lib_m_main" >&6; } if test $ac_cv_lib_m_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { echo "$as_me:$LINENO: checking for main in -lnsl" >&5 echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6; } if test "${ac_cv_lib_nsl_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_nsl_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6; } if test $ac_cv_lib_nsl_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi { echo "$as_me:$LINENO: checking for main in -lsocket" >&5 echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_socket_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 echo "${ECHO_T}$ac_cv_lib_socket_main" >&6; } if test $ac_cv_lib_socket_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then blt_have_dld=yes else blt_have_dld=no fi { echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5 echo "$as_me: error: Cannot use X directory names containing '" >&2;} { (exit 1); exit 1; }; };; #( *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <X11/Xlib.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <X11/Xlib.h> int main () { XrmInitialize () ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6; } fi if test "x${x_libraries}" != "x" ; then xtop=`dirname ${x_libraries}` PATH=$xtop/bin:$PATH fi # ----------------------------------------------------------------------- # Headers: # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <string.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f -r conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <stdlib.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f -r conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <ctype.h> #include <stdlib.h> #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <sys/types.h> #include <sys/wait.h> #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <sys/types.h> #include <sys/time.h> #include <time.h> int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi for ac_header in inttypes.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_inttypes_h}" = "yes" ; then HAVE_INTTYPES_H="#define HAVE_INTTYPES_H 1" else HAVE_INTTYPES_H="/* can't find inttypes.h */" fi for ac_header in limits.h sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in string.h ctype.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in errno.h float.h math.h ieeefp.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/time.h waitflags.h sys/wait.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in malloc.h memory.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in setjmp.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdlib.h stddef.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stropts.h termios.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in posix_openpt ptsname getpt grantpt unlockpt isastream setsid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in tcflush openpty do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in open_controlling_pty do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # FREETYPE2 header if test "${blt_with_ft2_include_dir}" != "no" ; then ft2_inc_spec=`freetype-config --cflags` echo ft2_inc_spec=$ft2_inc_spec save_CPPFLAGS=$CPPFLAGS CPPFLAGS="${ft2_inc_spec}" for ac_header in ft2build.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF FT2_INC_SPEC=${ft2_inc_spec} else FT2_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} # Xft header if test "${blt_with_xft_include_dir}" != "no" ; then if test "$blt_with_xft_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_xft_include_dir" != "yes" ; then for dir in $blt_with_xft_include_dir $blt_with_xft_include_dir/include ; do if test -r "${dir}/X11/Xft/Xft.h" ; then new_CPPFLAGS="-I${dir}" XFT_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/X11/Xft/Xft.h" ; then new_CPPFLAGS="-I${dir}" XFT_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS="${ft2_inc_spec} ${new_CPPFLAGS}" for ac_header in X11/Xft/Xft.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF XFT_INC_SPEC="${new_CPPFLAGS}" else XFT_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi fi # EXPAT header if test "${blt_with_expat_include_dir}" != "no" ; then if test "$blt_with_expat_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_expat_include_dir" != "yes" ; then for dir in $blt_with_expat_include_dir $blt_with_expat_include_dir/include ; do if test -r "${dir}/expat.h" ; then new_CPPFLAGS="-I${dir}" EXPAT_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/expat.h" ; then new_CPPFLAGS="-I${dir}" EXPAT_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in expat.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF EXPAT_INC_SPEC="${new_CPPFLAGS}" else EXPAT_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # MYSQL header if test "${blt_with_mysql_include_dir}" != "no" ; then if test "$blt_with_mysql_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_mysql_include_dir" != "yes" ; then for dir in $blt_with_mysql_include_dir $blt_with_mysql_include_dir/include ; do if test -r "${dir}/mysql/mysql.h" ; then new_CPPFLAGS="-I${dir}" MYSQL_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/mysql/mysql.h" ; then new_CPPFLAGS="-I${dir}" MYSQL_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in mysql/mysql.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF MYSQL_INC_SPEC="${new_CPPFLAGS}" else MYSQL_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # XPM header if test "${blt_with_xpm_include_dir}" != "no" ; then if test "$blt_with_xpm_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_xpm_include_dir" != "yes" ; then for dir in $blt_with_xpm_include_dir $blt_with_xpm_include_dir/include ; do if test -r "${dir}/X11/xpm.h" ; then new_CPPFLAGS="-I${dir}" XPM_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/X11/xpm.h" ; then new_CPPFLAGS="-I${dir}" XPM_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in X11/xpm.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF XPM_INC_SPEC="${new_CPPFLAGS}" else XPM_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # JPEG header if test "${blt_with_jpeg_include_dir}" != "no" ; then if test "$blt_with_jpeg_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_jpeg_include_dir" != "yes" ; then for dir in $blt_with_jpeg_include_dir $blt_with_jpeg_include_dir/include ; do if test -r "${dir}/jpeglib.h" ; then new_CPPFLAGS="-I${dir}" JPG_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/jpeglib.h" ; then new_CPPFLAGS="-I${dir}" JPG_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in jpeglib.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF JPG_INC_SPEC="${new_CPPFLAGS}" else JPG_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # TIFF header if test "${blt_with_tiff_include_dir}" != "no" ; then if test "$blt_with_tiff_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_tiff_include_dir" != "yes" ; then for dir in $blt_with_tiff_include_dir $blt_with_tiff_include_dir/include ; do if test -r "${dir}/tiff.h" ; then new_CPPFLAGS="-I${dir}" TIF_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/tiff.h" ; then new_CPPFLAGS="-I${dir}" TIF_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in tiff.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF TIF_INC_SPEC="${new_CPPFLAGS}" else TIF_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # PNG header if test "${blt_with_png_include_dir}" != "no" ; then if test "$blt_with_png_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_png_include_dir" != "yes" ; then for dir in $blt_with_png_include_dir $blt_with_png_include_dir/include ; do if test -r "${dir}/png.h" ; then new_CPPFLAGS="-I${dir}" PNG_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/png.h" ; then new_CPPFLAGS="-I${dir}" PNG_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in png.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF PNG_INC_SPEC="${new_CPPFLAGS}" else PNG_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # XRANDR header if test "${blt_with_xrandr_include_dir}" != "no" ; then if test "$blt_with_xrandr_include_dir" != "no" ; then new_CPPFLAGS="" if test "$blt_with_xrandr_include_dir" != "yes" ; then for dir in $blt_with_xrandr_include_dir $blt_with_xrandr_include_dir/include ; do if test -r "${dir}/X11/extensions/randr.h" ; then new_CPPFLAGS="-I${dir}" XRANDR_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/X11/extensions/randr.h" ; then new_CPPFLAGS="-I${dir}" XRANDR_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS=" ${new_CPPFLAGS}" for ac_header in X11/extensions/randr.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF XRANDR_INC_SPEC="${new_CPPFLAGS}" else XRANDR_INC_SPEC="" fi done CPPFLAGS=${save_CPPFLAGS} fi fi # ----------------------------------------------------------------------- # Types: # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6; } if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef pid_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi { echo "$as_me:$LINENO: checking whether union wait is defined correctly" >&5 echo $ECHO_N "checking whether union wait is defined correctly... $ECHO_C" >&6; } if test "${blt_cv_struct_wait_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <sys/types.h> #include <sys/wait.h> int main () { /* * Check whether <sys/wait.h> defines the type "union wait" * correctly. It's needed because of weirdness in HP-UX where * "union wait" is defined in both the BSD and SYS-V environments. * Checking the usability of WIFEXITED seems to do the trick. */ union wait x; WIFEXITED(x); /* Generates compiler error if WIFEXITED * uses an int. */ ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then blt_cv_struct_wait_works="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 blt_cv_struct_wait_works="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${blt_cv_struct_wait_works}" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNION_WAIT 1 _ACEOF fi { echo "$as_me:$LINENO: result: $blt_cv_struct_wait_works" >&5 echo "${ECHO_T}$blt_cv_struct_wait_works" >&6; } # ----------------------------------------------------------------------- # # Library Functions: Check for drand48, and srand48. # # ----------------------------------------------------------------------- for ac_func in strtolower strcasecmp strncasecmp drand48 srand48 finite isnan do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # For HPUX it's a little more complicated to search for isfinite { echo "$as_me:$LINENO: checking for isfinite" >&5 echo $ECHO_N "checking for isfinite... $ECHO_C" >&6; } if test "${blt_cv_have_isfinite+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <math.h> int main () { double x = 1.0; if (isfinite(x)) { return 0; } ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then blt_cv_have_isfinite="yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 blt_cv_have_isfinite="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi if test "${blt_cv_have_isfinite}" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_ISFINITE 1 _ACEOF fi { echo "$as_me:$LINENO: result: $blt_cv_have_isfinite" >&5 echo "${ECHO_T}$blt_cv_have_isfinite" >&6; } # ----------------------------------------------------------------------- # # Check the smallest value such that 1.0 + x != 1.0. # For ANSI compilers this is DBL_EPSILON in float.h # #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking whether DBL_EPSILON is defined in float.h" >&5 echo $ECHO_N "checking whether DBL_EPSILON is defined in float.h... $ECHO_C" >&6; } if test "${blt_cv_found_dbl_epsilon+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_FLOAT_H #include <float.h> #endif int main () { #ifdef DBL_EPSILON exit(0); #else exit(1); #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then blt_cv_found_dbl_epsilon=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 blt_cv_found_dbl_epsilon=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: ${blt_cv_found_dbl_epsilon}" >&5 echo "${ECHO_T}${blt_cv_found_dbl_epsilon}" >&6; } if test "${blt_cv_found_dbl_epsilon}" = "no" ; then if test "${blt_cv_dbl_epsilon+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else old_flags="$CFLAGS" CFLAGS="-lm" { echo "$as_me:$LINENO: checking whether DBL_EPSILON can be computed." >&5 echo $ECHO_N "checking whether DBL_EPSILON can be computed.... $ECHO_C" >&6; } if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: can not run test program while cross compiling" >&5 echo "$as_me: error: can not run test program while cross compiling" >&2;} { (exit 1); exit 1; }; } else cat > conftest.$ac_ext <<EOF #line 11247 "configure" #include "confdefs.h" #ifdef __cplusplus extern "C" void exit(int); #endif main () { double e, u; /* * Check the smallest value such that 1.0 + x != 1.0. * For ANSI compilers this is DBL_EPSILON in float.h */ u = 1.0; for(;;) { u *= 0.5; if ((1.0 + u) == 1.0) { break; } } e = u * 2.0; printf("%.17e\n", e); exit(0); } EOF eval $ac_link if test -s conftest && (./conftest > ./conftest.stdout; exit) 2>/dev/null; then blt_cv_dbl_epsilon=`cat ./conftest.stdout` else blt_cv_dbl_epsilon="" fi fi rm -fr conftest* CFLAGS="$old_flags" cat >>confdefs.h <<_ACEOF #define BLT_DBL_EPSILON ${blt_cv_dbl_epsilon} _ACEOF { echo "$as_me:$LINENO: result: ${blt_cv_dbl_epsilon}" >&5 echo "${ECHO_T}${blt_cv_dbl_epsilon}" >&6; } fi fi { echo "$as_me:$LINENO: checking whether strcasecmp is declared" >&5 echo $ECHO_N "checking whether strcasecmp is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_strcasecmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef strcasecmp (void) strcasecmp; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_strcasecmp=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strcasecmp=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_strcasecmp" >&5 echo "${ECHO_T}$ac_cv_have_decl_strcasecmp" >&6; } if test $ac_cv_have_decl_strcasecmp = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASECMP 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASECMP 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether strncasecmp is declared" >&5 echo $ECHO_N "checking whether strncasecmp is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_strncasecmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef strncasecmp (void) strncasecmp; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_strncasecmp=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strncasecmp=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_strncasecmp" >&5 echo "${ECHO_T}$ac_cv_have_decl_strncasecmp" >&6; } if test $ac_cv_have_decl_strncasecmp = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNCASECMP 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNCASECMP 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether strtolower is declared" >&5 echo $ECHO_N "checking whether strtolower is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_strtolower+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef strtolower (void) strtolower; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_strtolower=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_strtolower=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_strtolower" >&5 echo "${ECHO_T}$ac_cv_have_decl_strtolower" >&6; } if test $ac_cv_have_decl_strtolower = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRTOLOWER 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRTOLOWER 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether drand48 is declared" >&5 echo $ECHO_N "checking whether drand48 is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_drand48+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef drand48 (void) drand48; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_drand48=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_drand48=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_drand48" >&5 echo "${ECHO_T}$ac_cv_have_decl_drand48" >&6; } if test $ac_cv_have_decl_drand48 = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DRAND48 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DRAND48 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether srand48 is declared" >&5 echo $ECHO_N "checking whether srand48 is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_srand48+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef srand48 (void) srand48; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_srand48=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_srand48=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_srand48" >&5 echo "${ECHO_T}$ac_cv_have_decl_srand48" >&6; } if test $ac_cv_have_decl_srand48 = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SRAND48 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SRAND48 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether j1 is declared" >&5 echo $ECHO_N "checking whether j1 is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_j1+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef j1 (void) j1; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_j1=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_j1=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_j1" >&5 echo "${ECHO_T}$ac_cv_have_decl_j1" >&6; } if test $ac_cv_have_decl_j1 = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_J1 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_J1 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether hypot is declared" >&5 echo $ECHO_N "checking whether hypot is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_hypot+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef hypot (void) hypot; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_hypot=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_hypot=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_hypot" >&5 echo "${ECHO_T}$ac_cv_have_decl_hypot" >&6; } if test $ac_cv_have_decl_hypot = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_HYPOT 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_HYPOT 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether isnan is declared" >&5 echo $ECHO_N "checking whether isnan is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_isnan+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef isnan (void) isnan; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_isnan=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_isnan=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_isnan" >&5 echo "${ECHO_T}$ac_cv_have_decl_isnan" >&6; } if test $ac_cv_have_decl_isnan = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISNAN 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISNAN 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether isfinite is declared" >&5 echo $ECHO_N "checking whether isfinite is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_isfinite+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef isfinite (void) isfinite; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_isfinite=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_isfinite=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_isfinite" >&5 echo "${ECHO_T}$ac_cv_have_decl_isfinite" >&6; } if test $ac_cv_have_decl_isfinite = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISFINITE 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISFINITE 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether finite is declared" >&5 echo $ECHO_N "checking whether finite is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_finite+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef finite (void) finite; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_finite=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_finite=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_finite" >&5 echo "${ECHO_T}$ac_cv_have_decl_finite" >&6; } if test $ac_cv_have_decl_finite = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FINITE 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FINITE 0 _ACEOF fi { echo "$as_me:$LINENO: checking whether free is declared" >&5 echo $ECHO_N "checking whether free is declared... $ECHO_C" >&6; } if test "${ac_cv_have_decl_free+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #ifdef HAVE_MEMORY_H #include <memory.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ int main () { #ifndef free (void) free; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_free=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_free=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_have_decl_free" >&5 echo "${ECHO_T}$ac_cv_have_decl_free" >&6; } if test $ac_cv_have_decl_free = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FREE 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FREE 0 _ACEOF fi # ----------------------------------------------------------------------- # # System services: X, Tcl, Tk # # ----------------------------------------------------------------------- if test "x${x_libraries}" = "x" ; then X11_LIB_SPEC="-lX11" else X11_LIB_SPEC="-L${x_libraries} -lX11" fi if test "x${x_includes}" = "x" ; then X11_INC_SPEC="" else X11_INC_SPEC="-I${x_includes}" fi case "$target_cpu" in i[3-9]86|x86*|k5|k6|k6-2|k6-3|pentium*|athlon*) cat >>confdefs.h <<\_ACEOF #define HAVE_X86 1 _ACEOF ;; *) ;; esac # ----------------------------------------------------------------------- # # Find the Tcl build configuration file "tclConfig.sh" # # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for tclConfig.sh" >&5 echo $ECHO_N "checking for tclConfig.sh... $ECHO_C" >&6; } tcl_config_sh="" if test "x$blt_with_tcl" != "x" ; then # Verify that a tclConfig.sh file exists in the directory specified # by --with-tcl. for dir in \ $blt_with_tcl do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break elif test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done elif test "${blt_with_tcl_include_dir}" = "yes" -a \ "${blt_with_tcl_lib_dir}" = "yes" ; then # Otherwise, search for Tcl configuration file. # 1. Search previously named locations. for dir in \ $prefix \ $exec_prefix \ $blt_cv_tcl_lib do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break elif test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done # 2. Search source directories. if test "x$tcl_config_sh" = "x" ; then for dir in \ `ls -dr ../tcl[7-9].[0-9]* 2>/dev/null` \ ../tcl \ `ls -dr ../../tcl[7-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../../tcl[7-9].[0-9]* 2>/dev/null` \ ../../../tcl do if test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done fi # 3. Search standard locations. if test "x$tcl_config_sh" = "x" ; then for dir in \ /usr/local \ /usr do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break fi done fi fi { echo "$as_me:$LINENO: result: ${tcl_config_sh}" >&5 echo "${ECHO_T}${tcl_config_sh}" >&6; } # ----------------------------------------------------------------------- # # Find the Tk build configuration file "tkConfig.sh" # # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for tkConfig.sh" >&5 echo $ECHO_N "checking for tkConfig.sh... $ECHO_C" >&6; } tk_config_sh="" if test "x$blt_with_tk" != "x" -o "x$blt_with_tcl" != "x"; then # Verify that a tkConfig.sh file exists in the directory specified # by --with-tcl or --with-tk. for dir in \ $blt_with_tk \ $blt_with_tcl do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break elif test -r "$dir/$blt_platform/tkConfig.sh" ; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done elif test "${blt_with_tk_include_dir}" = "yes" -a \ "${blt_with_tk_lib_dir}" = "yes" ; then # Search for Tk configuration file. # 1. Search previously named locations. for dir in \ $prefix \ $exec_prefix \ $blt_cv_tk_lib \ $blt_cv_tcl_lib do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break elif test -r "$dir/$blt_platform/tkConfig.sh" ; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done # 2. Search source directories. if test "x$tk_config_sh" = "x" ; then for dir in \ ../tcl \ `ls -dr ../tk[4-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tk[4-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tk[4-9].[0-9]* 2>/dev/null` do if test -r "$dir/$blt_platform/tkConfig.sh"; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done fi # 3. Search standard locations. if test "x$tk_config_sh" = "x" ; then for dir in \ /usr/local \ ${x_libraries} \ /usr do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break fi done fi fi { echo "$as_me:$LINENO: result: ${tk_config_sh}" >&5 echo "${ECHO_T}${tk_config_sh}" >&6; } # ----------------------------------------------------------------------- # # Source in the Tcl/Tk configuration scripts. # # # Check for tclConfig.sh and tkConfig.sh. If found use values # in file, but don't check if libraries exist. # # ----------------------------------------------------------------------- if test "x${tcl_config_sh}" != "x" ; then . $tcl_config_sh TCL_INC_SPEC=${TCL_INCLUDE_SPEC} fi if test "x${tk_config_sh}" != "x" ; then . $tk_config_sh TK_INC_SPEC=${TK_INCLUDE_SPEC} fi tcl_includes_dir="" tk_includes_dir="" TCL_INC_SPEC=${TCL_INCLUDE_SPEC} TK_INC_SPEC=${TK_INCLUDE_SPEC} if test "${blt_with_tcl_include_dir}" = "no" ; then { { echo "$as_me:$LINENO: error: Can't find tcl.h: use --with-tclincdir switch" >&5 echo "$as_me: error: Can't find tcl.h: use --with-tclincdir switch" >&2;} { (exit 1); exit 1; }; } elif test "${blt_with_tcl_include_dir}" != "yes" ; then if test -r "${blt_with_tcl_include_dir}/tcl.h" ; then tcl_includes_dir=${blt_with_tcl_include_dir} TCL_INC_SPEC="-I${tcl_includes_dir}" cat > conftest.awk <<EOF /^# *define *TCL_MAJOR_VERSION[ \t]/ { print \$3 } EOF TCL_MAJOR_VERSION=`${AWK} -f conftest.awk "${tcl_includes_dir}/tcl.h"` rm -rf conftest* cat > conftest.awk <<EOF /^# *define *TCL_MINOR_VERSION[ \t]/ { print \$3 } EOF TCL_MINOR_VERSION=`${AWK} -f conftest.awk "${tcl_includes_dir}/tcl.h"` rm -rf conftest* TCL_VERSION=${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION} else { { echo "$as_me:$LINENO: error: Can't find tcl.h in \"${blt_with_tcl_include_dir}\"" >&5 echo "$as_me: error: Can't find tcl.h in \"${blt_with_tcl_include_dir}\"" >&2;} { (exit 1); exit 1; }; } fi else for dir in \ ${TCL_PREFIX}/include \ ${TCL_SRC_DIR}/generic \ /usr/local/include \ /usr/include do if test -r "$dir/tcl.h" ; then tcl_includes_dir=$dir break fi done if test "x${tcl_includes_dir}" = "x" ; then { { echo "$as_me:$LINENO: error: Can't find tcl.h header file." >&5 echo "$as_me: error: Can't find tcl.h header file." >&2;} { (exit 1); exit 1; }; } fi fi if test "${blt_with_tk_include_dir}" = "no" ; then { { echo "$as_me:$LINENO: error: Can't find tk.h: use --with-tkincdir switch" >&5 echo "$as_me: error: Can't find tk.h: use --with-tkincdir switch" >&2;} { (exit 1); exit 1; }; } elif test "${blt_with_tk_include_dir}" != "yes" ; then if test -r "${blt_with_tk_include_dir}/tk.h" ; then tk_includes_dir=${blt_with_tk_include_dir} TK_INC_SPEC="-I${tk_includes_dir}" cat > conftest.awk <<EOF /^# *define *TK_MAJOR_VERSION[ \t]/ { print \$3 } EOF TK_MAJOR_VERSION=`${AWK} -f conftest.awk "${tk_includes_dir}/tk.h"` rm -rf conftest* cat > conftest.awk <<EOF /^# *define *TK_MINOR_VERSION[ \t]/ { print \$3 } EOF TK_MINOR_VERSION=`${AWK} -f conftest.awk "${tk_includes_dir}/tk.h"` rm -rf conftest* TK_VERSION=${TK_MAJOR_VERSION}.${TK_MINOR_VERSION} else { { echo "$as_me:$LINENO: error: Can't find tk.h in \"${blt_with_tk_include_dir}\"" >&5 echo "$as_me: error: Can't find tk.h in \"${blt_with_tk_include_dir}\"" >&2;} { (exit 1); exit 1; }; } fi else for dir in \ ${TK_PREFIX}/include \ ${TK_SRC_DIR}/generic \ ${tcl_includes_dir} \ /usr/local/include \ /usr/include do if test -r "$dir/tk.h" ; then tk_includes_dir=$dir break fi done if test "x${tk_includes_dir}" = "x" ; then { { echo "$as_me:$LINENO: error: Can't find tk.h header file." >&5 echo "$as_me: error: Can't find tk.h header file." >&2;} { (exit 1); exit 1; }; } fi fi case $target in *-*-cygwin*|*-*-mingw*) TCL_LIB_VERSION="${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}sg" TK_LIB_VERSION="${TK_MAJOR_VERSION}${TK_MINOR_VERSION}sg" ;; *-sunos4*|*-*-netbsd|NetBSD-*|FreeBSD-*|OpenBSD-*) TCL_LIB_VERSION="${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}" TK_LIB_VERSION="${TK_MAJOR_VERSION}${TK_MINOR_VERSION}" ;; *) TCL_LIB_VERSION="${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}" TK_LIB_VERSION="${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}" ;; esac if test "${blt_with_tcl_lib_dir}" = "no" ; then { { echo "$as_me:$LINENO: error: Can't find Tcl library: use --with-tcllibdir switch" >&5 echo "$as_me: error: Can't find Tcl library: use --with-tcllibdir switch" >&2;} { (exit 1); exit 1; }; } elif test "${blt_with_tcl_lib_dir}" = "yes" ; then for libname in \ "${TCL_EXEC_PREFIX}/lib/${SO_PREFIX}tcl${TCL_LIB_VERSION}${SO_EXT}" \ "${TCL_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}${IMPLIB_EXT}" \ "${TCL_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}.lib" \ "${TCL_EXEC_PREFIX}/lib/libtcl${TCL_LIB_VERSION}.a" do if test -r "$libname" ; then TCL_LIB_DIR="${TCL_EXEC_PREFIX}/lib" TCL_LIB_SPEC="-L${TCL_LIB_DIR} -ltcl${TCL_LIB_VERSION}" break fi done else for libname in \ "${blt_with_tcl_lib_dir}/${SO_PREFIX}tcl${TCL_LIB_VERSION}${SO_EXT}" \ "${blt_with_tcl_lib_dir}/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}${IMPLIB_EXT}" \ "${blt_with_tcl_lib_dir}/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}.lib" \ "${blt_with_tcl_lib_dir}/libtcl${TCL_LIB_VERSION}.a" do if test -r "$libname" ; then TCL_LIB_DIR="${blt_with_tcl_lib_dir}" TCL_LIB_SPEC="-L${TCL_LIB_DIR} -ltcl${TCL_LIB_VERSION}" break fi done fi if test "x${TCL_LIB_DIR}" = "x" ; then { { echo "$as_me:$LINENO: error: Can't find tcl library ${libname} in \"${blt_with_tcl_lib_dir}\"" >&5 echo "$as_me: error: Can't find tcl library ${libname} in \"${blt_with_tcl_lib_dir}\"" >&2;} { (exit 1); exit 1; }; } fi if test "${blt_with_tk_lib_dir}" = "no" ; then { { echo "$as_me:$LINENO: error: Can't find Tcl library: use --with-tcllibdir switch" >&5 echo "$as_me: error: Can't find Tcl library: use --with-tcllibdir switch" >&2;} { (exit 1); exit 1; }; } elif test "${blt_with_tk_lib_dir}" = "yes" ; then for libname in \ "${TK_EXEC_PREFIX}/lib/${SO_PREFIX}tk${TK_LIB_VERSION}${SO_EXT}" \ "${TK_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}${IMPLIB_EXT}" \ "${TK_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}.lib" \ "${TK_EXEC_PREFIX}/lib/libtk${TK_LIB_VERSION}.a" do if test -r "$libname" ; then TK_LIB_DIR="${TK_EXEC_PREFIX}/lib" TK_LIB_SPEC="-L${TK_LIB_DIR} -ltk${TK_LIB_VERSION}" break fi done else for libname in \ "${blt_with_tk_lib_dir}/${SO_PREFIX}tk${TK_LIB_VERSION}${SO_EXT}" \ "${blt_with_tk_lib_dir}/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}${IMPLIB_EXT}" \ "${blt_with_tk_lib_dir}/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}$.lib" \ "${blt_with_tk_lib_dir}/libtk${TK_LIB_VERSION}.a" do if test -r "$libname" ; then TK_LIB_DIR="${blt_with_tk_lib_dir}" TK_LIB_SPEC="-L${TK_LIB_DIR} -ltk${TK_LIB_VERSION}" break fi done fi if test "x${TK_LIB_DIR}" = "x" ; then { { echo "$as_me:$LINENO: error: Can't find tk library." >&5 echo "$as_me: error: Can't find tk library." >&2;} { (exit 1); exit 1; }; } fi # ----------------------------------------------------------------------- # # Include files # # Append to INC_SPECS the various include files specifications # (built fromt the include directory information). # # ----------------------------------------------------------------------- # Tk include files if test "${tk_includes_dir}" != "/usr/include" ; then INC_SPECS="${INC_SPECS} ${TK_INC_SPEC}" fi # Tcl include files # # Add the include directory specification only if the Tcl # headers reside in a different directory from Tk's. if test "${tcl_includes_dir}" != "/usr/include" -a \ "${tcl_includes_dir}" != "${tk_includes_dir}" ; then INC_SPECS="${INC_SPECS} ${TCL_INC_SPEC}" fi # On Windows, override the default include directory with our own. if test "${blt_platform}" = "win"; then x_includes="NONE" fi # X11 include files if test "x${x_includes}" != "x" -a \ "${x_includes}" != "NONE" -a \ "${x_includes}" != "/usr/include" -a \ "${x_includes}" != "${tk_includes_dir}" -a \ "${x_includes}" != "${tcl_includes_dir}" ; then INC_SPECS="${INC_SPECS} -I${x_includes}" fi # ----------------------------------------------------------------------- # # Libraries # # Append to LIB the various library specifications # (built from the library directory information). # # ----------------------------------------------------------------------- # Collect the libraries for AIX that aren't using stubs. aix_lib_specs=$LIBS if test "${blt_platform}" = "unix"; then # Add specification for X11 library only on Unix platforms. if test "x${x_libraries}" = "x" -o \ "x${x_libraries}" = "NONE" -o \ "${x_libraries}" = "/usr/lib" -o \ "${x_libraries}" = "/usr/lib64" -o \ "${x_libraries}" = "${TK_LIB_DIR}" -o \ "${x_libraries}" = "${TCL_LIB_DIR}" ; then x_lib_spec="" aix_lib_specs="-lX11 ${aix_lib_specs}" else x_lib_spec="-L${x_libraries}" aix_lib_specs="-L${x_libraries} -lX11 ${aix_lib_specs}" if test "x${loader_run_path}" = "x" ; then loader_run_path="${x_libraries}" else loader_run_path="${loader_run_path}:${x_libraries}" fi fi fi # EXPAT library if test "${blt_with_expat_lib_dir}" != "no" -a \ "${ac_cv_header_expat_h}" != "no" ; then if test "$blt_with_expat_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_expat_lib_dir" = "yes" ; then lib_spec="-lexpat" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_ParserCreate (); int main () { return XML_ParserCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_expat_XML_ParserCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_expat_XML_ParserCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; } if test $ac_cv_lib_expat_XML_ParserCreate = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lexpat " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_ParserCreate (); int main () { return XML_ParserCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_expat_XML_ParserCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_expat_XML_ParserCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; } if test $ac_cv_lib_expat_XML_ParserCreate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then EXPAT_LIB_DIR="$dir" fi fi else for dir in $blt_with_expat_lib_dir $blt_with_expat_lib_dir/lib ; do lib_spec="-L${dir} -lexpat " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_ParserCreate (); int main () { return XML_ParserCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_expat_XML_ParserCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_expat_XML_ParserCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; } if test $ac_cv_lib_expat_XML_ParserCreate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then EXPAT_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBEXPAT 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" EXPAT_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # MYSQL client library if test "${blt_with_mysql_lib_dir}" != "no" -a \ "${ac_cv_header_mysql_mysql_h}" != "no" ; then if test "$blt_with_mysql_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_mysql_lib_dir" = "yes" ; then lib_spec="-lmysqlclient" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for mysql_init in -lmysqlclient" >&5 echo $ECHO_N "checking for mysql_init in -lmysqlclient... $ECHO_C" >&6; } if test "${ac_cv_lib_mysqlclient_mysql_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_init (); int main () { return mysql_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_mysqlclient_mysql_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mysqlclient_mysql_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_init" >&6; } if test $ac_cv_lib_mysqlclient_mysql_init = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lmysqlclient " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for mysql_init in -lmysqlclient" >&5 echo $ECHO_N "checking for mysql_init in -lmysqlclient... $ECHO_C" >&6; } if test "${ac_cv_lib_mysqlclient_mysql_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_init (); int main () { return mysql_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_mysqlclient_mysql_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mysqlclient_mysql_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_init" >&6; } if test $ac_cv_lib_mysqlclient_mysql_init = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then MYSQL_LIB_DIR="$dir" fi fi else for dir in $blt_with_mysql_lib_dir $blt_with_mysql_lib_dir/lib ; do lib_spec="-L${dir} -lmysqlclient " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for mysql_init in -lmysqlclient" >&5 echo $ECHO_N "checking for mysql_init in -lmysqlclient... $ECHO_C" >&6; } if test "${ac_cv_lib_mysqlclient_mysql_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_init (); int main () { return mysql_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_mysqlclient_mysql_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mysqlclient_mysql_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_init" >&6; } if test $ac_cv_lib_mysqlclient_mysql_init = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then MYSQL_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBMYSQL 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" MYSQL_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # JPEG library if test "${blt_with_jpeg_lib_dir}" != "no" -a \ "${ac_cv_header_jpeglib_h}" != "no" ; then if test "$blt_with_jpeg_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_jpeg_lib_dir" = "yes" ; then lib_spec="-ljpeg" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for jpeg_read_header in -ljpeg" >&5 echo $ECHO_N "checking for jpeg_read_header in -ljpeg... $ECHO_C" >&6; } if test "${ac_cv_lib_jpeg_jpeg_read_header+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_read_header (); int main () { return jpeg_read_header (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_jpeg_jpeg_read_header=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_jpeg_jpeg_read_header=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_read_header" >&6; } if test $ac_cv_lib_jpeg_jpeg_read_header = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -ljpeg " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for jpeg_read_header in -ljpeg" >&5 echo $ECHO_N "checking for jpeg_read_header in -ljpeg... $ECHO_C" >&6; } if test "${ac_cv_lib_jpeg_jpeg_read_header+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_read_header (); int main () { return jpeg_read_header (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_jpeg_jpeg_read_header=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_jpeg_jpeg_read_header=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_read_header" >&6; } if test $ac_cv_lib_jpeg_jpeg_read_header = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then JPG_LIB_DIR="$dir" fi fi else for dir in $blt_with_jpeg_lib_dir $blt_with_jpeg_lib_dir/lib ; do lib_spec="-L${dir} -ljpeg " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for jpeg_read_header in -ljpeg" >&5 echo $ECHO_N "checking for jpeg_read_header in -ljpeg... $ECHO_C" >&6; } if test "${ac_cv_lib_jpeg_jpeg_read_header+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_read_header (); int main () { return jpeg_read_header (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_jpeg_jpeg_read_header=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_jpeg_jpeg_read_header=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_read_header" >&6; } if test $ac_cv_lib_jpeg_jpeg_read_header = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then JPG_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBJPG 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" JPG_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # TIFF library if test "${blt_with_tiff_lib_dir}" != "no" -a \ "${ac_cv_header_tiff_h}" != "no" ; then if test "$blt_with_tiff_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_tiff_lib_dir" = "yes" ; then lib_spec="-ltiff" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for TIFFReadRGBAImage in -ltiff" >&5 echo $ECHO_N "checking for TIFFReadRGBAImage in -ltiff... $ECHO_C" >&6; } if test "${ac_cv_lib_tiff_TIFFReadRGBAImage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltiff $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TIFFReadRGBAImage (); int main () { return TIFFReadRGBAImage (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_tiff_TIFFReadRGBAImage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tiff_TIFFReadRGBAImage=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_tiff_TIFFReadRGBAImage" >&5 echo "${ECHO_T}$ac_cv_lib_tiff_TIFFReadRGBAImage" >&6; } if test $ac_cv_lib_tiff_TIFFReadRGBAImage = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -ltiff -lz" dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for TIFFReadRGBAImage in -ltiff" >&5 echo $ECHO_N "checking for TIFFReadRGBAImage in -ltiff... $ECHO_C" >&6; } if test "${ac_cv_lib_tiff_TIFFReadRGBAImage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltiff $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TIFFReadRGBAImage (); int main () { return TIFFReadRGBAImage (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_tiff_TIFFReadRGBAImage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tiff_TIFFReadRGBAImage=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_tiff_TIFFReadRGBAImage" >&5 echo "${ECHO_T}$ac_cv_lib_tiff_TIFFReadRGBAImage" >&6; } if test $ac_cv_lib_tiff_TIFFReadRGBAImage = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then TIF_LIB_DIR="$dir" fi fi else for dir in $blt_with_tiff_lib_dir $blt_with_tiff_lib_dir/lib ; do lib_spec="-L${dir} -ltiff -lz" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for TIFFReadRGBAImage in -ltiff" >&5 echo $ECHO_N "checking for TIFFReadRGBAImage in -ltiff... $ECHO_C" >&6; } if test "${ac_cv_lib_tiff_TIFFReadRGBAImage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltiff $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TIFFReadRGBAImage (); int main () { return TIFFReadRGBAImage (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_tiff_TIFFReadRGBAImage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tiff_TIFFReadRGBAImage=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_tiff_TIFFReadRGBAImage" >&5 echo "${ECHO_T}$ac_cv_lib_tiff_TIFFReadRGBAImage" >&6; } if test $ac_cv_lib_tiff_TIFFReadRGBAImage = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then TIF_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBTIF 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" TIF_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # PNG library if test "${blt_with_png_lib_dir}" != "no" -a \ "${ac_cv_header_png_h}" != "no" ; then if test "$blt_with_png_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_png_lib_dir" = "yes" ; then lib_spec="-lpng" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for png_read_png in -lpng" >&5 echo $ECHO_N "checking for png_read_png in -lpng... $ECHO_C" >&6; } if test "${ac_cv_lib_png_png_read_png+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_read_png (); int main () { return png_read_png (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_png_png_read_png=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_png_png_read_png=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_read_png" >&5 echo "${ECHO_T}$ac_cv_lib_png_png_read_png" >&6; } if test $ac_cv_lib_png_png_read_png = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lpng -lz" dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for png_read_png in -lpng" >&5 echo $ECHO_N "checking for png_read_png in -lpng... $ECHO_C" >&6; } if test "${ac_cv_lib_png_png_read_png+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_read_png (); int main () { return png_read_png (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_png_png_read_png=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_png_png_read_png=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_read_png" >&5 echo "${ECHO_T}$ac_cv_lib_png_png_read_png" >&6; } if test $ac_cv_lib_png_png_read_png = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then PNG_LIB_DIR="$dir" fi fi else for dir in $blt_with_png_lib_dir $blt_with_png_lib_dir/lib ; do lib_spec="-L${dir} -lpng -lz" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for png_read_png in -lpng" >&5 echo $ECHO_N "checking for png_read_png in -lpng... $ECHO_C" >&6; } if test "${ac_cv_lib_png_png_read_png+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_read_png (); int main () { return png_read_png (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_png_png_read_png=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_png_png_read_png=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_read_png" >&5 echo "${ECHO_T}$ac_cv_lib_png_png_read_png" >&6; } if test $ac_cv_lib_png_png_read_png = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then PNG_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBPNG 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" PNG_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # zlib library if test "${blt_with_z_lib_dir}" != "no" ; then if test "$blt_with_z_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_z_lib_dir" = "yes" ; then lib_spec="-lz" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for deflate in -lz" >&5 echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; } if test "${ac_cv_lib_z_deflate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_z_deflate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5 echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6; } if test $ac_cv_lib_z_deflate = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lz " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for deflate in -lz" >&5 echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; } if test "${ac_cv_lib_z_deflate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_z_deflate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5 echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6; } if test $ac_cv_lib_z_deflate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then Z_LIB_DIR="$dir" fi fi else for dir in $blt_with_z_lib_dir $blt_with_z_lib_dir/lib ; do lib_spec="-L${dir} -lz " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for deflate in -lz" >&5 echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6; } if test "${ac_cv_lib_z_deflate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_z_deflate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5 echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6; } if test $ac_cv_lib_z_deflate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then Z_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBZ 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" Z_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # XPM library old_CFLAGS=$CFLAGS CFLAGS=$X11_LIB_SPEC if test "${blt_with_xpm_lib_dir}" != "no" -a \ "${ac_cv_header_xpm_h}" != "no" ; then if test "$blt_with_xpm_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_xpm_lib_dir" = "yes" ; then lib_spec="-lXpm" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XpmCreateXpmImageFromBuffer in -lXpm" >&5 echo $ECHO_N "checking for XpmCreateXpmImageFromBuffer in -lXpm... $ECHO_C" >&6; } if test "${ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXpm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XpmCreateXpmImageFromBuffer (); int main () { return XpmCreateXpmImageFromBuffer (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&5 echo "${ECHO_T}$ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&6; } if test $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXpm " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XpmCreateXpmImageFromBuffer in -lXpm" >&5 echo $ECHO_N "checking for XpmCreateXpmImageFromBuffer in -lXpm... $ECHO_C" >&6; } if test "${ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXpm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XpmCreateXpmImageFromBuffer (); int main () { return XpmCreateXpmImageFromBuffer (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&5 echo "${ECHO_T}$ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&6; } if test $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XPM_LIB_DIR="$dir" fi fi else for dir in $blt_with_xpm_lib_dir $blt_with_xpm_lib_dir/lib ; do lib_spec="-L${dir} -lXpm " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XpmCreateXpmImageFromBuffer in -lXpm" >&5 echo $ECHO_N "checking for XpmCreateXpmImageFromBuffer in -lXpm... $ECHO_C" >&6; } if test "${ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXpm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XpmCreateXpmImageFromBuffer (); int main () { return XpmCreateXpmImageFromBuffer (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&5 echo "${ECHO_T}$ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer" >&6; } if test $ac_cv_lib_Xpm_XpmCreateXpmImageFromBuffer = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XPM_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXPM 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XPM_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # FREETYPE library if test "${blt_with_ft2_lib_dir}" != "no" -a \ "${ac_cv_header_ft2build_h}" != "no" ; then if test "$blt_with_ft2_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_ft2_lib_dir" = "yes" ; then lib_spec="-lfreetype" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FT_Init_FreeType in -lfreetype" >&5 echo $ECHO_N "checking for FT_Init_FreeType in -lfreetype... $ECHO_C" >&6; } if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfreetype $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FT_Init_FreeType (); int main () { return FT_Init_FreeType (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_freetype_FT_Init_FreeType=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_freetype_FT_Init_FreeType=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 echo "${ECHO_T}$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } if test $ac_cv_lib_freetype_FT_Init_FreeType = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lfreetype " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FT_Init_FreeType in -lfreetype" >&5 echo $ECHO_N "checking for FT_Init_FreeType in -lfreetype... $ECHO_C" >&6; } if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfreetype $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FT_Init_FreeType (); int main () { return FT_Init_FreeType (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_freetype_FT_Init_FreeType=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_freetype_FT_Init_FreeType=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 echo "${ECHO_T}$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } if test $ac_cv_lib_freetype_FT_Init_FreeType = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then FT2_LIB_DIR="$dir" fi fi else for dir in $blt_with_ft2_lib_dir $blt_with_ft2_lib_dir/lib ; do lib_spec="-L${dir} -lfreetype " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FT_Init_FreeType in -lfreetype" >&5 echo $ECHO_N "checking for FT_Init_FreeType in -lfreetype... $ECHO_C" >&6; } if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfreetype $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FT_Init_FreeType (); int main () { return FT_Init_FreeType (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_freetype_FT_Init_FreeType=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_freetype_FT_Init_FreeType=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 echo "${ECHO_T}$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } if test $ac_cv_lib_freetype_FT_Init_FreeType = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then FT2_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBFT2 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" FT2_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # Xft library if test "${blt_with_xft2_lib_dir}" != "no" -a \ "${ac_cv_header_x11_xft_xft_h}" != "no" ; then if test "$blt_with_xft_lib_dir" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$blt_with_xft_lib_dir" = "yes" ; then lib_spec="-lXft" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XftFontOpenPattern in -lXft -lexpat" >&5 echo $ECHO_N "checking for XftFontOpenPattern in -lXft -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_Xft__lexpat_XftFontOpenPattern+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXft -lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XftFontOpenPattern (); int main () { return XftFontOpenPattern (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xft__lexpat_XftFontOpenPattern=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xft__lexpat_XftFontOpenPattern=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&5 echo "${ECHO_T}$ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&6; } if test $ac_cv_lib_Xft__lexpat_XftFontOpenPattern = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXft -lexpat " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XftFontOpenPattern in -lXft -lexpat" >&5 echo $ECHO_N "checking for XftFontOpenPattern in -lXft -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_Xft__lexpat_XftFontOpenPattern+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXft -lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XftFontOpenPattern (); int main () { return XftFontOpenPattern (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xft__lexpat_XftFontOpenPattern=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xft__lexpat_XftFontOpenPattern=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&5 echo "${ECHO_T}$ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&6; } if test $ac_cv_lib_Xft__lexpat_XftFontOpenPattern = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XFT_LIB_DIR="$dir" fi fi else for dir in $blt_with_xft_lib_dir $blt_with_xft_lib_dir/lib ; do lib_spec="-L${dir} -lXft -lexpat " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XftFontOpenPattern in -lXft -lexpat" >&5 echo $ECHO_N "checking for XftFontOpenPattern in -lXft -lexpat... $ECHO_C" >&6; } if test "${ac_cv_lib_Xft__lexpat_XftFontOpenPattern+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXft -lexpat $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XftFontOpenPattern (); int main () { return XftFontOpenPattern (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xft__lexpat_XftFontOpenPattern=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xft__lexpat_XftFontOpenPattern=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&5 echo "${ECHO_T}$ac_cv_lib_Xft__lexpat_XftFontOpenPattern" >&6; } if test $ac_cv_lib_Xft__lexpat_XftFontOpenPattern = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XFT_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXFT 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XFT_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi if test "yes" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "yes" = "yes" ; then lib_spec="-lfontconfig" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FcPatternCreate in -lfontconfig" >&5 echo $ECHO_N "checking for FcPatternCreate in -lfontconfig... $ECHO_C" >&6; } if test "${ac_cv_lib_fontconfig_FcPatternCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfontconfig $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FcPatternCreate (); int main () { return FcPatternCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_fontconfig_FcPatternCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_fontconfig_FcPatternCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_fontconfig_FcPatternCreate" >&5 echo "${ECHO_T}$ac_cv_lib_fontconfig_FcPatternCreate" >&6; } if test $ac_cv_lib_fontconfig_FcPatternCreate = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lfontconfig " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FcPatternCreate in -lfontconfig" >&5 echo $ECHO_N "checking for FcPatternCreate in -lfontconfig... $ECHO_C" >&6; } if test "${ac_cv_lib_fontconfig_FcPatternCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfontconfig $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FcPatternCreate (); int main () { return FcPatternCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_fontconfig_FcPatternCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_fontconfig_FcPatternCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_fontconfig_FcPatternCreate" >&5 echo "${ECHO_T}$ac_cv_lib_fontconfig_FcPatternCreate" >&6; } if test $ac_cv_lib_fontconfig_FcPatternCreate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then FTCFG_LIB_DIR="$dir" fi fi else for dir in yes yes/lib ; do lib_spec="-L${dir} -lfontconfig " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for FcPatternCreate in -lfontconfig" >&5 echo $ECHO_N "checking for FcPatternCreate in -lfontconfig... $ECHO_C" >&6; } if test "${ac_cv_lib_fontconfig_FcPatternCreate+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfontconfig $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char FcPatternCreate (); int main () { return FcPatternCreate (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_fontconfig_FcPatternCreate=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_fontconfig_FcPatternCreate=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_fontconfig_FcPatternCreate" >&5 echo "${ECHO_T}$ac_cv_lib_fontconfig_FcPatternCreate" >&6; } if test $ac_cv_lib_fontconfig_FcPatternCreate = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then FTCFG_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBFTCFG 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" FTCFG_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi if test "yes" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "yes" = "yes" ; then lib_spec="-lXrender" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRenderQueryExtension in -lXrender" >&5 echo $ECHO_N "checking for XRenderQueryExtension in -lXrender... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrender_XRenderQueryExtension+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRenderQueryExtension (); int main () { return XRenderQueryExtension (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrender_XRenderQueryExtension=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrender_XRenderQueryExtension=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrender_XRenderQueryExtension" >&5 echo "${ECHO_T}$ac_cv_lib_Xrender_XRenderQueryExtension" >&6; } if test $ac_cv_lib_Xrender_XRenderQueryExtension = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXrender " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRenderQueryExtension in -lXrender" >&5 echo $ECHO_N "checking for XRenderQueryExtension in -lXrender... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrender_XRenderQueryExtension+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRenderQueryExtension (); int main () { return XRenderQueryExtension (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrender_XRenderQueryExtension=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrender_XRenderQueryExtension=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrender_XRenderQueryExtension" >&5 echo "${ECHO_T}$ac_cv_lib_Xrender_XRenderQueryExtension" >&6; } if test $ac_cv_lib_Xrender_XRenderQueryExtension = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XRENDER_LIB_DIR="$dir" fi fi else for dir in yes yes/lib ; do lib_spec="-L${dir} -lXrender " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRenderQueryExtension in -lXrender" >&5 echo $ECHO_N "checking for XRenderQueryExtension in -lXrender... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrender_XRenderQueryExtension+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRenderQueryExtension (); int main () { return XRenderQueryExtension (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrender_XRenderQueryExtension=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrender_XRenderQueryExtension=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrender_XRenderQueryExtension" >&5 echo "${ECHO_T}$ac_cv_lib_Xrender_XRenderQueryExtension" >&6; } if test $ac_cv_lib_Xrender_XRenderQueryExtension = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XRENDER_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXRENDER 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XRENDER_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi fi # Xrandr library if test "no" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "yes" = "yes" ; then lib_spec="-lXrandr" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRRGetScreenInfo in -lXrandr" >&5 echo $ECHO_N "checking for XRRGetScreenInfo in -lXrandr... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrandr_XRRGetScreenInfo+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRRGetScreenInfo (); int main () { return XRRGetScreenInfo (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrandr_XRRGetScreenInfo=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrandr_XRRGetScreenInfo=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrandr_XRRGetScreenInfo" >&5 echo "${ECHO_T}$ac_cv_lib_Xrandr_XRRGetScreenInfo" >&6; } if test $ac_cv_lib_Xrandr_XRRGetScreenInfo = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXrandr " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRRGetScreenInfo in -lXrandr" >&5 echo $ECHO_N "checking for XRRGetScreenInfo in -lXrandr... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrandr_XRRGetScreenInfo+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRRGetScreenInfo (); int main () { return XRRGetScreenInfo (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrandr_XRRGetScreenInfo=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrandr_XRRGetScreenInfo=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrandr_XRRGetScreenInfo" >&5 echo "${ECHO_T}$ac_cv_lib_Xrandr_XRRGetScreenInfo" >&6; } if test $ac_cv_lib_Xrandr_XRRGetScreenInfo = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XRANDR_LIB_DIR="$dir" fi fi else for dir in yes yes/lib ; do lib_spec="-L${dir} -lXrandr " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XRRGetScreenInfo in -lXrandr" >&5 echo $ECHO_N "checking for XRRGetScreenInfo in -lXrandr... $ECHO_C" >&6; } if test "${ac_cv_lib_Xrandr_XRRGetScreenInfo+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRRGetScreenInfo (); int main () { return XRRGetScreenInfo (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xrandr_XRRGetScreenInfo=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xrandr_XRRGetScreenInfo=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xrandr_XRRGetScreenInfo" >&5 echo "${ECHO_T}$ac_cv_lib_Xrandr_XRRGetScreenInfo" >&6; } if test $ac_cv_lib_Xrandr_XRRGetScreenInfo = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XRANDR_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXRANDR 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XRANDR_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi if test "no" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "yes" = "yes" ; then lib_spec="-lXdmcp" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XdmcpWrap in -lXdmcp" >&5 echo $ECHO_N "checking for XdmcpWrap in -lXdmcp... $ECHO_C" >&6; } if test "${ac_cv_lib_Xdmcp_XdmcpWrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXdmcp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XdmcpWrap (); int main () { return XdmcpWrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xdmcp_XdmcpWrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xdmcp_XdmcpWrap=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xdmcp_XdmcpWrap" >&5 echo "${ECHO_T}$ac_cv_lib_Xdmcp_XdmcpWrap" >&6; } if test $ac_cv_lib_Xdmcp_XdmcpWrap = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXdmcp " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XdmcpWrap in -lXdmcp" >&5 echo $ECHO_N "checking for XdmcpWrap in -lXdmcp... $ECHO_C" >&6; } if test "${ac_cv_lib_Xdmcp_XdmcpWrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXdmcp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XdmcpWrap (); int main () { return XdmcpWrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xdmcp_XdmcpWrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xdmcp_XdmcpWrap=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xdmcp_XdmcpWrap" >&5 echo "${ECHO_T}$ac_cv_lib_Xdmcp_XdmcpWrap" >&6; } if test $ac_cv_lib_Xdmcp_XdmcpWrap = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XDMCP_LIB_DIR="$dir" fi fi else for dir in yes yes/lib ; do lib_spec="-L${dir} -lXdmcp " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XdmcpWrap in -lXdmcp" >&5 echo $ECHO_N "checking for XdmcpWrap in -lXdmcp... $ECHO_C" >&6; } if test "${ac_cv_lib_Xdmcp_XdmcpWrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXdmcp $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XdmcpWrap (); int main () { return XdmcpWrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xdmcp_XdmcpWrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xdmcp_XdmcpWrap=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xdmcp_XdmcpWrap" >&5 echo "${ECHO_T}$ac_cv_lib_Xdmcp_XdmcpWrap" >&6; } if test $ac_cv_lib_Xdmcp_XdmcpWrap = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XDMCP_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXDMCP 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XDMCP_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi if test "no" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "yes" = "yes" ; then lib_spec="-lXau" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XauReadAuth in -lXau" >&5 echo $ECHO_N "checking for XauReadAuth in -lXau... $ECHO_C" >&6; } if test "${ac_cv_lib_Xau_XauReadAuth+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXau $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XauReadAuth (); int main () { return XauReadAuth (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xau_XauReadAuth=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xau_XauReadAuth=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xau_XauReadAuth" >&5 echo "${ECHO_T}$ac_cv_lib_Xau_XauReadAuth" >&6; } if test $ac_cv_lib_Xau_XauReadAuth = yes; then found="yes" else found="no" fi if test "${found}" = "no" ; then lib_spec="-L${dir} -lXau " dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XauReadAuth in -lXau" >&5 echo $ECHO_N "checking for XauReadAuth in -lXau... $ECHO_C" >&6; } if test "${ac_cv_lib_Xau_XauReadAuth+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXau $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XauReadAuth (); int main () { return XauReadAuth (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xau_XauReadAuth=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xau_XauReadAuth=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xau_XauReadAuth" >&5 echo "${ECHO_T}$ac_cv_lib_Xau_XauReadAuth" >&6; } if test $ac_cv_lib_Xau_XauReadAuth = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XAU_LIB_DIR="$dir" fi fi else for dir in yes yes/lib ; do lib_spec="-L${dir} -lXau " LDFLAGS="${lib_spec} ${save_LDFLAGS}" { echo "$as_me:$LINENO: checking for XauReadAuth in -lXau" >&5 echo $ECHO_N "checking for XauReadAuth in -lXau... $ECHO_C" >&6; } if test "${ac_cv_lib_Xau_XauReadAuth+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXau $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XauReadAuth (); int main () { return XauReadAuth (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_Xau_XauReadAuth=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xau_XauReadAuth=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_Xau_XauReadAuth" >&5 echo "${ECHO_T}$ac_cv_lib_Xau_XauReadAuth" >&6; } if test $ac_cv_lib_Xau_XauReadAuth = yes; then found="yes" else found="no" fi if test "${found}" = "yes" ; then XAU_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXAU 1 _ACEOF aix_lib_specs="${aix_lib_specs} ${lib_spec}" XAU_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi CFLAGS=$old_CFLAGS # Tcl libraries if test "${TCL_LIB_DIR}" != "/usr/lib" -a \ "${TCL_LIB_DIR}" != "/usr/lib64" -a \ "${TCL_LIB_DIR}" != "${TK_LIB_DIR}" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${TCL_LIB_DIR}" else loader_run_path="${TCL_LIB_DIR}:${loader_run_path}" fi fi # Tk libraries if test "${TK_LIB_DIR}" != "/usr/lib" -a \ "${TK_LIB_DIR}" != "/usr/lib64" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${TK_LIB_DIR}" else loader_run_path="${TK_LIB_DIR}:${loader_run_path}" fi fi # ----------------------------------------------------------------------- # # Set up a new default prefix to installation path. The ways # the prefix can be set and their precedence are as follows: # # 1. --prefix option given to ./configure. (prefix != NONE) # 2. use previously configured Tk prefix # # ----------------------------------------------------------------------- if test "$prefix" = "NONE" ; then prefix=${TCL_PREFIX} fi if test "$exec_prefix" = "NONE" ; then exec_prefix=${TCL_EXEC_PREFIX} fi # ------------------------------------------------------------------------- # # Extract the BLT version number for the blt.h header # # ------------------------------------------------------------------------- { echo "$as_me:$LINENO: checking BLT_MAJOR_VERSION" >&5 echo $ECHO_N "checking BLT_MAJOR_VERSION... $ECHO_C" >&6; } if test "${blt_cv_major_version+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat > conftest.awk <<EOF /^# *define *BLT_MAJOR_VERSION[ \t]/ { print \$3 } EOF blt_cv_major_version=`${AWK} -f conftest.awk "${srcdir}/src/blt.h"` rm -rf conftest* fi BLT_MAJOR_VERSION=${blt_cv_major_version} { echo "$as_me:$LINENO: result: $blt_cv_major_version" >&5 echo "${ECHO_T}$blt_cv_major_version" >&6; } { echo "$as_me:$LINENO: checking BLT_MINOR_VERSION" >&5 echo $ECHO_N "checking BLT_MINOR_VERSION... $ECHO_C" >&6; } if test "${blt_cv_minor_version+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat > conftest.awk <<EOF /^# *define *BLT_MINOR_VERSION[ \t]/ { print \$3 } EOF blt_cv_minor_version=`${AWK} -f conftest.awk "${srcdir}/src/blt.h"` rm -rf conftest* fi { echo "$as_me:$LINENO: result: $blt_cv_minor_version" >&5 echo "${ECHO_T}$blt_cv_minor_version" >&6; } BLT_MINOR_VERSION=${blt_cv_minor_version} BLT_VERSION=${BLT_MAJOR_VERSION}.${BLT_MINOR_VERSION} # Add BLT to the run path libdir=${exec_prefix}/lib if test "x${libdir}" != "x" -a \ "${libdir}" != "/usr/lib" -a \ "${libdir}" != "/usr/lib64" -a \ "${libdir}" != "${x_libraries}" -a \ "${libdir}" != "${TK_LIB_DIR}" -a \ "${libdir}" != "${TCL_LIB_DIR}" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${libdir}" else loader_run_path="${libdir}:${loader_run_path}" fi fi # ------------------------------------------------------------------------- # # Extract the Tcl version number for the tcl.h header # # ------------------------------------------------------------------------- if test "$TCL_VERSION" = "7.6" -a "$TK_VERSION" = "4.2" ; then : elif test "$TCL_VERSION" = "7.5" -a "$TK_VERSION" = "4.1" ; then : elif test "$TCL_VERSION" = "$TK_VERSION" ; then : else { { echo "$as_me:$LINENO: error: Mismatched Tcl/Tk versions ($TCL_VERSION != $TK_VERSION)" >&5 echo "$as_me: error: Mismatched Tcl/Tk versions ($TCL_VERSION != $TK_VERSION)" >&2;} { (exit 1); exit 1; }; } fi #-------------------------------------------------------------------- # # Check if we can generate shared libraries on this system. Set flags # to generate shared libraries for systems that we know about. Start # with the values found in tclConfig.sh, make changes as we know about # the different systems. # #-------------------------------------------------------------------- LIB_BASE_NAME=libBLT # Initialize shared library build variables SO_LD="$TCL_SHLIB_LD" SO_LDFLAGS="$TCL_LD_FLAGS" SO_RUNPATH="$TCL_LD_SEARCH_FLAGS" SO_TARGET="" SO_CFLAGS="" SO_LIBS="" LDFLAGS="" LD_RUN_PATH="" EXTRA_LIBS="" case $target in *-aix4.[2-9]*) # No Position-Independent flags needed SO_CFLAGS="" # Use the installed export file or the one found in the source directory. if test -r "${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" ; then tcl_exp="${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" else tcl_exp="${TCL_SRC_DIR}/unix/lib.exp" fi if test -r "${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" ; then tk_exp="${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" else tk_exp="${TK_SRC_DIR}/unix/lib.exp" fi full_src_path=`cd ${srcdir}; pwd` # Use shell-script to link shared library SO_LD="${full_src_path}/cf/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -bI:${tk_exp} -bI:${tcl_exp}" SO_LIBS="${aix_lib_specs} -lc" LDFLAGS="-L${loader_run_path}" EXTRA_LIBS="-ldl" ;; *-aix*) # No Position-Independent flags needed SO_CFLAGS="" # Use the installed export file or the one found in the source directory. if test -r "${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" ; then tcl_exp="${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" else tcl_exp="${TCL_SRC_DIR}/unix/lib.exp" fi if test -r "${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" ; then tk_exp="${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" else tk_exp="${TK_SRC_DIR}/unix/lib.exp" fi full_src_path=`cd ${srcdir}/cf; pwd` # Use shell-script to link shared library SO_LD="${full_src_path}/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -bI:${tk_exp} -bI:${tcl_exp}" SO_LIBS="${aix_lib_specs} -lc" LDFLAGS="-L${loader_run_path}" EXTRA_LIBS="-lld" ;; *-bsdi2*|*-bsdi3*) SO_CFLAGS="" SO_LD="shlicc" SO_LDFLAGS="-r" EXTRA_LIBS="-ldl" ;; *-bsdi4*) SO_CFLAGS="-export-dynamic -fPIC" SO_LD="${CC}" SO_LDFLAGS='-shared -Wl,-E -Wl,-soname,$@' ;; *-*-cygwin* | *-*-mingw*) SO_LD="${CC}" SO_LDFLAGS='-shared -Wl,-E -Wl,--out-implib,$@' EXTRA_LIBS="-lwinspool" SO_EXT=".dll" LDFLAGS="" ;; *-*-darwin*) SO_CFLAGS="-fno-common" SO_EXT=".dylib" SO_LD="${CC}" SO_LDFLAGS="-dynamiclib" { echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6; } save_LDFLAGS=$LDFLAGS LDFLAGS="$SO_LDFLAGS -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 single_module=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test "${single_module}" = "yes" ; then SO_LDFLAGS=$LDFLAGS fi { echo "$as_me:$LINENO: result: $single_module" >&5 echo "${ECHO_T}$single_module" >&6; } SO_LIBRARY_PATH="DYLD_LIBRARY_PATH" LDFLAGS="" ;; *-dgux*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-hpux*) if test "$blt_have_gcc" = "no" ; then DEFINES="$DEFINES -D_HPUX_SOURCE" fi if test "${blt_have_dld}" = "yes" ; then SO_CFLAGS="+Z" SO_LD="ld" SO_LDFLAGS="-b -E -n +s +b,${loader_run_path}:." SO_EXT=".sl" # The run path is included in both LDFLAGS and SO_LDFLAGS # because SO_LD is ld and LD is cc/gcc. LDFLAGS="-Wl,-E -Wl,+s,+b,${loader_run_path}:." EXTRA_LIBS="-ldld" fi ;; *-irix64-6.5*) SO_CFLAGS="" SO_LD="ld" SO_LDFLAGS="-32 -shared -rdata_shared" LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" ;; *-irix-56.*|*-irix64-*) SO_CFLAGS="" SO_LD="ld" SO_LDFLAGS="-shared -rdata_shared" LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" if test "$blt_have_gcc" = "yes" ; then SO_CFLAGS="-mabi=n32 $SO_CFLAGS" SO_LDFLAGS="-mabi=n32 $SO_LDFLAGS" LDFLAGS="-mabi=n32 $LDFLAGS" else CFLAGS="-n32 $CFLAGS" LDFLAGS="-n32 $LDFLAGS" fi ;; *-linux*) SO_CFLAGS="-fPIC" SO_LD="${CC}" SO_LDFLAGS='-rdynamic -shared -Wl,-E -Wl,-soname,$@' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" EXTRA_LIBS="-ldl" ;; *-mp-ras-02*) SO_CFLAGS="-G -K PIC" SO_LD="${CC}" SO_LDFLAGS="" ;; *-mp-ras-*) SO_CFLAGS="-G -K PIC" SO_LD="${CC}" SO_LDFLAGS="-Wl,-Bexport" ;; *-ncr-sysv4-*2*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-ncr-sysv4*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G -Wl,-Bexport" LDFLAGS="-Wl,-Bexport" EXTRA_LIBS="-ldl" ;; *-netbsd*|*-freebsd*|*-openbsd*) # Not available on all versions: check for include file. if test "${ac_cv_header_dlfcn_h+set}" = set; then { echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; } if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <dlfcn.h> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <dlfcn.h> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; } if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; } fi if test $ac_cv_header_dlfcn_h = yes; then test_ok=yes else test_ok=no fi if test "$test_ok" = yes; then SO_CFLAGS="-fpic" SO_LD="ld" SO_LDFLAGS="-Bshareable -x" fi ;; *-nextstep*) SO_CFLAGS="" SO_LD="cc" SO_LDFLAGS="-nostdlib -r" ;; *-osf1-1.012*) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SO_CFLAGS="" # Warning: Ugly Makefile Hack # Make package name same as library name SO_LD='ld -R -export $@:' ;; *-osf1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SO_CFLAGS="-fpic" SO_LD="ld -shared" ;; *-osf1V*) # Digital OSF/1 SO_CFLAGS="" SO_LD='ld' SO_LDFLAGS='-shared -expect_unresolved "*"' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" ;; *-sco*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. SO_CFLAGS="-Kpic -belf" SO_LD="ld" SO_LDFLAGS="-G" LDFLAGS="-belf -Wl,-Bexport" ;; *-sni-sysv*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-sunos4*) SO_CFLAGS="-PIC" SO_LD="ld" SO_LDFLAGS="-assert pure-text" EXTRA_LIBS="-ldl" ;; *-solaris2*) SO_CFLAGS="-KPIC" if test "${blt_with_gnu_ld}" = "yes" -a "$blt_have_gcc" = "yes" ; then SO_LD="gcc" SO_LDFLAGS='-rdynamic -shared -Wl,-E -Wl,-soname,$@' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" else SO_LD="/usr/ccs/bin/ld" SO_LDFLAGS="-G -z text" LD_RUN_PATH="-R ${loader_run_path}" fi EXTRA_LIBS="-ldl" ;; *-mips-dde-sysv*) SO_CFLAGS="-KPIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-pc-sysv4* | *-unixware-5*) SO_CFLAGS="-G -KPIC" SO_LD="${CC}" SO_LDFLAGS=" -Wl,-Bexport" ;; *) build_shared="no" ;; esac # If we're running gcc, then set SO_CFLAGS flags for compiling # shared libraries for gcc, instead of those of the vendor's # compiler. if test "$blt_have_gcc" = "yes" ; then if test "$blt_platform_win32" = "no" ; then SO_CFLAGS="-fPIC" fi fi # We can't back link against static versions of Tcl/Tk. # If # ${TCL_SHARED_BUILD} can't be found or isn't "1", assume that # shared libraries weren't built. if test "${TCL_SHARED_BUILD}" != "1" ; then SO_LIBS="" fi if test "${build_shared}" = "yes" -a "$blt_enable_shared" = "yes"; then BLT_SO_CFLAGS="$SO_CFLAGS" BLT_TARGET="shared" BLT_SO_LD="$SO_LD" BLT_SO_LDFLAGS="$SO_LDFLAGS" BLT_SO_LIBS="$SO_LIBS" BLT_SO_EXT="$SO_EXT" else BLT_TARGET="static" fi cat >>confdefs.h <<_ACEOF #define BLT_SO_EXT "$SO_EXT" _ACEOF cat >>confdefs.h <<_ACEOF #define BLT_SO_PREFIX "$SO_PREFIX" _ACEOF cat >>confdefs.h <<_ACEOF #define BLT_LIB_SUFFIX "$LIB_SUFFIX" _ACEOF BLT_SO_PREFIX="$SO_PREFIX" BLT_LIB_SUFFIX="$LIB_SUFFIX" if test "${blt_enable_stubs}" = "yes" ; then cat >>confdefs.h <<_ACEOF #define USE_TCL_STUBS 1 _ACEOF cat >>confdefs.h <<_ACEOF #define USE_TK_STUBS 1 _ACEOF TCL_STUBS_SPEC="-L${TCL_LIB_DIR} -ltclstub${TCL_LIB_VERSION}" TK_STUBS_SPEC="-L${TK_LIB_DIR} -ltkstub${TK_LIB_VERSION}" fi if test "${blt_platform_win32}" = "yes" ; then cat >>confdefs.h <<_ACEOF #define WIN32 1 _ACEOF fi WIN32=${blt_platform_win32} INCLUDES=${INC_SPECS} #-------------------------------------------------------------------- # The BLT script directory was either specified or we # assume <prefix>/lib #-------------------------------------------------------------------- if test "x${blt_with_scriptdir}" = "x" ; then BLT_LIBRARY="${prefix}/lib/blt${BLT_VERSION}" else BLT_LIBRARY="${blt_with_scriptdir}/blt${BLT_VERSION}" fi #-------------------------------------------------------------------- # Print out some of the more important settings #-------------------------------------------------------------------- echo "" echo "Configuration results:" echo "" echo " tcl.h found in $TCL_INC_SPEC" echo " tk.h found in $TK_INC_SPEC" echo " X11/Xlib.h found in $x_includes" echo " libtcl${TCL_LIB_VERSION} found in $TCL_LIB_SPEC" echo " libtk${TK_LIB_VERSION} found in $TK_LIB_SPEC" echo " libX11 found in $x_libraries" echo "" echo "Directories where BLT is to be installed:" echo "" echo " \"\$prefix\" is $prefix" echo " \"\$exec_prefix\" is $exec_prefix" echo "" echo " shells to be installed in $bindir" echo " libraries to be installed in $libdir" echo " scripts to be installed in $BLT_LIBRARY" echo " manual pages to be installed in $mandir" echo " MYSQL_LIB_SPEC=$MYSQL_LIB_SPEC" echo " MYSQL_INC_SPEC=$MYSQL_INC_SPEC" echo " EXPAT_LIB_SPEC=$EXPAT_LIB_SPEC" echo " EXPAT_INC_SPEC=$EXPAT_INC_SPEC" echo " FT2_LIB_SPEC=$FT2_LIB_SPEC" echo " FT2_INC_SPEC=$FT2_INC_SPEC" echo " JPG_LIB_SPEC=$JPG_LIB_SPEC" echo " JPG_INC_SPEC=$JPG_INC_SPEC" echo "" #-------------------------------------------------------------------- # # Generate the following Makefiles # # ./Makefile # ./src/Makefile # ./src/shared/Makefile # ./man/Makefile # ./library/Makefile # ./demos/Makefile # #-------------------------------------------------------------------- src_Makefile="src/Makefile" case ${blt_platform} in "win") src_Makefile="src/Makefile:src/Makefile-cyg.in" ;; "macosx") src_Makefile="src/Makefile:src/Makefile-macosx.in" ;; *) ;; esac # -------------------------------------------------------------- # List of files to have be generated from <name>.in files with # autoconf substitutions. # -------------------------------------------------------------- ac_config_files="$ac_config_files Makefile ${src_Makefile} src/bltHash.h src/shared/Makefile man/Makefile library/Makefile library/afm/Makefile demos/Makefile" test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "${src_Makefile}") CONFIG_FILES="$CONFIG_FILES ${src_Makefile}" ;; "src/bltHash.h") CONFIG_FILES="$CONFIG_FILES src/bltHash.h" ;; "src/shared/Makefile") CONFIG_FILES="$CONFIG_FILES src/shared/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "library/Makefile") CONFIG_FILES="$CONFIG_FILES library/Makefile" ;; "library/afm/Makefile") CONFIG_FILES="$CONFIG_FILES library/afm/Makefile" ;; "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim target!$target$ac_delim target_cpu!$target_cpu$ac_delim target_vendor!$target_vendor$ac_delim target_os!$target_os$ac_delim ac_prefix_program!$ac_prefix_program$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim CPP!$CPP$ac_delim AWK!$AWK$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim RANLIB!$RANLIB$ac_delim LN_S!$LN_S$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim SIZEOF_INT!$SIZEOF_INT$ac_delim SIZEOF_LONG!$SIZEOF_LONG$ac_delim SIZEOF_LONG_LONG!$SIZEOF_LONG_LONG$ac_delim SIZEOF_VOID_P!$SIZEOF_VOID_P$ac_delim SIZEOF_FLOAT!$SIZEOF_FLOAT$ac_delim XMKMF!$XMKMF$ac_delim HAVE_INTTYPES_H!$HAVE_INTTYPES_H$ac_delim BLT_SO_CFLAGS!$BLT_SO_CFLAGS$ac_delim BLT_TARGET!$BLT_TARGET$ac_delim BLT_SO_LD!$BLT_SO_LD$ac_delim BLT_SO_LDFLAGS!$BLT_SO_LDFLAGS$ac_delim BLT_SO_LIBS!$BLT_SO_LIBS$ac_delim BLT_SO_EXT!$BLT_SO_EXT$ac_delim LD_RUN_PATH!$LD_RUN_PATH$ac_delim BLT_SO_PREFIX!$BLT_SO_PREFIX$ac_delim BLT_LIB_SUFFIX!$BLT_LIB_SUFFIX$ac_delim IMPLIB_PREFIX!$IMPLIB_PREFIX$ac_delim IMPLIB_EXT!$IMPLIB_EXT$ac_delim TCL_STUBS_SPEC!$TCL_STUBS_SPEC$ac_delim TK_STUBS_SPEC!$TK_STUBS_SPEC$ac_delim WIN32!$WIN32$ac_delim AUX_LIBS!$AUX_LIBS$ac_delim BLT_MAJOR_VERSION!$BLT_MAJOR_VERSION$ac_delim BLT_MINOR_VERSION!$BLT_MINOR_VERSION$ac_delim BLT_VERSION!$BLT_VERSION$ac_delim DEFINES!$DEFINES$ac_delim DLL_PREFIX!$DLL_PREFIX$ac_delim EXPAT_INC_SPEC!$EXPAT_INC_SPEC$ac_delim EXPAT_LIB_SPEC!$EXPAT_LIB_SPEC$ac_delim EXTRA_LIBS!$EXTRA_LIBS$ac_delim FT2_INC_SPEC!$FT2_INC_SPEC$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS <conf$$subs.sed rm -f conf$$subs.sed cat >>$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF FT2_LIB_SPEC!$FT2_LIB_SPEC$ac_delim FTCFG_LIB_SPEC!$FTCFG_LIB_SPEC$ac_delim GCCFLAGS!$GCCFLAGS$ac_delim INCLUDES!$INCLUDES$ac_delim JPG_INC_SPEC!$JPG_INC_SPEC$ac_delim JPG_LIB_SPEC!$JPG_LIB_SPEC$ac_delim LIB_PREFIX!$LIB_PREFIX$ac_delim LIB_SUFFIX!$LIB_SUFFIX$ac_delim MYSQL_INC_SPEC!$MYSQL_INC_SPEC$ac_delim MYSQL_LIB_SPEC!$MYSQL_LIB_SPEC$ac_delim PNG_INC_SPEC!$PNG_INC_SPEC$ac_delim PNG_LIB_SPEC!$PNG_LIB_SPEC$ac_delim TCL_DBGX!$TCL_DBGX$ac_delim TCL_INC_SPEC!$TCL_INC_SPEC$ac_delim TCL_LIB_DIR!$TCL_LIB_DIR$ac_delim TCL_LIB_SPEC!$TCL_LIB_SPEC$ac_delim TCL_VERSION!$TCL_VERSION$ac_delim TIF_INC_SPEC!$TIF_INC_SPEC$ac_delim TIF_LIB_SPEC!$TIF_LIB_SPEC$ac_delim TK_INC_SPEC!$TK_INC_SPEC$ac_delim TK_LIB_SPEC!$TK_LIB_SPEC$ac_delim TK_XLIBSW!$TK_XLIBSW$ac_delim X11_INC_SPEC!$X11_INC_SPEC$ac_delim X11_LIB_SPEC!$X11_LIB_SPEC$ac_delim XAU_LIB_SPEC!$XAU_LIB_SPEC$ac_delim XDMCP_LIB_SPEC!$XDMCP_LIB_SPEC$ac_delim XFT_INC_SPEC!$XFT_INC_SPEC$ac_delim XFT_LIB_SPEC!$XFT_LIB_SPEC$ac_delim XPM_INC_SPEC!$XPM_INC_SPEC$ac_delim XPM_LIB_SPEC!$XPM_LIB_SPEC$ac_delim XRANDR_LIB_SPEC!$XRANDR_LIB_SPEC$ac_delim XRENDER_LIB_SPEC!$XRENDER_LIB_SPEC$ac_delim Z_LIB_SPEC!$Z_LIB_SPEC$ac_delim BLT_LIBRARY!$BLT_LIBRARY$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 36; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS <conf$$subs.sed rm -f conf$$subs.sed cat >>$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi �������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/Makefile.in�����������������������������������������������������������������������0000644�0001750�0001750�00000003136�11502740317�014314� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for BLT distribution # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Source and target installation directories # ------------------------------------------------------------------------ bindir = @bindir@ datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ includedir = @includedir@ libdir = @libdir@ prefix = @prefix@ srcdir = @srcdir@ version = @BLT_VERSION@ scriptdir = $(prefix)/lib bltdir = $(prefix)/lib/blt$(version) instdirs = $(prefix) \ $(exec_prefix) \ $(bindir) \ $(libdir) \ $(includedir) \ $(scriptdir) \ $(bltdir) # ------------------------------------------------------------------------ # Don't edit anything beyond this point # ------------------------------------------------------------------------ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ SHELL = /bin/sh MKDIR_P = @MKDIR_P@ RM = rm -f #subdirs = src library man demos subdirs = src all: for i in $(subdirs); do \ $(MAKE) -C $$i all || exit 1 ; \ done install: mkdirs install-all install-all: for i in $(subdirs); do \ $(MAKE) -C $$i install || exit 1 ; \ done mkdirs: @for i in $(instdirs) ; do \ $(MKDIR_P) $(DESTDIR)$$i; \ done clean: for i in $(subdirs); do \ $(MAKE) -C $$i clean || exit 1 ; \ done $(RM) *.bak *\~ "#"* *pure* .pure* GENERATED_FILES = \ config.status config.cache config.log Makefile distclean: clean $(RM) $(GENERATED_FILES) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/configure.in����������������������������������������������������������������������0000644�0001750�0001750�00000135171�11462120062�014557� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������define([AC_CACHE_LOAD], )dnl define([AC_CACHE_SAVE], )dnl AC_INIT(src/bltInit.c) AC_CONFIG_HEADER(src/config.h) AC_CONFIG_AUX_DIR(cf) AC_PREREQ(2.0) # ----------------------------------------------------------------------- # # Handle command line options # # --with-tcl=DIR # --with-tk=DIR # --with-cflags=flags This is probably for me only # --with-gnu-ld # # ----------------------------------------------------------------------- INC_SPECS="" loader_run_path="" DEFINES="" blt_enable_symbols="no" blt_enable_shared="yes" blt_with_expat_include_dir="yes" blt_with_expat_lib_dir="yes" blt_with_ft2_include_dir="yes" blt_with_ft2_lib_dir="yes" blt_with_gnu_ld="no" blt_with_jpeg_include_dir="yes" blt_with_jpeg_lib_dir="yes" blt_with_mysql_include_dir="yes" blt_with_mysql_lib_dir="yes" blt_with_png_include_dir="yes" blt_with_png_lib_dir="yes" blt_with_z_lib_dir="yes" blt_with_scriptdir="" blt_with_tcl="" blt_with_tcl_include_dir="yes" blt_with_tcl_lib_dir="yes" blt_with_tiff_include_dir="yes" blt_with_tiff_lib_dir="yes" blt_with_tk="" blt_with_tk_include_dir="yes" blt_with_tk_lib_dir="yes" blt_with_xft_include_dir="yes" blt_with_xft_lib_dir="yes" blt_with_xpm_include_dir="yes" blt_with_xpm_lib_dir="yes" blt_with_xrandr_include_dir="yes" blt_with_xrandr_lib_dir="yes" AC_ARG_WITH(blt, [AS_HELP_STRING([--with-blt=DIR],[install BLT scripts in DIR])], [blt_with_scriptdir=$withval]) AC_ARG_WITH(tcl, [AS_HELP_STRING([--with-tcl=DIR],[find tclConfig.sh in DIR])], [ blt_with_tcl=$withval]) AC_ARG_WITH(tk, [AS_HELP_STRING([--with-tk=DIR],[find tkConfig.sh in DIR])], [ blt_with_tk=$withval]) AC_ARG_WITH(tclincdir, [AS_HELP_STRING([--with-tclincdir=DIR],[find Tcl includes in DIR])], [blt_with_tcl_include_dir=$withval]) AC_ARG_WITH(tkincdir, [AS_HELP_STRING([--with-tkincdir=DIR],[find Tk includes in DIR])], [blt_with_tk_include_dir=$withval]) AC_ARG_WITH(tcllibdir, [AS_HELP_STRING([--with-tcllibdir=DIR],[find Tcl libraries in DIR])], [blt_with_tcl_lib_dir=$withval]) AC_ARG_WITH(tklibdir, [AS_HELP_STRING([--with-tklibdir=DIR],[find Tk libraries in DIR])], [blt_with_tk_lib_dir=$withval]) AC_ARG_WITH(jpegincdir, [AS_HELP_STRING([--with-jpegincdir=DIR],[find JPEG headers in DIR])], [unset ac_cv_header_jpeglib_h; blt_with_jpeg_include_dir=$withval]) AC_ARG_WITH(jpeglibdir, [AS_HELP_STRING([--with-jpeglibdir=DIR],[find JPEG libraries in DIR])], [unset ac_cv_lib_jpeg ac_cv_lib_jpeg_jpeg_read_header blt_with_jpeg_lib_dir=$withval]) # --with-tiffincdir AC_ARG_WITH(tiffincdir, [AS_HELP_STRING([--with-tiffincdir=DIR],[find TIFF headers in DIR])], [blt_with_tiff_include_dir=$withval]) # --with-tifflibdir AC_ARG_WITH(tifflibdir, [AS_HELP_STRING([--with-tifflibdir=DIR],[find TIFF libraries in DIR])], [blt_with_tiff_lib_dir=$withval]) # --with-pngincdir AC_ARG_WITH(pngincdir, [AS_HELP_STRING([--with-pngincdir=DIR],[find PNG headers in DIR])], [blt_with_png_include_dir=$withval]) # --with-pnglibdir AC_ARG_WITH(pnglibdir, [AS_HELP_STRING([--with-pnglibdir=DIR],[find PNG libraries in DIR])], [blt_with_png_lib_dir=$withval]) # --with-zlibdir AC_ARG_WITH(zlibdir, [AS_HELP_STRING([--with-zlibdir=DIR],[find zlib libraries in DIR])], [blt_with_z_lib_dir=$withval]) # --with-xpmincdir AC_ARG_WITH(xpmincdir, [AS_HELP_STRING([--with-xpmincdir=DIR],[find XPM headers in DIR])], [blt_with_xpm_include_dir=$withval]) # --with-xpmlibdir AC_ARG_WITH(xpmlibdir, [AS_HELP_STRING([--with-xpmlibdir=DIR],[find XPM libraries in DIR])], [blt_with_xpm_lib_dir=$withval]) # --with-freetype2incdir AC_ARG_WITH(freetype2incdir, [AS_HELP_STRING([--with-freetype2incdir=DIR],[find freetype2 headers in DIR])], [blt_with_ft2_include_dir=$withval]) # --with-freetype2libdir AC_ARG_WITH(freetype2libdir, [AS_HELP_STRING([--with-freetype2libdir=DIR],[find freetype2 libraries in DIR])], [blt_with_ft2_lib_dir=$withval]) # --with-xftincdir AC_ARG_WITH(xftincdir, [AS_HELP_STRING([--with-xftincdir=DIR],[find Xft headers in DIR])], [blt_with_xft_include_dir=$withval]) # --with-xftlibdir AC_ARG_WITH(xftlibdir, [AS_HELP_STRING([--with-xftlibdir=DIR],[find Xft libraries in DIR])], [blt_with_xft_lib_dir=$withval]) # --with-xrandrincdir AC_ARG_WITH(xrandrincdir, [AS_HELP_STRING([--with-xrandrincdir=DIR],[find Xrandr headers in DIR])], [blt_with_xrandr_include_dir=$withval]) # --with-xrandrlibdir AC_ARG_WITH(xrandrlibdir, [AS_HELP_STRING([--with-xrandrlibdir=DIR],[find Xrandr libraries in DIR])], [blt_with_xrandr_lib_dir=$withval]) # --with-expatincdir AC_ARG_WITH(expatincdir, [AS_HELP_STRING([--with-expatincdir=DIR],[find expat headers in DIR])], [blt_with_expat_include_dir=$withval]) # --with-expatlibdir AC_ARG_WITH(expatlibdir, [AS_HELP_STRING([--with-expatlibdir=DIR],[find expat libraries in DIR])], [blt_with_expat_lib_dir=$withval]) # --with-mysqlincdir AC_ARG_WITH(mysqlincdir, [AS_HELP_STRING([--with-mysqlincdir=DIR],[find mysql headers in DIR])], [blt_with_mysql_include_dir=$withval]) # --with-mysqllibdir AC_ARG_WITH(mysqllibdir, [AS_HELP_STRING([--with-mysqllibdir=DIR],[find mysql libraries in DIR])], [blt_with_mysql_lib_dir=$withval]) AC_ARG_WITH(gnu_ld, [AS_HELP_STRING([--with-gnu-ld], [use GNU linker])], [blt_with_gnu_ld="yes"]) AC_ARG_ENABLE(shared, [AS_HELP_STRING([--enable-shared],[created shared libraries])], [blt_enable_shared=$enableval]) AC_ARG_ENABLE(symbols, [AS_HELP_STRING([--enable-symbols],[compile with debugging symbols])], [blt_enable_symbols=$enableval]) AC_ARG_ENABLE(stubs, [AS_HELP_STRING([--enable-stubs],[compile with stubbed version of Tcl library])], [blt_enable_stubs=$enableval]) EXPAT_INC_SPEC="" EXPAT_LIB_SPEC="" FTCFG_LIB_SPEC="" FT2_INC_SPEC="" FT2_LIB_SPEC="" XFT_INC_SPEC="" XFT_LIB_SPEC="" JPG_INC_SPEC="" JPG_LIB_SPEC="" MYSQL_INC_SPEC="" MYSQL_LIB_SPEC="" PNG_INC_SPEC="" PNG_LIB_SPEC="" TCL_INC_SPEC="" TCL_LIB_SPEC="" TIF_INC_SPEC="" TIF_LIB_SPEC="" TK_INC_SPEC="" TK_LIB_SPEC="" XPM_INC_SPEC="" XPM_LIB_SPEC="" XRANDR_INC_SPEC="" XRANDR_LIB_SPEC="" XRENDER_LIB_SPEC="" XAU_LIB_SPEC="" XDMCP_LIB_SPEC="" Z_LIB_SPEC="" AC_CANONICAL_TARGET AC_PREFIX_PROGRAM(wish) # ----------------------------------------------------------------------- # Set a variable containing current working directory if /bin/sh # doesn't do it already. # ----------------------------------------------------------------------- PWD=`pwd` # ----------------------------------------------------------------------- # Programs: Check for existence of ranlib and install programs # ----------------------------------------------------------------------- # ----------------------------------------------------------------------- # C compiler and debugging flags # ----------------------------------------------------------------------- if test "x${CC}" = "x" ; then CC=cc fi AC_PROG_CC AC_PROG_CPP if test "x${GCC}" != "x" ; then blt_have_gcc="yes" fi case $host_os in *cygwin* | *mingw*) blt_platform_win32="yes" AC_MSG_CHECKING([if using MinGW compiler]) AC_TRY_COMPILE([], [ #ifndef __MINGW32__ _cc_is_not_mingw_ #endif ], [blt_have_mingw=yes], [blt_have_mingw=no]) AC_MSG_RESULT([$blt_have_mingw]) ;; * ) blt_platform_win32="no" ;; esac AC_PROG_CPP if test "x${GCC}" != "x" ; then blt_have_gcc="yes" else AC_MSG_CHECKING([if C compiler is really gcc]) AC_TRY_COMPILE([], [ #ifndef __GNUC__ _cc_is_not_gcc_ #endif ], [blt_have_gcc=yes], [blt_have_gcc=no]) AC_MSG_RESULT([$blt_have_gcc]) fi AC_PROG_AWK AC_PROG_INSTALL AC_PROG_RANLIB AC_PROG_LN_S AC_PROG_MKDIR_P AC_EGREP_CPP # # CFLAGS search order # # 1. command line (--with-cflags) # 2. cached variable ($blt_cv_prog_cflags) # 3. set to "-O3" if using gcc ($blt_have_gcc) # 4. otherwise, default to "-O" # # Setup default flags for the compiler. case $target:$blt_have_gcc:$blt_enable_symbols in *-solaris2*:no:yes) CFLAGS="-g -xs -O" ;; *:yes:no) CFLAGS="-O3" ;; *:yes:yes) CFLAGS="-g -O3" ;; *:no:no) CFLAGS="-O" ;; *) CFLAGS="-g -O3" ;; esac GCCFLAGS="" if test "${blt_have_gcc}" = "yes" ; then GCCFLAGS="-Wall -Wpointer-arith -Wno-uninitialized -Wmissing-declarations -Wimplicit -Wwrite-strings -Wmissing-prototypes -Wundef" fi SO_PREFIX="" SO_EXT="" IMPLIB_SUFFIX="" IMPLIB_EXT="" case $target in *-*-cygwin*|*-*-mingw*) blt_platform="win" if test "${blt_have_mingw}" = "yes" ; then SO_PREFIX="" SO_EXT=".dll" IMPLIB_EXT=".lib" IMPLIB_PREFIX="" else SO_PREFIX="cyg" SO_EXT=".dll" IMPLIB_EXT=".dll.a" IMPLIB_PREFIX="lib" fi ;; *-hpux*) SO_EXT=".sl" blt_platform="unix" SO_PREFIX="lib" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; *-*-darwin*) blt_platform="macosx" SO_EXT=".dylib" SO_PREFIX="lib" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; *) blt_platform="unix" SO_PREFIX="lib" SO_EXT=".so" IMPLIB_SUFFIX="" IMPLIB_EXT="" ;; esac build_shared="yes" if test $blt_enable_symbols = "yes" ; then LIB_SUFFIX=g fi # ----------------------------------------------------------------------- # Hardware characteristics: # ----------------------------------------------------------------------- AC_C_BIGENDIAN AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long, 4) AC_CHECK_SIZEOF(long long, 8) AC_CHECK_SIZEOF(void *, 4) AC_CHECK_SIZEOF(float, 4) # Save the values as shell variables so that we can substitute them # into bltHash.h for situtations where there's no bltInt.h. AC_SUBST(SIZEOF_INT, ${ac_cv_sizeof_int}) AC_SUBST(SIZEOF_LONG, ${ac_cv_sizeof_long}) AC_SUBST(SIZEOF_LONG_LONG, ${ac_cv_sizeof_long_long}) AC_SUBST(SIZEOF_VOID_P, ${ac_cv_sizeof_void_p}) AC_SUBST(SIZEOF_FLOAT, ${ac_cv_sizeof_float}) # ----------------------------------------------------------------------- # Libraries: # ----------------------------------------------------------------------- AC_CHECK_LIB(m, main) AC_CHECK_LIB(nsl, main) AC_CHECK_LIB(socket, main) AC_CHECK_LIB(dld, shl_load, [blt_have_dld=yes], [blt_have_dld=no]) AC_PATH_X if test "x${x_libraries}" != "x" ; then xtop=`dirname ${x_libraries}` PATH=$xtop/bin:$PATH fi # ----------------------------------------------------------------------- # Headers: # ----------------------------------------------------------------------- AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_TIME AC_CHECK_HEADERS(inttypes.h) if test "${ac_cv_header_inttypes_h}" = "yes" ; then AC_SUBST(HAVE_INTTYPES_H, ["#define HAVE_INTTYPES_H 1"]) else AC_SUBST(HAVE_INTTYPES_H, ["/* can't find inttypes.h */"]) fi AC_CHECK_HEADERS(limits.h sys/param.h) AC_CHECK_HEADERS(string.h ctype.h) AC_CHECK_HEADERS(errno.h float.h math.h ieeefp.h) AC_CHECK_HEADERS(sys/time.h waitflags.h sys/wait.h) AC_CHECK_HEADERS(malloc.h memory.h) AC_CHECK_HEADERS(setjmp.h) AC_CHECK_HEADERS(stdlib.h stddef.h unistd.h) AC_CHECK_HEADERS(stropts.h termios.h) AC_CHECK_FUNCS(posix_openpt ptsname getpt grantpt unlockpt isastream setsid) AC_CHECK_FUNCS(tcflush openpty) AC_CHECK_FUNCS(open_controlling_pty) # FREETYPE2 header if test "${blt_with_ft2_include_dir}" != "no" ; then ft2_inc_spec=`freetype-config --cflags` echo ft2_inc_spec=$ft2_inc_spec save_CPPFLAGS=$CPPFLAGS CPPFLAGS="${ft2_inc_spec}" AC_CHECK_HEADERS(ft2build.h, FT2_INC_SPEC=${ft2_inc_spec}, FT2_INC_SPEC="") CPPFLAGS=${save_CPPFLAGS} # Xft header if test "${blt_with_xft_include_dir}" != "no" ; then BLT_CHECK_HEADER(XFT, X11/Xft/Xft.h, $blt_with_xft_include_dir, ${ft2_inc_spec}) fi fi # EXPAT header if test "${blt_with_expat_include_dir}" != "no" ; then BLT_CHECK_HEADER(EXPAT, expat.h, $blt_with_expat_include_dir) fi # MYSQL header if test "${blt_with_mysql_include_dir}" != "no" ; then BLT_CHECK_HEADER(MYSQL, mysql/mysql.h, $blt_with_mysql_include_dir) fi # XPM header if test "${blt_with_xpm_include_dir}" != "no" ; then BLT_CHECK_HEADER(XPM, X11/xpm.h, $blt_with_xpm_include_dir) fi # JPEG header if test "${blt_with_jpeg_include_dir}" != "no" ; then BLT_CHECK_HEADER(JPG, jpeglib.h, $blt_with_jpeg_include_dir) fi # TIFF header if test "${blt_with_tiff_include_dir}" != "no" ; then BLT_CHECK_HEADER(TIF, tiff.h, $blt_with_tiff_include_dir) fi # PNG header if test "${blt_with_png_include_dir}" != "no" ; then BLT_CHECK_HEADER(PNG, png.h, $blt_with_png_include_dir) fi # XRANDR header if test "${blt_with_xrandr_include_dir}" != "no" ; then BLT_CHECK_HEADER(XRANDR, X11/extensions/randr.h, $blt_with_xrandr_include_dir) fi # ----------------------------------------------------------------------- # Types: # ----------------------------------------------------------------------- AC_TYPE_SIZE_T AC_TYPE_PID_T AC_MSG_CHECKING([whether union wait is defined correctly]) AC_CACHE_VAL(blt_cv_struct_wait_works, AC_TRY_COMPILE([#include <sys/types.h> #include <sys/wait.h>], [ /* * Check whether <sys/wait.h> defines the type "union wait" * correctly. It's needed because of weirdness in HP-UX where * "union wait" is defined in both the BSD and SYS-V environments. * Checking the usability of WIFEXITED seems to do the trick. */ union wait x; WIFEXITED(x); /* Generates compiler error if WIFEXITED * uses an int. */ ], [blt_cv_struct_wait_works="yes"], [blt_cv_struct_wait_works="no"])) if test "${blt_cv_struct_wait_works}" = "yes"; then AC_DEFINE([HAVE_UNION_WAIT], 1, [Define if 'wait' is a union.]) fi AC_MSG_RESULT([$blt_cv_struct_wait_works]) # ----------------------------------------------------------------------- # # Library Functions: Check for drand48, and srand48. # # ----------------------------------------------------------------------- AC_HAVE_FUNCS(strtolower strcasecmp strncasecmp drand48 srand48 finite isnan) # For HPUX it's a little more complicated to search for isfinite AC_MSG_CHECKING([for isfinite]) AC_CACHE_VAL(blt_cv_have_isfinite, AC_TRY_LINK([#include <math.h>], [ double x = 1.0; if (isfinite(x)) { return 0; } ], [blt_cv_have_isfinite="yes"], [blt_cv_have_isfinite="no"])) if test "${blt_cv_have_isfinite}" = "yes"; then AC_DEFINE([HAVE_ISFINITE], 1, [Define if we have a working 'isinfinite'.]) fi AC_MSG_RESULT([$blt_cv_have_isfinite]) # ----------------------------------------------------------------------- # # Check the smallest value such that 1.0 + x != 1.0. # For ANSI compilers this is DBL_EPSILON in float.h # #-------------------------------------------------------------------- AC_MSG_CHECKING([whether DBL_EPSILON is defined in float.h]) AC_CACHE_VAL(blt_cv_found_dbl_epsilon, AC_TRY_COMPILE([ #ifdef HAVE_FLOAT_H #include <float.h> #endif ], [ #ifdef DBL_EPSILON exit(0); #else exit(1); #endif ], blt_cv_found_dbl_epsilon=yes, blt_cv_found_dbl_epsilon=no) ) AC_MSG_RESULT([${blt_cv_found_dbl_epsilon}]) if test "${blt_cv_found_dbl_epsilon}" = "no" ; then AC_CACHE_VAL([blt_cv_dbl_epsilon], old_flags="$CFLAGS" CFLAGS="-lm" AC_MSG_CHECKING([whether DBL_EPSILON can be computed.]) BLT_RUN_WITH_OUTPUT([blt_cv_dbl_epsilon], [ main () { double e, u; /* * Check the smallest value such that 1.0 + x != 1.0. * For ANSI compilers this is DBL_EPSILON in float.h */ u = 1.0; for(;;) { u *= 0.5; if ((1.0 + u) == 1.0) { break; } } e = u * 2.0; printf("%.17e\n", e); exit(0); }]) CFLAGS="$old_flags" AC_DEFINE_UNQUOTED([BLT_DBL_EPSILON], ${blt_cv_dbl_epsilon}, [Define the smallest machine value DBL_EPILSON.]) AC_MSG_RESULT([${blt_cv_dbl_epsilon}]) ) fi AC_CHECK_DECLS(strcasecmp,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(strncasecmp,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(strtolower,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(drand48,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(srand48,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(j1,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(hypot,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(isnan,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(isfinite,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(finite,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif #ifdef HAVE_MATH_H #include <math.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) AC_CHECK_DECLS(free,,,[ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #ifdef HAVE_MEMORY_H #include <memory.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ ]) # ----------------------------------------------------------------------- # # System services: X, Tcl, Tk # # ----------------------------------------------------------------------- if test "x${x_libraries}" = "x" ; then X11_LIB_SPEC="-lX11" else X11_LIB_SPEC="-L${x_libraries} -lX11" fi if test "x${x_includes}" = "x" ; then X11_INC_SPEC="" else X11_INC_SPEC="-I${x_includes}" fi case "$target_cpu" in [i[3-9]86|x86*|k5|k6|k6-2|k6-3|pentium*|athlon*]) AC_DEFINE([HAVE_X86], 1, [Define if we're compiling for an X86.]) ;; *) ;; esac # ----------------------------------------------------------------------- # # Find the Tcl build configuration file "tclConfig.sh" # # ----------------------------------------------------------------------- AC_MSG_CHECKING([for tclConfig.sh]) tcl_config_sh="" if test "x$blt_with_tcl" != "x" ; then # Verify that a tclConfig.sh file exists in the directory specified # by --with-tcl. for dir in \ $blt_with_tcl do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break elif test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done elif test "${blt_with_tcl_include_dir}" = "yes" -a \ "${blt_with_tcl_lib_dir}" = "yes" ; then # Otherwise, search for Tcl configuration file. # 1. Search previously named locations. for dir in \ $prefix \ $exec_prefix \ $blt_cv_tcl_lib do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break elif test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done # 2. Search source directories. if test "x$tcl_config_sh" = "x" ; then for dir in \ `ls -dr ../tcl[[7-9]].[[0-9]]* 2>/dev/null` \ ../tcl \ `ls -dr ../../tcl[[7-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../../tcl[[7-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl do if test -r "$dir/$blt_platform/tclConfig.sh" ; then tcl_config_sh="$dir/$blt_platform/tclConfig.sh" break fi done fi # 3. Search standard locations. if test "x$tcl_config_sh" = "x" ; then for dir in \ /usr/local \ /usr do if test -r "$dir/tclConfig.sh" ; then tcl_config_sh="$dir/tclConfig.sh" break elif test -r "$dir/lib/tclConfig.sh" ; then tcl_config_sh="$dir/lib/tclConfig.sh" break fi done fi fi AC_MSG_RESULT([${tcl_config_sh}]) # ----------------------------------------------------------------------- # # Find the Tk build configuration file "tkConfig.sh" # # ----------------------------------------------------------------------- AC_MSG_CHECKING([for tkConfig.sh]) tk_config_sh="" if test "x$blt_with_tk" != "x" -o "x$blt_with_tcl" != "x"; then # Verify that a tkConfig.sh file exists in the directory specified # by --with-tcl or --with-tk. for dir in \ $blt_with_tk \ $blt_with_tcl do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break elif test -r "$dir/$blt_platform/tkConfig.sh" ; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done elif test "${blt_with_tk_include_dir}" = "yes" -a \ "${blt_with_tk_lib_dir}" = "yes" ; then # Search for Tk configuration file. # 1. Search previously named locations. for dir in \ $prefix \ $exec_prefix \ $blt_cv_tk_lib \ $blt_cv_tcl_lib do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break elif test -r "$dir/$blt_platform/tkConfig.sh" ; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done # 2. Search source directories. if test "x$tk_config_sh" = "x" ; then for dir in \ ../tcl \ `ls -dr ../tk[[4-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tk[[4-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tk[[4-9]].[[0-9]]* 2>/dev/null` do if test -r "$dir/$blt_platform/tkConfig.sh"; then tk_config_sh="$dir/$blt_platform/tkConfig.sh" break fi done fi # 3. Search standard locations. if test "x$tk_config_sh" = "x" ; then for dir in \ /usr/local \ ${x_libraries} \ /usr do if test -r "$dir/tkConfig.sh" ; then tk_config_sh="$dir/tkConfig.sh" break elif test -r "$dir/lib/tkConfig.sh" ; then tk_config_sh="$dir/lib/tkConfig.sh" break fi done fi fi AC_MSG_RESULT([${tk_config_sh}]) # ----------------------------------------------------------------------- # # Source in the Tcl/Tk configuration scripts. # # # Check for tclConfig.sh and tkConfig.sh. If found use values # in file, but don't check if libraries exist. # # ----------------------------------------------------------------------- if test "x${tcl_config_sh}" != "x" ; then . $tcl_config_sh TCL_INC_SPEC=${TCL_INCLUDE_SPEC} fi if test "x${tk_config_sh}" != "x" ; then . $tk_config_sh TK_INC_SPEC=${TK_INCLUDE_SPEC} fi tcl_includes_dir="" tk_includes_dir="" TCL_INC_SPEC=${TCL_INCLUDE_SPEC} TK_INC_SPEC=${TK_INCLUDE_SPEC} if test "${blt_with_tcl_include_dir}" = "no" ; then AC_ERROR([Can't find tcl.h: use --with-tclincdir switch]) elif test "${blt_with_tcl_include_dir}" != "yes" ; then if test -r "${blt_with_tcl_include_dir}/tcl.h" ; then tcl_includes_dir=${blt_with_tcl_include_dir} TCL_INC_SPEC="-I${tcl_includes_dir}" BLT_GET_SYMBOL(TCL_MAJOR_VERSION, TCL_MAJOR_VERSION, [${tcl_includes_dir}/tcl.h]) BLT_GET_SYMBOL(TCL_MINOR_VERSION, TCL_MINOR_VERSION, [${tcl_includes_dir}/tcl.h]) TCL_VERSION=${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION} else AC_ERROR([Can't find tcl.h in \"${blt_with_tcl_include_dir}\"]) fi else for dir in \ ${TCL_PREFIX}/include \ ${TCL_SRC_DIR}/generic \ /usr/local/include \ /usr/include do if test -r "$dir/tcl.h" ; then tcl_includes_dir=$dir break fi done if test "x${tcl_includes_dir}" = "x" ; then AC_ERROR([Can't find tcl.h header file.]) fi fi if test "${blt_with_tk_include_dir}" = "no" ; then AC_ERROR([Can't find tk.h: use --with-tkincdir switch]) elif test "${blt_with_tk_include_dir}" != "yes" ; then if test -r "${blt_with_tk_include_dir}/tk.h" ; then tk_includes_dir=${blt_with_tk_include_dir} TK_INC_SPEC="-I${tk_includes_dir}" BLT_GET_SYMBOL(TK_MAJOR_VERSION, TK_MAJOR_VERSION, ${tk_includes_dir}/tk.h) BLT_GET_SYMBOL(TK_MINOR_VERSION, TK_MINOR_VERSION, ${tk_includes_dir}/tk.h) TK_VERSION=${TK_MAJOR_VERSION}.${TK_MINOR_VERSION} else AC_ERROR([Can't find tk.h in \"${blt_with_tk_include_dir}\"]) fi else for dir in \ ${TK_PREFIX}/include \ ${TK_SRC_DIR}/generic \ ${tcl_includes_dir} \ /usr/local/include \ /usr/include do if test -r "$dir/tk.h" ; then tk_includes_dir=$dir break fi done if test "x${tk_includes_dir}" = "x" ; then AC_ERROR([Can't find tk.h header file.]) fi fi case $target in *-sunos4*|*-*-netbsd|NetBSD-*|FreeBSD-*|OpenBSD-*|*-*-cygwin*|*-*-mingw*) TCL_LIB_VERSION="${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}" TK_LIB_VERSION="${TK_MAJOR_VERSION}${TK_MINOR_VERSION}" ;; *) TCL_LIB_VERSION="${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}" TK_LIB_VERSION="${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}" ;; esac if test "${blt_with_tcl_lib_dir}" = "no" ; then AC_ERROR([Can't find Tcl library: use --with-tcllibdir switch]) elif test "${blt_with_tcl_lib_dir}" = "yes" ; then for libname in \ "${TCL_EXEC_PREFIX}/lib/${SO_PREFIX}tcl${TCL_LIB_VERSION}${SO_EXT}" \ "${TCL_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}${IMPLIB_EXT}" \ "${TCL_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}.lib" \ "${TCL_EXEC_PREFIX}/lib/libtcl${TCL_LIB_VERSION}.a" do if test -r "$libname" ; then TCL_LIB_DIR="${TCL_EXEC_PREFIX}/lib" TCL_LIB_SPEC="-L${TCL_LIB_DIR} -ltcl${TCL_LIB_VERSION}" break fi done else for libname in \ "${blt_with_tcl_lib_dir}/${SO_PREFIX}tcl${TCL_LIB_VERSION}${SO_EXT}" \ "${blt_with_tcl_lib_dir}/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}${IMPLIB_EXT}" \ "${blt_with_tcl_lib_dir}/${IMPLIB_PREFIX}tcl${TCL_LIB_VERSION}.lib" \ "${blt_with_tcl_lib_dir}/libtcl${TCL_LIB_VERSION}.a" do if test -r "$libname" ; then TCL_LIB_DIR="${blt_with_tcl_lib_dir}" TCL_LIB_SPEC="-L${TCL_LIB_DIR} -ltcl${TCL_LIB_VERSION}" break fi done fi if test "x${TCL_LIB_DIR}" = "x" ; then AC_ERROR([Can't find tcl library ${libname} in \"${blt_with_tcl_lib_dir}\"]) fi if test "${blt_with_tk_lib_dir}" = "no" ; then AC_ERROR([Can't find Tcl library: use --with-tcllibdir switch]) elif test "${blt_with_tk_lib_dir}" = "yes" ; then for libname in \ "${TK_EXEC_PREFIX}/lib/${SO_PREFIX}tk${TK_LIB_VERSION}${SO_EXT}" \ "${TK_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}${IMPLIB_EXT}" \ "${TK_EXEC_PREFIX}/lib/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}.lib" \ "${TK_EXEC_PREFIX}/lib/libtk${TK_LIB_VERSION}.a" do if test -r "$libname" ; then TK_LIB_DIR="${TK_EXEC_PREFIX}/lib" TK_LIB_SPEC="-L${TK_LIB_DIR} -ltk${TK_LIB_VERSION}" break fi done else for libname in \ "${blt_with_tk_lib_dir}/${SO_PREFIX}tk${TK_LIB_VERSION}${SO_EXT}" \ "${blt_with_tk_lib_dir}/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}${IMPLIB_EXT}" \ "${blt_with_tk_lib_dir}/${IMPLIB_PREFIX}tk${TK_LIB_VERSION}$.lib" \ "${blt_with_tk_lib_dir}/libtk${TK_LIB_VERSION}.a" do if test -r "$libname" ; then TK_LIB_DIR="${blt_with_tk_lib_dir}" TK_LIB_SPEC="-L${TK_LIB_DIR} -ltk${TK_LIB_VERSION}" break fi done fi if test "x${TK_LIB_DIR}" = "x" ; then AC_ERROR([Can't find tk library.]) fi # ----------------------------------------------------------------------- # # Include files # # Append to INC_SPECS the various include files specifications # (built fromt the include directory information). # # ----------------------------------------------------------------------- # Tk include files if test "${tk_includes_dir}" != "/usr/include" ; then INC_SPECS="${INC_SPECS} ${TK_INC_SPEC}" fi # Tcl include files # # Add the include directory specification only if the Tcl # headers reside in a different directory from Tk's. if test "${tcl_includes_dir}" != "/usr/include" -a \ "${tcl_includes_dir}" != "${tk_includes_dir}" ; then INC_SPECS="${INC_SPECS} ${TCL_INC_SPEC}" fi # On Windows, override the default include directory with our own. if test "${blt_platform}" = "win"; then x_includes="NONE" fi # X11 include files if test "x${x_includes}" != "x" -a \ "${x_includes}" != "NONE" -a \ "${x_includes}" != "/usr/include" -a \ "${x_includes}" != "${tk_includes_dir}" -a \ "${x_includes}" != "${tcl_includes_dir}" ; then INC_SPECS="${INC_SPECS} -I${x_includes}" fi # ----------------------------------------------------------------------- # # Libraries # # Append to LIB the various library specifications # (built from the library directory information). # # ----------------------------------------------------------------------- # Collect the libraries for AIX that aren't using stubs. aix_lib_specs=$LIBS if test "${blt_platform}" = "unix"; then # Add specification for X11 library only on Unix platforms. if test "x${x_libraries}" = "x" -o \ "x${x_libraries}" = "NONE" -o \ "${x_libraries}" = "/usr/lib" -o \ "${x_libraries}" = "/usr/lib64" -o \ "${x_libraries}" = "${TK_LIB_DIR}" -o \ "${x_libraries}" = "${TCL_LIB_DIR}" ; then x_lib_spec="" aix_lib_specs="-lX11 ${aix_lib_specs}" else x_lib_spec="-L${x_libraries}" aix_lib_specs="-L${x_libraries} -lX11 ${aix_lib_specs}" if test "x${loader_run_path}" = "x" ; then loader_run_path="${x_libraries}" else loader_run_path="${loader_run_path}:${x_libraries}" fi fi fi # EXPAT library if test "${blt_with_expat_lib_dir}" != "no" -a \ "${ac_cv_header_expat_h}" != "no" ; then BLT_CHECK_LIBRARY(EXPAT, expat, XML_ParserCreate, $blt_with_expat_lib_dir) fi # MYSQL client library if test "${blt_with_mysql_lib_dir}" != "no" -a \ "${ac_cv_header_mysql_mysql_h}" != "no" ; then BLT_CHECK_LIBRARY(MYSQL, mysqlclient, mysql_init, $blt_with_mysql_lib_dir) fi # JPEG library if test "${blt_with_jpeg_lib_dir}" != "no" -a \ "${ac_cv_header_jpeglib_h}" != "no" ; then BLT_CHECK_LIBRARY(JPG, jpeg, jpeg_read_header, $blt_with_jpeg_lib_dir) fi # TIFF library if test "${blt_with_tiff_lib_dir}" != "no" -a \ "${ac_cv_header_tiff_h}" != "no" ; then BLT_CHECK_LIBRARY(TIF, tiff, TIFFReadRGBAImage, $blt_with_tiff_lib_dir, -lz) fi # PNG library if test "${blt_with_png_lib_dir}" != "no" -a \ "${ac_cv_header_png_h}" != "no" ; then BLT_CHECK_LIBRARY(PNG, png, png_read_png, $blt_with_png_lib_dir, -lz) fi # zlib library if test "${blt_with_z_lib_dir}" != "no" ; then BLT_CHECK_LIBRARY(Z, z, deflate, $blt_with_z_lib_dir) fi # XPM library old_CFLAGS=$CFLAGS CFLAGS=$X11_LIB_SPEC if test "${blt_with_xpm_lib_dir}" != "no" -a \ "${ac_cv_header_xpm_h}" != "no" ; then BLT_CHECK_LIBRARY(XPM, Xpm, XpmCreateXpmImageFromBuffer, $blt_with_xpm_lib_dir) fi # FREETYPE library if test "${blt_with_ft2_lib_dir}" != "no" -a \ "${ac_cv_header_ft2build_h}" != "no" ; then BLT_CHECK_LIBRARY(FT2, freetype, FT_Init_FreeType, $blt_with_ft2_lib_dir) fi # Xft library if test "${blt_with_xft2_lib_dir}" != "no" -a \ "${ac_cv_header_x11_xft_xft_h}" != "no" ; then BLT_CHECK_LIBRARY(XFT, [Xft -lexpat], XftFontOpenPattern, $blt_with_xft_lib_dir) BLT_CHECK_LIBRARY(FTCFG, fontconfig, FcPatternCreate, yes) BLT_CHECK_LIBRARY(XRENDER, Xrender, XRenderQueryExtension, yes) fi # Xrandr library BLT_CHECK_LIBRARY(XRANDR, Xrandr, XRRGetScreenInfo, yes) BLT_CHECK_LIBRARY(XDMCP, Xdmcp, XdmcpWrap, yes) BLT_CHECK_LIBRARY(XAU, Xau, XauReadAuth, yes) CFLAGS=$old_CFLAGS # Tcl libraries if test "${TCL_LIB_DIR}" != "/usr/lib" -a \ "${TCL_LIB_DIR}" != "/usr/lib64" -a \ "${TCL_LIB_DIR}" != "${TK_LIB_DIR}" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${TCL_LIB_DIR}" else loader_run_path="${TCL_LIB_DIR}:${loader_run_path}" fi fi # Tk libraries if test "${TK_LIB_DIR}" != "/usr/lib" -a \ "${TK_LIB_DIR}" != "/usr/lib64" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${TK_LIB_DIR}" else loader_run_path="${TK_LIB_DIR}:${loader_run_path}" fi fi # ----------------------------------------------------------------------- # # Set up a new default prefix to installation path. The ways # the prefix can be set and their precedence are as follows: # # 1. --prefix option given to ./configure. (prefix != NONE) # 2. use previously configured Tk prefix # # ----------------------------------------------------------------------- if test "$prefix" = "NONE" ; then prefix=${TCL_PREFIX} fi if test "$exec_prefix" = "NONE" ; then exec_prefix=${TCL_EXEC_PREFIX} fi # ------------------------------------------------------------------------- # # Extract the BLT version number for the blt.h header # # ------------------------------------------------------------------------- AC_MSG_CHECKING([BLT_MAJOR_VERSION]) AC_CACHE_VAL(blt_cv_major_version, BLT_GET_SYMBOL(blt_cv_major_version, BLT_MAJOR_VERSION, ${srcdir}/src/blt.h) ) BLT_MAJOR_VERSION=${blt_cv_major_version} AC_MSG_RESULT([$blt_cv_major_version]) AC_MSG_CHECKING([BLT_MINOR_VERSION]) AC_CACHE_VAL(blt_cv_minor_version, BLT_GET_SYMBOL(blt_cv_minor_version, BLT_MINOR_VERSION, ${srcdir}/src/blt.h) ) AC_MSG_RESULT([$blt_cv_minor_version]) BLT_MINOR_VERSION=${blt_cv_minor_version} BLT_VERSION=${BLT_MAJOR_VERSION}.${BLT_MINOR_VERSION} # Add BLT to the run path libdir=${exec_prefix}/lib if test "x${libdir}" != "x" -a \ "${libdir}" != "/usr/lib" -a \ "${libdir}" != "/usr/lib64" -a \ "${libdir}" != "${x_libraries}" -a \ "${libdir}" != "${TK_LIB_DIR}" -a \ "${libdir}" != "${TCL_LIB_DIR}" ; then if test "x${loader_run_path}" = "x" ; then loader_run_path="${libdir}" else loader_run_path="${libdir}:${loader_run_path}" fi fi # ------------------------------------------------------------------------- # # Extract the Tcl version number for the tcl.h header # # ------------------------------------------------------------------------- if test "$TCL_VERSION" = "7.6" -a "$TK_VERSION" = "4.2" ; then : elif test "$TCL_VERSION" = "7.5" -a "$TK_VERSION" = "4.1" ; then : elif test "$TCL_VERSION" = "$TK_VERSION" ; then : else AC_ERROR([Mismatched Tcl/Tk versions ($TCL_VERSION != $TK_VERSION)]) fi #-------------------------------------------------------------------- # # Check if we can generate shared libraries on this system. Set flags # to generate shared libraries for systems that we know about. Start # with the values found in tclConfig.sh, make changes as we know about # the different systems. # #-------------------------------------------------------------------- LIB_BASE_NAME=libBLT # Initialize shared library build variables SO_LD="$TCL_SHLIB_LD" SO_LDFLAGS="$TCL_LD_FLAGS" SO_RUNPATH="$TCL_LD_SEARCH_FLAGS" SO_TARGET="" SO_CFLAGS="" SO_LIBS="" LDFLAGS="" LD_RUN_PATH="" EXTRA_LIBS="" case $target in *-aix4.[[2-9]]*) # No Position-Independent flags needed SO_CFLAGS="" # Use the installed export file or the one found in the source directory. if test -r "${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" ; then tcl_exp="${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" else tcl_exp="${TCL_SRC_DIR}/unix/lib.exp" fi if test -r "${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" ; then tk_exp="${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" else tk_exp="${TK_SRC_DIR}/unix/lib.exp" fi full_src_path=`cd ${srcdir}; pwd` # Use shell-script to link shared library SO_LD="${full_src_path}/cf/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -bI:${tk_exp} -bI:${tcl_exp}" SO_LIBS="${aix_lib_specs} -lc" LDFLAGS="-L${loader_run_path}" EXTRA_LIBS="-ldl" ;; *-aix*) # No Position-Independent flags needed SO_CFLAGS="" # Use the installed export file or the one found in the source directory. if test -r "${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" ; then tcl_exp="${TCL_LIB_DIR}/libtcl${TCL_LIB_VERSION}.exp" else tcl_exp="${TCL_SRC_DIR}/unix/lib.exp" fi if test -r "${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" ; then tk_exp="${TK_LIB_DIR}/libtk${TK_LIB_VERSION}.exp" else tk_exp="${TK_SRC_DIR}/unix/lib.exp" fi full_src_path=`cd ${srcdir}/cf; pwd` # Use shell-script to link shared library SO_LD="${full_src_path}/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -bI:${tk_exp} -bI:${tcl_exp}" SO_LIBS="${aix_lib_specs} -lc" LDFLAGS="-L${loader_run_path}" EXTRA_LIBS="-lld" ;; *-bsdi2*|*-bsdi3*) SO_CFLAGS="" SO_LD="shlicc" SO_LDFLAGS="-r" EXTRA_LIBS="-ldl" ;; *-bsdi4*) SO_CFLAGS="-export-dynamic -fPIC" SO_LD="${CC}" SO_LDFLAGS='-shared -Wl,-E -Wl,-soname,$@' ;; *-*-cygwin* | *-*-mingw*) SO_LD="${CC}" SO_LDFLAGS='-shared -Wl,-E -Wl,--out-implib,$@' EXTRA_LIBS="-lwinspool" SO_EXT=".dll" LDFLAGS="" ;; *-*-darwin*) SO_CFLAGS="-fno-common" SO_EXT=".dylib" SO_LD="${CC}" SO_LDFLAGS="-dynamiclib" AC_MSG_CHECKING([if ld accepts -single_module flag]) save_LDFLAGS=$LDFLAGS LDFLAGS="$SO_LDFLAGS -Wl,-single_module" AC_TRY_LINK(, [int i;], [single_module=yes], [single_module=no]) if test "${single_module}" = "yes" ; then SO_LDFLAGS=$LDFLAGS fi AC_MSG_RESULT([$single_module]) SO_LIBRARY_PATH="DYLD_LIBRARY_PATH" LDFLAGS="" ;; *-dgux*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-hpux*) if test "$blt_have_gcc" = "no" ; then DEFINES="$DEFINES -D_HPUX_SOURCE" fi if test "${blt_have_dld}" = "yes" ; then SO_CFLAGS="+Z" SO_LD="ld" SO_LDFLAGS="-b -E -n +s +b,${loader_run_path}:." SO_EXT=".sl" # The run path is included in both LDFLAGS and SO_LDFLAGS # because SO_LD is ld and LD is cc/gcc. LDFLAGS="-Wl,-E -Wl,+s,+b,${loader_run_path}:." EXTRA_LIBS="-ldld" fi ;; *-irix64-6.5*) SO_CFLAGS="" SO_LD="ld" SO_LDFLAGS="-32 -shared -rdata_shared" LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" ;; *-irix-[56].*|*-irix64-*) SO_CFLAGS="" SO_LD="ld" SO_LDFLAGS="-shared -rdata_shared" LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" if test "$blt_have_gcc" = "yes" ; then SO_CFLAGS="-mabi=n32 $SO_CFLAGS" SO_LDFLAGS="-mabi=n32 $SO_LDFLAGS" LDFLAGS="-mabi=n32 $LDFLAGS" else CFLAGS="-n32 $CFLAGS" LDFLAGS="-n32 $LDFLAGS" fi ;; *-linux*) SO_CFLAGS="-fPIC" SO_LD="${CC}" SO_LDFLAGS='-rdynamic -shared -Wl,-E -Wl,-soname,$@' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" EXTRA_LIBS="-ldl" ;; *-mp-ras-02*) SO_CFLAGS="-G -K PIC" SO_LD="${CC}" SO_LDFLAGS="" ;; *-mp-ras-*) SO_CFLAGS="-G -K PIC" SO_LD="${CC}" SO_LDFLAGS="-Wl,-Bexport" ;; *-ncr-sysv4-*2*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-ncr-sysv4*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G -Wl,-Bexport" LDFLAGS="-Wl,-Bexport" EXTRA_LIBS="-ldl" ;; *-netbsd*|*-freebsd*|*-openbsd*) # Not available on all versions: check for include file. AC_CHECK_HEADER(dlfcn.h, test_ok=yes, test_ok=no) if test "$test_ok" = yes; then SO_CFLAGS="-fpic" SO_LD="ld" SO_LDFLAGS="-Bshareable -x" fi ;; *-nextstep*) SO_CFLAGS="" SO_LD="cc" SO_LDFLAGS="-nostdlib -r" ;; *-osf1-1.[012]*) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SO_CFLAGS="" # Warning: Ugly Makefile Hack # Make package name same as library name SO_LD='ld -R -export $@:' ;; *-osf1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SO_CFLAGS="-fpic" SO_LD="ld -shared" ;; *-osf1V*) # Digital OSF/1 SO_CFLAGS="" SO_LD='ld' SO_LDFLAGS='-shared -expect_unresolved "*"' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" LDFLAGS="" ;; *-sco*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. SO_CFLAGS="-Kpic -belf" SO_LD="ld" SO_LDFLAGS="-G" LDFLAGS="-belf -Wl,-Bexport" ;; *-sni-sysv*) SO_CFLAGS="-K PIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-sunos4*) SO_CFLAGS="-PIC" SO_LD="ld" SO_LDFLAGS="-assert pure-text" EXTRA_LIBS="-ldl" ;; *-solaris2*) SO_CFLAGS="-KPIC" if test "${blt_with_gnu_ld}" = "yes" -a "$blt_have_gcc" = "yes" ; then SO_LD="gcc" SO_LDFLAGS='-rdynamic -shared -Wl,-E -Wl,-soname,$@' LD_RUN_PATH="-Wl,-rpath,${loader_run_path}" else SO_LD="/usr/ccs/bin/ld" SO_LDFLAGS="-G -z text" LD_RUN_PATH="-R ${loader_run_path}" fi EXTRA_LIBS="-ldl" ;; *-mips-dde-sysv*) SO_CFLAGS="-KPIC" SO_LD="cc" SO_LDFLAGS="-G" EXTRA_LIBS="-ldl" ;; *-pc-sysv4* | *-unixware-5*) SO_CFLAGS="-G -KPIC" SO_LD="${CC}" SO_LDFLAGS=" -Wl,-Bexport" ;; *) build_shared="no" ;; esac # If we're running gcc, then set SO_CFLAGS flags for compiling # shared libraries for gcc, instead of those of the vendor's # compiler. if test "$blt_have_gcc" = "yes" ; then if test "$blt_platform_win32" = "no" ; then SO_CFLAGS="-fPIC" fi fi # We can't back link against static versions of Tcl/Tk. # If # ${TCL_SHARED_BUILD} can't be found or isn't "1", assume that # shared libraries weren't built. if test "${TCL_SHARED_BUILD}" != "1" ; then SO_LIBS="" fi if test "${build_shared}" = "yes" -a "$blt_enable_shared" = "yes"; then AC_SUBST(BLT_SO_CFLAGS, "$SO_CFLAGS") AC_SUBST(BLT_TARGET, "shared") AC_SUBST(BLT_SO_LD, "$SO_LD") AC_SUBST(BLT_SO_LDFLAGS, "$SO_LDFLAGS") AC_SUBST(BLT_SO_LIBS, "$SO_LIBS") AC_SUBST(BLT_SO_EXT, "$SO_EXT") AC_SUBST(LD_RUN_PATH) else AC_SUBST(BLT_TARGET, "static") fi AC_DEFINE_UNQUOTED([BLT_SO_EXT], "$SO_EXT", [Define 'soext' as the extension for shared libraries.]) AC_DEFINE_UNQUOTED([BLT_SO_PREFIX], "$SO_PREFIX", [Define 'prefix' as the prefix for shared library names.]) AC_DEFINE_UNQUOTED([BLT_LIB_SUFFIX], "$LIB_SUFFIX", [Define 'suffix' as the suffix for library names.]) AC_SUBST(BLT_SO_PREFIX, "$SO_PREFIX") AC_SUBST(BLT_LIB_SUFFIX, "$LIB_SUFFIX") AC_SUBST(IMPLIB_PREFIX) AC_SUBST(IMPLIB_EXT) if test "${blt_enable_stubs}" = "yes" ; then AC_DEFINE_UNQUOTED([USE_TCL_STUBS], [1], [Define if Tcl stubs are used.]) AC_DEFINE_UNQUOTED([USE_TK_STUBS], [1], [Define if Tk stubs are used.]) TCL_STUBS_SPEC="-L${TCL_LIB_DIR} -ltclstub${TCL_LIB_VERSION}" AC_SUBST(TCL_STUBS_SPEC) TK_STUBS_SPEC="-L${TK_LIB_DIR} -ltkstub${TK_LIB_VERSION}" AC_SUBST(TK_STUBS_SPEC) fi if test "${blt_platform_win32}" = "yes" ; then AC_DEFINE_UNQUOTED([WIN32], [1], [Define if building for Win32.]) fi WIN32=${blt_platform_win32} AC_SUBST(WIN32) AC_SUBST(AUX_LIBS) AC_SUBST(BLT_MAJOR_VERSION) AC_SUBST(BLT_MINOR_VERSION) AC_SUBST(BLT_VERSION) AC_SUBST(CC) AC_SUBST(CFLAGS) AC_SUBST(DEFINES) AC_SUBST(DLL_PREFIX) AC_SUBST(EXPAT_INC_SPEC) AC_SUBST(EXPAT_LIB_SPEC) AC_SUBST(EXTRA_LIBS) AC_SUBST(FT2_INC_SPEC) AC_SUBST(FT2_LIB_SPEC) AC_SUBST(FTCFG_LIB_SPEC) AC_SUBST(GCCFLAGS) AC_SUBST(INCLUDES, ${INC_SPECS}) AC_SUBST(JPG_INC_SPEC) AC_SUBST(JPG_LIB_SPEC) AC_SUBST(LDFLAGS) AC_SUBST(LIBS) AC_SUBST(LIB_PREFIX) AC_SUBST(LIB_SUFFIX) AC_SUBST(MYSQL_INC_SPEC) AC_SUBST(MYSQL_LIB_SPEC) AC_SUBST(PNG_INC_SPEC) AC_SUBST(PNG_LIB_SPEC) AC_SUBST(TCL_DBGX) AC_SUBST(TCL_INC_SPEC) AC_SUBST(TCL_LIB_DIR) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_VERSION) AC_SUBST(TIF_INC_SPEC) AC_SUBST(TIF_LIB_SPEC) AC_SUBST(TK_INC_SPEC) AC_SUBST(TK_LIB_SPEC) AC_SUBST(X11_INC_SPEC) AC_SUBST(X11_LIB_SPEC) AC_SUBST(XAU_LIB_SPEC) AC_SUBST(XDMCP_LIB_SPEC) AC_SUBST(XFT_INC_SPEC) AC_SUBST(XFT_LIB_SPEC) AC_SUBST(XPM_INC_SPEC) AC_SUBST(XPM_LIB_SPEC) AC_SUBST(XRANDR_LIB_SPEC) AC_SUBST(XRENDER_LIB_SPEC) AC_SUBST(Z_LIB_SPEC) #-------------------------------------------------------------------- # The BLT script directory was either specified or we # assume <prefix>/lib #-------------------------------------------------------------------- if test "x${blt_with_scriptdir}" = "x" ; then BLT_LIBRARY="${prefix}/lib/blt${BLT_VERSION}" else BLT_LIBRARY="${blt_with_scriptdir}/blt${BLT_VERSION}" fi AC_SUBST(BLT_LIBRARY) #-------------------------------------------------------------------- # Print out some of the more important settings #-------------------------------------------------------------------- echo "" echo "Configuration results:" echo "" echo " tcl.h found in $TCL_INC_SPEC" echo " tk.h found in $TK_INC_SPEC" echo " X11/Xlib.h found in $x_includes" echo " libtcl${TCL_LIB_VERSION} found in $TCL_LIB_SPEC" echo " libtk${TK_LIB_VERSION} found in $TK_LIB_SPEC" echo " libX11 found in $x_libraries" echo "" echo "Directories where BLT is to be installed:" echo "" echo " \"\$prefix\" is $prefix" echo " \"\$exec_prefix\" is $exec_prefix" echo "" echo " shells to be installed in $bindir" echo " libraries to be installed in $libdir" echo " scripts to be installed in $BLT_LIBRARY" echo " manual pages to be installed in $mandir" echo " MYSQL_LIB_SPEC=$MYSQL_LIB_SPEC" echo " MYSQL_INC_SPEC=$MYSQL_INC_SPEC" echo " EXPAT_LIB_SPEC=$EXPAT_LIB_SPEC" echo " EXPAT_INC_SPEC=$EXPAT_INC_SPEC" echo " FT2_LIB_SPEC=$FT2_LIB_SPEC" echo " FT2_INC_SPEC=$FT2_INC_SPEC" echo " JPG_LIB_SPEC=$JPG_LIB_SPEC" echo " JPG_INC_SPEC=$JPG_INC_SPEC" echo "" #-------------------------------------------------------------------- # # Generate the following Makefiles # # ./Makefile # ./src/Makefile # ./src/shared/Makefile # ./man/Makefile # ./library/Makefile # ./demos/Makefile # #-------------------------------------------------------------------- src_Makefile="src/Makefile" case ${blt_platform} in "win") src_Makefile="src/Makefile:src/Makefile-cyg.in" ;; "macosx") src_Makefile="src/Makefile:src/Makefile-macosx.in" ;; *) ;; esac # -------------------------------------------------------------- # List of files to have be generated from <name>.in files with # autoconf substitutions. # -------------------------------------------------------------- AC_CONFIG_FILES( [ Makefile ${src_Makefile} src/bltHash.h src/shared/Makefile man/Makefile library/Makefile library/afm/Makefile demos/Makefile ] ) AC_OUTPUT() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/NEWS������������������������������������������������������������������������������0000644�0001750�0001750�00000064060�11462120062�012743� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������FEATURES ======== stripchart The graph's -areapattern, -areaforeground, -areabackground, and -areatile options are now available in the stripchart too. BUG FIXES ========= tree On 64-bit platforms, bltTree.c doesn't compile because of missing macros START_LOGSIZE and MAX_LIST_VALUES. Thanks to Keith W. Johnson <kwjohnson@llnl.gov> for the bug report. general When compiling under Tru64, bltInit.c fails to compile. Again many thanks to Keith W. Johnson <kwjohnson@llnl.gov> for the bug report. vector Vector always uses array variable in global namespace when name is not namespace-qualified. Thanks to Paul Kienzle <pkienzle@jazz.ncnr.nist.gov> for the bug report and example script. Changes from 2.4y to 2.4z FEATURES ======== graph/stripchart/barchart Under Windows, both the "print1" and "print2" operations will pop-up a standard printer dialog when you don't pass a printer argument. graph/stripchart/barchart New -state option for both elements and markers. If "disabled", marker or element isn't eligible for binding events. This is useful when you have lots (>100,000) of data points. graph/stripchart/barchart New axis option -titlealternate lets you place the axis title to the top or right of the axis. This used to automatically happen when you had more than one axis in a margin. This option lets you control it. tree Both "find" and "apply" operations may be given more than one pattern switch (-exact, -glob, or -regexp). This performs a logical "or"--if any one of the pattern matches, the node is a match. tree Both "find" and "apply" operations now have addition switches -keyexact, -keyglob, and -keyregexp (the -key switch works like -keyexact). You may supply more than one switch. This performs a logical "or"--if any one of the pattern matches, the node is a match. graph/stripchart/barchart New axis options -scrollmin and -scrollmax allow you to specify the scroll region. Thanks to both Meaghan Parizeau <Meaghan_Parizeau@srtelecom.com> and Julian H J Loaring <jhjl@bigj.demon.co.uk> for the solution. graph/stripchart/barchart Polygon marker will trigger bindings even if the marker is not filled (-fill "") or has no outline (-linewidth 0). Interior is always considered part of the polygon. tree Tree adaptively restructures data values from a linked list into a hash table when the number of values exceeds 20. configure.in Can build BLT with cygwin (gcc under Windows) distribution. Type ./configure and make to build. Use -disable-cygwin switch to build "mingw" version. Many thanks to Mumit Khan <khan@pluto.xraylith.wisc.edu> for all the hard work of porting the configure.in and Makefiles. BUG FIXES ========= eps Canvas item errors out with "can't get handle to EPS file" message. Thanks to Shamil Daghestani <shamild@hotmail.com> for the bug report. graph/stripchart/barchart Image marker doesn't get scaled correctly when scaling factor is large. Thanks to Paul Kienzle <pkienzle@jazz.ncnr.nist.gov> for the bug report and example script. It really helped. vector "min" and "max" initially don't report the correct value. Many thanks to Alexander Eisenhuth <stacom@stacom-software.de> for the bug report. treeview/tree "show -full $key" operation doesn't work. graph/stripchart/barchart Doesn't display trailing data points when there are more than 65331 points. Thanks to Val Shkolnikov <nvsoft@pacbell.net> for the bug report. vector Vectors leak memory when accessing them through the Tcl array variable. Thanks to Alexander Eisenhuth <stacom@stacom-software.de> for the bug report and especially the test script to demonstrate the problem. treeview/tree In "apply" operation, -regexp, -exact, or -glob switches don't work. Always matches every node. graph/stripchart/barchart Axis "-hide" option no longer accepts "all" value. "all" was supposed to hide the axis *and* all the elements mapped to it. I don't think this option ever worked correctly. It was also unclear whether to hide the legend entry, markers, etc. graph/stripchart/barchart Changing a marker's -hide option doesn't take effect until the graph is redrawn. Thanks to Alex Verstak <averstak@vt.edu> for the bug report. graph/stripchart/barchart Spurious characters in PostScript output generated under Windows. Thanks to Cary D. Renzema <Cary.Renzema@analog.com> for the bug report and sample files. graph/stripchart/barchart "snap" operation core dumps or returns X protocol error depending on arguments. Thanks to Carsten Mortensen <cbm@microlex.dk> for both the bug report and the fix. graph/stripchart/barchart Polygon marker not drawn unless no outline is specified (-linewith 0). Thanks to Nestor Patino <npatino@infovia.com.ar> for the bug report. treeview/tree Tags are removed when tree or treeview widget is destroyed. Many thanks to Todd Copeland <todd.copeland@legerity.com> for the report. treeview/tree "index" operation segfaults when tag is empty. Again thanks to Todd Copeland <todd.copeland@legerity.com> for the report. pkgIndex.tcl Added checks for package directory and its parent when searching for BLT shared library. Thanks to Anton Hartl <toni@devsoft.com> for the bug report. Changes from 2.4x to 2.4y FEATURES ======== tree Added -notags switch to "restore" operation. tree Added additional fields to the tree "dump" format. When trees are restored, will try to reuse old node ids (not always possible). tree Added -label switch to "copy" operation. This lets you relabel the destination node. BUG FIXES ========= graph/stripchart/barchart PostScript output sometimes includes a spurious box around an axis. Thanks to Harvey.Davies@csiro.au for the bug report and example. tabset/tabnotebook On errors tabnotebook grows ad infinitum. Thanks to Terri Fischer <terri@ner.com> for the bug report and example. <general> Tcl_Init fails with "can't find usable init.tcl" when running bltsh or bltwish compile with ActiveTcl. Changed Tcl_AppInit to set global "tclDefaultLibrary" variable. graph "legend get" operation doesn't account for hidden entries (i.e. -label is configured to ""). Thanks to Karl Voskuil <voskuil@ll.mit.edu> for the bug report and the fix. graph NULL pointer referenced (bindingTable) when destroying axis. bgexec File redirection broken under Windows. graph Area under curve not stippled correctly when bitmap is greater than 8x8 (W95/W98) or device context is a metafile (all?). Created XFillPolygon replacement for Windows. tree Node modifiers are incorrectly ignored when first component is a tag. treeview -shadow option no longer accepts empty string (no shadow). Many thanks to Todd Copeland <todd.copeland@legerity.com> for the report. vector Vector "create" operation slows down using #auto as more vectors are created. Thanks to Todd Copeland <todd.copeland@legerity.com> for the bug report. treeview/hiertable Widget doesn't scroll horizontally correctly when -hideleaves is true. Ignores last level when computing world width. treeview/hiertable Deleting a node doesn't remove tag references to it. Thanks to Steven Hafer <steven.hafer@legerity.com> for the bug report. treeview/hiertable Giving the -path option to the "index" operation always fails. Thanks to Paul Robins <paul.robins@st.com> for the bug report. <treeview.mann/hiertable.mann> Documentation for the "get" operation isn't clear that it always returns a list of lists when the -separator option is "" (the default), even when there is only one node specified. Changes from 2.4w to 2.4x FEATURES ======== dragdrop Back ported 8.3 "dde" command for use with 8.0. BUG FIXES ========= treeview/hiertable Can't create column that starts with a minus. Thanks to Todd Copeland <todd.copeland@legerity.com> for the bug report. <Makefile.in> pkgIndex.tcl file not getting rebuilt. Thanks to Terri Fischer <terri@ner.com> for the bug report and fix. <dragdrop1.tcl,dragdrop2.tcl> Send emulation script isn't needed for Tcl8.0 under Windows. Thanks to Linh H Phan <phan@grover.jpl.nasa.gov> for the bug report. graph/stripchart/barchart Using pen styles results in a bus error. Thanks to Julian H J Loaring <jhjl@bigj.demon.co.uk> for the bug report. hiertable/treeview/tree List of data values is reversed from 2.4v. Thanks to Jorge Suit Prez Ronda <jsperez@bayesinf.com> for the bug report. <bltObjConfig.c> Missing header file for varargs. Thanks to Terri Fischer <terri@ner.com> for the bug report and fix. <bltAlloc.c> TclpAlloc and TclpFree not found in Tcl 8.0. Again, thanks to Terri Fischer <terri@ner.com> for the bug report and fix. <BLT.mann,barchart.mann,eps.mann,graph.mann,tabset.man> Updated manual pages graciously provided by Terri Fischer <terri@ner.com>. Changes from 2.4v to 2.4w FEATURES ======== treeview New treeview widget is updated version of hiertable. Uses Tcl_Objs. The "hiertable" and "treeview" are the 100% syntax compatible. The old hiertable is temporariliy available as "hiertable-old" should you find errors. Also use the "treeview" instead of the "hierbox" widget. The "hierbox" isn't as capable and doesn't use tree data objects. treeview/hiertable Added tagging operations similar to the "tree" command. Attaching a tree to the treeview/hiertable (the -tree option) now gives you access to the tree's tags too. Don't confuse this with "bindtags". For example, you can tag nodes with the "tree" command and operate on them in the treeview/hiertable widget using that tag. If you don't want to share tags, the -newtags option will prevent this. There's an update "treeview" manual entry to describe this. treeview/hiertable The "nearest" operation can report what part of the entry the pointer is over. If a variable name argument is given, the variable will contain either "button", "label", "icon", or "". eps/winop Faster image zooming and rotation (fixed-point arithmetic). BUG FIXES ========= vector Test of real number in a range is broken. Thanks to Paul Robins for the bug report. treeview/hiertable "nearest" operation doesn't allow an optional "variable" argument. hiertable/hierbox The -selectioncommand command is invoked when closing an entry with no selected descendants. Thanks to Jorge Suit Prez Ronda <jsperez@bayesinf.com> for the bug report. hiertable/hierbox In single "mode", the selection anchor is not updated when the selection is moved via the keyboard. Thanks to Jorge Suit Prez Ronda <jsperez@bayesinf.com> for the bug report. hiertable Editor overwrites memory (seen best under Windows). hiertable The "open" and "close" operations don't check for no arguments. hiertable Vertical dotted lines start on wrong y-coordinate when clipped. hiertable Active button isn't clipped by column titles. hiertable Column titles are still displayed and picked despite -showtitles set to "no". hiertable Editor doesn't automatically select acquired text. hiertable Moving the cursor in the editor doesn't clear the selection. hiertable Typing a "space" doesn't replace the selection with a space. tree Traces on the same node loop infinitely. TRACE_ACTIVE flag not set/unset. tree The "restore" and "restorefile" operations don't handle newlines in data key/values, node labels, or tags. graph/barchart/stripchart Crosshairs left on screen when the mouse is pulled quicky from the widget. graph/barchart/stripchart Spurious crosshairs also left on the screen if axes are reconfigured (active axes). graph/barchart/stripchart Image marker not updated if image is changed. graph/barchart/stripchart PostScript not generated for -showvalues option. graph/barchart/stripchart PostScript not generated for errorbars. bgexec No check for wrong number of arguments if switch is present. <bltAlloc.c> Blt_MallocProcPtr and Blt_FreeProcPtr not declared extern in bltInt.h <bltTile.c> Bogus test for mask in Blt_TilePolygon routine. <bltImage.c> Counter for transparent pixels wrong in Win32 version of Blt_PolygonMask. <bltInit.c> blt_version not set when dynamically loaded into wish83.exe. Note: Stub support is still missing although patches have been graciously provided for the 2.4q release. This will be added as soon as I can get some free time. Changes from 2.4u to 2.4v FEATURES ======== bgexec New -linebuffered switch. bgexec myVar -linebuffered yes -onoutput ShowLine myProg & This option lets you process updated data (-onerror, -onoutput, -error, or -output) on a line by line basis. Normally notifications occur once for entire data block. This switch causes separate notifications to made for each complete line. bgexec New -decodeoutput and -decodeerror switches. bgexec myVar -decodeoutput unicode -output myOut myProg & Translates data from the specified encoding to UTF before passing it to the Tcl interpreter. Normally no translation is made (under Windows CR-LF conversions are made) and the raw, typically ASCII, characters are passed back to the Tcl interpreter. Binary data can be collected with the "binary" encoding. For versions using Tcl 8.1 or greater, data is returned as Tcl byte array object, so you can use the "binary" command to convert it as needed. set out [bgexec myVar -decodeoutput binary myProg] binary scan $myOut f values tree New "dumpfile" and "restorefile" operations to "tree" command. tree Extended -> syntax in tree command to use node names. set data [$tree get root->"fred"->"pebbles"] tree Improved memory handling of large trees. Pool allocators added to reduce overall memory consumption. graph/stripchart/barchart New -buffergraph switch. .graph configure -buffergraph no graph New options to fill area under curve of an element. .graph element configure line1 -areapattern solid .graph element configure line2 -areapattern BLT graph/stripchart/barchart New -reduce option. .graph element configure line1 -abstol 0.5 Designates error tolerance for line simplificiation. Points that vary less than the given tolerance are merged into a single line segment. miscellaneous Can globally replace memory allocation routines by setting pointers Blt_MallocProcPtr and Blt_FreeProcPtr. winop New "rotate" operation lets you rotate photo images. BUG FIXES ========= bgexec Fixed a race condition that caused assertion under Windows to fail. When both stdout and stderr are collected, if the stdout handler finishes first, the memory used by read thread handler could be freed before the stderr pipe was closed. graph/stripchart/barchart PostScript coordinates are no longer integers (screen resolution). graph/stripchart/barchart Polygon markers now clipped properly. vector Vectors can't be mapped to local variables. This was broken in the 2.4r release. Thanks to Johannes Zellner <johannes@zellner.org> for the bug report. vector Tcl command associated with a vector not destroyed when the vector is deleted. Much thanks to Alexander Eisenhuth <stacom@topmail.de> for the bug report and the example script. drag&drop "drag&drop" command fails when multiple formats are specified. Seen in the dragdrop2.tcl demo. spline Incorrectly reports the spline's x-vector to be non-monotonic. Thanks to Chang Li <changl@neatware.com> for the bug report. <pkgIndex.tcl> Fixed pkgIndex.tcl.in to figure out whether to load libBLT24.so or libBLTlite24.so when BLT is loaded, not when the package is registered. Thanks to Dr. Dieter Ruppert <ru@swb.siemens.de> for the bug report and fix. Changes from 2.4t to 2.4u BUG FIXES ========= <./configure> Fixed my stupid error (missing close brace) in ./configure file. <Makefile.in> Makefile in src/shared doesn't define BLT_LIBRARY. Thanks to terri@ner.com (Terri L. Fischer) for the bug report and fix. graph/barchart/stripchart graph doesn't find vector in global namespace when inside of another namespace. Thanks to Julian H J Loaring <bigj@bigj.demon.co.uk> for the bug report. graph/barchart/stripchart Scratch buffer to small for PostScript prolog. Thanks again to Julian H J Loaring <bigj@bigj.demon.co.uk> for the bug report and fix. graph "bind" would fail on elements without traces (-linewidth 0). Thanks again to terri@ner.com (Terri L. Fischer) for the bug report. o Many changes to "dnd" command. + -package option is treated as a command prefix (like the scrollbar), not a script. Percent sign substitutions are no longer allowed. Information is passed via key-value parameters like the -onleave, -ondrop procedures. Procedure must return 1 if operation was Ok, and 0 if it failed. + The command arguments for both the "setdata" and "getdata" operations have changed from an arbitrary Tcl script with percent sign substitutions, to a command prefix with key-value arguments appended. The general form is procName widget args... where args is one of more key value pairs. x Relative X-coordinate of drop or pickup. y Relative Y-coordinate of drop or pickup. timestamp Timestamp of transaction. format Format desired. value Value transfered (setdata only). You can use array set to parse "args". For example: proc GetColor { widget args } { array set info $args puts "x-coordinate is $info(x)" puts "selected format is $info(format)" return [$widget cget -bg] } + If an -onmotion procedure is specified for the target, it is automatically invoked on drops before the -dropcmd is run. If it returns 0, the drop is canceled. + Added ./demos/dnd2.tcl to show more complicated example. Just like dnd1.tcl, you need to run two of them at the same time to see the drag-and-drop operations. + Target property wasn't getting reset when changing -onmotion, -onleave, etc. procedures. + Timestamps now displayed as unsigned. Many thanks to Tom Lane <tgl@sss.pgh.pa.us> for all his help and suggestions. Changes from 2.4s to 2.4t o Tree command syntax changes. Notify and trace operation now work as advertised and a copy operation added. Many thanks to Matt Newman <matt@sensus.org> for meticulously reviewing the command. o graph "snap" operation syntax change. Added support for generating Aldus metafiles and enhanced metafiles under Windows. # Normal syntax. set image [image create photo] .graph snap $image # New additions. .graph snap -format emf myFile.emf ;# Enhanced metafile .graph snap -format wmf myFile.wmf ;# Aldus placable metafile .graph snap -format emf CLIPBOARD ;# Metafile written into clipboard. Old width and height arguments are replaced with -width and -height switches. .graph snap $image 500 500 ;# Old .graph snap -width 500 -height 500 $image ;# New Thanks to Alain Zuur <a.zuur@marlab.ac.uk> for the enhancement. o Tabset/Tabnotebook -selectforeground option for tabs using wrong configuration option type. Both the bug report and fix are from Mark E. Smith <mark@pearl.grand.gdats.com>. Thanks. o graph "bind" to use closest point instead of line segment when element contains only 1 point. Thanks to Uwe Klein <uwe-klein@foni.net> for the bug report and script. o Hiertable tree view column has been internally renamed to "BLT Hiertable widgetName". It was formerly the name of the widget. Fortunately, you can refer to the column as "treeView" instead. .ht column configure treeView -text "View Label" o There's no ".tree" suffix anymore on the default tree created by the hiertable widget. It's now just the widget name. o Many hiertable column bug fixes. Thanks to Julian H J Loaring <bigj@bigj.demon.co.uk> for all the tests and reports. o Rotated text displayed incorrectly under Windows 95/98 using non-TrueType fonts. A test for typetype fonts has been restored. Thanks to James Pakko <jpakko@ford.com> for the bug report and script. Under Windows, Non-TrueType fonts are drawn into a bitmap and the bitmap is rotated. This provides the same quality as using rotated fonts for on-screen display. Unfortunately it's much poorer for higher resolution devices such as printers. The best bet is to simply choose TrueType fonts if you can. o Improved Hiertable folder images. Many thanks to Tom Lane <tgl@sss.pgh.pa.us> for the new images. o Bgexec segfaults under Windows (NT/95) if file handler is deleted inside of callback. Thanks to Chris Oliver <coliver@mminternet.com> for the bug report. o graph segfaults if pen style range min/max are the same. Thanks to Thomas Wu <twu@gene.com> for the bug report and script. o tabnotebook and tabset widgets would generate X11 errors if embedded window was resize to zero width/height. Thanks to Ed Ohsone <eosn@rahul.net> for the report and the script to demonstrate the error. Changes from 2.4r to 2.4s o Fixed bug in stripchart (introduced in 2.4r) allowing uninitialized data to be displayed. Thanks to Dick Gooris <gooris@lucent.com> for the bug report. o AIX dynamic loading. Actually made it work on a 4.3 AIX box. o Fixed -tree option in hiertable. Would segfault if tree was not fully initialized first. o Tree insert operation syntax changed from tree0 insert $node key1 value1 key2 value2 to tree0 insert $node -data { key1 value1 key2 value2 } o Fixed tree label operation. Save uid instead of string. o Bug in TreeEventProc, should be node != NULL instead of node >= 0 Thanks to Julian H J Loaring <bigj@bigj.demon.co.uk> for the bug report. What's new in 2.4? 1. "eps" canvas item. An encapsulated PostScript canvas item lets you embed an EPS file into the canvas. The "eps" item displays either a EPS preview image found in the file, or a Tk image that you provide. 2. "hierbox" and "hiertable" widget. Hierarchical listbox widget. Displays a general ordered tree which may be built on-the-fly or all at once. 3. "tabset" and "tabnotebook" widget. Can be used either as a tab notebook or simple tabset. Tabs can be arranged in a variety of ways: multi-tiered, scrolled, and attached to any of the four sides. Tab labels can contain both images and text (text can be arbitrarily rotated). Notebook pages can be torn-off into separate windows and replaced later. 4. Changes to vectors. New features: o Vector expressions. The vector now has an "expr" operation that lets you perform math (including math library functions) on vectors. There are several new functions (such as "max", "min", "mean" "median", "q1", "q3", "prod", "sum", "adev", "sdev", "skew", ...) vector expr { sin(x)^2 + cos(x)^2 } y expr { log(x) * $value } o New syntax to create and destroy vectors: vector create x vector destroy x The old syntax for creating vectors still works. vector x o Vectors are *not* automatically deleted when their Tcl variable is unset anymore. This means that you can temporarily map vectors to variables and use them as you would an ordinary Tcl array (kind of like "upvar"). proc AddValue { vecName value } { $vecName variable x set x(++end) $value } There's an "-watchunset" flag to restore the old behavior if you need it. vector create x -watchunset yes o Vectors still automatically create Tcl variables by default. I'd like to change this, but it silently breaks lots of code, so it will stay. Bug fixes: o Vector reallocation failed when shrinking the vector. o Vector "destroy" callback made after vector was already freed. o Fixed vector/scalar operations. o Always store results in temporary, so not to overwrite accidently current vector values. 5. Changes to Graph, Barchart, Stripchart widgets. New features: o Drop shadows for text (titles, markers, etc). Drop shadows improve contrast when displaying text over a background with similar color intensities. o Postscript "-preview" option to generate a EPS PostScript preview image that can be read and displayed by the EPS canvas item. o New "-topvariable", "-bottomvariable", "-leftvariable", and "-rightvariable" options. They specify variables to contain the current margin sizes. These variables are updated whenever the graph is redrawn. o New "-aspect" option. Let's you maintain a particular aspect ratio for the the graph. o Image markers can now be stretched and zoomed like bitmap markers. o Bind operation for legend entries, markers, and elements. Much thanks to Julian Loaring <bigj@bigj.demon.co.uk> for the idea. o New "-xor" option for line markers, lets you draw the line by rubberbanded by XOR-ing without requiring the graph to be redrawn. This can be used, for example, to select regions for zooming. Thanks to Johannes Zellner (joze@krisal.physik.uni-karlsruhe.de) for the idea. o Can attach a scrollbar to an axis. .sbar configure -command { .graph axis view y } .graph axis configure y -scrollcommand { .sbar set } Bug fixes: o Closest line (point) broken when using pens styles. o Marker elastic coordinates were wrong. o PostScript bounding box included the border of the page. o Bad PostScript generated for barchart symbols with stipples. o Wrong dimensions computed with postscript " -maxpect" option. o Text markers fixed. Thanks to De Clarke for the bug report and fix. o Renamed axis configuration from "-range" to "-autorange" to match the documentation. Thanks to Brian Smith for the correction. o Fixed polygon marker pick routine. o Fixed active tab labels overlapping the selected tab. o PostScript graph footer turned off by default. Use -footer option to turn on. .graph postscript configure -footer yes ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/aclocal.m4������������������������������������������������������������������������0000644�0001750�0001750�00000005376�11462120062�014111� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������dnl BLT_RUN_WITH_OUTPUT(VARIABLE, PROGRAM,) AC_DEFUN(BLT_RUN_WITH_OUTPUT, [AC_REQUIRE([AC_PROG_CC])dnl if test "$cross_compiling" = yes; then ifelse([$3], , [errprint(__file__:__line__: warning: [AC_TRY_RUN_WITH_OUTPUT] called without default to allow cross compiling )dnl AC_MSG_ERROR(can not run test program while cross compiling)], [$3]) else cat > conftest.$ac_ext <<EOF [#]line __oline__ "configure" [#include "confdefs.h" #ifdef __cplusplus extern "C" void exit(int); #endif ]dnl [$2] EOF eval $ac_link if test -s conftest && (./conftest > ./conftest.stdout; exit) 2>/dev/null; then $1=`cat ./conftest.stdout` else $1="" fi fi rm -fr conftest*]) dnl BLT_GET_SYMBOL(VARIABLE, SYMBOL, FILE) AC_DEFUN(BLT_GET_SYMBOL, [AC_REQUIRE([AC_PROG_AWK])dnl cat > conftest.awk <<EOF [/^# *define *]$2[[ \t]]/ { print [\$][3] } EOF $1=`${AWK} -f conftest.awk "$3"` rm -rf conftest*]) dnl BLT_CHECK_LIBRARY(NAME, SPEC, SYMBOL, WITH, EXTRALIBS) AC_DEFUN(BLT_CHECK_LIBRARY, [ if test "$4" != "no" ; then save_LDFLAGS="${LDFLAGS}" if test "$4" = "yes" ; then lib_spec="-l$2" dir="" LDFLAGS="${lib_spec} ${save_LDFLAGS}" AC_CHECK_LIB([$2], [$3], [found="yes"],[found="no"]) if test "${found}" = "no" ; then lib_spec="-L${dir} -l$2 $5" dir=$exec_prefix/lib LDFLAGS="${lib_spec} ${save_LDFLAGS}" AC_CHECK_LIB([$2], [$3], [found="yes"],[found="no"]) if test "${found}" = "yes" ; then $1_LIB_DIR="$dir" fi fi else for dir in $4 $4/lib ; do lib_spec="-L${dir} -l$2 $5" LDFLAGS="${lib_spec} ${save_LDFLAGS}" AC_CHECK_LIB([$2], [$3],[found="yes"],[found="no"]) if test "${found}" = "yes" ; then $1_LIB_DIR="$dir" break fi done fi if test "${found}" = "yes" ; then AC_DEFINE([HAVE_LIB$1], 1, [Define to 1 if you have the `$1' library (-l$2).]) aix_lib_specs="${aix_lib_specs} ${lib_spec}" $1_LIB_SPEC=${lib_spec} if test "x${dir}" != "x" ; then loader_run_path="${loader_run_path}:${dir}" fi fi LDFLAGS=${save_LDFLAGS} fi ]) dnl BLT_CHECK_HEADER(NAME, SPEC, WITH, DEF) AC_DEFUN(BLT_CHECK_HEADER, [ if test "$3" != "no" ; then new_CPPFLAGS="" if test "$3" != "yes" ; then for dir in $3 $3/include ; do if test -r "${dir}/$2" ; then new_CPPFLAGS="-I${dir}" $1_INC_DIR="$dir" break fi done else for dir in $prefix $prefix/include ; do if test -r "${dir}/$2" ; then new_CPPFLAGS="-I${dir}" $1_INC_DIR="$dir" break fi done fi save_CPPFLAGS=${CPPFLAGS} CPPFLAGS="$4 ${new_CPPFLAGS}" AC_CHECK_HEADERS($2, [$1_INC_SPEC="${new_CPPFLAGS}"], [$1_INC_SPEC=""]) CPPFLAGS=${save_CPPFLAGS} fi ]) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/PROBLEMS��������������������������������������������������������������������������0000644�0001750�0001750�00000013176�11462120062�013414� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Specific problems: 1. I've built BLT, but when I run "bltwish", it doesn't know about any of the BLT commands. % graph .g invalid command name "graph" Starting with Tcl 8.x, the BLT commands are stored in their own namespace called "blt". The idea is to prevent name clashes with Tcl commands and variables from other packages, such as a "table" command in two different packages. You can access the BLT commands in a couple of ways. Prefix the BLT commands with the namespace qualifier "blt::" % blt::graph .g % blt::table . .g -resize both or import the BLT commands into the global namespace. % namespace import blt::* % graph .g % table . .g -resize both 2. I'm try to compile BLT with ActiveState's Tcl/Tk distribution, but all the demos core dump. Look in the "include" directory where you installed ActiveState. Is there an "X11" directory? Remove it and recompile BLT. It contains all the fake X11 headers needed for Windows builds. So it's okay to remove it for Solaris and Linux. 3. Under Windows the "drag&drop" command doesn't work for me. The "drag&drop" command uses the "send" command to communicate between Tk applications and under Windows Tk has no built-in "send" command. In ./demos/scripts/send.tcl there is a "send" look-a-like that uses the DDE package. Source this first and make sure you invoke the procedures "SendInit" and "SendVerify" *before* you create and drag-and-drop targets. 4. I'm using Windows 95/98 and the -stipple option doesn't seem to work. Under Windows 95/98, your bitmap must be exactly 8x8. If you use a bigger or smaller bitmap, Windows won't stipple the pattern correctly. For bitmaps larger than 8x8, only the upper-left 8x8 corner of the bitmap is used. For smaller bitmaps, the bitmap is extended to 8x8 with the new bits 0 (blank). This is a limitation of Windows 95/98, not Tk. 5. I can't run bltwish.exe under Windows with Tcl/Tk version 8.0. Did you compile and install Tcl/Tk yourself? Tcl is expecting a registry key to be set. The installer normally does that for you. The key tells Tcl where to find the Tcl library scripts. Setting the TCL_LIBRARY environment variable to the location of the Tcl script directory (where init.tcl is located) will fix things. Dynamic loading (package require BLT) of BLT should also work. This problem is fixed in later versions of Tcl. 6. I'm on a DEC Alpha running the graph widget. I don't see any ticks or lines. There's a problem with code generated by the GNU C compiler 2.8.[0-1] for bltGrAxis.c and bltGrLine.c (I think it's just these two files). Try compiling with either the native "cc" compiler or compile the two modules with -O0. 7. When I compile BLT on Solaris (maybe others?), I get lots of error messages in the form: <unknown> 0xf44 /usr/local/lib/libtcl7.6.a(tclCmdIL.o) <unknown> 0xf3c /usr/local/lib/libtcl7.6.a(tclCmdIL.o) <unknown> 0x628 /usr/local/lib/libtcl7.6.a(tclCmdIL.o) This is because Tcl and Tk have been installed only as static libraries, not shared libraries. The ./src/shared/Makefile creates the shared BLT library with a back-link to these libraries. The advantage of this link is that when you dynamically load BLT, the correct Tcl/Tk libraries are automatically searched for any unresolved references. You can fix this in one of two ways. o Remove the back-link. Edit ./src/shared/Makefile and cut the "-ltcl* -ltk*" references from the SHLIB_LD_LIBS macro. o Create shared libraries for Tcl and Tk. Re-configure, compile, and install Tcl/Tk from their sources. Make sure you add the "--enable-shared" switch to "configure". ./configure --enable-shared 8. How do I create a shared library of BLT under AIX? Check that Tcl and Tk were both configured with the --enable-shared flag. When you compile each of them, a "lib.exp" file is created in their respective "unix" subdirectories. The lib.exp files are removed when you do a "make clean", so you may need to recompile. The BLT Makefile uses the TCL_SRC_DIR and TK_SRC_DIR values in the tclConfig.sh and tkConfig.sh files to find these lib.exp files. You may need to edit ./src/Makefile/shared to reflect the real paths of the Tcl and Tk source distributions. 9. ./configure can't find the Tcl/Tk libraries (or finds the wrong version). If you build Tcl/Tk Tk with --enable-symbols versions, ./configure won't find the libraries (it's looking for libtcl8.4.a and your library is named libtcl8.4g.a) You need to build Tcl/Tk again, this time with --disable-symbols. General Problems: 1. I can't compile BLT. Send the output of both "./configure" and "make" to me at ghowlett@grandecom.net gah@silconmetrics.com This will make it easier to track down the exact problem. Make sure you put "BLT" in the subject line. 2. I get a segfault when running BLT in my application. The best method is to send a Tcl script that I can run that demonstrates the problem. Make sure you include all the necessary pieces to make it run (e.g. data file). If it's needed, include directions how to make the problem occur (e.g. "double click on the left mouse button"). The hard work you do pruning down the problem into a small script will greatly help solve it. Once I see the problem, I can usually fix it right away. 3. The manual page lies. I appreciate any help in pointing out errors, omissions, or lies in the manuals. If you have ideas how they might be improved, I'd love to hear them. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013341� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph3.tcl������������������������������������������������������������������0000755�0001750�0001750�00000004056�11462120062�015245� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl source scripts/stipples.tcl puts stderr "class=[winfo class .]" set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *Graph3.Button.Background red option add *TextMarker.Foreground black option add *TextMarker.Background yellow option add *LineMarker.Foreground black option add *LineMarker.Background yellow option add *PolyMarker.Fill yellow2 option add *PolyMarker.Outline "" option add *PolyMarker.Stipple fdiagonal1 option add *activeLine.Color red4 option add *activeLine.Fill red2 option add *Element.Color purple } image create picture bgTexture -file ./images/chalk.gif option add *Tile bgTexture option add *Button.Tile "" option add *Text.font { "Serif" 12 } option add *header.font { "Serif" 12 } option add *footer.font { "Serif" 12 } option add *HighlightThickness 0 option add *plotBorderWidth 0 option add *plotPadX 0 option add *plotPadY 0 set graph [blt::graph .g] source scripts/graph3.tcl set text { This is an example of a bitmap marker. Try zooming in on a region by clicking the left button, moving the pointer, and clicking again. Notice that the bitmap scales too. To restore the last view, click on the right button. } blt::htext .header -text $text blt::htext .footer -text {Hit the %% set im [image create picture -file ./images/stopsign.gif] button $htext(widget).quit -image $im -command { exit } $htext(widget) append $htext(widget).quit %% button when you've seen enough. %% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} blt::table . \ .header 0,0 -fill x -padx 4 -pady 4\ $graph 1,0 -fill both \ .footer 2,0 -fill x -padx 4 -pady 4 blt::table configure . r0 r2 -resize none source scripts/ps.tcl bind $graph <Shift-ButtonPress-1> { MakePsLayout $graph } if 0 { set printer [printer open [lindex [printer names] 0]] after 2000 { $graph print2 $printer } } after 2000 { PsDialog $graph } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bgexec1.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000015424�11462120062�015400� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl bitmap define blt.0 {{40 40} { 00 00 00 00 00 00 fc 07 00 00 00 04 08 00 00 00 04 04 00 00 00 e4 03 00 00 00 64 fe 07 00 00 64 02 04 00 00 e4 03 04 00 00 64 7e 02 00 00 64 1a 02 00 00 e4 1b 01 00 00 04 1a 01 00 00 04 1a 01 00 00 fc 1b 02 00 00 0c 1a 02 00 00 0c 02 04 00 00 0c 02 f4 03 80 ed fe 07 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.1 {{40 40} { 00 00 00 00 00 00 fc 07 00 00 00 04 08 00 00 00 04 04 00 00 00 e4 ff 0f 00 00 64 06 08 00 00 64 06 08 00 00 e4 ff 04 00 00 64 36 04 00 00 64 36 02 00 00 e4 37 02 00 00 04 34 02 00 00 04 34 04 00 00 fc 35 04 00 00 0c 04 08 00 00 0c 04 08 00 00 0c fc ef 03 80 ed 01 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.2 {{40 40} { 00 00 00 00 00 00 fc 0f 00 00 00 04 10 00 00 00 04 10 00 00 00 e4 fb 3f 00 00 64 0e 20 00 00 64 0e 20 00 00 e4 fb 13 00 00 64 ce 10 00 00 64 ce 08 00 00 e4 cb 08 00 00 04 c8 08 00 00 04 c8 10 00 00 fc cf 10 00 00 0c 08 20 00 00 0c 08 20 00 00 0c f8 bf 03 80 ed 03 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.3 {{40 40} { 00 00 00 00 00 00 fc 0f 00 00 00 04 f0 ff 00 00 04 00 80 00 00 e4 03 80 00 00 64 d6 4f 00 00 64 16 43 00 00 e4 13 23 00 00 64 16 23 00 00 64 16 23 00 00 e4 13 43 00 00 04 70 43 00 00 04 00 80 00 00 fc 0f 80 00 00 0c f0 ff 00 00 0c 00 00 00 00 0c f8 ff 03 80 ed 07 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.4 {{40 40} { 00 00 00 00 00 00 fc ff ff 03 00 04 00 00 02 00 04 00 00 02 00 e4 33 3f 01 00 64 36 0c 01 00 64 36 8c 00 00 e4 33 8c 00 00 64 36 8c 00 00 64 36 0c 01 00 e4 f3 0d 01 00 04 00 00 02 00 04 00 00 02 00 fc ff ff 03 00 0c 00 00 00 00 0c 00 00 00 00 0c f8 ff 03 80 ed 07 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } #set animate(colors) { #ff8813 #ffaa13 #ffcc13 #ffff13 #ffcc13 #ffaa13 #ff8813 } bitmap define blt.5 [bitmap data blt.3] bitmap define blt.6 [bitmap data blt.2] bitmap define blt.7 [bitmap data blt.1] set interval 200 proc AnimateBitmap { index } { global interval afterId if { ![winfo exists .logo] } { return } if { $index >= 0 } { .logo configure -bitmap blt.$index incr index if { $index >= 7 } { set index 0 } set afterId [after $interval "AnimateBitmap $index"] } } set length 80 option add *text.yScrollCommand { .vscroll set } option add *text.relief sunken option add *text.width $length option add *text.height 10 option add *text.borderWidth 2 option add *vscroll.command { .text yview } option add *vscroll.minSlider 4p option add *quit.command { exit } option add *quit.text { quit } option add *stop.command { set bgStatus {} } option add *stop.text { stop } option add *logo.relief sunken option add *logo.padX 4 option add *title.text "Virtual Memory Statistics" option add *title.font -*-Helvetica-Bold-R-*-*-14-*-*-*-*-*-*-* set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *text.background lightblue option add *text.foreground blue option add *quit.background red option add *quit.foreground white option add *stop.background yellow option add *stop.foreground navyblue option add *logo.background beige option add *logo.foreground brown } # Create widgets text .text scrollbar .vscroll button .quit button .stop label .logo label .title # Layout widgets in table blt::table . \ .title 0,0 -columnspan 4 \ .text 1,0 -columnspan 3 \ .vscroll 1,3 -fill y \ .logo 2,0 -anchor w -padx 10 -reqheight .6i -pady 4 \ .stop 2,1 \ .quit 2,2 set buttonWidth 1i blt::table configure . c1 c2 -width 1i blt::table configure . c3 -resize none blt::table configure . .stop .quit -reqwidth $buttonWidth -anchor e blt::table configure . .title .text -fill both wm min . 0 0 proc DisplayStats { data } { .text insert end "$data\n" set textlen [expr int([.text index end])] scan [.vscroll get] "%s %s %s %s" total window first last if { $textlen > $total } { .text yview [expr $textlen-$window] } update idletasks } set bgStatus {} AnimateBitmap 0 # # Pick a command that # 1) periodically writes output and # 2) flushes output each time. # set command { vmstat 1 } #set command { netstat -c } catch { eval "bgexec bgStatus -onoutput DisplayStats $command" } # Turn off animation by canceling any pending after task. if { [info exists afterId] } { after cancel $afterId } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bgexec4.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000011375�11462120062�015404� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl source scripts/globe.tcl option add *HighlightThickness 0 set program ../src/bltwish if { [info exists tcl_platform ] } { puts stderr $tcl_platform(platform) if { $tcl_platform(platform) == "windows" } { set shells [glob C:/Program\ Files/Tcl/bin/tclsh8*.exe ] set program [lindex $shells 0] } } if { ![file executable $program] } { error "Can't execute $program" } set command [list $program scripts/bgtest.tcl] array set animate { index -1 interval 200 colors "#ff8813 #ffaa13 #ffcc13 #ffff13 #ffcc13 #ffaa13 #ff8813" numBitmaps 30 prefix globe } proc Animate {} { global animate if { [info commands .logo] != ".logo" } { set animate(index) 0 return } if { $animate(index) >= 0 } { .logo configure -bitmap $animate(prefix).$animate(index) incr animate(index) if { $animate(index) >= $animate(numBitmaps) } { set animate(index) 0 } after $animate(interval) Animate } } proc InsertText { string tag } { .text insert end "$tag: " "" $string $tag set textlen [expr int([.text index end])] scan [.vscroll get] "%s %s %s %s" total window first last if { $textlen > $total } { .text yview [expr $textlen-$window] } update idletasks } proc DisplayOutput { name1 name2 how } { upvar #0 $name1 arr InsertText "$arr($name2)\n" stdout set arr($name2) {} } proc DisplayErrors { name1 name2 how } { upvar #0 $name1 arr InsertText "$arr($name2)\n" stderr set arr($name2) {} } option add *text.yScrollCommand { .vscroll set } option add *text.relief sunken option add *text.width 20 option add *text.height 10 option add *text.height 10 option add *text.borderWidth 2 option add *vscroll.command { .text yview } option add *vscroll.minSlider 4p option add *stop.command { set results {} } option add *stop.text { stop } option add *logo.padX 4 option add *title.text "Catching stdout and stderr" option add *title.font -*-Helvetica-Bold-R-*-*-14-*-*-*-*-*-*-* set visual [winfo screenvisual .] if { [string match *color $visual] } { option add *text.background white option add *text.foreground blue option add *stop.background yellow option add *stop.activeBackground yellow2 option add *stop.foreground navyblue option add *start.activeBackground green2 option add *start.background green option add *start.foreground navyblue option add *logo.background beige option add *logo.foreground brown option add *logo.foreground green4 option add *title.background lightblue option add *logo.background lightblue } . configure -bg lightblue trace variable results(stdout) w DisplayOutput trace variable results(stderr) w DisplayErrors proc Start { command } { global results animate .text delete 1.0 end if { $animate(index) < 0 } { set results(status) {} eval "bgexec results(status) -lasterror results(stderr) \ -lastoutput results(stdout) $command &" set animate(index) 0 Animate } } proc Stop { } { global results animate set results(status) {} set animate(index) -1 } # Create widgets text .text .text tag configure stdout -font -*-Helvetica-Bold-R-*-*-18-*-*-*-*-*-*-* \ -foreground green2 .text tag configure stderr -font -*-Helvetica-Medium-O-*-*-18-*-*-*-*-*-*-* \ -foreground red2 scrollbar .vscroll button .start -text "Start" -command [list Start $command] button .stop -text "Stop" -command Stop label .logo -bitmap globe.0 label .title # Layout widgets in table blt::table . \ .title 0,0 -columnspan 4 \ .text 1,0 -columnspan 3 \ .vscroll 1,3 -fill y \ .logo 2,0 -anchor w -padx 10 -reqheight .6i -pady 4 \ .start 2,1 \ .stop 2,2 set buttonWidth 1i blt::table configure . c1 c2 -width 1i blt::table configure . c3 r0 r2 -resize none blt::table configure . .start .stop -reqwidth $buttonWidth -anchor e blt::table configure . .title .text -fill both wm min . 0 0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/barchart2.tcl���������������������������������������������������������������0000755�0001750�0001750�00000014216�11462120062�015730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc FormatXTicks { w value } { # Determine the element name from the value set index [expr round($value)] if { $index != $value } { return $value } incr index -1 set name [lindex { A1 B1 A2 B2 C1 D1 C2 A3 E1 } $index] return $name } source scripts/stipples.tcl #image create picture bgTexture -file ./images/chalk.gif option add *Button.padX 5 option add *Radiobutton.relief flat option add *Radiobutton.borderWidth 2 option add *Radiobutton.highlightThickness 0 option add *Radiobutton.font "Arial 10 bold" option add *Htext.tileOffset no option add *Barchart.title "Comparison of Simulators" option add *x.Command FormatXTicks option add *x.Title "Simulator" option add *y.Title "Time (hrs)" option add *Axis.tickInterior yes option add *plotPadX 0 option add *plotPadY 0 option add *activeBar.Foreground pink option add *activeBar.stipple dot3 option add *Element.Background red option add *Element.Relief solid option add *Grid.dashes { 2 4 } option add *Grid.hide no option add *Grid.mapX "" option add *Legend.activeBorderWidth 2 option add *Legend.activeRelief raised option add *Legend.anchor ne option add *Legend.borderWidth 0 option add *Legend.position right set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *print.background yellow option add *quit.background red option add *quit.activeBackground red2 } blt::htext .title -text {\ Data points with like x-coordinates, can have their bar segments displayed in one of the following modes (using the -barmode option): } blt::htext .header -text { %% blt::tk::radiobutton .header.stacked -text stacked -variable barMode \ -anchor w -value "stacked" -command { .graph configure -barmode $barMode } .header append .header.stacked -width 1.0i -anchor w %% Bars are stacked on top of each other. The overall height is the sum of the y-coordinates. %% blt::tk::radiobutton .header.aligned -text aligned -variable barMode \ -anchor w -value "aligned" -command { .graph configure -barmode $barMode } .header append .header.aligned -width 1.0i -fill x %% Bars are drawn side-by-side at a fraction of their normal width. %% blt::tk::radiobutton .header.overlap -text "overlap" -variable barMode \ -anchor w -value "overlap" -command { .graph configure -barmode $barMode } .header append .header.overlap -width 1.0i -fill x %% Bars overlap slightly. %% blt::tk::radiobutton .header.normal -text "normal" -variable barMode \ -anchor w -value "normal" -command { .graph configure -barmode $barMode } .header append .header.normal -width 1.0i -fill x %% Bars are overlayed one on top of the next. } blt::htext .footer -text { Hit the %% set im [image create picture -file ./images/stopsign.gif] button $htext(widget).quit -image $im -command { exit } $htext(widget) append $htext(widget).quit -pady 2 %% button when you've seen enough. %% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} if 0 { set file ./images/jan25_palm3x_L.jpg set file ./images/blt98.gif set file ./images/folder.gif image create picture bgTexture -file $file set style [blt::bgpattern create tile -image bgTexture \ -xorigin 0 -yorigin 0 -relativeto self] } else { set style [blt::bgpattern create gradient -high grey60 -low grey85 \ -xorigin 0 -yorigin 0 -relativeto self -logscale yes] } blt::barchart .graph -bg $style -barwidth 0.9 blt::vector X Y0 Y1 Y2 Y3 Y4 X set { 1 2 3 4 5 6 7 8 9 } Y0 set { 0.729111111 0.002250000 0.09108333 0.006416667 0.026509167 0.007027778 0.1628611 0.06405278 0.08786667 } Y1 set { 0.003120278 0.004638889 0.01113889 0.048888889 0.001814722 0.291388889 0.0503500 0.13876389 0.04513333 } Y2 set { 11.534444444 3.879722222 4.54444444 4.460277778 2.334055556 1.262194444 1.8009444 4.12194444 3.24527778 } Y3 set { 1.015750000 0.462888889 0.49394444 0.429166667 1.053694444 0.466111111 1.4152500 2.17538889 2.55294444 } Y4 set { 0.022018611 0.516333333 0.54772222 0.177638889 0.021703889 0.134305556 0.5189278 0.07957222 0.41155556 } # # Element attributes: # # Label yData Foreground Background Stipple Borderwidth set attributes { "Setup" Y1 lightyellow3 lightyellow1 fdiagonal1 1 "Read In" Y0 lightgoldenrod3 lightgoldenrod1 bdiagonal1 1 "Other" Y4 lightpink3 lightpink1 fdiagonal1 1 "Solve" Y3 cyan3 cyan1 bdiagonal1 1 "Load" Y2 lightblue3 lightblue1 fdiagonal1 1 } foreach {label yData fg bg stipple bd} $attributes { # set img [image create picture -width 5 -height 5] # foreach {r g b} [winfo rgb . $bg] break # set r [expr int($r / 257.0)] # set g [expr int($g / 257.0)] # set b [expr int($b / 257.0)] # set color [format "0xA0%0.2x%0.2x%0.2x" $r $g $b] # puts stderr color=$color # $img blank $color set pat [blt::bgpattern create solid -color $bg -opacity 90.0] .graph element create $yData -label $label -bd $bd -relief raised \ -y $yData -x X -outline $fg -fill $pat } .header.stacked invoke blt::table . \ 0,0 .title -fill x \ 1,0 .header -fill x \ 2,0 .graph -fill both \ 3,0 .footer -fill x blt::table configure . r0 r1 r3 -resize none Blt_ZoomStack .graph Blt_Crosshairs .graph Blt_ActiveLegend .graph Blt_ClosestPoint .graph .graph marker bind all <B2-Motion> { set coords [%W invtransform %x %y] catch { %W marker configure [%W marker get current] -coords $coords } } .graph marker bind all <Enter> { set marker [%W marker get current] catch { %W marker configure $marker -bg green} } .graph marker bind all <Leave> { set marker [%W marker get current] catch { %W marker configure $marker -bg ""} } .graph element bind all <Enter> { set data [.graph element closest %x %y] if { $data != "" } { array set info $data puts stderr "$info(x) $info(y)" } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014606� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/folder.gif�����������������������������������������������������������0000644�0001750�0001750�00000000130�11462120062�016546� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ñ��ÿÿÿ‚‚‚ÿÁ% ,�������1„yÁ¬„”á8gÛצ0TÙ¨…�I‚"š©'[®°àΔiÓ¸]óá�ƒ¢ñˆ,��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/mini-doc.gif���������������������������������������������������������0000644�0001750�0001750�00000000133�11462120062�016775� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ñ��¿¿¿���ÿÿÿ,�������4„ƒÆ!jNŒ+Þ¢àÅœpÏ…]Á@yŸ„V$™µŒºž©õñ½²w®³Uz;‡â(c�_†�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/corrugated_metal.gif�������������������������������������������������0000644�0001750�0001750�00000017034�11462120062�020627� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aK�K�÷��ÿÿÿçççÞÞÞÎÎÎÆÆÆ½½½µµµ­­­œœœ”””ŒŒŒkkk999)))!!!„{{ŒssZJJŒkk„cc{RRk99��”cZsRJkRJ„RB1œ„{{cZZB9ŒcR„skkRB{cR„cJkJ1„sc{skRB1J1­¥œkcZJB9kZBscJ{scZRBkcR„{cJB)kcBÞÞÖ½½­ccZ„„sZZJ{{cRRBZZBZZ9{{JZZ1ksBs{RksJ„ŒkksRRZ9k{9RZB{„kJc!ZkB„Œ{ckZcsRkscZkJZsBJc1Jk9ÎÞÆk{cZ{J1R!RkJRsJR{J{„{kskckcRZRJRJBJBs„sc{c9J9kŒkc„cJcJBZBRsRZ­cR„ZZŒcBcJ9ZBR”cRkZ)B1JsZR{cJ„c1ZB1B9cskJkZJ{c1kRZ„sBkZ!ZBJscJŒsc{s1JBc„{Rsk9ZRR{s1cZs{{cssRccBRRc„„BZZRsscŒŒ9RR9cc1cc1kk))BZcBcsJcs1JZZs„Jc{cksJRZRk„1Jc19BRc{BRk)9R�s{ŒJRcksŒRZsJRkBJcks”ckŒJRsÖÖÞss{kk{ccscc{BBRcc„99ZBBk)skŒZRsJBcB1k”Œ¥{sŒZJ{J9kZJscR{½µÆZRcRBcZBs­¥µJBRkZ{„{ŒsZ„R9ckZskB{„kŒJ1RB)J{Z„k1{kJsk)s{s{ZRZcZcJBJB9BkZk{c{ZBZkJkR9RcBcJ1JkBkk9kk9ckBc„Z{œ{”{ZskJck)ZR9Jc9Rs9ZœBsνƄBcc1J)ŒRk„ZkkBR{ckZBJ„kskRZ„cksRZkJR{RZsJRkBJ„RZs9B���,����K�K��ÿ�¹å0 aè´Q©Å 8æHa²dãÕ(ø,dAå…Ó¦$ʆh"…èU}^|ÉÊhÛ¬j›°i 6£Gµ1€˜B&†<E Z0j1áËFi8(Ñ6†Ú9]žyÑqH™<YM %>M9r›Q Px rkÐ eBüœÒGÍ”xŒ$ì@§K¢D°¾hÖ)ƒ ¼j•ˆ¦/­\ú(‘(¾´ÁØv„Ú¦Øæ¤áV-̼MÙ"YûbáK—P›¶ÝÄhÁ"Eâ>6Ñ Û° ¢ÅÔŽ|ºiÊ÷i œpòÝr’%  /ó(+‘åß�suQYÿ°÷åŽ$%‡°¥QÖÍËŒV›Äd©§ÀU¡¯fxáóe†«AèèPF OÌáG<òE#-#&s¤G­€07{Ps‡QlRÎ&€xaA  üÀ 쓈,i”ÅØÐ)FÌ0È6–àã|hC‰ ô`C‰ úÌÌ)ß´È5ÞÓB:x@ -P@ÕT#Å==|Qͱ\1‚1ÁpL/Ø0¡‰:ƒ@b‰,üÓ† šqG‰`óEY`CM 5òqE:ØX!Ã+?|‚>ƒÜ"Q¼ÂE…Nðr5¯œ±ÉØÄâktc h@D ¦â"f QÆ ¿äÿÈ•&.ðOšâ ,ö´ Íõ|¢Ì)Ù|ß-ÛPã`óÉ3!|1ˆLx³ -ü`L"QPAM9ØdsA5nÔà ,Úä�C ž€¢I0ùÌsÇå”âË!s\Å  Hÿx‚29TCÍ*ˆAÕì@J|̳ÆË(RD'Å\°…šàƒß^ ÑE5xxÑ‚ ¥h³Ã•ÌPÄ)ClòÊ ÅsȧäÐJ*æà‚>=ÄûψÀ?Óðpƒ€QO$0ˆ)-”£ä-``“b2ˆthâÊ&ilBÍ7öP0Ûtcl$²M5¼lS#Æ´Ð _2hÿÇ õdâÇ+€X‘ƒ6& �0ÿlr6ŠT“O_@‘ˆ&]¤óJ5`¸BÍ)¥MsÇ<9dÃÍ'u)ó4 –t¡ 5NÌÇ& PÅÝØðE”3P“‚ Û¨òEÝ4‡úA(¢L@;èòó¼ÂGKJàÈçX€Çs´@Â@ì@C>Ül2ÏFDц6¶´ñE"4P“Æ+ˆäiŠ'3Жˆ‚6üp‡+0B38Á ÄðŠfØ@ ÈF,þa€�â¦pÀ?$Ыuä#è˜C„¡7´#s°À ±mlÂ’ðÂ6ñ{|£¯ B4�AnX]˜Áÿò‘Ù$BûL òÑ #, ˆ @3|pd, v0Q�®P Aàš¸Æ N±(”Àéè‹>”Q‡=løË6À°˜B kD °Ñj<Á¤HB%B `C ðB7À ‰j8¡€è)ŽÐ‹[œÆ eЄ´ñ� €�ÁèÆð|Á ö`)®q+$â±%ŽAŠ.lâwèÂñîPŒn !8œÃx8¤c‚A"8ð…WÀ!^ß>Œð md͉hAðЂ[`CEHÐ lÌàìø‡ ´á«'¼è«Æ1r ƒ'˜ õø†Tÿ lˆ‰h'¨¡ŽyB¶0Æ,Ð Ml£ðB¡`UäJ€C5à`lä ÕhÅ(`ˆüƒ°F?HA‹FÜj©HŒ†RX@X˜ƒ'ìñ (¤ a0i‘Œ`„…x…XÓ*ÌàÜðC0àŒb¤b. €hMp1àð:j„Á­§�Øé…4 !]èÂ(  SÌA ƒB+ô†`Æ1²A +Ø cÄÃ^Áˆ| ƒ@5°ñ„a­HC~°+ÌÁ¨ãP†6Á ßhMzL„0‡äi_<\1²‘‡ÿìÀ¸Æ0¨Á Dã Ŭ¡¼B©:ø‚+ pXMÜÁ¡iÐF#‘(¤`æ„Á¢±€PÃgà†&6` h Ø�2L4€5^� …ô¬± EÜAæX@5(Q‚#H� 3°ÂrVm”A2ÍÆ#´ƒtâV°†)87à#Ÿ Å,1„g(ã _F28a+tõÀdpe˜èM�ôp ?`ø˜Ê1†ÏÚ£5Ó�C"ŠÁ cÜc>ð‚ Na(¸¡KíÂ2âÈ…áèƒ&>œotƒˆ�M6¼P@Á‡hê&tpŠAÂÿP@œð }ŒàÝø¢b¾*,Ç–ˆE)Ô+´uSÈG¦a†Gø¢GàÆ }€¡¯`:à‘~”A ‚1v€‡3à tÀ‡2¬Q oæçÇ@@�p·‰x¬¢ø¢,ª±$â6°B1Ê@ tœÁÛð5, ƒih¢`Ƙà.˜Ld©Æ@À4çM´B{IÀÔñfÔÃW(ÇÚ0›iB«0ƒ‰æ‘<l FH)—øŠCÜá Ä $ЂC@a×±�¾`ŒbT#]à2Ñ‹É)ƒŒx1/Tî €ƒ5Ìa‹4H€ ¯ÿà5‚QUX(@šPÁ úa„ZÀ/¼(Ç"‘R> kˆ‚'áŠ{|=ØÄ&œÐ‡kÀ÷ÐÆÐë9ì( \ö&°¹œC#ðŰ D€^È‚91<hcCxB1ŒÑ¢P(Æ6tp†h±Â¤eË´qsð|ù0vˆø!Ò…"ŒÁ 0Œ ‚PEZ }k¨À ® MìcFˆžñ…€AcÈ)¾‡Dl¢QЄ‰à0/("È8Ú?Ä0f÷kÅÜ!‹/¸Çû€Œ0~‘ˆ| Â;ÂØÀq‚ƒ3¸„ÿ6|° 8 £`?„HqŠã —C¼ä„m¡¶¸…‰ 0ˆtÁ°pÿð�èà Pàd÷ø ` Là‰@–° V@ ŒàP€PP O° qg#’e ÆR—€ «ð7ò Üð¤à ^:° ©€ ¯�ZÐ{&B {°¥@ 8ÿÅÐ]pž Nð ˆP ˜€óÀOP` E°õ�‚úp P&²@ %0ú ¼à]à -0 €11pÐýP20Ø€ s�¬ø° “À  .`)ðwÿ0 ¯PÅÐ0ÿ² ¯0DÜ�û`÷@pó€a€¼@¤¦‡ðÔ ópv _° ;Ð ™µ ²àW·Qkr° æð‡E ¾€ ó�° p Äp &ÕD€Fð‰0iàb D‘è_0ž�å° _à¨� :p Ú  Õà c` Ê }† ò0RàOÐ9ð Ã�=@>0Ñð Bv9ð@]p �ÿÐ�ìò Ì€ LÐ 3 Àƒñ  ¿€ ø 0Ö°Ÿu9�¯ tå±áÝ È09ð ’ð  ®ÿ€ 4ÑOåØÐ€°®  €ð�° ™Ð § Õ@ (mPò@sã Ô¡ G °ðƒàЃðA€¶ð `›0¤0C𔿠õàÚ`æð€ WÊ –à Cd�)ÀÈøª�P¬'sÆc Øà ‚àÁà  I€ ¤ m0Ü`3`€Õ€2€ ør)—MÛЃ'ið:š�r3  ›`¶ Z@ ù` .ð4i°kРÁì p^°æ  ^àæÐ À ¥€VP ÿ€!‰ð \  ¾�¨ g  X€P D0P@ =�ɰ Oà• ”`š  6`§ðEÿ` N]�¡ ØP W  ð G  X€³ˆ]`)  * D Œ`ˆ‡‡30ø `0ìä t¾¨3ÂàNð 3P›P¨wA�&¢ šz¶ƒÔ@V3ð _�(Ù}¹ ¯9m�Ù mFp  ¯ùd %ð%¤ /bðiwp9øÀ‡ DW¦ð ö  Ý  Ÿ`"U�0ØÐ !&Ÿð áB Ð1°G|ÿ ÅðW¾° ~Q `` A€öpF0   Q±`Fà~`¾�:`á›û�ÝÐÊ0ŠpKe ƒpc &Å�Oµyà›)°Z`?° ° †` mp�O ‚P  ŽØ;` 1˜` Öp�P�0á7 à€­°JàÚÀ `0NÐ ù  p F`K‰ �`R‹É W   šðtÔ�ª  bFLb€³ ]Ð L÷àm@ŸÐ *�‰à� p"ÿà Cð Q Œ`?‰_ ƒ€ƒÐ ;° 0 qÿ 9 6ð Ø «ÿ0èà;�`W0Úp9`]@ˆP ¨€ Û  (Ð P]@ 0pÀ ÇÐVP Æ€ pð�ÿpðEõ`yC0‘wÀûà¶pàm†ƒC‰��Û`_�×P 98]°I  ^iÓ_@ ¤ðdÑw@ iТB6-ÀÞà ÜЙÀpùº�_„XÑÀ Pڦ΀ `� k ${€ bƒhÀ Q�.9P ó` ÝðÔCð›Ð ¥0Æ0ðÐ-P ÁP P ‘à´Ð ¯P «P - ‹ÿ`i hp4Psß× Oð¼ w€Ü·„ pT` · Üàð°¥0«4*Èü0‎0ËF P` _Pð ‰`Q0 I0 .° Ñk+¬Àç‹�ÿ�‰öð Š�ÎbÐü' P4€›Õ�ϰ P5Œà ù°\Ðø K¡æ% Pа�c`G° ’æºó@ ¤˜p 2ðˆ sð¶"�Ê0 p4C°šù /ÐÖq Y�¤ g IæŒà«p´`¯à i€ H0Óð¸p óûÿ` Vð Ô0Õp·p,< §pÚ6›pøð 0ðÜp >ðCCx� GÓ�9`Ìa È07òã0 z°�ÀI /9 {  ;ö¿Ð«À{�Àø‡!Ö]ι õØMp›O DxZ3 Ö`:Ðæ° x Õ0,�(üpP§0P€Ð¤0ó°P° b«½¹Ô _p?_@� À±P »°�(ѸŒd$çèÜP 9Ð^À š¿€©Ðgà­pºØ`ÆPp4b`i`(Y ·�w€ »�¤ÿc ‹0N°ÔÕà­ Âð € {¯að-@ ºtx@9*àư^ Ø`¶7·À_Ѓ@ &r¨iû-fÏnà›Õ°,ƒ€¦¤°ûpâPY�`Àe§à­ˆš0z bÐ pð_  ±ã%®° ƒ0À‡Ì$dÛ0?›à Œ° €'U{å`  |9`†ù9Ðä À i0 ‘8}Ú QÐ-0mú›2[Pé 9 æ`PP Ûñ °�ƒ ¥¶¿p ÷`ÑP ÏFDq­AðM£@ žôE  òÿP ãÙ_À°p †àiR—Õ`iPEMpÀ0�ɪˆøp e`’€Ì™Ð]@E^p àØ0Ö  )À¾Q€Cð MI° ¼€ gœ�q0ð‘…ðŽàHÐw0ñpu9õ`%õ0¤ðc€pÊ%;à ™ /²0@ ‰°Ü@ÞãYÒm­< Kó {À g`à° YÐ =‘�wzR -€ÔÀ¾90–dÀC–¨U ó€úa€øÐm=0Þàóð eñ e0F)÷L…ì¼ÆB¶pî`È ÿÿP­` Y€—W� #`¨P æ€V>à øÀ 蕯¹¥a8iPƒ§àР àqª@Ú0`ÐLSذŠ6pà (‰ 倓° ‚pKåôö`R ° ã¬ýò�m Y@)›€ Å�?   ²`wð64ØàÊPÊ0 Ô  ‹p­c ­€¬�ù5× %6º›W`Ï�3À½P †@fPðqð—€ >` ¸ð p�Õ0Ûð 1 Wè@oû LðÚ`±9×9p]0 à)®¥€éÀÔ`Ÿ ` „ÌÉÿ€Væ¼0W ÜP epÓ° æðÝ pp >`éóEØP5 Ø ˆ°Ø éP 𘂠Dg ‘<«ra@(`MŠÐ›°Ô„0\ðY°~Ð ù°§�­p·%p� ÁP'•%–á“Âp4›° p°�Ã`,^ àÚ@ ða^@ Ê` ±ÍVPN¯   ŸÐ ` úeÍ�DËú€ ^ò}2@fD` xP ØP ù@;C°�úg,0-W kÐ ’Ï Rà Á0 p@^’6°kð:@eàƒ s0Õ¥ÿ /€C;MOP €s0Ù N ®€Ñ¿pû>?¦à£9°�N�&å�7�Ö„)Ûg¯@_Ì ³ñ…B"Êü ‹–(Ú³kÚŒõ–Â> ÔÄ´˜BYjÊ\}Á¤ÉW38-¾tƒS J—ƒf8ùEQŠØzå@5‡[qþý À§(8õjÆ«IZ{´Í—'ÔÚÜúRcÎ ­à CAÓ¯/PòÑÚô…T R?š`Ó¦ÃÉŒ½fQã¶©ÚNw éƒZ‹_ÍØÁcé�ØR!$àß½A)Z´š¬‘˜[¿Ê é"¡‰·'¯rP0%C[ÿˆ0¾TS2Ï $N41º5U5D݈ˆÙ¶gF¢`%”©ƒÃ+Ì+ ¨bl¢Æá‹ÿ8.Ķ�ÿ´åKH Tš¨•¹âîT"›Q³§?›¥.y%s6ÁgL88…š,pŽn¾¸edÂðcl或'àhŽ”Ñp–pMX*�1TI\À†.J‰Æ„'æ¡KPP”mÊè&ŠV´ùâ‡`܈ ÅàØ�MÌØ›‚É"2|ËðxEšy„ØdžÀ0% {&�(¶ÉÊHY* Z¹F€iV©FŸr˜C0àÐÁaŒÜ¡¹l´yÿacf ç M°i¡|ªÁ†‚pFI¤ 'R¸£ž;*8barxÂ^îI„šê)ç ´¸ƒ1ª¹ ‘"‡¡æŸ„ô¢@%‘2v`ä‹y¼Ù%;¶ÁÆÉ+ yŠ;há "*a¢MÀ˜á z,ø‚/m4)lÙÒg/bnu' ^¶™ 8hãÍjàHä DôöÐ$N°i–D⣾ù‹y¾€Š9Zé—'D\ ‡G‹'\±`‡QZ™©šm¹#Š|Ð!EM|�—-¾8lPðe7(HB–( €Ba‡hàð“`8˜£ 1°qÿ¥…6FØf–l61¦šjÖ F‘A\ñ…(.)G2(ÚðD‰.rð‚šyîX„‹´9E\c˜Ñä‹mZdb©©†8>XªØ1 ƒO‚ùb‡ˆ8ÁžD^¡$Ÿm´ÁeŸ`äˆLé›oŒ‰A·(^‰«Tæ€Á‰2¸A¸žNÉÇkÀ ba b†¦ “’è‡l¬(G›Mæ°æ �¾ˆ&J,ÝA–¬IÄ M†®&|îA$²/‚I£\v™§‹|Z0bj2ɇ+69á‘.¤ÁbHÄ6>/4#`ÀFÖ S â>H:Àp 1DƒFXŠ�€ÿ€Ãi"_ÈÁ'H€,(ØðÃÅ’@ '*N¸C  ðƒD¤Ã¿€ ‚±MNÄ¡ 8 b rÐÇ/‚Á…]|¢øðE †4 BJpE5>Mü¡ƒøÂ4@ ˆSh‚SÊp‚0~°†[ÌÀ_0FÒ‘ø¢ò Æ ,�?,cI°Fëî€ Ü¢‚P5¨ÑŠyÈíP`D,à1WìàÁ°G=‚!“,l 2x„8þõk¤À.ôˆÁ>(Œ6$" ¿ØD¾Àz|¡˜�Õ �1¾_˜‚ 0Ã`Ñ YÈD?;ðI6Rà„hbmÀD5`Ð…+ÿ˜£ ¸À>± ø!ƒ0C ¦q l\A#ˆÀ?ÈýÑÙ€Ç'Œ`„ <Cb€.fð…O$ƒƒ@F ‘ƒX@}iÐY0^¡Œl| N Æ´oTà¤èB%7K4BCØ„+h‚,Àaf(Çèa l€a ™G Hq>4B‰Ð›êA/ºaùP7ºô¤a;3ÀƒªñŒ.|! `hÁÚrÜAb¨„9ˆ€T㟮C²MðÚ†b kXÀ–ðÂ'Ê  ™lã`bPF+4Q1Ãt[Ý„fp/Àöè†9z=´  �;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/chalk.gif������������������������������������������������������������0000644�0001750�0001750�00000010432�11462120062�016363� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a`�`�÷��ÞÝâßÞãàßäáàåâáæãâçäãèåäéæåêçæëèçìéèíêéîëêïìëðíìñîíòïîóðïôñðõòñöóò÷ôóøõôùP�� ����0L�©Â P��à à8�ò ¶ÿ�¿�Áà��P�.�©¶ ��à¸k�ð�ÿ�¿É�3 ��À�ñ ÿP¿�Ä��ð��ÿ�¿T�år ² PTÌrñªÿ¿WDl�ð€�ò �HL©�Â��P��  PLà�Âñ ÿXåò²àÿ¿P4È�/¨��`��ñ��ÿ��¿���¨������LLÂ����P�L�¼Â ðÿP¿t�äL(àÂPP�À¶��L¨�ÂL�€ ð�ÿ�¿L4Âò/ÿP¿P�娲��P�ÀüÃò¨«ÿ¿=óñÿ�¿�èLy�Â�L �Âð�ÿ�P¿4�ó ¶ÿ¿P��¨` ðÿ¿4óà¶���`� ����¶à��Pð�Üò ©�L)àÂP�8.`ªÁ�LR�Â`.`�Áª`R��à�¼à�ªð��Áà��P8èVóñªÿÿ¿¿4ÁPóñÿÿ¿P¿ð² òª�LXn)ò�¿� P`�ñ�ÿ`n[��ñ�¿`X �ò��c¾�ò¾�ÿ�¿PàøPõññÿÿÿ¿¿¿��¶����ò �ÿ�¿������������������������������������������������������������������������������������������������������������������,����`�`��þ� PÐàA„ƒ B€à Á‚ ,XÀ ¢ƒ‹/"Øxà€@T� |À€d‚—#2X ‘Á >ìØ‘¦L…t&ðX€@H”btèräĉ4¨èó%Ç")Î,ÙÀJ†7„ÚõÁƒ¦*@ÐqcL‰@¨ek€@ ´B¥º«Ø‘kkÎ\KÕ'IŠR¥Ît`Ë¡mkvU9„—Ä:ò%DŒÊ¥YR`ÞÂ#–ØV$ÄÏ[&X:5jWÚ ;X`R  ÍJ.,I¶m_oÌÚ5‚î©>7Ô|õ#Ï¿ÀË*:hÃÛ‰oþ‹ÎÜ×4ðÐ0·ŒÉÑ7DžX³wŸž°ìtÞtÝ/‡ñ÷‹þ4ßw3!VÐv¤‰UcfíVÒi›„H¦QäŸwµÕ]„Ü…�EžEôC릒sŽy·•XÝg˜D^ôTTŒg@‡|„cHÑVÛS4™”#Žæ”V61�Y6 ˜âE6†tÑ!©a¿¥Azy#vá˜ão(%V‘máIõhþIõÖ[Ì]ø€eÅe– |"‰X_l@ÆdPe¨·V]Ø’G"pf¥i¦†¾ùJ-4AzA ¶… 榤 g™z›u¨¢œÅäÙKe„à[þ‹ÆZЖáÅS‰ÙQˆ">´ªg^Ñ Z%)˜Z±á·Ür­b4ÚX±.ŠÞ¥˜fJZ:‚™cHûyÖšk³™åœN1‘e§K5­úV³2—WWÑZ$nzÎýx\oEÊí²t%7€Û1ªƒ| 6ãm™Å»\ G[Öx ¨zUGºâer%· *u!Ÿ“ÎDcc@™gj$*™bA.‡gomTÕf×jH5¦Ó±É>$Yh*<T*÷|'| Ñœ\¤Åj<0Ë冦M žœ*R\pĘj�´fø”wuÆÖ¶ß*È!^ª±/´Fð�o0@à’©TþmîI¶UÍhÞ|ôÉaeì—ºìÝ8&` È)'½ÏòdôÁБcª÷žlÓþÑ^…/¬'_BJøYh¥.à¹)FãngÙ5Ú.s–óET.:vD¸¯hq¯áN7ˆåUnÈ/DÞK9æP‹,9(ÚßÚ®]ÕÉŽÜØ«Å–‹äÇJvÝ‘iM¾=WV 9SB‹NÿkˆÒá^Ú˜-†vÐpþuä™rª¿,lxߪŒ…2h!IvÑjƒFS(À¶ÒM» “'^A`äÒÜ™˜€ÅÁét‰!Kå2ž³ÈMI"AN€“Kð8 $v`¤€1gC*»Û@Ž…éægþµqža€<Æì<*‘ÀÜØò¡Êuk|æi†C"v9 +1 T&®z=DNE\žgÐ$±‰D>3S0–Ÿ˜å…R+qm6¨´Ž¨Ì6šIÞYærøŒí1r@ö¼" Ì…BD¹ÜÉÀC“Þ &"Bº‹DŠV¬“©-^ÚQ…•¦3eiЏ”Zy—DöM/‡)YEšò®Ý”l"4kâMjå$’t Lv‰›¶ã: ¥¤Å‘KKòƒ—6î-•<]Θ¢Wî®G —.dË|‰9 rå3í7®Ê=(Y}i I°_b*CæŽ ÃËjâÒC§¡Ê¯b0ÿÈhˆ]þ!vÞGG!Ì‘oƒòVG¥°|iGàŠ%¸úyÿt©\ !¯X‘i2%TþË^¼àb–íŒG3H‰klT€kI&7¼\O‹¢I!êi,bŸTåbÆÙÙÞÜH“Hø@1OÇñȽ²w³Ø)åD˜¹(p”Ô³úX«W3„%²`$vUG>•`è212õ I“Ù’KѵJàYD©Y$à.Ç›A­vYíVÏ‚Š(¶¯¡¢š�†i,œI3cA¦gʆJ<.m&ñפR“"‰¤¡'*N4/…S9³d™K–blù�Ò§>+’ëKXC8ƒ]ÕTœÉ Z¨ˆ–ÇüŽ"©‰þaã›ÖQÇ#xýŽ*7ÓˆXG£{)#¥¤€"^è£ÇÙ­lXv­ºqÑ £ÌÅK Eê·’±RXhëÇ'eÈ¥VñyÀ\—(ήvUÊ 7“§àtE÷Yj¼¶V lé� p%Yu/ü²7;²} vžò®JuɾwÉȶdÈʹä²U½ÏPÈ—OE¬)üj/cfÔ>ªUjŽ˜¾†P³`È G»³ØŠ8O`ß,^(µ L.þ|Ø“èB¿É�*-°•u²:c… H™ #‘»°å Î8›S ¸¼[�‰f*ã‹ÏÃâø~‰B‚ ò¦dO‡ð‘˜»àþ«ªz?v’«ŸŒ¹Ï²²gÙhöou1 ˜;Kgù'`¾Ó*`àb¦°@¶ÍJ¦ËO¨ÄŸñÆŽ‰ˆõ¼gjfeQy¤`p¶TÒÄ$y­%O× €(¦&¸ÒK™Mp"Ä¡ÈFƒ¡Y#˜ÐàÎÁA]êR—˜d��@.v¥e‚°ÀÆÕ’[F±/‚µÊéÄ¥ï¥Ö’éâ@1ÉÓ/Šm Ÿ– _m•%‘´´3¬¢*égþùÙYºó±¶yûÛ'£kiœ¢gýE*ÂK¨�Þ,¨© z;õXG Kƒ©Pø¶Š)SÅÌè nWÖ´‡ð$íÎ*T=`µþ_¥e‹�wC­_ÚÓä3¥é¯�_‰‹œbˆ{¤4ô&óÀÚËòlë¼#òr2—§€í®ª{ŒhþO¨)À²º«ÚÛT¡=‹4êDžzWjêdëÓjT&à‘¢ºd•„kVß4@TaQÕq¯›9Ë#_ÑÙ,*súK ÕDÆ’ÿ{ÉuöƒYßZóÛ‘A!ƒÅÎ`1}fŠ\žîÀ2ÝvA•BËÆr"_g<¾pnr)†2”JTŸž�.bÑÄÙ¿¡érDˆL{zoX†u<o«ÉÑ×*(ˆ&£bÚ{ݨPxûæ ÿ¾²Vj:D²T8$zuÊËuËíþE3‘JÄ)ÚÉàž¦婃 “S”XƒðÏ2-ö4]!•ÊU.6EE ÆÚÂïa oÂè×{:šW^.‘aïã~­r\þ'.€È!O†T@âjчDµ6V²'NfGFÁMÉcO{¢m8ÅD6¶@ Ñ+ÓãyOf`€Ös¿’”m ‘!ÈVaTP{â'Xd•Â@6&;žÇ#å7ErÓ�²!ÉDƒ“„Ä’m Öxƒ£Q6FpŽ1ˆ)»ÑÈ'ŠCq·1]/2?Úò5 ágzQòJ—ÑjY¦A¶'¹Ó\â lxD‘ò&˜¥4£si}Ò8óJ’…þÓc4v!ç^¥ç n·rnÇd%dˆ #B‰A§Jãò„¢ˆMõH)¶b[ò‰ìÅ8¨Â#ÁD•&ñB â*'‚z´”„ÃD(¨T wˆ"Âô`¨ÄFúÇW²€bÄ0ÎÂRµ"AÞDgˆ9³Yò|2[Ñ÷ŠþTV1¡…Ñ$ÓôfMS<ј'C¶r@x!׆W$(p’²}XÌ£;Ã$Ûc'uäSçø^s8 eag`Ê#ÓEO$t3WB²á=ÌççeQu'î¡J qm ¤3tZ7ÕK”'ù¤wF‘¥t#úÑh<”( ÅsV¶W?²€åþ7‘òU4^»"_3E’Puî’²aJ¦³TÒhÑ6ÿöHˆñG ?ÓwKx“$Èvž‘uÄÄ6ÈYbBXìvIkçNQAuó.Rñzó!^1’H÷7¾ˆkt^„Åx¼†<H9+ÛGGåØ5_3I›‘*SW¢cp'fWm�—‹¦Râ8·ÆI@c ¤˜—}CV³4,O×^5”Re¤V†éƒáS<hI.÷"ˆ±A¦Å8Msq�§3áÃyÖwN;ñ5sv‘ A“‡1FñFOW�(Æd";è³"T,™bHH"CSA¡ô†;#Uïs“â¥>ðñ?B5ìCy¤þ.—ÁdaO$„!Œ±%˜ø%=$—¯DuÑ©Ke!7JÕOQItúãa/&ý–#s++ò9âÕ<‘Uy\8©žZDX”Sa"ÓžÀˆ(CghàéD‘)* ›ÔúYÃù ˜–½ò0͈!Mƒ>—%]†aTÔ�ØâyŠ”r @ÛaA°”~ ÑŒô1\@µq郔 @FªW0ꂉ)úö3É<³R'X?§fdˆ&„‡E–(ˆ]áBÃr-ômñ”kšu¼Ó*j± !ØŒT¸øÒ!œ¡}ÒÓ=6‘q†ÁAbÚiM± CD,‘2»0Ãâ¢þ^Zœ•¥³Ñ§±tWF­dCX‡d a]§¦uùÅ.êT ^–- CÔ-ƽ»d'XG&á7G ç»•&gqN¤H[÷&%§''/ àPÜ#@‡!bÓp Â>ñ‚R˳,!µ‹iÇ/Lg<80¿'F¤p€F†ØC“@rež“ŽÃå/SÉF‚ÑÔehgy~ja­B+êoÅÃ>…s“üT«ÙE˜bgƒ+�§sÞ“_ÔÉo“)ò91–.1>x¬ ¶Z'æ¦ZúJí“LMU­e2|ççm‡8 #X™° ÉÆ‰œ¨|aòt–„Ã�†ã—ÿQ pvWšÝV!PãeE�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/tan_paper.gif��������������������������������������������������������0000644�0001750�0001750�00000044730�11462120062�017262� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a � �æ��ÿÿÿçÞÎÞÖ½ÖεƽœÞÖµÎÆ¥Æ½”ÖÎ¥ÎÆœ½µŒµ­„ÎÆ”ƽŒ½µ„µ­{ƽ„­¥s¥œk¥œc½µ{µ­s­¥kççÞççÖÞÞÎïïÖççÎÞÞÆÖÖ½ÎεççÆÞÞ½ÖÖµÎÎ­ÆÆ¥½½œçç½ÞÞµÖÖ­ÎÎ¥ÆÆœççµ½½”ÞÞ­µµŒÖÖ¥ïïµÎΜçç­ÆÆ”ÞÞ¥½½ŒÖÖœµµ„ÎΔç祭­{ÆÆŒÞÞœ½½„¥¥sÖÖ”ÎÎŒµµ{ççœÞÞ”ÆÆ„­­sÖÖŒ½½{¥¥kçç”Î΄µµsœœcÞÞŒÆÆ{­­kÖÖ„½½s¥¥cÎÎ{µµkÆÆsÖÞŒÎÖ„ÖÞ„çï­ÖÞœÎÖ”ÆÎŒÞçœÖÞ”ÎÖŒµ½{Þç”ÆÎ„­µs½Æ{µ½sÖÞ¥ÎÖœÆÎ”Þ祵½„­µ{½Æ„çï½ÖÞ­ÎÖ¥ÆÎœÞ筽ƌÖÞµÎÖ­ÆÎ¥Þ絽ƔÞç½ÖÞ½���������������������,���� � ��ÿ€<‚<77g:4<:)+2(0+<4202ƒ@<@F:™C0::FCœ2@J:5f)4D@k70‡:007„:_‰_CJš@¿š™<FJD_<2 œ:24qÉÌ:72И qF@:gÉ+47ˆ:6‚ “4“0)É™4)Í‚“á“”0q Ôɉiä:£<6ÜÑXâŒZä ’ˆ·s¿lÀ ÁiÈ!¥ZQ£(¨ENϨINÇ ‰´âg `Ãx|ùE8×~X²$èÆ»˜l�É1NÆB—‘X0E%ƒï¡Ø@dø¸I‹5 é+ç.Y¡U)l4\*ˆ§ ¢Ãÿ|Ô4KkHQ2X©œ *ߨÒ'L‰ôã"”4Æ)%i)s@+\^0Í&-˜yó–ÂHÞF¹›:.à7§´JJ‚–Hç9pŸX±b¨ÄI3ôËÜÄ<†�I™æ»3Ÿx4ž•,(KÿA£$Ó‘#¿¾8�2ääò|gÙ™žMi<AI”Èž ~”ø·bDAjg0PÉ$ÐÀœ ˜sÎ" ¤ð<ÌØá ˆ$rÆ >ˆ%CZKy#SDJT° 3 :Àƒ„‚3™Ì% 9[زÆÂ�öËFqÄJÁP4 :hqC"qPD‹ 6ôrÎÿËlQCÓHfKdã,'É,g €‚ÿQDM:ñÖŒÀÙ±¥ ‘<ó`2úÐ@KM„ÌÔ5’Øð�&™ðÙÒ/jaÉ)'ˆ¿ 2D!xò ßCðó F ªR+4£È‰4üB@è§%†­2Di¤PH :Äaà ’Ù•Y…‚«Ð'M:6ÑЂkžðN  Cg>–ÐÏ7•4ƒ"A’Ø„ˆ±Ö4œôòâ>|òjbq‚¬ŽÐ §p"Mìª Ì@�Ć 2sÃ#‰(a’8éÐ�2¸å³ &ØqÀ*n°D È4cS:ÍT¥ŽlÚ±ÂÿÁXmÈ"&kXç% oX–$-(Éx*]ö’L‚<°é }^UIŸádBÍ ÊÍe Ž‚x† Ÿî)âÂ!à´µáD³Ä 5Ö™F>­âÈ -¨“L ¼É9îXýQ´’Œ6¤M2€æ;vD³é,9èð$(psLC-GÄžŠ´¶ï 'µX”l/ e8µ”‰{ørD¾(L;:4òÈ f4ËÍ;ä5£¹ pFÃD2$±$)Hhâ—2p)Ù4H(1'[Ó²GWqòMa4(àL´S½…É&e"èräX¼òæB ò“ òÊGÍÁÏ8CÔv&ÿ޲`­¤áÈÿT(ÀR>›4òC™8ðùDç¤@1‰/-¥À_jLò†g.5ɸŠß䯒cl_‹G´ÂB/j¬!i”Ddã0…6âÒ-Gj HOKÀ1‰„[`@F™¼ Áù£Flà�nTî:š{Ã'ÂJ8ì .pA:P°¸Äˆá „1Ä© ä�ùšð :%¦kp†3%¨Dn¬À”¦Æ ¹]¦H ¨fØ­åñ-EúÜ;¦h(â>—‰›Ë†�Ì6â“Á4öÄ ˆeE'`Á `à‘Ô€'Ðê6äV­@£F  ”Ö¸íÿ� ‚ @IILã”ð@F*p€á PC ºµBþI ÌÆhD™#D`9€1‚c´à)âkÛ—H¶‘¸@ya€–Rp‚Tbl:PCZLjUŒãsnX$ ²Hù… šp[#hñˆ-åŠ-x€kbD|Øá_i(¤~�‹!mAy3D>„RŒm:ïXW`ZÅ�^þÅ TÉ€´Kš°$¿`ÅÔ ~Íæ‰9ƒ­h±‚] BÉAÜg&p†9³øì¾q4t�—i :``‡|ÐÇ3ì[d $p,8áA˜Ô¼é¢Ø‚À=¼%< ¤íÜÿx`^$¸¾¥!G ŠZùÀM]F3ÑW/,Ñ69"‰Ð  ;ºÒ€Iny .GI͉¬ˆ2‘Ñ• B�¿«Ð@uOŒØrq¿QVÂ5ûzÄ(„‹Íe<›O`à‚¸Ù.LÖy¢>rÌ09p×`tàEBÑ@ „âØa6E#aÈà°Ý:f•|È`s€ÁšÀ‚"†A’£â07(2йbšQˆœà õ¡a¡h¢0'ZÜØ×C¦b‰80€zûT@þ5‹С_–ðœ_2—xá ™¥o„¡#mä&Þ‰x.šñ )eÅqV‡jd\ëSÿ‘À!H-V"áD’:V±´YÀÀ „Hn"·¼ÃÇü P¼ˆä23bõ |f' �Wp-àfqGÔu(>ý¢ XÈ/ŒÇèèN&(þƒ7˜ÈÇaZÁa€à€þý†Ű–z ¡¡f ¢4›Jy”aˆiìðÌh‰pdB 8!ð�w¼ª/Ég&œé3°6q8ÊR”JP:@AgßЀDYf%0’´q€ÅÜ‹A¨"ÈÍN‰1 FÐ'êCËã[ BÔP4 ÕJg´A‰g¢¢Š{æ1'‚ú+$’`Mÿ!yD aƒ´�ý˜‚ìlÆ/X›2Xd3§h{Ji ÕŒ�á‰ÌLü—_(¡ M@FÜÒ ˜A:HCdPj–°28`¶;…@*u—‚ˆB¢Èûþ(`D+(¨æ[6‘H�¤¶TªÌl¬óƒll  E¶3Ìbß×9t簞‚…•žÏTò=5jMXÞða˜ ÉÀ5@Ú#÷åÌ!7ÀØ6gCài 8ûqPt 2ŽéÌ.0@ B¸8/Z£ÔöUêH€?–'+xÁ}ÞXF[Á$›(öMÆ L‚i8š!‚* �ÿt`vx€ølà.qxKn†s„r‡‚$à'ð—c¶ ƒ7PP‘ÑA64`&­ƒAf†ê‘xš µ€‚¢0 %)„ŠvŽú`ù¦,(†‘¤.å Åó@F@›F\CSY 鱈à4QRËŽÒP°‘ HÁMRâPÊ4»1€ÑÔ‡DÒ1´Y: ð† X3``Ї2Ÿ!–©£~Úp¥ÓnÈ0 ~ô ¡ #gp¸wÔ† úq‚t3(@;B‘gã0Õ7ÞÂ5aÁ "àßÔL\ƒ·B1�!DЖ‘$�7Vòc D4‘ÿr/‚”»'p¯ïP$†× @DÓР�Ebuãä¤" S\K R¸Ç «LR7`,°{5=æ/ Â)@Ô°œ“‹C5!DqD4 b1¡eb:Nè`�$àR­á*i)5(íÖ` /¢Å ÝÁY>0.@0\„ç'�zvr )À|üð0 cgT£a×*Ÿ0Ý À5€« Å�Q’´ éT Ÿ3;D$•¦o„² ˰4I2T x.°BWšÂÀ9°�:²š!3(ÿ Í4Ð(x(€T‡j}Aq7 )@„Ž !@-à!(Á XM3!48PR<ƒ7PçSZAf®B¡e¼± jÀã.7ETR1Ö<!HÍa£àظq1Ø(ðH  °GÐ s1(òaô2(@° ­&@4@„e «‘’ô :b7þñrC°ji³t”p>`\‚4‚Éà·µO~·0EÉG"€J’À0,ƒ‚f@=e}ÒgðH .pÁ ÛDq -°�) R‚Âeµ!@Ðx[éa•àÿ 9pãÔ+޲.–™ñ[‘�òw‚²Ô0.ó €B,2)€{8‘4"H7ðKÆ?âŸH #1.ÀIãÄ­y(p^Ø&)p+lâ?Þ îp760 ãq¥`Ž7 DÄB>²0z2)¸ °j q *E ÀfQe2°³0$*c†±š(°…Æ"‚dhÉ!–ŠÀ [ÀMwŒ”pNG‚½Á¶¶” :P˜géivP qÓs< 1h&gp�P{D“°[ :âx(`'�°H° EÐÑxÀÉ|{òÿI§{Â=0.p>P"�aoà?p:<‰d$a*P~W©M`[Y)V!/Q2å|³rn( 9 Zð Š@¢´X{­–„)� À¹=Ð “á³ ®E›!`Ÿ¢kqB•ó—(à) � á‚È0'p¡úÆfà£X 7À%Ð)B<XúMð*ƒ..`%�RhJ™Ð;`Ÿ> ìX]ã6”ð-ð+Í“ ÉPÂ’!Ÿø[Ã*Jà�'Àø(¨#@Øà+¿ñ�D1C³´#ã�&çhó'…0 "€ôÿ=òHaÔ“ût‹œqð/çDõ  ¦ CG92C€;§,5Àt¨EiÐg$YZ`\ÂZŒÀ’&sȰCR¡ë8(¥¦N�g2ЉÇDT³É#@-àœå>à0Jº#20tU‘ f°H>cß‘§19. É bjð7;#ˆP ЌèkŠð/_¢%•P tqò£¨¹ÃVÛS¨F?ã”+õ:Ó á„Eqº"`�#@Õ<Ñ¢HÑ›"SŽ’,=šqS930E01pm ]*™­Ðÿ6@&îr‹6 h¦pŠ`\¿@Œ&Â$Ž1¥B2ÐÔ�Sá.I'jòeÔd6B¢L/÷)®­¶^„· °'À„p�tP¼AÞé»–;wK¹)¢¦f‚6rXýA ` (�à§©5  D±a‘VMœ¹<ÙËYYài 1\Ž÷ œàcÞæ®ÒÀ*p¦YP"2ç”â¥%[Ò`‘½sI‰@‘µ .+ñK¡)˜`}К ç°�h÷Hñ*-@AÆ—N sÁ|Ž–wb mØi sò!0¦E ŽÐ,¢0sÿ †v.6P2Û†'7——‚B5¥€B40Äx^û’+Ë7¤’�w1(`ÁF¯2à?f‚ý±%(x}Œ°XQ>ÅcK!Àb¬ …Ø žZ–:Ð 165,C*,îppÀ° ‰ü€w4ùP�a ›ð¾(àôanv^û4,0,0 ÿ÷+ó¸À¡IZâ2à:‘·6  ÁlçP ’0@ØV `•+ Ûô¹‚Ò±$Ð<ë’ ±±É@1>A„Ow+ã’q"p�0P² ñ[´` 8¶Hê’,/‘×Ñ'F°>IŸ� ÿ­ò[ÀOŽšÊ N‘6pG 2Ò­”ËC¡w€ÑJea(°°H!€¬óh z¨\¨ö[û2? Çð ;¢‡ËPqã‚{>¦xÉ5â@I¢b±¬¬™ ¶a õÌ�éÁenÀP•‘©òC!äˆÿ©ÏEÊu\“½k Ëá†lºMj1Ù�®@QeƒrX¸R¡q‹+µ‡vCš­v­&ÙèZƒB(Ì„Í0z—¸´Ìp+¡1I¨ >Ú<çˆmµ°aí¼ÈÈ?˜­°/q ­‹' )ódzà¹^l"‡5æ>N‘žçg�ÿ‘¤p�‰9™‰»t6 R¬ p�jp�W ßZË-<·Šg3.1)ÒJ“H M5XW˜ ÐQ JP€ÐDà ¼¨ý iàîÐYïP )š@§Õ,¥‹$ß‘ÃF* vðšâ1«‡Í9¿¢¿Vñ(Hq6 ýéi)³ït/GX:ðêP> ‡Ü¢=¶*‘�êðGÐ i D(û¸gÒA;ˆ†tð†¶Ô¯¤”Fà„î (xŽH1ô§ñÁï ;à#Âtãð)¦t”š¨%\â9Ôà`ôàDµëÿ €¡=ö 1RÁ?+àúR•à!ßÕÙ š H'D5y‚@(!`ÍÄyE20�†÷ò­@Ž¡:ù¦L’àUJp#6;§e5@ŒµàV ÙÓGÃÉÐ ‚òbŠ œ+ oñ+Ä1 ƒâ¢>F Œð=Ê *²_œÁU*Å..ƒ%´ Ø'Pºq3N ,—a\!Ô\æ;ÖÑ 7À7ÛÐÆ'C=5°<Ùà ñ�ßö/ ù©Ð�:É‹j —Ä|;¹)ÚëžÐc„ æFñ€Ö S×4+ƒR“ºõD­CW—E‘àø¨¶°ž5ÿXz¢‹tf@„b6¢*IÚ ̓"Y> ŸÒÛWÄTºêP>pÔ~3x'J2°{lÂ5üÀ¼ñÉÈP)Ô)U‘¤m’,¸©6ñ™¼(… •é´p‰fQé'0è *NJR ªEÀ*1z‡þšä!¬bdà³/œàHœ%5Ÿ@CW$ý±aóq$Ôy«o³‹À ¦²k…¸Z€!‰ü!E7£mÚ0Kw›Û˜À¦ùT«HC]íÁØfX𧻢E²s†$øZ];P4† œåCàYÐh/3:Bœ°>€�o0»÷ÿ„Xœô?fæ/˜ó9ËgÜ6°�RÌÌDPH-5ž§­@Ø0÷è âo€fMZ6bÐeZb8×Q µ‹|,ÐÚ0î¼Ê ”«8·Å;�1–! p¨ø•i  `ŠP¦�³„9ßë”Tãó"H›E,‘ÑBìq6C’É §1É버™¿ô!Ćˢ)Ø2LoÏg…¯^{IÿÂEP÷ 4(074<::g)@@‚@i)6FD@:<D+†>e,&(†4COU55>:0?<ŒŒ—G62 4+69š9D=”6@<À42g:4o22i6Â4@ÿË+È0Ì4Å_ºG˜2<¾bÀDGKD”ŒDÎD²4ë:)…¿È@JŒ:2?È #)2ˆ5'(ìÐø‘%U$ül´ð¥ÃitLâñ£Q³J ` p$‡Ž-? ùaäF‘‡‡0²¡‰[ÂüúRaœCK2RÄQ°Â™ŸÚÔd!M›°–”üÌÁôP gJ†\Š@d›"bx‰â2DIê DÍ•/‡ixÆ!. œàwC P²`hüTã†FqXÉúå B`)L4Cäw‹"ˆX9ûÆÃn³2„-3´Œ¤³{24ݬm3ËbiCeF&y…-6m<h‘CIÿÇ[@Œ¬áQL?ê~3Ò¤ëº8–~;üÒlŶŒg˜8!bXå!: ÀB… b(´“c¬‘mi†ø­¡â¯õ2nh¹AÄ*K—cêŸñà×™ñ†!<8ÐBf´ð`[eΤ`HN,ñ³ÍK9ÈöËOO5bGC% 1„?¬Áˆº!‚Œ0—a›ÀØOq ÐB ‡¼Ò2de›W"ć'°R"mŒ3(ÜàÆ /G^_p¹ÇÇdöƒ@qD…vË2GÒ§’O94²?œñ Þ/ ´à;–ój´@ÃKUÕ@¿üp…:Ôõ„jÿS  ¿ýÂ6•Gà mA)!_qg:lUgÉ[>ÀðI3Aã–%9�ÃÃ?àc× úI‡ 74RZ|šÜÒ6¤±Â-¤¡ÆÔh €Ú°?É1Ò=ë¼´Ž<.vÄT†¯9”f±Iq^¡ý¸éC|ÄnÁØ`AycW –ÚSÃ|°–£É UYbȈƒ4i#"ÍOÅæ&C™ˆ $ÂO:ÔðW |&ûH%ÚÁèO9ã±£(YX+–æO®µ € 8é°~J„”ƒ4P ©«`‚œu]ö`­ ð¶á 5 Pè ÀÆ[.°�åGö¼ÿê:áŽ( sŒ ' £0ƒ;ø%‘£I„uƒ[¿ÔU¶’áWN+\’&SÛ™Ž@!COÍ“CD†±œ Äa™ .9@T`®[2Ð(%#Ò@Î9Ð|Ä‹©"Ô¯4-¤²ê .Ô áÚ45ˆØƒ‚0tÄJ††TÅCp±`FŽ#ày#š‚B?~ñpíBJj³ÅX»,ð’Ç, ¦™ýV-b,¹‹.=èR[æ�þÌØØî×ETÔ•ª‡¬’µ%^<a„uœ�ƒ]'˜ŸÓyƒ0n 6ZÊ67�È¡Œ r rE¨ é2¢±�á>XÚ03´ÿáÉp"VR–|7Â8z`½hÖ°É%ódUÀi�U`s„V<@ @øaÔà‹pHà<ø‚%Œà…bâ5¨ˆƒå—‰§D娄ÖFˆØ‰Ðj°DDà'™&A5x–ÒÆŠ!„g8@΀œÀÀÆMrú2°ŽôÂàZ€ïî„ œ¡°ÇÆñ€nÃ.iT wñ€B6`!¿Hƒàn±‹#Ìc@x£F©…¿H¥°º„FÃh�' †%Ð'„Ðã9z„¦~Ãý±. :xÂDñìÀ <hA\ 4VDæ7©òKŠXA„/œÿ¤IÁ¯"ð44ðÃdÅÓ¨9H_x%(\±€aÛ¨3¹òÅ9¬“ƒô ‡ø—¢â-¬ ±‚ `;x,2!‚åºPužÈ ¡Îp? ïH¦Àt7È Q¦ä 66�â°Ê¸¥ŠŒ¸ ÒÔ4Fy%„ `Ó5`ÍP5T‡9yФ¼0ê~ü €H0zBö€hLQBðX¦(Ô¤*åW Dº†TÂ…þ\‘#KÀÀ HCD ‚þ}À*ÒxÚŠˆ¹@€ÓýVÃ;ì7JH¨!ƒ:ƒ2hÿ@¡þò€Õ oIz‰¼9B½A&䊑E|Q‹,D¡ÚP¨‘|¡)]Ð39—Th¤CŽÈ™28Àäc 3n@À€Q(Ì€>«!“T° $€<Zm_¤Ÿ¦á¨êKÜ–£fÂÐF”(²ø™Y<Ð ›Ø‚kx Ë”Ã/l#$)|ÊŽ;ò`X’áUª%:H N˜B~ F!¾O<†„B‡· �%8A­€pHÒ@öÈ B@×Õmä)Ëœ³: Ù@=Ðú‚/*‹~€ãD„‡\Ñj€di€@dpظ{J  ÿâ°šÕ6Rû�Bb2™3 ÈÍŒÌE êO€Âæ®#JìR ¬³“‘RÑ¿”f >࣠Îóu¤ ú+Ï!jp‰°é5(IÂnì‘@ü`yâdÅ:E œv  a¸ŠˆŸìsy‰÷7âá�!óµò{‹%k©Á¥€F3œëY”0 Mµˆ[˜ÉrãD¡  3°¯â\ƒG»E?¡`‚2œ„µA¨±Ù<¯*t‘M€ Æ/7öepH eKhòØ‘ ¢Ö ¼Ägmf°3„ Åxz´V:Î= "ÔÒÅCâ|ÿ>\’ä 8‚`p&’ñÀ ¶Y vpJõÔÀ¾í‡] ‚¤ùöh mVƒ§ s扬7 €šbLކ€>.7âSHUB ’‚ͮɴ „NÏðÜU¥à©ZÑCtQ²n#M9A1‹Úá€8¡ÈÁaåHcy“P\ ¤wÂ/>�‰²à¿Z#GÉŠ‘‚ºÂ™¡Á´-…Δ\E@Å VP—1x?`B| „4ƒ<n1Bç�ƒ?!¤:öMìF¤4Äw>bEkFÜòÀÆ´–³ aš­07Î\hÝú´ó‚:0ƒN¡áÿÄ™.Àxïш'!#’­EÝaÔË€ÛÊLÀî„øµÉàF™±C¢¨©Er?‹Þ�ƒ)"2Á  ƒ“üÂzyC$*SÏ44À\ÁX‰‘âCÙ¬LE3D|ïá Ó÷~û58j¤vôpˆ°Y±?gp.à&À ÐÕ¡i(À|†–°!Æ(rb~ ‰440_0]ù´J®óQšÂ8 TuÓ@+ ?9‚v€�Yàj,ƒ\ùõ‰´U¬°UˆpO#e6Ð)Ð+•� «P"‡k.B!P3&æÒ ”P<4àõ€wE5`ÿ $tÀ"à÷q?Pa;…$ ¦Ò|4� ±+k0\Ç2Ô1”0†¡id<) �MrR•~öÐ7p›0CÐW4`_?09"Ç€!D # @� †@v�+ 5[1WcÑC&dàñ0B^Q<#Âqˆ¾•$ VÚÐ$`l!  ‡GâBü[=ÂÃ&"7§@$Ãt¡â]o0<Ló¬Q7öðÂbN?pK¥T8$6 àDËà‡òiB9´ô1GcÅ03•0¨‚_À`iòñ! …¼¸ÌÈ ÿ$@[+€" ©D‚¢M$ÕÁ2™Ñ6hT‘±D±å Ô�çÁZ:°ûKÏe¨ð¾50:q(Þ¤Èá�CT;®õ ò°b~ÆóåÂ8?>&E?ñ�æ²FZ�Ú ( è3Q ~áx<�t�6Ï¢V'� À‘!à†e’ua!¿1"ð†<ðÕA…? D£ç1\†EVÐä&aÑK30ð§L…èôy0K¥dXF@(¸'X+†d*¡ØDð‰ð5¦�+d¡4kãiRÿsΰ6Ʀ€9‚ñѵ4b !Å20 ) }£ÿÌ iÔ¨ƒ?`‚K¹qõÐ*q€Rã ©`ß1 ½yýðÀð4×– Â(ôð aHzñ0vd6e$I ÄeG 4Kußñ ÔäyB d† pHÄsopoð5á-A‘ÂðÖ50ÒpðÓ4°%±ã2”–‚¹Ä/< 1‚PK†xÃô.ãi¨”o02–C“-Aã&¶‡Ë�µ ¡'¶P 40— šòs•! TLZÉÔµ}•“’,A™J2l]°6Å ΈA\ 8r¡¬ð¡"—ÿ# `ôprÌ� �ð†0\ÍÿB2Óâ æ@ #`¨op£V ¼Ø(?ÄX2F!Ñäb ø€5¿ $B" Õ$©Ð - ~3d’WA.q€�fÀiÒÀ+ð­Ã†tSaH\Œ 2Ëðíàš�,)à^“^w(r37±Õ@`’Oà æâ% âS#à êÅ,ÖD­Y aŠ €Ÿ+Õ�t•wŸ‚ ­x[ÀT÷±:²pkÔ�ùµD]Z,›#•/|v$]@+]B k2bÁ÷0•ÑÌZö -4{7¤)Wç°sK * ÑÿYæÔ(w²ƒœ‘:Ô@r¸€ x± ?ÐIp&¤Õ`Zù‘фɀ5àÚ #Å©/¿ÀJc#à$ç1PXo¡?Èp) ² 4CZã(û:/Q7ùÔ,+°:i@q çÀÛ…­ ° -pYA4GvP[±C %Dp#Ó’:°6"h[jé—¯zHÁ‘]M2 åñDQ<çA# Œe+µ-Œ@F ‘Ñ´u‡*`4ÉP xHäÈ2¥¤Š™V CÏrÚ¤iiP@Ä2[0\Äåš‚P¢Å� P”b�ù"ð,°ÿ0ê’¡€R¢¥”ÉVJä6Ž W©¤zfÔ:­S´h6A¸…âñb! NÄEÇ7'F1‡¥Ö�•©£ wòei«ÃV„+£$"eé @! ªøÐâ ñIÎtÇ=sæ #°“! ðÂ?  ö`À}E@†àÛ°rX¯•¡j:ÐkìÁg€x‡Hó*ùBnàV¥„?u#°9”}íªwv@—Ë�O4 '›€Hòyƒ °œ’#`�4@$‡ b“‡j%)6ðŒ8L³k¦¸Ö@qH½©\)X gP:ÉGÿQCÀ`àB0rð\öE/Q^!µ¤¸ÃTˆ�FS:Ó5qûóÉ‘°‡ÐD£wì— �OL(ù~ªѲ&-08A‡�º€# o  € -dÌTl4·ið�+�#C¡JR‘L9¢š3¡jà2  A:3èA!� `9ų¤8B(çi’Yâ�i�¦Øýà! Žy>™kñµ_# 7Ü�ë úõ�i¢/Ç· „¡a @Ð¤Îøyb9Èе® l!6 G#±8kÐ¥da"çð4[°L}!Icpkð�î“)Øzÿnà[ ¨¡ØA¬ðMšF†rDÐ�i�މê( ¯ øÂ!³“•Ñ#J¤«²Õ•�XÚ�3nAM@ÉK¦ÿ¢¿1¶b� ‡ ©‚¥Â$¡¶.Æ^u& 5�gºcc,Ð _°`‡ðޱSv,ñ:}q R™ÜÐëµø!à~¸2ë$ͤë]nt,²°&Âà¿–1id uÚ“‰ŒpÔ/‡­í+Ð)& Ä ›”Cà‰ŒÎ@p�4- [ [pê«J¦$´ò @ o° ôÁ`U  ?}Õ°¤ÿ4:ÀL´E12`!0¹U &… iºKv‘Ìq víp²T€­'¤¥e`³ âK„ V7¡q;P9}�‚ñ¯6PPИ'àÀíEd§ "-v’Í� ç À†7 lDcñF"¦€ q–¤ÅYZ0,`+ct`�#@¤U»¾ßð C)2À�ä µ“±Æ-!â 9 '‰L0•±zÆÂ7ã@.ªÃC¾)C¡Ë3dbD¼ xÁÆC;=¡P0P¨!$OvfiÏ @+¬3ZÈ€¸S"*ké?¾�¥ @0tà k¤€RÝñÿŽç ÀKh$2¼HDAì }ËT)Ð$êl6*Á£ýš¹µ°ù…ðÂ;M±¼öü@”=Á³‚>+(À±ÃÀD!èHÑ�ËS5á5<ªÖ¤†$$Hs\F²6ª2)(@� °”~+@¾u�+®3Ã3 y!!ŒR3¡². š0ŽÙ§€4�z‰û,zyçx´å›^×ÿå�Wáx$“wñ=AT 14@Už¶dÃÓãèI̸»“oáuž°S#¬ yÔüW¼”_r$Y¾1Y�3°;•^9ÁNq£ ú.€$Ïå§šq÷H¤{ÿ,e’ðÓ(@~0à!‘DãðŒ/qÔµ 1P …"ð†¦Ñv0< » ê5A¢ávò~…R5�(2ÂpdËkÐ��$¹^±E+ðJ:@D¤#ÐpÉÜE¤3¥ éeÇ&j² 6�¾ù´€t $D›œR²” +Òr!p(³w*á&%‚'ÒLÎ A�ƒW],À˜·$ÝÝùiäѯš"0ãñ5»ÃÓs$û“—.€�ÉQç!ð†‹N‚"�ÎÞªœ¶ì¿QL–Mz!œ íÆÝ‚ 4á…À®€€Ýõr.’ " òtØ yH•0ÿ\f@bËІ! ! ŽI$o` ¶µ_ nÀãˆ5Â8)SÚñ&YÁ‡g(€i_?ª¨ 6‰Vkñ#†PáåiÊÒ›¾):0jvæuû�¤©@“K ŽFJk::(+!"(6NG@@:@G[7:702<@7"!('"-6((!Ї)422…F?72­q:20·0Y?…5™7.0 ''&,2)šo"+4Ð(q$Ðv"")):$!Ú664:6@<+o<<ZC6<406D@+6+#)µ4â2™4€ä§îÆ 6Ô¨B„#CtpJC…‹fÿš£Áƒ%"6ŒðQK“Cq`¤ð0Bœ!N¸È…âFÀ‡¬Ðð ¾Ä»qæF f`\„bÆ ":È‚!¬tŒ[”bÅO(F`KÑb…ŽäZ!Èå‚“<RÌ#’cE(j bƒ‡¦pêµ²‘ÃÜŽ=€l2D$…5 $Jâñåá' @ ¬¸P×|dÜ£Ñ"¬›wOÔ€&¦"ŒRTP"ÌÍ­ `4Sã S':œ8õ)Dßœ@Ò¸ñåÆªitœqq"ŇV¤(&ZF:û ­mN‰ûD°ñ G’µdæñ \C:´Hrÿ£È?<a„%œ¬15ADF,lj9[ðð^ "È0B?=ô ùôÃCfäÀ ¢‚‚Dlà üp Á#+j‡ci#B@œRŽE(a , “ÂH0–(ñpÀ"ÊlÏ $uÅ‘X­@‘\´"š $ÝÂÑ<æððà ™‚É ?´ i4Ì!)Ä[ÏO:äà˜4бIŽ€”Ãêä§4GVÄ%~°èÀÀã`ud ¶BCZÑ¥,4˜`<.¡Ó8#t�Â"(#ÂIÊ ÊxâhFÃyQ¹L`4à�>v@’‡Ðüé�&ÿ?” É n”ÃÃ<¬qCB� <äðà@CG`ƃåijI8~Ú@ ˜“†9$øùE!áÅ%i2vD$ÁcÃ>v´ÒBá€6øB°Ô”‚ (0Œ…*aS iŒTÎÚa& ¶ÂS–Ó @C6(ð$jä † ðŽÃP(Œs€ø]²‚6D6Ù~DD$ƒ*K b)PŠhqªsN8€ói4Ô`n‘& G˲q$p‚>È gÐà€¼+Tóð s̬ ˜£ô•4ˆ0O+1ÇLÒ Ä%B’6ر‚@€±òrí$§D+ÏJb8 C$áƒÿLlÑ�´ó4JÀkDIfàº<Œ ƒ$Úá,`<  "Øñ^;+ªçËáOiæ&q´ÎÀvV48]$köL^5Œ4¬ôÀ?Ô#ä°$|¬ÈP±vÔrΘ^"IJ㠄“&Z‰”ØEx1Ä?¬¨Ã±“‰c„:Q…F0‚@ƒh%J:0'Ì„•€hÅÆ8 !º`+³Á²@Ý�i…@ƒ/,!éÐ Ž¨£"ñØ €‚9èespF)ö…°VÐAJ@À’fö1eÈÀO±Š Öuèಀ޵_Ì"ÿÁËÅ…Qƒ£ü ùÁ¶HwT‘/ ´PaÄ…•´dX éŠ`äÒ‡0 tÝ1±8 óHŽ9| h™c0 ŽÑ€5�SРÚèx¼h"}:¨Œ@R \˜eP ŒC ©h=$R!äÈjbøæJY“/Òp‰¾˜Ã‘ø¶Ð "Ú .aÈZÐ' Á»žhVPŠ:¤Î ˆïðSˆè4`øáˆD`•NèÀø� (‰´¡+-€¦é̃T)áÓD(ùr'DB” &AüÀIš}¹D!~!üÄò>QÊ&*&#$ÁÿIÔôú•£îK@Êr<Ť³/ÐàP €°�Ù nˆ2³iŽHäâ ¤Lƒ@b>0AÔ@6WØ¡v4Hi 3’uµ"fqA@‘ÀBé åo S¦±“ãÐåA"‘‘¨ZP¨Dˆ „Žb“"QGÀr+í(bIB °±Ï†d=~êç`zð€à†ex1@šH”¾,€TZ'(À 1 D¤9X@¦L¦¹€$ïj8¾ô¬ZØÀ< ´³ð9c/ýLgMx²§ÔÐÒ&„¢’X:Ãkfîeƒ5 !´0è‚ShB)ºÿ>8B¥ÐvK9‘Ö ÂáCðÅ0Ñš°‚ PHçZ@µ±�åœ Œö(†]­ 4ƒÓЍ7ŸxÀÈ¬à‹ŸTŠ–v‰$H‘A ¨#ƒ!ÀÀ†Òä.1„/1é ~ ðƒ!´€.5hì0… t�œ(K¸8D×r�¡pleÿÔ±Œñx¥h‚]ZhC.èB;žá'¬Ô‚v(€.<t¨+¸ÁõÞ`�;ëAðømøRèI‰^ äBÀT2ÄÁ(0*‚pãHüçîTZ.8a„5ŒDS<H… FšØ•Ä〖uÖ d7¦À™.ÛHÿ—’¡+��£Åòí«å=ÔõH£ ¸@¤ó,O\‚¾üH+É&4©*èíÉm"1a=êĬ9œÌÑU¸aº0‘A}ÜÁ¡ ‚4(Ìʨ ¹ÝÊcYV„ØCp€€«7‘QÚùÍUôaËa)v÷PŸh yŽè×ðza‚³‰ËgÙDy›g2‹L–I5@ò­ *qèG´øŠÀ°�F¨8 5q$‰(Å…HHÄîZÜ*ŒC¢£Ì@Š B¡$b'¿päPB=üº¸üÃ"é(˜>#«À�n8AܯÿYp$‹‰ÑB"1¢Ë̳DÑˆÒ -àx6áÔHrƒüg Kå ^!\4 ŸºàÐ=˜ùŒVüm”ˆ@»´å ä=0fÉô…»È¥©<ƒ :ñ ¾lÒ›C24<«<LÀ’S -(¶ RE ášx!àÓ'¦‡É§"o¸¯K]…lJC lhm’šæøàYnn…CeR‹ðeeýìˆ)¦ËG(!²ƒ²H0»KXYá‹Òz„ <c€½DH¸ÙÔÇ€x¢‘H.Ú´‘\/(x¾ÈÅ!šˆÃ¶wÌ`<p‚ŠÀËE ÿkÀ%$Üœ5Tà `r¹Àø± @=‹B+WTŒEÐq068õh'¡¦M.à>&ð0O‡v~T1 @ZÁfø< ð1 a ó0¸� 6¥.´P¡À@rƒ34„oQZ<µ?@Šq @:·ð6C#<0?`�OìQ@åÐ: =`2p�(B8É÷[¡ð+@{Œa&ŽsT5RÁ- B<@`‚AHá£m‘ Xq0EÁy@2e'­´9‰"+7g ;›E0r0`1(ÿ<$áS;˜6ý33‹Â` ÇbÒ¡næ“�¸b€A<µ-N0á3• }òK”ða Š½çFàD¥F€/ëµ2OׂGN%‡„-®“TU;Ñòiµ ¹ð:01*zâ*pv€I7P~K€Bè<ò[t‘i5Eqº)–ˆ ]Då �ÓכğÃñ¦'!òv!‡Ðâç|!S¡ã +p ÐMài Q;‘(1âfÚÒ q`Z‰ƒAðMU•" ' ûðä0…Ý£e 4½PO$05È´Ÿ'ÿ‘ódvFe™ wq„ñGþp¸4òjà€9�LîA€¹Ð�î!| ¥76]HC×Mæs'cs-œð¤-ØÔ^òJÓ&(>?0Ž¿!>/ÔJŠa3ðA ÐEf`eNáBÂ� eô-ð°t´ÐIeƒ(Ð@¥ ’„sbÜr…ky¥Xó 8¶“[D |ñyêðEÞ±Á@O@1ÒR¾I zÂÚÒI¸€…'zÆÈ4ÂY2'3Ã�fpͳv™‡/”„ð-ã@Ð3CPNÄ�ƒsQÒ“2Éq*äG K€b Pÿ–D�ŽÃP‰øÑ�@@5(а¤ÔÕ�ÿ� wÉ2]´J /)Î&t˜p¡·‘YZQ<à$Á8lfx/âN33CQ >Ô‚è(yZOЯáDqŸ B6 ~jpQ€b°ÖñùyoTB‘@?ð¢9hO6ðyÀ2¼+ Ñ ‹´|‘ 5ñpnpsìQ_ÐUA$‹BçŒyÿÀ‘¿ÅŒ%Ù`“åP%…‡…!ƒÙà4 6 .tê0iÈ>’#$Fø1 Q°G°�€âÒsX–D:R2bê €˧ÿ@?p¡9vø s }*.…ð¶D;oæ }JM;øŠó4 гÊ @ ~q;� vPŠ.¹·E&Pu0‡Q'-x€ ÅŒâ0ìÑ(vjW0iÐóYâšQã!Ê�ïÐUJ‘ˆ1òD €‚i°Ï0 úD…ð[¡t žúBa fàzpaƒc#a2#?Áb` uÀP‡L$ñ°|ѰÀ§%Иm6 ®“+8´ÀðXAÙsƒ`(Fuœ@  DGàXOS /’ˆþôlYÅbð¤<P!QŒaÿ!+@�!u6Äw¼¤n² •á�]• Œ#QhBš±J?1gà p÷À˜A V6FqYò¿![ÔaØDÝ y1HE€KtáruµRá­éäWÌ·B=0”pùQFà´ †%lr?‚ØP˜Â‹jÐD³D4'¹JÈB!S@›P6‰"„5àec"+.09ÖI°àf›yZà›4¢ ¥OñBOT¾` ºy¢›#Ò² ®�ºcx2@êžWQvœ@©<ꞟ‡,eäöFMÀS³ñG~¤‘P�&- �í´›à`’™þ$€J‘'Žÿ>‘® ’:p=†7ä@a»T@×D'0. €Ì©(Â….äÀÛ&ñ«0PÃ!¬6ªá2õ0 ? Ÿ×{N!ÄGਠñyÙiðY ½÷ê [°DéSN O¸¿B 0ZA£~ä*[blË6u-·�µšp pe À¬G¡ð 0@%JA>ð—à þñQ=�r-`‰1¹à0ðHUf�CVç@²i>ý@Vk *¤^† @PïáFJá,ýs~z¢)ö�HŠÁ‘Ø¢1l…<ÙôOéó-eÒªÁÓKs0 ’f]TÿgìNÊ_`ã¸ôD?0B� ,¬@Za{xc2/Be›€ÄÔÚpthî@÷0ž Q›4s<š³fÑg­”«5ª9ŒUG8A“ÔÔ²µ~â�à¢4  ºH¾ 4:0¶– ›³‡&p ©ù0)�^À”U`*ë8�Ø Æ3NFDgxA¥Ë ©Ýo"ç¦ib*™e-Ѭ4ì1}2p `sßò„qW‘«$¹(â@6‹Í÷ÀM@¯ãð[†w…p@êAu ðtÃ"Ñ� …'IüIͶ¿÷*°9º÷cbËÎ<�ÿiàtñ]BJiИáSä�z¨’)}5êBê@Z û’„ýÔïðý"˜-ÐÐ\· [jx¾ *!>›¥ õÑ:Cð¾Ñ/)P³hB-˜¡•JÀþkJ#)ö4y§šñBj•(ÆA¡8¡Åײ%6+#h!rÒÁÍOô[Ð œ•M/´¾ –>çÉt˜Ä«jlj 9 `Á�+3(Iv-b£„ð[Î)µ5µ¦Ù¿U i€ yÐÐ�q@5ˆ\£MSprBýs ¡ä¯GÍ¡=ÎøØ]U´1“›ý©@ðÎê&­jÒíÏ…ÿ T™£Y¡nÊlwúå|ÛUÿà b'~y" p P1�)C­“ÖGR¥Å‡1œñ+MÕ™a'6ðÓnPÐ&0Pa!šÒëkF…¹Œ´Z`ÎB8!ÕW‘}¡;Ø¢4!$Eq Ç^ÎÐ�²£ œÒ¸ƒÊ4RE�…€}—§{3^bÏàÿÀž»iPøÙ}µH™I(<5DVø(ÕCÜi°8îÔKŠU¨«`âG‚i»f8†¢ `:ƒGÈ?pÉ6A.5•.„Mš ÂߣA¹à=6õ6¥“_Öªz2¥ D;1 žå/݇ŽPÿÜdvB“ta8@’š{ÙO$¡½ d QGË" Ø,À%íF…I>д¬0p êp kªªE0ã¶,íB{vsCÑê-Ý« °y&Ô ¶ø #+à'#QXøh;xå±iHd.>R~R÷ÛRAÏ:a³)^EOM…ÆŽ×%7÷¢ÿ&ì2r%Z1}pÂkÙ¬âC¥-¹¿XÕ 4­ 67¬…€·A –sÖY§o†OñeJcñœ/òö 1Ù{*¼-ÝòX^&ù· öÆ&ÒêÙ÷•bFZ±00ò+ôäãÙ.ÉÜ‚�ºÓW@²ˆÓSñMÛ°³ÿëã�Oàgì¼FM*9Þ[ƒkr2þ)wKÄ�ZÐiìa ÁRV3›øÑµ³‡ÂA”¨{,añe0ð-¥jx A86´b¯7£"QG‚ñ¡ä aåÌvQ 7&>ø~tÀ�­îëfdk B×ó]ýª|þ€Ia �פ›´]øUÞÆ˜zi’‹j‘åQ1‘ö‚KŠ~­8kБnA•›ºaœ$™á§ÜÄSoƼ›* Û7*0ƒÍ87¡Úpkí ×$P—Л›¡þÙ:ųïjÅa2.& ïe¡¥b幨øÑ~ Z¨ÿ– 'I'nFå9’o<ÜÔO¸)(49@<C<@i<<[:44<<“i4‡<64-<:g7)+)422)6@+466Œ›>0.(2 2´25Z:@6”C:ŒFa@2:k:<i@‡ g¤“”Š<D@†Í@FÓ4i©Ø½DDžÒ<>>7:ë g?ˆ:7êE?^‰’̇@“Íj‡CF$µj Œ ¦5ÊDéË>I•t¤€câ*+z]< ƒ5I4˜zcª† Ož’ IÔQQêd4;XäÆ)M’âÈ�dœn<Ö(Ä4³cÏ}q‚*2²†Ð!ît(²æ$7?"Ý8ãÀPÿ0Lêh )RGŒ'[¥J ’U>_š*ÉXqL‡)Š(*êX±ÂΊMoPˆZµâ@Šg”aýq#¨<ï¡°©# y¼Œt„Ä ˆeÎ$SDÄHUe<(ˆÙ§„Ȧ¤‡Ö5ƒ@ÉA@#tliLIŸ¯6'UP‰â1Si|åÑ"%_ 2ÓÄÐÆ_°gdO!†™‰‚xäq’F "HæEÖ�’]Pë‚5ëã [’„9$‰¬çk¨EZi4¼ÚI<Øñ%L„CHÇ [„UKëœdJ>½tô•$[”W H½8‡ #ŠÐàH7ÏáÔ‘]‡q‡•$-¬°—Z6cÿ ÁI2„…C´NØ(± gÀÀ@ vP�”&ŸPÈÃbQ6>¡ÃóÅDBÀÜ�QÇ4㉠:£È7Ôp ÷1ȃl5°Âc’œ 3&òp�%—´â‰]q·IqvÑ\Î=æÀ ôòç–=áP2“¬3ç6FL<20sß’lÍ £H2�õC_¸ÆC½Å&T/:|µ ÔäO|ÔÁùæa>ü0ÄCÈp�#£D’�FÜ!ÇŠu%gÃ\Ù ‰CC0PQ y ‰vÜaÔœ$פa �E¢H<‰üÂC”ØA« 9lRŒuËTÂå6 Ä‘Û ö¤6ÿ„JÓ$b&X´õDÞe7ÜLŒù0¤@¥$0H^îdå Y· ¯rEcÐT]miòÊ!gˆ@ÊH(üup˜\+ƒ!š(Áà qdeC@©É r«TbI*¾�A[RãÃCnÓxš7ÜÅC nÌɃÏýÐ<ÆRÚ)28"É((,i nÐbŽ ®ìÃÝa§¦& ;ŽûH­˜ ƒÜÂɰ†/#‚+IE )¢ –Lƒš'bR?©ŒcD3›kÙ¯"òJŠüäÜ'„”®×<0F%¦PB߯ŒK ¸G{!‹ÔbGYò"ŽØ°“Ýu¦tYo¬@Nàð»ÿIE7ôÍÐ/+]¥ Êh™k¨ó4ÊäpÍ8é`C@ÞÌ” Cš~ç¹""Ô#7piÄŸð#¤ °ÒàFиBU"1²3Åd2W4À›€ŽßWŠäÝâÐ"E+0²6„DF:³Ë1ˆd¤x0`Kr‘J0×=…å@GÞLT„*ÁH6XC¼n�/lÎqðY<Ð&U‘gixÀ%ŽA5ð ") [:"’Hô'yqÀ\²‰‡ˆÇ~™@d‡$Sä…$z²Y)6æ1Ñ&‹DV¾5 È[€&x´3qc” Ï\æ€C€ÃJÈâAR€ø _("ÿ:€‰ HbƒøD.Ê™]””%î Üá A4Eª¤2G¡ÚR¨4DÇÑšäaÄ3Šî À>IÃÙ‹t`%³BßðD3(p ^¬Ãwí&ÐG5©7žÊ jz" 8ikP'ò8@(]t‹¤&®Õ�Wª<´Ddƃ°#¦è#$áˆåTp0qÀoÄ3—xò…03»Úý¦iZZXwèFFØÅLž•XÑšk˜ÏD¨@k´¤ƒbXŽ*ب ì¨¡)My*­¢D²3 ;8A¿K(@‹æ¬ fÙGZ )o8 ´ªîì‘ü(f4ÿê¸z‘‚/šç «„ìÅÄ E,T¡[ÃÌ0_(cäP†Ž@'ôÀ'GH«8´ÊÕŠ·$ N¸Ç*D¬„½ãQwNð†€± åÊwH²M4‡i#R“Ùd ÍSDK'ŒÛ dæX:À °@P$¡Ùx° µÔ9½ÁƒÄtÏ?@‘xfšE~J( ŽÐƒ³R V9xÀ6’¡ªHøç_IUG¸ô20ÃÊ8�:‰‘žÒ(Õ^< Qs©Ï\–7 ¶lÒ<hº…äOÆÒªÏÙ,ÐÊ#O¬uÏ!ùL L’#-m¥±“h…%"Ä0‰æsÂù=¶q ä I9çÔÎ(’$ p oâÅ!Ìà‚ûÐ`¥’ÐF² ¸Ì'@[|ñ—JØ ȱ¢Ÿè¶¼H�;����������������������������������������./saods9/blt3.0.1/demos/images/mini-display.gif�����������������������������������������������������0000644�0001750�0001750�00000000155�11462120062�017701� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò��²ÀÜÿÿÿ�����ÿÙÙÙ������,�������:ÜÎj‰Ië*ˆÁ{ט4dI‚ÙFæ¹¥c놠<Ã6Šù>Ž—ÄB <ÈN$¢¡ÆH2©H��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/open.gif�������������������������������������������������������������0000644�0001750�0001750�00000000224�11462120062�016240� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ò�����¿¿¿ÿÿÿÿÿ����������!þ$File written by Adobe Photoshop¨ 5.0�,����� ��98Ìúp„8ã‚d!›“ƒ&rP�€Û8š^ë¬UBœÞÀœ¾±¼O£;T)“ÑåΨTš��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/smblue_rock.gif������������������������������������������������������0000644�0001750�0001750�00000007354�11462120062�017617� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aP�P�Õ��ÿÿÿRcZZkcs{{kssckkRZZZccJRRBJJk{{cssZkkRccJZZBRRZssRkkJccZksRck1BJcs{BRZk{„JZc{„ŒZck9BJks{cksJRZBJRRZc19BZcsck{s{ŒRZkJRckkscckRRZZZcJJRccsZZkRRc������������������������������������������������,����P�P��ÿÀÐæSØ„>MÁ y ¡B4„Ú0ϧéøxèñ³é¶BÃÆð9¬Â!´ ©¥ÍgñãP‹…SFn jM '‡_Gsbs*kJB*! sRDtF˜ks+R+h•O Mdk+lŸa•œm*¼lœ ›! Çk)·up*‡[Ì* )[{Y[°—BƒSB•”‚·PudskÈÊMM+÷ò}+Vj+,H$¤C“)„0ùðÀÈ&IÞ1BL¿„cºÙé×€ !C€Ø2 Qu¤@³#Ï@ Šœ9àñˆ ³è¤S ‰ÿ7+Šè7‡@~}²ÓmÐ[Ô ûÐá 5Ÿ(£…S%,C<p°áb„`8©I¨ÎUA ì%°£fK2!Àbµ"Èœ¼#hÕÄÓ)(Ö_wM®8;�‚ŃÒâåB®<Ññ€ ’»«Li½ÒfiçœÊ…Ë/onXx¢E8Y $R•˜mx:lP‘ÕÝ:P6U~ÓœDO)S1ûjƒ Á&Т+„Á:Ci£“€½²BÚÌê–BÅÈ{hsޞ呃ÉÑ,`/Ë‘q^máØO$ÐÉxqŒW è•ÞPdBýÀÔ„`‘ÖSDT"ÿEIK4@A_#VÖ@‚µLhDtL�Jx°À)ÄÓËF »ì2‡Dö#MàsŽF»!€gà)SÇ)eÔs\Œd&á CЂô3…nÇ•5Ì‚P$"F¶AÈ|éTÄu•tä2Ì1ð„Q–ÓÍ!~$õEv<`Â#øäý˜€#œ£P#B¡ <ú·A"%uÕÎź@’E'R8zãPF)Åîl*EiM("Dæ‘rW„aBÅ€¯ ²„&ŒàÁñ@v!V*xQ×p^öuÆ.gp¢¢ž<†(†5v£ìPÂTGÊAÿÇAƒ€Ì •=À0LD€ˆ°á& Aè/*³)N´°ë #†0"2#j¡D7eÍæF ò�h°PqýêF/XÙ¡ ª90¦‘„¬òx6Äus8pqJàÑbkdb2)P8D)Œh„³vD-Œëm@ðfKRà$,œE%LÌ1&¨RÕpØ…Há€ç£N3ÚåónQ…÷:Ô%+$á¨<opB7×’DFTA–;Ž^GÀ 0Ö¼+ß/|±"p¦H‹)/ó0R €éÒdÑž§ |]BÊü!OPÀƒ˜^­kG » 3P?D\S E‘ÿŽ´¬w§tÐA “3Èz 0@ó@›~PÇfEj›Á+k„C!Ç'•q¤Õò¼@Æîn1B&8mÁ×1°_I¼(màc‡¿€Ï“Ürž0¹·Õ�bŽNâ(aŒ„äzM¹65¥MI‚=2ÒOÔ¨%éÄAf¡.I¡Nè_– dèi ÙX™`$_5‚\ ÓIÒú0wýkS‡¢@2ô…oà!ˆqŠˆr…AcÀËøÄFÔ�Ἄ?¢B ¾ïä{3Q†ôº•À=úQ±v¡†Y ¯îÛ�»a>@‡Y•¸Û¦æ ¨(°aƒ ìÕ˜ÿdSÈðÊ‘:â20àPäP‰”‘…„áÍ#qäÛ`†cE!wî˜@  ÃÛ˜#"B3AÆf@…ìJ7²3‡ †/§ •Ø•õœ@),@9§HˆËÆA b…`u "¡jE“,~d.¸Õ„ò…´ �&ðF â0xíé#!@z”3‘#À, )â!(…†•$nÝ¡¯R±)(K’X˜ÜÄ'N<É 'PdÈÖw'8ÜBŒ§PØ4S³´Ùì*"æÐ DÈx bÊò€˜Â¬´áBúCÃ$Â055ikd`¤ƒ'¬L7íbe<TQ(ðÆ„r5`1_7 )øëBÿUÛ‘N Nàh€¨›6™Jà«G‚@&`ÝõlY"Ä$'0€E 8*°xŒ‡Øë:Pž¡$4e¼îHaVjÈ5ÍQ€ @ñ0† '|b5p*BñÔ… Nvcõ'¹¨y$£Ãs ELðÓ˜`’LÂÞ¤ðí!Yí…Cx±·€uD(×1dùN!Li æD¼)9XÅqFÁ‚êô™Äôå™ÂlZl ì¤�)´adDß9Ù0f¹Ã#(`@½Ü6´¡2К~jrE–9À TY'­hSv0[ó ÈPd)ÿB"¿·¬:u£oÂŽ$†ÌæÛsÎþʰ+rè¦ ˜„2…°'5 ‹Nûn¤âv')<G¶îÄÐ>�âh ¯Û›…`¾)22z´)"å¤àWd™úQ�Uò•* Æ™tx ¢ú·œH¡  ”œE[ìK%@É9Í [˜�7yÉ+¬G‘ØÕ^¢„. Â+ !j‚/ ¶¬ +@†N^PM8 r"zZ™oSæÐ½$Fh¹D0b¥“¸ñ­~eIXTüQ—iR”N)×ÔÈHÀJ°nºA�Š�f•8„$&˜@ÓëüD†ëV¶– EM!ÁR%ÿ˜¥³ëÕYh9C’ ²2Ží1aè.ùÈ–Êe÷#šÅÕ¸|T4÷e©¢Úã˜À:iÒ„ÄrÇöl#8Àè„s’© Ð.Ïèúˆ;Y.Œ(ƒ¨þ Fæ»"-p*t<œÌ vƒ¦Ú¸óx<i¦B!TW—+ñ ~a©»ÐظT†^ YDöÕšfÐíYŒˆRz:t%úN&•SY š¯¶X ¤À#b2!!Ù”Œ�Z豂±�{&˜¬+ÂŽõT“ØU3[­D®ÀÚ‘,gÕ·„œ€„-¨µÆå´žFN ·$I­‚ÎÀ/C ÁÑÉÅ„¦È0ÿ‚k'á•QÞN“Ðo'„‹P ù«(=Â,A7ÔxƒY«ó5NÛ’"eM(Riz á´ '&°$¾\’"Tkò8<—‰¨DýÖ/ä `0òï:-@!0À)-®HªÑuˆé‹(­0f©RŒ¢L+'w—„,8`$V“*-‚]I刲sH+Õv­Ø7¤u 29Ç€}Ʋý±ž<“œ [D¥ð(€y?’à¡ïí PeNì0Çàs¥ÏÐT PuH’<f‘…„à9 žpÀ×ù¸oÊç u¼ƒh EˆW ÊB)X6q‘ØU�Â1 RG'ÿ¥"Z #°‚'¹·bʧ2J£qò u,!X)u)Jãp§@h’)âCHG’[3DjÅJz ˆÔcÊ×ø¢X¬£¬“q»p'?è;öm´³zdzL u@jNÐ_©!* Ñ *) aH I—€uy&DFÀC0'”+?g@‡¶¤y@KȰåRá'u¨Uã#D•„11=+êt$¹Ã œG+£0»R8#“‚dt1(§ þsÊ@3…vÙæ!4#‚XI3˜¨ á—ãÒ Ròz |¶·2%$&y8…O0@’B5š‘Jÿ&0E |â4P~ÿšvŸ—]u 0Ê2º‘$^02çp q¯Ô�Õæàõ”‡Wd¹‚j<7T³¡,¾R ¨ÎX7úç²4Ôüæ�³€HZ|ŽGð`R…f<G-0z¢qãÓ!`\€‡ ±½02~!F„ÁŽÃ—L'㊠'±VF)´‘¹Ó„E”;&r'aÑ3¿2(`Œ0/Ф"0ÁN;öäÒ%&4h”9²Žè’Xä;ÃJeàaáQ‡Zã ”Òu%QO‰L ôŽš2’ &IÀHeðJ!€@é2T¦ñ÷ ²cáÚÿ?c<dðq®µÝ'ŠVÐ}âþ¡0”¶à…ÀŽ]1H°Á @o$_Önç7q£<|ƒbbR‡wRu¢_x%]Ñ5‘†Rpˆ2Á`±\JÀ:af~›&Îá›vçÀ3|a  ø=@æ‘t»0û[ÅO ž ö`˜ h™3„!Ž€:Ãö2g†ñîÒ Ïã6ö… ±U C�KPœ¶ƒ ä ¤âTH€�õ©pä²Ê÷0Rµ)ö%Á@51Q da”…TH„ u¥|ƒ�1V*+0 qó”p’3 BXEãaZñ!ïæV¾·ÿƃ7,¹·’ßà›Ek†yOL€5“:Žq(ôá EÀN®ƒÔàvÐVãey¡FŽ32Éð ¡-Ú�ÑBtü¦µˆ©0�¹Ó—q7!ß@ZÐpüÆ%Ò#E²+da)ÔB,° ‚!Þ±r™8¤5°ð>j˜¶óKeêr @o±0üvº08M° :áUcà$`ñó¢@à¡¥yª^^`˜Ñ'+#M<Ó O"_©ÓSù#÷@´›Ð <š‚sq¡"á"ÛÐnù8#FNkèå?â÷\r!Òça;¶¢›á¹=öðnB C¿ IâA��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/blt98.gif������������������������������������������������������������0000644�0001750�0001750�00000107557�11462120062�016262� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aò�T÷��TLN´¬±  D<DÌÄÌļļ´¼ÔÌÔôìôäÜä 4,8 ììüääó´´½ÄÄÍÔÔÝôôü+,59;Fiku"$-‰Œ˜DEI´ÄüÔÜùÄÌ穬¶´Äô¼ÌückGKWUZhÜäüØÜç­Ö¸¼ÆÈÌÖ¬Äü©»åx…¡Ÿ¿ «Ä¼ÆÜ™¦¬Äô´Ìü˜©ÍÀÔü¨¸Øˆ•®¸Èépy‹ÌÜü´ÀØÜäôVWYz{}©ª¬%ÃÔôÌÚôš£³|ƒÉÔ蜴ݴÌô¬ÄꩵȬÌüÔäüèðüŒ¼ü|´ü–ÄüœÄô¤Ìü¬ÌôÃÜü¼ÅÐt´ü|´ô„¼üŒ¼ôt´ô|¼ü„¼ôŒÄû”ÄôœÌü¤Ìô¬Ôü´ÔôÔäôÜìüäìô;FPÊäû|¼óœÌôÌÜꆼç¬Ôô™Çç¹Üô“ÁÝ[fm¹Ôäw²Ï¬´¸ÌÔØ¥Üô¹äôÜäç’ÂÏKUX‹•˜kvx*67 ìüüäôô´¼¼ÔÜÜìôôøüügiiƒ……ÊÌÌÃÄĘ™™~´²—¹· 1.H<<EA !>!Š•ŠÄÌÄ´¼´ÌÔÌäìäÜäÜÔ×Ô&euc¬´«ìôëYeW+6)9E5£¥¢IY?PVLsuq‹ŒŠÀÄ»+7´¶¬ŠŽxlnX«®ŽƒlÅȦ«¬¡ÔÕËõöëäåÛìíã'(›}·¹˜–—‰`b1{}UWX@ÖØ«vwaßợ¤Ž¶·¤Íκ¸¹QQR'¢£V‹ŒX½¾y¬­oÉʆ“”lÖÕ½¼‰‡dc›š XWwwHG88¬«((¾¾*44 „„"XXcc3 qp)DD88ƒƒ?OO2mmF77(EE3aaSLLF¼¼²ÜÜÓÌÌÄ$$#,,+mk )( MLA> TL!4,4, ”ŒŠ4,+ ļ¼¼´´ÜÔÔìäääÜÜìììäääÜÜܼ¼¼´´´888 ,����ò�T�þ�ˆHP‰Aƒ((\Ȱ!Ã.D±¢Å‹3jÌHÄJHˆ©£ DüÈr¢Â%¢\Ér%Ê3•Ìt“çÌ– &¤ðçD1:’&%Q’à@ƒ&Å ¤ $¨˜Ã˜Ô ”bG˜`5Jܱ,W bHpX ÌZ¥Nœ)5åÂ=F•üÁ+ñbC½ ó>l4.T1 +‰‹.ãÇu¡ê”:)S1ou¨Õñ ©\Ä‹…:(ŠRL˜‘$`ó'!i¢U†íWáž ÿå©w4ïÝ:€ÞÖ±Ö‰ý[ïrž owŒNT·kŸÐ©’vZš2bîÈþ> ©Y|òÏá§I©æµÜƇ»Ú{\”tß'Ù/qkŸg5Dm¶©ÔQ õ¤Sv¤Å?ü \|`,•šj¦=àh:馛t¼å5Ú]Òá•WUØ-· U âÇÓ@ì­&]‹9 RSŽ¥õ]b™#I7î7ðK÷ÄS3 „Ðbïq°_ñ1‰ ±±8 I0Q SxÈ U,¡Ä€I‡` ªØÜmJ„„â \[ZHAª©¶bEýwbuUÁI“J¤9ÇS ±5YZZí)Òx"DYbœé0_Rãw!ŸäiFÂ~ò­EÂp@láktÁÁþ`t¡ƒ[°bPA†N±£>8E_�Qd…J,ñÇ< 8T1S�ÒDGJ$áš^1´œº‡GJ€Å 3D(á„Å]µg¤§iˆjEAN¶V.‚ÔmŽ"„Õiå-ÆÂ“’ ^R`¹)\î­§ž£‚1e‘v&ñ:ñÅi¤ÁAn‘ÐE$˜±†eè�…m‘A%ÄFAmdà@Fk„‘ÅM$¡ÄIü±DQ0ÔD_,^$1ÝKa}.‰-UÔí €àîÇÄ”:Ž'•nyHUU²Í5‹r3TwPÉÝxcþRëMJic Ç–[y*ñZTRù ÇrÀn»î >øÅ†“‘†{nÙÙîæDjU…N $¢kuµå· øíDçÊ–Ñ×_ˆín»‚èãžÆvL U]Qc}Äöîí¦£í"nøRšþ®‘¥–zäpvrõ?<Ž»`ƒ½ùóËWa[G‚œýæ3à@B=:Õ_n¼¡ä¦–ÔõÅûGÒÍÖí aÇ6äâ@VꃘŸÔOxÂW¢“?­y¥5!iOߨ¢)!• uBUàÖ"1#ÙÉ|×»—>°+lc‹ªŒ¾øçz$4aú<³ž¬ˆ wtÀ æºßT%Kþª+]Kn³:ŒP  [ØŠ»ìI X™QZ°R£v$_jª›šbÂ;.Â$Aê™—S"¯Áƒu ?h='ÒécNŒÐ㢶|¡²‹\úª'1"=èƒç#!‘Få„Óè-X`ÊÂÄð1ô ø(Áž2ž`é‡ÚYr"Òð†M[š×HG%òOlbÃAIö¤žÅ�?À×eYDÔuÑ+Ùv %’3Ú©H,ìžØ�ˆFጄÈäÞ)‹€Æ WÈB¶ …Pá K˜¬ðƒ%4SØB€Ð+Ì  [X¸ð„(IU° ®@…2h! Lþà@òI†%dAW@C>PP \A ZIO˜`&pa4S¨Ê¦ ›±ç;<d[¾‚Äf‚  À# ?æ™ä+J^öÕ¬]Í‹µá¢¿: ³õÀ6Ò~ŒNzœ ˆ>Až0 åŸ@À…&Dè ìÊB„®�„%Ì©L˜Á¦0&€LJ`Ђ¨P…'¬Å×ã@Ö²@bƒ ÃÄ 1˜M i�ÝhÓš(,66ÂÝû£—”�Œ£IØ^ì@ºÄ"Ì�{šÑb°"ÉÂÏE…ýCò•º«½Ô³_Q o¢©íÑÎNi\æÿ¾7;9Š ªÊ þ$ “ T-4ZX‚°U4¡ ?˜Â¬¹(lá Y�AY½ù„&XJK˜ÂD³`d ÕÂ d ƒèA%èp'LÒ [P‚Π„'„ ä!•‚šÊÞÇ,•ig`Gÿ} IžªoêR'AM˜Ü¬Km³Ñ—8ø~'²QÄ|ZÔÆŠr�*»¢€Öz8±8;a@ŠÇ¯–]\Å0÷Dh=Ž g _ØÞù¢PLœ!Àƒfhº8$$ˆöf¡¾…¡4ë;Íi@œLvá� DZ˜R¤TÈÀrQT‰sÜäw tÈ^mÄï¡/ÙSbþìüÇ?¨uÅ ›Rbå 2„p] øc•Èçaž¶Ù£“õøˆÚ¬k]È<ß`ñŒüÃ9 o°¢àN=ë¹YÇH58Ÿf= ÉÍíä¯.)ÒCÜò,Ãç,h%…eSa–;GåD@Cɨ"ô¿7óš$îsH›Xj)M©¾IU²éâ:~4Ï!¶°aKBEË–¨ó_Øp`g,£Gp• 7àïf¨ÊiZ$ç$h¦Ý‰ƒá¿:d$á‚é>|8E@&¹h'p3Jnˆ˜Dù$XŒ+Ò<AÏJDª³?ŠGí騉!<%!¤Án¸þGÌØ¢¶¶ÉÉ4¥5Òƒ´ |ËÛñÞ‚¤¹(DÈædÓé ÄÁGÓßËé„×sêmÔ’ªlŒ:iA 2¤»ékp³Ó‘y’Om<"õë{–¸ ç-%«/Œ}(9ûÂâêýxØ`ûžOœá›ÏÛÃòþBPs5R0Ù1¿ØƒMÂuÁ‘l¬ÞC̽@WoƒŠWwµå¨óÌ”gO:¿;Ãî¶$Û=—·ºAÄ(ê žRìHåoÜÿ÷´~^Éø…ÈÕó«lÆÇät/üâÓêGxoÏrT¡ää#ø¢ží’a'ßzœ†>áP¯Óºk¿§l¼ðþ@|Î\å8Äté?îž'ŽÜ@Òx/Aö¸Ûƒ½ŽÈÿ*fo—¿üPöµßoÜõœÌ_ÞŸ'`nÇ?"UÝ9²AlÁAo7gB(4v±Ex›CjÈ7vŽ·_r„>ÂÆz´s's©#õòngôB&%?§1,H*rflo÷Qî÷u«%ë 6.…LÖ~¹wwr†gwj—ëòLy†GfG+4htT ·gÇf¦Äz²Åut·|)×.xtG"52Ê@ðAnœzLÁAíT·{ú¦‚B>ˆL_Ç_ó1Ÿg+AD:¶KÖ€s¸a!$ggç�C¨Wþ!±dngZ48l¦|‚†FdÓ~Œ%qxGçfÙ·f'ql†r‹5…•hG åS’ƒ$ˆ#jAV|¦§=Ø|BׄÆaB5ƒq'ˆƒTÄC À^qKÀ~5G®‡qìƒvOò‹ëC6b¦õl}–[0xmË·zö~¨÷lb|–z·7m÷£ø~#36¤AÒsÀôŒ¦Tm�äS8csˆ&[2XG·8ŒÅæn7¡‡à‚F“dZàNÈ„V3€q7^pu_'O jÎ}áX"|ZHxïÈ_2HƒáŠ·è~ã8w¨…q'r²óX’ÓB.”xço¦þLÌW‡¨a1 zr^T††ɦC.±Ñ\aP ¶í¤[ßÄIöJa4 a[Q@U™«ëÄ.Z€TMðQˆ[]†«åk<Õk2ˆ“è~;Ù‘ii‹3ˆ“ÝÈXL”’LxŠF÷Œa×fh[߃r[(—¸GÉvBY\PUP^0ZÀ$ÀP8àMH‹é0G¦ŸCL05¡'$0L¢e2^À^ \L�v¢)mÀÇS§´f©§zné~’¹éL‰›Üx“¸Y€þ•Bϧx/©¸×?c¹‘€ih5˜é#%h÷`‡éø§lN¹0Ÿþ¤:Å'ÎHjΖzøŽ}¦mK4Œ·¨zÀ¦îÇ.q —À —»©œy”BAµ(—¹9wÞxb拇rÅX)§SÖɃ¢g@äÞ)oûi‹Irïw&‰›ð —tè‘Îô›$ŽìÙ&¦„Ê7“Ù“Ù÷›ÚH‡®ˆwθ{!æNeW) a ¡&Êxƒy¸ ±6Â4”(CoŸä¹›–vGu¤rI‰FÚ›«'¤áx¡rIruiBJˆ|È÷’·“JƒÊôŠ€Ç¢—¶$”@^ã†Ø?AD_q1Ý9*x¶Ÿr©¥E*v4@žàøž[Úž8éž}Z¤þ”¨é‘¨f½¦„ œI ¡Ãô>™HØno˜P:z˜M &X LM�UaQH0{Ðd€Zp&€0d-T1*pw“ÿó¤íF�r3ps؈ꙖIª¤µù§l©¬ëyç9mh‹xº2ä¥ó§v†„lûá‘0±A£©óîåK°X@b‚b‚4©™_©3QP­ &1 o ·J[!©«ø(ƒ^ ˜HEr- y—�û§Òç›b§žê9¬ƒÚã)wÙx{Z‰¶Yƒq€j—ˆ@vv£Bø@„p�ñà .¢”° ±°þ„ èBJîÙ~É‘ºz40* Mj›y*¨µ‰¬@Ûžýº›Óª¬ rÚ¬H»z˜VN)£ì³ŒJ¶v©P°p®p²\[ãPÿÀî:Õœ*Ú¡9+Ðhñï9´Ìš«ðÉ›ñi¨2´À±¶É¤¸—¢j¥õUÆ–qP9„×` ÎÐhÿP ]˵ð­` Ö:ÝrgŒ÷œÉœ2PmÀÏ`°q§¥C›rÉš¢èI±`w´Fº¥ l*z³êL(_5©A8¦ë` µ <@иÑ4§ëÐ Þbv¶{îD‹M6vDÀ0¸éþy°²{“Ȉƒú¨7+¨ÙÛ´ŽÊ½ û§Ê¥uH˜“jlN™¹à ²€!е†6&O±¼®b’rQà^$ð ƒÀÛ³*8Ð1�‡Îù첓'ôAÐa#Áq÷L¥¥2Ȫ\дÊ“B+q3+´ «½+Ÿw›¬­{¨¹Ç†Ÿwçrpz²èº¿X §Ìý›h «ñAÜÿÊä NS²*Îø«RªQà5\1àÀ_7ÂXàÀZ –Œ5½j¨Ãš}P8´/Œ´g‹|ai˜›L8³†ƒÈ> „K K€P€À¤ºþ@Ì@l@\a0H€]RªîÅOÐTîZ¡9š‹,gU àÔÀ“ÙÃŒÇÁMÅÅXÅ<M°¨+Æ[Ú° ‹¤‚ ¸é™¬4‹¶ÍŠÂ€‰¹Ñ*žrlq# /Syܵl·d‹qðö -Ê~dòQ]i‰²››lU`§Úë°…Š›pk¥°K´røŽ¸.ì·†˜{T}fÆrœvì`¢T ¿|²oƒ–Jtsæ“æœp ¥Ýë°ð™¡¤«««,·ÓüÏ⹯ú(H.:‹h‹n–ŸQH@ÄÅãËëŒ&ùZÐx÷Ÿ(…>‹Ï¹ZÏ,\Æh‹¡¥+¾,œÆr µ`ºˆ xþz( ©·Ð»ÜIôÓ`®ãË)ÑÌ{=ÿÙaÿ9Gg¶ÚK¤Üë¤@ °Ërè¨oÜÊ-‡u뜼§ªèÎwöÑ:‡êƒ¿#??!72J«SÓ_TK³qD‰EÏŒ—>†ÓfÛd}›·ýÊ×ûÖ! ¸P˜ÊBq¥gƒkuf7BbIÔKš>I Ÿ´!þ‘Ò¡·¡ƒ]}?®Ãa'gMÑó|wÛ3½ž ;q žýqÙ °JÕƒ9ˆ¯Ge‘vي҈ƽYƒý±!aÄJýFqXY¤&œuÑÕ.U¦7í�è“aŠÙòF³{ÖÂj³¨›ŸnþɤoLÂ?jqƒ«™ÉCøÕv‰õqƒ­=‰td?’q‹¢(¯† &D ¶/SÑÞ¶ ·ªÚ'­‚ÇL$ ½þ¼zÞØÆ›T,C%i¤«%¾‡Üì±ÝY{¯ÝƒÏL×î4d˜#74`¡“ŒèÍ"(ÂRôFÂ!rÇí`!‘±Q+€ÊfßÇæ{-ú£¥{·`l°IÍÖP:Ëåè´„ù“P©(ÀÕÔˆŠh{M–V&*G2@ùßÁ$¢Óws¨‘;eÑ2.ÀÝ-Q[µÇø”ÃÌû±."1™ðÈ4v3ŽšJz…çœ9-àIÅÙ<ƒ2£îæ0¡A¨P¿þb±&mwÖmž>Fxž·€‚;u¡r ‘;h¡‡lªIð Ák ª¹¹$0Y!]@«Jðí%^à^î*æO`ΠJp“Jà›^5¬qOcÈaª3À"Q=@[´•3ÀUÌ.ÃÞÙÓ]ÕÍÊíq´8àMj×{T!7”¼H¿ø‡5Û“iHo>÷Æiá~çM1‚é¡[ÐDópÛ¢M`_Ð2:@¾V)•®šV ‹9U©ÄïSÀ>O€”O€d`ªÀÒ-³g&î%É Cîš„bªéMU€ÌÀ8€—MYÕ“»wÜ<þ»§Û·(ŠÑ=i*qò­fªuTb¥Då„ð‘‚{­™“S¢0ïA` Z –³˜@&QÐU�3T0%IÑVÀY + ’<ôXpëY¿Ÿs¡:$P™–iïK [Á–þ9dBîep$Pg�N†fõ^@®ÁØ3“Œ\¿.L� 'Ýnò¬—ÑKã×L˜8 ÖBi·uøS6hˆ£±R¡,¦t¢¢6â¡ZQ#ÙA¹P¢1úF*,ÈÊ6ñ­ ylŸ3ðjb5o Úpu iµË¾Ló‚÷}»„ë×=hÂk¹µg•âòÕ©hsé›Aúþ&íëS`d&‰à³tgƒy#!##"ß,‰×í*ždê}:Þ£Û©øá²”¶ÿÐg iìûû½1ÙyˆDˆD‹ˆgý—ÖœÖú ¸�$”8 ÐB† >Da%“$Á1ãÇ /&)X0LŠRp†5þÀ:tˆ¹ù@Œ;ž|¨„Â%aH€á„ÃJ —)ÆE¡)0¬ˆ$‰0SB|8è_(@\à00äÚ‘m’�y®È©)¶ W`”– ZFÁpGÂ…ómÉQ+È‚…ì0á]£ '“„ΉžR þUH¡hF ~œ> „ƒ!Å<€Ý5Œ˜ƒ“^ez*Κhª–;ò3è«€¢`E ²+ñÈEëbQärªEIµnT¸×áTµ_Ø7qËÂ?‚Oxà¤"A7‡ïpè»J“Êå®Õ„‘“ö 5ÕÀ¸© Øvz- %¸P‰(”H‚‹)�yB‰(¦Ø#‰ˆþ0鮣îÓ‚„)”˜¢‰0(x‚‹(’ð‚Â'ªªÚŠ‹O2óº®:z+Gþ& 颤2šÁ/ò [ê<%Ï+,$’$ª1J«€¼o«;é!¢È*J"Šh5z ãPA1¼`BŒ%ZÄ‹ K$þQ‰â" ÑÖX‚.HXãB½ `Š(˜£‰Ü¸hB @¸,È?®¢Qʈ( i¸þú#Ž>ªNÚT´·Ò#²H#=Âo«µV…«Êý³4JLWãÊN˜q¦LšãR * ¤MÍ`;{¢Ñ'ÌØ#/Z\–Â0ZÄ3‰=h" š MÑ?`ÐÏ'˜Œg½ãQ'«Šìžæ&#i*Ðö˜¯¿xÓÞùÍ"Ëo#_—‚+‰ÝIº¸¢ÖXk•.%žag–~6á5`­Æ´ Á:4É`Åø‚ ¢*e1>ú–óÂч¼8ΡŠÜ«¢}ìY×+æ]WÞ=•T~þK L+¹"©èì >wç…—§’¢#¾—­ü4Ma?Þé­¡\x2…ᣀh¡v޹¡{ôA€¡JXáù=)¿Æ7«ðÆ3,Iü ÂÎÝŠ¨"Z8•—fúÇ·‹2hªþ´.i'‰êñ?î• Èžh92Q;mΖYPÙÇò« }Û9£J=Ò©óœl‹ï·p$œ$¥gÚ±²-·.á)QšŠq„(ÚZ(-mˆe2b ƒŒ$^œÁ É«¸“!$4 c‰…*L^r/f�$y™�ãË¢ÅðY‡k9ä82$ @¸� Bì8\%M0ž˜„RãÈÖ¿L!zv’ÍþT•)Ê\v U^w»„ dRC ðèç=ýMo ãDª`†0á #L‚ô¦ð,\M0‘žš@&8ä8å’^›0T A •ÄB–ÀöByå‚_C @0¡r 1 –Ð(’ ù Ì_p À¸pE âZ"‰Nè… …A)§³‹à ¸F†ÑgvøÂÙ¦Èà(%4¡E5„¤§…6Q3€¡눕@.A áò£b…D™ˆ aa±þöG%LQ‡‰âüª`¢*2„K¨d£V…2ä dáƒ.ù-„È2¾JB¦C‘F9   C ½Ð„¼R K˜ÞþÈFbNi‚`éO”ªÃÛ4ñNp ]1¥ÙL½2 LeWL„%$ÓefüÈ/íâMoNSšå4§sðE£aJ&4é4§‡&¶`niuJˆÀ€²©u¶ž²ª?›ÉÆ€jÉŸ’]q ÙƒRS°k˜ª–óÈ`gTæáJ¨ø)Ì…þ³¢É¤”@߉Î"B¤\ôÞ{®B«Àè¤*{–Dâqí_0ÂJE9ø(FÑCid&ä“6 a jÂþѸ«2iA˜Fª~zlR—TCz› UÊŒ€˜"ä2´pYÏ:Qh”¼zav¤€ô2¯¦L $A‚5þ-¡\ÇÔ! 69B&x/ w­Â¦¸‡*¯yÉMCž°÷åÆN[p@n´É'"s2ŸiÞ:•‘e•ªVÍY¨”pA­JÕˆ ½J¹ k”ë­ðzJ¤ÑȨ¢À¶H£ð{¤^ó˜Är…!‰‘©Â$WXG=²E† a‡úÂ6RÌ£h`¨,ÄUE'Í™wŒBƒ…(3ÚÔ¼LK)ÔºÓS«åÔj'¥5xyM4ýIYHC(ì¡xÀ»Þ˜˜=2<&|K$!¹6z&6ø"ÆÑЊÀkÒ„tiERP¸ŒHG 5¤eϺ”þfJµ®A`U8Ž`æØFúÌ…†;¯I|rßþ¡ÀW«ì¨sP¢5Æ}Æ]öEÉOh<U¶Ô ÔRKCšÐõÙ8ÝkïCX4a|}¡¡È´ÎVV›8ÍF æí|GÛмó67†­åö`ÞÕ^Í'%‘Tš~¢µ“l´sM¨1³ªÞ­êY^Jh”cuåÈLäe79ˆŒb&®„6‰[mÇ&u¯Ö¶Ö^|Ns’oã1Úx,$ŒîÉnv£8NÃw”/k9ÅPa°¾”Ê*Ó[ä$çXÐ7œ¨Þ›µŒé#6é‰ÕHé;Ïõ‚¬}õš9ô#;ãy¤}Í™xãk¹ÜDM5ÑÉ›»Ã!I±z¾-vW‡ø£jWK$Σ•ihA|þКзfáÎT1)Oá�Ml2¦Îä®:“Ñ]Â&µÚùx¬(Á*ÉAÎKÚ?Ü£ÌÀ ¿rï§Ø:ÈwN®fµÜuÌ+MãIgvB%œ;;Þ¸9t^Ð¥s¢p­Bzæw3u†nôQì³a5IÐÅy²(<៲ÙÂwãhG KÎ#Ûtòã3&2ˆ½ 2 ŒeÛÍ÷÷Njt`%äŠ#µTd¼q¤/[ „x€>s…’sÉe¶õÌsí)±gÆWjqqT*R&ŸH%XœîôÓ;Ä*Æ7ýa;àwæ„{7¥#™L4¿’|[ü&#y�á ÿh«þßù¦<ÐsΕ‘SDìl1ˆO ž& ¤� ÊÀÍKwΧ¾ë 4j_Í·‹�òÀVâÍDrÃËYq–sšZUñûÐöØéIÎÁ£ù˜5?P øe’ñé$Û¼&=ÕÓ²XVü"ûÓÈé ‰;ÝÌø‡7NÀrÄUú‚ñ¢ rs-M+¦˜a/q€š ¯v5ƒ#:É>ð˜®x Ã#ºVù—ÓC#'é‚x 8 l ÌAÌAñ{Š}öžðºµH‹Àh ¬+Ó·š�¶Ã ŒQAop%xÐ:ë6ÐØ½MÙ²û‘`¢43ƒ§œéë "D ´ ¹Î°þ óÓ˜ìCP ˆË»ºî[Œ*Q’§ 8Ä( ¿XÃÒàÓH ÕÈ·ÕÐ7ú³  c¿ ÃCŸÛ7{C‹¥Ð¼™è¼¥°·!P4±@7k¹#BÆA9ù"¸©b¨»#(ƒú¬Ï¸;8ë©è `£·šˆ8›@ –x‰¼ºl 2@ ¥0ûè~1•Òø‚�\üð3’0$ 0ƒ-�*Ø‚,Ð+0ƒ5(ø‚.ø0Ø ¡õÈ<0 !¡>Ã?|³A‘H¼Rû²ªécãƒ/t#³àË;°¹Äs§Ù㸾ÓAŒ ‰;|A—ø‹4„ >lŠü 4þ/H\ÌÅø‚ÒÀ"pC˜�+Ø ØèÈ‚-Ð,p‚¥ð‚/˜›Ä`‚ÄØ˜H0ùÀ´ˆA˜(Aœ ¡;s¾73‰KµŸpÄÚø1yÁ»ÖÒÄ\㙲© ¯P»”@‹{ º £¾SÄÇñ�I¾ ÁÉ}l ò"È‚Œ«$H (‚"ø¿ØÅ5‰/üÂÎ[žû À¼ƒtC\¤›‘´<VAÔPÊTT ®C>ãÀ¯ûÄDK5s·û?Mœ+Lûê tžà<|C Š“ ðJ7LÊ\ÊÜÇ~™\ÄÊ\\C¬ŒØÅ5ü>•ä>ÍKÂ\ÃþªìÅŒØG/ù˜à ÌsCÉ|‰AL’¼èŒ¦#¼D;5¡Iùê6ú¨³tS­Ã±1g³*ú aÑÒÜ<Ë#Áñ0’�ÉêœKñ°J«ÄÊ«„LÍ^M0lŠ4œµÜN[üÊÔ×Hž`CÎ\ÃÚÜ<òƒ¿µxЫO`“ÀD󌘔5€Ã ûò7¯˜/%D§lªQó4�¿UtP") ZTC7TK5,’ ]K«ÌÌ–ØÎ( H…<�ù>òdÏ"¹ÊÌ$È‚¼E#)ÁêtC&(-ÀÊ­+Ø'¸œC(€SdÆ/ÐÁÓ#`™ ½éwQ»r¼¯rt»-ÃÉ'%À5ºþ3™ä h|ÊÕˆ_2Wš–¨J mÃìÜÎÕÌ1HÑ5,‚%Ià‚-�¤ôÅ–à#@â¥P¤m-ø‚=- -0 ÍL+8Ï…Ï8\ 3°ÕˆH{3¤X“”‰5°‚& ƒ/ÈàS2x+0Ø‚/Øã±‚?X>’ˆ™49ÿœµ<'Ò 30Êð°L-R‹%ñ¥.5•B%ÓÄàN¬äЂôÐíTH ÊÒÐGÙd‚4Ø`¥_e‚X‚‚|‚@‚)rV £ÒÀÊ<åÎ…LOÓ@ÖÔøBÐI�Bˆ‚¥ÈÈ+HƒCB.€H°H0ƒ,2p0þp“’[ùn1BÜé8·ãJ§¹R8IÁ‰´°Î—0_" � Ö@Q3Ý΋µØ1aS.¨[ô -(ƒ"X¦ÌÌ.�MºJ,à‚`Ù‚¬—å‚<­.¸Å«l‚)’V$àÎÈ‚% S'(’dÝ4B¨4à�-È‚4�‚M¼ø+p‚4° ­Hh+8ž(°1XÐ+P‚*Ø$Ö¢3À$ЭùOM«9“ Á—Ø84Á= ]ÝØ1EQ5’MÓo5Vc-Ö05Hn\ŒÅÊh5Üóô[‚ì ªÝÅ=AØJ?è4Ìc†äº5p"þÖ(‹ ‚ ü¸Fü Ä Þù3Z›¦ÃA /QS6ܾ½NnuÜÞEM`E2ÓÎÌÅ"(S‚<H¶ÖŸý[¿ÕпíUÔ SÐŒÏÓˆ‚T°…;°ŽhÏ"QK‘‰Æ,ÊùEÕ4£ŠsÎM™4»‹ÒK„Û(¡�1H‚»ÍEµLÏëÄP‚ÜL_ÍØ‹ÝßåÜ«DSÇåÌÍÓó<QmÜ_5ÓÆ\ƒ4µ<\7üf0‡xp„u‰ƒ QùœÃÆRú{´+9›¡É¿|"Û(ø½»ÓZÉÕ|ϹlÃŒµX/X^ŒÝPÀ½JÞÎþaíœV=Þ^åØFQ,ÀX¿èþV‹UÈ_åL3H\hgpj  ÐÕÇPÈ"è¢-ÏÎ%D|Û7‚¸šO ¶8ó8Iá±8Ь4w{#,BÑœõ_èåá1Õáñp`ÉýaEÈíœEÒ‚*˜&h&–Ù&pâþåØeb,ÈÓFŽ&P$&Àí„¡0HpÜ+YlmTà‹7`5¨-ÈE&hÖbí‚,8 * •ä<г¶ì#_äCÌ’ã6m5Ç0-Cû7<k2¤ˆº^Þ=öá>~`Çb˜½J.ÐaW>ÏÒNß‚±L^Ù¸ÓÆÊ%˜‚ „}påÅJ•:PÒ@ƒ6±/þÀÙBÍ’…ÓdÅñ»:1é@{£A”8ÖC¼#tÄë×C;+Â"£‘¢`fÞÕÌ\âþa>†ÏnÖèi&àÞíÝŒÞÌþ…Ϲ¼¥ÌÅŽ3è}@âí,>ˆ?ȈƒbÝJƒ<ââ5 |”˸ŒA{#jt »±7_öŒ$mÝs•å ¶ÙˆGn{݈æ½àPw.Ó‚\6$SîáŽæ îݰkeAMý Ý•Nn…Z�p0#hâÐ(‚¤!€‘Ž­<ÈïÅ\†œÃÃæ9´„Êñã:odÄ’k>Þq*Vá‰Ðk:RSß3#Òqf>Žàþlþ®¦\Œ­fÇ5QþU–áeÑÒáýÐÌTeÀ•X"àá\Àn蕎è�Ün¾]ÜõUˆ¼: íˆùü4ó[¶­€yÅ3á‰Ùˆ Eã´ÊÈÄðÝ‹.é ÝØÙÜØÓ.iæãÒ^ÞjÍÌ—kàU ʹŒÖÞ[-…`0­ÞNp†gø‡°0.…XðƒoUJb5^{^m M/OµîܤEt€¢óÍŠ0ÊR²k<áŠ}ñn¿Íj)ÎjµžK>Vq¬¬æ‰FY>b^o•Üõ Œ&ø»9FÎU¾¨Séœ\#(P"`YÀ•�¿þÖ_5%Èè4AmÑïdQð]I4ð2´3½å–Á|²% %QVm&¿Î¦Tóí‚b(âMÏÅ)roåM TI,X•¸È!! ÊYk ­ëYh0"¹dÊFŸPê}X)tÄ­b+ï<ƒÎ‰ÓÝ7|ÁÁ°ÆãÎÀ§ÀAó "±XUb¥,uú Zôèoâ̬‚žuV,à%ÊÅÝNEV h,/¸í Y"/p¥XУÂXZìãݾXuVÇN{¶á¾ÈcUÑ'·ôгÃD æˆ}„J/ÿtÃ�äðNâS·qÂÀÕpšØà%í@þÞê´FñÁÀ‘HÀêð ¼°ˆ¤­0Œ×þÛ7ŒôH ‰tSñÒZä]âMÍeÅ£4D|‹‰»UÏ/μD äþ>5ÖHÜ 9j˜%‰Pï6SÝЕvàßEq­X@£¹Ž”xaß !ÁÕ‰å4o÷ËØyR!÷äÖŽþÖ’VH ÑÎe ¢¦8A$ÚœZ ö—|ü‹VÏ¢�^qͤ-½› ˜ûˆw÷$\æeC ¦ÌzXš%þؑҾµÈyxú¿èõÅs°OjTë6ÌYŒ­bquðߨÆçœ›®ÔL¥—zGñ_%qè%y0W· š¸?ùŽô[íLŸgíþºŠ“+Î`®š£A¹'õ¬ wŸ'¶ðw} 0av•ŽäÌÌÎíP‰/MÓtOïMÓ ÎßZlk¢Þ­?-ÅM¿) öwR‘wáÕç´W}lô‡›fÒªÑ_ÕÖ ’{Œ~‰B˜Â}ñGú{B|q•Ì6­ÆïÛë”âíýÍùÇ÷ì^o„yû£;×ÏzÉôPΈFÁaG’„IH0T¨„%þìdñ" 2n´G£ÆˆD,I’$C >Læe’%K†!QSe„wî<E`Œ3@-Z´È?b€P:ãÇP¥‚xÇÏZ&5þJ”hQ¢3‚Ž- ”iÕ« †) ’ž¸q)ˆ¤Ys%McDªw`AƒS.LR#Æ‹-.V ò#È™J^6l³íäºvS*ä`¹0çœ9õ[¶tŒ"ª‹€øòåGÓ§¡FÕzõv^­U¿z ë;ìi´±ýÎ0ȃM1n?bܸ2ÝÍI8ä.ƒøŒÀ‚²}9fÛ¶ˆ;Nl>qÇÈ4q®…)qfä›;¦O9´Á¡dc›öZ)¬55`S´ä™Nxå…ÕO»‘X¨ùg”YÅÇVD‘w\½7™JX Bnm·VwÉQLmMä‡émx^soXŸdþp”Ñdw}æ][­§ Pc5œX_E(`j±EõÃ<u¦`‰FþF!SeEˆ]v *§ÄŒ4:Ýd+i•„UO ¤SJ™åÈ¢M2ÁˆQ‰y^4†Q1À\Í•ùP}ÞÍDeTÇp§m¹×³èa7¦ÐUY%–dXšVÅ!ÄTtçp±hæ@9 V$TQE3T±„Lp‘ÄUPMÔÔ–­a41T1 S01{,Ȭ-…€`ÑD³L�Òß^«,J4±Ä`ÂU§yÐá#†ÞɹNÔeµåXE×ilVáàŠÃ²¨Äþeò©Dˆú†º0ÃÙýt©`¢:qH5Ùk ,1”n[Áraî,Á…U€èb\@Ažd Q…¶1Ëm Z�rEI|Ë J�bóÎO�ÆÆ.±GJ<µUèœ>Ôr˜Ed£|®&¼§[zº(¨þþK©Õ+JF/NiÚpv¡f…vÆaæÄíAðÁW±O„áEºdpñ±Q1C.5á§D ÑÄFOx¡H�1PP9Md» ƒL.4É= ëEâ€xáÆ>Nx‘àB_ÅO+öÀ>$ˆ!µ[:jtw½jÄï¾[Q(Õv—™Ô{tdÞ˜þubW)*nÕo‡Óuß üÁ¢±çR[°_½£ ½koè•Ô}8+’Ñ ÚÓE Hò]ÙÓõ}ÂÆsú?–¸f¤´$/&uù\~w¶»dJmÖ{à‰Örµó¡Š.Y;NÚc6uÑ("¡ y$q÷/Ý@E'( lüâ@ÈwàQ© kë)DÀ-Äj¿#sX’¼a‚�“Òq$1¦J"0QÉMf>=)áTLÄH,x�:ííÂÖxÆ?6¡½p¬cÖøG#"°?lD}‰He�v¶E,û ¤üÂÃ$ˆáKÙÛžªð¦µQJ !”ÿxʼnþ¤&=RÂäèò6*ò"S ê.³‰ÍÂŒhÄ7´w?äcÀYÝ$€@œ@ ˆÃ)PÁŠ|$F"—© ^àÖ ®é°S CÜÂÄ»9@!Ûg@ÓúI]t[$zà"™L!dUø˜ç¦†k2Ë"Kð ’ð¸pËsÓšØ2Tyä#Ь›`td¤ãÿˆ„cÜöÌq(eù –üùK€ùš Jö¨LCݤG†âà;Ï—¿‰&adÀÂKÈ…5[š¦Elq fçTLD¡9Æ,悸Çú NÅHQYËÉÚV¡ªøË3Ø{f• †c²‰þ-B²šY†R-1¥òcÌÝ&Ã#$QhŒÏ|æ’žI,iÍÉ“S™HQdd„„ +jÈ÷ /lûA6ä�µn<ÀØ2’³->aujwT׿þ5ÃP>$ñ‡œà"´l×GîF™¼ä,b?¦—4ΩˆªŒòÆ÷–¹P`¯,aõô¶+µ½Ç2œáX�± Æ4J=qäC'#ÂHêñ0NMèdOö%2§9Yíœ\+Ñçd„1bB­tQÕŠ\„â@-¬aiüƒ Ø¡ðÖ=‡7„æ_÷$“ÃD=Ðamví ÝJ6¿þ€µ2‚祘FVd)•àÒ!ÄÌa¤«žx¢v<õõoªðë\ÁqLÖ/cþ`×m.&Y°2yÒ¦ ú÷-vqu?|Ýç4Wµ?LOu÷[I ¯6Æ\-»óÄDÑ'´2¾âhsÌÒ#«µ¾7¾¯ŽuÌR »FT.qt`! ÅØcò#XƒùƉ %C"æý:Ówеaçte‰ÒĦ ]þÀüÔçz¤FzÓ)ð‘˜ö-“í ³¬æÕ2GÎÖ…3ƒÝë.4¾õ™sÿ|]>—‡ÌÙ•QY*’?œȇ>ôIF2èÆM’ÑQ5§w¼äøzȉ…þñ¡"ç\æÑö—ÓUžrkC¼×½º:¹¤ªPGbZB»Í¤õsßmÔîv˜wÖŠr½_MZ̪Í4’§íç|Nd"‰63ªIRª>F„ݦ=É )lfç@çÜi&Ÿ e}XDWŒjLè;#^Ö€}u9ìcìšz.9OoUtÀ5k¤Ùº[·²S­n:úEJ äáóñ4;óÙQNL$æáŠJ �‘VU¨%m(ûºÉL›ôu=4Q‚ÿ’‘½¹~›×æWƒI&÷æù$ÿÐGܯË3­ô!‘Adˆ‘ÑÝH½êAD€.T¿Ú}i~V䢙ˆŸ(€‘VÈÏŠåaþm mß^çè¡x&0¥ÜÝÉHðg<Cû­·D”S‰AP¢.ë^w% à€ûÅsèf–©+Q‰´bìV:[íæŽÄâëXF?@V肬øˆ4·m§˜}惹XgN2Û£w1›; Ý{?wп÷Õ§>ŠúÈÇP—¾nˆ\£˜@ †JønÚ!Qº(^ ‰H¡‚ÄDö¾sçüáX(8‘X¨#Ö¸Å;Ä“G{Öž¾{”…žºä˜9Ó{”›[hÈáíª­–Ž”¬½Å|IÄ8P‚ö‰ÁRe ”€3¨ƒ;”ÀHHB%þ4ÞcDÛÇm/pÃ/TB”ßLÂYí•j>ÐÒ àC�ÜÃ,X;üƒ%¸î¨áŽ-ÐÑîåß}ÜÕ àa^öàB š•U£yß¶aʼn„$°Ã:„‘Š  <� Ð B€ÂˆA>tB+h¡‚Ä4<Ã3Ì–P@>@�%œÀ°i†™%+èƒ>àC!¤’H¤Y£ýžþdÚœÝß¡ÙÈ%—œ\Ý’SM¡Ä)[¢­Ú›ÖšA†)ò_ŒýN¼Q�-”C!¼� ”�ó“<ÀŒ<€($ô€>”Û 1àDI!ÜAD€D€6<Ã1ìÀþd„hQ�&°‘’Åà1›ñ…ž¼5¢þe!ŒeD\€ d àDóZâ1_ö)4¦_ÒEc**E„ž0Ö ÁùÎHD•ö •ô±#ó‘@°Ã2(Ãx�SQXš)ˆ¨Ë3¼Â,ôƒ%”Vå­Zã ‚l„ýÄÙ  Ñ¡šoiÝ&˜Z˜þd›‘œàD&ªããeŸ¹µÚ’¡ ‰£Éۣͱ̈́»©›:*Á5<B €‚ˆñeˆ[[T×D€H@HÄÂ4L8<„Õž|œö5Û‡È;ò;" ïÑá©Ð[‡ ­ŸŽ5W#v¢4]ÜH„Áºþ¤Š¼Ÿqt] ñ¥"IF[ÇÍW¶äÒÝ¢rˆ ›ª•Û6Ê ÅÓDÞFXÃ:\Ã?èA#�BôÀEP˜ Ú© IôžHˆ-F_©æ±®åðE†œœÿ)Æ¡µ›ö9€-ö„ U²e5ò%Õà}å$J‘d–![:¦#©¨æ:ŽÄjžãsÜœh>ã›E€$À � ø6pC%ôÁt‘¤ŠÄ[ÇQ!;2„¬gr¤£ÆI'$Ò èI ¤mH#âfbjàK”Šî faFbÍÛ ¢T» ç3*º)§–=ÀR¥æJB§ÖÉÛ¸õVï½ZbÈ–3üƒ¸\éX¼9æÓþ)[éÀq‡1]»1_y’\Rba‚½4Ò'ŽIcþf~ªã^\gÙÜ«õ݌֦òùV‚Š%?nà{¬æª[Þ˜(î]ÒéH´¥B'àÃÜÂ>(Üõ% ZúœiÆÓ ñ'�A‰6çPÝ%Æ%Ý“r£JŽfú•Öï=œÂ}DÇ©£M´›:‰ñ(ÂÕª¸ÜqDïe\á%fá&¡5Ž}Þ§öéŽP5écgGX‹éÃûÀE«¥à8*¡Úˆ-)™rÀQŽh¾!?2ÕFFr†å°Užº@‡êä`"Lž*»íh·©KBZ¨…%Æûèƒy@Y©•Ö‘¦$Dý]þ‚ä±™[êØ«V\D� d÷yÞ$MŠ&æ‘Úð Œé…¬'¹’€즊:a4~è»)åaPd[ÒŒ„Þ‡ú£'*Ûq„‡|h V'›þ\”å€&úNè©$Ô¢àC'8ÁN›�–&t~Itº+¦RR%²0(ƒ9lC ôÌ ‚LÂ*HF’Š¢‚+€¨®'©žk-ªæ£ö«Ž„)ªr ¼ui—¦—¹œ²I\ÅbÞ6î^iµfM**|äÏ)úØ=èƒ$,\“‰ÜªýlyŠýhD%Ф)PÅŤ)L–&Qm¢IŒ:0Ã2ØS!(Á TÂPBÉVhlFþêþ”(¹žèÒ‘JnîíÐj„¾áJ.'0ªÄz¥_ÚÈ;V¹©š#šº‚d¼y%E¾HLêÈý‚4|l Et�cªi,`C5Ü ‘Ð H kbáªQ,^6fª…d*ð�ð€d€H�èƒænGj†Õ)N˜ëÅéâæ©£*‡è©e˜~\'òcI¨iºÖ”fð]ï5+›+¡`«"ei:¯I8ëŠôl$X3äè ž€RÂ3¬Ã+üÃ"�B%ÜC>H‚©|Ÿh¶šäƒPMBbL-’À>Nï̱ê�-ƒ1�ÀÁ-!Rá&Ô©çR©#-Vpزc�vo.þJßB§­ºä­Rá&B.Fóáìmºäƒr¯c–&YIÀüÞ}ÙcʼnÜ<À ÔµÆÂ>àƒÖºh Î>€,VÂ>Æìn¢kŠÁ>ÄÁ¨ÑÁ>®ÃhCø@#AJÓ‰2hß%Þägnöº>À>ú¤ªyaþ¤ŸêÎ×é·1š²c6FèL<©3â±¥(ç-“-âle#4§úQÔϽQÄ\�,bÔI¨ë%j„èÃ$ÜOÞ¾!ñž¡4¹›àC8\i&ˆ‚ ‘À@ä@¸@B€AÜí­%‡‹$nYFÄ?ï^¥¥«±+š"• 0©Øea²cþ¢&åï¡­›¤f?Ö„1±,°,˜iž*%XªÇj…ì ôªE#ÜCü$Ù/ÜÁ>dÀ'œ€6»*2h!äƒnîƒöU©¢!© a[Ã9$Ã:ø�è�,[O‰Nó+ƒBÇ2 Ts[ø\ÑæÄ¦°W¦1t‰\Æ ³‘"¥Šúd¹²›ÖÕâÏ8JÞÜ{ª'K3¨Ns5ëÀ~ºq:.—cžÛ>€¥¢_Xž Âùþ°"Æ »KÅa,H¨Â:<C†Z‚P ‚TBŒ(¹¾áÝêÀ:ØA Ø<ƒóu�D¨Á™&Äß©‹#‚Šèÿšã~ þÜ|i£nôr)4¥ð°·n›Uð2DA ,6�A¸®4”+šaû¤#5˜C9´Á—X/‚4tƒ*ôÁ=H�8ºèR@tDÀ HeëåCТ¹.6p™«1å� ´Àt� œ€*Ì�Ó=Em@ $XƒA$A °…ÈrŸþ u˜šXZ^JæÄÆñ ÿæ\¢4¹êu/LÒiMîìk‡4OGA“AaÓ†a‹kËš«2ßbÿf^~37<C:€Àâ>! ÜÂ3¤­ô!p(%h­÷Qš­C9HAŽ.̲4‰²4Ëþ@2¸Ã2L€„ T�!þ¼�ü8ü !¨‚-æÃ <->@œ6æ‡&œtfܺUp»á©zç¨Ëž+ƒÊ::›‹îp%z‹«¸†k¸Nü�z³t^ sÞ2Õ¬:€Ôéf1e™9‚‰äÝà B8Lƒ6t‚t),LÂ-d�Œ�'à5{£&¬ôq6Ђ7ð(`± ìFmC3¤Ã4ðƒ¨H@9@`‚x‚úL$l‘¶zèáò¨6î£îpn6R"¨‚3ƒ’ñ™¦Ä]~å«!J5»9¨ ùUÌm9bSÊY_7šÚ*¡ÉgºÑ4bäa†vƒ’ §Ž9� Ô%o®w-ö˜Šºð|€þ EGUXƒ38C9üC"Ð�üÂ4Xƒ4\@!ÄO(@†C%`ò$àŒ¼Z.”¾¯­î^?§æ0;ó^Ý}Ù’1á�‘ × $…R\ø‘ƒ÷T;¨Q…1m`nún¶­é xÀtðu#:Š0ƒ’hXCI‘×F�5Åð €À  Á”Q:ƒ2tƒê¥Âô@%H‚LM‚¿磡"Ké::*L ¯ÿãÅõ§sjðìž–XGÁ¯ãF©×ÆS„5B—è`Dß.{v¢D{®åÅÁ&)h k³FçP=<TÀ{‰ðÒƒER A¨@x¬:,ƒ:0€àþB1PC.TÂ8ÄÉ á¦µ–Ì™¦rÞ(DSìnFtñÂęДaHh Ïÿü¤€umHT„5¨J3¸€‰^JA'6lÆ-“ímÒ¬Ž�í¨U›-?©óöTpÍ£xÅ^*ßÂ'ìB9ðC:°C†þC"`ZÄ �kˆY`NH‡ðòÐõ:Ú⦳äÀY3#°WÏ“Ð{©yX6t3p! d?Ë‚5ƒ—ëŵEY2 ²Z˜bþJžg &%tÞà v%ȆV;„�PÄGÁBH <@ Âä@¼òöj‘0r›L¤@zì#ÕÒ= 1fÔxþÑÁJ”8óÑAIQŠ Y2Œ˜‘._– yPM›71*¡†DQ€FÁ1”(Ð3Š€øñCéÒ¥@ž‚C×,I.¤$I‡T Q¤âà0v,$Î’príGþ(R‰iÕŠQ›w$H· •´¬´Šƒ+3–‚˜BñÆ1 Gžã1d1fDIB"Ì[ ¨–=c¯Ð= ãP€ W’Âqãl’Å=9ÿl¤Ù#\”r;ž¼2îG—%a&÷ìðfs›ÃIp=:=óO£‹ùñ%ñ£N—&qæì£#.†Jýãû¯R9˜Õ¡÷Þ¼nûGN¢§þV­üïÚ+Œ«+0½”D q¤8‚=ÄónºË"«00,b0$£#1( ¦”6:Ydg(€+·aš™†$`Fg&p§ •(éáþÀ‡%öÈí¢=n²·¹„Ô)£”èR °ŠÛÍ9ç~ c(¡¨;* ê¾ ,)¥cLÂ¥Žj¡Zh!®<BB#ôj¬»à‰3µJª¯.'íã`+?É# 0ÀàÏPûZâ’c˜‘&ô =QŠšŽ2È&»B@È$Ž($¨D‡(éK NPI ¹âúãgÒ™àK(ã}B1å{ò9a 2iÅò"tþ#ò6ÞxΤ+É—²9Hø)Kê; ²¤b(±ì£n)¼ s„°a1ìŒн±¢Ã‹?—0ÏNˆn¨!€à`*È8P­ÒºK‡0¸ÉÆ›°$”Z†d?µ²ÎÛÈ.[¬B:À=$!$ŸV6TaÎÖR”àŽ 0*Q2¡Dd^¹&dzKZiAJ1HŒn+²ÙÕÍ!)­$ŸÞµ3ˬ¶ìËxÉü12¬ùÄ’÷‹q*Á©"”�磾{í"AAŸ q*,¯ºKÐBîìŒ £uâ‰çŸà°Ó'm3­p†\þ‰$Ÿõrˆ¥BÄQù®B¥àO‚䜬ËRÒùwxX'gºù'‘lRŒ+œ•Hš8¹ŠÔ(i ˆÄm8§—¦Ò0’Ø2kÉ:޼B’7ÌxÃt÷*ã8Ì!ô™…!N ´.?Ài¢Q&t5Dw½§†k³³ZRé£Î”(¡„ó.€”Àús%çÅ æ8F2¬1ÜbF×ð€!l%è@åû�H- I† .°Š ,„8âŠ@ëûè„Kþ ‘À$.ÄQ‘NZe¬Þø¥†rɈÒ0RæÔD =ÙÇh©¬‹2_XŒá5=¬i13èþDâðƒ|Àa(ÊB(³€q,Ñ(G9‘ˆ(HBC®pbâ'Ÿw€RÑ@2 þ<.K ˆÂ7Bp„1X`³¸€ Ä1~bû(Lp …8$¡ýTZ\B‚ºÄ¡?:]Ô8€­,xð”*9$ñ]|-ŒÌ°•~q‹Ó4RDli€’±…–—½K9fŠ”fôfŽg0£Iø>^),``$#5P„€À3B�f Ž"%Ž÷*Ftˆ4bÐ_GéV·†’ƒ"À"Dtr�)†ÂJ�(&•ùâI[\Bo@cÀDþ'Øñ uücåÛ ŸöÊ¿8kƒü©ÓžD²; $E9)"ÕÜi¡É(q[¢_z`^Ê2ŠyÆ3üñ! ã´ˆ€{ö¾ië2ý.†0ˆé¬g~N2In”¶‡æÜ0<áãJ#4¢x±•pWJ�UG¨'1ŒèŒE,dá ZR˜(!Ì0:º±Z8ã©û‡'8p–Ôg°*éKG4ê–?Ø/‰º× ÿâÅbëªG¼šbfº¼«Ñ´˜šýV¹T@ÔÀì°Æ?DЕ½M%DaJdr`ŽtðC¼ gD¨Y xUíɃÐ!lÃ͸&þöƒ{äê0(TSp"wÐW¦Ÿ9Ý%9õSB:¶ÑmhÀ A”Pˆ€ŒÜÍd k?(­äsþÑW€H/üH9{e3õ®^ ˜c g³v™qqs,°Á™ôÖ·UxÀ] ˆƒ #„EàÁyS73 1jÎÙC÷…4Q1( ÅnºŒ¸Ã9 D/ÀQ LÀ¢¨„ žq„­@%*“+í¤ÄA/�Ÿ’�­RsN˜ ë�¹Ö8.9 WþT–ÿèëPyIò€¶RYêxÖ—¿Ü,0»E™ÆtzLQ x~ â<W£²Äþ“$À 2`ª9ƒXâ‹'~B*Æ9?䀥C($ÑQxƒá(AÀðm`“¨ÄIÑÕ êÈî%ß>—ê  ã@> @‰6¿rõPw£3°°´5Ì~*Aí¥/¶E‰˜ÂªemµÉ`VÀ}„ö¥ '®lVÑ;à™A/œÁˆÅµar9Ų™Î0gˆŠ¶–oµÒƒRà€(x9\×8CéXF9t g$ƒÿ@ôBµ¦È+¨dÙîÊ4¨Ì� z€P }èc×ÜÕ½ò¥2®lé'é¶ÁêpŒý§Rг´³ÌmÍ|[ï|Ì‚ÁtþçÄ¥& XNŠ Ô]´†¸[Ñ'Îcr± kœãC˜ð ~8ãŸD ÈÑ�â=ð€ ÑPXéAbê6bäDFB©Œ?aÌ )hu.Œ€[áf>Bu%KKѳPûFÅ% }„9f&ÄfÈg (Š×*Q$Ð�áÜ–™ùÛÍõ&PÃÇ(‡»ÒôiB÷¸ >˜N%b造¸ÀÁˆÍî,÷ðƒà@|´»?*A¶¢¨s­>(¿&³J@@€„1ž „Ïša”û²i>×:¥oS<Wþ»fšZ[‰R”³–.¿øþÅŸA8Äß_¢˜ßµDIB-!xŒñøcŽ˜£…ò* ö¦¤7*!0a8`@Ä $A-0’g1Ä^˜<ø&¨Êo*Ž¢ŒªA¼aØaþÁ!ÞCå¦o ¤Š°CÕ–oñøo(²Åò"Sº¥ýàì1¦ãèüÏ?œp3\à   O¸âÇáž0ÍœhÀJ€ ðGéj‚Œaf!þ�öÁ£†:ò. öaôö°!mÂÙƒŠ˜B;Æ]²ë=RmŽ`™ØAVÁX Z€r Þƒ�&¨Â1C¦ þŽˆb*Ð ÿyü£åž‡Í0ëý˜P ÉÌP4¬ÁôÀþé(c=äg3ZQÈÌ 5IIÚzad¥ðA¡&\ap maØ6$$€ü!lï°žc'ϘÂ%;ÄN؃üˆŒ)&# j@V@2àŽÂ¾ÇÜCLÆT+»vkÊÑüXM å?’ ˆçªCršÍÙª(ä§�„'"-¤�ZÀŽ€þp`Î(Èà?&ÒPÀP&2étÂZ\Aÿ þ`¨¡5°5¬Á¬¡à¡(�náva¡ÆP`þ¼ñ9j*L’âl0«!dLÜi"ckã$¡Þ¼ã�d$ŽºÍÎ’:üÏOôÅN"2$ŸÎq¨—”°y¶%~ÒC :C"ybp`4/]äRÝî¤3 ðxÒR“¤*ö^¥àþá�0"�ü àz@�AN¡HA(€!XAjŽò9Š(ýfjz §[Þnz¾`ö¡Ž(;*ïè@1*¡$ABO,k ÝnëN Å/žd8OÊ¿\.khnÕí.¡å#J ¤ô dÁ$Á¶ÖƒñÆŒ$9#0ôˆ@NÒ9¡&\Ï&¸áv¡& J!òþÁ:ˆ«N@=k‚Ž!8mª ìA Æew01ÂÄ)ƒú€¶$;Œ©0PŽ6gºÆ;‰ªÃ¾¼ÓކC'ì¨@ôÈ87¦j&/3Ȳ­ ÒC‡XZO „nJ†à¿®s:�cÄ@ Wô#4i·jòFSˆÆÓbOê ÎXZÁŽ!lò´&�ÁffðZ¢ƒ—Øï½&*ß®ô¡ ˜èÀ‹\àÊÐ^àPóÀ$CÿÌ2 ©åi~hYœÎ/¬Ê'”G!—Pþ'è¢Eä6$!*á"è@ "#_àüôMž)’ :þ q ”Úíõ�“ ›BAAzÁzá0��¡Ba>kÂßadáZ’’ÙÒï;o+ÜÐA´% `þ¡vÀJ‹ÀþáfàlžhŠÐM;ã#€tª„èCG’?P•3UoZÓ9Záôa.B@Ⓤ³ ÔanÀ'$e3”ä;#–á¹Â3lÕ†ï!ìaðA @;štéÜ [•äš0 R,AŒ¡àád€Ù^å²aq.a``j Ú�2ÊŠBÄ ÿÚj>ЦS™®·PÌOŸ-þ°ó þ P §„˜¡àúÁðcøô·¤\v ò@€ Öƒ#ýHÒÕ9œ¡faqà”!PÁ�Hµ3íÁ+éÁ&þ€î¡"�¡ZAÇ“·ŠÓOcH2-ñg™’¡0ÀîÀ' L€T�¾`›@ h > ~`á¢@ à”,µ¢%¸•ToÂ鬪å4Ö{B;×MÑTááVÕ¦$€ÑB×K‹€=TÀ{¤àéÀPIJLpLÎaÀ–Tm¡ò!PÌ!T?—XAt–WÒ¿°" $ OEH`J@ \ 8ùè)' @þ @`(a¤áv!sÅï¶Tx<·9@×’äoÌÐÒNdâzK ²ákáCÙÒKÉéÖ ghi¢[›ú€`ÂÓÝš4`QÈA�½°Áþ¡j‚TÝ­Jö(c´Â,!2h†' ‹DE(APðV#¨á´zᦠÎn ÒäR“N#©Åö(hU/"5J€í� `VAÄ…–=Ž. °¡h¡áìD #',–İð¦ëÜ¡,a¸2( à�AHMð³QÍ!‘ŽeÎi#(—\aè¡ò¡‚6ÿ˜ð¦þþÁ&Ýh f` X`˜°;# xªF* ‘G†ç(85b”qâ霰 IÀÂçÉU'zGJ6¢Y,ÖŠ÷…)÷ð¤–a�À&J‹§êábybñô–.±Ý( d2aP ö¡”òqÏÂ�k€Ž@2£µrÌ:—•q¢·dâ½WIª…õ·ªF” ;t%–Cª|i”EVy7˜ƒJa�™Ù<^AKÁ!X¡< Axàb{Bcù-¶SH¦ä„¡:a¨2  2€8Ö™’€ ®éxW[‰–žÙØYF¸UidÚZnCDKw†þYTE€§wjˆX¦D9—i¢˜aÉ&Zèà0¡fµÝð—‰ùàÈ,K€ßa–A|`Ø!dðx $H1¥_9hIÒŽr:j~äxrvžãZ®Mª–C´wvº®Aâ8V¢8Šå–´v•Å¡(�¤Qâ€ì˜Ö8‚3bÑ ÌKo«%|·h¯áø& Á�J ·í‹3ôºú�j㮟ø–¶V¶›n-¡ˆÐ‰#ô‚tæ+–kZàÂHðA=+¡W.b(÷^›xž#j<£MR‚—Î2/`Îa(Àõ>é~Î’µí$µÑR r#æsþÄÁ¶IYkÕÛ×)gñ·•Ó)\ï¢~æÊT DEæ‚B¶¹îA(@ŽahLšDòaXnÙŠOJKx—¸•ºobTÛY­»ó.‡0ùV fS Lí2𰽟ÅÝ{*—sB ¡“TCüãmðK£ñ¤eXÅ#$A ØT^aUA²9¡& $ÆD|éž&¯0¿fÂÂ[˜;Ѳ�5‰.S AðRÒÇ aêVÅÑülñ{ xâ@‚a6a|*J@ŒÂHaæŠ-œ$�¼áúA,! ¡ðàØH:@ "€ú$á7`þ)r⢑ÎO<¤ÅY™g%²ˆvQŸ\,.Ö!š¡V5ÍQ½Ädn§ñt²ÁÖ¡úÁ–×þÎ@¨äG°èc®:ªî�$ Öa™ÐaHaX@v;å+8‹² ™?rÖZîadrQ£¦H„³?†0N€”ΰ°áÐaq¡™S}Þo×B%û‡4"$`B¡È4ô¨L®,èd>ôÂ<|€€rw 4œ Æ"vààáPèã.×Â>Î$W/j4îLï(!ïv–Ñ´Ü-�a<–éN 6^àþè}çkÂJaz v)@–Æh~Ähà]•àa}ðLNü„×½ Ðë¾ÁÜ2@ ` D ¢Œ’’àâ@"™Ì»u±$¬¼ß!*�taø0öFê~ µZÔ3úÀlµbyžÞ[a Ž�¢† ÿ@ÜxT:&@–Šù´+@x"_N¥3^Â%,ÞèÔÆ! ü�’ Î�ceÌnÜ ß$Üí®>AÚAš¡˜×½×ÉP¡2_-ÑÔ»3¡x€1Eáüy#|#Î:�ÉDo¼‚P nT¸«x¢êþDŒR,\‚ÂbPXñs:«aœad¬<þ6<w²ÕXÑœÛ"ß=@ <ˆ0aA R0ØP¡D‰õẊ à1kê.�zrÑ$ERPB‚D’$€àø1ãÇ 4p�ƒ³D:(é ¡cJ«p¡«G¥3'1&Ê(Ž8'ppÀQbÈÍ”$Âp ãàáDƒ/�uz¡Š ¡Ö}ë`Çù¶Âw€P¥I­Âý{‘&I¬ð&@¬*„õ­?rråŽÌPäB%JÂ$sT¦Ì˜3ir¨4H¾A,Iò�iŸQjÎÖ™ ‚6þo þá¡Çʼn8*õ°ÊC˜0bˆ ÃY,`¿ë²ŽXá\Ã(h%ŽÂB…òU"™ý­á’èç.L.ßÇu­¢PPÆô'UB€ À45•P ¨qÄ1Î(ƒG?àPKc€Â@#3Ôp„6„É ‘ÓŽ4¡$a ‚Å™a¥#`†V‰^“SL7§T"ÉHU£C )QØ—voÉ‚Î/öˆ!9&Ý{?^‰ÐIžá1QÄ &9ìG>qдŽ5Ïü£—QÁD,bÄ è(ƒÌG€°Í2ìôóÏFÙ€C$ˆÁYþXU )D‚1ddC5ê3H2È£Œu­’X¢F$QCHžÔ"ª™evª¤"ôL›ÿ”C$àã¤ýq9€_|!à˜½â@‹1Ì$cG‘Á5,Rà 1Ä cÆÐB6ðlóÏ?+a 5´ñ qè“$LÞ«¯ÙJ®®DZªx¨*A0ê0Ó ´ô²Í4>ÄÈ'™´‡e®&yåa”6J„¥ÄÄøþ/{ë½ç# qx@Á7ùhó‹¹¢‡åXl9C3�ÀH 7v˜"ˆ?ŒÈE>…à@‡ ÒJq´1Ç0à Ӛ`B¯„®ÌPˆ6¤°2þ‰Dj>RR"Š*€L2½Ú¡j±Ï8óÏ›ñDrÇ ( àÇ'ß{êƒJgFf\q£NŒ±‚·è�Å—ñ ’A鬓Î?pÍu{c¡”„˽ B_1àhF8‹ ÂAHù C¢ a4F-­ É´£Œ ?ðàŒ5縣‡“¶×ñ$J‘½K(ñš؉·¨µ(�’A¯èà\‹žêHWÊj‘ˆ_øÄ‰KìbúŒ&Îh‹…ã[ñàwL¹ äó‰˜ñMyB(y iÍ.fž˜Æ$“¨¥À1–± !x@vÓ¢àÑŒÆnL ÿH„ ¢Àþ2„`˜”‘ŠÔ8BäB»àÅ+|ú0Oa‰{Ÿá&F8 bX”~ÄômÏE„ØüŒ$?TQ Aüá~h¸æp¦‰@dÔýV8à 3&i÷2–ÄóŒÍ=ùŸ�g'  ‚®s4ë�)@Àe¬ãÖAñ LKZ^Ø£g‚4mPN …!„åû؇‘ðÑ £Ë F7ÒÁޏCf•óg>É’‰@á ü 1¬U$¢ã'DF=€+>LIð�æ0ŠœYÔOxbÊ@щϫ¡Ä¾¸^¶2paчîQ6â¡ E Pì,x@þÐi〃*j ƒŒAQÁ L0ÀÙm΂1Ö ò8(a«�-¶/ ŒäÞøF-ÐÁô€œ(ÁÆþ‚2’H,”ÍÉžü\4K” D%è@ ?ìÒ¡Q¼âú8“K¬d%\ùIJLêC1̲”`HL™’ Š’{Ï»ØI ·Ò^q—Zƒ&Q &ŠgžÞcY¯d‡Ô4þ  3 ÔÑŽYB1XÁ `€´vfu€›K§°¢@ e´£‘ �;˜Á küãÑaH $� ôÁxˆ£Ü³”)Œoñ;™˜¸›Þƒ` D%†P‚pX´]YÔ_›SEþŠá' rirF ”RÂô'-u©MnbJ fÏ9ë»âûzxRZr…QèpF3È%$hžƒ€Þ–4×UÚÑá§E˜Ý À±ƒø �¢ÒyÆ=ªs8(…3²áŒÞäáA€€.ðŒ¿j/b.º×ü׸Êyp„ÏùÐwDŒ@â¨Ä.ð�Pä§&E-Jp)Z+ªE4‘ rXrE‘� ŸYIK­R“Ïžt–ΦGw)¸898ÉlJT!Lø @! |²[¢·¹9¦„ š²;B((‘Ù­‚1 &˜\4þ±WJB\p„#ÄáàLlI€ËÄÝþC.Ê,Æ=ï!qxŒs_[ꨅÆÏ0«(D(Hq køÃ (cu ÌE9�͸|ÀOf©ƒˤ&þ5 È0a [eY2ÍKÙÌœ0q¥ÞeJP$2 ç²+ Hpüb¹„jUr/ñx¨Ø7àáœcs¢*aƒiƒÐ;/èUiõªK JIÓ+‚À‡(äÑ òp§Î©aGò]dkooªB¶x’HT<#Ũ…)îÐ ÜÁ hÄ À`J ¶¤¨©^“(ÐÙ(.iÉ¢¯ân ¸¬4@h)0éÀ.%äˆø}NœÝix¿›þ¤$Â1tÔpe¤RqYcÀkÉà+hƒÑ¼Ð;eÜÀÓ&J0hu«$S�‡e£¤Špr$ú‹Þ¡÷¸Ç°¡WLf>ûÙØŸÅÒÇ=Œ é$S® ÚöŒcüƒ4C ~°‚x‚Â¥$º4{è伤WâqË\BïþJÅ%dBUê Z¾¸bln3-up•–½&qø»“ •¡ H„\ç=oÚh%B!�ƒ3š`ÝøÄ?¡A˜€ƒ ^ kÙ•Ç]J”-¥HÚ|HžãàA%BÁ Óâ¾2ý(gúÐ!õ2×í‹N¥àw’ìâþB8‚†ËáÐ`Y3Ü)Œ—‚GV×cÂcш¦K¤P€ô‘ ,‹®È®Ø^õpËúÑ/Ð…0„ÿ Ar€¨=û—ÇØÅÄႬZ2 C `à ¯° ݲ ^§y×¢y1ƒr\’~@±>7T1~p Å  Ò ³ðÊÐ�m�úFìaPtCbJBä©ÅXdC Ô"tm@6Ð ¹:söYêrƒ-•`^ ÍW~^Ïg}2á5ƒp3á÷ ãpZÁ 8q|Z§iä„3 × Ô 8à3Á~à_ Gb°Úà ¿€GÓþ?@ °6k,ædBh€ÒâNu¦(â?ÍA®@ ìÀËð&ÿÐ ¢Ðä°€¥S=Ä>ØP 5En¶¿¤`L­T{¦ù°ø@ ­@&1a@@£è4ñ|Q@b=,\G~@„w00á}ì"ÖY-Ñ_›×н"ÛPœðÝPp0öp<6…ôçNF£ Ì0ˆÑ„ ø`šÇy³Öy"†¸%3@ÈnyHD#iU #À³�9lã²�l‰¨õCŽY¥>‡¦(ÌñÙÓ(«ÕX¶DKJ0€ «A3ÒWñ&vA8!aÈ+Uhr'þ, ö ’0/0÷° •@ ù°,£(Ð,íÔƒ½B+€5úà•P<H“<0, “-`1pùД{$ ` ‰” HbÎ×nâÖF¨€ ‹@ ÝÂ: %p/` ¨Â>E–‚(Y@TJÐaESmãVR0•ú &R�,_ & É¢ñ%é_#µóg“Ö$3i,”°@l(™@6@ð ö6ÙN$™E€VØÀQP‘4é2«ÐQà.0k*06@ “€x@2 ¢@ WÁ—±é_$æ…;A5?W =þPðø~€ÐU”fÈÉ+ÕB$1”2“eYÓI`q€VÿÀ P"°F5H wI‡FÁ Š"`±™i¼âƒw43I%€)P ™€ ø°Œ31gÕgr5)˜ÖDš > ð2á8k³ rC0P’'Ð “0 Ö° 0±X#‰RY±‰¡‰")`í3tÉf™ ÷À• ’ÀCç3YˆKâF‰<±>àƒ${ðD: h6Á~ìF`Ã7Ð`}_`’3�îôâ)`´búˆhèyT HAnàÄ€ ݰ §à‘ìb®8®ÈŒ\¢ŠH;b5þ&pr_*R ´� €  ‰R ÍP ‚à ‹ð `# ¿À„p±¹_ªUž|™rÌe‚0«"<2 }� ÂC•  LË=<¡(8±a`tšÑÿ³,uæR1|7à%XÝy@8 ,ç6ž¶$8ܳ¤ûÕ¤¹er1pšB ÿ  tz}àk4}0@0”-Cjht4œ‘+Î�AÏàA@Ðì Þ‰ ‚p1ൡÿ ˜Ë¡®µªÍyPVbø0Ð ¢€€ °¥]VDZÀd|jö"•! ñ??2}Í(¦€)  ãþ%âÉ &@‡©ëj«ÿñGH Å ÿ€ Ȱ0ÿàR}]úš,ѤF¡9È…4šr±©B@P–P« ?p�A0Cp�'0R?0ypVAR'Ø몮‡–­0ÃÐ Ó� •P Ëp ë° ð s^„ch0¥5¢(q—5Ù+(Ð+­9; ƒhµ¶.¢EÌæ•ÛäèI;}ð9Éð&þ�îÐ6‡}G:žg¨š¦\¤¦‰‚YëÊ.~°¢ð RÀ à Öp / P Ã7³¶¤М´ê®ˆa ÙÀ ‚þÈåÐ «@ûPå` RÀ]~C>Q„¨Fòà½26�@0 T P ­à˜c\‡"'EÑÑ*²G«^Ñ—‚Û+A ÏP®É0€„Ò-Š qªÈn—uiú¨±Ì³Þè´¶¤®q›a�rÓ°ÒH>¶ìàoR'·—±úUë�ÐQ±Ž‚½ Ñ çðýx'àß 5OT>%pD|Xl«,³ 0à Ô«¥©@]uF,Û5)Úa-²¤ˆ–[Hp½bN§hÝ"�yÎp(âÀ]q‚Y¾Å¥N^'±Iº·ÚŸ°ŒGŒ›@¾þ+.ö 'G R`|ù›*ˆÑ ~ úÀ𠪜÷� 1íIžødè#JF÷ñ”0Cà «0k¢0‘@ [ ·cÒ%*Q‰¢ô.g#{³7bÉ5&dð3P/á~ ßà CðËÖ‰C¾Bl· (¿™»]Ø÷� ì` È pðJ'˜P“�š))³a¹Šr8*,•À é`Ì �úpƒ°%:“p ܰ ¬CålI$#ä;¢ø Í•Ì` ¡ ]¢9K9,*áXw“™ÁËÑ—ËÚ+F@#€".ày)±•ûŒ©þ›u‹þy(Wk­e^# ~�t šzÀJ[¡~P„ Gi‡ÈœÌa˜Ý“ö0 …À‰ % ×°­Pšé ϰ î�2Œƒ'± Ñ  å� ®@IÀo ìa¦2›‚ø’01‚*äë¤_:R+µn¼l¨"Å §±8fM:ž^!E‚€Í÷€˜ptð�Œƒ žT%°úð”‹TšÉ~z‹/zUûÁ 3mš€�€Ð€+a Ï�ˆÿ �À t 7À /{C—Aí lÃÏ�G¼€W9ë~*†)‡m$Eµ_.ë2{þ™¤)¼*œ\¾/»\{û‹›bq Ì  0¬  · eÇ }¢ìÀ¾ÿ -�@±3k è´°kµlKðÇ”ª ™@ ÎL•� ;ð ¡PÑÓóDÃ$Ù!t°AvÀ�v�ƒZ×Ê—ã‰Ò(¡EèP-’±jLp[œ¨˜!˜#Öô—N´ã+Ñ>r¦Ð ¦ðP £ÝÔ�@¥ð  ðxµ�RÐG Ð¤æ¬ ÞÆ{[%¯R ¤`šºÀù CoaÍ€ C«±-0ЀGžÚ—-›(¯Éüq/ÂŒ¹OëÕ¬’%^’OZ¹4,WÇ(þôS×!ÁI…° jQ×esí)‘Õ×ÝœÛÝ%) ‘ ¼ „p ËP ;`Í®Û3Û¬=³ç‘§.°ÝI÷ÒK >>=¬{à. ·<Ü)—Ï)è€@AØkҲ݋¹RŒ85%M€Àl£ ð ÞÀ Ý‚ â…2¥2Ÿ>¢‚?ñ‰¬ÍäPr÷ä‘R®,«©äÑMŠ[ª¸Šù«Æ›NFˆ1€ûЭa@€‡”€äSýÕž½ÛS ð® �–P€Pù� “b¶®$ !€@ „Ps‘“0”*¦ J޹P­þé­LØ3zs8³ì¥¢Áž¬Êª¿:Øž•Ð'€Æ °@| Òp ®P «üJ3zÚDRPdJ O_ÉÆ?žnÍ•PO• û�Êû.ø %÷p ! ¤P ùà O¨#µÌÝû¿.Âð¯=è[bð?íUûÝ0’¢ µP ÓÐ-'°ë ­ÿ0¨Ž8ô³Ão° TA‡Â¡1ó3§"ôq’€ …`ùn9A}P ô¢ …PÌ)/ÅSÛ®‚ `>õu¾7Aí†*›ï݃ )˜ ¾)p>À@ m  ݹÚsWþ2)BÐ hfXãà`Q4>fû=6_Д ¾@ ÙP pÐ#[#á@8M'À/×p ™àJ:µµzÛœQÕ—?Ÿ`Þì—¦ä¦.`˜¬ñ ÉÀ Û±Q%�0BDàýÃϱø0ÿƒ�ò‘ ñà„b”8P¨äÏCˆ”L¤P‘0d‚M"µŽ»u þ‰±¸Ç" \ÈnÂ' 3gÏÒýƒ§GG‚a”ÌƧO>P�TÔèQ¤I•.eÚ´èÉ¢JpâäY•g¬XƒR$êÔi.Uïü[Äj©D%bÑ©˜i•R‹ð£ þ­"¡Ãï_Ndñ”T¤ôl;käÚ�âqP¡N +¦ðç¥:dì–•ëa”G‡!îhÒ ”„$NÔ¹ØëmܹáF*´çO×9)ênŠP=@º½7IWøÄ Û÷‡’g@]-ZTD„qØœ-óuôèý8mB„ Å8ÞÄ ›¤H¤@ÇÁƒ´£O‰Szå;þIä’=Ò £¬:H‚ƒ¬’¨Ê§Ù¤R‚8;Ü-;‰r JÄßz£o9uëÁ”{ðiÅg’¡æAžÚn»?ö¨ÅœŒqG“u¢ù矒�âH ÔÓ¡ öJK>Äþ£H‰ ²#‰‚Ä*ê0ÄæS¢)t …0è#!«ª,¼JM)HñM+ŠêL­¬Ž0ÙP„Ó«TÒq'rÀg•BÂY ‘ @¤À¤)ÈŽ6n@f¨Ar~˜á$9�£/PáKˆ>Á\l»ÅNí¯³VbÈ'vîŸ켳¢=öÔ•Ãè¬ð‰‚•sW¯î¡`ŸAÈa¤¨{�i–­Š®4i’Š&"!’¨Á†h˜!ŠÂýSôÀàà/ƒDU¾ÿX׊&ù£91&‘KÚ¦"HJDœ 1¢$¬6“ˆ5ø¶}­Í`m;Ø«| Ä9£Ü•3ŸA*ŸAþâ°6$È!\’7Ýt\N0 0ÖKÈ 0Ú›/¾Î,¢‡1ð‡19 J¸˜L˜Ä vÀ¥6©aõ|8N©¨ÂŠB4§|zêÜ(ĹI Aá˜lŒ¹Ã@J „œ ɇŽMqqQ·SO[^ï/¿j;|D!¤q2¡e˜\Zé¡ &iE¢0èЂIÉðï…·`¤äÔNj®9D‹Î¹ç¶p1γ3 ôЙuæ•d”Ë%”vʲŒÃ±¼BD¹újºÃe$L¯\–—to>w‹bÅU<Àu”y&Òx`…’UHš„A ‘¤® r ÅþFÓ?I»ÖÏ·¶ôÒ-<q}EÛWJSº± ð9@gIŒèZQH(, r³[冼¼-I‚Y£ÂÁ s£(  ð‚~ä‘à Á d#šxÀÖˆS’=h^ž£!ˆì—,°tQ˜›lló.ÍÙu\ÛÇ=øÑˆ8‹bøðZ'ô‹[äB¢"Vä&¼áÙÍxÆS¨,V”a°c<Θ€�±>P@¿ÀÃ; ‘@LƒêpÆ2°§9$.{,Éà4D¦`) äaÉf€ƒ$(ä]}\Q<×>|¼ÀYIÁ…1ŽaŠmƒCòħ¨x¦¹ìþ 0ÙÝ’¤·QÑ'u€�Ê¢pã(ì(îXA  üàÇ>âäÈùM1[HÍ(Ä*êsË!¸ yÈÓYlQQßvêçÂÐ=†þø#„€Á9zp�„Oo1“™Cš§�"ž€àF)¼A!ýCŠBÛ;EG“$f]iˆ«4L‡ÈÐF~|Š2ýøÈ†&e8 bpÑ@30!Ì–â.ˆÄp† >ܦ‹}Tℸƒ$P`•è¤V’Û‘ˆg¡ùЇ!:Å&S’Ø }"žýegº´/—¹J©ëB C™¾¹-2l¤RzE7‹b””QþÀ)bbª‚b‰˜N3‰B­É:ú3)•Ð$4ˆTèãP„ê4¢ZÉ\è9Ë(%õT)pV'\Ž|dÂ%ºŠK{¨B!‚Ì…'}`3WMŬ+>‰Q•H«¢Î�YͨFkóÍÆ«:mêD¤ Äô©Î‘B¬á5Åq‚Bd,´@†^PW­üjDjºŠ§&HˆDÉ|ð,M>Dá¬pt"} Ä$kÇD ~ÄHв¾,i³z-ª¸#ª 7§lØPÊP>3\ˆdCØÀˆ@¢"GõRî ˜T¥jEPq ~Tã}„>:Qˆxèá8¡þ"…°ö+vR¥LœM æ–›BìCƒ „-aŠ@¢“ Ä®P•žµ+-Ó›SPb*F§eH{öÅ“ ¶g" ÉRƒßgò¼>þqò‚¬®'é"R­ˆ4Ëú.)-MUÑEX4" ÀANà«!<sCÏéf1nY°F*Ñ»dƒ͘�8*±X<Å$„©V{X^¾=¹!œYÚ_¢ƒô̸Æ}Á‰du¢ß†àDÆÁ#Yü$È·½²ç5ó¹ñ{Úô^-IÕ]„™YCØÛ‡�Â…¸ƒ*¨±Œ` ´:8$¾:ùlm™r htƒwÐþ+<òu0ÃIdlDi˜–¾$äÆsAˆÓr˜ÌŽ ÛåÄÎs<sÕIyú²Sh¿®<0+:˜…“Tß�u!ÜÎéW³Üáar´ÛA O Zf,£ØÆ2ÖÁÍPPBÆq &(Ñé’E²ªzÎS 6ç©£Øð(¡ W°â‚ØÁ?ôPš¦,—}ËÎÇ£ Ôj[¿N¢à̺$¿¬yn@(Èp¼«[BB¼áéô éSîì±}»]SëX`qˆ”}œ¾Ù* ¹¨Å9˜1¤G” `Ђ¢ƒŠB¾óÅ ±uMÕå})Ë€I2†„ !à�ù@=þ�©Ì£ôt9R;Ìl0½sý¾¦iL.wø-§‰ÍDÇAwë}¼ô„ò5MÒ‰~zrĽLcÈA,õ"K¹Ã>ÆÎôé}¡×wP ° x@ ¨„H�^œB†-)gPw9/r™N xÀD"ñº¡á2óÆç”=ð Œëw¾‚p�¥eÊ8_S¨ ½t%»âЋŽ2·Ê\ʹ`Põþ 7®kzó⢕l ƒ8(¢€@P‚U8B@¨#ch‡6 ŒŠæÓ(9S¨\Ñ»¥ð޹‡o˜§ÙZÁ³øƒu¹1öˆ©Ú@¯DcB’/M þ6a;§âÙÁ“1Qj:›š$‰¦™=}Ó·'q¼÷àĺ¼1(›¢ fx†fà!p!¸ À€ ð†( ­‹"%ú:4<+µZZ¢¢€„AÀŽìηªˆ¼Që¶8 ã6Ns&CÒM)¥šÚÁó ›ùÃAœ¯óh™ £!ÅX~Û·V‹!{’Çã Qˆ. N„¨U؇ø†°„#À8À˜Ò­30C7ó/w¢&kZ¨Ø* B àf¹¡¤h¼!ë1/é9 ȇ3(žqÁ|Ї¹á¡E——C<…©7C<ú:.ÌYRQb̲öþ"•…¸‰Ó2€SFÑ»àƒËpù —/ „¶‰²=/Gú(¯ô±Å:ÜÐ?оÙJ<û£¨âÄÊÚ© ± ½F¤AСPÂÇ’Äѳ«»Jà¶ÓQ$¸À’RÁ¶ñ* 1�7W &aÙ#ŽÁ§xªè+¢ƒqÀ„jx\¨â! )“À²”´¦Ñ:wY‹?p:¨b ‡\˜B¸ÅbƒŠÃóŠT –RY—…€ÊN�ƒBä�¹ƒA"aÃGºÑyS“Þ˜•*úÙø¢‘„5¦)(…pÁÆó7ÔyaÑœ+;ȑ̗RøM8ƒU°Ñ8;rè�6c’þ ‘‚â°öZˆT(„?Àn`f8†x˜�~°!¹2‹!³ªJ¨©2°‚2QAø.tŠ0}…ßA$‹œ¿A”›…¹ rª «ÔÖÚ)W¦ÄਇAA»»îƒÉ¿Ü½uX‡tp~H‚(X6°„«ÑG¤ªŠÙØ6‚*•!…@ЇJ@hàЀMx@>ª²š©29s(Ña”âŒÄ;–I(„ºRÄ?‡;0D`›»eÄÍŽÔÄ­èßÄýÓ1ùˆ½¦šOk‹(:Ü @!°„¹Ys:7Û³Š˜i/üJ4¿˜ g0c@|`-Èþ p/�C ‰ SA‹è[îђ¯+wé;õÛ”U „xpyRN{¦Ñ¢?ÓÉMžØpå¨tü—õGƒÙú‚0ø­x: ¡7Mô‰~ƒ5>½s àSx…³ë˜ 庚2‰ð¯i*jêËÛ¾†BŸ=: Bè€�D“„0$Œœ»øçCħËM¥A+O݃ÃÀ®;=b¨ƒ4ÚàÃÒi3åÑ.ÖBàAÒKÓã €€ x†8²†hš•4&¦É2€\¤úY¨bM«ÕÑœ?èB‚$% ¨„J˜„IEÄJ}Fæ›Òpq¦47þ*‰‘dNI•bB iBÒ|,¤5«vr�Ù „,É£X¥âQ’%�Í " ×’’¯2ŒUÓ#Të>PÍF)06<Š{¨„}è$—|èƒJ°-K@ä@CÚT­x/6¬¦Òd¬Oûœ31ð1%hFc”8K{ h…8à›It=) "ÓÊ`ѺÀò/õÉalÉ‘2¶{˜„&¥Î(JÈI°ØU5P@-=¤Ñ£Í_ùÑÅ׳p¨Î×tý#úX’K}P‚(¾JFÊx­¨e@|¨ãjÕ Ð4øPžKÜ×~t-£âŠS "‰°Äþ†áŽÏ‡Õ‡ŠIØ|‡¬¸°k,K,ÊÚs[Pø8©ô¬îSAF¢`|À‰ðƒ4j E¨Œší¤¦3Aü|�*¾ˆ °û´%é. ³ Qq§ÙPI®Ã²÷Ø[^åD‹ÄÉ‹€€ È€ˆH`…‡]P[©PÊTUËààÚ£ ÝÒMA‰€ƒ„J@†eH‡fèƒ{yª˜|�À‡!ÀTRÊLȇP¿SÂ×O±A¾Ê[Z•Âø8I,Ý´X iÕßåÄ[ŒB(b@†i€†3ÀÊÁ„ ™Ú[ªXê4ÚôΆažj)Õ‘Ê¿ÄÐðÍ q`oJ þƒ[�…W’ðƒ¥PB¨/8i† „Ap?ý-OéC¼I%‰,päU¥"•0@º¬4žÚèd8kP�xPuhƒˆIÈàØÇ|Ù[²œ¯6ÓÄÈL‹?5Œ-ו- ]á¤X‡{H" (�@˜X8RŠ=hF}„Èêa†l¨�!U¾JIVFEäÁ{ &!(OL¥qk3 k³ySa(†Mòb¸†bhbÀ„V(…%Q_Çኆ©ÐjÙ©)s<¡5/é{¨§IáðmÛ}8¢_$Wà_ÐL€ƒ0‚¨€!áEt¿âQÆ@þÄfô¨ n ƒOûZ’} *Ý«¼!ˆO¹cøf0†fhs`†d@x‡ÄÅ•Ïl´Ð)²„¬¤ÑRút'ö '98›J:F˜±Í èƽaÀ P hàù�XE2üC'YE’éÀÙu?'S`ƒpL £F”HÍÛ\лƒ:b�,T‡‹°šCÎõQ cUo{§Ï‘Pô¹@ˆÆÛ1þË’UÛŽ£ÊYûqëb…í¹PˆF¸„+’€XDQª›iÜ”Ñ*‚"(%#.ÝÕ”® HC$´fÄÌc³BL‚r˜%¿r�‡~øà¾JU»Š•þù)MlàMV/4æ±€åa%)\\Ñ|êƒiIXWðƒAÎ8@»¸)8¨)ˆ7 $¥"™AÄT­QÚ¼9—“Vѽ":ç Dqù–mõC¢û‡ Ø 8nòœ®fÑ‘ :9Ѩ9TY­T˜È*¸wuµàuÂrųҜŽ:&È~“zh–| ,µBJ¨Š} ƒJP̹éŒ-RÒVWl>måæ$Fg¤;§x»T’ž;Œ›°� ø6ðkPhP@˜€x+MÙ Ž“à¨øÔ’ÈC?剼F­­Kê¸\&ñb Ûåî|Ðþ¾{Èi(†l„Bp‘£ƒ|x`h~èJˆ7§‹ëAœï —(û¾m"ä"&^ý½"¬•oúR*Ïmá™� ƒ ø@„uH@(@��d¦ª±;õNúd$k´5ËÛus5Ä}Õ.°æ¦2’jè£T‚\˜`†X„Á1ŠjPeÐè4‡ B¶Eôaá¡_LÅ¢2$7k»Yò{]3$PˆR"ÿ‚" _ùžpQ ‚¸J*ƒD`1O”C5“yUÖj¹8KX@8ŒÝ%Ñ85¿onÈ(A¨>ÚnÀ*2æ½ð„L zX‡dþx…a`… „aà%Mx«{P‡e8†h€WÀ†˜�<€ògšòK-C«­Övm×–FØÎfÍá‰ÞwDMñáѲô/Ȩ°”#h ™¥Aˆ�p Œã6Ú_þõÅ …Pgýþp‚ª¯~ã1ŠX5p¸e'&É6ÕÛ˜…vHvðhgÉ^ PÐ>@°S!È�;ØØ–g¨Ú’x"/à ”w4ëá™ÒNç”N7¤è¥Z�—ˆu÷ €Ø@ Á3¢Ãj4ìn‘¾Ðïî,¿%2p+êá¤:_]v® ªkºÅkê¸h„äHk0P€qè %‚þSoñyááÀ 4|«=|­ºtûVm�kç³ÈÊ­ÜjÜÁ$ð‡)Ö®Å@8ŠÁ£ËZŸ$|:šMâsYQñà(II„`§ñÒO¯ ¸ùìî§ÙÒp“a0…oP���F¸ƒ9Á*Å/~Œªo¢¿(W,~M/ë/FèB’áªÍU“:¹ÜÒ!!àY*D‘A0b!ù eˆ 3S`vY¯•/uAܳW•ˆh”ƒ-2„Ž-:@€Np›JøÏå'z€�c`Œ "$8CàA‚ c€ˆ¢ˆ/~ù1I>’)r¤È&“Pâ`¥ .)�Š)s&Íš6þmÂäRfΛ5)üq F‡0`8€ ù@ŒP%NY2uàT!Å„$ªƒ„P1bT‚e©äY§^:ešö«Ô–Nî”è^p’"Å “ÇBˆ „X0pCÀ7ŒHâ—‹ŽÿþàØ$I‘aÂŒD 2LË—ž=û -z4iNÓÕêu©W¯JÔ®ÕHU¤HÁl%õµT×c”=­„Âë«!Ã|uÝ–Ž}~ðéä L¢”èå{8°Á‡~Î/>ü_†Æ ˆñ—ðIpäð3 úõ/ÓÇϹ§N˜{ø— €¢¹ôX­1¥–rOu ÌálFá–ÛþKõöÕk2ˆUnD‰„f8P‰>ôAI>× “6¡‚Ý^QÞ`E4žŽ;Ú8bè­'Dîq ™|(‘„gNá÷Oýá4 ”SRð_YBu… l+œ˜ñÅÑ@à0RD]˜ n®!øZq$õ…æF>·SÈ$±8£N2(ðO.Ùá@ã_< ÄcxQ0Ê莇飤5æÞQ™Ä‘I '€1Á”S¨:MYj€U6¸[É=e pAIEÕ ?ЊØ´Uµ•®p–gMyE‚{qDÕ†%´P3KÒðƒBð B?>ø�&G4ŽÇmâÑ(þ™¸|1Ê×x‰6P`¹·ÑFãVuR}ÂíáÓN¦â;àgO©ÕVXžE–ÙGë­¸fõ@}Z’páDíEæ¸â†áŒ1ë˜3Aÿ4r‡U7t0„ &Mü®£à¾+n‘‹Ë­`ì:ôc ™Ëò±ñ¢†p÷æÛsÏ/§YA Ý`Àhae«F´Î�ĘÉ~¨pà c…•GE–+!™[{ƒ3ÿÐFm¼€’z]mó¸ÞN|äI-o+žwëù8d)Û\Õ±))ñß½£ú¸¾R�œTø\Äa¶ò¬›‰«UZQ®œEj$ž­áE&Y,àÐGhʱ+ÇAˆÊÄŠþ›òI&…ôúG-Ÿ{wêŠÇú±&¹Íû¼€ƒ¥€<÷G¼àöþg¥gà ç’ߡʸ—ÁÓGxTUÖ…”¦z¡(ç™óuƒ­I Ä8”�I’"ûÛâÊ[I(»­¡¶¶cý°Ë_JÃA)T;yÉððx3qž“g¼=(!$ErÚB˜v°Ý&Y¢` ã½Í…Qø%zÐ}œ`(¨Œf…¬ã܇I:ÓO}<B2Žô胘²¡e.ƒý\æw/qà�‹h<š|‚ŠyvD|ù­xO4M 55›éAƒÚ ¿¥£Ì•K#aª!t� |hCä@Å=þ€ Ÿ1v›ñ¡T„sšéì‡6ŒÛ޼•2Ôp†vf:㙳0xÆCàiÊR¥GBÒ3Qìɧ†GªÏ„†8LŠ]‘gÁYͦLeº"ÓþB#L©mbI€ƒ>*q�IlcΰF?‚pGì8%3÷©O]ò–A:H‚8\Të4'8ó–2lɘ§É·<rÏS$ t´@UÍKb 8E$zST™|dZ0ZdiXL爙©Ý¹Ï#.`F3®QŠJŒ¬9‚‘Ç[Jå½b"÷PGÌÌn[©<ÒUI@Ñ—ÙJ[‚2–!2‘EäpȲ¼ î)‡\þþ0M#2‘'˜ÕHåÒÐ4³8¥ÓÈ¡ öÅ…vH"!I …;|ÿøG9:x€gp^3W•xª¥ö‚äiÊ:’!kS|Û¦h hMf ª¯bžX/Ê@³0èš.©£d–z”8ÕèóžW¼Ñ„* ršÁ*‚ÓÌY¤"¦CÒ}ÞxK«²à-8ÂŽàÃæ¹ÔobUK%o*¯Fž'© ’Ä ×zá5¤*iH¤æš²üá+® ËY„Æ¥ºŠ¢­Ù–œ*€%2™fu`½V:Î\Jo!‘Èp5XüÌ ˜œ¹LBqЂ$ÐѤ/]àK<J¥˜"T~„½Œg+kþÙ¶TMWEIš´ä• ½êp‹³f µ…UMÊ1œE™74‹^…7Pm­I#ùM$nrs.Ej…ù$÷ŸÛÔ$}š ’ó~“?ÿ í& [UaE*Ó% Pг£\O>”–°Xs^§>%‘gʇ,ך®¸I ²(—Іœ®f¶;‹hi G¨ª=® äÎȤ„¢2gªõ®cÓA¢x`N’R‡…bC½˜•#1wYµ_¾%µX1а,¢ó²ÉM]r‹Þ;’`!gÉK<p%íÎ!3v$h°ãɼ Ier“!šK°(Wg„Æ Ð<Äc‰ WÖÃÃf{[þ’'®~Ö…rUÞ†ÍÖ¼ûUUâwfhfTª=öª}NG™åªõd]¸¬Ú(Ú²¢Ž4“AýÊÕ%ÎPà”åPJÆL“»J›ëx8¡ l´—È%gæ5¹Æ«Öö²¬½Í´¤£\]ô“ž \ÊG­6MW¦2‘�Ð's½å@†š¬¡Þôœ]grÐöø€š œU«ƒaOhv“mmåË!BÇMÂL¼” ze+ÜÚ“ݤ؀×Õ$ ü1Ô“£\�“I(N�Ód‡(ŸùÉ'`}×{ 3Áy½ èh®š¾TUk¬8ÊÈÅÌXºeT¬&Þ þÒÊL N ˆBD’£´ÍãÇQíWƒg*_6€æ3—ÉÆ†º—\¦*2;Ê}€ïž¢ÞJˆ‰ê]¯0Ð{óú©@À}a%bÊ® I´DÛ¥P-G=J„Žn½ëUDŒ—˜d’–A;¥øRB؇ʀtþäˆÉN~v H0 kgûPÝN“zóA&pÇ»tz§aï¹^`ô<®eŠc{%\AóRˆ²›:¾ÉŠNCºmÎÔéªéH›Ò"›ç·Þ&ðë¡GóP^Ž˜”ý;Ð ˜´LˆóG�åç'DQ¸ß~߀ ½Þã/‡Ýš8"‘–°”°$ÈÅÖòd\öðÕþiÐ].Ü\µÔ�õLèÝÁY�Ê]�é™ùýÙÍ Ê‰üÅü… „ ½þOHYZ¨E…›ŒÖ‰AÖ© œL(i‘„ÄGa=–ÀQ’�­›”„Þ”C9¤Ùe | )š†F½• ýÍDàÜÜ©`®‰UoÄÙñÁ ‚DŧH”‡Lm ™Œ‰­�üÓ¯ˆÓ†i^¾ Ûa@°a ÙÑå8¡OÐ Ž €Ö òÜîžß8›yiˆSÁF„µÕx‘aQdÌK[[“…Ûøe N 4í¡O|ÎQáýAÜÕb“U׆ÀoÌØX$þ^yXÄÌJ-ÚT­$A6á_öÍDþC!È„8á;lâ3­ÄN|âù]ä[PÀ¼‘b½Ý[Lä)¦¢*®•«(ò±Ä1’±5Î(eŽxtαìÇCíbMøb(ÈD� Ü=�Bø_ŸžÜO´!ÝÕË(ÚÀ â5æFÖŒÑK€T fÒ&m™côA—¢]¡oÅÄöÉ„  \%Äc1¨$ãßùìÉŸÜÉÄ?d@®Õo¬IBþÖ›ü*!˜…ñ¢I$ ø"è5@?Œ]F²?x†J˜gäÝÑÛ4¥ê‹JU">NXiœÔp´ÄÐðÝ©€Õ•íT‘] þUNå%ŠÝ÷ñ$ÛùäK Üß°ÔKè[5ʨè4Ö^R.Ѩä£e”ÏDÒõñÙ×…”’,I"Ý•A GŽÓT �ëýÃèÅD˱ÞüäÉ…`ºe½}Fðœ3.¥N\_¯%N¥itæÏ€ÖLâ‹Dy `ÎUAiTV àì¯H Ñ$’€Á¬AÜWQ@ÁÁ‚AàíKF1PlŠ\7}dI–ŠD6PDù¢T8Iç“$'•ôD™Õ] ä[¹ŠzùqJ’ùVtª•SH7ÉÕ¦ðp˜h$K’Óz¡ÅŒq#%¦oy“Rþårb´¹â‚)“¸½æjàq'l§ÈÊW¹ H¡Õ3Á H!’nª§tÏzš¥r‚¢9•\Å`”!_lÒEM`ލ°1ѵ¢7rgr0Å‚¦ Þ‘SYTF¥Ú!=[Ú–|‰Õа„$e”iFgj!!›Xù±-ÌQ!Ho<Uâ4¨v:Ï6%KYTk,‰H T×át m-È‹ý†w¶Ö¾¤Êi!ÎZ° l<á4Ðò ZæJ)ç[\Xm…‡è†R ¬¨d¦hzúW`fRñð V`È ŠTƒ׉‚$éštųÙp†i‡¤–�;�������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/mini-windows.gif�����������������������������������������������������0000644�0001750�0001750�00000000126�11462120062�017724� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ñ��²ÀÜ�����ÿÿÿÿ,�������/Œ âïÂb£Ú*'w ot ô„×a(ˆ¨YªGŠa½Þi® û¡i6,â��;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/ofolder.gif����������������������������������������������������������0000644�0001750�0001750�00000000156�11462120062�016735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò��ÿÿÿ���ÙÙÙÿÿ����������,�������;*Ìúˆ8ãƒä!›“€&r€Û8š^ë¬UCœÞDÀœ¾±¼O£;T)“Ñå ΨT*«�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/mini-book1.gif�������������������������������������������������������0000644�0001750�0001750�00000000155�11462120062�017247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò��²ÀÜ���ÿ��ÿÿ�ÿÿÿ������,�������:ºÁp9!^T“R˲Ö\3 _É9cùYA•ª[³½ë9“[PÝí;B¨UÑ‘–Ž AÍËÓ¹H��;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/mini-ofolder.gif�����������������������������������������������������0000644�0001750�0001750�00000000162�11462120062�017664� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò��²ÀÜ���ÿÿÿÙÙÙÿÿ�������,�������?*ÌúˆA©ˆo’²ÉhÍ2p¤W}4te)` ïtÞ/Q¯- ¿*–°–šôJ°”ê¸y)e²€ ­Z­˜ì#�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/jan25_palm3x_L.jpg���������������������������������������������������0000644�0001750�0001750�00000007720�11462120062�020000� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÿØÿà�JFIF��H�H��ÿÛ�C�       ÿÛ�C ÿÀ��d�I"�ÿÄ������������� ÿÄ�D� ����!1A "Qaq2Ñ‘#$&3BSbr±%6CR„’“¤ÁÂÒðÿÄ��������������ÿÄ�2�� ��������!1AQq"23ab‘±ÁCr‚ðñÿÚ� ��?�4½(½#ïœ «Û–늊á5í*¦•ê‹òÆ‘À Œ’dó=1õÖQ¶}38ݽ¹öÇlõþíXš¥!Y  ‘ùT…ñ2FAÎAÔôÓoX©þql0;ûÇ¿oÇO î¿‰»Û…T Ÿwª¤–àå‹S ,’Æ ¯õI9¶�úß,ê΢kpïCfѳUéUéCm¬ºWpºÝMéO?‹ ˆêî@P±—æpr0À{ƒV$ôôâzmXÓ§örõ¡ }-8¿p2¢o:ùä” ¤þ!ذ\¨b= 2;u5³î;Ó~Ü¢µíšZz‰êiÞ²¨ÓDð  βJФ9ïÛ'¶€b01´ºbÑ]Здhÿ�.'6²Y@Çsã?ókçðê⛹HívlޤAûô!µ³‰ÍI lû}MJ«ÁSÊ&‚U`YY_ €H9뎚…²Ý7Ö㞢’ÃOI[-'/Õ„qÌYT€Ê £vÏm/Æet]¨PL$FÒúnqr¢d§¦³ÛY"$pó33„*÷bO@ž¯¼[ãoxGn³\¯]§Z·£ (¢(ªÄ?: ~ :yè�†‡ôó$´V�’ÆÈct¯@ÊH,Œê2 ö8é©c¹ø½{­8‰w¨š’)8½’°$ÁT¼l£¬N¡*@È öÆ”XŒ¿+Y ÚON©Äz]è±Ç ÁÆÍ·~ªÜ–úZzËÍ(¼JlòLr‚AìÜƒŽºkpÐêïŸÅÚÛõ2Kü?ðpþš.uÀÉ\ÑÁ6ßX¿úű1åEqÏÛžÓBÎÝÚ›|nŠ >è’®:(¨*k|JZ·¦’7ŒÆCó©È�3dgh£õʱî-ŒXüŠáŒüüH4.lºº8·½ªj‘;r[ëü8áˆJò9ERƒ…,qôü´9›žÜšS£[|Âã1!¦º'5|$átûuÞZ+Œ×ºŠI-"o‰ÁFgunÌ”9éÌ{v°í]©Ãëµ¾·ní[õ%DT2ï8!I£¤qHyyß“%GO–q«|íêh%—rÙáLB%± Qä%Ç %Ï( (Î�9ÒŽñÂSQ,ƒbr ªp\`³ˆóÐç*BçË:ÌÎ*pÒ×jpîkä8t¥Qª6ShéèíÄ[(vµÖz fQL°_¨Äq a <xæpep¤BíM“´¶Ü÷Ø;#pµeePjè¡Ü°Êíeˆ™K)å¤O„þ“®­°]xQQJiaÚP¤Ë Û§ER„.@1c9àÔ# 9¶îÍœ°Wî‹^Ó¬Š_A4‰K4U3©å%‚¨èNFzvΠɉœÐÇo]@'•ú_NhK[ýñRt›J‚¶–*›‹nº:§"y©št—‘À*ªYcå`�è3ÛYŸ¶Ý¯kOe†Ð÷•sÏ<ÞÙ‚Ï',j_!’B¨$äá@5 7vûÃ,ÔÖûÄÂE—–ž© ‡Ô�Sž^b: dë6âÆë·n «3PS×D)ÚL˜eA uR ‰�8èAÎuqä Å Ö-`¿oT¢€;X´Zz¸\¶Üâ Ÿ+å1ÿ�´OÓF.ƒVÌÆKÐÿ�VíFß¾›øÑ­휭Áž²F1ßv#ôø¨î õüphVØ2Ò?ìVBΓQW„eb¦6TÖî0žŠ¯Yx)_ÃéGo ä§÷ÓèIáõUAâVÜ‚ž2é-Î*€Ä'„„ êy‚ŒyöרÖI1øOÕq›Õ+WµWß)Â]©AI[Yˆ¹ã[¡¨Âò¶ qæ 9‡Pp{jPî>&,r<›"LÆ>JØÈÜË’€(Ç1-ôï¨+UÞ¹&Z;m¡Ç‚Þ%eª:PÕAËøŽH%OAËç©qîj*?hâWÊÆ¢•L|KƒÉœ’2’O\çÈ d2¾"iú|u_¡WÙ7×*›¹ ½}ãrŒã1g¾AÏßJKïù˜®Î…Ê€z×F Œy01×Ï_¾˜{Ÿw¸+ûF·‡RKzŒŒäg®@#¾0~š›´ÁYGnX¯· uub³x•ó¬ ’€ È)�àõ#:‰+¢ °ÖwæBbG¹HP×ß'¢Š{­ ]YË B)‘OE|.r�=‡ŸßYo$–Iöø˜Tç3àË)' Ôr÷ÿ�÷}iR{c'Ú¹éçùgY?¤ƒšÂajr›&&cŽ‹Œç¶®üß:‹j—/„¢ƒÚOú³‰÷_“Òåo=~´íúhÙÐ;êÅ5¿‰i“‘]lcùÃ/飋Z¦/iœ­™Á³e*¼>˜c9¹¯_>”ú ø}E_vÌHQ}šè$å$S�r#$ƒßËF¬á3oáÛ€Iö‹˜éþ4�_6$Í`¥¯ÜçoRPÃSYQp´†(Ô.G(*Hò ¶t8æ r™cq«]]oÓš ¨ˆÈv,UÆXoöæXƒFñ= ÆC+HªÊrº 1Ætâ‹fmúJôõ[åê«%ÔÉøS…2Û·LƒÛT¢Û~¾Ýj¦·]æškE=,‘û¸ÓÖH›–b¯ åçä|µc£²KK4nMÔ@dð—à ‚ ƒ)�ä òZÈ%‡Ò[¬ö£÷<Ô3'BŸ>ÃÙÄÁšðL«¼wU‰Ê+3b®2 9$¿-;M¡¶hÚ£%ã HŒ×@ñ°ç,O+ÈUˆf$ 1ØW$°4tÒB‘Þ<"§áˆÆ¤Œ’@ldƒ×Ëí© ­rH°†¼K eˆð†pOÊlà䃓’zäh xŽÍxôî—™õ]ááÞÌ»ÐÒÝœ ®`º’=ÀĘQÛ:«qáåw±,§#Æå3'8\ã—¯ß:±ÑfØÐVÝo"âZSqÓFy V1âz+ �{ãTŽ'n«Vú¶Ø¯6s2Ä’OO,s Ib”%X@8#±#W¾LÊüÞÉe¢÷?´¢dOkÁwUú°3ì<K9ÈöËXÏÏø™´rèõ`ÇËhâCyûÆÜ¿ºýtpëGÅï3•ƒx «ÖmóKbWý Ö®,Žãž�Í4lzJ{ÖáK5Å<ZzÊZˆäBz…9û‚24{úÊ(<~Ø®?’n('°A(ê|†@מJhjê'‚¦â( š–X^¤€ëŒ�™ïýÜùè¤ÓåòDÎ$ïÅ ®ÖÁi³Úigº;ó^ªë*£§žµ¦ŠGäÅeˆ˜€PÈ@g V‚ÎTaOR>¹}c;‚i[j…%îÑES$±­<ąÎ|B]@2|tÂŽ¤õÖ…O¿-ëø•Ìá@fñ°Žçðþ~z𸜗_èFâ;#°­ ¤Hì>Gë×IŽ˜)=ñ޾X韮«¿-âx¥¤2 ò¨ ë€H ~Zýÿ�iðÈièó嚣ô臮##ÌG蟒}—-Ój°]!­‡sUGKIõÒfX3+J«·E8$uÈÁ#T=ûo°ÙvõŠ ·2ÍI,ÓÔ{@”JgršFqÑŽ‚@Æ1Ó]·Å—|XkmwÛG ­<TÃøÉ"爿*H)(Kg”à}sV¼ÒClÛ4t-º¢¾Ü²¢²ºt„À¢IŽXãì�cÏï«ü›+Åa±1É l¯Ÿø…ûŠG7ªý¶—jÛý­â‘ûSgÿ�m\ãätz³hšŸ„;ŠàGJýÉ(SóÓÀ£L“¢ÿ�•õ}‰73»¤ÞôêÛÍôw¾Nf¶ÔÑWŒy‰ú‘å¯.k­Ó]ÑŠóÉ4PC’"VyU',yFOSœ kÙ¾-mx÷¯ ÷.Õ’>quµÔÒªÿ�}£!1õæÆ¼z¨Üà¹\„³TA$nDl!’7‰X/ÂÁ†A àŽ£Sð2B0ïk¯]Šé\þÜ”)YŠ8¸ÜÂ<Ηjïm$mÜÇŠo»¶…ßaî%Û·–†wzT«Š¦Ÿ›Ãq’A=È`AÔ}Κ®Õi·]« >Í ôÊ®]ÌBFˆ¹ rŒ:0*NqƒMn›…Ãt_g¾Üëk«jfè%«‘YÂù�U@%P5ö®x_l¦Û¥žåì~ÑímA7†ÔñÏæñ±ø†{•�|‰`º]©šUp½RÛ®5k3øôΫI*˜œ|=%cñ‚r@)Œ~!œYögwG¤¹E¶(¢—Ýp¥ç”Ï‚R5RrY‚œ`c#ëÒµ<SQÜéå´I=|æ?a,„©L ¨å ’Aç=m[v}î§i5m]¶®ëm¸UAà‰èZ<òç<§O)œ:ža’<ó¤ «a ›rÜí–{sÃEÒ¡)b5r‘œ|Mä|±Žý4ïtíkŽÓÜÓ틚(©†4™YYIdb@$) ‚Fb3‚zv¤¶ÃDRËLî‘È$²²¾r!ûƒÓ<Øï©KÔ­{¼Ô_kd«–yÈ2M]Tj&`�g* €�  |´åÕÍ Õè¿ —ÝŽö™�júúú²{dÊõé‰L}N²OE{,–ì»|ð´Rû¦)äFR ´¥¥ ç®~=kš¦y·Qð\j< #Ï#XFàà· këæ­¬á݆I§‘žGö4RÌH$ž\u$’t´´AÙ%üàËžÙ?è×\£ç$nVá­›òGYòm-->§uJ×%ôwà9ýšZ~ÂAØ‹N!à'" ì½1ø¢fò3¥¥¢sqJÓØx+ÂHˆðêÂ>ôjÏR´<+á­4Ê`ØV*AèèOÓýÝ--£ctàì¶{<IGÀ^ƒË§aôÔ†––’eÿÙ������������������������������������������������./saods9/blt3.0.1/demos/images/sample.gif�����������������������������������������������������������0000644�0001750�0001750�00000553367�11462120062�016605� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aA<÷��1…š† ¨„JF\¨ÄÁ’GÎ…BÄI4H VE!—f&ØÇ±Ue_‰M' &4ÖˆàäЋji‡JY¦¦¡RIYh'‰)f¬¾Õ©‘Qh~ÑËÉ"gu*G§Jk†n¬*+¼§”®g(°ie- k†Ÿhhvl î©‘*F±äñ9D6ñåÉš8Èi,×§PuEq)AhKY¯HUJ0FºŠŒ§ÆØˆ:ñÊÌÌit¿„C8$˜U ѯ¸µu)r˜¬2KiòƗЉk’xjU4˜¬Àh8%1+GwU'q¼ÊÔ¨Y ¿¶¡1XuŠtv{¢—”P Ö¸žïëê86®zcPXgÚÙÔÒ—ròŠ“áõòl™Œšw!½†içn…¨ZVZSž8,(Xy®hCI3)hŒlY`øø÷©2ƒž³Êynž)3wdApH7†z‡ˆ„nÆy7ÝÕ¸¸Êy±±M+(t/﹞+/¥†l48JXTH‘X:КŠ0Bš®‡ÁÍÇI\ð§r­+C©œ{ÁÄ Tg‹¬ÂR„ˆ¥Ó—BŒ8IÁöõÛ´rvta8et(w”7O5UUñÖ·52g:DšÕßÇZh¼œyº™ñ˜ž¨´¨¯:JÅX9ZxdïÛÕ½Øâñ·eL;I­8%Þ{IÁÕÂæ‰tç˜pÒ»½SFDgMâæäµvD–tRU|¾¹»‡šŽòº¿;uxj„‘p ÂIrŽl‡¨I8p 3ÀæñÆjQÖ¥xuVBYy–Q/ª{‰K\~‹ZwÐ{sf\‰.¡9I¬–Tˆ¤Å‡‡Š8h’è”H8u•Á‘?ç|‡¨ur§‡¸ËRl4FU2(/R7.¨Z6g{“¢š¦756ÚÜæn\v0;j;iNˆ¥»ª°ñȰÆzQöï˹’s¿§zi¹ÄŸ,E– (Þ‰>X %.™HSw*xhsy7¸Y_:Vo‰¬­ßšŽRš¶x8D©ØêÖYj9‘©ŠËÚŒ'0ô©«Š:+ÀÅ¿¸œ§,����A<�þ�ÓH° Áƒ*\È —ãTQiÂ€ŠˆC ¶jõp`ÇŒ%0hrˆÎ8…\ª´J“²JJUÒÄT©r£Ë†)¢  'Q¦L‰sÛ¶¢G[vŒù‘` Z´W%èÀ*.¶2šeã¶%Kü‰ÚÆAÔÖm;>Äjðc :t0:3+N¶*³l“YÅhÝPà¤8PE*Ö”Y²Ä …ugO*‡*ÑÉÂïÙ®9,á`´,Í ;oÎ"ÊŸiK\.f`ˆJʼn”±zÝJÓ¦ÊmXsë–]»UÍš¾ƒ÷-§q̉·— jræÌ“'Ö;]zõmY8Lÿü9»wíà¹þsð'¾¼øX²ÉéCJŽ”N¢ô9Q ;tN¬°°R •(ïÉÒ€8 J#¾@cˆ•d¤VTÕ[‡0PI-°UYeuå¢l©ÄGY%”…*ª0E… ÝÄÒŒ3¶“L4„•U'äae\H`RœquÖJ7ÎÔÔUXÑ1Q9†øÔ!“wÅYL­è"TAUå£R§p[(-„"Y\ ÀEÇn¹y›(EçgKœrTKèEy›XU(t@Ó„&M4¡J„¹ ÙJq¼¥¤œj/)¥Û]ðÆè¢Ä·¨rPa TÛ„¢œrzBg”‰EvÕ±Šþ¬fÇÝvÞÉÊ*䉗+yþ¨Ò 8"H TÐI °@ɲ”4ÐE²È2(� öŽØf«- îÉДcRC7¸dAU„’C\S…ˆ®‡º}ÈæP. ¥-fÑB0"”ä8–{ZÜÕãU0AÚ×6» hÔQ¿-*0L½›‘Ä“Ø=œewXbæn7R…ÛF]YÖ˜’‰á!lÌæ]X=Lr¨[%72‘FÙø–Th‚±OitxäÉ4ÉF2^‡QET•ÖÖ)ÔÆ)*¤¡l”õÕØiÊt­|]_›:ª­Ö*ëvæµÍëg»Žg^,T EVÈŸþ, D ( €ÐÅ<„Ï# $r8ÅlëøãUrÆåhôTãô ¹ŽE›™&¢34±è#œ–@§/´âOSñk`¹£—~ÐI¡džùZ8^•Ö‰¾Ù¯¹Ëî:ÅU0PEÆWÇz1&ê• Œmw6V+¥‰R3ɶ«Ù¡»l†Ï—o¿%~KãH%BE…ŠðâmU(qp2ÑF|K%–¨ÒÔPWŠSÖSN®–%œåìQ¤jN¨Æöœê$<­ŠUÛ¸ó¶ñàªW¼ÂUw8€ž  íÁ± !‡ÄÉA”äPŒ>ôa,Ð)6GÃò«dG%^S‘‘t¨8þ©úÞn6 Àå]*H—’Ä9‚¡Î! y‹²­ÐÅDs9êH™ÀÛ=ñ‰La Ô;˜àÎGÄ ^° h¸f_Vá ùx£4´´¢a[ ÎQβ‹mŒN~aÓ8Œø“9†OaÀÃÒ!Ù’4ìPqÙÃb“µ=2Æ|û Q› &MÑ„9K³d•…µ(ªˆ¢$[–І*¬1P:Úy¥­¾ó@¸™çmä€É“ô€£XÅþ± # b ÀÞ Ì#ÜáÖXÅ*, ØðšÚ Š*Q‰Ì Ç+4 &UB± C%¤B&2‰(›¶ÉëXR¯1Ö¨@Rþ¬„†—- …áW“TÑ„Jañ\KQBKÆâE th‚ÊDªx$tO´’‚“1rÄ6'bØQü±¥¥P§ ÃSª’’qpa­€©K›6F?ÑQD½ÑÆ‘*l¢"D؃èÀ—âì1§ Ëʉd‚¿˜â¦ûÛÈL9iL…Í8‹ r�x5QMlY�bXX«Q¥­;µ¤ Z5¨K Ê­Wà¡['TAa:ÀÁ˜À Þp `L%˜B¦p‰b ÀB°ÉXléP*:I9Ê!ÊÒPh‚6+ ¨"ªÐ€D; ® Mµ»¢EÆ#ÌQsX¼þf漇9ö«#{Kf3:Üät ]ËC1ªÔ†¦K¢$Ù^NG0¥šˆ#ôbªjz·Gt”MO‰Ë!cÑ›ÔÔ¥.}éëȚŒÑ.å£ÉCZÀ€ž0@ÅCˆj2P‘ï¾ðÑazSµM%Ê”�îïÖöÈœ¬nj••\”uÈà®U¶t›ZsõVîÐ DˆæÐðBRx8š«˜Á ,` ArXE4Ëb .“gk&×E¹�Mä 9D° l‚o`9À¡ ˆÀ¯ ‚ÂQ‰p¨¢²"ÈÂá$ŠÀ%¥´µ–ck÷Ä(\–mÂBÁ’TÅB !#þ˜‹.($.È(Iæ˜Òæ~Äžö¼hð†ÂgáÖň 8„O8Ð]zÝd%çMtZ|COÕÔëÐõ*Zñ\ M@ª˜óþöê1ÚÑ1UI |wSÿEUkZâ(³&*Qi­k§ëך¯R'mg• \·R˜—™8²ARXã…«h@1@ÑJœà„Ê– ‹b°CÚh±¶ò–‰\Äx†È*Y×P¯Ð„Ô‡WšÐ4ȱ‰+¸A Ý„~ì‹ ôØÈäp+š€1pjb„”ðd‚s3¯qÍ:¥²Ímn™írU2ÇÏ̅⇨m˜þ‚Ð…ôˆCT!ÓJ¶•gÎAD‰8EÈ9žæ¶¸<xL«J¼tîe:d.W$ʵ”—05 9‰FÚ¡qÐAs Z†`"$Ü,mŽyŒWï’Ö;ÃÈS* p²´µ¼ P”Åaõ¨¸:6Y¢ê3§ U¬hÙ¶ìPXn±\Áãa7¡r€D0û C@¢úi€2@ÐKè' 'XÅ|¶Mù„0.È®v 1ßq�ªT؃ÜXY°¢¬àñ8E°_¼a³rðñ|ñŠ&lB ›ø+@ ĸ¬xE9¨à×h‚DPwï5q…W¤»àà4D9ä"™‘ c ‡8õ5þÄ�2M|#I“JÓ'•©˜¿B>zhC ÂÚ«l¼uéãøÈR..ßn¦éÛ¡øŸÒºá&I2gñ÷'¢s¸qqë„Cò§q#sfES÷rˆ€¡  ÇNÇ�:væ3GBrúÅR²!^µ±‚�¦)^Ñ)ªÖ)•dTÀñØ!6¦¢* $Aµ²kâ!+¿&7ãÁ�yÇ+Y@þP�p8,À}à� �C’‡b p Êà�Ê •÷…ì&ÁS€Ö $Vd Ð� @pšÕÖ€²Y†@ `Рbx¾� "� àB b{°Tþ¯°bd•° ´g9šÐ àIàðBS@¯À�BðMAãÈ0¾Wë6|¯A9`&8´€jr&°fOú$O¡eüB€(PMwåW[G bQ|1%/Wð—9ÙíTÐÝÄŒS~:ä×#Ëx!€²q .³>±Nù‡9tÌéÓ9R!Jt€ ’ í5|å ˆ$á‚Ãáhkq¢ƒH ‚- QCaÇIšÂi•2=g7`Y3V:#*1³@ ö@taÜ&½¦Vz·AÚ!W‡p,ÌV V@ Q€Xh€8 Ày RPþÙ `X“_PiPÀ(/•‡à“Á� À�þ ±,†%(=anÐP@‡ÖðÒF›`à †Tá   dõ–‡¾à ~Ð^{0|D ŠÆƒ<GB àDÓgnŸÓÕ7†³hÝ×29  ã— úG&ê„Z€B˜�+…"%‘&9$>w<š%@£YšàsT€&r© “}1öà„‰{ð W@{@¬ààÐà�Ãç$áÄcmDÐ,6� ÿ6Z>F†�ˆÐo†`9FÖYøS Çpq}Á€pa8¶ Ðc°›Ð >°cÐçSþ'T  ›ÀÃ�áà-’"�„(áR(„Â�,1G‘5‡1l?†áR43v.8Vuœ6P‘ÅÑ¡¢)˜J³ÖUCi‘¶‚VÚkleA´+uƒM¨ €BðQ7Æ¢YvS7‚!^h“&ÊrÑ#\2Hüg~2xîA±@† ’GQ"šÐO7@Ó› p } ódÅà r  T¯€1DZ†X Ñ ·>qApè(h1Ž ×E[&´He’aŽé#‹yDib0r99¶Ga#ᆛ¥ Î7Y 0ð 0}ðЕX› nþå JædLÖ€pYp€|D: !}À ÿ °¬0Š84ênð ‚â{u.š)”Õ‘a;ܤNåàGà 6°  {o0O {@W@bp A¶ ²yo\I6°3ð�oTké-Ä ­¡!xÙŽJSUéU@¹Ó&†S—⦦¹¥”G›"‘£3UµJ°v5 ª6=H+î*wi5A©}ç¡àð+Lh,*“Ù 0Ù…,¹':° Qræ²3QQf!™+§ƒÆrÑ›²˜E‚—™êÔ^r�Ir‘&†ð … ¬‹>ª°.â$¿Éþ˜™ zR1ê„C妞çt›Õ}xù…‚—rÑœ"TÐ<Q¹C Y ÷¨á orÁ Ðð•  ›�—ÃçdÐà Ð äðUŠ1›ð DZˆëCDàF·9žBfdœ99ãt<Ð09âD›5|TбtPY©Ê/yK— €šÔ bp›@oà T`D`d†ë ˆ8f DPL¹º oð�‹ëc… 8ú«º&ü¹I U3]¡$:ÅXQ)ªË‚IG yU ™®´iW@d*Ó!K š²ôƒ¡ózwM�H9¼¿D¢$ŠB+-R 3Ù¼ÙÀ’;½b°þ³r³³‹/• @$O1qÝ´Cp9Ua”k3ƒÄ:éƒY °ћ䴪ÆãTú9U6e¢R½é"Px„ôrá9ihœ&T0zëô9¬`Ð>"PD0 ‡1" Š‘‘íå �ÈC›° � •€< P h� Ügž:Kå_v L¡ž4¬šN’!„ø A3(wÀÀc{à�?f Ö R0p"À Ö Â…Xµ"ð­a{PàEàFM ˆ“E(áô^Hzc·‚Iã(ŸÆ/qSƱ‚.˜Æ©K568ã°›@Š¢`©»þÕ‘Ôá¡‘À&„‰YaŸñKÆ[7ýš ‘ 2 “Í›¼Ê É+I½š¼É&7…±e÷'ŒTºQSÇ.%PâH6í{¥=q&#Q¤Z˜ZªÃåG†€·q!M }*¥&%¡RQ1¹,€¢ rp™cz~¨Y»¬�¯� 6¶Ë…'~ ÷s `7ªh{B"˜÷‡~›!‡pËQr§�(»œ™›Âߢ™‡  ‰c9š– 0Áé�ôÌ }`¿íÜÅ � !nr0zt¸YwÆëÓ•ÑP Ö M°<}ѶQ¸A<31j¢†?›Ô­TE5P%þ@Áá?þéIViwk×±®m7wIÈdKÀû±@¼ÂÿЯR Ô”ì¼R°]¸•ì�œÜÔN½90’§|R&QÁ%gêÍbx„?›‹ƒT(%1qÌ:=G6í²/Rd;-?ÌTàAÓ‡™‡PšU˜>÷sd“˜öˉásðËB)V„Öj§)Ep¡/âømùˬì^%ë©¥œ²0s×ȰB$!hó²2rUx§À—rÑ…R9žj ]5C>O?»ñÆûµu/•ÆÛ:DzñY2@Ë!‘¥4VdW®¹Û`<Aê»™Kã¡ãA×=íÈCþM¢Ï“2‰¼‚¡ [øÔÜÝÝ›ü/®³#gf;ç%xftŸJ$^üSÅñRl^32H÷‡:'‡‚®ÃÞöͧ|ÕM‡?jS…E� à•)Pѽ@á´fDa5Yp §à?AØ?ñe¾ þ`(¼%ºô‰u•")§«†ÑiiÜisL»«„ÇáJ@¤„jfµ`€L+;ˆ‘³â‘ˆajE7Hù+"j7ÖMÝvÓ¯ÿÊ…RàÝLÞäNþä6t.£ó#L4 Ûëèßà•.Å“Þ OQD`ÎDÓ*Ÿ£H#ÒH޶æù#G\U)Í1fJkW®ê:V:HÓ ÊþÈ=µw>~K4¼HùKðKýêÈ/I¢2i7‹¾ÝPé’>éó8YAVîÉ8òmæh§L\mF7ÒaÄ$ ãhfd'hE Âitäç>øµâcgœ†b÷ŸxVYBk]Ñ1 „6Ô» a®ÇîܺèN¼C¢Dí�C “($ÔÚMéØžíÜMæó/3;nÞ©“©óV„;E·~Ãe‚ûµ\ß¾éö2]‘òw¡æu¡_%®›dvÎ5/æCÒ+Þ�5ó£âbg_¹ æ�jV Ô  †Vº¶6ñºì¶”}× ±ðw˜<äÉ› † Ô!*®í$_þòËbîþEþ<¿U:Àµévîrïj)7Ñî†æ'†¦IÑÕóä>6á;$Mj³qS]có§>]pÌuÀáôEv6!vª®}Q`Eq5ÍÑ2­q'w<ölãõB+åáK==lu3n"Êè×ÍñÒkòr?÷5©òï^ê¡^1zOt¤ƒ÷çŽská[O1;¯^µôí~âô²óâ:G6ECß&—´uÓ >;b#†ÔT\f~U…šâ‚\óæW…®IØ/wccÓÆ¾ã¾{wÑ-äÖÝè1iݘüKÒNÉt¿ûso½c÷/ïòïî/9¢#F·_1ßHk¶f£ÒJþ±éˆté5RSþ>)Xj“‚IûHîHÇ(¨ƒSLñuãƒIWÅ_TcuFã¯æ? ìªÆ)àºûJ€^õ¯Êž+½„ñ…n,Âæ¡�‘MJ… 6© KŠYÒ<„QâDŠ-^ĘQãFŽ=~ò#‘«l<™2âÉ•Yj$é² É—i¦‰ù°fš)iV:(Ož)OÆ<9Ž(—*­Zú´•„mA‹JeZThT§UŸB­²­•N£`£6E›V¨S©MÙ†ýÚ*”[§¡ØÊm•…j(±z·Ù¥šw*Õm~³>•EqaÅ7ÎÂA1ʉ%S¦ìóeUàÀuþWa h)¥ žÎfˆtÊJ¾†[ölÚµ/î´íq(n—Duú–ø8E¤¿sδIôhrœ6Ëe”iÖ¬8­FWnÖìW»sƒ~5}«X»w£fyª|ºÚèq›¶ˆ.Á½T»n¹âµ?ujX è÷o“@¹�\Œ*½ „,ÁÅ&‹L²ÈÄ,²S(ƒP±X:i¢‰NNM!+5Ñ(Í×rC1EWd±ÅÚx“¨'à^’¢˜rÊI&šÊÑ"ä¬++;«vÏ7•Ðï;íÎÚjÈïÌë)ô´Ò*-õÆ¡É) ÚƒŠ­ª¼“ê®´” °©tª¿þôBï°¼+ Á/£þÁ,&„ð²<#¼  Á)m!GK-¤È¦e”‘£Q…4RI'}ôHëŒD颬Tú͹¡šã´·%‹¢ÒÒç–«<¨¢É&ñz ;ýXÂN(œ°tR-$•ìò+Ý’¯ÌV¤JX¼ V@�ÕTð09›­ÓÎÌŒBk)‹%4)òРCKkhQK£´\sÏE×E'bÉÒá4ýí¥‘Sé&#ºiSRQ=ÒTŸ ª²W-w#‹Õ¦ª„²ª-ÓØF,€ûír»´´ä2.-‡%óL¼�ûK¿ºòê¯cņeÎ9„e;éÔó2üAˆ4Ófæv!qea-›twæ¹gŸmþ µ¤­J®Çñ±ÊVMU®i"#ŽØ;í~Ú-‡›L#”)ã]zb´˜j«­]ósKU±Ù’¯©«bS¾Á–ëÙÆTîɨ62Íìæ ƒ ´!…�gÈÑÀ‰¡Ÿg¼ñHi䈺N›ÛèhH²œ8Šhüôa{™ö—j~w“®ôíV‹§aL×&·jïl²/S­0ÓÞËmój˜ãªÔŒÓ¯5,Œn:ïΓŽO¡C2 舥´DO tÐ 6< ¡—³u¼{ᅦTF¦Cº8옫¨:²dªrß}rúý®Gï+ñê{˦²h·Õ¢¸”ØÙ,F»ò¼Å)cÊÛþä×2éå.Ëd�'Æ$È2(»àe”·™æÕ©00 h®Gšny¦ ‰»P,úÖ ðµÐ…/Ì”FÚu9˜dd9ÃáOîÕ9–*‡ñƒØèPÕ5ƒ½å;YAOçv•]ÅnUg1 }¨’Àý¸­LLSð@¶ •©XŠ‘Û‚¤u7XO›‘L(ú6½Ïø©º^,ä(GUtB}k õ¸Çï­ËGMk‰æà$|ÝІ“kXôÅ:Ðe'IüâÉzžV«  ®HUÙåžhºG~ÍkOÑíèã¶PHXô"•õÅ`F@Í‚eƒ ÓAÈTFƒ“‰™Aüäl&['<Ä…ÀþáÄùC±àc2•™LÜüP74 dp&RœênSÄ&éLÇÈ!­Çi½:ØYxrKµÊœœD‹ Ø �æ.s¹]šÚ¹:ŽÝežý± ½øÅ ¦nYXBe‰¼ r€e4žß ÒF^v"D(Œ…*xyÂr€—ËÄhF¿'9Ìõ$EåÐw¯HŠ*^î#]ImµœzIçÐyüþ¥?° LuAÑKÿƱ°×¥DaŠKÚ.ÆŸ§ÀS*¦ Ð`º2 ‰cN•‹?V fõ³eÓÒÓdü±åeAyà€Aƒ¡9V�qˆÅË8PÇĽì¢%\åJ›ò­Ä¥‘+$årÔþÑÌa~¥JÚæÞw’¶Üï‰Þì)½¦3°û¥w3DÎNy¥¿GBI¨g*`ØêSÙbA³ËÊ'œø"Ú†… ZÆè´&„'”U˜'ôl¯·ÖˆRHŽ{ëÛ\?âGÝö#G«+Ž2R×–Rš!]äJ…$$%)¥Uëæsfƒ%viI¤×úª€+I–<@·•­+ TÆ"È&Æt6–#Ë‹ƒÎ¸²®Nˆnm¨B†Ù„ÏÌQ…Y¨#f`æ[Žð–RZ‹…¬"Ë/¤»mÎ^G*ÒŠ´”¹ï¦ºÖ>È1’ôšI+®I/±@D)%]Â6¹N&2*êüd¯¾ä¥þî<Ed…›³æÆ~ŽÑxd”åc ‡Öƒ3è›ß>Ó„½ùM…ØZ0·Á p Ê•ûh5ãבÌñF¸™"Ø¿&4@^ê(?$KaÇêÀU<ÐQä¼] •ŰŠÄU+Æ6>gLÁ²qyÕ«Þ¸½Édí…S`ÐÓÏ Ê÷Aöµdˆùä,ø­s<!/ÓZ­j]Y\h…?¶áiºšØ¤˜rW=j‘.ã°t(Ž$ævôa6GØ&˜"X^*?ÇnE²èÜŸ¥vz“•rá×J±’@–=»wúÙç÷‚YM{‚®ÌŽÙ¤˜ÑO2}ñ1ÊJ·cªµoh-úäÍþ™¤v¡ÚÆï —yÕñ ’I9Yv½ËßÇ lŒúEkœðõRµ¦æLß|*+ɹÎìyµP¢³µ“êØZ‘de߃$°!iL@Í'=; ™²‚Let,í¶cX²L«{£ƒ¦µÚîjiæ­ôßtÒeà1\º˜Âpvþ­ê‘Jø6aÞ׎dúRn2×~úëiu• u4/%6UŠkìùywdRä®�ý±--‡± Ú‡•O´‘gx±|LVWnF ‘‘O‘pfj»œGD)'î;øøM´€Ÿšjzµa"„¾/ŸrûŠúƧk™>‡é•úœ[—+³0(üû‰x\Gõ-þ¾K®e~Ô rÅ©VsÛÈAF ƼéÚ#cL‘éãÍB´ä4§Ó*Q›o:ðãE(ÆÑ‚q4ÿïËw~ó[7À?¤úMÐ ;ÝÒÂTºL>et ×ÛñVw¾¥fíÜÙ‡PŸ ›yªÍ©I…>Ézz(ßþaÛÎØ3ù8h£‹ò*º€§ŽY;X1­‘iŒ|Ú‹”sŒ•±Œ»³@½Y7#>‰º£Ûz7zä ¡*`�*‡$‡+¸hè*(ÐM( Á¤A¤‚¨„PØAæ»>ì󈬺éøA:[À"˜gò$æ ®uñ—$T"Q Šõã<¢™þšÇó¡‡ëºïP§@¤ƒS8&Ñ™Ø3±›¦0*Œ ¾X*²ó¹™®hŒ*КÒ#y;ä‘ „z4uÛ›&ëÜÚ4 ¼à� ‚b&Ѐp ‚ (‚K *Ѐ$‚"8A9`hh‚C`€&€7˜�hÐ�U €A  ƒhŒ>ë‹& ¼5뀎¢,ñ(Âú 1Pá°NyB$!©ô±7öÁ·˜š ² Ã¹h*Ü—có¹©ñ ûI6ýq¤ÿቴᚢÆ#¢—ùØ.±á:^á‚�9¨š¢j‹ìÕ› p3 ª2™9©@¾(4ړ೨;þ²¨€\·ÀÃ$*"xÁ XÅ`pV°°ÈMˆƒYP:È*…¤Q4„7؃< D* ‡x_Ð� øƒMø‚OÔ�ȘÐ�ÈpÐÁ|ÅXŒÆž,%åÓ Àƒœxk°ÉA,a3.@m@¸¥ü”“Ú2ˆH’{3ósF©d—¨T޹…`8Êáœo""•Ž[¬3PFu²¾ê0Pé:ð¨©2Œ˜ª·) Àà û@“¿ˆ“°ð ­qÀ÷’—ãGûúü“¨´Â-T‚¤ƒ&p�„W`Å=hHCÐ�h*@DÄȯlh˜Aþ:(‡JÐ؃¤Drxƒ'HJÔ„?ØV ‡Ð$AMüÔÉJ°ÁJˆF⤃PxÅçqËÍ“¾#¼ç£ˆ0—âPF@K6Û©Á…S˜7£xŠ¡©‰»rÆðœ¦ã¡Çû+QY'ùNç ! ˘r‰$©)mü5,)³4‹c‹­È$±ì$Có »]I³aÃPÊ"ô¿Ä§¸™|/¼c€Ú»[+AüGD‚d�9°€C0„bP€>Ñ,9pƒ& ƒS`�:¨ÌhM MxrØQ"Ѐ&(‡=N M"P�…\Ř|… :€M"ðþ…7˜A¬„=`=øÍ‚S hËå‹FX‡J€R5Ó¤UÈpäJéó™¾’�·ÊH]+.«D.Rñ],šY áJ•"’ôй[Joº$TÛ?€‘¤Å’8ýÓö9Ç6sŽþ\ `Û’Vø¸Õ[=…¢ý4Œ)%¦‚@’A¥CËÕcɘ%ð=jQ7?”(lÙPÍÀ>p€>èd8å€CÅ^¥ÑCè„N8å,m!ØA ˜�7x…M¸I(%7ƒJXDЄOÁM(ÒMð…M`€M€Q`7€Í=P…&xC¸ÑôÒq8ÎåëÁ˜Q¤+MSrþxVMU ˜�VØ`�â4Ó|e€,ÓÍkXt‡lñ‡æá°L>°ä¹ÈXòôÓ.$‰?+Ô{á«3+¸Ä·Fu8ÇrK˜ú \Ï…‘¬363ÐN5À( “�, ±ð¬´‹@91L šŠ¼‘» ´¥X·Xå¥C˜UÍø@Ü®�8Å¥äºåk§¯D¾*€EX¤h@ƒMR7ðkp‚"@ƒ 8ÅM kxÔÉMp1XRqÕ„>�EH¯Ý)ªíRª=X{e€q`€C¨R`µIr ‡¬ÄM˜�kPIMtÄ~=„„QUØ)XD:�X* ƒ¬„Ñ ‡þp`VÒ¥‚?Є<XIJÔ�rè…ЀȃڅÒ̓Yà à‡ÜÕÉP˜Ð�†7ð…0†à‡Y`^æÍçýJNɺê£^ÉX:J^©³÷Q "K¦k¦À’§Óð˜|Pº‹õ-%�)Ÿõ˨Z´’C4Ý+žZº“ÍÀ*4â=Ì(7vó[œ¾*?·-'@‡f`t(~à`tH€" Vxƒ+0Áƒe�hØ)€ÑWT=:“×ÖANæËWÃR:xD³µI"Ð}ƒIÍF$hN0ŒA¦Q€½ÁÔ€/ˆVЀGÐ$žþ‚)¸r ]rðƒ#¸‚—4ƒÈb?(ƒ+ V€‡'~â °‡ � Ž`4N€;°‡a 7 ¸{°‡ °˜ô´MðQM€Ðd€hüJ°¤Úèu.1•¾çk'æKXÜ.³, HÞ¼í² SŸ¼ºˆãÒ;Š©Kck˜•¸Ÿs’c›Ô2<ª¯«¡ø³¢Í§÷Mk³'i§Ú»G=¬@Yº–kéß;š›Ã j²ã“�2ಈPø‡wP`�@g�gnà†fh~æ–à;pÈM¨çã‰2Ôd‰·”¾ Ñª}:dƒrÅCˆa(†r A!`�7þP�(‡rÐ àÑ×d�eMrÖ–Ö=I ¸‚U$ãÕ€M€rÈhxÑ܃;x`tx‚'x�ÎèŽfk®fgNà;¨;àŽà'à'p$?f…WhçÃõA¯¢ °ŒFîF¯*2ml5¨um‚<Ý™‚’Ô�zö`NÁ=˜]r°/ÈMV Æåã=؃$Õr؃Ý4A*˜ÉȃpÐ�¤¶çÔAæƒÆ˜’¼èX Ò&G:,Óû:W;MUßc»ÍÊ¬î¨ mË‚´#؆3z •QŒ|¤`¦9ÓŒYÅ>夫- Uˆƒ>¨'éþg–æh¾fѦfÓžæ'°†¸a*ZüA“ª}ädÖ^ÅNDY8Vª¥ƒpƒ}†Mr X*Xê¥fVÐá•ÖM¸h"ð"Ø·]�M0„MðH°†&èD°ftp‚ké6ïóŽf'x`o–``éxƒU,ê݃r(êCèfßE~¾Ã~>ä4SG‡ ¹AõØ‚r ‡Ö]É=è×WhAM n_ðƒ/P]Æý‚7xƒ/èç×íW ï…~Ö‚WðƒWøÙÍrp…+ÐrÐ#ŽA§Ýu3K}ˆaéêGVÁ8dÛÂZrºX_y:òxJþh# Õ Å6Ì•Sl乌3j™ÈôǼ[7âË­B,¥W¼Z¿ÊX…íÓo‘mgoò>ïÒv‚UˆCJÙˆ¾q¦QÎlçk=€ëC@·W¤Q*€Høá|m)x[D—pQP�C0„†_P�"€4x‚òFïOõÐVoñFã~à"@H*¨„õÈUXáÌŒüZ(-Ü¿ó܃âZ{íoAwWNÜ„ì×}Ži¸Lçîj7àð/+øƒ?ЀˆMøƒ¯Ö„+(nÆÁ&]A|rP� ð}.dxH€CÀÜ`�¡ä•î¤k•Â[þÁ5!¤¤ïÜ&$_O’¶44 Û’c@,B;ƒ?8Á“†¡È^‚YíÇÉÖд"È¿õAâh ꔈ,ˆN?sñv‚í5íOsPWim(†8`€ëíÉ’NÁ²‘aS щ-æSÐ pWbMˆ?Æ*h‚=ƒ³å6õ¤WzÒ.'øhg~‚#Èj ƒ×ÌóçE €õ<ßÁPøss†Å4õʯÌ×<VƒjCXW_(V´~×¢7×7èƒf…éþkxƒ‡M€„ÖÞhÐÑW˜t~®a*H7(ÁÓD9x…}–AC€UxíLEŽôp,ÍW©þâ@ºpl?ó÷¦˜Ù�*#Ÿ+‚5Qýÿ@lÃ�8‰/h‰»åáG‹jLxxíÿ%ÈéÓìà˜7§p°†ÑFóñFz”7oÐ^ú®xícž I ^´>t.“}žS�+e�C(‡>xú¥7ÿP`Ò&éÀê=HÐÌlck^mç‰ÅÆEHÎW\¾gô*ˆqã*jÂá`Múø¡i“*Áܬš`È4 ¬ô‘"ÚÃ=<Š@3D…Ц>VÜ4aHÄ!H ^6©pèH Ê9)Y¹rn m2Ä Jš4U–rAÚ*i•VK“rQŠôêÒ¬Uš:MþÓ´i+©\ÆqJv©T±U$D *-Ú¨kѲÝ&ABØm­BÙí‹7”»­ìf)l8 _ò,>œå ‡Ç!KŽ ™C¬Ëýùƒœ93䤢G“.mú4êÔªW³=.Í8¤¥«rá¶U–¼UÓdyçp�ÀÑ9ù�òäÇ—'WŽüxóæË—(f¨5ö¤¯§fïîZû¸MDžnþ<úôÏ—/ñdd •*Ñ‘Ýt´ì©Ubïo!P`V¡À6ŽÒq tHÐ ì!GKTø°IoøÒ4T $h¸!‡†Tà€nÄQAŒR"„;ÑÑ‚!tÒÄ‹t4â!þ;1#Fš”³9{@K Pme$Ta‰v•RMîvd“ZÉ%¥R\à•ÕX[]u›\aµ%Õ\R±ÕJ`nÝ–o †Û6|ýµfbz%–Å6ŒvÐ)wJ–gd…Y¦Ygš´fràw‰*º(vûí÷ÚiZ>•†XdƒÅpÂ焦çAçitŸz�zÈQ$£®½ÖB l%º[m^µš ôÁ\yêéºk§Åýö°ïi�Û~»}wš± U“(û_SãdÑ}T|ôJF ¨àbwµB [wå¶Ô]ÞXÅ‹Бź ¶ÀîA;6MI†É±8mVYµM“H2«Ÿþ~^i9%We©¥åYä’Ù%™£Ù^{¥uÛ[z™yÙY§a¸9vctNö¡”© YÊ„zP,œš*Í53êhvHqpB5¿­wÜÅ•w§EK‡œÑ¼>×)R@Êè8 &ÈA ²e÷4jüA [ïàª4غNG°%(@‡€£ešÕ¥=ÍdÀ¯íöt µ”°egl²S½†5~6Håœä*Z{e•T?iU\ee¥˜÷!5˜û ¹–cjÞe˜­´À%™¹áUqÄ·u[˜›„ÖXÉ#–çd$û¹YŸ©r*)cv?ªØ<<ñª9Ê*à‘&µ3§ëé!þœÏ¤PtóÍ#öÑÏéQŒ©ÆJ(tpPŸ¢.UuÕK¶rŸv½ñÐ)öñ«7p<È!ÂÓÛažZ²oãgÖX–¥4Ô-!5r–kÆR›Ê*V 4–ù(5)Êieq°‘À|¨@‡J° )_¡V¼T%«°ï>’;¡”°¹)1¥\¨Zåºö€®.ŒqÓ^rc±¿tl/mòac@;:å®d§ ™ejw'ÊwÀÛÝÌŠ'Å)j§ €É[k²P ëM<ÄÉÕÐ8õÅóp{ÇáÁ;š@³*¼kjûñNÛ¬ ‚y n¡ð¨ä§Ç£Ñï D�‡lþÆÆo1‹4JÖÀŒÄ”CBþŠAd ›Y-®_TÛâ˜â¯ªhò.ÌÚòä§<%.‰ÌO•°2•õA.a—;˜\¾‚90Á%+•Á2:4iìLdÒcóC_v%듟øT?Õî2ðÔfz3*R“xkiPÚR#:8�¹#q>µœ¤íqTH³†Àѽ›E]ôÎú¸>¸µ-)±p@5†VÎ}ê8NèD¬Ô½q6¤‰Ui¢"„&…A;¢Bšp:lÇr  YÈbÁÚ…“ ¥Ü’æÆ:Â(•˜Öä`YJ¹,)J§„RVäV,[Ò”,RÑÄr˸ÔÑKi¹™*榻ô%þ7B´“a@æ:=Én‰•A柠‰;àU³ª4#;“·¤\«ø¦¯¦çœMù*üëЀò%êiá«'U:šÚ¬/sVKiTBav˜õ¬z'qˆª„p_aáO„ÚfkPˆÔ”ñQPJoI[ÁÒÀË]Å„Gê×Ñ• ÄÆ_x…%*ÛÆIÓ2¥µœ“àÁ¢þt+bú\X0g4“– /¨¦&coyÈpÃeÞN2L½ÝËœx(™]&V½.ÔzHÁiðÁÒ¦W½èiÊW>ó+z–¬lÀ•5lüÛèPE˜rG4aá‚#¸° ½´M*þs¬B°àôî38˹ƒæÚŠ]lƒÁƒÑ‹ÆÞ©`/Õf¿û]Ø6é „Á%¨@›\ÀL[ÈÖ6‘V뺲0ŠVž •×R2©‚RÊ-WØBc,%·´¬¥OS‡&Œ¥E0‹ðÇL˜ßf©±‹ ŸŽ8ñ)ñ1ªxÙ¡ È+s�»^*:H R(†¡'Þæ Ç8}=«—œÄ¡|$`{Ñ•¹6pñ4Ræ8R½â@5¤`Ûør÷­ëE“T½`U°°äÒP èˆh+Á\ʬd’Ô5Ø‘^É*.¦ÅxýðæâêRȉš³bþ¡5èRXǸHJ,ºE]—ó%¢ ù.|ù¡1Y'2Ö%õ¹ÌŒ*ž4“'º¬wÒäŒð¾¬mÖü-5YPE ªQCǼÉùMœÁ¨Ç2ž[ÎÀ™eÅÿÄ&yQÑØŤÕ¶-uÊ Ø]è#ç ï8E%û@(1HÅ2µå~ódaþ6é5 ’¬§;ÈÚYŸÚÆ#T%ˆ ©”¿%(…±Udß`×Κ¼”Œ£¥M]K úz·h¹mT`–] UNƒ0^ÚÔÀ˜ì¨C„22—(åñ-÷2Òuúîµí©›&b†Ê­†öÅ/²ÙŸŽÑΛœ'Ä!ÛÝ_ BQµÒþO)†eþ ‘fáh s\¨[¡ 4üëüD)ÔØg *…U•…‚rÿü'¯B¼a)¹ð„F¡àÏ)´8VF)³2>¨ [5ŽP0€XR$wà’Èùfþ´4Ւ´ò„ñçL‹Xè¬l¹t|ùeÆ“ìÃ$ñÙH<&Ÿ¤ <Ð<‘êÎW[ÔÒÞѬ‚ÜkÚõÃûfì‘ózéFÐ0ý¬%èÓüߢQŠ`´CöPÁ0Øàg.Ö°ßÿ€T@ßø©ÛIäÁ#<‚xA9¼H€Ï½¿À’Åuu›Èu–¬l”ÇZ&eÔ|–DQTJ%EãHë±\ëþe’â€ÅRü+5 NnÝêÙ]Œ· F·Æ’ Óo•Ç0íL†”-SM• tF3IÝó9_«ÜEiÓý! º•ÕôlÊöí‘ÐÓ8™dSkHË´¬šÞ´ÔA-Ið �¢!ØÀ‰]E'Ô@yåŸJÇT€|ù lTBô‚3< hA ,�2QË- ‰íÙå„BãÁ•U ¿Ñª}G¨m´ìˆxšÞˆ’Ee³XjI*œGy”V4Œ\x V̰ ™¸pÉ’YÌ/ñbàFë´N0õàð=›2QTM™TJgtF>Ÿè «œHþ¦øÓ–UqT¡_I»G5Àѧa‘òÈU0$�8®C¬Ã:P�”†ˆ€6Èa¡¡ƒ5€C^–Ã+,€0Â(,€ b%„hPˆí³äÍŠyÚ剡¬í†Ë†L ¿<Ö~„”ü×kÑÓ­ÍX ^ŽÁ¢Éí”\ôØííÒmÝÖ•ØÒ˜�ÆèÅ_ø… #:F/ÝaЕ‘Œø4]T=]ðtÙ1R]løGú˜F+àÑtLcY…SV5X%°Cß9AÐlßÖµzÇ8 äå±À PÐ0À÷p@Ð&¸Á¬¥0†±TÀ;<;Ú*øÃWˆþá@PÄ€ Á(ÀÀ@%ä@8”C"C¸ÚÖ@±�ˆ‚Ü•BŠœhÞ9"KÀ$ËÜìÄDaȹT¬ŽkÕ˜äPIlÁ’+ÙÜÍdkM -Ù’êœÉ[” bUð Q› RßS a´ÙŽ ,—q¥¶¥ ΘF,t„“x±°Ð¨¸øÂ¼Â+ø‚5ðÀp”€{(@…(�p§y0‡¨p‘‚„!Rid‹ M½e^”B LÀEF»°‹B0€³€I,€¼Ï\Ú ¨‚ÁÕ8P\€+ \@ä„Â#ü€øH6Eâ]ÎJ«Üx˜&±Oˆþ‘†­èH˜iÀJÃ$E(‚álP‹™VY€`}9Žã¸˜©bH O•fjžÅ]¸àkp¡Ž‘¹ŽlÞàbˆLÒ1SÇeÓTA4qN�iÄ‘qð�èÁt¤°<�<¼Â@ü+ø‚Áø‚…ˆ+°‚¼XÃô•Ø•:TÃu`GÝ,Ȫ䙬q€8€*„4¸D‚¨ ÈIˆ]€Vã%4A(Ì‚é-P·1@?”À´@*(Á\ÁßôÂ5¼ÂÊœŠVX2ˆ*$Ä´´BÕX Ã;$ ÁuBXr$�å¾i”!Ù Bþ%xÜÉ("=N¥šˆñ˜,ÉÒúìÖ·< çÜœkšäëäÆˆËe †›Ól–ë’âfü`ҭ̵)UUé¶½QG•ƘyUƒ6ð€›©[r¸Ç\�¸Â¬+˜iú$–AøA Ä€<À›‘™ \©§v ¤Ì(²dÁ<XžDØÀ&@Ä!øÃ)H@ôjžfÊ¥þ:Ô�.üC0̽PA?$€ŒÃ#¬ÃØ�YHÀ´Áƒ }ØB>–ºÌQ·}EÏ XÃpSˆ—?´�ÈÁ*TC¼ETxlìˆ&b¤¥ÞŒº˜"vg¥WÄFæpþÅŰ ‰íRj~ ¸’/Í"Sëäàë8Û³éÉø¬kNá¡\F1¥¼~½É ipÀ (õð@5Ty¨UNÁ¸‚8\+,é–Á+8¬ê^ƒôC?Ä�0Œ›§Ty8A1 VŽ7ÊÕ\yRäÀ?d¤ú^pÀ&Ü5¾,Ø@Ç\‚/ Ã,4ÐhhÀ �+¤AŒc0üÍ+€ìäÖŠ6”º$È‹¶aÛ„‚*ä©5ÄB1À¡XºÜÁ ‡ãn‡â¸TÝ0�}”Cxb+Q\¥Öž¥’æi’YNlŒ&]üXåèÖŨÉÎÉ"-î¢K†œˆŒ›þ̉ºÝÉ<iî(.¶Ïp>®Uµ`´—¼O¹Ç{|išÕî{XC ˜A\8ì€8 Áh|8|+8ì5\ƒà�Àħžb_iƒài´�(½èj´À&Á„ƒW´Â)¤¬h8‹øêò2oØ@wN�d&Ex‚�@ äÀ¬Ã1°‚$<¬ƒh¬¥`<^Љþ’"¦Á6ÄÂr8�(';(€Pìr Vi¡’FÉÆù¶ ÀÍž•ÐG…hˆÂÒKL­MYpXdŽùTèΗ˜$ÆðbǨIÝ’)™M6•áò&)_ã¢0va~ªØgþ¯N¡RR¥pш՘(ì5ˆî|ÁûðèŽn\Ã6ÀÃÁ”�‰Õx:2Pqi”‚H j,E(ø@;„A@ ^Õlj#ë¯[ö�À%˜^i¼1 À=ˆÀ¬Ã\ÀXÁ €h€|YŸ’§)Ž˜"Ù \q¸G Ü9Cˆe–~ÔJÂ!h*Pªyl(‹ª– …&æž+Ls«ÅD…ç| `üÐ0QR•k-ãæ’c3-®´!0cW%ȉFr–‡yMU.çr Ç<À˜7ó‚ïÀññè’@ q?,þq Xôlí²ØÉv¬èN€Új,Å,´C;ø€@(Rä�?ЃôÁæî3 Í%(Tä@%0Àì Á+Á|µ°$� „„OKéoÜ Èù¦‰ä¾ÖnHÀ)œx=Áž~ŠÔèeZ I4\d­ ¤’€&g!ð޹m” PláÔÜÒ”.]ŒÞò´ÞW nðÐ…L¹öbáþ n:SÃ+pÊS§0¹¨‹ôMxs’º]O{tõÀ8ûÁ‹Ãû°ô‚ Áç÷ÀÀ[Ã÷hç§Íö¡îÊ&Dyšiφ±ä@\À5\ lÐIþl.؃ Ü9û+cMØ€ÃåÀ,° L� áÄ�vTv4 P�  §€üW=­X«œÚrÎ¾ÐÆ.€@TVêt^Á xqôî¦Ôj1 ƒäHAh*”W C®­(‚d"½mç™\–¼…±Pä¬+£‰šð´ Qñt0_“æò2mwû&´¥ 1 ‡w0kVØŠF3×͸aßÑ”À€.@p³+°YŸ5= Á¤u~Ó÷ç‚�ø¬¥ì‚tFÇ*BkH�(e“z>PR¨¬ (Ä ˜A#\Bpç·£9ó9ñ€‰g84òþ*°À¬%(À,4@Àô”�8 @‚HÁ,ÜÇ²Šø(!9S‹È‚J�‹5ÌÀ ÜAœ;°‚`”‰å”§•ƒ`VÁÜUò.Gn9®²iîèjªÅJ¢àO‘NŜΤýEÏÑKÞàa÷ì̹N–1nÔ9.ŸHi‡‰~ízˆ‘R¦:L<lú¦3Á5ð‚èZs¤ñXó¥»Â5|Â5äB.$±BOÁ§OáõˆÊqh8œ¨ÈÄ‹DÚØÇåHÁ$€`€„�Šã¸åºZÑKÐXý€ÃcÈ(°€%@@G?C'À°ƒ%8ŒóÓ; XþÁ*HÁ…2KÔ˜ôDy(Jžh0À*pŠXù£ ¬‚Lqžb~(D²"C Z%~Þ¬ááq§èj’²® ’ä¤Å踢 Î å\„mO ]š¬‰axp.Êù}¦+o†0:uÅ_áOc8}Ÿt z?Àè>7¿�}Ó·5Ÿµ€°8ðÂ63¦ç<$ô\ŸWXÍpyTC‚õulæÕ‰Z@Cx‚3ô €cHO5‚Ýžº‡x)Œ3ùÿp<ˆ,@‚X³sg LÁ­—�XÂ{<@$(;'<XH©’¦Ê†iÒŒ“@§“t$4\˜þ† GŽ!¦9ä�+P�àĉ2ˆ_:ä²Ê¡&å É¡²æË­Z5œ ³ÊL† ;:|hôaQ? úqfС ƒV‘ªµUÆ­OµV ¶U ­¶IP›¶,ÚV¡$d1›6 Ûºjår8ÅAn_¿yùfáXpß½ƒÓAì/dcÇ!G–<™reËÕJh±$‡l�Jtš¥“$GV šÇ3c|øÀ„ɧ2âÄ}ù2„·–!¾‡|áUæñ\Ÿ®Àp䃪Uƒ^½R¥9“:ÅÀ&ƒq>C><ÊðÔ<Y Yé£`z{÷ïá¯.-ËÐèž”P &Fþ‘#G¬yà‰é¢‹/>tJ@ÆXªh¡jH*!¦˜bB+˜»@ tYçHè¢ :ꨱqÆaࢸZ€ê(.`„ê;‘D‡…NÊ£�K$H£Ÿ\‡):9¤…&Dh!¡–$ª¨Æ êi¼'¬‡²âÂJ¡®Ä «­¸8Ë«³´: (¡Äì*  Ì” ”²¶yÓÍ·ÎLk›,àŠ“®¿þ"¬°Á ë 1¾8Pe B;l°ËmÔÑG+G0øR¢ ViO5Ѥ{)Üé'—Ùj»†q\‡‚ãM·Ý¾§ â»æš1úÁá‚)òKºÐÞƒ„È@Jƒ:*þA±AbCE šh€_ ¬¶ºéxІ‡’ÞãÁkîxCŒ~à1ã"x(ÁÚuACG © L›B‰ Ü¡pŠ"˜]P� 9Å.1¼"¥#K_ô(¦Z¨F%JN‘ €è´éq¦ì®š’*ᮉ±2ªÄ²¢IâÇxŠ ¨«´ê£.5úª!ÁêL­Z䢕½ *#¶¸¢s´ÎbëÍ<æÓ/BQÂüYlP²îšHÁ[lÊÔ¤cª4Zx‡Û•j—$ø*á#ú1 &l¡¸SsÛ­Õ!X•ሻæ“\rÁ¡Ÿ .ÈoíÕŸnþ,Ë¢ :œ•ÊÆZ¨$ øÉ•0ܦ„çØ=°]ü€m?`€' Âðà 3b¸¤ˆS‡»mt´¥ ÆÙdŒIÖI`ùç™/¢X„_N#”&qØašL”¬‚ÕÈÆXÚq£5«ÊCà‰¨£Âšž~œD ç&{vÊÿª¼”•q´¬LI#à™Š6':EMo¡ íä&ºÜÉ/4L^¬&Di00ƒñ㵬„%|”QÂ3£4Ä‚ú}"wŸ)Äà ¹°Õ5zð\”!U¹G«b«°Á…«ra�À£BáÖh"§#õXF"Èþij¹¥„Da`ž–×¼ôNu!ˆ€÷;¹!b` \ÁÌŠbPÀÞFF÷”ä ìhB4ÐŽ}�c^Ö°0®c UPa÷|2ŽPBš!ž µ8ˆ@�,`2L4Œ ÕSJ”´ÂN\®EKR™S r¦)i2f SŠÍlÆ%œ=E*YŠÎX1\1à\BÁ=Á¥.r±Ÿâ"µ,ìE0Š! ¡¬ÉA¾œB1þP×¾fBqŽ32&úŠBÒ‚XŒ@*1c ã&·7ÄÀ ~È…®†2œÊo¼q•8®À†X‘à†¶Bb”¨«)8±=QTÉþH%ú„MðÎÃ6Éð< mÿØí€!†(u÷1c žðÿ¼Á§séÚÈŠkÀ‘¨"+ÊÀ _ì.õ”§ž † „APÂ:ê{�#‘ÐS Bb%ˆÄhIÖÃZ€2ˆ‰Å‚ˆ,° YtÂD§€K(¡°¤4%d¡àÀEVÔ”ŒÒäl››eþ˜ÔUÿ‘E#�àV¬t¦^åM\i–º24vE˜‰¦âT–¸ Å/•K4¥)5BQóOzŒbNÁ€¬ j/ª` 9Q›Ú:"ª(Æã¸Õº†¢t ¸À%àñxÐsV_`ƒ?µ@Tøæ Ð ªþô6‚™Á�cX¢;xÕ6ýÔ O dhB¤J m,é^ÌÂC‡XL€ír§U‚Rð€WO˜Û’ÀŠ/¼â oP@îà‡2\¿exiÊŠ0Ô1 I×»è ‘Ïk^|!p¼ŒÐÃCÂÓ¤P@dÃi€Vö²Ð¢¨P#(›Þ)N#Çœ" ¨@Lª –£´�«ÉÞ†—2¿°d¸X2ÑñÄ8ò£«´Ì*^ò’WøŠäœ…É‹ÝJÑ´É2-‚É4K2ÝäL+_Vš~ ©æÁ­3k^Uí™O81 k[0°¦ƒöÚöÌé—m/á‡8W Zè=ˆþ «"Ϊ ÈQbBݱ+éžwîl‚D³Ãc˜30ƒ1x8 kt ½ãÁ¬ Û! ~`Å4ñœx¿®pÅ=hB—vµ{Ãø¥®Ô½YBHmÞ:JðˆüãMMäò³†„¢» G (yÅѤ~)ó®dó£©ÒO#[ZiÜ¢¬•~gK S¸­?ýQû)C¹ /á-!µ ˜�¬vbBo£I¥hl²“œì$Ìmü{àq1xœ2ÛA¹€› 's¢cÚE¡™â%dmDÞq‡Áy5§{‚Hû¥¯Oè×Gpµð‡^¬œäØȪY çIÄÁpÀþÄ…ú>pLÊxB‡aÔÚvO ¡‡÷äq×<ð+ î?”zûÍ ® ›Wœz¿ºqÅ\±›+ ' aÈÅrÑ1˜ë f—ëN7! iÀDY ;ÂH!1ü•ÉÂE@ˆQIB+J‰ ©Qoÿ¸JϦB¾¦üù¤®’çR.«z3‡°Ýa¡Ù’)×Å2¹±[Ù÷›ØÄÀ³¬éNvì›öÔ̹X°Ë‚ªš\NQÍ1?¼â½›•Z‘(ý‰ãxzó÷)ü§¾¶{< ß“ÿÆÏè…߀ãêT19À½óµñ\%}˜LC¸s,â™9ÃÛæˆúšþ·Q+u%°‚ þ ý·ú ÁñMÖ¿`�`íUb%ë‚Cl§°öAëëÒ…Œ` &ä paX`¤x(`–ö@ ¦ ó") ü!ĈnJ„ÆÉ`$±|„ –¦TŒ#VægîG)ÀHa»ªj­xâlÆ-ÝdB¯`°¯„°ót)Kx†LŒÉôÒD°ë»²H 3õBa.0ëM.P®éË´‰´¬i´Å÷Ȱ2¾‹ÙF, À¡FŠÓ€å d¡*$ü��ƒ¡¿HÀ Ê%U~#apÆÀxáâáÚÁ�ÈÜk+ÍZªÁÌPhˆYˆ®ÇbBa þ‚b¡X æ…:í î@ ÌàˆÖH€~k¸tcÈÈá ú,å¬öà ÐHBò£B€¡9RŠü¬e½f`”$³@&à&�«„ñôŠ!ÌBI¬^¤( hÌd`Ðëbà¶Á) H ip¢BHš€ 0b~bŒ!*§ ¯>""¸M÷ªKhÉŒ‰ H±èdLRoL†°¢ii,ë.’Ë2 ÷njòâ0Ž/¬Éƒ$® 1’2À- C¡Íâ r-4ž@níFÍ Ä��Ùà H€Ø@rATÂ@zR`†ƒxáì±ÂÂè^‡WÆèíNk£þL„Æ.ç"‚<€$Ò¢ä@ ä€|Ð ?@êÚ!Р€ l€4@ÊAzAÆ’ òàsXáŽ<n½x Òå4Pê4: �žÀŠ¡@¢{Z�ˆ ˜å¢EÎIÏ-aPh³(–fiDA+³õìÄÜ^BàñÊ«nIó6ÏÚ”MÙ6•>Ï‘:o¯°‚Lˆ -POõËôK˜�.±²²ÐþËÌÂö2( &21CQ<kk%#‘³Yª)Ba¨ ¼b˼B²]Jà|¡?–/´Ó (@ ÄÀüàÄ€8ôÐ \A„@´à lÅþúê+ Ž€W,„WÀíÖ&À1¾« Ž¥ .G®äg‘"&À! ¢`j€¤Ø¥àÖveBâNB–/ Ð2 |@ÔCgá Žà–ÏÞÀ&€ˆ€Ð @’o(õÈ &纀ì%2»ºä2¤AÐIªŠa¨Ä#bÄÝ^ÄÉÜ‚£Bd&í”æ±)êj¢8Š@4}úG˜¬ôJ ,Ìä€BÉò+ÆäK ’-šõîÄ-b/‚Ò7§P‚P¾pâ’3#M¤ ²@, «6aÁ¤3:ïCnìa>a*·Lr_VêéžÎ .À�®à¡A ^¡p'  þAÜÀ ìã\ê 8ŽüV!"ØO’$� zB®ÚO~¤ ,`Zª¥.€Óè9â.ŽÀ4`Â!4tò@Xóàd@ à¡ü�ë¾àlÀö€ú@@ÌHBC@Ûd,$ºç;¢ä6 “~x¦œHÔ ÞÔ­ *{„àXŒ2d¢®~]·ÈuIHAo_¹¤5PLG¯˜ºbi˜ (*S _¯,�Î qsM1¦&k¸i8cN-mbÁD@¨à "Q¶ÜAæ¦P%Aâd!¡ÂýÀ�èé A=ðvü@ R€ zSE Êòत‹þ€@“¾CU×Ïò.IC¢”Œ\J xà XEÝÀ vª*Ä H@ò€4àþ€Céá  °ô©[R7®ÀÄï.Ñ üa[¿•U¯Ä©±aÆ“x¬™Ò(Ù*oÃc; g A°èf<]4¡dÜ~ä–à­rëÇgHo¯²¢+¤€¢ßKÊ‚‰L¥â¦ ˘†² r m8kᶆ8 åbÉP£ÊBèrÀtí§>ÒŒö¥9œãdOª¨ "Üà Ê@Õb  †�®¡e™£ž¼òÔÜ–^ÄàDhÛ£M2Üd)%£h¥ "Šá.Ýéd§ÀþÔ¾`þ ÕRô ¤®ž¾2åÄöèäèycÒnt’nμ’ÖŽ�T¹7>ú`q¯Äf¦q~´­�£íÑ[gäœ8¢\×ínwÉKâzpBÊAIúJòbéq—–x°(xF—øÑݺ¤*~¦(ô±ö­L–¦°(õ^s, 7ãBOÔäiˆáV—O@8Á¬"E1:«kŒŽv+®|«€^ˆÓ6Å…ÐþãÀ?Dêtâ ˆ@èà^\Á�®axÁ p äü�×ü@ à!}! ÚávbÀBP*rž–>f@ T¤F E€óƒÙQ¾CЗ:‹à "`®þ`ëö«%sávÌàyË€Uòw’¯€8òxÓ. 0T.ÀLÍâ¶*ß! ÒµNë18±#ÊBP¶b75»çc.ï”6X,²)×±¨ »^—}Ì„)w—ïñ…Gø”Š,†ìÞz©Ú@H?·ß¤P ×ä Ž-n¹/h¯ö 0lokÄŠ}¯—£* |Ñ6ÎmžàÀ3 ô¯Ž(€_€á jë  A>]!ÄATxáÜÁàÞà ’àaö@¤€qxSªwðccÁÁú`’²¢*ÀŠ8@1TD˜­a&íÙTzFÎ} b X!Ê v¤NŸŠc”p‡|HVˆ# þÌ B…\d@CG2äºsw"‘ŒVAf‰[wÐ2*X+†ý úcLÄ—‚eFˆIˆÐ•í݈‰¯¾ÂÞ:"#º”ßFOLÌd‡Ý‚‡#+(ðÄNZà†¥&öúäËŽjÚt÷Â‰Ï ’4q¸×ͪ äwYÅá¦Âà 졘ãÌ€p‡4€ Ю÷P î‹ Y ¦ nîóŠà€á¨£7ATkå I 4áÊ!9|@ÈáYD@.çaè�OUAúà‘ÏÈ%k®A“W^ãûp 8íymGw‹\€BîS_‚qþ³çs©{§Àá\=Âo!“€¦‚õ¶Qد–¯ è"Elâ”ÆVæ35‘Jæ'd´úP‰…‰ìÞLS+¶dg|fKÛ$(Æß’FUS·®o8²®œ×ôœ½°Ó¹8 c/»â8‘'BTóó¼ð#T6{7fºv²2+Í ª›R­ Ì€>Á”]á¡D‰�6¼„$äa.ëƒé|G,Ü�DÂaÜ€ 2ÔË©`&`Ær,‰ ˆÀ¢T *�Nô¹¡û® aîE ¦`W쥞°\n'¡ _ à ( ¾J`¶Eµ%Ï¥Z«RXþ„Ù&s6C’$ ‚Q:«åX*Áa:½Ó¯Ó%3Ur@èÖœ | ·YýÔ‘EÓåQ³ªæa6ƒÖ™ x¶d¦m„§D<¤d™É­K&w¿ýç+4×Kª"#\Ù7—­K+æâŤ2Â,Ë5Õ„öbO/ ’j‚S÷4Èšöb"OÅÁ‹þÓÊH:PJ úa“Ë æœ+í,t�XÁvÂà Õ¶ „`L­¾vg%j¤î@„RÉ×+?‹a@ A„ ÂXÌ© ã£•Ì7a¨à|AÖqcE€ Á´Á=þnJàæìtL§:׎þÈúܘËM³ÛhëbÞ€ƒw¢Í¥}Iáb!¨` a|àW3S Ô23Ëaö€C·ÞúÔR:^*ù€ È’ Œ·q–àxY¡Êî_Á Ä€ÐR4á RÒúβ`l5€Ì5ÁË“ô&â§@c*²BJä”\ØÞZfÈØúKX˜¯ÔºÈêG*Zd°V²¶”™œ¥ ˆÒË8ó‚‰ÑùšÄŒàûÜQ+‹| J XP*T À<‘ xÜ òWàá~‹³éÉTâàÁò@ ¾û\@@CnXÔ€@”n]ŠÁèÀ ᪎Åþ^A2“ÂAc©` Aðtc›@äÀ¶Å¥Kà ò© A� 'höPxÓÏwJÌ\ËåÇ… îÌñEb”'%С{S¢D‚)ðÞ鈀ʕ,[º|bƒ&D|½Ù£ •^¯’ÁI%97¾È‰ÂàQ/hT„Py”‡ «$GˆèµiÀƒIz9%ÇêȽ4”ûòf «/ZÈ ‰ñ$ÆräÊ„QæËr{þQ©Té&hMªTI“¦ —q†WiÅñáÄ’¹žl8³fí8oî¬øq ­:w–ÙtæÅ–3ýºjÏ£—¾-{[¨þÜ­¶IÈ’û·îmÀwÿ΂œòåÌ—+OžE9‡SÒ£s˜N'ºuþT!þ>¼øñäË›?½eÊi* ÒeË”=>!‰#†™2WÄé½ÂJeP†+lháŠý˜‘Ë'ñ|J¤BÏA¬„áÇ%E°PÄ@¡À<AŸNÈ'MHË!tüJªtÂA(tÐÑàT  Ü(‡†ô¨Ê!MÈ '¢Èä|%¼ñŠ= $:%ðàD ¾\á‹= ¹ãf„qýLTR?~°ÖSˆtÄ”#qÉÅ×$“NTã@TìáÆLQ¡{„UŽšh²Éþ+¾$ZŽ&„îQNhRé�IˆñÊRšâ+ä CN/{øñ“{ü¡‰E±— _ôâ¬ó)4{‘®šü± 8vˆ\v˜e­96ÙwÉ"›Xk¡yÖ™´ qh¢©fZiµ°Øf¶Ù†›a–y{Ú¶¡Öj¾GZ(º1/qÍ1WvËIpÝuÐeác¿þ^ç‡×lz /ÌpÃiD†Xd˜ÅQMž+Õç‘÷ÁÓO 1,P [äh±I/唥 +f(ÑF) ðÉ'Hx =ט!+$°É¦~PðóÖXó„ž(ÊáOã ¶4Ä\<ýÝÓ=ü pÐþBëÒ¡JR,i1ŠöùÆñp%Ü÷�QÆÐ<îàO;†aÆë\�„! ~x =Sþª5#â6Kö9 Â!ÿÔ´ ÿeà ø 4›l2 "ˆ@Nå¸A"|±I9D$Á 4†–#ÂI챉®T@ÃÊ›¨*Â&a½¡É{8�"‚!Ìk¢@1ªÓÎ@(¡´@M4Ax¯ç{­Ö³æžï˜´Ûn«jåŠv.n¥-vZi-Üv¿lú—Æ.ÿ­ì¶ûIà]»É‚¼ /äØë^Y°×sšÓ¯YG`£ Ã.ˆÁ š'4ß ÀÖþ$úÔgmSÀ�<p`�3,ÀCÐ [4ðº,à C.âqx䢸€ Ä ?˜g~Hp ™áéHãT‰&bàI˜Ó¾³´*,- - K@ظµùá I@Féýh£Üàk`Ží€ÇDdÀ±1 ¨ ×(ƒ#a+`|"�žÀCøƒR ±½&ÂHjÂLŠä�9€ãV£Ã! UD’ ”CpQB" Rˆ…*T)¼£Ш€À± Hô¡†¨€DP È¡ pžú ‰H‡@e˜ÇÊ<Fb—Ùø¤õ0þÇ0Kb”9Ì8â'la+œãBW¹f£­Ú´â5ŒáL·²•-ãÆ6òò_oþÇ®z†¢û\`™Cé<P;}Î@©‚U°_á¡¢ Qñ@›ã@Ç$Œu„„JÀÀ ÐG6ˆcâ` ¾ Ž+$ÈŽðX@äÀc ¡ÇÊ@#Ä o€Ûá`T £MêC¼WEÊ@L3ìI*xŠaH—X‰1°ÓÚxe† ‡¹0€ƒüÀÃ$)ÞÜ1Š,h?×àExq Á™Á‚,‚ŠÕ•8�#e!‡NÂE§ ¦!\”¿éÙ!M ¦Pþ,!ˆE¿N1Ù t¢`“í„4[ÊV�€„,8Љ T  €D9 a`­P¦$#Y HæaàsLgœ­iÏ|ÞbWfbS­ü‰S1ù\Mþȵ¾V<W4ÔºÍ�ó×>Ý”fÚ-MÓ z-ð9¼×@ êçPÐ`þØ"7# ßø–§Õ ªTáS'd¬4«Cx1„TX ¦Ç\a€‰Àg®xÅ�‡ƒ™^€ „à„¾€!6…!úÙ¨äÄ'’B Y”L´Yž‰¶‚jD^Çß7\@1`ÅPÊ>v5¬`5@â6¸BˆmŒÛD”pB°ºþcA~œ’ƒÅ½X%NèÓ  &2ßlš{¿IÅ�·<MCÌŠKæ‡ci7:…–³,,Ó¡6ëM & XhFYÃ݆³L\f•‹[ØnM“µ¬ÙÓ0ý[4ûìg?l½Flt>µÜ›øF6ÇñÍw¸Of¡ Ì×6ªSP ´_"Ø¢|_ Q‡~§QÐoá“1Ž„Ä 4­ˆÊ -p")àG*ØÀ‹®*A pÀÁú(Ž•òX �0*è¡-´PÜ&ï� [Ò hV³~[Eq]&2Kå‚–•1e• ã Tk 2Ä™Al\P ýÀBnãmþÁ¿.ƒÀG4 ñ×a¢”ãí„r3l1ã‘õ‰aÝÔ?'&Îq΂‰ùÜM­5µ|ê~'ŸebŨ¦œüÍþ¶üÜÛØ¦Ñœöôÿ¤‹xg8ÈÑ»d“XíîKÔ ŒàzW-°/D ãLŸøÒ)cQûŠmÞúÕØ. &Y;¨€ë ™P | 7äE¶µÀ„Ù¹^1 ¸(ßd|Â4f¢Æ9GjCvâÇ<lňé â½¶•Dä‚Ú1 ô4«8èAv —kÄà þ=Rð»üºª>ó™èÀLÙ «ðÎÅU¾ˆ‡ðÐbV6“•Í+f“ðþOînŧÛ4ü¶1[dLb®…ÍÄlCÌëžVÈ[Cq Š&F¤Áºã>÷Õ¯åÜRôÿ€C.-gá1úÜÆmº[ß^ü[λŠþ@ús‚Ü„«_ßôü£§ 6àAãèC"!4R€ã #5^w a� • À €A=°y`‚e0Úöà ’Dý 0"N`oÀ Œ#u*Gµ[“5¸'fæ3ƒ±—_oVr¬ dxc›bc{ l°87ýð {AU|Sô )ÐB6@zw>EfP°‚.QH.¸MLEEÒÂn¼EµnÚÔ|þ”±rã“&&\«1ÄW>|f.ÝDx‡+'K3T@àð q — 09ð†àNÖ7O§-Ý¢NœfOÖµ?÷ô–f@ü3D'^¢†jÒPêÔq_púçŠõ{4 %`HTç1Kæ èVpe�¹pCSýЀfpZBZà3ð`�aåþ‘mC0WÀG×0A5Op ¬° w zð‘Q,HeE/Hrâs’]˜'VòH rW „Ð`œ`3uÔ8pŒ½Pu!Df`�$pmô�CšàBW@nåm—À…ñþ�Êà,ÜÄA7rçÓ[ëè|\Ù‘TC†wø†v-L…,Ã7‡Ó#›ÑãÐ`¾PFh%U‚ ¶6o £Ów³v.¤A”ð$?¸¡}èT”ñ’~ý¤eï"ò/•6/á%ŠÌ‘ø¢/¨Aëõ cöŠa‰EßÁ�3àŽ-a"Vb%O�î0fÐ}´€‘ @—]õm¼@œ@Äp36Ôo l¨°Cà #Pñ°vë 6O �$ E€'…ÄÚ€I•’Ýôgn¸ŽŽ1y%o@n7 õ¸ŒR))ÀŒÿ¸ ¯ÀšÉøW DÎlŸ— {þñ*u7¾e†THÊà‘/(>!§œL•œëØ‘t|Âe>æó={–’è#.̲|ìF>oˆ,³  ÿ°hðÕ kƒžèYz° }€r "0g!§‰.‡”2×?îÃhË•HÉŸÔ@¹@7¢ViW‰tF— à 1‹bùŠ÷Àp–“%ú•1¹Ø7Ó L�ŒL0ƒ™ dç¡° 9”CŸ0+:0.ó l` $µ ˜ xð&Y%>`  �N@ æ¶œ‰,ljj˜þ‡xSà â $à zQ*A‘áÀ�)`B¤Fe€½À ψAC@þy ðmR~„7é£òáÙ°béø™²÷,瓎•A¤âƒ‘Ñ’N¡}zŠ,…¨ÁU-rh~F5,f{i 9° ¾p fƒž¸Fœùu3 >#’±±i›hO¨‘}3—ŸôÔ6'•ß•XáU[þ¢]¡öO¢j>’^þ2Aþ°«P³Ð ¡eHE³ðúDw‡1¼Ö7pÉ¡º¢`C¹p ŸàS=u V8ÐF¿Œ× £È‚cp<©�6¦¤a³WÁÇ™}ꑞ™’`™ÿ7o(¥Rª½áÀ¯)@®€7kel@ÆÜÚ­ñÀ ܦ¬Ù °þ¦_À lbw@œ,a |Mj¤4HƒÐÙœz¤ÌÇ‘p8›9²*‡xÈ’äÓA 'P N¤zô!Žac³¸f%—>Ðwœñ”ö‰fÜ]Où]Ý¥i77@ë²|�AîW«æ0¢–ÖÑ«—Õ/W@Ý#¬š0U° ïq³ê*Bè°W}Óiû¹P¢, Œ7d Ö78'VcÀLàRoe nUŸ`À�b  Ub@‹8k¶Û¨ ²îzY@‘�°6ö ¢BBüZ ®‰l¿ÈC!ú ¼ Ɇm ­ÏV&õBeÑ vI4F™'`t"ÚÐ�´÷,}þú‚%ù™¹›œ#wMÞ¹‘# ’$ûqâ¢>éw{ËR>¡ ¤P1bs1c;½òž<€ "€»!î„\ú³-ù³ië"?˜V/¥ ûtW¹ Uû´Zi^³^×a›€]ûjeè,½>j¶´ˆ1$±|Ä×ðc!ú¶ °DøBy  ðº»(¦pùd9Ä pµ€ýða"ñ�Q!f1f V}Zh‰,Úà…Od%5ÆtQMÁ�hú_@ 4pº&ª (­ÀØ&®lày­« 9¦Dd4eìpF€§$¼qHM½¥†ŽªTnṙœ…ºœêȼÍ7>ñS¤ þà�óJ‘"$oõqqð³™Q”ÞRN—ȽÀa~ì2@æÇ½7gNÃщâ—^Ç1PÌjYIP¸Ú/ªj×1f`®†¿úçP9@ x§ÈZO°¡{$ V“BÕÊÀ)Ð ¶€ úQY€n•C=Ðë0€:%cq #Ü™íZ{%ì{ip+F%°ƒaÀB¥R»©-”cÁYz¿v!~ðcl¦‰Rùšm¡ç3o´ü£ì€²4Sì®Wüˆ˜1²Í©Ž(lÂ_ü®' >ðJ¨‹ú®†Á¡à�«�ÂQÕ…ñÁÏ?ÚRÀ�𱯑¨×gNØ×£J¾�”þŸÿãŽõ~=Ç@žFtùr^F'¿ ðÀwÜtŠaqÁÏ!,¹x’m—®�`s`rcB`²dyC‚m²˜› (Ô€IÐÃ:Ôào’��7ö »Ô{_è ExÚMÁ‹ŽDZ>±`Æ!\Öà3'¥  lÊm_P&}„D7ö›UhÃ:F­m¥'µ¦ÿŠ!ÙœzÄɲРÀq{è“>ó ìœ>ÏÇÅÐ…*ØjØÎð 1­’ç²|êȪà�ыԵÙLR¤0z¶]?vüNzÜŸ¶Ñ]ÆQ@TÙª�^¢È§˜^ÐaÑëU0©@¹9àÑbihþŽÄ™³Vâb}�$7KÖhU&¹À¨€Ü¨0ºŸP­]õQ)„ÀÈFå*E@U5‘f;ÙÓkËJ¥»wš²Ê‚Y0ÕSE`zÔØ )°ÞUÈ$µ€Â, lñØf`B  {Y l¡të3I0•¬Äþ°beXÎÉ‘Ã5¤¦§„m²ïlÎ蜧êF¨y-¨©¡[—QbUP} o‘›W)ñð’ÑÉr¥ŠOƒ†¾¤ZO­@Kã¥Ýþ´OÊ0Èá¾µ Ylp¬ ¸³Ít“>�ÀÕ+½6ÛÏO๠Z@©p3eôà7vCÔ&Úþ3ÓlmàQÒŠ°§kC!jG‚¬ b�Ž,ŒÝœTÔ»IMàÑ 9ˆw�4a ZðyZP&»¸˜q ®%E°þAC0Gp…Àlyzñt+dtÛ3áÌ(œ¼™unnjxçÈ{΂íâÍAÉkሺ|Í»4"@ 'ÒÏܹNP › Ûšñªî†y¬â÷ t²1ÐêçÐÂj|Œ ¬­•º:AÉ!0e0bÀµD_G*ÿ0´⌓�ð�宀 „ ‡„ ʄ¯9RØxÁ}d…ÀH&uÙFݾ 6P¾@‹²¾Ý,±ÔٔŇœŽª¿²ðþ£/†lzè¶ùcmU7„¢¡°ñÀxóQƒ¹€ÌM ¿–R�»‹A”‹s¸(r"X ádð»ìÝñ¼¸w’|Ú,OÌ™KU¼,¶¶·g:æ§4Ø} nŽ#âp�Õ@ ö›5nŒ”,ǽR)] ]æw~ÖÕsž¦e€Üî»ìH§öãð ¡@í°öˆª0'ÿ☳*Qq4 RÎèfp8rAyP 2é‡\Ôá 5\ö庻]:€DaHv§Í6q qJ`8ðΧ7¤‘Á  #ŽÉ¥Ç  ÃGügîp�…¹ (�©þ¯úð0Ñ(dQªRt{ *s3° fì ÀyÈwþ^PMM¹Ë¸¿ Õ-„Í×^¼É]›Ñêæ¦ fâóñïGÔ5 š¡?O£}ùÃÙ ˆ¾Ü5Oúó‰AW«µÎNŠ^O ºPÖQöWp¿iA'V Ú�%� $XÐàA�è –pg¦Œ«T©v”¹æ.A‚ ý®DRi\šq!A†l‘#Å6ðÜõc3„œ¸OƘǃǪ;èxXQÀ :'>TX!ÍÑ4UŽrQª©R.G›&š†©U©G—@bÇnhÁ  K¼ñãç+â\ù s-Œ¸xcÜ)QÒ°Ÿ3þnÙˆ#Á‹â…uû•w…–!W(–õ“¤È"D ªÌŸT.L«læœÔsSР¯:JÚéçÑTEw.½ùjÔ«ª“–ž½¹U•Û·«h®’¥óQhÿZÜøñ„Ñ G“#T‹Þ­ZI¨²M‚éÓ¥[ÏÞ*”ô*²lû.|«,泬ÿN~ý{øñãs¿ž~ùýÑçŸ?™ ö�) 4ð@TpA‘ª* pJ¹‚ˆë© .0ƒ•2R¡GVz€ç‚Œ6ôã -Ê¡ã: ZhŽpòȃH0£26éå/®i3.x¢„áxxG›°ˆúj¸l ¤4¬<þÓ,+Ò2#P‚S”Iò«°žˆÁ ³®q…+®)Ã3ÌÀ °uà)㨇!è¨Dˆÿã%Pp§Œ+Ä‚ž!@ìÁ¬²Žx…x¸° ¶i¶¦¢ªô³Ù0e©ÔZËôÉO-•m7PK m3Ì8Ó3.лí£PX…%)´õV„´q ‹4r›Ž êÀË­é¾û.»ï²È.=IÕ EÒé¬Ûæ½iã»>:죃¿ùôãÖ?ÿö”ã#'4÷\tÓÅå§ZqM®Â)Ì£ zRqåLx”X§¡xÂ`ã?æd€ *Ðd/¾°± ü aˆ?zà™Ì8b9¢Ø!eËGþRH ¡Üí)Ϩ,³ØG–jC§„'ŽÈ‹-@Å)ƒŠp¸�…)²!…pèhÅ*Xƒ2úÑÍ!¾ ±2ËZàš$Ž`e‚ &Ë5 Ø(5UÔX£JÓ”ÅFUJMiÓÔª©ØM³UQå 7ºgC¯©‘‚‡ :Æ•8w‹sâUBQ»î°C¼»ì°ÃM<ìBñíYÉ­‹|= žÍ\¼ôä»ï¾õ²Íö[ÿð×??.pà´t[w}Á Œ=& |Éu¬.cˆ!p#—~è Ÿ\®‰çá/†Ð‚G?ìé'ø>áI‹-z¹ÂÌÈÅŒ;NÒoƒÐq€äµE6«þ‘)e½+ŽsŠ7޹Œ0ü�´iÞÙègŠ Üƒ„?,• 5À#6°Â ýÐ8þ …|ˆ×À^YÌ0…#ÜÁDÚZ+žB*L• *¥áÔ“ÎFª‘¹æd!! U#7KÁ°6–Š¡°æÆïl£)t˜À*¸ÛQ9щ2ÒcÅM§<:dQn’¹mœ'qçI–x¬³i½‡sð¡z@güpÑ?§0Ý)bp‡=ëukd£‚b—†8pðozQ0âV¸.׸F. Ð ŒpÃÂ@‚~µe €¤K`.†1iA’¯˜Ú5.¾v …8Êp¡ØjóÉf%5þ‡6Žc…8l‚GÀ£+ÎòIöB’×�LFÞ1PÀ $ G fÔwÈ�2P‰ü�KM<í^<‹$´œ …%(Nà�[õÂ)•ªS$;§¤d6QPœµ™Û g3šrjn¼)VRšà�mXHˆóÜ** ŠðàFRÏÒŽwZÁšÇŸJü'v˜…,N =ã‘|ÔF0‚®tö!]üs„Èumä¨ëôÆ4Ì�cô _ Šà ûM¹($ð�‰ƒ~€ $hÇ á 8¸cMJ€‡Ã`Ù‹/ŒÀLbˆÁü&Íîràæ§>37OÊÍ›Gi‚)£ C0`2þCKÊðÓ§ ¡ I� H4…ðï N»Â.²Ž´¶) ûB/†àŠ00L¬( ‘ 9v`ç©êÜT9Q¶±f…O-ߺºñÆ5S¹dɉ›ÊVÇpih Ðð ’T´©†:ñÍÐaЍ%¨t̃¸(â¦<”ƒœ´BÁ¹ÚÂÇ=ž[OLQ‹J”ûɈ�5vT¹­‚ü:Z ãðpÈJ ð&\ã¹=ø‘6°t ‹pàÕ/Po™ˆ²ÇŽM:ö,T7c8û:…7Hé„)8t<`6Ãäµ�Åì€)x ïz€‚‹$ ˜éþÇÓD¢‹ðïöK˜òîJA –å -Ž2b!»r~ê†ùmá ókºyj²/!©xS¯J78\yÒ Š>ä“Ð%ivU…qØæq˜VâÊZr'е2÷ž‚rñ=Üê-E…{:¬b³'› H—ÛÑ”Áæ(-Å êHä—= ƒá£vµË W¸"P°Øx“Ú{Už3TºÀ7LaÈÙ Ò€Dª¬™t7OU…Íž- ¡C£•Í�ã"öxÈLíŠhá â`CÌ ¯²Ú£gq‹8…uð/M$Ð3ï ÕÇCùA ¾¸Ø¢28^u¦„“u’þqÌ©´Ñ<’Ý/«RÎ'½-²—j•m$Õ”P.x»ˆ|n‚° ÉÂ4ãèfÃ(·'‰ÿláÞSï‡*k:˜«yªÑÒ<ŒÞ²„â3'Ü@}JTá(t¥<˜BOë,Ôð"-®HÀ´€ 6¼€ÚÍ…^³·;-جf(Âmìä c‘faÛôû›ßÓ*“"Mâ©Ô—-ç bÈóôÜ  fäð@Á:.�ê.òy*)æJ6äU^4í�écY|ñ†É(ÄÓŒ–ùefÈl¹ó°PqÛAIé¹evÆd»48QÕmÚF7ÿ¼MRZáUˆÁ ¶‹8‘þ«±+Õ§XÚ!–t¯hQîˆ�}–¾“e-W™ßZ¾Ï6òãåŠò‡uiWxé³B¾40`…—ø 3³Ä£Î^J¾ðz C0/^ÀG3œ<wmKìAq˜=¾«øHr]8¶AUvKqû6N$O÷DèD”bªW¨<“àÖN÷ ìÃë_ ‡¼j¿B áL`¡ry £.§ÑS7Øv£›ËÊ›¬ÌÀ1ès¥ð;ðH;ûzªmË;"¬Ó§^Ñ¡Î7îy3z‚9!r‚PßËaœ~r­fA+ª­cqº¢Ûb¨Ò-†b»AãþýèÓ[.Mc‚U ±s[ Á ê*ƒíÂ3ºRž§Y5µXŒ\¶)L“æ™Z´iRª¨†, —$kÚ¹Š’£¨€X’O+_˜—=sIê‘÷;‹ú!ž\8†vÈ…~Á£›Vµªh +£r=à �ŸjÈsÀ(é¶Ócª +ù¨ÝÈÄÿ£ü"3h™ÌB'k“>rŠÜ P9È œ'œ'ˆƒuÓœÛèœ`9(„j}z­ÌƒœÎ±_¬ùø·ñ j ½Ïü¨¹JüÁ6½7‣ º¨8?ànÄ3^‡ÚKþX5¯*¡ª33¡ƒa#äÁQHp�Èœp‡H26Û£ †3³é³ŠCF ƒètØ0‡1 ="Gœ9H¯?Çó0?ó*3a…WØÈ±49D4ªÐv�Š’Ì• €±Ðx J±¬°ý·AÁ, d1Ã2¬súŒ¸™@Ûà±ì¨‚ ‚F ­ÀѾ¤b='X…(à€cÙŒf‰–%jÁÌ¡7hAi±­Ì‰"~"Fb4Æ-ó²%`ÆÓA=š„FŽÚ(Ö)ÊW-PKÂ~ØFWxH¯Z«„1º@콤 ^¸‚¶PwÐBÂ3å‹/Ÿ°z¤ƒ&þ=x"U`€ ØpÌJ7-² 5b¸^9…öÙì ‹—1 (µ/˜K£S ³(6èûr°å!”½¸—2X�Ý\€²8“tÇ�-Ÿpå[@=ÏüÁä|¾l¡Ç’ Ѐ7ïÀ:€î)wy™'à'x�î´‰'OâŒ8=èƒøîÀ ^Œœí×*(׺œ­ŒAhIbËúø"ÒSð4p©/´T®Ñ+Žb=˜‘H+xDc5-Ð�*èrX ¼0�>òFš�Œ°Fä(ÌìÓ`�( 0Ø P½Ç|Q¡ £9þ: 80*¨¡)š­Î …w(LŸt˜‚x´`ƒ¹¤ˆy©K(< Iª—ÝûF6ð‹>À³°µ x€-L’j`s3RP…qp¡ 7ÃI2’(šXS6«„9Sq‘‰=¥¹ùˆ©H2ûj>›èÈ/ì»RˆEMÚΰ†7H”ò1p_ðP�îÄ>ƒ¢Up�Ã"ÌZœbÏóHUyƒëH–†Šó¸¼Û­¸Ï30sF]ÐÖiɆŸc½cÛÎmÐx!ˆzèêí*ƒxàÆxh‡À¼Õ¤9" +€‚&þ0„;0„&PoU…&‚ÈðQ5š…7x…©*ØVp" PU€í;âlTPãªr1ûÉ3µà¸Sû‚@¹ß¹O¸†uŒË\h„ ˜‚ðÔ?ýs‚bèƒ` +ƒÈìVM ‡%@-Ø„?Ð�¸‚W  ˜…<`Ù=° Ð˜ ø Ð� h‚)˜uW¢ÌMÚÈT…¥%Z:…e€e³6•œÈJÈU¤Æ1êt�WtÔO O9“Ÿ²ƒ¼‚=X["ÀT+pG±-ˆ‚XÈØÄ©ñŽñPA̹ €Í™½å[Ä¢þ­d€û"0š�Íé^M—ä<›ˆ÷ŠÛ£\Ä!iP¹â…äQž<`Ö¢ŸhíÆkX׃[8# tèƒ&ÀÑ‚1„b¨€‚9„U ˆ]Zs%:(*€W"`�¥‚M`_Ø*h €GiÄÿÒ�­åàê¢Æp º¼Vƒ(ÅÈ2à…yq‹ª°à™´2ª„(7Ÿ@HhÔ‚m€†ß¥C€hHZp€ÈØ•r ‡åÞá]rð<`€p РZ€†EqÞ‚YÛ=žÕQ) ‚MhÞàM0ZUxÚÛb€Þ}Ž$£ÑÀQþÚX¨¦VÑ7e€wp¯ì²}€ 8‚~H‚Þ4µ=�"�V°ëT£tm@˜aPÅ99_,­L\Å™„U-2Æ+r\Ø2Ê2"#/;ãã4K´™\t!½¶Q…"VåOדõ ”TH²MqàÆk V´J€'°X˜{#"�¨9˜Ó¡ƒC8„SX¾õ‡Cà€kÉ‚J>*ÀÑWæÕà&ØHXÞÅp°�OF.­-)9û Œôƒ\È‹\Àº¶0“úÙå~°‡}(?ÐÂ-·žN Rx³jІb�U×áu€`�jþæ€ `Ð�uU×xhÞq•‚=xL‚iQMxðÊÔ� ‚L`hÐ�7èƒ (‡¦‚r ؃& ‡1"x…&(P6¡å-šÈÚ&@†=�‡2ÎŒÈSŠPp�WŽ[tèáðáéҚѳ»tÙ23ˆ"°Øç "@�Ãß:U}:ÁXm–(Ê¡ÎÑ<õðâÝê·ÊÜ*ËJ.³UÒK�%\,8®D_]êÔÃÜwÑ\\ Îð,Ö´Ò?“äá6`Tˆ€–°{p«}‚ hiª¦ "²N ..àǸ¶ êø¿¸¾Ž PÌ M^Eƒ†þ)ðÖæõ!t`‡ñ¬–Á8‚†˜J“(•½kH _6¨šx�´â`Ïgzá4=І“<6v€Hƒ&øV –"€†Ål‚C€H MðÖ&ÐèÚ6lCCèY¡¥ÌW(YÀFe7€„u€&pƒ$€„݆Þƒ" mn5˜W€~m:(‡ý˜Ø%o­�Ú�7pmÕ ÍH<˜3¥åHd.‚§Ë^>”=;5œ¡ •Æ(1}G\q‚Xè ®EA%*\äÛ,hA©ôŽù¼é,~-fiÌ5fÜàZFúpƪ覦.—f3Kp@P;V Iä}þ«Œp˜11ž¯f… ÈLõ½Ða8뉅ëƒs>ë –ëø<ü¨�Yp€lh ä>è c °"€ì§³‡/¹l¬K XÒ‚Üûƒ¤iéçêÂÑ$aß„ NH°îrxmCÈgH¨�P6„WèVM`€&Àíé¦PþÖ7·óÅßÇÄÝ•ƒ|vƒU.‡>P�7àÑâF"ØÖ˜sV8Uhx}í„.hÚ6„á.FwôëØ¹û´ØÀ¿™´&¨£.>òCp4º¾¤·  7Hk×ÃÎÀ9±¾…¢ëø6Ã5\eñbTE¨‚’2ÄÕé¾õ0Ú"cþÔO\YÎïAÒ“ _¨†µÎN$ Oõ=䬦®09‹‡•SÅ íq GKˆb€qð ,™|Éè³ #G•q Y(†€PhÁ)!†,: ˜—´~Ùï""øP¹¿ú/:*m8Ü¥ä×.‡N0y:Ù×–Ú½]¥äJ~òmèJÎÑMì½dÙVhÊÌße�(šC(‘ÚM—ƒrxQܽm×®är /€d°Q®ñIÀ…–[íT_9w€‡ Ë…(“îÇ{i‹4éÈöl ¢”lœÆ–O §7¾ã·þ©Ü^L–fÙiÇí–2ƱDj‹ #gd3ãö3S›µ‘м_së…DN+õU‚ϯ wÀƒjµÖ50?€l`¸Ösë:Hƒ"g³Hk›æ[ 5{ŠIH¹^ŠSè„N¨� „ÅÞ?c´xøpNà„°¶qŸjê/åxbâ>„æãÇ~¯ýæ«ëQ£¨p¾¡YSÈ‚9¥9rŽ8åÓH“�h0„‘�;Ý÷Éù¡Óõˆƒ?„„¶m€ð—…K«P«äp³ª€†Blˆ“'<.`„ÏL?3f®]+sE›‘_®°qUæšG{ðŽLIPbbÄš6þ•q©R¥U–V·I°³UÐ*@[m+øSBÁ,²@Ý5‹T @ŸFý9u+ש§²|åÀ¡k±bӤɉ6M´m×›v®ÜºvﺅÛ6ç[·¡.Ñ´)x0áOf¢+‘àI‚˜S”<¸0eÊ%ë¦\ž¬ù‚V=Ž–€0éÁèZk2®,­Ùêl+öÚ*\¸°ÅMwNŸky§}*á”'6Ññ8âŠÕµÏŽP`劯\—L ñ´i‰Æ:é#‡ApcãêÖ øî¹·yK3ΩÓºq#wÜÛk[ôáVXáF'ñ­ÅŸ|-TŸƒòéTI •RŽþ?ÔŠzÿÜñDiÛ¡óÄ”i¤‘G=øQ†ŠâŒtÅe¸òÊ‹aô`ðØ£bFô[>õäQI1eUF†âSCúÊ6Iõ$TVaÕ}da9ÖTZB%VYþp�f^³Ù¦W]ºá•&^e¾5Û}}¥aÐB<Ò)˜N V‚žmö˜Ÿ’ñÉçð¤hÆ’íX'èhÓÄ‘tŒŠ[êÉFimrá[BÞ·ÖS_Ñ¡ ;ÇMQ„J×$!ÙØóF.²AÁ:2ÑÄ]D¶ÒÙGä‹*ýÖæz¼½‡{iÝæ–•L!˜ šl­Õ ‚tôÁ;V°Ð‡jv¥“òqÁþ -´À@þlÃÅ6U0˜†!âJÚDŠ=qÁ%Æ`€(¦(Ò_ìàâ+®ÄX†Áã 2)êP°U$•B%¥R?ý •H=uOSm£e(TQ ²U]qÉå–e…y֘В m]pÒe¬ÌqÑ|©™7— Wyqh×°¢!Τ爚aFÙîÀƒÃIF¢*šÏ‡Å+ôv=!GãDÜWÌ0ß¼©†ÐrjÛPiÙö^+h`Åqõ²rÒrG`§'‘!–]w‚eíwH‘ƒXëÄ[l•^ª“O‰ßö6~mÑi H v+ƧÞÍþŒ^¨Ölm‹/Þ‚Oä^þ•OIUa3xMó–À0ƒâ/IøáÇ5 ¨x…+_ oü+¯”±€ôô �3EÐt><TÅH%Iä’DÕÓ‘D>ÉS÷PB•äÊTaIVÊeuiËfÁ¶—Ú<ãõìofêÌo)NXk¥5:MÄ ‰Ï"5¨1 1ˆÁK¬F™ô`%€ vjg»Ö®v«8„|r¿úÍ…¨SZlã‚ì¤-¡Ð‰X”Á‚¹=€°bÅ%ž~ph ¼]Ìö¼ )j[!ƒ4µBÅ. hÂwò£JiˆqÐ’Å 1:P Hb´ÃØÜF'ãˆÏSþL¨“h@!,ͼD4…á1àÍ <Vø‹`.ú‚+Œ7�ƒÕ¨ SØhÕ0'H!‹AáØÄ0Ö=«8©dKá˜Sž”ªp…)Nâ R¶$?-‰LfáÀ)¼tÄIÉÌs)”Ù±ìÒ?KñïfÊ \þñ�‚°N@\`î"3%P†iƒjZ ¶´$ô€ e`‚ܵZAäNß&D¬QÅ8™ÊÍêgN¥u*TO+èà€QÕ$w¾˜Á.Áƒ¾ù-˜áE�°Í‡ðÀ± Óæ~´ÎÅ™3fã¯Æ‚9'Æ)UÜI¦Z€'P¢r³ Âîp‰UðÙ@¢ã–þØ .¬f¡ CRÔ;Áü$ L&:mŒ½:SÈ/”„ È;ɶ’ƒiÄ%ª¢]œÀŽND…*;1U„$$«hˆ(™ÜP:9JáLI*| ÄÚ¾­”õ+`aY+ÍÒÖ²©eR³TÓ.Ý#³Î‘­lmÙÅÛ6%�æzúœ)âCÃ$ÀÈTBFnƒ½ä1XÀv\\À‘ù|È?‡Âj8`i)h¦dÉ6XÖïqºyÝ÷ÔÆÏq @•ˆ8Xš±&z(†*°èÆ,ê$IIB·RáøGA”ŠÝX÷¬>Xš`�9( S`"q؆Ùjþ›üìÄ •hMR²˜ƒMÁCtLÌlê™hfD‡„:„! Ï'y Y¼ôcPG¨v‚hv° <áREY¤«ðD8Ÿ”0&«òIÄÂKO:™S°B2®Œ%Ä(+ ÚJ?5‰ =*Ö\í’Â6Õ-üñÁ*càÛÖ* Ô« hw8Í�NcfæŠ<O´3ìwîˆ; ÍV§qB1A°ÑY õ\ ÙÂU«&‹ NJRNø×¾f!M~ÈiÚŒÍÛP¶‰fà�U¬kdeUbl¸šQ´ôcUÕ”|²†I¢tSe®T qÓ×q†Ç¬«ÓþÃemI×rÛ2Žv¢ TËæ¸ U@c¶2Ží3…;\�§”É£ý†$Dv#$øÂ"ð- È[I"5r¨ÉÔVQzX…‚áשbU«ÜËØ´Ç\¾O޹¨€C“ÒÕ³fÉ•ð ñ*9�UpÀÅeƒ¢\ZÜ3që=ŠVmB‘ƒ ð�΋ !EòT‚)áJp‡Â»!;Ö� ÀÄáŠàˆÑ¦z ‡Î9Ê3Vjè1!”XnÉPâH»i»VmgC¢ ÁmÆKÊɸ¾Áƒ«!ND«àöN rŠVì"C¯û2†¶± QHu…�ÓïW¦×þî¥XUØ;äƒ+\"z�ÞqƒXü¦¸jÜI BÁ�*‚•0<u0|qc– ½’ÁÈìa3´# a A;Ì wôCïBýÂþ@a/Ç#ýˆ=bp_2µ©–�G+ÔJ$§,…HHÙ¼Ç:߯‘-)þè„CÓÇ>p‹•㎟kX)Ï 8·^¡5N^β/ý³«Í^ ýµ @0kžÍ­qÇ Ô†<pwÀ�MÃA’P†`Ÿ�žSpqgÜ8³ý›Dx°‡0†¯r¥¥8[zÐFgqÑ´Rk* 9€ ðœcÐÄoü9`,ÐAþè†DÎæ<Ž#Xp9‘}Å%Z§­‹Q [l�hC0\B58`AHeC6$Û@]l„BÙÑŒÅN„ LYßD„¬ ŽPK¸˜ ÌtÄ«ü˯’ÁøŠxÄ<Ÿ¢88DUOXEy1IÄE'QaW •X˜¹q€ ¸•…TÛÊ”›X<„TƒIJ°¤QzÁŒ¦ÔÒØx¸¬Eø�7tÈíè[à´™ àžHôÂá� ™ô�Hx!9\`�÷áÊTC&ê�ÂÌmS †L�¬T°Z]h¯¬Ð …Ùi_H€þ*X™hmCÈ i€¢ñUžô“Ã?øÀ,ä�?ˆ€¼Åa:…Y˜¹–BQȆ£Å—y[º¸…ÜI¶‚%PlÀtB E‰]ìÄë°FÄŽ øCÜ{\«TÍä”L4Æî\Bn„¼J!¹BHÄ@Lˆ¼M@•ë••pTW}WqU•%II&aس™ —´†ê9[—8›ê¥!ÜŠ€ŠÝ^Ì ‰ï‘‰mÙþÄ…ÃÖÿÝ ¿eG à‰ap†G@Äá�à@ôMM¼öí�/HŸ%îS5°À*hC&‚àv(P.ÚD ¸,ÔÈ•þÙï%ÈU‚åÀZÊ*¢Qo˜‚*¤Zp€,\›Ñ$ù“EЄSYCDÀÐCØÀ·¸È¡‡Ô¹F3J€Èx[¡EDÁXl�t�-tA6,ÁÇ•Ù+¢Æ¤»ŒŒÚ„B0ÈTM‚HÜ=ÀÁÀ„%Î˼ŠK$ÕÔ€ŠÌGøA.˜ÁXFž¢ÄËøƒ@¸ÎÄI’¨&5É´yáT´Ñ…0§’aê­Þ*µU[ÁåD™ð,©ä8u6jÁE(Ø€5èAoÆ%aÍË$†ž G$b.ä‚Ó|€HÁì�9ì€J™õ¬Ú*ôÁ <%;þègÇTdõÁ|Ñ·¼GÛÜÕxåPA Ì ‹â à éDo¸Z`N Úª­ÂlÑ\zF«U `b¬ƒ àLÁ&tÎâp(êÈ›ÚX™S(×âpÊëÈÆ6H,̃,Ä‘Þ_¼bƒøê8É®»dU(8@ (ž†aÁ%x„XMcÐ ýÔä£Áø£`�ÁUF|©Ö(C,†IOx’2Å„) %•’µÌQdÁWIÉVˆÕûê)•…‰­ò�)@¦ÄÒ˜tYJæÕšD\TB0z¢hMºYNÆ¿ÁC?$b""0AHð~îÀþ”ô\€v8Á*ph&~"xÔ{ÖÉôô–âœàZÐ9 ƒ+R°ý䀺͓ `ý,š´&»¨B9ÜAœ(UvjElžL1(�(Á+4‘ÆÎ ÝhÛäÄ|0Húñ‡ÉD¥Á×°E –QCfƒáÄ+J™TD¹F(Œ×æÀ l\îSb\ÄùA;Àf$@ä[a/HFdl„­•AßY(NÅ„LM‚F„ŒÌéTðDW I”TXûx˜ÆˆUø svdÔ¬üx¤+AÊ¢‚ˆU@°Ô¡’ÓïõL®Û]Œƒ*ÌÂ:Îd§z*E$P{&À þÀÀ@Äeí5¸öÒ\Ã">€v C&j)d"äVC(;<;<íq Ã*‚|”ÞŽC%Ã�Ò5øÁ¯m44üH†PW —Z,ZpµÀB±hÖ8ÕþÙ$É‚ÔrÇw$€ � ë Èvv‡íZ²Earg A$˜…£ D@hŠ 0èAä@ƒHëæœQÐ4dÁã¦Á?Ô–µÙ�ÃäÂÁ,âãÍE¸AL9Þ¸ƒ>ò‚ÁXÍuP† ¼ã/,8Áo&ª—lEÇœLUðiÅê žž‡/ȬOÎêlÊÔiË´ÒÖÌÑ*¼áédʳþ”¥ÑNÊ©©B¨‚,ï·ÄÅ8ˆÀ\‚AíqH!NÄaèÔÒŒêÕ Ùô@.„„+ˆÃŒÀô�dùçò�Ô€&²x€à°ãûàl)œB»=n P°9Ãì@A%„‚&€Ã•ò‡¦Ñ\ðƒPAä~+Í"¯zÇõ“M<á £Ã:tnç¾:¥Ó©àâÄk|äðºÂÆë´¯jÉX0a箃.¬Ã:<†6ˆ4nV)‰*¸ E(¨�šFˆ`,Þ…„èKô °€°À(�2¡õú/„A˜‚ìN-0pòa2(ƒ$ªb›&uXU`UþTŒÒYqX–LEÏŠØü´L¹©›ÉÿšIDm¥±d²šQ0€?4A,0)*ð~üƒ ÜG°ÿN e(`môE_DÓðÂ|,@ô!"÷Al¢6X†_5<‚ÎÔ èv A–á ¹Œøm«L·€T@–Éæ,I .šnðÇ ª0õ_Æ=ó:Ç ‚P ¶-«¡Ctñ:|q8# ꈻ¬âë0TÀŽ#¤ (A?À ¬ƒ�°40œMÃPâP”TÎ!0À)¼«ª…¯ ·™aDÆÝ®Š`­/8²Xƒ5A$Aª`ÄG¼H€ÁþcL†b�Ãð¦åî“2èYiÉUl¡&E¤T�j&ÌÈœUé!ËÌ©ù¦Ò[—X˜¸ HÒ00@¤Ö éž^ŒL¯ˆ€HÁ8ÀýÁ�+ÔÍIP�÷éIø’l›µ°Ö3+†Ò�Ùp-ª~Bð‚8ˆÃ”pÓÀ »m5lâ÷YÌ9Á“QÄ.šíÖ4tvð@1Ø€bÆN8ÌB’+ 2+Â)¸_‘å¢5q쨂¬1w6±çœ6?(~rÛrˆ\€=$TÀ+º°B”g®Ô¸œ+q™Ð²+Z°Açºt{£€5,—aºPäÜFaVŽûG PÀþÉ‹aHóÂŒ”?†+�!ŽÀ*cõÃ5ø£ÄÆ”­ ßI+Š”)‘ÏÉ`ÒSd›é¥ûR…Ì®rGz$Ê4×G†d¹=-wXÃüƒX6Îʽ–Œe*øŠ§e4!lÂø„Ó£ž4vßÐí O¥�^.sOí¼ðÉc8MP@ª^à Œ@8MAä=¥Ô:i¯st߉µèˆ9ƒ ù%¸A0ƒhpB*ÐC;ÄÀ£~Ñ)®±ˆ16¥œ8@18t>¹Y™Ktk¿³O·®hC”À*4¶È<§ ™´†|ÿ %ZÐÃwqþßAì°E¼6)“ ÅjL 0@LÌí+ldt„„ €ÞypÞÕ¦GTÆÒàÝö-†CÙ"¹VÛ„ˆ t:$úF$kM؇aEW-g‰»ÏFºÆü¦ž@P'pjœ…ˆ6AºµÛ‹áÆåÄ‚@ƒø�§·F¨°ø XCñòwºD󜹙ŽÍËd»;`€5ƒH¬ê5øÎ0A<˜'ë ÁSê9“Ûbb&ú“÷­(˜×݃ÆcîM.P{þÛ„A8¬FˆÑBýÁÜuè®®âN£ÑF8À %lnA6šË°?Í:Õà;ú˜“‚ì!PP@þH¼ªÓ~ ðq ©.ëq“¨Ç8¤ÀOA©£À¨ïnP<®AÔG(hÀ˜¶cî�\G0o¡˜ÁôÃ<Ï1pÁ=xGÄDÜ¡ÜÔ …k,ÈÁÛ´òX}”lØË^‰XÁ/®ÞGNþ,§¸XÖ`à$ôÁìo³Èˆ>Øp€È!¼»±Ò!ˆ€!8�À¾/XÃài"Ÿ¡Ód¡ }vÊÞÛgÂk³+0Ácá€f³ÂÕ ;�¨ €’„gâjƒààTC ”¹¢{‡ˆµ<Á& 튬a0ø‡MSÁ,ðC<4‚üDÝÚ9‰· ×/þGAÅ(®@v Î� $èANtòäIH¬‚Ù° cFŒÿ|ä¨2. È4U²dñØ¢ÊÈPURriÕjÌm1WŠDµnÝœ(pNH9’eÐ*­‚†’€²…:G[lš’�]B…Ñ•àñà<3ü„¹f&—™1¹ú( ÏÝwî0àhg¦Ÿ»§è¸Qð$*º'<Nõ;õD1 i$”4\¸¤„m`†Z¼-T–VY;N\r›á’t4wö\’‡,¢9píj£OqhÍáÁ¾R j»S‡•U¾ÐìQÅ@(Ëq)[dñ!e“páòhñgÓ¦=6&¼Yþu/�Ú &”º{ø¿ÞóFuR¢j‚):§(1p­Ì5&¹®¹×#LÊðºré6RúXEHY¥¬@!=œp‚ªÑ£š,¬¦RH™ð �žpBk¬±¢>ØDR.©á «´)4¬qâ"l0äŠvÂ0à!Œ/T ¥…V¸pé%$CYi(–Ò £…ú¢j<ÚŠJ;íÌÒ¯-ňÁ„Jxâ'¦x"ÆT³ª½jð%˜rð¤qZ@)8–¸`i2Q²…±mÒ4Pà §uPp‡ƒA¬"¦=YZÒ¨BÉN¡£’`¦@Oª) ŠÊL¬þúëšTýÈ¥\5VàÁÁZû)+®uHà7((âÓ½²û’»j,á�RÄ23ì1Å S,‹Å(Ë ±h5‹lÙÎDí³ÐHãÖÛm9ˆ%\PÖšK¬p*mV‘"ˆ˜NhD°tÉJ.e€ ¨PEp£ ìéç{îH³¼ñ´DèAðˆ˜ÊïH5³Å]ŸÊ©øX5€¿ûôÃ>^^±n•N¨Ä µáA¾>|‚RШF›jÞ­ ,Xe•uŸÐc/ IáƒK�Ñ£fmÔCYN9¥P´)˜=T€CცpäȲ‡je¥m‚))�þˆIån¡¹ˆ!„üU ½Ê4s=†%îÛo †™N‘Æ®ŠP`Ò³ $%ç‚Ðq<ézk8¡!–Ÿ†Ú“¨ÐG›Uš ‚èÈÁ `J ¶ªŠÐ Ö1®ñêöküH¾2ü0ž[ xË%Wâxì9¢ˆèFïm…¢ŠÅq˜(“iZÇ Ë–ÙjK2ê3ϾݖÛòÉ'íüpQ í‚)Žpc4ÐÃJú`Am¸ã`äÕÃŰ40N€(ÆnÓ"65Ì;wëNyJ ·è]JZš›€1…"ø¢y<˜‚ÊÀ üà ep…bxôà p€†úЀ>þ8è!�`™j 'àì 5¸ÏÞaž‘"g€ØáC !hiÚ`‡X0E@8}ØDJ$�‰ŒimkŠR‚”“.ŒãH/‰\S’P8`X¤Š—°4&khñΕò70I<t9ÂÚSH]±©;,Áz.ð�?lB•X\J “&ééHŒ I l°5�ñˆ‡;pñ(È]r%KÊ\C:„ øwÚô�”e+¹Ø]HàŠ^Šã âøÂ qpÀ ~h<”`¼)´ï8‚=àÑH=Ê‘ Q˜”³(3-gQ+|žá^8ÅÅ-Ó€ 4á M:ÕÉ>Šþa{˜€5hÃJôá~Ö8)®‘óXexÃ@¦ýegpËR Iõaƒ´¡àÞÐ<VìÁÖpž5&ÀŠ$Àão`Å+Ü„$(À @´¡ X {q:&äÜðâ%¬1eÌ ¥5€´¤m  |ÀýØ�KXâAì€È*1(hÈ ÈÉ®¶:¯ ø€„r”‘ÊF¹‘¤!D€Dñv¨”@vGð…@Å Å­,ˆÉs‡7àJ8ò”� ¨$L(Bû¦r„ãN)™Éd™´§á,nP-ÈA?¸v(O˜BJ˜¡$ ”&¡þ1˜âL 2U  Ö/c’æ­ÆÐƒU]ƒ$† Ž!|a®0ÃZàa€0ü®ð@Á3¥Mw(Ï28Óëþ='¬‚%™± fª™Ìpoœá_8­e˜rnk} YÂiRƒx,ž>ØÃ%B•Å>Üó]<µF ª—¼ ÀUÉ‹§²ÿ:" b+DË;_ ©SP „ƒ TB8BQ Wf%iˆÅ úÀ‡{bñA,ˆB¤‡˜ùowâq ‡UÄiBB†øÀ‡£jã rˆ$°À2tˆnr@Š ¦¨‡=$ KÀUp€1DÁä‘¥YÌ�Kþ ~‚âÝÀï IðE‹ü Q¹YK}ë£ÅŽà‡ô@Vú‡ Ž€©œgðÈϬ\Q‰€¤’pÌ68°˜É¤-ô‚¢´V è`p”P\§ÆI�Ô-P¥rÀbt¨oá“ ‚wªßùÁ¼à…o‡Àqð¢ í•à³£jæoˆÁ¢9…âÉ¥E°};5™e5KZ—Ñžv¡E>ñ][3¢1 ú¬ÝNo­‡à�+{ ÞP*ì° ì· k¸KŸüDhƒLàYbé­Ù ÌâæGt‚虂*ú !¤.bUøÂÓ)P`—øÐPqeÄAèþP"Sd ‘9ˆÃÈÑm8ÌÀBÂ;¢…Ìà¹5î  ±hL¨fš¸Š“0PP70±„NÿD¬ãð/.qžTG¯*¯MH16±@HT€YШPV<`Ma† v*XW‰ª*Gx…8vð‚¸ öô:ˆºV®2Àzá‘‘x×z3ÙE+Pò`˜!cHÔ®|aˆCT ›‰–…â¸;¥¸òê¼Áð)+pÙŠRH6|ÁÖ®ˆÏ5Ðâ*ܲÁ—iyJ2a}„â)!ºŸJhô²AFkFZÍŠc"S´IË{Þo·®m:°×ÛÞºþ‚@5ÊW3ãïžìÖçu`&z×ûÞäyH5¬¢ýâ†Í}ú¿a7Ǩ³Â1ØÃ*9b3fòŒ—Tp1š_ f C&à²ÁøàŠ”PD,À¤@À!VÁix@ÞAb.p ¢@æ¢àÐ`‚aÞÀü˦î@àÊà Ì`avE Ìà T!%vº` æ¡DAPeqÆ!Üà’m÷ÂC/Dˆ�ä€TÁÂT‡†£*a9RG4á 誮žÎ;*ˆ)*.À\á�˜AÔá�~àΠâH;ž Ž ändŽ©\AV"$'(\b‚þÂÖAH ´v…ö òÒ Hë”´Ìïd\Iu²€Þ!ŠLÈDy ` ɶTˆ xÁ—¼¢ |t§ ÄA ¾€à=€|g+‚Gö¨kÁŠ%Ê ø¦»šÅq0£›c2²­|̫ͫ4ÂåFÜBã5Öç Þ€&nt†hjÀ öË ®d¡ÊßÚªÌðí!ˆæCðí0‘ý&æ­ÐÄ@ àP‡•ø¤¬¸Œ’Ðj€.a(`EÐCC²!,ÀͰ(Bô�R. â§¿~ˆ PþÁÞÁ"ã ¤�ú�(~î€~JàæÔd `åÒd‘þ1$€ DÁºÀÖà¶%4kØ t* ‚/Þ†¦  aPÇ•è Ã`ILâ•r f!¦0D€ LŠB…*à*˜`Lá ÕaÔ0 †ÐsΤz` �à�0À Âà †r8LëlÄÊÞdDÀ4€HˬÔèl.I(P" T3ª@Ôè`Pmý¦BaåT¸" J×&³uË)™Ê€ý Ø.€NÏwÌbÏ.�‘°I*ô 'Z²&$ 2Ð&{#Ú.Ã6Kb]ÃÚÌg4ÎÉ[FãÛ~“2½Ê¿ÀÄÌði@ØDHD ßÐÑþó*†¡®üRM×Q<òb Ü ¢XAÂ!óðd$\¢lÎ ­â éVáåHaè‡gâ@ÀÍÐ °À(¤¥Ð�h`&f´!|�¤ DP°â ªAhjÀ \Œ¿xàÉÞÀéÉà 6ŒÄì@ì` ba&fáÈúax¢ €æø&<œàvÃF6átJCu<,S\iN–#ò  5à Xá Þ C¼¤!.qpÄd bà˜à¢ÔœÁ¼ ÚºÐA°Âü`óc-×r ˜à ÈAè@m€âH„" ²@* 8ãÌjPÌjI&/(q("þƒÄÍ•’RôFÝñbàTrÁý  â¡ ,S…H a¥6Óú¡Øà3Ù ×ÚáVÜÁ°`TŽœ ÙZa{cøt±0´§3ª¥øºi²Í5Ði¶%7IãÊÔéÌ%4ü <ª¡Ýú@HáÝ,ðeBå Ãd:ÁpÀ"ˆY¹$;µ³ÀÜO/||2% ŽM?ÂIÅÞá†ú� RŽˆªøà°��`Q„Äp†ªá‰&f0Dþ"(l€ ôl¦Að†ô@CøkLŠ€à =@¥î¯�æaŒ r@6’«™Å}lX²ó ¬l„Èáþ4 S.Œ ó u8ãÂ@eÿ%¨€ö€^B¯é ¾Q!J y à>àFà�\`J Ò¯î ¤Ì Z-Ö@)\a�ö€ r`¬:íR~â%îþ€BOÕ4(Š# ¡ üÔ(ÞèH«KzÈÄ’éiwx§wr«_Mô �- š0U45¹Ü ž•XÀO‚ï›:ã» E» ­E4Z4²@rÅå[´…4Ö«Àmp¨h`Ê¥ZŠDlƒ¨Ì/.‘*øÆóÔOg¡U;Ëã *ªÞÀ–¤Ô˜$O΢ X N� T ��©,€ôÀDª¤ ÞaþBcæ<Z,Cø“&€|²¡ 4¯¤ åNà AáÀ7?‡¦E.! ÀN;xà¥N¹  ÞóÉ é™˜K-ú! ŽÀu¨±Kü ýà ìÁ®€  €´ 9CGUË„ ©@4àdÞà(t–h©âÐ�p pà~€`Àv ÚT€á\è@ç˜é“|$Pá b�žÑ(H2ØÔ%îÏH†Â’‚ã‡)m ƒ~c‰ÄX í®Pae+xMw®>,R½‚Hà+ú!žë¹´‚|)>ÄbÏtpÅC›€xZLÕ0À§q³çY$ƒœŽq7'w|ÂþEsSãÛ¤Ä] ¤Ì/DRÄ P̣͡!š˜<œUÙÊu#ŠT.¡ /á “)‰Iôp$8€ °@ ´ÁøàhŒ×ÀÐ@Þ!â,Ä<@#O`D0�@@¥à¤@` °€¢€y+ €h4äŽÀ¦ñºD $B‚ˆà.�TyÖ¡~`-žk=êÊ:Ûö€%C×£I‹TèáG1¥` UG4 Èá ÌôXáB§`À¾®Ž@?ÚÒ�F�Fa``æÎui.²ÊØ0r¡ ’àžàþ!áƒÑM&¸€ÑvA/&d‚&þ'&0c&�32Œ‚32%áÒ ³1%Hû¡•×¼,vÇ Röxá ²Ø¶$uôz€²˜è#¹PøŒÅƒí3£‹Øø¶kUÙéÚÒ§žÏr›18CC!|h®‘g¬  ¤üöèCP·K¤1“Õmù‚¢³àFˆDbó48e"a.F_‹ˆ¨!å,� °�àâ�9â`�ä6jª,@¤àä ¸?ßad޳‹° °€å 0BŒèޤˆ ! Ó 6ádZØön¯™ž"š¢I…w¥<äF­Â…é ÌÀB»4 Äà è!sTþ<g!Ã4à ö@‹gG„»}’ vÌ$yÚF€z \ñLÖ#'@e‘Ëk˜Àp€ ¦�| ;zï%Hõ2`â%¶÷Ôz4CO")Š2 GØáÞöŠ È$`%,è£s>n' †Úôx!•Š¡Vz'UÈBp¡"©ÃCD㻀¯©—¼æxÅ‹~“£O7â¥dœ3D„Õ9›J >¤‚r6n*ÄÝš¥‡ì4ê $¹qžòØ4 ¶!f€À�ãä.®V¡°…Y”¡{.AŒYC° 4 âÀâ �WáŠaÔ<bþî_?7ædθaÎÕãœGÝ áB 4Ö"?z€ ˜àÔ²™Ë,uWo¾° äåúŽÛ_4ÀL‰À^á þ@¨`¹5à´€ŠûÕ ‰oÁŽp«âÉÔ„G`ÔFA ®dã)ÚCWd j'BIbàSJ@†!áH•¬ÖT(%tꛈû»Ñ‚˜ðÓN`óОÄ&®ÞVŠáCõz Æ@ôÆ‚ŠÃ€¨ÅŽKÃçp1 ‘@Ü'Æ :A^“»dÓ›²uY†1|¼‡Å» 4ž5^#úZCܸú ªl´¯£Æ™“nòÂéÂqTòYÈþ;ÞÞ´ƒž@êúRü!tÒˆ(%nf0†60�ùÀÌã {´à<ˆàA1 `£ ê ”"[¹âÄuä0°@Ï‹aääœC¤‚úÀ"r¡-0àFà~ J?!îÐB ŽÉRÍnFe‘ ´€R@‚›c‚{A¾à ´à2ŒLÝöà ^¡ öà 4Až¯@€+„b=*våÆË ÁwtB=râ)øÇà)ü€ Ì ÙŸ�à[.8öDlóDO—Üqˆ13[‰£wLbàmS…5õ-úÁxP�yð@ àa lg¦ÉâþVnå-©¸ÆÀSÍxÁÂL H7Ï©½+Z­6m1ê8)×ÇGáa¼5°z}‚\*éÄpÆ ¶‰ÎzY¹°‰¿T_ÚãÓÞÞè&Ž@ .%4> ¸´’P%MšPhj8цæÒ¥U—f8$ÌÂŒ 2¢A3ÃBŸzœT«¦ Ë»ܰD‘’-8qÞe‹S¬Ø„(ïb{)ç],@…ˆ¢Œ”OJ sìˆ;8JJ}øñÃËX?À¡C©kö.(E ¬Ù²dÏ@‡îÉWè ¹"†‚˜7bü\Ñ2¤o¹< Â¥Øôå 9MÐ4P Ž _ü\˜ÌþC©ÚËfÙ¢+QbŠçuS.)#ŽMwëÖ¡˜˜µU3|MI ¤k¿2¾p.‘�WÁ*UZTW¥ð‚\ª$Ožæ¸ñâÇ£%AB:èdi%<Tœ´˜/—xrž?a\‰»ríZ.Ô ÖÅ_§¤ß>wJ.äw×Ï<ó~äbÀ¸óÀ–…§àeà¥å@YpK„YdQ…V¸uYl“ᇂ("ˆ§ÐÁÁ‰žÈ‰§¨˜¡Š0žx; ôÑ@}°`6VðÀC ,(P l9ÁVfh%Ix 6‰¤“PF© “™=ÁÃ5ø’ªp \+­$WP9\R �zP´þ )wÜáP OÌ0.qì¡ÌF}BÊ™�TóD (óNžXœðŽÙà.ªH‹¡‹(ã*dã@1}X@J7@¡L6Ô8ñ„OlöD|]IE•U/ €�` ×Äã0 ªEåYqÍsQpàlê%Îü±X8 ñ… Cüñ‡y„“C%9„óÇfáÙ‘Qn¶Y䯗ÀG\ñ…8 €}žMq‰/¾¼A®;ø™A‚= lÆÙ%¿ŠtÀ‰Y0Áa ÜsÖ1pÈŠRׂ»NYBy~\FWˆã ¹` Ÿ|ñ¹ÓŽø½›Údð¸cF;¹ŒÃ}³-þ¹–”˜9¡V±øã3K€èá‡Cƒ¨Ýˆ#ž2â‰&F㊴ˆ"úÌ€?˜åÄk8ö¡À*<ò 6 ÂB5F’eäÍ7Û\1Îg¹ .ÜtOÉ6¯<<PÄTPÁ*Â1w\ÿ„T ÿH‘‘¸àZͤÔPÃ*hôÆ }è€H5ÄñOÜXP ) dƒ.ˆrÐ8‚rE6±4áÀgÂÔÈ# zp–€5\rDW!„ðA Œ0Â¥„€TJÀ‘K?º©ÙÜU&ƒºð̦ÔxGñÅeð…&ä‘G/6°áJe˜Çð´ÃÆôü1ÄqÁ¥þ‚[Æâ/rñ¦è xwåG4¾`…ìQ‚u4¢hGŽP½Ü¡³hNt„³0€é„ÏÎs¢BàH€:ªc�$ЂP¬Ho»^ îP¿\”ÏW`/â§„‘ÍG xp‡ .@2rMæ<40@hÀºéJ-NèÖ€v¢QHCÊPÑ^ô!ªUj_좩æÅ5–ÈiN[Œüñ°-š¥,ðEVñµUX¡V`)Öd…'èìnJ:RéV$'‘V¬›ÍÎrȶ<à|£‚*üA*tr`ÛˆIª‘¦(ì$RˆÃ ô€„ðal,(.2…nhC$ÅàþÆ&¤ð8Ì hˆ8*ð p¨B9P8>×K—T —:‰°Ð�–D zÈ& øè|�/zÀæ•‚@ÑÂ4ãHG¢{e)ŠÀ V¸Â ç:P ð²‡=Tâ~ðƒ³¦%q”Aca0C� {¸¢0eðC '-i€šùÞ÷€áŽ˜¥C�ppÇdŽà‹\€6¹€ X«ÎHî Ê0Ètš.ì¦5…N(Z :œ‚t0dØ„>H‰-À¸@?Úq {vŒñh<.€r515 eèÄ÷ŒaX'$éöH4"ØFÔ¢–¥!- ¡#þˆ¨F×¹Uik­^éºF3bÍi=›ã&‡ê²8á}Ðã*»Šm“~Ò™ÛÚ¦™EJ²Ž´l“0+É™êPEP³ÓãTÀPx.”A„wÈá'gr‚äq‚¨’@Ã*HYÄ!Fjót€à¥’)\ðÒhxÇî0ƒ=ø�RxÇb-PmÄâ¤à;X`¹àø”‡€ož_“9©f6×NCŽå2ÕP€/®à Va z#ÒèÉŠ^# ×(Ca¾àŠx˜Á =`ƒBs�>à\=h ¼µ”µÅ­mkYÊE¿'®øäb!Àþã{á¸#ÂZˆ@¦€`ÔàDª "Óßð8Í‘©Á¤“†!Wa`-H²P¶¢*P,\%àýÚu™æ‡$ƒ;ÊÅe.¯ðhÄÇüU•àI›ÕÆ”töÇ´¶ÂEz}ë†Âˆ43z1gÌ3œS£Iù­[lÖ »¹UìQÖd,·Ç…D‘ ®,ˆ É´8€iÓ¬‚Ú©éËTR‡œÉ†¢3°¹ ¨.¸q 4ÈÂRŠÃ‚6�A eÈ¢g±@ƒ6ôä„8Üö0Þá‹\ºVqГþ¡ÌLÀ“³lV)Áà0ž0ä�3¨;œþ` ˜c@/´‚Y7ó½Y} x+D;¸Â ³‡`¼ÂÒ"Çî ?W°A_0t…$@oE˜À|Q‚~\¡ bØpR|½”Í!é¢GÒYR°qÞ$  `@�à€xøï¿SPBâ1„<D@¼¹qR–" ',`@2qˆ3¦‚¹èÀzŽöÂà¤A ^ËÃáÑ\øá¡ì!Aù®p˜ÁY-˜ÅÀ Ó\£ÀƒXqÆŽUxI$éPœv µFhrýuÌøVá5Cn­+ÆAŸh‹0zØæx€£>~ Gh(ÆšxY¹eZÒQGó‡ðþvRóRºô¸Ëɳ%¹9 áNyzê™L`rúíM¢Ð�°ã±È½2gÀƒ;ò×@áÈFâÀ HÊ&»…æKb2ƒD·#¤@C0`)Ø�ÜÀFë?pa K8AÑGx� `�XáàÃ⌸&bIëÊÞ¯ ‡Aå¬gEK š+zP†Æcñ &í>2pbpI�£Á 5¥OlC%iá ³±îÀ :P òñ5îp ¼@)ÀÀ@rÀÐ;lÁb@Ô‘tt 5Ô9 =•dÕ1ÕÑ ãd¥U„+RƒS0Iá±$þ%p 2P?×@âeåó \Çua�X…U¡q1°1Z×ý‘‚¸Y«@%‡´6Õ°  ä!{"2W_T‡/"xlÄwuÕVs„x‡7GWSx�@#˜â5†yÅ€CRV%*bkáa8Ó xk“yôufèÀ‹HzM¸y”dzq¡ BÛ9¸0 ÃÀ Q  Õà�9À>0 p !ñ†6 )qr 8Q«@]Qà�' ‹ÁÄKÙ:Á´lÿð×犠 ÿ@ bÐcHRð`� Ð1>  �:â#’È c�Öàê ǂ gþ0là>Z$(ë¼Ð£.Á@¯@Wào…G°s»rQq#Yn gð ¼°ê…8�Jà³R©p‚ ÅPJáHEà '@%"@M�TŽ!“}ãA%GhÒSp…Õ‘‡p ðB“ðiGYnQOäå?eàTWà,C�2fP îÐröðfÀ ðcýÐ=ë”yláv9³9%P QW¡ g{(F}w‡w!¢"Y O³W*"5s˜‡7)Yc]ÃG8ò††)”÷qEâkôf3žx=ì‡O�ˆ3†D*†%^ŸÇHoþ× èP RÁÛ Á«¦ZbðK%09X`z`Ù˜‹° pRz<ã�yŒ ¡•"Á0”µ:Ñç�¹7Áæ¼Tÿà�Ü@ Á`Á0 Å€9”ÇSöPIÐnP n°G~DW¤+ {pqTè>eð Cæ#P'C¬@)   …qqM%–¬ð4Æq×#Y 2E¯°.Y¼ sÀn82`�®@y2 ’la%ŰçA P 3y"`”EiÐ M@Ey <Š;T&¤@J‡ÐF¹ p¹tþ†Ä$©H%Ppü‘ V•õ ó, Ê 0Ód s ±VýòŽMrˆz@ši¥ƒEg­w#‡A#F-r ¢�‡’—kµVrt§X#5‚VxQãWs …Å €)y8¢f¦÷N‘‰íhQM"b ¸ g´H©Ös©wSV¢ bN@mY`ËQÉ$\ÜðŒïŒÂ8M2aLÐEO@:Ä}¤°°æqPK‹ºŒ:a)¾Ä Éx ‡¼XªÕH  }€}°›èžeoŽ,`ìÀ=„”É+„¡åsp\g_` )ð¥þ v àŸ\G†ñZ@½ðŸ¬p »AzW©fÑõC : 6ð"À�š  ?PNÏ£îÀZ@WV)È€"ä'e{@yðäÐ Ðt@)›“AåÁ%9¨ƒ9@ƒ9X •àЪ00Æ‘­`{fúNN 7“U'•VÚ® ÆufwveÙcàÇÐEt_™ª O  sH€w‡¤tÆV§Ð  904qi‡G£h¤>•‡BÅWCx'Ò%]¢"ª ›tL…•ˆ °X]ƒ#É(¡ï”•iI{E”x=+@GHzФ“™$iþª5jè¸ñÔ†=×b² >ðïP9' ‹ÝY[®ÙymÁrÀ3àma›‚›{/Aq€ÜðȆ Æ” ½n3^½Å ¸`H€–³ Q(ïP ¤@Q›ñ�ö@o€cHQ*¢²¹MÂÄuåà Aô  å£Bš�?ô÷pnÀ È@äŸ÷«.…¡ Êu ª~ û© Rx ñ @ 6€£†  p ÌS ð„À b� +¨ó¯^ë@_À%3é²TP 2«³  y@ᓱ× Ø¢Iá ÃŽÑ7C{BKgîdQwPþþƒ/f°1b(°Zª¯×Ud‰µí@¹Ð"Ó/˜x3½W™ha àE³!x×!f449жi[FvëSAU"%1m 5L£"4x"2ô7}‹Çƒ5¸ìP ž†æºÅŸ—E‚y‘ºpc® .šÆÙ„Žl¹CÜqZŠ•¤« >¦”P9kB Å`\Ê  ,!Q`ïЪ¤RªPR  °LÙ¸Ä4¬2!Æl'ð> ÿpœÜ@» 9€ ¨ƒT( pŒï`&’•7¸o‘„Eà uåc>ìk  • M𯰽yðô`Î Fþ ½€ D€¥¯€p_°âp¿~ð_gfXg¨Cñ!íàÀÄ@ äà åÀWÑ<00â` nBJH0Ë$а!{/ ³5K"´6K @³@E>kÒTP“6ù³‡@¤0noÇ ysö€ã¨ÄDW@YxèX;¥à c $ŒÅV„ƒt†ìÀ–  ÛÁ¶’ÕÛ° x7FY]Fd´Fzy*"Tyû4€[xƒåg~ö7X «°¨]Ê~B™F’Y‰ÜYjÓN’ÛqšeȾö#A$ÖÜž†uך5Ä›3*«§Êcþ ¼Ã¤B Àˈþ²Ê» !±ï� QpXð|’ƒ ±À8¸€º©üÆtLÖ™)D à6Ð9à '®ŒÜ Ú} ØJ½Ó„:àuHYØ’„ÖÀU¬eAôô@³P-ñ›ä0�Èà¾T¿&õüê“ ä°`âo®Ð_%‘ ÷6D*@þx�Z�Œp�?€ÔL°£Ð f�9’S ²  60µQ Q5 \p ° .­€¨þÀ£QãSEù£lÜÆ‡�¤§0DzHªƒG ,°+kIG`1P ýÐbØ1C…Ýê´pAjW=¡øµW´ ¾0Ye¡TÝ�þ±ÀÕ»§y¹—ÂÕ"B5oKWÛÐäe­·RŽ"|ë"yü·W¸~¦ 5ñÇ'P}À”hyãñÏOݽF™–5IE2*5€¤ 9–l7ö׌˜M”CŠ2åwB‹<° 6 Ô'3°‚wpÚp,  㕜áV'�Q 'Í7(¸ >  ÙÀ }@¬0ˬæ¼ ›À8½}à�€œ«P¤@ÁÚšsØY¬Cðè‘lð)0 ³ày¿T@EZÐ á]βÃy@&°êA•ÅφLY‘H¹¼9$WRîÀŒà€^sà0þEðGwP K_ ç ÐJ�  ãPd\0Á-À&Õ—4ÔC)”2( n!<Zw§X´tP 6›»nyq øÒ]5Ÿ÷î$Ðf+ør+g™ã ¤ÐL¸Öʰ¶r!HîVâ!:Fc¤óEƒWÇ£Y GqvF0r A#¨ku§M5Å� 5Q P „ŒfÙ®ñ—¹ º×W1ŒÜžmN* ñéìYî¤3£7Lr°a‹@ÖQ yk‚mÁ•Á »¼X*Õ09ÅpixÿP @² Öæ Ë{ ³ùËàp]ÿ°G¤´ =ñêþcL¼ 9ª<¬ ñ긅 ©½†˜†‰’‰O–I|É’ -9 ²é#°ÇC`ë1…¡ÎBB°ì\÷>…q1Pó•휋` @ –�@S€ýà ;ÀÎà ʳ0�ð�Ö`%ð¢ô�2ƒÐ<à.îàáƒÃaƒAt"~jð_BNÃ�² `Òïiàðrn1zó�ÆO˜~îàõ㊄8ql\±áEâÚ53ý๛2åÉtè�|éÄ#H’%IZë3$:=«¢@ò—%‹™Ûdʤ™Å¦„]Yvñ<5󧨠>³ˆ’ JÔ¶m¢8=ª3þéQ›§‚žZ**‹U«»NIèzìØS U =UéHŽoMÞÅ ×mÇŽ"KÚÍ ·o '%ªÍ(ÆÖ-Þ·€ïÊuBÒ‰žjwÐü«R% ¸(Qм›° W k܆­%EjÆ0nÙâ é£Ôªr¤(³ÐYJ¬86&\²€ë„²8¸ü‡¶¶bqXhcËÂA,q,²Àíƒwb”£©AªÆ%ÕN̳°¦ÀÊ¿÷ê]YâÉxoÌ<ü£J:áèP¡BƒG´ G -þ8ž!¾âŠ/®HAƒ<&ÌC-¾G¢2ÊJI$ÀÀ ,!€4|¹dwþ®)ƒùa‰¡ˆ"xP�]Ñ„AŒ�#×&”42c’É4Òh%”ÌB‘²É)« ’J,«Ø¦ 2{ÌqÒà‚=æR‰/ùžx�?Þ¤¨ ~Ì(ƒ 62Œˆ^Âȇ~.˜"@$Ñ=“X²"M'Øaá8¨B¼œ‰¦,³lÁK ¸ S/Çi¥.8íT‚P=•`›T»4• /_5õTT«§ÓJK¥©ÔJûh HÞ)†…È+Q°½ž`§PCIê‹/gå2vYfEô¨% ´VÚÈ ý(Ûh%I¾.ÁåUlà&×চÃÐà<`°S.˜ jX…þšÈÆ4¬a' 9bña“î÷„HA"8îNX™ ¢x' >,¸‚lÞ¹Ž jHw˜Kô¸c•w¸)æ„UØ@7Þ( +>ì+¯¸BBç"¦8¢ŸvÄ"…< ‡¢Ñ —^6)G?*訄h þ(pˆüô+ºÂ Åèš0Þ°gŠŽ�¸£à[¸ >|Q@Ç$v`„‘9\`†bˆ!$ Ä@^â9¦%PPb°ÇZ—”RÊP¹hRÉÌZ™2ÔË­sI,C©$‡$wà†Eç‰;xà žcðà ?6ôã"x ðãx)cðkâ1�ƒ@݈þ=µÛ�@L„@ùe‘À 4à qZ½ ìµoÖ̺{*ů„ÊЉ>?‡Î':z4H!œˆg–<ìŸÿ?6ù†+‚!+( †�о+ìñ²ö¡|  ÓÁ4f#æ‘–Í:¹¥0©ó‹²˜µ˜±}DÚÐF5¼u(øpk.Ù’K³p¦ò HP[ ,0ƒr9 XàtÐ0`˜ÇðâÆ ú@ 4Ø�9PÅ?®cYL‡:¸ˆCqN`8œÌ4ïÀ¢2²Ñ„N€ã:¤à$–(p£Hèv&ð`T#ehÐâà€”X# ¬pCþ·Ö=áPc³‹¬Á _dvWB/öCa?ÐÀ&œµJ´ BÈC/dµ -úÂâ1‘Š\℺C5D(™KP ÀÐȬÐ7( ^¸Û(`àŒü Ex�2`S° fp ‡¸u¬ÃðA"ç9(êJ—ÛçÄù¤%å€Ã.@a # ÂÀB `ž"Xã Sx@F.ÙÍ® $ðàŠ˜!a€Q.ú!ÍuLá¬{¡ø¢<>L‚eÇ<Ó¶tTƒ¾‚† ° ’ŠÀ˜üƒ|°?Ø`Áèß‚Œ+L b°G Ž ƒþ#,ð ýˆ=èc#¨óG€<Œú�@e„©YÜâ%(ªFumk‹*z¥–>T.“áÁJ¶åAvp$ƒ,ô‹HÔÊó8ÁxcÕ–Zç€'hƒ `Ç 5¨Öná,.ÛÒÃd´±ŠÔàH0á†,œ [\E �Q"Jl@²xG5jŒP@1h0^ Xpˆ€—ØŽkÀѯ8L`;R¨�8V n`'5ÜÀÀ‡7‚ÙÀÅ%Pâ�YHá«@ƒˆP7•a^ðÂpp„ÖýEDwá4qu£®8@É��a²JÁ#öS!÷ÁZx/=ò“þä!ïBâ3ÕªëƒY¥¥ @4CAŽàË@&aêÅ(ÔñWô ^Å#` ¸#q‹Ædp] ÃDp˜DåÍ͹ªKdê9eŠYã–‹Sˆ2al –І=ß@ÝŒð¬¹ëXá qPä"AÜ‘)¬ãJ€G ”:¼:Á“5øà檃º._¾š¦Ž€hPòá�Œàó `. ‘=÷Ùu‹T‘χæ3#wÆó¡ñ\ÕE—@ÐXÕÈT©êºb¸ÁW}P@XçÂ𤭅Òë_â⺸5ÍO¬C´—ˆþD<@¡¼Ê˜ FuŪ Dá’W'° ñJ¡yô€…(œ� èdQ PX€æ�%P e`A5ˆƒ*|ŒaÌà­Aÿ±‰ÔL/ÙˆE6þá�\¼VÝ*âà1ì`Ú€#àjT� — ,:!HôaqCˆûÁ‹Œ€ =øÓ:(™¼¬ÐD öi†+hA’y�P€èAQÒƒ ú9¤ò‘ÿˆ~@ |w¡.ˆœÀk\wYO¸D;hà‰sŒÁ�ˆA`a/0‚4Á®ÑƒWhá }Rg•ñ¬3¼¡5†ª*ˆªþ \xåÈ´v´“‰ c;¥²0 D€ÇÀÃ:”`1„¡2�6�PPb°oðÅCJ,€oêA®PŠà@ ð(ªQ“ꧤJPD7¨A�jL‚€xsT?¿‰ªín.^Dßiܹ†Îg>y€ÏÚGšu»w]åÌ:â#3÷­ýÖñÉ×Ma÷r~5Â|×Åù ¼*Æ­Q·ë1g ©A(׸¼yvAd 碇̅«p[øKô×C¹õ•ckkKŠñŽ8œ@ß@bƒc³�)p�eh€U�2 8hÀç ×ê¶K�»H &r�°¡pþ�pP…(Z-îè¢ èƒ¡ °�¸¬(K8#è„>¨]ê„ ¨�)�>ˆ_`›k`‡Ãh” \‰'(0?8ÙùMø�¹©Q;Ù3h‡0V¸©0€¤!‚‘{BLWà?¹¿Ž¨ ´¡µÔ¹ƒƒ0ƒØ›H‚X�rØ/èX�/€È‘)@)P‚B*öÛ±;˜È.á€XðUà€,¸Ä*‘±0¡8*r€†—úŸ0 �{]ÀƒF6Ø‚-ˆ‡¿£€ÎÀ†  „UXÈ'@¡$€‘(V(W@CÊþ ƒˆ$€‡$x“Çó…xÂØ­0›2K`<À†j(`À%.»„ °GÃ¥934AcCs>|ú=ç;¾é#¾w|‚8#¾ç»Çyܽ5y�{lëëG9¾>{¬G·AHX…;h tàè±7œ¥•€ ãq–àYû*f‰¡4‹Ed?6$_˜³9¤zDRR�†z!v0™b`7"m ,Peð È@)06l€(�…>HA À‚ù: Ì"åØ?¬†<ª�xÙêí˜ (†™ú‡xAARÀXÆB@P†SX4°=°‚”‚MøþR ‚ ˜kø&ø€8œ ¾[�;b�Ð!Ø)ƒ=ð8§ ?Hˆ‡U2x01ˆ~ Là…g`Txz�¹ I-`ÊÓ©ûŒz'°„jˆ³#Ðð_x1€†Çã› ›x�A™`¸ƒHµÂ@½ pÈ (@ŽƒñU'»žpȤ/x¨Ê€#AsˆbØNà0 s �\ˆeP„ ]\<ur3`…x…2x…(ƒÜù'W¸‚+p¼Ùy…ˆú*= ŒÐ“j R›UlO íl(u’©*0{øÆ þ± XyÔYGÖÙ™êëGâÛÖ±‚}¾)8Ñ;°>6a¾e=â©Gê«ÇâAQý½8‹3RP�Z…õHj°‚P!ô;+¹b«—«ºJœé–îó¨Hmà;Іz$7Xˆô 4é–½¤«'˜1ž#$,4˜�4Ð>PA^©�؇Ye�e8@9x…eˆ öÓ€Û pˆp¨�î°€>ø \�‡ê¨Ž¬¢!:­jp º¬l‚8¨€Xè„ X…Ô‘)©Ïª4ƒŒP‚»¼KŒ˜¸´aȤhœ'Ôñš$z`ƒ»6ˆ�z‡Ðá‡+þà/È…LÈ„èUL*¯G@/ॊ¨¯* â–¼XÀ·aÃ<XZ$¾Y�gØ3ø<�kÀ nà€à†@$0™²u3@؃}݃Wx?Hà'3ÀÛ%€8€6 bàbPcÈÈ„0°‡<EˆkЧ#8wˆÈ»W¨ÏùÜ0ØúLÙú¼†Ø©¡º`@‚ J È+=�G ºxÈNiBÐ%è°%¸�6h‡;KDCÛ½=ã+¥ÚáÓ‘½³¾°†~Ôˆ;X' 3|²†Õ>„3þy,Èé›Q}°ä¥°ê“5"U?#uÈ@jq+¶ú*ÕL?’Òq+¾PÒ …ÖуÀÅK°i10ՋȨÇK¸„o«ÇláK˜ °€'˜3Š‚lµø 8P†`h·wxex‡ð*'ð¨ä�KœÄB•ƒÕh‚ax4P m˜à† ˆKnˆ$8¸PµA×(]Uh‚|HÕà¢Ýƒ‡»d¸�½œH·à4pƒ7Ðø|BIª/ˆ^ƒc臘Ññ¤©ù6 U"0TVLJš!4„‡|∠ŠÜ½­Çʰ†ª…˜Z+˜8þT—Q:g ‘$ø<=@‚Ù¨†œ¥!@à`\à€m …¶à`ìØ!áM"4 €ò…73ˆÊÌwØ HØhƒ6Èb€Øc„x¼óV(P„fsM*Ù¹UÙ ™ˆ”% ÆûŒhœZ±%@#*%[<v8†vh„1Ø88%P<pc؇~È»vÈwÐ…u@7^ÇežÚ¸øZ5QÅÇàәߛG×[`ˆ³\Û~>e>x¼ÇK¦>êC _(†U㌔ ðû–ˆìÛ¾¥–²"п…HS‹ ¸ ¾ ÔÀEö«Gk®.MR[‰Êþm+®%Hm(3'�ªT“ ˆÙ �4h§@ƒ`€f_\ãp�Ÿäm`zJHÀ°ÄX¨€NˆU�‡Ó˜D-ì€ælU)hTA]T\àðp€† x½j¸×µÀ†Á4é$¸€Vý‹¢H7›{`…¡!UHð.wðÂ/Ѐ¢!šKÒ‚p«I�Q¯Á^¸†¤J_˜æS³½•©j¥‹õ@ m]…$x€ès=à·`S£Þ-y0.†õ�¨Ú±/®`À³}7˜Lè568P8RØþ<P †Ã� ØcH]Hâô´‚"x¾9²”€`ÆjY)ƒ@Ù–Í…ØyƒA²k u½ê¨R‚6ð@°6@ƒxcHØ}؇1hwX8hc8íDZÜ+‚ÕÑ‘ÄNízb;Б¸A&D.>ã+HƒÈçóÇÖ©=|G­ÒáãÚE._Y…B25RžHhQ3RCû`™Ž!½ÀÅ2¿gyÅ®øÛ¤Q«‹›ù*Q.QBYħdp{JRhµk‹,ñH]Ùí¢Ô˜f\"˜7è É>0¼<ŠÄGðGi…`�4ˆËwƒêè¢w®g)` &ŠþäX­8† è@) x�–À\ßDÙ@ƒU¸�3˜º#ÐeZ#!¾H€#`…õ¥¤¬¡‚ƒHœ÷ä“ËÖB>©xˆ� P¢‚^ØÑ4ƒÐ`=›‰|€KP(-Ä�èÂC¸„ÛjWØèhA!f@ð€É‚å„ Ȇ%¨ƒbÃxBAàp6$ ЫB‡xð»~hƒ5Þƒc€¶nƒT”‡Õw`cc@ôuà1Ph�—qø¼†ùôW�Õ¯2ø„Jÿ§à—Ìm`H>ǼÓ]`c8@€Ëöƒ\ÈÂFØ#AØ}h„\PÃQ·V‚"Aþ±Œ±Ô[Ø[ÖÞP`‡ízB&{äíÇ …>­Qï>QßäÝdà&ÈØ‹Ûb˜€O®C*åˆô¾7Ô‹Áý´¯R8;“÷€ âýÍXæ·zJö" ­?¾ú‹*ýÚ*}=JfR †U8Ôaö(¢Ì `­Y¯„T8ÊUJ0.†U˜UPŸGÉ‚P`�,Žã�‡†…O™ê …Ž2·‘ï—6zUÈÀwHùŽ:ápËÈ ð{¢á Wî’x‚&ü‚ü¯¢Ù?`ƒŠ0D=F6ÎuW‡?øûùqûr ¨FˆÐ�h(G—tC“ðÑ“þbògp`„+¸†‚˜²\¸–þ€è0/f¼ð�l0lˆ'Æb,£œ{“¥ ³$§�-<‡6k°bÐ_%0 ÈscPgà@|ÈW‚<£l€ÂS€8º–Íb*ÞOˆ‡O¸t¸( ?€F_8‚GƱÊÞì,m ‰�hÎ�\‡Îƒ\ÈÎ&…uu8æEC¦;(ä"¨ò ]G0>ئäe¯ë8Û‘€ômÝöcå~lwÑ­Qò·¦Ô†ÆØÛ_!ñ–¡q/vRÄ­«ŒÜNë–»m3Ä55ªÈɈ�€î`Á‚èª]ºsg†þ¯<œ t‚D[7 ¨õ‰GNœU¤Xp;‘ÃUÙ4Z¸ˆÄB”hªU gÕ e¢ éS#Ž \¸€[ªJ•ÿHYC3TŠUÿÞUÓÃâƒb¤j¬šQŒ®w¤4ÆÉæÀÁ; 8©A ‰ž—Z)r‰º„yó&ì[°ÄƒKW´ü¡Â@Tè ¹B⚟¹ÌŒÁ�G rùù“'q8*4ôÒòå‹+?J$xãëÎA¾eÿe%¦ ›!~ðÀˆÐx0`P2¦TåÌ0$ˆ„”¶ªNÐQȃ0|�` ˆ" $|T-ìÉ�OÞ„¡a,.þ*2ñóÁ pÚìkƒ û¨î4bÏ%hpE1¾˜aÆd~„á/׌°À+®P/e”Á ˆa„a\�Š(®£‹rcsÌJ€B:p xd–ÆŒ±O? Â1# ˜) ÀÜqDwDiÍU>ðÄX¢‡%èñP%]>pÇ]f‰^–_^‰æa¢WÂ%È)'›^¶ù¥av‰u±Í†_³TQwÑ6(uÓ4Ý^lQDEÌP ^±1JÝŸQWMžO(ºW˜N<á§BŠ2#†/«¤g“zÒÇ  EYàH«tþ¤JHU€†ÜhîÙô¡M¬�TƒF'ªP‘ͤ”h¬€èaAÁÄÁM ©ÃÍ;ÁHÇ z<›,·B’ 85ÐD Ü(“MÙdó7HÔà„¬'ôŠN Öh3§@‡hw¡óÄa ¡I/T –h ññ®ÄӃ׼ü0Nb¢‘Ö˯°:ŵèÔ¼—à p‰ ý|pÍ ¼9³ÃC0QÜ‘(`€ÃýȈA? P§n5ìd«- × cÄdMw�h—ÍÀ�s-öP ‚~ðíC$D@ýc ô×aèð 2�Cá˜áâþ"îG×ðâJ $¢~ˆñ† ëh¾N’(袋1žxrÌ>xìócé(Ï[ì³£�xŸ. méb˜Ù¹JL¡ÄÀ<p”ÖDYeE\ù@–U¶Y¦–zò0Å—jZiýôh2¿e—{†y¥›<äÙý›éÉV¤ ;Œ³¥™®ßþúŸbÊumÚ|Ð¥ìxÚ]¬�;q­x ‡Øìå ¤¨ÆÿHõ§C™ªÕ€.Q$Ì* ,€†ÄA àpÀ¹ˆ…† %ÙÀ…ãÀ“p£ò¢I5žPŒøÀ˜ÞÂED{ÖÐÀ·t qˆƒVV)8@þ±PE,bá€Ô #'ÙÑ R p['è!tØvˆŠ:pºÖ tF¶8 Nø9*f1*h@ ©€±<¤@}¤‡òpG<&F1 ‚zAŽWø¢7Ó”ÂΙ¨^à:Ñ ¸£wîÃ:Ä0¡ Í[ÿå(�x`Kà°„YZ |è)Æ+:äA‚CŒ¡ <袈�?t0µ¡™Úö‘‹l¸Q;>—$%¸Ã Þàц~´Ã¾xC ŽÀ¼)LsùQÂet±è u:hÆ $}âG4ð„�Ú†1¨@þwëd’ „6È EÒ6•� vfi ×{€5Œg%+)àÊ«R]”w<^{kBO™ÊD½”N/RÕ“Þžâd'+Xc”ZK5´QRí/ícãlè—Sy }…BÔ^Ö(FqŠ&V{”ýJ ª.©ë‘RÕK_Ø÷„8dTÑÞñŽp£Xü‰€™È-R`â;€B´ôaïà β 4!,.œ¼ôµ/ªåÕÁ!.âðŽ Äa}XE ¢cxeº!7àP+¬7¬Ê>B`¤X‹”4C!*g}AŸÍbð ÄQt,G ©*Ì"¾þÅX ³[ F6`…=¼šÆSùå ¬9‚L¶€tÆ ;A  ]^ˆZ Ú+ÐÿéaT;ÍÚ4’a,X H�;ÞëÞÄåŒ×*AÏð€5Ü *1®ù d¢ ÆØ‡ Žá þ�Ó™  ˆÁ ~4BJ؇eŒ‘<Èà2ÊŒæÚ™ß1)?m(D?2—�ØCÂ>`Ö¡·cä¢íPºOÐàF:¬œüÈ (àœ’v´Í)$À¢Ox€§¼•^i Ê“RŒ—Q2E£wpSóÂD½1«©MwzžÈT½•ºÉSwê.ЉULÄ <8þík­PRa PkÜéx"ÀÉÆOÿ›N ô³�²c¼ô  ¨Êû?J•Ç Oˆ¡R›Ô¤ZJªpêC6*°/p£'[YŘ² "Ä¢ Z¹7|ñH%_Ê?ÎòÔ 5ɇ¡/&:€«X¬TÁ� ‹x‡¼´QE TãZz€ó?š@ëlüCÔq .f0¢8@] ↜Àî<‹²Ç•ÐÈZ×6Ã+® 1:’†ŸAÌ,ð™p`l4xdGóˆŽ]á  $רFçNÁ ®x…äb €xa (CàáŽ~˜Wp ñ �²%ÝREÇþw��n˜ÀF8ØAF@À`»¬ïA w�ónû0F#81‹Ylaw Ez&tà‰}Ì( ÀC<ˆA S4A:Ú6@CB;e¬õãðD!Αâ0€Z·ÁÜ䙵£Æ*ˆ¦èhP Òefìu’Žð{(G¡¼û;p„#\¢f¾õº¤<1UïÉc*ÓH=Úe’йóTv¾|fòm‰{}€Ä;Ša2$§€î;Ha…KJ}oØ@<C�úy:‡6ÔBª±ŠG µ©n®6Àâ”Ò=·§ÍÔ•@›%PÅÐZDH,RÜ¡¦{}‡ þžR¬B$q ¡!Ð"‡l4àøÇ,Ð’bñÄï?‹(Ö ôAXI·¡K±@›6Œ7à Ø:ÜA·ü:€ üà ø.Ø�Z¸Å]Y@º}‘ÚÄI?àÀ\ÀÜ _¬mìÔAL/ÀÃôQ/ô‚ÅèVbäÁ,Øq’RA¥@/DÀÈÀjÚNÝ^s±<¸ÂixA(@Ä€Çy\:]€;\À(À�¸À(@ƒ@8  GºaÊ@Ì6ALCÎq‡ÂÜ.ÙÌ�ÙŒÐið— ìÃ1(Ý,dB~(”éC<d‚'`€$Í:ÀA#ăþàA:ŒA<x‚¤àÜè@<ÄC;ˆ0^@ùÈ9ø“èø4 Ø@€ÅM<@#@“åB½È9ìÃ9,ØÈ@á±0ž’  =ÄØ‘`﬉QÞ”=Ïæ©”çµTK­”ò<ÙGaÔGI ø<YöxÉKQcLµ™™¡‡@B1ôiŸDA8°€6ŒŠ§@œOEÎHÒè¼\UB¼œO= l¢!Š6´Ÿ§ˆÏÿ ‘¨¬šµ‰¶ÖÃ, }õI¢Ì�Q(Õš‚< û]D¼8¨‚*€Ã;Ì�M@®ÁžÐ •ä½äË"œ�V.L@©‘OŠþ›X‰ÄXXÀX½C[Ĭ‚DÄ .ðÊ;ìcdM)HU Y wØ4¹à@ Àƒåù¡¼£$ÁmœÆh‚íÑÊøV„C ágðÛ!áѦ=|Á˜œåké :X™ˆѸ‚ô@,À|œ˜ÀC BIüÀ#ì�é¤Ñ x6¨—0è\Ö|‡Ìœ0J ¬CéÝíC#<'lA#èØ1„ÑÀŒA< ˜Î9ìÇ?A`@dÜX|AÇÃlÆÎ1@Å xØ1ñ?<C<àXÖ=C;ô‡èð„éSîàÍ‹øÓþØ�’øÂ ¼<åX~løŽïLÁT7BÙæQ–tãJaã Ô|^™ÜA”i J}cëµ^L•£õ¡Ç^¡)4ZŸøBÐÄ*ÜÁtl £ÊûDPiŠÍ\ýdÕú8 ­¼ƒ:ÚÔÔyÊÄÅÿÜÉ ÌÙ–¨OEßAð�díYº]›TÀWðË hP1ðU1ˆÄº¨Ä4V6Á (V1CÃ00–GD2DÁA`)ð˸àBœ)0V¬Õ[Ô�àB6h¤2Ø€YL@UºÜ¯ØÕ;ôÊ�B„HðÀ 4‘ìÅ�àÀ0A˜Áþ(P$@  ¥€8œ9hÀ!!ÐA(ÐAä�°Œ õnñ›h +ˆÁjøI¡•¥Î”ÀÀC<Ž+ü�Ñ�#@@.ôCÓ8Îx30 |x‰ÊX CZ‡<$C2,‚ˆ¦D\ÔÙØŒéü¡1¨€È€?eB<ôÇ9”4Ó@yÂ9Ô¢‚¹kI“è¼ ü=p‚ÙáA„iÔÝs*bÔu'‡] Àâ1è�?à4 x P¢Û x 1 žŒCÜÁŠÔŽtbï Ý:$�0(ž™xT˜Ô™XCì§tÏ—Pþ‰7ž ôÐ ÷<ƒºÉŒ¢G¤ãî9J¢�šp Xõ•¨D.Uêií½* ðù…hƒ}K°átELÄDš›H †NärUz0Š6dTtÄ M A[Y€LˆÐ úáÂ%ÐDT@©Â9@ò L�.�C hÄÕ 6(ƒ2œ�OK$ûÅ•ýƒ„PU8@,ÄÝ‹FZ€6Ô™AhVDAø=à%´XC¬È®¯A$XÃ}€Ò0ÁôÀÈ›Y&„ *@ +°ÁˆƒgFÐA%„B%ШVBPA94ªb/i|̰B?<ÜùþhíÄ]€ À'ônÐ03¤Bü`Øð¤Ž‚0ëP±¡¢TCÁ"ðÕèÏM‡¶Ü—ô¡ƒÐ)ª¸>“.ÈÀèœCÐÀ gôéÈ‹ˆNÜ H.ç>ˆA0Ô? ´%â> B!¨Á»¶C4B.„â  ƒ×C;0,'\°�¨ BÜØ‘� <C<1\ˆ°Œ¡A<€æÄGÕ]Fï0cˆ]�$O•p™òtٚ퉕eÔ~*(–ØÅò@“yI¼ucКÙTñh¯8-±ÖV„6°À*X¥Póe[8ÐÛ®£¦ÜWýDÒÔÌŠþG [yÝWøB5Ä�ÁÉ“ið_¥H*AHÕŒŠJÁœ®[0ÅAÞ¯DÁI6åÁ¹ÌÀqC6ÄTÀ™öÁ·ðÊ­. ã–D`4�È‚l)pCf-BØ-V<QˆÅêhÝJNœÀ œ)¨’6ÄA¼Õy$WðŠì¶ C¼+XÀœ¸C)4*oŒÀïÔØÌË‘ïúX+P€„¸Â|A[zêô’*T§RAh@Ŵꈃ¼ÁNj­Þ;|�ø.ÌûªX0 È'¼À ÁoŒÂ�H [ìã�š,C"ÔÁ"tƒh¦›ñ%šœ$þkÝFSÝ(1œƒO{xÂ(”€É.*˜‚ƒpŽAïƒ;P€ Ì?ЃƒÝe  I.ä‹ăˆÀ0Ê€ÚC*6‚<Âq!ˆÎ"vçëÀÁ1èÀ€±A;P€;P]$J10¬CŽATèW’lññ$Ïao”4NÏÏ~IEEŠˆ‰J}Ï€‚OLI8zO˜ø ð�;XÁì©O5Ôò*°€+P¡9Šº°ÕVGË!ZÐxP„ A^½ƒ—Ì@&ÓYíD5ÜA5X)(@µY¤B U—PÁ¼)_1t©ˆDO„º(e1´ä&8ÀþîÕ½ ÅÕ@XÃb‰UNþZu‚?T€äz3¿ØK€Ã2[� ‘¤*8�)И¶¤Pî*pCt„Dé®ÂŸ„™Å¥ÙÝNWÃ*/P0øÁ ˜‚:l¸;3<Ä›yLÔÂ�ª0NâdÈÈË0�©–êÊø ’9|Á”ÁåÄ�©QDþÇ|À'ÌÁ ÌÁÑXŽ…ÀÏ8Ž:¸¯ÔØ„›!xxÀ´V+ÄŠL—€¶,d¢9—ÐQÞðG â1C!@Ø9B)”Î>ÐÀƒ~xB)œÃ‹ünΈ?é�(Ú $è¨Á‰õbxVðè¬ÃÙÜþã Ž Hç9¨A!ÄOCX;üˆ1,G#@Xôƒ‡U:çøB�ƒ< SÕC4ìÙ\”h™ñ¨Ù÷€Ùå½”•PY•c{ ™}±—I—À‰ž@Ù÷XÁHXƒhC±Ï½¡ ­¯< `ŸBèÁD J5èl£4CFá¥@:VMNpµÛí.5Äp; ³8q‡Éé¶­r •Oåi‹Þ5l•-çZŸ®X‰q[À“æ$d±_I\F ·™ÅNÄA-ÈA¾DQøC6(Ö;,-‚‚ƒ{sƒW‘IÁ¤ÔÀ0€C“êÊ ,à�8<ü5»…ä�€Ð;0‹º\þÐDXC0–ÞЗÕÀÌÁͼ�=<ÐŒÊ `öŰÂx+,�+”Á—øÖ[þ¡ª&h °‚ÀC ˆ/ñ޽`–�b@)¬sÐ�})`†~<qp|‚)˜A<;ë¯Q7¤×`³ÃO‡ŒÎ‰<ƒ->¢€ì"¨À @˜Y˜�'<Õ  "„E,‘Xñ&âA;ìƒk¦¹Äö4Áð1Ę–W ŒE $@+>ºšïb¨ÀP0èHfC´ƒT¾.¼Á\‘A”Þö’hŽð¬l–•Ô˜EÏI­”šñúç•ßGYÁÌJÏþ¨Ù“÷„ôX‚³�§ðAtÜž d,{XôñVŢЄNå?ÖÀ«¸¡÷A� Ô�@°X¥­Z5m€HÕx‚®Ú=NÐ9q²ŠCO>ˆN#:��éä kO€{s牕U¤8ˆóî]±b3ßY¨áäΪ}~ê1ا6v5ú¼S¥êŸ™q”µT•Sš¸Åɶ\¬ Ùb:à†eÆŒ8à¤P¬ñîßRàÞ!ÑCªÚ pd®ª¦Ç‡N-ÜÙ[OµÖf¼# ¯K—.¬òóƒòˆ/˜`Æq!A`—€¡ó(’tÈÒI4}w…Õ51eþþüÉ“'íÚ³5ÐûÓKÓŸ/_®\3Ó/†½…£K“V¾|9ºS”ÀÁ`àà ÌL0(‰Žv Ý•à`bÊL‚èô”x(š4  PÖ¬ÁÆGO}‰êñ—Ðï<Á:€Ã˜}4Ƙs¡AAOÔ€†x2!†Ÿ-Ù¢kCÁFtPaþtÑE�Ph„ bˆ £‘1r9Ç“A<iÎ9g<Ì3 �@,8a=dhÄ“BÚ0f <”ÀcŸcŒ9¦6,D…vt`#Œc¤DÁž7ìAa]²�c¸SBJ%>œâ‚)î¸ãŠx�£’æ|b ¦Àˆ‡7‹ˆÏ=‹¸£þk}ó";ÿÌ“‡E÷Ü“ÎE뜓' ²BX胈”c§HúP 4NjN9’ªÙH"NZ¥=˜‹HU”q ¦«‘ «æUÑœ(á#�œx€šô¼D‹¤U5ªáîpLŸ{' [Áiª˜wœr`†„jXe•K’Bƒm£x'¶ÙæŸ â@ã üñ'‹ÀÁE¬Wù¨%e¶…&¦l∃4¾�qk ÅTñ¡âlÞÁÅRÂu Wgà×Ð@Ob \]åbˆàÆšKf¸ä‰;bøagÔQÇ”>aÂ�x:K`ŠØCn$K,±¢š® gþˆ!¾p…•2^¹â‹?4Ð òÈí-~»Â•+X3Ãl?’X69‘<à#E ˆ9ÒJH�w¸Ã &|Æ!K´O»u”ã“~Ìí!ˆtDlÖ0ᄃÖ;¤ýœ«û¹ãŽÀ}Ρ 0â¹rÀAˆyFâ!fõhhhPñ˜kA…cÔH'À6Òi„†\ÚiçŽñü™xt1OI¼�‰;€ÁãIQ˜ö‘ÑÆ8Ç%<‰€ ,\ (hçÆ¿¹Ã°;) _gŠº}Nÿßd§'ê*`£öd XcP…zÓü¨‹ð ÈÒÓþEµH‹éà @•*åT ° $Ü`…­4ì°ÂâšE†"€(D´)4åGBé7,P,èa!œ’³ôP.k4‹ÚÐFGb8“\bG¸„/&@„,΄ˆÃ?ˆ‡ àB ¸�â ² 4L ªÈF,Ð\@%ª˜E6Àá€w`!RˆœB. ¼ë+Q˜@6D ‚ü# ÜXIáÅ`ãz@ƒ *àƒ<F!¤8™Vpч Ö`ÁàF HH°h ¤˜ÁÃ$ö“”À GxÁ˜‘Kë à0�gšåäôAà‚#ÒÀC°â ½ G/þÑ‹^�çÕ,Ù®°q  ¬`…Äpú¯˜À„Õby#¢ØE+¸ KÄMGÂ|B üà`€Ÿ80àŽ¿eI;^ZÇ:ÜñË¢€`ÏH÷‹EL H�„ªh™ÑÌ¡£3Jêœtö±èÂÏPí2#°n2 '81‹„LxÁ%´aŠÖÍ*|'�5 ¯ÄÛÇ÷ÚÁ‹-„!qz`!=o`<�F ”t!<d‚¥Ý#’'hà O#ñ0«@¥3РSt”  S°k.1¨>íõqâSŸ ø'ŒÜÉ{ÔEÜþ´¨‚s²Âµ(+è©$q;VŠ(È`*ìT16 H ¡"ásôàDœö#<@Ù*ô�v°c9uñ$)ÜE m XXAØ¡#bâ¢Ájâ¸7ª>S"Èqfð†K°ÉØ„Ĉí¾rà8âP 4Nª^”ÂWäðŽœÀ^¸ð|ÀER\bPEY’H $d£yÆ;X‹1&¦Q@ƒ6 ë rzÉ;Ðp‚Dˆ-)¢… � øUœ+%Rƒè!|¨HAŸ)¸c ø�JQ ê|�(F˜ã„(œ"™\àB$ðþ ?|a½ Â#¨5ij¯`żYΪ]a{ ‡Ê!MhÑ #À—i„]8ÂÇ$ó.ì@ ¹yD?GC;Æ0†û“ŸJ¨3† z&%¸ÃÎcø-P\bµçq‹8A7êó†:'XûÑ0” unLÆh‚ð¡ƒØ-i|JÐ… j‡"˜nm@ÒÒ ˆnt N�ÆwB ¡cÌšç)à¨Ä{„�øE=ò o—nSpß>Æð ÒÑ@JD!B�ÖAc !õR–öq%wpÑ!Q€Ìä>%�Ch8‚5Ž Ý#À©¯ ”5{+0ÐMÈS¤�Å'þ9Ý»²xª¤$Y Šä ,€„8 ‰UØ4ìèÃÁE»Šfq9a)Øá¬`Kƒíeg[ vÀ*"ûyBÌ\éÈ8D "7ÌHœÐJ>„¸\OøHy!̬’„Ä…“5‰y€ ìa}(`û„,&a�—µñU¼ËV`©×n]Å ÌÀ‘¼F (Ðòj`¡hB6˜²`˜zàƒÑ°1R<à% ŽÃË̵ n`C'XD°0áZ4À¢«8Fã¸Ô +~‡6ÐÑr$ÈÐùN:¤ÃÏRÄ™ ®xEx@šL5 ð3$†røá;Ð’© þÌ^t‚Žœ‡ÜÏž÷M`�A‡St¢  PD2€ G¬àÌ»¸ó±‹œBʰ€ÍÑ¡&ï„�mÀ�÷³óí|O;Ñ(p0´@:V† ! $Œ|#ø!ñyðiµLp©ïŽAÀ Ú¡Ftt€ˆ!ŽA ö'vÄX­.!|<BâábD�Òá@$ †áª ×Èà꡾aäÁ>ÂNöl¥„ÚÁ}P Ô@ ˆyðMÂ$ŽaÛ¦àLæª~²D†‚úäÜ⯤K¯äíèÝÜÄ ìí¯ÜÄä„Þ ±JBN"þ%£.耥4~h³â€lŽ4ž °k´J ……ˆeµÃ9fæÆa  (ÌE'HL$§.†Áp*ô$"µ,@¼ŠÈ!±¬ –‹–¬á"8âHÄ€VÁ]ä`”¡^ö"a`Ibâ‚ø ˆ,ÉÀÀ¥[e梓´åæÏÀBàbpáþ@NIXÍå!‚à xk1v î j`üå|`‡,cä ”áâÀÂÜΕHÉl`Þ`Ä€ áH¸*Ïø � üÉ�>av` "� ê`váǪ€ ZaÒ  þÈ© Èš¨ "©€ö*¡"+Â*òà~o NA² vaDÌP’ÌV`Daî¡%Eá$àZaø áðÄL´#Já§¾çBº§LþF ¦À9€Á!®¹‚iGÇäÁ¢ˆHG?Öã#@;>ç¨ ¤@taL ŒÚ�B<¡a¶` 2a Ç d@X�a €Ã ‚öo !F'J@Æ À ‚¡È #ÁˆK¾a1¡àHB¨D¾ ÌÀ®d tÀDÊÎ JºƒD¢ãLŽ¡~rü€r®® : 3d îà¥ÝüGP¥þÞôª ¥Þ…"«‚,ƒäD?þNZBNJƒŒnå`ëT. @¥´J@„榹JCI‰¸af Pæ¶<)¶ˆ+ЪHb†Ç¥B/"ž ’âbqnçƒÅ‚#¢#�à!x ´¶EÆeêÆÑ\$ ¬Ñ,� ]’»À!îTú ï¸á°€& �SX 6Á†a‚akòºÁ¨!`2lrìE1pÁU·Ø|ÀþAÀ& ¤�ö ˆd‹€¾‚!ØñFÔ Š¶�A^Í�J:ziÆ2ãF� (áîþ¡$á !ÇaL…@ÈZO ŒŒ !"àönÏöf¯6"r–@ìÔNK2OK%KÒ^Ò$³`$ÀôbAÎé ÖÄ;JŸfäLº£QÍî„*ØB‚…<ààÏ,J?<U?X‹£°Òÿ&M@lâAÙ:D�0€RªÜáð  ”À�rÁJ�<€ `P.žà*•¤âau2ad¤ V‡tdÀåan!z< –A„ å0³JH .ÁÄ X;°;0` °Ž*­ ªprÜÇ~ê~ÜÇ} Ch.@Pêí€Á¯Þ„6(€àDPþU`ã ²êÄ‚þ"¥‚.ƒ0¨ E"µú ˆ ^n$:f!� ²ì0†H¢¸Hìô;u‹ ZŽd sW€âèÊ "§Tèû »fÀ‚Ë48âPŽEe�xÀ\."=Bã bbŒœîÀ<I§°ÀiáÑpa¾Üe‡¢à•ÚEÐ Ì…¨!ð$6&L)f²…SéiI @²A&àhF j€•"FA!t‘‚´ \¤`Ä…R(ObI’ˆ X€uåø‰Ÿ>À2véJáz€õä@0¡OÝIHr$€ ²Àä o›àütá`MQWöxo)~ÏNWÀþ$a×ùb7OïôNßIP;·Uü!ú–øŒU¿¯›-;ÊO'ÝAQ€¡XØïR…‰m°!œrˆ+˜°÷#žCIð¦@€j@ d¥t�DªI2¡[í!¤Æ'¤ÂJ@ à0ÅódÀØ€ad H¡¾Ž'vÚ®nAó † <ÀZÎ À ¡ÀŠ\'2! h`Ôà{Ĥ3÷!®Pà;Îd àÌQR«’ŠÐØìõÜh øµ_ýĸ€`x±�î7/‚ß®%a•#"H¢�˜ŒNEƒ<ËT.õ²ªA¶FŽDNÙ¸fk¶´á²\þ‘øàhbŒ†  2¬p–ì%\eµF{&Î ¬á‰èP0bKâ¹Ì.D�‰ ' ä!ð¸áb†”ÖÅ]ôH²¿T¡PÕ °àa¤ ºÅ{¤€‘à VáGcá¤�µa]¢@bø@¨¨áœ"‚!páP ÞEÑA žV'zd’±àR F¶ªƒræ�Æ>  ¾àôÔ%íô%«Ù$ïá´ù@ò–�$ýaöTaöò@t²àâEOKò%ÿTvo×N·¡æ¹ª€$IRN!œEÀú!@ÐÏŸf þá@Jq�ÊoMZs/Q¸H£L ržRnt–ÍfÝú¡ÐUIB *MÎ!�u Î;Î!†! f T@XA†¤yTíËŠÁ>5s®ò̤{Áž˜  !À€mˆáJ DF$”58AÓ´rD $¤Æ�’;º ÈÊQwÚ~Héõ ¦à3Þ N˜°€ ˆ` ÈÞ`ü �€&hOK±ìú€ˆ³²Ö´x ˆ ´¡ˆY€a@OOž(Çt¤Fî ¤Øª¸4ŠË‰Û \1µ¾å ê`v�cŠÁH(Œ1¸Ø“xà<6N&¥?Ýþ#^fÑ ðˆ 6aˆ� H!ð°Á‘6€¡©IåaÊÂ]´À!þ(¹Æð¨oóÀ|�f@N� N š@®Ú.þaºeFk€“Æ1C¹X,ÀEiÂŒä¶îÀˆf ?IØáN�eù`* yË1àð¦Ê@vr € ¾@²€ Vr%aòùDÁš­yXÒKíô¼y üaœÙ” šÀ’ Ir›/<žåY8@sç¹ h|&%`ö™Tá Ì`F·'û7 ¦£hìŒ| ¬ÈaeÐŒÆ ºa’ÁædÈ(gþÀÂÀV„Ï0ÀF¶ò@vG�WU T`Pº„¤øE AbË<À$#°×r<c§Q d@#äA‡:�¾!ȀشL¤ZœÚ›íBˆJÆ @XÏ¢C«s!­>p<úoòM>ä¬6!H"èÝüJÞà X¸_ím€ ¨MæÍ ²x@7nNÅQPËàŠ¡~Ø…¬a¬ˆf}‰•ã¢‚É ”StK¶äqGžËè�ûäâ#ôà^æ•ÆEbЀŒPñ \é6N"Ø!Y*È´Ðc…žà ¯h$®X(÷øfû ¿Ft \D� Á)–`Vnþ»+bA–`&$”�ã Z  \ÎË Á‚€aÜËþa–³a^A&”¨Á±'/ÅÒ=’[J«¾xÑ€&CbÄ�Qï@<F`rfø† ~`�ÈA8€$—€%þÂ_’Âïaé—Þ%'|%—ÞN³ @Øôà©!Åsžow·A–`h<hœÆ[$³€t% èáÜJJy ø)Î   Äá�F p@Jý�냖æ�ž|¢ºád¨.|ÁH€® H Ê °²Îgªk FšL¸CZ‡2!¬<ðÕÀð� ¨¡þ&¡b ±õ™…£@J! Þ ¦ÁꡦáxŸ ‚ ÎmÈ9Pà*i` h�IÒª Æ@¬'Îld§½ÜaI܇;À$(Ñdû?N̺MÐú ñz6c½OèPx˜üd€°°®)èPêøP ¥9xb½VáTJÂR&+ÿ«G‚�ºj¤¨‘ZeO5@z:y¢Mšbhª t¢]‰'5ôܹ4ã)‘¤f8 Rщ6Rwœ {è„ÝÃ'4Ñ=ÑãÄ t<yĸt¡ˆÅžTãÓçÄ)DÞ*– \¶lqf”$ÎÐ?ÊxUWpàþ©ŠNJnHþÕàæÕw3°Â§“,Z¡9€†‹”¯aÿþÙàfò_6‹±¬ÂB $zªu|¨§F RÀ,ßÑfRJ)qúð9¤Æ nab\p×cÄÎvü1¢Ì€=Ð ÅZ²ä†¨{¢†ß;…i—¨Ãß[±+ú®Ì•o»Î²pÙÅeÛ®ëâ[‰¥||zõ¶µª? |.­$H(àOB•p›Â˜é7/ŒðA?f˜Ñ/Zh±ƒ=à`ÁÌ�Œ�8@†�H7&`à ¡#ÐwøÂʬpÅ$ˆÃ ×(±Î>cìÆsŽ :è@ƒ1ûìÓÆ9žÄþƒd&4ÐàI!j¨aLgHL‰á†VjˆNë  D?Ã�“�0DcK3¿LÓL3dြéD (á /ƒ „¸3F#ÇÓOCÞ¨ †¢€Ž6šç¡p4z(—\®Cã:S!ÃS<P„¦OXó€¦<LñÄ<ðjªEÜÑ)«ÖÜÁðÞñ�ª¯ò`â©OŒŠ+MºâŠë†99aIÆfH¢<hë/ùZ¥†:ñ„ŽV¬ÒG[X8æN%èqÐ hXålF5XÀÍO8QÍ*«pSQ5Õ F UL ±Ã9•�Œ5¸j“N=q„/ ²âƒ/ÕÜ þãÔ*^ýãƒbqC qxUÌ;ܼiQ”ì@qdóÎ*hø2C5zXðŽÈ}lÆ7+"…!›ü,š‘ .¸€4ŒÁÄåÀ hP£ 5,�’0”!±’6z”@Ê;KƒãCÿ€£ŒèN9 .Às< ¼=�2†@M9šøÅÕ"‹¬‘È Âar q‚ßsÏ Ð1GÜzÔQ]}t0@GY¸ÇU˜'Ê6èi.ÊW¹yKø |UÈwy+ôâÏ.Œ“…›ã‡^¸Cý´c†+©Ò‹&#ÀK*›øRáK.¿|7‹€ˆ éa¯ @9_\á þ0Á/4ºsŒ pà¡£ md’Iù4äÒä9ÇÐ$0È“çàñ ¸I¢+ PNyrÇ>Œ¡ `�C¿hà2–„[t#‚Ýè†<‚@ $<ðÀ†„<äi„JÈQŽ¥„}¸#…ûˆÔ¡tqBŠQ”ÚT¨¦ «"€ê´âAp¥*Y…ŠU?´•j«S=àb¯võDšH‘&ÑÊI¿Xp¬ ¹äZ,¨‰¾jb¥aU‹¤87ì‚â[i—VAŠ’X¨!XðÊ*ªá„;`¡ʈe2c™ŒÐäŽ/yˆLlÂÄU€‹]‡,A ¬á‹ <€a3ØU ¬Q’þÜá hð‹8Ð )œÄ]^›€ËÚòŽ”‘L ï°@ÞQ'ô¡3èÓ‡£ ÁXàFW汆�ø)†ÁKàâI“ËV8V K`ÁN€c ,#3·Èl¸p€þÑU€CÙˆ.¸Ñ #l“A„WT Fˆ…8#eœ�QHF P�¿n €»ÁˆÓœÏqn:ÐÙ…#¶!É…¢�]ÒÎu.8ÁŽ(Q¹] ¥t¦ƒ{TwŠ%ÐÁuà�8l€†7X/ I°ÇîÂ0-Œ¢?(…)8aƒaÈ,YÌÓ ‚ð<ax CO°‚ȱrhþB½Ø8x!Ž!€îX1†í¨Gì;Æt O¨áKºŸ‹ÂpŽ}¨A @Õ¢•! U ¯Ù’�Ô à¡!ÂhÆ7–A† vãk’D>êñ Jè!LÀŽ”€‡n)R#d ˜ÙºKpp!fi„JY �Æ¥îp„#A´²†lpXÃo°†h¥ÃZÅJ`B<~[+)nÄWOpds•kiYÁ –à X@¢u¡Cn@ƒÀ\B­�JËZ¤€„2Þ!‡wä²2.™e^'Ô€2X@C*cQN XB«PÆ"²•AÌ4D™•|IuÿŃÝ>þÑÆºJ &~dÀ MVòÆKpãg>ÐÀ?ˆ`šœ‹ÀEHÌôam©Á*¬‡M8`z�D¢°-m4`¾pñÁIB2´EáH�€þ˜´aÔà†_|A +Tã• ¼bɃ>pc%Ð p6²8@d܆6Sƒ'$�a¯ Ç&šp Q¡Kà@w¶±YÔÙèD,D‘Òâô8÷NqŠ3žÌ©§à©œå¸ Ÿ,´‡>­h…(²° I/¡¨C,Œàç%¨®èÄ6L‡ºJ‡.¥§8E©;QÎ>$Á IˆÁb`¶ùá .øÂLA+\‚þÊ+†¤ç¿ € sìÃÊñ*ô G®Õk„Á�J˜u„‡s#ƒ8F&8ñ ¨`hÍÄ3îG‚F¸Cš’�ï­!9Qj…ðD&ÚQã ÈãÞðÆb×ô|dÀP„%\2'Cá¡~¹páf9‹îC£À£J©ÒêâPëHÀ6õ„ 0ј²Uop‰7À\«â”5h‹«U÷T¤.°t•ª ý } �´Ñ‡(€ÚX:�žÀަ¢(4r*ñæ•Äï‚XÜ–‰U¾ÕÐZ/äJû’1ÙˆE”Áþ6 ¨Ày- ´Œ( wþ¼;ôÕåX�Àª„Iôç^¢‡¦‚˜±Ü2 4 ƒ¸J¤Tƒ•8í)c&…HŒ† üC R©�±-HÈ! c¶€ 0;_ðD3’YŽ{9$�ƒ¤À$Hˆ0_¼’í21.ø^ ˆ ¡¤$Í@9X£xo‹ˆ\b>-F 0#,áÔòáBüáéßÄ™ÑP¢¥ã鸧 v4¤å#U,!iðŠÑ� .Åháøà³àKPp:Xó§:í×~ÊQÆâ `k²)10�Cp�¼à ¯p [#@€à|Ð e†þ<ñ�°—T ) _`m0¹`�ýÐ]•�(0yr@ppI¨žÀ Ïp'í ` `€�ñ@öð�qBg‡o]ˆSÐø€ƒ0�æ?€� g° ß` ¶ ‘@ �à%'(` ø�4PZ2Z†"Zx0$£…YxàBº'¥5C–²)Àð¾ðo°x'W—°*L”[–(\Öp ¶•`´%\°+SD¡,>÷+ÉÕV |$'ÀŠR½b¤@DÐÎâ[#¢!ÕÐ�h`_LJw©Tà�KfÃzR‘O'°- EÓMQÁJÙâJP*ƒÜÀþ"b""1,¢bq‚*Õ`/ÔâOWw€¬p ¿….z5Ðe—° —ðç$.q`_Ê€èR X` +± ï0NÙ° ï 3Õ@ rPw†�Dp ša•�i¦ÝpQÐ:£Uщ,q öHü¨OzÅ FQ}Ú@"–Ñ5€ }€r� ïPN|À! Ð t Uà}\pà¢@…Qô± p£C9”öPŒvR•sñ”EVû YPP n�Ð R° 6 iôÄ@ à §Pþ@~¨CRóq9\  ei±@V � àIþð�V10®¬ HUÄ!€À| Ïhf  Á`ôÀ–CÀ $cà0)•¢°û¦;r =BÏ@m°À ³‰%çHLÇ”@ ÒÓ…øÆ�s ƒà$ç � `¶PÓ@ ì�N�–ÀÔ@%°º û �g(m0m0C-”Bc`ˆ£u> Ç(x‚Š˜ZŒ8»µ[E@*kfC6Ç*=*7w ŸòŽO`ŠJ„*µ"ЏâH%`\pDÌe,Iá }@l¬ØT×u\4¹ öÒ«ÀÚpª´ y¸M°eù(±PþªGGA4¸@zÿÀ '© & lA3+Ã23€Ÿñþ_�suÅ„Žˆ¤P ˆ'î2°¾P‰3`KVdG63:#4Õ@2©DKÕ0ïðoT d!fÓD '� ?CGLÊ*c¥R5Ð�ÚˆÁ°¤sZvàMq� O`ãŒÖP#úðU-wŒ@DÀ2ª óP9u9egÝq•W æáàg :X¹ þP�±°ª±0—¢�¨&—3ª  -p‡Ð"ð¦{€ b@0 $`Ä Ä gK@”äg:URYéhæñÊ sPþå0˜ù6?Po�ƒlZÄH€Ó0™ô-öÐñÀ VØ+4îÀmS@„pfà¦ùYâf m VP(O@ Pà_“Ù@P Š@ ÔP‡½Ù›_nÆ�ñÀ Äw@-` th%o !›ûÐ(3Ä%62 ×Bpp ZœCœ¥x"B†2 ��*œ¢‰©‚³óÙ)µ¢Cò©.EðC»"a¦*£ˆ*¾+*E§² ¿ ²à¦ ]ÄV`]³d,« �WgÎ"-Ÿ'1hz° *ƒ1³ð7¡ܰ4Ù McG¦«`¥­Ä` æ4ó#þvq 2ßKPGla Fö8ë ïð,�ŽÕ¢6«à {pbà `¥f“Q€c"’ša¥h@/053Z&€¤q“vÁ'�NÐa¯0 ‘‡ Ta6|wIq!ƒÌFV1*>01 òHcë2,‘!€ b:Ìë ÔD Qp Ÿ¡  9P: j•¦³ ±À¢ödª’–•°¾•@0O ¡P wy9xf¾‡@úKÃ�ôËgy¬Ã•Gwþàj°Xi@YRõaæ±”ª ³æ×Z0ðåPewpxW¢ŠE� þÙùžg8$@$`ð~#]•BžÀ¯  ž@ÐZ¿k�¿`Uõ ”�yå›]º‚e(¹0$ BÁ<÷ÆÕâZîàÅ$k('4²xq„(B…²Y…‚'ˆ˜'§ir•¨Cº%I*G´:¤C¸Ÿ¶ÅrCÛD=›D *04A*Ê´ ÊØ2KrÐ3-ºŠ§r-SGÂg/O·.ãÅo3<@$ãMÿPKÀp.&Zcv3KFb©ûF¤À+Ñ{@Kma}h�p’-‘ZóÒ\èPÅÀ‰3à w”Lõì¸Dà˜ 3#s.‹'GÅ þ¤[½ñe"ãJUv^Qð' ¤Ð q»T° šk¥Ü}¤ ¸`QÃzš"Ó|§Ü||@4⌠&b¥ˆG•afÇQ¨ÖzÃ�±„R° â 9À9ñ–ƒQ¨Svf¾æË�MÀ�áÐÑBP •À:æ›`Ñ¥³ ôÁpì“pö4¡À”â$ÙÐ3› u u–ÒvYR©Ó ãÐ ó  ^àq0Á�Z0opÅÆ!Ñë¡H%< pr0gx†ñ�n@bð@he@@#ê£jк` ž ý ¤�&ð Âþ°&Ëð ßð ò` Kì°â¥uG&ЇôC ôðö  ä¤û&Éw2в( �’Â%ç‰YXB¥å3³$g³¹5[¼µ*u,Ÿ°ýÚóI+Op‰>´[Gd\?tš G$\ˆ\ r Ê ^W qÇQ  zÅÐú’ŽRšº5@lèB,6_ ÌMFó¾§2Oá1' Ú`6áJð¼hÐ »t2‚ƒ!ÕÀwPù"Ú03ðbÖ@z`/qB ¢x D°ÁÀLVZ ;Úq€ÝpxG““Lhàq0ˆÑvA}'�âõ¥¢"à�þ{0SB4]!f$H@ ¤ efû.öU·zÀ.1½ 1¢öíJ+fH€Gß âÒŸÉÇHѨc—¡ö‹I‰”¸”þ  "ÀåÐ ÑÒ˜s ±°ó¤ “Ðjûw @óÄI:ű�Õ ó ° <}•SR©Vi0QF}Ô†ð Ià. ÁMÝ ZÀ S;᱓N50A�.1,7ñÏV�I0�I„î`¯o`P„:r…p:B×íÐ50 t A@Ó€ëA`Õ{oõ(¬ñ 2°%)t ™IýyoÔbdH0 “@þ 'ÉÙ`ìÙj,íÒþ(ÕŽˆ’ž%—�œ(+¼u°x*Çr9[Ǭ²D:”`«²[Iô\&R+¾%ŠP„*Z[ï4ÁØ23ÜÊ h0]£zrà� ¡¸"^zðοX3ïÝ–1%ZZcGFäÚpI¯äpÔ5yÊ  Ø=]ÁÖ‡rÃB}}�àVÁ,¶š š\.c*©|G©ô‚{fÔ·»|°e‘2k±|¼k pM7YeÙA»„©$‘2P"2àâ,%™LzÞ®¤HÚ|9Aö/Z' çtMú¢8‘¤@—õçøþw9§£©Sž”z”•–oΫ"@UÀ�)ÕiF P€ É ²�MÐÒäq ¤ÚÒõ”ÒªViâ!ã£gPO¢PiïaÑy_úwi °Öã .à; ûâÐp Ñ=à’QA%lò°Gsê.}ð}àÐÀ{ðÈ� eà€ö*ýî€>–ÕP²q@Ò%�A° &�{- ºÎ¼Žoz0›*Ðñ@ 'r 1Žä°N ±Ô 1(*ÐÙ†òÙ  ëP P2p <x $¨Ä¡ ¢HPâVî¹óÀ£Ç;Etì82äkÖPÞþáђǃ'1c>hÙ‘ÇL,aºŒie•‚>AûÌ(&ÇA1+zЃdTŽ4VZ¢à’>ܤD‰ó®X5t%ôŒõÀ �h £ª§ÏH Íxƒԉ8Ù*€ç Ú“KÀù˶Á ïâÌàQ‰�ÚVͰö„mL=Õô8yR¢îH•w,£sûΪ>¤&Ké[ŒT m¤¨™EÒ€š 6Àýs§·h,`Árâ„2Üô<QEÙšnÝjšáK ‘;wjX H…ÛÚú8 ÇÁª;%cá㤩Íz´ ¯1ÖÉ¥làä¤^Kª=Èئ•4ªHƒ‹*ªà¢Àþ¹ppAL°Ó°ðÀVZG‚Cš¨À&È¢“dæ™Ç–.L˜§Y ù°‰S¶Ùeæ© “N–¥•mz”‘B.ZÙE‚m–à`‰dŒ0"–”ðÉ ̰•*ZQåŸW^Àgæak˜"$ô@‰èº¡ÆJä‘G,f@ 7Ä`å•2Xaå zéeˆ!¾øÂ•2ú1‡#¸�{ö…tÔ0fŸ}ŒÁç“1`‡[¤©ç› º)“-ª�0õTTSEdØÂæ’UK ÔµTE&a¯ìiäQƒ ‚¨X(V�8àP‚¡‡ŠH—‚J þ)¬yé¢ €™b ¬)¢#‘^JéÜ´mé šh’©Ýì^b× šnré&m´a+´±&(H¤e+hê)9ˆ€dt  ³j†s@Š8&à†ªH#ÅjÔª Ääë£4ø ô -pbé‹›HS,¢Pæ„(ÞACå‡Ëw•J`«†”ã³*¬rŠ×1'䫿LÍœx'¿`„ëƒ> `§›(pyí4ÌCüQæ)²éœl‚±@δF™4ßFƒˆJÐÛLSõÀB¸'ªA㓳�¶>°¨o»j#Îmx°ê½ÐÎæ°jøÀùKj ÁP4þÁϬÐÂ'-<]Á 7ä@„N¢Ydžd¤©cAD9E‚*P„N²…‹m88%– *бGEwPu·‰¥Ž ŒØ1Èq¤2ÃÏ)l¾x yÅ gñÒ€~ú¹õL4Õnø…ià„bˆ ‡M´Ðà-¾ ‡ž^ðo©ÐÂÊ03ô#8‚H,C‚(8Çð�°€�¨…<ÎÄ`XFW#LÕc°ÀAÝ*®2f*\é 2€è†Ä‚G) Yaˆ@ªu à¡Xѱ B,Š$à Ö —5.a pá —5P!4ãBIž0…—l«æþB‰¸\R®ºÄä&1a6Øážj°�5'hJ1XÐH@‚D ÏxP*'‚™!.nÓ‡U@Î*ìàƒ,À‡±˜i:}`‡|…hÃLè¨Ëøâ�\pÇ=È y²‘8X�†U‰äf„=Ô€š©ÆZ.“ì,g†Msä™Ð Uƒ™›Í'n85PF6.”†HA {qY6fàŸ¬I ƒÍFÞILâ œÍÜ…p}È×ÓjÐ â—¨A5´Ñ€Ô€g]1Ð,0'>ȆXX…,¤¥hB£{¦BÚÐ5´ È  (Ôb Ò(þ�ÑŠ`ØÅƒT…mœ‚hÒC/„ õ( ,¥’“DW¥mˆÂGRòš0¨9Ì î˜‚=BXà a8ÞäÆ4n3ƒ @›øÃþüôAÐOZ GË@xÀã‹2CÜ1f5 ``C;žp*XC ¸DEØb*‡‘P†ÖP ÇtW½¦ŠTx= ¨A�t�”:ë'ÒCƒ0ËQÅrVA⬈X«"é Idð‘Žh¤ZdIC2’"XÁðLHj¢€'ªË]&YWgØU¯>4 ©É×u9(€LiÊûÀ³‡¡>òAÃ*9Mf |häþÆI Rhã1›Ó0±k&\üc7äAC8I\(ÆœX EÓ¬âÞǨŒ-9±€Ú CtÄ$;Õ` Øq¦z¤ˆƒÊ‹ÿX “F6¸1G.…ª`h aiþ•Øåƒ6¨!Œ á¼É<Ìf<€v�b\9ç*b2x³š‰Í×°,¤æïÀE° žì"Øð„%°°ˆ:è´ ¡“Ð3S—Ð 59¢ÏÌD¹pƒ5Ô¢]˜G’ƒ$ QøCG&…ñ¶‘æMù™¦kªì$˜òhF`>óN)zM à/øÀÖqyG4¸± ¯ØÄ?þªÚ§^h¡_‚´ðLJa8TX/@Ö\àA º0tp‚SËìb´Ã¨¯ ¬^ïÓˆF¨`z‹á=ØT¶�H�0Ü1)ËXJÀ�C‚c ™È©ø×‘´d$ßòˆ¥¢Úz¥D´âº¢g4.•¬6Œó²ÉÕ(¯T`rh@v%“Û¦X¡ €Dä04X°,0JP  Å¦_õԤœ^\(·½l±'Ъ1îT£âý‡@9ñX:ò6ŽÔ €ÐáVކ“«XJ`S[–�<�†5ê‰]G:€�7.fIK4r¨€i’þ‰†»4›°lqR�âiÔ°Ùy œö:¡ÃgÁ‚yÎ)ÊXv¸iÚ¨†wìY ã¼³Æ>åP'Pcœ¡Î;°` ,4�kè„(Äd);”J5Ðé*$:';èóXƒ,ŒP€,Oh¦PD!œÉ¥/uò”>g *(C`^éb#™2 WðÂúœ€ cXئ„Ñ C cpâF0ªš‡^@š‚�#�¨!°!†‚‡;>}x˜ÁëÈ«”¥ƒYD =S� "ÀØc4§êu­ÀàzÖÀ6ÿ SÕ+$� ºH&Ký!ºc@CÒúþCp–x”j9–kA0Š 0Â0Jzñˆm9-z¢'RÀœx‰Žx‚ÒÒ¶œ¨wÙ–›è á�eh€UÈ}+†lèŸ(’Ñ«8•wè ø‹³†åÐ.=`RÈ 4àÂy°Ü.=ؘ¨$‹’‰¸K�4@©'ZBBm(•qh¶ÀÂU … ø‡xR,—P R˜Þ€³ð� °'39 @H ÈC’“9AƒÐy¦‰±{‡h�vh�,8¥(�‹i¤§á†8°™ã e ™xù‹‡‰Ç:=à†K&²[\†@‰ãƒUp¥Ì›(þ·5�E0‚mx2'« h*‡(k2—’ÓQ ™©%È‚SÈ `Õ)2Ô"b,Æ)s))¼' ’œâ�Q FãYæÉ‚*  p&è ¸– nð¦è9aàa°�_˜€!@BHBˆGfH…!àS^(ƒO`‚\0€æ«°Š>?èŠ@hCS£ì»ƒbàNh‡KšU2?Uqkh¸< µŠ¡òC•é‚ Å"ˆfqä¡uP‚}0ƒ1è?’c15‰€Ë"êCвŽ�-‘øpوؗ;P€D¡‰ì�ì#�#t‰þz‰—'¨� ƒ&)Jh'èC8Ÿ@¤ÈYŽ\Y…izR@‚X…w¸˜¨! j@:«˜ã" «˜“úhœˆÉ Ë(ZËé˜Í€Gz«±@°;08íP€%"\˜;°¥µÀB ”§)Ø„T2 Rèåª',ðC 4™hºlx9a™gÊ9!G:)0‚ ˆÛDظ# H¯·9·¬�Þè åÒØÐ�èA4`{Ò$êÈ®j`Oœ�z¢Šj †;=ˆƒX’]X‚yP† ¸–‚ÅiVÆX„2ˆrˆºô”€Á{&[<“g,<Î3þFcäž„ª¼*’mY#ð‡(™E ‚�Çk1 ½r$ÛÛ&§â`ƒ|ä…KÉ…è3ø´ Px0�éÃw0Wø‚+ðƒ½”À}ØbX<hˆ`¸òÃÈŒ|–ÊIŠÁŒD1�x è‡hCIJ1hƒFÀ?iÀˆ(j™jû–(#Ÿäˆ#Ð"-Òpi v9-xÒò©�1ÊÀ0‚ÀÏx@—(iºM 8C`ÇXH@ƒ†Q- I ëÌ š¹˜›ƒ*¯C‚†)B"{ ¼¦!ó Ç8©'ÐËkZKøhš¶DÊþؘ>0 ˆ/á …;x "@ƒÐÐ ¡q [e; †`Øè(ˆº×hK\P†³‰ÝØ]8–[D"è„PP…w08ŸC²³€Nà�U‚ax ìzeð¸+ †ÅøŽ‰Y ç‚Ãt 샃¤'82yŒPŒa€Ô (Hm ȆX(›~¥Æé‰… =)X € IƒúLƒÁÛ<ÔYFøLO†ZØÖaf´ÏíɈµOûÔhüO}žV8…NpE]²J ‡WÇH€ ±nÍѽi˜\øDYi‡F°wP¬Š`9_˜«±Z”0ð?(?€‡gþhÓeÁ #(¶"•]c¿\RòK�)º„·BR]éƒåô@ØÂ†¡€`È„˜ˆ}PIê?‚؃Œ¬i‹¬‡�@�¤>™3Óq1‰qQ�©ÐÀuy‰7e—Õ£)P#ÑH#v©‹Úª –pÜ' ™‘‘‚™ª�±ä ²åŒU(†`N‡Aƒ´IŽÍˆ‰X±Þ Ö±à¤¦zšŽU­@\ø$òPt¸nH/˜ ÄøAÖ”#²•‚XˆƒaB‡Ó Ôµº=¸ƒŠT#þÚR½„7À"è¸b�³à §{Ëxš "؃ p€`˜L²u.ÔP.r=§ìÒ“Ù "À®þƒQHø‡MÈ]Bâ ‚8ð…CWm׈N²SÞa^J¯'¤ ÅH&&×òÈ‹–Ñ©PÌCô”OŠÅÅ÷D)b<Ù†¨‚uXÑÑX‡5^'ï,�Xãɼ&¸‚"¸–U¥Q!… h*›\ €"õÙW"N"Š p_ �{ˆ¾$` ¤½‚F¨–R;"ÐhY®U­åZòÓ›)E%E•¼Z%'p�Ckx UA_  …(5<p8è!%h‡\ø¡fÑ[$šˆƒÐ,‹"é=`P8ý6ø‰£L *Z­t‰„@ž8 LVÊÉþ­‹Å%DÂ#9H°#`‡‘Ɉ>ޤ8 àŠŸ#Øã†R4“áxt-Â'|šˆŽ›Ã8ˆ™·!œT² $pËa˜“Ä.ˆ…óÐŒs}Έ«9æŒj°‚–eꎀ«kð…»™€œ‹£8 Î$ÎÃ"˜€=xË€°ŠZŸƒœÔm:°`¸š�©�9‚ô †RDè"ð ïŠ'ìâ†b0²Ë—ïX…³hRx°k’sÂ,`ë:š10¬�p„]˜ Q³ Q؇-Øy)æÉá]ÜE‰‡1<ÁÛžÒq2c|Ðë‘Sð‡þCà€(¡&ÙVrX…ŠH€;ˆ'³ ®š†l@âz®=н© iÇ+xðƒ7p +¸‚b 5Ëš6ˆ€µ‡[a 4câkí¨¥Z³Š'0"ІSyŒŒA{†x8†6ƒ~(ä¢>8d†ðãd Àc©¤Ò]†Î’ ,‰Î*‚7¸„q1JŸLÜÕºzùŒ¥„Àv #©\#—ƒbpƒU#Ô�…A­Ýú ÑMì;j¯VUÕ¦"ܳÐB¾>÷±†Ä×´Ù0$œóE¥2ÙË#_€ RÈ Ö¦¹ƒ¿pŒÀ)Å ¶­ «ôJ8þBþ ñfÃèƒ`(ߦ“ÓÀWÜЙ \+†{æŽXÒK`(nxºaX×>8åCÀ»¼g)”]_ k`9á`k]~£É.!Û˜3l›ET. øV ÃY`›%pGȨ†aúäžì©iöŒ²V˜)a YÎc³]´i›n(–F1c© ¹<ü”âFè„ÝÉ‚(‰…%XaLO˜�kЛ«^K3™±™MÇEä°¡†ùóp€MÐ@Ù2ƒ7ð…?Vx�ðƒ0è%H€Â,%8†cp‡Â±õk[Ê/Ajã’Wh°ìÀ+'൨ è«c ؇›þŒ[%°Òþ»,…ÀÛ.MäœD)P‚¸�“èˆG‰qaõ;`õG6m‘°¢Ñ*#. °ÊMš/*­�Ne7h�Ýb ;rhm¡Ä€ˆ‰¿«ˆKÎÈŒh¤GÊ ùj‹K"NÛ½Ù›}B;œÅÀÍ8¯8P† `Mne±6´Î¶—U°'KXŽ'íK˜�Czšq.{{>˜xÎïõЧxJ»>à1áx‡((ÇḘ·áŽÝ}0«¹gCø‡ &9X€Ã¹9±ÚÛP®Æ1ÕÃÔœÅ8ëŠ%™E‚a6§8@(�U˜…šŸÈm–®2‹EŸ¦ÅÑÑÅÍ þ"¡qŸÏz¢.ò Ï‚+Ϲ؛©_¤ƒS`�:È‚­gØâ¹+ç�*—�ˆ/¯ö2‘ıH›Ì¥Ø'>Ú  ‚�²4F@…9ð 0-V¸�01˜¾P?@HðCGôU¡èý Fוjƒ  �8°€�žÊôxàô”Ûup‡cè‡ÌV«!@…tý1á>“ø•x�‘Ð 1ª}›X‰“øÛÂÅ¢mù d—›ØJ@9€„Š;ˆÍÈHž#»´ë†É'ˆ {òmàƒj(t±8Ci²%/KfïTx*÷ÁyK_8AIŒþ1DN�¨'ÔÀ®Óƒ„¤ñÉ&„°÷˜ €x‡k»bïÐX@b¡˜¯b3Ðôáf!ˆnÜ´éQØÇÂ*mH‘âó.[”lʸéq’ñãADâ|7a)«‘Š‚†:t«Šq;AJ:$5´ñ¨†ó]3¸¡ÁR Ô�Z…F&\"r„ •C•ªPÛÒ åÂ%Ë6µUÐÂ…[enܹoÓpÁ›¶ —V\øÆ›o•VvßÞMs8ðÝ*Û–øãЖpcÅŠ·qàÐJ:Y:K(ܪæXK–œÊÂÁ‡tzjèa—Ò‰@»UœpåK„?©RôÒòå‹BZ´ aÄlþÈ‹01Þ„!‡ãˆ?~.$X‡B %P °Î :�æÏ£?ï$=ûöéiëѦm½y@ökë Ä“;Ê›ÇÇ$|`e02ôsL.Çtžài§Äí<¨wx|žwàq¸�B¸N%�óÀ—<`MEøgÅ.òÀÃV¨x‹<ñÄ;î˜cŽü=!ãŽ1> #AcކH!GrÈ"$}PÉÎ��ø;NTƒ‘ù@:*uä|€4UO®MõN,à45ƒRÌ0ƒOÅa QÕ¬bÁTQ¡è CÑVÔ Hˆ©M Z¡1ÃOœ™�wÔ`ÍQS)DŠþ8à@0%ÄÎ3¬rœ |œ��¢ÍFè&ÚœPAdc µiƒ…Ê ¡ )}Ôy £hÄ'[qpSMO¡!TJJYŠSEï€dYÀŽÚPÂG˜¤ø² §e‰5VY­Äµ(¢lSY`÷εM½÷¦Vãð+—bU„µZˆÙ×`iV½ð L×eY|šY0JàÅÅc²Åô¦—´•0&  ‰Æ6üA=œbÜ®ôbÜZ¤2„:e„=1,pľ”!†ë¬Ã�pp<¹WµÕîeÉ% Òš§)zZAJkX–òyþÝ Ñ+ëAb#4Ð�‡v†¨D#¹<(5PsX¡‡ÛmâÒ"–0Åw¼QćÁC‘-Îx¸ŒþáXxŽŽó0Åü‰ùåGêˆ$ÈAz1}”y5¬ÆÎ›±X€…ÊD)ë©D›m_ª„h5ï¼ÃMDàâÔ;ÿüóÎ Šöè QJÊ%¤À†D5Ü8ÐzÕ ± Tƒê;)€ £ÔQ5yt‚°ïÄA7à1«qœ°J5|`q‚úDNšrCʈšÐ¦,ÈÂPFòÃ2JP¢ `Ÿ†aÁ®pêùÑö` dC ñ»•j@½;‚T}B gþ€ 4ðì°Ä ¢ ‡ýðà›PXÂ2 ¨b¡Ð D±QøÅ2 i¶‘D¹üe‰üš‹ÆÂ|Í%ŠJ¬‹é2ºä+3`@g*A �Œ-oQË à‘e¡ըͯÊ :V _ G/€óˆâ gCøÃ® W𢠸�#áÁ W9a˜Ó” ‹½eH�öxB–TçIOÞ¡A‡Šqºb8 }xBÊ:ÙWê§|@G ”pŒ1ÈnÚN.â±´½íƒoáéß æ·u�CD ¸Ã‰¬Á8=à™{@jMÿ‰GŽ;\ç†ô¨it˜+Ò‹xÐþ‡jÜð“]ëà ¨¤¥(Ä"ïÂ�IaGò`É Þ“^ ¤å„SÁv)¼²á¿wð€6òù¢ÞY `¼æ#úŠ~Þi¥Ë"³À*ú$«(œ (vz‡l` £@üžþ6 ËU`!>ðIâðQrc¸àˆpˆ&8 |¸U¢�‚h`ãy°Cƒƒ1`ŠàPÆ 5RhC)J!Å*ìD 4XoP50á;8bù`A '(%rË,®Ø—]ø£�KHbb¶Ø1É+Åõ¢Ä…I±0õ² ÄFË ö0ALß² UütÇ8ªÐ‚þΆÂRˆÅ_þrŠÓœfQ`ǘ°äZóÔ&_°z‘3䈃 +ü@{¸ƒ‘J¸�<àáò apÓºÓïXWê¤:«kž{b³wXÈC q:"•çAº¡A?%ØN0;Ä¡µƒ(X‡10€an¿(Ð……*¤¦•`™Õ¼„¸ù€ a ˜‚ Š ƒUSG(Â.a ;N›EÒæ(7Î#Îºæ©ÆJÏ©‡Uô“Ü`Ê Y°ž1ÍæK°)ðÊZ¾.½{¸�^f0”Çk5 Kˆ H„Ty•JÐù%‡Î€àF¢Ð€þÈB Q  p‘lü#~:SLÿQ“Da¨'p@þä;õ€>0B6‚‚JC8@yK­2H€…†š3† õ€†“ ¡£^¥Õ—tŒâjôó€&¼D޲%�Bà°Æú�d!bÌL S˜]ìâóBlÀƒÚ%Äâ’éë ›Øf4öcÃúª˜É2Vb‰…26A‡P´ tðGdqHtÂ_£9í³P�,Ч'ù¤ã$f †`°A:ÈD.r1`ÀJH�»×1`\Àfè‡Xq{A2ˆÐÞ§ `hÛjÔ1zÐQƒé]bzÑ´Æ ŠA„™ìþ!�‚€–Ñü�ÂìØÏ:tÑ7÷ÎW;cxÜcàwC ŠC4…#Â-*ÂŽîÀikpúà Α‚W`ŸK®ÃÑ„Q*Çʼ}�^´x0$¨˜}:YÒ]Ó6øÌ¸Æe�;΄`/xï�Ç?¤mWÀCëQ‚”äy’O˜Þ™’(å è”2•­¼fCÄ¡O3ˆ˜Í¾<%s£dÏÆ"Òœ) ÏQ±H‹d#P¨Ì†NG*4Ävú[:MÈT øâPx3œ£úä°[ KCM¸:ƒK(E?¤pÀ¦;meW"Ô9PMs½ UK€þÕ÷òØ«amš'. 1 ÂæÒ0¹€Ø=e²èýUØ_!X(²Àìy@ ËhDqZU`|°}-�œ�>ôA l /xñ &ŒA)à�¨[v°›‚W?ôÃ5\Ô+ì01à…�è‚�@Áq –¬%ÝÁ%ô+L@1XC0}@@7Ã-è ðQPÒÊ}È5M#ăvìMƒDÍÊõ…|œ2•È%(@©HŠXA5Y4Q08NèHÍ=Î9Ó†‘SúÇÉ£øÒœ'}UAXÀèÁ%èÁÔ�IåÙ*Ü:XC£€—PÏëÌÑþ;±Ãë É;Õ�.HAžÕÀüÊ*tJ§dÃpÃSHAiíTùÀ‡¦pÄ|¤LFÔÐ�ÉÁœÐX’iJG…$8€çÕŽ·T6à‚¶’ÕXœ6Ì@pЏY§œ$YC] œ×l�B|K1¸".ØŽ×(ñh[ÕÆ¬ šò¼“˜¨¼4A%([ùÑdÆ8ªµÂ.ø‹á…ыǑfø‹­-L^(_ÀDÑ__bFeH–ÁXFø›Y‘¨ÅB't‚,tÂ) F^´‚U„a>ÁÊ™�ÃÈÀ,à€|�ä‚Àƒ°‚8|Á\þA”A\+\GŽ$smÇ}Uˆ%É@5¨ÎÀq - „=\‚ ÔMà:¼Á ” L¤—x€Úì0¨À>Ž{=HÓôC.ä×}¥\†¸Wƒü2HŽ5ÄTS5©È PŽxŽøˆ`N[úȆýHzÈ${KíQÚP”�Ì�ðÌ€´ Ãpld—ÔÀS(™|ÀÔ•)ÙšhC ¬BŒ(EA .ô¥[}™ä±ÃW ù¸ÆBpC1ø |àOHµŠ@CìAŒ÷È8¨8ÏF(Eà£põIU�.x ŠÙÜ ¼Â‘™.àBÌ€°þÈFÜ<‘ôõô‰ÄBÐ yTÄ9éG˜@gWAE bAôA Pc@B9PA²…E²…†Z¤ùË8.Q_4ÃèKAJ ÷ñË8TB8A8„C%´�éK®ÕE=6FÂÆÀ E+p@,¨üÐp�j¸_+ô=FЋB^Wz؇m¬ -%€°Á Bm}$iRøÁH ŒŽd;Ì S:T à ÀJV—‰ÁN�9ƒ/°Òš<Á°Âz�Ü‚@€7L5` 0à;Ó Þ`Ó€4B?h‡;ÀÁ>\%à“ß�Ž2Iá‰3­Hþ†ÙÈŠÔ)奆% ˆ‡ýˆ’tŽˆq Q¼F ÍÀX} 0 A+ÑÒ—˜ lé¥@›ÍÀ ,B6œY§€„àl@* ”DY@O¬^DÄ`„JÔe1 Á±CÄAíÔ€,ƒˆ@0ÈÄ�õÙþTD0�Q8ÄT¬B@Bh Ø"ïÕeö“ø.€.\0P϶X� lkj;�B¤©Dø¨§R…×pC ¬;ˆ¤!Ëô<Kž]¬´€zVAguÌ.<Œ;’#^ìÂÅ'i<ÑÁ°Ú[TPA9 À+°Â°Âh‚X,äT¿þF(4Ñd8øý…aÀ‹a�Ũ†ˆb,lƒ¿ºßÌC',}’†íB+`CÁ鬄舖M0Ä ?ÐC ¤‚+ˆƒ Ò5Ä( À¨Òú\€ˆàÁ>œz‡�\BP@��t­Zð€ üƒ=hWˆÀ&l‚X+=Á%L@‘¾S7L‚•Ri×¢C<åpñ¨D‚¸CÉ1eÓÜWrȇx\‡tˆdeÓ°ÛCæé á8Î䜾\~áçD“’\nÑñ€u5"~|ÉCX�D} VÈ%>�yEDÁA D PöxŠHÁ;Åsr yø®6€”uŽ )gYþqUªJ­à©XC@‚ج‚pÞ ˜,zŠ5\2`ê™ñ Zà‚ èj,r4@Mª Jˆ�Y€Cñ0¤5æ¡ÂƤ¹bD7Pƒp«(€íxÄ·ffåQ…)+q‰—°Ž“Yƒà‚WR§¬'gM_+dÉç;ä6(¸£{Ö'ÃÔg(„=ˆÃºÂ�¨02”Ã!P0À Áð‚Ã&ø@½ŒÆè‹)(öñ…®éÅfdmƒ?dƒ˜Æ`ÍË ì)ˆ£¼œ†ª–(X@{„¨~Œ(-Q@D�= *˜B<|Â5$Ò5€ä‚„Á„Áþu` ÀA#ÊÝ×~C°�¸Ê ë‚mz¬.�m0\Â2Ã&ü"Û€“¾ÁœÈ@TmÜm×’‰–Í%gö peÔjÇ>Ó†äZÒÊù$»=�¹ˆ3•4qÓ6q¡æø[f“ã<æ ‰ž~eu ü™“]ÏœUÌàvÖŸmø.œ€öV�îž%Ô�@%â0àÂód”2p ï¨DìÊ;]‚EÄÏk¸¢Ì€ÞÁCÌ�¼ƒ5|•ˆ¢ä¥Ã] qCªn¯™¥"0 'eÆNxžÀ$hÔaA @CÚŠ€áY�Ú|)p ¢†7p^6Ìþª²@T;¬ 5`<4b|Ä­8pªN@2B ˆ-¤ñN­ì¥²ÄÂ) L(pã€â…ˆB@9ª…(t°A’FiL\°¿´@ÐøI‡”C/P„C¤� A.\Á&À&|¶læ'Ìh†jðt/8t‚iˆ‚¿úkèËÎË9¶B6l�ÖØQO�ƒ/\ÿé@<|@¹•›@?¤±uÌÓ4 C#À1PöÕÊ@VAé«ü1z�‚QpC0Ø�1€ �ƒ5®þÁ&|A0\/¼ÁÄ€ ÜÁ¤D(3-­I>X8Ó¼ÛÒ €1þ´x|~-.BÈ �%±Û„IF4“6å2åF·Ðe’ì)Ÿ†Î•¨“3ƒ”0 •´Ê X@tZ‚~ÐÑ·ÂØ°Ä› O±ÌÞ¹~‰$Ò 5T‹ð:a”¦T¤ÉvŠu–6ìâ@ ŠºdC›eƒ¤Ë%(ºîf,¢WÇ‚d«ŠuÊ¢E6X€<”VÄ ªà|K$ï6UÌ@6ÄMuJüôt~Váù>3НB*"¢ÁX5œ‰ÅŠP*¦d�l4pÌ_Ül¬ãÅ6XÛY¤¾„ö=h܃H�ä›&ÃØ–ô‘Å2ÀUWþV R€l‚øƒZ„õNSŒ¯‰,_Ì…ù½‘\p@¸uËz°«EªéË.ôp|nC,l€2 -å2u$¶  ¨±¥÷ƒ—cóèƒ PöÉé ÜÐvjñfs‰· 2 �ÜàÎ�ÙþAØÀlA,+¼Á„=J¤÷{`ɘôuÙð¶oÇÛ¾ñèsy›ŽöM„„œˆ°ÈáàÜŠ¼ÁjNtK7Ðá6¥5шZòèä²’€á'±CŽ×ˆŠ°Hb5pm¨D ®ÌŒ9@˜ Dêao ÀÎ’Õ� ˆ}|]÷ÜI#f•¢8°î–ô*œJª /NpD<D1(ƒâþk¢u²~ yç&ˆ�4 uJ"°ˆsYèÕ™íTÔI@Å;ŠŸ÷Y…54â;øÀ›«¥t•·Ø8šÄÃS £Ð„ QKœÉ‘³�Hà"Ô)1½àEF®½£=F,dAƒ:ýy¨Z@ÃÐÃ>‚™rh=X¬™ïÄúÁ+œf_Ü,¢cFd9#ìhdA,„ ¼ƃV(½¼õ.HÀÍR9û…_¨EAV�5�¬Ì¥©Ç¯÷„Ž$uX‡Ò²B( 'ó¶ìC#4Â9€2eïÍv ®}üñ=UÃ%XP  4e«€2=À·± Ð:9þø>H¢ˆÞñ%iñןì:§®ÉnOÁ–6B;PíâöMq_ÈÝ(„�·ˆÀ›FûÜÁ�j-·%‹4¡5aŒØ‘H‡y.‘(IuPPäfmÅGhîo1}° \‚/LÀÊšwª­²À­RH´ñáƒD$¤fXPX£†=OªãfCmÕôê…”“‚¤´‘ZÕ§OeÙ²É)¶ŠGUR&Ô@Ãí]”wÁ¤‹3á·‡|ºa†ÅªUhd«€M =ZkX@Cê]¶8q }ÅrâD…|H)s°iB1`w.͘F!Þ‡¤¢ÄÁ%pÆ*RZ«¡Á'jþ ’*‘8”¨‡ puN‰ÕŠKšÌ­¶µª’4èÌ¡I“æÂÁG,¡¸pæòt•*­–,iÕDÊz©z ùòEÜŽ/äþüI¡¹–W1ŽøáC–²œwµnu=K–mŸCs×|½U–%þ8Hض-‡Xª8ˆê|}WË﫼nÍe¶f.Û”Qkü�ÔH›;¬¸ãŽ"ŽˆÁŒÍðÃŒ7ìç‚ Ö¹p%dPá˜sÎQa<ŒÁC�%.Là v PÀ]|FÑ)á ºf  FdÀ]ÖÑ…G%¦�æì ãŠ/lfˆlhçŽ'Lblj*!ˆ¤�@GJ@þL0KH B%Ü9†wð€C P�6•XÓÍ:ít3Ã:×I`Š­IðŽ¬™âBŸ(ôŽ)žàáþ,ÁFy˜ôŽIµ¢Ðe4SKŸˆT�´9!) ÐHˆ¢â¡„-Ñ‘Ñ ��‰j¤¼d\g …‡'t¤j�±è#Š,Ø•”j ó‰]kÐF'�aGV$R‰”dõX…›U¢p�ÜwÞ™!UR¤Pk,¡ ƒ—bfpà>œ`‡,¢À¯Þùg“&ˆ‹>ªq‚”ƒx"°ÉšwäP&а0èþº¤†KHAƒ‚qgàf®†Áe_fPÀR¬Ñþ¦†°¬šÅ,€–±è¤6ËNÙeû:­´ ƒ®5fá Š÷€NC6Q8¸ š+´Ðbˆ^(Õ/´(§*Èãë?®ÀÁ7Zhƒ:–Øå²ê^K: Ïb+­¾ë¶9…ƒ¼9HO•Xbɳ]ZE¾Ÿñï¾ú˜Ö̈ø°„jØrQ|yãݹÀÎÝÇž ¦˜"ÒÈpÆhÄ“FÚØÇ˜ÓA˜ÀÔƒÅPuoqFnlÄz,]—t‘AÇ#H] ®¸‚6"ˆ€‚ €Y y´dž $ÿL�^¿¦¸P‰}tC 8ìl_9ñDa;QþhSúQ(}È"4}�E˜T(HMê‡úS¥,5À)XáP•Bþ„)¡WOÐàî\ä„>dÊx‡HRƒ˜Ä¡zÑä4¢Y¡c  SªRukã_Å [ðnàå<ØØ®�Œ F°—œPmôA…%L5&  nÄ! høJ¶¢ npƒ_´�FîнC޳ÀÒ¯!ý‚F€‚ , ÁH°8B± ˆa¾�GÝ’zeq–K´X ¿ cŒHàÆÐp‰è„z(L,ðÀZzñ€‚ û´†gîÙÆe037¡y‡þ4UP8Tápà<nÃÓ®#{ ÇÄQàh¡*ÁÌä )(Ã5ÊP ͬr ¢`Ï®3ÙlC;¡ðÎ)·Á,¬†ªPçyÎã3÷´r—£ùÌÏZšN`£J.š‘£0÷ ˆ! ahG?0à%˜Èt¦k߆¡½Î°[“j‡Ž�厃¡Ò0FFõHF¢€=vD(`<€t^J€=ÄpDà ö8BÌ´¡%€@§P†øÂ÷¢Ô®tëpÇžq÷Á©N%j“þìW']Lá~ô[ǘ…¨XRSÖ0T¥ÁI}µQ:TVĨ^•€þ ¤Ñ§2*«b(c&àðÁ;î@ \üÃ)ìà´Ø‹nå'ÜPáä¶RZã.3xB SuE\ C+%#.Þ‘•'�#fxGÄ¢mÝ¡±. €ÃQ@–WfЗ>‚4 #$ÎV@Ű�;HqeÈ5D®¤ e`‹|`“ùâªÈ^ߦj¨,Ê"‰”(òŽ8€+v 0œp‰êÁ ,@zŸ°$ñˆà6° ÑØgpµYlèæMÙT¡ŸñNþaÿãK¨LϺƒ™Vâ Iø‚&Š£ ô" B%8Ü‚J„#yþBüÐ|³�7ÅT|žÿÊæœ« Úk“P„Bªá*ÏÓJ¦)NÀAfÚiŒà"@T‰FExƒä?ä¢A›C¨éêwíÃCÇPA";c¸E^j+KP©`C4ˆG&Úa“^Õb`+Ä`Ið•ÀðÅÀç"P£8…?öªY­H|OH€—ÆÔvè v*Q‰šj¿6ù£ß¢À©BiAE°FDMê"h0¬“ X'e fPƒ±þªùx0f=`¡*àŠÃ®.kTƒ…}ÕR5jº­wL€´ïÀ ô`‘( Ê%¸CG•œÀ \�%d: þ­Û%‚YÀ±p�È,�&îZãÖv�{*ðŽla²¸ˆÅ ¦k c„ƒQÆz* 4¼¶XàF¬í _Ä;Û÷´Áj¬b(ÜèµmpÚì:Y窱6„ø¬Uƒ(Ê .j0ƒKt 5@;ØHDY.!…GLKÀ>÷åÂ.�·´Ð„"ì E+†^…Pl#âF0þàƒ,àGp°Œ ’p #§Є¨á^ S äHÁ\ád ˆ�4Y(À=n _¹½8«‘zhZ!5·ìgÀ›ÿþøÅŸ§€[a ÄêU`z@@';9 ’ÁþèL7¦ú]yðÐæc8äo2 oOÇ #t\ö:‡'h04â`… ÈaƒMøtfEzÅèt�hÀ"–‡X„ÂÝãƒÀò·T‚ Ø£o€‡®‘ ¤ÞÓ•Žê›ÜtéíïoÑÿãA5@Z‡5A‹2+¬¹Ê(kxú ŠÊÔ¢B©¶ª ßMJ%U††(¥J‰dA-úÊ  ec& .Ž-¬å‡f$U\H“>fV¡+À¨*fÞ¡¾¤±èè¤âvLîò/²á´pÁTHwš­X B¾Þk!ŽH66V!‰2)U°à.ÆâÖc Ä‚¤þ @¦~m&ÀÞ®Í0â `*æ&bK‰²E·f ´¬ÁˆÆKŠØá ÞÊú Œ¬A0Ž([ªN�6|n6¶Apø‹nˆî3®cèÄ©r@là|`vLIƒ’  )2LÂî ®ÀÄÉZêl@À†;¶¡Œ`ŒÀ6úkðdcqBƒ ÆAˆîÆrÀ*�þf à32#ðÞðþË3®# X`@f¤%Â|ÁÄÀHÌ djt¦@¥ÀMðÀR§CÎË *Ø$ó(€¬¡ÏJF€†¡DDÔÀtAì$ñ¾@ÊÑØ€ ~à àUþVᬠjaæ¡æ¡þFVãf`rlØAÐát€l Äú¡}ºÏ}*M ®ÏÒðç 8͆@í ÊOÔ%S"R*Å«T ý*åOÂ*ÕÔoRÚ ªáŠ”Á# Bc.ÁVT³a�õàáFÂ$&€þA&”´hª¡U–-@†ÒŠá£¾B³ÀŒ¾D#bb’våv,�W+bÁ¢`4i`4‰Â$ B"º‰, þAþ!ï`ŠR‰Ð ”!Õ)‚¡`„^«ä&àF’¢�\b�¢&F‹A‹b!€aWÈ+[¨ää@úÀþ ”å¬¡ÌØ¢À¾Ç48ã=„†i:ñßãè| Àø!>Ã:„fXÁ ñ2ìѾÀš, X¡ &�AÂ!3Z£2ñoê©;dãîþ.h$ òðÆÀá²’V3„L3^,eÃ3ZCl‘§fäŽà |! ü€Î@ Þ€9Dç ítPàÊÎá:Ä=äËà DŽ¡<ÊvÆÇ]¤ı¾ÑË`ìÁ¥þ 6á6aÔqÙ€¬A@(,º@æ Ö@—`ÝB¡Ä,A Ú!F àa!ïì‡Òš ©.­!ÏÇKîþà jà„TRlÈÌJS¨R¥Óˆþ˜PÌjÔºêPz%£œÀ"b‹½6â ,ð 4«¸TƒàV$b¦JxÀrâ�ŠªÁZLB\ºò¯.ʯСÌ‹„J€$’!ìm†²1ÁDå& Ž�¯P ¸d$bŽ˜Mdâ^,â!f`ˆâe´ae Æ"@ ú€@®|�//!‘´p!, Šá&“´¡TŽeŠT¢Nà&XÂ%*âJŒà ´A²8Ó°ª!eÊ(ࢠDcqLç4£¿<ñÇ®cY¡Óo <'h4Àñp3*aÊAžG†€¨f8H@ ö@-þMã  *`* ¸#ÀïïBQ%€:[ ;r�h–€ï5q~LœŽN6¸`Þb…|¥b 2' ¤FE‡tªûð ó<a·ŒËàÀ`2!ŽAôlç@_ä d�H€T@4-€Á G7ŠCB›„†À–`"¡ –sü!›.Eÿ ª–x�€að€Ì`ò” ¨°ÏÒØDNj©æ§Mä$¥Åîà4Ò`3µÊSªÊR<Å|®TýP€Å«…ƒX5*Ð+Lf¨)UA PÈLSåTbE“¢B"€¸ä"R¥ºÁþÞhˆKV¡"RR#ØÁMc ެEŽ ñz•BÐM¹AäÈ¥UøâÚ "Új h‚&P"‰ö(� ”¡bAË¢`w¥++¼$1•Ñ�L²E"” sïbJÀ¤@×ð"[(B¢+'çQ¥Šh„¼­@Õ|¬;Pó;=ZAãÆæ–€n+q&KCÌàÌ€z!„�Ä@òÀkò ô÷¯ÀXáAò€4h£j¡’ˆ* Ò ÄiZecZ$ ƒ©Ó<â.R1ngYŸSKxa¯£€ÍÜ…sà¡ú¡AúÁ6çDêBð“cÁc A¼þQ¢<o!h@Ë.!VVŸÐÁ‚t€ÚAxJ'€.A Ä ^C#€ âÙç �¢A xÎ=²ÁÌ â� (ÁV|dÀ 4G=/NÚÓ”@Ò{´~2 OM¬úäJýÄmÕŠF¤I…ÏjSè¬hS¾Šƒ†ÅXPY "Uø@. Ùˆ@¤ ”!µa #Fb, ¹b&"Ü´`n!ªáv*‹&%=ë!ðÈq©m@  �T²bÐ�"òÏÆh”yµÁN µ,À¯¬E!,B!NÀ¶Ø£ P‚TÐx,~ˆÀEz#F!þÌ4&î%¾~B04fœ‰œqÞ,‰,ØdDØYÐk#6bö;8ƒY¥h\1}[ BæÕ•~®œ”!* ›^cF1  a ¦¯SàCŒ¨€™@¬‡`®!àa(X6Ó x- áø¢36§4x_©Ó3ÎC=pia•5Èêãpì<êÉú€YÈäàa^¸Æ  ð M0ÄŽñ“C<ÁcÏÁ¼ñËJÄöDh€  ‰edj) l€ˆ( ˆÞ€Þ@A.áúh ŽÍêœ$ ;âf–`²A`UᔕA,w€aò¤zþ ”àŽàtêGNúXã¤ûêä!¥:l±¯v¼$Vm­$ÅPbmQ åÓ¤W4IR\mÔ¬SÂê’ù "’-†.*ëŠÀ‹â ¦+„\¹·}kà -Fh»®«&Â+"#Ðá*F N ŠØa-†-(!ZDVÔ ¨ Nb\ÐË»@ o p¡,�„þ¤€ ÂZºA¸a,h)p¾H\°`\¢* *JeRæÁîH‰< s­’¾}@ 2ü°€Ì’!\K[$‰"¦Þ!ds°ßƒä&ž–YA#o x„Ù÷è:Áêþààp,c�.À�   †`úwÁF8¬úw´à Ì.š �›¼ oBaèF[€è�Ì7¸Ê)*À§õãÇÂs6º©3d±›²àž`…€sܘš© jÓjCp”CtøÔ@«ÿÓkÛ�¢Ú!zfÀ@WöôÌlH ¤ÑÄ ´l dÞ`Þà0gP¬KŒ.;ÎãèÊ© ÂÍœN¡ ન¡Eœà²„Dª. Χ~²OûÞ‡Òy©RêJûGþ2eÔ¬*«$Ô…€ %# ¶ÿdhw˜Í °1|òªB°Y Jøp–hÒ"„a.þ­‚&pá[C8"0îÀ ¾wn"UTT×krªFBÎ"-VA¼€àq·�È*&z²$ÐsqA ̾¢V¬â@æŠÔ© T!2Æ+¢ Îbßbá.ñB‹fîdav«^¢;ŒÜíë\8ü!øy H|ZÄZ¢¦^¥‰¦ÍÀ!9O¡6þF;ã;ÇóCcàš Æ…Ú:àCÚÎ2n�,ãÞ  ľ�Ãò@ô7ìÇ^R@ ÄÎÞ@'e<l¾‰ Ix‚ÃÜî9à²ÀÀÍë)95ðl§I}¯£Ê³©K`t¬‡þs*Ä .à Îçt&ÿ>ûX³Ú½óèD 0�v‡îà÷ÊZ@hd.ìÁžàþ! Œ*‹@aV“’¨( -ûpÔ)Úˆ Bôþa*� x�J�C.d 졲9×ï„Ò>›~B»ª 媪€^[ÔÜ6AŒý«l¨QX;¨µã¶ÖB…V2 ¢ ¿¡Â!Nàà!"[Î0ÿJ µ>‚-ÞíHf ,88Aªš6 ÅVéAW‚šUÀJ<™R,ø"¥Ç n¸pÅц€I'w°DY…„Ô; Új²`›2p V{÷ÍŒÅâ(sPŒ”¶þƒ²a³ÀNŸbRÀmÚä`†…Ÿ3xƒä Ö?q.YC,ްÊ"é¦G…wÜ´!'ŠÈ8ø´äÈIÇ'ì8.üx Ÿ…€LšÔ.ã,KêH®scI+.\ZµªÂ¥J•4\‹ná/G ǘ5kÞÕj×®{+wì]ªúôcæ M„òT WIH*þ ÙA¢LV¾‚ù z3õ*­Òp®j›gëµ·h1.T%:8ø;ÅaI,ËŸÃk÷LŸóåËU¶é×¼M3vÿ<QB\`àS\0Å‚ëL‘À‚ D¸ JàGÇsÎ9ƨaŒ1p„¨ (þì³1º¬³N è8¡Ø‹0Æ#:42ı¨‹2ï8PA,±t¤!²€p7GÆ¡¤2DÄ̾\B"ˆ@e0H‰%8á: �³à*–9á„( Iâš#¢ �…JÄÙæšiøÄäySð€ç<äɃŸ<1(†jèwªè†ZS¢V*ãI€Tã„Ùd³È ÂX@ )'(…¤Ì@ŠL4aÁ 7qÄ¥‡¡z°ˆ0Ü‘@ <fA7|XpBÚ8)5ÔŠN ¡OG¶å³hp# :OèÁÃ*D8`ÁLp]ć6ÕÔÀQXÀlH¸¼c µþ<ñ…PÙ¤…Å*ÕX R6@3A¬²Ê XPmTeõAÊ*ïìñ8JZ`˜6€ ÑÀ; ̄Šè‹Ë·¤fÜ�~­¢°HH,q7ì$¦5±ˆÖŠ~´-qk©É'ÚÎiÐqˆgŽa×Ú.ޏ&Ê ¶É[m+ìÂÀa°Fe|AÎ#ádM½hÑõZ¤BO W¼2¢É·ÝÌÛHÚg›YW_(-„Štø£Ùþˆò}Õ'ø}ß©–Å.ÐÇ/`2zA<0¦‚6¸N„ ¬'û4²!‡Æ`L:ÆàÇ›q¶Ñ†—#AM_—Æ~iI~a³DÙH þYœ"JïúeÁ(§ÐI'È"ÅDøòÄ®DøÌ¾D·Ió€Ð�%ìð€Çb2¨$žIgœ!¢@>#²¯DŠi®¹0»Þ9èÖ�ZDÖ èÿ3Tø”¨'LÁ …‚TŸȃ"4 €ÇâAìœÀ$  FÀ 7°@ j+ hÐ7^2µÊ_ÂÖBj$9a¤F,Ð�|e‹F<¨F­x  4ìʨK[ZTƒoIK5àEð¬Äárq!)¸²ÅÁ¸¸ÄHq‰*C ¨€2d¡ŒE<Q¤(ÆÎr–aEDC5¦è�U€¥« EþÞñ°(DaŽ!EÀ “a¡TŒ.|È ?’v-š¢t¨,X@z�„Ë�`%ì,3­Å6p¦ÐìŒ:ŽŠ´qÁ5°|Íln¦4¦íârˆZšs…/h@•(N/4ðˆ<Œ")ÈCÂAVˆA§ü¤f²àm&<ôÝZ ,dÆ=X›h‡¡y‡>ÝÉ5ç“…80äq‹œ‚(G&Ë9(BSÀÃøöq HtQˆð&wœ£ ºˆÐ*6 ÉMÊî¡&¢�~ƒšÛ8ô³Sôg`?8 Š&ü#¶ †Àt<�àPÅ!þ:AÆ;Xãö¸€„¦ „\̉M0ôÉ>]ĉBò‹ŸŠÀCʰéMý§@Hå©R‚ ¢úD@¬Rê~Q ¦œ€ ’Bì%XÀB à„Ô ˆ—@C^r˜`ÑäïH×F9¬â"ÉËFÆjtФ)D)†’(XÐ/4A çø üË*hx‡™â—jŒUÚpÀ?ÎòŽ=âb—(b^e‘%ÖÂ…—ÐÆ*ä <Œ‰>éªÀRð¡eÚ胤` mH‹CQ†^2ƒa„äp±À_£  MEeh£_ôÐ $ðA¾E‚I„± ž&3˜ÁŒ)QþiÞ4d!qãÚ.šV˦‰b¾LsÄ)d±€W”!jÏÖŒ£e&Ó˜ÊLÄ€*´7¾š‘OzçÃÏØ>‰kE,ê°„shóÑŽv4 î”8êìÏ…«Ð„j`Ë@y’œäxzÏ¥î*ª‰4Ô†ND¦£ÆpŽ}�C$D—QKœàбÈA~ZÑ;¶ïÔô¨G©IåÀ¤ˆIî� Þ­2Ö°‡ tê  )¡F]“1L´ö±ïMtB*šÌD?•€Q€ÆÿòǨ<á)PÖèŸV)U©ECJ"†rj¬À¿Ùu„F0GE•±‘Z%¤ Gd«þŒ06AÓ‹ÀÆ žLeL Ũ†&+8®'ÐÈ$z˜×;ø@»jðáŠü²Š^ºñ+Ž0ÄK Ãí;¤À¯w¬àFÿ~â�Ø�,Ùõ‰LÞ9ж'íƒ.q@hÀIµðR W â¶�wõ¢‡jp£MñK¦¢ ‡,aÑÃj 6°¹öÁešìˆgÛ:Gmðá Hë š…]˜2h9ËÎßÚšùH ¼¨y¥|Wp´ÛÐ76MC\Xá_\Á9eÐÂØ‘‚GÂ8)èE/ȱ‡`@­ šy;33Ït¼œsóŒ$áVøÃðùp}Æ)¸øÀ Pü³ þ»QSäf<&Ë]sƒ茡"s( ºè@GtãáxX…%¼äP&Ë QØ]PLÍÞ!.Å'†›:#,…´p £ídÁ²&ÀXýbz^æP08µD'‚ƒ1Ƨϣ"•NgœŸï„@B-*‘TŒا¨Æø©…¾½íï7(C] #+7Àñl´ë­oQ†Ör•™¨ªrõQ6ÀQl0/Y…hÓe\’¡ %P ;”áepC²€ Q®¯¨ «Ô€Á7ã'€+»3`ìg€†bpcO‚Ð Q@}E H€Î7 D`JB/¦bDX;þ"QQÀ¢± 9¡À “à%ƒåkG"ÃÅn$Ó� PÙE} /R1ìp«~Úb£¢0ÊpŽ!7:ó`<Ctì•®áô…_±! ³t\p{ð ¼ lÀ$ Z@½€…ÈÀ  ›À^B'„×”6‚ó7(Ö6ÞAe¼ƒAó7GÇ9 <9  ÿà–§u•×v“p%° J0&ˆh9˜!(  ¢'PlGdÿ$"m   3á"~·d¤ ý<Y@etU€evcy³ð9`7'V/QpŠå`â JB¶6þ B!h"�2Tì£O â&nòSñ“&—ãgÑ@°W(%P‚"(Vµh†¶hŠ@@ƒ²@2â%³�è02 êâAÔpö×Hq «p à ÃÀ ÈƲ0QAEØ—€ ቜR^Öé�;Ñoq° <€*y…õÖ�ðVyD.hð0ï 3 ¸P hÀ(à!ù1„Ì2 �G2Ÿ"^fŠT ¸à#>À3± hÀVÔkÅA°/1/`Q‹ ŠP µ€Ö°OPX‹ñ,õò‚,B Â ì  3ÀoFÐq&bGGk³ÒÄ®þAK+€r´±–°±\p Zð®@l0ð_ðZð_0äð {°  ¬4‡'„Æ—tùAM¡@bÝTŠkø7ô± y¨iÿð6àvCR@byY-0B&ˆ!rcŒ(z¤#Œ˜ÈOm0‰q"Œšƒž@€À0Ú Ÿ¨%QŠá%PEM[§N°Ø–göp ar ôpbqP 'œïµDà"<àg4â‹j‚Tï#PqGPE5"?¥&ëP»"úc‡†'�dS€ò(ò)UŒ¢(ŽæTw`Ö0NE(—ÒžXí‚:¤[ÄŽ¤Àþ��.Q05°”Ö0nÌr h\s´ 3iߢ²ƒè`nÔ•Õ Y.âüWZÕ`k.ñ1:¤C%á[¾Õ¤0}©Uh@|D@¤°EÖÀ3�]Ê  †¡/Á@;J*ªfq€ ¯Â YÁm¢•¢ñÜàY;,}°1ï æÕ† '@]‹  ¸PÕpÕ~J–`7!x£X€HYJ \ _Úñ6'M±uEW–#w_±L¸¨M#§@rI®@…x9š <÷SuwXMit"&„oƒMA‹Ú± ¼Óuƒ—NÖá•Fga$uu>  W7 ¯¨þ#>e×JU� à©"¦Ù ª'!À€>æc¢GgEv:JP#¢9mÐOº� wÀ¦)$œLœäh@ Šp üñx¥8x¯h7³ `¡2 ç/ª N§ÈÙ0 ùh á‹™Ó&è)Œº@!Â8>x†žy¦T2Oh ë@ûÓ@oðù31†'6Õ(øóŸ€Ò(~‚(‹ŸU‡ްcÕ`I¼Ö"H�}†Á.3Ð.R.oõ¢ÖúVäR KY-má[4a,�;Á 9éYQDŽh^‚Öð@ %¢+ á"| ÿ,æbyÙàlce}À«°Èþ“1Ü€%3€2Ä& '�‹P|qp©"“XrÚá�OÒ–À–À”�Qp$¤� 5p ¸`ÿðYQm· Üêé·§é–nq €ØG*Ð-Ðtªñ!–ë…ÕÁ�$–ªÕñQ±t4i™–´±¨²8y@Wà W°x© x¹_ð À�t°br“aù`#7óÑÞAxŽ™9`™ý‘˜ññV§iQf7W—ž© ª�š%V>pcÃú ª7¥Y!'Bg"s6'¢>B¥"æ:À`­a+Úê%¥­$c  °•¬ñxúц°huD �ÁåWw0|U  Ùþª Zw‡� y(â+!á9"F%ŒþªÁüJ"¬C')r°Ôxó¨°ú©�3à ‰æ'7%);(‡æ'­W…" Ûz…†( ;Á™2ßÂVZ =q¸ö¸0{:B<áC$ üçÐ'oz¡1S‹kÆÕo‘-R+�AD  |-‘V‡1EóW.ÚWÀ/' CXXðEÊÅH¸V5gšA±P}B»Gh ¡¤ðA“¢ås} pjR�[«hDŠ ™yR¸ :DŽŽKŽ€ÙЪ x% ,Ë[ü‚¹¡JT·˜ƒJeÈSF€ed)3­àþµK󕺬»–¬Á�å@_pð äÀsÌÓ€bó¡Êˆi^pÓuˆù¡ª•Ç•7x“ùúÁ>@|>À¡‡WgÍ9 Ök½â1 v b+%P›&Òc "PêÃOç€E>èCPì¿Ö*»rk ø"N@ ó€8üÑàœQ° ³ÐW¾à�r0r`¯hÀ/hPGÓ<3@±à�š"ú*!r‚:ÿú¯Ïª>*:ÀØ&e Í(’b )»wÔ±Œ’h @±òÙ{˱w0iYµh¸h)1Ò"Ž Y&Ô¸Ðop+„*xµn„Ô³3À [Ñ#`þ]¨2€,´$Z‘Y/‘, á"%àð›ðh`y!YðgQPmh,©2IØå*¡ , ,²° †Æk Ê ÖlÍM D 6@¥ê"\0×f³Ñr ïæl)ŒG5p­3`� „½xd]+ �¤€ Ù`G~t§}PMà�›ó13sÁ›åÇ ¥–©Ñ·<_¹¬ºk™4»À9@°s¯p,Ƙ bôq^âÝÌÎü¿^÷†ª #ER8ÍöƒæÎÕ«ÚÛ«U0Ùáä¯ ¾O@?"L¿ñŒ¬±ù!Ïꈲþ’"B…:ûp =¶2 Àp @`À` ¶ö‰NÀól33€¸xv£ rÐo@X"Õ‰/NpÙàª*<ý^†ð¦.uO¦©OˆŒÏZàoÂÁ¦W>lrvÛ(ƒÖÓwÐ'Œ" ²wh�ôT‚"UO¥öUïÜ”áØÀ§×&drÐ.ò†m±Õh $sB= OôÝb}42>Ü�ÖÕkÚéHæ:”-Ö°F› ÎáU1Ý0Ôå� ªG¢V.^‹'àC²…R0RM� ¦ D‹ °$ZG™%G| HÕ è�whÔ$Ð�‹$0}P “þCp4jF1Ïfk´ƒ*W1_º²ü›pE <Í”9ª›kJÃótO'®ƒjEKEƒrªKr¬+ T–u  аr� › 1%§´¹©LÞã_åÜþ;3î$0 –IbÂt…ca90 ³pb°Xwˆ®“ý76@#š7 âËB™c:£"B5gtf"Ï*P#"�À!p�á� 2`aÐ@QÒR~ÇPÀ©¬îMeû.ͳÑÌã€D€xÄ ᄜäŠb�ó󬥗ŒÃh:ï°ãó¯D.?*rˆâ;‰fS7Ͱ†v’'vŸ ${Ö° “rÔþêT\¯Ô3RoH ¡ÔE|PÐ'´T*ÖÊEß"1–äAgz—{E�·|má]za¿$»H¢2±Vd^DÏZ2ù5��™”I^=wÚšügÞ‚³.±‡½ý¯EÕ’% %«à`1 «Òèx„}Bm¡ÀðÎõmÏ{ä‘’Õ÷x=£xT,'«`0jÄA¸§1qßN嵞‹Jœ!<ïÅÛ ^2J¬ñìg©–³¡–7SYuåÐȼ[ЧMžkîsXbÆîíáîÛ ±`F éwßþ u¿;7á ‹­Êµ �á/‡,þÒTÙƒN!º .,L Æ,^ÜwÑ8 PŽJŒ €£bŸŒ)xd´Ë¦] öJ ÓIΜ yZÔ©ÊÐVÛŒ-ªU:ªŠ¡ACÄÁ„&¼›@$NµUqüµÊ’Å_XtZˆ ’õº €á™W€.%u¡üHdȉ(ÖùEáغ¶èxܹcåâ‹?xÂã'OJTn™ÇæÃÖ&–üyq МyðDíPµj¤”e‹òŽO5=ÚHÕ¨öĉ“58ÑãZ }°X fAØ;e 9ˆýÝŒzÐ!!¥‡œ»ù¬B¢©ÙÕœþpåöN›ðÛæ‚Ik\ ÏX5#ý‰hf¼³/›af p‰C \V郕&ÊÁ)ˆè›«Ð(f9Ò‹ƒ4,èƒm´YųV©N=f°@>à# ø@C)²™>³ ;=j@CD=rÒƒF4jQ¾ш#»È"[E U8ئ•4Zᢠ.Òàr˃ŠÚ†‹¢Ú†K3s.va³Í]îYa…{îySÎ9E1j‰Xb9å”3ÿjK/ÿ$”Ë*Z eB ¥ C¹T´ŽX–e‰::©Ãˆ bá ‡,T§UýÒÊP8ða–BÉa›%V­Â(¥NÝþF©,Zî¸{'†xÈ¢sÚ0&£Œ,ꈣP"©ÙJÂãÖ¡¶‘xŽQÁ<ð˜¢;@Pó)'@"9¥ÊZÏÝ&,F­Â9xƒˆ`ܸd7ü[¥˜b|©¦)B!‹ƒ²8`€›;K „þ ‰®@Ò%0àˆ˜.$Vb¾þ¢‡žXl³Å"CìàÆNmŠÐ({BeÎ4»£³ƒ­8ø0+8{�5ÔV«‹ *ˆƒ pCB›ê²­šËô¨D,Ð8n<,Þ F èpyçUD‚…ùèÉ òXÓÆ Ð`­6 øq¾Ðaš=xÄ‚7Ç—Û¦æ†ERÐþ柂™@Š`ppnVÑPƒEؤ˜ÞV1DûŠÁ¢¾éD`xè=J�„<Õ�ლäаÁ‡„Æ‹°àC$V9¡G>pb‡”³µ¹CÅjøà&Á>ÖRȉK²Q…mbí²P.ÒŲŠS–8K3åBÌVÜdS6W¥ü9åÄdÎm*õÇ5Ï4î ¥ûD¦²Qîru ì ÀÔ)*°(ŠàÈF6bA*1 e fÁQŒQæjE+Z•Á*1`<áU¸Ð2`\À"…(İőÀa^FR’ºÈ@ ,ùK#TpŽD %�€% �þíÄ kè^­e”,¤+]U`Ô?X‘Ÿ ÄaV`JÔ¨<¡+ŒÊÂ@ð)< ! S˜ÆB‚‹ÅE ƒÃŶFÀü0ShKCž` >®ìd‹™Œcþ(L¡2"{e¬Q„ÄÄL2VxÂÁ©3ž c7ï�8 ³¸Ù¨(\ç1šÑªQ<)„*AëÛ;â U6‡ò!€â °�€�e5Êv‚pƒ6L«¸£ÉÇXˆú`64LÀ§›‹†CŸ8¼ãÆ0.ŒÛ ¡344 MH CBˆªñ!ß½>êà Р‡88ÓQ@;€yþ¨ŽÝÐQsÀ nÔ`m±#EÑHA9ã°`'¨³@Ö¸‹4 Ù�‡*þ‡¡®P…þª§%ù•ôJÛÈÞ¡²p >êPlúž›ä$Š{ÐtN7Mž(¸ Gį¤^òiý¶w”L©UûëÒúšè¿JÉb  ’¢B‹*%KÛðFSu”Z¥zÓkTCÁ�kè '=‰ 0ÔjŒ6Â…hƒ Ô ­biDY%‰cIh-%\@ pÉHG*¢Ü„,˜Ä‹H‹S$Q`Y RX²@‡,@ñ3àA3‰PŒj¼ƒ`ilC3RÌ  �SÅ@r� 4œ±! ÀƒD"Lj½þ1ŽÍ¢X^$æ—Œí¶cë8ã.¡�kÜÁ—(®hs˜"L&fË Í"¹²ÍH21Ÿ¡ŒÈ(YI' ¡>‚­£�8,8›Xs"E!ÊàÏ*Ѐ5 p#=ÜðЧŒ8ôá7»aÍjH5÷àr'=Q×n‡ÌèTE5€Œ6ªa OØw¤��ÜXƒ„Kôæ›þ±Š~¹qy Á3ÀE‚t¶B—fk@Fÿ¡ÉW²ƒQˆ‚2^£Œ‰Z->zQ| ß ñÁwð*OD  Æ ª1=Üá_i(S–â(.c9 YêXNÁ황{brDLÝDÓðÑÔþNwÂOç'(¡Öy{C‰RÌ<¿CIM•’8–P¦*,ªhbcY ÖÊ{� Ó¡… šÝÉpO ó†KÜa (ØÇ9R¨‘TdAµ õŠ<¸#¶7ì‹.àÀÖ}¬9€<"A† xàÀNð“÷˜˜®Sda FÇn"† øÇ t+ü!‡Èm3à¨UHCáeßá hËø±‘¼Q$p©ËÅ܆iL„9ãa&ó„"$·H.¾Ÿ+™ƒ!Æœ^…ɪ{Èy“ŒEÈîf¶‹R€£¨ÿ°¦Bö™@hƒ‹þ±’fÀE³OkÕ苸± Eþÿ‰ÎÖp²#¢;–<«yõœ„ÚHQp@6>œ'Œ2 ¨èŒð-'P™D}Èšfp P`7I²0°q¡¸ÙMˆc×nÜhÆ´´D7¨¡Œ €C>ˆ² >§‡'˜èuë%æÓ³„"yG5€›^“IpH¿¾3Ï*pÙ-“TPZRT%pˆ tb,°üvS5‹ïM»_œâTS¤h)‰H)³ëGª44ªQ&=È–â%ø£�þ؆¤`?”DAö(\ÊPRŸ¥<ãŠHGž “aŽÐÃþ²­6´a®.¬«JP­­‘ z†$q‡JP€‡~ ëßþ7Æ_)@„KädAGúmÉê÷éZ©d!ûË<Á3°Æ¥°È6²qà p¨ ˆØ3b6 �†P7qk¢ ºÀƒ’ˆÀ¸`7%ø4Œ<#ãòŒÅ(F*>ò·|ã#@ú·U`$š9$Ê™CŠ™üC¤…㉘�€9›(ÀjލˆhPb`ºÎ™‘šã±÷²€™ýˆƒw:óÒ%Síb‡c2>Ð…²€ú§Û°ñÐyz‡S†w vÀ%ó"»lƒ¤ó0$€›¹A‚na¸/URC,°¯‹ƒØ9Øà†`†IŽœK 8þ Žèܰ°a£@ ÿú%=@&j˜@à8j�„UøD*xÿ¹ $PªZ ùá2"³,p¼S…b�Nsé’VH³]p™º<:©©ó©W,)ù{Ñ=Ýã’Ó3³;‹•Nh<#è„Ö3ªj”sY•&‚Åíé’-Q ’(B”4à� ‚9œxmðV8‚) ’ÀˆZû¾s¨5ê;µdq!¼5•؇ºÈG‹p5°6°(/K¤Kp9†  Pýi>ó¿Éš�ø„7À¬À,)Š,h°óp�(R¢€)˜1  �·¿’ÀmÑ þºX·¾ÀÉÀȘ‰àÞJ˜†àHkÀŒ;¸„zc$A’®Í¨·yC$æJìÒ Ó0 Ì0t¸VÀ? l�ÅñX…ûë´K¸_€ 40Žñ³Ñ 膑{‡§‰‚ X…K@ƒé�› c÷0/JB¸ëƒÚáŽÑ¥`Ò4ˆU [ùŠ‚(mÐŽjhEØ(üè_±ʩ¯ m(2ÿ¸°ÝÁ%=àø@2A¯nP2�R8°¶ì†’Ó‘�Ó§3¬—kË&´¤!bx=°·d;ÚX#xÃã='ª‚XP†N8…NC ”%(�c«’0[5Û…Í{þb\GXùù“,‘dÆ3é²XQŠX$=@I½VØ“XØ=´¤àªˆ< Ú=ÞÃ3WÁgd€›¸ Kâ>x_xƒ~‰‚¾Œh¾sPB؇z¡º ‰»P‚}h„}@8h>5À€Yë— †Yà„0XÀ¾ä‰j°¸ c�°Y˜v9ˆ‚€PÈ(*3œˆ‚ Z2ƒ"èƒ>x€H­` ‚ä; Vhw@‰€ ”‰6²I›Ôɇ Œ¿ø4ŽQ`À#†x‚7èƒük8‚;(`8Fb¤B:Œš4.‘¹™ÏÀ –ÑŒ°ôþPPk�k˜èÀ‚.†ƒAÓH%JüxÂez?D¡é¥·l¦»ƒ°õJ@P‘Ý80óz¨j0ŽiC'XݨôPÅýp'­Á è ˆ…Sz‡}YLð …÷:DR †„b¹¡†d:¦ã�($˜È'ieÍÙ” ‡ãˆƒPÜ =˜ÍðØ‘UžÛÑáû=ºÒ\…(£œw8ã0ÍjàmȆÊâ³/±½VYà8„C ƒS`<(¶ìä‚_ËòGè)/yO b€NyO—RO<s ät?Ò‹<+ K©�#¨p€½ “ÛûªÂ»3þÕƒ¬XÈI‡&(P�¸Œó1xƒ7pÀ»€>c˜+by!‹ØÇލ h6Ú‡1Ø”R(5<h bà„ˆÀƒ„ÑY=°{°PmQ ˜€À©Ùöd—lpíà Y0Šüip(.ÊØ„ð ¸0ƒ«m‡~Àƒ½@·†™ˆÚzЏ”Ž¡<:£Œ<=Jä#lŒ~ËŒéB$IŠ ÅpAΠʜ(o{ƒ9½€7(‘ñRˆ3bÉ8‚Ú…Ób×HJUJ±Å¹'`!‘Õj›TE|^j‘o�1MÕ8(>(M>Àž &qþ±à¬;ˆ×!¬Àùz/®Ä‚ºû@€�KØ€5Ȇ 8lˆ‚Cœø†n= À0lØß©û…iø…þyp‚ÞÙB®a’¬!·ƒÖØ �àŠ;¥(Xà ž8ˆ…2# øk#À†E0‚S  €ƒm‚N€>…3kØïñҵ<ò¤ŸSQP…eLÏÂcÏÜ£½÷ŒÅ-ëëL #Ȇ:¨’êÉ 0óí¢èÙ½XÉaA+“4°…p‚(‚íµ‡ °£¹‰c™µYc+¤-µ»¢ˆˆÁ€cˆZ8(¸úˆ}ˆb x°‡LИ˜]�†Fh„cþÀGcH‡10†( h28*(¢  $$PbüQ¢8`ˆ›˜à,)ˆV 2Ø,7Š`Ú¬˜s›¸)ÓÇ]4M˜LF ʘǘSñÀã*.{«| [݌ʓ©Œá3«˜Ë°ð{€‡ €æy«ÊLž‚ (x0€p‡ °V ‚(†wœðr'P†ËÌ?'¸Kª Qt^�`Ñb ˆ‚bh€ßÈ jÀv€�ã§éK>8¢Ó¥óhàÀ×8œ8†é�9øP¡¥n¸¥[„I (˜i0EXƒdÀ† è†Zøè^ƒEH†DH„þdHéEø…�aÿmBàeJ¨á˜á°Ë"‘Uv8+|Õ†â©&¡žàᆠ¨ùÙÅ#%³E86Øqh: ƒ‚ X), 36 F`d“õÙÈC=BŠ¢òšÝXÑ#YöÜ2dŒY"þXƨªrâ3Ó’ ªH<C“.qF©€l¨€öKƒ`(P'ø7ŸõÇÀÐ-<¸” µb!ëëÝr‡6pØO6ðÐh<Ð…xÐ�ƒc0 d chƒ1è‡RßnÐÝ&Ë¿æ€bHÕ ‚jFÉ_xˆ)x…XÓ¸‚0xæO[eÝþ]`Â]£eSy´£1]–\lÉX$•Y ézÓ̽S9ŌϨe@⌒ٌ'©Œ[Ò›HfJ*Úí{¨Ý#P� Uˆx€)(‚0ƒkè0�€‡Ÿ]R�Ù„`X%ûH±þê"ˆmx�LKÊ $h�nè «(ÿ †øK˜„I †çè,Px‘k€cr¯>@L®ˆƒ=°@œ`š(³€k=?aX†eøEø†d„hX”5‚dØ€ZP„Z€X€‚Zˆéfˆ†høX†iØ_äèƒ(bbÀêø›èhŽl¸i³‘{5^t(ýþ²€p�n€ŒÑÑ»N“.á�Ny lø…*_³¨„J°êq°ô>)³îQ“7ùÿÙ).Ï?I”V …öa%ÙtÑŸSÿ’5‰Î²Ë# ’W„aò \Y—Cáë-ó X¨ … ¸‰'`{øY7(ênc’, ­µ68µJ–0†=† Q ˜cbA‰cÐxˆÓæ„- †kg+Oˆ‡vP{h`Ð' ƒH€ßCÔƒlà�U€<È)Ø ¿² ¢®7ðY¥Qˆ"ðVî¾ ‰)`–‰@ÓXÆn l\VŒÁØ-ðN€'Xz»ƒUà´7 €7Ð\|3JþÏ`óvABõ@è7k¸mÀ.É�™ÊPæLËù »å#0ƒ~€‡x0£Ëàâ#è‡ð&È…úE"…*r�wš�Ù,ª¯b8dVˆ;°%˜š€MKªô²�KˆaØ�(Ø�Õyqv VÇltê,x/n’ø¦â†ñ¬#±cRsþ53ÿ;(€hH†:¸:(�(P(€Z¨…5PZ˜(h†iø†høl˜5߀ÙX…Ï¡¥ hÓüP%®¤%@D`²ÏŽÖ¨KU¢ $àѹ4€aú„½X8i aƒ‚å_þ°jÊŠ<§vþ“ïé„X ƒ¶.ÏùY—UÇ~Xì@ÑT§=2Ññï ؆X¨®Ä÷HËbT_—ÉS4sŒ…¨�Y©¡âp �1IÞ¼ñud %pPP¢ ±ˆûöµ™hqŸ18pèÒˆNP`€Ó椺TÄ#¡ƒ†blh(A±Oxñ©ÈUhŸ®ÝÈ[&L˜‡EY–.õW@Xa&Dmã°$:>È)ÈÊ×tèJX3æ%5Õ h g­.rçÊÀ0! `S€­£»nJ‚è�”x¢íµÄ—±ö€Çƒ;’¹3åÉÈ0óÐ\¤ñV¬Üþé\­3ê›Åhíú5ì±w̰2ãK +1¦L¹p^3=®]cr­ßÞÖмCCjšï&Ä)¦G5mÕ�8 Ç x�Ú°(«Ð$[±jà°³ a¨Ed߃}úò£p£†€HEïpCŠ…cA z�ˆ€ÔœPË"ÉQGÉ$c ÉR‡ Öq!Øl°0¿$£ÈÓüòË7&Dó¢0ÓÃxzœ¦ h|·Ê;ÚUCJÜH )hD‘3h·JÅ¢)àòÎs¤ÔPè8ñ7RdÁEt"KKÔÅ/ѬK9å¸àÌ®8£þ"BG}öÉE\J‡!†ˆ@Å¡ ÐAG~¦A¦ŸUH:)¥\´"¨§p°é6’^Úg£i*ª¨Û`ÅA(“¶²j£­lã*,ΫU¬ºÍ.Ûફ®’Ššê«»HÐJ(Xm³Ä6Hw�°ŠÑú’AI\pÁGm)ݤB#…ÛÆ9e´rÁAC.¨¥£„�xdBL:€K 5rL;$Äã‰'çd„B qÆ2ÍD2ÉÛH@´âH`²kUYä@Å+1L‘„¹ÙÖ42Æ>ôjÛ–[Æp 3GvÕe3 }õEWÎ…Ng˜…öØþc©AÙÖ”6…jšíV4Ñ™ñPj<dV´ÕÝÁ¶ulè<q˜ñŠ8W˜qÄE\ƒfÇD<טÑ^óÎ %ð0ƒ͡ѠXZwÞ'ÈQ?KIÀ«h£4�%AxCI$APC�5òD2 ›ØD3Í4òá LÒÔPÈà€ ñŸÝÈ#L$ ¬‘ †Ž˜ Ñ$£æ/F$²H-ØPŠ‘@±† 2®±!ØLƒ¢0ݸæDàŠUßé¡M ÚLYM ¤Ìà€ÜdgAhTSÍ*ZnyIýwh]Í%¾ˆE™ü!‹F#zÁsÀ�^1&´Í þ~¸+ö T"U¾JÃ8ª rã `Å®°‡/h ㇟ å(buª §èDN‘…&T ±°X¨¥BGU!¦² ­²ðªUYpuàÝ.V•+Q0qL|âª5) d…ªˆE,D±‹XÈ ¬è _¸A nðÅŽ� •0"ƸÈIxB®sœC *0jf—‰Œ„!JØÇ9rq<4‚[àD.ÒF0’4ƒNhà‰t`%p‚7nqIœá  ÆR•ƒŠùC¹ºUUBQ‰M¼!G(ƒÂ`†¤ÑöAºäÒ—µàA*°‡=ð@¯ˆèB ÀþP Ïò’—uìl ðYfª!µ;T†4D;Ú"Ó˜È$M5’¹ƒC´Í<!4CãLiž®±³5ƒ)ÁŽÀ¶+|Á²¼ÖoÚv\çÇIΆ‹> C=ÂÛ”ž –Á8¯aA'hØ„,0JT8Á*äalÎuAØÀ/ @‹ ÁyѨEô¢¡ˆý‚ “€�LaŠºÔ¥nHXŠl1;¬a º4´ˆh$b 7€‚Öȃ&Ц„6YH‰°Å/ŽÂQ=¸ÆK­ÑÑ`ô`ð�BfíR V±ŠK°ÏGiµ€ ³Šj\2}3pR ¸s‡K\"MÀþà)æE€"xk¨$^Q¹À�1ˆÞ@‚=P!á¨D $uÂqäÎp…뇔½¨à E•Ã>…¢Š¶Š…2äpà ÈB Ȩõ(ÝFª‡z”«–Šá¶BRK¨À ¶ÁG삉KXÂ=žÈÄ]P·¸¢jÅ.–ÂÔ¡¹êÄÞ0îô¡¯pæE­ ¬%fy£ (2G:ž£ w$æBlV“ò4èÇ1Ø@N´cJÿÙŽx„¤`jJ �á Xl² …%b!©P0@>à@¨b+SU!68BhCYÄ oˆ=r¶_g2¸„þ=fpKwàA¸ì%0’3ë,.º´¤`DÃ+,91NN ÒT™ÄPó3ž¡fb¤¼™)œLʘi÷´ÖÎvŽ¥E À†0²Âs‹A?úÑ~’�–ðHÀÄ…wŒoÑy—4¸×èÁ N`A1 qˆá†Bh°€66  Eˆ®€R„ ¾1º DB¿P„§¡ð‘Z¥¥ ÂçL`‹ED ª–¬o y$¢7øð!çbãB0Á(Éc32¦g‹d|ãzp(ôÀU/¡ƒ|àÑFøpVîym3Ð7Àá�4Ü¡|5pB5¸ñíTãzp7Wþ‡t jΠUÀ!@‰NO£X(Æ+v°ƒ/8CZ�4¾°(›øÃ4arhày9>q¸Â =5‡´@·UÈ‚(Z‘†mÄb€8ykEµCÞòvR©ºnv…¨« 7 Xu›kTÝàÔ.Гè«pÀÃF�Ç .•…X¸Á­IìßЂôf vˆ�à  cЋ^pˆˆ1Ô@®;âåÊcMtI—zíão<G&^²Gz"'ŽlD;$I° � kF�šA‹H@€//–*8 U,µª‚*l�L1„aÅbð…ß� $`ìø± †þ!P\°ª§Á0` ÔxpÇ. ,w†,«`5VÁÉXCjU@ÒÀ)™ÆT3ÓÜ 6—ÿ„ð&2) fÆü1sm,E(ƒ Öü~á~ðà àÀ2”! "K€5ú`i#K^ú÷aÂ&„¢þçù?¼\Y@…T@4DÃ"(• üÂ@"|-C3ÈÈ7¼J¥T2LÏT‘ØZPŒ$C"Hà $­%‚ïAPùÔ­-‚€(6¬Á"0"$B­iÈ@€ÈŸ6,: 7ðA ÀÕüTC´9¸]q.L@ ðÀs¨S ÈþdƒÌ@ƒ€‡XXÀ ø0PŸ ˆ@¦Ìƒ,€B€Â¿±˜Â¤BA/”9<‚”ƒô!Ä}Á88|Á¨™!¢*°Á3ˆ �=<â,ä@¤´‚YJÇp€jÙܨÉÌíV£ØÜÍʰ,EœŠ®,A,Ü@ÑÝÃ èƒ ¸¢>èÃ*F—õ ™L8ðŽrõ°Â´FÁÄ%„XƒÅF„ÍPR:<£1@D¨�5âAË Ó.!“ºÐK]tË 8JÒ9¨€14 B<´ƒ ð<üB=ÔÃ74CÃ,@À4(— ÀŠ?$NªÌBz)À+lÂLþ�+œE„AZ<Ó3ÙÃ0pC(à Ã-xEÖN7tÃ-ÈÃðÇ \“C$SΔ¡`$†‚5tFd¬‚8Fg7ÆÐ„†“ñ�õé0„Æè;`‡60Ù—<`�À`ŽöußX+Œ_9Ü¡ô9|AÄ@ô@øÁ+˜ÁnÜÁsÚwpÇ`lw¸Æ Ð80ÄADA,B6Dõ¼È,,C›,`ô˜�¦ý6üBJEƒaÖ ò ô„”¦­4`ÈböŽ &†,Á"ÄB ¢¸`-D‚0Dƒ¸6Ü 4Á \ˆ0�‚Ž(TàP –€Ï;þ`ÁãèôüœtüÍ€8€6<A¼ƒüÃ?x¡D€4ÇdW4A¦¬@(K1Ã&¨™PÁ#PPò!PA äAèa˜A /ˆƒ),/ "²*Ã#C0ðƒ$Þ%þ¯ W1š¤ŠnAJ'‚ʤ�Ê|vÌ6¨Â«8Ñ*bB, ¬-( ®€Ñâ.|  &—Ç„+e1°@+DA ð†\8p‹BÀ%±hGÜÞ>È�á^B¨…;ìƒ0mÌÜ ¹‹¦ƒ1” À d‚ ÈÀ"Ø“ÖCš<"‚7t ™ØÜþ(ù�hÝÃ0Ü€+Ì1(Á3¡CàÁ °¥õXŽ7x�EN$EÚÇêtƒ0¼Ã0Ì^ŒâÌ\è3ùÌ’±¤MÒ´¤Ò6,ßd”=�òmF<0ìd èAg°¥JÛB¹“6_K%;żÐdguö‚&˜_$ÁùÁnìd !; Zk°C0�h‚ˆ�4ìf6dÃ`€Î°’èÀH¦½HŒ¼H¦±‰›ˆ ðÐ`20 TYÈÁ7°‰ $C¦­‰HPeöZ$6ȃ ,‚°Š6˜€´ª …,B°ƒ;q@Ç I•ĦzdG þa¸Z Oüt )¼CÄ2ð )ÜA]aA\G Tl  üA ÌÂ,l 8€&0€4ÁtRAôBö!”*0€øA@?ÀC;È’YÐÓÃmÏJÁdƒH€mƒÝŠÐ2ÒZ~îÖŸŠÉJ&®ÊR-VxLkY…?Üš è+Ââ+Òâ=¬À=¨Ü8 ÜíN,äA8°A^‘Á+ŒAP@؃׽K¶¨ÅŽšÝ١軜h¼\£ŒÙ·ìÃÙñ(32DC!|„�x -d€9˜ƒ4d�“FVýÂ2xC ÇÎ?  �£þF +@ƒÁ‘ß\/ð@Q&À:�Ã0ôå4Ef,ô®ïÂ"ÜP$ĨJØL3‘$: ñíÓ$54Ò_h¨¤óJ/|;t/8Õ(Ôz„ek8@‰ôxêö¼†X”€hB©r§Åõ‚+¼Âøù<LÁ¤J[Ž�kpìÕ:¡ƒ!0�®"ʸE�+6D0@0ÜŽ]þ¥Œà²ö¥_.†d ØB44ƒÕÎÃT½HŠÈˆÔAÆlYˆ t 6@ÅXgæZº.‚ÈQ¥:éÁ7pƒÂü8a €Ô�þF‘Â÷I¿&á;`I—”°À*8!·Uì3õÅCP�BË2@¤€¸q/ôÂtN§Ðÿ \Àè5‚#òÃ,„C$–¢} ªüg,AʈË,K«äÖnAÊ'6íŸØŠ%KímÙ üƒƒfƒ,\ˆ ¼¢9‚`î(߀(„mtÊRŒf2dÃ?ü°-�ÃÛ²z}ÁÃ8Ó_(òÞ¨6~ÜÞ»¸C¼¸ƒB(c~%SCÐŒ4û‘�¨ÁàA l�0¨4$¬y³ ƒÖ3M¬Ã q94A9h± °Â%(QêAí¢é 4C3tþ�,ÜBïZØïÞ‚?Od7ÌN7 CGÊ@Üå ‘=SI®•‘e@Ùõ"†Ò@g4ÍÐX tôh¨¤`†àp4 ”—$A¬*û–¯ûzŸ@Cʺñ\Á+\ø”Áè]ÒwPùš&;ðzhPLìj�«Y±’Î2Ž_ ‡�fðdšU |ˆ4pȤ0¦éT·– ÛÚ­aH'ØZD¦˜�óD…<Pƒ|hdO-BÚu•�ˆwÔ_‚8Al*q´qp:,`¤‘ Ì� h‡Ž ‰I×€ø¾[ à÷\’PF`<j,eÅUœ‹\ ŒöþçAvRTB%àñøY0ø€ ÷_d µÊR€Š«,Á)ìbõÇ ²Ì™©¬Ó(¥Pâ)Ð0€ dn¼Âì@ƒ,ÌÃYëÃÂY‹-& ‹¥ˆÂ“|<ç$Ã+|¡ÑØC�í‚dB¬‘9w£5j~‡)â&®žÒ…Zl„.ÔÌ\@:¼E‚0(ƒ[®APH7ÛBŒLƒðÞôO d,?<b—j ˆ\)<Ž{\‚±Â‚7ÜÔ$�Üô®@ t&µiñÎ�_œ3C׮ϠCñM¯cP–) ôeSJ¢L6•ÆðŒÆþG3Ù÷bÆh(� D‹•»¨ôJeW ñ°Âü=¤Àxœ”=±È@^…eþé%Ì °ƒ@À:PÁQo$¸Ç  ˆ<ÜŽ±ºÈPOÙBOÏ£‹`ts&£Jñ ñDCcƒ…PærbHÜ@Z׫!ÏLB wÃ$(ŒæHEgà (ðw8YqÉW-qOT5ÀÕ”4¬‚l l‰6Äæw$ahCwhƒ`Áˆ¿oÅ:__Æ,e*<â#ö-Ó×vT\†C´ÃA,�P•· YÊuµ‚(œB-v £Í‚*Ð;nþÊ…J¨pb$ÛŠ¡P+LŒ?P¤·Ü|€Û\ÃëB‚Ž [UvK&Ü+ŠB>‘ÈP�à%��4�zŸtAÜF=€ <@` |2¹WE´1´Á3μ¶Å€?#Ìà-Ï8„̈ÏØEP<5\‚ø™‘¸+æ^n‚"P%LÀ?ØÀ?pÂ3€è@< túÂíPQ–�9×À\.Ã$й:åð%Äx&Á)A ƒX‰z]Ÿö^ó¦dd\Æ|Õ@ÍdLd(8•†j¨ ÓÍ”§/$+Äíþ~ly÷¥™ÞAü?|Ady,ùÁŠ™=þÆP³G÷²C5йÖCV0�8HA¸GóxŽçàN‹X _¦”ô U²MÏ<d`Oe ïσRÕÂî_fòD°…€ëYßšñ •]ÿB7@�¤:ØŽ<`èG0\™~­:€áøl‰­úðzp¢ÏsÌ@@É*6x”OW ¥L�–¨´FÅv‡XÁ ¦Bh;@PéõåÊäþüÑ¢IC B¨Ú‰‰Å…K+Š\ªd¬˜¥•„VUÒ„l%JÔ’npض-T¨³|Äò‘#c«4\Bâ ’gΛUZ}Ì8®Š:" ½"Á*̵\>\òÅ•_¤Ô©“ÈV2[æêܸþwo…E K:E)vI†»�Ví¹ÂÊW_n|½¹3åM‘%LQ‚‚0 tá1&CE#{©P±ÏX:Ãxà0,�Ìxö¹Ã£dpẔàQ=X³€uëOyøÁÜL¬±eËμ_'&ü#ŒÄŒa3f"%Lž°iØ6t„„]xdœG º¿Ox<ù^ŸnÞЧ÷F Ë%`SP(Y7e°¿èÐñÿ Èƒ)�P?àáŽ"ôãÏš"îHp?�Ÿ˜‚À"úpƒˆWXÁë>bP †Ž8â7Ž�ÀÄQLQEñC'Kˆ¡ç?̨‘F¦Ä�FE'œ°þ„Ç« ÒG'Lìƒ:Bi°pnši"Ù a¤&Êi øEK(²ÌmhYd5æYCÌE’YÈ5’©Ãˆhj‰S–dÂÄæl²1¢“::1­¶237:噤›I%cƒ °©3 aø¨"ІÐC@ô …mªÑ€NI±À‚¨¡mH©a4`µ€vœÀO›nåÁ =f@ƒPyÄﯞ ÔDx´Ð"*¨`ÀY!Ê™ë‹i©Õ¤-† Á "²pdGvqä"Œ²Èƒ–@ i›%Lò³v·ÉA^UÀñÒ�*£òí—ß›rJ¨Œ@jáC®þxåŠ+Ê(ãƒÆødˆT\1ã ˆ¨ Ïݤ1GiD¹G”]Ò°(‹:¢@ð(>ˆ á•$6D#¯#xCü�fÒ ƒÃÕd{f àèFŠÆ`tÑå° =Í}0€èuNSMµÌPC3¸&¬l]€¡ 1“¡“›aˆkç$¨9ï2¦Y¦™h°i&‚ð ÕìACV—ç“-ÖùKS ºñà<o…�‹ÞS‚¾ùÇ€­±æ<°À <+jsP6ðžx‚¿"b㊥ı¿e“M¿'V ^x�ZD1\aÃ?X¹b�æÅhçtþT´Dˆä‘v¬¨Æ @L„ä8ÈF™°ØàÉi~Q¤}(6 rQ.éÿ—hL8slÆ”ELþ“Á¿>­Áùûß"L€i éO|jàV¦¶­!:d8”ä! 4jØà†©¼‡"i åABw�a>Tà D*a©H‘©j¨ª5 rf€ ðaRN Å*X *'TV+ –°�ã2±€I‚A…<ä!B ‚ö…!È(!ÐÀ¾À†vÀ+×.Æ•¯,¨„% E¶qƒ“$‚LuˆÎŠY€C± I*¢“ž Ò'JÆ‘†PP #+þÆ„1àÀ�/`Cüƒ7 ÁyòJl!d,a÷ØNª ŠX@ —8Â\¦� ‰¡C pÈŽp{Á;% Oi“˜}4ÆÇÆ1‡ÑŽv£h@Mk@Î(a^ë Д ´¡É€2Æ@:¦F¶Â¼¦>À†0(pÃhÄ%jp>€�A ƒ³Œi–¨0Šv‰z6šÂâþ²+$¢“ó†<@ 4Üf[\Šg+ðÀ ðOmJððà? ]x7:Õî¹ ‘=hv„ LáußOìJ0<ªHXS¸�ò®@ŽGPeƒ/¦—þ"'p¯þüÑôÀަÀ R ½ä€>yhÉ߈Loh騀6'(DB‘øEX5ÈbL@Ó˜Ö�„?!‚µ +›:ø¤0Õ¡�Zi`2XlÈÃ…zh"‡b!RÚ ÔRÙmtã„€àCŠÁ |H(á¦J ©Þ É)•6µPPé¡XwèÃ*,ðϯE<²BDЇh ðb³¬¨rl"Sd@8ŽÄ�/þ! /È4l£\èjÉbqÂJÃ]1Âß ˜Ë&óÁzÂ/7¶±'ã…VWˆcZèA p`†þ9ðâýˆŠ…E|, ´EÆ" Ф! x‡/Ž� Œ¾ /GPÀ†ú0¢7\â ðÎ|ƵÖCí À0¸Áœ@ÜpÎÛ†ÑZ<”M3Ù$ i´ ¬‘B£ŒuaŒ}¤áZÙ̆‚žw¨<5¥a“VƒÛ;¡¦ª±P$Ô 0D{�m@ŸÞÍ¡?bGCÓȃÀМ”Ú"=XC£}�±øS ‘èª3ÀÓ Ù‹X<(N]ä² KX-Úé¥Yä'¼¡y ‚÷À ½¬H{Ý’›ke$Ñ¡ïÐá4Š?¤UfFZMP‹hþÀ©¿€ŸúÂj è»¶]w½†DøÉÅ–ë²À¾·ª PFHSé´Ø‡ Q캱NRÔ*T]¶)´ÁŽU`€x‚±€†x€(m5Сt<W~Ç0.Q `ˆy¡ìÐ÷¨œ`Ã;hƒ£:8õ�P'XÃ>p+z¡¡2ëŠCmÈ…à,:H@•l� 6Zd'ƒÄcKÌ¥ñ ¢Ҙǰ°–x·&AÁH¿öß|Á1 iE²@‡Pá a(ƒÓ¿ …^”c�nèxAà1ÀC b@CÖ [€²m7Å6ÄÅü£—˜M‹úÀ 1$þÁIH‚ðâ‹KXC<Ä Œ¦ÉâFSÂXÆ2Î@†»ÝM‹ˆ.f ƒuHíÇÑ̦.‚l 8¸Ck‡CÖà€ù}´a¥W.Le‹æ¦I�`^ÿz×÷,öZÇç„ØÑTqI€î÷MU$�Q“3Þ N)ßgßÝcÁ¬p ñü‡@ˆPôù¾D7Hâ.CQ­ .BÏáG·øá¥1þ¿y¬ÐÂ7qÔ†¯GÝ V°Ld š„ °Àî'L Èצ¬Kܧº`×víh}AØì`Lv-7Œm×’!Ä+ð'ì¶‚¬t-ÜÅM"è¾ääþ&Aê„áo¨Æô ?VÝ,�T€VA� Z Ø­V†È�Š0ßR…f�¶Â UêàF¥î`,k„¬€¾¯îà l@–ˆ«¸8Ž þ€¸ò`¨!ºè LŽ 6AþeèÒ…`8@T!Ô+bA+:A @ÄÄTa½V¢çHîà0ƒ® Î%#¶¡Tþ€r!âØ€‚®à°î’ráªÂŠALÆÎ+’AV`dpB a½âŠX.|á.f‘ŽÀDЦìÌ0ƒbl˜ƒ ˆQñîæžî'�îgzŒ4žIÒ!þŒaÁÆÆ0” 38£ ¨Qð`j®ñ5,ê¢bÕlq`ãiç=6gqb‡@bã.*vhE„œÀ<<`<Àr(€l¸†ùœ€X £FÊÐA ädw$<Âc·XäûôÀXÆï ´xÒ/##nÓàá.€è!4@ Ž §„g©´Øzx„xJ`^áƒø€Åž£Q¸´D'}í×6 ­¾JL€ Ø†m º`Ö°{-˜-¢ál!Ä®« D°hê@ Ö $žC  ŠPj Wú� V®µHA·‚¤¢àj áV¡ÞAÐþômWj€bHªÁŠÁE…xÎÐ`ÂÃDdÁŠ¡% XžÀp‘„@ò€a3;3!þ€R 39Ž23þÁ&ä èöE‘è0®Š°k vAN¡�Œ�ðp T%‚¢¶ÁçZ® ÞÈè‘ü!€3²€À&€â¡à®á R€R@ xá Ø€ ÄÌ�Ä)Xá”a+»"ôÁŒvÁ"¨@ <§ÞˆÄˆàBfñ|A 4DcÇöŠL1!¸!„ Îà 5Ȃ΀�d 1�ïÇ�Ojã0¾¦32”j2T ŒáÔà$þÛ®QùC>üñ¢~¦¢Pà™c5|ê”À¤ä. fЦLê?ƒ…,A)ç$ïÉ$­ùî@sBTª6PJABªwhKÒ0’Ô²§%í‘z´´J5òÒ¼ã Ì�h´ èá 2 â†Ç ´ˆðî l� ¬  ~äÁ / EÕ­ hÖȪ¬„MMÒÄÊÄL&Lˆ}LÀÄ‹€LàÁ8tMÙu+—íNðIL êjÚMõ@ô <dŇƒ$­SbÌ8jâ`b(†ºc¡° SÌrÝvHR ªa ê�¬€N¡ ¡D¨Aþ``È¡¨µþ ¤NÊA!z–%¨À!¦HD ‹3‘Z.$Ìås *@cN'ð¶¡5EÂçÒeèX‚%–€l³�:¡�Žî5�åü p�. D�\S`Ø€¾€¸¾€È“Í€Þ!‚ºÊ0ÁŒ(b6 L¤Þ �|ôàBøS XÁ*’`ï¬�§h3T@†a„á´É ð /�–pÁœÆò²©š¨Q+30¯3ÀÚ 3‚†©±š<ãòRC5††È^ƒS#›21âÃàŽ 0Rçb FÂT¦.à4J<¼Côqþ¨a*ª>0 1£ïÜ<JnE'@T礲ÐdƒÌÆïDДÔND2¥KÕ ŒH@ Ìà ÄàÑ0m‰T2XJà Šafì¬h¸á9°¤'³„�Ùª­6� j¡€Ì äÊOү𪃰ÁvÙ„€ÊŠMd­€¢¡MìHÝ RP6 6 k!¨á0yKT6¥¢ ²²aj€%u•.9ˆàfÕÞ¡ÝLK:ìM´áˆ?:Åf ÀA VxÄG A4aˆ�ZiBXA.‚J´@!þ€¢.Y´à‹4’%´ÀŠó#Z!‘‰'2Â\|þ€|ÓT¡ZÂ%r`ç4b\tâ ¼¶A%Z-ê p‚(ˆ3R€®Á @ÄÓè@4@.¾À˜¥^Á�\ᘠc}   €’0Ḁ(â`þ�öÑDä`Ü@“h†D@øN<cT£(À° ‚àð/ñ`á‚à°`(@X#›„lɾQ1¨±3ÒA›JãgÜ¡4¶Ö3<Ãj£›JÏô´†lì 5PÃkàdÀ81^Ï |Êm=2@Š ?Þ®LkÏJàdoÜ@!ù¬ø@D§úÄwn—q3M·—%wE„%:¿À‡)àÏþL2ýô€4*~ƒÄ@ NÜçI°ÁȪVW'kA'¡`¤„Q‡²›ÉŠK$(MÒ¬Èvé~òGÖlw(Ü$ à#¡Á¬f¬.’GJÈH”ÃÞ¡“bA– ‚�|�`R W‚A paHÁÀ&…ª,TÊO~ÊTp¡Z‘zä€ aö@6ÁfÀ6¡4AZÉ4[éA ¦Åø ÈÁö`ZöËD BAª`®¸(Hîr€_“è`^ŸÚfÂÓÅ".â ßkýá#0‚»²à&ˆ¢°ÈìëÊà á¨@ áþ D@fá4ázÀ  Ê CV¡¾¤¡=%�'ÀJvó‘xF÷–Þ hæÃBg÷^ª©f ¾aîFŽtŠ1ó¸,àì0¦©C£i4Œ¬›4OÈà 0ðÀ¹0®1i'™ôJ¯ x”1*Tkœl Ž F®¡úá¢x:2nýc“ DpO‰ô@Ã4ì>€¡ö£vgt÷«vbÇ $.ü†9½ÕÛDÈï|!™½OrÙA¨ÁŸLd©(!@á(¹ä­¼jÖ6`¬„J°dvc ›µä«àd­åt M8p¯°Ê*L:¨€äùOb!òþ¯Œ`Ùæ¡°! ¢ Ý¨çT•¡ò0â Þá²Ád!}"EžÀUN…U|¶&Rä ÈÒ¼w¥Z¥UX¥WªÁD ¡É‘Aˆ€ˆ�©|á l€È¡ ¿P¦(2έɵ D@ˆK¦EŠŽ(ŒÂŒZ%8@&ñ¨O’Î4 í0ƒ{¸š_Vb ŠS†o" áƒÁ¾�ö�4€ `�ÚúÓfA4Aô˘à:ƒa¬€"5,vAnj¥ÞôqÁ§Wjñ.æ®/àx‡qHfêa`/È€­˜#"¡þ:àNÅWÅ6#E-Ô0œÝ4~Lœ0Cš¤IõŠ j;Cón¤1Ôà¡öÇ.�Ì Ú!Ì`><>'nãv6¦€e-f¦\¦¨ ¡H ¤@ þÂÑDŠ€£Þ`Aø£AôC„¸t½^½½£Ê¬a ÐO#—ÊzZ({B½N°«ví À�§ÄJö4P{M'¯YÁŸ’~¸DØKÖ‚7Ší~Š-¾*4Pn�­Í|fìfÈ# bÁþ!Ƴ&�£qÁÅ-� N ÆŒSh W ª°àˆó½øRâ¦^V”£TYÀ@ ÝÑ÷`ˆ@/¬að‚¤(þRÀ‹ò ä2ÓYDŽèÀY®Hè ŠbªÙï‹Îq½Ba$�é²Àš ¨  ê]|nÂZø_ˆN†c˜xBT¡rà àaqìAœ¥á¦z¡Ë·ó ^avÀ¯†‚u46“Úf�|@r êdà‡ê®i&Bç $ÄgìL tA.al¡ná`ØåaØŠ´Ÿ¡(A”£¢Æii˜Rol®ñ0YœÈ©ljÇ&ôÀé=¯É”àÜ¡ôÝûaFíÁ�bݺ)Sy0%Á”0~ü¸– A‰ ¢#å@V'CNJðxÀþcÊ“#­Í°Æƒ‡ž'OJ8A ¦Ì™4kÚ¼‰3§ÎœèÐM,s§N'ì¬èqÀ‰¥‹Ö�‰f┩TýÂU¶ª&™0Qëj´hkÖDÃ6m”_@€8…j"Z²dkâ–k²DFnÔ©s#› )‹N`±P­š6˜=«!Áâ 7\*ljó 7 3¸IQf; «T;ŠNϪͤHñ±@ ÉK'Oª•¨¶Šl=zjXAŠÎ¡=ÈÊiAnFË'GÞ NH*yQ R%ìÚCµU)*Yªd¡ãïY$HÈÒ*˶m¡ªl˪թ÷qPÕ„*þ±¨ÂA(ÛT`+ "˜FƒÚÇ÷qC}Uä BxW‘/T¤1N%T0Â_<"]ä|ñ#Zðr+lLàK5}±Ä=­4ØzÄ„D7x� €$e…/n¸ñF“ XSÄ <<10Sà‚.ÆÈ€‹-ŠÀòȉ0XPÂiZ }¬bÍ( pìƒJL¡§p  €*sÎ) ] Äz^€Ç>*¨Ðˆ 2샇 xà¡© Ÿæ©'ŒÃý¨ÚÏðôcF#TÄE$ta´JDèD”À%lÃ…("°ôDJÉ‚ôÀþw´ÔcBMKmµÖÆÄXO�u-Mè8AŠ<8A'l…<Ó°åÔSn•UÖW¿|µ•UR­…YOÙ;ÖX@HÍ<‰˜€MS‹`sUYùuC"cQ RØÆä„§µ¦3`±HaX²J1DDá@gºÆÍh,Fn ÚðÁoG¹”˜QßžV ¼õR h¢I9½ˆ  9¯XÔ ¬@Cty<­åhðÈtÖ á4Ô¨BÇÊ×B{ïÉg ¡´§_YpÀ@Ûª¨BÅÛæ·‚¡äW…ƒ V_(sx7›„“GDDAwW¢A.cø!νÐ3ChAþ×Äcy—‡(­p¡_9«h Hx`d‘EPM1¯Ð¨@“EÜñFKsÄ:º¤£ G"f™”œîlEX±ü—¼AÁ:J¤C}:н.pDºý§Ÿ:j¬fPàGb”AB0l\ABûÄÿ0í‡ñ>ÃØ?Œú»Ã' î¨ê ÀÃp”ÚÑx ä18‚Ž€+3˜ÁšÂ¬-Ÿ‰‚ \ØF90%$ëYÑ·º…¦0('T!�xp: 8¡ÔÀÂN ì¥]@ØK¤a„§ŒÅ*PØ@-&• làk0B2¢a/¬´ÅPÐáMÐÁœþk.FˆÅ np FÁ Rˆò2m¢ß"E7”±ˆwœ@Ö ‚ ‘ Ã`A¤À‚°ŠoÍ7ÚÚÖ ­‘›qEËb‰9 Lx� MDRjDÛ„Zò"a:y \z¡ Pö"j“#„>I üakrS[~$° XŠÍ•-Ç8ÔF:0@³ NÜ|àpø@ó9ÐÝêV.8¨ b@èS¡*Ìâ³H—�{ø ÜœE?ÜÑWã_¸¾@ˆÃ ¼@E<w Œ. YhÂ%K°-� ÁHN�X�=L`èCíP(�(>qÞ:�<.)cþA‚0@Š8= |­‚Ç Ò$`èbÖ»ž¢²(áS+U‚ ÜñÒKØã b¸‚ÈAŽMüa§>à‡þð5D-ªQqñŽËÄ$€à@à0†<ðSXG?ú‘‹0P@"EH‚’�ÃáÁð +BŠðø¤±ØÆ.¶a,_á (™;^"­|¶Ð…|í«P$f-Æ8áìàÖc p.¬ Ñ‹Uû•~!q˜V  u™à-¿˜Æ4¾—Æbe ‹øJSLàÙl0»¸Á °(XB5¨FRÈE.v�°@ ž° vÑ�6!p þÚ@‚"ã�4èÁ%'LM5j° ,äFÜÄ�‹Žbˆ@_À)4ö€^"¼á% ë6A-hB¾,ª/0„!¤"¿å ÆÖ¢y7ùD(BtP[ܳ¶C¨Â"øé6?DX6™º!úXHoyãÙò–†*„#-ø<€å¼wc>(C  `@ $`‘+HPT bö¨R1*ƒ†ßD«'ýLŠL�Á�”@`’/Þ €X Oh($ˆp„, xr´�%¨¡ gðQà¼jw%è"¥Šªˆ@€Q@{4¢a ‚q_A¨Ð€†b •Ãþ˜À0†‹`$Œft= `¡hXÅ%2Fa�îXGB2…~\£Îý�Ê|Ñ~pHo€‡Žp"(àÉ$yB,–€ë,PÁ eÉÄüšBÀ{ØÕú>eâjÌföT¨¨Ä´<6´ÛŠ©RDµÌ *ÓX‹d㲈dì´žMÆjq½ QÔ Pc¬ðvð€–°B½µa>ôAXP†2p‹lhãøÇ&D�Ž8˜ÆQȆúp”Ùë[¼Q )ªˆ—lË»…Å žp\rìa�Ð Ç�ö I"\< Â8wº¢újá âøÂL!Sà˜¨ªàþf} t¶ ÁY8E,š0ÞÛà çÂ"°t9@BóEß&9H™-@P‡« ~„ÇØL@ f€h`CR�8D 袲‚âB\áŽ<á‘FB•‡Œ@�G"¼àK@ V ÁO²†³úÀÐUHaÖ`óH)€R ©)à�O¥*xÜá�Æð  ‘x�† ì{ д¸ B04I„8øùÏv�QãpûÚ×þÑqp@¢p|̼c35œô*îð�G}“Ó¸ÃG�¬fõ@y@C®Ñx”àý°Ç«ð€#˜Áy,Ô¦kHXã[ù$¶þýïœL"UŒÆÁ°¡DJ$ ÂP&ÚVmô²PàYX( Ló²YOññbZT$K 7° Y`hÀÕ€HÖ` �'¨�ú¶ +h Ö0ðÿ¡ àxï T”a+ˆIõ«0€PH€z x¸e„DH„FbxH  Õ� Ðp¯p{� @åP}y%°ä5;õ`QCQC½0eà ¬pÙàuSøÑ5BÇ Ò àw ° 6°6À>í³>Wpšä�þ& þ@L;²7!æuŽ T@@ow°¸�|Ù À§°þ69°`›€^¬0,R—à+1=ÁPÔE.3!xèpJòP".< dN@ ·(€ ÐÚÐ^™®f*¡wÐ÷¤p p ÕXÒ8h0 Å0ð@{à�âè�ÿ · ÿ� •ÁŽíxQ€|Ø8„õØ[’†}p Ö'gà{r ¬P oP Pfððw Ð>à'%À;G”iýàf¥7=— àV ’ö'1€Ð  ¶pØYê’m €XÑYÌ&ΖXô/‘Ó0¨e@kà¶ ÿ¢C<™÷ Kþ0ÿÐ(aPb ÍÑ$oà ¾ð&ãrðÿ°`>€ —P�|h`ÿà ÃÀ ïÜÀF†¤0„¿ÖOŠ¡ ¢qFþÄÚð} IQ8�šð ¯� Æ¡ rÐ^ï5T@³À�‹“ÑÑ ® …Ðàó± m£KªÀu3:  ±`Ù 60ŽÁ0jXTÃ'‡xˆðÙð~Ìô ¡`6^ 9ð@V¢wÁ% Y¤ZKà§�ŠªÐ '5cÀ`B±È?ÁŠÜRF> 3ð3p;)1%ÛR ²àï`PoRcõ9x•~1€¦‚1ðþâ« i÷I öiÜP ï� r q 0y†`Žo—Ž"€\ÈUŽ•‘ þ6ð `&÷ˆ @ MyÐýÐ2@3{np+àäìÕo@®ð .k)S`aÐ~p%p ”ðn™W(tF!’@ k`?ù �èYž¥/MAZqÁl³ž€Wzq1&›e T”0ó@¶ú°¶ ^±u°­° 9@¦'eÖ×$fðW²'d3�|à0 O —05p Ü@ÕøjY2¤@[z@ Üp|ܰOF’q·•q­óOAþè° ›`äI¯@rÈ ('6pJž$ t "°"@þ \° »Ð pMàhS èkЉ¢0nÿ`ãXŽ  › Éʉ²À‰°èŒ˜ññ5"Š6   DðKKPÐEÆÙj“]“G·Žp U6`1×^ܵWÑ’,E` Oo«P =aàÐ -p  „‚p « V%ð�1ÐI`� g�Ià ô/sùf.IU|R "P§²æhp“§[ɉÿ ­ ÜÐ�7´ P7t=Û�'�|b>žBU˜þˆ0°6@{{Ù×`�ÖÑ—I@USàÇÐfàJ�o`?ê V°WÃ6¤FжCA1ÉÑ�¶P¿ ØDF`·C¹gန¥D6d&è€ÝæY•e@ iÊ c¥AÐ ¤pÊ�=÷÷sö@vÊQí�¢WµµMÒ Pi«0}À Ò¹C—o¸ðÑÕ„zð=»¶e©þ|ð“& UQ– Ðà  _ЅЀ ¢Zr¬ð¬@³")P5B T@4È0�;€ ¾š» -   €÷Q7‡Ê€ Ê€#°þŸˆkÐ Kp ¢”ï!  š•éu– b` a b0‡¢P�P·&:ñîñª9€œ ˜” ¯wµ-®øw2-¯øÌÓ,OV0qR0i Lº”^»‰Ê¯EÀ ^à €Ðp í`T¥Ÿ”Ð�Åpì ŽÇÄ[¹ÄàŽ&»ŽR­`۸p” XÜ F ®_œ Ô o·Á0wÅpþ6­F8@UM{GðMS��P@~ÐìÀ° *ñ›P D@ "\¶i‹Èi Xyû ß�É–¥ Äz0E”YÔ þljQX {ÔÉÓ@»šY64 eÒ¶g‚gd„7à2úCý@>~Ь€£T‘)A—Ðl÷Gq„|$ÜÐ|€d, –Æ ë¨ƒ¤Ý »–ŠÔРʶGõX€c"|Poð {p¬à¤J8EW�CïÜ „ ϰ }†^;@‡pîÁÀ�†� MP­` j³ Ð ‡ˆ q€#ÆZLó± ¤C‡¤SLnª6§°þšmõˆz“9° n× °À ¼ÀÝKÑŸŠø‘j#K «ÛпÑ� ÔPx×Ðrdkå+,‘SÀwþ VÑR ¶jKå@f�+éCe=¡�¤Z ~ý€`8 2 …X&ëpÀWhP–›°‡éø²õlÙðR ³¡ù6G׉­™RMP#Ý MÐÁ¤ š{ZÃp@¨ÐðN,r8u|Ç=°£Ñ²(š�=Q @Ö Â‰ÌÙMxݰl¿° Ë0 @PN„ Xà¸5ÔÉ•¡|ɯ=€iAYÜ, |›ÌF '¤„…—Úо€Dð¾ ŸbÀÀäÄ 4ö ¾°~ë'¾0Æ÷±‘3‘z&cÈü{‡Å@ /q€àÀ©òþ{tÛL ”€s câÕ eb AIÀ ˜0ˆ12Ð×Pâ`à¼Pb0q Î(GÐ5ºV4T@õÑÒ–©¸æÀ¦ÎLóäÑD:4:2­Ñ¡ •¹ !ö ÷& ð7‡íqL<’tÓð'i° §Ð: �xAq$Ñ^@Ñ^º$ኴ(�v8å¾@R  6`%ÐWð¯Paå*Wµ4ÜQpeK¥TÆG ¾|† 2‰&T[ùGn=¹rL2»Å�þk²‘‘¬àð×@·GÝݘ?í ýP­B%®—¹­¢þwä2@\<ðŠ Œg P š}Èø'lž{E.ò@D¿à¶¤™…¡±>&õ·ˆ¡cbC¨Úì=€WŠ µ.¾Í0&”` g «€´. 1Pfpš@á@Ï_@Rè Q‘OfG°AH ±¨:+gÄØU¹¥|¤°ÞA@ è Ûï”0&e"ñÎy(Ü$~À PÎe˜@ áû€¹p ¹`�„ÀGÜ0L ²*®ZÐ} ð«ýá^b"ÎŽ ò ² îš~.! ¢L.þ°0=ds7B!_Ù|sòñöþq7àYp§ u! C8d;úÊq2%Ô‰Õຊ)ˆ~à" ÊÀF à ^~âÐÊh�á‡J`ПW G ]ÆwIÕá= DçEŽq M°K±à±ð0ØÖÿ0ÆyHÅn=^çhÖ{ÀT ÷CºðÐdAև߈Íwup€ªö±ø+°öwVЬЖõgê©’ë. µÐÑ@YœÜìÉ,€‘PD¸Þë¨ûxÛjÁl'ÀC Êð³  o}ðŸA#íeÇbà…ð˜c¨ �ý sW>Ä kŸoï`šØïP2H:HÆþL˜3Z½k&êÉë- }€Éè­Úò ” ¡ÜÅìiÜI ?o�J”H`A(”, Í"Áö€S•eà8´ µ#‡³pØ(¡ÕÉ]UNVQY%T•mOr¡É¥UM›1ce«Àa[ iX^ô—…æÉ—¡:rPÅ4GH¤ÛBµòhr›ÊŽÛLÞÔº­Žƒz�Œë¤,º'OJ ÀãN5µ ×& 5Ãצ/{^½ãëʰ%xøy5d›kî”\p‡A†»u5f y7!N0ÌqlŽóîšbh¸óìY  o.‘ZÕ‡H,Uªš€g(›¡"²®B…þN¾g‹ñσ8r&à¢0£† `Ñ/Lᘽ0bìL[bÊâ)Ñ™xáÍth7¡¹CÖý{øñåϧ_ßþ}üùõ­Ö Aa¨™¤› „Fž ÄB˜ Ä¢Aa4pƒÄBy(±�À,Ä�mœp¢+ † 5Ð`?Ì`åŠ?X¤ƒT¡B„^4à VÌ0 ĘÀn¢8Á刘 4� ¨ "+)aÐÀ IJ› -°€š ±“’ ±à€´Â{à‚"à¼à"蠃괳„;f˜àŠ=bñg‰mD‰Eªb’Š)Øbã€%•Zþ©Â&J§ÚÆ"Q8eÓmvéÔ¦“BÝ&#–È¢• `â`¤mŽrI©Prˆ-8PŠ¥PsÕuד.ª#RØ"ˬ±Ð(=tô0Ѭ)ì™ÂØÒºšrÙã‹xÆhž)¢õK6Øà‡ ”p§Çð�ÆÏpÁ%\Þq7^nêÅ{OàV!¥†K.¹ƒ‡jªAãŸXš€¶ã¤¡‚Ù~3¤“C:ñÇŸ„;iB)”éÑ,¨˜´ž¨³ (hä‚“Râ»)H€ô²çˆµÐÙcöóùg ƒÚçñô`‡š ƒ $ ‘æ²Á äapƒ§Þ’j©ÑiyþŒ„)‰„`¾Å^z¡‡1® G XÄG[üÕ!í‰á’¬!Å4”éÌ 4H Ô’jƹŒpƒ´�Ë Ì¤L ° „L­…±Ÿp“êê4yŠ)€1hƒ*H;.!bHÊB”‹N:% Þsˆ%T‰eÕP„¢)(.ÒàÒ¥DYbUQx?EÑPmÊãA«P¾£¬r½hUb'–‘fñ(Ò]Ñßu«ëŇ‚±œ�j° ʼnšÙÂ_ÿb@/g'XÁ/¯¸ÂX†0P [OðÃ\Á\ƒ[ë0ÊuшfÍi¿fðA1Y€¤àþ µQ°jü­_«XE1¤Ð 4A6Ç‘ƒ*ÐB ÙøÇl¨àlÂÿ°4là€!"±35ЃÔ²–h=€O@–±Žp{¤ŠÐš‚5 E”`hc$cÍ(a•Å’Z×(§¹©a­rFgÇÈãrZãC™(á¶K}X…/ÈA…<´ha(9â¦Èmn ˜EfA…=ø¡ýxÃ.Q  RʘÀ îG3>ðC‘€ÚXI¡+%è@AG™äA ­i[£%5à-·áèV´P7…u�#™ªK@t’Y48àl« õrY/6>ˆEþX”I%yà JL²p Üb ÑK”L<â©‹ùCR0‘ ¤r¢Š% o ÀÑÈH”*ôá*RÊÕ©H¾ 4€jTF”cÍ �&Š–ŠÀ™…ÕxC àáVˆáZ¬¸€ÉXQ’`ŠÙb€Ñ'®â�Ód>8  ìÐ �Áv ¡IúL1â ÆFRˆ¤�Ž&4¡ÿØ„¾`ü!C 1l@°’ ›øGYã`’k-ËÂYØ¡3�#gÅHÐ3Q"¬åŒ{åk_ƒ6‰¨ˆVZ%Ôä .IMLÃB$.d 6Nîr”Ø;þ�!ÑjôÁ ŽLAÚ4 …+\ƒ q£‚‹‚:Њˆ Ç,Rp?Ä 53 Øï…ÄÏ“P+ «G0umrX¨Ür¹¹\’i|À‚6îð„¬BG(ÂE¡ Œð�c1I]Ì” ƒK ÃP]ÂîbґԆÛ€†*r>pdA{Ê£Ê8•÷ÍT±¤&¡ ®bÒ paU¦Zïæ “‘j|Ë6s�PIE¸%,y‰„O"˜ø$ÃÎ+¯?”· )@KXìàA`+( N<8ú ºu˜á f¸ƒÄp„L¡mdÃXV '€Öð×WSd"¡‰ÉÒƒ’…þZB> ÁÊøÆšðЍ›À…Š1»&DrË6pÒHÀ nã?>Yt¬Q&ª¥Šs}Þð Yt=Vz¬ñ†4«¯f!±æ3¿&úgìðZ„؈¡,¨AxŒD$€XG?ÚŽj†¥IH‰, `ÅRzÐã W(Ãþ·&G È*£<ð#]µîükLf„cB ú…ȹ2Ž :ƒºÖÆZ"HièFrÉ„… Y¢QІ²žÐ‡7œx Ð&1§àŽv\# WT X—Y9T æ•JB¡ üÁˆ›ˆ–cQ<\­Q@6™þ“y¦)øUINþÛŠ‘„YhöZÁ%¡¥ZBÇcq•˜R#ù­"Ü+êõªWËp ²èÆ 1PÀÖ%‚C0@åRB;úA"È¡tR#¿ …»á¸ ær‡ îp8×à_5€‹‰| Ÿv£¤N‘P*,XÖ€| "ôÅF²Tqv'ÝÁÖxØAh÷˜(hS¼ƒ^É’?tTC,t ùª÷@ Ñy7´¢olIKÚ†ªfGÓŽ~¬c…‹ ZbI@†®ÉATha_ 8þ@º‰ ìyHm(ÂAX2ßf©'­á‹þ}ÙoH˜„Ô y96èø\ZЂhú1ù’dªœ/ùp ÜÝ èCuI÷€+®ùÜÃàa%¬wÀ‚¤P�ÞI%VÐ�^ˆ°‡MPAG Up§.‡* ‰PhŠ …‰›'IÉ‚—Ðôy¸ “8¥� ˆ[‚N0‚Nè¸|Z”›'–#9pšŠ¤ (Ž˜ „óç9Ÿ�;×A»²?H‹Š`€hx3`Œ~°Mh køŽk@)-Ðr0� Ã{XÂè�¥jˆ=�eñ)*Aꆈ²¯C‚�Rxr€nø _˜�$C8÷þ¨†U€4` b‡¼«3ý1rƒ)+0<š¡@ÄÆC4ai«¿k¼Ç[Äø°Iš+y4-Y¬-a%Jã<Ê´gëJ˜ØrÐTت+ƒWˆ� HGêÙc€p¨„JH¤Jʃ?Xµ½`…#è$?‰ê$ a@6È©#«ñ-;J¬ ¹J�5ëK%­Á¥>2+0®"x‚;‚7)sé‡\’0øwCKh€x£·XÉú#‡´#²zŠ QØ…,Šà�€•P Þ‘€*� È ¨8íI.¸”“�:ÀƒŠVȧX¨ƒŽ³HþXH¼Šë/’ãž9I™ ÿ»ˆá‘¯,˜¹z9‚8‚W˜¹# r†úƒ!¸€# ‚&¨�Cxƒu¸��-è-ðƒ‚Xh{¸’q¢&*¨l¢$«Êª†j`¢d¦Ëà ñ Ј͈ƒað—jP–jÀn $k(CûeÉ-Ê;(*†(E|AD£¼ü;AË»Cl¼¾dD„n šf½Hd£d¤Äò-ä›´ZÒ ™œÏq+9Є^@^(ƒ0¸†yµDbÅW£‚p õŠ›<ð[|°/ð_�kX=ð€*Ù�lÀ† 8¾ Ø´®1þfƒ,YF/ÙšTâKàƒj‹²®Ñ ‹¦þ¹"*—Æ0?à…\@ð"8˜‡C8…S ð؃¯zVh/nj‹ø/™8‰4x ðÇà—`@X•oš”DQ‰ïa€É9„Ì‚|ºŽcÐŒÀ“”å!9 »îáHX¡ QÙ†Žó‰*Èb¸c1‚x�Vˆ­øÁ7#0ƒu˜‚ ¸*¸C°†‚è3p…"ÔWˆ™“I�*b²&ŠB=È)F¢J8¡‘²(Ќϓz9~aRÖ!R–ñ$=(÷ð�JØ€Z�(€e%QKþˆa‘(>„¢ ð›@„6 ¤¿´SDÛ4bSbI <LÂL4*a%aXLÐã4ǤÄK‹£ãóÍÞœ†ßô¥ (“BÕÅ^ø,q(3ÀQ”úƒrp‘]+ÍJ‡Dr)M؃Ò„ø‚/ð¤Â)ƒÔiÀ†ã\MÆa<[=9’´ NÎÓ#æÔ)J%l+†¨6áê|€"8‚2�P è0ƒhïôV€H(•èÁˆÐ�pøØ?ùU0ÚžS™”œÉV ¥Ø†¸&|u‰ë©'„ƒ”‚ô‡C `�„,”XpP܉ '‚ºþ|•?’S9E ¹X„`½z78PŽ9yfRY`€C�#‚8·2P=z¸x (J!-Ò¨«mH²äL¥a!ÛŠeˆ,È)$À)BZ~¡º¿aR1éR4(³H#áƒ(ž‹`€Mp€w˜ŸËÂÓ*¢™Âs õË=©4I#ýqSÀ¤‚©3'¸»@eDàƒ øM±#Ë£š¿eLk%dÛMƪÁ4á´1¹»U8¤G Wؤ!dЄP zȃ<È<ø,M ‡!‡+pÑ$+8‚#°)Â[5ÝĆ(àÍ¡Fýi€T¨¹þ]ÁZ=â£I¨ŸZ“>¢Ã¶(±8a]wÀ2ð ÀV¸†à…1�7h�°˜LQ…ð§ Œ ð ¥@sâ‘x¯§`À|õÇäP‰äH¬�È!Ch‚~ÀBáÐ%pЛ€üMv‰KáÏ<Ÿþ2AQ™×‹‹’4°€³}Eh؃K€Ñ7H37ØHØ)˜€'2çýÃ�H%RÊ©(#¡>Ò(K¥b>X…8P°�ùq‚' …'åÚUH ‚w(† 胺(†Fnè6÷HˆÊ2p°wx.:ÓK:¥Óh9–¿þ4;ÝSýÑ»³øK©}[²u‚èœ(8œãbqèhÛ»M4¨6(ðMÈz¬9ÆÞ„LÞÝÍ@FF=ZFl£ÀŸ>xµÍåÔ~°Ü?pEȃ(¿#`rHQü-Ð-("�rÈ!ȃ^ð1x€>ñŒÚ•]Ef6 N(¨]lh¶\†büåÊ4V½1áƒJ;jw0€kèh x2øR�(…WC(€Aa ÷Êpp€lx‡>‚ó –óžòzžƒ‚ßXIú¥8Ô¯'‡¬�h0Ü+@\9 Œ‹Bát@TŠœß‹U9�[ÀþMƒ&(€áá�)¨bQ�hCØ3 ¦°‡ar�U€)pÇ7€®  ØWX="xÁcÒT¢º;ø:©<lc2i�n` €„(èkà)`Vg-‹>0*_І¦–;(Fƒ˜ª¶Xªvm(†là€øâˆÚ"¸õË›(º2™:ÙKA¼Ã@J<¶xCKc²xšÑ¿qëaAh�4Ðãžéã½r^J¸ÕãcšG[¬i€‚ÄæÝÞôÍFõåe[F©Á¶ àPzWÓ‚(u³zÈÔÒÒ�€ìŠ00e¤ë…?ÐMx…/èÏ̓£ô….šwˆƒÝ4þ¨]P@ÜVšÝÂ…š˜]\6FÉ™>_j°Ñ»KðX3xð(h6€ÆÀR`‚èRP8À€ˆ·ô}à¡•ˆ%9lð‡˜Xúº‰^QPþ”ßWÉWoJŠ SÀ€"¨Ì!˜ÑÔÂ0QéÐû¦ uÀù•Žhޏˆ« 0C¸ €„&8øË‚Xj=@=À…;; ð…Öýß :lìÄ�ÑZ51X¿!¡ð—Õ ²>™ÌêvÐRÀ‚bh'•j*âU(²}+°¢¾ž±&‡q‚ц�e©³U˜€rž½š´¦·vÁîØÃ´þ%IJ -¥Dü;¹�기S#¶‚Òmð뽄I %aÀUÀÁ’ß äÜõ-H#_n6Æ-.1™»0pqp…2 !XÅDʃ&¸‚˜Y Ôùz(J Píù‚GȃGøƒÕ=‚!»meØmÚÅUl˜#¨™†(Ðí^Þ€_ýÙm¶[ŪYÆ=bm >Пoë¤7qxÀ¸êÆ�ø€°VÀ�jwƒxžôÕ²ðH°€9R‚¾‰ �¨ä8I A—˜oL÷uhh’“€CðÁ~¼‘UÑPO±KH¡è÷¯Ð¥P…zºØ–(@:Ø„=¨pt"‰þX@ŽoS €‡KŠ·_@U ¤MVk81ç¹k W`_°†"Ð8Cƒaè‹»_¸q4@'èÒÖH¡‹ç=9£Úñ0b#v"üÙ6æÃaA‚°€U32 “Z4>ã:årø ´-+è´Xs4¦";U¨FýáC'Hj;/£nÐ<©±#Ī4J\¬Ãu%¸W6a%ÜdÊ¡I%…jH€" xP·/Ð�Ï SÝ/ª™'¸�NOD"å+x…Cú¬! )kx�4ˆXõÚ­Ýi%;ºUEžÝÐdžÝîãÎÊö>²€=F°‚;‹“5ÃmµþVxHvkÅ݃RÀ/ÈLpðði” �VYÈ‹lqR8q =ûbwu÷Gä (÷ S…¢ƒqx¯› “‰$'„Fh…¸ùð C¸‚r8$*` ¦-{± ¸„%|1Ø‹7 hèG€ÈíÁ r›ˆ<x2eÝ…îâ•)óæ'À¦\¢ ¦˜¯«¬‘òH tzô8q‚I–è�ÀŒ)S& '€�A€ÀÎÒNž,øP Ôµµ¢`éCÅOKÚœòdÇ.åÌ™N`¢+QâI –2_¾–dI–W±Š½jöª“'«ª¥-yfW�<РñEŠ̹þa<©*x0á†EµIA6@Þ lZ¤È’+o˜6Mgy"qf2lQ¦5À"¯›<y´9q˜+—Ÿ+f©š.ǦK]]>8bƒž*T4hºÂFCzC®%¹cmÕ»(µL(;Ší((Þ¡X>Q› ä±aû~|lTËÃ"¬µj|øÈ[•ò‰µ7G\pÄðÄ�;ð ˆ<8Ð ôðŠ{üóªÄR8,ÒɶÂE#¦ÁE+­ŒÈ…(ÈÒÉ)UÀc(0¶2c¡àhciTqbˆ!VÁEŒUÐÑD,t´ÒBK.ÉAÛ ãˆ;NÉ£þ•;ÞØ ”BŠ8N1n3c -PA2šˆ  úcäZ% †œo°âË›l¢›¼Œ/hpÐS$PèfäÒÎ\•àÄV<ÜLB\e¥•Kˆâ“@M”ÄGš"Št¡H-]¬Ñ…kØÑª9vòê<‚aDtRGó¬! ²È’]'œ š?±0 <AàWVÀü6Ó_1¥D’X_¥$×T/©ÔÇ*^=álYw¼‚ÆOx5mZÚ Ö®»ï¶+“L%ÞmàÙe™ñ›¾ŸÉ#L¢‰YÁâm'™A´&<$ÐO)ž\³‡³0ŽÆWL‘®]GXÌþy”“Ü̑Æ—¼1ƒ'`£ zG•æzPˆ'Ú4ß-R^yé­×^yPcA|Â`¡Ú²ÚXðV[ø¢ÀˆàW#xôÐ×=,àÆ6ذæ†R€ãâ‰Û Xå—"rqŠÊtщ(9£¡Ôhã”=šÈ—4ò¸*àpÀ7ßL. e+_R‰¥•"^Éãã’cy98VQI9È CŽ& ¬É?±ÄbY‰A‚EÀÎ šäüÁÊ%¼ñЈ`C ”Àý4bÏ¿ie)�~‰uiU5õužÊ … ¨ÎSÀ§l³‹(ÝïÒÊ.ã;2þ.å¯`~¢,þQLJ7ÜP@üºÖa„,‹(#¬iQDF%–�+Y¹ºÀr-²0O&SÉ–ÐåX/|I‹W–Wm DË¥¶² x0„ ìF$º1‰nLæóÁŒd"S(ühàÉÌμs‚iœà=ÀdT„   Åö1†v”aTØMèñ… Tð%O¨ |�¨?c¶ñA ¾3ˆáQÈz°Q‹Z˜Æ4¥©¶Sñô =š±™ o†´€©&i|@‚6’¦p=á RÓš Tµ|m#ðÂÊð/„M ÃÀ…bpüÃlSÑ6(G¢,¡ˆ K�–,Œp þ\.GQÒæ|$á FÛ°dâp¤¥'=IQRå°¹QÉJ'ÚÑãRy£PTâš G9¨@‡5a¨ 0Ä*ºò AØC9|‘„àÀîoxƒ5Ù‡' ó …Zðœ'¶Ðä*8qLh¡ˆ À +X#¸àˆ~ . % h'áÐDZM|<Å“Â'ŠO_+¾·îuOK»ØÆ=$ŠQQ hH�:ÚYnõ%\eYµ(ÈŽj„ +zèC¬à’lå%PCƒ5\2–k@Ö胋jÔÁ�bXF$"!JœÑ h*3 Ò\GŽ3üŽdB#šþ,i *š5”€ ô€šÙ,R@ßÔ%&Ú(†�åD6”yÈÃÂ@_L Ê0M°ˆE€ÀŒµ€BVÑCÃM<$MiZ¸CñôiHó5NЀUèOðìàa€$�1XÀ¼°ƒ×î`�#XÀ+vðÈøá—ˆC6b!Š%HpÀü›å~T€ûu¢�ØE0e”7¿ñ¨GÁ\ˆy#ԩ⢭ÈB($°8¾Á¨DRŒx)")Áˆ—Ñ¥‘t¡tÌ0 È0Né8€º&4,)A|ÁŠ&a S°Çˆ0MÃWà&ˆ`·#©ºb‚¢lþ@@XCô! ~þ3Ä� ¨pIdâ(ñHGǼÑZÀ¹÷ÆÈÅ2b%ä‚Db{2 >˜�ð�Ô˜¥/ Ë\œÀ˜<Á V(‰XžÀ_ ¡çºé¥Ð1Tk¬ÈÒâÁ*ÐpÔ/™Š1Áfø ,yhFg‘á d¦Ã_DÆ;W<@C0ȨpažÂÂ%Š€x„A šh‚èŠ *Z1AC ŠB!$Ð�4ð…7¢‚ÍÎÌL€Æ3.r¤lÂ6PÆ«šZ²-ÄÂ~Ù c|hÀ Þñ–áE0m× °€GîÀŒ°-k°HŽÀ P@Š!‹%\4þá Òß‚YÜ‹>ôGêe/ŒhÞùHp@êv�U„" Ð%ßj¤ÝðRwHÃÝ‘yÓ‹^òF© .¦ƒq@‡m@ó¾þPK f¾A+o „l`+RP‰pT‚áBBÖiÜãu‰I\¢’ˆ ã8oÆÌ„£­³ Í#@Œ! çahGüÐŽv4èÄk Â0¢½è9'Á‚A DàôHf‘ƒ«‡âêXSŒ61ŒBÅÈ*‹V±:Æd+¢U@^xðX ÅX)¬Pj±Cvé²fåi…¥}p˜ /¨º™2þhŒ<nØæV&5Ld"Êä+`-X‘†…6íxè‡ÈÑ ü 0|J­>T@T¨9/xñh`h Å Æèi¡a§ƒ=cq†C9o�fæ™azܳ™zgâiÀ{–Å,«Õ ÉtÍë-Ò 8€:v ì¸âØ¿þÁ²›- î±mK)²Ò'ƒt¢ŠB ”#wjÄâŒBUAA¥AˆXÎ1q�80@+䀓´ÀŠy×ãœÜ.áýaÉàä·µX8d“\‚°�V܉ˆ@•�€=ÀD@„ °Á5ô‚TB%\JXþÈB" ˆÂ.dÁ. Wə؈ŒÃŽÉ˜Œƒ‹Á\8ðÃ,ð'¤�'lA*D€@<ă ÎF.ŒÁŽáÄä‚'Ѐ' � À Ð�  Ãı1D@p?èá,X]j]Ž„‚‹i€ôXaUÀD˜XPEÁ•Ä(@1ôۉܡ¬‚ÀÔµŒ—¹$ž!ž…ô—Þ)ºKÁ4,ƒ0l PFÁLgèÌåEÆU]UÀÐâI†E <À:ÀÃäÁ#D@;\€¥¤ :‚!p�<šà•+0‡\A”Õ‚Ä ÿÇ"DCypÚ Éþâf<^.ZWí%Ð"‰G�…i¼Ã hCÁuŸi}€|ÀüÀ�øãô€´Öô@üÀÄÈA@ø„ÉåP/…×@™HE%”+‰·ÍHx 0Ià€ädÁ†¨0ÉÝ(Γ µE—–´äyE×É]É“tˆw5Î64à…¨‚*BœÓòL€q@ �+ƒØÃØÃXCLA ¼BUî!ÈB2äŸ? WàLd‰ƒG>á˜\Ü,(c0ˆP€;¸¸ƒ(� À\Îå:Ø%;±Ó:Ù% Üe]Þå_J`ê%_Î¥Àƒ;àÁ>ÀC?˜ þF 4¡´Ó_8A5Ü’‘‚„âYT :ð€L@Xƒ3>Á¬B1¨&gF‘XBÙ‰/xKLÁD¹$ ân@AÀx€x€¾„†U‡08Õšm�à -\h„G-Z�TQƒ6ÜÁ„+¤@s @ØaE58�”0€ý+€éõ9lD,B6ôL{(Ãa–§IVaÃfô"›d”‘eœZi`5ÈCDÁ;ôÁH�ÆìÚ0„ŽÀ#yAà�ƒ¼‚+Œ�üÀ˜ÂC4AšÈ´IÜPÜXäEÂä¸e GVI–—E†—Þ€ƒl]þÐ-µÛ0Qdz‰Ï+aÎz­—MâdBbãˆB6`,4œ@ ¢CA|A<�ƒôB/`œ8€!€$8€@$t_1X(Î?ùS()!ŽÀ\s¬^4B#àÐe]æé:ä)aîå]&@^‰`ª`O¡®S **^"ª¢jº´E–í]1S`XKó¤Ä'Ö”E£ˆÐT¨ºÁöõÅ*”é@Bn@BM=;"$L�áñf­Î XÂgÃý ÁE§rêŒz´Ytn†tŽÇ©Ñ`­ X„Á ÀôÂêiEóÄ ƒÌîõÂþÀ+ˆ�=¼BRâB}.BÄa™@4|óEÃ}bŒ¾ô iäçóYÒ$‚"è ì[LÁà@0ôÀl-€…²e8èƒ:˜Â ŒÀØt‚?lÔ¸Íý}RÊY¤–° NúҷͤýµMäIŽÐT€éü¤€ƒ¨BlÃÝ´äLr‰‰t”èlt‘rAFúÈE=‰“ð$H”B TÃeŽÓ À¸B Ä€ìAB,8,‰£9À?ØÀìAŒÈ.Ld‰H�|mB´Ã[ê_þ%`ÎmŸÚmŸj5jðð-¡öåßò)Ý:*¢F‹`™Û½„àM@1þ0·Ì…[4º4ºXƒ/ø+ 0™@|¢°è²Â+Ħ¬v.ªN€­ª.L°5H�ÃüB,º¯ÖYtþ‚f¸Ù9žÇ/ÄyìÌÍ$'iŒXB´š;˜/°A<`�IÍÄhÝ,,Ó ÀZá\L€ºvèçÍ@Æ/Ìk4¯dÍiä e!LWÝ‘}L ħipCÀ†h,ƒì£Œ@xMƒ|À8!Â\èè*ƒ,ÄÂEuÒR䔘×É©(NNÎÆ¨Êš\Ež×ãNœN6lÂ?üÁ?œÛ“d$‹ÑŸ¸‰,ŠÑd”“+ùÈ.H€lÃþ“Øl:@4�$4@5èÝð�+üÁÔ² @ƒ&LÀlúåÀÅ@˜·Â)^Á@ ¸Ã( æåÿ%a¢�žÞmžÊåïi^ê­¡˜q¡þížê©Ünñ¢æ-º¼„XL…E TÃ*ô5X…@«–ýX¼A1„nøÂ"¢ƒ/ÈÁâ²Â¼+Ã+t®P2«B+èæêÚjëú‹<ücA7°†æaÆ9ú®z¸Ùϼ™óEVª†xð0ÅôÃ>@&˜Âd"L¬B6PAÖ…C,“B9ˆ�po8À"¬Á"DaÙL-äîøfÕwäçÎä"¾ˆFi¨Çbõþ"t;`A4d±œ€ÔÀ#RM?8È×øï5|Â'\Ã0Ã0Á@²Á SÊÉ$½%!@Tà€ ÿ’ʺ践\爀dC'ÄBØúÀDÿä’Èð‰èÈü©0ѦW‘²×ÚÀp+Ð0 íš4,4@1P‚ð6�BV¸Á¼¼‚DL±øÁÔ¡ÞèPÁ¹51 „Á14Â[Ò-£Î-Ÿ¢À|±aÂ%Kõ\ÊeTÃ¥8uæ:d±j_NAg±ÿéÜ.ª£þ:À:J)žÝW`Ë ‡®¸(�º ç†.+„.è’nlJ2&þ ¶&×* ¨UéjeM‚R•Î4ò者,î§ÁPÖ¾ÔP4 ])ÄC.@ à•Àø[TBh�9@ƒ!4Á#Ì).ÈaÝaÅÙwÌÑåEVñ•Q I–zŒÇ²º‡p›ÀP;ðÁ °QR¬Â•Ô€ôÃ…2HÄ@x(/ À”ôÃ\À ‹2€{Õdåxìü¥è'í,Nµ•¬øP›,á8ÐAË¢*|J2THÕÕì’ÐpKRàEÆ—,ÎmB5Éšä@,t‚S X`&:\BnJ2é�XŒÉˆ�Ä&”C„ˆ“,Xnê‹Ãñþc±Yá&TŸ\µŽó8ž^uãåRÛeŒ¯1Ÿ:5a:5 ù³‰“yŒ]Ц/ë*@@\XÅ;)�èºö¬*€°‚çz¹øaWå%¿Â„î+(6oŠó¾ÈâëJšíge,Cd@§›ý‚ ¬²œÉQÁ Úe…Ì� ðà ¨Á>8ù_ Cˆ€¿…Ã#hÁ00Àð.°k-–Ì”ÿì ¥‡"øni”Ç8úL4¸:4“ÇÏÌ¿$ë|�Ejœ@  ËÜÁX·iÅÀ€+|”Bà�(0pÌDCü¨”<ð/lŠ�ô‰¢þì kÎ�—GC%B9AC{ .„íO:‰ _‹É›¸lüµ;»WŒõÞäÈÍJ�.q�ÀÅ@(¨X�º<+4A9¸Aäæ0ä!ä74Hï|Ax÷+¸A9 d%t›æVl¡4yS£�0|qÛø>æ>°|Ã.ÀÁß)\ê‚ëBàvñε‹uàŽ5ϽRîoH®¶nk1|¢¤Æj«rê–?P0²`ïµ`7òaöÖWeUÁèŽ.œÇù)&•h4Œ,^žd1L+ÊÃ2\ÕžC-¼™yø.ЈïUY3;r7¼è@4Ø2�þ”À¤�Ç¥_=äA8XÚ¤k-Ìk-Ä ºªÏë"�«æÏk3Aç‹£8âçyHÖ¬;ß{ÈPÈ­5�ÿôSpÅ�ƒ;‚Hv_ƒ`�³_ HlÀ"Á  ÛX zK {ÿ³KÚ[û$4ŒŒ‰0ËÁ^K‹K)âB6ü{(Ô°»Ë[zmûܤÈþVédA¾{¿Í†‰âÄ_ã°?œ‚,€@-$ Ì�)p…582ZA�DŒ# b$ùBNÃzôø‰óãçK¹&tNIh‘ÃÇ‘%$˜’`]Ç릠X§D %pPÂAá…3i*€RW̘ºþPÊ\÷ó§. !‡®3‰¢äQ¤JŒ2eZô'ÈŽÑ•(ñ��tY¹:±6•kZ¬r㦘›>OœpÍêÄR9¯Ü°zÅŠ•ŸW{φÅËjÞ»vñ&±æë·‹7vüräÆ(a‰„š¼ P~m®5-H· òä ƒ2mÚ2a‘6üúeÂõ/lØL̆rzëÛPýº½a·w¸…Vbkã'{¨<ÒЋœ–/yfÍú£c¶h]jÕŠbâÄ4(µ±-Z³&Y¢D²¢_Äýy ÑÚÏ7a¢;6(À…mÀ¶yÌ�±dƒ Œâ„>X 剦˜âà9€ÜIÂ3ÆþÀµ±À‚i’e—4ÒçD«¨‚‹*TtÑDCi%Æ4X4±ÅW´1 .z¬¢• ƒÜf QÌqÅ*y7|‰ꈂRøàF™m8Ø& .»Ì¢•"wä"Ì%–؆ÌVXä" Q–ˆÅL-·”Sr 2<³ørÏS²(@ P°8An,¸£*€‘¡£.€ž0Ê S¶xæ7^©àŠü %‡Y(°*`@êT£JÂÉ&t€¦Xcåé%hí <L’ê©SO5餦‚•i&`ÖÁÃ(¨†ɪ«žHn1|IËItбÂ4Κ jÚZŒ…b䘠®¿þìºË_À:W°Øeåˆ'˜€Éì½_É�ñ€šÑú bñÄû4º¹…4Ô¦ÉMavm¶ˆõ[X·Ý°©e¿OˆâaÚÚÅЙAƒ<´⋃z ‡Nˆf‚.ºX¤–‹k»Í„öê0"™dŒ¨Ã–özF/™øâ‹æ¾Ú|ƒÂÀÙ6À/@v&ÁAOÀbx(á)àÁìz8¢‡ ø1âÀA vñ1FÇÉñÅPª˜±…Á„F]lÑoÀY\±Å!ïfQM<C '=bPÀCb‰¥“lji�‹Z*à`r/EÉâ”mÔ\1È]–ðg‰V¸]õ4ZÙ¥ÍþV–¨ãÍ:ü‰Å#:‰eÎ=ÃÜóN.Oñ>ØÁ‚4.¹ÄªdÀ‚ƒ‚ /9bŠ`]š"9:=å”C` ‡P4(â£F•=)&”tz_Öšt’‰~”€Qâ‚§B6¤TB&ÑÅrò?£ €GYVÿB‚Ž<N�ØÁmùâ E@ÇV‘®t‰Á VÀŠ[ر Ha.¬ð…üÀŠ+\á [ë]²—¿@b�D ËJÀƒ±ä ˆA¼—%¨A Œ† ëOÀ6@ yl4Ë�N$„!*F5Æl¶8±…m [¬EgJãŸòàâ,€€¾Åkíþy ‡CÊÀ†<ð#ÄhG1~Q.D# ³1Ám¦ÑEúÐ'g¿†"ºÆœ!í=µð™|Ö ýØ?ÂÐOäÑ ¨@XÀ%´µ\À�8¨Ðb�Ä ~ Á¤ …E$£Ž€›ßæÖ#..O9èR(ˆÉ»Åˆp~#œ‹˜£©Nt¤Ò6Z@*ü! S8À1¹:t¢'�Ed±†Edƒ@’À6Nñ9-‰BKgêD Úµ uK8`·„ìLwkÈíˆä».É) À)dA‰d˜=d€kBUàÀ)(>?ÀžuHDŒÀ;¨‚ ³þàÇÁ zÌÂŒB•ÿbr@¥Èʦ4¹ÉMZ–¨D&PIÿŒ5pX8= R¨¬©8ë<€V[´qÁ7\¢P�ŠAN`VЃµÐá„;¸n� XÊõŠ+øâ%°Æ&`Ã+Ü¥.wÙ94h-!þ°‹D¿¨Ñ JŒf5ÂÀÂf¾h6¸áLiƒ Õ,5ýan‰±*ÊæÙX°` K´‘+ÕðAR0‡à ôà…d€e˜  ¿¨ÙljܲgIÛ"X3EÓ,íbO[ƒ à³Ü›‰GÑF7&‘àl`± j@²¶µ P(þ›;.0!3 „ˆÆ7 ðË*ˆIG¿ü¥ßZŠ,p�¿^âÀÞ’¹L¿ÙHp:¢¯Ž¦¹ Tš¸Âà†MT ²�Gæ!‹(x ˆB'¶áºV€o øåÀ›tW�Qœb ˆÂ< pŠèS¡KèD¶±‹SÜ ó˜ÇîX× ä) ¡ØRB³á:eƒöè‡=´‚üw;ê‘/¹àˆµ"Yž…’ <j*þ �ÿ—½™„X6í©Oá€wìãÍîP Oè+¢H(±rJüŠ5“dÍ4ÌÍz‚¼åôr¾P€.ñ†>xP oð wWñè>£Ž~þ+ aÃW�®èàˆ° †D˜€&ö°k5°±þ+;H# „†Š=,c ¹0ÔÔæ>´yÒ~kÔ܆`_ü"g)qï€B:@ �Â-èð…†À‹\\C–lh�ïðŽdØb·Ý©Å~V‡Áœ[sùãÍ/ÈКÖhg7„üí&Áð!<V»ÐÀk˜’B_;Û—á2äA˜˜‡4ÞF&»éèF>‚ÛŠ´T§ì—˜0ÊàèÆòÅHõÍ“–|ª=¼¡¬Øƒ¤à�et¢MȆ,”Š$1`BS˜ð+ŠwÂ7H]+þ °b#HA EèÀ�`¡ŽxÝ?×0#øC�Ó:g¾'ï¢èä�8†±ä}X!+Ö(YX›‚GôBÐhNÑÃW¢9 NZàƒbÌ€O¸CGJ0æd Í'™BPÝW“5Õ§*ٌџD¥© šg¢ž$5) ä_ê§R•²F>9eéÃÞ €#¼aw°†¤ß _¸ ŽÎ–Zf€†²õ_¸Â^Q„g•ào˜Àˆ� ïÁÖx4^ñ,YŸ?ˆ€�í­qýY€Œ×%ö}ÚcÎù+Œ«A p ™3ýð'"¡¦á €(á´²M èþH r! H€ Ì€Á`ÝÐ-bzk ¡:°âí>ê­ àãÞèCº¨V£3tËØ˜†�¡ ¢ �<`œÆ@0G”,@kJ Ž@ ÀÅ*îš`O>°ÞFH@G¦ Iîë¤ö+ÈFg™˜ •I™‡tî†H>'¡B¡öàJ@ à²ÁäàvG²A®¦ 8 L€dO–@ö0Ç^¬Ê:adÂÖ ºNú`ÈdþIÇŒÀÄÖI¡ˆd„ŒK*Âðë€ÞÌ ¶Bï„€FqSA  F!¯„�ñòÀ«@ ¡þ,á n‘T‚"ÏþÇÏjâ~êç}VBÝ Ú¬Íö%xâôP¥(ZO~œ‘X2oö¢B*6Â*¬‚$è-XÀV! 2È0î@f ]’�„|áÑ–ÑB]TÈ.ö`úˆ  «Â ¬¸öà ä�®ŠaŠAªÐO ï…ܯ°2#, &`´cþc¸(g†‘ðã¾Á5†a)gÁ¢ 7–! ~# à-žà t 0ÀÌà €á ø æÁnCÞæÁyfæí·r'wä Çz²hì#7r‹6 ?2Æ‘°º�¡?N�  ú�k¬¡A þ–6ÏÜ¡‚Á$àÄNámvAÂDLäkÊø†äjF^ŽGgå®pp¬ðnˆ©K8�ž¨© r€<ÂlठŠá�²Âda”À�ÓŒ) fnêIÜíLj, Ö@ Àd¡9 áÊrLX¬�ºDŠÕN:A Ta|€aúAªœ |A ÊÀ0€~pÀ†@:v`Žà~ðÀ*�Eª ª@pa(ÀT~e¢~xJ&b¯~zV€n‚VüŒ(Š"w‚XâSXnª((Ï‘£‡®Ï 8,0(à ‚ŽÏΑ÷ŽO…¢þêf@­>èZí Ä ®l‹`Zèê6ÈÌo‚’Cݰ ŠBcr4F£4„á·’AnM‰B>êÍœr&hL 7‰b6CnæºN€n(aPò  <¡à�Æ àᬡ°Áä Ìq¬’èc¢îºT¤8°�n L‹R¤ÞÃ76C·ø8tò?Hƒ&J pá,� Hd ~°â.`. &úÁDA—v¡‚¤MÜ$NT‡oîr yDET$Àºp™ÔDH„dOè@˜à)HÒ 4 Cg 1Õ[ªaäÀ¤ b!@î:áþ| |¸¤þÄÊiæá6³%äÀ``�$ÂÁÁæN²`D‡Kž5˜.QüÁb!þh h HAªâ øþ`¶0À%ûáÈËý Å`þ Â"€R€;Õ§ýÌõ`Vx1%\Ï&r‚ÏÒ3&xj~E H&rÂ&fâV ¨õ6¯$²g¦®WÁúnÑ+œÏÄÀøžÅ+Ô "-ÑÞÀ@Ægણ^aÄ`že+ÈŠ¬¬"ª$HÔhvC;”Ci4BC4’J±àDic<�à4±¦ÿ˜+lA>€ ¹€@¾¨? ¦!þ|£„~£LË ¦à@ �Œs ô ¢ >° °Ág:0º€ÝÚ-æm6,£5Ö@ºô¡o –ë4î~A`p7€�0`˜r±„¡ˆ°€,@DÈAŽ�Ý!{¥†á²À½bŽLÌÝê`i$ ±pQ¥¬™^IÈ$æFGMÔ.è€P‡D:ÌF|ᦀD Àˆ ž� â€yOU@üau:Á1'¬n dìVÊì΄êb¡ Ê¡ € çP5ˆävíkOò„˜¼DíbAbÁ ¯ ÐàÞÁ04ɲÇΤ¢Yöþ³A8‚$”ÀÂÞ }¤;i*=QVhÂ(ŠÑ‚s^ÅV\V”ÑùÇÎVE~¢‘~F˜)*Öµ¬Š¡€"ï ì‘Ââ ÈʬÃú¬âu9¬¥‡®‡u–fÉ‚ªá…“£¬xV‰³Bý,ÀÖ ×‰KÃD…!#»_øÏŠ˜Ö‘Ì jm¡¹" Ù®Ò×¢@aÞA8¸¡ �(Áá.!À@ bâ#x€`;– »¶4wæá<z2Þfc„ncÝ€@Wq ÇÔ#ßhñ£Fwã!‹H“ÈX±@ ,À[µOË‹I!ä»Ä Àat)LNNŸöðä)þä’nšÉQcæ*HbÎY% V%@Ä6JHN„Š xÀ6˜7áxßàæ¥&Àx×P:—I¬’UžQž:5³— MT¡¾` jÉv't€Ä/…)˶áNö$¡üAÂbáˆ`%Å æôÀ HÁ‚7}@ÂÌ(ï ­A:â ä# $ÌÚÓò>˜‚måÛL“ñ&bÂQ¨¦ñTܧ„m‚X*z„ƒe×ÁT‚Ø+úùŸEZ& c_­É ˆ+g6ˆ›Œ¦­%‚t�x ܨÉ6è Øa„²bg—øüœà_níg«¨almàωÈàØ–š4˜–6©þÞ¦ö*é>PÃ@æ¸!k_°‰¦ & èO¯ÑX�êc?LÀgüØñ<‰ÙîÃ5@a3zãÖÀ¥A¤Š°è†$à6l­ôV”Hƒhí´¬‚Áœó#Š`ä ›ôp3CL³;NNÇ¥L¾^NÀ`™ )•uj™R*¡ÔN 9€š0 r ü. Æõl ^ˆ.ÁÞÀ(@ ìb A  GØÉÀ©¡YÙÉLüÁ²áœ ³À 4@DÀ^”!U/³eŽïK s€²€"š  ¡Žw‚<A�¡-œ�¶Æ#¢Ó…£ê þèD¤€9‚#Ï:~n"ô±ô^¢%¸`WB$šV "aãÓ¢%`õì}.ïÏ”`#Øu?õ@‡mÚV!f¡Å†aM+‚ˆªagÙ(¨‡š¨Ñ¯~¶DAëg†Šac4ÙP£Ö0C3ôÏ7„í<|¦hzf½ÈãÂZaÄ@a'àÄ $à àÔ†í>p)=6n€�?þÏÃì!Á’>c<’°EªM�ŒÉ7‚`º!ŒpÔ6«œxø`¼ºB¦€ˆ@HׯœÎL¼W—äKNŠR}ipuÀj¾š0q\ûRý¡ á:$ofþºæü@ÄÂÀád€¼Æ²—¬b@ 䀪³ ²àTAb»V·›eLAlÉ AÀ¡ ¤�¦ý wç2ÝY6On—9§º@âÀx} �~R;NÀ�À xÀ…‡ôÚ}H­à¿ý¿Sú È7¨ ‚õ0Ï(xÂŒY"=CÏŒ1ƒ–%ij€þl=O¢'<¸aÛ§¦nª©¶Ü¯Ð§­…€ÙõÅ·‚-+‰#ä…ÚÆo<°úågŸØÖž8"3zëp`N#DCãÖ 3–¨<pI(…²É¥–>Éa¦Á‘oãÐ`p¡¤K�Ý©ažÖÌ¿¼þ“µçÁ·jaqu«gÚmذ>7¦ÝÈô±¦®Í &a_ À’NÃ*´¨ÁN9ÙZºæ¿@š`M¶¤Fl :NäÕ鈤o|$ Õ½TGHÐD¾µ¾$àäè �¥ a¬³/sÀàÁ#à!üàra Ü¡£I,øQ.à 4 ª Ê@¥:¯ö«"DAã* ˆN@ Žè”AÊ© �íjñÝ ¿D]NàŠÜÁáÈÖ ­£AÞBÝ:«^ø\Xѯ?¥aø ܨð5Ïø má`F& :ýÓƒ'|'X"ÿ§'ö_Y§hBßþ3V@œòh œ C` Áƒ� D“„#JœHqâÄ+jÜȱ£Ç„A°l'/ˆ<,%ƒt»eRØ4(¿L@ eÙ4Z¦-‹$,Òȓ„¡6óÄ/lØ©“̈´¦É™ÀöëL¤QNC¬º€Äį5FŒ,J†vZ@’ÍKÆvÞšhµ¢-²&Ùh2±1rãF:7’™˜v–­¢ ,™02õÄ´ÂäY Æ‡5mÕØ}-Áƒ°>q²piu¯@'Y²ìâÂEÔ).il/Ù&j›ï*i€§ >\8î*\ª´Z¾švÚÉÓ´âФ‚¡"4ØþFdÂ&U9fý co]8 p‡Å:÷ïßãH¿Ž1î”Ø3C‚?Á„1³d ±ea[ úãO,É(S (P`J-‹ÈÒÉKˆÒ¡( î"Á6YøÆ±H¡LÄr¢°¸Á/ÑLã�8ñÄ¥=À#wð8Å¥=aäO ™@ 4¹Î“P>麸§„x �p‡í¡ €Æìcæ>pl  `®y%›íEy¥”lb©„.`†©Ä–yJ_œP.é�F>!Ð@ 4¢O(ªÐG9$PA9饘f 5òD’’<B}J’<Ë@aÂ]ÓxþÉK1™àê^®F³†TTA±O\EUU­JåªY0]¨LÅ¢‡z°CM$¦ÖòM4ie³ÈkÌcDupxC‡…ÕaD"eE YhQöK-k$‚X¢Ô6ÍÄ„W$ALE-¹^¶AlF «°P@::Q ÙÑ!¶u…p°Ä)ÈR€4% »ôÖJpU�òpÅ!·sÊá–ÜjUHpˆDøRÌ3XóD 8—`d“ ¼æL|b@)8€)ÀÑZ~ðÉ /04/ý€Ù³yMâ<Åà0°M(Yœ"±?0(J×±È `³Æaˆ-ñu,&H¢o¾qþHw€ŽÙˆôM‘LâÄà< i¤<>P¨E>‘ÀÍŽOe”í]‰'žWz™¥˜bâQ¦™[ri¹žu ß:JP¾'{Â!@{°¾¥{qÖþ|À,9Ðà…iÐï):)¢i:øà‹jªüòñAIf&ZRf$A”-îªDÀ®ÚÒ—÷‰$Bm"‚Ü HÒ|»¶”,Ól°APD!ÅëL¶baN�âÁ²PxÖÚ¢²¥,¥0ÒÖ ƒäo &�B4è²qkm÷X [ Ð)SÁOµø…06p‚ùa ž!…,À‚‹$¤Q8 (2¸-·q€þ Ã)þ*� œ¢�Ò˜ÇÆZ±ÝŒl" ™rZ±šm0§ÈYâ8Z!:4ÁÅXÅ%fp‰xå+¿+êöt%�iŸÀ�ÒÔ8(i#(ÅÐRG»u\À‹8ÈH1ƒl0€k8Dšpì‚C®Yƒ,ŒàˆBb±X‚*8àØp- ò ‰Ø›P¨B>°Á0ÞQ,Œ«´°ÄCˆ¤¸›ùˆ…,‡¤Ç=nÀ@.&§'0]‰Lž+ÓšÚˆ‡3áuaJ¦2õô'(UspÀ“žø´ÌÛÕ1PºcÁœP‚mO"ŠrH7¹™#G1O".<§:/ÕaP¢$ ¢Ÿ0ÈþP’Uý".ÑèT$hd‹ðI#vøg"¤Ñ0‚´|‚â@ÿ¹;´o1A™†KZU l@! P85��P Š0Aøê0•EdƒZ óV¨…¶¸Š/êb µ*È—¨ˆ+K¸G·¢„ Lƒ,o¡–EIˆ’ò›©Dœ@($°0÷˜ÍjªÈ�*Ò h€#¶b$È”¸É“11Š!Ç8Æ€ ¡Úh¢N`¸cÀÀ—à×1¨cr–J´|À�ø�è¨xt…x‰zÂ;þáƒMc8røÈ%€ƒE.*Ñ6N„·ä€ª ‚&þŠPH`9”ÜUŒbøB°ÕŒ@¡J�ð H¢e’w³ñÀ–‘›‚€19Ÿ]®=\ÚkžÆTÌ3 v™Ë¤ãíüäÌ;å)L±ûR•¾û]eR­j_é]7yÀ# Î!ÅÃÈî¥= yë̯~!5‰ x žŠŸ¨â7#8‚é⪺ʶbë|è‹°ù*A¨¯€¿ˆß¹*„lœ@€�À$(ñ‹Š‚k1Â\¬õ-•ª ‚eV‰ù²>Ô.}‘  Ø"Q$¢$¿0B2𠡤¨|@Rµ¡‡„X P o<$ ©®“Ue�:1yÜ�÷˜!XEÑHþ(*1N4«s„3Öø€ €)ä s.µÈkôz%w<I îX,Ü3Ê1±‰íÁaqàçÌ5x ñÊͼ’€bH6ŠE²ŽÄbµàá€xþaÙ c³à@Z›4£¹Ó˜å)”1+‹9Àè Rï ÷Ê)øÈGCÒY䚨öè‚uo ,ž^&< “KȯéjGºf†)K`ª³±ô¥0ùÌvÜ}zqæ^=Ì ::ˆ"©÷v¿û÷ò&ay¼³§ÀÆ–OžÐ‚Uf‰É2L~Öá| >ŒÜ-¶5 ˆ¯°é2T˜&X„P&vþì3/í“J6ž–00-áƒ`U°!.‚ßÅÆØPÄ´ØÂÜ`†kèÉ©dEB!3Eõ øÀm„ …jhÛ]8Ý9T¤ „JÄ"l:eàÍ9ä¶å„B‰i¦X•Ø‚*ä  q ‚VÁ;W<8 ùª„Å^ u€þ ¯„1$Ö�LÁÐxàÑíà#IQ ppà“ªè´¤° Êj� µ 6¿yp˜6�½^»MÖà†Þ²á¢ DÁ+Šƒ¥,‘d8WIŽ[ÇšûË7±Éuنݞ¼”¦dsNMÈfÓ{¦`¥kÆÇ—Ê$5·K»ê'þSÜU#·‘ºÙ(Þyÿ½¿sû{]˜Ny›?¿ÎƒgKt;*a,C~Š�L4¾¡ˆH˜@€ÒèÖ…œÄÄÂá‡ñW�å£p€1 /ÑaRñaA��B§RA—Ýbr˜�"K p³‚²Ò>T '}ájSC‰‘oÓbc² óCÔ@ Ô`|�a ‹À$Ãt\° Э uyÀ�•€"…qÿDٲآIfÅÏQ2e×Z9 oP3_ñhu—Wîà=S'{çî`FN#x?0^pt¶Žò;Nð�qÀ�€Z> { {°yÁ°yWð‡@þY>`ZY€7 €7Pã §p"à�{P Áð"¡J‘8%ð�¾V8¶w$¯ °ô8S� À\ªÃ:›Ó%cò:̦ u%ÌÖFÜf Üæ{•£|§cMØå9\r}ud;§³KT“3…bŒ…r(Ýä“r~ÎøŒÁÕ3*ò#?µ ™¡sÔ"A"ôo÷D!·Ø&Ø7- u°Y R�˜`‰ ÞÓ€q¿‚ #D�(.G-ôØ@ðX¢pF0+Ê ó`ŠÐOç3{G.M‹€=…‘Tq*,µµ ” ?Ô€«@ “# àƒÐñ´þ±ÆAEª 0 ª òHs²Ò6 CÛ° LÔ’$3…¡@ÿ° Yh—RÀЋ5&0yò&s²P J4?°~Pƒ¢<1Ð�Jÿà�p…¬ äðÛ± à³0 0Òiq Ž—- SVä>@j›Py…ˆfk½ã‰Âö8²÷‰´7»(P ц¢S%ØE™°Ã:š³ÈÆ:¨Ã&ÌG}ñљ˔&‘Œ¦émO’;U³$³Œè&lÜt(î´éŒ|`”Ï3?#„€ñã)ÂP tq€dÐ6±ò QA˜Ñ Ý€Â`ù†qêHþ C#(.,7ßð Ͱd0 “ Ð’KQ÷A˜°@ØržN‘ ùww‘!ÉÐ-æ9dVzá+}щ0ÿÙe@�”@ &1ƒšÁ!�¿P�*ó ÁEQXYZà± 9À!Bf óX�FPˆá$“D¡`Z·ÖvËSÀ”…mÐìAFí‘gøh4=pr…x¢nDr30wp5à "w` CÊ 'pq0BX°KÐ5$B'š7‡�J6pa Áà–9�Õ@˜Œék´ô‰Ib{´ôJ À˜ � »×˜WÂ:º&°;zÊ9Æf:R þ'¾Ä‹¦)¨É^ååmÁšîÑ3Ùw˜“Fn:“3:r_‡òhµy©çĺÙSA+3ÁPÐ ˜&0œ2! ´0B8Qx'QÝÀ©&!?–qkPl1SÃySõ ¶2*gá-çc7ž…Á0 —:• Ù`«KaPv VÁrE–qÁ6ß">xÁAòàõF ›Á?NÀ°1JV_G¸‘ y³€7( ÒPañVÀ0ÂD%Z' Rà *º<\È”ZÂW0 X­S£y4ŸÀL`�0_”_»ózÀöÅÕ°E—pÀP5Ð ¹ ìB"Yþ�9  Ÿ”6À f0$`«õ5kÁõ�¢˜$I¢3P¤SÀ¦¾&§ŒyŠº§{xpu2L³8^Ò4‹}Š]æU}²Kyb™]‚Rk™Âȋؔ}M9½£^:ãMÇ3›˜º¶˜Ò ¹éœ7¦U?Þ¸w!­Ç+¿ð,t€ÀÉ ’† hc¿BtAÛhQ,7-çy„7`r Ò0ĺ@ĺ-ï¹0Å`éSAyQA¶‚.ksrwQ ø3žqAÀ–��Ý0Ê’SfVêf| ÚUaö“­€¢°% > «  –ª)è� ðÐ_²Fþ!0c°'8°XT‰=Àeð°M´y“Z ÉÂÝ@�ÔðSu@7€¡°Q¡±`Z9`ð`j”õÅKC2´e;\Aòk¬d < <»{=óKx’%Ìö:W½¾$MÓ–LÁ§KÀHm¹xm¶˜]p‚:I›¨Q"¶Žó¿$<©îu_ݤ…Q~lûŒÚ` Ô€¾ò`*¿Â·!d*É>‰à=€1‚}! ¶0¿`ßpeñ d>v°Þ#A@ @ˆwd@6·.’›RÒ@ˆqž‡áOI.MaŸyë¸å’K1d¨›€Ó€&B“` Ô°úºf!óZY 2Ïaþ¢YÀ—0’jÓ!+Ð Žð“CeNT-p¢"€z°¼+:2�m£×[•׫8Ð=Ðf�\ÀÓÂ!‘PÊ P@ëë¾+ ‘'¿› ¸ð3™ˆ•U >â³Fr\%ﬤ8­$ÖphzŠSð¦¸d9]{™¾g4wBÁ•S|²óKˆ S[%]ÒÌìµíñ™R²K»h83¶…K& 9„i(g+l†b(ÜÂîœÿS/«›o-Ç+!%­gažõxS÷>¶ð :±OìÓPý4¯g¶Ä|±Ðâèa'`R'µ s@‡@“[6©-6IrÞ"P(+k $d{þa+ÑО(µR 8­3A=: Ô@ �2;Ø’DD2c•Dyã–w"½ñƒ«át‡´þÀ¯‡¨ ûo: ìa°yeF0fdŸÜ£ï �,€6 °ÕØÐ�'Ð�Ùоª†¡) ÿðyÿ0 {€Z+‹7ª° E K#ì¿ýkŒs$<@À¶g{Fûg˜£KRËmv ¨ÉdÍxò%Ñ¥&ÞuÁ¥“'Ç4L„=ÍlµaÎ#×e«}gÛ(Úg± YWíÎì` 08  R!ãÝi¶` ±Â>Iß®ELpáCójúP¬’{„鉭 ³ò¬Ý-“ ¢à`±IþˆÆJ¸-7@¾=ÛéâÛݲØ€S…‘ Öùr?óÓ�¬K å ëš2Áᄸ2} à |ÓH,É1="§àU Ð o¨_ñLm:Oé°«£G¡ OP ,€ïà�”À`.¢j9@"ðÿð–âá�àP“ª`‡ À�>0hà:3EÊ#À€×C[×{-{¾VŠŒÉ\ÜlEMQ)Ál2&²¨±ØmD^^¦ÀkBšÊd™Ò¼{‰ qºšL2Ι^Ǩ}¹œÙã£èÔàúå@ çû<÷è*|‹Ä~ñ+âÒ¹}Ø0 S1Ai‘Ã:ìþŸ9|ÜGˆi.%äæÔ6ÇÚ@Hr”‘)Së¢pMņAÐ íè´º·B=à ]°1v,O”Þ9 v'’7à Û ´± ]ã“=IIšæ�l‡”æ7 pwWF€7LÐ#à†í iµ¹;5° Ð�EÇQ €´áY`Ö>�>ÐÜM ÕŽZƒÔD‡£3㸷×hú�Eð[·œ$<£\Àp¨Ð]ÂçÀBŽØ=ÍÎ\l’¹Ø(` ¥Ùlv"•Ö(Œ9L¢Î½£#E¦˜Ë¥!×:²ŒçfN^æçÄ0È)AQ!|k«}¿²6Þ".þ¹6ü'ÛŽNC¶�‰ÑÐMlQ@±"é?ìp{^ÑTœ €ia‘âb4´@25‚C†qGx*˜Ûú%”  àéKEŽ˜Ç¡DTEÄÛÒ¶±С,ÛÊÀ<PgÏxÖpJÀ´h4e`Sñ îÚÀ,t¨.Z°q"£e"(bCúxR «0¤‘�@RœX8¿Vg ˆ¯�,ÀvãP.&wš&Në]¢³ã nÖ'Œ½w'ÑûŠ mÑ6Fo%gZÌçÅ3â\$Ç£}°$×9£Î8C0Ìèš´.ññö?à_/QÃ÷Gpmnû‰LÁþ„á-„±ÑBAs.Ad‘Óâ+yæ1Ák.+Œ®ç ç+záÅzNC+uSÙ"Ýà qN«‹€@îòë#Aº% `  °‘ô1+32\Sât0�‘¦JšVU V©Â%Í6Q¢–,¹q.ŽÆk²5+%�|RäH’%I–x2EÉ:wJ1àçŽGt&mÞÄ™ó£>X”E©+KYZpx(*K«Vۆ嫇¢Êª¡C÷¤H‘#ÖŠÜyöÁÖ;GŽÄxp¤)ly\x�vÊë” À+�8ºò PGÉ]¼…×á=œ¸îbÅë+ÑE¸0^]P( þx°`¼ƒW¢ ;eÝ\Ð ¯K:õ“OxXyâå”%Z·å‘û'½ÐžM»wìNœ`€Î €åÍ™ë„]zH'P ²¡¶h&L|ón"î&°‰-Y2 &%ºQ'™‘õFºÿšök¼#uê( ?ÿø[cd ˆDê&‘5ô[0¾:ŒÐ¿5¼¿ˆâÛ°Ž úP”ø’IˆE¤p lä "øóð†DŒp0šE¢©Š 6 y,8ÁˆXDÙF!Šª"”Cš`€*ÆAò #)Ú†ƒmv¹r›"9 ž@¤šjš®ÌäJ˜ë. ÀÁ þJÓL9¥„(bY‚ª¢²På=s*”,rhâþ ¡X¸£7k"àÚ곎¸ Ê†­)IJS`Hó /ÁtÌ2Ì ëk2Ã{•±É«ë°É*à Àà@A�Ë\l¥•P›"bUCv8Þz›m¶Ö\+·Üb®ÚÞxã͸'Ø1®&ã¾%sNqËj @˜_j1ϼòÒCy¹+p‘ðh\ˆ5Y›_~¡7™ÿb”‘àùCØC!/ ®Ã»÷8TxÈîùðˆê`øÆhÖðãh6 $ˆh&ÔpBúòíw,^ÆÂa¢�g -â"!þƒølâE¨ V(¢È.šÒËVB åŸdx ÎqåD' .p‡ÚŒzj¯o2΂©–Èâ¢ô|* ¦sPåŸ`&¡PTgkžˆ+·±È´ˆP¹ºƒ«#ø”︶:bÔºüªŒW^-ÛU0^%s51Âlm¬VÌ S•¯U+ó5ô^+«<´ÑEÖ64ÙR¶¶ЄVÚe_¯ö·à–ÕöÛÜ¿ýº÷›�±„jºQ÷óÎ /=î¢ñW˜iLXƒ¼_ €âc€åÅ ãAÖðÃ#q‰ŠoÀ¸B»¿ÆøŒ8Â9Θà†6¦¯»ôö/(XY` <Ðr´yþ`!2;2ê ¥ƒ$ä Di“² $!$ i8ÚA´D%¹c X‰S¸|w¬àífèA 08‰p„¾³D6²'+é‰*9Å6rà¼ã>HR(8"¬¢7HIYîP–Á¡,—¸@¨îpÀM‘oP¼€h&Ã]uF/z e*'™ÌÙJV§Ù"ö¢«»øªWœÖbtqÓ�uª±ÍRr›jÍÕšVqúH›ßä†Ãù "‰sœ6$N°D„'(ø«]âÁ^%M0 y8â~ò“ä± dËX|±ÊD¬§>ó Y÷ê` øäBFXóŒ€1¥þ |[ßz&Äž|È@É0O-¸×Ê9Ș‹8Ë`ÈÐJÛÐY+08:Ä›jKˆ@‚-‘3Kج‚¸B:’„%xÀX3< …î|a„R¦(>�‡‚!¨"8ü8äШ”°eŠT$0p‰7\âN´”=Þð•­@‡Ù‹ùÒ+Vc/(Ug:c¹X&1Š) Œ¡6бqtUJO³Ó;Þf.žbÍpôˆ-Üð&+(‘ !©ÈÞ°cZNÈ–Gð9B'Tƒ“ Æ´‡<ïøË_�ƒB~$–Ë5̃DÆ{z”©Ò@Ñ#¼ÒSÌc†¬þ•Ë\Pìõ±EHcuxÈ=TJcúgú:f‚rY¢:ì"}«ŒÞ3±q‚ Ù ž¬$´VAP"N$å‡aJ•ÀŽ€IjSµ VJ`©"ëµ°—”Q%E‡TiÛ?À¡ âª"â@&Àƒ×EŠo“ K¦ú¦–L]Ê™ºD Þpψôs|ïe‚™`e®r°êŒHCÊ™¼Pî¼8ÕÅwŠšžÎE³i‹P§5-á(kv³1ä²�9Üö®N,à5„¡=ã…Ç«µ`׿ܳ¯шDä᪠ô•ŒUûZ„1T G/İ´Ðš‰0A@þy½C>ÄVúÓÃ!3Â<ú3cŽ'=1†È|˜ŒlDCG/;Á :¡Ùk2ÅÉHÊŠBAŠŒ3hLÈиP¥làBŒ,pNJèš{†ùk܈üa¥,8…(¼UE,0(ªTé¸TG´”å’*ÂX¸¢©¸Xê j¹ƒvq<¬‘Ai`$½Þ`ÍʽqÌœ÷"iÍ´W¼ó­U¨1]+ùšÆÔª)Öžåk¹f¨­Æ—%-ß(‹ÕO0snµ±ëàa!¬àé*õž�b &p}L aï^..ÐýòÊ èÙȘӎÈzViáºòšŸÊp¹©¬Cþ°kŽ dž:`l–:æ±,ö5Y�EgƒÆÙVH€HRˆÎ¢T‚¼ Ùè;rv¶sáfrf½¹§*JØF(˜Òf!V<*Ù€„5xÃÄ‹R·+jAypQCÛ2LfP�^™‚·¨Zã`ZzÏÜes—‘ܤYUÏ4˜£b\JGÕÐW5£ *™…’üòà²ÖÛ¬¯uukñ·77S5X@ h#Á¾Ö$óDY s'7ZðÉ@tƒw8AâÙ¹‡yí:‚|jeDcõg±³,0Q9¡l¬!ýÁS|Ð-"T>ìíê ™ø3×� QXþD6¶¡MpöHrk Îrv¤RD›UàÀ;–vÚçÚ'ÙȆPÞì”Ñ/­Kù}SZ¡§X´K"O‹É¹òæSÔ˜œZŠ`0xØÇÕ«iUÍüú§ò y{Žº(ÝŒ=£d$“Rš‚F ¢ùÌ|sjúÓŸê ëð¯7®çÿÖвµ®ë =µڃ'`>;³c_ã*™†i  Ü{Ù€_XòQ¥ûYÈâ°fŠ%úذd¸wÛ¶ ™ô¡Y„õ¸‘ij˜:ˆ…•iÁXø]‘Êûˆá±}y€7–©P¨  Ê;š ª œþ¹ ÕK¢q„ ªUè䩪 mH lðQ8"a š¡8…~=-9…%ˆ…N)p�_H€°•;84`>_Ð(x84³x® xƒ~ À¾}Øc0™jDÏ!ÉÑ45Š ô#ŒËA/œ–K«ÄË8 ј‹ÑÅb!Å=B5;Bµ«SŰ*±X¢«+ªûJ [Ó£Öпà?*À., 㨆j¸+ÐØ5>‡óøQÊé±$›lX„yX1‚öP;@i¨¼%Ðn”VBÿÀ6U2ÍArcñ˜ ¡õ�ˆiœ;œ±òÙtó0úбþ ±‘r;…Ñ«2&t Ôª ,ܦ r2#¹ 4ø4˜½‘p8^¤H†c �e¨�-AC.À84”�¢8³Y30IUhp€b°†Zœ‚  ¨7ð…Cã íª>_ð1_0F˾š[D“jÄ.¢ŒÀÀƒžÓŒð¯Y5`1#•úË`¿O» •�Eû2Ö0–Ô #ÊŠWŒ‹¸�‹«³º¸°‚8ËXSE¼!œ²D¢¶$@±�ŠÔ倪j°`=p ¨K¨_‹ÀiØ(€°é‰0lxÆOò¿Jï°…UšiKA Ÿøhq±‰¥ ¡¥©¥}QþˆA|ˆ Á¦)€50Ì£‘5 ˜‡ZØ€E(€i¾Õ;š â= Bƒ§ÕkÈ kˆÈŠtÎÞál¨€%#7 …q¨8~²!Ð�k¨¯`¾K!Ï#xƒç«>æ;Ï«q‡}h„ìkDF„ÄTé I£©Í@¢óÄ3bŒ£ËÄ–zŒ1Ø^aJ»XºS£ú¢=rÅ%Ê¡²:¼K±8K´Ì¿ü³ºUK K'8¤o!ÆjàK¨Ú'ÐmØaˆ„ +ï«­’ñøZb˜os%[ c¢rs¥¼ÚÌ1‚pÄ1\r%qìLXÚ¶¼*7Áã°þ1c¼^â¶l­"·rL†"4‚€Ü…VøR'cŠlª8p² €kÂäˆ*ˆ€;¸­ç„S9al˜Æ8\-pŠ¢ εђ*q³¢8®7 º7ðƒíšÁí2ÏKÙ.<PE4† „U (ÊŒQƒ•Íy©—´)÷B©V©œÕœÖxa ˰W}”iÁиxU«»ƒWK±à¶È/t ^„*§ÒKjq*néKPŽ‹ä‘e %Ø ä*~ÁŸ-†ùÌ�B,û‰«ñèÌð�Õ¶é;à0з·Ê+ih{«Èz«�º‘ðÀ; 1ñ°þÅÄÑ*~!·y¸[‚0mB#Ñ,”Œ;XƒhH)lÈDùƒx7Ó‰>0¦XÜ› UÀ=UÀ&¦É!¢Ú: @ã_`…$p¹7ˆê+‚˜õ…$€Ù@4 {0ƒìS‚ì[ÄE̹Jô LÊñzŒ2úTùC£Wù¹_©T”Š/`ˆ¯øZù’•9J ÚqZÝVeP°�[•忲ÌÐ PÞ°E`ýªÊ–¤z¼ŒµØpR(Ìeë*cqùØ}‰¥ÎÌ¥ðÈ—h¸oÕŲtRîá˜hû˜´eÓÑacš)íe°á1þi¸Ò àŽbâgņ5X¦N5%-ãDˆäâ€*è= ÂB"†ˆŠåÝ2€h¼(Àaˆƒi¬€lXpÐ+ ÙŒk37ã "ð+Ð.˜…‡#€3¨>³H3˜É#P�ó´‡~ €~Øw˜T8�Z5ºTšŒ÷}£ùµ´ºx?ÍÑPs^9Êëà ðª ]¸¾Gµ‡a � 0àa°°ZÈؔð°†7°†Wõ›°¸U ¾º®Å`¶ « 4UdPX|�`ÅŠÜA‡â0ÙÉ ãàa(ÂÅžZèܽí`š…9xAxIžñ×ä$ Ür G\jþé°VGtM„XCá×ij—_à‘c«—þ9#È7,¡Â3`à�áòØÞ 8¦ù#b§Þ•cépj�… j8Š…5˜N=iCl⽊£ª C >L_ˆò½Þ˜Y_ðV`ä#ÐÙ~°‡÷”GdDET/I‹ HÃŒ¥dZóS ¥…Àð_IË ™rT%�˜nà†˜nÈåÀ…w˜K˜£R9Œ ÜðŠ ¶ŽòŠ@S"†Wähæ ¾P¶ÌÐ.ÜÝ¡DJ$«ËKÍŽ_�©$[W3Ýabïh°ô° øÀi\þÉQ[˜«VÍÜ—éž·Ò—#q”†oƒô×ô° ÒùxÒ‚E˜è1Y0¶EXãђ<i³ƒ,­ ÊeÐHß½6c€`@ÖGšã”Ö‰à¡Kð�‚E˜FQ�¬ÔܬԂ^í,ä&€†™äI_0ß0ƒ@L1`…Be¾¡îCT£Ÿ]£ìc#K]•£¬Ô¡E/¤¿Ò¹Pþ¾M{#G¼¾K˜wÀ…yù…f@k´&L,¸Ú—"æ;‹@ÃÕÀ©à°ð °è”%âëÀ™k±-±KTo±ËãPŽm9ŽkñK� xv16(P„Aèo{eš6yþggû†È G¿c+öHž5†þ8È\–Àñ@£%¡‘f’âq·è0k#7²h ¤5Hî@^(85S-ñ&¡Ð7¹aš,¨€(h�ˆ^]†+˜H•Öî‘`h�>`và(¨"yCX‚1ĸ‘I–^P7˜É¤þ阅Ù$p1H‚ëj p<p8À€½T™ºOÑÑ4œó_RºN¥‹Zœû䢧O¼À“rk (kÅŒÀeðpy 2XÑáµ€Kø¨ù#æOÙ ¿ñ U œµ8\ ËW}”¼1K$2æXm‹¦=ÞѦږ·Ö~mþà �¨yh6(ç5èÖjmÇiÀŽZÇDh'åLÑF ” `»ZP,Ü4˜Yãé0ÂýxŽžy ÌVªÖÔ±Æcs#qÃÜ$<~]„ZàMŠPš¦È¥’5ÙØ5eðóÿY3ªð_Ѓí–t“@8l €�Ji0M­¡øH4܆I~:YèéC³”EeäóìÞW5 ÐÞCTD‡êûNÛ4ø}´¾H)Ä�U£³•»Œ]¯ÔYÑ`˜²>k28X ƒnX v2@„) ǃÏZ%a¿vÕ¹ök«£¨Á¡ñ7`fþëݰU33Žþ8lãp*+8$vÈKa­ÜA$t�R�½{ÕѰv”MìP…)+VW;Ì hö(}Éa‘b¶ÊïH<Âb³ R»²þ¨øˆ@·Uâ1ïèxþÌÁÚYx»(í\eX„ *I-ƒÔ¦&”›ŒÓ¦,ÈÍêÑ;:X®I'z‘@m@eèK°„ ùR…äÈQuŒknS—ÞBbð…’;‚ž<O”+÷åc…r‡ ØÙŸU£Ë€_© cøoPc8{¹?‡s0”v˜–R=J«FvÀ‚üh†30ü3 ƒ[ ƒ X@D € v °€h4}þ�¨­À´­è|² ®àhžæK¨Õ½ÁàvÕ;€­Ã樲װw+°¼ÔÚol{+€*¹m!t¨†(€ÆîˆLé'wmPQˆuM„ƽ}ðù;Òþl×Îá«<ÉÃ%ù˜f“\»J<'þtã㱸²g‚‘bt›‡î€Fîñ~qÖ X]ƒÐ2‚;Î×mŠD!ˆ �E” (¶(V•„¡âhàð!Ĉ'R¬hñ"ÆŒ7r¤ˆî‰µ>°ÈK–…Ë®V)·e‘Ðr›Ë,­bf¡“…C–›7¥ÈIòæÈ‘ŸGйðàH {oÞøñÃŒ½5Ú§þÏ%pŒé 1¸½‹%Î"qâàz‡kØ»a3ìÉ�¶î.^xï¢èÛWIßu~Qè’1ƒ›°ÄgÈ,&C&H2°!º…ˆÀ­[‚ºs7A‰À.=x0åÁko¬y@ô§µÒ®SËæñÀJkÛ<ŠÄ¶rGö;;:)Îv<xXi®œ‡µUÖ¦[óÍüÉNx°Ëž½Ú“âN°D‰¶&™4LF€˜_³Æ|2 ¿L¬¹a¿N´:¢îí¿q¯€‰˜0`4@¬‘€uܰŸ(þÝsC‚Ò¬g‚<ØØb R‡4‰Ì³*xŸu$³†,@,rž®QG‚Ø7þ#„F,b¿d!„7F…ÛpÁE+\¤ad+ ™FG6™P Mr!Ë“P"Ï$A(Ó„TH¡€è 7&™ešyf™Ùñ@JXÄRd+Û°S(Û„"ÓÜygN§pð'TlÂÊR1üÔÚw\°T¡Bù’ýÀVYà¡Ã£Ì"ñåÀ7£JÒL3ŠüÅ4'¼Ã 2È ‹^‚ÕºN| ¦W_F7ÓL#Œ<‘ÁâX°Àr‹²Ëfæ ÐRC 0 X[BCýÆÃÖ %[Á•ö›¸¼¹6.jáõ@lØVš‰ �:â-×\ V,]<dþÇ‚ÒU÷@5w,÷ÄsÙ)g…5wè&5 Ô’ˆ4þ™¸ˆFœ˜Œ!¸Äƒùí2ò=˜L4P@Ç øà.ü\€‡‰h D-A@_2Bøa4&˜gÄ K@X‡‡7Ö‚á<F|¸Æ<ލ`ƒ Öñž<$sôÕ&œ�E''Y…‘ %™ÙL2YÅ6j·’LLb �€XÇøf¼}7¯ßWBvÚ`\T'KvæÀR(3Ù©§Y4~ MAOf¼QPCQ`¨=ð¼Ïž/uÄ2LÂUû£„¬“ÍŠ þ‚ê©Ë Šê2¬žpÂ[ÃÄšë^yþ fë`Wáì Â’Q¬cÇ’q‹dË>vK7·xãÍÜÕð`íµwuÁÞþvÚwœf[¸ñ6o¿ÝFQ¿…ûÀÛú]œÄ·0mXѱ†ûà‹>( ~ÖPÀÛÅ›2Ç ,Ðî åðMÔØ�€:¥Ç=kÐ}„2 égU«ƒl…HL#C4º¡ÑEÔbEó�Ž„Á2�A(k0AV”ˆh +bOd„8Í=J}$Š%ˆÂkØ�68¦±dÜ Ê𒜄6²‘Mq‹kC¡¶4øC“`‡% ��'<€ 'R@ü1†œþs¬¡X ‘““år’…:Q²“œdå$©“qdb`ÔçŽà“7Ä toøä‚RÊ#\¢SH�ì|…‚F ÃÉHÆ7~±Œi4ƒ—¾;ƒ$`q†eHâ ‹‘Ç4°WQÀäC¯–§+]†¸àå`™nDF2Õóff‚à½ïM€¨V®@îàLá[§aÎåšù™ï5ócMjèœØ4L8e*ÎwšCŠ æS:¾1 Öâ7øÂoP€Vƒšˆ6T>qÚóÀ;èë ô² ˆ¶ž_`#?c<QÆ‘ MBÑH„Ž–œMŒ0å/ íFæñþ{ ° XMñqO2¢ ŒD'It"õÌ7Y“ú è„îÁF6v‘µ%d¬cE“·¶³‘- h�5¢Ð� ¼ë %(ä!©€Ç yýëCÐk@§ÙP…&'ŠÇUr’­ db•†Jl¯,B àP3ø—@ŠÄ †¢ˆÁ¡†úÜ�#�È€X„.Q5e,C³õªŒ Lc’X‰á.`ŒÁàe ºBA:4%ƒ`ý"{Úœžc¼Éq›ÝøÞ-<�TÃ.¸ kPÓ>¢(à³®9Mið7± ‚ ðÅ%vã­vÙ¦S½þ²Ã° VÃ7Óa˜j¤ãšéD´¼uèõ††ú‚¬ðC_á _b³BxØQ Y�hØH¡Æš hãºÓ0¢Ëni’-Sƒ!Ê °iü"T ¼x¡­&¨gHCZˆÏÓT¨•¨DVËØÕ@ä"÷Œ¨h7(@’=lc/bLHi`ë“̦$³‰lEÒ6– œ€ YÊÐWÀÆ+€É ›ÿ ;<A5‚*p§:U®N”Ãäãr I›Œ£š8Bž°Ì.ø“oPÝO.PVˆÖÁ¬0C?ö¡`àbÑø†$�¼Ù «´õ]1i+Œe8FdˆD°þ°npCÉ»‹qmX@—¬f–0]-ì9×1Ý«®÷¼ç$Ô�v¹kög¾# ø €›Ó¤f(Eh][ó„)dç¾Éïs¨ Î�‚«xCfðÀLø}ƒ½ÍІ¾¯˜À+JËïOàÁ}÷%|a ìhç²ÈFʰñ"Íc:ŒÆ/2^ Üà<%ºƒ# Æî‰6’ùÔ�mF‰H„0t£!„u˜Ç‰¡"¶Dr*‹¢ái-"T^lr,d„—ȉѨ@Öˆ¶$‘5Ip*ÒÚ÷å$Åa<He¢Öç3iCÕáÁÃÆþHtD0ŸR`@bYò8;Éi&’lKp’“P„B¾�¥šÎÆ@´1@߀2º7$ÁI°Ç.`­ ÅTHõ©§‘Ëeœx‰î7ÉÐnc3A®j•kÀà!é~‘Í[$ëX‹L±!Ã=ÚÏð� œ� <à4%Àß¹Ìçš¡a\ÔVMkLSõy{[Íçjüi‘zññ9ÏÉàfm4°£G°/(po7üÁ &‚ƒÝPþÀ/Xþb`èÞë‹#0‡¯XÂ(ƒA¼È¹Ç<\ˆ"Lƒ ØÂ"ØÂ¬‡‹™È{ÇÁ™�6ÌÇÈ%ˆUIƒÕÜÀþ†$B¨ÔyTŒÓ$• ÝRÙŒŠ¨ˆÎ™ŠˆÎ "Ù} A¸ˆ˜€,ˆ‚ÙÀ‘Ô±Ñâ( Õ IÁ‘ÄALèœ=„_©™8ÙÙ†ñ€ Îv(_ÁÄ*Ø„ÞÝåø™ìÉ6šåèY Ð!|R”Ÿ,E|RS˜A<- <8ÅiÅ�< 0”À ˜À7€Z1¥ÚïüŽ$ÐÖmѰZtÑ^XÀ% Ó:L&¾NW,×48íÛ±pOõ�[(2˳øðé³z‹¹Dk E´ET·´F»ÜA·LÇ-²‹D±K·x„q<A5sÄsÜþAÀ›/¼[1LÀ@+À_‰£Lã¿9”üùÈßÀŸ/øAS°Â¿‰AD9š5\‚5°@(ƒ,B-œÒ„ˆØB¬Ê7ôÌ-ý‡ÑiLщ‘͘e`W¹L”ˆŒŒˆ4œ‡-œ‡ÍtH YU‰LUˆäŽ ed Ê‚ ÝÊ-A׈H΄°Mœ”•ÔiÕ)‘ VA@ƒ/èb ¨#ae!š< T‡"Ðâä™l‡¿ŒÄØDN\ŽÄ‰lCœÔINü‰N<L�Sˆ+$Á£,…çø„$APÄ¡|RÀCé�ƒÃCÏ0å–$¼å[“ïþüÒ0Õå#[Pâ$@i`¢`èÂëÆ Ëctƒ³PƱ°EW² b´øh0ìå\¾áÛ·f†ù´Ò¸EÀ-ºÆjôÓjhŸxG5)X6¬Â*Á*,l>P¼AXC-ú=XP”Ö‚ùB1\$Xå¸A14”Ã+ÀŸ”–�\À-…C%ÜCYà ¼CÈB¸Ø‡ØAˆüÂ7(‚-P ‚ˆÂÕp zV•‰  @Á‡Õp ÏÜQ9äË`R}Ü "ÍÓXQ ™AÍŠxš2t¤Í„ÜŠ„X-ÔBpÀ¾dn"¡ÕÑ8L�R<ŠC™þPN¡t†¾¸KsDa‡¦ €á¨ÜqÀèD$A’<Ö%…BÚD(H€ßY” g‘£øÁ+4Eh‘RóΣ½ XC ÃîЖ© çÓ[ÒV]Óï¨ZtÁB<tC ÔÀ�Ãixa´d$K÷0 " Ktu@$`%@5%� ‚xCdêi”À0 ‚ÅÆ·=ÔjDŸ¤­O¹U_àÆ-ºo´ºf­£ôAHÇ*dªtãqrc`”-X1|Ry5š/ø¦B-§ƒ5Ô4–_ƒ}cs†ÖB£ƒÜþ-…ÀXC€ DMˆ�A¨Š"¼þT‡HMlj !™ ¸ÇËU¤‘!«}<„ì”-ŒçË%ÕËI Hšœ>fd|,B@>•Í Ф Ä£Óaä`CÄB¬Õ6 áÚ°‘½…Ɖ%©‚@‚™V.”6Ì ‰–èE|„˜uðÀ‰Âb„„ÄtZƒ/¬è)øÃ)ȉSZRS6åcUÎ6H%K¬á&8…çJ82J 4 °Bhíè¡Ä@<…==,â©9©"òðª|ƒl9b#ø°C \‚µ W®¡�Z¢Ô©8öhFÈC$hm°�hC5 6ð5t5 Â$h—%èÁ^*/þâ›Q0,šÏ,’Fià›½}QØ[/Ž °€à̦†*\*„-£ Á‚…*+Dã§¼B1Àí{Ýߥ*9CMî LÀB-gCù¡¼ÂË>.\£-X|ñÀ*DÁ"¤È ˆ (üB4¸Å”ȸ‡‘iL‚ˆàÒë4¤>ÞRÏD«ƒÌ‡�‘ÐPÌzR¤ÕU‘ R̓ÎëÀTYÕ»nÀ˜‡§íÇDƒ2@ÛÐ+ÕeYZMKÂeAH¡ä&+<ã*@lÄJ„°ƒ… {±ƒþî/E€½í­p€p€?p€(°9%ÈVA ÐÝæþR†hÂO”’OÌá£Ä!éRš.‘*€nžŽYÎ@ôô,”ò’°ìR3ìN3UÆe\.™«S€Ï95›µ”†%†©ÔrSdŒž8á)%ôV±°@d: �‚6PLŸvÇ^&�0´ot öɆ·ågÝÁ»ýĘ£f¾Ag®ÆifGüÔ&)X©²Â2>£/¼±$`Ô{œ„1T£µªC=îÜêýM€&øÀÁÀŸƒ‰Á¿5ç4^ ó›ÁX€ÀŠÈÂ"tÁ§‰œ-HÈÆ «<.•‘ÅG-à.R%US¹HˆpÌ~ ddH‰H"¸n ´Z¤Õ÷ºþL"ÔøˆÐÉœHGÀ¼" üáåëJ^]p€ìãjeª²À,W„XÁXõ†vÐË7kD8G”ºXƒ*´�ûCRJ°åPΞ`’$ñ] 0€„ã+iiÝßý1…/˜V†–ÀjåBÕl?à¬5X�±ôìÏö’“öÐÂ4¨Ì/ GÏÖtÀD‹�C èBL0Å+q10 C±T÷Xmžv�%X� hÃ÷-‡¿<Tàé*î¥})Ÿ·¤—ò-߈eÆÆj¨c,²ÒºÐÙi¼fÀ@”jHcCÜqXý9ãú ÈüíÁ@'´ß4îÁ#þ¿B$¿4ø9¾Yû[“äfÁ‰#߯ Ä®ˆ-D Q2£T‘Ù Ê8k,w+õ:ï‡aÃ7œÐïNHõB/ y y}”ˆõöLF¢ˆE«ÒÊíÌÒ Å9Q-ÈBâ´ïƒ¢ÝëÕa+p@@‚Cñ[ƒ¹Ah_:0 nØÅOš ppïÑõå€Ãûƒ?ˆBN<åfÒ% Ú$]ó~9.VZ¤-ØŠÁüsËŸxN‚ÈnùÐ.â4Ð-4@$Ô´X�)L pK,"ø8Û%ÎST‹.¬Ã0exÏè]þ"ä7 €Ç»…ˆéNÿ’í$�‚„†lôex¥×õ-_PDŸµ¥W´ñÆi´†ÁÌ»<йqq.Å+t.¼=ƒ1²¿\CÃ|Á#_AêBƒ ì9Ü?[Ú?s.69ˆ€]ƒnù¹9@Ó—_„DdƒdƒSm0ãÜz0•‹yvаò‰P ”½{¬Ø|Ô‡± ›;Õxz6Rµ ­‡X•õº‡O ¨CÊàœGƒ,hGRY¬Aú–aJfÙÆIø+|jü¥*¼aárO„¬‚÷=s¨ƒsüvó¥ÆÜ„t'¥åÐ&VßU‚!¼Â)±þBÌ¡üÁ¬Ì:^h‘.þ[ÀÅõWLÃ7•êpç™Z$DB� kD›ÁÜA )È%LûëàŠ¤…Î$�5]„cF—~OD (Ǹ•†QEiøK¢¡ƒ¸wCˆ£ZŠ‹»ìežKŒñi’F;Ö ÆØ8÷øoòæoNXÁájƒí6û ¹ZCÃ8Ø@Ã&l‚¿!99ù!¿[C2]Ç_êªõ�ìlÂ[¿Âp4ˆÀ?Ã#æ*ƒ,tB/»ØšÛL'Xà¹&¯JíT4hë ˆ.äœÀdÜ+]C={ìT¨ø˜AvFÞÈ ÒÇ‹ÀÖ³þºÇÒD6Ô‚T€‡IXIÙ°¥g™Ö¹äÈ2À!œµX3gçjƒ7‡::¬[1,#ߘøKªWÄà³q¢ð%ë­—ác¡á­ï>‹¼ã™x7…à‰­’Àž’o’ã^êjRê¹0nY8)ˆf耎l´O \I$ 5èœ4PØ¢=”�5Õ€<ài´\—7È5�Bh<¤EäåÆzFÝPƒ��ðÀ%Ô“Á| v”ÀQ‡‹¢¨F(q¿Áƒuß>Tä[nBØ6"¥•–ÿÀɼ#ü4ç¨õ#“@ÓDŽÕ› ¬^%¼ò¦+Väö¼Ú³‡þ+7¬&B{Eä9h{äá(š&9 A²BÓ'ЬNÙ€$K¶†f²Dk­©cD§™‰ÍŒmM"iuÕQz´Ž5&~™ˆö‹ê/lØL,úÓH"[R�Y#S©ÌdK•ÞäsMØEµji…dQ2ò„mÀ¶Æˆ¬E}Mœ0adQYYÒ¤á¢Xq•*­·’ì˜2e.’[eá  «bD(¾rÈJN1t�P§V½šukׯa³®¶Ê¯Ú¾9bíR§c>\8:+Ö¹pçÎ *Y4oÛ–ez–PÛBY¯žCÂôìÖ[{u„|Œ#oÞIâP +1~|™‰Q0F {þýì]BŸÄ‚$V´aAže,°™f6 „+ްb€ò.x`Šœ`‡H"¡DtJ�Æ—7b@ï �&&!�‘[`Œ ˜¢Â p¦Âxxâ‰J@@‚°Ä Vy€¹#ŠÐ/½" ,"9)§àAÉx«²„)°„’K(èÒš"¬y%Šm‚W&pã ŽFôe7¯XS$Žö€Æ‡$*È—(zS´ŽÈÑ@<‚æ#ö@ˆ•Š8rà ‰öÐd"Ð"E£˜¤Èi¦šƒ¢ Œ( #|ú4š°’‘æ†¥ŒBË' ¨ŠÆ„«°™ a"™Æ„Sg2¡–þ¡rˈP5ë,¥”ºi¬d€¶lË„i&™D¾Š]› é$mNˆe±4ª@· .ƒL²m «"ÊZ¹¬•m8à€ŠbŠ™€ˆõ£bH!ÎàƒƒsÂ4Üè—•¸Dkú°æ „1θµ'V™Á—#îóŽ²Ëº“±³.”Pr8ùd:B'‡W|Q޼#ü`EÔcÅ1ÄHâç‹Ü�Z 3Þð% þècbmøæ—eÎX¦E°`Ák.€§à‰A¾°%”á`¦p y@©…@J`Ê#°œ`žÐ j‚ÂÈ'¨1o 3L.RþH «A‡”; óŽóp#¹ˆ­y·#vFî +瑇;Jx"Ì*°“1&˜À=&(Æ99Jâ<Ñ.B(ÏM4Ù¢IÓt¨$M,h9ö�^4ù´x÷C¢8båŠ�ݨû‡m+&ŠEªm‹/ž°©Å¦:d¢‰&¢Œ­£€£Aê†ûë ø—ÊVª–!Œeè$ü‹JNP…ª ¥}3IÆ«^Å÷Õä-ü#Š ú&¬˜`,8Á†2²q= !ÛHLº,Ó®È<f^޹Ìe¤cˆD"ÐÀÞ+Ü HôÁ ó¡ÁžÀ‚ÚXäv·sìñ†U\ì‡M4˜î°þ5ÝÈ `€É¨ê`;+»Î«0Žp|¬ëy…îÌCž7ˆ!!¯ƒÖó°7ºç nèCàž7ÌàÔÀ‹ÕÑ�X¡’PØê“ž#L¨k˜B œ@‰½4@m3ÐM…¸Ä¸)®5èÆŠÈ j��…›Â)/ œÄUÉGŽø�€IŠÉ‘[rÆô†‰I)dWÒ¥.wƒœ7èÇÉyCV±µTäQy’&Ð(1Ø#‚šÈlPá•£øC/4`( /QŠ"Ç& ¡(tFä$iãDò(MhÀR�Ë“h|ñ H¼ ‹� N’Ñ(˜`F‹Xp„þhÈ" P¤Q�ûåo&þ¼ÕP¦²+yLã,v± i,šä¤X8ÑI^…¬5È‚/uxÊ/jñ«d` ÓØ€¯ÈG>e," ,Ф  ¦‹]a½*ãÂÈh&œM¥ö@½èsVЃ±º1RÔî E´/(¶³f•¬­q‚(÷€a‚ÌÿP\¶Eë  ^Ò EXähõÑM”´œ-E€O€†<,i]íÃØA a4cÐxP{xMB8°G„Òx„ ¸cG%�@d)�+A`fHz>²;Ô€H膋"Ñ !î”\J%y¨´ÉÂþ �NØ›jÏ3L$·7E@O› Ý´*àr—@N˜Æd ¨.‰wØ$+Öt‘(*O M!¢‰BxÍÛD9‚ÎrL„‰ž¢ð»lâ#¯�TT‰�(ìE„PHyGÑb4 4i¼µˆ›Ì„.æ3iC‚af¡´Ò¸‰­ Â¿oLMA€BWf S±D£¤9aq…ú—S+Ãk˜Ç<Ú˜š@&·ªé4´ÂbóԤ胚ÐÇœ°¨‹q×c*ã®{A'"pHT ,Š<jÕ(kYõ �H¬é6µ©ng±/¯5訆ѳ›7H pY§3pþqÊY¨B%r@.åÌ%‚ÇG󰄈A—‰~Å‚‘"¾Á!#" ¨A «m€NH<Üê~íäG#y‡fˆN¨kGô?$-w¸D ­ D¤LÀ–l„8Ñw“OÒi<@ 'è!‰èY®~>7¢"äÎH|–ÔšÝ() i¸|ƒ•x0Gð:4Ш/¦æD߈€Æ†€žò…â ”2'¯y's^ªRÉ{… ¿@`G]“"˜ê>£pÿ¹ÏŸ|Yƒ-ÚB>÷9°+49èœÐdÙ ¿øñ4„Qâ_°oÍIX&˜Ð '£Z3yèNN5– eþ(kà8ÿlÎ⑞� }x‡À�%£]G½L»â…ôí´à’RlÍ*€lv";Ðp'ðÍv¾ ­aõ/£ƒÚå¶³û0p¨â:xv;uîUP´ tðCr|1k̉á qT<Yp"ô=·H{|ÁÆi*`X „<"!�”€¢ õ©ÝÑ ÍSGz�$ÝüfÆ–(Nç±®5j@[K@“@€m£;¤Òl˜d\~„šd«Í¹qÖÍÙ“x„²‡©QLbèš$¥â#§I¾ˆb’d;oª‚Ÿú¯€Ï©#†Š^D¶W_îS4Á«¯ȱýÁÃÓ{þÔ+É�l8'€±É=£bEô«ä\+9E•ÍŸbUÎ(Z*¨ˆÂ¢¡ãte@~Áláæˆ¥&l"ållå4®~*Îæèb(€�8®.xâ¢H%L N�@c`¨¸ èì%^&CÊ$ Z&6O^Á úÎ"$âë ¡x@ì~È Ð�˜ÇfÜ–ç Š¡€Ã±ªì¬aDúàˆ”H¿´#‹´H¶a$`ÊॠZ @‘ìƒD(�±k4~ðQ®àž´g¾À˜‰ }ÁРñ:DtDGBm´Dëf©k6+­~äGV|’&i>f¹œk¶øÀvþŠ D4 q€ö:QK|5, �’kbR‰ÖÎcsŠ/9îàì2ëø¶&b(G.!9à(çúî ¦ê©à)Ý6á¾D¢yæ‹Å#0#®iöKÊáú<bO&â �ƒQüÞލ‰?šIÄ1 j!Ç6� Ðñ/ ¥-Œ�3¬¢tÌ*®‚*v *°*<ÎyÌ¢,H*ŒåÿܤêÂ,NeÆ„bÅl%¯ þ¢+º¥øÅN6Æ!]ÃèVÊÖ¥ ª# Z %À,žà¾Ž¤ 3¦Š%Qð*ÂNÚ$HXÒ‰ôà8ñ6(&ØN^4#þ DáÎv! ºƒîB 4!JÄ >†ÒâI 4ê™éMHàþònP|a¢°6� œ uNi.@2ï,—ã ´Þ�.a9ЦšoÒ&m˜HH¡2-�”Ðau,mN ó”B��:M»€ër’ËD$SŠ.!ÍœD2ÁŠÛ$Fú¨+dÜÉþìêäQÊ/x6Á¼ê+!<‚Q�ûK¿â›ê+55Aþ` bûþm�îP,"Þà"^! Ý�þ@"@AØQ àY*Þgá~âSªE+p…¦šóÑQW,ˆ*¸S¡ bƒø§.DŠ|è¢ÂŒ¥¥lþÂYÄ‚A̦¥úÇÉGûàþäàÑE1bð… l2"#3ppTaØh©G±N$ä� Æê&  �S¦’:.‚_xàA!4cž@» ñv¬mD`eª@‹²¨(‹²;$€î@ö@‘’ëîÌ!Ü`ühæ"®É!ŠÇ©ïÜ(ë4°àGJ F‚ qp¤ßRl"ÄŽ@Ž�¶D­ò®ˆ(à6ŽÀ¬‹´aƒ�Ðfuz‹0{ë|¤‡ØÁØ.™äºxF7@ÔDÀJJ€O—fÀ·¦f¬‹ÛÆDJÂdPbýÄo:£†€Gðm˘{¢n"Êa¼þ‚4 ‚Q5¡ü2âÝxó´©ÎH"g 5O@5ÀF‚N€ "¦Ô§+êb(ü1ÇleZn¥ãN`njBîWó⦾áZ6`¦VÁ±B%(l®:W¥Å&¨¢Æb*úç*äÁöb¦:ÎVˆÂ/Nà3Z“¨@É#*]Sè2Œ’ª€¢n�†�þá#>¢¬ C#4ë>ƒOFã"Ä Ü�ÔŒ_3†l‘Û’`L$‰6Á‹NFn:n0^莮À ü`i~&¹šPî¯ï’æF9‚!ÈC`Ä °Â!ü ë|¡° f`;qt$•زA>Ëþ<ÞRJe�¨ô ¸M`oÒ&qbªÁM[¯¸œà ‚Íóz«0¹d“Nà ¨Á®ÐD”IJd¹’K»Guz‰—§IŸ�mNG"æ0Ýö ¾DsªÊ ö "Åw® `Ì æM ¾È¡ÄOÞúî ¢$‚ ÞàÑâmOóR^!$ ájAj –5’EžbXMà ÈãjŠWM×W}U çq–AX9Žu¯‚ÅdbVfîÅÜå:H(´b>u¬oN  ÉgLŸD`è£1T3f:r  4À_â–œ.En‰�è –Cö5ª¡îdªô©w$ERúþ »axàú�ÑìµÎã faîV†(öΨ r ,Â~!f ±."{®L4H„DTlàgÖcn§‰€$L ³óΆ-áá³ú¡>F ‚Öl.$LúÀ" ˜¸”ÛÔȧøÀ,œ� ÖBjG“Ö¶•Ôæ…³D@GJJB±¤s6»ÆK2JzƒG”¤æpûàV7ïO$¯ ‚Rª×ܾÈáyNq5áÍP3ýæä ‡$â7ã¶œ$ ¡r£@2—Ų¢s) ‡¢¬Ât…!ù¦¶3än**’õ¦te :Ž­b,þæ!YlN*‚ÌSpBç:£4™æBn²a¦üøV¦….”!Qï0èüì„èE]^H2¸`$À‹v‹‘G!"à¯"k~#}aã f€$愆*bÌ܃`ÝÀ¦Ð—…c6à=bàµÒè ¾€ Â!²~+¡BШ`n&š€Àémd…Ô#ˆÈQêЮÀz,¢ oV¡ªáiG‡KÀ0u¤-)l6«ÜABÂHÖw& ~!q‚{m,÷ÙG$ÚG.„·6)HÐái·†rJ-Î|i©h‰©rè¸-ù¢èr˜Ã0µìMìšðiÞiP&âQ¨‡¾:¢þ–óÄP¢qS“O@%  Eà«QÔm�¶çû¶ÇžE*w!ã‚(þ¯.ÀmÎÁWmŠW™]Õt­Â¦hÁ¡` �¦¬BsË1 òg¤°:+žåY;ˆ|ˆ….<Åš“!½¥ãüXáAl‡�ôs¨’*2b–!Cf !šVÓœ4"À,BR¢P™—™™SCÀfçH€B_™}¡¬{5û5Ô  ¹f-|Á4 b¦Z�и9rÀoß ~+¬‡wþÍÀ¾¾@ÞB!FD ŒÓ=í "ý ûˆÃ´¡XÀHUçûù6k³êãÜþ!„Ý!L´û b𝰶T f ´AmŠëH 'uìû×|÷ôûØ&7tãMdÀ$ŠøT»x#LôCP¯‹q°köx�Üè BP á67¡Þ&å© áë+zÞmûμrTr—h^qÛ8ÞÈ záP BzpuQJ‚žÈ ¤@¢@°aWq. >¥-€ÀÖ3çZuYm*/j(0Ò:É™W£.B™<Ù'ä:çø‚wè’±z,ÒríWä1}jЀÛLÀaî(C]–L%ƒÊ²� @nå–kˆà&¨.µeÃ늨A‚†–©A™HÐþ_Ã8²ða^k=~FGÂI4€ |àö�hŠ�÷ÊChàˆÜ°ïnG{ï+B#6¢På  ûy‡Ü`y 6”ò jÑÆỖl©lI9>ò`ÇeéyÚ N{¾Sç×€$Ú£ýרýGŽíCq ͶôH3yƒ7lñ|Ĥ¥Lp©ˆû™tx4§1{€Tó¤Pà+yVó-¥=—¾æIì]�¥‹;ܨI5"&%4ˆ�zp ÁìXf7ÀVæúSÄ¢ èS ¦hŠ«££ø‡9›39‘G…bjXŽXj.¡TpÌ|0ù)ð\hBþ®;£ ˜ýðõú6Ár …éÄ0 À®—¤�7·ß2âúØK V’ÑQƒú€všé‹¿Or¡i_©Þ5FDKæÃexÖòÉ È# Fn>ï .À?Ì�Ž’ ü£w ÂwêKÞ,bN`4Ëm  ®hŠF nêzD†«¤·.àì£>6KB&ƒÓ£7 ¦`DdDìáÛ I¢õ[¢ƒäô¥]Ú »Šo—”Ïr’¨¦MùȤJ*‡9¨+‰j·!ިݨh>“ëkl€Öϼ$üÂSüeûþ�zþÞ¿fSx,EŠ Õwî¶¼4þAÇ!!,i5tQ®åZ%( ÈVj*¨âVª"ãANuEþ£þM~ o¢w+ð' ²ƒ�b 5 $¸(R7a‹ŒY­6lP6D™ØçŽr{ö#B„•& áBU9™¦Ê¶“\²H £J´ {®¹Òq‘WDt|Ô#4CTäT€4©Ò¥L›:}Úk†ˆL mç+œ³Þ 6¬Ø±OVùò¥À/1o’°bå'‰_~ŽÄhk÷ÈxoÞØ{à…7¾b¹ëçí«2¬èŠóö­˜#÷¸ã†P"_l|yõ&2+·£Y]馕¬ŸLáìÂÞ7fþÞÀã /¼#öb˜ñõûÒ”è.¼Mâ‹p_{†?áÁÃÊ×O”x‚ý ëè¶o×ŽŽ‡5_3¬1¯àÍ%x¹ôÆÚ¥"wÜ9RDÁ‘'Ú÷ïÏÃÏÝ1Þc4é4?i†Óg¬ˆ‘ØVíñ +™½ò9äüQÎ&½lBΚÝôŠ/nì 4šPÔ+{øÄ‘&+v¤ 9¼µ“‚šP!Â+bøò 4ÈÅEó¬ñM4Ñ$Ðó$bDÒ‘L"VÚ2-X~ƒÍ/^*ò ¿|#æ/ÓÈD7ÝÈ &Ô"f-µ˜�„CaBžK&³†CVòéä"Lò¹ˆA‹ðþù 5 ˜M6k(3'LƒM‘VÜáKA”8mBE¡„’F©U”:N("@ŠN@ó4B£SP6nÖ‘"8`ÅX¾þêÔÖl¢SH(†ÄS§@²ŠÀ> íR<ô¡–5oÑå‹…jùáF\kÅõF?ºqÁÜMaM_—è•íbBÙW¼ $+ŸµÔƒ?>¨Ø²†x-$ù±‰Û%0ÅEØcW_ýØö†]1ÄÀ0oGÌ7: ÀÃpr_ð€l~ ;§vN<xÜ•°2wè k}Eô§ÝôY£�}aÍ{ ÌôyEǧ€|E§ g½BSVšþµ¨Yi[Ac“h.f"9 Rxa…k9-BM<ù4o5Ö¤á�Z ì¿{D&$‘ʘ`žÑØâ$ UJSGF$x"Ù±†-Ñ$iÂ7^z)¦˜&L#LÔDÓ¼é%6s®QåC™ É$38•L®^PéJ „0˜€6'@!éÊÔrB5Ö¸!G6Î{Å�šˆ * ˜tê8-dÁ€!¬r¦ ñvä“‚^‹¸Š2‘âl´âCõœÍ{ìU5MÐ*}„?~üañàK1hqVþ™–ÄeI˜3Üe7øy�wžpݬíÚJd*¤HF^ZÉš… ó\Eþ . ¸ÅAéÄ,»Îb£—¾üF\1HáÄdÃ1“• !c ~ŠPÀ£ýHB ôS®æ 'ÙÉÎudÖ=\§e"qF k$ð„YEÍ´¤- ‡<‹bÏ€f¹ˆÁ_Ä 4ˆ5µ΋\ÉNäÕ=â1æ $ÀWcÜ$¯ÑJA8aÅ�ȱ¶/ä$CÐp[GräyAÃr°Û"ê [HJ‘’C¦4%)%KÉ0ˆ’€À¸o˜àÍÀÝ/F 4QƒòØ�6LðJ=¡®J@X„뀀º>AòH‰†,"‹Et!zê’硌E˜ "Ó˜”0*e=ôþM@†GÈñd|á›’‚T‘ƒ„‚à0Ä܈ !-(&Có’…�¹¢«ÑÊrè ä‡O¤Hå ´ª•‚^Ǭcr˜�ò‰P¦Ü¡VÉ–/®R¡\È ¤‹^Hv„”P;¬™BÂ(ðÈÀ«Žo™€ˆÞ² f0—€Úƒ¶ò.?@F2 Úƒ/î`$€²9ÂæR›7ÜŇ;‚ ÈU®ýät ohâúá‡v,ÀfÐËÅdP®é\GeOX™Ø2ðV¸„5x†Ã¾”‡gÐÎSŸ¡ÑÇ>x ï k`†(Ò 9 XÍ­{À 6ƒr>ÐÈt¦oþAßõB2"Á“)rOp"«œ¨¨#”ýÈF¢ Xi‚TÆn ¤dÜ pFȤàQ¥ÀîtÉ– ’§_,c’ûE—(' ÙQÊs&PÄçf¹Aä!kHÄ‘(%AW É]Ã27`:eV*¸ÁµHï¬� r”£/Ò¦†zÚ~BCì¥,4Ü È?hb�‚toWp¢‰Mpeæœ@žÐø­Ì‡ìûXa”ê„èpBѱ ð$6Fû(4¯Ç¼E¦>, XK ' £;×9rÞ †"¼!G ‚ dB$"îA¬€O×¢™šÐ%‰Ì\䋌’x Äþ\(@±‰ ÕªMlî0œí\ño @ü@¦ÉzáX6ŽbgÄHtX*§g=6~gð#’™'DîKÒv×`ñfššV*ä–]sÆ…‰Oöø…›H& r¡hüŸ Z²2J¯£«ÍKyÑ+4Q ”Cx¬ˆƒ’[Q®¡�‚«%UºKBÄüd4<Ù¥Š”IN¾…Â4~=‘Q.sPh.¬›:d—.ÙÒîtM°yÌÃóX| \nœàÚx‚:2êWXöED�5¨ËÑ“œp³²Ê/ŠTdÊæ›Ø#Hˆ° ¼¢«p°þøZ&$³ù„'4!$ AP›ÔßøD‡LÁ ¦‘_ù‘Ø'†$Ìõ«^…Yu¨Ì øÂl‘aKbîõSg<k†H}ü-Ú¸¥.„ñXkÆ›SŒc»iáEÉU!jµ;<-B?|q2  oðèx±ºöçËGä(XÍ<âçøb]{±jFö7\B tO_‚¦0ôH±â)‚ó5—¸p°Bœ•ˆàvÎv$IÀŒ¼2þÓWLÈ&øJwŠ&DŽÂËk^-¢¯N®0Ykr rPAÌ5tBpAáryJêMI¤W,Ã4Îå •ºîRž°ñk(\~p)Ôtþ ò:*‘º„*j!y¡ólÇݰ€OèŒq6Æ ^må@!¹‰rÌwдêþPη“=˜óX 9$ÐÐ`†«er P ï"d%G ‚ÄÂÕ?¾"2mi‹‰®å1Ñ„qÉ‘feà‘�ÂG�yW`cc"Õö >å I€bê!SÁ }q1�dÿà µ±Xg¡QÓv2E1MÆ0»A@@'tS°Dó1`e¬b�Btw‘QÓ1øAƒ[ÅQ#¶OYG?o z124o0E5v@4g4:s sV ”.,g!ŒFS³6þ7rC_]³Fó²�>Ô?o‘˜/—/‚A0ò’cpt>’Åà�‹ðKÄ” u°y°Õ'T(«CL¤skµ6´{¸K°T¼õJ]&žÓ'PÂ'µ{¢ˆ #8kP(ŽH:°$ÂàÑ� ¸s;Ü X€z€V°å Yäi[±Mèã"Å£ ½ 3’YpÓ}Ú·G""~›`Äb› õ–o÷‡¾ÒrP![q µ¬`é—ÐÂn€,T!Á}¡ïH3åfwàU<P â± n&‚W f`Qepg‘ÿ”G6 hg-vþ±F%Ø-}0Âá8„?~=ÕS]ç„#Ód#ƒ33t |ºÑƒÕdÀñuÓñíAD¬!bH„fááVA8'ÓéR3õ‘vça6ù±…ë¡BU’áò_ /Ý@á âp353&x|q‘ÝI�†ä6„Pl”W�••!�…UXŸáx$nP£ Ê `B;²Å\|r:”\¦‰zB:Éf “ók§ôz™¸§9§´ˆB§SKÑIáQ]Êô ·3 P ¨’2)¥‰¤��<� " }"x‘!3v/{Méš Hþâ¶G~ £jž¥µ²›@œ›ÐMÐç8Rñ}pÑ=Â3ýD«Ð+Êù,z?•¥1É¡�b0›@Á�YÁg†Ðq,`"ga|;lÄiñ—ƒõäÀ‘-~PeÀ¡qq‰®ÁS÷ñFÅe€U]G@»Ñ-t uuÿ!`( Ó;NGuU÷UeöUÓ2€†QTx†Eÿ…,Å„<fýAEì1 ’pÁ- S�6’–ù¢0Å P¤'‹Ñ¢H"•/‚tR<*‹7c7Â- ÀÅPy°—z&P7Ðþ †“\›ù:¶´zzBzLBL¾¶_ŠJ”Ã[°dL·f%Ÿ7™|rk«#( ˆŠª]Ÿ) ‹’ Ê )ذ''À XpÖPnåÀ‹/‚M0"¥r#¢–×SX‘›,²Y׳_}%îEœÅ`báÐ`>�Õ:±Gr oDà ý–ª¿B?jáP„Ñ%§ö)ìãf8”øhãÁzR©?…`mS&lÄ}ÇÈqfð v¦.ûáæáSUtNØeJ.·a S.PŸq );h;é~@Ip42bfuH8bf–46–õ4Vpõ¡3ãÁ„lþ¦0ÿ¡� ÔTüa ùLqÎZU©£M)¤:ê±rè•p”‡@_£Fr|uXët#,#·™an!©W ÙÀZÉ�Kjª'1'‚¹¦‡ùˆP ©ç[fÒ]n"'µpJ@Ày“8{¬3ЇB(eŠŸ¹AÀÈd¶3 ï )X bÖpx+#3¶Z""Ž÷G—jXÂ"("Œï¦"5â6¡ @· Rá�æô F:wbœD ¡µ}` ~ë+wð‘-Œ–£ûdàIqa˜EÅŠEé2€èEÐ?ûƒ}¨qkRÄr(–ÀÑíÒþ>Åûa¡$3ðp##ãºóžcT.Úªtp‘aPWP~ SÐ:ø?G°“—Ь0G8bHIc JtVV˜°Ö<Ãfk[W3g…-3…!›�•Œñ¼ý $qÄ• ðŒÆAUI nA<ð"Sð'H>áxÄã1Mù ÷‹7ó6{0D’J™ˆ7‚3)¸S ¾'lxkaKÑð[ ¸ãkÁ ®”[¾µ$®˜Õå7´•й$]±f]‰Ú 'Q ·#ÄïpX`©y"‘j_0#ô ~!£! ,/5qM×ÓWXœ!’Zþ#‡çâ?ŽË%5cI,ÕCQÉ¢ÉiÆ`áÓ„,ZÓŽÂ>@B‡õuùžÕp¬E`g¡@eBú- dU�êsáS5g}!Sg1j)4M§g²Q  2¡½Ásýðžö /ò~pXvlp MRýpðP‚ö0`æ�Ð`ÏQ322nVW:#£E43� “vó ü Ÿ;SŒEr—ÁŽ1•sá¬Rœ¿oAùë.�ª­Q<u´iÕÃ=ù?â›bÀc«!B qð �µ%‰PKÊ´´rò:Á8·fK þc ‹ð ÄFlaò *, 5{´®×\‚“ '\˜ (´V:½gâ3Z¶ƒ*;'°Ñ„}ÐA€´Åøâw3¦ {¸xÝøœÒ#ïwM)ò‡}5OÕÇKRPo¯J!å ÷6ÅÀoAý<° yœ-×¢†Ëx½ê1G„EcÆ3«À„A5)vOùa¹¬ÿ©¹?B‘|¡bZ=€!'6è _&£E. #’æÊsº1¼(¯<Z d$à âða Ð×peŠËl Aùš�²QW2ƒÑÑLh»<ƒV 4¬ bg¥¾Ä¬QØaþA#6ù¬ûÀ³!S“µ;Õÿ#T8ÖÍSÙXtñ?Vm€8Ò"&U5xd�#Çvô5�ŒA�)}’ µ  Ãg]yÂ¥·l#LÂ&,˜œ8amÁåkn’'¸Äˆµö:´u¶W{ÕÕKy’¨Ñ\¶È À P€ÚàˆFY¡Å‹T3·…!ØSÅ676a6=Ñ=Ò)ÂS² ààN½ .wš!–‚G#ÂÀáM¡ êè#jéѽJÕm]é¡�é1f<°…kícÕkbr×ú~&ÒFÖìúÈA�»:»&ótëQ s¿+ ãþ·Áå=xÑÛÎ+/lð® @Jǰ|Ðeð¼fpËÎ{eð°“?•QH�N°ž0¾u³°54Æl OðuÀ€E=Ó°ÓáDw`ž¡Qä³ëÖèJ‰bâ  q!öŠq'Sh9»­Â -Ô.—Ë Å€#l@¶?Î <±R  QP%‹ ¨ÍÕIKR¦µä{ÖuJ¦§˜¶ž è[yr& ;pº$PâI…²z¸ÔˆM(…R:‚²Ÿù™¥ÓL‰*§  ì��O#>A#3"·ˆÅYœB².Ò²;1�&+hOš`Mh#·{ M �–â¾ü~ÀÔ=/ÿ´?¤þ¥ïûŽÕ° Åp!àù ¤»/2ÎrÈrÈ¡Q-ƒT”-?…”‘—þªï?¤bÈ %£«~` n¬.km6uØû~}°ÉsÌ:të ÙÏÛY‚ðÐW CÀ¹Ðíp K'ŰØÏë s21¬Ñ`HȤ` ÚPWîQ£¬½3R¤Q ôö“EPÉUwϼQ µA@<æç 3C¥BtÑä"5 pä3µ—G5Yp!1±»/SÅÖMˆ=Œ ² §»N]¾‡¦iºŠ{"«wJ¿ÅÂLJ;°DЍXÂÊdÎ&ŠþÉFß¶¤LX‹ B´%ÒXÐ�!�V Ü}¡Åþ’À×j9‘xÅsM™ªnvÕ²"iùI†P"pOߦQ×"A¦NnðÞK j™A¤¡/!}qbÚcFf€cj!vá±kÑ܃GbЄ6  ŽˆñU°Á7G¾)R¡¯7—ŠL9räÁŒwŠÜ¹pሽ#ðBÂë(ò‚’ ýÚõƒÃÌ53.˰a3äš;3eH”ñcà‚Ÿ2¬Â˜éCŒ™7öJ”@‡€Ó',läñ H‘7 ¬)à¡ñ’Àw¾Z»sç5OŠX+RÕÚÛŠGŒþ²¢PaÅá½É{äB‘#Ebùë±âƒÂqñòel&É3¾’øñãÆ+VI|se“=ÐÈíÙCäJi?%ÇH¢Ð eÊ DS¶!Ê"#k€D²¨÷îEÑ|¯1a"Úq »‹óRÜį_P¦AÙ LØ4lP~Õ*$YîÝÂu_´fp k’%[S>Ù"çÙ7@Y”Ìĉ X„m‡‹'Є MÈ!C4Ù<M ,GƒÑà7^¹b�Ò0Ë0´ÑH{å•®@f_1í ÒöÐd7œ`Fk´ñFsÔ‘Ftx°Æ 7Xy31† ÒVˆ2Éþ>vtòI(qDçG‚¢ =|Ìì‚è _*c艥–Bç _ŠaE 1ÖdI‚X©LÎ0‹4ªµÀÊJ Ž(¨µƒ|,+_�S¨K‚ ‹°'.æŽôŠÁ¿: ž)P2ž~Ì  NÍp…^Vº†q`2CT6`‚žUý �w`ªÆ'¬¸¤,«¬yÀ—KØzÀг‚}+"²ÌºcŠªÌzÀÇ;|½àÅ %̪Š<*ì"Œ:B¬£Ž˜".ºÈ0 ±Š’ˆ!ÊøRÈ—WHûB 6aQÅ+z²#{'Š(6Xdl°I¦ŽÜ„sØ8ã¢i﹈ûÆþ9ŒMnšêä bƒ„±q.=Ý‚C®½ãÌÓ=”Ë;¸¸kQf YjñO¿ü �'ØÑD„^"|p�"ʉ°ÒÈ™°œЄÅ=*K‘ÄÛt1èѾ â@M.ÜEI3Ä9ôp"J´Ó®;6RC!Åp£MV®r"X‘Qm¾Ó^EÉ7Y™{î"éý7/Í’#0*â‰FxbŠÞ³W ïkÞ¬ŽhÐ@ì 1Þxc ³¾ÔÓ 74³êªrb Ò ÈL *ÊÙ‰$p_}£ŸLSòô^®éÇú!ášžú‰•†2#žx釥vÊãx”—©½€þ¶¬µž`««g›Õê-ÌjÖ¬FŸà¡ª®ºbZo;Â#n¹ÅHÜnáoZû#`·s¿ PnìòkbðÁhè4 iÞæ‹ËÉÉŸõ`CF¨C"ˆsøˆŒ<É�Bt.ŒAì0Ät°ajÈCX {s g7êqyŠ£²bc:å1‚2¢Ð�aø'аϬ`£}á 'B‘‹ DŽ|Ð@9öe =\¨nCQÝ2! |QAšZ_ñ…+äq_€Fhˆ`…'ôM;B‡°™7$©M—›€†ØH„b4e“ÔÑ*H“7 3˜1Ícþ§Å™N”E(WW6b ˆ ©jWÈÖUîR.‹ÜO”A%+L7Rd–n �VLW.R¾ÎGÐH¹ž�ùå.1Ú²TH\r¿)ÄŠW(pÒƒR]£ý(CPA‚\´ƒ¨ˆÇúx°Çp Öa+IΨh±ŠYJЖ°ëYØ)}5¿aýSrôë ¸.àƒv„0´¥(U’Wá 8è®Ñ3 £}Õ¤(õ*ÁéJèþÈšËøAqEºB›4dšW\Æïƒ2°‘5Ø”„,Ćp|ß°'ÑŽvxÃ_g7߀‚v¤c¨rÇ*K|þ–2–é&9,+Î{Rh‚ PCK6ôƒ…þìç€�€5 M¤ÑŽ{„9´ˆ™¯Ù-¦mŒ)+J”GÌ àmp»Ì® ¤!ɰvÝ¡bXƒ’“¥Q ¬a:P P®ådÚ”·>첓lŠ5ˆ€Ø!A"K@ÂŒ .Á8ͤÆväŠEºaHpfÃâ’lU$-‡Dˆ@d—•K`ë—xCåR:»ˆRu€áÁJpLÊñàìTHô×¾á )ñC<xÁWlï¼üÂ7á‡N¹ãëp‡”€wÐ aØÇ:Þi&yÎè eË0y°–"XÁŸþ ´ÂRþ®gA%H˳ÜáXõ@ÃîÁ®±€ô�Ä 0@J¬aà ÅðP±†ýPÑ\ãÃAˆ0‚2Œà^Èñ|âÃïJL\X#$ɨ&^1¸$paÓƒE>FhNOëÃBÂÇÁ1A q±Œç9Ñ©N$6À±iÀpªêYÏxÔœÔò�G8F0{ê31„A¡c=XüE Xà �P  -#,úB‰^”˜.@CZÔâðHM!ÆÒW¨›œ‚"§$ÜÑ‘¬X€e’ÌTf¬pÀcC;ZÒöh¦“ G`á¿(€ ‘„õdÑ¡ 7¤òM’IRjÄ ™þ7\Fqrb“ébi&¦,¥Q—¸D\|AàV„!°Ã `2Ì[odZžË `¾‚Z'E”±ä®;¹°Äå/ð°GKD"ÞE3 âh/*x¸bçõƒpp[-%áŸ0Æe+xJRFOÐÆ[.á \–žw¨Šä¬Ñ¨fÏÝ“»nZä‡ «¸½F\îaÿ˜ =`Â:Lóà@ç;ß¹4ªákØ<è h9Ž]‘ã2¸âK¯ñ›ÞƒIÆ™ï’ËBbbº È!ÃF~¦Úˆ¹¬Ë¿ÈŽ Õ<¤ª¹‡]æØ~¢3Uz‰4„Ä€hœõäÆe@E˜0"Ÿ(þ`¡'¢0N ž) ƒU¶c\B™½øaB*ƒÝ$¿Ax]†eˆi3MW,ZÑ"šçcê ©Èn¨†h{­6 ¯e¹~r6^j‡Ì(Àõ¯WÛ”X1ÁŽÈE(ZæÄ@žÐ†ö„§�9[K¸d.C¶ÝÜ«8‹¹¾ LsÁK«üÅ"ˆQ>øGw‡cJ»\â—AZà¾K¼'Ç5j‚Þxô�¸p}#þ”¦��l ,@�0eA¥· ¥ k@|šŸ;°‚²°­R2&É9‰þË@3€»(§«9c‚šÁø€Ü@Ÿ›(Ó9lAŸó±û  :—þ{¥sWð±2ð‚#±Ä ºÅ`ˆ@\�«ü†Ûâ:‘ù…êXŠI0ƒ!æ³2“‡À-K‰QÝP;ò�ªðP™ˆá2㨅ih€_(jà† àaà†j’\1ÉpŒËp <ô3 Oñ—£ >Œ~H‰º·><©WT‹)Ë`WР@5 H°†Ýã=(™0s%Rº —ˆ–P(M춽 !!<Z’Ù’‹À ƒ+ˆÃ.@¦Z´ÅhëÅ #“Üy¸àEdÊ‹ %‰@°bY‹.¡œ xk“°ëÚ§Y¬ X‘Ø ¤þúº†0Ès€w²¯ ø¯l '(�‰§§@‰s ñ±-³x>c‚œ{‹BŸƒ0cª |¬¯ ¬/3�”±ƒŒ¹»&± ÁœëŸ[1žsAìÀšë± 3:W°ÁÄ1”±ò Q|Àp Ê)H�«iˆ"l”Q! ™iˆa°˜„1Žo¢h¨¡ °ÉëÐB&ó0™.Û2¾û!"2-;ùh*,°€¨,À(°��P‹¬p±[€$ðK‚!+1<žx1Ö(±’¤”$°Q<34É{…$˜<! ½WX�?86Íø=Ý;E¾)r¹¬È¹Øþ{³ˆ´�ÌÞ³Ó fƒ Ð#ÈÄ Æ8ŒB8„—ÉáLˆ+Ð,[LfÁb$Ä€¥ ¨6À0‹À¦­€Æøa–ÉÑô‹6x³Šö»�—èÃ¼Ø È—)€‡íÉ38'ÿZ‡—4E'p7ð!@ǧë\–êª.È‘›f0ŽÛŽK‹ì|Cþ«/ûR‚ c±‚4 “1†|2xÁ€Á”ȉìω\ÁýÔÁx9ñ¤ÃA1½L±’L ¬`làƒn „ 8ú8(™žrŽ”©¡*Žo˜!ä@Žçè˜H€©2Zˆ™,޽k³6þ ª5¨+{éH˜¦j€›Ñ8(Ðt(7@†0"g`„DÛdpM€#�gØW°gè&ÝØ-ÅA/p…Hº5±S“¼Só ¹ :4e ǘŒUÈDÆÔ‘3IÏy—¼ˆ‚O;5xÓ(A'¸Ó!DÀŽ(�Z¿"3ÓÉP)>œ £ºZ¿ÿ8Œ¨.ëJ8Ñ,ÆÎLM`(`.–`²Š.Ñ d‹'øÅfIŒŽJ €Ì0&qi¨“ÐÌIM€ux>…{Fèt _MGyNë$`€Î’{°É19ä|Ìj@¿�ÐóHj­H0Á†DÈþ†¤¹|H“HãψbA†¼Ïƒ„ÈúÔÁPºˆ¹2ÐËŠaèyhI-l³ÉÐìÐŽ ÝP¤ÊÉzê°(PEÈŽ£ä:ç8*äd0¡ô0‚Dø¡†U"y@ÑZ(˜(™Ý�=@X�#ÕH…(u†/p•%$u&ERè-p^` Y-`„øFpœÕ‚(ÕR•Ý[€.õ‚Sµt  SäÓ(yÆo Ž@ ŒËR+¨Úû±/ÍÔL[üÚÍÜŸ\5( c¨ö‰ ›Åõ#)CK¾ ÀˆTâ^LÖŽ[@¶x +H‹jÄ5j!þD{ØÌ 8Šs) å$‰ÿ¹TÄX–XÎGéT]e �™0w|N“{7ÉÙÎùÙÎ’ÃÇùùÛÏ%“aý€‰d�õ9À€Öí¿ý»0×µ¦ ü€lmȇ º™ÛÝ™[€™Ó°™sÁŠÌ9dAA :ÄÁ%5VÐipB…áª}Õé˜1ÃlØI0”¡_ˆy03lÈ©Z„­ó)mØ“)y0‚hàŽh€3É!Y(? ›œÅJtx£uºKP§‹¹hW›ƒ8€@`-ÝÐÒ@R˜ÍY •à/ÐÒ YgÈR,}`t¹ÉS€³qÓ­‘¥€&±]xþ(±" á6aŒPΓ8‰\ÍÕ)(Û® ïy'±Ma\ýa†Û" qb[D‡Ïd¾2™'Ý_üNü1€�‚ÛsL€ƒª¯ @%؇mÂÿB¸ 08c?¸„‡+Ô �†\¹2‘‘BúÜ3±N?õ\2©cùÑ[2YGÌ}‚j(EÖ½V&°Ýûä@Ôå9wHÏ ³¯EV1dÈråVšSÈë0o×AN±Öå9ø€‚œHà9³¼†ÌÀ¦l ¢-ëI˜ ™&„Ž´3‹1¦‚ŽÝ€,Äó­3®ú4K»äˆ6[ƒì¨¢Â†ÝÀj ®C+ýP«(àƒ sƒþÈA¤Õ±˜c¦{Èô¹J~HçsqøWp`Kç!Z ÅA¡=Y ŽRW¸àUS€&¤�¸€ZÔÌä,[R‚á>“û¹0Py Ûb†îˆ´}•sc\]‡õÌ‚&ý1â¦T[ÝŸ#ÞhqÁ®ÓäÅ»ÅÔ2áÊý–dsÕ~ƒ0ðƒqQax ؇ à PûÊ\…ËQ¹ ˆa|Æ;x”"6]<“ÍÝÎT%@¦fÇh;“¥XÇçdÇ´�Nî 3ÎD] û�âÝ9×eäGå #Á†,Ë1‹1›Û]CÝDN±MÖ9;õÏ ƒOAdüØ€ê˜þ†™á»øPѤRÑ…³óˆ˜æ8²{Ž`>¦Š†:¨iH„š†iXíH_‰ùó¨…ZPŠ l,@Pˆ"y˜J]>Ö{£=Pvuà¥û9¨m¦Û]VHþ¤9Ln×™{HtNà‡£s>€!8€/8€‚(ƒ‰‘|Α¦ÎKH €ÎUï9hx(‚³¹î‰ÓƒRh°ö¯‡Vè“øŸ²M(ù.©ÞL–>ûùnÍìÌâcÛ[4©ƒî‡s$/Ê/ÿr‡~°‡ëA(üš ³w€ðé Çȵ•FqU‹–>’öUaÅÍ<ÆÜ_ìÕ� ^ çþ\GNÞ@&0€\HÌ…ßë×¹±¦•ýóä‰4„¹ºäÁß-AëLÁÿtO㨉êT»¡ð]íÙPQÊl Q²[ÑìMWö“Iª¥Ž‚•Ž_H„öØýÀŽ.³r¤\:Sdí_íâ‚ÃC+(ò> ¸ô`n`Cw®m-Åmà–H„¾È'dwuHé‡éžnã¾Á¸ÙSò.ï{úJiO‰Ò¹öƒ#¤O_›' ž©ˆrÏþ‰„f¨ùf¦[whƒB \ÿîŒ. s±Ÿ"þn>¸ôëÌYµƒ[XyévП2öþ�žnQž0`3øâ1(…6˜éï!Ê1j#–°lj÷Óë:wËÅܨV\ÁÙ½VQöj¹æOO¶qxÀ€|ïdÞCHøœÁ`kàõ]CApF1ÖeA{—(Lj‚ È¡ê0*ß×ù�m(Xs˜©˜.+ Âe1oªÈ6‚EØsÿ+ í»ÍÉú0‚ pßhmE Ž+çe<Jˆ"à …§xƒÐô(tF_º9pîÛÞuX`ÛžSøû4€ 3Hû<rã­qäù€(`ÞAû-H‚ÞÚìVˆ|pVÚ²ŒU_uyjuNùOP©ò®  ˆ†uÞ¹þ{¸°„òûþcïñ2Û\¯ZŒæõ’’ïÃ_Î…k\XÁ)@œ8^0ƒ\Pá~h96(w‡0¸^à…1°/ch›F„{WõfA¦@_ŒÎul÷èÖw”¸§`]äùäþ4A÷mßïÏâ½÷±Þý«¥¹‹’Èm=È2€kÄ{Á¯ö9CnqÖ=5ˆ§3sC3L¿N˜è_*ì£ì2‰ Žæø…ý2³5È,¨=Ð$¨ÿª\\8<ÃÂ1l 3€¨#+š¢ZŠ ƒbbQ6l'NÈÃ"oCn´¡C—Ä•W#\Í™ãlÇ’!ç¼ø1ç�Ê“'Užþñ&#B¾`òáCžp�U‚â‚&Fy21` G£¿ˆA`*ÕªV¯bͪµªÔ칃‡‡ŸI˜ˆ¡ô ­nß­ZâÂwý ôêŽn]xuÝ oðà#{/à0¬øpÝ GÃl˜ï¿§Ð%Ló%”é>Þ|3ÝœéÞ¹`úI‰ ¦LyÝ/L.wJ”ˆÇ‹×§x(P`ˆ÷‰M<w(À¹Æ+Þµ1(ÀÙgtë LÃ6Í6ë'O2JÍØº5xñàK”O¯>½?*m_ôšûøòÛ»”æþþû1¸3ÖOý0•Kfôp ‚ &u &þõÓR6`”QLõdaO=(•Ä X$ô‹0¬±Æ"‹˜`B4@Å/µ`³ÁßDc66¦øK4‹ÔX£ˆ‘°H‘0ØÁ �H5U7ï`ƒ 6 ÑMALƒ 6'Q‡óÔ’â4C.bDµœÐ�a±|<ÀWìàŠG&Í1‚Nðà /ŒðÂJê¨s€ .Í¡§‚šÂŸ¥—;@ñä‘ÕõS‚#\óJ NÄÕ©§WMQ„ ‘ ƒZ¦*ÕC m}Ú*\Y7 Á¶N¬8vA GÖ+a„íêÎb†<“…Æh~šh£Á¦Zitl¯Y›-lÀþ$0^lÖÁc/$à×°ñŒ)8�×O.×Ô¶Î:îäRï °Îo¶ZçšiØqÇ]¬e„¤xè!ŒNÂä1ŒžÂæ9Ìž¤üM_¤LèÓ{8è÷“~c5V€_Q 2ÅD˜Ú9BS.7•2†©ÕÔ…*°À VÂ(5%F4Œ,bób4PTiÂ7&�7Fc%ŠPÈ8-®QG=‘,ÓL3Ë("4ÉØò A@�� Ý@¡ CÉd“Ì<@tqÐFÄ’šX40Ñ™Xè‘‘ä0rÀ;„¤’JyÞÉ“Í|¦Ò /µl¨…vòÙg…LàÐ^ž?¨Ü<¢ãÄþœºšúVEÛ×¼Æ�T?fØóê·[¥ð È ›SðkÝkÏRFšb•íU]‡=À¯¼‚ÆiœÕzm¬ÂÇö­ð»Ö}·ý‚?^uOdß l0†îŒa@[|¬£Âó{àqÕšµÛïN^’ç)L|ãy˜� hÀñ<!>zéÜÆìÃ! I dÓOÈøC“‘f}%c } °�”©ŒCK ÛÓ¥ø(fCv¶£ ÈcɈF-j5ªÝE{QŠá´¥jµ‘<°ˆZD¡uXÂ=î±G@q\€â ì�;üb`CN&#$c @b6Àˆ ,þXÀÂHÓC,à„Œ°ÂZØáæ@GqüÀ?@ÜrV¡;- eyÒcIúx§?^î…:‰Nn’ a¨8P‹R:×ð I¸Û$’JÐ`üÎZ| ËÚÄÉM’ï¿ó õ¶çÊë¹2{û‹U´#Êê½2—®ìž÷À÷=ïUç€þSØö.`ð" ý¸ÍP¸µK„¹¦Ë1]s=ïxç9`�ùKñu‹5l;—BDŠCõÙM$èvŠŽd$Of“kDÒq#| Qîc2b# P£Z2’a£ÁèP¸€˜¢9ô &h‘0(! #¡�þ؆(ZÑ .|þ” "é.DQÒ:H£FXÄú Œ0-±D_TE,@ J4`X`‡xÊp…BÚI%‡êáòH’t$g×`YËyHC 2¨sp…8Êà <%îülŠã€ÉSâ< HÍÖ<ß­#”o«êÐñÑLïÛë%¶´—K³ê2¯áûf/­iÍï¹²{ýë7»%ÀÁÆfƒö!Wô é* Oz¸ÒMj³<ã™kaƒ¹;Ávç³ÝŸ„úãOKæ¢>õñ@FN¥ŒA)¥¨$kqcÁ#>=X€MÊ�ºÍÙäf6»PG˜„EÄ•¸ô +a£‹(Ñ‚–£ˆÞ(þG …B,(,a »hÅx[Q…*˜÷¼UiF:RQ,aÝ@;@‘,áK¨ÜLð!3ñ­¦+5ÊÈ–1¡$TÝÁ�†êŠü`�r’SröA›Eõsw²‰â©²¥Duevò‚Mrb§2ˆƒ1Ð$[]…ޱ‹2‡ae Zœ:·*ï6£–]¹GËlñî•Áó1`_£×íÉÒÈ» lö¬óYà œ§ø´×c·„+NØr�ùªMƒ�aØô«/½·dÖDù{TF`kÚñý¬Rh1ƒ¤à) Ä¶èØžûó(±<*,ûáræLñÖN2ÃÙ…4–ªøAþW;0䱈DÔb¡VÚ‘‰€P£!¦hiAbÑ"`øÝFy?Z…PT¡½!u¯#FÞEX€8Á"n�ßXÔ!'úЙЀ œÀ +B UW U Ž“œ~P=º¢ÂbÊÙÇ>Ѝ›ãÐå I¡¨–x;X@XlcO-;ƪ\Þf0Ùww <ØÌi€Üclc7«­zgð\Ö®OFr]æd'7y ä{Í’K°ä¥ÙâÄøîªeØ‚M…²YyU¶¼eÌÞ[³Ø¼¸½iq5GÍ£JÀ1x²s)©µX9ýã Æ6¶¢ ©³Ï”ÀÀFþáíRc¦²§«-J‚°‘\yP"”0A"ªÜZXÑx®¨#ú\èBAAÀÂ"–°·¿½p7ozÏ›†õšW¤­E'Ö€ˆð:0Âz£P‚oÆ~ Þˆ1ä¬Ä}ô-…­í;q;ÃO*‚dzÏ-*eçf\å8Ï„ÄY{Å7¼Ññ€#$Á�„JdÜñ€³>.áÁë�ã™âÍ2–Ö2kµªuÖ)�ãxÍö̪- s±×ºøÄü|kUü—Ú—¸a±òl›œ¹8±)qîwo=_ùµï}výÂ&z:‡N 2ÐþÅ¥­Ïñüf ÍVÏÝþ€Ì0…{d^Ê,�„ȌӡEª¤J4@Œ5Tà/T×sÝ)T—X‰Š�‘,Ã4(ÄDm€mìÜmƒG¹š Þz©W rÁ6,(hI2ÈÂÛpC7�)´ E˜ÉâaA5ÀŠ,@¢•D† ×pŃ8„ Ò øp攣¤Dä I¸Ì¬DäQ¸[î­ŽÂ<€Äž„ü„©)™á[èÛd0`Ð…ý\ß¬È ïЊó™U(’e ´ü˜ ٷ쎵˜Æ´,¢¶ÄJ"^Ÿõ “zŒþ$"ù _&nÇv\"Äß%jœwHÜÊ=Ü^É\(Ð÷­xøþœk)Ð;½Ç{ŒEkÝ\|ÌÖlÁ†m ÚÉ<SࣅÐÚ }HÝ‚¨!7¼ƒ0PÃD°ÈdšØ-Bˆ§=T4ØBÐØ‚ ˆ ÚH %CxÁ—(tHµàzá] ¾:ªÞÉÝ),A°‘ ¬ÍΘI$²YBà¼Õ+TaäLžœ@’…,Õ|Â5D¡S<Hæ`J"‰Û·mø‰žÊE>’Ë$ZFæ‘dRê^ %µ!P$Á´I‚$W¼ )"-ñ î˜*iËïŒFÁY‡óYôYŸ¶� õÔd¿]‹,E¢ÀGdi’[‘iŸ•a"&%¶$þF%ûqÏ™µ7%Ì*‚™TàŸä‡ýMlõŸÉt •Sí |¼Ì0ÆÌ¥ã:ƒô„n1…øÁC¨]@A2 QtEˆÑŽMÐL—§Í/` š@ÖŒãÛqÀxµ Ý©— ¢×Ýqzy” :ÂÛÕA›=®ÍDÁ(œ€¼Ñ˜ÁµáQžàååÉš›‡ýÑR1Ê}ÛUoHNVAdæ¼À”Á¬ä«xŘÁ;]ÒZ5gV±ìcX†MþágÜ!e(Ïfü^ñ(ö„’­Ÿ ÞR¶àäŽá$õe¶à•$B–T¼Ñ–aGSbÁ%ô¡'þbqâ'žßÉ“öAf©â*®G€Ì"|Ø_O˜L=ý‡ií‡~Ü˼ä_¼å£á‰Ê8ŽãÜe†àˆ~˜R˜0Å  D´Mæ"`ƒ"˜@—œˆ@”Š &ýÂÙEf,øƒ(p€(lC©G±#f¶c º HT,A'6L 5PͱQM°ÀTˆ$+”ùÉLXPa[¡èQ† RN0J‚¥DPR¡ì‰NìDçm¡ž…@•渂à^ujÒY9ÅÀuú©U<ÁKd¬ŒñÅï˜Uc(‹cK`ü…ŒYÆ ÒJ|¶ŽPzêxÂçyj "Àå'baþÓ¨ªi4OfËÔ•«b"Æq\I“�=Ì*v¥®f„mñG€ÀǬ.Z(;5h€LkébXŠÉÌ%ƒlÎ$Å:! ¢W™(‚ˆ”I,Ã`C¬A2 ÈBXŠ@×sé(²« |ùé)\¦‘â+Þ¡#¤AÝ}ÔgÊÔA¨ @@8²5@™è’<Àx˜ªDæ\C™é ¸Æ:$ãHäJU¡Ò-N…ìÄNXHÉꄜ:ŽË0ÊËøÁêªd)L ”Å}ô�ÆìU$*©°%ñDËYQÆ`€†óÆ^FcÌyzgMJÏŽÁgñÀÕðþijð¥µÌ +ßÓò›«^ÅÅFU†S÷ø�P‚îjW~4m Èè�ÈXPP^ºÇÄ„Œ;‹Èô¬ïUƠŇ(ä]2J¤Ì„}ÜáZŒ˜AqD‚Ž(`2¬”ñˆ¤¥HB•ÚŽbƒ¨E6(Cd,Á)p@‘Â`gf¦gÆ`fæfÊ],`ƒ=À$A-PÄ ›tE@l!ml…R‰H`›”D…iÎÒáé…¡@nᢘ¬œª“Å`$Y/_NJæ¬ÂÜÁ‰F<@Îê¬¢ŠŽÐ®­œoMfç_`§¥ŽÆx6íÒÊïghm®D- ®çTögþ$ædþNOÖúÛþ4™VvŸÙ–­úå*Ù*041ŒiuÐ]P²b¨ŸÙ†<í"|ÄS,àÌЙ=mH|Ä.é™ÐE-Â$4�(Ñ4X€ ÄBÁ͹íPvéè•tÂÄB,pÀfÁÛ¡î¾¶c;v¦‘®“±(dÖyC3ÖÂ>>dÄøAœä‘!ÒœdÙɈƒÙc[Ææ r*N›vèÉŠÞÓ•¨nYØËï¼ÂЉ¯ÌNÁø>5E ØÛSž¥Å¤­üþü^€òÔ½1F(Íï#{ç¥(I+ÅϨröð!J2fàJ#.¢jø¯ªþLð(\­êª*6ÌÙ SÏŸÍ)«X,ë•ÌÛ6+£â–iãCCàpEJçÙ:ÕÖÝÖÈLJ1@‚2|ÕlÀKñ—¹ªë¦ñHØåD)6d °-ÁËÝgê«Ýñk{±ãyÁ8Ÿ×ÛÁ×J5@3^iG¼ÂQµ Ÿ˜HJà„!ÎH¶Ý³ž˜ÛšºñæÄñ’|ŽBX 5›‚ýæµ½BörîLI&EøV´¾Á$2±LFc¼çüVêúîüÂog@2%ãÊÏBË:@ þÞ$QZ×hUJò¿pÆ$“r'wrO;¢’i`pÄ|‡fIYgußÇ mþ¹å¤Ø[ž´*ÙÆ¼ \®“ÍÌ †,HtvÎÓ)d?½"[02 ÈRÔ‡2G <s¥@°Ms6O—ë/€à7@W-àMøè¿ü«g"q¬6Ýa&H¹ e D6üBN•Ijž�; É$8P•I¼)´M•@wæÒ=„$RTi1R™vµé‘ñ–B7˜‚™)ûV @»ioÌ¢ácÄ@ dEOž™Á`Ò¢NªüÖ¡^êŒ=*ÒBòP2­´ð›hòú­¼töHåõ1_,a vˆò$õ&–u35ÄŒmÍ­í+¿²©ÒmxÆmÈJgxFÉZXì“>! þQÐÞ?)Ð~“%†îâUÃåbH³id1L@üB$Pƒ”l�Á¨¦]ãŽ0faÖB©H'ðõ±¤ À"öyuæ»ã šcoC,¦ÈÕ<DôpJ (€\¢mžÍ$‚­)é¶,@…ÅvINqƒñAÛáT[ÒíÑP)AÊv„]íðvÈ]gn•R•ß5äůÜÖv.­°(·¤Ú¡q'½QF{ÎïѶô-A­ÓNÊ´¶\·${^O"'O%Å…OALÄx_*^Väâï @{cF`Ä"= ÿÑÞèèÖøíÆÐSþU°Î"n=Ê 9z%þÝC&È+$¤¡Áà.5LB7ÃÈŒ\ ßH¹šHb‘•¬AÔ¸Z´—¯óëzýúÝqfênÃy¥—Ü….†‡—´0,,hCÈ%>Ð(téÝspìM€„@;HQ%9K$ù¸{[›B’=y¨cÛ� ÀªÔö¡êŽ®ÀC·hyÈžÐó(ILWFs†Þ²R(çHS÷¦žo$Ò’#K÷!ÃÆ¬0|ÃçÕ¹RïèáY‰*^="¶ÔUÃqŸÀܪ+ º‚"°ÚZ°XÐÓþ%nâVR§óm%uÑр𢱜e=ý¢Bcsˆ/¸îÊC7�îþN׃K ©E¦aÖp K—Ø«yýº{‰a»z ±Õ{f )‡‹nV�ä[°ƒã=&a¸‘^!ʼn’Xñ3µ%yHÐÑJБ?€ek,>‡ñ"‰1Ȧ©›Ue[ Íɼ‚/A•SzèÊÜO•ópWª³<*fà$!¼JkPtojwŠ'ún*©B*f¼µ(|L?êaö 'Üž?ÈÓ¹O­ûñ’ÿ ­¯ªGÂŒÎèÀ¼RÜ…¼üË?HâîÇ¥{úYºe[²%º“ƒêVÓõ2†ìqâþâùÁZ¸Á;ÀДø×BÀhÓÛhÑ&Š8&©U‰2TÀþeŽ3HÉ °sa·#’‚ýi�‡m­DU8aˉ>è� C÷`Á«2#Fü°xñâŽs4îð2ÂË«®\uÜáÌ™Æ+çÌ9Ð’åˆkL˜¼7ÇÕ‹#^´üñ‚ɇL(–yñbÄ‹8]É,ãeÁˆ^Xa�kV­[¹võú•«Ãð mZµ yÜï‚» Gä^xpá½yñš1C/Š)J¦ ÀWIÞu„§¬k<rä)y †œ`JÍŽ1kö옱c½£3;MZs Õ JxvúµçÌ®×iά÷É”ÜSèåy÷mÒ¸oçÖü$µjÕè”›5ëþ¹CçÐÍ0c�»u38pÀ㎣ŸïîÜáÀþywÒ«'¯Ä½zxå¿cïa€¦Ð¡=øàßã:ëz¸ÆŒû΃G¼îp8ž"|9áyä&› „‰f Ù0Ãh°Á&°ù…Ä_Lñl²Y‚‹*Zt‘‹4Òà"F«°ÑÅVªÐ‘Ç[Ùf›CÉ"‹%b²a´Á¢v°bÎJÚᇬìh¥•Ä1å‡h¢©¢9trÅ”Liɧ¥”šƒ§¾¤ÈÍ Fø$N&îû�O;ß”jkø‰$z€'‰#ž8k­DÕ 'Þ8¬E%M´· ãk2É /«Mþ´Ä*#Í4R7]¯Ñb[U¶×8k¬3Vg{¢9嘫u5[•£µ^iõ5äZ 6ØÖ3n7ÌTµ­³aAî¸×Z›–µik…Î<îÞZO.øæKÏRõ¸ë§½÷ð"=q¿ûÀ�v ï¼vÿû`¦ý²;/[îêrG<xèz+’𣘠6˜fšE„‘Ç„EÖx8ÃELððÄùpâMX#–Vd¬bFCyÆ_¼qG”u¬b ª¥:á` #N@B›jœh#â F†È²#‹6úáL¤>àîƒO˜p(/é<ê˼$ÊN©ìÄŽ]0yúM:±¦)8™XÀN´ý þ‰¿’XÀ «”î¯J¸Cîºõ~R«Ü@…U¶ÆJ}L¯L[çï¼"[ÌUćU/PY}m¶á*wÍÚæXcMØåp­ÖVéDÇÕ׿xÝœXc=ƒvuÝ’SnsÕ]ïuó'ŽW÷âÚ=±øÈ‹K¾ôÊÅ€<ïÐãî^þ¼d7AóÌÈ…‰ý»Ó¼~qˆ¡»·º+/`ñbø¯‡Ñ8á„7°�‡“‘¸áE<ñbOTf‘N¶iñEi9d¹Ðñd,cÙ`¶ ˜q@±à€AXÀŽ1¤~¸I6¢Œ¸b'iÊ5Üd¬qÐMIEàT‘¸©„=ˆ Q€Â°ýäkJþщQ¾¶“”a"$á$ƒHí ˆŒâ0æĺñà„ÜàH£Ä nS9Uá0#š*Žæ4©²Ü¹X¸ÛÀ&W¹ª®ÂHF2ÞŠŒ¼*ãç`g-bËŒÔBÎmG,ÛÑJ7¿êÕaÜßÅÇ;î0Þñªw¯{mÍ?Ù¹O€¸ÃžìäK[ÚC¼ iŸ¡H¥ X€’ð i@!aØ6ÖŒ5l¨bÑûB”¢lÔÁei¸ÑÇPæ"‘Ũd>š¥Ž€$ Á fª …2*‹â yÀ+¤RB8" °ÈG¼0/\DšÉH<R¥”X¤"ðæÄ©‘|ä’pªþRKHR‰\„$$Á 8]Q†Wøa E4bÝœðÃ}Ö x›CP¹¡ ”™Lb#Æì¥¡ ÅË[:™ÃÜ¥7½¦,'­ãdf޳aÖQ—¹_ËvqT©JÕØèHG5-Õ#­8WÆ”ö³ƒd¹êSICþ”yñ !ÙÃmÑg’”Dž%Á÷Þ§~¸O úá nœ` S61 ½ïDßÑÅ>T‹E,aúÈØÊV —%[YÊ ¤,´¯,‡´¡ ®âI¶cÅŠòW°“$âØ6)8¥–(ƒ81,;-˜ARĆ™çÙþ󧨔á áþŸ�å'š\c&_.P‚QŸ¯M:¬a3Ï;oÑ­ u«[„Â¥  ªËîR…0H€ BŠ—#<÷ŠëâF·h—éNF£ÃÆd¶ëÒð@/Ý}@¥4z;j7v+eN?EöFÇ9ÏyN{§_tTï]Í[ªSiµìôxäÕµTüª©ŸA®UïÁðX b€ 7pã`ÓP†(£à°5DĵÀF-D„ PBáPH_Â?’ÝR–;zQ\qIJ^†b ¡ÅË*à8dA }àÙ%ŠÐÅÎaK/Qlо@A-™é&h2 R^À‹£¼€Nþõžþz§.¥?MU¡gùfð¥?v2Ð"á1Ù¾ÎjAÇ*Ž`†~\'v¦joùÌ ÞÊ…·þR.] ê–#7¡Éu®¢EêÒÜN7–ÔFÇËÞØEº˜º�06=…îzÔŒ¹�,UPÈ@ŒÕŠîpG—Ú×½±~õ«y6kàÕÅÄuñÞC`¤Žg=KM^"û ¨7}ikÕûó·êÃMZǪSñÍ6ÐU—xb&F˜0>dQÄõÅ{±ò ²qßx Y`Y+†¬pÈ iÄÐä—Xd²â˜’9+¢”ƒlCöL½'0µ(à¬È9iÑFÓ™a~ôþ´�'!Î×øV¬Q‰~ä C3…šÉyÑ3ÔBqÞȺΌFqš.9^îbòWÕæäÊê¨åÀËsÂ&ufÄK—#ë—6¤ÖÔ1 aDõ;tqk’û…×SõÄ.wy)ÌL$:u|)Èëý*}%(ë¼aäƒäÁa˜ FÈÅÒg(ìF¸Áýô7W”‰;Ü-j¸cÜŠ,�)¯Ì‚*�[ "p hà™/|A^xù2YðDúÔÌdz)E™Q<’’˜l;XIGthzŽü$ƒ /[Îeš  ?ø±Sƒ“Ûÿ>ˆàEÜ_eUŽŠ›1\ápþÆÕ�}Uè-©ª¡%»/zå­òèy…>¬a1ëû«:–H‘åó¶|s®;)÷Õ[_‡èK’I ;¾ô›­æ}à‰W!Å\uÝs¹y°ì¦gzî£b`|šaH¨ÛânîP¬b>)}Da­Ïïd‰–Ìí–j‰dväð$€HDr€š � ”¡b! °¢|A ÚÉ'(‚)pb±âI±nÂß4Ï™(âÀƒ6"žFÈ™ ßhÂiÚ¥]fÂêü#¨¬yÆ _�æ € ÿé!Š¡$Ê¢ª »¥T”è1bEç¸èvHjúÐ+sP'6ÂÏ£†®ÚÏsp4'ŽäsþPªVNçXhêvŽ¥W‘]ªÔÔcwÄEÀŒj>Éþ˜ð<„O¬¦]‚‚ P íä: Ì©ò¯zë¶LÍü€)Ñ ÜàR¬ƒ€6 îNéD@ Ä~¡dïh$¯¨–v1dâ 8ÐðfD0r@þAÐa˜ZP&O Ài"ŒÂÄAIbLt‚M~âábk¬Žô(îñD±Fl¾OÄÑ�È…;ÆÀ�rÁ�¨¨xŽÇé” ¬`g²Põ¦¬¢, xr«\Ч<æc[É=àÂè¡<.¸æÂ!1í..Àãô"£,Òu†cŽÒsÜ0úÐOXä0¾êþè¦#t<çaŠ$ã ¾J’Œ@‡Õ®…9| ]<1þâ¥þ§’ra(ü£@–^ „‘ì#¨èï@x+< ä>’ ;Ø1Þà@©¨&aFB¤C€ÀC¢¡b¤Fl¤EbÌÜTÆFÂ,˲®$€KPÀµ°@D¡�dg(À Fï Ë€šB´Œb" Él˜€©°&(¬Ù˜'OmNò#¨r]pÀ¨¬(¿n 2A¢Êx`?sRîF‹�ò\tçâB!ñ\ò\Š`!›ë0"Ò¹(Ó¬ëŽ ®Àž`¼²+8"Í Íät.YÔou’£X‚E7hg¥Xþò$uå¥LÒ¾¤³9eò¥Q{Êã×òO·„M[„­ë²íÃ’ÄÓ]ðƒy¼3{¸îz  {Ú’  †º!&áB6 D+?  ` 6pM†­Òe/ ÊM–~„-³€² }`и�´`ðÐ0ë´Œ0ðá¾äCÅlÚä½ÌkNköÎKP+ÙÌc/oO…Âì:%"\ápô 4{4-˜#ù†42%1fn"ù¢¸BNI мP¹üà†@ç² #¥ 5®‹‹ÎÐ"µ”JçH ;‡úb*¦ZJ$ψ:¥Óèf ãC§éx{*ìzòï‘î…þ‡<Ãóêö/<ïEP®C“ î®‚@¼áí$Ƭø3c²a<&eVæE2GÆ ¯,u, N8€T€�ª @¡DÁ7‹)2h$Ê ž®)´`•$2ƒrµ$@Oß VMWµÉUA+šÞE“Ž">B“ÂÇF•uX! hÅ÷|ÔGK`»„³ø.G¤Â/Šp.Š®TLC ƵH/Å¡Ãìa¤®4Koã4^å‹^.6„ãåö‚^¯/íhÿÐŽŽÃûV­sˆîVî°e é¶å-x ©‘Èã;øltÒï¯O#q( 3yĬ^úÃ/Þñ(¬þ@á¦2¨a8d ºàD¡ê`ðÒ AaFer1ev,]LFtäc‚±SUf!v °`êàDÁIÐá ìv@ ì°\á�K#˦6uðiõmWëé°¶Ö$œ–J\Á â©j+è…¨„°Š•)ÿc'¢b›ÊŒ)¿çO˜2 bÀv¦•ZA³6MºÎ6 %`UÎpVpb#\#Vç]G ã°^ƒSr'GpepãU[7uÞvB÷593GWFrt_Ê  =Ôq\Ä;´®§îe2¡P1ƒBé®c‘ž;† ÿÈ%b·§¹ÐÅ_ú`  #þ!ä Dì”AÄáxëàcØñzäyDR ´­>ÐcdiH²€ÁSU �€¨’da ü!ÑaÞ€°Žžæi›¦±žBË›‚ÅAßxA‰³þmáÞ)³4'”b‡2H*À‰+B´Ô¬m(|ŽÀ\ko3øIú‘¢h®<®zÓ6T**8 ×U wrØ0&ݰ EwĆQ9Ù°Ò«¦Hg†Í¨ŸN—`Ít½œ#!ÛCxÖ£ø[¶yˆÇ¨¢.c÷þ$–uÙƒ\š˜>€W á¡ì;Ð<Þ� àø€¦AB¦ÁÄFlÄL`!fÄð¶! þd¯tÖG�¨–p ø'e>f:•è@bÁ�À°€, N•°Â¬ÁÞ$‡¶)´vƒ^@0á„ÊrMZ‚Ê4¹MâdöPˆƒŽ‚'r‚'RmJ´öêE‘Àlkîö üIƒ©õ  /Šà¹v™6ï¢"ÇË.€9¡8­ä–erÞPÕ¦e òýªS¥Ò‹™›Ù™§y%öŒÐ¡‡M’½\tK�Œ&íaqêÏë ì)IÀ ̧ Dª°#@ µd„6 O€º¡6  ¦¬jC `.g„Hvde´·f'µf¹w–ÖŠÅ×ýÁ”�¡jA(þ f†°‚žà'±cO çi>¥¦àž…XúÊFàjVº1—ð [Tâìd™ðýë¨p Îñ‘g?f× üÀ €GkÙG™#ºø¢¹˜Ë¹í·æâ5­ €k.L-£.r4XG†Uc9c²9Ñ(%»ùL]ÒšëK¾èk:cÍýf ®çkÖÖÚýäštØøx” þÂëþµûxÒ¤/v?h"yôg[±OKâ4o÷ঠ °@Ä@ fCÖ@jÁÒÊðî*ñJò*µÍ2¯Ê­,cLEfTAš�Xà£-aj¢`E8` ú@ù æþ£¨˜† Ká—›k|JýË@ØQ¹£k丗*=s’Â9xƒ =º{Ž ”zoK 70#äš´Ô@6¯«Ûû@ø¢¨´Kõâû€X\‡¤B²~Ž…™3™÷Z–:Óô­£®\Á\®<·´çuå9@Üq‘¤§¨žIÑ®! ,ŽÁpˆÁ®PË PËr¡±c-©Á�eÃû§�¤?)Ï|Á ¢ ° j!Åjáa&€@F› 䨀ˆäðîŠÝê˜ÉË­Ütñµs–¶ÁÁØÁX�´– OŠ¡úÀŽ`"ä_¾ƒÇ�Í )ŠïåM„2þl ÃY_èQ>ޏ±wêB·â⨞ëPÈ»Zæê-%2Ö;¡&¢>.¾›¡† Ó°Ë!©ÈÒº(8”û*7¿scX’…å\øšÛšÀÜ­I}ÁœÁ£ããÀ1DåÖ˜4›Ô4»%\àÃòü}'Ï -e\}}1üh¸æ£V¡¢à¢a LÌÇ× æAèÇ8�É«]¶áÚSµWû@äïTg¯T! œÀ ,– �þçÅðjH¨  DÀÁ Ü@“ÊVFà’¢"*øD“HkYó+;Ü ¤> )êø!÷…;˜açƒ.p 6BoþÎx¢*ò1P@ <~\U êR.E䨫¸HÓI÷b»RÞåMæ, £¸ˆ£x£ÒH£¼F‰¦�¼êh#‰# Q`aÍÔ]-MGçèm /N£äƒé=U”`P`ꃨþê±¾ê?E0º2~]0˜Np<2¨>\ ½w£wz+Ïì! Ƈ =Ä`8dC¢!:a ‚Ú|›Üïu —Ì­@ ¤ d¡Ýiäf/ÕÜh$ ¡daö�á œá Xo�«Éø×V-®"k'œê>Vèß+Ùh0"›N*üd\Aµ~ “,îü´ÆMú# ã?þójNÑ#‡‰œ^/ÌõÐj0j>S*4FCìÉ1¨ 9ÍR†”p˜>ù‹y‹´´r€Þ‹vc7ê;7Ñv"Mœš×è½\4Ã2ªÿ0ÌuT¬4¡îü\P3’ Rx\ pÀÃÃ@A‚ 4À°!CðܹCÈ0Ã#ðÞ‹R yò-Z#RŠ‘X§²pØ–ET–mÛZIتJ•V7kÞ¼)¡•Oœ\ÒØšFèPª8Ø,Z4(S¡MÓ8eÚ‚•r䮸º2à‹+qWĉsEÖÕ²gË–ÝáªÌ‚=˜,`òÃÕWuñþ(S÷GÝ#~xA»àZaÃ=ÊœU¼à­þ#ü@–Ü®\¸=Ä$y‚€çÏ C‹Mº´éÓ¨S‹~ð`J‚)®]'˜M{lØ´¬Ó={wïܵy×½{qܳ§Ø¾}{ù%°/0·ýöòå¯_ïF^ö“Øß<É^={ìÜãÅOI?þ6{ñãÇ—x2_|‚÷ã?‰/¾„ÿñÍ÷_ èX :ˆÎ4è ƒJ(Ñ <Jäà…<àà`ä!‡Âs„I¤„;H$@ „ƒEQ(cA`—=|À\I<Da DqòPÃ6&´H6pEJ/Á´MO8á4ÔNU¶²M¡ÌDU€ù˜VþŽ)Õ™bV!`ÚÔ‚Q¡„£ W”qfpÍžeôPdf}å [dõ™£;~`#¼`×]ŽÎñC`#,°×_|e:Â5iM WC 0dÙr¶#¬Q‚j¬¶êê«¥u&Ú~±MÑs¸27œoçG›là ~ÉåÖ«±Á;\løÉ÷ßlôA -®¥g~ØÒFl¶üñçß}àbûí·áÞ7 €çž{ ºO¬#tÊI‰5tP(]ƒE4ˆ‘¾(Vè Š%¦è…ŸP $PC–ÁU)fL(ŠCFØPãq7Ø(#R6'9ÉÒ”Sþ´ÓPVfÙJ(þ>±´”š4«iTšO¡¹TQaeeÍ9¨¢Á&6¼†ð ú¦L0±'eZÆÒ×0áÐA42´ç5ŸpÊuÕqAýôž/”ñɦ0Êt¢R|jÓ{ö`\~°g°æ­÷Þª›Üm´YkŸ}‚ kx¶³m[®€æ¦—m³×JKß·ôÈx´éè쀹=žùçãš.èéšKúä™HàêN|«s÷Îûœ½Ìuˆ" ëD(á‰'ºÓ»…÷æ{pD»Xa‹ìðŠ¢Îm€ÐCÏöôI˜ƒ…}D5ÝP#Ï&ŒTA'þd‘ÅOèûd˜m^y“úæ¿„T;¥æTQ¡ÉTþP4ÓoÿP¡š°‰$!pùAÓšÆ6S1ð $ˆ ºC.$ˆƒ}``yÄšÃDA@°„€ A$¨Â9Ä! CžÀ·Úo Ïk¾SnI‹pâ*×°´õ,qqŽtéBݹ0‡DÒ­K]BPÿ³.Õ­Šª{¢¤ÈÅtYqŠ©3‚4 Ø8g_ÍÁ f—/x1ˆ#Š£‰¶ã.I(:ù†P40 ±h ƃG *Ôƒ¸ðzJ@ÁX ½nh#߃’ȷ˜µ‚ èsßPØg—±„= “Qb²>6EELFÙŸÍxö?¢Ô¬ ãȈðþªéˆ Q”Ž®‘‚|Ê JD"4»Ø)²D¾S^Cttµ ³DTH‹$ƒ²º¡6·šlzßAäÚc« áWáÜxx@¸vÞg=‰ë\;$ Ê… žž[«¨Ï(>1‹óጂ®¸ÅU‘‹cBÊÐ†Š‘Œm(Ca÷Æè¼î8Îa…b#¡}í1޶q¼ìÕ lxÀK‘‹X´¼ ’B!¤3#tmlŒ¤À‚0°0EÔa 2{ß%Ù¤¾*¹Ï~YŠ_¼Ä3R®OLéŸ(é÷ÊVVµ- ‚$Òƒ=¡í4ú@Êð1@.f¸Û¶"þ¤ÈŽÏ)NI•I¸\ÃN~hñ|7"œèzĘ¿@ nö°ŸáÁ¬Á¡7öKCýº@¿úe+ Y¶A–m k$kNÖÜ 6ž­–z>;vêG=¥-­z¾“ÎÅ…n\M¤âî@X*ޱŸ }¨Dw €Ýú–Œ ímo jQ yïbпâ5°áɈð‚UÚGâÄ ":XCF˜µ‚@¦ 1À ["Ì ¤°@$6À¬Á+i™Oøw%£þ¬gC¡‰ùâU-õªQýïTj&”ö-eK°, ^Ñ ŒÕNM;!ÔÊ(¶1dnyBˆÃ*‘ùF¥‘›!ãb–þäÕ�3шÜ“ÂvÇfèMÄÚ¸†w°†=àq„÷¸C@Ž,ˆÄY~qÖV z,f9ëYÌæŠ5H¾fA{Y\ehÊëÉr–»•8|Š®ˆÀ¸Ã%°O*êóŸgfèp *Üo~¦3¿5Йu»f8 ÷zcì2Ú¦¤s}¦…Šë = /°(äõ„™h¹5Ì!1ÈSRMuè '°�6p‚`#@¥‰Ö÷32aÉ•HÅ KâW“¦.e*øcå*y†jMªI}AG  qù!j¼¨Cv4 #jGwÚQ‘[T7þ’±¤iÄÀÄ »ÄQïp�cƒ™þ(˜x»±¸ùö€#\‚C?²qÑHdièA·ar†œœ«î¼‘´á¼ 0ŒÏ^`ßòÂÕkö+ÖŠÖq›B˜…-&fÎt^ü­D‡+\ßê–Íp¶óq/„ç\Å»ÇÌÍ# ›Ëñ™`€Vžwݪ„¤9ïz*2$C Ù1˜µ1ÀqpÅ� 8Á¢ðtB0QÙM0ÙÉS_r},«Â–$Šm˜ŒÖó3SÎþ+Êû¥a´Æo›ª4j5QÁ÷)B¼BáŠJ­&ìªÜe>È ÉøBwœ×…Ù¬1JÙ ±Ÿ‹!Yˆ°5·âUó üÊÅ­¨ÇkEžê˜þ´˜÷Nµ&Ï |ònôŽçGÿy{kÞZ x|ÀÂÑŠµû¡'ëyE…nñ¡bÄ­BZq�À‘ãÑ}N¼ñ× ¬çv/;:Wo“7i1~^¢‹—´Å CÛÄË0ä[� C‚2@½˜ŒZeFº­;ù“O:镳ÎÙSâ•úÃß}2ñ‰PBA„è Z1sð/`5 1¿tHÓ5]rFâR8'1)Ža =×aò.ÁÔk4´x ˜ R,8Êò+ä¡,òA‚†.ñÄZ‘C,Ñ-(X,²¡8?$9¸±z«·Cæ"zá!zê!Dí$•s:²—þDJt{_dff&QWx²p#5!Õ|v§Â·næ|*•LËóhضR!A:‡m1€",�tâÇ$åw>ês%œ´2t8‡8Ñ%*a>G±&æ?ÿ3vB3Cá�EÐ[Sà e ` ?À6=Â0#t15ÂKÉ#<#¶"±áG ñ P^ð‘X! 2oð¶;Rþ‚°+:Ä‚O¿b‚+OF[_–8çâ‚·8¢ƒàÂEh<°<ô,Ý¢Œð´9A”„KD{´·„ì:Ò:]„­£ºE ÉEdq$|ÑQ…DÛ!Žx7rk´…$õVʇ"½þÓQÈD†X##Õ§XƒRGÀš¶$à H§%qXkRÑtY‚ZBÐ÷U~8)Uþsê7"0 ò�1 C �^0lSB•H’~p'óGi(¶|û¢]“Á6Ñl3âGug\=FX±ø“ݤ+ТyCÙ¨8ÇŒÂò8ÁxD±FO•MèE³‡E…„�…ÛXÚHFÞÈO«“F¶/vdrfyޝƒ/í†GãÈF ˆ<.R"/æG,¢"tya(–—¢2B½DG` òðÙPK°òCJO×>ÿÓ2+“~4!u ÉÉJòG™õgö'UøGþ ßTP;p�;ð°W@*Ÿ"16r s“ yÂaÓ óVxô"n•/mUs*´añ¨<ƒ"ïÖŠØ”Æ NåQ‹B¤8Þ‚pβ9ÖX.+[ê"Eµw•HDfsÆPivPçPßžQ·P¸\Âç.[È€!âø:îè|3]²¹"Õç#€eILƒ› SMI°’8P TG=² ðu Y­T`4÷E‡­`>ðµ«D[‘€Èuyî3UÀ"qÙfQlx/à)8R5fa>"H–md)X'R &”²k!ÏKÆ–°þ*Æ‹¢CÌÁe±ÇŒÕ¯E9PJ•“OHÔ„õEZD¥�5PÞÙ噥¹%ždŠ kVg Õq™ÈGÂG–ïÒ ËA–S@0 øQtÚ;q=-†Ø¥r|œYC““BÄc1 ²@>I'T›d?8ÃuP‡_Ub>I¡•‘c¡šú¡šÙt£–tÀNð™Gà“¯Plu±4ÖF’Õ6=«)£˜›òXR"¢¶áKep�_0¼Pyœ0énï&Ž2Pdv¤°X S€W„7ÈŒ¾¥ŒS˜q΢ӈE]´­NôGˆ¥¸%gÿ´•hæ¥ÛÈOÀ¦¿Uqþg¦ êI/"Â|ey!˱q2eI§"’§+µ á›ÐwRV#=àv)¤BÒDÐ(QTêçJ‘Ú&M©j>Kà$y©€8‘—i3ÿå?¦ö&  £*EEЌœªÕVl€¡q¡ju1†b{Õž•4‰¡n±�fp@ÜÇYÄ$/P¦Ž0ªÊ‚wN¢åz+ØÓi:÷‹M :ÖˆŸÓµû±¥³7•LH®êgbJ®f \e ¯ ‚¦ 5…Jðnlš\öj…rºqïø–*ç"½Ô’=muH¹ woára€aŠ{À�3~@ñTøu%7£Iþú3ûõ +‘ø³ºÿÓJã *û™`…A³^Ã@¡4k'4«°€»l0Ru„h%7r“ ‰Xù¢W!0Q¦wrMfú´ãNµÉhŒV{Œ›CŒÔ:­ß* `‰¥¥¶·Ç½hvŸs¶Yj¶×æÙ¶è‹ [!{tr)híF–»#;wä.õX3/´]~û<úh°is±] }ý¬°‡�Kö‡m’&3c?¦±c y¨¡—Z²ªt&÷C²aG`W"K²‚ y®@€œò¼0)™²›£|i}·+GÑ'yÅm,–L@z"6lÄþcFö�Б¯Íj¤Ê{cà”Nù¦NZÖŒ®µD£³‹“s„S$E““•¦sÖ½^lZŒß›{bj®ëº{é«fn ·‘g–qÄ|'…r#Ò¦ë&!îÒQw+—ùë0…ä‰Ï4¼òH—&BQªÐ  -Ð>2±IÜ3Ê©Ê2ªY‡©²Æ¡J™i±°KV±²½uo05¤2³Kê4ÛUÈ6qm-5öI# ‹',G*†ð !ŠDSR>c˜¶I¬Äíñ+0(ƒ@xN\&ƒ@ÔC^¤DdÛDæJž]š[ãZf_ü„×L¾h¬{eܶ½Ç{ðZqW8ÇJðgÆGÀþ/Á4Ç)rrµ0†53‡Ë6SÏ¡"ÑÄ]‹Ö!¬Ðt@k‰Œj‘¬É¨dkL7ܹž‹™º™&ì#¢tP¢ß„à`$yVLÐ5^c*2º¿HK#{bvb�u;!*†ñ’û’HËÑ/ÿ2<˜Õ8̇żÖƒÍêƒ~µ’­@4ÅOØ­_Ô:^«®eû½f|Y9¶Ú¼¶eÜOìgìJqokga¸R!|EìÂñÉ¥‰ÅÁ¾´#L~º;xLR>L"e½‰dAù‹"à"PlÒt%«±• ÁôuÁ‘J‘LU©ÔÉjÂ�ЀÄþ r xK 4•¢(¢²}±@Õv ec5§bU‚„@ñ c•ª…‘µÜq'·GPMop‰ÇÓ5”C²p¢5N¢½ŽãCL áë„L= _9®NH¶`ùÔe{ÍÙ»Oã‹ÆÜY¦Ò•í:ΟŸ?ŠQähâ;û|Ça¯'u¯y”]»]דŸz—u)G!TÚ·]¯Ð ˜Dˆã ˜ü“±—ܨîc`4ÓÐÜ¡gÒà—9ày™Y%#¬Ñ1À) dm¨<·#Mã@psÂ/°5¹€}1âQŸØU^Š)y'Ö#MuKdÿbÛ PXº­Mê«CÜbþ-~ƒ8á‘­Í2ƒÔkÅœ£:œAPéÔXݽâJÕM.ÝUÍjë·E¦_™Pp»ÆpFRíf\nZRýà° sËó<¼k=€„0¿;mîMWÓLrnB)t °Y´¬° À» t›ZUªIsHj!ü~` Nk|(Ñm?` › Î1@~!)?°4(,f¡)ˆfqªÅÆ)ÆmÜf]b7r#fð)m‰ð`aÎã;Eö`á–ã7d­Bý8–ÃeøTOûÑÒÈDMصTMåN ÕçÕÍýìVζޜÕhû\½Psh8ÙàþVÐs Gþ=y’î]Eær£æ|7x(Èq>¸+‚a0QHc`=1àW� ñ5¡;ãÈëuŽüèìwBq2‰.²–ìÁ;vøu»VÙ¤ÑG5}³Õ¦x»sáÂHÊÆ4×°<±§€$‰5rL07ÄK‰&AûÀ)™WlÚ¼I†xmæëz“¤Å\- Ç”B È.Iݱ5Õܺͺ·Í_Ý[jÝ»UåéªÆÛ.q[¾P =—Š<Éqc™"@ª<&Íaý0]÷rÞæ;olË™XR2-&GÖbò�~� ‡@1–k¹Žý¹Guq˜/Ó Ï©—iþ8Ãè3ój_—¯PœßÄ‘ «¼Û6ge’œ5q00Æb‚œ5Ql&ÖÇ3;œê1ÀЃ]ædƒS¼@¿7I:”Ë<Oà.–•ÂÜg[åX]üWõb{•ÔnÕÕžÆÚ.QÆâFº!;»;{6;õ(e_ĹaãÞÞ;Ò8ûÓIð§. @†à‹º~Ì¡Re%‚(ˆ_ÉK²œ¡.‘�Q%M•*ãÒŒSu©��è�”xÊÑw˜3çLjG|ìaÀÀ&LF” ÉäÇŽ"™ô`b�—&{Œ(³ g1pÀ»pA‰Ð 0EÉ”þ¢ðà™‰a Æ‘#A“NyRC†]½~VìX²eÍ¢{ò$Ú) J¸-×-Öµoߪ½;åA‘<èfXp`t³.\¸b­q7Þªuëäȉ¾ÜØ1dÊ=Wz³dΟ'7D½µ¡CÓ­UVzÁél£@g;uϧH¸þœ)÷OxÄÝŸ ¼8ð™ÀûýÄ�ùqä¿ú”Žƒ»¥I4ù“Њ A‚Ó¤_…ËÀòíÏ£˜¾J+òê ÒXþý~þý÷«7 õØ«O>öÒoœ*B!‚Õ*áˆÄÉhŽ\)£Œxy¡Œk˜xá$“8ÒèW^0Éþ•Tò äBW\™Cœ~ñšüà G?~²*7«”긤’Z*¨u‚:ž$cÐÍž Žxà ³¦¤²J+Ǻ ®µÔò+-µðZ‹.Á˜¢-À[,MÃ0ƒl4ÂÚ|Œ2Òâ„Ó²É$£³Í7ítm+'ð´LÏÌ6ë³PÓRkíɪª²ªÑ¢‚*Ó*܈Œ-(£.@A©¡€djŠ#|t)¤r£.(P›³®9špI&‘fŠa:$àb½úړϾ÷È<_ÓÃØ[ý#ö½^=O×cq­• Pâ;o|ÑŠ!‡ž(¦—BúÀ€1> éƒÄ¦“>ü(&˜`te„vm,CÝV[þ(£ª“Nº¢Ü!Ž& Š*3R¦’´GIªàêJ…f˜¡¸�ƒ+´ÖªK0Å&^,«ºÜŠX´‡½´XÎ;錳ä9 í1@+댳9ù49Ð;˜ìO‘á\¹ÐÕXólµ‡ ¸Ìu.’Ò"‘BzŠê¸‹­Tê.Í ä¤Vµ¹ãfêÁŒW]5ÀŒxò:—krñƒVšE¼õruoY“=°=ç#>üŠå¯W¸ÍÏØl%Zòž-è¼4¸äÁ†ž€'‰rÅå­”‘x3�&˜ÄE‰ÞÊG¸†'Íi’É'ãžV‚ßâ–ë·8‘ ’î^H‡|RÒ;¤l¸vÛÉÚê‰2)îxLKþÀª-Œß¢Ø.yM‹sfÙ3—í|Ù´èI†ùææEÆOí £ù3æ å9ü†‚ÚÓ2‘zôÞI÷Í-_Ô©ƒç¹~åŽëpè‡rÐyê|õ®CÒš×Ì�:3ôƒäÐ@( ‚žÀµ > oU·ù´Â‚ôÁ±ÜÓŸüØjXÍ"O ÔcÄá CKü "&, ]%—ån2¢̰\<©\åp8“Öý†‡¦C•ªD‚Ãn ±Ž vh´¶\àHGpÐí¤8Ek=l ÀxÀŠ÷&Á<ÀP Þ—8f<̰ìa›ÀgƘáÌ1-ƒÞåÈÆéÍñN„ÑÙdâçGµïþ6ðèšÖ€Ó›üÅ/­CN?ܱ?â+_ÛyÚÓšâ4~EjCz…r°@?�ò[Ü|Ê¿éí>t£Û'3ÁÁ­W}càk5Âd-˜ÖBº‚Ž$A;ÈÈJ*R¢Žtdø…’É‘|„#eh¦3ï×>šð¤ˆžËaåȅͯñ&k"dTt#5«Llh(ͨ¸N†E&0Åû’]ƽLl£Ó„˜‘i&\ ™]ãÏ祬NÞèóp&Pš}Ï4~ðƒ”Ô¨$ýq610Ãl ƒ~tÔf0uð ÉMeS›RÊ2•)¤¨Ô¥JXGL‡Æ©L­C þ(HJ °(ðoÔO(ýËd!kWðÁɳÊü4µ•{Oß–Ÿõ®–U Â Ô¹šˆc¡ˆE^Ä Wˆã ÌÐEÄq�Wü  r׋.´qÀµ†R[N®a£žDD8üZ.(wMÞ/ IìÍŠ�© -‹'dgd¯¤22.fKb’KeÃT<Šé®KjtÓ˜Þ¹<î9tŽu#ÉJS=9vïd…£ôZSÇ ÈàuÀnS ´"uj)3M©L…Ó¶¬Ãœ5®9c*ª˜6v¥.•iIME” ‰ª@~ŠJ¢îM”€C–Þ¶KAº15@¢%(¥ª ë þpÀPX‚$”᫚Ëô«ßiá«eæ[Ë×Õ''òCL´YM&\ÃC×hë‡`hÍjÓ%7쀣ž`çîèT™²"Y›e1~žh„•·üS3£µ¢îÒR±ÐÜq4—áSCÿtÐ’o{ýÍ:ÛìyÈ®™Øq“¼d&7¶ÉÈEnrKÜ¡¬ƒ¥¢¢N©‰HչꇲAªàpˆpYÜÕ®Pª]\ÕÇoö©[xÄûW¾m‚ºjEj+¤pƒ.»21ø!C(*ɈlT#v}äE®á0ü‘»â�Càœ3kh€ó•ê0ð€-×à—\X¯œûþÿàzØ$±7ByÀxÀƒj•ØÖ_q²ø€«$YOw Óî EµÌ³wnºL>ñ¨Y2Ý‹#@×ø2Ø^zGö§ÌzdÊ<™ÉÉM²”eå™%H§« ¬h"Èçä/€][�¿ùM/ 4ÉEþ@‡Œw©¾Zå(!HÊÖg­x–Œz繡Yªlž`ÂÓŠMôAq¼4ƒ´f�É 1‡Y+—«JÒ¹¯‘|¯"¹†á & ¸pðx‘!ºz¨†_ë´È-—j¯é5C’ö“„Îljò%Š·Fújž€NÛ^ ‹,(™.á 1‹]"SÖLjcï©XŸe„ãþÊÄn䄦ld”ÙYÏ:!>1Ûfe­õZ“ö$ oÊÊ®pS Ór I}·iGû•J%€^ƒ·ÿòç?àDe&ýCÆ7ŠóDu‚E=¯)óg§õ“uà ^Kö`P»*³lY…c(ĸ־U¿­QN& «œ‚sMNǨ†{Åaåöº×·ò‚s0A¼^rå3aãdÓë^ýÐ`çIB _$“t[+†ètºÓwç±'á—ˆ’¬Ó¥.avOÖ š¼˜Ì¾Qîª5Zí³óÌg”¡™ëÒ0-çŸó O)ŸFÙ;KÁ>¢8$RÜ &©¼Óþ$)‘xëx¯éëð¡~0rè·¹ù<¹53ei³†³‘€ìÚ<†Y⼶Ѻ¡¼™�kðŠÂ¸�Þ ‰1À�Т1¸½‘@ÂÚË…’à à{9ÛãÎÉkðšÎ1ƒ—@¼Ä»†%̯¨<š¢ø0ðã‹)@ î“¬Ê Ü‚¬øÁH€]›Ë’±0ú Ðb-Í8Œ›¿eû…ú›‘-Åè¿DdĵC;9)¬#6RÄÏH;fsÄÚÈ—ŒšU!Žâˆ "¼@úDKrŠŠ’T$Ÿ &?Â­Š )Š›Ê1ð).†Ë36/¸¯ø˜ªþda‚؆ z³OBÆ[1½ÀI=C¥~Ë4x€ œxà‰RÀ1(…"âšU9Â#lH¢ŽèÈV "Ññ&A" Þ�©wã@çãÀÛs7©x &©ŠŒ"¨57Œ¬Ìà{º´¨,t€‹dÓÃΘÞQ™{­ÑÚú{?Ù:ık™ãº"kD;â1B”ðé G±})ŽüÁ(Úƒ·³(&Ñ4d«`ŠF <r²$¿S$¾+©ÒY 3hõ° aä.€£³ð‚8¶É¼ôHñš ¥¢PpJ„C¥d,¯‡¥2³Y¸ÚY Ð+pé¯KšÉÁqÜF©9rlþp¤W$Ñá!éСÅ{<üÉŸüı(w`Gy ¨ŠèGœ"´°ÃÆðãc³¿Ë,}êü3-òÛ'‰´¿¸@²C‹\‹D.º¶Õꓬh 'È5nŸ­¹Ž$Šêk¼V‰ dzT4Ž3œÃ¢9ŽC¢xÀ’2Š)‹ Î#Ø„\ÄÅ;{*:¾qA4C3i…ì2¥úø¼´i…mØì 9[*ÔSÆO¸A+ xÐ&ø&�I´ØÆ!Þ�—³ ޵Ì&úÄ·ÄÀ§È…ÀÀ¼ä¡¸lÉIêÄ4ì«°-~4”¢´àb#£dþ“±ˆÙºË”˜:œËT(Ì캎!DKdK¨Cl([ž7r¨' M@I»´ë1;BDÏàM¨ÉÀ¢ŽýÜÄßŨÝhÉXcŠK‰I«à5K1•ÝâM¡P©$-W`�*=å\ÁÊÃÒ²³[I\ñ VÈ‚<;ˆ¦J%»A8§ÔN„³  ø°¼x–él3³¸ðŠ)ðq@Ì‘D“ m ö$‰D{ñFÛã &© ¾DÕ Â›@GR’StM–Ô X€Œ² ÚxÀ(Iµ'à(#·™Åp?5J#Ž£=¼'Y¨ÉÌ54™ÄG”­œ ­ù(þ[È#ûHQwjQ•ÉÚ¨GßPÖêØÏ™¸”¦øJAÒ«€É (PæòË#‰ M Š`ƒ° ÄÒ¡„87ó¤¹I–]´mÓöZ¬ íäÎÏc/_ Ï‚X`èG´èq8 ’èSñÓ=]ËxB&Xؽ:ÔVÙŸH}•Ûð‰ŠuŠÃê ÝØ@ìÈ Ç‹=‚ŸˆMX$?ÀBâøØå8Ž¡Ð Õ-ÕÅ,HE  ÐÆôWÝÐËŠ§€”Ȩ‡a“€rD< üÑ\^=!V-ÚÓÄÕ¹«™jéŒ{AŸÚà@æ¨ލ A‘ü‘N‰V¢àÖ¨iþDÒQ!’Y,“ðpÓfL3Í;¯Ìk8ë”› r×ÐÓ³¦´›§”€í¬‚bL½¹ñ yUõh šp…õcòÓ­šA—ná  ˜X>©¨&Þó‰ðƒš#0€$¨Ø¨8,3pÏaµØm$*Ž•‰<ŽL)“ Õ—]'˜5Y›§ ³,-©,±›?…„LºXHâ!­•ÖÇàÐÐBÓÌ Å8“»ˆ?§ý¿-ÚyÑ5ê^tØÖJùÑMdoJÝê '©ŠØñK¤XŸQÙËiý»| Š?xƒ°¼¼J6Ë B¦L=q×,È‚^‘W‚È.5þœí4àZÊ׊Óéä‚qU(Ojôƒh ¿J—€q¬Ÿû<a‘X€áó9I«œЉ›¾ÃrNoÒ‰ãÓ+WxN‚$(Ý×ÅÖ¤ª`®€!UÈò]†Y?Yk <z1[2Ý©±;RHåÕc«¿JÌDù55QDØQëužã1¨Åˆ»Ô€Ñè•Ú¨} Õ(Ÿ‰%}šåÈØê ˆ¿t‡›—„ÖßH¨!•qºê“ × rã×ä”Û̫ۣêRûXS‰ PØÎ,à€w½•HªÁ™Îb¼ Sr3iàg9¸[Ê*8!®(ŒèIK4þ@=äßè w�ÝŠ"œXá·Â¨C+æk´x4 Se.ƒØ “Õ‰öœeöA d£˜ãòÑ‹Yëž%ž¬õ{�`øÙ#“Xk?‚ (@´,¹ˆ'Ñ:žIV4&ÀçuÚ:­B<™0ögµ_ïÉ7_>A %ž&®¥8~GíÈFxÂ\ø�¨è#<EÔ=¬ÃúX©øØêëh×ü#{Ä(’ŽÕн *¨ãl…N’[§:½Za Ì൙íìÁÒceð‡OÞÅ*%ì »© $® ûÀPÐ�"øWtàÊO�ËŽóÊWñ£TŒÍés_Ï(W¨gÐþg` ‰+ñœ›ðˆÌÙ–°‘Îù'œœàèŸ/cÙ¶0Ÿ É¢ °¸ƒ£g*!U:Þn#“/I±c«ž •'BTlÐ gÖÐUYíÌŠèðQÚCn[¨9jChž ­ó5}2pC°2OA ×NK-¬¯Iëk&Ýn2"Êùè€aWK‚#ˆ  Ö›ÎTÊšÞµ™%:Μ¾*«Ú ði ÎgÉ.3“€´ÑndŒSò*UNÜìDÜ< ‚#€=©¾7%œÏæàm¶d]øW(/(ùÞ0?pœp‘Ѝ«2h•;‰q‰‰\6Ή‰UQï/,Ëþ/Ks¼QI@ر֩  íëÝÀ I�Ó Œ‰µ/ Ñ~¦¬ #Äc¶ ;d£lÖVuÌÎ|ÿÛ%kiÃܶ7-÷^DQcÿó3ð…x ?Å‚I’FY ';U ]HWe Ytšå8û¼KoñûÜšq¡hõÄÂ~(ƒMHxä1g–X8›¦é½©‚0-ÆÀÉÎmðéXXàûHÊâžÎ¢Fê¥L%T:êyÍV0ïP-èV`5GCkd¾tq!ýúeƉM«&¡ü¤èn±ÏåPTUÉQêH‚I‰Ö˜”ŽŠ¥ŠªøÝÊCÅÁð±ÂÐ(AìÇÚ"þ.n;d»ÞY½žŒ Dt̹°Lk#hÊ�éÄXvÄÏžq±è]7ÌØö÷¿g1˨°!r×5àÆ(K­yƒn?¿ó{{xƒK6^»„ÅÒ˜Jm+“wxoíxOí{�%€8Ðàw~w‡pÔˆæŽøƒ?à1wÊ„Snøx,µé¦zsñ(ªìôdˆà€ íŽîÎATJW£åìþ$1ßPý mp‚^�·b…!6 “ÍØÜT«ô.«ŸnÇí€Á‚ϸiüaÅsë(Ñš%)CŒ2ƒ7¨TÝŒN…IOI2‚¼ðVÿþŠâ=ì;¼k°†(±‹—LwÚÐp-æAqÏ Hú3ÌÊ\L~Ò¶GÜ™´°l}c´›q¿—åÕ¸LÏŽö¾vŽJYl?ém÷Ýè‡p×8¨àT¡+˜!/$™ Hѻኲ¤.{om×~ÒY\ŽíXðÚÀ(rð…×ä9¸a¡Ûìä€et–SÈ‚XøéVj5E¸½­êüßä –Ÿ4SÂ…ÓP€~ U^ƒ<ÀŽ-À0€ádÞ¹R«œ.#Bý‰H¢Ä»=šh·Û}mÙ€·v°7ª±·Ž"Á‚pŸØÌÇ ÙYÑôz,ÑÃ=ä"°†aˆ)%J$(ñdà@tþ%¢k¸¡Ãƒ%œ|ÂpáÆ5fÜèqcEƒŠ|òdÊAŽ?àèD"ÂŽ+7¶léÑæL‡*1*¤ñç͆6kj$  æ”¤I/(’ÀéÒ à]825F?3ZÍø!qÍ­×x• Ãêšð ô3`¦m?wîàáh[ÇÛî¤^ËWÉÀuûÁ£[x¯Ô"~ölR•c[¨*’ÓHž\…òåÊU"kNÃ¥J«mY¶¥¡Üª•„,b5‰•e4h ­Z´ ºUäÚµ5®üù4ðÓU¶Ie<ÜkE¶¼`fÈ2zŒ¨Þ£GŒtcè>¢Ìµf®`b�‡ë×GþüpUü‚çÑ»5síÚûü Â,¸¶ÀÏW_áàzfÐe÷™ÁÖyýà¥U?qùÅSI=PaSh¸szø!ˆ!Š8⇠ñ áÀ$ÌI¥„QB:ÁˆD™dÒ@OP4’C2å´ÒŒ7Þ8ÐŽ9âÈÓ39‘äL9I‘/½IuePG¡£åPBµå–�LAá˜|Q(•S¬£Tš(¨Ø:J(!—œ¹uFaZ¹U_íôàGähAÎeœ–z\ Z†{#PÇDuñ%+¬ìñYì¶ni6*e¥•d¥ŽS‡Tà�8„™l¡¼ÖJ²HpÛ§¾Iö¯§I° ®¢Ñ‘C8³lrI 51§Ð8�È¥ÔZ×ÃÕýP+â ^L¼¶äö€Ÿ{à^“Ä‚…áƒZki%ŸÜåYowÚa•Ts¸À|!ÆW™REuÄ\ð¸cÕ¾Öðà%‰K<±‡ ˜À DåB‹DP% i£•M‚”SŽU–$²O&gä#Á̱Ê4“¤‘9ã ‘E0³f—4… ´³Ì�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/rain.gif�������������������������������������������������������������0000644�0001750�0001750�00000007311�11462120062�016234� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87al�l�ã��ÿÿÿÄæÿ”Ëÿ¼àÿ³Úÿ©ÓÿˆÄÿw¼ÿŸËÿ”Äÿˆ¼ÿw³ÿ�Ÿÿf©ÿ?Ÿÿ���,����l�l�@ÿP™„’º) Äy¦ÕVp1vee`–‚…�®Ê×Nš½Uv¦@ç°¸(ŠÜëd¬Y‡æb«yž5Úg‚µ|Ó&¦ó [ËÈ/(Áå5#–š¦Œ2]֢јNùP~@|…†|Dˆ|Œƒ}Q6†EN~T^x2;"0</tDlv<hQ“?–{–ˆ  ‰{}+« FQ2+¾KŸž$&%ÊÉ<»p0ÒË&=#¼µ¿NNFI^ææ/ÕÒ(ÓËÌÌÕôöôôó÷Ë#ÒéÊ`¸G ‡nmÄyØÁ‰Ä4êºd"ÁL  cêÞåÛÈ‘àºy#ÿªU…lÉÀŒP´[Ñ@'¶ì€¢â ïàùdòâÃT'½H³¦2‘4O�|±ËiÕØ‘É3™: J–´¨£ÓaÑNI«.á&F¨Lj||ûJ†“Ú0VT‰†si­vÈUHsÓ•a êJ$&Ê HWˆøÑS( ”ÒÂBŒ€ÅÞc½ÐÀñEbÃW4øMå ÓbK\• ÆÖÒÌ;{˜àˆ2`îȪ7˜fïøgLé zþŽÔ'o^@‹>¡Î4ôÓo–üpA[¯­ÂuZ\é;è¡:j<lre×AIœÍÂ÷m_ܧDa¥r8ÙlåNÿ2w]#„ èüÂYg‚…vÍa*ìô‰}5üÐZ˜‘qFlÄíäßm¡HÞiª‘„h¦ø¡›„¼¸�6#È ŠÉÒÀE¨KŽQ,f D(rD¢ÉK¼%£ _0” &"¢ÕºmsÀøQHvÙR"Œüà�‰”yd .IID`pN' G`X¢àK'v4cʆ<YF}l’²$”Lj¸……µC S>eS>’…‘LÝCåTx™¨ÐsÒ6Vf %Ð�þ¤W�GÍíÓÑ=ù8§Z%ª–jL:µFÚJ5–XÜIP¡ª‰€6YJ^OQEUQ²U­:�ÿ@´šg°Äåd¤ï¡S¤í¡ÀÞ¦ZÑ€JkÒj2Ñ€éÄp DYWŒ…î¤ö'ֈè·«±† B HFlcÅפäv…w,(¶ ‘}cÊa/ö8F*žè´ar6ø Ä·k„N°0k¾®9F~apƒÖ‚7(DØ »1.MÐqÀþ í¾vá“€³òZ­¿<ídŠQÀG^ùgÜ­Ac¤Ít@�HªÁD=òxÕPOÝq–£'€Z~‡!5,oæqÁˆý‘Ë«CQÝÉÖªR¹Ë¢ˆ^Q êŒüE"¡Z\üƒ!ßµ,êŠWÔjiÀ›µ@*^ÿסiš­)Dÿe”h¸"h!á•jgÐÆ/T±9Ne[yWIèy†æ*¯ÁÅ0z¾(¸eДØÃ‘+–¡è7Ù–5Í%%Æ–€%‘ÈðdíæJ½W(/×'ÞH ÷¡cDü–‹÷]~ þ-} ÿ ¶RÉb6 S}mvî´´£XÖø^v ¦˜‡ S¦[$p˜ûàÄ$u¡_@Ó„â »0,O+ˆ…~Æç½?„‰|T#±#àõGz‚øF8•÷¤Ç[d‘èp×96Œ/u&̈ I?oÝ3œ�Ðe lÐÁ¦Ô•Ôd„C qE¤·ŸÚªG Ǻl°vÿ@$YÑš²`µ£´ËVë ¸î@ ý}j]òr3¦Ê”ŠGsàñªÈŠYvQ ¥LC6žLTT’Rqî4Š(玒òãûF¬åZi¬È+Ä®Ä.K#_¶¬Õ#ŒJ|N¦ÀG5…DÍxîØ,$RëTÝåМ’U²Iy–Hx6*ˆÔch£r ¶Ò•D\½ðn()Gi®3Ë3V¼t [¨5ž°'SM©T3½R«Xƒ3¥‘YWŠY_ü$› 2Þ¾H«¯(3kщÝZI†b¾ä.úòÄkÖ™³¹9Ãt8Ø+CH¥á¬ © ‘u s”ÿ’DAT´ƒ¼.Õ¾Dš³íê-p)€¢3ÇEþI KË ¯™Óí ‘ _Ú.èƒ'9f1l†½ôE FhwR»×[83†Åm 2˜“7˜ö,‘!GlÊ�!p”º¡rf4«Ü œ€ÐBK; Ì ,6›hh¬%RLi½«ž9åÛ¼N7™©UãÓ:Îo¡¡À+3ÅŒµ:%8¹ ÐAwÑnÃ?`ø¢LÚi¥†ÖrÖ÷¯ºå]¾ªÕ1Œ¶&K´5afxX7¤f’lMË’ê�g¦ZuL–p =Ty js嬺h0lêV¶g!ª5+SÚÿJ×ÖsFžð‚™ÈdMÁ±ªBH"R$Ü0°NâüäŸ\\$+‹ÅÏÚøê4E‹v Å´‰u@y±ùîCû†.^–à - ËvÁ­ +-ÔÏÚ ÃUÕtJ3BR'U-n¨¯Vüjîu¯þîè$ô9—–aZpª|XgµÇ¹¦eİÎTq`£€ê`E^ï žG ÄË½Ø csÖÍ žá’pŒk}ÅE‰åBOSvïž<Û ÁX³ÙØDÉ4xZë(þÃd°žæ0³‹òÍp…÷H­lPBëŽÖ9X„Œ7æYI}ái¶;tr…P ƒ$ òYÊAÞ±ÿöÆZ¸ˆÏ»Hê  ¥gp¼Ùx²ëDkÇðh(hàzsm²�Ú$9ÙF¦ƒ^‘¨À‹-( É=0`}�@H16êÒZûiñ¶T3rŽZèX3Š+pL±`òܤA7!„ExEI_M$ÈðšÁ‰å a×d#dô ¼¡Â¤ÀôµÂ€³ˆ¶÷VëjOÚÓ€é+…‡#6CJÁ¡Ü$ø‡lŠI€Eh@ ¨îHÃéK ªçdÏ¢iå6”v†Ì·\ô»Ü³ Å«®ñ9ŒÚ œ´œ² ÷ Ë5¤¸"¾·ä?{éƒæ¡ÎqZǼ¯`ÚwfJ¶l…e`$ªP…ÿÄÁ@t°H̸r³€òA‡Áè„ÈÂÇšóe^S)JÒµT»kè«Ù—ØiX¢Lϳ8¬—›e›Ùët t‰­Àù ^ꀚîÂz$¼ŸNˆx5ó¨àTeFnù{¾ØL¯ÍŠá4A å"c 0˜zw@:MÒBÍÇ«Å0ã©´ÆG˜V›ÿT–½> lÖm®»7Œ, °ò9Ô©ûrÊ©>.«"µA"ŠÍ¥µYAŸbF¹³¬£:Áªo}¦WÁ$#G<?l?–&xCÛ2õ˜Œ­cX`ÝŒÕc×^å*æ ŠYÔÈdEnü‚û­‘7pµŽ¡1ÿ~œÿ›’´~”„pÞdÑJÜöפ1ï„�ãxDéç{¨¤, ˆ)õQÃÁYQ‚1YÌôæRþ‡ª"HH)ÏR1*Ø7zõ"*Ä% ÂåB¿d)yËR]Ñ!]cD„æ,d“O¸b"*ÁQµtZ¢%%g5ØÆ‚}ð÷K@ˆ*IXKM¨uUósÇ,á/·TO¤r'À¥Lž±PÖ�4Gˆ€tZ_x]`Ô[A³MÑ$76PQÇ"­‡Öõ\UèE=ÃŒ—D‘.h x„!6¨§ññXìÔKÅ’{˜¤[=S)¯d½‰fó ›Qÿâ°ÿB7Õ†›fèç5XhF-ˆ£(X† §¨.£ÂÉY댂~=/î Á7æÄ3jåIÂ…Ž8NêB‚bXwÈØKòÁŒ/áŒN ÿáI¹Ò)À)ø×Yçõ…Ä õ„O#GKwõIí@8Ü%cÃveX9aì‚Y`F‰¡$a®óP¥<!P¯#:QcD%³V(UÚ36§•'E=ð˜TîHY ùÇ×a±õ‰CDŒ£³c#ó/£.)Ö04Ög•|0ñÁfQ'skÇD”{¸#<nV_7/&r1¦Pÿ{ïÂ0r†Æ†"‘6÷×ZYÅ%}`y·C<&$“LI|I8 %&IãP|†6Ò9¿a.­•p=„xS¦“iE d‘U – P6Cv;^6R»c_„vs¼v4Ý'6`3³×ß3€‰Ë3„É7…‡�öm_FcÓà$“Âeo¹gãX•chLC5Ó8RRz5P¥P´ÉE )ö7W4I+„U!×mPgögQ�b#iXñøB”Då¶×+åe.“rvö}gSg]ÖIwÑY•²í!…}U4 &$”cC#ÜG4J±ÎWæ7ÿ{4ƒ=‘{¨•ˆ("d§0³7(ÐeSXˆbÁJX0Èò€{镌vr^$M•a\P€“B•xÚtO5±h§¤~²â[´”}aX.Õa€“Ê2á°9#-'X¢vä,õÀŸëWƒáD‹eÅgïÅd &)3DøC«ƒM,<ª*ÛR AZƒÄŠë‘à…•«€fæ‚0x–hÙ¨£$ºf¨¥§B]œZ~B[DUà„Y\7'›¨h-åA7…FȘ¦¹oê€RU;qÂv³a< ±\?h^ïÄEéõÎÇuà7AzJÉ}_ 2„§"e£¨|æ}ó‘uˆø~Ÿ:ª†ŠÕ.Äa:è  ghAi¹?ðÂc€2U„©1­ª^v·Eüäž¿:y`àáU¥6ñY1¶ÚšF:iŸUqÜÕg�™5}q`Åv6_zeðr[F ú£Qî5ªÞ2-²!K–£Šã—8u¢'nÖcÞÚžÖÑ��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/tan_paper2.gif�������������������������������������������������������0000644�0001750�0001750�00000044725�11462120062�017350� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a � �ö��ØÏÁʬ¾·¡©¡…ÊÃ¥³¬©¡~¾·’³¬ˆŸ˜v—n³«©¡wŸ˜o—g©¡qˆ_ˆ€Xˆ€RŸ˜g—`ˆXØØÈÊÊ»ØØÁÊÊ´¾¾¨³³ØØ¹Êʬ¾¾¡³³–©©ŸŸƒØØ±ÊÊ¥¾¾š³³©©…ØØ©ŸŸ}ÊÊ——u¾¾’³³ˆØØ¢©©~ÊÊ–ŸŸv¾¾‹——n³³ØØšf©©wÊÊŽŸŸoˆˆ_¾¾ƒ³³z——gØØ’Êʇ©©q_¾¾|ŸŸgˆˆX³³s——`€€QÊÊ©©iX¾¾uŸŸaˆˆR³³k——YÄʸ¾uÃÊxÃÊŽ·¾ƒ¬³zÐØ’Ãʇ·¾|™ŸgÐØŠ­³s‘—`¢©iÃÊ–·¾‹¬³™Ÿo‘—g¡©qÃÊ·¾’¬³ˆ¢©wÃÊ¥·¾š¬³ÐØ©¢©~Ãʬ���������������������������������������������������������,���� � ��þ€8‚833_6086&(.%,(80.,.ƒ<8<B6™?,66B?œ.<E61^&0@<b3,‡6,,3„6X‰X?Eš<¿š™8BE@X8. œ6.0fÉÌ63.И fB<6_É(03ˆ62‚ “0“,&É™0&Í‚“á“”,f Ôɉ`ä6£82ÜÁ@Qâ ŒTÔ�Rƒ‡·s¿d°€ÁéÇŽ¥ZQ£(ˆENϨIÎ ´Âaf `Ãp`ùEîœ 3×vX²$hÆ;˜dð¨1Î…B—ñXÐD%ƒï•Ø@\è¸I‹ 1 é+ç.Y¡U&d4\*ˆ§ ¢þÃ| Ô4KbHQ2X©œ *ߨR'L‰´c"”0Æ)%i)s@)\FÌ&*˜yóf‚ÌHÞF¹›:.à7§´JJ‚–Hç9p“@b¨ ˜3ËÜÄ8~ð�™æ»/Ÿp4ž•Ì(Kÿ-ÙR$Ó!¿°4àñãäò|_Ù™~Mi<A I”Èž ~”ø‡DAj_,PÉ$ÀÀœ ˜sÎ" ˜ð<̬á̈$òÅ :ˆåBZKy#SDEP° 3 6€ƒ„‚3™Ì% 9TØ"ÆÂ�ö‹B�1ÄJÁP4Ê6L1C"fPD‹ 2ôþrËPƒÓHfKdã,'É,_”PÂÿQDM:ñÖLÀ­±¥ ‘<ó`2úÀ0KM„̤5’Èà�&™ðÙÒ/a�!É)'H¿ òC!xâ ß?ðóËB ªR+4£È‰0ì`‚<è§%†­ò`˜PH 6˜! ’Ù•YyàÁ«Ð'M:6Á ‚k’ðŽ  Cg>–ÐÏ7•4ƒ"A’Ø„Ml±Ö4œôòâ>|âjbfR¬ŽÀ §p"Mì† Ì<ÀÆ 23Ã#‰!’8ÙÀ�2¸å³ &¬aÀ*d°Æƒ È4cS:ÍT¥Îlþ®ÂÁXmÈ"&bXçe eX–$-(Éx*]ö’L‚8°é }^UIŸádBÍ ÊÍe Ž‚x† Ÿî)²Â!à´µáD³Ä 5Ö >­â *¨“Œ ¼É9îXýQ´’Œ6¤M.„€æ;kD³é,9èð$%psLC-ÄžŠ´¶ï 'µX”l/ %8µ”‰{øòD¾(L;64òÈ ^4ËÍ;ä5£ù pÃD. ±$&Hhâ—.p)Ù0H(1'[òGWqòMa0$àL´S½… &e"èräX ¼²Ã¦B ²“ òÊGÍÁÏ8?Ôv&ÿŽ"`þ­€áÈT%ÀR>›4²™4ðùDç˜@1‰/-•À_aLò†g.5‰¸Š䯒cl_‹G´ÂB/jˆ!`”Ddã0…6âÒ-Gj HOKÀ1‰TX€F™¼ü ù£dÐ�nTî:š+Ã'ÂJ8¬ +XA:J°¸Äˆá „1Ä© ä�ùšð :%†bp†3储Dn¬À”¦Æ ¹]¦H ¨fØ­åñ-EúÜ;¦h(â>—‰›Ë~� 6âsÁ4öÄ ˆeÅ$H Xà‘Ä€$Ðê6äV¡@£† þ ”Ö¸Í� ‚ @9ILã”ð@†(0€ ƒ ºµBþi ÌÆhD™!@`9€‚c¦à)âkÛ—H¶‘¬ÀyY€–L@‚Tbl6C ZLjUŒãsdX$ ²Hùy š p[#hñˆ-åŠ*p€kbD|¬á_`(¤ v�‹!QAy3D>„RŒm:oXW`Zµ�^þ% TÉ€´Kš°$¿`… ~͆‰ù‚­h‚] B©A Üg¦p†9³Øì¾q´h€—i :X°†|ÐÇ3ì[\ $p,8Á˜Ô¼é¢ØzÀ=¼%þ<¤íÜx`^$¸¾C JZùÀM]F3ÑW/*Ñ69‰ÐF  ;ºÂ€Iny .GI͉¬ˆ2‘ÑÕ <�¿«À@uOŒØrq¿QVÂ5ûzÄ(„‹Íe<›X°‚¸Ù.LÖy¢>2ƒÌ05p×`làEBÁ` „âØa6E#a¸`°Ý:f•|¸�h`šÁÀ‚"†A’£Ìð2(2ЙbšQˆ  õ¡a¡h"0'ZÜØ×C¦b 3,€zûT@þ5 ¤¡_–ðœ_2—\á ™¥o„¡#mä&Þax.jñ )eÅqVb†þj\ëS‘À!H-VáD’:V±´Y°À „Hn"·¼c ÇüÊP¼‘ˆä.3bõ |f$�Qp-àfqÔu(>ý¢ XÈ/„@ÇèhI&(þÅ‚2˜ÈÇaBÁaxЀþýŰ–z ¡¡f ¢4›Jy”aˆiìðÌh‰p`†d" 8!à�w¼ª/Ég&œ¹/°6f8ÊRdJP6(AgËÀ€DYf%0r´q€ÅÜ‹A¨ ÈMN‰1 @ 'êCËã[ BÂ@0 ÕJg´A‰g¢¢Š{æ1'‚þú+$’`M!y$ ac¦�ý˜ìlÆ/X›2Xd3§h{Ja ÕŒðà‰ÌLü—_ H@FÜÀ xá6�C \j–°.øÂ`¶;yÀ*u—‚ˆB¢Èûþ(XàD+%¨æ[6‘H�¤¶TªÌl¬³ƒll  E¨3 bß×9t簞‚…•žTò=5jHXða˜ ¹`1@Ú#÷厠!7ÀØ6g=ài8ûqPt 2ŽéL+,` >˜8/Z£ÔöUê@€?–'+x�Á}ÞXF[Á$›(ãöM Fài8þš!‚* �œh`kp€ødà.qxKn†sDj`†‚ €$ð—c¨à‚2Pð‘±0p0`&­cÁf†ê‘xš §P‚¢, %)„ŠvŽê`ù¦,(†‘¤. Åó@@@›F\CS é|à4QRËŽÀ@°‘ HÁMRÌPÊ4»1€ÑÔ‡DÒ±´Y: ð† X‚ X�ÐÇ2Ÿ!–©£~Úð¥ÓnÈ0 ~ô a #_@¸7Ô† úq‚t3%@;B‘gã0Õ7ÞÂ5aÁ àßÔL\S·B1�á@–Q!�7Vþòc @4‘r/‚”»Ç$p¯âïP$†§@DÓ �Ebuã´¤" S\K ¸Ç «`L30)°{1=æ/ Â&Ô€œ‹C5!DqD4 b1¡eb6NèP�!àR­á*i)5(íÖ` /bÅPÝÁY>Q0.<�\„ç$�zvr &À|ü°,pcgTca×*ŸðÝÃ1P« µ�Q’´ éT Ÿó;!`•¦o„² ˰4I2T x.ç°BWšÂÀ5 �þ:²š!3( Í0Ð(x%`T‡j}Aq7 &„Žð*à!( XM3!44<ƒ3ÐçSZAf®¡e¼± aÀã.3ETR1Ö<!HÍ!£°Ø¸q1ØÅ%ðH  °C s1(òd!ô2(<° ­ö<�0@„e «‘’ô :bþñrC°ji³t”0@:`\‚4‚Éà·µO~·0EÉG€J’À0,ƒ‚^@=e}Ò_ðH à+pÁ ÛDqð* �& R‚Âþeµ!<Ðx[éa•à 50ãÔ+޲.–™ñ[�òw‚²Ô0.ó €B,2&€{8‘4"H3°KÆ?âŸH #ñ+ ãÄ­y%p^Ø&&p+lâ?Þ îp72€ãq¥`Ž3 DÄB>²0z)¸ €aPq *ÀfQe.°³0$*c†±š%p…Æ"‚dhÉ!–ŠÀ TÀMwŒ”pNGR½Á¶&” 6P˜géikP qÓs8 1h&_`�P{@“°[ :’x%0$аH° AþСlÉ|{²Ig{Â90.p:�ae ;ð:Á<‰d$1' ~WiH�[)V!/Q‚å|³rn( 9 S° ŠÈ@¢´X{­–„&ÐÀ‰9Ð “á³ ®E›°Ÿ¢kq•ó—%°&� á‚È€$p¡ú†^@£X 3À%Ð)B<XŠHð*ƒ.+0"ÐRhJ™€7`Ÿ:0ìX]ã6”ð*ð+Í“ ÉPÂ’áŸø[Ã*EÐ�$ø(¨ @¨à+¿á�D1C³´#ã�&þçXó'…0 €ô=ò˜aÔ“ût‹œ1ð/çDµ 0¦ CG9.@?€;§,1t¨E`Ðg$YS`\ÂZŒÀ’&sÈ €CR¡ë8(¥¦Nq�_@.ЉÇ@T³É *àœåi:@,�Jº#.€tU‘ ^°H:#ßQ§15+pÉ "a°7;#ˆP ЌèkŠð/_¢%•P tqò£¨¹ƒVÛS¨F?ã”+õ:Ó A„EqŠP� @Õ<Ñ¢HÑ›"SŽ’,=šqSù/ðþAð-@c ]*™­Ð2@&îr‹2 h¦pŠ`\¿0Œ&Â$Ž1¥B2ÐÄ�S¡+I':òeÔd6B¢LÂ/÷)®­†^„· €$À„`�iP¼Þ¹»–;wK¹)R¦f‚6rXýA ` %Ðà§©5  D±a‘VMœ¹<ÙËYRài 1\Ž÷ œàcÞæ®ÒÀ*pfRÐ2ç”â¥%[¢`‘½sI‰0‘µ .+ñK¡)˜`} š ç �h÷Hñ**@AÆWIÐsÁ|ŽVwb m¨iQ sþR�¦E ŽÐ,¢ðs †v.2P2Û†'7——‚B1 ¥€B0ðÄx^û’+Ë7¤‚�w1(`ÁF¯2à?f‚ý±%(x}Œ°XQ>ÅcK!Àb¬ …Ø žZF6  65,C*,îppÀ° ‰ü€w4ùP�a ›ð¾%@ô!nv^ûô)ð)0 ÿ÷+ó¸À¡IZB.à:‘·2  ÁlçP ’0@Øp0•( Ûô¹‚Ò±!Ð<ë’ ±±É@1>A„×Ow+ã’q`�,P² ñ[´` 8¶Hê’,þ/Q×Ñ'Bp>IŸÀ ­òTÀOŽšÊ N‘6pG 2Ò­”ËC¡w€ÑJea%€°H€¬óh z¨\¨ö[û?ËÇð ;¢‡›Pqã‚{>¦xÉ5²@I¢b±¬¬™ ¶a õ¼�éÁedÀP•‘©ò!äˆÿYÏEÊu\m“½k Ëá†lºMj1Ù�® QeƒrX¸R¡q‹+µ‡vCj­v­æÙèZƒB(Ì„Í0z—¸´Ìp+¡ñI¨ >Ú<çˆmµpa½¼ÈÈ?­°/f ­‹' )³Ç³ þ¹^l"‡5æ>N‘žçgБ¤ `�‰9™‰»t6 R¬`�a`�W ßZË- à·Šg3.1¹Ò “H M5XW˜ ÐQ E€Ð@ ¼¨ý `àîÐYïP )j<§Õ,¥‹$ß‘ÃF* kðšâ1«‡Í9¿¢¿Vñ(Hq6 ýéi)³ïtà/GX6PêP> ‡Ü¢=¶*�ê€CÐ ` @(û¸gÒA;ˆ†tð†¶Ô¯¤”Bp„î (xŽH1T§ñÁï07`à#Âôãð)¦þt”š¨%\â9Ôà`ôàDµë €¡=ö 1RÁ?+àúR•à!ßÕÙ š H'D1y‚@(àÍÄyE2,�†÷ò­0Ža:ù¦L’àUEp 6;§e1@Œµ PÐÙÓGÃÉÐ ‚òbŠ œ( oñ+Ä1 ƒâ¢>F Œð=Ê *²_œÁU*Å..ƒ%´ Ø$Pºq3N ,—a\!Ô\æ;ÖÑ 3P7«ÐÆ'C=1°<Ùà á�ßö/ ù©À�:É‹j —Ä|;¹)ÚëžÐc„ æFñ€Ö S×4+ƒRSþºõD­CW—E‘àø¨¶€ž5Xú¢‹t^@„ ²6¢*DÚ ̓": ŸÒÃÛWÄTºêÐ:pÔ~3x'J.°{lÂ5üÀ¼ñÉÈP)Ô)U‘¤m’,¸©6ñ™¼(… •é´èp‰fQé$0è *NJR ªAÀ*1z‡þšäá¬bdà³/œàHœ%5Ÿ0CW$ý±aSq$Ôy«o³‹À ¦²k…¸Z€!‰ü!E7£mÚ0Kw›Û˜À¦ùT«HC]íÁØ6X𧻢E²s†$øZ]7P4† œ¥?pþRÐh/Ã:œ@:p�e0»÷„¢Xœô?fæ/˜ó9ËgÜ2 �RÌÌ@@H-5ž§­@Ø0÷è ¢e€fMZ6Á[ÐeZb8×Q µ‹|)ÐÚ0î¼Ê ”«8·U7�1–! p¨ø•i  `Цo�³„9ßë”Tãó"H›E,‘¡Bìq6C’É §1É버™¿ô!Ćˢ)Ø2LoÏg…¯^{Iÿ‚AÐ÷;N€ÖŸ€ðeÂÃSÂf"#ÄcƒÔ€ƒ£Ó•2RB ó£ô£còƒCH9ä ã’�ƒ"S3Yþ”Ó(ã ãòeSæâ&à ÃSŒ"Ìb ó‹E;邃»E¡ 4dÔHä€ Ä Snc2sŒ#ÌSÔ@hã²#ÜbâbcCR²³#e”"÷d¨ÀeC`l0±£Ð1G X”XÁ£† *;òùØ!dF…’1ÉŒX¼äÂB¡›ÂG.L˜I€™ŒÔÂHÁŒ/Šì¬‡ ÈŠü€Hµ"@¶ØÚÂ# aùˆ,´ÑÈ*\ ÂØðÁ ¥.V qo†‹šX±°˜)Æ „̘b• Ù-ºLŒ8–o/Aò™B–m¦Œ.x£T $2y.&þÍðKí2Ê_f7Uö,2e8PQ£HÆX<„ˆÁSH;äf‚Dk93v+Är …µ‰_Œ ñ¡ÜWã4”`ÓáÄ [&œsÁ¬j`~ìq‚¯ ó.fL™¿œ ¾Ö1ÓVé qìýR`P‚C*Tæ ²­ƒŒ ”Ô„Ò=Õ¬Tƒk¹ìÄT!k$’?ذƒ„„a[>Â𠲡‹l¹¸€€%¨`‚RëuTLX•±¶Õí• ¦¬“O@Õè‚L 3AÂJã§W[k™a@0•í0C QÃ?ÅR ‘ð™¤S … pf8˜—‹&*¨fÎ#¿þìD*À ÀQR1`F.;D!„ rñD ÔèÂn¹à MCáÁ@‚ZM2C BÐ9NZÑ=–,dr AʬõH ºàðÅóÌ5ƒ}š±Â …„ÖÞ$±ä `  € `„á€3þ=Â_…2ˆqOq„àO9+•ÓŽŠ!Uáj ™)¬CMŒ'(>kîÅÃXðpÛ.2TÀ„]¿Ìe¤ñÄð^«ßL‚‚TPòa ¥óXJ1³“°µ¹ÐEe�xH_”°“>|©§±ˆ82á‰î”2/JÒ#~’q`f È@“ bL0 §@$ш,x×nQJ$ÄI§eþÓÊÐî+°C ‚~Á� `°µB MnÏzž–ãí‡íÀ€oÂ`q /èpÃ^-J„W3¬•‹\ßTû{Õ„$f"ðœã¬Á“0ïÄ Y7@T¸ÊÈ<V™ß[xÃã åŠ6ò! ðÑ\ÌC¬h*Aúê ƒ £ :à 18x6 ,|æL>ñ”@ ™R!%RáÀ@[)xÑÅÝø7Þ‡ ”€Ï^8P{БÔPV- ¬¤1JY–�>~IËÃHÖBK´ÄF¢5tÿ²4³ïõCiuªRbt¤ƒ¬@0ÑÈJ!/$°0 #´çÅseð2¯ÅŠP²™?%þ„0x㌠‚\BWj€…;Ð~€„xa $Æšòq±Ô� ˜Áº‘Ü…Èx„L ˜…‹2�¢Âš!œÂaàk\l#CÀ!„+üB)3ˆADä§½ðÈ;!ú†#Èp¶Ó¹îƒ¸Ã#Ò¾Ç A.ˆ³lP6SüÀ+ùø‚Ìðâø…5kRŠp €eä”è–vG'iÀà éh@<ÄÐ À°sá‹¢dX ’Éü‹Z ~ãu�Ê)ðå)ðh$ð±:«�% /Q>ÌàJ±".µà/uZ°~À‰þ…Ìà^À °£™Â1»1Õ^Jd `á � x¥É@�¦)–M@âb+(Áß„¥ Èæœf°.Â!8 9P %ÚáLA àN8¬Acfp $g…ðœó †/õúÙ�xéàÁŒ†.‘€ .‚@(í…Cc 43 ²m¦ò!è3%-Q[1Á¯ôåÖä T” É1N(É.‰RÊsƒDHáÁ]~`½ÆÃRÚ(”t ”Ù` 1‘JxºåBÿ„.!ŽXÁFYp?TØè, ƒÀ`†|@‰làsþˆB+pAŸºD¿R¸NÛMÌ4g¸@Èx‡  (¾8à4ÀCRƒVÒ€mþCPepI¸Z$\¼B9(5:$\\ŠEÔÌBÈõøˆZ¦ €÷ÄÃå4@]J/€ÏiÀ³¤`��VÕ„§´'i5‚€ð1à 7§ßˆ/¨„#z¬=>0EePð C&°ÀV‚2Ù Õèˆ ÄžšƒŽ8�Öc@H©ðàˆ *Bœ@„˜$Qù /ƒá Ž˜¡­è€H +2t_àO<*ÃÈÕ †XSŠñ1(‡Ä<“yš…\þ•øÐÆ‚ø¢ "!ÎàÈÀð�0¸€¨±öº ˜á4©U¤ ìÁƒ¬‚d'Œ[Œ«"Ô”°„ËQ…EÀåR7§!B"tGŒg!å0î¥Ä� HÓjHB„ÛÄÀ+Øò¾i tr¢_`Á`­æc'zî�\VòAü…x H|§…ƒûÆIü¡šBb@)žÁìäš| „"0âR)²Ú,Ñ?%è èk8Ç Ñk±OgXÐ�Œ  #ÁGegˆÁ5Ì“ 2äˆB±À« }ÜAͲ™;އ"‚˜�1| þ.í9›â‘Ì`dÞ§5º "shH´h±8“¯– ÁB†  d•P°ÌbpRš'+à->æR�·C€l=€‚, ˜å�Ç"@¤`¡8¸Tblôƒòm¹œ2jˆ dM2pE#pú…æ¢Êá0Õ‰B‹Ù°fªÉ‰QtŽä 9€@ ÈØ*…˜€ÈcDÚ" "¬ët{ÑG| …ý}˜ÐJuÒð ̵•ʨ €m4¦á ‚(f€‚ø¨LÁ?ØÁ¬ ƒÇäàY‹ˆð‰ Ñ¡ïa´0è%!»Û‘)3ᆇ5þ¤•\<úT!À …µY&‰=»ÆÞÀG´l¢ 3�Î)XAÅÍ(B0I&€ì+äÞ:”Þ!ÀVeüE§ÂŸÍ4ªÌàÄK}È‘ÅàÑWlPÀG qH`�Œ$ñ¸K±y‚ãÚÅI†ÔÉšàd&‚að׃ ÐÇ~ùõ7gdsT ùY ?_@+@#0Ñi%{F€–(o"{! †„:Ý€ÑeO¨´:eàDZp)ˆSH7…°i€÷c#± ¬†2Æu_X`HYe Yå/~‘±4Q&`*R5a�ÊP þ!¢·¦"0à1 c1.§ÐÂdÐW HM#Ð&8ñ+03°–Se0*Ê‘¸2½!“u(cAÓ_¨S`FÃc $%µÝ©1_Yþò{ôµþb#. .�rüÁÊ@ °­2Vƒq:$?Ö=8° ´ÂàƒÈ[&hE *2.Ð�Ô ~A$+”¯¥#‰lBsS0a2Iç)ÜUÀ³d,Ð0\q;ð+ã´_THUC!f°�KT z!;`&!`Cb�pþV„à�/ãúR*ˆ f& ѼÐWÄ‹Œ€²…%ðwaJà 8!6 D.(SiSFáHôZØà ¬1ªe(€?­Ô\^ eÀ[�c„²ME@ �D²ÃZ¹À'Ñ*ã7< !.ˆ³æCRN´0.h4,pMüQSP>`¡¿°‹‡\Ã,hEüÐéjØW")²ân\ˆeP¸GôŽ1ÁEXbÕLkâºôpÑ~6 T%PN+awþ’TIF5f B<@‚²2H£Ò‰¹›Ø>M ­Fs6ªa&þpO-‡ gClh#DÑV K!&�’Q(Ã`ï—7a £`F…P:D±²A µTãªb&Õ O1 ^°½°k‡e  KSm`p ‰òÉpƒt 3GsASCR„» \B0>“T_°+1aMI`'àÑAs!½±�„<3P$PL:‘É ˆ f/À 3Ð>ç�bT1*#i0`/|+á8`1RPJVxÀÄ.Àƒi¤A”eà/1fC‰3)àÓ%³WÅÐ~¯`q'°à0�Ç`*ªÉsëàÿ#LViÒu{å‘S’þ(•AGlVp6¿`ÊH|!\Œ§ 52¡¦Àa"BÊ" °ï@rÆÀÀÀ”\ÇÐ÷2Ђ à� Ð"]Ò§e0¡ ¸¨(<¤X/êEáòó@5»¹ "u ÂŒ£p *p~1`Bæ `@ábàšÆ 8€L¡:¸1Hta1ñÑ…Â…˜S ˆp+0 ½b 55±u„â6oóZ Ô%ö„¸0.[R <¨€^É2-=”šŽà¥4Á�ô™R WvÇ) *~GJ5$Æ $€F p_H¤¥Âr5²í²gDb±¢%€&!æþ{ ³ø€ á'‘eûÐAÜ¡Bh€w@jo8§d›`«ÐŒŽ5NŠB'7ˆ¦ã !' ÂP” ;€D@&¢¥°VÉŽ§ÓÃ@5Þz !u}y/¹J#  !§10Xlq?Â0&²CV³(ù /7ö¤,(@b`0fàá@Ùe­ P *PY>C�sQPXA@Ú$@@#Ðb:®ö!g;jæW­JH½q]JÒ ¥þÀD ÑP8@ã Ôе)…-„�Bà²õJá) 4Ãàtàˆ2¢dŠ— Ì¢×þ„i`@=„2T\Âu—RCS]ò šÐ�r)2�<‘;ñ7àþr.ã° &åS JDpl¢$nߨpë`J§7Fª£:D»b“ƒ+(+.¼°DYD|úBfto8j “ xC_”Fbj5¸/ "Q6ÿã‹`ŠeÐ, �aО@±L$P\fà�Ö#gÈÀ5BXY ‚�eàíÃ�¼WD WP (Lj󺨶iÅè‘_PxƒØGžÊ*öÓAdÀV¢T?q°6d}ëzwk�—ÅÐN#í“TÂy£ 0™b P�þ0!' ^S‡hõ(2°ŒL³;¦¶–<AH¹‰\ê_6™EÕP?pY >ðgÐ\ôu:+[á²dµ£TùÀB#:Ñqø³‰‘p‡ÌèCÿrwé ÐNJÕœ$É{Z΂&*ð7JÁŽ´@ ðeð~ *4É4l1W`à�(ÀŽqJOaL6bš/Qa€.`á@Ÿê åã@QÐ 9ƒ¤5(ã)’VÒ�`ÀŽ¢¨ø Á ŠI>˜+ï•_à 6Ì�åpøå�fr/ÄW QZÐ  ¤ÊÈy"þ9ÂÀµ¨Ð ,!2ðFq8b ¥a!"á°4T€LzñH\0bà�ëc)ÖªdÀ[h¡Öê@¦€JjEVr@À�`€�ŠYæè�¯¸¾ñ°3ë ¤¨r•ŽàWÔÀ2kH0ÉJv÷d»!¶[ÀJa¦B¢’$a²á-Ãó]tÆ 1ðf·#™3,Ы X`J±Ž®#v(Á:z1 pR˜¬ é…ôi°zx2åà#ÇУË]kD,¬€&¼à¿ú©fôrªþR‰„`Ô,g­¦£ 0&`& Ö9 °™Õ“?pˆ|Î<`�3þÍ X¤ T0êKIv$à€±² à eP ð OàÑ>{…­d46L²1.0�·õ $% fÒœºëJsÌfð~uÍp’T}'¢•e\S²K± S÷ŒA78m�ѯ2@ Ìh'Ú€ë5d¡`",6’ê`¨¬°�h8À4^ðn  Â�gR:ü@Ü5/kp22�AJµ’‘ ¹à/‘â ~›ð ååPÜb!¸Pw‚ȳ¨7,xÓ 0°§ <ä[2Š<BöEÄ{€<<±“Å‚êA.À$Pg”– þÿ³a­’:úb•í! ‡ %Ÿr–ûƒ üØW“À €Fè ÔÝÝxq0íí©)…‹AÔ9ÈÀ·JeJ’Îbc9Š`p)û öp_%Ð.¹Ó�ãG¡k q@™; èúò�®rNB@èDÁ�È5ß<¨¦¤ƒô#DS\Cr6§)%  ­d~(�¼ÕjÐ*«ƒÀÃvá ‰3 ‘²+`“ðÖw€0ð�:‰úüyv·x²¥›[§ýÕ�T±x St±9!T`10 Uœ¦dÀ“߸H¼¸·Ñ’l±u˜S#L ÔxÓÜW¹t_oâþ#Y¾ñRÀ/p9u^5‘N1C ~Ê.}#ÜÕ fâp�ÇH£K*%’ àÓ%~,°aDݰŒ+aÔ¯`1OÍ„°†à¥¡k�<Ÿ[ è…>‚ásÂ~‚1Ð'.ÂmTËbÀ�ý¹[E(ÀJ6D¡sÊ0Ȭ¤± ~ñèb—&gR 2€�º¹®Pip$þÒCš|R¯4 '¢r@$ƒw&±&!R'Ñ<Î1�€ZÁ)–Æg#ÙÙi౯ Z� ³ï5»À3rí#øS—+p�Å1ç°†‰‚��˾ªš†ì»þAKVJ:!˜‘ë¶Ý†`4ß…À¨P€ÛÅr*2 À ÂtÒPuøŽ\^ bņà ¢ Š$e� °`²ÿ dßH5¾)žJÚïY¾wg%`i\Ñ>¦h² 2iVh±!f0ááI ÄÐ~’›ºù9ˆju¶uöУ¦ÃŒ<cKàŒ‹"E Ð…�%2IC<<6<C‡T363,.8<3%$*2%%‚%(&0..66B;3.¦f6.,±,R;ª1‘3+,$$#).&’e(0Ê%f!Êk&&6!Ô22062<8(e88S?þ2 80,2@<(2( &¯0Ü.‘0<5Üä33pÈCŽ <„ü°A Œ+bx1 Œ€È‚ÃÅ+I:F™aabn2@x ±bV‰ûj0üBÒ¾%X<À²nÆ—1XxapP‰$\|Ðp¦C ƒ@`”²Ñm 9Y”�!Í„ 6bx3u`Ö J2Tà0ÑH f\”xŇ ’¶‘ÛfJF p;.æà1éÇŽÄ,`¨–„X’ä¡l/aUWçp†Š­dÄ%CÙ–‡,<d0A¡/2_¨"HÐKŒ2.<‘Ð@âÓ%rSÒc–œ‚±þñe  6Œ"õ‹³ iê!BÑ\‘0 êq6 ÃA_¹ŒÃÁ¶ƒ8lLQ„E:v(−˜n$„Ä Q%àPz&|à÷ä0ÌsxáQ(8J a�A $,°Ã,0¤Ž HŠ4gtEÍfððÉ76Q„,¤Ð‹ ±à™ ˜¬“A‚S™:(xt•E H…‚Cl!b g2x‹E퀃Ãä $3ì`¦.8€ÁÀ.blT?P¡Š:9ÙPBYÂÆ$5¢Q #UÊ�ùP•ñ¥bÃht#*<h PåV©À0Âþê¬àMÝ€ Aƒl@Ìhé‚&ÜqC ÌÕd1{Á`@ò¬H *ƒgìà%"3ñ _à Æ Rø  "êxƒC !B|³Î$ÛÜ)Ã.$�à„p'ªP$W•ž­x`x¤Ž õ¬aÊIíDEÈ€S¤ò’ #”Pp ’éJ&€ÑÑ7 "U–,@hŠMR: CÉ@>Š„QC2¤ÛA ”ÐÍ ùÅ÷ˆʰXcô± SHX**p•@'œ©IN8Û4 Í!ž9pÐ= dI…˜%¥kɘ� 6èÀ"<|Cë¢ð Â( Á2þ1Ynr×TÀðA;¦¨¬²G $°ÖBʰ üèÅÉÅ3\¦ «Èß0ü@„:AÉŽƒÊ‘®HØäâ�‚ Bt¸Æ±záð",|°Ff@8з륌.o…9DY–“˜aúX¼ùßnuLY2sÅЯd°Xìƒ „@P‘é•â‚à ¬ñJ8\^)Pɇ3 L’PÅÑ`?qÅJì@¢ À6ÆW¬òDB†00@•’6ð%¾$•}PÅ™�  !·„�$“ú1ÀÍ� 1E �,D ûÈ` ‹ã!ë¨ P4þÐ¥h@F'è0S¤aI<ˆeêÑ b¸àN Š È•Ø`¬`ÐE\´"º›Åyƒ ì ‡Ùµ:4Ñ.|Ð_¶%œ„W¹ _Ør„F<Ý!A4� í8t ‰dc,pŽ Ä`ˆÁ�‘RFÓÊÀƈÈEâ³ÁcŠ ‘WÈ,|B„_â¿D)+!ŠÊ E¾ðpØ�7ù ™p†GÜBHÄt@SðP9@‰A $W<Ðô8ƒ‚NÌ!÷8Ö>nU,‡݈EÒ�¨TÂ#À�X0DÌ` WQA2?ÄþÀI&О$4i8Ù`9,PP \° Ä'M˼Ë#T±ÅG•À Q&á°-B�ˆ v0{´í8WöñàFœwQF…TÀLìU ƒÊ‚)Mp$beè$„ ‘ïÙ@w%¸À̆®b ®ƒÈ<ó—ŽË�Ë öt$.Ÿ&só/1€‡–ìÆ,²…t„,˜Â@„"\D”ä9À X‘BõT zÄ#乓=û’èî/%“KÄÔ!ØE¥h (1Jl¡­$õ1’°E#&HO·%d½B:ÀA¿&@ dþu±§8ÛèA!õŸ#H– $Á’¨ò¨%à)$/ˆášu€ æi|BDi„äa‘&iÖZĹȲf° |ŒÂ. PÉÔ P`‚93"H ç<€€_¦×0Ì ›áUÐ<ö¬#Eà(…]îd N˜ÔJŠ bàü€.\&¼ðˆŽØ@{XÉ]âó€ü@n‰ÁR)Pt@© ÄW´U¡¶~ƒ9@£)WAŽbp+“:Ü¢Œ€.XΑŒ;Iå!XÎ�á~(ÀBß@Á  W†¬XRnµg3<`NB¼R ’%-À þ@IQ¼°�'?±8çÐfA !ˆ¡#“ÂA(\ÀQÁ–dÿ{ì±P°:.íEÁ4!×:²7t 9@A: )z^*ð.  çb¨%™¥Øem‚ØGT¡ˆ4“ÙÔ=SHgãHz¤‰ç9Ge*¨Áҫ€ ÌU‰ ÜƒŽ A讀Á_@ð•BAè¤p´–ô [² Ü€@ÚăX•!‡…"En¢BWòj°ÝˆÇø8“LC¸N× ,ÍX" &ä+×0³VHÒK܈A > ob4©B8rÅŽ” )ÅòL™ìpCH8@' ÄA„@uÐþªÖ_²¬àJ<üÄx ù„íðFÞqoÍ­%‡*²”™U‘€,  <@yµÂ"Q\ˆŠ ’ˆ¶ô|e—õÉ´pàSL!Æ7€ ™æ‘¼�?\ º*áìoÉ‚ö¤E…âQÌd˜odìk¥zü§ÏÁ/=6/Ä…-FÅ„ð&Ûi’’  \•qÙáA"••¨?£¥&ÚàДK—ò.¾-!l=)|Oº)\p@(LàB¦ˆ’ÍÇÃs€ <¡!KÇ6.ÝWôÃ.$³çE<Á\ƒ¢ŠåÓ{4‰Ô=âÉ6Àˆ]†fû!P û³þ¥@ÀPM£&&à Cfa¦Êpz(‚âå…f‘„¨E¸¤à/ÀAŠ„Z„0C,qæ‘„XÈÒfaø  ÍC(­:UX1�waí°`|ó`à�` j¢iÓ´+  f b¢ìhQaGoaýÀ�i@eº³�ù­  Ñý ÊðRä°sá îä  ç/Bñ�:˜žUSűDÀùC$À� h³C)‚\°k0�éTýó waaBà"}#|¸• ¹@²g_r8ÑTU8 "„þ!%¡ƒ0 =Ó–ƒe?ð8 'ù³RobJ”#(«s,ð«CY.‘"qÁ#Ð-PºÓqê =® Z³ ?Ð/ @(ñ�ÿ,kÀãö=;¦îPSÔ’NÁR‘`'¸Ä ¡£h{I çÑSä ñB è*ì-ptTñGÑr:ÃÑT®£,é VÅ0 Iah°™2'+p$°‘4ÞGtù·ƒ+P#¸å5 VK´qA‰òˆ²p@ô À|AIv9¡nE. !h§qñ‘,1qa+¥9È€_À�w—f®ã‚¢"g6-þbB@‰è0±<0X`Tªà(¼@gPeà Lh=ÑSpA?p ApD>ÀJLôy¡8;Ðe_À_M .£àw„3Kíp ‡Ið�RQ¹tý7 p»—QT1bc%xÄsÖô=pÂ5ÐB X?ÓM÷p%ù04ñÛ³ܘÛsB¦D#ðÄ�UäO†&Ä ©ÐEØ¢Dç –ä5¢ ~Ñ Ù7 V-Cð©&WƒÕEc49Ef�[`˜GWtõ€'ê° í„¡"&u›®0'õ7-–$ B¡ r2gL?°›±rþ|Á2 àa<TÀ_$ yqB#AHØÒ 6óaD À7µ<"3C Bç1`!–�^ Jq8†D‰ ÀMÓ›˜J¤Ð\ ©�—%SEbf🮀"‰rl±: ’E:à…Sf‡"çÄ2ѯ DÐL‹±‡‡2š¥VF´ð¹$ãCÀ!–j9 ž˜‡vÐ$ ¹ù³(*ƒï$˜G%SKªR¦0H•a‘ðX0aA0W߀V•C«¸sÇ('‰[8PXÌ1 0Ñññ N¢ jø+(}ëpþ�d�!°BG? †å³ˆ)â`‹ÀF0 ''9À†^Ù£µ"k@û·`@|äÐ�>±` “ó†ÉÀ¦ê`§Û¢ ¹ñJ­ƒfj§ÍDƒ¨x1e�›Èª8°�®€3pº°Ÿ!Ú"{Åñr1" /ª@R`‚q¡Ê€QÅÈ ýPbC0vþ9Àž±­ƒ¡4B VU`‚¨"X�û·—à`�õ Ü‘¡G¤ ¸¥I±p©XÀŽà§§/È5. 5›±2ë㱞 )tÁäk÷ æ`q' †if­p:“þ‚ã Qˆe@ =0è�BbMG ŒP[�L0‡…4¯€"‚xOÈ&U8°HŠr`‚ Q`Ó{3PKã¶Z©ð `U‘Pˆ)¢„D¤”Ýð¸ð�±?fp�…Ù>ðd!%9‘«å�MÞ`-‰0{±ä'çV$u×*NwU|#”ÀC 1 G[`QR&ð³‡)µ‡Ñ3Cr"«„,0 1ý3 ^#(;: PIÆ%«²ŒÃ_–” gF™_0:@9fÐ"´ðQš'tD1€ Ž0k< 'DA9)²,“p ™Ë…þ “£ç^G Z£ç‰yÁÒE:ðnÍô�5Õwt'9ŠD°Y¢ `N¥1 !’yOûGrr8Zsq:‰ÀraÐ3aqã FKýM0@/°ûWœƒÂ JhBd»f¸Ê]ÐPjœº "ó­°E€y¶ç�â”A80‡ª˜÷; Ó / A.@C$>‘”„ô» �=A-jGxq «V¶öðRÐ I+ ŸVÀ;¹D¡,ÁMB0 øñ¸p;€Γ¡-1 HÁˆädP‘/]¼šßs]5þFˆ BãùÁ€fDDz à7'“xD-CF ¨ º#Mø$>Øâ%¦ª;¶„½ÀYVE]�ÆçD ò•5WKG´/àˆPÂD¯7ƒ"M6 ñ×K‘¨F€†nÜ©ß@ImÁÆì19ƒ�vfJ²ê¢“SXm$-ÙL÷°Zõp' -C“¹<🃄 äà?Ý`\ûH©@9ÅayB1$`ä@‘cÙ…EùŸò°‡“¦� *sdŽÑs§S³ ‹jMê¶q†ð™6’“á%Ê¢ÌCSÌç_°�/‡-H¸j•²Ú‘„ 0ð²ÑþÕÔ�íÚ ¸õwq¡ ÿ øðM‡�eÐ6Á 0Pq"ÄX@D`lô ¯ ñ�”óŸÅ?FlÙŒ�çáa%þ0”ÿ,ø°D 0‡#)Òðá¢&Di0µ©@/BhOw‘Øi/t™Ê¢ Æ 6@¥‡ ³@ÛCY´à¦óe€öbÁŠd‚D°SY†q¯ª64<!ÒòðNÜ!wI'4VÃbă£Yu½Z[C2{æÇÕ|D¸¥ »éØŽqBä›aâ>ŠÜÆzÙ»£œ² ƒÊ  €°+S³!dв5ä@H¸uœ ¡ IëRdŠ—w[þ¯�òq¡ `MÈ.ªÏ-•&´ ± I÷ ÔjcÚymU>«2²iŸtÁè<.Ybª}ê¼P²Ð”2:ã6ÌoGâáÍA]Ï‘¸P o‚b!'.€�_€�“*d:b $áYu¨Â`€¸b4U9o"8<°f¦¡"M¾^ä—ÄØªþu,}£Qâq³-C“AŒñ�,éq%ÙÜ� °:ÔP)†Ë§Ñ"ªI˜×p º0s%‘ ˜‘q¹õ�/‰í0<`Wƒ$™}RSmbtç<½ „sN¶4Xªº‘%+�$‘Fþkó'„�ŸÃw}¼ „tRLiBÑ$ Œ=4 ×óRéðR3‰e¦:'L:@Q½pYçqBÉ èa�ªPMPñ&-éCí±¨²§—öäÓ;@ÿamD,ŠfUbn0à—Ý“LõP }±@±@¦£ÚCùÂmõPÒ&Dg0צnÒ¶º�T 'êàAbi•Ï)‚wÒ~`AƒP®šPDPqâu'¿&…¬ ƺŠrUídTa|xVs(Šo»¾"PBÌ—&µ&Í”±=Mj’ôU¦ÐÒ’ðr¼ª %®ð8`-utfñ‘X64�¡Îòþ²n¢’¶7ÂÔb-ˆ…è^"µðne¢ ¦.};à(^D“"¸ÒN7.-Ù"Ì&˜/šË|ý³ŠÁ<o´w‘:´Þ é”}¿^kÍ4’ÜM*H& sO‰‹1D 0–VððŸ, +^Ų“á:t¸+‘C&º3À¿ æXÆØ‚X£&ªƒ\Ó?b°õT3ÁmÄê æÍv¯�cÛ/Ù— `ê·îEB@Ö=Øe¯Ã‡‘´2€�,�ME@IÔJuM<ðKz9—I¨é£(Zñ.±4èaŠ? ‰MII™«ÅB2wZM5…fÅKùþ™’¹v“(™Â*h\z„A °fN©�Mûô¶Y…Ôj¾CïceZÂ-†è’dš5bÞYшÑwÊSHŽ0'D 'g†EÞÉ‘hÜÕdO±ä�ŒÖS÷Š=…H(Q~ °€ð5c‚bãâb"Ã##†#£Ã²Râ"è‚é3eÃ#ƒƒóc)¤5Áãb#fƒÆÃƒÃðe3::KÄS#++” ¶è „cƒ;ª£3c#½ðµCj3´sõƒC,‹Ãƒ+6û#þÈðêc£’;Ú0›‹EþmcÂÂÒߊP ¸p4î8ˆÊ ŠábÙ2"?¼þfA4²à™‘H83.JñHVD1ó`�;ä² 3+Ç ¡Â‚åj6ŠüQ˜Ìf|iðËŒ m0�Çì ÀˆÑ·.V¨Q¢¡`e‘¿ÿl @±Ť2%5BaÀ„‰/¯†î˜±2› k³J€´€E6PBRa¶¨È«_\"è+¶+dÍYÒd= §NÈTðê'C)H\.y$øæ"}3_©XÄGƒw±$Ù“¤vé«M¸`á¥_[qD„aâÇd[18V4S²Ž³(ÃÂ"Zf-t‰™Çd§!Ã(39"Ž5 ›ÝÄþ93³ÌÌ ÒÎPI"Z…rRàPñLà„‚›K‘ŒC-å6ÉAaÉeÜP਀‚YUÉ Ì0¬Îþ�4üÕPê|ÁÂ&¬1J’Ø 88°…î�ƒ’z?t·QBó”2ƒ>`°"NX$±23Äð á"ŒW1€‚^àDwK,â`À(`8" f°6ÉBfÈ jÍ¢W($Jš6™ >®à" BÈ(„¥`ãB,½4PÌ“0L+㸒ÎJ;Ef´èÂK¡Ø ”4,$46Ûù¦e–ré°ÃTüà‚‘ 7›Ä §ÃµÏþo?,ð c�qÆ t8½€Á é036ތ⣬Á€$5L¢Š (ÀòÍ‘22`Æh3tCÙåâM”,|v’s‚Í^)ZÜ¥ƒ‹ë‚€ %U Q+ –¹œúM"X­…Vî„….ø†ÃÒP jÁÚK2 ò‹$Eà0ƒDÉ@JT 3[# Á²ˆ(<|FS2§à0Z.ŠzÓåc³˜@†¡8¬ ÏÇeë(‹%â‚…àR‚±±@&Í8 9ÆÉ5é+4ƒ‰Íf7±18°à5k.ˆÑÕAÊ‚óVã�ó�.J$u“ËD#M9‹$s¨Œ²¼2!Ì‚þà<¤„%4k­Ò8ܵÍ(ˆŒCš‘Ä)ñÁm!2Ãå<¬9™(õãw>ãX(ƒY7çˆy—ÂS"c®HÿÌ öoÜV$Ô,¼¢Q<ˆM1ͼRC/Éäcƒ ê„CŽ=¿ŠÅê-CÓO£”v¤XðXN‹.0 $Ü èýæ7tŽH|óÝâ @2 QìæÌ#‡X CÂÈÕX0©L6¬àOŒ°±€?E¬'0óêUƒq Av©‚„É@ ÛšÁ°p¨½5`eØ`À•,åi€Ákb Âð6¹Œâ*a3‚»u4ÀNë˜D>˜#ƒ´„nþ ƒÁp6ñD|ld‡0X V°!‚„_Ì ŠR †ÆÑÂGÎqÉ‰Ä aLb,I™$ÀPßȈ4Þ ‰ óíüùÃqCdà�”Dl& ûŠ|hÒC¸•Á8§‚Á�ve3ðIúÚ›2ö&<‚j ‘ s qœ€Çf%Ó „$µY$ ËÅX§f¼âZÍ‘Äõ"†éBQD™ÌINÁƒåB ôY†œ"ýL˵[€$NÆ�<fÏ9 ,>†Ìï ˆ8H$Àa!¥D,g9HRÃ;•ó,oYx¨¦ÙP35:SO”ŽCM D",âXFä„äÌô¢zþ¿�Ò# U îOp¬Á(A—BJQ>ÊÔ(0œK¬ÁBòÉM"&‰�LÜ"»Ó¤TP(b4À áúÆÁÂb¹hhˆh˳ @:eà×7@÷ˆº_zœvà…´ ÉPÆ+Š0 $!(‚W‹p Ë T0Pek„× Vä‘X8@”]+ÅO¡c‡œK·ÉL¨$543¼"IÞÌR‚6 ,8Â�p@VÔ'¨–!®D‚.̳Ðfõ¢YDÆX�R Ã!䀫èT  #WXŠO9 ”‚;b é,\à…@š‚ÃHÂ!2‘é\†sÀœì”EæÒïŽ„Ž H’X¯‘S°áÊ£/OD’E‚¡KÌÃÇ@ˆH=Fa�gš$„p #Üaõ’`=õâ·-ªëf°Ш÷C–@1 /¬ <0�éƒdA«ú¡àhˆk ®" µ|ƒ¯³9"š¨©’�;�������������������������������������������./saods9/blt3.0.1/demos/images/mini-book2.gif�������������������������������������������������������0000644�0001750�0001750�00000000135�11462120062�017246� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ñ��¿¿¿���ÿÿÿ,�������6¦»!“ŠòÁÆmöYièQŽxjŽù‘k¨~‹º3«/ž!ÚÍX9D`C8A0 Ê¥¡��;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/qv100.t.gif����������������������������������������������������������0000644�0001750�0001750�00000005206�11462120062�016415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aD�&�÷��ÿÿÿ÷÷÷ïïïçççÞÞÞÖÖÖ¥¥¥”””„„„{{{sssZZZJJJBBB999111)))!!!çÞÞÞÖÖÖÎÎÆ½½­¥¥œ””Œ„„skkƵµRJJïÖÖµœœ911­””1)))!!!­{{¥sssJJZ99Þ„„R11)ŒJJZ!!kZB��9��)��!��½cZ­RJŒ91c�çcRŒZRœcZ„JB{B9½RBR)!÷{cB÷­œÎ„sïsZέ¥Ö”„÷{Z1ÿŒkÆZ9Þ”{ï„cÞ{ZÞsRÎkJc1!„ZJ„B)s1ŒcRÿœs”ZBŒ{sÿÆ­J91ÿ¥{R1!!Æ”{ÿ½”{cR1)!÷çÎ1!Þ¥1)!ç¥Î¥)Þµ!Ö­Æœ�ÿ÷ÎskBµœ)ïç­Æµ1ε�ÿ÷µRRJJJBBB999111)ïï½199B!BRÎÞµJs1�ZŒ9Bc1k{ckœZZ”J„­{{­sÞ÷ÞŒµŒÆÖÎ!1)cŒ{ÎïçÖÞÞŒ””Zcc!!)ZcŒ¥1RZ)k{)cs!sŒ)Rcs„Œ1BJÖïÿŒµÎ{”¥)Z{½Þ÷œ½Ö9c„¥Î­9BJ!9­½ÎBJR)19ŒµÞ)B!sƵ½Æ”œ¥s{„19BJRc�!k�!{÷÷ÿÖÖÞÎÎÖµµ½½½Æ¥¥­œœ¥””œŒŒ”„„Œss{{{„kksÖÖçcck½½ÎRRZZZcJJRBBJ{{Œkk{99B119ÞÖçÎÆÖ”Œœÿ÷ÿ÷ï÷ïçïÞÖÞÖÎÖÎÆÎ½µ½Æ½Æµ­µ­¥­„{„sksRJRçÎç„s„÷çïÖÆÎ½­µZJRsRcƵ½„s{!祽œ„Œ¥Œ”ÿÆÖÿ¥½Æ¥­Þœ­ÿµÆ÷Œ¥Þµ½µŒ”ŒcksJR½k{¥Rcï½ÆçŒœÆcs÷­µ­ckÎs{������������������,����D�&��þ�H° Áƒ*\Ȱ¡Ã‡#JœàY‹(ð ¶^¿zõÒåà#¯^wíJ°‹—.] TÛÕ˶.uaË¥ëšO]ÛèJ´Z­[̘ÝÚ5,BixåšÊ,×kIJٲUÍšWkО [¡›4¯]«Ù²f 1^Ö¶Ú¢e­Ö4i¤á’“ 3€%PppÐÚƒaÛx)^Ìì…kHvì)SÙÛlØæc˜ÕZ¦¬Wâ]Ì~5Vyš·Å5p+Á} 6"ÑkÖ2iË¢E“&-›>\˜™cv@.¸(a€ÙsÀÐ(à ŽWqþ@»nÀVù ^¾ÌåÀ΃%z5C¨K€fÍbáß/¿þùûÍÇ0ÀàŒ0¿ü¢K4ÎÜ7ß@ÿÝ÷Ì/p`/ÕT@�4@0ú(Ü2$’ ‰²Wâo%ÐÈ/<@Ì1ÃãK-ЬH"0Ë@3 ¡8€A�@À¡@0 /ÀHC ).Ã#WS‹–Z>£26À�1¶Ì"ËŽQc,Í0£ 3¬äA6MãL,ÓdH 5ÒdÈ „�›5ÓPSK-{î)¥¢Ò˜E\£R^Í,Ò$Ù¥—6P¹dcÇšÙ7Ï8c 5FI#Ü4ÌL lþ (“q‡$Êç£ÒPšk”^ðè- Ó� 4�[± SB¶Dð�¢ dÎ3Ê|ÍXҰꪼ8pL±Äƒ¬¸à{ì°È6 .˜8°@0çjF ô2à,ˆÕ"Ö\D£2µ0cËŽ8Ð-H ð¸Úð®N qÄŒ#—4F¬¹Æ>P/ÎfCA¤Ê’A5ÌJ 3ÂØB °ÒÀ0K@ÔÍ8ç,ñœöÒû 2°-Y@ÀJ{ÃŒ<5Ï,cËI , Ì7¿Üò²0Â0à� Ñ‚Ê)™DJ,±,9>,2ìÂÀ0ÐáîÐTœ ÄD@þÓÑ`Í.)ð -V;òK0`&s� ‰'§À�ªÄÍÙ‚¬„´À³ #,híÁ1TÍ�zU“g†yâòr#bF q´�4€"FJSÀ!p� BMLÅÈÄh¬d ]º¨us¾·2Ë0“!-Ӽދ«¿8À€#· ÌÍh$F�XA]\°À5åt `À]´f˜ mlòíê½´2+K‹5èbíI@ ÆÄìS8 a~È�ä Œlăú �5Ú6 D`uƒ�þò‡©ÔáYþH5�¨ Y£+tù“²!,‰%ƒjHC A>�àþs Rà… ´#hK†#ìd4Oh—â_ÑŽ‘Âô0e_qá-$–.P n¸ƒ" ‡=�`zÐC¸ 0!ŒÀ Њå‘P2È8aŒPE°°*‹_¹Eô¦@‰a0 8ØB(‡<èp9îqzÔƒIü àDL‰îRíŠQÿTZàâ+¨\Å(�¦9LŒ+ØAœpƒ? ˆ@€<Ôu¨ãèà ñ"À®v…Ž„@å(2hP㔨ôŠ )@ d£a·IœPƒ/˜@YàÂ1„àpl�0G>:„í1Ét@¤ˆ:‚P#ÀþÐÀ-öy ìLÓXy£À#ô¡…)�a 9ÈÂ;¬0GD B … š1„tPF›,á1©Ìv£¹À2Vf«D1£a�€âôá.Ü óž…ièÃ10‡|p�\”hïÐŽùIQzK0€½j`/{·pÄ`¸µÛÀâœ`@”€È�C¡€9Ð Ta~ÉèXŒB`‡OEo¨¡‹Є‘: GÖ{]W¬ÁŒPÀ‰šI(ð4c\â›8lœŠQ Vl"Â(F(Ð&bÔ“˜…$ðèIN*ðq˜¡××E•!� ¶J} VŽ€þÀ#&�GŒ@0ƒ¬«ðÂ@B &Z‰R´‚“—õ^#¨1gP£z.ÌSo „aË®0†1ŒR`2Ùߊ%Ê@–€%&ÁÞÍÖbj@A¨Ñ[dkvÉ.ªJP1v1¼`…1DB·„ÞáE1@ù€”â˜�M.%¨Ëã(È4fa Üâ9ý¤Mu/#˜Xmj3±Š‘Å€Ì!¾sè(2BÀÖ G1z BF, ¢ hÈb-ÖÈ�›5c^HN2½ŽìšM"ù“áhžÏ¢ÍÁ ·J ì@‡.w¹«dÀ1ò8Tþ…@®D­Ãr„üÞ¸^*¬eXœ#s „ ÈYXIÐâbm&]€V ÉE.p= HaDUp‘‹çТ³¨3E °€@�R{Q6ÆÄ€l # F0¢&ê #j ÐÀÊq€làÕâ@�®‘�”CCɵ®�;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/txtrflag.gif���������������������������������������������������������0000644�0001750�0001750�00000041357�11462120062�017146� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a �x�ö��ÿ�ÿRƵ½ÿÞ­ÿ½¥)�œÿç”ÿçŒÿ½Œï½ŒÿŒŒZ9„ÿç{÷µ{Þœ{÷„{ÿ{{ÞB{ŒsÿcsÞ1sÿçk÷ÞkÿÆk�½kçµkï­k­”k÷{kçZkÆ1k”1k{kÞœc÷Zc¥9c”1c­)cœ)cÞZZ½)Zœ)Z½!ZÿÞRç”RÎŒR¥ŒR­{Rc9RÞ1R÷ÖJïÎJÖ½JÆ{JscJïJJÖJJ„9JZ9Jœ!J­„B”{B¥sB„kB”cBscB¥BBR9B„!B{Z9kR9{99R99k19R19÷Î1­„1¥k1ÖB1ç½)Ö„)½„)”s)„k)”Z)¥R)sR)Þ))Æ))ε!¥Œ!¥c!½Z!cB!J9!k)!J)!œ!!”s{Z¥R”R„J9)½”)½­”¥Z”ZœBcBÿÿ�¥{�”{�{Z�{B�Z�9�ÿ��œ��„�������������������,���� �x��þ€x‚ƒyl\Pe7xyy‹uŒQ,5QP5‚j˜e-->>PxjxuXx/z!«!ltnon,lhKmkk\otd\\nKOYK3¾\+q[KYLkZYÂY++O3[cgv=H> )**11WçW71#*)&#Xç7ô7(ø$õ8N'<,¡Â„‰„t¨ƒTž:u…pò‹‹ FyôÔ Ó„E“-‘Lad„‡E *-Þ´`±èâF=vj€BŇ..t̸‘ñdΜ'M̘aæÍ7Qž<YÊ6V´ÉbA‹-bhÀ¡1cÅ…4hˆ9ãÅH/T¾ìØá!:zþWbPH±ƒ.‘1n\qBÂ=xHì‡ãž<|X8BB!"p4 ó(7l Ü c âC;yâ`fA‡‰¨E#ëÔ(SfK In¬ÓŽ;uÜ”áB”M7o¼ˆ™2¥V4Y°>†æÉŠ%2–1K>eÎ0ˆ1¡aÅ‹wïI<AA"E ,anÈ“7Â|])Â8q‚‹ˆ)JP(á—+Xp@Q÷”` c&ä@DBT†uÐñ[¸¡P´‡˜±!ZB(Ò…E4ÔñFul±¨ÇI@´PzÔXÇuxˆFJÍa‡YHhñ†Èe‘År þ³ÄJÍðDWµˆaÝYˆÅxQ]1ÆYcAÄ$P€ TÔwEl¢pŽ 8 GŸ<|…a&=Äð_àà†"DPÂ÷L@:(¡Ä±qA†t€‘†tè±…‡”á Qn˜± «‘AÇ&\Ä1‡t¤J!° Ô@mz€±GÃ(¹dcLáÅ^¼Ñ.V%)Ç\,Á n`(UX`@XPr†u¬ÀÀ 30@Àò�ÆB(øÅžéè•f a`1çÄÐA|á zŒ:Ãóâ�Á "ì ÄI aȵt$SvxgGf˾âuþ˜áh ‡h †[4a¼8!Säá±vÔúp©JòF—Ed!CIf!×É‘ËÁÕú’·ØÑp1PdÖ1\1°ƒ›è¨QîJœû…éÐI›÷î…êˆplb!„äÆ0Á'  ÀI$FÛl`v)ÛAcxÔ€aѯÐÑF æQE%¤±QsÐ"‰E¡¸˜GÊ5jн4KTẔÆE7ÑÄf´Ì0TÒÀ eT±*T-óDçºñÒÆ c„eòÜq…k~‘D`(qFó pµ|ôá@Î ˆ0U8¼B@Ab~Q B"ñEþ¼Ýpvlƒr{àF(ŒcÈ j¸Ñ d´±"-„@Å ¢ˆÒˆ·©Á*€€€VPá2eˆƒë Q´8Ä lx•¨×¢ qKVX¬òø¢9rà� ¦p†Ð V8ê<0ÔáaB'” =zqÂÒ<p¶´ 7ÀAd°@ Pà¢@pp‚ 8€yÀ‚eð@±`Ù Åd¸09ÆÕ4Œ¸$Ñ Ô€!à@K¢‡<˜¡-€£^À… ]† A˜CÄðÄ¡Uª™‘Ö@ƒ ÕÂ+ÈÑÙÖ0†5 A`‰VÐ….œa Løž=þ"ð "#˜‹v€ ðn/W@Á~v`¨�õhÞ b ´> €Ä&‹â¢ÊàÏŒä,x!‡‡ Aa tˆ‚N?—@Ä Q nã á›=è¬0†)Ñ@ޤ( aÌ€J8[Ã’´†ihÁ®ªÁ ¼€²$‚RÁ(O9,ä‡.㠤ǟ¶(!eº„(Q!Ô’‡É˜´¤2Í„@ñ—<Cr#ÂP(ÐÁ5[àðÀP&"_<Âù  ¥ÄA ژ„ô¦<!‘ÈqFÐ(C4x†"³@þ@Á=«B¦Ð”“ûI zøáíYË^n ‚”Àk” ˆç¨sà  '(&©á¡9ØInŠ7TÁ hàBF@C uª tȃÿ"B™6Ô¡ mÊ <ÀÙÜfnU#: L‘Ãì010a 1eA-¾)fA4\Ð�Q¢Àªé©YÐzq9Ѐ  � T0î ~wpW]PŽ„`¡ aÁ9!hO ÒsBŽà.!ž�8Á H†!ä@DÀÃb <¸"(»"\Qœ¸ n8akЂ܂Ìp©:`GÆÐ„þ”á‹z¸Íö`‡/<¥YKЂPÇ�œ8¼a¸Æˆ ’dÁÝŒ FKf ø¢[è¸@ƒ X€*5 %FY,üU† ’á^æ#6SèËy뙑Év.8Ôë€&P°!è J˜qnFª2taR(û‚Z *&DH7ccô(Å~[0ƒTBˆð ´ABö<\…u·]‚ áœüBÐKY‚/ Í¡-Üx ˆÎŠæ(*W ç´€4"taQãr—Ô 6"‹š­X€%„P.ÈP†a˜À¸G"€ÁJЪ•F›¡ ¸\«éV! þ™aŒ# ÖlZW4op@ D!‚’r-Ðà öÀ‚Eº PhÎ2ø¶2Ôá2Ò™ÛfËPh6Ìà8Ò¨ç X�ŠbnƒÎà‚Œa­ç u¾ð×!OÔè›|âÂ.®a!õ™OœÔ1þdO<D�È Žð§WÄí2uKY„(?ÓA4'„®PX¤¬¢,°üPCj5 ¬5p@|P�ÿ· #]Š Ç‚ e€÷²âÆ k GË ¸0‹i¬@ EðBà7 R/WÁ†pOCÔsªÏu¯ ‚d/€jâ æCK\"¤ 8Á¿ò^†úÞþaCjx¦v£X;Üln $[҈ܠ#QhÕ ¨Ð�Ô„‚>yA ó-:n½ÝB ™P-,Uf?Yd 6Da S±¨zh¬Ø5®@‚õ$€á?ñ€ö’€âŸA Ùr ­Ý;PÁ:T@¯Ý�õ)Ðö"<€‰'èÀEZ"Å®ªÞ D@E'¨Q}'E†X@ÏÕ@$Œð ^Ð 4 /`Xð:ÁK€Z�lgð° bð 3 µ h€{2°K!W!%ˆOò p�`ðLJk!·;àÅV¤4wáçÀþõ5%@àwé•=åÑD�/óB�/p! Ìò c”E,R5°ŽC“£b,ÐMÀ§Ñx€Bá]PqD Gõ™UI¾â”Ö!{›n°bܲ$TEk`3€UnÀÍR4âô(Ôa°£´c;€òîpŠA'7p;`ƒ ð;\D"P^‡800æ‚jÀR“µ!³ð>Xäës,Py„PÀ¼…³x°yàM +{ðE72f:×µ0†^à+ÕÁ€Ç±Qp$40ÊbD¡YRcp-†Ð TÀ70r°þ<€iÒÇ*0&DP5èàå¨t‚ÚS Eó!½ /  �8° DˆB@Gð•á4åR9RÀ„h0c™áQ‘*sÐEG1L?5°wCZ”ò50×Ò3>±sðGe!>0LT"ŠV-ÿ5c\ÐA)–S04dÐán¸·\ƒâåp¤æ.X°cAøð'XÀCmDpX@qÂ&õ‚K G�H Cp#G`3F [° `p`ð¢ls“*l l‘`5pc@Rh?v�2‘‡s`¸g–»˜�#å tàŒP�Ãþ#T<b$³°„YlpBNR%^=½PU�A.‚`\a`é°&ùxò±4yq}@Yï(çuaSsw/ "�…Cp›Dà`€!…æ7dP7¤E7ò ¸T@¡Ttà1s@"` €…(3ZuÐ�qAÿÕ!Á€’Q9¯pŒhÀ�‡@!@Po¸7ön+°ÝÆs°¢Â�O›Ù3àuè¾s_� DWòÑ.?‰j10•îÒ.0$§D€9IÐO¿Ãk¾PuC·rYÃå ¼ñÍi7à -tþ mð0là"ƒ uÐð_LÀìÖ ÇæÈñ$OQ9—É KÀž¿À_Ђæ$ï¶ 4°ÛQÝh¼ÒkÀZ4 ;5Ç&G_p_qÚEj{b¢Ø;p6@}U€dЖ´ä®D;S£|8 �N–.%x0¡ºðX`„†EãŒå?y tPÌr,5ñÓ!£¹ˆs¿�`©RS $––1c è ¶À‘q°à Ú8ÏâžbÀT1�ßqä¦D G�j€¤V�Rƒ16E(úAN°Dÿ`Kàl!õX¡þRFãÃ5`«rn\�Eõ•T4Nˆ…ùn’@`,` òS>ðš×œ>Ð�[�’`4= To0¢)¼‘TO' Z0IOÐ SF¢P üôoé�?ò è!Â7(¥éùa %ýÀ@ÄVÌÊ­dLd²°6¾T yà_‡Àhuб!“ªF§zs,àN‹§ñQ«áð!�ŸpTÍ ZÐ0Ä“ÆÁ m O'@3 ƒ¤< Qµ°pYð2AP^@UË¥(ypç°wQ àJ²)®dVÍ5þ؈XPKlÁm1ú}�ŠÕÀ!‡Pnlp …z ‘³&sn> ¨¡LùõB_Pf8ŒÈÑso°F¢Wg$LÀZ ÍQ¥h{SGB …Æn–°Q`S` %ðÚƒ‹j`&lq*€zšÚ“*ÀÎS‰®Ä”á§ 9@6B`64WRx0R”S-Ë”,�M’¥¹…¥¤Q¹o°à P5°g5’uðÐ�Uê@TNc`v€"‰»o¸Nçd-KW-`$s¸ia uÔ @U›É-# V)@® pqøþA%À|kE" | ' (ü"Bt)@J€ƒ)‡’•"3–LÕ²„±_›Rs�s+áˆ#…¼…sM  �9G°IÐuÐ�/° 4¥!™b{€kÐ,ï-©$PÐ…¦’ÐñnwH¾7å¶U ŸÑÂ-3Ð�gâÑÇ4üƒ1ppëþÉiô0Qê1wJÖˆwïu“(:€kô8—"æ–c€!šrf‡Ðo 8ªa¦åq°‘É* à¿3)i x›Z‰å‡`$Èq»KLŽ’A¸{0ÄÕ’^±PER™pì +p�Ý‚eàVþ<©jEj,w/ô CW”ó šN€]œ1W°j" ^b5J�`à~›[-AQæöEÈäRiY4"JF!ÐcPf�—bÐ>Ð i€·"À4¢]`N°­Nq€JQ NÐ1_`8oA³+ÀŒ4€3€@ÝYÂ! ÀSt°=Ô§ì2lò=Gð™õqyr(@(l"GpT"AdkJ �gºK"Íb!zàzPt`+²)²ÀoÀL@M@i€“Ú/ÀTX7c ?@ seä£Ç‰6n=ƒ:ŽY�bNËhÐþ»ÀÏ"{4 2ÀF`ÀÑ+b°Òè°n�<Ss/Î:wõ!CT°;áLõ¡1¤ÍÙ¥w71ðƒÐaÀ/ ­EÃ:9ÀvEc´)Ž% 0WÐM0+-à7/•*"”t?ý¬>€�œ>P”#1Gu,KA9”óMäS"3Ê¢b‚–Í�ïÆ ?Àugñc àµrÿéBJÀu?¤N&ë±V8$šÿà.ôàÂ'âR)y'e¼Ù,5 :µa7†ªXhX¯’±Bôa„>€ºV=»>/¢y¡Ë1Ea�t¯аNèt¬Ü é TÅÖþÁ$-3 7¶âVÞAÛƒ+H=uÐÎ_àjqÂê¸Ùãp²X04Ü~¡¼B w P¡à"' 7X@é1�I„�ÉR_óƒTÐ*•Ð .â?‚ÐLtðMÐPr"á&…ä”$V $O Ï  9AµaUÂç:#3P$ýnc°oÀáK`Ç{a”(¡Ài¹”)À·é0ápßÖà÷ïPhÃjsï§>ƒÀËÂ!NP„?0Ç*#!NÀ!°²Âr™0_xPaà¶áBv ,qðzÁ°Àb>ÀñªëT3þbÐk 3°ÛØ�2`»Yð|2Ðâf3°ÐÖ-LàVhÍ& ]å8#;‚w"`CƒR#`Ôg}—XK!»cüA6¥^,å x@¼ñ_Œ m¹Uƒ R,ÀnÊ9 Ñ?1GJ°H€7ÚqàHW1Œ­U¤ƒˆ’=ÇÏ 4è=sZÀôv\ L4`Ítqé%�qÐ QDpƒûDÛ3J‚Aêsw‚{­dï&€KY9’‘£”@u\6ðEü>qð¸6êypÄMÀY¤ÍôݺRmgðMÇ‘TÀ¢þu¾Â$½5bI"hµànÕò|$hÃàÏÄ[ðgW÷ÁÑba0&@z½swz:k;"Np*ðDP8Pˆ|qFLù8`6(Hp›`PëГ3\±…–„ Ó_‘¥Æ;W» 2§¼  ;'fzzY�LnOÀ ?¡@>cÏh\À-Ññ N�`P@ØFR®Ê­­vǰh-ØagVÊ—"ð“XW0&àå&£ÆŽlwúâfp/€`†vs"r‚3!âD„¥“4t†—‡·•ÅÕVgçVVWêÆÆÆEÅBUSåFWÇþVÖ¶5×Äá„§†ã†g§— ÷¢gŒÉFÆ•µ„–õäÌV寥ÌõíÄFçÄõ½D³´”•µÂ²åV ¥,C“!v0gÑ¢‚‚us&ôutôE–+©F '7n8q‡5aè`r$ŒÄPPø˜âˆ’3H”pÁóŠ »7Æô¼±C¦)7t̰qcfN*,¸”aÁ¢3tèÄá´ Bž;¼Ô¼°ããE _ìpQ÷e›'Í¢=±æ¦M“QP¾®€U…L+Pâ@‹2c\k\jRY1cŠ/]z¨!ø— –$`ÔI >'ŒsQÃñ (†q¢Ë„ Tþt¦àÁÄ¿ ¹@™É… K;t¬œICå›6mÔÑ©ãF ”(\8¨ÉStKeP^¨Á3)O<dÌÔpàƒ «WÕma³â š%OV`jâ„ 2sœ-¹¹%•.Ü—¬È²†Lµë©+¬cÅË+FÔø'x…a‘„Bx¡ÄX,âÄ>ƒ,4 1p ‘5$Q àÁxA <0ȸ _¤aL0{´Á7ѱE(²ÃqMáQT5´À5$‡Gy¨á@-ÔðBW‘QFt|AtDãL]qÐá†[\³6ã˜CÎZÐ ‡ O\° ÌðžFþØqÆ^`ø7‚B„_|QEùôƒŒ)æA ¡¥ðádBœ�C"tð¡ %˜ < À `²N(vØÁÆ'eXqNБ[D¡Òoy™Ç(µÀ,h ÈMòÉ$!h€€M„€@h414Œ¡…L˜ùe4åÈA4Yı„ KÀ¹F¸ð}‹œDÁ oxá‚o ‡‚ø(x„B ©aQ Ý &¨ða¢@ÀHÔ™9$JD “rÊÁi—aq\Q©•! %a §nKêX‡£¢ÄBN´”Q j(pÜuø3ó&q¡F6Yt‘ÆþRèW^4kÈ¡]ϬÑ]¸+Xàí rhÁD´YÌpšJ©A!Ç3H!jÜ€B 7Ä@!©P‚ )¤­¯ŒíA #PðÁ)¨p(Œáð!ß›öÅ `!Ä ÇyœillQaÌ:ëo¥°ÁB _@N+³u´q[•t„àCP Ô±‡1þèa ÙhÇÕvH!Çz­1ÎÐZd¡bÈW\­ÀEr,±Æ k}7°|ã$ ïÐpž¥ °ùäsņ)±ÃÜŠ\Q(¤í¡1`AEƒUêÄ 7(€C"C(ñb¼ ¹â¡Ì:‰zÌJŠÉå\NªFQþ‡ôØ‚\�’.@;lB,ƒÐ‡œi'sxƒì°.;4ãhƒ ç.X¨$T⇸òP(£ Qˆ‚ ²ð&D¬Û‹ u5x 3*H ˆ 6.8Ä;ØL p°E@1 UHp ‚àà Dèt ä@ÎHahÁP¤Z9î¤h¤ (4!¸ÒÄ–:‚ TAa¨ƒJH¸puÃÖÐ…2Á-2pƒî²ñŒÌÊXÂí2@ƒ5œIß0C5¾aЀ<x º—¨A_sBöRp7"ô0 R¢bÀ8ÁB‚…þ 'ØA’„c*!r³Ã¬ @À8.5H­6¸¡hB Fá†ÄÁ'Pƒšp‚LEz¨Â¨V‡Á5Ìa;ã@C)Ró lÐÀZ÷D”.0ƒg˜p rˆ–A7l.°€æ0ì`¢$�AT ‰­1C ²+8øp€ËŒ”A"ÂIq°éà I¸ÜoúGN´@JnÀ*âP*šH° †Ãr °…-´ !0r| ŠhÀz².ÀXm#l@ƒšàpXŒâXÒÂ0Qµ¸¡ qx„·10a„2XÚÊÀ„.þá ­‘èÙ°ð)Fl"¥Hfް˜ŽD 18>�(R Cl˜„(* làìMš`‡.|â6ßðÁXéS‡Æ‰ÑdGÂB0”¼à xÀBl‹ ÔÀ h�^Ѐt¤F%lh†3žP2@‰ ¬àNvÖPÚ¸AWࢶ„Ã>µ€Æp†"Á nÈLr„=}a!¹Á S…Ì€Æ3QÁÛ$‘8A`”@ˆ¾pE<àþ´MN‘@3˜ ¼ pTá²YÉ?x¨ÁšÀ‚Ô`"“‘J&‚&´€"^7®¦ nµçIU¨BQÊQŽ%¸þ!wO;àSŽhIË+ˆ‚D)…:ìeHH�/Àˆ‹Dàõ†¨6±aAh vðD@‹ÜF0EqH|588à€¦ÜácNð#éœþá¡.,ÀÁã>f¤:`¡ >€B  ð1æáq³ò¬À n@êˆRXtöÞ¸7h¨Âñrvé®xu8ÎÐô†\ Q¨€ó~Þ:QÁ 1ØÁ”U@!Ô! \¬iÜBÓ¯<|؈J@"¨`%-„ ®ü¡˜ ~è€ÎÌ‹8×A `8ƒÊ ‡Cîc<cmóàÌ©¡ @jBÊP:üþ EƒÌìPíQ±àžtp#ãà£ö€É„h˜–Ö ¦Pdá4Xà ®& ˆ Þ`�ºÇÀã <¡B8eÚúñ…3Ô¡ C _¢r ìîRm˜•e Ó hÄ#(A ø9PB@fõ¸"û løB3hp/E®(â[&±CFhh�v•oªÁ Ôƒ6Q%7dƒ;m˜²¦…Ûy¥kˆ‚ÔÐC|šæ†8„ ‡…›¨$”3°@rƒ0L”{ÇùÚ_|íë%!iÈÄæè­1A ƒœÐ ‹XˆÄr‡#Hrx(JQÔíYÝþlˆƒLØîWiÀÜ C¦Ð†2 %<Эì�HØ@FË·v¬Ý…1xáV; ÚÙ³A.̥ʀB¶FH8šy¡` ðiŒoC$З`¾—ã€`;Ð/cÊëÌÜ�"a ?ㆇà ò @AMu�jã·6àm pé1#¥GP0-EamðbÀ>P> A¥CAÆÐh�K€ Zàv°=à×qÊEVO0` ÊeCq%Ù23�+˜€ Dá+�¢45°(pJj³D é5/ùXPµE„°0!%eÀUPþpõC�C )Ð*©ò [ S ä…d�+êÀ9³  LðgPP•±Gs°9ÀÀ /°up{n˜B\¤&eàcÐ^5c€z>1 Ä Ca Uð/ qAwÖ@m0ob�u`QLP  Wð]ð„1 Aë…°¸ø Á´>—A‰ü�Ä  �IÐE �PQ@˜p ¡õi`wå'ÐèAu`@a=±+5s@o�!@þASÅ#<P-$È27Ác s°5¹ÃhiUòQcÀs7&äð·ãþ\è2À‚OÀi°F0tp_“ûàG`:"p1N_ŠAîՆбK¼$1ÐO"„ƒvž%*i`mv{`8o¥p ©[€@Ñw0 ¸e@ ¿¢*j@ ð,Ð� óMÊ@7‘oÜÁ'ˆ"ŽÔ ÐÐPàU=S4 p <Q°4€I|Q'^pDƒð}TSC@v6ŠÑàã0b#€!p‚6%ð�Ãy˜Á*À‚:›ð P€1Ñ6 d` 5pý³ áÂQ¼2 Ÿé8€,«×�IÒêþ PÀPóoc°%]å,ZpiÜñûÄv2P<b Z`<æÀ�<æ<E°ç_˜úÀF´>WãXðœd#E Qòr|ãrC7* y LÈñ ˜*¼¡m¿2T°”A‰YÕÁ%Èñ8ËÑy PÇ¢ ðM,sO R0V@o0Ð@<pð4hðø¶ð\]Ù&R Sðän"ƒÓö`¤wT&=&0áJ‰ò!þe>°Â=L„6øð/‰ ()ð–âÀlœ‚9ü“S‰ \€ 9 Jz,ŸnV°þ@&a ƒ�!à�²õ@Ï bÙeüñAv�&CƒC“‡äB 4Q.^¹ °Üq.œqÀ� Е P~²”;@ R l%P~ý¨î%SÆ(7Êr‹à>àÒ$ð0ô7W$Føc9™O‘sœ§MßäÊ,”@QðtK¸z“PVš0Ÿ> ]ºRÐ]`Lp5&ðQ¦ ú 2à,ÞQûä< O[°•C5àP2€�(7&`IÐ=á­x%ð0b3‘*ârwƒ.J­þ•˜rø'€[ü'A ÄupiDþª‹Se€“yáDÑÈUËæöª£ÓÁp~Ò$kÀ%DÂ÷ s0ÞØ-Ü¡-\Ñ ¤`Úæ 3@3@W1GlPw` `4 w}:QÝ j€6§d0'‡"�°—Ôº `(\p` 7@'PS#@sõI¤°•X o€¯[@yK˜A" °âF X 22­à®ç`ðG~ÄŒd4¦P h`åà-O MôÆÅÅièò‚¯r3¸¡kðv>%þÔ�/›C ;Šq$z‚D =rp=îÕ —®B`š¹4)îþsHPsg€LVS|diàGoÀNR5œÃ%°ÀM0޼!†ÿ‡R`n!Ð�Ç z@:{°uVtà¯ê@ #Ô‚×€"qú ¨b¥ µ¹ I°’Ÿ´ ÎîäJADDG�}”'Wp‘ÁppvEúû°'\¶’gÁ†LEfO¯O,ò©uëH\"w>Ñ ö>€t¨`À9/Po VeGà"{À"LpÉ]&¡Ð½ŸÔ-5†¶ MP+`6}ß@ ˜038WñâJùà�éÕ–†Ã®†;ŒP¤‘aê?þðRWˆLI [¸ ©Œ`¸§Öq¶qOý*Gà±8˜ZÝÈpÁà¥óÄKÁûP2T@Îð ¥@ ò±`Ƴg¡ °mP›Z@îáP4I^ð,tàM ~ò:P´äJû°úð´40_€¼TŠ… ž'€€ó3;p5b¥ÔSŸP M)3á7�UÐ*¡l!Ь`N0$Aô+ÐG`Uó§QÛòc0Oô©, «óq DÿF¸"kj ‚¹ŠV` ™'ñš7 —q(ƒ †‚þÐùƒ 0ÄtÔ*Œ1 / E7áwM ©P@)±8¥�þ!g” ‡êäDmáM°!ðleÁ:ÎÐA"XoÀ¥Ç–ÄjR9ãÐÀq%]ÉLÀÙ‘-éAt€÷Œ Dðà÷‘ë{ lÛ3fMÜKïã„J˜'Ððs9 sŒ˜À¬ÇÁK*áš0$†9ÞÔií£ª7•xõâ 9S¦Î o0c`s .p<ÝvO IÍÀ;S 8ƒ;&5á§uJ]ðop–^àQ„*Q€—‘ðëûþ¥Ùç³ &7rƒDB�ö°Ö=B= ó�ð�B +Êa$ƒ ô}9°Agªx`- àh¾L€ÆŸØÚH›ã ô=ài�Q‰;å0ã�b²`Ia7W40k@Íxq}mÒ_+p±u°=ÒSÚ'ÇÃ`xB˜W�˜€kÖº=ñó>0L”$àr1PR'� @žAG¼4áS:‡9jШp[Ÿ d�$tpÁ?Ò`“pLåuàfŸ€3«óŽs€¡]P'ª±e:Ó:©qÛ·.ÑðÑwPÐãªþÝe°}Je`®–'Ï)l—²&`!"9¨Ôsx»ø�‰*–20ó!±6(kŽChqÖ|P0á˜#$Q€R€]ç6ùg®b ÅÈk­¤2ãG_@¡À-âí€]Á‰= ´³,ø ê° + LpCÀâmÇh$[w3p�07;  Q˜ 1�K©´6¸t'§"@êœá>,õв gpx§Hài„ 2‚ ß`ª?š Û€.Û$ ­'#SAÇÒÀëGÆ‹:Ï|Ì; 8ã-…¾UCÄZ /¸<PpC3ÈÞW€sAµIþéL`=�³7 w€=×ó5„¹ ®lòì >Nà¢øÀpM D:#µK0� IàC ºÕ€@T¢NB2 MP$\bÛôMÆrÄFsàF¨ÐGP9-`@ÀÁÆC E \ïÖòý\à4œt¯BiUW‚;5ëÀ5¿\à&}ŒpÌ)ÔaÐQš !ð 0îãJhœ½0ÄÔæÛEC€©±ô³  / `À@ÑÈ%žt#ø ºÂ!éuðQrKÒ�‰6¼HR*é¬âIO�ô Õ ¥À¨7ßÐV#[Lþó j‘šl c4 ú˜!é[+¡õRx ¿~‘'ò_  ÄTë[tCð#Á³ìQÀg€µ¬Qò7_5áèP9ÍcÐz› ,p5‘at€:z2·ÑgÌ'éf�•ÑÐFPRŠlà…ÞV‘¶& §Kи‹`‹,Z»ê^ADGÐE_�—¶jWX„B8@B"7U7"W7BnNaa_aNU"8a;a  l\P\lPuozvz{¯tPµtmlnl»f5MP¿-,us,-QUyyUUXj!t/M/ 4tnqh\¨hhOKO§ªdþdÞKYY+PKZZKãkckbñYPY44RÒØè!EJ—:W*üòåÈ‘3gn8Ár… –*”„`¡€e‚“8a¡‚% N(PøTB%…'„œP �Š.(§êÀ²cç.NØTT£Æ 25ÔÔÀ†¨3>j°`¢E5yðä¹¢K  ¨ñBƒƒ%rž<YƒfÜ“Z¤ˆù‰F š5ðÖ­Èòö­<vZhˆ‘“ÏߌÃcŒxIãE‡5w^’¤Žš:˜‰„QáRJ'Wœ¨À£4 "©žpƒ‚‰%XRÐøÇ„lê”ÁSà ;Ú¸èrC+žã6/ë9þžç°¾4„Àƒ5ë2h-8N@C¸¶kž ñ"gŒù9SÂ=isWNø5kd€›‘E‹…,ø˜LÑÒƒð Yü³E`¼±ØÏŒæ„|!ˆ ¾©@„&´¤k1¨@A %˜ðÉG©ÝP¸FD )xP”Ò äaVuàAGtDá¿áQ£V[TÁÅ2Ë„A[´ÓUgd”AE `)©V8P¨Å„Rx¡ßhd±^hð�8lÉEìõÎõÁG‡Y°ÂxrÐÀmtáA ;x ¡B Ý Š)rFA 7 ðg D”°Ã¢'L 0•øÉþP‚G'p�d¥•©xxãF\¨†Œ§ª DÁjÇ2J¶ð‚1m,£•[¼€Goœ¡G]´�œxâ<!Ç=xQ,OqŒ _ZZdß|-1†+,F?k01Ã4 Â KÈP'ý�ZB ’¦@Á"௠¢XÂ#܇ÿƒ;„(ˆŽ– ŸLÀ¨Gœð…Vǽâ£?¹±…uD"ÇÈÖá‘ mà²E yÔUelPG,Æê¡Gâ´•…rLaàb¼7ÜŠóí Œ³B+¬ž+X0ÃQp°Å)P”ÑžR[`œîh†p…Eþ Ž€B&LöIŠ)Nz!WáÄŽtƒLˆ†CèÀVvÔákd¤ÂÌiÅxP áxœPƒe5lQGt˜ÑFÂÔàÀT¶Ð€Nz¤±‡,ë¨&kÌñÄlµ¥Š78YPíPl±.*lЗŠq´“5¨lQÌÀ¼0 ‚Ø;tHh Ý€6$% €£x€ÂLìw%N|Å °_JˆðÅI€qÄD.ó8N¸CŽ|.»`C ‡P ³BCRf†Ü¼ Ta“ZPƒtÁfDBÔµ 6ȃ[kêàtœB<¨ Â9‚‚“þ¬@ZxËâªÐ.HÉ-ˆB*ð `WˆÁJãH¬o}7!„D!$Q`NÀp„  |áXÁ bЉ<€`P ”0ÊE¡#|–G‡6" œ£C�¸<¤4`*qÈ .Ú 9%5€ >`ÒåvR æBÈûÉÜ1¦n˜Á eø Éá:TSd°‚'È€.äÂÕ|gC1Р`‚š@«„èËUB¨Bd¹¾„¨a"„Èeu, Âaà‚I°š(à(¸_t@"ØyÿÛƒ¬Ð à´á'Úè\6SAd¹hCư5’þa 8Ð�DÀè- BZ@†r,qb�GZÀqú„âÊ@†/LÎ ÜÓà�‡5¬�Ä« xp†"Ø¡q¸^/Q K€á @¤!œ05¤ I¹ ‘à� ñ;"0ÓD@š‘‰)x 6ðäÆê s¡ 7ÖB xàÀ+Ø 4¡Uà�.C”ÊM)*£;g¸`†2Ta Üj‹¸¸°ÕŸ¬â p8…¸<˜ùÐ@Në ÁVÀ8Í€ xà ò,ˆPBðBˆð!(! X4Â`·0\! Š@"(€E¦0J‹8Á†( !D þBPÀ:À:�Ð f˜Ù+ w+¤â x¸ƒÐà <J+Hå+˜¹´ŒH—aŠZ°*¼ÀÂáȰ‹¢ÍÕƒrXBÖŽ,È.yO}´€&ˆa Rc�;œGƒ(Ø� {Rš0 IøBêw¨€¤;@>²‘Ø´„#H*Ì* SŠÀ'Nð�˜ àl¸NèP80èÁÏ8ưPƒÄÝ@+¯2μéƒ/ìŠ:ÎëD l  _˜#6&1Äq˜]¶Â±³,Ü…-b’» -0¡<èZà ¤µŒÁ Vð¦P…[2*þy�£>z…#|BE*ÚE2+(zµÄèÄ âçL�Ìø€œ)pÌCÁ8ŒËƒ0ÃÊ<î8†£ È€eøê8(CšÀ„&h`d®µfìp*8€'ÌGÞð† xá sØ'8î!‡8ha㈂|ÔT­%Ð [êx xØ-¼ýxW® í@¥H)¨?¥à÷Ңơpöì¼TW–ì@ ͤ/p-c2TЂЧR±² Ic&5hA-à˜n©Á AŽ ‹=ÌŒq€C[x|†7LAZo@5_¸Eƒ»ˆNÃ{áfà.ð®`É þÐBzºŠTРÿ°À÷Ž­"Ü {û5g E‰€%#H&‘ÜF ÁF› ä�p6÷ç×NN*Ë3¢@…,£çth·ÀªÏma*àB Ìð‚=afÐCÔ MKa ]øÎ`‡È± ¼wi]xІuCaíL Á Û¡ª2p®Î „Ыz§A$°‘Žï R(`Š"ìÒˆàÁû%i/%’X^9¨ßši*ÃݪeþûšPÑ„ÜäÂQ XÖ&ƒsSÀQŽ2ð Ý33,dQq©å G~ChäZì‚€YšþÑ‘ŠZÙr¨�(Kïs4arýX2ªwøaRÀb \Š\Að" „}×í6‹  8h,å1¿^ gð˜ó*"mAލ•9�T [àt°Pp eà�d éÆ 9Ò>ÀNP À °Z6 °\ ]K`s h]Kà\p}5`o·G¡ ¾“ áòxW€ GQBÞPNS Ðb3œQ!•p öƒX€EM±_·ÔK©u€Bp-00 I0XðÉÄ8\P«€Œñ`öÞTZntMlP{7B%Gu þGv0Ä[ –p{ñ6ǧ ¤3¿Âa\@aðK0h¢$J%â.ì dE 3Ðfði]P^@$xö%i@BÀ]! ±X¡ ðRX�,eî¥`ÔfSJpЦ h¤ …£fði ËS œc€{Æg”8U0uPÀg4M°fÀËÀ#ZÑ�ÚQ/Ða%TP’3hcˆx çð¦Õ‹dC?A“kb¢Pz²Z`�s�p^°_p†¢X uÀGà@Q XQ6.T@R„'à!Ÿ°!�–61ˆ¥þUÒrŒ{ð v¨ w¸FnÐ#ÂpzQ�:_a€TC†CC¢ƒ�»²ˆe@Pè maÉÕSà!$dp�•w­³xõ¸Æ0`.à‚eKfS „g ‚DáÑN`yÁ(¶f¶_8p‘œ(0 p58Q >à Ç6Qn@xÞä »a$Çá7RPaf€Æñ#y�c d0OÂ�IdøvjwÁ¨PaÅáÁë & w.ðð!$KQ�JY0ÁV ?‘q— –ðD€E\±K –‚ÒBYþì#*ò/$p‘;  Ç×|e`l@©0$ÔTHUC\E‘+5ðhÀJ�'°b'ÀWP/p,f`>`B„l°cpj44 ];Ç›´Oôsoàš09ëtàsð`�IÔx Ñ W¤#DhÃ@XðE‘B‘b*ÐrW€RžÅ``SGÐk³ÇA5@ èà ,ó*çFPàUiÙÀbð9Qu@A hhi !n!b°S0z5{BðæR3òP^ëàõ°¹PC'þýp°}8pX%áW@½ö 4U"qÇÙL‚ò"µ\p~ D ”ªHp>+Z‘ T0n­’?§²¢ XHE$-0szÔÇÀZ±€A7ó{wÁ-bÿf ^PšoUÔõºp2�^ x±Q Þ $\ðlÀ�R@'ÿ"œÁ/÷Õ‚ !2')óR“ºÈ)B¨N 5€ $µ>Nð�8pC H€_ytDRvhT†BWaPq“Pd #…$l` DcOÅ$B@«± â]Í"]úov°¥¦µ£-mþq2ËÅ*P ÷ñM£©p}^å .äf 6€¨)0x Q=(2s)ÂK(‡ç ¡AGP‘X€qI�i g?·‚ÔFvg*zt@µzySQAePg”oÀ™f�AÃ¥t€Aö©?ðàc :hpkˆømwBæÈ‚‹è « wKÀ t=e€À`r'Z@ÓƒB9ðD ÁY²_( 1€‚ØóB�C+´La uP†@'J_J€©ÀEVìh€dÐ2‚ %ÄGºÀm·ƒ MÀV(C:d™‘d- ÇõƒÂAˆþNpvââŽeÌåá2€‚EÈ#x¥ãà\p§æ]°œöü’_€z_ cWÄ„¸$´øBRé'`Š@1B€TIØžI � �‰‡´*Âq3]P8Ãm@“G™ã>àQW8’2àT_PÃ9zBð@à�-@ p2ã aB‰jÁÎÚ ŠÔ.Äã ð¸\{‘uµp°pÿ›CÐ^‡ù׃P7Ж‘ ÇQMA–©ì#wévã~NPlhöYÀû‹7‘8ä8 “€º0BwXW€ ŒC «ÇeÀü+/Ðþ�/�/Ž»ðź3m1PUPO¨Esµ©Pt µ@5z"4G&Q=4p?0Xy–!\ñÕ’ »É¨TH»4S2ñ#À0G!‘ò_ïÚ0á‘å�7@½?e3{ÐÁoÐऻ¶ð¦Š1œ9ÓÁ-S¸ da:dÉE½>9a%�äŒn`‚bPq ²îð�¢ÿ‘=°�b¡V€ÃX9tpKáÇ›y0º_H0]±>~)±:) q®™•§,A!4E02* ±›HM?BÁ„N59*¶ 1Fµê!à0þmÇáV@@àCÌ…PÜ ;OGy„&s`jn2jQœÄarð@ÿJ203 Ypq`»ÖÃFp]*RŒB§1´7Ð"úãŠÐ´_ö'$ððx9×q[:F©`XáZDZ<eP¿U8y L@Tð�€Æ¯wŒWJ˜¡t Ÿë!rÀY@¸ûa‡WjR>&&º]4ÀÚLÈãÂÍ@B°Yв¹>x "ö5s*! °)@s;ða@ïj3Å0!Id”™š-…dݧŠT˜¡z©@2þ>¿PLR'€ ¼8xð6Ò¤TP¬h ç¸zµW]p&8ÛÜ%òÑ4àB9v‡ÁM¦ƒÙq p")")À–= á( À!r®¢ñ "!9°8QÔœ/¡E·¡¸h¨J{t¹©8” áªeðÔ‘f gUÆú“]�4Ç M�°Å²`i1m€œ6\S0šV ÄK€5»ÀÅ3^€‰PðU“;LÀC@ ?”"ß³Q냸üò²öÜNp(ðœ=œ=ÌÛK1!0¢Cp`0Cýw+†£gÍËþ8™á}MhÉ@T‚ƒmФMÐ$!�´* v ŒTLÀic×á›´prjså&ÄÂizàÌÂ\ ×ÜY;ÄØL0�9Ævx?üXAdT~x9PAϾ$�¡1‘1` –›~SŒD`9 s^p¸�9y�‚LuPCjÜ ÷´\hL@m�­m 0O¥âÜÇb¦³ 8^Bl ª:û�<P@¬"T¼?Á$[Wv¢&LÌUç@LPqÐ4ð€) £XXBP_00Wà ¥#@ ‘G(ELŒ ¾Y ð"(p\(_±þMÂqz§Ð‰i`©­Î8zÔ1?QCêVA»0›ÆX1ð 7rÑ-°Và�R¤*»B)-]ªðÌ»ˆíŒËe€t Ç�ˆxNl PbÐ%oecÐŽeDCVàš‘ê a$µ¸_á×rúMf K1sïZSD@"¾‰ë&3“†©# l08s4[5@,`Ì5à9bRrª×aаְQ²ˆç49mà¶ÌòÊlà¬äBáÅD¶-+Ðÿa°üi?  àØsT˜GÀõ‹zð"õÃÎÐK+• ë£[­•§ñ ÐÌõHœ–Ãv°:o�P ©p ¦UZ+ØãI"žÄwð*Ú¨áÈÁ`Ô`€Š˜àÀ-y„‚0s}m@šëâ�ò+0aó͵–Að´ùc<€pv”–tvuå$‚åæ„Evv%rƒursƒs‚ƒu#Â1áQRBáá¡ÒÑq¢pÒ�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/close2.gif�����������������������������������������������������������0000644�0001750�0001750�00000000216�11462120062�016467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ò�����¿¿¿ÿ¿�ÿÿÿ���������!þ$File written by Adobe Photoshop¨ 5.0�,����� ��3HÌú1¨ñÍÊosR–@ØZh¥b-ûlí–°-ãt|›:ÎëCü”€¤r¹L��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/buckskin.gif���������������������������������������������������������0000644�0001750�0001750�00000016611�11462120062�017117� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a^�r�÷��¢^:¥_:£_=¥_<¦`:¦a=¨a:¨b=¬c>ªe>­f>¬i?°g=²i>µk>²l?µl?¸k>¹l?«f@­gA®iA¯lA¯kD²jAµkA²mA¶nB°kD²mEµoE¹nB¼oC¹oD¶pC¶qE·tG¹pC½qCºqE½rE¹tG¾tF¶rH½sHºvI¾vI»wM»xJ½xK¾zMÀsEÁuGÄwGÁvIÄwIÃxJÅyJÆ|KÁzMÆzLÂ|NÆ}NÈzKÉ{MÉ~NÌOÆ{PÃ}PÅ~PÊ~PÍQÊ€OÌOÇ€QÊ€QÍQÏ„RʃT΂UÊ„TÏ„TЃSÐ…SцUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,����^�r��þ�¡@QR¤`Á;\Ĉ‘℈ hx°Ã'P °ÁãG B¤ˆ”„ɑ#}ðÈ¡’‡ 'O2)DH<lh<áaC 64x Bĉ ]ìØa°ˆ% lZáB†)Jˆ¸b† Blä˜ãc’‘%˜4D¥•—¨eò„ &Slù‘ÃÆ !|bø©¢ˆ).ìáƒHAÇP¡8YB¤qÓ a¤ Q(D¡`ÅÒÈA:H&QšÔ¥k„‰¶AxÈ~ÝÚÈ\&M¦0IDGŽ: ¥TCQŠcôpü؇Ó%O ö(âci Í):C B†'hþØ(7•Ô%]?ý¶íG#KÒãŽBE7’›8ÄŸøÁÁ Vb0´°CÓMWPtT-e] œ=Ex·Á á§CK4AÅyM0±Äˆì!›l>¼6b|MÐGE÷é€C~ûùÔ]…8 -¸ÔrT9ÕÔR 1DgÆmT…à±0ZYH˜÷¢ˆ$²D[/]y%m#6ááyLÜ—C~(ÔØ•D† 1à ÃÌ-äm.tä#(aW] 9l˜„—/z‰)Âöž¢A¼ö^NQhHø†ƒ 'ð)¡îÈ# 8´ 'AN9§„©VÉYžz¥Õÿàý¹!§å6Eˆ‡¾äᇪÄ}FñNqënbæ Â~l UgzîȦB8ôÀà© "xVEE”VAUfiI iåÒŠå[íéú’iåz«—”ö–CFUX”„D!†›Ê!Xcb&öÜî»/à‚ ¥AšÛÄñ21ì¡#"¡¯¿Æ+ï¹¼‘æB™#t%³ '·ÐÁ²ëf³ÙBvœ*ܰÀú_¡¹Õ‹DkÄ»bƇá³¹-Ú§’ ˜–°Í&+ÀWµ¬„¶+_åBCšü¥Ô•¨}èån½Åµ„ÐC¨Äˆ™å%¡Q¸ÆÃ6`xòÓþ"pWÔ¿Y/fíà+÷p0·g>½ä#œ`Ã<ñ„‹ô‰øQ䯽Ý6‰®aij”¯w7¦{2Ü7E"$Ʀ 0³N]UVƒf=$ Ó|‚§Täex—åJÎ!‰šk¾lñÙå{]FŒ^&Ÿ|w•äQ«cv W_M'‰Ñ¼é«|:ü8E<1yè‡ÈmOøîKÇ3ÏÖˆô¡…ùÍ'„)ô(ó:WqÝcdp¸àiy�Ãø†;Ý-å5æ+ úâ³¾×PÉoÑAŠFä# á#LþŒ@$3Õ®B |À[°2„DÁ FУ’E„;KÚ�¬Bp<.X­þ™œ|Þƒ¹æ¹'W*"Ë“<Ôà¯$´ x+>ù-" a Nð0‡=p \`@<Md_ÏÂ{øÃš/DuƒÛk È—¬+xt!j@Ç„-%„€ LØ\Õ­ái-c –C„ôHeÌÓÓœ¥•8í<D9ƒò ¦g”úY£UÙèÀ7<mÌB«$Ì«}A(¥ ¤X&RÒ’ZyZ§NЂ1¨‘ŽìQk®äëÆì¡wp%Ím ñºÏG€Ð<Ù°äDFV¼Œ"‹uo#ÃP³žV»%i�O<¦ƒ|y@<u +á:AŲ‘¥Ä¥$‘òÿ˜4;i„fú`K@hf+Ë5·ô q),�$³œ%OxrªZ\§ÿ3tÀ8:4Š<K�+ Õs@PKˆè¥Ï¸Qó5‹êç»zÜà%wÓ ³™Ì=i ¥h/w0ưÊ7-Ì-qiÉL²@6μխ<V¯¶ÐFQ¯ÂJ™j+ûa<çF‰jÉ®xࢬA" hÀÃŒà¢çl€Ér‡¯ŒìÎ4ÆŠ+S¥‰Ä¨¶g•Ú¬X\åM¼• _¸sVWÀªàé0½|Á :€V X @-J×L`Iü '‡2IBBݧ=RmÌ^âvݧ$")W\s5&¨�]5 §þ ëØÇZ€±]”á .úX‰2N RàZ×â@ƒ’ÔFÒÙ_±+n©LlÒ¡v$Ê…‘ZëZìé?C DÛäV+Ác5°�Çj í5Ùp‹;šNª>ËIz–°«êÆÒ ìAÔi¯+…¸¢«73*nV$ôÞ`à± °ÀmËÛEŦ׽í}lp;?¹àO9ûœfS[’”TWªM®°„•<ær“7ÛÅ hàÚ¾—òÀKCŶ`»­€Ý[‘�=m¾*°ÁŒ"†—™lV-ìÑ– ÒI)¿ë$§Ñ¯n>2¦ÅÀµ þ€+á X@ÈåònWþpf3›™¶šòðŒ–,bÔ–¸QºÂ t™Rݽë#(YnIt“„ÏY É”ô¤'a TÀÁ#ð�#-ä!7zO³¬ f¤ä² 6Ë%M'ãæÜ·P‡ÔN} [ì|´‘FÉ—zíü# :º·¦ÀÒ äT`•r|{‚·Ó¤±¯Hlrg¿„ŽÎ!ß[–€ç#Æmœµ iºl×&î?X@°ÍkÆ^àܨ�c+Ò'‡eɤBMÔÒRQR'r‰Âà[Fû. ê[g´sMJ@͘Ê,Ҥ݌íõÃ/@!_ +á% \ð8œÄ;B·Ž0ÿ4]Âb×ãßÈanKBÈ…àqœàíRSôE8Pés«»¼gõ¹' ë1ÿçB?€@šÈ$r;y¥·Üm3bŒKú½A\ÛLW:Ú•Ÿ`€â�¶Å {Ñ ¨ý×»n€E|²„ï�'ÖdzÈãöTv a¥¬N—Û„·oë‰:[öÎô˜H6 AAÙ…Ò€¸=ÝjŸ°¯ÓÎùsË=|ïö¸lJúà¥dëJŸs l@xÈÈ-ª¶é™öà-8|ÊÀÙÝÎyr3ö×H@Ú…_ óI,ÏJfÐ%® ïw+øÃTðá9ãàn.ÙºI‘8û•þð�8å�á ·Å@‚_€ò�Ø h�X¦ÉYÞ`ô¤wz±”ƒ¬ä7}1}¼D}7gÛ¶] ÕLZòx9!S5’ðõkP~èkêFX`|±bY6p&PFð$ˆDìÂ8Kݶ,â'®ks¦ZÇ}$ètÜ÷}³ôZÏ3~`~øh € 0„ 'cI*ð$?pŽ·t9À$È€]6#4öZX˜®E4°d€âxOH‚M¸tK(†4†K[ñ�D„8„B†å7„•&°…5°m7`"yxP¸m'c3f…à„ø™”„\h€ÿW†7pß·„9P\¨ÃUjȆXi˜Ø†pd•Å…5À‡ŽXŠ~HâÑ]Åt‡L&`YI8c_ˆ‡¥øÖ´„\Hc”•K‡ n¾˜� Ð^\!&pŒ(@LH8XŠ8…ˆ”Uv_1%ðŠˆ(‹ÌøøŒÑ؈5@»8!°� ŒÁH„hI¯8¡˜‹³Š8LÈiÅEYãt`AIu¸…â1µØŒ*87 ‰Ç[�_C¨Ž p��‡C¨V®øŽ3ðÉx‘õX‹J6‰*°‹P!ýá�ÝAS%�‹¹(cÞøâ14€“ é4ÿ ™Ž‘ P�°“ €“éøy!p’Èø¯¸cÁ„ã1K [–Ôð”$ÙàŽÿÈ…öDŽؒäh3pŒÇX#f“=Ù“ “����‘ `�ÂHÆ` �0‰‘IŠàGcU’N •R9••…’ʸ’~¡”A &—=±a`“p�P��@�:I���À– €r—bA—1IQâ~JY\¸$•Où—ÜA•ô¥‚JÉ4:h‘]‰†¨{r—Ž@���—I™�Ĺ™ Pž¸é•äXš'›èZ¯hIàšR‰#€KÿH}Ðù’ÿ¥é•È8—€¡›AØ›¾��œ”y� ™™À�`‘0—r©˜P&¥Y˜LS…”Ø”®Ù594¥Å;›s©˜s™Ÿ!ð ‡�;I�iy�À™ž ‘Йט PŸ ú¡ú¹·ù¸šÖù Õy#4µ4àˆé3 P'ð¡ Š£Ï“ € `�¡p–0�íyžP=ªœ°Ò °‚LÁI8IÖ]ÿYÝ¡@Ý‘–Ô,8ô¢°˜„2j…°õ¤ jˆã¹p €�Åy�ð¦gù¦p�šy�@= špYŸ*Z°r’(¦[•¥ @žØUÿàAKÅÕ¨V(O* À§†ø ñù˜½9§0�C �Eš¡ � p{ +­‰L¯å¨ª.Ý1‹š±U¨%‰K(Y\õPyªºC×(ª¡œz–�`¤ì™?JªºpªPÉP«Ú¨»øR9˜–t:RÉQÙȪuhL³ö”§*Ìš›_q� ™í §ÄJœi‰�¡ú˜`qt·a жjþ™^ª@÷ ˜ªÈ7D B¹…ªÙP`¯òÐ ð˜ðš–ÄI¬™9§vª Ÿ yO¹a àÈ‹ÉتÔZ¨7ä,Ú” é¢Hè¨Lé4 »aÿÀÇ�»¦û›Äú¦ÇŠ® ¬Íª¢¨ú”¢…#Û]úO´Ú²®•K´Š¯Ùh 4fY®pªAk®±@ê¦éI¤û®¢Jª{*f •hªI5úVH ­“(O7B Gè‚–ŒW&Í"®�åú º'ªéZ¡Ãê©Æúžê–ƒ…MÚ§“jˆ€ä÷’MÛ¥ÜAIˆx¥skIFû‚#£PE®ÍÚ«X¨›¢Ú›Aº©º©íIœª+ j¶OJO>äŒÔ×]/[²G˜²NóšI}ÎèŒ:Á3õ¤½:ž<ú˜mʺÀ œI§l¹pÅš Ú ¤¶*è‘ÿW’:Ä´»ˆ¥ßkLTÛm²™ |š£*>Ú›ªžêižꙋ 9н±IÛ‹´•€é•nK­Áû‚²‰‘z» ¯(¢Á£ ™;9™”©“š™™ü‹É¹Š “A—¥©‘I”¸‹ËUÈ4傱h³T£ßyŒD ¥+w幓ũž;Y™*ŒÅG‘¸Y—œ¿§y·ç‘áÛ,Z“*©,:ÀV (¨éœ¶)—¸Iy>º–¾‰Ã7Ü~‘Y~¢úy®µ1éÁõ8T˜„:ˆKþû¤Z«-ÈŒÀ!:!“ŠÙ¥Ákùí‡Ã:Ùžl)Œ `|TéÂ( šÿækŠÀ‘ù’P-ê§®h°A¼’7àCÍÙ•� ³ –j™–IùÇÃX„ÿË•a “/ùÀÑY…L +Aáý1¾u¨—ÊhxY—>ì’3) ‰j©Žn8]A•4ŠÄëÐXŠùÁ½Óêôú§‚ ˆËüw‰á &l)–¿aF8È¡øß·ÊÐè‡26‰Ô—Öˆ(œ‹O‚•é‡ À¶#èˆ6ًىE!OÉÈ…Û&x¹ŒèÜ̺»>aˆZØÄ³ǯæˆÛ–‹Ô¸`ìõËXi¾(‡äTËÇü„Éöˆ …ÿ×eê|…Q´ôÕ…³(|‡ÿ'2Ñ“hL‚ÑmÓk¨Vß{˜ Í„E†`¸]ש¹>uÔ–%Ǩ'P5¸tåÜ9àõ—¸‰Ç‰fÐ~çGð±€”|ø‡D5HzÙy H›‰†!�9K€9®Gu58M7K …ÒÆ{ìW~Øî·Õ�ò§C™4KM­%Ü·.*áz7G›ËB\Üùsx)Âx7¸мɿÆÕå‡~?|½lÖb!›ÿÇ|ÍôobÇœöaÃq¶'X…"ªf׳‡à72UtÇnw~¡½kŒE¥}nsש=Kú×|£¤o±qx'c3#¯xÿ«Ä|?à}D-Eâç™—vÆ lÄÍsPqé­nÆ7w=4×açÎ7<TJ'÷O-á ®WJ4ì­uÓä}j HÐ#w–§vPq7õUéViæ½p ·i£8á6aI�îñÒ}’}ÍcD>"(¡7v'yжp·FtGÜ»åk.dÐ}‚p›(ÿÇ Q#Çãá)bbQáq“r%Nm»äB`MÉfݘ"~àk÷à7ãB÷sEæ,’ÍÜ_¸tBÀ5qG J±ÑE@mûV}æ9%Ÿv!WÒÖíZ[Än7åk�qåfÇéhC\ö“ô�Ʀ10&Ûö9$ÑRìÑá´ÑˆGjÏumRP32øa*P!çnÖfh¦f”Vim&TÁ0°h}e1æºÑY(.eÐm§–Ö™>hÛ‡†hâk;·vkâæ#Ðk+À^o&ab&!HFx€W„–±nmoÁríÒáé©%0‚söaù"=…ñXnff+ ijÆçföXà•$HÆê ¤™^³Þá(Fø çFtNbVõ‡+f1îä~f¼æc…kë5Æ7G‹€"(¶¢_eYò_1ëÖä"a`12x•k;ñYä~Næõþ�!ãÅŠ,XX`pAƒ„Dˆ(¡"… 6pø’¤ *S¦Ha’äˆ A|`,é£ÈÊ“%M"ñ„‰)5¥LáØ$‰I6TüTñpà TР!¡ V¼øbD‡I&m aè%"Å‘#fœm†Db²¥ÚkÕ¢LbófÙ&0sà ñ3…‰"´]ðÀjÒ¦Oe¬Êô*a B‡zEB…< !;%IÜ)!]¶rrG[@Ô^F’„Iç8ëšÌá…‰}!8A”0SƒF@•ábĈ #<$ñ�‡ÜC?œ€… C|0¡%ófî;KþDGiðFt”LÍ Ù&Ú™áÁà èô?|*â„S‘{á„s¡…ãšBî1¯Œ.2ªb íš °;ïà+Ï—Ê Â´ô¸£Â(–bˆæ;!„ûò*7 Òà@NpA†dh8ßüËÏ«ÚJ¸ï9\ˆ/ˆ%˜XÂ6“©C“8 ¢¼ÐJZ¢»$™ˆ‚‰#à“¾îó±¶Üüªª âÜ!Írn¸Æ¸‚È+çês!MÓŽ@2ÄÔRs  4Të;?¿K"½‘4MìÃoƒE€ ·†#h„5Ó¼qÍ5Ûl ‚ÛZÜà¾"sÁ†¾[≠™i ‹þøÓˆøtÐ!4Œ€5ˆ-Ñšð‰÷†âÄEéÒ¡Ún‹´±á4ma4"vXÇÜl.N9K:l Ž‡ Œ"Ü=£¯YgÍ¡²(£ôACV“Ìò½ø¸uºÚz4R¢†Çf‰ ¢‚KÓpë롵Ô�M5Ëx]-7<xÀèâvq o‰#Ãâ ðnÝÁ [øƒzßH!b€¡"Šx‡Rà™„ ”ky+çJÕTŽUÍÒWKŠÕˆµ`¨¼\@\*D6WØ/J_8ØRžcèÁæ"”8µ[ „¯ÁVáFiL¼'žh\$þIÜØ5Ï /$>Fòn‘Ðzè á~à!`P;VZ©*ç9…‡FØ1ë¼Uqì¨Øû;#D^ú$˜<FTÃ#7’øî"xhü1ˆ ÍO„HHÁr²{À¼ˆ²ÉÞžûr·Û†jx‡[Oçõ÷¾; $”Pb‰î½÷ø‰#�ý–ú옵dv(Ò1ñå™r²-'^%ã+לfž]tž«¾èž^8âÏl}ƒC ÷З’Œ¬'ç[îêÅ>8} 7c£ŸÚd`3%d®r›S›òš£H} "t‹ v<R¡ .D ù2¢‘Ì ®C%“m>9ßµ@~ þ$[Tr¼ÊÑLm*pYÆ2…%…™Y e8ô¡æ…¨™IZRE(²*9pA½N°D¡Dn"EbÙ”p’ãP~¿#cÂ6@§tŽ=ìéNZ gÅ% ¦$ݹc…¾ÆzU‹Œ"�^‹X¶“ø€xeëA f¶³‚ùÅ’¶ RPG™„(Š—IBë2f’·`„U… äÓ•úlew®ŒY ÒX¶€d%LSph³Üh røš rp™¬g JK»Ì•!fâ #œN’‰FåÇ!„Îä$Y§›ÝÒ›˜–Úàè—ÆüÅ9!ØÖ0˜™¼yLp2Ä•KÈž%ˆ(НÑÿÁ]Z)´r¾,f”ÃAšŠ7PpÚHm³$ÿ69në90\ª7¥AÉ[%ñ–iÊs¤õ ðzé¢ÁÉö³•_:d$hÚê´Ìuð›8ë¦ÖÄK_ú’+  *òÐz” [Ú16¥(9Áoë ¤°“tÙ€(Az›ƒL1»¦Vr³rÏxÆ#‚#¡¥<·5§ª\É@B°Sˆ RèH´„'¾acßù)žÞ W`ôÜ A×~F«"2>Í#ÃJîyOˆÝ X$úråpÀÖjƒ‡zË­©Úø(Ÿ‹mh GЫg2ȿΠ°h�²ƒ~vU ’ͽ­Çœ�—bΑœ«äÁ4€ 4€¡EëVIhR&ˆµ€:‰X¢†Ú#øÊ&[â·Z‰ pW+<¬mÙª(ì ŽÅ\L'™‚1þì/ÄÍätŠT>æ" µÅX|PB]$Ù„$ÙLŠ6�ߢ„íÁ“ähìw¶%@ ��;�����������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/open2.gif������������������������������������������������������������0000644�0001750�0001750�00000000224�11462120062�016322� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ò�����¿¿¿ÿÿÿÿ¿����������!þ$File written by Adobe Photoshop¨ 5.0�,����� ��98Ìúp„8ã‚d!›“ƒ&rP�€Û8š^ë¬UBœÞÀœ¾±¼O£;T)“ÑåΨTš��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/out.ps���������������������������������������������������������������0000644�0001750�0001750�00002465037�11462120062�016006� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 72 104 539 687 %%Pages: 0 %%Creator: (BLT 2.4 Graph) %%CreationDate: (Sun May 16 22:17:22 1999) %%Title: (out.ps) %%%%DocumentData: Clean7Bit %Orientation: Landscape %%DocumentNeededResources: font Helvetica Courier %%EndComments %%BeginPreview: 599 480 8 9584 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000000000FF % 101018111818181818181818181818181818181818181818181811181010 % 1218181818181A181A181818161010101010101010101010101817181818 % 161210101210121012101216181818181818181818181010121018181818 % 181818101012101018111818181818181818181818181818181818181818 % 1818111810101218181818181A181A181818161010101010101010101010 % 101817181818161210101210121012101216181818181818181818181010 % 121018181818181818101012101018111818181818181818181818181818 % 1818181818181818111810101218181818181A181A181818161010101010 % 101010101010101817181818161210101210121012101216181818181818 % 181818181010121018181818181818101012101018111818181818181818 % 1818181818181818181818181818111810101218181818181A181A181818 % 161010101010101010101010101817181818161210101210121012101216 % 181818181818181818181010121018181818181818101012101018111818 % 181818181818181818181818181818181818181811181010121818181818 % 1A181A181818161010101010101010101010101817181818161210101210 % 121012101216181818181818181818181010121018181818181818101012 % 101018111818181818181818181818181818181818181818181811181010 % 1218181818181A181A181818161010101010101010101010101817181818 % 161210101210121012101216181818181818181818181010121018181818 % 18181810101210101811181818181818181818181818181818181800FF12 % 1810181018181018181818181A1818181818181A18181818161818131810 % 181818181A18181818181818181012101010101010101010181818181818 % 18181012161816121610181218161818161818121012101012101818181A % 1818101010121810181018181018181818181A1818181818181A18181818 % 161818131810181818181A18181818181818181012101010101010101010 % 181818181818181810121618161216101812181618181618181210121010 % 12101818181A1818101010121810181018181018181818181A1818181818 % 181A18181818161818131810181818181A18181818181818181012101010 % 101010101010181818181818181810121618161216101812181618181618 % 18121012101012101818181A181810101012181018101818101818181818 % 1A1818181818181A18181818161818131810181818181A18181818181818 % 181012101010101010101010181818181818181810121618161216101812 % 18161818161818121012101012101818181A181810101012181018101818 % 1018181818181A1818181818181A18181818161818131810181818181A18 % 181818181818181012101010101010101010181818181818181810121618 % 16121610181218161818161818121012101012101818181A181810101012 % 1810181018181018181818181A1818181818181A18181818161818131810 % 181818181A18181818181818181012101010101010101010181818181818 % 18181012161816121610181218161818161818121012101012101818181A % 1818101010121810181018181018181818181A1818181818181A00FF1810 % 121812161218101818181818181818181A18181818181818181810181018 % 181818181818181818181818101810121010101010101012121012181818 % 181012181818181212101210181218181810101810181010121218181818 % 181810121810121812161218101818181818181818181A18181818181818 % 181810181018181818181818181818181818101810121010101010101012 % 121012181818181012181818181212101210181218181810101810181010 % 121218181818181810121810121812161218101818181818181818181A18 % 181818181818181810181018181818181818181818181818101810121010 % 101010101012121012181818181012181818181212101210181218181810 % 101810181010121218181818181810121810121812161218101818181818 % 181818181A18181818181818181810181018181818181818181818181818 % 101810121010101010101012121012181818181012181818181212101210 % 181218181810101810181010121218181818181810121810121812161218 % 101818181818181818181A18181818181818181810181018181818181818 % 181818181818101810121010101010101012121012181818181012181818 % 181212101210181218181810101810181010121218181818181810121810 % 121812161218101818181818181818181A18181818181818181810181018 % 181818181818181818181818101810121010101010101012121012181818 % 181012181818181212101210181218181810101810181010121218181818 % 181810121810121812161218101818181818181818181A181800FF171816 % 12161012161210181818181818181A181818181818181818181810181818 % 18181A181818101812181810121018101210121010101010101010121818 % 121618181818161010121012101216121818181818181010101012101818 % 16181817181612161012161210181818181818181A181818181818181818 % 18181018181818181A181818101812181810121018101210121010101010 % 101010121818121618181818161010121012101216121818181818181010 % 10101210181816181817181612161012161210181818181818181A181818 % 18181818181818181018181818181A181818101812181810121018101210 % 121010101010101010121818121618181818161010121012101216121818 % 181818181010101012101818161818171816121610121612101818181818 % 18181A18181818181818181818181018181818181A181818101812181810 % 121018101210121010101010101010121818121618181818161010121012 % 101216121818181818181010101012101818161818171816121610121612 % 10181818181818181A18181818181818181818181018181818181A181818 % 101812181810121018101210121010101010101010121818121618181818 % 161010121012101216121818181818181010101012101818161818171816 % 12161012161210181818181818181A181818181818181818181810181818 % 18181A181818101812181810121018101210121010101010101010121818 % 121618181818161010121012101216121818181818181010101012101818 % 16181817181612161012161210181818181818181A18181800FF18181818 % 121010101010121618181818181818181A1818181A181818181818181818 % 181818181818181010101012101818181010101010101010101010181810 % 121810181318131010101012101210101210181818181818121012101018 % 181818181818121010101010121618181818181818181A1818181A181818 % 181818181818181818181818181010101012101818181010101010101010 % 101010181810121810181318131010101012101210101210181818181818 % 121012101018181818181818121010101010121618181818181818181A18 % 18181A181818181818181818181818181818181010101012101818181010 % 101010101010101010181810121810181318131010101012101210101210 % 181818181818121012101018181818181818121010101010121618181818 % 181818181A1818181A181818181818181818181818181818181010101012 % 101818181010101010101010101010181810121810181318131010101012 % 101210101210181818181818121012101018181818181818121010101010 % 121618181818181818181A1818181A181818181818181818181818181818 % 181010101012101818181010101010101010101010181810121810181318 % 131010101012101210101210181818181818121012101018181818181818 % 121010101010121618181818181818181A1818181A181818181818181818 % 181818181818181010101012101818181010101010101010101010181810 % 121810181318131010101012101210101210181818181818121012101018 % 181818181818121010101010121618181818181818181A00FF1012181010 % 1010101010101012181818181818181818181A181A181818181818181818 % 181818181818101210101010181210181012101010101012101218181817 % 181618161816121012101012101012101210121818181818101012121218 % 1210121810101010101010101012181818181818181818181A181A181818 % 181818181818181818181818101210101010181210181012101010101012 % 101218181817181618161816121012101012101012101210121818181818 % 101012121218121012181010101010101010101218181818181818181818 % 1A181A181818181818181818181818181818101210101010181210181012 % 101010101012101218181817181618161816121012101012101012101210 % 121818181818101012121218121012181010101010101010101218181818 % 1818181818181A181A181818181818181818181818181818101210101010 % 181210181012101010101012101218181817181618161816121012101012 % 101012101210121818181818101012121218121012181010101010101010 % 1012181818181818181818181A181A181818181818181818181818181818 % 101210101010181210181012101010101012101218181817181618161816 % 121012101012101012101210121818181818101012121218121012181010 % 1010101010101012181818181818181818181A181A181818181818181818 % 181818181818101210101010181210181012101010101012101218181817 % 181618161816121012101012101012101210121818181818101012121218 % 1210121810101010101010101012181818181818181800FF121010101010 % 0810101010101010101218161818181A181A181818181817181818181818 % 181818181818101010101010101210121010181010101010121818181818 % 181818181818181810181010121010121010101210181818181810101010 % 1210101010100810101010101010101218161818181A181A181818181817 % 181818181818181818181818101010101010101210121010181010101010 % 121818181818181818181818181810181010121010121010101210181818 % 1818101010101210101010100810101010101010101218161818181A181A % 181818181817181818181818181818181818101010101010101210121010 % 181010101010121818181818181818181818181810181010121010121010 % 101210181818181810101010121010101010081010101010101010121816 % 1818181A181A181818181817181818181818181818181818101010101010 % 101210121010181010101010121818181818181818181818181810181010 % 121010121010101210181818181810101010121010101010081010101010 % 1010101218161818181A181A181818181817181818181818181818181818 % 101010101010101210121010181010101010121818181818181818181818 % 181810181010121010121010101210181818181810101010121010101010 % 0810101010101010101218161818181A181A181818181817181818181818 % 181818181818101010101010101210121010181010101010121818181818 % 181818181818181810181010121010121010101210181818181810101010 % 12101010101008101010101010101012181618181800FF10101210101010 % 0A0F0A10101010101010121618181820181A181818181818121618181818 % 1818181818121010101010101010101818181817121018161818181A1818 % 181818181818181812101210101210121012101012101816181612101010 % 1012101010100A0F0A10101010101010121618181820181A181818181818 % 121618181818181818181812101010101010101010181818181712101816 % 1818181A1818181818181818181812101210101210121012101012101816 % 1816121010101012101010100A0F0A10101010101010121618181820181A % 181818181818121618181818181818181812101010101010101010181818 % 1817121018161818181A1818181818181818181812101210101210121012 % 1010121018161816121010101012101010100A0F0A101010101010101216 % 18181820181A181818181818121618181818181818181812101010101010 % 1010101818181817121018161818181A1818181818181818181812101210 % 1012101210121010121018161816121010101012101010100A0F0A101010 % 10101010121618181820181A181818181818121618181818181818181812 % 1010101010101010101818181817121018161818181A1818181818181818 % 181812101210101210121012101012101816181612101010101210101010 % 0A0F0A10101010101010121618181820181A181818181818121618181818 % 1818181818121010101010101010101818181817121018161818181A1818 % 181818181818181812101210101210121012101012101816181612101010 % 1012101010100A0F0A101010101010101216181800FF1012101010101010 % 0A1010080A10081010101818181A18181818181818101810181217181818 % 181818181010101010101010101218181818181818181818181818181818 % 181618181818181612161012101010101010101010121818181818181012 % 1010101010100A1010080A10081010101818181A18181818181818101810 % 181217181818181818181010101010101010101218181818181818181818 % 181818181818181618181818181612161012101010101010101010121818 % 1818181810121010101010100A1010080A10081010101818181A18181818 % 181818101810181217181818181818181010101010101010101218181818 % 181818181818181818181818181618181818181612161012101010101010 % 1010101218181818181810121010101010100A1010080A10081010101818 % 181A18181818181818101810181217181818181818181010101010101010 % 101218181818181818181818181818181818181618181818181612161012 % 1010101010101010101218181818181810121010101010100A1010080A10 % 081010101818181A18181818181818101810181217181818181818181010 % 101010101010101218181818181818181818181818181818181618181818 % 181612161012101010101010101010121818181818181012101010101010 % 0A1010080A10081010101818181A18181818181818101810181217181818 % 181818181010101010101010101218181818181818181818181818181818 % 181618181818181612161012101010101010101010121818181818181012 % 1010101010100A1010080A100810101018181800FF181216121818181010 % 10101008100810101012181818181A181818181818101210101818121818 % 12161216121010100A10101012181818181818181818181A181818181818 % 121018181818181210121018101812121612101010181818181818181216 % 12181818101010101008100810101012181818181A181818181818101210 % 10181812181812161216121010100A10101012181818181818181818181A % 181818181818121018181818181210121018101812121612101010181818 % 18181818121612181818101010101008100810101012181818181A181818 % 18181810121010181812181812161216121010100A101010121818181818 % 18181818181A181818181818121018181818181210121018101812121612 % 101010181818181818181216121818181010101010081008101010121818 % 18181A18181818181810121010181812181812161216121010100A101010 % 12181818181818181818181A181818181818121018181818181210121018 % 101812121612101010181818181818181216121818181010101010081008 % 10101012181818181A181818181818101210101818121818121612161210 % 10100A10101012181818181818181818181A181818181818121018181818 % 181210121018101812121612101010181818181818181216121818181010 % 10101008100810101012181818181A181818181818101210101818121818 % 12161216121010100A10101012181818181818181818181A181818181818 % 121018181818181210121018101812121612101010181818181818181216 % 12181818101010101008100810101012181800FF18161210181618101210 % 101010080A10101010101818181818181817121012161218101210101010 % 121018121012101010101012181818181A18181818181818181818181010 % 121818171818101810181018181818181818181210121218161818161210 % 181618101210101010080A10101010101818181818181817121012161218 % 101210101010121018121012101010101012181818181A18181818181818 % 181818181010121818171818101810181018181818181818181210121218 % 161818161210181618101210101010080A10101010101818181818181817 % 121012161218101210101010121018121012101010101012181818181A18 % 181818181818181818181010121818171818101810181018181818181818 % 181210121218161818161210181618101210101010080A10101010101818 % 181818181817121012161218101210101010121018121012101010101012 % 181818181A18181818181818181818181010121818171818101810181018 % 181818181818181210121218161818161210181618101210101010080A10 % 101010101818181818181817121012161218101210101010121018121012 % 101010101012181818181A18181818181818181818181010121818171818 % 101810181018181818181818181210121218161818161210181618101210 % 101010080A10101010101818181818181817121012161218101210101010 % 121018121012101010101012181818181A18181818181818181818181010 % 121818171818101810181018181818181818181210121218161818161210 % 181618101210101010080A10101010101800FF1012101012181818181012 % 101010101010101218181818181818181812101218121012101210121010 % 18121612101010101010101818181A181A18181A181A1818181810121010 % 10181218101218181818181818181A181818181210101012181012101012 % 181818181012101010101010101218181818181818181812101218121012 % 10121012101018121612101010101010101818181A181A18181A181A1818 % 18181012101010181218101218181818181818181A181818181210101012 % 181012101012181818181012101010101010101218181818181818181812 % 10121812101210121012101018121612101010101010101818181A181A18 % 181A181A181818181012101010181218101218181818181818181A181818 % 1812101010121810121010121818181810121010101010FF1012181818FF % 181818181812101218121012101210121010181216121010101010101018 % 18181A181A18181A181A1818181810121010101812181012181818181818 % 18181A181818181210101012181012101012181818181012101010101010 % 101218181818181818181812101218121012101210121010181216121010 % 10101010101818181A181A18181A181A1818181810121010101812181012 % 18181818181818181A181818181210101012181012101012181818181012 % 101010101010101218181818181818181812101218121012101210121010 % 18121612101010101010101818181A181A18181A181A1818181810121010 % 10181218101218181818181818181A181818181210101012181012101012 % 1818181810121010101010101012181800FF181012101210101012101210 % 100A08101010101012101218101810121010101010181818181010101010 % 101210121810181012121818181A18181818181818181818101010101010 % 101010121010101012101818181818181818181818181018181012101210 % 101012101210100A08101010101012101218101810121010101010181818 % 181010101010101210121810181012121818181A18181818181818181818 % 101010101010101010121010101012101818181818181818181818181018 % 181012101210101012101210100A08101010101012101218101810121010 % 101010181818181010101010101210121810181012121818181A18181818 % 181818181818101010101010101010121010101012101818181818181818 % 181818181018181012101210101012101210100A081010FF101012FF1218 % 101810121010101010181818181010101010101210121810181012121818 % 181A18181818181818181818101010101010101010121010101012101818 % 181818181818181818181018181012101210101012101210100A08101010 % 101012101218101810121010101010181818181010101010101210121810 % 181012121818181A18181818181818181818101010101010101010121010 % 101012101818181818181818181818181018181012101210101012101210 % 100A08101010101012101218101810121010101010181818181010101010 % 101210121810181012121818181A18181818181818181818101010101010 % 101010121010101012101818181818181818181818181018181012101210 % 101012101210100A0810101010101200FF18181810101010121012161010 % 101010101010101010121012121010101010101018181818181810181010 % 101012101816121816181818181818181818181818181810101010101010 % 101012101210121018181718181618181818181818181818181810101010 % 121012161010101010101010101010121012121010101010101018181818 % 181810181010101012101816121816181818181818181818181818181810 % 101010101010101012101210121018181718181618181818181818181818 % 181810101010121012161010101010101010101010121012121010101010 % 101018181818181810181010101012101816121816181818181818181818 % 181818181810101010101010101012101210121018181718181618181818 % 18181818181818181010101012101216101010101010FF101010FF121012 % 121010101010101018181818181810181010101012101816121816181818 % 181818181818181818181810101010101010101012101210121018181718 % 181618181818181818181818181810101010121012161010101010101010 % 101010121012121010101010101018181818181810181010101012101816 % 121816181818181818181818181818181810101010101010101012101210 % 121018181718181618181818181818181818181810101010121012161010 % 101010101010101010121012121010101010101018181818181810181010 % 101012101816121816181818181818181818181818181810101010101010 % 101012101210121018181718181618181818181818181818181810101010 % 121012161010101010101010101000FF1818171818181810101210121010 % 101010101010101010101010101010081010101218181818181818101010 % 101010181212161818181A16181818181618181818101210101010101210 % 181818101810181018121818181818181818181818181818171818181810 % 101210121010101010101010101010101010101010081010101218181818 % 181818101010101010181212161818181A16181818181618181818101210 % 101010101210181818101810181018121818181818181818181818181818 % 171818181810101210121010101010101010101010101010101010081010 % 101218181818181818101010101010181212161818181A16181818181618 % 181818101210101010101210181818101810181018121818181818181818 % 18181818181817181818181010121012101010101010FF10FF1010101010 % 101010081010101218181818181818101010101010181212161818181A16 % 181818181618181818101210101010101210181818101810181018121818 % 181818181818181818181818171818181810101210121010101010101010 % 101010101010101010081010101218181818181818101010101010181212 % 161818181A16181818181618181818101210101010101210181818101810 % 181018121818181818181818181818181818171818181810101210121010 % 101010101010101010101010101010081010101218181818181818101010 % 101010181212161818181A16181818181618181818101210101010101210 % 181818101810181018121818181818181818181818181818171818181810 % 1012101210101010101010101000FF121818181818181012101810181816 % 12181818121010101210101010100A081010181818181818181818121010 % 101012101012121818181818161818181818161310101010101012161818 % 181818181210121012101810181818181818181818121818181818181012 % 10181018181612181818121010101210101010100A081010181818181818 % 181818121010101012101012121818181818161818181818161310101010 % 101012161818181818181210121012101810181818181818181818121818 % 18181818101210181018181612181818121010101210101010100A081010 % 181818181818181818121010101012101012121818181818161818181818 % 161310101010101012161818181818181210121012101810181818181818 % 18181812181818181818101210181018181612181818FF10101012101010 % 10100A081010181818181818181818121010101012101012121818181818 % 161818181818161310101010101012161818181818181210121012101810 % 181818181818181818121818181818181012101810181816121818181210 % 10101210101010100A081010181818181818181818121010101012101012 % 121818181818161818181818161310101010101012161818181818181210 % 121012101810181818181818181818121818181818181012101810181816 % 12181818121010101210101010100A081010181818181818181818121010 % 101012101012121818181818161818181818161310101010101012161818 % 181818181210121012101810181818181818181818121818181818181012 % 10181018181612181818121000FF10121012101212101012121618181818 % 181818181818101818131610101010101210181818181818181010101010 % 101010101010121018181818181818181818101210101010101818181818 % 1A1818181010101010121012101812161818181010121012101212101012 % 121618181818181818181818101818131610101010101210181818181818 % 181010101010101010101010121018181818181818181818101210101010 % 1018181818181A1818181010101010121012101812161818181010121012 % 101212101012121618181818181818181818101818131610101010101210 % 181818181818181010101010101010101010121018181818181818181818 % 1012101010101018181818181A1818181010101010121012101812161818 % 181010121012101212101012121618181818181818FF1818101818131610 % 101010101210181818181818181010101010101010101010121018181818 % 1818181818181012101010101018181818181A1818181010101010121012 % 101812161818181010121012101212101012121618181818181818181818 % 101818131610101010101210181818181818181010101010101010101010 % 1210181818181818181818181012101010101018181818181A1818181010 % 101010121012101812161818181010121012101212101012121618181818 % 181818181818101818131610101010101210181818181818181010101010 % 101010101010121018181818181818181818101210101010101818181818 % 1A1818181010101010121012101812161818181010121012101212101012 % 121618181818181818181800FF1210101210101010181010121818181818 % 181A181A1818181718181218181810101810181218181012101210101818 % 1010101010101212181818181818181818181012101010101818181A1818 % 181818121010101010121010101012101818101210101210101010181010 % 121818181818181A181A1818181718181218181810101810181218181012 % 101210101818101010101010121218181818181818181818101210101010 % 1818181A1818181818121010101010121010101012101818101210101210 % 101010181010121818181818181A181A1818181718181218181810101810 % 181218181012101210101818101010101010121218181818181818181818 % 1012101010101818181A1818181818121010101010121010101012101818 % 10121010121010101018101012181818181818FF18FF1818181718181218 % 181810101810181218181012101210101818101010101010121218181818 % 1818181818181012101010101818181A1818181818121010101010121010 % 101012101818101210101210101010181010121818181818181A181A1818 % 181718181218181810101810181218181012101210101818101010101010 % 1212181818181818181818181012101010101818181A1818181818121010 % 101010121010101012101818101210101210101010181010121818181818 % 181A181A1818181718181218181810101810181218181012101210101818 % 1010101010101212181818181818181818181012101010101818181A1818 % 181818121010101010121010101012101818101210101210101010181010 % 121818181818181A181A00FF181812101012101212101210101818161818 % 1A1818181818181818171818181612121012101010181810101212181018 % 181010101210101818181A18181818181816121012121818181818181A18 % 181810100B0E10101010100E101010121818181812101012101212101210 % 1018181618181A1818181818181818171818181612121012101010181810 % 101212181018181010101210101818181A18181818181816121012121818 % 181818181A18181810100B0E10101010100E101010121818181812101012 % 1012121012101018181618181A1818181818181818171818181612121012 % 101010181810101212181018181010101210101818181A18181818181816 % 121012121818181818181A18181810100B0E10101010100E101010121818 % 1818121010121012121012101018181618FF1A1818FF1818181818171818 % 181612121012101010181810101212181018181010101210101818181A18 % 181818181816121012121818181818181A18181810100B0E10101010100E % 1010101218181818121010121012121012101018181618181A1818181818 % 181818171818181612121012101010181810101212181018181010101210 % 101818181A18181818181816121012121818181818181A18181810100B0E % 10101010100E101010121818181812101012101212101210101818161818 % 1A1818181818181818171818181612121012101010181810101212181018 % 181010101210101818181A18181818181816121012121818181818181A18 % 181810100B0E10101010100E101010121818181812101012101212101210 % 1018181618181A181800FF18181818121010181010101012181810101818 % 181818121012101818181818181810101010101018181012101010181818 % 18181612161218181818181818181818181018131618181818181A181A18 % 1812101010101010100A100A101012161818181818121010181010101012 % 181810101818181818121012101818181818181810101010101018181012 % 101010181818181816121612181818181818181818181810181316181818 % 18181A181A181812101010101010100A100A101012161818181818121010 % 181010101012181810101818181818121012101818181818181810101010 % 101018181012101010181818181816121612181818181818181818181810 % 18131618181818181A181A181812101010101010100A100A101012161818 % 18181812101018101010101218181010FF181818FF121012101818181818 % 181810101010101018181012101010181818181816121612181818181818 % 18181818181018131618181818181A181A181812101010101010100A100A % 101012161818181818121010181010101012181810101818181818121012 % 101818181818181810101010101018181012101010181818181816121612 % 18181818181818181818181018131618181818181A181A18181210101010 % 1010100A100A101012161818181818121010181010101012181810101818 % 181818121012101818181818181810101010101018181012101010181818 % 18181612161218181818181818181818181018131618181818181A181A18 % 1812101010101010100A100A101012161818181818121010181010101012 % 181810101818181800FF1618181818181018181810121010101818161818 % 18161810101018131618181A181818121010101810181210181813181818 % 18181818181818181818181818181018101216181818181A181A18181818 % 1818181810100A1010101010101012181618181818181018181810121010 % 10181816181818161810101018131618181A181818121010101810181210 % 18181318181818181818181818181818181818181018101216181818181A % 181A181818181818181810100A1010101010101012181618181818181018 % 18181012101010181816181818161810101018131618181A181818121010 % 101810181210181813181818181818181818181818181818181810181012 % 16181818181A181A181818181818181810100A1010101010101012181618 % 1818181810181818101210101018FF1618181816FF10101018131618181A % 181818121010101810181210181813181818181818181818181818181818 % 18181018101216181818181A181A181818181818181810100A1010101010 % 101012181618181818181018181810121010101818161818181618101010 % 18131618181A181818121010101810181210181813181818181818181818 % 18181818181818181018101216181818181A181A18181818181818181010 % 0A1010101010101012181618181818181018181810121010101818161818 % 18161810101018131618181A181818121010101810181210181813181818 % 18181818181818181818181818181018101216181818181A181A18181818 % 1818181810100A1010101010101012181618181818181018181810121010 % 1018181618181800FF121818181818181818171210101010121012181018 % 121818181812161812161818181818101810121012161818101818181818 % 1818181818181818181A1818181818181818181818181818181818181216 % 181812101010121010101010101012121818181818181818171210101010 % 121012181018121818181812161812161818181818101810121012161818 % 1018181818181818181818181818181A1818181818181818181818181818 % 181818181216181812101010121010101010101012121818181818181818 % 171210101010121012181018121818181812161812161818181818101810 % 1210121618181018181818181818181818181818181A1818181818181818 % 181818181818181818181216181812101010121010101010101012121818 % 181818181818171210101010121012181018121818181812161812161818 % 1818181018101210121618181018181818181818181818181818181A1818 % 181818181818181818181818181818181216181812101010121010101010 % 101012121818181818181818171210101010121012181018121818181812 % 161812161818181818101810121012161818101818181818181818181818 % 1818181A1818181818181818181818181818181818181216181812101010 % 121010101010101012121818181818181818171210101010121012181018 % 121818181812161812161818181818101810121012161818101818181818 % 1818181818181818181A1818181818181818181818181818181818181216 % 181812101010121010101010101012121818181818181818171210101010 % 12101218101800FF10121612181610181818121612101012101210121618 % 181818181818121018101216181618181810181012101210181618181818 % 18181A181A18181818181818181818181818181018181818181812101012 % 161818121018101010101010101010121612181610181818121612101012 % 101210121618181818181818121018101216181618181810181012101210 % 18161818181818181A181A18181818181818181818181818181018181818 % 181812101012161818121018101010101010101010121612181610181818 % 121612101012101210121618181818181818121018101216181618181810 % 18101210121018161818181818181A181A18181818181818181818181818 % 181018181818181812101012161818121018101010101010101010121612 % 181610181818121612101012101210121618181818181818121018101216 % 18161818181018101210121018161818181818181A181A18181818181818 % 181818181818181018181818181812101012161818121018101010101010 % 101010121612181610181818121612101012101210121618181818181818 % 12101810121618161818181018101210121018161818181818181A181A18 % 181818181818181818181818181018181818181812101012161818121018 % 101010101010101010121612181610181818121612101012101210121618 % 181818181818121018101216181618181810181012101210181618181818 % 18181A181A18181818181818181818181818181018181818181812101012 % 161818121018101010101010101010121612181610181818121612101012 % 101210121600FF1010121012181218161810121012101010101010121216 % 181818161810181010121012181818181612101810121012121018181818 % 18181818181A18181A1E181A181818181818181818181818181810101210 % 181216181810121010121010101010121012181218161810121012101010 % 101010121216181818161810181010121012181818181612101810121012 % 12101818181818181818181A18181A1E181A181818181818181818181818 % 181810101210181216181810121010121010101010121012181218161810 % 121012101010101010121216181818161810181010121012181818181612 % 10181012101212101818181818181818181A18181A1E181A181818181818 % 181818181818181810101210181216181810121010121010101010121012 % 181218161810121012101010101010121216181818161810181010121012 % 18181818161210181012101212101818181818181818181A18181A1E181A % 181818181818181818181818181810101210181216181810121010121010 % 101010121012181218161810121012101010101010121216181818161810 % 18101012101218181818161210181012101212101818181818181818181A % 18181A1E181A181818181818181818181818181810101210181216181810 % 121010121010101010121012181218161810121012101010101010121216 % 181818161810181010121012181818181612101810121012121018181818 % 18181818181A18181A1E181A181818181818181818181818181810101210 % 181216181810121010121010101010121012181218161810121012101010 % 1010101200FF101010101012161218101812161210101012101210101210 % 181218181818181810181810121210121810121010101010121012181818 % 1818181818181A181A18181818181818181818181A181818181010121012 % 101210121810121010101210101010101012161218101812161210101012 % 101210101210181218181818181810181810121210121810121010101010 % 1210121818181818181818181A181A18181818181818181818181A181818 % 181010121012101210121810121010101210101010101012161218101812 % 161210101012101210101210181218181818181810181810121210121810 % 1210101010101210121818181818181818181A181A181818181818181818 % 18181A181818181010121012101210121810121010101210101010101012 % 161218101812161210101012101210101210181218181818181810181810 % 1212101218101210101010101210121818181818181818181A181A181818 % 18181818181818181A181818181010121012101210121810121010101210 % 101010101012161218101812161210101012101210101210181218181818 % 181810181810121210121810121010101010121012181818181818181818 % 1A181A18181818181818181818181A181818181010121012101210121810 % 121010101210101010101012161218101812161210101012101210101210 % 181218181818181810181810121210121810121010101010121012181818 % 1818181818181A181A18181818181818181818181A181818181010121012 % 101210121810121010101210101010101012161218101812161210101012 % 10121000FF10101012181818161818181018161810101010101012101210 % 101218161818181818101210101018161210121010101010101210121612 % 181818181A18201E1A181A18181818181818181818181818181812101010 % 101018101818181812101010101012181818161818181018161810101010 % 101012101210101218161818181818101210101018161210121010101010 % 101210121612181818181A18201E1A181A18181818181818181818181818 % 181812101010101018101818181812101010101012181818161818181018 % 161810101010101012101210101218161818181818101210101018161210 % 121010101010101210121612181818181A18201E1A181A18181818181818 % 181818181818181812101010101018101818181812101010101012181818 % 161818181018161810101010101012101210101218161818181818101210 % 101018161210121010101010101210121612181818181A18201E1A181A18 % 181818181818181818181818181812101010101018101818181812101010 % 101012181818161818181018161810101010101012101210101218161818 % 181818101210101018161210121010101010101210121612181818181A18 % 201E1A181A18181818181818181818181818181812101010101018101818 % 181812101010101012181818161818181018161810101010101012101210 % 101218161818181818101210101018161210121010101010101210121612 % 181818181A18201E1A181A18181818181818181818181818181812101010 % 101018101818181812101010101012181818161818181018161810101010 % 101000FF1810121018181818121810181818181810121012101010101012 % 101012121018181018101010101812101010101010101010101010101018 % 18181818181A181A18181818181613181818181818181818121010101010 % 101012101818181818181810121018181818121810181818181810121012 % 101010101012101012121018181018101010101812101010101010101010 % 10101010101818181818181A181A18181818181613181818181818181818 % 121010101010101012101818181818181810121018181818121810181818 % 181810121012101010101012101012121018181018101010101812101010 % 10101010101010101010101818181818181A181A18181818181613181818 % 181818181818121010101010101012101818181818181810121018181818 % 121810181818181810121012101010101012101012121018181018101010 % 10181210101010101010101010101010101818181818181A181A18181818 % 181613181818181818181818121010101010101012101818181818181810 % 121018181818121810181818181810121012101010101012101012121018 % 18101810101010181210101010101010101010101010101818181818181A % 181A18181818181613181818181818181818121010101010101012101818 % 181818181810121018181818121810181818181810121012101010101012 % 101012121018181018101010101812101010101010101010101010101018 % 18181818181A181A18181818181613181818181818181818121010101010 % 101012101818181818181810121018181818121810181818181810121012 % 1000FF1A1818181618181816181818181618181818101010101012121012 % 101010101218101210121010181016121010101010101010101010101018 % 18181818181820181A181818121612101818181012161216101010101012 % 1010181818181818181A1818181618181816181818181618181818101010 % 101012121012101010101218101210121010181016121010101010101010 % 10101010101818181818181820181A181818121612101818181012161216 % 1010101010121010181818181818181A1818181618181816181818181618 % 181818101010101012121012101010101218101210121010181016121010 % 10101010101010101010101818181818181820181A181818121612101818 % 1810121612161010101010121010181818181818181A1818181618181816 % 181818181618181818101010101012121012101010101218101210121010 % 18101612101010101010101010101010101818181818181820181A181818 % 1216121018181810121612161010101010121010181818181818181A1818 % 181618181816181818181618181818101010101012121012101010101218 % 101210121010181016121010101010101010101010101018181818181818 % 20181A181818121612101818181012161216101010101012101018181818 % 1818181A1818181618181816181818181618181818101010101012121012 % 101010101218101210121010181016121010101010101010101010101018 % 18181818181820181A181818121612101818181012161216101010101012 % 1010181818181818181A1818181618181816181818181618181818101010 % 00FF181818181A1818181810181018181816181216121018101010121010 % 101010101012101216181812181818181810101010101010101010101210 % 18181A20211818181818101612101210101210181018181310100A080810 % 10101216181A1818181818181A1818181810181018181816181216121018 % 101010121010101010101012101216181812181818181810101010101010 % 10101010121018181A202118181818181016121012101012101810181813 % 10100A08081010101216181A1818181818181A1818181810181018181816 % 181216121018101010121010101010101012101216181812181818181810 % 10101010101010101010121018181A202118181818181016121012101012 % 10181018181310100A08081010101216181A1818181818181A1818181810 % 181018181816181216121018101010121010101010101012101216181812 % 18181818181010101010101010101010121018181A202118181818181016 % 12101210101210181018181310100A08081010101216181A181818181818 % 1A1818181810181018181816181216121018101010121010101010101012 % 10121618181218181818181010101010101010101010121018181A202118 % 18181818101612101210101210181018181310100A08081010101216181A % 1818181818181A1818181810181018181816181216121018101010121010 % 101010101012101216181812181818181810101010101010101010101210 % 18181A20211818181818101612101210101210181018181310100A080810 % 10101216181A1818181818181A1818181810181018181816181216121000 % FF1818181818181A18101812121212181818181012101210101216181818 % 181210121018101812181612181618181818101010101010101010101218 % 1818201A1818181212181218101810121018101218161818101010081010 % 10181818181A181818181818181A18101812121212181818181012101210 % 101216181818181210121018101812181612181618181818101010101010 % 1010101012181818201A1818181212181218101810121018101218161818 % 10101008101010181818181A181818181818181A18101812121212181818 % 181012101210101216181818181210121018101812181612181618181818 % 1010101010101010101012181818201A1818181212181218101810121018 % 10121816181810101008101010181818181A181818181818181A18101812 % 121212181818181012101210101216181818181210121018101812181612 % 1816181818181010101010101010101012181818201A1818181212181218 % 10181012101810121816181810101008101010181818181A181818181818 % 181A18101812121212181818181012101210101216181818181210121018 % 1018121816121816181818181010101010101010101012181818201A1818 % 18121218121810181012101810121816181810101008101010181818181A % 181818181818181A18101812121212181818181012101210101216181818 % 181210121018101812181612181618181818101010101010101010101218 % 1818201A1818181212181218101810121018101218161818101010081010 % 10181818181A181818181818181A181018121212121818181810121000FF % 1A181A181A18181818121010101010181210101012101216121818181818 % 1818181818121618121012101212161818101010121010100E1010101218 % 181818181810101012101818181818101210121018181818121010101012 % 1818181A18181A181A181A18181818121010101010181210101012101216 % 121818181818181818181812161812101210121216181810101012101010 % 0E1010101218181818181810101012101818181818101210121018181818 % 1210101010121818181A18181A181A181A18181818121010101010181210 % 101012101216121818181818181818181812161812101210121216181810 % 1010121010100E1010101218181818181810101012101818181818101210 % 1210181818181210101010121818181A18181A181A181A18181818121010 % 101010181210101012101216121818181818181818181812161812101210 % 1212161818101010121010100E1010101218181818181810101012101818 % 1818181012101210181818181210101010121818181A18181A181A181A18 % 181818121010101010181210101012101216121818181818181818181812 % 1618121012101212161818101010121010100E1010101218181818181810 % 1010121018181818181012101210181818181210101010121818181A1818 % 1A181A181A18181818121010101010181210101012101216121818181818 % 1818181818121618121012101212161818101010121010100E1010101218 % 181818181810101012101818181818101210121018181818121010101012 % 1818181A18181A181A181A1818181812101010101018121010101200FF18 % 181818181818181810101010101018181012101010121012161818181818 % 181818181818131612101010101212181012101010101010101010101216 % 181812101210121012161818181818121010101012181818181210121018 % 18181A181818181818181818181810101010101018181012101010121012 % 161818181818181818181818131612101010101212181012101010101010 % 101010101216181812101210121012161818181818121010101012181818 % 18121012101818181A181818181818181818181810101010101018181012 % 101010121012161818181818181818181818131612101010101212181012 % 101010101010101010101216181812101210121012161818181818121010 % 10101218181818121012101818181A181818181818181818181810101010 % 101018181012101010121012161818181818181818181818131612101010 % 101212181012101010101010101010101216181812101210121012161818 % 18181812101010101218181818121012101818181A181818181818181818 % 181810101010101018181012101010121012161818181818181818181818 % 131612101010101212181012101010101010101010101216181812101210 % 12101216181818181812101010101218181818121012101818181A181818 % 181818181818181810101010101018181012101010121012161818181818 % 181818181818131612101010101212181012101010101010101010101216 % 181812101210121012161818181818121010101012181818181210121018 % 18181A181818181818181818181810101010101018181012101000FF1818 % 181818181818121010101010101818101010101218101012181818181818 % 181818181816181818121010101012161218101012101010101010121012 % 101010101010101212181818181818101210101010101216181216181818 % 18181A181818181818181818121010101010101818101010101218101012 % 181818181818181818181816181818121010101012161218101012101010 % 101010121012101010101010101212181818181818101210101010101216 % 18121618181818181A181818181818181818121010101010101818101010 % 101218101012181818181818181818181816181818121010101012161218 % 101012101010101010121012101010101010101212181818181818101210 % 10101010121618121618181818181A181818181818181818121010101010 % 101818101010101218101012181818181818181818181816181818121010 % 101012161218101012101010101010121012101010101010101212181818 % 18181810121010101010121618121618181818181A181818181818181818 % 121010101010101818101010101218101012181818181818181818181816 % 181818121010101012161218101012101010101010121012101010101010 % 10121218181818181810121010101010121618121618181818181A181818 % 181818181818121010101010101818101010101218101012181818181818 % 181818181816181818121010101012161218101012101010101010121012 % 101010101010101212181818181818101210101010101216181216181818 % 18181A1818181818181818181210101010101018181010101000FF181818 % 181818181810121010101010181618181216121010101210181810121818 % 181818181818181818161210101018121612101010101010121010121010 % 12101010101010101818181A181812101010100808101012101812171818 % 181818181818181818181810121010101010181618181216121010101210 % 181810121818181818181818181818161210101018121612101010101010 % 12101012101012101010101010101818181A181812101010100808101012 % 101812171818181818181818181818181810121010101010181618181216 % 121010101210181810121818181818181818181818161210101018121612 % 10101010101012101012101012101010101010101818181A181812101010 % 100808101012101812171818181818181818181818181810121010101010 % 181618181216121010101210181810121818181818181818181818161210 % 10101812161210101010101012101012101012101010101010101818181A % 181812101010100808101012101812171818181818181818181818181810 % 121010101010181618181216121010101210181810121818181818181818 % 181818161210101018121612101010101010121010121010121010101010 % 10101818181A181812101010100808101012101812171818181818181818 % 181818181810121010101010181618181216121010101210181810121818 % 181818181818181818161210101018121612101010101010121010121010 % 12101010101010101818181A181812101010100808101012101812171818 % 18181818181818181818181012101010101018161818121600FF12161818 % 101810181210121010101212181818181812101010121613101210181618 % 181818181818181818181010101216121012101216181810181012101216 % 12101010FFFFFFFF18181818FFFFFFFF1010100AFFFFFFFF121612181818 % 181812161818101810181210121010101212181818181812101010121613 % FFFFFFFFFFFF18181818FFFF1818181810FFFFFFFF121012101216181810 % 181012101216121010101010101818181818181818101010100A10FFFFFF % FFFFFF181818FFFFFFFF18181018FFFFFFFF121010101212181818181812 % 1010101216131012101816181818181818181818181810101012161210FF % FFFFFF1818101810FFFFFFFF121010101010101818181818181818101010 % 100A10101010121612181818181812161818101810181210121010FFFFFF % FF1818181812101010121613101210181618181818181818181818181010 % 10121612101210121618181018101210121612FFFFFFFF1010181818FFFF % FFFF18101010100A10101010121612181818181812161818101810181210 % 12101010121218181818181210FFFFFFFFFFFF121018FFFFFFFF18181818 % FFFFFFFF1010101216121012101216181810181012101216121010101010 % 10181818181818181810FFFFFFFFFFFF10101216FFFF1818181812FFFFFF % FF1810181210121010101212181818181812101010121613101210181618 % 181818181818181818FFFFFFFF12161210FFFFFFFF18181018FFFFFFFF16 % 121010101010101818181818181818101010100A10101010121612181818 % 181812161818101810181210121010101212181818181800FF1012101012 % 161210101010121012161818181A18181210181218181818101218121216 % 181818181218181818181012101810181018101218181818181216121812 % 1010FF101010FFFF181AFFFF1818FFFF1010FFFF100AFFFF101818181818 % 121012101012161210101010121012161818181A18181210181218181818 % FFFF18121216181818FFFF18181818FFFF1210FFFF181018101218181818 % 1812161218121010101010101818181A20181818101210101010100AFFFF % 10181818FFFF1210FFFF1012FFFF1010FFFF121012161818181A18181210 % 181218181818101218121216181818181218181818181012101810181018 % 10FFFF181818FFFF1612FFFF1010101010101818181A2018181810121010 % 1010100A101210181818181812101210101216121010101012FFFF1618FF % FF1A18181210181218181818101218121216181818181218181818181012 % 101810181018101218181818181216121812101010FFFF101818FFFF2018 % FFFF101210101010100A1012101818181818121012101012161210101010 % 121012161818181A181812101812FFFF18181012FFFF1216FFFF1818FFFF % 1818FFFF1012101810181018101218181818181216121812101010101010 % 1818181A201818181012FFFF1010100A101210FFFF18181812FFFF1010FF % FF1210101010121012161818181A18181210181218181818101218121216 % 18181818121818FF181810FFFF1810FFFF1810FFFF1818FFFF1216FFFF12 % 1010101010101818181A20181818101210101010100A1012101818181818 % 121012101012161210101010121012161818181A181800FF181818181810 % 1216121612161218181818181A1818181010101010121018101010101218 % 18181810121010101018181012101812181816181A181818181816181818 % 1818101010FFFF1216FFFF1818FFFF1210FFFF1010FFFF10101012101818 % 1818181818101216121612161218181818181A1818181010101010121018 % FFFF10101218181818FFFF101010FFFF1810FFFF1812181816181A181818 % 181816181818181810101010101216181818181810121010101010FFFF10 % 101012FFFF1818FFFF1818FFFF1612FFFF161218181818181A1818181010 % 101010121018101010101218181818101210101010181810121018121818 % 16FFFF1818FFFF1816FFFF18181810101010101216181818181810121010 % 101010101010101012101818181818181810121612161216FFFF1818FFFF % 1A1818181010101010121018101010101218181818101210101010181810 % 12101812181816181A181818181816181818181810FFFF1010FFFF1818FF % FF1810121010101010101010101012101818181818181810121612161216 % 1218181818181A181818101010FFFF12101810FFFF1012FFFF1818FFFF10 % 10FFFF18181012101812181816181A181818181816181818181810101010 % 10121618181818181012FFFF10101010101010FFFF101818FFFF1818FFFF % 1216121612161218181818181A1818181010101010121018101010101218 % 18181810121010101018FFFF1210FFFF1818FFFF1A18FFFF1818FFFF1818 % 181810101010101216181818181810121010101010101010101012101818 % 1818181818101216121612161218181818181A181800FF1A181818101210 % 181012101216181818181818181818181010101010101010101010101216 % 1818181010121012181810101216121618181818181AFFFFFFFFFFFF1818 % 16181818FFFF1012FFFF1810FFFF1010FFFF1210FFFF101210121618181A % 18181810121018101210121618181818181818FFFFFFFFFFFF1010101010 % FFFF101012161818FFFF101210FFFF1810FFFF16121618181818181A1818 % 18181818181816181818101010121810FFFFFFFFFFFF10101210FFFF1012 % 1012FFFF181AFFFF1810FFFF1810FFFF1216181818181818181818181010 % 101010101010101010101216181818101012FFFFFFFFFFFF121612FFFFFF % FFFF181AFFFF1818FFFF1818161818181010101218101810181210101010 % 12101010101210121618181A1818181012101810121012FFFF1818FFFF18 % 181818181010101010101010101010101216181818101012101218181010 % 1216121618181818181A18181818181818FFFFFFFFFF1010FFFF1810FFFF % 18121010101012101010101210121618181A181818101210181012101216 % 181818181818181818181010FFFF10101010FFFF1010FFFF1818FFFF1012 % FFFF181810101216121618181818181A1818181818181818161818181010 % 10121810181018121010FFFF121010101012FFFF161818FFFF1818FFFF10 % 181012101216181818181818181818181010101010101010101010101216 % 181818101012101218FFFF1012FFFF1618FFFF1818FFFF1818FFFF181818 % 16181818101010121810181018121010101012101010101210121618181A % 181818101210181012101216181818181818181800FF1818181818111813 % 161216121818181818181A18181818101010101010100A10101010101218 % 181818181012161218101210181318181818181818181818181012161318 % 18FFFFFF101012FFFFFFFFFF101012FFFF1618FFFF12161818FFFF181818 % 181818111813161216121818181818181A18181818101010101010100A10 % FFFF1010121818FFFF181012FFFF1810FFFF18131818FFFF181818181818 % 18101216131818181812101012101012101810101210121618FFFF121618 % 1818FFFFFFFF181818FFFF1316FFFF12181818FFFF181A18181818101010 % 101010100A1010101010121818181818101216121810121018FFFF1818FF % FF1818FFFF1818FFFF16131818FFFF121010121010121018101012101216 % 18161812161818181818181818181811181316121612FFFF1818FFFF1A18 % 1818FFFF1010101010100A10101010101218181818181012161218101210 % 181318181818181818181818181012FFFF1818FFFF1210FFFF1010FFFF18 % 101012FFFF16181618121618181818181818181818111813161216121818 % 181818181A181818181010FFFF1010100A10FFFFFFFF121818FFFF1810FF % FF12181012FFFF1318181818181818181818181012161318181818121010 % 12101012101810101210FFFF1816181216FFFF181818FFFF1818FFFF1813 % 1612FFFF1818181818181A18181818101010101010100A10101010101218 % 181818181012FFFFFF101210FFFFFFFFFF181818FFFF1818FFFF12161318 % FFFF18121010121010121018101012101216181618121618181818181818 % 181818111813161216121818181818181A181800FF1A1818181818161818 % 1210121618181A181A181818181810101010101010101010081010101818 % 181818181018161216121810181018101818181818181810101012181818 % 1818FFFF1010FFFF121012101210FFFF1818FFFF181818FF1818FF1A1818 % 1818181618181210121618181A181A18181818181010101010FFFF1010FF % FF101010181818FFFF1810FFFF1216FFFF101810FF1018FF181818181810 % 101012181818181818181010101012101210121012161818FFFF18181818 % FFFF181AFFFF1818FFFF1818FFFF121618FF1A18FF181818181810101010 % 101010101010081010101818181818181018161216121810FFFF1810FFFF % 1818FFFF1810FFFF121818FF1818FF181010101012101210121012161818 % 1818181818181818181A1818181818161818121012FFFF181AFFFF181818 % FF1810FF1010101010101010081010101818181818181018161216121810 % 1810181018181818181818101010FFFF1818FFFF1818FFFF1010FFFF1210 % 12FF1216FF181818181818181818181A1818181818161818121012161818 % 1A181A18181818181010FFFF10101010FFFF0810FFFF1818FFFF1818FFFF % 161216FF1810FF1018101818181818181810101012181818181818181010 % 1010121012FFFF1012FFFF181818181818FFFF1818FFFF1818FFFF161818 % FF1012FF18181A181A181818181810101010101010101010081010101818 % 18181818101816FFFF1218FFFF101810181818FFFF1818FFFF101218FF18 % 18FF181810101010121012101210121618181818181818181818181A1818 % 1818181618181210121618181A181A18181800FF18181818181818181712 % 16181818181818181A181818181118121012101010101010080E10101818 % 181818181210121018101810121812101818181817181218181816FF1818 % 18FFFF181810FFFF1810181012FFFF1818FFFF181818FF1818FF18181818 % 18181818171216181818181818181A181818181118121012FFFF1010FFFF % 080EFF101818FFFF1818FFFF1210FFFF181012FF1210FF18181817181218 % 181816181818181818181810121018101810121018FFFFFFFF18181818FF % FF1818FFFF1818FFFF1817FFFF181818FF1818FF1A181818181118121012 % 101010101010080E101018181818181812101210181018FFFF1812FFFF18 % 18FFFF1812FFFF181618FF1818FF18181810121018101810121018181818 % 1818181818181818181818181818181817121618FFFF1818FFFF1A1818FF % 1811FF121012101010101010080E10101818181818181210121018101810 % 12181210181818181718121818FFFF1818FFFF1818FFFF1012FFFF101810 % FF1018FF1818181818181818181818181818181818181712161818181818 % 18181A18181818FFFFFFFF12101010FFFF1008FFFF1018FFFF1818FFFF10 % 1210FF1018FF121812101818181817181218181816181818181818181810 % 12101810FFFF1210FFFF1818FF181818FFFF1818FFFF1818FFFF181817FF % 1618FF18181818181A181818181118121012101010101010080E10101818 % 1818FF181210FFFF181018FFFF1812101818FFFF1718FFFF181816FF1818 % FF1818181810121018101810121018181818181818181818181818181818 % 18181818171216181818181818181A181800FF18181818181A1818181812 % 181818181818181818181618181612161810121012101010101010101218 % 161818181018181316131810121010121612181812161818181818FFFFFF % FF1818181718FFFFFFFF101210FFFFFFFF1818181818FFFF181818181818 % 1A1818181812181818181818181818181618181612161810FFFFFFFF1010 % 10FFFFFFFFFFFF181818FFFFFFFF1613181012FFFF121612181812161818 % 18181810181218181818171818181210101210121218FFFF1818181818FF % FFFFFF1818181AFFFFFFFF1218181818FFFF181818181618181612161810 % 1210121010101010101012181618181810181813161318FFFFFFFF121612 % 18FFFFFFFF1818181810FFFF181818181718181812101012101212181818 % 1818181818181818181818181A18181818121818FFFFFFFF1818181816FF % FF1612161810121012101010101010101218161818181018181316131810 % 12101012161218181216181818FFFFFFFF12181818FFFFFFFF1812101012 % FFFF121818181818181818181818181818181A1818181812181818181818 % 1818181816181816FFFF1810121012FFFFFFFF10101012FFFFFFFF181018 % 1813FFFF1810121010121612181812161818181818101812181818181718 % 18181210FFFFFFFF121818FFFFFFFFFFFF181818FFFFFFFF1A18181818FF % FF1818181818181818181618181612161810121012101010101010101218 % 1618FFFFFFFF1813161318FFFFFFFF121612FFFFFFFF1818181818FFFF12 % 181818181718181812101012101212181818181818181818181818181818 % 1A18181818121818181818181818181800FF18181A181818181818181718 % 181818121818181818121210121012101216121012101210101010101012 % 181613101216181812161210121010121618181018181818181816121618 % 18181818181612161210101010121018181818181A18181818181A181818 % 181818181718181818121818181818121210121012101216121012101210 % 101010101012181613101216181812161210121010121618181018181818 % 18181612161818181818181612161210101010121018181818181A181818 % 18181A181818181818181718181818121818181818121210121012101216 % 121012101210101010101012181613101216181812161210121010121618 % 181018181818181816121618181818181816121612101010101210181818 % 18181A18181818181A181818181818181718181818121818181818121210 % 121012101216121012101210101010101012181613101216181812161210 % 121010121618181018181818181816121618181818181816121612101010 % 10121018181818181A18181818181A181818181818181718181818121818 % 181818121210121012101216121012101210101010101012181613101216 % 181812161210121010121618181018181818181816121618181818181816 % 12161210101010121018181818181A18181818181A181818181818181718 % 181818121818181818121210121012101216121012101210101010101012 % 181613101216181812161210121010121618181018181818181816121618 % 18181818181612161210101010121018181818181A18181818181A181818 % 18181818171818181812181818181800FF1818181818181A181818181818 % 181818161818161810101010101010121012181612101010100A10101210 % 181810121818181018101010101010121810181018181618181818181018 % 1818181612101810121010101010181612181818181A181818181818181A % 181818181818181818161818161810101010101010121012181612101010 % 100A10101210181810121818181018101010101010121810181018181618 % 1818181810181818181612101810121010101010181612181818181A1818 % 18181818181A181818181818181818161818161810101010101010121012 % 181612101010100A10101210181810121818181018101010101010121810 % 181018181618181818181018181818161210181012101010101018161218 % 1818181A181818181818181A181818181818181818161818161810101010 % 101010121012181612101010100A10101210181810121818181018101010 % 101010121810181018181618181818181018181818161210181012101010 % 1010181612181818181A181818181818181A181818181818181818161818 % 161810101010101010121012181612101010100A10101210181810121818 % 181018101010101010121810181018181618181818181018181818161210 % 1810121010101010181612181818181A181818181818181A181818181818 % 181818161818161810101010101010121012181612101010100A10101210 % 181810121818181018101010101010121810181018181618181818181018 % 1818181612101810121010101010181612181818181A181818181818181A % 181818181818181818161818161800FF181818181A181818181818181818 % 181818181818181818101012101010101018121810181010101012161818 % 181818161817181818181810101010101218181012121818181812101210 % 12101210121816121010101010101010101216181810181818181A181818 % 181818181818181818181818181818101012101010101018121810181010 % 101012161818181818161817181818181810101010101218181012121818 % 181812101210121012101218161210101010101010101012161818101818 % 18181A181818181818181818181818181818181818101012101010101018 % 121810181010101012161818181818161817181818181810101010101218 % 181012121818181812101210121012101218161210101010101010101012 % 16181810181818181A181818181818181818181818181818181818101012 % 101010101018121810181010101012161818181818161817181818181810 % 101010101218181012121818181812101210121012101218161210101010 % 10101010101216181810181818181A181818181818181818181818181818 % 181818101012101010101018121810181010101012161818181818161817 % 181818181810101010101218181012121818181812101210121012101218 % 16121010101010101010101216181810181818181A181818181818181818 % 181818181818181818101012101010101018121810181010101012161818 % 181818161817181818181810101010101218181012121818181812101210 % 12101210121816121010101010101010101216181810181818181A181818 % 1818181818181818181818181800FF1818181A1E181A1818181612101218 % 181818181818101810121010101010101218171818101210101018181818 % 181818181818171818161012101210121010101010101010121612161216 % 1218101810121010101010101010101010121810181818181A1E181A1818 % 181612101218181818181818101810121010101010101218171818101210 % 101018181818181818181818171818161012101210121010101010101010 % 121612161216121810181012101010101010101010101012181018181818 % 1A1E181A1818181612101218181818181818101810121010101010101218 % 171818101210101018181818181818181818171818161012101210121010 % 101010101010121612161216121810181012101010101010101010101012 % 1810181818181A1E181A1818181612101218181818181818101810121010 % 101010101218171818101210101018181818181818181818171818161012 % 101210121010101010101010121612161216121810181012101010101010 % 1010101010121810181818181A1E181A1818181612101218181818181818 % 101810121010101010101218171818101210101018181818181818181818 % 171818161012101210121010101010101010121612161216121810181012 % 1010101010101010101010121810181818181A1E181A1818181612101218 % 181818181818101810121010101010101218171818101210101018181818 % 181818181818171818161012101210121010101010101010121612161216 % 1218101810121010101010101010101010121810181818181A1E181A1818 % 18161210121818181818181800FF1818181A181A18181812101210101012 % 161218101818181010101010101010121612181818181812181818181818 % 181818181818181818181816121010121012101010101010121012101210 % 101012101210101210100810100F1010101012181818181A181A18181812 % 101210101012161218101818181010101010101010121612181818181812 % 181818181818181818181818181818181816121010121012101010101010 % 121012101210101012101210101210100810100F1010101012181818181A % 181A18181812101210101012161218101818181010101010101010121612 % 181818181812181818181818181818181818181818181816121010121012 % 101010101010121012101210101012101210101210100810100F10101010 % 12181818181A181A18181812101210101012161218101818181010101010 % 101010121612181818181812181818181818181818181818181818181816 % 121010121012101010101010121012101210101012101210101210100810 % 100F1010101012181818181A181A18181812101210101012161218101818 % 181010101010101010121612181818181812181818181818181818181818 % 181818181816121010121012101010101010121012101210101012101210 % 101210100810100F1010101012181818181A181A18181812101210101012 % 161218101818181010101010101010121612181818181812181818181818 % 181818181818181818181816121010121012101010101010121012101210 % 101012101210101210100810100F1010101012181818181A181A18181812 % 101210101012161218101800FF1818181A18181A18181810101010121012 % 101212161218101010100A1010101012181818181818181818181A181818 % 181818161812181818181818101210101810101010101010121613181018 % 1218161818181010100A100B101010101010181818181A18181A18181810 % 101010121012101212161218101010100A10101010121818181818181818 % 18181A181818181818161812181818181818101210101810101010101010 % 1216131810181218161818181010100A100B101010101010181818181A18 % 181A18181810101010121012101212161218101010100A10101010121818 % 18181818181818181A181818181818161812181818181818101210101810 % 1010101010101216131810181218161818181010100A100B101010101010 % 181818181A18181A18181810101010121012101212161218101010100A10 % 10101012181818181818181818181A181818181818161812181818181818 % 1012101018101010101010101216131810181218161818181010100A100B % 101010101010181818181A18181A18181810101010121012101212161218 % 101010100A1010101012181818181818181818181A181818181818161812 % 181818181818101210101810101010101010121613181018121816181818 % 1010100A100B101010101010181818181A18181A18181810101010121012 % 101212161218101010100A1010101012181818181818181818181A181818 % 181818161812181818181818101210101810101010101010121613181018 % 1218161818181010100A100B101010101010181818181A18181A18181810 % 1010101210121012121600FF1818181A181A181818181210121010121010 % 10101210121818101010100810121618181A181A181818181A1818181818 % 181012121816181212181018161010181818181810101012161216101316 % 101818181818181010100E101010101010181818181A181A181818181210 % 12101012101010101210121818101010100810121618181A181A18181818 % 1A1818181818181012121816181212181018161010181818181810101012 % 161216101316101818181818181010100E101010101010181818181A181A % 18181818121012101012101010101210121818101010100810121618181A % 181A181818181A1818181818181012121816181212181018161010181818 % 181810101012161216101316101818181818181010100E10101010101018 % 1818181A181A181818181210121010121010101012101218181010101008 % 10121618181A181A181818181A1818181818181012121816181212181018 % 161010181818181810101012161216101316101818181818181010100E10 % 1010101010181818181A181A181818181210121010121010101012101218 % 18101010100810121618181A181A181818181A1818181818181012121816 % 181212181018161010181818181810101012161216101316101818181818 % 181010100E101010101010181818181A181A181818181210121010121010 % 10101210121818101010100810121618181A181A181818181A1818181818 % 181012121816181212181018161010181818181810101012161216101316 % 101818181818181010100E101010101010181818181A181A181818181210 % 12101012101010101200FF10181818181818181818161216121810181018 % 1012101018181610101010081012161818181818181A1818181818181810 % 1210101012181010101210121818181818181A1818121818121818181218 % 181818181818161210101010101010101210181818181818181818161216 % 1218101810181012101018181610101010081012161818181818181A1818 % 1818181818101210101012181010101210121818181818181A1818121818 % 121818181218181818181818161210101010101010101210181818181818 % 181818161216121810181018101210101818161010101008101216181818 % 1818181A1818181818181810121010101218101010121012181818181818 % 1A1818121818121818181218181818181818161210101010101010101210 % 181818181818181818161216121810181018101210101818161010101008 % 1012161818181818181A1818181818181810121010101218101010121012 % 1818181818181A1818121818121818181218181818181818161210101010 % 101010101210181818181818181818161216121810181018101210101818 % 1610101010081012161818181818181A1818181818181810121010101218 % 1010101210121818181818181A1818121818121818181218181818181818 % 161210101010101010101210181818181818181818161216121810181018 % 1012101018181610101010081012161818181818181A1818181818181810 % 1210101012181010101210121818181818181A1818121818121818181218 % 181818181818161210101010101010101210181818181818181818161216 % 121810181018101200FF1012161818181818101210121018181818181312 % 101010101212181810121012101818181818181818181A18181818101210 % 10101012161010121012101210181818181818181810181618101818FF12 % 101010121818181010101010101010101012161818181818101210121018 % 18181818131210101010121218181012101210181818181818FF18181A18 % 181818101210101010121610101210121012101818181818181818101816 % 18101818161210101012181818101010101010101010FF12161818181818 % 101210121018181818181312101010101212181810121012101818181818 % 181818181A181818181012101010101216101012FF121012101818181818 % 181818101816181018181612101010121818181010101010101010101012 % 1618181818181012101210181818181813FF101010101212181810121012 % 101818181818181818181A18181818101210101010121610101210121012 % 1018181818181818181018161810FF181612101010121818181010101010 % 101010101012161818181818101210121018181818181312101010101212 % 181810121012101818181818FF1818181A18181818101210101010121610 % 101210121012101818181818181818101816181018181612101010121818 % 181010101010101010FF1012161818181818101210121018181818181312 % 101010101212181810121012101818181818181818181A18181818101210 % 10101012161010FF10121012101818181818181818101816181018181612 % 101010121818181010101010101010101012161818181818101210121018 % 1818181813121000FF101218161818101010101010101818181818181010 % 101010101618181816101018181818181818181818181818181012101010 % 101010121010101210101210181812161218181A18181218181810FF1010 % 101010101218101010121010101010101218161818101010101010101818 % 181818181010101010101618181816101018181818181818FF1818181818 % 181012101010101010121010101210101210181812161218181A18181218 % 181810181010101010101218101010121010101010FF1218161818101010 % 101010101818181818181010101010101618181816101018181818181818 % 18181818181818101210101010101012101010FF10101210181812161218 % 181A18181218181810181010101010101218101010121010101010101218 % 16181810101010101010181818181818FF10101010101618181816101018 % 181818181818181818181818181012101010101010121010101210101210 % 181812161218181A1818121818FF10181010101010101218101010121010 % 101010101218161818101010101010101818181818181010101010101618 % 1818161010181818181818FF181818181818181012101010101010121010 % 101210101210181812161218181A18181218181810181010101010101218 % 1010101210101010FF101218161818101010101010101818181818181010 % 101010101618181816101018181818181818181818181818181012101010 % 101010121010FF1210101210181812161218181A18181218181810181010 % 101010101218101010121010101010101218161818101010101010101818 % 18181818101000FF10101012101012101010101012181818181818181010 % 080A10101012181818181818181818181218181818171812181010101010 % 101012181810101012161818161816181618171A181818101218FF181812 % 101010101018121610101210101010101012101012101010101012181818 % 181818181010080A101010121818181818181818181812FF181818171812 % 181010101010101012181810101012161818161816181618171A18181810 % 1218181818121010101010181216101012101010FF101012101012101010 % 101012181818181818181010080A10101012181818181818181818181218 % 181818171812181010101010101012181810FF1012161818161816181618 % 171A18181810121818181812101010101018121610101210101010101012 % 101012101010101012181818181818FF1010080A10101012181818181818 % 181818181218181818171812181010101010101012181810101012161818 % 161816181618171A18181810FF1818181812101010101018121610101210 % 101010101012101012101010101012181818181818181010080A10101012 % 18181818181818181818FF18181818171812181010101010101012181810 % 101012161818161816181618171A18181810121818181812101010101018 % 12161010121010FF10101012101012101010101012181818181818181010 % 080A10101012181818181818181818181218181818171812181010101010 % 1010121818FF101012161818161816181618171A18181810121818181812 % 101010101018121610101210101010101012101012101010101012181818 % 181818181000FF1210121018101810101010101012161818181A18181010 % 101010101010101018181818181818161818181818101810121010101010 % 12181818181612101210181818181818181818181818181618FF18181710 % 101210121612101210101818101210121018101810101010101012161818 % 181A1818101010101010101010101818181818181816FF18181818101810 % 121010101010121818181816121012101818181818181818181818181816 % 18181818171010121012161210121010181810FF10121018101810101010 % 101012161818181A18181010101010101010101018181818181818161818 % 1818181018101210101010101218181818FF121012101818181818181818 % 181818181816181818181710101210121612101210101818101210121018 % 101810101010101012161818181AFF181010101010101010101018181818 % 181818161818181818101810121010101010121818181816121012101818 % 1818181818181818181818FF181818181710101210121612101210101818 % 101210121018101810101010101012161818181A18181010101010101010 % 101018181818181818FF1818181818101810121010101010121818181816 % 121012101818181818181818181818181816181818181710101210121612 % 101210101818FF1210121018101810101010101012161818181A18181010 % 101010101010101018181818181818161818181818101810121010101010 % 12181818FF16121012101818181818181818181818181816181818181710 % 101210121612101210101818101210121018101810101010101012161818 % 181A181800FF181818181818181810121210121012181818181818181010 % 101010101010101012161818181818181718121612101210101210121818 % 181818181818101210181818181818181818181818181811FF1218181818 % 161210181018101818181818181818181818181810121210121012181818 % 181818181010101010101010101012161818181818FF1718121612101210 % 101210121818181818181818101210181818181818181818181818181811 % 181218181818161210181018101818181818FF1818181818181810121210 % 121012181818181818181010101010101010101012161818181818181718 % 12161210121010121012181818181818FF18101210181818181818181818 % 181818181811181218181818161210181018101818181818181818181818 % 18181012121012101218181818FF18181010101010101010101012161818 % 181818181718121612101210101210121818181818181818101210181818 % 18181818181818181818FF11181218181818161210181018101818181818 % 181818181818181810121210121012181818181818181010101010101010 % 1010121618181818FF181718121612101210101210121818181818181818 % 101210181818181818181818181818181811181218181818161210181018 % 1018181818FF181818181818181810121210121012181818181818181010 % 101010101010101012161818181818181718121612101210101210121818 % 181818FF1818101210181818181818181818181818181811181218181818 % 161210181018101818181818181818181818181810121210121012181818 % 18181800FF1A181818181818181818101010101012181818181818101810 % 121010101010101210181218181818181612181012101010101010181818 % 18181A1818101010121012161216121012101818181818FF101210181818 % 1012101210121818181A181A181818181818181818101010101012181818 % 1818181018101210101010101012101812181818FF181612181012101010 % 10101018181818181A181810101012101216121612101210181818181810 % 1012101818181012101210121818181A18FF181818181818181818101010 % 101012181818181818101810121010101010101210181218181818181612 % 18101210101010101018181818181AFF1810101012101216121612101210 % 1818181818101012101818181012101210121818181A181A181818181818 % 181818101010101012181818FF1818101810121010101010101210181218 % 18181818161218101210101010101018181818181A181810101012101216 % 121612101210181818FF18101012101818181012101210121818181A181A % 181818181818181818101010101012181818181818101810121010101010 % 10121018121818FF1818161218101210101010101018181818181A181810 % 101012101216121612101210181818181810101210181818101210121012 % 1818181AFF1A181818181818181818101010101012181818181818101810 % 121010101010101210181218181818181612181012101010101010181818 % 1818FF181810101012101216121612101210181818181810101210181818 % 1012101210121818181A181A181818181818181818101010101012181818 % 181800FF1818181818181818181818121010101210121018101812101216 % 181018121610101210181718181818181810181012101010121818181A18 % 18181818181010101010101010101010101216181810FF10101018121210 % 101810121018181818181818181818181818181818121010101210121018 % 10181210121618101812161010121018171818FF18181810181012101010 % 121818181A18181818181810101010101010101010101012161818101210 % 10101812121010181012101818181818FF18181818181818181818121010 % 101210121018101812101216181018121610101210181718181818181810 % 181012101010121818181A181818FF181810101010101010101010101012 % 161818101210101018121210101810121018181818181818181818181818 % 1818181210101012101210FF101812101216181018121610101210181718 % 181818181810181012101010121818181A18181818181810101010101010 % 1010101010121618FF101210101018121210101810121018181818181818 % 181818181818181818121010101210121018101812101216181018121610 % 101210181718FF1818181810181012101010121818181A18181818181810 % 101010101010101010101012161818101210101018121210101810121018 % 181818FF1818181818181818181818121010101210121018101812101216 % 181018121610101210181718181818181810181012101010121818181A18 % 18FF18181810101010101010101010101012161818101210101018121210 % 101810121018181818181818181818181818181818121010101210121018 % 1000FF1A1818181818181818181818181210101010101012101018101218 % 1818181A181012101818181818181818181817181012101216181818181A % 181818121010101010101010101010101012181618FF1012101210101010 % 1210181018161818181A1818181818181818181818181210101010101012 % 1010181012181818181A1810121018181818FF1818181818171810121012 % 16181818181A181818121010101010101010101010101012181618181012 % 101210101010121018101816181818FF1818181818181818181818181210 % 1010101010121010181012181818181A1810121018181818181818181818 % 17181012101216181818181A18FF18121010101010101010101010101012 % 1816181810121012101010101210181018161818181A1818181818181818 % 18181818121010101010FF121010181012181818181A1810121018181818 % 18181818181817181012101216181818181A181818121010101010101010 % 10101010101218FF181810121012101010101210181018161818181A1818 % 1818181818181818181812101010101010121010181012181818181A1810 % 1210181818FF18181818181817181012101216181818181A181818121010 % 101010101010101010101012181618181012101210101010121018101816 % 1818FF1A1818181818181818181818181210101010101012101018101218 % 1818181A181012101818181818181818181817181012101216181818181A % FF1818121010101010101010101010101012181618181012101210101010 % 1210181018161818181A1818181818181818181818181210101010101012 % 00FF18181818181012101817181818181810121010121010121012161818 % 18181818181810181818181818181818181818181816181818181A181818 % 1816181818101010101010101010101010101218FF181818181612161216 % 121012101218181818181818181012101817181818181810121010121010 % 1210121618181818181818181018181818FF181818181818181818161818 % 18181A181818181618181810101010101010101010101010121818181818 % 1816121612161210121012181818FF181818181012101817181818181810 % 121010121010121012161818181818181818101818181818181818181818 % 18181816181818181A181818FF1618181810101010101010101010101010 % 121818181818181612161216121012101218181818181818181012101817 % 181818181810121010FF1010121012161818181818181818101818181818 % 18181818181818181816181818181A181818181618181810101010101010 % 101010101010FF1818181818181612161216121012101218181818181818 % 181012101817181818181810121010121010121012161818181818181818 % 10181818FF1818181818181818181816181818181A181818181618181810 % 101010101010101010101010121818181818181612161216121012101218 % 18FF18181818181012101817181818181810121010121010121012161818 % 18181818181810181818181818181818181818181816181818181A1818FF % 181618181810101010101010101010101010121818181818181612161216 % 121012101218181818181818181012101817181818181810121010121000 % FF1818111210101010121818181818181818181210101210101210121810 % 121618181818181818181A1818181818181818181818181818181A181818 % 18181818101210121010121010101010101818FF20191818181818181818 % 101010121012181818111210101010121818181818181818181210101210 % 10121012181012161818181818181818FF18181818181818181818181818 % 18181A181818181818181012101210101210101010101018181820191818 % 18181818181810101012101218FF18111210101010121818181818181818 % 181210101210101210121810121618181818181818181A18181818181818 % 18181818181818181A1818FF181818181012101210101210101010101018 % 181820191818181818181818101010121012181818111210101010121818 % 1818181818181812FF101210101210121810121618181818181818181A18 % 18181818181818181818181818181A181818181818181012101210101210 % 1010101010FF181820191818181818181818101010121012181818111210 % 101010121818181818181818181210101210101210121810121618181818 % 181818FF1A1818181818181818181818181818181A181818181818181012 % 101210101210101010101018181820191818181818181818101010121012 % FF1818111210101010121818181818181818181210101210101210121810 % 121618181818181818181A1818181818181818181818181818181A18FF18 % 181818181012101210101210101010101018181820191818181818181818 % 1010101210121818181112101010101218181818181818181812101000FF % 181818161812181612101212181818181018101813181818181612161818 % 181818181818181A181818181A1818181812101316181818181818181812 % 101210121012161818181010101010101018FF1818181818181810181818 % 181012101018181818161812181612101212181818181018101813181818 % 181612161818181818181818181A18FF18181A1818181812101316181818 % 181818181812101210121012161818181010101010101018181818181818 % 181810181818181012101018FF1818161812181612101212181818181018 % 101813181818181612161818181818181818181A181818181A1818181812 % 10131618181818181818FF12101210121012161818181010101010101018 % 181818181818181810181818181012101018181818161812181612101212 % 18181818101810FF13181818181612161818181818181818181A18181818 % 1A1818181812101316181818181818181812101210121012161818181010 % 10101010FF18181818181818181810181818181012101018181818161812 % 181612101212181818181018101813181818181612161818181818181818 % 181AFF1818181A1818181812101316181818181818181812101210121012 % 1618181810101010101010181818181818181818101818181810121010FF % 181818161812181612101212181818181018101813181818181612161818 % 181818181818181A181818181A1818181812101316181818181818FF1812 % 101210121012161818181010101010101018181818181818181810181818 % 18101210101818181816181218161210121218181818101810181300FF10 % 181018101818181818101618181818181818181816181212101210121818 % 181818181818181818181818181A18181618181818181818181818181610 % 1012101012101810181210121010101210FF101217181818101818181810 % 121010101810181018101818181818101618181818181818181816181212 % 1012101218181818181818181818FF181818181A18181618181818181818 % 181818181610101210101210181018121012101010121012101217181818 % 1018181818101210101018FF181018101818181818101618181818181818 % 181816181212101210121818181818181818181818181818181A18181618 % 181818181818181818FF1610101210101210181018121012101010121012 % 101217181818101818181810121010101810181018101818181818101618 % 181818181818FF1816181212101210121818181818181818181818181818 % 181A18181618181818181818181818181610101210101210181018121012 % 101010FF1012101217181818101818181810121010101810181018101818 % 181818101618181818181818181816181212101210121818181818181818 % 18FF18181818181A18181618181818181818181818181610101210101210 % 18101812101210101012101210121718181810181818181012101010FF10 % 181018101818181818101618181818181818181816181212101210121818 % 181818181818181818181818181A181816181818181818181818FF181610 % 101210101210181018121012101010121012101217181818101818181810 % 121010101810181018101818181818101618181818181818181800FF1012 % 121212101018181818181210121018121612161210101010101010101018 % 181818181818181818181A18181818181818181818181818181818181813 % 10101210121012181010101010101010FFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18181813 % 101012101210121810101010101010101012181812181618101210121010 % 1010101210121212121010181818181812101210181216121600FF121010 % 101010121810181818161010121010101210121612101010101010101012 % 10161818181818181A1820181A1818181818181818181818181818181618 % 101010101012101812121012101012101012101817121210181618101210 % 101010121010101010121810181818161010121010101210121612101010 % 10101010101210161818181818181A1820181A1818181818181818181818 % 181818181618101010101012101812121012101012101012101817121210 % 181618101210101010121010101010121810181818161010121010101210 % 12161210101010101010101210161818181818181A1820181A1818181818 % 181818181818181818181618101010101012101812121012101012101012 % 101817121210181618101210101010121010101010121810181818161010 % 12101010121012161210101010101010101210161818181818181A182018 % 1A1818181818181818181818181818181618101010101012101812121012 % 101012101012101817121210181618101210101010121010101010121810 % 181818161010121010101210121612101010101010101012101618181818 % 18181A1820181A1818181818181818181818181818181618101010101012 % 101812121012101012101012101817121210181618101210101010121010 % 101010121810181818161010121010101210121612101010101010101012 % 10161818181818181A1820181A1818181818181818181818181818181618 % 101010101012101812121012101012101012101817121210181618101210 % 10101012101010101012181018181816101012101010121000FF10101012 % 101210101218181810121012161218121612101010101008100E10101010 % 12121618181818181A181818181818181818181818181818181818181810 % 101010101012101817181612101010121618181818101618181816181618 % 181010101012101210101218181810121012161218121612101010101008 % 100E1010101012121618181818181A181818181818181818181818181818 % 181818181810101010101012101817181612101010121618181818101618 % 181816181618181010101012101210101218181810121012161218121612 % 101010101008100E1010101012121618181818181A181818181818181818 % 181818181818181818181810101010101012101817181612101010121618 % 181818101618181816181618181010101012101210101218181810121012 % 161218121612101010101008100E1010101012121618181818181A181818 % 181818181818181818181818181818181810101010101012101817181612 % 101010121618181818101618181816181618181010101012101210101218 % 181810121012161218121612101010101008100E10101010121216181818 % 18181A181818181818181818181818181818181818181810101010101012 % 101817181612101010121618181818101618181816181618181010101012 % 101210101218181810121012161218121612101010101008100E10101010 % 12121618181818181A181818181818181818181818181818181818181810 % 101010101012101817181612101010121618181818101618181816181618 % 181010101012101210101218181810121012161218121600FF1012101010 % 101010101012181818181012101010101210121010101010101010101010 % 1012181818181A18181A1818181818171818121618181818181618181010 % 101008101018181818181818181613181818181818121818181818181818 % 101012101010101010101012181818181012101010101210121010101010 % 1010101010101012181818181A18181A1818181818171818121618181818 % 181618181010101008101018181818181818181613181818181818121818 % 181818181818101012101010101010101012181818181012101010101210 % 1210101010101010101010101012181818181A18181A1818181818171818 % 121618181818181618181010101008101018181818181818181613181818 % 181818121818181818181818101012101010101010101012181818181012 % 1010101012101210101010101010101010101012181818181A18181A1818 % 181818171818121618181818181618181010101008101018181818181818 % 181613181818181818121818181818181818101012101010101010101012 % 181818181012101010101210121010101010101010101010101218181818 % 1A18181A1818181818171818121618181818181618181010101008101018 % 181818181818181613181818181818121818181818181818101012101010 % 101010101012181818181012101010101210121010101010101010101010 % 1012181818181A18181A1818181818171818121618181818181618181010 % 101008101018181818181818181613181818181818121818181818181818 % 1010121010101010101010121818181810121010101000FF121010121012 % 101210121010121612161216121813181718101210101010101010101010 % 101816181818181A18181818181812101210121812171818181218101010 % 08101010101818181A18181A181818181A18181818181818181818181810 % 121010121012101210121010121612161216121813181718101210101010 % 101010101010101816181818181A18181818181812101210121812171818 % 18121810101008101010101818181A18181A181818181A18181818181818 % 181818181810121010121012101210121010121612161216121813181718 % 101210101010101010101010101816181818181A18181818181812101210 % 12181217181818121810101008101010101818181A18181A181818181A18 % 181818181818181818181810121010121012101210121010121612161216 % 121813181718101210101010101010101010101816181818181A18181818 % 18181210121012181217181818121810101008101010101818181A18181A % 181818181A18181818181818181818181810121010121012101210121010 % 121612161216121813181718101210101010101010101010101816181818 % 181A18181818181812101210121812171818181218101010081010101018 % 18181A18181A181818181A18181818181818181818181810121010121012 % 101210121010121612161216121813181718101210101010101010101010 % 101816181818181A18181818181812101210121812171818181218101010 % 08101010101818181A18181A181818181A18181818181818181818181810 % 12101012101210121012101012161216121612181300FF10101210101210 % 1812101210101210181818181816181818181610101010100A0E10101212 % 181218181818181818181818101012101010121618121612181610101008 % 0A0000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000008 % 0A1010121818181820181818181818181818181812101210181216181010 % 101210101210181210121010121018181818181600FF1218101818181818 % 1A1818181810101818161216121012101218181818121010101010101010 % 101818181818181818101018121816121612101210121010121818101010 % FF2121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121001010 % 1010101816181A181A181A18181A181A1816121010121012101210181218 % 1018181818181A18181818101018181612161200FF101012101818181818 % 181A18181218181818181812101810101218181010101010101010101210 % AF16181818181612101210181018181818101810121012101216121010FF % 7D0000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000002100101010 % 101018181818181A18181A181A1818181812101210121012101812101012 % 101818181818181A1818121818181818181200FF10121010121012181818 % 1818181818181818181817181310101010101210101010101010101012AF % 10121212101210101012101218181818181810121010101010121818FF7D % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 007F7F7F0000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000000000FF % FFFF00000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000000000000000007F7F7F000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000FFFFFF000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000210018181813 % 16181818181A181818181818181818181010101010101012101010121010 % 121012181818181818181818181818181700FF1810101210101818181818 % 18181818181818181818181610101210101010101010101010121010AF10 % 121010121010101010101216181818181818101010101010101018FF7D00 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000007F7F7F % 1313137F7F7F000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000FFFFFFFF5353 % 53FFFFFF0000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000007F7F7F1313137F7F7F00000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000FFFFFF535353FFFFFF00000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000021001018181612 % 181818181818181818181818181810101010101010121010181810101210 % 1018181818181818181818181818181800FF181818101612181018181818 % 181818181818181818181818181010121018181010101210101012AF1010 % 10121010121010101010121818181818181012101010100A1010FF7D0000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000007F7F7F131313 % 7F7F1313137F7F0000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000FFFF53FF535353FFFF % 535353FFFF00000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000007F7F7F1313137F7F1313137F7F000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000000000FFFFFF535353FFFF535353FFFF000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000002100101010121818 % 1818181818181817181818181210121010C5C5C5C5181818181818101612 % 18101818181818181818181818181800FF1A181812121210181012121018 % 1818181818181812161818181012101818181010181018181818AF121012 % 10101216101010101012181818181818101210101010100810FF7D000000 % 00000000000000000000000000000000AFAFAFAFAFAF0000000000000000 % 000000FFFFFFFF0000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000007F13137F13137F13 % 13131313137F7F7F00000000000000000000000000000000000000000000 % 00000000000000000000000000000000000000FF535353FF5353FF535353 % 5353FFFFFF00000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000007F7F13137F13137F13131313137F7F7F000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000FF5353FF5353FF535353535353FFFFFF0000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000210008101010101818 % 171818181818181818181612101010C5C51012C5C518181A181812121210 % 181012121018181818181818181200FF1818121010101012101010121012 % 1818181718181618121810121210121218181818181818181AAF18181010 % 181818101210101010101818181818161217121010101010FF7D00000000 % 0000000000000000000000000000000000AFAF0000000000000000000000 % 00FFFF0000FFFF0000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000007F7F7F137F1313137F1313 % 13137F7F1313137F7F000000000000000000000000000000000000000000 % 00000000000000000000000000000000FFFFFF5353FF535353FF535353FF % FF535353FFFF000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000007F7F137F137F1313137F1313137F7F1313137F7F0000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000FFFFFF53FF535353FF53535353FFFF535353FFFF00000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000021001010101010101218 % 1818181818181118131810101010C5C51218C5C5181A1818121010101012 % 1010101210121818181718181600FF181810101010101210101010101216 % 181818181012101210101010101010101818181818181818181818181818 % 18181810101010AFAFAFAFAFAFAFAFAFAFAFAFAF181210FF7D0000000000 % 0000003A3A3A3A3A3A3A3A3A3A3A3A3AAFAF3A3A3A3A3A3A3A3A3A3A3A3A % FFFF3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F13137F13137F13131313 % 7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53FF535353FF5353FF535353FF5353 % 5353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A7F13137F13137F13137F1313137F131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3AFF53FF5353FF5353FF53535353FF53535353535353FF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A000000000000210012101010C5C5C5C5C5 % C5C5C5C5C5C5C5C51012101010C5C51618C5C51A18181810101010101210 % 10101010121618181818101200FF1818181010080810101010100B0E0A10 % 101618181818181810181316121612161210121618181818181818161218 % 101818181818161010101012101010121010AF121818FF7D000000000000 % 00003A3A3AAFAFAFAFAFAF3A3A3A3AAFAF3A3A3A3A3A3A3A3A3A3A3A3AFF % FF3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F13137F13137F131313137F % 13131313137F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3AFF53FF535353FF5353FF535353FF535353 % 5353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F13137F13137F13137F1313137F13131313137F7F7F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3AFF53FF5353FF5353FF53535353FF5353535353FFFFFF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A000000000000210018181618C51010181618 % 181A18181813101018101810C5C51818C5C5181818181810100808101010 % 10100B0E0A10101618181800FF1818181612101010101010101010101010 % 12181818181816101810161217121810121012AF1818181818AF18101810 % 1818181818181818101210101210101010AF161818FF7D00000000000000 % 003A3A3A3A3A3A3A3A3A3A3A3A3AAFAF3A3A3A3A3A3A3A3A3A3A3A3AFFFF % 3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F13137F1313137F137F1313137F1313 % 13137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFFFF5353FF53535353FF53FF5353FF53535353FF % FF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A7F7F1313137F1313137F137F13137F131313137F7F1313137F7F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FFFF5353FF535353FF53FF535353FF53535353FFFF535353FFFF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A000000000000210018181818C5181818181818 % 1818181818101210121816C5C51818C5C51A181818181612101010101010 % 1010101010101218181800FF181618181818181012101010101010101010 % 121618181818121812181218121012101210AF1018181816AF1810181210 % 12101818181818121010121012101210AF121818FF7D0000000000000000 % 3A3A3A3A3A3A3A3A3A3A3A3A3AAFAF3A3A3A3A3A3A3A3A3A3A3A3AFFFF3A % 3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F137F1313137F13137F13137F13137F131313 % 7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF53FF535353FF535353FF5353FF53FF535353FF5353 % 5353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 7F137F131313137F13137F13137F137F1313137F131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53 % FF535353FF5353FF5353FF5353FF535353FF53535353535353FF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A000000000000210018181818C518181818181818 % 18181818181316181012C5C51818C5C51818181618181818181012101010 % 10101010101012161800FF1812121618181812161210101010100A0F1010 % 12181818161817181618161810121010AFAFAFAFAFAFAFAF161218101010 % 181818181818121612181018101810AF101216FF7D00000000000000003A % 3A9D3A3A9D3A3A9D3A3AAFAFAFAF9D3A3A3A3A3A3A3A3A3A3A3AFFFF3A3A % FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A7F137F1313137F1313137F7F7F13137F1313137F % 131313131313137F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF53FF535353FF53535353FFFFFF53FF535353FF535353 % 53535353FF3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F % 137F131313137F1313137F7F7F137F1313137F131313131313137F3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF53FF % 535353FF535353FFFFFF5353FF535353FF53535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A000000000000210012161818C518181A1818181A18 % 18181818181818181816C5C5C5C518181818121216181818121612101010 % 10100A0F1010121800FF1810101012101216121810121010121010101010 % 121618181818181818181810101010AFAFAFAFAFAFAFAF12181018101818 % 1818181818161218101810181210AF101212FF7D0000000000000000FF3A % 9D3A3A9D3A3A9D3A3A3A3AAFAF9D3A3A3A3A3A3A3A3A3A3A3A3AFFFFFFFF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A7F1313137F1313137F7F1313137F7F7F137F137F1313 % 131313137F7F7F7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3AFF535353FF535353FFFF535353FFFFFFFFFF53FF5353535353 % 53FFFFFFFF3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313 % 137F131313137F7F1313137F7F7F7F137F131313131313137F7F7F3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFF535353FF % 535353FFFF535353FFFFFF53FF53FF535353535353FFFFFFFF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3AFF3A3A3A3AFF0000000000210012121818C518181818181818181A % 181818181818181818181818181818181810101012101216121810121010 % 1210101010101200FF181612101010101210121612101216101010101210 % 121818181818181818181612101010101210121012AF1216121818181818 % 18161210121012101210121010AF101010FF7D0000000000000000FF3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A3A3A9D3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A7F7F1313137F13131313137F7F7F3A3A3A7F7F137F131313 % 137F7F1313137F7F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3AFFFF535353FF5353535353FFFFFF3A3A3A3AFF53FF53535353FFFF % 535353FFFF3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A % 3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F131313 % 7F1313131313137F7F7F3A3A3A7F137F13131313137F7F1313137F7F3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF535353FF53 % 53535353FFFFFF3A3A3AFFFF53FF53535353FFFF535353FFFF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF3A3A3A3A3A00FF00000000210010101218C518181818181818181818 % 181A18181818181818181818181818181612101010101210121612101216 % 10101010121000FF18181816101010101012101210181216121010101012 % 1618181818181818181218101010101010101210AF101810181818181818 % 181210101210121012101210AF100F10FF7D0000000000000000FF3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9D % 3A3A3A9D7F137F131313137F7F1313137F7F3A3A3A3A3A3A7F7F1313137F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF53FF53535353FFFF535353FFFF3A9D3A3A3A3AFFFF535353FF535353 % 53535353FF3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F13131313 % 7F7F1313137F7F9D3A3A3A3A3A7F7F131313137F131313131313137F3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF5353FF53535353FFFF % 535353FFFF3A3A3A3A3A3AFFFF535353FF53535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % FF3A3AFF3A3A00FF0000000021000F101010C5101818181818181A18181A % 181A18181818181818181818181818181816101010101012101210181216 % 121010101000FF1818181818121010101010101818181810101010101012 % 181818181818181818181012101010121010101012101818101818181818 % 1816121010101210101010AF100A10FF7D0000000000000000FF3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9D3A % 3A3A9D7F13137F13131313137F7F7F3A3A3A3A3A3A3A3A9D3A7F13137F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF5353FF5353535353FFFFFF3A3A3A9D3A3A3A3A3A3AFF5353FF53535353 % 535353FF3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F13131313 % 137F7F7F3A3A9D3A3A3A3A3A3A3A7F1313137F131313131313137F3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF535353FF5353535353FF % FFFF3A3A3A3A3A3A3A3A3A3AFF5353FF53535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3AFF % 3A3AFF3A3A00FF0000000021000A101010C510121018181818181A181A18 % 201818181818181818181818181818181818121010101010101818181810 % 1010101000FF181818181010101010101218181618181818181818181818 % 1A1818181810101816181818181216101210121018101210101018181810 % 12101012101010121010AF100A08FF7D0000000000000000FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A7F1313137F131313131313137F3A3A3A3A3A3A3A3A3A3A7F137F131313 % 1313131313137F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3AFF53 % 5353FF53535353535353FF3A3A3A3A3A3A3A3A3A3AFF53FF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313137F1313131313 % 13137F3A3A3A3A9D3A3A3A3A3A7F13137F1313131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353FF53535353535353 % FF3A3A3A3A3A3A3A3A3A3AFF53FF535353535353535353FF3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF % FFFFFFFFFFFF0000000021000A081010C510101012161818181818181A18 % 181818101012101810181618181818181010101010101218181618181818 % 18181800FF16181818101012081010101012181818181818181818181A18 % 1A1818161212181818181818161210121010121216181010121010101212 % 161218101210101012AF101010FF7D0000000000000000FF3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 7F131313137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A7F7F13131313 % 13137F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353 % 5353FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3AFFFF53535353535353 % FFFFFF3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313137F7F1313137F % 7F3A3A3A3A3A3A3A3A3A3A3A9D7F7F7F1313131313137F7F7F7F3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3AFF5353535353FFFF535353FFFF3A % 9D3A3A3A3A3A3A3A3A3A3AFFFF535353535353FFFFFFFF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF % 3AFFFFFF0000000000210010101010C5101010101218181818181A181818 % 181810121012101210121216181818101012081010101012181818181818 % 181800FF121018121612100E0A081010101818181A18181A181818181818 % 181812101018181818181818181010181318161818121010101010101018 % 1816181810181216AF101010FF7D00000000000000003A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F % 1313131313137F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313137F % 7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353 % 535353FFFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353535353FFFF53 % 5353FFFF3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313131313137F7F7F7F3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F131313137F7F1313137F7F3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A3AFFFF53535353535353FFFFFF3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3AFF53535353FFFF535353FFFF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A000000000000210010101010C5100E1010121018181818181A181818 % 18101216121018101210121018121612100E0A081010101818181A18181A % 1800FF101210181818181010100A1010181818181818181818181A181818 % 181010121012101818181810181218161818181816181010101010121818 % 18181618121618AF121010FF7D00000000000000003A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313137F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F1313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353FF535353 % 53535353FF3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF535353FF53535353 % 535353FF3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F13137F131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F131313131313137F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFF5353FF53535353535353FF9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF5353FF53535353535353FF3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A000000000000210010101010C510101010101212101818181818181818 % 181810181112101610101210181818181010100A10101818181818181818 % 00FF1010101012101818181010101218181818181818181818181A181818 % 101210101010121012101018101818181818181818181818181010181218 % 101212101218AF101810FF7D0000000000FF00003A3AFF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313137F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353FF53535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353FF5353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F131313131313137F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF5353FF53535353535353FF3A3A3A3A3A3A3A % 9D3A3A9D3A9D3A3A9D3AFF5353FF53535353535353FF3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFFFFFFFF % FF0000000000210018101210C51010101010101012181818181818181018 % 101812181018121010101010121018181810101012181818181818181800 % FF1012101010101218181810121618181818181818181818181818181012 % 1010101010101012101212101810181818181818181A1818181216121612 % 1010101012AF181012FF7D00000000FF0000003A3A3AFF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313137F7F % 1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353FFFF535353 % FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313137F7F1313137F7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3AFF53535353FFFF535353FFFF3A3A3A3A3A3A3A3A9D % 3A3A9D3A9D3A3A9D3A3AFFFF535353535353535353FF3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFFFFFFFFFFFF % FF00000000210010121010C5101010101012101012121818161210101212 % 1612161818181210121010101012181818101216181818181818181800FF % 1810121010100E1816121810181618161818161818181818181818121012 % 101010101218181812101012121612181618181818181818181818181810 % 18121010AF101216FF7D00000000FF0000FF3A3A3AFF3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353FFFFFFFF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF5353535353535353 % 53FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F1313131313137F7F7F7F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF535353535353FFFFFFFF3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF3AFF3A3A00FF % 00000000210012161210C510101010101012101210121012101010101012 % 1818181818181810121010100E181612181018161816181816181800FF18 % 1810100A100A101010101812121218181818181818181818181810101010 % 101216181818181810121010121612181812101010181818181818181818 % 18180AAF101216FF7D00000000FF0000FF3A3A3AFF3A3A3A3A9D3A9D3A3A % 9D3A3A9D3A3A3A9D9D3A9D3A9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D9D3A9D % 9D3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F131313131313131313 % 7F9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D7F1313131313137F % 7F7F7F3A9D9D3A9D9D3A9D3A9D3A3A9D3A9DFF535353535353535353FF3A % 9D3A9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A3A3A3AFF535353535353FFFFFF % FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313137F7F7F7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3AFF535353535353FFFFFFFF3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3AFF3A3AFF3A3A00FF00 % 000000210012161210C51010101010101010101010121010101010101210 % 18181A181A181810100A100A101010101812121218181818181800FF1818 % 18101010100B101012101818181818181818181010181216121012101010 % 101218181818181A18181216121818121018181818181818181612181618 % 1818AF101210FF7D00000000FFFFFFFFFFFFFFFF3A3A3A3A9D3A9D3A3A9D % 3A3A9D3A3A3A9D9D3A9D3A9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D9D3A9D9D % 3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F7F7F131313131313137F9D % 9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D7F1313137F7F1313 % 137F7F9D9D3A9D9D3A9D3A9D3A3A9D3AFFFFFF53535353535353FF9D3A9D % 3A9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A3A3A3A3AFF535353FFFF535353FF % FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A7F7F7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F1313137F7F1313137F7F3A3A3A3A3A3A3A % 3A3A3A3A3AFFFFFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3AFF535353FFFF535353FFFF3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3AFF3A3AFFFFFFFFFF0000 % 0000210012101818C5101216121818181810101210101210101010101218 % 18181818181818101010100B1010121018181818181818181800FF181818 % 101210101010101012101210181818181818181211181012101012101010 % 101818181818181812101210181810121012181018181818181210121210 % 18AF181012FF7D0000000000FFFF00FFFFFF3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13137F131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A3A7F13137F1313131313 % 13137F3A9D3A3A9D9D3A9D3A3A9DFF5353FF53535353535353FF3A9D9D3A % 9D9D9D9D3A9D3A9D3A9D9D9D3A9D9D9D9D9D3AFF5353FF53535353535353 % FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D % 9D3A9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D7F13137F131313131313137F9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D7F13137F131313131313137F9D9D9D9D9D9D9D % 9D9D9DFF5353FF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9DFF5353FF53535353535353FF9D9D9D3A3A3A3A9D3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF3A3A3AFFFFFF00000000 % 00210010121612C518181818181818181218161812101010101010101012 % 18181818181810121010101010101210121018181818181800FF16181216 % 121012101010121010101018181818181818181812161216121012101218 % 181818181A18181010101010101010101010121012101210101010101018 % AF121012FF7D00000000000000003A3A3A3A9D3A3A3A3A3A9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F1313137F7F1313137F7F9D3A9D9D % 9D9D3A9D9D3A9D3A9D3A9D3A9D3A9D9D3A9D3A3A9D7F7F7F131313131313 % 137F9D3A9D9D3A3A9D3A9D3A3AFF535353FFFF535353FFFF3A3A3A9D3A9D % 3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3AFFFFFF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F1313137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F7F131313131313137F3A3A3A3A3A3A3A3A % 3A3AFF535353FFFF535353FFFF3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFFFFFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A000000000000 % 210010121018C51316181818181818181818181618181818101010101010 % 181816181216121012101010121010101018181818181800FF1812161218 % 10101210121010101010101218181818181818101812101210101217181A % 18181A1818181810101010101010101010101010101818121810101012AF % 121010FF7D00000000000000003A3A3A3A9D3A3A3A3A3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D7F1313131313137F7F7F7F9D9D3A9D9D9D % 9D3A9D9D3A9D3A9D3A9D3A9D3A9D9D3A9D3A3A9D3A7F1313131313131313 % 137F3A9D9D3A3A9D3A9D3AFF535353535353FFFFFFFF3A3A3A3A9D3A9D3A % 3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3AFF535353535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F1313131313137F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A % FF535353535353FFFFFFFF3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A00000000000021 % 0010101216C518181818181818181A181818121818181818121010101012 % 1818121612181010121012101010101010121818181800FF101018111818 % 181818181818181818181818181818181818181811181010121818181818 % 1A181A18181816101010101010101010101010181718181816121010AF10 % 1210FF7D000000000000FFFFFFFFFF3A3A3A3A3A9D3A3A9D9D9D3A9D9D9D % 9D3A9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D9D9D9D % 9D3A9D9D9D9D3A9D9D3A9D9D9D3A9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D3A % 9D9D3A9D9D9D9D9D9D9D3A9D7F1313131313131313137F9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F131313131313131313 % 7F9D9D3A9D9D9D3A9D3AFF535353535353535353FF9D9D9D9D3A9D3A3A9D % 9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9DFF535353535353535353FF9D % 9D9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D % 9D3A9D9D3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D3A9D9D3A9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D3A3A9D % 3A9D7F1313131313131313137F3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D3A3A % 3A3A9D3A9D3A3A9D3A3A7F1313131313131313137F3A3A9D3A3A3A3A3AFF % 535353535353535353FF3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF535353535353535353FF3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFFFFFFFFFFFF00000000002100 % 12101210C516181818181818181818181010121018181818181818101012 % 10101811181818181818181818181818181818181800FF12181018101818 % 1018181818181A1818181818181A18181818161818131810181818181A18 % 181818181818181012101010101010101010181818181818181810AF1618 % 16FF7D0000000000FFFFFFFFFFFFFF3A3A3A3A9D3A9D9D9D3A9D9D3A9D9D % 9D9D3A9D9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D3A3A3A9D9D3A9D9D9D3A9D % 9D3A9D9D9D9D9D3A9D9D3A3A9D9D9D3A9D3A9D9D3A9D9D3A9D9D3A9D9D9D % 9D3A9D9D9D9D3A3A9D9D9D7F1313131313131313137F9D9D3A9D3A3A9D9D % 9D9D9D9D3A9D3A9D9D9D3A3A3A9D3A3A9D3A3A7F1313131313131313137F % 9D9D9D9D3A9D9D9D3AFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9DFF535353535353535353FF9D9D % 9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A % 9D7F1313131313131313137F3A9D9D9D3A3A9D9D9D9D9D9D3A9D3A9D9D3A % 9D9D9D9D3A9D9D9D3A7F1313131313131313137F9D9D9D9D3A9D9D9DFF53 % 5353535353535353FF3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D % 9D9D9D9D9D9DFF535353535353535353FF3A9D3A9D9D9D9D9D9D9D9D9D9D % 3A9D9D9D9D9D9D9D9D3A3A3A3A3A3AFFFFFFFFFFFFFFFF00000000210018 % 161216C5181218161818161818121012101012101818181A181810101012 % 1810181018181018181818181A1818181818181A00FF1810121812161218 % 101818181818181818181A18181818181818181810181018181818181818 % 1818181818181018101210101010101010121210121818181810AF181818 % FF7D00000000FFFF00FF3A3A3AFF3A3A3A3A9D3A9D9D9D3A9D9D3A9D9D9D % 9D3A9D9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D3A3A3A9D9D3A9D9D9D3A9D9D % 3A9D9D9D9D9D3A9D9D3A3A9D9D9D3A9D3A9D9D3A9D9D3A9D9D3A9D9D9D9D % 3A9D9D9D9D3A3A9D9D9D3A7F131313131313137F9D9D9D3A9D3A3A9D9D9D % 9D9D9D3A9D3A9D9D9D3A3A3A9D3A3A9D3A3A3A7F131313131313137F3A9D % 9D9D9D3A9D9D9D3A9DFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9DFF53535353535353FF9D9D9D9D % 9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D % 9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D % 9D7F131313131313137F3A3A9D9D9D3A3A9D9D9D9D9D9D3A9D3A9D9D3A9D % 9D9D9D3A9D9D9D3A3A7F131313131313137F9D9D9D9D9D3A9D9D9D9DFF53 % 535353535353FF9D3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D % 9D9D9D9D9D9DFF53535353535353FF9D3A9D3A9D9D9D9D9D9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D3A3A3A3A3A3AFF3A3A3A3A3A00FF0000000021001818 % 1812C5101210181218181810101810181010121218181818181810121810 % 121812161218101818181818181818181A181800FF171816121610121612 % 10181818181818181A18181818181818181818181018181818181A181818 % 10181218181012101810121012101010101010101012181812AF181818FF % 7D00000000FF0000FF3A3A3AFF3A3A3A3A9D3A9D9D9D9D3A9D9D9D3A9D9D % 9D3A9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D3A9D3A9D9D9D % 3A9D9D9D3A9D9D9D9D9D3A3A9D9D3A9D3A9D9D9D9D9D9D9D9D3A9D3A9D9D % 9D9D9D9D9D9D3A9D9D9D7F131313131313137F3A9D9D9D9D3A9D9D3A9D3A % 9D3A9D9D9D9D3A9D9D3A9D3A3A9D9D3A9D3A7F1313131313137F7F7F3A9D % 9D9D9D9D9D3A3AFFFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF5353535353FFFFFF9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D7F % 7F131313131313137F9D3A3A3A9D9D3A3A9D9D3A9D3A9D9D9D3A3A3A9D9D % 9D3A9D3A3A9D9D9D7F13131313137F7F7F9D9D9D9D3A9D9D9D9D9DFF5353 % 5353535353FF3A9D3A9D9D3A9D9D3A3A9D9D3A9D3A9D3A9D9D9D9D9D9D9D % 3A9D9D9D9DFF5353535353FFFFFF3A9D3A3A3A3A3A9D9D3A9D9D9D9D3A9D % 9D3A3A9D3A9D9D3A9D3A3A3A3AFF3A3A3A3A3A00FF000000002100181818 % 16C510121012101216121818181818181010101012101818161818171816 % 12161012161210181818181818181A18181800FF18181818121010101010 % 121618181818181818181A1818181A181818181818181818181818181818 % 181010101012101818181010101010101010101010181810AF181018FF7D % 00000000FF0000FFFFFFFFFF3A3A3A3A9D3A9D9D3A3A9D9D3A9D3A9D3A9D % 9D9D3A3A9D9D3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A9D9D3A9D9D3A9D9D % 3A9D3A9D9D9D9D9D3A9D3A9D3A9D3A9D3A9D3A9D9D3A9D3A9D9D3A9D9D3A % 9D9D9D9D3A9D9D7F7F137F7F1313137F7F3A3A9D9D9D3A9D3A9D9D9D9D3A % 3A9D9D9D3A9D9D3A9D9D3A9D3A3A3A3A3A3A7F7F13137F7F1313137F7F9D % 9D9D9D3AFFFF5353FFFF535353FFFF3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9DFFFF53FFFF535353FFFF9D9D9D9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A7F7F1313 % 7F7F1313137F7F9D3A3A9D9D3A9D9D3A3A9D9D9D3A9D9D9D9D3A9D9D9D9D % 3A9D9D9D9D9D3A9D7F7F137F7F1313137F7F9D9D3A9D9D9DFFFF53FFFF53 % 5353FFFF3A9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D9D3A9D3A9D9D9D3A3A9D % 9D9D9D3A3AFFFF53FFFF535353FFFF3A9D3A3A3A3A9D9D9D3A9D9D9D9D3A % 9D9D3A9D9D9D3A9D3A3A3A9DFFFFFFFFFFFFFFFF00000000210010181318 % C51010101012101210101210181818181818121012101018181818181818 % 121010101010121618181818181818181A00FF1012181010101010101010 % 1012181818181818181818181A181A181818181818181818181818181818 % 1012101010101812101810121010101010121012181818AF181618FF7D00 % 000000FF000000FFFFFF3A3A3A3A3A9D3A9D9D3A3A9D9D3A9D3A9D3A9D9D % 9D3A3A9D9D3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A9D9D3A9D9D3A9D9D3A % 9D3A9D9D9D9D9D3A9D3A9D3A9D3A9D3A9D3A9D9D3A9D3A9D9D3A9D9D3A9D % 9D9D9D3A9D7F13131313137F7F7F9D9D3A3A9D9D9D3A9D3A9D9D9D9D3A3A % 9D9D9D3A9D9D3A9D9D3A9D3A3A3A3A3A3A9D9D7F7F131313131313137F9D % 9D9DFF535353535353FFFFFF3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF53535353535353FF9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A7F1313131313 % 137F7F7F9D3A9D3A3A9D9D3A9D9D3A3A9D9D9D3A9D9D9D9D3A9D9D9D9D3A % 9D9D9D9D9D3A9D3A9D7F131313131313137F9D3A9D9DFF5353535353FFFF % FF9D3A3A9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D9D3A9D3A9D9D9D3A3A9D9D % 9D9D3A3A3A3AFF53535353535353FF9D3A3A3A3A9D9D9D3A9D9D9D9D3A9D % 9D3A9D9D9D3A9D3A3A3A9D3AFFFFFFFFFFFF0000000000210016181618C5 % 121012101012101012101210121818181818101012121218121012181010 % 1010101010101012181818181818181800FF121010101010081010101010 % 1010101218161818181A181A181818181817181818181818181818181818 % 10101010101010121012101018101010101012181818AF181818FF7D0000 % 0000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A % 9D3A3A3A3A3A3A9D9D9D9D9D3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D3A % 9D9D9D9D3A9D9D9D3A9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A % 9D9D9D9D7F131313131313137F3A9D9D3A9D3A9D9D3A9D9D3A9D3A9D3A9D % 9D9D9D9D9D3A3A3A9D9D9D3A9D3A9D3A9D9D3A7F131313131313137F9D9D % 9DFF53535353535353FF3A9D9D9D3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D3A % 9D3A3A3A3A3A3A9D9D3A3A3A3A9D3A3AFF53535353535353FF3A9D9D9D9D % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D9D9D9D9D9D3A3A3A3A3A9D % 3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A9D3A3A3A9D3A9D9D7F131313131313 % 137F9D9D3A9D3A9D9D3A9D3A3A3A9D9D3A9D9D9D9D3A9D9D3A9D9D3A9D3A % 9D9D9D9D3A9D9D9D7F131313131313137F9D3A9D9DFF53535353535353FF % 9D9D9D9D9D9D3A3A9D3A9D3A9D3A9D9D9D9D3A9D9D9D9D3A9D9D9D3A9D3A % 3A3A9D3A9DFF53535353535353FF3A9D3A3A3A3A3A9D9D9D3A9D9D9D9D3A % 9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A000000000000210018181818C518 % 181810181010121010121010101210181818181810101010121010101010 % 08101010101010101012181618181800FF101012101010100A0F0A101010 % 10101010121618181820181A181818181818121618181818181818181812 % 101010101010101010181818181712101816181818AF181818FF7D000000 % 00000000003A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D3A9D9D9D9D3A9D3A % 3A9D3A3A9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D9D3A9D9D9D9D9D9D3A9D3A % 9D9D9D9D9D9D9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D3A3A9D9D9D9D9D3A % 9D9D7F1313131313131313137F9D3A9D9D9D9D9D9D3A3A9D3A9D3A9D9D9D % 9D9D3A9D9D3A3A9D9D9D3A3A9D3A9D9D9D7F1313131313131313137F9DFF % 535353535353535353FF9D9D9D3A3A3A3A3A9D9D9D9D3A3A3A9D3A9D9D3A % 3A3A3A3A3A3A9D9D9D3A3A3A3A3AFF535353535353535353FF9D9D9D3A9D % 3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D3A % 3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D9D3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D3A9D9D7F1313131313131313 % 137F9D3A3A9D3A3A3A9D9D3A3A3A9D9D3A9D9D9D9D9D3A3A9D9D9D3A9D3A % 9D9D9D9D9D3A7F1313131313131313137F3A9DFF535353535353535353FF % 3A9D9D9D3A9D9D3A9D9D3A3A9D9D9D3A9D9D3A9D9D9D3A9D3A9D3A9D3A3A % 9D3A3AFF535353535353535353FF3A9D3A9D3A3A3A9D9D9D9D9D9D9D9D3A % 9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181818C51818 % 181812101210101210121012101012101816181612101010101210101010 % 0A0F0A101010101010101216181800FF10121010101010100A1010080A10 % 081010101818181A18181818181818101810181217181818181818181010 % 1010101010101012181818181818181818181818AF181818FF7D00000000 % 00FFFFFFFFFFFF3A3A3A3A3A3A3A9D3A3A9D3A9D9D3A9D9D9D9D3A9D3A3A % 9D3A3A9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D9D3A9D9D9D9D9D9D3A9D3A9D % 9D9D9D9D9D9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D3A3A9D9D9D9D9D3A9D % 9D7F1313131313131313137F9D3A9D9D9D9D9D9D3A3A9D3A9D3A9D9D9D9D % 9D3A9D9D3A3A9D9D9D3A3A9D3A9D9D9D7F1313131313131313137F9DFF53 % 5353535353535353FF9D9D9D3A3A3A3A3A9D9D9D9D3A3A3A9D3A9D9D3A3A % 3A3A3A3A3A9D9D9D3A3A3A3A3AFF535353535353535353FF9D9D9D3A9D3A % 3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D3A3A % 3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D3A9D9D7F131313131313131313 % 7F9D3A3A9D3A3A3A9D9D3A3A3A9D9D3A9D9D9D9D9D3A3A9D9D9D3A9D3A9D % 9D9D9D9D3A7F1313131313131313137F3A9DFF535353535353535353FF3A % 9D9D9D3A9D9D3A9D9D3A3A9D9D9D3A9D9D3A9D9D9D3A9D3A9D3A9D3A3A9D % 3A3AFF535353535353535353FF3A9D3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D % 9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181816C5181818 % 181612161012101010101010101010121818181818181012101010101010 % 0A1010080A100810101018181800FF181216121818181010101010081008 % 10101012181818181A181818181818101210101818121818121612161210 % 10100A10101012181818181818181818181A18AF181818FF7D00000000FF % FFFFFFFFFFFFFF3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D3A3A9D3A9D3A3A % 9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A9D3A9D9D3A9D9D9D3A9D9D3A % 9D9D9D3A9D3A9D3A3A9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D9D3A9D9D3A9D % 7F1313131313131313137F9D9D9D3A9D9D3A9D9D3A9D9D3A9D3A9D3A9D9D % 9D3A9D3A9D3A9D3A9D9D3A3A3A9D9D7F1313131313131313137F9DFF5353 % 53535353535353FF9D9D9D9D3A3A9D3A3A3A9D9D3A3A3A9D9D9D3A3A3A3A % 3A3A3A3A9D9D9D3A3A3A3A3AFF535353535353535353FF9D9D9D9D3A9D9D % 3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A % 3A3A3A3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A9D9D3A3A3A3A3A3A % 9D9D9D9D3A3A3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A % 9D3A3A3A9D3A3A9D3A3A3A3A3A9D9D9D3A9D3A7F1313131313131313137F % 9D3A9D3A9D9D9D9D3A3A3A9D9D9D3A9D9D9D9D9D9D3A9D3A3A9D9D9D9D3A % 9D9D3A9D7F1313131313131313137F9D9DFF535353535353535353FF9D9D % 9D9D9D9D3A9D3A9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A % 9DFF535353535353535353FF9D9D3A9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D % 9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181812C518181818 % 181210121018101812121612101010181818181818181216121818181010 % 10101008100810101012181800FF18161210181618101210101010080A10 % 101010101818181818181817121012161218101210101010121018121012 % 101010101012181818181A18181818181818AF181818FF7D00000000FF00 % 00003A3A3AFF3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D3A3A9D9D3A3A3A9D9D % 9D3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D3A9D9D9D9D3A3A9D9D9D9D % 9D9D9D3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D3A % 7F131313131313137F3A9D3A9D9D9D9D3A9D9D3A9D3A9D3A9D9D9D3A9D9D % 9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A7F131313131313137F9D9D9DFF5353 % 5353535353FF3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A3A3A3A3A3A % 3A3A3A9D9D9D3A3A3A3A3A3AFF53535353535353FF3A9D9D3A9D3A9D3A3A % 9D3A3A3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A3A3A9D3A3A9D9D9D3A3A3A % 3A3A3A3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D9D3A3A3A3A3A3A3A % 9D9D9D3A3A3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A % 3A3A9D9D3A3A3A3A3A3A3A9D9D9D9D3A9D3A9D7F131313131313137F9D9D % 3A3A9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D9D9D3A3A9D9D9D3A9D9D9D3A % 9D9D3A9D7F131313131313137F9D3A9D9DFF53535353535353FF9D9D9D9D % 9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A3A9D % 9DFF53535353535353FF3A3A9D9D3A3A3A9D3A3A9D9D9D9D9D3A3A9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181010C51818171818 % 101810181018181818181818181210121218161818161210181618101210 % 101010080A10101010101800FF1012101012181818181012101010101010 % 101218181818181818181812101218121012101210121010181216121010 % 10101010101818181A181A18181A181A18AF181810FF7D00000000FF0000 % 003A3A3AFF3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D3A3A9D9D3A3A3A9D9D9D % 3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D3A9D9D9D9D3A3A9D9D9D9D9D % 9D9D3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D3A7F % 131313131313137F3A9D3A9D9D9D9D3A9D9D3A9D3A9D3A9D9D9D3A9D9D9D % 9D9D9D9D9D3A9D9D3A9D3A9D9D3A7F13131313137F7F7F9D9D9DFF535353 % 53535353FF3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A3A3A3A3A3A3A % 3A3A9D9D9D3A3A3A3A3A3AFF5353535353FFFFFF3A9D9D3A9D3A9D3A3A9D % 3A3A3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A3A3A9D3A3A9D9D9D3A3A3A3A % 3A3A3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D9D3A3A3A3A3A3A3A9D % 9D9D3A3A3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A % 3A9D9D3A3A3A3A3A3A3A9D9D9D9D3A9D3A9D7F131313131313137F9D9D3A % 3A9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D9D9D3A3A9D9D9D3A9D9D9D3A9D % 9D3A9D7F13131313137F7F7F9D3A9D9DFF53535353535353FF9D9D9D9D9D % 9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A3A9D9D % FF535353535353FFFFFF3A9D9D3A3A3A9D3A3A9D9D9D9D9D3A3A9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A000000000000210018101210C5C5C5C5C5C5C5 % 18181818181818181A181818181210101012181012101012181818181012 % 1010101010101012181800FF181012101210101012101210100A08101010 % 101012101218101810121010101010181818181010101010101210121810 % 181012121818181A1818181818181818AF181010FF7D00000000FFFFFFFF % FFFFFFFF3A3A3A3A9D3A9D9D9D3A9D3A3A9D9D3A9D3A3A3A9D9D9D3A3A3A % 9D9D3A9D3A9D9D3A3A3A3A9D9D3A3A3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D % 3A9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D7F7F137F % 7F1313137F7F9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D9D3A9D % 9D9D3A9D9D9D9D9D3A9D3A9D9D9D7F7F137F7F1313137FFFFF53FFFF5353 % 53FFFF3A3A9D9D9D3A3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A9D3A3A3A3A3A % 3A9D9D3A3A3A3A3A3A3A3AFFFF53FFFF535353FFFF9D9D9D3A9D3A9D3A3A % 9D3A3A3A9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A % 3A3A3A9D9D3A3A3A9D3A3A3A9D9D9D3A9D3A3A9D9D3A3A3A3A3A3A9D9D9D % 9D9D9D3A3A9D9D3A9D9D9D3A3A3A3A9D3A3A3A9D9D9D9D3A3A3A3A3A3A9D % 3A9D3A3A3A3A3A3A3A9D9D9D9D3A9D7F7F137F7F1313137F7F9D9D9D3A9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D3A9D9D9D9D9D % 9D3A9D7F7F137F7F1313137F7FFFFF53FFFF535353FFFF9D3A9D9D9D9D9D % 9D9D3A9D3A3A9D3A9D9D9D9D9D9D3A9D9D3A9D9D3A3A9D3A9D9D9D3A3A3A % FFFF5353FFFF535353FFFF3A9D9D9D3A9D3A3A9D9D3A9D3A9D9D9D9D3A9D % 3A3A3A3A3A3A3A3A3A3A000000000000210010101010C510101010121010 % 101012101818181818181818181818181018181012101210101012101210 % 100A0810101010101200FF18181810101010121012161010101010101010 % 101010121012121010101010101018181818181810181010101012101816 % 121816181818181818181818181818AF181010FF7D0000000000FFFFFFFF % FFFF3A3A3A3A3A9D3A9D9D9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A3A3A9D9D % 9D9D3A9D3A9D9D9D3A3A3A9D9D3A3A3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F1313131313 % 7F7F7F9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D7F1313131313FF5353535353FFFFFF % 3A3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A % 9D9D9D3A3A9D3A3A3A3A3A9DFF53535353535353FF3A9D9D3A9D3A3A3A3A % 3A3A3A9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A % 3A9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A9D9D3A3A3A3A3A3A9D9D3A9D % 9D3A9D3A9D9D3A3A9D9D3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D9D9D9D9D9D7F13131313137F7F7F9D9D9D9D3A3A3A9D % 9D9D3A9D3A3A9D9D3A9D9D9D9D9D3A9D9D3A3A3A3A9D9D3A9D3A9D9D9D3A % 3A9D3A9D7F131313131313FF5353535353FFFFFF3A9D9D9D9D9D9D9D9D9D % 9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D9D3A3A3A9D % 9DFFFF53535353535353FF9D9D3A3A3A9D3A3A9D9D9D9D3A9D9D9D3A9D3A % 3A3A3A3A3A3A3A3A3A000000000000210010101010C51010101012101210 % 121018181718181618181818181818181818181810101010121012161010 % 101010101010101000FF1818171818181810101210121010101010101010 % 101010101010101010081010101218181818181818101010101010181212 % 161818181A161818181816181818AF101210FF7D00000000000000003A3A % 3A3A3A3A3A3A9D3A9D9D9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A3A3A9D9D9D % 9D3A9D3A9D9D9D3A3A3A9D9D3A3A3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F131313131313 % 137F9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D3A9D9D9D9D7F1313131313FF53535353535353FF3A % 3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A9D % 9D9D3A3A9D3A3A3A3A3A9DFF53535353535353FF3A9D9D3A9D3A3A3A3A3A % 3A3A9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A % 9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A9D9D3A3A3A3A3A3A9D9D3A9D9D % 3A9D3A9D9D3A3A9D9D3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A9D9D9D9D9D9D7F131313131313137F9D9D9D9D3A3A3A9D9D % 9D3A9D3A3A9D9D3A9D9D9D9D9D3A9D9D3A3A3A3A9D9D3A9D3A9D9D9D3A3A % 9D3A9D7F131313131313FF53535353535353FF3A9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D9D3A3A3A9D9D % 9DFF53535353535353FF9D9D3A3A3A9D3A3A9D9D9D9D3A9D9D9D3A9D3A3A % 3A3A3A3A3A3A3A3A000000000000210012101010C5101210181818101810 % 181018121818181818181818181818181818171818181810101210121010 % 1010101010101000FF121818181818181012101810181816121818181210 % 10101210101010100A081010181818181818181818121010101012101012 % 12181818181816181818181816AF101010FF7D00000000000000003A3A3A % 3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D3A3A3A9D9D3A3A9D3A9D3A9D3A % 9D9D3A9D9D9D9D3A3A3A9D9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313 % 137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313FF535353535353535353FF3A % 3A3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A9D9D3A9D9D % 9D3A3A3A3A3A3A3A3AFF535353535353535353FF9D3A9D3A3A3A3A3A3A3A % 3A9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A9D9D3A9D9D3A3A9D3A3A3A3A3A3A3A9D9D9D9D3A9D % 3A3A3A3A9D3A9D9D3A3A3A3A3A3A3A9D9D9D9D3A9D3A3A3A3A3A3A9D9D3A % 3A3A3A3A3A3A9D9D9D9D7F1313131313131313137F9D3A3A3A9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D7F131313131313FF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D9D9D3A3A3A9D3A9D9DFF % 535353535353535353FF9D9D9D3A3A9D3A9D9D3A9D9D9D3A9D3A9D3A3A3A % 3A3A9D3A3A3A3A000000000000210010101010C512161818181818181210 % 121012101810181818181818181818121818181818181012101810181816 % 12181818121000FF10121012101212101012121618181818181818181818 % 101818131610101010101210181818181818181010101010101010101010 % 121018181818181818181818AF121010FF7D00000000000000003A3A3A3A % 9D3A3A3A9D3A9D9D9D9D9D3A9D3A3A9D3A9D9D9D3A3A3A9D9D3A9D3A9D9D % 9D3A9D3A3A9D9D9D3A3A9D9D3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D3A9D % 9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D3A9D9D7F131313131313131313 % 7F3A9D3A9D9D3A3A9D9D9D9D3A9D9D9D3A9D9D3A9D9D9D9D9D3A9D9D9D9D % 9D3A9D9D3A9D3A9D9D3A9D7F1313131313FF535353535353535353FF3A3A % 3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D % 3A3A3A3A3A3A3A3AFF535353535353535353FF9D3A9D3A3A3A3A3A3A3A9D % 9D9D9D3A3A3A9D3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A9D % 9D3A3A3A3A3A3A3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D % 9D9D9D3A9D3A3A3A3A9D3A3A3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A9D3A3A % 3A3A3A9D3A3A3A9D9D7F1313131313131313137F3A9D3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 7F131313131313FF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A3A9D3A9D3A9DFF53 % 5353535353535353FF3A3A9D9D9D3A3A3A9D3A3A9D9D9D9D3A3A3A3A3A3A % 3AFF3A3A3A3A00FF00000000210010101010C518181818181A1818181010 % 101010121012101812161818181010121012101212101012121618181818 % 181818181800FF1210101210101010181010121818181818181A181A1818 % 181718181218181810101810181218181012101210101818101010101010 % 1212181818181818181818AF101210FF7D00000000000000003A3A3A3A9D % 3A3A3A9D3A9D9D9D9D9D3A9D3A3A9D3A9D9D9D3A3A3A9D9D3A9D3A9D9D9D % 3A9D3A3A9D9D9D3A3A9D9D3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D3A9D9D % 9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D3A9D9D7F1313131313131313137F % 3A9D3A9D9D3A3A9D9D9D9D3A9D9D9D3A9D9D3A9D9D9D9D9D3A9D9D9D9D9D % 3A9D9D3A9D3A9D9D3A9D7F1313131313FF535353535353535353FF3A3A3A % 9D9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D3A % 3A3A3A3A3A3A3AFF535353535353535353FF9D3A9D3A3A3A3A3A3A3A9D9D % 9D9D3A3A3A9D3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A9D9D % 3A3A3A3A3A3A3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D9D % 9D9D3A9D3A3A3A3A9D3A3A3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A9D3A3A3A % 3A3A9D3A3A3A9D9D7F1313131313131313137F3A9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F % 131313131313FF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A3A9D3A9D3A9DFF5353 % 53535353535353FF3A3A9D9D9D3A3A3A9D3A3A9D9D9D9D3A3A3A3A3A3A3A % FF3A3A3A3A00FF00000000210012101010C51818181A1818181818121010 % 101010121010101012101818101210101210101010181010121818181818 % 181A181A00FF1818121010121012121012101018181618181A1818181818 % 181818171818181612121012101010181810101212181018181010101210 % 101818181A1818181818AF161210FF7D00000000000000003A3A3A3A3A3A % 3A3A9D3A9D9D3A9D9D9D9D3A9D3A3A3A9D3A3A9D9D9D3A3A9D9D3A9D9D3A % 9D3A9D9D9D3A3A3A9D9D3A9D3A3A9D9D3A9D9D3A3A9D3A9D9D3A9D3A3A3A % 3A3A9D9D3A3A3A3A9D3A3A3A9D3A9D9D3A9D3A7F131313131313137F3A9D % 9D9D9D3A9D3A9D9D3A9D3A9D9D3A9D3A9D3A9D3A3A9D3A9D3A3A9D9D3A9D % 9D9D3A9D3A9D3A9D3A3A7F1313131313FF53535353535353FF3A3A3A3A9D % 9D9D9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D9D3A3A % 3A3A3A3A3A3A9DFF53535353535353FF9D3A9D3A9D3A3A9D3A3A3A3A9D9D % 9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A9D9D3A % 3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A3A3A3A3A3A9D9D3A3A3A % 3A3A3A3A9D9D9D9D7F131313131313137F9D3A9D9D3A9D9D3A9D9D9D9D9D % 3A9D9D3A9D3A9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D7F % 131313131313FF53535353535353FF3A9D3A9D3A9D3A9D9D3A3A9D3A9D3A % 9D9D9D9D3A9D3A3A9D3A9D3A9D9D3A9D9D9D3A9D9D9D9D3A3A9D9DFF5353 % 5353535353FF9D3A3A9D9D3A3A9D3A3A9D9D3A9D9D9D3A9D3A3A3A3AFFFF % FFFFFFFFFFFF00000000210012101212C518181818181A18181810100B0E % 10101010100E101010121818181812101012101212101210101818161818 % 1A181800FF18181818121010181010101012181810101818181818121012 % 101818181818181810101010101018181012101010181818181816121612 % 181818AFAFAFAFAFAFAF181018FF7D00000000000000003A3A3A3A3A3A3A % 3A9D3A9D9D3A3A9D9D3A3A9D9D3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D % 9D9D9D3A3A3A9D3A9D9D3A3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D % 3A9D9D3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D7F131313131313137F9D3A3A % 9D3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A3A9D3A9D3A9D3A9D9D3A9D3A3A9D % 3A9D3A9D3A3A9D3A9D7F1313131313FF53535353535353FF3A3A3A3A9D9D % 9D3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3AFF53535353535353FF3A3A9D9D3A3A3A3A3A3A3A3A9D9D3A % 3A3A3A3A9D9D9D9D3A9D3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A % 3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D % 9D9D3A3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A9D9D9D3A7F131313131313137F3A3A9D3A3A9D3A9D3A3A9D3A9D3A % 9D3A9D9D9D3A9D3A9D9D3A9D3A9D3A9D3A9D3A3A9D3A3A3A3A3A9D9D7F13 % 1313131313FF53535353535353FF9D3A3A9D9D9D9D3A9D9D9D9D9D3A3A9D % 3A9D3A9D3A9D9D3A9D3A3A9D3A3A3A9D3A3A3A9D9D3A9D9D9D9DFF535353 % 53535353FF3A9D3A3A9D9D9D3A9D3A9D3A9D3A9D9D3A9D3A3A3A3AFFFFFF % FFFFFFFFFF00000000210010181316C5181818181A181A18181210101010 % 1010100A100A101012161818181818121010181010101012181810101818 % 181800FF1618181818181018181810121010101818161818181618101010 % 18131618181A181818121010101810181210181813181818181818181818 % 1818181818181818AF181012FF7D00000000000000003A3A3A3A3A3A3A3A % 9D3A9D9D3A3A9D9D3A3A9D9D3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D3A3A3A9D3A9D9D3A3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D3A % 9D9D3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D7F7F7F1313137F7F9D9D3A3A9D % 3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A3A9D3A9D3A9D3A9D9D3A9D3A3A9D3A % 9D3A9D3A3A9D3A9D3A7F7F131313FFFFFF535353FFFF3A3A3A3A3A9D9D9D % 3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3AFFFF535353FFFFFF3A3A9D9D3A3A3A3A3A3A3A3A9D9D3A3A % 3A3A3A9D9D9D9D3A9D3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A3A % 3A3A3A3A3A9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D % 9D3A3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A9D9D9D3A7F7F7F1313137F7F9D3A3A9D3A3A9D3A9D3A3A9D3A9D3A9D % 3A9D9D9D3A9D3A9D9D3A9D3A9D3A9D3A9D3A3A9D3A3A3A3A3A9D9D3A7F7F % 131313FFFFFFFF535353FFFF3A9D3A3A9D9D9D9D3A9D9D9D9D9D3A3A9D3A % 9D3A9D3A9D9D3A9D3A3A9D3A3A3A9D3A3A3A9D9D3A9D9D9D9D9DFFFF5353 % 53FFFFFF3A9D3A3A9D9D9D3A9D3A9D3A9D3A9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A00FF00000000210010121618C518181A181A18181818181818181010 % 0A1010101010101012181618181818181018181810121010101818161818 % 1800FF121818181818181818171210101010121012181018121818181812 % 161812161818181818101810121012161818101818181818181818181818 % 1818181A181818AF181818FF7D00000000000000003A3A3A3A3A3A3A3A3A % 3A9D9D9D9D9D9D3A9D3A3A9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D3A9D3A9D9D3A9D3A9D3A9D3A9D9D3A3A9D9D9D3A3A9D9D3A9D9D3A % 9D3A9D9D3A9D9D9D3A9D9D9D3A3A7F7F1313137F7F7F9D9D9D3A9D3A9D9D % 9D3A3A9D9D3A9D3A9D3A3A9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A9D9D3A9D % 3A3A9D3A9D3A9D3A9D9D7FFFFF535353FFFFFF9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3AFFFFFF535353FFFF9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A9D3A3A % 9D3A3A3A3A3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D9D3A7F7F1313137F7F7F3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A9D3A9D % 3A9D9D3A9D3A9D3A9D3A3A3A3A9D3A9D3A9D3A3A9D3A3A9D3A3A9D3A9D7F % FFFF535353FFFFFFFF3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D3A9D3A3A9D3A % 3A9D3A9D9D3A9D3A3A9D3A9D9D3A3A9D9D3A9D9D9D9D9D9D9D9D9DFFFFFF % 535353FFFF9D3A3A9D3A9D9D3A9D9D9D9D9D9D3A9D3A3A9D3A3A3A3A3A3A % 3A00FF00000000210018181818C518181818181818181216181812101010 % 121010101010101012121818181818181818171210101010121012181018 % 00FF10121612181610181818121612101012101210121618181818181818 % 12101810121618161818181018101210121018161818181818181A181A18 % 181818181818AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A % 9D3A9D9D9D9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 9D3A9D3A3A3A9D9D3A9D3A9D3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A9D3A9D3A3A3AFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9DFF53535353535353FF9D3A9D9D9D3A9D9D9D9D9D9D3A9D3A % 9D9D3A9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D7F131313131313137F3A9D3A3A3A9D9D3A3A3A9D9D3A3A3A3A3A3A9D3A % 9D3A9D9D3A9D3A9D3A9D9D3A3A3A9D9D3A3A9D9D3A9D9D9D9D3A9D9DFF53 % 535353535353FF3A9D3A9D3A3A3A9D3A9D9D3A9D3A3A9D9D9D3A9D9D9D3A % 3A3A9D3A9D3A9D3A3A9D3A9D3A9D3A9D9D9D3A3A3A3A3A3A3A3AFF535353 % 53535353FF3A3A9D9D9D3A9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 000000000000210018181818C51018181818181812101012161818121018 % 101010101010101010121612181610181818121612101012101210121600 % FF1010121012181218161810121012101010101010121216181818161810 % 18101012101218181818161210181012101212101818181818181818181A % 18181A1E18AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D % 3A9D9D9D9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A9D3A3A3A9D9D3A9D3A9D3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A9D3A3A3AFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9DFF53535353535353FF9D3A9D9D9D3A9D9D9D9D9D9D3A9D3A9D % 9D3A9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D % 9D9D9D3A9D9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 7F131313131313137F3A9D3A3A3A9D9D3A3A3A9D9D3A3A3A3A3A3A9D3A9D % 3A9D9D3A9D3A9D3A9D9D3A3A3A9D9D3A3A9D9D3A9D9D9D9D3A9D9DFF5353 % 5353535353FF3A9D3A9D3A3A3A9D3A9D9D3A9D3A3A9D9D9D3A9D9D9D3A3A % 3A9D3A9D3A9D3A3A9D3A9D3A9D3A9D9D9D3A3A3A3A3A3A3A3AFF53535353 % 535353FF3A3A9D9D9D3A9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00 % 0000000000210018181818C5181818181818181810101210181216181810 % 1210101210101010101210121812181618101210121010101010101200FF % 101010101012161218101812161210101012101210101210181218181818 % 181810181810121210121810121010101010121012181818181818181818 % 1A181A18AF181818FF7D0000000000FFFFFFFFFFFF3A3A3A3A3A9D3A9D9D % 9D3A9D9D9D3A9D3A9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A3A3A9D3A9D9D3A % 9D9D9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A9D3A3AFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9DFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D % 3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F13 % 13131313131313137F3A9D3A3A9D3A9D9D3A3A3A3A9D3A3A3A9D3A3A3A3A % 9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3AFF53535353 % 5353535353FF3A3A3A9D3A3A3A9D9D3A9D3A9D9D3A3A3A9D3A3A3A3A9D3A % 9D3A3A3A9D3A3A3A9D9D3A9D9D9D9D3A9D9D3A3A3A9D3AFF535353535353 % 535353FF3A9D9D3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A0000 % 00000000210018181818C51818181A181818181010121012101210121810 % 12101010121010101010101216121810181216121010101210121000FF10 % 101012181818161818181018161810101010101012101210101218161818 % 181818101210101018161210121010101010101210121612181818181A18 % 201E1AAF1A1818FF7D00000000FFFFFFFFFFFFFFFF3A3A3A3A9D3A9D9D9D % 9D9D3A9D9D3A9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D3A9D9D9D % 3A9D3A3A9D9D9D3A9D9D3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D % 3A3A3A9D3A3A3A9D7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 9D9D3A3A9DFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9DFF535353535353535353FF3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D % 9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F1313 % 131313131313137F9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A9D3A9D3A9D9D3A3A9D9D3A3A9D9D3A3A3A3A3A3AFF53535353535353 % 5353FF3A3A9D9D9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000 % 000000210018181818C51818181818181818181812101010101018101818 % 181812101010101012181818161818181018161810101010101000FF1810 % 121018181818121810181818181810121012101010101012101012121018 % 18101810101010181210101010101010101010101010101818181818181A % 181AAF181818FF7D00000000FF0000003A3A3AFF3A3A3A3A9D3A9D9D9D9D % 9D3A9D9D3A9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D3A9D9D9D3A % 9D3A3A9D9D9D3A9D9D3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D3A % 3A3A9D3A3A3A9D7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D3A3A9DFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9DFF535353535353535353FF3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D % 3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F131313 % 1313131313137F9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A9D3A9D3A9D9D3A3A9D9D3A3A9D9D3A3A3A3A3A3AFF5353535353535353 % 53FF3A3A9D9D9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000 % 0000210018181816C5181818181818181818121010101010101012101818 % 1818181818101210181818181218101818181818101210121000FF1A1818 % 181618181816181818181618181818101010101012121012101010101218 % 101210121010181016121010101010101010101010101018181818181818 % 20AF1A1818FF7D00000000FF0000003A3A3AFF3A3A3A3A9D3A9D3A9D3A9D % 3A9D9D3A9D3A3A9D3A9D9D9D9D3A3A3A3A3A9D3A3A9D9D3A9D9D9D3A9D9D % 3A3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D7F131313131313137F9D3A9D9D3A9D3A9D3A3A3A3A3A9D % 9D3A3A3A9D3A3A3A3A3A9D3A3A9D3A3A9D3A3A3A9D3A9D3A3A3A9D3A3A3A % 9D9D3A9DFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9DFF53535353535353FF9D3A9D3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D3A9D9D3A % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F131313 % 131313137F3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353 % 53FF3A9D3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A9D3A % 9D3A9D3A9D9D3A3A9D9D9D9D9D9D3A9D3A3A3A3A3AFF53535353535353FF % 9D3A3A9D9D3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000 % 00210018181812C512101818181012161216101010101012101018181818 % 1818181A181818161818181618181818161818181810101000FF18181818 % 1A1818181810181018181816181216121018101010121010101010101012 % 10121618181218181818181010101010101010101010121018181A202118 % AF181818FF7D00000000FFFFFFFFFFFFFFFF3A3A3A3A3A3A9D9D3A9D3A3A % 9D9D3A9D3A9D9D9D9D3A9D9D9D3A3A3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D % 3A9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A9D3A7F131313131313137F3A3A3A3A9D3A9D3A9D3A3A9D9D3A3A % 9D3A9D3A9D3A3A3A9D9D9D9D9D3A3A3A3A9D9D3A3A9D9D9D3A3A3A3A3A9D % 3A3A9DFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF53535353535353FF9D3A3A9D3A3A3A3A9D3A3A3A3A9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D9D3A3A3A3A3A9D3A3A3A9D % 3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A7F13131313 % 1313137F9D3A9D3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D3A9D3A3A3A3A9D3A % 9D3A3A3A9D3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A9D9DFF53535353535353 % FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D % 3A9D3A3A3A3A9D9D3A3A9D9D9D3A3A3A3A3A3A9DFF53535353535353FF9D % 9D3A9D9D3A9D3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000 % 210018181016C5101210101210181018181310100A08081010101216181A % 1818181818181A1818181810181018181816181216121000FF1818181818 % 181A18101812121212181818181012101210101216181818181210121018 % 1018121816121816181818181010101010101010101012181818201A18AF % 181212FF7D0000000000FFFFFFFFFFFF3A3A3A3A3A3A3A9D9D3A9D3A3A9D % 9D3A9D3A9D9D9D9D3A9D9D9D3A3A3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D3A % 9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A9D3A9D7F7F1313137F7F9D3A3A3A3A9D3A9D3A9D3A3A9D9D3A3A9D % 3A9D3A9D3A3A3A9D9D9D9D9D3A3A3A3A9D9D3A3A9D9D9D3A3A3A3A3A9D3A % 3A9D3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FFFF535353FFFF3A9D3A3A9D3A3A3A3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D9D3A3A3A3A3A9D3A3A3A9D3A % 9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A7F7F131313 % 7F7F3A9D3A9D3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D3A9D3A3A3A3A9D3A9D % 3A3A3A9D3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A9D9D3AFFFF535353FFFF3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D3A % 9D3A3A3A3A9D9D3A3A9D9D9D3A3A3A3A3A3A9D3AFFFF535353FFFF3A9D9D % 3A9D9D3A9D3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021 % 0012121812C510181012101810121816181810101008101010181818181A % 181818181818181A181018121212121818181810121000FF1A181A181A18 % 181818121010101010181210101012101216121818181818181818181812 % 1618121012101212161818101010121010100E101010121818181818AF10 % 1010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D3A9D9D3A3A9D3A % 3A3A3A9D9D3A3A9D9D9D3A3A3A3A3A3A3A3A9D9D9D3A3A9D9D3A9D9D3A3A % 9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A7F7F7F7F7F7F7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3AFFFFFFFFFFFF7F7F7F9D3A9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D % 9D3A9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D3A3A % 9DFFFFFFFFFFFFFF9D9D9D3A9D3A9D3A9D9D3A9D3A3A9D9D9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A9D3A3A9D3A9D3A9D9D9D9D9D3A % 3A9D9D3A3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D3A9D9D % 9D3A9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D7F7F7F7F7F7F9D % 3A3A3A9D9D9D3A3A3A3A3A3A3A3A9D3A9D3A3A9D9D3A9D9D9D9D9D3A3A9D % 3A3A3A9D9D9D3A9D3A3A9D3A9D3A9D9D3A9D3A3AFFFFFFFFFFFF7F7F7F7F % 3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A9D3A3A9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A9D9DFFFFFFFFFFFF9D9D3A % 3A9D9D9D3A9D9D9D3A9D3A9D3A3A9D3A3A3A3A3A3A3A0000000000002100 % 10101210C5181818181012101210181818181210101010121818181A1818 % 1A181A181A1818181812101010101018121010101200FF18181818181818 % 181810101010101018181012101010121012161818181818181818181818 % 131612101010101212181012101010101010101010101216181812AF1210 % 12FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D3A9D9D9D3A % 3A3A9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D9D9D3A9D % 9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D % 7F7F1313137F7F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A9D3AFFFF % 535353FFFF7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 9D3AFFFF535353FFFF9D9D9D9D3A3A3A3A9D3A9D3A3A3A9D3A9D3A9D3A9D % 3A3A9D3A9D9D9D3A3A3A3A3A9D3A9D3A3A9D9D3A9D9D3A9D9D3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A9D3A9D3A9D3A3A9D % 3A3A9D3A9D3A9D3A9D3A9D9D3A3A9D3A9D3A9D9D7F7F1313137F7F9D3A9D % 9D3A9D3A9D3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D9D9D3A3A3A3A3A9D3A3A3A3A3A3A9DFFFF535353FFFF7F7F1313137F % 7F3A3A9D3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D9D9D9D9D3A3A9D3A3A9D3A % 9D3A3A9D9D9D3A9D3A9D9D3A3A3A9D3A3A3A9D9D9DFFFF535353FFFF3A9D % 9D3A9D3A9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A000000000000210010 % 121012C5181818181812101010101218181818121012101818181A181818 % 181818181818181810101010101018181012101000FF1818181818181818 % 121010101010101818101010101218101012181818181818181818181816 % 1818181210101010121612181010121010101010101210121010AF101010 % FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D3A9D9D9D3A3A % 3A9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D9D9D3A9D9D % 3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A7F13 % 1313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A9DFF535353 % 53535353FF13131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % FF53535353535353FF9D9D9D3A3A3A3A9D3A9D3A3A3A9D3A9D3A9D3A9D3A % 3A9D3A9D9D9D3A3A3A3A3A9D3A9D3A3A9D9D3A9D9D3A9D9D3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A9D3A9D3A9D3A3A9D3A % 3A9D3A9D3A9D3A9D3A9D9D3A3A9D3A9D3A9D7F131313131313137F3A9D9D % 3A9D3A9D3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D9D9D3A3A3A3A3A9D3A3A3A3A3A3AFF53535353535353FF131313131313 % 7F3A9D3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D9D9D9D9D3A3A9D3A3A9D3A9D % 3A3A9D9D9D3A9D3A9D9D3A3A3A9D3A3A3A9D9DFF53535353535353FF9D9D % 3A9D3A9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A00000000000021001010 % 1012C518181818181810121010101010121618121618181818181A181818 % 1818181818181210101010101018181010101000FF181818181818181810 % 121010101010181618181216121010101210181810121818181818181818 % 18181816121010101812161210101010101012101012101012AF101010FF % 7D00000000000000003A3A9D3A3A3A3A3A9D3A9D9D9D9D3A9D3A9D3A3A9D % 9D9D9D3A9D9D3A9D3A3A3A3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D3A3A9D9D % 9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D3A3A3A3A7F1313 % 13131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3AFF53535353 % 535353FF13131313137F3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A9D9D9D9D % 9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D3A9D3A3A3AFF % 53535353535353FF3A9D9D9D9D9D9D9D9D3A3A9D9D9D3A9D3A3A3A3A3A9D % 9D3A9D9D9D9D9D3A3A3A9D9D9D3A3A9D3A3A9D3A9D3A9D3A9D9D9D9D3A3A % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D3A9D3A9D9D3A9D3A % 9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D3A7F131313131313137F9D9D9D3A % 9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A9D9D3A3A3A9D3AFF53535353535353FF1313131313137F % 3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D3A9D3A9D9D3A3A3A3A9D3A9D9D3A % 3A9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A9D9DFF53535353535353FF3A9D9D % 9D9D3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100101010 % 10C51818181A181812101010100808101012101812171818181818181818 % 18181818181012101010101018161818121600FF12161818101810181210 % 121010101212181818181812101010121613101210181618181818181818 % 181818181010101216121012101216181810181012101216AF101010FF7D % 00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D3A9D3A9D9D % 3A9D9D9D9D3A9D9D3A3A3A3A3A3A9D9D3A9D9D3A9D9D3A9D9D3A9D9D9D9D % 3A3A3A3A9D3A3A3A3A3A9D3A3A3A9D9D9D3A3A3A3A3A3A3A3A7F13131313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFF535353535353 % 535353FF13131313137F9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D % 9D9D9D9D3A9D9D9D9D3A9D3A3A9D9D3A9D9D3A9D9D3A9D3A9D9D3AFF5353 % 53535353535353FF9D9D3A9D9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D9D3A3A3A3A3A9D3A9D3A9D3A9D3A9D9D9D9D9D3A3A9D9D % 3A9D9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D % 3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A7F1313131313131313137F9D9D9D9D % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3AFF535353535353535353FF1313131313137F % 3A3A3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A9D3A3A % 9D9D9D9D9D3A3A9D9D3A3A3A3A3A3A9DFF535353535353535353FF9D3A9D % 3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A000000000000210010101010 % C51818181818181818101010100A10101010121612181818181812161818 % 101810181210121010101212181818181800FF1012101012161210101010 % 121012161818181A18181210181218181818101218121216181818181218 % 1818181810121018101810181012181818181812161218AF101010FF7D00 % 000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D3A9D3A9D9D3A % 9D9D9D9D3A9D9D3A3A3A3A3A3A9D9D3A9D9D3A9D9D3A9D9D3A9D9D9D9D3A % 3A3A3A9D3A3A3A3A3A9D3A3A3A9D9D9D3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFF53535353535353 % 5353FF13131313137F9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D % 9D9D9D3A9D9D9D9D3A9D3A3A9D9D3A9D9D3A9D9D3A9D3A9D9D3AFF535353 % 535353535353FF9D9D3A9D9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D9D3A3A3A3A3A9D3A9D3A9D3A9D3A9D9D9D9D9D3A3A9D9D3A % 9D9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A % 9D3A3A3A3A3A9D3A3A3A3A9D3A3A7F1313131313131313137F9D9D9D9D9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3AFF535353535353535353FF1313131313137F3A % 3A3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A9D3A3A9D % 9D9D9D9D3A3A9D9D3A3A3A3A3A3A9DFF535353535353535353FF9D3A9D3A % 3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A000000000000210010101010C5 % 1818181A20181818101210101010100A1012101818181818121012101012 % 161210101010121012161818181A181800FF181818181810121612161216 % 1218181818181A1818181010101010121018101010101218181818101210 % 10101018181012101812181816181A18181818181618AF181818FF7D0000 % 0000000000003A3A3A3A9D3A3A3A3A3A9D9D9D9D3A9D3A9D3A3A9D9D9D9D % 9D9D9D3A9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D3A3A9D3A9D9D3A % 3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353535353535353 % 53FF13131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A9D9D3A3A3A3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D3A9D3A3AFF53535353 % 5353535353FF9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D3A9D9D3A % 9D3A9D9D3A3A9D3A3A3A9D3A9D3A3A9D3A9D3A9D3A9D9D3A3A3A9D3A3A9D % 9D9D9D3A9D9D9D9D9D3A9D3A9D3A9D3A9D3A9D9D9D9D3A3A9D3A9D3A9D3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A9D3A9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3AFF535353535353535353FF1313131313137F3A3A % 3A3A3A9D3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D % 3A9D9D3A9D3A3A3A3A3A3A9D3A9DFF535353535353535353FF9D9D9D3A3A % 9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181010C510 % 101216181818181810121010101010101010101012101818181818181810 % 1216121612161218181818181A181800FF1A181818101210181012101216 % 181818181818181818181010101010101010101010101216181818101012 % 1012181810101216121618181818181A1818181818AF181816FF7D000000 % 00000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A3A9D9D9D3A3A9D9D3A3A9D % 9D9D3A9D9D3A3A9D3A3A3A9D9D9D9D9D3A9D9D9D3A9D3A3A9D9D9D3A3A3A % 3A9D3A3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A9D3A3A3A3A7F131313131313 % 137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF53535353535353FF % 13131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D3A9D3A3A9D3A % 3A3A3A9D3A9D3A9D9D3A9D9D9D3A3A9D9D3A9D9D3A9D3A3A9DFF53535353 % 535353FF9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D3A9D9D % 3A9D9D3A9D3A3A3A9D3A9D9D3A3A9D3A9D9D9D3A9D9D9D3A3A9D3A3A9D9D % 3A9D3A9D3A3A9D9D9D3A9D3A9D3A9D3A9D9D9D3A3A3A9D9D3A9D3A9D3A3A % 3A3A9D3A3A3A3A3A3A3A9D3A3A7F131313131313137F9D9D3A9D3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A9D3A3A3A3A3AFF53535353535353FF1313131313137F3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A9D9D3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D9D9D % 9D9D3A9D9D9D3A3A3A3A3A3A9D9DFF53535353535353FF3A9D3A9D9D3A9D % 9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018161818C51010 % 10121810181018121010101012101010101210121618181A181818101210 % 181012101216181818181818181800FF1818181818111813161216121818 % 181818181A18181818101010101010100A10101010101218181818181012 % 1612181012101813181818181818181818181810AF161318FF7D00000000 % 000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A3A9D9D9D3A3A9D9D3A3A9D9D % 9D3A9D9D3A3A9D3A3A3A9D9D9D9D9D3A9D9D9D3A9D3A3A9D9D9D3A3A3A3A % 9D3A3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A9D3A3A3A3A7F13131313131313 % 7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF53535353535353FF13 % 131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D3A9D3A3A9D3A3A % 3A3A9D3A9D3A9D9D3A9D9D9D3A3A9D9D3A9D9D3A9D3A3A9DFF5353535353 % 5353FF9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D3A9D9D3A % 9D9D3A9D3A3A3A9D3A9D9D3A3A9D3A9D9D9D3A9D9D9D3A3A9D3A3A9D9D3A % 9D3A9D3A3A9D9D9D3A9D3A9D3A9D3A9D9D9D3A3A3A9D9D3A9D3A9D3A3A3A % 3A9D3A3A3A3A3A3A3A9D3A3A7F131313131313137F9D9D3A9D3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A9D3A3A3A3A3AFF53535353535353FF1313131313137F3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A9D9D3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D9D9D9D % 9D3A9D9D9D3A3A3A3A3A3A9D9DFF53535353535353FF3A9D3A9D9D3A9D9D % 9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210013181818C5121010 % 121010121018101012101216181618121618181818181818181818111813 % 161216121818181818181A181800FF1A1818181818161818121012161818 % 1A181A181818181810101010101010101010081010101818181818181018 % 16121612181018101810181818181818181010AF121818FF7D0000000000 % 0000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D3A9D9D3A9D3A9D9D9D9D3A % 9D9D3A3A3A3A3A9D3A3A9D9D9D3A3A9D9D3A9D9D3A3A9D9D3A9D3A3A3A3A % 3A9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A9D3A3A3A7F7F1313137F7F3A % 9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF7F1313 % 137F7F3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D3A9D3A9D9D3A9D3A9D % 9D9D3A3A9D3A9D9D9D3A3A9D9D9D9D9D9D3A9D3A3A9D9D9DFFFF535353FF % FF9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A % 3A9D9D3A9D3A9D3A9D9D3A9D3A3A9D3A9D9D3A9D9D9D3A3A9D9D3A3A9D9D % 9D9D9D9D9D3A9D9D9D3A3A9D3A3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D9D3A % 3A3A3A3A3A3A3A9D3A9D3A3A7F7F1313137F7F3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9DFFFF535353FFFF7F7F1313137F7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A9D9D9D9D9D3A3A3A9D3A9D3A3A9D3A9D9D9D3A9D9D % 3A9D3A9D3A3A3A3A3A3A9D9D9DFFFF535353FFFF9D3A9D9D9D3A3A9D3A9D % 9D3A3A3A3A9D3A3A3A3A3A3A3A000000000000210018181818C518181010 % 1010121012101210121618181818C5C5C5C51818181A18C5C518181618C5 % C5C5C5C5C5181A181A18181800FF18181818181818181712161818181818 % 18181A181818181118121012101010101010080E10101818181818181210 % 121018101810121812101818181817181218AF181618FF7D000000000000 % 00003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D3A3A3A9D9D9D3A9D9D9D3A % 9D9D3A3A3A3A3A3A9D9D3A9D9D3A9D9D9D9D9D3A3A9D9D9D9D3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A7F7F7F3A3A9D9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A7F7F7F % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A9D3A3A9D9D3A9D3A % 9D9D9D9D3A9D3A3A3A9D9D9D3A9D9D3A3A3A3A9D9D9D9D9D9DFFFFFF9D9D % 9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D3A3A % 3A3A9D3A3A3A3A3A3A9D9D3A9D3A9D3A9D9D3A9D9D9D3A3A9D3A3A9D9D3A % 9D9D3A9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D3A9D3A3A3A3A3A9D3A3A9D3A % 3A3A3A3A3A9D9D9D9D3A3A3A3A7F7F7F3A9D3A3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A % 3A9D3A9D3A9D3A3A9D3A9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D9D9D9D % 9D3A9D3A3A3A9D3A3A9D9D9D9D9DFFFFFF9D9D9D3A9D3A9D9D3A9D9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A000000000000210016181818C51818181810 % 121018101810121018181818C5C51818C5C518181818C5C51818181817C5 % C5181818181818181A181800FF18181818181A1818181812181818181818 % 181818181618181612161810121012101010101010101218161818181018 % 1813161318101210101216121818121618AF181818FF7D00000000000000 % 003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D3A3A3A9D9D9D3A9D9D9D3A9D % 9D3A3A3A3A3A3A9D9D3A9D9D3A9D9D9D9D9D3A3A9D9D9D9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A9D9D9D9D9D3A3A3A3A3A3A7F7F7F3A3A3A3A3A9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A7F % 7F7F3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A9D3A3A9D9D3A9D3A9D % 9D9D9D3A9D3A3A3A9D9D9D3A9D9D3A3A3A3A9D9D9D9D9D9D9D9D9DFFFFFF % 9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D3A3A3A % 3A9D3A3A3A3A3A3A9D9D3A9D3A9D3A9D9D3A9D9D9D3A3A9D3A3A9D9D3A9D % 9D3A9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D3A9D3A3A3A3A3A9D3A3A9D3A3A % 3A3A3A3A9D9D9D9D3A7F7F7F9D3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A % 9D3A9D3A9D3A3A9D3A9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D9D9D9D9D % 3A9D3A3A3A9D3A3A9D9D9D9D9D9D9D3AFFFFFF3A9D3A9D9D3A9D9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A000000000000210018181018C5181818181718 % 1818121010121012121818C5C51818C5C5181818181818181A18181818C5 % C518181818181818181800FF18181A181818181818181718181818121818 % 181818121210121012101216121012101210101010101012181613101216 % 18181216121012101012161818101818AF181818FF7D0000000000000000 % 3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D3A9D3A9D9D3A9D9D9D9D9D3A9D % 3A3A3A3A9D3A3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A9D3A3A9D9D9D3A3A7F7F1313137F7F3A3A3A3A9D3A3A % 3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3AFFFF535353FFFF3A3A3A3A3A7F7F1313 % 137F7F3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D3A3A9D9D9D3A9D % 3A3A9D3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A9DFFFF535353FF % FF9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D3A3A9D9D3A9D3A3A3A9D3A % 9D3A3A3A9D3A3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D9D % 9D9D3A3A9D3A9D9D9D3A9D9D3A9D3A3A3A3A9D9D3A9D9D9D3A9D3A3A3A9D % 3A3A3A3A9D9D7F7F1313137F7F3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A9D9D9D3A3A9D3A3A9D9D3A9D9D9D3A9D9D9D3A3A9D3A9D9D3A3A % 3A9D3AFFFF535353FFFF9D9D3A9D3A3A7F7F1313137F7F9D9D9D3A3A3A3A % 3A3A3A3A9D3A9D3A3A9D3A9D3A3A9D3A3A3A3A9D3A3A9D3A3A9D9D3A9D3A % 9D3A3A3A3A3A3A9D9D3A9D3A9DFFFF535353FFFF9D3A3A3A9D9D9D9D3A3A % 3A3A3A3A3A3A3A3A3A3A000000000000210018181612C5C5C5C5C5C5C5C5 % C5C5C5C5C51010121018C5C51818C5C5181818181A1818181818181817C5 % C5181812181818181800FF1818181818181A181818181818181818161818 % 161810101010101010121012181612101010100A10101210181810121818 % 181018101010101010121810181018AF161818FF7D00000000000000003A % 3A3A3A3A9D3A3A9D3A9D9D9D9D3A3A9D9D3A3A3A9D3A9D3A9D9D3A9D3A3A % 3A9D3A3A3A9D9D3A9D3A3A9D3A9D9D3A3A9D3A9D9D9D3A3A3A3A3A9D3A3A % 3A9D3A3A3A3A3A3A3A9D3A9D9D3A7F131313131313137F3A3A9D9D9D9D3A % 9D9D3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D3A3A3A3A9D % 9D9D9D3A3A3A9D3A3A3A3A3AFF53535353535353FF9D3A3A7F1313131313 % 13137F9D3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A9D9D9D3A9D3A3A9D9D9D9D % 9D9D3A3A9D9D9D3A9D9D9D3A9D3A3A9D9D9D9D3A9D9DFF53535353535353 % FF3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A9D3A3A9D9D3A3A3A % 9D3A3A3A3A3A3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D3A9D9D3A3A3A % 9D3A9D3A9D9D9D3A9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A9D9D3A3A9D3A9D9D3A9D3A9D9D3A9D3A9D3A3A9D3A9D9D3A3A3A3A3A % 9DFF53535353535353FF3A9D3A9D7F131313131313137F3A3A3A3A3A3A3A % 3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A9D9D9D9D3A3A9D9D9D9D3A9D9D3A3A % 3A3A3A3A3A3A9D9D9D3A3AFF53535353535353FF3A3A9D9D9D9D9D3A9D3A % 3A9D3A3A3A3A3A3A3A000000000000210018181818C51018181818161210 % 181012101010101018C5C51818C5C51A181818181818181A1818181818C5 % C51818161818161800FF181818181A181818181818181818181818181818 % 18181810101210101010101812181018101010AF12161818181818161817 % 1818181818101010101012181810AF121818FF7D00000000000000003A3A % 3A3A3A9D3A3A9D3A9D9D9D9D3A3A9D9D3A3A3A9D3A9D3A9D9D3A9D3A3A3A % 9D3A3A3A9D9D3A9D3A3A9D3A9D9D3A3A9D3A9D9D9D3A3A3A3A3A9D3A3A3A % 9D3A3A3A3A3A3A3A9D3A9D9D3A7F131313131313137F3A3A9D9D9D9D3A9D % 9D3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D3A3A3A3A9D9D % 9D9D3A3A3A9D3A3A3A3A3AFF53535353535353FF9D3A3A7F131313131313 % 137F9D3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A9D9D9D3A9D3A3A9D9D9D9D9D % 9D3A3A9D9D9D3A9D9D9D3A9D3A3A9D9D9D9D3A9D9DFF53535353535353FF % 3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A9D3A3A9D9D3A3A3A9D % 3A3A3A3A3A3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D3A9D9D3A3A3A9D % 3A9D3A9D9D9D3A9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A9D9D3A3A9D3A9D9D3A9D3A9D9D3A9D3A9D3A3A9D3A9D9D3A3A3A3A3A9D % FF53535353535353FF3A9D3A9D7F131313131313137F3A3A3A3A3A3A3A3A % 3A9D3A3A3A9D3A9D3A9D3A9D3A3A9D9D9D9D3A3A9D9D9D9D3A9D9D3A3A3A % 3A3A3A3A3A9D9D9D3A3AFF53535353535353FF3A3A9D9D9D9D9D3A9D3A3A % 9D3A3A3A3A3A3A3A000000000000210018181818C5101210121012101218 % 1612101010101010C5C51012C5C51810181818181A181818C5C51818C5C5 % 1818181818181800FF1818181A1E181A1818181612101218181818181818 % 101810121010101010101218171818101210AF1018181818181818181818 % 17181816101210121012101010AF101010FF7D00000000000000003A3A3A % 3A3A3A3A3A9D3A9D9D3A9D3A3A9D9D3A3A3A9D3A9D3A9D9D3A9D3A3A3A3A % 3A3A3A9D9D9D9D9D9D9D9D3A9D3A3A9D9D3A9D9D3A3A9D3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A9D9D7F1313131313131313137F9D3A9D3A3A3A9D3A % 9D3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D9D3A9D9D9D3A3A9D3A % 9D3A3A3A3A9D9D3A3AFF535353535353535353FF9D7F1313131313131313 % 137F9D3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A9D3A9D9D9D9D9D9D9D3A9D3A % 3A9D9D9D3A9D9D9D3A9D3A3A3A9D9D9D9D9D9DFF535353535353535353FF % 9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D3A9D3A9D9D3A9D3A9D3A % 3A3A3A3A9D9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D3A3A3A9D9D9D9D3A9D3A % 3A3A3A9D9D9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A3A9D3A3A3A3A3A3A3A9D % 9D7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A9D3A9D9D3A3A9D3A9D3A9D9D3A3A9D9D9D9D3A3A3A3AFF53 % 5353535353535353FF3A3A7F1313131313131313137F3A3A3A3A3A3A9D3A % 3A3A9D3A3A9D3A3A9D3A3A3A3A3A9D9D3A3A3A9D9D3A9D9D9D3A9D9D3A3A % 3A3A3A3A9D9D9D3AFF535353535353535353FF3A9D3A9D9D9D3A3A3A3A3A % 3A3A3A3A3A3A3A000000000000210010101012C512161216121810181012 % 10101010101010C5C51010C5C510181818181A1E181A18C5C51612C5C518 % 18181818181800FF1818181A181A18181812101210101012161218101818 % 1810101010101010101216121818181818AF181818181818181818181818 % 181818181816121010121012AF101010FF7D00000000000000003A3A3A3A % 3A3A3A3A9D3A9D9D9D9D3A3A9D9D9D9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A % 3A3A3A9D9D9D3A9D9D3A9D9D3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A3A3A9D9D9D7F1313131313131313137F9D3A9D3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A3A9D3A3A9D9D3A3A3A9D3A3A3A9D3A3A9D9D9D9D3A3A % 9D3A3A3A3A9D9D3AFF535353535353535353FF3A7F131313131313131313 % 7F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A9D9D9D3A9D3A9D3A3A % 3A3A9D9D9D9D3A3A9D3A3A9D9D9D9D9D9D9DFF535353535353535353FF9D % 9D9D3A9D9D9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A3A9D3A9D % 3A3A3A3A3A9D9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A3A3A9D9D9D9D3A9D9D % 9D3A3A3A3A9D9D3A9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D9D % 7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9DFF5353 % 53535353535353FF3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A % 9D3A9D9D9D9D9D9D3A3A3A9D3A9D3A9D3A3A3A9D9D3A9D9D3A9D3A3A3A3A % 3A3A3A9D9D9D9DFF535353535353535353FF3A9D9D9D9D9D3A9D3A3A9D3A % 3A3A3A3A3A3A000000000000210010101010C51012101210101012101210 % 10121010081010C5C5C5C51012181818181A181A181818C5C5C5C5101012 % 161218101800FF1818181A18181A18181810101010121012101212161218 % 101010100A1010101012181818181818AF1818181A181818181818161812 % 1818181818181012101018AF101010FF7D00000000000000003A3A3A3A3A % 3A3A3A9D3A9D9D9D9D3A3A9D9D9D9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A3A % 3A3A9D9D9D3A9D9D3A9D9D3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D9D3A3A3A9D9D9D7F1313131313131313137F9D3A9D3A3A3A3A3A9D3A % 3A3A3A3A9D3A3A3A9D3A3A9D9D3A3A3A9D3A3A3A9D3A3A9D9D9D9D3A3A9D % 3A3A3A3A9D9D3AFF535353535353535353FF3A7F1313131313131313137F % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A9D9D9D3A9D3A9D3A3A3A % 3A9D9D9D9D3A3A9D3A3A9D9D9D9D9D9D9DFF535353535353535353FF9D9D % 9D3A9D9D9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A3A9D3A9D3A % 3A3A3A3A9D9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A3A3A9D9D9D9D3A9D9D9D % 3A3A3A3A9D9D3A9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D9D7F % 1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9DFF535353 % 535353535353FF3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A9D % 3A9D9D9D9D9D9D3A3A3A9D3A9D3A9D3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A % 3A3A9D9D9D9DFF535353535353535353FF3A9D9D9D9D9D3A9D3A3A9D3A3A % 3A3A3A3A3A000000000000210010101010C5121613181018121816181818 % 1010100A100B101010101010181818181A18181A18181810101010121012 % 1012121600FF1818181A181A181818181210121010121010101012101218 % 18101010100810121618181A181A18AF18181A1818181818181012121816 % 18121218101816101018AF181818FF7D00000000000000003A3A3A3A3A3A % 3A3A9D3A9D9D9D9D3A3A9D9D3A3A3A3A9D3A9D3A9D9D3A9D3A3A3A9D3A3A % 9D9D3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A % 9D9D9D9D9D9D9D3A3A7F131313131313137F3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A9D3A3A % 9D3A3A3A3A9D3AFF53535353535353FF3A3A3A7F131313131313137F3A3A % 3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D9D9D9D9D9D9D9D9D3A3A3A3A9D % 9D9D9D9D3A3A9D3A9D9D3A9D9D9D3A9D9DFF53535353535353FF9D9D9D9D % 9D9D3A9D3A9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D3A9D3A3A3A9D3A3A9D3A % 3A3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D3A3A3A3A9D9D9D9D9D3A9D9D % 3A3A9D9D9D9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D7F % 131313131313137F3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9DFF535353 % 53535353FF3A3A9D3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A % 9D9D9D9D3A9D3A3A3A9D3A9D9D9D3A3A9D9D3A9D9D9D9D3A9D3A3A3A9D3A % 3A9D9D9D3A9DFF53535353535353FF3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A % 3A3A3A3A000000000000210018181010C512161216101316101818181818 % 181010100E101010101010181818181A181A181818181210121010121010 % 10101200FF10181818181818181818161216121810181018101210101818 % 1610101010081012161818181818AF1A1818181818181810121010101218 % 101010121012181818AF18181AFF7D00000000000000003A3A3A3A3A3A3A % 3A9D3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A9D % 9D9D3A9D3A9D9D9D3A3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A9D9D3A9D3A3A3A7F131313131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A % 3A3A3A9D9D9DFF53535353535353FF3A3A3A7F131313131313137F3A3A3A % 3A3A3A3A3A3A3A9D3A3A9D9D3A9D3A9D3A9D3A9D3A9D3A3A3A9D9D9D9D9D % 9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9DFF53535353535353FF9D3A9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D3A3A3A3A9D % 3A3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D9D9D3A9D9D9D9D3A % 9D9D9D3A9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A7F13 % 1313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A % 9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9DFF53535353 % 535353FF3A3A9D9D7F131313131313137F3A3A3A9D3A3A3A3A3A3A9D3A9D % 3A9D9D3A3A3A3A3A9D3A9D9D3A9D3A3A9D9D9D3A9D3A9D3A3A3A3A3A3A3A % 9D9D9D9D3AFF53535353535353FF9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A0000000000002100181A1818C51818121818181218181818181818 % 161210101010101010101210181818181818181818161216121810181018 % 101200FF1012161818181818101210121018181818181312101010101212 % 181810121012101818181818181818181A18181818101210101010121610 % 1012101210121018AF181818FF7D00000000000000003A3A3A3A3A3A3A3A % 9D3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A9D9D % 9D3A9D3A9D9D9D3A3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 9D9D3A9D3A3A3A3A7F7F1313137F7F9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D9D3AFFFF535353FFFF3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A9D9D3A9D3A9D3A9D3A9D3A9D3A3A3A9D9D9D9D9D9D % 9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9DFFFF535353FFFF9D9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D3A3A3A3A9D3A % 3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D9D9D3A9D9D9D9D3A9D % 9D9D3A9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A7F7F % 1313137F7F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3AFFFF535353 % FFFF3A3A3A9D9D3A7F7F1313137F7F3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A % 9D9D3A3A3A3A3A9D3A9D9D3A9D3A3A9D9D9D3A9D3A9D3A3A3A3A3A3A3A9D % 9D9D9D3A9DFFFF535353FFFF9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A000000000000210018181818C5101816181018181612101010121818 % 181010101010101010101012161818181818101210121018181818181312 % 1000FF101218161818101010101010101818181818181010101010101618 % 181816101018181818181818181818181818181012101010101010121010 % 10121010121018AF121612FF7D00000000000000003A3A3A3A3A3A3A3A9D % 3A9D9D9D3A9D3A9D9D9D9D3A3A9D3A9D9D9D9D9D3A3A3A3A3A3A3A9D9D3A % 9D9D9D9D9D3A3A3A9D3A9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A7F7F7F3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A % 3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A9D9D9D9D9DFFFFFFFF3A9D3A3A3A3A3A9D9D7F7F7F7F3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D9D3A3A9D3A9D9D9D9D9D3A9D9D3A % 3A9D9D3A9D9D3A9D9D9D3A9D9D3A9D9D9DFFFFFF9D9D3A9D9D9D9D9D9D3A % 9D9D3A9D9D9D9D9D3A9D3A9D9D9D3A9D9D3A9D9D3A3A3A3A9D3A3A3A9D3A % 9D3A9D9D9D3A3A9D9D3A9D9D9D9D9D9D3A9D3A3A9D9D3A9D3A9D3A9D3A9D % 9D3A9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F % 7F7F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9DFFFFFF3A % 3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A9D % 3A9D3A3A3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A9D9D % 3A9D3A9D3A9DFFFFFF9D9D9D9D3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A000000000000210016121818C518181218181810181010101010101218 % 101010121010101010101218161818101010101010101818181818181010 % 00FF10101012101012101010101012181818181818181010080A10101012 % 1818181818181818AFAFAFAFAFAF18171812181010101010101012181810 % 101012161818AF181618FF7D00000000000000003A3A3A3A3A3A3A3A9D3A % 9D3A9D9D9D3A3A9D9D3A9D3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A9D9D9D % 9D3A9D3A9D3A3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A7F3A3A3A3A3A3A9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A3AFF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D3A9D3A9D % 3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9DFF3A9D9D9D9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D3A9D3A3A9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D % 3A9D3A9D3A9D3A9D9D3A3A9D3A3A9D3A3A3A9D3A9D3A3A9D3A9D9D7F9D3A % 3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF3A3A3A3A3A % 9D3A3A3A3A3A3A3A9D3A7F3A3A3A9D3A9D3A3A3A3A3A9D3A3A3A9D3A3A9D % 3A3A3A3A3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D9D % 9D9D9D3A9D3A3AFF9D9D3A9D3A9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 000000000000210016181618C51A18181810121818181812101010101018 % 121610101210101010101012101012101010101012181818181818181000 % FF1210121018101810101010101012161818181A18181010101010101010 % 101018181818AFAFAFAFAFAFAFAF18101810121010101010121818181816 % 1210121018AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D % 3A9D9D9D3A3A9D9D3A9D3A3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A9D9D9D9D % 3A9D3A9D3A3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A7F7F7F3A3A3A3A3A3A9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3AFFFFFFFF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F7F7F7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D3A9D3A9D3A % 3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9DFFFFFF9D9D3A9D9D9D9D9D9D % 9D9D9D9D9D9D3A9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D3A9D3A3A9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D3A % 9D3A9D3A9D3A9D9D3A3A9D3A3A9D3A3A3A9D3A9D3A3A9D3A7F7F7F9D3A3A % 3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3AFFFFFF3A3A3A3A3A9D % 3A3A3A3A3A3A3A9D3A3A7F7F7F9D3A9D3A3A3A3A3A9D3A3A3A9D3A3A9D3A % 3A3A3A3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D9D9D % 9D9D3A9D3A3A9DFFFFFF9D3A9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00 % 0000000000210018181818C5181818181816181818181710101210121612 % 101210101818101210121018101810101010101012161818181A181800FF % 181818181818181810121210121012181818181818181010101010101010 % 1010121618AF181818181718AF1612101210101210121818181818181818 % 10121018AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D % 9D3A9D3A3A9D9D9D9D3A3A9D9D3A9D3A9D3A3A3A3A3A3A3A9D9D9D3A9D3A % 9D9D3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A % 3A7F7F1313137F7F9D3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3AFFFF % 535353FFFF3A3A3A3A3A3A3A9D3A3A3A3A3A7F7F1313137F7F3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A3A9D9D9D3A9D3A3A % 9D3A9D9D9D9D9D9D9D9D9D9D9D9D9DFFFF535353FFFF9D9D9D9D9D9D9D9D % 9D9D9D9D3A9D3A9D3A3A9D9D3A3A3A3A3A3A9D3A3A9D3A9D3A3A9D3A9D3A % 9D9D3A9D9D3A9D9D9D9D9D9D9D3A3A9D3A3A9D9D3A9D9D9D3A3A9D9D9D9D % 3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A7F7F1313137F7F3A9D % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF9D3A3A3A3A % 3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D % 3A3A3A3A9D3A9D9D9D9D3A3A9D9D3A3A9D9D3A3A3A3A3A3A3A9D9D9D3A9D % 3A9D9D3AFFFF535353FFFF9D3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A0000 % 00000000210018181818C518181818181811181218181818161210181018 % 10181818181818181818181818181012121012101218181818181800FF1A % 181818181818181818101010101012181818181818101810121010101010 % 10121018AF181818181816AF18101210101010101018181818181A181810 % 101012AF121612FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A % 9D9D9D3A3A9D9D9D9D3A3A9D3A3A9D3A9D9D3A3A3A3A3A3A9D9D9D9D3A9D % 9D3A9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 53535353FF3A9D3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A3A3A9D9D3A9D9D9D3A3A9D3A3A9D9D % 9D9D3A9D9D9D9D9D3A9D3A9D9DFF53535353535353FF9D9D3A3A9D9D9D9D % 9D9D9D3A3A9D9D3A9D3A9D3A9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A9D3A9D % 9D3A9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A9D3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A9D9D9D9D7F131313131313137F9D9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A % 3A3A3A3A3A7F131313131313137F9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A9D % 3A3A3A3A3A9D9D9D3A9D3A3A3A9D9D9D3A9D3A3A3A3A3A3A9D9D3A9D9D9D % 9D3AFF53535353535353FF3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000 % 000000210016121612C51210181818181810101210181818101210121012 % 1818181A181A181818181818181818101010101012181818181800FF1818 % 181818181818181818121010101210121018101812101216181018121610 % 101210AFAFAFAFAFAFAFAF10181012101010121818181A18181818181810 % 1010AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D % 9D9D3A3A9D9D9D9D3A3A9D3A3A9D3A9D9D3A3A3A3A3A3A9D9D9D9D3A9D9D % 3A9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353 % 535353FF3A9D3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A9D3A3A3A9D9D3A9D9D9D3A3A9D3A3A9D9D9D % 9D3A9D9D9D9D9D3A9D3A9D9DFF53535353535353FF9D9D3A3A9D9D9D9D9D % 9D9D3A3A9D9D3A9D3A9D3A9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A9D3A9D9D % 3A9D9D9D9D3A9D9D9D9D3A9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A9D3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A9D3A9D9D9D9D7F131313131313137F9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A % 3A3A3A3A7F131313131313137F9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A9D3A % 3A3A3A3A9D9D9D3A9D3A3A3A9D9D9D3A9D3A3A3A3A3A3A9D9D3A9D9D9D9D % 3AFF53535353535353FF3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000 % 0000210010101010C5101012161818101210101018121210101810121018 % 1818181818181818181818181818181210101012101210181000FF1A1818 % 1818181818181818181812101010101010121010181012181818181A1810 % 121018AFAFAFAFAFAF18181817181012101216181818181A181818121010 % 10AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D3A9D9D9D % 3A3A3A9D9D9D9D3A3A9D9D9D9D9D3A3A9D3A3A3A3A3A9D3A9D3A9D3A3A3A % 9D3A9D9D9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D3A9D3A3A9D3A3A3A3A9D9D9D9D9D % 9D9D3A9D3A3A9D9D9D9DFF535353535353535353FF3A9D9D9D9D9D9D9D9D % 3A9D3A3A3A3A9D3A9D9D3A9D3A9D9D3A9D3A9D3A3A9D3A9D3A9D9D9D3A3A % 9D9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A9D9D3A9D9D3A9D9D3A9D3A9D3A9D % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A % 3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353535353535353FF3A3A3A3A3A3A % 3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A % 3A3A3A9D9D9D9D9D3A3A9D9D9D3A9D9D3A3A3A3A3A3A9D3A9D3A9D9D3AFF % 535353535353535353FF3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000 % 00210010101010C510101012181618181012101210101010121018101816 % 1818181A181818181818181818181818121010101010101200FF18181818 % 181012101817181818181810121010121010121012161818181818181818 % 101818181818181818181818181818161818AFAFAFAFAFAFAFAFAFAFAFAF % AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D % 9D3A3A3A3A3A9D3A3A3A9D3A3A3A9D9D9D9D9D9D3A9D3A3A9D3A3A3A9D9D % 9D9D9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A9D9D3A9D3A3A9D9D9D9D9D3A % 9D9D9D9D9D9D3A9D3AFF535353535353535353FF9D9D9D3A9D9D9D9D9D3A % 3A3A9D3A3A9D9D9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A9D9D % 3A9D9D9D9D9D9D3A9D9D9D3A3A9D3A9D9D9D9D9D3A3A9D9D3A3A9D9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A9D % 3A7F1313131313131313137F3A3A3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A % 3A3A3A9D9D9D3A9D3A3A9D9D3A3A9D9D9D9D9D9D9D3A9D9D3A9D9D3AFF53 % 5353535353535353FF3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A000000000000 % 210010101010C51010101010121818181818181612161216121012101218 % 181818181818181012101817181818181810121010121000FF1818111210 % 101010121818181818181818181210101210101210121810121618181818 % 181818181A1818181818181818181818181818181A1818181818181810AF % 101210FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D % 3A3A3A3A3A9D3A3A3A9D3A3A3A9D9D9D9D9D9D3A9D3A3A9D3A3A3A9D9D9D % 9D9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353535353535353 % 53FF3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A9D9D3A9D3A3A9D9D9D9D9D3A9D % 9D9D9D9D9D3A9D3AFF535353535353535353FF9D9D9D3A9D9D9D9D9D3A3A % 3A9D3A3A9D9D9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A9D9D3A % 9D9D9D9D9D9D3A9D9D9D3A3A9D3A9D9D9D9D9D3A3A9D9D3A3A9D9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A9D3A % 7F1313131313131313137F3A3A3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 3A3A9D9D9D3A9D3A3A9D9D3A3A9D9D9D9D9D9D9D3A9D9D3A9D9D3AFF5353 % 53535353535353FF3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A00000000000021 % 0012101012C5101010101018181820191818181818181818101010121012 % 1818181112101010101218181818181818181812101000FF181818161812 % 181612101212181818181018101813181818181612161818181818181818 % 181A181818181A181818181210131618181818181818181210121012AF12 % 1618FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D % 3A9D9D3A9D3A3A3A9D9D9D3A9D3A9D3A9D3A9D9D3A9D3A3A3A9D3A9D9D9D % 9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A7F1313131313 % 13137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A9D3A9D3A3A9D3A9D3A9D9D3A3A9D9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D9DFF53535353535353FF9D9D9D3A9D9D3A9D9D9D9D3A9D % 3A3A3A9D3A9D3A3A9D3A3A9D3A9D3A3A9D3A9D9D3A9D9D9D9D3A9D9D9D3A % 9D3A9D9D9D9D3A9D9D3A3A9D9D3A9D9D3A9D3A3A9D9D3A3A9D3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A9D3A3A3A3A3A3A9D3AFF53535353535353FF3A3A3A9D3A3A3A3A3A9D % 7F131313131313137F9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A % 3A3A9D9D9D9D9D3A3A9D9D3A3A9D9D9D3A9D9D9D9D3A9D3A3A9D9DFF5353 % 5353535353FF9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100 % 16181818C510101010101018181818181818181810181818181012101018 % 18181816181218161210121218181818101810181300FF10181018101818 % 181818101618181818181818181816181212101210121818181818181818 % 181818181818181A18181618181818181818181818181610101210AF1210 % 18FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A3A % 3A9D9D9D9D9D3A3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D3A3A % 9D9D3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A9D7F131313131313 % 137F3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D3AFF53535353535353FF3A % 3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D % 9D9D3A9D9D9D9DFF53535353535353FF9D3A9D9D9D9D9D9D9D9D9D3A3A9D % 3A3A9D9D3A3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A9D9D % 9D3A9D3A9D9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3AFF53535353535353FF9D3A3A3A3A3A3A3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A % 3A9D9D9D9D9D3A3A3A3A9D9D9D3A3A9D3A3A3A9D9D3A3A3A9D9DFF535353 % 53535353FF9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010 % 181018C51012101010121012101217181818101818181810121010101810 % 181018101818181818101618181818181818181800FF1012121212101018 % 181818181210121018121612161210101010101010101018181818181818 % 181818AFAF181818181818181818181818181818181818131010AF101210 % FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A3A3A % 9D9D9D9D9D3A3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D3A3A9D % 9D3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A7F7F1313137F7F % 3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A % 9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D3A3AFFFF535353FFFF3A3A3A % 3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D9D % 9D3A9D9D9D9D9DFFFF535353FFFF9D9D3A9D9D9D9D9D9D9D9D9D3A3A9D3A % 3A9D9D3A3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A9D9D9D % 3A9D3A9D9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F9D3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A9D3A3A3A3A3A3A3A3A3A3A7F % 7F1313137F7F3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A % 9D9D9D9D9D3A3A3A3A9D9D9D3A3A9D3A3A3A9D9D3A3A3A9D9D9DFFFF5353 % 53FFFF3A9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021001210 % 1218C5101010101010101012181812181618101210121010101010121012 % 1212121010181818181812101210181216121600FF121010101010121810 % 181818161010121010101210121612101010101010101012101618181818 % 1818AFAF20181A181818181818181818181818181818161810AF101010FF % 7D00000000000000003A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D3A9D3A9D9D % 9D9D9D9D9D3A3A3A9D3A9D3A9D3A9D3A9D3A3A3A3A9D9D9D9D9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D7F7F7F3A3A9D % 9D9D9D9D3A9D3A3A3A9D9D9D9D9D3A3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D % 9D9D3A3A3A3A9D9D3A9D9D3A3A3A9D9D9D9D9D3A3AFFFFFF9D9D3A9D9D3A % 3A3A9D9D9D9D3A3A3A3A3A7F7F7F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A9D3A9D9D9D3A3A9D3A3A3A9D3A9D9D9D9D9D9D3A3A9D9D9D9D3A % 9D9D9D9D9D9D9D9DFFFFFF9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D9D3A3A % 9D3A3A3A3A9D3A3A3A9D3A3A3A9D9D9D3A9D9D9D9D9D9D3A9D3A9D3A9D9D % 9D9D9D9D3A9D3A9D3A3A3A3A9D3A3A3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A9D3A7F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A9D9D3A % 9D9D9D9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D3AFFFFFF % FF3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A0000000000002100101012 % 10C512121012101012101012101817121210181618101210101010121010 % 10101012181018181816101012101010121000FF10101012101210101218 % 181810121012161218121612101010101008100E10101010121216181818 % 18181A181818181818181818181818181818181818181810AF101010FF7D % 00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D3A3A9D3A % 9D9D9D3A9D9D3A3A9D9D9D9D3A9D9D3A3A3A3A3A9D9D9D9D3A3A9D3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D3A9D3A7F9D3A3A3A9D3A9D % 9D3A3A9D9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A % 3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A9D9DFF3A3A9D9D3A3A9D9D3A3A % 3A9D9D3A9D9D3A3A3A3A3A9D7F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A9D9D9D3A3A9D3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D3A9DFF9D9D9D9D9D3A9D3A9D9D9D9D3A3A3A9D3A3A9D9D % 9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D % 9D9D3A9D9D9D9D3A3A9D3A9D3A9D9D3A9D3A9D3A9D3A9D9D3A3A3A3A3A3A % 3A9D3A3A3A3A9D3A3A3A3A3A7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3AFF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D7F3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A % 9D9D9D3A3A9D9D3A3A9D9D9D9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D3AFF % 9D3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010101012 % C51817181612101010121618181818101618181816181618181010101012 % 101210101218181810121012161218121600FF1012101010101010101012 % 181818181012101010101210121010101010101010101010101218181818 % 1A18181A18181818181718181216181818181816181810AF101008FF7D00 % 000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D3A3A9D3A9D % 9D9D3A9D9D3A3A9D9D9D9D3A9D9D3A3A3A3A3A9D9D9D9D3A3A9D3A3A9D3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D3A7F7F7F9D3A3A3A9D3A9D9D % 3A3A9D9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A3A % 3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3AFFFFFF3A3A9D9D3A3A9D9D3A3A3A % 9D9D3A9D9D3A3A3A3A3A9D3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A9D9D9D3A3A9D3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D3A9D9DFFFFFF9D9D3A9D3A9D9D9D9D3A3A3A9D3A3A9D9D9D % 3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D % 9D3A9D9D9D9D3A3A9D3A9D3A9D9D3A9D3A9D3A9D3A9D9D3A3A3A3A3A3A3A % 9D3A3A3A3A9D3A3A7F7F7F7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3AFFFFFF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A7F7F7F3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D % 9D9D3A3A9D9D3A3A9D9D9D9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D3AFFFF % FFFF9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010081010C5 % 181818181818181613181818181818121818181818181818101012101010 % 1010101010121818181810121010101000FF121010121012101210121010 % 121612161216121813181718101210101010101010101010101816181818 % 181A1818181818181210121012181217181818121810AF100810FF7D0000 % 0000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D3A9D9D3A9D3A9D9D3A % 3A9D9D3A9D3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3A3A9D3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D7F7F1313137F7F3A3A3A3A3A3A3A % 3A3A9D3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A3AFFFF535353FFFF3A3A3A3A9D9D3A3A3A9D % 3A3A3A3A9D3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A9D9D9D9D3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D % 9D9D3A9D9D9DFFFF535353FFFF9D9D9D9D9D9D3A3A3A9D3A3A9D3A9D3A3A % 9D3A3A3A3A9D3A3A3A3A9D3A9D3A9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D % 9D3A9D3A9D9D3A9D9D3A9D3A9D3A9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F7F1313137F7F9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F % 1313137F7F3A9D3A9D3A3A3A9D3A3A3A3A3A9D3A9D3A3A3A3A9D3A3A3A9D % 9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A3A3A9D3AFFFF5353 % 53FFFF9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210008101010C518 % 18181A18181A181818181A18181818181818181818181810121010121012 % 10121012101012161216121612181300FF10101210101210181210121010 % 1210181818181816181818181610101010100A0E10101212181218181818 % 181818181818101012101010121618121612181610AF10080AFF7D000000 % 00000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D3A3A3A9D3A9D3A9D % 9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A % 3A9D3A3A3A9D3A3A3A9D9D3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A % 3A9D3A3A3A3A9D9D3A3A3AFF53535353535353FF3A3A3A9D9D3A3A3A9D9D % 3A3A3A3A3A9D3A7F131313131313137F3A9D3A3A3A3A3A3A3A9D3A3A3A3A % 9D9D9D9D3A9D9D3A3A9D9D3A3A9D9D9D3A9D9D9D3A9D9D3A9D9D9D3A3A9D % 9D9D9D3AFF53535353535353FF3A9D9D9D9D9D3A9D3A9D3A9D3A3A3A9D3A % 3A3A3A9D3A3A9D3A3A3A3A9D9D9D9D9D9D3A9D3A3A9D9D9D3A9D9D9D9D3A % 9D9D9D9D9D3A3A9D3A9D3A3A3A3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F131313131313137F3A9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF53535353535353FF3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A9D7F131313 % 131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A9D9D3A9D9D % 9D3A3A9D9D9D3A9D3A3A3A3A9D9D9D9D3A3A9D3A3A3A9D9DFF5353535353 % 5353FF3A9D3A3A3A9D3A3A3A3A3A3A0000000000002100080A1010C51818 % 181820181818181818181818181812101210181216181010101210101210 % 181210121010121018181818181600FF12181018181818181A1818181810 % 101818161216121012101218181818121010101010101010101818AF1818 % 1818181010181218161216121012101210101218AF101010FF7D00000000 % 000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D3A3A3A9D3A9D3A9D9D % 9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A9D9D3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A % 9D3A3A3A3A9D9D3A3A3AFF53535353535353FF3A3A3A9D9D3A3A3A9D9D3A % 3A3A3A3A9D3A7F131313131313137F3A9D3A3A3A3A3A3A3A9D3A3A3A3A9D % 9D9D9D3A9D9D3A3A9D9D3A3A9D9D9D3A9D9D9D3A9D9D3A9D9D9D3A3A9D9D % 9D9D3AFF53535353535353FF3A9D9D9D9D9D3A9D3A9D3A9D3A3A3A9D3A3A % 3A3A9D3A3A9D3A3A3A3A9D9D9D9D9D9D3A9D3A3A9D9D9D3A9D9D9D9D3A9D % 9D9D9D9D3A3A9D3A9D3A3A3A3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A7F131313131313137F3A9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % FF53535353535353FF3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A9D7F13131313 % 1313137F3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A9D9D3A9D9D9D % 3A3A9D9D9D3A9D3A3A3A3A9D9D9D9D3A3A9D3A3A3A9D9DFF535353535353 % 53FF3A9D3A3A3A9D3A3A3A3A3A3A000000000000210010101010C5181618 % 1A181A181A18181A181A1816121010121012101210181218101818181818 % 1A18181818101018181612161200FF101012101818181818181A18181218 % 1818181818121018101012181810101010101010AFAFAFAF121618AF1818 % 16121012101810181818181018101210121012AF121010FF7D0000000000 % 0000003A3A3A3A9D3A3A3A9D3A9D9D9D9D9D3A9D3A9D9D3A9D9D3A9D3A9D % 9D3A3A9D9D9D9D3A3A3A9D9D9D3A3A3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A % 3A3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A9D9D9D3A % 3A3A3A9D9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A % 9D9D9D3A9D3A3A3AFF535353535353535353FF3A9D9D3A3A3A3A9D9D3A3A % 9D3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D % 9D3A3A9D3A3A3A9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 9DFF535353535353535353FF9D9D9D3A3A3A3A3A9D3A3A9D9D3A9D3A3A9D % 3A3A3A3A3A3A3A9D9D3A9D9D9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A9D3A9D % 9D9D3A9D3A9D3A9D9D3A3A9D9D9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 7F1313131313131313137F3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3AFF53 % 5353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A % 9D9D3A9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A9D3A9DFF5353535353535353 % 53FF9D3A3A3A3A3A3A3A3A3A3A000000000000210010101010C518181818 % 181A18181A181A1818181812101210121012101812101012101818181818 % 181A1818121818181818181200FF10121010121012181818181818181818 % 18181818171813101010101012101010101010AFAFAF12101012AF121012 % 101010121012181818181818101210101010AF121818FF7D000000000000 % 00003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A9D % 9D3A9D9D3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A9D3A3A3A7F1313131313131313137F3A3A3A3A3A9D9D3A3A % 3A3A9D3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D % 9D3A9D9D3A3A3AFF535353535353535353FF3A3A9D3A3A3A3A3A9D9D9D3A % 3A3A3A7F1313131313131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D % 3A3A9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A3A9D % FF535353535353535353FF9D9D3A9D3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A % 3A9D3A3A9D3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A3A9D3A9D9D9D9D9D9D % 9D9D9D3A3A9D9D9D3A3A3A9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A7F % 1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3AFF5353 % 53535353535353FF3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F13131313131313 % 13137F3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A % 9D3A9D9D3A9D3A9D9D3A9D3A3A3A9D9D9D3A9D9DFF535353535353535353 % FF3A3A3A3A3A3A3A3A3A3A3A000000000000210018181813C5181818181A % 181818181818181818181010101010101012101010121010121012181818 % 181818181818181818181700FF1810101210101818181818181818181818 % 181818181816101012101010101010101010AF12AF10121012AF10121010 % 1010101012161818181818181010101010AF101018FF7D00000000000000 % 003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A9D9D % 3A9D9D3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A9D3A3A3A7F1313131313131313137F3A3A3A3A3A9D9D3A3A3A % 3A9D3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D % 3A9D9D3A3A3AFF535353535353535353FF3A3A9D3A3A3A3A3A9D9D9D3A3A % 3A3A7F1313131313131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A % 3A9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A3A9DFF % 535353535353535353FF9D9D3A9D3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A % 9D3A3A9D3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A3A9D3A9D9D9D9D9D9D9D % 9D9D3A3A9D9D9D3A3A3A9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A7F13 % 13131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3AFF535353 % 535353535353FF3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F1313131313131313 % 137F3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D % 3A9D9D3A9D3A9D9D3A9D3A3A3A9D9D9D3A9D9DFF535353535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A000000000000210010181816C5181818181818 % 181818181818181810101010101010121010181810101210101818181818 % 1818181818181818181800FF181818101612181018181818181818181818 % 1818181818181810101210181810101012AF10AFAFAFAFAFAF1210101210 % 10101010121818181818181012101010AF0A1010FF7D0000000000000000 % 3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D3A9D9D9D9D3A9D3A3A3A9D3A3A3A % 9D9D9D9D3A9D3A3A3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F131313131313137F9D3A3A3A3A3A3A9D9D3A3A3A % 9D9D3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A3A9DFF53535353535353FF3A3A3A9D9D3A3A3A9D3A3A3A9D3A3A % 3A3A7F131313131313137F3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D3A3A % 9D9D9D3A3A3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9DFF % 53535353535353FF9D9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A % 9D9D3A9D3A9D9D9D9D3A9D3A9D9D3A3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D3A3A9D3A9D9D3A9D9D9D9D9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A7F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A % 3A9D9D9D3A9D9D9D3A9D3A3A9D3A9D9D9D3A9DFF53535353535353FF3A9D % 3A3A3A3A3A3A3A3A3A3A000000000000210010101012C518181818181818 % 181718181818121012101010121010181818181818101612181018181818 % 18181818181818181800FF1A181812121210181012121018181818181818 % 18121618181810121018181810101810AF1818AFAFAFAF12101012161010 % 101010121818181818181012101010AF100810FF7D00000000000000003A % 3A3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D3A9D3A9D3A % 9D3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A7F131313131313137F3A3A3A9D9D3A3A3A9D3A3A3A9D % 3A3A3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A % 9D3A3A3A9DFF53535353535353FF9D3A3A9D9D3A3A3A9D9D3A3A3A3A3A3A % 3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D % 3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9DFF53 % 535353535353FF9D9D3A3A3A3A9D3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A9D % 3A3A9D3A9D9D9D9D3A9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D3A3A3A9D9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313 % 13131313137F3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353 % 535353FF9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A7F131313131313137F9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D % 9D3A3A3A3A3A3A9D3A9D3A9D9D9D9D3A9D9DFF53535353535353FF3A9D3A % 3A3A3A3A3A3A3A3A3A000000000000210008101010C5C5C5C5C5C5C51818 % 18181818161210101010101012181818181A181812121210181012121018 % 181818181818181200FF1818121010101012101010121012181818171818 % 1618121810121210121218181818181818181A1818181010181818101210 % 1010101018181818181612171210AF101010FF7D00000000000000003A3A % 3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D9D3A9D3A9D3A9D % 3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A9D7F7F1313137F7F3A3A3A3A9D9D3A3A3A9D3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A9D % 3A3A3A9D3AFFFF535353FFFF3A9D3A3A9D9D3A3A3A9D9D3A3A3A3A3A3A3A % 3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A % 9D3A3A3A9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9DFFFF % 535353FFFF9D9D9D3A3A3A3A9D3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A9D3A % 3A9D3A9D9D9D9D3A9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 3A3A3A9D9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A7F7F13 % 13137F7F3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353 % FFFF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F7F1313137F7F3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D % 3A3A3A3A3A3A9D3A9D3A9D9D9D9D3A9D9D9DFFFF535353FFFF9D3A9D3A3A % 3A3A3A3A3A3A3A3A000000000000210010101010C5101218181818181818 % 1118131810101010101012181818181A1818121010101012101010121012 % 1818181718181600FF181810101010101210101010101216181818181012 % 101210101010101010101818181818181818181818181818181818101010 % 10101218181818181818181810AF181210FF7D00000000000000003A3A3A % 3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D3A3A3A3A9D3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A7F7F7F9D3A3A3A3A3A9D3A3A3A3A9D3A3A3A9D9D3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D3A3A3A3A9D3A3A9D9D3A % 3A3A9D3A3A3AFFFFFF3A3A3A9D3A3A9D9D3A3A3A9D9D3A3A9D3A3A3A3A9D % 3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D % 3A3A3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9DFF % FFFF9D9D9D9D3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A9D9D3A % 9D9D9D9D9D9D9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A % 9D3A3A9D3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F % 7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3AFFFFFF3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D % 3A3A9D3A3A9D3A9D9D9D3A9D3A9D9D9D9D9D3AFFFFFF3A9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A000000000000210012101010C510101818181818181818 % 181810121010101012161818181A18181810101010101210101010101216 % 18181818101200FF1818181010080810101010100B0E0A10101618181818 % 181810181316121612161210121618181818181818161218101818181818 % 161010101012101010121010AF121818FF7D00000000000000003A3A3A3A % 3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A3A3A % 3A3A9D9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A9D7F9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A9D9D9D9D % 9D3A3A3A3A9D3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A % 3A9D9D9DFF3A9D9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A3A % 3A9D3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D3A9D3A3A3A % 3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D % FF9D9D9D9D3A9D3A9D3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D % 3A9D9D9D9D3A9D3A3A9D9D9D9D9D3A9D9D9D9D3A9D9D9D3A9D3A9D9D3A3A % 9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A3AFF9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A000000000000210018181618C51010181618181A18181813 % 10101810181012181818181A18181818181010080810101010100B0E0A10 % 101618181800FF1818181612101010101010101010101010121818181818 % 161018101612171218101210121818181818181818101810181818181818 % 1818101210101210101010AF161818FF7D00000000000000003A3A3A3A3A % 3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A3A3A3A % 3A9D9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A7F7F7F9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A9D9D9D9D9D % 3A3A3A3A9D3A9D3A3A3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D3A3A3A3A % 9DFFFFFF3A9D9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A3A3A % 9D3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D3A9D3A3A3A3A % 9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D % FFFFFF9D3A9D3A9D3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D3A % 9D9D9D9D3A9D3A3A9D9D9D9D9D3A9D9D9D9D3A9D9D9D3A9D3A9D9D3A3A9D % 3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A3A9DFFFFFF3A9D3A3A3A3A3A % 3A3A3A3A3A000000000000210018181818C5181818181818181818181810 % 12101218161216181818181A181818181612101010101010101010101010 % 1218181800FF181618181818181012101010101010101010121618181818 % 121812181218121012101210121018181816181810181210121018181818 % 18121010121012101210AF121818FF7D00000000000000003A3A3A3A3A3A % 3A3A9D3A9D9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D9D9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D9D9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A9D3A3A9D3AFFFF % 535353FFFF3A3A3A3A9D3A9D3A3A3A3A3A9D3A9D9D3A3A3A3A3A3A3A3A9D % 7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A3A9D9D9D9D9DFFFF53 % 5353FFFF9D3A9D3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D3A9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D3A3A3A % 9D3A9D3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F7F1313137F7F3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A9D % 9D9D9D3A3A9D9D3A9D9D9D9D9D9D9D9D9DFFFF535353FFFF3A3A3A3A3A3A % 3A3A3A3A000000000000210018181818C518181818181818181818181813 % 1618101218181818181A1818181618181818181012101010101010101010 % 12161800FF1812121618181812161210101010100A0F1010121818181618 % 171816181618101210101010121018181812161218101010181818181818 % 121612181018101810AF101216FF7D00000000000000003A3A3A3A3A3A3A % 3A9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D3A3A9D3A % 3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F % 131313131313137F3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 53535353FF9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A7F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A3A9D9D9D % 9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9DFF53535353 % 535353FF3A9D3A9D3A9D3A3A3A3A9D3A9D3A3A3A3A9D3A9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D % 3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F131313131313137F9D3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A9D9D3A9D9D9D9D9D3A3A9D9D3AFF53535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A % 9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A9D % 9D9D9D9D3A9D9D9D3A9D9D3A9D9D9DFF53535353535353FF3A3A3A3A3A3A % 3A3A3A000000000000210012161818C518181A1818181A18181818181818 % 18181816181818181818181812121618181812161210101010100A0F1010 % 121800FF1810101012101216121810121010121010101010121618181818 % 181818181810101010121010101210121612181018101818181818181816 % 1218101810181210AF101212FF7D00000000000000003A3A3A3A3A3A3A3A % 9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D3A3A9D3A3A % 3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F13 % 1313131313137F3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353 % 535353FF9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A7F1313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A3A9D9D9D9D % 3A9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9DFF5353535353 % 5353FF3A9D3A9D3A9D3A3A3A3A9D3A9D3A3A3A3A9D3A9D3A9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A % 3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F131313131313137F9D3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A9D9D3A9D9D9D9D9D3A3A9D9D3AFF53535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D3A3A9D9D % 9D9D9D3A9D9D9D3A9D9D3A9D9D9DFF53535353535353FF3A3A3A3A3A3A3A % 3A3A000000000000210012121818C518181818181818181A181818181818 % 181818181818181818181810101012101216121810121010121010101010 % 1200FF181612101010101210121612101216101010101210121818181818 % 181818181612101010101210121012101216121818181818181612101210 % 12101210121010AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D % 3A9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F131313 % 1313131313137F3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A7F13131313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A9D3A3A9D9D9D9D9D % 9D9D3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9DFF53535353535353 % 5353FF3A9D9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A9D9D3A9D9D9D3A % 9D9D3A9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A3A9D9D3A3A % 9D3A3A3A9D9D9D9D9D9D3A9DFF535353535353535353FF3A3A3A9D3A3A3A % 3A000000000000210010101218C518181818181818181818181A18181818 % 181818181818181818181612101010101210121612101216101010101210 % 00FF18181816101010101012101210181216121010101012161818181818 % 181818121810101010101010121012101810181818181818181210101210 % 121012101210AF100F10FF7D00000000000000003A3A3A3A3A9D3A3A9D3A % 9D9D9D3A3A9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F13131313 % 13131313137F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D9D % 9D9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D3A9D9D9D9DFF5353535353535353 % 53FF3A9D3A3A9D3A9D3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D9D9D9D3A9D % 9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D9D3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F3A3A3A9D3A % 3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A9D3A9D3A9D3A9D9D9D9D9D9D3A % 9D3A9D3A9D3A9D3A3A3A9D3AFF535353535353535353FF3A9D3A9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D3A7F1313131313131313137F9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D3A9D9D3A % 9D3A9D3A9D9D9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A3A3A % 00000000000021000F101010C5101818181818181A18181A181A18181818 % 181818181818181818181816101010101012101210181216121010101000 % FF1818181818121010101010101818181810101010101012181818181818 % 181818181012101010121010101012101818101818181818181612101010 % 1210101010AF100A10FF7D00000000000000003A3A3A3A3A9D3A3A9D3A9D % 9D9D3A3A9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF5353535353535353 % 53FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D3A9D9D9D9DFF535353535353535353 % FF3A9D3A3A9D3A9D3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D9D9D9D3A9D9D % 9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D9D3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F3A3A3A9D3A3A % 3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A9D3A9D3A9D3A9D9D9D9D9D9D3A9D % 3A9D3A9D3A9D3A3A3A9D3AFF535353535353535353FF3A9D3A9D3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A9D3A7F1313131313131313137F9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D3A9D9D3A9D % 3A9D3A9D9D9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A3A3A00 % 000000000021000A101010C510121018181818181A181A18201818181818 % 1818181818181818181818181210101010101018181818101010101000FF % 1818181810101010101012181816181818181818181818181A1818181810 % 101816181818181216101210121018101210101018181810121010121010 % 10121010AF100A08FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D % 9D9D9D3A9D9D3A3A9D9D9D9D3A9D9D9D9D9D3A9D9D9D3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 13137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 137F3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D3A9DFF53535353535353FF9D % 9D9D9D9D9D3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D3A9D9D3A % 9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A3A9D3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A9D3A9D3A3A3A3A9D3A3A9D3A9D3A9D9D9D3A3A9D9D9D3A % 9D9D9D9D3A9D3A9D9D9D3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A9D3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D % 9D9D3A9D9D9D3A9D9D9DFF53535353535353FF3A3A3A3A3A3A3A3A3A0000 % 0000000021000A081010C510101012161818181818181A18181818101012 % 10181018161818181818101010101010121818161818181818181800FF16 % 181818101012081010101012181818181818181818181A181A1818161212 % 181818181818161210121010121216181010121010101212161218101210 % 101012AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D % 3A9D3A9D9D3A9D3A3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A7F131313131313 % 137F3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D3A9D % 9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D9DFF53535353535353FF3A9D % 9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D9D9D3A3A9D9D9D9D % 3A9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D % 9D3A9D9D9D3A9D9D9D3AFF53535353535353FF3A3A3A3A3A9D3A3A9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A9D9D9D3A3A % 3A9D3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D9D9D9D % 9D3A9D9D9D9D9D9D9DFF53535353535353FF3A3A9D3A3A3A3A3A3A000000 % 000000210010101010C5101010101218181818181A181818181810121012 % 101210121216181818101012081010101012181818181818181800FF1210 % 18121612100E0A081010101818181A18181A181818181818181812101018 % 181818181818181010181318161818121010101010101018181618181018 % 1216AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A % 9D3A9D9D3A9D3A3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A7F7F1313137F7F % 3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D3A9D9D % 9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9DFFFF535353FFFF3A3A9D9D % 3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D9D9D3A3A9D9D9D9D3A % 9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D9D % 3A9D9D9D3A9D9D9D3A3AFFFF535353FFFF9D3A3A3A3A3A9D3A3A9D9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A9D9D9D3A3A3A % 9D3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D9D9D9D9D % 3A9D9D9D9D9D9D9D9DFFFF535353FFFF3A3A3A9D3A3A3A3A3A3A00000000 % 0000210010101010C5100E1010121018181818181A181818181012161210 % 18101210121018121612100E0A081010101818181A18181A1800FF101210 % 181818181010100A1010181818181818181818181A181818181010121012 % 101818181810181218161818181816181010101010121818181816181216 % 18AF121010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D % 3A9D3A3A9D9D3A9D3A9D3A9D9D3A9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F7F7F7F3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F7F7F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9DFFFFFF9D3A9D9D3A9D9D % 9D9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D9D3A9D9D9D9D % 3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D9D9D3A9D9D3A3A3A % 9D3A3A3A9D3A9D9D9D3AFFFFFFFF3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F7F3A3A3A9D3A3A3A9D3A3A3A9D3A9D % 3A9D3A9D3A9D3A9D3A3A3A9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D3A9D9D % 9D9D3A9D9D9D3A3A3A9DFFFFFF3A9D3A3A3A3A3A3A3A3A3A3A0000000000 % 00210010101010C510101010101212101818181818181818181810181112 % 101610101210181818181010100A1010181818181818181800FF10101010 % 12101818181010101218181818181818181818181A181818101210101010 % 121012101018101818181818181818181818181010181218101212101218 % AF101810FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D % 3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F9D3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF3A3A9D3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A9D3A % 9D9D3A9D3A9D3A9D9D3A3A9D3A9D9D9D9D9D9D9D9DFF9D9D9D3A9D3A9D3A % 9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A9D3A3A9D9D9D3A9D9D9D9D9D3A9D9D % 9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D9DFF3A9D9D9D3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A9D3A7F3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A % 9D3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A9D3A9D9D % 9D9D9D3A9D9D3A9D9D9D3AFF3A9D3A3A3A9D3A3A3A3A3A3A000000000000 % 210018101210C51010101010101012181818181818181018101812181018 % 121010101010121018181810101012181818181818181800FF1012101010 % 101218181810121618181818181818181818181818181012101010101010 % 1012101212101810181818181818181A18181812161216121010101012AF % 181012FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F9D3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3AFF3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A9D3A9D % 9D3A9D3A9D3A9D9D3A3A9D3A9D9D9D9D9D9D9D9D9DFF9D9D3A9D3A9D3A9D % 9D3A9D9D3A9D3A3A3A3A3A3A3A3A9D3A3A9D9D9D3A9D9D9D9D9D3A9D9D9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D9DFF3A9D9D9D3A9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A9D3A7F3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D % 3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A9D3A9D9D9D % 9D9D3A9D9D3A9D9D9D3A9DFF9D3A3A3A9D3A3A3A3A3A3A00000000000021 % 0010121010C5101010101012101012121818161210101212161216181818 % 1210121010101012181818101216181818181818181800FF181012101010 % 0E1816121810181618161818161818181818181818121012101010101218 % 18181210101212161218161818181818181818181818181018121010AF10 % 1216FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D3A % 3A9D9D3A3A9D3A3A3A9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A9D % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A7F7F7F7F3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A9D3A3A7F7F7F9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFFFF9D9D9D9D9D9D9D % 9D9D9D9D9D3A9D3A3A3A9D3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A7F7F7F3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D3A9D9D3A9D9D3A3A3A9D3A9D3A9D % 3A9D9D9DFFFFFFFF3A9D3A9D3A9D3A3A3A3A3A9D3A3A9D9D3A3A3A9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A7F7F7F7F9D3A3A9D9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D3A9D9D3A9D3A9D % 3A9D9D3A9D9D9D9D9D9DFFFFFF3A3A3A3A3A3A3A3A3A0000000000002100 % 12161210C510101010101012101210121012101010101012181818181818 % 1810121010100E181612181018161816181816181800FF181810100A100A % 101010101812121218181818181818181818181810101010101216181818 % 18181012101012161218181210101018181818181818181818180AAF1012 % 16FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D3A3A3A % 9D9D9D3A9D3A9D3A3A9D3A9D9D9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F7F1313137F7F3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A9D3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFF535353FFFF3A9D3A9D9D9D % 3A9D3A9D9D3A9D3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F7F1313137F7F3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A9D9D3A9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D3A % 3AFFFF535353FFFF9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D % 9D3A9D3A9D3A9DFFFF535353FFFF3A3A3A3A3A3A3A000000000000210012 % 161210C5101010101010101010101012101010101010121018181A181A18 % 1810100A100A101010101812121218181818181800FF181818101010100B % 101012101818181818181818181010181216121012101010101218181818 % 181A181812161218181210181818181818181816121816181818AF101210 % FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D3A3A3A9D % 9D9D3A9D3A9D3A3A9D3A9D9D9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A7F131313131313137F3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3AFF53535353535353FF3A3A3A3A9D3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF53535353535353FF9D3A9D9D9D3A % 9D3A9D9D3A9D3A3A3A3A3A9D3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A7F131313131313137F3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A3A3A3A3A9D9D3A9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D3AFF % 53535353535353FF9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A7F131313131313137F3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D9D % 3A9D3A9D3AFF53535353535353FF3A3A3A3A3A3A00000000000021001210 % 1818C5101216121818181810101210101210101010101218181818181818 % 18101010100B1010121018181818181818181800FF181818101210101010 % 101012101210181818181818181211181012101012101010101818181818 % 18181210121018181012101218101818181818121012121018AF181012FF % 7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D3A3A9D3A3A3A3A % 9D9D3A3A3A3A9D3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A9D9D3A3A9DFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A9D % 3A9D3A3A3A3A3A3A9D3A9D3A3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D % 3A9D9D3A9D9D9D9D9D3A9D9D9D9DFF53535353535353FF9D9D9D3A9D9D9D % 9D9D9D9D9D9D9D3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D9D9D9D3A9D9D3A9D9D9D3A9D9D9D9D3A9D9D3A3A9D3A9DFF53 % 535353535353FF9D3A9D9D9D3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A7F131313131313137F3A9D9D9D9D3A3A3A3A9D3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D9D3A9D3A9D % 3A9D3A9DFF53535353535353FF3A3A3A3A3A3A0000000000002100101216 % 12C518181818181818181218161812101010101010101012181818181818 % 10121010101010101210121018181818181800FF16181216121012101010 % 121010101018181818181818181812161216121012101218181818181A18 % 181010101010101010101010121012101210101010101018AF121012FF7D % 00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A3A9D % 9D9D3A3A3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A3A3A3A % 3A3A9D3A3A3A3A9D3A9D3A3A9D3A9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9D % 3A9D9D9D9D9D9D9D9D9D9D9DFF535353535353535353FF3A9D9D9D3A9D9D % 9D9D9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D % 9D3A9D9D9D3A9D9D9D9D9D9D9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A7F % 1313131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A3A9D9D9DFF535353 % 535353535353FF9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A9D3A9D3A9D3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A % 3A9DFF535353535353535353FF3A3A3A3A3A000000000000210010121018 % C51316181818181818181818181618181818101010101010181816181216 % 121012101010121010101018181818181800FF1812161218101012101210 % 10101010101218181818181818101812101210101217181A18181A181818 % 1810101010101010101010101010101818121810101012AF121010FF7D00 % 000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A3A9D9D % 9D3A3A3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A3A3A3A3A % 3A9D3A3A3A3A9D3A9D3A3A9D3A9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9DFF535353535353535353FF3A9D9D9D3A9D9D9D % 9D9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D % 3A9D9D9D3A9D9D9D9D9D9D9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A7F13 % 13131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A3A9D9D9DFF53535353 % 5353535353FF9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A9D3A9D3A9D3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A3A % 9DFF535353535353535353FF3A3A3A3A3A000000000000210010101216C5 % 18181818181818181A181818121818181818121010101012181812161218 % 1010121012101010101010121818181800FF101018111818181818181818 % 1818181818181818181818181818111810101218181818181A181A181818 % 16101010101010101010101010181718181816121010AF101210FF7D0000 % 0000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D % 3A9D3A9D3A9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A9D3A7F1313131313131313137F3A3A3A3A9D3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D % 9D9D9D9D9DFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A % 3A3A3A3A3A9D3A9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D9D9DFF535353535353535353FF9D9D9D9D9D9D3A9D9D % 3A9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F1313 % 131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3A9D9D3A3A3A9D9D9D9D9D3A9D3A9D9D3A9D3A3A9D3A9D3AFF5353535353 % 53535353FF3A3A3A9D3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F1313131313131313137F3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D % FF535353535353535353FF3A3A3A3A3A000000000000210012101210C516 % 181818181818181818181010121018181818181818101012101018111818 % 18181818181818181818181818181800FF12181018101818101818181818 % 1A1818181818181A18181818161818131810181818181A18181818181818 % 181012101010101010101010181818AFAFAFAFAFAFAF161816FF7D000000 % 00000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D % 9D3A3A3A3A9D9D9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D % 9D9D9D3A3AFF53535353535353FF9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A % 3A3A3A3A9D9D9D3A3A9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D9D9D3A9D % 9D9D9D9D3A9D9D9D9D9DFF53535353535353FF9D9D9D9D3A9D3A9D9D9D9D % 9D3A9D3A9D9D3A3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A9D9D % 9D9D9D9D9D9D3A9D9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A7F1313 % 13131313137F3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A % 9D9D9D9D9D3A9D3A9D3A9D9D3A3A3A3A3A3A3A9D3A9D9D3AFF5353535353 % 5353FF9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D % FF53535353535353FF3A3A3A3A3A3A000000000000210018161216C51812 % 18161818161818121012101012101818181A181810101012181018101818 % 1018181818181A1818181818181A00FF1810121812161218101818181818 % 181818181A18181818181818181810181018181818181818181818181818 % 1018101210101010101010121210121818181810AF181818FF7D00000000 % 000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D9D % 3A3A3A3A9D9D9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D % 9D9D3A3AFF53535353535353FF9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A9D9D9D3A3A9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D9D9D3A9D9D % 9D9D9D3A9D9D9D9D9DFF53535353535353FF9D9D9D9D3A9D3A9D9D9D9D9D % 3A9D3A9D9D3A3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A9D9D9D % 9D9D9D9D9D3A9D9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A7F131313 % 131313137F3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A9D % 9D9D9D9D3A9D3A9D3A9D9D3A3A3A3A3A3A3A9D3A9D9D3AFF535353535353 % 53FF9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9DFF % 53535353535353FF3A3A3A3A3A3A000000000000210018181812C5101210 % 181218181810101810181010121218181818181810121810121812161218 % 101818181818181818181A181800FF171816121610121612101818181818 % 18181A18181818181818181818181018181818181A181818101812181810 % 12101810121012101010101010101012181812AF181818FF7D0000000000 % 0000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D3A9D % 3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A9D9D9D % 9D3A9D9DFFFF535353FFFF9D9D3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9DFFFF535353FFFF9D9D9D3A9D9D9D9D9D9D3A9D9D9D % 9D9D9D3A9D3A9D9D9D9D3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A % 9D9D3A9D9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313 % 137F7F3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D3A % 9D9D9D3A9D3A9D9D9D3A9D9D9D9D3A9D3A9D3A9D3A9D9DFFFF535353FFFF % 9D9D9D3A9D3A9D9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A % 3A3A3A9D3A9D3A3A9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF % FF535353FFFF3A3A3A3A3A3A3A000000000000210018181816C510121012 % 101216121818181818181010101012101818161818171816121610121612 % 10181818181818181A18181800FF18181818121010101010121618181818 % 181818181A1818181A181818181818181818181818181818181010101012 % 101818181010101010101010101010181810AF181018FF7D000000000000 % 00003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D % 3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A7F7F7F3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D3A % 3A9D9D9D3AFFFFFF3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D % 9D9D9D9D9D3A9D3A9D9DFFFFFF9D9D3A9D9D9D9D9D3A3A9D9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D3A9D9D % 9D9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F % 3A3A3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D % 3A3A9D9D9D9D9D9D3A9D3A3A9D3A3A3A3A3A9D3A3A3A9D3AFFFFFF9D9D3A % 9D9D3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F7F7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D3A3A9D3A3A3A9D9D9D9D % FFFFFF3A3A3A3A3A3A3A3A3A000000000000210010181318C51010101012 % 101210101210181818181818121012101018181818181818121010101010 % 121618181818181818181A00FF1012181010101010101010101218181818 % 1818181818181A181A181818181818181818181818181818101210101010 % 1812101810121010101010121012181818AF181618FF7D00000000000000 % 003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A % 3A9D9D9D9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D3A3A % 9D9D9D3AFF3A9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D % 9D9D9D9D3A9D3A9D9D3A9D9DFF9D3A9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D % 9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D3A9D9D9D % 9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A % 3A9D9D9D9D9D9D3A9D3A3A9D3A3A3A3A3A9D3A3A3A9D3AFF3A9D9D9D3A9D % 9D3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D3A3A9D3A3A3A9D9D9D9D3A % 9DFF3A3A3A3A3A3A3A3A3A000000000000210016181618C5121012101012 % 101012101210121818181818101012121218121012181010101010101010 % 1012181818181818181800FF121010101010081010101010101010121816 % 1818181A181A181818181817181818181818181818181818101010101010 % 10121012101018101010101012181818AF181818FF7D0000000000000000 % 3A3A3A3A3A3A3A3A9D3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D9D9D9D9D3A3A % 3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A7F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D % 9D9DFF9D3A9D3A3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D3A9D3A3A3A9D9DFF3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D % 9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D % 3A9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A7F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D3A3A % 9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A3A9DFF3A3A9D9D3A3A9D3A % 3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A % 3A9D3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D9D9D3A9D % FF3A3A3A3A9D3A3A3A3A000000000000210018181818C518181810181010 % 1210101210101012101818C5C5C5C51010101210C5C51010081010C5C5C5 % C5C51012181618181800FF101012101010100A0F0A101010101010101216 % 18181820181A181818181818121618181818181818181812101010101010 % 101010181818181712101816181818AF181818FF7D00000000000000003A % 3A3A3A3A3A3A3A9D9D9D9D3A9D9D9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A3A % 9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A9D9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A9D9D9D % 3AFF3A9D3A9D9D3A3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A9D3A7F3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D % 3A3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D3A9DFF9D9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D % 9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D % 9D9D3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A9D3A % 3A3A3A9D3A3A3A3A3A3A9D9D3A3A9D3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D % 3A9D3A9D9D3A3A3A3A3A3A9D9D9D3A9D9D3A3A3AFF9D9D3A9D9D9D9D9D3A % 9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A9D9D3A9D3A9D9D9D3A9D3A3A3A3A9D3A3A3A3A9D3A3A9D3A9D3A % FF3A3A3A3A3A3A3A3A000000000000210018181818C51818181812101210 % 101210121012101012C5C51618C5C510101010C5C51010100A0F0A10C5C5 % 101010101216181800FF10121010101010100A1010080A10081010101818 % 181A18181818181818101810181217181818181818181010101010101010 % 1012181818181818181818181818AF181818FF7D00000000000000003A3A % 3A3A3A3A3A3A9D9D9D9D3A9D9D9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A3A9D % 9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A9D9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A9D9DFFFF % FF3A9D3A9D9D3A3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A9D3A7F7F7F3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A % 3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D % 9D9D9D3A9D9D9D3A9D9DFFFFFF3A9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D % 3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D9D % 9D3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A9D3A3A % 3A3A9D3A3A3A3A3A3A9D9D3A3A9D3A3A3A3A3A9D3A9D9D9D3A9D9D9D9D3A % 9D3A9D9D3A3A3A3A3A3A9D9D9D3A9D9D3AFFFFFF9D9D3A9D9D9D9D9D3A9D % 9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D7F7F7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A9D9D3A9D3A9D9D9D3A9D3A3A3A3A9D3A3A3A3A9D3A3A9D3A9D3AFF % FFFF3A3A3A3A3A3A000000000000210018181816C5181818181612161012 % 1010101010101010C5C51818C5C518181012101010101010C5C5C5C5C5C5 % 0810101018181800FF181216121818181010101010081008101010121818 % 18181A18181818181810121010181812181812161216121010100A101010 % 12181818181818181818181A18AF181818FF7D00000000000000003A3A3A % 3A3A3A3A3A9D3A9D9D3A9D3A9D9D3A3A9D9D3A3A3A9D9D9D9D3A3A9D3A9D % 9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F13 % 13137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D9D9D9D9D3A3A9D9D9D3A9D9D9D9D3AFFFF535353 % FFFF9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A9D3A3A9D3A9D3A9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D3A % 9D3A9D9D9D3A9DFFFF535353FFFF9D9D9D3A9D9D9D9D9D9D9D3A9D3A3A9D % 3A9D3A9D9D9D9D9D3A9D3A9D9D3A9D9D9D3A9D9D9D9D3A9D9D9D9D3A9D9D % 9D9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A % 3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D9D9D9D % 9D9D9D9D3A3A9D3A3A9D3A3A9D9DFFFF535353FFFF9D9D9D9D3A9D9D9D9D % 3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F % 7F1313137F7F3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A % 3A3A9D9D3A9D9D9D3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D9D3A3AFFFF5353 % 53FFFF3A3A3A3A000000000000210018181812C5C5C5C5C5C5C5C5C5C5C5 % C5C51212161210C5C51818C5C518181812161218181810C51010C5C51008 % 10101012181800FF18161210181618101210101010080A10101010101818 % 181818181817121012161218101210101010121018121012101010101012 % 181818181A18181818181818AF181818FF7D00000000000000003A3A3A3A % 3A3A3A3A9D9D9D9D9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D9D3A3A3A3A9D9D % 3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A7F13131313 % 1313137F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D3A3A9D9D9D9DFF535353535353 % 53FF9D9D9D9D9D3A9D9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A9D3A9D3A3A9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A % 9D9D3A9D3AFF53535353535353FF9D3A9D9D3A9D9D3A9D3A9D3A9D3A3A9D % 3A9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D % 9D9D3A3A3A9D3A3A3A9D3A3A3A9D3A7F131313131313137F3A3A3A3A3A3A % 3A3A3A3A3A9D3A9D9D3A3A3A9D3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D % 9D3A9D3A9D3A9D9D9D3A9D9DFF53535353535353FF9D3A9D9D9D3A9D9D3A % 9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313 % 13131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D % 9D3A9D9D3A9D9D3A9D9D9D3A3A9D3A9D9D9D3A9D9D3A9D9DFF5353535353 % 5353FF3A3A3A000000000000210018181010C51818171818101810181018 % 181818181818C5C51012C5C51618181612101816181012C510C5C5080A10 % 101010101800FF1012101012181818181012101010101010101218181818 % 181818181812101218121012101210121010181216121010101010101018 % 18181A181A18181A181A18AF181810FF7D00000000000000003A3A3A3A3A % 3A3A3A9D9D9D9D9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D9D3A3A3A3A9D9D3A % 9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 13137F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D3A3A9D9D9D9DFF53535353535353 % FF9D9D9D9D9D3A9D9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A9D3A9D3A3A9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D % 9D3A9D3AFF53535353535353FF9D3A9D9D3A9D9D3A9D3A9D3A9D3A3A9D3A % 9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D3A3A3A9D3A3A3A9D3A3A3A9D3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A9D3A9D9D3A3A3A9D3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D9D % 3A9D3A9D3A9D9D9D3A9D9DFF53535353535353FF9D3A9D9D9D3A9D9D3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F131313 % 131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D % 3A9D9D3A9D9D3A9D9D9D3A3A9D3A9D9D9D3A9D9D3A9D9DFF535353535353 % 53FF3A3A3A000000000000210018101210C5101812181012181818181818 % 18181A1818C5C51210C5C5121810121010121818181810C5C5C510101010 % 1012181800FF181012101210101012101210100A08101010101012101218 % 101810121010101010181818181010101010101210121810181012121818 % 181A1818181818181818AF181010FF7D00000000000000003A3A3A3A3A3A % 3A3A9D3A9D9D3A9D3A9D9D9D3A9D3A3A9D3A9D9D3A9D9D3A9D3A9D9D3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 13137F3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A9D9D9D9D9D9D9D3A9D9D9D9D3A3A9D9D9DFF535353535353535353 % FF9D9D9D3A3A9D9D3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D % 3A9D9D9D9D3A9D9D9D3A9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D3A3A % 9D9DFF535353535353535353FF9D9D9D9D9D9D3A9D3A9D3A3A3A3A3A9D3A % 9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D % 3A3A3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A % 3A3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A9D9D9D9D9D % 3A9D9D3A3A3A9D3A9DFF535353535353535353FF9D9D9D3A3A9D3A3A3A9D % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D % 9D9D9D9D9D9D3A9D9D9D3A3A9D3A3A9D9D3A9D9D9DFF5353535353535353 % 53FF3A3A000000000000210010101010C510101010121010101012101818 % 18181818C5C51818C5C5101818101210121010101210C5C5C50A08101010 % 10101200FF18181810101010121012161010101010101010101010121012 % 121010101010101018181818181810181010101012101816121816181818 % 181818181818181818AF181010FF7D00000000000000003A3A3A3A3A3A3A % 3A9D3A9D9D9D9D9D9D3A3A3A9D3A9D9D3A9D9D9D3A3A3A3A9D9D3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313 % 137F3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A9D3A9D9D9D9D9D9D3A9D9D9D9DFF535353535353535353FF % 9D3A9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A % 3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D % 9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A % 9DFF535353535353535353FF3A3A9D3A9D3A3A3A9D3A9D9D3A3A3A9D3A3A % 9D9D9D9D9D9D9D3A9D3A9D9D3A9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D3A % 3A3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A9D % 3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D % 3A3A9D9D3A3A9D9DFF535353535353535353FF9D3A9D9D9D9D3A9D3A9D9D % 3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A9D3A9D % 9D9D9D9D3A3A9D9D9D9D3A3A3A3A3A3A9D3A9D9DFF535353535353535353 % FF3A3A000000000000210010101010C51010101012101210121018181718 % 18161818C5C5C5C51818181818181010101012101216C5C5101010101010 % 101000FF1818171818181810101210121010101010101010101010101010 % 101010081010101218181818181818101010101010181212161818181A16 % 1818181816181818AF101210FF7D00000000000000003A3A3A3A3A3A3A3A % 9D3A9D9D9D9D9D9D3A3A3A9D3A9D9D3A9D9D9D3A3A3A3A9D9D3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F131313131313131313 % 7F3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A9D3A9D9D9D9D9D9D3A9D9D9D9DFF535353535353535353FF9D % 3A9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A % 3A3A7F1313131313131313137F3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D % 9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D % FF535353535353535353FF3A3A9D3A9D3A3A3A9D3A9D9D3A3A3A9D3A3A9D % 9D9D9D9D9D9D3A9D3A9D9D3A9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D3A3A % 3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A9D3A % 9D3A9D3A9D3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A % 3A9D9D3A3A9D9DFF535353535353535353FF9D3A9D9D9D9D3A9D3A9D9D3A % 3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 13137F3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A9D3A9D9D % 9D9D9D3A3A9D9D9D9D3A3A3A3A3A3A9D3A9D9DFF535353535353535353FF % 3A3A000000000000210012101010C5101210181818101810181018121818 % 181818181818181818181818171818181810101210121010101010101010 % 1000FF121818181818181012101810181816121818181210101012101010 % 10100A081010181818181818181818121010101012101012121818181818 % 16181818181816AF101010FF7D00000000000000003A3A3A3A3A3A3A3A9D % 3A9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D3A3A9D9D9D3A9D3A3A % 3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A9D7F131313131313137F3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A9D9D9D9D3A9D9D3A9D9D9D9D9D3A3A3A3AFF53535353535353FF3A3A9D % 9D9D9D9D9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D7F131313131313137F3A3A3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D3A9D3A9D9D9D3A9D9D9D9D9D3A9D3A9D3A9D9D3A % FF53535353535353FF9D9D3A9D3A3A9D3A9D3A9D3A3A3A3A3A9D3A9D3A3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D9D9D9D9D3A3A3A % 9D3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A9D3A3A3A3A3A9D % 3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A9D9D9D9D3A3A9D9D9D % 3A9D9D9D3A9D9DFF53535353535353FF9D9D9D9D9D3A9D9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A9D9D3A3A3A9D9D9D9D9D3A9D % 3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9DFF53535353535353FF3A3A % 3A000000000000210010101010C512161818181818181210121012101810 % 181818181818181818121818181818181012101810181816121818181210 % 00FF10121012101212101012121618181818181818181818101818131610 % 101010101210181818181818181010101010101010101010121018181818 % 181818181818AF121010FF7D00000000000000003A3A3A3A3A3A3A3A9D3A % 9D9D3A9D9D9D3A9D3A3A3A9D9D3A9D3A9D9D9D3A3A9D9D3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D % 9D9D9D9D9D9D9D3A3A9D9D9D3A3A3A3A3AFF53535353535353FF9D3A9D9D % 3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A7F131313131313137F3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D3A9D % 9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A9D9D3A9D9DFF % 53535353535353FF9D9D3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D3A9D9D3A % 9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D % 3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A % 9D9D3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D9D9D9D9D3A9D3A3A9D9D3A % 9D9D9D9D3A9DFF53535353535353FF9D9D9D9D9D3A9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D3A9D3A9D9D9D9D9D9D % 9D3A9D9D9D3A9D3A9D3A9D9D3A9D3A3A9D9DFF53535353535353FF3A3A3A % 000000000000210010101010C518181818181A1818181010101010121012 % 101812161818181010121012101212101012121618181818181818181800 % FF1210101210101010181010121818181818181A181A1818181718181218 % 181810101810181218181012101210101818101010101010121218181818 % 1818181818AF101210FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D % 9D3A9D9D9D3A9D3A3A3A9D9D3A9D3A9D9D9D3A3A9D9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D % 9D9D9D9D9D9D3A3A9D9D9D3A3A3A3A3A3AFFFF535353FFFF9D9D3A9D9D3A % 9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A7F7F1313137F7F9D3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D9D3A9D9D % 9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A9D9D3A9D9D9DFF % FF535353FFFF3A9D9D3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D3A9D9D3A9D % 9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A9D3A9D % 9D3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D9D9D9D9D3A9D3A3A9D9D3A9D % 9D9D9D3A9D9DFFFF535353FFFF3A9D9D9D9D9D3A9D9D9D3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D3A9D3A9D9D9D9D9D9D9D % 3A9D9D9D3A9D3A9D3A9D9D3A9D3A3A9D9D3AFFFF535353FFFF3A3A3A3A00 % 0000000000210012101010C51818181A1818181818121010101010121010 % 101012101818101210101210101010181010121818181818181A181A00FF % 1818121010121012121012101018181618181A1818181818181818171818 % 181612121012101010181810101212181018181010101210101818181A18 % 18181818AF161210FF7D00000000000000003A3A3A3A9D3A3A3A9D9D9D9D % 9D9D9D9D9D9D3A9D9D9D9D3A9D9D3A3A9D9D9D3A9D9D3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D % 9D9D9D3A9D9D9D9D9D3A3A3A3A3A3A3A3AFFFFFFFF3A3A9D3A9D3A3A3A9D % 9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A9D9D9D9D9D9D3A9D % 9D9D9D3A9D9D9D3A9D3A9D9D3A9D3A3A9D9D9D9D3A9D9D3A9D9D3A9D9D9D % FFFFFF9D9D9D9D3A3A9D3A9D3A3A9D3A3A9D3A9D3A9D3A9D3A9D3A9D3A9D % 9D9D9D9D9D9D3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A3A3A9D3A3A % 3A9D3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A9D9D3A % 9D9D9D9D9D3A9DFFFFFF3A3A3A9D9D9D3A9D3A9D3A9D9D9D9D9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A9D3A9D9D9D3A % 9D3A9D9D3A9D3A9D3A3A9D9D9D9D9D9D3A9D3AFFFFFF3A3A3A3A3A3A0000 % 00000000210012101212C518181818181A18181810100B0E10101010100E % 1010101218181818121010121012121012101018181618181A181800FF18 % 181818121010181010101012181810101818181818121012101818181818 % 181810101010101018181012101010181818181816121612181818181818 % 181818AF181018FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D % 9D9D3A9D9D3A3A9D3A9D9D3A9D3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D % 9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3AFF3A3A3A3A3A3A9D9D9D3A9D9D9D % 9D3A9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D3A9D9D9D % 9DFF9D3A9D3A9D3A3A9D3A9D9D3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A3A % 3A3A3A3A9D3A3A3A3A7F3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D9D3A % 3A3A3A9D3A3A3A3A9D9D9D3A9D9D3A9D9D9D3A9D9D3A3A3A3A3A9D9D9D3A % 9D9D9D3A9D9DFF3A9D3A3A3A9D9D9D9D9D9D3A9D9D3A9D9D9D3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D9D9D9D3A9D3A9D9D9D9D % 9D9D9D9D3A9D9D9D9D3A3A9D9D9D9D3A9D3A3A3AFF3A3A3A3A3A3A000000 % 000000210010181316C5181818181A181A181812101010101010100A100A % 101012161818181818121010181010101012181810101818181800FF1618 % 18181818101818181012101010181816181818161810101018131618181A % 181818121010101810181210181813181818181818181818181818181818 % 1818AF181012FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D % 9D3A9D9D3A3A9D3A9D9D3A9D3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D9D9D % 9D3A9D9D9D9D3A3A3A3A3A3A3A3A3AFF3A3A3A3A3A3A9D9D9D3A9D9D9D9D % 3A9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D3A9D9D9D9D % 9DFF3A9D3A9D3A3A9D3A9D9D3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A3A3A % 3A3A3A9D3A3A3A7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D9D3A3A % 3A3A9D3A3A3A3A9D9D9D3A9D9D3A9D9D9D3A9D9D3A3A3A3A3A9D9D9D3A9D % 9D9D3A9DFF3A3A9D3A3A3A9D9D9D9D9D9D3A9D9D3A9D9D9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A9D3A9D9D9D9D3A9D3A9D9D9D9D9D % 9D9D9D3A9D9D9D9D3A3A9D9D9D9D3A9D3A3A3A3AFF3A3A3A3A3A00000000 % 0000210010121618C518181A181A181818181818181810100A1010101010 % 1010121816181818181810181818101210101018181618181800FF121818 % 181818181818171210101010121012181018121818181812161812161818 % 1818181018101210121618181018181818181818181818181818181A1818 % 18AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D % 9D9D9D3A9D3A3A9D9D3A9D3A3A9D3A9D9D9D3A3A9D9D3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D9D9D9D3A9D3A9D % 9D9D3A9D3A3A9D9D9D9D9DFFFFFFFF3A3A3A3A3A3A9D9D9D9D9D3A3A9D9D % 9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A7F7F7F3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D3A9D9D % FFFFFF3A9D3A3A3A9D3A3A9D9D3A9D3A3A3A3A9D3A3A9D3A3A3A9D3A9D3A % 9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D3A3A3A3A3A % 3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A % 3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D9D3A3A9D9D3A9D9D9D9D9D % 3AFFFFFF3A9D9D3A3A3A9D9D3A9D9D3A9D3A9D3A9D9D3A9D3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A7F7F7F3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A9D9D3A9D3A3A3A9D9D9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3AFFFFFF3A3A3A0000000000 % 00210018181818C518181818181818181216181812101010121010101010 % 10101212181818181818181817121010101012101218101800FF10121612 % 181610181818121612101012101210121618181818181818121018101216 % 18161818181018101210121018161818181818181A181A18181818181818 % AF181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D % 9D9D3A9D3A9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A % 9D9D9D3A3A9D9D9DFFFF535353FFFF9D3A3A3A3A3A3A3A9D9D9D9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F % 7F1313137F7F3A3A9D3A3A3A9D3A9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D % 3A9D9D3A9D9D9D3A9D9D3A9D9D3A9D9D3A9D3A9D9D9D3A9D3A9D9DFFFF53 % 5353FFFF3A3A9D3A9D9D3A9D3A3A3A9D3A9D3A3A9D3A3A9D3A9D9D9D9D9D % 9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A3A9D3A3A3A3A3A3A % 3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A3A3A3A % 3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D9D3A9D3A9D3A9D3A3A9D9DFFFF % 535353FFFF3A9D3A3A9D9D9D9D9D3A9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F9D3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A9D9D3A9D9D9D3A9D9D % 9D9D9D9D3A9D9D9D3A9D9D9D3A9D3A3AFFFF535353FFFF3A000000000000 % 210018181818C51018181818181812101012161818121018101010101010 % 101010121612181610181818121612101012101210121600FF1010121012 % 181218161810121012101010101010121216181818161810181010121012 % 18181818161210181012101212101818181818181818181A18181A1E18AF % 181818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D % 9D3A9D3A9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F131313131313137F3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A9D % 9D9D3A3A9D9DFF53535353535353FF3A3A3A3A3A3A3A9D9D9D9D9D9D3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313 % 13131313137F3A9D3A3A3A9D3A9D3A9D9D3A9D9D9D9D9D9D3A9D9D9D9D3A % 9D9D3A9D9D9D3A9D9D3A9D9D3A9D9D3A9D3A9D9D9D3A9D3A9DFF53535353 % 535353FF3A9D3A9D9D3A9D3A3A3A9D3A9D3A3A9D3A3A9D3A9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A3A9D3A3A3A3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A3A3A3A3A % 3A3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D9D3A9D3A9D3A9D3A3A9DFF535353 % 53535353FF9D3A3A9D9D9D9D9D3A9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D3A3A9D9D3A9D9D9D3A9D9D9D % 9D9D9D3A9D9D9D3A9D9D9D3A9D3AFF53535353535353FF00000000000021 % 0018181818C5181818181818181810101210181216181810121010121010 % 1010101210121812181618101210121010101010101200FF101010101012 % 161218101812161210101012101210101210181218181818181810181810 % 1212101218101210101010101210121818181818181818181A181A18AF18 % 1818FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A % 9D9D9D3A9D3A9D3A9D9D3A3A9D9D9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D9D9D9D9D % 3A3A3A3A3AFF53535353535353FF9D9D3A3A3A3A9D3A9D9D9D9D9D3A3A9D % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D7F131313 % 131313137F3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9DFF5353535353 % 5353FF3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A3A9D3A9D9D3A9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A3A3A9D3A3A3A3A9D3A7F13 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D9D3A9D3A3A3A3A3A % 9D3A3A3A3A9D9D3A9D9D9D3A9D9D3A9D9D3A3A9D3A9D3A9D9DFF53535353 % 535353FF9D3A3A9D9D9D9D9D9D9D3A9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A9D3A3A3A % 3A3A3A3A3A3A9D9D3A3A9D9D3A9D9D3A3A9D9D3A9D9D9D3A9D9D9D3A9D9D % 9D9D9D9D3A9D9D3A9D9D3A9D3AFF53535353535353FF0000000000002100 % 18181818C51818181A181818181010121012101210121810121010101210 % 10101010101216121810181216121010101210121000FF10101012181818 % 161818181018161810101010101012101210101218161818181818101210 % 101018161210121010101010101210121612181818181A18201E1AAF1A18 % 18FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D3A3A3A % 9D3A9D9D3A9D9D9D9D3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D3A % 3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A % 9D3A3AFF535353535353535353FF9D3A3A3A3A3A9D9D9D9D9D9D9D3A9D9D % 9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3A9D3A9D3A9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D9D9DFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D9D % 3A9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D3A3A3A9D3A3A3A3A3A7F131313 % 1313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A % 3A9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D3A3A9D3A9D3A9DFF535353535353 % 535353FF3A3A9D9D3A9D9D3A9D9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F3A3A9D3A3A % 3A3A3A3A9D3A3A3A9D9D3A9D9D3A3A3A9D9D9D3A9D3A3A9D9D9D9D9D3A9D % 3A3A3A9D3A9D3A9D9D3A9DFF535353535353535353FF0000000000210018 % 181818C51818181818181818181812101010101018101818181812101010 % 101012181818161818181018161810101010101000FF1810121018181818 % 121810181818181810121012101010101012101012121018181018101010 % 10181210101010101010101010101010101818181818181A181AAF181818 % FF7D00000000000000003A3A3A3A3A3A3A3A9D3A9D9D9D3A9D9D3A3A3A9D % 3A9D9D3A9D9D9D9D3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D3A3A % 3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A9D % 3A3AFF535353535353535353FF9D3A3A3A3A3A9D9D9D9D9D9D9D3A9D9D9D % 3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A3A9D3A9D3A9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D9D9DFF5353535353535353 % 53FF3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9D9D9D3A % 9D9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D3A3A3A9D3A3A3A3A3A7F13131313 % 13131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D3A3A9D3A9D3A9DFF53535353535353 % 5353FF3A3A9D9D3A9D9D3A9D9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F3A3A9D3A3A3A % 3A3A3A9D3A3A3A9D9D3A9D9D3A3A3A9D9D9D3A9D3A3A9D9D9D9D9D3A9D3A % 3A3A9D3A9D3A9D9D3A9DFF535353535353535353FF000000000021001818 % 1816C5181818181818181818121010101010101012101818181818181810 % 1210181818181218101818181818101210121000FF1A1818181618181816 % 181818181618181818101010101012121012101010101218101210121010 % 18101612101010101010101010101010101818181818181820AF1A1818FF % 7D00000000000000003A3A3A3A3A3A3A9D9D3A9D9D9D9D9D9D3A9D3A9D9D % 3A9D9D3A9D3A9D3A3A3A9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A % 3A3A3A9D3A3A3A3A3A9D3A3A3A3A9D9D9D9D9D3A9D9D9D9D3A9D3A3A3A3A % 3AFF535353535353535353FF9D3A3A9D3A3A9D9D9D9D9D9D9D3A9D9D9D9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A7F13131313131313 % 13137F3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D3AFF535353535353535353 % FF3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A9D3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A9D3A9D3A9D3A9D3A9D9D3A9D3A3A3A9D9D3A9DFF5353535353535353 % 53FF9D3A9D9D9D9D3A9D3A9D3A3A9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A % 3A3A9D9D3A9D9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D9D % 9D9D9D9D9D9D9D3A9DFF535353535353535353FF00000000002100181818 % 12C5121018181810121612161010101010121010181818181818181A1818 % 18161818181618181818161818181810101000FF181818181A1818181810 % 181018181816181216121018101010121010101010101012101216181812 % 18181818181010101010101010101010121018181A202118AF181818FF7D % 00000000000000003A3A9D3A3A3A3A3A9D3A9D9D3A9D9D3A9D3A3A9D3A9D % 3A9D9D9D9D9D9D3A9D3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F131313131313137F3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D3A3A3A3A3A % 3AFF53535353535353FF9D9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A9D3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D % 9D9D9D9D9D9D9D3A9D3A9D9D9D9D3A9D9D9D9D3AFF53535353535353FF3A % 3A9D3A3A9D3A3A9D3A3A3A3A3A3A9D3A9D3A3A3A9D9D9D9D3A9D9D9D9D9D % 9D9D9D3A3A9D9D9D9D3A9D9D9D9D3A3A9D9D3A3A3A3A3A3A7F1313131313 % 13137F3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A9D3A9D3A9D3A9D3A9D9D9D9D3A3A9D3A3A9D9D9DFF53535353535353FF % 3A3A3A9D9D9D9D3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A % 9D3A3A9D9D3A9D3A9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D3A3A3A3A % 9D9D9D9D9D9D3A9D3AFF53535353535353FF000000000000210018181016 % C5101210101210181018181310100A08081010101216181A181818181818 % 1A1818181810181018181816181216121000FF1818181818181A18101812 % 121212181818181012101210101216181818181210121018101812181612 % 1816181818181010101010101010101012181818201A18AF181212FF7D00 % 000000000000003A3A9D3A3A3A3A3A9D3A9D9D3A9D9D3A9D3A3A9D3A9D3A % 9D9D9D9D9D9D3A9D3A9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F131313131313137F3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A % FF53535353535353FF9D9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 3A3A3A3A3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D9D % 9D9D9D9D9D9D3A9D3A9D9D9D9D3A9D9D9D9D3AFF53535353535353FF3A3A % 9D3A3A9D3A3A9D3A3A3A3A3A3A9D3A9D3A3A3A9D9D9D9D3A9D9D9D9D9D9D % 9D9D3A3A9D9D9D9D3A9D9D9D9D3A3A9D9D3A3A3A3A3A3A7F131313131313 % 137F3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 9D3A9D3A9D3A9D3A9D9D9D9D3A3A9D3A3A9D9D9DFF53535353535353FF3A % 3A3A9D9D9D9D3A9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D % 3A3A9D9D3A9D3A9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D3A3A3A3A9D % 9D9D9D9D9D3A9D3AFF53535353535353FF000000000000210012121812C5 % 10181012101810121816181810101008101010181818181A181818181818 % 181A181018121212121818181810121000FF1A181A181A18181818121010 % 101010181210101012101216121818181818181818181812161812101210 % 1212161818101010121010100E101010121818181818AF101010FF7D0000 % 0000000000003A3A3A3A3A3A3A3A9D9D9D9D9D9D9D3A3A9D3A3A9D9D3A9D % 3A9D3A9D9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F7F1313137F7F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D3A9D9D9D3A3A3A3A3A3A3A9D % FFFF535353FFFF9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D7F7F1313137F7F3A3A % 3A3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 3A9D3A9D9D9D9D9D3A9D9D9D9D9D3A9D9D9D9DFFFF535353FFFF3A9D3A3A % 3A9D3A3A9D3A3A3A3A3A9D9D3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 9D9D9D9D3A9D3A9D9D9D9D3A3A9D9D3A9D3A3A3AFFFF535353FFFF9D3A3A % 3A9D3A9D9D9D9D9D9D3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D3A3A3A3A3A3A3A3A9D % 9D9D9D9D9D9D3A3A3A3A9D9D9D3A9D9D9D3A9D3A3A9D9D9D9D3A3A3A9D3A % 9D3A9D9D3A9D3A3AFFFF535353FFFF3A000000000000210010101210C518 % 1818181012101210181818181210101010121818181A18181A181A181A18 % 18181812101010101018121010101200FF18181818181818181810101010 % 101018181012101010121012161818181818181818181818131612101010 % 101212181012101010101010101010101216181812AF121012FF7D000000 % 00000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A3A9D3A3A9D9D3A % 9D9D9D3A3A9D3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A9D9D % 9DFFFFFF3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A % 3A3A3A3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D % 9D9D3A9D9D9D3A9D9D9D3A9D3A3A9D3A9D9D9D9DFFFFFF3A3A3A3A3A9D9D % 3A3A9D3A3A9D3A3A3A3A3A9D3A3A3A9D9D3A9D3A3A9D9D3A9D9D9D9D9D9D % 9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A3A3A3A3A9D3A3A3A3A7F7F7F3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D % 9D9D9D3A3A9D9D9D9D3A3A3A3A9D9D9D9D9D9D9D9DFFFFFF9D3A3A9D3A3A % 9D9D9D3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 9D9D3A9D3A9D3A3A9D3A9D3A9D9D9D9D3A3A9D9D9D9D3A9D3A9D9D3A9D3A % 9D9D9D3A9D3A3A3A3AFFFFFF3A3A3A000000000000210010121012C51818 % 18181812101010101218181818121012101818181A181818181818181818 % 181810101010101018181012101000FF1818181818181818121010101010 % 101818101010101218101012181818181818181818181816181818121010 % 1010121612181010121010101010101210121010AF101010FF7D00000000 % 000000003A3A3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A3A9D3A3A9D9D3A9D % 9D9D3A3A9D3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A9D9D9D % FF3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A % 3A3A3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D3A9D9D9D3A9D9D9D3A9D3A3A9D3A9D9D9D9D3A9DFF3A3A3A3A3A9D9D3A % 3A9D3A3A9D3A3A3A3A3A9D3A3A3A9D9D3A9D3A3A9D9D3A9D9D9D9D9D9D9D % 9D3A9D9D3A9D9D9D9D9D3A3A9D3A3A3A3A3A9D3A3A3A7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9D % 9D9D3A3A9D9D9D9D3A3A3A3A9D9D9D9D9D9D9D9DFF9D9D9D3A3A9D3A3A9D % 9D9D3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D % 9D3A9D3A9D3A3A9D3A9D3A9D9D9D9D3A3A9D9D9D9D3A9D3A9D9D3A9D3A9D % 9D9D3A9D3A3A3A3A3A3A3AFF3A3A000000000000210010101012C5181818 % 18181810121010101010121618121618181818181A181818181818181818 % 1210101010101018181010101000FF181818181818181810121010101010 % 181618181216121010101210181810121818181818181818181818161210 % 10101812161210101010101012101012101012AF101010FF7D0000000000 % 0000003A3A3A3A3A3A3A9D3A3A9D9D3A9D9D3A3A9D3A3A9D3A9D3A9D3A9D % 3A9D3A3A3A3A9D9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A % 3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A3A9D3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A3A3A9D9DFF3A % 3A3A3A9D9D9D9D3A3A3A3A9D3A9D3A9D3A9D9D3A3A3A9D3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A7F3A3A3A9D3A3A % 9D3A9D9D9D3A9D9D9D9D3A9D9D9D3A9D9D9D9D3A9D9D3A9D9D9D3A9D3A9D % 9D9D9D3A9D9D9D9D3A9D3A3A9D9D9D3A9D3A9D9DFF9D9D3A3A9D3A3A3A9D % 3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D9D9D9D9D9D9D9D3A3A3A9D3A3A3A3A3A3A9D3A3A7F3A3A9D3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A9D9D3A9D % 9D9D9D3A3A9D9D9D3A3A9D3A3A9D3A9D9D9DFF9D9D3A3A3A3A3A3A3A9D9D % 3A9D9D3A3A9D9D3A3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D7F3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D9D % 9D3A3A9D3A9D9D3A9D9D9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D % 9D3A9D3A3A3A3A3A3A3AFF3A3A000000000000210010101010C51818181A % 181812101010100808101012101812171818181818181818181818181810 % 12101010101018161818121600FF12161818101810181210121010101212 % 181818181812101010121613101210181618181818181818181818181010 % 101216121012101216181810181012101216AF101010FF7D000000000000 % 00003A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D9D3A9D9D9D9D9D9D % 9D9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D9D3A3A3A9D3A3A3A9D9DFF9D9D % 9D9D9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A7F3A3A3A3A3A3A3A % 3A9D3A9D3A3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D3AFF3A9D3A3A9D3A3A9D3A % 9D9D9D9D3A9D3A3A9D3A3A3A9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D % 9D9D3A9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A9D7F3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D % 3A3A9D9D3A9D9D3A3A9D3A9D9D9D3A9D9DFF3A3A3A3A3A9D3A3A9D9D9D9D % 3A9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D % 3A9D3A3A3A9D3A3A3AFF3A3A000000000000210010101010C51818181818 % 181818101010100A10101010121612181818181812161818101810181210 % 121010101212181818181800FF1012101012161210101010121012161818 % 181A18181210181218181818101218121216181818181218181818181012 % 1018101810181012181818181812161218AF101010FF7D00000000000000 % FFFFFF3A3A3A3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D % 9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A7F7F7F % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D9D3A3A3A9D3A3A3AFFFFFF9D9D9D % 9D9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A7F7F7F3A3A3A3A3A % 9D3A9D3A3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D3AFFFFFF3A3A9D3A3A9D3A9D % 9D9D9D3A9D3A3A9D3A3A3A9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D3A9D9D9D9D9D3A3A9D3A9D3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D3A % 3A9D9D3A9D9D3A3A9D3A9D9D9D3AFFFFFF3A3A3A3A3A9D3A3A9D9D9D9D3A % 9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A % 3A3A3A3A3A9D3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A % 9D3A3A3A9D3A3A3A3AFFFFFF0000000000210010101010C51818181A2018 % 1818101210101010100A1012101818181818121012101012161210101010 % 121012161818181A181800FF181818181810121612161216121818181818 % 1A1818181010101010121018101010101218181818101210101010181810 % 12101812181816181A18181818181618AF181818FF7D0000000000FFFF53 % 5353FFFF3A9D3A3A9D3A9D9D9D9D9D3A3A9D9D3A3A9D9D9D3A9D3A9D9D9D % 9D3A3A3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F % 7F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A9D9D9D9D9D3A9D9D9D9D9D3A3A3A3A3AFFFF535353FFFF9D9D % 9D3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A9D % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D3A3A9D9D3A9D3A9D3A9D9D3AFFFF535353FFFF3A3A9D3A9D9D9D % 9D9D9D9D3A3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D9D9D9D9D3A9D3A9D3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A9D9D3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D3A9D % 3A9D3A3A9D9D3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A9D9D3A3A9D9D9D % 9D9D3A9D9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A % 3A3A9D3A9D9D9D9D3A9D3A9D9D3A9D9D3A9D9D9D9D9D3A9D3A9D9D9D3A9D % 3A3A3A3A3A3AFFFF535353FFFF000000210018181010C510101216181818 % 181810121010101010101010101012101818181818181810121612161216 % 1218181818181A181800FF1A1818181012101810121012AF181818181818 % 181818181010101010101010101010101216181818101012101218181010 % 1216121618181818181A1818181818AF181816FF7D00000000FF53535353 % 535353FF3A3A3A9D3A9D3A9D9D9D3A3A3A3A9D3A3A9D9D3A3A9D9D3A9D9D % 9D9D3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D9D9D3A9D3A9D9D9D3A3A3A3AFF53535353535353FF3A9D % 9D9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A9D3A % 9D3A3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A % 9D3A9D9D9D9D3A9D9D9D9D9D9D3AFF53535353535353FF3A9D9D3A9D9D9D % 3A9D3A9D9D3A3A3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D3A9D3A9D3A3A3A7F131313131313137F3A3A9D3A3A3A3A3A3A3A % 3A9D3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D % 9D9D9D9D9D9D3A9D9DFF53535353535353FF9D9D3A9D9D9D9D9D3A9D9D3A % 9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D % 3A3A3A3A9D9D9D9D9D3A9D9D3A9D3A9D3A9D9D3A9D9D3A9D9D9D9D3A9D3A % 3A3A3A3AFF53535353535353FF0000210018161818C51010101218101810 % 18121010101012101010101210121618181A181818101210181012101216 % 181818181818181800FF18181818181118131612161218AFAF1818181A18 % 181818101010101010100A1010101010AFAFAFAFAFAF1012161218101210 % 1813181818181818181818181810AF161318FF7D00000000FF5353535353 % 5353FF3A3A3A9D3A9D3A9D9D9D3A3A3A3A9D3A3A9D9D3A3A9D9D3A9D9D9D % 9D3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D9D9D3A9D3A9D9D9D3A3A3A3AFF53535353535353FF3A9D9D % 9D9D3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A9D3A9D % 3A3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D % 3A9D9D9D9D3A9D9D9D9D9D9D3AFF53535353535353FF3A9D9D3A9D9D9D3A % 9D3A9D9D3A3A3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D3A9D3A9D3A3A3A7F131313131313137F3A3A9D3A3A3A3A3A3A3A3A % 9D3A3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D % 9D9D9D9D9D3A9D9DFF53535353535353FF9D9D3A9D9D9D9D9D3A9D9D3A9D % 9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A % 3A3A3A9D9D9D9D9D3A9D9D3A9D3A9D3A9D9D3A9D9D3A9D9D9D9D3A9D3A3A % 3A3A3AFF53535353535353FF0000210013181818C5121010121010121018 % 101012101216181618121618181818181818181818111813161216121818 % 181818181A181800FF1A1818181818161818121012161818AFAF1A181818 % 1818101010101010101010100810AFAFAFAFAFAFAFAF1018161216121810 % 18101810181818181818181010AF121818FF7D000000FF53535353535353 % 5353FF3A9D9D9D9D9D9D3A9D9D3A3A9D9D3A3A9D9D3A3A9D9D3A9D9D9D9D % 9D3A9D9D9D3A3A3A3A9D3A3A3A3A3A9D3A3A9D7F1313131313131313137F % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A9D9D3A9D9D3A9D9D9D3A3A3AFF535353535353535353FF9D9D9D % 9D3A3A3A3A3A3A9D9D9D3A9D9D9D9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A9D3A9D3A % 3A9D9D9D9D3A9D9D9D9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A % 9D9D3A9D3A9D9D9D9D3A3AFF535353535353535353FF9D9D9D9D9D9D9D9D % 3A9D3A9D3A9D3A9D3A9D3A9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D3A9D3A9D3A3A7F1313131313131313137F3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A9D3A3A9D9D3A3A3A3A9D3A3A3A3A3A9D3A9D9D3A3A9D3A3A9D % 9D3A9D9D9D9DFF535353535353535353FF9D9D9D9D3A9D9D3A3A9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F1313131313131313137F3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A9D9D9D9D3A9D9D3A3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A % 3AFF535353535353535353FF00210018181818C518181010101012101210 % 1210121618181818181818181818181A1818181818161818121012161818 % 1A181A18181800FF1818181818181818171216181818181818AFAFAFAFAF % 18111812101210101010101008AF101018181818AF181210121018101810 % AFAFAFAFAFAFAFAFAFAFAFAFAF181618FF7D000000FF5353535353535353 % 53FF3A3A9D3A9D9D3A9D9D3A3A9D3A3A3A9D9D3A3A9D9D9D9D3A3A9D9D9D % 9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A7F1313131313131313137F3A % 3A3A3A3A3A9D9D9D9D9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A9D3A9D9D3A9D3A9D9D3A9D3A3AFF535353535353535353FF9D9D9D9D % 3A3A3A3A3A3A3A9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F3A3A3A9D3A3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A3A9D % 9D9D3A9D3A3A9D3A9D9DFF535353535353535353FF3A9D9D3A9D9D3A3A3A % 9D3A3A9D3A9D3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D9D % 3A3A9D3A9D3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A9D9D9D9D9D9D3A9D % 9D9D3A9D9DFF535353535353535353FF9D9D3A3A9D9D3A9D9D9D3A9D9D3A % 3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D9D7F1313131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A % 9D9D9D3A3A9D9D9D9D3A9D9D3A9D9D3A9D9D3A9D9D3A9D9D3A9D3A3A3A3A % FF535353535353535353FF00210016181818C5C5C5C5C5C5C51018101810 % 121018181818181818181818181818181818181818181712161818181818 % 18181A181800FF18181818181A181818181218181818AFAF181818181618 % 181612161810121012101010AF101010121816AF18181018181316131810 % 1210101216121818121618AF181818FF7D000000FF535353535353535353 % FF3A9D3A9D9D3A9D9D9D9D3A3A3A3A9D9D9D9D3A3A9D9D9D3A9D9D9D9D9D % 9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A % 3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 9D9D9D9D3A3A9D9D3A9D9D9D3A3AFF535353535353535353FF9D9D9D9D3A % 3A9D3A3A9D9D9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A9D3A3A3A3A9D % 9D9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D3A9D3A % 9D9D3A9D9D9D9D9D3AFF535353535353535353FF3A9D3A9D3A3A9D3A3A3A % 3A9D3A3A3A9D3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D9D9D3A9D9D9D9D9D3A % 3A9D3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A3A9D3A9D9D % 3A9D3A9DFF535353535353535353FF3A3A9D9D9D3A9D3A9D9D9D9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A % 3A7F1313131313131313137F3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D9D9D3A % 3A3A3A9D3A9D3A9D3A9D3A9D3A9D3A9D9D9D3A9D3A9D9D3A9D3A3A9D3AFF % 535353535353535353FF00210018181018C5181818181718181812101012 % 1012121818181818181818181818181818181A1818181812181818181818 % 1818181800FF18181A18181818181818171818AFAF121818181818121210 % 1210121012161210121012AFAFAFAFAFAFAFAF1613101216181812161210 % 12101012161818101818AF181818FF7D00000000FF53535353535353FF3A % 3A9D3A9D9D3A9D9D9D9D3A3A3A3A9D9D9D9D3A3A9D9D9D3A9D9D9D9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A % 9D3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D % 9D9D9D3A3A9D9D3A9D9D9D3A3A3AFF53535353535353FF3A9D9D9D9D3A3A % 9D3A3A9D9D9D3A3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A9D3A3A3A3A9D9D % 9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D3A9D3A9D % 9D3A9D9D9D9D9D3A9DFF53535353535353FF3A3A9D3A9D3A3A9D3A3A3A3A % 9D3A3A3A9D3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D9D9D3A9D9D9D9D9D3A3A % 9D3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A3A9D3A9D9D3A % 9D3A9D9DFF53535353535353FF3A3A3A9D9D9D3A9D3A9D9D9D9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A % 3A7F131313131313137F3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D9D9D3A3A % 3A3A9D3A9D3A9D3A9D3A9D3A9D3A9D9D9D3A9D3A9D9D3A9D3A3A9D3A3AFF % 53535353535353FF0000210018181612C518181818181816121612101010 % 10121018181818181A18181818181A181818181818181718181818121818 % 18181800FF1818181818181A1818181818AF181818161818161810101010 % 1010101210121816121010AFAFAFAFAFAF10181810121818181018101010 % 101010121810181018AF161818FF7D00000000FF53535353535353FF3A3A % 3A9D3A9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D3A9D9D9D3A9D3A9D9D3A9D9D % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A % 3A3A9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D3A9D9D3A9D9D9D9D3A3A3A3AFF53535353535353FF3A9D9D9D9D3A3A3A % 3A3A9D9D9D9D9D9D9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A9D3A9D9D9D % 9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D % 3A3A9D3A9D9D3A9DFF53535353535353FF9D3A3A9D3A9D9D3A3A3A3A9D3A % 3A9D3A9D3A9D3A9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A3A9D % 3A9D3A3A3A7F131313131313137F3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D3A9D9D9D3A9D3A % 9D9D3AFF53535353535353FF3A9D9D9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A % 7F131313131313137F3A3A9D3A3A3A3A3A9D3A3A3A3A3A9D9D3A3A3A3A3A % 9D9D3A9D3A9D3A3A9D9D9D3A9D3A9D3A9D9D9D9D9D3A9D3A3A3A3A3AFF53 % 535353535353FF0000210018181818C51018181818161210181012101010 % 1010181612181818181A181818181818181A181818181818181818161818 % 161800FF181818181A181818181818181818181818181818181818101012 % 101010101018121810181010101012161818181818161817181818181810 % 1010101012181810AF121818FF7D0000000000FFFF535353FFFF9D3A3A9D % 3A9D9D9D9D9D9D9D3A3A3A9D3A3A9D9D3A3A3A9D9D3A3A9D9D3A9D3A9D9D % 9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F9D3A3A3A3A3A3A % 3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D % 9D9D3A9D9D9D9D9D9D9D3A3A3AFFFF535353FFFF3A3A9D9D9D9D3A3A3A3A % 9D3A9D9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A9D3A9D3A9D3A9D9D % 9D9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A9D % 3A3A9D9D3A9D9D3AFFFF535353FFFF3A3A3A9D3A9D3A9D3A3A3A3A3A9D3A % 3A3A9D3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D3A % 3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A9D9D9D3A9D9D9D9D9D3A % 9D9D9DFFFF535353FFFF9D9D9D3A9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A3A3A % 7F7F1313137F7F3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A9D3A9D3A3A9D9D3A % 3A9D9D9D9D3A3A3A9D9D3A9D3A3A9D9D9D3A9D9D3A9D3A3A9D3A3A3AFFFF % 535353FFFF000000210018181818C5101210121012101218161210101010 % 10101010101216181810181818181A181818181818181818181818181818 % 1800FF1818181A1E181A1818181612101218181818181818101810121010 % 101010101218171818101210101018181818181818181818171818161012 % 10121012101010AF101010FF7D00000000000000FFFFFF3A3A9D3A3A9D3A % 9D9D9D9D9D9D9D3A3A3A9D3A3A9D9D3A3A3A9D9D3A3A9D9D3A9D3A9D9D9D % 9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D7F7F7F3A3A9D3A3A3A3A3A3A3A % 3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D9D % 9D3A9D9D9D9D9D9D9D3A3A3A3A3AFFFFFF9D3A3A3A9D9D9D9D3A3A3A3A9D % 3A9D9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A9D3A9D3A9D3A9D9D9D % 9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A % 3A9D9D3A9D9D3A9D3AFFFFFF9D9D3A3A3A9D3A9D3A9D3A3A3A3A3A9D3A3A % 3A9D3A9D3A9D9D9D3A9D3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D3A3A % 3A3A3A3A9D3A7F7F7F3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 9D9D9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A9D9D9D3A9D9D9D9D9D3A9D % 9D9D9D9DFFFFFF3A9D9D9D9D3A9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A3A3A3A % 3A7F7F7F9D3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A9D3A9D3A3A9D9D3A3A % 9D9D9D9D3A3A3A9D9D3A9D3A3A9D9D9D3A9D9D3A9D3A3A9D3A3A3A3A3AFF % FFFF0000000000210010101012C512161216121810181012101010101010 % 1010101010121810181818181A1E181A1818181612101218181818181818 % 00FF1818181A181A18181812101210101012161218101818181010101010 % 101010121612181818181812181818181818181818181818181818181816 % 121010121012AF101010FF7D00000000000000003AFF3A3A3A3A3A3A9D3A % 9D9D9D9D9D3A3A3A3A9D3A9D9D9D3A3A9D9D9D3A9D9D9D9D3A9D9D9D9D9D % 9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D9D9D9D9D9D9D9D3A3A3A9D9DFF9D9D9D3A3A9D9D9D9D3A3A3A3A3A9D9D % 9D9D9D9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A9D3A9D3A9D9D9D9D9D9D % 9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D9D9D3A9D3A9D9D % 9D9D9D9D3A9D3A9D3A3AFF3A3A3A3A9D3A3A3A9D9D3A3A3A9D3A9D3A9D3A % 3A3A9D3A9D3A9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A % 3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 3A3A9D3A3A9D3A3A3A9D3A3A3A9D3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D3A % 3A9D3AFF3A9D9D9D3A9D9D9D9D9D3A9D3A9D9D3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D9D3A3A3A3A % 3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A9D3A9D3A9D % 3A9D9D3A9D3A9D3A3A9D3A9D9D3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 000000000000210010101010C51012101210101012101210101210100810 % 100F1010101012181818181A181A18181812101210101012161218101800 % FF1818181A18181A18181810101010121012101212161218101010100A10 % 10101012181818181818181818181A181818181818161812181818181818 % 1012101018AF101010FF7D00000000000000003AFF3A3A3A3A3A9D3A9D9D % 9D9D9D3A9D3A3A9D9D3A3A9D9D3A9D3A9D9D9D3A3A3A9D9D3A9D9D3A9D9D % 9D3A3A3A3A3A3A3A3A3A9D3A3A3A7F3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D9D3A % 3A9D9D9D9D9D9D9D3A3A3AFF3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D9D % 9D9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A9D3A3A9D3A3A3A3A3A3A7F3A3A3A9D3A3A9D3A9D3A9D9D9D9D9D3A9D % 9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D3A9D3A9D3A9D9D3A % 9D9D9D3A9D3A9D3A3AFF3A3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D9D % 3A9D3A9D3A9D3A3A9D3A9D3A3A9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A3A3A % 3A3A3A7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D9D9D3A9D9D3A9D9D9D % 3AFF9D9D9D9D3A3A9D9D9D9D9D3A9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A % 3A7F3A3A3A3A3A9D3A3A9D3A3A9D3A3A9D9D3A3A3A3A9D3A9D9D3A9D9D9D % 9D9D3A3A3A9D9D9D3A9D3A9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00 % 0000000000210010101010C51216131810181218161818181010100A100B % 101010101010181818181A18181A181818101010101210121012121600FF % 1818181A181A181818181210121010121010101012101218181010101008 % 10121618181A181A181818181A1818181818181012121816181212181018 % 16101018AF181818FF7D00000000000000003A3AFF3A3A3A3A9D3A9D9D9D % 9D9D3A9D3A3A9D9D3A3A9D9D3A9D3A9D9D9D3A3A3A9D9D3A9D9D3A9D9D9D % 3A3A3A3A3A3A3A3A3A9D3A3A3A7F3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A % 9D9D9D9D9D9D9D3A3A3AFF3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D9D9D % 9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A9D3A3A9D3A3A3A3A3A3A9D7F3A3A9D3A3A9D3A9D3A9D9D9D9D9D3A9D9D % 9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D3A9D3A9D3A9D9D3A9D % 9D9D3A9D3A9D3A3A3AFF3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D9D3A % 9D3A9D3A9D3A3A9D3A9D3A3A9D9D9D9D3A9D9D9D9D9D3A9D3A9D3A3A3A3A % 3A3A7F3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D9D9D3A9D9D3A9D9D9D3A % FF9D9D9D9D3A3A9D9D9D9D9D3A9D9D9D9D3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A % 3A7F3A3A3A3A9D3A3A9D3A3A9D3A3A9D9D3A3A3A3A9D3A9D9D3A9D9D9D9D % 9D3A3A3A9D9D9D3A9D3A9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000 % 00000000210018181010C512161216101316101818181818181010100E10 % 1010101010181818181A181A18181818121012101012101010101200FF10 % 181818181818181818161216121810181018101210101818161010101008 % 1012161818181818181A1818181818181810121010101218101010121012 % 181818AF18181AFF7D00000000000000003A3AFFFFFF3A3A3A9D3A9D9D3A % 3A3A9D9D3A9D9D3A3A3A9D3A3A3A9D9D3A9D3A9D9D3A9D3A3A9D9D9D3A3A % 3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 9D9D9D9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D9D9D3A3A9D % 9D9D9D9D9D9D9DFFFFFF3A9D3A3A3A3A3A3A3A9D3A3A3A9D9D9D9D9D9D9D % 9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A9D3A9D3A9D9D9D9D9D9D9D3A9D % 9D9D9D9D9D9D3A9D3A9D9D3A9D3A9D3A9D9D9D3A9D9D3A9D3A9D9D9D9D3A % 3A9D3A3A3A3A9D3AFFFFFF3A3A3A3A9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A % 9D3A3A3A9D9D9D9D3A9D9D9D3A9D9D9D9D3A9D9D9D3A9D3A3A3A3A3A3A7F % 7F7F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A9D9D9D9D3A9D9D9D9DFFFFFF % 9D9D3A9D3A3A3A3A9D3A3A9D9D9D9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A3A % 7F7F7F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A9D9D3A3A9D3A9D9D9D % 3A9D3A9D9D9D3A3A3A9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000 % 0000002100181A1818C51818121818181218181818181818161210101010 % 101010101210181818181818181818161216121810181018101200FF1012 % 161818181818101210121018181818181312101010101212181810121012 % 101818181818181818181A18181818101210101010121610101210121012 % 1018AF181818FF7D0000000000000000FFFF535353FFFF9D3A3A9D9D9D9D % 9D9D3A9D9D9D3A3A9D9D3A9D3A9D9D3A3A3A3A9D3A3A3A9D3A3A9D9D9D9D % 3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D % 9D9D3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D3A9D3A % 9D3A9D9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A7F7F1313137F7F3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D3A3A9D9D3A3A9D % 3A9D3A9D3AFFFF535353FFFF9D3A9D3A9D9D3A3A3A9D3A3A9D3A9D3A9D3A % 3A9D3A3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D3A9D3A9D3A3A3A3A7F7F1313 % 137F7F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A % 3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D9D9D3AFFFF535353FF % FF9D9D9D9D9D3A3A9D9D9D3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A9D % 3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D3A7F7F13 % 13137F7F3A3A3A3A9D3A3A9D3A9D3A3A3A9D3A9D9D3A9D9D9D3A9D3A9D3A % 3A3A9D9D3A9D3A3A3A9D3A9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A00000000 % 0000210018181818C5101816181018181612101010121818181010101010 % 1010101010121618181818181012101210181818181813121000FF101218 % 161818101010101010101818181818181010101010101618181816101018 % 181818181818181818181818181012101010101010121010101210101210 % 18AF121612FF7D00000000000000FF53535353535353FF3A3A9D9D9D9D9D % 9D3A9D9D9D3A3A9D9D3A9D3A9D9D3A3A3A3A9D3A3A3A9D3A3A9D9D9D9D3A % 3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D % 9D3AFF53535353535353FF3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D3A9D3A9D % 3A9D9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D7F131313131313137F3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D3A3A9D9D3A3A9D3A % 9D3A9DFF53535353535353FF3A9D3A9D9D3A3A3A9D3A3A9D3A9D3A9D3A3A % 9D3A3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D3A9D3A9D3A3A3A7F1313131313 % 13137F3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D9D9DFF53535353535353 % FF9D9D9D9D3A3A9D9D9D3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A % 3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D7F13131313 % 1313137F3A3A3A9D3A3A9D3A9D3A3A3A9D3A9D9D3A9D9D9D3A9D3A9D3A3A % 3A9D9D3A9D3A3A3A9D3A9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A0000000000 % 00210016121818C518181218181810181010101010101218101010121010 % 10101010121816181810101010101010181818181818101000FF10101012 % 101012101010101012181818181818181010080A10101012181818181818 % 181818181218181818171812181010101010101012181810101012161818 % AF181618FF7D00000000000000FF53535353535353FF9D9D9D9D3A9D3A9D % 9D9D3A9D3A3A9D9D3A3A9D9D9D3A3A9D9D3A3A9D3A3A3A3A9D3A3A9D3A3A % 3A9D3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A % 3AFF53535353535353FF3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D9D9D9D9D9D % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A7F131313131313137F3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D3A % 9D9D9D3A9D9D9D9D9D3A3A3A3A9D9D9D9D3A9D3A3A9D9D3A9D9D9D3A3A3A % 9D3AFF53535353535353FF3A9D3A9D3A3A3A3A9D3A3A3A9D3A3A3A9D3A9D % 3A9D3A3A9D3A9D9D9D9D9D9D9D3A9D9D9D3A3A9D3A3A3A7F131313131313 % 137F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D9DFF53535353535353FF % 3A9D3A9D9D9D9D9D9D3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D7F1313131313 % 13137F9D3A3A3A3A3A9D3A3A3A3A3A9D3A9D9D9D3A9D9D3A9D9D3A3A9D3A % 9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000 % 210016181618C51A18181810121818181812101010101018121610101210 % 101010101012101012101010101012181818181818181000FF1210121018 % 101810101010101012161818181A18181010101010101010101018181818 % 1818181618181818181018101210101010101218181818161210121018AF % 181818FF7D000000000000FF535353535353535353FF3A9D9D3A9D9D9D9D % 9D9D9D3A3A9D9D3A3A9D9D9D3A9D3A9D9D9D9D3A3A3A3A9D9D9D9D3A3A3A % 3A3A7F1313131313131313137F3A9D3A3A3A3A9D3A3A9D9D9D3A3A3A9D9D % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9DFF % 535353535353535353FF3A3A3A3A3A9D9D3A9D9D9D3A3A9D3A3A9D3A9D3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F1313131313131313137F3A3A3A9D9D9D9D9D9D9D9D9D3A9D3A9D % 9D3A9D3A9D3A3A3A3A3A3A9D3A3A9D3A9D9D3A9D3A9D9D3A3A9D3A3A3A9D % FF535353535353535353FF3A9D3A9D3A9D3A3A3A3A9D3A3A3A9D3A3A9D3A % 3A3A9D3A9D9D9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A7F1313131313131313 % 137F3A3A3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3AFF535353535353535353FF % 9D9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A9D9D7F13131313131313 % 13137F3A3A3A3A9D9D3A9D3A3A3A9D9D3A3A3A3A9D9D9D3A9D9D3A3A3A9D % 9D9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021 % 0018181818C5181818181816181818181710101210121612101210101818 % 101210121018101810101010101012161818181A181800FF181818181818 % 181810121210121012181818181818181010101010101010101012161818 % 18181818171812161210121010121012181818181818181810121018AF18 % 1818FF7D000000000000FF535353535353535353FF3A9D9D3A9D9D9D9D9D % 9D9D3A3A9D9D3A3A9D9D9D3A9D3A9D9D9D9D3A3A3A3A9D9D9D9D3A3A3A3A % 3A7F1313131313131313137F3A9D3A3A3A3A9D3A3A9D9D9D3A3A3A9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9DFF53 % 5353535353535353FF3A3A3A3A3A9D9D3A9D9D9D3A3A9D3A3A9D3A9D3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A7F1313131313131313137F3A3A3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D % 3A9D3A9D3A3A3A3A3A3A9D3A3A9D3A9D9D3A9D3A9D9D3A3A9D3A3A3A9DFF % 535353535353535353FF3A9D3A9D3A9D3A3A3A3A9D3A3A3A9D3A3A9D3A3A % 3A9D3A9D9D9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A7F131313131313131313 % 7F3A3A3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3AFF535353535353535353FF9D % 9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A9D9D7F1313131313131313 % 137F3A3A3A3A9D9D3A9D3A3A3A9D9D3A3A3A3A9D9D9D3A9D9D3A3A3A9D9D % 9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100 % 18181818C518181818181811181218181818161210181018101818181818 % 18181818181818181012121012101218181818181800FF1A181818181818 % 181818101010101012181818181818101810121010101010101210181218 % 18181818161218101210101010101018181818181A181810101012AF1216 % 12FF7D000000000000FF535353535353535353FF3A9D9D9D9D9D9D3A9D3A % 9D9D3A3A9D3A3A9D9D9D3A9D9D3A9D9D3A9D9D9D3A9D9D3A9D3A3A3A3A3A % 7F1313131313131313137F3A3A3A9D3A3A3A3A3A3A9D9D9D9D9D9D3A3A3A % 3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D3A3A9DFF5353 % 53535353535353FF9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D3A % 3A7F1313131313131313137F3A9D3A3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D % 9D3A9D3A9D9D9D9D9D3A3A9D3A3A9D9D9D3A3A3A3A9D9D3A9D3A9D3AFF53 % 5353535353535353FF3A9D9D3A3A9D3A3A9D3A9D9D3A9D3A9D9D3A9D9D3A % 3A9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D3A7F1313131313131313137F % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A9DFF535353535353535353FF9D3A % 3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D9D9D3A7F131313131313131313 % 7F3A9D3A9D3A3A9D3A3A3A9D3A3A9D3A9D9D9D9D3A9D3A3A3A3A9D9D9D9D % 9D3A9D3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210016 % 121612C512101818181818101012101818181012101210121818181A181A % 181818181818181818101010101012181818181800FF1818181818181818 % 181818121010101210121018101812101216181018121610101210181718 % 181818181810181012101010121818181A181818181818101010AF101010 % FF7D00000000000000FF53535353535353FF3A3A9D9D3A9D9D9D9D9D9D9D % 9D3A9D9D3A3A9D9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A9D9D3A3A3A3A3A3A % 7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D3AFF5353 % 5353535353FF9D9D9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D3A9D9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A7F131313131313137F3A3A3A3A3A9D9D9D9D3A9D9D9D3A9D3A9D3A9D3A % 9D9D3A9D3A3A3A3A3A3A9D3A9D9D3A3A3A9D9D9D3A3A3A3A3A3A9D9DFF53 % 535353535353FF3A9D9D9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A9D % 3A9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D3A3A7F131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF53535353535353FF3A3A3A9D % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A7F131313131313137F3A % 3A3A3A9D9D9D3A9D3A9D9D9D9D3A3A9D9D3A9D3A3A9D3A9D3A9D9D9D9D9D % 3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021001010 % 1010C5101012161818101210101018121210101810121018181818181818 % 1818181818181818181210101012101210181000FF1A1818181818181818 % 1818181812101010101010121010181012181818181A1810121018181818 % 18181818181817181012101216181818181A18181812101010AF101010FF % 7D00000000000000FF53535353535353FF3A3A9D9D3A9D9D9D9D9D9D9D9D % 3A9D9D3A3A9D9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A9D9D3A3A3A3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D3AFF535353 % 53535353FF9D9D9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D3A9D9D3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 7F131313131313137F3A3A3A3A3A9D9D9D9D3A9D9D9D3A9D3A9D3A9D3A9D % 9D3A9D3A3A3A3A3A3A9D3A9D9D3A3A3A9D9D9D3A3A3A3A3A3A9D9DFF5353 % 5353535353FF3A9D9D9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A9D3A % 9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A9D3A3A7F131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF53535353535353FF3A3A3A9D3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A7F131313131313137F3A3A % 3A3A9D9D9D3A9D3A9D9D9D9D3A3A9D9D3A9D3A3A9D3A9D3A9D9D9D9D9D3A % 3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100101010 % 10C5101010121816181810121012101010101210181018161818181A1818 % 18181818181818181818121010101010101200FF18181818181012101817 % 181818181810121010121010121012161818181818181818101818181818 % 18181818181818181816181818181A181818181618181810AF101010FF7D % 0000000000000000FFFF535353FFFF9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D % 3A9D9D3A9D9D3A3A9D9D9D3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D7F % 7F1313137F7F3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D3AFFFF5353 % 53FFFF3A3A9D3A9D3A3A9D9D3A9D9D9D9D3A9D3A9D3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 7F7F1313137F7F3A3A3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D % 3A9D3A9D3A9D3A3A3A3A3A9D9D3A9D3A3A9D3A9D9D9D3A9D3A9D3AFFFF53 % 5353FFFF3A9D9D9D3A9D3A3A9D9D9D9D9D3A9D9D9D3A3A9D3A3A3A3A9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A3A3A3A7F7F1313137F7F3A3A3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3AFFFF535353FFFF3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F7F1313137F7F3A3A3A3A % 3A9D3A9D3A3A3A9D3A3A3A3A9D9D9D3A9D3A9D3A3A3A3A9D9D9D9D9D3A3A % 3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010101010 % C51010101010121818181818181612161216121012101218181818181818 % 181012101817181818181810121010121000FF1818111210101010121818 % 181818181818181210101210101210121810121618181818181818181A18 % 18181818181818181818181818181A1818181818181810AF101210FF7D00 % 000000000000003A3AFFFFFF3A3A3A3A3A9D9D9D9D9D3A9D9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A9D3A3A9D9D3A % 7F7F7F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3AFFFFFF % 3A3A3A9D9D3A3A9D3A9D9D9D9D3A9D3A3A9D9D9D9D3A3A3A9D3A3A3A3A3A % 9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A7F7F7F3A3A3A3A3A3A9D3A3A9D9D9D9D9D9D9D3A9D3A3A9D9D3A3A3A3A % 9D3A9D3A3A3A9D3A9D3A3A3A9D3A3A9D3A9D9D3A9D9D3A3A9D9D9D9DFFFF % FF9D9D3A9D9D3A9D3A3A9D3A9D9D9D9D9D9D3A9D3A3A3A3A3A9D9D9D9D9D % 9D9D3A9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3AFFFFFFFF9D3A3A9D3A3A9D3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F7F3A3A3A3A3A9D % 3A9D3A3A9D9D9D9D3A3A9D9D9D9D9D3A3A3A9D3A3A3A9D9D3A9D9D3A3A3A % 9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210012101012C5 % 101010101018181820191818181818181818101010121012181818111210 % 1010101218181818181818181812101000FF181818161812181612101212 % 181818181018101813181818181612161818181818181818181A18181818 % 1A181818181210131618181818181818181210121012AF121618FF7D0000 % 0000000000003A3A3A3AFF3A3A3A3A3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D % 9D3A9D9D9D9D9D3A3A3A3A9D3A3A3A3A3A3A9D9D3A3A3A9D3A3A9D9D3A7F % 3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3AFF9D9D3A % 3A3A9D9D3A3A9D3A9D9D9D9D3A9D3A3A9D9D9D9D3A3A3A9D3A3A3A3A3A9D % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A7F3A3A3A3A3A3A9D3A3A9D9D9D9D9D9D9D3A9D3A3A9D9D3A3A3A3A9D % 3A9D3A3A3A9D3A9D3A3A3A9D3A3A9D3A9D9D3A9D9D3A3A9D9D9D9D3A3AFF % 9D9D3A9D9D3A9D3A3A9D3A9D9D9D9D9D9D3A9D3A3A3A3A3A9D9D9D9D9D9D % 9D3A9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A9D3A3A3AFF3A3A3A9D3A3A9D3A3A9D3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A9D3A % 9D3A3A9D9D9D9D3A3A9D9D9D9D9D3A3A3A9D3A3A3A9D9D3A9D9D3A3A3A9D % 9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210016181818C510 % 101010101018181818181818181810181818181012101018181818161812 % 18161210121218181818101810181300FF10181018101818181818101618 % 181818181818181816181212101210121818181818181818181818181818 % 181A18181618181818181818181818181610101210AF121018FF7D000000 % 00000000003A3A3A3A3AFF3A3A9D9D9D9D9D3A9D3A3A9D3A9D9D9D3A9D9D % 9D3A9D3A3A9D3A9D3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A9D3A7F3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D9D9D3A9DFF3A9D9D9D9D % 9D3A9D3A9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A7F3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D3A % 9D3A9D3A9D3A3A9D9D9D3A9D3A3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9DFF % 9D9D9D9D3A9D3A3A9D9D9D3A9D9D3A9D9D3A9D3A9D3A3A3A9D9D9D9D9D9D % 9D9D9D9D9D9D3A3A9D3A9D3A3A3A3A3A7F3A3A9D9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A9D3A3A9D3A3A3A3AFF3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A % 3A9D3A9D9D3A9D3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A9D3A9D3A % 9D9D9D9D3A3A9D9D3A9D9D9D9D9D3A9D3A3A3A9D9D9D9D9D9D3A9D3A3A9D % 9D9D9D3A9D3A3A3A3A3A9D3A3A3A3A000000000000210010181018C51012 % 101010121012101217181818101818181810121010101810181018101818 % 181818101618181818181818181800FF1012121212101018181818181210 % 121018121612161210101010101010101018181818181818181818181A18 % 1818181818181818181818181818181818131010AF101210FF7D00000000 % 000000003A3A3A3A9DFFFFFF9D3A9D9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D % 9D9D9D3A3A9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A7F7F7F3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D9D3A9DFFFFFF9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D3A9D3A9D9D3A9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A7F7F7F3A3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A9D3A9D9D % 3A3A3A9D3A9D9D3A3A3A3A9D3A3A9D9D3A9D3A9D3A9D3A9D3A3A3A9DFFFF % FF9D9D9D3A3A3A9D9D3A9D3A3A3A3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D3A3A3A9D9D3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A9D3A3AFFFFFFFF3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F7F7F7F9D9D9D9D9D9D % 9D9D9D3A9D9D3A9D3A9D9D9D9D9D3A9D3A3A3A9D9D9D9D3A9D3A3A3A9D9D % 9D9D3A9D3A3A9D3A3A3A3A3A3A3A000000000000210012101218C5101010 % 101010101012181812181618101210121010101010121012121212101018 % 1818181812101210181216121600FF121010101010121810181818161010 % 12101010121012161210101010101010101210161818181818181A182018 % 1A181818181818181818181818181818161810AF101010FF7D0000000000 % 0000003A3A3AFFFF535353FFFF9D9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D9D % 9D9D3A3A9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A7F7F1313137F7F3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D9D9DFFFF535353FFFF9D9D9D9D9D % 9D9D9D9D9D9D3A9D3A9D3A9D9D3A9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F % 1313137F7F3A3A9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A9D3A9D9D3A % 3A3A9D3A9D9D3A3A3A3A9D3A3A9D9D3A9D3A9D3A9D3A9D3A3AFFFF535353 % FFFF9D3A3A3A9D9D3A9D3A3A3A3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D3A3A3A9D9D3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A9DFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A7F7F1313137F7F9D9D9D9D9D % 9D9D3A9D9D3A9D3A9D9D9D9D9D3A9D3A3A3A9D9D9D9D3A9D3A3A3A9D9D9D % 9D3A9D3A3A9D3A3A3A3A3A3A3A000000000000210010101210C512121012 % 101012101012101817121210181618101210101010121010101010121810 % 18181816101012101010121000FF10101012101210101218181810121012 % 161218121612101010101008100E1010101012121618181818181A181818 % 181818181818181818181818181818181810AF101010FF7D000000000000 % 00003A3AFF53535353535353FF9D9D9D9D3A9D3A3A9D9D9D3A9D3A9D9D9D % 3A3A3A9D3A9D9D9D3A9D9D9D9D3A3A9D3A3A3A7F131313131313137F3A3A % 3A3A3A3A3A9D3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A9D3A3A3A3A3A3A3A9D3AFF53535353535353FF9D9D3A3A9D % 9D9D3A3A3A9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D7F131313 % 131313137F3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A9D3A9D % 3A9D9D3A9D3A9D9D3A3A3A9D9D3A9D3A9D9D9D9D9D9D3AFF535353535353 % 53FF3A9D3A9D9D9D3A3A9D9D9D9D9D9D3A3A3A9D9D9D3A9D9D9D9D9D9D9D % 9D9D3A3A9D3A9D3A7F131313131313137F3A3A9D3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A % 9D9D3A9D3AFF53535353535353FF3A9D3A9D3A9D9D9D9D9D3A9D9D9D9D9D % 9D9D3A9D9D9D9D3A9D9D3A9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F9D9D9D9D9D % 9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A9D9D9D3A9D9D9D3A3A3A9D9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010101012C51817181612 % 101010121618181818101618181816181618181010101012101210101218 % 181810121012161218121600FF1012101010101010101012181818181012 % 1010101012101210101010101010101010101012181818181A18181A1818 % 1818181718181216181818181816181810AF101008FF7D00000000000000 % 003A3AFF53535353535353FF9D9D3A9D9D9D9D3A9D9D3A3A3A9D3A9D3A3A % 3A9D3A9D3A3A3A3A9D3A9D9D3A9D3A3A3A3A7F131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3AFF53535353535353FF9D9D3A3A9D9D % 9D3A3A9D3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A7F13131313 % 1313137F3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D9D3A3A3A % 9D3A9D3A9D3A9D3A9D3A9D3A9D9D9D9D3A9D3A9D3A9DFF53535353535353 % FF3A3A3A3A9D9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D3A9D9D3A9D3A7F131313131313137F3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A % 3A3A9D3AFF53535353535353FF3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A7F131313131313137F9D9D9D9D3A9D % 9D3A3A9D9D3A3A3A9D9D9D3A3A3A9D9D3A9D3A9D9D3A9D3A9D9D9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A000000000000210010081010C5181818181818 % 181613181818181818121818181818181818101012101010101010101012 % 1818181810121010101000FF121010121012101210121010121612161216 % 121813181718101210101010101010101010101816181818181A18181818 % 18181210121012181217181818121810AF100810FF7D0000000000000000 % 3AFF535353535353535353FF9D3A9D9D9D9D3A9D9D3A3A3A9D3A9D3A3A3A % 9D3A9D3A3A3A3A9D3A9D9D3A9D3A3A3A7F1313131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353535353535353FF9D3A3A9D9D9D % 3A3A9D3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F131313131313 % 1313137F9D9D3A9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D9D3A3A3A9D % 3A9D3A9D3A9D3A9D3A9D3A9D9D9D9D3A9D3A9D3AFF535353535353535353 % FF3A3A3A9D9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 3A9D9D3A9D7F1313131313131313137F3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A9DFF535353535353535353FF3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F9D9D9D3A9D9D % 3A3A9D9D3A3A3A9D9D9D3A3A3A9D9D3A9D3A9D9D3A9D3A9D9D9D9D9D3A9D % 3A3A3A3A3A3A3A3A3A3A000000000000210008101010C51818181A18181A % 181818181A18181818181818181818181810121010121012101210121010 % 12161216121612181300FF10101210101210181210121010121018181818 % 1816181818181610101010100A0E10101212181218181818181818181818 % 101012101010121618121612181610AF10080AFF7D00000000000000003A % FF535353535353535353FF9D9D3A9D9D9D3A3A9D3A9D9D9D9D3A3A3A3A3A % 3A9D9D9D3A9D9D9D3A3A9D9D9D3A9D7F1313131313131313137F9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF9D9D3A9D9D9D9D % 9D9D9D9D3A9D9D9D9D3A3A9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 13137F3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A3A9D9D9D9D % 9D3A9D3A9D3A9D3A3A9D9D9D3A3A9D9D3A9D3AFF535353535353535353FF % 9D3A9D3A3A9D9D9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A % 9D3A9D3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3AFF535353535353535353FF3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A7F1313131313131313137F9D9D9D9D3A3A9D % 9D9D9D9D9D3A3A3A3A9D3A9D9D9D9D9D9D3A9D9D9D3A3A9D9D9D9D3A9D3A % 3A9D3A3A3A3A3A3A3A0000000000002100080A1010C51818181820181818 % 181818181818181812101210181216181010101210101210181210121010 % 121018181818181600FF12181018181818181A1818181810101818161216 % 121012101218181818121010101010101010101818181818181818101018 % 1218161216121012101210101218AF101010FF7D00000000000000003AFF % 535353535353535353FF9D3A9D3A9D3A3A9D3A3A9D9D3A3A3A9D9D3A9D3A % 3A3A3A9D3A3A9D9D9D3A9D9D9D3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF9D3A9D9D3A9D3A3A % 9D9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313 % 137F3A3A9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D3A9D3A9D3A9D % 9D9D3A9D9D3A3A3A9D3A3A9D9D3A3A9D9D3AFF535353535353535353FF3A % 3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A % 3A9D3A7F1313131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F1313131313131313137F9D3A3A3A3A9D3A9D % 3A9D3A3A9D9D3A3A9D9D9D9D9D3A3A9D9D3A9D3A3A9D9D9D3A9D3A9D3A3A % 3A3A3A3A3A3A3A3A000000000000210010101010C51816181A181A181A18 % 181A181A1816121010C5C5C5C51210181218C5C5181818181AC5C5C5C510 % 1018181612161200FF101012101818181818181A18181218181818181812 % 101810101218181010101010101010101210121618181818161210121018 % 10181818181018101210121012AF121010FF7D00000000000000003A3AFF % 53535353535353FF3A9D3A9D3A9D3A3A9D3A3A9D9D3A3A3A9D9D3A9D3A3A % 3A3A9D3A3A9D9D9D3A9D9D9D3A3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF9D9D3A9D9D3A9D3A3A9D % 9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 3A3A3A9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D3A9D3A9D3A9D9D % 9D3A9D9D3A3A3A9D3A3A9D9D3A3A9D9D3A9DFF53535353535353FF9D3A3A % 3A3A9D3A3A3A3A3A3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A3A % 9D3A3A7F131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F9D9D3A3A3A3A9D3A9D3A % 9D3A3A9D9D3A3A9D9D9D9D9D3A3A9D9D3A9D3A3A9D9D9D3A9D3A9D3A3A3A % 3A3A3A3A3A3A3A000000000000210010101010C518181818181A18181A18 % 1A181818181210C5C51210C5C518121010C5C518181818C5C51A18C5C518 % 18181818181200FF10121010121012181818181818181818181818181718 % 131010101010121010101010101010101210101212121012101010121012 % 181818181818101210101010AF121818FF7D00000000000000003A3AFF53 % 535353535353FF9D9D9D9D9D9D9D3A9D3A9D9D9D3A3A9D9D3A3A3A9D9D9D % 9D9D3A9D3A9D9D9D3A9D9D9D3A7F131313131313137F3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3AFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A7F131313131313137F3A % 9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D3A9D9D9D3A9D % 9D9D3A3A3A9D3A9D9D3A9D3A9D3A3A3A3AFF53535353535353FF3A3A3A3A % 3A3A3A9D3A3A9D3A9D3A3A3A9D9D9D9D3A9D9D9D3A9D9D9D9D3A9D3A3A9D % 9D3A7F131313131313137F3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF % 53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A7F131313131313137F9D9D3A3A9D9D9D9D3A9D3A % 9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A000000000000210018181813C5181818181A181818181818 % 181818181010C5C51010C5C510101012101012101218C5C51818C5C51818 % 181818181700FF1810101210101818181818181818181818181818181816 % 101012101010101010101010101210101210121010121010101010101216 % 1818181818181010101010AF101018FF7D00000000000000003A3A3AFFFF % 535353FFFF9D9D9D3A9D9D3A9D3A9D3A9D3A3A9D3A9D3A3A9D9D3A9D9D9D % 9D3A9D3A9D3A9D9D9D9D3A9D9D7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3AFFFF535353FFFF3A3A3A9D9D3A3A3A9D9D3A3A3A % 9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A7F7F1313137F7F3A3A3A % 9D3A9D3A3A9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A3A9D3A9D3A9D3A9D % 3A9D9D9D3A9D3A9D9D3A9D3A3A9D3A3A3AFFFF535353FFFF9D3A3A3A9D3A % 3A9D3A3A9D3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A % 3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A9D3A9D9D3A9D9D9D9D3A3A3A9D3A9D9D3A9D3A3AFF % FF535353FFFF9D3A3A9D9D3A3A3A9D9D3A9D9D3A9D9D9D9D3A9D3A9D3A3A % 9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F9D3A3A9D9D9D9D9D9D9D3A3A9D % 9D3A9D9D9D9D3A3A9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A3A9D3A3A % 9D3A3A3A3A000000000000210010181816C5C5C5C5C5C5C5C5C5C5C5C5C5 % 1818101010C5C51010C5C510181810101210101818C5C51818C5C5181818 % 1818181800FF181818101612181018181818181818181818181818181818 % 181010121018181010101210101012101010101210101210101010101218 % 18181818181012101010AF0A1010FF7D00000000000000003A3A3A3A3AFF % FFFF3A9D9D9D9D3A9D9D3A9D3A9D3A9D3A3A9D3A9D3A3A9D9D3A9D9D9D9D % 3A9D3A9D3A9D9D9D9D3A9D9D3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3AFFFFFF3A9D3A3A3A9D9D3A3A3A9D9D3A3A3A9D % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A7F7F7F3A3A3A3A3A9D % 3A9D3A3A9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A3A9D3A9D3A9D3A9D3A % 9D9D9D3A9D3A9D9D3A9D3A3A9D3A3A3A9D3AFFFFFF3A3A9D3A3A3A9D3A3A % 9D3A3A9D3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A3A % 3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A9D3A9D9D3A9D9D9D9D3A3A3A9D3A9D9D3A9D3A3A9D9D % FFFFFF9D3A9D3A3A9D9D3A3A3A9D9D3A9D9D3A9D9D9D9D3A9D3A9D3A3A9D % 3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A9D9D3A3A9D9D9D9D9D9D9D3A3A9D9D % 3A9D9D9D9D3A3A9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A3A9D3A3A9D % 3A3A3A3A000000000000210010101012C518181818181818181718181818 % 12101210C5C51210C5C518181818181016121810C5C5C5C5C51818181818 % 18181800FF1A181812121210181012121018181818181818181216181818 % 101210181818101018101818181816121012101012161010101010121818 % 181818181012101010AF100810FF7D00000000000000003A3A3A3A3A3A3A % FF9D3A9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D3A9D3A9D9D9D9D9D9D3A9D3A % 9D9D9D9D9D3A3A9D9D9D9D9D7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A9D3A3AFF3A3A3A3A3A3A3A9D9D3A3A9D9D3A3A3A3A3A3A % 9D3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A7F3A3A3A3A3A9D3A % 9D3A3A9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A9D3A9D9D9D3A % 9D3A9D3A9D3A9D9D3A3A9D3A9D3A3A3A3A9D3A3AFF3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D3A9D3A3A3A3A % 3A3A7F3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A9D3A3A3A3A9D3A9D3A3A3A9D9D3A3A3A3A3A9D3A9D3AFF % 3A9D3A9D9D3A3A9D9D3A3A3A3A9D9D3A9D3A9D3A9D9D3A3A3A3A9D3A9D3A % 9D9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A9D % 3A3A9D3A3A9D3A3A3A3A3A3A7F3A3A9D3A3A9D9D9D9D3A9D9D3A9D9D9D9D % 9D3A9D9D9D3A3A9D9D9D9D3A9D3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A000000000000210008101010C51818171818181818181818181612 % 101010C5C51012C5C518181A18181212121018C5C5121018181818181818 % 181200FF1818121010101012101010121012181818171818161812181012 % 1210121218181818181818181A1818181010181818101210101010101818 % 1818181612171210AF101010FF7D00000000000000003A3A3A9D3A3A3AFF % 3A9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D % 9D9D9D9D9D9D3A9D9D9D9D7F9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A9D3A3A3A3A9D3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A3A3A3A3A9D % 9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A3A9D3A9D9D3A9D9D9D3A9D3A9D % 3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A9D3A3A9DFF3A3A9D3A9D3A3A9D3A3A % 3A9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D3A3A3A3A % 7F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D9D3A9D3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A9D9D3A3AFF9D3A % 9D3A3A3A3A3A3A9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A9D9D3A9D3A9D % 3A3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A7F9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D % 9D9D9D3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A000000000000210010101010C5101218181818181818111813181010 % 1010C5C51218C5C5181A181812101010101210C5C5121012181818171818 % 1600FF181810101010101210101010101216181818181012101210101010 % 101010101818181818181818181818181818181818101010101012181818 % 18181818181810AF181210FF7D00000000000000003A3A3A9D3A3A3A9DFF % 9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D9D % 9D9D9D9D9D3A9D9D9D9D7F9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D3A3A3A9D3A3A3A3A9D3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D7F3A3A3A3A3A3A9D9D % 3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A3A9D3A9D9D3A9D9D9D3A9D3A9D3A % 3A3A9D3A9D3A3A9D3A3A3A3A3A3A9D3A3A9DFF3A3A9D3A9D3A3A9D3A3A3A % 9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D3A3A3A3A7F % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A9D3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A9D9D3A3AFF9D3A9D % 3A3A3A3A3A3A9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A9D9D3A9D3A9D3A % 3A3A9D3A3A3A9D3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D7F9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D % 9D9D3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A % 3A000000000000210012101010C510101818181818181818181810121010 % 1010C5C5C5C5181A1818181010101010121010C5C5C5C516181818181012 % 00FF1818181010080810101010100B0E0A10101618181818181810181316 % 121612161210121618181818181818161218101818181818161010101012 % 101010121010AF121818FF7D00000000000000003A3A3A3A3A3A3A3AFFFF % FF3A9D3A9D3A9D3A9D9D9D3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D3A9D9D % 9D3A9D9D9D3A7F7F7F9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A9D3A % 9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D3A9D3A9D9D3A3A9D9D9D9D3A3A3A % 9D3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A9DFFFFFF3A3A3A3A3A9D3A9D3A % 3A3A9D3A3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D3A3A9D3A9D3A3A7F7F7F3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D9D3A3A3A3A9D9D3A3A9D9D3A3A3A9D3A3A9D3A3A3AFFFFFF3A3A9D3A % 3A3A3A9D3A9D3A9D3A3A9D9D3A9D9D3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D7F7F7F9D9D9D9D9D3A9D3A9D3A9D3A9D9D9D9D9D % 9D3A9D3A3A9D9D9D9D3A9D9D3A9D9D9D3A9D3A9D3A3A3A9D3A3A3A3A3A3A % 000000000000210018181618C51010181618181A18181813101018101810 % 12181818181A18181818181010080810101010100B0E0A10101618181800 % FF1818181612101010101010101010101010121818181818161018101612 % 171218101210121818181818181818101810181818181818181810121010 % 1210101010AF161818FF7D00000000000000003A3A3A3A3A3AFFFF535353 % FFFF9D9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A9D % 9D9D9D7F7F1313137F7F9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 9DFFFF535353FFFF3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A7F7F1313137F7F3A9D3A9D9D3A % 3A9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A3A9D3A3A9D9D3A9D3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A9D3A3A9D3A3A3AFFFF535353FFFF9D3A9D3A9D3A3A9D % 9D3A3A9D9D9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D3A3A3A7F7F1313137F7F % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A % 9D3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A9D3AFFFF535353FFFF3A9D3A % 9D3A9D3A9D3A3A3A9D3A3A9D3A9D9D9D3A3A3A3A3A3A9D3A3A3A9D3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 9D3A3A3A3A3A3A7F7F1313137F7F9D9D9D9D3A9D9D3A9D9D3A9D3A9D9D9D % 9D9D9D3A3A9D9D3A9D9D3A9D9D3A9D9D9D3A9D3A3A3A3A3A9D3A3A3A3A00 % 0000000000210018181818C5181818181818181818181810121012181612 % 16181818181A1818181816121010101010101010101010101218181800FF % 181618181818181012101010101010101010121618181818121812181218 % 121012101210121018181816181810181210121018181818181210101210 % 12101210AF121818FF7D00000000000000003A3A3A3A3AFF535353535353 % 53FF9D9D3A9D3A3A3A3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A9D9D % 9D7F131313131313137F3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFF % 53535353535353FF3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A7F131313131313137F9D3A9D9D3A3A % 9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A3A9D3A3A9D9D3A9D3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A9D3A3A9D3A3AFF53535353535353FF3A9D3A9D3A3A9D9D % 3A3A9D9D9D9D9D9D3A9D9D9D9D9D3A9D9D3A9D3A3A7F131313131313137F % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D % 3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A9DFF53535353535353FF9D3A9D % 3A9D3A9D3A3A3A9D3A3A9D3A9D9D9D3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D % 3A3A3A3A3A7F131313131313137F9D9D9D3A9D9D3A9D9D3A9D3A9D9D9D9D % 9D9D3A3A9D9D3A9D9D3A9D9D3A9D9D9D3A9D3A3A3A3A3A9D3A3A3A3A0000 % 00000000210018181818C518181818181818181818181813161810121818 % 1818181A181818161818181818101210101010101010101012161800FF18 % 12121618181812161210101010100A0F1010121818181618171816181618 % 101210101010121018181812161218101010181818181818121612AFAFAF % AFAFAFAF101216FF7D00000000000000003A3A3A3A3AFF53535353535353 % FF9D9D9D9D3A9D3A3A3A3A9D3A9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D3A9D % 7F131313131313137F9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53 % 535353535353FF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A9D3A9D3A3A9D % 9D9D9D9D9D9D9D9D9D3A9D9D3A3A9D3A9D3A9D3A9D3A3A9D3A3A3A3A3A9D % 9D3A9D3A9D3A3A3A9D3A3A9DFF53535353535353FF3A3A3A3A3A3A3A3A9D % 3A3A9D9D9D9D9D9D9D9D9D9D3A3A9D9D3A9D3A9D7F131313131313137F3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D3A % 9D3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3AFF53535353535353FF3A3A9D3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A9D3A3A3A3A9D9D3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A7F131313131313137F9D9D3A9D9D3A9D9D3A9D9D9D9D3A9D3A9D % 3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000 % 000000210012161818C518181A1818181A18181818181818181818161818 % 18181818181812121618181812161210101010100A0F1010121800FF1810 % 101012101216121810121010121010101010121618181818181818181810 % 101010121010101210121612181018101818181818181816121810181018 % 1210AF101212FF7D00000000000000003A3A3A3AFF535353535353535353 % FF9D9D3A3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D3A9D9D3A3A9D3A9D9D7F13 % 13131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353 % 535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A7F1313131313131313137F3A3A9D9D3A3A9D % 9D9D9D9D9D9D3A9D9D3A3A3A3A9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A9D3A % 9D3A3A3A3A9D3A3A3A9DFF535353535353535353FF3A3A9D3A9D3A9D3A3A % 9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D9D7F1313131313131313137F3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353535353535353FF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A7F1313131313131313137F9D9D9D3A9D3A9D3A9D9D3A9D9D9D3A9D9D % 9D3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A3A9D3A3A3A3A3A3A00000000 % 0000210012121818C518181818181818181A181818181818181818181818 % 1818181818101010121012161218101210101210101010101200FF181612 % 101010101210121612101216101010101210121818181818181818181612 % 101010101210121012101216121818181818181612101210121012101210 % 10AF101010FF7D00000000000000003A3A3A3AFF535353535353535353FF % 9D9D3A3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D3A9D9D3A3A9D3A9D9D7F1313 % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF53535353 % 5353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A7F1313131313131313137F3A3A9D9D3A3A9D9D % 9D9D9D9D9D3A9D9D3A3A3A3A9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A9D3A9D % 3A3A3A3A9D3A3A3A9DFF535353535353535353FF3A3A9D3A9D3A9D3A3A9D % 9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D9D7F1313131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A7F1313131313131313137F9D9D9D3A9D3A9D3A9D9D3A9D9D9D3A9D9D9D % 3A9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A3A3A9D3A3A3A3A3A3A0000000000 % 00210010101218C518181818181818181818181A18181818181818181818 % 18181818161210101010121012161210121610101010121000FF18181816 % 101010101012101210181216121010101012161818181818181818121810 % 101010101010121012101810181818181818181210101210121012101210 % AF100F10FF7D00000000000000003A3A3A3AFF535353535353535353FF3A % 9D9D3A3A3A3A9D9D3A9D9D3A9D3A9D9D9D9D9D3A3A9D9D9D9D3A7F131313 % 1313131313137F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9DFF5353535353 % 53535353FF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A7F1313131313131313137F3A3A3A9D9D3A9D9D9D % 9D9D9D9D9D9D3A3A9D3A3A3A9D9D9D3A9D3A3A9D9D9D3A3A3A3A9D3A9D3A % 9D3A9D3A3A3A3A3AFF535353535353535353FF3A9D3A3A3A3A3A3A9D9D9D % 9D9D9D9D9D9D9D9D9D3A9D3A3A9D3A9D7F1313131313131313137F3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 7F1313131313131313137F9D9D9D9D9D3A3A9D9D9D9D9D9D9D3A9D3A9D3A % 3A9D9D9D9D9D3A9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000 % 21000F101010C5101818181818181A18181A181A18181818181818181818 % 181818181816101010101012101210181216121010101000FF1818181818 % 121010101010101818181810101010101012181818181818181818181012 % 1010101210101010121018181018181818181816121010101210101010AF % 100A10FF7D00000000000000003A3A3A3A3AFF53535353535353FF9D9D9D % 9D3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D9D9D3A9D3A9D9D9D9D7F131313 % 131313137F9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF5353535353 % 5353FF3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A7F131313131313137F9D3A9D3A9D9D3A3A9D9D9D % 9D9D9D9D3A9D3A9D9D3A3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A3A9D3A3A3A % 3A3A3A3A3A9D3A3AFF53535353535353FF3A3A3A3A9D3A9D3A3A9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D3A9D3A3A9D3A7F131313131313137F3A3A3A3A3A % 3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A % 7F131313131313137F9D9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D9D3A3A9D % 9D9D9D3A9D9D3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021 % 000A101010C510121018181818181A181A18201818181818181818181818 % 1818181818181210101010101018181818101010101000FF181818181010 % 1010101012181816181818181818181818181A1818181810101816181818 % 18121610121012101810121010101818181012101012101010121010AF10 % 0A08FF7D00000000000000003A3A3A3A3AFF53535353535353FF9D9D9D9D % 3A3A9D3A9D9D9D9D3A3A9D9D3A9D9D9D9D9D3A9D3A9D9D9D9D7F13131313 % 1313137F9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF535353535353 % 53FF3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A7F131313131313137F9D3A9D3A9D9D3A3A9D9D9D9D % 9D9D9D3A9D3A9D9D3A3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A % 3A3A3A3A9D3A3AFF53535353535353FF3A3A3A3A9D3A9D3A3A9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D3A9D3A3A9D3A7F131313131313137F3A3A3A3A3A3A % 9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A7F % 131313131313137F9D9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D9D3A3A9D9D % 9D9D3A9D9D3A3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100 % 0A081010C510101012161818181818181A18181818101012101810181618 % 18181818101010101010121818161818181818181800FF16181818101012 % 081010101012181818181818181818181A181A1818161212181818181818 % 161210121010121216181010121010101212161218101210101012AF1010 % 10FF7D00000000000000003A3A3A3A3A3AFFFF535353FFFF9D9D9D9D9D3A % 3A3A9D9D9D9D3A9D9D3A3A9D3A9D3A9D9D3A9D9D9D9D3A9D3A7F7F131313 % 7F7F9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D3A9D3A9D9D3A3A9D9D9D9D % 9D9D9D3A9D9D3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D % 3A3A3A3A9D3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D % 9D9D9D9D3A3A3A9D3A9D3A9D3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D7F % 7F1313137F7F3A9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D3A9D % 9D9D9D3A9D9D9D9D9D3A9D3A3A9D3A3A9D3A3A3A3A000000000000210010 % 101010C5101010101218181818181A181818181810121012101210121216 % 181818101012081010101012181818181818181800FF121018121612100E % 0A081010101818181A18181A181818181818181812101018181818181818 % 1810101813181618181210101010101010181816181810181216AF101010 % FF7D00000000000000003A3A3A3A3A3A3A9DFFFFFF9D3A3A9D3A9D3A3A3A % 9D9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A9D7F7F7F9D % 3A9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A9D3A3A9D3A9D9D3A3A9D9D9D9D9D % 3A9D3A9D3A9D3A3A3A3A3A9D3A9D3A3A3A9D3A3A3A9D3A9D9D3A3A3A3A3A % 3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A9D3A3A9D3A3A9D9D9D9D3A9D9D9D9D % 9D9D9D3A3A9D3A9D9D3A9D3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 7F7F7F3A9D3A9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D3A9D9D3A3A9D3A3A9D % 9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021001010 % 1010C5100E1010121018181818181A181818181012161210181012101210 % 18121612100E0A081010101818181A18181A1800FF101210181818181010 % 100A1010181818181818181818181A181818181010121012101818181810 % 18121816181818181618101010101012181818181618121618AF121010FF % 7D00000000000000003A3A3A3A3A3A3A9D3A9DFF9D3A3A9D3A9D3A3A3A9D % 9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A9D7F9D9D9D3A % 9D9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F3A3A3A9D3A3A9D3A9D9D3A3A9D9D9D9D9D3A % 9D3A9D3A9D3A3A3A3A3A9D3A9D3A3A3A9D3A3A3A9D3A9D9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3AFF3A3A3A3A9D3A3A9D3A3A9D9D9D9D3A9D9D9D9D9D % 9D9D3A3A9D3A9D9D3A9D3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D % 3A7F3A9D3A9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D3A9D9D3A3A9D3A3A9D9D % 9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100101010 % 10C510101010101212101818181818181818181810181112101610101210 % 181818181010100A1010181818181818181800FF10101010121018181810 % 10101218181818181818181818181A181818101210101010121012101018 % 101818181818181818181818181010181218101212101218AF101810FF7D % 00000000000000003A3A3A3A3A3A3A3A9D3A9DFF9D9D9D9D9D3A3A3A9D9D % 9D3A9D9D9D9D3A3A3A9D9D3A9D3A9D9D9D9D9D9D9D3A9D7F3A9D9D9D9D3A % 9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFF3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A7F3A3A9D9D3A3A3A3A9D9D3A3A9D9D9D9D9D9D % 9D9D3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A9D3A3A3A3A9D3A3AFF3A9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D9D % 3A3A9D3A3A9D3A9D3A3A3A3A3A7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A9D9D3A % 3A3A3A3A9D9D9D9D9D9DFF3A3A9D3A9D9D3A9D3A3A3A3A3A3A9D3A3A3A3A % 9D3A9D3A9D3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D3A3A9D % 9D7F9D3A9D3A9D9D3A9D9D9D9D3A9D9D3A9D3A9D3A9D9D3A3A3A3A3A3A9D % 9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018101210 % C51010101010101012181818181818181018101812181018121010101010 % 121018181810101012181818181818181800FF1012101010101218181810 % 121618181818181818181818181818181012101010101010101210121210 % 1810181818181818181A18181812161216121010101012AF181012FF7D00 % 000000000000003A9D3A3A3A3A3A9D3A9D9DFFFFFF9D3A9D3A3A9D9D9D9D % 9D9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F7F7F9D9D3A9D9D3A9D % 3A9D9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A9D3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A7F7F7F3A9D3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D % 3A9D3A9D3A9D3A9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A % 3A3A9D9D3A3A3A3AFFFFFF3A9D3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A % 3A9D3A3A9D3A9D9D3A3A7F7F7F3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A9D9D9D9D9D % 3A3A9D9D9D3A9DFFFFFF3A3A3A9D9D9D9D9D3A3A3A3A9D9D9D3A3A3A3A3A % 9D9D9D9D3A3A3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A9D3A3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D % 7F7F7F3A9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D3A3A9D9D3A3A3A9D % 9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010121010C5 % 101010101012101012121818161210101212161216181818121012101010 % 1012181818101216181818181818181800FF1810121010100E1816121810 % 181618161818161818181818181818121012101010101218181812101012 % 12161218161818181818181818181818181018121010AF101216FF7D0000 % 0000000000003A9D3A3A3A3A3A9D3AFFFF535353FFFF9D3A3A9D9D9D9D9D % 9D3A9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D7F7F1313137F7F3A9D9D3A9D3A % 9D9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFFFF535353FFFF3A3A3A9D3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A7F7F1313137F7F3A3A9D3A9D9D9D3A9D9D9D9D9D9D9D3A % 9D3A9D3A9D3A9D9D3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A % 3A9D9D3A3AFFFF535353FFFF3A9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A % 9D3A3A9D3A9D9D7F7F1313137F7F3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A9D9D9D9D3A3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A3A9D9D9D9D9D3A % 3A9D9D9DFFFF535353FFFF3A9D9D9D9D9D3A3A3A3A9D9D9D3A3A3A3A3A9D % 9D9D9D3A3A3A3A3A9D9D9D9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A9D3A % 3A3A3A9D3A3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A7F7F13 % 13137F7F9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D9D9D3A3A9D9D3A3A3A9D9D % 9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210012161210C510 % 101010101012101210121012101010101012181818181818181012101010 % 0E181612181018161816181816181800FF181810100A100A101010101812 % 121218181818181818181818181810101010101216181818181810121010 % 12161218181210101018181818181818181818180AAF101216FF7D000000 % 00000000003A3A3A9D3A3A3A9DFF53535353535353FF3A3A9D9D9D9D9D9D % 9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D7F131313131313137F9D9D9D3A9D3A % 9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F131313131313137F3A9D3A9D9D9D3A3A9D9D9D9D9D9D9D9D % 9D3A9D9D3A3A3A9D9D3A9D3A9D3A3A3A3A3A9D3A9D3A3A3A9D3A3A3A3A9D % 3A3A3AFF53535353535353FF3A3A9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D % 3A3A3A3A9D7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A9D3A3A % 3A3AFF53535353535353FF3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A3A9D3A3A3A3A9D9D3A3A3A9D3A3A9D9D3A3A3A3A3A3A9D3A3A % 3A3A9D3A3A3A9D3A9D3A9D9D3A3A3A9D3A9D9D3A3A9D9D9D9D7F13131313 % 1313137F3A9D3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D9D9D9D9D9D3A3A9D9D % 9D9D9D3A9D3A3A9D3A3A3A3A3A3A3A000000000000210012161210C51010 % 10101010101010101012101010101010121018181A181A181810100A100A % 101010101812121218181818181800FF181818101010100B101012101818 % 181818181818181010181216121012101010101218181818181A18181216 % 1218181210181818181818181816121816181818AF101210FF7D00000000 % 000000003A3A3A3A3A3A3A3AFF53535353535353FF3A3A9D9D9D3A9D9D9D % 3A9D9D3A3A3A3A9D3A3A3A3A3A3A7F131313131313137F9D9D9D3A9D9D9D % 9D3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F131313131313137F3A3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A % 9D3A9D3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9DFF53535353535353FF3A3A9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D3A3A % 9D3A3A9D7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A % 3AFF53535353535353FF3A3A3A3A3A9D3A3A9D9D3A3A3A9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A % 3A9D3A3A3A9D9D3A3A3A9D9D3A3A3A3A9D3A3A9D9D3A9D9D7F1313131313 % 13137F3A9D3A3A3A3A9D3A9D9D3A9D9D3A9D9D9D9D9D3A9D9D9D3A9D9D9D % 9D9D3A9D3A3A3A3A3A9D3A3A3A3A000000000000210012101818C5101216 % 12181818181010121010121010101010121818181818181818101010100B % 1010121018181818181818181800FF181818101210101010101012101210 % 181818181818181211181012101012101010101818181818181812101210 % 18181012101218101818181818121012121018AF181012FF7D0000000000 % 0000003A3A3A3A3A3A3AFF535353535353535353FF3A9D9D9D3A9D9D9D3A % 9D9D3A3A3A3A9D3A3A3A3A3A7F1313131313131313137F9D9D3A9D9D9D9D % 3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A7F1313131313131313137F3A9D3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D % 3A9D3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF535353535353535353FF3A9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D3A3A9D % 3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3AFF % 535353535353535353FF3A3A3A3A9D3A3A9D9D3A3A3A9D3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A % 9D3A3A3A9D9D3A3A3A9D9D3A3A3A3A9D3A3A9D9D3A9D7F13131313131313 % 13137F9D3A3A3A3A9D3A9D9D3A9D9D3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D % 9D3A9D3A3A3A3A3A9D3A3A3A3A000000000000210010121612C518181818 % 181818181218161812101010101010101012181818181818101210101010 % 10101210121018181818181800FF16181216121012101010121010101018 % 181818181818181812161216121012101218181818181A18181010101010 % 101010101010121012101210101010101018AF121012FF7D000000000000 % 00003A3A3A3A3A3A3AFF535353535353535353FF3A9D3A9D9D9D9D9D3A9D % 3A3A3A9D3A3A3A9D3A9D3A7F1313131313131313137F9D9D9D3A9D9D9D3A % 3A3A9D3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A9D3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A7F1313131313131313137F3A9D3A9D9D9D3A3A9D9D9D9D9D9D9D9D3A9D % 3A9D9D3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A3AFF % 535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D3A9D3A % 3A7F1313131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D9D3A3A3A9D3A3A3AFF53 % 5353535353535353FF9D3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A9D9D3A3A3A9D3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A9D9D9D3A9D3A9D3A9D9D9D9D7F1313131313131313 % 137F9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A9D3A9D9D9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010121018C51316181818 % 181818181818181618181818101010101010181816181216121012101010 % 121010101018181818181800FF1812161218101012101210101010101012 % 18181818181818101812101210101217181A18181A181818181010101010 % 1010101010101010101818121810101012AF121010FF7D00000000000000 % 003A3A3A3A3A3A3AFF535353535353535353FF3A9D9D9D3A9D9D3A9D9D9D % 9D9D3A3A3A3A3A3A3A3A7F1313131313131313137F9D3A9D3A3A9D3A9D3A % 3A3A3A3A3A9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 7F1313131313131313137F3A9D3A9D3A3A9D9D3A3A9D9D9D9D9D9D9D9D3A % 9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3AFF53 % 5353535353535353FF9D9D9D9D9D9D9D9D9D3A3A3A9D9D9D3A9D3A9D3A3A % 7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 9D9D9D3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A9D9D3A9D9D3A3A3AFF5353 % 53535353535353FF9D9D9D3A3A3A9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D % 3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D9D3A3A3A3A3A3A9D3A3A3A3A9D3A % 3A3A3A9D3A3A3A3A3A9D3A9D3A9D3A3A3A9D3A9D7F131313131313131313 % 7F9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A3A9D9D9D9D9D3A % 9D3A3A3A3A3A9D3A3A3A3A000000000000210010101216C5181818181818 % 18181A181818121818181818121010101012181812161218101012101210 % 1010101010121818181800FF101018111818181818181818181818181818 % 1818181818181818111810101218181818181A181A181818161010101010 % 10101010101010181718181816121010AF101210FF7D0000000000000000 % 3A3A3A3A3A3A3A9DFF53535353535353FF3A3A9D9D9D3A9D9D3A9D9D9D9D % 9D3A3A3A3A3A3A3A3A9D7F131313131313137F9D9D3A9D3A3A9D3A9D3A3A % 3A3A3A3A9D3A9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9DFF53535353535353FF3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 7F131313131313137F3A3A9D3A9D3A3A9D9D3A3A9D9D9D9D9D9D9D9D3A9D % 3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF53 % 535353535353FF9D9D9D9D9D9D9D9D9D9D3A3A3A9D9D9D3A9D3A9D3A3A3A % 7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 9D9D3A3A9D3A3A3A3A3A3A9D9D3A3A3A3A3A9D9D3A9D9D3A3A3A9DFF5353 % 5353535353FF3A9D9D9D3A3A3A9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A9D3A % 3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D9D3A3A3A3A3A3A9D3A3A3A3A9D3A3A % 3A3A9D3A3A3A3A3A9D3A9D3A9D3A3A3A9D3A9D3A7F131313131313137F9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D3A3A9D9D9D9D9D3A9D % 3A3A3A3A3A9D3A3A3A3A000000000000210012101210C516181818181818 % 181818181010121018181818181818101012101018111818181818181818 % 18181818181818181800FF121810181018181018181818181A1818181818 % 181A18181818161818131810181818181A18181818181818181012101010 % 101010101010181818181818181810AF161816FF7D00000000000000003A % 3A3A3A3A3A3A3AFF53535353535353FF3A3A9D9D9D9D3A9D3A9D9D9D3A9D % 9D9D3A3A3A3A3A3A3A7F131313131313137F3A3A9D3A3A9D9D9D9D3A9D3A % 9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3AFF53535353535353FF9D3A3A3A9D3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F % 131313131313137F3A3A3A3A9D3A9D9D9D3A3A9D9D9D9D9D9D9D9D9D3A9D % 9D9D3A3A3A9D9D3A9D3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3AFF5353 % 5353535353FF9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D3A3A9D3A9D3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A % 9D3A3A3A3A9D3A3A3A3A9D9D3A3A3A3A3A3A9D9D9D9D3A3A3A3AFF535353 % 53535353FF3A3A3A9D9D3A3A3A3A9D9D9D3A3A9D3A3A9D9D9D9D9D9D3A3A % 3A3A9D9D9D3A3A3A3A3A9D9D9D9D3A3A3A3A3A3A3A9D3A9D9D9D3A3A9D3A % 3A3A3A9D3A3A3A9D3A9D9D3A9D9D3A9D3A9D3A7F131313131313137F9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D3A9D3A3A9D9D3A9D9D3A9D3A % 3A3A3A3A3A3A3A3A3A000000000000210018161216C51812181618181618 % 18121012101012101818181A181810101012181018101818101818181818 % 1A1818181818181A00FF1810121812161218101818181818181818181A18 % 181818181818181810181018181818181818181818181818101810121010 % 1010101010121210121818181810AF181818FF7D00000000000000003A3A % 3A3A3A3A3A9D3AFFFF535353FFFF9D3A3A9D3A3A9D9D9D9D9D9D9D9D3A3A % 3A9D3A3A9D3A3A3A3A7F7F1313137F7F9D9D9D3A3A9D3A9D3A9D3A3A3A3A % 9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A7F % 7F1313137F7F3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A % 3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D3A3A3A9DFFFF53 % 5353FFFF9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D3A3A3A3A9D3A7F % 7F1313137F7F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A9D3A3A3A3A3AFFFF5353 % 53FFFF3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A % 9D3A3A3A9D3A3A9D3A9D3A3A9D3A3A9D3A9D9D7F7F1313137F7F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D3A3A9D9D9D9D9D9D3A9D3A3A % 9D3A3A3A3A3A3A3A000000000000210018181812C5101210181218181810 % 101810181010121218181818181810121810121812161218101818181818 % 181818181A181800FF17181612161012161210181818181818181A181818 % 18181818181818181018181818181A181818101812181810121018101210 % 12101010101010101012181812AF181818FF7D00000000000000003A3A3A % 3A3A3A3A9D3A9D9DFFFFFF9D3A9D3A3A9D3A3A9D9D9D9D9D9D9D9D3A3A3A % 9D3A3A9D3A3A3A3A3A9D7F7F7F9D9D9D9D9D3A3A9D3A9D3A9D3A3A3A3A9D % 9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3AFFFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A % 7F7F7F7F3A3A3A3A3A3A9D9D9D3A9D9D9D3A9D9D9D9D9D9D9D9D9D9D3A3A % 9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3AFFFF % FF9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D3A3A3A3A9D3A9D7F % 7F7F7F9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A9DFFFFFF % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A9D % 3A3A3A9D3A3A9D3A9D3A3A9D3A3A9D3A9D9D9D9D7F7F7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D9D3A3A9D9D9D9D9D9D3A9D3A3A9D % 3A3A3A3A3A3A3A000000000000210018181816C510121012101216121818 % 181818181010101012101818161818171816121610121612101818181818 % 18181A18181800FF18181818121010101010121618181818181818181A18 % 18181A181818181818181818181818181818181010101012101818181010 % 101010101010101010181810AF181018FF7D00000000000000003A3A3A3A % 3A9D3A9D3A3A9D9D3AFF9D9D3A3A3A9D3A3A9D9D9D3A9D3A9D3A9D9D3A3A % 3A3A3A3A3A3A3A3A7F9D9D9D3A9D9D9D3A9D3A9D9D3A9D9D9D3A9D3A9D3A % 9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 9D3A7F9D3A3A3A3A3A9D3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D3A9D % 9D3A3A9D3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFF % 9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D3A9D3A3A9D3A9D7F3A % 9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9DFF3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A9D9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A % 3A3A3A3A3A3A9D9D3A9D3A3A3A9D3A9D3A9D3A9D9D7F3A3A3A3A9D3A9D9D % 3A9D3A9D3A3A3A9D9D9D9D3A3A9D9D9D3A3A9D3A9D9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A000000000000210010181318C51010101012101210101210 % 181818181818121012101018181818181818121010101010121618181818 % 181818181A00FF1012181010101010101010101218181818181818181818 % 1A181A181818181818181818181818181818101210101010181210181012 % 1010101010121012181818AF181618FF7D00000000000000003A3A9D3A3A % 3A3A9D3A9D9D3A9D9DFFFFFF3A3A9D9D9D3A9D9D3A9D9D9D9D9D9D3A3A3A % 3A3A3A9D3A7F7F7F9D9D9D3A9D3A3A9D3A9D3A9D9D3A9D9D3A3A9D3A9D9D % 3A9D9D9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3AFFFFFFFF3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3A7F7F7F7F3A9D3A9D9D3A3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D3A9D3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9DFF % FFFF9D9D9D9D9D9D9D3A3A9D9D3A3A9D9D9D9D9D3A9D3A3A7F7F7F7F3A9D % 9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D3A3A3A3A % 3A3A3A3A9D9D3A3A9D3A3A3A3A9D3A9D9D9D3A3A3A3AFFFFFF3A3A3A3A3A % 3A9D3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A9D3A % 3A9D9D3A9D3A9D9D3A9D9D3A3A9D9D9D3A9D9D3A9D7F7F7F3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D9D3A9D9D3A9D9D3A9D9D9D3A9D9D9D3A9D3A3A3A3A3A % 3A3A3A3A3A000000000000210016181618C5121012101012101012101210 % 121818181818101012121218121012181010101010101010101218181818 % 1818181800FF1210101010100810101010101010101218161818181A181A % 181818181817181818181818181818181818101010101010101210121010 % 18101010101012181818AF181818FF7D00000000000000003A3A9D3A3A3A % 3A9D3A9D9D3AFFFF535353FFFF9D9D9D3A9D9D3A9D9D9D9D9D9D3A3A3A3A % 3A3A7F7F1313137F7F9D3A9D3A3A9D3A9D3A9D9D3A9D9D3A3A9D3A9D9D3A % 9D9D9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF % FF535353FFFF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D7F % 7F1313137F7F3A9D9D3A3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D3A9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFFFF5353 % 53FFFF9D9D9D9D9D3A3A9D9D3A3A9D9D9D9D9D3A9D7F7F1313137F7F9D9D % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D3A3A3A3A3A % 3A3A3A9D9D3A3A9D3A3A3A3A9D3A9D9D9D3A3AFFFF535353FFFF3A3A3A3A % 9D3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A % 9D3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A9D3A9D3A3A % 9D9D3A9D3A9D9D3A9D9D3A3A9D9D9D3A9D9D7F7F1313137F7F3A3A3A3A3A % 3A3A3A9D3A3A9D9D3A9D9D3A9D9D3A9D9D9D3A9D9D9D3A9D3A3A3A3A3A3A % 3A3A3A3A000000000000210018181818C518181810181010121010121010 % 101210181818181810101010121010101010081010101010101010121816 % 18181800FF101012101010100A0F0A10101010101010121618181820181A % 181818181818121618181818181818181812101010101010101010181818 % 181712101816181818AF181818FF7D00000000000000003A3A3A3A3A3A3A % 9D3A9D9DFF53535353535353FF9D9D3A9D9D9D9D9D3A9D9D3A3A9D3A3A3A % 7F131313131313137F9D3A3A9D9D9D9D3A9D9D3A9D9D3A3A9D3A3A9D9D3A % 9D9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF5353 % 5353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F1313 % 13131313137F9D3A9D9D9D3A9D9D9D3A3A3A9D9D9D9D9D9D9D9D3A9D9D3A % 3A3A3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A3A9D3A3A3AFF5353535353 % 5353FF9D9D9D9D3A3A9D9D9D9D9D9D3A9D9D3A7F131313131313137F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D3A3A3A3A3A % 3A3A9D9D9D9D3A3A3A9D3A9D9D9D9D9D3AFF53535353535353FF3A9D3A3A % 9D9D9D3A3A3A9D3A9D9D9D9D3A3A3A9D9D9D3A9D9D9D3A3A3A9D9D9D9D9D % 3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A9D3A9D9D9D9D3A9D3A3A9D3A9D9D3A7F131313131313137F3A3A3A3A3A % 9D3A9D9D9D9D3A9D9D9D9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A3A3A3A9D3A % 3A3A3A000000000000210018181818C5C5C5C5C5C5C51210101210121012 % 1010121018161816121010101012101010100A0F0A101010101010101216 % 181800FF10121010101010100A1010080A10081010101818181A18181818 % 181818101810181217181818181818181010101010101010101218181818 % 1818181818181818AF181818FF7D00000000000000003A3A3A3A3A3A3A9D % 3A9D9DFF53535353535353FF9D3A3A3A9D9D3A3A9D3A9D9D3A3A3A3A3A7F % 131313131313137F9D9D9D9D9D9D9D3A9D3A9D9D9D3A3A9D9D3A3A3A9D3A % 9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3AFF535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313 % 131313137F9D9D3A9D3A9D3A9D9D3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D3A % 9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9DFF535353535353 % 53FF9D9D3A3A3A9D9D9D3A9D3A9D9D9D9D3A7F131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A9D9D3A3A9D % 9D3A9D3A9D9D3A9D9D3A9D9D3A9D3A7F131313131313137F3A3A9D3A3A9D % 3A9D9D3A9D9D3A9D3A9D3A3A9D9D9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A000000000000210018181816C5181818181612161012101010101010 % 1010101218181818181810121010101010100A1010080A10081010101818 % 1800FF18121612181818101010101008100810101012181818181A181818 % 18181810121010181812181812161216121010100A101010121818181818 % 18181818181A18AF181818FF7D00000000000000003A3A3A3A3A3A3A9D3A % 9DFF535353535353535353FF3A3A3A9D9D3A3A9D3A9D9D3A3A3A3A7F1313 % 131313131313137F9D9D9D9D9D9D3A9D3A9D9D9D3A3A9D9D3A3A3A9D3A9D % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3AFF5353535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F9D3A9D3A9D3A9D9D3A9D3A3A3A9D9D9D9D9D9D9D9D3A9D3A9D % 9D9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3AFF5353535353535353 % 53FF9D3A3A3A9D9D9D3A9D3A9D9D9D9D7F1313131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A9D9D3A3A9D9D % 3A9D3A9D9D3A9D9D3A9D9D3A9D7F1313131313131313137F3A9D3A3A9D3A % 9D9D3A9D9D3A9D3A9D3A3A9D9D9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A % 3A000000000000210018181812C518181818181210121018101812121612 % 101010181818181818181216121818181010101010081008101010121818 % 00FF18161210181618101210101010080A10101010101818181818181817 % 121012161218101210101010121018121012101010101012181818181A18 % 181818181818AF181818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D % FF535353535353535353FF3A9D3A9D9D9D9D3A9D9D9D3A9D3A3A7F131313 % 1313131313137F9D3A9D3A3A3A3A9D3A9D3A9D9D3A9D3A3A9D9D9D9D9D3A % 3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A7F131313131313 % 1313137F9D3A9D9D3A9D3A9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D3A9D3A3A % 3A3A9D3A9D3A3A3A3A9D3A3A3A9D3A3A3A3A9D9DFF535353535353535353 % FF3A3A3A3A9D9D3A9D9D9D9D3A9D9D7F1313131313131313137F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3AFF535353535353535353FF3A3A3A9D3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D9D % 3A9D9D9D9D9D9D3A9D9D9D9D7F1313131313131313137F3A3A3A3A3A3A9D % 9D3A3A9D9D9D9D9D3A3A9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 000000000000210018181010C51818171818101810181018181818181818 % 181210121218161818161210181618101210101010080A10101010101800 % FF1012101012181818181012101010101010101218181818181818181812 % 10121812101210121012101018121612101010101010101818181A181A18 % 181A181A18AF181810FF7D00000000000000003A3A3A3A3A3A3A9D3A9DFF % 535353535353535353FF3A3A3A9D9D9D9D3A3A3A9D3A3A3A3A7F13131313 % 13131313137F9D9D3A9D9D9D3A9D3A9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A % 3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3AFF53535353535353 % 5353FF9D3A9D3A3A9D9D3A3A3A3A9D9D3A3A9D3A3A9D9D3A3A9D9D3A3A9D % 9D3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 13137F3A3A9D9D3A9D3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9DFF535353535353535353FF % 3A9D9D9D9D3A9D9D3A9D9D3A3A9D7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A9D9D % 9D3A9D9D9D9D3A9D9D9D9D7F1313131313131313137F3A3A9D3A9D3A9D3A % 3A9D9D9D9D9D9D3A3A9D9D9D9D9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A00 % 0000000000210018101210C510181218101218181818181818181A181818 % 1812101010121810121010121818181810121010101010101012181800FF % 181012101210101012101210100A08101010101012101218101810121010 % 101010181818AFAFAFAFAFAF101210121810181012121818181A18181818 % 18181818AF181010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9DFF % 53535353535353FF9D3A3A3A9D9D9D9D3A3A3A9D3A3A3A3A3A7F13131313 % 1313137F3A9D9D3A9D9D9D3A9D3A9D9D9D3A3A9D3A9D3A3A9D3A9D9D3A3A % 3A3A3A3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A3A3A9DFF53535353535353 % FF3A9D3A9D3A3A9D9D3A3A3A3A9D9D3A3A9D3A3A9D9D3A3A9D9D3A3A9D9D % 3A3A9D3A3A3A9D3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A % 3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F9D3A3A9D9D3A9D3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9DFF53535353535353FF3A3A % 9D9D9D9D3A9D9D3A9D9D3A3A9D3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A9D9D9D % 3A9D9D9D9D3A9D9D9D9D9D7F131313131313137F3A3A3A9D3A9D3A9D3A3A % 9D9D9D9D9D9D3A3A9D9D9D9D9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A0000 % 00000000210010101010C510101010121010101012101818181818181818 % 181818181018181012101210101012101210100A0810101010101200FF18 % 181810101010121012161010101010101010101010121012121010101010 % 10101818AFAFAFAFAFAFAFAF101012101816121816181818181818181818 % 181818AF181010FF7D00000000000000003A3A3A3A9D3A3A3A3A9D9DFF53 % 535353535353FF3A3A3A9D9D9D9D9D3A9D9D9D3A3A3A3A3A7F1313131313 % 13137F9D9D9D9D9D9D9D3A3A9D3A9D9D3A9D3A3A3A3A9D9D9D9D3A3A3A9D % 9D9D3A9D3A9D9D9D3A3A3A3A3A9D3A3A9D3A9D3A9DFF53535353535353FF % 3A3A9D3A3A3A9D3A9D3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A9D3A3A9D3A3A % 3A9D9D3A3A3A9D9D3A9D3A3A9D9D3A3A9D3A9D3A9D3A3A9D3A3A3A9D3A9D % 3A9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F % 9D9D3A9D9D9D9D9D9D3A9D9D9D3A9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D3A9D3A3A9D9D9D9D9D9D9D9D9DFF53535353535353FF9D9D3A % 9D3A9D3A9D9D9D3A9D3A9D3A9D7F131313131313137F3A3A3A3A3A9D3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3AFF53535353535353FF3A3A3A3A9D3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D % 9D9D9D9D3A9D9D3A9D9D7F131313131313137F9D3A3A3A3A3A9D9D9D3A9D % 9D9D3A9D3A3A3A9D3A9D3A9D9D9D9D3A9D3A3A3A9D3A3A3A3A3A3A000000 % 000000210010101010C51010101012101210121018181718181618181818 % 181818181818181810101010121012161010101010101010101000FF1818 % 171818181810101210121010101010101010101010101010101010081010 % 101218AF181818181810AF10101010181212161818181A16181818181618 % 1818AF101210FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3AFFFF % 535353FFFF9D3A3A9D9D9D9D9D9D9D3A9D9D3A9D3A3A9D3A7F7F1313137F % 7F9D3A9D9D9D9D3A9D3A9D3A9D9D9D9D3A9D9D3A3A9D3A9D3A3A9D9D9D9D % 3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A9D9D9D3A3A3AFFFF535353FFFF3A3A % 3A9D3A3A3A9D9D9D3A9D3A9D9D9D3A9D3A3A9D9D3A3A9D9D9D9D3A3A9D3A % 9D3A3A3A9D3A9D3A3A3A3A9D3A3A9D9D3A9D3A9D3A3A3A9D9D9D9D3A9D3A % 9D9D3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D7F7F1313137F7F9D9D % 3A3A9D9D9D9D3A3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFF535353FFFF9D3A9D9D9D % 9D3A9D9D3A9D3A9D3A9D3A3A9D7F7F1313137F7F9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A9D3A3AFFFF535353FFFF3A9D3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A9D9D % 3A9D9D3A9D9D9D9D9D3A7F7F1313137F7F3A3A3A9D3A3A9D3A9D9D3A9D9D % 9D9D9D3A3A9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000 % 0000210012101010C5101210181818101810181018121818181818181818 % 1818181818181718181818101012101210101010101010101000FF121818 % 18181818101210181018181612181818121010101210101010100A081010 % 1818AF181818181818AF1010101012101012121818181818161818181818 % 16AF101010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3A9D9DFF % FFFFFF3A9D3A3A9D9D9D9D9D9D9D3A9D9D3A9D3A3A9D3A3A3A7F7F7F9D9D % 9D3A9D9D9D9D3A9D3A9D3A9D9D9D9D3A9D9D3A3A9D3A9D3A3A9D9D9D9D3A % 9D3A9D3A9D3A3A3A3A3A3A3A3A3A9D9D9D3A3A3A9D9DFFFFFF3A9D3A3A3A % 9D3A3A3A9D9D9D3A9D3A9D9D9D3A9D3A3A9D9D3A3A9D9D9D9D3A3A9D3A9D % 3A3A3A9D3A9D3A3A3A3A9D3A3A9D9D3A9D3A9D3A3A3A9D9D9D9D3A9D3A9D % 9D3A9D3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D9D7F7F7F3A3A9D9D3A % 3A9D9D9D9D3A3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFFFF3A3A9D3A9D9D9D9D % 3A9D9D3A9D3A9D3A9D3A3A9D9D9D7F7F7F9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A9D3A3A3A3AFFFFFF3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A9D9D3A % 9D9D3A9D9D9D9D9D3A9D9D7F7F7F3A3A3A3A3A9D3A3A9D3A9D9D3A9D9D9D % 9D9D3A3A9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000 % 00210010101010C512161818181818181210121012101810181818181818 % 18181812181818181818101210181018181612181818121000FF10121012 % 101212101012121618181818181818181818101818131610101010101210 % 18AFAFAFAFAFAFAFAF101010101010101010121018181818181818181818 % AF121010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3A9D9D3A3A % 3AFF9D3A9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A7F3A3A9D9D9D3A % 9D9D9D3A9D9D9D3A9D3A9D3A9D3A9D3A3A3A9D9D9D9D9D9D3A3A9D3A9D9D % 9D9D9D9D3A3A9D3A3A3A3A3A3A9D9D3A9D9D3A9DFF3A9D3A3A3A9D3A3A9D % 3A3A3A9D9D9D3A9D3A9D9D9D9D9D9D3A9D9D3A3A9D9D9D9D9D3A3A3A9D9D % 3A3A9D9D9D9D9D3A3A9D9D3A9D3A3A9D9D9D3A3A3A9D9D3A9D3A9D9D3A9D % 3A9D3A9D9D9D9D3A3A3A3A9D3A3A9D3A3A3A9D9D3A9D3A7F9D9D9D3A9D3A % 9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3AFF9D3A9D9D9D9D3A3A9D % 9D9D9D9D9D9D3A3A9D9D9D9D7F9D9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D3A9D9D9D3A9D3A % 9D3A3A9D9D9D3A9D9D9D3A9D7F3A3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D9D % 9D3A3A9D9D9D3A3A9D3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A000000000000 % 210010101010C518181818181A1818181010101010121012101812161818 % 181010121012101212101012121618181818181818181800FF1210101210 % 101010181010121818181818181A181A1818181718181218181810101810 % 18AFAFAFAFAFAF12101018181010101010101212181818181818181818AF % 101210FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3A3A % FFFFFFFF9D3A9D3A9D3A9D9D9D9D9D3A3A3A3A3A7F7F7F3A3A9D9D9D9D3A % 9D9D9D9D9D9D3A9D3A9D9D9D9D3A3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D9D % 3A9D9D3A3A3A3A3A3A3A3A3A3A3A3A9D3AFFFFFF3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A9D3A3A9D3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D9D9D7F7F7F3A3A3A9D % 9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3A9D9DFFFFFF9D9D9D3A3A3A9D % 9D9D9D9D3A3A9D3A3A7F7F7F9D9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A9D9D9D3A9D9D9D9D % 3A3A9D9D9D9D9D3A9D9D9D9D7F7F7F3A3A3A3A3A3A9D9D3A3A9D3A9D9D9D % 3A3A9D3A3A9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021 % 0012101010C51818181A1818181818121010101010121010101012101818 % 101210101210101010181010121818181818181A181A00FF181812101012 % 1012121012101018181618181A1818181818181818171818181612121012 % 101010181810101212181018181010101210101818181A1818181818AF16 % 1210FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D9D9D3AFFFF % 535353FFFF9D3A9D3A9D9D9D9D9D3A3A3A7F7F1313137F7F9D9D9D9D3A9D % 9D9D9D9D9D3A9D3A9D9D9D9D3A3A9D3A9D3A3A9D3A3A3A9D3A9D3A9D9D3A % 9D9D3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A3A3A3A9D3A9D3A3A3A9D3A3A9D3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D7F7F1313137F7F3A9D9D % 9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A3AFFFF535353FFFF9D3A3A3A9D9D % 9D9D9D3A3A9D7F7F1313137F7F3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A9D3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A9D9D3A9D9D9D3A9D9D9D9D3A % 3A9D9D9D9D9D3A9D9D7F7F1313137F7F3A3A3A3A9D9D3A3A9D3A9D9D9D3A % 3A9D3A3A9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100 % 12101212C518181818181A18181810100B0E10101010100E101010121818 % 1818121010121012121012101018181618181A181800FF18181818121010 % 181010101012181810101818181818121012101818181818181810101010 % 101018181012101010181818181816121612181818181818181818AF1810 % 18FF7D00000000000000003A3A3A3A3A3A3A3A3A9D9D3A9D9D3AFF535353 % 53535353FF3A9D9D3A9D9D3A9D3A9D7F131313131313137F9D9D9D3A9D9D % 9D3A9D9D3A3A9D3A9D9D3A9D9D3A9D9D9D9D3A9D3A3A3A3A9D9D9D3A9D9D % 3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A7F131313131313137F3A3A3A % 3A3A9D3A9D9D3A3A9D3A9D3A9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D3A3A3A9DFF53535353535353FF9D9D3A9D3A9D % 3A9D9D9D7F131313131313137F9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A % 3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A9D3A9D3A9D3A9D3A9D9D3A9D9D9D3A9D9D3A3A % 9D9D9D3A3A9D9D7F131313131313137F3A3A9D3A9D9D3A9D3A9D9D9D3A3A % 9D9D9D9D9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210010 % 181316C5181818181A181A181812101010101010100A100A101012161818 % 181818121010181010101012181810101818181800FF1618181818181018 % 18181012101010181816181818161810101018131618181A181818121010 % 1018101812101818131818181818181818181818181818181818AF181012 % FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A3A9DFF53535353 % 535353FF3A3A9D9D3A9D9D9D3A3A7F131313131313137F9D9D9D3A9D9D9D % 3A9D3A3A9D3A3A9D9D9D3A3A9D9D3A3A3A9D3A3A9D3A9D9D9D3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A9D3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D7F131313131313137F3A3A9D3A % 3A9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A3A3A9D9D9DFF53535353535353FF9D9D9D3A9D3A3A % 9D9D9D7F131313131313137F9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D3A3A3A % 9D9D9D9D3A9D7F131313131313137F3A3A3A3A9D9D3A9D3A9D9D9D3A9D9D % 3A9D3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A00000000000021001012 % 1618C518181A181A181818181818181810100A1010101010101012181618 % 1818181810181818101210101018181618181800FF121818181818181818 % 171210101010121012181018121818181812161812161818181818101810 % 1210121618181018181818181818181818181818181A181818AF181818FF % 7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A3AFF535353535353 % 535353FF3A9D9D3A9D9D9D3A7F1313131313131313137F9D9D3A9D9D9D3A % 9D3A3A9D3A3A9D9D9D3A3A9D9D3A3A3A9D3A3A9D3A9D9D9D3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A9D3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D7F1313131313131313137F3A9D3A3A % 9D9D9D9D9D3A9D9D9D3A9D9D9D9D9D9D3A3A3A9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A3A3A9D9DFF535353535353535353FF9D9D3A9D3A3A9D % 9D7F1313131313131313137F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF % 535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A9D9D9D9D9D9D9D9D9D9D3A3A3A9D % 9D9D9D3A7F1313131313131313137F3A3A3A9D9D3A9D3A9D9D9D3A9D9D3A % 9D3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A0000000000002100181818 % 18C518181818181818181216181812101010121010101010101012121818 % 18181818181817121010101012101218101800FF10121612181610181818 % 121612101012101210121618181818181818121018101216181618181810 % 18AFAF101210181618181818AFAFAFAFAFAFAFAFAFAFAFAFAF181818FF7D % 00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D9DFF53535353535353 % 5353FF9D3A9D3A3A3A9D3A7F1313131313131313137F3A3A3A9D9D3A9D3A % 9D3A9D3A9D3A9D9D9D9D3A9D9D3A3A3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF535353535353535353FF9D3A3A3A3A3A3A3A3A3A3A % 9D3A3A9D3A3A9D9D3A9D3A9D3A9D3A3A9D3A3A3A9D9D3A3A3A9D9D3A9D3A % 9D9D3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A9D9D9D3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3AFF535353535353535353FF3A9D3A9D3A9D3A3A % 7F1313131313131313137F9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFF53 % 5353535353535353FF3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A9D9D3A9D3A9D9D3A3A9D9D3A3A3A3A9D9D % 3A9D3A7F1313131313131313137F3A3A9D9D3A3A3A9D3A9D3A9D3A9D9D3A % 9D9D3A9D9D9D3A9D3A9D3A9D3A3A3A3A3A3A000000000000210018181818 % C51018181818181812101012161818121018101010101010101010121612 % 181610181818121612101012101210121600FF1010121012181218161810 % 121012101010101010121216181818161810181010121012181818181612 % AFAF1012101212101818181818181818181A18181A1E18AF181818FF7D00 % 000000000000003A3A3A3A3A3A3A9D3A9D9D3A9D9DFF5353535353535353 % 53FF3A9D3A3A9D3A9D3A7F1313131313131313137F9D3A9D3A9D3A9D3A9D % 3A9D3A3A9D9D3A3A9D9D9D9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A9D3A3A % 3A3A3A3A3A3A3AFF535353535353535353FF3A9D9D3A9D3A9D9D3A3A3A9D % 9D3A3A3A3A9D3A3A9D3A3A3A9D3A9D9D3A3A3A9D3A3A9D3A3A9D9D9D9D3A % 9D3A3A3A3A3A3A9D3A9D9D9D3A9D3A9D3A3A9D9D9D3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A9D7F1313131313131313137F3A9D9D9D9D3A % 9D3A9D3A3A3A9D3A3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A7F % 1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9DFF5353 % 53535353535353FF3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D3A9D9D9D3A9D3A9D9D9D3A3A9D9D9D % 3A9D7F1313131313131313137F3A9D9D9D9D3A3A9D9D9D9D3A9D9D3A3A9D % 9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181818C5 % 181818181818181810101210181216181810121010121010101010121012 % 1812181618101210121010101010101200FF101010101012161218101812 % 161210101012101210101210181218181818181810181810121210121810 % 1210101010101210121818181818181818181A181A18AF181818FF7D0000 % 0000000000003A3A3A3A3A3A3A9D3A9D9D3A9D9D9DFF53535353535353FF % 9D3A9D3A3A9D3A9D3A9D7F131313131313137F9D9D3A9D3A9D3A9D3A9D3A % 9D3A3A9D9D3A3A9D9D9D9D3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A9D3A3A3A % 3A3A3A3A3A3A3AFF53535353535353FF3A3A9D9D3A9D3A9D9D3A3A3A9D9D % 3A3A3A3A9D3A3A9D3A3A3A9D3A9D9D3A3A3A9D3A3A9D3A3A9D9D9D9D3A9D % 3A3A3A3A3A3A9D3A9D9D9D3A9D3A9D3A3A9D9D9D3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A9D3A7F131313131313137F9D3A9D9D9D9D3A9D % 3A9D3A3A3A9D3A3A3A3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A7F % 131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF5353 % 5353535353FF3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D9D9D3A9D9D3A9D9D9D3A9D3A9D9D9D3A3A9D9D9D3A % 9D3A7F131313131313137F3A3A9D9D9D9D3A3A9D9D9D9D3A9D9D3A3A9D9D % 9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181818C518 % 18181A181818181010121012101210121810121010101210101010101012 % 16121810181216121010101210121000FF10101012181818161818181018 % 161810101010101012101210101218161818181818101210101018161210 % 121010101010101210121612181818181A18201E1AAF1A1818FF7D000000 % 00000000003A3A3A3A3A3A3A9D3A9D9D9D3A3A9DFF53535353535353FF9D % 3A9D9D9D3A9D3A3A3A7F131313131313137F9D9D9D9D9D9D3A3A9D9D3A9D % 3A9D3A3A9D9D9D9D9D3A3A9D9D9D3A9D3A3A9D3A9D9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF53535353535353FF9D3A3A9D3A9D3A9D3A3A3A3A3A3A3A % 9D9D3A9D9D9D9D9D3A3A9D9D9D9D9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A % 3A3A9D9D3A9D3A3A9D9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A9D3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3AFF53535353535353FF3A3A3A3A3A3A9D3A3A3A7F13 % 1313131313137F3A9D3A3A9D3A3A3A3A9D3A3A9D3A3A9D3A3A3A9D3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D9D9D3A9D3A9D9D3A9D9D3A9D3A9D9D9D3A3A3A3A9D9D3A9D3A % 9D7F131313131313137F3A3A3A3A9D3A9D3A9D3A9D3A9D3A9D9D9D3A9D9D % 3A9D9D3A9D3A9D3A3A3A3A3A3A3A3A000000000000210018181818C51818 % 181818181818181812101010101018101818181812101010101012181818 % 161818181018161810101010101000FF1810121018181818121810181818 % 181810121012101010101012101012121018181018101010101812101010 % 10101010101010101010101818181818181A181AAF181818FF7D00000000 % 000000003A3A3A3A3A3A3A9D3A9D9D9D9D9D3A3AFFFF535353FFFF9D9D9D % 9D3A9D3A9D9D3A9D3A7F7F1313137F7F9D9D9D9D3A9D9D3A9D3A3A3A3A3A % 9D9D9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A9D3A3A9D3A3A3A3A3A3A3A7F7F % 1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFFFF5353 % 53FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D9D3A9D9D9D3A3A3A9D9D9D3A9D9D % 9D7F7F1313137F7F3A3A3A3A9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D3A9D9D % 9D9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181816C5181818 % 181818181818121010101010101012101818181818181810121018181818 % 1218101818181818101210121000FF1A1818181618181816181818181618 % 181818101010101012121012101010101218101210121010181016121010 % 10101010101010101010101818181818181820AF1A1818FF7D0000000000 % 0000003A3A3A3A3A3A3A9D3A9D9D9D9D9D3A3A3A9DFFFFFF3A9D9D9D9D9D % 3A9D3A9D9D3A9D3A3A3A7F7F7F3A3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A9D % 9D9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A7F % 7F7F3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3AFFFFFFFF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A9D9D3A9D3A9D3A3A9D3A3A9D3A9D9D3A9D9D9D3A3A3A9D9D9D3A9D9D9D % 9D3A7F7F7F3A3A3A3A3A3A9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D3A9D9D9D % 9D3A9D3A3A3A3A3A3A3A3A3A3A000000000000210018181812C512101818 % 1810121612161010101010121010181818181818181A1818181618181816 % 18181818161818181810101000FF181818181A1818181810181018181816 % 18121612101810101012101010101010101210121618181218AF18181810 % 10101010101010101010121018181A202118AF181818FF7D000000000000 % 00003A3A3A3A3A3A3A9D3A9D9D9D3A9D9D3A3A3A3A9DFF3A9D9D3A9D9D9D % 9D9D9D9D3A3A3A3A7F3A3A3A3A3A9D9D9D9D3A9D9D9D9D9D3A3A9D3A9D9D % 3A9D9D3A3A3A9D3A3A9D3A9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3AFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A9D3A3A7F3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A9D3A3AFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D9D % 9D3A9D9D9D9D3A3A3A9D9D9D3A9D9D3A9D9D9D3A3A9D9D9D9D3A9D9D3A9D % 9D3A3A7F3A3A3A3A3A9D3A9D9D3A9D9D3A9D3A3A3A9D9D9D9D9D3A9D9D9D % 3A9D3A3A3A9D3A3A3A3A3A3A000000000000210018181016C51012101012 % 10181018181310100A08081010101216181A1818181818181A1818181810 % 181018181816181216121000FF1818181818181A18101812121212181818 % 181012101210101216181818181210121018AFAFAFAF161218AF18181818 % 1010101010101010101012181818201A18AF181212FF7D00000000000000 % 003A3A3A3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A9D3A3AFFFFFF9D3A9D9D3A % 9D9D9D3A9D7F7F7F3A3A3A9D3A9D9D9D3A9D9D9D9D9D3A3A9D9D3A9D3A9D % 9D3A9D9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A9DFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3AFFFFFF3A3A3A3A3A3A3A3A3A3A7F7F7F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFFFF3A3A9D3A3A % 3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D % 9D3A3A9D3A3A3A3A9D9D3A9D9D9D3A3A3A9D3A3A3A9D9D3A9D3A9D9D3A9D % 3A3A3A7F7F7F3A3A3A3A9D9D9D3A9D9D9D3A9D3A3A9D9D3A3A9D3A9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A000000000000210012121812C5101810121018 % 10121816181810101008101010181818181A181818181818181A18101812 % 1212121818181810121000FF1A181A181A18181818121010101010181210 % 1010121012161218181818181818181818AFAFAF12101210AF1216181810 % 1010121010100E101010121818181818AF101010FF7D0000000000000000 % 3A3A3A3A3A3A3A3A3A9D9D9D3A9D9D3A3A3A9DFFFF535353FFFF9D9D3A9D % 9D9D7F7F1313137F7F3A9D3A9D9D9D3A9D9D9D9D9D3A3A9D9D3A9D3A9D9D % 3A9D9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3AFF % FF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F7F3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A3A7F7F1313137F7F3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF3A9D3A3A3A % 3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A9D9D % 3A3A9D3A3A3A3A9D9D3A9D9D9D3A3A3A9D3A3A3A9D9D3A9D3A9D9D3A9D3A % 7F7F1313137F7F3A3A9D9D9D3A9D9D9D3A9D3A3A9D9D3A3A9D3A9D9D3A9D % 3A3A3A3A3A3A3A3A3A3A000000000000210010101210C518181818101210 % 1210181818181210101010121818181A18181A181A181A18181818121010 % 10101018121010101200FF18181818181818181810101010101018181012 % 10101012101216181818181818181818AF18AF16121010AF101212181012 % 101010101010101010101216181812AF121012FF7D00000000000000003A % 3A9D3A3A3A3A9D3A9D9D9D9D3A9D9D3A3AFF53535353535353FF9D3A9D3A % 7F131313131313137F3A3A9D9D9D3A9D3A9D9D3A3A3A3A3A9D3A9D9D3A3A % 9D3A9D3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3AFF5353 % 5353535353FF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3AFF53535353535353FF3A3A3A9D7F131313131313137F3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D3A9D % 9D3A9D3A3A9D9D9D9D9D9D9D3A3A3A9D3A3A9D9D9D9D9D3A9D9D9D9D7F13 % 1313131313137F9D9D3A3A9D9D3A9D3A3A9D3A9D9D9D9D9D9D9D9D3A9D3A % 9D3A3A3A3A3A3A3A3A000000000000210010121012C51818181818121010 % 10101218181818121012101818181A181818181818181818181810101010 % 101018181012101000FF1818181818181818121010101010101818101010 % 101218101012181818181818181818AF18AFAFAFAFAFAF10101012161218 % 1010121010101010101210121010AF101010FF7D00000000000000003A3A % 3A3A3A9D3A9D3A9D9D9D3A9D9D3A3A3AFF53535353535353FF9D3A9D3A7F % 131313131313137F3A9D9D9D9D3A9D9D9D3A3A3A3A3A3A9D9D9D9D3A9D9D % 9D9D9D3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3AFF535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A9D3A3AFF53535353535353FF3A3A3A3A7F131313131313137F9D3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3AFF53535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A % 3A3A9D3A9D9D3A3A9D9D3A9D9D9D9D3A3A9D9D9D9D9D3A9D3A9D9D7F1313 % 13131313137F9D9D9D3A9D9D9D9D3A3A9D3A9D9D9D3A9D9D9D9D3A9D3A3A % 3A3A3A3A3A3A3A3A000000000000210010101012C5181818181818101210 % 10101010121618121618181818181A181818181818181818121010101010 % 1018181010101000FF181818181818181810121010101010181618181216 % 1210101012101818101218181818AF1818AFAFAFAF161210101018121612 % 10101010101012101012101012AF101010FF7D00000000000000003A3A3A % 3A3A9D3A9D3A9D9D9D3A9D9D3A3AFF535353535353535353FF3A9D7F1313 % 131313131313137F9D9D9D9D3A9D9D9D3A3A3A3A3A3A9D9D9D9D3A9D9D9D % 9D9D3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9DFF5353535353 % 53535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A9D3AFF535353535353535353FF3A3A7F1313131313131313137F3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3AFF535353535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A % 3A9D3A9D9D3A3A9D9D3A9D9D9D9D3A3A9D9D9D9D9D3A9D3A9D7F13131313 % 13131313137F9D9D3A9D9D9D9D3A3A9D3A9D9D9D3A9D9D9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A000000000000210010101010C51818181A181812101010 % 100808101012101812171818181818181818181818181810121010101010 % 18161818121600FF12161818101810181210121010101212181818181812 % 101010121613101210181618181818181818181818181010101216121012 % 101216181810181012101216AF101010FF7D00000000000000003A3A3A3A % 3A3A3A9D3A9D9D9D3A3A9D9D3AFF535353535353535353FF3A3A7F131313 % 1313131313137F3A9D9D3A3A9D9D9D9D9D3A3A3A3A3A9D3A9D9D9D3A9D3A % 9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3AFF535353535353535353FF3A3A7F1313131313131313137F3A3A3A3A % 3A3A3A3A3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3AFF535353535353535353FF3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A9D3A % 3A3A9D3A9D3A9D9D9D9D9D9D3A3A3A9D9D9D9D3A3A3A3A9D7F1313131313 % 131313137F9D3A3A9D9D9D9D3A3A9D3A3A9D9D9D3A9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A000000000000210010101010C51818181818181818101010 % 100A10101010121612181818181812161818101810181210121010101212 % 181818181800FF1012101012161210101010121012161818181A18181210 % 181218181818101218121216181818181218181818181012101810181018 % 1012181818181812161218AF101010FF7D00000000000000003A3A3A3A3A % 3A3A9D3A9D9D9D9D9D3A9D3AFF535353535353535353FF3A9D7F13131313 % 13131313137F3A9D9D9D3A3A9D3A3A3A3A9D3A3A9D3A9D9D3A9D3A9D9D9D % 3A9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3AFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF535353535353535353FF3A3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A0000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000000000000000007F131313131313 % 1313137F0000000000000000000000000000000000000000000000000000 % 0000000000000000000000210010101010C51818181A2018181810121010 % 1010100A1012C5C5C5C51818121012C5C51216121010C5C5C5C512161818 % 181A181800FF1818181818101216121612161218181818181A1818181010 % 101010121018101010101218181818101210101010181810121018121818 % 16181A18181818181618AF181818FF7D00000000000000003A3A3A3A3A3A % 3A9D3A9D9D9D9D9D3A9D3A3AFF53535353535353FF9D3A9D9D7F13131313 % 1313137F3A3A9D9D9D3A3A9D3A3A3A3A9D3A3A9D3A9D9D3A9D3A9D9D9D3A % 9D9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353 % FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF53535353535353FF3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF2121212121212121212121212121212121212121212121 % 212121212121212121212121212121212121212121212121212121212121 % 21212121212121212121212121212121212121212121217F131313131313 % 137F21212121212121212121212121212121212121212121212121212121 % 21212121212100000000210018181010C510101216181818181810121010 % 10101010C5C51010C5C518181818C5C518101216C5C51216C5C518181818 % 1A181800FF1A181818101210181012101216181818181818181818181010 % 101010101010101010101216181818101012101218181010121612161818 % 1818181A1818181818AF181816FF7D00000000000000003A3A3A3A3A3A3A % 9D3A9D9D3A9D3A9D9D3A3AFF53535353535353FF3A9D3A9D7F1313131313 % 13137F3A9D9D9D9D9D3A3A9D3A9D3A3A9D9D3A9D9D9D9D3A9D9D3A9D3A9D % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3AFF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF53535353535353FF3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D3A % 9D3A9D9D9D3A3A9D3A3A3A9D3A9D9D3A9D3A9D9D9D9D7F13131313131313 % 7F9D9D3A3A9D3A9D9D3A9D3A9D9D3A3A9D9D3A9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A002100000000210018161818C51010101218101810181210101010 % 121010C5C51210C5C518181A18181810121018C5C51012C5C51818181818 % 181800FF1818181818111813161216121818181818181A18181818101010 % 101010100A10101010101218181818181012161218101210181318181818 % 1818181818181810AF161318FF7D00000000000000003A3A3A3A3A3A3A9D % 3A9D9D9D9D9D9D9D3A3A3AFFFF535353FFFF9D9D3A9D9D9D7F7F1313137F % 7F3A3A3A9D9D9D9D3A9D3A9D3A9D9D3A9D9D3A9D9D9D3A3A9D3A9D9D3A9D % 3A9D3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D3A9D3AFFFF535353FFFF9D9D % 9D9D3A3A9D3A9D3A9D9D3A9D3A9D3A9D3A9D3A9D3A3A3A3A3A3A3A9D3A9D % 9D9D3A9D3A3A3A9D3A9D3A9D3A3A3A9D3A9D3A3A3A9D9D3A9D9D3A3A3A9D % 3A9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D % 3A3A3A7F7F1313137F7F9D9D9D9D3A9D3A3A3A3A3A9D9D9D9D9D9D3A9D3A % 9D3A9D3A9D3A9D3A9D9D9D3A3A9D3A9D9D3A9D9D3A3A9D3A3A9D3A9D9D3A % FFFF535353FFFF9D3A9D3A9D3A7F7F1313137F7F3A3A3A9D3A9D3A9D3A3A % 3A3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D3A9D3A9D % 3A9D3A9D3A3A3A9D3A9DFFFF535353FFFF9D3A9D3A9D3A3A9D3A9D3A3A9D % 3A9D3A9DFF7D3A3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A3A3A9D3A3A3A3A3A % 3A9D9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D9D9D9D9D % 9D3A9D9D3A3A9D3A9D3A3A9D9D3A9D9D9D9D9D9D3A3A7F7F1313137F7F3A % 3A9D9D9D3A9D3A9D3A3A3A3A3A9D3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A002100000000210013181818C5C5C5C5C5C5C5C5C5C5C5C5C5101216 % 1816C5C51618C5C518181818181818111813C5C51612C5C5181818181A18 % 1800FF1A18181818181618181210121618181A181A181818181810101010 % 101010101010081010101818181818181018161216121810181018101818 % 18181818181010AF121818FF7D00000000000000003A3A3A3A3A3A3A9D3A % 9D9D9D9D9D9D9D3A3A3A9D3AFFFFFF3A3A9D9D3A9D9D9D9D7F7F7F7F3A3A % 3A3A3A9D9D9D9D3A9D3A9D3A9D9D3A9D9D3A9D9D9D3A3A9D3A9D9D3A9D3A % 9D3A3A3A3A3A3A3A3A3A3A3A9D9D3A9D9D3A9D3A3A9DFFFFFF9D9D9D9D9D % 9D3A3A9D3A9D3A9D9D3A9D3A9D3A9D3A9D3A9D3A3A3A3A3A3A3A9D3A9D9D % 9D3A9D3A3A3A9D3A9D3A9D3A3A3A9D3A9D3A3A3A9D9D3A9D9D3A3A3A9D3A % 9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D3A % 3A3A3A3A7F7F7F3A9D9D9D9D9D3A9D3A3A3A3A3A9D9D9D9D9D9D3A9D3A9D % 3A9D3A9D3A9D3A9D9D9D3A3A9D3A9D9D3A9D9D3A3A9D3A3A9D3A9D9D3A3A % 9DFFFFFFFF9D9D3A9D3A9D3A3A3A7F7F7F3A3A3A3A3A9D3A9D3A9D3A3A3A % 3A3A3A9D3A9D3A9D3A3A3A3A3A3A3A3A9D3A9D3A9D3A3A3A9D3A9D3A9D3A % 9D3A9D3A3A3A9D3A9D3A9DFFFFFF3A3A9D3A9D3A9D3A3A9D3A9D3A3A9D3A % 9D3A9DFF7D3A3A3A9D3A3A3A9D3A9D3A9D3A9D3A3A3A3A9D3A3A3A3A3A3A % 9D9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A9D9D9D9D9D9D9D9D % 3A9D9D3A3A9D3A9D3A3A9D9D3A9D9D9D9D9D9D3A3A3A3A7F7F7F7F3A3A3A % 9D9D9D3A9D3A9D3A3A3A3A3A9D3A3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A % 3A002100000000210018181818C518181010101012101210121012161818 % 18C5C51818C5C518181A1818181818161818C5C5C5C518181A181A181818 % 00FF1818181818181818171216181818181818181A181818181118121012 % 101010101010080E10101818181818181210121018101810121812101818 % 181817181218AF181618FF7D00000000000000003A3A3A3A3A3A3A9D3A9D % 9D9D9D9D9D3A9D3A3A3A3A9D9D3AFFFFFF9D9D9D7F7F7F7F3A3A3A3A3A3A % 3A3A9D9D9D9D9D9D9D3A3A3A9D3A9D3A9D9D3A9D9D9D3A9D3A3A9D3A9D3A % 3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A3A9D3AFFFFFF9D3A9D3A3A3A3A3A3A % 3A3A9D3A9D3A9D3A9D3A9D3A3A3A9D3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A % 9D3A9D3A9D3A3A3A9D3A3A3A9D3A9D9D3A3A9D3A3A9D3A9D3A3A9D3A9D3A % 9D3A9D3A3A9D3A9D9D3A9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D3A3A9D3A9D % 3A3A3A3A3A3A7F7F7F3A3A3A9D3A9D9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 9D3A3A9D3A3A9D3A3A9D3A9D3A9D3A9D9D3A9D3A9D3A3A9D9D9D3A9D9D9D % 9D3A9DFFFFFFFF3A9D9D7F7F7F3A3A3A3A3A3A9D3A3A9D3A3A9D9D3A3A3A % 9D9D9D3A9D3A9D3A9D3A3A3A3A3A9D9D9D9D3A3A3A3A9D3A9D3A9D3A9D3A % 9D3A3A3A9D9D3AFFFFFF3A9D3A9D3A9D3A9D3A9D9D9D3A9D3A3A3A9D3A9D % 9D3AFF7D9D9D9D3A3A9D9D3A9D9D3A9D9D3A3A9D3A9D3A9D3A3A3A9D3A9D % 3A9D3A9D3A9D3A9D3A9D3A9D9D3A3A3A3A3A3A3A9D9D3A3A9D3A9D3A3A3A % 9D9D3A3A3A9D3A3A9D3A9D9D3A9D9D9D3A9D9D3A3A3A3A3A3A7F7F7F7F9D % 3A9D9D9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 002100000000210016181818C51818181810121018101810121018181818 % C5C51818C5C518181818181818181818C5C51618C5C5181818181A181800 % FF18181818181A1818181812181818181818181818181618181612161810 % 121012101010101010101218161818181018181316131810121010121612 % 1818121618AF181818FF7D00000000000000003A3A3A9D3A3A3A9D3A9D9D % 3A9D3A9D9D9D3A3A3A3A9DFFFF535353FFFF7F1313137F7F3A3A3A3A3A9D % 3A9D9D9D3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D3A9D3A9D3A9D9D3A9D3A3A % 9D3A3A3A3A3A3A9D3A3A3A3A3A3A3AFFFF535353FFFF3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D % 9D3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D9D3A9D3A % 3A3A3A7F7F1313137F7F3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 9DFFFF535353FFFF7F1313137F7F3A3A3A3A9D3A3A3A3A3A3A3A3A9D9D3A % 3A3A9D3A9D3A3A9D3A3A3A9D9D3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D3A3A % 9D9D9D9DFFFF535353FFFF9D3A3A9D3A9D9D9D3A9D3A9D9D9D3A3A9D9D3A % 9DFF7D3A3A9D3A9D3A9D9D3A9D9D3A9D9D3A3A3A3A9D9D9D9D9D9D3A9D9D % 3A3A9D9D3A9D9D9D3A9D9D3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D9D9D % 9D9D3A3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A3A7F7F1313137F7F % 9D9D3A9DB2FF8B9D3A9D9D9D9D9D3A9D9D3A9D3A8BFF603A3A3A3A3A3A00 % 2100000000210018181018C51818181817181818121010121012121818C5 % C51818C5C5181818181818181A1818C5C51218C5C51818181818181800FF % 18181A181818181818181718181818121818181818121210121012101216 % 121012101210101010101012181613101216181812161210121010121618 % 18101818AF181818FF7D00000000000000003A3A3A9D3A3A3A9D3A9D9D3A % 9D3A9D9D9D3A3A3A3AFF53535353535353FF13131313137F3A3A3A3A9D3A % 9D9D9D3A9D9D9D9D9D9D9D3A3A9D9D9D9D9D3A9D3A9D3A9D9D3A9D3A3A9D % 3A3A3A3A3A3A9D3A3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D % 3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D9D3A9D3A3A % 3A7F131313131313137F3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF % 53535353535353FF13131313137F3A3A3A9D3A3A3A3A3A3A3A3A9D9D3A3A % 3A9D3A9D3A3A9D3A3A3A9D9D3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D3A3A9D % 9D9DFF53535353535353FF3A3A9D3A9D9D9D3A9D3A9D9D9D3A3A9D9D3A9D % FF7D3A3A9D3A9D3A9D9D3A9D9D3A9D9D3A3A3A3A9D9D9D9D9D9D3A9D9D3A % 3A9D9D3A9D9D9D3A9D9D3A3A3A3A3A3A3A9D3A3A9D3A9D3A9D3A9D9D9D9D % 9D3A3A9D9D3A9D3A9D9D9D9D3A9D9D9D9D3A3A3A3A7F131313131313137F % 9D3A9DE3E33A9D3A9D9D9D9D9D3A9D9D3A9D3A3AC8C83A3A3A3A3A3A0021 % 00000000210018181612C5181818181818161216121010101012101818C5 % C5C5C518181818181A181818181818C5C5C5C5181812181818181800FF18 % 18181818181A181818181818181818161818161810101010101010121012 % 181612101010100A10101210181810121818181018101010101010121810 % 181018AF161818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3A9D % 9D9D3A9D9D3A3A3AFF53535353535353FF13131313137F9D3A3A3A3A3A9D % 9D9D9D9D3A9D9D3A9D3A9D9D3A3A9D3A3A9D3A3A3A9D3A9D3A9D3A3A3A3A % 9D3A3A3A3A9D3A9D9D9D9D9DFF53535353535353FF9D9D9D9D9D9D9D3A9D % 9D9D9D9D9D9D3A9D9D9D9D3A3A3A9D3A3A3A3A9D3A9D9D9D3A9D3A3A3A9D % 9D9D9D9D3A3A3A3A9D9D3A3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D9D3A9D3A % 9D9D9D9D9D9D3A9D9D9D9D3A3A9D9D9D9D9D9D3A9D9D3A3A3A9D3A9D3A3A % 7F131313131313137F9D3A3A3A9D3A9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D % 9D9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D3A9D9D3A3A3AFF53 % 535353535353FF13131313137F3A9D3A3A9D3A9D9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A9D9D3A3A % 3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9DFF % 7D3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D9D3A3A9D3A9D3A3A9D9D3A9D9D9D % 9D9D3A3A9D3A9D9D3A9D9D3A9D9D3A9D3A3A3A3A7F131313131313137F9D % 9D82FF603A9D9D3A3A9D9D3A9D9D9D3A9D3A3A60FF823A3A3A3A3A002100 % 000000210018181818C51018181818161210181012101010101018161218 % 1818181A181818181818181A181818181818181818161818161800FF1818 % 18181A181818181818181818181818181818181818101012101010101018 % 121810181010101012161818181818161817181818181810101010101218 % 1810AF121818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D3A % 9D9D3A9D3A9DFF535353535353535353FF13131313137F3A3A3A3A3A9D9D % 9D3A9D9D9D3A9D3A9D9D3A9D9D9D9D3A9D3A3A3A9D3A9D9D9D3A3A3A3A3A % 3A3A3A3A9D3A9D9D9D9DFF535353535353535353FF3A9D9D9D9D3A3A9D3A % 9D9D9D9D3A3A3A9D9D9D3A3A9D3A3A3A3A3A3A9D9D9D3A3A9D3A3A3A3A9D % 9D9D3A3A9D3A9D9D3A3A9D3A9D9D9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A9D % 3A9D9D9D3A9D3A3A9D9D9D3A3A3A9D9D9D9D3A3A9D9D3A3A3A9D3A9D7F13 % 13131313131313137F9D9D3A3A3A9D9D9D9D9D3A3A9D3A9D3A3A3A9D3A9D % 9D9D3A3A9D9D9D9D9D3A3A3A9D3A3A9D9D9D3A3A9D9D9D9D9D3AFF535353 % 535353535353FF13131313137F9D3A9D9D3A3A9D9D9D3A3A9D9D9D9D9D9D % 9D9D9D3A3A3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D9D3A9D3A3AFF % 535353535353535353FF9D9D3A9D3A9D3A9D3A3A9D3A9D9D3A9D3A9DFF7D % 9D9D9D3A3A9D3A9D3A9D3A3A9D9D3A9D9D9D3A3A3A9D9D7F7F7F7F7F3A3A % 3A9D3A9D3A3A9D9D3A3A3A3A3A3A9D9D3A9D9D9D9D3A3A9D9D3A9D9D3A9D % 9D9D3A3A3A9D3A9D3A9D9D9D9D9D9D3A3A3A7F1313131313131313137FA3 % FFB19D3A3A9D3A9D9D9D9D9D9D9D3A9D3A9D3AB1FF483A3A3A3A00210000 % 0000210018181818C5101210121012101218161210101010101010101012 % 16181810181818181A1818181818181818181818181818181800FF181818 % 1A1E181A1818181612101218181818181818101810121010101010101218 % 171818101210101018181818181818181818171818161012101210121010 % 10AF101010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D3A9D % 9D3A9D3A9DFF535353535353535353FF13131313137F3A3A3A3A3A9D9D9D % 3A9D9D9D3A9D3A9D9D3A9D9D9D9D3A9D3A3A3A9D3A9D9D9D3A3A3A3A3A3A % 3A3A3A9D3A9D9D9D9DFF535353535353535353FF3A9D9D9D9D3A3A9D3A9D % 9D9D9D3A3A3A9D9D9D3A3A9D3A3A3A3A3A3A9D9D9D3A3A9D3A3A3A3A9D9D % 9D3A3A9D3A9D9D3A3A9D3A9D9D9D9D3A9D9D3A9D9D9D9D9D3A3A9D3A9D3A % 9D9D9D3A9D3A3A9D9D9D3A3A3A9D9D9D9D3A3A9D9D3A3A3A9D3A9D7F1313 % 131313131313137F9D9D3A3A3A9D9D9D9D9D3A3A9D3A9D3A3A3A9D3A9D9D % 9D3A3A9D9D9D9D9D3A3A3A9D3A3A9D9D9D3A3A9D9D9D9D9D3AFF53535353 % 5353535353FF13131313137F9D3A9D9D3A3A9D9D9D3A3A9D9D9D9D9D9D9D % 9D9D3A3A3A9D9D9D9D9D9D3A9D3A9D9D9D9D9D3A9D9D9D9D3A9D3A3AFF53 % 5353535353535353FF9D9D3A9D3A9D3A9D3A3A9D3A9D9D3A9D3A9DFF7D9D % 9D9D3A3A9D3A9D3A9D3A3A9D9D3A9D9D9D3A3A7F7F7F13131313137F7F7F % 9D3A9D3A3A9D9D3A3A3A3A3A3A9D9D3A9D9D9D9D3A3A9D9D3A9D9D3A9D9D % 9D3A3A3A9D3A9D3A9D9D9D9D9D9D3A3A3A7F1313131313131313137FC0FF % 609D3A3A9D3A9D9D9D9D9D9D9D3A9D3A9D3A60FF823A3A3A3A0021000000 % 00210010101012C512161216121810181012101010101010101010101012 % 1810181818181A1E181A181818161210121818181818181800FF1818181A % 181A18181812101210101012161218101818181010101010101010121612 % 181818181812181818181818181818181818181818181816121010121012 % AF101010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D % 9D9D3A9DFF535353535353535353FF13131313137F3A3A3A3A3A9D9D9D9D % 9D3A9D9D9D9D9D3A9D3A9D9D9D3A9D3A9D3A3A3A3A9D3A9D3A9D3A3A9D3A % 9D3A3A3A9D9D9D9DFF535353535353535353FF9D3A9D9D9D3A3A3A9D3A9D % 9D9D9D3A9D3A9D9D3A3A9D3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A3A9D9D3A % 3A9D3A9D9D9D3A3A9D3A9D9D9D3A3A9D3A3A3A9D9D9D9D3A9D9D3A3A9D9D % 9D9D3A3A9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D7F131313 % 1313131313137F9D9D3A3A9D3A9D9D9D9D3A3A9D3A9D3A9D9D3A9D9D9D9D % 3A3A9D3A9D9D9D3A3A9D9D3A9D3A9D9D3A3A9D9D9D9D3A3AFF5353535353 % 53535353FF13131313137F9D9D9D9D3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A % 3A9D3A3A3A3A9D3A9D3A9D9D9D3A9D9D9D3A3A3A9D3A3A9D3A9D3AFF5353 % 53535353535353FF9D3A3A9D3A9D9D9D3A3A3A9D9D9D9D3A3A9DFF7D9D9D % 3A9D3A9D9D9D9D3A3A9D9D3A9D9D3A3A9D7F13131313131313131313137F % 9D3A3A9D3A3A3A3A3A3A3A9D9D3A3A9D3A9D3A9D9D54C6FFFFDAB73A3A9D % 3A3A9DA6C0E3FFC8C0A39D9D3A3A3A3A7F1313131313131313137FC8E39D % 9D9D3AC6FFBD3A9D3A9D9DBDFFC63A3A3A3AC8C83A3A3A3A002100000000 % 210010101010C51012101210101012101210101210100810100F10101010 % 12181818181A181A18181812101210101012161218101800FF1818181A18 % 181A18181810101010121012101212161218101010100A10101010121818 % 18181818181818181A1818181818181618121818181818181012101018AF % 101010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D3A9D9D % 3A3A9D3AFF53535353535353FF13131313137F3A3A3A3A3A3A9D9D9D3A9D % 9D3A9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A % 3A3A3A9D9D9D9D3AFF53535353535353FF3A9D3A9D9D9D3A3A9D3A9D9D9D % 9D3A3A9D3A9D9D3A3A9D3A3A3A3A3A9D9D9D9D3A9D9D3A3A3A9D3A9D3A3A % 3A3A9D9D9D3A9D3A9D3A9D9D9D3A9D3A3A3A9D9D9D9D3A9D3A3A3A3A9D9D % 9D3A3A9D3A9D9D9D3A3A9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A3A7F131313 % 131313137F9D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D3A3A3A3A9D9D9D9D3A % 9D3A3A9D9D9D3A9D9D3A3A3A3A9D9D3A3A9D3A9D9D9D3A9DFF5353535353 % 5353FF13131313137F9D9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D9D9D3A3A9D % 9D9D3A3A3A3A9D9D3A3A9D3A3A9D9D9D3A3A9D9D3A3A9D9D9D3A3AFF5353 % 5353535353FF9D9D9D3A9D9D9D9D9D3A3A9D3A9D9D9D3A9D3AFF7D9D9D3A % 3A9D9D9D9D9D3A3A9D3A9D9D9D3A7F7F131313131313131313131313137F % 7F3A9D3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D3AB2FFFFFFFFFFFFD13A9D3A % 9DB2FFFFFFFFFFFFFFB23A3A3A9DA3FF7F131313131313137F60FFC69D3A % 9D3A3ADAFF549D9D9DA9FFC89D3A3A3A3A8BFF603A3A3A00210000000021 % 0010101010C51216131810181218161818181010100A100B101010101010 % 181818181A18181A181818101010101210121012121600FF1818181A181A % 18181818121012101012101010101210121818101010100810121618181A % 181A181818181A181818181818101212181618121218101816101018AF18 % 1818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D3A9D9D3A % 3A9D3AFF53535353535353FF13131313137F3A3A3A3A3A3A9D9D9D3A9D9D % 3A9D3A9D9D9D3A9D9D9D3A9D9D3A9D3A9D3A3A9D9D3A3A3A3A3A3A3A3A3A % 3A3A9D9D9D9D3AFF53535353535353FF3A9D3A9D9D9D3A3A9D3A9D9D9D9D % 3A3A9D3A9D9D3A3A9D3A3A3A3A3A9D9D9D9D3A9D9D3A3A3A9D3A9D3A3A3A % 3A9D9D9D3A9D3A9D3A9D9D9D3A9D3A3A3A9D9D9D9D3A9D3A3A3A3A9D9D9D % 3A3A9D3A9D9D9D3A3A9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A3A7F13131313 % 1313137F9D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D3A3A3A3A9D9D9D9D3A9D % 3A3A9D9D9D3A9D9D3A3A3A3A9D9D3A3A9D3A9D9D9D3A9DFF535353535353 % 53FF13131313137F9D9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D9D9D3A3A9D9D % 9D3A3A3A3A9D9D3A3A9D3A3A9D9D9D3A3A9D9D3A3A9D9D9D3A3AFF535353 % 53535353FF9D9D9D3A9D9D9D9D9D3A3A9D3A9D9D9D3A9D3AFF7D9D9D3A3A % 9D9D9D9D9D3A3A9D3A9D9D9D3A7F1313131313131313131313131313137F % 3A9D3A3A3A3A3A3A9D9D3A9D9D3A9D3A9D48FFFFB73A9DA9D1FF719D3AA3 % E3FF8BA33AA3C6FFE3483A3AB7FFA37F131313131313137F82FFB49D3A9D % 3A3AA9FFC89D9D9DDAFF599D3A3A3A3A66FF823A3A3A0021000000002100 % 18181010C512161216101316101818181818181010100E10101010101018 % 1818181A181A18181818121012101012101010101200FF10181818181818 % 181818161216121810181018101210101818161010101008101216181818 % 1818181A1818181818181810121010101218101010121012181818AF1818 % 1AFF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D9D9D3A % 3A9D3AFFFF535353FFFF7F1313137F7F9D9D9D9D3A9D3A9D9D3A9D3A9D9D % 9D9D9D9D3A3A9D9D3A3A9D9D3A3A9D3A3A9D3A9D9D3A3A3A3A9D3A3A3A3A % 3A9D9D9D9D3A3AFFFF535353FFFF9D3A3A9D9D9D9D3A3A9D3A3A9D9D9D9D % 3A3A3A3A9D3A3A3A3A3A9D3A3A9D9D9D3A3A9D3A3A9D3A3A9D3A3A3A9D9D % 9D9D9D3A3A9D3A9D9D9D9D3A3A9D3A9D3A9D9D9D3A9D9D3A3A9D9D9D9D3A % 3A3A3A3A9D3A3A3A3A9D9D9D9D3A3A3A9D9D9D3A3A3A9D3A3A7F7F131313 % 7F7F9D9D9D9D3A3A3A3A9D9D9D9D3A3A9D3A3A3A9D3A9D9D9D9D3A9D3A3A % 9D9D9D3A3A3A3A9D3A3A9D9D9D3A3A3A3A3A3A3A3A3A3AFFFF535353FFFF % 7F1313137F7F3A3A9D9D9D9D3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A9D3A3A % 9D3A3A3A3A9D3A3A3A3A9D9D9D3A3A9D9D3A3A9D9D9D9D9D3A9DFFFF5353 % 53FFFF3A9D9D3A3A9D3A3A9D9D3A9D3A3A9D9D9D3A9D3AFF7D9D9D3A9D3A % 9D9D9D9D3A9D3A3A9D9D9D7F13131313131313131313131313131313137F % 9D3A3A3A3A3A9D3A9D3A3A9D9D9D9D3A77FFC03A9D9D3AA3FFB19D9D77FF % CB9D9D9D9D3A96FFBD3A3AB1FF483A7F7F1313137F7F3ACBFF549D9D9D3A % 3A3ABDFFC69DBDFFC63A9D3A3A3A3A54FF963A3A3A002100000000210018 % 1A1818C51818121818181218181818181818161210101010101010101210 % 181818181818181818161216121810181018101200FF1012161818181818 % 101210121018181818181312101010101212181810121012101818181818 % 181818181A181818181012101010101216101012101210121018AF181818 % FF7D00000000000000003A3A3A9D3A3A3A9D3A9D9D3A9D3A9D3A9D9D3A3A % 9D3A3A9DFFFFFFFFFFFF7F7F7F9D3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A % 9D9D9D3A3A9D9D3A9D9D9D3A9D9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A % 9D9D9D9D9DFFFFFFFFFFFF9D9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A % 9D3A3A9D3A9D3A3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A3A9D9D3A9D3A9D9D % 9D9D3A3A9D9D3A9D9D9D3A9D9D9D3A9D9D9D9D3A9D3A3A9D3A9D9D9D3A3A % 9D3A3A3A9D3A3A3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D3A3A3A3A7F7F7F7F % 7F7F9D9D9D3A3A9D3A9D9D9D3A3A9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A % 9D9D3A3A9D9D9D3A9D3A9D9D3A3A9D3A9D9D9D3A3A3A3A3AFFFFFFFFFFFF % 7F7F7F3A3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D3A % 3A3A3A3A9D3A9D3A9D9D9D9D3A3A9D3A9D3A3A9D9D9D9D3AFFFFFFFFFFFF % 9D3A9D9D9D3A3A9D3A3A3A9D3A3A3A3A9D9D9D3A3A3AFF7D9D9D3A3A3A9D % 9D9D3A3A3A9D9D9D9D7F131313131313131313131313131313131313137F % 3A3A3A3A3A9D3A9D3A9D3A9D9D9D3AA3FF549D9D3A3A9D9D3A3A9DA3FFAF % 9D9D9D3A9DAFFFA33A3A3A3A3A3A3A3A7F7F7F7F7F7FFFFF9D9D9D9D9D3A % 9D3AD1FF77FFE39D3A9D3A3A9D3A3AFFFF3A3A3A00210000000021001818 % 1818C5101816181018181612101010121818181010101010101010101012 % 1618181818181012101210181818181813121000FF101218161818101010 % 101010101818181818181010101010101618181816101018181818181818 % 18181818181818101210101010101012101010121010121018AF121612FF % 7D00000000000000003A3A3A9D3A3A3A9D3A9D9D3A9D3A9D3A9D9D3A3A9D % 3A3A9D9DFFFF535353FFFF9D9D3A3A3A3A3A3A3A3A9D3A9D3A9D9D9D3A9D % 9D9D3A3A9D9D3A9D9D9D3A9D9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A9D3A9D % 9D9DFFFF535353FFFF9D9D9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A9D % 3A3A9D3A9D3A3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A3A9D9D3A9D3A9D9D9D % 9D3A3A9D9D3A9D9D9D3A9D9D9D3A9D9D9D9D3A9D3A3A9D3A9D9D9D3A3A9D % 3A3A3A9D3A3A3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D3A3A3A3A3A7F7F1313 % 137F7F9D3A3A9D3A9D9D9D3A3A9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A9D % 9D3A3A9D9D9D3A9D3A9D9D3A3A9D3A9D9D9D3A3A3A3A3A3AFFFF535353FF % FF3A3A3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D9D9D3A3A9D3A9D3A3A % 3A3A3A9D3A9D3A9D9D9D9D3A3A9D3A9D3A3A9D9D9DFFFF535353FFFF9D9D % 3A9D9D9D3A3A9D3A3A3A9D3A3A3A3A9D9D9D3A3A3AFF7D9D9D3A3A3A9D9D % 9D3A3A3A9D9D9D9D7F131313131313131313131313131313131313137F3A % 3A3A3A3A9D3A9D3A9D3A9D9D9D3AFFFF3A9D9D3A3A9D9D3A3A9DFFFF9D9D % 9D9D3A9D9DFFFF3A3A3A3A3A486082B17F7F1313137F7F9D9D9D9D9D3A9D % 3AA6FFFFFFAF9D3A9D3A3A9D3A3AFFFF3A3A3A0021000000002100161218 % 18C518181218181810181010101010101218101010121010101010101218 % 16181810101010101010181818181818101000FF10101012101012101010 % 101012181818181818181010080A10101012181818181818181818181218 % 181818171812181010101010101012181810101012161818AF181618FF7D % 00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D3A9D3A3A9D % 3A3AFF53535353535353FF9D9D9D3A9D9D9D9D3A9D3A3A9D9D3A9D9D9D9D % 3A3A9D9D3A9D3A9D9D3A3A9D9D3A9D3A9D9D3A3A3A3A3A3A3A3A3A9D3A9D % FF53535353535353FF9D9D9D3A9D3A9D9D9D3A3A9D3A3A9D9D9D3A9D9D3A % 3A3A3A9D3A3A3A3A3A3A9D9D9D3A3A9D3A3A3A3A9D3A9D3A3A9D9D9D9D9D % 3A3A9D3A3A9D9D3A3A9D3A3A9D3A9D9D9D3A3A9D3A3A3A9D9D9D3A9D9D3A % 3A9D3A9D3A9D9D9D9D9D3A3A9D9D9D9D9D3A9D3A3A3A3A3A7F1313131313 % 13137F9D3A9D3A9D9D9D9D3A9D3A9D3A3A3A3A9D9D9D3A3A9D3A9D3A9D9D % 3A3A3A9D3A3A9D3A9D9D3A9D9D3A3A9D3A9D9D3A9D9DFF53535353535353 % FF3A3A3A9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D9D9D9D3A9D9D3A3A9D9D3A % 9D3A9D9D3A3A3A9D9D9D9D3A9D9D3A3A3A9D9DFF53535353535353FF3A3A % 3A9D9D3A3A9D9D3A9D9D3A3A9D3A9D9D9D3A3A9DFF7D3A3A9D9D3A9D9D9D % 9D3A9D3A9D9D9D7F131313131313131313131313131313131313137F3A3A % 3A3A3A9D9D3A9D9D9D9D3A3A9DFFFF3A9D9D3A3A9D9D9D3A9DFFFF9D3A3A % 9D9D3A3AFFFF9D3A3A59A3FFFFFF7F131313131313137F9D3A9D9D9D3A3A % 9D96FFDA9D9D3A9D3A3A3A3A3AFFFF3A3A3A002100000000210016181618 % C51A18181810121818181812101010101018121610101210101010101012 % 101012101010101012181818181818181000FF1210121018101810101010 % 101012161818181A18181010101010101010101018181818181818161818 % 1818181018101210101010101218181818161210121018AF181818FF7D00 % 000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D3A9D3A9D3A3A9D % 3AFF53535353535353FF9D9D3A9D3A9D3A9D9D9D9D9D3A3A9D9D9D9D3A9D % 3A9D3A3A9D9D9D9D3A3A9D9D3A3A3A3A9D3A9D3A3A3A3A9D3A3A9D3A9DFF % 53535353535353FF9D9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A9D9D3A3A % 9D3A9D9D3A3A3A3A3A9D9D9D3A9D9D9D3A9D3A3A9D3A3A3A9D9D9D3A3A3A % 3A9D3A9D9D9D9D3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D9D3A3A9D3A9D % 3A3A9D3A9D9D9D9D9D3A3A9D9D9D9D3A3A3A9D3A3A3A9D7F131313131313 % 137F3A3A3A9D9D9D9D3A3A9D3A9D3A3A3A9D9D9D9D3A3A9D3A3A9D9D9D9D % 3A9D9D3A3A3A9D9D9D3A9D9D3A3A3A3A3A9D9D9D9DFF53535353535353FF % 9D3A3A9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A3A3A3A9D3A % 3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D9D9DFF53535353535353FF9D3A9D % 9D9D9D9D9D9D3A3A3A9D9D3A9D9D9D9D3A9D9DFF7D9D3A3A9D3A9D9D9D9D % 3A3A3A9D9D7F1313131313131313131313131313131313131313137F3A3A % 3A9D3A9D3A9D9D3A9D3A9D9DFFFF3A3A9D3A3A3A9D9D3A3AFFFF9D9D9D9D % 3A3A9DFFFF9D3A60FFFFFFFFB17F131313131313137F9D9D9D3A9D3A3AAF % FFFFFFB49D3A9D3A3A3A3A3AFFFF3A3A3A002100000000210018181818C5 % 181818181816181818181710101210121612101210101818101210121018 % 101810101010101012161818181A181800FF181818181818181810121210 % 121012181818181818181010101010101010101012161818181818181718 % 12161210121010121012181818181818181810121018AF181818FF7D0000 % 0000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D9D9D3A9D3A9D3A3A9DFF % 535353535353535353FF9D3A9D3A9D3A9D9D9D9D9D3A3A9D9D9D9D3A9D3A % 9D3A3A9D9D9D9D3A3A9D9D3A3A3A3A9D3A9D3A3A3A3A9D3A3A9D3AFF5353 % 53535353535353FF9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A9D9D3A3A9D % 3A9D9D3A3A3A3A3A9D9D9D3A9D9D9D3A9D3A3A9D3A3A3A9D9D9D3A3A3A3A % 9D3A9D9D9D9D3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D9D3A3A9D3A9D3A % 3A9D3A9D9D9D9D9D3A3A9D9D9D9D3A3A3A9D3A3A3A7F1313131313131313 % 137F3A3A9D9D9D9D3A3A9D3A9D3A3A3A9D9D9D9D3A3A9D3A3A9D9D9D9D3A % 9D9D3A3A3A9D9D9D3A9D9D3A3A3A3A3A9D9D9DFF535353535353535353FF % 3A3A9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A3A3A3A9D3A3A % 3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D9DFF535353535353535353FF3A9D9D % 9D9D9D9D9D3A3A3A9D9D3A9D9D9D9D3A9D9DFF7D9D3A3A9D7F7F7F7F7F7F % 7F7F7F7F7F1313131313131313131313131313131313131313137F7F7F7F % 7F7F7F7F7F7F3A9D3A9D9DA3FF543A9D3A3A3A9D9D3A3AA3FFAF9D9D9D3A % 3AAFFFA39D3AB1FF9660487F1313131313131313137F9D9D3A9D3A3AE3FF % B4E3E3A63A9D3A3A3A3A54FF963A3A3A002100000000210018181818C518 % 181818181811181218181818161210181018101818181818181818181818 % 18181012121012101218181818181800FF1A181818181818181818101010 % 101012181818181818101810121010101010101210181218181818181612 % 18101210101010101018181818181A181810101012AF121612FF7D000000 % 00000000003A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D9D9D3A9D3A3A9DFF53 % 5353535353535353FF3A9D9D3A9D9D9D3A9D3A3A9D3A9D3A9D9D9D3A3A9D % 3A3A9D3A9D9D3A3A9D9D3A9D3A9D3A3A3A3A3A9D3A3A9D3A3A9DFF535353 % 535353535353FF9D9D3A9D9D9D9D9D3A3A9D3A9D9D9D9D3A3A9D3A9D3A3A % 9D3A3A3A3A3A3A9D9D9D3A3A9D9D3A3A3A9D3A9D3A9D9D9D9D3A3A3A3A9D % 9D3A9D9D9D3A9D9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D9D3A3A9D3A9D3A3A % 3A9D3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D3A3A9D7F131313131313131313 % 7F3A3A3A9D9D9D9D3A9D9D9D3A3A9D9D9D9D3A3A9D9D9D3A9D9D9D3A3A9D % 3A9D3A3A3A9D9D3A3A9D3A9D3A3A3A3A9D9DFF535353535353535353FF3A % 3A9D9D9D9D3A3A9D9D9D9D9D9D3A3A3A9D9D9D3A3A9D3A9D3A3A9D9D3A3A % 9D3A3A9D9D9D3A9D9D3A3A9D3A9D9DFF535353535353535353FF3A3A9D9D % 3A3A9D9D3A9D3A3A3A3A9D9D9D9D3A9D3AFF7D9D9D3A3A7F7F7F7F7F7F7F % 7F7F7F7F1313131313131313131313131313131313131313137F7F7F7F7F % 7F7F7F7F7F9D3A9D9D9DBDFFC63A9D3A3A54FFDA9D9DBDFFCB9D3A9D3A3A % 96FFBD9D3AFFFF9D3A3A7F1313131313131313137F9D3A9D9D9D8BFFBD9D % 66FFD13A9D3A3A3A3A60FF823A3A3A002100000000210016121612C51210 % 1818181818101012101818181012101210121818181A181A181818181818 % 181818101010101012181818181800FF1818181818181818181818121010 % 101210121018101812101216181018121610101210181718181818181810 % 181012101010121818181A181818181818101010AF101010FF7D00000000 % 000000003A3A9D3A3A3A3A9D3A9D9D3A9D3A9D3A9D3A3A3A3A3A3AFF5353 % 53535353535353FF9D9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D3A3A3A9D9D3A % 9D3A9D9D3A3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3AFF53535353 % 5353535353FF9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A9D3A9D3A3A9D % 3A9D3A3A3A3A9D9D9D3A3A9D3A9D9D3A3A9D3A9D9D9D9D3A3A3A9D3A9D3A % 3A9D9D3A3A9D9D3A3A9D9D9D9D3A9D9D3A3A3A9D9D9D3A3A3A3A9D9D3A9D % 3A9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A3A3A3A7F1313131313131313137F % 9D3A3A9D9D9D3A3A3A9D9D3A3A9D9D9D9D3A3A3A9D9D3A3A9D9D9D3A3A9D % 9D3A3A9D9D9D3A3A3A3A9D9D3A3A3A9D9DFF535353535353535353FF3A3A % 3A9D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A3A9D3A3A3A9D3A3A3A3A % 9D9D9D9D9D3A9D3A3A3A9D9D9D9DFF535353535353535353FF3A9D9D9D3A % 3A9D9D3A9D9D3A3A9D9D9D9D9D3A3A9DFF7D9D9D3A3A3A9D9D9D3A3A3A9D % 9D9D7F1313131313131313131313131313131313131313137F3A3A3A9D3A % 9D9D9D9D3A9D9D3A9D48FFFFBD489D54A3FF719D9DA3E3FFC6A39D488BFF % E3A39D9DA3FF82A33A7F1313131313131313137F9D9D9D9DAFFFB19D9D9D % CBFF719D3A3A3A3A82FF603A3A3A002100000000210010101010C5101012 % 161818101210101018121210101810121018181818181818181818181818 % 1818181210101012101210181000FF1A1818181818181818181818181210 % 1010101010121010181012181818181A1810121018181818181818181818 % 17181012101216181818181A18181812101010AF101010FF7D0000000000 % 0000003A3A9D3A3A3A3A9D3A9D9D3A9D3A9D3A9D3A3A3A3A3A3A9DFF5353 % 5353535353FF9D9D9D3A3A9D9D9D9D3A9D9D3A3A9D9D9D3A3A3A9D9D3A9D % 3A9D9D3A3A3A9D9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A9DFF53535353 % 535353FF9D9D9D3A3A3A9D9D9D3A3A9D3A3A9D9D9D3A3A9D3A9D3A3A9D3A % 9D3A3A3A3A9D9D9D3A3A9D3A9D9D3A3A9D3A9D9D9D9D3A3A3A9D3A9D3A3A % 9D9D3A3A9D9D3A3A9D9D9D9D3A9D9D3A3A3A9D9D9D3A3A3A3A9D9D3A9D3A % 9D9D9D9D9D3A3A9D9D9D9D3A3A9D3A3A3A3A9D7F131313131313137F3A9D % 3A3A9D9D9D3A3A3A9D9D3A3A9D9D9D9D3A3A3A9D9D3A3A9D9D9D3A3A9D9D % 3A3A9D9D9D3A3A3A3A9D9D3A3A3A9D9D9DFF53535353535353FF9D3A3A3A % 9D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D9D3A3A3A9D3A3A3A9D3A3A3A3A9D % 9D9D9D9D3A9D3A3A3A9D9D9D9D9DFF53535353535353FF9D3A9D9D9D3A3A % 9D9D3A9D9D3A3A9D9D9D9D9D3A3A9DFF7D9D9D3A3A3A9D9D9D3A3A3A9D9D % 9D7F1313131313131313131313131313131313131313137F3A3A3A9D3A9D % 9D9D9D3A9D9D3A9D3AB2FFFFFFFFFFFFD13A9D9D9DB2FFFFFFFFFFFFE3B2 % 9D9D9D4EC8FFFFFFFF7F131313131313137F9D9D9D9D9DE3FF549D9D9D9D % E3FFA63A3A3A3AC8FF3A3A3A3A002100000000210010101010C510101012 % 1816181810121012101010101210181018161818181A1818181818181818 % 18181818121010101010101200FF18181818181012101817181818181810 % 121010121010121012161818181818181818101818181818181818181818 % 18181816181818181A181818181618181810AF101010FF7D000000000000 % 00003A3A3A3A3A3A3A9D3A9D9D9D3A9D3A9D3A3A3A9D9D3A9D3AFF535353 % 53535353FF9D9D3A9D3A3A9D3A3A9D9D9D9D3A9D9D3A3A9D3A9D9D3A3A3A % 3A9D9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A9D9D3A9D9DFF5353535353 % 5353FF9D9D9D3A9D3A9D9D9D3A3A9D3A3A9D9D9D3A3A9D3A9D9D3A9D9D3A % 3A3A3A3A9D9D9D9D3A3A9D3A9D3A3A9D3A9D9D9D3A3A9D3A3A3A3A9D3A9D % 9D9D3A9D9D9D3A3A9D9D9D3A9D9D3A3A3A9D9D9D3A3A9D3A9D9D3A3A3A3A % 9D9D9D9D3A3A9D9D9D9D3A9D3A3A3A3A9D9D7F131313131313137F3A9D3A % 3A9D9D9D9D3A9D9D3A3A3A9D9D9D9D3A3A9D9D9D3A3A9D9D3A3A9D9D3A3A % 3A3A9D9D3A3A9D9D9D9D9D3A3A9D9D9DFF53535353535353FF9D3A3A3A9D % 9D9D3A3A9D3A9D9D9D3A9D3A9D9D9D9D3A3A9D3A9D3A3A9D3A3A3A3A9D9D % 9D9D9D3A3A9D3A3A3A9D9D9D9DFF53535353535353FF3A9D9D9D9D3A3A9D % 3A9D9D9D3A3A9D3A9D9D9D3A9D9DFF7D9D9D9D3A3A9D9D9D9D3A3A9D3A9D % 9D7F131313131313131313131313131313131313137F3A3A9D3A3A3A9D9D % 9D3A9D9D3A9D9D3A9D548BC8FFB1B79D3A3A9D9D9DA682E3FFC8C0A63A9D % 9D3A9DA3C0B1FFFF7F131313131313137FB29D9D9DC6FF773A9D9D3A9DAF % FFDA3A3A3A60FF823A3A3A3A002100000000210010101010C51010101010 % 121818181818181612161216121012101218181818181818181012101817 % 181818181810121010121000FF1818111210101010121818181818181818 % 181210101210101210121810121618181818181818181A18181818181818 % 18181818181818181A1818181818181810AF101210FF7D00000000000000 % 003A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A9D3A9D9D3A3A3A7FFFFF5353 % 53FFFFFF9D9D9D3A3A9D9D9D9D9D9D3A9D9D9D9D3A3A3A9D9D9D3A9D3A9D % 9D3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A9D9D9D3AFFFFFFFF535353FF % FF9D9D9D9D3A3A3A9D9D9D3A3A3A3A9D9D9D9D9D3A3A9D9D3A3A3A3A3A3A % 3A3A9D9D9D9D3A3A3A3A3A9D9D3A3A9D9D9D9D3A9D3A9D9D3A3A3A3A9D9D % 9D3A9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D9D9D3A3A3A3A9D9D3A9D3A3A9D % 9D9D9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A9D7F7F1313137F7F7F7F9D9D3A % 9D9D9D3A9D9D9D9D3A3A9D9D9D3A9D3A3A9D9D9D3A9D9D9D3A9D9D9D3A3A % 3A9D9D3A3A3A9D9D9D3A3A9D9D9D9D7FFFFF535353FFFFFF3A3A3A3A9D9D % 9D9D3A3A3A9D9D9D3A3A9D3A9D9D9D3A3A3A9D9D3A3A3A3A9D3A3A3A3A9D % 9D3A3A3A3A3A9D9D9D9D9D9DFFFFFF535353FFFF3A9D9D3A9D9D3A3A9D3A % 9D9D9D3A3A9D3A9D9D9D3A3A3AFF7D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D % 7F131313131313131313131313131313131313137F3A3A3A3A3A9D9D3A9D % 9D3A9D9D9D9D9D3A3A9D9D3A3A9D3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D % 3A9D3A3A9D9D9D9D7F7F1313137F7F7FDA3A9D3A3A3A3A3A9D9D3A9D9D3A % 9D9D3A3ADAFF483A3A3A3A002100000000210012101012C5101010101018 % 181820191818181818181818101010121012181818111210101010121818 % 1818181818181812101000FF181818161812181612101212181818181018 % 101813181818181612161818181818181818181A181818181A1818181812 % 10131618181818181818181210121012AF121618FF7D0000000000000000 % 3A3A3A3A3A3A3A9D3A9D9D9D9D9D9D9D3A9D3A9D9D3A7F7F131313FFFFFF % 535353FFFF9D3A3A9D9D9D9D9D9D3A9D9D9D9D3A3A3A9D9D9D3A9D3A9D9D % 3A9D9D9D9D3A9D9D3A9D3A3A3A3A3A3A3A9D9DFFFF535353FFFFFFFF3A3A % 9D9D9D9D3A3A3A9D9D9D3A3A3A3A9D9D9D9D9D3A3A9D9D3A3A3A3A3A3A3A % 3A9D9D9D9D3A3A3A3A3A9D9D3A3A9D9D9D9D3A9D3A9D9D3A3A3A3A9D9D9D % 3A9D9D9D9D9D9D9D9D3A9D9D3A3A3A9D9D9D3A3A3A3A9D9D3A9D3A3A9D9D % 9D9D3A3A9D9D3A9D3A3A3A3A3A3A3A3A9D9D3A7F7F7F7F1313137F7F3A9D % 9D9D3A9D9D9D9D3A3A9D9D9D3A9D3A3A9D9D9D3A9D9D9D3A9D9D9D3A3A3A % 9D9D3A3A3A9D9D9D3A3A9D9D7F7F131313FFFFFF535353FFFF3A3A9D9D9D % 9D3A3A3A9D9D9D3A3A9D3A9D9D9D3A3A3A9D9D3A3A3A3A9D3A3A3A3A9D9D % 3A3A3A3A3A9D9D9D9DFFFF535353FFFFFF9D3A3A9D9D3A9D9D3A3A9D3A9D % 9D9D3A3A9D3A9D9D9D3A3A3AFF7D9D9D3A3A3A9D9D9D9D3A3A9D3A9D9D7F % 131313131313131313131313131313131313137F3A3A3A3A3A9D9D3A9D9D % 3A9D9D9D9D9D3A3A9D9D3A3A9D3A3A3A3A3A9D9D9D3A3A9D3A3A9D3A9D3A % 9D3A3A9D9D9D9D9D9D7F7F7F1313137F7F9D3A3A3A3A3A9D9D3A9D9D3A9D % 9D3A60FF823A3A3A3A3A002100000000210016181818C510101010101018 % 181818181818181810181818181012101018181818161812181612101212 % 18181818101810181300FF10181018101818181818101618181818181818 % 181816181212101210121818181818181818181818181818181A18181618 % 181818181818181818AFAFAFAFAFAFAF121018FF7D00000000000000003A % 3A3A9D3A3A3A9D3A9D9D3A9D3A9D3A9D3A9D3A3A7F1313131313FF535353 % 53535353FF9D9D9D9D9D3A9D9D9D9D9D3A3A3A3A9D9D9D9D3A9D3A9D3A3A % 3A9D9D9D3A3A9D9D9D3A9D3A3A3A3A3A9DFF53535353535353FF9D9D9D9D % 9D9D9D3A3A9D9D9D9D9D3A3A9D9D9D9D9D9D3A3A9D9D3A9D3A3A3A3A3A3A % 3A9D9D9D9D3A3A9D9D9D9D3A3A9D9D9D3A9D3A9D9D9D9D3A3A9D9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D9D3A9D3A9D9D9D3A3A9D9D9D9D9D % 9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D9D3A3A7F131313131313137F9D9D % 9D9D9D9D9D9D3A3A3A9D9D3A3A3A3A9D9D9D9D9D9D3A9D9D9D3A3A3A9D9D % 9D3A3A3A9D9D9D3A9D3A7F1313131313FF53535353535353FF3A9D3A9D9D % 3A3A3A9D9D3A3A3A3A3A9D9D9D3A3A3A9D9D3A9D3A3A3A3A3A3A9D9D9D3A % 3A3A9D9D3A9D9DFF53535353535353FF3A3A3A3A3A3A9D9D3A3A3A3A9D9D % 9D3A9D3A3A9D9D9D3A3A3AFF7D9D9D3A9D3A9D9D9D9D3A3A3A9D3A9D9D7F % 13131313131313131313131313131313137F3A3A3A3A3A3A9D3A3A9D9D9D % 9D9D9D9D9D9D9D3A9D3A3A3A9D9D9D9D3A9D9D9D9D3A9D9D9D9D9D3A9D3A % 3A9D9D3A3A9D9D9D7F131313131313137F3A3A9D9D9D9D9D9D9D9D3A9D3A % 3AC8C83A3A3A3A3A3A002100000000210010181018C51012101010121012 % 101217181818101818181810121010101810181018101818181818101618 % 181818181818181800FF1012121212101018181818181210121018121612 % 161210101010101010101018181818181818181818181A18181818181818 % 1818181818181818181818131010AF101210FF7D00000000000000003A3A % 3A3A3A9D3A9D3A9D9D9D9D9D9D3A9D3A3A3A9D7F1313131313FF53535353 % 535353FF3A9D9D9D3A9D9D9D9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A3A3A % 9D9D9D3A9D9D3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A3A9D3A9D % 3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D3A9D3A % 3A9D3A9D3A3A3A3A9D3A3A9D3A9D3A3A3A3A9D3A9D3A3A9D3A3A9D3A3A3A % 3A3A3A3A9D3A3A3A9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A9D9D3A % 9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D7F131313131313137F3A9D3A % 9D3A3A9D3A3A3A9D3A9D3A3A3A3A3A9D3A9D3A3A9D9D3A9D9D3A9D9D9D9D % 9D9D9D9D3A9D3A3A3A7F1313131313FF53535353535353FF3A3A3A9D3A3A % 3A9D3A9D3A3A9D3A9D3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3AFF53535353535353FF9D3A9D3A9D3A9D3A3A3A3A9D3A9D9D % 3A9D3A9D3A9D9D3A9D3AFF7D3A9D3A9D3A9D9D9D9D9D3A3A3A9D3A3A9D7F % 1313131313131313131313131313137F3A3A3A3A3A3A9D3A9D9D3A9D9D9D % 3A9D9D9D9D3A9D3A9D3A3A9D9D9D3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D % 3A3A9D9D3A9D9D7F131313131313137F3A9D3A9D9D9D3A9D9D9D3A9D3A8B % FF593A3A3A3A3A3A002100000000210012101218C5101010101010101012 % 181812181618101210121010101010121012121212101018181818181210 % 1210181216121600FF121010101010121810181818161010121010101210 % 12161210101010101010101210161818181818181A1820181A1818181818 % 18181818181818181818161810AF101010FF7D00000000000000003A3A3A % 3A3A9D3A9D3A9D9D9D9D9D9D3A9D3A3A3A7F1313131313FF535353535353 % 535353FF9D9D9D3A9D9D9D9D3A3A9D3A3A9D9D9D9D9D3A9D3A9D3A3A3A9D % 9D9D3A9D9D3A3A3A3A3A3A3A3A3AFF535353535353535353FF3A9D3A9D3A % 3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A9D3A9D3A3A % 9D3A9D3A3A3A3A9D3A3A9D3A9D3A3A3A3A9D3A9D3A3A9D3A3A9D3A3A3A3A % 3A3A3A9D3A3A3A9D3A9D3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A9D9D3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D7F1313131313131313137F9D3A9D % 3A3A9D3A3A3A9D3A9D3A3A3A3A3A9D3A9D3A3A9D9D3A9D9D3A9D9D9D9D9D % 9D9D9D3A9D3A3A7F1313131313FF535353535353535353FF3A3A9D3A3A3A % 9D3A9D3A3A9D3A9D3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3AFF535353535353535353FF3A9D3A9D3A9D3A3A3A3A9D3A9D9D3A % 9D3A9D3A9D9D3A9D3AFF7D3A9D3A9D3A9D9D9D9D9D3A3A3A9D3A3A9D7F7F % 131313131313131313131313137F7F3A3A3A3A3A3A9D3A9D9D3A9D9D9D3A % 9D9D9D9D3A9D3A9D3A3A9D9D9D3A3A3A9D3A9D3A9D9D9D9D9D9D9D9D9D3A % 3A9D9D3A9D7F1313131313131313137F9D3A9D9D9D3A9D9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A002100000000210010101210C512121012101012101012 % 101817121210181618101210101010121010101010121810181818161010 % 12101010121000FF10101012101210101218181810121012161218121612 % 101010101008100E1010101012121618181818181A181818181818181818 % 181818181818181818181810AF101010FF7D00000000000000003A3A3A3A % 3A3A3A9D3A9D9D9D3A9D9D3A9D3A3A9D7F1313131313FF53535353535353 % 5353FF9D9D9D9D9D9D9D9D3A3A9D3A9D9D9D9D9D9D3A9D9D9D3A3A3A9D9D % 9D3A3A9D3A9D3A3A3A3A3A3A3AFF535353535353535353FF3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A % 9D3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A7F1313131313FF535353535353535353FF3A3A3A3A9D9D3A % 3A3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A % 3A9D3AFF535353535353535353FF9D3A9D3A9D9D9D9D9D9D9D9D9D3A3A9D % 3A9D3A9D3A9D9D3AFF7D3A3A3A9D3A3A9D3A9D9D9D3A3A3A3A9D3A3A9D7F % 13131313131313131313137F3A3A3A3A3A3A3A3A3A9D3A3A9D3A9D9D9D9D % 9D3A3A9D9D9D3A3A9D3A9D3A9D3A3A9D9D3A9D3A9D9D9D9D3A9D3A9D3A9D % 9D9D9D9D7F1313131313131313137F9D3A9D9D9D9D9D9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A002100000000210010101012C51817181612101010121618 % 181818101618181816181618181010101012101210101218181810121012 % 161218121600FF1012101010101010101012181818181012101010101210 % 1210101010101010101010101012181818181A18181A1818181818171818 % 1216181818181816181810AF101008FF7D00000000000000003A3A3A3A3A % 3A3A9D3A9D9D3A9D9D9D3A3A9D3A9D7F1313131313FF5353535353535353 % 53FF3A3A9D3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A9D9D9D3A3A9D9D9D9D % 3A3A9D3A3A3A3A3A9D3A3A3AFF535353535353535353FF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A7F1313131313131313137F3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F1313131313FF535353535353535353FF3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3AFF535353535353535353FF3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A9D3A3A3A9DFF7D3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A7F % 7F7F13131313137F7F7F3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A9D9D3A9D9D % 3A3A9D9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D % 9D9D3A7F1313131313131313137F9D3A9D3A9D3A3A9D9D3A9D3A3A3A9D3A % 3A3A3A3A3A002100000000210010081010C5181818181818181613181818 % 181818121818181818181818101012101010101010101012181818181012 % 1010101000FF121010121012101210121010121612161216121813181718 % 101210101010101010101010101816181818181A18181818181812101210 % 12181217181818121810AF100810FF7D00000000000000003A3A3A3A3A3A % 3A9D3A9D9D3A9D9D9D3A3A9D3A9D3A7F1313131313FF53535353535353FF % 9D3A3A9D3A3A3A3A3A3A9D3A9D9D9D9D9D3A9D3A9D9D9D3A3A9D9D9D9D3A % 3A9D3A3A3A3A3A9D3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A7F1313131313FF53535353535353FF3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3AFF53535353535353FF3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A9D3A3A3A9DFF7D3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A7F7F7F7F7F3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A9D3A9D9D3A9D9D3A % 3A9D9D3A9D3A3A9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D3A9D7F131313131313137F9D9D3A9D3A9D3A3A9D9D3A9D3A3A3A9D3A3A % 3A3A3A3A002100000000210008101010C51818181A18181A181818181A18 % 181818181818181818181810121010121012101210121010121612161216 % 12181300FF10101210101210181210121010121018181818181618181818 % 1610101010100A0E10101212181218181818181818181818101012101010 % 121618121612181610AF10080AFF7D00000000000000003A3A3A3A3A3A3A % 9D3A9D9D9D9D9D9D3A9D9D3A3A3A7F1313131313FF535353535353FFFFFF % 9D9D3A9D3A9D9D3A9D3A9D9D9D3A9D9D9D9D9D9D9D3A9D9D3A9D3A9D3A9D % 3A9D3A9D3A3A3A3A9D3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313137F7F7F3A3A3A3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A7F7F1313131313FF5353535353FFFFFF3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A % 3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A % 3A9D3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A9D9D3A9D9D9D9D3A3A9D % 3A9D9D9D3A3A9D3A9D9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D % 9D9D7F13131313137F7F7F9D9D3A3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A % 3A3A3A0021000000002100080A1010C51818181820181818181818181818 % 181812101210181216181010101210101210181210121010121018181818 % 181600FF12181018181818181A1818181810101818161216121012101218 % 181818121010101010101010101818181818181818101018121816121612 % 1012101210101218AF101010FF7D00000000000000003A3A3A9D3A3A3A9D % 3A9D9D3A9D9D9D3A9D3A3A7F7F137F7F1313137FFFFF5353FFFF535353FF % FF9D9D3A3A3A3A9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D9D9D9D9D3A3A9D % 9D3A9D9D3A3A3A3AFFFF53FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F137F7F1313137F7F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D3A3A % 7F7F13137F7F1313137FFFFF53FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF % 53FFFF535353FFFF3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D3A9D3A3A9D3A % 9D9D9D3A9D9D9D9D9D9D3A3A9D3A9D9D3A9D9D3A9D3A3A9D9D9D9D9D9D9D % 9D3A7F7F137F7F1313137F7F9D9D3A9D9D9D9D9D3A9D3A3A3A3A3A9D3A3A % 3A3A002100000000210010101010C51816181A181A181A18181A181A1816 % 1210101210121012101812181018181818181A1818181810101818161216 % 1200FF101012101818181818181A18181218181818181812101810101218 % 181010101010101010101210121618181818161210121018101818181810 % 18101210121012AF121010FF7D00000000000000003A3A3A9D3A3A3A9D3A % 9D9D3A9D9D9D3A9D3A7F13131313137F7F7F9D9D3AFFFF53535353535353 % FF9D3A3A3A3A9D9D9D3A9D9D9D9D9D9D3A9D9D3A3A9D9D9D9D9D3A3A9D9D % 3A9D9D3A3A3AFF5353535353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A7F131313131313137F3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A9D3A7F13 % 13131313137F7F7F3A3A9DFF53535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 5353FFFFFF3A9D3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D9D3A9D3A3A9D3A9D % 9D9D3A9D9D9D9D9D9D3A3A9D3A9D9D3A9D9D3A9D3A3A9D9D9D9D9D9D9D9D % 3A9D3A7F131313131313137F9D3A9D9D9D9D9D3A9D3A3A3A3A3A9D3A3A3A % 3A002100000000210010101010C5C5C5C5C5C5C518181A181A1818181812 % 101210121012101812101012101818181818181A18181218181818181812 % 00FF10121010121012181818181818181818181818181718131010101010 % 121010101010101010101210101212121012101010121012181818181818 % 101210101010AF121818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D % 9D9D9D9D9D3A9D9D7F131313131313137F9D3A9D3AFF53535353535353FF % 3A9D3A9D9D3A9D9D9D9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D3A3A9D3A3A % 3A3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313137F3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313 % 13131313137F3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A9D3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A9D9D9D9D3A3A9D9D3A3A % 9D3A9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A7F131313131313137F3A3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A % 002100000000210018181813C5181818181A181818181818181818181010 % 101010101012101010121010121012181818181818181818181818181700 % FF1810101210101818181818181818181818181818181816101012101010 % 101010101010101210101210121010121010101010101216181818181818 % 1010101010AF101018FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D % 9D3A9D9D3A9D7F1313131313131313137F9D3AFF535353535353535353FF % 3A9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D3A3A3A9D3A3A9D % 9D9D9DFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D3A9D9D3A9D9D3A9D3A9D % 3A9D3A9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A9D3A9D3A9D3A9D9D3A9D3A3A % 9D3A3A9D3A9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D9D3A9D3A9D3A % 9D3A9D3A3A9D3A9D3A9D3A7F1313131313131313137F9D3A3A3A3A3A3A3A % 3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313 % 13131313137F3A3AFF535353535353535353FF3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3AFF535353535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A3A3A9D9D9D3A9D % 9D9D9D9D9D9D3A9D3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D % 7F1313131313131313137F3A9D9D9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A00 % 2100000000210010181816C5181818181818181818181818181810101010 % 1010101210101818101012101018181818181818181818181818181800FF % 181818101612181018181818181818181818181818181818181010121018 % 181010101210101012101010101210101210101010101218181818181810 % 12101010AF0A1010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D % 3A9D9D3A9D7F1313131313131313137F9D3AFF535353535353535353FF3A % 9D9D9D9D9D9D9D9D9D3A9D9D9D3A9D3A9D9D9D9D9D9D3A3A3A9D3A3A9D9D % 9D9DFF535353535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D3A9D9D3A9D3A9D9D9D9D3A9D3A9D9D3A9D9D3A9D3A9D3A % 9D3A9D9D3A3A9D9D3A9D3A9D9D3A9D3A3A9D3A9D3A9D3A9D9D3A9D3A3A9D % 3A3A9D3A9D3A9D3A9D3A3A9D3A9D3A9D3A3A9D3A9D3A9D9D3A9D3A9D3A9D % 3A9D3A3A9D3A9D3A9D3A7F1313131313131313137F9D3A3A3A3A3A3A3A3A % 9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313131313 % 131313137F3A3AFF535353535353535353FF3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3AFF53535353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % FF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A9D9D9D3A3A3A9D9D9D3A9D9D % 9D9D9D9D9D3A9D3A3A9D3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A9D9D9D7F % 1313131313131313137F3A9D9D9D9D9D3A9D3A9D3A3A3A3A3A3A3A3A0021 % 00000000210010101012C518181818181818181718181818121012101010 % 12101018181818181810161218101818181818181818181818181800FF1A % 181812121210181012121018181818181818181216181818101210181818 % 101018101818181816121012101012161010101010121818181818181012 % 101010AF100810FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D % 9D9D3A9D7F1313131313131313137F3A3AFF535353535353535353FF3A9D % 3A3A3A9D9D9D9D9D9D9D9D9D3A3A9D9D3A9D3A3A9D9D3A3A9D9D3A3A3A3A % 3AFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A7F1313131313131313137F3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 1313137F3A9DFF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A9D3A3A3A3A3A3A3A3A9D3A9D3A9D9D3A3A9DFF5353535353535353 % 53FF3A9D3A9D3A9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D9DFF % 7D9D9D9D9D9D3A9D9D9D9D9D3A9D9D9D9D3A9D3A9D3A9D3A9D3A9D3A9D9D % 3A9D9D3A9D9D3A9D9D3A9D3A9D9D3A9D3A9D9D9D9D3A3A9D9D9D9D3A3A9D % 9D9D9D3A9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A3A3A9D9D9D9D3A9D7F13 % 13131313131313137F3A9D9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A3A002100 % 000000210008101010C51818171818181818181818181612101010101010 % 12181818181A181812121210181012121018181818181818181200FF1818 % 121010101012101010121012181818171818161812181012121012121818 % 1818181818181A1818181010181818101210101010101818181818161217 % 1210AF101010FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3A3A9D % 9D3A9D9D7F131313131313137F9D3A3A9DFF53535353535353FF9D3A3A9D % 9D9D9D3A9D9D9D9D3A9D3A9D9D9D3A9D3A9D3A9D9D3A3A9D9D9D9D9D9D9D % 9DFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D9D3A9D3A3A9D9D3A9D9D9D9D3A9D % 3A9D3A3A9D3A3A9D3A3A9D3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A3A9D % 3A3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D3A9D3A3A % 9D3A3A9D3A3A9D3A9D7F131313131313137F3A3A3A9D3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F131313131313 % 137F3A3A3A3AFF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF7D % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3A9D9D3A9D9D3A9D3A % 9D9D9D9D9D3A9D9D9D9D9D9D3A3A9D9D9D3A3A3A9D3A3A9D9D60FF8B7F13 % 1313131313137F9D3A9D9DC6FFB23A9D3A3A3A3A3A3A3A3A3A3A00210000 % 0000210010101010C5101218181818181818111813181010101010101218 % 1818181A18181210101010121010101210121818181718181600FF181810 % 101010101210101010101216181818181012101210101010101010101818 % 181818181818181818181818181818101010101012181818181818181818 % 10AF181210FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D3A3A9D9D % 3A9D9D7F131313131313137F9D3A3A9DFF5353535353FFFFFF9D3A3A9D9D % 9D9D3A9D9D9D9D3A9D3A9D9D9D3A9D3A9D3A9D9D3A3A9D9D9D9D9D9D9D9D % FF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D9D3A9D3A3A9D9D3A9D9D9D9D3A9D3A % 9D3A3A9D3A3A9D3A3A9D3A3A3A9D3A3A9D3A9D3A3A3A3A3A3A9D3A3A9D3A % 3A3A9D3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A9D3A9D3A3A9D % 3A3A9D3A3A9D3A9D7F13131313137F7F7F3A3A3A9D3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F13131313131313 % 7F3A3A3A3AFF5353535353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53535353535353FF3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF7D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D9D9D9D9D9D3A3A9D9D3A9D9D3A9D3A9D % 9D9D9D9D3A9D9D9D9D9D9D3A3A9D9D9D3A3A3A9D3A3A9D9DC8E33A7F1313 % 1313137F7F7F9D3A9D9D9DE3E33A9D3A3A3A3A3A3A3A3A3A3A0021000000 % 00210012101010C510101818181818181818181810121010101012161818 % 181A1818181010101010121010101010121618181818101200FF18181810 % 10080810101010100B0E0A10101618181818181810181316121612161210 % 121618181818181818161218101818181818161010101012101010121010 % AF121818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D9D3A9D9D % 7F7F137F7F1313137F7F9D9D3A3A9D9DFFFF53FFFF535353FFFF9D9D3A9D % 9D9D9D3A9D9D9D3A9D9D3A9D9D9D3A9D3A9D9D3A9D9D9D9D3A9D9DFFFF53 % FFFF535353FFFF9D9D9D3A9D3A9D9D3A9D9D9D9D9D9D3A9D3A9D9D3A9D9D % 9D9D9D9D3A9D9D3A3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D7F7F137F7F1313137F7F9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D7F7F137F7F1313137F7F9D % 9D9D9D9D9DFFFF53FFFF535353FFFF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFF53FFFF535353FFFF9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF7D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D3A3A9D3A9D3A9D9D3A9D9D3A % 9D9D9D9D9D9D9D3A9D3A9D9D9D3A9D9D9D9D9D9D9D9DC0FF609D3A7F7F13 % 7F7F1313137F7F9D9D9DB2FF829D3A3A3A9D3A3A3A3A3A3A002100000000 % 210018181618C51010181618181A1818181310101810181012181818181A % 18181818181010080810101010100B0E0A10101618181800FF1818181612 % 101010101010101010101010121818181818161018101612171218101210 % 1218181818181818181018101818181818181818101210101210101010AF % 161818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D9D7F13 % 131313137F7F7F3A9D3A9D3A3A9D9D9D3AFF53535353535353FF9D3A9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D9D9D9D9DFF53535353 % 53FFFFFF9D9D3A3A9D9D3A9D9D9D3A9D9D9D3A9D9D3A9D9D9D3A9D9D3A9D % 9D3A9D9D9D9D3A3A9D9D3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A9D3A3A9D3A9D3A9D9D9D3A9D3A9D3A9D3A3A3A3A3A3A9D3A % 3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A9D3A3A9D9D3A9D3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A % 9D3A9D9D3A9D3A9D3A9D9D9D9D9D9D3A9D7F13131313137F7F7F9D9D9D9D % 9D9D9D9D9D9DFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF5353535353FFFFFF9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF7D9D9D9D % 3A9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9D9D9D9DFFFFFFFFFF3A9D3A9D9D % 9D9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D3A3A9D9D3A9D3A9D9D9D9D9D9D % 3A3A9D9D3A9D3A9D9D3A9D9D9D9D9D3A9D3A9D9DA3FFDA3A9D3A3A9D7F13 % 1313131313137F9D3A9DDAFFA33A3A3A3A3A3A3A3A3A3A00210000000021 % 0018181818C518181818181818181818181012101218161216181818181A % 1818181816121010101010101010101010101218181800FF181618181818 % 181012101010101010101010121618181818121812181218121012101210 % 12101818181618181018121012101818181818121010121012101210AF12 % 1818FF7D00000000000000003A3A3A3A3A3A3A9D3A9D9D9D3A9D9D7F1313 % 13131313137F3A9D3A9D3A3A9D9D9D3AFF53535353535353FF9D3A9D3A9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D9D9D9D9D9DFF5353535353 % 5353FF9D9D3A3A9D9D3A9D9D9D3A9D9D9D3A9D9D3A9D9D9D3A9D9D3A9D9D % 3A9D9D9D9D3A3A9D9D3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A9D3A3A9D3A9D3A9D9D9D3A9D3A9D3A9D3A3A3A3A3A3A9D3A3A % 3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A % 9D3A3A9D9D3A9D3A7F131313131313137F3A3A3A3A3A3A3A3A3A3A9D3A9D % 3A9D9D3A9D3A9D3A9D9D9D9D9D9D3A9D7F131313131313137F9D9D9D9D9D % 9D9D9D9D9DFF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF53535353535353FF9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF7D9D9D9D3A % 9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9DFFFFFF5353535353FFFFFF9D9D9D % 9D9D9D9D9D9D9D9D9D3A9D9D3A9D9D9D3A3A9D9D3A9D3A9D9D9D9D9D9D3A % 3A9D9D3A9D3A9D9D3A9D9D9D9D9D3A9D3A9D9DC0FFB23A9D3A3A9D7F1313 % 13131313137F9D3A9DB2FFC03A3A3A3A3A3A3A3A3A3A0021000000002100 % 18181818C5181818181818181818181818131618101218181818181A1818 % 18161818181818101210101010101010101012161800FF18121216181818 % 12161210101010100A0F1010121818181618171816181618101210101010 % 121018181812161218101010181818181818121612181018101810AF1012 % 16FF7D00000000000000003A3A3A3A3A3A3A9D3A9D3A9D9D9D7F13131313 % 13131313137F3A9D9D3A3A3A9D3AFF535353535353535353FF9D9D3A9D3A % 9D9D9D9D9D3A9D3A9D3A9D9D9D3A9D3A3A9D9D9D9D9DFF53535353535353 % 5353FF9D9D9D9D9D9D3A9D9D9D9D9D9D9D9D3A9D3A9D3A9D9D9D9D9D9D3A % 9D3A9D3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D9D9D9D3A3A3A3A3A9D9D3A3A % 3A9D9D3A3A3A3A3A9D3A3A3A3A3A9D9D3A3A3A3A3A9D9D3A3A3A9D9D9D3A % 3A3A3A9D9D3A3A3A3A9D9D3A3A9D9D3A3A3A3A3A3A9D9D9D3A3A3A9D9D3A % 3A3A9D9D9D9D7F1313131313131313137F3A9D3A3A3A3A3A9D9D3A3A3A3A % 9D3A3A9D9D9D9D3A3A3A3A9D9D3A7F1313131313131313137F3A3A3A3A3A % 3A9D3AFF535353535353535353FF3A9D9D9D3A3A3A3A3A3A9D3A3A3A3A3A % 9D9D9D3A3A3A3A9D9D3A3A3AFF535353535353535353FF3A3A9D9D9D9D9D % 3A3A3A3A3A3A9D9D3A3A3A3A9D3A3A9D3A3A3A3A9D9D9DFF7D9D3A9D9D3A % 9D9D3A9D9D3A9D9D3A9D9D3A3A9DFF5353535353535353535353FF9D9D9D % 9D3A9D3A9D9D9D9D9D9D9D3A9D9D9D3A3A9D71D1FFFFB1BD9D9D9D9D9DFF % FF3A9D9DFFFF9D9D9D9D3A9DFFFF9D9D3A9DE3E39D3A9D3AC67F13131313 % 13131313137F9D9D9DC8E33A3A3A3A3A3A3A3A3A3A002100000000210012 % 161818C518181A1818181A18181818181818181818161818181818181818 % 12121618181812161210101010100A0F1010121800FF1810101012101216 % 121810121010121010101010121618181818181818181810101010121010 % 1012101216121810181018181818181818161218101810181210AF101212 % FF7D00000000000000003A3A9D3A3A9D3A9D3A9D9D9D3A9D7F1313131313 % 131313137F3A9D9D3A9D9D9D9DFF535353535353535353FF9D9D9D3A9D3A % 9D3A9D3A9D9D9D9D9D9D3A9D3A9D3A3A9D9D9D9D9DFF5353535353535353 % 53FF9D3A9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D3A9D % 9D9D9D3A3A9D9D9D9D3A3A3A3A3A9D3A9D9D9D9D3A3A9D3A3A9D3A9D9D3A % 9D9D9D3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D9D3A9D9D9D3A3A % 3A3A9D3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A9D9D9D9D3A3A3A9D9D9D9D % 9D9D9D9D9D7F1313131313131313137F9D9D9D3A3A3A3A9D9D3A9D9D3A9D % 9D3A9D3A3A3A3A3A3A3A3A9D3A7F1313131313131313137F9D3A3A3A3A9D % 9D3AFF535353535353535353FF3A3A9D9D9D3A3A3A3A3A9D9D9D9D3A3A9D % 9D9D9D9D3A9D9D3A3A3A3AFF535353535353535353FF3A3A3A9D9D9D9D3A % 3A3A3A3A3A9D9D9D9D3A3A3A3A3A9D9D9D3A3A9D9D9DFF7D9D9D9D3A9D9D % 9D9D9D9D9D9D3A9D9D3A9DFFFF53535353535353535353535353FFFF9D9D % 9D9D9D9D9D9D9D9D9D9D3A3A9D9D3A3AD1FFFFFFFFFFFFC8A39D9D9DFFFF % 9D9D9DFFFF9D3A9D9D9D3AFFFF3A9D9DB2FFC69D3A3A3A9D7F1313131313 % 131313137F9D9D9D8BFF609D3A3A3A3A3A3A3A3A00210000000021001212 % 1818C518181818181818181A181818181818181818181818181818181810 % 1010121012161218101210101210101010101200FF181612101010101210 % 121612101216101010101210121818181818181818181612101010101210 % 12101210121612181818181818161210121012101210121010AF101010FF % 7D00000000000000003A3A9D3A3A9D3A9D3A9D9D9D3A9D7F131313131313 % 1313137F3A9D9D3A9D9D9D9DFF535353535353FFFFFFFF9D9D9D3A9D3A9D % 3A9D3A9D9D9D9D9D9D3A9D3A9D3A3A9D9D9D9D9DFF535353535353535353 % FF9D3A9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9D9D9D3A9D9D % 9D9D3A3A9D9D9D9D3A3A3A3A3A9D3A9D9D9D9D3A3A9D3A3A9D3A9D9D3A9D % 9D9D3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D9D3A9D9D9D3A3A3A % 3A9D3A3A3A3A3A9D9D9D3A9D3A3A3A3A3A3A9D9D9D9D3A3A3A9D9D9D9D9D % 9D9D9D9D7F1313131313137F7F7F7F9D9D9D3A3A3A3A9D9D3A9D9D3A9D9D % 3A9D3A3A3A3A3A3A3A3A9D3A7F1313131313131313137F9D3A3A3A3A9D9D % 3AFF535353535353FFFFFFFF3A3A9D9D9D3A3A3A3A3A9D9D9D9D3A3A9D9D % 9D9D9D3A9D9D3A3A3A3AFF535353535353535353FF3A3A3A9D9D9D9D3A3A % 3A3A3A3A9D9D9D9D3A3A3A3A3A9D9D9D3A3A9D9D9DFF7D9D9D9D3A9D9D9D % 9D9D9D9D9D3A9D9D3A9DFF535353535353535353535353535353FF9D9D9D % 9D9D9D9D9D9D9D9D9D3A3A9D9D3A71FFD1AF9D9DA3C6FFC69D9D9DFFFF9D % 9D9DFFFF9D3A9D9D9D3AFFFF3A9D9DC0FFB49D3A3A3A9D7F131313131313 % 137F7F7F9D9D9D66FF829D3A3A3A3A3A3A3A3A0021000000002100101012 % 18C518181818181818181818181A18181818181818181818181818181612 % 10101010121012161210121610101010121000FF18181816101010101012 % 101210181216121010101012161818181818181818121810101010101010 % 121012101810181818181818181210101210121012101210AF100F10FF7D % 00000000000000003A3A3A3A3A3A3A9D3A9D3A9D7F7F137F131313131313 % 137F9D9D3A9D3A9D9D9D9D3AFF535353FFFF535353FFFF9D9D9D9D3A9D3A % 9D3A9D9D9D9D9D9D9D9D3A9D3A9D9D9D9D9DFFFFFF53535353535353FF9D % 9D9D9D9D9D9D3A9D9D9D3A3A9D3A9D9D9D3A9D9D3A9D9D9D9D3A9D9D9D9D % 3A3A3A9D9D9D9D3A3A3A3A3A3A3A9D9D9D9D3A3A3A3A9D3A3A9D9D9D9D9D % 9D3A3A3A3A9D9D3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D9D9D9D3A3A3A3A % 3A3A3A3A9D9D9D9D9D9D3A9D3A3A3A3A3A9D9D9D9D3A3A3A9D9D9D9D9D9D % 9D9D9D9D7F1313137F7F1313137F7F9D9D3A3A3A3A9D3A3A9D9D9D9D3A3A % 3A3A3A3A3A3A3A3A3A9D7F7F7F131313131313137F9D9D9D3A3A3A9D3A3A % 3AFF535353FFFF535353FFFF9D3A9D9D9D3A3A3A3A3A9D3A9D9D3A9D9D9D % 9D9D9D9D3A3A3AFFFF53FF53535353535353FF9D3A3A3A9D9D9D9D9D3A3A % 3A3A9D9D9D9D9D3A3A3A3A3A9D9D3A9D3A9D9D9DFF7D9D9D9D9D3A9D9D3A % 9D3A9D9D9D9D9D9DFF5353535353535353535353535353535353FF9D3A9D % 3A9D9D3A9D9D9D9D3A3A9D9D3AB1FFA39D3A9D9D3AFFFF9D3A3AFFFF9D9D % 3AFFFF9D3A9D3A9D9DFFFF9D9D9DCBFFA93A9D3A3A9D9D7F131313137F7F % 1313137F7F9D54FF963A3A3A3A3A3A3A3A3A00210000000021000F101010 % C5101818181818181A18181A181A18181818181818181818181818181816 % 101010101012101210181216121010101000FF1818181818121010101010 % 101818181810101010101012181818181818181818181012101010121010 % 1010121018181018181818181816121010101210101010AF100A10FF7D00 % 000000000000003A3A3A3A3A3A3A9D3A9D9D7F1313137F13131313131313 % 7F9D9D3A9D3A9D9D9D9D9DFF5353FF53535353535353FF9D9D9D9D9D9D3A % 9D9D3A9D9D9D9D9D9D9D3A3A9D9D9D3AFF5353FF53535353535353FF9D9D % 9D9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D % 3A3A9D9D9D9D3A3A3A3A3A9D9D3A3A9D9D3A3A3A3A3A9D3A9D3A3A9D9D9D % 3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D9D3A9D9D9D3A3A3A3A9D % 9D3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D9D9D3A3A3A3A9D9D9D9D9D9D % 9D9D9D7F13137F131313131313137F9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A % 3A3A3A3A3A3A3A9D7F13137F131313131313137F9D9D3A3A3A3A9D9D3A3A % FF5353FF53535353535353FF9D9D9D9D3A3A3A3A9D3A3A9D9D9D9D9D9D9D % 9D3A3A3A3AFF535353FF53535353535353FF9D3A3A3A9D9D3A9D9D3A9D3A % 3A9D9D3A9D9D3A3A9D3A3A3A3A9D9D9D9D9D9DFF7D9D9D9D3A9D9D9D9D9D % 9D9D3A9D9D9DFF53535353535353535353535353535353535353FF9D3A9D % 3A9D9D9D3A9D3A9D3A3A9D3A3A3A9D9D9D3A9DA6FFFF9D3A3AFFFF9D3A9D % FFFF9D9D9D9D3A9DFFFF9D9D3AFFFF9D9D9D3A9D9D3A7F1313137F131313 % 131313137F3AFFFF3A3A3A3A3A3A3A3A3A00210000000021000A101010C5 % 10121018181818181A181A18201818181818181818181818181818181818 % 1210101010101018181818101010101000FF181818181010101010101218 % 1816181818181818181818181A1818181810101816181818181216101210 % 12101810121010101818181012101012101010121010AF100A08FF7D0000 % 0000000000003A3A3A3A3A3A3A9D3A9D9D7F131313137F7F1313137F7F9D % 9D9D3A9D3A9D9D9D9D9D9DFFFFFF53535353535353FF9D9D9D9D9D9D3A9D % 9D3A9D9D9D9D9D9D9D3A3A9D9D9D3AFF535353FFFF535353FFFF9D9D9D9D % 9D9D9D3A9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A9D9D9D9D9D9D9D3A % 3A9D9D9D9D3A3A3A3A3A9D9D3A3A9D9D3A3A3A3A3A9D3A9D3A3A9D9D9D3A % 3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A9D3A9D9D3A9D9D9D3A3A3A3A9D9D % 3A3A3A3A3A9D9D9D3A3A3A3A3A3A9D9D9D9D9D3A3A3A3A9D9D9D9D9D9D9D % 9D9D3A7F7F7F131313131313137F9D3A3A3A3A9D9D3A9D9D3A9D3A3A3A3A % 3A3A3A3A3A3A9D7F1313137F7F1313137F7F3A9D9D3A3A3A3A9D9D3A3A3A % FFFFFF53535353535353FF9D9D9D9D3A3A3A3A9D3A3A9D9D9D9D9D9D9D9D % 3A3A3A3AFF53535353FFFF535353FFFF9D9D3A3A3A9D9D3A9D9D3A9D3A3A % 9D9D3A9D9D3A3A9D3A3A3A3A9D9D9D9D9D9DFF7D9D9D9D3A9D9D9D9D9D9D % 9D3A9D9D9DFF53535353535353535353535353535353535353FF9D3A9D3A % 9D9D9D3A9D3A9D3A3A9D3A3A3A9DA3B282DAFFFF8B9D3A3AFFFF9D3A9DFF % FF9D9D9D9D3A9DFFFF9D9D3AFFFF9D9D9D3A9D9D3A9D7F7F137F13131313 % 1313137F3AFFFF3A3A3A3A3A3A3A3A3A00210000000021000A081010C510 % 101012161818181818181A18181818101012101810181618181818181010 % 10101010121818161818181818181800FF16181818101012081010101012 % 181818181818181818181A181A1818161212181818181818161210121010 % 121216181010121010101212161218101210101012AF101010FF7D000000 % 00000000003A3A3A3A3A3A3A9D3A9D7F131313131313137F7F7F3A9D9D9D % 9D9D3A3A9D9D9D9D9D3A9DFF535353535353535353FF9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D3A9D9D9D9DFF535353535353FFFFFFFF9D3A9D9D3A9D % 3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9D3A9D3A9D9D3A9D3A9D9D9D3A3A3A % 9D9D9D3A3A3A3A3A3A9D3A3A3A9D9D3A3A3A3A3A9D9D3A3A3A9D9D3A3A3A % 3A3A9D3A3A3A3A3A9D9D3A3A3A3A3A9D9D3A3A3A9D9D9D3A3A3A3A9D9D3A % 3A3A3A3A9D9D9D9D3A3A3A3A3A9D9D9D9D9D3A3A3A3A3A9D9D9D9D9D9D9D % 3A3A3A7F1313131313131313137F3A3A3A3A9D9D9D3A3A3A9D3A3A3A3A3A % 9D9D9D9D9D7F1313131313137F7F7F7F3A3A9D9D3A3A3A3A9D9D3A3A3A3A % FF535353535353535353FF3A9D9D3A3A3A3A9D9D9D9D3A3A9D9D9D9D3A3A % 9D3AFF53535353535353FFFFFF3A9D9D9D3A3A3A9D3A3A9D3A3A3A3A3A9D % 3A3A9D9D3A3A3A3A3A9D9D3A3A3A9D9D9DFF7D9D9D3A9D3A3A9D3A9D9D9D % 9D9D9D3AFF53535353535353535353535353535353535353FF9D3A9D9D9D % 9D9D9D9D9D9D9D3A9D3A3AAFD1FFFFFFFFFFDAA63A9D3AFFFF9D9D9DFFFF % 9D9D3A9D9D3AFFFF9D3A9DFFFF9D9D9D3A9D9D9D9D3ACB7F131313131313 % 1313137FFFFF3A3A9D3A3A3A3A3A3A002100000000210010101010C51010 % 10101218181818181A181818181810121012101210121216181818101012 % 081010101012181818181818181800FF121018121612100E0A0810101018 % 18181A18181A181818181818181812101018181818181818181010181318 % 1618181210101010101010181816181810181216AF101010FF7D00000000 % 000000003A3A3A3A3A3A3A9D3A9D7F1313131313131313137F9D3A9D9D9D % 9D9D9D9D9D9D9D9D9D3AFF535353535353FFFFFFFF9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9DFF535353535353535353FF9D9D9D9D9D9D9D % 3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A3A9D % 9D9D3A9D3A9D3A3A3A3A9D3A9D9D3A9D3A3A9D3A3A3A3A9D3A9D3A3A9D3A % 3A3A3A9D3A9D9D3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A9D % 3A9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A9D3A3A9D9D9D9D9D3A % 3A9D7F1313131313137F7F7F7F3A3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A % 3A3A3A3A7F1313131313131313137F3A3A9D3A3A3A3A3A9D9D3A3A3A3AFF % 53535353535353FFFFFF3A3A3A3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3A % 3AFF535353535353535353FF3A9D9D3A3A3A9D9D9D3A3A9D3A3A3A3A3A3A % 3A9D3A3A3A3A3A9D9D9D3A3A3A9D9D9DFF7D9D9D9D9D9D9D9D9D3A9D3A9D % 9D9DFF535353535353535353535353535353535353535353FF9D9D3A9D3A % 9D9D3A9D9D9D3A9D3AB2FFFFFFFFDAC0AF9D3A9D9D9DFFFF3A9D3AFFFF9D % 9D9D9D3A9DFFFF9D9D9DFFFF3A9D9D3A9D9D9D3AAFFF7F1313131313137F % 7F7F7FFFFF3A3A3A3A3A3A3A3A3A002100000000210010101010C5100E10 % 10121018181818181A18181818101216121018101210121018121612100E % 0A081010101818181A18181A1800FF101210181818181010100A10101818 % 18181818181818181A181818181010121012101818181810181218161818 % 18181618101010101012181818181618121618AF121010FF7D0000000000 % 0000003A3A3A3A3A3A3A9D3A7F7F1313131313131313137F9D3A9D9D9D9D % 9D9D9D9D9D9D9D9D3AFF53535353FFFF535353FFFF9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9DFFFF535353535353535353FF9D9D9D9D9D9D9D3A % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A9D9D9D9D9D3A3A9D9D % 9D3A9D3A9D3A3A3A3A9D3A9D9D3A9D3A3A9D3A3A3A3A9D3A9D3A3A9D3A3A % 3A3A9D3A9D9D3A9D3A3A3A3A3A9D3A3A3A3A9D3A3A9D3A3A3A3A3A3A9D3A % 9D9D9D9D9D9D3A9D9D3A9D9D9D9D3A3A3A9D3A3A9D3A3A9D9D9D9D9D3A3A % 9D7F131313137F7F1313137F7F3A3A3A3A3A3A3A3A3A9D9D3A3A3A3A3A3A % 3A3A7F7F1313131313131313137F3A3A9D3A3A3A3A3A9D9D3A3A3A3AFF53 % 53535353FFFF535353FFFF3A3A3A3A3A9D3A3A3A3A3A9D9D9D3A3A3A3AFF % FF535353535353535353FF3A9D9D3A3A3A9D9D9D3A3A9D3A3A3A3A3A3A3A % 9D3A3A3A3A3A9D9D9D3A3A3A9D9D9DFF7D9D9D9D9DFFFFFFFFFFFFFFFFFF % FFFF535353535353535353535353535353535353535353FFFFFFFFFFFFFF % FFFFFF9D9D3A9D3ADAFFCBB2489D9D9D9D3A9D9D9DFFFF3A9D3AFFFFA69D % 9D9D3A9DFFFF9D9D9DCBFF549D9D3A9D9D9D3AE3FF7F131313137F7F1313 % 137F7F963A3A3A3A3A3A3A3A3A002100000000210010101010C510101010 % 101212101818181818181818181810181112101610101210181818181010 % 100A1010181818181818181800FF10101010121018181810101012181818 % 18181818181818181A181818101210101010121012101018101818181818 % 181818181818181010181218101212101218AF101810FF7D000000000000 % 00003A3A3A3A9D3A3A9D7F13137F131313131313137F9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9DFF5353FF53535353535353FF9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9DFF5353FF53535353535353FF9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D7F13137F131313131313137F9D9D9D9D9D9D9D9D9D9D9D9D9D3A3A9D9D % 7F13137F131313131313137F9D3A3A3A3A3A3A9D3A3A9D3A3A3A3A3AFF53 % 5353FF53535353535353FF3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3AFF5353 % FF53535353535353FF3A3A3A3A3A3A3A9D9D3A3A3A9D3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A9D9D9D9DFF7D9D9D9D9DFFFFFFFFFFFFFFFFFFFF % FF535353535353535353535353535353535353535353FFFFFFFFFFFFFFFF % FFFF9D9D9D3A3AFFFF9D9D9D9D9DA3FFE39D9D9DFFFF9D9D9DFFFF719D9D % 9D3A54FFFF9D3A9DC0FFB29D9D3A9D9D9DC6FF779D7F13137F1313131313 % 13137F3A3A3A3A3A3A3A3A3A002100000000210018101210C51010101010 % 101012181818181818181018101812181018121010101010121018181810 % 101012181818181818181800FF1012101010101218181810121618181818 % 181818181818181818181012101010101010101210121210181018181818 % 1818181A18181812161216121010101012AF181012FF7D00000000000000 % 003A3A3A3A3A3A3A9D7F13137F131313131313137F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFF5353FF53535353535353FF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF5353FF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 7F13137F131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A3A7F % 13137F131313131313137F3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF5353 % 53FF53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF5353FF % 53535353535353FF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9D9DFF7D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF % 535353535353535353535353535353535353535353FF9D9D9D9D9D9D9D9D % 9D9D9D9D9D9DD1FFC0A39D9DA9D1FFC09D9D9DFFFF9D9D9DFFFFDAC6A69D % A9D1FFC69D9D9DB2FFC09D9D9D9D9DAFFFDA9D9D7F13137F131313131313 % 137F3A3A9D3A3A3A3A3A3A002100000000210010121010C5101010101012 % 101012121818161210101212161216181818121012101010101218181810 % 1216181818181818181800FF1810121010100E1816121810181618161818 % 161818181818181818121012101010101218181812101012121612181618 % 18181818181818181818181018121010AF101216FF7D0000000000000000 % 3A3A3A3A3A3A3A7F131313137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3AFFFF535353535353FFFFFFFF3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFF53535353FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A % 3A3A3A9D3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 7F7F1313131313137F7F7F7F3A3A3A3A3A3A9D3A3A3A3A9D3A9D3A7F1313 % 13137F7F1313137F7F9D3A9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFFFFFF % 535353535353FFFFFFFF9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF53535353FF % FF535353FFFF9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D % 9D9D9D9D9D9D9D9D9D9D9D9DFF7D9D9D9D9D9D9D9D9D9D9D9D9D9D9DFF53 % 5353535353535353535353535353535353535353FF9D9D9D9D9D9D9D9D9D % 9D9D9D9D9DA6E3FFFFFFFFFFFFDA9D9D9D9DFFFF9D9D9DFFFFA6E3FFFFFF % FFFFA99D9D9D9DFFE39D9D9D9D9DE3FFA99D9D9D7F7F1313131313137F7F % 7F7F3A9D3A3A3A3A3A3A002100000000210012161210C510101010101012 % 1012101210121010101010121818181818181810121010100E1816121810 % 18161816181816181800FF181810100A100A101010101812121218181818 % 181818181818181810101010101216181818181810121010121612181812 % 10101018181818181818181818180AAF101216FF7D00000000000000003A % 3A3A3A3A3A7F7F1313131313137F7F7F7F3A9D3A9D9D9D3A3A9D3A9D9D3A % 9D3A9D3A3A9D9D9DFF53535353FFFF535353FFFF9D9D3A3A9D9D3A3A9D3A % 9D9DFFFFFF535353535353FFFFFFFF3A3A3A9D3A9D3A3A9D3A9D3A3A3A3A % 3A3A3A9D3A3A9D3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A % 3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 7F131313137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F131313 % 1313137F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53 % 535353FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353535353 % FFFFFFFF3A3A3A3A3A3A3A3A3A9D3A3A9D3A3A3A9D3A3A3A9D3A3A3A9D3A % 3A3A9D3A3A3A3A3A3A3A3AFF7D3A3A3A9D3A3A3A9D3A3A9D3A9D3A3AFF53 % 535353535353535353535353535353535353FF3A9D3A3A3A9D3A9D3A9D3A % 9D3A3A9D3A48C0B1FFFFD1719D3A9D3A3AFFFF3A3A9DFFFF9DA6CBFFFFC6 % A99D9D3A9D9D82FFB23A9D9DC6FFBD3A9D9D3A9D7F131313137F7F131313 % 7F7F3A3A3A3A3A3A3A002100000000210012161210C51010101010101010 % 10101012101010101010121018181A181A181810100A100A101010101812 % 121218181818181800FF181818101010100B101012101818181818181818 % 181010181216121012101010101218181818181A18181216121818121018 % 1818181818181816121816181818AF101210FF7D00000000000000003A3A % 3A3A3A7F137F1313131313131313137F3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 9D3A3A9D3A3A3AFF535353FF53535353535353FF3A3A3A3A3A3A9D3A3A3A % FF5353FF535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9D3A3A3A7F % 1313137F131313131313137F3A3A9D3A9D3A9D3A9D9D3A7F137F13131313 % 13131313137F9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9DFF5353 % 53FF53535353535353FF9D9D9D9D9D9D9D9D9D9DFF53FF53535353535353 % 5353FF9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D9D % 9D3A9D3A3A3A9D9D9D9DFF7D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9DFF5353 % 5353535353535353535353535353535353FF9D3A9D3A9D9D3A9D9D9D3A9D % 9D9D9D3A3A9D3A9D9D3A9D3A9D3A9D3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A % 3A3A9D3A9D48FFB19D3A3A9D3A9D3A9D3A9D3A7F1313137F131313131313 % 137F3A3A3A3A3A3A002100000000210012101818C5101216121818181810 % 10121010121010101010121818181818181818101010100B101012101818 % 1818181818181800FF181818101210101010101012101210181818181818 % 181211181012101012101010101818181818181812101210181810121012 % 18101818181818121012121018AF181012FF7D00000000000000003A3A3A % 3A3A7F13137F131313131313137F3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D % 3A3A9D3A3A3A3AFF5353FF535353535353FFFFFF3A3A3A3A3A9D3A3A3AFF % 535353FF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A9D3A % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A9D3A3A3A9D3A3A3A9D7F % 13137F1313131313137F7F7F3A9D3A9D3A9D3A9D9D7F7F13137F13131313 % 1313137F9D9D9D9D9D9D9D3A9D9D3A9D9D9D9D9D9D9D9D9D9D9D9DFF5353 % FF5353535353FFFFFF9D9D9D9D9D9D9D9D9D9DFF5353FF53535353535353 % FF9D9D9D9D9D9D9D9D9D9D3A3A9D3A9D3A9D3A9D3A9D3A3A9D9D3A9D9D9D % 3A9D3A3A3A9D9D9D9DFF7D9D9D9D3A9D9D9D9D9D9D3A9D3A9D9DFF535353 % 53535353535353535353535353535353FF9D3A9D3A9D9D3A9D9D9D3A9D9D % 9D9D3A3A9D3A9D9D3A9D3A9D3A9D3A9D9D9D9D3A9D3A3A3A3A3A3A3A3A3A % 3A9D3A9D3AC0FFB23A3A9D3A9D3A9D3A9D3A3A7F13137F13131313137F7F % 7F3A3A3A3A3A3A002100000000210010121612C518181818181818181218 % 161812101010101010101012181818181818101210101010101012101210 % 18181818181800FF16181216121012101010121010101018181818181818 % 181812161216121012101218181818181A18181010101010101010101010 % 121012101210101010101018AF121012FF7D00000000000000003A3A3A7F % 7F1313137F131313131313137F3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF53FF5353535353FFFF535353FFFF3A3A3A3A3AFFFF5353 % 5353FF53535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A % 3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A9D3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F13 % 7F13131313137F7F1313137F7F3A3A3A3A3A7F7F7F1313137F1313131313 % 13137F3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3AFF53FF53 % 535353FFFF535353FFFF3A3A3A3A3A3AFFFF535353FF53535353535353FF % 3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A9D3A9D3A3A3A3AFF7D3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3AFF535353 % 5353535353535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF3A3A3A3A9D3A3A3A3A3A3A3A9D3A % 3A3A3A3A3AC8C83A3A3A3A3A3A3A3A3A3A9D7F137F131313137F7F131313 % 7F7F3A3A3A3A002100000000210010121018C51316181818181818181818 % 181618181818101010101010181816181216121012101010121010101018 % 181818181800FF1812161218101012101210101010101012181818181818 % 18101812101210101217181A18181A181818181010101010101010101010 % 1010101818121810101012AF121010FF7D000000000000007F7F7F7F137F % 131313137F7F1313137F7F3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A % 3A3A3A3A3A3AFFFF53535353FF5353535353FFFFFFFFFFFFFF53FF535353 % 5353FFFF535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F7F % 131313137F13131313137F7F7F7F7F7F7F13137F131313137F7F1313137F % 7F3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3AFFFF5353 % 53FF5353535353FFFFFFFFFFFF3AFF53FF53535353FFFF535353FFFF3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 535353535353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A59FF8B3A3A3A3A3A3A3A3A3A3A3A7F7F1313137F13131313137F % 7F7F3A7F7F7F2100000000210010101216C518181818181818181A181818 % 121818181818121010101012181812161218101012101210101010101012 % 1818181800FF101018111818181818181818181818181818181818181818 % 1818111810101218181818181A181A181818161010101010101010101010 % 10181718181816121010AF101210FF7D00000000007F7F137F7F7F137F13 % 13131313137F7F7F7F3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF53535353FF535353FFFF53FFFF53FFFFFF53FF53535353 % 535353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 9D3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A9D3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F13 % 1313137F1313137F7F137F7F137F7F7F13137F1313131313137F7F7F7F3A % 3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3AFF535353 % FF535353FFFF53FFFF5353FFFFFF53FF535353535353FFFFFFFF3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF535353 % 53535353535353535353FFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313137F1313137F7F1313 % 7F7F1313137F7F000000210012101210C516181818181818181818181010 % 121018181818181818101012101018111818181818181818181818181818 % 18181800FF121810181018181018181818181A1818181818181A18181818 % 161818131810181818181A18181818181818181012101010101010101010 % 181818181818181810AF161816FF7D000000007F13137F137F1313137F13 % 1313131313137F3A3A3A3A3AFFFFFFFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFF5353FF535353FF5353FF5353FF53FF535353FF53535353 % 535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A9D3A3A3A9D3A3A9D3A3A9D3A3A3A3A3A3A3A9D3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A7F13 % 137F1313137F13137F13137F137F131313137F131313131313137F3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53FF53 % 5353FF5353FF535353FF53FF535353FF53535353535353FF3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF535353 % 5353535353535353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F1313137F1313137F13 % 1313131313137F0000210018161216C51812181618181618181210121010 % 121018C5C5C5C5C5C51010121810181018181018181818181A1818181818 % 181A00FF1810121812161218101818181818181818181A18181818181818 % 18181018101818181818AF1818181818AF18101810121010101010101012 % 1210121818181810AF181818FF7D000000007F13137F137F1313137F1313 % 13131313137F3A3A3A3A3A3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFF5353FF535353FF5353FF5353FF53FF535353FF5353535353 % 5353FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A7F1313 % 7F1313137F13137F13137F137F131313137F131313131313137F3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53FF5353 % 53FF5353FF535353FF53FF535353FF53535353535353FF3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFFFF53 % 53535353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F1313137F1313137F1313 % 13131313137F0000210018181812C5101210181218181810101810181010 % 12121818C5C5181810121810121812161218101818181818181818181A18 % 1800FF17181612161012161210181818181818181A181818181818181818 % 18181018181818181AAF1818101812AF1810121018101210121010101010 % 10101012181812AF181818FF7D0000007F13137F13137F131313137F7F13 % 13137F7F3A3A3A3A3A3A3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3AFFFFFF5353FF5353FF5353FF5353FF53535353FFFF535353FF % FF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A9D3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F7F % 13137F13137F13137F13137F13131313137F7F1313137F7F3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF5353FF % 5353FF535353FF5353FF53535353FFFF535353FFFF3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFFFF % FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F13137F1313137F13131313 % 13131313137F00210018181816C510121012101216121818181818181010 % 101012C5C51816181817181612161012161210181818181818181A181818 % 00FF18181818121010101010121618181818181818181A1818181A181818 % 18181818181818AFAFAFAFAFAFAFAF101012101818181010AFAFAFAFAFAF % AFAFAFAFAFAFAF181018FF7D0000007F13137F1313137F13131313137F7F % 7F3A3A3A3A3A3A3A3A3A3AFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3AFFFF53FF5353FF5353FF535353FF5353535353FFFFFF3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F7F % 137F13137F13137F1313137F1313131313137F7F7F3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3AFF53FF53 % 53FF535353FF535353FF5353535353FFFFFF3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3AFF7D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A % 3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A7F137F1313137F1313131313 % 131313137F00210010181318C5C5C5C5C5C5C5C5C5C5C5C5C51818181818 % 1210C5C51018181818181818121010101010121618181818181818181A00 % FF10121810101010101010101012181818181818181818181A181A181818 % 181818181818AFAFAFAFAFAFAFAF10101010181210181012101010101012 % 101218181817181618FF7D0000007F13137F1313137F131313131313137F % 00000000000000000000FFFF000000000000000000000000000000000000 % 000000000000FF53FF5353FF5353FF535353FF53535353535353FF000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000007F13 % 7F13137F13137F1313137F131313131313137F0000000000000000000000 % 00000000000000000000000000000000000000000000000000FF53FF5353 % FF535353FF535353FF53535353535353FF00000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00FF7D000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000007F137F1313137F131313131313 % 1313137F0021001618161816121012101012101012101210121818181818 % 10C5C51212181210121810101010101010101012181818181818181800FF % 1210101010100810101010101010101218161818181A181A181818181817 % 181818181818181818181818AF1010101010101210121010181010101010 % 1218181818181818FF7D000000007F13137F1313137F7F1313137F7F0000 % 000000000000000000FFFF00000000000000000000000000000000000000 % 000000000000FFFFFF5353FF5353FF535353FFFF535353FFFF0000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000007F7F % 7F13137F13137F1313137F7F1313137F7F00000000000000000000000000 % 00000000000000000000000000000000000000000000000000FFFFFF5353 % FF535353FF535353FFFF535353FFFF000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % FF7D00000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000007F7F7F1313137F131313131313 % 137F00002100181818181818181810181010121010121010101210181818 % C5C51010101012101010101008101010101010101012181618181800FF10 % 1012101010100A0F0A10101010101010121618181820181A181818181818 % 1216181818181818181818AF101010101010101010181818181712101816 % 1818181A181818FF7D000000007F13137F13131313137F7F7F0000000000 % 000000000000FFFFFFFF0000000000000000000000000000000000000000 % 00000000000000FF5353FF5353FF5353535353FFFFFF0000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000000000000000000000000000007F % 13137F13137F13131313137F7F7F00000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000FF5353FF % 535353FF5353535353FFFFFF000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000000000FF % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7F1313137F13131313131313 % 7F0000210018181818181818181812101210101210121012101012C5C5C5 % C516121010101012101010100A0F0A101010101010101216181800FF1012 % 1010101010100A1010080A10081010101818181A18181818181818101810 % 181217181818181818181010101010101010101218181818181818181818 % 181818181818FF7D00000000007F7F137F7F1313137F7F00000000000000 % 00000000000000FFFF000000000000000000000000000000000000000000 % 00000000000000FFFF53FFFF53FFFF535353FFFF00000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 00000000000000000000000000000000000000000000000000000000007F % 7F137F7F137F7F1313137F7F000000000000000000000000000000000000 % 0000000000000000000000000000000000000000000000000000FFFF53FF % FF5353FFFF535353FFFF0000000000000000000000000000000000000000 % 00000000000000000000000000000000000000000000000000000000FFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F13137F7F1313137F7F00 % 00002100181818161818181818161216101210101010101010101012C5C5 % 1818181810121010101010100A1010080A100810101018181800FF181216 % 12181818101010101008100810101012181818181A181818181818101210 % 10181812181812161216121010100A10101012181818181818181818181A % 1818181818FF7D000000000000007F7F7F7F7F7F00000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 0000000000000000FFFFFFFFFFFFFFFFFF00000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 7F7F7F7F7F7F7F7F7F000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000FFFFFF % FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000007F7F7F007F7F7F00000000 % 002100181818121018181818181210121018101812121612101010181818 % 18181818121612181818101010101008100810101012181800FF18161210 % 181618101210101010080A10101010101818181818181817121012161218 % 101210101010121018121012101010101012181818181A18181818181818 % 18181818FF7D000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 210018181010121818171818101810181018181818181818181210121218 % 161818161210181618101210101010080A10101010101800FF1012101012 % 181818181012101010101010101218181818181818181812101218121012 % 10121012101018121612101010101010101818181A181A18181A181A1818 % 181810FF7D00000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000021 % 00181012101010181218101218181818181818181A181818181210101012 % 1810121010121818181810121010101010101012181800FF181012101210 % 101012101210100A08101010101012101218101810121010101010181818 % 181010101010101210121810181012121818181A18181818181818181818 % 1010FF7D0000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000000000 % 000000000000000000000000000000000000000000000000000000002100 % 101010101010101010121010101012101818181818181818181818181018 % 181012101210101012101210100A0810101010101200FF18181810101010 % 121012161010101010101010101010121012121010101010101018181818 % 181810181010101012101816121816181818181818181818181818181810 % 10FF7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D % 7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D7D210010 % 101010101010101012101210121018181718181618181818181818181818 % 181810101010121012161010101010101010101000FF1818171818181810 % 101210121010101010101010101010101010101010081010101218181818 % 181818101010101010181212161818181A16181818181618181818101210 % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001210 % 101010101210181818101810181018121818181818181818181818181818 % 1718181818101012101210101010101010101000FF121818181818181012 % 10181018181612181818121010101210101010100A081010181818181818 % 181818121010101012101012121818181818161818181818161310101010 % 101012161818181818181210121012101810181818181818181818121818 % 18181818101210181018181612181818121010101210101010100A081010 % 181818181818181818121010101012101012121818181818161818181818 % 161310101010101012161818181818181210121012101810181818181818 % 181818121818181818181012101810181816121818181210101012101010 % 10100A081010181818181818181818121010101012101012121818181818 % 161818181818161310101010101012161818181818181210121012101810 % 181818181818181818121818181818181012101810181816121818181210 % 10101210101010100A081010181818181818181818121010101012101012 % 121818181818161818181818161310101010101012161818181818181210 % 121012101810181818181818181818121818181818181012101810181816 % 12181818121010101210101010100A081010181818181818181818121010 % 101012101012121818181818161818181818161310101010101012161818 % 181818181210121012101810181818181818181818121818181818181012 % 10181018181612181818121010101210101010100A081010181818181818 % 181818121010101012101012121818181818161818181818161310101010 % 101012161818181818181210121012101810181818181818181818121818 % 18181818101210181018181612181818121000FF10121012101212101012 % 121618181818181818181818101818131610101010101210181818181818 % 181010101010101010101010121018181818181818181818101210101010 % 1018181818181A1818181010101010121012101812161818181010121012 % 101212101012121618181818181818181818101818131610101010101210 % 181818181818181010101010101010101010121018181818181818181818 % 1012101010101018181818181A1818181010101010121012101812161818 % 181010121012101212101012121618181818181818181818101818131610 % 101010101210181818181818181010101010101010101010121018181818 % 1818181818181012101010101018181818181A1818181010101010121012 % 101812161818181010121012101212101012121618181818181818181818 % 101818131610101010101210181818181818181010101010101010101010 % 1210181818181818181818181012101010101018181818181A1818181010 % 101010121012101812161818181010121012101212101012121618181818 % 181818181818101818131610101010101210181818181818181010101010 % 101010101010121018181818181818181818101210101010101818181818 % 1A1818181010101010121012101812161818181010121012101212101012 % 121618181818181818181818101818131610101010101210181818181818 % 181010101010101010101010121018181818181818181818101210101010 % 1018181818181A1818181010101010121012101812161818181010121012 % 101212101012121618181818181818181800FF1210101210101010181010 % 121818181818181A181A1818181718181218181810101810181218181012 % 101210101818101010101010121218181818181818181818101210101010 % 1818181A1818181818121010101010121010101012101818101210101210 % 101010181010121818181818181A181A1818181718181218181810101810 % 181218181012101210101818101010101010121218181818181818181818 % 1012101010101818181A1818181818121010101010121010101012101818 % 101210101210101010181010121818181818181A181A1818181718181218 % 181810101810181218181012101210101818101010101010121218181818 % 1818181818181012101010101818181A1818181818121010101010121010 % 101012101818101210101210101010181010121818181818181A181A1818 % 181718181218181810101810181218181012101210101818101010101010 % 1212181818181818181818181012101010101818181A1818181818121010 % 101010121010101012101818101210101210101010181010121818181818 % 181A181A1818181718181218181810101810181218181012101210101818 % 1010101010101212181818181818181818181012101010101818181A1818 % 181818121010101010121010101012101818101210101210101010181010 % 121818181818181A181A1818181718181218181810101810181218181012 % 101210101818101010101010121218181818181818181818101210101010 % 1818181A1818181818121010101010121010101012101818101210101210 % 101010181010121818181818181A181A00FF181812101012101212101210 % 1018181618181A1818181818181818171818181612121012101010181810 % 101212181018181010101210101818181A18181818181816121012121818 % 181818181A18FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A18181818181816121012121818 % 181818181A18181810100B0E10101010100E101010121818181812101012 % 1012121012101018181618181A181800FF18181818121010181010101012 % 181810101818181818121012101818181818181810101010101018181012 % 101010181818181816121612181818181818181818181810181316181818 % 18181A181AFF1812101010101010100A100A101012161818181818121010 % 1810101010121818101018181818181210121018FF181818181810101010 % 101018181012101010181818181816121612181818181818181818181810 % 181316181818FF181A181A181812101010101010100A100A101012161818 % 18181812101018101010101218181010181818181812FF12101818181818 % 181810101010101018181012101010181818181816121612181818181818 % 1818181818101813FF18181818181A181A181812101010101010100A100A % 101012161818181818121010181010101012181810101818FF1818121012 % 101818181818181810101010101018181012101010181818181816121612 % 18181818181818181818FF1018131618181818181A181A18181210101010 % 1010100A100A1010121618181818181210101810101010121818FF101818 % 181818121012101818181818181810101010101018181012101010181818 % 181816121612181818181818FF181818181018131618181818181A181A18 % 1812101010101010100A100A10101216181818181812101018101010FF12 % 181810101818181818121012101818181818181810101010101018181012 % 1010101818181818161216121818FF181818181818181810181316181818 % 18181A181A181812101010101010100A100A101012161818181818121010 % 181010101012181810101818181800FF1618181818181018181810121010 % 10181816181818161810101018131618181A181818121010101810181210 % 18181318181818181818181818181818181818181018101216181818181A % 181A1818FF181818181810100A1010101010101012181618181818181018 % 18181012101010181816181818161810101018FF1618181A181818121010 % 101810181210181813181818181818181818181818181818181810181012 % 1618181818FF181A181818181818181810100A1010101010101012181618 % 181818181018181810121010101818161818181618FF101018131618181A % 181818121010101810181210181813181818181818181818181818181818 % 18181018101216FF1818181A181A181818181818181810100A1010101010 % 1010121816181818181810181818101210101018181618FF181618101010 % 18131618181A181818121010101810181210181813181818181818181818 % 181818181818181810FF101216181818181A181A18181818181818181010 % 0A101010101010101218161818181818101818181012101010FF18161818 % 18161810101018131618181A181818121010101810181210181813181818 % 1818181818181818181818FF18181018101216181818181A181A18181818 % 1818181810100A1010101010101012181618181818181018181810FF1010 % 10181816181818161810101018131618181A181818121010101810181210 % 18181318181818181818181818FF1818181818181018101216181818181A % 181A181818181818181810100A1010101010101012181618181818181018 % 1818101210101018181618181800FF121818181818181818171210101010 % 121012181018121818181812161812161818181818101810121012161818 % 1018181818181818181818181818181A1818181818181818181818181818 % 181818FF1216181812101010121010101010101012121818181818181818 % 171210101010121012181018121818181812FF1812161818181818101810 % 1210121618181018181818181818181818181818181A1818181818181818 % 18181818FF18181818181216181812101010121010101010101012121818 % 1818181818181712101010101210121810181218FF181812161812161818 % 1818181018101210121618181018181818181818181818181818181A1818 % 181818181818FF1818181818181818181216181812101010121010101010 % 10101212181818181818181817121010101012101218FF18121818181812 % 161812161818181818101810121012161818101818181818181818181818 % 1818181A18181818FF181818181818181818181818181216181812101010 % 121010101010101012121818181818181818171210101010FF1012181018 % 121818181812161812161818181818101810121012161818101818181818 % 1818181818181818181AFF18181818181818181818181818181818181216 % 1818121010101210101010101010121218181818181818181712FF101010 % 121012181018121818181812161812161818181818101810121012161818 % 101818181818181818181818FF18181A1818181818181818181818181818 % 181818181216181812101010121010101010101012121818181818181818 % 17121010101012101218101800FF10121612181610181818121612101012 % 101210121618181818181818121018101216181618181810181012101210 % 18161818181818181A181A18181818181818181818181818181018181818 % 1818FF101012161818121018101010101010101010121612181610181818 % 1216121010121012101216181818181818FF121018101216181618181810 % 18101210121018161818181818181A181A18181818181818181818181818 % 181018FF1818181812101012161818121018101010101010101010121612 % 18161018181812161210101210121012161818FF18181818121018101216 % 18161818181018101210121018161818181818181A181A18181818181818 % 1818181818FF181018181818181812101012161818121018101010101010 % 101010121612181610181818121612101012101210FF1618181818181818 % 12101810121618161818181018101210121018161818181818181A181A18 % 18181818181818FF18181818181018181818181812101012161818121018 % 1010101010101010101216121816101818181216121010FF101210121618 % 181818181818121018101216181618181810181012101210181618181818 % 18181A181A18181818FF1818181818181818181018181818181812101012 % 16181812101810101010101010101012161218161018181812FF12101012 % 101210121618181818181818121018101216181618181810181012101210 % 18161818181818181A181AFF181818181818181818181818181018181818 % 181812101012161818121018101010101010101010121612181610181818 % 121612101012101210121600FF1010121012181218161810121012101010 % 101010121216181818161810181010121012181818181612101810121012 % 12101818181818181818181A18181A1E181A181818181818181818181818 % 18FF10101210181216181810121010121010101010121012181218161810 % 12101210101010101012121618181816FF10181010121012181818181612 % 10181012101212101818181818181818181A18181A1E181A181818181818 % 1818FF181818181810101210181216181810121010121010101010121012 % 181218161810121012101010101010121216FF1818161810181010121012 % 18181818161210181012101212101818181818181818181A18181A1E181A % 18181818FF18181818181818181810101210181216181810121010121010 % 1010101210121812181618101210121010101010FF121216181818161810 % 18101012101218181818161210181012101212101818181818181818181A % 18181A1E181AFF1818181818181818181818181810101210181216181810 % 12101012101010101012101218121816181012101210FF10101010121216 % 181818161810181010121012181818181612101810121012121018181818 % 18181818181A1818FF1E181A181818181818181818181818181810101210 % 181216181810121010121010101010121012181218161810FF1012101010 % 101010121216181818161810181010121012181818181612101810121012 % 12101818181818181818FF1A18181A1E181A181818181818181818181818 % 181810101210181216181810121010121010101010121012181218161810 % 1210121010101010101200FF101010101012161218101812161210101012 % 101210101210181218181818181810181810121210121810121010101010 % 1210121818181818181818181A181A18181818181818181818181A181818 % FF1010121012101210121810121010101210101010101012161218101812 % 161210101012101210101210181218FF1818181810181810121210121810 % 1210101010101210121818181818181818181A181A181818181818181818 % 18FF1A181818181010121012101210121810121010101210101010101012 % 1612181018121612101010121012101012FF181218181818181810181810 % 1212101218101210101010101210121818181818181818181A181A181818 % 181818FF181818181A181818181010121012101210121810121010101210 % 10101010101216121810181216121010101210FF10101210181218181818 % 181810181810121210121810121010101010121012181818181818181818 % 1A181A1818FF18181818181818181A181818181010121012101210121810 % 121010101210101010101012161218101812161210FF1012101210101210 % 181218181818181810181810121210121810121010101010121012181818 % 1818181818181AFF1A18181818181818181818181A181818181010121012 % 1012101218101210101012101010101010121612181018FF161210101012 % 101210101210181218181818181810181810121210121810121010101010 % 121012181818181818FF18181A181A18181818181818181818181A181818 % 181010121012101210121810121010101210101010101012161218101812 % 16121010101210121000FF10101012181818161818181018161810101010 % 101012101210101218161818181818101210101018161210121010101010 % 101210121612181818181A18201E1A181A181818181818181818181818FF % 181812101010101018101818181812101010101012181818161818181018 % 161810101010101012101210101218161818181818101210101018161210 % 121010101010101210121612181818181A18201E1A181A18181818181818 % FF1818181818181812101010101018101818181812101010101012181818 % 161818181018161810101010101012101210101218161818181818101210 % 101018161210121010101010101210121612181818181A18201E1A181A18 % 1818FF181818181818181818181812101010101018101818181812101010 % 101012181818161818181018161810101010101012101210101218161818 % 181818101210101018161210121010101010101210121612181818181A18 % 201E1A18FF18181818181818181818181818181812101010101018101818 % 181812101010101012181818161818181018161810101010101012101210 % 101218161818181818101210101018161210121010101010101210121612 % 181818181A18FF1E1A181A18181818181818181818181818181812101010 % 101018101818181812101010101012181818161818181018161810101010 % 101012101210101218161818181818101210101018161210121010101010 % 1012101216121818FF181A18201E1A181A18181818181818181818181818 % 181812101010101018101818181812101010101012181818161818181018 % 161810101010101000FF1810121018181818121810181818181810121012 % 101010101012101012121018181018101010101812101010101010101010 % 10101010101818181818181A181A1818181818161318181818181818FF18 % 121010101010101012101818181818181810121018181818121810181818 % 181810121012101010101012101012121018181018101010101812101010 % 10101010101010101010101818181818181A181A181818181816131818FF % 181818181818121010101010101012101818181818181810121018181818 % 121810181818181810121012101010101012101012121018181018101010 % 10181210101010101010101010101010101818181818181A181A18181818 % 18FF13181818181818181818121010101010101012101818181818181810 % 121018181818121810181818181810121012101010101012101012121018 % 18101810101010181210101010101010101010101010101818181818181A % 181A18FF1818181613181818181818181818121010101010101012101818 % 181818181810121018181818121810181818181810121012101010101012 % 101012121018181018101010101812101010101010101010101010101018 % 1818181818FF181A18181818181613181818181818181818121010101010 % 101012101818181818181810121018181818121810181818181810121012 % 101010101012101012121018181018101010101812101010101010101010 % 10101010101818FF1818181A181A18181818181613181818181818181818 % 121010101010101012101818181818181810121018181818121810181818 % 1818101210121000FF1A1818181618181816181818181618181818101010 % 101012121012101010101218101210121010181016121010101010101010 % 10101010101818181818181820181A181818121612101818181012FF1216 % 1010101010121010181818181818181A1818181618181816181818181618 % 181818101010101012121012101010101218101210121010181016121010 % 10101010101010101010101818181818181820181A18181812161210FF18 % 1810121612161010101010121010181818181818181A1818181618181816 % 181818181618181818101010101012121012101010101218101210121010 % 18101612101010101010101010101010101818181818181820181A181818 % FF16121018181810121612161010101010121010181818181818181A1818 % 181618181816181818181618181818101010101012121012101010101218 % 101210121010181016121010101010101010101010101018181818181818 % 2018FF181818121612101818181012161216101010101012101018181818 % 1818181A1818181618181816181818181618181818101010101012121012 % 101010101218101210121010181016121010101010101010101010101018 % 18181818FF1820181A181818121612101818181012161216101010101012 % 1010181818181818181A1818181618181816181818181618181818101010 % 101012121012101010101218101210121010181016121010101010101010 % 101010101018FF181818181820181A181818121612101818181012161216 % 1010101010121010181818181818181A1818181618181816181818181618 % 18181810101000FF181818181A1818181810181018181816181216121018 % 101010121010101010101012101216181812181818181810101010101010 % 10101010121018181A2021181818181810161210121010121018FF181813 % 10100A08081010101216181A1818181818181A1818181810181018181816 % 181216121018101010121010101010101012101216181812181818181810 % 10101010101010101010121018181A202118181818181016121012FF1012 % 10181018181310100A08081010101216181A1818181818181A1818181810 % 181018181816181216121018101010121010101010101012101216181812 % 18181818181010101010101010101010121018181A2021181818181810FF % 12101210101210181018181310100A08081010101216181A181818181818 % 1A1818181810181018181816181216121018101010121010101010101012 % 10121618181218181818181010101010101010101010121018181A202118 % 18FF1818101612101210101210181018181310100A08081010101216181A % 1818181818181A1818181810181018181816181216121018101010121010 % 101010101012101216181812181818181810101010101010101010101210 % 18181AFF211818181818101612101210101210181018181310100A080810 % 10101216181A1818181818181A1818181810181018181816181216121018 % 101010121010101010101012101216181812181818181810101010101010 % 1010101012FF18181A202118181818181016121012101012101810181813 % 10100A08081010101216181A1818181818181A1818181810181018181816 % 181216121000FF1818181818181A18101812121212181818181012101210 % 101216181818181210121018101812181612181618181818101010101010 % 1010101012181818201A181818121218121810181012101810FF18161818 % 10101008101010181818181A181818181818181A18101812121212181818 % 181012101210101216181818181210121018101812181612181618181818 % 1010101010101010101012181818201A18181812121812181018FF121018 % 10121816181810101008101010181818181A181818181818181A18101812 % 121212181818181012101210101216181818181210121018101812181612 % 1816181818181010101010101010101012181818201A181818121218FF18 % 10181012101810121816181810101008101010181818181A181818181818 % 181A18101812121212181818181012101210101216181818181210121018 % 1018121816121816181818181010101010101010101012181818201A1818 % FF121218121810181012101810121816181810101008101010181818181A % 181818181818181A18101812121212181818181012101210101216181818 % 181210121018101812181612181618181818101010101010101010101218 % 1818FF1A1818181212181218101810121018101218161818101010081010 % 10181818181A181818181818181A18101812121212181818181012101210 % 101216181818181210121018101812181612181618181818101010101010 % 10101010FF181818201A1818181212181218101810121018101218161818 % 10101008101010181818181A181818181818181A18101812121212181818 % 1810121000FF1A181A181A18181818121010101010181210101012101216 % 121818181818181818181812161812101210121216181810101012101010 % 0E1010101218181818181810101012101818181818101210FF1018181818 % 1210101010121818181A18181A181A181A18181818121010101010181210 % 101012101216121818181818181818181812161812101210121216181810 % 1010121010100E101010121818181818181010101210181818FF18101210 % 1210181818181210101010121818181A18181A181A181A18181818121010 % 101010181210101012101216121818181818181818181812161812101210 % 1212161818101010121010100E1010101218181818181810101012FF1818 % 1818181012101210181818181210101010121818181A18181A181A181A18 % 181818121010101010181210101012101216121818181818181818181812 % 1618121012101212161818101010121010100E10101012181818181818FF % 1010121018181818181012101210181818181210101010121818181A1818 % 1A181A181A18181818121010101010181210101012101216121818181818 % 1818181818121618121012101212161818101010121010100E1010101218 % 18FF18181810101012101818181818101210121018181818121010101012 % 1818181A18181A181A181A18181818121010101010181210101012101216 % 121818181818181818181812161812101210121216181810101012101010 % 0E1010FF1218181818181810101012101818181818101210121018181818 % 1210101010121818181A18181A181A181A18181818121010101010181210 % 10101200FF18181818181818181810101010101018181012101010121012 % 161818181818181818181818131612101010101212181012101010101010 % 101010101216181812101210121012161818181818121010101012181818 % 18121012101818181A181818181818181818181810101010101018181012 % 101010121012161818181818181818181818131612101010101212181012 % 101010101010101010101216181812101210121012161818181818121010 % 10101218181818121012101818181A181818181818181818181810101010 % 101018181012101010121012161818181818181818181818131612101010 % 101212181012101010101010101010101216181812101210121012161818 % 18181812101010101218181818121012101818181A181818181818181818 % 181810101010101018181012101010121012161818181818181818181818 % 131612101010101212181012101010101010101010101216181812101210 % 12101216181818181812101010101218181818121012101818181A181818 % 181818181818181810101010101018181012101010121012161818181818 % 181818181818131612101010101212181012101010101010101010101216 % 181812101210121012161818181818121010101012181818181210121018 % 18181A181818181818181818181810101010101018181012101010121012 % 161818181818181818181818131612101010101212181012101010101010 % 101010101216181812101210121012161818181818121010101012181818 % 18121012101818181A181818181818181818181810101010101018181012 % 101000FF1818181818181818121010101010101818101010101218101012 % 181818181818181818181816181818121010101012161218101012101010 % 101010121012101010101010101212181818181818101210101010101216 % 18121618181818181A181818181818181818121010101010101818101010 % 101218101012181818181818181818181816181818121010101012161218 % 101012101010101010121012101010101010101212181818181818101210 % 10101010121618121618181818181A181818181818181818121010101010 % 101818101010101218101012181818181818181818181816181818121010 % 101012161218101012101010101010121012101010101010101212181818 % 18181810121010101010121618121618181818181A181818181818181818 % 121010101010101818101010101218101012181818181818181818181816 % 181818121010101012161218101012101010101010121012101010101010 % 10121218181818181810121010101010121618121618181818181A181818 % 181818181818121010101010101818101010101218101012181818181818 % 181818181816181818121010101012161218101012101010101010121012 % 101010101010101212181818181818101210101010101216181216181818 % 18181A181818181818181818121010101010101818101010101218101012 % 181818181818181818181816181818121010101012161218101012101010 % 101010121012101010101010101212181818181818101210101010101216 % 18121618181818181A181818181818181818121010101010101818101010 % 1000FF181818181818181810121010101010181618181216121010101210 % 181810121818181818181818181818161210101018121612101010101010 % 12101012101012101010101010101818181A181812101010100808101012 % 101812171818181818181818181818181810121010101010181618181216 % 121010101210181810121818181818181818181818161210101018121612 % 10101010101012101012101012101010101010101818181A181812101010 % 100808101012101812171818181818181818181818181810121010101010 % 181618181216121010101210181810121818181818181818181818161210 % 10101812161210101010101012101012101012101010101010101818181A % 181812101010100808101012101812171818181818181818181818181810 % 121010101010181618181216121010101210181810121818181818181818 % 181818161210101018121612101010101010121010121010121010101010 % 10101818181A181812101010100808101012101812171818181818181818 % 181818181810121010101010181618181216121010101210181810121818 % 181818181818181818161210101018121612101010101010121010121010 % 12101010101010101818181A181812101010100808101012101812171818 % 181818181818181818181810121010101010181618181216121010101210 % 181810121818181818181818181818161210101018121612101010101010 % 12101012101012101010101010101818181A181812101010100808101012 % 101812171818181818181818181818181810121010101010181618181216 % 00FF12161818101810181210121010101212181818181812101010121613 % 101210181618181818181818181818181010101216121012101216181810 % 181012101216121010101010101818181818181818101010100A10101010 % 121612181818181812161818101810181210121010101212181818181812 % 101010121613101210181618181818181818181818181010101216121012 % 101216181810181012101216121010101010101818181818181818101010 % 100A10101010121612181818181812161818101810181210121010101212 % 181818181812101010121613101210181618181818181818181818181010 % 101216121012101216181810181012101216121010101010101818181818 % 181818101010100A10101010121612181818181812161818101810181210 % 121010101212181818181812101010121613101210181618181818181818 % 181818181010101216121012101216181810181012101216121010101010 % 101818181818181818101010100A10101010121612181818181812161818 % 101810181210121010101212181818181812101010121613101210181618 % 181818181818181818181010101216121012101216181810181012101216 % 121010101010101818181818181818101010100A10101010121612181818 % 181812161818101810181210121010101212181818181812101010121613 % 101210181618181818181818181818181010101216121012101216181810 % 181012101216121010101010101818181818181818101010100A10101010 % 121612181818181812161818101810181210121010101212181818181800 % FF1012101012161210101010121012161818181A18181210181218181818 % 101218121216181818181218181818181012101810181018101218181818 % 1812161218121010101010101818181A20181818101210101010100A1012 % 101818181818121012101012161210101010121012161818181A18181210 % 181218181818101218121216181818181218181818181012101810181018 % 1012181818181812161218121010101010101818181A2018181810121010 % 1010100A1012101818181818121012101012161210101010121012161818 % 181A18181210181218181818101218121216181818181218181818181012 % 1018101810181012181818181812161218121010101010101818181A2018 % 1818101210101010100A1012101818181818121012101012161210101010 % 121012161818181A18181210181218181818101218121216181818181218 % 181818181012101810181018101218181818181216121812101010101010 % 1818181A20181818101210101010100A1012101818181818121012101012 % 161210101010121012161818181A18181210181218181818101218121216 % 181818181218181818181012101810181018101218181818181216121812 % 1010101010101818181A20181818101210101010100A1012101818181818 % 121012101012161210101010121012161818181A18181210181218181818 % 101218121216181818181218181818181012101810181018101218181818 % 1812161218121010101010101818181A20181818101210101010100A1012 % 101818181818121012101012161210101010121012161818181A181800FF % 1818181818101216121612161218181818181A1818181010101010121018 % 10101010121818181810121010101018181012101812181816181A181818 % 181816181818181810101010101216181818181810121010101010101010 % 1010121018181818181818101216121612161218181818181A1818181010 % 101010121018101010101218181818101210101010181810121018121818 % 16181A181818181816181818181810101010101216181818181810121010 % 101010101010101012101818181818181810121612161216121818181818 % 1A1818181010101010121018101010101218181818101210101010181810 % 12101812181816181A181818181816181818181810101010101216181818 % 181810121010101010101010101012101818181818181810121612161216 % 1218181818181A1818181010101010121018101010101218181818101210 % 10101018181012101812181816181A181818181816181818181810101010 % 101216181818181810121010101010101010101012101818181818181810 % 1216121612161218181818181A1818181010101010121018101010101218 % 18181810121010101018181012101812181816181A181818181816181818 % 181810101010101216181818181810121010101010101010101012101818 % 1818181818101216121612161218181818181A1818181010101010121018 % 10101010121818181810121010101018181012101812181816181A181818 % 181816181818181810101010101216181818181810121010101010101010 % 1010121018181818181818101216121612161218181818181A181800FF1A % 181818101210181012101216181818181818181818181010101010101010 % 1010101012161818181010121012181810101216121618181818181A1818 % 181818181818161818181010101218101810181210101010121010101012 % 10121618181A181818101210181012101216181818181818181818181010 % 101010101010101010101216181818101012101218181010121612161818 % 1818181A1818181818181818161818181010101218101810181210101010 % 12101010101210121618181A181818101210181012101216181818181818 % 181818181010101010101010101010101216181818101012101218181010 % 1216121618181818181A1818181818181818161818181010101218101810 % 18121010101012101010101210121618181A181818101210181012101216 % 181818181818181818181010101010101010101010101216181818101012 % 1012181810101216121618181818181A1818181818181818161818181010 % 10121810181018121010101012101010101210121618181A181818101210 % 181012101216181818181818181818181010101010101010101010101216 % 1818181010121012181810101216121618181818181A1818181818181818 % 16181818101010121810181018121010101012101010101210121618181A % 181818101210181012101216181818181818181818181010101010101010 % 1010101012161818181010121012181810101216121618181818181A1818 % 181818181818161818181010101218101810181210101010121010101012 % 10121618181A181818101210181012101216181818181818181800FF1818 % 181818111813161216121818181818181A18181818101010101010100A10 % 101010101218181818181012161218101210181318181818181818181818 % 181012161318181818121010121010121018101012101216181618121618 % 181818181818181818111813161216121818181818181A18181818101010 % 101010100A10101010101218181818181012161218101210181318181818 % 181818181818181012161318181818121010121010121018101012101216 % 181618121618181818181818181818111813161216121818181818181A18 % 181818101010101010100A10101010101218181818181012161218101210 % 181318181818181818181818181012161318181818121010121010121018 % 101012101216181618121618181818181818181818111813161216121818 % 181818181A18181818101010101010100A10101010101218181818181012 % 161218101210181318181818181818181818181012161318181818121010 % 121010121018101012101216181618121618181818181818181818111813 % 161216121818181818181A18181818101010101010100A10101010101218 % 181818181012161218101210181318181818181818181818181012161318 % 181818121010121010121018101012101216181618121618181818181818 % 181818111813161216121818181818181A18181818101010101010100A10 % 101010101218181818181012161218101210181318181818181818181818 % 181012161318181818121010121010121018101012101216181618121618 % 181818181818181818111813161216121818181818181A181800FF1A1818 % 1818181618181210121618181A181A181818181810101010101010101010 % 081010101818181818181018161216121810181018101818181818181810 % 101012181818181818181010101012101210121012161818181818181818 % 1818181A18181818181618181210121618181A181A181818181810101010 % 101010101010081010101818181818181018161216121810181018101818 % 181818181810101012181818181818181010101012101210121012161818 % 1818181818181818181A18181818181618181210121618181A181A181818 % 181810101010101010101010081010101818181818181018161216121810 % 181018101818181818181810101012181818181818181010101012101210 % 1210121618181818181818181818181A1818181818161818121012161818 % 1A181A181818181810101010101010101010081010101818181818181018 % 161216121810181018101818181818181810101012181818181818181010 % 1010121012101210121618181818181818181818181A1818181818161818 % 1210121618181A181A181818181810101010101010101010081010101818 % 181818181018161216121810181018101818181818181810101012181818 % 1818181810101010121012101210121618181818181818181818181A1818 % 1818181618181210121618181A181A181818181810101010101010101010 % 081010101818181818181018161216121810181018101818181818181810 % 101012181818181818181010101012101210121012161818181818181818 % 1818181A18181818181618181210121618181A181A18181800FF18181818 % 18181818171216181818181818181A181818181118121012101010101010 % 080E10101818181818181210121018101810121812101818181817181218 % 181816181818181818181810FFFFFFFF1810121018181818181818181818 % 18181818181818181818171216181818181818181A181818181118121012 % 101010101010080E10101818181818181210121018101810121812101818 % 1818171812FFFFFFFF1818181818FFFF18101210FFFFFFFFFFFF18181818 % 18181818181818181818181818181818171216181818181818181A181818 % 181118121012101010101010080E10101818181818181210121018101810 % 12181210181818FFFFFFFF1818181618FFFF1818181818FFFFFFFFFF1810 % 121018181818181818181818181818181818181818181712161818181818 % 18181A181818181118121012101010101010080E10101818181818181210 % 121018101810121812FFFFFFFF1817181218FFFF1618181818FFFFFFFF10 % 121018101810121018181818181818181818181818181818181818181712 % 16181818181818181A181818181118121012101010101010080E10101818 % 1818181812101210181018FFFFFFFF1018181818FFFF1218181816FFFFFF % FF1818181810121018101810121018181818181818181818181818181818 % 18181818171216181818181818181A181818181118121012101010101010 % 080E101018181818181812101210181018101218FFFFFFFFFFFF17181218 % 181816181818181818181810121018101810121018181818181818181818 % 18181818181818181818171216181818181818181A181800FF1818181818 % 1A1818181812181818181818181818181618181612161810121012101010 % 101010101218161818181018181316131810121010121612181812161818 % 18181810181218181818FFFF1818FFFF1012101212181818181818181818 % 1818181818181A1818181812181818181818181818181618181612161810 % 121012101010101010101218161818181018181316131810121010121612 % 181812FFFF1818FFFF10181218FFFF1817181818FFFF1012101212181818 % 1818181818181818181818181A1818181812181818181818181818181618 % 181612161810121012101010101010101218161818181018181316131810 % 1210101216FFFF1812FFFF18181818FFFF12181818181718FFFF12101012 % 1012121818181818181818181818181818181A1818181812181818181818 % 181818181618181612161810121012101010101010101218161818181018 % 18131613181012FFFF1216FFFF18121618FFFF18181018FFFF1818FFFF18 % 1818121010121012121818181818181818181818181818181A1818181812 % 181818181818181818181618181612161810121012101010101010101218 % 161818181018181316FFFF1012FFFF12161218FFFF16181818FFFF1018FF % FF1818181718181812101012101212181818181818181818181818181818 % 1A1818181812181818181818181818181618181612161810121012101010 % 101010101218161818181018181316131810121010FFFF12181812161818 % 181818101812181818181718181812101012101212181818181818181818 % 1818181818181A18181818121818181818181818181800FF18181A181818 % 181818181718181818121818181818121210121012101216121012101210 % 101010101012181613101216181812161210121010121618181018181818 % 181816121618181818FFFF1612FFFF10101010121018181818181A181818 % 18181A181818181818181718181818121818181818121210121012101216 % 121012101210101010101012181613101216181812161210121010121618 % 1810FFFF1818FFFF161216181818181818161216FFFF1010101210181818 % 18181A18181818181A181818181818181718181818121818181818121210 % 121012101216121012101210101010101012181613101216181812161210 % 12101012FFFF1810FFFF18181818161216181818FFFFFFFFFFFF12101010 % 10121018181818181A18181818181A181818181818181718181818121818 % 181818121210121012101216121012101210101010101012181613101216 % 181812161210FFFF1012FFFF18101818181818181612FFFF1818FFFF1816 % 12161210101010121018181818181A18181818181A181818181818181718 % 181818121818181818121210121012101216121012101210101010101012 % 1816131012161818FFFF1210FFFF10121618181018181818FFFF1612FFFF % 18181818181612161210101010121018181818181A18181818181A181818 % 181818181718181818121818181818121210121012101216121012101210 % 1010101010121816131012161818121612101210FFFF1618181018181818 % 18181612161818181818181612161210101010121018181818181A181818 % 18181A18181818181818171818181812181818181800FF1818181818181A % 181818181818181818161818161810101010101010121012181612101010 % 100A10101210181810121818181018101010101010121810181018181618 % 1818181810181818FFFF1210FFFF121010101010181612181818181A1818 % 18181818181A181818181818181818161818161810101010101010121012 % 181612101010100A10101210181810121818181018101010101010121810 % 18FFFF1816FFFF18181810181818181612101810FFFF1010101018161218 % 1818181A181818181818181A181818181818181818161818161810101010 % 101010121012181612101010100A10101210181810121818181018101010 % 101010FFFF1018FFFF18161818181818101818FF1816FFFF181012101010 % 1010181612181818181A181818181818181A181818181818181818161818 % 161810101010101010121012181612101010100A10101210181810121818 % 1810181010FFFF1010FFFF10181018181618181818FFFF1818FFFF161210 % 1810121010101010181612181818181A181818181818181A181818181818 % 181818161818161810101010101010121012181612101010100A10101210 % 18181012181818FFFF1010FFFF10101218101810181816FFFF1818FFFF18 % 1818181612101810121010101010181612181818181A181818181818181A % 181818181818181818161818161810101010101010121012181612101010 % 100A1010121018181012181818101810101010FFFF121810181018181618 % 1818181810181818181612101810121010101010181612181818181A1818 % 18181818181A181818181818181818161818161800FF181818181A181818 % 181818181818181818181818181818101012101010101018121810181010 % 101012161818181818161817181818181810101010101218181012121818 % 18181210121012FFFF1012FFFF1210101010101010101012161818101818 % 18181A181818181818181818181818181818181818101012101010101018 % 121810181010101012161818181818161817181818181810101010101218 % FFFF1212FFFF1818121012101210121012181612FFFF1010101010101012 % 16181810181818181A181818181818181818181818181818181818101012 % 101010101018121810181010101012161818181818161817181818181810 % 1010FFFF1218FFFF1212181818181210121012FF12FFFF18161210101010 % 10101010101216181810181818181A181818181818181818181818181818 % 181818101012101010101018121810181010101012161818181818161817 % 18181818FFFF1010FFFF12181810121218181818FFFFFFFFFF1012101218 % 16121010101010101010101216181810181818181A181818181818181818 % 181818181818181818101012101010101018121810181010101012161818 % 181818161817FFFF1818FFFF1010101012181810121218FFFFFFFF101210 % 12101210121816121010101010101010101216181810181818181A181818 % 181818181818181818181818181818101012101010101018121810181010 % 101012161818181818161817181818181810FFFF10101218181012121818 % 181812101210121012101218161210101010101010101012161818101818 % 18181A1818181818181818181818181818181800FF1818181A1E181A1818 % 181612101218181818181818101810121010101010101218171818101210 % 101018181818181818181818171818161012101210121010101010101010 % 121612161216FFFF1018FFFF101010101010101010101012181018181818 % 1A1E181A1818181612101218181818181818101810121010101010101218 % 1718181012101010181818181818181818181718181610121012101210FF % FF1010FFFF10121612161216121810FFFF1210FFFF101010101010101012 % 1810181818181A1E181A1818181612101218181818181818101810121010 % 101010101218171818101210101018181818181818181818171818161012 % 10FFFF1210FFFF101010101012161216121612FFFFFF1012101010101010 % 1010101010121810181818181A1E181A1818181612101218181818181818 % 101810121010101010101218171818101210101018181818181818181818 % 171818FFFF1210FFFF12101010101010101012FFFF161216121810181012 % 1010101010101010101010121810181818181A1E181A1818181612101218 % 181818181818101810121010101010101218171818101210101018181818 % 1818181818FFFF1818FFFF12101210121010101010FFFF1012FFFF161216 % 1218101810121010101010101010101010121810181818181A1E181A1818 % 181612101218181818181818101810121010101010101218171818101210 % 1010181818181818181818181718181610FFFF1210121010101010101010 % 121612161216121810181012101010101010101010101012181018181818 % 1A1E181A181818161210121818181818181800FF1818181A181A18181812 % 101210101012161218101818181010101010101010121612181818181812 % 181818181818181818181818181818181816121010121012101010101010 % 1210121012FFFF1012FFFF10101210100810100F1010101012181818181A % 181A18181812101210101012161218101818181010101010101010121612 % 18181818181218181818181818181818181818181818181612101012FFFF % 1010FFFF10101210121012101010FFFF1210FFFF10100810100F10101010 % 12181818181A181A18181812101210101012161218101818181010101010 % 101010121612181818181812181818181818181818181818181818181816 % FFFF1012FFFF101010101010121012101210FFFFFF101210101210100810 % 100F1010101012181818181A181A18181812101210101012161218101818 % 181010101010101010121612181818181812181818181818181818181818 % 1818FFFF1816FFFF1012101210101010101012FFFF101210101012101210 % 101210100810100F1010101012181818181A181A18181812101210101012 % 161218101818181010101010101010121612181818181812181818181818 % 18181818FFFF1818FFFF18161210101210121010FFFF1010FFFF12101210 % 101012101210101210100810100F1010101012181818181A181A18181812 % 101210101012161218101818181010101010101010121612181818181812 % 1818181818181818181818181818FFFFFFFF121010121012101010101010 % 121012101210101012101210101210100810100F1010101012181818181A % 181A18181812101210101012161218101800FF1818181A18181A18181810 % 101010121012101212161218101010100A10101010121818181818181818 % 18181A181818181818161812181818181818101210101810101010101010 % 1216131810FFFFFFFF1818181010100A100B101010101010181818181A18 % 181A18181810101010121012101212161218101010100A10101010121818 % 18181818181818181A18181818181816181218181818181810121010FFFF % FFFF101010101216131810181218FFFFFFFF1010100A100B101010101010 % 181818181A18181A18181810101010121012101212161218101010100A10 % 10101012181818181818181818181A181818181818161812181818181818 % FFFFFFFF1810101010101010121613181018FFFF161818181010100A100B % 101010101010181818181A18181A18181810101010121012101212161218 % 101010100A1010101012181818181818181818181A181818181818161812 % 1818FFFFFFFF10121010181010101010101012FFFFFFFF18121816181818 % 1010100A100B101010101010181818181A18181A18181810101010121012 % 101212161218101010100A1010101012181818181818181818181A181818 % 18181816FFFFFFFF181818181012101018101010FFFFFFFF121613181018 % 1218161818181010100A100B101010101010181818181A18181A18181810 % 101010121012101212161218101010100A10101010121818181818181818 % 18181A181818181818161812181818FFFF18101210101810101010101010 % 1216131810181218161818181010100A100B101010101010181818181A18 % 181A181818101010101210121012121600FF1818181A181A181818181210 % 12101012101010101210121818101010100810121618181A181A18181818 % 1A1818181818181012121816181212181018161010181818181810101012 % 161216101316101818181818181010100E101010101010181818181A181A % 18181818121012101012101010101210121818101010100810121618181A % 181A181818181A1818181818181012121816181212181018161010181818 % 181810101012161216101316101818181818181010100E10101010101018 % 1818181A181A181818181210121010121010101012101218181010101008 % 10121618181A181A181818181A1818181818181012121816181212181018 % 161010181818181810101012161216101316101818181818181010100E10 % 1010101010181818181A181A181818181210121010121010101012101218 % 18101010100810121618181A181A181818181A1818181818181012121816 % 181212181018161010181818181810101012161216101316101818181818 % 181010100E101010101010181818181A181A181818181210121010121010 % 10101210121818101010100810121618181A181A181818181A1818181818 % 181012121816181212181018161010181818181810101012161216101316 % 101818181818181010100E101010101010181818181A181A181818181210 % 12101012101010101210121818101010100810121618181A181A18181818 % 1A1818181818181012121816181212181018161010181818181810101012 % 161216101316101818181818181010100E101010101010181818181A181A % 18181818121012101012101010101200FF10181818181818181818161216 % 1218101810181012101018181610101010081012161818181818181A1818 % 1818181818101210101012181010101210121818181818181A1818121818 % 121818181218181818181818161210101010101010101210181818181818 % 181818161216121810181018101210101818161010101008101216181818 % 1818181A1818181818181810121010101218101010121012181818181818 % 1A1818121818121818181218181818181818161210101010101010101210 % 181818181818181818161216121810181018101210101818161010101008 % 1012161818181818181A1818181818181810121010101218101010121012 % 1818181818181A1818121818121818181218181818181818161210101010 % 101010101210181818181818181818161216121810181018101210101818 % 1610101010081012161818181818181A1818181818181810121010101218 % 1010101210121818181818181A1818121818121818181218181818181818 % 161210101010101010101210181818181818181818161216121810181018 % 1012101018181610101010081012161818181818181A1818181818181810 % 1210101012181010101210121818181818181A1818121818121818181218 % 181818181818161210101010101010101210181818181818181818161216 % 1218101810181012101018181610101010081012161818181818181A1818 % 1818181818101210101012181010101210121818181818181A1818121818 % 121818181218181818181818161210101010101010101210181818181818 % 181818161216121810181018101200FF1012161818181818101210121018 % 181818181312101010101212181810121012101818181818181818181A18 % 181818101210101010121610101210121012101818181818181818101816 % 181018181612101010121818181010101010101010101012161818181818 % 101210121018181818181312101010101212181810121012101818181818 % 181818181A18181818101210101010121610101210121012101818181818 % 181818101816181018181612101010121818181010101010101010101012 % 161818181818101210121018181818181312101010101212181810121012 % 101818181818181818181A18181818101210101010121610101210121012 % 101818181818181818101816181018181612101010121818181010101010 % 101010101012161818181818101210121018181818181312101010101212 % 181810121012101818181818181818181A18181818101210101010121610 % 101210121012101818181818181818101816181018181612101010121818 % 181010101010101010101012161818181818101210121018181818181312 % 101010101212181810121012101818181818181818181A18181818101210 % 101010121610101210121012101818181818181818101816181018181612 % 101010121818181010101010101010101012161818181818101210121018 % 181818181312101010101212181810121012101818181818181818181A18 % 181818101210101010121610101210121012101818181818181818101816 % 181018181612101010121818181010101010101010101012161818181818 % 1012101210181818181813121000FF101218161818101010101010101818 % 181818181010101010101618181816101018181818181818181818181818 % 181012101010101010121010101210101210181812161218181A18181218 % 181810181010101010101218101010121010101010101218161818101010 % 101010101818181818181010101010101618181816101018181818181818 % 181818181818181012101010101010121010101210101210181812161218 % 181A18181218181810181010101010101218101010121010101010101218 % 161818101010101010101818181818181010101010101618181816101018 % 181818181818181818181818181012101010101010121010101210101210 % 181812161218181A18181218181810181010101010101218101010121010 % 101010101218161818101010101010101818181818181010101010101618 % 181816101018181818181818181818181818181012101010101010121010 % 101210101210181812161218181A18181218181810181010101010101218 % 101010121010101010101218161818101010101010101818181818181010 % 101010101618181816101018181818181818181818181818181012101010 % 101010121010101210101210181812161218181A18181218181810181010 % 101010101218101010121010101010101218161818101010101010101818 % 181818181010101010101618181816101018181818181818181818181818 % 181012101010101010121010101210101210181812161218181A18181218 % 181810181010101010101218101010121010101010101218161818101010 % 10101010181818181818101000FF10101012101012101010101012181818 % 181818181010080A10101012181818181818181818181218181818171812 % 181010101010101012181810101012161818161816181618171A18181810 % 121818181812101010101018121610101210101010101012101012101010 % 101012181818181818181010080A10101012181818181818181818181218 % 181818171812181010101010101012181810101012161818161816181618 % 171A18181810121818181812101010101018121610101210101010101012 % 101012101010101012181818181818181010080A10101012181818181818 % 181818181218181818171812181010101010101012181810101012161818 % 161816181618171A18181810121818181812101010101018121610101210 % 101010101012101012101010101012181818181818181010080A10101012 % 181818181818181818181218181818171812181010101010101012181810 % 101012161818161816181618171A18181810121818181812101010101018 % 121610101210101010101012101012101010101012181818181818181010 % 080A10101012181818181818181818181218181818171812181010101010 % 101012181810101012161818161816181618171A18181810121818181812 % 101010101018121610101210101010101012101012101010101012181818 % 181818181010080A10101012181818181818181818181218181818171812 % 181010101010101012181810101012161818161816181618171A18181810 % 121818181812101010101018121610101210101010101012101012101010 % 101012181818181818181000FF1210121018101810101010101012161818 % 181A18181010101010101010101018181818181818161818181818101810 % 121010101010121818181816121012101818181818181818181818181816 % 181818181710101210121612101210101818101210121018101810101010 % 101012161818181A18181010101010101010101018181818181818161818 % 181818101810121010101010121818181816121012101818181818181818 % 181818181816181818181710101210121612101210101818101210121018 % 101810101010101012161818181A18181010101010101010101018181818 % 181818161818181818101810121010101010121818181816121012101818 % 181818181818181818181816181818181710101210121612101210101818 % 101210121018101810101010101012161818181A18181010101010101010 % 101018181818181818161818181818101810121010101010121818181816 % 121012101818181818181818181818181816181818181710101210121612 % 101210101818101210121018101810101010101012161818181A18181010 % 101010101010101018181818181818161818181818101810121010101010 % 121818181816121012101818181818181818181818181816181818181710 % 101210121612101210101818101210121018101810101010101012161818 % 181A18181010101010101010101018181818181818161818181818101810 % 121010101010121818181816121012101818181818181818181818181816 % 181818181710101210121612101210101818101210121018101810101010 % 101012161818181A181800FF181818181818181810121210121012181818 % 181818181010101010101010101012161818181818181718121612101210 % 101210121818181818181818101210181818181818181818181818181811 % 181218181818161210181018101818181818181818181818181810121210 % 121012181818181818181010101010101010101012161818181818181718 % 121612101210101210121818181818181818101210181818181818181818 % 181818181811181218181818161210181018101818181818181818181818 % 181810121210121012181818181818181010101010101010101012161818 % 181818181718121612101210101210121818181818181818101210181818 % 181818181818181818181811181218181818161210181018101818181818 % 181818181818181810121210121012181818181818181010101010101010 % 101012161818181818181718121612101210101210121818181818181818 % 101210181818181818181818181818181811181218181818161210181018 % 101818181818181818181818181810121210121012181818181818181010 % 101010101010101012161818181818181718121612101210101210121818 % 181818181818101210181818181818181818181818181811181218181818 % 161210181018101818181818181818181818181810121210121012181818 % 181818181010101010101010101012161818181818181718121612101210 % 101210121818181818181818101210181818181818181818181818181811 % 181218181818161210181018101818181818181818181818181810121210 % 12101218181818181800FF1A181818181818181818101010101012181818 % 181818101810121010101010101210181218181818181612181012101010 % 10101018181818181A181810101012101216121612101210181818181810 % 1012101818181012101210121818181A181A181818181818181818101010 % 101012181818181818101810121010101010101210181218181818181612 % 18101210101010101018181818181A181810101012101216121612101210 % 1818181818101012101818181012101210121818181A181A181818181818 % 181818101010101012181818181818101810121010101010101210181218 % 18181818161218101210101010101018181818181A181810101012101216 % 1216121012101818181818101012101818181012101210121818181A181A % 181818181818181818101010101012181818181818101810121010101010 % 10121018121818181818161218101210101010101018181818181A181810 % 101012101216121612101210181818181810101210181818101210121012 % 1818181A181A181818181818181818101010101012181818181818101810 % 121010101010101210181218181818181612181012101010101010181818 % 18181A181810101012101216121612101210181818181810101210181818 % 1012101210121818181A181A181818181818181818101010101012181818 % 181818101810121010101010101210181218181818181612181012101010 % 10101018181818181A181810101012101216121612101210181818181810 % 1012101818181012101210121818181A181A181818181818181818101010 % 101012181818181800FF1818181818181818181818121010101210121018 % 101812101216181018121610101210181718181818181810181012101010 % 121818181A18181818181810101010101010101010101012161818101210 % 101018121210101810121018181818181818181818181818181818121010 % 101210121018101812101216181018121610101210181718181818181810 % 181012101010121818181A18181818181810101010101010101010101012 % 161818101210101018121210101810121018181818181818181818181818 % 181818121010101210121018101812101216181018121610101210181718 % 181818181810181012101010121818181A18181818181810101010101010 % 101010101012161818101210101018121210101810121018181818181818 % 181818181818181818121010101210121018101812101216181018121610 % 101210181718181818181810181012101010121818181A18181818181810 % 101010101010101010101012161818101210101018121210101810121018 % 181818181818181818181818181818121010101210121018101812101216 % 181018121610101210181718181818181810181012101010121818181A18 % 181818181810101010101010101010101012161818101210101018121210 % 101810121018181818181818181818181818181818121010101210121018 % 101812101216181018121610101210181718181818181810181012101010 % 121818181A18181818181810101010101010101010101012161818101210 % 101018121210101810121018181818181818181818181818181818121010 % 1012101210181000FF1A1818181818181818181818181210101010101012 % 1010181012181818181A1810121018181818181818181818171810121012 % 16181818181A181818121010101010101010101010101012181618181012 % 1012101010101210181018161818181A1818181818181818181818181210 % 1010101010121010181012181818181A1810121018181818181818181818 % 17181012101216181818181A181818121010101010101010101010101012 % 1816181810121012101010101210181018161818181A1818181818181818 % 1818181812101010101010121010181012181818181A1810121018181818 % 18181818181817181012101216181818181A181818121010101010101010 % 1010101010121816181810121012101010101210181018161818181A1818 % 1818181818181818181812101010101010121010181012181818181A1810 % 12101818181818181818181817181012101216181818181A181818121010 % 101010101010101010101012181618181012101210101010121018101816 % 1818181A1818181818181818181818181210101010101012101018101218 % 1818181A181012101818181818181818181817181012101216181818181A % 181818121010101010101010101010101012181618181012101210101010 % 1210181018161818181A1818181818181818181818181210101010101012 % 1010181012181818181A1810121018181818181818181818171810121012 % 16181818181A181818121010101010101010101010101012181618181012 % 1012101010101210181018161818181A1818181818181818181818181210 % 10101010101200FF18181818181012101817181818181810121010121010 % 121012161818181818181818101818181818181818181818181818161818 % 18181A181818181618181810101010101010101010101010121818181818 % 181612161216121012101218181818181818181012101817181818181810 % 121010121010121012161818181818181818101818181818181818181818 % 18181816181818181A181818181618181810101010101010101010101010 % 121818181818181612161216121012101218181818181818181012101817 % 181818181810121010121010121012161818181818181818101818181818 % 18181818181818181816181818181A181818181618181810101010101010 % 101010101010121818181818181612161216121012101218181818181818 % 181012101817181818181810121010121010121012161818181818181818 % 10181818181818181818181818181816181818181A181818181618181810 % 101010101010101010101010121818181818181612161216121012101218 % 181818181818181012101817181818181810121010121010121012161818 % 18181818181810181818181818181818181818181816181818181A181818 % 181618181810101010101010101010101010121818181818181612161216 % 121012101218181818181818181012101817181818181810121010121010 % 121012161818181818181818101818181818181818181818181818161818 % 18181A181818181618181810101010101010101010101010121818181818 % 181612161216121012101218181818181818181012101817181818181810 % 121010121000FF1818111210101010121818181818181818181210101210 % 101210121810121618181818181818181A18181818181818181818181818 % 18181A181818181818181012101210101210101010101018181820191818 % 181818181818101010121012181818111210101010121818181818181818 % 181210101210101210121810121618181818181818181A18181818181818 % 18181818181818181A181818181818181012101210101210101010101018 % 181820191818181818181818101010121012181818111210101010121818 % 181818181818181210101210101210121810121618181818181818181A18 % 18181818181818181818181818181A181818181818181012101210101210 % 101010101018181820191818181818181818101010121012181818111210 % 101010121818181818181818181210101210101210121810121618181818 % 181818181A1818181818181818181818181818181A181818181818181012 % 101210101210101010101018181820191818181818181818101010121012 % 181818111210101010121818181818181818181210101210101210121810 % 121618181818181818181A1818181818181818181818181818181A181818 % 181818181012101210101210101010101018181820191818181818181818 % 101010121012181818111210101010121818181818181818181210101210 % 101210121810121618181818181818181A18181818181818181818181818 % 18181A181818181818181012101210101210101010101018181820191818 % 181818181818101010121012181818111210101010121818181818181818 % 1812101000FF181818161812181612101212181818181018101813181818 % 181612161818181818181818181A181818181A1818181812101316181818 % 181818181812101210121012161818181010101010101018181818181818 % 181810181818181012101018181818161812181612101212181818181018 % 101813181818181612161818181818181818181A181818181A1818181812 % 101316181818181818181812101210121012161818181010101010101018 % 181818181818181810181818181012101018181818161812181612101212 % 181818181018101813181818181612161818181818181818181A18181818 % 1A1818181812101316181818181818181812101210121012161818181010 % 101010101018181818181818181810181818181012101018181818161812 % 181612101212181818181018101813181818181612161818181818181818 % 181A181818181A1818181812101316181818181818181812101210121012 % 161818181010101010101018181818181818181810181818181012101018 % 181818161812181612101212181818181018101813181818181612161818 % 181818181818181A181818181A1818181812101316181818181818181812 % 101210121012161818181010101010101018181818181818181810181818 % 181012101018181818161812181612101212181818181018101813181818 % 181612161818181818181818181A181818181A1818181812101316181818 % 181818181812101210121012161818181010101010101018181818181818 % 181810181818181012101018181818161812181612101212181818181018 % 10181300FF10181018101818181818101618181818181818181816181212 % 101210121818181818181818181818181818181A18181618181818181818 % 181818181610101210101210181018121012101010121012101217181818 % 101818181810121010101810181018101818181818101618181818181818 % 181816181212101210121818181818181818181818181818181A18181618 % 181818181818181818181610101210101210181018121012101010121012 % 101217181818101818181810121010101810181018101818181818101618 % 181818181818181816181212101210121818181818181818181818181818 % 181A18181618181818181818181818181610101210101210181018121012 % 101010121012101217181818101818181810121010101810181018101818 % 181818101618181818181818181816181212101210121818181818181818 % 181818181818181A18181618181818181818181818181610101210101210 % 181018121012101010121012101217181818101818181810121010101810 % 181018101818181818101618181818181818181816181212101210121818 % 181818181818181818181818181A18181618181818181818181818181610 % 101210101210181018121012101010121012101217181818101818181810 % 121010101810181018101818181818101618181818181818181816181212 % 101210121818181818181818181818181818181A18181618181818181818 % 181818181610101210101210181018121012101010121012101217181818 % 101818181810121010101810181018101818181818101618181818181818 % 181800FF1012121212101018181818181210121018121612161210101010 % 101010101018181818181818181818181A18181818181818181818181818 % 181818181813101012101210121810101010101010101012181812181618 % 101210121010101010121012121212101018181818181210121018121612 % 161210101010101010101018181818181818181818181A18181818181818 % 181818181818181818181813101012101210121810101010101010101012 % 181812181618101210121010101010121012121212101018181818181210 % 121018121612161210101010101010101018181818181818181818181A18 % 181818181818181818181818181818181813101012101210121810101010 % 101010101012181812181618101210121010101010121012121212101018 % 181818181210121018121612161210101010101010101018181818181818 % 181818181A18181818181818181818181818181818181813101012101210 % 121810101010101010101012181812181618101210121010101010121012 % 121212101018181818181210121018121612161210101010101010101018 % 181818181818181818181A18181818181818181818181818181818181813 % 101012101210121810101010101010101012181812181618101210121010 % 101010121012121212101018181818181210121018121612161210101010 % 101010101018181818181818181818181A18181818181818181818181818 % 181818181813101012101210121810101010101010101012181812181618 % 101210121010101010121012121212101018181818181210121018121612 % 1600FF121010101010121810181818161010121010101210121612101010 % 10101010101210161818181818181A1820181A1818181818181818181818 % 181818181618101010101012101812121012101012101012101817121210 % 181618101210101010121010101010121810181818161010121010101210 % 12161210101010101010101210161818181818181A1820181A1818181818 % 181818181818181818181618101010101012101812121012101012101012 % 101817121210181618101210101010121010101010121810181818161010 % 12101010121012161210101010101010101210161818181818181A182018 % 1A1818181818181818181818181818181618101010101012101812121012 % 101012101012101817121210181618101210101010121010101010121810 % 181818161010121010101210121612101010101010101012101618181818 % 18181A1820181A1818181818181818181818181818181618101010101012 % 101812121012101012101012101817121210181618101210101010121010 % 101010121810181818161010121010101210121612101010101010101012 % 10161818181818181A1820181A1818181818181818181818181818181618 % 101010101012101812121012101012101012101817121210181618101210 % 101010121010101010121810181818161010121010101210121612101010 % 10101010101210161818181818181A1820181A1818181818181818181818 % 181818181618101010101012101812121012101012101012101817121210 % 181618101210101010121010101010121810181818161010121010101210 % 00FF10101012101210101218181810121012161218121612101010101008 % 100E1010101012121618181818181A181818181818181818181818181818 % 181818181810101010101012101817181612101010121618181818101618 % 181816181618181010101012101210101218181810121012161218121612 % 101010101008100E1010101012121618181818181A181818181818181818 % 181818181818181818181810101010101012101817181612101010121618 % 181818101618181816181618181010101012101210101218181810121012 % 161218121612101010101008100E1010101012121618181818181A181818 % 181818181818181818181818181818181810101010101012101817181612 % 101010121618181818101618181816181618181010101012101210101218 % 181810121012161218121612101010101008100E10101010121216181818 % 18181A181818181818181818181818181818181818181810101010101012 % 101817181612101010121618181818101618181816181618181010101012 % 101210101218181810121012161218121612101010101008100E10101010 % 12121618181818181A181818181818181818181818181818181818181810 % 101010101012101817181612101010121618181818101618181816181618 % 181010101012101210101218181810121012161218121612101010101008 % 100E1010101012121618181818181A181818181818181818181818181818 % 181818181810101010101012101817181612101010121618181818101618 % 181816181618181010101012101210101218181810121012161218121600 % FF1012101010101010101012181818181012101010101210121010101010 % 1010101010101012181818181A18181A1818181818171818121618181818 % 181618181010101008101018181818181818181613181818181818121818 % 181818181818101012101010101010101012181818181012101010101210 % 1210101010101010101010101012181818181A18181A1818181818171818 % 121618181818181618181010101008101018181818181818181613181818 % 181818121818181818181818101012101010101010101012181818181012 % 1010101012101210101010101010101010101012181818181A18181A1818 % 181818171818121618181818181618181010101008101018181818181818 % 181613181818181818121818181818181818101012101010101010101012 % 181818181012101010101210121010101010101010101010101218181818 % 1A18181A1818181818171818121618181818181618181010101008101018 % 181818181818181613181818181818121818181818181818101012101010 % 101010101012181818181012101010101210121010101010101010101010 % 1012181818181A18181A1818181818171818121618181818181618181010 % 101008101018181818181818181613181818181818121818181818181818 % 101012101010101010101012181818181012101010101210121010101010 % 1010101010101012181818181A18181A1818181818171818121618181818 % 181618181010101008101018181818181818181613181818181818121818 % 1818181818181010121010101010101010121818181810121010101000FF % 121010121012101210121010121612161216121813181718101210101010 % 101010101010101816181818181A18181818181812101210121812171818 % 18121810101008101010101818181A18181A181818181A18181818181818 % 181818181810121010121012101210121010121612161216121813181718 % 101210101010101010101010101816181818181A18181818181812101210 % 1218121718184774BBFFFFFF7A59201010181818FFFFFF1A181818FFFFFF % 1818181818FFFFFF181818101210477FFFFF7F4010121010121612161216 % 12183077FFFFBB742E28FFFF7F1010FFFFFF1018161818FFFFFF18181818 % 182D74FFFF8E5318FFFFFF18181218101010081010101018184777BBFFFF % A37746181A1818181818184677BBFFFF773E121010121012104072FFFFFF % 90551216121612FFFFFF17181012FFFFFF1010101010FFFFFF1816181818 % 184F83FFFF8346181210121012181217181818FFFFFF1010081010101018 % 18181A18183877FFFF934F18FFFFFF18181818FFFFFF1810121010FFFFFF % 10121012102067BBFFFF7F451218131817187FFFFF71101010FFFFFF1010 % 101816184677BBFFFF7747181818121012FFFFFF1217181818FFFFFF1010 % 0810103E72FFFFFF9357181A181818181A18181818181818181818181810 % 121010121012101210121010121612161216121813181718101210101010 % 101010101010101816181818181A18181818181812101210121812171818 % 18121810101008101010101818181A18181A181818181A18181818181818 % 18181818181012101012101210121012101012161216121612181300FF10 % 101210101210181210121010121018181818181618181818161010101010 % 0A0E10101212181218181818181818181818101012101010121618121612 % 1816101010080A1010121818181820181818181818181818181812101210 % 181216181010101210101210181210121010121018181818181618181818 % 1610101010100A0E10101212181218181818181818181818101012101010 % 1216181291FFFFFFFFFFFFFFFFBB3E12181818FFFFFF18181818FFFFFF18 % 18181210FFFFFF1216181029BBFFFFFFFFFFFF6710121010121018181818 % 3EFFFFFFFFFFFFFFBBFFFF350A0EFFFFFF1218121818FFFFFF181818183E % FFFFFFFFFFFF7FFFFFFF16121816101010080A1010122893FFFFFFFFFFFF % FFFFA32D18181818128EFFFFFFFFFFFFFF72101210101265FFFFFFFFFFFF % FF8E18181818FFFFFF18181816FFFFFF10100A0E10FFFFFF181218182EBB % FFFFFFFFFFFF651012101010121618121612FFFFFF1010080A1010121818 % 1818202EFFFFFFFFFFFF6AFFFFFF12101210FFFFFF1810101012FFFFFF10 % 18121038BBFFFFFFFFFFFF6A1816181877FFFFFF8E101010FFFFFF101212 % 181293FFFFFFFFFFFFFF771810101210FFFFFF1618121612FFFFFF101008 % 0A65FFFFFFFFFFFFFF931818181818181818181812101210181216181010 % 101210101210181210121010121018181818181618181818161010101010 % 0A0E10101212181218181818181818181818101012101010121618121612 % 1816101010080A1010121818181820181818181818181818181812101210 % 181216181010101210101210181210121010121018181818181600FF1218 % 1018181818181A1818181810101818161216121012101218181818121010 % 101010101010101818181818181818101018121816121612101210121010 % 1218181010101010101816181A181A181A18181A181A1816121010121012 % 1012101812181018181818181A1818181810101818161216121012101218 % 181818121010101010101010101818181818181818101018121816121612 % 10127FFFFFFFFFFFFFFFFFFFFFFF29181618FFFFFF181A1818FFFFFF1816 % 121010FFFFFF10121018BBFFFFFFFFFFFFFFFF3E18181810101818161291 % FFFF67101246BBFFFFFF101010FFFFFF1010101818FFFFFF18181810BBFF % FFFFFFFFFFFFFFFFFF121010121818101010101021BBFFFFFFFFFFFFFFFF % FFFFBB301816128EFFFFFFFFFFFFFFFFFF7710181847FFFF932E181861FF % FF69181612FFFFFF12101218FFFFFF1210101010FFFFFF10101818BBFFFF % FFFFFFFFFFFF3818161216121012101210FFFFFF18101010101010181618 % 1A1877FFFFFFFFFFFFFFFFFFFF10101210FFFFFF1018121810FFFFFF1818 % 1A18BBFFFFFFFFFFFFFFFF55121012BBFFFFFF6A181210FFFFFF10101010 % 8EFFFFFFFFFFFFFFFFFF7218121816FFFFFF1012101210FFFFFF1810103E % FFFF8E2D161864FFFF6A1A18181A181A1816121010121012101210181218 % 1018181818181A1818181810101818161216121012101218181818121010 % 101010101010101818181818181818101018121816121612101210121010 % 1218181010101010101816181A181A181A18181A181A1816121010121012 % 1012101812181018181818181A18181818101018181612161200FF101012 % 101818181818181A18181218181818181812101810101218181010101010 % 101010101210121618181818161210121018101818181810181012101210 % 121612101010101018181818181A18181A181A1818181812101210121012 % 101812101012101818181818181A18181218181818181812101810101218 % 181010101010101010101210121618181818161210121018101818181810 % 46FFFFFF74291216123EBBFFFF71181818FFFFFF18181A18FFFFFF181812 % 1012FFFFFF12101849FFFFBB3618184FFFFF931A1818121818181818FFFF % FF1810101235FFFFFF101010FFFFFF1012101216FFFFFF18161252FFFFBB % 3E18184EBBFFFFFF12101210121612101010107FFFFFBB57291A182E64FF % FFFF83181840FFFFFF5321122161FFFFFF401018A3FFFF29181A1818FFFF % BB181818FFFFFF18101012FFFFFF1010101010FFFFFF1210124DFFFFBB3E % 161247FFFF9210181818181018101210FFFFFF1612101010101018181818 % 18BBFFFF6C181A3EBBFFFFFF10121012FFFFFF1812101012FFFFFF181818 % 57FFFFBB30182893FFFFA3121018FFFFFF1828101010FFFFFF10101040FF % FFFF5628182860FFFFFF3E181018FFFFFF1018101210FFFFFF161210A0FF % FF2018181818FFFFBB181A181A1818181812101210121012101812101012 % 101818181818181A18181218181818181812101810101218181010101010 % 101010101210121618181818161210121018101818181810181012101210 % 121612101010101018181818181A18181A181A1818181812101210121012 % 101812101012101818181818181A1818121818181818181200FF10121010 % 121012181818181818181818181818181718131010101010121010101010 % 101010101210101212121012101010121012181818181818101210101010 % 10121818181316181818181A181818181818181818181010101010101012 % 101010121010121012181818181818181818181818181718131010101010 % 121010101010101010101210101212121012101010121012181818181877 % FFFF721010101012182EFFFFFF181818FFFFFF18181818FFFFFF18181010 % 10FFFFFF1012107FFFFF3E10121012181818181818181818181818A3FFFF % 4010101010FFFFFF101010FFFFFF1010121010FFFFFF1012107FFFFF3E12 % 1818184EFFFFFF1210101010101218181838FFFFBB2D181A181818183EA3 % 622E18187FFFFF51101010121065FFFF7210121012181818184777FFFFFF % 181818FFFFFF13101010FFFFFF1010101010FFFFFF1012107FFFFF401012 % 101010121012181818181818101210FFFFFF10121818181316181818181A % FFFFFF281818183EFFFFFF10101010FFFFFF1010101210FFFFFF12181893 % FFFF4618181828A3612D171813FFFFFF1010121010FFFFFF1010107FFFFF % 52121212101265FFFF74101218FFFFFF1818101210FFFFFF101218181813 % 1618184677FFFFFF18181818181818181010101010101012101010121010 % 121012181818181818181818181818181718131010101010121010101010 % 101010101210101212121012101010121012181818181818101210101010 % 10121818181316181818181A181818181818181818181010101010101012 % 101010121010121012181818181818181818181818181700FF1810101210 % 101818181818181818181818181818181816101012101010101010101010 % 101210101210121010121010101010101216181818181818101010101010 % 101018181612181818181818181818181818181810101010101010121010 % 181810101210101818181818181818181818181818181816101012101010 % 10101010101010121010121012101012101010101010121618181818BBFF % FF2110101010101018FFFFFF181818FFFFFF18181818FFFFFF1810101010 % FFFFFF121010BBFFFF10121010181818181818181818181818184FFFFFFF % A072532DFFFFFF101010FFFFFF1210101210FFFFFF121010FFFFFF101216 % 181818FFFFFF1010101010101010181868FFFF5618181818181818181818 % 181810FFFFFF2010101210102DFFFFBB12101018284F92FFFFFFFFFF9318 % 1818FFFFFF16101012FFFFFF1010101010FFFFFF101012BBFFFF10121010 % 1010101012161818181818181010FFFFFF101010181816121818181818FF % FFFF1818181818FFFFFF10101010FFFFFF1018181010FFFFFF181818FFFF % FF1818181818181818181816FFFFFF1010101010FFFFFF101012FFFFFF21 % 121010121029FFFFBB101216FFFFFF1818181010FFFFFF10101018182749 % 93FFFFFFFFFF931818181818181810101010101010121010181810101210 % 101818181818181818181818181818181816101012101010101010101010 % 101210101210121010121010101010101216181818181818101010101010 % 101018181612181818181818181818181818181810101010101010121010 % 1818101012101018181818181818181818181818181800FF181818101612 % 181018181818181818181818181818181818181010121018181010101210 % 10101210101010121010121010101010121818181818181012101010100A % 101010121818181818181818181718181818121012101010121010181818 % 181818101612181018181818181818181818181818181818181010121018 % 181010101210101012101010101210101210101010101218181818181810 % 12101010100A287FFFFFA3181818FFFFFF18181718FFFFFF1210121010FF % FFFF101818FFFFFFFFFFFFFFFFFFFFFF181818181818181818184EA3FFFF % FFFFFFFFFFFF181010FFFFFF1010121010FFFFFF101012FFFFFF10101218 % 1818FFFFFF1012101010100A101010A0FFFF351818181818181718181818 % 1210FFFFFF10121010181818FFFFFF10161269FFFFFFFFFFFFFFBB2D1818 % 18FFFFFF18181810FFFFFF1818101010FFFFFF101210FFFFFFFFFFFFFFFF % FFFFFF10121818181818181012FFFFFF100A10101012181818181818FFFF % FF1718181818FFFFFF10101012FFFFFF1818181818FFFFFF181018FFFFFF % 1818181818181818181818FFFFFF1012101818FFFFFF121010FFFFFF1010 % 1012101012FFFFFF101012FFFFFF1818181012FFFFFF100A101065FFFFFF % FFFFFFFFBB2D181718181818121012101010121010181818181818101612 % 181018181818181818181818181818181818181010121018181010101210 % 10101210101010121010121010101010121818181818181012101010100A % 101010121818181818181818181718181818121012101010121010181818 % 18181810161218101818181818181818181818181800FF1A181812121210 % 181012121018181818181818181216181818101210181818101018101818 % 181816121012101012161010101010121818181818181012101010101008 % 10101010181817181818181818181818161210101010101012181818181A % 181812121210181012121018181818181818181216181818101210181818 % 101018101818181816121012101012161010101010121818181818181012 % 10294671BBFFFFFFFF52181817FFFFFF18181818FFFFFF1210101010FFFF % FF181818BBFFFFFFFFFFFFFFFFFFBB1210181818181818181812162E4E69 % 8EFFFFFFFF181010FFFFFF1818181612FFFFFF101216FFFFFF1010121818 % 18FFFFFF10121010101010081010FFFFFF18171818181818181818181612 % 10FFFFFF2010121818182EFFFFFF12125CFFFFFFFFFFFF77471818181818 % FFFFFF18181810FFFFFF1818101018FFFFFF181816BBFFFFFFFFFFFFFFFF % FFBB10121818181818181012FFFFFFFFFFFFFFFFFFFFFF18171818FFFFFF % 1818181816FFFFFF10101010FFFFFF18181A1818FFFFFF101810FFFFFF18 % 18181818181818121618FFFFFF1210181818FFFFFF101818FFFFFF221012 % 1010122CFFFFFF101012FFFFFF1818181012FFFFFF10100859FFFFFFFFFF % FF774718181818181818161210101010101012181818181A181812121210 % 181012121018181818181818181216181818101210181818101018101818 % 181816121012101012161010101010121818181818181012101010101008 % 10101010181817181818181818181818161210101010101012181818181A % 181812121210181012121018181818181818181200FF1818121010101012 % 101010121012181818171818161812181012121012121818181818181818 % 1A1818181010181818101210101010101818181818161217121010101010 % 1010101012181818181818181118131810101010101012181818181A1818 % 121010101012101010121012181818171818161812181012121012121818 % 1818181818181A18181810101818181012101010101018181818181640A3 % FFFFFFFFFFFFFF6510101218FFFFFF18181811FFFFFF3E10101020FFFFFF % 18181877FFFF2210101010FFFF7F10121012181818171818161812181012 % 12FFFFFF181818FFFFFF46181A1829FFFFFF1818187FFFFF3E1010101847 % FFFFFF16121712101010101010FFFFFF1218181818181818111813181010 % 71FFFF5212181818186CFFFF741010BBFFFFFF723E1210121818181718FF % FFFF12181012FFFFFF4018181829FFFFFF181A1877FFFF2118181810FFFF % 7F10101018181818181612FFFFFFFFFFFFFFFFFFFFFF12181818FFFFFF18 % 11181318FFFFFF10101012FFFFFF471A181822FFFFFF1012107FFFFF3E12 % 181828A3612E161812FFFFFF1210121218FFFFFF18181877FFFF57181010 % 18186AFFFF71101010FFFFFF4618181622FFFFFF101010BBFFFFFF724018 % 1818181818181118131810101010101012181818181A1818121010101012 % 101010121012181818171818161812181012121012121818181818181818 % 1A1818181010181818101210101010101818181818161217121010101010 % 1010101012181818181818181118131810101010101012181818181A1818 % 1210101010121010101210121818181718181600FF181810101010101210 % 101010101216181818181012101210101010101010101818181818181818 % 181818181818181818101010101012181818181818181818101818121010 % 100A10101818181818181818181810121010101012161818181A18181810 % 101010101210101010101216181818181012101210101010101010101818 % 181818181818181818181818181818101010101012181818181883FFFFFF % FFFFFFFFA03E100A101018FFFFFF18181818FFFFFFBB3E101072FFFFFF18 % 181A47FFFF8E21102171FFFF47101010121618181818A0FFFF2A10101010 % FFFFFF101818FFFFFFBB47181877FFFFFF1818184EFFFFBB3E101246BBFF % FFFF18181818101818121010FFFFFF10181818181818181818181012103E % FFFFFF5528182964FFFFFF3E1010FFFFFF2910101021FFFFA3181818FFFF % FF12101010FFFFFFBB3E181877FFFFFF18181846FFFF9229182977FFFF46 % 10101218181818181818FFFFFFFFFFFFFFFFFFFFFF10181818FFFFFF1818 % 181810FFFFFF10101216FFFFFFBB47181872FFFFFF10121052FFFFBB3016 % 2892FFFFA0121012FFFFFF1010101010FFFFFF18181847FFFFFF57281829 % 61FFFFFF3E101010FFFFFFBB46181877FFFFFF181812FFFFFF2210101828 % FFFFA3181818181810121010101012161818181A18181810101010101210 % 101010101216181818181012101210101010101010101818181818181818 % 181818181818181818101010101012181818181818181818101818121010 % 100A10101818181818181818181810121010101012161818181A18181810 % 10101010121010101010121618181818101200FF18181810100808101010 % 10100B0E0A10101618181818181810181316121612161210121618181818 % 181818161218101818181818161010101012101010121010101218181618 % 101010181618181A1818181310101810181012181818181A181818181810 % 10080810101010100B0E0A10101618181818181810181316121612161210 % 12161818181818181816121810181818181816101010101252FFFFFFFFBB % 72492D18161810101018FFFFFF1A181818FFFFFFFFFFFFFFFFFFFF77181A % 181892FFFFFFFFFFFFFFBB1010100B0E0A1010161857FFFF9328101867FF % FF83121612FFFFFFFFFFFFFFFFFFFF7512181018BBFFFFFFFFFFFFFFFFFF % FF1010121010101218181692FFFF29181618181A1818181310101810187F % FFFFFFFFFFFFFFFFFF831810106AFFFF461010208BFFFF52101618FFFFFF % 18181018FFFFFFFFFFFFFFFFFFFF771818181892FFFFFFFFFFFFFFBB1818 % 161010101012101010FFFFFF101218181618101010181618FFFFFF181813 % 1010FFFFFF10121818FFFFFFFFFFFFFFFFFFFF6A08101010BBFFFFFFFFFF % FFFFFF4718FFFFFFFFFFFFFF121612FFFFFF1216181883FFFFFFFFFFFFFF % FFFF8318181816FFFFFFFFFFFFFFFFFFFF7210121877FFFF4710102891FF % FF571818181310101810181012181818181A181818181810100808101010 % 10100B0E0A10101618181818181810181316121612161210121618181818 % 181818161218101818181818161010101012101010121010101218181618 % 101010181618181A1818181310101810181012181818181A181818181810 % 10080810101010100B0E0A10101618181800FF1818181612101010101010 % 101010101010121818181818161018101612171218101210121818181818 % 181818101810181818181818181810121010121010101012161818181818 % 18181818181818181818181012101218161216181818181A181818181612 % 101010101010101010101010121818181818161018101612171218101210 % 1218181818181818181018101818181818181818101210A0FFFF7F361012 % 161818181818181818FFFFFF18181818FFFFFF65FFFFFFFFFFFF3518181A % 181893FFFFFFFFFFFF36101010101010101012181892FFFFFFFFFFFFFFFF % 3C121810FFFFFF69FFFFFFFFFFFF35101810183EFFFFFFFFFFFF8EFFFFFF % 1210101010121618181869FFFF5718181818181818181810121012181690 % FFFFFFFFFFFFFF831818161229BBFFFFFFFFFFFFFF8E10101218FFFFFF18 % 161018FFFFFF68FFFFFFFFFFFF35181818181893FFFFFFFFFFFF3E181818 % 1818101210101210FFFFFF121618181818181818181818FFFFFF18181810 % 12FFFFFF16121618FFFFFF6CFFFFFFFFFFFF2E1010101029BBFFFFFFFFFF % FF691818FFFFFFFFFFFFFF121712FFFFFF101218181892FFFFFFFFFFFFFF % 831818181818FFFFFF67FFFFFFFFFFFF2E1216182EBBFFFFFFFFFFFFFF92 % 18181818181012101218161216181818181A181818181612101010101010 % 101010101010121818181818161018101612171218101210121818181818 % 181818101810181818181818181810121010121010101012161818181818 % 18181818181818181818181012101218161216181818181A181818181612 % 1010101010101010101010101218181800FF181618181818181012101010 % 101010101010121618181818121812181218121012101210121018181816 % 181810181210121018181818181210101210121012101012181818181818 % 1818181818181818181818131618101218181818181A1818181618181818 % 181012101010101010101010121618181818121812181218121012101210 % 12101818181618181018121012101818181818121010FFFFFF1012101012 % 28FFFFFF18181818FFFFFF18181818FFFFFF16478EFFFF773518181A1818 % 18164693FFBB6A29121010101010101010101216184F83FFFFFFA06A2A18 % 121012FFFFFF123E92FFFF75351810181210122977BBFFA35612FFFFFF10 % 12101210101218181835FFFFBB2D18181818181835A3612B161810121847 % 77FFFFFF7746181618181818295A90FFFFFF7F471010101012FFFFFF1818 % 1218FFFFFF18408EFFFF732E12101818181618478EFFBB652A1018181818 % 18121010121012FFFFFF101218181818181818181818FFFFFF1818181813 % FFFFFF12181818FFFFFF184692FFFF77351818101210102165A0FFFF8E3E % 121618FFFFFFFFFFFFFF121812FFFFFF1210121018184775FFFFFF774010 % 1210181818FFFFFF103E90FFFF72301010121818296193FFFFFF834E1818 % 1818181818131618101218181818181A1818181618181818181012101010 % 101010101010121618181818121812181218121012101210121018181816 % 181810181210121018181818181210101210121012101012181818181818 % 1818181818181818181818131618101218181818181A1818181618181818 % 18101210101010101010101012161800FF18121216181818121612101010 % 10100A0F1010121818181618171816181618101210101010121018181812 % 161218101010181818181818121612181018101810101012161818181818 % 1A1818181A18181818181818181818161818181818181818121216181818 % 12161210101010100A0F1010121818181618171816181618101210101010 % 121018181812161218101010181818181818121612A3FFFF652810102990 % FFFF831818181A1818181A18181818181818181818161818181818181818 % 12121618181812161210101010100A0F1010121818181618171816181618 % 10121010101012101818181216121810101018181818181812FFFFFF1018 % 10181010101216181883FFFFBB5728181A2E56FFFFFF8318181818161818 % 18181818181812121618181812161210101010100A0F1010121818181618 % 171816181618101210101010121018181812161218101010181818181818 % 121612181018FFFFFF1010121618181818181A1818181A18181818181818 % 18181816181818181818181812121618181812161210101010100A0F1010 % 12181818FFFFFF1816181618101210101010121018181812161218101010 % 1818181818181216121810181018101010121618181818181A1818181A18 % 181818181818181818161818181818181818121216181818121612101010 % 10100A0F1010121818181618171816181618101210101010121018181812 % 161218101010181818181818121612181018101810101012161818181818 % 1A1818181A18181818181818181818161818181818181818121216181818 % 12161210101010100A0F1010121800FF1810101012101216121810121010 % 121010101010121618181818181818181810101010121010101210121612 % 181018101818181818181816121810181018121010101212181818181818 % 18181818181A181818181818181818181818181818181810101012101216 % 121810121010121010101010121618181818181818181810101010121010 % 101210121612181018101818181818181816121852FFFFFFFFFFFFFFFFFF % FF3E18181818FFFFFF18181A181818181818181818181818181818181810 % 101012101216121810121010121010101010121618181818181818181810 % 101010121010101210121612181018101818181818181816FFFFFF181018 % 12101010121218181893FFFFFFFFFFFFFFFFFFFFFF361818181818181818 % 1818181818101010121012161218101210101210101010FFFFFF18181818 % 181818181810101010121010101210121612181018101818181818181816 % 1218101810FFFFFFFFFFFFFFFFFFFFFFFF1818181818181A181818181818 % 181818181818181818181810101012101216121810121010121010101010 % 121618FFFFFF1818181818FFFFFF10121010101210121612181018101818 % 18181818181612181018101812101010121218181818181818181818181A % 181818181818181818181818181818181810101012101216121810121010 % 121010101010121618181818181818181810101010121010101210121612 % 181018101818181818181816121810181018121010101212181818181818 % 18181818181A181818181818181818181818181818181810101012101216 % 1218101210101210101010101200FF181612101010101210121612101216 % 101010101210121818181818181818181612101010101210121012101216 % 121818181818181612101210121012101210101010101012181818181818 % 181818181818181A18181818181818181818181818181612101010101210 % 121612101216101010101210121818181818181818181612101010101210 % 121012101216121818181818181612101210121067FFFFFFFFFFFFFFFF5C % 1818181818FFFFFF18181818181A18181818181818181818181818181612 % 101010101210121612101216101010101210121818181818181818181612 % 1010101012101210121012161218181818181816121012FFFFFF12101210 % 10101010101218181883FFFFFFFFFFFFFFFFBB4018181818181818181818 % 18181818161210101010121012161210121610101010FFFFFF1818181818 % 181818181612101010101210121012101216121818181818181612101210 % 12101210FFFFFFFFFFFFFFFFFFFFFFFF1818181818181818181A18181818 % 181818181818181818181612101010101210121612101216101010101210 % 12183EBBFF1818181818FFFFFF1010101210121012101216121818181818 % 181612101210121012101210101010101012181818181818181818181818 % 181A18181818181818181818181818181612101010101210121612101216 % 101010101210121818181818181818181612101010101210121012101216 % 121818181818181612101210121012101210101010101012181818181818 % 181818181818181A18181818181818181818181818181612101010101210 % 12161210121610101010121000FF18181816101010101012101210181216 % 121010101012161818181818181818121810101010101010121012101810 % 18181818181818121010121012101210121010100F101010121018181818 % 18181A18181A181A18181818181818181818181818181816101010101012 % 101210181216121010101012161818181818181818121810101010101010 % 12101210181018181818181818121010121012104072BBFFFFA0652D1010 % 12101818FFFFFF181A18181A181A18181818181818181818181818181816 % 101010101012101210181216121010101012161818181818181818121810 % 10101010101012101210181018181818181818121010FFFFFF1012101210 % 10100F1010101210183E77A3FFFFBB834F1A181A18181818181818181818 % 181818181816101010101012101210181216121010FFFFFF161818181818 % 181818121810101010101010121012101810181818181818181210101210 % 121012FFFFFFFFFFFFFFFFFFFFFFFF18181818181A18181A181A18181818 % 181818181818181818181816101010101012101210181216121010101012 % 161818771818181818FFFFFF101010101010121012101810181818181818 % 18121010121012101210121010100F10101012101818181818181A18181A % 181A18181818181818181818181818181816101010101012101210181216 % 121010101012161818181818181818121810101010101010121012101810 % 18181818181818121010121012101210121010100F101010121018181818 % 18181A18181A181A18181818181818181818181818181816101010101012 % 101210181216121010101000FF1818181818121010101010101818181810 % 101010101012181818181818181818181012101010121010101012101818 % 101818181818181612101010121010101010100A10101010101210181818 % 18181A181A18201818181818181818181818181818181818121010101010 % 101818181810101010101012181818181818181818181012101010121010 % 101012101818101818181818181612101010121010101010100A10101010 % 10121018181818181A181A18201818181818181818181818181818181818 % 121010101010101818181810101010101012181818181818181818181012 % 101010121010101012101818101818181818181612101010121010101010 % 100A1010101010121018181818181A181A18201818181818181818181818 % 181818181818121010101010101818181810101010101012181818181818 % 181818181012101010121010101012101818101818181818181612101010 % 121010101010100A1010101010121018181818181A181A18201818181818 % 181818181818181818181818121010101010101818181810101010101012 % 181818181818181818181012101010121010101012101818101818181818 % 181612101010121010101010100A1010101010121018181818181A181A18 % 201818181818181818181818181818181818121010101010101818181810 % 101010101012181818181818181818181012101010121010101012101818 % 101818181818181612101010121010101010100A10101010101210181818 % 18181A181A18201818181818181818181818181818181818121010101010 % 1018181818101010101000FF181818181010101010101218181618181818 % 1818181818181A1818181810101816181818181216101210121018101210 % 1010181818101210101210101012101010100A0810101010101012161818 % 181818181A18181818101012101810181618181818181010101010101218 % 1816181818181818181818181A1818181810101816181818181216101210 % 1210181012101010181818101210101210101012101010100A0810101010 % 101012161818181818181A18181818101012101810181618181818181010 % 1010101012181816181818181818181818181A1818181810101816181818 % 181216101210121018101210101018181810121010121010101210101010 % 0A0810101010101012161818181818181A18181818101012101810181618 % 1818181810101010101012181816181818181818181818181A1818181810 % 101816181818181216101210121018101210101018181810121010121010 % 1012101010100A0810101010101012161818181818181A18181818101012 % 101810181618181818181010101010101218181618181818181818181818 % 1A1818181810101816181818181216101210121018101210101018181810 % 1210101210101012101010100A0810101010101012161818181818181A18 % 181818101012101810181618181818181010101010101218181618181818 % 1818181818181A1818181810101816181818181216101210121018101210 % 1010181818101210101210101012101010100A0810101010101012161818 % 181818181A18181818101012101810181618181818181010101010101218 % 18161818181818181800FF16181818101012081010101012181818181818 % 181818181A181A1818161212181818181818161210121010121216181010 % 121010101212161218101210101012101010101010101010101012181818 % 18181A181818181810121012101210121216181818101012081010101012 % 181818181818181818181A181A1818161212181818181818161210121010 % 121216181010121010101212161218101210101012101010101010101010 % 10101218181818181A181818181810121012101210121216181818101012 % 081010101012181818181818181818181A181A1818161212181818181818 % 161210121010121216181010121010101212161218101210101012101010 % 10101010101010101218181818181A181818181810121012101210121216 % 181818101012081010101012181818181818181818181A181A1818161212 % 181818181818161210121010121216181010121010101212161218101210 % 10101210101010101010101010101218181818181A181818181810121012 % 101210121216181818101012081010101012181818181818181818181A18 % 1A1818161212181818181818161210121010121216181010121010101212 % 16121810121010101210101010101010101010101218181818181A181818 % 181810121012101210121216181818101012081010101012181818181818 % 181818181A181A1818161212181818181818161210121010121216181010 % 121010101212161218101210101012101010101010101010101012181818 % 18181A181818181810121012101210121216181818101012081010101012 % 181818181818181800FF121018121612100E0A081010101818181A18181A % 181818181818181812101018181818181818181010181318161818121010 % 101010101018181618181018121612101010101010100E10101210181818 % 18181A18181818101216121018101210121018121612100E0A0810101018 % 18181A18181A181818181818181812101018181818181818181010181318 % 161818121010101010101018181618181018121612101010101010100E10 % 10121018181818181A18181818101216121018101210121018121612100E % 0A081010101818181A18181A181818181818181812101018181818181818 % 181010181318161818121010101010101018181618181018121612101010 % 101010100E1010121018181818181A181818181012161210181012101210 % 18121612100E0A081010101818181A18181A181818181818181812101018 % 181818181818181010181318161818121010101010101018181618181018 % 121612101010101010100E1010121018181818181A181818181012161210 % 18101210121018121612100E0A081010101818181A18181A181818181818 % 181812101018181818181818181010181318161818121010101010101018 % 181618181018121612101010101010100E1010121018181818181A181818 % 18101216121018101210121018121612100E0A081010101818181A18181A % 181818181818181812101018181818181818181010181318161818121010 % 101010101018181618181018121612101010101010100E10101210181818 % 18181A18181818101216121018101210121018121612100E0A0810101018 % 18181A18181A1800FF101210181818181010100A10101818181818181818 % 18181A181818181010121012101818181810181218161818181816181010 % 101010121818181816181216181812101010101010101010101212101818 % 181818181818181810181112101610101210181818181010100A10101818 % 18181818181818181A181818181010121012101818181810181218161818 % 181816181010101010121818181816181216181812101010101010101010 % 101212101818181818181818181810181112101610101210181818181010 % 100A1010181818181818181818181A181818181010121012101818181810 % 181218161818181816181010101010121818181816181216181812101010 % 101010101010101212101818181818181818181810181112101610101210 % 181818181010100A1010181818181818181818181A181818181010121012 % 101818181810181218161818181816181010101010121818181816181216 % 181812101010101010101010101212101818181818181818181810181112 % 101610101210181818181010100A1010181818181818181818181A181818 % 181010121012101818181810181218161818181816181010101010121818 % 181816181216181812101010101010101010101212101818181818181818 % 181810181112101610101210181818181010100A10101818181818181818 % 18181A181818181010121012101818181810181218161818181816181010 % 101010121818181816181216181812101010101010101010101212101818 % 181818181818181810181112101610101210181818181010100A10101818 % 18181818181800FF10101010121018181810101012181818181818181818 % 18181A181818101210101010121012101018101818181818181818181818 % 181010181218101212101218181018101210101010101010101012181818 % 181818181018101812181018121010101010121018181810101012181818 % 18181818181818181A181818101210101010121012101018101818181818 % 181818181818181010181218101212101218181018101210101010101010 % 101012181818181818181018101812181018121010101010121018181810 % 10101218181818181818181818181A181818101210101010121012101018 % 101818181818181818181818181010181218101212101218181018101210 % 101010101010101012181818181818181018101812181018121010101010 % 12101818181010101218181818181818181818181A181818101210101010 % 121012101018101818181818181818181818181010181218101212101218 % 181018101210101010101010101012181818181818181018101812181018 % 12101010101012101818181010101218181818181818181818181A181818 % 101210101010121012101018101818181818181818181818181010181218 % 101212101218181018101210101010101010101012181818181818181018 % 101812181018121010101010121018181810101012181818181818181818 % 18181A181818101210101010121012101018101818181818181818181818 % 181010181218101212101218181018101210101010101010101012181818 % 181818181018101812181018121010101010121018181810101012181818 % 181818181800FF1012101010101218181810121618181818181818181818 % 1818181810121010101010101012101212101810181818181818181A1818 % 181216121612101010101210181012101010101010101012101012121818 % 161210101212161216181818121012101010101218181810121618181818 % 181818181818181818181012101010101010101210121210181018181818 % 1818181A1818181216121612101010101210181012101010101010101012 % 101012121818161210101212161216181818121012101010101218181810 % 121618181818181818181818181818181012101010101010101210121210 % 1810181818181818181A1818181216121612101010101210181012101010 % 101010101012101012121818161210101212161216181818121012101010 % 101218181810121618181818181818181818181818181012101010101010 % 1012101212101810181818181818181A1818181216121612101010101210 % 181012101010101010101012101012121818161210101212161216181818 % 121012101010101218181810121618181818181818181818181818181012 % 1010101010101012101212101810181818181818181A1818181216121612 % 101010101210181012101010101010101012101012121818161210101212 % 161216181818121012101010101218181810121618181818181818181818 % 1818181810121010101010101012101212101810181818181818181A1818 % 181216121612101010101210181012101010101010101012101012121818 % 161210101212161216181818121012101010101218181810121618181818 % 1818181800FF1810121010100E1816121810181618161818161818181818 % 181818121012101010101218181812101012121612181618181818181818 % 181818181810181210101010121612101010101010101012101210121012 % 1010101010121818181818181810121010100E1816121810181618161818 % 161818181818181818121012101010101218181812101012121612181618 % 181818181818181818181810181210101010121612101010101010101012 % 1012101210121010101010121818181818181810121010100E1816121810 % 181618161818161818181818181818121012101010101218181812101012 % 121612181618181818181818181818181810181210101010121612101010 % 101010101012101210121012101010101012181818181818181012101010 % 0E1816121810181618161818161818181818181818121012101010101218 % 181812101012121612181618181818181818181818181810181210101010 % 121612101010101010101012101210121012101010101012181818181818 % 1810121010100E1816121810181618161818161818181818181818121012 % 101010101218181812101012121612181618181818181818181818181810 % 181210101010121612101010101010101012101210121012101010101012 % 1818181818181810121010100E1816121810181618161818161818181818 % 181818121012101010101218181812101012121612181618181818181818 % 181818181810181210101010121612101010101010101012101210121012 % 1010101010121818181818181810121010100E1816121810181618161818 % 16181800FF181810100A100A101010101812121218181818181818181818 % 181810101010101216181818181810121010121612181812101010181818 % 18181818181818180A101012161210121010101010101010101010121010 % 10101010121018181A181A181810100A100A101010101812121218181818 % 181818181818181810101010101216181818181810121010121612181812 % 10101018181818181818181818180A101012161210121010101010101010 % 10101012101010101010121018181A181A181810100A100A101010101812 % 121218181818181818181818181810101010101216181818181810121010 % 12161218181210101018181818181818181818180A101012161210121010 % 10101010101010101012101010101010121018181A181A181810100A100A % 101010101812121218181818181818181818181810101010101216181818 % 18181012101012161218181210101018181818181818181818180A101012 % 16121012101010101010101010101012101010101010121018181A181A18 % 1810100A100A101010101812121218181818181818181818181810101010 % 101216181818181810121010121612181812101010181818181818181818 % 18180A101012161210121010101010101010101010121010101010101210 % 18181A181A181810100A100A101010101812121218181818181818181818 % 181810101010101216181818181810121010121612181812101010181818 % 18181818181818180A101012161210121010101010101010101010121010 % 10101010121018181A181A181810100A100A101010101812121218181818 % 181800FF181818101010100B101012101818181818181818181010181216 % 121012101010101218181818181A18181216121818121018181818181818 % 181612181618181818101210181818101216121818181810101210101210 % 10101010121818181818181818101010100B101012101818181818181818 % 181010181216121012101010101218181818181A18181216121818121018 % 181818181818181612181618181818101210181818101216121818181810 % 10121010121010101010121818181818181818101010100B101012101818 % 181818181818181010181216121012101010101218181818181A18181216 % 121818121018181818181818181612181618181818101210181818101216 % 12181818181010121010121010101010121818181818181818101010100B % 101012101818181818181818181010181216121012101010101218181818 % 181A18181216121818121018181818181818181612181618181818101210 % 181818101216121818181810101210101210101010101218181818181818 % 18101010100B101012101818181818181818181010181216121012101010 % 101218181818181A18181216121818121018181818181818181612181618 % 181818101210181818101216121818181810101210101210101010101218 % 18181818181818101010100B101012101818181818181818181010181216 % 121012101010101218181818181A18181216121818121018181818181818 % 181612181618181818101210181818101216121818181810101210101210 % 10101010121818181818181818101010100B101012101818181818181818 % 1800FF181818101210101010101012101210181818181818181211181012 % 101012101010101818181818181812101210181810121012181018181818 % 181210121210181818101216121818181818181818181218161812101010 % 101010101012181818181818101210101010101012101210181818181818 % 181211181012101012101010101818181818181812101210181810121012 % 181018181818181210121210181818101216121818181818181818181218 % 161812101010101010101012181818181818101210101010101012101210 % 181818181818181211181012101012101010101818181818181812101210 % 181810121012181018181818181210121210181818101216121818181818 % 181818181218161812101010101010101012181818181818101210101010 % 101012101210181818181818181211181012101012101010101818181818 % 181812101210181810121012181018181818181210121210181818101216 % 121818181818181818181218161812101010101010101012181818181818 % 101210101010101012101210181818181818181211181012101012101010 % 101818181818181812101210181810121012181018181818181210121210 % 181818101216121818181818181818181218161812101010101010101012 % 181818181818101210101010101012101210181818181818181211181012 % 101012101010101818181818181812101210181810121012181018181818 % 181210121210181818101216121818181818181818181218161812101010 % 101010101012181818181818101210101010101012101210181818181818 % 00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF % FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 %%EndPreview % including file "../library/bltGraph.pro" % % PostScript prolog file of the BLT graph widget. % % Copyright 1989-1992 Regents of the University of California. % Permission to use, copy, modify, and distribute this % software and its documentation for any purpose and without % fee is hereby granted, provided that the above copyright % notice appear in all copies. The University of California % makes no representations about the suitability of this % software for any purpose. It is provided "as is" without % express or implied warranty. % % Copyright 1991-1997 Bell Labs Innovations for Lucent Technologies. % % Permission to use, copy, modify, and distribute this software and its % documentation for any purpose and without fee is hereby granted, provided % that the above copyright notice appear in all copies and that both that the % copyright notice and warranty disclaimer appear in supporting documentation, % and that the names of Lucent Technologies any of their entities not be used % in advertising or publicity pertaining to distribution of the software % without specific, written prior permission. % % Lucent Technologies disclaims all warranties with regard to this software, % including all implied warranties of merchantability and fitness. In no event % shall Lucent Technologies be liable for any special, indirect or % consequential damages or any damages whatsoever resulting from loss of use, % data or profits, whether in an action of contract, negligence or other % tortuous action, arising out of or in connection with the use or performance % of this software. % 200 dict begin /BaseRatio 1.3467736870885982 def % Ratio triangle base / symbol size /BgColorProc 0 def % Background color routine (symbols) /DrawSymbolProc 0 def % Routine to draw symbol outline/fill /StippleProc 0 def % Stipple routine (bar segments) /DashesProc 0 def % Dashes routine (line segments) % Define the array ISOLatin1Encoding (which specifies how characters are % encoded for ISO-8859-1 fonts), if it isn't already present (Postscript % level 2 is supposed to define it, but level 1 doesn't). systemdict /ISOLatin1Encoding known not { /ISOLatin1Encoding [ /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /minus /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /space /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedillar /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def } if % font ISOEncode font % This procedure changes the encoding of a font from the default % Postscript encoding to ISOLatin1. It's typically invoked just % before invoking "setfont". The body of this procedure comes from % Section 5.6.1 of the Postscript book. /ISOEncode { dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def currentdict end % I'm not sure why it's necessary to use "definefont" on this new % font, but it seems to be important; just use the name "Temporary" % for the font. /Temporary exch definefont } bind def /Stroke { gsave stroke grestore } def /Fill { gsave fill grestore } def /SetFont { % Stack: pointSize fontName findfont exch scalefont ISOEncode setfont } def /Box { % Stack: x y width height newpath exch 4 2 roll moveto dup 0 rlineto exch 0 exch rlineto neg 0 rlineto closepath } def /SetFgColor { % Stack: red green blue CL 0 eq { pop pop pop 0 0 0 } if setrgbcolor CL 1 eq { currentgray setgray } if } def /SetBgColor { % Stack: red green blue CL 0 eq { pop pop pop 1 1 1 } if setrgbcolor CL 1 eq { currentgray setgray } if } def % The next two definitions are taken from "$tk_library/prolog.ps" % desiredSize EvenPixels closestSize % % The procedure below is used for stippling. Given the optimal size % of a dot in a stipple pattern in the current user coordinate system, % compute the closest size that is an exact multiple of the device's % pixel size. This allows stipple patterns to be displayed without % aliasing effects. /EvenPixels { % Compute exact number of device pixels per stipple dot. dup 0 matrix currentmatrix dtransform dup mul exch dup mul add sqrt % Round to an integer, make sure the number is at least 1, and compute % user coord distance corresponding to this. dup round dup 1 lt {pop 1} if exch div mul } bind def % width height string filled StippleFill -- % % Given a path and other graphics information already set up, this % procedure will fill the current path in a stippled fashion. "String" % contains a proper image description of the stipple pattern and % "width" and "height" give its dimensions. If "filled" is true then % it means that the area to be stippled is gotten by filling the % current path (e.g. the interior of a polygon); if it's false, the % area is gotten by stroking the current path (e.g. a wide line). % Each stipple dot is assumed to be about one unit across in the % current user coordinate system. % width height string StippleFill -- % % Given a path already set up and a clipping region generated from % it, this procedure will fill the clipping region with a stipple % pattern. "String" contains a proper image description of the % stipple pattern and "width" and "height" give its dimensions. Each % stipple dot is assumed to be about one unit across in the current % user coordinate system. This procedure trashes the graphics state. /StippleFill { % The following code is needed to work around a NeWSprint bug. /tmpstip 1 index def % Change the scaling so that one user unit in user coordinates % corresponds to the size of one stipple dot. 1 EvenPixels dup scale % Compute the bounding box occupied by the path (which is now % the clipping region), and round the lower coordinates down % to the nearest starting point for the stipple pattern. Be % careful about negative numbers, since the rounding works % differently on them. pathbbox 4 2 roll 5 index div dup 0 lt {1 sub} if cvi 5 index mul 4 1 roll 6 index div dup 0 lt {1 sub} if cvi 6 index mul 3 2 roll % Stack now: width height string y1 y2 x1 x2 % Below is a doubly-nested for loop to iterate across this area % in units of the stipple pattern size, going up columns then % across rows, blasting out a stipple-pattern-sized rectangle at % each position 6 index exch { 2 index 5 index 3 index { % Stack now: width height string y1 y2 x y gsave 1 index exch translate 5 index 5 index true matrix tmpstip imagemask grestore } for pop } for pop pop pop pop pop } bind def /LS { % Stack: x1 y1 x2 y2 newpath 4 2 roll moveto lineto stroke } def /EndText { %Stack : grestore } def /BeginText { %Stack : w h theta centerX centerY gsave % Translate the origin to the center of bounding box and rotate translate neg rotate % Translate back to the origin of the text region -0.5 mul exch -0.5 mul exch translate } def /DrawAdjText { %Stack : str strWidth x y moveto % Go to the text position exch dup dup 4 2 roll % Adjust character widths to get desired overall string width % adjust X = (desired width - real width)/#chars stringwidth pop sub exch length div 0 3 -1 roll % Flip back the scale so that the string is not drawn in reverse gsave 1 -1 scale ashow grestore } def /DrawBitmap { % Stack: ?bgColorProc? boolean centerX centerY width height theta imageStr gsave 6 -2 roll translate % Translate to center of bounding box 4 1 roll neg rotate % Rotate by theta % Find upperleft corner of bounding box 2 copy -.5 mul exch -.5 mul exch translate 2 copy scale % Make pixel unit scale newpath 0 0 moveto 0 1 lineto 1 1 lineto 1 0 lineto closepath % Fill rectangle with background color 4 -1 roll { gsave 4 -1 roll exec fill grestore } if % Paint the image string into the unit rectangle 2 copy true 3 -1 roll 0 0 5 -1 roll 0 0 6 array astore 5 -1 roll imagemask grestore }def % Symbols: % Skinny-cross /Sc { % Stack: x y symbolSize gsave 3 -2 roll translate 45 rotate 0 0 3 -1 roll Sp grestore } def % Skinny-plus /Sp { % Stack: x y symbolSize gsave 3 -2 roll translate 2 idiv dup 2 copy newpath neg 0 moveto 0 lineto DrawSymbolProc newpath neg 0 exch moveto 0 exch lineto DrawSymbolProc grestore } def % Cross /Cr { % Stack: x y symbolSize gsave 3 -2 roll translate 45 rotate 0 0 3 -1 roll Pl grestore } def % Plus /Pl { % Stack: x y symbolSize gsave 3 -2 roll translate dup 2 idiv exch 6 idiv % % 2 3 The plus/cross symbol is a % closed polygon of 12 points. % 0 1 4 5 The diagram to the left % x,y represents the positions of % 11 10 7 6 the points which are computed % below. % 9 8 % newpath 2 copy exch neg exch neg moveto dup neg dup lineto 2 copy neg exch neg lineto 2 copy exch neg lineto dup dup neg lineto 2 copy neg lineto 2 copy lineto dup dup lineto 2 copy exch lineto 2 copy neg exch lineto dup dup neg exch lineto exch neg exch lineto closepath DrawSymbolProc grestore } def % Circle /Ci { % Stack: x y symbolSize 3 copy pop moveto newpath 2 div 0 360 arc closepath DrawSymbolProc } def % Square /Sq { % Stack: x y symbolSize dup dup 2 div dup 6 -1 roll exch sub exch 5 -1 roll exch sub 4 -2 roll Box DrawSymbolProc } def % Line /Li { % Stack: x y symbolSize 3 1 roll exch 3 -1 roll 2 div 3 copy newpath sub exch moveto add exch lineto stroke } def % Diamond /Di { % Stack: x y symbolSize gsave 3 1 roll translate 45 rotate 0 0 3 -1 roll Sq grestore } def % Triangle /Tr { % Stack: x y symbolSize gsave 3 -2 roll translate BaseRatio mul 0.5 mul % Calculate 1/2 base dup 0 exch 30 cos mul % h1 = height above center point neg % b2 0 -h1 newpath moveto % point 1; b2 dup 30 sin 30 cos div mul % h2 = height below center point 2 copy lineto % point 2; b2 h2 exch neg exch lineto % closepath DrawSymbolProc grestore } def % Bitmap /Bm { % Stack: x y symbolSize gsave 3 1 roll translate pop DrawSymbolProc grestore } def %%BeginSetup gsave % Save the graphics state % Default line/text style parameters 1 setlinewidth % width 1 setlinejoin % join 0 setlinecap % cap [] 0 setdash % dashes /CL 0 def % Set color level mode 0 0 0 setrgbcolor % color % Transform coordinate system to use X11 coordinates % Flip the y-axis by changing the origin and reversing the scale, % making the origin the upper left corner 0.600000 -0.600000 scale 0 -1319 translate % User defined page layout %% Set color level /CL 2 def % Set origin 120 173 translate % Landscape orientation 0 972.127 translate -90 rotate %% Set max aspect ratio 1.62292 1.62292 scale %%EndSetup 14 /Helvetica-Bold SetFont 0.996109 0.996109 0.996109 SetBgColor 69 80 479 333 Box Fill gsave clip % Marker "bg" is a bitmap 0.304692 0.929702 0.578134 SetBgColor newpath 79 90 moveto 539 90 lineto 539 404 lineto 79 404 lineto 79 90 lineto closepath Fill 0 0.542977 0 SetFgColor gsave 79 404 translate 460 -314 scale 460 314 true [460 0 0 -314 0 314] { <000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000040000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000400000000000000000 000000000000000000000000000000000000000000000000000000000000 002410000000000000000449010000000000002000000000000000000000 000000000000000000000000000000002000000000000000000800004A00 000000000000000220002002010200000080000000000008020000000000 00002000000000200000000000008000000420000000000800004A000000 000000000002200020020102000000800000000000080200000000000000 2000000000200000000000008000000420000100000000A1000000000000 001011010020881020280000020004000000088040000000000000110201 411020000000000000020200004000000000804090040020800000200001 00000002010008800000005110912ADEEFFDBFFFFFFFFEFDFFCAA9BA3EEF D72DF36ADDE5AAF400AA5504C00000008040900400208000002000010000 0002010008800000005110912ADEEFFDBFFFFFFFFEFDFFCAA9BA3EEFD72D F36ADDE5AAF400AA5504C000016D572D4E95599695514A02420404200000 000000000001000000000000000000000000000000244444001129550524 5525544BEF6DD6DF40000100000000000000000000000000000008100844 400840000100020808529B5FFFFFFFFFFFFFFFFFFFFFFCFFFFFFFFFFFFFF FFFFFFFFFFFF440001000000000000000000000000000000081008444008 40000100020808529B5FFFFFFFFFFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFF FFFFFFFF4400097FFFFFFFFFFFFFFFFFFFFFFFFF9FFFFFFFFFFFFFFFFFFF FFFFFFFFFFCDDDE0480A20004050C03101003DFBEFFFFDDFFF9FFFFEE57E FBBF40000177F5FFEBFFFFFFFFFFFDFFFFEF9D42D21485A084817EDE24F9 018006000004182060107019C63901071CFF5F7BEEAEB756F7D7EFF6EEBF 40000177F5FFEBFFFFFFFFFFFDFFFFEF9D42D21485A084817EDE24F90180 06000004182060107019C63901071CFF5F7BEEAEB756F7D7EFF6EEBF400001 5F6BE7DFBFFFFEFF736B7FFAD71C08C18C1060C70C1E0F83F86041C41FC1 E61820761E790B071209831CD2FD6575BBFF4F9ABBB75EF7D54400017BEF D7F6DBF6FE77FDFEFFBFBF9E0CC14E1070B70C1C0F87FC7061B400E0B618 307E13FC07071B4D90FCEFEEDDDFFAEA4774EFEBBEDFF74000017BEFD7F6 DBF6FE77FDFEFFBFBF9E0CC14E1070B70C1C0F87FC7061B400E0B618307E 13FC07071B4D90FCEFEEDDDFFAEA4774EFEBBEDFF74000015EDBD7B3FFAB FD7F777F72EDEF1E03C27E18703F00FD078FFC01E13C00411F10782E0B7F 03071F0F835CF6BF7EF5B5BCCED4B75DFA6FAF40002575F5B7D5BEABF53F FBEDBDFAF79E0BC96E1070B7083A078FFC60E1B68048B618381C1E7D8307 1E07839DEFF6EFB7FFFCCFEF7B76EC6FAF50002575F5B7D5BEABF53FFBED BDFAF79E0BC96E1070B7083A078FFC60E1B68048B618381C1E7D83071E07 839DEFF6EFB7FFFCCFEF7B76EC6FAF5000015FBB316BAD7D5D3EEAFF7FAB F51C0FC18C1060C70C33038C78204184F0C184093C381070C3C63E06121C B6DB3FADF5FDCBBFDFEDBD7FDF400001767D53A7F5FFFCBFB766EEDDB798 2300092BAA042200002268980056AFDF7FFFFFFFFFFFFFFFFFFFFFFCEFD5 FFE5FFEDCD7E6B7D753F1B400001767D53A7F5FFFCBFB766EEDDB7982300 092BAA042200002268980056AFDF7FFFFFFFFFFFFFFFFFFFFFFCEFD5FFE5 FFEDCD7E6B7D753F1B4000017B3B736BB7BB75BDDBDD6FD6FD9FFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFFFFFFFFFB CADBFAEFFD7D1F44000166DDB3AD9EF5D59FFFFFFFFFFF95A6F524894091 20082524A4010100000000000000000000000000000200000000000FCDAF BF389A9D5F40000166DDB3AD9EF5D59FFFFFFFFFFF95A6F5248940912008 2524A4010100000000000000000000000000000200000000000FCDAFBF38 9A9D5F4000017EDCF37AA3FE699800000000000000000000000000000000 080000000000402000004201592D2AFF7FFDFBEF555B6D6BCF3DFBFC7B3A DF40000176EFBB8D3FEEBF13FFFFFFFFFB5EB6AB35A55A4AA54AD54AA954 0201000100001080000400000000000000000000008B8EFE94802EDFDF50 000176EFBB8D3FEEBF13FFFFFFFFFB5EB6AB35A55A4AA54AD54AA9540201 000100001080000400000000000000000000008B8EFE94802EDFDF500001 7ECEF40B5BFEBB9000000000000000000000000000000000000000000000 040100080000000000000200000000000093CCBA000200009F4000116E96 F895877ECF9B010000000000000000000000000000004000000420442010 0000101000111200100000000000000B4BBF2DA7FAD3DF4100116E96F895 877ECF9B0100000000000000000000000000000040000004204420100000 101000111200100000000000000B4BBF2DA7FAD3DF4100017EC6F20EB5DF DAAA10420000000000200000041100000000280110000400000004000000 40400000000000002080841BCB973FFEFFFB1F4000016E56C1F902FAE790 400000000000200010048000004000088000000000000080002000200100 0840104412010100102B669F6FFDEFEB534400016E56C1F902FAE7904000 000000002000100480000040000880000000000000800020002001000840 104412010100102B669F6FFDEFEB53440001769203F7F97EE39400000400 000000804100220001000200004200200001000001824200A05436BFE55B 12E12810004BE72A6BD5FE5B7F4000057E8B27B7793EA3B0011251400502 94250A4808A4A05A000311291414DBFD17780452A90010021550B56A57C4 B40400B77A9C57FCDFC9774000057E8B27B7793EA3B00112514005029425 0A4808A4A05A000311291414DBFD17780452A90010021550B56A57C4B404 00B77A9C57FCDFC9774000116AA04EDFBE1EA39D07FFFCF9F9A03CF3AF3D FFCF5CFD200CFFFF8C3F71C74474163071A071BD381874E3D78B1D1A004F FD1EF7D33EBCFF4000017F589FF3F78EB7B407733C70F9807833D61DFEC7 0D3CD00C73779D3BB8C73C301E397184307EBCD972E3C7972918006DF320 E4A9FAB41B6400017F589FF3F78EB7B407733C70F9807833D61DFEC70D3C D00C73779D3BB8C73C301E397184307EBCD972E3C7972918006DF320E4A9 FAB41B640001751ABA693D961BA006FB3D7272D83CA5C85DCEC72C3CF439 1A7B1E7330CF9DDB1CBAF290F91E397972EFE79754BD823B6833DB6EDE7F 1BC000216A8133F3D9C6B18400737C7272943965E2999EC70D7CF21D7A71 9E3399C31CB91C797110FA3E39B9B3E7C71F69DC40BDAA97F9F1065FDF40 00216A8133F3D9C6B18400737C7272943965E2999EC70D7CF21D7A719E33 99C31CB91C797110FA3E39B9B3E7C71F69DC40BDAA97F9F1065FDF400001 7BD272DBA57259A824F33DF2F290398AF0DD9ECF28BCF33F407B9E7728CA 1FC23CFC72993B2F3D19A1EBCFAF410E40CEF51F686A56FBBB4000017752 F36AF9EA7985097B7C7276583BA470BC9ECF297CF11FF0F28F27B1D83FF3 3E797E10392F39BF8DEF978F658E60AD6918F9A006BD3F4000017752F36A F9EA7985097B7C7276583BA470BC9ECF297CF11FF0F28F27B1D83FF33E79 7E10392F39BF8DEF978F658E60AD6918F9A006BD3F4000017BA4EAF7A6F3 59AC01713D727610390A7C992E47657CFA0FFD7A872B12D96FFA3CBCF66B 1EC7B919B2E737AF569E206F2B3BCCE00E772F4000116AC9F5C02BB9BB18 02FA7C7272503926BCDDDE97223CF303F9724FAB3ACB81783CB97282BCA7 B9B910E3C71F4C072055CB32FB000CFEB74800116AC9F5C02BB9BB1802FA 7C7272503926BCDDDE97223CF303F9724FAB3ACB81783CB97282BCA7B9B9 10E3C71F4C072055CB32FB000CFEB74800017FC9CD5EB5F9992C20F13CF2 784139247CBCAECF043C7120787917A709C008791E7972421CCFBD9934EB D7A744C79053C5B6FC4086DC5F4000017597EC803B5DDA9800F37D72F2C8 3D8A1D5D1E872E7CF216B8F2C3D3B0CBB399BCB973864E67391DF2EBCF97 319F9036AAF5D7880F74DF4000017597EC803B5DDA9800F37D72F2C83D8A 1D5D1E872E7CF216B8F2C3D3B0CBB399BCB973864E67391DF2EBCF97319F 9036AAF5D7880F74DF4000017FD3AB003EFAEA1528F23D717AC839265CB9 1ECF3CBCF31299795BCB9ACF18B89E79710AEE253D5971E7D79B29879019 5B64FBC016BD574000017B5B7C803BADE8B802FB3CF2F1C81C872CBDBE57 4E3CC519B8F945CF89CFBCE31673FE3F5F7A7AFD52D5E54DC6B14C0DE6DC 57E00F697F5000017B5B7C803BADE8B802FB3CF2F1C81C872CBDBE574E3C C519B8F945CF89CFBCE31673FE3F5F7A7AFD52D5E54DC6B14C0DE6DC57E0 0F697F5000016EC75A083ED648A842FC7FFBFBC42E8F867EBF5FBCFD8A3E 62FDD7F7EBEB1F4512C0210120060000000400120000080CA6F96DA08ED3 374000116B85A920BBF9F569020100000008003020800010008034000900 08000400100A0403148C12A9EFA5D7352B6C3F66EC04ABE6BDE00FBAFB40 00116B85A920BBF9F5690201000000080030208000100080340009000800 0400100A0403148C12A9EFA5D7352B6C3F66EC04ABE6BDE00FBAFB400001 7E86FC003F8ADD2809525402AA28082A22C94AA5A55494082C0089255A9D E8B40498EA83C2AA3555745AE6D95155560328C4B7600DFBDF4000017F17 37803D5B72D4006D2BF2B55405D15146C552A554D007D07EAAB96C965350 01502A01515515A54A55115420612021FECA6FC007504F4000017F173780 3D5B72D4006D2BF2B55405D15146C552A554D007D07EAAB96C9653500150 2A01515515A54A55115420612021FECA6FC007504F4000016B2FCB027CA6 F6A00200000000000000000000000000000000000000000000000000002A 00000000000000000000000035C8B5E11CB59B4000017D16F64039096BB0 100000000000000000000000000000000000000000000000200000000000 000000000000040008403AB2B76007169B4400017D16F64039096BB01000 000000000000000000000000000000000000000000002000000000000000 00000000040008403AB2B76007169B4400017317F30033E0BA8200900000 000000000000000480000000040000000042000000014200000020000020 0000000400308AFC786014F2774000057615B5427B81EF90400200000000 000004000400010000000000000080080800040800011000841000040000 000000122CDE7D604EF2EF4000057615B5427B81EF904002000000000000 040004000100000000000000800808000408000110008410000400000000 00122CDE7D604EF2EF4000217B17D5083AC1650500800881000000000020 00002800000000800000008041110080000402120000010080040820007B 4FE27DE10CD2FF5000007627B740BBE6B690020020000900200000048024 8000004840040000080000000000021000000022102000400004204C86E2 35A00774CB4000007627B740BBE6B6900200200009002000000480248000 004840040000080000000000021000000022102000400004204C86E235A0 0774CB40000176137F003DF2D89680020000000000240000000000040400 09000000200200000000000000000000000000000000023BC76E7B6016D1 F74400017C4BEB403DA0E001201000000000000044000000008000000000 0080800004800200000000000800000042000000002D496E3BC00F75EF40 00017C4BEB403DA0E0012010000000000000440000000080000000000080 800004800200000000000800000042000000002D496E3BC00F75EF400001 722BBA083F9A9F3A58000019501BE7C9F51A6F7842000000000800000081 2011284849104010000080040001208000075B5C35E00555DB5000016E0C A5413AAA67820880000358C245893D02EA71000254ABD441480000080000 00000000004001220240000402004000EDD73AE11E7B3F4000016E0CA541 3AAA67820880000358C245893D02EA71000254ABD4414800000800000000 0000004001220240000402004000EDD73AE11E7B3F4000017C2CD10031AA BD81480000840093548C6B002A7200020000000000000202555129520002 0000800008000000000000081ACC35A00C55B7540001721637003DD27312 E010080050002000002000002000E3F27DDF8FFFFC7D374FD3A000000000 0000000210000002008407FE3DC006BB4F400001721637003DD27312E010 080050002000002000002000E3F27DDF8FFFFC7D374FD3A0000000000000 000210000002008407FE3DC006BB4F4000006C636D443DD96DE876000000 02000000000000028000CCF0595E3FFFFF1DD6AF85D00000000410000010 004000200202AB76736096B9FF4000017E055F003DFAF2915B0008810042 900204210A240800BF0FDBF9FFFFFFC7F8F93E9001104010008000000100 00000000CDDE7DE00CB93F4000017E055F003DFAF2915B00088100429002 04210A240800BF0FDBF9FFFFFFC7F8F93E90011040100080000001000000 0000CDDE7DE00CB93F4000016C286D013BBAA8FCBF206DA2475FB3E33E69 C6B57848D7AFD763FFFFFFF179FCFED00000008000008000000408000000 36EA77400779CB5000016C93FB483DEAF653D5007184475D33CA284D47AD 2800FCCF3F9FFFFFFFFC5ED53BA000040000102004008000000400008BB6 FBE096F9FF4000016C93FB483DEAF653D5007184475D33CA284D47AD2800 FCCF3F9FFFFFFFFC5ED53BA000040000102004008000000400008BB6FBE0 96F9FF4000087C11F7023FF96878EB82558C451501231A6548A9A000C36F DD1FFFF4FFFF357560C09000080001008048000001000010077EDAA20EE8 AF4400017EA8F10075BAE52C03004410A61933322405008A00003CCD78FF FA001FFF8F6C9E20010420010000000024400800100055DEFB6054FCFB50 00017EA8F10075BAE52C03004410A61933322405008A00003CCD78FFFA00 1FFF8F6C9E20010420010000000024400800100055DEFB6054FCFB500001 6612F7443342B4F90080000000000000000000000100C2ED79FF428443FF E1BD808000100004080104420004004000010B7EFC60067CDF4000017E18 CB003BFAE62C0008000000000000008000000000016AD1FEB80008FFF1D7 A000000020110000400010280004021066B6D4E096D4F74000017E18CB00 3BFAE62C0008000000000000008000000000016AD1FEB80008FFF1D7A000 000020110000400010280004021066B6D4E096D4F74000016A2DF6403E7B 64D81000009000000000100000400008805DC7FB0848241FFCFDA1E00000 BC078BE7C27178EE3E0E82100AF4B36417BE6B4100216E1DBF023D2B65B8 4080000100000400000010000400A1678FF48000203FFCCFA23004104806 42E040984040222302114D6CEDC004DB774000216E1DBF023D2B65B84080 000100000400000010000400A1678FF48000203FFCCFA2300410480642E0 40984040222302114D6CEDC004DB774000053313AB003DD6EAB400080000 00400022200100080002905E3FF64A10081FFF75A5A84001220406008008 80400311021080D1570B51E72F4000017E93FC483FE54374000001000000 000000080000201040777FE50101225FFF3F855900002000462050004840 0202023089497E00007B3F4800017E93FC483FE543740000010000000000 00080000201040777FE50101225FFF3F8559000020004620500048400202 023089497E00007B3F480000771EBB803F93D5A800410004110040000020 00000004105CFFB8D4400803FF9CA2580020542181E0C018727E1C1E02E4 22DAABFFFFEA9B4000017F1DBE01366940B8000000400008000001000000 0082114CFF5A80002005FF8EA24800003C818362427128420E4B021082A2 BFFFFFB59F4100017F1DBE01366940B80000004000080000010000000082 114CFF5A80002005FF8EA24800003C818362427128420E4B021082A2BFFF FFB59F4100017F57D1140F7B882810040200400000000008104002011973 FD6A80488081FFE7A43000804004462040C0C002031142110757D7FFFFEF 5F4000006B1DD84015F7803000100004000001020000400200001157FAA8 100004447FF326000000220004104004C404001102118C26F5085B7DDF41 00006B1DD84015F7803000100004000001020000400200001157FAA81000 04447FF326000000220004104004C404001102118C26F5085B7DDF410011 7D1FEFFFFFF58020008000000000800000000000000012E7FD8D41442110 7FF98400000220004620C40080064313021158B3DBEAAB7F9F480041769F AFFFFF6B2100020004000420002002400000000412EFEAB2804118053FFC 96010800780783E750F870783C0C0211A0085D7DFEE63F400041769FAFFF FF6B2100020004000420002002400000000412EFEAB2804118053FFC9601 0800780783E750F870783C0C0211A0085D7DFEE63F400000BF8EF1AFE9EA 0000200000400000000020000000001030CFF142001042101FFC94000020 28050183F16810A81402000140069AB7B5607B400001728FD3F6B5DE0400 0000000000000000000000000000259F5414458000049EFE5A0000008000 0000000000000040080480082AECFEC9FF400001728FD3F6B5DE04000000 000000000000000000000000259F5414458000049EFE5A00000080000000 000000000040080480082AECFEC9FF4000007FC7B2B7ABD4000000020000 04000210000820080000159FD8A80048414007FE2A000000004008000002 02010000001004014ABBFE5BDF4900016BCBCDF5F3282010802002002001 20010000800040406B3FAC5489008100A7FFA90000820000A01000204008 1000000040408DDDDACF674000016BCBCDF5F32820108020020020012001 0000800040406B3FAC5489008100A7FFA90000820000A010002040081000 000040408DDDDACF674000013EC36BE7B9BA000002002010800400000000 02000200437FC8E9C2A80A9207FFA5002008000004001200002041200000 0004497CFEA7D74000007D8BCDB2D9580002000000800000000811000000 0800467F61340284500153FF978880000002000400000000000110100000 4D756EEFFB4400007D8BCDB2D95800020000008000000008110000000800 467F61340284500153FF9788800000020004000000000001101000004D75 6EEFFB4400016BD0BBF7AAF800000012000000080080000000000000D4FF D95483512A8009FF9A800000008358400004008521A0000080088EDB7AAF FF4000017743FED6FDB011001000040400400000000000082004ACFF689A 0884801533F7DA000000020950115A5544B81110000002408FEDAFCDB741 00017743FED6FDB011001000040400400000000000082004ACFF689A0884 801533F7DA000000020950115A5544B81110000002408FEDAFCDB7410000 EAB937FBBB60400040000000000000080000000100000BFF55678A500502 89BFE9400102000186624321536011800202000067D57E9EDD4400117FED 7BF7F7E20004002020001200400004A2104000101BFEB2DD452048A451FF E54100001001A17BD8A0436835110820000477FDFE9BFF4000117FED7BF7 F7E20004002020001200400004A2104000101BFEB2DD452048A451FFE541 00001001A17BD8A0436835110820000477FDFE9BFF400000B7ECAFD7CF80 0000010000408019812020000000040053FF5F575594200008FFE6801008 0000A1460A2CC35615882008292009EDF73D1F4000017B54A6F57B100000 080800020118C40200000000200053FD7CAAEB48891250FFF68000004000 ADE2D314C6DEA4A00000800059FCDE7F5F4900017B54A6F57B1000000808 00020118C40200000000200053FD7CAAEB48891250FFF68000004000ADE2 D314C6DEA4A00000800059FCDE7F5F4900017FD731F5DC00040240000100 15FFF800000800020120A7FFAD7716A1500128F77A600201001000000000 00000000000000042E7AFCFFDF400008AA931A13B90000080000200001ED 3C000200000000042FFDD55D899BC48408FFF84000040000800000000000 100000840000461533E69D400008AA931A13B90000080000200001ED3C00 0200000000042FFDD55D899BC48408FFF840000400008000000000001000 00840000461533E69D4000016DCBC0EE74004000008000003EF7FBCA2000 248001004FFF79F54E68FE53E87FF9501000000200040448200200800200 02085BCFC2FDCF4800007BD8A285A000000000040010776726C000000000 4002DFFD6C5557AA7A0FD57FFDA040100008050010008080040080000020 2FB31C6B5F4000007BD8A285A000000000040010776726C0000000004002 DFFD6C5557AA7A0FD57FFDA0401000080500100080800400800000202FB3 1C6B5F4000017E9D717791100124800042026F671BA0004000040408DFF6 F56B1AFD3D5CFC77FCA1010080201080D5015F7F7B7800000000BFE03C3B 8F400008BF55F9284010040011000807BFFFEADE040000000020BFED2C58 4D544F1A157FFE30000000000040040001000090000201007FED7D1E8F48 0008BF55F9284010040011000807BFFFEADE040000000020BFED2C584D54 4F1A157FFE30000000000040040001000090000201007FED7D1E8F480000 FA5DD2823020200000110043EDF577FC000202000100BFEDF54E97FFDE9D B51FFE500C02090000201210120B40A00020000015E6FA3F4F4100003EFF BE103131800040000003F38CBD3C4108000020013FA614512D9E3697E83F BE50000080002000810124020010100000020A79F11B1B4000003EFFBE10 3131800040000003F38CBD3C4108000020013FA614512D9E3697E83FBE50 000080002000810124020010100000020A79F11B1B400001F9FDB3805030 40110000200366E537AA0000101000023FDD55069755374FB90FFF500010 200481000A0002014050400002280510EA1F1F40000037FB35FAB0198000 F000001EDE7FF5DD9000000000207BAAD02C703C8B804897FF0800000111 0000014CC402011000003880875E695F1F40000037FB35FAB0198000F000 001EDE7FF5DD9000000000207BAAD02C703C8B804897FF08000001110000 014CC402011000003880875E695F1F400000BF593B6ED0080103F084008A 7FFF75F70000028102027FD75F270D4A4D92D6CFF7A8080200000004454D 5041042000023C0014897A1F5B400000B7F33AF0F00004271800440FED40 3725020008000000FFAD4096B228055089175FA8000848008002027FFF02 00000000E70003461D8E1B400000B7F33AF0F00004271800440FED403725 020008000000FFAD4096B228055089175FA8000848008002027FFF020000 0000E70003461D8E1B400010F5D33990910240000A0000199F00067F0800 00040004FFEEF87A6E20AA84454BFB9080800002001003E2D7E540110000 83004105DB2F5F4000013F735844F00000020800007FCC0007AAC0200000 2006FFFF5DDA99502AC4A935EF50080020050210139FFCE1401404200300 0945BA8D174900013F735844F00000020800007FCC0007AAC02000002006 FFFF5DDA99502AC4A935EF50080020050210139FFCE14014042003000945 BA8D17490000B1B11AD38000001078220173FC2023FC60009000000AFEFE B576BC844288047BBDD000010020800C1EF7A13E020000800E040082CBAE 3F4000017D335C6DC0104100FA001073F80201FDE0080212044AFBFFEEBA B7502A456A94F7D40020000500151DBBE7DE400000001C0092616F8EB740 00017D335C6DC0104100FA001073F80201FDE0080212044AFBFFEEBAB750 2A456A94F7D40020000500151DBBE7DE400000001C0092616F8EB7400000 BE173BDF80800003C000003FF1F9E0FF01000000000AFFDFFEEEBF50118A 8ADBFFC0000012009112F36577D6008000047000005055A96F4000097F13 19AF9001040300410277F078F0BED0200000000ABFF77F7D4DA98A822BA5 DFC8110040070014EFBE9EDBC40010106010106A678D3B4800097F1319AF 9001040300410277F078F0BED0200000000ABFF77F7D4DA98A822BA5DFC8 110040070014EFBE9EDBC40010106010106A678D3B480000BB5EBAD80200 2006020001DBC070F07F700000000002F7EFFFD696A4A584ABDDFFCA0004 00208002DD6FF3A600000000C040820C1A9D5F4000016F0F3BF400000026 000011E6E074F273780090004090FF7EFD95BED24A422BA5F7C80400020A 801796BBD8EBC0000040C00010270AAAEB4800016F0F3BF4000000260000 11E6E074F273780090004090FF7EFD95BED24A422BA5F7C80400020A8017 96BBD8EBC0000040C00010270AAAEB480000B64679E108000007F81040B5 A078F01E500400020404FFFFF7E74BD08D895AF7BECA0000000A0113F77E FF3764800000FF020108E7B6DB400001FB3337DC209042002081006DC470 F03BD10000080014F7ABFFF6BCD41FEAABB7FFEA2000200984164DEF6FD9 20008800008080807B1BFF400000AE1337B08000000080000075C070F03B B02000002014DEFFDFD7BF685BAC56FFFFEA0004024A0012FFBF3EFB6100 0001000004087DAB6F400000AE1337B08000000080000075C070F03BB020 00002014DEFFDFD7BF685BAC56FFFFEA0004024A0012FFBF3EFB61000001 000004087DAB6F400004BE675E3800000810020801F7C07F802A50000000 001DFFEAFFFCD5B497F2AB7FDFEA08000005801753044067D88000040220 1042F5B7D7400000FCBBFD3000100000000007E5C47F803BBC0000110014 FBBFBFFFDEAA4BD236FFBDF28100400A8045365D813DD800008000820600 8EEFFB440000FCBBFD3000100000000007E5C47F803BBC0000110014FBBF BFFFDEAA4BD236FFBDF28100400A8045365D813DD8000080008206008EEF FB440001364AA86804010000082020BDE070F0AB10800440025DEEF6EBDE 9D6C88094FFEFFE204110015081BCE4BF01B32810200020087CB7ABFDF40 0000BE93724900000800800200BFC070F03BD0001000001DBFFFDEEE97B0 648234DFEDF208000044801F3C3FFC9DBC000000080005A95E7AD7400000 BE93724900000800800200BFC070F03BD0001000001DBFFFDEEE97B06482 34DFEDF208000044801F3C3FFC9DBC000000080005A95E7AD7400000FE4D 58C0000000020080007DC078703BD1000008002BFFFFF5F7DFD1120D57FB FFF000000012800F5E68C317EA801000000807F0EE9E2B400020B695FAC8 000010080000003FE070701FD0010000882DFFEB7FAF795849028F7F9EF3 0000400500155E4EC21EDC000000204009A81DDC3F400020B695FAC80000 10080000003FE070701FD0010000882DFFEB7FAF795849028F7F9EF30000 400500155E4EC21EDC000000204009A81DDC3F400001BF5B51F000400100 090821F7A078727F78000040002BFDFFEEFD97557FFF4BFFF7B004010012 80155A35875EA6810008000006EAFFBDFF440000BB16F188110000000001 005FE470F07F7108000200ABF7FFBDD7FFAD00081FEEBFF10004000480B7 BE56C49B770002008002046C74FA2B400000BB16F188110000000001005F E470F07F7108000200ABF7FFBDD7FFAD00081FEEBFF10004000480B7BE56 C49B770002008002046C74FA2B400000BFBAB3D10000400000000077F070 F0BE60002010002BFFBFFFEF7ED4810296FFF5F108100026821BB657CD9F D6000000090803366EEFDB400000B7D6D7C8000004208008007F39FBC07E 80000040022B7EF6EDB5D7E8B4525FFBDFB1000000950016FD53769F7500 20000020400E9BBF77400000B7D6D7C8000004208008007F39FBC07E8000 0040022B7EF6EDB5D7E8B4525FFBDFB1000000950016FD53769F75002000 0020400E9BBF77400000BFD34B98200800080121087AE9FF03E781000400 002BEFFFBBEDBDB44D0915EF7FF1000000048017BE6FB31B569000022000 054D1FDFFF400000BECB47D0010000000000006FBC0003BD60000000002B FFF7FFD5EFD4B2A45FFFF6F1010010130876EC1DD91FB70102080000018B D7FBCF400000BECB47D0010000000000006FBC0003BD60000000002BFFF7 FFD5EFD4B2A45FFFF6F1010010130876EC1DD91FB70102080000018BD7FB CF400008FFDECED0000000001000007FBE00051FE0008008002AFDEEB4F6 DEF949555FDDBFF110000004801DBE5BEC1D5F0000200000008BAEB53F40 0000B746B990000001080000021FE7000EDF00001020402BB7BFEFDB7BAC 5085BEFFFFF10000000B0097FA6F775F740000000810006AFEEAD3400000 B746B990000001080000021FE7000EDF00001020402BB7BFEFDB7BAC5085 BEFFFFF10000000B0097FA6F775F740000000810006AFEEAD3400000BFF6 FCE8084020000042100F6F8014FF01000080012BFFFABBEADFFD2A0A7FFD DDF10000420A801FBCEEF51F7400080040009063EBB7FF400000BF16E190 00010000220000057EFFFB5300210000002BFFB7EFFB56F94589FD6FB7F1 0082002A8077B7999DDBD62020000084010ABE7817400000BF16E1900001 0000220000057EFFFB5300210000002BFFB7EFFB56F94589FD6FB7F10082 002A8077B7999DDBD62020000084010ABE7817400000B5D2DAD100000100 8000011FDE7FE9CD880000002022DEEB7BECDBFFEA0BF7FEFF710008000A 020E1F62A57E44010080000000077F726F400000FF6DF0D4010004240000 20556E7BB3EE208010010029FFFBFFFB5FEB6A97BDFFEFF1110000058815 DEAED7B76880000900008041B6E5DB440000FF6DF0D40100042400002055 6E7BB3EE208010010029FFFBFFFB5FEB6A97BDFFEFF1110000058815DEAE D7B76880000900008041B6E5DB440000B598F2D00000000000480003E77B 3FF400004000012BFFDFFAF5D6FDFD2BEB77BDF10000000A001EFF926CFD EC000000020808086ED496400000F79AD1D00020000001000203E5FBAB3C 000100200429FDFBEFFEEFBFB7DEFFFD7FB100001081905DEB03B1DF7E00 1000402001006BA109400000F79AD1D00020000001000203E5FBAB3C0001 00200429FDFBEFFEEFBFB7DEFFFD7FB100001081905DEB03B1DF7E001000 402001006BA109400000B525F1900200408020000003FF3FD4DC00000001 002DFFDEFFFD19EFFDEFD9DFEDF202200002810B2F7FF232501040090000 0008344047410000B7DAF3D010000401000000027B39D5A000080000000D DFFBF5FADEF9FFDFFF7BBF600000020280153F48223B5011000001008080 FE7C8F400000B7DAF3D010000401000000027B39D5A000080000000DDFFB F5FADEF9FFDFFF7BBF600000020280153F48223B5011000001008080FE7C 8F400000BFEDA1D000020008000000003FBD96C140200004022DFFEFFFEF 4DDFBF5EDDFFDBF200008009005DD77AACF75804000800000A0A73FFFF40 0000BDF6C39800000000020442103FFCFFC004000200001CFEEEEFBFB7F5 F59BF7EDFEE2080000250207D580B0C3F8000020000200007DBDFF400000 BDF6C39800000000020442103FFCFFC004000200001CFEEEEFBFB7F5F59B F7EDFEE2080000250207D580B0C3F8000020000200007DBDFF400000BBDB 55D00040100108100000017FCC00000000000015EFFBFDFF4B7EDE9FFEFF BFEA0000000080163EB4AFDE2030000004200004675F7D400000BFC707D0 0000012000000000013FC800000020000214BF57DFFFDDBBFA1FDBDEEFE2 2008000200137F7E7B3FC04000008000102A77B797400000BFC707D00000 012000000000013FC800000020000214BF57DFFFDDBBFA1FDBDEEFE22008 000200137F7E7B3FC04000008000102A77B797400000B48613D000000000 008000000119C000000000202814FDFFB7DF9FEFFC1FFF7BFFCA00000001 0007B77B2E76E050020423C24000EEFAAD400000BD1D4B91000080084000 088000100005000000808004EFE6FFFFCABAD05FB5FFFDCA000080800440 DF4FF3FF00000800020000805D2F57400000BD1D4B910000800840000880 00100005000000808004EFE6FFFFCABAD05FB5FFFDCA000080800440DF4F F3FF00000800020000805D2F57400000B7991FD021080200101000000200 00000020420800047DFFFFFFEFFFA20FFFF7B7CA000008011000DDB157B5 41312001260000057ED5BF400000BF3FFFD0000000044001000088002040 088000000002F7AD597FFAB6804EFBBFFFC800800004801137EBFFF74090 0048040A94007EBEDD440000BF3FFFD00000000440010000880020400880 00000002F7AD597FFAB6804EFBBFFFC800800004801137EBFFF740900048 040A94007EBEDD440000BE9AB79408201000020020200000020020010000 004AFFDFEFEFEDED401BDEFEFFC01000010020403BEC45C640C00000222A A880FF7B8F400000BAD1DED000810110080400000000000200000000000A EEF7DFFF6350085E7BF7BFD00000400000205E6F773D41300002038A4804 2FDFFF440000BAD1DED000810110080400000000000200000000000AEEF7 DFFF6350085E7BF7BFD00000400000205E6F773D41300002038A48042FDF FF440000BECF7DD000000001200000000008000000000002010AFFFCFFDB FFEC801F6EDFEF90400100002142573BD736400420000000000077DDD740 0004B9FB7B9000002004002002044000800000000008004AFFEFB5FFE528 097F7DFDFDB080040008060157EAA2EA2A40040020000021DABFBB400004 B9FB7B9000002004002002044000800000000008004AFFEFB5FFE528097F 7DFDFDB080040008060157EAA2EA2A40040020000021DABFBB400000BBDF F5D00008000010800000000000000080008000A4FEEDFFFDEDA020B76BBF B7A1001000200000007FFF000000004200000106647EEF410000BDF7EB90 0900022002020810040000080004040000CCF7B7BFDFEAA142BFFEFFFFB9 008000800800004DF30000000008040804073EEDF7400000BDF7EB900900 022002020810040000080004040000CCF7B7BFDFEAA142BFFEFFFFB90080 00800800004DF30000000008040804073EEDF7400000BBDF55F100110007 C018081C110927614160100000B07FFBFCFFFAA800FFDDF7BF8A82000001 001000088002000080404000000A79BFFB400000BDFDFA0E20002002E03C 3E14070387B040B0100002687FEEBFEFEAA80177A7DEEB29800000000840 8000800000200000002008081FFECF400000BDFDFA0E20002002E03C3E14 070387B040B0100002687FEEBFEFEAA80177A7DEEB298000000008408000 800000200000002008081FFECF400000BBF7E10080400004304232000C84 C4013190900000AE3FEFEFFFE1100ADFF8FFFF4B20000000000000000008 00800000008200AE4BAFAB400000BEBFD548410002043062220488844401 31801000011A3FDBFFF6F0A82497A9FFFF19A00040082000002800002400 12220000010C0AF76F400000BEBFD5484100020430622204888444013180 1000011A3FDBFFF6F0A82497A9FFFF19A000400820000028000024001222 0000010C0AF76F400000BD7A23D130020006220632040004440031101202 01CE3EEFDFDBF40202D7ACBFFE5BE0220020020000000000000000000008 088774BBDB400000BF5F5B1C00008082700C2A040086C5C020E01F08014A 3FFFB97EBA24212FDACBFE71A200000000000000804000008000220001AD 68ED5F000000BF5F5B1C00008082700C2A040086C5C020E01F08014A3FFF B97EBA24212FDACBFE71A200000000000000804000008000220001AD68ED 5F000008BEB6B3C714121007A01C3A04070746206190100008C8BFBFFFFE FC13480DED7CBAB3A4000881002008000202000000040010086FFA153F40 0000BB8AFD3FE1000004300223040C0860303182102021ECCEEDCF77DF54 4243F4EF7CA190002208208100020000024408400090373A1E4797440000 BB8AFD3FE1000004300223040C0860303182102021ECCEEDCF77DF544243 F4EF7CA190002208208100020000024408400090373A1E4797440000B6D6 6803F108012430026100080420303108100005E95FF7BDFF7E25210AF6BD ADABA800002004000000000000000002882846300662BB400000BBCBB3D8 3C902006B16622042804406331B0500001724DFFF7BFAF138015F7F7795A AC0420008001000000401000020801004E67F03B6F400000BBCBB3D83C90 2006B16622042804406331B0500001724DFFF7BFAF138015F7F7795AAC04 20008001000000401000020801004E67F03B6F400000AF5FC5543E000007 60FA3E1F9786C7C1B1E0100005722FCF7FDFFF19088EFD5FA84360008200 000000100000000010000050DE8FFCF99D000000BF8F89BFBE6120810008 08100A038500000000010AD7A7DBBF7F7FC982417F75F2F3880000221000 040020000080000022103E1C8C7CEB400000BF8F89BFBE61208100080810 0A038500000000010AD7A7DBBF7F7FC982417F75F2F38800002210000400 20000080000022103E1C8C7CEB400000BF5A3AAD17A00410000000000000 0000000000200252B37FFDF7DBD1494B7BAF66D320800080002010010204 0010421200A03E677A7EBF400000BD8223F48F9080000000000000000000 000000000074D3EFD7DFEF89CA08BB7EE5F3320020000000004000000401 0080890074CFED973B000000BD8223F48F90800000000000000000000000 00000074D3EFD7DFEF89CA08BB7EE5F33200200000000040000004010080 890074CFED973B000000AE3CF90545D08000000000010010000000004000 013A43FA7EBF7FA16B52B9DBE5B6A80800040404000000201000040000C0 F9D8159D3B400000B73C9607B7680008000000000000000010010401088D C9EFADDF9FCD54942DEF49F54020BFFD800000040000000000122420E8E8 1BC397400000B73C9607B7680008000000000000000010010401088DC9EF ADDF9FCD54942DEF49F54020BFFD800000040000000000122420E8E81BC3 97400000BA79A80EB3601500208300805000401000800044017E74BFFFF7 FFD4C094ADBF9373D2003DCD8000800000000100080002C2F3301D679308 0000AE69D807A9E00000800C0807F800008902000000409554FFF7BDFFEA 554A7FFB17FD55922968240000004004002020A08902B5E01FA757400000 AE69D807A9E00000800C0807F800008902000000409554FFF7BDFFEA554A 7FFB17FD55922968240000004004002020A08902B5E01FA757400000BAF2 F80DF179001000103009000C003E083C20006F2FB36EDDEFDBEBB6115CDF A6AB5E000000008001C000004C0000060285E6E01AB3DF000000BCF3780E B9F0010D00320002001C003B10360009AAA3FB7FFFFBFFF5534277F7AEF7 72800336804012500020480600102B05A7501EF2DF400000BCF3780EB9F0 010D00320002001C003B10360009AAA3FB7FFFFBFFF5534277F7AEF77280 0336804012500020480600102B05A7501EF2DF400000BCC2B44D55B8103F 8204001910181212042004204FF87CB76DDFD7FB54485DFF0FB3E88002C6 120024100020480400000F45CDE89DCB9B000000BCF7BC076CE80031C045 04113113C8656E68800125D43C9FF77F7EF4905076BE1EE1B10443A40000 04100028FE0000002FC546D01EBB5F480000BCF7BC076CE80031C0450411 3113C8656E68800125D43C9FF77F7EF4905076BE1EE1B10443A400000410 0028FE0000002FC546D01EBB5F480000B4C5680FF4D90020C0DD140257EE 50C9C1D9B08457F4EE8FFFFEFFDBAD41AFFA3D0FE7920324200004165678 69E1B10112418DD81DE9D7000004BCC5688D2CB82202C073D8027B30F103 4272E011BA7E774F7FF7FDF54C40DDFCB15D5FA800400004065AD4B0594A D2004553CF601C599F480004BCC5688D2CB82202C073D8027B30F1034272 E011BA7E774F7FF7FDF54C40DDFCB15D5FA800400004065AD4B0594AD200 4553CF601C599F480000BDADF427F6E80029C00104100500000800000005 E9D23F2FDDBFB7F9A288AD79BF2ED0DD10C004004393772C49F49DC02948 49A81AE98F000000BD8EEC0DBE78081F00030000120200000000022226BD 1D87FFFEFFFCB081AB726DD9FD0481E1100440000000000000054BCBCFE8 9FDD6F400000BD8EEC0DBE78081F00030000120200000000022226BD1D87 FFFEFFFCB081AB726DD9FD0481E1100440000000000000054BCBCFE89FDD 6F400000BD6BD8273668203C10010100960000000000801D5AE5CFD3D7DF EFFF835696E67F72522B00A0004000008000040000002F8A5DA81EF5CB08 0000B9CCEC8FBA7080B0400400000800000831000021A42B7369FDF7FBFD 6D165DC9A9D571A8404406810000020100002000980A8FB81A596F400000 B9CCEC8FBA7080B0400400000800000831000021A42B7369FDF7FBFD6D16 5DC9A9D571A8404406810000020100002000980A8FB81A596F4000083D4F EC0EEE5810240080082038040000480820008186FDE8FF7FCFFDAC8A5589 EFAABCA90000296001020000201000142402DDA05EFDCF400000BDADEC0D B6F082380000000000000101040080057F7A6DACEFF77800030557CDF6DF BFF4109083E00010002000810040900A4F981CD54D000000BDADEC0DB6F0 82380000000000000101040080057F7A6DACEFF77800030557CDF6DFBFF4 109083E00010002000810040900A4F981CD54D000020BD4F6847FA7A003F C01040020000001070200225FFBEBEE8FFBFCE837C7255E6FFF6EB5BEFEF 7F5020402003100000022AC2CBE81FD9EF400000B5C5EC0DAED008011248 0100082062011C040000000000030DF0A2A970536C1100495495595AAB51 2200038204802200DFC94EB11EEB5B000000B5C5EC0DAED0080112480100 082062011C040000000000030DF0A2A970536C1100495495595AAB512200 038204802200DFC94EB11EEB5B000000AC86700E6CB800A4001004028401 42005F7BFDBFB7F6F7F367AB4E000494AF99FFBFBBBF77FFBC700A6F91D2 B4F0000900024BD819B9DD48000034D7B806D5D2400020AE61532A3E19C1 200000000000000794843FFFFF8C117C000000009120A2A03150A2455300 000850850CE05FDB5B40000034D7B806D5D2400020AE61532A3E19C12000 00000000000794843FFFFF8C117C000000009120A2A03150A24553000008 50850CE05FDB5B400000AAD2F04DD9A80000005256A0C4124511BFFFFFFF FFFFFFFF2D07FFFFFFFC2CFFFFFFFFFFFFFFFF2400010000002022220215 67E81A731F400010BED37806E9D84404888000000000000E5FFFFFFFFFFF FFFF9C7FFDFFFFFFAC7FFFFFFFFFFFFFFED40200000000208004A0056660 1BB3DF400010BED37806E9D84404888000000000000E5FFFFFFFFFFFFFFF 9C7FFDFFFFFFAC7FFFFFFFFFFFFFFED40200000000208004A00566601BB3 DF400000BBABD805B920108800100000000000053FFFFFFFFFFFFFFEBFFF D54800FFFFF9FFFFFFFFFFFFFD25844250840002846B10A237B10EE60300 0000AF494100A351400000000080000000450FFFFFFFFFFFFFFF55DFADAB FD0FFDE52DFFFFFFFFFFFD46302B56337B7428B4EE2A55C023A75F400000 AF494100A351400000000080000000450FFFFFFFFFFFFFFF55DFADABFD0F FDE52DFFFFFFFFFFFD46302B56337B7428B4EE2A55C023A75F4000003F4C FFFFD6AB39B5BB9ABD735335A695792A001001000000F80006A040C001A0 038903400006890112AD50A92526955BA4B4B37FFEE5BF480000B334AFFF 164A952DA92C4654122AD2A516A41C1801C200008C0307A0E07007F007FE 03B00403AEA4A55D6AA41864B4F7CAB488DFFE4EAB400000B334AFFF164A 952DA92C4654122AD2A516A41C1801C200008C0307A0E07007F007FE03B0 0403AEA4A55D6AA41864B4F7CAB488DFFE4EAB400000B7A2736B8D365A0C 22D65DEB5AA537545B601E0600F700E0EA438180E01807F80FE801FC0603 D276DF6BF77BEFA76AACAF4ADDE7FB9937400008BE971AE9CD5BFDFBFBBB 6EB3DDBEFB5B2FA01E07007700E0F4078980E0180F681FFA10DC0411ED65 000000000000000040115457461C4F000008BE971AE9CD5BFDFBFBBB6EB3 DDBEFB5B2FA01E07007700E0F4078980E0180F681FFA10DC0411ED650000 00000000000040115457461C4F0000002FD1956F18200000000000000000 0008EEC01E074037008FF4038080E0100D901E8580F40C07CA98FFFFFFFF FFFFFFFFFFFF0E2DAA72DD410000BE52C7AE317FFFFFFFFFFFFFFFFFFFAF 55A21E076007208FDA038080E0380F181B598074004FE9FE3A6FB0D72BFF BBFFDFFFB18EACC4F7400000BE52C7AE317FFFFFFFFFFFFFFFFFFFAF55A2 1E076007208FDA038080E0380F181B598074004FE9FE3A6FB0D72BFFBBFF DFFFB18EACC4F7400000BA68E358627FF7FBDBDFFFFFED7DDF5D6BA01C07 620600CE75238080F0188E981F9B84781407ABA75FFFE55FBDFBEF7F4BF6 CB8BB8E9AF400000AEE638018AF3FAAFFAFEF3AF6AEFF6B7E7C05E077007 00E8D4839384E0180E180E1B803C0C07AAFB3F7773BB5577BDFF4FF7A460 0313E7400000AEE638018AF3FAAFFAFEF3AF6AEFF6B7E7C05E07700700E8 D4839384E0180E180E1B803C0C07AAFB3F7773BB5577BDFF4FF7A4600313 E7400000BDF29C0785BB753EBBDBDF7B6D5D563EF5E01E46380700E0F603 81C0E0301C181E1BC0384483ADA55E3BF4F6FFACEB7EB6FFF5784EA7DB40 000025BD27FE1BF5FCDFD9F77BEFCAFB39776F401C1E2C0704C0E80303C0 C0600810081180300403B3EB231BE75F5577DEBB676EA90F7A8FF7400000 25BD27FE1BF5FCDFD9F77BEFCAFB39776F401C1E2C0704C0E80303C0C060 0810081180300403B3EB231BE75F5577DEBB676EA90F7A8FF7400000BFFC 81F0177BDDB7FEEFD7B5B57E3AB5ABEC1C1C0A061000F00217F041C00000 0000010103045DF75A37B6BDFBF77EFCABDEE8A6B41DEF000000B3573202 8DB5F555ADBDFBE75E76D03157B7EBFFFDFFFFFFDFFFFFDFFFFFFFFFFFFF FFFFFFFFD2D54D9DEF7D6D77D79D7DEB9E004877B7440000B35732028DB5 F555ADBDFBE75E76D03157B7EBFFFDFFFFFFDFFFFFDFFFFFFFFFFFFFFFFF FFFFD2D54D9DEF7D6D77D79D7DEB9E004877B7440000BDDD18009AEEF9AF F5FEF7F7B57B4D3D6FCFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFFF FD76A335C74F7AF7DEEB66AFEF00A0DECB400000BB7BE3FC6EDF675B6F79 DDDE9FAE24571EEBFFFFFF7FFFFFF7FFFFB7FF5FFFFFFFFFFFFFFFFFE5D7 8E7EB7B97FFBFDB6BDFEFFF057FEFF000000BB7BE3FC6EDF675B6F79DDDE 9FAE24571EEBFFFFFF7FFFFFF7FFFFB7FF5FFFFFFFFFFFFFFFFFE5D78E7E B7B97FFBFDB6BDFEFFF057FEFF0000009DEFF803BFBDBBBDFB7F7F77FFFF FFFEFBAAFFE9FBBFFFFFD9FFFEDB7DDFFFFFDDF7FFBDA9552502AA454292 45102050804000048800004000083FFFFF5FFFFFFFFFFFFFFDFEF6AAD2AB 2CA504142440000000000000000000000000000000000000000000000000 0000020000000000804800083FFFFF5FFFFFFFFFFFFFFDFEF6AAD2AB2CA5 041424400000000000000000000000000000000000000000000000000000 0200000000008048000080000000000000000000000000211224134AEAB7 ABBEFFFFFFFFFFFFFFFBFFFFFFFFED77FFBFFFFFFFFFFFFFFFFFFFFFFFFF FFFFF08400000000A48D53EDB6EFFFFFFFFFFFF7FFDEFDB56D4AAA54A080 000000000000000000000000000000000000000000000000000000000000 020000900000A48D53EDB6EFFFFFFFFFFFF7FFDEFDB56D4AAA54A0800000 000000000000000000000000000000000000000000000000000000000200 009000000000000000000000000000000000000000000000001000000000 000000000000000000000000000000000000000000000800040000800000 000000000000000000000000000000000000000000000000100000000000 000000000000000000000000000000100000004400948000100200400000 000000000000000000000000000000000000000000001000000000000000 000000000000000000000000001000000044009480001002004000000100 800000000000000000000000000000000000040040880000000000000000 000000000010100000000000000000004000000040000200000004000000 000000008000000000000000000000000008000084200000000000000002 088401008000800004000002200004000020000040000000040000000000 000080000000000000000000000000080000842000000000000000020884 010080008000040000022000040000200000400000000000000004400000 000000000000000002080008000000000000000000000000000000000002 000004010000000000000000000100010000000010000000000000000001 444000020000000000002000002200000000000000000000000020200000 000400040010001080000000000400100000100000000000000000014440 000200000000000020000022000000000000000000000000202000000004 000400100010800000000004001000000008910800000000000000000000 000010002000002000800820880000000000020010080200000000000010 0080000000000400001000000024810000000000800A0084000042000001 008000800100420000020000000011000810802000480002010000400400 040020001000000004000024810000000000800A00840000420000010080 008001004200000200000000110008108020004800020100004004000400 200010000000040000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000 00> } imagemask grestore 0.500008 0.500008 0.500008 SetBgColor 421 154 121 2 Box Fill 540 86 2 70 Box Fill 0.750011 0.750011 0.750011 SetBgColor newpath 421 156 moveto 421 86 lineto 542 86 lineto 540 88 lineto 423 88 lineto 423 154 lineto 421 156 lineto 421 156 lineto closepath Fill 0 setlinejoin 0 setlinecap 0 0 0 SetFgColor 3 setlinewidth [ ] 0 setdash 448 102 42 Li 1 setlinewidth [ ] 0 setdash /DrawSymbolProc { gsave 0.996109 0.644541 0 SetBgColor Fill 0 0 0 SetFgColor stroke grestore } def 448 102 21 Ci 58 27 0 502 104 BeginText 14 /Helvetica SetFont 0 0 0 SetFgColor (sin\(x\)) 58 0 21 DrawAdjText EndText 0 setlinejoin 0 setlinecap 0.542977 0.542977 0 SetFgColor 3 setlinewidth [ ] 0 setdash 448 135 42 Li 1 setlinewidth [ ] 0 setdash /DrawSymbolProc { gsave 0.996109 0.996109 0 SetBgColor Fill 0.542977 0.542977 0 SetFgColor stroke grestore } def 448 135 21 Ci 64 27 0 505 137 BeginText 14 /Helvetica SetFont 0 0 0 SetFgColor (cos\(x\)) 64 0 21 DrawAdjText EndText 24 16 90 537 388 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (360) 24 0 12 DrawAdjText EndText 32 16 90 79 384 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (-360) 32 0 12 DrawAdjText EndText 8 16 0 85 90 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (1) 8 0 12 DrawAdjText EndText 16 16 0 89 402 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (-1) 16 0 12 DrawAdjText EndText 8 16 90 537 364 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (1) 8 0 12 DrawAdjText EndText 8 16 90 79 356 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0) 8 0 12 DrawAdjText EndText 8 16 0 101 90 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (1) 8 0 12 DrawAdjText EndText 8 16 0 109 402 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0) 8 0 12 DrawAdjText EndText % Element "line2" 0 setlinejoin 0 setlinecap 0.542977 0.542977 0 SetFgColor 1 setlinewidth [ ] 0 setdash /DashesProc {} def newpath 79 90 moveto 82 90 lineto 85 92 lineto 88 95 lineto 91 99 lineto 94 104 lineto 98 110 lineto 101 118 lineto 104 126 lineto 107 135 lineto 110 145 lineto 114 156 lineto 117 168 lineto 120 180 lineto 123 192 lineto 126 205 lineto 130 219 lineto 133 232 lineto 136 246 lineto 139 260 lineto 142 273 lineto 145 287 lineto 149 300 lineto 152 312 lineto 155 324 lineto 158 336 lineto 161 347 lineto 165 357 lineto 168 366 lineto 171 374 lineto 174 382 lineto 177 388 lineto 181 393 lineto 184 397 lineto 187 400 lineto 190 402 lineto 193 403 lineto 196 402 lineto 200 400 lineto 203 397 lineto 206 393 lineto 209 388 lineto 212 382 lineto 216 374 lineto 219 366 lineto 222 357 lineto 225 347 lineto 228 336 lineto 232 324 lineto 235 312 lineto 238 300 lineto 241 287 lineto 244 273 lineto 247 260 lineto 251 246 lineto 254 232 lineto 257 219 lineto 260 205 lineto 263 192 lineto 267 180 lineto 270 168 lineto 273 156 lineto 276 145 lineto 279 135 lineto 283 126 lineto 286 118 lineto 289 110 lineto 292 104 lineto 295 99 lineto 298 95 lineto 302 92 lineto 305 90 lineto 308 90 lineto 311 90 lineto 314 92 lineto 318 95 lineto 321 99 lineto 324 104 lineto 327 110 lineto 330 118 lineto 334 126 lineto 337 135 lineto 340 145 lineto 343 156 lineto 346 168 lineto 349 180 lineto 353 192 lineto 356 205 lineto 359 219 lineto 362 232 lineto 365 246 lineto 369 260 lineto 372 273 lineto 375 287 lineto 378 300 lineto 381 312 lineto 385 324 lineto 388 336 lineto 391 347 lineto 394 357 lineto 397 366 lineto 400 374 lineto 404 382 lineto 407 388 lineto 410 393 lineto 413 397 lineto 416 400 lineto 420 402 lineto 423 403 lineto 426 402 lineto 429 400 lineto 432 397 lineto 436 393 lineto 439 388 lineto 442 382 lineto 445 374 lineto 448 366 lineto 451 357 lineto 455 347 lineto 458 336 lineto 461 324 lineto 464 312 lineto 467 300 lineto 471 287 lineto 474 273 lineto 477 260 lineto 480 246 lineto 483 232 lineto 487 219 lineto 490 205 lineto 493 192 lineto 496 180 lineto 499 168 lineto 502 156 lineto 506 145 lineto 509 135 lineto 512 126 lineto 515 118 lineto 518 110 lineto 522 104 lineto 525 99 lineto 528 95 lineto 531 92 lineto 534 90 lineto 538 90 lineto DashesProc stroke 1 setlinewidth [ ] 0 setdash /DrawSymbolProc { gsave 0.996109 0.996109 0 SetBgColor Fill 0.542977 0.542977 0 SetFgColor stroke grestore } def 79 90 9 Ci 82 90 9 Ci 85 92 9 Ci 88 95 9 Ci 91 99 9 Ci 94 104 9 Ci 98 110 9 Ci 101 118 9 Ci 104 126 9 Ci 107 135 9 Ci 110 145 9 Ci 114 156 9 Ci 117 168 9 Ci 120 180 9 Ci 123 192 9 Ci 126 205 9 Ci 130 219 9 Ci 133 232 9 Ci 136 246 9 Ci 139 260 9 Ci 142 273 9 Ci 145 287 9 Ci 149 300 9 Ci 152 312 9 Ci 155 324 9 Ci 158 336 9 Ci 161 347 9 Ci 165 357 9 Ci 168 366 9 Ci 171 374 9 Ci 174 382 9 Ci 177 388 9 Ci 181 393 9 Ci 184 397 9 Ci 187 400 9 Ci 190 402 9 Ci 193 403 9 Ci 196 402 9 Ci 200 400 9 Ci 203 397 9 Ci 206 393 9 Ci 209 388 9 Ci 212 382 9 Ci 216 374 9 Ci 219 366 9 Ci 222 357 9 Ci 225 347 9 Ci 228 336 9 Ci 232 324 9 Ci 235 312 9 Ci 238 300 9 Ci 241 287 9 Ci 244 273 9 Ci 247 260 9 Ci 251 246 9 Ci 254 232 9 Ci 257 219 9 Ci 260 205 9 Ci 263 192 9 Ci 267 180 9 Ci 270 168 9 Ci 273 156 9 Ci 276 145 9 Ci 279 135 9 Ci 283 126 9 Ci 286 118 9 Ci 289 110 9 Ci 292 104 9 Ci 295 99 9 Ci 298 95 9 Ci 302 92 9 Ci 305 90 9 Ci 308 90 9 Ci 311 90 9 Ci 314 92 9 Ci 318 95 9 Ci 321 99 9 Ci 324 104 9 Ci 327 110 9 Ci 330 118 9 Ci 334 126 9 Ci 337 135 9 Ci 340 145 9 Ci 343 156 9 Ci 346 168 9 Ci 349 180 9 Ci 353 192 9 Ci 356 205 9 Ci 359 219 9 Ci 362 232 9 Ci 365 246 9 Ci 369 260 9 Ci 372 273 9 Ci 375 287 9 Ci 378 300 9 Ci 381 312 9 Ci 385 324 9 Ci 388 336 9 Ci 391 347 9 Ci 394 357 9 Ci 397 366 9 Ci 400 374 9 Ci 404 382 9 Ci 407 388 9 Ci 410 393 9 Ci 413 397 9 Ci 416 400 9 Ci 420 402 9 Ci 423 403 9 Ci 426 402 9 Ci 429 400 9 Ci 432 397 9 Ci 436 393 9 Ci 439 388 9 Ci 442 382 9 Ci 445 374 9 Ci 448 366 9 Ci 451 357 9 Ci 455 347 9 Ci 458 336 9 Ci 461 324 9 Ci 464 312 9 Ci 467 300 9 Ci 471 287 9 Ci 474 273 9 Ci 477 260 9 Ci 480 246 9 Ci 483 232 9 Ci 487 219 9 Ci 490 205 9 Ci 493 192 9 Ci 496 180 9 Ci 499 168 9 Ci 502 156 9 Ci 506 145 9 Ci 509 135 9 Ci 512 126 9 Ci 515 118 9 Ci 518 110 9 Ci 522 104 9 Ci 525 99 9 Ci 528 95 9 Ci 531 92 9 Ci 534 90 9 Ci 538 90 9 Ci % Element "line1" 0 setlinejoin 0 setlinecap 0 0 0 SetFgColor 1 setlinewidth [ ] 0 setdash /DashesProc {} def newpath 79 246 moveto 82 232 lineto 85 219 lineto 88 205 lineto 91 192 lineto 94 180 lineto 98 168 lineto 101 156 lineto 104 145 lineto 107 135 lineto 110 126 lineto 114 118 lineto 117 110 lineto 120 104 lineto 123 99 lineto 126 95 lineto 130 92 lineto 133 90 lineto 136 90 lineto 139 90 lineto 142 92 lineto 145 95 lineto 149 99 lineto 152 104 lineto 155 110 lineto 158 118 lineto 161 126 lineto 165 135 lineto 168 145 lineto 171 156 lineto 174 168 lineto 177 180 lineto 181 192 lineto 184 205 lineto 187 219 lineto 190 232 lineto 193 246 lineto 196 260 lineto 200 273 lineto 203 287 lineto 206 300 lineto 209 312 lineto 212 324 lineto 216 336 lineto 219 347 lineto 222 357 lineto 225 366 lineto 228 374 lineto 232 382 lineto 235 388 lineto 238 393 lineto 241 397 lineto 244 400 lineto 247 402 lineto 251 403 lineto 254 402 lineto 257 400 lineto 260 397 lineto 263 393 lineto 267 388 lineto 270 382 lineto 273 374 lineto 276 366 lineto 279 357 lineto 283 347 lineto 286 336 lineto 289 324 lineto 292 312 lineto 295 300 lineto 298 287 lineto 302 273 lineto 305 260 lineto 308 246 lineto 311 232 lineto 314 219 lineto 318 205 lineto 321 192 lineto 324 180 lineto 327 168 lineto 330 156 lineto 334 145 lineto 337 135 lineto 340 126 lineto 343 118 lineto 346 110 lineto 349 104 lineto 353 99 lineto 356 95 lineto 359 92 lineto 362 90 lineto 365 90 lineto 369 90 lineto 372 92 lineto 375 95 lineto 378 99 lineto 381 104 lineto 385 110 lineto 388 118 lineto 391 126 lineto 394 135 lineto 397 145 lineto 400 156 lineto 404 168 lineto 407 180 lineto 410 192 lineto 413 205 lineto 416 219 lineto 420 232 lineto 423 246 lineto 426 260 lineto 429 273 lineto 432 287 lineto 436 300 lineto 439 312 lineto 442 324 lineto 445 336 lineto 448 347 lineto 451 357 lineto 455 366 lineto 458 374 lineto 461 382 lineto 464 388 lineto 467 393 lineto 471 397 lineto 474 400 lineto 477 402 lineto 480 403 lineto 483 402 lineto 487 400 lineto 490 397 lineto 493 393 lineto 496 388 lineto 499 382 lineto 502 374 lineto 506 366 lineto 509 357 lineto 512 347 lineto 515 336 lineto 518 324 lineto 522 312 lineto 525 300 lineto 528 287 lineto 531 273 lineto 534 260 lineto 538 246 lineto DashesProc stroke 1 setlinewidth [ ] 0 setdash /DrawSymbolProc { gsave 0.996109 0.644541 0 SetBgColor Fill 0 0 0 SetFgColor stroke grestore } def 79 246 9 Ci 82 232 9 Ci 85 219 9 Ci 88 205 9 Ci 91 192 9 Ci 94 180 9 Ci 98 168 9 Ci 101 156 9 Ci 104 145 9 Ci 107 135 9 Ci 110 126 9 Ci 114 118 9 Ci 117 110 9 Ci 120 104 9 Ci 123 99 9 Ci 126 95 9 Ci 130 92 9 Ci 133 90 9 Ci 136 90 9 Ci 139 90 9 Ci 142 92 9 Ci 145 95 9 Ci 149 99 9 Ci 152 104 9 Ci 155 110 9 Ci 158 118 9 Ci 161 126 9 Ci 165 135 9 Ci 168 145 9 Ci 171 156 9 Ci 174 168 9 Ci 177 180 9 Ci 181 192 9 Ci 184 205 9 Ci 187 219 9 Ci 190 232 9 Ci 193 246 9 Ci 196 260 9 Ci 200 273 9 Ci 203 287 9 Ci 206 300 9 Ci 209 312 9 Ci 212 324 9 Ci 216 336 9 Ci 219 347 9 Ci 222 357 9 Ci 225 366 9 Ci 228 374 9 Ci 232 382 9 Ci 235 388 9 Ci 238 393 9 Ci 241 397 9 Ci 244 400 9 Ci 247 402 9 Ci 251 403 9 Ci 254 402 9 Ci 257 400 9 Ci 260 397 9 Ci 263 393 9 Ci 267 388 9 Ci 270 382 9 Ci 273 374 9 Ci 276 366 9 Ci 279 357 9 Ci 283 347 9 Ci 286 336 9 Ci 289 324 9 Ci 292 312 9 Ci 295 300 9 Ci 298 287 9 Ci 302 273 9 Ci 305 260 9 Ci 308 246 9 Ci 311 232 9 Ci 314 219 9 Ci 318 205 9 Ci 321 192 9 Ci 324 180 9 Ci 327 168 9 Ci 330 156 9 Ci 334 145 9 Ci 337 135 9 Ci 340 126 9 Ci 343 118 9 Ci 346 110 9 Ci 349 104 9 Ci 353 99 9 Ci 356 95 9 Ci 359 92 9 Ci 362 90 9 Ci 365 90 9 Ci 369 90 9 Ci 372 92 9 Ci 375 95 9 Ci 378 99 9 Ci 381 104 9 Ci 385 110 9 Ci 388 118 9 Ci 391 126 9 Ci 394 135 9 Ci 397 145 9 Ci 400 156 9 Ci 404 168 9 Ci 407 180 9 Ci 410 192 9 Ci 413 205 9 Ci 416 219 9 Ci 420 232 9 Ci 423 246 9 Ci 426 260 9 Ci 429 273 9 Ci 432 287 9 Ci 436 300 9 Ci 439 312 9 Ci 442 324 9 Ci 445 336 9 Ci 448 347 9 Ci 451 357 9 Ci 455 366 9 Ci 458 374 9 Ci 461 382 9 Ci 464 388 9 Ci 467 393 9 Ci 471 397 9 Ci 474 400 9 Ci 477 402 9 Ci 480 403 9 Ci 483 402 9 Ci 487 400 9 Ci 490 397 9 Ci 493 393 9 Ci 496 388 9 Ci 499 382 9 Ci 502 374 9 Ci 506 366 9 Ci 509 357 9 Ci 512 347 9 Ci 515 336 9 Ci 518 324 9 Ci 522 312 9 Ci 525 300 9 Ci 528 287 9 Ci 531 273 9 Ci 534 260 9 Ci 538 246 9 Ci % Unset clipping grestore 0.750011 0.750011 0.750011 SetBgColor 0 0 598 82 Box Fill 0 82 70 329 Box Fill 546 82 52 329 Box Fill 0 411 598 68 Box Fill 0.500008 0.500008 0.500008 SetBgColor 69 410 478 2 Box Fill 545 80 2 332 Box Fill 0.750011 0.750011 0.750011 SetBgColor newpath 69 412 moveto 69 80 lineto 547 80 lineto 545 82 lineto 71 82 lineto 71 410 lineto 69 412 lineto 69 412 lineto closepath Fill 311 29 0 308 20 BeginText 14 /Helvetica-Bold SetFont 0 0 0 SetFgColor (Sine and Cosine Functions) 311 0 23 DrawAdjText EndText 7 16 0 308 463 BeginText 8 /Helvetica SetFont 0 0 0 SetFgColor (X) 7 0 13 DrawAdjText EndText 40 16 0 79 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (-360°) 40 0 12 DrawAdjText EndText 40 16 0 136 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (-270°) 40 0 12 DrawAdjText EndText 40 16 0 193 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (-180°) 40 0 12 DrawAdjText EndText 32 16 0 251 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (-90°) 32 0 12 DrawAdjText EndText 16 16 0 308 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0°) 16 0 12 DrawAdjText EndText 24 16 0 365 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (90°) 24 0 12 DrawAdjText EndText 32 16 0 423 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (180°) 32 0 12 DrawAdjText EndText 32 16 0 480 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (270°) 32 0 12 DrawAdjText EndText 32 16 0 538 441 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (360°) 32 0 12 DrawAdjText EndText 0 setlinejoin 0 setlinecap 0 0 0 SetFgColor 1 setlinewidth [ ] 0 setdash 79 416 538 416 LS 79 416 79 428 LS 136 416 136 428 LS 193 416 193 428 LS 251 416 251 428 LS 308 416 308 428 LS 365 416 365 428 LS 423 416 423 428 LS 480 416 480 428 LS 538 416 538 428 LS 9 16 90 18 246 BeginText 8 /Helvetica SetFont 0.566415 0.171878 0.929702 SetFgColor (Y) 9 0 13 DrawAdjText EndText 16 16 90 40 403 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (-1) 16 0 12 DrawAdjText EndText 32 16 90 40 324 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (-0.5) 32 0 12 DrawAdjText EndText 8 16 90 40 246 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (0) 8 0 12 DrawAdjText EndText 24 16 90 40 168 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (0.5) 24 0 12 DrawAdjText EndText 8 16 90 40 90 BeginText 8 /CourierNewBold-Bold SetFont 0.566415 0.171878 0.929702 SetFgColor (1) 8 0 12 DrawAdjText EndText 0 setlinejoin 0 setlinecap 0.566415 0.171878 0.929702 SetFgColor 1 setlinewidth [ ] 0 setdash 65 403 65 90 LS 65 363 59 363 LS 65 403 53 403 LS 65 285 59 285 LS 65 324 53 324 LS 65 207 59 207 LS 65 246 53 246 LS 65 129 59 129 LS 65 168 53 168 LS 65 90 53 90 LS 8 16 0 79 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0) 8 0 12 DrawAdjText EndText 24 16 0 170 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0.2) 24 0 12 DrawAdjText EndText 24 16 0 262 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0.4) 24 0 12 DrawAdjText EndText 24 16 0 354 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0.6) 24 0 12 DrawAdjText EndText 24 16 0 446 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (0.8) 24 0 12 DrawAdjText EndText 8 16 0 538 51 BeginText 8 /CourierNewBold-Bold SetFont 0 0 0 SetFgColor (1) 8 0 12 DrawAdjText EndText 0 setlinejoin 0 setlinecap 0 0 0 SetFgColor 1 setlinewidth [ ] 0 setdash 79 76 538 76 LS 124 76 124 70 LS 79 76 79 64 LS 216 76 216 70 LS 170 76 170 64 LS 308 76 308 70 LS 262 76 262 64 LS 400 76 400 70 LS 354 76 354 64 LS 492 76 492 70 LS 446 76 446 64 LS 538 76 538 64 LS 8 16 0 572 403 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (0) 8 0 12 DrawAdjText EndText 24 16 0 580 340 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (0.2) 24 0 12 DrawAdjText EndText 24 16 0 580 277 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (0.4) 24 0 12 DrawAdjText EndText 24 16 0 580 215 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (0.6) 24 0 12 DrawAdjText EndText 24 16 0 580 152 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (0.8) 24 0 12 DrawAdjText EndText 8 16 0 572 90 BeginText 8 /CourierNewBold-Bold SetFont 0.800793 0 0.800793 SetFgColor (1) 8 0 12 DrawAdjText EndText 0 setlinejoin 0 setlinecap 0.800793 0 0.800793 SetFgColor 1 setlinewidth [ ] 0 setdash 551 403 551 90 LS 551 371 557 371 LS 551 403 563 403 LS 551 309 557 309 LS 551 340 563 340 LS 551 246 557 246 LS 551 277 563 277 LS 551 183 557 183 LS 551 215 563 215 LS 551 121 557 121 LS 551 152 563 152 LS 551 90 563 90 LS showpage %Trailer grestore end %EOF �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/clouds.gif�����������������������������������������������������������0000644�0001750�0001750�00000014416�11462120062�016600� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87aP�P�÷��ÿÿÿ÷ÿÿïÿÿçÿÿÞ÷ÿç÷ÿµÖçÖïÿÎç÷½Öç­ÎçœÆç­Ö÷ÞïÿÖç÷ÎçÿÎÞïÆÖç¥ÆçŒµÞœ½ç”µÞŒµçÖçÿ½Ö÷­Æç¥½ÞœµÖ½Î电猭ÞÎÞ÷œµÞÎÞÿÆÖ÷½ÎïµÆçœµç”­ÞŒ¥Ö”­çŒ¥Þ{”ÎÆÖÿ½Î÷­½ç¥µÞœ­Ö”­ï„œÖŒ¥ç{”ÖsŒÎZsµ½ÆÞµÆ÷œ­Þ”¥Ö„œÞZs½RkµJc­¥µçµÆÿœ­ç”¥Þ{ŒÆJcµ9R¥)B”1„½Æç­½÷œ­ïŒœÖ”¥ç„”Î{ŒÎs„ÆBZ­!9ŒÎÖ÷œ­÷ŒœÞ”¥ï„”Ö{ŒÖk{½s„ÎcsµZkµRc­1”!„�{ÆÎ÷­µÞk{Æcs½Zk½RcµJZ­BR¥9Jœ9J¥1B”1Bœ)9Œ!1„)„œ¥ÞJZµBR­BRµ9J­1B¥)9”)9œ!1Œ!1”!„{�s”œÖŒ”Μ¥ç{„Æ)9¥!1œ�{”œÞŒ”Ö„ŒÎ„ŒÖs{½{„Îs{Æks½ckµck½Zc­ZcµRZ­JR¥BJœ9B”JR­JRµBJ­9B¥)1Œ)1”!)Œ!„{s„�sÞÞÿÖÖ÷ÆÆçÖÖÿÎÎ÷½½çµµÞµµç­­Þ­­ç¥¥ÞœœÖ””Îkk½ccµcc½ZZ­ZZµRR¥JJœRRµJJ¥BB”JJ­BBœJJµBB¥99”BB­99œ99¥11”11œ))Œ))”!!„{„Œs{„ks��{��s��k��c��Z��R��J��B��9scZµB9”µ­Þƽç������������������������������������������������������������������������������������������������������������������������,����P�P��ÿ�ÃĈQ¥ ™* ¸’#‡VÆ|õzv K S`1q!âˆ) ; S¥$F&3œÄÐñfJÉ)~¾àB A%8¦0ääJŠ¬ÄˆÉŠ Æ)­ø(1XRE$ %Dˆ Eb1ƒå¤ÊSVL@ ˆ‚CÈ+Í®\i2e‰l“!BT¥—§4iÂd¯Q üøñ™¢«“ÃL”€œâ³îÞ&)5‹JÀ©ª†±ò…«ÉÅJ˜ÂBH#:MÂhI1åi ,aX "’d•0Ÿ«üÊW”~ •„uÖIÅO™¯b‘GÍ¢9{¦ä(‡ 5 Æf“ÏÖ%«¸ÿ9ríŠàdlg<Må ížU¢Q‘â)éB{6‰Á' Ï0Fq. }¶D*øÁŠ‚Tá€Jd¡ÄJÒ‰!ÚÉ!Æab¤P…1±Ä5 Љ¹äU  !ËYèE3‡•ÂGW ÁLTᄉ8àAT‘–g?ÑÐ!°°² BDAdäÀdžL"KN(¡„ûÅ |€€)¦x8CIWTÑ ¬`!FIÁÆSÒÁ ’âfP^9òH?w…d„Q„&FJÒ„fd2DkE6Ó ,ˆâÆ ´0ÊO)¨°ÊV8qk‡$ÿRR'°(q\"J†1…eÁ#3@ê•^ÝÆBì%äTñÉÜØ†~ˆÑ +a8…‘y†hÁ£4 @ƒ(ñÓ^…4ÄDTT³Äa~ùcIKPÑÌ ¸à‚#¶öS¶ÝVÕ¹A<8E%æ¤DpDð²IWadJUÁžâ)ÌPßq=VA ¢F†¬�§€‹°G0Y,ÖD1¤€§‹šñS KxØÄZ¡í‘“¯D"î=+ö‰å0k ²G*©‡gBÂJ$z€ÔŒ.L01˜ÅäÀ¬nn(áQÁä÷SÏ‘¡HM¬à�[S$bǦàÿà+‡ò|Ôc„á‡)0a!{ì¡«Z¼ËÖNfXÑ„-Ï<ÚØW¨ÑLà»Þߨ†!Æb%ÙJ³bUˆà€P3\€À'¸ÃcøÌÖQæ¦ÐB™„Æ]é…ݬ$3ÇJãÌÎN$’F1Ï0AJa2Š€˜œ­TgCmþ U€@"!Äj¤ÄÓ¬µ€D 4Ð@{”䄲B+2&¢C|(WH„#Ø`ºÿ5!lYK憠.ah‚ ®AôlWƒ¸@;QøM~3` @‚†’¤&hÀZ ˜`CX+zv$¢fUÈB“ÿ”ຠ0lA h@ [£+nR‚ pÐL˜A-¸P ¢ 7¬4TI š ˆÿD1ŠÃ*ˆÆ‡ Xª c˜‚¼T¤,ÁKNÆÂÐ 8tÆv+�)ø° @l‡;sÀÃaRàúà€Ï0ƒ„pB* pC‚`ˆð¡'…ùŸ^Æ`.(á ^ZËQਥ!L ƒ—Ì�I_¤AXXFHá&ÒGÍ(F°€‡^�b ôaOtÕ„½ Á¨Bp¡é$;­yŶ©…1‚c¤TIÒ„7T�hA"^ùdô¢Íà„qêC†<è#ÑC1ÚTÿ\M9¦T„f ¬ 4€Ë!€�& ?QÉaDi–)@´œMyŠþ¢ò‰ª‚ l†# ”°D@.XÌ„¹–¶t…-š¨Qj.â’‹ðÆbŸÈ€ ¨ìmo/B\5’Ô,³à_Cp¨ñ„(ºa‹ôä7¨Ñ kþÙ<á y‚ L€}ágCk©jp˜0¬KœW +Zp%`RmE0è %´ à¯xñ¢™…§ Æ1@®P•dÌQ=Oi‚Ô&h(£FƒÐWÞȰ#&¼gˆ ŽS…Y訪ž®†5µ@U¸‚—`y >ÿð!(ÿ£A›špˆ½,PH (¦„5a„ d Ä £*üa Bž,e†>å`*Ibî‚•L&�Y¡v…5V©§RÁ_§êåæ&·yi ÀàF*T›ú‚EøP UØ„#l•7%9$IDذ`A€è"à Â^°ÇÚ18Áœ/™pÀ£ÞÈBAD“‹;²ành�J Dg„ðÃ!<0…XÁV(×64'ݤ TºÑ#ˆÐ�!@X A®@ˆd56«Âk9@Ö\` ޼ ’v…ì †G(À¸¼’ÞZA]A€A,@â’9áÿd†ÃI]Ö ©®Ÿ‡ƒZÐ`Ï„j -¸˜&ÕfˆYðI%!"ëÏüÀ‡AD�c± Ç| ²’¬y `F-Â6¶bì០A Ò¶6?p‰x£[ nÁ „¨H©ip²¢ýA~G™‚!^ᇞâJdœšJ¼rµ¬)Âyˆ…3œá0AcèV@¥ÀC¸BشͺBÒM`fp–‚NMN Æ¡¼‚A´G NÀÇ8Çí* "šœ!ž�Ô_8mŽÞ¨Ç‡ëí§ LåŠÄ¢ˆjAÒU÷6gP¢ôm8«ðÙ«X4… ¶dú€†W¼'#Oy ÿÁA@€…’x Ž�„ò°°2†5‰XøqðâÀU<¥g„«B™dH�Q¸~«�‘ØÒ„ ¤ÚŸ°('¡ pŠ·Á‚¬LDX(B `ˆDìå¬x„as‘Ô˜ë)®!b˜IC 1hh V1³Ÿå`} !ˆbà„.GS$ü~qTÁM€ëɇfpáNªÆ#zqŒD¬™ ‚Zr’ß}"*.EÍUˆT•D WxƒõL-´±/—ÊU~+¡ ÈpÆ.|1ÒfÁ á ÐŒ.ìå0ƒÇ1]=‚Á†+ó 0µñ|Lÿ(½Ò„U¨ÑK¨T ÚK±¶i°ävÁ fà Ið@êé‚P@SßÔ ä!z‚h€Ãå %M  8¡b±*a $t@áD.dN Aë䊠 Y ®�1&�n RºD‚RK2É $nÂá¡*PJòå|$a1àdX ‹åDNNS1I„À‰ k X`¤Z MX•€ÃäY°@>*`AÐ »&MÀ�Pô—bàqB°9NÐ1–£VPÍ€�Rñ .ÐdW€ ¿°šÐx‘.@%Œ%èÿá!¬Qca`BÑP94eVù‘VýÑVC@$WðPsTE6Mà³™£p‚aÈ !Â"t´ P$P ã7)*\d#3R#1€|y£#aóYÄŸ)Ð {Ñ;N€Uo ÂPÂ{p%z`ª¡\â%`â%à�_€�¤‚_Qƒð?–ƒ¬àCt ˆ€'„@]Ö…]†`3À¬ [%@¹V§¤¯Ðð @A@%V¢bP¿à S Ò °b-V\ˆõ?‡Qfü¤µ‰Ð[6 ¶`V`A1� ÐqË”Bÿ`:³t°ŽA ƒ´—² Y€LÀtW P�£P�:ÐOÑLüCO‘OÑ:òÒc?dù²/¼`.%€:·ñˆp΂�Ñâl€!XP ÂÐ&@$ºF1år1U}¡ÇA%¡ $Cxo–) g"@g1Óm­DõáðS ã{ppc»""Ó i N5RUj3,Ϧ5¸Ð5?6Ï6 žj£¥I¦f-jÑ% ¡S0 ½À>V4.0TdÐlmVg!†C ó¶8x´+`%a¬af0V@ Óñœ£ËÿÀ‘¡� ÖæMrW,»¢VSð’t#,@n:°ž ÁKÓf@…'ˆ’$r#‡jìDY ˆÒ<Ïp†j#=ÆP=)bà47†A U@%!®Æ_°("à.º�±E>S©S@7pèC�üã?ʲ(CA@×ö!’pÀÊã@6·VŒAà¬CxÍ´Ns"V"L¸؃B1@iÐD°&~G;9õ!]Id Cvsè!Y`¬ vcDqD‡à¸@gŠ  >V [6Ã^âVÓDBØÑ%6ft»2‹@<¶ç!%¡D† )ÿÀeZ2uV÷G“G LÐ w°½Ð pkÁgÛ!zWP–-*_àEÐ2µ¶p不“¦”~Ÿê4°!Y�±4KµÔ dK»d©”çÌ LX °� pA}s‘Ï�‡à"�—„�,¸I`U!”­@ݺUb§.´AMÀP °pÁ Å`KÍp ó4üÇ,ÎøMúÔ&V�0ê#^ zqÒjUQqJà’âÇŠYxŠHhNJð %Á U�%5"U<‚�é��õ¹O¤N€äV ¡ENÂrP‡P‡/}Z3@ŒÁ Šÿž â„0ÃÀâ– mšQf€$ !n€  ‡À(¨ƒÐ–Sà`53€Ä™†Kò �ÿ RQo£]…Zc� Ãð › ,p Ðd~Ð lÐ v‚(¢9@  ð?B° ˆ0•Äy�‚V:I3ðA¨€ g冠ü3BBDb$‰ ¡¬‡ B�oN & ‹Ôà•Ÿ™ UÁŽ Xð#.1•®S >ŒáQˆ ²ŒSÌ€Yš•:b[íxnRºAGñ1J0 Yð {‘6¦ Ö¡ñ?†€†@qœVpR @"0­9ÿàq4ã#õfr2w2]M`˜Ð“€!L€‚Bí²Ë„,å%Š]q¯%1EQKsôs¸¢Á`nP $À80­A $%1α’ZWz�mÁʲ+ž$¨àfП2iãdÿƒPdÞwo~p)·`FÈTŒµS`�{ Ðrئf§mƒ ìB ’#i<)Ï@%šÄË£3"7£–9F±X°£y† ¾KvL<¥à%s¤aJÐ ‡-åBå"%12®F¾ÄëcrÀ2$0TYlà66œ²P "n¢v1°JàÒq‹AC£Áaaÿã rÂ23Su¬` ]3_6І ›ðiŸànpmpš@§0æâ¸t#±äÆ�ãÅ`o8ïò‹B<¦0½ø8b@$xs•Óß)á9ž+�ÕV$”ºlà=­a+…!b®&Ÿr8sבR•“ ?‘Ÿ<Л5ƒX¦ÔAÁ¯ šÓqÑ“›ð ‡=K¡¤ i°Ê.¨{‘õŠb  It_€“’@‹?Q G€ b3š�$Y€$=c@ºsvÂ%{‘ I¤$s0Á�EuVƒP Ñ•zCd±’Å5o‘q¥Áÿ � Eå#eUÀ O±–D¦°0`÷�0vÍÀÏP'l` xºsÛqEWÐW:@ ç”$ 6: aTÓwh´ckQ|o®õF¦Þ£6z„.•@ÿÙ‘–J¬Âäǰ©VK}Ëä¬pàÒjIê9à ”ºÑ1ƒ§´:9°ÊZ®K²¤´ô ñ«ºD É×�¦ÀSÐ û'¡Á¯@åà~7ÁNº†!BÑ >M™âêBC€�‚줮Aó$CQà�80™+¥»ã}1OT5UTBY‡À2®="‚ ÿ{G8F“@N‘RÑ�UKD±3+ ,ðÉz!ɉÂ"]5µUë#릵„ð½nX² Äã`Ó¨w¨3 Aõc~Xo+´¬ rÐDr´„�îÓ¹ Ó 5Y¼ŒVñ‰?¡‰b3Ó‰‘[ÂEÒ‡ñªø ƒà�GÁ±l0 UãâÁ  @\&Á"U�Œ1#»[<šuœ•ŒXË(¹Ò •»Óøl\â•!ƒ°†° Ò •°!ªÛOæ² b-@¤ &4ÓZºE'Ð%]z²¾˜ðJ_êkâ¨s†w‰¢pÿú)rD à42ÁØ%;Æ•:Pâ¦b$� ¨²Ao!°‚2`ÁÒ¥†p=¾à ¿bzAœ7)´ŽÀ“Âò¦�J±b@šR‘WŽ‘ð 8@;Õv@r¤àh¶�0°”9/UÐlÌ� àˆ‰i&pÏ*’A!$R¢ r v¹½P”ëòÜ’é“�@$ã‡2¶ dä«(ÓlO@í# P°Ä&�dÍË—ê3 ù8@°YÓ05X™zâ%� ¼�â¶2lT ]jŠ Ê�ÌP˜|e  ©à ží¦ 6uÿ¼ùÑlS s0iÿò39–9±kt@cJ@$æ2Õ Nú Q_²ÍŽi*¿ÊÆl8À9h€ /<#€RàN аL£¬"Jà3C7vÞc`nh‚êFœ|ÉÐé¤`D¬E<á|<zŠrJào4Fx‰€—ÎÀ6°Ù£ÛSe mÖlk³°1ð½°Óðµ£I¹ƒÍ¬ñM?Aþw0�3ºtˆÑ`p = Äu ‡d Mp$±P3:0•:à@ú,"Ò¤ëC,€“KmôÑ¢7 p�Ð�#0x„GŽU `ó_ˆ+�DŒ 'pQÁÐ9 D4`™E�ã8 a ßqÊÏ °>¢†R¤P2CÇ^AR˜™Q¥É• ²ðñ@¨‰1„(Q‚£Š˜2XªƒHF•’š0x@ �(UÅÒ4땦¬^XœX˜0A d¿ž$ºbkŠ,¢¸ùЀC %N¦iĉ•*„”LÙ*F –2µ¦LñÐDÌ•+|R½P‚ÈU %=65ãd‰Q£cM@‘P%�XÍŠõêU¬Y°-Á*ô¹‚ÈÉiš|±bÒ„LäbH$DÇM¦4É¢c¬WÎ�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/close.gif������������������������������������������������������������0000644�0001750�0001750�00000000216�11462120062�016405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a� �ò�����¿¿¿ÿÿ�ÿÿÿ���������!þ$File written by Adobe Photoshop¨ 5.0�,����� ��3HÌú1¨ñÍÊosR–@ØZh¥b-ûlí–°-ãt|›:ÎëCü”€¤r¹L��;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/mini-filemgr.gif�����������������������������������������������������0000644�0001750�0001750�00000000152�11462120062�017656� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ò��¿¿¿ÿÿÿÙÙÙ������������,�������7ºÜ0F†½<É5 B(Ù#¨EÞ^jù ð°¶ ‹î·)†½Ù.Æ2ÕH¸ †r�x<G�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/images/stopsign.gif���������������������������������������������������������0000644�0001750�0001750�00000000403�11462120062�017144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a��ó��ÿÿÿÿïïÿÏÏÿ¿¿ÿ¯¯ÿúþÿ˜˜ÿÿppÿ``ÿPPÿ@@ÿ00ÿ ÿÿ��,�������¸°ÈYž½ÓM³ÏÜöW(‘覩ȶçËVŽÌÖ6Š;Èp<‹ƒðx8 >KcˆÈ�Pà <Ôß‚ °^�†‡‚a™Z�Â�, �ْΘÅîöbû~äË`8ww~{yqs€s„lt[Y[^Žgn[ Švw y[ |o€˜jXz“ƒO� ° ‘ ½} ‚92Ç#Ê.Í*Ð&É9Ô1Èר0�;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/stripchart1.tcl�������������������������������������������������������������0000755�0001750�0001750�00000027546�11462120062�016336� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish lappend auto_path /usr/local/blt/lib/blt3.0 package require BLT source scripts/demo.tcl # ---------------------------------------------------------------------- # EXAMPLE: simple driver for stripchart widget # ---------------------------------------------------------------------- # Michael J. McLennan # mmclennan@lucent.com # Bell Labs Innovations for Lucent Technologies # ====================================================================== # Copyright (c) 1996 Lucent Technologies # ====================================================================== option add *Axis.tickInterior yes option add *Axis.tickDefault 5 option add *Axis.Grid yes option add *Axis.GridColor lightblue option add *Legend.Hide yes #option add *Axis.GridDashes 0 option add *bufferElements no option add *bufferGraph yes option add *symbol triangle option add *symbol none option add *Axis.lineWidth 1 #option add *Axis*Rotate 90 option add *pixels 1.25m #option add *PlotPad 25 option add *Stripchart.width 6i option add *Stripchart.height 6i #option add *Smooth quadratic #option add *x.descending yes # ---------------------------------------------------------------------- # USAGE: random ?<max>? ?<min>? # # Returns a random number in the range <min> to <max>. # If <min> is not specified, the default is 0; if max is not # specified, the default is 1. # ---------------------------------------------------------------------- proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed 14823 # ---------------------------------------------------------------------- toplevel .addSource wm title .addSource "Add Source" wm group .addSource . wm withdraw .addSource wm protocol .addSource WM_DELETE_WINDOW {.addSource.controls.cancel invoke} frame .addSource.info pack .addSource.info -expand yes -fill both -padx 4 -pady 4 label .addSource.info.namel -text "Name:" entry .addSource.info.name label .addSource.info.maxl -text "Maximum:" entry .addSource.info.max label .addSource.info.minl -text "Minimum:" entry .addSource.info.min blt::table .addSource.info \ .addSource.info.namel 0,0 -anchor e \ .addSource.info.name 0,1 -fill x \ .addSource.info.maxl 1,0 -anchor e \ .addSource.info.max 1,1 -fill x \ .addSource.info.minl 2,0 -anchor e \ .addSource.info.min 2,1 -fill x frame .addSource.color pack .addSource.color -padx 8 -pady 4 frame .addSource.color.sample \ -width 30 -height 30 \ -borderwidth 2 -relief raised pack .addSource.color.sample -side top -fill both scale .addSource.color.r -label "Red" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.r -side left -fill y scale .addSource.color.g -label "Green" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.g -side left -fill y scale .addSource.color.b -label "Blue" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.b -side left -fill y proc source_color {args} { set r [expr round(2.55*[.addSource.color.r get])] set g [expr round(2.55*[.addSource.color.g get])] set b [expr round(2.55*[.addSource.color.b get])] set color [format "#%2.2x%2.2x%2.2x" $r $g $b] .addSource.color.sample configure -background $color } source_color frame .addSource.sep -borderwidth 1 -height 2 -relief sunken pack .addSource.sep -fill x -pady 4 frame .addSource.controls pack .addSource.controls -fill x -padx 4 -pady 4 button .addSource.controls.ok -text "OK" -command { wm withdraw .addSource set name [.addSource.info.name get] set color [.addSource.color.sample cget -background] set max [.addSource.info.max get] set min [.addSource.info.min get] if {[catch {source_create $name $color $min $max} err] != 0} { puts "error: $err" } } pack .addSource.controls.ok -side left -expand yes -padx 4 button .addSource.controls.cancel -text "Cancel" -command { wm withdraw .addSource } pack .addSource.controls.cancel -side left -expand yes -padx 4 set useAxes y blt::bitmap define pattern1 { {4 4} {01 02 04 08} } blt::bitmap define hobbes { {25 25} { 00 00 00 00 00 00 00 00 00 c0 03 00 78 e0 07 00 fc f8 07 00 cc 07 04 00 0c f0 0b 00 7c 1c 06 00 38 00 00 00 e0 03 10 00 e0 41 11 00 20 40 11 00 e0 07 10 00 e0 c1 17 00 10 e0 2f 00 20 e0 6f 00 18 e0 2f 00 20 c6 67 00 18 84 2b 00 20 08 64 00 70 f0 13 00 80 01 08 00 00 fe 07 00 00 00 00 00 00 00 00 00 } } proc source_create {name color min max} { global sources if {[info exists sources($name-controls)]} { error "source \"$name\" already exists" } if {$max <= $min} { error "bad range: $min - $max" } set unique 0 set win ".sources.nb.s[incr unique]" while {[winfo exists $win]} { set win ".sources.nb.s[incr unique]" } set xvname "xvector$unique" set yvname "yvector$unique" set wvname "wvector$unique" global $xvname $yvname $wvname blt::vector $xvname $yvname $wvname if {$xvname == "xvector1"} { $xvname append 0 } else { xvector1 variable thisVec $xvname append $thisVec(end) } $yvname append [random $max $min] $wvname append 0 catch {.sc element delete $name} set bg [blt::bgpattern create solid -opacity 50 -color $color] .sc element create $name \ -areabackground $bg \ -x $xvname \ -y $yvname \ -color $color if { $name != "default" } { .sc axis create $name \ -loose no \ -title $name \ -grid yes \ -rotate 0 \ -limitscolor $color \ -limitsformat "%4.4g" \ -titlecolor ${color} .sc element configure $name -mapy $name global useAxes lappend useAxes $name set count 0 if 0 { set yUse $useAxes set y2Use {} foreach axis $useAxes { if { $count & 1 } { lappend yUse $axis .sc axis configure $axis -rotate 90 } else { lappend y2Use $axis .sc axis configure $axis -rotate -90 } incr count } .sc y2axis use $y2Use .sc yaxis use $yUse } else { .sc y2axis use $useAxes } } set cwin .sources.choices.rb$unique radiobutton $cwin -text $name \ -variable choices -value $win -command " foreach w \[pack slaves .sources.nb\] { pack forget \$w } pack $win -fill both " pack $cwin -anchor w frame $win pack $win -fill x label $win.limsl -text "Limits:" entry $win.lims bind $win.lims <KeyPress-Return> " .sc yaxis configure -limits {%%g} " label $win.smoothl -text "Smooth:" frame $win.smooth radiobutton $win.smooth.linear -text "Linear" \ -variable smooth -value linear -command " .sc element configure $name -smooth linear " pack $win.smooth.linear -side left radiobutton $win.smooth.step -text "Step" \ -variable smooth -value step -command " .sc element configure $name -smooth step " pack $win.smooth.step -side left radiobutton $win.smooth.natural -text "Natural" \ -variable smooth -value natural -command " .sc element configure $name -smooth natural " pack $win.smooth.natural -side left label $win.ratel -text "Sampling Rate:" scale $win.rate -orient horizontal -from 10 -to 1000 blt::table $win \ $win.smoothl 0,0 -anchor e \ $win.smooth 0,1 -fill x -padx 4 \ $win.limsl 1,0 -anchor e \ $win.lims 1,1 -fill x -padx 4 \ $win.ratel 2,0 -anchor e \ $win.rate 2,1 -fill x -padx 2 if {$unique != 1} { button $win.del -text "Delete" -command [list source_delete $name] pack $win.del -anchor w blt::table $win $win.del 3,1 -anchor e -padx 4 -pady 4 } $win.rate set 200 catch {$win.smooth.[.sc element cget $name -smooth] invoke} mesg set sources($name-choice) $cwin set sources($name-controls) $win set sources($name-stream) [after 10 [list source_event $name 10]] set sources($name-x) $xvname set sources($name-y) $yvname set sources($name-w) $wvname set sources($name-max) $max set sources($name-min) $min set sources($name-steady) [random $max $min] $cwin invoke } proc source_delete {name} { global sources after cancel $sources($name-stream) destroy $sources($name-choice) destroy $sources($name-controls) unset sources($name-controls) set first [lindex [pack slaves .sources.choices] 0] $first invoke } proc source_event {name delay} { global sources set xv $sources($name-x) set yv $sources($name-y) set wv $sources($name-w) global $xv $yv $wv $xv variable x set x(++end) [expr $x(end) + 0.001 * $delay] $yv variable y if {[random] > 0.97} { set y(++end) [random $sources($name-max) $sources($name-min)] } else { set y(++end) [expr $y(end)+0.1*($sources($name-steady)-$y(end))] } set val [random] if {$val > 0.95} { $wv append 2 } elseif {$val > 0.8} { $wv append 1 } else { $wv append 0 } #$wv notify now if { [$xv length] > 1000 } { $xv delete 0 $yv delete 0 $wv delete 0 } update set win $sources($name-controls) set delay [$win.rate get] set sources($name-stream) [after $delay [list source_event $name $delay]] } # ---------------------------------------------------------------------- frame .mbar -borderwidth 2 -relief raised pack .mbar -fill x menubutton .mbar.main -text "Main" -menu .mbar.main.m pack .mbar.main -side left -padx 4 menu .mbar.main.m .mbar.main.m add command -label "Add Source..." -command { set x [expr [winfo rootx .]+50] set y [expr [winfo rooty .]+50] wm geometry .addSource +$x+$y wm deiconify .addSource } .mbar.main.m add separator .mbar.main.m add command -label "Quit" -command exit menubutton .mbar.prefs -text "Preferences" -menu .mbar.prefs.m pack .mbar.prefs -side left -padx 4 menu .mbar.prefs.m .mbar.prefs.m add cascade -label "Warning Symbol" -menu .mbar.prefs.m.wm menu .mbar.prefs.m.wm .mbar.prefs.m add cascade -label "Error Symbol" -menu .mbar.prefs.m.em menu .mbar.prefs.m.em foreach sym {square circle diamond plus cross triangle} { .mbar.prefs.m.wm add radiobutton -label $sym \ -variable warningsym -value $sym \ -command {.sc pen configure "warning" -symbol $warningsym} .mbar.prefs.m.em add radiobutton -label $sym \ -variable errorsym -value $sym \ -command {.sc pen configure "error" -symbol $errorsym} } catch {.mbar.prefs.m.wm invoke "circle"} catch {.mbar.prefs.m.em invoke "cross"} # ---------------------------------------------------------------------- blt::stripchart .sc -title "" -stackaxes yes -invert no \ -bufferelements no pack .sc -expand yes -fill both .sc xaxis configure -title "Time (s)" -autorange 20.0 -shiftby 0.5 .sc yaxis configure -title "Samples" frame .sources frame .sources.nb -borderwidth 2 -relief sunken label .sources.title -text "Sources:" frame .sources.choices -borderwidth 2 -relief groove if 0 { pack .sources -fill x -padx 10 -pady 4 pack .sources.nb -side right -expand yes -fill both -padx 4 -pady 4 pack .sources.title -side top -anchor w -padx 4 pack .sources.choices -expand yes -fill both -padx 4 -pady 4 } source_create default red 0 10 source_create temp blue3 0 10 source_create pressure green3 0 200 source_create volume orange3 0 1020 source_create power yellow3 0 0.01999 source_create work magenta3 0 10 Blt_ZoomStack .sc .sc axis bind all <Enter> { %W axis activate [%W axis get current] } .sc axis bind all <Leave> { %W axis deactivate [%W axis get current] } .sc axis bind Y <ButtonPress-1> { set axis [%W axis get current] %W axis configure $axis -logscale yes } .sc axis bind Y <ButtonPress-3> { set axis [%W axis get current] %W axis configure $axis -logscale no } after 5000 { puts stderr "printing stripchart" .sc postscript output sc.ps } ����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hiertable3.tcl��������������������������������������������������������������0000755�0001750�0001750�00000010116�11462120062�016075� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set saved [pwd] #blt::bltdebug 100 image create picture bgTexture -file ./images/rain.gif set imageList {} foreach f [glob ./images/mini-*.gif] { lappend imageList [image create picture -file $f] } #option add *Hiertable.Tile bgTexture option add *Hiertable.ScrollTile yes #option add *Hiertable.Column.background grey90 option add *Hiertable.titleShadow { grey80 } option add *Hiertable.titleFont {*-helvetica-bold-r-*-*-11-*-*-*-*-*-*-*} hiertable .h -width 0\ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -selectmode multiple \ -hideroot yes #.h configure -icons "" -activeicons "" .h column configure treeView -text "View" .h column insert 0 mtime atime gid .h column insert end nlink mode type ctime uid ino size dev .h column configure uid -background \#eaeaff -style text .h column configure mtime -hide no -bg \#ffeaea -style text .h column configure size gid nlink uid ino dev -justify right -style text .h column configure treeView -hide no -edit no -style text scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } blt::table configure . c1 r1 -resize none image create picture fileImage -file images/stopsign.gif proc DoFind { dir parent } { global count set saved [pwd] cd $dir foreach f [lsort [glob -nocomplain *]] { set node [tree0 insert $parent -label $f] if { [catch { file stat $f info }] == 0 } { if 0 { if { $info(type) == "file" } { set info(type) @fileImage } else { set info(type) "" } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(size) [FormatSize $info(size)] set info(mode) [FormatMode $info(mode)] eval tree0 set $node [array get info] } incr count if { [file isdirectory $f] } { DoFind $f $node } } cd $saved } proc Find { dir } { global count set count 0 catch { file stat $dir info } incr count tree create tree0 tree0 label root [file tail $dir] eval tree0 set root [array get info] DoFind $dir root puts "$count entries" } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath ..] Find $top focus .h .h configure -tree tree0 -separator / set nodes [.h find -glob -name *.c] eval .h entry configure $nodes -foreground green4 set nodes [.h find -glob -name *.h] eval .h entry configure $nodes -foreground cyan4 set nodes [.h find -glob -name *.o] eval .h entry configure $nodes -foreground red4 cd $saved .h column bind all <ButtonRelease-3> { %W configure -flat no } proc SortColumn { column } { set old [.h sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.h sort cget -decreasing] set decreasing [expr !$decreasing] } .h sort configure -decreasing $decreasing -column $column .h configure -flat yes .h sort auto yes blt::busy hold .h update blt::busy release .h } foreach column [.h column names] { .h column configure $column -command [list SortColumn $column] } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu1.tcl������������������������������������������������������������������0000755�0001750�0001750�00000021655�11462120062�015255� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set icon2 [image create picture -file images/blt98.gif] set icon [image create picture -data $imgData] set bg white set image "" option add *ComboEntry.takeFocus 1 if { [file exists ../library] } { set blt_library ../library } # -postcommand {.e.m configure -width [winfo width .e] ; update} \ set myIcon "" blt::comboentry .e \ -image $image \ -textvariable myText1 \ -iconvariable myIcon1 \ -textwidth 0 \ -menu .e.m \ -menuanchor se \ -exportselection yes \ -xscrollcommand { .s set } \ -closebutton yes \ -command "puts {button pressed}" # -bg $bg blt::combomenu .e.m \ -background white \ -activebackground skyblue4 \ -activeforeground white \ -restrictwidth min \ -height 200 \ -checkbuttonoutlinecolor "" \ -checkbuttonfillcolor "" \ -disabledbackground \#f0f0f0 \ -textvariable myText1 \ -iconvariable myIcon1 \ -yscrollbar .e.m.ybar \ -xscrollbar .e.m.xbar blt::tk::scrollbar .e.m.xbar blt::tk::scrollbar .e.m.ybar set onOff 1 set wwho "" foreach {item type} { Undo command X1 checkbutton Y1 radiobutton Redo checkbutton Cut command Copy checkbutton X2 checkbutton Y2 radiobutton Paste checkbutton "Edit Options" separator "Select All" checkbutton X3 checkbutton Y3 radiobutton Find cascade Replace checkbutton } { set char [string range $item 0 0] .e.m add \ -type $type \ -text $item \ -accel "Ctrl+$char" \ -underline 0 \ -tag "$type [string tolower $char]" \ -icon $icon \ -variable $item \ -value $item \ } set X1 1 set Redo 1 .e.m item configure Find -menu .e.m.m #-state disabled .e.m item configure x -state disabled .e.m item configure radiobutton -variable wwho .e.m item configure Y1 -state disabled puts stderr "config=[.e.m item configure Y3]" set wwho Y1 blt::combomenu .e.m.m \ -bg $bg \ -textvariable myText1 \ -iconvariable myIcon1 \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -height { 0 500 } \ -yscrollbar .e.m.m.ybar \ -xscrollbar .e.m.m.xbar \ -font "Arial 8" blt::tk::scrollbar .e.m.m.xbar blt::tk::scrollbar .e.m.m.ybar set onOff 0 foreach item { Undo X1 Y1 Redo Cut Copy X2 Y2 Paste "Select All" X3 Y3 Find Replace } { set char [string range $item 0 0] .e.m.m add \ -type checkbutton \ -text $item \ -accel "Ctrl+$char" \ -accel "" \ -underline 0 \ -tag [string tolower $char] \ -icon $icon \ -variable $item \ -value $item \ } set wwho2 "" .e.m.m item configure Undo -type command .e.m.m item configure Cut -type command .e.m.m item configure Find -type cascade -menu .e.m.m.m #-state disabled .e.m.m item configure Y3 -type command -image $icon2 .e.m.m item configure Undo -type command .e.m.m item configure Paste -type separator .e.m.m item configure x -state disabled .e.m.m item configure y -type radiobutton -variable wwho2 set labels { Aarhus Aaron Ababa aback abaft abandon abandoned abandoning abandonment abandons abase abased abasement abasements abases abash abashed abashes abashing abasing abate abated abatement abatements abater abates abating Abba abbe abbey abbeys abbot abbots Abbott abbreviate abbreviated abbreviates abbreviating abbreviation abbreviations Abby abdomen abdomens abdominal abduct abducted abduction abductions abductor abductors abducts Abe abed Abel Abelian Abelson Aberdeen Abernathy aberrant aberration aberrations abet abets abetted abetter abetting abeyance abhor abhorred abhorrent abhorrer abhorring abhors abide abided abides abiding Abidjan Abigail Abilene abilities ability abject abjection abjections abjectly abjectness abjure abjured abjures abjuring ablate ablated ablates ablating ablation ablative ablaze able abler ablest ably Abner abnormal abnormalities abnormality abnormally Abo aboard abode abodes abolish abolished abolisher abolishers abolishes abolishing abolishment abolishments abolition abolitionist abolitionists abominable abominate aboriginal aborigine aborigines abort aborted aborting abortion abortions abortive abortively aborts Abos abound abounded abounding abounds about above aboveboard aboveground abovementioned abrade abraded abrades abrading Abraham Abram Abrams Abramson abrasion abrasions abrasive abreaction abreactions abreast abridge abridged abridges abridging abridgment abroad abrogate abrogated abrogates abrogating abrupt abruptly abruptness abscess abscessed abscesses abscissa abscissas abscond absconded absconding absconds absence absences absent absented absentee absenteeism absentees absentia absenting absently absentminded absents absinthe absolute absolutely absoluteness absolutes absolution absolve absolved absolves absolving absorb absorbed absorbency absorbent absorber absorbing absorbs absorption absorptions absorptive abstain abstained abstainer abstaining abstains abstention abstentions abstinence abstract abstracted abstracting abstraction abstractionism abstractionist abstractions abstractly abstractness abstractor abstractors abstracts abstruse abstruseness absurd absurdities absurdity absurdly Abu abundance abundant abundantly abuse abused abuses abusing abusive abut abutment abuts abutted abutter abutters abutting abysmal abysmally abyss abysses Abyssinia Abyssinian Abyssinians acacia academia academic academically academics academies academy Acadia Acapulco accede acceded accedes accelerate accelerated accelerates accelerating acceleration accelerations accelerator accelerators accelerometer accelerometers accent accented accenting accents accentual accentuate accentuated accentuates accentuating accentuation accept acceptability acceptable acceptably acceptance acceptances accepted accepter accepters accepting acceptor acceptors accepts access accessed accesses accessibility accessible accessibly accessing accession accessions accessories accessors accessory accident accidental accidentally accidently accidents acclaim acclaimed acclaiming acclaims acclamation acclimate acclimated acclimates acclimating acclimatization acclimatized accolade accolades accommodate accommodated accommodates accommodating accommodation accommodations accompanied accompanies accompaniment accompaniments accompanist accompanists accompany accompanying accomplice accomplices accomplish accomplished accomplisher accomplishers accomplishes accomplishing accomplishment accomplishments accord accordance accorded accorder accorders according accordingly accordion accordions accords accost accosted accosting accosts account accountability accountable accountably accountancy accountant accountants accounted accounting accounts Accra accredit accreditation accreditations accredited accretion accretions accrue accrued accrues accruing acculturate acculturated acculturates acculturating acculturation accumulate accumulated accumulates accumulating accumulation accumulations accumulator accumulators accuracies accuracy accurate accurately accurateness accursed accusal accusation accusations accusative accuse accused accuser accuses accusing accusingly accustom accustomed accustoming accustoms ace aces acetate acetone acetylene Achaean Achaeans ache ached aches achievable achieve achieved achievement achievements achiever achievers achieves achieving Achilles aching acid acidic acidities acidity acidly acids acidulous Ackerman Ackley acknowledge acknowledgeable acknowledged acknowledgement acknowledgements acknowledger acknowledgers acknowledges acknowledging acknowledgment acknowledgments acme acne acolyte acolytes acorn acorns acoustic acoustical acoustically acoustician acoustics acquaint acquaintance acquaintances acquainted acquainting acquaints acquiesce acquiesced acquiescence acquiescent acquiesces acquiescing acquirable acquire acquired acquires acquiring acquisition acquisitions } blt::combomenu .e.m.m.m \ -bg $bg \ -textvariable myText1 \ -iconvariable myIcon1 \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -width { 0 400 } \ -height { 0 500 } \ -yscrollbar .e.m.m.m.ybar \ -xscrollbar .e.m.m.m.xbar .e.m.m.m listadd $labels \ -icon $icon blt::tk::scrollbar .e.m.m.m.xbar blt::tk::scrollbar .e.m.m.m.ybar blt::tk::scrollbar .s -orient vertical -command { .e xview } bind ComboEntry <3> { grab release [grab current] } blt::table . \ 0,0 .e -fill x -anchor n #blt::table configure . r0 -resize none #blt::table configure . r1 -resize both �����������������������������������������������������������������������������������./saods9/blt3.0.1/demos/container.tcl���������������������������������������������������������������0000755�0001750�0001750�00000000630�11462120062�016035� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT namespace import blt::* #set cmd "xterm" set cmd "xclock" set cmd "xterm" blt::container .c -width 800 -height 400 eval bgexec myVar $cmd & pack .c -fill both -expand yes .c configure -relief raised -bd 2 button .b -text "Quit" -command exit pack .b update #.c configure -relief raised -bd 2 -name "Mozilla Firefox" #.c configure -relief raised -bd 2 -command $cmd ��������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/htext.txt�������������������������������������������������������������������0000644�0001750�0001750�00000052404�11462120062�015247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� This is a (for lack of a better name) hypertext widget. This widget combines text and other Tk widgets in the same window. It is sort of a cross between a read-only text widget and the pack command. Any widget can be attached to the hypertext window by the %% set this $htext(widget) blt::tile::label $this.lab -text "append " -relief sunken \ -font *-Courier-Bold-R-Normal-*-12-120-* $this append $this.lab %% command. For example, %% message $this.msg -relief sunken -bd 2 -aspect 10000 -font \ *-Courier-Medium-R-Normal-*-12-* -text {set w $htext(widget) blt::tile::label $w.face -bitmap @bitmaps/face.xbm \ -relief sunken -borderwidth 2 $w append $w.face -padx 2 -pady 0.25i} $this append $this.msg \ -fill both %% added this %% global tk_library blt::tile::label $this.face \ -bitmap @bitmaps/face.xbm \ -relief sunken -borderwidth 2 $this append $this.face -padx 2 -pady 0.25i %%. There can be many types of widgets in the same document. For example, this is a simple %% blt::tile::button $this.but -bg pink -text { button } \ -command { puts stderr { a stupid message } } $this append $this.but %%. If you click on the button, it prints a stupid message. Any Tk widget can be used, including %% set whichTile 0 proc ChangeTile { w } { global whichTile if { $whichTile } { $w configure -bg $bg2 } else { $w configure -bg $bg1 } } blt::tile::checkbutton $this.ckbut -bg lightblue -text { check buttons } \ -variable whichTile -command "ChangeTile $this" $this append $this.ckbut -justify top %%, %% blt::tile::radiobutton $this.rdbut -bg mediumseagreen -text { radio buttons } \ -command { puts stderr { radio button pressed } } $this append $this.rdbut -justify bottom %%, and scales %% # -sliderforeground scale $this.sc -showvalue true \ -length 100 \ -foreground powderblue \ -sliderlength 10 \ -orient horizontal $this append $this.sc %%. Widget trees can be also be included. The following example is *borrowed* from the widget demo. It is a couple of frames surrounding a listbox, a message, and a button widget. %% set w $this.frame frame $w message $w.msg -font *times-medium-r-normal--*-12-120-* -aspect 300 \ -text "A listbox containing the 50 states is displayed below, along with a scrollbar. You can scan the list either using the scrollbar or by dragging in the listbox window with button 3 pressed. Click the \"OK\" button when you've seen enough." -bg lightsteelblue -relief sunken frame $w.frame -borderwidth 10 pack append $w.frame \ [scrollbar $w.frame.scroll -relief sunken \ -command "$w.frame.list yview"] {right expand filly frame w} \ [listbox $w.frame.list -yscroll "$w.frame.scroll set" -relief sunken] \ {left expand filly frame e} $w.frame.list insert 0 Alabama Alaska Arizona Arkansas California \ Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois \ Indiana Iowa Kansas Kentucky Louisiana Maine Maryland \ Massachusetts Michigan Minnesota Mississippi Missouri \ Montana Nebraska Nevada "New Hampshire" "New Jersey" "New Mexico" \ "New York" "North Carolina" "North Dakota" \ Ohio Oklahoma Oregon Pennsylvania "Rhode Island" \ "South Carolina" "South Dakota" \ Tennessee Texas Utah Vermont Virginia Washington \ "West Virginia" Wisconsin Wyoming button $w.ok -text OK -command "puts stderr $w; destroy $w" pack append $w $w.msg {top fill} $w.frame {top expand fill} \ $w.ok {bottom fill} $w config -bg lightsteelblue -relief sunken $this append $w -pady 0.25i %% You can add you own home-grown widgets. Here's the graph widget. Beside it is the "color" demo. Moving the scales, adjusts the background color of the graph. %% # # Simple script to change colors of a window. # global xlabel ylabel red green blue graph set red 255 set green 215 set blue 0 option add *Scale.sliderForeground "#cdb79e" option add *Scale.activeForeground "#ffe4c4" set w $this.colorFrame frame $w scale $w.red -command "color red" -label "Red Intensity" \ -from 0 -to 255 -orient horizontal -bg "#ffaeb9" -length 250 scale $w.green -command "color green" -label "Green Intensity" \ -from 0 -to 255 -orient horizontal -bg "#43cd80" scale $w.blue -command "color blue" -label "Blue Intensity" \ -from 0 -to 255 -orient horizontal -bg "#7ec0ee" $w.blue set $blue $w.green set $green $w.red set $red pack append $w $w.red {top expand fill} pack append $w $w.green {top expand fill} pack append $w $w.blue {top expand fill} proc color {which intensity} { global red green blue graph xlabel ylabel set $which $intensity set rgb [format #%02x%02x%02x $red $green $blue] $graph config -bg $rgb $xlabel config -bg $rgb $ylabel config -bg $rgb } $this append $w %% %% proc makeplot { widget } { blt::graph $widget set X { 2.00000e-01 4.00000e-01 6.00000e-01 8.00000e-01 1.00000e+00 1.20000e+00 1.40000e+00 1.60000e+00 1.80000e+00 2.00000e+00 2.20000e+00 2.40000e+00 2.60000e+00 2.80000e+00 3.00000e+00 3.20000e+00 3.40000e+00 3.60000e+00 3.80000e+00 4.00000e+00 4.20000e+00 4.40000e+00 4.60000e+00 4.80000e+00 5.00000e+00 } $widget element create Y1 -x $X -y { 1.14471e+01 2.09373e+01 2.84608e+01 3.40080e+01 3.75691e+01 3.91345e+01 3.92706e+01 3.93474e+01 3.94242e+01 3.95010e+01 3.95778e+01 3.96545e+01 3.97313e+01 3.98081e+01 3.98849e+01 3.99617e+01 4.00384e+01 4.01152e+01 4.01920e+01 4.02688e+01 4.03455e+01 4.04223e+01 4.04990e+01 4.05758e+01 4.06526e+01 } -symbol circle -label VGS=2.0 -color blue4 -fill blue $widget element create Y2 -x $X -y { 2.61825e+01 5.04696e+01 7.28517e+01 9.33192e+01 1.11863e+02 1.28473e+02 1.43140e+02 1.55854e+02 1.66606e+02 1.75386e+02 1.82185e+02 1.86994e+02 1.89802e+02 1.90683e+02 1.91047e+02 1.91411e+02 1.91775e+02 1.92139e+02 1.92503e+02 1.92867e+02 1.93231e+02 1.93595e+02 1.93958e+02 1.94322e+02 1.94686e+02 } -symbol diamond -label VGS=3.5 -color green4 -fill green $widget element create Y3 -x $X -y { 4.07008e+01 7.95658e+01 1.16585e+02 1.51750e+02 1.85051e+02 2.16479e+02 2.46024e+02 2.73676e+02 2.99427e+02 3.23267e+02 3.45187e+02 3.65177e+02 3.83228e+02 3.99331e+02 4.13476e+02 4.25655e+02 4.35856e+02 4.44073e+02 4.50294e+02 4.54512e+02 4.56716e+02 4.57596e+02 4.58448e+02 4.59299e+02 4.60151e+02 } -symbol triangle -label VGS=5.0 -color red4 -fill red } option add *graph.title "Plot Title" option add *graph.xTitle "X Axis Label" option add *graph.yTitle "Y Axis Label" #option add *graph.legendMapped false option add *graph.elemPixels 8 option add *graph.relief ridge option add *graph.borderWidth 2 set graph $this.graph set xlabel $this.xlab set ylabel $this.ylab makeplot $graph $this append $graph -padx 0.25i -pady 0.25i %% If you click on any button in the graph, you will get the coordinate values at the pointer location. The current coordinate values are %% label $xlabel -text { ??? ??? } -relief sunken label $ylabel -text { ??? ??? } -relief sunken bind $graph <ButtonPress> {labelxy [ %W invtransform %x %y ]} proc labelxy { values } { global xlabel ylabel scan $values "%e %e" x y $xlabel config -text $x $ylabel config -text $y } $this append $this.xlab -width 100 -fill x %% and %% $this append $this.ylab -width 100 -fill x %%. There are four global variables automatically created when a hypertext file is read. They are: %% button $this.l1 -text " \$htext(widget) " \ -command "puts $this" -bg orange $this append $this.l1 -width 200 -pady 4 %%the pathname of the hypertext widget. %% button $this.l2 -text " \$htext(file) " \ -command "puts $htext(file)" -bg orange $this append $this.l2 -width 200 -pady 4 %%the file being read. %% button $this.l3 -text " \$htext(line) " \ -command "puts $htext(line)" -bg orange $this append $this.l3 -width 200 -pady 4 %%the current line number. %% button $this.l4 -text " \$htext(index) " \ -command "puts $htext(index)" -bg orange $this append $this.l4 -width 200 -pady 4 %%the current index in the text. Click on any button and the current value is printed on standard output. The hypertext widget works with plain text too. If you don't want to read it, click on the %% button $this.goto -text button -fg purple -bg white \ -command "global endOfText; $this gotoline \$endOfText" $this append $this.goto %% to jump to the end of the plain text. ------------------------------------------------------ [This is a pre-release version of BLT. It's basically the latest snapshot of BLT, as it moves towards a full release. What this means is that the documentation and demos still need work. Let me know about any configuration/compiler/installation goofs so I make sure they're fixed for the next release.] This is version 2.4 of the BLT library. It's an extension to the Tcl/Tk toolkit. You simply compile and link with the Tcl/Tk libraries. It does not require the Tcl or Tk source files. BLT is available from ftp.tcltk.com in the "pub/blt" directory. The URL is ftp://ftp.tcltk.com/pub/blt/BLT2.4.tar.gz This release has been compiled and tested with versions: Tcl 7.5 / Tk 4.1 Tcl 7.6 / Tk 4.2 Tcl/Tk 8.0 Tcl/Tk 8.1a2 What is BLT? BLT is an extension to Tk. It adds plotting widgets (X-Y graph, barchart, stripchart), a powerful geometry manager, a new canvas item, and several new commands to Tk. Plotting widgets: graph, barchart, stripchart BLT has X-Y graph, barchart, and stripchart widgets that are both easy to use and customize. All the widgets work with BLT vector data objects, which makes it easy to manage data. Hierarchical list box: hierbox Displays a general ordered tree which may be built on-the-fly or all at once. Tab set: tabset Can be used either as a tab notebook or simple tabset. Multi-tiered and/or scrolled tabsets are available. Notebook pages can be torn-off into separate windows and later put back. Geometry Manager: table A table-based geometry manager. Lets you specify widget layouts by row and column positions in the table. Unlike the packer or grid, you can finely control and constrain window sizes. Vector Data Object: vector Lets you manage a vector of floating point values in a high-level fashion. Vectors inter-operate seamlessly with the plotting widgets. The graphs will automatically redraw themselves when the vector data changes. Vector's components can be managed through a Tcl array variable, a Tcl command, or the using its own C API. Background Program Execution: bgexec Like Tcl's "exec ... &", but collects the output, error, and status of the detached UNIX subprocesses. Sets a Tcl variable upon completion. Busy Command: busy For preventing user-interactions when the application is busy. Manages an invisible "busy" window which prevents further user interactions (keyboard, mouse, button, etc.). Also you can provide a busy cursor that temporarily overrides those of the Tk widgets. New Canvas Item: eps An new item is added to the Tk canvas for handling encapsulated PostScript. It lets you embed an EPS file into the canvas displaying either an EPS preview image found in the file, or a Tk image that you provide. When you print the canvas the EPS item will automatically include the EPS file, translating and scaling the PostScript. For example, you could use "eps" items to tile several PostScript pages into single page. The "eps" item can also be used as a replacement for "image" canvas items. Unlike "image" canvas items, the image of an eps item can be printed and scaled arbitrarily. Drag & Drop Facility: drag&drop Adds drag-n-drop capabilities to Tk. It uses "send"-style communication between drag-drop sources and targets. The result is a much more powerful drag-and-drop mechanism than is available with OpenLook or Motif. Bitmap Command: bitmap Lets you read and write bitmaps from Tcl. You can define bitmaps from ordinary text strings. Bitmaps can also be scaled and rotated. For example, you can create a button with rotated text by defining a bitmap from a text string and rotating it. You can then use the bitmap in the button widget. Miscellaneous Commands: winop Basic window operations. You can raise, lower, map, or, unmap windows. Other operations let you move the pointer or take photo image snapshots of Tk widgets. bltdebug Lets you trace the execution of Tcl commands and procedures. Prints out each Tcl command before it's executed. watch Lets you specify Tcl procedures to be run before and/or after every Tcl command. May be used for logging, tracing, profiling, or debugging or Tcl code. spline Computes a spline fitting a set of data points (x and y vectors) and produces a vector of the interpolated images (y-coordinates) at a given set of x-coordinates. htext A simple hypertext widget. Allows text and Tk widgets to be combined in a scroll-able text window. Any Tk widget can be embedded and used to form hyper-links. Other options allow for selections and text searches. What's new in 2.4? 1. "eps" canvas item. An encapsulated PostScript canvas item lets you embed an EPS file into the canvas. The "eps" item displays either a EPS preview image found in the file, or a Tk image that you provide. 2. "hierbox" widget. Hierarchical listbox widget. Displays a general ordered tree which may be built on-the-fly or all at once. 3. "tabset" widget. Can be used either as a tab notebook or simple tabset. Tabs can be arranged in a variety of ways: multi-tiered, scrolled, and attached to any of the four sides. Tab labels can contain both images and text (text can be arbitrarily rotated). Notebook pages can be torn-off into separate windows and replaced later. 4. Changes to vectors. New features: o Vector expressions. The vector now has an "expr" operation that lets you perform math (including math library functions) on vectors. There are several new functions (such as "max", "min", "mean" "median", "q1", "q3", "prod", "sum", "adev", "sdev", "skew", ...) vector expr { sin(x)^2 + cos(x)^2 } y expr { log(x) * $value } o New syntax to create and destroy vectors: vector create x vector destroy x The old syntax for creating vectors still works. vector x o Vectors are *not* automatically deleted when their Tcl variable is unset anymore. This means that you can temporarily map vectors to variables and use them as you would an ordinary Tcl array (kind of like "upvar"). proc AddValue { vecName value } { $vecName variable x set x(++end) $value } There's an "-watchunset" flag to restore the old behavior if you need it. vector create x -watchunset yes o Vectors still automatically create Tcl variables by default. I'd like to change this, but it silently breaks lots of code, so it will stay. Bug fixes: o Vector reallocation failed when shrinking the vector. o Vector "destroy" callback made after vector was already freed. 5. Changes to Graph, Barchart, Stripchart widgets. New features: o Drop shadows for text (titles, markers, etc). Drop shadows improve contrast when displaying text over a background with similar color intensities. o Postscript "-preview" option to generate a EPS PostScript preview image that can be read and displayed by the EPS canvas item. o New "-topvariable", "-bottomvariable", "-leftvariable", and "-rightvariable" options. They specify variables to contain the current margin sizes. These variables are updated whenever the graph is redrawn. o New "-aspect" option. Let's you maintain a particular aspect ratio for the the graph. o Image markers can now be stretched and zoomed like bitmap markers. o Bind operation for legend entries, markers, and elements. Much thanks to Julian Loaring <bigj@bigj.demon.co.uk> for the suggestions. o New "-xor" option for line markers, lets you draw the line by rubberbanded by XOR-ing without requiring the graph to be redrawn. This can be used, for example, to select regions like in zooming. Thanks to Johannes Zellner (joze@krisal.physik.uni-karlsruhe.de) for the suggestion. Bug fixes: o Closest line (point) broken when using pens styles. o Marker elastic coordinates were wrong. o PostScript bounding box included the border of the page. o Bad PostScript generated for barchart symbols with stipples. o Wrong dimensions computed with postscript " -maxpect" option. o Text markers fixed. Thanks to De Clarke for the bug report and fix. o Renamed axis configuration from "-range" to "-autorange" to match the documentation. Thanks to Brian Smith for the correction. o Fixed polygon marker pick routine. o Fixed active tab labels overlapping the selected tab. What's incompatible with releases prior to BLT 2.4? 1. Vector names must start with a letter and contain letters, digits, or underscores. Namespace Issues: Vector names are still global. If Tcl provides an API, vectors may in the future be created on a per-namespace basis. Right now, there's no mechanism for detecting when a namespace has been destroyed. Which is why you can't currently prefix a vector name with a namespace qualifier. [Ok, there is... Thanks to Michael McLennan for pointing this out to me. So maybe soon there will be vectors on a per namespace basis.] 2. The "-mapped" options throughout the graph have been replaced by the "-hide" option. The many usages of the word "map" was getting confusing. # No longer works. .graph legend configure -mapped no # Instead use this. .graph legend configure -hide yes How to compile and test BLT? See the file "INSTALL" for instructions. When will the so-called "official" BLT work with Windows? It currently compiles and runs with MS VC++ and EGCS 1.1 under Windows 95/NT (loadable binary versions will be forthcoming). Everything pretty much works: graphs, bgexec, busy, drag&drop etc. When will...? In general, I can't answer the "When will" questions, mostly out of embarrassment. My estimates of when new features and releases will occur usually turn out to be way way off. What does BLT stand for? Whatever you want it to. --gah %% global endOfText set endOfText [expr $htext(line)-1 ] global updateInterval count barchart global Red Green Blue set updateInterval 200 set count 0 set Red bb set Green 00 set Blue 33 option add *barchart.title "Bar Chart" option add *barchart.x.title "X" option add *barchart.y.title "Y" option add *barchart.y2.title "Y" option add *barchart.Axis.subTicks 0 option add *barchart.x.stepSize 0 option add *barchart.x.Ticks 0 option add *barchart.legend.hide yes option add *barchart.Axis.Font *-Courier-Bold-R-Normal-*-8-80-* option add *barchart.y2.hide yes set barchart $this.barchart blt::barchart $barchart -bd 2 -relief raised -bg $bg2 $barchart y2axis use y $this append $barchart -fill both -padx 10 -pady 10 -relwidth 0.8 proc AnimateBarchart { } { global updateInterval global barchart count Red Blue Green if { [info commands $barchart] != $barchart } { return } incr count if { $count > 100 } { $barchart element delete [lindex [$barchart element show] end] } set color [format "%x" [expr $count%16]] set Green ${color}${color} $barchart element create $count -data { $count sin($count*0.1)} \ -fg #${Red}${Green}${Blue} -bg brown after $updateInterval AnimateBarchart } AnimateBarchart %% Press %% button $this.quit -command { exit } -text {Quit} -bg pink $this append $this.quit %% to remove the window. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabnotebook2.tcl������������������������������������������������������������0000755�0001750�0001750�00000002533�11462120062�016450� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl image create picture bgTile -file ./images/smblue_rock.gif image create picture label1 -file ./images/mini-book1.gif image create picture label2 -file ./images/mini-book2.gif image create picture testImage -file ./images/txtrflag.gif scrollbar .s -command { .t view } -orient horizontal blt::tabset .t \ -outerborderwidth 2 \ -outerrelief sunken \ -tabwidth same \ -scrollcommand { .s set } \ -slant right \ -textside right \ -tiers 2 label .t.l -image testImage set attributes { graph1 "Graph \#1" red .t.graph1 graph2 "Graph \#2" green .t.graph2 graph3 "Graph \#3" cyan .t.graph3 graph5 "Graph \#5" yellow .t.graph5 graph6 one orange .t.l } foreach { entry label color window } $attributes { .t insert end -text $label -fill both } foreach label { there bunky another test of a widget } { set id [.t insert end -text $label] } set img [image create picture -file ./images/blt98.gif] .t tab configure $id -image label2 blt::table . \ .t 0,0 -fill both \ .s 1,0 -fill x blt::table configure . r1 -resize none set index 0 foreach file { graph1 graph2 graph3 graph5 } { namespace eval $file { set graph [blt::graph .t.$file] source scripts/$file.tcl .t tab configure $index -window $graph incr index } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bgexec3.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000017311�11462120062�015377� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl bitmap define blt.0 {{40 40} { 00 00 00 00 00 00 fc 07 00 00 00 04 08 00 00 00 04 04 00 00 00 e4 03 00 00 00 64 fe 07 00 00 64 02 04 00 00 e4 03 04 00 00 64 7e 02 00 00 64 1a 02 00 00 e4 1b 01 00 00 04 1a 01 00 00 04 1a 01 00 00 fc 1b 02 00 00 0c 1a 02 00 00 0c 02 04 00 00 0c 02 f4 03 80 ed fe 07 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.1 {{40 40} { 00 00 00 00 00 00 fc 07 00 00 00 04 08 00 00 00 04 04 00 00 00 e4 ff 0f 00 00 64 06 08 00 00 64 06 08 00 00 e4 ff 04 00 00 64 36 04 00 00 64 36 02 00 00 e4 37 02 00 00 04 34 02 00 00 04 34 04 00 00 fc 35 04 00 00 0c 04 08 00 00 0c 04 08 00 00 0c fc ef 03 80 ed 01 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.2 {{40 40} { 00 00 00 00 00 00 fc 0f 00 00 00 04 10 00 00 00 04 10 00 00 00 e4 fb 3f 00 00 64 0e 20 00 00 64 0e 20 00 00 e4 fb 13 00 00 64 ce 10 00 00 64 ce 08 00 00 e4 cb 08 00 00 04 c8 08 00 00 04 c8 10 00 00 fc cf 10 00 00 0c 08 20 00 00 0c 08 20 00 00 0c f8 bf 03 80 ed 03 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.3 {{40 40} { 00 00 00 00 00 00 fc 0f 00 00 00 04 f0 ff 00 00 04 00 80 00 00 e4 03 80 00 00 64 d6 4f 00 00 64 16 43 00 00 e4 13 23 00 00 64 16 23 00 00 64 16 23 00 00 e4 13 43 00 00 04 70 43 00 00 04 00 80 00 00 fc 0f 80 00 00 0c f0 ff 00 00 0c 00 00 00 00 0c f8 ff 03 80 ed 07 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } bitmap define blt.4 {{40 40} { 00 00 00 00 00 00 fc ff ff 03 00 04 00 00 02 00 04 00 00 02 00 e4 33 3f 01 00 64 36 0c 01 00 64 36 8c 00 00 e4 33 8c 00 00 64 36 8c 00 00 64 36 0c 01 00 e4 f3 0d 01 00 04 00 00 02 00 04 00 00 02 00 fc ff ff 03 00 0c 00 00 00 00 0c 00 00 00 00 0c f8 ff 03 80 ed 07 00 04 e0 0c 00 20 09 10 0c 00 00 12 10 0c 00 00 10 30 00 00 00 19 d0 03 00 00 14 b0 fe ff ff 1b 50 55 55 55 0d e8 aa aa aa 16 e4 ff ff ff 2f f4 ff ff ff 27 d8 ae aa bd 2d 6c 5f d5 67 1b bc f3 7f d0 36 f8 01 10 cc 1f e0 45 8e 92 0f b0 32 41 43 0b d0 cf 3c 7c 0d b0 aa c2 ab 0a 60 55 55 55 05 c0 ff ab aa 03 00 00 fe ff 00 00 00 00 00 00} } set program tclsh if { [info exists tcl_platform ] } { puts stderr $tcl_platform(platform) if { $tcl_platform(platform) == "windows" } { set shells [glob C:/Program\ Files/Tcl/bin/tclsh8*.exe ] set program [lindex $shells 0] } } if { ![file executable $program] } { # error "Can't execute $program" } set command [list $program scripts/bgtest.tcl] set animate(index) -1 set animate(interval) 200 #set animate(colors) { #ff8813 #ffaa13 #ffcc13 #ffff13 #ffcc13 #ffaa13 #ff8813 } bitmap define blt.5 [bitmap data blt.3] bitmap define blt.6 [bitmap data blt.2] bitmap define blt.7 [bitmap data blt.1] proc Animate {} { global animate if { [info commands .logo] != ".logo" } { set animate(index) 0 return } if { $animate(index) >= 0 } { .logo configure -bitmap blt.$animate(index) incr animate(index) if { $animate(index) >= 7 } { set animate(index) 0 } after $animate(interval) Animate } } proc InsertText { string tag } { .text insert end "$tag: " "" $string $tag set textlen [expr int([.text index end])] scan [.vscroll get] "%s %s %s %s" total window first last if { $textlen > $total } { .text yview [expr $textlen-$window] } update idletasks update } proc DisplayOutput { data } { InsertText "$data\n" stdout } proc DisplayErrors { data } { InsertText "$data\n" stderr } set length 80 option add *text.yScrollCommand { .vscroll set } option add *text.relief sunken option add *text.width 20 option add *text.height 10 option add *text.height 10 option add *text.borderWidth 2 option add *vscroll.command { .text yview } option add *vscroll.minSlider 4p option add *stop.command { set results {} } option add *stop.text { stop } option add *logo.relief sunken option add *logo.padX 4 option add *title.text "Catching stdout and stderr" option add *title.font -*-Helvetica-Bold-R-*-*-14-*-*-*-*-*-*-* set visual [winfo screenvisual .] if { [string match *color $visual] } { option add *text.background white option add *text.foreground blue option add *stop.background yellow option add *stop.activeBackground yellow2 option add *stop.foreground navyblue option add *start.activeBackground green2 option add *start.background green option add *start.foreground navyblue option add *logo.background beige option add *logo.foreground brown } proc Start { command } { global results animate .text delete 1.0 end if { $animate(index) < 0 } { set results {} set animate(index) 0 eval "blt::ptyexec -variable results -error barney -output fred -killsignal SIGINT \ -onoutput DisplayOutput -onerror DisplayErrors -linebuffered no \ $command &" Animate } } proc Stop { } { global results animate set results {} set animate(index) -1 } # Create widgets text .text .text tag configure stdout -font { Courier-Bold 14 } -foreground green2 .text tag configure stderr -font { Courier 14 } -foreground red2 scrollbar .vscroll button .start -text "Start" -command [list Start $command] button .stop -text "Stop" -command Stop label .logo -bitmap blt.0 label .title # Layout widgets in table blt::table . \ .title 0,0 -columnspan 4 \ .text 1,0 -columnspan 3 \ .vscroll 1,3 -fill y \ .logo 2,0 -anchor w -padx 10 -reqheight .6i -pady 4 \ .start 2,1 \ .stop 2,2 set buttonWidth 1i blt::table configure . c1 c2 -width 1i blt::table configure . c3 r0 r2 -resize none blt::table configure . .start .stop -reqwidth $buttonWidth -anchor e blt::table configure . .title .text -fill both wm min . 0 0 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/drawerset2.tcl��������������������������������������������������������������0000644�0001750�0001750�00000002146�11462120062�016136� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::graph .g -bg \#CCCCFF -height 800 set w [blt::drawerset .g -side top -sashthickness 20] blt::barchart .g.b -bg \#FFCCCC -height 300 blt::barchart .g.b2 -bg \#CCFFCC -height 300 $w add -window .g.b -fill x -resize both $w add -window .g.b2 -fill y $w open pane0 set pressed 0 bind PanesetSash <Enter> { if { !$pressed } { %W activate } } bind PanesetSash <Leave> { if { !$pressed } { %W deactivate } } bind PanesetSash <KeyPress-Left> { %W move -10 0 } bind PanesetSash <KeyPress-Right> { %W move 10 0 } bind PanesetSash <KeyPress-Up> { %W move 0 -10 } bind PanesetSash <KeyPress-Down> { %W move 0 10 } bind PanesetSash <Shift-KeyPress-Left> { %W move -100 0 } bind PanesetSash <Shift-KeyPress-Right> { %W move 100 0 } bind PanesetSash <Shift-KeyPress-Up> { %W move 0 -100 } bind PanesetSash <Shift-KeyPress-Down> { %W move 0 100 } bind PanesetSash <ButtonPress-1> { set pressed 1 %W anchor %X %Y } bind PanesetSash <B1-Motion> { %W mark %X %Y } bind PanesetSash <ButtonRelease-1> { set pressed 0 %W set %X %Y } blt::table . \ 0,0 .g -fill both ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/htext1.tcl������������������������������������������������������������������0000755�0001750�0001750�00000007165�11462120062�015302� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT #source scripts/demo.tcl set visual [winfo screenvisual .] if { $visual == "staticgray" || $visual == "grayscale" } { set activeBg black set normalBg white set bitmapFg black set bitmapBg white option add *top.background white } else { option add *htext.foreground navyblue if { $tk_version >= 4.0 } { set file1 ./images/clouds.gif set file2 ./images/chalk.gif image create picture texture1 -file $file1 image create picture texture2 -file $file2 set bg1 [blt::bgpattern create tile -image texture1] set bg2 [blt::bgpattern create tile -image texture2] option add *htext.foreground black option add *htext.background $bg1 option add *htext.selectBackground gold1 } } option add *highlightThickness 0 proc Blt_FindPattern { htext } { toplevel .search wm title .search "Text search" label .search.label1 -text "Enter Pattern" entry .search.entry -relief sunken label .search.clear -text "Clear" \ -command ".search.entry delete 0 end" label .search.cancel -text "Cancel" \ -command "destroy .search; focus $htext" label .search.search -text "Search" -command "Blt_Search&Move $htext" bind .search.entry <Return> "Blt_Search&Move $htext" blt::table .search \ .search.label1 0,0 -padx 4 \ .search.entry 0,1 -cspan 2 -pady 4 -padx 4 -reqwidth 3i \ .search.search 3,0 -reqwidth .75i -anchor w -padx 10 -pady 5 \ .search.clear 3,1 -reqwidth .75i -anchor center -padx 10 -pady 5 \ .search.cancel 3,2 -reqwidth .75i -anchor e -padx 10 -pady 5 focus .search.entry bind .search <Visibility> { raise .search } } set last 0 set lastPattern {} proc Blt_Search&Move { h } { global last global lastPattern set pattern [.search.entry get] if { [string compare $pattern $lastPattern] != 0 } { set last 0 set lastPattern $pattern } if { $pattern == "" } { return } set indices [$h search $pattern $last end] if { $indices == "" } { bell } else { set first [lindex $indices 0] set last [lindex $indices 1] $h selection range $first $last $h gotoline $first incr last } } # Create horizonatal and vertical scrollbars scrollbar .vscroll -command { .htext yview } -orient vertical scrollbar .hscroll -command { .htext xview } -orient horizontal # Create the hypertext widget blt::htext .htext -file ./htext.txt \ -yscrollcommand { .vscroll set } \ -xscrollcommand { .hscroll set } \ -yscrollunits 10m -xscrollunits .25i \ -height 6i blt::table . \ .htext 0,0 -fill both \ .vscroll 0,1 -fill y \ .hscroll 1,0 -fill x blt::table configure . r1 c1 -resize none bind .htext <B1-Motion> { %W select to @%x,%y } bind .htext <1> { %W select from @%x,%y %W select to @%x,%y } bind .htext <Shift-1> { %W select word @%x,%y } bind .htext <Meta-1> { %W select line @%x,%y } bind .htext <Control-1> { puts stderr [%W select index @%x,%y] } bind .htext <B2-Motion> { %W scan dragto @%x,%y } bind .htext <2> { %W scan mark @%x,%y } bind .htext <3> { %W select adjust @%x,%y } bind .htext <Control-p> { set line [%W gotoline] if { $line == 0 } { bell } else { set line [expr $line-1] %W gotoline $line.0 } } bind .htext <Control-n> { set line [%W gotoline] incr line if { [%W gotoline $line.0] != $line } { bell } } bind .htext <Control-v> { %W yview [expr [%W yview]+10] } bind .htext <Meta-v> { %W yview [expr [%W yview]-10] } bind .htext <Alt-v> { %W yview [expr [%W yview]-10] } bind .htext <Any-q> { exit 0 } bind .htext <Control-s> { Blt_FindPattern %W } wm min . 0 0 focus .htext �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scrollset1.tcl��������������������������������������������������������������0000644�0001750�0001750�00000000442�11462120062�016144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::scrollset .ss \ -xscrollbar .ss.xsbar \ -yscrollbar .ss.ysbar \ -window .ss.g blt::tk::scrollbar .ss.ysbar -orient vertical blt::tk::scrollbar .ss.xsbar -orient horizontal blt::graph .ss.g pack .ss -fill both -expand yes ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph6.tcl������������������������������������������������������������������0000755�0001750�0001750�00000405167�11462120062�015260� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set tcl_precision 15 set graph .graph option add *Graph.Width 10i option add *Graph.leftMargin .75i option add *Graph.Height 6i option add *Graph.plotBackground black option add *LineMarker.color white option add *LineMarker.Dashes 5 option add *TextMarker.foreground white option add *TextMarker.Background {} option add *Graph.x.hide yes option add *Graph.x.title "" option add *Graph.y.rotate 90 #option add *Graph.y.stepSize 2.0 option add *Graph.title "" option add *graph.Title "Example s27" option add *graph.x.hide no option add *graph.topMargin 0 option add *graph.bottomMargin 0 option add *x.Title Time option add *y.Title Signals option add *Pixels 1 option add *Reduce 0.5 option add *bufferElements no option add *Element.color green4 option add *Element.ScaleSymbols true option add *Element.Color grey70 option add *Element.Symbol none option add *Element.LineWidth 1 #option add *Element.Smooth natural option add *Element.Smooth catrom option add *activeLine.LineWidth 2 option add *activeLine.Color white option add *activeLine.Color green1 #option add *Legend.Hide yes option add *Legend.Position right option add *Legend.Relief flat option add *Legend.activeRelief sunken option add *Legend.borderWidth 2 option add *Legend.Font -*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-* option add *Grid.hide no option add *Grid.dashes "1 5" #option add *foreground white option add *zoomOutline.outline yellow blt::graph .graph blt::vector x -variable "" for { set i 1 } { $i <= 39 } { incr i } { blt::vector create v${i} -variable "" } x set { 0 1e-10 2e-10 3e-10 4e-10 5e-10 6e-10 7e-10 8e-10 9e-10 1e-09 1.1e-09 1.2e-09 1.3e-09 1.4e-09 1.5e-09 1.6e-09 1.7e-09 1.8e-09 1.9e-09 2e-09 2.1e-09 2.2e-09 2.3e-09 2.4e-09 2.5e-09 2.6e-09 2.7e-09 2.8e-09 2.9e-09 3e-09 3.1e-09 3.2e-09 3.3e-09 3.4e-09 3.5e-09 3.6e-09 3.7e-09 3.8e-09 3.9e-09 4e-09 4.1e-09 4.2e-09 4.3e-09 4.4e-09 4.5e-09 4.6e-09 4.7e-09 4.8e-09 4.9e-09 5e-09 5.1e-09 5.2e-09 5.3e-09 5.4e-09 5.5e-09 5.6e-09 5.7e-09 5.8e-09 5.9e-09 6e-09 6.1e-09 6.2e-09 6.3e-09 6.4e-09 6.5e-09 6.6e-09 6.7e-09 6.8e-09 6.9e-09 7e-09 7.1e-09 7.2e-09 7.3e-09 7.4e-09 7.5e-09 7.6e-09 7.7e-09 7.8e-09 7.9e-09 8e-09 8.1e-09 8.2e-09 8.3e-09 8.4e-09 8.5e-09 8.6e-09 8.7e-09 8.8e-09 8.9e-09 9e-09 9.1e-09 9.2e-09 9.3e-09 9.4e-09 9.5e-09 9.6e-09 9.7e-09 9.8e-09 9.9e-09 1e-08 1.01e-08 1.02e-08 1.03e-08 1.04e-08 1.05e-08 1.06e-08 1.07e-08 1.08e-08 1.09e-08 1.1e-08 1.11e-08 1.12e-08 1.13e-08 1.14e-08 1.15e-08 1.16e-08 1.17e-08 1.18e-08 1.19e-08 1.2e-08 1.21e-08 1.22e-08 1.23e-08 1.24e-08 1.25e-08 1.26e-08 1.27e-08 1.28e-08 1.29e-08 1.3e-08 1.31e-08 1.32e-08 1.33e-08 1.34e-08 1.35e-08 1.36e-08 1.37e-08 1.38e-08 1.39e-08 1.4e-08 1.41e-08 1.42e-08 1.43e-08 1.44e-08 1.45e-08 1.46e-08 1.47e-08 1.48e-08 1.49e-08 1.5e-08 1.51e-08 1.52e-08 1.53e-08 1.54e-08 1.55e-08 1.56e-08 1.57e-08 1.58e-08 1.59e-08 1.6e-08 1.61e-08 1.62e-08 1.63e-08 1.64e-08 1.65e-08 1.66e-08 1.67e-08 1.68e-08 1.69e-08 1.7e-08 1.71e-08 1.72e-08 1.73e-08 1.74e-08 1.75e-08 1.76e-08 1.77e-08 1.78e-08 1.79e-08 1.8e-08 1.81e-08 1.82e-08 1.83e-08 1.84e-08 1.85e-08 1.86e-08 1.87e-08 1.88e-08 1.89e-08 1.9e-08 1.91e-08 1.92e-08 1.93e-08 1.94e-08 1.95e-08 1.96e-08 1.97e-08 1.98e-08 1.99e-08 2e-08 2.01e-08 2.02e-08 2.03e-08 2.04e-08 2.05e-08 2.06e-08 2.07e-08 2.08e-08 2.09e-08 2.1e-08 2.11e-08 2.12e-08 2.13e-08 2.14e-08 2.15e-08 2.16e-08 2.17e-08 2.18e-08 2.19e-08 2.2e-08 2.21e-08 2.22e-08 2.23e-08 2.24e-08 2.25e-08 2.26e-08 2.27e-08 2.28e-08 2.29e-08 2.3e-08 2.31e-08 2.32e-08 2.33e-08 2.34e-08 2.35e-08 2.36e-08 2.37e-08 2.38e-08 2.39e-08 2.4e-08 2.41e-08 2.42e-08 2.43e-08 2.44e-08 2.45e-08 2.46e-08 2.47e-08 2.48e-08 2.49e-08 2.5e-08 2.51e-08 2.52e-08 2.53e-08 2.54e-08 2.55e-08 2.56e-08 2.57e-08 2.58e-08 2.59e-08 2.6e-08 2.61e-08 2.62e-08 2.63e-08 2.64e-08 2.65e-08 2.66e-08 2.67e-08 2.68e-08 2.69e-08 2.7e-08 2.71e-08 2.72e-08 2.73e-08 2.74e-08 2.75e-08 2.76e-08 2.77e-08 2.78e-08 2.79e-08 2.8e-08 2.81e-08 2.82e-08 2.83e-08 2.84e-08 2.85e-08 2.86e-08 2.87e-08 2.88e-08 2.89e-08 2.9e-08 2.91e-08 2.92e-08 2.93e-08 2.94e-08 2.95e-08 2.96e-08 2.97e-08 2.98e-08 2.99e-08 3e-08 3.01e-08 3.02e-08 3.03e-08 3.04e-08 3.05e-08 3.06e-08 3.07e-08 3.08e-08 3.09e-08 3.1e-08 3.11e-08 3.12e-08 3.13e-08 3.14e-08 3.15e-08 3.16e-08 3.17e-08 3.18e-08 3.19e-08 3.2e-08 3.21e-08 3.22e-08 3.23e-08 3.24e-08 3.25e-08 3.26e-08 3.27e-08 3.28e-08 3.29e-08 3.3e-08 3.31e-08 3.32e-08 3.33e-08 3.34e-08 3.35e-08 3.36e-08 3.37e-08 3.38e-08 3.39e-08 3.4e-08 3.41e-08 3.42e-08 3.43e-08 3.44e-08 3.45e-08 3.46e-08 3.47e-08 3.48e-08 3.49e-08 3.5e-08 3.51e-08 3.52e-08 3.53e-08 3.54e-08 3.55e-08 3.56e-08 3.57e-08 3.58e-08 3.59e-08 3.6e-08 } wm min . 0 0 v1 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } .graph element create V1 -x x -y v1 v2 set { 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 5.32907e-15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } .graph element create V2 -x x -y v2 v3 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } .graph element create V3 -x x -y v3 v4 set { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } .graph element create V4 -x x -y v4 v5 set { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } .graph element create V5 -x x -y v5 v6 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } .graph element create V6 -x x -y v6 v7 set { 5 5.16904 4.84159 3.34542 0.317102 0.103304 0.0275721 0.0221534 0.017689 0.0142639 0.0113974 0.00918238 0.00742541 0.00616602 0.00481195 0.00397049 -0.0659889 -0.025671 0.165495 0.986891 3.05229 4.55511 4.91611 4.98192 4.99428 4.99833 4.99095 4.97295 4.95493 4.93428 4.90723 4.94799 4.98584 4.99566 4.99813 4.99907 4.99947 4.99965 4.99976 4.99984 4.99989 4.99992 4.99994 4.99996 4.99998 5.00002 5.00006 5.00002 4.99996 4.99994 4.99999 5.00003 5.00002 5 4.99997 4.99997 4.99997 4.99997 4.99997 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.16575 4.69986 2.43862 0.0230224 0.035229 -0.0210607 -0.0292766 -0.0172693 -0.00271479 -0.000912251 -0.000349106 -0.000116866 -4.24733e-05 -1.39536e-05 -3.01179e-05 -0.0657192 -0.0204835 0.183378 1.07181 3.118 4.46472 4.84158 4.94795 4.98173 4.99236 4.99762 5.01939 5.0433 5.05332 5.04959 5.03955 5.02851 5.02052 5.01422 5.00965 5.00631 5.00405 5.00248 5.00083 5.00012 5.00209 5.00387 5.00347 4.99917 4.99213 4.98411 4.97521 4.96332 4.94601 4.9304 4.94633 4.97936 4.99264 4.99685 4.99857 4.99925 4.99954 4.9997 4.99973 4.9997 4.99973 4.99979 4.99983 4.99986 4.99988 4.9999 4.9999 4.99992 4.99993 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5.14242 4.76101 3.16003 0.299374 0.0645506 -0.000498424 -2.45108e-05 -2.27986e-05 -5.24401e-05 -4.9884e-05 -4.92491e-05 -2.93354e-05 -3.21402e-05 -2.11851e-05 -3.37925e-05 -0.0657892 -0.020563 0.182582 1.06058 3.12484 4.46552 4.84146 4.95102 4.98556 4.99472 4.99806 4.99909 4.99955 4.99976 4.99994 4.99992 5.00029 4.99967 4.99849 4.99736 4.99884 5.00099 5.00377 5.00215 4.99994 4.99893 4.99788 4.99862 5.00055 5.00134 5.00127 5.00073 5.00039 5.00018 5.00006 5.00001 4.99985 5.00026 5.00018 5.00003 4.99981 4.99985 4.99987 4.99985 4.99982 4.99982 4.99982 4.99983 4.99985 4.99987 4.99989 4.99991 4.99992 4.99994 4.99995 4.99995 4.99994 4.99994 4.99996 4.99999 5.00002 5.00008 5.00009 5.00006 5.00001 5 4.99999 4.99998 4.99997 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } .graph element create V7 -x x -y v7 v8 set { 5 5.03758 5.04711 4.96911 4.20882 3.96295 4.01117 4.15521 4.2967 4.42274 4.5295 4.6176 4.69014 4.74831 4.7966 4.83537 4.80526 4.787 4.79295 4.88588 5.08978 5.15615 5.10778 5.07718 5.06652 5.08225 4.9744 4.52977 3.77452 2.69426 1.15294 0.245509 0.0981544 0.0567527 0.0367487 0.0252578 0.0180599 0.0133837 0.0101497 0.0078616 0.00620186 0.00499056 0.0041027 0.00344223 0.00295808 0.00260089 0.00229887 0.00200817 0.00176397 0.00160116 0.00147381 0.00134645 0.00125029 0.00116043 0.00107371 0.00101981 0.000965921 0.000912028 0.000858135 0.000804242 0.000761669 0.00072672 0.000691771 0.000656823 0.000621874 0.000588722 0.00057041 0.000552098 0.000533785 0.000515473 0.000497162 0.00047885 0.000460537 0.000442226 0.000423914 0.000405601 0.000388399 0.000378694 0.000368989 0.000359284 0.00034958 0.000339875 0.00033017 0.000320465 0.00031076 0.000301055 0.00029135 0.000282207 0.000276247 0.000270287 0.000264327 0.000258367 0.000252407 0.000246447 0.000240487 0.000234527 0.000228567 0.000222607 0.000217086 0.000213696 0.000210307 0.000206918 0.000203528 0.000200139 0.00019675 0.00019336 0.000189971 0.000186582 0.000183192 0.000179803 0.000176414 0.000173025 0.000169635 0.000166246 0.000162857 0.000159467 0.000156078 0.000152689 0.000149299 0.00014591 0.00014255 0.0316021 0.163272 0.348732 0.603651 0.35745 0.135965 0.0707354 0.0314595 0.0201047 0.00994945 0.00389601 0.00138839 0.00060778 0.000329648 0.000492396 -0.0732035 -0.0844077 -0.0789062 -0.0390837 0.0197559 0.0183094 -0.00180099 -0.0189565 -0.0424144 -0.0735904 -0.0892423 0.285039 1.13702 2.10809 2.95826 3.60164 4.0435 4.35771 4.57254 4.71769 4.81329 4.87534 4.91487 4.94264 4.97375 5.01526 5.06517 5.10154 5.06259 4.89005 4.5787 4.12226 3.46151 2.49023 1.2586 0.32725 0.116753 0.0701865 0.0455509 0.0286914 0.0178176 0.0117599 0.00902715 0.00760583 0.00637745 0.00543811 0.00439377 0.00352448 0.0030151 0.00285771 0.002465 0.00203114 0.00173004 0.0014839 0.00125177 0.00105327 0.000894905 0.000766372 0.000658894 0.000569105 0.000492114 0.000427938 0.000370217 0.000314758 0.000266569 0.000233726 0.000209048 0.000191957 0.000177169 0.000166604 0.000161 0.000157314 0.000143828 0.000130342 0.000116857 0.000103371 8.98855e-05 7.63998e-05 6.29141e-05 5.76583e-05 5.30027e-05 4.8347e-05 4.36913e-05 3.90357e-05 3.438e-05 2.97243e-05 2.72507e-05 2.59083e-05 2.45659e-05 2.32235e-05 2.18811e-05 2.05387e-05 1.91963e-05 1.78539e-05 1.65115e-05 1.51691e-05 1.38267e-05 1.24843e-05 1.11419e-05 9.79954e-06 8.51574e-06 7.69807e-06 6.8804e-06 6.06273e-06 5.24506e-06 0.0287318 0.0317111 -0.0320087 -0.103609 0.0369639 0.0121128 0.00961197 0.00934971 0.00820853 0.00699769 0.00607002 0.00535541 0.00476552 0.00427601 0.00376357 -0.073012 -0.0866964 -0.0809538 -0.038005 0.0277001 0.0188906 0.00614597 0.00373629 0.00489787 0.0146573 0.0191052 0.0151708 0.0124224 0.0105859 0.00879272 0.00729464 0.0070047 0.00449575 -0.00626652 -0.0252417 -0.0147287 0.022538 0.0822905 0.0947372 0.0657516 0.0445506 0.0316753 0.0220971 0.0158101 0.0140971 0.0161498 0.0139876 0.0122447 0.0106994 0.009397 0.00822236 0.00686509 0.00797431 0.00751269 0.00671173 0.00595243 0.00524633 0.00459528 0.00401688 0.00350109 0.00303954 0.00260569 0.00222792 0.00191033 0.00163917 0.00140949 0.00121464 0.0010471 0.000900638 0.000768847 0.000645236 0.000524807 0.000460275 0.000442237 0.000446775 0.000397026 0.000301585 0.000228994 0.000190894 0.000166569 0.000152261 0.000137953 0.000123644 0.000109336 9.50281e-05 8.56557e-05 7.78437e-05 7.00318e-05 6.22198e-05 5.44079e-05 4.87539e-05 4.57761e-05 4.27982e-05 3.98203e-05 3.68425e-05 3.38646e-05 3.08868e-05 2.79089e-05 2.4931e-05 2.19532e-05 1.89753e-05 1.75244e-05 1.64095e-05 1.52946e-05 1.41797e-05 1.30648e-05 1.19499e-05 1.0835e-05 9.72011e-06 8.60521e-06 7.4903e-06 6.5117e-06 6.10334e-06 5.69497e-06 5.2866e-06 4.87824e-06 4.46987e-06 4.06151e-06 3.65314e-06 3.24477e-06 } .graph element create V8 -x x -y v8 v9 set { 1.86175 1.99708 2.07867 2.01211 2.43309 3.27194 3.63896 3.90426 4.11074 4.27932 4.41496 4.52543 4.61491 4.68862 4.7479 4.79666 4.72895 4.68886 4.70354 4.81353 5.01568 5.14184 5.10482 5.07362 5.05143 5.03638 5.02323 5.01465 5.00853 5.00383 4.99985 5.00454 5.00652 5.00546 5.00411 5.003 5.00214 5.00151 5.00106 5.00073 5.0005 5.00034 5.00023 5.00015 5.0001 5.00005 5 5.00001 5.00005 5.00005 5.00003 5 4.99998 4.99996 4.99994 4.99995 4.99997 4.99998 5 5.00001 5.00002 5.00002 5.00003 5.00003 5.00003 5.00003 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.17392 4.94828 3.78491 1.52079 0.608874 0.244031 0.127087 0.0552995 0.0361032 0.0169025 0.006364 0.00217624 0.000921391 0.000457305 0.000786754 -0.120016 -0.148054 -0.15898 -0.0801463 0.16463 0.174017 0.0799249 0.0318788 0.0129696 0.00483397 0.0025677 0.0042079 0.00350003 0.00178404 -8.72902e-05 -0.00128497 -0.00142213 -0.00130018 -0.00106874 -0.000789207 -0.000824335 -0.00104518 -0.00136799 -0.004366 -0.0102621 -0.0109254 -0.00649259 -0.00194842 0.00029793 0.00148673 0.00221085 0.00228291 0.00185261 0.00139687 0.00148183 0.00562266 0.00844119 0.00754627 0.00657396 0.00591212 0.00539269 0.0049282 0.00448417 0.0040572 0.00363719 0.00320392 0.00279607 0.00243938 0.00211505 0.00182302 0.00156254 0.0013341 0.00113834 0.000971865 0.00082776 0.000706193 0.000602499 0.000515059 0.000441401 0.00037897 0.000325459 0.00028083 0.000242096 0.000207274 0.000176444 0.000150372 0.000126407 0.000103373 9.05522e-05 8.53555e-05 8.63685e-05 9.02593e-05 8.37346e-05 7.72099e-05 7.06852e-05 6.41605e-05 5.76358e-05 5.11112e-05 4.45865e-05 4.08176e-05 3.72497e-05 3.36818e-05 3.01138e-05 2.65459e-05 2.2978e-05 1.94101e-05 1.76154e-05 1.67399e-05 1.58645e-05 1.4989e-05 1.41136e-05 1.32381e-05 1.23626e-05 1.14872e-05 1.06117e-05 9.73629e-06 8.86083e-06 7.98538e-06 7.10993e-06 6.23447e-06 5.44363e-06 5.32578e-06 5.20792e-06 5.09007e-06 4.97222e-06 0.0784323 0.0474527 -0.0764232 -0.151146 0.0615785 0.0144489 0.00974161 0.00947176 0.00849005 0.00728201 0.00630581 0.00554032 0.00487809 0.00441504 0.00384139 -0.118943 -0.149894 -0.161173 -0.0825299 0.171686 0.176912 0.0816085 0.0335236 0.013791 0.0056976 0.00238833 0.00105348 0.000526199 0.00025969 0.000396026 0.000837835 0.00170131 0.00196699 -0.000553314 -0.0061621 -0.0111895 -0.0142698 -0.0124608 -0.00795847 -0.00467822 -0.0043058 -0.00874449 -0.0118584 -0.00871386 -0.00377892 1.95244e-05 0.00218952 0.00325486 0.00386497 0.00422837 0.00446883 0.00447065 0.00486647 0.00547838 0.00565398 0.00559092 0.00538752 0.00507015 0.00466305 0.00420756 0.00373465 0.00328404 0.00287059 0.00250057 0.00216124 0.00184861 0.00156815 0.00134624 0.00117857 0.00103412 0.0008948 0.000761012 0.000619853 0.000462614 0.000319965 0.000287666 0.000356415 0.000379946 0.000339183 0.00027972 0.000252982 0.000226244 0.000199507 0.000172769 0.000146031 0.000130097 0.000117578 0.000105059 9.25401e-05 8.00213e-05 7.11204e-05 6.67061e-05 6.22918e-05 5.78775e-05 5.34632e-05 4.90489e-05 4.46346e-05 4.02203e-05 3.5806e-05 3.13916e-05 2.69773e-05 2.4827e-05 2.31747e-05 2.15225e-05 1.98702e-05 1.8218e-05 1.65658e-05 1.49135e-05 1.32613e-05 1.1609e-05 9.95678e-06 8.50108e-06 7.86765e-06 7.23422e-06 6.60079e-06 5.96736e-06 5.33393e-06 4.7005e-06 4.06707e-06 3.43363e-06 } .graph element create V9 -x x -y v9 v10 set { 1.86175 1.99308 2.16619 2.46661 3.09359 3.76864 4.31299 4.65564 4.83425 4.92153 4.96157 4.98063 4.98649 4.99039 4.9945 4.9972 4.96206 4.89882 4.83865 4.83202 4.91016 5.04479 5.06078 5.04827 5.03474 5.0246 5.01639 5.00996 5.00569 5.00239 5.00043 5.00296 5.00437 5.00382 5.00287 5.00208 5.00148 5.00104 5.00073 5.0005 5.00034 5.00023 5.00016 5.00011 5.00008 5.00007 5.00007 5.00004 5 4.99998 4.99998 4.99997 4.99998 4.99999 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5.10081 5.10949 4.98359 5.00733 5.15145 4.37298 2.36126 0.470759 0.0577238 0.0115884 0.00262611 0.000671499 0.000389038 0.000291291 0.000317347 -0.0167823 -0.0158344 -0.0140559 0.0104849 0.0865874 0.107813 0.0524688 0.0214369 0.00876443 0.00341595 0.00170778 0.00259042 0.0022241 0.00118519 1.10217e-06 -0.000784506 -0.000948169 -0.000856256 -0.000696719 -0.000485987 -0.000724787 -0.000981491 -0.001454 -0.00552498 -0.0114992 -0.0105266 -0.00543527 -0.000982798 0.00127356 0.00224212 0.00275439 0.00281098 0.0025471 0.00230368 0.00222576 0.00485522 0.00729453 0.00691796 0.0062615 0.00573987 0.0052688 0.00481185 0.00436934 0.00394326 0.00352712 0.00309978 0.00270038 0.00235335 0.00203742 0.00175256 0.00150067 0.00128126 0.00109323 0.000933619 0.000795113 0.000678182 0.00057843 0.000494345 0.000423609 0.000363821 0.000312766 0.000269856 0.000232389 0.000198382 0.000168126 0.00014267 0.000119293 9.69034e-05 8.5669e-05 8.26828e-05 8.64066e-05 9.26665e-05 8.5454e-05 7.82416e-05 7.10291e-05 6.38167e-05 5.66043e-05 4.93918e-05 4.21794e-05 3.86073e-05 3.53007e-05 3.19941e-05 2.86876e-05 2.5381e-05 2.20744e-05 1.87678e-05 1.70933e-05 1.62648e-05 1.54363e-05 1.46079e-05 1.37794e-05 1.2951e-05 1.21225e-05 1.12941e-05 1.04656e-05 9.63716e-06 8.80871e-06 7.98026e-06 7.1518e-06 6.32335e-06 5.5374e-06 5.08959e-06 4.64178e-06 4.19397e-06 3.74616e-06 0.0438026 0.0242078 -0.0602019 -0.0840866 0.00148461 -0.00292489 0.000442098 0.00219489 0.00281478 0.00290756 0.00277945 0.00263896 0.00240099 0.00223283 0.001947 -0.0153629 -0.0148815 -0.0128673 0.0126017 0.0905161 0.11051 0.0538958 0.022562 0.00935726 0.00397422 0.00172534 0.000790207 0.000416322 0.000191632 0.000469721 0.0009779 0.00192566 0.00200688 -0.0016502 -0.00733932 -0.0128113 -0.0147608 -0.0115456 -0.00668995 -0.00401368 -0.00463908 -0.0101197 -0.0118993 -0.0076276 -0.00262656 0.000813059 0.00264455 0.00350796 0.00399494 0.0043049 0.00451658 0.00444739 0.00503842 0.00559516 0.00568213 0.00556459 0.0053176 0.00496654 0.00454337 0.00408592 0.00362171 0.00317793 0.00277001 0.00240394 0.00207009 0.00176575 0.00149725 0.00129045 0.00114257 0.00101135 0.000871672 0.000723764 0.000580438 0.000427507 0.000296956 0.000281834 0.000376628 0.000412266 0.000367547 0.000295305 0.000264513 0.000233721 0.000202929 0.000172137 0.000141345 0.000124721 0.000112577 0.000100433 8.82893e-05 7.61453e-05 6.75517e-05 6.33609e-05 5.91701e-05 5.49792e-05 5.07884e-05 4.65976e-05 4.24067e-05 3.82159e-05 3.40251e-05 2.98342e-05 2.56434e-05 2.36401e-05 2.21181e-05 2.05961e-05 1.90741e-05 1.75521e-05 1.60301e-05 1.45081e-05 1.29861e-05 1.14641e-05 9.94208e-06 8.59252e-06 7.96439e-06 7.33626e-06 6.70813e-06 6.07999e-06 5.45186e-06 4.82373e-06 4.1956e-06 3.56747e-06 } .graph element create V10 -x x -y v10 v11 set { 1.86175 1.73419 1.42874 1.04055 0.943004 0.268275 0.0826455 0.0388346 0.0214104 0.0135431 0.00961322 0.00712846 0.00588262 0.00432397 0.00377774 0.00270134 -0.00393731 -0.00542187 -0.00126596 0.0113777 0.0134522 0.00477056 -0.00211067 -0.00229253 -0.00173355 -0.00122404 -0.00113426 -0.000744931 -0.000520112 -0.000410048 -0.000220439 0.000508104 5.15856e-05 -0.000112593 -0.000118917 -9.57394e-05 -7.15727e-05 -5.11847e-05 -3.58275e-05 -2.47166e-05 -1.68866e-05 -1.14082e-05 -7.66646e-06 -5.12139e-06 -3.63426e-06 -3.01815e-06 -2.64862e-06 -1.4947e-06 -1.91403e-07 -2.5763e-08 -7.73699e-07 -1.52164e-06 -1.07268e-06 -3.81696e-07 2.6727e-07 4.75489e-07 6.83708e-07 8.91926e-07 1.10014e-06 1.30836e-06 1.2482e-06 1.00726e-06 7.66311e-07 5.25364e-07 2.84417e-07 6.27857e-08 7.43904e-10 -6.12979e-08 -1.2334e-07 -1.85382e-07 -2.47423e-07 -3.09465e-07 -3.71507e-07 -4.33549e-07 -4.95591e-07 -5.57633e-07 -6.04571e-07 -5.4944e-07 -4.9431e-07 -4.3918e-07 -3.84049e-07 -3.28919e-07 -2.73789e-07 -2.18659e-07 -1.63528e-07 -1.08398e-07 -5.32678e-08 1.062e-09 5.08502e-08 1.00638e-07 1.50427e-07 2.00215e-07 2.50003e-07 2.99791e-07 3.4958e-07 3.99368e-07 4.49156e-07 4.98944e-07 5.34512e-07 5.01032e-07 4.67553e-07 4.34073e-07 4.00593e-07 3.67113e-07 3.33633e-07 3.00153e-07 2.66674e-07 2.33194e-07 1.99714e-07 1.66234e-07 1.32754e-07 9.92744e-08 6.57945e-08 3.23147e-08 -1.16513e-09 -3.4645e-08 -6.81248e-08 -1.01605e-07 -1.35084e-07 -1.68564e-07 -2.18729e-07 0.0114926 -0.0245378 -0.111828 0.0964775 1.61491 3.22668 4.22041 4.54492 4.82845 4.94868 4.98588 4.99609 4.9981 4.99908 4.99788 4.98395 4.99294 4.99724 5.01939 5.0471 5.00902 4.98194 4.98496 4.99188 4.99623 4.99862 5.00025 4.99974 4.99953 4.99946 4.99958 5.00012 4.99997 4.99992 4.99988 4.99985 4.9998 4.9997 4.9988 4.99806 4.99982 5.00143 5.00159 5.00098 5.00053 5.00028 5.00007 4.99977 4.99992 5.00005 5.00133 5.0009 4.99993 4.99972 4.99975 4.9998 4.99982 4.99983 4.99983 4.99983 4.99983 4.99984 4.99986 4.99987 4.99989 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5.01457 4.99482 4.96561 4.99326 5.03452 5.00424 5.00101 5.00045 5.00004 4.99965 4.99997 4.99994 4.99958 4.99999 4.99936 4.9839 4.99248 4.99717 5.01976 5.04869 5.0087 4.98143 4.98488 4.99199 4.99622 4.9983 4.99928 4.99971 4.99986 5.00031 5.00022 5.00035 5.0001 4.99884 4.99811 4.99803 4.99887 5.00078 5.00151 5.00116 5.00007 4.99843 4.99915 5.00107 5.00168 5.00141 5.00092 5.00055 5.0003 5.00016 5.0001 5.00001 5.00016 5.0002 5.00009 4.99993 4.99975 4.99984 4.99991 4.99991 4.99982 4.99974 4.99974 4.99985 4.99995 4.99999 4.99998 5.00004 5.00013 5.00015 5.00007 4.99988 4.99982 4.99985 4.99995 5.00006 5.0002 5.00025 5.0002 5.00009 5.00006 5.00004 5.00002 5 4.99998 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } .graph element create V11 -x x -y v11 v12 set { 5 5.16975 4.78685 2.94241 0.126698 0.0487004 -0.00422591 -0.00130689 -0.000486756 -0.000195875 -0.000108988 -6.66736e-05 -7.26005e-05 -5.63608e-05 -3.81859e-05 -2.123e-05 -0.0646846 -0.0184474 0.182248 1.06731 3.10988 4.46133 4.84133 4.95113 4.98364 4.99455 4.99694 4.99727 4.9994 4.99975 5.0001 5.00132 5.00089 5.00039 5.00019 5.00011 5.00006 5.00005 5.00004 5.00001 4.99992 4.99992 5.00002 5.00013 5.00017 5.00009 4.99992 4.99991 4.99994 4.99996 4.99998 4.99999 5.00001 5.00004 5.00006 5.00005 5.00004 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.14699 4.78074 3.19424 0.305663 0.0611255 -0.00179951 -0.0012032 0.000405978 0.000989399 0.000445194 0.000191447 8.30476e-05 3.96236e-05 1.91866e-05 1.70665e-05 -0.0655239 -0.0210234 0.1827 1.06848 3.11554 4.46518 4.84212 4.94853 4.98244 4.99434 4.9997 5.00081 5.00009 4.99972 4.99985 4.99974 4.9995 4.99949 4.99958 4.99973 4.99948 4.99914 4.99874 4.99946 5.00309 5.0091 5.01576 5.01835 5.01852 5.0176 5.01625 5.01479 5.01345 5.01264 5.011 5.01092 5.01344 5.01363 5.01289 5.01184 5.01071 5.00956 5.00848 5.00751 5.00663 5.00577 5.00497 5.00427 5.00365 5.0031 5.00264 5.00224 5.00191 5.00163 5.00138 5.00117 5.00099 5.00083 5.00071 5.00061 5.00053 5.00045 5.00037 5.00029 5.00022 5.00019 5.0002 5.00023 5.00024 5.00023 5.00023 5.00022 5.0002 5.00018 5.00016 5.00014 5.00011 5.00009 5.00007 5.00006 5.00005 5.00005 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.14298 4.79809 3.32704 0.498385 0.105773 0.0160646 0.0319912 0.0299434 0.0240102 0.0185844 0.0130411 0.0106532 0.00864871 0.00744519 0.00660887 -0.0612913 -0.0203719 0.174998 0.991787 3.06292 4.60005 4.93058 4.98917 5.00033 4.9999 4.99909 4.9966 4.9955 4.99488 4.99374 4.9943 5.00131 5.00506 4.99311 4.96288 4.93567 4.92439 4.94236 4.9732 4.98864 4.99458 5.00031 5.00694 5.01525 5.01945 5.01998 5.01953 5.01874 5.01766 5.0164 5.01509 5.01326 5.01423 5.01455 5.01361 5.01245 5.01122 5.01002 5.00888 5.00783 5.00687 5.00596 5.00514 5.00442 5.00379 5.00325 5.00279 5.0024 5.00208 5.0018 5.00153 5.00126 5.00107 5.00094 5.00085 5.00078 5.00072 5.00063 5.00053 5.00042 5.00038 5.00034 5.0003 5.00027 5.00023 5.00021 5.00019 5.00017 5.00015 5.00013 5.00012 5.00011 5.0001 5.0001 5.00009 5.00008 5.00007 5.00007 5.00006 5.00005 5.00005 5.00004 5.00004 5.00003 5.00003 5.00002 5.00002 5.00002 5.00001 5.00001 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 } .graph element create V12 -x x -y v12 v13 set { 9.73784e-10 0.0189926 0.0926769 0.206309 0.111533 0.0953491 0.0426966 0.0214177 0.0117943 0.00741442 0.00528816 0.00398417 0.0032967 0.00266499 0.00206647 0.00158788 -0.0371391 -0.0439528 -0.0408653 -0.0188706 0.0150241 0.0126852 0.00209817 -0.000239206 -5.31488e-05 0.000876324 -0.00451221 -0.0165223 -0.0284127 -0.0427584 -0.0502453 -0.0257366 -0.00903938 -0.00376456 -0.00233385 -0.00169922 -0.00130397 -0.00102542 -0.000811435 -0.000648115 -0.000529266 -0.00043795 -0.00036574 -0.00030716 -0.00026221 -0.000229662 -0.000205112 -0.000181038 -0.000162045 -0.000148988 -0.000137633 -0.000126278 -0.000115562 -0.000104976 -9.49324e-05 -9.0585e-05 -8.62375e-05 -8.18901e-05 -7.75426e-05 -7.31952e-05 -6.93752e-05 -6.59106e-05 -6.24461e-05 -5.89815e-05 -5.55169e-05 -5.22412e-05 -5.05263e-05 -4.88114e-05 -4.70966e-05 -4.53817e-05 -4.36668e-05 -4.19519e-05 -4.0237e-05 -3.85222e-05 -3.68073e-05 -3.50924e-05 -3.34782e-05 -3.25442e-05 -3.16102e-05 -3.06763e-05 -2.97423e-05 -2.88083e-05 -2.78744e-05 -2.69404e-05 -2.60064e-05 -2.50725e-05 -2.41385e-05 -2.32635e-05 -2.27232e-05 -2.21829e-05 -2.16426e-05 -2.11023e-05 -2.0562e-05 -2.00217e-05 -1.94814e-05 -1.89411e-05 -1.84007e-05 -1.78604e-05 -1.73647e-05 -1.70853e-05 -1.68059e-05 -1.65265e-05 -1.62471e-05 -1.59677e-05 -1.56883e-05 -1.54089e-05 -1.51295e-05 -1.48501e-05 -1.45707e-05 -1.42913e-05 -1.40119e-05 -1.37325e-05 -1.34531e-05 -1.31737e-05 -1.28943e-05 -1.26149e-05 -1.23355e-05 -1.20561e-05 -1.17767e-05 -1.14973e-05 -1.10954e-05 0.0152675 0.0228237 -0.00460678 -0.0341525 0.0232109 -0.0138039 -0.0416538 -0.0458764 -0.0201967 -0.00878316 -0.00379173 -0.00164621 -0.000785131 -0.00037575 -0.000352375 -0.0545586 -0.0746881 -0.0771865 -0.05386 -0.0022199 0.0136703 0.00633526 0.00138826 -0.00108934 0.0038886 0.0298077 0.0475776 0.0481003 0.0464167 0.047818 0.042789 0.035207 0.0264423 0.0193959 0.0151614 0.00624257 -0.00913057 -0.0310696 -0.0430238 0.016426 0.189762 0.49025 0.820116 1.13919 1.43549 1.70658 1.95183 2.17414 2.38506 2.5657 2.73958 2.97905 3.21403 3.43025 3.62645 3.8028 3.96002 4.09996 4.22443 4.33427 4.42886 4.51097 4.5817 4.64326 4.6957 4.74132 4.7797 4.81298 4.84102 4.86512 4.88523 4.90224 4.91649 4.92846 4.93868 4.94755 4.95483 4.96114 4.96682 4.97161 4.97502 4.9776 4.97944 4.98141 4.98319 4.98467 4.98585 4.9869 4.98796 4.98902 4.99008 4.99114 4.9922 4.99326 4.9938 4.99429 4.99479 4.99528 4.99578 4.99628 4.99677 4.99704 4.99718 4.99733 4.99747 4.99762 4.99777 4.99791 4.99806 4.9982 4.99835 4.9985 4.99864 4.99879 4.99893 4.99907 4.99916 4.99925 4.99934 4.99943 5.01473 4.92293 4.61974 4.0316 3.7835 3.74195 3.78344 3.87272 3.97386 4.07319 4.16686 4.25256 4.33126 4.40264 4.46697 4.49249 4.51807 4.55803 4.64055 4.78574 4.86074 4.88334 4.8999 4.91455 4.92814 4.93926 4.94761 4.95433 4.95907 4.9654 4.98317 5.0208 5.05134 4.85852 4.16041 3.00077 1.68376 0.672707 0.240838 0.0794725 -0.0106347 -0.00879443 0.107196 0.368163 0.701424 1.03581 1.3601 1.6678 1.95731 2.22701 2.47544 2.69099 2.92327 3.16648 3.3877 3.59067 3.77344 3.93584 4.08066 4.20863 4.32065 4.41791 4.50211 4.57423 4.63614 4.68888 4.73377 4.7721 4.80519 4.83338 4.85732 4.87815 4.89514 4.90927 4.92108 4.93122 4.94014 4.94845 4.95601 4.96251 4.96576 4.969 4.97225 4.9755 4.97874 4.98087 4.98265 4.98442 4.9862 4.98797 4.98924 4.9899 4.99055 4.9912 4.99186 4.99251 4.99316 4.99381 4.99447 4.99512 4.99577 4.99609 4.99634 4.99659 4.99683 4.99708 4.99732 4.99757 4.99782 4.99806 4.99831 4.99853 4.99863 4.99873 4.99883 4.99893 4.99903 4.99913 4.99923 4.99933 } .graph element create V13 -x x -y v13 v14 set { 1.86175 2.00147 1.85141 1.0654 0.275481 0.205547 0.0712627 0.0313387 0.0151431 0.00864531 0.00593861 0.00438111 0.0037479 0.00305857 0.00221221 0.0017081 -0.0896128 -0.109079 -0.121356 -0.0542001 0.175821 0.177442 0.0814591 0.0333042 0.0134909 0.00625777 0.00100092 -0.00552776 -0.00411139 -0.00150395 -0.000564784 3.48169e-05 -0.000287014 -0.000538515 -0.000456537 -0.000325677 -0.000275468 -0.000166452 -8.27481e-05 -8.28704e-05 -7.47644e-05 -4.60552e-05 -2.61481e-06 2.26359e-05 2.53852e-05 -1.39853e-06 -4.23456e-05 -4.0907e-05 -2.8501e-05 -1.5945e-05 -9.01122e-06 -2.07747e-06 1.49328e-06 4.38398e-06 6.84248e-06 4.76711e-06 2.69173e-06 6.16362e-07 -1.45901e-06 -3.53438e-06 -4.14256e-06 -3.76238e-06 -3.3822e-06 -3.00202e-06 -2.62184e-06 -2.24878e-06 -1.93456e-06 -1.62033e-06 -1.3061e-06 -9.91867e-07 -6.77638e-07 -3.63409e-07 -4.91792e-08 2.6505e-07 5.7928e-07 8.93509e-07 1.16076e-06 1.11055e-06 1.06034e-06 1.01014e-06 9.59927e-07 9.09719e-07 8.59511e-07 8.09302e-07 7.59094e-07 7.08886e-07 6.58678e-07 5.99251e-07 4.87523e-07 3.75795e-07 2.64068e-07 1.5234e-07 4.06119e-08 -7.1116e-08 -1.82844e-07 -2.94572e-07 -4.063e-07 -5.18027e-07 -6.08517e-07 -5.95879e-07 -5.83241e-07 -5.70604e-07 -5.57966e-07 -5.45328e-07 -5.3269e-07 -5.20053e-07 -5.07415e-07 -4.94777e-07 -4.8214e-07 -4.69502e-07 -4.56864e-07 -4.44226e-07 -4.31589e-07 -4.18951e-07 -4.06313e-07 -3.93676e-07 -3.81038e-07 -3.684e-07 -3.55762e-07 -3.43125e-07 1.06736e-05 0.0797407 0.0437947 -0.0645098 -0.0877312 0.0653203 -0.00621184 -0.0353188 -0.0491378 -0.0251957 -0.0110996 -0.00481123 -0.0020941 -0.000998038 -0.000478747 -0.000445332 -0.102046 -0.135753 -0.154351 -0.0827509 0.163348 0.174012 0.0794822 0.0310624 0.0112213 0.00249061 0.00130764 0.00181315 0.00163875 0.00101454 0.000497435 0.000195258 5.31901e-05 2.4607e-05 6.62736e-05 7.90718e-05 4.0372e-05 -0.000141184 -0.000280623 5.5608e-05 0.000799565 0.000920189 0.000931616 0.000494527 0.000162303 -8.24884e-05 -0.000183938 -0.000203899 -0.000144788 -9.87063e-05 -0.000227929 2.93932e-05 0.000208563 1.88958e-06 -7.6335e-05 -0.000172472 -0.000165656 -0.000145889 -0.000177311 -0.000191058 -0.000168287 -0.00015755 -0.00013142 -8.10488e-05 -6.36115e-05 -7.8699e-05 -8.11282e-05 -7.98625e-05 -5.98807e-05 -3.40879e-05 -1.95464e-05 -1.79247e-05 -4.45514e-05 -7.47995e-05 -8.7682e-05 -7.50806e-05 -3.25561e-05 -4.34114e-05 -7.69099e-05 -0.000141101 -0.00018743 -0.000148471 -5.06546e-05 0.000120195 0.000177635 0.000177052 0.000146344 9.75126e-05 8.31233e-05 6.8734e-05 5.43447e-05 3.99554e-05 2.55661e-05 1.11768e-05 -3.21253e-06 -3.88937e-06 -3.56628e-06 -3.24318e-06 -2.92008e-06 -2.59699e-06 -2.27389e-06 -1.9508e-06 -1.73227e-06 -1.56796e-06 -1.40365e-06 -1.23934e-06 -1.07503e-06 -9.10722e-07 -7.46412e-07 -5.82101e-07 -4.1779e-07 -2.5348e-07 -8.91694e-08 7.51412e-08 2.39452e-07 4.03762e-07 5.95733e-07 1.00771e-06 1.41969e-06 1.83167e-06 2.24365e-06 0.0828257 0.231038 0.465438 1.54516 2.8461 3.19221 3.40395 3.6382 3.80758 3.93848 4.04882 4.15428 4.247 4.32917 4.40235 4.36941 4.397 4.48862 4.64552 4.86595 5.03475 5.0348 5.02627 5.01967 5.01542 5.00925 4.98613 4.9519 4.91581 4.87357 4.82302 4.80403 4.82565 4.86102 4.89483 4.92253 4.94428 4.96257 4.97608 4.98373 4.98823 4.99182 4.99437 4.99635 4.99745 4.99802 4.99843 4.99873 4.99895 4.99912 4.99925 4.99931 4.99962 4.99973 4.99972 4.99971 4.9997 4.99969 4.9997 4.99971 4.99973 4.99974 4.99976 4.99978 4.9998 4.99982 4.99985 4.99987 4.99989 4.9999 4.99991 4.99991 4.99993 4.99994 4.99997 5.00001 5.00006 5.00008 5.00006 5.00002 5 4.99999 4.99998 4.99997 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99999 5 5 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 } .graph element create V14 -x x -y v14 v15 set { 1.86175 2.00199 2.08919 1.84314 1.08254 0.214737 0.0377351 0.00952455 0.00232763 0.000563614 0.000263477 0.000148642 0.000285086 0.000242592 7.34699e-05 -1.53467e-05 -0.0161874 -0.0157876 -0.0141194 0.0132576 0.0903272 0.109938 0.0535295 0.0224216 0.00940945 0.00466825 -0.000649972 -0.00654752 -0.00333248 -0.00103671 -0.000508276 -5.8896e-05 -0.00043938 -0.000544704 -0.00044444 -0.000307093 -0.00024517 -0.000154538 -8.78602e-05 -7.10461e-05 -6.06485e-05 -3.91039e-05 -8.45988e-06 9.43442e-06 1.28351e-05 -2.16734e-06 -2.6142e-05 -2.54768e-05 -1.88997e-05 -1.17906e-05 -7.3808e-06 -2.97101e-06 1.19146e-07 2.94246e-06 5.38942e-06 3.88851e-06 2.38761e-06 8.86704e-07 -6.14201e-07 -2.11511e-06 -2.59565e-06 -2.38885e-06 -2.18205e-06 -1.97525e-06 -1.76845e-06 -1.56241e-06 -1.36258e-06 -1.16276e-06 -9.62939e-07 -7.63116e-07 -5.63293e-07 -3.6347e-07 -1.63647e-07 3.61756e-08 2.35999e-07 4.35822e-07 6.07653e-07 5.90323e-07 5.72994e-07 5.55665e-07 5.38336e-07 5.21007e-07 5.03678e-07 4.86349e-07 4.6902e-07 4.51691e-07 4.34361e-07 4.11899e-07 3.60315e-07 3.08731e-07 2.57146e-07 2.05562e-07 1.53977e-07 1.02393e-07 5.08082e-08 -7.76222e-10 -5.23607e-08 -1.03945e-07 -1.47815e-07 -1.54225e-07 -1.60635e-07 -1.67045e-07 -1.73455e-07 -1.79864e-07 -1.86274e-07 -1.92684e-07 -1.99094e-07 -2.05504e-07 -2.11914e-07 -2.18324e-07 -2.24734e-07 -2.31144e-07 -2.37554e-07 -2.43964e-07 -2.50373e-07 -2.56783e-07 -2.63193e-07 -2.69603e-07 -2.76013e-07 -2.82423e-07 2.92534e-06 0.0446777 0.024278 -0.0518987 -0.0636547 0.00983929 -0.000518204 -0.000265194 0.000154772 0.000299538 3.12715e-05 -3.18225e-05 -2.48268e-05 -1.16701e-05 -6.05117e-06 7.61116e-06 -0.0163668 -0.0158244 -0.0141177 0.0100085 0.0857144 0.107784 0.051862 0.0204448 0.00629858 0.000967736 0.00121674 0.00190276 0.00154009 0.000860922 0.000410386 0.000164585 3.99493e-05 1.93797e-05 5.67594e-05 0.000110126 2.49925e-05 -7.17815e-05 -0.000142299 -1.63109e-05 0.000439529 0.000562489 0.000594599 0.000326164 0.000126423 -4.26063e-05 -0.000122927 -0.000114152 -6.72706e-05 -6.41242e-05 -0.000135588 2.61507e-05 0.000134036 6.43734e-06 -4.6223e-05 -0.000112047 -0.000101388 -8.67847e-05 -0.000117664 -0.000133957 -0.000116558 -0.000100873 -7.65448e-05 -4.44964e-05 -3.6677e-05 -5.26632e-05 -5.45172e-05 -5.13545e-05 -3.73869e-05 -1.99732e-05 -1.0907e-05 -1.10081e-05 -3.02609e-05 -5.18517e-05 -6.13597e-05 -5.30706e-05 -2.39572e-05 -3.24146e-05 -5.70062e-05 -0.000103448 -0.000135376 -0.0001024 -2.39007e-05 0.000110929 0.000151226 0.000142044 0.000105922 5.62834e-05 4.78476e-05 3.94117e-05 3.09759e-05 2.25401e-05 1.41042e-05 5.66837e-06 -2.76747e-06 -3.08639e-06 -2.81341e-06 -2.54043e-06 -2.26745e-06 -1.99447e-06 -1.72149e-06 -1.44851e-06 -1.26226e-06 -1.12096e-06 -9.79661e-07 -8.38363e-07 -6.97065e-07 -5.55768e-07 -4.1447e-07 -2.73173e-07 -1.31875e-07 9.42259e-09 1.5072e-07 2.92018e-07 4.33315e-07 5.74613e-07 7.10363e-07 8.01984e-07 8.93604e-07 9.85225e-07 1.07685e-06 0.04474 0.0928765 0.141327 0.0176048 -0.071675 -0.0124613 0.989022 2.28104 3.40619 4.21417 4.67173 4.87438 4.96044 4.98996 4.99858 4.96672 4.89502 4.79391 4.76433 4.8387 4.98612 5.0161 5.01722 5.01437 5.01256 4.99827 4.95807 4.9209 4.88217 4.83006 4.78461 4.80759 4.85548 4.89604 4.9254 4.94617 4.96126 4.97374 4.98255 4.98792 4.99126 4.99361 4.99554 4.99699 4.99792 4.99846 4.99881 4.99905 4.99924 4.99938 4.99949 4.99955 4.9997 4.9998 4.99982 4.99982 4.99982 4.99982 4.99982 4.99983 4.99984 4.99985 4.99986 4.99987 4.99988 4.99989 4.9999 4.99992 4.99993 4.99994 4.99995 4.99995 4.99996 4.99996 4.99998 4.99999 5.00001 5.00002 5.00002 5.00001 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 } .graph element create V15 -x x -y v15 v16 set { 1.86175 1.73073 1.50572 1.89001 3.39004 4.36034 4.79012 4.93798 4.98305 4.99539 4.9979 4.99904 4.99772 4.9983 4.99935 4.99975 4.98837 4.99456 4.99728 5.01838 5.04568 5.00759 4.98112 4.98479 4.99197 4.99641 4.99747 4.99775 5.00043 5.0007 5.00035 5.00023 4.99976 5.00002 5.00007 5.0002 4.99993 5.00003 5.00021 5.00006 4.99993 4.99992 5.00002 5.00013 5.00017 5.00009 4.99992 4.99991 4.99993 4.99996 4.99998 4.99999 5.00001 5.00003 5.00005 5.00004 5.00004 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.01498 4.99342 4.96899 5.00301 5.02627 4.9977 4.99548 4.99757 5.00277 5.00245 5.0014 5.00069 5.00032 5.00014 5.00009 4.9867 4.99262 4.99607 5.01805 5.04713 5.00927 4.98184 4.98483 4.9914 4.99616 4.99902 4.9999 4.99987 4.99979 4.99981 4.99989 4.99994 4.99998 5.0002 5.00001 5.00008 5.00008 5.0001 5.00021 5.00032 5.00025 5.00019 5.00006 5.00007 4.99994 4.99997 4.99999 5.00023 5.00008 4.99993 4.99998 4.99986 4.99982 5.00003 4.99985 4.99996 5.00014 5 4.99984 4.99979 4.99982 4.99993 5.00008 5.00011 5.00002 4.99996 4.9999 4.99994 5.00001 5.00007 5.00009 4.99995 4.99978 4.99971 4.99976 4.99997 4.99996 4.99989 4.99972 4.99955 4.99953 4.99959 4.99976 4.9999 5.00005 5.00023 5.00039 5.00034 5.00029 5.00024 5.00019 5.00014 5.00009 5.00004 5.00003 5.00002 5.00001 5 5 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00002 5.00003 5.00004 5.01564 5.03395 5.04932 5.11868 3.92502 1.31888 0.163888 0.0946876 0.0789578 0.0565084 0.0260333 0.0156986 0.00907667 0.00613629 0.00468417 -0.00174008 -0.0021422 0.000586962 0.0124937 0.0147977 0.00838454 0.00039383 -0.000522021 -0.000426598 -0.000290214 -0.00173713 -0.00384132 -0.00382945 -0.00429219 -0.00580193 -0.00393246 0.0017543 0.00423045 0.00408931 0.0031976 0.00245457 0.00187293 0.00159068 0.00105697 0.000609902 0.000358825 0.000334125 0.000212708 0.000168116 8.97349e-05 5.21578e-05 3.84527e-05 2.93033e-05 2.10067e-05 1.59954e-05 1.13917e-05 5.49738e-06 2.77217e-05 6.51259e-06 -6.65468e-06 2.09837e-06 -6.617e-06 -4.80187e-06 1.55031e-06 4.26536e-06 7.69457e-07 -1.46213e-06 -7.25202e-07 3.26501e-06 6.55807e-06 7.524e-06 6.07209e-06 6.00701e-06 5.41166e-06 3.86573e-06 1.10651e-06 -2.74603e-06 -2.18566e-06 2.3658e-06 8.59956e-06 8.35046e-06 2.90621e-06 -8.75982e-07 -1.87189e-06 -2.1528e-06 -1.94875e-06 -1.74471e-06 -1.54067e-06 -1.33662e-06 -1.13258e-06 -8.40567e-07 -5.20743e-07 -2.00918e-07 1.18906e-07 4.38731e-07 6.11382e-07 6.01529e-07 5.91675e-07 5.81822e-07 5.71968e-07 5.62115e-07 5.52261e-07 5.42407e-07 5.32554e-07 5.227e-07 5.12847e-07 4.72812e-07 4.26137e-07 3.79462e-07 3.32786e-07 2.86111e-07 2.39436e-07 1.92761e-07 1.46086e-07 9.94107e-08 5.27356e-08 -2.77779e-10 -7.98079e-08 -1.59338e-07 -2.38868e-07 -3.18398e-07 -3.97928e-07 -4.77458e-07 -5.56988e-07 -6.36519e-07 } .graph element create V16 -x x -y v16 v17 set { 5 5.16963 4.84136 3.33754 0.316206 0.103113 0.0273341 0.0221102 0.0177008 0.0143758 0.0115203 0.00929231 0.00752716 0.00625439 0.00489872 0.00403656 -0.0657317 -0.0256467 0.165394 0.985963 3.05067 4.55799 4.89728 4.92464 4.8882 4.90592 4.97315 4.99241 4.99694 4.99845 4.99905 4.99939 4.99959 4.99971 4.9998 4.99986 4.9999 4.99993 4.99995 4.99996 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00001 5.00003 5.00005 5.00004 5.00002 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00025 5.1657 4.69981 2.43895 0.0229743 0.0351406 -0.0211974 -0.0312063 -0.0160331 -0.0021718 -0.000766597 -0.000251052 -5.49363e-05 -3.36364e-06 -2.01983e-06 -9.70575e-06 -0.0657007 -0.0205247 0.183332 1.07163 3.11839 4.46213 4.84163 4.95195 4.99159 5.02084 5.04029 5.04138 5.0271 5.00445 4.97957 4.95702 4.95231 4.97819 4.99191 4.9963 4.99822 4.99878 4.99903 4.99925 4.99942 4.9995 4.99954 4.99957 4.99961 4.99966 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 4.99988 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.14239 4.76219 3.16574 0.299969 0.0631609 -0.00118611 -0.00026052 -5.96333e-05 -1.44904e-05 -4.3859e-06 -2.99454e-06 1.10547e-06 4.84662e-06 1.30971e-05 2.23082e-05 -0.0655844 -0.0204818 0.182507 1.05954 3.12277 4.46735 4.83915 4.94512 4.97679 4.98654 4.9966 5.00833 5.00776 5.00432 5.00199 5.00086 5.00033 5.00008 5 5.00001 5 5.00005 5.00002 4.99981 4.99991 4.99998 4.99979 4.99979 4.99984 4.9998 4.9998 5.00006 5.00002 5.00001 5 5 4.99992 4.99998 4.99999 5.00002 5.00014 4.99999 4.99987 4.99993 5.00003 5.00011 5.00005 4.99996 4.99987 4.99985 4.99994 5.00009 5.0001 5 4.99993 4.99997 5.00008 5.00015 5.00021 5.00021 5.00007 4.99978 4.99965 4.99973 4.9999 4.99992 4.99995 4.99997 4.99999 5.00001 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 } .graph element create V17 -x x -y v17 v18 set { 5 5.0333 5.02472 4.92559 4.18383 3.93923 3.9961 4.14293 4.28591 4.41336 4.52157 4.61101 4.68472 4.7439 4.79294 4.83239 4.80697 4.78808 4.79322 4.8838 5.08529 5.21863 4.88852 3.90198 2.14586 0.383977 0.101103 0.0525711 0.0318287 0.020895 0.0146908 0.010831 0.00830272 0.00656377 0.00532066 0.00440078 0.00369956 0.00315713 0.00272614 0.00237965 0.00209659 0.00186339 0.00167014 0.0015081 0.00137172 0.00125607 0.00115393 0.00106076 0.000980166 0.000918015 0.000862837 0.00080766 0.000763488 0.000721541 0.000680825 0.000653026 0.000625226 0.000597426 0.000569627 0.000541827 0.000519087 0.000499756 0.000480424 0.000461093 0.000441761 0.000423291 0.000411941 0.00040059 0.00038924 0.000377889 0.000366539 0.000355188 0.000343838 0.000332487 0.000321137 0.000309786 0.000299055 0.000292509 0.000285963 0.000279417 0.000272871 0.000266325 0.000259779 0.000253233 0.000246686 0.00024014 0.000233594 0.000227387 0.0002231 0.000218813 0.000214526 0.00021024 0.000205953 0.000201666 0.000197379 0.000193092 0.000188805 0.000184519 0.000180526 0.000177963 0.0001754 0.000172837 0.000170274 0.000167711 0.000165148 0.000162585 0.000160022 0.000157459 0.000154895 0.000152332 0.000149769 0.000147206 0.000144643 0.00014208 0.000139517 0.000136954 0.000134391 0.000131828 0.000129265 0.000126702 0.000132838 0.0311184 0.163151 0.34986 0.604501 0.357125 0.136137 0.0711304 0.0346959 0.0212674 0.00872193 0.00252206 0.000455269 7.59332e-05 2.91532e-05 0.000320562 -0.0720911 -0.0840491 -0.0791345 -0.0404143 0.0182035 -0.0235871 -0.0426072 -0.0597501 0.00824773 0.481404 1.32496 2.11949 2.57317 2.58202 2.15054 1.33786 0.45702 0.153772 0.0913584 0.0604989 0.0421591 0.0271456 0.0170021 0.0115815 0.00907886 0.00742466 0.00626096 0.00531127 0.00450501 0.00381927 0.00323718 0.00274374 0.00232494 0.00196885 0.00166686 0.00141134 0.00119437 0.0010109 0.000855534 0.000723378 0.000611408 0.000516704 0.000436769 0.000369523 0.000313026 0.00026526 0.000223976 0.000188972 0.000159042 0.000134148 0.000112688 9.49738e-05 7.97877e-05 6.721e-05 5.65115e-05 4.77194e-05 4.03591e-05 3.42848e-05 2.92627e-05 2.50435e-05 2.1412e-05 1.84532e-05 1.58624e-05 1.34673e-05 1.14461e-05 1.00935e-05 9.12375e-06 8.50202e-06 7.81431e-06 7.20729e-06 6.73936e-06 6.3702e-06 5.90049e-06 5.43077e-06 4.96105e-06 4.49133e-06 4.02162e-06 3.5519e-06 3.08218e-06 2.79099e-06 2.51281e-06 2.23463e-06 1.95645e-06 1.67827e-06 1.40009e-06 1.12191e-06 1.01376e-06 9.9375e-07 9.73741e-07 9.53733e-07 9.33724e-07 9.13715e-07 8.93707e-07 8.73698e-07 8.5369e-07 8.33681e-07 8.13673e-07 7.93664e-07 7.73655e-07 7.53647e-07 7.21781e-07 5.956e-07 4.69419e-07 3.43239e-07 2.17058e-07 0.0284032 0.0374438 -0.0157543 -0.0680497 0.0504768 0.0100294 0.00222261 0.000528697 0.000132929 3.99489e-05 2.46066e-05 4.56327e-06 -6.54853e-06 1.33783e-05 -3.68221e-05 -0.0724498 -0.0843663 -0.0792935 -0.0406426 0.0200019 0.0426259 0.0220753 0.00668555 -0.000968483 0.024662 0.0383437 0.0911513 0.087848 0.0602076 0.0390559 0.0260573 0.0180444 0.012974 0.00985409 0.00788132 0.0064228 0.005545 0.00453571 0.00364245 0.00310278 0.00270523 0.00236439 0.0020945 0.00186808 0.00167493 0.00151731 0.00138594 0.00126945 0.00116695 0.0010762 0.000996366 0.000928387 0.000864414 0.000808258 0.000759574 0.000713865 0.000666712 0.000632716 0.000601262 0.000572163 0.000543986 0.000515253 0.0004897 0.000468112 0.000449313 0.000432981 0.000417911 0.000401307 0.000382712 0.000366678 0.000355736 0.000349171 0.000335727 0.000317091 0.000296086 0.000283543 0.000277366 0.000272233 0.000267001 0.000263147 0.000256699 0.000250251 0.000243803 0.000237355 0.000230907 0.000225424 0.000220247 0.000215069 0.000209892 0.000204714 0.000200213 0.000196548 0.000192884 0.00018922 0.000185556 0.000181892 0.000178228 0.000174564 0.0001709 0.000167236 0.000163572 0.000160824 0.000158279 0.000155733 0.000153187 0.000150641 0.000148095 0.000145549 0.000143003 0.000140457 0.000137911 0.000135457 0.000133386 0.000131315 0.000129245 0.000127174 0.000125103 0.000123032 0.000120961 0.000118891 } .graph element create V18 -x x -y v18 v19 set { 1.86175 1.99994 2.0833 2.01627 2.42503 3.25769 3.62134 3.88827 4.09688 4.26773 4.40529 4.51734 4.60827 4.68313 4.74346 4.79302 4.72815 4.68959 4.70421 4.81316 5.01375 5.14493 5.10305 5.0699 5.04484 5.03751 5.03348 5.02504 5.01799 5.01271 5.00895 5.00628 5.0044 5.00309 5.00216 5.00151 5.00105 5.00073 5.00051 5.00034 5.00023 5.00015 5.0001 5.00007 5.00003 4.99998 4.99993 4.99993 4.99995 4.99999 5.00001 5.00003 5.00002 5.00001 5 5 5 5 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00017 5.17398 4.94779 3.78508 1.52302 0.608808 0.244311 0.126053 0.0597175 0.038422 0.0158174 0.00481338 0.00107847 0.000301256 0.000114861 0.00059489 -0.118904 -0.147478 -0.158986 -0.080544 0.165361 0.171378 0.0776087 0.0435738 0.0428235 0.0423755 0.0347695 0.0225061 0.0155539 0.0121357 0.0107997 0.0103976 0.0124406 0.016814 0.0167556 0.0149852 0.01459 0.0141182 0.0131934 0.0120286 0.0108692 0.0097184 0.00855881 0.00744912 0.00643877 0.00554044 0.00475165 0.00406535 0.00347158 0.00295981 0.00251995 0.00214318 0.00182101 0.00154613 0.00131196 0.0011119 0.000941587 0.000796999 0.000674582 0.000571283 0.000484276 0.000410649 0.000347005 0.000292984 0.000246715 0.000208143 0.00017489 0.000147412 0.000123854 0.000104332 8.77229e-05 7.40686e-05 6.2637e-05 5.32e-05 4.53946e-05 3.88343e-05 3.31864e-05 2.85905e-05 2.45725e-05 2.08671e-05 1.77301e-05 1.55911e-05 1.40153e-05 1.29421e-05 1.18693e-05 1.09815e-05 1.03484e-05 9.87664e-06 9.14446e-06 8.41228e-06 7.68011e-06 6.94793e-06 6.21575e-06 5.48357e-06 4.7514e-06 4.38454e-06 4.04432e-06 3.7041e-06 3.36388e-06 3.02366e-06 2.68344e-06 2.34322e-06 2.15196e-06 2.03791e-06 1.92386e-06 1.80982e-06 1.69577e-06 1.58173e-06 1.46768e-06 1.35363e-06 1.23959e-06 1.12554e-06 1.0115e-06 8.9745e-07 7.83404e-07 6.69358e-07 4.76113e-07 -3.47071e-07 -1.17025e-06 -1.99344e-06 -2.81662e-06 0.0783754 0.0500262 -0.0659563 -0.120914 0.0815957 0.0154255 0.00347177 0.000840357 0.000214582 6.54655e-05 3.91709e-05 8.07396e-06 -4.44265e-07 1.74384e-05 -4.52725e-05 -0.119379 -0.147984 -0.159247 -0.0824604 0.169014 0.177628 0.0758742 0.010558 -0.0346506 -0.0710288 -0.0838952 -0.0599521 -0.034568 -0.0181615 -0.00968034 -0.00547115 -0.00333511 -0.00232468 -0.00181159 -0.00143841 -0.00116601 -0.000839755 -0.000569764 -0.000578683 -0.000490551 -0.000411712 -0.000437859 -0.000408185 -0.000356644 -0.000311332 -0.000269006 -0.000221396 -0.000210054 -0.0001923 -0.000175122 -0.000161039 -0.0001428 -0.000126123 -0.000127893 -8.14516e-05 -0.000120166 -0.000154909 -0.000112733 -8.40377e-05 -7.11342e-05 -8.09538e-05 -9.77789e-05 -9.82402e-05 -7.73531e-05 -5.28255e-05 -3.1096e-05 -1.87967e-05 -1.96552e-05 -4.16655e-05 -5.77185e-05 -5.24142e-05 -2.83153e-05 -1.90012e-05 -1.54415e-05 -2.52569e-05 -6.23747e-05 -0.000130543 -0.000149394 -0.000110886 -4.35517e-05 -4.17084e-05 -3.98651e-05 -3.80218e-05 -3.61785e-05 -3.43352e-05 -3.36249e-05 -3.32729e-05 -3.29208e-05 -3.25687e-05 -3.22166e-05 -3.17143e-05 -3.10258e-05 -3.03372e-05 -2.96486e-05 -2.89601e-05 -2.82715e-05 -2.75829e-05 -2.68944e-05 -2.62058e-05 -2.55173e-05 -2.48287e-05 -2.43043e-05 -2.38159e-05 -2.33276e-05 -2.28393e-05 -2.2351e-05 -2.18626e-05 -2.13743e-05 -2.0886e-05 -2.03977e-05 -1.99093e-05 -1.945e-05 -1.91122e-05 -1.87744e-05 -1.84366e-05 -1.80987e-05 -1.77609e-05 -1.74231e-05 -1.70853e-05 -1.67474e-05 } .graph element create V19 -x x -y v19 v20 set { 1.86175 1.99724 2.17266 2.48439 3.15933 3.85231 4.38091 4.69033 4.85034 4.92851 4.96453 4.98188 4.98736 4.991 4.99482 4.9973 4.96422 4.89989 4.83907 4.83151 4.90868 5.04854 5.06104 5.04571 5.03219 5.03025 5.02273 5.01707 5.0123 5.0087 5.00611 5.00429 5.00301 5.00211 5.00148 5.00103 5.00072 5.0005 5.00035 5.00024 5.00016 5.00011 5.00007 5.00005 5.00003 5.00001 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 5 5 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99981 5.10081 5.10903 4.98404 5.00999 5.14946 4.36501 2.23938 0.325144 0.00660272 -0.0102186 -0.0082401 -0.00556785 -0.00374178 -0.00264763 -0.00202823 -0.0182241 -0.0169551 -0.0150395 0.0103736 0.0877592 0.104382 0.0515938 0.0373818 0.0411547 0.0397009 0.0308946 0.0205793 0.0154037 0.0129191 0.0119327 0.011527 0.0124295 0.0161152 0.0161076 0.0145391 0.0144541 0.0139287 0.0129215 0.0117239 0.0105795 0.00942983 0.00827423 0.00718354 0.00619954 0.00532868 0.00456631 0.00390448 0.00333254 0.00284003 0.00241714 0.00205524 0.0017458 0.00148202 0.00125739 0.0010655 0.000902213 0.000763611 0.000646279 0.000547291 0.000463934 0.000393401 0.000332424 0.000280655 0.000236328 0.000199386 0.000167536 0.000141218 0.000118654 9.99559e-05 8.40479e-05 7.09694e-05 6.00188e-05 5.09786e-05 4.3502e-05 3.72191e-05 3.18114e-05 2.74071e-05 2.35539e-05 1.99967e-05 1.69871e-05 1.49449e-05 1.3451e-05 1.24492e-05 1.14256e-05 1.05669e-05 9.94487e-06 9.47514e-06 8.77318e-06 8.07123e-06 7.36927e-06 6.66731e-06 5.96536e-06 5.2634e-06 4.56144e-06 4.23044e-06 3.92649e-06 3.62254e-06 3.31858e-06 3.01463e-06 2.71068e-06 2.40673e-06 2.23063e-06 2.12082e-06 2.01102e-06 1.90121e-06 1.7914e-06 1.68159e-06 1.57178e-06 1.46197e-06 1.35216e-06 1.24235e-06 1.13255e-06 1.02274e-06 9.12929e-07 8.0312e-07 6.33171e-07 -1.51288e-08 -6.63428e-07 -1.31173e-06 -1.96003e-06 0.0437517 0.0265689 -0.0515377 -0.0658688 0.010727 -0.000511921 -8.36924e-05 2.13278e-05 1.45207e-05 4.54862e-06 -6.14726e-06 2.0062e-06 1.02709e-06 1.4152e-05 -3.08225e-05 -0.0166501 -0.0157139 -0.013957 0.0107537 0.0873717 0.111302 0.0454129 -0.00530142 -0.0468336 -0.0790063 -0.0826944 -0.0534753 -0.0288705 -0.0149009 -0.00801592 -0.0046342 -0.00291835 -0.00213019 -0.00170055 -0.001352 -0.00110593 -0.000742655 -0.000532042 -0.000544742 -0.000479206 -0.000407307 -0.000403575 -0.000366209 -0.000324161 -0.000286183 -0.000247579 -0.000214281 -0.000203435 -0.000186896 -0.000171033 -0.00015779 -0.000145259 -0.000128069 -0.000122647 -9.89398e-05 -0.000114926 -0.000132195 -0.000107872 -8.91015e-05 -7.87996e-05 -8.14061e-05 -8.9098e-05 -8.83368e-05 -7.6122e-05 -6.14668e-05 -4.75402e-05 -3.81855e-05 -3.69696e-05 -4.78656e-05 -5.61346e-05 -5.35007e-05 -4.1459e-05 -3.35411e-05 -2.52374e-05 -2.37479e-05 -4.6406e-05 -9.41884e-05 -0.000109222 -8.52676e-05 -4.25166e-05 -4.10125e-05 -3.95085e-05 -3.80045e-05 -3.65004e-05 -3.49964e-05 -3.41627e-05 -3.3541e-05 -3.29193e-05 -3.22976e-05 -3.16758e-05 -3.10334e-05 -3.03653e-05 -2.96971e-05 -2.9029e-05 -2.83609e-05 -2.76928e-05 -2.70246e-05 -2.63565e-05 -2.56884e-05 -2.50203e-05 -2.43521e-05 -2.38716e-05 -2.34324e-05 -2.29932e-05 -2.25539e-05 -2.21147e-05 -2.16755e-05 -2.12362e-05 -2.0797e-05 -2.03578e-05 -1.99186e-05 -1.95079e-05 -1.9217e-05 -1.8926e-05 -1.8635e-05 -1.8344e-05 -1.8053e-05 -1.7762e-05 -1.74711e-05 -1.71801e-05 } .graph element create V20 -x x -y v20 v21 set { 1.86175 1.73273 1.42016 1.02483 0.944013 0.274107 0.0823742 0.0379366 0.020816 0.0132952 0.00955525 0.00717008 0.00592286 0.00437379 0.00383557 0.00273694 -0.0037467 -0.0054191 -0.00131454 0.0112179 0.0133918 0.00519747 -0.00260113 -0.00252847 -0.00181292 0.000183398 -0.000667607 -0.000750747 -0.000594314 -0.000433904 -0.000308985 -0.000217858 -0.000152926 -0.000107454 -7.54076e-05 -5.2675e-05 -3.66299e-05 -2.54341e-05 -1.75095e-05 -1.18848e-05 -7.97289e-06 -5.30239e-06 -3.53615e-06 -2.38504e-06 -2.40158e-06 -3.84485e-06 -5.29435e-06 -2.57099e-06 1.95189e-06 3.55083e-06 2.06179e-06 5.72753e-07 3.30469e-07 3.40296e-07 3.60221e-07 4.86081e-07 6.1194e-07 7.37799e-07 8.63659e-07 9.89518e-07 9.21274e-07 7.22275e-07 5.23276e-07 3.24277e-07 1.25278e-07 -5.59467e-08 -9.03265e-08 -1.24706e-07 -1.59086e-07 -1.93466e-07 -2.27846e-07 -2.62226e-07 -2.96605e-07 -3.30985e-07 -3.65365e-07 -3.99745e-07 -4.24266e-07 -3.82163e-07 -3.40061e-07 -2.97959e-07 -2.55857e-07 -2.13755e-07 -1.71652e-07 -1.2955e-07 -8.7448e-08 -4.53457e-08 -3.24353e-09 3.76901e-08 7.19937e-08 1.06297e-07 1.40601e-07 1.74904e-07 2.09208e-07 2.43512e-07 2.77815e-07 3.12119e-07 3.46422e-07 3.80726e-07 4.04507e-07 3.77191e-07 3.49876e-07 3.22561e-07 2.95246e-07 2.67931e-07 2.40616e-07 2.13301e-07 1.85986e-07 1.58671e-07 1.31356e-07 1.04041e-07 7.67256e-08 4.94105e-08 2.20955e-08 -5.21962e-09 -3.25347e-08 -5.98498e-08 -8.71649e-08 -1.1448e-07 -1.41795e-07 -1.6911e-07 7.87893e-06 0.0114592 -0.0245712 -0.111637 0.0961324 1.61168 3.22343 4.20442 4.53535 4.83834 4.95464 4.98874 4.99746 4.99883 4.99948 4.99815 4.98431 4.99298 4.99718 5.01948 5.04749 5.008 4.98243 4.98985 4.99781 4.99887 4.99679 4.99616 4.99743 4.99859 4.99936 4.99972 5.00058 5.00123 5.0002 4.99945 4.99983 4.9998 4.99966 4.99958 4.99956 4.99956 4.99956 4.99958 4.99961 4.99965 4.99969 4.99973 4.99977 4.9998 4.99983 4.99985 4.99987 4.99989 4.99991 4.99992 4.99993 4.99994 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.01454 4.99566 4.96796 4.99819 5.03232 5.00034 4.99867 4.99937 4.99977 4.99992 4.99997 4.99999 5.00001 5.00021 4.99974 4.98462 4.99301 4.99723 5.01936 5.04807 5.00929 4.9789 4.97876 4.98244 4.9863 4.99575 5.0069 5.00863 5.00624 5.00357 5.0019 5.00098 5.00048 5.00025 5.00016 5.00011 5.00013 5.00009 4.99982 4.99994 5.00005 4.99994 4.99988 4.99989 4.99997 5.00003 5.00005 5.00002 5.00001 5.00001 5.00001 4.99993 4.99999 5 5.00021 4.99997 4.99981 5 5.00009 5.0001 5.00001 4.99991 4.9999 5 5.00011 5.00017 5.00018 5.00018 5.00014 5.00007 4.99999 4.9999 4.9999 5.00001 5.00016 5.00014 4.99999 4.99993 4.99999 5.00009 5.00007 5.00006 5.00004 5.00003 5.00001 5.00001 5 4.99999 4.99998 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 } .graph element create V21 -x x -y v21 v22 set { 7.10441e-10 0.00107105 0.000637109 -0.00236346 -0.018079 -0.0120077 -0.00217059 0.00266679 0.00403383 0.00403836 0.00356705 0.00303303 0.00244716 0.00198586 0.0016855 0.00136497 -3.96022e-05 -0.000367409 -3.77079e-05 0.00194085 0.00506964 -0.0400214 -0.0402572 0.0524434 0.286234 0.803011 1.44795 2.02473 2.54768 3.02748 3.4415 3.78287 4.09667 4.35152 4.53987 4.67614 4.77407 4.84319 4.89227 4.92702 4.95119 4.96764 4.97846 4.98557 4.98982 4.99209 4.99371 4.99569 4.99727 4.99802 4.99834 4.99867 4.99892 4.99915 4.99936 4.99939 4.99943 4.99946 4.9995 4.99953 4.99957 4.9996 4.99963 4.99967 4.9997 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 4.9998 4.99981 4.99982 4.99983 4.99984 4.99985 4.99986 4.99986 4.99986 4.99987 4.99987 4.99988 4.99988 4.99989 4.99989 4.9999 4.9999 4.9999 4.9999 4.99991 4.99991 4.99991 4.99991 4.99992 4.99992 4.99992 4.99992 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 5.00145 5.00659 5.01209 5.01931 5.00279 4.99273 4.99217 4.99295 4.99471 4.99594 4.99696 4.9978 4.99844 4.99891 4.99924 4.99635 4.99699 4.99813 5.00068 5.00307 5.0588 4.96365 4.54012 3.6307 2.35176 1.0322 0.354379 0.115986 0.0435668 0.0245112 0.020786 0.0164656 0.0118409 0.00849698 0.00597078 0.0040105 0.0026076 0.0016597 0.00118185 0.00121067 0.00153587 0.00174836 0.00136519 -0.000189116 -0.00315555 -0.00646603 -0.00898042 -0.010203 -0.0110896 -0.0123764 -0.00953841 -0.00225795 0.000818314 0.00152252 0.00150269 0.00119025 0.000767068 0.000308852 -3.79272e-05 -0.00019691 -0.000186642 -9.73653e-05 -8.49784e-06 2.04147e-05 -9.91086e-06 -1.55959e-05 -1.80499e-05 -1.77097e-05 -1.51548e-05 -1.1978e-05 -9.84916e-06 -1.29728e-05 -1.67235e-05 -1.74153e-05 -1.39958e-05 -5.92272e-06 -8.08216e-06 -1.53077e-05 -2.92531e-05 -3.91049e-05 -2.98935e-05 -7.32122e-06 3.18534e-05 4.39134e-05 4.18753e-05 3.22759e-05 1.86766e-05 1.58432e-05 1.30098e-05 1.01765e-05 7.34312e-06 4.50975e-06 1.67639e-06 -1.15697e-06 -1.23877e-06 -1.11991e-06 -1.00106e-06 -8.82208e-07 -7.63355e-07 -6.44502e-07 -5.2565e-07 -4.29318e-07 -3.44661e-07 -2.60004e-07 -1.75347e-07 -9.06904e-08 -6.03349e-09 7.86234e-08 1.6328e-07 2.47937e-07 3.32594e-07 4.17251e-07 5.01908e-07 5.86565e-07 6.71222e-07 7.36123e-07 6.43886e-07 5.5165e-07 4.59414e-07 3.67178e-07 0.000334759 -4.60833e-05 -0.00106139 -0.00166624 0.000859563 0.00102606 0.00410037 0.00419931 0.00518997 0.00459791 0.00503125 0.00523877 0.00452158 0.00339924 0.00233399 0.000876915 0.000546439 0.000444299 0.000983968 0.00119304 -0.0429422 -0.0403983 0.0534896 0.288013 0.807345 1.44247 2.03448 2.57021 3.05049 3.47332 3.8131 4.1009 4.34677 4.53512 4.67127 4.76531 4.82526 4.86593 4.89586 4.91904 4.93806 4.95348 4.96597 4.97629 4.9843 4.98983 4.99335 4.9957 4.99741 4.99864 4.99946 4.99994 5.00047 5.00073 5.00086 5.00092 5.00094 5.00091 5.00087 5.00081 5.00074 5.00067 5.00059 5.00052 5.00046 5.0004 5.00034 5.0003 5.00026 5.00022 5.00019 5.00016 5.00014 5.00012 5.0001 5.00009 5.00007 5.00006 5.00006 5.00005 5.00004 5.00004 5.00004 5.00003 5.00003 5.00003 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 } .graph element create V22 -x x -y v22 v23 set { 5 5.00284 5.01266 5.01895 4.98936 4.99575 4.99217 4.99545 4.99775 4.99894 4.99946 4.99968 4.99975 4.99977 4.99986 4.9999 4.99528 4.99808 5.00039 5.00392 5.00512 4.99985 4.99863 4.99942 4.99992 5.00017 4.99897 4.99803 4.99784 4.99739 4.99883 5.00365 5.00298 5.00133 5.00048 5.00019 5.00008 5.00005 5.00004 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 4.99999 4.99997 4.99995 4.99996 4.99998 5 5.00001 5.00001 5.00002 5.00002 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5.00217 5.00108 4.99547 4.99658 5.00667 4.99641 4.99532 4.99938 5.00328 5.00222 5.00114 5.00052 5.00024 5.00011 5.00009 4.99285 4.99591 4.99897 5.00403 5.00786 5.00318 4.99942 4.9992 4.99949 5.001 5.00408 5.00319 5.00063 4.99995 5.00014 4.99982 4.99832 4.99838 4.99865 4.99912 4.99836 4.99735 4.99606 4.99814 5.00958 5.02973 5.05293 5.06103 4.99342 4.80726 4.50744 4.07509 3.41358 2.37924 1.03194 0.261552 0.142392 0.0904482 0.0555071 0.0322869 0.018289 0.0113802 0.00875182 0.00757055 0.00629906 0.00523 0.00403349 0.0031953 0.00280864 0.00286119 0.00250389 0.00202815 0.001723 0.00147312 0.0012411 0.00104401 0.000886204 0.000758277 0.000651915 0.00056348 0.000487966 0.000424048 0.000365613 0.000308178 0.000258725 0.000228061 0.000207976 0.000198491 0.00018518 0.000172716 0.000163197 0.000155007 0.000141734 0.000128461 0.000115188 0.000101915 8.86417e-05 7.53686e-05 6.20956e-05 5.69164e-05 5.23275e-05 4.77385e-05 4.31495e-05 3.85605e-05 3.39716e-05 2.93826e-05 2.69449e-05 2.56224e-05 2.42999e-05 2.29774e-05 2.16549e-05 2.03324e-05 1.90099e-05 1.76873e-05 1.63648e-05 1.50423e-05 1.37198e-05 1.23973e-05 1.10748e-05 9.75232e-06 8.48447e-06 7.65129e-06 6.81811e-06 5.98494e-06 5.15176e-06 0.00056893 -0.00787906 -0.0217381 -0.0370066 -0.00770505 0.00659312 0.00975477 0.00949456 0.00777552 0.00655645 0.00568776 0.00508782 0.00458121 0.00410187 0.00365665 0.0015121 0.00160863 0.00263181 0.00638941 0.00772607 0.00225583 0.0010843 0.000882939 0.000801563 0.00075632 0.000554992 0.000435131 0.0003474 0.000217667 0.000491602 0.0012267 0.00250446 0.000212058 -0.0174972 -0.0527527 -0.0479071 0.194908 1.45838 3.40677 4.49242 4.86894 4.97215 5.01218 5.04342 5.06228 5.03069 4.87169 4.57056 4.11523 3.38264 2.19691 0.715839 0.172818 0.102162 0.0627162 0.0363388 0.020289 0.0119414 0.00826608 0.0066417 0.00549092 0.00492505 0.00439443 0.0037156 0.00306471 0.00247451 0.00195965 0.0014822 0.0010815 0.000904464 0.0010514 0.00152308 0.00120752 0.000228447 -0.00102833 -0.00116644 -0.00042067 4.78758e-05 5.09599e-05 -4.45756e-05 -3.22966e-06 3.81163e-05 7.94622e-05 0.000120808 0.000162154 0.000161895 0.000148481 0.000135068 0.000121654 0.000108241 9.81453e-05 9.2164e-05 8.61827e-05 8.02014e-05 7.42201e-05 6.82388e-05 6.22576e-05 5.62763e-05 5.0295e-05 4.43137e-05 3.83324e-05 3.54323e-05 3.321e-05 3.09877e-05 2.87654e-05 2.65431e-05 2.43209e-05 2.20986e-05 1.98763e-05 1.7654e-05 1.54317e-05 1.34612e-05 1.25441e-05 1.1627e-05 1.07099e-05 9.79276e-06 8.87564e-06 7.95851e-06 7.04139e-06 6.12427e-06 } .graph element create V23 -x x -y v23 v24 set { 5 5.01099 5.00866 4.97845 4.92369 4.9273 4.97413 4.9929 4.99826 4.99958 4.99978 5.00005 4.99968 4.99959 5.00014 4.99979 4.99914 4.99982 5.00023 5.00295 5.00664 4.99854 4.99647 5.00438 5.01722 5.03681 5.04766 5.04799 5.04867 5.04873 5.04685 5.04413 5.0367 5.02505 5.01726 5.01183 5.00806 5.00549 5.00371 5.00246 5.00162 5.00105 5.00069 5.00045 5.00031 5.00024 5.00019 5.00012 5.00007 5.00004 5.00001 4.99998 4.99999 4.99999 5 5.00001 5.00001 5.00002 5.00002 5.00003 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5.00418 4.99953 4.99152 4.99807 5.00497 5.00112 5.00055 5.00038 5.00018 5.00006 5.00006 5.00007 5.00006 5.00004 5.00004 4.99853 4.99945 4.99998 5.00304 5.00935 5.00742 4.99181 4.97421 4.93603 4.8853 4.8927 4.93984 4.97458 4.99039 4.99614 4.99801 4.99851 4.99869 4.99924 5.00108 5.00181 5.00119 5.00059 5.00031 5.00022 5.00018 5.00011 5.00001 5.00006 4.99981 4.99977 4.99982 5.00012 4.99993 5.00008 5.00043 5.00048 5.00024 5.00008 4.99984 4.99993 5.00011 4.99996 4.9998 4.99977 4.9998 4.99993 5.00008 5.00011 5.00002 4.99995 4.99989 4.99993 5 5.00007 5.00009 4.99994 4.99977 4.9997 4.99975 4.99996 4.99996 4.99988 4.9997 4.99952 4.9995 4.99956 4.99973 4.99988 5.00005 5.00025 5.00042 5.00036 5.00031 5.00025 5.0002 5.00014 5.00009 5.00003 5.00002 5.00001 5.00001 5 4.99999 4.99998 4.99998 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5.00284 5.00442 5.00381 4.98997 4.99092 5.00733 5.07791 4.98237 4.86434 4.76835 4.74067 4.79278 4.85094 4.90068 4.93603 4.95698 4.96984 4.97856 4.98869 4.99904 5.0005 4.99524 5.00181 5.01878 5.05177 5.07986 4.98917 4.56217 3.68 2.3539 1.18541 0.505772 0.221044 0.115287 0.0760938 0.0589194 0.0476784 0.0457213 0.0412911 0.033889 0.0259741 0.0191452 0.0139018 0.0100235 0.00711788 0.00497657 0.00349368 0.00250021 0.00176179 0.00121843 0.000838368 0.000582711 0.000423458 0.000294608 0.000201251 0.000133748 8.6227e-05 5.44252e-05 3.30514e-05 1.93926e-05 1.09814e-05 5.29857e-06 1.92247e-06 3.08708e-07 -3.74311e-07 -6.11121e-07 -7.27807e-07 -4.87604e-07 -4.80493e-07 -9.15925e-07 -2.03774e-06 -4.01128e-06 -2.46644e-06 2.10626e-06 8.22422e-06 1.04922e-05 9.83047e-06 7.27106e-06 3.29654e-06 -2.06736e-06 -2.18019e-06 -2.29303e-06 -2.40586e-06 -2.51869e-06 -2.63153e-06 -2.24615e-06 -1.70325e-06 -1.16036e-06 -6.17468e-07 -7.45754e-08 2.45198e-07 2.88285e-07 3.31373e-07 3.7446e-07 4.17548e-07 4.60635e-07 5.03723e-07 5.4681e-07 5.89898e-07 6.32985e-07 6.76073e-07 6.19054e-07 5.4001e-07 4.60967e-07 3.81923e-07 3.02879e-07 2.23836e-07 1.44792e-07 6.57488e-08 -1.32948e-08 -9.23383e-08 -1.6698e-07 -2.23206e-07 -2.79432e-07 -3.35658e-07 -3.91884e-07 -4.48109e-07 -5.04335e-07 -5.60561e-07 -6.16787e-07 } .graph element create V24 -x x -y v24 v25 set { 1.34824 1.35838 1.36465 1.34675 1.29167 1.23161 1.2201 1.2185 1.2181 1.21798 1.21793 1.21788 1.21785 1.21782 1.21779 1.21776 1.21655 1.21656 1.21669 1.21871 1.22421 1.22247 1.21858 1.2228 1.23803 1.27737 1.10647 0.395248 0.0600669 0.027687 0.0192374 0.015425 0.0130881 0.00977445 0.00696598 0.00491122 0.00341952 0.00237078 0.00162339 0.00109178 0.000726647 0.000478886 0.00031568 0.000207902 0.000143494 0.000109768 8.62987e-05 5.69775e-05 3.36547e-05 2.30356e-05 1.86108e-05 1.41861e-05 1.08293e-05 7.68835e-06 4.79593e-06 4.51019e-06 4.22444e-06 3.9387e-06 3.65295e-06 3.36721e-06 3.04559e-06 2.69981e-06 2.35403e-06 2.00825e-06 1.66247e-06 1.34508e-06 1.26225e-06 1.17941e-06 1.09657e-06 1.01373e-06 9.30893e-07 8.48054e-07 7.65216e-07 6.82378e-07 5.9954e-07 5.16702e-07 4.37489e-07 3.82774e-07 3.2806e-07 2.73346e-07 2.18632e-07 1.63917e-07 1.09203e-07 5.4489e-08 -2.2523e-10 -5.49395e-08 -1.09654e-07 -1.52862e-07 -1.3079e-07 -1.08718e-07 -8.6646e-08 -6.45739e-08 -4.25019e-08 -2.04298e-08 1.64229e-09 2.37144e-08 4.57864e-08 6.78585e-08 8.71693e-08 9.30725e-08 9.89758e-08 1.04879e-07 1.10782e-07 1.16685e-07 1.22589e-07 1.28492e-07 1.34395e-07 1.40298e-07 1.46201e-07 1.52105e-07 1.58008e-07 1.63911e-07 1.69814e-07 1.75718e-07 1.81621e-07 1.87524e-07 1.93427e-07 1.9933e-07 2.05234e-07 2.11137e-07 2.19788e-07 0.000393944 -0.000218983 -0.00105784 0.00172403 -0.00027134 -0.000204147 8.79968e-06 5.93762e-05 5.83554e-05 4.13815e-05 3.71369e-05 3.03372e-05 2.25336e-05 1.5986e-05 1.07284e-05 -7.5239e-05 5.60593e-05 6.97571e-05 0.000667617 0.000960856 0.00131749 -0.00759564 -0.0217897 -0.0450321 -0.076646 -0.128569 -0.186391 -0.202175 -0.206953 -0.2082 -0.208416 -0.208669 -0.208934 -0.209111 -0.209234 -0.209329 -0.209389 -0.209416 -0.2094 -0.209329 -0.20926 -0.209204 -0.209208 -0.209285 -0.209454 -0.209641 -0.20977 -0.209811 -0.209833 -0.209887 -0.209653 -0.209127 -0.208893 -0.208811 -0.208777 -0.208758 -0.208747 -0.20874 -0.208726 -0.208697 -0.208657 -0.208611 -0.208565 -0.208524 -0.208488 -0.208451 -0.208412 -0.208373 -0.208333 -0.208294 -0.208256 -0.208219 -0.208183 -0.208145 -0.208107 -0.208066 -0.208029 -0.207993 -0.207959 -0.207923 -0.207883 -0.207838 -0.207789 -0.207747 -0.20771 -0.207675 -0.207642 -0.207605 -0.207568 -0.207531 -0.207494 -0.207457 -0.20742 -0.207383 -0.207346 -0.207308 -0.207271 -0.207233 -0.207196 -0.207158 -0.207121 -0.207084 -0.207046 -0.207009 -0.206972 -0.206935 -0.206898 -0.206861 -0.206823 -0.206786 -0.206749 -0.206712 -0.206675 -0.206638 -0.2066 -0.206563 -0.206526 -0.206489 -0.206452 -0.206415 -0.203384 -0.20015 -0.196872 -0.205024 -0.210727 -0.206779 -0.0685263 0.586138 1.4665 2.22945 2.77554 3.076 3.24926 3.34515 3.40164 3.43006 3.43713 3.43075 3.42886 3.4384 3.46567 3.49025 3.51287 3.53821 3.57841 3.39846 2.80753 2.22947 1.7549 1.30429 0.707786 0.303206 0.131352 0.0671706 0.0429955 0.032461 0.0257161 0.0239521 0.0217397 0.0179705 0.0138745 0.0102813 0.00749643 0.0054328 0.00386817 0.0027004 0.00189442 0.00135552 0.000954715 0.000659981 0.000453435 0.000313993 0.000231347 0.000159665 0.000108122 7.10528e-05 4.50233e-05 2.77892e-05 1.62765e-05 8.9893e-06 4.5471e-06 1.54614e-06 -1.6542e-07 -8.68508e-07 -1.04369e-06 -9.63086e-07 -8.44294e-07 -6.57339e-07 -7.35885e-07 -9.80056e-07 -1.39772e-06 -2.10199e-06 -1.37474e-06 6.13269e-07 3.3028e-06 4.60941e-06 4.91053e-06 4.14186e-06 2.45258e-06 -8.7388e-09 -3.59647e-07 -7.10554e-07 -1.06146e-06 -1.41237e-06 -1.76328e-06 -1.63073e-06 -1.34534e-06 -1.05995e-06 -7.74561e-07 -4.8917e-07 -2.95733e-07 -2.16326e-07 -1.3692e-07 -5.75135e-08 2.18929e-08 1.01299e-07 1.80706e-07 2.60112e-07 3.39519e-07 4.18925e-07 4.98332e-07 4.83984e-07 4.4901e-07 4.14035e-07 3.79061e-07 3.44087e-07 3.09112e-07 2.74138e-07 2.39163e-07 2.04189e-07 1.69215e-07 1.26002e-07 4.83213e-08 -2.9359e-08 -1.07039e-07 -1.8472e-07 -2.624e-07 -3.4008e-07 -4.1776e-07 -4.95441e-07 } .graph element create V25 -x x -y v25 v26 set { 7.10441e-10 0.000309731 -0.000308186 -0.001694 -0.00360784 8.40909e-05 0.00203175 0.0012896 0.000596548 0.000277191 0.000161134 0.000120439 8.4915e-05 9.49929e-05 6.18812e-05 1.65433e-05 1.89682e-05 3.97578e-05 4.95446e-05 0.000225325 0.000214579 -0.00230134 -0.000451102 0.00997237 0.0341443 0.0449314 0.0424411 0.0341996 0.0315315 0.0308892 0.0291614 0.024365 0.0190282 0.0188976 0.017238 0.0138526 0.0105645 0.00778548 0.00561753 0.0039871 0.00279554 0.00194075 0.0013468 0.000934775 0.000664723 0.000498911 0.000377384 0.000254183 0.000163421 0.000120773 9.65058e-05 7.22384e-05 5.60316e-05 4.14549e-05 2.79516e-05 2.57096e-05 2.34677e-05 2.12257e-05 1.89837e-05 1.67417e-05 1.46737e-05 1.27228e-05 1.07719e-05 8.82099e-06 6.87009e-06 5.0896e-06 4.71705e-06 4.34451e-06 3.97196e-06 3.59941e-06 3.22686e-06 2.85431e-06 2.48176e-06 2.10921e-06 1.73666e-06 1.36411e-06 1.02855e-06 9.42931e-07 8.57316e-07 7.71701e-07 6.86086e-07 6.00471e-07 5.14856e-07 4.29241e-07 3.43626e-07 2.58011e-07 1.72396e-07 9.85409e-08 9.14091e-08 8.42773e-08 7.71456e-08 7.00138e-08 6.2882e-08 5.57503e-08 4.86185e-08 4.14867e-08 3.4355e-08 2.72232e-08 2.05821e-08 1.63235e-08 1.2065e-08 7.80643e-09 3.54786e-09 -7.10696e-10 -4.96926e-09 -9.22782e-09 -1.34864e-08 -1.77449e-08 -2.20035e-08 -2.62621e-08 -3.05206e-08 -3.47792e-08 -3.90378e-08 -4.32963e-08 -4.75549e-08 -5.18134e-08 -5.6072e-08 -6.03306e-08 -6.45891e-08 -6.88477e-08 -8.76373e-06 0.000131607 -0.00021685 -0.000433027 0.00047234 0.000211593 -0.000189601 3.2492e-05 0.000575955 7.72235e-05 -0.000285172 -0.000242061 -0.000135112 -3.50117e-05 -2.75868e-05 5.48974e-05 1.80604e-07 5.48911e-05 3.97478e-05 0.000192909 0.000297932 0.00402253 -0.0122366 -0.047853 -0.0963082 -0.108071 -0.0567275 -0.0239271 -0.0178628 -0.0233027 -0.031853 -0.0400843 -0.0482725 -0.0576154 -0.0627218 -0.0511236 -0.0279524 -0.0150986 -0.00931091 -0.00652876 -0.00479286 -0.00344346 -0.00249578 -0.0019532 -0.00157977 -0.00131848 -0.00111251 -0.000939229 -0.000797445 -0.000708384 -0.000630452 -0.000539722 -0.000508862 -0.000480596 -0.000439484 -0.000407217 -0.000363866 -0.000329506 -0.000318642 -0.000307362 -0.000286511 -0.000266253 -0.000242943 -0.000218107 -0.000204661 -0.00020241 -0.000194435 -0.000185062 -0.000173042 -0.000160549 -0.000151407 -0.000145626 -0.000145976 -0.000147342 -0.000145288 -0.000137979 -0.000124481 -0.000123218 -0.000127453 -0.000139006 -0.000145486 -0.000129764 -9.82749e-05 -4.72596e-05 -3.08671e-05 -3.28834e-05 -4.52254e-05 -6.25389e-05 -6.32516e-05 -6.39643e-05 -6.4677e-05 -6.53897e-05 -6.61023e-05 -6.6815e-05 -6.75277e-05 -6.61005e-05 -6.45173e-05 -6.29341e-05 -6.13509e-05 -5.97676e-05 -5.81844e-05 -5.66012e-05 -5.54231e-05 -5.4455e-05 -5.3487e-05 -5.25189e-05 -5.15508e-05 -5.05828e-05 -4.96147e-05 -4.86466e-05 -4.76785e-05 -4.67105e-05 -4.57424e-05 -4.47743e-05 -4.38063e-05 -4.28382e-05 -4.18821e-05 -4.10211e-05 -4.016e-05 -3.9299e-05 -3.8438e-05 4.29885e-05 5.14113e-05 -0.000127986 -0.000611463 -0.000149428 0.000882394 0.00297059 -0.00405825 -0.00591067 -0.00546997 -0.00158744 0.00190677 0.00298403 0.00268595 0.00196161 0.00130289 0.000783347 0.000520683 0.000565306 0.00053419 -0.00224696 -0.000920818 0.0132755 0.0322504 0.0442808 0.0638615 0.0701007 0.0539356 0.0247771 0.056244 0.294266 0.831368 1.45424 2.02898 2.54559 2.9937 3.35333 3.72609 4.06363 4.32789 4.52413 4.66504 4.7652 4.83637 4.88631 4.92109 4.94464 4.96046 4.97218 4.98079 4.98679 4.99076 4.99361 4.99555 4.99686 4.99783 4.99853 4.99902 4.99936 4.99959 4.99973 4.99983 4.9999 4.99993 4.99996 4.99998 5 5.00001 5 4.99999 4.99997 4.99994 4.99993 4.99994 4.99996 4.99999 5.00004 5.00006 5.00005 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 } .graph element create V26 -x x -y v26 v27 set { 5 4.99984 4.99796 4.99478 4.9889 4.98738 4.98896 4.99087 4.99262 4.99419 4.99552 4.99659 4.99743 4.99807 4.99855 4.9989 4.99894 4.99908 4.99935 5.00001 5.0007 5.00132 5.00032 4.99976 5.00134 5.00339 5.00315 5.00157 5.00091 5.00058 5.00012 4.99944 4.99886 4.9994 4.99934 4.99899 4.99876 4.99868 4.99872 4.99883 4.99898 4.99914 4.9993 4.99944 4.99956 4.99967 4.99976 4.99982 4.99986 4.9999 4.99993 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00009 5.00028 5.00015 4.99983 5.00036 4.99996 4.99834 4.99783 5.00383 5.00734 5.00387 5.00058 4.99893 4.99836 4.99832 4.99854 4.99873 4.99905 4.99927 4.99952 4.99969 4.99834 4.99536 4.99163 4.99073 5.0053 5.03631 5.03103 4.9008 4.62503 4.21887 3.70902 3.09967 2.35791 1.41912 0.519675 0.210458 0.131362 0.0980819 0.0708209 0.0471701 0.0323272 0.0253535 0.0199144 0.0152615 0.0117228 0.00917696 0.00738117 0.00609292 0.00512664 0.00436184 0.0037961 0.00331639 0.00289006 0.0025477 0.00226529 0.00202925 0.00182793 0.00165474 0.00150531 0.00137529 0.00125983 0.00115603 0.00106455 0.000982977 0.000911255 0.000846819 0.000790092 0.000738698 0.000692816 0.00065107 0.000613595 0.000579642 0.000548935 0.00052106 0.000495598 0.000472174 0.000450849 0.000431118 0.000412667 0.000395868 0.000381319 0.000368487 0.000357327 0.000344212 0.000330334 0.00031622 0.000303298 0.000295809 0.00028832 0.000280831 0.000273342 0.000265853 0.000258364 0.000250875 0.000245118 0.000239488 0.000233857 0.000228227 0.000222596 0.000216966 0.000211336 0.000207047 0.000203455 0.000199863 0.00019627 0.000192678 0.000189085 0.000185493 0.0001819 0.000178308 0.000174716 0.000171123 0.000167531 0.000163938 0.000160346 0.000156835 0.000153973 0.00015111 0.000148248 0.000145385 0.000296579 -3.96718e-05 -0.000449085 0.000323433 0.000750086 0.000268264 0.000149028 -0.000100249 7.00956e-05 0.00012605 0.00022592 0.000193036 0.000120453 8.07865e-05 7.65771e-05 -3.27828e-05 0.000116759 0.000169498 0.000409804 0.000414965 0.00092323 -0.00590633 -0.0175477 -0.032433 -0.0559842 -0.0820373 0.0688484 0.626629 1.32929 2.01657 2.60925 3.12329 3.38952 3.14128 2.38463 1.23802 0.316019 0.107832 0.0694707 0.051837 0.035247 0.0209999 0.0116618 0.00967674 0.00789182 0.00574566 0.00386872 0.00258612 0.00167126 0.00104169 0.000641093 0.000401246 0.000277928 0.000171775 0.000102266 5.89376e-05 3.29258e-05 1.80463e-05 1.0057e-05 6.4571e-06 5.10093e-06 4.06791e-06 3.62716e-06 3.63321e-06 3.99625e-06 4.64368e-06 5.20886e-06 4.77728e-06 3.23919e-06 1.14113e-06 -1.29416e-06 -4.15607e-06 -1.88532e-06 5.24411e-06 1.38678e-05 1.28823e-05 3.6758e-06 -2.52285e-06 -3.97133e-06 -4.03071e-06 -3.37154e-06 -2.71238e-06 -2.05321e-06 -1.39404e-06 -7.34872e-07 -3.73325e-07 -1.05873e-07 1.61578e-07 4.2903e-07 6.96482e-07 8.18468e-07 7.60065e-07 7.01662e-07 6.43258e-07 5.84855e-07 5.26452e-07 4.68049e-07 4.09646e-07 3.51243e-07 2.9284e-07 2.34437e-07 1.71213e-07 1.06928e-07 4.2644e-08 -2.16403e-08 -8.59247e-08 -1.50209e-07 -2.14493e-07 -2.78778e-07 -3.43062e-07 -4.07346e-07 -4.55065e-07 -4.3348e-07 -4.11896e-07 -3.90311e-07 -3.68726e-07 -3.47141e-07 -3.25556e-07 -3.03971e-07 -2.82386e-07 } .graph element create V27 -x x -y v27 v28 set { 0.368163 0.361756 0.327463 0.269513 0.149476 0.0805716 0.0501146 0.03403 0.0230886 0.0160474 0.0116071 0.00870013 0.00679614 0.00542384 0.00432512 0.00340653 -0.00129719 -0.00399429 -0.00318719 0.00443085 0.0150156 0.0334147 0.0132288 -0.0189751 -0.0508377 -0.0252174 -0.0142489 -0.00675908 -0.0038653 -0.00243423 -0.00168891 -0.00120901 -0.000900426 -0.000685575 -0.000557595 -0.000457268 -0.000377427 -0.000315269 -0.000266613 -0.000228397 -0.000198283 -0.000174248 -0.000154886 -0.00013892 -0.000125864 -0.000115189 -0.000105841 -9.66611e-05 -8.84262e-05 -8.23872e-05 -7.74668e-05 -7.25463e-05 -6.79992e-05 -6.35276e-05 -5.92413e-05 -5.68994e-05 -5.45574e-05 -5.22154e-05 -4.98735e-05 -4.75315e-05 -4.54981e-05 -4.36726e-05 -4.18471e-05 -4.00216e-05 -3.81961e-05 -3.64559e-05 -3.54209e-05 -3.43858e-05 -3.33508e-05 -3.23157e-05 -3.12807e-05 -3.02456e-05 -2.92105e-05 -2.81755e-05 -2.71404e-05 -2.61054e-05 -2.51232e-05 -2.44984e-05 -2.38736e-05 -2.32487e-05 -2.26239e-05 -2.19991e-05 -2.13742e-05 -2.07494e-05 -2.01246e-05 -1.94998e-05 -1.88749e-05 -1.82865e-05 -1.79044e-05 -1.75224e-05 -1.71403e-05 -1.67582e-05 -1.63762e-05 -1.59941e-05 -1.56121e-05 -1.523e-05 -1.4848e-05 -1.44659e-05 -1.41138e-05 -1.39075e-05 -1.37011e-05 -1.34947e-05 -1.32883e-05 -1.30819e-05 -1.28755e-05 -1.26691e-05 -1.24627e-05 -1.22563e-05 -1.205e-05 -1.18436e-05 -1.16372e-05 -1.14308e-05 -1.12244e-05 -1.1018e-05 -1.08116e-05 -1.06052e-05 -1.03988e-05 -1.01924e-05 -9.98605e-06 -9.77966e-06 -2.85319e-05 0.00281092 0.00180106 -0.000981083 0.00551926 -0.00119763 -0.0295069 -0.0367677 0.064749 0.119022 0.0882007 0.0552062 0.03418 0.0223243 0.015545 0.011949 0.00757134 0.00667655 0.00583243 0.00644443 0.00650959 -0.0302575 -0.0437806 -0.0355466 0.0381776 0.282109 0.674178 1.07582 1.45189 1.789 2.08649 2.34663 2.57245 2.81211 3.04778 3.2523 3.45877 3.65593 3.83396 3.9923 4.13368 4.25864 4.36719 4.46064 4.54086 4.60962 4.66835 4.71838 4.76094 4.79716 4.82796 4.85413 4.87634 4.89518 4.91116 4.92476 4.93631 4.94608 4.95434 4.9613 4.96715 4.97211 4.97638 4.98001 4.98312 4.98571 4.98795 4.98979 4.99138 4.99269 4.99381 4.99474 4.99551 4.99615 4.99668 4.99713 4.99752 4.99783 4.99811 4.99836 4.99858 4.99873 4.99884 4.99892 4.999 4.99907 4.99912 4.99916 4.99921 4.99926 4.99932 4.99937 4.99942 4.99948 4.99953 4.99956 4.99958 4.99961 4.99963 4.99966 4.99968 4.99971 4.99972 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 4.99979 4.9998 4.9998 4.99981 4.99982 4.99983 4.99984 4.99985 4.99986 4.99986 4.99987 4.99987 5.00498 5.00354 4.99359 4.98981 5.00498 5.00099 5.00041 5.00022 5.00015 5.00012 5.0001 5.00008 5.00005 5.00003 5 4.99431 4.99459 4.99591 5.00087 5.01029 5.03935 4.92784 4.51643 3.78356 2.68745 1.43417 0.583128 0.205094 0.0777337 0.0391566 0.02723 0.023883 0.018808 0.010165 0.00254623 -0.00377463 -0.0038097 0.00144145 0.00267231 0.00193045 0.00144538 0.00121758 0.00112893 0.00109424 0.0010226 0.000948072 0.000882573 0.000826996 0.000776391 0.000729719 0.000686499 0.000647333 0.000610108 0.000575631 0.000545069 0.000515485 0.000488514 0.000465316 0.000443215 0.000422454 0.00040292 0.00038488 0.000368472 0.000353628 0.000339643 0.000326197 0.000313483 0.000302884 0.000294038 0.000284003 0.000270941 0.000254925 0.000246511 0.000244089 0.000245538 0.000242099 0.000235728 0.000227482 0.000218001 0.000207257 0.000202127 0.000196997 0.000191868 0.000186738 0.000181608 0.00017758 0.000173899 0.000170219 0.000166538 0.000162857 0.000159576 0.00015679 0.000154005 0.000151219 0.000148433 0.000145647 0.000142861 0.000140076 0.00013729 0.000134504 0.000131718 0.000129603 0.000127635 0.000125668 0.0001237 0.000121732 0.000119765 0.000117797 0.000115829 0.000113862 0.000111894 0.000109993 0.000108372 0.000106751 0.00010513 0.000103509 0.000101887 0.000100266 9.86449e-05 9.70237e-05 } .graph element create V28 -x x -y v28 v29 set { 5 4.99899 4.99654 4.99327 4.9863 4.98954 4.99212 4.99378 4.9951 4.99624 4.99715 4.99786 4.99839 4.99879 4.99909 4.99931 4.99922 4.99933 4.99971 5.00064 5.00084 5.00123 4.99865 4.99853 4.99983 5.00457 5.00242 5.00105 5.00062 5.00042 4.99971 4.9994 4.9992 4.9996 4.99955 4.99932 4.99918 4.99915 4.99919 4.99927 4.99937 4.99948 4.99957 4.99966 4.99974 4.9998 4.99985 4.99989 4.99992 4.99993 4.99994 4.99994 4.99996 4.99998 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.9997 4.99998 4.99954 4.99963 5.00059 4.99945 4.99732 4.99957 5.00919 5.00558 5.00033 4.99851 4.9983 4.99854 4.99871 4.99928 4.99914 4.99939 4.99952 4.9998 4.99976 4.99744 4.99598 4.99478 4.99806 5.01911 5.04602 5.05469 5.01317 4.89484 4.69655 4.42036 4.06069 3.60793 3.12531 2.72975 2.45187 2.25081 2.09841 1.98509 1.90211 1.84084 1.79411 1.7574 1.72763 1.70283 1.68188 1.66389 1.64823 1.63438 1.62201 1.61088 1.60081 1.59163 1.58323 1.57549 1.56835 1.56173 1.55558 1.54985 1.54451 1.53951 1.53479 1.53035 1.52615 1.5222 1.51845 1.5149 1.51153 1.50834 1.50529 1.5024 1.49964 1.497 1.49449 1.49208 1.48977 1.48755 1.48542 1.48336 1.48138 1.47948 1.47765 1.4759 1.47419 1.47255 1.47096 1.46949 1.46823 1.46696 1.4657 1.46444 1.46317 1.46191 1.46065 1.45956 1.4585 1.45743 1.45636 1.45529 1.45422 1.45315 1.45226 1.45145 1.45064 1.44983 1.44902 1.44821 1.4474 1.44659 1.44579 1.44498 1.44417 1.44336 1.44255 1.44174 1.44094 1.44019 1.43944 1.43868 1.43793 1.43765 1.43679 1.43515 1.43405 1.43478 1.43387 1.43345 1.43184 1.43086 1.43021 1.43003 1.42988 1.42944 1.42883 1.42818 1.42702 1.42642 1.42595 1.42586 1.42616 1.42783 1.41733 1.38106 1.30738 1.3877 2.09819 3.05285 3.58059 3.77601 3.87609 4.02557 4.24887 4.4608 4.60411 4.72109 4.8255 4.90465 4.97379 5.01253 5.01532 5.01239 5.0092 5.00665 5.00474 5.00333 5.00232 5.00163 5.00117 5.00082 5.00057 5.00039 5.00027 5.00019 5.00013 5.00009 5.00006 5.00004 5.00003 5.00002 5.00001 5.00001 5 5 5 4.99998 4.99995 4.99992 4.99996 5.00005 5.00012 5.00008 4.99996 4.9999 4.99985 4.99986 4.99997 5.00021 5.0003 5.00024 5.00009 5.00007 5.00005 5.00003 5.00001 4.99998 4.99998 4.99998 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } .graph element create V29 -x x -y v29 v30 set { 7.10441e-10 5.70385e-05 0.000226143 0.000131916 -0.000887764 -8.01837e-05 -3.49653e-05 9.40039e-05 0.000118663 0.000108025 8.6059e-05 6.33268e-05 4.99295e-05 3.16843e-05 3.60692e-05 2.07572e-05 -8.6375e-05 3.44583e-05 8.07397e-05 0.000196296 0.000115615 -7.12768e-05 -0.000129812 -4.18679e-05 7.94364e-05 0.000182034 -5.41226e-05 -0.000451819 -0.000713937 -0.00129863 -0.00262186 -0.00213417 -0.00133767 0.000775698 0.000969902 0.000549281 0.000280946 0.000140321 8.6919e-05 7.22446e-05 6.5631e-05 6.45263e-05 6.63087e-05 7.17391e-05 7.59042e-05 7.59172e-05 7.03353e-05 6.33558e-05 5.31136e-05 4.64278e-05 4.40594e-05 4.16909e-05 4.05674e-05 3.96957e-05 3.87875e-05 3.74977e-05 3.62079e-05 3.49181e-05 3.36283e-05 3.23385e-05 3.12427e-05 3.02775e-05 2.93124e-05 2.83472e-05 2.7382e-05 2.64613e-05 2.59077e-05 2.5354e-05 2.48004e-05 2.42468e-05 2.36931e-05 2.31395e-05 2.25859e-05 2.20322e-05 2.14786e-05 2.0925e-05 2.03916e-05 1.9995e-05 1.95984e-05 1.92019e-05 1.88053e-05 1.84087e-05 1.80122e-05 1.76156e-05 1.7219e-05 1.68225e-05 1.64259e-05 1.6051e-05 1.57991e-05 1.55471e-05 1.52952e-05 1.50433e-05 1.47913e-05 1.45394e-05 1.42875e-05 1.40356e-05 1.37836e-05 1.35317e-05 1.32978e-05 1.31513e-05 1.30048e-05 1.28583e-05 1.27118e-05 1.25653e-05 1.24188e-05 1.22724e-05 1.21259e-05 1.19794e-05 1.18329e-05 1.16864e-05 1.15399e-05 1.13934e-05 1.12469e-05 1.11005e-05 1.0954e-05 1.08075e-05 1.0661e-05 1.05145e-05 1.0368e-05 1.02215e-05 1.76447e-05 7.21516e-05 -3.59786e-05 -0.000159618 0.000156236 0.000135106 -0.000336402 -0.000302283 0.000699323 0.000473866 -0.000156146 -0.000225625 -0.000123592 -3.78116e-05 8.47472e-06 2.43387e-06 -7.44762e-05 7.80111e-05 9.43608e-05 0.000170159 8.83919e-05 -0.00018802 -0.000373512 -0.000390597 0.000156875 0.0032343 0.00776304 -0.000566905 -0.00760695 -0.0159226 -0.0245989 -0.0331402 -0.0100902 0.067837 0.266702 0.910818 1.82282 2.69714 3.43247 3.98325 4.32893 4.51529 4.67087 4.79288 4.87574 4.92797 4.95902 4.97655 4.98622 4.99195 4.99526 4.99735 4.9991 4.99974 4.99982 4.99974 4.99961 4.9995 4.99943 4.9994 4.9994 4.99942 4.99944 4.99948 4.99952 4.99956 4.99961 4.99965 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 4.99988 4.9999 4.99991 4.99992 4.99993 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00019 4.99888 4.99663 4.99457 4.99902 5.00229 5.00323 5.00302 5.0023 5.0015 5.00085 5.00041 5.00013 4.99993 4.99979 4.99948 4.99954 4.99983 5.00055 5.00109 5.00009 4.9987 4.998 4.99755 4.99676 4.99618 5.01091 5.05272 5.04156 4.80112 4.27692 3.42343 2.23953 0.967179 0.429813 0.540757 1.32991 2.32147 3.14903 3.78143 4.22325 4.47978 4.59448 4.69875 4.79798 4.87419 4.92339 4.95249 4.97174 4.98408 4.99124 4.99478 4.99729 4.99868 4.9992 4.99941 4.99947 4.99946 4.99943 4.9994 4.99939 4.9994 4.99942 4.99946 4.99951 4.99956 4.99961 4.99967 4.99973 4.99977 4.9998 4.99981 4.99983 4.99984 4.99987 4.99992 5.00001 5.00005 5.00001 4.99994 4.99995 4.99995 4.99996 4.99996 4.99996 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } .graph element create V30 -x x -y v30 v31 set { 1.8179e-09 -5.28841e-06 -1.44913e-05 -3.62932e-05 -9.75719e-05 0.000141781 3.73396e-05 -1.65603e-05 -1.5271e-05 -6.73884e-06 4.40157e-06 -4.85345e-06 -1.02964e-05 2.03126e-05 -1.89457e-05 -8.75564e-06 7.67422e-06 4.71103e-06 1.29798e-05 6.13469e-06 -1.14363e-05 -0.0394563 -0.0477298 -0.0622012 -0.0519225 0.262499 0.943611 1.67052 2.31017 2.84028 3.28467 3.61582 3.85887 4.13011 4.36511 4.54063 4.67013 4.76408 4.83263 4.8825 4.91837 4.94373 4.96117 4.97318 4.98093 4.98562 4.98906 4.99267 4.99539 4.99666 4.99731 4.99797 4.99844 4.99887 4.99927 4.99933 4.99938 4.99944 4.99949 4.99955 4.9996 4.99965 4.9997 4.99975 4.9998 4.99985 4.99986 4.99987 4.99989 4.9999 4.99991 4.99992 4.99993 4.99995 4.99996 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99997 5.00002 5.00004 5.0001 5.0001 4.99987 5.00009 5.00021 5.00002 5.00004 4.99988 5.00013 4.99993 5.00026 4.99973 5 5.00006 5.00009 5.00004 5.00004 5.04854 4.82711 4.04208 2.64155 0.838902 0.19014 0.0982549 0.0723197 0.0576863 0.0427644 0.0301979 0.020146 0.0135728 0.00980358 0.00774482 0.00586604 0.0036687 0.00211511 0.00121906 0.000647581 0.000828436 0.00190938 0.00224254 0.00199956 0.00165488 0.00135612 0.00113715 0.000984181 0.000877175 0.000789973 0.000741139 0.000689338 0.000625676 0.000586082 0.000550152 0.000529573 0.000505606 0.000482117 0.000460574 0.000441649 0.000424674 0.000408398 0.000391914 0.000376272 0.000361487 0.000348181 0.000336045 0.000324466 0.000313545 0.000303046 0.000293056 0.00028356 0.000274586 0.000266155 0.000258279 0.000250938 0.000243789 0.000236912 0.000230244 0.000224186 0.000219291 0.000215346 0.000212468 0.000207291 0.000200862 0.00019368 0.000186767 0.000183515 0.000180263 0.00017701 0.000173758 0.000170506 0.000167253 0.000164001 0.000161164 0.000158357 0.00015555 0.000152743 0.000149936 0.000147129 0.000144322 0.000142066 0.000140096 0.000138127 0.000136157 0.000134187 0.000132218 0.000130248 0.000128278 0.000126308 0.000124339 0.000122369 0.000120399 0.000118429 0.00011646 0.000114527 0.000112892 0.000111258 0.000109623 0.000107988 0.000103598 6.86052e-05 3.337e-05 7.00783e-05 0.000218764 0.000221318 0.000118593 -0.000113962 5.78552e-05 9.42068e-05 0.000237037 0.000171302 0.0001033 6.16066e-05 5.52908e-05 6.30233e-05 7.01897e-05 8.48573e-05 0.000106859 8.37213e-05 -0.0391541 -0.047722 -0.0618454 -0.0169804 0.345725 1.03426 1.74825 2.37152 2.88737 3.32173 3.66761 3.9707 4.17762 3.98832 3.30483 2.09737 0.710892 0.148159 0.0707463 0.0555808 0.045618 0.0319116 0.0199589 0.0133357 0.00898528 0.00586075 0.00375478 0.00245443 0.00156038 0.000962344 0.000590953 0.000375107 0.000250243 0.00015882 0.000100203 6.18122e-05 3.7372e-05 2.23009e-05 1.32569e-05 8.29437e-06 5.72457e-06 3.96832e-06 2.98935e-06 2.59699e-06 2.75024e-06 3.38689e-06 4.0453e-06 3.50095e-06 1.64988e-06 -3.84371e-07 -2.03828e-06 -3.46401e-06 -1.24301e-06 4.63458e-06 1.14104e-05 1.02619e-05 2.15487e-06 -2.98487e-06 -3.67221e-06 -2.94279e-06 -2.58649e-06 -2.23019e-06 -1.87389e-06 -1.5176e-06 -1.1613e-06 -7.92127e-07 -4.18889e-07 -4.56502e-08 3.27588e-07 7.00827e-07 8.79539e-07 8.17025e-07 7.5451e-07 6.91996e-07 6.29481e-07 5.66966e-07 5.04452e-07 4.41937e-07 3.79422e-07 3.16908e-07 2.54393e-07 1.90078e-07 1.25366e-07 6.0654e-08 -4.05776e-09 -6.87696e-08 -1.33481e-07 -1.98193e-07 -2.62905e-07 -3.27617e-07 -3.92329e-07 -4.40392e-07 -4.18802e-07 -3.97213e-07 -3.75624e-07 -3.54035e-07 -3.32446e-07 -3.10856e-07 -2.89267e-07 -2.67678e-07 } .graph element create V31 -x x -y v31 v32 set { 1.10294 1.10297 1.10291 1.10277 1.10259 1.10294 1.10313 1.10306 1.10299 1.10296 1.10295 1.10295 1.10294 1.10294 1.10294 1.10294 1.10294 1.10294 1.10294 1.10296 1.10296 1.00547 0.998599 1.5201 2.49297 3.31258 3.73162 3.84757 3.92505 4.02965 4.16599 4.30294 4.41541 4.52886 4.64414 4.73865 4.81065 4.86391 4.90315 4.93188 4.95258 4.96726 4.97738 4.98436 4.98888 4.99162 4.99363 4.99573 4.99731 4.99804 4.99843 4.99881 4.99909 4.99934 4.99957 4.9996 4.99964 4.99967 4.9997 4.99973 4.99977 4.9998 4.99983 4.99986 4.99988 4.99991 4.99992 4.99992 4.99993 4.99994 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5.00028 4.99988 4.99968 5.00019 4.99987 5.00021 4.99973 4.99977 4.99996 4.99997 5.0002 4.99957 5.00026 4.99947 5.00074 5.00003 4.99987 4.99979 5.00008 4.99997 5.08794 5.05993 4.76875 3.99197 3.10174 2.5197 2.21771 2.04 1.92235 1.83874 1.77592 1.72665 1.686 1.65276 1.6286 1.61299 1.60039 1.58934 1.57954 1.57083 1.56306 1.55604 1.54963 1.54375 1.53832 1.53331 1.52865 1.52432 1.52026 1.51645 1.51287 1.50949 1.50629 1.50327 1.50039 1.49766 1.49505 1.49257 1.49019 1.48792 1.48574 1.48365 1.48164 1.47971 1.47784 1.47604 1.47431 1.47264 1.47102 1.46945 1.46794 1.46647 1.46505 1.46367 1.46233 1.46103 1.45976 1.45853 1.45733 1.45616 1.45502 1.45392 1.45284 1.45179 1.45076 1.44975 1.4488 1.44795 1.44711 1.44626 1.44541 1.44457 1.44372 1.44287 1.44212 1.44138 1.44063 1.43989 1.43914 1.4384 1.43766 1.43701 1.43641 1.43581 1.43522 1.43462 1.43402 1.43342 1.43282 1.43223 1.43163 1.43103 1.43043 1.42984 1.42924 1.42865 1.42808 1.42752 1.42695 1.42639 1.42584 1.42529 1.42472 1.42412 1.42365 1.42326 1.42304 1.42162 1.42082 1.42032 1.42029 1.42026 1.41995 1.41947 1.41894 1.41841 1.4179 1.41742 1.41699 1.41656 1.32097 1.30963 1.78765 2.64656 3.35764 3.747 3.86589 3.94217 4.04185 4.18453 4.3561 4.53439 4.68621 4.74905 4.77848 4.84629 4.91261 4.97541 5.01284 5.01548 5.01248 5.00924 5.00666 5.00475 5.00334 5.00234 5.00164 5.00118 5.00083 5.00058 5.0004 5.00028 5.00019 5.00013 5.00009 5.00007 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5 5 4.99999 4.99995 4.99992 4.99996 5.00006 5.00012 5.00009 4.99997 4.9999 4.99985 4.99986 4.99997 5.00021 5.00031 5.00024 5.0001 5.00007 5.00005 5.00003 5.00001 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } .graph element create V32 -x x -y v32 v33 set { 5 5.00012 5.00023 5.0003 4.99972 4.99988 4.99984 4.99991 4.99996 4.99999 5.00008 5.00009 4.99986 5.00003 5.00007 4.99995 4.9999 4.99997 5.00013 5.00014 5.00013 4.99701 4.99763 4.99742 4.99998 5.02836 5.07262 4.96856 4.57267 3.85637 2.79544 1.45942 0.408016 0.084885 0.0271375 0.0119294 0.00707546 0.0051087 0.00373035 0.00264737 0.00186477 0.00130379 0.000915857 0.000653121 0.000483893 0.000380852 0.000302362 0.000219498 0.000154435 0.000121928 0.000104026 8.61242e-05 7.48526e-05 6.49216e-05 5.56238e-05 5.29689e-05 5.03139e-05 4.7659e-05 4.5004e-05 4.23491e-05 4.00356e-05 3.79522e-05 3.58687e-05 3.37852e-05 3.17018e-05 2.97592e-05 2.89804e-05 2.82016e-05 2.74228e-05 2.66441e-05 2.58653e-05 2.50865e-05 2.43077e-05 2.35289e-05 2.27501e-05 2.19714e-05 2.12346e-05 2.07821e-05 2.03295e-05 1.98769e-05 1.94244e-05 1.89718e-05 1.85192e-05 1.80667e-05 1.76141e-05 1.71615e-05 1.6709e-05 1.62828e-05 1.60061e-05 1.57294e-05 1.54527e-05 1.5176e-05 1.48993e-05 1.46226e-05 1.43459e-05 1.40692e-05 1.37925e-05 1.35158e-05 1.3262e-05 1.31191e-05 1.29761e-05 1.28332e-05 1.26903e-05 1.25474e-05 1.24045e-05 1.22615e-05 1.21186e-05 1.19757e-05 1.18328e-05 1.16898e-05 1.15469e-05 1.1404e-05 1.12611e-05 1.11182e-05 1.09752e-05 1.08323e-05 1.06894e-05 1.05465e-05 1.04036e-05 1.02606e-05 1.00185e-05 3.8343e-05 -3.06781e-05 -0.000111758 0.000111673 0.000130815 -0.000210491 -0.000231304 0.000310226 0.000265303 3.0878e-05 -4.48405e-05 -1.2852e-05 -7.84469e-06 3.29986e-05 -1.23286e-05 -6.07871e-05 5.35082e-05 7.69194e-05 0.000126221 6.57178e-05 0.00223349 -0.0148854 -0.0476636 -0.0491447 0.220125 1.11174 2.03988 2.90209 3.61069 4.13554 4.50679 4.71501 4.83916 4.91027 4.95284 4.98086 4.99151 4.98651 4.97113 4.95075 4.93102 4.93683 4.95457 4.97071 4.98212 4.98948 4.99386 4.99636 4.99785 4.9987 4.99927 4.99989 5.00014 5.00007 4.99988 4.99982 4.99976 4.99973 4.99972 4.99972 4.99973 4.99974 4.99975 4.99977 4.99979 4.99981 4.99984 4.99986 4.99988 4.99989 4.99991 4.99992 4.99993 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00012 4.99946 4.99839 4.99733 4.99948 5.00114 5.00158 5.00147 5.00113 5.00073 5.00043 5.0002 5.00006 4.99995 4.99986 4.99973 4.99976 4.9999 5.00029 5.00055 4.99704 4.99734 4.9972 5.00278 5.03354 5.07184 4.94057 4.51936 3.75638 2.60982 1.23803 0.315016 0.0796102 0.0252894 0.0165723 0.0827785 0.491298 1.40686 2.33436 3.1251 3.7691 4.22201 4.49976 4.68115 4.80513 4.88509 4.93208 4.95861 4.97579 4.98655 4.99268 4.99571 4.99771 4.99881 4.99929 4.99954 4.99965 4.9997 4.99971 4.99971 4.99971 4.99971 4.99972 4.99974 4.99976 4.99978 4.99981 4.99984 4.99987 4.99989 4.99991 4.99991 4.99992 4.99992 4.99993 4.99997 5.00003 5.00006 5.00004 5.00001 5 4.99999 4.99998 4.99998 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 } .graph element create V33 -x x -y v33 v34 set { 5 5.00207 5.00813 5.01486 5.00156 5.0018 4.99861 4.99844 4.99888 4.9993 4.99956 4.99971 4.99979 4.99983 4.99987 4.99989 4.99671 4.9974 4.99864 5.00131 5.00377 5.0021 5.00039 4.99993 5.00004 5.0009 5.00109 4.99636 4.98617 4.96778 4.92047 4.89528 4.91112 4.9559 4.98286 4.99369 4.99812 4.99951 4.99994 5.00014 5.00008 4.99994 4.99984 4.99989 4.99998 5.00004 5.00004 5.00006 5.00005 5.00001 4.99997 4.99992 4.99993 4.99994 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 5.00131 5.00072 4.9977 4.99811 5.00325 4.99647 4.98948 4.99459 5.00262 5.00276 5.00156 5.00072 5.0003 5.00013 4.99995 4.99668 4.99775 4.99917 5.00173 5.00386 5.00188 4.99888 4.99757 4.99951 5.01712 5.0557 5.07088 5.07704 5.07758 5.06958 5.04223 5.03331 5.0279 5.03408 5.07611 5.01911 4.68594 3.99152 2.92195 1.69878 0.809 0.344091 0.154663 0.0788717 0.0467212 0.0336168 0.0280514 0.0254947 0.024173 0.0223567 0.0220555 0.0271514 0.0295872 0.0296052 0.0283971 0.0264726 0.0241813 0.0218244 0.0195349 0.017368 0.0152495 0.013295 0.0115444 0.00996982 0.00857091 0.00733891 0.00627261 0.0053494 0.00456316 0.00388373 0.00331073 0.00282181 0.00240991 0.00206389 0.00177187 0.00152283 0.00131167 0.00112558 0.000954373 0.000805726 0.00069326 0.000600991 0.000525743 0.00047355 0.00044359 0.000434815 0.000436053 0.000402511 0.000368969 0.000335427 0.000301886 0.000268344 0.000234802 0.00020126 0.000184967 0.000169932 0.000154896 0.000139861 0.000124825 0.00010979 9.47546e-05 8.67896e-05 8.24901e-05 7.81906e-05 7.38911e-05 6.95915e-05 6.5292e-05 6.09925e-05 5.66929e-05 5.23934e-05 4.80939e-05 4.37943e-05 3.94948e-05 3.51953e-05 3.08957e-05 2.67968e-05 2.42936e-05 2.17904e-05 1.92872e-05 1.6784e-05 0.00125927 -0.00794344 -0.0305499 -0.0621697 -0.0463796 -0.0224608 -0.00538381 0.00546086 0.0108675 0.012883 0.0131787 0.0127271 0.0119702 0.0110398 0.0100635 0.00649617 0.00489388 0.00545863 0.0098351 0.0167428 0.0126563 0.00697542 0.00427027 0.00330002 0.00390774 0.00408999 -0.00259143 -0.0160578 -0.0451849 -0.0409651 0.1301 0.597429 1.3848 2.63426 3.81272 4.51373 4.8412 4.98731 4.88165 4.37165 3.40034 2.17681 1.12217 0.505129 0.219703 0.104992 0.0622333 0.0448317 0.0355782 0.0311867 0.0293529 0.0274615 0.0288739 0.0307845 0.0304909 0.029245 0.0273602 0.0251006 0.022697 0.0202765 0.0179357 0.0157106 0.0136562 0.0117951 0.0101273 0.00865784 0.00739394 0.00634364 0.00551356 0.00480538 0.00415747 0.00356084 0.00297585 0.00236711 0.00181853 0.00160713 0.00169822 0.00166542 0.00145504 0.00120252 0.00109259 0.000982658 0.00087273 0.000762802 0.000652874 0.000584068 0.000528263 0.000472458 0.000416653 0.000360848 0.000321155 0.000301442 0.000281729 0.000262016 0.000242303 0.00022259 0.000202877 0.000183164 0.000163451 0.000143738 0.000124025 0.000114582 0.000107399 0.000100216 9.30332e-05 8.58502e-05 7.86672e-05 7.14841e-05 6.43011e-05 5.7118e-05 4.9935e-05 4.35378e-05 4.04281e-05 3.73184e-05 3.42088e-05 3.10991e-05 2.79894e-05 2.48798e-05 2.17701e-05 1.86604e-05 } .graph element create V34 -x x -y v34 v35 set { 7.24585e-12 2.21843e-05 3.20014e-05 1.25076e-05 -2.44947e-05 1.8425e-05 5.50546e-06 3.53025e-05 -1.07551e-05 -3.94383e-06 -2.27848e-06 -9.04789e-05 7.44215e-05 -2.7662e-05 0.000200038 -2.11998e-05 -2.09011e-05 2.37098e-05 2.18751e-05 -2.28422e-05 -6.23659e-05 3.58241e-05 1.76386e-05 -4.28311e-05 0.000355626 0.00156903 0.00100999 -0.0085304 -0.02067 -0.0389485 -0.0651568 -0.128475 -0.314362 -0.406837 -0.421558 -0.421277 -0.418176 -0.414481 -0.410845 -0.407348 -0.403971 -0.400716 -0.397582 -0.394563 -0.391658 -0.388866 -0.386178 -0.383585 -0.381094 -0.378789 -0.376569 -0.37435 -0.372256 -0.370188 -0.36815 -0.366422 -0.364694 -0.362967 -0.361239 -0.359511 -0.357888 -0.356334 -0.354781 -0.353227 -0.351674 -0.350152 -0.348888 -0.347625 -0.346361 -0.345098 -0.343834 -0.342571 -0.341307 -0.340044 -0.33878 -0.337517 -0.336279 -0.335215 -0.334152 -0.333088 -0.332024 -0.330961 -0.329897 -0.328833 -0.32777 -0.326706 -0.325642 -0.324601 -0.323683 -0.322766 -0.321849 -0.320932 -0.320014 -0.319097 -0.31818 -0.317263 -0.316345 -0.315428 -0.314545 -0.313825 -0.313106 -0.312387 -0.311667 -0.310948 -0.310228 -0.309509 -0.308789 -0.30807 -0.307351 -0.306631 -0.305912 -0.305192 -0.304473 -0.303754 -0.303034 -0.302315 -0.301595 -0.300876 -0.300157 -0.299437 -0.298716 -0.29798 -0.297329 -0.296691 -0.295837 -0.29516 -0.294725 -0.294044 -0.292917 -0.292351 -0.291965 -0.291365 -0.290687 -0.290027 -0.289376 -0.288772 -0.288193 -0.287505 -0.286892 -0.28626 -0.285714 -0.284545 -0.289246 -0.298717 -0.298492 -0.214163 0.181451 0.0749974 0.0454707 0.0292987 0.0196837 0.0124119 0.00884715 0.00527181 0.00585821 0.0296361 0.169856 0.361207 0.538856 0.67469 0.685933 0.392802 0.17772 0.0813085 0.0424601 0.0246654 0.0175258 0.0144256 0.0129859 0.012205 0.0112846 0.010933 0.0134813 0.0147254 0.0147981 0.0142156 0.0132732 0.0121355 0.0109587 0.00981238 0.00872731 0.00767007 0.00669346 0.00581341 0.00502167 0.00431819 0.00369842 0.00316168 0.00269663 0.00230035 0.00195801 0.00166928 0.00142286 0.00121522 0.00104072 0.000893384 0.000767675 0.000661268 0.000567659 0.000481766 0.000407101 0.000350044 0.000302721 0.000263424 0.000236813 0.00022199 0.000218182 0.000219548 0.0002027 0.000185853 0.000169006 0.000152158 0.000135311 0.000118463 0.000101616 9.33782e-05 8.57685e-05 7.81588e-05 7.0549e-05 6.29393e-05 5.53296e-05 4.77199e-05 4.36954e-05 4.15296e-05 3.93637e-05 3.71978e-05 3.50319e-05 3.28661e-05 3.07002e-05 2.85343e-05 2.63685e-05 2.42026e-05 2.20367e-05 1.98709e-05 1.7705e-05 1.55391e-05 1.34772e-05 1.22416e-05 1.10061e-05 9.77055e-06 8.535e-06 0.000631271 -0.00362586 -0.0146235 -0.0308486 -0.0237466 -0.0117522 -0.00304171 0.00251033 0.00531986 0.0063897 0.00657351 0.00636494 0.00599705 0.00553442 0.00505994 0.00330925 0.00246671 0.0027006 0.00473161 0.00830333 0.00649147 0.00356815 0.00217448 0.00187579 0.00270447 0.00219543 -0.00546118 -0.0179576 -0.0445306 -0.0649309 0.0197935 0.473629 0.87268 0.269542 0.0086094 0.0844602 0.606456 1.04929 0.906014 0.916205 0.919425 0.872867 0.556244 0.262457 0.11838 0.0571226 0.0333451 0.0237133 0.0185096 0.0159617 0.0148663 0.0138683 0.0144081 0.0153797 0.0152551 0.0146487 0.0137192 0.0125973 0.0113996 0.0101903 0.00901851 0.00790495 0.00687502 0.00593994 0.00510092 0.00436111 0.00372439 0.0031945 0.00277537 0.00241888 0.002095 0.00179943 0.00150419 0.00119264 0.00090934 0.000802394 0.000852816 0.000838368 0.000730842 0.000601028 0.000546616 0.000492205 0.000437793 0.000383381 0.000328969 0.00029454 0.000266428 0.000238317 0.000210205 0.000182093 0.000162091 0.000152145 0.000142198 0.000132252 0.000122306 0.000112359 0.000102413 9.24665e-05 8.25201e-05 7.25738e-05 6.26274e-05 5.78553e-05 5.42216e-05 5.05878e-05 4.69541e-05 4.33204e-05 3.96867e-05 3.60529e-05 3.24192e-05 2.87855e-05 2.51518e-05 2.19153e-05 2.03406e-05 1.8766e-05 1.71913e-05 1.56167e-05 1.4042e-05 1.24674e-05 1.08927e-05 9.31806e-06 } .graph element create V35 -x x -y v35 v36 set { 5 5.01426 5.02852 5.01923 4.77685 4.56471 4.52338 4.56813 4.63122 4.693 4.74776 4.79385 4.83258 4.86358 4.88918 4.91021 4.90553 4.89733 4.89554 4.91953 5.00757 5.07101 5.06318 5.05241 5.05535 5.08042 5.07251 4.90973 4.56136 3.98637 3.237 2.67216 2.33678 2.13529 2.00544 1.91429 1.84638 1.79461 1.75338 1.71958 1.69175 1.6686 1.64918 1.63258 1.61836 1.60607 1.59506 1.58483 1.57575 1.56847 1.56193 1.55538 1.54968 1.54416 1.5388 1.53523 1.53165 1.52807 1.52449 1.52091 1.51771 1.51477 1.51182 1.50888 1.50593 1.50309 1.50113 1.49917 1.4972 1.49524 1.49328 1.49132 1.48935 1.48739 1.48543 1.48346 1.48157 1.48012 1.47868 1.47724 1.47579 1.47435 1.47291 1.47146 1.47002 1.46857 1.46713 1.46574 1.46462 1.4635 1.46238 1.46126 1.46014 1.45902 1.4579 1.45678 1.45567 1.45455 1.45349 1.45275 1.45201 1.45127 1.45053 1.44979 1.44905 1.44831 1.44757 1.44683 1.44609 1.44535 1.44461 1.44387 1.44313 1.44239 1.44165 1.44091 1.44017 1.43943 1.43869 1.43795 1.43721 1.43874 1.43976 1.43619 1.43182 1.43726 1.43084 1.42587 1.42383 1.42642 1.42728 1.42736 1.4271 1.42669 1.42621 1.42569 1.41703 1.41244 1.41019 1.41199 1.41833 1.42502 1.41504 1.37535 1.28381 1.44779 2.33713 3.25835 3.67554 3.84975 4.01125 4.2253 4.45433 4.62215 4.74478 4.82998 4.8868 4.92396 4.94768 4.96498 4.98537 5.0128 5.04467 5.06722 5.06535 5.01475 4.91956 4.80647 4.7242 4.7059 4.73552 4.76379 4.81684 4.87376 4.92276 4.96112 4.9884 5.0045 5.00999 5.00933 5.00619 5.00384 5.00342 5.00373 5.00362 5.00309 5.00272 5.00239 5.00204 5.00172 5.00146 5.00124 5.00105 5.00089 5.00076 5.00065 5.00057 5.00048 5.00041 5.00034 5.00028 5.00023 5.00019 5.00015 5.00015 5.00016 5.0002 5.00023 5.00021 5.00019 5.00017 5.00015 5.00012 5.0001 5.00008 5.00007 5.00006 5.00005 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00062 4.99506 4.9835 4.96726 4.9728 4.97877 4.98675 4.9966 5.00406 5.00679 5.00629 5.00561 5.00487 5.00429 5.00384 5.002 5.00164 5.00229 5.00484 5.00769 5.00019 5.00242 5.01319 5.0335 5.07265 5.10129 5.11485 5.12551 5.13953 5.16048 5.18862 5.22811 5.25656 5.25627 5.19975 4.9139 4.24745 3.43732 2.8202 2.43224 2.17409 2.01333 1.93951 1.94622 1.98861 2.02217 2.05383 2.08376 2.11184 2.13793 2.16191 2.18267 2.20502 2.22837 2.24958 2.26901 2.28648 2.302 2.31582 2.32802 2.33869 2.34795 2.35596 2.36282 2.3687 2.37371 2.37797 2.38161 2.38476 2.38743 2.3897 2.39168 2.39329 2.39463 2.39575 2.39671 2.39756 2.39835 2.39907 2.39968 2.39999 2.4003 2.40061 2.40091 2.40122 2.40142 2.40159 2.40176 2.40193 2.4021 2.40222 2.40228 2.40234 2.4024 2.40247 2.40253 2.40259 2.40265 2.40271 2.40277 2.40284 2.40287 2.40289 2.40291 2.40294 2.40296 2.40298 2.40301 2.40303 2.40305 2.40308 2.4031 2.40311 2.40312 2.40313 2.40314 2.40315 2.40316 2.40317 2.40318 } .graph element create V36 -x x -y v36 v37 set { 5 5.01732 5.03181 5.05944 5.12686 5.20725 5.28103 5.31254 5.32901 5.33709 5.3408 5.34257 5.34311 5.34347 5.34386 5.34411 5.3406 5.33484 5.32942 5.32904 5.33644 5.34869 5.35001 5.34882 5.34758 5.34672 5.34599 5.34496 5.34364 5.34165 5.33712 5.33502 5.3366 5.34067 5.34306 5.34398 5.34434 5.34442 5.34443 5.34443 5.34441 5.34439 5.34437 5.34437 5.34438 5.34438 5.34438 5.34438 5.34438 5.34437 5.34437 5.34436 5.34436 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.35377 5.35451 5.34265 5.34488 5.35861 5.28622 4.90033 4.75027 4.89731 4.97098 4.99293 4.99832 4.99909 4.99956 4.99858 4.99829 4.9998 5.00035 5.0038 5.00989 5.00251 4.99438 4.9953 4.99761 4.99985 5.00152 5.0011 5.00046 4.99996 4.99925 4.99862 4.99919 4.99961 5.00048 5.00234 4.99654 4.98235 4.95936 4.83738 4.53021 4.21004 4.00593 3.91207 3.88059 3.87822 3.89117 3.91278 3.94044 3.97376 4.01152 4.05052 4.10679 4.17908 4.25673 4.33414 4.40875 4.47879 4.54342 4.60258 4.65595 4.70291 4.74414 4.78018 4.81185 4.83915 4.86291 4.88301 4.90048 4.91528 4.92802 4.9387 4.94777 4.95539 4.9618 4.96725 4.97195 4.97588 4.97932 4.98247 4.98512 4.98697 4.98831 4.98919 4.99015 4.99101 4.99169 4.99222 4.99282 4.99341 4.994 4.9946 4.99519 4.99578 4.99638 4.99667 4.99693 4.9972 4.99747 4.99773 4.998 4.99827 4.99841 4.99849 4.99856 4.99864 4.99872 4.9988 4.99888 4.99896 4.99904 4.99911 4.99919 4.99927 4.99935 4.99943 4.9995 4.99955 4.9996 4.99965 4.9997 5.00736 4.98252 4.87516 4.66727 4.49142 4.43103 4.4301 4.4571 4.49729 4.5407 4.5835 4.62363 4.66114 4.69577 4.72738 4.74632 4.75971 4.77576 4.80671 4.87073 4.91665 4.93252 4.94418 4.95331 4.96094 4.96727 4.97148 4.97471 4.97612 4.98276 5.00247 5.04086 5.08628 5.10673 5.08887 5.0564 5.02767 5.01336 4.99685 4.97422 4.90866 4.67035 4.33117 4.07888 3.94432 3.89105 3.88174 3.89292 3.91442 3.94564 3.98708 4.0355 4.09134 4.16315 4.24088 4.31918 4.39527 4.46693 4.53337 4.59405 4.6486 4.69693 4.73938 4.77617 4.80809 4.83551 4.85895 4.87894 4.89596 4.91081 4.92417 4.93651 4.94552 4.95198 4.9565 4.96096 4.96523 4.96972 4.97428 4.97868 4.98064 4.9826 4.98455 4.98651 4.98847 4.98967 4.99064 4.9916 4.99257 4.99353 4.99422 4.99457 4.99493 4.99528 4.99563 4.99598 4.99633 4.99668 4.99703 4.99738 4.99773 4.9979 4.99804 4.99817 4.9983 4.99843 4.99856 4.99869 4.99883 4.99896 4.99909 4.99921 4.99926 4.99931 4.99937 4.99942 4.99948 4.99953 4.99959 4.99964 } .graph element create V37 -x x -y v37 v38 set { 4.49849 4.53282 4.58329 4.66625 4.83345 4.97823 5.0207 5.01816 5.01116 5.00595 5.00296 5.00148 5.00073 5.00062 5.00033 5.0003 4.99864 4.99661 4.99652 4.99928 5.00361 5.12573 5.17251 5.22612 5.33479 5.44503 5.44432 5.44379 5.44334 5.443 5.44276 5.44258 5.44246 5.44238 5.44232 5.44228 5.44225 5.44223 5.44221 5.4422 5.44219 5.44219 5.44218 5.44218 5.44218 5.44218 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44212 5.45159 5.45236 5.44064 5.44307 5.45616 5.38122 4.77163 3.53297 2.74466 2.34448 2.11802 1.9783 1.88656 1.82001 1.77389 1.72955 1.69632 1.66971 1.6526 1.65236 1.56034 1.53764 1.97139 2.75096 3.39212 3.74042 3.82345 3.85696 3.88547 3.91862 3.9585 4.00467 4.05903 4.1254 4.19533 4.26791 4.34517 4.42112 4.49238 4.55807 4.6179 4.6713 4.71815 4.75889 4.79418 4.82456 4.85062 4.87291 4.89196 4.90823 4.92209 4.93388 4.9439 4.95242 4.95968 4.96585 4.97108 4.9755 4.97923 4.98237 4.98503 4.98732 4.98927 4.99094 4.99233 4.99353 4.99452 4.99538 4.99608 4.99668 4.99718 4.9976 4.99794 4.99822 4.99847 4.99867 4.99884 4.99899 4.99913 4.99924 4.99932 4.99938 4.99943 4.99947 4.99951 4.99953 4.99955 4.99958 4.99961 4.99964 4.99967 4.99969 4.99972 4.99975 4.99977 4.99978 4.99979 4.99981 4.99982 4.99983 4.99985 4.99986 4.99986 4.99987 4.99987 4.99988 4.99988 4.99988 4.99989 4.99989 4.9999 4.9999 4.99991 4.99991 4.99992 4.99992 4.99993 4.99993 4.99993 4.99994 5.00381 5.00064 4.99246 4.99823 5.00349 5.00076 5.00033 5.00015 5.00009 5.00007 5.00005 5.00004 5.00003 5.00002 4.99988 4.99732 4.99728 4.9978 5.00187 5.00927 5.08712 5.07654 4.92855 4.4863 3.76162 3.00049 2.49834 2.20883 2.03492 1.92384 1.84676 1.79021 1.74716 1.7132 1.68576 1.66309 1.64406 1.62785 1.61383 1.60162 1.59081 1.58117 1.57253 1.56473 1.55765 1.55117 1.54527 1.53988 1.53485 1.53012 1.5257 1.5216 1.51773 1.51411 1.51071 1.50746 1.50438 1.50146 1.49868 1.49603 1.4935 1.49109 1.48878 1.48657 1.48445 1.48242 1.48046 1.47858 1.47677 1.47502 1.47333 1.4717 1.47012 1.46859 1.46711 1.46568 1.46428 1.46292 1.4616 1.46034 1.45923 1.45812 1.45701 1.4559 1.45479 1.45378 1.45279 1.45181 1.45082 1.44983 1.44893 1.44813 1.44732 1.44652 1.44571 1.44491 1.4441 1.4433 1.44249 1.44169 1.44089 1.44019 1.43951 1.43883 1.43815 1.43747 1.4368 1.43612 1.43544 1.43476 1.43408 1.43342 1.43283 1.43223 1.43163 1.43104 1.43044 1.42984 1.42924 1.42865 } .graph element create V38 -x x -y v38 v39 set { 5 5.01048 5.01221 4.98887 4.76261 4.54943 4.51564 4.56249 4.62621 4.68843 4.74374 4.79044 4.82972 4.86127 4.88724 4.90862 4.90791 4.89858 4.89589 4.91767 5.00405 5.16956 5.12391 4.7557 3.87953 3.01124 2.48482 2.20424 2.03812 1.92679 1.84956 1.79256 1.74907 1.71487 1.68724 1.6644 1.64513 1.6287 1.61446 1.60197 1.59095 1.58117 1.57245 1.5646 1.55752 1.55109 1.54516 1.53958 1.53444 1.53008 1.52606 1.52205 1.51843 1.5149 1.51146 1.50893 1.50639 1.50387 1.50133 1.4988 1.49651 1.49436 1.49222 1.49007 1.48793 1.48585 1.48433 1.4828 1.48128 1.47975 1.47823 1.4767 1.47518 1.47365 1.47213 1.4706 1.46912 1.46795 1.46678 1.46561 1.46444 1.46327 1.4621 1.46093 1.45976 1.45859 1.45741 1.45628 1.45534 1.45441 1.45347 1.45254 1.4516 1.45067 1.44973 1.4488 1.44786 1.44693 1.44604 1.44539 1.44475 1.4441 1.44345 1.44281 1.44216 1.44151 1.44086 1.44022 1.43957 1.43892 1.43828 1.43763 1.43698 1.43633 1.43569 1.43504 1.43439 1.43375 1.4331 1.43245 1.4318 1.43157 1.43089 1.43001 1.43042 1.42899 1.42439 1.42216 1.43447 1.44048 1.43705 1.43314 1.43039 1.42861 1.42739 1.42651 1.42548 1.42488 1.4243 1.42392 1.4235 1.32443 1.31149 1.78169 2.64844 3.43211 3.95252 4.20231 4.3746 4.49948 4.58929 4.65742 4.71183 4.77057 4.83196 4.88354 4.92894 4.96625 4.99235 5.00651 5.00941 5.00813 5.00689 5.00588 5.00504 5.00431 5.00368 5.00314 5.00268 5.00228 5.00194 5.00165 5.0014 5.00118 5.001 5.00085 5.00072 5.00061 5.00052 5.00044 5.00037 5.00031 5.00027 5.00022 5.00019 5.00016 5.00013 5.00011 5.00009 5.00008 5.00007 5.00006 5.00005 5.00004 5.00003 5.00003 5.00003 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00002 5.00003 5.00004 5.00022 4.99974 4.99942 4.99997 5.00063 5.00002 5.00003 4.99994 4.99998 4.99999 5 5 5 5 5 4.99981 4.99998 5.00004 5.00036 5.00049 5.12012 5.16315 5.19712 5.21835 4.87874 4.10151 3.31555 2.74207 2.38075 2.15872 2.01614 1.91886 1.84852 1.79401 1.75052 1.71508 1.68672 1.66467 1.64602 1.62985 1.61576 1.60343 1.59256 1.58287 1.57418 1.56632 1.55922 1.55282 1.54687 1.54132 1.53618 1.53143 1.52698 1.52282 1.51895 1.51527 1.5118 1.50851 1.5054 1.50244 1.49963 1.49695 1.4944 1.49196 1.48963 1.4874 1.48527 1.48322 1.48124 1.47934 1.47751 1.47574 1.47403 1.47239 1.4708 1.46926 1.46777 1.46632 1.46491 1.46355 1.46237 1.4612 1.46002 1.45884 1.45766 1.45659 1.45555 1.45451 1.45346 1.45242 1.45147 1.45062 1.44978 1.44894 1.44809 1.44725 1.4464 1.44556 1.44472 1.44387 1.44303 1.4423 1.44159 1.44088 1.44017 1.43947 1.43876 1.43805 1.43734 1.43664 1.43593 1.43524 1.43462 1.434 1.43338 1.43276 1.43213 1.43151 1.43089 1.43027 } .graph element create V39 -x x -y v39 toplevel .top .graph legend configure -position .top.legend pack .top.legend -fill both -expand yes button .quit -text "quit" -bg "red" -command "exit" blt::table . \ .graph 0,0 -fill both \ Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ClosestPoint $graph Blt_PrintKey $graph $graph legend bind all <ButtonRelease-1> { HighlightTrace %W } $graph legend bind all <ButtonRelease-3> { %W legend deactivate * eval %W element deactivate [%W element activate] } proc HighlightTrace { graph } { set entry [$graph legend get current] set active [$graph legend activate] if { [lsearch $active $entry] < 0 } { $graph legend activate $entry $graph element activate $entry } else { $graph legend deactivate $entry $graph element deactivate $entry } } set lastRow 0 set logicPlots {} set leftMargin 0 set rightMargin 0 proc LogicPlot { from graph signal args } { if { ![winfo exists $graph] } { global rightMargin leftMargin graph $graph -title "" -topmargin 1 -bottommargin 1 -height 0.75i \ -plotpadx 4 -plotpady 8 -bd 0 \ -leftmargin $leftMargin -rightmargin $rightMargin $graph grid off set xMin [$from axis cget x -min] set xMax [$from axis cget x -max] set yLim [$from axis limits y] set yMin [lindex $yLim 0] set yMax [lindex $yLim 1] $graph axis configure x -title "" -hide yes -min $xMin -max $xMax $graph axis configure y -title $signal -min $yMin -max $yMax $graph legend configure -anchor nw global lastRow incr lastRow blt::table . $graph $lastRow,0 -fill both global logicPlots lappend logicPlots $graph } set list [linsert $args 0 $signal ] foreach i [$graph element names] { if { [lsearch $list $i] < 0 } { $graph element delete $i } } foreach i $list { if { ![$graph element exists $i] } { $graph element create $i } set pen [$from element cget $i -pen] set xData [$from element cget $i -x] set yData [$from element cget $i -y] $graph element configure $i -x $xData -y $yData -pen $pen } } set changePending "no" proc EventuallyChangePlots { p1 p2 how } { global changePending if { $changePending == "no" } { after idle ChangePlots } set changePending "yes" } proc ChangePlots { } { global changePending global logicPlots global leftMargin rightMargin set from .graph set xMin [$from axis cget x -min] set xMax [$from axis cget x -max] set yLim [$from axis limits y] set yMin [lindex $yLim 0] set yMax [lindex $yLim 1] foreach g ".graph .g2 .g3" { $g configure -leftmargin $leftMargin -rightmargin $rightMargin $g axis configure x -min $xMin -max $xMax #$g axis configure y -min $yMin -max $yMax } set changePending "no" } #LogicPlot .graph .g1 V1 #LogicPlot .graph .g2 V5 #LogicPlot .graph .g3 V9 # LogicPlot .graph .g4 V13 # LogicPlot .graph .g5 V17 # LogicPlot .graph .g6 V22 # LogicPlot .graph .g7 V26 #.g1 configure -leftvariable leftMargin -rightvariable rightMargin trace variable leftMargin w EventuallyChangePlots trace variable rightMargin w EventuallyChangePlots ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu3.tcl������������������������������������������������������������������0000644�0001750�0001750�00000041074�11462120062�015251� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set colors { 000000 black 000000 gray0 000000 grey0 000080 NavyBlue 000080 navy 000080 {navy blue} 00008B DarkBlue 00008B blue4 00008B {dark blue} 0000CD MediumBlue 0000CD blue3 0000CD {medium blue} 0000EE blue2 0000FF blue 0000FF blue1 006400 DarkGreen 006400 {dark green} 00688B DeepSkyBlue4 00868B turquoise4 008B00 green4 008B45 SpringGreen4 008B8B DarkCyan 008B8B cyan4 008B8B {dark cyan} 009ACD DeepSkyBlue3 00B2EE DeepSkyBlue2 00BFFF DeepSkyBlue 00BFFF DeepSkyBlue1 00BFFF {deep sky blue} 00C5CD turquoise3 00CD00 green3 00CD66 SpringGreen3 00CDCD cyan3 00CED1 DarkTurquoise 00CED1 {dark turquoise} 00E5EE turquoise2 00EE00 green2 00EE76 SpringGreen2 00EEEE cyan2 00F5FF turquoise1 00FA9A MediumSpringGreen 00FA9A {medium spring green} 00FF00 green 00FF00 green1 00FF7F SpringGreen 00FF7F SpringGreen1 00FF7F {spring green} 00FFFF cyan 00FFFF cyan1 030303 gray1 030303 grey1 050505 gray2 050505 grey2 080808 gray3 080808 grey3 0A0A0A gray4 0A0A0A grey4 0D0D0D gray5 0D0D0D grey5 0F0F0F gray6 0F0F0F grey6 104E8B DodgerBlue4 121212 gray7 121212 grey7 141414 gray8 141414 grey8 171717 gray9 171717 grey9 1874CD DodgerBlue3 191970 MidnightBlue 191970 {midnight blue} 1A1A1A gray10 1A1A1A grey10 1C1C1C gray11 1C1C1C grey11 1C86EE DodgerBlue2 1E90FF DodgerBlue 1E90FF DodgerBlue1 1E90FF {dodger blue} 1F1F1F gray12 1F1F1F grey12 20B2AA LightSeaGreen 20B2AA {light sea green} 212121 gray13 212121 grey13 228B22 ForestGreen 228B22 {forest green} 242424 gray14 242424 grey14 262626 gray15 262626 grey15 27408B RoyalBlue4 292929 gray16 292929 grey16 2B2B2B gray17 2B2B2B grey17 2E2E2E gray18 2E2E2E grey18 2E8B57 SeaGreen 2E8B57 SeaGreen4 2E8B57 {sea green} 2F4F4F DarkSlateGray 2F4F4F DarkSlateGrey 2F4F4F {dark slate gray} 2F4F4F {dark slate grey} 303030 gray19 303030 grey19 32CD32 LimeGreen 32CD32 {lime green} 333333 gray20 333333 grey20 363636 gray21 363636 grey21 36648B SteelBlue4 383838 gray22 383838 grey22 3A5FCD RoyalBlue3 3B3B3B gray23 3B3B3B grey23 3CB371 MediumSeaGreen 3CB371 {medium sea green} 3D3D3D gray24 3D3D3D grey24 404040 gray25 404040 grey25 40E0D0 turquoise 4169E1 RoyalBlue 4169E1 {royal blue} 424242 gray26 424242 grey26 436EEE RoyalBlue2 43CD80 SeaGreen3 454545 gray27 454545 grey27 458B00 chartreuse4 458B74 aquamarine4 4682B4 SteelBlue 4682B4 {steel blue} 473C8B SlateBlue4 474747 gray28 474747 grey28 483D8B DarkSlateBlue 483D8B {dark slate blue} 4876FF RoyalBlue1 48D1CC MediumTurquoise 48D1CC {medium turquoise} 4A4A4A gray29 4A4A4A grey29 4A708B SkyBlue4 4D4D4D gray30 4D4D4D grey30 4EEE94 SeaGreen2 4F4F4F gray31 4F4F4F grey31 4F94CD SteelBlue3 525252 gray32 525252 grey32 528B8B DarkSlateGray4 53868B CadetBlue4 545454 gray33 545454 grey33 548B54 PaleGreen4 54FF9F SeaGreen1 551A8B purple4 556B2F DarkOliveGreen 556B2F {dark olive green} 575757 gray34 575757 grey34 595959 gray35 595959 grey35 5C5C5C gray36 5C5C5C grey36 5CACEE SteelBlue2 5D478B MediumPurple4 5E5E5E gray37 5E5E5E grey37 5F9EA0 CadetBlue 5F9EA0 {cadet blue} 607B8B LightSkyBlue4 616161 gray38 616161 grey38 636363 gray39 636363 grey39 63B8FF SteelBlue1 6495ED CornflowerBlue 6495ED {cornflower blue} 666666 gray40 666666 grey40 668B8B PaleTurquoise4 66CD00 chartreuse3 66CDAA MediumAquamarine 66CDAA aquamarine3 66CDAA {medium aquamarine} 68228B DarkOrchid4 68838B LightBlue4 6959CD SlateBlue3 696969 DimGray 696969 DimGrey 696969 gray41 696969 grey41 696969 {dim gray} 696969 {dim grey} 698B22 OliveDrab4 698B69 DarkSeaGreen4 6A5ACD SlateBlue 6A5ACD {slate blue} 6B6B6B gray42 6B6B6B grey42 6B8E23 OliveDrab 6B8E23 {olive drab} 6C7B8B SlateGray4 6CA6CD SkyBlue3 6E6E6E gray43 6E6E6E grey43 6E7B8B LightSteelBlue4 6E8B3D DarkOliveGreen4 707070 gray44 707070 grey44 708090 SlateGray 708090 SlateGrey 708090 {slate gray} 708090 {slate grey} 737373 gray45 737373 grey45 757575 gray46 757575 grey46 76EE00 chartreuse2 76EEC6 aquamarine2 778899 LightSlateGray 778899 LightSlateGrey 778899 {light slate gray} 778899 {light slate grey} 787878 gray47 787878 grey47 79CDCD DarkSlateGray3 7A378B MediumOrchid4 7A67EE SlateBlue2 7A7A7A gray48 7A7A7A grey48 7A8B8B LightCyan4 7AC5CD CadetBlue3 7B68EE MediumSlateBlue 7B68EE {medium slate blue} 7CCD7C PaleGreen3 7CFC00 LawnGreen 7CFC00 {lawn green} 7D26CD purple3 7D7D7D gray49 7D7D7D grey49 7EC0EE SkyBlue2 7F7F7F gray50 7F7F7F grey50 7FFF00 chartreuse 7FFF00 chartreuse1 7FFFD4 aquamarine 7FFFD4 aquamarine1 828282 gray51 828282 grey51 836FFF SlateBlue1 838B83 honeydew4 838B8B azure4 8470FF LightSlateBlue 8470FF {light slate blue} 858585 gray52 858585 grey52 878787 gray53 878787 grey53 87CEEB SkyBlue 87CEEB {sky blue} 87CEFA LightSkyBlue 87CEFA {light sky blue} 87CEFF SkyBlue1 8968CD MediumPurple3 8A2BE2 BlueViolet 8A2BE2 {blue violet} 8A8A8A gray54 8A8A8A grey54 8B0000 DarkRed 8B0000 red4 8B0000 {dark red} 8B008B DarkMagenta 8B008B magenta4 8B008B {dark magenta} 8B0A50 DeepPink4 8B1A1A firebrick4 8B1C62 maroon4 8B2252 VioletRed4 8B2323 brown4 8B2500 OrangeRed4 8B3626 tomato4 8B3A3A IndianRed4 8B3A62 HotPink4 8B3E2F coral4 8B4500 DarkOrange4 8B4513 SaddleBrown 8B4513 chocolate4 8B4513 {saddle brown} 8B4726 sienna4 8B475D PaleVioletRed4 8B4789 orchid4 8B4C39 salmon4 8B5742 LightSalmon4 8B5A00 orange4 8B5A2B tan4 8B5F65 LightPink4 8B636C pink4 8B6508 DarkGoldenrod4 8B668B plum4 8B6914 goldenrod4 8B6969 RosyBrown4 8B7355 burlywood4 8B7500 gold4 8B7765 PeachPuff4 8B795E NavajoWhite4 8B7B8B thistle4 8B7D6B bisque4 8B7D7B MistyRose4 8B7E66 wheat4 8B814C LightGoldenrod4 8B8378 AntiqueWhite4 8B8386 LavenderBlush4 8B864E khaki4 8B8682 seashell4 8B8878 cornsilk4 8B8970 LemonChiffon4 8B8989 snow4 8B8B00 yellow4 8B8B7A LightYellow4 8B8B83 ivory4 8C8C8C gray55 8C8C8C grey55 8DB6CD LightSkyBlue3 8DEEEE DarkSlateGray2 8EE5EE CadetBlue2 8F8F8F gray56 8F8F8F grey56 8FBC8F DarkSeaGreen 8FBC8F {dark sea green} 90EE90 LightGreen 90EE90 PaleGreen2 90EE90 {light green} 912CEE purple2 919191 gray57 919191 grey57 9370DB MediumPurple 9370DB {medium purple} 9400D3 DarkViolet 9400D3 {dark violet} 949494 gray58 949494 grey58 969696 gray59 969696 grey59 96CDCD PaleTurquoise3 97FFFF DarkSlateGray1 98F5FF CadetBlue1 98FB98 PaleGreen 98FB98 {pale green} 9932CC DarkOrchid 9932CC {dark orchid} 999999 gray60 999999 grey60 9A32CD DarkOrchid3 9AC0CD LightBlue3 9ACD32 OliveDrab3 9ACD32 YellowGreen 9ACD32 {yellow green} 9AFF9A PaleGreen1 9B30FF purple1 9BCD9B DarkSeaGreen3 9C9C9C gray61 9C9C9C grey61 9E9E9E gray62 9E9E9E grey62 9F79EE MediumPurple2 9FB6CD SlateGray3 A020F0 purple A0522D sienna A1A1A1 gray63 A1A1A1 grey63 A2B5CD LightSteelBlue3 A2CD5A DarkOliveGreen3 A3A3A3 gray64 A3A3A3 grey64 A4D3EE LightSkyBlue2 A52A2A brown A6A6A6 gray65 A6A6A6 grey65 A8A8A8 gray66 A8A8A8 grey66 A9A9A9 DarkGray A9A9A9 DarkGrey A9A9A9 {dark gray} A9A9A9 {dark grey} AB82FF MediumPurple1 ABABAB gray67 ABABAB grey67 ADADAD gray68 ADADAD grey68 ADD8E6 LightBlue ADD8E6 {light blue} ADFF2F GreenYellow ADFF2F {green yellow} AEEEEE PaleTurquoise2 AFEEEE PaleTurquoise AFEEEE {pale turquoise} B03060 maroon B0B0B0 gray69 B0B0B0 grey69 B0C4DE LightSteelBlue B0C4DE {light steel blue} B0E0E6 PowderBlue B0E0E6 {powder blue} B0E2FF LightSkyBlue1 B22222 firebrick B23AEE DarkOrchid2 B2DFEE LightBlue2 B3B3B3 gray70 B3B3B3 grey70 B3EE3A OliveDrab2 B452CD MediumOrchid3 B4CDCD LightCyan3 B4EEB4 DarkSeaGreen2 B5B5B5 gray71 B5B5B5 grey71 B8860B DarkGoldenrod B8860B {dark goldenrod} B8B8B8 gray72 B8B8B8 grey72 B9D3EE SlateGray2 BA55D3 MediumOrchid BA55D3 {medium orchid} BABABA gray73 BABABA grey73 BBFFFF PaleTurquoise1 BC8F8F RosyBrown BC8F8F {rosy brown} BCD2EE LightSteelBlue2 BCEE68 DarkOliveGreen2 BDB76B DarkKhaki BDB76B {dark khaki} BDBDBD gray74 BDBDBD grey74 BEBEBE gray BEBEBE grey BF3EFF DarkOrchid1 BFBFBF gray75 BFBFBF grey75 BFEFFF LightBlue1 C0FF3E OliveDrab1 C1CDC1 honeydew3 C1CDCD azure3 C1FFC1 DarkSeaGreen1 C2C2C2 gray76 C2C2C2 grey76 C4C4C4 gray77 C4C4C4 grey77 C6E2FF SlateGray1 C71585 MediumVioletRed C71585 {medium violet red} C7C7C7 gray78 C7C7C7 grey78 C9C9C9 gray79 C9C9C9 grey79 CAE1FF LightSteelBlue1 CAFF70 DarkOliveGreen1 CCCCCC gray80 CCCCCC grey80 CD0000 red3 CD00CD magenta3 CD1076 DeepPink3 CD2626 firebrick3 CD2990 maroon3 CD3278 VioletRed3 CD3333 brown3 CD3700 OrangeRed3 CD4F39 tomato3 CD5555 IndianRed3 CD5B45 coral3 CD5C5C IndianRed CD5C5C {indian red} CD6090 HotPink3 CD6600 DarkOrange3 CD661D chocolate3 CD6839 sienna3 CD6889 PaleVioletRed3 CD69C9 orchid3 CD7054 salmon3 CD8162 LightSalmon3 CD8500 orange3 CD853F peru CD853F tan3 CD8C95 LightPink3 CD919E pink3 CD950C DarkGoldenrod3 CD96CD plum3 CD9B1D goldenrod3 CD9B9B RosyBrown3 CDAA7D burlywood3 CDAD00 gold3 CDAF95 PeachPuff3 CDB38B NavajoWhite3 CDB5CD thistle3 CDB79E bisque3 CDB7B5 MistyRose3 CDBA96 wheat3 CDBE70 LightGoldenrod3 CDC0B0 AntiqueWhite3 CDC1C5 LavenderBlush3 CDC5BF seashell3 CDC673 khaki3 CDC8B1 cornsilk3 CDC9A5 LemonChiffon3 CDC9C9 snow3 CDCD00 yellow3 CDCDB4 LightYellow3 CDCDC1 ivory3 CFCFCF gray81 CFCFCF grey81 D02090 VioletRed D02090 {violet red} D15FEE MediumOrchid2 D1D1D1 gray82 D1D1D1 grey82 D1EEEE LightCyan2 D2691E chocolate D2B48C tan D3D3D3 LightGray D3D3D3 LightGrey D3D3D3 {light gray} D3D3D3 {light grey} D4D4D4 gray83 D4D4D4 grey83 D6D6D6 gray84 D6D6D6 grey84 D8BFD8 thistle D9D9D9 gray85 D9D9D9 grey85 DA70D6 orchid DAA520 goldenrod DB7093 PaleVioletRed DB7093 {pale violet red} DBDBDB gray86 DBDBDB grey86 DCDCDC gainsboro DDA0DD plum DEB887 burlywood DEDEDE gray87 DEDEDE grey87 E066FF MediumOrchid1 E0E0E0 gray88 E0E0E0 grey88 E0EEE0 honeydew2 E0EEEE azure2 E0FFFF LightCyan E0FFFF LightCyan1 E0FFFF {light cyan} E3E3E3 gray89 E3E3E3 grey89 E5E5E5 gray90 E5E5E5 grey90 E6E6FA lavender E8E8E8 gray91 E8E8E8 grey91 E9967A DarkSalmon E9967A {dark salmon} EBEBEB gray92 EBEBEB grey92 EDEDED gray93 EDEDED grey93 EE0000 red2 EE00EE magenta2 EE1289 DeepPink2 EE2C2C firebrick2 EE30A7 maroon2 EE3A8C VioletRed2 EE3B3B brown2 EE4000 OrangeRed2 EE5C42 tomato2 EE6363 IndianRed2 EE6A50 coral2 EE6AA7 HotPink2 EE7600 DarkOrange2 EE7621 chocolate2 EE7942 sienna2 EE799F PaleVioletRed2 EE7AE9 orchid2 EE8262 salmon2 EE82EE violet EE9572 LightSalmon2 EE9A00 orange2 EE9A49 tan2 EEA2AD LightPink2 EEA9B8 pink2 EEAD0E DarkGoldenrod2 EEAEEE plum2 EEB422 goldenrod2 EEB4B4 RosyBrown2 EEC591 burlywood2 EEC900 gold2 EECBAD PeachPuff2 EECFA1 NavajoWhite2 EED2EE thistle2 EED5B7 bisque2 EED5D2 MistyRose2 EED8AE wheat2 EEDC82 LightGoldenrod2 EEDD82 LightGoldenrod EEDD82 {light goldenrod} EEDFCC AntiqueWhite2 EEE0E5 LavenderBlush2 EEE5DE seashell2 EEE685 khaki2 EEE8AA PaleGoldenrod EEE8AA {pale goldenrod} EEE8CD cornsilk2 EEE9BF LemonChiffon2 EEE9E9 snow2 EEEE00 yellow2 EEEED1 LightYellow2 EEEEE0 ivory2 F08080 LightCoral F08080 {light coral} F0E68C khaki F0F0F0 gray94 F0F0F0 grey94 F0F8FF AliceBlue F0F8FF {alice blue} F0FFF0 honeydew F0FFF0 honeydew1 F0FFFF azure F0FFFF azure1 F2F2F2 gray95 F2F2F2 grey95 F4A460 SandyBrown F4A460 {sandy brown} F5DEB3 wheat F5F5DC beige F5F5F5 WhiteSmoke F5F5F5 gray96 F5F5F5 grey96 F5F5F5 {white smoke} F5FFFA MintCream F5FFFA {mint cream} F7F7F7 gray97 F7F7F7 grey97 F8F8FF GhostWhite F8F8FF {ghost white} FA8072 salmon FAEBD7 AntiqueWhite FAEBD7 {antique white} FAF0E6 linen FAFAD2 LightGoldenrodYellow FAFAD2 {light goldenrod yellow} FAFAFA gray98 FAFAFA grey98 FCFCFC gray99 FCFCFC grey99 FDF5E6 OldLace FDF5E6 {old lace} FF0000 red FF0000 red1 FF00FF magenta FF00FF magenta1 FF1493 DeepPink FF1493 DeepPink1 FF1493 {deep pink} FF3030 firebrick1 FF34B3 maroon1 FF3E96 VioletRed1 FF4040 brown1 FF4500 OrangeRed FF4500 OrangeRed1 FF4500 {orange red} FF6347 tomato FF6347 tomato1 FF69B4 HotPink FF69B4 {hot pink} FF6A6A IndianRed1 FF6EB4 HotPink1 FF7256 coral1 FF7F00 DarkOrange1 FF7F24 chocolate1 FF7F50 coral FF8247 sienna1 FF82AB PaleVioletRed1 FF83FA orchid1 FF8C00 DarkOrange FF8C00 {dark orange} FF8C69 salmon1 FFA07A LightSalmon FFA07A LightSalmon1 FFA07A {light salmon} FFA500 orange FFA500 orange1 FFA54F tan1 FFAEB9 LightPink1 FFB5C5 pink1 FFB6C1 LightPink FFB6C1 {light pink} FFB90F DarkGoldenrod1 FFBBFF plum1 FFC0CB pink FFC125 goldenrod1 FFC1C1 RosyBrown1 FFD39B burlywood1 FFD700 gold FFD700 gold1 FFDAB9 PeachPuff FFDAB9 PeachPuff1 FFDAB9 {peach puff} FFDEAD NavajoWhite FFDEAD NavajoWhite1 FFDEAD {navajo white} FFE1FF thistle1 FFE4B5 moccasin FFE4C4 bisque FFE4C4 bisque1 FFE4E1 MistyRose FFE4E1 MistyRose1 FFE4E1 {misty rose} FFE7BA wheat1 FFEBCD BlanchedAlmond FFEBCD {blanched almond} FFEC8B LightGoldenrod1 FFEFD5 PapayaWhip FFEFD5 {papaya whip} FFEFDB AntiqueWhite1 FFF0F5 LavenderBlush FFF0F5 LavenderBlush1 FFF0F5 {lavender blush} FFF5EE seashell FFF5EE seashell1 FFF68F khaki1 FFF8DC cornsilk FFF8DC cornsilk1 FFFACD LemonChiffon FFFACD LemonChiffon1 FFFACD {lemon chiffon} FFFAF0 FloralWhite FFFAF0 {floral white} FFFAFA snow FFFAFA snow1 FFFF00 yellow FFFF00 yellow1 FFFFE0 LightYellow FFFFE0 LightYellow1 FFFFE0 {light yellow} FFFFF0 ivory FFFFF0 ivory1 FFFFFF gray100 FFFFFF grey100 FFFFFF white } if { [file exists ../library] } { set blt_library ../library } set bg [blt::bgpattern create gradient -low grey100 -high grey90 \ -dir y -jitter yes -log yes -relativeto toplevel] set bg white set myIcon "" blt::comboentry .e \ -textvariable myText1 \ -iconvariable myIcon1 \ -textbackground $bg \ -menu .e.m \ -menuanchor ne \ -exportselection yes blt::combomenu .e.m \ -textvariable myText1 \ -iconvariable myIcon1 \ -height { 0 400 } \ -width { 0 400 } \ -background $bg \ -yscrollbar .e.m.ybar \ -xscrollbar .e.m.xbar blt::tk::scrollbar .e.m.xbar blt::tk::scrollbar .e.m.ybar set bg [image create picture -width 30 -height 20] $bg blank 0x0000000 $bg draw rectangle 5 5 14 26 -color 0xFF00000 $bg blur $bg 4 foreach {rgb name} $colors { set icon [image create picture -width 27 -height 27] $icon blank 0x00000000 $icon draw circle 12 12 11 -fill \#$rgb \ -shadow 2 -antialiased 1 -linewidth 1 .e.m add -text $name -icon $icon } button .quit -text "Exit" -command exit blt::table . \ 0,0 .e -fill both -padx 2 -pady 2 \ 1,0 .quit ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop5.tcl������������������������������������������������������������������0000644�0001750�0001750�00000004031�11462120062�015270� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set filter sinc set shadow 8 #set imgfile ./images/sample.gif set imgfile ./images/blt98.gif #set imgfile ~/.icons/cd-player.xpm if { [llength $argv] > 0 } { set imgfile [lindex $argv 0] } if { [ file exists $imgfile] } { set src [image create picture -file $imgfile] } else { puts stderr "no image file" exit 0 } set xoff 5 set yoff 5 set name [file root [file tail $imgfile]] set width 500 set height 500 set bg [image create picture -width $width -height $height] set bg2 [image create picture -width $width -height $height] set r 200 set cx [expr $width / 2] set cy [expr $height / 2] set x [expr $cx + $xoff] set y [expr $cy + $yoff] #$bg draw circle $x $y $r -color blue -thickness 0 set layer1 [image create picture -width $width -height $height] $layer1 blank 0x00000000 $layer1 draw circle $x $y $r -color 0xFFFFFFFF -thickness 0 $layer1 blur $layer1 10 set layer2 [image create picture -width $width -height $height] set layer3 [image create picture -width $width -height $height] $layer2 select $layer1 0x01000000 0xFFFFFFFF $layer2 and 0xFF000000 $layer2 and $layer1 $layer3 copy $layer1 $layer3 select $layer1 0x01000000 0xFFFFFFFF #$layer3 and 0x00FFFF00 $bg2 gradient -low green2 -high green4 -jitter yes -log no puts bg2=[$bg2 get 200 200] #$bg2 and 0x00FFFFFF puts bg2=[$bg2 get 200 200] puts layer1=[$layer1 get 200 200] $layer1 and $bg2 puts and=[$layer1 get 200 200] $bg gradient -low blue1 -high blue4 -jitter yes -log no #$layer1 or 0xFF000000 #$layer1 blend $bg $layer1 #-matte $layer3 #$layer1 min $bg $bg blend $bg $layer2 #-matte $layer1 set src $layer1 set src $bg set dest $layer1 option add *Label.font *helvetica*10* option add *Label.background white label .l0 -image $src label .header0 -text "$width x $height" label .footer0 -text "100%" . configure -bg white set iw $width set ih $height label .header -text "$iw x $ih" label .footer -text "$filter" label .l1 -image $dest blt::table . \ 0,1 .header \ 1,1 .l0 1,2 .l1 \ 2,1 .footer �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop6.tcl������������������������������������������������������������������0000644�0001750�0001750�00000001747�11462120062�015304� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT set shadow 8 set xoff 5 set yoff 5 set width 500 set height 500 set r 200 set cx [expr $width / 2] set cy [expr $height / 2] set x [expr $cx + $xoff] set y [expr $cy + $yoff] set l1 [image create picture -width $width -height $height] set l2 [image create picture -width $width -height $height] set bg [image create picture -file images/blt98.gif -width 200 -height 200 -aspect no] $bg and 0x00FFFFFF $l1 blank 0x00000000 $l1 draw rectangle 8 8 200 200 -color 0xFFFFFFFF -thickness 0 $l1 blur $l1 8 $l2 select $l1 0x01000000 0xFFFFFFFF $l1 and 0xFF000000 -mask $l2 $l1 or $bg -mask $l2 $l1 sub 0x0F000000 -mask $l2 set bg [image create picture -width $width -height $height] $bg gradient -high yellow -low black -jitter yes -log no $bg blend $bg $l1 option add *Label.font *helvetica*10* option add *Label.background white label .l0 -image $l1 label .l1 -image $l2 label .l3 -image $bg . configure -bg white blt::table . \ 1,1 .l0 1,2 .l1 1,3 .l3 �������������������������./saods9/blt3.0.1/demos/scrollset2.tcl��������������������������������������������������������������0000644�0001750�0001750�00000000733�11462120062�016150� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::scrollset .ss \ -xscrollbar .ss.xsbar \ -yscrollbar .ss.ysbar \ -window .ss.t blt::tk::scrollbar .ss.ysbar -orient vertical blt::tk::scrollbar .ss.xsbar -orient horizontal text .ss.t -wrap none .ss.t insert end "salsadkjlda s adslkjda lskjd asldkjda lskjd sa aslkj dlsakj lkdsa asdlkjdalskj ds aslkdj aldskjd ls asldkj dlskjd sl asldkj dlskjd l adlaldksjd ldkasj ldkjs ld" pack .ss -fill both -expand yes �������������������������������������./saods9/blt3.0.1/demos/paneset4.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000533�11462120062�015575� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::paneset .ps -width 800 -mode spreadsheet blt::graph .ps.g blt::barchart .ps.b blt::barchart .ps.b2 .ps add -window .ps.g -fill both .ps add -window .ps.b -fill both .ps add -window .ps.b2 -fill both focus .ps blt::table . \ 0,0 .ps -fill both blt::table configure . r1 -resize none ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/ctree1.tcl������������������������������������������������������������������0000644�0001750�0001750�00000002175�11462120062�015241� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� proc find { tree parent dir } { global count set saved [pwd] cd $dir foreach f [glob -nocomplain *] { set name [file tail $f] if { [file type $f] == "directory" } { set node [$tree insert $parent -label $name] find $tree $node $f } } cd $saved } set tree [blt::tree create] set path ../.. find $tree root $path $tree label root [file normalize $path] if { [file exists ../library] } { set blt_library ../library } puts [$tree label 0] # -postcommand {.e.m configure -width [winfo width .e] ; update} \ set myIcon "" blt::comboentry .e \ -font { arial 9 } \ -textvariable myText1 \ -iconvariable myIcon1 \ -textwidth 20 \ -menu .e.m \ -menuanchor se \ -exportselection yes \ -command "puts {button pressed}" blt::combotree .e.m \ -tree $tree \ -borderwidth 1 \ -font { arial 10 } \ -textvariable myText1 \ -iconvariable myIcon1 \ -separator / \ -height -200 \ -linecolor grey50 \ -yscrollbar .e.m.ybar \ -xscrollbar .e.m.xbar blt::tk::scrollbar .e.m.xbar blt::tk::scrollbar .e.m.ybar focus .e.m blt::table . \ .e -fill x ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu5.tcl������������������������������������������������������������������0000644�0001750�0001750�00000003756�11462120062�015260� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set icon2 [image create picture -file images/blt98.gif] set icon [image create picture -data $imgData] set bg [blt::bgpattern create gradient -low grey100 -high grey90 \ -dir x -jitter yes -log yes -relativeto self] set image "" option add *ComboEntry.takeFocus 1 if { [file exists ../library] } { set blt_library ../library } # -postcommand {.e.m configure -width [winfo width .e] ; update} \ set myIcon "" blt::comboentry .e \ -image $image \ -textvariable myText1 \ -iconvariable myIcon1 \ -textwidth 6 \ -menu .e.m \ -menuanchor se \ -exportselection yes \ -xscrollcommand { .s set } \ -command "puts {button pressed}" # -bg $bg blt::combomenu .e.m \ -textvariable myText1 \ -iconvariable myIcon1 \ -font { Arial 8 } -acceleratorfont { Arial 8 } \ -yscrollbar .e.m.ybar \ -xscrollbar .e.m.xbar blt::tk::scrollbar .e.m.xbar blt::tk::scrollbar .e.m.ybar set onOff 1 set wwho "" foreach {item type} { Undo command X1 checkbutton Y1 radiobutton Redo checkbutton Cut command Copy checkbutton X2 checkbutton Y2 radiobutton Paste checkbutton separator separator "Select" checkbutton X3 checkbutton Y3 radiobutton Find cascade Replace checkbutton } { set char [string range $item 0 0] .e.m add \ -type $type \ -text $item \ -accel "Ctrl+$char" \ -underline 0 \ -tag "$type [string tolower $char]" \ -icon $icon \ -variable $item \ -value $item \ } .e.m item configure radiobutton -variable "wwho" set X1 1 set Redo 1 set wwho2 "" blt::tk::scrollbar .s -orient vertical -command { .e xview } bind ComboEntry <3> { grab release [grab current] } blt::table . \ 0,0 .e -fill x -anchor n blt::table configure . r0 -resize none blt::table configure . r1 -resize expand ������������������./saods9/blt3.0.1/demos/scrollset3.tcl��������������������������������������������������������������0000644�0001750�0001750�00000011466�11462120062�016156� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc SortColumn { column } { set old [.ss.t sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.ss.t sort cget -decreasing] set decreasing [expr !$decreasing] } .ss.t sort configure -decreasing $decreasing -column $column -mode integer if { ![.ss.t cget -flat] } { .ss.t configure -flat yes } .ss.t sort auto yes blt::busy hold .ss.t update blt::busy release .ss.t } proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } proc Find { tree parent dir } { global count set saved [pwd] cd $dir foreach f [glob -nocomplain *] { set name [file tail $f] if { [catch { file stat $f info }] != 0 } { set node [$tree insert $parent -label $name] } else { if 0 { if { $info(type) == "file" } { set info(type) [list @::blt::TreeView::openIcon $name] } else { set info(type) "@::blt::TreeView::openIcon " } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(size) [FormatSize $info(size)] set info(mode) [FormatMode $info(mode)] set node [$tree insert $parent -label $name -data [array get info]] } incr count if { [file type $f] == "directory" } { Find $tree $node $f } } cd $saved } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } option add *TreeView.focusOutSelectForeground white option add *TreeView.focusOutSelectBackground grey80 #option add *TreeView.Button.activeBackground pink option add *TreeView.Button.activeBackground grey90 #option add *TreeView.Button.background grey95 option add *TreeView.Column.background grey90 option add *TreeView.CheckBoxStyle.activeBackground white if 0 { if 1 { option add *TreeView.Column.titleFont { Arial 10 } option add *TreeView.text.font { Monotype.com 10 Bold } option add *TreeView.CheckBoxStyle.font Courier-10 option add *TreeView.ComboBoxStyle.font Helvetica-10 option add *TreeView.TextBoxStyle.font {Arial 10 bold } } else { option add *TreeView.Column.titleFont { Arial 14 } } } button .b -font { Helvetica 11 bold } set top [GetAbsolutePath ..] #set top [GetAbsolutePath /home/gah] set trim "$top" set tree [blt::tree create] blt::scrollset .ss \ -xscrollbar .ss.hs \ -yscrollbar .ss.vs \ -window .ss.t blt::tk::scrollbar .ss.vs -orient vertical blt::tk::scrollbar .ss.hs -orient horizontal blt::treeview .ss.t \ -width 0 \ -height 0 \ -highlightthickness 0 \ -borderwidth 0 \ -selectmode multiple \ -separator / \ -tree $tree .ss.t column configure treeView -text "" -edit yes #file .ss.t column insert 0 mtime atime gid .ss.t column insert end nlink mode type ctime uid ino size dev .ss.t column configure uid -background \#eaeaff -relief raised .ss.t column configure mtime -hide no -bg \#ffeaea -relief raised .ss.t column configure size gid nlink uid ino dev -justify left -edit yes .ss.t column configure size type -justify left -edit yes .ss.t column configure treeView -hide no -edit yes \ -icon ::blt::TreeView::openIcon focus .ss.t blt::table . \ 0,0 .ss -fill both set count 0 Find $tree root $top puts "$count entries" $tree find root -glob *.c -addtag "c_files" $tree find root -glob *.h -addtag "header_files" $tree find root -glob *.tcl -addtag "tcl_files" .ss.t entry configure "c_files" -foreground green4 .ss.t entry configure "header_files" -foreground cyan4 .ss.t entry configure "tcl_files" -foreground red4 .ss.t column bind all <ButtonRelease-3> { %W configure -flat no } foreach column [.ss.t column names] { .ss.t column configure $column -command [list SortColumn $column] } #.ss.t style configure text -background #F8fbF8 -selectbackground #D8fbD8 .ss.t style checkbox check \ -onvalue 100 -offvalue "50" \ -showvalue yes .ss.t style combobox combo -icon ::blt::TreeView::openIcon .ss.t column configure uid -style combo .ss.t column configure gid -style check ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/listview1.tcl���������������������������������������������������������������0000644�0001750�0001750�00000003741�11462120062�016005� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT blt::tk::radiobutton .rowmode -text "Row Layout" \ -variable layoutMode -value row \ -command [list .ss.l configure -layoutmode row] blt::tk::radiobutton .colmode -text "Column Layout" \ -variable layoutMode -value column \ -command [list .ss.l configure -layoutmode column] blt::tk::radiobutton .iconsmode -text "Icons Layout" \ -variable layoutMode -value icons \ -command [list .ss.l configure -layoutmode icons] blt::scrollset .ss \ -xscrollbar .ss.xs \ -yscrollbar .ss.ys \ -window .ss.l blt::listview .ss.l \ -width 3i \ -height 2i \ -layoutmode column \ -selectmode multiple \ -activebackground grey95 .ss.l sort configure \ -decreasing 0 \ -auto 1 \ -by type image create picture closeIcon -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } proc debugselect {} { puts stderr selected=[.ss.l curselection] } proc icon { name } { global icons if { [info exists icons($name)] } { return $icons($name) } set file "" foreach dir { ~/neeshub/indeed/src/icons/filetype ~/neeshub/indeed/src/icons/misc } { if { [file exists $dir/$name.png] } { set file $dir/$name.png break } } if { $file == "" } { return closeIcon } set icons($name) [image create picture -file $file] return $icons($name) } foreach f [lsort [glob -nocomplain ~/*]] { set name [file tail $f] set ext [file ext $name] set ext [string trimleft $ext .] if { [file isdir $f] } { set ext .dir } .ss.l add -text $name -icon [icon $ext] -type $ext \ -bigicon [icon folder-green] } blt::tk::scrollbar .ss.xs blt::tk::scrollbar .ss.ys blt::table . \ 0,0 .rowmode \ 0,1 .colmode \ 0,2 .iconsmode \ 1,0 .ss -fill both -cspan 3 blt::table configure . r0 -resize none .colmode select �������������������������������./saods9/blt3.0.1/demos/hierbox1.tcl����������������������������������������������������������������0000755�0001750�0001750�00000003530�11462120062�015576� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT #source scripts/demo.tcl set saved [pwd] #blt::bltdebug 100 set imagedir images image create picture bgTexture -file $imagedir/rain.gif set imageList {} foreach f [glob $imagedir/mini-*.gif] { lappend imageList [image create picture -file $f] } #option add *TreeView.Tile bgTexture option add *TreeView.ScrollTile yes option add *xTreeview.openCommand { set path /home/gah/src/blt/%P if { [file isdirectory $path] } { cd $path set files [glob -nocomplain * */. ] if { $files != "" } { eval %W insert -at %n end $files } } } option add *xTreeView.closeCommand { eval %W delete %n 0 end } blt::treeview .h \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x blt::table configure . c1 r1 -resize none proc DoFind { entry } { global fileList lappend fileList $entry #puts "$entry" if { [file type $entry] == "directory" } { foreach f [lsort [glob -nocomplain $entry/*]] { DoFind $f } } } proc Find { dir } { global fileList set fileList {} DoFind $dir return $fileList } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath .] set trim "$top" .h configure -separator "/" -autocreate yes -trim $trim .h entry configure root -label "$top" .h configure -bg grey90 update set fileList [Find $top] eval .h insert end $fileList .h configure -bg white -alternatebackground grey95 # %n => %# # no -activebackground # no -image focus .h # -labelcolor == -foreground set nodes [.h find -glob -name *.c] eval .h entry configure $nodes -foreground red cd $saved ������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/barchart4.tcl���������������������������������������������������������������0000755�0001750�0001750�00000004417�11462120062�015734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed 14823 set graph .graph source scripts/stipples.tcl source scripts/patterns.tcl option add *x.Title "X Axis" option add *y.Title "Y Axis" option add *LineMarker.Foreground yellow set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *print.background yellow option add *quit.background red option add *graph.background palegreen } blt::htext .header -text \ { This is an example of the barchart widget. The barchart has many components; x and y axis, legend, crosshairs, elements, etc. To create a postscript file "bar.ps", press the %% set w $htext(widget) button $w.print -text {Print} -command { $graph postscript output bar.ps } $w append $w.print %% button. } blt::barchart $graph $graph xaxis configure -rotate 90 -stepsize 0 blt::htext .footer -text { Hit the %% set im [image create picture -file ./images/stopsign.gif] button $htext(widget).quit -image $im -command { exit } $htext(widget) append $htext(widget).quit -pady 2 %% button when you've seen enough. %% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} set attributes { red bdiagonal1 orange bdiagonal2 yellow fdiagonal1 green fdiagonal2 blue hline1 cyan hline2 magenta vline1 violetred vline2 purple crossdiag lightblue hobbes } set count 0 foreach { color stipple } $attributes { $graph pen create pen$count \ -fill ${color}1 -outline ${color}4 -relief solid lappend styles [list pen$count $count $count] incr count } blt::vector x y w x seq 0 1000 400 y expr random(x)*90.0 w expr round(y/10.0)%$count y expr y+10.0 $graph element create data -label {} \ -x x -y y -weight w -styles $styles blt::table . \ 0,0 .header -fill x \ 1,0 .graph -fill both \ 2,0 .footer -fill x blt::table configure . r0 r2 -resize none wm min . 0 0 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hierbox2.tcl����������������������������������������������������������������0000755�0001750�0001750�00000003471�11462120062�015603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc AddDirEntries { w dir } { if { [file isdirectory $dir] } { set files [glob -nocomplain $dir/*] eval $w insert end [lsort $files] set subdirs [glob -nocomplain $dir/*/] eval $w entry configure [lsort $subdirs] -button yes } } set imageList {} foreach f [glob ./images/mini-*.gif] { lappend imageList [image create picture -file $f] } set top ../ #option add *Hierbox.Tile bgTexture option add *Hierbox.TileOffset yes option add *forceGadgets no option add *Hierbox.openCommand { AddDirEntries %W "$top/%P" } option add *Hierbox.closeCommand { eval %W delete %n 0 end } image create picture openFolder -file images/open.gif image create picture closeFolder -file images/close.gif option add *Hierbox.icons "closeFolder openFolder" #option add *Hierbox.Button.activeForeground red #option add *Hierbox.bindTags "Label all" hierbox .h \ -selectmode multiple \ -hideroot yes \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } .h button configure -activebackground grey92 scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } button .test -text Test -command { set index [.h curselection] set names [eval .h get -full $index] puts "selected names are $names" } button .quit -text Quit -command { exit 0 } blt::table . \ 0,0 .h -fill both \ 2,0 .quit \ 0,1 .vs -fill y 1,0 .hs -fill x \ 3,0 .test blt::table configure . c1 r1 r2 r3 -resize none .h configure -separator "/" -trim $top \ -allowduplicates no #.h entry configure 0 -label [file tail $top] AddDirEntries .h $top focus .h set nodes [.h find -glob -name *.c] eval .h entry configure $nodes -labelcolor red wm protocol . WM_DELETE_WINDOW { destroy . } #blt::bltdebug 100�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/barchart3.tcl���������������������������������������������������������������0000755�0001750�0001750�00000006452�11462120062�015734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl source scripts/stipples.tcl source scripts/patterns.tcl option add *graph.xTitle "X Axis Label" option add *graph.yTitle "Y Axis Label" option add *graph.title "A Simple Barchart" option add *graph.xFont *Times-Medium-R*12* option add *graph.elemBackground white option add *graph.elemRelief raised set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *print.background yellow option add *quit.background red } blt::htext .header -text { This is an example of the barchart widget. To create a postscript file "bar.ps", press the %% button $htext(widget).print -text {Print} -command { $graph postscript output bar.ps -maxpect 1 } $htext(widget) append $htext(widget).print %% button.} set graph [blt::barchart .b] $graph configure \ -invert false \ -baseline 1.2 $graph xaxis configure \ -command FormatLabel \ -descending no $graph legend configure \ -hide yes blt::htext .footer -text {Hit the %% button $htext(widget).quit -text quit -command exit $htext(widget) append $htext(widget).quit %% button when you've seen enough.%% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo -padx 20 %%} set data { One 1 1 red green bdiagonal1 raised Two 2 2 green blue bdiagonal2 raised Three 3 3 blue purple checker2 raised Four 4 4 purple orange checker3 raised Five 5 5 orange brown cross1 raised Six 6 6 brown cyan cross2 raised Seven 7 7 cyan navy cross3 raised Eight 8 8 navy red crossdiag raised Nine 9 -1 pink black "" solid Ten 10 -2 seagreen palegreen hobbes raised Eleven 11 -3 blue blue4 "" raised } foreach { name x y fg bg bitmap relief } $data { $graph element create $name \ -data { $x $y } -fg $fg -bg $bg -stipple $bitmap \ -relief $relief -bd 2 set labels($x) $name } $graph marker create bitmap \ -coords { 4 0.3 } -anchor center \ -bitmap @bitmaps/sharky.xbm \ -name bitmap -fill "" $graph marker create text \ -coords { 10 5.3 } -anchor center \ -text "Hi there" \ -name text -rotate 45 -font "Arial 14" -fg blue $graph marker create polygon \ -coords { 5 0 7 2 10 10 10 2 } \ -name poly -linewidth 1 -fill "" -outline red4 -under yes blt::table . \ .header 0,0 -padx .25i \ $graph 1,0 -fill both \ .footer 2,0 -padx .25i blt::table configure . r0 r2 -resize none wm min . 0 0 proc FormatLabel { w value } { global labels set value [expr int(round($value))] # Determine the element name from the value if { [info exists labels($value)] } { return "$labels($value)" } return "$value" } Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph $graph marker bind all <B3-Motion> { set coords [%W invtransform %x %y] catch { %W marker configure [%W marker get current] -coords $coords } } $graph marker bind all <Enter> { set marker [%W marker get current] catch { %W marker configure $marker -fill green3 } } $graph marker bind all <Leave> { set marker [%W marker get current] catch { %W marker configure $marker -fill "" } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/usmap.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000325537�11462120062�015215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------- # DATA: US Map # ------------------------------------------------------------------------- # COURSE: Effective Tcl/Tk Programming # AUTHOR: Michael J. McLennan # ========================================================================= # Copyright (c) 1997-1999 Cadence Design Systems, Inc. # ========================================================================= # # Coordinates for each map region # ------------------------------------------------------------------------- set us_regions(WV.60) {217.03 79.0715 220.0 85.2274 220.16 85.2624 220.16 85.2624 224.995 86.9429 229.995 82.059 235.0 76.154 235.0 76.1131 235.0 76.1015 239.965 73.289 241.405 72.7755 241.405 72.7755 241.4 72.7697 240.0 70.815 234.995 71.8186 232.615 69.9747 230.0 69.9747 227.405 63.5562 227.405 63.5446 225.0 71.0484 220.0 74.8353 217.035 79.0773 217.03 79.0715 } set us_regions(NV.35) {30.005 54.0568 30.0 59.0925 30.0 59.2675 30.0 69.0586 29.995 75.0278 34.995 79.9001 39.995 84.9123 44.995 90.0938 49.995 95.4387 54.995 100.947 56.825 103.007 56.835 103.012 59.745 89.026 59.79 54.0627 59.76 54.0627 54.995 54.0393 49.995 54.0277 44.995 54.0277 44.87 54.016 40.03 54.0277 35.15 54.0627 30.05 54.0452 30.005 54.0568 } set us_regions(IA.20) {176.795 50.4567 176.815 50.4216 175.0 49.0037 173.91 43.5072 170.02 43.5072 165.055 43.5188 160.045 43.513 155.03 43.5072 150.01 43.513 147.765 43.5072 147.735 43.513 147.785 50.5909 150.0 57.2369 150.01 57.482 150.0 57.7154 151.175 63.918 151.17 63.9238 151.18 63.9238 155.04 63.988 160.065 63.9997 165.07 63.9122 170.005 63.7896 172.905 65.3709 175.0 61.6657 175.01 59.8802 175.0 58.0188 176.785 50.4742 176.795 50.4567 } set us_regions(IA.21) {176.675 51.8687 176.675 51.8512 176.675 51.7812 176.675 51.8512 176.675 51.8687 } set us_regions(PA.49) {227.4 51.7228 227.405 63.5446 227.405 63.5562 230.0 69.9747 232.615 69.9747 232.625 69.9747 235.0 69.9631 240.0 69.9631 245.0 69.9806 250.0 69.9689 251.06 69.9689 252.925 69.4087 254.99 67.8274 255.0 65.1492 254.995 60.5104 256.525 58.5148 256.525 58.5148 255.0 57.4645 250.03 54.0218 245.0 54.0102 240.0 54.0218 235.0 54.0218 231.185 50.515 231.19 50.4041 230.0 51.0402 227.5 51.7053 227.4 51.7228 } set us_regions(IN.19) {205.97 56.1458 205.0 55.6965 200.005 55.6965 195.33 55.6906 194.375 55.6848 193.96 55.6906 193.895 55.6906 190.0 81.2713 190.015 81.4172 190.0 81.6564 189.86 83.4302 190.0 83.4361 194.985 82.5667 199.99 82.0298 204.99 76.6091 205.87 74.2926 205.9 74.281 205.97 56.1458 } set us_regions(KS.22) {156.91 89.0377 155.02 71.8828 155.0 70.284 155.01 68.726 153.46 68.0258 153.46 68.02 150.02 68.0142 145.035 68.0083 140.01 68.0025 135.0 68.0025 130.035 68.0083 125.0 68.0025 120.025 67.9967 119.815 67.9967 119.74 67.9967 119.79 89.0727 119.86 89.0727 120.04 89.0727 125.01 89.0377 130.01 89.0143 135.03 89.0318 140.015 89.0377 145.03 89.0318 150.02 89.0318 155.02 89.0318 156.91 89.0377 } set us_regions(ND.45) {143.825 4.99617 143.815 4.99617 143.81 4.99617 143.645 4.99617 143.535 4.99617 143.205 4.99617 143.05 4.99617 142.945 4.99617 142.875 4.99617 142.85 4.99617 142.75 4.99617 142.685 4.99617 142.215 4.99617 142.195 4.99617 141.89 4.99617 141.875 4.99617 141.805 4.99617 141.75 4.99617 141.69 4.99617 141.595 4.99617 141.57 4.99617 141.56 4.99617 141.5 4.99617 141.28 4.99617 141.25 4.99617 141.045 4.99617 140.985 4.99617 140.925 4.99617 140.905 4.99617 140.895 4.99617 140.715 4.99617 140.685 4.99617 140.58 4.99617 140.575 4.99617 140.455 4.99617 140.355 4.99617 140.25 4.99617 140.25 4.99617 140.205 4.99617 140.0 4.99617 139.835 4.99617 139.605 5.002 139.395 5.002 139.335 5.002 138.97 5.002 138.955 5.002 138.95 5.002 138.945 5.002 138.94 5.002 138.94 5.002 138.85 5.002 138.825 5.002 138.735 5.002 138.69 5.002 138.63 5.002 138.55 5.002 138.285 5.002 138.175 5.002 138.11 5.002 137.73 5.002 137.635 5.002 137.625 5.002 137.57 5.002 137.05 5.002 136.97 5.002 136.89 5.002 136.885 5.002 136.88 5.002 136.87 5.002 136.63 5.002 136.555 5.002 136.53 5.002 136.315 5.002 136.26 5.002 135.66 5.002 135.655 5.002 135.625 5.002 135.625 5.002 135.425 5.002 135.39 5.002 135.315 5.002 135.0 5.002 135.0 5.002 135.0 5.002 134.98 5.002 134.95 5.002 134.89 5.002 134.835 5.002 134.78 5.002 134.335 5.002 134.245 5.002 134.18 5.002 134.115 5.002 133.71 5.00784 133.685 5.00784 133.485 5.00784 133.265 5.00784 133.245 5.00784 133.14 5.00784 133.12 5.00784 133.115 5.00784 133.03 5.00784 132.635 5.00784 132.37 5.00784 132.37 5.00784 132.34 5.00784 132.26 5.00784 132.15 5.00784 132.06 5.00784 132.045 5.00784 131.715 5.00784 131.705 5.00784 131.595 5.00784 131.495 5.00784 131.42 5.00784 131.275 5.00784 131.165 5.00784 131.165 5.00784 130.945 5.00784 130.895 5.00784 130.835 5.00784 130.7 5.00784 130.695 5.00784 130.695 5.00784 130.69 5.00784 130.62 5.00784 130.61 5.00784 130.6 5.00784 130.59 5.00784 130.535 5.00784 130.43 5.00784 130.43 5.00784 130.4 5.00784 130.335 5.00784 130.3 5.00784 130.175 5.00784 130.065 5.00784 129.755 5.00784 129.75 5.00784 129.74 5.00784 129.73 5.00784 129.65 5.00784 129.19 5.00784 129.185 5.00784 129.1 5.00784 129.085 5.00784 129.075 5.00784 128.975 5.00784 128.97 5.00784 128.94 5.00784 128.935 5.00784 128.905 5.00784 128.76 5.00784 128.74 5.00784 128.46 5.00784 128.425 5.00784 128.36 5.00784 128.32 5.00784 128.24 5.00784 128.215 5.00784 128.17 5.00784 128.165 5.00784 128.125 5.00784 127.84 5.00784 127.84 5.002 127.83 5.00784 127.83 5.00784 127.77 5.00784 127.5 5.00784 127.22 5.00784 127.115 5.00784 127.03 5.00784 126.875 5.00784 126.855 5.00784 126.565 5.00784 126.515 5.00784 126.455 5.00784 126.25 5.00784 126.235 5.00784 125.905 5.00784 125.795 5.00784 125.735 5.00784 125.625 5.00784 125.465 5.002 125.43 5.002 125.41 5.00784 125.395 5.00784 125.36 5.00784 125.21 5.00784 125.06 5.00784 125.0 5.00784 124.915 5.00784 124.81 5.00784 124.7 5.00784 124.59 5.00784 124.545 5.00784 124.49 5.00784 124.375 5.00784 124.265 5.00784 124.155 5.00784 124.045 5.00784 123.995 5.00784 123.97 5.00784 123.935 5.00784 123.92 5.00784 123.9 5.00784 123.895 5.00784 123.875 5.00784 123.87 5.00784 123.845 5.00784 123.835 5.00784 123.83 5.00784 123.725 5.00784 123.725 5.00784 123.61 5.00784 123.515 5.00784 123.5 5.00784 123.44 5.00784 123.28 5.00784 123.175 5.00784 123.175 5.00784 122.85 5.00784 122.515 5.00784 122.405 5.002 122.3 5.00784 121.94 5.00784 121.865 5.00784 121.86 5.00784 121.855 5.00784 121.535 5.00784 121.205 5.00784 121.065 5.00784 120.985 5.00784 120.74 5.00784 120.725 5.00784 120.55 5.00784 120.375 5.00784 120.17 5.00784 120.165 5.00784 120.055 5.00784 120.0 5.00784 119.895 5.00784 119.83 5.00784 119.785 5.00784 119.7 5.00784 119.675 5.00784 119.655 5.00784 119.635 5.00784 119.62 5.00784 119.585 5.00784 119.56 5.00784 119.34 5.00784 119.24 5.00784 119.13 5.01367 119.02 5.01367 118.945 5.01367 118.93 5.01367 118.915 5.01367 118.68 5.00784 118.675 5.00784 118.625 5.00784 118.58 5.00784 118.53 5.00784 118.405 5.00784 118.255 5.00784 118.24 5.00784 118.145 5.00784 118.03 5.00784 117.94 5.00784 117.93 5.00784 117.82 5.00784 117.71 5.00784 117.6 5.00784 117.41 5.00784 117.405 5.00784 117.33 5.00784 117.255 5.00784 117.24 5.00784 117.225 5.00784 117.215 5.00784 117.185 5.00784 117.16 5.00784 116.83 5.00784 116.615 5.00784 116.395 5.00784 116.18 5.00784 116.17 5.00784 116.06 5.00784 116.05 5.00784 115.98 5.00784 115.975 5.00784 115.96 5.00784 115.85 5.00784 115.82 5.00784 115.815 5.00784 115.805 5.00784 115.78 5.00784 115.755 5.00784 115.63 5.00784 115.305 5.00784 115.305 5.00784 115.095 5.00784 115.0 5.00784 114.98 5.00784 114.755 5.00784 114.685 5.00784 114.65 5.00784 114.54 5.00784 114.43 5.00784 114.205 5.00784 114.095 5.00784 113.995 5.00784 113.985 5.00784 113.55 5.00784 113.44 5.00784 113.42 5.00784 113.33 5.00784 113.25 5.00784 113.245 5.00784 113.225 5.002 113.11 5.00784 113.0 5.00784 112.965 5.00784 112.89 5.00784 112.8 5.00784 112.78 5.00784 112.675 5.00784 112.66 5.00784 112.565 5.00784 112.345 5.00784 112.18 5.00784 112.125 5.00784 112.02 5.00784 112.015 5.00784 111.905 5.00784 111.365 5.00784 111.25 5.00784 110.965 5.00784 110.96 5.00784 110.95 5.00784 110.74 5.00784 110.72 5.00784 110.71 5.002 110.705 5.002 110.685 5.002 110.675 5.002 110.675 5.002 110.625 5.00784 110.615 5.00784 110.415 5.002 110.405 5.00784 110.39 5.00784 110.385 5.00784 110.155 5.00784 110.155 5.00784 110.12 5.002 110.095 5.00784 110.09 5.002 110.08 5.002 110.055 5.00784 110.04 5.00784 109.94 5.00784 109.9 5.002 109.76 5.002 109.755 5.002 109.775 26.3931 109.83 26.3931 110.05 26.3931 115.02 26.3931 120.005 26.3989 125.095 26.3989 130.07 26.4165 135.025 26.4281 140.005 26.4573 145.005 26.4573 147.185 26.4631 147.185 26.4456 145.0 12.9784 143.855 4.99617 143.85 4.99617 143.825 4.99617 143.825 4.99617 } set us_regions(DC.13) {244.4 75.483 244.805 76.4808 244.82 76.4691 245.0 76.2707 244.995 75.2729 244.4 75.483 } set us_regions(UT.56) {59.79 54.0627 59.745 89.026 59.995 89.0202 64.995 89.026 69.995 89.0202 74.995 89.0085 79.995 89.0377 84.775 89.0318 84.775 89.0318 84.75 61.0122 80.0 61.0355 75.02 61.0355 74.765 54.016 74.765 54.0043 74.755 54.0043 70.0 54.0277 64.995 54.0277 59.995 54.0685 59.79 54.0627 } set us_regions(OR.48) {9.77 31.3237 9.745 31.3645 9.765 31.8955 9.765 31.8955 9.75 32.0122 9.72 32.1348 9.52 32.7007 9.545 32.9458 9.55 32.9458 9.56 33.01 9.56 33.0392 9.555 33.045 9.55 33.0917 9.55 33.1442 9.545 33.1734 9.545 33.1792 9.545 33.2317 9.535 33.2901 9.505 33.4185 9.505 33.5176 9.45 33.7977 9.43 33.8969 9.37 33.9961 9.365 33.9961 9.3 34.1303 9.295 34.3462 9.265 34.5621 9.29 35.0639 9.25 35.3965 9.3 35.5015 9.305 35.5366 9.275 35.5891 9.29 35.8808 9.3 36.0034 9.2 36.3476 9.175 36.5635 9.23 36.7794 9.22 36.9486 9.215 37.0537 9.175 37.4154 9.135 37.6255 9.095 37.7772 9.065 38.0748 9.07 38.2615 9.06 38.6816 9.0 39.1368 9.02 39.3468 8.96 39.7553 8.935 39.8836 8.86 40.8756 8.855 40.8873 8.85 40.9689 8.82 41.1907 8.745 41.6808 8.745 41.6866 8.73 41.7683 8.57 42.3402 8.57 42.6378 8.55 42.7311 8.55 42.7369 8.47 43.0812 8.35 43.513 8.355 43.513 8.3 43.6997 8.235 43.8514 8.12 44.149 7.84 44.3474 7.81 44.3883 7.8 44.3883 7.69 45.1001 7.69 45.1818 7.67 45.2285 7.66 45.2635 7.665 45.6369 7.495 45.9754 7.425 46.1271 7.425 46.1796 7.43 46.3605 7.395 46.8273 7.335 47.014 7.345 47.014 7.24 47.3349 6.87 47.8834 6.87 47.8893 6.6 48.3794 6.505 48.7645 6.51 48.7645 6.87 48.9979 7.21 49.1788 7.28 49.2255 7.325 49.5522 7.405 49.6398 7.4 49.6398 7.495 49.6923 7.625 50.0599 7.55 50.2174 7.495 50.2699 7.495 50.2699 7.485 50.2816 7.47 50.2991 7.28 50.515 7.26 50.515 7.22 50.5675 7.28 51.0985 7.495 51.2269 7.53 51.2444 7.505 51.3202 7.495 51.3903 7.525 51.7637 7.6 52.0613 7.6 52.0613 7.59 52.1488 7.57 52.2655 7.59 52.4464 7.83 52.8548 7.825 52.9715 7.85 53.1408 7.895 53.3216 7.945 53.555 8.115 53.7943 8.12 53.8001 8.255 53.8993 8.34 54.016 8.355 54.0277 8.745 54.0277 10.165 54.0452 15.025 53.9927 20.125 53.9868 25.03 54.0627 30.005 54.0568 30.05 54.0452 35.15 54.0627 40.03 54.0277 44.87 54.016 44.995 40.9631 45.01 38.2965 45.0 34.7197 45.425 26.0488 45.42 26.043 45.0 26.0313 40.015 26.0022 35.005 26.0839 30.0 27.3209 25.07 28.4645 20.01 28.6863 15.015 25.1094 10.005 24.0883 9.37 24.1758 9.2 24.1816 9.225 24.2575 9.37 24.5726 9.775 24.9285 9.8 24.9927 9.86 25.1269 9.86 25.1328 9.91 25.2786 9.92 25.3195 9.92 25.3253 9.98 25.6754 9.975 25.8446 9.96 25.9321 9.885 26.008 9.825 26.078 9.8 26.1072 9.71 26.1422 9.695 26.7374 9.77 26.7782 9.79 26.9008 9.8 27.0933 9.675 27.5251 9.665 27.5484 9.665 27.5543 9.65 27.6885 9.83 27.9511 9.92 28.412 9.92 28.4879 9.91 28.6162 9.9 28.6338 9.895 28.6338 9.855 28.7271 9.845 28.838 9.815 29.0305 9.685 29.7016 9.71 29.9233 9.7 30.3843 9.625 30.5826 9.795 31.0786 9.785 31.2595 9.77 31.3237 } set us_regions(ID.17) {45.42 26.043 45.425 26.0488 45.0 34.7197 45.01 38.2965 44.995 40.9631 44.87 54.016 44.995 54.0277 49.995 54.0277 54.995 54.0393 59.76 54.0627 59.79 54.0627 59.995 54.0685 64.995 54.0277 70.0 54.0277 74.755 54.0043 74.765 54.0043 74.755 36.6919 70.025 36.2601 65.015 36.8786 60.0 28.1319 55.0 19.2336 50.0 12.43 49.755 5.002 49.755 4.99617 49.755 4.99617 49.695 4.99617 49.68 4.99617 49.235 4.99617 49.105 4.99617 49.095 4.99617 49.09 4.99617 48.935 4.99617 48.83 4.99617 48.81 4.99617 48.685 4.99617 48.685 4.99617 48.665 4.99617 48.52 4.99617 48.425 4.99617 48.36 4.99617 48.355 4.99617 48.33 4.99617 48.32 4.99617 48.205 4.99617 48.155 4.99617 47.645 5.002 47.625 5.002 47.585 5.002 47.58 5.002 47.505 5.002 47.495 5.002 47.495 5.002 47.49 5.002 47.485 5.002 47.475 5.002 47.175 5.002 47.03 5.002 46.93 5.002 46.87 5.002 46.49 5.002 46.485 5.002 46.445 5.002 46.325 5.002 46.31 5.002 46.275 5.002 46.245 5.002 46.215 5.002 46.215 5.002 46.21 5.002 45.86 5.002 45.855 5.002 45.79 5.002 45.31 5.00784 45.155 5.00784 44.995 5.00784 44.985 5.00784 44.89 5.00784 44.84 5.00784 44.84 5.17705 45.005 23.8782 45.42 26.043 } set us_regions(TX.55) {126.135 143.863 126.66 144.453 126.755 145.077 126.77 145.135 127.22 146.244 127.26 146.262 127.46 146.857 127.465 147.008 127.455 147.067 127.44 147.102 127.445 147.172 127.495 147.394 128.21 148.794 128.85 150.393 128.94 150.667 128.94 150.667 130.0 151.98 130.025 152.044 130.31 152.353 130.625 153.316 130.625 153.392 130.625 153.468 131.34 154.25 131.365 154.296 131.87 154.547 132.055 154.67 132.315 154.874 132.335 154.944 132.43 155.055 132.44 155.067 132.445 155.096 132.445 155.096 132.43 155.148 132.43 155.148 132.425 155.148 132.39 155.259 132.385 155.329 132.375 155.417 132.375 155.434 132.365 155.504 132.365 155.522 132.42 155.557 132.45 155.551 132.465 155.545 132.47 155.545 132.485 155.545 132.525 155.551 132.6 155.644 132.595 155.685 132.585 155.761 132.575 155.784 132.575 155.79 132.575 155.796 132.53 155.872 132.525 155.983 132.525 155.988 132.54 156.047 132.55 156.105 132.56 156.175 132.485 156.479 132.48 156.508 132.465 156.7 132.43 156.735 132.73 157.19 132.79 157.517 132.85 158.41 132.975 159.046 132.98 159.064 133.075 159.174 133.38 159.933 134.155 162.045 134.165 162.127 134.165 162.133 134.16 162.144 134.85 163.166 134.875 163.177 134.89 163.189 134.905 163.218 134.91 163.23 134.915 163.241 135.0 163.3 135.075 163.288 135.08 163.288 135.085 163.282 135.2 163.265 135.34 163.317 135.36 163.288 135.495 163.451 135.73 163.492 135.86 163.469 135.985 163.486 136.01 163.551 136.1 163.761 136.255 163.778 136.61 164.239 136.85 164.274 136.875 164.239 136.905 164.298 136.93 164.298 137.065 164.245 137.1 164.298 137.145 164.362 137.24 164.321 137.39 164.496 137.46 164.473 137.61 164.508 137.67 164.484 137.755 164.484 138.065 164.939 138.21 164.858 138.41 165.225 138.42 165.231 138.5 165.231 138.5 165.225 138.605 165.225 138.67 165.225 138.64 165.383 138.695 165.465 138.74 165.494 138.97 165.581 138.985 165.599 138.995 165.628 139.08 165.599 139.085 165.605 139.1 165.593 139.145 165.564 139.19 165.599 139.19 165.657 139.22 165.657 139.35 165.529 139.345 165.575 139.375 165.616 139.625 165.791 139.96 165.622 140.0 165.593 140.245 165.616 140.25 165.616 140.4 165.64 140.69 165.558 141.045 165.686 141.11 165.844 141.175 165.733 141.465 165.785 141.64 165.809 141.67 165.838 141.82 166.048 141.83 166.048 141.915 166.188 141.96 166.211 142.1 166.433 142.085 166.486 142.205 166.521 142.315 166.532 142.37 166.742 142.385 166.783 142.385 166.783 142.475 166.807 142.515 166.76 142.55 166.865 142.565 166.853 142.565 166.859 142.595 166.882 142.605 166.877 142.645 166.83 142.65 166.83 142.725 166.894 142.725 166.894 142.875 167.162 142.96 167.052 143.125 167.168 143.125 167.069 143.125 167.052 143.165 166.637 143.295 166.544 144.27 166.351 144.27 166.252 144.545 166.229 144.53 166.048 144.53 166.048 144.555 165.587 144.375 164.321 144.375 164.309 144.165 163.154 144.085 162.745 144.075 162.716 144.035 162.547 144.035 162.547 143.875 161.847 143.75 161.438 143.41 158.171 143.515 157.296 143.56 157.103 143.75 156.298 143.96 155.662 143.965 155.65 144.0 155.545 144.165 155.107 144.175 155.067 144.315 154.705 144.855 153.614 145.0 153.503 145.08 153.415 145.205 152.919 145.625 152.254 145.78 152.044 145.92 151.886 146.25 151.507 146.585 151.169 146.6 151.151 146.61 151.14 146.625 151.128 146.795 150.959 146.905 150.859 147.13 150.673 147.45 150.428 147.5 150.393 147.665 150.294 148.025 150.083 148.125 150.008 148.59 149.418 148.71 149.191 148.71 149.191 148.71 149.191 148.75 149.156 148.825 149.091 149.17 148.823 149.375 148.695 149.61 148.543 149.62 148.543 149.755 148.461 150.0 148.31 150.0 148.31 150.0 148.31 150.0 148.321 150.0 148.315 150.05 148.292 150.625 147.965 150.9 147.796 151.11 147.668 151.7 147.248 151.875 147.125 152.09 146.968 152.34 146.793 152.33 146.793 152.515 146.658 152.895 146.372 152.99 146.372 153.125 146.332 153.53 145.917 153.53 145.917 153.7 145.783 154.52 144.739 154.54 144.604 154.565 144.569 154.74 144.464 154.92 144.359 155.0 144.313 155.0 144.313 155.18 144.167 155.18 144.167 155.44 143.928 155.44 143.928 155.49 143.887 155.8 143.653 155.805 143.653 156.13 143.426 156.135 143.42 156.245 143.315 156.25 143.309 156.25 143.309 156.26 143.292 156.26 143.292 156.825 142.86 156.875 142.714 156.875 142.609 156.875 142.597 156.87 142.574 156.845 142.51 156.77 142.381 157.365 141.961 157.5 141.879 157.505 141.874 157.9 141.658 157.9 141.658 157.905 141.658 158.12 141.541 158.12 141.541 158.125 141.541 158.125 141.564 158.155 141.547 158.165 141.541 158.155 141.541 158.15 141.541 158.155 141.535 158.225 141.494 158.75 141.208 158.75 141.214 159.375 140.87 159.835 140.666 160.0 140.631 160.0 140.631 160.465 140.666 160.47 140.666 160.82 140.864 160.93 140.864 160.895 140.666 160.0 124.31 159.785 116.9 157.57 112.57 155.005 111.001 150.005 110.925 150.0 110.989 150.01 111.076 145.0 110.942 140.0 110.05 135.0 108.503 130.0 106.111 125.025 92.5328 120.035 92.527 115.085 92.527 115.0 92.527 114.99 92.527 114.88 92.5212 110.0 124.036 104.995 124.03 99.995 124.018 97.355 125.547 97.355 125.565 97.45 125.711 97.56 125.804 97.565 125.804 97.57 125.804 97.575 125.804 97.585 125.798 97.635 125.781 97.635 125.775 97.635 125.775 97.635 125.775 97.66 125.716 97.73 125.681 97.74 125.681 97.76 125.699 97.78 125.711 97.815 125.74 97.825 125.746 97.825 125.746 97.84 125.757 97.89 125.763 97.98 125.822 97.98 125.822 98.03 125.857 98.07 125.892 98.16 126.067 98.215 126.119 98.265 126.201 98.31 126.335 98.35 126.428 98.395 126.522 98.46 126.644 98.48 126.697 98.495 126.743 98.515 126.813 98.52 126.831 98.535 126.878 98.535 126.878 98.56 126.936 98.6 127.105 98.705 127.181 98.745 127.222 98.765 127.239 98.935 127.724 99.28 128.021 99.345 128.062 99.37 128.068 99.38 128.074 100.015 128.325 100.08 128.395 100.095 128.412 100.455 128.85 100.46 128.85 100.725 129.124 100.87 129.375 101.245 129.883 101.515 130.116 101.615 130.163 101.645 130.174 101.685 130.192 101.765 130.233 101.935 130.414 101.985 130.46 102.015 130.554 102.085 130.705 102.1 130.764 102.1 130.781 102.14 130.91 102.165 131.009 102.345 131.161 102.395 131.213 102.48 131.26 102.495 131.271 102.505 131.289 102.53 131.347 102.595 131.452 102.605 131.464 102.745 131.569 102.77 131.627 102.855 131.703 102.985 131.797 103.115 132.082 103.19 132.088 103.205 132.117 103.23 132.141 103.54 132.258 103.74 132.462 103.82 132.421 103.93 132.415 103.93 132.421 103.945 132.438 104.16 132.584 104.165 132.584 104.355 132.788 104.37 132.8 104.6 133.139 104.795 133.22 104.97 133.244 104.99 133.29 104.99 133.296 105.005 133.343 105.04 133.36 105.07 133.401 105.07 133.413 105.07 133.419 105.075 133.442 105.1 133.635 105.215 133.769 105.38 133.81 105.405 133.88 105.47 134.002 105.515 134.078 105.52 134.107 105.55 134.195 105.565 134.306 105.595 134.393 105.625 134.457 105.635 134.451 105.64 134.457 105.64 134.539 105.635 134.539 105.66 134.79 105.67 134.901 105.66 134.953 105.76 135.099 105.72 135.222 105.9 135.414 105.915 135.414 105.91 135.473 105.93 135.473 105.94 135.513 105.905 135.613 106.015 135.729 106.075 135.823 106.105 135.846 106.175 135.904 106.185 136.114 106.19 136.12 106.26 136.138 106.24 136.19 106.27 136.219 106.35 136.231 106.38 136.272 106.485 136.552 106.56 136.867 106.575 137.031 106.555 137.06 106.57 137.264 106.57 137.27 106.565 137.293 106.575 137.34 106.57 137.392 106.545 137.544 106.475 137.667 106.505 137.783 106.49 137.83 106.55 137.97 106.565 138.145 106.635 138.349 106.665 138.67 106.72 138.723 106.765 138.857 106.805 138.921 106.82 138.933 106.875 139.084 106.875 139.084 106.93 139.125 106.95 139.172 106.93 139.201 106.95 139.277 107.04 139.37 107.08 139.47 107.11 139.528 107.165 139.668 107.24 139.849 107.255 139.936 107.255 139.995 107.275 140.024 107.395 140.444 107.51 140.567 107.6 140.642 107.625 140.672 107.72 140.788 107.76 140.835 107.805 140.87 107.815 140.876 107.835 140.893 107.855 140.911 108.015 141.063 108.02 141.074 108.03 141.127 108.03 141.133 108.025 141.144 108.025 141.144 108.11 141.238 108.14 141.238 108.19 141.296 108.235 141.331 108.395 141.343 108.415 141.313 108.535 141.389 108.545 141.407 108.555 141.407 108.575 141.413 108.615 141.424 108.635 141.43 108.65 141.442 108.665 141.442 108.68 141.442 108.69 141.465 108.705 141.494 108.73 141.494 108.76 141.518 108.82 141.559 108.82 141.564 108.845 141.687 108.85 141.687 108.855 141.687 108.86 141.681 108.93 141.64 108.935 141.652 108.945 141.658 108.945 141.699 108.93 141.868 109.03 141.984 109.035 141.996 109.095 142.078 109.095 142.107 109.14 142.183 109.145 142.206 109.28 142.329 109.32 142.346 109.37 142.375 109.375 142.375 109.375 142.375 109.535 142.521 109.57 142.591 109.6 142.626 109.615 142.626 109.65 142.638 109.655 142.65 109.715 142.679 109.72 142.685 109.715 142.702 109.735 142.743 109.74 142.743 109.81 142.796 109.87 142.842 109.875 142.842 109.965 142.889 109.995 142.901 110.0 142.906 110.155 142.947 110.155 142.947 110.165 142.947 110.39 143.0 110.485 143.035 110.5 143.029 110.51 143.041 110.64 143.064 110.65 143.076 110.665 143.07 110.72 143.07 110.72 143.07 110.78 143.087 110.92 143.128 110.98 143.221 111.035 143.204 111.09 143.204 111.09 143.204 111.09 143.216 111.125 143.303 111.095 143.344 111.15 143.496 111.275 143.49 111.295 143.519 111.455 143.747 111.71 143.852 111.945 143.881 112.085 143.992 112.105 143.992 112.115 143.98 112.125 143.968 112.285 144.027 112.35 144.062 112.375 144.19 112.55 144.324 112.645 144.441 112.745 144.552 112.84 144.674 112.885 144.744 112.89 144.739 112.915 144.744 112.915 144.768 112.915 144.774 112.97 144.768 113.045 144.797 113.25 144.797 113.28 144.715 113.28 144.721 113.33 144.733 113.365 144.785 113.44 144.861 113.465 144.884 113.45 144.931 113.52 144.995 113.525 144.995 113.57 145.182 113.57 145.188 113.795 145.176 113.805 145.165 113.815 145.153 113.86 145.1 113.88 145.13 113.98 145.13 114.06 145.159 114.08 145.165 114.09 145.17 114.34 145.153 114.475 144.803 114.47 144.744 114.475 144.733 114.495 144.657 114.5 144.645 114.5 144.639 114.515 144.61 114.6 144.429 114.735 144.342 114.925 144.138 114.925 144.132 114.93 144.073 114.96 144.003 114.995 143.98 114.995 143.968 115.0 143.951 115.015 143.863 115.015 143.799 115.05 143.758 115.275 143.717 115.28 143.717 115.385 143.694 115.385 143.694 115.41 143.659 115.42 143.531 115.515 143.064 115.56 142.831 115.58 142.749 115.62 142.568 115.625 142.568 115.69 142.58 115.775 142.469 115.785 142.41 115.785 142.41 115.795 142.399 115.905 142.253 115.87 142.212 115.835 142.165 115.88 141.897 115.87 141.839 115.93 141.734 115.975 141.541 115.965 141.518 115.96 141.383 116.12 141.103 116.18 141.022 116.21 140.852 116.305 140.765 116.295 140.602 116.31 140.572 116.315 140.549 116.375 140.485 116.505 140.251 116.51 140.17 116.515 140.152 116.55 139.983 116.585 139.948 116.945 139.802 116.96 139.802 116.975 139.791 117.045 139.796 117.135 139.703 117.14 139.656 117.17 139.65 117.265 139.82 117.41 139.592 117.495 139.569 117.5 139.569 117.74 139.61 117.905 139.656 118.065 139.68 118.13 139.388 118.18 139.154 118.255 139.003 118.385 138.915 118.395 138.886 118.4 138.886 118.425 138.88 118.515 138.915 118.565 138.944 118.655 138.962 118.745 139.049 118.745 139.02 118.78 139.044 118.87 139.143 119.02 139.184 119.035 139.143 119.085 139.114 119.17 139.26 119.255 139.37 119.26 139.382 119.26 139.382 119.32 139.429 119.41 139.429 119.54 139.493 119.62 139.522 119.625 139.528 119.8 139.429 120.0 139.4 120.09 139.405 120.12 139.33 120.275 139.429 120.54 139.458 120.55 139.458 120.68 139.44 120.725 139.388 120.975 139.429 120.945 139.545 121.06 139.575 121.195 139.569 121.345 139.639 121.41 139.633 121.42 139.645 121.7 139.656 121.87 139.645 121.875 139.645 121.875 139.645 122.24 139.411 123.135 140.152 123.47 140.666 123.445 140.73 123.61 140.695 123.63 140.666 123.73 140.654 123.74 140.666 123.75 140.672 123.75 140.777 123.75 140.87 123.79 141.092 123.785 141.092 123.785 141.092 123.765 141.115 124.1 141.43 124.115 141.436 124.16 141.541 124.16 141.541 124.19 141.605 124.19 141.605 124.24 141.693 124.25 141.71 124.335 141.699 124.35 141.693 124.375 141.716 124.38 141.716 124.38 141.728 124.49 141.745 124.555 141.751 124.68 141.821 124.7 141.85 124.7 141.85 124.705 141.891 124.71 141.897 124.715 141.926 124.805 142.125 124.93 142.416 124.93 142.422 124.95 142.463 124.985 142.486 125.0 142.492 125.0 142.492 125.27 142.626 125.36 142.755 125.4 142.761 125.505 142.871 126.025 143.35 126.135 143.863 } set us_regions(WY.62) {84.75 61.0122 84.995 61.0122 89.995 61.0063 94.995 60.9947 99.995 61.0355 104.995 61.0297 109.735 61.0063 109.735 61.0063 109.735 47.0082 109.71 33.0275 109.7 33.0275 104.995 33.01 99.995 33.0567 94.995 33.0333 89.995 33.0042 84.995 33.01 79.995 32.9867 74.995 32.9983 74.755 36.6919 74.765 54.0043 74.765 54.016 75.02 61.0355 80.0 61.0355 84.75 61.0122 } set us_regions(MA.28) {271.005 53.9577 274.555 57.9955 274.74 58.1005 274.855 58.3923 274.87 58.4156 275.005 58.5381 275.52 58.4273 275.53 59.2208 276.755 58.9407 276.98 58.9232 277.535 59.0574 277.62 59.1275 280.005 59.6993 279.97 57.978 278.83 58.3339 277.55 57.7737 277.485 57.5112 277.485 57.5112 278.13 57.0969 279.53 56.7585 279.61 56.7293 279.66 56.7701 279.975 57.6162 280.02 53.5959 278.615 53.2166 278.385 53.1933 278.13 53.1641 276.88 52.9132 276.815 52.8198 276.62 52.2655 276.705 51.3903 276.76 51.1744 276.915 50.515 276.405 48.7645 276.325 47.8893 276.265 47.8893 274.98 47.9709 269.965 49.0154 267.705 48.9279 265.0 48.8287 263.75 48.7937 263.675 48.7937 262.565 53.6659 262.585 53.6659 265.0 53.7476 270.0 53.8293 271.005 53.9577 } set us_regions(RI.50) {274.555 57.9955 271.005 53.9577 270.465 58.8882 271.045 59.7285 271.355 59.0749 271.74 58.9291 271.875 58.8766 272.125 58.7715 272.455 58.8649 274.555 57.9955 } set us_regions(CT.11) {270.465 58.8882 271.005 53.9577 270.0 53.8293 265.0 53.7476 262.585 53.6659 262.565 53.6659 262.56 53.8059 265.0 60.4053 270.005 58.9466 270.465 58.8882 } set us_regions(OH.46) {227.405 63.5446 227.4 51.7228 227.35 51.7345 224.98 52.248 224.95 52.2538 224.465 52.353 224.045 52.4347 223.545 52.6448 222.525 53.3391 222.235 53.5492 221.875 53.8059 221.875 53.8001 221.67 53.946 221.57 54.016 221.455 54.016 221.06 54.2727 220.145 54.8737 220.0 54.9671 218.75 55.7957 218.335 56.0641 218.26 56.1166 216.37 56.1283 216.25 56.0466 215.97 55.854 215.965 55.854 215.84 55.7665 215.84 55.7665 215.02 55.2122 214.665 54.9788 214.665 54.9729 214.44 54.3019 214.375 54.3603 209.91 55.9999 205.97 56.1458 205.9 74.281 209.99 76.5566 214.98 76.9125 217.02 79.054 217.03 79.0715 217.035 79.0773 220.0 74.8353 225.0 71.0484 227.405 63.5446 } set us_regions(TN.54) {181.335 96.0222 180.005 99.103 178.45 103.03 178.455 103.059 179.99 103.065 185.0 103.065 189.0 103.059 189.0 103.059 190.0 102.989 195.0 103.065 199.965 103.106 201.945 103.135 201.975 103.135 201.98 103.135 205.0 103.118 208.39 103.112 210.0 100.054 214.995 97.6151 219.985 94.8727 221.61 91.9085 221.61 91.9085 221.61 91.9085 219.97 91.8676 214.975 91.8676 211.625 91.821 211.62 91.8326 209.975 91.8968 204.875 91.6926 199.985 91.6226 194.975 91.5175 190.0 91.2958 185.0 92.5095 182.915 92.5328 182.575 92.5445 182.305 92.5387 181.335 96.0222 } set us_regions(CO.10) {114.99 89.026 115.0 89.026 119.775 89.0727 119.79 89.0727 119.74 67.9967 119.74 67.9208 115.0 61.0005 109.995 61.0063 109.735 61.0063 109.735 61.0063 104.995 61.0297 99.995 61.0355 94.995 60.9947 89.995 61.0063 84.995 61.0122 84.75 61.0122 84.775 89.0318 84.775 89.0318 85.195 89.0318 90.015 89.026 95.07 89.026 100.015 89.0552 105.495 89.0727 110.015 89.0552 114.99 89.026 } set us_regions(VA.58) {220.16 85.2624 220.0 85.4141 215.0 90.0413 211.625 91.821 211.625 91.821 214.975 91.8676 219.97 91.8676 221.61 91.9085 221.61 91.9085 221.655 91.9085 225.0 92.0835 230.0 92.2294 235.0 92.2294 240.0 92.2177 245.0 92.2177 250.015 92.1711 251.01 92.1711 250.9 91.6518 250.75 91.1908 250.685 91.0157 250.65 90.8874 250.625 90.8173 250.615 90.7473 250.605 90.7065 250.605 90.7006 250.495 90.1347 250.475 90.0296 250.455 89.9246 250.43 89.8021 250.365 89.4695 250.455 89.0902 250.47 89.026 250.625 88.5534 251.015 88.1507 251.25 87.8007 251.36 87.2755 251.425 87.0946 251.795 86.4878 251.875 86.2485 252.015 85.8693 252.125 85.525 252.225 85.3383 252.365 85.0524 252.36 84.9473 252.305 84.8073 252.42 84.3988 252.5 84.1188 252.535 84.0371 252.65 83.7862 252.65 83.7803 252.65 83.7745 252.775 83.5003 252.955 83.2785 253.125 83.3544 253.625 82.8993 253.75 82.5958 254.06 82.024 254.17 81.8314 250.0 82.3508 245.0 80.0693 244.805 76.4866 244.805 76.4808 244.4 75.483 241.405 72.7755 241.405 72.7755 239.965 73.289 235.0 76.1015 235.0 76.1131 235.0 76.154 229.995 82.059 224.995 86.9429 220.16 85.2624 } set us_regions(MS.31) {174.17 117.005 175.0 120.459 175.005 120.658 175.0 120.891 175.0 121.352 175.0 121.533 175.0 122.7 175.0 131.044 180.0 131.026 184.52 136.879 184.625 136.961 184.755 136.867 184.93 136.867 184.97 136.896 185.0 136.902 185.0 136.902 185.0 136.914 185.335 136.914 185.5 136.85 186.025 136.64 186.59 136.774 186.655 136.791 186.765 136.803 186.91 136.826 187.765 137.013 188.08 136.931 189.0 103.059 189.0 103.059 185.0 103.065 179.99 103.065 178.455 103.059 175.01 110.277 175.0 111.438 175.03 111.619 174.17 117.005 174.17 117.005 } set us_regions(NY.41) {235.345 48.0643 235.215 48.1868 235.015 48.3736 235.0 48.3852 234.78 48.5019 234.77 48.5019 233.44 49.208 233.31 49.278 233.17 49.348 232.94 49.4705 232.52 49.6923 232.34 49.7856 231.685 50.1357 231.19 50.4041 231.185 50.515 235.0 54.0218 240.0 54.0218 245.0 54.0102 250.03 54.0218 255.0 57.4645 256.525 58.5148 259.98 60.7204 260.0 62.5818 259.79 64.4548 260.28 64.3615 260.565 64.5832 260.585 64.5482 261.155 64.2798 261.47 64.2798 261.49 64.2798 261.86 64.2798 262.125 64.3031 262.25 64.3206 262.355 64.344 262.44 64.3615 262.495 64.3673 262.575 64.3731 262.875 64.2798 263.675 64.1281 264.4 63.8246 264.44 63.8071 265.625 63.2936 265.755 63.247 265.96 63.1594 266.09 63.1011 266.25 63.0252 266.36 62.9844 266.535 62.9202 266.955 62.7685 267.06 62.7277 267.29 62.6285 267.715 62.4534 268.125 62.29 268.39 62.1442 268.675 61.9924 268.955 61.8466 269.025 61.8174 269.375 61.6365 269.43 61.6132 269.745 61.4556 270.1 61.2689 271.11 60.4462 271.095 60.3703 271.045 60.1428 271.045 59.7285 270.465 58.8882 270.005 58.9466 265.0 60.4053 262.56 53.8059 262.565 53.6659 263.675 48.7937 263.285 32.9341 263.24 32.9341 263.24 32.9341 263.145 32.9341 263.145 32.9341 263.14 32.9341 263.135 32.9341 263.135 32.9341 263.06 32.94 262.995 32.94 262.79 32.9458 262.74 32.9458 262.735 32.9458 262.58 32.9575 262.47 32.9575 262.415 32.9633 262.405 32.9633 262.34 32.9633 262.2 32.9692 262.135 32.9692 261.985 32.9808 261.875 32.9808 261.8 32.9867 261.74 32.9867 261.625 32.9925 261.425 32.9867 261.365 32.9867 261.215 32.9867 261.185 32.9867 261.07 32.9867 261.04 32.9867 260.99 32.9925 260.985 32.9925 260.94 32.9925 260.925 32.9925 260.305 33.0158 260.21 33.0217 260.14 33.0275 260.0 33.0333 259.99 33.0333 259.925 33.0392 259.865 33.0392 259.765 33.045 259.76 33.045 259.58 33.0567 259.57 33.0567 259.525 33.0567 259.38 33.0625 259.275 33.0683 259.265 33.0683 259.255 33.0683 259.2 33.0683 259.125 33.0683 259.115 33.0683 259.07 33.0683 258.99 33.0683 258.86 33.0625 258.79 33.0625 258.785 33.0625 258.725 33.0625 258.715 33.0625 258.685 33.0683 258.49 33.0625 258.465 33.0625 258.46 33.0625 258.29 33.0625 258.285 33.0625 258.21 33.0567 258.2 33.0567 258.14 33.0567 258.095 33.0508 258.08 33.0508 258.0 33.045 257.885 33.0392 257.875 33.0392 257.79 33.0333 257.775 33.0333 257.75 33.0333 257.73 33.0333 257.71 33.0333 257.57 33.0275 257.535 33.0275 257.465 33.0217 257.46 33.0217 257.455 33.0275 257.425 33.0217 257.27 33.0217 257.205 33.0217 257.14 33.0158 257.08 33.0158 256.985 33.0158 256.97 33.0158 256.93 33.0158 256.92 33.0158 256.875 33.0158 256.875 33.0158 256.855 33.0158 256.815 33.0158 256.81 33.0158 256.795 33.0158 256.79 33.0158 256.765 33.0158 256.75 33.0158 256.71 33.0158 256.695 33.01 256.69 33.01 256.61 33.01 256.57 33.01 256.425 33.01 256.37 33.045 256.3 33.0742 256.215 33.0508 256.19 33.01 256.07 32.975 256.025 32.9633 255.56 33.01 255.305 33.1209 255.265 33.115 254.985 33.2726 254.925 33.3426 254.675 33.506 254.305 33.7102 253.77 33.9611 253.72 34.0078 253.465 34.1653 253.47 34.2412 253.13 34.5329 252.78 34.813 252.71 34.8772 252.6 34.9764 252.55 35.0114 252.505 35.0464 252.5 35.0523 252.495 35.0581 252.47 35.0756 252.395 35.1573 252.1 35.4665 251.95 35.6299 251.695 35.8633 251.31 36.2659 250.945 36.7852 250.7 37.1879 250.625 37.2579 250.49 37.3863 250.4 37.4329 250.1 37.5846 250.085 37.5788 250.06 37.5788 250.05 37.5788 250.045 37.5788 250.0 37.5788 249.775 37.6897 249.645 37.8005 249.375 37.9464 249.18 38.3315 248.99 38.4949 248.675 38.5824 248.515 38.5999 248.235 39.0726 248.22 39.0784 248.125 39.1426 248.0 39.2243 247.505 40.012 247.5 40.012 246.325 42.0543 246.23 42.2235 246.12 42.6086 245.825 42.6086 245.445 42.6086 245.19 42.6086 245.0 42.6086 244.96 42.6086 244.335 42.5969 244.04 42.5969 243.705 42.5911 243.455 42.5911 243.06 42.5911 242.345 42.5911 241.26 42.5911 240.03 42.5969 239.805 42.5911 239.41 42.5969 239.03 42.5911 238.705 42.5911 238.535 42.5911 237.655 42.5794 235.0 43.3613 234.255 44.3883 234.375 44.6333 234.62 45.1235 234.65 45.176 234.72 45.2343 234.72 45.2402 234.72 45.2635 234.725 45.3569 234.73 45.4852 234.75 45.6661 234.735 45.7595 234.735 45.8062 234.745 45.8237 234.76 45.8587 234.775 45.9404 234.74 46.0921 234.71 46.2496 234.71 46.2555 234.68 46.343 234.665 46.3838 234.77 46.5064 234.8 46.5122 234.835 46.5239 234.855 46.5297 234.865 46.5297 234.905 46.5355 234.965 46.553 235.005 46.6231 234.94 47.119 235.085 47.2066 235.135 47.2474 235.34 47.3233 235.39 47.3699 235.42 47.4166 235.43 47.4341 235.44 47.4516 235.46 47.51 235.47 47.5683 235.47 47.6208 235.47 47.6675 235.47 47.6734 235.45 47.7725 235.44 47.8076 235.425 47.8484 235.345 48.0643 } set us_regions(IL.18) {184.335 89.1485 185.0 87.4564 189.85 83.4361 189.86 83.4302 190.0 81.6564 190.015 81.4172 190.0 81.2713 193.895 55.6906 193.96 55.6906 194.9 50.5617 194.375 50.5617 189.995 50.55 185.0 50.5442 180.0 50.4683 176.795 50.4567 176.785 50.4742 175.0 58.0188 175.01 59.8802 175.0 61.6657 172.905 65.3709 172.89 65.3884 175.0 72.0345 180.015 82.2807 184.335 89.1485 } set us_regions(MN.30) {173.91 43.5072 170.03 37.4096 169.99 21.0132 175.0 17.9557 180.0 16.9521 180.215 16.9696 182.585 11.9106 182.555 11.9048 182.5 11.9106 182.16 12.004 182.14 12.0215 182.085 12.0273 182.07 12.004 182.07 12.004 182.07 12.004 182.07 11.9982 182.06 11.9923 182.025 11.9748 182.01 11.969 181.985 11.969 181.97 11.9632 181.965 11.9573 181.955 11.9457 181.91 11.9281 181.885 11.9223 181.88 11.9281 181.875 11.9281 181.875 11.9281 181.875 11.9223 181.83 11.9398 181.81 11.9457 181.72 11.9515 181.67 11.9515 181.655 11.9457 181.64 11.934 181.56 11.9281 181.475 11.9573 181.46 11.934 181.41 11.8873 181.38 11.864 180.885 11.9281 180.855 11.9748 180.855 11.9865 180.845 12.004 180.845 12.004 180.825 12.004 180.825 12.004 180.785 12.004 180.785 12.004 180.785 12.0215 180.76 12.0565 180.685 12.074 180.565 12.0974 180.365 11.9923 180.16 11.9048 180.125 11.8406 180.085 11.829 180.025 11.7881 180.02 11.7764 180.015 11.7589 180.02 11.7414 180.02 11.7298 180.0 11.5839 179.97 11.5489 179.785 11.3738 179.75 11.3563 179.38 11.2513 179.375 11.2513 179.375 11.2513 179.345 11.2279 179.32 11.2163 179.31 11.2163 179.28 11.2163 179.265 11.2279 178.75 11.2805 178.51 11.2863 178.48 11.2746 178.285 11.3388 178.28 11.3446 178.155 11.3446 178.09 11.3505 178.01 11.2863 177.525 11.3038 177.52 11.3096 177.5 11.3096 177.485 11.3096 177.46 11.3096 177.18 11.3096 177.16 11.2921 177.14 11.1521 177.045 11.1638 176.9 11.2221 176.875 11.2221 176.24 11.368 176.19 11.3155 176.165 11.2163 176.13 11.1754 176.13 11.1696 176.125 11.1638 176.12 11.1463 176.12 11.1463 176.105 11.1288 176.08 11.1054 176.065 11.1112 176.075 11.0587 176.03 11.0529 176.025 11.0529 176.04 11.012 176.11 10.8545 176.105 10.8545 176.095 10.8487 176.085 10.8545 175.985 10.802 175.945 10.7436 175.82 10.4752 175.8 10.3994 175.505 10.3177 175.445 10.3702 175.18 10.4461 175.115 10.4694 174.84 10.6853 174.84 10.6853 174.82 10.6795 174.82 10.6795 174.815 10.6795 174.77 10.6795 174.735 10.6911 174.72 10.6853 174.31 10.942 174.31 10.9479 174.11 11.1288 174.085 11.1463 174.05 11.1288 174.05 11.1288 174.05 11.1288 173.75 11.4147 173.75 11.4147 173.69 11.4438 173.465 11.4964 173.445 11.4964 173.36 11.508 173.355 11.508 173.335 11.5197 173.325 11.5197 173.255 11.5022 173.23 11.508 172.885 11.6481 172.84 11.6656 172.81 11.6539 172.805 11.6481 172.795 11.6131 172.79 11.6072 172.745 11.5255 171.795 11.3155 171.54 11.1754 171.445 11.1813 171.465 10.9304 171.455 10.7962 171.385 10.7903 171.29 10.6094 171.25 10.6094 171.205 10.5686 171.01 10.5861 170.7 10.5511 170.625 10.4461 170.465 10.341 170.46 10.3352 170.23 10.2535 170.23 10.2477 170.23 10.2418 170.18 10.2302 170.145 10.2302 170.15 10.2593 170.13 10.2827 170.125 10.2885 170.115 10.2885 170.115 10.2768 170.11 10.271 170.1 10.271 170.0 10.1601 170.0 9.75169 169.545 9.52413 169.54 9.51829 168.52 10.0551 168.525 10.0668 168.65 10.2535 168.65 10.2652 168.375 10.3469 168.33 10.3644 168.165 10.4519 168.15 10.4519 168.105 10.3819 168.08 10.3118 168.08 10.306 168.035 10.1893 168.03 10.1776 167.865 9.86839 167.8 9.80421 167.795 9.79254 167.725 9.68167 167.71 9.6525 167.655 9.54746 167.65 9.52996 167.5 8.91145 167.33 8.87061 166.885 8.93479 166.875 8.93479 166.865 8.93479 166.48 8.63721 166.495 8.59636 166.715 8.503 166.715 8.503 166.73 8.49133 166.765 8.503 166.805 8.503 166.815 8.50884 166.83 8.503 166.835 8.503 166.845 8.45632 166.845 8.44465 166.845 8.44465 166.845 8.43882 166.875 8.40964 166.875 8.40964 166.87 8.40964 166.865 8.4038 166.865 8.36296 166.845 8.29294 166.825 8.20542 166.775 8.19375 166.575 8.19958 166.435 8.21709 166.36 8.22875 165.625 7.88449 165.455 7.83197 165.25 7.62775 165.25 7.59274 165.225 7.58107 165.1 7.62775 165.075 7.63942 165.0 7.63359 164.91 7.62775 164.56 7.61025 164.375 7.62192 164.29 7.62775 164.235 7.63359 164.12 7.63942 164.1 7.62775 164.055 7.58107 164.04 7.57524 163.255 7.62775 163.25 7.64525 163.235 7.69777 163.235 7.69777 163.165 7.74445 163.125 7.76779 163.03 7.77946 163.005 7.77363 162.99 7.75612 162.99 7.75029 162.925 7.76779 162.845 7.8203 162.74 7.85532 162.67 7.89033 162.69 7.98368 162.69 7.98368 162.585 8.19958 162.06 8.29878 162.055 8.29878 162.05 8.29878 161.91 8.33379 161.41 8.38046 161.22 8.39797 161.17 8.39213 161.14 8.39213 161.095 8.39213 161.03 8.39213 160.925 8.31628 160.94 8.15874 160.94 8.15874 160.97 7.97201 160.83 7.62775 160.635 7.58691 160.595 7.58691 160.43 7.56357 160.425 7.56357 160.01 7.51105 159.615 7.49354 159.6 7.49354 159.375 7.49354 159.155 7.46437 158.765 7.42353 158.755 7.41186 158.75 7.40602 158.75 7.40602 158.71 7.16095 158.68 7.11427 158.63 7.1026 158.505 7.03842 158.46 7.03258 158.235 7.07342 158.135 7.04425 158.12 7.03842 158.105 7.02675 158.08 7.02091 157.91 7.03258 157.9 7.03258 157.88 7.06175 157.88 7.06759 157.85 7.09676 157.8 7.13761 157.78 7.14928 157.74 7.15512 157.69 7.13761 157.42 7.09676 157.41 7.09676 157.37 7.09093 157.31 7.08509 157.27 7.01508 157.245 6.99757 157.065 6.98007 157.055 6.97423 157.05 6.97423 157.05 6.96839 157.045 6.96839 157.035 6.95089 156.95 6.88087 156.905 6.84003 156.875 6.83419 156.85 6.82836 156.825 6.82252 156.805 6.81668 156.795 6.81668 156.775 6.75834 156.77 6.7525 156.775 6.7525 156.74 6.71166 156.71 6.68832 156.675 6.6533 156.59 6.58912 156.55 6.55995 156.545 6.55411 156.545 6.55411 156.545 6.54828 156.525 6.45492 156.52 6.42574 156.52 6.39073 156.515 6.31488 156.48 6.23318 156.485 6.19234 156.5 6.169 156.55 6.13399 156.555 6.07564 156.535 6.02896 156.55 5.95894 156.55 5.95894 156.545 5.94143 156.54 5.91809 156.58 5.89475 156.58 5.87725 156.585 5.8189 156.585 5.81307 156.49 5.38128 156.405 5.002 156.405 5.002 156.25 5.002 156.25 4.3018 155.785 2.73218 155.73 2.73218 155.625 2.67967 155.135 2.42293 155.0 2.45794 155.0 2.45794 154.375 2.41709 154.235 2.31207 154.235 2.3179 154.235 2.41709 154.235 2.41709 154.235 2.42876 154.235 2.44043 154.235 2.52213 154.235 2.53963 154.235 2.58631 154.235 2.59798 154.235 2.59798 154.235 2.59798 154.235 2.60382 154.235 2.73802 154.235 2.73802 154.235 2.73802 154.235 2.73802 154.235 2.74386 154.235 2.79054 154.235 2.83721 154.235 2.84305 154.235 2.84888 154.235 2.84888 154.235 2.86055 154.235 2.98309 154.235 3.2515 154.235 3.26317 154.235 3.28067 154.235 3.38571 154.235 3.44989 154.235 3.46156 154.235 3.64828 154.235 3.70663 154.235 3.7358 154.235 3.75331 154.235 3.77082 154.23 4.12675 154.235 4.12675 154.23 4.94949 154.23 5.002 154.23 5.00784 153.75 5.00784 153.585 5.00784 153.525 5.01367 153.46 5.01367 153.425 5.01367 153.42 5.00784 153.385 5.00784 153.295 5.01367 153.22 5.01367 153.155 5.01367 153.13 5.00784 153.125 5.00784 153.125 5.00784 153.12 5.00784 153.025 5.00784 152.875 5.00784 152.805 5.00784 152.745 5.00784 152.63 5.00784 152.585 5.00784 152.58 5.00784 152.5 5.00784 152.5 5.00784 152.5 5.00784 152.475 5.00784 152.32 5.00784 151.915 5.00784 151.785 5.00784 151.71 5.00784 151.695 5.00784 151.695 5.00784 151.69 5.00784 151.675 5.00784 151.41 5.00784 151.205 5.002 151.17 5.002 151.165 5.002 150.725 5.002 150.72 5.002 150.615 5.002 150.52 5.002 150.39 5.002 150.385 5.002 150.27 5.002 150.125 5.002 150.11 5.002 150.0 5.002 149.96 5.002 149.775 5.002 149.375 5.002 149.3 5.002 148.955 5.002 148.75 5.002 148.53 5.002 148.205 5.002 147.975 5.002 147.755 5.002 147.7 5.002 147.51 5.002 147.505 5.002 147.49 5.002 147.47 5.002 147.32 5.002 147.32 5.002 146.875 5.002 146.655 5.002 146.325 5.002 146.25 5.002 146.01 5.002 146.0 5.002 145.99 5.002 145.785 5.002 145.35 5.002 145.345 5.002 145.345 4.99617 145.0 5.002 145.0 5.002 144.69 4.99617 144.58 4.99617 144.47 4.99617 144.245 4.99617 144.16 4.99617 144.1 4.99617 144.09 4.99617 144.07 4.99617 144.03 4.99617 144.02 4.99617 143.985 4.99617 143.98 4.99617 143.965 4.99617 143.92 4.99617 143.86 4.99617 143.855 4.99617 145.0 12.9784 147.185 26.4456 147.185 26.4631 147.735 43.513 147.765 43.5072 150.01 43.513 155.03 43.5072 160.045 43.513 165.055 43.5188 170.02 43.5072 173.91 43.5072 } set us_regions(MI.29) {193.96 55.6906 194.375 55.6848 195.33 55.6906 200.005 55.6965 205.0 55.6965 205.97 56.1458 209.91 55.9999 214.375 54.3603 214.44 54.3019 214.375 54.1094 214.345 54.016 214.34 53.9927 214.315 53.9226 214.31 53.9168 214.29 53.8468 214.28 53.8176 214.265 53.7709 214.255 53.7243 214.275 53.6367 214.275 53.6309 214.325 53.4267 214.33 53.3975 214.335 53.3858 214.335 53.38 214.355 53.3041 214.36 53.2808 214.36 53.275 214.365 53.2575 214.375 53.2108 214.38 53.1874 214.385 53.1641 214.395 53.1349 214.39 53.1291 214.39 53.1116 214.385 53.0941 214.375 53.0532 214.36 52.9599 214.33 52.7907 214.335 52.7206 214.34 52.6623 214.34 52.6448 214.345 52.5923 214.345 52.5631 214.35 52.5164 214.35 52.4931 214.36 52.3705 214.36 52.3414 214.39 52.2888 214.41 52.2597 214.43 52.2188 214.445 52.1896 214.47 52.1255 214.51 52.0088 214.515 51.9854 214.545 51.9387 214.6 51.857 214.605 51.8512 214.63 51.8337 214.68 51.7929 214.685 51.787 214.75 51.7637 214.8 51.7462 214.805 51.7462 214.805 51.7403 214.87 51.717 214.905 51.7053 214.91 51.7053 214.93 51.7053 214.975 51.6995 214.995 51.6937 215.055 51.6878 215.205 51.6353 215.275 51.5828 215.29 51.577 215.34 51.5653 215.38 51.5536 215.38 51.5536 215.385 51.5478 215.43 51.5361 215.445 51.5303 215.47 51.5245 215.505 51.507 215.535 51.5011 215.54 51.5011 215.55 51.4953 215.575 51.4894 215.625 51.4719 215.855 51.3903 215.905 51.3261 215.945 51.2677 216.25 50.8593 216.35 50.7134 216.37 50.69 216.385 50.6725 216.495 50.515 216.495 50.515 216.605 50.3575 216.615 50.3458 216.665 50.2758 216.875 50.1124 217.09 50.1007 217.14 50.0132 217.205 49.949 217.405 49.7098 217.41 49.7039 217.42 49.6573 217.425 49.6398 217.445 49.5814 217.45 49.4414 217.45 49.4063 217.495 49.2021 217.5 49.1905 217.505 49.1788 217.515 49.1496 217.52 49.1379 217.53 49.0971 217.565 49.0212 217.58 48.9862 217.58 48.9162 217.635 48.747 217.59 48.3677 217.6 48.2802 217.61 48.2277 217.64 48.1285 217.65 47.8717 217.69 47.6617 217.76 47.4516 217.765 47.4516 217.785 47.4283 217.815 47.3991 217.89 47.2999 217.92 47.2416 217.925 47.2182 217.925 47.1599 217.92 47.154 217.91 47.1365 217.895 47.119 217.885 47.0198 217.885 47.014 217.91 46.9848 217.92 46.9732 217.95 46.9148 217.95 46.909 218.005 46.7223 218.05 46.5764 218.125 46.378 218.125 46.3955 218.215 46.1388 218.22 46.1388 218.275 45.9754 218.33 45.8237 218.85 44.3591 219.375 42.8186 219.375 42.807 219.33 42.5269 219.275 42.1418 219.03 40.6188 218.9 39.8136 218.75 38.8975 218.75 38.8567 218.55 37.643 218.51 37.3921 218.35 36.4235 218.22 35.6358 218.225 35.6358 218.165 35.2857 218.125 35.0523 218.125 34.9939 218.07 34.7605 218.085 34.7605 217.955 34.002 217.545 31.5513 217.5 31.2712 217.495 31.2595 216.985 30.3843 216.685 30.1917 216.25 29.9116 215.625 29.5323 215.605 29.509 215.0 29.1122 214.805 28.9897 214.375 28.7213 214.235 28.6338 212.58 27.6068 212.5 27.6068 211.815 27.5893 212.26 26.8833 212.405 26.6615 212.5 26.5215 212.83 26.0138 212.82 26.008 212.5 25.6579 211.875 25.1911 210.625 25.4303 210.35 25.5937 210.345 25.5937 210.275 25.6054 210.225 25.6054 210.12 25.2903 210.0 25.2028 209.97 25.1794 209.97 25.1328 209.835 24.8585 209.645 24.7185 209.515 24.4267 209.46 24.3217 209.46 24.3158 209.475 24.2867 209.49 24.2575 209.455 24.1583 209.405 23.8024 209.415 23.6682 209.31 23.4114 209.375 22.7171 209.375 22.7171 209.435 22.507 209.445 22.4778 209.445 22.4778 209.415 22.3961 209.385 22.3611 209.385 22.3611 209.375 22.3436 209.355 22.2969 209.27 22.2911 209.265 22.2911 209.255 22.2969 209.24 22.3028 209.235 22.3086 209.22 22.3144 209.205 22.3144 209.19 22.3203 208.87 22.2678 208.75 22.4662 208.73 22.5012 208.72 22.507 208.68 22.542 208.665 22.5478 208.535 22.5595 208.47 22.5362 208.375 22.507 208.355 22.4953 208.31 22.4662 208.195 22.4487 208.125 22.4487 208.125 22.4487 208.06 22.4895 208.035 22.507 208.015 22.5128 207.995 22.507 207.97 22.507 207.9 22.5012 207.89 22.507 207.775 22.5829 207.685 22.7346 207.665 22.7696 207.62 22.8396 207.215 22.7812 207.215 22.7812 207.215 22.7812 207.05 22.5829 206.985 22.507 205.705 19.7821 204.37 19.006 203.84 18.6792 203.83 18.6734 203.75 18.6267 203.75 18.6092 202.9 18.1308 202.92 18.1308 201.39 17.2555 201.395 17.2555 201.25 17.1563 201.25 17.1738 200.725 16.8646 200.625 16.8062 200.625 16.7887 200.0 16.4328 200.0 16.4736 199.865 16.3803 199.9 16.3803 199.375 16.0885 199.375 16.0418 198.75 15.6859 198.75 15.6625 198.475 15.505 198.435 15.505 198.195 15.3766 198.125 15.3416 198.125 15.3416 197.5 15.0265 197.5 15.0207 196.875 14.6648 196.875 14.6823 196.83 14.6298 196.845 14.6298 196.25 14.2797 196.25 14.303 196.165 14.2563 195.255 13.7545 195.295 13.7545 194.435 13.276 193.75 12.9084 193.695 12.8793 192.115 12.004 192.13 12.004 191.875 11.8698 191.875 11.8581 191.76 11.7998 191.25 11.5547 191.25 11.543 190.625 11.1988 190.625 11.2104 190.46 11.1288 190.445 11.1288 190.0 10.9129 190.0 10.8545 189.135 10.3877 188.78 10.1952 188.75 10.1835 188.75 10.1835 188.46 10.0259 188.18 9.87422 188.125 9.86839 188.125 9.86839 186.735 10.2535 186.73 10.2535 186.25 10.4927 186.25 10.4927 185.985 10.6444 185.145 11.1288 185.14 11.1288 185.0 11.2104 185.0 11.2104 183.625 12.004 183.625 12.004 183.2 12.144 182.84 12.004 182.845 12.004 182.73 11.9573 182.585 11.9106 180.215 16.9696 180.0 23.814 185.0 25.302 190.0 27.4492 195.0 29.8999 195.005 38.915 194.9 50.5558 194.9 50.5617 193.96 55.6906 } set us_regions(MD.27) {232.615 69.9747 234.995 71.8186 240.0 70.815 241.4 72.7697 241.405 72.7755 244.4 75.483 244.995 75.2729 245.0 76.2707 244.82 76.4691 244.805 76.4808 244.805 76.4866 245.0 80.0693 250.0 82.3508 254.17 81.8314 254.375 81.3646 254.44 81.1488 254.71 80.2735 255.0 79.4216 255.0 79.3983 255.0 79.3399 255.07 78.8614 255.035 78.8614 254.755 78.8614 251.06 69.9689 250.0 69.9689 245.0 69.9806 240.0 69.9631 235.0 69.9631 232.625 69.9747 232.615 69.9747 } set us_regions(NE.34) {153.46 68.02 151.17 63.9238 151.175 63.918 150.0 57.7154 150.01 57.482 150.0 57.2369 147.785 50.5909 145.01 48.6945 140.03 48.6595 135.045 47.0257 130.185 47.0257 125.16 47.0257 120.025 47.0198 115.06 47.0082 110.04 47.0023 109.75 47.0082 109.735 47.0082 109.735 61.0063 109.995 61.0063 115.0 61.0005 119.74 67.9208 119.74 67.9967 119.815 67.9967 120.025 67.9967 125.0 68.0025 130.035 68.0083 135.0 68.0025 140.01 68.0025 145.035 68.0083 150.02 68.0142 153.46 68.02 } set us_regions(NJ.37) {259.42 70.6458 259.9 68.8953 259.96 68.4635 260.0 68.1834 260.02 68.0959 260.175 67.3373 260.195 67.1448 260.56 64.6299 260.565 64.5832 260.28 64.3615 259.79 64.4548 260.0 62.5818 259.98 60.7204 256.525 58.5148 256.525 58.5148 254.995 60.5104 255.0 65.1492 254.99 67.8274 252.925 69.4087 254.925 76.5041 255.0 76.4049 255.0 76.4049 255.445 75.8972 255.435 75.8972 256.25 75.3429 256.415 75.022 256.4 75.022 256.875 74.0184 256.875 74.0184 257.08 73.7091 257.085 73.7091 257.085 73.7091 257.44 73.2307 257.445 73.2307 257.545 73.1023 257.545 73.1023 257.675 72.9331 257.735 72.8981 258.125 72.7989 258.445 72.3962 258.725 71.9236 258.75 71.8536 258.84 71.696 258.935 71.521 258.945 71.521 259.375 70.7158 259.42 70.6458 } set us_regions(SC.52) {228.115 121.912 228.125 121.883 228.125 121.638 228.31 121.41 228.315 121.369 228.315 121.369 228.43 121.299 228.43 121.299 228.43 121.299 228.47 121.253 228.695 121.008 228.825 120.698 228.88 120.658 229.075 120.588 229.26 120.576 229.4 120.535 229.66 120.162 230.0 120.15 230.3 119.916 230.61 119.66 230.625 119.648 230.825 119.461 231.1 119.199 231.25 118.837 231.36 118.785 231.705 118.516 231.875 118.3 231.92 118.283 232.355 117.909 232.8 117.326 233.125 117.407 233.5 117.034 233.69 116.684 234.61 115.704 234.605 115.645 234.58 114.408 234.85 113.807 235.0 113.632 235.085 113.533 235.365 113.031 235.37 113.02 235.415 112.955 235.57 112.745 235.625 112.669 235.625 112.669 235.635 112.658 235.635 112.658 235.77 112.494 235.815 112.442 235.825 112.424 235.87 112.366 235.93 112.296 235.945 112.278 236.06 112.162 236.105 112.115 236.2 112.022 236.25 111.981 236.305 111.94 236.31 111.934 236.435 111.835 236.46 111.812 236.5 111.782 236.735 111.637 236.8 111.607 236.875 111.572 236.895 111.567 237.5 111.345 237.505 111.345 237.5 111.339 235.0 108.357 229.995 104.372 225.0 102.546 219.995 101.711 214.985 102.826 214.455 103.024 215.0 106.724 219.995 113.405 224.995 123.342 226.25 123.674 226.285 123.674 226.27 123.488 226.325 123.394 226.41 123.347 226.51 123.254 226.555 123.207 226.6 123.161 226.635 123.114 226.87 123.003 226.875 122.997 226.9 122.974 226.91 122.968 226.92 122.962 227.065 122.898 227.53 122.285 227.515 122.285 227.615 122.256 227.705 122.198 228.005 122.11 228.105 121.941 228.11 121.912 228.115 121.912 } set us_regions(AR.2) {174.17 117.005 174.17 117.005 175.03 111.619 175.0 111.438 175.01 110.277 178.455 103.059 178.45 103.03 180.005 99.103 181.335 96.0222 180.02 96.0338 175.015 92.5387 170.015 92.5387 165.01 92.5445 160.005 92.5328 156.91 92.5328 156.91 92.5328 157.57 112.57 159.785 116.9 160.0 116.9 165.0 116.911 170.0 116.981 174.15 117.005 174.17 117.005 } set us_regions(OK.47) {114.99 89.026 114.99 92.527 115.0 92.527 115.085 92.527 120.035 92.527 125.025 92.5328 130.0 106.111 135.0 108.503 140.0 110.05 145.0 110.942 150.01 111.076 150.0 110.989 150.005 110.925 155.005 111.001 157.57 112.57 156.91 92.5328 156.91 89.0377 155.02 89.0318 150.02 89.0318 145.03 89.0318 140.015 89.0377 135.03 89.0318 130.01 89.0143 125.01 89.0377 120.04 89.0727 119.86 89.0727 119.79 89.0727 119.775 89.0727 115.0 89.026 114.99 89.026 } set us_regions(KY.23) {189.86 83.4302 189.85 83.4361 185.0 87.4564 184.335 89.1485 182.915 92.5328 185.0 92.5095 190.0 91.2958 194.975 91.5175 199.985 91.6226 204.875 91.6926 209.975 91.8968 211.62 91.8326 211.625 91.821 211.625 91.821 215.0 90.0413 220.0 85.4141 220.16 85.2624 220.16 85.2624 220.0 85.2274 217.03 79.0715 217.02 79.054 214.98 76.9125 209.99 76.5566 205.9 74.281 205.87 74.2926 204.99 76.6091 199.99 82.0298 194.985 82.5667 190.0 83.4361 189.86 83.4302 } set us_regions(KY.24) {182.305 92.5387 182.575 92.5445 182.305 92.5387 } set us_regions(AZ.1) {84.75 128.71 84.775 89.0318 84.775 89.0318 79.995 89.0377 74.995 89.0085 69.995 89.0202 64.995 89.026 59.995 89.0202 59.745 89.026 56.835 103.012 56.4 119.0 56.355 119.094 56.35 119.135 56.295 119.245 56.265 119.35 56.26 119.386 56.245 119.415 56.235 119.426 56.18 119.531 56.1 119.607 56.09 119.654 56.09 119.66 55.995 119.852 56.0 119.911 56.04 120.068 56.025 120.179 55.98 120.418 55.93 120.576 56.05 120.623 56.09 120.64 56.11 120.652 56.225 120.698 56.325 120.739 56.89 120.978 56.935 120.996 57.18 121.101 57.87 121.393 58.25 121.556 58.355 121.603 58.36 121.603 58.475 121.649 58.56 121.69 58.565 121.69 58.6 121.708 58.62 121.714 58.795 121.79 58.85 121.813 58.985 121.871 59.11 121.924 59.14 121.941 59.225 121.976 59.275 121.994 59.39 122.046 59.41 122.052 59.445 122.07 59.46 122.075 59.51 122.099 59.54 122.11 59.665 122.163 59.785 122.215 59.845 122.245 59.905 122.268 60.03 122.321 60.145 122.373 60.185 122.391 60.2 122.396 60.25 122.42 60.255 122.42 60.3 122.443 60.355 122.461 60.455 122.507 60.475 122.513 60.56 122.554 60.615 122.577 60.625 122.583 60.705 122.612 60.755 122.636 60.91 122.706 61.075 122.776 61.09 122.781 61.29 122.869 61.395 122.916 61.48 122.951 61.665 123.032 61.805 123.097 61.945 123.155 63.33 123.768 63.415 123.803 63.485 123.832 63.585 123.878 63.615 123.89 63.86 123.995 63.915 124.018 63.955 124.042 64.145 124.124 64.585 124.316 65.62 124.748 65.64 124.76 65.655 124.765 65.665 124.765 65.845 124.847 65.91 124.87 65.915 124.876 65.96 124.894 66.025 124.923 66.125 124.964 66.25 125.022 66.375 125.075 66.41 125.086 66.51 125.133 66.61 125.174 66.66 125.197 66.775 125.244 66.825 125.267 66.87 125.285 66.88 125.291 66.96 125.326 67.155 125.407 67.22 125.436 67.23 125.442 67.325 125.483 67.48 125.547 67.765 125.67 67.835 125.699 67.915 125.734 67.925 125.74 68.005 125.775 68.045 125.792 68.06 125.798 68.175 125.851 68.42 125.956 68.45 125.967 68.77 126.107 69.0 126.207 69.145 126.271 69.21 126.3 69.285 126.335 69.37 126.37 69.435 126.399 69.54 126.446 69.62 126.481 69.735 126.533 69.81 126.563 69.835 126.574 69.86 126.586 69.91 126.609 69.995 126.644 70.03 126.662 70.045 126.668 70.105 126.691 70.14 126.708 70.71 126.959 70.95 127.07 71.03 127.099 71.15 127.158 71.305 127.222 71.675 127.391 71.7 127.403 71.705 127.403 71.815 127.449 71.86 127.473 71.885 127.484 71.99 127.531 72.1 127.578 72.18 127.613 72.2 127.619 72.275 127.654 72.42 127.718 72.45 127.735 72.485 127.747 72.51 127.765 72.54 127.77 72.565 127.782 72.58 127.794 72.71 127.852 72.745 127.864 72.78 127.881 72.79 127.887 72.93 127.951 73.075 128.015 73.09 128.021 73.165 128.056 73.17 128.056 73.21 128.074 73.215 128.074 73.24 128.085 73.285 128.109 73.37 128.144 73.435 128.173 73.575 128.237 73.66 128.278 73.745 128.313 73.885 128.377 73.915 128.389 74.205 128.523 74.295 128.558 74.355 128.587 74.48 128.646 74.51 128.657 74.58 128.692 74.665 128.71 74.84 128.71 74.935 128.71 75.05 128.71 75.115 128.71 75.15 128.71 75.175 128.71 75.275 128.71 75.29 128.71 75.29 128.71 75.295 128.71 75.295 128.71 75.41 128.704 75.435 128.704 75.445 128.704 75.545 128.704 75.555 128.704 75.66 128.704 75.75 128.704 75.765 128.704 76.025 128.704 76.105 128.704 76.16 128.704 76.195 128.704 76.345 128.704 76.58 128.704 76.595 128.704 76.67 128.704 76.73 128.704 76.815 128.704 76.89 128.704 76.9 128.704 77.015 128.704 77.035 128.704 77.05 128.704 77.23 128.704 77.33 128.704 77.425 128.704 77.475 128.704 77.59 128.71 77.69 128.71 77.7 128.71 77.805 128.71 77.885 128.71 78.065 128.71 78.08 128.71 78.4 128.704 78.63 128.704 78.745 128.704 79.245 128.698 79.32 128.698 79.37 128.698 79.495 128.698 79.98 128.704 79.985 128.704 79.995 128.704 80.045 128.704 80.06 128.704 80.12 128.704 80.19 128.704 80.215 128.704 80.23 128.704 80.305 128.704 80.325 128.704 80.41 128.698 80.415 128.698 80.62 128.698 80.735 128.698 80.83 128.698 80.96 128.698 80.98 128.698 81.035 128.698 81.045 128.698 81.085 128.698 81.26 128.698 81.28 128.698 81.35 128.698 81.38 128.698 81.415 128.698 81.605 128.698 81.675 128.698 81.765 128.698 81.855 128.698 82.105 128.698 82.155 128.698 82.17 128.698 82.185 128.698 82.195 128.698 82.2 128.698 82.2 128.698 82.245 128.698 82.27 128.698 82.295 128.698 82.315 128.698 82.345 128.698 82.36 128.698 82.365 128.698 82.445 128.698 82.53 128.698 82.565 128.698 82.57 128.698 82.665 128.698 83.3 128.698 83.495 128.698 83.5 128.698 83.515 128.698 83.63 128.698 83.64 128.698 83.655 128.698 83.67 128.698 83.7 128.698 83.735 128.698 83.96 128.704 84.1 128.704 84.235 128.704 84.34 128.71 84.34 128.71 84.555 128.71 84.75 128.71 } set us_regions(NH.36) {267.705 48.9279 269.965 49.0154 274.98 47.9709 276.265 47.8893 276.325 47.8893 276.325 47.8893 276.525 47.3174 277.125 47.5917 275.0 39.5802 274.59 30.9911 274.58 30.8744 273.97 31.2362 273.27 31.1078 273.185 31.1486 273.1 31.3295 273.035 31.3412 272.94 31.3529 272.87 31.3762 272.785 31.3645 272.84 31.4054 272.96 31.6796 272.95 31.6971 272.825 31.9889 272.86 32.0939 272.66 32.4207 272.605 32.4207 272.52 32.5257 272.51 32.5432 272.49 32.9166 272.5 32.9166 269.995 37.7305 267.705 48.9279 } set us_regions(NM.40) {97.355 125.547 99.995 124.018 104.995 124.03 110.0 124.036 114.88 92.5212 114.99 92.527 114.99 89.026 110.015 89.0552 105.495 89.0727 100.015 89.0552 95.07 89.026 90.015 89.026 85.195 89.0318 84.775 89.0318 84.775 89.0318 84.75 128.71 84.82 128.71 84.86 128.71 84.995 128.71 85.015 128.71 85.565 128.71 85.695 128.71 85.745 128.71 85.89 128.71 86.205 128.71 86.22 128.71 86.405 128.704 86.715 128.704 86.825 128.704 86.91 128.704 87.31 128.704 87.35 128.704 87.35 128.704 88.005 128.704 88.055 128.704 88.16 128.704 88.16 128.704 88.86 128.704 88.955 128.546 88.96 128.401 88.96 128.033 88.96 127.829 88.955 127.537 88.955 127.537 88.955 127.537 88.955 127.531 88.955 127.508 88.955 127.467 88.955 127.333 88.96 127.204 88.96 126.994 88.96 126.913 88.96 126.831 88.96 126.743 88.96 126.627 88.96 126.493 88.96 126.212 88.96 126.172 88.96 125.985 88.96 125.979 88.96 125.973 88.96 125.553 89.005 125.553 89.18 125.553 89.475 125.553 89.585 125.553 89.61 125.553 89.74 125.553 90.18 125.553 90.67 125.553 90.76 125.553 91.13 125.553 91.46 125.553 91.495 125.553 91.835 125.553 91.85 125.553 91.86 125.553 91.865 125.553 91.875 125.553 91.88 125.553 92.46 125.553 92.585 125.553 92.89 125.553 92.89 125.553 93.515 125.547 93.61 125.547 94.25 125.553 94.995 125.553 94.995 125.553 95.01 125.553 95.01 125.553 95.03 125.553 95.04 125.553 95.065 125.553 95.695 125.547 96.15 125.547 96.245 125.547 96.245 125.553 96.99 125.547 97.0 125.547 97.165 125.547 97.34 125.547 97.34 125.547 97.355 125.547 97.355 125.547 97.355 125.547 } set us_regions(LA.25) {184.625 136.961 184.52 136.879 180.0 131.026 175.0 131.044 175.0 122.7 175.0 121.533 175.0 121.352 175.0 120.891 175.005 120.658 175.0 120.459 174.17 117.005 174.15 117.005 170.0 116.981 165.0 116.911 160.0 116.9 159.785 116.9 160.0 124.31 160.895 140.666 160.93 140.864 161.14 140.666 161.25 140.281 161.875 140.111 162.835 140.006 163.07 140.036 163.125 140.094 163.305 140.17 163.415 140.135 163.88 139.954 163.925 139.966 164.32 140.076 164.375 140.1 164.63 140.216 164.805 140.292 164.93 140.333 164.935 140.339 165.0 140.356 165.53 140.666 165.625 140.73 165.665 140.747 166.115 141.004 166.165 141.028 166.25 141.074 166.25 141.074 166.915 141.343 167.87 141.518 168.015 141.541 168.015 141.541 168.46 141.669 168.925 141.541 168.915 141.541 169.78 141.494 169.785 141.541 169.795 141.605 170.0 141.815 170.085 141.821 170.32 142.037 170.51 142.416 170.59 142.486 170.625 142.515 170.625 142.515 170.955 142.416 171.25 142.37 172.04 142.51 172.5 142.708 172.685 142.801 173.23 143.362 174.815 144.161 174.815 144.161 174.82 144.167 174.82 144.167 175.0 144.213 175.015 144.208 175.135 144.202 175.055 144.301 175.0 144.348 175.0 144.348 174.91 144.674 175.0 144.884 175.23 145.024 175.23 145.024 175.26 145.042 176.045 145.13 176.54 145.042 176.55 145.042 177.035 144.861 177.05 144.855 177.315 144.832 177.5 144.937 177.78 145.03 177.79 145.03 177.825 145.042 177.955 145.077 177.955 145.077 178.075 145.054 178.095 145.042 178.095 145.042 178.84 144.814 178.87 144.814 179.375 144.517 179.72 144.19 179.75 144.167 179.9 144.003 180.015 143.922 180.5 143.402 180.53 143.373 180.545 143.35 180.625 143.292 180.785 143.239 180.85 143.204 181.41 143.292 181.41 143.292 181.58 143.391 181.875 143.612 181.95 143.642 182.115 143.694 182.19 143.723 182.255 143.752 182.33 143.799 182.5 143.963 182.505 143.968 182.58 144.143 182.59 144.167 182.595 144.184 182.625 144.243 182.66 144.342 182.675 144.429 182.675 145.042 182.61 145.917 182.685 145.993 182.7 146.005 183.09 145.917 183.125 145.865 183.43 145.404 183.665 145.065 183.675 145.042 183.75 145.013 183.75 145.013 183.765 145.042 183.955 145.287 184.375 145.561 184.705 145.089 184.73 145.042 184.73 145.042 185.0 144.552 185.0 144.552 185.23 143.77 185.125 143.362 185.0 143.14 184.58 142.807 184.575 142.807 184.44 142.661 184.44 142.661 184.375 142.445 184.355 142.416 184.375 141.856 184.775 141.634 184.825 141.541 185.0 141.313 185.0 141.313 185.065 141.197 185.605 140.508 185.625 140.479 185.625 140.467 186.135 138.04 186.115 138.04 185.98 137.637 185.625 137.322 185.31 137.597 185.485 138.04 185.47 138.04 185.0 138.915 185.0 138.927 184.655 139.791 185.0 140.123 185.01 140.228 185.0 140.257 184.76 140.508 184.74 140.567 184.73 140.666 184.395 141.022 184.375 141.057 184.255 141.22 184.125 140.602 184.125 140.59 184.375 139.067 184.61 138.915 184.59 138.489 184.375 138.104 184.37 138.098 184.37 138.098 184.32 138.04 184.375 137.952 184.375 137.958 184.375 137.381 184.32 137.165 184.34 137.153 184.375 137.13 184.625 136.961 } set us_regions(VT.57) {269.21 32.9692 269.14 32.9692 269.095 32.9692 269.02 32.9692 268.945 32.975 268.765 32.975 268.725 32.9808 268.715 32.9808 268.71 32.9808 268.625 32.9808 268.62 32.9808 268.58 32.9808 268.355 32.975 268.165 32.9692 268.125 32.9633 268.03 32.9633 267.995 32.9633 267.94 32.9575 267.92 32.9575 267.91 32.9575 267.835 32.9517 267.785 32.9517 267.755 32.9517 267.48 32.9517 267.23 32.9517 267.105 32.9341 267.09 32.9283 267.075 32.9283 267.065 32.9283 267.06 32.9283 267.05 32.9225 266.905 32.9108 266.69 32.905 266.68 32.905 266.66 32.905 266.63 32.905 266.5 32.8991 266.485 32.8991 266.445 32.8991 266.36 32.8991 266.11 32.8991 265.87 32.8933 265.865 32.8933 265.835 32.8933 265.785 32.8933 265.465 32.8991 265.345 32.905 265.335 32.905 265.11 32.905 265.035 32.905 265.015 32.905 264.925 32.905 264.92 32.905 264.76 32.8991 264.74 32.8991 264.7 32.8991 264.685 32.8991 264.575 32.8991 264.57 32.8991 264.545 32.905 264.375 32.905 264.15 32.9108 264.04 32.9166 263.95 32.9166 263.94 32.9166 263.795 32.9225 263.785 32.9225 263.69 32.9225 263.595 32.9283 263.52 32.9341 263.515 32.9283 263.325 32.9341 263.325 32.9341 263.285 32.9341 263.675 48.7937 263.75 48.7937 265.0 48.8287 267.705 48.9279 269.995 37.7305 272.5 32.9166 272.49 32.9166 272.475 32.9166 272.47 32.9166 272.22 32.9225 272.2 32.9225 272.02 32.9225 272.005 32.9225 271.94 32.9225 271.93 32.9225 271.79 32.9283 271.645 32.9283 271.585 32.9283 271.555 32.9283 271.51 32.9283 271.185 32.9283 271.035 32.9341 271.03 32.9341 271.025 32.9341 271.025 32.9341 271.025 32.9341 271.005 32.9341 270.905 32.94 270.68 32.9458 270.51 32.9517 270.23 32.9517 270.11 32.9575 270.06 32.9575 270.0 32.9575 269.93 32.9633 269.885 32.9633 269.85 32.9633 269.815 32.9633 269.74 32.9633 269.64 32.9692 269.56 32.9692 269.555 32.9692 269.545 32.9692 269.53 32.9692 269.52 32.9692 269.51 32.9692 269.5 32.9692 269.47 32.9692 269.455 32.9692 269.45 32.9692 269.45 32.9692 269.44 32.9692 269.35 32.9692 269.29 32.9692 269.265 32.9692 269.21 32.9692 } set us_regions(CA.3) {24.25 99.424 24.34 99.529 24.37 99.5698 24.705 99.9725 24.715 99.99 24.85 100.124 24.89 100.142 24.995 100.159 25.035 100.153 25.08 100.177 25.345 100.381 25.355 100.463 25.36 100.503 25.37 100.55 25.36 100.696 25.295 100.883 25.235 101.034 25.2 101.192 25.195 101.279 25.62 101.91 26.135 102.254 26.245 102.266 26.405 102.26 26.41 102.266 26.46 102.295 26.49 102.312 26.525 102.324 26.55 102.336 26.555 102.394 26.53 102.791 26.52 102.855 26.485 103.03 26.44 103.228 26.36 103.532 26.33 103.724 26.375 103.905 26.52 104.582 26.49 104.781 26.48 105.656 27.06 106.531 27.205 106.613 27.495 107.208 27.91 107.249 28.875 107.097 29.37 107.103 29.89 107.173 29.995 107.237 30.215 107.336 30.24 107.348 30.36 107.406 30.42 107.43 30.7 107.54 30.715 107.546 30.73 107.552 30.805 107.552 30.905 107.523 31.06 107.505 31.22 107.587 31.22 107.587 31.25 107.605 31.3 107.628 31.325 107.645 31.405 107.675 31.45 107.675 31.555 107.622 31.58 107.605 31.7 107.517 31.705 107.511 31.94 107.459 31.95 107.465 32.115 107.54 32.195 107.605 32.305 107.645 32.325 107.657 32.35 107.657 32.495 107.745 33.12 108.281 33.24 108.346 33.33 108.375 33.35 108.427 33.355 108.433 33.355 108.433 33.355 108.439 33.355 108.439 33.45 108.719 33.495 108.847 33.555 109.005 33.695 109.227 33.79 109.367 33.835 109.448 33.865 109.513 33.91 109.594 34.71 109.898 34.71 109.898 35.075 110.032 35.24 110.085 35.335 110.09 36.13 110.33 36.31 110.195 36.45 110.184 36.515 110.184 36.855 110.131 37.15 110.108 37.15 110.108 37.155 110.114 37.185 110.12 37.205 110.12 37.215 110.12 37.245 110.155 37.26 110.178 37.275 110.195 37.29 110.23 37.315 110.265 37.37 110.341 37.38 110.359 37.395 110.394 37.43 110.458 37.495 110.604 37.505 110.615 37.575 110.738 37.62 110.814 37.7 110.96 37.72 111.001 37.76 111.076 37.775 111.129 37.765 111.181 37.715 111.24 37.64 111.322 37.585 111.403 37.575 111.45 37.59 111.794 37.63 111.882 38.24 112.366 38.325 112.401 38.535 112.401 38.63 112.389 38.745 112.284 38.78 112.238 38.865 112.197 39.155 112.191 39.22 112.179 39.37 112.15 39.4 112.214 39.65 112.582 39.695 112.629 39.715 112.652 39.72 112.658 39.995 112.879 39.995 112.879 40.0 112.885 40.01 112.891 40.015 112.897 40.055 112.932 40.055 112.932 40.21 113.072 40.44 113.265 40.47 113.288 40.64 113.399 40.65 113.41 40.815 113.527 40.82 113.533 40.865 113.556 40.88 113.568 40.915 113.597 40.995 113.714 41.01 113.726 41.065 113.836 41.145 113.965 41.245 114.099 41.465 114.21 41.545 114.286 41.56 114.303 41.575 114.321 41.6 114.344 41.655 114.397 41.67 114.408 41.87 114.636 41.945 114.694 42.44 115.243 42.46 115.284 42.495 115.336 42.815 115.779 42.95 116.1 42.975 116.159 43.12 116.509 43.125 116.521 43.125 116.526 43.18 116.783 43.18 116.789 43.215 116.935 43.24 117.046 43.26 117.145 43.27 117.197 43.33 117.46 43.295 118.178 43.315 118.254 43.335 118.341 43.35 118.434 43.355 118.499 43.365 118.761 43.365 118.779 43.37 118.86 43.38 119.047 43.51 119.543 43.605 119.66 43.745 119.73 43.865 119.701 43.885 119.689 43.885 119.701 43.94 119.952 43.975 120.331 44.37 120.296 44.375 120.296 44.405 120.29 44.665 120.261 44.685 120.255 44.79 120.243 44.8 120.243 44.845 120.237 44.85 120.237 44.86 120.237 44.865 120.237 44.87 120.237 44.945 120.226 45.015 120.22 45.305 120.185 45.31 120.185 45.36 120.179 45.41 120.173 45.495 120.162 45.535 120.156 45.62 120.144 45.715 120.132 45.855 120.115 45.88 120.115 45.89 120.115 45.915 120.109 46.025 120.097 46.07 120.092 46.09 120.092 46.215 120.074 46.27 120.068 46.555 120.039 46.865 119.998 46.87 119.998 46.92 119.992 47.125 119.969 47.18 119.963 47.295 119.952 47.32 119.946 47.325 119.946 47.425 119.934 47.725 119.899 47.8 119.893 47.805 119.893 47.825 119.887 47.91 119.881 47.93 119.876 48.05 119.864 48.105 119.858 48.26 119.841 48.465 119.817 48.495 119.811 48.6 119.8 48.645 119.8 48.945 119.765 48.955 119.759 48.985 119.759 49.01 119.759 49.065 119.753 49.07 119.747 49.17 119.741 49.47 119.706 49.485 119.701 49.62 119.689 49.83 119.666 50.09 119.636 50.46 119.601 50.475 119.596 51.54 119.485 51.69 119.467 52.335 119.397 52.4 119.391 52.42 119.391 52.42 119.391 52.465 119.386 52.465 119.386 52.495 119.386 52.5 119.38 52.515 119.38 52.52 119.38 52.52 119.38 52.525 119.38 52.55 119.38 52.57 119.374 52.605 119.374 52.61 119.374 52.63 119.368 52.675 119.362 53.155 119.321 53.315 119.304 55.095 119.129 56.245 119.018 56.315 119.012 56.35 119.006 56.355 119.006 56.365 119.006 56.365 119.006 56.37 119.006 56.4 119.006 56.4 119.0 56.835 103.012 56.825 103.007 54.995 100.947 49.995 95.4387 44.995 90.0938 39.995 84.9123 34.995 79.9001 29.995 75.0278 30.0 69.0586 30.0 59.2675 30.0 59.0925 30.005 54.0568 25.03 54.0627 20.125 53.9868 15.025 53.9927 10.165 54.0452 8.745 54.0277 8.355 54.0277 8.365 54.0335 8.54 54.4536 8.54 54.4595 8.595 54.8913 8.6 54.8913 8.595 54.9204 8.35 54.8913 8.14 54.8096 8.12 54.8096 8.12 54.8096 7.905 54.8913 7.805 55.2238 8.12 55.6556 8.12 55.6615 8.155 55.6731 8.24 55.7665 8.42 55.9182 8.58 56.0232 8.745 56.1341 8.82 56.1574 8.955 56.2975 8.965 56.6126 8.975 56.6418 9.06 56.986 9.245 57.517 9.315 57.7679 8.855 58.8415 9.19 59.0166 9.13 59.2208 9.12 59.2675 9.125 59.2792 9.125 59.2908 8.78 59.9093 8.745 60.0552 8.745 60.1252 8.745 60.1369 8.745 60.1428 8.745 60.1486 8.75 60.1544 8.91 60.7788 8.93 60.8254 8.935 60.8371 8.935 60.8371 9.03 61.2747 9.03 61.2747 8.985 61.4673 8.98 61.479 8.85 61.8933 8.82 61.9749 8.595 62.4242 8.445 62.7685 8.165 63.3112 8.155 63.3287 8.12 63.4162 8.02 63.6438 7.65 64.7524 7.785 65.3943 8.12 66.6138 8.69 67.1448 8.745 67.2148 8.98 67.4482 8.985 67.454 9.325 68.0025 9.34 68.02 9.335 68.02 9.37 68.0667 9.995 68.8194 10.04 68.8544 10.485 69.7705 10.62 70.2198 10.81 71.1359 10.765 71.3518 10.735 71.416 10.635 71.521 10.625 71.5735 10.62 71.661 10.62 71.6669 10.605 71.7252 10.56 72.0286 10.55 72.0987 10.515 72.3904 10.52 72.4488 10.595 72.7872 10.605 72.9097 10.62 72.9797 10.62 72.9856 10.66 73.1315 10.97 74.1467 10.97 74.1467 11.035 74.3043 11.07 74.3743 11.1 74.9987 11.1 74.9987 11.075 75.022 11.075 75.022 11.025 75.0803 11.245 75.9498 11.54 76.3582 11.84 76.7142 11.87 76.7375 11.925 76.7725 11.93 76.7725 12.0 76.8075 12.565 77.4669 12.915 77.9979 13.12 78.3363 13.345 78.523 13.355 78.523 13.745 78.8614 13.79 78.8673 13.98 79.054 14.05 79.194 14.175 79.2991 14.2 79.3983 14.325 79.9467 14.37 80.0109 14.555 80.2735 14.88 81.1488 14.57 82.024 14.58 82.1349 14.58 82.1407 15.035 82.4383 15.62 82.2574 16.07 82.8176 16.11 82.8993 16.625 83.086 16.84 83.2318 16.87 83.2727 16.87 83.2727 16.94 83.3194 17.085 83.6228 17.09 83.6753 17.1 83.7862 17.11 83.8854 17.125 84.0779 17.13 84.1246 17.15 84.3697 17.155 84.428 17.16 84.5097 17.125 84.6614 17.105 84.7373 17.08 84.8306 17.06 85.0115 17.15 85.6417 17.195 85.7292 17.46 86.0502 17.495 86.1668 17.6 86.4002 17.64 86.8204 17.625 86.9429 17.92 88.1507 18.12 88.565 18.43 88.6409 18.67 89.026 18.745 89.1252 18.815 89.1835 19.205 89.4636 19.47 89.6037 19.62 89.6562 19.74 90.2864 19.77 90.4264 19.845 90.7765 19.865 92.2002 19.91 92.527 19.96 92.7079 19.995 92.7487 19.995 92.7546 20.0 92.7721 20.0 92.7837 20.005 92.8888 20.165 93.6823 20.185 93.7699 20.34 94.2016 20.35 94.2133 20.43 94.2775 20.62 94.5692 20.655 94.5984 21.245 94.9952 21.375 95.1527 22.495 97.1308 22.81 97.4517 23.03 97.7785 23.12 98.1228 23.38 98.6538 23.745 98.823 24.06 99.0447 24.065 99.0505 24.25 99.424 } set us_regions(FL.14) {218.41 161.077 218.375 161.234 218.51 161.613 218.535 161.672 218.59 161.818 218.64 162.069 218.725 162.296 218.75 162.43 218.75 162.436 218.755 162.459 218.77 162.547 218.855 162.769 219.02 162.903 219.135 162.985 219.375 163.346 219.44 163.405 219.48 163.422 219.48 163.422 219.505 163.434 219.59 163.446 219.6 163.446 219.81 163.37 219.92 163.306 219.96 163.282 220.11 163.247 220.165 163.288 220.29 163.422 220.305 163.44 220.395 163.568 220.47 163.737 220.57 164.076 220.59 164.216 220.59 164.222 220.625 164.443 220.65 164.508 220.675 164.723 220.685 164.922 220.685 164.969 220.69 165.056 220.695 165.103 220.695 165.144 220.695 165.167 220.695 165.173 220.7 165.254 220.72 165.453 220.725 165.494 220.75 165.61 220.895 166.001 220.92 166.048 220.95 166.106 220.995 166.229 220.97 166.375 220.97 166.381 220.975 166.421 221.08 166.702 221.115 166.859 221.305 167.227 221.8 167.658 221.875 167.641 222.145 167.437 222.58 167.798 223.125 168.557 223.665 169.549 223.75 169.771 223.835 171.299 224.075 172.175 224.375 172.507 224.4 172.537 225.0 173.663 225.085 173.925 225.505 173.96 225.555 174.042 225.545 174.083 225.47 174.112 225.0 174.38 225.0 174.369 224.95 174.386 224.64 174.474 224.29 174.299 223.91 173.925 223.6 173.925 223.34 173.943 223.115 173.925 222.865 173.925 222.86 173.925 222.595 174.054 222.335 174.229 222.295 174.287 222.13 174.375 222.035 174.421 221.93 174.515 221.91 174.544 221.875 174.555 221.775 174.649 221.58 174.795 221.445 174.871 221.425 174.9 221.4 174.935 221.075 175.127 220.975 175.174 220.965 175.18 220.745 175.343 220.625 175.396 220.0 175.67 219.98 175.67 219.775 175.746 219.68 175.67 219.145 175.67 218.925 175.973 218.91 176.271 219.12 176.545 219.105 176.545 219.47 176.545 219.505 176.545 219.74 176.545 219.73 176.545 219.78 176.627 219.83 176.674 220.0 176.72 220.125 176.755 221.06 176.615 221.04 176.586 221.055 176.586 221.135 176.58 221.225 176.954 221.395 177.041 221.605 176.983 221.73 176.948 222.045 176.796 222.355 176.545 222.37 176.545 222.405 176.353 222.5 176.119 222.56 176.148 222.775 176.143 222.865 176.084 222.945 176.061 223.005 176.061 223.035 176.061 223.41 175.927 223.935 175.67 224.12 175.623 224.27 175.518 224.545 175.617 224.87 175.437 224.885 175.407 224.885 175.402 224.925 175.384 225.0 175.361 225.0 175.366 225.11 175.285 225.11 175.279 225.205 175.215 225.625 174.946 225.79 174.806 225.83 174.795 226.145 174.69 226.85 174.124 226.875 174.094 227.01 173.925 227.02 173.925 227.05 173.861 227.125 173.791 227.5 173.453 227.59 173.418 227.68 173.365 227.835 173.05 227.83 173.05 228.005 172.875 228.045 172.747 228.045 172.717 228.125 172.607 228.225 172.525 228.425 172.175 228.42 172.175 228.5 171.988 228.75 171.795 228.805 171.299 228.805 171.299 228.795 171.282 229.25 170.85 229.375 170.558 229.375 170.086 229.365 170.08 229.31 170.022 229.375 169.637 229.375 169.578 229.39 169.549 229.395 169.549 229.395 169.543 229.73 168.72 229.7 168.674 229.695 168.674 229.525 168.446 229.515 168.271 229.555 168.114 229.545 167.997 229.645 167.798 229.74 166.223 229.745 166.141 229.795 165.4 229.875 164.63 229.91 164.274 229.925 163.802 229.925 163.696 229.925 163.691 229.925 163.591 229.945 163.311 229.965 163.06 229.97 163.02 229.985 162.868 230.0 162.751 230.01 162.716 230.03 162.524 230.03 162.512 230.035 162.477 230.07 162.29 230.075 162.232 230.09 161.958 230.095 161.934 230.095 161.882 230.095 161.736 230.095 161.672 230.095 161.514 230.1 161.316 230.125 161.094 230.11 160.995 230.1 160.797 230.125 160.633 230.125 160.581 230.105 160.347 230.075 160.19 230.045 160.032 230.04 159.98 230.015 159.869 230.0 159.799 229.975 159.67 229.935 159.478 229.93 159.454 229.925 159.443 229.925 159.437 229.885 159.256 229.85 159.046 229.695 158.457 229.635 158.276 229.595 158.171 229.53 157.897 229.375 157.395 229.375 157.395 229.31 157.208 229.055 156.42 228.985 156.222 228.91 155.988 228.9 155.953 228.86 155.802 228.86 155.697 228.855 155.668 228.75 155.411 228.75 155.405 228.68 155.148 228.66 155.037 228.63 154.868 228.625 154.856 228.525 154.53 228.46 154.232 228.44 154.121 228.38 153.87 228.36 153.794 228.075 153.013 228.04 152.919 227.91 152.581 227.77 152.225 227.695 152.044 227.635 151.869 227.615 151.811 227.6 151.776 227.59 151.752 227.575 151.706 227.535 151.606 227.5 151.496 227.48 151.373 227.46 151.233 227.435 151.07 227.42 151.0 227.415 150.959 227.41 150.93 227.405 150.877 227.395 150.83 227.39 150.789 227.385 150.76 227.38 150.731 227.365 150.649 227.36 150.609 227.355 150.574 227.35 150.55 227.28 150.142 227.295 150.013 227.305 149.938 227.31 149.862 227.32 149.798 227.325 149.722 227.34 149.628 227.36 149.529 227.375 149.459 227.375 149.453 227.385 149.389 227.4 149.307 227.485 149.197 227.5 149.179 227.5 148.31 227.46 148.105 226.82 146.793 226.685 146.507 226.39 145.917 226.37 145.876 226.25 145.62 226.18 145.48 226.18 145.48 226.02 145.13 225.995 145.083 225.84 144.744 225.775 144.604 225.7 144.447 225.695 144.447 225.645 144.342 225.64 144.33 225.64 144.33 225.625 144.301 225.625 144.295 225.48 144.05 225.395 143.846 225.27 143.449 225.24 143.362 225.22 143.292 225.21 143.262 225.195 143.216 225.125 143.023 225.075 142.889 225.055 142.836 225.03 142.761 225.0 142.685 225.0 142.685 224.99 142.644 224.77 142.014 224.79 142.014 224.69 141.693 224.655 141.576 224.64 141.541 224.62 141.477 224.585 141.366 224.43 140.946 224.375 140.782 224.245 140.345 224.17 140.018 224.12 139.866 224.095 139.791 224.03 139.551 224.005 139.423 223.99 139.33 223.98 139.3 223.97 139.172 223.965 139.049 223.955 138.915 223.955 138.909 223.87 138.548 223.77 138.238 223.75 138.163 223.725 138.04 223.685 137.818 223.575 137.165 223.5 136.774 223.4 136.29 223.4 136.272 223.4 136.266 223.41 136.266 223.365 136.05 223.36 136.021 223.35 135.951 223.345 135.934 223.34 135.893 223.34 135.887 223.335 135.834 223.33 135.77 223.325 135.642 223.325 135.513 223.38 135.414 223.395 135.368 223.415 135.268 223.205 134.527 223.125 134.311 223.095 134.002 223.09 133.815 223.09 133.763 223.095 133.646 223.125 133.442 223.265 133.051 220.0 132.52 215.0 133.728 210.0 133.337 205.0 131.242 204.99 131.032 204.99 131.032 204.99 131.032 199.97 131.085 194.98 131.044 192.41 136.435 193.025 136.29 193.035 136.29 193.125 136.266 193.485 136.149 193.75 136.179 194.035 136.144 194.375 136.068 194.885 135.934 195.0 135.916 195.415 135.811 195.625 135.764 195.75 135.747 195.995 135.7 196.005 135.694 197.55 135.724 197.615 135.724 197.79 135.735 198.01 135.764 198.02 135.764 198.125 135.782 198.66 135.928 198.78 135.98 199.41 136.237 199.52 136.29 199.615 136.336 200.0 136.546 200.03 136.564 200.605 136.943 200.87 137.165 200.9 137.188 200.915 137.206 201.08 137.404 201.145 137.48 201.25 137.579 201.7 137.859 202.025 138.244 202.195 138.443 202.395 138.612 202.5 138.664 202.705 138.694 202.77 138.734 202.725 138.787 202.625 139.137 202.63 139.359 202.655 139.569 202.675 139.674 202.695 139.791 202.75 140.036 202.85 140.351 202.975 140.578 203.035 140.666 203.51 140.666 203.75 140.654 203.77 140.66 203.82 140.666 203.825 140.666 204.36 141.004 204.375 141.004 204.495 141.115 204.66 141.273 204.855 141.261 205.0 141.197 205.625 140.852 205.95 140.666 206.71 139.971 206.72 139.96 206.875 139.884 207.085 139.791 207.405 139.382 207.5 139.219 207.595 139.201 207.855 139.049 208.535 138.915 208.53 138.915 208.72 138.408 208.675 138.198 208.675 138.192 208.72 138.133 208.745 138.069 208.75 138.069 209.035 138.157 209.35 138.04 209.36 138.028 209.37 138.017 209.37 138.017 209.37 138.017 209.375 138.011 209.395 137.982 209.625 137.795 210.0 137.952 210.15 138.04 210.625 138.454 210.83 138.606 210.885 138.659 211.25 138.781 211.365 138.886 211.405 138.915 211.77 139.598 211.79 139.791 211.795 139.82 211.875 139.983 211.88 140.001 211.905 140.076 212.5 140.625 212.595 140.631 212.68 141.168 212.7 141.389 212.73 141.541 213.125 141.973 213.355 142.323 213.395 142.34 213.455 142.416 213.55 142.667 213.685 142.755 213.75 142.825 213.795 143.076 213.8 143.286 213.8 143.292 214.075 143.677 214.135 143.799 214.375 144.634 215.0 144.674 215.0 144.686 215.21 144.529 215.625 144.727 215.635 144.727 215.665 144.721 215.73 144.896 215.735 145.007 215.735 145.024 215.74 145.042 215.725 145.042 215.76 145.643 215.96 145.818 215.975 145.917 216.025 146.04 215.93 146.407 215.94 146.53 216.025 146.763 216.045 146.979 216.11 147.183 216.25 147.592 216.295 147.668 216.3 147.668 216.36 147.878 216.305 148.0 216.255 148.304 216.26 148.543 216.26 148.543 216.28 148.596 216.25 148.934 216.23 149.01 216.07 149.342 216.045 149.418 216.005 149.523 216.0 149.547 215.995 149.657 215.95 150.048 215.905 150.183 215.625 150.241 215.46 150.55 215.475 150.842 215.475 151.046 215.485 151.175 215.495 151.21 215.52 151.472 215.555 151.676 215.57 151.921 215.575 152.12 215.575 152.155 215.565 152.202 215.56 152.283 215.5 152.482 215.475 152.663 215.465 152.744 215.46 152.937 215.47 153.042 215.55 153.322 215.605 153.439 215.605 153.444 215.61 153.45 215.615 153.468 215.62 153.479 215.625 153.485 215.77 153.73 215.925 153.999 215.965 154.069 215.975 154.104 215.94 154.308 215.935 154.524 215.885 155.049 215.99 155.405 216.08 155.545 216.14 155.644 216.145 155.65 216.155 155.673 216.155 155.673 216.185 155.743 216.2 155.778 216.25 155.948 216.25 155.948 216.255 155.965 216.475 156.315 216.565 156.543 216.61 156.636 216.61 156.636 216.875 157.126 216.875 157.132 216.88 157.185 217.17 157.599 217.22 157.786 217.35 158.171 217.38 158.357 217.445 158.515 217.47 158.62 217.5 158.743 217.5 158.737 217.54 158.824 217.545 158.824 217.545 158.824 217.655 159.046 217.815 159.425 217.815 159.425 217.84 159.484 217.995 159.84 218.025 159.921 218.125 160.085 218.325 160.528 218.4 160.785 218.41 161.077 } set us_regions(MT.33) {60.2 5.00784 60.025 5.00784 59.995 5.00784 59.75 5.00784 59.71 5.00784 59.66 5.00784 59.485 5.00784 59.36 5.00784 58.895 5.002 58.885 5.002 58.875 5.002 58.87 5.002 58.635 4.99617 58.45 4.99617 58.45 4.99617 58.45 4.99617 58.18 4.99033 57.965 4.99617 57.96 4.99617 57.88 4.99617 57.805 4.99617 57.705 4.99617 57.62 4.99617 57.61 4.99617 57.51 4.99617 57.395 4.99617 57.31 4.99617 57.29 4.99617 57.255 4.99617 57.205 4.99617 57.16 4.99617 56.935 4.99617 56.84 4.99617 56.84 4.99617 56.68 4.99617 56.645 4.99617 56.63 4.99617 56.61 4.99617 56.365 4.99617 56.36 4.99617 56.19 4.99617 56.175 4.99617 56.14 4.99617 56.125 4.99617 56.105 4.99617 56.05 4.99617 56.025 4.99617 55.995 4.99617 55.885 4.99617 55.69 4.99617 55.55 5.002 55.515 5.002 55.51 5.002 55.295 5.002 55.265 5.002 55.285 5.002 55.12 5.002 54.97 5.00784 54.965 5.00784 54.72 5.00784 54.69 5.00784 54.58 5.00784 54.545 5.00784 54.175 5.00784 54.145 5.00784 54.12 5.00784 54.085 5.00784 54.04 5.00784 53.96 5.00784 53.745 5.00784 53.68 5.00784 53.665 5.002 53.625 5.002 53.575 5.002 53.17 5.002 53.12 5.002 53.04 5.002 52.95 5.002 52.94 5.002 52.915 5.002 52.8 4.99617 52.675 4.99617 52.525 4.99617 52.27 4.99617 52.245 4.99617 51.99 4.99617 51.98 4.99617 51.97 4.99617 51.9 4.99617 51.79 4.99617 51.785 4.99617 51.765 4.99617 51.69 4.99617 51.625 4.99617 51.465 4.99617 51.45 4.99617 51.205 4.99617 51.095 4.99617 50.95 4.99617 50.92 4.99617 50.32 4.99617 50.315 4.99617 50.315 4.99617 50.27 4.99617 50.15 4.99617 50.12 4.99617 50.045 4.99617 49.93 4.99617 49.93 4.99617 49.755 4.99617 49.755 5.002 50.0 12.43 55.0 19.2336 60.0 28.1319 65.015 36.8786 70.025 36.2601 74.755 36.6919 74.995 32.9983 79.995 32.9867 84.995 33.01 89.995 33.0042 94.995 33.0333 99.995 33.0567 104.995 33.01 109.7 33.0275 109.71 33.0275 109.775 26.3931 109.755 5.002 109.61 5.002 109.375 5.002 109.37 5.002 109.175 5.002 109.06 5.002 108.94 5.002 108.93 5.002 108.595 5.002 108.585 5.002 108.54 5.002 108.525 5.00784 108.475 5.00784 108.46 5.00784 108.4 5.002 108.115 5.00784 108.01 5.00784 107.895 5.00784 107.745 5.00784 107.64 5.00784 107.515 5.00784 107.395 5.00784 107.37 5.00784 107.28 5.00784 107.28 5.00784 107.23 5.00784 107.14 5.00784 107.125 5.00784 106.94 5.00784 106.87 5.00784 106.765 5.00784 106.695 5.00784 106.58 5.00784 106.465 5.00784 106.36 5.00784 106.25 5.00784 106.14 5.00784 106.03 5.00784 105.685 5.00784 105.47 5.00784 105.395 5.00784 105.37 5.00784 105.26 5.00784 105.22 5.00784 104.955 5.00784 104.835 5.00784 104.71 5.00784 104.445 5.00784 104.44 5.00784 104.37 5.00784 104.3 5.00784 104.28 5.00784 104.19 5.00784 104.105 5.00784 104.03 5.00784 103.795 5.00784 103.755 5.00784 103.725 5.00784 103.675 5.00784 103.655 5.00784 103.61 5.00784 103.48 5.00784 103.475 5.00784 103.285 5.00784 103.22 5.00784 103.17 5.00784 103.16 5.00784 103.15 5.00784 103.065 5.00784 103.065 5.00784 103.045 5.00784 103.035 5.00784 103.035 5.00784 102.99 5.00784 102.97 5.00784 102.96 5.00784 102.95 5.00784 102.94 5.00784 102.895 5.00784 102.88 5.00784 102.855 5.00784 102.85 5.00784 102.845 5.00784 102.745 5.00784 102.735 5.002 102.695 5.002 102.67 5.002 102.615 5.00784 102.54 5.00784 102.515 5.002 102.385 5.002 102.24 5.00784 102.105 5.002 102.105 5.002 102.0 5.002 101.96 5.002 101.935 5.002 101.865 5.002 101.86 5.002 101.75 5.002 101.75 5.00784 101.48 5.002 101.415 5.002 101.215 5.002 101.16 5.002 101.12 5.002 101.12 5.002 101.11 5.002 100.83 5.002 100.27 5.002 100.205 5.002 100.17 5.00784 100.17 5.00784 100.025 5.00784 99.995 5.00784 99.99 5.00784 99.745 5.00784 99.44 5.00784 99.225 5.00784 99.2 5.00784 98.925 5.00784 98.88 5.00784 98.83 5.00784 98.825 5.00784 98.785 5.00784 98.77 5.00784 98.695 5.00784 98.69 5.00784 98.63 5.00784 98.63 5.00784 98.575 5.00784 98.395 5.00784 98.185 5.002 98.165 5.00784 98.16 5.00784 98.16 5.00784 98.125 5.002 98.11 5.002 97.975 5.002 97.91 5.002 97.895 5.00784 97.895 5.00784 97.855 5.00784 97.825 5.00784 97.825 5.00784 97.8 5.002 97.795 5.002 97.795 5.002 97.79 5.00784 97.78 5.00784 97.78 5.00784 97.78 5.00784 97.745 5.00784 97.665 5.00784 97.63 5.00784 97.625 5.00784 97.6 5.00784 97.54 5.00784 97.54 5.00784 97.51 5.00784 97.495 5.00784 97.495 5.002 97.49 5.002 97.41 5.00784 97.305 5.00784 97.21 5.00784 96.91 5.002 96.91 5.00784 96.91 5.00784 96.895 5.002 96.89 5.002 96.87 5.002 96.87 5.002 96.84 5.002 96.785 5.002 96.745 5.002 96.73 5.002 96.61 5.002 96.525 5.002 96.45 5.002 96.405 5.002 96.305 5.002 96.29 5.002 96.28 5.002 96.27 5.002 96.105 5.002 96.105 5.002 96.06 5.002 95.87 5.002 95.84 5.002 95.82 5.002 95.805 5.002 95.79 5.002 95.76 5.002 95.74 5.002 95.645 5.002 95.625 5.002 95.62 5.002 95.58 5.002 95.44 5.002 95.375 5.002 95.305 5.002 95.305 5.002 95.185 5.002 95.085 5.002 95.035 5.002 95.015 5.002 94.995 5.002 94.555 5.002 94.55 5.002 94.48 5.002 94.47 5.002 94.37 5.002 94.355 5.002 94.2 5.002 94.17 5.002 94.145 5.002 94.1 5.002 94.035 5.002 93.965 5.002 93.895 5.002 93.745 5.002 93.715 5.002 93.55 5.002 93.485 5.002 93.425 5.002 93.31 5.002 93.18 5.002 93.13 5.002 92.945 5.00784 92.9 5.00784 92.895 5.00784 92.845 5.00784 92.795 5.00784 92.78 5.00784 92.77 5.00784 92.61 5.00784 92.5 5.00784 92.45 5.00784 92.4 5.00784 92.29 5.00784 92.24 5.00784 92.215 5.002 92.18 5.00784 92.16 5.00784 92.075 5.00784 92.07 5.00784 92.065 5.00784 92.025 5.002 91.955 5.002 91.95 5.00784 91.835 5.002 91.66 5.002 91.635 5.002 91.6 5.002 91.475 5.002 91.36 5.002 91.285 5.002 91.275 5.002 91.175 5.002 91.155 5.002 91.115 5.002 91.1 5.002 91.085 5.002 91.02 5.002 91.01 5.002 90.95 5.002 90.84 5.002 90.645 5.002 90.585 5.002 90.555 5.002 90.165 5.002 90.135 5.002 90.13 5.002 89.93 5.002 89.765 5.00784 89.58 5.00784 89.505 5.00784 88.82 5.002 88.17 5.00784 88.06 5.00784 87.56 5.00784 87.44 5.00784 87.285 5.00784 86.65 5.00784 86.29 5.00784 86.195 5.00784 86.115 5.00784 85.885 5.00784 85.8 5.00784 85.73 5.00784 85.625 5.00784 85.04 5.00784 85.025 5.00784 85.015 5.00784 84.995 5.00784 84.995 5.00784 84.875 5.00784 84.86 5.00784 84.75 5.002 84.715 5.002 84.7 5.002 84.695 5.002 84.64 5.00784 84.585 5.002 84.53 5.002 84.45 5.002 84.44 5.002 84.425 5.002 84.31 5.002 84.2 5.002 84.14 5.002 84.09 5.002 83.98 5.002 83.945 5.002 83.835 5.002 83.765 5.002 83.76 5.002 83.745 5.002 83.57 4.99617 83.455 4.99617 83.325 4.99617 83.12 4.99617 83.08 5.002 83.08 4.99617 83.075 5.002 82.915 4.99617 82.84 4.99617 82.815 4.99617 82.73 4.99617 82.7 4.99617 82.685 4.99617 82.55 4.99617 82.52 4.99617 82.495 4.99617 82.44 4.99617 82.44 4.99617 82.43 4.99617 82.405 4.99617 82.29 5.002 82.275 5.002 82.225 5.002 82.03 5.002 82.0 5.002 81.87 5.002 81.72 5.002 81.635 5.002 81.63 5.002 81.63 5.002 81.625 5.002 81.475 5.002 81.46 5.002 81.445 5.002 81.34 5.002 80.865 5.002 80.62 5.002 80.42 5.002 80.355 5.002 80.135 5.002 80.125 5.002 80.02 5.002 79.995 5.002 79.89 5.002 79.635 5.00784 79.625 5.00784 79.61 5.00784 79.47 5.00784 79.37 5.00784 79.25 5.00784 79.14 5.00784 79.045 5.00784 79.04 5.00784 78.96 5.00784 78.92 5.00784 78.92 5.00784 78.645 5.00784 78.595 5.00784 78.49 5.00784 77.795 5.00784 77.78 5.00784 77.775 5.00784 77.66 5.00784 77.35 5.01367 77.345 5.01367 77.34 5.01367 77.34 5.01367 77.335 5.01367 77.33 5.01367 77.3 5.01367 77.295 5.01367 77.29 5.01367 77.07 5.00784 77.065 5.00784 77.045 5.00784 77.04 5.00784 76.945 5.00784 76.86 5.00784 76.83 5.01367 76.825 5.01367 76.82 5.01367 76.815 5.01367 76.62 5.01367 76.445 5.01367 76.285 5.01367 76.115 5.01367 76.03 5.01367 75.655 5.01367 75.625 5.01367 75.565 5.01367 75.565 5.01367 75.12 5.0195 75.075 5.0195 75.05 5.0195 74.98 5.0195 74.815 5.0195 74.8 5.0195 74.665 5.0195 74.655 5.0195 74.325 5.0195 74.16 5.0195 74.14 5.0195 73.965 5.0195 73.845 5.0195 73.84 5.0195 73.83 5.0195 73.795 5.0195 73.71 5.0195 73.645 5.0195 73.55 5.0195 73.515 5.0195 73.48 5.0195 73.4 5.0195 73.125 5.0195 73.055 5.0195 73.005 5.0195 72.91 5.02534 72.64 5.02534 72.565 5.02534 72.445 5.02534 72.155 5.02534 72.065 5.0195 71.675 5.0195 71.67 5.0195 71.245 5.0195 71.19 5.0195 71.19 5.0195 71.105 5.0195 71.065 5.0195 70.955 5.01367 70.955 5.01367 70.84 5.01367 70.73 5.01367 70.73 5.01367 70.62 5.01367 70.62 5.01367 70.4 5.01367 70.285 5.01367 70.21 5.01367 70.205 5.01367 70.2 5.01367 70.185 5.01367 70.175 5.01367 70.065 5.00784 69.995 5.00784 69.98 5.01367 69.56 5.01367 69.41 5.00784 69.325 5.00784 69.28 5.00784 69.27 5.00784 69.205 5.00784 69.03 5.00784 68.5 5.00784 68.49 5.00784 68.36 5.00784 68.245 5.00784 68.175 5.00784 68.12 5.00784 68.015 5.00784 67.795 5.00784 67.74 5.00784 67.495 5.00784 67.38 5.00784 67.225 5.00784 67.22 5.00784 66.985 5.00784 66.505 5.01367 66.295 5.01367 66.205 5.01367 66.06 5.01367 65.84 5.01367 65.685 5.01367 65.475 5.01367 65.095 5.01367 65.04 5.01367 65.02 5.00784 65.0 5.00784 64.95 5.01367 64.945 5.01367 64.945 5.01367 64.94 5.01367 64.905 5.01367 64.875 5.01367 64.765 5.01367 64.735 5.01367 64.595 5.01367 64.57 5.01367 64.56 5.01367 64.54 5.01367 64.525 5.01367 64.51 5.01367 64.485 5.01367 64.465 5.01367 64.45 5.01367 64.44 5.01367 64.42 5.01367 64.38 5.01367 64.37 5.01367 64.37 5.01367 64.37 5.01367 64.34 5.01367 64.29 5.01367 64.285 5.01367 64.23 5.01367 64.175 5.01367 63.795 5.00784 63.795 5.00784 63.72 5.01367 63.64 5.01367 63.445 5.01367 63.36 5.01367 63.28 5.01367 63.215 5.01367 63.105 5.01367 63.0 5.01367 62.965 5.01367 62.695 5.01367 62.665 5.01367 62.665 5.01367 62.65 5.01367 62.465 5.01367 62.415 5.01367 62.355 5.01367 62.285 5.01367 62.25 5.01367 62.145 5.01367 62.135 5.01367 62.07 5.01367 62.025 5.01367 62.0 5.01367 61.955 5.01367 61.805 5.01367 61.695 5.0195 61.585 5.0195 61.565 5.0195 61.225 5.0195 61.01 5.01367 60.68 5.01367 60.57 5.01367 60.56 5.01367 60.535 5.01367 60.475 5.00784 60.435 5.00784 60.43 5.00784 60.315 5.00784 60.29 5.00784 60.255 5.00784 60.2 5.00784 } set us_regions(CA.4) {14.995 84.533 14.995 84.5447 15.035 84.5389 15.31 84.0546 14.995 83.6228 14.37 83.2727 14.23 83.3777 14.13 83.5936 14.37 84.0079 14.995 84.533 } set us_regions(FL.15) {215.17 175.956 215.21 175.979 215.595 176.014 215.625 176.026 215.89 175.915 215.89 175.915 215.89 175.915 216.01 175.822 216.0 175.81 215.97 175.752 215.585 174.999 215.49 175.04 215.385 175.186 215.335 175.256 215.065 175.67 215.065 175.676 215.085 175.833 215.17 175.956 215.17 175.956 } set us_regions(CA.5) {33.52 110.032 32.66 109.589 30.655 109.157 30.26 109.157 30.04 109.577 28.735 109.624 28.3 109.157 28.505 110.254 28.745 110.674 29.0 110.907 29.92 110.907 29.995 110.837 30.475 110.458 32.54 110.149 33.52 110.032 } set us_regions(MO.32) {153.46 68.02 153.46 68.0258 155.01 68.726 155.0 70.284 155.02 71.8828 156.91 89.0377 156.91 92.5328 156.91 92.5328 160.005 92.5328 165.01 92.5445 170.015 92.5387 175.015 92.5387 180.02 96.0338 181.335 96.0222 182.305 92.5387 182.575 92.5445 182.915 92.5328 184.335 89.1485 180.015 82.2807 175.0 72.0345 172.89 65.3884 172.905 65.3709 170.005 63.7896 165.07 63.9122 160.065 63.9997 155.04 63.988 151.18 63.9238 151.17 63.9238 153.46 68.02 } set us_regions(NC.44) {251.01 92.1711 250.015 92.1711 245.0 92.2177 240.0 92.2177 235.0 92.2294 230.0 92.2294 225.0 92.0835 221.655 91.9085 221.61 91.9085 221.61 91.9085 219.985 94.8727 214.995 97.6151 210.0 100.054 208.39 103.112 209.975 103.118 214.395 103.024 214.455 103.024 214.985 102.826 219.995 101.711 225.0 102.546 229.995 104.372 235.0 108.357 237.5 111.339 237.505 111.345 238.125 111.088 238.16 111.076 238.835 110.995 239.935 111.403 240.0 111.66 240.285 111.753 240.51 111.537 240.515 111.526 240.515 111.292 240.53 110.907 240.795 110.032 240.79 110.032 240.93 109.583 241.075 109.157 241.07 109.157 241.23 108.941 241.25 108.9 241.25 108.906 241.6 108.281 241.625 108.258 242.37 107.406 242.5 107.29 242.575 107.231 243.125 106.834 243.475 106.642 243.585 106.554 243.61 106.531 244.22 106.035 244.375 105.948 244.415 105.942 245.0 105.714 245.245 105.656 245.245 105.656 245.31 105.638 245.31 105.638 245.385 105.627 246.535 105.527 246.795 105.656 246.875 105.685 247.5 106.233 247.725 105.726 247.755 105.656 247.815 105.533 248.125 105.02 248.145 104.991 248.175 104.944 248.29 104.781 248.385 104.646 248.44 104.576 248.6 104.372 248.75 104.185 248.815 104.127 249.02 103.905 249.375 103.497 249.835 103.03 249.965 102.989 250.0 102.983 250.04 102.954 250.075 102.931 251.1 102.155 251.315 102.044 251.365 102.038 251.875 101.799 252.5 101.787 252.68 101.408 252.7 101.309 252.705 101.303 252.705 101.279 252.885 99.9666 252.915 99.6865 252.925 99.529 253.0 98.8755 252.975 98.6538 252.81 97.8018 252.8 97.7785 252.64 97.3817 252.5 97.0608 252.44 96.9032 252.17 96.1972 252.09 96.028 252.09 96.028 252.045 95.9113 251.875 95.4912 251.455 94.3125 251.445 94.2775 251.275 93.6298 251.25 93.554 251.15 93.0463 251.045 92.527 251.045 92.527 251.01 92.1711 } set us_regions(ME.26) {279.085 43.513 279.38 43.2504 280.555 42.5794 281.065 42.4043 281.66 42.0484 283.83 41.5933 284.72 40.9981 284.95 41.4241 285.005 41.4708 285.005 41.4708 286.285 40.4088 286.395 40.2804 287.59 39.8136 288.01 39.6619 289.145 38.6816 289.36 38.1623 289.395 38.1506 289.44 38.139 290.005 38.0514 290.17 37.8706 290.23 37.7597 290.565 37.7772 290.685 37.7947 290.88 37.7247 291.025 37.3863 291.03 37.2112 291.125 37.1353 291.25 37.252 291.255 37.252 291.285 37.2695 291.725 37.3046 291.865 37.3279 292.365 37.1003 292.505 37.0186 293.015 36.4001 293.285 36.3651 294.41 35.6358 294.55 35.4607 294.94 34.9939 295.005 34.9589 295.575 34.4512 295.335 34.2353 295.12 34.037 295.11 34.0136 295.1 33.9961 295.095 33.9728 295.095 33.9086 295.12 33.8036 295.13 33.7744 295.145 33.6985 295.04 33.5352 295.015 33.5118 294.99 33.471 294.905 33.3426 294.85 33.2376 294.835 33.2084 294.585 32.6191 294.545 32.5315 294.385 32.1348 294.38 32.1231 294.13 31.8547 293.755 31.738 293.695 31.6971 293.68 31.6913 293.65 31.6738 293.545 31.7263 293.545 31.738 293.515 31.8197 293.475 31.9947 293.29 32.1289 293.13 31.9889 293.04 31.9305 292.975 31.8722 292.995 31.7671 292.665 31.2595 292.615 31.0786 292.565 31.0436 292.63 30.9678 292.87 29.4857 292.87 29.2231 292.88 29.1822 292.86 29.0597 292.86 29.0247 292.875 28.9547 292.775 28.8321 292.405 28.8905 291.88 28.6921 291.73 28.6746 291.685 28.6338 291.675 28.6338 291.665 28.6338 291.38 28.2136 291.35 28.1845 291.37 28.2953 291.37 28.3653 291.36 28.3653 291.335 28.3595 291.225 28.3303 290.97 28.2428 291.035 27.7585 290.975 27.5951 291.1 27.2975 291.1 27.2917 291.1 27.28 291.18 27.2684 291.18 27.1983 291.05 27.0466 291.02 26.9533 290.985 26.9299 290.98 26.8599 291.005 26.8132 291.11 26.7257 291.155 26.6965 291.095 26.4048 291.095 26.3639 291.095 26.2998 291.095 26.2647 291.095 26.2472 291.095 26.113 291.095 26.0022 291.095 25.8563 291.095 25.4945 291.095 25.4012 291.095 25.3895 291.095 25.337 291.095 25.337 291.095 25.3311 291.095 25.2728 291.095 25.1561 291.095 25.0802 291.095 25.0744 291.095 25.0627 291.095 25.0627 291.095 24.9927 291.095 24.7943 291.095 24.7827 291.095 24.7068 291.095 24.6718 291.09 24.4851 291.09 24.4209 291.09 24.415 291.09 24.38 291.09 24.3392 291.09 24.1408 291.09 24.1058 291.09 24.0766 291.09 24.0533 291.09 23.9366 291.085 23.7849 291.085 23.7674 291.085 23.7265 291.085 23.5515 291.085 23.5048 291.085 23.3939 291.08 23.3181 291.08 23.2831 291.075 22.8629 291.075 22.8571 291.075 22.7404 291.07 22.4837 291.07 22.4311 291.065 22.1627 291.06 22.0344 291.06 22.0227 291.06 21.8243 291.06 21.8068 291.06 21.801 291.06 21.7951 291.06 21.7893 291.055 21.6026 291.055 21.5559 291.055 21.4392 291.055 21.3108 291.055 21.1825 291.055 21.0891 291.055 20.9199 291.055 20.7623 291.055 20.6982 291.055 20.6865 291.055 20.6456 291.05 20.4472 291.05 20.4472 291.05 20.4472 291.05 20.4414 291.05 20.4414 291.05 20.4356 291.05 20.4122 291.05 20.2664 291.05 20.2313 291.05 20.1263 291.05 20.033 291.05 19.9921 291.055 19.8988 291.055 19.8696 291.055 19.8579 291.055 19.8404 291.055 19.7587 291.05 19.6537 291.05 19.5487 291.05 19.537 291.05 19.3619 291.05 19.2919 291.05 19.2219 291.055 19.1577 291.055 19.1052 291.05 18.8951 291.055 18.8076 291.05 18.7843 291.05 18.7376 291.05 18.7143 291.05 18.6501 291.05 18.6034 291.055 18.58 291.05 18.5392 290.36 17.909 290.35 17.8857 290.345 17.8798 290.305 17.8098 290.29 17.7807 290.23 17.6173 290.005 17.4772 290.005 17.4714 289.69 17.2088 289.095 16.6895 288.8 16.5261 288.525 16.497 288.355 16.4853 288.315 16.4853 288.235 16.5028 287.69 16.9813 287.505 16.9404 287.035 17.0863 286.975 17.2613 286.945 17.2847 286.88 17.308 286.51 17.3197 285.865 17.5531 285.59 17.7223 285.495 17.7573 285.105 17.4772 285.005 17.4072 284.85 17.3197 284.835 17.3197 284.78 17.2555 284.735 16.9462 284.77 16.3161 284.78 16.3219 284.805 16.3102 284.79 16.2227 284.795 16.2169 284.745 16.0126 284.515 16.0126 284.285 15.8843 283.94 15.8201 283.88 15.7851 283.815 15.8726 283.63 16.1235 283.6 16.1644 283.41 16.4211 283.27 16.6195 283.16 16.7712 283.09 16.8646 282.945 17.0571 282.72 17.3722 282.635 17.4831 282.455 17.7398 282.385 17.8332 282.355 17.874 282.27 17.9907 282.19 18.1016 282.09 18.2416 281.99 18.3817 281.855 18.5684 281.615 18.901 281.59 18.936 281.46 19.111 281.365 19.2511 281.25 19.4028 281.25 19.4028 281.145 19.5545 281.095 19.6245 281.05 19.6829 281.03 19.712 280.785 20.0563 280.68 20.2022 280.57 20.3597 280.165 20.9257 280.02 21.1299 280.015 21.1533 280.01 21.165 279.91 21.8185 279.9 21.8593 279.9 21.871 279.885 21.9877 279.865 22.1044 279.785 22.647 279.775 22.7171 279.725 23.0322 279.72 23.0555 279.72 23.0905 279.72 23.0905 279.62 23.143 279.335 23.4231 279.12 23.5048 278.74 24.2458 278.62 24.5551 278.81 24.9752 278.74 25.267 278.715 25.3078 278.55 25.3545 278.44 26.2064 278.8 26.4106 278.385 27.0233 278.015 27.3676 278.02 27.3909 277.905 28.0152 277.235 28.3362 277.16 28.4412 277.01 28.6046 276.775 28.7621 276.56 29.0597 276.45 29.3456 276.42 29.6024 275.96 30.3609 275.83 31.0669 275.635 31.3762 275.605 31.3762 275.42 31.0845 275.33 30.7752 275.0 30.6177 274.735 30.8277 274.735 30.8277 274.72 30.8219 274.58 30.8744 274.59 30.9911 275.0 39.5802 277.125 47.5917 277.255 46.1388 277.465 45.8703 277.44 45.8878 278.9 43.7289 279.085 43.513 } set us_regions(CA.6) {37.76 113.533 36.87 114.128 36.87 114.134 37.255 114.408 37.25 114.408 37.495 115.044 38.12 115.213 38.28 115.284 38.295 115.284 38.455 115.284 38.45 115.284 38.745 115.062 38.745 115.068 38.745 114.572 37.76 113.533 } set us_regions(CA.7) {37.815 118.785 37.9 118.785 38.35 117.909 38.355 117.909 38.12 117.676 37.595 117.034 37.6 117.034 37.495 116.818 36.87 116.433 36.65 117.034 36.775 117.034 36.87 117.402 36.98 117.699 37.815 118.785 } set us_regions(CA.8) {33.12 115.178 32.885 114.963 32.855 114.933 32.85 114.928 31.87 114.898 31.87 115.394 32.495 115.861 33.12 115.686 33.12 115.19 33.12 115.178 } set us_regions(AL.0) {204.99 131.032 204.99 131.026 205.0 130.98 205.0 130.933 205.0 122.752 205.0 121.784 205.0 121.591 204.995 120.477 201.975 103.135 201.945 103.135 199.965 103.106 195.0 103.065 190.0 102.989 189.0 103.059 188.08 136.931 189.19 136.64 189.695 137.031 189.815 137.013 190.0 136.82 190.0 136.82 190.095 136.803 190.095 136.803 190.945 136.797 191.015 136.785 191.28 136.727 191.53 136.675 191.7 136.651 191.875 136.599 192.41 136.435 194.98 131.044 199.97 131.085 204.99 131.032 204.99 131.032 } set us_regions(CA.9) {34.995 113.282 34.995 113.282 35.01 113.294 34.995 114.105 34.995 113.282 } set us_regions(WA.59) {35.685 5.002 35.62 4.99617 35.545 5.002 35.485 5.002 35.225 5.002 34.995 5.002 34.97 5.002 34.905 5.002 34.895 5.002 34.535 5.002 34.34 5.002 34.315 5.002 34.1 5.002 34.095 5.002 34.075 5.002 33.845 5.002 33.74 5.002 33.66 5.002 33.575 5.002 33.565 5.002 33.56 5.002 33.485 5.002 33.02 5.002 32.865 5.002 32.855 5.002 32.815 5.002 32.785 5.002 32.71 5.002 32.69 5.002 32.655 5.002 32.635 5.002 32.495 5.002 32.455 5.002 32.445 5.002 32.415 5.002 32.355 5.002 32.34 5.002 32.335 5.002 32.32 5.002 32.31 5.002 32.295 5.002 32.265 5.002 32.24 5.002 32.12 5.002 32.025 5.002 31.89 5.002 31.695 5.002 31.685 5.002 31.67 5.002 31.665 5.002 31.64 5.002 31.495 5.002 31.49 5.002 31.49 5.002 31.395 5.002 31.375 5.002 31.37 4.99617 31.365 4.99617 31.13 5.002 30.995 5.002 30.62 4.99617 30.615 4.99617 30.575 5.002 30.405 5.002 30.325 5.002 30.185 5.002 29.845 5.00784 29.815 5.00784 29.775 5.00784 29.65 5.00784 29.625 5.00784 29.5 5.002 29.42 5.002 29.295 5.002 29.27 5.002 29.22 5.002 28.8 5.002 28.745 5.002 28.475 4.99617 28.365 4.99617 28.205 4.99617 28.12 4.99617 27.87 4.99617 27.685 4.99617 27.575 4.99617 27.425 4.99617 27.225 4.99617 27.22 4.99617 26.92 4.99617 26.84 4.99617 26.595 5.002 26.415 5.002 26.0 5.002 25.985 5.002 25.745 5.002 25.58 5.002 25.25 5.002 25.105 5.002 24.9 4.99617 24.72 4.99617 24.685 4.99617 24.665 4.99617 24.55 4.99617 24.4 4.99617 23.965 4.99617 23.85 4.99617 23.84 4.99617 23.76 4.99617 23.755 4.99617 23.49 4.99617 23.465 4.99617 23.315 4.99617 23.245 4.99617 23.02 5.002 22.945 5.002 22.88 5.002 22.77 5.002 22.71 5.002 22.38 5.00784 22.38 5.00784 22.37 5.00784 21.935 5.01367 21.725 5.01367 21.715 5.01367 21.55 5.0195 21.385 5.0195 21.155 5.0195 21.03 5.01367 20.855 5.01367 20.58 5.00784 20.435 5.002 20.415 5.002 20.33 5.002 20.33 5.002 20.295 5.002 20.265 5.002 20.25 5.002 19.985 4.99617 19.955 4.99617 19.755 4.99033 19.32 4.9845 19.315 4.9845 19.195 4.9845 19.18 4.9845 19.08 4.9845 19.025 4.9845 18.835 4.9845 18.74 4.9845 18.685 4.9845 18.685 4.9845 18.675 4.9845 18.67 4.9845 18.665 4.9845 18.665 4.9845 18.665 4.9845 18.64 4.9845 18.54 4.9845 18.305 4.9845 18.275 4.9845 18.275 4.9845 18.185 4.9845 18.12 4.9845 17.97 4.9845 17.965 4.9845 17.96 4.9845 17.805 4.9845 17.805 4.9845 17.74 4.9845 17.685 4.9845 17.63 4.9845 17.575 4.9845 17.385 4.9845 17.245 4.9845 16.97 4.9845 16.585 4.9845 16.475 4.9845 16.385 4.9845 16.38 4.9845 16.325 4.99033 16.325 4.99033 16.32 4.99033 16.32 4.99033 16.31 4.99033 16.28 4.9845 16.255 4.9845 16.23 4.9845 16.22 4.9845 16.215 4.9845 16.21 4.9845 16.21 4.9845 16.165 4.9845 16.16 4.9845 16.105 4.9845 15.88 4.9845 15.765 4.9845 15.665 4.9845 15.62 4.9845 15.39 4.9845 14.995 4.99033 14.975 4.99033 14.935 4.99033 14.825 4.9845 14.605 4.99033 14.545 4.99033 14.37 4.99033 14.37 4.99033 13.405 5.002 14.37 5.73721 14.56 5.87725 14.71 5.99395 14.875 6.12232 14.96 6.18067 14.635 6.7525 14.37 6.86337 14.37 6.86337 13.745 7.10843 13.715 7.12594 13.695 7.12594 13.745 7.51105 13.76 7.58691 13.765 7.59858 13.885 8.08288 14.055 8.503 14.055 8.503 14.06 8.50884 14.2 8.82976 14.37 8.99314 14.38 9.00481 14.42 9.03982 14.42 9.04566 14.37 9.12151 14.19 9.37825 14.19 9.37825 13.755 10.0143 13.515 10.0785 13.255 10.1543 13.095 10.1952 13.07 10.2068 12.995 10.2302 12.915 10.2535 12.905 10.2535 12.395 10.3994 12.205 10.4169 11.32 10.2535 11.32 10.2535 11.11 10.2068 10.315 10.0143 10.26 10.0026 9.37 9.69334 9.37 9.69917 8.665 9.42493 8.545 9.37825 8.545 9.37825 8.195 9.24404 7.495 8.98147 7.495 8.97563 7.28 8.89395 7.24 8.88228 6.83 8.72473 6.36 8.54384 6.26 8.50884 6.25 8.503 6.25 8.503 6.245 8.503 6.185 8.503 6.185 8.503 6.245 8.86477 6.27 8.88228 6.27 8.88228 6.245 8.89395 6.08 10.0785 6.045 10.2535 5.905 11.1288 6.03 11.3271 6.085 12.3133 6.245 12.6517 6.245 12.6517 6.265 12.6809 6.285 12.7042 6.395 12.7859 6.425 12.8442 6.45 12.8793 6.44 12.8793 6.47 12.9726 6.87 13.3811 6.87 13.3752 7.145 13.7545 7.275 13.8887 7.31 13.9529 7.19 14.198 7.415 14.6298 7.41 14.6298 7.495 14.6531 7.805 14.974 7.815 15.0557 7.85 15.2716 7.85 15.2716 7.89 15.505 7.89 15.505 7.98 16.5611 8.075 16.7303 8.12 16.7654 8.22 17.0046 8.455 17.2555 8.455 17.2555 8.475 17.2905 8.565 17.664 8.635 17.979 8.745 18.3291 8.745 18.3291 8.745 18.3525 8.78 18.8835 8.79 19.006 8.79 19.006 8.78 19.1227 8.795 19.6887 8.955 19.8813 9.095 20.4531 9.12 20.6165 9.205 21.0132 9.235 21.1241 9.33 22.1686 9.33 22.4136 9.33 22.507 9.335 22.5187 9.34 22.5478 9.34 22.5712 9.34 22.7462 9.34 23.038 9.35 23.2364 9.34 23.4289 9.33 23.4756 9.315 23.5456 9.3 23.639 9.285 23.6973 9.2 24.1816 9.37 24.1758 10.005 24.0883 15.015 25.1094 20.01 28.6863 25.07 28.4645 30.0 27.3209 35.005 26.0839 40.015 26.0022 45.0 26.0313 45.42 26.043 45.005 23.8782 44.84 5.17705 44.84 5.00784 44.765 5.00784 44.33 5.00784 44.2 5.00784 44.155 5.00784 44.15 5.00784 44.01 5.00784 43.995 5.00784 43.82 5.00784 43.66 5.002 43.66 5.002 43.5 5.002 43.5 5.002 43.245 5.002 43.24 5.002 43.225 5.002 43.11 5.002 42.855 4.99617 42.835 4.99617 42.825 4.99617 42.68 4.99617 42.67 4.99617 42.605 4.99617 42.55 4.99617 42.385 4.99617 42.28 4.99617 42.23 4.99617 42.225 4.99617 42.03 4.99617 41.865 4.99617 41.865 4.99617 41.855 4.99617 41.845 4.99617 41.84 4.99617 41.835 4.99617 41.83 4.99617 41.82 4.99617 41.635 4.99617 41.625 4.99617 41.56 4.99617 41.495 4.99617 41.39 4.99617 41.355 4.99617 41.255 4.99617 41.24 4.99617 40.98 4.99617 40.975 4.99617 40.84 4.99617 40.83 4.99617 40.655 4.99617 40.62 4.99617 40.62 5.002 40.58 5.002 40.545 5.002 40.455 5.002 40.415 5.002 40.35 5.002 40.34 5.002 40.285 5.002 40.275 5.002 40.19 5.002 40.175 5.002 40.15 5.002 40.105 5.002 39.995 5.002 39.995 4.99617 39.99 4.99617 39.905 5.002 39.87 5.002 39.795 5.002 39.78 5.002 39.775 5.002 39.77 5.002 39.665 5.002 39.665 5.002 39.59 5.002 39.58 5.002 39.325 5.002 39.275 5.002 39.125 5.002 39.015 5.002 38.885 5.002 38.88 5.002 38.875 5.002 38.745 4.99617 38.62 5.002 38.55 5.002 38.5 5.002 38.45 5.002 38.32 5.002 38.205 5.002 38.175 5.002 38.12 4.99617 37.96 4.99617 37.68 5.002 37.54 5.002 37.54 5.002 37.51 5.002 37.48 5.002 37.32 5.002 37.105 5.002 36.945 5.002 36.895 5.002 36.71 5.002 36.605 5.002 36.6 5.002 36.59 5.002 36.515 5.002 36.4 5.002 36.365 5.002 36.29 5.002 36.195 5.002 36.15 5.002 36.14 5.002 35.95 5.002 35.87 5.002 35.815 5.002 35.72 5.002 35.685 5.002 } set us_regions(SD.53) {109.775 26.3931 109.71 33.0275 109.735 47.0082 109.75 47.0082 110.04 47.0023 115.06 47.0082 120.025 47.0198 125.16 47.0257 130.185 47.0257 135.045 47.0257 140.03 48.6595 145.01 48.6945 147.785 50.5909 147.735 43.513 147.185 26.4631 145.005 26.4573 140.005 26.4573 135.025 26.4281 130.07 26.4165 125.095 26.3989 120.005 26.3989 115.02 26.3931 110.05 26.3931 109.83 26.3931 109.775 26.3931 } set us_regions(DE.12) {252.925 69.4087 251.06 69.9689 254.755 78.8614 255.035 78.8614 255.07 78.8614 255.07 78.7564 255.075 78.6222 255.08 78.523 255.08 78.523 255.06 78.1554 255.03 77.7236 255.015 77.6478 255.0 77.6186 254.95 77.0059 254.935 76.615 254.925 76.5041 252.925 69.4087 } set us_regions(GA.16) {223.1 132.718 223.125 132.316 223.47 131.102 223.435 131.038 223.435 131.038 223.415 131.015 223.275 130.624 223.57 130.32 223.555 130.163 223.555 130.163 223.555 130.157 223.75 129.912 223.75 129.912 223.975 129.492 224.07 129.287 224.08 128.978 224.105 128.692 224.14 128.412 224.055 128.231 224.375 127.689 224.47 127.537 224.47 127.537 224.5 127.409 224.52 127.391 224.525 127.391 224.67 126.662 224.74 126.102 225.0 125.827 225.015 125.798 225.015 125.787 225.29 125.39 225.6 124.911 225.625 124.87 225.675 124.777 225.925 124.456 226.06 124.246 226.08 124.083 226.085 124.077 226.09 124.036 226.095 123.96 226.24 123.808 226.24 123.808 226.245 123.791 226.25 123.785 226.285 123.674 226.25 123.674 224.995 123.342 219.995 113.405 215.0 106.724 214.455 103.024 214.395 103.024 209.975 103.118 208.39 103.112 205.0 103.118 201.98 103.135 201.975 103.135 204.995 120.477 205.0 121.591 205.0 121.784 205.0 122.752 205.0 130.933 205.0 130.98 204.99 131.026 204.99 131.032 204.99 131.032 205.0 131.242 210.0 133.337 215.0 133.728 220.0 132.52 223.265 133.051 223.125 132.736 223.12 132.73 223.1 132.718 223.1 132.718 } set us_regions(WI.61) {180.215 16.9696 180.0 16.9521 175.0 17.9557 169.99 21.0132 170.03 37.4096 173.91 43.5072 175.0 49.0037 176.815 50.4216 176.795 50.4567 180.0 50.4683 185.0 50.5442 189.995 50.55 194.375 50.5617 194.9 50.5617 194.9 50.5558 195.005 38.915 195.0 29.8999 190.0 27.4492 185.0 25.302 180.0 23.814 180.215 16.9696 } �����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�015000� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/xbob.xbm������������������������������������������������������������0000644�0001750�0001750�00000005157�11462120062�016456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define bob_x_hot 30 #define bob_y_hot 37 #define bob_width 61 #define bob_height 75 static short bobr_bits[] = { /* a right-going ``Bob'' */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0x07ff, 0x0000, 0x0000, 0xfffe, 0x1fff, 0x0000, 0x8000, 0xffff, 0xfbff, 0x0000, 0xc000, 0xcfff, 0xd19f, 0x0003, 0xf000, 0x8c7f, 0x9133, 0x0007, 0xf800, 0x18a7, 0xb127, 0x0006, 0xfc00, 0x3147, 0xa64e, 0x000e, 0xfe00, 0x214f, 0xae4c, 0x003d, 0xff00, 0x23df, 0xbe8d, 0x007d, 0xff80, 0x67ff, 0xfebd, 0x01ff, 0xff80, 0x7fff, 0xffbf, 0x03ff, 0xffc0, 0xffff, 0xffbf, 0x07f8, 0xffc0, 0xffff, 0x3fbf, 0x07f8, 0xffc0, 0xffff, 0x07ff, 0x0ff8, 0xffc0, 0xffff, 0x003f, 0x0ff8, 0x7fe0, 0xf800, 0x0007, 0x0ff0, 0x3fe0, 0x0000, 0x0000, 0x07f0, 0x3fe0, 0x0000, 0x0000, 0x07f0, 0x3fe0, 0x0000, 0x0000, 0x07f4, 0x3fe0, 0x0000, 0x0000, 0x07e4, 0x3fe0, 0x0000, 0x0000, 0x07e4, 0x3fe0, 0x0000, 0x0000, 0x07e6, 0x3fe0, 0x0000, 0x0000, 0x07e7, 0x3fe0, 0x0000, 0x0000, 0x07e6, 0x3fe0, 0x0000, 0x0000, 0x07e6, 0x3fe0, 0x0000, 0x0000, 0x07e6, 0x3fc0, 0x0000, 0x7800, 0x07f6, 0xbfa0, 0x00ff, 0xff00, 0x07f7, 0x9f70, 0x01ff, 0xff80, 0x07ef, 0x1cf0, 0x0380, 0x01e0, 0x07ef, 0x1ff0, 0x07be, 0x3ff0, 0x07ee, 0x9de0, 0x1f83, 0xe1f8, 0x07dc, 0xc1e0, 0x1f7f, 0xfffc, 0x07c8, 0xc1e0, 0x1e69, 0xca7e, 0x03c0, 0x81e0, 0x1fb8, 0x0ec0, 0x03c0, 0x01e0, 0x1bc0, 0xcfc0, 0x03c1, 0x03c0, 0x11f7, 0x7f00, 0x03c0, 0x03c0, 0x187c, 0x1c00, 0x02c0, 0x02c0, 0x0830, 0x0000, 0x0340, 0x0340, 0x0800, 0x0000, 0x0240, 0x1340, 0x0c00, 0x0000, 0x0260, 0x1240, 0x0e00, 0x0000, 0x03c0, 0x3380, 0x0e80, 0x0000, 0x01a8, 0x3300, 0x0f40, 0x03a0, 0x002c, 0x7400, 0x0f30, 0x0738, 0x002e, 0x7400, 0x1f98, 0x1e1e, 0x002f, 0xfc00, 0xff8f, 0xfc0f, 0x002f, 0xf800, 0xffe3, 0xf803, 0x002f, 0xf800, 0xfffd, 0xff81, 0x003f, 0xb800, 0x1ff9, 0x0ff8, 0x001e, 0x3000, 0xf0f1, 0x030f, 0x000e, 0x3000, 0x01f1, 0x0180, 0x000f, 0x2000, 0xf7f1, 0x00ff, 0x0007, 0x6000, 0x01e3, 0x8060, 0x0007, 0x6000, 0xefc3, 0x803f, 0x0003, 0x4000, 0xffc2, 0xc00f, 0x0003, 0xc000, 0x1fe6, 0xc000, 0x0001, 0x8000, 0xfef4, 0xe03f, 0x0000, 0x8000, 0xfe79, 0xe01f, 0x0000, 0x01c0, 0x3e3d, 0x7000, 0x0000, 0x0630, 0x0f3e, 0x3800, 0x0000, 0x8cc8, 0x071f, 0x3800, 0x0000, 0xccf4, 0x078f, 0x1c00, 0x0000, 0xee72, 0x07f7, 0x0e00, 0x0000, 0xff02, 0x07e3, 0x0700, 0x0000, 0xfe32, 0xffc1, 0x038f, 0x0000, 0xfe3e, 0xff80, 0x01ff, 0x0000, 0x7c7e, 0x0000, 0x007e, 0x0000, 0x3c7c, 0x0000, 0x0000, 0x0000, 0x1cfc, 0x0000, 0x0000, 0x0000, 0x1cf8, 0x0000, 0x0000, 0x0000, 0x0ff0, 0x0000, 0x0000, 0x0000, 0x07e0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/���������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�015712� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand13.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-13_width 16 #define hand6-13_height 16 #define hand6-13_x_hot 10 #define hand6-13_y_hot 11 static unsigned char hand6-13_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xaf, 0x80, 0xa9, 0x80, 0x29, 0x80, 0x6f, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand01.xbm�����������������������������������������������������0000644�0001750�0001750�00000000526�11462120062�017504� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-1_width 16 #define hand6-1_height 16 #define hand6-1_x_hot 8 #define hand6-1_y_hot 10 static unsigned char hand6-1_bits[] = { 0x00, 0x00, 0x80, 0x03, 0xe0, 0x0e, 0xa0, 0x1a, 0xa0, 0x2a, 0xa0, 0x2a, 0xa0, 0x2a, 0xb8, 0x2a, 0x28, 0x28, 0x28, 0x20, 0x28, 0x20, 0x08, 0x20, 0x08, 0x20, 0x10, 0x20, 0x20, 0x10, 0xe0, 0x1f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand04m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017661� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-04m_width 16 #define hand6-04m_height 16 #define hand6-04m_x_hot 10 #define hand6-04m_y_hot 11 static unsigned char hand6-04m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0xbc, 0x7f, 0xbc, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0x80, 0xff, 0xb8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xe0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand12.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017505� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-12_width 16 #define hand6-12_height 16 #define hand6-12_x_hot 10 #define hand6-12_y_hot 11 static unsigned char hand6-12_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xef, 0xaa, 0xa9, 0xa0, 0xa9, 0x80, 0xaf, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand12m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017660� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-12m_width 16 #define hand6-12m_height 16 #define hand6-12m_x_hot 10 #define hand6-12m_y_hot 11 static unsigned char hand6-12m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xef, 0xff, 0xef, 0xff, 0xef, 0xff, 0xef, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand04.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-04_width 16 #define hand6-04_height 16 #define hand6-04_x_hot 10 #define hand6-04_y_hot 11 static unsigned char hand6-04_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0xbc, 0x6a, 0xa4, 0xaa, 0xa4, 0xaa, 0xbc, 0xaa, 0x80, 0xa0, 0xb8, 0x80, 0xc8, 0x80, 0x98, 0x80, 0x30, 0x80, 0xe0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand10m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017656� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-10m_width 16 #define hand6-10m_height 16 #define hand6-10m_x_hot 10 #define hand6-10m_y_hot 11 static unsigned char hand6-10m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x8f, 0x3f, 0x8f, 0x7f, 0x8f, 0xff, 0x8f, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand05m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017662� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-05m_width 16 #define hand6-05m_height 16 #define hand6-05m_x_hot 10 #define hand6-05m_y_hot 11 static unsigned char hand6-05m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xbc, 0x3f, 0xbc, 0x3f, 0xbc, 0x7f, 0xbc, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0xb8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xe0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand03.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017505� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-03_width 16 #define hand6-03_height 16 #define hand6-03_x_hot 10 #define hand6-03_y_hot 11 static unsigned char hand6-03_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0xbc, 0xaa, 0xa4, 0xaa, 0xa4, 0xaa, 0xbc, 0xa0, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x80, 0x08, 0x80, 0xf8, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand02.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017504� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-02_width 16 #define hand6-02_height 16 #define hand6-02_x_hot 10 #define hand6-02_y_hot 11 static unsigned char hand6-02_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0xbc, 0xaa, 0xa4, 0xaa, 0xa4, 0xa0, 0xbc, 0x80, 0x80, 0x80, 0xf8, 0x80, 0x08, 0x80, 0xf8, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand07.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017511� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-07_width 16 #define hand6-07_height 16 #define hand6-07_x_hot 10 #define hand6-07_y_hot 11 static unsigned char hand6-07_bits[] = { 0x1e, 0x00, 0x12, 0x00, 0x12, 0x0e, 0x9e, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand03m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017660� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-03m_width 16 #define hand6-03m_height 16 #define hand6-03m_x_hot 10 #define hand6-03m_y_hot 11 static unsigned char hand6-03m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0xbc, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0x80, 0xff, 0x80, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand06.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-06_width 16 #define hand6-06_height 16 #define hand6-06_x_hot 10 #define hand6-06_y_hot 11 static unsigned char hand6-06_bits[] = { 0x00, 0x00, 0x3c, 0x00, 0x24, 0x0e, 0xa4, 0x3b, 0xbc, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0x80, 0xaa, 0x80, 0xa0, 0xb8, 0x80, 0xc8, 0x80, 0x98, 0x80, 0x30, 0x80, 0xe0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand11m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-11m_width 16 #define hand6-11m_height 16 #define hand6-11m_x_hot 10 #define hand6-11m_y_hot 11 static unsigned char hand6-11m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x8f, 0xff, 0x8f, 0xff, 0xef, 0xff, 0xef, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand13m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017661� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-13m_width 16 #define hand6-13m_height 16 #define hand6-13m_x_hot 10 #define hand6-13m_y_hot 11 static unsigned char hand6-13m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xef, 0xff, 0xef, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand09.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017513� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-09_width 16 #define hand6-09_height 16 #define hand6-09_x_hot 10 #define hand6-09_y_hot 11 static unsigned char hand6-09_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x89, 0x3b, 0x89, 0x2a, 0x8f, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand10.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017503� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-10_width 16 #define hand6-10_height 16 #define hand6-10_x_hot 10 #define hand6-10_y_hot 11 static unsigned char hand6-10_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x8f, 0x2a, 0x89, 0x6a, 0x89, 0xaa, 0x8f, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand08.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017512� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-08_width 16 #define hand6-08_height 16 #define hand6-08_x_hot 10 #define hand6-08_y_hot 11 static unsigned char hand6-08_bits[] = { 0x00, 0x00, 0x0f, 0x00, 0x09, 0x0e, 0x89, 0x3b, 0x8f, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand14m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017662� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-14m_width 16 #define hand6-14m_height 16 #define hand6-14m_x_hot 10 #define hand6-14m_y_hot 11 static unsigned char hand6-14m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xcf, 0xff, 0x8f, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand05.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017507� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-05_width 16 #define hand6-05_height 16 #define hand6-05_x_hot 10 #define hand6-05_y_hot 11 static unsigned char hand6-05_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xbc, 0x3b, 0xa4, 0x2a, 0xa4, 0x6a, 0xbc, 0xaa, 0x80, 0xaa, 0x80, 0xaa, 0x80, 0xa0, 0xb8, 0x80, 0xc8, 0x80, 0x98, 0x80, 0x30, 0x80, 0xe0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand06m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017663� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-06m_width 16 #define hand6-06m_height 16 #define hand6-06m_x_hot 10 #define hand6-06m_y_hot 11 static unsigned char hand6-06m_bits[] = { 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x0e, 0xbc, 0x3f, 0xbc, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0xb8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xe0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand01m.xbm����������������������������������������������������0000644�0001750�0001750�00000000532�11462120062�017656� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-1m_width 16 #define hand6-1m_height 16 #define hand6-1m_x_hot 8 #define hand6-1m_y_hot 9 static unsigned char hand6-1m_bits[] = { 0x00, 0x00, 0x80, 0x03, 0xe0, 0x0f, 0xe0, 0x1f, 0xe0, 0x3f, 0xe0, 0x3f, 0xe0, 0x3f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf0, 0x3f, 0xe0, 0x1f, 0xe0, 0x1f}; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand09m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017666� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-09m_width 16 #define hand6-09m_height 16 #define hand6-09m_x_hot 10 #define hand6-09m_y_hot 11 static unsigned char hand6-09m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x8f, 0x3f, 0x8f, 0x3f, 0x8f, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand11.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017504� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-11_width 16 #define hand6-11_height 16 #define hand6-11_x_hot 10 #define hand6-11_y_hot 11 static unsigned char hand6-11_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x8f, 0xaa, 0x89, 0xaa, 0xe9, 0xaa, 0xaf, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x20, 0x80, 0x60, 0x80, 0xc0, 0xc0, 0x80, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand02m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-02m_width 16 #define hand6-02m_height 16 #define hand6-02m_x_hot 10 #define hand6-02m_y_hot 11 static unsigned char hand6-02m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0x80, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand14.xbm�����������������������������������������������������0000644�0001750�0001750�00000000534�11462120062�017507� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-14_width 16 #define hand6-14_height 16 #define hand6-14_x_hot 10 #define hand6-14_y_hot 11 static unsigned char hand6-14_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x3b, 0x80, 0x2a, 0x80, 0x6a, 0x80, 0xaa, 0x80, 0xaa, 0xe0, 0xaa, 0xa0, 0xa0, 0xa0, 0x80, 0xa0, 0x80, 0x2f, 0x80, 0x69, 0x80, 0xc9, 0xc0, 0x8f, 0x7f}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand07m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017664� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-07m_width 16 #define hand6-07m_height 16 #define hand6-07m_x_hot 10 #define hand6-07m_y_hot 11 static unsigned char hand6-07m_bits[] = { 0x1e, 0x00, 0x1e, 0x00, 0x1e, 0x0e, 0x9e, 0x3f, 0x80, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hand/hand08m.xbm����������������������������������������������������0000644�0001750�0001750�00000000541�11462120062�017665� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hand6-08m_width 16 #define hand6-08m_height 16 #define hand6-08m_x_hot 10 #define hand6-08m_y_hot 11 static unsigned char hand6-08m_bits[] = { 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0e, 0x8f, 0x3f, 0x8f, 0x3f, 0x80, 0x7f, 0x80, 0xff, 0x80, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x80, 0x7f}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hobbes_mask.xbm�����������������������������������������������������0000644�0001750�0001750�00000001374�11462120062�017776� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hobbes_width 25 #define hobbes_height 25 #define hobbes_x_hot 16 #define hobbes_y_hot 15 static unsigned char hobbes_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x78, 0xe0, 0x07, 0x00, 0xfc, 0xf8, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0x80, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/face.xbm������������������������������������������������������������0000644�0001750�0001750�00000030604�11462120062�016415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define face_width 108 #define face_height 144 static char face_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x20, 0x80, 0x24, 0x05, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88, 0x24, 0x20, 0x80, 0x24, 0x00, 0x00, 0x00, 0x10, 0x80, 0x04, 0x00, 0x01, 0x00, 0x01, 0x40, 0x0a, 0x09, 0x00, 0x92, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x12, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x84, 0x24, 0x40, 0x22, 0xa8, 0x02, 0x14, 0x84, 0x92, 0x40, 0x42, 0x12, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52, 0x11, 0x00, 0x12, 0x00, 0x40, 0x02, 0x00, 0x20, 0x00, 0x08, 0x00, 0xaa, 0x02, 0x54, 0x85, 0x24, 0x00, 0x10, 0x12, 0x00, 0x00, 0x81, 0x44, 0x00, 0x90, 0x5a, 0x00, 0xea, 0x1b, 0x00, 0x80, 0x40, 0x40, 0x02, 0x00, 0x08, 0x00, 0x20, 0xa2, 0x05, 0x8a, 0xb4, 0x6e, 0x45, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10, 0x02, 0xa8, 0x92, 0x00, 0xda, 0x5f, 0x10, 0x00, 0x10, 0xa1, 0x04, 0x20, 0x41, 0x02, 0x00, 0x5a, 0x25, 0xa0, 0xff, 0xfb, 0x05, 0x41, 0x02, 0x04, 0x00, 0x00, 0x08, 0x40, 0x80, 0xec, 0x9b, 0xec, 0xfe, 0x7f, 0x01, 0x04, 0x20, 0x90, 0x02, 0x04, 0x00, 0x08, 0x20, 0xfb, 0x2e, 0xf5, 0xff, 0xff, 0x57, 0x00, 0x04, 0x02, 0x00, 0x00, 0x20, 0x01, 0xc1, 0x6e, 0xab, 0xfa, 0xff, 0xff, 0x05, 0x90, 0x20, 0x48, 0x02, 0x00, 0x04, 0x20, 0xa8, 0xdf, 0xb5, 0xfe, 0xff, 0xff, 0x0b, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x04, 0xe0, 0xbb, 0xef, 0xff, 0xff, 0x7f, 0x01, 0x00, 0x04, 0x48, 0x02, 0x00, 0x20, 0x80, 0xf4, 0x6f, 0xfb, 0xff, 0xff, 0xff, 0x20, 0x90, 0x40, 0x02, 0x00, 0x00, 0x04, 0x08, 0xb8, 0xf6, 0xff, 0xff, 0xdf, 0xbe, 0x12, 0x45, 0x10, 0x90, 0x04, 0x90, 0x00, 0x22, 0xfa, 0xff, 0xff, 0xff, 0xbb, 0xd7, 0xe9, 0x3a, 0x02, 0x02, 0x00, 0x04, 0x90, 0x80, 0xfe, 0xdf, 0xf6, 0xb7, 0xef, 0xbe, 0x56, 0x57, 0x40, 0x48, 0x09, 0x00, 0x04, 0x00, 0xfa, 0xf5, 0xdf, 0xed, 0x5a, 0xd5, 0xea, 0xbd, 0x09, 0x00, 0x00, 0x40, 0x00, 0x92, 0xfe, 0xbf, 0x7d, 0xb7, 0x6a, 0x55, 0xbf, 0xf7, 0x02, 0x11, 0x01, 0x00, 0x91, 0x00, 0xff, 0xff, 0xaf, 0x55, 0x55, 0x5b, 0xeb, 0xef, 0x22, 0x04, 0x04, 0x04, 0x00, 0xa4, 0xff, 0xf7, 0xad, 0xaa, 0xaa, 0xaa, 0xbe, 0xfe, 0x03, 0x20, 0x00, 0x10, 0x44, 0x80, 0xff, 0x7f, 0x55, 0x12, 0x91, 0x2a, 0xeb, 0xbf, 0x0b, 0x82, 0x02, 0x00, 0x00, 0xd1, 0x7f, 0xdf, 0xa2, 0xa4, 0x54, 0x55, 0xfd, 0xfd, 0x47, 0x08, 0x08, 0x00, 0x21, 0xe4, 0xff, 0x37, 0x11, 0x09, 0xa5, 0xaa, 0xb6, 0xff, 0x0d, 0x80, 0x00, 0x00, 0x04, 0xd0, 0xff, 0x4f, 0x44, 0x20, 0x48, 0x55, 0xfb, 0xff, 0x27, 0x11, 0x02, 0x40, 0x40, 0xe2, 0xfb, 0x15, 0x11, 0x4a, 0x55, 0x4a, 0x7d, 0xf7, 0x0f, 0x00, 0x00, 0x04, 0x08, 0xf8, 0xdf, 0x52, 0x44, 0x01, 0x52, 0xb5, 0xfa, 0xff, 0x0f, 0x49, 0x02, 0x00, 0x02, 0xe9, 0xf6, 0x0a, 0x11, 0xa4, 0x88, 0x4a, 0x6d, 0xff, 0x5f, 0x00, 0x00, 0x10, 0x20, 0xf0, 0x2f, 0x21, 0x44, 0x10, 0x52, 0xb5, 0xfa, 0xff, 0x0f, 0x44, 0x04, 0x80, 0x08, 0xf8, 0xab, 0x8a, 0x00, 0x81, 0xa4, 0xd4, 0xd6, 0xfe, 0x2f, 0x00, 0x00, 0x04, 0x40, 0xb5, 0x2d, 0x21, 0x08, 0x04, 0x90, 0xaa, 0xfa, 0xff, 0x1f, 0x11, 0x01, 0x00, 0x04, 0xf0, 0x57, 0x0a, 0x22, 0x40, 0x4a, 0xda, 0x5e, 0xfb, 0x1f, 0x40, 0x00, 0x40, 0x20, 0xba, 0x95, 0x90, 0x00, 0x01, 0xa0, 0xaa, 0xea, 0xff, 0x5f, 0x02, 0x02, 0x00, 0x01, 0xe8, 0x57, 0x05, 0x00, 0x00, 0x12, 0xd5, 0xfe, 0xfd, 0x1f, 0x48, 0x00, 0x04, 0x48, 0x7a, 0x95, 0x08, 0x02, 0x10, 0x40, 0xaa, 0x55, 0xf7, 0x1f, 0x00, 0x09, 0x20, 0x00, 0xf8, 0x57, 0x22, 0x10, 0x00, 0x28, 0xa9, 0xfa, 0xff, 0x5f, 0x02, 0x00, 0x00, 0x49, 0xdd, 0x29, 0x01, 0x00, 0x80, 0x80, 0xaa, 0xd7, 0xff, 0x0f, 0x10, 0x00, 0x08, 0x00, 0xf8, 0x96, 0x08, 0x00, 0x00, 0x20, 0x54, 0xfa, 0xee, 0x3f, 0x81, 0x04, 0x40, 0x24, 0xfe, 0x55, 0x82, 0x00, 0x00, 0x82, 0xd2, 0xad, 0xff, 0x0f, 0x08, 0x00, 0x04, 0x80, 0x6c, 0x97, 0x00, 0x00, 0x02, 0x20, 0xa9, 0xf6, 0xdf, 0x5f, 0x00, 0x02, 0x20, 0x09, 0xfa, 0x49, 0x12, 0x00, 0x20, 0x84, 0x54, 0xdb, 0xfe, 0x1f, 0x91, 0x00, 0x00, 0x00, 0xf8, 0x2b, 0x00, 0x20, 0x00, 0x40, 0xa4, 0xf6, 0xbb, 0x1f, 0x04, 0x00, 0x44, 0x92, 0x7e, 0x95, 0x02, 0x00, 0x00, 0x89, 0xaa, 0xdd, 0xff, 0x1f, 0x20, 0x09, 0x10, 0x00, 0xf4, 0x57, 0x20, 0x01, 0x08, 0x20, 0xa9, 0x76, 0xff, 0x5f, 0x02, 0x00, 0x00, 0x21, 0xfc, 0x4a, 0x05, 0x00, 0x01, 0x80, 0x54, 0xdb, 0xff, 0x1e, 0x08, 0x02, 0x04, 0x08, 0xf9, 0x2b, 0x00, 0x00, 0x40, 0x28, 0xd2, 0xf6, 0xff, 0xbf, 0x80, 0x00, 0x90, 0x00, 0xbc, 0x92, 0x08, 0x10, 0x00, 0x82, 0x54, 0xdb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x44, 0xf9, 0x55, 0x02, 0x01, 0x00, 0x20, 0xaa, 0xbd, 0xfd, 0x3f, 0x08, 0x04, 0x04, 0x10, 0xf4, 0x2a, 0x01, 0x00, 0x22, 0x80, 0xd4, 0xf6, 0xff, 0x5f, 0x82, 0x00, 0x40, 0x02, 0xf8, 0x55, 0x20, 0x00, 0x00, 0x50, 0x6a, 0xdf, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x48, 0xe9, 0x4a, 0x05, 0x08, 0x00, 0xa5, 0xd5, 0xf5, 0xff, 0x3f, 0x10, 0x01, 0x10, 0x01, 0xb0, 0xab, 0x92, 0x02, 0x40, 0xf8, 0xbf, 0xde, 0xfe, 0x5f, 0x02, 0x04, 0x04, 0x48, 0xfa, 0xd4, 0x6f, 0x20, 0x84, 0xef, 0xff, 0xfb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xed, 0xbf, 0x0b, 0xa1, 0x7e, 0xff, 0xbf, 0xfd, 0x5f, 0x04, 0x01, 0x20, 0x49, 0xd2, 0xfb, 0xfe, 0x55, 0xd4, 0xff, 0xff, 0xf6, 0xff, 0x07, 0x00, 0x04, 0x00, 0x00, 0xc0, 0xaa, 0xfb, 0x2b, 0xa2, 0xfe, 0xff, 0xdf, 0xee, 0x1f, 0x91, 0x00, 0x82, 0xa4, 0xa4, 0xf5, 0xff, 0x57, 0xd5, 0xff, 0xbf, 0xfd, 0xff, 0x4d, 0x00, 0x00, 0x20, 0x00, 0x88, 0x5b, 0xff, 0x2f, 0x69, 0xff, 0xff, 0xdb, 0xfe, 0x1f, 0x24, 0x02, 0x00, 0x49, 0xa2, 0xd6, 0xff, 0x5f, 0xea, 0xff, 0x7f, 0x7f, 0x7f, 0x0d, 0x00, 0x00, 0x10, 0x00, 0x40, 0xab, 0xf7, 0xbb, 0xf0, 0xdf, 0xff, 0xd5, 0xff, 0xbf, 0x82, 0x04, 0x42, 0x24, 0x91, 0xd5, 0xaa, 0xae, 0xd4, 0xaa, 0x52, 0x7b, 0xff, 0x15, 0x08, 0x00, 0x00, 0x01, 0x04, 0x55, 0xd5, 0x55, 0x70, 0x5b, 0x75, 0xdd, 0xdf, 0x1f, 0x40, 0x00, 0x08, 0x48, 0xa0, 0x4a, 0xa9, 0x56, 0xea, 0x56, 0xad, 0x6a, 0x7d, 0x9b, 0x04, 0x01, 0x00, 0x02, 0x42, 0x2a, 0xd5, 0xaa, 0xa8, 0xaa, 0xaa, 0xfa, 0xdf, 0x2f, 0x10, 0x04, 0x22, 0x48, 0x08, 0x45, 0x2a, 0x15, 0x68, 0x55, 0x55, 0xd7, 0x76, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x40, 0x2a, 0x80, 0xa0, 0xb2, 0x09, 0x48, 0xb9, 0xdf, 0x17, 0x22, 0x01, 0x00, 0x24, 0x45, 0x8a, 0x24, 0x4a, 0x54, 0x51, 0x91, 0xf6, 0x6e, 0x4b, 0x00, 0x04, 0x90, 0x00, 0x80, 0x52, 0x00, 0x20, 0x69, 0x05, 0xa4, 0xaa, 0xff, 0x1e, 0x48, 0x00, 0x02, 0x92, 0x08, 0x05, 0x81, 0x94, 0xd4, 0x92, 0x40, 0xfd, 0xb6, 0x8b, 0x00, 0x01, 0x40, 0x00, 0x82, 0x54, 0x00, 0x48, 0x68, 0x05, 0x90, 0xa4, 0xef, 0x06, 0x24, 0x00, 0x08, 0x12, 0x10, 0x05, 0x00, 0x10, 0xb5, 0x01, 0x42, 0xfb, 0xbf, 0x43, 0x00, 0x09, 0x00, 0x40, 0x81, 0xa8, 0x08, 0x4a, 0xaa, 0x96, 0x90, 0xac, 0x6d, 0x15, 0x22, 0x00, 0x20, 0x09, 0x04, 0x15, 0x80, 0x28, 0xdc, 0x01, 0x24, 0xfb, 0xbf, 0x01, 0x80, 0x04, 0x09, 0x00, 0x40, 0x48, 0x02, 0x45, 0xb2, 0x2e, 0x41, 0x6d, 0xef, 0x05, 0x11, 0x00, 0x40, 0x52, 0x02, 0x15, 0x29, 0x2a, 0xac, 0x42, 0x54, 0xfb, 0x3b, 0x51, 0x84, 0x00, 0x08, 0x00, 0x20, 0x54, 0x80, 0x05, 0xb5, 0x3d, 0xa2, 0xb6, 0xdf, 0x00, 0x20, 0x04, 0x20, 0x49, 0x89, 0xa8, 0x6a, 0x29, 0xac, 0xd6, 0x54, 0xff, 0x3f, 0x84, 0x00, 0x01, 0x04, 0x10, 0x00, 0x94, 0xa8, 0x56, 0xda, 0x5f, 0xab, 0xd5, 0x1e, 0x10, 0x48, 0x00, 0x90, 0x82, 0x48, 0xa8, 0xb2, 0xac, 0xfd, 0x55, 0xd5, 0xfe, 0x9f, 0x80, 0x00, 0x0a, 0x02, 0x08, 0x02, 0x55, 0x5a, 0x75, 0xff, 0xaf, 0xb6, 0xf7, 0x2d, 0x12, 0x92, 0x00, 0x10, 0x20, 0x10, 0xa8, 0x54, 0xd5, 0xbf, 0x5d, 0xad, 0xdd, 0x0f, 0x00, 0x00, 0x04, 0x40, 0x09, 0x84, 0xa8, 0xaa, 0x5a, 0xed, 0xeb, 0x6a, 0xff, 0x9f, 0xa4, 0x24, 0x01, 0x02, 0xa0, 0x20, 0x50, 0x55, 0xd5, 0xbe, 0xae, 0xad, 0xfd, 0x16, 0x00, 0x10, 0x04, 0x20, 0x0a, 0x08, 0xb4, 0xaa, 0x95, 0xaa, 0x7b, 0xb7, 0xdb, 0x5f, 0x92, 0x04, 0x01, 0x84, 0x20, 0x21, 0x51, 0xd5, 0x2a, 0xa9, 0xee, 0xd5, 0xfe, 0x0d, 0x00, 0x20, 0x04, 0x10, 0x00, 0x08, 0x50, 0xe9, 0xd7, 0xd4, 0xfb, 0xb5, 0xff, 0x9f, 0x24, 0x09, 0x01, 0x42, 0x4a, 0xa2, 0x64, 0xd5, 0x55, 0x7b, 0x7f, 0xda, 0x7d, 0x4f, 0x00, 0x20, 0x04, 0x00, 0x80, 0x00, 0xa0, 0x2a, 0x13, 0x84, 0x6a, 0x55, 0xff, 0x1d, 0x48, 0x8a, 0x00, 0x94, 0x24, 0x8a, 0xc8, 0xaa, 0x42, 0x20, 0x5d, 0xf5, 0xff, 0x5f, 0x01, 0x00, 0x02, 0x01, 0x00, 0x20, 0xa2, 0x4a, 0x1a, 0x82, 0x56, 0xda, 0xbd, 0x3f, 0x92, 0x92, 0x00, 0x90, 0x92, 0x00, 0x40, 0x95, 0x6a, 0xf4, 0x55, 0x6d, 0xff, 0xd6, 0x00, 0x00, 0x0a, 0x04, 0x20, 0x14, 0x49, 0x4b, 0xaa, 0xaa, 0x56, 0xf5, 0xff, 0xbf, 0xab, 0xa4, 0x00, 0x20, 0x89, 0x40, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xde, 0xbf, 0xeb, 0x03, 0x00, 0x02, 0x04, 0x02, 0x0a, 0x10, 0x2b, 0x2a, 0x55, 0x5b, 0xf5, 0xff, 0xd7, 0x2f, 0x92, 0x00, 0x10, 0x28, 0x21, 0x01, 0x56, 0x95, 0xa0, 0x56, 0xdf, 0xef, 0xea, 0x87, 0x40, 0x0a, 0x42, 0x41, 0x00, 0x90, 0xaa, 0x52, 0xb6, 0xad, 0xfa, 0xff, 0xd5, 0x2f, 0x14, 0x00, 0x00, 0x04, 0x95, 0x04, 0xaa, 0xac, 0x55, 0x6b, 0xff, 0xb7, 0xea, 0x9f, 0x40, 0x02, 0x28, 0x51, 0x00, 0x40, 0x58, 0xd5, 0xda, 0xd6, 0x6e, 0x7f, 0xf9, 0x3f, 0x12, 0x04, 0x02, 0x04, 0x49, 0x25, 0x55, 0xaa, 0x77, 0xab, 0xff, 0x2b, 0xfd, 0x3f, 0x48, 0x01, 0x20, 0x41, 0x00, 0x00, 0x58, 0xa9, 0xda, 0xea, 0xfd, 0xaf, 0xfa, 0xff, 0x02, 0x04, 0x08, 0x14, 0x29, 0x49, 0x52, 0x55, 0x55, 0x55, 0xff, 0x8d, 0xfe, 0x3f, 0xa8, 0x00, 0x02, 0x41, 0x00, 0x02, 0xa0, 0xa2, 0xaa, 0xea, 0xff, 0x53, 0xfd, 0xff, 0x02, 0x04, 0x50, 0x04, 0x25, 0xa8, 0x54, 0x49, 0x52, 0xb5, 0xbf, 0x8a, 0xfe, 0xff, 0xa9, 0x08, 0x04, 0x50, 0x80, 0x02, 0xa1, 0x2a, 0x95, 0xea, 0xff, 0xa1, 0xff, 0xff, 0x03, 0x02, 0x90, 0x02, 0x09, 0x08, 0x44, 0x49, 0x52, 0xbd, 0x7f, 0xca, 0xff, 0xff, 0x2b, 0x09, 0x04, 0x48, 0x40, 0x82, 0x90, 0x56, 0xa9, 0xf6, 0xbf, 0xd0, 0xff, 0xff, 0x47, 0x00, 0x50, 0x02, 0x15, 0x11, 0x40, 0x95, 0xaa, 0xfd, 0x2f, 0xe9, 0xff, 0xff, 0x8f, 0x0a, 0x84, 0x50, 0x40, 0x84, 0x14, 0xaa, 0x6a, 0xff, 0x5f, 0xf2, 0xff, 0xff, 0x7f, 0x00, 0x10, 0x02, 0x09, 0x10, 0x40, 0x7d, 0xf7, 0xff, 0x0b, 0xfc, 0xff, 0xff, 0xaf, 0x02, 0x84, 0x50, 0x42, 0x85, 0x12, 0xd0, 0xdd, 0xff, 0xa7, 0xf2, 0xff, 0xff, 0xff, 0x04, 0x00, 0x0a, 0x08, 0x10, 0x48, 0xf8, 0xff, 0xff, 0x0a, 0xfe, 0xff, 0xff, 0x7f, 0x03, 0xa4, 0x80, 0xa2, 0x8a, 0x02, 0x68, 0xff, 0xff, 0x52, 0xfd, 0xff, 0xff, 0xff, 0x07, 0x00, 0x2a, 0x08, 0x20, 0x28, 0xdc, 0xff, 0x5f, 0x05, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x92, 0x40, 0x22, 0x09, 0x02, 0xea, 0xfb, 0xaf, 0x48, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x12, 0x81, 0xa0, 0x48, 0x9c, 0x6e, 0x93, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa8, 0x40, 0x28, 0x0a, 0x02, 0x74, 0xb5, 0x45, 0x81, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x02, 0x0a, 0x81, 0x20, 0x08, 0xae, 0xaa, 0x90, 0xe8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x90, 0x40, 0x28, 0x88, 0x12, 0x58, 0x15, 0x50, 0xd0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x44, 0x0a, 0x41, 0x21, 0x08, 0xae, 0x04, 0x14, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, 0x14, 0x88, 0x04, 0xba, 0x02, 0x28, 0xe8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x15, 0x41, 0x21, 0x05, 0xad, 0x00, 0x05, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, 0x24, 0x8a, 0x0e, 0x36, 0x00, 0x0a, 0xf4, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x25, 0x90, 0xd0, 0x8b, 0xc2, 0x41, 0x05, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x08, 0x05, 0xe8, 0x8e, 0x58, 0x80, 0x02, 0xfa, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x4a, 0x20, 0xa8, 0xba, 0x0b, 0x2b, 0x51, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x8a, 0x02, 0xe8, 0xaf, 0x84, 0x90, 0x04, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x52, 0x21, 0x54, 0xbf, 0x1f, 0x15, 0xa5, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x08, 0x01, 0xfa, 0xb6, 0xa4, 0x52, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x4a, 0xa2, 0x54, 0xef, 0x5f, 0x4b, 0xa4, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x10, 0x82, 0xfe, 0xbf, 0x92, 0x52, 0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x12, 0x42, 0xa8, 0xbf, 0x1f, 0x24, 0x80, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, 0x8a, 0xf7, 0x37, 0x80, 0x52, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x82, 0xe0, 0xff, 0x1f, 0x00, 0x20, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, 0xca, 0xff, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x42, 0xf0, 0xfd, 0x1b, 0x00, 0x50, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xa4, 0x10, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x22, 0xf8, 0xff, 0x0e, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xaa, 0x88, 0xe2, 0xff, 0x0f, 0x10, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x25, 0xfa, 0xff, 0x0f, 0x01, 0x11, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xfb, 0xfb, 0xff, 0x7f, 0x5d, 0xd5, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f}; ����������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/greenback.xbm�������������������������������������������������������0000644�0001750�0001750�00000204645�11462120062�017450� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define greenback_width 499 #define greenback_height 210 static char greenback_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x44, 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x09,0x10,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, 0x20,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x40,0x00, 0x08,0x20,0x20,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x10, 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x02,0x00, 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x11,0x00,0x00,0x01,0x00, 0x00,0x00,0x48,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x02,0x04, 0x48,0x10,0x02,0x01,0x01,0x09,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00, 0x22,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x04,0x48,0x10,0x01, 0x41,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x10,0x40,0x00,0x00,0x00, 0x40,0x00,0x02,0x08,0x48,0x00,0x02,0x80,0x20,0x00,0x00,0x80,0x04,0x00,0x00, 0x01,0x40,0x00,0x00,0x04,0x10,0x00,0x44,0x00,0x00,0x00,0x10,0x14,0x22,0x54, 0xa4,0xb6,0xf7,0xfe,0x6f,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0x9f,0xaa,0xd9, 0x95,0xef,0xfe,0xba,0xda,0xd7,0x56,0x77,0xaf,0x56,0x7d,0x81,0x50,0x45,0x15, 0xc9,0x00,0x00,0x00,0x6d,0xb5,0xd3,0x95,0xab,0xaa,0x35,0xad,0xaa,0x4a,0x29, 0x40,0x92,0x40,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x20,0x11,0x22,0x12,0x00,0x21,0x25,0x55,0xa8,0xa4,0x54,0xa9,0xaa,0x92,0x7e, 0x6f,0x7b,0xed,0xbe,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x88,0x00,0x42,0xa4,0x00,0x08, 0x41,0x00,0x00,0x01,0x00,0x81,0x80,0xa4,0x54,0x5b,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x08,0x00,0x10,0xfd,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xbb,0xf7,0x80,0x84, 0x28,0x22,0x00,0x06,0x14,0x0c,0x68,0x04,0x08,0x80,0xf7,0xf7,0xfd,0xff,0xbf, 0xfb,0xff,0xf3,0xff,0xff,0xbb,0xea,0xef,0xbb,0xbf,0x00,0x00,0x00,0xdd,0xbf, 0xfe,0xbf,0xfe,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xef,0xe7,0x8a,0x5a, 0x82,0x92,0xb4,0x40,0x48,0x40,0x7f,0x7b,0x54,0x3e,0x02,0x06,0x00,0x07,0x00, 0x00,0x0c,0x06,0x03,0x23,0x08,0x1e,0x30,0x8e,0xe1,0x84,0x08,0x0e,0xe7,0xbf, 0xbe,0xef,0x7b,0xf5,0xda,0xb5,0xbd,0x5f,0xbf,0xff,0xee,0xae,0xbf,0x00,0x00, 0x00,0xf5,0x5d,0x9f,0xdf,0xdf,0xff,0xff,0xef,0xbf,0x63,0xeb,0xfe,0xbf,0xd6, 0xe5,0xc0,0x18,0x1c,0x83,0xc1,0xe0,0x38,0x1a,0x3c,0xf0,0x81,0x3f,0x18,0x18, 0x1c,0x83,0x7f,0xf0,0x1c,0x06,0x02,0x77,0x78,0x3e,0x61,0x83,0x43,0x82,0x19, 0x2c,0x67,0xd5,0x6f,0x53,0xb7,0xdd,0xff,0xe5,0x67,0xed,0xee,0xae,0xe7,0x7d, 0xab,0x08,0x00,0x00,0xbd,0xdf,0xaf,0x7f,0xbb,0xfd,0xee,0xcf,0xfb,0xdf,0xbf, 0xff,0xfd,0xfb,0xe7,0xc1,0x19,0x2c,0x87,0xc1,0x61,0x3b,0x1c,0x1c,0xf0,0xc1, 0x7f,0x38,0x38,0x6c,0x01,0xf0,0xa0,0x1d,0x06,0x06,0x7f,0xc8,0x7f,0xc0,0x83, 0xc3,0x96,0x9b,0xf0,0xe7,0xfe,0xdd,0xdd,0xfd,0xdf,0xae,0xa4,0xbb,0xba,0xbf, 0xdd,0x77,0xff,0xbb,0x00,0x00,0x00,0xf5,0x6e,0xaf,0x6f,0xfe,0x5f,0xfb,0xd7, 0xbf,0x7b,0xff,0x4e,0x77,0xef,0xe5,0x01,0x1e,0xe2,0x87,0xc3,0x21,0x3f,0x80, 0xdf,0xe0,0xe1,0xff,0x00,0x3e,0xe4,0x03,0x60,0x10,0x3f,0x82,0x0f,0x7a,0xd0, 0xfe,0x01,0x83,0xc3,0x87,0x1f,0x6c,0xe7,0x5b,0x7f,0xbf,0xb7,0xad,0x7b,0xe6, 0xad,0x6a,0xd7,0xfb,0xcd,0xbe,0xbd,0x20,0x00,0x24,0x5d,0xbf,0xb6,0x5f,0xdd, 0x57,0xfd,0x95,0xff,0xf7,0xdb,0xbd,0xbf,0xde,0xe7,0xc1,0x9e,0x6c,0x87,0xc1, 0x61,0x3b,0x08,0x2e,0xe0,0xe1,0x7f,0x18,0x3c,0x6c,0x17,0x60,0xa2,0x1d,0x06, 0x0f,0x3c,0x78,0x7e,0x03,0x83,0xc3,0x03,0x1f,0x3c,0xf7,0xfe,0xdb,0xfb,0xee, 0xff,0x7f,0xe6,0xdf,0xf7,0xf6,0x76,0xcb,0xbe,0xbd,0x02,0x00,0x00,0xf5,0x7b, 0x33,0xb5,0x5e,0xeb,0x57,0x97,0xdf,0xb5,0x7f,0xff,0xb5,0x5f,0xe3,0xc0,0x1f, 0x1c,0x83,0xc1,0xe0,0x38,0x18,0xe6,0xc0,0x61,0x3c,0x10,0x18,0x0c,0xf3,0x70, 0x30,0x0c,0x24,0x1e,0x1e,0x08,0x1e,0x46,0x8f,0xf1,0x03,0x86,0x04,0xa7,0xdd, 0xb6,0xfe,0xba,0xaf,0x7f,0x67,0xf7,0xdf,0xbf,0xdb,0xdb,0x7f,0xbe,0x00,0x00, 0x00,0xdd,0xfc,0xaa,0x2e,0xff,0xfa,0xff,0x27,0x7f,0x7b,0xb3,0x77,0x7b,0xdb, 0x67,0x10,0x06,0x00,0x49,0xba,0x2a,0x08,0x25,0x80,0x00,0x84,0x2c,0x64,0x00, 0x50,0x57,0xbf,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xe7,0xfe,0xea,0xff,0xb3,0xff,0x6f,0xd7,0xfa,0xb5,0xf6,0xeb,0x9a,0x9f, 0xb6,0x20,0x00,0x00,0xbd,0x79,0x3b,0xb6,0xde,0xde,0xdb,0x35,0xef,0xf6,0x5d, 0xf7,0xdb,0x7e,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff,0xbf,0x47,0x6d,0xff,0xba, 0xff,0xdb,0x97,0xbe,0x08,0x00,0x00,0xcd,0xf6,0xb6,0xae,0xad,0xf7,0x76,0x35, 0xfe,0xff,0xff,0xff,0xff,0xff,0xa7,0x56,0x7b,0x55,0x92,0x52,0x40,0x22,0x01, 0x08,0xa4,0x54,0x4a,0x01,0x12,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0xe7, 0xd6,0xef,0xe7,0x91,0x35,0x57,0xbe,0x00,0x00,0x00,0xfd,0xe6,0x3c,0xf7,0x5a, 0xfc,0xcf,0x32,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x10,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01, 0x00,0x00,0x42,0x04,0xb5,0xd2,0xaa,0xfa,0xef,0xff,0xf7,0xf7,0xbd,0x55,0xdd, 0xb6,0xad,0xc7,0xf3,0xfe,0xfe,0xe3,0x9d,0x6b,0xbe,0x00,0x00,0x40,0xdd,0xde, 0x77,0x8e,0xc5,0x7f,0xaf,0x5f,0xf2,0xff,0xff,0xff,0xff,0xbf,0xed,0x75,0xab, 0xd6,0x5a,0x55,0x8b,0x54,0x55,0xa9,0xab,0xaa,0xaa,0xaa,0x00,0x02,0x08,0x80, 0x10,0x10,0x00,0x84,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xa2,0xd3,0xfd,0x4b,0x49,0x40,0x77,0x7f,0xbe,0x02,0x00, 0x00,0xfd,0xd6,0xbd,0x81,0xb6,0xfd,0xaf,0x3b,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x20,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x92,0xe7,0x74,0x01,0x00,0x04,0x00,0x20, 0xbe,0x00,0x00,0x08,0xed,0xaa,0x7d,0x48,0x1d,0xee,0x6f,0x7e,0x36,0x40,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x41,0x20,0x84,0x00,0x02,0x00,0x00,0x08,0x10,0x00,0x20, 0x42,0x02,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x55,0xf7,0xa7,0xad, 0xfe,0x6d,0x79,0xbf,0x40,0x00,0x00,0xfd,0x96,0x3d,0x82,0xeb,0xba,0x7f,0x2b, 0x15,0x02,0x21,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x24,0x22,0x00, 0x00,0x00,0x00,0x28,0x00,0x42,0x00,0x00,0x02,0x00,0x00,0x00,0x11,0x00,0x00, 0x00,0x44,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x00,0x21,0xb0,0x67, 0xa7,0xe7,0xff,0xf7,0xff,0x1b,0xbf,0x00,0x00,0x00,0xed,0xb4,0x0d,0xfc,0x14, 0xf4,0xed,0x7c,0x82,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80,0x80,0x24, 0x00,0x00,0x04,0x01,0x00,0x20,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00, 0x00,0x02,0x00,0x08,0x00,0x02,0x80,0x10,0x80,0x40,0x04,0x11,0x20,0x40,0x10, 0x08,0xa9,0xad,0xe5,0xb7,0xff,0x7b,0xff,0x5a,0xb3,0x08,0x00,0x00,0xdd,0x2a, 0x01,0x7f,0xff,0xe9,0xef,0xb8,0x0a,0x00,0x00,0x20,0x00,0x00,0x04,0x00,0x08, 0x20,0x08,0x80,0x08,0x00,0x40,0x00,0x40,0x00,0x00,0x09,0x01,0x20,0x00,0x00, 0x10,0x00,0x00,0xc0,0x40,0x42,0x02,0x0a,0xa8,0x60,0xeb,0x7f,0x5a,0x1b,0xd5, 0xa1,0x0a,0x0c,0x00,0xa5,0xaf,0x53,0xb3,0xde,0xfa,0x57,0xdb,0xbf,0x00,0x00, 0x20,0xfd,0x4a,0x93,0x6f,0xf7,0xc9,0xaf,0x78,0x03,0x40,0x24,0x8a,0x02,0x40, 0x01,0x25,0x21,0x15,0xa5,0x02,0x52,0x49,0x05,0xad,0x00,0x80,0x11,0x52,0x42, 0x41,0xb5,0xfd,0x17,0xbd,0x07,0x10,0x45,0x95,0x00,0x10,0x00,0x49,0x55,0xd1, 0xea,0x4a,0xfd,0xc8,0x16,0x28,0x00,0xda,0x7d,0xe5,0x52,0xff,0xb3,0x7f,0xd2, 0xbb,0x00,0x00,0x08,0xad,0x1a,0xc8,0xdb,0xef,0x87,0xaf,0xb8,0x2e,0xf8,0xff, 0x3f,0x3f,0x3f,0x17,0xf0,0x79,0x5e,0xcf,0xf7,0xff,0xbc,0x9e,0xdf,0x04,0x68, 0xfe,0xff,0x87,0xe1,0xef,0x78,0x5c,0x8c,0x0b,0x34,0x16,0x8e,0x0b,0x5c,0xf6, 0xf2,0xc0,0xe1,0xf2,0x78,0x79,0x74,0x5c,0x5c,0x00,0xe5,0xff,0xe2,0x79,0xdf, 0xcc,0xb7,0xe7,0xbf,0x00,0x00,0x00,0xfd,0x65,0xe4,0x7f,0xfe,0x1e,0xaf,0x7d, 0x0b,0x78,0x67,0x3c,0x1e,0x3e,0x07,0xf8,0x60,0xbe,0x86,0xf7,0xef,0x38,0x5c, 0x1e,0x0b,0x70,0x9c,0xbb,0xc7,0xe5,0xde,0x71,0x9c,0x07,0x03,0x3d,0xae,0x8e, 0x43,0x98,0xf8,0xe5,0xd9,0xe9,0xf4,0x78,0x7a,0x7a,0x4a,0x1c,0x00,0x6d,0x3f, 0x13,0x38,0xa9,0xf9,0xad,0x85,0xb6,0x09,0x00,0x00,0x5d,0x69,0x75,0xb3,0xd4, 0x9b,0x0e,0xbb,0x01,0xb8,0xef,0xbc,0x9e,0x9c,0x6e,0xf0,0x29,0x3d,0xa1,0x77, 0xce,0x38,0x1b,0x1e,0x2f,0x3c,0xb1,0x79,0xd3,0x73,0xce,0x70,0x3e,0xe7,0x36, 0x9c,0x5e,0x4f,0x13,0x3e,0xe2,0xe9,0xf4,0xe9,0xf4,0xfe,0x7a,0x3a,0x95,0xbe, 0x41,0xb9,0x5d,0x30,0xdf,0x76,0xb7,0xd7,0x1f,0xf6,0x00,0x00,0x04,0xad,0x12, 0xb2,0x7e,0xbe,0x39,0xae,0x71,0x08,0x10,0xe7,0x3e,0x9e,0x9c,0xa6,0xf0,0x34, 0x7d,0x94,0x33,0xcf,0x38,0x5c,0x9f,0x4f,0x78,0xbd,0x39,0xd6,0x63,0x9e,0x79, 0x18,0x4f,0x27,0x1d,0x9f,0x8e,0x12,0x3e,0xf1,0xe9,0xec,0xd9,0xfc,0x7c,0x3a, 0x3e,0xcb,0x3d,0x02,0x7a,0x5b,0xa5,0xff,0xfc,0x08,0x4e,0x7f,0xbf,0x00,0x00, 0x00,0xbd,0x37,0xb9,0xda,0x5e,0xea,0x4c,0x73,0x05,0x99,0x67,0xbc,0x9f,0x9e, 0x26,0xf0,0x8c,0xfa,0xb0,0x37,0xcf,0x3c,0x8b,0x1e,0xcf,0xfc,0x85,0x78,0xd7, 0x73,0x4f,0x71,0x0a,0xff,0x10,0x9e,0x3f,0x4e,0x33,0x39,0xd3,0xe3,0xc5,0x59, 0xf8,0x7a,0x7e,0x3d,0x41,0x78,0x02,0xe6,0xbe,0xe2,0xb7,0x70,0xa5,0xe6,0xbb, 0xb7,0x00,0x00,0x00,0xdd,0x2d,0x3d,0xb7,0xfa,0x79,0xcd,0xb3,0x28,0x54,0x6f, 0x3e,0x9e,0xdc,0x6a,0xf0,0x2e,0xf1,0xd0,0x27,0xcf,0x3c,0x4b,0x9f,0x8f,0xf8, 0x9f,0x3c,0xa5,0x27,0xdf,0x78,0x83,0xff,0x33,0x3e,0x9f,0x7e,0x10,0x78,0xd2, 0xeb,0xec,0x1f,0xfb,0x3e,0x79,0x7c,0xd3,0x78,0x06,0x6a,0x5d,0x62,0xfa,0x6c, 0x00,0xb6,0x97,0xbf,0x00,0x00,0x00,0xbd,0x9b,0x5c,0x7a,0x5f,0xf6,0x5a,0x33, 0x0d,0x40,0x47,0xbc,0x9e,0xdc,0x24,0xf0,0x84,0xe2,0x93,0x93,0x9e,0xb8,0x53, 0x1f,0x5f,0xf0,0xff,0x7a,0x05,0xa7,0x8e,0x74,0xd3,0xfe,0x17,0x9f,0x3e,0x6f, 0xae,0xf1,0x8d,0xe7,0xc4,0xd9,0xf4,0x9c,0x7d,0x3d,0xb5,0x7c,0x04,0xec,0x59, 0x73,0x9f,0x39,0x00,0xd7,0x9d,0xbd,0x10,0x00,0x08,0xad,0x4e,0xbe,0x1d,0x50, 0xdd,0xb1,0x5b,0x06,0xa0,0x2f,0x3f,0x9e,0x9c,0x28,0xf0,0x24,0xdb,0xb3,0x77, 0x4f,0x3a,0x21,0x9e,0xcf,0x88,0x3f,0x3a,0x89,0xaf,0xce,0x75,0x3a,0xa0,0x07, 0x9e,0x9e,0x4e,0x81,0xfa,0x94,0xf7,0xec,0x89,0xf0,0x78,0x38,0x3e,0x19,0xf0, 0x04,0x54,0x57,0x33,0xfd,0x06,0x00,0xeb,0xaf,0xbb,0x04,0x00,0x00,0xfd,0x4f, 0xce,0xd5,0xcb,0xfa,0x35,0x13,0x0d,0x81,0x47,0x3c,0x9f,0x3c,0x0c,0xf2,0x24, 0xe1,0xd3,0xa7,0xce,0x3c,0x14,0x9e,0x8e,0x04,0x3c,0x79,0x52,0x2f,0x0f,0x79, 0x00,0x82,0x27,0x3d,0x9f,0x4e,0x86,0xf0,0xcc,0xe7,0xcd,0xc9,0xf2,0x7a,0x7b, 0x39,0x91,0xe1,0x09,0x95,0xa7,0xb6,0xfb,0x11,0x10,0x6e,0x47,0xbf,0x00,0x00, 0x00,0x5d,0xa3,0xdf,0x09,0xc0,0xad,0x77,0xab,0x06,0x88,0x67,0xbe,0x9e,0x9e, 0x4e,0xf0,0x8d,0x92,0xab,0x17,0x4f,0x38,0x39,0x1f,0x4f,0xd8,0x3a,0x3d,0x0d, 0x5e,0xde,0x70,0xba,0x79,0x66,0x9e,0x9e,0xce,0xc3,0xe4,0x99,0xf3,0xc4,0xfb, 0xf4,0x7a,0x7e,0x7a,0xc6,0xfc,0x09,0xd8,0x6a,0xbd,0x5e,0x0f,0x01,0xdf,0x65, 0xbf,0x00,0x00,0x00,0xfd,0x27,0xd7,0x06,0xd0,0xf7,0xeb,0x0a,0x2a,0x85,0x27, 0xbc,0x1e,0xbd,0x4e,0xf0,0x24,0xb3,0xd3,0x13,0xcf,0x3c,0x9f,0x9e,0xcf,0x98, 0x32,0x7b,0xca,0x9e,0x9e,0x75,0x1e,0x53,0x47,0x3c,0x8f,0x8e,0xa2,0xee,0x91, 0xea,0xd5,0xe9,0xf8,0x7c,0x79,0x76,0xca,0xf0,0x09,0x30,0x75,0x9b,0xfa,0x1e, 0x80,0xb6,0x57,0xbb,0x00,0x00,0x00,0xbd,0x65,0xfb,0x09,0xd0,0x5d,0xf7,0x62, 0x07,0xa0,0x6f,0x3d,0x9f,0x1e,0x4f,0xe0,0x09,0x47,0xd3,0xb7,0x9f,0xba,0x3c, 0x1e,0xa3,0x38,0x3b,0x7d,0x1a,0x9d,0x1f,0x79,0xbe,0xcf,0x31,0x34,0xe7,0x7f, 0xf8,0xf5,0x7b,0xf9,0xfa,0xab,0x74,0xf5,0xac,0xec,0xb1,0x96,0x32,0x60,0xaf, 0xed,0x54,0xbf,0x00,0xdf,0xd2,0xbf,0x12,0x00,0x00,0xed,0x96,0x6b,0x82,0xc0, 0xb7,0x4e,0xa2,0x85,0xa0,0x1f,0xff,0xbf,0xbf,0x8f,0xd0,0x8b,0x1f,0xe6,0xaf, 0xbf,0x7e,0x9f,0xdf,0x51,0xfc,0x8c,0xfd,0x5e,0x7f,0x7f,0xfd,0x1a,0xbf,0x28, 0xa4,0x21,0x84,0x00,0x09,0x80,0x01,0x00,0x00,0x00,0x04,0x00,0x12,0x00,0x00, 0x10,0x61,0x9a,0x7d,0xb6,0x2d,0x10,0x77,0x99,0xbb,0x00,0x00,0x08,0xad,0x93, 0xd6,0x24,0xd8,0xfd,0xf5,0xd5,0x25,0x20,0x40,0x00,0x00,0x00,0x40,0x00,0x60, 0x40,0x10,0x00,0x00,0x02,0x80,0x00,0x2c,0x00,0x20,0x02,0x80,0x00,0x00,0x02, 0x00,0x01,0x14,0x10,0xd0,0x28,0x61,0x50,0x55,0xbe,0xaf,0xba,0xae,0x95,0xb6, 0x4d,0x7e,0x6b,0x37,0x40,0x6a,0x9f,0xed,0xbd,0x00,0xbf,0xeb,0xb7,0x00,0x00, 0x00,0xfd,0x92,0xfd,0x01,0xe0,0x1f,0x6d,0x97,0x05,0x44,0xa5,0x2a,0xa0,0xaa, 0x52,0xc0,0xa0,0x52,0xb4,0x52,0x4a,0x69,0x55,0x15,0x29,0x20,0x68,0x00,0x84, 0x24,0xa9,0x55,0xf7,0x4a,0x0b,0x90,0x2c,0x57,0x81,0x47,0x55,0x61,0x55,0xeb, 0x52,0xeb,0xda,0xa6,0x45,0xad,0xea,0x80,0x59,0x8c,0x6a,0x37,0x00,0xfb,0x7b, 0xbe,0x10,0x00,0x00,0xfd,0xa9,0xb3,0x0f,0xd0,0xab,0xdd,0xe9,0x0a,0x00,0x5b, 0xd5,0xaf,0x5a,0xad,0x00,0x5d,0xac,0x28,0x6d,0xb4,0x52,0x55,0x55,0x0b,0xc0, 0x17,0xf8,0xb5,0xea,0x6a,0x53,0x4d,0xb9,0x02,0x40,0x05,0x54,0x02,0x95,0xaa, 0x4a,0xad,0x2a,0x45,0x15,0xa5,0x0a,0x02,0x83,0x04,0x08,0xff,0x4d,0xb1,0x9f, 0x00,0x5e,0x41,0xbd,0x00,0x00,0x00,0xad,0xd9,0xcf,0x06,0xf2,0x53,0xee,0x6d, 0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8, 0x4e,0x6a,0x3d,0x88,0xab,0x35,0xb6,0x00,0x00,0x00,0x7d,0xa9,0xbd,0x13,0xc0, 0x09,0xd3,0x7a,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x00, 0x10,0x05,0x78,0x35,0x6d,0xb7,0x00,0x1e,0x2d,0xb7,0x08,0x00,0x00,0x9d,0xa9, 0x3f,0x06,0xd0,0x7c,0xa2,0x6b,0x10,0x90,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x20, 0x08,0x00,0x00,0x00,0x80,0x42,0x00,0x00,0x00,0x20,0x00,0x00,0x80,0x00,0x00, 0x00,0x00,0x20,0x00,0x18,0x62,0xfd,0xf2,0xb0,0x80,0xe2,0xc9,0xbb,0x00,0x00, 0x20,0xdd,0xa8,0xb6,0x15,0xf2,0x1d,0xf2,0xbe,0x82,0x00,0x20,0x00,0x00,0x00, 0x00,0x80,0x00,0x00,0x02,0x00,0x04,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x10,0x00,0x02,0x02,0x80,0x10,0x08,0x00,0x00,0x11,0x00,0x04,0x41,0x00, 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x90,0xc8,0xec,0xf5,0x35,0x20,0xf7,0xe9, 0xbd,0x00,0x00,0x04,0xbd,0xa9,0xaf,0x85,0xc0,0x35,0xd4,0x54,0x28,0x80,0x00, 0x10,0x11,0x01,0x04,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x09,0x00,0x00,0x00, 0x00,0x04,0x00,0x00,0x00,0x10,0x40,0x20,0x22,0x80,0x00,0x00,0x40,0x00,0x21, 0x01,0x00,0x00,0x08,0x20,0x04,0x88,0x08,0x02,0x00,0xbc,0xe5,0x1f,0xf1,0xbd, 0x08,0x6b,0xe9,0xbf,0x22,0x00,0x00,0xdc,0x98,0xb7,0x17,0xd8,0x7d,0xae,0xad, 0x02,0x20,0x00,0x04,0x00,0x20,0x01,0x10,0x00,0x00,0x00,0x24,0x00,0x49,0x00, 0x00,0x00,0x22,0x04,0x80,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x40, 0x10,0x00,0x00,0x00,0x20,0x84,0x80,0x00,0x80,0x00,0x00,0x20,0x04,0x64,0x92, 0x1d,0x65,0x2d,0x00,0xde,0x65,0xb5,0x00,0x00,0x00,0xdd,0x28,0xfb,0x07,0xc0, 0xfb,0x6c,0x23,0x5a,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x00, 0x10,0x00,0x00,0x10,0x20,0x00,0x20,0x02,0x10,0x00,0x40,0x80,0x08,0x00,0x00, 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x40,0xb8,0xa7,0xdb,0xf3,0xb6,0x80,0x66,0xf1,0xbb,0x08,0x00,0x00,0x7d,0x4c, 0x5f,0x17,0xd0,0x5b,0xe4,0x00,0x20,0x01,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x20,0x02,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00, 0x00,0x44,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x10, 0x00,0x00,0x00,0x00,0x68,0x55,0xda,0xe3,0x1e,0x00,0xdf,0xf5,0xbd,0x00,0x00, 0x00,0x9d,0x58,0xf7,0x82,0xd0,0x9f,0x2d,0x9f,0x97,0x06,0x00,0x00,0x38,0x15, 0x62,0x1f,0x9f,0xfc,0x8a,0xcb,0xbe,0x87,0x20,0x00,0x00,0x00,0x00,0x40,0x00, 0x00,0x00,0x10,0x90,0x00,0x22,0x0a,0x09,0x92,0x10,0x84,0x20,0x00,0x80,0x10, 0x00,0x04,0x00,0x20,0x82,0x08,0x00,0xc0,0x75,0xeb,0x62,0xbd,0x00,0x5a,0x75, 0xb7,0x02,0x00,0x00,0xed,0xc8,0x94,0x15,0xe4,0x55,0xc9,0x3c,0x10,0x8c,0x00, 0x00,0x90,0x35,0x0e,0x09,0x8d,0xd4,0x0b,0xe9,0xaa,0x23,0x00,0xa0,0x2a,0xad, 0x57,0x09,0x8a,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, 0x00,0x24,0x04,0x44,0x00,0x00,0x08,0x20,0x00,0x02,0x00,0xde,0xae,0xe7,0x3a, 0x88,0xd7,0x9b,0xbf,0x10,0x00,0x00,0x7d,0xd8,0x2c,0x04,0xd0,0x58,0xab,0x77, 0xa0,0x0c,0x00,0x00,0x41,0x00,0x26,0x2b,0x89,0x71,0x0d,0x81,0x9a,0x13,0x00, 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x48,0xa5,0xa2,0x4a,0x45,0x00, 0x84,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x20,0x70, 0xcd,0x62,0xad,0x00,0x4b,0xb5,0xbb,0x0a,0x00,0x00,0x9d,0xa8,0xb1,0x07,0xe0, 0xbb,0xca,0x99,0xd2,0x11,0x04,0x10,0x00,0x14,0x00,0x10,0x00,0x00,0x40,0x00, 0x00,0x00,0x01,0x40,0xc7,0x9f,0x7c,0xef,0x87,0xff,0xff,0xe3,0x97,0xbd,0xfc, 0xe5,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x40, 0x00,0x42,0xa0,0xff,0xe3,0x1d,0x00,0xb6,0x5b,0xbd,0x00,0x00,0x00,0x6c,0x1c, 0xdb,0x15,0xd1,0xbb,0xd1,0xf6,0x85,0x3b,0x00,0x01,0x00,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x33,0x1f,0x34,0xeb,0xf1,0xff,0xff,0x8f, 0x77,0x5d,0xfd,0xd0,0x05,0x00,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x01,0x80, 0x00,0x00,0x02,0x40,0x80,0x6a,0xbb,0x73,0xb6,0x90,0xae,0xf3,0xbf,0x00,0x00, 0x00,0xfd,0x88,0xea,0x07,0xd0,0xfb,0xe9,0xa9,0xa2,0x6e,0x00,0x10,0x11,0x01, 0x08,0x25,0x00,0x02,0x42,0x10,0x2a,0x09,0x0c,0x40,0xfd,0xe0,0xb7,0x7f,0xfe, 0xff,0xff,0x7f,0xfc,0xcb,0x27,0xbf,0x04,0x80,0x10,0x04,0x20,0x00,0x08,0x00, 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xd6,0xee,0xf3,0x3d,0x00,0xab,0x93, 0xbf,0x00,0x00,0x00,0x6d,0x58,0xd8,0x05,0xc4,0xdd,0xab,0xe2,0x4f,0x7f,0x02, 0xb7,0xa5,0xc4,0xed,0x37,0x3e,0xd6,0x67,0x72,0x6c,0xab,0x0f,0x49,0xeb,0xe5, 0xd7,0x1b,0xff,0xff,0xff,0xff,0xd1,0xeb,0xcf,0xbf,0x05,0x00,0x00,0x00,0x04, 0x00,0x80,0x10,0x10,0x00,0x00,0x08,0x08,0x00,0x00,0x00,0xb8,0x5d,0x73,0x97, 0x00,0xde,0x73,0xb5,0x02,0x00,0x40,0x6d,0x32,0x7f,0x97,0xd0,0x7b,0xeb,0xcd, 0xf2,0x5a,0x00,0x8e,0x61,0xc4,0xed,0x32,0x9e,0x52,0xa1,0x56,0x7c,0x2d,0x0d, 0x00,0x3f,0xeb,0xf9,0xe7,0xff,0xff,0xff,0xff,0x47,0xdf,0xaa,0xee,0x02,0x00, 0x44,0x80,0x00,0x40,0x20,0x00,0x02,0x20,0x00,0x80,0x00,0x20,0x00,0x00,0x42, 0xb7,0xf9,0xbe,0x90,0xee,0xf3,0xbf,0x20,0x00,0x10,0x7c,0x30,0xbe,0x07,0xd2, 0xff,0xd3,0xc2,0xc7,0xf5,0x20,0xab,0x71,0x44,0xa5,0x02,0x24,0x96,0x65,0x54, 0x42,0x65,0x05,0x40,0xc3,0xee,0xf7,0xe2,0xff,0x7f,0xf5,0xff,0x9f,0xb5,0xab, 0x83,0x01,0x09,0x00,0x20,0x00,0x08,0x04,0x10,0x40,0x02,0x00,0x00,0x40,0x08, 0x00,0x10,0xa0,0xfb,0xd9,0x2a,0x04,0xf7,0xa2,0xbd,0x08,0x00,0x00,0xfd,0x5a, 0xbc,0x04,0xf0,0xda,0xeb,0x94,0x0d,0x68,0x00,0x22,0x08,0xca,0x64,0xb2,0x66, 0x52,0x82,0x14,0x40,0x14,0x04,0x00,0x3c,0x6b,0xbd,0xfc,0xff,0x02,0x80,0xff, 0x3f,0xbe,0xcd,0x3c,0x02,0x80,0x40,0x08,0x00,0x02,0x00,0x00,0x00,0x80,0x88, 0x00,0x08,0x00,0x08,0x00,0xb4,0xee,0xf9,0xb6,0xa0,0xea,0xe7,0xb7,0x02,0x00, 0x00,0xcd,0x30,0xbd,0x17,0xd1,0x2c,0xaa,0xe5,0x27,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x43,0x77,0x3d,0xff,0x0b, 0x0a,0x21,0xfc,0xff,0x68,0xef,0x80,0x00,0x00,0x10,0x00,0x80,0x80,0x00,0x08, 0x42,0x08,0x00,0x08,0x00,0x01,0x00,0x01,0x51,0xfb,0xf9,0xb1,0x00,0xd6,0xe7, 0xbe,0x00,0x00,0x00,0xfd,0x68,0xcc,0x06,0xd0,0xfd,0xeb,0x8c,0x0d,0x00,0x08, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x40,0x80,0xb6, 0x16,0xff,0xf5,0x00,0x00,0xf1,0xff,0xf1,0x7a,0x02,0x20,0x00,0x00,0x08,0x20, 0x02,0x00,0x20,0x10,0x00,0x01,0x05,0x00,0x28,0x40,0x10,0x8c,0xb5,0x59,0x39, 0x90,0x66,0xe5,0xbb,0x00,0x00,0x00,0xad,0xd8,0xbe,0x13,0xd0,0xe7,0xdb,0xe4, 0x06,0x12,0x00,0x00,0x09,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00, 0x88,0x01,0x7a,0xc7,0x7f,0x83,0x90,0x44,0x82,0xff,0xcf,0x6f,0xc3,0x03,0x00, 0x00,0xfa,0x80,0x8f,0x3e,0x3e,0xe4,0xd1,0xc7,0x9d,0x3e,0x78,0xc1,0x10,0x60, 0xbd,0x6c,0x36,0x82,0xbe,0xcf,0xb5,0x40,0x00,0x04,0xed,0xe8,0xf6,0x07,0xe2, 0x4b,0xd9,0xb4,0x87,0x80,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00, 0x11,0x00,0x10,0x40,0x85,0xd6,0xe3,0xbf,0x14,0x00,0x42,0xc0,0xff,0xcf,0x7c, 0x23,0x06,0x20,0x10,0xa4,0x80,0x19,0x3a,0x20,0x30,0x43,0x84,0x00,0x22,0xca, 0xc0,0x10,0xc5,0xda,0xbc,0x5d,0x00,0x6a,0xdb,0xbb,0x00,0x00,0x20,0x99,0x31, 0x57,0x07,0xd0,0xbb,0xee,0xaa,0x0b,0x00,0x08,0x00,0x00,0x00,0x08,0x40,0x20, 0x42,0x00,0x10,0x00,0x04,0x00,0x60,0x09,0xfa,0xf8,0xbf,0x89,0x42,0x00,0x01, 0xff,0xbf,0x6b,0xd3,0x0a,0x02,0x00,0x09,0x81,0x10,0x03,0x10,0x10,0x22,0x84, 0x00,0x60,0x84,0x40,0x10,0x22,0x2c,0x56,0x47,0xad,0xf8,0x9c,0xbd,0x20,0x00, 0x00,0xfd,0x32,0xff,0x91,0xd0,0x7f,0x56,0xd8,0x0b,0x00,0x00,0x81,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x44,0x02,0xde,0xfd,0x9f,0x02, 0x04,0x48,0x24,0xff,0x3f,0x7f,0x51,0x8d,0x00,0x00,0x88,0x00,0x18,0x23,0xa0, 0x00,0x40,0x86,0x00,0x20,0x48,0xc0,0x18,0x62,0x4a,0xf6,0x03,0x00,0xd0,0x9b, 0xbf,0x04,0x00,0x00,0xdc,0xf1,0x75,0x0f,0xd0,0x9f,0x7a,0xb5,0x05,0x10,0x41, 0x00,0x40,0x10,0x01,0x08,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x90,0x08,0x7a, 0xfe,0x77,0x5c,0x11,0x02,0x01,0xf8,0x7f,0x4e,0x23,0x0d,0x00,0x08,0xd4,0x10, 0x0e,0x3c,0x30,0x00,0xc3,0x91,0x1f,0x1c,0x7c,0x40,0x4f,0x08,0x6d,0xab,0xfe, 0xff,0xff,0x2a,0xb7,0x00,0x00,0x00,0xfd,0xf1,0xf6,0x03,0xe4,0x66,0x55,0xa0, 0x07,0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x80, 0xa0,0x88,0x6a,0xfe,0x6b,0x05,0x00,0x40,0x00,0xf4,0x7f,0x5c,0x23,0x09,0x00, 0x00,0xf8,0x04,0x16,0x36,0x24,0xc4,0x91,0x86,0x10,0x38,0xd9,0xc0,0x10,0x12, 0x15,0xeb,0xff,0xff,0xbf,0x35,0xbf,0x40,0x00,0x00,0xfd,0xa5,0xaf,0x44,0x01, 0xef,0x39,0x42,0x05,0x02,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02, 0x81,0x00,0x20,0xc0,0x98,0x9e,0xff,0x5a,0x05,0x90,0x10,0x90,0xf0,0xff,0xf9, 0x12,0x06,0x00,0x01,0x84,0x80,0x18,0x23,0x20,0x70,0x60,0x04,0x10,0x60,0x84, 0xc2,0x10,0x81,0xab,0x5f,0xff,0xff,0xff,0x5e,0xbe,0x00,0x00,0x40,0xac,0xe1, 0x6e,0x10,0x80,0xfa,0x3e,0x80,0x03,0x00,0x04,0x00,0x40,0x00,0x00,0x00,0x04, 0x02,0x00,0x40,0x00,0x10,0x00,0x00,0x88,0xda,0xbf,0x55,0x50,0x00,0x04,0x22, 0xc4,0xff,0xb3,0x32,0x00,0x00,0x00,0x08,0x01,0x10,0x41,0x20,0x10,0x64,0x0c, 0x08,0x00,0x84,0x40,0x10,0xd3,0x90,0x7b,0x45,0xa1,0xdd,0x77,0xbe,0x40,0x00, 0x08,0x7d,0xe9,0xdf,0xff,0xff,0xff,0x36,0x80,0x01,0x80,0x00,0x00,0x10,0x00, 0x00,0x04,0x00,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x48,0xcf,0x7f,0xc6,0x0a, 0x14,0x41,0x08,0xc1,0xff,0xe7,0x10,0x00,0x00,0x80,0x88,0x00,0x18,0x23,0x30, 0x12,0x20,0x04,0x18,0x61,0xcc,0xc0,0x10,0x75,0x34,0xdf,0x7e,0x55,0xdd,0x3f, 0xbe,0x04,0x00,0x02,0xdd,0xe2,0xd7,0xff,0xff,0x6f,0x9d,0x10,0x00,0x20,0x00, 0x20,0x00,0x40,0x10,0x40,0x20,0x00,0x24,0x00,0x00,0x00,0x00,0x10,0x48,0xe7, 0xaf,0x35,0x05,0x10,0x88,0x41,0x94,0xff,0xcf,0x34,0x80,0x10,0x00,0x7c,0x80, 0x0f,0x3e,0xae,0xf0,0xc3,0x83,0x07,0x1e,0x38,0xc0,0x10,0x0b,0x40,0xd4,0xf5, 0xfb,0xf7,0x8c,0xbf,0x10,0x00,0x00,0xfa,0xcb,0x3d,0xad,0x7f,0x79,0x0d,0x00, 0x00,0x01,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00, 0x04,0x0c,0xf3,0x9f,0x0a,0x01,0x40,0x20,0x04,0x01,0xff,0xcf,0x14,0x00,0x00, 0x08,0x68,0x80,0x02,0x0c,0xfc,0xd8,0x02,0x41,0x05,0x14,0x40,0x00,0x00,0x05, 0x80,0xc9,0xea,0xde,0xda,0xc0,0xb7,0x00,0x00,0x00,0x9d,0xca,0xaf,0x7e,0xeb, 0xba,0x0f,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xa4,0xf9,0x55,0xa1,0x08,0x0d,0x00,0x00,0x24,0xdf,0x9f, 0x2d,0x20,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11, 0x10,0x40,0x02,0x40,0xa2,0x7a,0xf3,0x67,0xf2,0xbf,0x00,0x00,0x00,0xfc,0x97, 0x37,0x6b,0x6f,0xbd,0x06,0x00,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x42, 0x00,0x00,0x82,0x00,0x04,0x00,0x00,0xa8,0xf9,0x37,0x54,0x10,0x90,0x20,0xa8, 0x00,0xfc,0x1f,0x2b,0x00,0x00,0x00,0x00,0x08,0x80,0x00,0x00,0x00,0x08,0x10, 0x20,0x00,0x00,0x00,0x10,0x90,0x00,0x96,0xea,0xfd,0x57,0x7b,0xbf,0x44,0x00, 0x00,0xad,0x57,0xcf,0x7d,0xfd,0x4c,0x83,0x00,0x42,0x00,0x02,0x40,0x20,0x08, 0x00,0x92,0x00,0x04,0x00,0x20,0x20,0x80,0x00,0x01,0xd6,0xfc,0x6b,0xa9,0x84, 0x04,0x14,0x48,0xa0,0xfc,0x7f,0x4b,0x00,0x00,0x81,0x00,0x00,0x24,0x40,0x00, 0x80,0x40,0x04,0x04,0x04,0x00,0x00,0x00,0x04,0x08,0x88,0xdd,0xbb,0x6d,0xde, 0xb9,0x00,0x00,0x00,0xf9,0x06,0x5b,0x3f,0xef,0xd9,0x0b,0x00,0x00,0x20,0x00, 0x04,0x08,0x02,0x80,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x20,0x00,0xc2,0xfe, 0xa7,0x5c,0x0e,0xaa,0x00,0x15,0x09,0xfc,0x7f,0x53,0x00,0x04,0x20,0x00,0x00, 0x00,0x01,0x80,0x24,0x00,0x00,0x01,0x41,0x02,0x00,0x00,0x00,0x80,0x94,0xf4, 0xf3,0xa7,0x7c,0xbb,0x00,0x00,0x00,0x7c,0x4b,0xcf,0x6d,0xba,0xa9,0x01,0x00, 0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x80,0x80,0x08,0x00,0x00,0x00,0x08, 0x80,0x62,0xfe,0x8d,0xb2,0x20,0x0a,0xa1,0x00,0x50,0xf9,0xff,0xf4,0x08,0x01, 0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x40,0x00,0x80,0x08,0x11,0x00, 0x00,0x92,0xf5,0x6a,0xef,0xfe,0xb7,0x08,0x00,0x40,0xad,0x2f,0xf4,0x7e,0x6f, 0xf5,0x05,0x40,0x00,0x08,0x24,0x00,0x00,0x00,0x40,0x00,0x08,0x10,0x00,0x00, 0x00,0x00,0x00,0x00,0x2b,0xff,0xb7,0xaa,0x14,0x56,0x48,0x55,0x00,0xf2,0xff, 0xac,0x00,0x00,0x00,0x00,0x04,0xdb,0x10,0x00,0x00,0x04,0x40,0xa8,0xc2,0x12, 0x00,0x00,0x02,0x40,0x88,0xdb,0xed,0xb5,0xfe,0xbf,0x00,0x00,0x00,0xdd,0x0d, 0xff,0x5b,0xfb,0xdb,0x00,0x11,0x00,0x02,0x00,0x20,0x40,0x00,0x08,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x01,0x10,0x35,0xff,0x2d,0x65,0x81,0x08,0x11,0x00, 0x95,0xf9,0xfb,0x2d,0x00,0x00,0x04,0x00,0x41,0x5a,0x40,0xa9,0x55,0x55,0x4c, 0x47,0x44,0x04,0x00,0x00,0x10,0x09,0x8a,0x7f,0x5b,0x7f,0xb6,0xbb,0x40,0x00, 0x00,0xae,0x7a,0xb2,0xff,0xde,0x6d,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0x00, 0x02,0x80,0x80,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0xd0,0xff,0xd5,0x9a,0xa7, 0x52,0x02,0x0a,0x28,0x62,0xff,0x4b,0x01,0x80,0x80,0x40,0x00,0x16,0x33,0x24, 0x8c,0x50,0xb3,0x41,0xc4,0x00,0x40,0x80,0x00,0x00,0x30,0xdf,0xea,0x2f,0x6f, 0xae,0x08,0x00,0x08,0xfd,0xdf,0xfa,0x7e,0xff,0x7e,0x08,0x00,0x08,0x00,0x82, 0x04,0x00,0x90,0x00,0x08,0x00,0x00,0x52,0x08,0x91,0x00,0x00,0x84,0xd8,0xff, 0x9a,0xed,0x2a,0x25,0x24,0xd1,0x44,0xf1,0xff,0x53,0x81,0x00,0x00,0x10,0x00, 0x36,0xf4,0xbd,0xb1,0x40,0xb2,0x45,0x56,0x84,0x10,0x08,0x00,0x80,0x74,0xff, 0xfb,0x37,0xfb,0xbf,0x00,0x00,0x00,0xda,0xdf,0xd4,0x5f,0x3f,0x1f,0x02,0x00, 0x00,0x40,0x00,0x00,0x12,0x02,0x60,0x06,0x24,0x40,0x00,0x00,0x00,0x00,0x10, 0x80,0xca,0xff,0xf5,0xab,0x4b,0x4d,0x45,0x00,0x00,0xc2,0xff,0xb3,0x00,0x08, 0x20,0x00,0x00,0x24,0x94,0x06,0xa5,0x66,0xb2,0x9a,0xd4,0x18,0x04,0x20,0x48, 0x12,0x80,0x7c,0xfb,0x9e,0x97,0xbe,0x00,0x00,0x00,0xbd,0xad,0x94,0x7b,0xf5, 0x8d,0x00,0x00,0x00,0x04,0x08,0x00,0x80,0x00,0x61,0x0c,0x01,0x12,0x00,0x00, 0x00,0x00,0x01,0x00,0xca,0x7f,0x7d,0x55,0xbd,0x96,0x10,0x49,0x49,0xd1,0xff, 0xb7,0x20,0x00,0x04,0x04,0x00,0xa4,0xbd,0xb4,0x2c,0x65,0xda,0xde,0x92,0x0a, 0x00,0x00,0x02,0x00,0xd2,0xfc,0xb3,0xcf,0xdf,0xbe,0x44,0x00,0x00,0xfd,0xb7, 0xb3,0x7c,0xbd,0x03,0x00,0x44,0x90,0x00,0x00,0x80,0x00,0x50,0xff,0xff,0x00, 0x00,0x00,0x02,0x00,0x10,0x40,0x42,0xe5,0xff,0x6b,0xbb,0x53,0x2b,0xaa,0x80, 0x90,0xca,0xbb,0x2f,0x03,0x40,0x00,0x01,0x20,0x10,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0xf3,0xf5,0xf3,0x7f,0xbe,0x00,0x00, 0x10,0xaa,0x2a,0x63,0x43,0xde,0x09,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00, 0xdf,0xf2,0x01,0x00,0x84,0x00,0x00,0x00,0x00,0x50,0xf4,0x7f,0xd7,0xea,0x96, 0xcc,0x3e,0x12,0x04,0xc2,0xff,0x0f,0x01,0x00,0x40,0x00,0x00,0x04,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x42,0x00,0x00,0x14,0xc3,0xca,0xfc,0xac, 0xae,0x00,0x00,0x00,0x6d,0x57,0x8f,0xb8,0xf3,0x02,0x40,0x00,0x00,0x88,0x80, 0x00,0x20,0xf8,0xbe,0xff,0x9e,0x42,0x00,0x80,0x44,0x00,0x40,0x80,0xf2,0xff, 0xbd,0xbe,0xaa,0xb3,0xf4,0xa7,0xf9,0x92,0xff,0x4f,0x05,0x08,0x02,0x80,0x00, 0x01,0x00,0x02,0x42,0x82,0x00,0x90,0x80,0x00,0x40,0x00,0x00,0x41,0xd0,0x1e, 0x3f,0xe4,0x77,0xbc,0x24,0x00,0x00,0xbc,0x77,0x14,0x0b,0x5d,0x00,0x04,0x00, 0x00,0x00,0x10,0x00,0x08,0xdc,0x99,0x93,0x1b,0x00,0x00,0x00,0x00,0x80,0x00, 0xa0,0xfb,0x7f,0x6d,0xa9,0x4a,0xaf,0xe6,0x05,0x7e,0xa5,0xff,0xdf,0x02,0x02, 0x10,0x00,0x40,0x00,0x05,0x80,0x00,0x20,0x40,0x00,0x10,0x00,0x01,0x00,0x00, 0x10,0xa0,0xef,0x8c,0xcb,0x5a,0xbe,0x00,0x00,0x00,0xfd,0xea,0xba,0x74,0x9f, 0x88,0x00,0x10,0x49,0x00,0x00,0x42,0x80,0xec,0x9b,0xe3,0x2e,0x10,0x20,0x00, 0x00,0x08,0x10,0x08,0xfb,0xdf,0xde,0x5a,0xe3,0xfa,0xcd,0xab,0xe7,0x87,0xfb, 0x9f,0x82,0x80,0x00,0x02,0x10,0x40,0x88,0xb0,0x1a,0x50,0xbf,0xbf,0x6f,0x1f, 0x00,0x00,0x00,0x00,0xe8,0xbf,0xc0,0x8b,0xbb,0xbc,0x00,0x00,0x10,0xfa,0xad, 0x7e,0xa4,0x30,0x80,0x04,0x04,0x00,0x42,0x00,0x10,0xc0,0xfb,0xff,0xdf,0xda, 0x03,0x02,0x00,0x00,0x00,0x00,0x42,0xfd,0x77,0x69,0x69,0x88,0x55,0x21,0x8f, 0x0b,0xa5,0xff,0x3f,0x06,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x22,0x00,0x22, 0x40,0x80,0x04,0x00,0x80,0x20,0x02,0xf2,0x7f,0xeb,0x1b,0x2f,0xbc,0x04,0x00, 0x00,0xbe,0xf4,0xae,0x0a,0xd2,0x40,0x80,0x00,0x00,0x00,0x44,0x00,0x82,0x6f, 0xbf,0x7a,0xff,0x01,0x00,0x08,0x08,0x00,0x40,0x40,0xfd,0x6f,0x5f,0xcb,0x65, 0xff,0xbf,0x57,0xb7,0x25,0xfe,0x3f,0x05,0x30,0x80,0x20,0x02,0x10,0x20,0x80, 0x04,0x01,0x15,0x34,0x81,0x02,0x00,0x08,0x00,0x00,0x40,0x7d,0xf6,0x95,0x5f, 0xbd,0x40,0x00,0x00,0xf8,0xfe,0xf7,0x43,0xe0,0xc8,0x30,0x00,0x80,0x08,0x00, 0x00,0x90,0x9f,0xc7,0xf4,0xe5,0x21,0x08,0x02,0x00,0x00,0x01,0xc0,0xfc,0xd5, 0xd0,0x28,0xb2,0xcd,0xc7,0x96,0xfd,0x02,0xff,0x3e,0x05,0x00,0x00,0x02,0x00, 0x20,0x80,0x10,0x18,0x90,0x0a,0x50,0x00,0x04,0x08,0x00,0x00,0x00,0x81,0xf2, 0xf9,0x18,0x1b,0xb6,0x00,0x00,0x00,0x3f,0xff,0xb6,0x0e,0xb0,0xc0,0x40,0x00, 0x22,0x00,0x00,0x04,0x80,0xcd,0x9e,0x32,0xaf,0x02,0x00,0x00,0x01,0x02,0x00, 0xa0,0xfc,0x7b,0xd5,0x82,0x45,0x57,0xcd,0x2e,0xbe,0x2b,0xfc,0x7f,0x05,0x00, 0x10,0x08,0x80,0x14,0x04,0x01,0x25,0x00,0x12,0x60,0x01,0x15,0x02,0x00,0x00, 0x51,0x00,0xc5,0x70,0x15,0x9f,0xbe,0x00,0x00,0x00,0xd8,0x7f,0xb3,0xfd,0xda, 0x80,0x31,0x00,0xc0,0x03,0x00,0x00,0xf8,0xf6,0xfc,0x3f,0xdd,0x9d,0x80,0x00, 0x00,0x00,0x00,0x82,0xde,0xa5,0x16,0xd0,0x78,0xe0,0x11,0x9d,0x40,0x42,0xfa, 0x7f,0x08,0x00,0x00,0x00,0x22,0x02,0x80,0x00,0x48,0x66,0x0a,0x90,0x40,0x04, 0x00,0x01,0x78,0x04,0x08,0xd7,0x67,0x59,0x1f,0xbe,0x00,0x00,0x40,0xfa,0x75, 0x72,0xb7,0xbb,0x00,0x01,0x10,0xf0,0x83,0x10,0x00,0xb1,0xfc,0xff,0x7b,0x7d, 0x0f,0x00,0x00,0x48,0x20,0x24,0xa0,0xfe,0xdb,0xf5,0x93,0x83,0x95,0x26,0x1b, 0x69,0xdd,0xfc,0xf7,0x0a,0x10,0x80,0x80,0x00,0x00,0x00,0x22,0x6a,0x56,0x83, 0x60,0x10,0x0a,0x00,0x80,0xf8,0x00,0x40,0x09,0xe9,0x15,0x5f,0xb6,0x10,0x00, 0x00,0xda,0x3f,0xf3,0x7a,0xf8,0x00,0x00,0x04,0x39,0x0e,0x00,0x22,0xf0,0x6f, 0x0b,0xb0,0x27,0x0d,0x04,0x00,0x02,0x00,0x00,0x40,0xff,0x6d,0x05,0xa4,0x75, 0xa2,0x00,0x2a,0x21,0x22,0xba,0xfd,0x1a,0x00,0x20,0x24,0x00,0x0c,0x80,0x04, 0xd4,0xff,0x3f,0x90,0x00,0x00,0x00,0x00,0x8e,0x03,0x04,0x16,0x86,0x3b,0x0e, 0xb6,0x00,0x00,0x08,0x5e,0x27,0x73,0x4d,0xa8,0x08,0x48,0x00,0x00,0x2c,0x80, 0x00,0x38,0xf3,0x01,0x80,0xf3,0x0f,0x01,0x00,0x00,0x08,0x00,0x50,0xff,0xf7, 0x3e,0x79,0xb9,0x23,0x52,0x15,0x44,0xac,0xf4,0xef,0x14,0x01,0x01,0x00,0x00, 0x01,0x40,0x01,0xfc,0x68,0xf9,0x29,0x01,0x84,0x00,0x00,0x02,0x03,0x10,0x04, 0xba,0x9d,0x5e,0xbf,0x00,0x00,0x00,0xf9,0x3d,0x6b,0x10,0xf9,0x00,0x00,0x00, 0x10,0x0c,0x00,0x00,0xfe,0x67,0x00,0x00,0xaf,0x3a,0x40,0x00,0x00,0x00,0x01, 0x70,0xff,0xff,0xf5,0x6e,0xe5,0x54,0x44,0xb5,0xa4,0x2a,0xeb,0x7b,0x15,0x10, 0x00,0x08,0x80,0x0a,0x42,0x80,0x3c,0xff,0xcf,0x61,0x01,0x24,0x20,0x08,0x00, 0x03,0x80,0x94,0xda,0x35,0x16,0xbb,0x44,0x00,0x00,0x1a,0x3b,0xe2,0x5a,0x2e, 0x00,0x00,0x00,0x82,0x07,0x22,0x80,0x9e,0x7f,0x10,0x10,0xfe,0x69,0x00,0x20, 0x01,0x00,0x00,0x68,0x7f,0xff,0x5a,0xbb,0xf5,0x09,0x21,0x54,0x02,0x94,0x77, 0xdf,0x05,0x00,0x00,0x01,0x10,0x04,0x80,0x83,0xf7,0xbd,0x24,0x5f,0x20,0x00, 0x00,0x02,0xc0,0x81,0x00,0x08,0x34,0xbd,0x8e,0xbf,0x00,0x00,0x00,0x7d,0x39, 0xeb,0xb1,0x3d,0x80,0x44,0x90,0xc0,0x27,0x00,0x08,0x9e,0x3f,0x00,0x01,0xfc, 0x7d,0x00,0x02,0x08,0x12,0x10,0xa9,0xdf,0xff,0xef,0x75,0x75,0x57,0x44,0x25, 0xd4,0x5a,0xca,0xf7,0x35,0x00,0x08,0x00,0x80,0x02,0x40,0x8a,0xbb,0xfb,0xfa, 0x5e,0x01,0x08,0x00,0x00,0xf0,0x00,0x48,0x32,0x68,0x3f,0xae,0xbb,0x20,0x00, 0x00,0xfa,0xa0,0x73,0xde,0x0f,0x10,0x00,0x00,0xf0,0x00,0x00,0x01,0xfc,0x1f, 0x7f,0x9e,0xf8,0x17,0x08,0x00,0x00,0x00,0x04,0xa8,0xff,0xfb,0xff,0xdd,0xf5, 0x57,0x84,0x58,0x2a,0xda,0xf6,0xff,0x21,0x00,0x02,0x10,0x01,0x4c,0x44,0xf5, 0xec,0xd4,0xfb,0x5a,0x80,0x08,0x00,0x40,0x3c,0x00,0x00,0xd0,0xa0,0xba,0xd2, 0xbd,0x00,0x00,0x10,0xfd,0x29,0x63,0xad,0x8f,0x00,0x10,0x04,0x30,0x00,0x41, 0x40,0xee,0x1f,0x7c,0x3c,0xe8,0xbb,0x40,0x00,0x00,0x00,0x00,0xa8,0xfd,0xdf, 0xfd,0xfb,0xaa,0xad,0x18,0x95,0x88,0x7a,0xe9,0xfd,0x29,0x88,0x00,0x04,0x80, 0x13,0x40,0x72,0xbf,0x2f,0xdf,0xf6,0x11,0x08,0x08,0x10,0x0c,0x20,0x40,0x70, 0x65,0x3e,0x96,0xb7,0x14,0x00,0x00,0xba,0xed,0x75,0xda,0x00,0x04,0x82,0x00, 0x18,0x20,0x00,0x80,0xbb,0x07,0x38,0x3c,0xf0,0xef,0x00,0x00,0x00,0x00,0x00, 0xa0,0xef,0xef,0xff,0xaf,0x55,0x2b,0x51,0x5a,0xa4,0xfa,0xee,0xff,0x69,0x00, 0x40,0x00,0x10,0x04,0x80,0xb4,0xeb,0xfe,0x75,0x59,0x00,0x00,0x00,0x00,0x06, 0x08,0x08,0x82,0x83,0x35,0xd7,0xbe,0x00,0x00,0x00,0xed,0xd1,0x73,0x7e,0x01, 0x00,0x00,0x00,0x19,0x00,0x00,0x88,0xe7,0x0e,0xbc,0x3c,0x72,0xe6,0x01,0x20, 0x01,0x80,0x80,0x84,0xff,0xfe,0x7e,0xa6,0xf6,0x5b,0x26,0x25,0x88,0x7a,0xe9, 0xf7,0x29,0x20,0x00,0x00,0x41,0x05,0x40,0x9f,0xb6,0x7b,0xc7,0xf5,0x01,0x00, 0x00,0x04,0x06,0x00,0x40,0xa0,0x0e,0xad,0xea,0xb5,0x04,0x00,0x00,0xda,0x8c, 0xf9,0x3c,0x04,0x01,0x04,0x40,0xf8,0x0f,0x04,0x02,0x5d,0x0b,0x78,0xbc,0xc0, 0xb3,0x00,0x04,0x00,0x10,0x10,0x90,0xff,0xff,0xdf,0x9f,0xab,0x5e,0x14,0x5b, 0x52,0xdb,0x7b,0xbf,0x69,0x00,0x00,0x00,0x40,0x11,0x44,0xfd,0xee,0xef,0x3f, 0xbb,0x93,0x00,0x80,0x00,0xfe,0x03,0x01,0x04,0x71,0xbe,0xed,0xb6,0x00,0x00, 0x00,0xbf,0x39,0xb3,0xdf,0x41,0x90,0x40,0x08,0x00,0x89,0x40,0x00,0x76,0x47, 0x3c,0x3c,0xe0,0xbe,0x08,0x01,0x20,0x04,0x04,0x94,0xef,0xad,0xff,0xbf,0xf5, 0x59,0x83,0xff,0xaa,0x7a,0xfb,0xff,0x5b,0x04,0x00,0x08,0x40,0x06,0x41,0x27, 0xfb,0xde,0xfe,0x66,0x02,0x08,0x11,0x00,0x20,0x04,0x08,0x48,0xe0,0x1d,0xfb, 0xbf,0x00,0x00,0x00,0xea,0x28,0xb3,0x6f,0x08,0x00,0x00,0x00,0x40,0x00,0x00, 0x00,0x6e,0x07,0x3c,0x3c,0xe0,0xde,0x40,0x00,0x00,0x00,0x01,0x94,0x7b,0xff, 0xf7,0xaf,0xf7,0xb7,0xa4,0xdd,0x46,0xdd,0xff,0xff,0x5b,0x00,0x42,0x00,0x49, 0x11,0x40,0xf5,0xbf,0x9f,0xdf,0xb7,0x43,0x00,0x00,0x00,0x01,0x00,0x02,0x41, 0xe1,0xbb,0xda,0xbd,0x20,0x00,0x20,0xfa,0x9c,0xeb,0xe3,0x00,0x00,0x00,0x02, 0x02,0x20,0x08,0x80,0xef,0x07,0xf8,0x07,0xa0,0xa2,0x00,0x00,0x00,0x00,0x00, 0xdc,0xff,0xb7,0xfe,0xff,0x6c,0x6d,0x91,0xfe,0xa9,0xba,0xff,0xfd,0x4b,0x10, 0x00,0x40,0x80,0x16,0x40,0xaf,0x0c,0x44,0x84,0xf9,0x8d,0x00,0x00,0x40,0x10, 0x11,0x40,0x10,0xf4,0xba,0x7d,0xbb,0x00,0x00,0x00,0x7e,0x7a,0xff,0x65,0x00, 0x80,0x00,0x40,0x00,0x00,0x00,0xe0,0x67,0x47,0xf8,0x07,0xe0,0xde,0x03,0x01, 0x00,0x22,0x00,0x94,0xdf,0xfd,0xfb,0xff,0xef,0xab,0x26,0xbd,0x89,0xdd,0x7f, 0xdf,0x57,0x81,0x00,0x04,0x40,0x05,0x10,0xcb,0x46,0x37,0x22,0xef,0x0d,0x00, 0x00,0x02,0x00,0x04,0x01,0x83,0x10,0xf7,0xfe,0xb7,0x08,0x00,0x00,0xd9,0x54, 0xd5,0xb0,0x20,0x02,0x10,0x00,0x00,0x04,0x82,0x04,0x7d,0x0f,0x3a,0xbc,0xa8, 0x96,0x10,0x00,0x84,0x00,0x20,0xdd,0x77,0xdf,0xae,0xef,0xd5,0xb5,0x11,0x01, 0x52,0xfe,0xdf,0xff,0x53,0x20,0x10,0x01,0xa0,0x92,0xc0,0x3d,0x47,0xfa,0x05, 0xb6,0xa6,0x90,0x40,0x00,0x00,0x01,0x08,0x1f,0xed,0xb5,0xff,0xbe,0x00,0x00, 0x00,0xfa,0x32,0xbb,0x92,0x04,0x00,0x00,0x02,0x40,0x00,0x20,0x00,0xfd,0x07, 0x38,0x3c,0xe0,0xbe,0x00,0x00,0x01,0x00,0x04,0xdc,0xfd,0xff,0xf7,0xdd,0x55, 0x6f,0x64,0x52,0x88,0xd5,0xfe,0xdb,0x57,0x10,0x00,0x80,0x88,0x14,0xc0,0xcf, 0x93,0xff,0x4f,0xee,0x1e,0x00,0x00,0x00,0x40,0x00,0x00,0x2d,0xa9,0xd7,0x6b, 0xbb,0x00,0x00,0x40,0xfe,0xd4,0x6a,0x19,0x00,0x00,0x02,0x00,0x10,0x80,0x00, 0x00,0x7e,0x07,0x78,0x78,0xe0,0xbe,0x88,0x00,0x00,0x04,0x00,0xea,0xff,0xff, 0xdf,0xbe,0xef,0x5f,0x8a,0x04,0x56,0xfd,0xf7,0xff,0x17,0x00,0x00,0x00,0x20, 0x05,0x80,0xaf,0xc7,0x62,0x30,0xfa,0xab,0x00,0x08,0x00,0x00,0x40,0x00,0xff, 0x70,0x2f,0x8f,0xb5,0x00,0x00,0x04,0xda,0xaa,0x7e,0x9a,0x00,0x00,0x00,0x41, 0x04,0x00,0x00,0x00,0xfc,0x0f,0x3a,0x78,0xc0,0xbf,0x00,0x10,0x00,0x40,0x08, 0xda,0xff,0xb7,0xfd,0xd7,0xfb,0xd4,0x24,0x89,0x28,0xbe,0x7f,0xbd,0xd7,0x00, 0x00,0x04,0x80,0x12,0xc0,0xaa,0x47,0x6e,0x12,0xde,0x1d,0x00,0x00,0x00,0x08, 0x08,0x84,0xac,0x81,0x7b,0x87,0xbf,0x20,0x00,0x00,0xfb,0x6d,0xab,0x7c,0x00, 0x20,0x00,0x10,0x00,0x44,0x08,0x84,0xef,0x0b,0x78,0x78,0xf2,0xf7,0x01,0x00, 0x80,0x00,0x00,0xea,0xbf,0xff,0xef,0xfd,0x56,0x57,0xed,0xff,0x5f,0xfa,0xff, 0xf7,0x06,0x20,0x02,0x81,0x20,0x15,0xc0,0xaa,0xa5,0x35,0xbc,0xde,0xb2,0x88, 0x00,0x20,0x00,0x00,0x00,0x7b,0xf5,0xbf,0xf7,0xbf,0x08,0x00,0x00,0xba,0xb1, 0x3d,0x8d,0x80,0x08,0x00,0x00,0x00,0x00,0x40,0x00,0xfa,0x4f,0x3c,0x7c,0xf0, 0xf7,0x08,0x02,0x00,0x10,0x80,0xea,0xef,0xff,0x7b,0xaf,0xff,0xaf,0x09,0x40, 0x02,0xff,0xdd,0xfe,0x97,0x00,0x40,0x00,0x80,0x14,0x68,0xdf,0x67,0x6d,0x4a, 0x36,0x77,0x00,0x40,0x00,0x02,0x00,0x01,0x71,0xe3,0xea,0x8b,0xb5,0x00,0x00, 0x00,0xfa,0x7b,0x35,0x5e,0x04,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0xde,0x1f, 0x38,0x3c,0xe8,0x73,0x80,0x80,0x00,0x02,0x00,0xea,0xff,0xfd,0xff,0xdf,0xfb, 0x5b,0x13,0x08,0x28,0xdd,0xff,0xd7,0x87,0x10,0x10,0x00,0x90,0x05,0xc2,0xdd, 0x56,0x7d,0x6e,0xfe,0x35,0x00,0x00,0x00,0x40,0x42,0x00,0xe6,0x66,0xf7,0x7e, 0xb7,0x00,0x00,0x00,0xda,0xa7,0xad,0x9f,0x00,0x00,0x04,0x04,0x41,0x00,0x08, 0x00,0xfe,0x39,0x7f,0x0f,0xf0,0x1b,0x00,0x00,0x80,0x00,0x22,0xea,0x7e,0xdf, 0xee,0xb6,0x5e,0xbf,0xd4,0x22,0x49,0xff,0xf7,0xfd,0xa6,0x00,0x02,0x80,0xa4, 0x12,0x40,0xf7,0x6b,0xd9,0x59,0xbe,0x57,0x10,0x04,0x00,0x00,0x10,0x10,0x00, 0x97,0xbd,0xdf,0xbb,0x00,0x00,0x00,0xfa,0x37,0x4b,0xcf,0x40,0x00,0x01,0x00, 0x04,0x48,0x42,0x10,0xbe,0x2e,0xff,0x03,0x3e,0x1f,0x08,0x00,0x04,0x00,0x00, 0xea,0xf7,0xff,0xbb,0xdf,0xf6,0x6d,0x25,0x4b,0x12,0xed,0xbd,0xff,0x87,0x00, 0x00,0x00,0x80,0x14,0x40,0xdf,0xc7,0xbe,0x35,0x36,0xb5,0x04,0x00,0x80,0x08, 0x00,0x00,0x95,0x8b,0x7f,0xff,0xbf,0x20,0x00,0x40,0xfa,0x4e,0x8b,0x5f,0x00, 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0x7b,0x00,0x40,0xee,0x6d,0x00,0x00, 0x00,0x00,0x00,0xea,0xff,0xdf,0xff,0xaf,0xbe,0x5f,0xd5,0xd4,0x44,0xff,0xff, 0xb7,0xa7,0x80,0x00,0x10,0x20,0x93,0x70,0x77,0x03,0x77,0x27,0xfe,0x76,0x80, 0x40,0x20,0x00,0x00,0x02,0x4c,0xbd,0xfe,0x7b,0xbd,0x00,0x00,0x10,0xfe,0xef, 0xcd,0x5b,0x10,0x00,0x00,0x40,0x00,0x02,0x00,0x00,0xfe,0xfb,0x00,0x00,0xc5, 0x7f,0x00,0x20,0x00,0x04,0x04,0xaa,0xbf,0xf7,0x5a,0xbd,0xed,0xfb,0x2a,0xa9, 0x55,0xff,0xee,0xfe,0x87,0x08,0x00,0x00,0x80,0x14,0xc0,0xdb,0x47,0xfb,0x0e, 0xae,0x7d,0x00,0x00,0x08,0x00,0x00,0x00,0x48,0x5d,0xb7,0x95,0xbf,0x00,0x00, 0x00,0xda,0x95,0xf5,0x4c,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x41,0xf8,0xcf, 0x01,0xc0,0xdb,0x0f,0x00,0x01,0x01,0x81,0x00,0xea,0xed,0xfd,0xef,0x6f,0xfb, 0xae,0xa5,0x50,0xb4,0xdf,0xff,0xff,0x87,0x00,0x00,0x00,0x40,0x13,0x48,0xff, 0xc5,0xde,0xbd,0x7e,0x17,0x00,0x00,0x00,0x40,0x20,0x00,0x30,0xf5,0xef,0xea, 0xb2,0x10,0x00,0x00,0xfa,0xbf,0xfd,0xb9,0x00,0x21,0x80,0x00,0x00,0x00,0x21, 0x08,0xf0,0xed,0x07,0x60,0xf9,0x07,0x08,0x00,0x40,0x00,0x40,0xea,0xff,0xbf, 0xba,0x5f,0xdd,0xff,0x4d,0x85,0xca,0xff,0xef,0xdd,0xa7,0x00,0x00,0x04,0x41, 0x15,0xc0,0xdf,0xf3,0xee,0x2b,0xbe,0x17,0x00,0x10,0x00,0x04,0x00,0x48,0xb0, 0x7c,0xbd,0xfd,0xbf,0x00,0x00,0x00,0xfa,0xa9,0x1d,0x4c,0x10,0x00,0x12,0x00, 0x00,0x21,0x00,0x00,0x50,0xfd,0xfe,0xff,0x56,0x0e,0x40,0x10,0x10,0x00,0x00, 0xea,0xff,0xdd,0xef,0x7f,0x6b,0xfb,0x2a,0x5a,0xf2,0xb7,0x7d,0xf7,0x87,0x00, 0x81,0x40,0x50,0x05,0xf0,0xde,0x3e,0x33,0xef,0xf6,0x35,0x02,0x04,0x00,0x00, 0x84,0x00,0x84,0xd5,0xd7,0x03,0xba,0x20,0x00,0x00,0x5a,0x2f,0x6d,0x5a,0x04, 0x00,0x00,0x10,0x40,0x00,0x00,0x80,0xf8,0xf7,0xfa,0xdf,0x9c,0x1d,0x01,0x00, 0x00,0x00,0x01,0x62,0x7b,0xaf,0xbd,0xdf,0xec,0xfe,0x7f,0x45,0xfa,0xfd,0xdf, 0x7f,0x97,0x00,0x20,0x00,0x40,0x11,0x82,0x87,0xcf,0xa8,0xac,0x5f,0x11,0x90, 0x00,0x02,0x10,0x00,0x00,0x40,0xee,0xdf,0xc9,0xbd,0x00,0x00,0x00,0xfe,0xdd, 0x3e,0x58,0x01,0x08,0x00,0x04,0x09,0x00,0x80,0x04,0x6a,0xed,0x78,0xb7,0xbe, 0x43,0x10,0x00,0x01,0x20,0x00,0xca,0xff,0xbf,0xff,0x7f,0xdb,0xbf,0x6e,0x55, 0xbd,0xef,0xff,0xfb,0xa7,0x88,0x00,0x00,0x80,0x96,0xc0,0xba,0xb7,0x6e,0x7b, 0x7b,0x8b,0x08,0x00,0x20,0x01,0x00,0x08,0x90,0xd8,0xee,0x74,0xb7,0x08,0x00, 0x00,0x5a,0x73,0xbc,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x80,0xcf, 0x7b,0xf3,0x7f,0x01,0x00,0x40,0x00,0x00,0x40,0xea,0xff,0xfb,0xbf,0xbd,0x6e, 0xfb,0xfb,0xcb,0xfa,0xba,0xfb,0xde,0x97,0x00,0x00,0x00,0x40,0x11,0xc0,0xf7, 0x3f,0xc9,0xce,0xef,0x1b,0x08,0x80,0x00,0x00,0x41,0x82,0x00,0x61,0x77,0xa5, 0x9a,0x00,0x00,0x00,0xde,0x73,0x2d,0x5d,0x00,0x40,0x00,0x00,0x00,0x48,0x00, 0x40,0x80,0x4f,0x7f,0xd7,0xe6,0x09,0x00,0x10,0x00,0x01,0x10,0xca,0xbf,0xbf, 0xef,0xff,0xbd,0xef,0xdf,0x7e,0xef,0xff,0xaf,0xff,0x86,0x00,0x00,0x10,0x04, 0x56,0xd0,0x7b,0x2d,0xb8,0xe5,0x7e,0x3f,0x00,0x08,0x00,0x04,0x10,0x00,0x44, 0x60,0xbd,0x10,0xa5,0x00,0x00,0x80,0x5a,0x99,0x3e,0x4c,0x00,0x04,0x40,0x20, 0x00,0x01,0x80,0x00,0x80,0xff,0xf5,0x2f,0xd9,0x01,0x00,0x00,0x00,0x20,0x00, 0xda,0xff,0xfb,0xfe,0xff,0xd2,0xbc,0xff,0xfb,0x7e,0xeb,0xfe,0xdb,0x57,0x40, 0x08,0x00,0x00,0x05,0x84,0x4d,0xcf,0xff,0x13,0x53,0x05,0x04,0x02,0x20,0x21, 0x00,0x00,0x00,0xc1,0x52,0x40,0xb9,0x40,0x00,0x00,0xda,0x6f,0x3d,0x5e,0x80, 0x00,0x00,0x04,0x20,0x00,0x00,0x00,0xa0,0xbc,0x75,0x6e,0x2d,0x00,0x00,0x02, 0x20,0x00,0x00,0xd8,0xfb,0xbf,0x5f,0x7f,0xed,0xfb,0xfa,0x3f,0xff,0xbf,0x77, 0x7f,0x13,0x00,0x00,0x00,0x01,0x15,0x40,0xcb,0x6f,0x82,0x12,0x77,0x05,0x8c, 0x00,0x00,0x00,0x02,0x08,0x08,0xf0,0xd7,0x27,0xbc,0x00,0x00,0x00,0xfa,0xdf, 0x96,0x5c,0x20,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0xf8,0xf7,0xa6,0x1b, 0x24,0x40,0x00,0x00,0x08,0x22,0xda,0xff,0xf7,0xff,0xdf,0xab,0xdd,0xdf,0x6f, 0x6f,0xf7,0xff,0xed,0x57,0x00,0x00,0x02,0x40,0x12,0xd0,0xbb,0xde,0xab,0xce, 0xbb,0x0d,0x20,0x00,0x20,0x00,0x00,0x80,0x42,0xe5,0xfc,0xff,0xbf,0x00,0x00, 0x00,0x7a,0xbf,0x0d,0xce,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x42,0x08,0xf8, 0xff,0xfc,0x1f,0x00,0x02,0x00,0x08,0x00,0x00,0x9c,0x7f,0xef,0xee,0xf7,0x77, 0x7f,0xfb,0x1a,0xfb,0xfd,0xed,0xbf,0x53,0x10,0x00,0x00,0x90,0x02,0x82,0xbe, 0x3a,0xa0,0xc1,0xf0,0x0f,0x08,0x00,0x09,0x00,0x00,0x01,0x00,0xe0,0xbb,0xf7, 0xbf,0x00,0x00,0x00,0xba,0x6f,0xab,0x5d,0x00,0x20,0x00,0x01,0x20,0x04,0x04, 0x00,0x00,0x00,0xfb,0xcf,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0xf7,0xbf, 0x7f,0xff,0xab,0xf6,0xb7,0x17,0xff,0xdf,0x7f,0xff,0x5b,0x00,0x00,0x40,0x00, 0x14,0x40,0xc7,0xb7,0xa5,0xfe,0x5e,0x02,0x06,0x00,0x00,0x80,0x10,0x00,0x40, 0x62,0x5e,0xdf,0xaf,0x10,0x00,0x00,0xfa,0x87,0x83,0x5f,0x00,0x00,0x02,0x10, 0x01,0x00,0x00,0x00,0x00,0x00,0xf1,0xcf,0x00,0x00,0x00,0x80,0x00,0x00,0x20, 0x94,0xfd,0xda,0xf7,0xff,0xdf,0xed,0xfe,0x05,0x7f,0xfb,0xde,0xfb,0x53,0x04, 0x22,0x00,0x00,0x09,0x40,0xed,0xef,0xcf,0x37,0xff,0x01,0x09,0x00,0x00,0x02, 0x00,0x40,0x20,0xe5,0xbe,0xbd,0xba,0x00,0x00,0x00,0x5a,0x82,0xa1,0x5e,0x00, 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x61,0x0e,0x00,0x10,0x00,0x00, 0x00,0x01,0x09,0x94,0xbf,0xff,0xdb,0xef,0xd7,0xbf,0xff,0x83,0xff,0xbf,0xf7, 0xff,0x69,0x00,0x00,0x00,0x00,0x02,0x80,0xde,0xde,0x9b,0x9e,0xdb,0x03,0x0d, 0x40,0x40,0x08,0x0f,0x11,0x00,0x70,0xf7,0xab,0xad,0x00,0x00,0x00,0x7a,0xe9, 0x4a,0x4f,0x04,0x00,0x20,0x00,0x84,0x08,0x00,0x11,0x01,0x00,0x20,0x00,0x00, 0x05,0x00,0x00,0x40,0x40,0x00,0x90,0xf7,0xd7,0xfe,0xff,0xaf,0xea,0xb6,0x20, 0xbf,0xed,0xff,0xdf,0x69,0x00,0x00,0x02,0x04,0x08,0x91,0xb0,0x6f,0xfe,0xf3, 0x7f,0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x08,0xa0,0x9b,0xde,0xba,0x00,0x00, 0x00,0xda,0x63,0xe2,0x5f,0x40,0x08,0x01,0x08,0x00,0x02,0x04,0x00,0x20,0x80, 0x04,0x00,0x00,0x00,0x40,0x40,0x08,0x04,0x00,0x90,0xbe,0xff,0xff,0xff,0xbf, 0xff,0x5f,0x04,0xfe,0xff,0xfb,0xf6,0x69,0x00,0x00,0x20,0x00,0x42,0x00,0xb0, 0xbb,0x51,0x7d,0x6b,0x41,0x8e,0x04,0x00,0x89,0x01,0x00,0x40,0xea,0x77,0xb5, 0xbf,0x20,0x00,0x80,0xfa,0xf9,0xff,0x5f,0x00,0x00,0x00,0x40,0x88,0x00,0x40, 0x00,0x00,0x22,0x00,0x10,0x10,0x00,0x11,0x00,0x00,0x00,0x00,0xa0,0xef,0x6d, 0xb5,0xfa,0xff,0x6a,0x17,0xa0,0xee,0x7b,0xff,0xff,0x29,0x00,0x01,0x00,0x80, 0x04,0x40,0xc9,0xfe,0xfa,0xff,0x7b,0x81,0x04,0x00,0x24,0x80,0x40,0x4b,0x01, 0xe0,0xb7,0x6f,0xaf,0x08,0x00,0x00,0xfa,0x62,0xb5,0x4f,0x01,0x41,0x00,0x01, 0x00,0x20,0x00,0x04,0x04,0x00,0x00,0x00,0x02,0x40,0x00,0x10,0x00,0x00,0x00, 0xa9,0xff,0xfb,0xef,0xdf,0xbf,0xbd,0x2d,0x00,0x7b,0xdf,0xdf,0xff,0x21,0x08, 0x00,0x00,0x02,0x20,0x90,0xc0,0xfd,0x46,0xea,0x18,0x81,0x01,0x00,0x00,0x08, 0x51,0xab,0x88,0xf0,0xdf,0xbb,0xbc,0x00,0x00,0x00,0xba,0x2e,0xee,0x5b,0x10, 0x10,0x14,0x10,0x02,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00, 0x00,0x00,0x00,0x28,0x77,0xdf,0xf7,0xff,0x3b,0x56,0x00,0xa1,0xcf,0xfb,0x7b, 0xff,0x25,0x00,0x00,0x04,0x00,0x10,0x20,0xa0,0xd7,0xde,0x3b,0x6f,0x41,0x06, 0x00,0x80,0x00,0x47,0x93,0x00,0x42,0x7f,0xff,0xbf,0x08,0x00,0x00,0xfa,0xd6, 0xfb,0x5d,0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x42,0x00,0x00, 0x00,0x00,0x00,0x00,0x10,0x40,0x68,0xff,0x7f,0xfe,0x6f,0xff,0xbf,0x11,0x80, 0xdf,0xde,0xfe,0xfb,0x14,0x02,0x00,0x01,0x00,0x20,0x14,0xa4,0xae,0x7b,0x3d, 0x1b,0x01,0x20,0x04,0x01,0x00,0x00,0x00,0x00,0xe0,0x7e,0xf7,0xba,0x00,0x00, 0x20,0x3a,0x7f,0xfb,0x4e,0x00,0x00,0x80,0x00,0x08,0x00,0x02,0x40,0x40,0x04, 0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x69,0xff,0xef,0xdb,0xfe,0x3f, 0xa5,0x00,0xe9,0xdf,0xf7,0xef,0xdf,0x16,0x01,0x40,0x40,0x40,0x00,0x03,0xa8, 0xfe,0xaa,0xd2,0x55,0x2a,0x09,0x20,0x00,0x08,0x00,0x00,0x20,0xb8,0xb5,0xbf, 0xb7,0x00,0x00,0x00,0xba,0xf7,0xbf,0x5d,0x00,0x00,0x01,0x00,0x00,0x82,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x40,0x00,0x80,0x52,0x7f,0x77, 0xff,0xff,0xbe,0x2d,0x40,0xd0,0xdd,0x7a,0x7f,0xf7,0x92,0x00,0x10,0x00,0x10, 0x00,0x00,0x00,0xc0,0xff,0x3f,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x04, 0x66,0xc2,0xef,0xbd,0x40,0x00,0x00,0x7a,0xbf,0xdf,0x4e,0x00,0x09,0x00,0x08, 0x01,0x20,0x20,0x10,0x08,0x40,0x04,0x00,0x80,0x00,0x00,0x04,0x04,0x00,0x84, 0x59,0xef,0xdd,0xfb,0xef,0xbf,0x2a,0x2a,0xd4,0xff,0xdf,0xff,0xff,0x9e,0x00, 0x01,0x00,0x04,0x88,0x00,0x01,0x40,0xf6,0x33,0x00,0x00,0x00,0x00,0x20,0x90, 0x40,0x04,0x01,0xce,0xef,0xf6,0xbb,0x00,0x00,0x00,0xba,0xef,0xab,0x7d,0x04, 0x80,0x10,0x40,0xf8,0x00,0x0c,0x10,0x78,0x10,0x41,0x12,0x37,0x34,0x68,0x00, 0x21,0x00,0x80,0x06,0xfe,0xbf,0x7f,0xfd,0xff,0xaa,0x02,0xf0,0x7f,0xf7,0x7b, 0xff,0x58,0x41,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x22,0x00,0x10,0x00,0x00, 0x01,0x04,0x04,0x00,0x02,0x00,0xe5,0xb9,0xff,0xb7,0x10,0x00,0x00,0x7a,0xff, 0xfe,0x82,0x43,0x00,0x80,0x00,0xd0,0x01,0x1e,0x7c,0x58,0xc0,0x01,0x07,0x6f, 0x28,0xd0,0x01,0x21,0x00,0x20,0x8b,0xfe,0xf7,0xfa,0xdf,0xbf,0xaa,0x00,0xe8, 0xbd,0xfc,0xde,0x6b,0x9a,0x01,0x00,0x00,0x00,0x80,0x10,0x10,0x00,0x20,0x00, 0x00,0x00,0x02,0x00,0x00,0x00,0x10,0x80,0x40,0x81,0xff,0x6f,0xbd,0x00,0x00, 0x00,0xba,0xbf,0x1f,0x04,0x08,0x20,0x00,0x00,0x08,0x03,0x21,0x4c,0x20,0x60, 0x86,0x0c,0x01,0xcc,0x98,0x21,0x21,0x00,0x80,0xba,0xfc,0xef,0xef,0xff,0x3f, 0x44,0x00,0x75,0xff,0xcb,0xff,0x7f,0xe9,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x01,0x00,0x04,0x01,0x28,0x27,0xbd,0xbe, 0xb5,0x00,0x00,0x00,0xfa,0xfa,0xaf,0x95,0x30,0x08,0x02,0x08,0x08,0x03,0x23, 0x44,0x40,0x22,0x86,0x08,0x01,0xc4,0x18,0x01,0x21,0x00,0x42,0xac,0xfc,0xbb, 0xff,0xbf,0x7d,0xa8,0x40,0x52,0xbd,0xf2,0xff,0x7f,0xac,0x05,0x00,0x84,0x40, 0x20,0x00,0x00,0x80,0x02,0x00,0x00,0x12,0x00,0x48,0x88,0x10,0x00,0x00,0x04, 0x03,0xed,0xdd,0xbd,0x00,0x00,0x00,0x7a,0x7d,0x91,0x5e,0xc4,0x00,0x08,0x80, 0x18,0x21,0x30,0x4d,0x60,0x00,0x84,0x08,0x01,0xc0,0x88,0x01,0x29,0x10,0xc0, 0xb9,0x7c,0xef,0xf7,0x6f,0x7f,0x01,0x06,0x74,0xbd,0x4e,0xff,0x3f,0xed,0x07, 0x88,0x00,0x10,0x00,0x02,0x00,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00, 0x40,0x80,0x08,0xee,0xb2,0x7b,0xb6,0x00,0x00,0x00,0xfa,0xed,0x6b,0xc7,0x01, 0x00,0x20,0x20,0x90,0x03,0x18,0x54,0x60,0x00,0x86,0x0d,0x1d,0x50,0xf0,0x00, 0x3f,0x04,0x40,0x69,0xfc,0xff,0xbb,0xfa,0xf5,0x22,0x43,0xc8,0x7e,0xdb,0xf4, 0x3f,0xa7,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x40,0x00,0x00, 0x01,0x00,0x08,0x01,0x00,0x2c,0x6b,0xf1,0x56,0x3f,0x20,0x00,0x10,0xfa,0xba, 0xb5,0x1e,0x97,0x82,0x08,0x01,0x78,0x01,0x1c,0x5c,0x60,0xc0,0x81,0x0b,0x23, 0x70,0x98,0x01,0x21,0x00,0x88,0x49,0xfd,0xfd,0xff,0xff,0xfd,0x41,0x2e,0x81, 0xf6,0xae,0x4f,0xaf,0xd6,0x25,0x00,0x20,0x04,0x02,0x20,0x00,0x01,0x00,0x10, 0x10,0x00,0x00,0x00,0x40,0x00,0x20,0x80,0xb0,0xff,0x0d,0x95,0xbf,0x00,0x00, 0x00,0xba,0x53,0xfd,0xe5,0x7f,0x08,0x00,0x00,0x08,0x03,0x20,0xc4,0x60,0x60, 0x40,0x18,0x60,0xc0,0x18,0x09,0x21,0x01,0xc1,0x1b,0x73,0x77,0xe7,0xbb,0xef, 0x57,0x25,0x24,0xf8,0xd5,0xbd,0x9f,0xa2,0x09,0x00,0x08,0x41,0x20,0x08,0x08, 0x00,0x08,0x00,0x00,0x20,0x21,0x10,0x04,0x00,0x24,0x60,0xe7,0x85,0x47,0xbc, 0xba,0x08,0x00,0x00,0xda,0xa6,0x59,0x00,0xfe,0x08,0x05,0x10,0x09,0x03,0x20, 0x86,0x20,0x20,0x80,0x10,0x60,0xc0,0x08,0x03,0x21,0x00,0xd0,0xcb,0xfa,0xdf, 0xfb,0xfe,0xfb,0x23,0x4b,0x08,0xea,0x5d,0xef,0xda,0xea,0x15,0x02,0x00,0x10, 0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x42,0x50,0x10,0xe3, 0x00,0xce,0xa8,0xb7,0x00,0x00,0x00,0xba,0x57,0x37,0xde,0xd0,0x93,0x80,0x00, 0x58,0x43,0x33,0x44,0x60,0x28,0x80,0x08,0x30,0xc6,0xd8,0x41,0x21,0x00,0x40, 0xa7,0xb2,0xff,0xdf,0xf7,0xb7,0x47,0x1e,0x80,0xf5,0xfd,0xbb,0x4f,0x4d,0x35, 0x40,0x08,0x00,0x04,0x00,0x08,0x00,0x00,0x82,0x00,0x04,0x00,0x40,0x20,0x00, 0x02,0x92,0x33,0xfe,0x80,0xdb,0xbd,0x00,0x00,0x00,0xea,0xf5,0x8f,0x55,0xe1, 0x07,0x00,0x00,0xb8,0x81,0x2f,0x7c,0xf8,0xd3,0x87,0x0d,0x1f,0xdc,0x78,0x01, 0x21,0x00,0x50,0x27,0xf4,0xeb,0xfd,0xef,0xff,0xc7,0x0a,0x51,0xee,0xaf,0xfe, 0x0a,0xc1,0x06,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00, 0x08,0x00,0x20,0x28,0xd8,0x0b,0xff,0xf3,0xb3,0x2e,0x00,0x00,0x00,0xfa,0xc3, 0x47,0xed,0xcf,0x67,0x90,0x20,0x20,0x00,0x08,0x10,0x08,0xa0,0x04,0x07,0x05, 0x10,0x00,0x00,0x00,0x20,0xa8,0xf5,0xe5,0xbb,0xfb,0xfb,0xfb,0x9f,0x1a,0xa4, 0xd0,0xbf,0xeb,0xa7,0xd7,0x11,0x00,0x40,0x10,0x41,0x00,0x00,0x02,0x80,0x00, 0x00,0x80,0x00,0x00,0x00,0x08,0x21,0xe0,0xc3,0x13,0xcb,0xe7,0xb5,0x20,0x00, 0x00,0xfa,0x65,0x71,0xab,0x95,0x5e,0x02,0x04,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x22,0xa5,0xcd,0xfe,0x7f,0xbf,0xef, 0x5e,0x2a,0x69,0xda,0x7b,0xbd,0xb3,0xd5,0x04,0x01,0x00,0x04,0x00,0x20,0x80, 0x00,0x10,0x10,0x08,0x00,0x04,0x42,0x90,0x00,0x14,0xe4,0xb3,0xee,0xcd,0xaf, 0xbf,0x00,0x00,0x00,0x7a,0x13,0x91,0x7e,0x29,0x9f,0x20,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0xcb,0xf7, 0xd7,0xef,0xbf,0x8f,0x3a,0x85,0xa2,0xbb,0xdf,0xd3,0xd7,0x4c,0x00,0x08,0x00, 0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x10,0x80,0x00,0x02,0x42,0x02,0x72,0x59, 0x7f,0x3b,0x9d,0x37,0x00,0x00,0x80,0xea,0xf8,0xfc,0x04,0x35,0xba,0x22,0x00, 0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40, 0x6e,0xc2,0xbf,0xfc,0xf5,0xfb,0x2f,0x6a,0xad,0xa9,0xeb,0xf6,0xd3,0x76,0x15, 0x20,0x40,0x80,0x10,0x01,0x02,0x00,0x00,0x00,0x01,0x04,0x00,0x20,0x00,0x00, 0x0c,0xfa,0xdc,0x81,0x3a,0x97,0xb7,0x10,0x00,0x00,0xda,0xf9,0xa4,0x03,0xef, 0x6e,0x01,0x40,0x04,0x08,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x11, 0x04,0x20,0x88,0xd8,0x93,0xf7,0x6b,0xef,0xd7,0x9f,0xad,0x12,0x85,0xf6,0xbd, 0xc9,0xb7,0x02,0x08,0xfa,0xff,0x0e,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00, 0x00,0x91,0x88,0x10,0xbc,0xb8,0x81,0x7d,0xb8,0xba,0x00,0x00,0x00,0xba,0x7c, 0x56,0x80,0xdb,0x6c,0x00,0x15,0x00,0x81,0xe0,0x00,0x01,0x14,0x00,0x08,0x40, 0x10,0x10,0x00,0x80,0x08,0x44,0x7f,0x2e,0xfd,0xff,0xbf,0xff,0x5f,0x35,0x50, 0xa5,0x6e,0xff,0x64,0xd7,0x4b,0x04,0xf8,0xce,0x0e,0x00,0x10,0x00,0x00,0x04, 0x00,0x40,0x00,0x10,0x00,0x00,0x0d,0x7d,0xe6,0x80,0xdb,0x3c,0x33,0x04,0x00, 0x00,0xea,0x5c,0x6e,0x00,0x6f,0x79,0x00,0x00,0x40,0x00,0x18,0x10,0xc0,0x3f, 0x04,0x80,0x88,0x04,0x04,0x00,0x00,0x80,0x82,0xd4,0x2a,0xff,0xdf,0xf7,0xfe, 0xbf,0xa6,0x6a,0xca,0xff,0xb7,0xf4,0xbf,0xaa,0x93,0x68,0x5a,0x28,0x01,0x00, 0x00,0x40,0x00,0x08,0x00,0x12,0x04,0x0a,0x42,0x02,0x6d,0x3d,0x80,0xbf,0x5c, 0xbb,0x00,0x00,0x00,0xba,0x3e,0xfd,0x80,0xfd,0xe8,0x13,0x00,0x02,0x00,0x04, 0x0c,0x30,0x01,0xc0,0x00,0xe0,0x03,0xc1,0x87,0x00,0x80,0x7d,0xfa,0xcd,0xee, 0xf6,0xde,0xef,0xbe,0xde,0x06,0x51,0xcf,0x7e,0xb2,0xca,0x7a,0x04,0x00,0x00, 0x00,0x08,0x00,0x78,0x00,0x00,0x80,0x19,0x00,0x00,0xc1,0x20,0x85,0x3e,0x7b, 0x80,0xb5,0x79,0x3e,0x10,0x00,0x00,0x7a,0x3e,0x7b,0x81,0xdb,0xf9,0x02,0x10, 0x2c,0x00,0x26,0x00,0x90,0x00,0xe0,0x00,0xe0,0x8e,0xc0,0x0d,0x00,0x64,0xab, 0xe2,0xdf,0xfe,0xff,0x7f,0xff,0x7f,0xa9,0xac,0xc8,0xfd,0x7b,0xbb,0xf7,0x4e, 0x05,0x40,0xb3,0x05,0x10,0x80,0x44,0x01,0x00,0x01,0x09,0x60,0x00,0x10,0x48, 0x83,0x2e,0xd7,0x80,0xef,0x69,0xbe,0x00,0x00,0x00,0x7a,0x16,0xb5,0x91,0xb5, 0xda,0x01,0x01,0x7f,0x20,0x90,0x00,0x38,0x11,0x60,0xa0,0x42,0x0a,0x42,0x00, 0x04,0x81,0xfc,0x0f,0x3e,0xdd,0x6d,0xef,0x5f,0xff,0xae,0x22,0x42,0xef,0x3f, 0xf9,0xc6,0x17,0x01,0x40,0x8d,0x41,0x02,0x40,0x02,0x01,0x00,0x41,0x09,0x20, 0x00,0x00,0xe0,0x8b,0x9e,0xbd,0x91,0x7b,0xba,0x36,0x00,0x00,0x00,0x7a,0xbe, 0xf7,0x01,0x77,0x73,0x01,0x80,0xe3,0x08,0xd1,0x20,0x08,0x19,0x25,0xcf,0x30, 0x65,0x67,0x22,0x00,0x20,0xd1,0x95,0x3c,0xf9,0xdf,0xfb,0xfb,0x7b,0x93,0x20, 0xc1,0x5d,0x9f,0xbc,0xa3,0x8d,0x44,0x44,0x97,0x00,0x00,0x00,0x02,0x01,0x00, 0xc5,0x3f,0x00,0x00,0x00,0xe8,0x8f,0x16,0xdb,0x80,0xaf,0xdb,0xbe,0x24,0x00, 0x00,0x5a,0x96,0xda,0x80,0xff,0xb2,0x11,0x80,0xc1,0x80,0xdd,0x28,0x80,0xd4, 0xdf,0x29,0x98,0x3c,0xb8,0xb3,0x41,0x88,0xf6,0x57,0x77,0xf1,0xff,0xff,0xfd, 0xdf,0x5e,0x2b,0xb0,0xfe,0x97,0x5e,0xf8,0xe7,0x93,0x40,0x93,0x20,0x00,0x00, 0x02,0x4d,0x99,0x07,0xcb,0x93,0x8d,0x01,0x31,0x09,0x8e,0xdd,0x81,0xfb,0xf2, 0x3a,0x00,0x00,0x20,0x7a,0x8e,0x5a,0x89,0x55,0xd3,0x81,0x08,0xd0,0x00,0xe7, 0x1b,0x80,0xbc,0x33,0x3c,0x04,0x36,0xe4,0xe9,0x00,0x62,0x2f,0xbf,0xee,0xf2, 0xfd,0xbf,0xff,0x7d,0x2b,0x63,0x60,0xf7,0x4f,0x46,0xbd,0xfa,0x2d,0x00,0x08, 0x08,0x00,0x03,0x46,0x6b,0x4d,0x03,0x4d,0x59,0x4b,0x01,0xa4,0x2a,0x9f,0xb7, 0x80,0x53,0xb3,0xbe,0x04,0x00,0x00,0x7a,0xdb,0xbe,0x21,0xff,0x76,0x05,0x00, 0xe5,0x10,0xc0,0x20,0x08,0x40,0x01,0x00,0x80,0x00,0x00,0x00,0x00,0xe8,0xcd, 0x65,0xfc,0xe4,0x77,0xf7,0x77,0xff,0x5a,0x54,0xa2,0xb6,0x67,0x7f,0x7a,0x0b, 0x77,0x11,0x0c,0x00,0x01,0x20,0x3c,0xd9,0x3b,0x0d,0xc9,0x37,0xb9,0x07,0x48, 0x4a,0x92,0x6c,0x81,0xf5,0xb2,0x3c,0x00,0x00,0x00,0x7a,0xcb,0xdd,0x81,0xed, 0xe7,0x05,0x02,0x3e,0x00,0x60,0x00,0x00,0x90,0x00,0x01,0x00,0x00,0x00,0x00, 0x08,0x11,0xb5,0xde,0xb8,0xc9,0xff,0xff,0xfd,0xff,0xd5,0x90,0xb0,0xba,0x93, 0xdb,0x8d,0xbf,0x42,0x02,0x1e,0x42,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x40,0x65,0x4f,0x9f,0xbf,0x91,0x7f,0xd7,0xbd,0x00,0x00,0x80,0x7a,0x5d, 0x6f,0x21,0xe7,0x66,0x83,0x00,0x0f,0x02,0x40,0x80,0x20,0xd2,0x00,0x00,0x00, 0x00,0x00,0x20,0x00,0xae,0xae,0xd3,0xf3,0x9b,0xd7,0xef,0xbf,0xff,0x1f,0x2c, 0x2d,0xdd,0x99,0x7f,0x57,0x4a,0xac,0x41,0x14,0x08,0x10,0x00,0x00,0x20,0x00, 0x00,0x10,0x00,0x00,0x00,0xe8,0x47,0xd3,0x6d,0x81,0xf7,0x75,0x35,0x04,0x00, 0x00,0x3a,0xd7,0xdc,0x89,0xef,0xe5,0x22,0xa0,0x83,0x00,0x10,0x00,0x00,0x20, 0x00,0x00,0x80,0xc0,0x08,0x00,0x00,0x61,0x11,0xea,0xce,0x36,0x7f,0xbf,0xff, 0xfe,0x69,0x0b,0x4d,0xf7,0xe4,0xca,0xb5,0x8e,0x2b,0x04,0x88,0x00,0x0b,0x08, 0x00,0x00,0x10,0x20,0x00,0x00,0x84,0x00,0x72,0x40,0x8b,0xef,0x81,0x55,0xd3, 0xbd,0x00,0x00,0x10,0x78,0xd5,0xdf,0x81,0x7b,0xa7,0x05,0x01,0x09,0x90,0x00, 0x10,0x04,0x38,0x80,0x00,0x00,0x30,0x01,0x82,0x20,0x40,0xc4,0xb0,0xbf,0x27, 0xfe,0xfb,0xaf,0xff,0x5b,0x93,0x4a,0x75,0xe4,0xfb,0x4a,0x3d,0x29,0x81,0x00, 0xa0,0x34,0x00,0x08,0x08,0x00,0x00,0x02,0x04,0x00,0x50,0xa8,0x00,0xdb,0xad, 0xa0,0xef,0xf7,0xbc,0x00,0x00,0x00,0x7a,0xdb,0xde,0x81,0xed,0xf6,0x22,0x88, 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0c,0x02,0x20,0x00,0xa8,0x7f, 0xaf,0xb6,0x6d,0xee,0xbf,0xfb,0x00,0x00,0x0c,0x54,0xfd,0xec,0xb7,0xfd,0xfd, 0x5f,0x10,0x24,0x04,0x3e,0x00,0x00,0x01,0x04,0x01,0x80,0x80,0x00,0x04,0x32, 0x40,0x95,0xcf,0x81,0x73,0x55,0x2d,0x00,0x00,0x04,0x7a,0xc5,0x5b,0x11,0xff, 0xe5,0x09,0x80,0xff,0x00,0x04,0x02,0x80,0x00,0x00,0x00,0x40,0xe0,0x40,0x00, 0x08,0xe9,0xff,0x7e,0x7d,0x27,0xfe,0xf7,0x8f,0x0b,0xee,0xe3,0x49,0xed,0xd9, 0xff,0x77,0xd7,0xb6,0xef,0xdf,0xfb,0x57,0x40,0x40,0x80,0x00,0x70,0x04,0x00, 0x00,0x80,0x68,0x0d,0x9b,0x7e,0x81,0x7f,0xf3,0xbd,0x20,0x00,0x00,0x5a,0x97, 0xde,0x81,0x6d,0xb7,0x00,0x02,0x20,0x22,0x89,0x80,0x00,0x20,0x10,0x18,0x02, 0x94,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x90,0x61,0x3f,0x34,0xaa,0xea,0x60, 0xd9,0x16,0x22,0x00,0x89,0x2a,0x55,0xb5,0x6a,0xad,0x56,0x48,0x04,0x00,0x74, 0x10,0x90,0x10,0x44,0x00,0xf6,0x4f,0x96,0xeb,0x88,0xf7,0x5a,0x37,0x00,0x00, 0x00,0x6a,0x8a,0xb9,0x80,0x73,0xd3,0x01,0x20,0x09,0x00,0x04,0x20,0xa0,0x42, 0x00,0x0a,0x02,0xb0,0xef,0xfb,0x77,0x7f,0xf7,0xb7,0xef,0x9f,0xcd,0x57,0x9b, 0x03,0x00,0x52,0xa5,0x7e,0xe6,0xff,0xfe,0xdd,0xfb,0xdd,0xff,0xf7,0x71,0x00, 0xd5,0x3e,0xe5,0xd2,0x96,0x0f,0x00,0x20,0x01,0x00,0x95,0xde,0x81,0xb9,0x73, 0xae,0x04,0x00,0x00,0x58,0xb6,0xf7,0x00,0xbb,0xba,0x4a,0x00,0x00,0x91,0xba, 0x86,0x9a,0xa9,0xf2,0xe1,0x1c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0, 0xd3,0x84,0xf0,0xff,0xff,0x1f,0x06,0xb1,0x0f,0x00,0x00,0x00,0x00,0x12,0x12, 0x24,0x2a,0xc0,0x58,0xa1,0x92,0x28,0x65,0x10,0x00,0x21,0x34,0x84,0x86,0xb9, 0xa0,0x7f,0xdb,0xb6,0x10,0x00,0x00,0xaa,0x26,0x3d,0x91,0xbd,0x59,0x03,0x00, 0x00,0x00,0xa5,0x6a,0x05,0x46,0x24,0x49,0x45,0xdc,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x69,0x82,0xff,0xff,0xff,0xff,0x87,0xce,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0x27,0x03,0x00,0x10,0x00,0x00,0x00,0x02,0x44,0x88,0x00, 0xa1,0x36,0x7f,0x81,0xcd,0x19,0xbe,0x00,0x00,0x08,0xfa,0x2e,0x7b,0x01,0x7b, 0xb9,0x43,0x04,0x48,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xb3,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xf3,0xf8,0xff,0xfd,0xff,0xff,0xbf,0x8e,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0x02,0x04,0x00,0x00,0x00,0x00,0x02, 0x01,0x40,0x2a,0x80,0x36,0xb3,0x80,0xbd,0x79,0xbe,0x00,0x00,0x00,0xba,0x5b, 0x6f,0x00,0xcd,0x49,0x00,0x21,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0xd5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfa,0xff,0x5f,0x95,0x00,0xf0, 0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x25,0x1a,0x42,0x48,0x41, 0x08,0x00,0x48,0x21,0xad,0x31,0x14,0x65,0xef,0x08,0xef,0x0c,0x31,0x10,0x00, 0x80,0xea,0x55,0x0a,0x04,0x58,0xac,0x54,0x00,0x00,0x08,0x00,0x00,0x01,0x00, 0x00,0x00,0x10,0x15,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xee,0xb7, 0xad,0xfe,0x8b,0xfe,0xf7,0xa9,0xda,0xff,0xff,0xff,0xff,0xff,0xff,0x95,0xc6, 0x90,0x5a,0x1d,0x73,0x6f,0x27,0x94,0x5a,0xce,0x51,0x55,0x1d,0x40,0xbc,0x5c, 0xbf,0x00,0x00,0x00,0xf8,0xc5,0xfc,0xff,0xbf,0x56,0x9b,0x73,0x6b,0xe7,0xac, 0xbd,0xae,0x95,0xb3,0x56,0x4b,0xe5,0x49,0x0a,0x00,0x02,0x40,0x00,0x00,0x00, 0x3e,0x00,0x00,0x2b,0x20,0x30,0x00,0x70,0x01,0xe0,0x88,0xc0,0x06,0x40,0x80, 0x85,0x84,0x88,0xb4,0x56,0x45,0xa5,0x52,0x6a,0xa9,0xb5,0xab,0xb4,0x68,0xf6, 0xff,0xf7,0xb4,0xbf,0x04,0x00,0x00,0x9a,0xb9,0xd4,0xff,0x97,0x26,0x2d,0x55, 0x6d,0x55,0x1a,0x63,0x4a,0x90,0x54,0x2d,0x2a,0x95,0x56,0x05,0x07,0x06,0xc0, 0x61,0x00,0x00,0xe2,0x00,0x03,0x2f,0x70,0xe0,0x01,0xfc,0x03,0xf0,0x7f,0xc0, 0x1d,0xc0,0x00,0xb7,0x2b,0x53,0x6a,0xd7,0x56,0x49,0x0c,0x2b,0x2d,0xdf,0x67, 0xb5,0x88,0xd8,0xff,0x57,0xae,0xb5,0x00,0x00,0x00,0xda,0x1b,0xb9,0xb6,0x2e, 0xcb,0x4e,0x4b,0x0c,0xa9,0xb5,0xba,0xb7,0xb5,0x96,0xb2,0x57,0xb1,0xed,0x00, 0x0f,0x18,0x80,0xf7,0x00,0x07,0xae,0x09,0x07,0x0c,0x70,0x80,0x03,0xfc,0x07, 0xf8,0x2b,0x80,0x7f,0xc0,0x01,0x5f,0x72,0xb6,0xdf,0xfa,0xbd,0xf7,0xfb,0xea, 0xd6,0x6a,0xda,0x4b,0xdb,0xbd,0xfe,0x3d,0x93,0xbb,0x00,0x00,0x10,0xfa,0xaa, 0xe3,0xba,0x3c,0xab,0xfd,0xf7,0xf7,0xf7,0x6e,0x77,0xad,0x77,0xf7,0xfd,0xd6, 0x4e,0x5f,0x01,0x0f,0x38,0x04,0xf7,0x00,0x17,0x5e,0x81,0x97,0x0c,0x70,0x80, 0x03,0xbe,0x05,0xfc,0x5f,0x08,0x77,0xc0,0x20,0xbe,0x35,0x0a,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x56,0xd1,0x2e,0x16,0x47,0x3d,0x00,0x00, 0x00,0xe8,0x27,0xa6,0xb5,0x87,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x78,0xb7,0x00,0x0f,0xb8,0x00,0xf6,0x00,0xe1,0xdf,0x00,0x07, 0x08,0x70,0x80,0x01,0x6e,0x02,0xbc,0xb0,0x01,0x5f,0xe0,0x80,0x9f,0xca,0xf1, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x87,0x63,0x5b,0xc5,0x69, 0xae,0x40,0x00,0x00,0xfa,0x2c,0x8d,0xaf,0xe3,0xe8,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xaf,0xb7,0x5a,0x08,0x0f,0xb8,0x01,0xf0,0x04,0xf1, 0xb7,0x01,0x07,0x08,0x70,0xc0,0x03,0x3e,0x06,0x6c,0x8d,0x01,0x5e,0x40,0xc8, 0xbf,0xfc,0xc7,0xd5,0xbe,0xc5,0xba,0xea,0xff,0xdd,0xff,0xf7,0xff,0x6f,0x8c, 0x57,0x63,0xe4,0xbb,0x10,0x00,0x00,0xba,0x5c,0x1c,0xd6,0x70,0xe4,0xff,0xfd, 0xf7,0xee,0xfd,0xff,0xff,0x6f,0xfb,0xee,0xd7,0x6d,0xdd,0x00,0x07,0xb8,0x21, 0xb0,0x00,0xe3,0x5c,0x13,0x07,0x08,0xf0,0x80,0x23,0x5e,0x06,0xfc,0xdc,0x21, 0x3e,0xd0,0x80,0xaf,0xae,0xae,0xff,0xff,0xaa,0xfe,0xde,0xdf,0xf7,0xfd,0x55, 0xbf,0x9d,0x0e,0xdd,0xf1,0xb2,0xbd,0x00,0x00,0x00,0xea,0x9e,0x71,0x00,0x1c, 0xf5,0xfa,0x2b,0xfd,0xb7,0xbf,0xcf,0xf5,0xad,0xde,0x7f,0x6b,0x7f,0xbe,0x40, 0x0f,0xb8,0x07,0xf0,0x00,0x37,0x56,0x04,0x47,0x0e,0x71,0x80,0x03,0x1e,0x86, 0x38,0xec,0x01,0x7c,0xe0,0x80,0xb7,0xfa,0xcd,0xdf,0xdd,0x75,0xb7,0x55,0xf7, 0xbd,0xff,0xd5,0xbf,0x2f,0x71,0x00,0x1c,0xf9,0xb9,0x00,0x00,0x40,0x7a,0x3f, 0xe5,0x01,0x2f,0xda,0xdb,0x55,0x5f,0xef,0xed,0xfb,0xbe,0x6d,0xeb,0xaa,0xe3, 0xfb,0x7a,0x01,0x8f,0x18,0x0f,0xf0,0x00,0x0f,0xde,0x01,0x07,0x1c,0x70,0xc0, 0x01,0x0f,0x06,0x3c,0xcc,0x03,0x38,0xc4,0x04,0xaf,0xad,0xaa,0x97,0xfb,0xcd, 0xdb,0xff,0x3a,0xd7,0xfd,0xba,0xfd,0x7f,0xf5,0x21,0xaf,0x7c,0xb7,0x00,0x00, 0x00,0x48,0xfb,0x92,0xff,0xa3,0xfd,0xf6,0xe7,0xfe,0xd6,0x77,0xdf,0xf7,0xa7, 0x7e,0xf3,0x74,0x77,0xaf,0x00,0x07,0x1e,0x1b,0xf0,0x20,0x03,0xae,0x00,0x03, 0x1e,0x30,0xe0,0x00,0x02,0x02,0x08,0x84,0x01,0x18,0xc0,0x00,0x6f,0xbe,0x4d, 0x1c,0xfb,0xba,0xbe,0x55,0xef,0x7b,0xbb,0xad,0xdb,0xad,0x04,0xef,0x25,0xfe, 0xbb,0x20,0x00,0x00,0xfa,0xff,0x84,0x7c,0x80,0xee,0x7b,0x37,0xfb,0xbf,0xfb, 0xeb,0x6d,0x5b,0xfd,0xf1,0x6a,0x5d,0x7d,0x06,0x07,0x0e,0x2c,0x30,0x08,0x00, 0x1e,0x00,0x41,0x7f,0x20,0x38,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x01,0x83, 0xd8,0xfd,0xae,0xa5,0xbd,0x5d,0xef,0xef,0xef,0xfe,0x7e,0x5a,0xef,0xbb,0x28, 0xd6,0x12,0xf7,0x3d,0x00,0x00,0x00,0x9a,0xb5,0x33,0x02,0x2a,0xdb,0xf6,0xd5, 0x6a,0xdd,0xde,0xdf,0xd7,0xf5,0xba,0x2d,0x60,0xb4,0xde,0xfd,0xfa,0xff,0xdf, 0xff,0xff,0xff,0xf7,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x5f,0x5a,0x2a,0x3b,0xf7,0xbe,0xaf,0x5b,0xf7,0xeb,0x73,0xfd, 0x5e,0xcf,0x03,0x20,0xc9,0xbd,0xbb,0x08,0x00,0x00,0x7a,0xf7,0x62,0x01,0x88, 0x75,0xef,0x73,0xfd,0xdb,0xbf,0xef,0xef,0x5b,0x7d,0xcb,0xe5,0x75,0xbf,0xfe, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x75,0x57,0xac,0x75,0xba,0x7c,0xaf,0xe7, 0xfb,0xae,0xad,0xd5,0xbf,0x07,0x50,0x60,0x6f,0xb5,0x00,0x00,0x00,0xba,0x7d, 0x1f,0xfe,0x71,0xb7,0xdf,0xdc,0xb6,0x7d,0xcf,0xbb,0xfb,0xf2,0xd7,0x51,0x51, 0x8f,0x77,0xfb,0xff,0xff,0x7f,0xff,0xff,0xff,0xdf,0xff,0xff,0x6f,0xff,0xaf, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xdd,0x1e,0xc7,0xaf,0x7d, 0xa7,0xff,0xdf,0xbf,0xdb,0xfa,0xfe,0xfb,0xff,0xa0,0xfe,0xef,0x3f,0x00,0x00, 0x40,0x72,0xdf,0xff,0x00,0xce,0xdf,0xb7,0x7b,0xef,0x77,0x7f,0xff,0xde,0xff, 0xff,0xff,0xff,0xfb,0x5d,0xea,0xff,0xe5,0xef,0xfe,0xff,0xff,0x37,0xff,0xff, 0xdb,0xee,0x7b,0xff,0xff,0xff,0xdd,0xf7,0xff,0x7b,0xab,0xaa,0x2a,0x85,0x54, 0x55,0x54,0x52,0x52,0x51,0x04,0x84,0x14,0x02,0x08,0x04,0x00,0x12,0x09,0x00, 0x80,0x00,0x00,0x10,0xf8,0xff,0xff,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xbf,0xff,0xde,0x56,0xad,0xaa,0x56,0x53,0x15,0x04,0x0a,0x11,0x01,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x20,0x80,0x24,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x22,0x22,0x91,0xac,0xea,0x6a,0x7b,0xed, 0xbe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xb7, 0xde,0xff,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0x20,0x04,0x01,0x00,0x00,0x00,0x4a,0xca,0xaa,0xbe,0xdd, 0x76,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xef,0xfd,0x6d,0x6d,0xab,0xaa, 0x9a,0x4a,0x81,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x40,0x02,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x20,0x80,0x00,0x00,0x00, 0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x01,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0x10,0xa4,0x08,0x80,0x80,0x00,0x08, 0x80,0x00,0x00,0x00,0x00,0x01,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x21, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x00,0x00,0x00, 0x20,0x00,0x00,0x10,0x10,0x00,0x80,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0x00, 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x00,0x00,0x42,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10, 0x41,0x00,0x02,0x04,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x40,0x04,0x00,0x80, 0x00,0x00,0x20,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x04,0x02, 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x10,0x02,0x80,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x22,0x02,0x00,0x00,0x01,0x00, 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,0x00,0x20,0x04,0x00, 0x08,0x00,0x04,0x80,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00, 0x00,0x00,0x40,0x24,0x84,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x02,0x00,0x01,0x20,0x10,0x84, 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x20,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x80,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x00,0x01, 0x00,0x00,0x00,0x24,0x02,0x01,0x00,0x00,0x00,0x00,0x20,0x00,0x14,0x88,0x10, 0x00,0x00,0x84,0x00,0x00,0x00,0x04,0x10,0x00,0x40,0x00,0x40,0x00,0x42,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x21,0x00,0x08,0x04,0x01,0x08,0x00,0x48, 0x00,0x00,0x04,0x08,0x00,0x80,0x00,0x10,0x00,0x20,0x00,0x08,0x00,0x40,0x00, 0x00,0x00,0x00,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; �������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/���������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�015731� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/left1m.xbm�����������������������������������������������������0000644�0001750�0001750�00000000526�11462120062�017640� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_left1m_width 16 #define fc_left1m_height 16 #define fc_left1m_x_hot 8 #define fc_left1m_y_hot 8 static char fc_left1m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xe0, 0x17, 0xf0, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xe0, 0x13, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/leftm.xbm������������������������������������������������������0000644�0001750�0001750�00000000521�11462120062�017552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_leftm_width 16 #define fc_leftm_height 16 #define fc_leftm_x_hot 8 #define fc_leftm_y_hot 8 static char fc_leftm_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0xf0, 0x83, 0xfc, 0xe3, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfc, 0xe3, 0xf0, 0x83, 0x80, 0x03, 0x00, 0x07, 0x00, 0x00}; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/left.xbm�������������������������������������������������������0000644�0001750�0001750�00000000514�11462120062�017377� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_left_width 16 #define fc_left_height 16 #define fc_left_x_hot 8 #define fc_left_y_hot 8 static char fc_left_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x04, 0x70, 0x82, 0x8c, 0xe2, 0x22, 0x9c, 0x2d, 0x90, 0x2d, 0x80, 0x21, 0x90, 0x22, 0x9c, 0x1c, 0xe3, 0x70, 0x82, 0x80, 0x02, 0x00, 0x07, 0x00, 0x00}; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/rightm.xbm�����������������������������������������������������0000644�0001750�0001750�00000000526�11462120062�017742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_rightm_width 16 #define fc_rightm_height 16 #define fc_rightm_x_hot 8 #define fc_rightm_y_hot 8 static char fc_rightm_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xe0, 0x03, 0xc1, 0x0f, 0xc7, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xc7, 0x3f, 0xc1, 0x0f, 0xc0, 0x01, 0xe0, 0x00, 0x00, 0x00}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/mid.xbm��������������������������������������������������������0000644�0001750�0001750�00000000507�11462120062�017220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_mid_width 16 #define fc_mid_height 16 #define fc_mid_x_hot 8 #define fc_mid_y_hot 8 static char fc_mid_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0x40, 0x04, 0x20, 0x08, 0xe0, 0x0e, 0xe0, 0x0e, 0x20, 0x08, 0xa0, 0x0b, 0xe0, 0x0f, 0xa0, 0x0b, 0x40, 0x04, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00}; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/left1.xbm������������������������������������������������������0000644�0001750�0001750�00000000521�11462120062�017456� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_left1_width 16 #define fc_left1_height 16 #define fc_left1_x_hot 8 #define fc_left1_y_hot 8 static char fc_left1_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x02, 0xe0, 0x14, 0x10, 0x1f, 0xd8, 0x14, 0xd8, 0x14, 0x08, 0x10, 0x08, 0x14, 0xd0, 0x14, 0x70, 0x1e, 0x60, 0x13, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00}; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/right.xbm������������������������������������������������������0000644�0001750�0001750�00000000521�11462120062�017560� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_right_width 16 #define fc_right_height 16 #define fc_right_x_hot 8 #define fc_right_y_hot 8 static char fc_right_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x20, 0x03, 0x41, 0x0e, 0x47, 0x30, 0x39, 0x44, 0x09, 0xb4, 0x01, 0xb4, 0x09, 0x84, 0x39, 0x44, 0xc7, 0x38, 0x41, 0x0e, 0x40, 0x01, 0xe0, 0x00, 0x00, 0x00}; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/midm.xbm�������������������������������������������������������0000644�0001750�0001750�00000000514�11462120062�017373� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_midm_width 16 #define fc_midm_height 16 #define fc_midm_x_hot 8 #define fc_midm_y_hot 8 static char fc_midm_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00}; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/right1.xbm�����������������������������������������������������0000644�0001750�0001750�00000000526�11462120062�017646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_right1_width 16 #define fc_right1_height 16 #define fc_right1_x_hot 8 #define fc_right1_y_hot 8 static char fc_right1_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x03, 0x28, 0x07, 0xf8, 0x08, 0x28, 0x1b, 0x28, 0x1b, 0x08, 0x10, 0x28, 0x10, 0x28, 0x0b, 0x38, 0x0e, 0xc8, 0x06, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/fish/right1m.xbm����������������������������������������������������0000644�0001750�0001750�00000000533�11462120062�020021� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define fc_right1m_width 16 #define fc_right1m_height 16 #define fc_right1m_x_hot 8 #define fc_right1m_y_hot 8 static char fc_right1m_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0x03, 0xe8, 0x07, 0xf8, 0x0f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x0f, 0xf8, 0x0f, 0xc8, 0x07, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/sharky.xbm����������������������������������������������������������0000644�0001750�0001750�00000022331�11462120062�017016� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define sharky_width 171 #define sharky_height 68 static char sharky_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfd, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x49, 0x92, 0x54, 0x55, 0x45, 0xeb, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x41, 0x55, 0x84, 0x44, 0x85, 0xa2, 0x50, 0x94, 0x0f, 0x00, 0x00, 0x06, 0x00, 0xfc, 0x17, 0x00, 0x40, 0x12, 0x12, 0x42, 0x00, 0x01, 0x04, 0x04, 0x51, 0x75, 0x75, 0xd5, 0xae, 0x55, 0x10, 0x00, 0x80, 0x0f, 0x00, 0xfe, 0x1f, 0x00, 0x5c, 0x54, 0x45, 0x89, 0x04, 0x10, 0x00, 0x80, 0x08, 0x55, 0xd5, 0x5e, 0x55, 0xa5, 0x25, 0x15, 0xa0, 0x1f, 0x00, 0xfe, 0x1f, 0x00, 0xde, 0x55, 0xb5, 0x76, 0x65, 0x25, 0x52, 0x22, 0xd0, 0x56, 0x7b, 0xd5, 0xff, 0x5d, 0xb5, 0xa2, 0xd7, 0x1f, 0x00, 0xff, 0x0d, 0x00, 0x17, 0x41, 0x40, 0x00, 0x7a, 0x95, 0x00, 0x91, 0x0a, 0xd9, 0xed, 0x7f, 0xd5, 0x73, 0x5b, 0x55, 0x54, 0x7f, 0x80, 0xde, 0x07, 0x00, 0xab, 0x54, 0x14, 0x49, 0xa8, 0x6e, 0x55, 0x0c, 0x64, 0x75, 0xff, 0xff, 0xbf, 0xde, 0x57, 0xd5, 0x95, 0xfa, 0x43, 0x7f, 0x07, 0x00, 0x17, 0x00, 0x09, 0x00, 0x74, 0xd1, 0x5b, 0xb5, 0xa9, 0xdd, 0xd5, 0xf7, 0xfd, 0x5f, 0x5e, 0x55, 0x52, 0x95, 0xdd, 0xfd, 0x05, 0x00, 0x76, 0x55, 0x52, 0x25, 0xf9, 0x15, 0x76, 0x6f, 0xb6, 0xf7, 0xff, 0xff, 0xff, 0xfb, 0xd7, 0xf7, 0xaa, 0x75, 0xf7, 0xf7, 0x03, 0x00, 0xd8, 0x15, 0x50, 0x00, 0xf8, 0x60, 0xe8, 0xdd, 0x5d, 0x7f, 0xff, 0xff, 0xef, 0xff, 0xfd, 0x5e, 0x5b, 0xff, 0xbf, 0xad, 0x03, 0x00, 0x70, 0x27, 0x05, 0x49, 0xf9, 0x0a, 0x12, 0xb6, 0xf5, 0xfd, 0x7f, 0xdf, 0xfd, 0xff, 0xff, 0xdf, 0xff, 0xbd, 0x6d, 0xd6, 0x07, 0x00, 0xe0, 0x5b, 0x75, 0x04, 0x7c, 0x01, 0x40, 0xa8, 0xee, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xbf, 0xff, 0xeb, 0xd7, 0xd5, 0xbd, 0x05, 0x00, 0x80, 0x7f, 0x05, 0x51, 0xb1, 0x44, 0x95, 0x46, 0x75, 0xe7, 0xff, 0xff, 0xff, 0xde, 0xfb, 0xfb, 0x7e, 0x7d, 0x75, 0xef, 0x07, 0x00, 0x00, 0x7e, 0x5b, 0x12, 0x00, 0x10, 0x00, 0x18, 0x4a, 0x9d, 0xfd, 0xdf, 0xf6, 0xfb, 0xff, 0xdf, 0xd7, 0xa5, 0x4d, 0xd5, 0x06, 0x00, 0x00, 0xf8, 0xd7, 0xad, 0x0a, 0x02, 0x44, 0x82, 0x52, 0x77, 0xef, 0xfd, 0xbf, 0xdf, 0xd6, 0xf6, 0x7e, 0x5f, 0x03, 0xf7, 0x0f, 0x00, 0x00, 0xe0, 0x5f, 0xb6, 0x44, 0x08, 0x11, 0x51, 0x54, 0x4a, 0xbb, 0xf7, 0xed, 0x7a, 0xdf, 0xdd, 0xd5, 0x75, 0x00, 0x5e, 0x1d, 0x00, 0x00, 0x00, 0x3f, 0x93, 0x5d, 0x43, 0x44, 0x08, 0x11, 0x69, 0xd5, 0x5e, 0x7f, 0xdf, 0x7b, 0x77, 0x75, 0x3b, 0x00, 0xf0, 0x2b, 0x00, 0x00, 0x00, 0xfc, 0x5d, 0x67, 0x11, 0x00, 0x21, 0x44, 0x55, 0x7b, 0x75, 0xd5, 0x6b, 0xd5, 0x6d, 0x5f, 0x07, 0x00, 0x50, 0x37, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x9d, 0x84, 0x48, 0x48, 0x89, 0x50, 0xb6, 0xd6, 0xbd, 0x5a, 0x77, 0xdb, 0xd6, 0x3d, 0x00, 0xc0, 0x76, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x57, 0x40, 0x02, 0x45, 0x44, 0xd7, 0x55, 0x55, 0xd5, 0x54, 0x55, 0x35, 0x33, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x3f, 0x15, 0x50, 0x50, 0xd1, 0x7f, 0x54, 0xb5, 0x56, 0xdd, 0xf6, 0x1d, 0x5c, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x40, 0x45, 0x09, 0x41, 0xe4, 0x5f, 0x95, 0x52, 0x55, 0x25, 0x55, 0x07, 0x74, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x54, 0x12, 0x32, 0x11, 0x15, 0xf1, 0xff, 0x52, 0x15, 0x53, 0xa9, 0xdd, 0x1f, 0x10, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00, 0x00, 0x40, 0x05, 0xc9, 0x44, 0x49, 0x55, 0xf4, 0xf7, 0x12, 0x45, 0x11, 0x55, 0xd5, 0x1f, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x56, 0x5b, 0xb5, 0xa4, 0xea, 0x5f, 0x4f, 0x51, 0xcc, 0xd6, 0x3f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x56, 0x5b, 0xf5, 0xff, 0x50, 0x55, 0xdb, 0xff, 0x1f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xbf, 0xff, 0x55, 0xff, 0xff, 0xaf, 0xd6, 0xff, 0xc1, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xef, 0xfe, 0xf7, 0xff, 0xdf, 0xff, 0x05, 0xe0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xaf, 0x1f, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x02, 0x00, 0x3c, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0x00, 0xe0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmaps/hobbes.xbm����������������������������������������������������������0000644�0001750�0001750�00000001365�11462120062�016763� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define hobbes_width 25 #define hobbes_height 25 #define hobbes_x_hot 16 #define hobbes_y_hot 15 static char hobbes_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x78, 0xe0, 0x07, 0x00, 0xfc, 0xf8, 0x07, 0x00, 0xcc, 0x07, 0x04, 0x00, 0x0c, 0xf0, 0x0b, 0x00, 0x7c, 0x1c, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x10, 0x00, 0xe0, 0x41, 0x11, 0x00, 0x20, 0x40, 0x11, 0x00, 0xe0, 0x07, 0x10, 0x00, 0xe0, 0xc1, 0x17, 0x00, 0x10, 0xe0, 0x2f, 0x00, 0x20, 0xe0, 0x6f, 0x00, 0x18, 0xe0, 0x2f, 0x00, 0x20, 0xc6, 0x67, 0x00, 0x18, 0x84, 0x2b, 0x00, 0x20, 0x08, 0x64, 0x00, 0x70, 0xf0, 0x13, 0x00, 0x80, 0x01, 0x08, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/centry1.tcl�����������������������������������������������������������������0000644�0001750�0001750�00000005377�11462120062�015452� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } #set icon [image create picture -data $imgData] set icon [image create picture -file images/mini-book1.gif] #set icon [image create picture -file images/blt98.gif] #set image [image create picture -file ~/images.jpeg] set activebg [blt::bgpattern create gradient -high grey70 -low grey85 \ -jitter yes -log yes -relativeto self] set bg [blt::bgpattern create gradient -high grey80 -low grey95 \ -jitter yes -log yes -relativeto self] set image "" option add *ComboEntry.takeFocus 1 blt::comboentry .e \ -textvariable t \ -font { arial 10 } \ -image $image \ -iconvariable icon \ -textwidth 6 \ -menu .e.m \ -exportselection yes \ -xscrollcommand { .s set } \ -command "puts {button pressed}" \ -closebutton yes \ -closecommand { .e delete 0 end } blt::combobutton .b \ -textvariable t \ -image $image \ -iconvariable icon \ -bg $bg \ -font { Arial 12 } -justify left \ -underline 19 \ -arrowborderwidth 2 \ -arrowrelief flat blt::tk::scrollbar .s -orient vertical -command { .e xview } blt::table . \ 0,0 .e -fill both -cspan 2 -padx 2 -pady 2 blt::table configure . c1 -resize shrink blt::table configure . r0 -resize shrink blt::table configure . c0 -pad { 2 0 } blt::table configure . c1 -pad { 0 2 } blt::combomenu .e.m -relief sunken -bg white -textvariable t .e.m add -text "one" -accelerator "^A" .e.m add -text "two" -accelerator "^B" .e.m add -text "three" -accelerator "^C" .e.m add -text "four" -accelerator "^D" .e.m add -type cascade -text "cascade" -accelerator "^E" -menu .e.m.m blt::combomenu .e.m.m -relief sunken -bg white -textvariable t .e.m.m add -text "five" -accelerator "^A" .e.m.m add -text "six" -accelerator "^B" .e.m.m add -text "seven" -accelerator "^C" .e.m.m add -text "eight" -accelerator "^D" .e.m.m add -text "nine" -accelerator "^D" -command "set t {really really really long entry}" .e.m.m add -type cascade -text "cascade" -accelerator "^E" after idle { set t "Hello, World" .e insert 0 "Fred says: \n" puts "($t)" update } proc AddEntry { e m } { set s [$e get] puts stderr "current entry is $s" puts stderr "$m find $s -from 0 -type command => [$m find $s -from 0 -type command]" puts stderr "$m find * -from 0 -type separator -glob => [$m find * -from 0 -type separator -glob]" if { [$m find $s -from 0 -type command] < 0 } { set sep [$m index "mysep"] if { $sep < 0 } { $m insert before 0 -type separator -text "mysep" } $m insert before 0 -text $s } } bind .e <Return> [list AddEntry .e .e.m] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cbutton3.tcl����������������������������������������������������������������0000644�0001750�0001750�00000041160�11462120062�015614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set colors { 000000 black 000000 gray0 000000 grey0 000080 NavyBlue 000080 navy 000080 {navy blue} 00008B DarkBlue 00008B blue4 00008B {dark blue} 0000CD MediumBlue 0000CD blue3 0000CD {medium blue} 0000EE blue2 0000FF blue 0000FF blue1 006400 DarkGreen 006400 {dark green} 00688B DeepSkyBlue4 00868B turquoise4 008B00 green4 008B45 SpringGreen4 008B8B DarkCyan 008B8B cyan4 008B8B {dark cyan} 009ACD DeepSkyBlue3 00B2EE DeepSkyBlue2 00BFFF DeepSkyBlue 00BFFF DeepSkyBlue1 00BFFF {deep sky blue} 00C5CD turquoise3 00CD00 green3 00CD66 SpringGreen3 00CDCD cyan3 00CED1 DarkTurquoise 00CED1 {dark turquoise} 00E5EE turquoise2 00EE00 green2 00EE76 SpringGreen2 00EEEE cyan2 00F5FF turquoise1 00FA9A MediumSpringGreen 00FA9A {medium spring green} 00FF00 green 00FF00 green1 00FF7F SpringGreen 00FF7F SpringGreen1 00FF7F {spring green} 00FFFF cyan 00FFFF cyan1 030303 gray1 030303 grey1 050505 gray2 050505 grey2 080808 gray3 080808 grey3 0A0A0A gray4 0A0A0A grey4 0D0D0D gray5 0D0D0D grey5 0F0F0F gray6 0F0F0F grey6 104E8B DodgerBlue4 121212 gray7 121212 grey7 141414 gray8 141414 grey8 171717 gray9 171717 grey9 1874CD DodgerBlue3 191970 MidnightBlue 191970 {midnight blue} 1A1A1A gray10 1A1A1A grey10 1C1C1C gray11 1C1C1C grey11 1C86EE DodgerBlue2 1E90FF DodgerBlue 1E90FF DodgerBlue1 1E90FF {dodger blue} 1F1F1F gray12 1F1F1F grey12 20B2AA LightSeaGreen 20B2AA {light sea green} 212121 gray13 212121 grey13 228B22 ForestGreen 228B22 {forest green} 242424 gray14 242424 grey14 262626 gray15 262626 grey15 27408B RoyalBlue4 292929 gray16 292929 grey16 2B2B2B gray17 2B2B2B grey17 2E2E2E gray18 2E2E2E grey18 2E8B57 SeaGreen 2E8B57 SeaGreen4 2E8B57 {sea green} 2F4F4F DarkSlateGray 2F4F4F DarkSlateGrey 2F4F4F {dark slate gray} 2F4F4F {dark slate grey} 303030 gray19 303030 grey19 32CD32 LimeGreen 32CD32 {lime green} 333333 gray20 333333 grey20 363636 gray21 363636 grey21 36648B SteelBlue4 383838 gray22 383838 grey22 3A5FCD RoyalBlue3 3B3B3B gray23 3B3B3B grey23 3CB371 MediumSeaGreen 3CB371 {medium sea green} 3D3D3D gray24 3D3D3D grey24 404040 gray25 404040 grey25 40E0D0 turquoise 4169E1 RoyalBlue 4169E1 {royal blue} 424242 gray26 424242 grey26 436EEE RoyalBlue2 43CD80 SeaGreen3 454545 gray27 454545 grey27 458B00 chartreuse4 458B74 aquamarine4 4682B4 SteelBlue 4682B4 {steel blue} 473C8B SlateBlue4 474747 gray28 474747 grey28 483D8B DarkSlateBlue 483D8B {dark slate blue} 4876FF RoyalBlue1 48D1CC MediumTurquoise 48D1CC {medium turquoise} 4A4A4A gray29 4A4A4A grey29 4A708B SkyBlue4 4D4D4D gray30 4D4D4D grey30 4EEE94 SeaGreen2 4F4F4F gray31 4F4F4F grey31 4F94CD SteelBlue3 525252 gray32 525252 grey32 528B8B DarkSlateGray4 53868B CadetBlue4 545454 gray33 545454 grey33 548B54 PaleGreen4 54FF9F SeaGreen1 551A8B purple4 556B2F DarkOliveGreen 556B2F {dark olive green} 575757 gray34 575757 grey34 595959 gray35 595959 grey35 5C5C5C gray36 5C5C5C grey36 5CACEE SteelBlue2 5D478B MediumPurple4 5E5E5E gray37 5E5E5E grey37 5F9EA0 CadetBlue 5F9EA0 {cadet blue} 607B8B LightSkyBlue4 616161 gray38 616161 grey38 636363 gray39 636363 grey39 63B8FF SteelBlue1 6495ED CornflowerBlue 6495ED {cornflower blue} 666666 gray40 666666 grey40 668B8B PaleTurquoise4 66CD00 chartreuse3 66CDAA MediumAquamarine 66CDAA aquamarine3 66CDAA {medium aquamarine} 68228B DarkOrchid4 68838B LightBlue4 6959CD SlateBlue3 696969 DimGray 696969 DimGrey 696969 gray41 696969 grey41 696969 {dim gray} 696969 {dim grey} 698B22 OliveDrab4 698B69 DarkSeaGreen4 6A5ACD SlateBlue 6A5ACD {slate blue} 6B6B6B gray42 6B6B6B grey42 6B8E23 OliveDrab 6B8E23 {olive drab} 6C7B8B SlateGray4 6CA6CD SkyBlue3 6E6E6E gray43 6E6E6E grey43 6E7B8B LightSteelBlue4 6E8B3D DarkOliveGreen4 707070 gray44 707070 grey44 708090 SlateGray 708090 SlateGrey 708090 {slate gray} 708090 {slate grey} 737373 gray45 737373 grey45 757575 gray46 757575 grey46 76EE00 chartreuse2 76EEC6 aquamarine2 778899 LightSlateGray 778899 LightSlateGrey 778899 {light slate gray} 778899 {light slate grey} 787878 gray47 787878 grey47 79CDCD DarkSlateGray3 7A378B MediumOrchid4 7A67EE SlateBlue2 7A7A7A gray48 7A7A7A grey48 7A8B8B LightCyan4 7AC5CD CadetBlue3 7B68EE MediumSlateBlue 7B68EE {medium slate blue} 7CCD7C PaleGreen3 7CFC00 LawnGreen 7CFC00 {lawn green} 7D26CD purple3 7D7D7D gray49 7D7D7D grey49 7EC0EE SkyBlue2 7F7F7F gray50 7F7F7F grey50 7FFF00 chartreuse 7FFF00 chartreuse1 7FFFD4 aquamarine 7FFFD4 aquamarine1 828282 gray51 828282 grey51 836FFF SlateBlue1 838B83 honeydew4 838B8B azure4 8470FF LightSlateBlue 8470FF {light slate blue} 858585 gray52 858585 grey52 878787 gray53 878787 grey53 87CEEB SkyBlue 87CEEB {sky blue} 87CEFA LightSkyBlue 87CEFA {light sky blue} 87CEFF SkyBlue1 8968CD MediumPurple3 8A2BE2 BlueViolet 8A2BE2 {blue violet} 8A8A8A gray54 8A8A8A grey54 8B0000 DarkRed 8B0000 red4 8B0000 {dark red} 8B008B DarkMagenta 8B008B magenta4 8B008B {dark magenta} 8B0A50 DeepPink4 8B1A1A firebrick4 8B1C62 maroon4 8B2252 VioletRed4 8B2323 brown4 8B2500 OrangeRed4 8B3626 tomato4 8B3A3A IndianRed4 8B3A62 HotPink4 8B3E2F coral4 8B4500 DarkOrange4 8B4513 SaddleBrown 8B4513 chocolate4 8B4513 {saddle brown} 8B4726 sienna4 8B475D PaleVioletRed4 8B4789 orchid4 8B4C39 salmon4 8B5742 LightSalmon4 8B5A00 orange4 8B5A2B tan4 8B5F65 LightPink4 8B636C pink4 8B6508 DarkGoldenrod4 8B668B plum4 8B6914 goldenrod4 8B6969 RosyBrown4 8B7355 burlywood4 8B7500 gold4 8B7765 PeachPuff4 8B795E NavajoWhite4 8B7B8B thistle4 8B7D6B bisque4 8B7D7B MistyRose4 8B7E66 wheat4 8B814C LightGoldenrod4 8B8378 AntiqueWhite4 8B8386 LavenderBlush4 8B864E khaki4 8B8682 seashell4 8B8878 cornsilk4 8B8970 LemonChiffon4 8B8989 snow4 8B8B00 yellow4 8B8B7A LightYellow4 8B8B83 ivory4 8C8C8C gray55 8C8C8C grey55 8DB6CD LightSkyBlue3 8DEEEE DarkSlateGray2 8EE5EE CadetBlue2 8F8F8F gray56 8F8F8F grey56 8FBC8F DarkSeaGreen 8FBC8F {dark sea green} 90EE90 LightGreen 90EE90 PaleGreen2 90EE90 {light green} 912CEE purple2 919191 gray57 919191 grey57 9370DB MediumPurple 9370DB {medium purple} 9400D3 DarkViolet 9400D3 {dark violet} 949494 gray58 949494 grey58 969696 gray59 969696 grey59 96CDCD PaleTurquoise3 97FFFF DarkSlateGray1 98F5FF CadetBlue1 98FB98 PaleGreen 98FB98 {pale green} 9932CC DarkOrchid 9932CC {dark orchid} 999999 gray60 999999 grey60 9A32CD DarkOrchid3 9AC0CD LightBlue3 9ACD32 OliveDrab3 9ACD32 YellowGreen 9ACD32 {yellow green} 9AFF9A PaleGreen1 9B30FF purple1 9BCD9B DarkSeaGreen3 9C9C9C gray61 9C9C9C grey61 9E9E9E gray62 9E9E9E grey62 9F79EE MediumPurple2 9FB6CD SlateGray3 A020F0 purple A0522D sienna A1A1A1 gray63 A1A1A1 grey63 A2B5CD LightSteelBlue3 A2CD5A DarkOliveGreen3 A3A3A3 gray64 A3A3A3 grey64 A4D3EE LightSkyBlue2 A52A2A brown A6A6A6 gray65 A6A6A6 grey65 A8A8A8 gray66 A8A8A8 grey66 A9A9A9 DarkGray A9A9A9 DarkGrey A9A9A9 {dark gray} A9A9A9 {dark grey} AB82FF MediumPurple1 ABABAB gray67 ABABAB grey67 ADADAD gray68 ADADAD grey68 ADD8E6 LightBlue ADD8E6 {light blue} ADFF2F GreenYellow ADFF2F {green yellow} AEEEEE PaleTurquoise2 AFEEEE PaleTurquoise AFEEEE {pale turquoise} B03060 maroon B0B0B0 gray69 B0B0B0 grey69 B0C4DE LightSteelBlue B0C4DE {light steel blue} B0E0E6 PowderBlue B0E0E6 {powder blue} B0E2FF LightSkyBlue1 B22222 firebrick B23AEE DarkOrchid2 B2DFEE LightBlue2 B3B3B3 gray70 B3B3B3 grey70 B3EE3A OliveDrab2 B452CD MediumOrchid3 B4CDCD LightCyan3 B4EEB4 DarkSeaGreen2 B5B5B5 gray71 B5B5B5 grey71 B8860B DarkGoldenrod B8860B {dark goldenrod} B8B8B8 gray72 B8B8B8 grey72 B9D3EE SlateGray2 BA55D3 MediumOrchid BA55D3 {medium orchid} BABABA gray73 BABABA grey73 BBFFFF PaleTurquoise1 BC8F8F RosyBrown BC8F8F {rosy brown} BCD2EE LightSteelBlue2 BCEE68 DarkOliveGreen2 BDB76B DarkKhaki BDB76B {dark khaki} BDBDBD gray74 BDBDBD grey74 BEBEBE gray BEBEBE grey BF3EFF DarkOrchid1 BFBFBF gray75 BFBFBF grey75 BFEFFF LightBlue1 C0FF3E OliveDrab1 C1CDC1 honeydew3 C1CDCD azure3 C1FFC1 DarkSeaGreen1 C2C2C2 gray76 C2C2C2 grey76 C4C4C4 gray77 C4C4C4 grey77 C6E2FF SlateGray1 C71585 MediumVioletRed C71585 {medium violet red} C7C7C7 gray78 C7C7C7 grey78 C9C9C9 gray79 C9C9C9 grey79 CAE1FF LightSteelBlue1 CAFF70 DarkOliveGreen1 CCCCCC gray80 CCCCCC grey80 CD0000 red3 CD00CD magenta3 CD1076 DeepPink3 CD2626 firebrick3 CD2990 maroon3 CD3278 VioletRed3 CD3333 brown3 CD3700 OrangeRed3 CD4F39 tomato3 CD5555 IndianRed3 CD5B45 coral3 CD5C5C IndianRed CD5C5C {indian red} CD6090 HotPink3 CD6600 DarkOrange3 CD661D chocolate3 CD6839 sienna3 CD6889 PaleVioletRed3 CD69C9 orchid3 CD7054 salmon3 CD8162 LightSalmon3 CD8500 orange3 CD853F peru CD853F tan3 CD8C95 LightPink3 CD919E pink3 CD950C DarkGoldenrod3 CD96CD plum3 CD9B1D goldenrod3 CD9B9B RosyBrown3 CDAA7D burlywood3 CDAD00 gold3 CDAF95 PeachPuff3 CDB38B NavajoWhite3 CDB5CD thistle3 CDB79E bisque3 CDB7B5 MistyRose3 CDBA96 wheat3 CDBE70 LightGoldenrod3 CDC0B0 AntiqueWhite3 CDC1C5 LavenderBlush3 CDC5BF seashell3 CDC673 khaki3 CDC8B1 cornsilk3 CDC9A5 LemonChiffon3 CDC9C9 snow3 CDCD00 yellow3 CDCDB4 LightYellow3 CDCDC1 ivory3 CFCFCF gray81 CFCFCF grey81 D02090 VioletRed D02090 {violet red} D15FEE MediumOrchid2 D1D1D1 gray82 D1D1D1 grey82 D1EEEE LightCyan2 D2691E chocolate D2B48C tan D3D3D3 LightGray D3D3D3 LightGrey D3D3D3 {light gray} D3D3D3 {light grey} D4D4D4 gray83 D4D4D4 grey83 D6D6D6 gray84 D6D6D6 grey84 D8BFD8 thistle D9D9D9 gray85 D9D9D9 grey85 DA70D6 orchid DAA520 goldenrod DB7093 PaleVioletRed DB7093 {pale violet red} DBDBDB gray86 DBDBDB grey86 DCDCDC gainsboro DDA0DD plum DEB887 burlywood DEDEDE gray87 DEDEDE grey87 E066FF MediumOrchid1 E0E0E0 gray88 E0E0E0 grey88 E0EEE0 honeydew2 E0EEEE azure2 E0FFFF LightCyan E0FFFF LightCyan1 E0FFFF {light cyan} E3E3E3 gray89 E3E3E3 grey89 E5E5E5 gray90 E5E5E5 grey90 E6E6FA lavender E8E8E8 gray91 E8E8E8 grey91 E9967A DarkSalmon E9967A {dark salmon} EBEBEB gray92 EBEBEB grey92 EDEDED gray93 EDEDED grey93 EE0000 red2 EE00EE magenta2 EE1289 DeepPink2 EE2C2C firebrick2 EE30A7 maroon2 EE3A8C VioletRed2 EE3B3B brown2 EE4000 OrangeRed2 EE5C42 tomato2 EE6363 IndianRed2 EE6A50 coral2 EE6AA7 HotPink2 EE7600 DarkOrange2 EE7621 chocolate2 EE7942 sienna2 EE799F PaleVioletRed2 EE7AE9 orchid2 EE8262 salmon2 EE82EE violet EE9572 LightSalmon2 EE9A00 orange2 EE9A49 tan2 EEA2AD LightPink2 EEA9B8 pink2 EEAD0E DarkGoldenrod2 EEAEEE plum2 EEB422 goldenrod2 EEB4B4 RosyBrown2 EEC591 burlywood2 EEC900 gold2 EECBAD PeachPuff2 EECFA1 NavajoWhite2 EED2EE thistle2 EED5B7 bisque2 EED5D2 MistyRose2 EED8AE wheat2 EEDC82 LightGoldenrod2 EEDD82 LightGoldenrod EEDD82 {light goldenrod} EEDFCC AntiqueWhite2 EEE0E5 LavenderBlush2 EEE5DE seashell2 EEE685 khaki2 EEE8AA PaleGoldenrod EEE8AA {pale goldenrod} EEE8CD cornsilk2 EEE9BF LemonChiffon2 EEE9E9 snow2 EEEE00 yellow2 EEEED1 LightYellow2 EEEEE0 ivory2 F08080 LightCoral F08080 {light coral} F0E68C khaki F0F0F0 gray94 F0F0F0 grey94 F0F8FF AliceBlue F0F8FF {alice blue} F0FFF0 honeydew F0FFF0 honeydew1 F0FFFF azure F0FFFF azure1 F2F2F2 gray95 F2F2F2 grey95 F4A460 SandyBrown F4A460 {sandy brown} F5DEB3 wheat F5F5DC beige F5F5F5 WhiteSmoke F5F5F5 gray96 F5F5F5 grey96 F5F5F5 {white smoke} F5FFFA MintCream F5FFFA {mint cream} F7F7F7 gray97 F7F7F7 grey97 F8F8FF GhostWhite F8F8FF {ghost white} FA8072 salmon FAEBD7 AntiqueWhite FAEBD7 {antique white} FAF0E6 linen FAFAD2 LightGoldenrodYellow FAFAD2 {light goldenrod yellow} FAFAFA gray98 FAFAFA grey98 FCFCFC gray99 FCFCFC grey99 FDF5E6 OldLace FDF5E6 {old lace} FF0000 red FF0000 red1 FF00FF magenta FF00FF magenta1 FF1493 DeepPink FF1493 DeepPink1 FF1493 {deep pink} FF3030 firebrick1 FF34B3 maroon1 FF3E96 VioletRed1 FF4040 brown1 FF4500 OrangeRed FF4500 OrangeRed1 FF4500 {orange red} FF6347 tomato FF6347 tomato1 FF69B4 HotPink FF69B4 {hot pink} FF6A6A IndianRed1 FF6EB4 HotPink1 FF7256 coral1 FF7F00 DarkOrange1 FF7F24 chocolate1 FF7F50 coral FF8247 sienna1 FF82AB PaleVioletRed1 FF83FA orchid1 FF8C00 DarkOrange FF8C00 {dark orange} FF8C69 salmon1 FFA07A LightSalmon FFA07A LightSalmon1 FFA07A {light salmon} FFA500 orange FFA500 orange1 FFA54F tan1 FFAEB9 LightPink1 FFB5C5 pink1 FFB6C1 LightPink FFB6C1 {light pink} FFB90F DarkGoldenrod1 FFBBFF plum1 FFC0CB pink FFC125 goldenrod1 FFC1C1 RosyBrown1 FFD39B burlywood1 FFD700 gold FFD700 gold1 FFDAB9 PeachPuff FFDAB9 PeachPuff1 FFDAB9 {peach puff} FFDEAD NavajoWhite FFDEAD NavajoWhite1 FFDEAD {navajo white} FFE1FF thistle1 FFE4B5 moccasin FFE4C4 bisque FFE4C4 bisque1 FFE4E1 MistyRose FFE4E1 MistyRose1 FFE4E1 {misty rose} FFE7BA wheat1 FFEBCD BlanchedAlmond FFEBCD {blanched almond} FFEC8B LightGoldenrod1 FFEFD5 PapayaWhip FFEFD5 {papaya whip} FFEFDB AntiqueWhite1 FFF0F5 LavenderBlush FFF0F5 LavenderBlush1 FFF0F5 {lavender blush} FFF5EE seashell FFF5EE seashell1 FFF68F khaki1 FFF8DC cornsilk FFF8DC cornsilk1 FFFACD LemonChiffon FFFACD LemonChiffon1 FFFACD {lemon chiffon} FFFAF0 FloralWhite FFFAF0 {floral white} FFFAFA snow FFFAFA snow1 FFFF00 yellow FFFF00 yellow1 FFFFE0 LightYellow FFFFE0 LightYellow1 FFFFE0 {light yellow} FFFFF0 ivory FFFFF0 ivory1 FFFFFF gray100 FFFFFF grey100 FFFFFF white } if { [file exists ../library] } { set blt_library ../library } set bg [blt::bgpattern create gradient -low grey100 -high grey90 \ -dir y -jitter yes -log yes -relativeto toplevel] set bg white set myIcon "" blt::combobutton .b \ -font { arial 10 bold } \ -textvariable myText1 \ -iconvariable myIcon1 \ -borderwidth 2 \ -highlightthickness 1 \ -arrowon yes \ -menu .b.m blt::table . \ 0,0 .b -fill both blt::combomenu .b.m \ -textvariable myText1 \ -height 400 \ -background $bg \ -iconvariable myIcon1 \ -font { Arial 9 bold } \ -acceleratorfont { Arial 8 } \ -yscrollbar .b.m.ybar \ -xscrollbar .b.m.xbar blt::tk::scrollbar .b.m.xbar blt::tk::scrollbar .b.m.ybar set bg [image create picture -width 30 -height 20] $bg blank 0x0000000 $bg draw rectangle 5 5 14 26 -color 0xFF00000 $bg blur $bg 4 foreach {rgb name} $colors { set icon [image create picture -width 25 -height 25] $icon blank 0x00000000 $icon draw circle 11 11 9 -fill \#$rgb -antialias yes \ -outline black -linewidth 1 -shadow 2 #$icon draw circle 10 10 2 -color black -antialias yes .b.m add -text $name -icon $icon } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/barchart5.tcl���������������������������������������������������������������0000755�0001750�0001750�00000002373�11462120062�015734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl source scripts/stipples.tcl option add *graph.x.Title "X Axis Label" option add *graph.y.Title "Y Axis Label" option add *graph.title "A Simple Barchart" option add *graph.Element.Relief raised blt::htext .htext -text \ { This is an example of the barchart widget. The barchart has many components; x and y axis, legend, crosshairs, elements, etc. To create a postscript file "bar.ps", press the %% set w $htext(widget) button $w.print -text {Print} -command { $graph postscript output bar.ps } $w append $w.print %% button. %% set graph [blt::barchart .htext.graph] $graph xaxis configure -stepsize 0 $w append $graph -fill both -padx 4 %% Hit the %% button $w.quit -text quit -command exit $w append $w.quit %% button when you've seen enough.%% label $w.logo -bitmap BLT $w append $w.logo -padx 20 %% } set tcl_precision 15 blt::vector create x blt::vector create y x seq -5.0 5.0 50 y expr sin(x) set barWidth 0.19 $graph element create sin -relief raised -bd 1 -x x -y y -barwidth $barWidth blt::table . .htext -fill both wm min . 0 0 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabnotebook3.tcl������������������������������������������������������������0000755�0001750�0001750�00000065402�11462120062�016455� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #blt::bltdebug 100 image create picture label1 -file user1.png image create picture label2 -file ./images/mini-book2.gif image create picture testImage -file ./images/txtrflag.gif blt::tabset .ts \ -scrollcommand { .s set } \ -scrollincrement 1 \ -scrolltabs yes label .ts.l -image testImage set attributes { "Graph \#1" pink "Graph \#2" lightblue "Graph \#3" orange "Graph \#5" yellow "Barchart \#2" green } foreach { label color } $attributes { .ts insert end $label \ -selectbackground ${color}3 \ -background ${color}3 \ -activebackground ${color}2 } foreach item [.ts configure] { if { [llength $item] == 5 } { set switch [lindex $item 0] set config($switch) [lindex $item 4] } } .ts insert end -selectbackground salmon2 -background salmon3 \ -selectbackground salmon3 -activebackground salmon2 -window .ts.l set tabLabels { Aarhus Aaron Ababa aback abaft abandon abandoned abandoning abandonment abandons abase abased abasement abasements abases abash abashed abashes abashing abasing abate abated abatement abatements abater abates abating Abba abbe abbey abbeys abbot abbots Abbott abbreviate abbreviated abbreviates abbreviating abbreviation abbreviations Abby abdomen abdomens abdominal abduct abducted abduction abductions abductor abductors abducts Abe abed Abel Abelian Abelson Aberdeen Abernathy aberrant aberration aberrations abet abets abetted abetter abetting abeyance abhor abhorred abhorrent abhorrer abhorring abhors abide abided abides abiding Abidjan Abigail Abilene abilities ability abject abjection abjections abjectly abjectness abjure abjured abjures abjuring ablate ablated ablates ablating } set extra { ablation ablative ablaze able abler ablest ably Abner abnormal abnormalities abnormality abnormally Abo aboard abode abodes abolish abolished abolisher abolishers abolishes abolishing abolishment abolishments abolition abolitionist abolitionists abominable abominate aboriginal aborigine aborigines abort aborted aborting abortion abortions abortive abortively aborts Abos abound abounded abounding abounds about above aboveboard aboveground abovementioned abrade abraded abrades abrading Abraham Abram Abrams Abramson abrasion abrasions abrasive abreaction abreactions abreast abridge abridged abridges abridging abridgment abroad abrogate abrogated abrogates abrogating abrupt abruptly abruptness abscess abscessed abscesses abscissa abscissas abscond absconded absconding absconds absence absences absent absented absentee absenteeism absentees absentia absenting absently absentminded absents absinthe absolute absolutely absoluteness absolutes absolution absolve absolved absolves absolving absorb absorbed absorbency absorbent absorber absorbing absorbs absorption absorptions absorptive abstain abstained abstainer abstaining abstains abstention abstentions abstinence abstract abstracted abstracting abstraction abstractionism abstractionist abstractions abstractly abstractness abstractor abstractors abstracts abstruse abstruseness absurd absurdities absurdity absurdly Abu abundance abundant abundantly abuse abused abuses abusing abusive abut abutment abuts abutted abutter abutters abutting abysmal abysmally abyss abysses Abyssinia Abyssinian Abyssinians acacia academia academic academically academics academies academy Acadia Acapulco accede acceded accedes accelerate accelerated accelerates accelerating acceleration accelerations accelerator accelerators accelerometer accelerometers accent accented accenting accents accentual accentuate accentuated accentuates accentuating accentuation accept acceptability acceptable acceptably acceptance acceptances accepted accepter accepters accepting acceptor acceptors accepts access accessed accesses accessibility accessible accessibly accessing accession accessions accessories accessors accessory accident accidental accidentally accidently accidents acclaim acclaimed acclaiming acclaims acclamation acclimate acclimated acclimates acclimating acclimatization acclimatized accolade accolades accommodate accommodated accommodates accommodating accommodation accommodations accompanied accompanies accompaniment accompaniments accompanist accompanists accompany accompanying accomplice accomplices accomplish accomplished accomplisher accomplishers accomplishes accomplishing accomplishment accomplishments accord accordance accorded accorder accorders according accordingly accordion accordions accords accost accosted accosting accosts account accountability accountable accountably accountancy accountant accountants accounted accounting accounts Accra accredit accreditation accreditations accredited accretion accretions accrue accrued accrues accruing acculturate acculturated acculturates acculturating acculturation accumulate accumulated accumulates accumulating accumulation accumulations accumulator accumulators accuracies accuracy accurate accurately accurateness accursed accusal accusation accusations accusative accuse accused accuser accuses accusing accusingly accustom accustomed accustoming accustoms ace aces acetate acetone acetylene Achaean Achaeans ache ached aches achievable achieve achieved achievement achievements achiever achievers achieves achieving Achilles aching acid acidic acidities acidity acidly acids acidulous Ackerman Ackley acknowledge acknowledgeable acknowledged acknowledgement acknowledgements acknowledger acknowledgers acknowledges acknowledging acknowledgment acknowledgments acme acne acolyte acolytes acorn acorns acoustic acoustical acoustically acoustician acoustics acquaint acquaintance acquaintances acquainted acquainting acquaints acquiesce acquiesced acquiescence acquiescent acquiesces acquiescing acquirable acquire acquired acquires acquiring acquisition acquisitions } foreach label $tabLabels { .ts insert end $label -image label1 } blt::tk::scrollbar .s -command { .ts view } -orient horizontal -borderwidth 1 blt::tk::label .side_l -text "-side" blt::combobutton .side -textvariable text(-side) -menu .side.m blt::combomenu .side.m -textvariable text(-side) array set side2rotate { top 0 bottom 0 left 90 right 270 } .side.m add -type radiobutton -text [.ts cget -side] .side.m add -type separator .side.m add -type radiobutton -text "top" .side.m add -type radiobutton -text "bottom" .side.m add -type radiobutton -text "left" .side.m add -type radiobutton -text "right" .side.m item configure all -variable config(-side) \ -command { .ts configure -side $config(-side) -rotate $side2rotate($config(-side)) } .side.m select 0 blt::tk::label .iconpos_l -text "-iconposition" blt::combobutton .iconpos -textvariable text(-iconposition) -menu .iconpos.m blt::combomenu .iconpos.m -textvariable text(-iconposition) .iconpos.m add -type radiobutton -text [.ts cget -iconposition] .iconpos.m add -type separator .iconpos.m add -type radiobutton -text "right" .iconpos.m add -type radiobutton -text "left" .iconpos.m add -type radiobutton -text "bottom" .iconpos.m add -type radiobutton -text "top" .iconpos.m item configure all -variable config(-iconposition) \ -command { .ts configure -iconposition $config(-iconposition) } .iconpos.m select 0 blt::tk::label .slant_l -text "-slant" blt::combobutton .slant -textvariable text(-slant) -menu .slant.m blt::combomenu .slant.m -textvariable text(-slant) .slant.m add -type radiobutton -text [.ts cget -slant] .slant.m add -type separator .slant.m add -type radiobutton -text "none" .slant.m add -type radiobutton -text "left" .slant.m add -type radiobutton -text "right" .slant.m add -type radiobutton -text "both" .slant.m item configure all -variable config(-slant) \ -command { .ts configure -slant $config(-slant) } .slant.m select 0 blt::tk::label .rotate_l -text "-rotate" blt::combobutton .rotate -textvariable rotatelabel -menu .rotate.m blt::combomenu .rotate.m -textvariable rotatelabel .rotate.m add -type radiobutton -text [.ts cget -rotate] .rotate.m add -type separator .rotate.m add -type radiobutton -text "0" .rotate.m add -type radiobutton -text "90" .rotate.m add -type radiobutton -text "180" .rotate.m add -type radiobutton -text "270" .rotate.m add -type radiobutton -text "30" .rotate.m item configure all -variable rotate \ -command { .ts configure -rotate $rotate } .rotate.m select 0 blt::tk::label .scrolltabs_l -text "-scrolltabs" blt::combobutton .scrolltabs -textvariable text(-scrolltabs) \ -menu .scrolltabs.m blt::combomenu .scrolltabs.m -textvariable text(-scrolltabs) .scrolltabs.m add -type radiobutton -text [.ts cget -scrolltabs] .scrolltabs.m add -type separator .scrolltabs.m add -type radiobutton -text "No" -value "0" .scrolltabs.m add -type radiobutton -text "Yes" -value "1" .scrolltabs.m item configure all -variable config(-scrolltabs) \ -command { .ts configure -scrolltabs $config(-scrolltabs) } .scrolltabs.m select 1 blt::tk::label .closebutton_l -text "-closebutton" blt::combobutton .closebutton -textvariable text(-closebutton) \ -menu .closebutton.m blt::combomenu .closebutton.m -textvariable text(-closebutton) .closebutton.m add -type radiobutton -text [.ts cget -closebutton] .closebutton.m add -type separator .closebutton.m add -type radiobutton -text "No" -value "0" .closebutton.m add -type radiobutton -text "Yes" -value "1" .closebutton.m item configure all -variable config(-closebutton) \ -command { .ts configure -closebutton $config(-closebutton) } .closebutton.m select 0 blt::tk::label .showsingletab_l -text "-showsingletab" blt::combobutton .showsingletab -textvariable text(-showsingletab) \ -menu .showsingletab.m blt::combomenu .showsingletab.m -textvariable text(-showsingletab) .showsingletab.m add -type radiobutton -text [.ts cget -showsingletab] .showsingletab.m add -type separator .showsingletab.m add -type radiobutton -text "No" -value "0" .showsingletab.m add -type radiobutton -text "Yes" -value "1" .showsingletab.m item configure all -variable config(-showsingletab) \ -command { .ts configure -showsingletab $config(-showsingletab) } .showsingletab.m select 0 blt::tk::label .tiers_l -text "-tiers" blt::combobutton .tiers -textvariable text(-tiers) -menu .tiers.m blt::combomenu .tiers.m -textvariable text(-tiers) .tiers.m add -type radiobutton -text [.ts cget -tiers] .tiers.m add -type separator .tiers.m add -type radiobutton -text "1" .tiers.m add -type radiobutton -text "2" .tiers.m add -type radiobutton -text "3" .tiers.m add -type radiobutton -text "4" .tiers.m add -type radiobutton -text "5" .tiers.m add -type radiobutton -text "10" .tiers.m item configure all -variable tiers \ -command { .ts configure -tiers $tiers } .tiers.m select 0 blt::tk::label .tabwidth_l -text "-tabwidth" blt::combobutton .tabwidth -textvariable text(-tabwidth) -menu .tabwidth.m blt::combomenu .tabwidth.m -textvariable text(-tabwidth) .tabwidth.m add -type radiobutton -text [.ts cget -tabwidth] .tabwidth.m add -type separator .tabwidth.m add -type radiobutton -text "variable" .tabwidth.m add -type radiobutton -text "same" .tabwidth.m add -type radiobutton -text ".5 inch" -value "0.5i" .tabwidth.m add -type radiobutton -text "1 inch" -value "1i" .tabwidth.m add -type radiobutton -text "2 inch" -value "2i" .tabwidth.m item configure all -variable config(-tabwidth) \ -command { .ts configure -tabwidth $config(-tabwidth) } .tabwidth.m select 0 blt::tk::label .justify_l -text "-justify" blt::combobutton .justify -textvariable text(-justify) -menu .justify.m blt::combomenu .justify.m -textvariable text(-justify) .justify.m add -type radiobutton -text [.ts cget -justify] .justify.m add -type separator .justify.m add -type radiobutton -text "left" .justify.m add -type radiobutton -text "center" .justify.m add -type radiobutton -text "right" .justify.m item configure all -variable config(-justify) \ -command { .ts configure -justify $config(-justify) } .justify.m select 0 blt::tk::label .tearoff_l -text "-tearoff" blt::combobutton .tearoff -textvariable text(-tearoff) -menu .tearoff.m blt::combomenu .tearoff.m -textvariable text(-tearoff) .tearoff.m add -type radiobutton -text [.ts cget -tearoff] .tearoff.m add -type separator .tearoff.m add -type radiobutton -text "No" -value "0" .tearoff.m add -type radiobutton -text "Yes" -value "1" .tearoff.m item configure all -variable config(-tearoff) \ -command { .ts configure -tearoff $config(-tearoff) } .tearoff.m select 0 blt::tk::label .highlightthickness_l -text "-highlightthickness" blt::combobutton .highlightthickness -textvariable text(-highlightthickness) \ -menu .highlightthickness.m blt::combomenu .highlightthickness.m -textvariable text(-highlightthickness) .highlightthickness.m add -type radiobutton -text [.ts cget -highlightthickness] .highlightthickness.m add -type separator .highlightthickness.m add -type radiobutton -text "0" .highlightthickness.m add -type radiobutton -text "1" .highlightthickness.m add -type radiobutton -text "2" .highlightthickness.m add -type radiobutton -text "3" .highlightthickness.m add -type radiobutton -text "10" .highlightthickness.m item configure all -variable config(-highlightthickness) \ -command { .ts configure -highlightthickness $config(-highlightthickness) } .highlightthickness.m select 0 blt::tk::label .outerpad_l -text "-outerpad" blt::combobutton .outerpad -textvariable text(-outerpad) -menu .outerpad.m blt::combomenu .outerpad.m -textvariable text(-outerpad) .outerpad.m add -type radiobutton -text [.ts cget -outerpad] .outerpad.m add -type separator .outerpad.m add -type radiobutton -text "0" .outerpad.m add -type radiobutton -text "1" .outerpad.m add -type radiobutton -text "2" .outerpad.m add -type radiobutton -text "3" .outerpad.m add -type radiobutton -text "10" .outerpad.m item configure all -variable config(-outerpad) \ -command { .ts configure -outerpad $config(-outerpad) } .outerpad.m select 0 blt::tk::label .borderwidth_l -text "-borderwidth" blt::combobutton .borderwidth -textvariable text(-borderwidth) \ -menu .borderwidth.m blt::combomenu .borderwidth.m -textvariable text(-borderwidth) .borderwidth.m add -type radiobutton -text [.ts cget -borderwidth] .borderwidth.m add -type separator .borderwidth.m add -type radiobutton -text "0" .borderwidth.m add -type radiobutton -text "1" .borderwidth.m add -type radiobutton -text "2" .borderwidth.m add -type radiobutton -text "3" .borderwidth.m add -type radiobutton -text "10" .borderwidth.m item configure all -variable config(-borderwidth) \ -command { .ts configure -borderwidth $config(-borderwidth) } .borderwidth.m select 0 blt::tk::label .gap_l -text "-gap" blt::combobutton .gap -textvariable text(-gap) -menu .gap.m blt::combomenu .gap.m -textvariable text(-gap) .gap.m add -type radiobutton -text [.ts cget -gap] .gap.m add -type separator .gap.m add -type radiobutton -text "0" .gap.m add -type radiobutton -text "1" .gap.m add -type radiobutton -text "2" .gap.m add -type radiobutton -text "3" .gap.m add -type radiobutton -text "10" .gap.m item configure all -variable config(-gap) \ -command { .ts configure -gap $config(-gap) } .gap.m select 0 blt::tk::label .relief_l -text "-relief" blt::combobutton .relief -textvariable text(-relief) -menu .relief.m blt::combomenu .relief.m -textvariable text(-relief) .relief.m add -type radiobutton -text [.ts cget -relief] .relief.m add -type separator .relief.m add -type radiobutton -text "flat" .relief.m add -type radiobutton -text "sunken" .relief.m add -type radiobutton -text "raised" .relief.m add -type radiobutton -text "groove" .relief.m add -type radiobutton -text "ridge" .relief.m add -type radiobutton -text "solid" .relief.m item configure all -variable config(-relief) \ -command { .ts configure -relief $config(-relief) } .relief.m select 0 blt::tk::label .background_l -text "-background" blt::combobutton .background -textvariable text(-background) \ -menu .background.m blt::combomenu .background.m -textvariable text(-background) .background.m add -type radiobutton -text [.ts cget -background] .background.m add -type separator .background.m add -type radiobutton -text "grey" .background.m add -type radiobutton -text "white" .background.m add -type radiobutton -text "black" .background.m add -type radiobutton -text "lightblue" .background.m item configure all -variable config(-background) \ -command { .ts configure -background $config(-background) } .background.m select 0 blt::tk::label .activebackground_l -text "-activebackground" blt::combobutton .activebackground -textvariable text(-activebackground) \ -menu .activebackground.m blt::combomenu .activebackground.m -textvariable text(-activebackground) .activebackground.m add -type radiobutton -text [.ts cget -activebackground] .activebackground.m add -type separator .activebackground.m add -type radiobutton -text "grey" .activebackground.m add -type radiobutton -text "white" .activebackground.m add -type radiobutton -text "black" .activebackground.m add -type radiobutton -text "lightblue" .activebackground.m item configure all -variable config(-activebackground) \ -command { .ts configure -activebackground $config(-activebackground) } .activebackground.m select 0 blt::tk::label .activeforeground_l -text "-activeforeground" blt::combobutton .activeforeground -textvariable text(-activeforeground) \ -menu .activeforeground.m blt::combomenu .activeforeground.m -textvariable text(-activeforeground) .activeforeground.m add -type radiobutton -text [.ts cget -activeforeground] .activeforeground.m add -type separator .activeforeground.m add -type radiobutton -text "grey" .activeforeground.m add -type radiobutton -text "white" .activeforeground.m add -type radiobutton -text "black" .activeforeground.m add -type radiobutton -text "lightblue" .activeforeground.m item configure all -variable config(-activeforeground) \ -command { .ts configure -activeforeground $config(-activeforeground) } .activeforeground.m select 0 blt::tk::label .selectbackground_l -text "-selectbackground" blt::combobutton .selectbackground -textvariable text(-selectbackground) \ -menu .selectbackground.m blt::combomenu .selectbackground.m -textvariable text(-selectbackground) .selectbackground.m add -type radiobutton -text [.ts cget -selectbackground] .selectbackground.m add -type separator .selectbackground.m add -type radiobutton -text "grey" .selectbackground.m add -type radiobutton -text "white" .selectbackground.m add -type radiobutton -text "black" .selectbackground.m add -type radiobutton -text "lightblue" .selectbackground.m item configure all -variable config(-selectbackground) \ -command { .ts configure -selectbackground $config(-selectbackground) } .selectbackground.m select 0 blt::tk::label .troughcolor_l -text "-troughcolor" blt::combobutton .troughcolor -textvariable text(-troughcolor) \ -menu .troughcolor.m blt::combomenu .troughcolor.m -textvariable text(-troughcolor) .troughcolor.m add -type radiobutton -text [.ts cget -troughcolor] .troughcolor.m add -type separator .troughcolor.m add -type radiobutton -text "grey" .troughcolor.m add -type radiobutton -text "white" .troughcolor.m add -type radiobutton -text "black" .troughcolor.m add -type radiobutton -text "lightblue" .troughcolor.m item configure all -variable config(-troughcolor) \ -command { .ts configure -troughcolor $config(-troughcolor) } .troughcolor.m select 0 blt::tk::label .foreground_l -text "-foreground" blt::combobutton .foreground -textvariable text(-foreground) \ -menu .foreground.m blt::combomenu .foreground.m -textvariable text(-foreground) .foreground.m add -type radiobutton -text [.ts cget -foreground] .foreground.m add -type separator .foreground.m add -type radiobutton -text "grey" .foreground.m add -type radiobutton -text "white" .foreground.m add -type radiobutton -text "black" .foreground.m add -type radiobutton -text "lightblue" .foreground.m item configure all -variable config(-foreground) \ -command { .ts configure -foreground $config(-foreground) } .foreground.m select 0 blt::tk::label .outerborderwidth_l -text "-outerborderwidth" blt::combobutton .outerborderwidth -textvariable text(-outerborderwidth) \ -menu .outerborderwidth.m blt::combomenu .outerborderwidth.m -textvariable text(-outerborderwidth) .outerborderwidth.m add -type radiobutton -text [.ts cget -outerborderwidth] .outerborderwidth.m add -type separator .outerborderwidth.m add -type radiobutton -text "0" .outerborderwidth.m add -type radiobutton -text "1" .outerborderwidth.m add -type radiobutton -text "2" .outerborderwidth.m add -type radiobutton -text "3" .outerborderwidth.m add -type radiobutton -text "10" .outerborderwidth.m item configure all -variable config(-outerborderwidth) \ -command { .ts configure -outerborderwidth $config(-outerborderwidth) } .outerborderwidth.m select 0 blt::tk::label .outerrelief_l -text "-outerrelief" blt::combobutton .outerrelief -textvariable text(-outerrelief) \ -menu .outerrelief.m blt::combomenu .outerrelief.m -textvariable text(-outerrelief) .outerrelief.m add -type radiobutton -text [.ts cget -outerrelief] .outerrelief.m add -type separator .outerrelief.m add -type radiobutton -text "flat" .outerrelief.m add -type radiobutton -text "sunken" .outerrelief.m add -type radiobutton -text "raised" .outerrelief.m add -type radiobutton -text "groove" .outerrelief.m add -type radiobutton -text "ridge" .outerrelief.m add -type radiobutton -text "solid" .outerrelief.m item configure all -variable config(-outerrelief) \ -command { .ts configure -outerrelief $config(-outerrelief) } .outerrelief.m select 0 blt::tk::label .selectforeground_l -text "-selectforeground" blt::combobutton .selectforeground -textvariable text(-selectforeground) \ -menu .selectforeground.m blt::combomenu .selectforeground.m -textvariable text(-selectforeground) .selectforeground.m add -type radiobutton -text [.ts cget -selectforeground] .selectforeground.m add -type separator .selectforeground.m add -type radiobutton -text "grey" .selectforeground.m add -type radiobutton -text "white" .selectforeground.m add -type radiobutton -text "black" .selectforeground.m add -type radiobutton -text "lightblue" .selectforeground.m item configure all -variable config(-selectforeground) \ -command { .ts configure -selectforeground $config(-selectforeground) } .selectforeground.m select 0 blt::tk::label .selectpadx_l -text "-selectpadx" blt::combobutton .selectpadx -textvariable text(-selectpadx) \ -menu .selectpadx.m blt::combomenu .selectpadx.m -textvariable text(-selectpadx) .selectpadx.m add -type radiobutton -text [.ts cget -selectpadx] .selectpadx.m add -type separator .selectpadx.m add -type radiobutton -text "0" .selectpadx.m add -type radiobutton -text "1" .selectpadx.m add -type radiobutton -text "2" .selectpadx.m add -type radiobutton -text "3" .selectpadx.m add -type radiobutton -text "10" .selectpadx.m item configure all -variable config(-selectpadx) \ -command { .ts configure -selectpadx $config(-selectpadx) } .selectpadx.m select 0 blt::tk::label .selectpady_l -text "-selectpady" blt::combobutton .selectpady -textvariable text(-selectpady) \ -menu .selectpady.m blt::combomenu .selectpady.m -textvariable text(-selectpady) .selectpady.m add -type radiobutton -text [.ts cget -selectpady] .selectpady.m add -type separator .selectpady.m add -type radiobutton -text "0" .selectpady.m add -type radiobutton -text "1" .selectpady.m add -type radiobutton -text "2" .selectpady.m add -type radiobutton -text "3" .selectpady.m add -type radiobutton -text "10" .selectpady.m item configure all -variable config(-selectpady) \ -command { .ts configure -selectpady $config(-selectpady) } .selectpady.m select 0 blt::table . \ .ts 0,0 -fill both -rspan 25 \ .activebackground_l 1,1 -anchor e \ .activebackground 1,2 -fill x \ .activeforeground_l 2,1 -anchor e \ .activeforeground 2,2 -fill x \ .background_l 3,1 -anchor e \ .background 3,2 -fill x \ .borderwidth_l 4,1 -anchor e \ .borderwidth 4,2 -fill x \ .gap_l 5,1 -anchor e \ .gap 5,2 -fill x \ .foreground_l 6,1 -anchor e \ .foreground 6,2 -fill x \ .highlightthickness_l 7,1 -anchor e \ .highlightthickness 7,2 -fill x \ .iconpos_l 8,1 -anchor e \ .iconpos 8,2 -fill x \ .justify_l 9,1 -anchor e \ .justify 9,2 -fill x \ .outerborderwidth_l 10,1 -anchor e \ .outerborderwidth 10,2 -fill x \ .outerpad_l 11,1 -anchor e \ .outerpad 11,2 -fill x \ .outerrelief_l 12,1 -anchor e \ .outerrelief 12,2 -fill x \ .relief_l 13,1 -anchor e \ .relief 13,2 -fill x \ .rotate_l 14,1 -anchor e \ .rotate 14,2 -fill x \ .scrolltabs_l 15,1 -anchor e \ .scrolltabs 15,2 -fill x \ .selectbackground_l 16,1 -anchor e \ .selectbackground 16,2 -fill x \ .selectforeground_l 17,1 -anchor e \ .selectforeground 17,2 -fill x \ .selectpadx_l 18,1 -anchor e \ .selectpadx 18,2 -fill x \ .selectpady_l 19,1 -anchor e \ .selectpady 19,2 -fill x \ .side_l 20,1 -anchor e \ .side 20,2 -fill x \ .closebutton_l 21,1 -anchor e \ .closebutton 21,2 -fill x \ .showsingletab_l 22,1 -anchor e \ .showsingletab 22,2 -fill x \ .slant_l 23,1 -anchor e \ .slant 23,2 -fill x \ .tabwidth_l 24,1 -anchor e \ .tabwidth 24,2 -fill x \ .tearoff_l 25,1 -anchor e \ .tearoff 25,2 -fill x \ .tiers_l 26,1 -anchor e \ .tiers 26,2 -fill x \ .troughcolor_l 27,1 -anchor e \ .troughcolor 27,2 -fill x \ .s 27,0 -fill x foreach option { borderwidth gap highlightthickness justify outerpad relief rotate side slant tabwidth tearoff tiers iconposition } { set $option [.ts cget -$option] } blt::table configure . r* c1 -resize none blt::table configure . r24 -resize expand focus .ts .ts focus 0 if 1 { set filecount 0 foreach file { graph1 graph2 graph3 graph5 barchart2 } { namespace eval $file { if { [string match graph* $file] } { set graph [blt::graph .ts.$file] } else { set graph [blt::barchart .ts.$file] } source scripts/$file.tcl .ts tab configure $filecount -window $graph -fill both incr filecount } } } .ts select 0 .ts activate 0 .ts focus 0 after 5000 { .ts tab configure 0 -state disabled } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/busy3.tcl�������������������������������������������������������������������0000755�0001750�0001750�00000014113�11462120062�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT #source scripts/demo.tcl set spcount 0 # # Script to test the "busy" command. # # # General widget class resource attributes # option add *Button.padX 10 option add *Button.padY 2 option add *Scale.relief sunken #option add *Scale.orient horizontal option add *Entry.relief sunken option add *Frame.borderWidth 2 set visual [winfo screenvisual .] if { $visual == "staticgray" || $visual == "grayscale" } { set activeBg black set normalBg white set bitmapFg black set bitmapBg white option add *f1.background white } else { set activeBg red set normalBg springgreen set bitmapFg blue set bitmapBg green option add *Button.background khaki2 option add *Button.activeBackground khaki1 option add *Frame.background khaki2 option add *f2.tile textureBg # option add *Button.tile textureBg option add *releaseButton.background limegreen option add *releaseButton.activeBackground springgreen option add *releaseButton.foreground black option add *holdButton.background red option add *holdButton.activeBackground pink option add *holdButton.foreground black option add *f1.background springgreen } # # Instance specific widget options # option add *f1.relief sunken option add *f1.background $normalBg option add *testButton.text "Test" option add *quitButton.text "Quit" option add *newButton.text "New button" option add *holdButton.text "Hold" option add *releaseButton.text "Release" option add *buttonLabel.text "Buttons" option add *entryLabel.text "Entries" option add *scaleLabel.text "Scales" option add *textLabel.text "Text" proc LoseFocus {} { focus -force . } proc KeepRaised { w } { bindtags $w keepRaised } bind keepRaised <Visibility> { raise %W } set file ./images/chalk.gif image create picture textureBg -file $file # # This never gets used; it's reset by the Animate proc. It's # here to just demonstrate how to set busy window options via # the host window path name # #option add *f1.busyCursor bogosity # # Counter for new buttons created by the "New button" button # set numWin 0 menu .menu .menu add command -label "First" .menu add command -label "Second" .menu add command -label "Third" .menu add command -label "Fourth" . configure -menu .menu # # Create two frames. The top frame will be the host window for the # busy window. It'll contain widgets to test the effectiveness of # the busy window. The bottom frame will contain buttons to # control the testing. # frame .f1 frame .f2 # # Create some widgets to test the busy window and its cursor # label .buttonLabel button .testButton -command { puts stdout "Not busy." } button .quitButton -command { exit } entry .entry scale .scale text .text -width 20 -height 4 # # The following buttons sit in the lower frame to control the demo # button .newButton -command { global numWin incr numWin set name button#${numWin} button .f1.$name -text "$name" \ -command [list .f1 configure -bg blue] blt::table .f1 \ .f1.$name $numWin+3,0 -padx 10 -pady 10 } set spinner [image create picture] button .holdButton -command { if { [blt::busy isbusy .f1] == "" } { global activeBg .f1 configure -bg $activeBg } blt::busy .f1 -opaque 1 -darken 50 -image $spinner blt::busy .#menu LoseFocus } button .releaseButton -command { if { [blt::busy isbusy .f1] == ".f1" } { blt::busy release .f1 blt::busy release .#menu } global normalBg .f1 configure -bg $normalBg } # # Notice that the widgets packed in .f1 and .f2 are not their children # blt::table .f1 \ .testButton 0,0 \ .scale 1,0 \ .entry 0,1 \ .text 1,1 -fill both \ .quitButton 2,0 blt::table .f2 \ .newButton 0,0 \ .holdButton 1,0 \ .releaseButton 2,0 blt::table configure .f1 .testButton .scale .entry .quitButton \ -padx 10 -pady 10 -fill both blt::table configure .f2 .newButton .holdButton .releaseButton \ -padx 10 -pady 10 blt::table configure .f2 c0 -resize none # # Finally, realize and map the top level window # blt::table . \ .f1 0,0 \ .f2 1,0 blt::table configure . .f1 .f2 -fill both # Initialize a list of bitmap file names which make up the animated # fish cursor. The bitmap mask files have a "m" appended to them. blt::table configure . r1 -resize none set bitmapList { left left1 mid right1 right } # # Simple cursor animation routine: Uses the "after" command to # circulate through a list of cursors every 0.075 seconds. The # first pass through the cursor list may appear sluggish because # the bitmaps have to be read from the disk. Tk's cursor cache # takes care of it afterwards. # proc StartAnimation { widget count } { global bitmapList set prefix "bitmaps/fish/[lindex $bitmapList $count]" set cursor [list @${prefix}.xbm ${prefix}m.xbm black white ] blt::busy configure $widget -cursor $cursor incr count global spinner global spcount set file [format ~/spinner%02d.png [incr spcount]] $spinner configure -file $file blt::busy configure .f1 -image $spinner puts stderr "changing to picture $file" update if { $spcount >= 30 } { set spcount 0 } set limit [llength $bitmapList] if { $count >= $limit } { set count 0 } global afterId set afterId($widget) [after 125 StartAnimation $widget $count] } proc StopAnimation { widget } { global afterId after cancel $afterId($widget) } proc TranslateBusy { window } { #set widget [string trimright $window "_Busy"] set widget [string trimright $window "Busy"] set widget [string trimright $widget "_"] # if { [winfo toplevel $widget] != $widget } { # set widget [string trimright $widget "."] # } return $widget } if { [info exists tcl_platform] && $tcl_platform(platform) == "unix" } { bind Busy <Map> { StartAnimation [TranslateBusy %W] 0 } bind Busy <Unmap> { StopAnimation [TranslateBusy %W] } } # # For testing, allow the top level window to be resized # wm min . 0 0 # # Force the demo to stay raised # raise . KeepRaised . �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�015030� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/graph3.tcl����������������������������������������������������������0000644�0001750�0001750�00000003646�11462120062�016735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������proc FormatAxisLabel {graph x} { return "[expr int($x)]\260" } set configOptions [subst { Axis.Hide no Axis.Limits "%g" BorderWidth 1 Element.Pixels 1.75m Element.ScaleSymbols no Legend.ActiveBorderWidth 2 Legend.ActiveRelief raised Legend.Anchor ne Legend.BorderWidth 0 Legend.Position plotarea Relief sunken Title "Sine and Cosine Functions" x.Command [namespace current]::FormatAxisLabel x.StepSize 90 x.Subdivisions 0 x.Title "X" y.Color purple2 y.Loose no y.Title "Y" y.rotate 90 y2.color magenta3 }] set resName [string trimleft $graph .] foreach { option value } $configOptions { option add *$resName.$option $value } $graph configure -leftvar changed set tcl_precision 15 set pi1_2 [expr 3.14159265358979323846/180.0] blt::vector create x sinX cosX -variable "" x seq -360 360 100 sinX expr { sin(x*$pi1_2) } cosX expr { cos(x*$pi1_2) } set s1 [image create picture -width 25 -height 25] $s1 blank 0x00000000 $s1 draw circle 12 12 5 -shadow 0 -linewidth 1 \ -fill 0x90FF0000 -antialias yes $graph element create line1 \ -label "sin(x)" \ -fill orange \ -color black \ -x x \ -y sinX \ -symbol $s1 set s2 [image create picture -width 25 -height 25] $s2 blank 0x00000000 $s2 draw circle 12 12 5 -shadow 0 -linewidth 1 \ -fill 0x900000F0 -antialias yes \ -outline orange set s2 splus $graph element create line2 \ -label "cos(x)" \ -color yellow4 \ -fill yellow \ -x x \ -y cosX \ -symbol $s2 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph #Blt_PrintKey $graph $graph marker create bitmap \ -name bg \ -coords "-360 -1 360 1" \ -bitmap @bitmaps/greenback.xbm \ -bg darkseagreen1 \ -fg darkseagreen3 \ -under yes \ -rotate 45 # -rotate 45 $graph postscript configure \ -landscape yes ������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/ps.tcl��������������������������������������������������������������0000644�0001750�0001750�00000060044�11462120062�016166� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#bltdebug 100 array set cursors { w left_side e right_side n top_side s bottom_side sw bottom_left_corner ne top_right_corner se bottom_right_corner nw top_left_corner } set paperSizes { "Letter (8 1/2 x 11 in.)" "i 8.5i 11i" "A3 (29.7 x 42 cm.)" "c 28.7c 41c" "A4 (21 x 29.7 cm.)" "c 21c 29.7c" "A5 (14.85 x 21 cm.)" "c 14.85c 21c" "Legal (8 1/2 x 14 in.)" "i 8.5i 14i" "Large (11 x 17 in.)" "i 11i 17i" } array set paperSize $paperSizes array set pageInfo { gripSize 8 scale 0.25 radioFont -*-helvetica-medium-r-*-*-11-120-*-*-*-*-*-* labelFont "Arial 10 bold" printCmd "nlp -d2a211" printFile "out.ps" units "i" uscale 1.0 } proc ApplyWhenIdle { } { global pageInfo set data [$pageInfo(graph) postscript output] puts stderr "landscape= [$pageInfo(graph) postscript cget -landscape]" $pageInfo(image) import ps -data $data -crop no puts stderr "writing out2.ps" $pageInfo(graph) postscript output -file out2.ps unset pageInfo(afterId) } proc SetUnits { units } { global pageInfo switch -glob $units { "i*" { set pageInfo(uscale) [winfo fpixels . 1i] } "c*" { set pageInfo(uscale) [winfo fpixels . 1c] } default { error "unknown unit \"$units\"" } } set pageInfo(units) [string index $units 0] } proc ConvertUnits { value } { global pageInfo set value [expr double($value) / $pageInfo(uscale)] return [format "%.1f%s" $value $pageInfo(units)] } proc SetPaperSize {} { global pageInfo set extents $pageInfo(paperExtents) foreach { unit w h } $extents break SetUnits $unit set pageInfo(-paperwidth) $w set pageInfo(-paperheight) $h ApplyPs } proc SetCanvasSize { canvas width height } { global pageInfo set width [winfo pixels . $width] set height [winfo pixels . $height] $canvas configure -width $width -height $height } proc SetCanvasOrientation { canvas } { global pageInfo set width $pageInfo(paperWidth) set height $pageInfo(paperHeight) SetCanvasSize $canvas $width $height } proc GetPsOptions { graph } { global pageInfo foreach opt [$graph postscript configure] { set pageInfo([lindex $opt 0]) [lindex $opt 4] } } proc SetOutline { canvas } { global pageInfo foreach var { gripSize xMin yMin xMax yMax } { set $var $pageInfo($var) } set xMid [expr ($xMax + $xMin - $gripSize) * 0.5] set yMid [expr ($yMax + $yMin - $gripSize) * 0.5] $canvas coords image $xMin $yMin $canvas itemconfigure image \ -width [expr $xMax - $xMin] -height [expr $yMax - $yMin] $canvas coords nw \ $xMin $yMin [expr $xMin + $gripSize] [expr $yMin + $gripSize] $canvas coords se \ [expr $xMax - $gripSize] [expr $yMax - $gripSize] $xMax $yMax $canvas coords ne \ [expr $xMax - $gripSize] [expr $yMin + $gripSize] $xMax $yMin $canvas coords sw \ $xMin $yMax [expr $xMin + $gripSize] [expr $yMax - $gripSize] SetCanvasOrientation $canvas $canvas coords n \ $xMid $yMin [expr $xMid + $gripSize] [expr $yMin + $gripSize] $canvas coords s \ $xMid [expr $yMax - $gripSize] [expr $xMid + $gripSize] $yMax $canvas coords e \ [expr $xMax - $gripSize] $yMid $xMax [expr $yMid + $gripSize] $canvas coords w \ $xMin $yMid [expr $xMin + $gripSize] [expr $yMid + $gripSize] } proc CreateOutline { canvas } { global pageInfo foreach var { gripSize xMin yMin xMax yMax } { set $var $pageInfo($var) } if { ![blt::bitmap exists pattern8] } { blt::bitmap define pattern8 { {8 8} {ff 00 ff 00 ff 00 ff 00 } } } $canvas create eps $xMin $yMin \ -tags "outline image" \ -width [expr $xMax - $xMin] \ -height [expr $yMax - $yMin] $canvas bind image <ButtonPress-1> "StartMove $canvas %x %y" $canvas bind image <B1-Motion> "MoveOutline $canvas %x %y" $canvas bind image <ButtonRelease-1> "EndMove $canvas" $canvas bind image <Shift-B1-Motion> "ConstrainMoveOutline $canvas %x %y" $canvas bind image <Enter> "EnterImage $canvas" $canvas bind image <Leave> "LeaveImage $canvas" focus $canvas $canvas create rectangle \ $xMin $yMin [expr $xMin + $gripSize] [expr $yMin + $gripSize] \ -tags "outline grip nw" $canvas create rectangle \ [expr $xMax - $gripSize] [expr $yMax - $gripSize] $xMax $yMax \ -tags "outline grip se" $canvas create rectangle \ [expr $xMax - $gripSize] [expr $yMin + $gripSize] $xMax $yMin \ -tags "outline grip ne" $canvas create rectangle \ $xMin $yMax [expr $xMin + $gripSize] [expr $yMax - $gripSize] \ -tags "outline grip sw" set xMid [expr ($xMax + $xMin - $gripSize) * 0.5] set yMid [expr ($yMax + $yMin - $gripSize) * 0.5] $canvas create rectangle \ $xMid $yMin [expr $xMid + $gripSize] [expr $yMin + $gripSize] \ -tags "outline grip n" $canvas create rectangle \ $xMid [expr $yMax - $gripSize] [expr $xMid + $gripSize] $yMax \ -tags "outline grip s" $canvas create rectangle \ [expr $xMax - $gripSize] $yMid $xMax [expr $yMid + $gripSize] \ -tags "outline grip e" $canvas create rectangle \ $xMin $yMid [expr $xMin + $gripSize] [expr $yMid + $gripSize] \ -tags "outline grip w" foreach grip { e w s n sw ne se nw } { $canvas bind $grip <ButtonPress-1> "StartResize %W $grip %x %y" $canvas bind $grip <B1-Motion> "ResizeOutline %W %x %y" $canvas bind $grip <ButtonRelease-1> "EndResize %W $grip %x %y" $canvas bind $grip <Enter> "EnterGrip %W $grip %x %y" $canvas bind $grip <Leave> "LeaveGrip %W $grip" } $canvas raise grip $canvas itemconfigure grip -fill red -outline black set pageInfo(image) [image create picture] set data [$pageInfo(graph) postscript output] $pageInfo(image) import ps -data $data -crop no $canvas itemconfigure image -image $pageInfo(image) $pageInfo(graph) postscript output out2.ps } proc EnterImage { canvas } { global cursors global pageInfo bind $canvas <KeyPress-Left> { MoveOutline %W [expr $pageInfo(lastX) - 1] $pageInfo(lastY) } bind $canvas <KeyPress-Right> { MoveOutline %W [expr $pageInfo(lastX) + 1] $pageInfo(lastY) } bind $canvas <KeyPress-Up> { MoveOutline %W $pageInfo(lastX) [expr $pageInfo(lastY) - 1] } bind $canvas <KeyPress-Down> { MoveOutline %W $pageInfo(lastX) [expr $pageInfo(lastY) + 1] } focus $canvas $canvas configure -cursor fleur set pageInfo(lastX) 0 set pageInfo(lastY) 0 } proc LeaveImage { canvas } { bind $canvas <KeyPress-Left> "" bind $canvas <KeyPress-Right> "" bind $canvas <KeyPress-Up> "" bind $canvas <KeyPress-Down> "" $canvas configure -cursor "" } proc EnterGrip { canvas grip x y } { global pageInfo $canvas itemconfigure $grip -fill blue -outline black set pageInfo(grip) $grip global cursors bind $canvas <KeyPress-Left> { ResizeOutline %W [expr $pageInfo(lastX) - 1] $pageInfo(lastY) } bind $canvas <KeyPress-Right> { ResizeOutline %W [expr $pageInfo(lastX) + 1] $pageInfo(lastY) } bind $canvas <KeyPress-Up> { ResizeOutline %W $pageInfo(lastX) [expr $pageInfo(lastY) - 1] } bind $canvas <KeyPress-Down> { ResizeOutline %W $pageInfo(lastX) [expr $pageInfo(lastY) + 1] } focus $canvas $canvas configure -cursor $cursors($grip) set pageInfo(lastX) $x set pageInfo(lastY) $y } proc LeaveGrip { canvas grip } { $canvas itemconfigure $grip -fill red -outline black bind $canvas <KeyPress-Left> "" bind $canvas <KeyPress-Right> "" bind $canvas <KeyPress-Up> "" bind $canvas <KeyPress-Down> "" $canvas configure -cursor "" } proc StartMove { canvas x y } { global pageInfo set pageInfo(lastX) $x set pageInfo(lastY) $y set pageInfo(direction) "undecided" $canvas configure -cursor fleur } proc MoveOutline { canvas x y } { global pageInfo $canvas move outline [expr $x - $pageInfo(lastX)] [expr $y - $pageInfo(lastY)] set pageInfo(lastX) $x set pageInfo(lastY) $y } proc ConstrainMoveOutline { canvas x y } { global pageInfo set dx [expr $x - $pageInfo(lastX)] set dy [expr $y - $pageInfo(lastY)] if { $pageInfo(direction) == "undecided" } { if { abs($dx) > abs($dy) } { set pageInfo(direction) x $canvas configure -cursor sb_h_double_arrow } else { set pageInfo(direction) y $canvas configure -cursor sb_v_double_arrow } } switch $pageInfo(direction) { x { set dy 0 ; set pageInfo(lastX) $x } y { set dx 0 ; set pageInfo(lastY) $y } } $canvas move outline $dx $dy } proc EndMove { canvas } { $canvas configure -cursor "" set coords [$canvas coords image] set x [lindex $coords 0] set y [lindex $coords 1] set w [$canvas itemcget image -width] set h [$canvas itemcget image -height] global pageInfo set pageInfo(xMin) $x set pageInfo(xMin) $y set pageInfo(xMax) [expr $x + $w] set pageInfo(yMax) [expr $y + $h] global pageInfo set pageInfo(-padx) [list $pageInfo(xMin) [expr $pageInfo(paperWidth) - $pageInfo(xMax)]] set pageInfo(-pady) [list $pageInfo(yMin) [expr $pageInfo(paperHeight) - $pageInfo(yMax)]] } proc StartResize { canvas grip x y } { global pageInfo $canvas itemconfigure image -quick yes set pageInfo(grip) $grip $canvas itemconfigure $grip -fill red -outline black $canvas raise grip global cursors $canvas configure -cursor $cursors($grip) set pageInfo(lastX) $x set pageInfo(lastY) $y } proc EndResize { canvas grip x y } { $canvas itemconfigure image -quick no ResizeOutline $canvas $x $y $canvas itemconfigure $grip -fill "" -outline "" $canvas configure -cursor "" } proc ResizeOutline { canvas x y } { global pageInfo foreach var { gripSize xMin yMin xMax yMax } { set $var $pageInfo($var) } switch $pageInfo(grip) { n { set yMin $y } s { set yMax $y } e { set xMax $x } w { set xMin $x } sw { set xMin $x ; set yMax $y } ne { set xMax $x ; set yMin $y } se { set xMax $x ; set yMax $y } nw { set xMin $x ; set yMin $y } } set width [expr $xMax - $xMin] set height [expr $yMax - $yMin] if { ($width < 1) || ($height < 1) } { return } SetOutline $canvas foreach var { xMin yMin xMax yMax } { set pageInfo($var) [set $var] } } proc ComputePlotGeometry { graph } { global pageInfo GetPsOptions $graph set width [winfo width $graph] set height [winfo height $graph] if { $pageInfo(-width) > 0 } { set width $pageInfo(-width) } if { $pageInfo(-height) > 0 } { set height $pageInfo(-height) } set left [lindex $pageInfo(-padx) 0] set right [lindex $pageInfo(-padx) 1] set top [lindex $pageInfo(-pady) 0] set bottom [lindex $pageInfo(-pady) 1] set padx [expr $left + $right] set pady [expr $top + $bottom] if { $pageInfo(-paperwidth) > 0 } { set paperWidth $pageInfo(-paperwidth) } else { set paperWidth [expr $width + $padx] } if { $pageInfo(-paperheight) > 0 } { set paperHeight $pageInfo(-paperheight) } else { set paperHeight [expr $height + $pady] } set scale 1.0 if { $pageInfo(-maxpect) } { set xScale [expr ($paperWidth - $padx) / double($width)] set yScale [expr ($paperHeight - $pady) / double($height)] set scale [expr min($xScale,$yScale)] set bboxWidth [expr round($width * $scale)] set bboxHeight [expr round($height * $scale)] } else { if { ($width + $padx) > $paperWidth } { set width [expr $paperWidth - $padx] } if { ($height + $pady) > $paperHeight } { set height [expr $paperHeight - $pady] } set bboxWidth $width set bboxHeight $height } set x $left set y $top if { $pageInfo(-center) } { if { $paperWidth > $bboxWidth } { set x [expr ($paperWidth - $bboxWidth) / 2] } if { $paperHeight > $bboxHeight } { set y [expr ($paperHeight - $bboxHeight) / 2] } } set pageInfo(xMin) [expr $x * $pageInfo(scale)] set pageInfo(yMin) [expr $y * $pageInfo(scale)] set pageInfo(xMax) [expr ($x + $bboxWidth) * $pageInfo(scale)] set pageInfo(yMax) [expr ($y + $bboxHeight) * $pageInfo(scale)] set pageInfo(paperHeight) [expr $paperHeight * $pageInfo(scale)] set pageInfo(paperWidth) [expr $paperWidth * $pageInfo(scale)] } proc PsDialog { graph } { global pageInfo paperSizes set pageInfo(graph) $graph set top $graph.top toplevel $top option add *graph.top*Radiobutton.font $pageInfo(radioFont) GetPsOptions $graph ComputePlotGeometry $graph set canvas $top.layout canvas $canvas -confine yes \ -width $pageInfo(paperWidth) -height $pageInfo(paperHeight) -bg gray \ -bd 2 -relief sunken CreateOutline $canvas SetCanvasOrientation $canvas blt::tk::label $top.titleLabel -text "PostScript Options" blt::table $top \ 0,0 $top.titleLabel -cspan 7 \ 1,0 $canvas -cspan 7 set row 2 set col 0 blt::tk::label $top.paperLabel -text "Paper" -font "Arial 10 bold" blt::combobutton $top.paper \ -textvariable pageInfo(paperSize) \ -font { Arial 10 } \ -menu $top.paper.m set menu [blt::combomenu $top.paper.m -textvariable pageInfo(paperSize)] foreach { key value } $paperSizes { $menu add -type command -text $key -value $value } $menu item configure command -variable pageInfo(paperExtents) \ -command "SetPaperSize" set pageInfo(paperSize) [lindex $paperSizes 0] blt::table $top \ $row,$col $top.paperLabel -anchor e \ $row,$col+1 $top.paper -anchor e -fill x incr row blt::tk::label $top.orientLabel -text "Orientation" -font "Arial 10 bold" blt::combobutton $top.orient \ -textvariable pageInfo(orient) \ -font { Arial 10 } \ -menu $top.orient.m set menu [blt::combomenu $top.orient.m -textvariable pageInfo(orient)] $menu add -type command -text "Portrait" -value "0" \ -variable pageInfo(-landscape) -command "ApplyPs" $menu add -type command -text "Landscape" -value "1" \ -variable pageInfo(-landscape) -command "ApplyPs" set pageInfo(orient) "Landscape" set pageInfo(-landscape) 1 blt::table $top \ $row,$col $top.orientLabel -anchor e \ $row,$col+1 $top.orient -anchor e -fill x incr row set col 0 incr row blt::tk::label $top.sizeLabel -text "Plot Size" -font "Arial 10 bold" blt::combobutton $top.plotsize \ -textvariable pageInfo(plotsize) \ -font { Arial 10 } \ -menu $top.plotsize.m set menu [blt::combomenu $top.plotsize.m -textvariable pageInfo(plotsize)] $menu add -type command -text "Default" -value "default" \ -variable pageInfo(-plotsize) -command "SetPlotSize" $menu add -type command -text "Max Aspect" -value "maxpect" \ -variable pageInfo(-plotsize) -command "SetPlotSize" $menu add -type command -text "Small (3.25 in x 3.25 in)" -value "small" \ -variable pageInfo(-plotsize) -command "SetPlotSize" $menu add -type command -text "Large (6 in x 8 in)" -value "large" \ -variable pageInfo(-plotsize) -command "SetPlotSize" $menu add -type command -text "Other" -value "other" \ -variable pageInfo(-plotsize) \ -command "SizeDialog $graph {Adjust Plot Size}" set pageInfo(plotsize) "Default" blt::table $top \ $row,$col $top.sizeLabel -anchor e \ $row,$col+1 $top.plotsize -anchor e -fill x incr row blt::tk::label $top.modeLabel -text "Color mode" -font "Arial 10 bold" blt::combobutton $top.colormode \ -textvariable pageInfo(colormode) \ -font { Arial 10 } \ -menu $top.colormode.m set menu [blt::combomenu $top.colormode.m -textvariable pageInfo(colormode)] $menu add -type command -text "Full Color" -value "0" \ -variable pageInfo(-greyscale) -command "ApplyPs" $menu add -type command -text "Greyscale" -value "1" \ -variable pageInfo(-greyscale) -command "ApplyPs" set pageInfo(colormode) "Full Color" blt::table $top \ $row,$col $top.modeLabel -anchor e \ $row,$col+1 $top.colormode -anchor e -fill x incr row set pageInfo(oldPadX) $pageInfo(-padx) set pageInfo(oldPadY) $pageInfo(-pady) blt::tk::label $top.posLabel -text "Position" -font "Arial 10 bold" blt::combobutton $top.position \ -textvariable pageInfo(position) \ -font { Arial 10 } \ -menu $top.position.m set menu [blt::combomenu $top.position.m -textvariable pageInfo(position)] $menu add -type command -text "Center" -value "1" \ -variable pageInfo(-position) -command { CenterPlot } $menu add -type command -text "Origin" -value "0" \ -variable pageInfo(-position) -command { ApplyPs } $menu add -type command -text "Move" -value "move" \ -variable pageInfo(-position) -command { MoveDialog } set pageInfo(position) "Center" blt::table $top \ $row,$col $top.posLabel -anchor e \ $row,$col+1 $top.position -anchor e -fill x incr row blt::tk::label $top.previewLabel -text "Preview" -font "Arial 10 bold" blt::combobutton $top.preview \ -textvariable pageInfo(preview) \ -font { Arial 10 } \ -menu $top.preview.m set pageInfo(preview) "No" set menu [blt::combomenu $top.preview.m -textvariable pageInfo(preview)] $menu add -type command -text "Yes" -value "1" \ -variable pageInfo(-preview) -command "ApplyPs" $menu add -type command -text "No" -value "0" \ -variable pageInfo(-preview) -command "ApplyPs" blt::table $top \ $row,$col $top.previewLabel -anchor e \ $row,$col+1 $top.preview -anchor e -fill x incr row blt::tk::label $top.printLabel -text "Print To" -font "Arial 10 bold" blt::combobutton $top.printer \ -textvariable pageInfo(printer) \ -font { Arial 10 } -justify left \ -menu $top.printer.m set menu [blt::combomenu $top.printer.m -textvariable pageInfo(printer)] $menu add -type command -text "File" -value "printFile" \ -command "$top.fileEntry configure -textvariable pageInfo(printCmd)" \ -variable pageInfo(printTo) $menu add -type command -text "Command" -value "printCmd" \ -command "$top.fileEntry configure -textvariable pageInfo(printCmd)" \ -variable pageInfo(printTo) entry $top.fileEntry -textvariable pageInfo(printTo) $menu invoke "File" blt::table $top \ $row,$col $top.printLabel -anchor e \ $row,$col+1 $top.printer -anchor e -fill x \ $row+1,1 $top.fileEntry -anchor w -fill x -cspan 3 incr row 2 #blt::table configure $top c4 -width .125i frame $top.frame button $top.frame.cancel -text "Cancel" -command "destroy $top" button $top.frame.print -text "Ok" -command "PrintPs $graph" blt::table $top.frame \ 0,0 $top.frame.cancel -width 0.5i \ 0,1 $top.frame.print -width 0.5i blt::table $top \ $row,$col $top.frame -fill x -columnspan 2 blt::table configure $top r* -resize none -pady { 0 2 } blt::table configure $top r1 -resize both } proc PrintPs { graph } { $graph postscript output "out.ps" puts stdout "wrote file \"out.ps\"." flush stdout } proc ApplyPs { } { global pageInfo set graph $pageInfo(graph) foreach option [$graph postscript configure] { set var [lindex $option 0] set old [lindex $option 4] if { [catch {$graph postscript configure $var $pageInfo($var)}] != 0 } { $graph postscript configure $var $old set pageInfo($var) $old } } ComputePlotGeometry $graph foreach var { -paperheight -paperwidth -width -height } { set pageInfo($var) [ConvertUnits $pageInfo($var)] } SetOutline $graph.top.layout if { ![info exists pageInfo(afterId)] } { set pageInfo(afterId) [after idle ApplyWhenIdle] } } proc StartChange { w delta } { ChangeSize $w $delta global pageInfo set pageInfo(afterId) [after 300 RepeatChange $w $delta] } proc RepeatChange { w delta } { ChangeSize $w $delta global pageInfo set pageInfo(afterId) [after 100 RepeatChange $w $delta] } proc EndChange { w } { global pageInfo after cancel $pageInfo(afterId) } proc ChangeSize { w delta } { set f [winfo parent $w] set value [$f.entry get] set value [expr $value + $delta] if { $value < 0 } { set value 1 } $f.entry delete 0 end $f.entry insert 0 $value } proc MakeSizeAdjustor { w label var } { frame $w label $w.label -text $label button $w.plus -text "+" -padx 1 -pady 0 -font \*symbol\* entry $w.entry -width 6 -textvariable "pageInfo($var)" button $w.minus -text "-" -padx 1 -pady 0 -font \*symbol\* label $w.units -text "in" bind $w.plus <ButtonPress-1> { StartChange %W 0.1} bind $w.plus <ButtonRelease-1> { EndChange %W } bind $w.minus <ButtonPress-1> { StartChange %W -0.1} bind $w.minus <ButtonRelease-1> { EndChange %W } blt::table $w \ 0,1 $w.label \ 1,1 $w.entry -rspan 2 -fill y \ 1,0 $w.minus -padx 2 -pady 2 \ 2,0 $w.plus -padx 2 -pady { 0 2 } \ 1,2 $w.units -rspan 2 -fill y } proc SizeDialog { graph title } { global pageInfo set top .plotSize if { [winfo exists $top] } { return } toplevel $top label $top.title -text $title button $top.cancel -text "Cancel" -command "destroy $top" button $top.ok -text "Ok" -command "ApplyPs; destroy $top" MakeSizeAdjustor $top.plotWidth "Width" -width MakeSizeAdjustor $top.plotHeight "Height" -height blt::table $top \ 0,0 $top.title -cspan 2 \ 1,0 $top.plotWidth \ 1,1 $top.plotHeight \ 2,0 $top.cancel -pady 4 -padx 4 -width 1i \ 2,1 $top.ok -pady 4 -padx 4 -width 1i set width [winfo fpixels . $pageInfo(-width)] set height [winfo fpixels . $pageInfo(-height)] if { $width == 0 } { set width [expr ($pageInfo(xMax) - $pageInfo(xMin)) / $pageInfo(scale)] set pageInfo(-width) [ConvertUnits $width] } if { $height == 0 } { set height [expr ($pageInfo(yMax) - $pageInfo(yMin)) / $pageInfo(scale)] set pageInfo(-height) [ConvertUnits $height] } set pageInfo(-maxpect) 0 } proc SetPlotSize { } { global pageInfo set graph $pageInfo(graph) switch $pageInfo(-plotsize) { default { set pageInfo(-width) 0 set pageInfo(-height) 0 set pageInfo(-maxpect) 0 set pageInfo(-padx) $pageInfo(oldPadX) set pageInfo(-pady) $pageInfo(oldPadY) } maxpect { set pageInfo(-width) 0 set pageInfo(-height) 0 set pageInfo(-maxpect) 1 set pageInfo(-padx) $pageInfo(oldPadX) set pageInfo(-pady) $pageInfo(oldPadY) } resize { set pageInfo(-maxpect) 0 } } ApplyPs } proc PaperSizeDialog { title } { set top .paperSize if { [winfo exists $top] } { return } toplevel $top label $top.title -text $title MakeSizeAdjustor $top.width "Width" -paperwidth MakeSizeAdjustor $top.height "Height" -paperheight button $top.cancel -text "Cancel" -command "destroy $top" button $top.ok -text "Ok" -command "ApplyPs; destroy $top" blt::table $top \ 0,0 $top.title -cspan 2 \ 1,0 $top.width \ 1,1 $top.height \ 2,0 $top.cancel -pady 4 -padx 4 -width 1i \ 2,1 $top.ok -pady 4 -padx 4 -width 1i } proc MarginDialog { graph } { set top $graph.top.options if { [winfo exists $top] } { return } toplevel $top set row 0 set col 0 label $top.modeLabel -text "Printer" radiobutton $top.color -text "Color" -value "color" \ -variable pageInfo(-colormode) -command "ApplyPs" radiobutton $top.greyscale -text "Greyscale" -value "greyscale" \ -variable pageInfo(-colormode) -command "ApplyPs" blt::table $top \ $row,$col $top.modeLabel -anchor e \ $row,$col+1 $top.color -anchor w \ $row+1,$col+1 $top.greyscale -anchor w blt::table configure $top r$row -pady { 4 0 } label $top.previewLabel -text "Preview" radiobutton $top.previewYes -text "Yes" -value "1" \ -variable pageInfo(-preview) -command "ApplyPs" radiobutton $top.previewNo -text "No" -value "0" \ -variable pageInfo(-preview) -command "ApplyPs" set col 2 blt::table $top \ $row,$col $top.previewLabel -anchor e \ $row,$col+1 $top.previewYes -anchor w \ $row+1,$col+1 $top.previewNo -anchor w incr row 2 button $top.cancel -text "Cancel" -command "destroy $top" button $top.ok -text "Done" -command "PrintPs $graph" blt::table $top \ $row,0 $top.cancel -pady 4 -padx 4 -width 1i \ $row,1 $top.ok -pady 4 -padx 4 -width 1i } proc CenterPlot { } { global pageInfo set pageInfo(-padx) $pageInfo(oldPadX) set pageInfo(-pady) $pageInfo(oldPadY) ApplyPs } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/barchart2.tcl�������������������������������������������������������0000644�0001750�0001750�00000006523�11462120062�017416� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� proc FormatXTicks { w value } { # Determine the element name from the value set index [expr round($value)] if { $index != $value } { return $value } incr index -1 set name [lindex { A1 B1 A2 B2 C1 D1 C2 A3 E1 } $index] return $name } source scripts/patterns.tcl image create picture bgTexture -file ./images/chalk.gif set configOptions { Axis.TickFont -*-helvetica-medium-r-*-*-12-*-* Axis.TitleFont -*-helvetica-bold-r-*-*-12-*-* Element.Background white Element.Relief raised Grid.Dashes { 2 4 } Grid.Hide no Grid.MapX "" Legend.Font "-*-helvetica*-bold-r-*-*-12-*-*" Legend.ActiveBorderWidth 2 Legend.ActiveRelief raised Legend.Anchor ne Legend.BorderWidth 0 Legend.Position right TextMarker.Font *Helvetica-Bold-R*14* activeBar.Foreground black activeBar.Stipple pattern1 BarMode stacked Font -*-helvetica-bold-r-*-*-14-*-* Tile bgTexture Title "Comparison of Simulators" x.Command FormatXTicks x.Title "Simulator" y.Title "Time (hrs)" } set resource [string trimleft $graph .] foreach { option value } $configOptions { option add *$resource.$option $value } $graph configure -barmode stacked set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *print.background yellow option add *quit.background red option add *quit.activeBackground red2 } blt::vector X Y0 Y1 Y2 Y3 Y4 X set { 1 2 3 4 5 6 7 8 9 } Y0 set { 0.729111111 0.002250000 0.09108333 0.006416667 0.026509167 0.007027778 0.1628611 0.06405278 0.08786667 } Y1 set { 0.003120278 0.004638889 0.01113889 0.048888889 0.001814722 0.291388889 0.0503500 0.13876389 0.04513333 } Y2 set { 11.534444444 3.879722222 4.54444444 4.460277778 2.334055556 1.262194444 1.8009444 4.12194444 3.24527778 } Y3 set { 1.015750000 0.462888889 0.49394444 0.429166667 1.053694444 0.466111111 1.4152500 2.17538889 2.55294444 } Y4 set { 0.022018611 0.516333333 0.54772222 0.177638889 0.021703889 0.134305556 0.5189278 0.07957222 0.41155556 } # # Element attributes: # # Label yData Color Stipple Pattern set attributes { "Load" Y2 lightblue pattern1 "Other" Y4 lightpink pattern1 1 "Read In" Y0 lightgoldenrod pattern1 1 "Setup" Y1 lightyellow pattern2 1 } set attributes { "Load" Y2 lightblue1 lightblue3 pattern1 1 "Solve" Y3 cyan1 cyan3 pattern2 1 "zOther" Y4 lightpink1 lightpink3 pattern1 1 "Read In" Y0 lightgoldenrod1 lightgoldenrod3 pattern1 1 "Setup" Y1 lightyellow1 lightyellow3 pattern2 1 } foreach {label yData fg bg stipple bd} $attributes { $graph element create $yData \ -label $label \ -borderwidth $bd \ -y $yData \ -x X \ -fg $fg \ -bg $bg \ -stipple $stipple } Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph $graph marker bind all <B2-Motion> { set coords [%W invtransform %x %y] catch { %W marker configure [%W marker get current] -coords $coords } } $graph marker bind all <Enter> { set marker [%W marker get current] catch { %W marker configure $marker -bg green} } $graph marker bind all <Leave> { set marker [%W marker get current] catch { %W marker configure $marker -bg ""} } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/patterns.tcl��������������������������������������������������������0000644�0001750�0001750�00000001462�11462120062�017403� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������blt::bitmap define pattern1 { {4 4} {01 02 04 08} } blt::bitmap define pattern2 { {4 4} {08 04 02 01} } blt::bitmap define pattern3 { {2 2} {01 02 } } blt::bitmap define pattern4 { {4 4} {0f 00 00 00} } blt::bitmap define pattern5 { {4 4} {01 01 01 01} } blt::bitmap define pattern6 { {2 2} {01 00 } } blt::bitmap define pattern7 { {4 4} {0f 01 01 01} } blt::bitmap define pattern8 { {8 8} {ff 00 ff 00 ff 00 ff 00 } } blt::bitmap define pattern9 { {4 4} {03 03 0c 0c} } blt::bitmap define hobbes { {25 25} { 00 00 00 00 00 00 00 00 00 c0 03 00 78 e0 07 00 fc f8 07 00 cc 07 04 00 0c f0 0b 00 7c 1c 06 00 38 00 00 00 e0 03 10 00 e0 41 11 00 20 40 11 00 e0 07 10 00 e0 c1 17 00 10 e0 2f 00 20 e0 6f 00 18 e0 2f 00 20 c6 67 00 18 84 2b 00 20 08 64 00 70 f0 13 00 80 01 08 00 00 fe 07 00 00 00 00 00 00 00 00 00 } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/stipples.tcl��������������������������������������������������������0000644�0001750�0001750�00000007317�11462120062�017413� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������blt::bitmap define bdiagonal1 { #define bdiagonal1_width 8 #define bdiagonal1_height 8 static unsigned char bdiagonal1_bits[] = { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11}; } blt::bitmap define bdiagonal2 { #define bdiagonal2_width 8 #define bdiagonal2_height 8 static unsigned char bdiagonal2_bits[] = { 0x08, 0x04, 0x02, 0x01, 0x80, 0x40, 0x20, 0x10}; } blt::bitmap define checker2 { #define checker2_width 8 #define checker2_height 8 static unsigned char checker2_bits[] = { 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc}; } blt::bitmap define checker3 { #define checker3_width 8 #define checker3_height 8 static unsigned char checker3_bits[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0}; } blt::bitmap define cross1 { #define cross1_width 8 #define cross1_height 8 static unsigned char cross_bits[] = { 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa}; } blt::bitmap define cross2 { #define cross2_width 8 #define cross2_height 8 static unsigned char cross2_bits[] = { 0xff, 0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88}; } blt::bitmap define cross3 { #define cross3_width 8 #define cross3_height 8 static unsigned char cross3_bits[] = { 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; } blt::bitmap define crossdiag { #define crossdiag_width 8 #define crossdiag_height 8 static unsigned char crossdiag2_bits[] = { 0x18, 0x24, 0x42, 0x81, 0x81, 0x42, 0x24, 0x18}; } blt::bitmap define dot1 { #define dot1_width 8 #define dot1_height 8 static unsigned char dot1_bits[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa}; } blt::bitmap define dot2 { #define dot2_width 8 #define dot2_height 8 static unsigned char dot2_bits[] = { 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00}; } blt::bitmap define dot3 { #define dot3_width 8 #define dot3_height 8 static unsigned char dot3_bits[] = { 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00}; } blt::bitmap define dot4 { #define dot4_width 8 #define dot4_height 8 static unsigned char dot4_bits[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } blt::bitmap define fdiagonal1 { #define fdiagonal1_width 8 #define fdiagonal1_height 8 static unsigned char fdiagonal1_bits[] = { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}; } blt::bitmap define fdiagonal2 { #define fdiagonal2_width 8 #define fdiagonal2_height 8 static unsigned char fdiagonal2_bits[] = { 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08}; } blt::bitmap define hline1 { #define hline1_width 8 #define hline1_height 8 static unsigned char hline1_bits[] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00}; } blt::bitmap define hline2 { #define hline2_width 8 #define hline2_height 8 static unsigned char hline2_bits[] = { 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00}; } blt::bitmap define lbottom { #define lbottom_width 8 #define lbottom_height 8 static unsigned char lbottom_bits[] = { 0x00, 0x11, 0x11, 0x77, 0x00, 0x11, 0x11, 0x77}; } blt::bitmap define ltop { #define ltop_width 8 #define ltop_height 8 static unsigned char ltop_bits[] = { 0xee, 0x88, 0x88, 0x00, 0xee, 0x88, 0x88, 0x00}; } blt::bitmap define rbottom { #define rbottom_width 8 #define rbottom_height 8 static unsigned char rbottom_bits[] = { 0x00, 0x88, 0x88, 0xee, 0x00, 0x88, 0x88, 0xee}; } blt::bitmap define rtop { #define rtop_width 8 #define rtop_height 8 static unsigned char rtop_bits[] = { 0x77, 0x11, 0x11, 0x00, 0x77, 0x11, 0x11, 0x00}; } blt::bitmap define vline1 { #define vline1_width 8 #define vline1_height 8 static unsigned char vline1_bits[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; } blt::bitmap define vline2 { #define vline2_width 8 #define vline2_height 8 static unsigned char vline2_bits[] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33}; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/graph8.tcl����������������������������������������������������������0000644�0001750�0001750�00000005264�11462120062�016740� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set X { 2.00000e-01 4.00000e-01 6.00000e-01 8.00000e-01 1.00000e+00 1.20000e+00 1.40000e+00 1.60000e+00 1.80000e+00 2.00000e+00 2.20000e+00 2.40000e+00 2.60000e+00 2.80000e+00 3.00000e+00 3.20000e+00 3.40000e+00 3.60000e+00 3.80000e+00 4.00000e+00 4.20000e+00 4.40000e+00 4.60000e+00 4.80000e+00 5.00000e+00 } set Y1 { 1.14471e+01 2.09373e+01 2.84608e+01 3.40080e+01 3.75691e+01 3.91345e+01 3.92706e+01 3.93474e+01 3.94242e+01 3.95010e+01 3.95778e+01 3.96545e+01 3.97313e+01 3.98081e+01 3.98849e+01 3.99617e+01 4.00384e+01 4.01152e+01 4.01920e+01 4.02688e+01 4.03455e+01 4.04223e+01 4.04990e+01 4.05758e+01 4.06526e+01 } set Y2 { 2.61825e+01 5.04696e+01 7.28517e+01 9.33192e+01 1.11863e+02 1.28473e+02 1.43140e+02 1.55854e+02 1.66606e+02 1.75386e+02 1.82185e+02 1.86994e+02 1.89802e+02 1.90683e+02 1.91047e+02 1.91411e+02 1.91775e+02 1.92139e+02 1.92503e+02 1.92867e+02 1.93231e+02 1.93595e+02 1.93958e+02 1.94322e+02 1.94686e+02 } set Y3 { 4.07008e+01 7.95658e+01 1.16585e+02 1.51750e+02 1.85051e+02 2.16479e+02 2.46024e+02 2.73676e+02 2.99427e+02 3.23267e+02 3.45187e+02 3.65177e+02 3.83228e+02 3.99331e+02 4.13476e+02 4.25655e+02 4.35856e+02 4.44073e+02 4.50294e+02 4.54512e+02 4.56716e+02 4.57596e+02 4.58448e+02 4.59299e+02 4.60151e+02 } proc FormatLabel { w value } { return $value } #option add *Graph.aspect 1.25 option add *Graph.title "A Simple X-Y Graph" option add *Graph.x.loose yes option add *Graph.x.title "X Axis Label" option add *Graph.y.title "Y Axis Label" option add *Graph.y.rotate 90 option add *Graph.y.logScale yes option add *Graph.y.loose no option add *Graph.Axis.titleFont {Times 18 bold} option add *Legend.activeRelief sunken option add *Legend.background "" option add *Legend.activeBackground khaki2 option add *Graph.background brown option add *Element.xData $X option add *activeLine.Color yellow4 option add *activeLine.Fill yellow option add *Element.smooth natural option add *Element.pixels 6 option add *Element.scaleSymbols yes option add *Graph.line1.symbol circle option add *Graph.line1.color red4 option add *Graph.line1.fill red1 option add *Graph.line2.symbol square option add *Graph.line2.color purple4 option add *Graph.line2.fill purple1 option add *Graph.line3.symbol triangle option add *Graph.line3.color green4 option add *Graph.line3.fill green1 $graph configure \ -width 4i \ -height 5i $graph element create line1 \ -ydata $Y2 $graph element create line2 \ -ydata $Y3 $graph element create line3 \ -ydata $Y1 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/demo.tcl������������������������������������������������������������0000644�0001750�0001750�00000001466�11462120062�016473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------------------- # # The following code is solely a convenience so that you can test the # BLT distribution without first installing it. # # ---------------------------------------------------------------------------- # If we're in the ./demos directory, we can simply specify # "../library" as the library directory without having to install the # files. if { [file exists ../library/bltGraph.pro] } { global blt_library set blt_library ../library set auto_path [linsert $auto_path 0 $blt_library] auto_reset } # Add a binding for convenience to let you exit with pressing the # "quit" button. wm protocol . WM_DELETE_WINDOW { DoExit 0 } bind all <Control-KeyPress-c> { DoExit 0 } proc DoExit { code } { #destroy . exit $code } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/globe.tcl�����������������������������������������������������������0000644�0001750�0001750�00000066237�11462120062�016646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������blt::bitmap define globe.0 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x40, 0x02, 0x00, 0x00, 0x1c, 0x3c, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x80, 0x80, 0xfe, 0x03, 0x60, 0x00, 0xff, 0x07, 0x10, 0xc0, 0xf1, 0x0f, 0x00, 0x80, 0xc0, 0x1f, 0x00, 0xc0, 0x07, 0x3f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x4f, 0x02, 0xf0, 0xff, 0x5d, 0x00, 0xf0, 0xff, 0x1b, 0x00, 0xf0, 0xff, 0x8f, 0x02, 0xf0, 0xff, 0x0f, 0x06, 0xe0, 0xfc, 0x0f, 0x0e, 0x00, 0xf8, 0x0f, 0x0f, 0x00, 0xf8, 0x07, 0x3f, 0x00, 0xf8, 0x03, 0x7e, 0x00, 0xf0, 0x03, 0x7e, 0x00, 0xf0, 0x03, 0x3e, 0x00, 0xf0, 0x0b, 0x3c, 0x00, 0xf0, 0x09, 0x3c, 0x00, 0xf0, 0x01, 0x18, 0x00, 0xf0, 0x00, 0x18, 0x00, 0x70, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00}; } blt::bitmap define globe.1 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0xc0, 0x00, 0x00, 0x00, 0x34, 0x38, 0x00, 0x00, 0x02, 0xe8, 0x00, 0x80, 0x01, 0xfa, 0x03, 0xe0, 0x00, 0xfc, 0x07, 0x30, 0x00, 0xe6, 0x0f, 0x10, 0x00, 0x86, 0x1f, 0x08, 0x00, 0x3e, 0x3c, 0x04, 0x00, 0xff, 0x3f, 0x04, 0x80, 0xff, 0x5f, 0x02, 0x80, 0xff, 0x3f, 0x00, 0x80, 0xff, 0x2f, 0x00, 0x80, 0xff, 0x3f, 0x0c, 0x00, 0xff, 0x3f, 0x1c, 0x00, 0xee, 0x3f, 0x3c, 0x00, 0xc0, 0x3f, 0x7e, 0x00, 0xc0, 0x1f, 0xfe, 0x01, 0x80, 0x1f, 0xfc, 0x03, 0x80, 0x1f, 0xfc, 0x01, 0x80, 0x1f, 0xfc, 0x01, 0x80, 0x2f, 0xf8, 0x01, 0x80, 0x0f, 0xf0, 0x00, 0x80, 0x17, 0xf0, 0x00, 0x80, 0x03, 0xf0, 0x00, 0x80, 0x03, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00}; } blt::bitmap define globe.2 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0xc0, 0x01, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x80, 0x07, 0xe0, 0x03, 0xe0, 0x01, 0xf0, 0x07, 0xf0, 0x00, 0x38, 0x0f, 0x30, 0x00, 0x10, 0x1e, 0x18, 0x00, 0xf0, 0x30, 0x04, 0x00, 0xf8, 0x3f, 0x10, 0x00, 0xf8, 0x7f, 0x12, 0x00, 0xfc, 0x7f, 0x02, 0x00, 0xfc, 0x7f, 0x04, 0x00, 0xfc, 0x7f, 0x74, 0x00, 0xf8, 0x7f, 0xf0, 0x00, 0x70, 0x7f, 0xf8, 0x01, 0x00, 0x7e, 0xf8, 0x03, 0x00, 0x7e, 0xf8, 0x0f, 0x00, 0x7c, 0xf8, 0x1f, 0x00, 0x3c, 0xf0, 0x1f, 0x00, 0x3c, 0xf0, 0x0f, 0x00, 0x3e, 0xe0, 0x0f, 0x00, 0x5e, 0xc0, 0x07, 0x00, 0x1c, 0xc0, 0x03, 0x00, 0x0e, 0xc0, 0x03, 0x00, 0x04, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1c, 0x00}; } blt::bitmap define globe.3 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0xc0, 0x01, 0x00, 0x00, 0xdc, 0x20, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x80, 0x1f, 0xa0, 0x03, 0xe0, 0x07, 0xc0, 0x07, 0xf0, 0x01, 0xc0, 0x0c, 0xf8, 0x00, 0x40, 0x18, 0x78, 0x00, 0xc0, 0x23, 0x08, 0x00, 0xc0, 0x3f, 0x04, 0x00, 0xe0, 0x7f, 0x54, 0x00, 0xe0, 0x7f, 0x0c, 0x00, 0xc0, 0x7f, 0x10, 0x00, 0xc0, 0xff, 0xd0, 0x01, 0xc0, 0xff, 0xc0, 0x03, 0x80, 0xfb, 0xe0, 0x0f, 0x00, 0xf0, 0xe0, 0x1f, 0x00, 0xf0, 0xe0, 0xff, 0x00, 0xf0, 0xe0, 0xff, 0x00, 0x70, 0xc0, 0xff, 0x00, 0x70, 0xc0, 0x7f, 0x00, 0x70, 0x00, 0x7f, 0x00, 0x70, 0x00, 0x3f, 0x00, 0x30, 0x00, 0x1f, 0x00, 0x38, 0x00, 0x1f, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00}; } blt::bitmap define globe.4 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0xc0, 0x03, 0x00, 0x00, 0x7c, 0x03, 0x00, 0x00, 0x13, 0x00, 0x00, 0x80, 0x7f, 0xc0, 0x03, 0xc0, 0x1f, 0x00, 0x07, 0xe0, 0x0f, 0x00, 0x0d, 0xf0, 0x03, 0x00, 0x10, 0xf0, 0x01, 0x00, 0x0e, 0x38, 0x01, 0x00, 0x3e, 0x10, 0x00, 0x00, 0x7f, 0x50, 0x00, 0x00, 0x7f, 0x30, 0x00, 0x00, 0x7f, 0x40, 0x00, 0x00, 0xff, 0x00, 0x1e, 0x00, 0xfe, 0x00, 0x3f, 0x00, 0xec, 0x00, 0x7f, 0x00, 0xc0, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xff, 0x07, 0xc0, 0x00, 0xff, 0x0f, 0xc0, 0x00, 0xfe, 0x07, 0xc0, 0x00, 0xfe, 0x07, 0xc0, 0x00, 0xf8, 0x03, 0x40, 0x00, 0xf8, 0x01, 0x60, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xf8, 0x00, 0x20, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00}; } blt::bitmap define globe.5 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0xc0, 0x03, 0x00, 0x00, 0xbc, 0x06, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x80, 0xff, 0x01, 0x02, 0xc0, 0x7f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x0e, 0xe0, 0x1f, 0x00, 0x14, 0xe0, 0x0f, 0x00, 0x18, 0xe0, 0x00, 0x00, 0x38, 0x60, 0x00, 0x00, 0x78, 0x40, 0x08, 0x00, 0x78, 0xc0, 0x01, 0x00, 0x78, 0x00, 0x02, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x00, 0xf8, 0x07, 0x80, 0x00, 0xf8, 0x0f, 0x80, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0xf0, 0x3f, 0x80, 0x00, 0xf0, 0x3f, 0x80, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x07, 0x40, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00}; } blt::bitmap define globe.6 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x80, 0x07, 0x00, 0x00, 0x7c, 0x0d, 0x00, 0x00, 0x9f, 0x03, 0x00, 0x00, 0xff, 0x07, 0x02, 0x00, 0xff, 0x03, 0x04, 0x80, 0xff, 0x00, 0x08, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x30, 0x80, 0x07, 0x00, 0x20, 0x00, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0x60, 0x00, 0x0e, 0x00, 0x60, 0x00, 0x10, 0x00, 0xe0, 0x00, 0x80, 0x07, 0xc0, 0x00, 0x80, 0x0f, 0xc0, 0x00, 0x80, 0x3f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; } blt::bitmap define globe.7 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x80, 0x07, 0x00, 0x00, 0xfc, 0x1a, 0x00, 0x00, 0x7d, 0x02, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x01, 0x20, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x18, 0x00, 0x40, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}; } blt::bitmap define globe.8 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x07, 0x00, 0x00, 0xfc, 0x25, 0x00, 0x00, 0xf8, 0x19, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}; } blt::bitmap define globe.9 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x03, 0x00, 0x00, 0xfc, 0x27, 0x00, 0x00, 0xf0, 0x13, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0x47, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}; } blt::bitmap define globe.10 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x06, 0x00, 0x00, 0xf4, 0x2f, 0x00, 0x00, 0xc8, 0x4f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x04, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00}; } blt::bitmap define globe.11 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x06, 0x00, 0x00, 0xec, 0x1f, 0x00, 0x00, 0x91, 0x9f, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00}; } blt::bitmap define globe.12 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x04, 0x00, 0x00, 0xdc, 0x3f, 0x00, 0x00, 0x42, 0x7e, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x20, 0x00, 0xf0, 0x07, 0x10, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } blt::bitmap define globe.13 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x04, 0x00, 0x00, 0xbc, 0x3f, 0x00, 0x00, 0x01, 0x79, 0x00, 0x80, 0x00, 0xe0, 0x03, 0x60, 0x00, 0xc0, 0x07, 0x10, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1f, 0x08, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00}; } blt::bitmap define globe.14 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x03, 0xe6, 0x00, 0x80, 0x01, 0xc0, 0x03, 0x60, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x38, 0x04, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00}; } blt::bitmap define globe.15 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3d, 0x00, 0x00, 0x27, 0xc8, 0x00, 0x80, 0x13, 0x00, 0x03, 0xe0, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00}; } blt::bitmap define globe.16 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3b, 0x00, 0x00, 0x9f, 0xa0, 0x00, 0x80, 0x4f, 0x00, 0x02, 0xe0, 0x0f, 0x00, 0x04, 0xf0, 0x01, 0x00, 0x08, 0x70, 0x00, 0x00, 0x10, 0x38, 0x00, 0x00, 0x20, 0x3c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00}; } blt::bitmap define globe.17 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x37, 0x00, 0x00, 0x3f, 0x42, 0x00, 0x80, 0x3f, 0x01, 0x02, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf0, 0x11, 0x00, 0x00, 0xf8, 0x04, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x08, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00}; } blt::bitmap define globe.18 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0x84, 0x00, 0x80, 0xff, 0x04, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0xf0, 0x9f, 0x00, 0x00, 0xf0, 0x97, 0x00, 0x00, 0xf8, 0x27, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x60, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x05, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00}; } blt::bitmap define globe.19 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x40, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0x13, 0x00, 0x80, 0xff, 0x13, 0x00, 0xe0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0x9f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xba, 0x07, 0x00, 0x00, 0x98, 0x23, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00}; } blt::bitmap define globe.20 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x80, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x13, 0x00, 0xf0, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xe6, 0x1e, 0x00, 0x00, 0x62, 0x1c, 0x01, 0x00, 0x20, 0x18, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0x68, 0x08, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00}; } blt::bitmap define globe.21 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x80, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x80, 0xff, 0xbf, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xf8, 0xff, 0x17, 0x00, 0xf8, 0xff, 0x27, 0x00, 0xec, 0xff, 0x0f, 0x00, 0x8c, 0xff, 0x07, 0x00, 0x9e, 0xf7, 0x00, 0x00, 0x0e, 0xe3, 0x00, 0x00, 0x06, 0xc1, 0x00, 0x00, 0x06, 0x81, 0x10, 0x00, 0x03, 0x40, 0x04, 0x00, 0x03, 0x20, 0x06, 0x00, 0x03, 0x40, 0x06, 0x00, 0x01, 0x80, 0x00, 0x03, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.22 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x80, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x3f, 0x00, 0x34, 0xfe, 0x3f, 0x00, 0x76, 0xbc, 0x07, 0x00, 0x36, 0x1c, 0x07, 0x00, 0x0e, 0x08, 0x0e, 0x00, 0x1e, 0x08, 0x80, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x07, 0x00, 0x36, 0x00, 0x07, 0x00, 0x04, 0x08, 0x07, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0b, 0x16, 0x00, 0x80, 0x0f, 0x04, 0x00, 0xe0, 0x0f, 0x04, 0x00, 0xe0, 0x0f, 0x08, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.23 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x80, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0x01, 0xe8, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0x01, 0xdc, 0xf2, 0xff, 0x01, 0xde, 0xe3, 0x3d, 0x00, 0xde, 0xe1, 0x38, 0x02, 0x7e, 0x40, 0x70, 0x00, 0xfe, 0x40, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x30, 0x01, 0x3e, 0x00, 0xa0, 0x01, 0x1e, 0x00, 0x20, 0x20, 0x1e, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 0x3e, 0x1c, 0x00, 0x00, 0x3f, 0x18, 0x00, 0x80, 0x3f, 0x10, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.24 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x80, 0xff, 0xff, 0x01, 0xc0, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03, 0x18, 0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0x07, 0x7c, 0x87, 0xff, 0x07, 0xfe, 0x1f, 0xef, 0x01, 0xfe, 0x0e, 0xc6, 0x01, 0xfe, 0x01, 0x82, 0x03, 0xfe, 0x03, 0x02, 0x00, 0xff, 0x03, 0x00, 0x08, 0xfc, 0x01, 0x80, 0x09, 0xfc, 0x00, 0x00, 0x0d, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x80, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x20, 0x78, 0x02, 0x00, 0x70, 0x70, 0x02, 0x00, 0x7c, 0x70, 0x00, 0x00, 0x3c, 0x60, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.25 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x80, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0x07, 0xa0, 0xff, 0xff, 0x07, 0x10, 0xff, 0xff, 0x07, 0x30, 0xf8, 0xff, 0x0f, 0xf8, 0xdf, 0xff, 0x1f, 0xfc, 0x3b, 0xfc, 0x1f, 0xfc, 0xfb, 0x78, 0x07, 0xfe, 0x77, 0x30, 0x0e, 0xfe, 0x1f, 0x30, 0x0c, 0xfe, 0x3f, 0x00, 0x48, 0xfe, 0x1f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x24, 0xf0, 0x07, 0x00, 0xa0, 0xf0, 0x07, 0x00, 0x08, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x27, 0x00, 0xc0, 0xe0, 0x13, 0x00, 0x40, 0xc0, 0x13, 0x00, 0x70, 0xc0, 0x03, 0x00, 0x70, 0x80, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.26 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xff, 0xff, 0x07, 0xc0, 0xfe, 0xff, 0x0f, 0x40, 0xf0, 0xff, 0x1f, 0xe0, 0xe0, 0xff, 0x1f, 0xf0, 0xff, 0xfe, 0x3f, 0xf8, 0xdf, 0xe1, 0x3f, 0xf8, 0xdf, 0xc7, 0x1b, 0xfc, 0xbf, 0x83, 0x19, 0xfc, 0xff, 0x80, 0x30, 0xfc, 0xff, 0x01, 0x20, 0xf8, 0xff, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0xe0, 0x80, 0x3f, 0x00, 0x20, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x80, 0x80, 0x9f, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x40, 0x00, 0x0f, 0x00, 0x60, 0x00, 0x0e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00}; } blt::bitmap define globe.27 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x80, 0x00, 0x00, 0x00, 0xc4, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xeb, 0xff, 0x0f, 0x80, 0xc9, 0xff, 0x1f, 0x80, 0x07, 0xff, 0x3f, 0xc0, 0xff, 0xf7, 0x3f, 0xe0, 0xff, 0x0e, 0x7f, 0xf0, 0xff, 0x3e, 0x6e, 0xf0, 0xff, 0x1d, 0x64, 0xf0, 0xff, 0x07, 0x44, 0xf0, 0xff, 0x0f, 0x00, 0x60, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0x40, 0x00, 0xfe, 0x03, 0x00, 0x01, 0xfc, 0x01, 0x00, 0x01, 0xfc, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfc, 0x09, 0x00, 0x02, 0xfc, 0x08, 0x00, 0x00, 0xf8, 0x04, 0x00, 0x00, 0x78, 0x00, 0x40, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00}; } blt::bitmap define globe.28 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x3f, 0x00, 0x00, 0x40, 0xff, 0x00, 0x00, 0xe8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x8c, 0xff, 0x0f, 0x00, 0x06, 0xfe, 0x1f, 0x00, 0x1e, 0xf8, 0x3f, 0x00, 0xff, 0xbf, 0x3f, 0x80, 0xff, 0x77, 0x7c, 0x80, 0xff, 0xff, 0x79, 0xc0, 0xff, 0xef, 0x10, 0xc0, 0xff, 0x3f, 0x90, 0xc0, 0xff, 0x7f, 0x00, 0x81, 0xfb, 0x7f, 0x00, 0x01, 0xf0, 0x3f, 0x00, 0x01, 0xf0, 0x1f, 0x00, 0x03, 0xe0, 0x1f, 0x00, 0x07, 0xe0, 0x0f, 0x00, 0x02, 0xc0, 0x1f, 0x00, 0x02, 0xe0, 0x5f, 0x00, 0x06, 0xe0, 0x47, 0x00, 0x04, 0xc0, 0x27, 0x00, 0x04, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00}; } blt::bitmap define globe.29 { #define globe_width 32 #define globe_height 32 static char globe_bits[] = { 0x00, 0x40, 0x01, 0x00, 0x00, 0x0c, 0x3f, 0x00, 0x00, 0x80, 0xfd, 0x00, 0x00, 0xa0, 0xff, 0x03, 0x20, 0xe0, 0xff, 0x07, 0x00, 0x30, 0xfd, 0x0f, 0x00, 0x10, 0xf4, 0x1f, 0x00, 0xf8, 0xc0, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xfc, 0xbf, 0x73, 0x00, 0xfe, 0xff, 0x67, 0x00, 0xfe, 0x7f, 0x47, 0x00, 0xfe, 0xff, 0x41, 0x00, 0xfe, 0xff, 0x03, 0x01, 0xdc, 0xff, 0x03, 0x03, 0x00, 0xff, 0x01, 0x07, 0x80, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x1f, 0x00, 0x7e, 0x00, 0x0e, 0x00, 0xfe, 0x00, 0x0e, 0x00, 0xff, 0x02, 0x0e, 0x00, 0x3f, 0x01, 0x0c, 0x00, 0x3e, 0x01, 0x0c, 0x00, 0x1e, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00}; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/page.tcl������������������������������������������������������������0000755�0001750�0001750�00000005556�11462120062�016472� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/local/bin/tclsh array set page " rows 2 columns 2 padx 0.5 pady 0.5 width 8.5 height 11 gutter 0.25 " proc Pica { dist } { expr $dist * 72.0 } # ------------------------------------------------------------------ # # TileFiles # # Tiles graph postscript files together in a pre-defined # grid. # # Arguments: # outFile -- Resulting tiled PostScript output file. # args -- Names of input graph PostScript files. # # ------------------------------------------------------------------ proc TileFiles { outFile args } { global page set row 0 set column 0 set padx [Pica $page(padx)] set pady [Pica $page(padx)] set width [Pica $page(width)] set height [Pica $page(height)] set gutter [Pica $page(gutter)] set totalGutters [expr $gutter * ($page(columns) - 1)] set w [expr $width - (2 * $padx) - $totalGutters] set totalGutters [expr $gutter * ($page(rows) - 1)] set h [expr $height - (2 * $pady) - $totalGutters] set cellWidth [expr double($w) / $page(columns)] set cellHeight [expr double($h) / $page(rows)] set out [open $outFile "w"] puts $out "%!PS-Adobe-3.0 EPSF-3.0" puts $out "%%Pages: 1" puts $out "%%Title: (Graph tiler)" puts $out "%%DocumentNeededResources: font Helvetica Courier" puts $out "%%CreationDate: [clock format [clock seconds]]" puts $out "%%EndComments" puts $out "/showsheet { showpage } bind def" puts $out "/showpage { } def" puts $out "$padx $pady translate" set first {} foreach inFile $args { set in [open $inFile "r"] # Warning, this is assuming that the BoundingBox is in the first # twenty lines of the graph's PostScript. for { set count 0 } { $count < 20 } { incr count } { gets $in line if { [string match "%%BoundingBox:*" $line] } { set bbox $line break; } append first "$line\n" if { [eof $in] } { break } } if { ![info exists bbox] } { error "can't find \"%%BoundingBox:\" line" } set n [scan $bbox "%%%%BoundingBox: %d %d %d %d" x1 y1 x2 y2] if { $n != 4} { error "Bad bounding box line \"$bbox\"" } set rest [read $in] close $in set x [expr ($cellWidth + $gutter) * $column] set y [expr ($cellHeight + $gutter) * $row] set w [expr abs($x2 - $x1)] set h [expr abs($y2 - $y1)] set scaleX [expr $cellWidth / $w] set scaleY [expr $cellHeight / $h] if { $scaleX > $scaleY } { set scale $scaleY } else { set scale $scaleX } puts $out "% " puts $out "% Tiling \"$inFile\" at ($row,$column)" puts $out "% " puts $out "gsave" puts $out "$x $y translate" puts $out "$scale $scale scale" puts $out "-$x1 -$y1 translate" puts $out $first puts $out $rest puts $out "grestore" incr column if { $column >= $page(columns) } { set column 0 incr row } } puts $out "showsheet" close $out } eval TileFiles $argv ��������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/xcolors.tcl���������������������������������������������������������0000755�0001750�0001750�00000013041�11462120062�017233� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../bltwish # # Tk version of xcolors # package require BLT source scripts/demo.tcl set numCols 0 set numRows 0 set maxCols 15 set cellWidth 40 set cellHeight 20 set numCells 0 set lastCount 0 set beginInput(0) 0 set map 0 set entryCount 0 set lastTagId {} scrollbar .xscroll -command { .canvas xview } -orient horizontal scrollbar .yscroll -command { .canvas yview } label .sample \ -font -*-new*century*schoolbook*-bold-r-*-*-24-*-*-*-*-*-*-* \ -text {"Bisque is Beautiful".} button .name -font -*-helvetica-medium-r-*-*-18-*-*-*-*-*-*-* \ -command "AddSelection name" button .rgb -font -*-courier-medium-r-*-*-18-*-*-*-*-*-*-* \ -command "AddSelection rgb" canvas .canvas \ -confine 1 \ -yscrollcommand { .yscroll set } \ -width [expr 16*$cellWidth] -height 400 \ -scrollregion [list 0 0 [expr 16*$cellWidth] 800] frame .border -bd 2 -relief raised label .status \ -anchor w \ -font -*-helvetica-medium-r-*-*-14-*-*-*-*-*-*-* button .quit -text "Quit" -command "exit" button .next -text "Next" -command "DisplayColors next" button .prev -text "Previous" -command "DisplayColors last" selection handle .name GetColor selection handle .rgb GetValue bind .name <Enter> { .status config -text \ "Press button to write color name into primary selection" } bind .rgb <Enter> { .status config -text \ "Press button to write RGB value into primary selection" } bind .name <Leave> { .status config -text "" } bind .rgb <Leave> { .status config -text "" } bind .canvas <Enter> { .status config -text \ "Press button 1 to change background; Button 2 changes foreground" } blt::table . \ .sample 0,0 -cspan 2 -fill both -reqheight 1i \ .name 1,0 -fill both -anchor w \ .rgb 1,1 -fill both -anchor w \ .canvas 2,0 -cspan 2 -fill both \ .yscroll 2,2 -fill y \ .border 3,0 -cspan 2 -fill x -reqheight 8 \ .status 4,0 -cspan 2 -fill both \ .quit 4,1 -anchor e -reqwidth 1i -fill y -padx 10 -pady 4 \ .prev 5,0 -anchor e -reqwidth 1i -fill y -padx 10 -pady 4 \ .next 5,1 -anchor e -reqwidth 1i -fill y -padx 10 -pady 4 proc AddSelection { what } { selection own .$what if {$what == "name" } { set mesg "Color name written into primary selection" } else { set mesg "RGB value written into primary selection" } .status config -text $mesg } proc GetColor { args } { return [lindex [.name config -text] 4] } proc GetValue { args } { return [lindex [.rgb config -text] 4] } proc ShowInfo { tagId what info } { global lastTagId if { $lastTagId != {} } { .canvas itemconfig $lastTagId -width 1 } .canvas itemconfig $tagId -width 3 set lastTagId $tagId set name [lindex $info 3] .name config -text $name set value [format "#%0.2x%0.2x%0.2x" \ [lindex $info 0] [lindex $info 1] [lindex $info 2]] .rgb config -text $value .sample config $what $name .status config -bg $name } proc MakeCell { info } { global numCols numRows maxCols cellWidth cellHeight numCells set x [expr $numCols*$cellWidth] set y [expr $numRows*$cellHeight] set color [lindex $info 3] if [catch {winfo rgb . $color}] { return "ok" } # if { [tk colormodel .] != "color" } { # bind . <Leave> { # .status config -text "Color table full after $numCells entries." # } # .status config -text "Color table full after $numCells entries." # return "out of colors" # } set id [.canvas create rectangle \ $x $y [expr $x+$cellWidth] [expr $y+$cellHeight] \ -fill $color -outline black] if { $color == "white" } { global whiteTagId set whiteTagId $id } .canvas bind $id <1> [list ShowInfo $id -bg $info] .canvas bind $id <2> [list ShowInfo $id -fg $info] incr numCols if { $numCols > $maxCols } { set numCols 0 incr numRows } return "ok" } proc DisplayColors { how } { global lastCount numCells cellHeight numRows numCols rgbText global map beginInput # tk colormodel . color set initialized no if { $how == "last" } { if { $map == 0 } { return } set map [expr $map-1] } else { incr map if ![info exists beginInput($map)] { set beginInput($map) $lastCount } } set start $beginInput($map) if { $numCells > 0 } { .canvas delete all set numRows 0 set numCols 0 set initialized yes } set input [lrange $rgbText $start end] set lineCount $start set entryCount 0 foreach i $input { incr lineCount if { [llength $i] == 4 } { if { [MakeCell $i] == "out of colors" } { break } incr entryCount } } if { $entryCount == 0 } { bind . <Leave> { .status config -text "No more entries in RGB database" } .status config -text "No more entries in RGB database" } set lastCount $lineCount proc tkerror {args} { #dummy procedure } if { $initialized == "no" } { global cellWidth set height [expr $cellHeight*($numRows+1)] .canvas config -scrollregion [list 0 0 [expr 16*$cellWidth] $height] if { $height < 800 } { .canvas config -height $height } global whiteTagId if [info exists whiteTagId] { ShowInfo $whiteTagId -bg {255 255 255 white} } } update idletasks update rename tkerror {} } wm min . 0 0 foreach location { /usr/X11R6/lib/X11 /util/X11R6/lib/X11 /usr/openwin/lib/X11 /usr/dt/lib/X11 /usr/lib/X11 /usr/share/X11 } { set file [file join $location rgb.txt] if { [file exists $file] } { break } } set in [open $file "r"] set rgbText [read $in] close $in set rgbText [split $rgbText \n] DisplayColors next wm min . 0 0 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/graph1.tcl����������������������������������������������������������0000644�0001750�0001750�00000004445�11462120062�016731� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set X { 2.00000e-01 4.00000e-01 6.00000e-01 8.00000e-01 1.00000e+00 1.20000e+00 1.40000e+00 1.60000e+00 1.80000e+00 2.00000e+00 2.20000e+00 2.40000e+00 2.60000e+00 2.80000e+00 3.00000e+00 3.20000e+00 3.40000e+00 3.60000e+00 3.80000e+00 4.00000e+00 4.20000e+00 4.40000e+00 4.60000e+00 4.80000e+00 5.00000e+00 } set Y1 { 4.07008e+01 7.95658e+01 1.16585e+02 1.51750e+02 1.85051e+02 2.16479e+02 2.46024e+02 2.73676e+02 2.99427e+02 3.23267e+02 3.45187e+02 3.65177e+02 3.83228e+02 3.99331e+02 4.13476e+02 4.25655e+02 4.35856e+02 4.44073e+02 4.50294e+02 4.54512e+02 4.56716e+02 4.57596e+02 4.58448e+02 4.59299e+02 4.60151e+02 } set Y2 { 5.14471e-00 2.09373e+01 2.84608e+01 3.40080e+01 3.75691e+01 3.91345e+01 3.92706e+01 3.93474e+01 3.94242e+01 3.95010e+01 3.95778e+01 3.96545e+01 3.97313e+01 3.98081e+01 3.98849e+01 3.99617e+01 4.00384e+01 4.01152e+01 4.01920e+01 4.02688e+01 4.03455e+01 4.04223e+01 4.04990e+01 4.05758e+01 4.06526e+01 } set Y3 { 2.61825e+01 5.04696e+01 7.28517e+01 9.33192e+01 1.11863e+02 1.28473e+02 1.43140e+02 1.55854e+02 1.66606e+02 1.75386e+02 1.82185e+02 1.86994e+02 1.89802e+02 1.90683e+02 1.91047e+02 1.91411e+02 1.91775e+02 1.92139e+02 1.92503e+02 1.92867e+02 1.93231e+02 1.93595e+02 1.93958e+02 1.94322e+02 1.94686e+02 } set configOptions { Element.Pixels 6 Element.Smooth catrom Legend.ActiveBackground khaki2 Legend.ActiveRelief sunken Legend.Background "" Legend.Position plotarea Title "A Simple X-Y Graph" activeLine.Color yellow4 activeLine.Fill yellow background khaki3 line1.Color red4 line1.Fill red1 line1.Symbol circle line2.Color purple4 line2.Fill purple1 line2.Symbol arrow line3.Color green4 line3.Fill green1 line3.Symbol triangle x.Descending no x.Loose no x.Title "X Axis Label" y.Rotate 90 y.Title "Y Axis Label" } set resource [string trimleft $graph .] foreach { option value } $configOptions { option add *$resource.$option $value } $graph element create line1 -x $X -y $Y2 $graph element create line2 -x $X -y $Y3 $graph element create line3 -x $X -y $Y1 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/clone.tcl�����������������������������������������������������������0000644�0001750�0001750�00000004373�11462120062�016647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� proc CopyOptions { cmd orig new } { set all [eval $orig $cmd] set configLine $new foreach arg $cmd { lappend configLine $arg } foreach option $all { if { [llength $option] != 5 } { continue } set switch [lindex $option 0] set initial [lindex $option 3] set current [lindex $option 4] if { [string compare $initial $current] == 0 } { continue } lappend configLine $switch $current } eval $configLine } proc CopyBindings { oper orig new args } { set tags [$orig $oper bind] if { [llength $args] > 0 } { lappend tags [lindex $args 0] } foreach tag $tags { foreach binding [$orig $oper bind $tag] { set cmd [$orig $oper bind $tag $binding] $new $oper bind $tag $binding $cmd } } } proc CloneGraph { orig new } { graph $new CopyOptions "configure" $orig $new # Axis component foreach axis [$orig axis names] { if { [$new axis name $axis] == "" } { $new axis create $axis } CopyOptions [list axis configure $axis] $orig $new } foreach axis { x y x2 y2 } { $new ${axis}axis use [$orig ${axis}axis use] } # Pen component foreach pen [$orig pen names] { if { [$new pen name $pen] == "" } { $new pen create $pen } CopyOptions [list pen configure $pen] $orig $new } # Marker component foreach marker [$orig marker names] { $new marker create [$orig marker type $marker] -name $marker CopyBindings marker $orig $new $marker CopyOptions [list marker configure $marker] $orig $new } # Element component foreach elem [$orig element names] { $new element create $elem CopyBindings element $orig $new $elem CopyOptions [list element configure $elem] $orig $new } # Fix element display list $new element show [$orig element show] # Legend component CopyOptions {legend configure} $orig $new CopyBindings legend $orig $new # Postscript component CopyOptions {postscript configure} $orig $new # Grid component CopyOptions {grid configure} $orig $new # Grid component CopyOptions {crosshairs configure} $orig $new # Graph bindings foreach binding [bind $orig] { set cmd [bind $orig $binding] bind $new $binding $cmd } return $new } toplevel .top pack [CloneGraph $graph .top.graph] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/graph2.tcl����������������������������������������������������������0000644�0001750�0001750�00000006766�11462120062�016742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������option add *HighlightThickness 0 option add *Tile bgTexture option add *Button.Tile "" image create picture bgTexture -file ./images/chalk.gif set configOptions [subst { InvertXY no Axis.TickFont { {Sans Serif} 14 bold } Axis.TitleFont { {Sans Serif} 12 bold } BorderWidth 2 Element.Pixels 8 Element.ScaleSymbols true Element.Smooth cubic Font { {Serif} 10 } Foreground white Legend.ActiveBorderWidth 2 Legend.ActiveRelief raised Legend.Anchor ne Legend.BorderWidth 0 Legend.Font { Serif 14 } Legend.Foreground orange #Legend.Position plotarea Legend.Hide yes Legend.Relief flat Postscript.Preview yes Relief raised Shadow { navyblue 2 } Title "Bitmap Symbols" degrees.Command [namespace current]::FormatAxisLabel degrees.LimitsFormat "Deg=%g" degrees.Subdivisions 0 degrees.Title "Degrees" degrees.stepSize 90 temp.LimitsFormat "Temp=%g" temp.Title "Temperature" y.Color purple2 y.LimitsFormat "Y=%g" y.Rotate 90 y.Title "Y" y.loose no y2.Color magenta3 y2.Hide no xy2.Rotate 270 y2.Rotate 0 y2.Title "Y2" y2.LimitsFormat "Y2=%g" x2.LimitsFormat "x2=%g" }] set resource [string trimleft $graph .] foreach { option value } $configOptions { option add *$resource.$option $value } proc FormatAxisLabel {graph x} { format "%d%c" [expr int($x)] 0xB0 } set max -1.0 set step 0.2 set letters { A B C D E F G H I J K L } set count 0 for { set level 30 } { $level <= 100 } { incr level 10 } { set color [format "#dd0d%0.2x" [expr round($level*2.55)]] set pen "pen$count" set symbol "symbol$count" set im [image create picture -width 25 -height 35] $im blank 0x00000000 if 0 { $im draw text [lindex $letters $count] 0 0 -color $color \ -font "Arial 12" -anchor nw } $graph pen create $pen -symbol $im set min $max set max [expr $max + $step] lappend styles "$pen $min $max" incr count } $graph axis create temp \ -color lightgreen \ -title Temp $graph axis create degrees \ -rotate 90 $graph xaxis use degrees set tcl_precision 15 set pi1_2 [expr 3.14159265358979323846/180.0] blt::vector create w x sinX cosX radians x seq -360.0 360.0 10.0 #x seq -360.0 -180.0 30.0 radians expr { x * $pi1_2 } sinX expr sin(radians) cosX expr cos(radians) cosX dup w blt::vector destroy radians blt::vector create xh xl yh yl set pct [expr ($cosX(max) - $cosX(min)) * 0.025] yh expr {cosX + $pct} yl expr {cosX - $pct} set pct [expr ($x(max) - $x(min)) * 0.025] xh expr {x + $pct} xl expr {x - $pct} set s1 [image create picture -width 25 -height 25] $s1 blank 0x00000000 $s1 draw circle 11 11 7 -shadow 0 -linewidth 2 \ -fill 0x90FF0000 -antialias yes $graph element create line3 \ -color green4 \ -fill green \ -label "cos(x)" \ -mapx degrees \ -styles $styles \ -symbol $s1 \ -weights w \ -x x \ -y cosX \ -yhigh yh -ylow yl set s2 [image create picture -width 25 -height 25] $s2 blank 0x00000000 $s2 draw circle 12 12 7 -shadow 0 -linewidth 2 \ -fill 0x9000FF00 -antialias yes \ -outline orange $graph element create line1 \ -color orange \ -outline black \ -fill orange \ -fill yellow \ -label "sin(x)" \ -mapx degrees \ -pixels 6m \ -symbol $s2 \ -x x \ -y sinX Blt_ZoomStack $graph Blt_Crosshairs $graph #Blt_ActiveLegend $graph Blt_ClosestPoint $graph Blt_PrintKey $graph ����������./saods9/blt3.0.1/demos/scripts/graph5.tcl����������������������������������������������������������0000644�0001750�0001750�00000002712�11462120062�016730� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set configOptions { Element.LineWidth 0 Element.Pixels 0.7c Element.ScaleSymbols true Font { Courier 18 bold} Height 4i Legend.ActiveRelief raised Legend.Font { Courier 14 } Legend.padY 0 Title "Element Symbol Types" Width 5i } set resName [string trimleft $graph .] foreach { option value } $configOptions { option add *$resName.$option $value } blt::vector xValues xValues set { 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 } for { set i 0 } { $i < 10 } { incr i } { set vecName "y${i}" blt::vector ${vecName}(10) $vecName variable x set x(:) [expr $i*50.0+10.0] } set attributes { none "None" red red4 y0 circle "Circle" yellow yellow4 y2 cross "Cross" cyan cyan4 y6 diamond "Diamond" green green4 y3 plus "Plus" magenta magenta4 y9 splus "Splus" Purple purple4 y7 scross "Scross" red red4 y8 square "Square" orange orange4 y1 triangle "Triangle" blue blue4 y4 "@bitmaps/hobbes.xbm @bitmaps/hobbes_mask.xbm" "Bitmap" yellow black y5 } set count 0 foreach { symbol label fill color yVec } $attributes { $graph element create line${count} \ -label $label \ -symbol $symbol \ -color $color \ -fill $fill \ -x xValues \ -y $yVec incr count } $graph element configure line0 \ -dashes { 2 4 2 } \ -linewidth 2 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph Blt_PrintKey $graph ������������������������������������������������������./saods9/blt3.0.1/demos/scripts/bgtest.tcl����������������������������������������������������������0000644�0001750�0001750�00000001043�11462120062�017026� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set fid [open "../README" "r"] set data [read $fid] close $fid regsub -all "\r|\n|\t" $data " " data set data [split $data " "] set count 0 set maxWords 500 foreach word $data { if { $word == "" } { continue } if { $count & 0x1 } { puts -nonewline stderr "($word)" flush stderr } else { puts -nonewline stdout "($word)" flush stdout } incr count if { ($count % 10) == 0 } { puts stdout "" puts stderr "" flush stdout flush stderr } if { $count > $maxWords } { break } after 500 } exit 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scripts/send.tcl������������������������������������������������������������0000644�0001750�0001750�00000006362�11462120062�016500� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� # -------------------------------------------------------------------------- # # SendInit -- # # Creates a "send" proc to replace the former Tk send command. # Uses DDE services to simulate the transfer. This must be # called before any drag&drop targets are registered. Otherwise # they will pick up the wrong application name. # # The first trick is to determine a unique application name. This # is what other applications will use to send to us. Tk used to # do this for us. # # Note that we can generate the same name for two different Tk # applications. This can happen if two Tk applications picking # names at exactly the same time. [In the future, we should # probably generate a name based upon a global system value, such # as the handle of the main window ".".] The proc "SendVerify" # below will verify that you have only one DDE server registered # with this application's name. # # Arguments: # myInterp Sets the application name explicitly to this # string. If the argument isn't given, or is the # empty string, then the routine picks a name for # us. # # Results: # Returns the name of the application. # # Side Effects: # Sets the name of our application. You can call "tk appname" to # get the name. A DDE topic using the same name is also created. # A send proc is also automatically created. Be careful that you # don't overwrite an existing send command. # # -------------------------------------------------------------------------- proc SendInit { {myInterp ""} } { # Load the DDE package. package require dde if { $myInterp == "" } { # Pick a unique application name, replicating what Tk used to do. # This is what other applications will use to "send" to us. We'll # use DDE topics to represent interpreters. set appName [tk appname] set count 0 set suffix {} # Keep generating interpreter names by suffix-ing the original # application name with " #number". Sooner of later we'll find # one that's not currently use. while { 1 } { set myInterp "${appName}${suffix}" set myServer [list TclEval $myInterp] if { [lsearch [dde services TclEval {}] $myServer] < 0 } { break } incr count set suffix " \#$count" } } tk appname $myInterp dde servername $myInterp proc send { interp args } { dde eval $interp $args } return $myInterp } # -------------------------------------------------------------------------- # # SendVerify -- # # Verifies that application name picked is uniquely registered # as a DDE server. This checks that two Tk applications don't # accidently use the same name. # # Arguments: # None Used the current application name. # # Results: # Generates an error if either a server can't be found or more # than one server is registered. # # -------------------------------------------------------------------------- proc SendVerify {} { # Load the DDE package. package require dde set count 0 set appName [tk appname] foreach server [dde services TclEval {}] { set topic [lindex $server 1] if { [string compare $topic $appName] == 0 } { incr count } } if {$count == 0} { error "Service not found: wrong name registered???" } if { $count > 1 } { error "Duplicate names found for \"[tk appname]\"" } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop7.tcl������������������������������������������������������������������0000644�0001750�0001750�00000001136�11462120062�015275� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT set imgfile ~/rc_logo_sm.gif set im1 [image create picture -width 50 -height 50] $im1 blank 0x00000000 set x 6 set y 30 $im1 draw text $x $y \ -text "048" \ -font "arial 14 bold" \ -color 0xFF000000 $im1 blur $im1 2 set im2 [image create picture] $im2 select $im1 0x01000000 0xFFFFFFFF $im1 and 0xFF000000 -mask $im2 set im [image create picture -file $imgfile -width 50 -height 50 -filter sinc] $im blend $im $im1 incr x -1 incr y -1 $im draw text $x $y \ -text "048" \ -font "arial 14 bold" \ -color white label .show -image $im pack .show ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/picture3.tcl����������������������������������������������������������������0000644�0001750�0001750�00000003321�11462120062�015606� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT set dest [image create picture -width 800 -height 600] source usmap.tcl set count 0 array set colors { 0 red 1 green 2 blue 3 cyan 4 orange 5 purple 6 brown 7 violet 8 seagreen 9 lightblue 10 yellow 11 pink 12 khaki 13 grey } blt::vector all blt::vector x blt::vector y set subset * label .l -image $dest $dest blank white set bg [image create picture -file images/blt98.gif] $dest copy $bg pack .l foreach region [array names us_regions $subset] { set coords $us_regions($region) set cnum [expr {int(rand()*14.0)}] all set $coords # all split x y # set min [blt::vector expr min(x)] # x expr { (x-$min)*3.0 + 10 } # set min [blt::vector expr min(y)] # y expr { (y-$min)*3.0 + 10 } # all merge x y all expr { all * 3.0 } set coords [all values] $dest draw polygon -coords $coords -color $colors($cnum) \ -antialiased 1 -shadow 1 -alpha 155 #$dest draw line -coords $coords -color black # foreach {rx ry} $coords { # $dest draw rectangle [expr int($rx-2)] [expr int($ry-2)] [expr int($rx+2)] [expr int($ry+2)] -color red # } incr count } #$dest draw rectangle 200 200 300 300 -color green -shadow 0 \ -radius 10 -alpha 100 #$dest draw rectangle 200 200 400 300 -color blue -linewidth 29 \ -radius 19 -shadow 0 -antialiased 0 -alpha 180 $dest draw circle 200 200 100 -alpha 055 -fill yellow -shadow 0 \ -antialiased 1 -linewidth 10 -outline 0xA0FF00FF #$dest draw text "Hi George" 200 200 -anchor c -rotate 0.0 \ -font "@/usr/share/fonts/100dpi/helvB24-ISO8859-1.pcf.gz" \ -alpha 155 -color black #$dest draw line -coords "200 200 500 200" -color black ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/Makefile.vc�����������������������������������������������������������������0000644�0001750�0001750�00000004036�11462120062�015417� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for demos # ------------------------------------------------------------------------ include ../vc.config srcdir = ../$(TOP)/demos destdir = $(scriptdir)/demos SHELL = bash RM = rm -rf INSTALL = install -m 0755 INSTALL_DATA = install -m 0644 instdirs = $(prefix) $(exec_prefix) $(libdir) $(scriptdir) \ $(destdir) \ $(destdir)/bitmaps \ $(destdir)/bitmaps/hand \ $(destdir)/bitmaps/fish \ $(destdir)/images \ $(destdir)/scripts demos = barchart1.tcl barchart2.tcl barchart3.tcl barchart4.tcl \ barchart5.tcl \ bgexec1.tcl bgexec2.tcl bgexec3.tcl bgexec4.tcl \ bitmap.tcl \ busy1.tcl \ dragdrop1.tcl dragdrop2.tcl \ eps.tcl \ graph1.tcl graph2.tcl graph3.tcl graph4.tcl graph5.tcl \ graph6.tcl graph7.tcl \ hierbox1.tcl hierbox2.tcl hierbox3.tcl hierbox4.tcl \ hiertable1.tcl hiertable2.tcl hiertable3.tcl \ htext1.tcl htext.txt \ spline.tcl stripchart1.tcl \ tabset1.tcl tabset2.tcl tabset3.tcl tabset4.tcl \ tabnotebook1.tcl tabnotebook2.tcl tabnotebook3.tcl \ treeview1.tcl \ winop1.tcl winop2.tcl all: install: inst-dirs inst-bitmaps inst-images inst-scripts inst-scripts: for i in $(srcdir)/scripts/*.tcl ; do \ $(INSTALL) $$i $(destdir)/scripts ; \ done for i in $(demos) ; do \ $(INSTALL) $(srcdir)/$$i $(destdir)/$$i ; \ done inst-bitmaps: for i in $(srcdir)/bitmaps/*.xbm ; do \ $(INSTALL_DATA) $$i $(destdir)/bitmaps ; \ done for i in $(srcdir)/bitmaps/hand/*.xbm ; do \ $(INSTALL_DATA) $$i $(destdir)/bitmaps/hand ; \ done for i in $(srcdir)/bitmaps/fish/*.xbm ; do \ $(INSTALL_DATA) $$i $(destdir)/bitmaps/fish ; \ done inst-images: for i in $(srcdir)/images/*.gif $(srcdir)/images/*.ps ; do \ $(INSTALL_DATA) $$i $(destdir)/images ; \ done inst-dirs: @for i in $(instdirs) ; do \ if test -d "$$i" ; then : ; else mkdir "$$i" ; fi ; \ done clean: $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* distclean: clean $(RM) *.ps Makefile ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu2.tcl������������������������������������������������������������������0000644�0001750�0001750�00000021056�11462120062�015246� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set colors { aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkturquoise darkviolet deeppink deepskyblue dimgray dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightsteelblue lightyellow lime limegreen linen magenta #008000 mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen } set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set icon2 [image create picture -file images/blt98.gif] set icon [image create picture -data $imgData] set bg [blt::bgpattern create gradient -high grey100 -low grey90 \ -dir x -jitter yes -log yes -relativeto self] set image "" option add *ComboEntry.takeFocus 1 if { [file exists ../library] } { set blt_library ../library } set myIcon "" blt::comboentry .e \ -image $image \ -textvariable myText1 \ -iconvariable myIcon1 \ -textwidth 6 \ -menu .e.m \ -menuanchor se \ -exportselection yes \ -xscrollcommand { .s set } \ -postcommand {.e.m configure -width [winfo width .e] ; update} \ -command "puts {button pressed}" set labels { Aarhus Aaron Ababa aback abaft abandon abandoned abandoning abandonment abandons abase abased abasement abasements abases abash abashed abashes abashing abasing abate abated abatement abatements abater abates abating Abba abbe abbey abbeys abbot abbots Abbott abbreviate abbreviated abbreviates abbreviating abbreviation abbreviations Abby abdomen abdomens abdominal abduct abducted abduction abductions abductor abductors abducts Abe abed Abel Abelian Abelson Aberdeen Abernathy aberrant aberration aberrations abet abets abetted abetter abetting abeyance abhor abhorred abhorrent abhorrer abhorring abhors abide abided abides abiding Abidjan Abigail Abilene abilities ability abject abjection abjections abjectly abjectness abjure abjured abjures abjuring ablate ablated ablates ablating ablation ablative ablaze able abler ablest ably Abner abnormal abnormalities abnormality abnormally Abo aboard abode abodes abolish abolished abolisher abolishers abolishes abolishing abolishment abolishments abolition abolitionist abolitionists abominable abominate aboriginal aborigine aborigines abort aborted aborting abortion abortions abortive abortively aborts Abos abound abounded abounding abounds about above aboveboard aboveground abovementioned abrade abraded abrades abrading Abraham Abram Abrams Abramson abrasion abrasions abrasive abreaction abreactions abreast abridge abridged abridges abridging abridgment abroad abrogate abrogated abrogates abrogating abrupt abruptly abruptness abscess abscessed abscesses abscissa abscissas abscond absconded absconding absconds absence absences absent absented absentee absenteeism absentees absentia absenting absently absentminded absents absinthe absolute absolutely absoluteness absolutes absolution absolve absolved absolves absolving absorb absorbed absorbency absorbent absorber absorbing absorbs absorption absorptions absorptive abstain abstained abstainer abstaining abstains abstention abstentions abstinence abstract abstracted abstracting abstraction abstractionism abstractionist abstractions abstractly abstractness abstractor abstractors abstracts abstruse abstruseness absurd absurdities absurdity absurdly Abu abundance abundant abundantly abuse abused abuses abusing abusive abut abutment abuts abutted abutter abutters abutting abysmal abysmally abyss abysses Abyssinia Abyssinian Abyssinians acacia academia academic academically academics academies academy Acadia Acapulco accede acceded accedes accelerate accelerated accelerates accelerating acceleration accelerations accelerator accelerators accelerometer accelerometers accent accented accenting accents accentual accentuate accentuated accentuates accentuating accentuation accept acceptability acceptable acceptably acceptance acceptances accepted accepter accepters accepting acceptor acceptors accepts access accessed accesses accessibility accessible accessibly accessing accession accessions accessories accessors accessory accident accidental accidentally accidently accidents acclaim acclaimed acclaiming acclaims acclamation acclimate acclimated acclimates acclimating acclimatization acclimatized accolade accolades accommodate accommodated accommodates accommodating accommodation accommodations accompanied accompanies accompaniment accompaniments accompanist accompanists accompany accompanying accomplice accomplices accomplish accomplished accomplisher accomplishers accomplishes accomplishing accomplishment accomplishments accord accordance accorded accorder accorders according accordingly accordion accordions accords accost accosted accosting accosts account accountability accountable accountably accountancy accountant accountants accounted accounting accounts Accra accredit accreditation accreditations accredited accretion accretions accrue accrued accrues accruing acculturate acculturated acculturates acculturating acculturation accumulate accumulated accumulates accumulating accumulation accumulations accumulator accumulators accuracies accuracy accurate accurately accurateness accursed accusal accusation accusations accusative accuse accused accuser accuses accusing accusingly accustom accustomed accustoming accustoms ace aces acetate acetone acetylene Achaean Achaeans ache ached aches achievable achieve achieved achievement achievements achiever achievers achieves achieving Achilles aching acid acidic acidities acidity acidly acids acidulous Ackerman Ackley acknowledge acknowledgeable acknowledged acknowledgement acknowledgements acknowledger acknowledgers acknowledges acknowledging acknowledgment acknowledgments acme acne acolyte acolytes acorn acorns acoustic acoustical acoustically acoustician acoustics acquaint acquaintance acquaintances acquainted acquainting acquaints acquiesce acquiesced acquiescence acquiescent acquiesces acquiescing acquirable acquire acquired acquires acquiring acquisition acquisitions } blt::combomenu .e.m \ -textvariable myText1 \ -iconvariable myIcon1 \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -width { 0 400 } \ -height { 0 2i } \ -yscrollbar .e.m.ybar \ -xscrollbar .e.m.xbar .e.m listadd $labels \ -icon $icon blt::tk::scrollbar .e.m.xbar blt::tk::scrollbar .e.m.ybar blt::tk::scrollbar .s -orient vertical -command { .e xview } bind ComboEntry <3> { grab release [grab current] } blt::table . \ 0,0 .e -fill x -anchor n blt::table configure . r0 -resize none blt::table configure . r1 -resize expand wm geometry . 200x400 #blt::bltdebug 100����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tv3.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000001515�11462120062�014567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT package require Tk set a [frame .a -bg red] set tree [::blt::treeview $a.tree\ -relief flat\ -selectmode single\ -exportselection false] $tree configure -yscrollcommand "$a.y set" -xscrollcommand "$a.x set" scrollbar $a.y -command "$tree yview" scrollbar $a.x -command "$tree xview" -orient horizontal grid $tree -row 0 -column 1 -sticky nsew grid $a.y -row 0 -column 2 -sticky ns grid $a.x -row 1 -column 1 -sticky we grid columnconfigure $a 1 -weight 1 grid rowconfigure $a 0 -weight 1 $tree configure -width 0 $tree column configure treeView -width 0 $tree insert end hola -label hola pack $a bind $tree Configure " puts \[winfo geometry $tree\] " puts [$tree configure -width] puts [winfo geometry $tree] update ::update idletasks puts [$tree configure -width] puts [winfo geometry $tree] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hiertable2.tcl��������������������������������������������������������������0000755�0001750�0001750�00000011005�11462120062�016072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set saved [pwd] #blt::bltdebug 100 image create picture bgTexture -file ./images/rain.gif set imageList {} foreach f [glob ./images/mini-*.gif] { lappend imageList [image create picture -file $f] } #option add *Hiertable.Tile bgTexture option add *Hiertable.ScrollTile yes #option add *Hiertable.Column.background grey90 option add *Hiertable.titleShadow { grey80 } option add *Hiertable.titleFont {*-helvetica-bold-r-*-*-11-*-*-*-*-*-*-*} option add *xHiertable.openCommand { set path /home/gah/src/blt/%P if { [file isdirectory $path] } { cd $path set files [glob -nocomplain * */. ] if { $files != "" } { eval %W insert -at %n end $files } } } option add *xHiertable.closeCommand { eval %W delete %n 0 end } hiertable .h -width 0\ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -selectmode multiple .h column configure treeView -text "View" .h column insert 0 mtime atime gid .h column insert end nlink mode type ctime uid ino size dev .h column configure uid -background \#eaeaff .h column configure mtime -hide no -bg \#ffeaea .h column configure size gid nlink uid ino dev -justify right .h column configure treeView -hide no -edit no scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } blt::table configure . c1 r1 -resize none image create picture fileImage -file images/stopsign.gif proc DoFind { dir path } { global fileList count set saved [pwd] cd $dir foreach f [lsort [glob -nocomplain *]] { set entry [file join $path $f] if { [catch { file stat $entry info }] != 0 } { lappend fileList $entry } else { if 0 { if { $info(type) == "file" } { set info(type) @fileImage } else { set info(type) "" } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(size) [FormatSize $info(size)] set info(mode) [FormatMode $info(mode)] lappend fileList $entry -data [array get info] } incr count if { [file isdirectory $f] } { DoFind $f $entry } } cd $saved } proc Find { dir } { global fileList count set fileList {} catch { file stat $dir info } incr count lappend fileList $dir -data [array get info] DoFind $dir $dir return $fileList } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath ..] set trim "$top" .h configure -separator "/" -trim $trim set count 0 #.h entry configure root -label [file tail [GetAbsolutePath $top]] .h configure -bg grey90 regsub -all {\.\./*} [Find $top] {} fileList puts "$count entries" eval .h insert end $fileList .h configure -bg white focus .h set nodes [.h find -glob -name *.c] eval .h entry configure $nodes -foreground green4 set nodes [.h find -glob -name *.h] eval .h entry configure $nodes -foreground cyan4 set nodes [.h find -glob -name *.o] eval .h entry configure $nodes -foreground red4 cd $saved #bltdebug 100 .h column bind all <ButtonRelease-3> { %W configure -flat no } proc SortColumn { column } { set old [.h sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.h sort cget -decreasing] set decreasing [expr !$decreasing] } .h sort configure -decreasing $decreasing -column $column .h configure -flat yes .h sort auto yes blt::busy hold .h update blt::busy release .h } foreach column [.h column names] { .h column configure $column -command [list SortColumn $column] } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bgexec2.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000002411�11462120062�015371� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* # namespace import -force blt::tk::* } source scripts/demo.tcl proc ShowResult { name1 name2 how } { global var .l$name2 configure -text "$var($name2)" after 2000 "blt::table forget .l$name2" } for { set i 1 } { $i <= 20 } { incr i } { label .l$i blt::table . .l$i $i,0 set pid [bgexec var($i) du /usr/include &] .l$i configure -text "Starting #$i pid=$pid" trace variable var($i) w ShowResult update after 500 } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph4.tcl������������������������������������������������������������������0000755�0001750�0001750�00000404002�11462120062�015241� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT package require blt_datatable_vector source scripts/demo.tcl set tcl_precision 15 set graph .graph image create picture bgTexture -file ./images/chalk.gif option add *default normal option add *Button.tile bgTexture #option add *Htext.font -*-times*-bold-r-*-*-18-*-* #option add *Text.font "Serif 18" option add *header.font "{Times New Roman} 12" #option add *footer.font -*-times*-medium-r-*-*-18-*-* option add *Graph.relief raised #option add *Graph.borderWidth 2 option add *Graph.height 5i option add *Graph.plotBackground black option add *Graph.width 7i option add *Graph.tile bgTexture option add *Graph.halo 0 option add *Graph.title "s27.out" option add *Axis.titleColor red2 option add *x.title "Time" option add *y.title "Signals" option add *Crosshairs.Color white option add *activeLine.Fill navyblue option add *activeLine.LineWidth 2 option add *Element.ScaleSymbols yes option add *Element.Smooth natural option add *Symbol square option add *Element.LineWidth 1 option add *Pen.LineWidth 1 option add *Pixels 1 option add *Grid.color grey50 option add *Grid.dashes "2 4" option add *Grid.hide no option add *Legend.ActiveRelief sunken option add *Legend.Position right option add *Legend.Relief flat option add *Legend.Pad 0 option add *Legend.hide no option add *LineMarker.Dashes 5 option add *LineMarker.Foreground white option add *zoomOutline.outline yellow option add *TextMarker.Background {} option add *TextMarker.Foreground white blt::vector create x -variable "" for { set i 1 } { $i <= 39 } { incr i } { blt::vector create "v$i" -variable "" } x set { 0 1e-10 2e-10 3e-10 4e-10 5e-10 6e-10 7e-10 8e-10 9e-10 1e-09 1.1e-09 1.2e-09 1.3e-09 1.4e-09 1.5e-09 1.6e-09 1.7e-09 1.8e-09 1.9e-09 2e-09 2.1e-09 2.2e-09 2.3e-09 2.4e-09 2.5e-09 2.6e-09 2.7e-09 2.8e-09 2.9e-09 3e-09 3.1e-09 3.2e-09 3.3e-09 3.4e-09 3.5e-09 3.6e-09 3.7e-09 3.8e-09 3.9e-09 4e-09 4.1e-09 4.2e-09 4.3e-09 4.4e-09 4.5e-09 4.6e-09 4.7e-09 4.8e-09 4.9e-09 5e-09 5.1e-09 5.2e-09 5.3e-09 5.4e-09 5.5e-09 5.6e-09 5.7e-09 5.8e-09 5.9e-09 6e-09 6.1e-09 6.2e-09 6.3e-09 6.4e-09 6.5e-09 6.6e-09 6.7e-09 6.8e-09 6.9e-09 7e-09 7.1e-09 7.2e-09 7.3e-09 7.4e-09 7.5e-09 7.6e-09 7.7e-09 7.8e-09 7.9e-09 8e-09 8.1e-09 8.2e-09 8.3e-09 8.4e-09 8.5e-09 8.6e-09 8.7e-09 8.8e-09 8.9e-09 9e-09 9.1e-09 9.2e-09 9.3e-09 9.4e-09 9.5e-09 9.6e-09 9.7e-09 9.8e-09 9.9e-09 1e-08 1.01e-08 1.02e-08 1.03e-08 1.04e-08 1.05e-08 1.06e-08 1.07e-08 1.08e-08 1.09e-08 1.1e-08 1.11e-08 1.12e-08 1.13e-08 1.14e-08 1.15e-08 1.16e-08 1.17e-08 1.18e-08 1.19e-08 1.2e-08 1.21e-08 1.22e-08 1.23e-08 1.24e-08 1.25e-08 1.26e-08 1.27e-08 1.28e-08 1.29e-08 1.3e-08 1.31e-08 1.32e-08 1.33e-08 1.34e-08 1.35e-08 1.36e-08 1.37e-08 1.38e-08 1.39e-08 1.4e-08 1.41e-08 1.42e-08 1.43e-08 1.44e-08 1.45e-08 1.46e-08 1.47e-08 1.48e-08 1.49e-08 1.5e-08 1.51e-08 1.52e-08 1.53e-08 1.54e-08 1.55e-08 1.56e-08 1.57e-08 1.58e-08 1.59e-08 1.6e-08 1.61e-08 1.62e-08 1.63e-08 1.64e-08 1.65e-08 1.66e-08 1.67e-08 1.68e-08 1.69e-08 1.7e-08 1.71e-08 1.72e-08 1.73e-08 1.74e-08 1.75e-08 1.76e-08 1.77e-08 1.78e-08 1.79e-08 1.8e-08 1.81e-08 1.82e-08 1.83e-08 1.84e-08 1.85e-08 1.86e-08 1.87e-08 1.88e-08 1.89e-08 1.9e-08 1.91e-08 1.92e-08 1.93e-08 1.94e-08 1.95e-08 1.96e-08 1.97e-08 1.98e-08 1.99e-08 2e-08 2.01e-08 2.02e-08 2.03e-08 2.04e-08 2.05e-08 2.06e-08 2.07e-08 2.08e-08 2.09e-08 2.1e-08 2.11e-08 2.12e-08 2.13e-08 2.14e-08 2.15e-08 2.16e-08 2.17e-08 2.18e-08 2.19e-08 2.2e-08 2.21e-08 2.22e-08 2.23e-08 2.24e-08 2.25e-08 2.26e-08 2.27e-08 2.28e-08 2.29e-08 2.3e-08 2.31e-08 2.32e-08 2.33e-08 2.34e-08 2.35e-08 2.36e-08 2.37e-08 2.38e-08 2.39e-08 2.4e-08 2.41e-08 2.42e-08 2.43e-08 2.44e-08 2.45e-08 2.46e-08 2.47e-08 2.48e-08 2.49e-08 2.5e-08 2.51e-08 2.52e-08 2.53e-08 2.54e-08 2.55e-08 2.56e-08 2.57e-08 2.58e-08 2.59e-08 2.6e-08 2.61e-08 2.62e-08 2.63e-08 2.64e-08 2.65e-08 2.66e-08 2.67e-08 2.68e-08 2.69e-08 2.7e-08 2.71e-08 2.72e-08 2.73e-08 2.74e-08 2.75e-08 2.76e-08 2.77e-08 2.78e-08 2.79e-08 2.8e-08 2.81e-08 2.82e-08 2.83e-08 2.84e-08 2.85e-08 2.86e-08 2.87e-08 2.88e-08 2.89e-08 2.9e-08 2.91e-08 2.92e-08 2.93e-08 2.94e-08 2.95e-08 2.96e-08 2.97e-08 2.98e-08 2.99e-08 3e-08 3.01e-08 3.02e-08 3.03e-08 3.04e-08 3.05e-08 3.06e-08 3.07e-08 3.08e-08 3.09e-08 3.1e-08 3.11e-08 3.12e-08 3.13e-08 3.14e-08 3.15e-08 3.16e-08 3.17e-08 3.18e-08 3.19e-08 3.2e-08 3.21e-08 3.22e-08 3.23e-08 3.24e-08 3.25e-08 3.26e-08 3.27e-08 3.28e-08 3.29e-08 3.3e-08 3.31e-08 3.32e-08 3.33e-08 3.34e-08 3.35e-08 3.36e-08 3.37e-08 3.38e-08 3.39e-08 3.4e-08 3.41e-08 3.42e-08 3.43e-08 3.44e-08 3.45e-08 3.46e-08 3.47e-08 3.48e-08 3.49e-08 3.5e-08 3.51e-08 3.52e-08 3.53e-08 3.54e-08 3.55e-08 3.56e-08 3.57e-08 3.58e-08 3.59e-08 3.6e-08 } v1 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } v2 set { 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 5.32907e-15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } v3 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } v4 set { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } v5 set { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 } v6 set { 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } v7 set { 5 5.16904 4.84159 3.34542 0.317102 0.103304 0.0275721 0.0221534 0.017689 0.0142639 0.0113974 0.00918238 0.00742541 0.00616602 0.00481195 0.00397049 -0.0659889 -0.025671 0.165495 0.986891 3.05229 4.55511 4.91611 4.98192 4.99428 4.99833 4.99095 4.97295 4.95493 4.93428 4.90723 4.94799 4.98584 4.99566 4.99813 4.99907 4.99947 4.99965 4.99976 4.99984 4.99989 4.99992 4.99994 4.99996 4.99998 5.00002 5.00006 5.00002 4.99996 4.99994 4.99999 5.00003 5.00002 5 4.99997 4.99997 4.99997 4.99997 4.99997 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.16575 4.69986 2.43862 0.0230224 0.035229 -0.0210607 -0.0292766 -0.0172693 -0.00271479 -0.000912251 -0.000349106 -0.000116866 -4.24733e-05 -1.39536e-05 -3.01179e-05 -0.0657192 -0.0204835 0.183378 1.07181 3.118 4.46472 4.84158 4.94795 4.98173 4.99236 4.99762 5.01939 5.0433 5.05332 5.04959 5.03955 5.02851 5.02052 5.01422 5.00965 5.00631 5.00405 5.00248 5.00083 5.00012 5.00209 5.00387 5.00347 4.99917 4.99213 4.98411 4.97521 4.96332 4.94601 4.9304 4.94633 4.97936 4.99264 4.99685 4.99857 4.99925 4.99954 4.9997 4.99973 4.9997 4.99973 4.99979 4.99983 4.99986 4.99988 4.9999 4.9999 4.99992 4.99993 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5.14242 4.76101 3.16003 0.299374 0.0645506 -0.000498424 -2.45108e-05 -2.27986e-05 -5.24401e-05 -4.9884e-05 -4.92491e-05 -2.93354e-05 -3.21402e-05 -2.11851e-05 -3.37925e-05 -0.0657892 -0.020563 0.182582 1.06058 3.12484 4.46552 4.84146 4.95102 4.98556 4.99472 4.99806 4.99909 4.99955 4.99976 4.99994 4.99992 5.00029 4.99967 4.99849 4.99736 4.99884 5.00099 5.00377 5.00215 4.99994 4.99893 4.99788 4.99862 5.00055 5.00134 5.00127 5.00073 5.00039 5.00018 5.00006 5.00001 4.99985 5.00026 5.00018 5.00003 4.99981 4.99985 4.99987 4.99985 4.99982 4.99982 4.99982 4.99983 4.99985 4.99987 4.99989 4.99991 4.99992 4.99994 4.99995 4.99995 4.99994 4.99994 4.99996 4.99999 5.00002 5.00008 5.00009 5.00006 5.00001 5 4.99999 4.99998 4.99997 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } v8 set { 5 5.03758 5.04711 4.96911 4.20882 3.96295 4.01117 4.15521 4.2967 4.42274 4.5295 4.6176 4.69014 4.74831 4.7966 4.83537 4.80526 4.787 4.79295 4.88588 5.08978 5.15615 5.10778 5.07718 5.06652 5.08225 4.9744 4.52977 3.77452 2.69426 1.15294 0.245509 0.0981544 0.0567527 0.0367487 0.0252578 0.0180599 0.0133837 0.0101497 0.0078616 0.00620186 0.00499056 0.0041027 0.00344223 0.00295808 0.00260089 0.00229887 0.00200817 0.00176397 0.00160116 0.00147381 0.00134645 0.00125029 0.00116043 0.00107371 0.00101981 0.000965921 0.000912028 0.000858135 0.000804242 0.000761669 0.00072672 0.000691771 0.000656823 0.000621874 0.000588722 0.00057041 0.000552098 0.000533785 0.000515473 0.000497162 0.00047885 0.000460537 0.000442226 0.000423914 0.000405601 0.000388399 0.000378694 0.000368989 0.000359284 0.00034958 0.000339875 0.00033017 0.000320465 0.00031076 0.000301055 0.00029135 0.000282207 0.000276247 0.000270287 0.000264327 0.000258367 0.000252407 0.000246447 0.000240487 0.000234527 0.000228567 0.000222607 0.000217086 0.000213696 0.000210307 0.000206918 0.000203528 0.000200139 0.00019675 0.00019336 0.000189971 0.000186582 0.000183192 0.000179803 0.000176414 0.000173025 0.000169635 0.000166246 0.000162857 0.000159467 0.000156078 0.000152689 0.000149299 0.00014591 0.00014255 0.0316021 0.163272 0.348732 0.603651 0.35745 0.135965 0.0707354 0.0314595 0.0201047 0.00994945 0.00389601 0.00138839 0.00060778 0.000329648 0.000492396 -0.0732035 -0.0844077 -0.0789062 -0.0390837 0.0197559 0.0183094 -0.00180099 -0.0189565 -0.0424144 -0.0735904 -0.0892423 0.285039 1.13702 2.10809 2.95826 3.60164 4.0435 4.35771 4.57254 4.71769 4.81329 4.87534 4.91487 4.94264 4.97375 5.01526 5.06517 5.10154 5.06259 4.89005 4.5787 4.12226 3.46151 2.49023 1.2586 0.32725 0.116753 0.0701865 0.0455509 0.0286914 0.0178176 0.0117599 0.00902715 0.00760583 0.00637745 0.00543811 0.00439377 0.00352448 0.0030151 0.00285771 0.002465 0.00203114 0.00173004 0.0014839 0.00125177 0.00105327 0.000894905 0.000766372 0.000658894 0.000569105 0.000492114 0.000427938 0.000370217 0.000314758 0.000266569 0.000233726 0.000209048 0.000191957 0.000177169 0.000166604 0.000161 0.000157314 0.000143828 0.000130342 0.000116857 0.000103371 8.98855e-05 7.63998e-05 6.29141e-05 5.76583e-05 5.30027e-05 4.8347e-05 4.36913e-05 3.90357e-05 3.438e-05 2.97243e-05 2.72507e-05 2.59083e-05 2.45659e-05 2.32235e-05 2.18811e-05 2.05387e-05 1.91963e-05 1.78539e-05 1.65115e-05 1.51691e-05 1.38267e-05 1.24843e-05 1.11419e-05 9.79954e-06 8.51574e-06 7.69807e-06 6.8804e-06 6.06273e-06 5.24506e-06 0.0287318 0.0317111 -0.0320087 -0.103609 0.0369639 0.0121128 0.00961197 0.00934971 0.00820853 0.00699769 0.00607002 0.00535541 0.00476552 0.00427601 0.00376357 -0.073012 -0.0866964 -0.0809538 -0.038005 0.0277001 0.0188906 0.00614597 0.00373629 0.00489787 0.0146573 0.0191052 0.0151708 0.0124224 0.0105859 0.00879272 0.00729464 0.0070047 0.00449575 -0.00626652 -0.0252417 -0.0147287 0.022538 0.0822905 0.0947372 0.0657516 0.0445506 0.0316753 0.0220971 0.0158101 0.0140971 0.0161498 0.0139876 0.0122447 0.0106994 0.009397 0.00822236 0.00686509 0.00797431 0.00751269 0.00671173 0.00595243 0.00524633 0.00459528 0.00401688 0.00350109 0.00303954 0.00260569 0.00222792 0.00191033 0.00163917 0.00140949 0.00121464 0.0010471 0.000900638 0.000768847 0.000645236 0.000524807 0.000460275 0.000442237 0.000446775 0.000397026 0.000301585 0.000228994 0.000190894 0.000166569 0.000152261 0.000137953 0.000123644 0.000109336 9.50281e-05 8.56557e-05 7.78437e-05 7.00318e-05 6.22198e-05 5.44079e-05 4.87539e-05 4.57761e-05 4.27982e-05 3.98203e-05 3.68425e-05 3.38646e-05 3.08868e-05 2.79089e-05 2.4931e-05 2.19532e-05 1.89753e-05 1.75244e-05 1.64095e-05 1.52946e-05 1.41797e-05 1.30648e-05 1.19499e-05 1.0835e-05 9.72011e-06 8.60521e-06 7.4903e-06 6.5117e-06 6.10334e-06 5.69497e-06 5.2866e-06 4.87824e-06 4.46987e-06 4.06151e-06 3.65314e-06 3.24477e-06 } v9 set { 1.86175 1.99708 2.07867 2.01211 2.43309 3.27194 3.63896 3.90426 4.11074 4.27932 4.41496 4.52543 4.61491 4.68862 4.7479 4.79666 4.72895 4.68886 4.70354 4.81353 5.01568 5.14184 5.10482 5.07362 5.05143 5.03638 5.02323 5.01465 5.00853 5.00383 4.99985 5.00454 5.00652 5.00546 5.00411 5.003 5.00214 5.00151 5.00106 5.00073 5.0005 5.00034 5.00023 5.00015 5.0001 5.00005 5 5.00001 5.00005 5.00005 5.00003 5 4.99998 4.99996 4.99994 4.99995 4.99997 4.99998 5 5.00001 5.00002 5.00002 5.00003 5.00003 5.00003 5.00003 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.17392 4.94828 3.78491 1.52079 0.608874 0.244031 0.127087 0.0552995 0.0361032 0.0169025 0.006364 0.00217624 0.000921391 0.000457305 0.000786754 -0.120016 -0.148054 -0.15898 -0.0801463 0.16463 0.174017 0.0799249 0.0318788 0.0129696 0.00483397 0.0025677 0.0042079 0.00350003 0.00178404 -8.72902e-05 -0.00128497 -0.00142213 -0.00130018 -0.00106874 -0.000789207 -0.000824335 -0.00104518 -0.00136799 -0.004366 -0.0102621 -0.0109254 -0.00649259 -0.00194842 0.00029793 0.00148673 0.00221085 0.00228291 0.00185261 0.00139687 0.00148183 0.00562266 0.00844119 0.00754627 0.00657396 0.00591212 0.00539269 0.0049282 0.00448417 0.0040572 0.00363719 0.00320392 0.00279607 0.00243938 0.00211505 0.00182302 0.00156254 0.0013341 0.00113834 0.000971865 0.00082776 0.000706193 0.000602499 0.000515059 0.000441401 0.00037897 0.000325459 0.00028083 0.000242096 0.000207274 0.000176444 0.000150372 0.000126407 0.000103373 9.05522e-05 8.53555e-05 8.63685e-05 9.02593e-05 8.37346e-05 7.72099e-05 7.06852e-05 6.41605e-05 5.76358e-05 5.11112e-05 4.45865e-05 4.08176e-05 3.72497e-05 3.36818e-05 3.01138e-05 2.65459e-05 2.2978e-05 1.94101e-05 1.76154e-05 1.67399e-05 1.58645e-05 1.4989e-05 1.41136e-05 1.32381e-05 1.23626e-05 1.14872e-05 1.06117e-05 9.73629e-06 8.86083e-06 7.98538e-06 7.10993e-06 6.23447e-06 5.44363e-06 5.32578e-06 5.20792e-06 5.09007e-06 4.97222e-06 0.0784323 0.0474527 -0.0764232 -0.151146 0.0615785 0.0144489 0.00974161 0.00947176 0.00849005 0.00728201 0.00630581 0.00554032 0.00487809 0.00441504 0.00384139 -0.118943 -0.149894 -0.161173 -0.0825299 0.171686 0.176912 0.0816085 0.0335236 0.013791 0.0056976 0.00238833 0.00105348 0.000526199 0.00025969 0.000396026 0.000837835 0.00170131 0.00196699 -0.000553314 -0.0061621 -0.0111895 -0.0142698 -0.0124608 -0.00795847 -0.00467822 -0.0043058 -0.00874449 -0.0118584 -0.00871386 -0.00377892 1.95244e-05 0.00218952 0.00325486 0.00386497 0.00422837 0.00446883 0.00447065 0.00486647 0.00547838 0.00565398 0.00559092 0.00538752 0.00507015 0.00466305 0.00420756 0.00373465 0.00328404 0.00287059 0.00250057 0.00216124 0.00184861 0.00156815 0.00134624 0.00117857 0.00103412 0.0008948 0.000761012 0.000619853 0.000462614 0.000319965 0.000287666 0.000356415 0.000379946 0.000339183 0.00027972 0.000252982 0.000226244 0.000199507 0.000172769 0.000146031 0.000130097 0.000117578 0.000105059 9.25401e-05 8.00213e-05 7.11204e-05 6.67061e-05 6.22918e-05 5.78775e-05 5.34632e-05 4.90489e-05 4.46346e-05 4.02203e-05 3.5806e-05 3.13916e-05 2.69773e-05 2.4827e-05 2.31747e-05 2.15225e-05 1.98702e-05 1.8218e-05 1.65658e-05 1.49135e-05 1.32613e-05 1.1609e-05 9.95678e-06 8.50108e-06 7.86765e-06 7.23422e-06 6.60079e-06 5.96736e-06 5.33393e-06 4.7005e-06 4.06707e-06 3.43363e-06 } v10 set { 1.86175 1.99308 2.16619 2.46661 3.09359 3.76864 4.31299 4.65564 4.83425 4.92153 4.96157 4.98063 4.98649 4.99039 4.9945 4.9972 4.96206 4.89882 4.83865 4.83202 4.91016 5.04479 5.06078 5.04827 5.03474 5.0246 5.01639 5.00996 5.00569 5.00239 5.00043 5.00296 5.00437 5.00382 5.00287 5.00208 5.00148 5.00104 5.00073 5.0005 5.00034 5.00023 5.00016 5.00011 5.00008 5.00007 5.00007 5.00004 5 4.99998 4.99998 4.99997 4.99998 4.99999 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5.10081 5.10949 4.98359 5.00733 5.15145 4.37298 2.36126 0.470759 0.0577238 0.0115884 0.00262611 0.000671499 0.000389038 0.000291291 0.000317347 -0.0167823 -0.0158344 -0.0140559 0.0104849 0.0865874 0.107813 0.0524688 0.0214369 0.00876443 0.00341595 0.00170778 0.00259042 0.0022241 0.00118519 1.10217e-06 -0.000784506 -0.000948169 -0.000856256 -0.000696719 -0.000485987 -0.000724787 -0.000981491 -0.001454 -0.00552498 -0.0114992 -0.0105266 -0.00543527 -0.000982798 0.00127356 0.00224212 0.00275439 0.00281098 0.0025471 0.00230368 0.00222576 0.00485522 0.00729453 0.00691796 0.0062615 0.00573987 0.0052688 0.00481185 0.00436934 0.00394326 0.00352712 0.00309978 0.00270038 0.00235335 0.00203742 0.00175256 0.00150067 0.00128126 0.00109323 0.000933619 0.000795113 0.000678182 0.00057843 0.000494345 0.000423609 0.000363821 0.000312766 0.000269856 0.000232389 0.000198382 0.000168126 0.00014267 0.000119293 9.69034e-05 8.5669e-05 8.26828e-05 8.64066e-05 9.26665e-05 8.5454e-05 7.82416e-05 7.10291e-05 6.38167e-05 5.66043e-05 4.93918e-05 4.21794e-05 3.86073e-05 3.53007e-05 3.19941e-05 2.86876e-05 2.5381e-05 2.20744e-05 1.87678e-05 1.70933e-05 1.62648e-05 1.54363e-05 1.46079e-05 1.37794e-05 1.2951e-05 1.21225e-05 1.12941e-05 1.04656e-05 9.63716e-06 8.80871e-06 7.98026e-06 7.1518e-06 6.32335e-06 5.5374e-06 5.08959e-06 4.64178e-06 4.19397e-06 3.74616e-06 0.0438026 0.0242078 -0.0602019 -0.0840866 0.00148461 -0.00292489 0.000442098 0.00219489 0.00281478 0.00290756 0.00277945 0.00263896 0.00240099 0.00223283 0.001947 -0.0153629 -0.0148815 -0.0128673 0.0126017 0.0905161 0.11051 0.0538958 0.022562 0.00935726 0.00397422 0.00172534 0.000790207 0.000416322 0.000191632 0.000469721 0.0009779 0.00192566 0.00200688 -0.0016502 -0.00733932 -0.0128113 -0.0147608 -0.0115456 -0.00668995 -0.00401368 -0.00463908 -0.0101197 -0.0118993 -0.0076276 -0.00262656 0.000813059 0.00264455 0.00350796 0.00399494 0.0043049 0.00451658 0.00444739 0.00503842 0.00559516 0.00568213 0.00556459 0.0053176 0.00496654 0.00454337 0.00408592 0.00362171 0.00317793 0.00277001 0.00240394 0.00207009 0.00176575 0.00149725 0.00129045 0.00114257 0.00101135 0.000871672 0.000723764 0.000580438 0.000427507 0.000296956 0.000281834 0.000376628 0.000412266 0.000367547 0.000295305 0.000264513 0.000233721 0.000202929 0.000172137 0.000141345 0.000124721 0.000112577 0.000100433 8.82893e-05 7.61453e-05 6.75517e-05 6.33609e-05 5.91701e-05 5.49792e-05 5.07884e-05 4.65976e-05 4.24067e-05 3.82159e-05 3.40251e-05 2.98342e-05 2.56434e-05 2.36401e-05 2.21181e-05 2.05961e-05 1.90741e-05 1.75521e-05 1.60301e-05 1.45081e-05 1.29861e-05 1.14641e-05 9.94208e-06 8.59252e-06 7.96439e-06 7.33626e-06 6.70813e-06 6.07999e-06 5.45186e-06 4.82373e-06 4.1956e-06 3.56747e-06 } v11 set { 1.86175 1.73419 1.42874 1.04055 0.943004 0.268275 0.0826455 0.0388346 0.0214104 0.0135431 0.00961322 0.00712846 0.00588262 0.00432397 0.00377774 0.00270134 -0.00393731 -0.00542187 -0.00126596 0.0113777 0.0134522 0.00477056 -0.00211067 -0.00229253 -0.00173355 -0.00122404 -0.00113426 -0.000744931 -0.000520112 -0.000410048 -0.000220439 0.000508104 5.15856e-05 -0.000112593 -0.000118917 -9.57394e-05 -7.15727e-05 -5.11847e-05 -3.58275e-05 -2.47166e-05 -1.68866e-05 -1.14082e-05 -7.66646e-06 -5.12139e-06 -3.63426e-06 -3.01815e-06 -2.64862e-06 -1.4947e-06 -1.91403e-07 -2.5763e-08 -7.73699e-07 -1.52164e-06 -1.07268e-06 -3.81696e-07 2.6727e-07 4.75489e-07 6.83708e-07 8.91926e-07 1.10014e-06 1.30836e-06 1.2482e-06 1.00726e-06 7.66311e-07 5.25364e-07 2.84417e-07 6.27857e-08 7.43904e-10 -6.12979e-08 -1.2334e-07 -1.85382e-07 -2.47423e-07 -3.09465e-07 -3.71507e-07 -4.33549e-07 -4.95591e-07 -5.57633e-07 -6.04571e-07 -5.4944e-07 -4.9431e-07 -4.3918e-07 -3.84049e-07 -3.28919e-07 -2.73789e-07 -2.18659e-07 -1.63528e-07 -1.08398e-07 -5.32678e-08 1.062e-09 5.08502e-08 1.00638e-07 1.50427e-07 2.00215e-07 2.50003e-07 2.99791e-07 3.4958e-07 3.99368e-07 4.49156e-07 4.98944e-07 5.34512e-07 5.01032e-07 4.67553e-07 4.34073e-07 4.00593e-07 3.67113e-07 3.33633e-07 3.00153e-07 2.66674e-07 2.33194e-07 1.99714e-07 1.66234e-07 1.32754e-07 9.92744e-08 6.57945e-08 3.23147e-08 -1.16513e-09 -3.4645e-08 -6.81248e-08 -1.01605e-07 -1.35084e-07 -1.68564e-07 -2.18729e-07 0.0114926 -0.0245378 -0.111828 0.0964775 1.61491 3.22668 4.22041 4.54492 4.82845 4.94868 4.98588 4.99609 4.9981 4.99908 4.99788 4.98395 4.99294 4.99724 5.01939 5.0471 5.00902 4.98194 4.98496 4.99188 4.99623 4.99862 5.00025 4.99974 4.99953 4.99946 4.99958 5.00012 4.99997 4.99992 4.99988 4.99985 4.9998 4.9997 4.9988 4.99806 4.99982 5.00143 5.00159 5.00098 5.00053 5.00028 5.00007 4.99977 4.99992 5.00005 5.00133 5.0009 4.99993 4.99972 4.99975 4.9998 4.99982 4.99983 4.99983 4.99983 4.99983 4.99984 4.99986 4.99987 4.99989 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5.01457 4.99482 4.96561 4.99326 5.03452 5.00424 5.00101 5.00045 5.00004 4.99965 4.99997 4.99994 4.99958 4.99999 4.99936 4.9839 4.99248 4.99717 5.01976 5.04869 5.0087 4.98143 4.98488 4.99199 4.99622 4.9983 4.99928 4.99971 4.99986 5.00031 5.00022 5.00035 5.0001 4.99884 4.99811 4.99803 4.99887 5.00078 5.00151 5.00116 5.00007 4.99843 4.99915 5.00107 5.00168 5.00141 5.00092 5.00055 5.0003 5.00016 5.0001 5.00001 5.00016 5.0002 5.00009 4.99993 4.99975 4.99984 4.99991 4.99991 4.99982 4.99974 4.99974 4.99985 4.99995 4.99999 4.99998 5.00004 5.00013 5.00015 5.00007 4.99988 4.99982 4.99985 4.99995 5.00006 5.0002 5.00025 5.0002 5.00009 5.00006 5.00004 5.00002 5 4.99998 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } v12 set { 5 5.16975 4.78685 2.94241 0.126698 0.0487004 -0.00422591 -0.00130689 -0.000486756 -0.000195875 -0.000108988 -6.66736e-05 -7.26005e-05 -5.63608e-05 -3.81859e-05 -2.123e-05 -0.0646846 -0.0184474 0.182248 1.06731 3.10988 4.46133 4.84133 4.95113 4.98364 4.99455 4.99694 4.99727 4.9994 4.99975 5.0001 5.00132 5.00089 5.00039 5.00019 5.00011 5.00006 5.00005 5.00004 5.00001 4.99992 4.99992 5.00002 5.00013 5.00017 5.00009 4.99992 4.99991 4.99994 4.99996 4.99998 4.99999 5.00001 5.00004 5.00006 5.00005 5.00004 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.14699 4.78074 3.19424 0.305663 0.0611255 -0.00179951 -0.0012032 0.000405978 0.000989399 0.000445194 0.000191447 8.30476e-05 3.96236e-05 1.91866e-05 1.70665e-05 -0.0655239 -0.0210234 0.1827 1.06848 3.11554 4.46518 4.84212 4.94853 4.98244 4.99434 4.9997 5.00081 5.00009 4.99972 4.99985 4.99974 4.9995 4.99949 4.99958 4.99973 4.99948 4.99914 4.99874 4.99946 5.00309 5.0091 5.01576 5.01835 5.01852 5.0176 5.01625 5.01479 5.01345 5.01264 5.011 5.01092 5.01344 5.01363 5.01289 5.01184 5.01071 5.00956 5.00848 5.00751 5.00663 5.00577 5.00497 5.00427 5.00365 5.0031 5.00264 5.00224 5.00191 5.00163 5.00138 5.00117 5.00099 5.00083 5.00071 5.00061 5.00053 5.00045 5.00037 5.00029 5.00022 5.00019 5.0002 5.00023 5.00024 5.00023 5.00023 5.00022 5.0002 5.00018 5.00016 5.00014 5.00011 5.00009 5.00007 5.00006 5.00005 5.00005 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.14298 4.79809 3.32704 0.498385 0.105773 0.0160646 0.0319912 0.0299434 0.0240102 0.0185844 0.0130411 0.0106532 0.00864871 0.00744519 0.00660887 -0.0612913 -0.0203719 0.174998 0.991787 3.06292 4.60005 4.93058 4.98917 5.00033 4.9999 4.99909 4.9966 4.9955 4.99488 4.99374 4.9943 5.00131 5.00506 4.99311 4.96288 4.93567 4.92439 4.94236 4.9732 4.98864 4.99458 5.00031 5.00694 5.01525 5.01945 5.01998 5.01953 5.01874 5.01766 5.0164 5.01509 5.01326 5.01423 5.01455 5.01361 5.01245 5.01122 5.01002 5.00888 5.00783 5.00687 5.00596 5.00514 5.00442 5.00379 5.00325 5.00279 5.0024 5.00208 5.0018 5.00153 5.00126 5.00107 5.00094 5.00085 5.00078 5.00072 5.00063 5.00053 5.00042 5.00038 5.00034 5.0003 5.00027 5.00023 5.00021 5.00019 5.00017 5.00015 5.00013 5.00012 5.00011 5.0001 5.0001 5.00009 5.00008 5.00007 5.00007 5.00006 5.00005 5.00005 5.00004 5.00004 5.00003 5.00003 5.00002 5.00002 5.00002 5.00001 5.00001 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 } v13 set { 9.73784e-10 0.0189926 0.0926769 0.206309 0.111533 0.0953491 0.0426966 0.0214177 0.0117943 0.00741442 0.00528816 0.00398417 0.0032967 0.00266499 0.00206647 0.00158788 -0.0371391 -0.0439528 -0.0408653 -0.0188706 0.0150241 0.0126852 0.00209817 -0.000239206 -5.31488e-05 0.000876324 -0.00451221 -0.0165223 -0.0284127 -0.0427584 -0.0502453 -0.0257366 -0.00903938 -0.00376456 -0.00233385 -0.00169922 -0.00130397 -0.00102542 -0.000811435 -0.000648115 -0.000529266 -0.00043795 -0.00036574 -0.00030716 -0.00026221 -0.000229662 -0.000205112 -0.000181038 -0.000162045 -0.000148988 -0.000137633 -0.000126278 -0.000115562 -0.000104976 -9.49324e-05 -9.0585e-05 -8.62375e-05 -8.18901e-05 -7.75426e-05 -7.31952e-05 -6.93752e-05 -6.59106e-05 -6.24461e-05 -5.89815e-05 -5.55169e-05 -5.22412e-05 -5.05263e-05 -4.88114e-05 -4.70966e-05 -4.53817e-05 -4.36668e-05 -4.19519e-05 -4.0237e-05 -3.85222e-05 -3.68073e-05 -3.50924e-05 -3.34782e-05 -3.25442e-05 -3.16102e-05 -3.06763e-05 -2.97423e-05 -2.88083e-05 -2.78744e-05 -2.69404e-05 -2.60064e-05 -2.50725e-05 -2.41385e-05 -2.32635e-05 -2.27232e-05 -2.21829e-05 -2.16426e-05 -2.11023e-05 -2.0562e-05 -2.00217e-05 -1.94814e-05 -1.89411e-05 -1.84007e-05 -1.78604e-05 -1.73647e-05 -1.70853e-05 -1.68059e-05 -1.65265e-05 -1.62471e-05 -1.59677e-05 -1.56883e-05 -1.54089e-05 -1.51295e-05 -1.48501e-05 -1.45707e-05 -1.42913e-05 -1.40119e-05 -1.37325e-05 -1.34531e-05 -1.31737e-05 -1.28943e-05 -1.26149e-05 -1.23355e-05 -1.20561e-05 -1.17767e-05 -1.14973e-05 -1.10954e-05 0.0152675 0.0228237 -0.00460678 -0.0341525 0.0232109 -0.0138039 -0.0416538 -0.0458764 -0.0201967 -0.00878316 -0.00379173 -0.00164621 -0.000785131 -0.00037575 -0.000352375 -0.0545586 -0.0746881 -0.0771865 -0.05386 -0.0022199 0.0136703 0.00633526 0.00138826 -0.00108934 0.0038886 0.0298077 0.0475776 0.0481003 0.0464167 0.047818 0.042789 0.035207 0.0264423 0.0193959 0.0151614 0.00624257 -0.00913057 -0.0310696 -0.0430238 0.016426 0.189762 0.49025 0.820116 1.13919 1.43549 1.70658 1.95183 2.17414 2.38506 2.5657 2.73958 2.97905 3.21403 3.43025 3.62645 3.8028 3.96002 4.09996 4.22443 4.33427 4.42886 4.51097 4.5817 4.64326 4.6957 4.74132 4.7797 4.81298 4.84102 4.86512 4.88523 4.90224 4.91649 4.92846 4.93868 4.94755 4.95483 4.96114 4.96682 4.97161 4.97502 4.9776 4.97944 4.98141 4.98319 4.98467 4.98585 4.9869 4.98796 4.98902 4.99008 4.99114 4.9922 4.99326 4.9938 4.99429 4.99479 4.99528 4.99578 4.99628 4.99677 4.99704 4.99718 4.99733 4.99747 4.99762 4.99777 4.99791 4.99806 4.9982 4.99835 4.9985 4.99864 4.99879 4.99893 4.99907 4.99916 4.99925 4.99934 4.99943 5.01473 4.92293 4.61974 4.0316 3.7835 3.74195 3.78344 3.87272 3.97386 4.07319 4.16686 4.25256 4.33126 4.40264 4.46697 4.49249 4.51807 4.55803 4.64055 4.78574 4.86074 4.88334 4.8999 4.91455 4.92814 4.93926 4.94761 4.95433 4.95907 4.9654 4.98317 5.0208 5.05134 4.85852 4.16041 3.00077 1.68376 0.672707 0.240838 0.0794725 -0.0106347 -0.00879443 0.107196 0.368163 0.701424 1.03581 1.3601 1.6678 1.95731 2.22701 2.47544 2.69099 2.92327 3.16648 3.3877 3.59067 3.77344 3.93584 4.08066 4.20863 4.32065 4.41791 4.50211 4.57423 4.63614 4.68888 4.73377 4.7721 4.80519 4.83338 4.85732 4.87815 4.89514 4.90927 4.92108 4.93122 4.94014 4.94845 4.95601 4.96251 4.96576 4.969 4.97225 4.9755 4.97874 4.98087 4.98265 4.98442 4.9862 4.98797 4.98924 4.9899 4.99055 4.9912 4.99186 4.99251 4.99316 4.99381 4.99447 4.99512 4.99577 4.99609 4.99634 4.99659 4.99683 4.99708 4.99732 4.99757 4.99782 4.99806 4.99831 4.99853 4.99863 4.99873 4.99883 4.99893 4.99903 4.99913 4.99923 4.99933 } v14 set { 1.86175 2.00147 1.85141 1.0654 0.275481 0.205547 0.0712627 0.0313387 0.0151431 0.00864531 0.00593861 0.00438111 0.0037479 0.00305857 0.00221221 0.0017081 -0.0896128 -0.109079 -0.121356 -0.0542001 0.175821 0.177442 0.0814591 0.0333042 0.0134909 0.00625777 0.00100092 -0.00552776 -0.00411139 -0.00150395 -0.000564784 3.48169e-05 -0.000287014 -0.000538515 -0.000456537 -0.000325677 -0.000275468 -0.000166452 -8.27481e-05 -8.28704e-05 -7.47644e-05 -4.60552e-05 -2.61481e-06 2.26359e-05 2.53852e-05 -1.39853e-06 -4.23456e-05 -4.0907e-05 -2.8501e-05 -1.5945e-05 -9.01122e-06 -2.07747e-06 1.49328e-06 4.38398e-06 6.84248e-06 4.76711e-06 2.69173e-06 6.16362e-07 -1.45901e-06 -3.53438e-06 -4.14256e-06 -3.76238e-06 -3.3822e-06 -3.00202e-06 -2.62184e-06 -2.24878e-06 -1.93456e-06 -1.62033e-06 -1.3061e-06 -9.91867e-07 -6.77638e-07 -3.63409e-07 -4.91792e-08 2.6505e-07 5.7928e-07 8.93509e-07 1.16076e-06 1.11055e-06 1.06034e-06 1.01014e-06 9.59927e-07 9.09719e-07 8.59511e-07 8.09302e-07 7.59094e-07 7.08886e-07 6.58678e-07 5.99251e-07 4.87523e-07 3.75795e-07 2.64068e-07 1.5234e-07 4.06119e-08 -7.1116e-08 -1.82844e-07 -2.94572e-07 -4.063e-07 -5.18027e-07 -6.08517e-07 -5.95879e-07 -5.83241e-07 -5.70604e-07 -5.57966e-07 -5.45328e-07 -5.3269e-07 -5.20053e-07 -5.07415e-07 -4.94777e-07 -4.8214e-07 -4.69502e-07 -4.56864e-07 -4.44226e-07 -4.31589e-07 -4.18951e-07 -4.06313e-07 -3.93676e-07 -3.81038e-07 -3.684e-07 -3.55762e-07 -3.43125e-07 1.06736e-05 0.0797407 0.0437947 -0.0645098 -0.0877312 0.0653203 -0.00621184 -0.0353188 -0.0491378 -0.0251957 -0.0110996 -0.00481123 -0.0020941 -0.000998038 -0.000478747 -0.000445332 -0.102046 -0.135753 -0.154351 -0.0827509 0.163348 0.174012 0.0794822 0.0310624 0.0112213 0.00249061 0.00130764 0.00181315 0.00163875 0.00101454 0.000497435 0.000195258 5.31901e-05 2.4607e-05 6.62736e-05 7.90718e-05 4.0372e-05 -0.000141184 -0.000280623 5.5608e-05 0.000799565 0.000920189 0.000931616 0.000494527 0.000162303 -8.24884e-05 -0.000183938 -0.000203899 -0.000144788 -9.87063e-05 -0.000227929 2.93932e-05 0.000208563 1.88958e-06 -7.6335e-05 -0.000172472 -0.000165656 -0.000145889 -0.000177311 -0.000191058 -0.000168287 -0.00015755 -0.00013142 -8.10488e-05 -6.36115e-05 -7.8699e-05 -8.11282e-05 -7.98625e-05 -5.98807e-05 -3.40879e-05 -1.95464e-05 -1.79247e-05 -4.45514e-05 -7.47995e-05 -8.7682e-05 -7.50806e-05 -3.25561e-05 -4.34114e-05 -7.69099e-05 -0.000141101 -0.00018743 -0.000148471 -5.06546e-05 0.000120195 0.000177635 0.000177052 0.000146344 9.75126e-05 8.31233e-05 6.8734e-05 5.43447e-05 3.99554e-05 2.55661e-05 1.11768e-05 -3.21253e-06 -3.88937e-06 -3.56628e-06 -3.24318e-06 -2.92008e-06 -2.59699e-06 -2.27389e-06 -1.9508e-06 -1.73227e-06 -1.56796e-06 -1.40365e-06 -1.23934e-06 -1.07503e-06 -9.10722e-07 -7.46412e-07 -5.82101e-07 -4.1779e-07 -2.5348e-07 -8.91694e-08 7.51412e-08 2.39452e-07 4.03762e-07 5.95733e-07 1.00771e-06 1.41969e-06 1.83167e-06 2.24365e-06 0.0828257 0.231038 0.465438 1.54516 2.8461 3.19221 3.40395 3.6382 3.80758 3.93848 4.04882 4.15428 4.247 4.32917 4.40235 4.36941 4.397 4.48862 4.64552 4.86595 5.03475 5.0348 5.02627 5.01967 5.01542 5.00925 4.98613 4.9519 4.91581 4.87357 4.82302 4.80403 4.82565 4.86102 4.89483 4.92253 4.94428 4.96257 4.97608 4.98373 4.98823 4.99182 4.99437 4.99635 4.99745 4.99802 4.99843 4.99873 4.99895 4.99912 4.99925 4.99931 4.99962 4.99973 4.99972 4.99971 4.9997 4.99969 4.9997 4.99971 4.99973 4.99974 4.99976 4.99978 4.9998 4.99982 4.99985 4.99987 4.99989 4.9999 4.99991 4.99991 4.99993 4.99994 4.99997 5.00001 5.00006 5.00008 5.00006 5.00002 5 4.99999 4.99998 4.99997 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99999 5 5 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 } v15 set { 1.86175 2.00199 2.08919 1.84314 1.08254 0.214737 0.0377351 0.00952455 0.00232763 0.000563614 0.000263477 0.000148642 0.000285086 0.000242592 7.34699e-05 -1.53467e-05 -0.0161874 -0.0157876 -0.0141194 0.0132576 0.0903272 0.109938 0.0535295 0.0224216 0.00940945 0.00466825 -0.000649972 -0.00654752 -0.00333248 -0.00103671 -0.000508276 -5.8896e-05 -0.00043938 -0.000544704 -0.00044444 -0.000307093 -0.00024517 -0.000154538 -8.78602e-05 -7.10461e-05 -6.06485e-05 -3.91039e-05 -8.45988e-06 9.43442e-06 1.28351e-05 -2.16734e-06 -2.6142e-05 -2.54768e-05 -1.88997e-05 -1.17906e-05 -7.3808e-06 -2.97101e-06 1.19146e-07 2.94246e-06 5.38942e-06 3.88851e-06 2.38761e-06 8.86704e-07 -6.14201e-07 -2.11511e-06 -2.59565e-06 -2.38885e-06 -2.18205e-06 -1.97525e-06 -1.76845e-06 -1.56241e-06 -1.36258e-06 -1.16276e-06 -9.62939e-07 -7.63116e-07 -5.63293e-07 -3.6347e-07 -1.63647e-07 3.61756e-08 2.35999e-07 4.35822e-07 6.07653e-07 5.90323e-07 5.72994e-07 5.55665e-07 5.38336e-07 5.21007e-07 5.03678e-07 4.86349e-07 4.6902e-07 4.51691e-07 4.34361e-07 4.11899e-07 3.60315e-07 3.08731e-07 2.57146e-07 2.05562e-07 1.53977e-07 1.02393e-07 5.08082e-08 -7.76222e-10 -5.23607e-08 -1.03945e-07 -1.47815e-07 -1.54225e-07 -1.60635e-07 -1.67045e-07 -1.73455e-07 -1.79864e-07 -1.86274e-07 -1.92684e-07 -1.99094e-07 -2.05504e-07 -2.11914e-07 -2.18324e-07 -2.24734e-07 -2.31144e-07 -2.37554e-07 -2.43964e-07 -2.50373e-07 -2.56783e-07 -2.63193e-07 -2.69603e-07 -2.76013e-07 -2.82423e-07 2.92534e-06 0.0446777 0.024278 -0.0518987 -0.0636547 0.00983929 -0.000518204 -0.000265194 0.000154772 0.000299538 3.12715e-05 -3.18225e-05 -2.48268e-05 -1.16701e-05 -6.05117e-06 7.61116e-06 -0.0163668 -0.0158244 -0.0141177 0.0100085 0.0857144 0.107784 0.051862 0.0204448 0.00629858 0.000967736 0.00121674 0.00190276 0.00154009 0.000860922 0.000410386 0.000164585 3.99493e-05 1.93797e-05 5.67594e-05 0.000110126 2.49925e-05 -7.17815e-05 -0.000142299 -1.63109e-05 0.000439529 0.000562489 0.000594599 0.000326164 0.000126423 -4.26063e-05 -0.000122927 -0.000114152 -6.72706e-05 -6.41242e-05 -0.000135588 2.61507e-05 0.000134036 6.43734e-06 -4.6223e-05 -0.000112047 -0.000101388 -8.67847e-05 -0.000117664 -0.000133957 -0.000116558 -0.000100873 -7.65448e-05 -4.44964e-05 -3.6677e-05 -5.26632e-05 -5.45172e-05 -5.13545e-05 -3.73869e-05 -1.99732e-05 -1.0907e-05 -1.10081e-05 -3.02609e-05 -5.18517e-05 -6.13597e-05 -5.30706e-05 -2.39572e-05 -3.24146e-05 -5.70062e-05 -0.000103448 -0.000135376 -0.0001024 -2.39007e-05 0.000110929 0.000151226 0.000142044 0.000105922 5.62834e-05 4.78476e-05 3.94117e-05 3.09759e-05 2.25401e-05 1.41042e-05 5.66837e-06 -2.76747e-06 -3.08639e-06 -2.81341e-06 -2.54043e-06 -2.26745e-06 -1.99447e-06 -1.72149e-06 -1.44851e-06 -1.26226e-06 -1.12096e-06 -9.79661e-07 -8.38363e-07 -6.97065e-07 -5.55768e-07 -4.1447e-07 -2.73173e-07 -1.31875e-07 9.42259e-09 1.5072e-07 2.92018e-07 4.33315e-07 5.74613e-07 7.10363e-07 8.01984e-07 8.93604e-07 9.85225e-07 1.07685e-06 0.04474 0.0928765 0.141327 0.0176048 -0.071675 -0.0124613 0.989022 2.28104 3.40619 4.21417 4.67173 4.87438 4.96044 4.98996 4.99858 4.96672 4.89502 4.79391 4.76433 4.8387 4.98612 5.0161 5.01722 5.01437 5.01256 4.99827 4.95807 4.9209 4.88217 4.83006 4.78461 4.80759 4.85548 4.89604 4.9254 4.94617 4.96126 4.97374 4.98255 4.98792 4.99126 4.99361 4.99554 4.99699 4.99792 4.99846 4.99881 4.99905 4.99924 4.99938 4.99949 4.99955 4.9997 4.9998 4.99982 4.99982 4.99982 4.99982 4.99982 4.99983 4.99984 4.99985 4.99986 4.99987 4.99988 4.99989 4.9999 4.99992 4.99993 4.99994 4.99995 4.99995 4.99996 4.99996 4.99998 4.99999 5.00001 5.00002 5.00002 5.00001 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 } v16 set { 1.86175 1.73073 1.50572 1.89001 3.39004 4.36034 4.79012 4.93798 4.98305 4.99539 4.9979 4.99904 4.99772 4.9983 4.99935 4.99975 4.98837 4.99456 4.99728 5.01838 5.04568 5.00759 4.98112 4.98479 4.99197 4.99641 4.99747 4.99775 5.00043 5.0007 5.00035 5.00023 4.99976 5.00002 5.00007 5.0002 4.99993 5.00003 5.00021 5.00006 4.99993 4.99992 5.00002 5.00013 5.00017 5.00009 4.99992 4.99991 4.99993 4.99996 4.99998 4.99999 5.00001 5.00003 5.00005 5.00004 5.00004 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.01498 4.99342 4.96899 5.00301 5.02627 4.9977 4.99548 4.99757 5.00277 5.00245 5.0014 5.00069 5.00032 5.00014 5.00009 4.9867 4.99262 4.99607 5.01805 5.04713 5.00927 4.98184 4.98483 4.9914 4.99616 4.99902 4.9999 4.99987 4.99979 4.99981 4.99989 4.99994 4.99998 5.0002 5.00001 5.00008 5.00008 5.0001 5.00021 5.00032 5.00025 5.00019 5.00006 5.00007 4.99994 4.99997 4.99999 5.00023 5.00008 4.99993 4.99998 4.99986 4.99982 5.00003 4.99985 4.99996 5.00014 5 4.99984 4.99979 4.99982 4.99993 5.00008 5.00011 5.00002 4.99996 4.9999 4.99994 5.00001 5.00007 5.00009 4.99995 4.99978 4.99971 4.99976 4.99997 4.99996 4.99989 4.99972 4.99955 4.99953 4.99959 4.99976 4.9999 5.00005 5.00023 5.00039 5.00034 5.00029 5.00024 5.00019 5.00014 5.00009 5.00004 5.00003 5.00002 5.00001 5 5 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00002 5.00003 5.00004 5.01564 5.03395 5.04932 5.11868 3.92502 1.31888 0.163888 0.0946876 0.0789578 0.0565084 0.0260333 0.0156986 0.00907667 0.00613629 0.00468417 -0.00174008 -0.0021422 0.000586962 0.0124937 0.0147977 0.00838454 0.00039383 -0.000522021 -0.000426598 -0.000290214 -0.00173713 -0.00384132 -0.00382945 -0.00429219 -0.00580193 -0.00393246 0.0017543 0.00423045 0.00408931 0.0031976 0.00245457 0.00187293 0.00159068 0.00105697 0.000609902 0.000358825 0.000334125 0.000212708 0.000168116 8.97349e-05 5.21578e-05 3.84527e-05 2.93033e-05 2.10067e-05 1.59954e-05 1.13917e-05 5.49738e-06 2.77217e-05 6.51259e-06 -6.65468e-06 2.09837e-06 -6.617e-06 -4.80187e-06 1.55031e-06 4.26536e-06 7.69457e-07 -1.46213e-06 -7.25202e-07 3.26501e-06 6.55807e-06 7.524e-06 6.07209e-06 6.00701e-06 5.41166e-06 3.86573e-06 1.10651e-06 -2.74603e-06 -2.18566e-06 2.3658e-06 8.59956e-06 8.35046e-06 2.90621e-06 -8.75982e-07 -1.87189e-06 -2.1528e-06 -1.94875e-06 -1.74471e-06 -1.54067e-06 -1.33662e-06 -1.13258e-06 -8.40567e-07 -5.20743e-07 -2.00918e-07 1.18906e-07 4.38731e-07 6.11382e-07 6.01529e-07 5.91675e-07 5.81822e-07 5.71968e-07 5.62115e-07 5.52261e-07 5.42407e-07 5.32554e-07 5.227e-07 5.12847e-07 4.72812e-07 4.26137e-07 3.79462e-07 3.32786e-07 2.86111e-07 2.39436e-07 1.92761e-07 1.46086e-07 9.94107e-08 5.27356e-08 -2.77779e-10 -7.98079e-08 -1.59338e-07 -2.38868e-07 -3.18398e-07 -3.97928e-07 -4.77458e-07 -5.56988e-07 -6.36519e-07 } v17 set { 5 5.16963 4.84136 3.33754 0.316206 0.103113 0.0273341 0.0221102 0.0177008 0.0143758 0.0115203 0.00929231 0.00752716 0.00625439 0.00489872 0.00403656 -0.0657317 -0.0256467 0.165394 0.985963 3.05067 4.55799 4.89728 4.92464 4.8882 4.90592 4.97315 4.99241 4.99694 4.99845 4.99905 4.99939 4.99959 4.99971 4.9998 4.99986 4.9999 4.99993 4.99995 4.99996 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00001 5.00003 5.00005 5.00004 5.00002 5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00025 5.1657 4.69981 2.43895 0.0229743 0.0351406 -0.0211974 -0.0312063 -0.0160331 -0.0021718 -0.000766597 -0.000251052 -5.49363e-05 -3.36364e-06 -2.01983e-06 -9.70575e-06 -0.0657007 -0.0205247 0.183332 1.07163 3.11839 4.46213 4.84163 4.95195 4.99159 5.02084 5.04029 5.04138 5.0271 5.00445 4.97957 4.95702 4.95231 4.97819 4.99191 4.9963 4.99822 4.99878 4.99903 4.99925 4.99942 4.9995 4.99954 4.99957 4.99961 4.99966 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 4.99988 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.14239 4.76219 3.16574 0.299969 0.0631609 -0.00118611 -0.00026052 -5.96333e-05 -1.44904e-05 -4.3859e-06 -2.99454e-06 1.10547e-06 4.84662e-06 1.30971e-05 2.23082e-05 -0.0655844 -0.0204818 0.182507 1.05954 3.12277 4.46735 4.83915 4.94512 4.97679 4.98654 4.9966 5.00833 5.00776 5.00432 5.00199 5.00086 5.00033 5.00008 5 5.00001 5 5.00005 5.00002 4.99981 4.99991 4.99998 4.99979 4.99979 4.99984 4.9998 4.9998 5.00006 5.00002 5.00001 5 5 4.99992 4.99998 4.99999 5.00002 5.00014 4.99999 4.99987 4.99993 5.00003 5.00011 5.00005 4.99996 4.99987 4.99985 4.99994 5.00009 5.0001 5 4.99993 4.99997 5.00008 5.00015 5.00021 5.00021 5.00007 4.99978 4.99965 4.99973 4.9999 4.99992 4.99995 4.99997 4.99999 5.00001 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 } v18 set { 5 5.0333 5.02472 4.92559 4.18383 3.93923 3.9961 4.14293 4.28591 4.41336 4.52157 4.61101 4.68472 4.7439 4.79294 4.83239 4.80697 4.78808 4.79322 4.8838 5.08529 5.21863 4.88852 3.90198 2.14586 0.383977 0.101103 0.0525711 0.0318287 0.020895 0.0146908 0.010831 0.00830272 0.00656377 0.00532066 0.00440078 0.00369956 0.00315713 0.00272614 0.00237965 0.00209659 0.00186339 0.00167014 0.0015081 0.00137172 0.00125607 0.00115393 0.00106076 0.000980166 0.000918015 0.000862837 0.00080766 0.000763488 0.000721541 0.000680825 0.000653026 0.000625226 0.000597426 0.000569627 0.000541827 0.000519087 0.000499756 0.000480424 0.000461093 0.000441761 0.000423291 0.000411941 0.00040059 0.00038924 0.000377889 0.000366539 0.000355188 0.000343838 0.000332487 0.000321137 0.000309786 0.000299055 0.000292509 0.000285963 0.000279417 0.000272871 0.000266325 0.000259779 0.000253233 0.000246686 0.00024014 0.000233594 0.000227387 0.0002231 0.000218813 0.000214526 0.00021024 0.000205953 0.000201666 0.000197379 0.000193092 0.000188805 0.000184519 0.000180526 0.000177963 0.0001754 0.000172837 0.000170274 0.000167711 0.000165148 0.000162585 0.000160022 0.000157459 0.000154895 0.000152332 0.000149769 0.000147206 0.000144643 0.00014208 0.000139517 0.000136954 0.000134391 0.000131828 0.000129265 0.000126702 0.000132838 0.0311184 0.163151 0.34986 0.604501 0.357125 0.136137 0.0711304 0.0346959 0.0212674 0.00872193 0.00252206 0.000455269 7.59332e-05 2.91532e-05 0.000320562 -0.0720911 -0.0840491 -0.0791345 -0.0404143 0.0182035 -0.0235871 -0.0426072 -0.0597501 0.00824773 0.481404 1.32496 2.11949 2.57317 2.58202 2.15054 1.33786 0.45702 0.153772 0.0913584 0.0604989 0.0421591 0.0271456 0.0170021 0.0115815 0.00907886 0.00742466 0.00626096 0.00531127 0.00450501 0.00381927 0.00323718 0.00274374 0.00232494 0.00196885 0.00166686 0.00141134 0.00119437 0.0010109 0.000855534 0.000723378 0.000611408 0.000516704 0.000436769 0.000369523 0.000313026 0.00026526 0.000223976 0.000188972 0.000159042 0.000134148 0.000112688 9.49738e-05 7.97877e-05 6.721e-05 5.65115e-05 4.77194e-05 4.03591e-05 3.42848e-05 2.92627e-05 2.50435e-05 2.1412e-05 1.84532e-05 1.58624e-05 1.34673e-05 1.14461e-05 1.00935e-05 9.12375e-06 8.50202e-06 7.81431e-06 7.20729e-06 6.73936e-06 6.3702e-06 5.90049e-06 5.43077e-06 4.96105e-06 4.49133e-06 4.02162e-06 3.5519e-06 3.08218e-06 2.79099e-06 2.51281e-06 2.23463e-06 1.95645e-06 1.67827e-06 1.40009e-06 1.12191e-06 1.01376e-06 9.9375e-07 9.73741e-07 9.53733e-07 9.33724e-07 9.13715e-07 8.93707e-07 8.73698e-07 8.5369e-07 8.33681e-07 8.13673e-07 7.93664e-07 7.73655e-07 7.53647e-07 7.21781e-07 5.956e-07 4.69419e-07 3.43239e-07 2.17058e-07 0.0284032 0.0374438 -0.0157543 -0.0680497 0.0504768 0.0100294 0.00222261 0.000528697 0.000132929 3.99489e-05 2.46066e-05 4.56327e-06 -6.54853e-06 1.33783e-05 -3.68221e-05 -0.0724498 -0.0843663 -0.0792935 -0.0406426 0.0200019 0.0426259 0.0220753 0.00668555 -0.000968483 0.024662 0.0383437 0.0911513 0.087848 0.0602076 0.0390559 0.0260573 0.0180444 0.012974 0.00985409 0.00788132 0.0064228 0.005545 0.00453571 0.00364245 0.00310278 0.00270523 0.00236439 0.0020945 0.00186808 0.00167493 0.00151731 0.00138594 0.00126945 0.00116695 0.0010762 0.000996366 0.000928387 0.000864414 0.000808258 0.000759574 0.000713865 0.000666712 0.000632716 0.000601262 0.000572163 0.000543986 0.000515253 0.0004897 0.000468112 0.000449313 0.000432981 0.000417911 0.000401307 0.000382712 0.000366678 0.000355736 0.000349171 0.000335727 0.000317091 0.000296086 0.000283543 0.000277366 0.000272233 0.000267001 0.000263147 0.000256699 0.000250251 0.000243803 0.000237355 0.000230907 0.000225424 0.000220247 0.000215069 0.000209892 0.000204714 0.000200213 0.000196548 0.000192884 0.00018922 0.000185556 0.000181892 0.000178228 0.000174564 0.0001709 0.000167236 0.000163572 0.000160824 0.000158279 0.000155733 0.000153187 0.000150641 0.000148095 0.000145549 0.000143003 0.000140457 0.000137911 0.000135457 0.000133386 0.000131315 0.000129245 0.000127174 0.000125103 0.000123032 0.000120961 0.000118891 } v19 set { 1.86175 1.99994 2.0833 2.01627 2.42503 3.25769 3.62134 3.88827 4.09688 4.26773 4.40529 4.51734 4.60827 4.68313 4.74346 4.79302 4.72815 4.68959 4.70421 4.81316 5.01375 5.14493 5.10305 5.0699 5.04484 5.03751 5.03348 5.02504 5.01799 5.01271 5.00895 5.00628 5.0044 5.00309 5.00216 5.00151 5.00105 5.00073 5.00051 5.00034 5.00023 5.00015 5.0001 5.00007 5.00003 4.99998 4.99993 4.99993 4.99995 4.99999 5.00001 5.00003 5.00002 5.00001 5 5 5 5 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00017 5.17398 4.94779 3.78508 1.52302 0.608808 0.244311 0.126053 0.0597175 0.038422 0.0158174 0.00481338 0.00107847 0.000301256 0.000114861 0.00059489 -0.118904 -0.147478 -0.158986 -0.080544 0.165361 0.171378 0.0776087 0.0435738 0.0428235 0.0423755 0.0347695 0.0225061 0.0155539 0.0121357 0.0107997 0.0103976 0.0124406 0.016814 0.0167556 0.0149852 0.01459 0.0141182 0.0131934 0.0120286 0.0108692 0.0097184 0.00855881 0.00744912 0.00643877 0.00554044 0.00475165 0.00406535 0.00347158 0.00295981 0.00251995 0.00214318 0.00182101 0.00154613 0.00131196 0.0011119 0.000941587 0.000796999 0.000674582 0.000571283 0.000484276 0.000410649 0.000347005 0.000292984 0.000246715 0.000208143 0.00017489 0.000147412 0.000123854 0.000104332 8.77229e-05 7.40686e-05 6.2637e-05 5.32e-05 4.53946e-05 3.88343e-05 3.31864e-05 2.85905e-05 2.45725e-05 2.08671e-05 1.77301e-05 1.55911e-05 1.40153e-05 1.29421e-05 1.18693e-05 1.09815e-05 1.03484e-05 9.87664e-06 9.14446e-06 8.41228e-06 7.68011e-06 6.94793e-06 6.21575e-06 5.48357e-06 4.7514e-06 4.38454e-06 4.04432e-06 3.7041e-06 3.36388e-06 3.02366e-06 2.68344e-06 2.34322e-06 2.15196e-06 2.03791e-06 1.92386e-06 1.80982e-06 1.69577e-06 1.58173e-06 1.46768e-06 1.35363e-06 1.23959e-06 1.12554e-06 1.0115e-06 8.9745e-07 7.83404e-07 6.69358e-07 4.76113e-07 -3.47071e-07 -1.17025e-06 -1.99344e-06 -2.81662e-06 0.0783754 0.0500262 -0.0659563 -0.120914 0.0815957 0.0154255 0.00347177 0.000840357 0.000214582 6.54655e-05 3.91709e-05 8.07396e-06 -4.44265e-07 1.74384e-05 -4.52725e-05 -0.119379 -0.147984 -0.159247 -0.0824604 0.169014 0.177628 0.0758742 0.010558 -0.0346506 -0.0710288 -0.0838952 -0.0599521 -0.034568 -0.0181615 -0.00968034 -0.00547115 -0.00333511 -0.00232468 -0.00181159 -0.00143841 -0.00116601 -0.000839755 -0.000569764 -0.000578683 -0.000490551 -0.000411712 -0.000437859 -0.000408185 -0.000356644 -0.000311332 -0.000269006 -0.000221396 -0.000210054 -0.0001923 -0.000175122 -0.000161039 -0.0001428 -0.000126123 -0.000127893 -8.14516e-05 -0.000120166 -0.000154909 -0.000112733 -8.40377e-05 -7.11342e-05 -8.09538e-05 -9.77789e-05 -9.82402e-05 -7.73531e-05 -5.28255e-05 -3.1096e-05 -1.87967e-05 -1.96552e-05 -4.16655e-05 -5.77185e-05 -5.24142e-05 -2.83153e-05 -1.90012e-05 -1.54415e-05 -2.52569e-05 -6.23747e-05 -0.000130543 -0.000149394 -0.000110886 -4.35517e-05 -4.17084e-05 -3.98651e-05 -3.80218e-05 -3.61785e-05 -3.43352e-05 -3.36249e-05 -3.32729e-05 -3.29208e-05 -3.25687e-05 -3.22166e-05 -3.17143e-05 -3.10258e-05 -3.03372e-05 -2.96486e-05 -2.89601e-05 -2.82715e-05 -2.75829e-05 -2.68944e-05 -2.62058e-05 -2.55173e-05 -2.48287e-05 -2.43043e-05 -2.38159e-05 -2.33276e-05 -2.28393e-05 -2.2351e-05 -2.18626e-05 -2.13743e-05 -2.0886e-05 -2.03977e-05 -1.99093e-05 -1.945e-05 -1.91122e-05 -1.87744e-05 -1.84366e-05 -1.80987e-05 -1.77609e-05 -1.74231e-05 -1.70853e-05 -1.67474e-05 } v20 set { 1.86175 1.99724 2.17266 2.48439 3.15933 3.85231 4.38091 4.69033 4.85034 4.92851 4.96453 4.98188 4.98736 4.991 4.99482 4.9973 4.96422 4.89989 4.83907 4.83151 4.90868 5.04854 5.06104 5.04571 5.03219 5.03025 5.02273 5.01707 5.0123 5.0087 5.00611 5.00429 5.00301 5.00211 5.00148 5.00103 5.00072 5.0005 5.00035 5.00024 5.00016 5.00011 5.00007 5.00005 5.00003 5.00001 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 5 5 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99981 5.10081 5.10903 4.98404 5.00999 5.14946 4.36501 2.23938 0.325144 0.00660272 -0.0102186 -0.0082401 -0.00556785 -0.00374178 -0.00264763 -0.00202823 -0.0182241 -0.0169551 -0.0150395 0.0103736 0.0877592 0.104382 0.0515938 0.0373818 0.0411547 0.0397009 0.0308946 0.0205793 0.0154037 0.0129191 0.0119327 0.011527 0.0124295 0.0161152 0.0161076 0.0145391 0.0144541 0.0139287 0.0129215 0.0117239 0.0105795 0.00942983 0.00827423 0.00718354 0.00619954 0.00532868 0.00456631 0.00390448 0.00333254 0.00284003 0.00241714 0.00205524 0.0017458 0.00148202 0.00125739 0.0010655 0.000902213 0.000763611 0.000646279 0.000547291 0.000463934 0.000393401 0.000332424 0.000280655 0.000236328 0.000199386 0.000167536 0.000141218 0.000118654 9.99559e-05 8.40479e-05 7.09694e-05 6.00188e-05 5.09786e-05 4.3502e-05 3.72191e-05 3.18114e-05 2.74071e-05 2.35539e-05 1.99967e-05 1.69871e-05 1.49449e-05 1.3451e-05 1.24492e-05 1.14256e-05 1.05669e-05 9.94487e-06 9.47514e-06 8.77318e-06 8.07123e-06 7.36927e-06 6.66731e-06 5.96536e-06 5.2634e-06 4.56144e-06 4.23044e-06 3.92649e-06 3.62254e-06 3.31858e-06 3.01463e-06 2.71068e-06 2.40673e-06 2.23063e-06 2.12082e-06 2.01102e-06 1.90121e-06 1.7914e-06 1.68159e-06 1.57178e-06 1.46197e-06 1.35216e-06 1.24235e-06 1.13255e-06 1.02274e-06 9.12929e-07 8.0312e-07 6.33171e-07 -1.51288e-08 -6.63428e-07 -1.31173e-06 -1.96003e-06 0.0437517 0.0265689 -0.0515377 -0.0658688 0.010727 -0.000511921 -8.36924e-05 2.13278e-05 1.45207e-05 4.54862e-06 -6.14726e-06 2.0062e-06 1.02709e-06 1.4152e-05 -3.08225e-05 -0.0166501 -0.0157139 -0.013957 0.0107537 0.0873717 0.111302 0.0454129 -0.00530142 -0.0468336 -0.0790063 -0.0826944 -0.0534753 -0.0288705 -0.0149009 -0.00801592 -0.0046342 -0.00291835 -0.00213019 -0.00170055 -0.001352 -0.00110593 -0.000742655 -0.000532042 -0.000544742 -0.000479206 -0.000407307 -0.000403575 -0.000366209 -0.000324161 -0.000286183 -0.000247579 -0.000214281 -0.000203435 -0.000186896 -0.000171033 -0.00015779 -0.000145259 -0.000128069 -0.000122647 -9.89398e-05 -0.000114926 -0.000132195 -0.000107872 -8.91015e-05 -7.87996e-05 -8.14061e-05 -8.9098e-05 -8.83368e-05 -7.6122e-05 -6.14668e-05 -4.75402e-05 -3.81855e-05 -3.69696e-05 -4.78656e-05 -5.61346e-05 -5.35007e-05 -4.1459e-05 -3.35411e-05 -2.52374e-05 -2.37479e-05 -4.6406e-05 -9.41884e-05 -0.000109222 -8.52676e-05 -4.25166e-05 -4.10125e-05 -3.95085e-05 -3.80045e-05 -3.65004e-05 -3.49964e-05 -3.41627e-05 -3.3541e-05 -3.29193e-05 -3.22976e-05 -3.16758e-05 -3.10334e-05 -3.03653e-05 -2.96971e-05 -2.9029e-05 -2.83609e-05 -2.76928e-05 -2.70246e-05 -2.63565e-05 -2.56884e-05 -2.50203e-05 -2.43521e-05 -2.38716e-05 -2.34324e-05 -2.29932e-05 -2.25539e-05 -2.21147e-05 -2.16755e-05 -2.12362e-05 -2.0797e-05 -2.03578e-05 -1.99186e-05 -1.95079e-05 -1.9217e-05 -1.8926e-05 -1.8635e-05 -1.8344e-05 -1.8053e-05 -1.7762e-05 -1.74711e-05 -1.71801e-05 } v21 set { 1.86175 1.73273 1.42016 1.02483 0.944013 0.274107 0.0823742 0.0379366 0.020816 0.0132952 0.00955525 0.00717008 0.00592286 0.00437379 0.00383557 0.00273694 -0.0037467 -0.0054191 -0.00131454 0.0112179 0.0133918 0.00519747 -0.00260113 -0.00252847 -0.00181292 0.000183398 -0.000667607 -0.000750747 -0.000594314 -0.000433904 -0.000308985 -0.000217858 -0.000152926 -0.000107454 -7.54076e-05 -5.2675e-05 -3.66299e-05 -2.54341e-05 -1.75095e-05 -1.18848e-05 -7.97289e-06 -5.30239e-06 -3.53615e-06 -2.38504e-06 -2.40158e-06 -3.84485e-06 -5.29435e-06 -2.57099e-06 1.95189e-06 3.55083e-06 2.06179e-06 5.72753e-07 3.30469e-07 3.40296e-07 3.60221e-07 4.86081e-07 6.1194e-07 7.37799e-07 8.63659e-07 9.89518e-07 9.21274e-07 7.22275e-07 5.23276e-07 3.24277e-07 1.25278e-07 -5.59467e-08 -9.03265e-08 -1.24706e-07 -1.59086e-07 -1.93466e-07 -2.27846e-07 -2.62226e-07 -2.96605e-07 -3.30985e-07 -3.65365e-07 -3.99745e-07 -4.24266e-07 -3.82163e-07 -3.40061e-07 -2.97959e-07 -2.55857e-07 -2.13755e-07 -1.71652e-07 -1.2955e-07 -8.7448e-08 -4.53457e-08 -3.24353e-09 3.76901e-08 7.19937e-08 1.06297e-07 1.40601e-07 1.74904e-07 2.09208e-07 2.43512e-07 2.77815e-07 3.12119e-07 3.46422e-07 3.80726e-07 4.04507e-07 3.77191e-07 3.49876e-07 3.22561e-07 2.95246e-07 2.67931e-07 2.40616e-07 2.13301e-07 1.85986e-07 1.58671e-07 1.31356e-07 1.04041e-07 7.67256e-08 4.94105e-08 2.20955e-08 -5.21962e-09 -3.25347e-08 -5.98498e-08 -8.71649e-08 -1.1448e-07 -1.41795e-07 -1.6911e-07 7.87893e-06 0.0114592 -0.0245712 -0.111637 0.0961324 1.61168 3.22343 4.20442 4.53535 4.83834 4.95464 4.98874 4.99746 4.99883 4.99948 4.99815 4.98431 4.99298 4.99718 5.01948 5.04749 5.008 4.98243 4.98985 4.99781 4.99887 4.99679 4.99616 4.99743 4.99859 4.99936 4.99972 5.00058 5.00123 5.0002 4.99945 4.99983 4.9998 4.99966 4.99958 4.99956 4.99956 4.99956 4.99958 4.99961 4.99965 4.99969 4.99973 4.99977 4.9998 4.99983 4.99985 4.99987 4.99989 4.99991 4.99992 4.99993 4.99994 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.01454 4.99566 4.96796 4.99819 5.03232 5.00034 4.99867 4.99937 4.99977 4.99992 4.99997 4.99999 5.00001 5.00021 4.99974 4.98462 4.99301 4.99723 5.01936 5.04807 5.00929 4.9789 4.97876 4.98244 4.9863 4.99575 5.0069 5.00863 5.00624 5.00357 5.0019 5.00098 5.00048 5.00025 5.00016 5.00011 5.00013 5.00009 4.99982 4.99994 5.00005 4.99994 4.99988 4.99989 4.99997 5.00003 5.00005 5.00002 5.00001 5.00001 5.00001 4.99993 4.99999 5 5.00021 4.99997 4.99981 5 5.00009 5.0001 5.00001 4.99991 4.9999 5 5.00011 5.00017 5.00018 5.00018 5.00014 5.00007 4.99999 4.9999 4.9999 5.00001 5.00016 5.00014 4.99999 4.99993 4.99999 5.00009 5.00007 5.00006 5.00004 5.00003 5.00001 5.00001 5 4.99999 4.99998 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 } v22 set { 7.10441e-10 0.00107105 0.000637109 -0.00236346 -0.018079 -0.0120077 -0.00217059 0.00266679 0.00403383 0.00403836 0.00356705 0.00303303 0.00244716 0.00198586 0.0016855 0.00136497 -3.96022e-05 -0.000367409 -3.77079e-05 0.00194085 0.00506964 -0.0400214 -0.0402572 0.0524434 0.286234 0.803011 1.44795 2.02473 2.54768 3.02748 3.4415 3.78287 4.09667 4.35152 4.53987 4.67614 4.77407 4.84319 4.89227 4.92702 4.95119 4.96764 4.97846 4.98557 4.98982 4.99209 4.99371 4.99569 4.99727 4.99802 4.99834 4.99867 4.99892 4.99915 4.99936 4.99939 4.99943 4.99946 4.9995 4.99953 4.99957 4.9996 4.99963 4.99967 4.9997 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 4.9998 4.99981 4.99982 4.99983 4.99984 4.99985 4.99986 4.99986 4.99986 4.99987 4.99987 4.99988 4.99988 4.99989 4.99989 4.9999 4.9999 4.9999 4.9999 4.99991 4.99991 4.99991 4.99991 4.99992 4.99992 4.99992 4.99992 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99993 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 5.00145 5.00659 5.01209 5.01931 5.00279 4.99273 4.99217 4.99295 4.99471 4.99594 4.99696 4.9978 4.99844 4.99891 4.99924 4.99635 4.99699 4.99813 5.00068 5.00307 5.0588 4.96365 4.54012 3.6307 2.35176 1.0322 0.354379 0.115986 0.0435668 0.0245112 0.020786 0.0164656 0.0118409 0.00849698 0.00597078 0.0040105 0.0026076 0.0016597 0.00118185 0.00121067 0.00153587 0.00174836 0.00136519 -0.000189116 -0.00315555 -0.00646603 -0.00898042 -0.010203 -0.0110896 -0.0123764 -0.00953841 -0.00225795 0.000818314 0.00152252 0.00150269 0.00119025 0.000767068 0.000308852 -3.79272e-05 -0.00019691 -0.000186642 -9.73653e-05 -8.49784e-06 2.04147e-05 -9.91086e-06 -1.55959e-05 -1.80499e-05 -1.77097e-05 -1.51548e-05 -1.1978e-05 -9.84916e-06 -1.29728e-05 -1.67235e-05 -1.74153e-05 -1.39958e-05 -5.92272e-06 -8.08216e-06 -1.53077e-05 -2.92531e-05 -3.91049e-05 -2.98935e-05 -7.32122e-06 3.18534e-05 4.39134e-05 4.18753e-05 3.22759e-05 1.86766e-05 1.58432e-05 1.30098e-05 1.01765e-05 7.34312e-06 4.50975e-06 1.67639e-06 -1.15697e-06 -1.23877e-06 -1.11991e-06 -1.00106e-06 -8.82208e-07 -7.63355e-07 -6.44502e-07 -5.2565e-07 -4.29318e-07 -3.44661e-07 -2.60004e-07 -1.75347e-07 -9.06904e-08 -6.03349e-09 7.86234e-08 1.6328e-07 2.47937e-07 3.32594e-07 4.17251e-07 5.01908e-07 5.86565e-07 6.71222e-07 7.36123e-07 6.43886e-07 5.5165e-07 4.59414e-07 3.67178e-07 0.000334759 -4.60833e-05 -0.00106139 -0.00166624 0.000859563 0.00102606 0.00410037 0.00419931 0.00518997 0.00459791 0.00503125 0.00523877 0.00452158 0.00339924 0.00233399 0.000876915 0.000546439 0.000444299 0.000983968 0.00119304 -0.0429422 -0.0403983 0.0534896 0.288013 0.807345 1.44247 2.03448 2.57021 3.05049 3.47332 3.8131 4.1009 4.34677 4.53512 4.67127 4.76531 4.82526 4.86593 4.89586 4.91904 4.93806 4.95348 4.96597 4.97629 4.9843 4.98983 4.99335 4.9957 4.99741 4.99864 4.99946 4.99994 5.00047 5.00073 5.00086 5.00092 5.00094 5.00091 5.00087 5.00081 5.00074 5.00067 5.00059 5.00052 5.00046 5.0004 5.00034 5.0003 5.00026 5.00022 5.00019 5.00016 5.00014 5.00012 5.0001 5.00009 5.00007 5.00006 5.00006 5.00005 5.00004 5.00004 5.00004 5.00003 5.00003 5.00003 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 } v23 set { 5 5.00284 5.01266 5.01895 4.98936 4.99575 4.99217 4.99545 4.99775 4.99894 4.99946 4.99968 4.99975 4.99977 4.99986 4.9999 4.99528 4.99808 5.00039 5.00392 5.00512 4.99985 4.99863 4.99942 4.99992 5.00017 4.99897 4.99803 4.99784 4.99739 4.99883 5.00365 5.00298 5.00133 5.00048 5.00019 5.00008 5.00005 5.00004 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 4.99999 4.99997 4.99995 4.99996 4.99998 5 5.00001 5.00001 5.00002 5.00002 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5.00217 5.00108 4.99547 4.99658 5.00667 4.99641 4.99532 4.99938 5.00328 5.00222 5.00114 5.00052 5.00024 5.00011 5.00009 4.99285 4.99591 4.99897 5.00403 5.00786 5.00318 4.99942 4.9992 4.99949 5.001 5.00408 5.00319 5.00063 4.99995 5.00014 4.99982 4.99832 4.99838 4.99865 4.99912 4.99836 4.99735 4.99606 4.99814 5.00958 5.02973 5.05293 5.06103 4.99342 4.80726 4.50744 4.07509 3.41358 2.37924 1.03194 0.261552 0.142392 0.0904482 0.0555071 0.0322869 0.018289 0.0113802 0.00875182 0.00757055 0.00629906 0.00523 0.00403349 0.0031953 0.00280864 0.00286119 0.00250389 0.00202815 0.001723 0.00147312 0.0012411 0.00104401 0.000886204 0.000758277 0.000651915 0.00056348 0.000487966 0.000424048 0.000365613 0.000308178 0.000258725 0.000228061 0.000207976 0.000198491 0.00018518 0.000172716 0.000163197 0.000155007 0.000141734 0.000128461 0.000115188 0.000101915 8.86417e-05 7.53686e-05 6.20956e-05 5.69164e-05 5.23275e-05 4.77385e-05 4.31495e-05 3.85605e-05 3.39716e-05 2.93826e-05 2.69449e-05 2.56224e-05 2.42999e-05 2.29774e-05 2.16549e-05 2.03324e-05 1.90099e-05 1.76873e-05 1.63648e-05 1.50423e-05 1.37198e-05 1.23973e-05 1.10748e-05 9.75232e-06 8.48447e-06 7.65129e-06 6.81811e-06 5.98494e-06 5.15176e-06 0.00056893 -0.00787906 -0.0217381 -0.0370066 -0.00770505 0.00659312 0.00975477 0.00949456 0.00777552 0.00655645 0.00568776 0.00508782 0.00458121 0.00410187 0.00365665 0.0015121 0.00160863 0.00263181 0.00638941 0.00772607 0.00225583 0.0010843 0.000882939 0.000801563 0.00075632 0.000554992 0.000435131 0.0003474 0.000217667 0.000491602 0.0012267 0.00250446 0.000212058 -0.0174972 -0.0527527 -0.0479071 0.194908 1.45838 3.40677 4.49242 4.86894 4.97215 5.01218 5.04342 5.06228 5.03069 4.87169 4.57056 4.11523 3.38264 2.19691 0.715839 0.172818 0.102162 0.0627162 0.0363388 0.020289 0.0119414 0.00826608 0.0066417 0.00549092 0.00492505 0.00439443 0.0037156 0.00306471 0.00247451 0.00195965 0.0014822 0.0010815 0.000904464 0.0010514 0.00152308 0.00120752 0.000228447 -0.00102833 -0.00116644 -0.00042067 4.78758e-05 5.09599e-05 -4.45756e-05 -3.22966e-06 3.81163e-05 7.94622e-05 0.000120808 0.000162154 0.000161895 0.000148481 0.000135068 0.000121654 0.000108241 9.81453e-05 9.2164e-05 8.61827e-05 8.02014e-05 7.42201e-05 6.82388e-05 6.22576e-05 5.62763e-05 5.0295e-05 4.43137e-05 3.83324e-05 3.54323e-05 3.321e-05 3.09877e-05 2.87654e-05 2.65431e-05 2.43209e-05 2.20986e-05 1.98763e-05 1.7654e-05 1.54317e-05 1.34612e-05 1.25441e-05 1.1627e-05 1.07099e-05 9.79276e-06 8.87564e-06 7.95851e-06 7.04139e-06 6.12427e-06 } v24 set { 5 5.01099 5.00866 4.97845 4.92369 4.9273 4.97413 4.9929 4.99826 4.99958 4.99978 5.00005 4.99968 4.99959 5.00014 4.99979 4.99914 4.99982 5.00023 5.00295 5.00664 4.99854 4.99647 5.00438 5.01722 5.03681 5.04766 5.04799 5.04867 5.04873 5.04685 5.04413 5.0367 5.02505 5.01726 5.01183 5.00806 5.00549 5.00371 5.00246 5.00162 5.00105 5.00069 5.00045 5.00031 5.00024 5.00019 5.00012 5.00007 5.00004 5.00001 4.99998 4.99999 4.99999 5 5.00001 5.00001 5.00002 5.00002 5.00003 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5.00418 4.99953 4.99152 4.99807 5.00497 5.00112 5.00055 5.00038 5.00018 5.00006 5.00006 5.00007 5.00006 5.00004 5.00004 4.99853 4.99945 4.99998 5.00304 5.00935 5.00742 4.99181 4.97421 4.93603 4.8853 4.8927 4.93984 4.97458 4.99039 4.99614 4.99801 4.99851 4.99869 4.99924 5.00108 5.00181 5.00119 5.00059 5.00031 5.00022 5.00018 5.00011 5.00001 5.00006 4.99981 4.99977 4.99982 5.00012 4.99993 5.00008 5.00043 5.00048 5.00024 5.00008 4.99984 4.99993 5.00011 4.99996 4.9998 4.99977 4.9998 4.99993 5.00008 5.00011 5.00002 4.99995 4.99989 4.99993 5 5.00007 5.00009 4.99994 4.99977 4.9997 4.99975 4.99996 4.99996 4.99988 4.9997 4.99952 4.9995 4.99956 4.99973 4.99988 5.00005 5.00025 5.00042 5.00036 5.00031 5.00025 5.0002 5.00014 5.00009 5.00003 5.00002 5.00001 5.00001 5 4.99999 4.99998 4.99998 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5.00284 5.00442 5.00381 4.98997 4.99092 5.00733 5.07791 4.98237 4.86434 4.76835 4.74067 4.79278 4.85094 4.90068 4.93603 4.95698 4.96984 4.97856 4.98869 4.99904 5.0005 4.99524 5.00181 5.01878 5.05177 5.07986 4.98917 4.56217 3.68 2.3539 1.18541 0.505772 0.221044 0.115287 0.0760938 0.0589194 0.0476784 0.0457213 0.0412911 0.033889 0.0259741 0.0191452 0.0139018 0.0100235 0.00711788 0.00497657 0.00349368 0.00250021 0.00176179 0.00121843 0.000838368 0.000582711 0.000423458 0.000294608 0.000201251 0.000133748 8.6227e-05 5.44252e-05 3.30514e-05 1.93926e-05 1.09814e-05 5.29857e-06 1.92247e-06 3.08708e-07 -3.74311e-07 -6.11121e-07 -7.27807e-07 -4.87604e-07 -4.80493e-07 -9.15925e-07 -2.03774e-06 -4.01128e-06 -2.46644e-06 2.10626e-06 8.22422e-06 1.04922e-05 9.83047e-06 7.27106e-06 3.29654e-06 -2.06736e-06 -2.18019e-06 -2.29303e-06 -2.40586e-06 -2.51869e-06 -2.63153e-06 -2.24615e-06 -1.70325e-06 -1.16036e-06 -6.17468e-07 -7.45754e-08 2.45198e-07 2.88285e-07 3.31373e-07 3.7446e-07 4.17548e-07 4.60635e-07 5.03723e-07 5.4681e-07 5.89898e-07 6.32985e-07 6.76073e-07 6.19054e-07 5.4001e-07 4.60967e-07 3.81923e-07 3.02879e-07 2.23836e-07 1.44792e-07 6.57488e-08 -1.32948e-08 -9.23383e-08 -1.6698e-07 -2.23206e-07 -2.79432e-07 -3.35658e-07 -3.91884e-07 -4.48109e-07 -5.04335e-07 -5.60561e-07 -6.16787e-07 } v25 set { 1.34824 1.35838 1.36465 1.34675 1.29167 1.23161 1.2201 1.2185 1.2181 1.21798 1.21793 1.21788 1.21785 1.21782 1.21779 1.21776 1.21655 1.21656 1.21669 1.21871 1.22421 1.22247 1.21858 1.2228 1.23803 1.27737 1.10647 0.395248 0.0600669 0.027687 0.0192374 0.015425 0.0130881 0.00977445 0.00696598 0.00491122 0.00341952 0.00237078 0.00162339 0.00109178 0.000726647 0.000478886 0.00031568 0.000207902 0.000143494 0.000109768 8.62987e-05 5.69775e-05 3.36547e-05 2.30356e-05 1.86108e-05 1.41861e-05 1.08293e-05 7.68835e-06 4.79593e-06 4.51019e-06 4.22444e-06 3.9387e-06 3.65295e-06 3.36721e-06 3.04559e-06 2.69981e-06 2.35403e-06 2.00825e-06 1.66247e-06 1.34508e-06 1.26225e-06 1.17941e-06 1.09657e-06 1.01373e-06 9.30893e-07 8.48054e-07 7.65216e-07 6.82378e-07 5.9954e-07 5.16702e-07 4.37489e-07 3.82774e-07 3.2806e-07 2.73346e-07 2.18632e-07 1.63917e-07 1.09203e-07 5.4489e-08 -2.2523e-10 -5.49395e-08 -1.09654e-07 -1.52862e-07 -1.3079e-07 -1.08718e-07 -8.6646e-08 -6.45739e-08 -4.25019e-08 -2.04298e-08 1.64229e-09 2.37144e-08 4.57864e-08 6.78585e-08 8.71693e-08 9.30725e-08 9.89758e-08 1.04879e-07 1.10782e-07 1.16685e-07 1.22589e-07 1.28492e-07 1.34395e-07 1.40298e-07 1.46201e-07 1.52105e-07 1.58008e-07 1.63911e-07 1.69814e-07 1.75718e-07 1.81621e-07 1.87524e-07 1.93427e-07 1.9933e-07 2.05234e-07 2.11137e-07 2.19788e-07 0.000393944 -0.000218983 -0.00105784 0.00172403 -0.00027134 -0.000204147 8.79968e-06 5.93762e-05 5.83554e-05 4.13815e-05 3.71369e-05 3.03372e-05 2.25336e-05 1.5986e-05 1.07284e-05 -7.5239e-05 5.60593e-05 6.97571e-05 0.000667617 0.000960856 0.00131749 -0.00759564 -0.0217897 -0.0450321 -0.076646 -0.128569 -0.186391 -0.202175 -0.206953 -0.2082 -0.208416 -0.208669 -0.208934 -0.209111 -0.209234 -0.209329 -0.209389 -0.209416 -0.2094 -0.209329 -0.20926 -0.209204 -0.209208 -0.209285 -0.209454 -0.209641 -0.20977 -0.209811 -0.209833 -0.209887 -0.209653 -0.209127 -0.208893 -0.208811 -0.208777 -0.208758 -0.208747 -0.20874 -0.208726 -0.208697 -0.208657 -0.208611 -0.208565 -0.208524 -0.208488 -0.208451 -0.208412 -0.208373 -0.208333 -0.208294 -0.208256 -0.208219 -0.208183 -0.208145 -0.208107 -0.208066 -0.208029 -0.207993 -0.207959 -0.207923 -0.207883 -0.207838 -0.207789 -0.207747 -0.20771 -0.207675 -0.207642 -0.207605 -0.207568 -0.207531 -0.207494 -0.207457 -0.20742 -0.207383 -0.207346 -0.207308 -0.207271 -0.207233 -0.207196 -0.207158 -0.207121 -0.207084 -0.207046 -0.207009 -0.206972 -0.206935 -0.206898 -0.206861 -0.206823 -0.206786 -0.206749 -0.206712 -0.206675 -0.206638 -0.2066 -0.206563 -0.206526 -0.206489 -0.206452 -0.206415 -0.203384 -0.20015 -0.196872 -0.205024 -0.210727 -0.206779 -0.0685263 0.586138 1.4665 2.22945 2.77554 3.076 3.24926 3.34515 3.40164 3.43006 3.43713 3.43075 3.42886 3.4384 3.46567 3.49025 3.51287 3.53821 3.57841 3.39846 2.80753 2.22947 1.7549 1.30429 0.707786 0.303206 0.131352 0.0671706 0.0429955 0.032461 0.0257161 0.0239521 0.0217397 0.0179705 0.0138745 0.0102813 0.00749643 0.0054328 0.00386817 0.0027004 0.00189442 0.00135552 0.000954715 0.000659981 0.000453435 0.000313993 0.000231347 0.000159665 0.000108122 7.10528e-05 4.50233e-05 2.77892e-05 1.62765e-05 8.9893e-06 4.5471e-06 1.54614e-06 -1.6542e-07 -8.68508e-07 -1.04369e-06 -9.63086e-07 -8.44294e-07 -6.57339e-07 -7.35885e-07 -9.80056e-07 -1.39772e-06 -2.10199e-06 -1.37474e-06 6.13269e-07 3.3028e-06 4.60941e-06 4.91053e-06 4.14186e-06 2.45258e-06 -8.7388e-09 -3.59647e-07 -7.10554e-07 -1.06146e-06 -1.41237e-06 -1.76328e-06 -1.63073e-06 -1.34534e-06 -1.05995e-06 -7.74561e-07 -4.8917e-07 -2.95733e-07 -2.16326e-07 -1.3692e-07 -5.75135e-08 2.18929e-08 1.01299e-07 1.80706e-07 2.60112e-07 3.39519e-07 4.18925e-07 4.98332e-07 4.83984e-07 4.4901e-07 4.14035e-07 3.79061e-07 3.44087e-07 3.09112e-07 2.74138e-07 2.39163e-07 2.04189e-07 1.69215e-07 1.26002e-07 4.83213e-08 -2.9359e-08 -1.07039e-07 -1.8472e-07 -2.624e-07 -3.4008e-07 -4.1776e-07 -4.95441e-07 } v26 set { 7.10441e-10 0.000309731 -0.000308186 -0.001694 -0.00360784 8.40909e-05 0.00203175 0.0012896 0.000596548 0.000277191 0.000161134 0.000120439 8.4915e-05 9.49929e-05 6.18812e-05 1.65433e-05 1.89682e-05 3.97578e-05 4.95446e-05 0.000225325 0.000214579 -0.00230134 -0.000451102 0.00997237 0.0341443 0.0449314 0.0424411 0.0341996 0.0315315 0.0308892 0.0291614 0.024365 0.0190282 0.0188976 0.017238 0.0138526 0.0105645 0.00778548 0.00561753 0.0039871 0.00279554 0.00194075 0.0013468 0.000934775 0.000664723 0.000498911 0.000377384 0.000254183 0.000163421 0.000120773 9.65058e-05 7.22384e-05 5.60316e-05 4.14549e-05 2.79516e-05 2.57096e-05 2.34677e-05 2.12257e-05 1.89837e-05 1.67417e-05 1.46737e-05 1.27228e-05 1.07719e-05 8.82099e-06 6.87009e-06 5.0896e-06 4.71705e-06 4.34451e-06 3.97196e-06 3.59941e-06 3.22686e-06 2.85431e-06 2.48176e-06 2.10921e-06 1.73666e-06 1.36411e-06 1.02855e-06 9.42931e-07 8.57316e-07 7.71701e-07 6.86086e-07 6.00471e-07 5.14856e-07 4.29241e-07 3.43626e-07 2.58011e-07 1.72396e-07 9.85409e-08 9.14091e-08 8.42773e-08 7.71456e-08 7.00138e-08 6.2882e-08 5.57503e-08 4.86185e-08 4.14867e-08 3.4355e-08 2.72232e-08 2.05821e-08 1.63235e-08 1.2065e-08 7.80643e-09 3.54786e-09 -7.10696e-10 -4.96926e-09 -9.22782e-09 -1.34864e-08 -1.77449e-08 -2.20035e-08 -2.62621e-08 -3.05206e-08 -3.47792e-08 -3.90378e-08 -4.32963e-08 -4.75549e-08 -5.18134e-08 -5.6072e-08 -6.03306e-08 -6.45891e-08 -6.88477e-08 -8.76373e-06 0.000131607 -0.00021685 -0.000433027 0.00047234 0.000211593 -0.000189601 3.2492e-05 0.000575955 7.72235e-05 -0.000285172 -0.000242061 -0.000135112 -3.50117e-05 -2.75868e-05 5.48974e-05 1.80604e-07 5.48911e-05 3.97478e-05 0.000192909 0.000297932 0.00402253 -0.0122366 -0.047853 -0.0963082 -0.108071 -0.0567275 -0.0239271 -0.0178628 -0.0233027 -0.031853 -0.0400843 -0.0482725 -0.0576154 -0.0627218 -0.0511236 -0.0279524 -0.0150986 -0.00931091 -0.00652876 -0.00479286 -0.00344346 -0.00249578 -0.0019532 -0.00157977 -0.00131848 -0.00111251 -0.000939229 -0.000797445 -0.000708384 -0.000630452 -0.000539722 -0.000508862 -0.000480596 -0.000439484 -0.000407217 -0.000363866 -0.000329506 -0.000318642 -0.000307362 -0.000286511 -0.000266253 -0.000242943 -0.000218107 -0.000204661 -0.00020241 -0.000194435 -0.000185062 -0.000173042 -0.000160549 -0.000151407 -0.000145626 -0.000145976 -0.000147342 -0.000145288 -0.000137979 -0.000124481 -0.000123218 -0.000127453 -0.000139006 -0.000145486 -0.000129764 -9.82749e-05 -4.72596e-05 -3.08671e-05 -3.28834e-05 -4.52254e-05 -6.25389e-05 -6.32516e-05 -6.39643e-05 -6.4677e-05 -6.53897e-05 -6.61023e-05 -6.6815e-05 -6.75277e-05 -6.61005e-05 -6.45173e-05 -6.29341e-05 -6.13509e-05 -5.97676e-05 -5.81844e-05 -5.66012e-05 -5.54231e-05 -5.4455e-05 -5.3487e-05 -5.25189e-05 -5.15508e-05 -5.05828e-05 -4.96147e-05 -4.86466e-05 -4.76785e-05 -4.67105e-05 -4.57424e-05 -4.47743e-05 -4.38063e-05 -4.28382e-05 -4.18821e-05 -4.10211e-05 -4.016e-05 -3.9299e-05 -3.8438e-05 4.29885e-05 5.14113e-05 -0.000127986 -0.000611463 -0.000149428 0.000882394 0.00297059 -0.00405825 -0.00591067 -0.00546997 -0.00158744 0.00190677 0.00298403 0.00268595 0.00196161 0.00130289 0.000783347 0.000520683 0.000565306 0.00053419 -0.00224696 -0.000920818 0.0132755 0.0322504 0.0442808 0.0638615 0.0701007 0.0539356 0.0247771 0.056244 0.294266 0.831368 1.45424 2.02898 2.54559 2.9937 3.35333 3.72609 4.06363 4.32789 4.52413 4.66504 4.7652 4.83637 4.88631 4.92109 4.94464 4.96046 4.97218 4.98079 4.98679 4.99076 4.99361 4.99555 4.99686 4.99783 4.99853 4.99902 4.99936 4.99959 4.99973 4.99983 4.9999 4.99993 4.99996 4.99998 5 5.00001 5 4.99999 4.99997 4.99994 4.99993 4.99994 4.99996 4.99999 5.00004 5.00006 5.00005 5.00003 5.00002 5.00001 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 } v27 set { 5 4.99984 4.99796 4.99478 4.9889 4.98738 4.98896 4.99087 4.99262 4.99419 4.99552 4.99659 4.99743 4.99807 4.99855 4.9989 4.99894 4.99908 4.99935 5.00001 5.0007 5.00132 5.00032 4.99976 5.00134 5.00339 5.00315 5.00157 5.00091 5.00058 5.00012 4.99944 4.99886 4.9994 4.99934 4.99899 4.99876 4.99868 4.99872 4.99883 4.99898 4.99914 4.9993 4.99944 4.99956 4.99967 4.99976 4.99982 4.99986 4.9999 4.99993 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00009 5.00028 5.00015 4.99983 5.00036 4.99996 4.99834 4.99783 5.00383 5.00734 5.00387 5.00058 4.99893 4.99836 4.99832 4.99854 4.99873 4.99905 4.99927 4.99952 4.99969 4.99834 4.99536 4.99163 4.99073 5.0053 5.03631 5.03103 4.9008 4.62503 4.21887 3.70902 3.09967 2.35791 1.41912 0.519675 0.210458 0.131362 0.0980819 0.0708209 0.0471701 0.0323272 0.0253535 0.0199144 0.0152615 0.0117228 0.00917696 0.00738117 0.00609292 0.00512664 0.00436184 0.0037961 0.00331639 0.00289006 0.0025477 0.00226529 0.00202925 0.00182793 0.00165474 0.00150531 0.00137529 0.00125983 0.00115603 0.00106455 0.000982977 0.000911255 0.000846819 0.000790092 0.000738698 0.000692816 0.00065107 0.000613595 0.000579642 0.000548935 0.00052106 0.000495598 0.000472174 0.000450849 0.000431118 0.000412667 0.000395868 0.000381319 0.000368487 0.000357327 0.000344212 0.000330334 0.00031622 0.000303298 0.000295809 0.00028832 0.000280831 0.000273342 0.000265853 0.000258364 0.000250875 0.000245118 0.000239488 0.000233857 0.000228227 0.000222596 0.000216966 0.000211336 0.000207047 0.000203455 0.000199863 0.00019627 0.000192678 0.000189085 0.000185493 0.0001819 0.000178308 0.000174716 0.000171123 0.000167531 0.000163938 0.000160346 0.000156835 0.000153973 0.00015111 0.000148248 0.000145385 0.000296579 -3.96718e-05 -0.000449085 0.000323433 0.000750086 0.000268264 0.000149028 -0.000100249 7.00956e-05 0.00012605 0.00022592 0.000193036 0.000120453 8.07865e-05 7.65771e-05 -3.27828e-05 0.000116759 0.000169498 0.000409804 0.000414965 0.00092323 -0.00590633 -0.0175477 -0.032433 -0.0559842 -0.0820373 0.0688484 0.626629 1.32929 2.01657 2.60925 3.12329 3.38952 3.14128 2.38463 1.23802 0.316019 0.107832 0.0694707 0.051837 0.035247 0.0209999 0.0116618 0.00967674 0.00789182 0.00574566 0.00386872 0.00258612 0.00167126 0.00104169 0.000641093 0.000401246 0.000277928 0.000171775 0.000102266 5.89376e-05 3.29258e-05 1.80463e-05 1.0057e-05 6.4571e-06 5.10093e-06 4.06791e-06 3.62716e-06 3.63321e-06 3.99625e-06 4.64368e-06 5.20886e-06 4.77728e-06 3.23919e-06 1.14113e-06 -1.29416e-06 -4.15607e-06 -1.88532e-06 5.24411e-06 1.38678e-05 1.28823e-05 3.6758e-06 -2.52285e-06 -3.97133e-06 -4.03071e-06 -3.37154e-06 -2.71238e-06 -2.05321e-06 -1.39404e-06 -7.34872e-07 -3.73325e-07 -1.05873e-07 1.61578e-07 4.2903e-07 6.96482e-07 8.18468e-07 7.60065e-07 7.01662e-07 6.43258e-07 5.84855e-07 5.26452e-07 4.68049e-07 4.09646e-07 3.51243e-07 2.9284e-07 2.34437e-07 1.71213e-07 1.06928e-07 4.2644e-08 -2.16403e-08 -8.59247e-08 -1.50209e-07 -2.14493e-07 -2.78778e-07 -3.43062e-07 -4.07346e-07 -4.55065e-07 -4.3348e-07 -4.11896e-07 -3.90311e-07 -3.68726e-07 -3.47141e-07 -3.25556e-07 -3.03971e-07 -2.82386e-07 } v28 set { 0.368163 0.361756 0.327463 0.269513 0.149476 0.0805716 0.0501146 0.03403 0.0230886 0.0160474 0.0116071 0.00870013 0.00679614 0.00542384 0.00432512 0.00340653 -0.00129719 -0.00399429 -0.00318719 0.00443085 0.0150156 0.0334147 0.0132288 -0.0189751 -0.0508377 -0.0252174 -0.0142489 -0.00675908 -0.0038653 -0.00243423 -0.00168891 -0.00120901 -0.000900426 -0.000685575 -0.000557595 -0.000457268 -0.000377427 -0.000315269 -0.000266613 -0.000228397 -0.000198283 -0.000174248 -0.000154886 -0.00013892 -0.000125864 -0.000115189 -0.000105841 -9.66611e-05 -8.84262e-05 -8.23872e-05 -7.74668e-05 -7.25463e-05 -6.79992e-05 -6.35276e-05 -5.92413e-05 -5.68994e-05 -5.45574e-05 -5.22154e-05 -4.98735e-05 -4.75315e-05 -4.54981e-05 -4.36726e-05 -4.18471e-05 -4.00216e-05 -3.81961e-05 -3.64559e-05 -3.54209e-05 -3.43858e-05 -3.33508e-05 -3.23157e-05 -3.12807e-05 -3.02456e-05 -2.92105e-05 -2.81755e-05 -2.71404e-05 -2.61054e-05 -2.51232e-05 -2.44984e-05 -2.38736e-05 -2.32487e-05 -2.26239e-05 -2.19991e-05 -2.13742e-05 -2.07494e-05 -2.01246e-05 -1.94998e-05 -1.88749e-05 -1.82865e-05 -1.79044e-05 -1.75224e-05 -1.71403e-05 -1.67582e-05 -1.63762e-05 -1.59941e-05 -1.56121e-05 -1.523e-05 -1.4848e-05 -1.44659e-05 -1.41138e-05 -1.39075e-05 -1.37011e-05 -1.34947e-05 -1.32883e-05 -1.30819e-05 -1.28755e-05 -1.26691e-05 -1.24627e-05 -1.22563e-05 -1.205e-05 -1.18436e-05 -1.16372e-05 -1.14308e-05 -1.12244e-05 -1.1018e-05 -1.08116e-05 -1.06052e-05 -1.03988e-05 -1.01924e-05 -9.98605e-06 -9.77966e-06 -2.85319e-05 0.00281092 0.00180106 -0.000981083 0.00551926 -0.00119763 -0.0295069 -0.0367677 0.064749 0.119022 0.0882007 0.0552062 0.03418 0.0223243 0.015545 0.011949 0.00757134 0.00667655 0.00583243 0.00644443 0.00650959 -0.0302575 -0.0437806 -0.0355466 0.0381776 0.282109 0.674178 1.07582 1.45189 1.789 2.08649 2.34663 2.57245 2.81211 3.04778 3.2523 3.45877 3.65593 3.83396 3.9923 4.13368 4.25864 4.36719 4.46064 4.54086 4.60962 4.66835 4.71838 4.76094 4.79716 4.82796 4.85413 4.87634 4.89518 4.91116 4.92476 4.93631 4.94608 4.95434 4.9613 4.96715 4.97211 4.97638 4.98001 4.98312 4.98571 4.98795 4.98979 4.99138 4.99269 4.99381 4.99474 4.99551 4.99615 4.99668 4.99713 4.99752 4.99783 4.99811 4.99836 4.99858 4.99873 4.99884 4.99892 4.999 4.99907 4.99912 4.99916 4.99921 4.99926 4.99932 4.99937 4.99942 4.99948 4.99953 4.99956 4.99958 4.99961 4.99963 4.99966 4.99968 4.99971 4.99972 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 4.99979 4.9998 4.9998 4.99981 4.99982 4.99983 4.99984 4.99985 4.99986 4.99986 4.99987 4.99987 5.00498 5.00354 4.99359 4.98981 5.00498 5.00099 5.00041 5.00022 5.00015 5.00012 5.0001 5.00008 5.00005 5.00003 5 4.99431 4.99459 4.99591 5.00087 5.01029 5.03935 4.92784 4.51643 3.78356 2.68745 1.43417 0.583128 0.205094 0.0777337 0.0391566 0.02723 0.023883 0.018808 0.010165 0.00254623 -0.00377463 -0.0038097 0.00144145 0.00267231 0.00193045 0.00144538 0.00121758 0.00112893 0.00109424 0.0010226 0.000948072 0.000882573 0.000826996 0.000776391 0.000729719 0.000686499 0.000647333 0.000610108 0.000575631 0.000545069 0.000515485 0.000488514 0.000465316 0.000443215 0.000422454 0.00040292 0.00038488 0.000368472 0.000353628 0.000339643 0.000326197 0.000313483 0.000302884 0.000294038 0.000284003 0.000270941 0.000254925 0.000246511 0.000244089 0.000245538 0.000242099 0.000235728 0.000227482 0.000218001 0.000207257 0.000202127 0.000196997 0.000191868 0.000186738 0.000181608 0.00017758 0.000173899 0.000170219 0.000166538 0.000162857 0.000159576 0.00015679 0.000154005 0.000151219 0.000148433 0.000145647 0.000142861 0.000140076 0.00013729 0.000134504 0.000131718 0.000129603 0.000127635 0.000125668 0.0001237 0.000121732 0.000119765 0.000117797 0.000115829 0.000113862 0.000111894 0.000109993 0.000108372 0.000106751 0.00010513 0.000103509 0.000101887 0.000100266 9.86449e-05 9.70237e-05 } v29 set { 5 4.99899 4.99654 4.99327 4.9863 4.98954 4.99212 4.99378 4.9951 4.99624 4.99715 4.99786 4.99839 4.99879 4.99909 4.99931 4.99922 4.99933 4.99971 5.00064 5.00084 5.00123 4.99865 4.99853 4.99983 5.00457 5.00242 5.00105 5.00062 5.00042 4.99971 4.9994 4.9992 4.9996 4.99955 4.99932 4.99918 4.99915 4.99919 4.99927 4.99937 4.99948 4.99957 4.99966 4.99974 4.9998 4.99985 4.99989 4.99992 4.99993 4.99994 4.99994 4.99996 4.99998 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.9997 4.99998 4.99954 4.99963 5.00059 4.99945 4.99732 4.99957 5.00919 5.00558 5.00033 4.99851 4.9983 4.99854 4.99871 4.99928 4.99914 4.99939 4.99952 4.9998 4.99976 4.99744 4.99598 4.99478 4.99806 5.01911 5.04602 5.05469 5.01317 4.89484 4.69655 4.42036 4.06069 3.60793 3.12531 2.72975 2.45187 2.25081 2.09841 1.98509 1.90211 1.84084 1.79411 1.7574 1.72763 1.70283 1.68188 1.66389 1.64823 1.63438 1.62201 1.61088 1.60081 1.59163 1.58323 1.57549 1.56835 1.56173 1.55558 1.54985 1.54451 1.53951 1.53479 1.53035 1.52615 1.5222 1.51845 1.5149 1.51153 1.50834 1.50529 1.5024 1.49964 1.497 1.49449 1.49208 1.48977 1.48755 1.48542 1.48336 1.48138 1.47948 1.47765 1.4759 1.47419 1.47255 1.47096 1.46949 1.46823 1.46696 1.4657 1.46444 1.46317 1.46191 1.46065 1.45956 1.4585 1.45743 1.45636 1.45529 1.45422 1.45315 1.45226 1.45145 1.45064 1.44983 1.44902 1.44821 1.4474 1.44659 1.44579 1.44498 1.44417 1.44336 1.44255 1.44174 1.44094 1.44019 1.43944 1.43868 1.43793 1.43765 1.43679 1.43515 1.43405 1.43478 1.43387 1.43345 1.43184 1.43086 1.43021 1.43003 1.42988 1.42944 1.42883 1.42818 1.42702 1.42642 1.42595 1.42586 1.42616 1.42783 1.41733 1.38106 1.30738 1.3877 2.09819 3.05285 3.58059 3.77601 3.87609 4.02557 4.24887 4.4608 4.60411 4.72109 4.8255 4.90465 4.97379 5.01253 5.01532 5.01239 5.0092 5.00665 5.00474 5.00333 5.00232 5.00163 5.00117 5.00082 5.00057 5.00039 5.00027 5.00019 5.00013 5.00009 5.00006 5.00004 5.00003 5.00002 5.00001 5.00001 5 5 5 4.99998 4.99995 4.99992 4.99996 5.00005 5.00012 5.00008 4.99996 4.9999 4.99985 4.99986 4.99997 5.00021 5.0003 5.00024 5.00009 5.00007 5.00005 5.00003 5.00001 4.99998 4.99998 4.99998 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } v30 set { 7.10441e-10 5.70385e-05 0.000226143 0.000131916 -0.000887764 -8.01837e-05 -3.49653e-05 9.40039e-05 0.000118663 0.000108025 8.6059e-05 6.33268e-05 4.99295e-05 3.16843e-05 3.60692e-05 2.07572e-05 -8.6375e-05 3.44583e-05 8.07397e-05 0.000196296 0.000115615 -7.12768e-05 -0.000129812 -4.18679e-05 7.94364e-05 0.000182034 -5.41226e-05 -0.000451819 -0.000713937 -0.00129863 -0.00262186 -0.00213417 -0.00133767 0.000775698 0.000969902 0.000549281 0.000280946 0.000140321 8.6919e-05 7.22446e-05 6.5631e-05 6.45263e-05 6.63087e-05 7.17391e-05 7.59042e-05 7.59172e-05 7.03353e-05 6.33558e-05 5.31136e-05 4.64278e-05 4.40594e-05 4.16909e-05 4.05674e-05 3.96957e-05 3.87875e-05 3.74977e-05 3.62079e-05 3.49181e-05 3.36283e-05 3.23385e-05 3.12427e-05 3.02775e-05 2.93124e-05 2.83472e-05 2.7382e-05 2.64613e-05 2.59077e-05 2.5354e-05 2.48004e-05 2.42468e-05 2.36931e-05 2.31395e-05 2.25859e-05 2.20322e-05 2.14786e-05 2.0925e-05 2.03916e-05 1.9995e-05 1.95984e-05 1.92019e-05 1.88053e-05 1.84087e-05 1.80122e-05 1.76156e-05 1.7219e-05 1.68225e-05 1.64259e-05 1.6051e-05 1.57991e-05 1.55471e-05 1.52952e-05 1.50433e-05 1.47913e-05 1.45394e-05 1.42875e-05 1.40356e-05 1.37836e-05 1.35317e-05 1.32978e-05 1.31513e-05 1.30048e-05 1.28583e-05 1.27118e-05 1.25653e-05 1.24188e-05 1.22724e-05 1.21259e-05 1.19794e-05 1.18329e-05 1.16864e-05 1.15399e-05 1.13934e-05 1.12469e-05 1.11005e-05 1.0954e-05 1.08075e-05 1.0661e-05 1.05145e-05 1.0368e-05 1.02215e-05 1.76447e-05 7.21516e-05 -3.59786e-05 -0.000159618 0.000156236 0.000135106 -0.000336402 -0.000302283 0.000699323 0.000473866 -0.000156146 -0.000225625 -0.000123592 -3.78116e-05 8.47472e-06 2.43387e-06 -7.44762e-05 7.80111e-05 9.43608e-05 0.000170159 8.83919e-05 -0.00018802 -0.000373512 -0.000390597 0.000156875 0.0032343 0.00776304 -0.000566905 -0.00760695 -0.0159226 -0.0245989 -0.0331402 -0.0100902 0.067837 0.266702 0.910818 1.82282 2.69714 3.43247 3.98325 4.32893 4.51529 4.67087 4.79288 4.87574 4.92797 4.95902 4.97655 4.98622 4.99195 4.99526 4.99735 4.9991 4.99974 4.99982 4.99974 4.99961 4.9995 4.99943 4.9994 4.9994 4.99942 4.99944 4.99948 4.99952 4.99956 4.99961 4.99965 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 4.99988 4.9999 4.99991 4.99992 4.99993 4.99994 4.99995 4.99995 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00019 4.99888 4.99663 4.99457 4.99902 5.00229 5.00323 5.00302 5.0023 5.0015 5.00085 5.00041 5.00013 4.99993 4.99979 4.99948 4.99954 4.99983 5.00055 5.00109 5.00009 4.9987 4.998 4.99755 4.99676 4.99618 5.01091 5.05272 5.04156 4.80112 4.27692 3.42343 2.23953 0.967179 0.429813 0.540757 1.32991 2.32147 3.14903 3.78143 4.22325 4.47978 4.59448 4.69875 4.79798 4.87419 4.92339 4.95249 4.97174 4.98408 4.99124 4.99478 4.99729 4.99868 4.9992 4.99941 4.99947 4.99946 4.99943 4.9994 4.99939 4.9994 4.99942 4.99946 4.99951 4.99956 4.99961 4.99967 4.99973 4.99977 4.9998 4.99981 4.99983 4.99984 4.99987 4.99992 5.00001 5.00005 5.00001 4.99994 4.99995 4.99995 4.99996 4.99996 4.99996 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } v31 set { 1.8179e-09 -5.28841e-06 -1.44913e-05 -3.62932e-05 -9.75719e-05 0.000141781 3.73396e-05 -1.65603e-05 -1.5271e-05 -6.73884e-06 4.40157e-06 -4.85345e-06 -1.02964e-05 2.03126e-05 -1.89457e-05 -8.75564e-06 7.67422e-06 4.71103e-06 1.29798e-05 6.13469e-06 -1.14363e-05 -0.0394563 -0.0477298 -0.0622012 -0.0519225 0.262499 0.943611 1.67052 2.31017 2.84028 3.28467 3.61582 3.85887 4.13011 4.36511 4.54063 4.67013 4.76408 4.83263 4.8825 4.91837 4.94373 4.96117 4.97318 4.98093 4.98562 4.98906 4.99267 4.99539 4.99666 4.99731 4.99797 4.99844 4.99887 4.99927 4.99933 4.99938 4.99944 4.99949 4.99955 4.9996 4.99965 4.9997 4.99975 4.9998 4.99985 4.99986 4.99987 4.99989 4.9999 4.99991 4.99992 4.99993 4.99995 4.99996 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99997 5.00002 5.00004 5.0001 5.0001 4.99987 5.00009 5.00021 5.00002 5.00004 4.99988 5.00013 4.99993 5.00026 4.99973 5 5.00006 5.00009 5.00004 5.00004 5.04854 4.82711 4.04208 2.64155 0.838902 0.19014 0.0982549 0.0723197 0.0576863 0.0427644 0.0301979 0.020146 0.0135728 0.00980358 0.00774482 0.00586604 0.0036687 0.00211511 0.00121906 0.000647581 0.000828436 0.00190938 0.00224254 0.00199956 0.00165488 0.00135612 0.00113715 0.000984181 0.000877175 0.000789973 0.000741139 0.000689338 0.000625676 0.000586082 0.000550152 0.000529573 0.000505606 0.000482117 0.000460574 0.000441649 0.000424674 0.000408398 0.000391914 0.000376272 0.000361487 0.000348181 0.000336045 0.000324466 0.000313545 0.000303046 0.000293056 0.00028356 0.000274586 0.000266155 0.000258279 0.000250938 0.000243789 0.000236912 0.000230244 0.000224186 0.000219291 0.000215346 0.000212468 0.000207291 0.000200862 0.00019368 0.000186767 0.000183515 0.000180263 0.00017701 0.000173758 0.000170506 0.000167253 0.000164001 0.000161164 0.000158357 0.00015555 0.000152743 0.000149936 0.000147129 0.000144322 0.000142066 0.000140096 0.000138127 0.000136157 0.000134187 0.000132218 0.000130248 0.000128278 0.000126308 0.000124339 0.000122369 0.000120399 0.000118429 0.00011646 0.000114527 0.000112892 0.000111258 0.000109623 0.000107988 0.000103598 6.86052e-05 3.337e-05 7.00783e-05 0.000218764 0.000221318 0.000118593 -0.000113962 5.78552e-05 9.42068e-05 0.000237037 0.000171302 0.0001033 6.16066e-05 5.52908e-05 6.30233e-05 7.01897e-05 8.48573e-05 0.000106859 8.37213e-05 -0.0391541 -0.047722 -0.0618454 -0.0169804 0.345725 1.03426 1.74825 2.37152 2.88737 3.32173 3.66761 3.9707 4.17762 3.98832 3.30483 2.09737 0.710892 0.148159 0.0707463 0.0555808 0.045618 0.0319116 0.0199589 0.0133357 0.00898528 0.00586075 0.00375478 0.00245443 0.00156038 0.000962344 0.000590953 0.000375107 0.000250243 0.00015882 0.000100203 6.18122e-05 3.7372e-05 2.23009e-05 1.32569e-05 8.29437e-06 5.72457e-06 3.96832e-06 2.98935e-06 2.59699e-06 2.75024e-06 3.38689e-06 4.0453e-06 3.50095e-06 1.64988e-06 -3.84371e-07 -2.03828e-06 -3.46401e-06 -1.24301e-06 4.63458e-06 1.14104e-05 1.02619e-05 2.15487e-06 -2.98487e-06 -3.67221e-06 -2.94279e-06 -2.58649e-06 -2.23019e-06 -1.87389e-06 -1.5176e-06 -1.1613e-06 -7.92127e-07 -4.18889e-07 -4.56502e-08 3.27588e-07 7.00827e-07 8.79539e-07 8.17025e-07 7.5451e-07 6.91996e-07 6.29481e-07 5.66966e-07 5.04452e-07 4.41937e-07 3.79422e-07 3.16908e-07 2.54393e-07 1.90078e-07 1.25366e-07 6.0654e-08 -4.05776e-09 -6.87696e-08 -1.33481e-07 -1.98193e-07 -2.62905e-07 -3.27617e-07 -3.92329e-07 -4.40392e-07 -4.18802e-07 -3.97213e-07 -3.75624e-07 -3.54035e-07 -3.32446e-07 -3.10856e-07 -2.89267e-07 -2.67678e-07 } v32 set { 1.10294 1.10297 1.10291 1.10277 1.10259 1.10294 1.10313 1.10306 1.10299 1.10296 1.10295 1.10295 1.10294 1.10294 1.10294 1.10294 1.10294 1.10294 1.10294 1.10296 1.10296 1.00547 0.998599 1.5201 2.49297 3.31258 3.73162 3.84757 3.92505 4.02965 4.16599 4.30294 4.41541 4.52886 4.64414 4.73865 4.81065 4.86391 4.90315 4.93188 4.95258 4.96726 4.97738 4.98436 4.98888 4.99162 4.99363 4.99573 4.99731 4.99804 4.99843 4.99881 4.99909 4.99934 4.99957 4.9996 4.99964 4.99967 4.9997 4.99973 4.99977 4.9998 4.99983 4.99986 4.99988 4.99991 4.99992 4.99992 4.99993 4.99994 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5.00028 4.99988 4.99968 5.00019 4.99987 5.00021 4.99973 4.99977 4.99996 4.99997 5.0002 4.99957 5.00026 4.99947 5.00074 5.00003 4.99987 4.99979 5.00008 4.99997 5.08794 5.05993 4.76875 3.99197 3.10174 2.5197 2.21771 2.04 1.92235 1.83874 1.77592 1.72665 1.686 1.65276 1.6286 1.61299 1.60039 1.58934 1.57954 1.57083 1.56306 1.55604 1.54963 1.54375 1.53832 1.53331 1.52865 1.52432 1.52026 1.51645 1.51287 1.50949 1.50629 1.50327 1.50039 1.49766 1.49505 1.49257 1.49019 1.48792 1.48574 1.48365 1.48164 1.47971 1.47784 1.47604 1.47431 1.47264 1.47102 1.46945 1.46794 1.46647 1.46505 1.46367 1.46233 1.46103 1.45976 1.45853 1.45733 1.45616 1.45502 1.45392 1.45284 1.45179 1.45076 1.44975 1.4488 1.44795 1.44711 1.44626 1.44541 1.44457 1.44372 1.44287 1.44212 1.44138 1.44063 1.43989 1.43914 1.4384 1.43766 1.43701 1.43641 1.43581 1.43522 1.43462 1.43402 1.43342 1.43282 1.43223 1.43163 1.43103 1.43043 1.42984 1.42924 1.42865 1.42808 1.42752 1.42695 1.42639 1.42584 1.42529 1.42472 1.42412 1.42365 1.42326 1.42304 1.42162 1.42082 1.42032 1.42029 1.42026 1.41995 1.41947 1.41894 1.41841 1.4179 1.41742 1.41699 1.41656 1.32097 1.30963 1.78765 2.64656 3.35764 3.747 3.86589 3.94217 4.04185 4.18453 4.3561 4.53439 4.68621 4.74905 4.77848 4.84629 4.91261 4.97541 5.01284 5.01548 5.01248 5.00924 5.00666 5.00475 5.00334 5.00234 5.00164 5.00118 5.00083 5.00058 5.0004 5.00028 5.00019 5.00013 5.00009 5.00007 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5 5 4.99999 4.99995 4.99992 4.99996 5.00006 5.00012 5.00009 4.99997 4.9999 4.99985 4.99986 4.99997 5.00021 5.00031 5.00024 5.0001 5.00007 5.00005 5.00003 5.00001 4.99998 4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 } v33 set { 5 5.00012 5.00023 5.0003 4.99972 4.99988 4.99984 4.99991 4.99996 4.99999 5.00008 5.00009 4.99986 5.00003 5.00007 4.99995 4.9999 4.99997 5.00013 5.00014 5.00013 4.99701 4.99763 4.99742 4.99998 5.02836 5.07262 4.96856 4.57267 3.85637 2.79544 1.45942 0.408016 0.084885 0.0271375 0.0119294 0.00707546 0.0051087 0.00373035 0.00264737 0.00186477 0.00130379 0.000915857 0.000653121 0.000483893 0.000380852 0.000302362 0.000219498 0.000154435 0.000121928 0.000104026 8.61242e-05 7.48526e-05 6.49216e-05 5.56238e-05 5.29689e-05 5.03139e-05 4.7659e-05 4.5004e-05 4.23491e-05 4.00356e-05 3.79522e-05 3.58687e-05 3.37852e-05 3.17018e-05 2.97592e-05 2.89804e-05 2.82016e-05 2.74228e-05 2.66441e-05 2.58653e-05 2.50865e-05 2.43077e-05 2.35289e-05 2.27501e-05 2.19714e-05 2.12346e-05 2.07821e-05 2.03295e-05 1.98769e-05 1.94244e-05 1.89718e-05 1.85192e-05 1.80667e-05 1.76141e-05 1.71615e-05 1.6709e-05 1.62828e-05 1.60061e-05 1.57294e-05 1.54527e-05 1.5176e-05 1.48993e-05 1.46226e-05 1.43459e-05 1.40692e-05 1.37925e-05 1.35158e-05 1.3262e-05 1.31191e-05 1.29761e-05 1.28332e-05 1.26903e-05 1.25474e-05 1.24045e-05 1.22615e-05 1.21186e-05 1.19757e-05 1.18328e-05 1.16898e-05 1.15469e-05 1.1404e-05 1.12611e-05 1.11182e-05 1.09752e-05 1.08323e-05 1.06894e-05 1.05465e-05 1.04036e-05 1.02606e-05 1.00185e-05 3.8343e-05 -3.06781e-05 -0.000111758 0.000111673 0.000130815 -0.000210491 -0.000231304 0.000310226 0.000265303 3.0878e-05 -4.48405e-05 -1.2852e-05 -7.84469e-06 3.29986e-05 -1.23286e-05 -6.07871e-05 5.35082e-05 7.69194e-05 0.000126221 6.57178e-05 0.00223349 -0.0148854 -0.0476636 -0.0491447 0.220125 1.11174 2.03988 2.90209 3.61069 4.13554 4.50679 4.71501 4.83916 4.91027 4.95284 4.98086 4.99151 4.98651 4.97113 4.95075 4.93102 4.93683 4.95457 4.97071 4.98212 4.98948 4.99386 4.99636 4.99785 4.9987 4.99927 4.99989 5.00014 5.00007 4.99988 4.99982 4.99976 4.99973 4.99972 4.99972 4.99973 4.99974 4.99975 4.99977 4.99979 4.99981 4.99984 4.99986 4.99988 4.99989 4.99991 4.99992 4.99993 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5.00012 4.99946 4.99839 4.99733 4.99948 5.00114 5.00158 5.00147 5.00113 5.00073 5.00043 5.0002 5.00006 4.99995 4.99986 4.99973 4.99976 4.9999 5.00029 5.00055 4.99704 4.99734 4.9972 5.00278 5.03354 5.07184 4.94057 4.51936 3.75638 2.60982 1.23803 0.315016 0.0796102 0.0252894 0.0165723 0.0827785 0.491298 1.40686 2.33436 3.1251 3.7691 4.22201 4.49976 4.68115 4.80513 4.88509 4.93208 4.95861 4.97579 4.98655 4.99268 4.99571 4.99771 4.99881 4.99929 4.99954 4.99965 4.9997 4.99971 4.99971 4.99971 4.99971 4.99972 4.99974 4.99976 4.99978 4.99981 4.99984 4.99987 4.99989 4.99991 4.99991 4.99992 4.99992 4.99993 4.99997 5.00003 5.00006 5.00004 5.00001 5 4.99999 4.99998 4.99998 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 } v34 set { 5 5.00207 5.00813 5.01486 5.00156 5.0018 4.99861 4.99844 4.99888 4.9993 4.99956 4.99971 4.99979 4.99983 4.99987 4.99989 4.99671 4.9974 4.99864 5.00131 5.00377 5.0021 5.00039 4.99993 5.00004 5.0009 5.00109 4.99636 4.98617 4.96778 4.92047 4.89528 4.91112 4.9559 4.98286 4.99369 4.99812 4.99951 4.99994 5.00014 5.00008 4.99994 4.99984 4.99989 4.99998 5.00004 5.00004 5.00006 5.00005 5.00001 4.99997 4.99992 4.99993 4.99994 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 5.00131 5.00072 4.9977 4.99811 5.00325 4.99647 4.98948 4.99459 5.00262 5.00276 5.00156 5.00072 5.0003 5.00013 4.99995 4.99668 4.99775 4.99917 5.00173 5.00386 5.00188 4.99888 4.99757 4.99951 5.01712 5.0557 5.07088 5.07704 5.07758 5.06958 5.04223 5.03331 5.0279 5.03408 5.07611 5.01911 4.68594 3.99152 2.92195 1.69878 0.809 0.344091 0.154663 0.0788717 0.0467212 0.0336168 0.0280514 0.0254947 0.024173 0.0223567 0.0220555 0.0271514 0.0295872 0.0296052 0.0283971 0.0264726 0.0241813 0.0218244 0.0195349 0.017368 0.0152495 0.013295 0.0115444 0.00996982 0.00857091 0.00733891 0.00627261 0.0053494 0.00456316 0.00388373 0.00331073 0.00282181 0.00240991 0.00206389 0.00177187 0.00152283 0.00131167 0.00112558 0.000954373 0.000805726 0.00069326 0.000600991 0.000525743 0.00047355 0.00044359 0.000434815 0.000436053 0.000402511 0.000368969 0.000335427 0.000301886 0.000268344 0.000234802 0.00020126 0.000184967 0.000169932 0.000154896 0.000139861 0.000124825 0.00010979 9.47546e-05 8.67896e-05 8.24901e-05 7.81906e-05 7.38911e-05 6.95915e-05 6.5292e-05 6.09925e-05 5.66929e-05 5.23934e-05 4.80939e-05 4.37943e-05 3.94948e-05 3.51953e-05 3.08957e-05 2.67968e-05 2.42936e-05 2.17904e-05 1.92872e-05 1.6784e-05 0.00125927 -0.00794344 -0.0305499 -0.0621697 -0.0463796 -0.0224608 -0.00538381 0.00546086 0.0108675 0.012883 0.0131787 0.0127271 0.0119702 0.0110398 0.0100635 0.00649617 0.00489388 0.00545863 0.0098351 0.0167428 0.0126563 0.00697542 0.00427027 0.00330002 0.00390774 0.00408999 -0.00259143 -0.0160578 -0.0451849 -0.0409651 0.1301 0.597429 1.3848 2.63426 3.81272 4.51373 4.8412 4.98731 4.88165 4.37165 3.40034 2.17681 1.12217 0.505129 0.219703 0.104992 0.0622333 0.0448317 0.0355782 0.0311867 0.0293529 0.0274615 0.0288739 0.0307845 0.0304909 0.029245 0.0273602 0.0251006 0.022697 0.0202765 0.0179357 0.0157106 0.0136562 0.0117951 0.0101273 0.00865784 0.00739394 0.00634364 0.00551356 0.00480538 0.00415747 0.00356084 0.00297585 0.00236711 0.00181853 0.00160713 0.00169822 0.00166542 0.00145504 0.00120252 0.00109259 0.000982658 0.00087273 0.000762802 0.000652874 0.000584068 0.000528263 0.000472458 0.000416653 0.000360848 0.000321155 0.000301442 0.000281729 0.000262016 0.000242303 0.00022259 0.000202877 0.000183164 0.000163451 0.000143738 0.000124025 0.000114582 0.000107399 0.000100216 9.30332e-05 8.58502e-05 7.86672e-05 7.14841e-05 6.43011e-05 5.7118e-05 4.9935e-05 4.35378e-05 4.04281e-05 3.73184e-05 3.42088e-05 3.10991e-05 2.79894e-05 2.48798e-05 2.17701e-05 1.86604e-05 } v35 set { 7.24585e-12 2.21843e-05 3.20014e-05 1.25076e-05 -2.44947e-05 1.8425e-05 5.50546e-06 3.53025e-05 -1.07551e-05 -3.94383e-06 -2.27848e-06 -9.04789e-05 7.44215e-05 -2.7662e-05 0.000200038 -2.11998e-05 -2.09011e-05 2.37098e-05 2.18751e-05 -2.28422e-05 -6.23659e-05 3.58241e-05 1.76386e-05 -4.28311e-05 0.000355626 0.00156903 0.00100999 -0.0085304 -0.02067 -0.0389485 -0.0651568 -0.128475 -0.314362 -0.406837 -0.421558 -0.421277 -0.418176 -0.414481 -0.410845 -0.407348 -0.403971 -0.400716 -0.397582 -0.394563 -0.391658 -0.388866 -0.386178 -0.383585 -0.381094 -0.378789 -0.376569 -0.37435 -0.372256 -0.370188 -0.36815 -0.366422 -0.364694 -0.362967 -0.361239 -0.359511 -0.357888 -0.356334 -0.354781 -0.353227 -0.351674 -0.350152 -0.348888 -0.347625 -0.346361 -0.345098 -0.343834 -0.342571 -0.341307 -0.340044 -0.33878 -0.337517 -0.336279 -0.335215 -0.334152 -0.333088 -0.332024 -0.330961 -0.329897 -0.328833 -0.32777 -0.326706 -0.325642 -0.324601 -0.323683 -0.322766 -0.321849 -0.320932 -0.320014 -0.319097 -0.31818 -0.317263 -0.316345 -0.315428 -0.314545 -0.313825 -0.313106 -0.312387 -0.311667 -0.310948 -0.310228 -0.309509 -0.308789 -0.30807 -0.307351 -0.306631 -0.305912 -0.305192 -0.304473 -0.303754 -0.303034 -0.302315 -0.301595 -0.300876 -0.300157 -0.299437 -0.298716 -0.29798 -0.297329 -0.296691 -0.295837 -0.29516 -0.294725 -0.294044 -0.292917 -0.292351 -0.291965 -0.291365 -0.290687 -0.290027 -0.289376 -0.288772 -0.288193 -0.287505 -0.286892 -0.28626 -0.285714 -0.284545 -0.289246 -0.298717 -0.298492 -0.214163 0.181451 0.0749974 0.0454707 0.0292987 0.0196837 0.0124119 0.00884715 0.00527181 0.00585821 0.0296361 0.169856 0.361207 0.538856 0.67469 0.685933 0.392802 0.17772 0.0813085 0.0424601 0.0246654 0.0175258 0.0144256 0.0129859 0.012205 0.0112846 0.010933 0.0134813 0.0147254 0.0147981 0.0142156 0.0132732 0.0121355 0.0109587 0.00981238 0.00872731 0.00767007 0.00669346 0.00581341 0.00502167 0.00431819 0.00369842 0.00316168 0.00269663 0.00230035 0.00195801 0.00166928 0.00142286 0.00121522 0.00104072 0.000893384 0.000767675 0.000661268 0.000567659 0.000481766 0.000407101 0.000350044 0.000302721 0.000263424 0.000236813 0.00022199 0.000218182 0.000219548 0.0002027 0.000185853 0.000169006 0.000152158 0.000135311 0.000118463 0.000101616 9.33782e-05 8.57685e-05 7.81588e-05 7.0549e-05 6.29393e-05 5.53296e-05 4.77199e-05 4.36954e-05 4.15296e-05 3.93637e-05 3.71978e-05 3.50319e-05 3.28661e-05 3.07002e-05 2.85343e-05 2.63685e-05 2.42026e-05 2.20367e-05 1.98709e-05 1.7705e-05 1.55391e-05 1.34772e-05 1.22416e-05 1.10061e-05 9.77055e-06 8.535e-06 0.000631271 -0.00362586 -0.0146235 -0.0308486 -0.0237466 -0.0117522 -0.00304171 0.00251033 0.00531986 0.0063897 0.00657351 0.00636494 0.00599705 0.00553442 0.00505994 0.00330925 0.00246671 0.0027006 0.00473161 0.00830333 0.00649147 0.00356815 0.00217448 0.00187579 0.00270447 0.00219543 -0.00546118 -0.0179576 -0.0445306 -0.0649309 0.0197935 0.473629 0.87268 0.269542 0.0086094 0.0844602 0.606456 1.04929 0.906014 0.916205 0.919425 0.872867 0.556244 0.262457 0.11838 0.0571226 0.0333451 0.0237133 0.0185096 0.0159617 0.0148663 0.0138683 0.0144081 0.0153797 0.0152551 0.0146487 0.0137192 0.0125973 0.0113996 0.0101903 0.00901851 0.00790495 0.00687502 0.00593994 0.00510092 0.00436111 0.00372439 0.0031945 0.00277537 0.00241888 0.002095 0.00179943 0.00150419 0.00119264 0.00090934 0.000802394 0.000852816 0.000838368 0.000730842 0.000601028 0.000546616 0.000492205 0.000437793 0.000383381 0.000328969 0.00029454 0.000266428 0.000238317 0.000210205 0.000182093 0.000162091 0.000152145 0.000142198 0.000132252 0.000122306 0.000112359 0.000102413 9.24665e-05 8.25201e-05 7.25738e-05 6.26274e-05 5.78553e-05 5.42216e-05 5.05878e-05 4.69541e-05 4.33204e-05 3.96867e-05 3.60529e-05 3.24192e-05 2.87855e-05 2.51518e-05 2.19153e-05 2.03406e-05 1.8766e-05 1.71913e-05 1.56167e-05 1.4042e-05 1.24674e-05 1.08927e-05 9.31806e-06 } v36 set { 5 5.01426 5.02852 5.01923 4.77685 4.56471 4.52338 4.56813 4.63122 4.693 4.74776 4.79385 4.83258 4.86358 4.88918 4.91021 4.90553 4.89733 4.89554 4.91953 5.00757 5.07101 5.06318 5.05241 5.05535 5.08042 5.07251 4.90973 4.56136 3.98637 3.237 2.67216 2.33678 2.13529 2.00544 1.91429 1.84638 1.79461 1.75338 1.71958 1.69175 1.6686 1.64918 1.63258 1.61836 1.60607 1.59506 1.58483 1.57575 1.56847 1.56193 1.55538 1.54968 1.54416 1.5388 1.53523 1.53165 1.52807 1.52449 1.52091 1.51771 1.51477 1.51182 1.50888 1.50593 1.50309 1.50113 1.49917 1.4972 1.49524 1.49328 1.49132 1.48935 1.48739 1.48543 1.48346 1.48157 1.48012 1.47868 1.47724 1.47579 1.47435 1.47291 1.47146 1.47002 1.46857 1.46713 1.46574 1.46462 1.4635 1.46238 1.46126 1.46014 1.45902 1.4579 1.45678 1.45567 1.45455 1.45349 1.45275 1.45201 1.45127 1.45053 1.44979 1.44905 1.44831 1.44757 1.44683 1.44609 1.44535 1.44461 1.44387 1.44313 1.44239 1.44165 1.44091 1.44017 1.43943 1.43869 1.43795 1.43721 1.43874 1.43976 1.43619 1.43182 1.43726 1.43084 1.42587 1.42383 1.42642 1.42728 1.42736 1.4271 1.42669 1.42621 1.42569 1.41703 1.41244 1.41019 1.41199 1.41833 1.42502 1.41504 1.37535 1.28381 1.44779 2.33713 3.25835 3.67554 3.84975 4.01125 4.2253 4.45433 4.62215 4.74478 4.82998 4.8868 4.92396 4.94768 4.96498 4.98537 5.0128 5.04467 5.06722 5.06535 5.01475 4.91956 4.80647 4.7242 4.7059 4.73552 4.76379 4.81684 4.87376 4.92276 4.96112 4.9884 5.0045 5.00999 5.00933 5.00619 5.00384 5.00342 5.00373 5.00362 5.00309 5.00272 5.00239 5.00204 5.00172 5.00146 5.00124 5.00105 5.00089 5.00076 5.00065 5.00057 5.00048 5.00041 5.00034 5.00028 5.00023 5.00019 5.00015 5.00015 5.00016 5.0002 5.00023 5.00021 5.00019 5.00017 5.00015 5.00012 5.0001 5.00008 5.00007 5.00006 5.00005 5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00062 4.99506 4.9835 4.96726 4.9728 4.97877 4.98675 4.9966 5.00406 5.00679 5.00629 5.00561 5.00487 5.00429 5.00384 5.002 5.00164 5.00229 5.00484 5.00769 5.00019 5.00242 5.01319 5.0335 5.07265 5.10129 5.11485 5.12551 5.13953 5.16048 5.18862 5.22811 5.25656 5.25627 5.19975 4.9139 4.24745 3.43732 2.8202 2.43224 2.17409 2.01333 1.93951 1.94622 1.98861 2.02217 2.05383 2.08376 2.11184 2.13793 2.16191 2.18267 2.20502 2.22837 2.24958 2.26901 2.28648 2.302 2.31582 2.32802 2.33869 2.34795 2.35596 2.36282 2.3687 2.37371 2.37797 2.38161 2.38476 2.38743 2.3897 2.39168 2.39329 2.39463 2.39575 2.39671 2.39756 2.39835 2.39907 2.39968 2.39999 2.4003 2.40061 2.40091 2.40122 2.40142 2.40159 2.40176 2.40193 2.4021 2.40222 2.40228 2.40234 2.4024 2.40247 2.40253 2.40259 2.40265 2.40271 2.40277 2.40284 2.40287 2.40289 2.40291 2.40294 2.40296 2.40298 2.40301 2.40303 2.40305 2.40308 2.4031 2.40311 2.40312 2.40313 2.40314 2.40315 2.40316 2.40317 2.40318 } v37 set { 5 5.01732 5.03181 5.05944 5.12686 5.20725 5.28103 5.31254 5.32901 5.33709 5.3408 5.34257 5.34311 5.34347 5.34386 5.34411 5.3406 5.33484 5.32942 5.32904 5.33644 5.34869 5.35001 5.34882 5.34758 5.34672 5.34599 5.34496 5.34364 5.34165 5.33712 5.33502 5.3366 5.34067 5.34306 5.34398 5.34434 5.34442 5.34443 5.34443 5.34441 5.34439 5.34437 5.34437 5.34438 5.34438 5.34438 5.34438 5.34438 5.34437 5.34437 5.34436 5.34436 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.35377 5.35451 5.34265 5.34488 5.35861 5.28622 4.90033 4.75027 4.89731 4.97098 4.99293 4.99832 4.99909 4.99956 4.99858 4.99829 4.9998 5.00035 5.0038 5.00989 5.00251 4.99438 4.9953 4.99761 4.99985 5.00152 5.0011 5.00046 4.99996 4.99925 4.99862 4.99919 4.99961 5.00048 5.00234 4.99654 4.98235 4.95936 4.83738 4.53021 4.21004 4.00593 3.91207 3.88059 3.87822 3.89117 3.91278 3.94044 3.97376 4.01152 4.05052 4.10679 4.17908 4.25673 4.33414 4.40875 4.47879 4.54342 4.60258 4.65595 4.70291 4.74414 4.78018 4.81185 4.83915 4.86291 4.88301 4.90048 4.91528 4.92802 4.9387 4.94777 4.95539 4.9618 4.96725 4.97195 4.97588 4.97932 4.98247 4.98512 4.98697 4.98831 4.98919 4.99015 4.99101 4.99169 4.99222 4.99282 4.99341 4.994 4.9946 4.99519 4.99578 4.99638 4.99667 4.99693 4.9972 4.99747 4.99773 4.998 4.99827 4.99841 4.99849 4.99856 4.99864 4.99872 4.9988 4.99888 4.99896 4.99904 4.99911 4.99919 4.99927 4.99935 4.99943 4.9995 4.99955 4.9996 4.99965 4.9997 5.00736 4.98252 4.87516 4.66727 4.49142 4.43103 4.4301 4.4571 4.49729 4.5407 4.5835 4.62363 4.66114 4.69577 4.72738 4.74632 4.75971 4.77576 4.80671 4.87073 4.91665 4.93252 4.94418 4.95331 4.96094 4.96727 4.97148 4.97471 4.97612 4.98276 5.00247 5.04086 5.08628 5.10673 5.08887 5.0564 5.02767 5.01336 4.99685 4.97422 4.90866 4.67035 4.33117 4.07888 3.94432 3.89105 3.88174 3.89292 3.91442 3.94564 3.98708 4.0355 4.09134 4.16315 4.24088 4.31918 4.39527 4.46693 4.53337 4.59405 4.6486 4.69693 4.73938 4.77617 4.80809 4.83551 4.85895 4.87894 4.89596 4.91081 4.92417 4.93651 4.94552 4.95198 4.9565 4.96096 4.96523 4.96972 4.97428 4.97868 4.98064 4.9826 4.98455 4.98651 4.98847 4.98967 4.99064 4.9916 4.99257 4.99353 4.99422 4.99457 4.99493 4.99528 4.99563 4.99598 4.99633 4.99668 4.99703 4.99738 4.99773 4.9979 4.99804 4.99817 4.9983 4.99843 4.99856 4.99869 4.99883 4.99896 4.99909 4.99921 4.99926 4.99931 4.99937 4.99942 4.99948 4.99953 4.99959 4.99964 } v38 set { 4.49849 4.53282 4.58329 4.66625 4.83345 4.97823 5.0207 5.01816 5.01116 5.00595 5.00296 5.00148 5.00073 5.00062 5.00033 5.0003 4.99864 4.99661 4.99652 4.99928 5.00361 5.12573 5.17251 5.22612 5.33479 5.44503 5.44432 5.44379 5.44334 5.443 5.44276 5.44258 5.44246 5.44238 5.44232 5.44228 5.44225 5.44223 5.44221 5.4422 5.44219 5.44219 5.44218 5.44218 5.44218 5.44218 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44212 5.45159 5.45236 5.44064 5.44307 5.45616 5.38122 4.77163 3.53297 2.74466 2.34448 2.11802 1.9783 1.88656 1.82001 1.77389 1.72955 1.69632 1.66971 1.6526 1.65236 1.56034 1.53764 1.97139 2.75096 3.39212 3.74042 3.82345 3.85696 3.88547 3.91862 3.9585 4.00467 4.05903 4.1254 4.19533 4.26791 4.34517 4.42112 4.49238 4.55807 4.6179 4.6713 4.71815 4.75889 4.79418 4.82456 4.85062 4.87291 4.89196 4.90823 4.92209 4.93388 4.9439 4.95242 4.95968 4.96585 4.97108 4.9755 4.97923 4.98237 4.98503 4.98732 4.98927 4.99094 4.99233 4.99353 4.99452 4.99538 4.99608 4.99668 4.99718 4.9976 4.99794 4.99822 4.99847 4.99867 4.99884 4.99899 4.99913 4.99924 4.99932 4.99938 4.99943 4.99947 4.99951 4.99953 4.99955 4.99958 4.99961 4.99964 4.99967 4.99969 4.99972 4.99975 4.99977 4.99978 4.99979 4.99981 4.99982 4.99983 4.99985 4.99986 4.99986 4.99987 4.99987 4.99988 4.99988 4.99988 4.99989 4.99989 4.9999 4.9999 4.99991 4.99991 4.99992 4.99992 4.99993 4.99993 4.99993 4.99994 5.00381 5.00064 4.99246 4.99823 5.00349 5.00076 5.00033 5.00015 5.00009 5.00007 5.00005 5.00004 5.00003 5.00002 4.99988 4.99732 4.99728 4.9978 5.00187 5.00927 5.08712 5.07654 4.92855 4.4863 3.76162 3.00049 2.49834 2.20883 2.03492 1.92384 1.84676 1.79021 1.74716 1.7132 1.68576 1.66309 1.64406 1.62785 1.61383 1.60162 1.59081 1.58117 1.57253 1.56473 1.55765 1.55117 1.54527 1.53988 1.53485 1.53012 1.5257 1.5216 1.51773 1.51411 1.51071 1.50746 1.50438 1.50146 1.49868 1.49603 1.4935 1.49109 1.48878 1.48657 1.48445 1.48242 1.48046 1.47858 1.47677 1.47502 1.47333 1.4717 1.47012 1.46859 1.46711 1.46568 1.46428 1.46292 1.4616 1.46034 1.45923 1.45812 1.45701 1.4559 1.45479 1.45378 1.45279 1.45181 1.45082 1.44983 1.44893 1.44813 1.44732 1.44652 1.44571 1.44491 1.4441 1.4433 1.44249 1.44169 1.44089 1.44019 1.43951 1.43883 1.43815 1.43747 1.4368 1.43612 1.43544 1.43476 1.43408 1.43342 1.43283 1.43223 1.43163 1.43104 1.43044 1.42984 1.42924 1.42865 } v39 set { 5 5.01048 5.01221 4.98887 4.76261 4.54943 4.51564 4.56249 4.62621 4.68843 4.74374 4.79044 4.82972 4.86127 4.88724 4.90862 4.90791 4.89858 4.89589 4.91767 5.00405 5.16956 5.12391 4.7557 3.87953 3.01124 2.48482 2.20424 2.03812 1.92679 1.84956 1.79256 1.74907 1.71487 1.68724 1.6644 1.64513 1.6287 1.61446 1.60197 1.59095 1.58117 1.57245 1.5646 1.55752 1.55109 1.54516 1.53958 1.53444 1.53008 1.52606 1.52205 1.51843 1.5149 1.51146 1.50893 1.50639 1.50387 1.50133 1.4988 1.49651 1.49436 1.49222 1.49007 1.48793 1.48585 1.48433 1.4828 1.48128 1.47975 1.47823 1.4767 1.47518 1.47365 1.47213 1.4706 1.46912 1.46795 1.46678 1.46561 1.46444 1.46327 1.4621 1.46093 1.45976 1.45859 1.45741 1.45628 1.45534 1.45441 1.45347 1.45254 1.4516 1.45067 1.44973 1.4488 1.44786 1.44693 1.44604 1.44539 1.44475 1.4441 1.44345 1.44281 1.44216 1.44151 1.44086 1.44022 1.43957 1.43892 1.43828 1.43763 1.43698 1.43633 1.43569 1.43504 1.43439 1.43375 1.4331 1.43245 1.4318 1.43157 1.43089 1.43001 1.43042 1.42899 1.42439 1.42216 1.43447 1.44048 1.43705 1.43314 1.43039 1.42861 1.42739 1.42651 1.42548 1.42488 1.4243 1.42392 1.4235 1.32443 1.31149 1.78169 2.64844 3.43211 3.95252 4.20231 4.3746 4.49948 4.58929 4.65742 4.71183 4.77057 4.83196 4.88354 4.92894 4.96625 4.99235 5.00651 5.00941 5.00813 5.00689 5.00588 5.00504 5.00431 5.00368 5.00314 5.00268 5.00228 5.00194 5.00165 5.0014 5.00118 5.001 5.00085 5.00072 5.00061 5.00052 5.00044 5.00037 5.00031 5.00027 5.00022 5.00019 5.00016 5.00013 5.00011 5.00009 5.00008 5.00007 5.00006 5.00005 5.00004 5.00003 5.00003 5.00003 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 5.00002 5.00003 5.00004 5.00022 4.99974 4.99942 4.99997 5.00063 5.00002 5.00003 4.99994 4.99998 4.99999 5 5 5 5 5 4.99981 4.99998 5.00004 5.00036 5.00049 5.12012 5.16315 5.19712 5.21835 4.87874 4.10151 3.31555 2.74207 2.38075 2.15872 2.01614 1.91886 1.84852 1.79401 1.75052 1.71508 1.68672 1.66467 1.64602 1.62985 1.61576 1.60343 1.59256 1.58287 1.57418 1.56632 1.55922 1.55282 1.54687 1.54132 1.53618 1.53143 1.52698 1.52282 1.51895 1.51527 1.5118 1.50851 1.5054 1.50244 1.49963 1.49695 1.4944 1.49196 1.48963 1.4874 1.48527 1.48322 1.48124 1.47934 1.47751 1.47574 1.47403 1.47239 1.4708 1.46926 1.46777 1.46632 1.46491 1.46355 1.46237 1.4612 1.46002 1.45884 1.45766 1.45659 1.45555 1.45451 1.45346 1.45242 1.45147 1.45062 1.44978 1.44894 1.44809 1.44725 1.4464 1.44556 1.44472 1.44387 1.44303 1.4423 1.44159 1.44088 1.44017 1.43947 1.43876 1.43805 1.43734 1.43664 1.43593 1.43524 1.43462 1.434 1.43338 1.43276 1.43213 1.43151 1.43089 1.43027 } set attributes { V1 v1 red red V2 v2 green red V3 v3 blue red V4 v4 yellow red V5 v5 magenta red V6 v6 cyan red V7 v7 white red V8 v8 red green V9 v9 green green V10 v10 blue green V11 v11 yellow green V12 v12 magenta green V13 v13 cyan green V14 v14 red red V15 v15 green red V16 v16 blue red V17 v17 yellow red V18 v18 magenta red V19 v19 cyan red V20 v20 white red V21 v21 red green V22 v22 green green V23 v23 blue green V24 v24 yellow green V25 v25 magenta green V26 v26 cyan green V27 v27 red red V28 v28 green red V29 v29 blue red V30 v30 yellow red V31 v31 magenta red V32 v32 cyan red V33 v33 white red V34 v34 red green V35 v35 green green V36 v36 blue green V37 v37 yellow green V38 v38 magenta green V39 v39 cyan green } text .header -wrap word -width 0 -height 6 set text { To zoom in on a region of the graph, simply click once on the left mouse button to pick one corner of the area to be zoomed. Move the mouse to the other corner and click again. } regsub -all "\n" $text "" text .header insert end "$text\n" .header insert end { You can click on the } set im [image create picture -file ./images/qv100.t.gif] button .header.snap -image $im -command { MakeSnapshot } .header window create end -window .header.snap .header insert end { button to see a picture image snapshot.} .header configure -state disabled blt::graph $graph blt::htext .footer -text {Hit the %% set im [image create picture -file ./images/stopsign.gif] button $htext(widget).quit -image $im -command { exit } $htext(widget) append $htext(widget).quit %% button when you've seen enough. %% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} foreach {label yData outline color} $attributes { .graph element create $label -x x -y $yData -outline $outline -color $color } set unique 0 proc Sharpen { photo } { set kernel { -1 -1 -1 -1 16 -1 -1 -1 -1 } #set kernel { 0 -1 0 -1 4.9 -1 0 -1 0 } blt::winop convolve $photo $photo $kernel } proc MakeSnapshot {} { update idletasks global unique set top ".snapshot[incr unique]" set im1 [image create picture] .graph snap $im1 set width 410 set height 293 set thumb1 [image create picture -width $width -height $height -gamma 2.2] $thumb1 resize $im1 -filter sinc image delete $im1 set thumb2 [image create picture -window .graph -width $width \ -height $height -filter sinc -gamma 2.2 -aspect yes] toplevel $top wm title $top "Snapshot \#$unique of \"[.graph cget -title]\"" label $top.l1 -image $thumb1 label $top.l2 -image $thumb2 button $top.but -text "Dismiss" -command "DestroySnapshot $top" blt::table $top \ 0,0 $top.l1 \ 0,1 $top.l2 \ 1,0 $top.but -pady 4 focus $top.but } proc DestroySnapshot { win } { set im [$win.l1 cget -image] $im export jpg -file test.jpg image delete $im destroy $win } blt::table . \ .header 0,0 -fill x \ .graph 1,0 -fill both \ .footer 2,0 -fill x blt::table configure . r0 r2 -resize none Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph Blt_PrintKey $graph $graph element bind all <Enter> { %W legend activate [%W element get current] } $graph element bind all <Leave> { %W legend deactivate [%W element get current] } set table [blt::datatable create] $table column extend "x" $table import vector "x" 1 $table column type "x" double set col 1 foreach vector [lsort -dictionary [blt::vector names ::v*]] { set name [string trim $vector ::] $table column extend $name $table column type $name double incr col $table import vector $vector $col } $table dump -file graph4.tab ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/container3.tcl��������������������������������������������������������������0000755�0001750�0001750�00000036176�11462120062�016136� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT namespace import blt::* image create picture mini-apm-alert -data { R0lGODdhEAAQAPIAALLA3AAAAAAAoMDAwKCgoICAgP8AAP///ywAAAAAEAAQAAADSgiq1bGQ tTNKuBHMMmrwEdeMDfEAhqENROu2Z7q6xhurXJvWsCLnOpsPx3q5bjNjD0VULhdAJTJqnBZ0 qZbgBAkIvuBtRnEpYyIJADs= } image create picture mini-apm-empty -data { R0lGODdhEAAQAPIAALLA3AAAAMDAwKCgoICAgP8AAP///wAAACwAAAAAEAAQAAADSQiq1LGQ NSNIuBFMImrwUVE0ZCNGhDisq/hAnNoWw7twgyrbjDDTK57Gl5PVUD4dUBgDFo8w40woZZ1g BJYWCglsgxnFZYyJJAAAOw== } image create picture mini-apm-full -data { R0lGODdhEAAQAPIAALLA3AAAAAAAoMDAwICAgP8AAP///wAAACwAAAAAEAAQAAADQAiq1LGQ NTNIuBFMMmrwEdeMjfBAnKCu6rmkasG6zBAXchva8byzPhQPaPoRi8Ij8jUE0jSEW265CByf 1YsWmwAAOw== } image create picture mini-apm-half -data { R0lGODdhEAAQAPIAALLA3AAAAAAAoMDAwKCgoICAgP8AAP///ywAAAAAEAAQAAADRwiq1bGQ tTNKuBHMMmrwEdeMDfFAHKGu6rmkqsG6zBAbchva8byzKwFNMxAYj8YhB4lUFpnJHTSKKhhx huMQEJhuFZcwJpIAADs= } image create picture mini-apm-loading -data { R0lGODdhEAAQAPMAALLA3AAAAP//AMDAwKCgoICAgP8AAICAAP///wAAAAAAAAAAAAAAAAAA AAAAAAAAACwAAAAAEAAQAAAEXRBIWWo4oNyZKxqHcFzi5BUDKBYhRg1VFcqC9hJ4rFvZkH+p ICzQwxk0gaSSWDQWENCUrfkTTlGCbA0oZWK1ggBw2gNnl5yd9smkPKGI2KcNgCoH8AEdkOQv +xwAEQA7 } image create picture mini-apm-online -data { R0lGODdhEAAQAPIAALLA3AAAAICAAMDAwICAgP//AP///wAAACwAAAAAEAAQAAADRQi6QCHt sSkKrHAuDLhWFUGEwSeeaMkQxuC+g6M5QW2rs6G7stm+vRwsqAn8iJ/bBLVg4RosneHUeups A+ngCagtblxAAgA7 } image create picture mini-apm-unknown -data { R0lGODdhEAAQAPIAALLA3AAAAP//AMDAwICAgP8AAP///wAAACwAAAAAEAAQAAADRAiq1LGQ NTNIuBFMMmrwEdeMjfBAnKCu6rmkQiGvLjPEa9GGt676Nc0tR+MRi6ghDvlSskzGHytYeu4i ASs0A7h4MZEEADs= } image create picture mini-folder -data { R0lGODdhIAAbAPIAALLA3ICAgP//////AMDAwAAAAICAAAAAACwAAAAAIAAbAAADeQgK0e4r yhmDuBgHyqUdBCiGxNZxHzmO5lkRcCzPT10XTKbvPF8UqZVqKBQagAKisrg8BpdQpjPJrEan 1qxyGu0Wsd4wiKsth8BmLVnsRbOt6/QVKVcj3206Hn6vz59+Rn17TXqBW0AGiouMjY6Pijg/ k5SVlpeTAAkAOw== } image create picture mini-arch -data { R0lGODdhEAAQAPEAAICAgAAAAMBkMv+gMiwAAAAAEAAQAAACQQSCqXoi46B7YtlVA51Q1sxN EaQhmyKWmoMYzTCoZOUes/kF9SrHtKvxIW47mIr1M/AyxqQtF2wVYzpG7ZC4arcFADs= } image create picture mini-asmail -data { R0lGODdhEAAQAPMAAJSUlP///97e3mNjYzz4NK2trfgUQL29vXNzc0JCQoCAgAAAAAAAAAAA AAAAAAAAACwAAAAAEAAQAAAEVFDJOYGgmA5iMwaGIYwfAAzDqJLT6q4ScMyvOsSyW9i3MhwC hGo3GhR6JuHLeEAoAgUTcGVEWA9Q089WOCQTWROgcBxYv2GxWoxIeK3weDzhqdvrEQA7 } image create picture mini-audiovol -data { R0lGODdhDgAOAPEAALLA3AAA7v///2ZmZiwAAAAADgAOAAACMYQdcxgLkdhQK8E0oIMz4+19 ztMNwohQ5zkmK8BK0Xtel0I/tgv3uq3y7SiGmARlKAAAOw== } image create picture mini-ball -data { R0lGODdhEAAQAPEAALLA3AAAAP///4CAgCwAAAAAEAAQAAACG4SPqcvtD1mYMAhBncVh6Dl5 Xyc6wxml6so+BQA7 } image create picture mini-bball -data { R0lGODdhEAAQAPEAALLA3AAA/////4CAgCwAAAAAEAAQAAACG4SPqcvtD1mYMAhBncVh6Dl5 Xyc6wxml6so+BQA7 } image create picture mini-bomb -data { R0lGODdhEAAQAPIAALLA3AAAAICAgMDAwP//AP///wAAAAAAACwAAAAAEAAQAAADPAi63K4h vhZWneDaGTV0nbQxgVAMHbkIQcF2wpgFw5sqBJCHHVHlhNwsJEDhggpbhBXTUXgeh62JqVon CQA7 } image create picture mini-book1 -data { R0lGODdhEAAQAPIAALLA3AAAAP8AAP//AICAgP///wAAAAAAACwAAAAAEAAQAAADPAi63K4h vBaFkLNai5neWwcEwwCeXVSeIBZcK8uNXNymtckFBeHlkUKPIHpdeMOI48UjEEWUwHPigVKv CQA7 } image create picture mini-book2 -data { R0lGODdhEAAQAPEAAL+/vwAAAICAgP///ywAAAAAEAAQAAACOYSPeRHqIUZbLMEhAcNzRf5J lXFxGNiVUgil7Lm6p9p6M1zbK5fbgYgRdDwMgdE4JLUYzKTSAY0CCgA7 } image create picture mini-books -data { R0lGODdhEAAQAPIAAICAgP////8AAAAA/wAAAP//AAAAAAAAACwAAAAAEAAQAAADSgi63B3B wRdFGGoSBy5exaYIwjJgRQGECwlgJ0Bs7FjGqFoDLgGvOhGvJIgBV0KXwKdIIVtEX+6Zqcww k11PQVMJZbPG7MspmzkJADs= } image create picture mini-briefcase -data { R0lGODdhEAAQAPIAALLA3ICAAMDAwAAAAICAgP///wAAAAAAACwAAAAAEAAQAAADSQi63B4Q OhaKuCJMFcT4g9ZEZFgClWANAuGpahBegTsUa1eHRY17v5lMRyrWCLwOZpnJzJo6aAZZiVqh z6uVauzKAKCw+LMpJwAAOw== } image create picture mini-bug1 -data { R0lGODdhEAAQAPIAALLA3AAAAMDAwICAgP///wAAAAAAAAAAACwAAAAAEAAQAAADNAi63P5Q hTWjDDUKzEUcAcENEChiIOlgxCCA2MoF2yxjddwEMD1mjA4H4ituLDygZckEJAAAOw== } image create picture mini-bug2 -data { R0lGODdhEAAQAPIAALLA3AAAAICAgMDAwP///wAAAAAAAAAAACwAAAAAEAAQAAADOAi63A5h xceCpUvYLajQW/A9FsFdjWZ+oFiV1hCiyiyHjT1XbXBbmtzmN+ENTw/QrYMBCAbMZjMBADs= } image create picture mini-bx2 -data { R0lGODdhEAAQAPAAALLA3AAAACwAAAAAEAAQAAACIoSPqcuNAeEKL9Kn7AU7ae5EoAOKDfVN R4pVptGtFknXdQEAOw== } image create picture mini-calc -data { R0lGODdhEAAQAPIAALLA3ICAgP///wAAANnZ2QAAAAAAAAAAACwAAAAAEAAQAAADRAi63Bow SgmCuDjjUQUhQyiKYPcN2hWU1jdJrPfN9NkFA4Hr+c5ZIVAuSLz1jrwYcciM7Z7In2AprP5q WBtgxB05vo0EADs= } image create picture mini-camera -data { R0lGODdhEAAQAPEAALLA3AAAAP///4CAgCwAAAAAEAAQAAACNYSPqRDta4KYNCAnhxviyYo1 YBgMJplp5XSWqtByptrC9HyLc7O7bx/q2YA4DQNFgiiXTGYBADs= } image create picture mini-cat -data { R0lGODdhEAAQAPEAAICAgAAAAP//AP8AACwAAAAAEAAQAAACOYSPecGqIUR4YNZoEdw36yh1 FTNBoGSa2Cah5xsN2AW/llqHHYjPdErydTiblCG1wvhIo2PJ44gWAAA7 } image create picture mini-cave -data { R0lGODdhEAAQAPMAAAD//wBy/QAA/AAAuAD/jwD/Cv+EAHL/AP//AA8Pbf8AAP9FAP/HAAAA AAAAAAAAACwAAAAAEAAQAAAEWhBIGaq4I+c5a7iCNhBEYRzGCFjggCAJARCJ8hKskOwJIAAw Cc5C4yVgiUEBODHydL9dgVRw8haJxeKAtO4WBgSDofAaGYcD1sxD49iJwAE9hbcRZXtPz7dH AAA7 } image create picture mini-cd -data { R0lGODdhEAAQAPIAALLA3ICAgP//AMDAwAAAAAD//wD/AP///ywAAAAAEAAQAAADUQiq0b2Q BSGGJSSCUGi1FxQYRfdZx5AxBkmBqcpYbYeCcgCSAaHjmR8tQ8DlcIceB7iBoQyCAmili9Gi 0tXGesVqm7gW5SvZGTCaRQNDTrsVCQA7 } image create picture mini-cdlabel -data { R0lGODdhEAAQAPEAALLA3AAAAICAgAAAACwAAAAAEAAQAAACM4SPecEg8SJcIFQpqVWpsfcx 21aVBmmlZTqpbinE66yeVUt7NC2/qAkciYYQEeeITCoTBQA7 } image create picture mini-chinese -data { R0lGODdhEAAQAPAAAICAgAAA/ywAAAAAEAAQAAACJoQdB6kXrx5ri0FapZ4R2baFEpVAHFkt WCaunuuFcDq/NV1f91oAADs= } image create picture mini-clipboard -data { R0lGODdhEAAQAPIAALLA3AAAAP//AICAAICAgMDAwAAAgP///ywAAAAAEAAQAAADUgi63B4w OBWhEFXSQUbAX9ARmkgWaCp6BBBwWUSQ7TpyeCe6+WD8QMPOxjEcjsdfrWdEHowG141gjDyB r1vTmSRSD7Gnq7LlRgGzWXB9bqTfswQAOw== } image create picture mini-clock -data { R0lGODdhEAAQAPEAALLA3AAAAP///8DAwCwAAAAAEAAQAAACMoSPqRDda5qY86UwaKAjXCps GiJqYHiU1elFoPSmrNoybDjKZ55me6eAaWpBBxGCTCoKADs= } image create picture mini-colors -data { R0lGODdhEAAQAPIAALLA3ICAgP8AAP//AAAA/wAAAP///wAAACwAAAAAEAAQAAADPgi63P4w skCrtSqILYYfREgEBaBxHyiSJtd94lieWxqzgaEbVuEXuB2v8gPOhL1fcJf04S5QSglQrFYl WGwCADs= } image create picture mini-connect -data { R0lGODdhEAAQAPIAALLA3AAAAICAgP8AAP//AAAAAAAAAAAAACwAAAAAEAAQAAADLwi63P7Q hbgECJaKMfJ8GzdcWROKHXSKpYl2n7MKsUkIOK3edFAzAh6l0tIMj44EADs= } image create picture mini-crosbone -data { R0lGODdhEAAQAPEAAICAgAAAAP///8DAwCwAAAAAEAAQAAACQUQCqXqMu5qRMJ0HxBV8jygM 4jhoUPAhKTBgVnvAqGtkIcrVJ1uKeoUi0Rwz2SnQmSE1j4PgJXowLRHKr4LNagEFADs= } image create picture mini-cross -data { R0lGODdhEAAQAPEAALLA3P8AAICAgAAAACwAAAAAEAAQAAACKISPqcsbHgQKFEpAM8x0DMYF X8ONYNhgovpApqasU5TItWngiZ72TAEAOw== } image create picture mini-desktop -data { R0lGODdhEAAQAPIAAICAgACAgAAAAAD//8DAwP///4CAAP//ACwAAAAAEAAQAAADQgi6EMIQ BveidEBUG8asWqSNobJZzIku6tq62UIARSEQhkHsRDXXNtwhd/PRgoaD8vB49EjPkekIrAJj K0iTxCUpEgA7 } image create picture mini-dfolder -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwP//AAAA/wAAAP///wAAACwAAAAAEAAQAAADSQi63BsQ OhbEsCJMUK/PkcQZZGmSQTF+YTtiwWkWsRcTeB7TBmwQP52BZwvmCLuY74hLGopM5LAVo+4A hax2u93ESJkNlqsFJAAAOw== } image create picture mini-diff -data { R0lGODdhEAAQAPEAALLA3P8AAAAAAP///ywAAAAAEAAQAAACQYSPqcLtckSYQYyLIZDGVnxB HDBYw5dtAbldaKhGrhkyVTODTBnU07PjUSiaTsZBlIEyydbS93M+RVGgo1NUaA0FADs= } image create picture mini-diskette -data { R0lGODdhEAAQAPIAAAAAgAAAAICAgP//AODg4P///8DAwAAAACwAAAAAEAAQAAADQAgQ3B5K qEGrHQoCwrsnmVKMZFmE2/ehZouq6yK2JarcOK4pRu8bOhwQ8AvehsXbjsjzGXnNnk4STWYE goe2kQAAOw== } image create picture mini-display -data { R0lGODdhEAAQAPIAALLA3ICAgP///wAAAAAA/8DAwAAAAAAAACwAAAAAEAAQAAADPgi63Bsw SviEvdgOFcT4INhtwEic6DlyHiGkqscOMLqWbU3cps7ntd9gIpHhMkgSIMQEOTqXQkC5aDYd 2EYCADs= } image create picture mini-doc -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwAAAAP///wAAAAAAAAAAACwAAAAAEAAQAAADNAix3PAw kEmnCPDJSgXBEUcN5BCKnamh6ckKqsJa8fbWMwG76L7OPhkQN4wIjshksMRsqhIAOw== } image create picture mini-doc1 -data { R0lGODdhEAAQAPEAALLA3AAAAP///4CAgCwAAAAAEAAQAAACOYSPicEdeoKYk0EghxbyKUlx zSdomxYMCRhW6lKaW7q2FA3L8xvZbq0bcHgGVgsXcSiJhqDsAgUUAAA7 } image create picture mini-dog -data { R0lGODdhEAAQAPEAAICAgAAAAP///8DAwCwAAAAAEAAQAAACPoSPqRbt6oKYgiEpxqA1XKkJ zeRdGTZg4pVybgk0sTvFMENydhJsI3WbTVIRnoiSWqhsMmOIEzRwntGFFVAAADs= } image create picture mini-edit -data { R0lGODdhEAAQAPIAALLA3AAAAICAgP///wAA/wAAAAAAAAAAACwAAAAAEAAQAAADPwi63CAw RveGvUMEJ7LMw7YQHWZpgUiQXoRta1CaVxBX0ndXtLXjOQ1BpJi9UkRgBBliGEMvZ6/GQFqv lGwjAQA7 } image create picture mini-espada -data { R0lGODdhEAAQAPAAAICAgAAAACwAAAAAEAAQAAACIoSPqRbr7RSMJ1jK7I26v+4l4CiOYWVq 0tWo1IQBMHfGSwEAOw== } image create picture mini-exclam -data { R0lGODdhEAAQAPIAALLA3ICAgACAAP///wAAAAAAAAAAAAAAACwAAAAAEAAQAAADLQi6GsKQ hSFEiJJWglf9XOeAV/dtnXKGKZh6AvvGLyOnU1UDZznHPhwhuEslAAA7 } image create picture mini-exp -data { R0lGODdhEAAQAPEAALLA3AAAAICAgP//ACwAAAAAEAAQAAACMoSPqRbrzYQDYbQAD97VWtUN 4shJzIiSSZhmDKuuaayJmN1lHGVT2GHSuAJB0OSInBQAADs= } image create picture mini-eye -data { R0lGODdhEAAQAPEAALLA3AAAAIKCgsPDwywAAAAAEAAQAAACK4SPqcvtb4KcYs1wKJIADzF0 HTZGgBBU5JiaX0hWh6Bmp5yoHA71/g+EFAAAOw== } image create picture mini-eyes -data { R0lGODdhEAAQAPIAALLA3AAAAICAgMDAwP///wAAAAAAAAAAACwAAAAAEAAQAAADPwi63P4w tkDDqvYOQoYNW5eBHOeF5leWwcoFQuvKK9xSLIG/sSefO48AQBL1UoIhsZJcUpqLJBQgVUqu 2KwiAQA7 } image create picture mini-fax -data { R0lGODdhEAAQAPIAALLA3ICAgAAAAMDAwP///wAAAAAAAAAAACwAAAAAEAAQAAADSAi6HM5w BUIfdI5qIuQk39Yp0zBkokScpTlwJ1DOQuAKZkYHtXvWu17OAaSYhBii0DhMdnC5VZI3Agig LGXEitNuF9fqd7xIAAA7 } image create picture mini-fdisk -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwAAAAP8AAP///wAAAAAAACwAAAAAEAAQAAADMgi63P4w yhmqvVYFwbvnwRAUZGmSlfh9hJBu3eW9bjrcVq125hxiQMtAcSsajZOkcpkAADs= } image create picture mini-filemgr -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwAAAAP///wAAAAAAAAAAACwAAAAAEAAQAAADPggK0f5L BUGraCO+jTX5IDF0S0BY1Bhk5TkMlcpKJyp7qHCXb9+TtNBnR8sRGS5YCog0riJN24zn60Gv 2EUCADs= } image create picture mini-folder -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwP//AAAAAP///wAAAAAAACwAAAAAEAAQAAADOwi63BsQ OhbEsCJMUK/PkcQVZGmSATF+rJWOWHu9QSHHdBHvs1rfnhxvlwO6fKFkSAUgOJ9Q6GZKdSQA ADs= } image create picture mini-font -data { R0lGODdhEAAQAPEAALLA3AAAAICAgAAAACwAAAAAEAAQAAACJ4SPqcvtF8IzMYhXrYuCN95p Cwh4Y2YmoBBequWWIpLKMcIm+cQ3BQA7 } image create picture mini-fractal -data { R0lGODdhEAAQAPIAALLA3AAAAICAgP8AAP//AMDAwACAAAAA/ywAAAAAEAAQAAADSQi63BpB MAHjqvCNQXh4T7V15Fd8gZF24iZpxqBe3hXPALp9j4HzgcMAuBnmLofDK7AL5ZJE1iMJvZQu kFeOZHTQrt4HlxcuexMAOw== } image create picture mini-frame -data { R0lGODdhEAAQAPEAALLA3P8AAAAAAAAAACwAAAAAEAAQAAACM4SPqcGsGISU4YF43V3izrpx IdMlWFRhZqeeD+rFJniWEHu4ptGwNmSQyF4NlQUw+R2PBQA7 } image create picture mini-ftp -data { R0lGODdhEAAQAPEAAICAgP///wAAAAAA/ywAAAAAEAAQAAACNoSPqcEdelwDDwh7w9hN+ItI EhhtphmQhuiolMa1l/eyaQKf3ZzZd3gatHA+l+93+CiVkCagAAA7 } image create picture mini-gball -data { R0lGODdhEAAQAPEAALLA3ACAAP///4CAgCwAAAAAEAAQAAACG4SPqcvtD1mYMAhBncVh6Dl5 Xyc6wxml6so+BQA7 } image create picture mini-go -data { R0lGODdhEAAQAPEAAICAgAAA//8AAP///ywAAAAAEAAQAAACMoSPecEpj8IYzYgJjaTh3JEB zOg9oViVgsK27gtbJ9p52KpN6Rduu4mjpQCmBCmGdBUAADs= } image create picture mini-gopher -data { R0lGODdhEAAQAPIAAICAgICAAIAAAP///wAAAAAAAAAAAAAAACwAAAAAEAAQAAADSQgKESLN LRXAg+41SzO+zbM4Q0mawuQQxECy0ijAGZzKmheOHst+qcvFRwAKQT8joIhkhggK5oywoq4m LFSJNZloB92weExWJAAAOw== } image create picture mini-graph -data { R0lGODdhEAAQAPIAAICAgAAAAP8A/wAA/wD/AP8AAAAAAAAAACwAAAAAEAAQAAADOwi6G86Q CRGindUCV7EGw9BRXzhmlgl4DAeKK8kQRKWyC23Dnqu/J0ChUPndSMNiDRirJDnQKPRDrSoS ADs= } image create picture mini-gv -data { R0lGODdhEAAQAPEAALLA3AAAAP///wAAACwAAAAAEAAQAAACMYSPqcGhGYQU7oE4ZV1ZP0Zp FINgYYhtZjdtF9tyrHussdzRL0yV7e+pNS4kkuUIKAAAOw== } image create picture mini-hammer -data { R0lGODdhEAAQAPEAAL+/vwAAAP///4CAgCwAAAAAEAAQAAACK4SPiRHAr5wQYdqWqt00i6FN TLc0TzA4WAQZq9JG5SurtBzXtn7ktc8L6goAOw== } image create picture mini-happy -data { R0lGODdhEAAQAPEAALLA3AAAAP//AAAAACwAAAAAEAAQAAACM4SPqRDda5qY86VAc70VSxEg WAeO4GFK3xlpbti6GcxU2kjXpbOJFN8TmToQhiNXTCoPBQA7 } image create picture mini-hdisk -data { R0lGODdhEAAQAPIAALLA3ICAgMDAwAAAAACAAP///wAAAAAAACwAAAAAEAAQAAADLgi63P4w yhmqvVYFwbvnwRAUZGmSlfh9hJBu6/e62EWr53nXfKgMwKAwOCkajwkAOw== } image create picture mini-heart -data { R0lGODdhEAAQAPAAAICAgAAAACwAAAAAEAAQAAACIoSPqbvh54KKj0pogb16b+RRSRhNIeMx RqauTwvBoBzTbQEAOw== } image create picture mini-hex -data { R0lGODdhEAAQAPEAAICAgP///wAAAAAA/ywAAAAAEAAQAAACO4SPecHdIBIbjQYQ4qLcQqFh 3FRlS2ChZei0DauSJDtYY20a8qjC6Z/DuFq+0myjulFoydjyAIpKpYACADs= } image create picture mini-hextris -data { R0lGODdhEAAQAPIAALLA3ICAgP//AAAAAP8AAAAAAAAAAAAAACwAAAAAEAAQAAADNAi63P5Q hRlXEHjUSzrR0eANQQUMaLlhAvlM3EhZrNgNtSR4H7qPCttHJXQFUwyU0cRsMhMAOw== } image create picture mini-iconify -data { R0lGODdhEAAOAPEAALLA3P8AAAAAAAAAACwAAAAAEAAOAAACKoyPKSHt7xgDtFoqxd0g8+tV iIYtJHacIWqopgWJ7ydPdGnfUsKn0A8pAAA7 } image create picture mini-icons -data { R0lGODdhEAAQAPIAAICAgP///wAAAAAA/wD/AP8AAP//AAAAACwAAAAAEAAQAAADPAi63BoQ ihfDBGFo+4jnmDaAgUeQImmS1VWBQiwr8uzceL68bvsUQJJhSAIWhESXEWlgRXpPWu0yvega CQA7 } image create picture mini-keyboard -data { R0lGODdhEQAQAPEAAICAgP///wAAAMDAwCwAAAAAEQAQAAACPYSPecHtDgQIqsY5hwiab31R QzQKZRlqwsq2kuTFHQPC2nkPqO32LxZrdGoYnI50gUV8rYul8mL2ntRqogAAOw== } set images1 { apm-alert apm-empty apm-full apm-half apm-loading apm-online apm-unknown folder arch asmail audiovol ball bball } set images2 { bomb book1 book2 books briefcase bug1 bug2 bx2 calc camera cat cave cd cdlabel chinese clipboard clock colors connect crosbone } set images3 { cross desktop dfolder diff diskette display doc doc1 dog edit espada exclam exp eye eyes fax fdisk filemgr font fractal } set images4 { frame ftp gball go gopher graph gv hammer happy hdisk heart hex hextris iconify icons keyboard } proc MakeContainer { count images } { set c .c$count set top .top$count set b .b$count blt::container $c -bd 0 -highlightthickness 0 toplevel $top wm withdraw $top wm protocol $top WM_DELETE_WINDOW "$b invoke" frame $top.f -relief raised -highlightthickness 0 pack $top.f -expand yes -fill x foreach img $images { button $top.f.$img -image mini-$img -bd 1 -command "puts $img" \ -highlightthickness 0 pack $top.f.$img -side left -padx 0 -pady 0 } global $img checkbutton $b -variable $img -onvalue $top -offvalue "" -command \ [subst -nocommands { $c configure -window \$$img }] $b select blt::table . \ $b $count,0 -anchor w \ $c $count,1 -fill x blt::table configure . c0 -resize none blt::table configure . r$count -resize none after 1 [subst { update wm deiconify $top $c configure -window $top }] return $c } MakeContainer 1 $images1 MakeContainer 2 $images2 MakeContainer 3 $images3 MakeContainer 4 $images4 canvas .a blt::table . .a -cspan 40 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop2.tcl������������������������������������������������������������������0000755�0001750�0001750�00000001101�11462120062�015263� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set file images/qv100.t.gif if { [file exists $file] } { set photo [image create picture -file $file] } else { puts stderr "no image file" exit 0 } option add *Label.font *helvetica*10* option add *Label.background lightsteelblue set i 0 foreach r { -45 0 45 90 135 180 225 270 315 360 -315 } { set dest [image create picture -rotate $r -image $photo] label .footer$i -text "$r degrees" label .l$i -image $dest blt::table . \ 0,$i .l$i \ 1,$i .footer$i update incr i } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/paneset3.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000711�11462120062�015572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::paneset .vps -orient vertical blt::paneset .vps.hps blt::graph .vps.g -height 400 -width 500 blt::barchart .vps.hps.b -height 400 -width 400 blt::barchart .vps.hps.b2 -height 400 -width 400 .vps add -window .vps.g -fill both .vps add -window .vps.hps -fill both .vps.hps add -window .vps.hps.b -fill both .vps.hps add -window .vps.hps.b2 -fill both focus .vps pack .vps -fill both -expand yes �������������������������������������������������������./saods9/blt3.0.1/demos/graph1.tcl������������������������������������������������������������������0000755�0001750�0001750�00000104652�11462120062�015246� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish if { [info exists env(BLT_LIBRARY)] } { lappend auto_path $env(BLT_LIBRARY) } package require BLT source scripts/demo.tcl set normalBg [blt::bgpattern create gradient -low grey40 -high grey95 \ -jitter yes -log no -opacity 80] set normalBg [blt::bgpattern create texture -type checkered -low grey85 -high grey98] #set normalBg white #set activeBg grey95 # option add *Axis.activeBackground $activeBg # option add *Legend.activeBackground $activeBg set graph .g blt::graph .g \ -bg $normalBg \ -plotrelief solid \ -plotborderwidth 1 \ -relief raised \ -plotpadx 0 -plotpady 0 \ -borderwidth 2 blt::htext .header \ -text {\ This is an example of the graph widget. It displays two-variable data with assorted line attributes and symbols. To create a postscript file "xy.ps", press the %% blt::tk::button $htext(widget).print -text print -command { puts stderr [time { blt::busy hold . update .g postscript output demo1.eps -width 5i -height 5i update blt::busy release . update }] } $htext(widget) append $htext(widget).print %% button.} set X { 2.00000e-01 4.00000e-01 6.00000e-01 8.00000e-01 1.00000e+00 1.20000e+00 1.40000e+00 1.60000e+00 1.80000e+00 2.00000e+00 2.20000e+00 2.40000e+00 2.60000e+00 2.80000e+00 3.00000e+00 3.20000e+00 3.40000e+00 3.60000e+00 3.80000e+00 4.00000e+00 4.20000e+00 4.40000e+00 4.60000e+00 4.80000e+00 5.00000e+00 } set Y1 { 4.07008e+01 7.95658e+01 1.16585e+02 1.51750e+02 1.85051e+02 2.16479e+02 2.46024e+02 2.73676e+02 2.99427e+02 3.23267e+02 3.45187e+02 3.65177e+02 3.83228e+02 3.99331e+02 4.13476e+02 4.25655e+02 4.35856e+02 4.44073e+02 4.50294e+02 4.54512e+02 4.56716e+02 4.57596e+02 4.58448e+02 4.59299e+02 4.60151e+02 } set Y2 { 5.14471e-00 2.09373e+01 2.84608e+01 3.40080e+01 3.75691e+01 3.91345e+01 3.92706e+01 3.93474e+01 3.94242e+01 3.95010e+01 3.95778e+01 3.96545e+01 3.97313e+01 3.98081e+01 3.98849e+01 3.99617e+01 4.00384e+01 4.01152e+01 4.01920e+01 4.02688e+01 4.03455e+01 4.04223e+01 4.04990e+01 4.05758e+01 4.06526e+01 } set Y3 { 2.61825e+01 5.04696e+01 7.28517e+01 9.33192e+01 1.11863e+02 1.28473e+02 1.43140e+02 1.55854e+02 1.66606e+02 1.75386e+02 1.82185e+02 1.86994e+02 1.89802e+02 1.90683e+02 1.91047e+02 1.91411e+02 1.91775e+02 1.92139e+02 1.92503e+02 1.92867e+02 1.93231e+02 1.93595e+02 1.93958e+02 1.94322e+02 1.94686e+02 } set configOptions { Element.Pixels 6 Element.Smooth catrom Legend.ActiveBackground khaki2 Legend.ActiveRelief sunken Legend.Background "" Legend.Position plotarea Title "A Simple X-Y Graph" activeLine.Color yellow4 activeLine.Fill yellow background khaki3 line1.Color red4 line1.Fill red1 line1.Symbol splus line2.Color purple4 line2.Fill purple1 line2.Symbol arrow line3.Color green4 line3.Fill green1 line3.Symbol triangle x.Descending no x.Loose no x.Title "X Axis Label" y.Rotate 0 y.Title "Y Axis Label" } set resource [string trimleft $graph .] foreach { option value } $configOptions { option add *$resource.$option $value } $graph element create line1 -x $X -y $Y2 $graph element create line2 -x $X -y $Y3 $graph element create line3 -x $X -y $Y1 Blt_ZoomStack $graph Blt_Crosshairs $graph #Blt_ActiveLegend $graph Blt_ClosestPoint $graph blt::htext .footer \ -text {Hit the %% blt::tk::button $htext(widget).quit -text quit -command { exit } $htext(widget) append $htext(widget).quit %% button when you've seen enough.%% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} proc MultiplexView { args } { eval .g axis view y $args eval .g axis view y2 $args } blt::tk::scrollbar .xbar \ -command { .g axis view x } \ -orient horizontal \ -highlightthickness 0 blt::tk::scrollbar .ybar \ -command MultiplexView \ -orient vertical -highlightthickness 0 blt::table . \ 0,0 .header -cspan 3 -fill x \ 1,0 .g -fill both -cspan 3 -rspan 3 \ 2,3 .ybar -fill y -padx 0 -pady 0 \ 4,1 .xbar -fill x \ 5,0 .footer -cspan 3 -fill x blt::table configure . c3 r0 r4 r5 -resize none .g axis configure x \ -scrollcommand { .xbar set } \ -scrollmax 10 \ -scrollmin 2 \ -activeforeground red3 \ -activebackground white \ -title "X ayis" \ -exterior no .g axis configure y \ -scrollcommand { .ybar set } \ -scrollmax 1000 \ -activeforeground red3 \ -activebackground white \ -scrollmin -100 \ -rotate 0 \ -title "Y ayis" \ -exterior no .g axis configure y2 \ -scrollmin 0.0 -scrollmax 1.0 \ -hide no \ -rotate 0 \ -exterior no \ -title "Y2" .g axis configure x2 \ -scrollmin 0.0 -scrollmax 1.0 \ -hide no \ -rotate 0 \ -exterior no \ -title "X2" .g legend configure \ -relief flat -bd 0 \ -activerelief flat \ -activeborderwidth 1 \ -position plotarea -anchor ne -padx 10 -pady 10 -bg "" #.g configure -plotpadx 0 -plotpady 0 -plotborderwidth 1 -plotrelief solid \ # -Width 4.4i -plotwidth 2.0i -leftmargin 0i -rightmargin 1.0i .g pen configure "activeLine" \ -showvalues y .g configure -halo 50 .g element bind all <Enter> { eval %W legend deactivate * %W legend activate [%W element get current] } .g configure -plotpady { 0 0 } .g element bind all <Leave> { %W legend deactivate * } .g axis bind all <Enter> { set axis [%W axis get current] #%W axis activate $axis %W axis focus $axis } .g axis bind all <Leave> { set axis [%W axis get current] #%W axis deactivate $axis %W axis focus "" } .g configure -leftvariable left trace variable left w "UpdateTable .g" proc UpdateTable { graph p1 p2 how } { blt::table configure . c0 -width [$graph extents leftmargin] blt::table configure . c2 -width [$graph extents rightmargin] blt::table configure . r1 -height [$graph extents topmargin] blt::table configure . r3 -height [$graph extents bottommargin] } set image1 [image create picture -file bitmaps/sharky.xbm] set image2 [image create picture -file images/buckskin.gif] set bg1 [blt::bgpattern create solid -color blue -opacity 30] set bg2 [blt::bgpattern create solid -color green -opacity 40] set bg3 [blt::bgpattern create solid -color pink -opacity 40] .g element configure line1 -areabackground $bg1 -areaforeground blue #.g element configure line2 -areabackground $bg2 #.g element configure line3 -areabackground $bg3 .g configure -title "Graph Title" .g marker create line -name "y100" -coords { -Inf 100 Inf 100 } -dashes 1 \ -outline green -linewidth 1 .g configure -plotpady 10 -plotpadx 10 if { $tcl_platform(platform) == "windows" } { if 0 { set name [lindex [blt::printer names] 0] set printer {Lexmark Optra E310} blt::printer open $printer blt::printer getattrs $printer attrs puts $attrs(Orientation) set attrs(Orientation) Landscape set attrs(DocumentName) "This is my print job" blt::printer setattrs $printer attrs blt::printer getattrs $printer attrs puts $attrs(Orientation) after 5000 { $graph print2 $printer blt::printer close $printer } } else { after 5000 { $graph print2 } } if 1 { after 2000 { $graph snap -format emf CLIPBOARD } } } focus .g .g xaxis bind <Left> { .g xaxis view scroll -1 units } .g xaxis bind <Right> { .g xaxis view scroll 1 units } .g yaxis bind <Up> { .g yaxis view scroll -1 units } .g yaxis bind <Down> { .g yaxis view scroll 1 units } .g y2axis bind <Up> { .g y2axis view scroll -1 units } .g y2axis bind <Down> { .g y2axis view scroll 1 units } .g axis bind all <ButtonPress-1> { set b1(x) %x set b1(y) %y set axis [%W axis get current] %W axis activate $axis } .g axis bind all <ButtonRelease-1> { set b1(x) %x set b1(y) %y set axis [%W axis get current] %W axis deactivate $axis # %W axis focus "" } .g xaxis bind <B1-Motion> { set dist [expr %x - $b1(x)] .g xaxis view scroll $dist pixels set b1(x) %x } .g yaxis bind <B1-Motion> { set dist [expr %y - $b1(y)] .g yaxis view scroll $dist pixels set b1(y) %y } blt::LegendSelections .g .g legend configure -selectmode multiple proc FixAxes { g option value } { global axisd foreach a [$g axis names $axisd(axis)] { $g axis configure $a $option $value } } proc AxisOptions { w } { global axisd $w insert end "Axis" set t [frame $w.axis] $w tab configure "Axis" -window $w.axis blt::tk::label $t.axis_l -text "Select Axis:" blt::combobutton $t.axis -textvariable axisd(-axis) \ -menu $t.axis.m -command "puts hi" set m [blt::combomenu $t.axis.m -textvariable axisd(-axis)] foreach axis [.g axis names] { $m add -type radiobutton -text $axis -value $axis } $m add -type radiobutton -text "all" -value "*" $m item configure all -variable axisd(axis) blt::tk::label $t.exterior_l -text "-exterior" blt::combobutton $t.exterior -textvariable axisd(-exterior) \ -menu $t.exterior.m set m [blt::combomenu $t.exterior.m] $m add -type radiobutton -text "yes" $m add -type radiobutton -text "no" $m item configure all -variable axisd(-exterior) \ -command { FixAxes .g -exterior $axisd(-exterior) } blt::tk::label $t.color_l -text "-color" blt::combobutton $t.color -textvariable axisd(-color) \ -menu $t.color.m set m [blt::combomenu $t.color.m] $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable axisd(-color) \ -command { FixAxes .g -color $axisd(-color) } blt::tk::label $t.linewidth_l -text "-linewidth" blt::combobutton $t.linewidth -textvariable axisd(-linewidth) \ -menu $t.linewidth.m set m [blt::combomenu $t.linewidth.m] $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable axisd(-linewidth) \ -command { FixAxes .g -linewidth $axisd(-linewidth) } blt::tk::label $t.showticks_l -text "-showticks" blt::combobutton $t.showticks -textvariable axisd(-showticks) \ -menu $t.showticks.m set m [blt::combomenu $t.showticks.m] $m add -type radiobutton -text "yes" $m add -type radiobutton -text "no" $m item configure all -variable axisd(-showticks) \ -command { FixAxes .g -showticks $axisd(-showticks) } blt::tk::label $t.hide_l -text "-hide" blt::combobutton $t.hide -textvariable axisd(-hide) \ -menu $t.hide.m set m [blt::combomenu $t.hide.m] $m add -type radiobutton -text "yes" $m add -type radiobutton -text "no" $m item configure all -variable axisd(-hide) \ -command { FixAxes .g -hide $axisd(-hide) } blt::tk::label $t.loose_l -text "-loose" blt::combobutton $t.loose -textvariable axisd(-loose) \ -menu $t.loose.m set m [blt::combomenu $t.loose.m] $m add -type radiobutton -text "yes" $m add -type radiobutton -text "no" $m add -type radiobutton -text "always" $m item configure all -variable axisd(-loose) \ -command { FixAxes .g -loose $axisd(-loose) } blt::tk::label $t.title_l -text "-title" blt::combobutton $t.title -textvariable axisd(-title) \ -menu $t.title.m set m [blt::combomenu $t.title.m] $m add -type radiobutton -text "title1" $m add -type radiobutton -text "Title2" $m add -type radiobutton -text "none" -value "" $m item configure all -variable axisd(-title) \ -command { FixAxes .g -title $axisd(-title) } $t.axis.m select 0 foreach option { color exterior showticks linewidth loose title hide } { set value [.g axis cget $axisd(axis) -$option] set axisd(-$option) $value } blt::table $t \ 0,0 $t.axis_l -anchor e \ 0,1 $t.axis -fill x \ 2,0 $t.color_l -anchor e \ 2,1 $t.color -fill x \ 3,0 $t.exterior_l -anchor e \ 3,1 $t.exterior -fill x \ 4,0 $t.hide_l -anchor e \ 4,1 $t.hide -fill x \ 5,0 $t.linewidth_l -anchor e \ 5,1 $t.linewidth -fill x \ 6,0 $t.loose_l -anchor e \ 6,1 $t.loose -fill x \ 7,0 $t.showticks_l -anchor e \ 7,1 $t.showticks -fill x \ 8,0 $t.title_l -anchor e \ 8,1 $t.title -fill x blt::table configure $t r0 -pady 8 } proc GraphOptions { w } { global graphd $w insert end "Graph" set t [frame $w.graph] $w tab configure "Graph" -window $w.graph blt::tk::label $t.plotborderwidth_l -text "-plotborderwidth" blt::combobutton $t.plotborderwidth -textvariable graphd(-plotborderwidth) \ -menu $t.plotborderwidth.m set m [blt::combomenu $t.plotborderwidth.m] $m add -type radiobutton -text [.g cget -plotborderwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable graphd(-plotborderwidth) \ -command { .g configure -plotborderwidth $graphd(-plotborderwidth) } blt::tk::label $t.borderwidth_l -text "-borderwidth" blt::combobutton $t.borderwidth -textvariable graphd(-borderwidth) \ -menu $t.borderwidth.m set m [blt::combomenu $t.borderwidth.m] $m add -type radiobutton -text [.g cget -borderwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable graphd(-borderwidth) \ -command { .g configure -borderwidth $graphd(-borderwidth) } blt::tk::label $t.plotpady_l -text "-plotpady" blt::combobutton $t.plotpady -textvariable graphd(-plotpady) \ -menu $t.plotpady.m set m [blt::combomenu $t.plotpady.m] $m add -type radiobutton -text [.g cget -plotpady] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable graphd(-plotpady) \ -command { .g configure -plotpady $graphd(-plotpady) } blt::tk::label $t.plotpadx_l -text "-plotpadx" blt::combobutton $t.plotpadx -textvariable graphd(-plotpadx) \ -menu $t.plotpadx.m set m [blt::combomenu $t.plotpadx.m] $m add -type radiobutton -text [.g cget -plotpadx] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable graphd(-plotpadx) \ -command { .g configure -plotpadx $graphd(-plotpadx) } blt::tk::label $t.plotrelief_l -text "-plotrelief" blt::combobutton $t.plotrelief -textvariable graphd(-plotrelief) \ -menu $t.plotrelief.m set m [blt::combomenu $t.plotrelief.m] $m add -type radiobutton -text [.g cget -plotrelief] $m add -type separator $m add -type radiobutton -text "flat" $m add -type radiobutton -text "groove" $m add -type radiobutton -text "raised" $m add -type radiobutton -text "ridge" $m add -type radiobutton -text "solid" $m add -type radiobutton -text "sunken" $m item configure all -variable graphd(-plotrelief) \ -command { .g configure -plotrelief $graphd(-plotrelief) } blt::tk::label $t.relief_l -text "-relief" blt::combobutton $t.relief -textvariable graphd(-relief) \ -menu $t.relief.m set m [blt::combomenu $t.relief.m] $m add -type radiobutton -text [.g cget -relief] $m add -type separator $m add -type radiobutton -text "flat" $m add -type radiobutton -text "groove" $m add -type radiobutton -text "raised" $m add -type radiobutton -text "ridge" $m add -type radiobutton -text "solid" $m add -type radiobutton -text "sunken" $m item configure all -variable graphd(-relief) \ -command { .g configure -relief $graphd(-relief) } blt::tk::label $t.plotwidth_l -text "-plotwidth" blt::combobutton $t.plotwidth -textvariable graphd(-plotwidth) \ -menu $t.plotwidth.m set m [blt::combomenu $t.plotwidth.m] $m add -type radiobutton -text [.g cget -plotwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "100" $m add -type radiobutton -text "200" $m add -type radiobutton -text "2i" $m add -type radiobutton -text "4i" $m add -type radiobutton -text "8i" $m item configure all -variable graphd(-plotwidth) \ -command { .g configure -plotwidth $graphd(-plotwidth) } blt::tk::label $t.plotheight_l -text "-plotheight" blt::combobutton $t.plotheight -textvariable graphd(-plotheight) \ -menu $t.plotheight.m set m [blt::combomenu $t.plotheight.m] $m add -type radiobutton -text [.g cget -plotheight] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "100" $m add -type radiobutton -text "200" $m add -type radiobutton -text "2i" $m add -type radiobutton -text "4i" $m add -type radiobutton -text "8i" $m item configure all -variable graphd(-plotheight) \ -command { .g configure -plotheight $graphd(-plotheight) } blt::tk::label $t.width_l -text "-width" blt::combobutton $t.width -textvariable graphd(-width) \ -menu $t.width.m set m [blt::combomenu $t.width.m] $m add -type radiobutton -text [.g cget -width] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "100" $m add -type radiobutton -text "2.5i" $m add -type radiobutton -text "4i" $m add -type radiobutton -text "6i" $m add -type radiobutton -text "8.5i" $m item configure all -variable graphd(-width) \ -command { .g configure -width $graphd(-width) } blt::tk::label $t.height_l -text "-height" blt::combobutton $t.height -textvariable graphd(-height) \ -menu $t.height.m set m [blt::combomenu $t.height.m] $m add -type radiobutton -text [.g cget -height] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "200" $m add -type radiobutton -text "2.5i" $m add -type radiobutton -text "4i" $m add -type radiobutton -text "6i" $m add -type radiobutton -text "8.5i" $m item configure all -variable graphd(-height) \ -command { .g configure -height $graphd(-height) } blt::tk::label $t.plotbackground_l -text "-plotbackground" blt::combobutton $t.plotbackground -textvariable graphd(-plotbackground) \ -menu $t.plotbackground.m set m [blt::combomenu $t.plotbackground.m] $m add -type radiobutton -text [.g cget -plotbackground] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable graphd(-plotbackground) \ -command { .g configure -plotbackground $graphd(-plotbackground) } blt::tk::label $t.background_l -text "-background" blt::combobutton $t.background -textvariable graphd(-background) \ -menu $t.background.m set m [blt::combomenu $t.background.m] $m add -type radiobutton -text [.g cget -background] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable graphd(-background) \ -command { .g configure -background $graphd(-background) } blt::tk::label $t.title_l -text "-title" blt::combobutton $t.title -textvariable graphd(-title) \ -menu $t.title.m set m [blt::combomenu $t.title.m] $m add -type radiobutton -text [.g cget -title] $m add -type separator $m add -type radiobutton -text "title1" $m add -type radiobutton -text "Title2" $m add -type radiobutton -text "none" -value "" $m item configure all -variable graphd(-title) \ -command { .g configure -title $graphd(-title) } blt::tk::label $t.leftmargin_l -text "-leftmargin" blt::combobutton $t.leftmargin -textvariable graphd(-leftmargin) \ -menu $t.leftmargin.m set m [blt::combomenu $t.leftmargin.m] $m add -type radiobutton -text [.g cget -leftmargin] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "10" $m add -type radiobutton -text ".25i" $m add -type radiobutton -text ".5i" $m add -type radiobutton -text "1.0i" $m add -type radiobutton -text "2.0i" $m item configure all -variable graphd(-leftmargin) \ -command { .g configure -leftmargin $graphd(-leftmargin) } blt::tk::label $t.rightmargin_l -text "-rightmargin" blt::combobutton $t.rightmargin -textvariable graphd(-rightmargin) \ -menu $t.rightmargin.m set m [blt::combomenu $t.rightmargin.m] $m add -type radiobutton -text [.g cget -rightmargin] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "10" $m add -type radiobutton -text ".25i" $m add -type radiobutton -text ".5i" $m add -type radiobutton -text "1.0i" $m add -type radiobutton -text "2.0i" $m item configure all -variable graphd(-rightmargin) \ -command { .g configure -rightmargin $graphd(-rightmargin) } blt::tk::label $t.topmargin_l -text "-topmargin" blt::combobutton $t.topmargin -textvariable graphd(-topmargin) \ -menu $t.topmargin.m set m [blt::combomenu $t.topmargin.m] $m add -type radiobutton -text [.g cget -topmargin] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "10" $m add -type radiobutton -text ".25i" $m add -type radiobutton -text ".5i" $m add -type radiobutton -text "1.0i" $m add -type radiobutton -text "2.0i" $m item configure all -variable graphd(-topmargin) \ -command { .g configure -topmargin $graphd(-topmargin) } blt::tk::label $t.bottommargin_l -text "-bottommargin" blt::combobutton $t.bottommargin -textvariable graphd(-bottommargin) \ -menu $t.bottommargin.m set m [blt::combomenu $t.bottommargin.m] $m add -type radiobutton -text [.g cget -bottommargin] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "10" $m add -type radiobutton -text ".25i" $m add -type radiobutton -text ".5i" $m add -type radiobutton -text "1.0i" $m add -type radiobutton -text "2.0i" $m item configure all -variable graphd(-bottommargin) \ -command { .g configure -bottommargin $graphd(-bottommargin) } foreach option { borderwidth plotrelief relief background plotbackground background plotborderwidth plotpadx plotpady plotwidth plotheight width height title rightmargin leftmargin topmargin bottommargin } { $t.$option.m select 0 } blt::table $t \ 1,0 $t.background_l -anchor e \ 1,1 $t.background -fill x \ 2,0 $t.borderwidth_l -anchor e \ 2,1 $t.borderwidth -fill x \ 3,0 $t.bottommargin_l -anchor e \ 3,1 $t.bottommargin -fill x \ 4,0 $t.height_l -anchor e \ 4,1 $t.height -fill x \ 5,0 $t.leftmargin_l -anchor e \ 5,1 $t.leftmargin -fill x \ 6,0 $t.plotbackground_l -anchor e \ 6,1 $t.plotbackground -fill x \ 7,0 $t.plotborderwidth_l -anchor e \ 7,1 $t.plotborderwidth -fill x \ 8,0 $t.plotheight_l -anchor e \ 8,1 $t.plotheight -fill x \ 9,0 $t.plotpadx_l -anchor e \ 9,1 $t.plotpadx -fill x \ 10,0 $t.plotpady_l -anchor e \ 10,1 $t.plotpady -fill x \ 11,0 $t.plotrelief_l -anchor e \ 11,1 $t.plotrelief -fill x \ 12,0 $t.plotwidth_l -anchor e \ 12,1 $t.plotwidth -fill x \ 13,0 $t.relief_l -anchor e \ 13,1 $t.relief -fill x \ 14,0 $t.rightmargin_l -anchor e \ 14,1 $t.rightmargin -fill x \ 15,0 $t.title_l -anchor e \ 15,1 $t.title -fill x \ 16,0 $t.topmargin_l -anchor e \ 16,1 $t.topmargin -fill x \ 17,0 $t.width_l -anchor e \ 17,1 $t.width -fill x } proc LegendOptions { w } { global legend $w insert end "Legend" set t [frame $w.legend] $w tab configure "Legend" -window $w.legend blt::tk::label $t.selectborderwidth_l -text "-selectborderwidth" blt::combobutton $t.selectborderwidth -textvariable legend(-selectborderwidth) \ -menu $t.selectborderwidth.m set m [blt::combomenu $t.selectborderwidth.m] $m add -type radiobutton -text [.g legend cget -selectborderwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable legend(-selectborderwidth) \ -command { .g legend configure -selectborderwidth $legend(-selectborderwidth) } blt::tk::label $t.borderwidth_l -text "-borderwidth" blt::combobutton $t.borderwidth -textvariable legend(-borderwidth) \ -menu $t.borderwidth.m set m [blt::combomenu $t.borderwidth.m] $m add -type radiobutton -text [.g legend cget -borderwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable legend(-borderwidth) \ -command { .g legend configure -borderwidth $legend(-borderwidth) } blt::tk::label $t.pady_l -text "-pady" blt::combobutton $t.pady -textvariable legend(-pady) \ -menu $t.pady.m set m [blt::combomenu $t.pady.m] $m add -type radiobutton -text [.g legend cget -pady] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable legend(-pady) \ -command { .g legend configure -pady $legend(-pady) } blt::tk::label $t.padx_l -text "-padx" blt::combobutton $t.padx -textvariable legend(-padx) \ -menu $t.padx.m set m [blt::combomenu $t.padx.m] $m add -type radiobutton -text [.g legend cget -padx] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable legend(-padx) \ -command { .g legend configure -padx $legend(-padx) } blt::tk::label $t.selectrelief_l -text "-selectrelief" blt::combobutton $t.selectrelief -textvariable legend(-selectrelief) \ -menu $t.selectrelief.m set m [blt::combomenu $t.selectrelief.m] $m add -type radiobutton -text [.g legend cget -selectrelief] $m add -type separator $m add -type radiobutton -text "flat" $m add -type radiobutton -text "groove" $m add -type radiobutton -text "raised" $m add -type radiobutton -text "ridge" $m add -type radiobutton -text "solid" $m add -type radiobutton -text "sunken" $m item configure all -variable legend(-selectrelief) \ -command { .g legend configure -selectrelief $legend(-selectrelief) } blt::tk::label $t.relief_l -text "-relief" blt::combobutton $t.relief -textvariable legend(-relief) \ -menu $t.relief.m set m [blt::combomenu $t.relief.m] $m add -type radiobutton -text [.g legend cget -relief] $m add -type separator $m add -type radiobutton -text "flat" $m add -type radiobutton -text "groove" $m add -type radiobutton -text "raised" $m add -type radiobutton -text "ridge" $m add -type radiobutton -text "solid" $m add -type radiobutton -text "sunken" $m item configure all -variable legend(-relief) \ -command { .g legend configure -relief $legend(-relief) } blt::tk::label $t.position_l -text "-position" blt::combobutton $t.position -textvariable legend(-position) \ -menu $t.position.m set m [blt::combomenu $t.position.m] $m add -type radiobutton -text [.g legend cget -position] $m add -type separator $m add -type radiobutton -text "left" $m add -type radiobutton -text "right" $m add -type radiobutton -text "top" $m add -type radiobutton -text "bottom" $m add -type radiobutton -text "plotarea" $m add -type radiobutton -text "@200,200" $m item configure all -variable legend(-position) \ -command { .g legend configure -position $legend(-position) } blt::tk::label $t.hide_l -text "-hide" blt::combobutton $t.hide -textvariable legend(-hide) \ -menu $t.hide.m set m [blt::combomenu $t.hide.m] $m add -type radiobutton -text [.g legend cget -hide] $m add -type separator $m add -type radiobutton -text "yes" $m add -type radiobutton -text "no" $m item configure all -variable legend(-hide) \ -command { .g legend configure -hide $legend(-hide) } blt::tk::label $t.activebackground_l -text "-activebackground" blt::combobutton $t.activebackground -textvariable legend(-activebackground) \ -menu $t.activebackground.m set m [blt::combomenu $t.activebackground.m] $m add -type radiobutton -text [.g legend cget -activebackground] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable legend(-activebackground) \ -command { .g legend configure -activebackground $legend(-activebackground) } blt::tk::label $t.activeborderwidth_l -text "-activeborderwidth" blt::combobutton $t.activeborderwidth -textvariable legend(-activeborderwidth) \ -menu $t.activeborderwidth.m set m [blt::combomenu $t.activeborderwidth.m] $m add -type radiobutton -text [.g legend cget -activeborderwidth] $m add -type separator $m add -type radiobutton -text "0" $m add -type radiobutton -text "1" $m add -type radiobutton -text "2" $m add -type radiobutton -text "3" $m add -type radiobutton -text "4" $m add -type radiobutton -text "10" $m item configure all -variable legend(-activeborderwidth) \ -command { .g legend configure -activeborderwidth $legend(-activeborderwidth) } blt::tk::label $t.selectbackground_l -text "-selectbackground" blt::combobutton $t.selectbackground -textvariable legend(-selectbackground) \ -menu $t.selectbackground.m set m [blt::combomenu $t.selectbackground.m] $m add -type radiobutton -text [.g legend cget -selectbackground] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable legend(-selectbackground) \ -command { .g legend configure -selectbackground $legend(-selectbackground) } blt::tk::label $t.selectforeground_l -text "-selectforeground" blt::combobutton $t.selectforeground -textvariable legend(-selectforeground) \ -menu $t.selectforeground.m set m [blt::combomenu $t.selectforeground.m] $m add -type radiobutton -text [.g legend cget -selectforeground] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable legend(-selectforeground) \ -command { .g legend configure -selectforeground $legend(-selectforeground) } blt::tk::label $t.background_l -text "-background" blt::combobutton $t.background -textvariable legend(-background) \ -menu $t.background.m set m [blt::combomenu $t.background.m] $m add -type radiobutton -text [.g legend cget -background] $m add -type separator $m add -type radiobutton -text "black" $m add -type radiobutton -text "blue" $m add -type radiobutton -text "green" $m add -type radiobutton -text "grey" $m add -type radiobutton -text "red" $m add -type radiobutton -text "white" $m add -type radiobutton -text "yellow" $m item configure all -variable legend(-background) \ -command { .g legend configure -background $legend(-background) } puts stderr [$m item configure "black"] foreach option { borderwidth selectrelief relief selectbackground background selectborderwidth padx pady selectforeground activebackground position hide activeborderwidth } { $t.$option.m select 0 } blt::table $t \ 1,0 $t.activebackground_l -anchor e \ 1,1 $t.activebackground -fill x \ 2,0 $t.activeborderwidth_l -anchor e \ 2,1 $t.activeborderwidth -fill x \ 3,0 $t.background_l -anchor e \ 3,1 $t.background -fill x \ 4,0 $t.borderwidth_l -anchor e \ 4,1 $t.borderwidth -fill x \ 5,0 $t.hide_l -anchor e \ 5,1 $t.hide -fill x \ 6,0 $t.padx_l -anchor e \ 6,1 $t.padx -fill x \ 7,0 $t.pady_l -anchor e \ 7,1 $t.pady -fill x \ 8,0 $t.position_l -anchor e \ 8,1 $t.position -fill x \ 9,0 $t.relief_l -anchor e \ 9,1 $t.relief -fill x \ 10,0 $t.selectbackground_l -anchor e \ 10,1 $t.selectbackground -fill x \ 11,0 $t.selectborderwidth_l -anchor e \ 11,1 $t.selectborderwidth -fill x \ 12,0 $t.selectforeground_l -anchor e \ 12,1 $t.selectforeground -fill x \ 13,0 $t.selectrelief_l -anchor e \ 13,1 $t.selectrelief -fill x } set t [toplevel .cntrl] blt::tabnotebook $t.tb blt::table $t \ 0,0 $t.tb -fill both GraphOptions $t.tb AxisOptions $t.tb LegendOptions $t.tb ��������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/paneset2.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000542�11462120062�015573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT source scripts/demo.tcl blt::paneset .ps -height 900 \ -orient vertical blt::graph .ps.g blt::barchart .ps.b blt::barchart .ps.b2 .ps add -window .ps.g -fill both .ps add -window .ps.b -fill both .ps add -window .ps.b2 -fill both focus .ps blt::table . \ 0,0 .ps -fill both blt::table configure . r1 -resize none ��������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/dragdrop1.tcl���������������������������������������������������������������0000755�0001750�0001750�00000010456�11462120062�015745� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl if { ([info exists tcl_platform]) && ($tcl_platform(platform) == "windows") } { source scripts/send.tcl SendInit SendVerify } # ---------------------------------------------------------------------- # This procedure is invoked each time a token is grabbed from the # sample window. It configures the token to display the current # color, and returns the color value that is later passed to the # target handler. # ---------------------------------------------------------------------- proc package_color {token} { set bg [.sample cget -background] set fg [.sample cget -foreground] $token.label configure -background $bg -foreground $fg return $bg } # ---------------------------------------------------------------------- # Main application window... # ---------------------------------------------------------------------- label .sample -text "Color" -height 2 -bd 10 -relief sunken # # Set up the color sample as a drag&drop source for "color" values: # drag&drop source .sample \ -packagecmd {package_color %t} \ -sitecmd { puts "%s %t" } drag&drop source .sample handler color # # Set up the color sample as a drag&drop target for "color" values: # drag&drop target .sample handler color {set_color %v} # # Establish the appearance of the token window: # set token [drag&drop token .sample] label $token.label -text "Color" pack $token.label scale .redScale -label "Red" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .redSample -width 20 -height 20 -borderwidth 3 -relief sunken scale .greenScale -label "Green" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .greenSample -width 20 -height 20 -borderwidth 3 -relief sunken scale .blueScale -label "Blue" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .blueSample -width 20 -height 20 -borderwidth 3 -relief sunken # ---------------------------------------------------------------------- # This procedure loads a new color value into this editor. # ---------------------------------------------------------------------- proc set_color {cval} { set rgb [winfo rgb . $cval] set rval [expr round([lindex $rgb 0]/65535.0*255)] .redScale set $rval set gval [expr round([lindex $rgb 1]/65535.0*255)] .greenScale set $gval set bval [expr round([lindex $rgb 2]/65535.0*255)] .blueScale set $bval } # ---------------------------------------------------------------------- # This procedure is invoked whenever an RGB slider changes to # update the color samples in this display. # ---------------------------------------------------------------------- proc adjust_color {args} { set rval [.redScale get] .redSample configure -background [format "#%.2x0000" $rval] set gval [.greenScale get] .greenSample configure -background [format "#00%.2x00" $gval] set bval [.blueScale get] .blueSample configure -background [format "#0000%.2x" $bval] .sample configure -background \ [format "#%.2x%.2x%.2x" $rval $gval $bval] if {$rval+$gval+$bval < 1.5*255} { .sample configure -foreground white } else { .sample configure -foreground black } } blt::table . .sample 0,0 -columnspan 2 -fill both -pady {0 4} blt::table . .redScale 1,0 -fill both blt::table . .redSample 1,1 -fill both blt::table . .greenScale 2,0 -fill both blt::table . .greenSample 2,1 -fill both blt::table . .blueScale 3,0 -fill both blt::table . .blueSample 3,1 -fill both ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop9.tcl������������������������������������������������������������������0000644�0001750�0001750�00000000641�11462120062�015277� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl # -fontfile /usr/share/fonts/100dpi/helvR18.pcf.gz set img [image create picture -width 500 -height 500] $img draw rectangle 100 100 111 111 -color blue $img draw text "This is a test\nzxcVAbnm<//gqy" 100 100 \ -rotate 0 \ -kerning 1 \ -font { "arial" 24 bold } \ -color 0x7FFFFFFF label .l -image $img blt::table . \ 0,0 .l �����������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/picture4.tcl����������������������������������������������������������������0000644�0001750�0001750�00000001076�11462120062�015614� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set s1 [image create picture -width 25 -height 25] $s1 blank 0x00000000 $s1 draw circle 12 12 5 -shadow 0 -linewidth 1 \ -fill 0x90FF0000 -antialias yes set bg [image create picture -width 600 -height 600] $bg blank white set n 500000 puts stderr [time { blt::vector create points($n) points expr { round(random(points) * 512) + 30 } }] puts stderr [time { foreach {x y} [points print] { $bg copy $s1 -to "$x $y" -blend yes #$bg draw circle $x $y 30 -shadow 0 -linewidth 2 \ -fill 0x90FF0000 -antialias no } }] label .l -image $bg pack .l ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/dragdrop2.tcl���������������������������������������������������������������0000755�0001750�0001750�00000011630�11462120062�015741� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl if { ([info exists tcl_platform]) && ($tcl_platform(platform) == "windows") } { source scripts/send.tcl SendInit SendVerify } # ---------------------------------------------------------------------- # This procedure is invoked each time a token is grabbed from the # sample window. It configures the token to display the current # color, and returns the color value that is later passed to the # target handler. # ---------------------------------------------------------------------- proc package_color {token} { set bg [.sample cget -background] set fg [.sample cget -foreground] $token.label configure -text "Color" -background $bg -foreground $fg return $bg } # ---------------------------------------------------------------------- # This procedure is invoked each time a token is grabbed from an # entry widget. It configures the token to display the current # string, and returns the string that is later passed to the target # handler. # ---------------------------------------------------------------------- proc package_string {str token} { if {[string length $str] > 20} { set mesg "[string range $str 0 19]..." } else { set mesg $str } $token.label configure -text $mesg return $str } # ---------------------------------------------------------------------- # Main application window... # ---------------------------------------------------------------------- label .sample -text "Color" -height 2 -borderwidth 3 -relief sunken # # Set up the color sample as a drag&drop source for "color" values # and "string" values # drag&drop source .sample -packagecmd {package_color %t} drag&drop source .sample handler color drag&drop source .sample handler string # # Set up the color sample as a drag&drop target for "color" values: # drag&drop target .sample handler color {set_color %v} # # Establish the appearance of the token window: # set token [drag&drop token .sample -activebackground yellow ] label $token.label -text "Color" pack $token.label scale .redScale -label "Red" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .redSample -width 20 -height 20 -borderwidth 3 -relief sunken scale .greenScale -label "Green" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .greenSample -width 20 -height 20 -borderwidth 3 -relief sunken scale .blueScale -label "Blue" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .blueSample -width 20 -height 20 -borderwidth 3 -relief sunken frame .color label .color.label -text "Color:" pack .color.label -side left entry .color.value -width 10 pack .color.value -side left -expand yes -fill both bind .color.value <KeyPress-Return> {set_color [%W get]} # # Set up the entry widget as a drag&drop source for "string" values: # drag&drop source .color.value \ -packagecmd {package_string [%W get] %t} \ -selftarget yes drag&drop source .color.value handler string # # Set up the entry widget as a drag&drop target for "string" values: # drag&drop target .color.value handler string { %W delete 0 end %W insert 0 "%v" } # # Establish the appearance of the token window: # set token [drag&drop token .color.value] label $token.label pack $token.label # ---------------------------------------------------------------------- # This procedure loads a new color value into this editor. # ---------------------------------------------------------------------- proc set_color {cval} { set rgb [winfo rgb . $cval] set rval [expr round([lindex $rgb 0]/65535.0*255)] .redScale set $rval set gval [expr round([lindex $rgb 1]/65535.0*255)] .greenScale set $gval set bval [expr round([lindex $rgb 2]/65535.0*255)] .blueScale set $bval } # ---------------------------------------------------------------------- # This procedure is invoked whenever an RGB slider changes to # update the color samples in this display. # ---------------------------------------------------------------------- proc adjust_color {args} { set rval [.redScale get] .redSample configure -background [format "#%.2x0000" $rval] set gval [.greenScale get] .greenSample configure -background [format "#00%.2x00" $gval] set bval [.blueScale get] .blueSample configure -background [format "#0000%.2x" $bval] .sample configure -background \ [format "#%.2x%.2x%.2x" $rval $gval $bval] if {$rval+$gval+$bval < 1.5*255} { .sample configure -foreground white } else { .sample configure -foreground black } } blt::table . \ 0,0 .sample -columnspan 2 -pady {0 4} \ 1,0 .color -columnspan 2 -padx 4 -pady 4 \ 2,0 .redScale \ 2,1 .redSample \ 3,0 .greenScale \ 3,1 .greenSample \ 4,0 .blueScale \ 4,1 .blueSample eval blt::table configure . [winfo children .] -fill both ��������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu4.tcl������������������������������������������������������������������0000644�0001750�0001750�00000002151�11462120062�015243� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT blt::tk::button .quit -command exit -text "Quit" blt::tk::button .cancel -command exit -text "Cancel" blt::tk::button .cont -command exit -text "Continue" blt::combomenu .m \ -textvariable myText1 \ -iconvariable myIcon1 \ -background grey90 \ -relief raised \ -font "arial 9" set image1 [image create picture -file ~/neeshub/indeed/src/icons/sensor/hidden/user.png] set image2 [image create picture -file ~/neeshub/indeed/src/icons/sensor/user.png] set image3 [image create picture -width 20 -height 20] $image3 copy $image1 -from "0 0 11 20" $image3 copy $image2 -from "10 0 20 20" -to "10 0" .m add -text "Hide" -accel "Ctrl-H" \ -command "puts hide" -underline 0 -icon $image1 .m add -text "Show" -accel "Ctrl-S" \ -command "puts show" -underline 0 -icon $image2 .m add -text "Toggle" -accel "Ctrl-T" \ -command "puts toggle" -underline 0 proc Post { x y } { puts stderr "posting menu..." blt::ComboMenu::popup .m $x $y } bind all <ButtonPress-3> { Post %X %Y } blt::table . \ 0,0 .cont -pady 10 \ 0,1 .quit -pady 10 \ 0,2 .cancel -pady 10 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/ctree2.tcl������������������������������������������������������������������0000644�0001750�0001750�00000001702�11462120062�015235� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� proc find { tree parent dir } { global count set saved [pwd] cd $dir foreach f [glob -nocomplain *] { set name [file tail $f] if { [file type $f] == "directory" } { set node [$tree insert $parent -label $name] find $tree $node $f } } cd $saved } set tree [blt::tree create] set path ../.. find $tree root $path $tree label root [file normalize $path] if { [file exists ../library] } { set blt_library ../library } puts [$tree label 0] # -postcommand {.e.m configure -width [winfo width .e] ; update} \ set myIcon "" blt::combobutton .b \ -text "Select Directory" \ -command "puts {button pressed}" \ -font { arial 10 bold } \ -menu .b.m blt::combotree .b.m \ -tree $tree \ -borderwidth 1 \ -font { arial 10 } \ -separator / \ -yscrollbar .b.m.ybar \ -xscrollbar .b.m.xbar blt::tk::scrollbar .b.m.xbar blt::tk::scrollbar .b.m.ybar focus .b blt::table . \ .b -fill x ��������������������������������������������������������������./saods9/blt3.0.1/demos/graph2.tcl������������������������������������������������������������������0000755�0001750�0001750�00000006507�11462120062�015247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl source scripts/stipples.tcl if { ![string match "*gray*" [winfo screenvisual .]] } { option add *Button.Background red option add *TextMarker.Foreground black option add *TextMarker.Background yellow option add *LineMarker.Foreground black option add *LineMarker.Background yellow option add *PolyMarker.Fill yellow2 option add *PolyMarker.Outline "" option add *PolyMarker.Stipple bdiagonal1 option add *activeLine.Color red4 option add *activeLine.Fill red2 option add *Element.Color purple } set data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== } set image [image create picture -data $data] set graph [blt::graph .g] blt::table . \ 0,0 $graph -fill both source scripts/graph2.tcl $graph postscript configure \ -landscape yes $graph configure \ -width 6i \ -height 4i \ -title "Graph" \ -plotpady 0 -plotpadx 0 -plotborderwidth 0 $graph axis configure y \ -titlefont "arial 10" \ -title "Y Axis" if 1 { set bg [blt::bgpattern create gradient -low grey40 -high grey95 \ -jitter yes -log no -opacity 80] $graph element configure line1 # -areapattern solid -areaforeground green # -areatile $image $graph element configure line3 \ -areaforeground red \ -areabackground $bg } if 0 { set fileName testImg.jpg if { [file exists $fileName] } { set image [image create picture -file $fileName] if 1 { puts stderr [time { $graph marker create image -image $image -resamplefilter sinc \ -coords "-360.0 -1.0 360.0 1.0" \ -under yes \ -mapx degrees \ -name $fileName }] } } } bind $graph <Control-ButtonPress-3> { MakeSnapshot } bind $graph <Shift-ButtonPress-3> { %W postscript output demo2.ps update %W snap -format emf demo2.emf } $graph configure -title "This is the \nTitle\n" set unique 0 proc MakeSnapshot {} { update idletasks global unique graph set top ".snapshot[incr unique]" set im [image create photo] $graph snap $im 210 150 toplevel $top wm title $top "Snapshot \#$unique of \"[$graph cget -title]\"" label $top.lab -image $im button $top.but -text "Dismiss" -command "DestroySnapshot $top" blt::table $top $top.lab blt::table $top $top.but -pady 4 focus $top.but } proc DestroySnapshot { win } { set im [$win.lab cget -image] image delete $im destroy $win exit } if { $tcl_platform(platform) == "windows" } { if 0 { set name [lindex [blt::printer names] 0] set printer {Lexmark Optra E310} blt::printer open $printer blt::printer getattrs $printer attrs puts $attrs(Orientation) set attrs(Orientation) Landscape set attrs(DocumentName) "This is my print job" blt::printer setattrs $printer attrs blt::printer getattrs $printer attrs puts $attrs(Orientation) after 5000 { $graph print2 $printer blt::printer close $printer } } else { after 5000 { # $graph print2 } } if 1 { after 2000 {$graph snap -format emf CLIPBOARD} } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tv1.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000001621�11462120062�014563� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT package require Tk set paned [panedwindow .panedwindow] set a [frame $paned.a -bg red] set tree [::blt::treeview $a.tree\ -relief flat\ -selectmode single\ -exportselection false] $tree configure -yscrollcommand "$a.y set" -xscrollcommand "$a.x set" scrollbar $a.y -command "$tree yview" scrollbar $a.x -command "$tree xview" -orient horizontal grid $tree -row 0 -column 1 -sticky nsew grid $a.y -row 0 -column 2 -sticky ns grid $a.x -row 1 -column 1 -sticky we grid columnconfigure $a 1 -weight 1 grid rowconfigure $a 0 -weight 1 $tree column configure treeView -width 0 $tree insert end hola -label hola pack $paned -fill both -expand true $tree configure -width 0 set m [frame $paned.m -bg yellow] $paned add $a $paned add $m update ::update idletasks $paned sash place 0 180 1 puts [$tree configure -width] puts [winfo geometry $tree] puts [$paned configure] ���������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph5.tcl������������������������������������������������������������������0000755�0001750�0001750�00000003436�11462120062�015250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl option add *Element.ScaleSymbols true option add *Axis.loose true option add *Pixels .8c option add *Element.lineWidth 0 option add *Legend.ActiveRelief raised option add *Legend.padY 0 option add *Button*Font { Arial 14 } widgetDefault option add *Legend*Font { Arial 14 bold } widgetDefault option add *Graph.Font { Arial 18 bold } widgetDefault option add *Graph.title "Element Symbol Types" option add *Graph.width 8i option add *Graph.height 6i option add *Graph.plotPadY .25i option add *Graph.plotPadX .25i set graph .graph blt::graph $graph blt::vector x -variable "" x set { 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 } for { set i 0 } { $i < 11 } { incr i } { set vecName "y${i}" blt::vector ${vecName} $vecName length 11 $vecName variable y set y(:) [expr $i*100.0] } set attributes { none "None" red red4 y0 arrow "Arrow" brown brown4 y10 circle "Circle" yellow yellow4 y2 cross "Cross" cyan cyan4 y6 diamond "Diamond" green green4 y3 plus "Plus" magenta magenta4 y9 splus "Splus" Purple purple4 y7 scross "Scross" red red4 y8 square "Square" orange orange4 y1 triangle "Triangle" blue blue4 y4 "@bitmaps/hobbes.xbm @bitmaps/hobbes_mask.xbm" "Bitmap" yellow black y5 } set count 0 foreach {symbol label fill color yVec} $attributes { $graph element create line${count} \ -label $label -symbol $symbol -color $color -fill $fill -x x -y $yVec incr count } $graph element configure line0 -dashes { 2 4 2 } -linewidth 2 button .quit -text Quit -command exit blt::table . \ $graph 0,0 -fill both \ .quit 1,0 -fill x Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph Blt_PrintKey $graph ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hierbox3.tcl����������������������������������������������������������������0000755�0001750�0001750�00000002705�11462120062�015603� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc AddDirEntries { w dir } { if { [file isdirectory $dir] } { set files [glob -nocomplain $dir/*] eval $w insert end [lsort $files] set subdirs [glob -nocomplain $dir/*/] eval $w entry configure [lsort $subdirs] -button yes } } set imageList {} foreach f [glob ./images/mini-*.gif] { lappend imageList [image create picture -file $f] } image create picture openFolder -file images/open.gif image create picture closeFolder -file images/close.gif option add *Hierbox.icons "closeFolder openFolder" #option add *Hierbox.openCommand { AddDirEntries %W "$top/%P" } #option add *Hierbox.closeCommand { eval %W delete %n 0 end } hierbox .h \ -allowduplicates no \ -hideroot yes \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } button .test -text Test -command { set index [.h curselection] set names [eval .h get -full $index] puts "selected names are $names" } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x \ blt::table configure . c1 r1 r2 -resize none set top ../ .h configure -separator "/" -trim $top -autocreate yes #.h entry configure 0 -label [file tail $top] catch { exec du $top } files foreach f [split $files \n ] { .h insert end [lindex $f 1] -text [lindex $f 0] -button auto } focus .h �����������������������������������������������������������./saods9/blt3.0.1/demos/paneset6.tcl����������������������������������������������������������������0000644�0001750�0001750�00000004052�11462120062�015577� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl set pictures [glob -nocomplain "*.jpg"] set autocolors { #0000cd #cd0000 #00cd00 #3a5fcd #cdcd00 #cd1076 #009acd #00c5cd #a2b5cd #7ac5cd #66cdaa #a2cd5a #cd9b9b #cdba96 #cd3333 #cd6600 #cd8c95 #cd00cd #9a32cd #6ca6cd #9ac0cd #9bcd9b #00cd66 #cdc673 #cdad00 #cd5555 #cd853f #cd7054 #cd5b45 #cd6889 #cd69c9 #551a8b } proc Move { w pane } { # puts stderr "w=$w pane=$pane" .ps see $pane } blt::filmstrip .ps -bg grey -width 600 -scrollcommand { .s set } \ -sashthickness 3 -handlepad 1 -handleborderwidth 2 \ -activehandlerelief raised -handlerelief flat #-scrolldelay 10 -scrollincrement 10 for { set i 0 } { $i < 32 } { incr i } { set color [lindex $autocolors $i] blt::graph .ps.g$i -bg $color -width 500 set pane [.ps add -window .ps.g$i -fill both] bind .ps.g$i <ButtonPress-1> [list Move %W $pane] bind .ps.g$i <ButtonPress-2> [list Move %W pane0] bind .ps.g$i <ButtonPress-3> [list Move %W pane35] } blt::tk::scrollbar .s -command { .ps view } -orient horizontal set pressed 0 bind PanesetHandle <Enter> { %W activate } bind PanesetHandle <Leave> { if { !$pressed } { %W deactivate } } bind PanesetHandle <KeyPress-Left> { %W move -10 0 } bind PanesetHandle <KeyPress-Right> { %W move 10 0 } bind PanesetHandle <KeyPress-Up> { %W move 0 -10 } bind PanesetHandle <KeyPress-Down> { %W move 0 10 } bind PanesetHandle <Shift-KeyPress-Left> { %W move -100 0 } bind PanesetHandle <Shift-KeyPress-Right> { %W move 100 0 } bind PanesetHandle <Shift-KeyPress-Up> { %W move 0 -100 } bind PanesetHandle <Shift-KeyPress-Down> { %W move 0 100 } bind PanesetHandle <ButtonPress-1> { set pressed 1 %W anchor %X %Y focus %W } bind PanesetHandle <B1-Motion> { %W mark %X %Y } bind PanesetHandle <ButtonRelease-1> { set pressed 0 %W set %X %Y } blt::table . \ 0,0 .ps -fill both \ 1,0 .s -fill x blt::table configure . r1 -resize none focus .ps after 5000 { #.ps pane configure 1 -size { 0 10000 10 } focus . #.ps see pane2 #.ps size pane2 1i } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabset2.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000002443�11462120062�015423� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl image create picture bgTile -file ./images/smblue_rock.gif image create picture label1 -file ./images/mini-book1.gif image create picture label2 -file page-zoom.png image create picture testImage -file ./images/txtrflag.gif blt::tk::scrollbar .s -command { .t view } -orient horizontal blt::tabset .t \ -outerrelief flat \ -font "Arial 8" \ -outerborderwidth 2 \ -textside right \ -tabwidth same \ -tiers 2 \ -scrollcommand { .s set } \ -scrollincrement 1 -selectforeground green2 blt::tk::label .t.l -image testImage set attributes { graph1 "Graph \#1" red .t.graph1 graph2 "Graph \#2" green .t.graph2 graph3 "Graph \#3" cyan .t.graph3 graph5 "Graph \#5" yellow .t.graph5 graph6 one orange .t.l } foreach { entry label color window } $attributes { .t insert end $entry -text $label -fill both } foreach page { there bunky another test of a widget } { .t insert end $page -image label2 } blt::table . \ .t 0,0 -fill both \ .s 1,0 -fill x blt::table configure . r1 -resize none foreach file { graph1 graph2 graph3 graph5 } { namespace eval $file { set graph [blt::graph .t.$file] source scripts/$file.tcl .t tab configure $file -window $graph } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hierbox4.tcl����������������������������������������������������������������0000755�0001750�0001750�00000002667�11462120062�015613� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc AddDirEntries { w dir } { if { [file isdirectory $dir] } { set files [glob -nocomplain $dir/*] eval $w insert end [lsort $files] set subdirs [glob -nocomplain $dir/*/] eval $w entry configure [lsort $subdirs] -gadget yes } } #blt::bltdebug 100 image create picture openFolder -file images/open.gif image create picture closeFolder -file images/close.gif option add *Hierbox.icons "closeFolder openFolder" option add *Hierbox.cursor crosshair option add *Hierbox.Button.Relief solid option add *Hierbox.Button.ActiveBackground white option add *Hierbox.Button.Background white hierbox .h \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -activebackground lightskyblue1 \ -selectbackground lightskyblue2 scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } button .test -text Test -command { set index [.h curselection] set names [eval .h get -full $index] puts "selected names are $names" } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x \ 2,0 .test blt::table configure . c1 r1 -resize none .h configure -autocreate yes -font { Helvetica 34 } focus .h .h insert end { The Quick Brown Fox Jumped Over the } .h entry configure root -label {[Root]} .h insert end { The\nQuick\nBrown\nFox\nJumped\nOver\nthe } .h configure -focusedit yes �������������������������������������������������������������������������./saods9/blt3.0.1/demos/bgexec5.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000002351�11462120062�015377� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl set shell bltwish if { [info exists tcl_platform] && $tcl_platform(platform) == "windows" } { set shell "$shell.exe" } if { [file executable "../src/$shell"] } { set shell "../src/$shell" } set count 0 foreach demo [glob barchart?.tcl] { bgexec var $shell $demo & } button .kill -text "Kill All" -command { set var 0 } blt::table . .kill -fill both ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/paneset5.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000531�11462120062�015574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::paneset .ps -height 900 -orient vertical blt::graph .ps.g blt::barchart .ps.b blt::barchart .ps.b2 .ps add -window .ps.g -fill both .ps add -window .ps.b -fill both .ps add -window .ps.b2 -fill both focus .ps blt::table . \ 0,0 .ps -fill both blt::table configure . r1 -resize none �����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph4a.tcl�����������������������������������������������������������������0000644�0001750�0001750�00000013516�11462120062�015405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set tcl_precision 15 set graph .graph image create picture bgTexture -file ./images/chalk.gif option add *default normal option add *Button.tile bgTexture option add *Htext.font "Times 18 bold" option add *Text.font "Times 18 bold" option add *header.font "Times 12" option add *footer.font "Times 18" option add *Graph.relief raised #option add *Graph.borderWidth 2 #option add *Graph.Legend.activeBackground white option add *Graph.height 5i option add *Graph.plotBackground black option add *Graph.width 7i option add *Graph.tile bgTexture option add *Graph.halo 0 option add *Graph.title "s27.out" option add *Axis.titleColor red2 option add *x.title "Time" option add *y.title "Signals" option add *Crosshairs.Color white option add *activeLine.Fill navyblue option add *activeLine.LineWidth 2 option add *Element.ScaleSymbols yes option add *Element.Smooth natural option add *Symbol square option add *Element.LineWidth 1 option add *Pen.LineWidth 1 option add *Pixels 1 option add *Grid.color grey50 option add *Grid.dashes "2 4" option add *Grid.hide no option add *Legend.ActiveRelief sunken option add *Legend.Position right option add *Legend.Relief flat option add *Legend.font "Helvetica 6" option add *Legend.Pad 0 option add *Legend.hide no option add *LineMarker.Dashes 5 option add *LineMarker.Foreground white option add *zoomOutline.outline yellow option add *TextMarker.Background {} option add *TextMarker.Foreground white set table [blt::datatable create] $table restore -file graph4a.tab set attributes { V1 v1 red red V2 v2 green red V3 v3 blue red V4 v4 yellow red V5 v5 magenta red V6 v6 cyan red V7 v7 white red V8 v8 red green V9 v9 green green V10 v10 blue green V11 v11 yellow green V12 v12 magenta green V13 v13 cyan green V14 v14 red red V15 v15 green red V16 v16 blue red V17 v17 yellow red V18 v18 magenta red V19 v19 cyan red V20 v20 white red V21 v21 red green V22 v22 green green V23 v23 blue green V24 v24 yellow green V25 v25 magenta green V26 v26 cyan green V27 v27 red red V28 v28 green red V29 v29 blue red V30 v30 yellow red V31 v31 magenta red V32 v32 cyan red V33 v33 white red V34 v34 red green V35 v35 green green V36 v36 blue green V37 v37 yellow green V38 v38 magenta green V39 v39 cyan green } text .header -wrap word -width 0 -height 6 set text { To zoom in on a region of the graph, simply click once on the left mouse button to pick one corner of the area to be zoomed. Move the mouse to the other corner and click again. } regsub -all "\n" $text "" text .header insert end "$text\n" .header insert end { You can click on the } set im [image create picture -file ./images/qv100.t.gif] button .header.snap -image $im -command { MakeSnapshot } .header window create end -window .header.snap .header insert end { button to see a picture image snapshot.} .header configure -state disabled blt::graph $graph blt::htext .footer -text {Hit the %% set im [image create picture -file ./images/stopsign.gif] button $htext(widget).quit -image $im -command { exit } $htext(widget) append $htext(widget).quit %% button when you've seen enough. %% label $htext(widget).logo -bitmap BLT $htext(widget) append $htext(widget).logo %%} foreach {label yData outline color} $attributes { set xx [list $table "x"] set yy [list $table $yData] .graph element create $label -x $xx -y $yy -outline $outline -color $color } set unique 0 proc Sharpen { photo } { set kernel { -1 -1 -1 -1 16 -1 -1 -1 -1 } #set kernel { 0 -1 0 -1 4.9 -1 0 -1 0 } blt::winop convolve $photo $photo $kernel } proc MakeSnapshot {} { update idletasks global unique set top ".snapshot[incr unique]" set im1 [image create picture] .graph snap $im1 set width 210 set height 150 set thumb1 [image create picture -width $width -height $height -gamma 2.2] $thumb1 resize $im1 -filter sinc image delete $im1 set thumb2 [image create picture -window .graph -width $width \ -height $height -filter sinc -gamma 2.2 -aspect yes] toplevel $top wm title $top "Snapshot \#$unique of \"[.graph cget -title]\"" label $top.l1 -image $thumb1 label $top.l2 -image $thumb2 button $top.but -text "Dismiss" -command "DestroySnapshot $top" blt::table $top \ 0,0 $top.l1 \ 0,1 $top.l2 \ 1,0 $top.but -pady 4 focus $top.but } proc DestroySnapshot { win } { set im [$win.l1 cget -image] $im export jpg -file test.jpg image delete $im destroy $win } blt::table . \ .header 0,0 -fill x \ .graph 1,0 -fill both \ .footer 2,0 -fill x blt::table configure . r0 r2 -resize none Blt_ZoomStack $graph Blt_Crosshairs $graph #Blt_ActiveLegend $graph Blt_ClosestPoint $graph Blt_PrintKey $graph $graph element bind all <Enter> { %W legend activate [%W element get current] } $graph element bind all <Leave> { %W legend deactivate [%W element get current] } if 0 { $table column extend "x" $table import vector "x" 1 $table column type "x" double set col 1 foreach vector [lsort -dictionary [blt::vector names ::v*]] { set name [string trim $vector ::] $table column extend $name $table column type $name double incr col $table import vector $vector $col } $table dump -file graph4.tab } blt::LegendSelections $graph focus $graph toplevel .top update $graph legend configure \ -exportselection yes \ -selectbackground lightblue4 \ -selectforeground white \ -position .top.legend pack .top.legend -fill both -expand yes #-nofocusselectbackground grey90 # -nofocusselectforeground white ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/dnd1.tcl��������������������������������������������������������������������0000755�0001750�0001750�00000014713�11462120062�014710� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl if { ([info exists tcl_platform]) && ($tcl_platform(platform) == "windows") } { source scripts/send.tcl SendInit SendVerify } proc OnEnter { widget args } { array set info $args $widget configure -highlightbackground red return 1 } proc OnMotion { widget args } { puts stderr "OnMotion: args=$args" array set info $args set x1 [$widget cget -bd] set x1 20 set y1 $x1 set x2 [expr [winfo width $widget] - $x1] set y2 [expr [winfo height $widget] - $y1] if { ($info(x) >= $x1) && ($info(x) <= $x2) && ($info(y) >= $y1) && ($info(y) <= $y2) } { puts stderr "OnMotion: found args=$args" $widget configure -highlightbackground red -relief sunken -highlightthickness 10 return 1 } $widget configure -highlightbackground grey -relief raised return 0 } proc OnLeave { widget args } { $widget configure -highlightbackground grey return 0 } option add *OnEnter OnEnter option add *OnLeave OnLeave option add *OnMotion OnMotion # ---------------------------------------------------------------------- # This procedure is invoked each time a token is grabbed from the # sample window. It configures the token to display the current # color, and returns the color value that is later passed to the # target handler. # ---------------------------------------------------------------------- proc PackageSample { widget args } { array set info $args set bg [.sample cget -background] set fg [.sample cget -foreground] $info(token).label configure -background $bg -foreground $fg return 1 } proc ShowResult { widget args } { puts stderr args=$args array set info $args puts "drop transaction($info(timestamp)) completed: result was $info(action)" } # ---------------------------------------------------------------------- # Main application window... # ---------------------------------------------------------------------- image create picture openFolder -data { R0lGODdhEAAOAPIAAP///wAAAH9/f9nZ2f//AAAAAAAAAAAAACwAAAAAEAAOAAADOwgqzPoQ iDjjAoPkIZuTgCZykBCA2ziaXusRrFUGQ5zeRMCcE76xvJBPozuBVCmT0eUKGAHOqFQqqwIS ADs= } label .sample \ -text "Color" \ -height 12 \ -width 20 \ -bd 2 \ -relief raised \ -highlightthickness 2 set cursors { { @bitmaps/hand/hand01.xbm bitmaps/hand/hand01m.xbm black white } { @bitmaps/hand/hand02.xbm bitmaps/hand/hand02m.xbm black white } { @bitmaps/hand/hand03.xbm bitmaps/hand/hand03m.xbm black white } { @bitmaps/hand/hand04.xbm bitmaps/hand/hand04m.xbm black white } { @bitmaps/hand/hand05.xbm bitmaps/hand/hand05m.xbm black white } { @bitmaps/hand/hand06.xbm bitmaps/hand/hand06m.xbm black white } { @bitmaps/hand/hand07.xbm bitmaps/hand/hand07m.xbm black white } { @bitmaps/hand/hand08.xbm bitmaps/hand/hand08m.xbm black white } { @bitmaps/hand/hand09.xbm bitmaps/hand/hand09m.xbm black white } { @bitmaps/hand/hand10.xbm bitmaps/hand/hand10m.xbm black white } { @bitmaps/hand/hand11.xbm bitmaps/hand/hand11m.xbm black white } { @bitmaps/hand/hand12.xbm bitmaps/hand/hand12m.xbm black white } { @bitmaps/hand/hand13.xbm bitmaps/hand/hand13m.xbm black white } { @bitmaps/hand/hand14.xbm bitmaps/hand/hand14m.xbm black white } } # Set up the color sample as a drag&drop source and target for "color" values: blt::dnd register .sample \ -source yes \ -target yes \ -package PackageSample \ -result ShowResult \ -cursors $cursors blt::dnd getdata .sample color GetColor blt::dnd setdata .sample color SetColor # Establish the appearance of the token window: set token [blt::dnd token window .sample] label $token.label -text "Color" -bd 2 -highlightthickness 1 pack $token.label blt::dnd token configure .sample \ -borderwidth 2 \ -relief raised \ -activerelief raised \ -outline pink \ -fill red \ -anchor s if 1 { scale .redScale -label "Red" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .red -width 20 -height 20 -borderwidth 3 -relief sunken scale .greenScale -label "Green" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .green -width 20 -height 20 -borderwidth 3 -relief sunken scale .blueScale -label "Blue" -orient horizontal \ -from 0 -to 255 -command adjust_color frame .blue -width 20 -height 20 -borderwidth 3 -relief sunken # ---------------------------------------------------------------------- # This procedure loads a new color value into this editor. # ---------------------------------------------------------------------- proc GetColor { widget args } { return [$widget cget -bg] } proc SetColor { widget args } { array set info $args set rgb [winfo rgb . $info(value)] set r [lindex $rgb 0] set g [lindex $rgb 1] set b [lindex $rgb 2] .redScale set [expr round($r/65535.0 * 255)] .greenScale set [expr round($g/65535.0 * 255)] .blueScale set [expr round($b/65535.0 * 255)] } # ---------------------------------------------------------------------- # This procedure is invoked whenever an RGB slider changes to # update the color samples in this display. # ---------------------------------------------------------------------- proc adjust_color {args} { set rval [.redScale get] .red configure -background [format "#%.2x0000" $rval] set gval [.greenScale get] .green configure -background [format "#00%.2x00" $gval] set bval [.blueScale get] .blue configure -background [format "#0000%.2x" $bval] .sample configure -background \ [format "#%.2x%.2x%.2x" $rval $gval $bval] if {$rval+$gval+$bval < 1.5*255} { .sample configure -foreground white } else { .sample configure -foreground black } } blt::table . .redScale 1,0 -fill both blt::table . .red 1,1 -fill both blt::table . .greenScale 2,0 -fill both blt::table . .green 2,1 -fill both blt::table . .blueScale 3,0 -fill both blt::table . .blue 3,1 -fill both } blt::table . .sample 0,0 -columnspan 2 -fill both -pady {0 4} proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed [clock clicks] .redScale set [expr round([random 255.0])] .blueScale set [expr round([random 255.0])] .greenScale set [expr round([random 255.0])] bind .sample <KeyPress-Escape> { blt::dnd cancel .sample } focus .sample �����������������������������������������������������./saods9/blt3.0.1/demos/winop1.tcl������������������������������������������������������������������0000755�0001750�0001750�00000002614�11462120062�015274� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #set imgfile ./images/sample.gif set imgfile ./images/blt98.gif set imgfile ~/dstrange.xpm set imgfile ~/8.jpg set imgfile ~/250px-KittyPryde+Wolverine4.jpg set imgfile ~/thunderbird.png set imgfile ~/testfile.png if { [llength $argv] > 0 } { set imgfile [lindex $argv 0] } if { [ file exists $imgfile] } { set src [image create picture -file $imgfile] } else { puts stderr "no image file" exit 0 } set name [file root [file tail $imgfile]] set width [image width $src] set height [image height $src] option add *Label.font *helvetica*10* option add *Label.background white label .l0 -image $src label .header0 -text "$width x $height" label .footer0 -text "100%" . configure -bg white #$src quantize $src 150 set type gif set i 0 foreach scale { 0.8 0.6666666 0.5 0.4 0.3333333 0.3 0.25 0.2 0.15 0.1 } { incr i set iw [expr int($width * $scale)] set ih [expr int($height * $scale)] set r [format %6g [expr 100.0 * $scale]] image create picture r$i -width $iw -height $ih #puts stderr before=[r$i info] r$i resize $src -filter sinc #puts stderr after=[r$i info] r$i export $type -file ${name}-${scale}.$type #triangle #box label .header$i -text "$iw x $ih" label .footer$i -text "$r%" label .l$i -image r$i blt::table . \ 0,$i .header$i \ 1,$i .l$i \ 2,$i .footer$i update } ��������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/bitmap2.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000023164�11462120062�015420� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl source scripts/patterns.tcl source scripts/stipples.tcl blt::bitmap define hobbes { #define hobbes_width 25 #define hobbes_height 25 static char hobbes_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x78, 0xe0, 0x07, 0x00, 0xfc, 0xf8, 0x07, 0x00, 0xcc, 0x07, 0x04, 0x00, 0x0c, 0xf0, 0x0b, 0x00, 0x7c, 0x1c, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x10, 0x00, 0xe0, 0x41, 0x11, 0x00, 0x20, 0x40, 0x11, 0x00, 0xe0, 0x07, 0x10, 0x00, 0xe0, 0xc1, 0x17, 0x00, 0x10, 0xe0, 0x2f, 0x00, 0x20, 0xe0, 0x6f, 0x00, 0x18, 0xe0, 0x2f, 0x00, 0x20, 0xc6, 0x67, 0x00, 0x18, 0x84, 0x2b, 0x00, 0x20, 0x08, 0x64, 0x00, 0x70, 0xf0, 0x13, 0x00, 0x80, 0x01, 0x08, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } blt::bitmap define gort { #define gort_width 64 #define gort_height 64 static char gort_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x80, 0x01, 0x00, 0xc0, 0xdf, 0x0f, 0x1e, 0x00, 0x80, 0x01, 0x00, 0x60, 0xdf, 0x7f, 0x38, 0x00, 0x80, 0x01, 0x00, 0x30, 0x84, 0xfd, 0x67, 0x00, 0x80, 0x01, 0x00, 0x18, 0x04, 0xf6, 0xef, 0x00, 0x80, 0x01, 0x00, 0x0c, 0x86, 0xe1, 0xc7, 0x01, 0x80, 0x01, 0x00, 0x06, 0x06, 0xc0, 0x96, 0x01, 0x80, 0x01, 0x00, 0x06, 0x06, 0x00, 0x97, 0x03, 0x80, 0x01, 0x00, 0x06, 0x06, 0x00, 0x3c, 0x03, 0x80, 0x01, 0x00, 0x03, 0x06, 0x00, 0x5c, 0x07, 0x80, 0x01, 0x00, 0x03, 0x02, 0x00, 0xd8, 0x06, 0x80, 0x01, 0x00, 0x03, 0x02, 0x00, 0xd8, 0x06, 0x80, 0x01, 0x00, 0x43, 0x02, 0x00, 0xb0, 0x0c, 0x80, 0x01, 0x80, 0x31, 0x03, 0x00, 0xe0, 0x0d, 0x80, 0x01, 0x80, 0x61, 0x03, 0x00, 0xe0, 0x0d, 0x80, 0x01, 0x80, 0x1b, 0x03, 0x00, 0xf0, 0x0c, 0x80, 0x01, 0x80, 0xb3, 0x03, 0xff, 0xff, 0x1d, 0x80, 0x01, 0xc0, 0xeb, 0xfb, 0xff, 0xff, 0x1d, 0x80, 0x01, 0xe0, 0xc5, 0x7f, 0xfe, 0x7f, 0x3f, 0x01, 0xe0, 0xeb, 0xe3, 0xff, 0xff, 0x6e, 0x80, 0x01, 0xd0, 0x3b, 0xfe, 0x01, 0x80, 0x40, 0xcf, 0x80, 0x01, 0xf0, 0xf7, 0x07, 0x00, 0x30, 0x8e, 0x80, 0x01, 0xf0, 0xf4, 0x00, 0x00, 0x1b, 0x98, 0x80, 0x01, 0x70, 0x14, 0x00, 0x00, 0x1f, 0xdc, 0x80, 0x01, 0x30, 0xfe, 0xff, 0x1f, 0xc8, 0xff, 0x80, 0x01, 0x20, 0xee, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x20, 0xf7, 0xff, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0xc0, 0xe1, 0xff, 0xff, 0xfe, 0x3f, 0x80, 0x01, 0x80, 0xed, 0xff, 0xff, 0xff, 0x19, 0x80, 0x01, 0x80, 0x99, 0xff, 0xff, 0xff, 0x18, 0x80, 0x01, 0x00, 0x63, 0x83, 0xff, 0x7f, 0x08, 0x80, 0x01, 0x00, 0xc3, 0x06, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x9b, 0x07, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0xb6, 0x07, 0x00, 0x10, 0x0c, 0x80, 0x01, 0x00, 0xc6, 0x07, 0x00, 0x10, 0x04, 0x80, 0x01, 0x00, 0x36, 0x06, 0x00, 0x18, 0x06, 0x80, 0x01, 0x00, 0x66, 0x06, 0x00, 0x18, 0x06, 0x80, 0x01, 0x00, 0x8c, 0x0d, 0x00, 0x18, 0x02, 0x80, 0x01, 0x00, 0x18, 0x0e, 0x00, 0x18, 0x03, 0x80, 0x01, 0x00, 0xf0, 0x0c, 0x00, 0x18, 0x03, 0x80, 0x01, 0x00, 0x30, 0x0f, 0x00, 0x98, 0x01, 0x80, 0x01, 0x00, 0xb0, 0x1f, 0x01, 0x98, 0x01, 0x80, 0x01, 0x00, 0x60, 0x1f, 0x03, 0xdc, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x3f, 0x03, 0xdc, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x3b, 0x07, 0xee, 0x00, 0x80, 0x01, 0x00, 0x70, 0xf8, 0xff, 0xff, 0x01, 0x80, 0x01, 0x00, 0xf0, 0x80, 0xff, 0x37, 0x03, 0x80, 0x01, 0x00, 0xfc, 0x00, 0x08, 0xd8, 0x03, 0x80, 0x01, 0x00, 0xfe, 0x03, 0xf8, 0x7f, 0x07, 0x80, 0x01, 0xc0, 0x87, 0x07, 0xe0, 0x3f, 0x1c, 0x80, 0x01, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x8f, 0x81, 0xff, 0x00, 0x38, 0x00, 0xf6, 0xf9, 0xff, 0xfd, 0x3f, 0x00, 0xe0, 0x00, 0x83, 0x8f, 0xff, 0xff, 0x00, 0x00, 0x80, 0x01, 0x00, 0xfc, 0xc0, 0x07, 0x0e, 0x00, 0x38, 0xe0, 0x00, 0xe0, 0x9f, 0xf9, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0xff, 0x7f, 0x80, 0x01, 0x00, 0xc0, 0x00, 0x00, 0xf0, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x80, 0x01, 0x30, 0x00, 0x00, 0x38, 0xc0, 0xc0, 0x80, 0x01, 0x1c, 0xe0, 0x00, 0x0c, 0xc0, 0x83, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; } blt::bitmap define xbob { #define bob_x_hot 30 #define bob_y_hot 37 #define bob_width 61 #define bob_height 75 static char bob_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xfb, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xcf, 0x9f, 0xd1, 0x03, 0x00, 0x00, 0xf0, 0x7f, 0x8c, 0x33, 0x91, 0x07, 0x00, 0x00, 0xf8, 0xa7, 0x18, 0x27, 0xb1, 0x06, 0x00, 0x00, 0xfc, 0x47, 0x31, 0x4e, 0xa6, 0x0e, 0x00, 0x00, 0xfe, 0x4f, 0x21, 0x4c, 0xae, 0x3d, 0x00, 0x00, 0xff, 0xdf, 0x23, 0x8d, 0xbe, 0x7d, 0x00, 0x80, 0xff, 0xff, 0x67, 0xbd, 0xfe, 0xff, 0x01, 0x80, 0xff, 0xff, 0x7f, 0xbf, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xf8, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xbf, 0x3f, 0xf8, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, 0x0f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x0f, 0xe0, 0x7f, 0x00, 0xf8, 0x07, 0x00, 0xf0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x78, 0xf6, 0x07, 0xa0, 0xbf, 0xff, 0x00, 0x00, 0xff, 0xf7, 0x07, 0x70, 0x9f, 0xff, 0x01, 0x80, 0xff, 0xef, 0x07, 0xf0, 0x1c, 0x80, 0x03, 0xe0, 0x01, 0xef, 0x07, 0xf0, 0x1f, 0xbe, 0x07, 0xf0, 0x3f, 0xee, 0x07, 0xe0, 0x9d, 0x83, 0x1f, 0xf8, 0xe1, 0xdc, 0x07, 0xe0, 0xc1, 0x7f, 0x1f, 0xfc, 0xff, 0xc8, 0x07, 0xe0, 0xc1, 0x69, 0x1e, 0x7e, 0xca, 0xc0, 0x03, 0xe0, 0x81, 0xb8, 0x1f, 0xc0, 0x0e, 0xc0, 0x03, 0xe0, 0x01, 0xc0, 0x1b, 0xc0, 0xcf, 0xc1, 0x03, 0xc0, 0x03, 0xf7, 0x11, 0x00, 0x7f, 0xc0, 0x03, 0xc0, 0x03, 0x7c, 0x18, 0x00, 0x1c, 0xc0, 0x02, 0xc0, 0x02, 0x30, 0x08, 0x00, 0x00, 0x40, 0x03, 0x40, 0x03, 0x00, 0x08, 0x00, 0x00, 0x40, 0x02, 0x40, 0x13, 0x00, 0x0c, 0x00, 0x00, 0x60, 0x02, 0x40, 0x12, 0x00, 0x0e, 0x00, 0x00, 0xc0, 0x03, 0x80, 0x33, 0x80, 0x0e, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x33, 0x40, 0x0f, 0xa0, 0x03, 0x2c, 0x00, 0x00, 0x74, 0x30, 0x0f, 0x38, 0x07, 0x2e, 0x00, 0x00, 0x74, 0x98, 0x1f, 0x1e, 0x1e, 0x2f, 0x00, 0x00, 0xfc, 0x8f, 0xff, 0x0f, 0xfc, 0x2f, 0x00, 0x00, 0xf8, 0xe3, 0xff, 0x03, 0xf8, 0x2f, 0x00, 0x00, 0xf8, 0xfd, 0xff, 0x81, 0xff, 0x3f, 0x00, 0x00, 0xb8, 0xf9, 0x1f, 0xf8, 0x0f, 0x1e, 0x00, 0x00, 0x30, 0xf1, 0xf0, 0x0f, 0x03, 0x0e, 0x00, 0x00, 0x30, 0xf1, 0x01, 0x80, 0x01, 0x0f, 0x00, 0x00, 0x20, 0xf1, 0xf7, 0xff, 0x00, 0x07, 0x00, 0x00, 0x60, 0xe3, 0x01, 0x60, 0x80, 0x07, 0x00, 0x00, 0x60, 0xc3, 0xef, 0x3f, 0x80, 0x03, 0x00, 0x00, 0x40, 0xc2, 0xff, 0x0f, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0xe6, 0x1f, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0xf4, 0xfe, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x79, 0xfe, 0x1f, 0xe0, 0x00, 0x00, 0xc0, 0x01, 0x3d, 0x3e, 0x00, 0x70, 0x00, 0x00, 0x30, 0x06, 0x3e, 0x0f, 0x00, 0x38, 0x00, 0x00, 0xc8, 0x8c, 0x1f, 0x07, 0x00, 0x38, 0x00, 0x00, 0xf4, 0xcc, 0x8f, 0x07, 0x00, 0x1c, 0x00, 0x00, 0x72, 0xee, 0xf7, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x02, 0xff, 0xe3, 0x07, 0x00, 0x07, 0x00, 0x00, 0x32, 0xfe, 0xc1, 0xff, 0x8f, 0x03, 0x00, 0x00, 0x3e, 0xfe, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x7e, 0x7c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } blt::bitmap compose text "Text String" -font {courier 12} . configure -bg grey80 label .angle -text "Angle" -font { Helvetica 12 bold } -bg grey80 label .scale -text "Scale" -font { Helvetica 12 bold } -bg grey80 blt::table . \ 0,0 .angle -fill both \ 0,5 .scale -fill both set row 1 foreach angle { 0 90 180 270 360 45 -45 101 } { label .angle$angle -text $angle -bg grey80 blt::table . \ $row,0 .angle$angle -fill both set column 1 foreach bitmap { hobbes gort xbob text } { set data [blt::bitmap data $bitmap] blt::bitmap define $bitmap$row$column $data -rotate $angle label .$bitmap$row$column -bitmap $bitmap$row$column -bg white blt::table . \ $row,$column .$bitmap$row$column incr column } incr row } set row 1 foreach scale { 1.0 0.5 0.75 1.4 3.0 } { label .scale$row -text $scale -bg grey80 blt::table . \ $row,5 .scale$row -fill both set column 6 foreach bitmap { hobbes gort xbob text } { set data [blt::bitmap data $bitmap] blt::bitmap define $bitmap$row$column $data -scale $scale label .$bitmap$row$column -bitmap $bitmap$row$column -bg white blt::table . \ $row,$column .$bitmap$row$column incr column } incr row } foreach scale { 2.0 0.8 1.2 } angle { 45 -45 101 } { label .scale$row -text "$scale/$angle" -bg grey80 blt::table . \ $row,5 .scale$row -fill both set column 6 foreach bitmap { hobbes gort xbob text } { set data [blt::bitmap data $bitmap] blt::bitmap define $bitmap$row $data -scale $scale -rotate $angle label .$bitmap$row -bitmap $bitmap$row -bg white blt::table . \ $row,$column .$bitmap$row incr column } incr row } blt::table configure . c* -padx 2������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/hiertable1.tcl��������������������������������������������������������������0000755�0001750�0001750�00000011744�11462120062�016103� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set saved [pwd] #blt::bltdebug 100 image create picture bgTexture -file ./images/rain.gif set imageList {} foreach f [glob ./images/mini-*.gif] { lappend imageList [image create picture -file $f] } #option add *Hiertable.Tile bgTexture #option add *Hiertable.Column.background grey90 option add *Hiertable.ScrollTile yes option add *Hiertable.titleShadow { grey80 } option add *Hiertable.titleFont {*-helvetica-bold-r-*-*-11-*-*-*-*-*-*-*} option add *xHiertable.openCommand { set path /home/gah/src/blt/%P if { [file isdirectory $path] } { cd $path set files [glob -nocomplain * */. ] if { $files != "" } { eval %W insert -at %n end $files } } } option add *xHiertable.closeCommand { eval %W delete %n 0 end } hiertable .h -hideroot no -width 0 \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -selectmode single -hideleaves false .h column configure treeView -text View .h column insert 0 mtime atime gid .h column insert end nlink mode type ctime uid ino size dev .h column configure uid -background \#eaeaff -relief raised -bd 1 .h column configure mtime -hide no -bg \#ffeaea -relief raised -bd 1 .h column configure size gid nlink uid ino dev -justify right -edit yes .h column configure treeView -hide no -edit no scrollbar .vs -orient vertical -command { .h yview } scrollbar .hs -orient horizontal -command { .h xview } blt::table . \ 0,0 .h -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } blt::table configure . c1 r1 -resize none image create picture fileImage -file images/stopsign.gif proc DoFind { dir path } { global fileList count set saved [pwd] cd $dir foreach f [lsort [glob -nocomplain *]] { set entry [file join $path $f] if { [catch { file stat $entry info }] != 0 } { lappend fileList $entry } else { if 0 { if { $info(type) == "file" } { set info(type) @fileImage } else { set info(type) "" } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(size) [FormatSize $info(size)] set info(mode) [FormatMode $info(mode)] lappend fileList $entry -data [array get info] } incr count if { [file type $f] == "directory" } { DoFind $f $entry } } cd $saved } proc Find { dir } { global fileList count set fileList {} catch { file stat $dir info } incr count lappend fileList $dir -data [array get info] DoFind $dir $dir return $fileList } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath ..] set trim "$top" .h configure -separator "/" -trim $trim set count 0 .h entry configure root -label [file tail [GetAbsolutePath $top]] .h configure -bg grey90 regsub -all {\.\./*} [Find $top] {} fileList puts "$count entries" eval .h insert end $fileList .h configure -bg white focus .h set nodes [.h find -glob -name *.c] eval .h entry configure $nodes -foreground green4 set nodes [.h find -glob -name *.h] eval .h entry configure $nodes -foreground cyan4 set nodes [.h find -glob -name *.o] eval .h entry configure $nodes -foreground red4 cd $saved #bltdebug 100 toplevel .top blt::hiertable .top.h2 -tree .h -yscrollcommand { .top.sbar set } scrollbar .top.sbar -command { .top.h2 yview } pack .top.h2 -side left -expand yes -fill both pack .top.sbar -side right -fill y .h column bind all <ButtonRelease-3> { %W configure -flat no } proc SortColumn { column } { set old [.h sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.h sort cget -decreasing] set decreasing [expr !$decreasing] } .h sort configure -decreasing $decreasing -column $column -mode integer .h configure -flat yes .h sort auto yes blt::busy hold .h update blt::busy release .h } foreach column [.h column names] { .h column configure $column -command [list SortColumn $column] } scale .s -from 0 -to 300 -orient horizontal -length 300 blt::table . \ 3,0 .s update .s set 20 if 1 { .s configure -command { .h entry configure 0 -height } } ����������������������������./saods9/blt3.0.1/demos/bitmap.tcl������������������������������������������������������������������0000755�0001750�0001750�00000025445�11462120062�015342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT # -------------------------------------------------------------------------- # Starting with Tcl 8.x, the BLT commands are stored in their own # namespace called "blt". The idea is to prevent name clashes with # Tcl commands and variables from other packages, such as a "table" # command in two different packages. # # You can access the BLT commands in a couple of ways. You can prefix # all the BLT commands with the namespace qualifier "blt::" # # blt::graph .g # blt::table . .g -resize both # # or you can import all the command into the global namespace. # # namespace import blt::* # graph .g # table . .g -resize both # # -------------------------------------------------------------------------- if { $tcl_version >= 8.0 } { namespace import blt::* namespace import -force blt::tk::* } source scripts/demo.tcl source scripts/stipples.tcl source scripts/patterns.tcl bitmap define wide_weave { #define wide_weave_width 16 #define wide_weave_height 16 static char wide_weave_bits[] = { 0x11, 0x11, 0xb8, 0xb8, 0x7c, 0x7c, 0x3a, 0x3a, 0x11, 0x11, 0xa3, 0xa3, 0xc7, 0xc7, 0x8b, 0x8b, 0x11, 0x11, 0xb8, 0xb8, 0x7c, 0x7c, 0x3a, 0x3a, 0x11, 0x11, 0xa3, 0xa3, 0xc7, 0xc7, 0x8b, 0x8b}; } bitmap define hobbes3 { #define hobbes_width 25 #define hobbes_height 25 static char hobbes_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x78, 0xe0, 0x07, 0x00, 0xfc, 0xf8, 0x07, 0x00, 0xcc, 0x07, 0x04, 0x00, 0x0c, 0xf0, 0x0b, 0x00, 0x7c, 0x1c, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x10, 0x00, 0xe0, 0x41, 0x11, 0x00, 0x20, 0x40, 0x11, 0x00, 0xe0, 0x07, 0x10, 0x00, 0xe0, 0xc1, 0x17, 0x00, 0x10, 0xe0, 0x2f, 0x00, 0x20, 0xe0, 0x6f, 0x00, 0x18, 0xe0, 0x2f, 0x00, 0x20, 0xc6, 0x67, 0x00, 0x18, 0x84, 0x2b, 0x00, 0x20, 0x08, 0x64, 0x00, 0x70, 0xf0, 0x13, 0x00, 0x80, 0x01, 0x08, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } -scale 3.0 bitmap define gort { #define gort_width 64 #define gort_height 64 static char gort_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x80, 0x01, 0x00, 0xc0, 0xdf, 0x0f, 0x1e, 0x00, 0x80, 0x01, 0x00, 0x60, 0xdf, 0x7f, 0x38, 0x00, 0x80, 0x01, 0x00, 0x30, 0x84, 0xfd, 0x67, 0x00, 0x80, 0x01, 0x00, 0x18, 0x04, 0xf6, 0xef, 0x00, 0x80, 0x01, 0x00, 0x0c, 0x86, 0xe1, 0xc7, 0x01, 0x80, 0x01, 0x00, 0x06, 0x06, 0xc0, 0x96, 0x01, 0x80, 0x01, 0x00, 0x06, 0x06, 0x00, 0x97, 0x03, 0x80, 0x01, 0x00, 0x06, 0x06, 0x00, 0x3c, 0x03, 0x80, 0x01, 0x00, 0x03, 0x06, 0x00, 0x5c, 0x07, 0x80, 0x01, 0x00, 0x03, 0x02, 0x00, 0xd8, 0x06, 0x80, 0x01, 0x00, 0x03, 0x02, 0x00, 0xd8, 0x06, 0x80, 0x01, 0x00, 0x43, 0x02, 0x00, 0xb0, 0x0c, 0x80, 0x01, 0x80, 0x31, 0x03, 0x00, 0xe0, 0x0d, 0x80, 0x01, 0x80, 0x61, 0x03, 0x00, 0xe0, 0x0d, 0x80, 0x01, 0x80, 0x1b, 0x03, 0x00, 0xf0, 0x0c, 0x80, 0x01, 0x80, 0xb3, 0x03, 0xff, 0xff, 0x1d, 0x80, 0x01, 0xc0, 0xeb, 0xfb, 0xff, 0xff, 0x1d, 0x80, 0x01, 0xe0, 0xc5, 0x7f, 0xfe, 0x7f, 0x3f, 0x01, 0xe0, 0xeb, 0xe3, 0xff, 0xff, 0x6e, 0x80, 0x01, 0xd0, 0x3b, 0xfe, 0x01, 0x80, 0x40, 0xcf, 0x80, 0x01, 0xf0, 0xf7, 0x07, 0x00, 0x30, 0x8e, 0x80, 0x01, 0xf0, 0xf4, 0x00, 0x00, 0x1b, 0x98, 0x80, 0x01, 0x70, 0x14, 0x00, 0x00, 0x1f, 0xdc, 0x80, 0x01, 0x30, 0xfe, 0xff, 0x1f, 0xc8, 0xff, 0x80, 0x01, 0x20, 0xee, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x20, 0xf7, 0xff, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0xc0, 0xe1, 0xff, 0xff, 0xfe, 0x3f, 0x80, 0x01, 0x80, 0xed, 0xff, 0xff, 0xff, 0x19, 0x80, 0x01, 0x80, 0x99, 0xff, 0xff, 0xff, 0x18, 0x80, 0x01, 0x00, 0x63, 0x83, 0xff, 0x7f, 0x08, 0x80, 0x01, 0x00, 0xc3, 0x06, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x9b, 0x07, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0xb6, 0x07, 0x00, 0x10, 0x0c, 0x80, 0x01, 0x00, 0xc6, 0x07, 0x00, 0x10, 0x04, 0x80, 0x01, 0x00, 0x36, 0x06, 0x00, 0x18, 0x06, 0x80, 0x01, 0x00, 0x66, 0x06, 0x00, 0x18, 0x06, 0x80, 0x01, 0x00, 0x8c, 0x0d, 0x00, 0x18, 0x02, 0x80, 0x01, 0x00, 0x18, 0x0e, 0x00, 0x18, 0x03, 0x80, 0x01, 0x00, 0xf0, 0x0c, 0x00, 0x18, 0x03, 0x80, 0x01, 0x00, 0x30, 0x0f, 0x00, 0x98, 0x01, 0x80, 0x01, 0x00, 0xb0, 0x1f, 0x01, 0x98, 0x01, 0x80, 0x01, 0x00, 0x60, 0x1f, 0x03, 0xdc, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x3f, 0x03, 0xdc, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x3b, 0x07, 0xee, 0x00, 0x80, 0x01, 0x00, 0x70, 0xf8, 0xff, 0xff, 0x01, 0x80, 0x01, 0x00, 0xf0, 0x80, 0xff, 0x37, 0x03, 0x80, 0x01, 0x00, 0xfc, 0x00, 0x08, 0xd8, 0x03, 0x80, 0x01, 0x00, 0xfe, 0x03, 0xf8, 0x7f, 0x07, 0x80, 0x01, 0xc0, 0x87, 0x07, 0xe0, 0x3f, 0x1c, 0x80, 0x01, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x8f, 0x81, 0xff, 0x00, 0x38, 0x00, 0xf6, 0xf9, 0xff, 0xfd, 0x3f, 0x00, 0xe0, 0x00, 0x83, 0x8f, 0xff, 0xff, 0x00, 0x00, 0x80, 0x01, 0x00, 0xfc, 0xc0, 0x07, 0x0e, 0x00, 0x38, 0xe0, 0x00, 0xe0, 0x9f, 0xf9, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0xff, 0x7f, 0x80, 0x01, 0x00, 0xc0, 0x00, 0x00, 0xf0, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x80, 0x01, 0x30, 0x00, 0x00, 0x38, 0xc0, 0xc0, 0x80, 0x01, 0x1c, 0xe0, 0x00, 0x0c, 0xc0, 0x83, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; } -rotate 180 bitmap define xbob { #define bob_x_hot 30 #define bob_y_hot 37 #define bob_width 61 #define bob_height 75 static char bob_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xfb, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xcf, 0x9f, 0xd1, 0x03, 0x00, 0x00, 0xf0, 0x7f, 0x8c, 0x33, 0x91, 0x07, 0x00, 0x00, 0xf8, 0xa7, 0x18, 0x27, 0xb1, 0x06, 0x00, 0x00, 0xfc, 0x47, 0x31, 0x4e, 0xa6, 0x0e, 0x00, 0x00, 0xfe, 0x4f, 0x21, 0x4c, 0xae, 0x3d, 0x00, 0x00, 0xff, 0xdf, 0x23, 0x8d, 0xbe, 0x7d, 0x00, 0x80, 0xff, 0xff, 0x67, 0xbd, 0xfe, 0xff, 0x01, 0x80, 0xff, 0xff, 0x7f, 0xbf, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xf8, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xbf, 0x3f, 0xf8, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, 0x0f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x0f, 0xe0, 0x7f, 0x00, 0xf8, 0x07, 0x00, 0xf0, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x07, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x78, 0xf6, 0x07, 0xa0, 0xbf, 0xff, 0x00, 0x00, 0xff, 0xf7, 0x07, 0x70, 0x9f, 0xff, 0x01, 0x80, 0xff, 0xef, 0x07, 0xf0, 0x1c, 0x80, 0x03, 0xe0, 0x01, 0xef, 0x07, 0xf0, 0x1f, 0xbe, 0x07, 0xf0, 0x3f, 0xee, 0x07, 0xe0, 0x9d, 0x83, 0x1f, 0xf8, 0xe1, 0xdc, 0x07, 0xe0, 0xc1, 0x7f, 0x1f, 0xfc, 0xff, 0xc8, 0x07, 0xe0, 0xc1, 0x69, 0x1e, 0x7e, 0xca, 0xc0, 0x03, 0xe0, 0x81, 0xb8, 0x1f, 0xc0, 0x0e, 0xc0, 0x03, 0xe0, 0x01, 0xc0, 0x1b, 0xc0, 0xcf, 0xc1, 0x03, 0xc0, 0x03, 0xf7, 0x11, 0x00, 0x7f, 0xc0, 0x03, 0xc0, 0x03, 0x7c, 0x18, 0x00, 0x1c, 0xc0, 0x02, 0xc0, 0x02, 0x30, 0x08, 0x00, 0x00, 0x40, 0x03, 0x40, 0x03, 0x00, 0x08, 0x00, 0x00, 0x40, 0x02, 0x40, 0x13, 0x00, 0x0c, 0x00, 0x00, 0x60, 0x02, 0x40, 0x12, 0x00, 0x0e, 0x00, 0x00, 0xc0, 0x03, 0x80, 0x33, 0x80, 0x0e, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x33, 0x40, 0x0f, 0xa0, 0x03, 0x2c, 0x00, 0x00, 0x74, 0x30, 0x0f, 0x38, 0x07, 0x2e, 0x00, 0x00, 0x74, 0x98, 0x1f, 0x1e, 0x1e, 0x2f, 0x00, 0x00, 0xfc, 0x8f, 0xff, 0x0f, 0xfc, 0x2f, 0x00, 0x00, 0xf8, 0xe3, 0xff, 0x03, 0xf8, 0x2f, 0x00, 0x00, 0xf8, 0xfd, 0xff, 0x81, 0xff, 0x3f, 0x00, 0x00, 0xb8, 0xf9, 0x1f, 0xf8, 0x0f, 0x1e, 0x00, 0x00, 0x30, 0xf1, 0xf0, 0x0f, 0x03, 0x0e, 0x00, 0x00, 0x30, 0xf1, 0x01, 0x80, 0x01, 0x0f, 0x00, 0x00, 0x20, 0xf1, 0xf7, 0xff, 0x00, 0x07, 0x00, 0x00, 0x60, 0xe3, 0x01, 0x60, 0x80, 0x07, 0x00, 0x00, 0x60, 0xc3, 0xef, 0x3f, 0x80, 0x03, 0x00, 0x00, 0x40, 0xc2, 0xff, 0x0f, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0xe6, 0x1f, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0xf4, 0xfe, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x79, 0xfe, 0x1f, 0xe0, 0x00, 0x00, 0xc0, 0x01, 0x3d, 0x3e, 0x00, 0x70, 0x00, 0x00, 0x30, 0x06, 0x3e, 0x0f, 0x00, 0x38, 0x00, 0x00, 0xc8, 0x8c, 0x1f, 0x07, 0x00, 0x38, 0x00, 0x00, 0xf4, 0xcc, 0x8f, 0x07, 0x00, 0x1c, 0x00, 0x00, 0x72, 0xee, 0xf7, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x02, 0xff, 0xe3, 0x07, 0x00, 0x07, 0x00, 0x00, 0x32, 0xfe, 0xc1, 0xff, 0x8f, 0x03, 0x00, 0x00, 0x3e, 0xfe, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x7e, 0x7c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; } -rotate -123 bitmap compose top "Top\nScaled 2x" -pady 5 -padx 10 -rotate 0 -scale 2.0 bitmap compose left "Left\na\nb\nc" -rotate 90 bitmap compose right {Right} -rotate 270 bitmap compose center {Center} -rotate 45 bitmap compose bottom {Bottom} -rotate 180 # # Test bitmap # # 1. Test of rotated text bitmap # 2. Define bitmap from output of "data" command # 3. Define bitmap from X11 bitmap file # 4. Define bitmap from X10 bitmap file # 5. Define bitmap from internal Tcl list # 6. Use predefined internal bitmap # proc ChangeBitmap { w } { global count bitmapList if { [incr count] >= [llength $bitmapList] } { exit } $w configure -bitmap [lindex $bitmapList $count] } set count -1 set bitmapList { sharky hobbes3 xbob gort question large_question questhead large_questhead hobbes BLT } option add *center*padX 8 option add *center*padY 4 button .left -bitmap left -command { .center configure -bitmap sharky ; set count -1 } button .top -bitmap top -command { .center configure -bitmap hobbes3 ; set count 0 } button .right -bitmap right -command { .center configure -bitmap xbob ; set count 1 } button .bottom -bitmap bottom -command { .center configure -bitmap gort ; set count 2 } button .center -bitmap center -command "ChangeBitmap .center" set bitmapFile @bitmaps/sharky.xbm bitmap define sharky [bitmap data $bitmapFile] -rotate 45 -scale 0.75 bitmap define large_question [bitmap data question] -scale 2.0 bitmap define large_questhead [bitmap data questhead] -scale 2.0 blt::table . \ .top 0,1 -fill x \ .left 1,0 -fill y \ .center 1,1 -fill both \ .right 1,2 -fill y \ .bottom 2,1 -fill x ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/barchart1.tcl���������������������������������������������������������������0000755�0001750�0001750�00000007462�11462120062�015734� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set graph .bc proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed 148230 proc FormatLabel { w value } { # Determine the element name from the value set names [$w element show] set index [expr round($value)] if { $index != $value } { return $value } global elemLabels if { [info exists elemLabels($index)] } { return $elemLabels($index) } return $value } source scripts/stipples.tcl set normalBg [blt::bgpattern create gradient -shape linear \ -dir y -low white -high grey -relativeto self] set normalBg [blt::bgpattern create solid -color lightblue -opacity 50] #set normalBg lightblue option add *Htext.tileOffset no option add *Barchart.title "A Simple Barchart" option add *x.Title "X Axis Label" option add *x.Rotate 60 option add *x.Command FormatLabel option add *y.Title "Y Axis Label" option add *x.tickFont "{San Serif} 8" option add *Element.Background white #option add *Element.Relief solid option add *Element.BorderWidth 1 option add *Legend.hide yes option add *Grid.hide no option add *Grid.dashes { 2 4 } option add *Grid.mapX "" set visual [winfo screenvisual .] if { $visual != "staticgray" && $visual != "grayscale" } { option add *print.background yellow option add *quit.background red option add *graph.background palegreen } blt::htext .header -text { The barchart has several components: coordinate axes, data elements, legend, crosshairs, grid, postscript, and markers. They each control various aspects of the barchart. For example, the postscript component lets you generate PostScript output. Pressing the %% set w $htext(widget) button $w.print -text {Print} -command { .bc postscript output bar.ps } $w append $w.print %% button will create a file "bar.ps" } blt::htext .footer -text { Hit the %% set w $htext(widget) button $w.quit -text quit -command exit $w append $w.quit %% button when you've seen enough.%% label $w.logo -bitmap BLT $w append $w.logo -padx 20 %% } blt::barchart .bc -plotpadx 10 .bc configure -bg white -plotborderwidth 0 # # Element attributes: # # Label Foreground Background Stipple Pattern source scripts/stipples.tcl set bg [blt::bgpattern create gradient -high orange2 -low yellow2 \ -shape linear -dir y -jitter no -log no -relativeto toplevel] set bitmaps { bdiagonal1 bdiagonal2 checker2 checker3 cross1 cross2 cross3 crossdiag dot1 dot2 dot3 dot4 fdiagonal1 fdiagonal2 hline1 hline2 lbottom ltop rbottom rtop vline1 vline2 } set count 1 foreach stipple $bitmaps { set label [file tail $stipple] set label [file root $label] set y [random -2 10] set yhigh [expr $y + 0.5] set ylow [expr $y - 0.5] .bc element create $label -y $y -x $count \ -fg "" -bg $normalBg -yhigh $yhigh -ylow $ylow -errorbarcolor brown \ -relief raised -bd 2 set elemLabels($count) $label incr count } blt::table . \ 0,0 .header -fill x \ 1,0 .bc -fill both \ 2,0 .footer -fill x blt::table configure . r0 r2 -resize none Blt_ZoomStack .bc Blt_Crosshairs .bc Blt_ActiveLegend .bc Blt_ClosestPoint .bc if 0 { set printer [blt::printer open [lindex [blt::printer names] 0]] blt::printer getattr $printer attrs set attrs(Orientation) Portrait blt::printer setattr $printer attrs after 2000 { $graph print2 $printer blt::printer close $printer } } .bc axis bind x <Enter> { set axis [%W axis get current] %W axis configure $axis -color blue3 -titlecolor blue3 } .bc axis bind x <Leave> { set axis [%W axis get current] %W axis configure $axis -color black -titlecolor black } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cbutton1.tcl����������������������������������������������������������������0000644�0001750�0001750�00000026636�11462120062�015625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� foreach {key file} { save_as /usr/share/gtk-doc/html/pygtk/icons/stock_save_as_24.png new_tab /usr/share/gtk-doc/html/pygtk/icons/stock_new_24.png new_window /usr/share/gtk-doc/html/pygtk/icons/stock_network_24.png open_file /usr/share/gtk-doc/html/pygtk/icons/stock_open_24.png quit /usr/share/gtk-doc/html/pygtk/icons/stock_exit_24.png print /usr/share/gtk-doc/html/pygtk/icons/stock_print_24.png print_preview /usr/share/gtk-doc/html/pygtk/icons/stock_print_preview_24.png undo /usr/share/gtk-doc/html/pygtk/icons/stock_undo_24.png redo /usr/share/gtk-doc/html/pygtk/icons/stock_redo_24.png cut /usr/share/gtk-doc/html/pygtk/icons/stock_cut_24.png paste /usr/share/gtk-doc/html/pygtk/icons/stock_paste_24.png copy /usr/share/gtk-doc/html/pygtk/icons/stock_copy_24.png delete /usr/share/gtk-doc/html/pygtk/icons/stock_trash_24.png select_all /usr/share/gtk-doc/html/pygtk/icons/stock_broken_image_24.png find /usr/share/gtk-doc/html/pygtk/icons/stock_search_24.png preferences /usr/share/gtk-doc/html/pygtk/icons/stock_preferences_24.png stop /usr/share/gtk-doc/html/pygtk/icons/stock_stop_24.png reload /usr/share/gtk-doc/html/pygtk/icons/stock_refresh_24.png back /usr/share/gtk-doc/html/pygtk/icons/stock_left_arrow_24.png forward /usr/share/gtk-doc/html/pygtk/icons/stock_right_arrow_24.png home /usr/share/gtk-doc/html/pygtk/icons/stock_home_24.png help /usr/share/gtk-doc/html/pygtk/icons/stock_help_24.png about /usr/share/gtk-doc/html/pygtk/icons/stock_about_24.png download /usr/share/icons/gnome/24x24/emblems/emblem-downloads.png bookmark /usr/share/icons/gnome/24x24/stock/object/stock_bookmark.png } { set icon($key) [image create picture -file $file] } if { [file exists ../library] } { set blt_library ../library } set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } #set image [image create picture -file ~/images.jpeg] set bg [blt::bgpattern create gradient -high grey70 -low grey95 \ -jitter yes -log yes -relativeto self] set image "" blt::tk::frame .mbar -bg $bg set t "Hello, World" blt::combobutton .mbar.file \ -text "File" \ -underline 0 \ -image $image \ -relief flat \ -activerelief raised \ -arrowon off \ -bg $bg \ -font { Arial 9 } -justify left \ -menuanchor sw \ -menu .mbar.file.m blt::combomenu .mbar.file.m \ -width { 0 400 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.file.m add -text "New Window" -accelerator "Ctrl+N" -underline 0 \ -icon $icon(new_window) .mbar.file.m add -text "New Tab" -accelerator "Ctrl+T" -underline 4 \ -icon $icon(new_tab) .mbar.file.m add -text "Open Location..." -accelerator "Ctrl+L" -underline 5 .mbar.file.m add -text "Open File..." -accelerator "Ctrl+O" -underline 0 \ -icon $icon(open_file) .mbar.file.m add -text "Close Window" -accelerator "Ctrl+Shift+W" -underline 9 .mbar.file.m add -text "Close Tab" -accelerator "Ctrl+W" -underline 0 .mbar.file.m add -type separator .mbar.file.m add -text "Save Page As..." -accelerator "Ctrl+O" -underline 10 \ -icon $icon(save_as) .mbar.file.m add -text "Save Page As PDF..." -accelerator "Ctrl+Shift+W" -underline 15 .mbar.file.m add -text "Send Link..." -accelerator "Ctrl+W" -underline 1 .mbar.file.m add -type separator .mbar.file.m add -text "Page Setup..." -underline 8 .mbar.file.m add -text "Print Preview" -accelerator "Ctrl+Shift+W" -underline 9 \ -icon $icon(print_preview) .mbar.file.m add -text "Print..." -accelerator "Ctrl+P" -underline 0 \ -icon $icon(print) .mbar.file.m add -type separator .mbar.file.m add -text "Import..." -underline 0 .mbar.file.m add -type separator .mbar.file.m add -text "Work Offline" -underline 0 .mbar.file.m add -text "Quit" -accelerator "Ctrl+Q" -underline 0 \ -icon $icon(quit) blt::combobutton .mbar.edit \ -text "Edit" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.edit.m blt::combomenu .mbar.edit.m \ -width { 0 400 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.edit.m add -text "Undo" -accelerator "Ctrl+Z" \ -icon $icon(undo) .mbar.edit.m add -text "Redo" -accelerator "Ctrl+Shift+Z" \ -icon $icon(redo) .mbar.edit.m add -type separator .mbar.edit.m add -text "Cut" -accelerator "Ctrl+X" \ -icon $icon(cut) .mbar.edit.m add -text "Copy" -accelerator "Ctrl+C" \ -icon $icon(copy) .mbar.edit.m add -text "Paste" -accelerator "Ctrl+V" \ -icon $icon(paste) .mbar.edit.m add -text "Delete" -accelerator "Del" \ -icon $icon(delete) .mbar.edit.m add -type separator .mbar.edit.m add -text "Select All" -accelerator "Ctrl+X" \ -icon $icon(select_all) .mbar.edit.m add -type separator .mbar.edit.m add -text "Find" -accelerator "Ctrl+F" \ -icon $icon(find) .mbar.edit.m add -text "Find Again" -accelerator "Ctrl+G" .mbar.edit.m add -type separator .mbar.edit.m add -text "Preferences" \ -icon $icon(preferences) blt::combomenu .mbar.edit.m.m .mbar.edit.m.m add -type command -text "five" -accelerator "^A" -command "set t five" .mbar.edit.m.m add -type command -text "six" -accelerator "^B" -command "set t six" .mbar.edit.m.m add -type command -text "seven" -accelerator "^C" -command "set t seven" .mbar.edit.m.m add -type command -text "eight" -accelerator "^D" -command "set t eight" .mbar.edit.m.m add -type cascade -text "cascade" -accelerator "^E" blt::combobutton .mbar.view \ -text "View" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.view.m blt::combomenu .mbar.view.m \ -width { 0 600 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.view.m add -type cascade -text "Toolbars" -underline 0 .mbar.view.m add -type checkbutton -text "Status Bar" \ -underline 4 -variable statusbar .mbar.view.m add -type checkbutton -text "Sidebar" \ -underline 5 -variable sidebar .mbar.view.m add -type checkbutton -text "Adblock Plus: Blockable items" \ -accelerator "Ctrl+Shift+V" -underline 0 -variable adblock .mbar.view.m add -type separator .mbar.view.m add -text "Stop" -accelerator "Esc" -underline 9 \ -icon $icon(stop) .mbar.view.m add -text "Reload" -accelerator "Ctrl+R" -underline 0 \ -icon $icon(reload) .mbar.view.m add -type separator .mbar.view.m add -type cascade -text "Zoom" -accelerator "Ctrl+O" -underline 10 .mbar.view.m add -type cascade -text "Page Style" -accelerator "Ctrl+Shift+W" \ -underline 15 .mbar.view.m add -type cascade -text "Character Encoding" -accelerator "Ctrl+W" \ -underline 1 .mbar.view.m add -type separator .mbar.view.m add -text "Page Source" -underline 8 -accelerator "Ctrl+U" .mbar.view.m add -text "Full Screen" -accelerator "F11" -underline 9 blt::combobutton .mbar.history \ -text "History" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.history.m blt::combomenu .mbar.history.m \ -width { 0 600 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.history.m add -text "Back" -accelerator "Alt+Left Arrow" \ -underline 0 -icon $icon(back) .mbar.history.m add -text "Forward" -accelerator "Alt+Right Arrow" \ -underline 4 -icon $icon(forward) .mbar.history.m add -text "Home" -accelerator "Alt+Home" \ -underline 5 -icon $icon(home) .mbar.history.m add -text "Show All History" -accelerator "Ctrl+Shift+H" \ -underline 0 .mbar.history.m add -type separator .mbar.history.m add -type cascade -text "Recently Closed Tabs" \ -accelerator "Ctrl+O" -underline 10 blt::combobutton .mbar.bmarks \ -text "Bookmarks" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.bmarks.m blt::combomenu .mbar.bmarks.m \ -width { 0 600 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.bmarks.m add -text "Bookmark This Page" -accelerator "Ctrl+D" \ -underline 0 -icon $icon(bookmark) .mbar.bmarks.m add -text "Subscribe to This Page..." \ -underline 4 -icon $icon(forward) .mbar.bmarks.m add -text "Bookmark All Tabs" \ -underline 5 -icon $icon(home) .mbar.bmarks.m add -text "Organize Bookmarks" \ -underline 0 .mbar.bmarks.m add -type separator .mbar.bmarks.m add -type cascade -text "Bookmarks Toolbar" \ -underline 10 .mbar.bmarks.m add -type separator .mbar.bmarks.m add -type cascade -text "Recently Bookmarked" \ -underline 10 .mbar.bmarks.m add -type cascade -text "Recent Tags" \ -underline 10 .mbar.bmarks.m add -type separator .mbar.bmarks.m add -text "Page 1" \ -underline 10 .mbar.bmarks.m add -text "Page 2" \ -underline 10 blt::combobutton .mbar.tools \ -text "Tools" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.tools.m blt::combomenu .mbar.tools.m \ -width { 0 600 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.tools.m add -text "Web Search" -accelerator "Ctrl+K" \ -underline 0 .mbar.tools.m add -type separator .mbar.tools.m add -text "Downloads" -accelerator "Ctrl+Y" \ -underline 4 -icon $icon(download) .mbar.tools.m add -text "Add-ons" -underline 0 .mbar.tools.m add -type separator .mbar.tools.m add -text "PDF Download - Options" -underline 0 .mbar.tools.m add -text "Save Images From Tabs" -underline 10 .mbar.tools.m add -text "Error Console" \ -accelerator "Ctrl+Shift+J" -underline 10 .mbar.tools.m add -text "Adblock Plus Preferences..." \ -accelerator "Ctrl+Shift+E" -underline 10 .mbar.tools.m add -text "Page Info" \ -accelerator "Ctrl+I" -underline 10 .mbar.tools.m add -type separator .mbar.tools.m add -text "Clear Private Data" \ -accelerator "Ctrl+Shift+Del" -underline 10 .mbar.tools.m add -text "Batch Download Settings" \ -underline 10 blt::combobutton .mbar.help \ -text "Help" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 9 } -justify left \ -underline 0 \ -arrowon no \ -menuanchor nw \ -menu .mbar.help.m blt::combomenu .mbar.help.m \ -width { 0 600 } -font "Arial 9" -acceleratorfont "Arial 9" \ -bg grey85 -relief raised -bd 1 .mbar.help.m add -text "Help Contents" \ -underline 0 -icon $icon(help) .mbar.help.m add -text "Release Notes" -underline 0 .mbar.help.m add -text "Report Broken Website..." -underline 5 .mbar.help.m add -text "Report Web Forgery..." -underline 0 .mbar.help.m add -type separator .mbar.help.m add -text "Check For Updates..." -underline 0 .mbar.help.m add -text "About..." -underline 0 -icon $icon(about) canvas .c blt::table .mbar \ 1,0 .mbar.file -fill both \ 1,1 .mbar.edit -fill both \ 1,2 .mbar.view -fill both \ 1,3 .mbar.history -fill both \ 1,4 .mbar.bmarks -fill both \ 1,5 .mbar.tools -fill both \ 1,6 .mbar.help -fill both \ blt::table configure .mbar c* -padx 2 -resize none blt::table configure .mbar c7 -resize expand blt::table . \ 0,0 .mbar -fill x \ 1,0 .c -fill both blt::table configure . r0 -resize none blt::table configure . r1 -resize expand ��������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabset1.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000002451�11462120062�015421� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl option add *Tabset.Tab.padY 0 #option add *Tabset.Tab.background green image create picture bgTile -file ./images/chalk.gif image create picture label1 -file ./images/mini-book1.gif image create picture label2 -file ./images/mini-book2.gif image create picture label3 -width 10 -height 10 label3 blank white blt::tabset .t \ -outerrelief raised \ -tabwidth same \ -outerborderwidth 0 \ -highlightthickness 0 \ -scrollcommand { .s set } \ -closebutton yes \ -width 3i .t add First \ -image label1 \ -anchor center \ -selectbackground darkolivegreen2 foreach page { Again Next another test of a widget } { .t add $page \ -anchor center \ -selectbackground darkolivegreen2 \ -image label3 } .t add -text Again -selectbackground lightblue set tabcount 0 proc NewTab { args } { global tabcount set i [.t insert last "New Tab $tabcount"] .t select $i update .t focus $i .t see last incr tabcount } .t add "+" \ -font "Arial 10" \ -anchor center \ -selectbackground yellow \ -command NewTab blt::tk::scrollbar .s -command { .t view } -orient horizontal blt::table . \ .t 0,0 -fill both \ .s 1,0 -fill x blt::table configure . r1 -resize none focus .t �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop3.tcl������������������������������������������������������������������0000755�0001750�0001750�00000002714�11462120062�015277� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #set imgfile ./images/sample.gif set imgfile ./images/blt98.gif if { [llength $argv] > 0 } { set imgfile [lindex $argv 0] } if { [ file exists $imgfile] } { set src [image create picture -file $imgfile] } else { puts stderr "no image file" exit 0 } set name [file root [file tail $imgfile]] set width [image width $src] set height [image height $src] set filter sinc option add *Label.font *helvetica*10* option add *Label.background white label .l0 -image $src label .header0 -text "$width x $height" label .footer0 -text "100%" . configure -bg white set iw $width set ih $height set dest [image create picture -width $iw -height $ih] $dest resize $src -filter $filter label .header -text "$iw x $ih" label .footer -text "$filter" label .l1 -image $dest set filters { "bell" "bessel" "box" "bspline" "catrom" "default" "dummy" "gauss8" "gaussian" "gi" "lanczos3" "mitchell" "none" "sinc" "tent" "triangle" } proc Doit { filter } { global dest src set time [time {$dest resize $src -filter $filter}] .footer configure -text $time } set i 0 frame .f foreach f $filters { radiobutton .f.$f -variable filter -value $f -text $f \ -command "Doit $f" blt::table .f $i,0 .f.$f -anchor w incr i } blt::table . \ 0,0 .f -rspan 3 \ 0,1 .header \ 1,1 .l0 1,2 .l1 \ 2,1 .footer ����������������������������������������������������./saods9/blt3.0.1/demos/spline.tcl������������������������������������������������������������������0000755�0001750�0001750�00000002201�11462120062�015341� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl option add *graph.Element.ScaleSymbols true # test to show spline over-shooting set tcl_precision 15 # Make and fill small vectors blt::vector x y x seq 10 0 -0.5 y expr sin(x^3) x expr x*x x sort y blt::vector x2 y1 y2 y3 # make and fill (x only) large vectors x populate x2 10 # natural spline interpolation blt::spline natural x y x2 y1 # quadratic spline interpolation blt::spline quadratic x y x2 y2 # make plot blt::graph .graph .graph xaxis configure -title "x^2" -grid yes .graph yaxis configure -title "sin(y^3)" -grid yes .graph pen configure activeLine -pixels 5 .graph element create Original \ -x x -y y \ -color red4 \ -fill red \ -pixels 5 \ -symbol circle .graph element create Natural -x x2 -y y1 \ -color green4 \ -fill green \ -pixels 3 \ -symbol triangle .graph element create Quadratic -x x2 -y y2 \ -color blue4 \ -fill orange2 \ -pixels 3 \ -symbol arrow blt::table . .graph -fill both Blt_ZoomStack .graph Blt_Crosshairs .graph Blt_ActiveLegend .graph Blt_ClosestPoint .graph Blt_PrintKey .graph �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/Makefile.in�����������������������������������������������������������������0000644�0001750�0001750�00000004607�11462120062�015421� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ------------------------------------------------------------------------ # Makefile for demos # ------------------------------------------------------------------------ datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ libdir = @libdir@ prefix = @prefix@ srcdir = @srcdir@ version = @BLT_VERSION@ scriptdir = $(prefix)/lib/blt$(version) destdir = $(scriptdir)/demos SHELL = /bin/sh RM = rm -rf INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ instdirs = $(prefix) \ $(exec_prefix) \ $(libdir) \ $(scriptdir) \ $(destdir) \ $(destdir)/bitmaps \ $(destdir)/bitmaps/hand \ $(destdir)/bitmaps/fish \ $(destdir)/images \ $(destdir)/scripts demos = barchart1.tcl barchart2.tcl barchart3.tcl barchart4.tcl \ barchart5.tcl \ bgexec1.tcl bgexec2.tcl bgexec3.tcl bgexec4.tcl \ bitmap.tcl \ busy1.tcl busy2.tcl \ dnd1.tcl dnd2.tcl dragdrop1.tcl dragdrop2.tcl \ eps.tcl \ graph1.tcl graph2.tcl graph3.tcl graph4.tcl graph5.tcl \ graph6.tcl graph7.tcl \ hierbox1.tcl hierbox2.tcl hierbox3.tcl hierbox4.tcl \ hiertable1.tcl hiertable2.tcl \ htext1.tcl htext.txt \ spline.tcl stripchart1.tcl \ tabset1.tcl tabset2.tcl tabset3.tcl tabset4.tcl \ tabnotebook1.tcl tabnotebook2.tcl tabnotebook3.tcl \ treeview1.tcl \ winop1.tcl winop2.tcl all: install: mkdirs install-bitmaps install-images install-scripts install-scripts: for i in $(srcdir)/scripts/*.tcl ; do \ $(INSTALL) $$i $(DESTDIR)$(destdir)/scripts ; \ done for i in $(demos) ; do \ $(INSTALL) $(srcdir)/$$i $(DESTDIR)$(destdir)/$$i ; \ done install-bitmaps: for i in $(srcdir)/bitmaps/*.xbm ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(destdir)/bitmaps ; \ done for i in $(srcdir)/bitmaps/hand/*.xbm ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(destdir)/bitmaps/hand ; \ done for i in $(srcdir)/bitmaps/fish/*.xbm ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(destdir)/bitmaps/fish ; \ done install-images: for i in $(srcdir)/images/*.gif $(srcdir)/images/*.ps ; do \ $(INSTALL_DATA) $$i $(DESTDIR)$(destdir)/images ; \ done mkdirs: @for i in $(instdirs) ; do \ if test -d $(DESTDIR)"$$i" ; then \ : ; \ else \ echo " mkdir $(DESTDIR)$$i" ; \ mkdir $(DESTDIR)"$$i" ; \ fi ; \ done clean: $(RM) $(srcdir)/*.bak $(srcdir)/*\~ $(srcdir)/"#"* distclean: clean $(RM) *.ps Makefile �������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph4a.tab�����������������������������������������������������������������0000644�0001750�0001750�00000751476�11462120062�015407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������i 361 40 0 0 c 1 x double {} c 2 v1 double {} c 3 v2 double {} c 4 v3 double {} c 5 v4 double {} c 6 v5 double {} c 7 v6 double {} c 8 v7 double {} c 9 v8 double {} c 10 v9 double {} c 11 v10 double {} c 12 v11 double {} c 13 v12 double {} c 14 v13 double {} c 15 v14 double {} c 16 v15 double {} c 17 v16 double {} c 18 v17 double {} c 19 v18 double {} c 20 v19 double {} c 21 v20 double {} c 22 v21 double {} c 23 v22 double {} c 24 v23 double {} c 25 v24 double {} c 26 v25 double {} c 27 v26 double {} c 28 v27 double {} c 29 v28 double {} c 30 v29 double {} c 31 v30 double {} c 32 v31 double {} c 33 v32 double {} c 34 v33 double {} c 35 v34 double {} c 36 v35 double {} c 37 v36 double {} c 38 v37 double {} c 39 v38 double {} c 40 v39 double {} r 1 r1 {} r 2 r2 {} r 3 r3 {} r 4 r4 {} r 5 r5 {} r 6 r6 {} r 7 r7 {} r 8 r8 {} r 9 r9 {} r 10 r10 {} r 11 r11 {} r 12 r12 {} r 13 r13 {} r 14 r14 {} r 15 r15 {} r 16 r16 {} r 17 r17 {} r 18 r18 {} r 19 r19 {} r 20 r20 {} r 21 r21 {} r 22 r22 {} r 23 r23 {} r 24 r24 {} r 25 r25 {} r 26 r26 {} r 27 r27 {} r 28 r28 {} r 29 r29 {} r 30 r30 {} r 31 r31 {} r 32 r32 {} r 33 r33 {} r 34 r34 {} r 35 r35 {} r 36 r36 {} r 37 r37 {} r 38 r38 {} r 39 r39 {} r 40 r40 {} r 41 r41 {} r 42 r42 {} r 43 r43 {} r 44 r44 {} r 45 r45 {} r 46 r46 {} r 47 r47 {} r 48 r48 {} r 49 r49 {} r 50 r50 {} r 51 r51 {} r 52 r52 {} r 53 r53 {} r 54 r54 {} r 55 r55 {} r 56 r56 {} r 57 r57 {} r 58 r58 {} r 59 r59 {} r 60 r60 {} r 61 r61 {} r 62 r62 {} r 63 r63 {} r 64 r64 {} r 65 r65 {} r 66 r66 {} r 67 r67 {} r 68 r68 {} r 69 r69 {} r 70 r70 {} r 71 r71 {} r 72 r72 {} r 73 r73 {} r 74 r74 {} r 75 r75 {} r 76 r76 {} r 77 r77 {} r 78 r78 {} r 79 r79 {} r 80 r80 {} r 81 r81 {} r 82 r82 {} r 83 r83 {} r 84 r84 {} r 85 r85 {} r 86 r86 {} r 87 r87 {} r 88 r88 {} r 89 r89 {} r 90 r90 {} r 91 r91 {} r 92 r92 {} r 93 r93 {} r 94 r94 {} r 95 r95 {} r 96 r96 {} r 97 r97 {} r 98 r98 {} r 99 r99 {} r 100 r100 {} r 101 r101 {} r 102 r102 {} r 103 r103 {} r 104 r104 {} r 105 r105 {} r 106 r106 {} r 107 r107 {} r 108 r108 {} r 109 r109 {} r 110 r110 {} r 111 r111 {} r 112 r112 {} r 113 r113 {} r 114 r114 {} r 115 r115 {} r 116 r116 {} r 117 r117 {} r 118 r118 {} r 119 r119 {} r 120 r120 {} r 121 r121 {} r 122 r122 {} r 123 r123 {} r 124 r124 {} r 125 r125 {} r 126 r126 {} r 127 r127 {} r 128 r128 {} r 129 r129 {} r 130 r130 {} r 131 r131 {} r 132 r132 {} r 133 r133 {} r 134 r134 {} r 135 r135 {} r 136 r136 {} r 137 r137 {} r 138 r138 {} r 139 r139 {} r 140 r140 {} r 141 r141 {} r 142 r142 {} r 143 r143 {} r 144 r144 {} r 145 r145 {} r 146 r146 {} r 147 r147 {} r 148 r148 {} r 149 r149 {} r 150 r150 {} r 151 r151 {} r 152 r152 {} r 153 r153 {} r 154 r154 {} r 155 r155 {} r 156 r156 {} r 157 r157 {} r 158 r158 {} r 159 r159 {} r 160 r160 {} r 161 r161 {} r 162 r162 {} r 163 r163 {} r 164 r164 {} r 165 r165 {} r 166 r166 {} r 167 r167 {} r 168 r168 {} r 169 r169 {} r 170 r170 {} r 171 r171 {} r 172 r172 {} r 173 r173 {} r 174 r174 {} r 175 r175 {} r 176 r176 {} r 177 r177 {} r 178 r178 {} r 179 r179 {} r 180 r180 {} r 181 r181 {} r 182 r182 {} r 183 r183 {} r 184 r184 {} r 185 r185 {} r 186 r186 {} r 187 r187 {} r 188 r188 {} r 189 r189 {} r 190 r190 {} r 191 r191 {} r 192 r192 {} r 193 r193 {} r 194 r194 {} r 195 r195 {} r 196 r196 {} r 197 r197 {} r 198 r198 {} r 199 r199 {} r 200 r200 {} r 201 r201 {} r 202 r202 {} r 203 r203 {} r 204 r204 {} r 205 r205 {} r 206 r206 {} r 207 r207 {} r 208 r208 {} r 209 r209 {} r 210 r210 {} r 211 r211 {} r 212 r212 {} r 213 r213 {} r 214 r214 {} r 215 r215 {} r 216 r216 {} r 217 r217 {} r 218 r218 {} r 219 r219 {} r 220 r220 {} r 221 r221 {} r 222 r222 {} r 223 r223 {} r 224 r224 {} r 225 r225 {} r 226 r226 {} r 227 r227 {} r 228 r228 {} r 229 r229 {} r 230 r230 {} r 231 r231 {} r 232 r232 {} r 233 r233 {} r 234 r234 {} r 235 r235 {} r 236 r236 {} r 237 r237 {} r 238 r238 {} r 239 r239 {} r 240 r240 {} r 241 r241 {} r 242 r242 {} r 243 r243 {} r 244 r244 {} r 245 r245 {} r 246 r246 {} r 247 r247 {} r 248 r248 {} r 249 r249 {} r 250 r250 {} r 251 r251 {} r 252 r252 {} r 253 r253 {} r 254 r254 {} r 255 r255 {} r 256 r256 {} r 257 r257 {} r 258 r258 {} r 259 r259 {} r 260 r260 {} r 261 r261 {} r 262 r262 {} r 263 r263 {} r 264 r264 {} r 265 r265 {} r 266 r266 {} r 267 r267 {} r 268 r268 {} r 269 r269 {} r 270 r270 {} r 271 r271 {} r 272 r272 {} r 273 r273 {} r 274 r274 {} r 275 r275 {} r 276 r276 {} r 277 r277 {} r 278 r278 {} r 279 r279 {} r 280 r280 {} r 281 r281 {} r 282 r282 {} r 283 r283 {} r 284 r284 {} r 285 r285 {} r 286 r286 {} r 287 r287 {} r 288 r288 {} r 289 r289 {} r 290 r290 {} r 291 r291 {} r 292 r292 {} r 293 r293 {} r 294 r294 {} r 295 r295 {} r 296 r296 {} r 297 r297 {} r 298 r298 {} r 299 r299 {} r 300 r300 {} r 301 r301 {} r 302 r302 {} r 303 r303 {} r 304 r304 {} r 305 r305 {} r 306 r306 {} r 307 r307 {} r 308 r308 {} r 309 r309 {} r 310 r310 {} r 311 r311 {} r 312 r312 {} r 313 r313 {} r 314 r314 {} r 315 r315 {} r 316 r316 {} r 317 r317 {} r 318 r318 {} r 319 r319 {} r 320 r320 {} r 321 r321 {} r 322 r322 {} r 323 r323 {} r 324 r324 {} r 325 r325 {} r 326 r326 {} r 327 r327 {} r 328 r328 {} r 329 r329 {} r 330 r330 {} r 331 r331 {} r 332 r332 {} r 333 r333 {} r 334 r334 {} r 335 r335 {} r 336 r336 {} r 337 r337 {} r 338 r338 {} r 339 r339 {} r 340 r340 {} r 341 r341 {} r 342 r342 {} r 343 r343 {} r 344 r344 {} r 345 r345 {} r 346 r346 {} r 347 r347 {} r 348 r348 {} r 349 r349 {} r 350 r350 {} r 351 r351 {} r 352 r352 {} r 353 r353 {} r 354 r354 {} r 355 r355 {} r 356 r356 {} r 357 r357 {} r 358 r358 {} r 359 r359 {} r 360 r360 {} r 361 r361 {} d 1 1 0.0 d 2 1 1e-10 d 3 1 2e-10 d 4 1 3e-10 d 5 1 4e-10 d 6 1 5e-10 d 7 1 6e-10 d 8 1 7e-10 d 9 1 8e-10 d 10 1 9e-10 d 11 1 1e-09 d 12 1 1.1e-09 d 13 1 1.2e-09 d 14 1 1.3e-09 d 15 1 1.4e-09 d 16 1 1.5e-09 d 17 1 1.6e-09 d 18 1 1.7e-09 d 19 1 1.8e-09 d 20 1 1.9e-09 d 21 1 2e-09 d 22 1 2.1e-09 d 23 1 2.2e-09 d 24 1 2.3e-09 d 25 1 2.4e-09 d 26 1 2.5e-09 d 27 1 2.6e-09 d 28 1 2.7e-09 d 29 1 2.8e-09 d 30 1 2.9e-09 d 31 1 3e-09 d 32 1 3.1e-09 d 33 1 3.2e-09 d 34 1 3.3e-09 d 35 1 3.4e-09 d 36 1 3.5e-09 d 37 1 3.6e-09 d 38 1 3.7e-09 d 39 1 3.8e-09 d 40 1 3.9e-09 d 41 1 4e-09 d 42 1 4.1e-09 d 43 1 4.2e-09 d 44 1 4.3e-09 d 45 1 4.4e-09 d 46 1 4.5e-09 d 47 1 4.6e-09 d 48 1 4.7e-09 d 49 1 4.8e-09 d 50 1 4.9e-09 d 51 1 5e-09 d 52 1 5.1e-09 d 53 1 5.2e-09 d 54 1 5.3e-09 d 55 1 5.4e-09 d 56 1 5.5e-09 d 57 1 5.6e-09 d 58 1 5.7e-09 d 59 1 5.8e-09 d 60 1 5.9e-09 d 61 1 6e-09 d 62 1 6.1e-09 d 63 1 6.2e-09 d 64 1 6.3e-09 d 65 1 6.4e-09 d 66 1 6.5e-09 d 67 1 6.6e-09 d 68 1 6.7e-09 d 69 1 6.8e-09 d 70 1 6.9e-09 d 71 1 7e-09 d 72 1 7.1e-09 d 73 1 7.2e-09 d 74 1 7.3e-09 d 75 1 7.4e-09 d 76 1 7.5e-09 d 77 1 7.6e-09 d 78 1 7.7e-09 d 79 1 7.8e-09 d 80 1 7.9e-09 d 81 1 8e-09 d 82 1 8.1e-09 d 83 1 8.2e-09 d 84 1 8.3e-09 d 85 1 8.4e-09 d 86 1 8.5e-09 d 87 1 8.6e-09 d 88 1 8.7e-09 d 89 1 8.8e-09 d 90 1 8.9e-09 d 91 1 9e-09 d 92 1 9.1e-09 d 93 1 9.2e-09 d 94 1 9.3e-09 d 95 1 9.4e-09 d 96 1 9.5e-09 d 97 1 9.6e-09 d 98 1 9.7e-09 d 99 1 9.8e-09 d 100 1 9.9e-09 d 101 1 1e-08 d 102 1 1.01e-08 d 103 1 1.02e-08 d 104 1 1.03e-08 d 105 1 1.04e-08 d 106 1 1.05e-08 d 107 1 1.06e-08 d 108 1 1.07e-08 d 109 1 1.08e-08 d 110 1 1.09e-08 d 111 1 1.1e-08 d 112 1 1.11e-08 d 113 1 1.12e-08 d 114 1 1.13e-08 d 115 1 1.14e-08 d 116 1 1.15e-08 d 117 1 1.16e-08 d 118 1 1.17e-08 d 119 1 1.18e-08 d 120 1 1.19e-08 d 121 1 1.2e-08 d 122 1 1.21e-08 d 123 1 1.22e-08 d 124 1 1.23e-08 d 125 1 1.24e-08 d 126 1 1.25e-08 d 127 1 1.26e-08 d 128 1 1.27e-08 d 129 1 1.28e-08 d 130 1 1.29e-08 d 131 1 1.3e-08 d 132 1 1.31e-08 d 133 1 1.32e-08 d 134 1 1.33e-08 d 135 1 1.34e-08 d 136 1 1.35e-08 d 137 1 1.36e-08 d 138 1 1.37e-08 d 139 1 1.38e-08 d 140 1 1.39e-08 d 141 1 1.4e-08 d 142 1 1.41e-08 d 143 1 1.42e-08 d 144 1 1.43e-08 d 145 1 1.44e-08 d 146 1 1.45e-08 d 147 1 1.46e-08 d 148 1 1.47e-08 d 149 1 1.48e-08 d 150 1 1.49e-08 d 151 1 1.5e-08 d 152 1 1.51e-08 d 153 1 1.52e-08 d 154 1 1.53e-08 d 155 1 1.54e-08 d 156 1 1.55e-08 d 157 1 1.56e-08 d 158 1 1.57e-08 d 159 1 1.58e-08 d 160 1 1.59e-08 d 161 1 1.6e-08 d 162 1 1.61e-08 d 163 1 1.62e-08 d 164 1 1.63e-08 d 165 1 1.64e-08 d 166 1 1.65e-08 d 167 1 1.66e-08 d 168 1 1.67e-08 d 169 1 1.68e-08 d 170 1 1.69e-08 d 171 1 1.7e-08 d 172 1 1.71e-08 d 173 1 1.72e-08 d 174 1 1.73e-08 d 175 1 1.74e-08 d 176 1 1.75e-08 d 177 1 1.76e-08 d 178 1 1.77e-08 d 179 1 1.78e-08 d 180 1 1.79e-08 d 181 1 1.8e-08 d 182 1 1.81e-08 d 183 1 1.82e-08 d 184 1 1.83e-08 d 185 1 1.84e-08 d 186 1 1.85e-08 d 187 1 1.86e-08 d 188 1 1.87e-08 d 189 1 1.88e-08 d 190 1 1.89e-08 d 191 1 1.9e-08 d 192 1 1.91e-08 d 193 1 1.92e-08 d 194 1 1.93e-08 d 195 1 1.94e-08 d 196 1 1.95e-08 d 197 1 1.96e-08 d 198 1 1.97e-08 d 199 1 1.98e-08 d 200 1 1.99e-08 d 201 1 2e-08 d 202 1 2.01e-08 d 203 1 2.02e-08 d 204 1 2.03e-08 d 205 1 2.04e-08 d 206 1 2.05e-08 d 207 1 2.06e-08 d 208 1 2.07e-08 d 209 1 2.08e-08 d 210 1 2.09e-08 d 211 1 2.1e-08 d 212 1 2.11e-08 d 213 1 2.12e-08 d 214 1 2.13e-08 d 215 1 2.14e-08 d 216 1 2.15e-08 d 217 1 2.16e-08 d 218 1 2.17e-08 d 219 1 2.18e-08 d 220 1 2.19e-08 d 221 1 2.2e-08 d 222 1 2.21e-08 d 223 1 2.22e-08 d 224 1 2.23e-08 d 225 1 2.24e-08 d 226 1 2.25e-08 d 227 1 2.26e-08 d 228 1 2.27e-08 d 229 1 2.28e-08 d 230 1 2.29e-08 d 231 1 2.3e-08 d 232 1 2.31e-08 d 233 1 2.32e-08 d 234 1 2.33e-08 d 235 1 2.34e-08 d 236 1 2.35e-08 d 237 1 2.36e-08 d 238 1 2.37e-08 d 239 1 2.38e-08 d 240 1 2.39e-08 d 241 1 2.4e-08 d 242 1 2.41e-08 d 243 1 2.42e-08 d 244 1 2.43e-08 d 245 1 2.44e-08 d 246 1 2.45e-08 d 247 1 2.46e-08 d 248 1 2.47e-08 d 249 1 2.48e-08 d 250 1 2.49e-08 d 251 1 2.5e-08 d 252 1 2.51e-08 d 253 1 2.52e-08 d 254 1 2.53e-08 d 255 1 2.54e-08 d 256 1 2.55e-08 d 257 1 2.56e-08 d 258 1 2.57e-08 d 259 1 2.58e-08 d 260 1 2.59e-08 d 261 1 2.6e-08 d 262 1 2.61e-08 d 263 1 2.62e-08 d 264 1 2.63e-08 d 265 1 2.64e-08 d 266 1 2.65e-08 d 267 1 2.66e-08 d 268 1 2.67e-08 d 269 1 2.68e-08 d 270 1 2.69e-08 d 271 1 2.7e-08 d 272 1 2.71e-08 d 273 1 2.72e-08 d 274 1 2.73e-08 d 275 1 2.74e-08 d 276 1 2.75e-08 d 277 1 2.76e-08 d 278 1 2.77e-08 d 279 1 2.78e-08 d 280 1 2.79e-08 d 281 1 2.8e-08 d 282 1 2.81e-08 d 283 1 2.82e-08 d 284 1 2.83e-08 d 285 1 2.84e-08 d 286 1 2.85e-08 d 287 1 2.86e-08 d 288 1 2.87e-08 d 289 1 2.88e-08 d 290 1 2.89e-08 d 291 1 2.9e-08 d 292 1 2.91e-08 d 293 1 2.92e-08 d 294 1 2.93e-08 d 295 1 2.94e-08 d 296 1 2.95e-08 d 297 1 2.96e-08 d 298 1 2.97e-08 d 299 1 2.98e-08 d 300 1 2.99e-08 d 301 1 3e-08 d 302 1 3.01e-08 d 303 1 3.02e-08 d 304 1 3.03e-08 d 305 1 3.04e-08 d 306 1 3.05e-08 d 307 1 3.06e-08 d 308 1 3.07e-08 d 309 1 3.08e-08 d 310 1 3.09e-08 d 311 1 3.1e-08 d 312 1 3.11e-08 d 313 1 3.12e-08 d 314 1 3.13e-08 d 315 1 3.14e-08 d 316 1 3.15e-08 d 317 1 3.16e-08 d 318 1 3.17e-08 d 319 1 3.18e-08 d 320 1 3.19e-08 d 321 1 3.2e-08 d 322 1 3.21e-08 d 323 1 3.22e-08 d 324 1 3.23e-08 d 325 1 3.24e-08 d 326 1 3.25e-08 d 327 1 3.26e-08 d 328 1 3.27e-08 d 329 1 3.28e-08 d 330 1 3.29e-08 d 331 1 3.3e-08 d 332 1 3.31e-08 d 333 1 3.32e-08 d 334 1 3.33e-08 d 335 1 3.34e-08 d 336 1 3.35e-08 d 337 1 3.36e-08 d 338 1 3.37e-08 d 339 1 3.38e-08 d 340 1 3.39e-08 d 341 1 3.4e-08 d 342 1 3.41e-08 d 343 1 3.42e-08 d 344 1 3.43e-08 d 345 1 3.44e-08 d 346 1 3.45e-08 d 347 1 3.46e-08 d 348 1 3.47e-08 d 349 1 3.48e-08 d 350 1 3.49e-08 d 351 1 3.5e-08 d 352 1 3.51e-08 d 353 1 3.52e-08 d 354 1 3.53e-08 d 355 1 3.54e-08 d 356 1 3.55e-08 d 357 1 3.56e-08 d 358 1 3.57e-08 d 359 1 3.58e-08 d 360 1 3.59e-08 d 361 1 3.6e-08 d 1 2 5.0 d 2 2 5.0 d 3 2 5.0 d 4 2 5.0 d 5 2 5.0 d 6 2 5.0 d 7 2 5.0 d 8 2 5.0 d 9 2 5.0 d 10 2 5.0 d 11 2 5.0 d 12 2 5.0 d 13 2 5.0 d 14 2 5.0 d 15 2 5.0 d 16 2 5.0 d 17 2 5.0 d 18 2 5.0 d 19 2 5.0 d 20 2 5.0 d 21 2 5.0 d 22 2 5.0 d 23 2 5.0 d 24 2 5.0 d 25 2 5.0 d 26 2 5.0 d 27 2 5.0 d 28 2 5.0 d 29 2 5.0 d 30 2 5.0 d 31 2 5.0 d 32 2 5.0 d 33 2 5.0 d 34 2 5.0 d 35 2 5.0 d 36 2 5.0 d 37 2 5.0 d 38 2 5.0 d 39 2 5.0 d 40 2 5.0 d 41 2 5.0 d 42 2 5.0 d 43 2 5.0 d 44 2 5.0 d 45 2 5.0 d 46 2 5.0 d 47 2 5.0 d 48 2 5.0 d 49 2 5.0 d 50 2 5.0 d 51 2 5.0 d 52 2 5.0 d 53 2 5.0 d 54 2 5.0 d 55 2 5.0 d 56 2 5.0 d 57 2 5.0 d 58 2 5.0 d 59 2 5.0 d 60 2 5.0 d 61 2 5.0 d 62 2 5.0 d 63 2 5.0 d 64 2 5.0 d 65 2 5.0 d 66 2 5.0 d 67 2 5.0 d 68 2 5.0 d 69 2 5.0 d 70 2 5.0 d 71 2 5.0 d 72 2 5.0 d 73 2 5.0 d 74 2 5.0 d 75 2 5.0 d 76 2 5.0 d 77 2 5.0 d 78 2 5.0 d 79 2 5.0 d 80 2 5.0 d 81 2 5.0 d 82 2 5.0 d 83 2 5.0 d 84 2 5.0 d 85 2 5.0 d 86 2 5.0 d 87 2 5.0 d 88 2 5.0 d 89 2 5.0 d 90 2 5.0 d 91 2 5.0 d 92 2 5.0 d 93 2 5.0 d 94 2 5.0 d 95 2 5.0 d 96 2 5.0 d 97 2 5.0 d 98 2 5.0 d 99 2 5.0 d 100 2 5.0 d 101 2 5.0 d 102 2 5.0 d 103 2 5.0 d 104 2 5.0 d 105 2 5.0 d 106 2 5.0 d 107 2 5.0 d 108 2 5.0 d 109 2 5.0 d 110 2 5.0 d 111 2 5.0 d 112 2 5.0 d 113 2 5.0 d 114 2 5.0 d 115 2 5.0 d 116 2 5.0 d 117 2 5.0 d 118 2 5.0 d 119 2 5.0 d 120 2 5.0 d 121 2 5.0 d 122 2 5.0 d 123 2 5.0 d 124 2 5.0 d 125 2 5.0 d 126 2 5.0 d 127 2 5.0 d 128 2 5.0 d 129 2 5.0 d 130 2 5.0 d 131 2 5.0 d 132 2 5.0 d 133 2 5.0 d 134 2 5.0 d 135 2 5.0 d 136 2 5.0 d 137 2 5.0 d 138 2 5.0 d 139 2 5.0 d 140 2 5.0 d 141 2 5.0 d 142 2 5.0 d 143 2 5.0 d 144 2 5.0 d 145 2 5.0 d 146 2 5.0 d 147 2 5.0 d 148 2 5.0 d 149 2 5.0 d 150 2 5.0 d 151 2 5.0 d 152 2 5.0 d 153 2 5.0 d 154 2 5.0 d 155 2 5.0 d 156 2 5.0 d 157 2 5.0 d 158 2 5.0 d 159 2 5.0 d 160 2 5.0 d 161 2 5.0 d 162 2 5.0 d 163 2 5.0 d 164 2 5.0 d 165 2 5.0 d 166 2 5.0 d 167 2 5.0 d 168 2 5.0 d 169 2 5.0 d 170 2 5.0 d 171 2 5.0 d 172 2 5.0 d 173 2 5.0 d 174 2 5.0 d 175 2 5.0 d 176 2 5.0 d 177 2 5.0 d 178 2 5.0 d 179 2 5.0 d 180 2 5.0 d 181 2 5.0 d 182 2 5.0 d 183 2 5.0 d 184 2 5.0 d 185 2 5.0 d 186 2 5.0 d 187 2 5.0 d 188 2 5.0 d 189 2 5.0 d 190 2 5.0 d 191 2 5.0 d 192 2 5.0 d 193 2 5.0 d 194 2 5.0 d 195 2 5.0 d 196 2 5.0 d 197 2 5.0 d 198 2 5.0 d 199 2 5.0 d 200 2 5.0 d 201 2 5.0 d 202 2 5.0 d 203 2 5.0 d 204 2 5.0 d 205 2 5.0 d 206 2 5.0 d 207 2 5.0 d 208 2 5.0 d 209 2 5.0 d 210 2 5.0 d 211 2 5.0 d 212 2 5.0 d 213 2 5.0 d 214 2 5.0 d 215 2 5.0 d 216 2 5.0 d 217 2 5.0 d 218 2 5.0 d 219 2 5.0 d 220 2 5.0 d 221 2 5.0 d 222 2 5.0 d 223 2 5.0 d 224 2 5.0 d 225 2 5.0 d 226 2 5.0 d 227 2 5.0 d 228 2 5.0 d 229 2 5.0 d 230 2 5.0 d 231 2 5.0 d 232 2 5.0 d 233 2 5.0 d 234 2 5.0 d 235 2 5.0 d 236 2 5.0 d 237 2 5.0 d 238 2 5.0 d 239 2 5.0 d 240 2 5.0 d 241 2 5.0 d 242 2 5.0 d 243 2 5.0 d 244 2 5.0 d 245 2 5.0 d 246 2 5.0 d 247 2 5.0 d 248 2 5.0 d 249 2 5.0 d 250 2 5.0 d 251 2 5.0 d 252 2 5.0 d 253 2 5.0 d 254 2 5.0 d 255 2 5.0 d 256 2 5.0 d 257 2 5.0 d 258 2 5.0 d 259 2 5.0 d 260 2 5.0 d 261 2 5.0 d 262 2 5.0 d 263 2 5.0 d 264 2 5.0 d 265 2 5.0 d 266 2 5.0 d 267 2 5.0 d 268 2 5.0 d 269 2 5.0 d 270 2 5.0 d 271 2 5.0 d 272 2 5.0 d 273 2 5.0 d 274 2 5.0 d 275 2 5.0 d 276 2 5.0 d 277 2 5.0 d 278 2 5.0 d 279 2 5.0 d 280 2 5.0 d 281 2 5.0 d 282 2 5.0 d 283 2 5.0 d 284 2 5.0 d 285 2 5.0 d 286 2 5.0 d 287 2 5.0 d 288 2 5.0 d 289 2 5.0 d 290 2 5.0 d 291 2 5.0 d 292 2 5.0 d 293 2 5.0 d 294 2 5.0 d 295 2 5.0 d 296 2 5.0 d 297 2 5.0 d 298 2 5.0 d 299 2 5.0 d 300 2 5.0 d 301 2 5.0 d 302 2 5.0 d 303 2 5.0 d 304 2 5.0 d 305 2 5.0 d 306 2 5.0 d 307 2 5.0 d 308 2 5.0 d 309 2 5.0 d 310 2 5.0 d 311 2 5.0 d 312 2 5.0 d 313 2 5.0 d 314 2 5.0 d 315 2 5.0 d 316 2 5.0 d 317 2 5.0 d 318 2 5.0 d 319 2 5.0 d 320 2 5.0 d 321 2 5.0 d 322 2 5.0 d 323 2 5.0 d 324 2 5.0 d 325 2 5.0 d 326 2 5.0 d 327 2 5.0 d 328 2 5.0 d 329 2 5.0 d 330 2 5.0 d 331 2 5.0 d 332 2 5.0 d 333 2 5.0 d 334 2 5.0 d 335 2 5.0 d 336 2 5.0 d 337 2 5.0 d 338 2 5.0 d 339 2 5.0 d 340 2 5.0 d 341 2 5.0 d 342 2 5.0 d 343 2 5.0 d 344 2 5.0 d 345 2 5.0 d 346 2 5.0 d 347 2 5.0 d 348 2 5.0 d 349 2 5.0 d 350 2 5.0 d 351 2 5.0 d 352 2 5.0 d 353 2 5.0 d 354 2 5.0 d 355 2 5.0 d 356 2 5.0 d 357 2 5.0 d 358 2 5.0 d 359 2 5.0 d 360 2 5.0 d 361 2 5.0 d 1 3 0.0 d 2 3 1.0 d 3 3 2.0 d 4 3 3.0 d 5 3 4.0 d 6 3 5.0 d 7 3 5.0 d 8 3 5.0 d 9 3 5.0 d 10 3 5.0 d 11 3 5.0 d 12 3 5.0 d 13 3 5.0 d 14 3 5.0 d 15 3 5.0 d 16 3 5.0 d 17 3 4.0 d 18 3 3.0 d 19 3 2.0 d 20 3 1.0 d 21 3 0.0 d 22 3 0.0 d 23 3 0.0 d 24 3 0.0 d 25 3 0.0 d 26 3 0.0 d 27 3 0.0 d 28 3 0.0 d 29 3 0.0 d 30 3 0.0 d 31 3 0.0 d 32 3 0.0 d 33 3 0.0 d 34 3 0.0 d 35 3 0.0 d 36 3 0.0 d 37 3 0.0 d 38 3 0.0 d 39 3 0.0 d 40 3 0.0 d 41 3 0.0 d 42 3 0.0 d 43 3 0.0 d 44 3 0.0 d 45 3 0.0 d 46 3 0.0 d 47 3 0.0 d 48 3 0.0 d 49 3 0.0 d 50 3 0.0 d 51 3 0.0 d 52 3 0.0 d 53 3 0.0 d 54 3 0.0 d 55 3 0.0 d 56 3 0.0 d 57 3 0.0 d 58 3 0.0 d 59 3 0.0 d 60 3 0.0 d 61 3 0.0 d 62 3 0.0 d 63 3 0.0 d 64 3 0.0 d 65 3 0.0 d 66 3 0.0 d 67 3 0.0 d 68 3 0.0 d 69 3 0.0 d 70 3 0.0 d 71 3 0.0 d 72 3 0.0 d 73 3 0.0 d 74 3 0.0 d 75 3 0.0 d 76 3 0.0 d 77 3 0.0 d 78 3 0.0 d 79 3 0.0 d 80 3 0.0 d 81 3 0.0 d 82 3 0.0 d 83 3 0.0 d 84 3 0.0 d 85 3 0.0 d 86 3 0.0 d 87 3 0.0 d 88 3 0.0 d 89 3 0.0 d 90 3 0.0 d 91 3 0.0 d 92 3 0.0 d 93 3 0.0 d 94 3 0.0 d 95 3 0.0 d 96 3 0.0 d 97 3 0.0 d 98 3 0.0 d 99 3 0.0 d 100 3 0.0 d 101 3 0.0 d 102 3 0.0 d 103 3 0.0 d 104 3 0.0 d 105 3 0.0 d 106 3 0.0 d 107 3 0.0 d 108 3 0.0 d 109 3 0.0 d 110 3 0.0 d 111 3 0.0 d 112 3 0.0 d 113 3 0.0 d 114 3 0.0 d 115 3 0.0 d 116 3 0.0 d 117 3 0.0 d 118 3 0.0 d 119 3 0.0 d 120 3 0.0 d 121 3 0.0 d 122 3 1.0 d 123 3 2.0 d 124 3 3.0 d 125 3 4.0 d 126 3 5.0 d 127 3 5.0 d 128 3 5.0 d 129 3 5.0 d 130 3 5.0 d 131 3 5.0 d 132 3 5.0 d 133 3 5.0 d 134 3 5.0 d 135 3 5.0 d 136 3 5.0 d 137 3 4.0 d 138 3 3.0 d 139 3 2.0 d 140 3 1.0 d 141 3 5.32907e-15 d 142 3 0.0 d 143 3 0.0 d 144 3 0.0 d 145 3 0.0 d 146 3 0.0 d 147 3 0.0 d 148 3 0.0 d 149 3 0.0 d 150 3 0.0 d 151 3 0.0 d 152 3 0.0 d 153 3 0.0 d 154 3 0.0 d 155 3 0.0 d 156 3 0.0 d 157 3 0.0 d 158 3 0.0 d 159 3 0.0 d 160 3 0.0 d 161 3 0.0 d 162 3 0.0 d 163 3 0.0 d 164 3 0.0 d 165 3 0.0 d 166 3 0.0 d 167 3 0.0 d 168 3 0.0 d 169 3 0.0 d 170 3 0.0 d 171 3 0.0 d 172 3 0.0 d 173 3 0.0 d 174 3 0.0 d 175 3 0.0 d 176 3 0.0 d 177 3 0.0 d 178 3 0.0 d 179 3 0.0 d 180 3 0.0 d 181 3 0.0 d 182 3 0.0 d 183 3 0.0 d 184 3 0.0 d 185 3 0.0 d 186 3 0.0 d 187 3 0.0 d 188 3 0.0 d 189 3 0.0 d 190 3 0.0 d 191 3 0.0 d 192 3 0.0 d 193 3 0.0 d 194 3 0.0 d 195 3 0.0 d 196 3 0.0 d 197 3 0.0 d 198 3 0.0 d 199 3 0.0 d 200 3 0.0 d 201 3 0.0 d 202 3 0.0 d 203 3 0.0 d 204 3 0.0 d 205 3 0.0 d 206 3 0.0 d 207 3 0.0 d 208 3 0.0 d 209 3 0.0 d 210 3 0.0 d 211 3 0.0 d 212 3 0.0 d 213 3 0.0 d 214 3 0.0 d 215 3 0.0 d 216 3 0.0 d 217 3 0.0 d 218 3 0.0 d 219 3 0.0 d 220 3 0.0 d 221 3 0.0 d 222 3 0.0 d 223 3 0.0 d 224 3 0.0 d 225 3 0.0 d 226 3 0.0 d 227 3 0.0 d 228 3 0.0 d 229 3 0.0 d 230 3 0.0 d 231 3 0.0 d 232 3 0.0 d 233 3 0.0 d 234 3 0.0 d 235 3 0.0 d 236 3 0.0 d 237 3 0.0 d 238 3 0.0 d 239 3 0.0 d 240 3 0.0 d 241 3 0.0 d 242 3 1.0 d 243 3 2.0 d 244 3 3.0 d 245 3 4.0 d 246 3 5.0 d 247 3 5.0 d 248 3 5.0 d 249 3 5.0 d 250 3 5.0 d 251 3 5.0 d 252 3 5.0 d 253 3 5.0 d 254 3 5.0 d 255 3 5.0 d 256 3 5.0 d 257 3 4.0 d 258 3 3.0 d 259 3 2.0 d 260 3 1.0 d 261 3 0.0 d 262 3 0.0 d 263 3 0.0 d 264 3 0.0 d 265 3 0.0 d 266 3 0.0 d 267 3 0.0 d 268 3 0.0 d 269 3 0.0 d 270 3 0.0 d 271 3 0.0 d 272 3 0.0 d 273 3 0.0 d 274 3 0.0 d 275 3 0.0 d 276 3 0.0 d 277 3 0.0 d 278 3 0.0 d 279 3 0.0 d 280 3 0.0 d 281 3 0.0 d 282 3 0.0 d 283 3 0.0 d 284 3 0.0 d 285 3 0.0 d 286 3 0.0 d 287 3 0.0 d 288 3 0.0 d 289 3 0.0 d 290 3 0.0 d 291 3 0.0 d 292 3 0.0 d 293 3 0.0 d 294 3 0.0 d 295 3 0.0 d 296 3 0.0 d 297 3 0.0 d 298 3 0.0 d 299 3 0.0 d 300 3 0.0 d 301 3 0.0 d 302 3 0.0 d 303 3 0.0 d 304 3 0.0 d 305 3 0.0 d 306 3 0.0 d 307 3 0.0 d 308 3 0.0 d 309 3 0.0 d 310 3 0.0 d 311 3 0.0 d 312 3 0.0 d 313 3 0.0 d 314 3 0.0 d 315 3 0.0 d 316 3 0.0 d 317 3 0.0 d 318 3 0.0 d 319 3 0.0 d 320 3 0.0 d 321 3 0.0 d 322 3 0.0 d 323 3 0.0 d 324 3 0.0 d 325 3 0.0 d 326 3 0.0 d 327 3 0.0 d 328 3 0.0 d 329 3 0.0 d 330 3 0.0 d 331 3 0.0 d 332 3 0.0 d 333 3 0.0 d 334 3 0.0 d 335 3 0.0 d 336 3 0.0 d 337 3 0.0 d 338 3 0.0 d 339 3 0.0 d 340 3 0.0 d 341 3 0.0 d 342 3 0.0 d 343 3 0.0 d 344 3 0.0 d 345 3 0.0 d 346 3 0.0 d 347 3 0.0 d 348 3 0.0 d 349 3 0.0 d 350 3 0.0 d 351 3 0.0 d 352 3 0.0 d 353 3 0.0 d 354 3 0.0 d 355 3 0.0 d 356 3 0.0 d 357 3 0.0 d 358 3 0.0 d 359 3 0.0 d 360 3 0.0 d 361 3 0.0 d 1 4 5.0 d 2 4 5.0 d 3 4 5.0 d 4 4 5.0 d 5 4 5.0 d 6 4 5.0 d 7 4 5.0 d 8 4 5.0 d 9 4 5.0 d 10 4 5.0 d 11 4 5.0 d 12 4 5.0 d 13 4 5.0 d 14 4 5.0 d 15 4 5.0 d 16 4 5.0 d 17 4 5.0 d 18 4 5.0 d 19 4 5.0 d 20 4 5.0 d 21 4 5.0 d 22 4 4.0 d 23 4 3.0 d 24 4 2.0 d 25 4 1.0 d 26 4 8.88178e-16 d 27 4 0.0 d 28 4 0.0 d 29 4 0.0 d 30 4 0.0 d 31 4 0.0 d 32 4 0.0 d 33 4 0.0 d 34 4 0.0 d 35 4 0.0 d 36 4 0.0 d 37 4 0.0 d 38 4 0.0 d 39 4 0.0 d 40 4 0.0 d 41 4 0.0 d 42 4 0.0 d 43 4 0.0 d 44 4 0.0 d 45 4 0.0 d 46 4 0.0 d 47 4 0.0 d 48 4 0.0 d 49 4 0.0 d 50 4 0.0 d 51 4 0.0 d 52 4 0.0 d 53 4 0.0 d 54 4 0.0 d 55 4 0.0 d 56 4 0.0 d 57 4 0.0 d 58 4 0.0 d 59 4 0.0 d 60 4 0.0 d 61 4 0.0 d 62 4 0.0 d 63 4 0.0 d 64 4 0.0 d 65 4 0.0 d 66 4 0.0 d 67 4 0.0 d 68 4 0.0 d 69 4 0.0 d 70 4 0.0 d 71 4 0.0 d 72 4 0.0 d 73 4 0.0 d 74 4 0.0 d 75 4 0.0 d 76 4 0.0 d 77 4 0.0 d 78 4 0.0 d 79 4 0.0 d 80 4 0.0 d 81 4 0.0 d 82 4 0.0 d 83 4 0.0 d 84 4 0.0 d 85 4 0.0 d 86 4 0.0 d 87 4 0.0 d 88 4 0.0 d 89 4 0.0 d 90 4 0.0 d 91 4 0.0 d 92 4 0.0 d 93 4 0.0 d 94 4 0.0 d 95 4 0.0 d 96 4 0.0 d 97 4 0.0 d 98 4 0.0 d 99 4 0.0 d 100 4 0.0 d 101 4 0.0 d 102 4 0.0 d 103 4 0.0 d 104 4 0.0 d 105 4 0.0 d 106 4 0.0 d 107 4 0.0 d 108 4 0.0 d 109 4 0.0 d 110 4 0.0 d 111 4 0.0 d 112 4 0.0 d 113 4 0.0 d 114 4 0.0 d 115 4 0.0 d 116 4 0.0 d 117 4 0.0 d 118 4 0.0 d 119 4 0.0 d 120 4 0.0 d 121 4 0.0 d 122 4 0.0 d 123 4 0.0 d 124 4 0.0 d 125 4 0.0 d 126 4 0.0 d 127 4 0.0 d 128 4 0.0 d 129 4 0.0 d 130 4 0.0 d 131 4 0.0 d 132 4 0.0 d 133 4 0.0 d 134 4 0.0 d 135 4 0.0 d 136 4 0.0 d 137 4 0.0 d 138 4 0.0 d 139 4 0.0 d 140 4 0.0 d 141 4 0.0 d 142 4 1.0 d 143 4 2.0 d 144 4 3.0 d 145 4 4.0 d 146 4 5.0 d 147 4 5.0 d 148 4 5.0 d 149 4 5.0 d 150 4 5.0 d 151 4 5.0 d 152 4 5.0 d 153 4 5.0 d 154 4 5.0 d 155 4 5.0 d 156 4 5.0 d 157 4 5.0 d 158 4 5.0 d 159 4 5.0 d 160 4 5.0 d 161 4 5.0 d 162 4 5.0 d 163 4 5.0 d 164 4 5.0 d 165 4 5.0 d 166 4 5.0 d 167 4 5.0 d 168 4 5.0 d 169 4 5.0 d 170 4 5.0 d 171 4 5.0 d 172 4 5.0 d 173 4 5.0 d 174 4 5.0 d 175 4 5.0 d 176 4 5.0 d 177 4 5.0 d 178 4 5.0 d 179 4 5.0 d 180 4 5.0 d 181 4 5.0 d 182 4 5.0 d 183 4 5.0 d 184 4 5.0 d 185 4 5.0 d 186 4 5.0 d 187 4 5.0 d 188 4 5.0 d 189 4 5.0 d 190 4 5.0 d 191 4 5.0 d 192 4 5.0 d 193 4 5.0 d 194 4 5.0 d 195 4 5.0 d 196 4 5.0 d 197 4 5.0 d 198 4 5.0 d 199 4 5.0 d 200 4 5.0 d 201 4 5.0 d 202 4 5.0 d 203 4 5.0 d 204 4 5.0 d 205 4 5.0 d 206 4 5.0 d 207 4 5.0 d 208 4 5.0 d 209 4 5.0 d 210 4 5.0 d 211 4 5.0 d 212 4 5.0 d 213 4 5.0 d 214 4 5.0 d 215 4 5.0 d 216 4 5.0 d 217 4 5.0 d 218 4 5.0 d 219 4 5.0 d 220 4 5.0 d 221 4 5.0 d 222 4 5.0 d 223 4 5.0 d 224 4 5.0 d 225 4 5.0 d 226 4 5.0 d 227 4 5.0 d 228 4 5.0 d 229 4 5.0 d 230 4 5.0 d 231 4 5.0 d 232 4 5.0 d 233 4 5.0 d 234 4 5.0 d 235 4 5.0 d 236 4 5.0 d 237 4 5.0 d 238 4 5.0 d 239 4 5.0 d 240 4 5.0 d 241 4 5.0 d 242 4 5.0 d 243 4 5.0 d 244 4 5.0 d 245 4 5.0 d 246 4 5.0 d 247 4 5.0 d 248 4 5.0 d 249 4 5.0 d 250 4 5.0 d 251 4 5.0 d 252 4 5.0 d 253 4 5.0 d 254 4 5.0 d 255 4 5.0 d 256 4 5.0 d 257 4 5.0 d 258 4 5.0 d 259 4 5.0 d 260 4 5.0 d 261 4 5.0 d 262 4 4.0 d 263 4 3.0 d 264 4 2.0 d 265 4 1.0 d 266 4 2.13718e-14 d 267 4 0.0 d 268 4 0.0 d 269 4 0.0 d 270 4 0.0 d 271 4 0.0 d 272 4 0.0 d 273 4 0.0 d 274 4 0.0 d 275 4 0.0 d 276 4 0.0 d 277 4 0.0 d 278 4 0.0 d 279 4 0.0 d 280 4 0.0 d 281 4 0.0 d 282 4 0.0 d 283 4 0.0 d 284 4 0.0 d 285 4 0.0 d 286 4 0.0 d 287 4 0.0 d 288 4 0.0 d 289 4 0.0 d 290 4 0.0 d 291 4 0.0 d 292 4 0.0 d 293 4 0.0 d 294 4 0.0 d 295 4 0.0 d 296 4 0.0 d 297 4 0.0 d 298 4 0.0 d 299 4 0.0 d 300 4 0.0 d 301 4 0.0 d 302 4 0.0 d 303 4 0.0 d 304 4 0.0 d 305 4 0.0 d 306 4 0.0 d 307 4 0.0 d 308 4 0.0 d 309 4 0.0 d 310 4 0.0 d 311 4 0.0 d 312 4 0.0 d 313 4 0.0 d 314 4 0.0 d 315 4 0.0 d 316 4 0.0 d 317 4 0.0 d 318 4 0.0 d 319 4 0.0 d 320 4 0.0 d 321 4 0.0 d 322 4 0.0 d 323 4 0.0 d 324 4 0.0 d 325 4 0.0 d 326 4 0.0 d 327 4 0.0 d 328 4 0.0 d 329 4 0.0 d 330 4 0.0 d 331 4 0.0 d 332 4 0.0 d 333 4 0.0 d 334 4 0.0 d 335 4 0.0 d 336 4 0.0 d 337 4 0.0 d 338 4 0.0 d 339 4 0.0 d 340 4 0.0 d 341 4 0.0 d 342 4 0.0 d 343 4 0.0 d 344 4 0.0 d 345 4 0.0 d 346 4 0.0 d 347 4 0.0 d 348 4 0.0 d 349 4 0.0 d 350 4 0.0 d 351 4 0.0 d 352 4 0.0 d 353 4 0.0 d 354 4 0.0 d 355 4 0.0 d 356 4 0.0 d 357 4 0.0 d 358 4 0.0 d 359 4 0.0 d 360 4 0.0 d 361 4 0.0 d 1 5 0.0 d 2 5 0.0 d 3 5 0.0 d 4 5 0.0 d 5 5 0.0 d 6 5 0.0 d 7 5 0.0 d 8 5 0.0 d 9 5 0.0 d 10 5 0.0 d 11 5 0.0 d 12 5 0.0 d 13 5 0.0 d 14 5 0.0 d 15 5 0.0 d 16 5 0.0 d 17 5 0.0 d 18 5 0.0 d 19 5 0.0 d 20 5 0.0 d 21 5 0.0 d 22 5 1.0 d 23 5 2.0 d 24 5 3.0 d 25 5 4.0 d 26 5 5.0 d 27 5 5.0 d 28 5 5.0 d 29 5 5.0 d 30 5 5.0 d 31 5 5.0 d 32 5 5.0 d 33 5 5.0 d 34 5 5.0 d 35 5 5.0 d 36 5 5.0 d 37 5 5.0 d 38 5 5.0 d 39 5 5.0 d 40 5 5.0 d 41 5 5.0 d 42 5 5.0 d 43 5 5.0 d 44 5 5.0 d 45 5 5.0 d 46 5 5.0 d 47 5 5.0 d 48 5 5.0 d 49 5 5.0 d 50 5 5.0 d 51 5 5.0 d 52 5 5.0 d 53 5 5.0 d 54 5 5.0 d 55 5 5.0 d 56 5 5.0 d 57 5 5.0 d 58 5 5.0 d 59 5 5.0 d 60 5 5.0 d 61 5 5.0 d 62 5 5.0 d 63 5 5.0 d 64 5 5.0 d 65 5 5.0 d 66 5 5.0 d 67 5 5.0 d 68 5 5.0 d 69 5 5.0 d 70 5 5.0 d 71 5 5.0 d 72 5 5.0 d 73 5 5.0 d 74 5 5.0 d 75 5 5.0 d 76 5 5.0 d 77 5 5.0 d 78 5 5.0 d 79 5 5.0 d 80 5 5.0 d 81 5 5.0 d 82 5 5.0 d 83 5 5.0 d 84 5 5.0 d 85 5 5.0 d 86 5 5.0 d 87 5 5.0 d 88 5 5.0 d 89 5 5.0 d 90 5 5.0 d 91 5 5.0 d 92 5 5.0 d 93 5 5.0 d 94 5 5.0 d 95 5 5.0 d 96 5 5.0 d 97 5 5.0 d 98 5 5.0 d 99 5 5.0 d 100 5 5.0 d 101 5 5.0 d 102 5 5.0 d 103 5 5.0 d 104 5 5.0 d 105 5 5.0 d 106 5 5.0 d 107 5 5.0 d 108 5 5.0 d 109 5 5.0 d 110 5 5.0 d 111 5 5.0 d 112 5 5.0 d 113 5 5.0 d 114 5 5.0 d 115 5 5.0 d 116 5 5.0 d 117 5 5.0 d 118 5 5.0 d 119 5 5.0 d 120 5 5.0 d 121 5 5.0 d 122 5 5.0 d 123 5 5.0 d 124 5 5.0 d 125 5 5.0 d 126 5 5.0 d 127 5 5.0 d 128 5 5.0 d 129 5 5.0 d 130 5 5.0 d 131 5 5.0 d 132 5 5.0 d 133 5 5.0 d 134 5 5.0 d 135 5 5.0 d 136 5 5.0 d 137 5 5.0 d 138 5 5.0 d 139 5 5.0 d 140 5 5.0 d 141 5 5.0 d 142 5 4.0 d 143 5 3.0 d 144 5 2.0 d 145 5 1.0 d 146 5 0.0 d 147 5 0.0 d 148 5 0.0 d 149 5 0.0 d 150 5 0.0 d 151 5 0.0 d 152 5 0.0 d 153 5 0.0 d 154 5 0.0 d 155 5 0.0 d 156 5 0.0 d 157 5 0.0 d 158 5 0.0 d 159 5 0.0 d 160 5 0.0 d 161 5 0.0 d 162 5 0.0 d 163 5 0.0 d 164 5 0.0 d 165 5 0.0 d 166 5 0.0 d 167 5 0.0 d 168 5 0.0 d 169 5 0.0 d 170 5 0.0 d 171 5 0.0 d 172 5 0.0 d 173 5 0.0 d 174 5 0.0 d 175 5 0.0 d 176 5 0.0 d 177 5 0.0 d 178 5 0.0 d 179 5 0.0 d 180 5 0.0 d 181 5 0.0 d 182 5 0.0 d 183 5 0.0 d 184 5 0.0 d 185 5 0.0 d 186 5 0.0 d 187 5 0.0 d 188 5 0.0 d 189 5 0.0 d 190 5 0.0 d 191 5 0.0 d 192 5 0.0 d 193 5 0.0 d 194 5 0.0 d 195 5 0.0 d 196 5 0.0 d 197 5 0.0 d 198 5 0.0 d 199 5 0.0 d 200 5 0.0 d 201 5 0.0 d 202 5 0.0 d 203 5 0.0 d 204 5 0.0 d 205 5 0.0 d 206 5 0.0 d 207 5 0.0 d 208 5 0.0 d 209 5 0.0 d 210 5 0.0 d 211 5 0.0 d 212 5 0.0 d 213 5 0.0 d 214 5 0.0 d 215 5 0.0 d 216 5 0.0 d 217 5 0.0 d 218 5 0.0 d 219 5 0.0 d 220 5 0.0 d 221 5 0.0 d 222 5 0.0 d 223 5 0.0 d 224 5 0.0 d 225 5 0.0 d 226 5 0.0 d 227 5 0.0 d 228 5 0.0 d 229 5 0.0 d 230 5 0.0 d 231 5 0.0 d 232 5 0.0 d 233 5 0.0 d 234 5 0.0 d 235 5 0.0 d 236 5 0.0 d 237 5 0.0 d 238 5 0.0 d 239 5 0.0 d 240 5 0.0 d 241 5 0.0 d 242 5 0.0 d 243 5 0.0 d 244 5 0.0 d 245 5 0.0 d 246 5 0.0 d 247 5 0.0 d 248 5 0.0 d 249 5 0.0 d 250 5 0.0 d 251 5 0.0 d 252 5 0.0 d 253 5 0.0 d 254 5 0.0 d 255 5 0.0 d 256 5 0.0 d 257 5 0.0 d 258 5 0.0 d 259 5 0.0 d 260 5 0.0 d 261 5 0.0 d 262 5 1.0 d 263 5 2.0 d 264 5 3.0 d 265 5 4.0 d 266 5 5.0 d 267 5 5.0 d 268 5 5.0 d 269 5 5.0 d 270 5 5.0 d 271 5 5.0 d 272 5 5.0 d 273 5 5.0 d 274 5 5.0 d 275 5 5.0 d 276 5 5.0 d 277 5 5.0 d 278 5 5.0 d 279 5 5.0 d 280 5 5.0 d 281 5 5.0 d 282 5 5.0 d 283 5 5.0 d 284 5 5.0 d 285 5 5.0 d 286 5 5.0 d 287 5 5.0 d 288 5 5.0 d 289 5 5.0 d 290 5 5.0 d 291 5 5.0 d 292 5 5.0 d 293 5 5.0 d 294 5 5.0 d 295 5 5.0 d 296 5 5.0 d 297 5 5.0 d 298 5 5.0 d 299 5 5.0 d 300 5 5.0 d 301 5 5.0 d 302 5 5.0 d 303 5 5.0 d 304 5 5.0 d 305 5 5.0 d 306 5 5.0 d 307 5 5.0 d 308 5 5.0 d 309 5 5.0 d 310 5 5.0 d 311 5 5.0 d 312 5 5.0 d 313 5 5.0 d 314 5 5.0 d 315 5 5.0 d 316 5 5.0 d 317 5 5.0 d 318 5 5.0 d 319 5 5.0 d 320 5 5.0 d 321 5 5.0 d 322 5 5.0 d 323 5 5.0 d 324 5 5.0 d 325 5 5.0 d 326 5 5.0 d 327 5 5.0 d 328 5 5.0 d 329 5 5.0 d 330 5 5.0 d 331 5 5.0 d 332 5 5.0 d 333 5 5.0 d 334 5 5.0 d 335 5 5.0 d 336 5 5.0 d 337 5 5.0 d 338 5 5.0 d 339 5 5.0 d 340 5 5.0 d 341 5 5.0 d 342 5 5.0 d 343 5 5.0 d 344 5 5.0 d 345 5 5.0 d 346 5 5.0 d 347 5 5.0 d 348 5 5.0 d 349 5 5.0 d 350 5 5.0 d 351 5 5.0 d 352 5 5.0 d 353 5 5.0 d 354 5 5.0 d 355 5 5.0 d 356 5 5.0 d 357 5 5.0 d 358 5 5.0 d 359 5 5.0 d 360 5 5.0 d 361 5 5.0 d 1 6 0.0 d 2 6 0.0 d 3 6 0.0 d 4 6 0.0 d 5 6 0.0 d 6 6 0.0 d 7 6 0.0 d 8 6 0.0 d 9 6 0.0 d 10 6 0.0 d 11 6 0.0 d 12 6 0.0 d 13 6 0.0 d 14 6 0.0 d 15 6 0.0 d 16 6 0.0 d 17 6 0.0 d 18 6 0.0 d 19 6 0.0 d 20 6 0.0 d 21 6 0.0 d 22 6 1.0 d 23 6 2.0 d 24 6 3.0 d 25 6 4.0 d 26 6 5.0 d 27 6 5.0 d 28 6 5.0 d 29 6 5.0 d 30 6 5.0 d 31 6 5.0 d 32 6 5.0 d 33 6 5.0 d 34 6 5.0 d 35 6 5.0 d 36 6 5.0 d 37 6 5.0 d 38 6 5.0 d 39 6 5.0 d 40 6 5.0 d 41 6 5.0 d 42 6 5.0 d 43 6 5.0 d 44 6 5.0 d 45 6 5.0 d 46 6 5.0 d 47 6 5.0 d 48 6 5.0 d 49 6 5.0 d 50 6 5.0 d 51 6 5.0 d 52 6 5.0 d 53 6 5.0 d 54 6 5.0 d 55 6 5.0 d 56 6 5.0 d 57 6 5.0 d 58 6 5.0 d 59 6 5.0 d 60 6 5.0 d 61 6 5.0 d 62 6 5.0 d 63 6 5.0 d 64 6 5.0 d 65 6 5.0 d 66 6 5.0 d 67 6 5.0 d 68 6 5.0 d 69 6 5.0 d 70 6 5.0 d 71 6 5.0 d 72 6 5.0 d 73 6 5.0 d 74 6 5.0 d 75 6 5.0 d 76 6 5.0 d 77 6 5.0 d 78 6 5.0 d 79 6 5.0 d 80 6 5.0 d 81 6 5.0 d 82 6 5.0 d 83 6 5.0 d 84 6 5.0 d 85 6 5.0 d 86 6 5.0 d 87 6 5.0 d 88 6 5.0 d 89 6 5.0 d 90 6 5.0 d 91 6 5.0 d 92 6 5.0 d 93 6 5.0 d 94 6 5.0 d 95 6 5.0 d 96 6 5.0 d 97 6 5.0 d 98 6 5.0 d 99 6 5.0 d 100 6 5.0 d 101 6 5.0 d 102 6 5.0 d 103 6 5.0 d 104 6 5.0 d 105 6 5.0 d 106 6 5.0 d 107 6 5.0 d 108 6 5.0 d 109 6 5.0 d 110 6 5.0 d 111 6 5.0 d 112 6 5.0 d 113 6 5.0 d 114 6 5.0 d 115 6 5.0 d 116 6 5.0 d 117 6 5.0 d 118 6 5.0 d 119 6 5.0 d 120 6 5.0 d 121 6 5.0 d 122 6 5.0 d 123 6 5.0 d 124 6 5.0 d 125 6 5.0 d 126 6 5.0 d 127 6 5.0 d 128 6 5.0 d 129 6 5.0 d 130 6 5.0 d 131 6 5.0 d 132 6 5.0 d 133 6 5.0 d 134 6 5.0 d 135 6 5.0 d 136 6 5.0 d 137 6 5.0 d 138 6 5.0 d 139 6 5.0 d 140 6 5.0 d 141 6 5.0 d 142 6 4.0 d 143 6 3.0 d 144 6 2.0 d 145 6 1.0 d 146 6 0.0 d 147 6 0.0 d 148 6 0.0 d 149 6 0.0 d 150 6 0.0 d 151 6 0.0 d 152 6 0.0 d 153 6 0.0 d 154 6 0.0 d 155 6 0.0 d 156 6 0.0 d 157 6 0.0 d 158 6 0.0 d 159 6 0.0 d 160 6 0.0 d 161 6 0.0 d 162 6 0.0 d 163 6 0.0 d 164 6 0.0 d 165 6 0.0 d 166 6 0.0 d 167 6 0.0 d 168 6 0.0 d 169 6 0.0 d 170 6 0.0 d 171 6 0.0 d 172 6 0.0 d 173 6 0.0 d 174 6 0.0 d 175 6 0.0 d 176 6 0.0 d 177 6 0.0 d 178 6 0.0 d 179 6 0.0 d 180 6 0.0 d 181 6 0.0 d 182 6 0.0 d 183 6 0.0 d 184 6 0.0 d 185 6 0.0 d 186 6 0.0 d 187 6 0.0 d 188 6 0.0 d 189 6 0.0 d 190 6 0.0 d 191 6 0.0 d 192 6 0.0 d 193 6 0.0 d 194 6 0.0 d 195 6 0.0 d 196 6 0.0 d 197 6 0.0 d 198 6 0.0 d 199 6 0.0 d 200 6 0.0 d 201 6 0.0 d 202 6 0.0 d 203 6 0.0 d 204 6 0.0 d 205 6 0.0 d 206 6 0.0 d 207 6 0.0 d 208 6 0.0 d 209 6 0.0 d 210 6 0.0 d 211 6 0.0 d 212 6 0.0 d 213 6 0.0 d 214 6 0.0 d 215 6 0.0 d 216 6 0.0 d 217 6 0.0 d 218 6 0.0 d 219 6 0.0 d 220 6 0.0 d 221 6 0.0 d 222 6 0.0 d 223 6 0.0 d 224 6 0.0 d 225 6 0.0 d 226 6 0.0 d 227 6 0.0 d 228 6 0.0 d 229 6 0.0 d 230 6 0.0 d 231 6 0.0 d 232 6 0.0 d 233 6 0.0 d 234 6 0.0 d 235 6 0.0 d 236 6 0.0 d 237 6 0.0 d 238 6 0.0 d 239 6 0.0 d 240 6 0.0 d 241 6 0.0 d 242 6 0.0 d 243 6 0.0 d 244 6 0.0 d 245 6 0.0 d 246 6 0.0 d 247 6 0.0 d 248 6 0.0 d 249 6 0.0 d 250 6 0.0 d 251 6 0.0 d 252 6 0.0 d 253 6 0.0 d 254 6 0.0 d 255 6 0.0 d 256 6 0.0 d 257 6 0.0 d 258 6 0.0 d 259 6 0.0 d 260 6 0.0 d 261 6 0.0 d 262 6 1.0 d 263 6 2.0 d 264 6 3.0 d 265 6 4.0 d 266 6 5.0 d 267 6 5.0 d 268 6 5.0 d 269 6 5.0 d 270 6 5.0 d 271 6 5.0 d 272 6 5.0 d 273 6 5.0 d 274 6 5.0 d 275 6 5.0 d 276 6 5.0 d 277 6 5.0 d 278 6 5.0 d 279 6 5.0 d 280 6 5.0 d 281 6 5.0 d 282 6 5.0 d 283 6 5.0 d 284 6 5.0 d 285 6 5.0 d 286 6 5.0 d 287 6 5.0 d 288 6 5.0 d 289 6 5.0 d 290 6 5.0 d 291 6 5.0 d 292 6 5.0 d 293 6 5.0 d 294 6 5.0 d 295 6 5.0 d 296 6 5.0 d 297 6 5.0 d 298 6 5.0 d 299 6 5.0 d 300 6 5.0 d 301 6 5.0 d 302 6 5.0 d 303 6 5.0 d 304 6 5.0 d 305 6 5.0 d 306 6 5.0 d 307 6 5.0 d 308 6 5.0 d 309 6 5.0 d 310 6 5.0 d 311 6 5.0 d 312 6 5.0 d 313 6 5.0 d 314 6 5.0 d 315 6 5.0 d 316 6 5.0 d 317 6 5.0 d 318 6 5.0 d 319 6 5.0 d 320 6 5.0 d 321 6 5.0 d 322 6 5.0 d 323 6 5.0 d 324 6 5.0 d 325 6 5.0 d 326 6 5.0 d 327 6 5.0 d 328 6 5.0 d 329 6 5.0 d 330 6 5.0 d 331 6 5.0 d 332 6 5.0 d 333 6 5.0 d 334 6 5.0 d 335 6 5.0 d 336 6 5.0 d 337 6 5.0 d 338 6 5.0 d 339 6 5.0 d 340 6 5.0 d 341 6 5.0 d 342 6 5.0 d 343 6 5.0 d 344 6 5.0 d 345 6 5.0 d 346 6 5.0 d 347 6 5.0 d 348 6 5.0 d 349 6 5.0 d 350 6 5.0 d 351 6 5.0 d 352 6 5.0 d 353 6 5.0 d 354 6 5.0 d 355 6 5.0 d 356 6 5.0 d 357 6 5.0 d 358 6 5.0 d 359 6 5.0 d 360 6 5.0 d 361 6 5.0 d 1 7 5.0 d 2 7 5.0 d 3 7 5.0 d 4 7 5.0 d 5 7 5.0 d 6 7 5.0 d 7 7 5.0 d 8 7 5.0 d 9 7 5.0 d 10 7 5.0 d 11 7 5.0 d 12 7 5.0 d 13 7 5.0 d 14 7 5.0 d 15 7 5.0 d 16 7 5.0 d 17 7 5.0 d 18 7 5.0 d 19 7 5.0 d 20 7 5.0 d 21 7 5.0 d 22 7 4.0 d 23 7 3.0 d 24 7 2.0 d 25 7 1.0 d 26 7 8.88178e-16 d 27 7 0.0 d 28 7 0.0 d 29 7 0.0 d 30 7 0.0 d 31 7 0.0 d 32 7 0.0 d 33 7 0.0 d 34 7 0.0 d 35 7 0.0 d 36 7 0.0 d 37 7 0.0 d 38 7 0.0 d 39 7 0.0 d 40 7 0.0 d 41 7 0.0 d 42 7 0.0 d 43 7 0.0 d 44 7 0.0 d 45 7 0.0 d 46 7 0.0 d 47 7 0.0 d 48 7 0.0 d 49 7 0.0 d 50 7 0.0 d 51 7 0.0 d 52 7 0.0 d 53 7 0.0 d 54 7 0.0 d 55 7 0.0 d 56 7 0.0 d 57 7 0.0 d 58 7 0.0 d 59 7 0.0 d 60 7 0.0 d 61 7 0.0 d 62 7 0.0 d 63 7 0.0 d 64 7 0.0 d 65 7 0.0 d 66 7 0.0 d 67 7 0.0 d 68 7 0.0 d 69 7 0.0 d 70 7 0.0 d 71 7 0.0 d 72 7 0.0 d 73 7 0.0 d 74 7 0.0 d 75 7 0.0 d 76 7 0.0 d 77 7 0.0 d 78 7 0.0 d 79 7 0.0 d 80 7 0.0 d 81 7 0.0 d 82 7 0.0 d 83 7 0.0 d 84 7 0.0 d 85 7 0.0 d 86 7 0.0 d 87 7 0.0 d 88 7 0.0 d 89 7 0.0 d 90 7 0.0 d 91 7 0.0 d 92 7 0.0 d 93 7 0.0 d 94 7 0.0 d 95 7 0.0 d 96 7 0.0 d 97 7 0.0 d 98 7 0.0 d 99 7 0.0 d 100 7 0.0 d 101 7 0.0 d 102 7 0.0 d 103 7 0.0 d 104 7 0.0 d 105 7 0.0 d 106 7 0.0 d 107 7 0.0 d 108 7 0.0 d 109 7 0.0 d 110 7 0.0 d 111 7 0.0 d 112 7 0.0 d 113 7 0.0 d 114 7 0.0 d 115 7 0.0 d 116 7 0.0 d 117 7 0.0 d 118 7 0.0 d 119 7 0.0 d 120 7 0.0 d 121 7 0.0 d 122 7 0.0 d 123 7 0.0 d 124 7 0.0 d 125 7 0.0 d 126 7 0.0 d 127 7 0.0 d 128 7 0.0 d 129 7 0.0 d 130 7 0.0 d 131 7 0.0 d 132 7 0.0 d 133 7 0.0 d 134 7 0.0 d 135 7 0.0 d 136 7 0.0 d 137 7 0.0 d 138 7 0.0 d 139 7 0.0 d 140 7 0.0 d 141 7 0.0 d 142 7 1.0 d 143 7 2.0 d 144 7 3.0 d 145 7 4.0 d 146 7 5.0 d 147 7 5.0 d 148 7 5.0 d 149 7 5.0 d 150 7 5.0 d 151 7 5.0 d 152 7 5.0 d 153 7 5.0 d 154 7 5.0 d 155 7 5.0 d 156 7 5.0 d 157 7 5.0 d 158 7 5.0 d 159 7 5.0 d 160 7 5.0 d 161 7 5.0 d 162 7 5.0 d 163 7 5.0 d 164 7 5.0 d 165 7 5.0 d 166 7 5.0 d 167 7 5.0 d 168 7 5.0 d 169 7 5.0 d 170 7 5.0 d 171 7 5.0 d 172 7 5.0 d 173 7 5.0 d 174 7 5.0 d 175 7 5.0 d 176 7 5.0 d 177 7 5.0 d 178 7 5.0 d 179 7 5.0 d 180 7 5.0 d 181 7 5.0 d 182 7 5.0 d 183 7 5.0 d 184 7 5.0 d 185 7 5.0 d 186 7 5.0 d 187 7 5.0 d 188 7 5.0 d 189 7 5.0 d 190 7 5.0 d 191 7 5.0 d 192 7 5.0 d 193 7 5.0 d 194 7 5.0 d 195 7 5.0 d 196 7 5.0 d 197 7 5.0 d 198 7 5.0 d 199 7 5.0 d 200 7 5.0 d 201 7 5.0 d 202 7 5.0 d 203 7 5.0 d 204 7 5.0 d 205 7 5.0 d 206 7 5.0 d 207 7 5.0 d 208 7 5.0 d 209 7 5.0 d 210 7 5.0 d 211 7 5.0 d 212 7 5.0 d 213 7 5.0 d 214 7 5.0 d 215 7 5.0 d 216 7 5.0 d 217 7 5.0 d 218 7 5.0 d 219 7 5.0 d 220 7 5.0 d 221 7 5.0 d 222 7 5.0 d 223 7 5.0 d 224 7 5.0 d 225 7 5.0 d 226 7 5.0 d 227 7 5.0 d 228 7 5.0 d 229 7 5.0 d 230 7 5.0 d 231 7 5.0 d 232 7 5.0 d 233 7 5.0 d 234 7 5.0 d 235 7 5.0 d 236 7 5.0 d 237 7 5.0 d 238 7 5.0 d 239 7 5.0 d 240 7 5.0 d 241 7 5.0 d 242 7 5.0 d 243 7 5.0 d 244 7 5.0 d 245 7 5.0 d 246 7 5.0 d 247 7 5.0 d 248 7 5.0 d 249 7 5.0 d 250 7 5.0 d 251 7 5.0 d 252 7 5.0 d 253 7 5.0 d 254 7 5.0 d 255 7 5.0 d 256 7 5.0 d 257 7 5.0 d 258 7 5.0 d 259 7 5.0 d 260 7 5.0 d 261 7 5.0 d 262 7 4.0 d 263 7 3.0 d 264 7 2.0 d 265 7 1.0 d 266 7 2.13718e-14 d 267 7 0.0 d 268 7 0.0 d 269 7 0.0 d 270 7 0.0 d 271 7 0.0 d 272 7 0.0 d 273 7 0.0 d 274 7 0.0 d 275 7 0.0 d 276 7 0.0 d 277 7 0.0 d 278 7 0.0 d 279 7 0.0 d 280 7 0.0 d 281 7 0.0 d 282 7 0.0 d 283 7 0.0 d 284 7 0.0 d 285 7 0.0 d 286 7 0.0 d 287 7 0.0 d 288 7 0.0 d 289 7 0.0 d 290 7 0.0 d 291 7 0.0 d 292 7 0.0 d 293 7 0.0 d 294 7 0.0 d 295 7 0.0 d 296 7 0.0 d 297 7 0.0 d 298 7 0.0 d 299 7 0.0 d 300 7 0.0 d 301 7 0.0 d 302 7 0.0 d 303 7 0.0 d 304 7 0.0 d 305 7 0.0 d 306 7 0.0 d 307 7 0.0 d 308 7 0.0 d 309 7 0.0 d 310 7 0.0 d 311 7 0.0 d 312 7 0.0 d 313 7 0.0 d 314 7 0.0 d 315 7 0.0 d 316 7 0.0 d 317 7 0.0 d 318 7 0.0 d 319 7 0.0 d 320 7 0.0 d 321 7 0.0 d 322 7 0.0 d 323 7 0.0 d 324 7 0.0 d 325 7 0.0 d 326 7 0.0 d 327 7 0.0 d 328 7 0.0 d 329 7 0.0 d 330 7 0.0 d 331 7 0.0 d 332 7 0.0 d 333 7 0.0 d 334 7 0.0 d 335 7 0.0 d 336 7 0.0 d 337 7 0.0 d 338 7 0.0 d 339 7 0.0 d 340 7 0.0 d 341 7 0.0 d 342 7 0.0 d 343 7 0.0 d 344 7 0.0 d 345 7 0.0 d 346 7 0.0 d 347 7 0.0 d 348 7 0.0 d 349 7 0.0 d 350 7 0.0 d 351 7 0.0 d 352 7 0.0 d 353 7 0.0 d 354 7 0.0 d 355 7 0.0 d 356 7 0.0 d 357 7 0.0 d 358 7 0.0 d 359 7 0.0 d 360 7 0.0 d 361 7 0.0 d 1 8 5.0 d 2 8 5.16904 d 3 8 4.84159 d 4 8 3.34542 d 5 8 0.317102 d 6 8 0.103304 d 7 8 0.0275721 d 8 8 0.0221534 d 9 8 0.017689 d 10 8 0.0142639 d 11 8 0.0113974 d 12 8 0.00918238 d 13 8 0.00742541 d 14 8 0.00616602 d 15 8 0.00481195 d 16 8 0.00397049 d 17 8 -0.0659889 d 18 8 -0.025671 d 19 8 0.165495 d 20 8 0.986891 d 21 8 3.05229 d 22 8 4.55511 d 23 8 4.91611 d 24 8 4.98192 d 25 8 4.99428 d 26 8 4.99833 d 27 8 4.99095 d 28 8 4.97295 d 29 8 4.95493 d 30 8 4.93428 d 31 8 4.90723 d 32 8 4.94799 d 33 8 4.98584 d 34 8 4.99566 d 35 8 4.99813 d 36 8 4.99907 d 37 8 4.99947 d 38 8 4.99965 d 39 8 4.99976 d 40 8 4.99984 d 41 8 4.99989 d 42 8 4.99992 d 43 8 4.99994 d 44 8 4.99996 d 45 8 4.99998 d 46 8 5.00002 d 47 8 5.00006 d 48 8 5.00002 d 49 8 4.99996 d 50 8 4.99994 d 51 8 4.99999 d 52 8 5.00003 d 53 8 5.00002 d 54 8 5.0 d 55 8 4.99997 d 56 8 4.99997 d 57 8 4.99997 d 58 8 4.99997 d 59 8 4.99997 d 60 8 4.99996 d 61 8 4.99997 d 62 8 4.99997 d 63 8 4.99998 d 64 8 4.99998 d 65 8 4.99999 d 66 8 5.0 d 67 8 5.0 d 68 8 5.0 d 69 8 5.0 d 70 8 5.0 d 71 8 5.0 d 72 8 5.00001 d 73 8 5.00001 d 74 8 5.00001 d 75 8 5.00001 d 76 8 5.00001 d 77 8 5.00001 d 78 8 5.00001 d 79 8 5.00001 d 80 8 5.00001 d 81 8 5.00001 d 82 8 5.00001 d 83 8 5.00001 d 84 8 5.00001 d 85 8 5.0 d 86 8 5.0 d 87 8 5.0 d 88 8 5.0 d 89 8 5.0 d 90 8 5.0 d 91 8 5.0 d 92 8 4.99999 d 93 8 4.99999 d 94 8 4.99999 d 95 8 4.99999 d 96 8 4.99999 d 97 8 4.99999 d 98 8 4.99998 d 99 8 4.99998 d 100 8 4.99998 d 101 8 4.99999 d 102 8 4.99999 d 103 8 4.99999 d 104 8 4.99999 d 105 8 4.99999 d 106 8 4.99999 d 107 8 4.99999 d 108 8 4.99999 d 109 8 4.99999 d 110 8 4.99999 d 111 8 4.99999 d 112 8 4.99999 d 113 8 4.99999 d 114 8 4.99999 d 115 8 5.0 d 116 8 5.0 d 117 8 5.0 d 118 8 5.0 d 119 8 5.0 d 120 8 5.0 d 121 8 5.0 d 122 8 5.16575 d 123 8 4.69986 d 124 8 2.43862 d 125 8 0.0230224 d 126 8 0.035229 d 127 8 -0.0210607 d 128 8 -0.0292766 d 129 8 -0.0172693 d 130 8 -0.00271479 d 131 8 -0.000912251 d 132 8 -0.000349106 d 133 8 -0.000116866 d 134 8 -4.24733e-05 d 135 8 -1.39536e-05 d 136 8 -3.01179e-05 d 137 8 -0.0657192 d 138 8 -0.0204835 d 139 8 0.183378 d 140 8 1.07181 d 141 8 3.118 d 142 8 4.46472 d 143 8 4.84158 d 144 8 4.94795 d 145 8 4.98173 d 146 8 4.99236 d 147 8 4.99762 d 148 8 5.01939 d 149 8 5.0433 d 150 8 5.05332 d 151 8 5.04959 d 152 8 5.03955 d 153 8 5.02851 d 154 8 5.02052 d 155 8 5.01422 d 156 8 5.00965 d 157 8 5.00631 d 158 8 5.00405 d 159 8 5.00248 d 160 8 5.00083 d 161 8 5.00012 d 162 8 5.00209 d 163 8 5.00387 d 164 8 5.00347 d 165 8 4.99917 d 166 8 4.99213 d 167 8 4.98411 d 168 8 4.97521 d 169 8 4.96332 d 170 8 4.94601 d 171 8 4.9304 d 172 8 4.94633 d 173 8 4.97936 d 174 8 4.99264 d 175 8 4.99685 d 176 8 4.99857 d 177 8 4.99925 d 178 8 4.99954 d 179 8 4.9997 d 180 8 4.99973 d 181 8 4.9997 d 182 8 4.99973 d 183 8 4.99979 d 184 8 4.99983 d 185 8 4.99986 d 186 8 4.99988 d 187 8 4.9999 d 188 8 4.9999 d 189 8 4.99992 d 190 8 4.99993 d 191 8 4.99994 d 192 8 4.99995 d 193 8 4.99996 d 194 8 4.99996 d 195 8 4.99997 d 196 8 4.99997 d 197 8 4.99998 d 198 8 4.99998 d 199 8 4.99998 d 200 8 4.99999 d 201 8 4.99999 d 202 8 4.99999 d 203 8 4.99999 d 204 8 4.99999 d 205 8 4.99999 d 206 8 4.99999 d 207 8 5.0 d 208 8 5.0 d 209 8 5.0 d 210 8 5.00001 d 211 8 5.00001 d 212 8 5.00001 d 213 8 5.00001 d 214 8 5.00002 d 215 8 5.00002 d 216 8 5.00002 d 217 8 5.00002 d 218 8 5.00001 d 219 8 5.00001 d 220 8 5.00001 d 221 8 5.0 d 222 8 5.0 d 223 8 5.0 d 224 8 5.0 d 225 8 5.0 d 226 8 5.0 d 227 8 5.0 d 228 8 5.0 d 229 8 4.99999 d 230 8 4.99999 d 231 8 4.99999 d 232 8 4.99999 d 233 8 4.99999 d 234 8 4.99999 d 235 8 4.99999 d 236 8 4.99999 d 237 8 4.99999 d 238 8 4.99999 d 239 8 4.99999 d 240 8 5.0 d 241 8 5.0 d 242 8 5.14242 d 243 8 4.76101 d 244 8 3.16003 d 245 8 0.299374 d 246 8 0.0645506 d 247 8 -0.000498424 d 248 8 -2.45108e-05 d 249 8 -2.27986e-05 d 250 8 -5.24401e-05 d 251 8 -4.9884e-05 d 252 8 -4.92491e-05 d 253 8 -2.93354e-05 d 254 8 -3.21402e-05 d 255 8 -2.11851e-05 d 256 8 -3.37925e-05 d 257 8 -0.0657892 d 258 8 -0.020563 d 259 8 0.182582 d 260 8 1.06058 d 261 8 3.12484 d 262 8 4.46552 d 263 8 4.84146 d 264 8 4.95102 d 265 8 4.98556 d 266 8 4.99472 d 267 8 4.99806 d 268 8 4.99909 d 269 8 4.99955 d 270 8 4.99976 d 271 8 4.99994 d 272 8 4.99992 d 273 8 5.00029 d 274 8 4.99967 d 275 8 4.99849 d 276 8 4.99736 d 277 8 4.99884 d 278 8 5.00099 d 279 8 5.00377 d 280 8 5.00215 d 281 8 4.99994 d 282 8 4.99893 d 283 8 4.99788 d 284 8 4.99862 d 285 8 5.00055 d 286 8 5.00134 d 287 8 5.00127 d 288 8 5.00073 d 289 8 5.00039 d 290 8 5.00018 d 291 8 5.00006 d 292 8 5.00001 d 293 8 4.99985 d 294 8 5.00026 d 295 8 5.00018 d 296 8 5.00003 d 297 8 4.99981 d 298 8 4.99985 d 299 8 4.99987 d 300 8 4.99985 d 301 8 4.99982 d 302 8 4.99982 d 303 8 4.99982 d 304 8 4.99983 d 305 8 4.99985 d 306 8 4.99987 d 307 8 4.99989 d 308 8 4.99991 d 309 8 4.99992 d 310 8 4.99994 d 311 8 4.99995 d 312 8 4.99995 d 313 8 4.99994 d 314 8 4.99994 d 315 8 4.99996 d 316 8 4.99999 d 317 8 5.00002 d 318 8 5.00008 d 319 8 5.00009 d 320 8 5.00006 d 321 8 5.00001 d 322 8 5.0 d 323 8 4.99999 d 324 8 4.99998 d 325 8 4.99997 d 326 8 4.99996 d 327 8 4.99997 d 328 8 4.99997 d 329 8 4.99998 d 330 8 4.99998 d 331 8 4.99999 d 332 8 4.99999 d 333 8 4.99999 d 334 8 5.0 d 335 8 5.0 d 336 8 5.0 d 337 8 5.0 d 338 8 5.00001 d 339 8 5.00001 d 340 8 5.00001 d 341 8 5.00001 d 342 8 5.00001 d 343 8 5.00001 d 344 8 5.00001 d 345 8 5.00001 d 346 8 5.00001 d 347 8 5.00001 d 348 8 5.00001 d 349 8 5.00001 d 350 8 5.0 d 351 8 5.0 d 352 8 5.0 d 353 8 5.0 d 354 8 5.0 d 355 8 4.99999 d 356 8 4.99999 d 357 8 4.99999 d 358 8 4.99999 d 359 8 4.99998 d 360 8 4.99998 d 361 8 4.99998 d 1 9 5.0 d 2 9 5.03758 d 3 9 5.04711 d 4 9 4.96911 d 5 9 4.20882 d 6 9 3.96295 d 7 9 4.01117 d 8 9 4.15521 d 9 9 4.2967 d 10 9 4.42274 d 11 9 4.5295 d 12 9 4.6176 d 13 9 4.69014 d 14 9 4.74831 d 15 9 4.7966 d 16 9 4.83537 d 17 9 4.80526 d 18 9 4.787 d 19 9 4.79295 d 20 9 4.88588 d 21 9 5.08978 d 22 9 5.15615 d 23 9 5.10778 d 24 9 5.07718 d 25 9 5.06652 d 26 9 5.08225 d 27 9 4.9744 d 28 9 4.52977 d 29 9 3.77452 d 30 9 2.69426 d 31 9 1.15294 d 32 9 0.245509 d 33 9 0.0981544 d 34 9 0.0567527 d 35 9 0.0367487 d 36 9 0.0252578 d 37 9 0.0180599 d 38 9 0.0133837 d 39 9 0.0101497 d 40 9 0.0078616 d 41 9 0.00620186 d 42 9 0.00499056 d 43 9 0.0041027 d 44 9 0.00344223 d 45 9 0.00295808 d 46 9 0.00260089 d 47 9 0.00229887 d 48 9 0.00200817 d 49 9 0.00176397 d 50 9 0.00160116 d 51 9 0.00147381 d 52 9 0.00134645 d 53 9 0.00125029 d 54 9 0.00116043 d 55 9 0.00107371 d 56 9 0.00101981 d 57 9 0.000965921 d 58 9 0.000912028 d 59 9 0.000858135 d 60 9 0.000804242 d 61 9 0.000761669 d 62 9 0.00072672 d 63 9 0.000691771 d 64 9 0.000656823 d 65 9 0.000621874 d 66 9 0.000588722 d 67 9 0.00057041 d 68 9 0.000552098 d 69 9 0.000533785 d 70 9 0.000515473 d 71 9 0.000497162 d 72 9 0.00047885 d 73 9 0.000460537 d 74 9 0.000442226 d 75 9 0.000423914 d 76 9 0.000405601 d 77 9 0.000388399 d 78 9 0.000378694 d 79 9 0.000368989 d 80 9 0.000359284 d 81 9 0.00034958 d 82 9 0.000339875 d 83 9 0.00033017 d 84 9 0.000320465 d 85 9 0.00031076 d 86 9 0.000301055 d 87 9 0.00029135 d 88 9 0.000282207 d 89 9 0.000276247 d 90 9 0.000270287 d 91 9 0.000264327 d 92 9 0.000258367 d 93 9 0.000252407 d 94 9 0.000246447 d 95 9 0.000240487 d 96 9 0.000234527 d 97 9 0.000228567 d 98 9 0.000222607 d 99 9 0.000217086 d 100 9 0.000213696 d 101 9 0.000210307 d 102 9 0.000206918 d 103 9 0.000203528 d 104 9 0.000200139 d 105 9 0.00019675 d 106 9 0.00019336 d 107 9 0.000189971 d 108 9 0.000186582 d 109 9 0.000183192 d 110 9 0.000179803 d 111 9 0.000176414 d 112 9 0.000173025 d 113 9 0.000169635 d 114 9 0.000166246 d 115 9 0.000162857 d 116 9 0.000159467 d 117 9 0.000156078 d 118 9 0.000152689 d 119 9 0.000149299 d 120 9 0.00014591 d 121 9 0.00014255 d 122 9 0.0316021 d 123 9 0.163272 d 124 9 0.348732 d 125 9 0.603651 d 126 9 0.35745 d 127 9 0.135965 d 128 9 0.0707354 d 129 9 0.0314595 d 130 9 0.0201047 d 131 9 0.00994945 d 132 9 0.00389601 d 133 9 0.00138839 d 134 9 0.00060778 d 135 9 0.000329648 d 136 9 0.000492396 d 137 9 -0.0732035 d 138 9 -0.0844077 d 139 9 -0.0789062 d 140 9 -0.0390837 d 141 9 0.0197559 d 142 9 0.0183094 d 143 9 -0.00180099 d 144 9 -0.0189565 d 145 9 -0.0424144 d 146 9 -0.0735904 d 147 9 -0.0892423 d 148 9 0.285039 d 149 9 1.13702 d 150 9 2.10809 d 151 9 2.95826 d 152 9 3.60164 d 153 9 4.0435 d 154 9 4.35771 d 155 9 4.57254 d 156 9 4.71769 d 157 9 4.81329 d 158 9 4.87534 d 159 9 4.91487 d 160 9 4.94264 d 161 9 4.97375 d 162 9 5.01526 d 163 9 5.06517 d 164 9 5.10154 d 165 9 5.06259 d 166 9 4.89005 d 167 9 4.5787 d 168 9 4.12226 d 169 9 3.46151 d 170 9 2.49023 d 171 9 1.2586 d 172 9 0.32725 d 173 9 0.116753 d 174 9 0.0701865 d 175 9 0.0455509 d 176 9 0.0286914 d 177 9 0.0178176 d 178 9 0.0117599 d 179 9 0.00902715 d 180 9 0.00760583 d 181 9 0.00637745 d 182 9 0.00543811 d 183 9 0.00439377 d 184 9 0.00352448 d 185 9 0.0030151 d 186 9 0.00285771 d 187 9 0.002465 d 188 9 0.00203114 d 189 9 0.00173004 d 190 9 0.0014839 d 191 9 0.00125177 d 192 9 0.00105327 d 193 9 0.000894905 d 194 9 0.000766372 d 195 9 0.000658894 d 196 9 0.000569105 d 197 9 0.000492114 d 198 9 0.000427938 d 199 9 0.000370217 d 200 9 0.000314758 d 201 9 0.000266569 d 202 9 0.000233726 d 203 9 0.000209048 d 204 9 0.000191957 d 205 9 0.000177169 d 206 9 0.000166604 d 207 9 0.000161 d 208 9 0.000157314 d 209 9 0.000143828 d 210 9 0.000130342 d 211 9 0.000116857 d 212 9 0.000103371 d 213 9 8.98855e-05 d 214 9 7.63998e-05 d 215 9 6.29141e-05 d 216 9 5.76583e-05 d 217 9 5.30027e-05 d 218 9 4.8347e-05 d 219 9 4.36913e-05 d 220 9 3.90357e-05 d 221 9 3.438e-05 d 222 9 2.97243e-05 d 223 9 2.72507e-05 d 224 9 2.59083e-05 d 225 9 2.45659e-05 d 226 9 2.32235e-05 d 227 9 2.18811e-05 d 228 9 2.05387e-05 d 229 9 1.91963e-05 d 230 9 1.78539e-05 d 231 9 1.65115e-05 d 232 9 1.51691e-05 d 233 9 1.38267e-05 d 234 9 1.24843e-05 d 235 9 1.11419e-05 d 236 9 9.79954e-06 d 237 9 8.51574e-06 d 238 9 7.69807e-06 d 239 9 6.8804e-06 d 240 9 6.06273e-06 d 241 9 5.24506e-06 d 242 9 0.0287318 d 243 9 0.0317111 d 244 9 -0.0320087 d 245 9 -0.103609 d 246 9 0.0369639 d 247 9 0.0121128 d 248 9 0.00961197 d 249 9 0.00934971 d 250 9 0.00820853 d 251 9 0.00699769 d 252 9 0.00607002 d 253 9 0.00535541 d 254 9 0.00476552 d 255 9 0.00427601 d 256 9 0.00376357 d 257 9 -0.073012 d 258 9 -0.0866964 d 259 9 -0.0809538 d 260 9 -0.038005 d 261 9 0.0277001 d 262 9 0.0188906 d 263 9 0.00614597 d 264 9 0.00373629 d 265 9 0.00489787 d 266 9 0.0146573 d 267 9 0.0191052 d 268 9 0.0151708 d 269 9 0.0124224 d 270 9 0.0105859 d 271 9 0.00879272 d 272 9 0.00729464 d 273 9 0.0070047 d 274 9 0.00449575 d 275 9 -0.00626652 d 276 9 -0.0252417 d 277 9 -0.0147287 d 278 9 0.022538 d 279 9 0.0822905 d 280 9 0.0947372 d 281 9 0.0657516 d 282 9 0.0445506 d 283 9 0.0316753 d 284 9 0.0220971 d 285 9 0.0158101 d 286 9 0.0140971 d 287 9 0.0161498 d 288 9 0.0139876 d 289 9 0.0122447 d 290 9 0.0106994 d 291 9 0.009397 d 292 9 0.00822236 d 293 9 0.00686509 d 294 9 0.00797431 d 295 9 0.00751269 d 296 9 0.00671173 d 297 9 0.00595243 d 298 9 0.00524633 d 299 9 0.00459528 d 300 9 0.00401688 d 301 9 0.00350109 d 302 9 0.00303954 d 303 9 0.00260569 d 304 9 0.00222792 d 305 9 0.00191033 d 306 9 0.00163917 d 307 9 0.00140949 d 308 9 0.00121464 d 309 9 0.0010471 d 310 9 0.000900638 d 311 9 0.000768847 d 312 9 0.000645236 d 313 9 0.000524807 d 314 9 0.000460275 d 315 9 0.000442237 d 316 9 0.000446775 d 317 9 0.000397026 d 318 9 0.000301585 d 319 9 0.000228994 d 320 9 0.000190894 d 321 9 0.000166569 d 322 9 0.000152261 d 323 9 0.000137953 d 324 9 0.000123644 d 325 9 0.000109336 d 326 9 9.50281e-05 d 327 9 8.56557e-05 d 328 9 7.78437e-05 d 329 9 7.00318e-05 d 330 9 6.22198e-05 d 331 9 5.44079e-05 d 332 9 4.87539e-05 d 333 9 4.57761e-05 d 334 9 4.27982e-05 d 335 9 3.98203e-05 d 336 9 3.68425e-05 d 337 9 3.38646e-05 d 338 9 3.08868e-05 d 339 9 2.79089e-05 d 340 9 2.4931e-05 d 341 9 2.19532e-05 d 342 9 1.89753e-05 d 343 9 1.75244e-05 d 344 9 1.64095e-05 d 345 9 1.52946e-05 d 346 9 1.41797e-05 d 347 9 1.30648e-05 d 348 9 1.19499e-05 d 349 9 1.0835e-05 d 350 9 9.72011e-06 d 351 9 8.60521e-06 d 352 9 7.4903e-06 d 353 9 6.5117e-06 d 354 9 6.10334e-06 d 355 9 5.69497e-06 d 356 9 5.2866e-06 d 357 9 4.87824e-06 d 358 9 4.46987e-06 d 359 9 4.06151e-06 d 360 9 3.65314e-06 d 361 9 3.24477e-06 d 1 10 1.86175 d 2 10 1.99708 d 3 10 2.07867 d 4 10 2.01211 d 5 10 2.43309 d 6 10 3.27194 d 7 10 3.63896 d 8 10 3.90426 d 9 10 4.11074 d 10 10 4.27932 d 11 10 4.41496 d 12 10 4.52543 d 13 10 4.61491 d 14 10 4.68862 d 15 10 4.7479 d 16 10 4.79666 d 17 10 4.72895 d 18 10 4.68886 d 19 10 4.70354 d 20 10 4.81353 d 21 10 5.01568 d 22 10 5.14184 d 23 10 5.10482 d 24 10 5.07362 d 25 10 5.05143 d 26 10 5.03638 d 27 10 5.02323 d 28 10 5.01465 d 29 10 5.00853 d 30 10 5.00383 d 31 10 4.99985 d 32 10 5.00454 d 33 10 5.00652 d 34 10 5.00546 d 35 10 5.00411 d 36 10 5.003 d 37 10 5.00214 d 38 10 5.00151 d 39 10 5.00106 d 40 10 5.00073 d 41 10 5.0005 d 42 10 5.00034 d 43 10 5.00023 d 44 10 5.00015 d 45 10 5.0001 d 46 10 5.00005 d 47 10 5.0 d 48 10 5.00001 d 49 10 5.00005 d 50 10 5.00005 d 51 10 5.00003 d 52 10 5.0 d 53 10 4.99998 d 54 10 4.99996 d 55 10 4.99994 d 56 10 4.99995 d 57 10 4.99997 d 58 10 4.99998 d 59 10 5.0 d 60 10 5.00001 d 61 10 5.00002 d 62 10 5.00002 d 63 10 5.00003 d 64 10 5.00003 d 65 10 5.00003 d 66 10 5.00003 d 67 10 5.00003 d 68 10 5.00003 d 69 10 5.00002 d 70 10 5.00002 d 71 10 5.00001 d 72 10 5.00001 d 73 10 5.00001 d 74 10 5.0 d 75 10 5.0 d 76 10 5.0 d 77 10 4.99999 d 78 10 4.99999 d 79 10 4.99999 d 80 10 4.99999 d 81 10 4.99999 d 82 10 4.99999 d 83 10 4.99999 d 84 10 4.99999 d 85 10 4.99999 d 86 10 4.99998 d 87 10 4.99998 d 88 10 4.99998 d 89 10 4.99999 d 90 10 4.99999 d 91 10 4.99999 d 92 10 4.99999 d 93 10 5.0 d 94 10 5.0 d 95 10 5.0 d 96 10 5.0 d 97 10 5.00001 d 98 10 5.00001 d 99 10 5.00001 d 100 10 5.00001 d 101 10 5.00001 d 102 10 5.00001 d 103 10 5.00001 d 104 10 5.00001 d 105 10 5.00001 d 106 10 5.00001 d 107 10 5.00001 d 108 10 5.00001 d 109 10 5.00001 d 110 10 5.00001 d 111 10 5.00001 d 112 10 5.00001 d 113 10 5.00001 d 114 10 5.00001 d 115 10 5.00001 d 116 10 5.00001 d 117 10 5.00001 d 118 10 5.00001 d 119 10 5.00001 d 120 10 5.00001 d 121 10 5.00001 d 122 10 5.17392 d 123 10 4.94828 d 124 10 3.78491 d 125 10 1.52079 d 126 10 0.608874 d 127 10 0.244031 d 128 10 0.127087 d 129 10 0.0552995 d 130 10 0.0361032 d 131 10 0.0169025 d 132 10 0.006364 d 133 10 0.00217624 d 134 10 0.000921391 d 135 10 0.000457305 d 136 10 0.000786754 d 137 10 -0.120016 d 138 10 -0.148054 d 139 10 -0.15898 d 140 10 -0.0801463 d 141 10 0.16463 d 142 10 0.174017 d 143 10 0.0799249 d 144 10 0.0318788 d 145 10 0.0129696 d 146 10 0.00483397 d 147 10 0.0025677 d 148 10 0.0042079 d 149 10 0.00350003 d 150 10 0.00178404 d 151 10 -8.72902e-05 d 152 10 -0.00128497 d 153 10 -0.00142213 d 154 10 -0.00130018 d 155 10 -0.00106874 d 156 10 -0.000789207 d 157 10 -0.000824335 d 158 10 -0.00104518 d 159 10 -0.00136799 d 160 10 -0.004366 d 161 10 -0.0102621 d 162 10 -0.0109254 d 163 10 -0.00649259 d 164 10 -0.00194842 d 165 10 0.00029793 d 166 10 0.00148673 d 167 10 0.00221085 d 168 10 0.00228291 d 169 10 0.00185261 d 170 10 0.00139687 d 171 10 0.00148183 d 172 10 0.00562266 d 173 10 0.00844119 d 174 10 0.00754627 d 175 10 0.00657396 d 176 10 0.00591212 d 177 10 0.00539269 d 178 10 0.0049282 d 179 10 0.00448417 d 180 10 0.0040572 d 181 10 0.00363719 d 182 10 0.00320392 d 183 10 0.00279607 d 184 10 0.00243938 d 185 10 0.00211505 d 186 10 0.00182302 d 187 10 0.00156254 d 188 10 0.0013341 d 189 10 0.00113834 d 190 10 0.000971865 d 191 10 0.00082776 d 192 10 0.000706193 d 193 10 0.000602499 d 194 10 0.000515059 d 195 10 0.000441401 d 196 10 0.00037897 d 197 10 0.000325459 d 198 10 0.00028083 d 199 10 0.000242096 d 200 10 0.000207274 d 201 10 0.000176444 d 202 10 0.000150372 d 203 10 0.000126407 d 204 10 0.000103373 d 205 10 9.05522e-05 d 206 10 8.53555e-05 d 207 10 8.63685e-05 d 208 10 9.02593e-05 d 209 10 8.37346e-05 d 210 10 7.72099e-05 d 211 10 7.06852e-05 d 212 10 6.41605e-05 d 213 10 5.76358e-05 d 214 10 5.11112e-05 d 215 10 4.45865e-05 d 216 10 4.08176e-05 d 217 10 3.72497e-05 d 218 10 3.36818e-05 d 219 10 3.01138e-05 d 220 10 2.65459e-05 d 221 10 2.2978e-05 d 222 10 1.94101e-05 d 223 10 1.76154e-05 d 224 10 1.67399e-05 d 225 10 1.58645e-05 d 226 10 1.4989e-05 d 227 10 1.41136e-05 d 228 10 1.32381e-05 d 229 10 1.23626e-05 d 230 10 1.14872e-05 d 231 10 1.06117e-05 d 232 10 9.73629e-06 d 233 10 8.86083e-06 d 234 10 7.98538e-06 d 235 10 7.10993e-06 d 236 10 6.23447e-06 d 237 10 5.44363e-06 d 238 10 5.32578e-06 d 239 10 5.20792e-06 d 240 10 5.09007e-06 d 241 10 4.97222e-06 d 242 10 0.0784323 d 243 10 0.0474527 d 244 10 -0.0764232 d 245 10 -0.151146 d 246 10 0.0615785 d 247 10 0.0144489 d 248 10 0.00974161 d 249 10 0.00947176 d 250 10 0.00849005 d 251 10 0.00728201 d 252 10 0.00630581 d 253 10 0.00554032 d 254 10 0.00487809 d 255 10 0.00441504 d 256 10 0.00384139 d 257 10 -0.118943 d 258 10 -0.149894 d 259 10 -0.161173 d 260 10 -0.0825299 d 261 10 0.171686 d 262 10 0.176912 d 263 10 0.0816085 d 264 10 0.0335236 d 265 10 0.013791 d 266 10 0.0056976 d 267 10 0.00238833 d 268 10 0.00105348 d 269 10 0.000526199 d 270 10 0.00025969 d 271 10 0.000396026 d 272 10 0.000837835 d 273 10 0.00170131 d 274 10 0.00196699 d 275 10 -0.000553314 d 276 10 -0.0061621 d 277 10 -0.0111895 d 278 10 -0.0142698 d 279 10 -0.0124608 d 280 10 -0.00795847 d 281 10 -0.00467822 d 282 10 -0.0043058 d 283 10 -0.00874449 d 284 10 -0.0118584 d 285 10 -0.00871386 d 286 10 -0.00377892 d 287 10 1.95244e-05 d 288 10 0.00218952 d 289 10 0.00325486 d 290 10 0.00386497 d 291 10 0.00422837 d 292 10 0.00446883 d 293 10 0.00447065 d 294 10 0.00486647 d 295 10 0.00547838 d 296 10 0.00565398 d 297 10 0.00559092 d 298 10 0.00538752 d 299 10 0.00507015 d 300 10 0.00466305 d 301 10 0.00420756 d 302 10 0.00373465 d 303 10 0.00328404 d 304 10 0.00287059 d 305 10 0.00250057 d 306 10 0.00216124 d 307 10 0.00184861 d 308 10 0.00156815 d 309 10 0.00134624 d 310 10 0.00117857 d 311 10 0.00103412 d 312 10 0.0008948 d 313 10 0.000761012 d 314 10 0.000619853 d 315 10 0.000462614 d 316 10 0.000319965 d 317 10 0.000287666 d 318 10 0.000356415 d 319 10 0.000379946 d 320 10 0.000339183 d 321 10 0.00027972 d 322 10 0.000252982 d 323 10 0.000226244 d 324 10 0.000199507 d 325 10 0.000172769 d 326 10 0.000146031 d 327 10 0.000130097 d 328 10 0.000117578 d 329 10 0.000105059 d 330 10 9.25401e-05 d 331 10 8.00213e-05 d 332 10 7.11204e-05 d 333 10 6.67061e-05 d 334 10 6.22918e-05 d 335 10 5.78775e-05 d 336 10 5.34632e-05 d 337 10 4.90489e-05 d 338 10 4.46346e-05 d 339 10 4.02203e-05 d 340 10 3.5806e-05 d 341 10 3.13916e-05 d 342 10 2.69773e-05 d 343 10 2.4827e-05 d 344 10 2.31747e-05 d 345 10 2.15225e-05 d 346 10 1.98702e-05 d 347 10 1.8218e-05 d 348 10 1.65658e-05 d 349 10 1.49135e-05 d 350 10 1.32613e-05 d 351 10 1.1609e-05 d 352 10 9.95678e-06 d 353 10 8.50108e-06 d 354 10 7.86765e-06 d 355 10 7.23422e-06 d 356 10 6.60079e-06 d 357 10 5.96736e-06 d 358 10 5.33393e-06 d 359 10 4.7005e-06 d 360 10 4.06707e-06 d 361 10 3.43363e-06 d 1 11 1.86175 d 2 11 1.99308 d 3 11 2.16619 d 4 11 2.46661 d 5 11 3.09359 d 6 11 3.76864 d 7 11 4.31299 d 8 11 4.65564 d 9 11 4.83425 d 10 11 4.92153 d 11 11 4.96157 d 12 11 4.98063 d 13 11 4.98649 d 14 11 4.99039 d 15 11 4.9945 d 16 11 4.9972 d 17 11 4.96206 d 18 11 4.89882 d 19 11 4.83865 d 20 11 4.83202 d 21 11 4.91016 d 22 11 5.04479 d 23 11 5.06078 d 24 11 5.04827 d 25 11 5.03474 d 26 11 5.0246 d 27 11 5.01639 d 28 11 5.00996 d 29 11 5.00569 d 30 11 5.00239 d 31 11 5.00043 d 32 11 5.00296 d 33 11 5.00437 d 34 11 5.00382 d 35 11 5.00287 d 36 11 5.00208 d 37 11 5.00148 d 38 11 5.00104 d 39 11 5.00073 d 40 11 5.0005 d 41 11 5.00034 d 42 11 5.00023 d 43 11 5.00016 d 44 11 5.00011 d 45 11 5.00008 d 46 11 5.00007 d 47 11 5.00007 d 48 11 5.00004 d 49 11 5.0 d 50 11 4.99998 d 51 11 4.99998 d 52 11 4.99997 d 53 11 4.99998 d 54 11 4.99999 d 55 11 5.0 d 56 11 5.0 d 57 11 5.00001 d 58 11 5.00001 d 59 11 5.00001 d 60 11 5.00002 d 61 11 5.00002 d 62 11 5.00001 d 63 11 5.00001 d 64 11 5.00001 d 65 11 5.00001 d 66 11 5.0 d 67 11 5.0 d 68 11 5.0 d 69 11 5.0 d 70 11 5.0 d 71 11 5.0 d 72 11 4.99999 d 73 11 4.99999 d 74 11 4.99999 d 75 11 4.99999 d 76 11 4.99999 d 77 11 4.99999 d 78 11 4.99999 d 79 11 4.99999 d 80 11 4.99999 d 81 11 4.99999 d 82 11 4.99999 d 83 11 4.99999 d 84 11 5.0 d 85 11 5.0 d 86 11 5.0 d 87 11 5.0 d 88 11 5.0 d 89 11 5.0 d 90 11 5.0 d 91 11 5.0 d 92 11 5.0 d 93 11 5.00001 d 94 11 5.00001 d 95 11 5.00001 d 96 11 5.00001 d 97 11 5.00001 d 98 11 5.00001 d 99 11 5.00001 d 100 11 5.00001 d 101 11 5.00001 d 102 11 5.00001 d 103 11 5.00001 d 104 11 5.00001 d 105 11 5.00001 d 106 11 5.00001 d 107 11 5.00001 d 108 11 5.00001 d 109 11 5.00001 d 110 11 5.00001 d 111 11 5.00001 d 112 11 5.00001 d 113 11 5.00001 d 114 11 5.0 d 115 11 5.0 d 116 11 5.0 d 117 11 5.0 d 118 11 5.0 d 119 11 5.0 d 120 11 5.0 d 121 11 5.0 d 122 11 5.10081 d 123 11 5.10949 d 124 11 4.98359 d 125 11 5.00733 d 126 11 5.15145 d 127 11 4.37298 d 128 11 2.36126 d 129 11 0.470759 d 130 11 0.0577238 d 131 11 0.0115884 d 132 11 0.00262611 d 133 11 0.000671499 d 134 11 0.000389038 d 135 11 0.000291291 d 136 11 0.000317347 d 137 11 -0.0167823 d 138 11 -0.0158344 d 139 11 -0.0140559 d 140 11 0.0104849 d 141 11 0.0865874 d 142 11 0.107813 d 143 11 0.0524688 d 144 11 0.0214369 d 145 11 0.00876443 d 146 11 0.00341595 d 147 11 0.00170778 d 148 11 0.00259042 d 149 11 0.0022241 d 150 11 0.00118519 d 151 11 1.10217e-06 d 152 11 -0.000784506 d 153 11 -0.000948169 d 154 11 -0.000856256 d 155 11 -0.000696719 d 156 11 -0.000485987 d 157 11 -0.000724787 d 158 11 -0.000981491 d 159 11 -0.001454 d 160 11 -0.00552498 d 161 11 -0.0114992 d 162 11 -0.0105266 d 163 11 -0.00543527 d 164 11 -0.000982798 d 165 11 0.00127356 d 166 11 0.00224212 d 167 11 0.00275439 d 168 11 0.00281098 d 169 11 0.0025471 d 170 11 0.00230368 d 171 11 0.00222576 d 172 11 0.00485522 d 173 11 0.00729453 d 174 11 0.00691796 d 175 11 0.0062615 d 176 11 0.00573987 d 177 11 0.0052688 d 178 11 0.00481185 d 179 11 0.00436934 d 180 11 0.00394326 d 181 11 0.00352712 d 182 11 0.00309978 d 183 11 0.00270038 d 184 11 0.00235335 d 185 11 0.00203742 d 186 11 0.00175256 d 187 11 0.00150067 d 188 11 0.00128126 d 189 11 0.00109323 d 190 11 0.000933619 d 191 11 0.000795113 d 192 11 0.000678182 d 193 11 0.00057843 d 194 11 0.000494345 d 195 11 0.000423609 d 196 11 0.000363821 d 197 11 0.000312766 d 198 11 0.000269856 d 199 11 0.000232389 d 200 11 0.000198382 d 201 11 0.000168126 d 202 11 0.00014267 d 203 11 0.000119293 d 204 11 9.69034e-05 d 205 11 8.5669e-05 d 206 11 8.26828e-05 d 207 11 8.64066e-05 d 208 11 9.26665e-05 d 209 11 8.5454e-05 d 210 11 7.82416e-05 d 211 11 7.10291e-05 d 212 11 6.38167e-05 d 213 11 5.66043e-05 d 214 11 4.93918e-05 d 215 11 4.21794e-05 d 216 11 3.86073e-05 d 217 11 3.53007e-05 d 218 11 3.19941e-05 d 219 11 2.86876e-05 d 220 11 2.5381e-05 d 221 11 2.20744e-05 d 222 11 1.87678e-05 d 223 11 1.70933e-05 d 224 11 1.62648e-05 d 225 11 1.54363e-05 d 226 11 1.46079e-05 d 227 11 1.37794e-05 d 228 11 1.2951e-05 d 229 11 1.21225e-05 d 230 11 1.12941e-05 d 231 11 1.04656e-05 d 232 11 9.63716e-06 d 233 11 8.80871e-06 d 234 11 7.98026e-06 d 235 11 7.1518e-06 d 236 11 6.32335e-06 d 237 11 5.5374e-06 d 238 11 5.08959e-06 d 239 11 4.64178e-06 d 240 11 4.19397e-06 d 241 11 3.74616e-06 d 242 11 0.0438026 d 243 11 0.0242078 d 244 11 -0.0602019 d 245 11 -0.0840866 d 246 11 0.00148461 d 247 11 -0.00292489 d 248 11 0.000442098 d 249 11 0.00219489 d 250 11 0.00281478 d 251 11 0.00290756 d 252 11 0.00277945 d 253 11 0.00263896 d 254 11 0.00240099 d 255 11 0.00223283 d 256 11 0.001947 d 257 11 -0.0153629 d 258 11 -0.0148815 d 259 11 -0.0128673 d 260 11 0.0126017 d 261 11 0.0905161 d 262 11 0.11051 d 263 11 0.0538958 d 264 11 0.022562 d 265 11 0.00935726 d 266 11 0.00397422 d 267 11 0.00172534 d 268 11 0.000790207 d 269 11 0.000416322 d 270 11 0.000191632 d 271 11 0.000469721 d 272 11 0.0009779 d 273 11 0.00192566 d 274 11 0.00200688 d 275 11 -0.0016502 d 276 11 -0.00733932 d 277 11 -0.0128113 d 278 11 -0.0147608 d 279 11 -0.0115456 d 280 11 -0.00668995 d 281 11 -0.00401368 d 282 11 -0.00463908 d 283 11 -0.0101197 d 284 11 -0.0118993 d 285 11 -0.0076276 d 286 11 -0.00262656 d 287 11 0.000813059 d 288 11 0.00264455 d 289 11 0.00350796 d 290 11 0.00399494 d 291 11 0.0043049 d 292 11 0.00451658 d 293 11 0.00444739 d 294 11 0.00503842 d 295 11 0.00559516 d 296 11 0.00568213 d 297 11 0.00556459 d 298 11 0.0053176 d 299 11 0.00496654 d 300 11 0.00454337 d 301 11 0.00408592 d 302 11 0.00362171 d 303 11 0.00317793 d 304 11 0.00277001 d 305 11 0.00240394 d 306 11 0.00207009 d 307 11 0.00176575 d 308 11 0.00149725 d 309 11 0.00129045 d 310 11 0.00114257 d 311 11 0.00101135 d 312 11 0.000871672 d 313 11 0.000723764 d 314 11 0.000580438 d 315 11 0.000427507 d 316 11 0.000296956 d 317 11 0.000281834 d 318 11 0.000376628 d 319 11 0.000412266 d 320 11 0.000367547 d 321 11 0.000295305 d 322 11 0.000264513 d 323 11 0.000233721 d 324 11 0.000202929 d 325 11 0.000172137 d 326 11 0.000141345 d 327 11 0.000124721 d 328 11 0.000112577 d 329 11 0.000100433 d 330 11 8.82893e-05 d 331 11 7.61453e-05 d 332 11 6.75517e-05 d 333 11 6.33609e-05 d 334 11 5.91701e-05 d 335 11 5.49792e-05 d 336 11 5.07884e-05 d 337 11 4.65976e-05 d 338 11 4.24067e-05 d 339 11 3.82159e-05 d 340 11 3.40251e-05 d 341 11 2.98342e-05 d 342 11 2.56434e-05 d 343 11 2.36401e-05 d 344 11 2.21181e-05 d 345 11 2.05961e-05 d 346 11 1.90741e-05 d 347 11 1.75521e-05 d 348 11 1.60301e-05 d 349 11 1.45081e-05 d 350 11 1.29861e-05 d 351 11 1.14641e-05 d 352 11 9.94208e-06 d 353 11 8.59252e-06 d 354 11 7.96439e-06 d 355 11 7.33626e-06 d 356 11 6.70813e-06 d 357 11 6.07999e-06 d 358 11 5.45186e-06 d 359 11 4.82373e-06 d 360 11 4.1956e-06 d 361 11 3.56747e-06 d 1 12 1.86175 d 2 12 1.73419 d 3 12 1.42874 d 4 12 1.04055 d 5 12 0.943004 d 6 12 0.268275 d 7 12 0.0826455 d 8 12 0.0388346 d 9 12 0.0214104 d 10 12 0.0135431 d 11 12 0.00961322 d 12 12 0.00712846 d 13 12 0.00588262 d 14 12 0.00432397 d 15 12 0.00377774 d 16 12 0.00270134 d 17 12 -0.00393731 d 18 12 -0.00542187 d 19 12 -0.00126596 d 20 12 0.0113777 d 21 12 0.0134522 d 22 12 0.00477056 d 23 12 -0.00211067 d 24 12 -0.00229253 d 25 12 -0.00173355 d 26 12 -0.00122404 d 27 12 -0.00113426 d 28 12 -0.000744931 d 29 12 -0.000520112 d 30 12 -0.000410048 d 31 12 -0.000220439 d 32 12 0.000508104 d 33 12 5.15856e-05 d 34 12 -0.000112593 d 35 12 -0.000118917 d 36 12 -9.57394e-05 d 37 12 -7.15727e-05 d 38 12 -5.11847e-05 d 39 12 -3.58275e-05 d 40 12 -2.47166e-05 d 41 12 -1.68866e-05 d 42 12 -1.14082e-05 d 43 12 -7.66646e-06 d 44 12 -5.12139e-06 d 45 12 -3.63426e-06 d 46 12 -3.01815e-06 d 47 12 -2.64862e-06 d 48 12 -1.4947e-06 d 49 12 -1.91403e-07 d 50 12 -2.5763e-08 d 51 12 -7.73699e-07 d 52 12 -1.52164e-06 d 53 12 -1.07268e-06 d 54 12 -3.81696e-07 d 55 12 2.6727e-07 d 56 12 4.75489e-07 d 57 12 6.83708e-07 d 58 12 8.91926e-07 d 59 12 1.10014e-06 d 60 12 1.30836e-06 d 61 12 1.2482e-06 d 62 12 1.00726e-06 d 63 12 7.66311e-07 d 64 12 5.25364e-07 d 65 12 2.84417e-07 d 66 12 6.27857e-08 d 67 12 7.43904e-10 d 68 12 -6.12979e-08 d 69 12 -1.2334e-07 d 70 12 -1.85382e-07 d 71 12 -2.47423e-07 d 72 12 -3.09465e-07 d 73 12 -3.71507e-07 d 74 12 -4.33549e-07 d 75 12 -4.95591e-07 d 76 12 -5.57633e-07 d 77 12 -6.04571e-07 d 78 12 -5.4944e-07 d 79 12 -4.9431e-07 d 80 12 -4.3918e-07 d 81 12 -3.84049e-07 d 82 12 -3.28919e-07 d 83 12 -2.73789e-07 d 84 12 -2.18659e-07 d 85 12 -1.63528e-07 d 86 12 -1.08398e-07 d 87 12 -5.32678e-08 d 88 12 1.062e-09 d 89 12 5.08502e-08 d 90 12 1.00638e-07 d 91 12 1.50427e-07 d 92 12 2.00215e-07 d 93 12 2.50003e-07 d 94 12 2.99791e-07 d 95 12 3.4958e-07 d 96 12 3.99368e-07 d 97 12 4.49156e-07 d 98 12 4.98944e-07 d 99 12 5.34512e-07 d 100 12 5.01032e-07 d 101 12 4.67553e-07 d 102 12 4.34073e-07 d 103 12 4.00593e-07 d 104 12 3.67113e-07 d 105 12 3.33633e-07 d 106 12 3.00153e-07 d 107 12 2.66674e-07 d 108 12 2.33194e-07 d 109 12 1.99714e-07 d 110 12 1.66234e-07 d 111 12 1.32754e-07 d 112 12 9.92744e-08 d 113 12 6.57945e-08 d 114 12 3.23147e-08 d 115 12 -1.16513e-09 d 116 12 -3.4645e-08 d 117 12 -6.81248e-08 d 118 12 -1.01605e-07 d 119 12 -1.35084e-07 d 120 12 -1.68564e-07 d 121 12 -2.18729e-07 d 122 12 0.0114926 d 123 12 -0.0245378 d 124 12 -0.111828 d 125 12 0.0964775 d 126 12 1.61491 d 127 12 3.22668 d 128 12 4.22041 d 129 12 4.54492 d 130 12 4.82845 d 131 12 4.94868 d 132 12 4.98588 d 133 12 4.99609 d 134 12 4.9981 d 135 12 4.99908 d 136 12 4.99788 d 137 12 4.98395 d 138 12 4.99294 d 139 12 4.99724 d 140 12 5.01939 d 141 12 5.0471 d 142 12 5.00902 d 143 12 4.98194 d 144 12 4.98496 d 145 12 4.99188 d 146 12 4.99623 d 147 12 4.99862 d 148 12 5.00025 d 149 12 4.99974 d 150 12 4.99953 d 151 12 4.99946 d 152 12 4.99958 d 153 12 5.00012 d 154 12 4.99997 d 155 12 4.99992 d 156 12 4.99988 d 157 12 4.99985 d 158 12 4.9998 d 159 12 4.9997 d 160 12 4.9988 d 161 12 4.99806 d 162 12 4.99982 d 163 12 5.00143 d 164 12 5.00159 d 165 12 5.00098 d 166 12 5.00053 d 167 12 5.00028 d 168 12 5.00007 d 169 12 4.99977 d 170 12 4.99992 d 171 12 5.00005 d 172 12 5.00133 d 173 12 5.0009 d 174 12 4.99993 d 175 12 4.99972 d 176 12 4.99975 d 177 12 4.9998 d 178 12 4.99982 d 179 12 4.99983 d 180 12 4.99983 d 181 12 4.99983 d 182 12 4.99983 d 183 12 4.99984 d 184 12 4.99986 d 185 12 4.99987 d 186 12 4.99989 d 187 12 4.9999 d 188 12 4.99991 d 189 12 4.99992 d 190 12 4.99994 d 191 12 4.99995 d 192 12 4.99995 d 193 12 4.99996 d 194 12 4.99997 d 195 12 4.99997 d 196 12 4.99998 d 197 12 4.99998 d 198 12 4.99998 d 199 12 4.99998 d 200 12 4.99999 d 201 12 4.99999 d 202 12 4.99999 d 203 12 4.99999 d 204 12 4.99999 d 205 12 4.99999 d 206 12 4.99999 d 207 12 5.0 d 208 12 5.0 d 209 12 5.0 d 210 12 5.00001 d 211 12 5.00001 d 212 12 5.00001 d 213 12 5.00002 d 214 12 5.00002 d 215 12 5.00002 d 216 12 5.00002 d 217 12 5.00002 d 218 12 5.00001 d 219 12 5.00001 d 220 12 5.00001 d 221 12 5.0 d 222 12 5.0 d 223 12 5.0 d 224 12 5.0 d 225 12 5.0 d 226 12 5.0 d 227 12 5.0 d 228 12 5.0 d 229 12 4.99999 d 230 12 4.99999 d 231 12 4.99999 d 232 12 4.99999 d 233 12 4.99999 d 234 12 4.99999 d 235 12 4.99999 d 236 12 4.99999 d 237 12 4.99999 d 238 12 4.99999 d 239 12 4.99999 d 240 12 5.0 d 241 12 5.0 d 242 12 5.01457 d 243 12 4.99482 d 244 12 4.96561 d 245 12 4.99326 d 246 12 5.03452 d 247 12 5.00424 d 248 12 5.00101 d 249 12 5.00045 d 250 12 5.00004 d 251 12 4.99965 d 252 12 4.99997 d 253 12 4.99994 d 254 12 4.99958 d 255 12 4.99999 d 256 12 4.99936 d 257 12 4.9839 d 258 12 4.99248 d 259 12 4.99717 d 260 12 5.01976 d 261 12 5.04869 d 262 12 5.0087 d 263 12 4.98143 d 264 12 4.98488 d 265 12 4.99199 d 266 12 4.99622 d 267 12 4.9983 d 268 12 4.99928 d 269 12 4.99971 d 270 12 4.99986 d 271 12 5.00031 d 272 12 5.00022 d 273 12 5.00035 d 274 12 5.0001 d 275 12 4.99884 d 276 12 4.99811 d 277 12 4.99803 d 278 12 4.99887 d 279 12 5.00078 d 280 12 5.00151 d 281 12 5.00116 d 282 12 5.00007 d 283 12 4.99843 d 284 12 4.99915 d 285 12 5.00107 d 286 12 5.00168 d 287 12 5.00141 d 288 12 5.00092 d 289 12 5.00055 d 290 12 5.0003 d 291 12 5.00016 d 292 12 5.0001 d 293 12 5.00001 d 294 12 5.00016 d 295 12 5.0002 d 296 12 5.00009 d 297 12 4.99993 d 298 12 4.99975 d 299 12 4.99984 d 300 12 4.99991 d 301 12 4.99991 d 302 12 4.99982 d 303 12 4.99974 d 304 12 4.99974 d 305 12 4.99985 d 306 12 4.99995 d 307 12 4.99999 d 308 12 4.99998 d 309 12 5.00004 d 310 12 5.00013 d 311 12 5.00015 d 312 12 5.00007 d 313 12 4.99988 d 314 12 4.99982 d 315 12 4.99985 d 316 12 4.99995 d 317 12 5.00006 d 318 12 5.0002 d 319 12 5.00025 d 320 12 5.0002 d 321 12 5.00009 d 322 12 5.00006 d 323 12 5.00004 d 324 12 5.00002 d 325 12 5.0 d 326 12 4.99998 d 327 12 4.99997 d 328 12 4.99998 d 329 12 4.99998 d 330 12 4.99999 d 331 12 4.99999 d 332 12 4.99999 d 333 12 5.0 d 334 12 5.0 d 335 12 5.0 d 336 12 5.0 d 337 12 5.0 d 338 12 5.00001 d 339 12 5.00001 d 340 12 5.00001 d 341 12 5.00001 d 342 12 5.00001 d 343 12 5.00001 d 344 12 5.00001 d 345 12 5.00001 d 346 12 5.00001 d 347 12 5.00001 d 348 12 5.00001 d 349 12 5.00001 d 350 12 5.0 d 351 12 5.0 d 352 12 5.0 d 353 12 5.0 d 354 12 5.0 d 355 12 4.99999 d 356 12 4.99999 d 357 12 4.99999 d 358 12 4.99999 d 359 12 4.99998 d 360 12 4.99998 d 361 12 4.99998 d 1 13 5.0 d 2 13 5.16975 d 3 13 4.78685 d 4 13 2.94241 d 5 13 0.126698 d 6 13 0.0487004 d 7 13 -0.00422591 d 8 13 -0.00130689 d 9 13 -0.000486756 d 10 13 -0.000195875 d 11 13 -0.000108988 d 12 13 -6.66736e-05 d 13 13 -7.26005e-05 d 14 13 -5.63608e-05 d 15 13 -3.81859e-05 d 16 13 -2.123e-05 d 17 13 -0.0646846 d 18 13 -0.0184474 d 19 13 0.182248 d 20 13 1.06731 d 21 13 3.10988 d 22 13 4.46133 d 23 13 4.84133 d 24 13 4.95113 d 25 13 4.98364 d 26 13 4.99455 d 27 13 4.99694 d 28 13 4.99727 d 29 13 4.9994 d 30 13 4.99975 d 31 13 5.0001 d 32 13 5.00132 d 33 13 5.00089 d 34 13 5.00039 d 35 13 5.00019 d 36 13 5.00011 d 37 13 5.00006 d 38 13 5.00005 d 39 13 5.00004 d 40 13 5.00001 d 41 13 4.99992 d 42 13 4.99992 d 43 13 5.00002 d 44 13 5.00013 d 45 13 5.00017 d 46 13 5.00009 d 47 13 4.99992 d 48 13 4.99991 d 49 13 4.99994 d 50 13 4.99996 d 51 13 4.99998 d 52 13 4.99999 d 53 13 5.00001 d 54 13 5.00004 d 55 13 5.00006 d 56 13 5.00005 d 57 13 5.00004 d 58 13 5.00003 d 59 13 5.00002 d 60 13 5.00001 d 61 13 5.0 d 62 13 4.99999 d 63 13 4.99999 d 64 13 4.99998 d 65 13 4.99998 d 66 13 4.99997 d 67 13 4.99997 d 68 13 4.99998 d 69 13 4.99998 d 70 13 4.99998 d 71 13 4.99998 d 72 13 4.99999 d 73 13 4.99999 d 74 13 4.99999 d 75 13 4.99999 d 76 13 5.0 d 77 13 5.0 d 78 13 5.0 d 79 13 5.0 d 80 13 5.0 d 81 13 5.0 d 82 13 5.00001 d 83 13 5.00001 d 84 13 5.00001 d 85 13 5.00001 d 86 13 5.00001 d 87 13 5.00001 d 88 13 5.00002 d 89 13 5.00001 d 90 13 5.00001 d 91 13 5.00001 d 92 13 5.00001 d 93 13 5.00001 d 94 13 5.00001 d 95 13 5.00001 d 96 13 5.0 d 97 13 5.0 d 98 13 5.0 d 99 13 5.0 d 100 13 5.0 d 101 13 5.0 d 102 13 5.0 d 103 13 5.0 d 104 13 5.0 d 105 13 5.0 d 106 13 5.0 d 107 13 5.0 d 108 13 5.0 d 109 13 5.0 d 110 13 5.0 d 111 13 5.0 d 112 13 5.0 d 113 13 5.0 d 114 13 4.99999 d 115 13 4.99999 d 116 13 4.99999 d 117 13 4.99999 d 118 13 4.99999 d 119 13 4.99999 d 120 13 4.99999 d 121 13 5.0 d 122 13 5.14699 d 123 13 4.78074 d 124 13 3.19424 d 125 13 0.305663 d 126 13 0.0611255 d 127 13 -0.00179951 d 128 13 -0.0012032 d 129 13 0.000405978 d 130 13 0.000989399 d 131 13 0.000445194 d 132 13 0.000191447 d 133 13 8.30476e-05 d 134 13 3.96236e-05 d 135 13 1.91866e-05 d 136 13 1.70665e-05 d 137 13 -0.0655239 d 138 13 -0.0210234 d 139 13 0.1827 d 140 13 1.06848 d 141 13 3.11554 d 142 13 4.46518 d 143 13 4.84212 d 144 13 4.94853 d 145 13 4.98244 d 146 13 4.99434 d 147 13 4.9997 d 148 13 5.00081 d 149 13 5.00009 d 150 13 4.99972 d 151 13 4.99985 d 152 13 4.99974 d 153 13 4.9995 d 154 13 4.99949 d 155 13 4.99958 d 156 13 4.99973 d 157 13 4.99948 d 158 13 4.99914 d 159 13 4.99874 d 160 13 4.99946 d 161 13 5.00309 d 162 13 5.0091 d 163 13 5.01576 d 164 13 5.01835 d 165 13 5.01852 d 166 13 5.0176 d 167 13 5.01625 d 168 13 5.01479 d 169 13 5.01345 d 170 13 5.01264 d 171 13 5.011 d 172 13 5.01092 d 173 13 5.01344 d 174 13 5.01363 d 175 13 5.01289 d 176 13 5.01184 d 177 13 5.01071 d 178 13 5.00956 d 179 13 5.00848 d 180 13 5.00751 d 181 13 5.00663 d 182 13 5.00577 d 183 13 5.00497 d 184 13 5.00427 d 185 13 5.00365 d 186 13 5.0031 d 187 13 5.00264 d 188 13 5.00224 d 189 13 5.00191 d 190 13 5.00163 d 191 13 5.00138 d 192 13 5.00117 d 193 13 5.00099 d 194 13 5.00083 d 195 13 5.00071 d 196 13 5.00061 d 197 13 5.00053 d 198 13 5.00045 d 199 13 5.00037 d 200 13 5.00029 d 201 13 5.00022 d 202 13 5.00019 d 203 13 5.0002 d 204 13 5.00023 d 205 13 5.00024 d 206 13 5.00023 d 207 13 5.00023 d 208 13 5.00022 d 209 13 5.0002 d 210 13 5.00018 d 211 13 5.00016 d 212 13 5.00014 d 213 13 5.00011 d 214 13 5.00009 d 215 13 5.00007 d 216 13 5.00006 d 217 13 5.00005 d 218 13 5.00005 d 219 13 5.00004 d 220 13 5.00003 d 221 13 5.00002 d 222 13 5.00001 d 223 13 5.00001 d 224 13 5.00001 d 225 13 5.00001 d 226 13 5.00001 d 227 13 5.00001 d 228 13 5.00001 d 229 13 5.00001 d 230 13 5.00001 d 231 13 5.00002 d 232 13 5.00002 d 233 13 5.00002 d 234 13 5.00002 d 235 13 5.00002 d 236 13 5.00002 d 237 13 5.00002 d 238 13 5.00002 d 239 13 5.00001 d 240 13 5.00001 d 241 13 5.00001 d 242 13 5.14298 d 243 13 4.79809 d 244 13 3.32704 d 245 13 0.498385 d 246 13 0.105773 d 247 13 0.0160646 d 248 13 0.0319912 d 249 13 0.0299434 d 250 13 0.0240102 d 251 13 0.0185844 d 252 13 0.0130411 d 253 13 0.0106532 d 254 13 0.00864871 d 255 13 0.00744519 d 256 13 0.00660887 d 257 13 -0.0612913 d 258 13 -0.0203719 d 259 13 0.174998 d 260 13 0.991787 d 261 13 3.06292 d 262 13 4.60005 d 263 13 4.93058 d 264 13 4.98917 d 265 13 5.00033 d 266 13 4.9999 d 267 13 4.99909 d 268 13 4.9966 d 269 13 4.9955 d 270 13 4.99488 d 271 13 4.99374 d 272 13 4.9943 d 273 13 5.00131 d 274 13 5.00506 d 275 13 4.99311 d 276 13 4.96288 d 277 13 4.93567 d 278 13 4.92439 d 279 13 4.94236 d 280 13 4.9732 d 281 13 4.98864 d 282 13 4.99458 d 283 13 5.00031 d 284 13 5.00694 d 285 13 5.01525 d 286 13 5.01945 d 287 13 5.01998 d 288 13 5.01953 d 289 13 5.01874 d 290 13 5.01766 d 291 13 5.0164 d 292 13 5.01509 d 293 13 5.01326 d 294 13 5.01423 d 295 13 5.01455 d 296 13 5.01361 d 297 13 5.01245 d 298 13 5.01122 d 299 13 5.01002 d 300 13 5.00888 d 301 13 5.00783 d 302 13 5.00687 d 303 13 5.00596 d 304 13 5.00514 d 305 13 5.00442 d 306 13 5.00379 d 307 13 5.00325 d 308 13 5.00279 d 309 13 5.0024 d 310 13 5.00208 d 311 13 5.0018 d 312 13 5.00153 d 313 13 5.00126 d 314 13 5.00107 d 315 13 5.00094 d 316 13 5.00085 d 317 13 5.00078 d 318 13 5.00072 d 319 13 5.00063 d 320 13 5.00053 d 321 13 5.00042 d 322 13 5.00038 d 323 13 5.00034 d 324 13 5.0003 d 325 13 5.00027 d 326 13 5.00023 d 327 13 5.00021 d 328 13 5.00019 d 329 13 5.00017 d 330 13 5.00015 d 331 13 5.00013 d 332 13 5.00012 d 333 13 5.00011 d 334 13 5.0001 d 335 13 5.0001 d 336 13 5.00009 d 337 13 5.00008 d 338 13 5.00007 d 339 13 5.00007 d 340 13 5.00006 d 341 13 5.00005 d 342 13 5.00005 d 343 13 5.00004 d 344 13 5.00004 d 345 13 5.00003 d 346 13 5.00003 d 347 13 5.00002 d 348 13 5.00002 d 349 13 5.00002 d 350 13 5.00001 d 351 13 5.00001 d 352 13 5.0 d 353 13 5.0 d 354 13 5.0 d 355 13 5.00001 d 356 13 5.00001 d 357 13 5.00001 d 358 13 5.00002 d 359 13 5.00002 d 360 13 5.00002 d 361 13 5.00002 d 1 14 9.73784e-10 d 2 14 0.0189926 d 3 14 0.0926769 d 4 14 0.206309 d 5 14 0.111533 d 6 14 0.0953491 d 7 14 0.0426966 d 8 14 0.0214177 d 9 14 0.0117943 d 10 14 0.00741442 d 11 14 0.00528816 d 12 14 0.00398417 d 13 14 0.0032967 d 14 14 0.00266499 d 15 14 0.00206647 d 16 14 0.00158788 d 17 14 -0.0371391 d 18 14 -0.0439528 d 19 14 -0.0408653 d 20 14 -0.0188706 d 21 14 0.0150241 d 22 14 0.0126852 d 23 14 0.00209817 d 24 14 -0.000239206 d 25 14 -5.31488e-05 d 26 14 0.000876324 d 27 14 -0.00451221 d 28 14 -0.0165223 d 29 14 -0.0284127 d 30 14 -0.0427584 d 31 14 -0.0502453 d 32 14 -0.0257366 d 33 14 -0.00903938 d 34 14 -0.00376456 d 35 14 -0.00233385 d 36 14 -0.00169922 d 37 14 -0.00130397 d 38 14 -0.00102542 d 39 14 -0.000811435 d 40 14 -0.000648115 d 41 14 -0.000529266 d 42 14 -0.00043795 d 43 14 -0.00036574 d 44 14 -0.00030716 d 45 14 -0.00026221 d 46 14 -0.000229662 d 47 14 -0.000205112 d 48 14 -0.000181038 d 49 14 -0.000162045 d 50 14 -0.000148988 d 51 14 -0.000137633 d 52 14 -0.000126278 d 53 14 -0.000115562 d 54 14 -0.000104976 d 55 14 -9.49324e-05 d 56 14 -9.0585e-05 d 57 14 -8.62375e-05 d 58 14 -8.18901e-05 d 59 14 -7.75426e-05 d 60 14 -7.31952e-05 d 61 14 -6.93752e-05 d 62 14 -6.59106e-05 d 63 14 -6.24461e-05 d 64 14 -5.89815e-05 d 65 14 -5.55169e-05 d 66 14 -5.22412e-05 d 67 14 -5.05263e-05 d 68 14 -4.88114e-05 d 69 14 -4.70966e-05 d 70 14 -4.53817e-05 d 71 14 -4.36668e-05 d 72 14 -4.19519e-05 d 73 14 -4.0237e-05 d 74 14 -3.85222e-05 d 75 14 -3.68073e-05 d 76 14 -3.50924e-05 d 77 14 -3.34782e-05 d 78 14 -3.25442e-05 d 79 14 -3.16102e-05 d 80 14 -3.06763e-05 d 81 14 -2.97423e-05 d 82 14 -2.88083e-05 d 83 14 -2.78744e-05 d 84 14 -2.69404e-05 d 85 14 -2.60064e-05 d 86 14 -2.50725e-05 d 87 14 -2.41385e-05 d 88 14 -2.32635e-05 d 89 14 -2.27232e-05 d 90 14 -2.21829e-05 d 91 14 -2.16426e-05 d 92 14 -2.11023e-05 d 93 14 -2.0562e-05 d 94 14 -2.00217e-05 d 95 14 -1.94814e-05 d 96 14 -1.89411e-05 d 97 14 -1.84007e-05 d 98 14 -1.78604e-05 d 99 14 -1.73647e-05 d 100 14 -1.70853e-05 d 101 14 -1.68059e-05 d 102 14 -1.65265e-05 d 103 14 -1.62471e-05 d 104 14 -1.59677e-05 d 105 14 -1.56883e-05 d 106 14 -1.54089e-05 d 107 14 -1.51295e-05 d 108 14 -1.48501e-05 d 109 14 -1.45707e-05 d 110 14 -1.42913e-05 d 111 14 -1.40119e-05 d 112 14 -1.37325e-05 d 113 14 -1.34531e-05 d 114 14 -1.31737e-05 d 115 14 -1.28943e-05 d 116 14 -1.26149e-05 d 117 14 -1.23355e-05 d 118 14 -1.20561e-05 d 119 14 -1.17767e-05 d 120 14 -1.14973e-05 d 121 14 -1.10954e-05 d 122 14 0.0152675 d 123 14 0.0228237 d 124 14 -0.00460678 d 125 14 -0.0341525 d 126 14 0.0232109 d 127 14 -0.0138039 d 128 14 -0.0416538 d 129 14 -0.0458764 d 130 14 -0.0201967 d 131 14 -0.00878316 d 132 14 -0.00379173 d 133 14 -0.00164621 d 134 14 -0.000785131 d 135 14 -0.00037575 d 136 14 -0.000352375 d 137 14 -0.0545586 d 138 14 -0.0746881 d 139 14 -0.0771865 d 140 14 -0.05386 d 141 14 -0.0022199 d 142 14 0.0136703 d 143 14 0.00633526 d 144 14 0.00138826 d 145 14 -0.00108934 d 146 14 0.0038886 d 147 14 0.0298077 d 148 14 0.0475776 d 149 14 0.0481003 d 150 14 0.0464167 d 151 14 0.047818 d 152 14 0.042789 d 153 14 0.035207 d 154 14 0.0264423 d 155 14 0.0193959 d 156 14 0.0151614 d 157 14 0.00624257 d 158 14 -0.00913057 d 159 14 -0.0310696 d 160 14 -0.0430238 d 161 14 0.016426 d 162 14 0.189762 d 163 14 0.49025 d 164 14 0.820116 d 165 14 1.13919 d 166 14 1.43549 d 167 14 1.70658 d 168 14 1.95183 d 169 14 2.17414 d 170 14 2.38506 d 171 14 2.5657 d 172 14 2.73958 d 173 14 2.97905 d 174 14 3.21403 d 175 14 3.43025 d 176 14 3.62645 d 177 14 3.8028 d 178 14 3.96002 d 179 14 4.09996 d 180 14 4.22443 d 181 14 4.33427 d 182 14 4.42886 d 183 14 4.51097 d 184 14 4.5817 d 185 14 4.64326 d 186 14 4.6957 d 187 14 4.74132 d 188 14 4.7797 d 189 14 4.81298 d 190 14 4.84102 d 191 14 4.86512 d 192 14 4.88523 d 193 14 4.90224 d 194 14 4.91649 d 195 14 4.92846 d 196 14 4.93868 d 197 14 4.94755 d 198 14 4.95483 d 199 14 4.96114 d 200 14 4.96682 d 201 14 4.97161 d 202 14 4.97502 d 203 14 4.9776 d 204 14 4.97944 d 205 14 4.98141 d 206 14 4.98319 d 207 14 4.98467 d 208 14 4.98585 d 209 14 4.9869 d 210 14 4.98796 d 211 14 4.98902 d 212 14 4.99008 d 213 14 4.99114 d 214 14 4.9922 d 215 14 4.99326 d 216 14 4.9938 d 217 14 4.99429 d 218 14 4.99479 d 219 14 4.99528 d 220 14 4.99578 d 221 14 4.99628 d 222 14 4.99677 d 223 14 4.99704 d 224 14 4.99718 d 225 14 4.99733 d 226 14 4.99747 d 227 14 4.99762 d 228 14 4.99777 d 229 14 4.99791 d 230 14 4.99806 d 231 14 4.9982 d 232 14 4.99835 d 233 14 4.9985 d 234 14 4.99864 d 235 14 4.99879 d 236 14 4.99893 d 237 14 4.99907 d 238 14 4.99916 d 239 14 4.99925 d 240 14 4.99934 d 241 14 4.99943 d 242 14 5.01473 d 243 14 4.92293 d 244 14 4.61974 d 245 14 4.0316 d 246 14 3.7835 d 247 14 3.74195 d 248 14 3.78344 d 249 14 3.87272 d 250 14 3.97386 d 251 14 4.07319 d 252 14 4.16686 d 253 14 4.25256 d 254 14 4.33126 d 255 14 4.40264 d 256 14 4.46697 d 257 14 4.49249 d 258 14 4.51807 d 259 14 4.55803 d 260 14 4.64055 d 261 14 4.78574 d 262 14 4.86074 d 263 14 4.88334 d 264 14 4.8999 d 265 14 4.91455 d 266 14 4.92814 d 267 14 4.93926 d 268 14 4.94761 d 269 14 4.95433 d 270 14 4.95907 d 271 14 4.9654 d 272 14 4.98317 d 273 14 5.0208 d 274 14 5.05134 d 275 14 4.85852 d 276 14 4.16041 d 277 14 3.00077 d 278 14 1.68376 d 279 14 0.672707 d 280 14 0.240838 d 281 14 0.0794725 d 282 14 -0.0106347 d 283 14 -0.00879443 d 284 14 0.107196 d 285 14 0.368163 d 286 14 0.701424 d 287 14 1.03581 d 288 14 1.3601 d 289 14 1.6678 d 290 14 1.95731 d 291 14 2.22701 d 292 14 2.47544 d 293 14 2.69099 d 294 14 2.92327 d 295 14 3.16648 d 296 14 3.3877 d 297 14 3.59067 d 298 14 3.77344 d 299 14 3.93584 d 300 14 4.08066 d 301 14 4.20863 d 302 14 4.32065 d 303 14 4.41791 d 304 14 4.50211 d 305 14 4.57423 d 306 14 4.63614 d 307 14 4.68888 d 308 14 4.73377 d 309 14 4.7721 d 310 14 4.80519 d 311 14 4.83338 d 312 14 4.85732 d 313 14 4.87815 d 314 14 4.89514 d 315 14 4.90927 d 316 14 4.92108 d 317 14 4.93122 d 318 14 4.94014 d 319 14 4.94845 d 320 14 4.95601 d 321 14 4.96251 d 322 14 4.96576 d 323 14 4.969 d 324 14 4.97225 d 325 14 4.9755 d 326 14 4.97874 d 327 14 4.98087 d 328 14 4.98265 d 329 14 4.98442 d 330 14 4.9862 d 331 14 4.98797 d 332 14 4.98924 d 333 14 4.9899 d 334 14 4.99055 d 335 14 4.9912 d 336 14 4.99186 d 337 14 4.99251 d 338 14 4.99316 d 339 14 4.99381 d 340 14 4.99447 d 341 14 4.99512 d 342 14 4.99577 d 343 14 4.99609 d 344 14 4.99634 d 345 14 4.99659 d 346 14 4.99683 d 347 14 4.99708 d 348 14 4.99732 d 349 14 4.99757 d 350 14 4.99782 d 351 14 4.99806 d 352 14 4.99831 d 353 14 4.99853 d 354 14 4.99863 d 355 14 4.99873 d 356 14 4.99883 d 357 14 4.99893 d 358 14 4.99903 d 359 14 4.99913 d 360 14 4.99923 d 361 14 4.99933 d 1 15 1.86175 d 2 15 2.00147 d 3 15 1.85141 d 4 15 1.0654 d 5 15 0.275481 d 6 15 0.205547 d 7 15 0.0712627 d 8 15 0.0313387 d 9 15 0.0151431 d 10 15 0.00864531 d 11 15 0.00593861 d 12 15 0.00438111 d 13 15 0.0037479 d 14 15 0.00305857 d 15 15 0.00221221 d 16 15 0.0017081 d 17 15 -0.0896128 d 18 15 -0.109079 d 19 15 -0.121356 d 20 15 -0.0542001 d 21 15 0.175821 d 22 15 0.177442 d 23 15 0.0814591 d 24 15 0.0333042 d 25 15 0.0134909 d 26 15 0.00625777 d 27 15 0.00100092 d 28 15 -0.00552776 d 29 15 -0.00411139 d 30 15 -0.00150395 d 31 15 -0.000564784 d 32 15 3.48169e-05 d 33 15 -0.000287014 d 34 15 -0.000538515 d 35 15 -0.000456537 d 36 15 -0.000325677 d 37 15 -0.000275468 d 38 15 -0.000166452 d 39 15 -8.27481e-05 d 40 15 -8.28704e-05 d 41 15 -7.47644e-05 d 42 15 -4.60552e-05 d 43 15 -2.61481e-06 d 44 15 2.26359e-05 d 45 15 2.53852e-05 d 46 15 -1.39853e-06 d 47 15 -4.23456e-05 d 48 15 -4.0907e-05 d 49 15 -2.8501e-05 d 50 15 -1.5945e-05 d 51 15 -9.01122e-06 d 52 15 -2.07747e-06 d 53 15 1.49328e-06 d 54 15 4.38398e-06 d 55 15 6.84248e-06 d 56 15 4.76711e-06 d 57 15 2.69173e-06 d 58 15 6.16362e-07 d 59 15 -1.45901e-06 d 60 15 -3.53438e-06 d 61 15 -4.14256e-06 d 62 15 -3.76238e-06 d 63 15 -3.3822e-06 d 64 15 -3.00202e-06 d 65 15 -2.62184e-06 d 66 15 -2.24878e-06 d 67 15 -1.93456e-06 d 68 15 -1.62033e-06 d 69 15 -1.3061e-06 d 70 15 -9.91867e-07 d 71 15 -6.77638e-07 d 72 15 -3.63409e-07 d 73 15 -4.91792e-08 d 74 15 2.6505e-07 d 75 15 5.7928e-07 d 76 15 8.93509e-07 d 77 15 1.16076e-06 d 78 15 1.11055e-06 d 79 15 1.06034e-06 d 80 15 1.01014e-06 d 81 15 9.59927e-07 d 82 15 9.09719e-07 d 83 15 8.59511e-07 d 84 15 8.09302e-07 d 85 15 7.59094e-07 d 86 15 7.08886e-07 d 87 15 6.58678e-07 d 88 15 5.99251e-07 d 89 15 4.87523e-07 d 90 15 3.75795e-07 d 91 15 2.64068e-07 d 92 15 1.5234e-07 d 93 15 4.06119e-08 d 94 15 -7.1116e-08 d 95 15 -1.82844e-07 d 96 15 -2.94572e-07 d 97 15 -4.063e-07 d 98 15 -5.18027e-07 d 99 15 -6.08517e-07 d 100 15 -5.95879e-07 d 101 15 -5.83241e-07 d 102 15 -5.70604e-07 d 103 15 -5.57966e-07 d 104 15 -5.45328e-07 d 105 15 -5.3269e-07 d 106 15 -5.20053e-07 d 107 15 -5.07415e-07 d 108 15 -4.94777e-07 d 109 15 -4.8214e-07 d 110 15 -4.69502e-07 d 111 15 -4.56864e-07 d 112 15 -4.44226e-07 d 113 15 -4.31589e-07 d 114 15 -4.18951e-07 d 115 15 -4.06313e-07 d 116 15 -3.93676e-07 d 117 15 -3.81038e-07 d 118 15 -3.684e-07 d 119 15 -3.55762e-07 d 120 15 -3.43125e-07 d 121 15 1.06736e-05 d 122 15 0.0797407 d 123 15 0.0437947 d 124 15 -0.0645098 d 125 15 -0.0877312 d 126 15 0.0653203 d 127 15 -0.00621184 d 128 15 -0.0353188 d 129 15 -0.0491378 d 130 15 -0.0251957 d 131 15 -0.0110996 d 132 15 -0.00481123 d 133 15 -0.0020941 d 134 15 -0.000998038 d 135 15 -0.000478747 d 136 15 -0.000445332 d 137 15 -0.102046 d 138 15 -0.135753 d 139 15 -0.154351 d 140 15 -0.0827509 d 141 15 0.163348 d 142 15 0.174012 d 143 15 0.0794822 d 144 15 0.0310624 d 145 15 0.0112213 d 146 15 0.00249061 d 147 15 0.00130764 d 148 15 0.00181315 d 149 15 0.00163875 d 150 15 0.00101454 d 151 15 0.000497435 d 152 15 0.000195258 d 153 15 5.31901e-05 d 154 15 2.4607e-05 d 155 15 6.62736e-05 d 156 15 7.90718e-05 d 157 15 4.0372e-05 d 158 15 -0.000141184 d 159 15 -0.000280623 d 160 15 5.5608e-05 d 161 15 0.000799565 d 162 15 0.000920189 d 163 15 0.000931616 d 164 15 0.000494527 d 165 15 0.000162303 d 166 15 -8.24884e-05 d 167 15 -0.000183938 d 168 15 -0.000203899 d 169 15 -0.000144788 d 170 15 -9.87063e-05 d 171 15 -0.000227929 d 172 15 2.93932e-05 d 173 15 0.000208563 d 174 15 1.88958e-06 d 175 15 -7.6335e-05 d 176 15 -0.000172472 d 177 15 -0.000165656 d 178 15 -0.000145889 d 179 15 -0.000177311 d 180 15 -0.000191058 d 181 15 -0.000168287 d 182 15 -0.00015755 d 183 15 -0.00013142 d 184 15 -8.10488e-05 d 185 15 -6.36115e-05 d 186 15 -7.8699e-05 d 187 15 -8.11282e-05 d 188 15 -7.98625e-05 d 189 15 -5.98807e-05 d 190 15 -3.40879e-05 d 191 15 -1.95464e-05 d 192 15 -1.79247e-05 d 193 15 -4.45514e-05 d 194 15 -7.47995e-05 d 195 15 -8.7682e-05 d 196 15 -7.50806e-05 d 197 15 -3.25561e-05 d 198 15 -4.34114e-05 d 199 15 -7.69099e-05 d 200 15 -0.000141101 d 201 15 -0.00018743 d 202 15 -0.000148471 d 203 15 -5.06546e-05 d 204 15 0.000120195 d 205 15 0.000177635 d 206 15 0.000177052 d 207 15 0.000146344 d 208 15 9.75126e-05 d 209 15 8.31233e-05 d 210 15 6.8734e-05 d 211 15 5.43447e-05 d 212 15 3.99554e-05 d 213 15 2.55661e-05 d 214 15 1.11768e-05 d 215 15 -3.21253e-06 d 216 15 -3.88937e-06 d 217 15 -3.56628e-06 d 218 15 -3.24318e-06 d 219 15 -2.92008e-06 d 220 15 -2.59699e-06 d 221 15 -2.27389e-06 d 222 15 -1.9508e-06 d 223 15 -1.73227e-06 d 224 15 -1.56796e-06 d 225 15 -1.40365e-06 d 226 15 -1.23934e-06 d 227 15 -1.07503e-06 d 228 15 -9.10722e-07 d 229 15 -7.46412e-07 d 230 15 -5.82101e-07 d 231 15 -4.1779e-07 d 232 15 -2.5348e-07 d 233 15 -8.91694e-08 d 234 15 7.51412e-08 d 235 15 2.39452e-07 d 236 15 4.03762e-07 d 237 15 5.95733e-07 d 238 15 1.00771e-06 d 239 15 1.41969e-06 d 240 15 1.83167e-06 d 241 15 2.24365e-06 d 242 15 0.0828257 d 243 15 0.231038 d 244 15 0.465438 d 245 15 1.54516 d 246 15 2.8461 d 247 15 3.19221 d 248 15 3.40395 d 249 15 3.6382 d 250 15 3.80758 d 251 15 3.93848 d 252 15 4.04882 d 253 15 4.15428 d 254 15 4.247 d 255 15 4.32917 d 256 15 4.40235 d 257 15 4.36941 d 258 15 4.397 d 259 15 4.48862 d 260 15 4.64552 d 261 15 4.86595 d 262 15 5.03475 d 263 15 5.0348 d 264 15 5.02627 d 265 15 5.01967 d 266 15 5.01542 d 267 15 5.00925 d 268 15 4.98613 d 269 15 4.9519 d 270 15 4.91581 d 271 15 4.87357 d 272 15 4.82302 d 273 15 4.80403 d 274 15 4.82565 d 275 15 4.86102 d 276 15 4.89483 d 277 15 4.92253 d 278 15 4.94428 d 279 15 4.96257 d 280 15 4.97608 d 281 15 4.98373 d 282 15 4.98823 d 283 15 4.99182 d 284 15 4.99437 d 285 15 4.99635 d 286 15 4.99745 d 287 15 4.99802 d 288 15 4.99843 d 289 15 4.99873 d 290 15 4.99895 d 291 15 4.99912 d 292 15 4.99925 d 293 15 4.99931 d 294 15 4.99962 d 295 15 4.99973 d 296 15 4.99972 d 297 15 4.99971 d 298 15 4.9997 d 299 15 4.99969 d 300 15 4.9997 d 301 15 4.99971 d 302 15 4.99973 d 303 15 4.99974 d 304 15 4.99976 d 305 15 4.99978 d 306 15 4.9998 d 307 15 4.99982 d 308 15 4.99985 d 309 15 4.99987 d 310 15 4.99989 d 311 15 4.9999 d 312 15 4.99991 d 313 15 4.99991 d 314 15 4.99993 d 315 15 4.99994 d 316 15 4.99997 d 317 15 5.00001 d 318 15 5.00006 d 319 15 5.00008 d 320 15 5.00006 d 321 15 5.00002 d 322 15 5.0 d 323 15 4.99999 d 324 15 4.99998 d 325 15 4.99997 d 326 15 4.99995 d 327 15 4.99995 d 328 15 4.99995 d 329 15 4.99995 d 330 15 4.99995 d 331 15 4.99995 d 332 15 4.99995 d 333 15 4.99996 d 334 15 4.99997 d 335 15 4.99997 d 336 15 4.99998 d 337 15 4.99999 d 338 15 5.0 d 339 15 5.0 d 340 15 5.00001 d 341 15 5.00002 d 342 15 5.00002 d 343 15 5.00002 d 344 15 5.00002 d 345 15 5.00002 d 346 15 5.00002 d 347 15 5.00002 d 348 15 5.00002 d 349 15 5.00002 d 350 15 5.00002 d 351 15 5.00001 d 352 15 5.00001 d 353 15 5.00001 d 354 15 5.00001 d 355 15 5.00001 d 356 15 5.0 d 357 15 5.0 d 358 15 5.0 d 359 15 4.99999 d 360 15 4.99999 d 361 15 4.99999 d 1 16 1.86175 d 2 16 2.00199 d 3 16 2.08919 d 4 16 1.84314 d 5 16 1.08254 d 6 16 0.214737 d 7 16 0.0377351 d 8 16 0.00952455 d 9 16 0.00232763 d 10 16 0.000563614 d 11 16 0.000263477 d 12 16 0.000148642 d 13 16 0.000285086 d 14 16 0.000242592 d 15 16 7.34699e-05 d 16 16 -1.53467e-05 d 17 16 -0.0161874 d 18 16 -0.0157876 d 19 16 -0.0141194 d 20 16 0.0132576 d 21 16 0.0903272 d 22 16 0.109938 d 23 16 0.0535295 d 24 16 0.0224216 d 25 16 0.00940945 d 26 16 0.00466825 d 27 16 -0.000649972 d 28 16 -0.00654752 d 29 16 -0.00333248 d 30 16 -0.00103671 d 31 16 -0.000508276 d 32 16 -5.8896e-05 d 33 16 -0.00043938 d 34 16 -0.000544704 d 35 16 -0.00044444 d 36 16 -0.000307093 d 37 16 -0.00024517 d 38 16 -0.000154538 d 39 16 -8.78602e-05 d 40 16 -7.10461e-05 d 41 16 -6.06485e-05 d 42 16 -3.91039e-05 d 43 16 -8.45988e-06 d 44 16 9.43442e-06 d 45 16 1.28351e-05 d 46 16 -2.16734e-06 d 47 16 -2.6142e-05 d 48 16 -2.54768e-05 d 49 16 -1.88997e-05 d 50 16 -1.17906e-05 d 51 16 -7.3808e-06 d 52 16 -2.97101e-06 d 53 16 1.19146e-07 d 54 16 2.94246e-06 d 55 16 5.38942e-06 d 56 16 3.88851e-06 d 57 16 2.38761e-06 d 58 16 8.86704e-07 d 59 16 -6.14201e-07 d 60 16 -2.11511e-06 d 61 16 -2.59565e-06 d 62 16 -2.38885e-06 d 63 16 -2.18205e-06 d 64 16 -1.97525e-06 d 65 16 -1.76845e-06 d 66 16 -1.56241e-06 d 67 16 -1.36258e-06 d 68 16 -1.16276e-06 d 69 16 -9.62939e-07 d 70 16 -7.63116e-07 d 71 16 -5.63293e-07 d 72 16 -3.6347e-07 d 73 16 -1.63647e-07 d 74 16 3.61756e-08 d 75 16 2.35999e-07 d 76 16 4.35822e-07 d 77 16 6.07653e-07 d 78 16 5.90323e-07 d 79 16 5.72994e-07 d 80 16 5.55665e-07 d 81 16 5.38336e-07 d 82 16 5.21007e-07 d 83 16 5.03678e-07 d 84 16 4.86349e-07 d 85 16 4.6902e-07 d 86 16 4.51691e-07 d 87 16 4.34361e-07 d 88 16 4.11899e-07 d 89 16 3.60315e-07 d 90 16 3.08731e-07 d 91 16 2.57146e-07 d 92 16 2.05562e-07 d 93 16 1.53977e-07 d 94 16 1.02393e-07 d 95 16 5.08082e-08 d 96 16 -7.76222e-10 d 97 16 -5.23607e-08 d 98 16 -1.03945e-07 d 99 16 -1.47815e-07 d 100 16 -1.54225e-07 d 101 16 -1.60635e-07 d 102 16 -1.67045e-07 d 103 16 -1.73455e-07 d 104 16 -1.79864e-07 d 105 16 -1.86274e-07 d 106 16 -1.92684e-07 d 107 16 -1.99094e-07 d 108 16 -2.05504e-07 d 109 16 -2.11914e-07 d 110 16 -2.18324e-07 d 111 16 -2.24734e-07 d 112 16 -2.31144e-07 d 113 16 -2.37554e-07 d 114 16 -2.43964e-07 d 115 16 -2.50373e-07 d 116 16 -2.56783e-07 d 117 16 -2.63193e-07 d 118 16 -2.69603e-07 d 119 16 -2.76013e-07 d 120 16 -2.82423e-07 d 121 16 2.92534e-06 d 122 16 0.0446777 d 123 16 0.024278 d 124 16 -0.0518987 d 125 16 -0.0636547 d 126 16 0.00983929 d 127 16 -0.000518204 d 128 16 -0.000265194 d 129 16 0.000154772 d 130 16 0.000299538 d 131 16 3.12715e-05 d 132 16 -3.18225e-05 d 133 16 -2.48268e-05 d 134 16 -1.16701e-05 d 135 16 -6.05117e-06 d 136 16 7.61116e-06 d 137 16 -0.0163668 d 138 16 -0.0158244 d 139 16 -0.0141177 d 140 16 0.0100085 d 141 16 0.0857144 d 142 16 0.107784 d 143 16 0.051862 d 144 16 0.0204448 d 145 16 0.00629858 d 146 16 0.000967736 d 147 16 0.00121674 d 148 16 0.00190276 d 149 16 0.00154009 d 150 16 0.000860922 d 151 16 0.000410386 d 152 16 0.000164585 d 153 16 3.99493e-05 d 154 16 1.93797e-05 d 155 16 5.67594e-05 d 156 16 0.000110126 d 157 16 2.49925e-05 d 158 16 -7.17815e-05 d 159 16 -0.000142299 d 160 16 -1.63109e-05 d 161 16 0.000439529 d 162 16 0.000562489 d 163 16 0.000594599 d 164 16 0.000326164 d 165 16 0.000126423 d 166 16 -4.26063e-05 d 167 16 -0.000122927 d 168 16 -0.000114152 d 169 16 -6.72706e-05 d 170 16 -6.41242e-05 d 171 16 -0.000135588 d 172 16 2.61507e-05 d 173 16 0.000134036 d 174 16 6.43734e-06 d 175 16 -4.6223e-05 d 176 16 -0.000112047 d 177 16 -0.000101388 d 178 16 -8.67847e-05 d 179 16 -0.000117664 d 180 16 -0.000133957 d 181 16 -0.000116558 d 182 16 -0.000100873 d 183 16 -7.65448e-05 d 184 16 -4.44964e-05 d 185 16 -3.6677e-05 d 186 16 -5.26632e-05 d 187 16 -5.45172e-05 d 188 16 -5.13545e-05 d 189 16 -3.73869e-05 d 190 16 -1.99732e-05 d 191 16 -1.0907e-05 d 192 16 -1.10081e-05 d 193 16 -3.02609e-05 d 194 16 -5.18517e-05 d 195 16 -6.13597e-05 d 196 16 -5.30706e-05 d 197 16 -2.39572e-05 d 198 16 -3.24146e-05 d 199 16 -5.70062e-05 d 200 16 -0.000103448 d 201 16 -0.000135376 d 202 16 -0.0001024 d 203 16 -2.39007e-05 d 204 16 0.000110929 d 205 16 0.000151226 d 206 16 0.000142044 d 207 16 0.000105922 d 208 16 5.62834e-05 d 209 16 4.78476e-05 d 210 16 3.94117e-05 d 211 16 3.09759e-05 d 212 16 2.25401e-05 d 213 16 1.41042e-05 d 214 16 5.66837e-06 d 215 16 -2.76747e-06 d 216 16 -3.08639e-06 d 217 16 -2.81341e-06 d 218 16 -2.54043e-06 d 219 16 -2.26745e-06 d 220 16 -1.99447e-06 d 221 16 -1.72149e-06 d 222 16 -1.44851e-06 d 223 16 -1.26226e-06 d 224 16 -1.12096e-06 d 225 16 -9.79661e-07 d 226 16 -8.38363e-07 d 227 16 -6.97065e-07 d 228 16 -5.55768e-07 d 229 16 -4.1447e-07 d 230 16 -2.73173e-07 d 231 16 -1.31875e-07 d 232 16 9.42259e-09 d 233 16 1.5072e-07 d 234 16 2.92018e-07 d 235 16 4.33315e-07 d 236 16 5.74613e-07 d 237 16 7.10363e-07 d 238 16 8.01984e-07 d 239 16 8.93604e-07 d 240 16 9.85225e-07 d 241 16 1.07685e-06 d 242 16 0.04474 d 243 16 0.0928765 d 244 16 0.141327 d 245 16 0.0176048 d 246 16 -0.071675 d 247 16 -0.0124613 d 248 16 0.989022 d 249 16 2.28104 d 250 16 3.40619 d 251 16 4.21417 d 252 16 4.67173 d 253 16 4.87438 d 254 16 4.96044 d 255 16 4.98996 d 256 16 4.99858 d 257 16 4.96672 d 258 16 4.89502 d 259 16 4.79391 d 260 16 4.76433 d 261 16 4.8387 d 262 16 4.98612 d 263 16 5.0161 d 264 16 5.01722 d 265 16 5.01437 d 266 16 5.01256 d 267 16 4.99827 d 268 16 4.95807 d 269 16 4.9209 d 270 16 4.88217 d 271 16 4.83006 d 272 16 4.78461 d 273 16 4.80759 d 274 16 4.85548 d 275 16 4.89604 d 276 16 4.9254 d 277 16 4.94617 d 278 16 4.96126 d 279 16 4.97374 d 280 16 4.98255 d 281 16 4.98792 d 282 16 4.99126 d 283 16 4.99361 d 284 16 4.99554 d 285 16 4.99699 d 286 16 4.99792 d 287 16 4.99846 d 288 16 4.99881 d 289 16 4.99905 d 290 16 4.99924 d 291 16 4.99938 d 292 16 4.99949 d 293 16 4.99955 d 294 16 4.9997 d 295 16 4.9998 d 296 16 4.99982 d 297 16 4.99982 d 298 16 4.99982 d 299 16 4.99982 d 300 16 4.99982 d 301 16 4.99983 d 302 16 4.99984 d 303 16 4.99985 d 304 16 4.99986 d 305 16 4.99987 d 306 16 4.99988 d 307 16 4.99989 d 308 16 4.9999 d 309 16 4.99992 d 310 16 4.99993 d 311 16 4.99994 d 312 16 4.99995 d 313 16 4.99995 d 314 16 4.99996 d 315 16 4.99996 d 316 16 4.99998 d 317 16 4.99999 d 318 16 5.00001 d 319 16 5.00002 d 320 16 5.00002 d 321 16 5.00001 d 322 16 5.00001 d 323 16 5.0 d 324 16 4.99999 d 325 16 4.99999 d 326 16 4.99998 d 327 16 4.99998 d 328 16 4.99998 d 329 16 4.99998 d 330 16 4.99998 d 331 16 4.99998 d 332 16 4.99998 d 333 16 4.99998 d 334 16 4.99998 d 335 16 4.99998 d 336 16 4.99999 d 337 16 4.99999 d 338 16 4.99999 d 339 16 4.99999 d 340 16 5.0 d 341 16 5.0 d 342 16 5.0 d 343 16 5.0 d 344 16 5.0 d 345 16 5.0 d 346 16 5.00001 d 347 16 5.00001 d 348 16 5.00001 d 349 16 5.00001 d 350 16 5.00001 d 351 16 5.00001 d 352 16 5.00001 d 353 16 5.00001 d 354 16 5.00001 d 355 16 5.00001 d 356 16 5.00001 d 357 16 5.00001 d 358 16 5.00001 d 359 16 5.00001 d 360 16 5.00001 d 361 16 5.00001 d 1 17 1.86175 d 2 17 1.73073 d 3 17 1.50572 d 4 17 1.89001 d 5 17 3.39004 d 6 17 4.36034 d 7 17 4.79012 d 8 17 4.93798 d 9 17 4.98305 d 10 17 4.99539 d 11 17 4.9979 d 12 17 4.99904 d 13 17 4.99772 d 14 17 4.9983 d 15 17 4.99935 d 16 17 4.99975 d 17 17 4.98837 d 18 17 4.99456 d 19 17 4.99728 d 20 17 5.01838 d 21 17 5.04568 d 22 17 5.00759 d 23 17 4.98112 d 24 17 4.98479 d 25 17 4.99197 d 26 17 4.99641 d 27 17 4.99747 d 28 17 4.99775 d 29 17 5.00043 d 30 17 5.0007 d 31 17 5.00035 d 32 17 5.00023 d 33 17 4.99976 d 34 17 5.00002 d 35 17 5.00007 d 36 17 5.0002 d 37 17 4.99993 d 38 17 5.00003 d 39 17 5.00021 d 40 17 5.00006 d 41 17 4.99993 d 42 17 4.99992 d 43 17 5.00002 d 44 17 5.00013 d 45 17 5.00017 d 46 17 5.00009 d 47 17 4.99992 d 48 17 4.99991 d 49 17 4.99993 d 50 17 4.99996 d 51 17 4.99998 d 52 17 4.99999 d 53 17 5.00001 d 54 17 5.00003 d 55 17 5.00005 d 56 17 5.00004 d 57 17 5.00004 d 58 17 5.00003 d 59 17 5.00002 d 60 17 5.00001 d 61 17 5.0 d 62 17 4.99999 d 63 17 4.99999 d 64 17 4.99998 d 65 17 4.99998 d 66 17 4.99997 d 67 17 4.99997 d 68 17 4.99998 d 69 17 4.99998 d 70 17 4.99998 d 71 17 4.99998 d 72 17 4.99999 d 73 17 4.99999 d 74 17 4.99999 d 75 17 4.99999 d 76 17 5.0 d 77 17 5.0 d 78 17 5.0 d 79 17 5.0 d 80 17 5.0 d 81 17 5.0 d 82 17 5.00001 d 83 17 5.00001 d 84 17 5.00001 d 85 17 5.00001 d 86 17 5.00001 d 87 17 5.00001 d 88 17 5.00002 d 89 17 5.00001 d 90 17 5.00001 d 91 17 5.00001 d 92 17 5.00001 d 93 17 5.00001 d 94 17 5.00001 d 95 17 5.00001 d 96 17 5.0 d 97 17 5.0 d 98 17 5.0 d 99 17 5.0 d 100 17 5.0 d 101 17 5.0 d 102 17 5.0 d 103 17 5.0 d 104 17 5.0 d 105 17 5.0 d 106 17 5.0 d 107 17 5.0 d 108 17 5.0 d 109 17 5.0 d 110 17 5.0 d 111 17 5.0 d 112 17 5.0 d 113 17 4.99999 d 114 17 4.99999 d 115 17 4.99999 d 116 17 4.99999 d 117 17 4.99999 d 118 17 4.99999 d 119 17 4.99999 d 120 17 4.99999 d 121 17 5.0 d 122 17 5.01498 d 123 17 4.99342 d 124 17 4.96899 d 125 17 5.00301 d 126 17 5.02627 d 127 17 4.9977 d 128 17 4.99548 d 129 17 4.99757 d 130 17 5.00277 d 131 17 5.00245 d 132 17 5.0014 d 133 17 5.00069 d 134 17 5.00032 d 135 17 5.00014 d 136 17 5.00009 d 137 17 4.9867 d 138 17 4.99262 d 139 17 4.99607 d 140 17 5.01805 d 141 17 5.04713 d 142 17 5.00927 d 143 17 4.98184 d 144 17 4.98483 d 145 17 4.9914 d 146 17 4.99616 d 147 17 4.99902 d 148 17 4.9999 d 149 17 4.99987 d 150 17 4.99979 d 151 17 4.99981 d 152 17 4.99989 d 153 17 4.99994 d 154 17 4.99998 d 155 17 5.0002 d 156 17 5.00001 d 157 17 5.00008 d 158 17 5.00008 d 159 17 5.0001 d 160 17 5.00021 d 161 17 5.00032 d 162 17 5.00025 d 163 17 5.00019 d 164 17 5.00006 d 165 17 5.00007 d 166 17 4.99994 d 167 17 4.99997 d 168 17 4.99999 d 169 17 5.00023 d 170 17 5.00008 d 171 17 4.99993 d 172 17 4.99998 d 173 17 4.99986 d 174 17 4.99982 d 175 17 5.00003 d 176 17 4.99985 d 177 17 4.99996 d 178 17 5.00014 d 179 17 5.0 d 180 17 4.99984 d 181 17 4.99979 d 182 17 4.99982 d 183 17 4.99993 d 184 17 5.00008 d 185 17 5.00011 d 186 17 5.00002 d 187 17 4.99996 d 188 17 4.9999 d 189 17 4.99994 d 190 17 5.00001 d 191 17 5.00007 d 192 17 5.00009 d 193 17 4.99995 d 194 17 4.99978 d 195 17 4.99971 d 196 17 4.99976 d 197 17 4.99997 d 198 17 4.99996 d 199 17 4.99989 d 200 17 4.99972 d 201 17 4.99955 d 202 17 4.99953 d 203 17 4.99959 d 204 17 4.99976 d 205 17 4.9999 d 206 17 5.00005 d 207 17 5.00023 d 208 17 5.00039 d 209 17 5.00034 d 210 17 5.00029 d 211 17 5.00024 d 212 17 5.00019 d 213 17 5.00014 d 214 17 5.00009 d 215 17 5.00004 d 216 17 5.00003 d 217 17 5.00002 d 218 17 5.00001 d 219 17 5.0 d 220 17 5.0 d 221 17 4.99999 d 222 17 4.99998 d 223 17 4.99998 d 224 17 4.99998 d 225 17 4.99998 d 226 17 4.99998 d 227 17 4.99999 d 228 17 4.99999 d 229 17 4.99999 d 230 17 4.99999 d 231 17 4.99999 d 232 17 4.99999 d 233 17 4.99999 d 234 17 5.0 d 235 17 5.0 d 236 17 5.0 d 237 17 5.0 d 238 17 5.00001 d 239 17 5.00002 d 240 17 5.00003 d 241 17 5.00004 d 242 17 5.01564 d 243 17 5.03395 d 244 17 5.04932 d 245 17 5.11868 d 246 17 3.92502 d 247 17 1.31888 d 248 17 0.163888 d 249 17 0.0946876 d 250 17 0.0789578 d 251 17 0.0565084 d 252 17 0.0260333 d 253 17 0.0156986 d 254 17 0.00907667 d 255 17 0.00613629 d 256 17 0.00468417 d 257 17 -0.00174008 d 258 17 -0.0021422 d 259 17 0.000586962 d 260 17 0.0124937 d 261 17 0.0147977 d 262 17 0.00838454 d 263 17 0.00039383 d 264 17 -0.000522021 d 265 17 -0.000426598 d 266 17 -0.000290214 d 267 17 -0.00173713 d 268 17 -0.00384132 d 269 17 -0.00382945 d 270 17 -0.00429219 d 271 17 -0.00580193 d 272 17 -0.00393246 d 273 17 0.0017543 d 274 17 0.00423045 d 275 17 0.00408931 d 276 17 0.0031976 d 277 17 0.00245457 d 278 17 0.00187293 d 279 17 0.00159068 d 280 17 0.00105697 d 281 17 0.000609902 d 282 17 0.000358825 d 283 17 0.000334125 d 284 17 0.000212708 d 285 17 0.000168116 d 286 17 8.97349e-05 d 287 17 5.21578e-05 d 288 17 3.84527e-05 d 289 17 2.93033e-05 d 290 17 2.10067e-05 d 291 17 1.59954e-05 d 292 17 1.13917e-05 d 293 17 5.49738e-06 d 294 17 2.77217e-05 d 295 17 6.51259e-06 d 296 17 -6.65468e-06 d 297 17 2.09837e-06 d 298 17 -6.617e-06 d 299 17 -4.80187e-06 d 300 17 1.55031e-06 d 301 17 4.26536e-06 d 302 17 7.69457e-07 d 303 17 -1.46213e-06 d 304 17 -7.25202e-07 d 305 17 3.26501e-06 d 306 17 6.55807e-06 d 307 17 7.524e-06 d 308 17 6.07209e-06 d 309 17 6.00701e-06 d 310 17 5.41166e-06 d 311 17 3.86573e-06 d 312 17 1.10651e-06 d 313 17 -2.74603e-06 d 314 17 -2.18566e-06 d 315 17 2.3658e-06 d 316 17 8.59956e-06 d 317 17 8.35046e-06 d 318 17 2.90621e-06 d 319 17 -8.75982e-07 d 320 17 -1.87189e-06 d 321 17 -2.1528e-06 d 322 17 -1.94875e-06 d 323 17 -1.74471e-06 d 324 17 -1.54067e-06 d 325 17 -1.33662e-06 d 326 17 -1.13258e-06 d 327 17 -8.40567e-07 d 328 17 -5.20743e-07 d 329 17 -2.00918e-07 d 330 17 1.18906e-07 d 331 17 4.38731e-07 d 332 17 6.11382e-07 d 333 17 6.01529e-07 d 334 17 5.91675e-07 d 335 17 5.81822e-07 d 336 17 5.71968e-07 d 337 17 5.62115e-07 d 338 17 5.52261e-07 d 339 17 5.42407e-07 d 340 17 5.32554e-07 d 341 17 5.227e-07 d 342 17 5.12847e-07 d 343 17 4.72812e-07 d 344 17 4.26137e-07 d 345 17 3.79462e-07 d 346 17 3.32786e-07 d 347 17 2.86111e-07 d 348 17 2.39436e-07 d 349 17 1.92761e-07 d 350 17 1.46086e-07 d 351 17 9.94107e-08 d 352 17 5.27356e-08 d 353 17 -2.77779e-10 d 354 17 -7.98079e-08 d 355 17 -1.59338e-07 d 356 17 -2.38868e-07 d 357 17 -3.18398e-07 d 358 17 -3.97928e-07 d 359 17 -4.77458e-07 d 360 17 -5.56988e-07 d 361 17 -6.36519e-07 d 1 18 5.0 d 2 18 5.16963 d 3 18 4.84136 d 4 18 3.33754 d 5 18 0.316206 d 6 18 0.103113 d 7 18 0.0273341 d 8 18 0.0221102 d 9 18 0.0177008 d 10 18 0.0143758 d 11 18 0.0115203 d 12 18 0.00929231 d 13 18 0.00752716 d 14 18 0.00625439 d 15 18 0.00489872 d 16 18 0.00403656 d 17 18 -0.0657317 d 18 18 -0.0256467 d 19 18 0.165394 d 20 18 0.985963 d 21 18 3.05067 d 22 18 4.55799 d 23 18 4.89728 d 24 18 4.92464 d 25 18 4.8882 d 26 18 4.90592 d 27 18 4.97315 d 28 18 4.99241 d 29 18 4.99694 d 30 18 4.99845 d 31 18 4.99905 d 32 18 4.99939 d 33 18 4.99959 d 34 18 4.99971 d 35 18 4.9998 d 36 18 4.99986 d 37 18 4.9999 d 38 18 4.99993 d 39 18 4.99995 d 40 18 4.99996 d 41 18 4.99997 d 42 18 4.99998 d 43 18 4.99998 d 44 18 4.99999 d 45 18 4.99999 d 46 18 4.99999 d 47 18 4.99999 d 48 18 4.99999 d 49 18 5.0 d 50 18 5.00001 d 51 18 5.00003 d 52 18 5.00005 d 53 18 5.00004 d 54 18 5.00002 d 55 18 5.0 d 56 18 4.99999 d 57 18 4.99999 d 58 18 4.99998 d 59 18 4.99998 d 60 18 4.99997 d 61 18 4.99997 d 62 18 4.99998 d 63 18 4.99998 d 64 18 4.99999 d 65 18 4.99999 d 66 18 5.0 d 67 18 5.0 d 68 18 5.0 d 69 18 5.0 d 70 18 5.0 d 71 18 5.00001 d 72 18 5.00001 d 73 18 5.00001 d 74 18 5.00001 d 75 18 5.00001 d 76 18 5.00001 d 77 18 5.00002 d 78 18 5.00001 d 79 18 5.00001 d 80 18 5.00001 d 81 18 5.00001 d 82 18 5.00001 d 83 18 5.00001 d 84 18 5.00001 d 85 18 5.0 d 86 18 5.0 d 87 18 5.0 d 88 18 5.0 d 89 18 5.0 d 90 18 5.0 d 91 18 5.0 d 92 18 4.99999 d 93 18 4.99999 d 94 18 4.99999 d 95 18 4.99999 d 96 18 4.99999 d 97 18 4.99999 d 98 18 4.99998 d 99 18 4.99998 d 100 18 4.99998 d 101 18 4.99999 d 102 18 4.99999 d 103 18 4.99999 d 104 18 4.99999 d 105 18 4.99999 d 106 18 4.99999 d 107 18 4.99999 d 108 18 4.99999 d 109 18 4.99999 d 110 18 4.99999 d 111 18 4.99999 d 112 18 4.99999 d 113 18 4.99999 d 114 18 4.99999 d 115 18 5.0 d 116 18 5.0 d 117 18 5.0 d 118 18 5.0 d 119 18 5.0 d 120 18 5.0 d 121 18 5.00025 d 122 18 5.1657 d 123 18 4.69981 d 124 18 2.43895 d 125 18 0.0229743 d 126 18 0.0351406 d 127 18 -0.0211974 d 128 18 -0.0312063 d 129 18 -0.0160331 d 130 18 -0.0021718 d 131 18 -0.000766597 d 132 18 -0.000251052 d 133 18 -5.49363e-05 d 134 18 -3.36364e-06 d 135 18 -2.01983e-06 d 136 18 -9.70575e-06 d 137 18 -0.0657007 d 138 18 -0.0205247 d 139 18 0.183332 d 140 18 1.07163 d 141 18 3.11839 d 142 18 4.46213 d 143 18 4.84163 d 144 18 4.95195 d 145 18 4.99159 d 146 18 5.02084 d 147 18 5.04029 d 148 18 5.04138 d 149 18 5.0271 d 150 18 5.00445 d 151 18 4.97957 d 152 18 4.95702 d 153 18 4.95231 d 154 18 4.97819 d 155 18 4.99191 d 156 18 4.9963 d 157 18 4.99822 d 158 18 4.99878 d 159 18 4.99903 d 160 18 4.99925 d 161 18 4.99942 d 162 18 4.9995 d 163 18 4.99954 d 164 18 4.99957 d 165 18 4.99961 d 166 18 4.99966 d 167 18 4.9997 d 168 18 4.99974 d 169 18 4.99977 d 170 18 4.99981 d 171 18 4.99983 d 172 18 4.99986 d 173 18 4.99988 d 174 18 4.9999 d 175 18 4.99991 d 176 18 4.99992 d 177 18 4.99994 d 178 18 4.99995 d 179 18 4.99995 d 180 18 4.99996 d 181 18 4.99997 d 182 18 4.99997 d 183 18 4.99998 d 184 18 4.99998 d 185 18 4.99998 d 186 18 4.99999 d 187 18 4.99999 d 188 18 4.99999 d 189 18 4.99999 d 190 18 4.99999 d 191 18 4.99999 d 192 18 4.99999 d 193 18 5.0 d 194 18 5.0 d 195 18 5.0 d 196 18 5.0 d 197 18 5.0 d 198 18 5.0 d 199 18 5.0 d 200 18 5.0 d 201 18 5.0 d 202 18 5.0 d 203 18 5.0 d 204 18 5.0 d 205 18 5.0 d 206 18 5.0 d 207 18 5.0 d 208 18 5.0 d 209 18 5.0 d 210 18 5.0 d 211 18 5.0 d 212 18 5.0 d 213 18 5.0 d 214 18 5.0 d 215 18 5.0 d 216 18 5.0 d 217 18 5.00001 d 218 18 5.00001 d 219 18 5.00001 d 220 18 5.00002 d 221 18 5.00002 d 222 18 5.00002 d 223 18 5.00002 d 224 18 5.00002 d 225 18 5.00002 d 226 18 5.00002 d 227 18 5.00002 d 228 18 5.00001 d 229 18 5.00001 d 230 18 5.00001 d 231 18 5.00001 d 232 18 5.00001 d 233 18 5.00001 d 234 18 5.00001 d 235 18 5.0 d 236 18 5.0 d 237 18 5.0 d 238 18 4.99999 d 239 18 4.99998 d 240 18 4.99997 d 241 18 4.99996 d 242 18 5.14239 d 243 18 4.76219 d 244 18 3.16574 d 245 18 0.299969 d 246 18 0.0631609 d 247 18 -0.00118611 d 248 18 -0.00026052 d 249 18 -5.96333e-05 d 250 18 -1.44904e-05 d 251 18 -4.3859e-06 d 252 18 -2.99454e-06 d 253 18 1.10547e-06 d 254 18 4.84662e-06 d 255 18 1.30971e-05 d 256 18 2.23082e-05 d 257 18 -0.0655844 d 258 18 -0.0204818 d 259 18 0.182507 d 260 18 1.05954 d 261 18 3.12277 d 262 18 4.46735 d 263 18 4.83915 d 264 18 4.94512 d 265 18 4.97679 d 266 18 4.98654 d 267 18 4.9966 d 268 18 5.00833 d 269 18 5.00776 d 270 18 5.00432 d 271 18 5.00199 d 272 18 5.00086 d 273 18 5.00033 d 274 18 5.00008 d 275 18 5.0 d 276 18 5.00001 d 277 18 5.0 d 278 18 5.00005 d 279 18 5.00002 d 280 18 4.99981 d 281 18 4.99991 d 282 18 4.99998 d 283 18 4.99979 d 284 18 4.99979 d 285 18 4.99984 d 286 18 4.9998 d 287 18 4.9998 d 288 18 5.00006 d 289 18 5.00002 d 290 18 5.00001 d 291 18 5.0 d 292 18 5.0 d 293 18 4.99992 d 294 18 4.99998 d 295 18 4.99999 d 296 18 5.00002 d 297 18 5.00014 d 298 18 4.99999 d 299 18 4.99987 d 300 18 4.99993 d 301 18 5.00003 d 302 18 5.00011 d 303 18 5.00005 d 304 18 4.99996 d 305 18 4.99987 d 306 18 4.99985 d 307 18 4.99994 d 308 18 5.00009 d 309 18 5.0001 d 310 18 5.0 d 311 18 4.99993 d 312 18 4.99997 d 313 18 5.00008 d 314 18 5.00015 d 315 18 5.00021 d 316 18 5.00021 d 317 18 5.00007 d 318 18 4.99978 d 319 18 4.99965 d 320 18 4.99973 d 321 18 4.9999 d 322 18 4.99992 d 323 18 4.99995 d 324 18 4.99997 d 325 18 4.99999 d 326 18 5.00001 d 327 18 5.00002 d 328 18 5.00001 d 329 18 5.00001 d 330 18 5.00001 d 331 18 5.0 d 332 18 5.0 d 333 18 5.0 d 334 18 5.0 d 335 18 5.0 d 336 18 4.99999 d 337 18 4.99999 d 338 18 4.99999 d 339 18 4.99999 d 340 18 4.99999 d 341 18 4.99999 d 342 18 4.99998 d 343 18 4.99998 d 344 18 4.99999 d 345 18 4.99999 d 346 18 4.99999 d 347 18 4.99999 d 348 18 4.99999 d 349 18 4.99999 d 350 18 4.99999 d 351 18 5.0 d 352 18 5.0 d 353 18 5.0 d 354 18 5.0 d 355 18 5.0 d 356 18 5.00001 d 357 18 5.00001 d 358 18 5.00001 d 359 18 5.00002 d 360 18 5.00002 d 361 18 5.00002 d 1 19 5.0 d 2 19 5.0333 d 3 19 5.02472 d 4 19 4.92559 d 5 19 4.18383 d 6 19 3.93923 d 7 19 3.9961 d 8 19 4.14293 d 9 19 4.28591 d 10 19 4.41336 d 11 19 4.52157 d 12 19 4.61101 d 13 19 4.68472 d 14 19 4.7439 d 15 19 4.79294 d 16 19 4.83239 d 17 19 4.80697 d 18 19 4.78808 d 19 19 4.79322 d 20 19 4.8838 d 21 19 5.08529 d 22 19 5.21863 d 23 19 4.88852 d 24 19 3.90198 d 25 19 2.14586 d 26 19 0.383977 d 27 19 0.101103 d 28 19 0.0525711 d 29 19 0.0318287 d 30 19 0.020895 d 31 19 0.0146908 d 32 19 0.010831 d 33 19 0.00830272 d 34 19 0.00656377 d 35 19 0.00532066 d 36 19 0.00440078 d 37 19 0.00369956 d 38 19 0.00315713 d 39 19 0.00272614 d 40 19 0.00237965 d 41 19 0.00209659 d 42 19 0.00186339 d 43 19 0.00167014 d 44 19 0.0015081 d 45 19 0.00137172 d 46 19 0.00125607 d 47 19 0.00115393 d 48 19 0.00106076 d 49 19 0.000980166 d 50 19 0.000918015 d 51 19 0.000862837 d 52 19 0.00080766 d 53 19 0.000763488 d 54 19 0.000721541 d 55 19 0.000680825 d 56 19 0.000653026 d 57 19 0.000625226 d 58 19 0.000597426 d 59 19 0.000569627 d 60 19 0.000541827 d 61 19 0.000519087 d 62 19 0.000499756 d 63 19 0.000480424 d 64 19 0.000461093 d 65 19 0.000441761 d 66 19 0.000423291 d 67 19 0.000411941 d 68 19 0.00040059 d 69 19 0.00038924 d 70 19 0.000377889 d 71 19 0.000366539 d 72 19 0.000355188 d 73 19 0.000343838 d 74 19 0.000332487 d 75 19 0.000321137 d 76 19 0.000309786 d 77 19 0.000299055 d 78 19 0.000292509 d 79 19 0.000285963 d 80 19 0.000279417 d 81 19 0.000272871 d 82 19 0.000266325 d 83 19 0.000259779 d 84 19 0.000253233 d 85 19 0.000246686 d 86 19 0.00024014 d 87 19 0.000233594 d 88 19 0.000227387 d 89 19 0.0002231 d 90 19 0.000218813 d 91 19 0.000214526 d 92 19 0.00021024 d 93 19 0.000205953 d 94 19 0.000201666 d 95 19 0.000197379 d 96 19 0.000193092 d 97 19 0.000188805 d 98 19 0.000184519 d 99 19 0.000180526 d 100 19 0.000177963 d 101 19 0.0001754 d 102 19 0.000172837 d 103 19 0.000170274 d 104 19 0.000167711 d 105 19 0.000165148 d 106 19 0.000162585 d 107 19 0.000160022 d 108 19 0.000157459 d 109 19 0.000154895 d 110 19 0.000152332 d 111 19 0.000149769 d 112 19 0.000147206 d 113 19 0.000144643 d 114 19 0.00014208 d 115 19 0.000139517 d 116 19 0.000136954 d 117 19 0.000134391 d 118 19 0.000131828 d 119 19 0.000129265 d 120 19 0.000126702 d 121 19 0.000132838 d 122 19 0.0311184 d 123 19 0.163151 d 124 19 0.34986 d 125 19 0.604501 d 126 19 0.357125 d 127 19 0.136137 d 128 19 0.0711304 d 129 19 0.0346959 d 130 19 0.0212674 d 131 19 0.00872193 d 132 19 0.00252206 d 133 19 0.000455269 d 134 19 7.59332e-05 d 135 19 2.91532e-05 d 136 19 0.000320562 d 137 19 -0.0720911 d 138 19 -0.0840491 d 139 19 -0.0791345 d 140 19 -0.0404143 d 141 19 0.0182035 d 142 19 -0.0235871 d 143 19 -0.0426072 d 144 19 -0.0597501 d 145 19 0.00824773 d 146 19 0.481404 d 147 19 1.32496 d 148 19 2.11949 d 149 19 2.57317 d 150 19 2.58202 d 151 19 2.15054 d 152 19 1.33786 d 153 19 0.45702 d 154 19 0.153772 d 155 19 0.0913584 d 156 19 0.0604989 d 157 19 0.0421591 d 158 19 0.0271456 d 159 19 0.0170021 d 160 19 0.0115815 d 161 19 0.00907886 d 162 19 0.00742466 d 163 19 0.00626096 d 164 19 0.00531127 d 165 19 0.00450501 d 166 19 0.00381927 d 167 19 0.00323718 d 168 19 0.00274374 d 169 19 0.00232494 d 170 19 0.00196885 d 171 19 0.00166686 d 172 19 0.00141134 d 173 19 0.00119437 d 174 19 0.0010109 d 175 19 0.000855534 d 176 19 0.000723378 d 177 19 0.000611408 d 178 19 0.000516704 d 179 19 0.000436769 d 180 19 0.000369523 d 181 19 0.000313026 d 182 19 0.00026526 d 183 19 0.000223976 d 184 19 0.000188972 d 185 19 0.000159042 d 186 19 0.000134148 d 187 19 0.000112688 d 188 19 9.49738e-05 d 189 19 7.97877e-05 d 190 19 6.721e-05 d 191 19 5.65115e-05 d 192 19 4.77194e-05 d 193 19 4.03591e-05 d 194 19 3.42848e-05 d 195 19 2.92627e-05 d 196 19 2.50435e-05 d 197 19 2.1412e-05 d 198 19 1.84532e-05 d 199 19 1.58624e-05 d 200 19 1.34673e-05 d 201 19 1.14461e-05 d 202 19 1.00935e-05 d 203 19 9.12375e-06 d 204 19 8.50202e-06 d 205 19 7.81431e-06 d 206 19 7.20729e-06 d 207 19 6.73936e-06 d 208 19 6.3702e-06 d 209 19 5.90049e-06 d 210 19 5.43077e-06 d 211 19 4.96105e-06 d 212 19 4.49133e-06 d 213 19 4.02162e-06 d 214 19 3.5519e-06 d 215 19 3.08218e-06 d 216 19 2.79099e-06 d 217 19 2.51281e-06 d 218 19 2.23463e-06 d 219 19 1.95645e-06 d 220 19 1.67827e-06 d 221 19 1.40009e-06 d 222 19 1.12191e-06 d 223 19 1.01376e-06 d 224 19 9.9375e-07 d 225 19 9.73741e-07 d 226 19 9.53733e-07 d 227 19 9.33724e-07 d 228 19 9.13715e-07 d 229 19 8.93707e-07 d 230 19 8.73698e-07 d 231 19 8.5369e-07 d 232 19 8.33681e-07 d 233 19 8.13673e-07 d 234 19 7.93664e-07 d 235 19 7.73655e-07 d 236 19 7.53647e-07 d 237 19 7.21781e-07 d 238 19 5.956e-07 d 239 19 4.69419e-07 d 240 19 3.43239e-07 d 241 19 2.17058e-07 d 242 19 0.0284032 d 243 19 0.0374438 d 244 19 -0.0157543 d 245 19 -0.0680497 d 246 19 0.0504768 d 247 19 0.0100294 d 248 19 0.00222261 d 249 19 0.000528697 d 250 19 0.000132929 d 251 19 3.99489e-05 d 252 19 2.46066e-05 d 253 19 4.56327e-06 d 254 19 -6.54853e-06 d 255 19 1.33783e-05 d 256 19 -3.68221e-05 d 257 19 -0.0724498 d 258 19 -0.0843663 d 259 19 -0.0792935 d 260 19 -0.0406426 d 261 19 0.0200019 d 262 19 0.0426259 d 263 19 0.0220753 d 264 19 0.00668555 d 265 19 -0.000968483 d 266 19 0.024662 d 267 19 0.0383437 d 268 19 0.0911513 d 269 19 0.087848 d 270 19 0.0602076 d 271 19 0.0390559 d 272 19 0.0260573 d 273 19 0.0180444 d 274 19 0.012974 d 275 19 0.00985409 d 276 19 0.00788132 d 277 19 0.0064228 d 278 19 0.005545 d 279 19 0.00453571 d 280 19 0.00364245 d 281 19 0.00310278 d 282 19 0.00270523 d 283 19 0.00236439 d 284 19 0.0020945 d 285 19 0.00186808 d 286 19 0.00167493 d 287 19 0.00151731 d 288 19 0.00138594 d 289 19 0.00126945 d 290 19 0.00116695 d 291 19 0.0010762 d 292 19 0.000996366 d 293 19 0.000928387 d 294 19 0.000864414 d 295 19 0.000808258 d 296 19 0.000759574 d 297 19 0.000713865 d 298 19 0.000666712 d 299 19 0.000632716 d 300 19 0.000601262 d 301 19 0.000572163 d 302 19 0.000543986 d 303 19 0.000515253 d 304 19 0.0004897 d 305 19 0.000468112 d 306 19 0.000449313 d 307 19 0.000432981 d 308 19 0.000417911 d 309 19 0.000401307 d 310 19 0.000382712 d 311 19 0.000366678 d 312 19 0.000355736 d 313 19 0.000349171 d 314 19 0.000335727 d 315 19 0.000317091 d 316 19 0.000296086 d 317 19 0.000283543 d 318 19 0.000277366 d 319 19 0.000272233 d 320 19 0.000267001 d 321 19 0.000263147 d 322 19 0.000256699 d 323 19 0.000250251 d 324 19 0.000243803 d 325 19 0.000237355 d 326 19 0.000230907 d 327 19 0.000225424 d 328 19 0.000220247 d 329 19 0.000215069 d 330 19 0.000209892 d 331 19 0.000204714 d 332 19 0.000200213 d 333 19 0.000196548 d 334 19 0.000192884 d 335 19 0.00018922 d 336 19 0.000185556 d 337 19 0.000181892 d 338 19 0.000178228 d 339 19 0.000174564 d 340 19 0.0001709 d 341 19 0.000167236 d 342 19 0.000163572 d 343 19 0.000160824 d 344 19 0.000158279 d 345 19 0.000155733 d 346 19 0.000153187 d 347 19 0.000150641 d 348 19 0.000148095 d 349 19 0.000145549 d 350 19 0.000143003 d 351 19 0.000140457 d 352 19 0.000137911 d 353 19 0.000135457 d 354 19 0.000133386 d 355 19 0.000131315 d 356 19 0.000129245 d 357 19 0.000127174 d 358 19 0.000125103 d 359 19 0.000123032 d 360 19 0.000120961 d 361 19 0.000118891 d 1 20 1.86175 d 2 20 1.99994 d 3 20 2.0833 d 4 20 2.01627 d 5 20 2.42503 d 6 20 3.25769 d 7 20 3.62134 d 8 20 3.88827 d 9 20 4.09688 d 10 20 4.26773 d 11 20 4.40529 d 12 20 4.51734 d 13 20 4.60827 d 14 20 4.68313 d 15 20 4.74346 d 16 20 4.79302 d 17 20 4.72815 d 18 20 4.68959 d 19 20 4.70421 d 20 20 4.81316 d 21 20 5.01375 d 22 20 5.14493 d 23 20 5.10305 d 24 20 5.0699 d 25 20 5.04484 d 26 20 5.03751 d 27 20 5.03348 d 28 20 5.02504 d 29 20 5.01799 d 30 20 5.01271 d 31 20 5.00895 d 32 20 5.00628 d 33 20 5.0044 d 34 20 5.00309 d 35 20 5.00216 d 36 20 5.00151 d 37 20 5.00105 d 38 20 5.00073 d 39 20 5.00051 d 40 20 5.00034 d 41 20 5.00023 d 42 20 5.00015 d 43 20 5.0001 d 44 20 5.00007 d 45 20 5.00003 d 46 20 4.99998 d 47 20 4.99993 d 48 20 4.99993 d 49 20 4.99995 d 50 20 4.99999 d 51 20 5.00001 d 52 20 5.00003 d 53 20 5.00002 d 54 20 5.00001 d 55 20 5.0 d 56 20 5.0 d 57 20 5.0 d 58 20 5.0 d 59 20 4.99999 d 60 20 4.99999 d 61 20 4.99999 d 62 20 5.0 d 63 20 5.0 d 64 20 5.0 d 65 20 5.0 d 66 20 5.0 d 67 20 5.0 d 68 20 5.0 d 69 20 5.0 d 70 20 5.0 d 71 20 5.0 d 72 20 5.0 d 73 20 5.0 d 74 20 5.0 d 75 20 5.0 d 76 20 5.0 d 77 20 5.0 d 78 20 5.0 d 79 20 5.0 d 80 20 5.0 d 81 20 5.0 d 82 20 5.0 d 83 20 5.0 d 84 20 5.0 d 85 20 5.0 d 86 20 5.0 d 87 20 5.0 d 88 20 5.0 d 89 20 5.0 d 90 20 5.0 d 91 20 5.0 d 92 20 5.0 d 93 20 5.0 d 94 20 5.0 d 95 20 5.0 d 96 20 5.0 d 97 20 5.0 d 98 20 5.0 d 99 20 5.0 d 100 20 5.0 d 101 20 5.0 d 102 20 5.0 d 103 20 5.0 d 104 20 5.0 d 105 20 5.0 d 106 20 5.0 d 107 20 5.0 d 108 20 5.0 d 109 20 5.0 d 110 20 5.0 d 111 20 5.0 d 112 20 5.0 d 113 20 5.0 d 114 20 5.0 d 115 20 5.0 d 116 20 5.0 d 117 20 5.0 d 118 20 5.0 d 119 20 5.0 d 120 20 5.0 d 121 20 5.00017 d 122 20 5.17398 d 123 20 4.94779 d 124 20 3.78508 d 125 20 1.52302 d 126 20 0.608808 d 127 20 0.244311 d 128 20 0.126053 d 129 20 0.0597175 d 130 20 0.038422 d 131 20 0.0158174 d 132 20 0.00481338 d 133 20 0.00107847 d 134 20 0.000301256 d 135 20 0.000114861 d 136 20 0.00059489 d 137 20 -0.118904 d 138 20 -0.147478 d 139 20 -0.158986 d 140 20 -0.080544 d 141 20 0.165361 d 142 20 0.171378 d 143 20 0.0776087 d 144 20 0.0435738 d 145 20 0.0428235 d 146 20 0.0423755 d 147 20 0.0347695 d 148 20 0.0225061 d 149 20 0.0155539 d 150 20 0.0121357 d 151 20 0.0107997 d 152 20 0.0103976 d 153 20 0.0124406 d 154 20 0.016814 d 155 20 0.0167556 d 156 20 0.0149852 d 157 20 0.01459 d 158 20 0.0141182 d 159 20 0.0131934 d 160 20 0.0120286 d 161 20 0.0108692 d 162 20 0.0097184 d 163 20 0.00855881 d 164 20 0.00744912 d 165 20 0.00643877 d 166 20 0.00554044 d 167 20 0.00475165 d 168 20 0.00406535 d 169 20 0.00347158 d 170 20 0.00295981 d 171 20 0.00251995 d 172 20 0.00214318 d 173 20 0.00182101 d 174 20 0.00154613 d 175 20 0.00131196 d 176 20 0.0011119 d 177 20 0.000941587 d 178 20 0.000796999 d 179 20 0.000674582 d 180 20 0.000571283 d 181 20 0.000484276 d 182 20 0.000410649 d 183 20 0.000347005 d 184 20 0.000292984 d 185 20 0.000246715 d 186 20 0.000208143 d 187 20 0.00017489 d 188 20 0.000147412 d 189 20 0.000123854 d 190 20 0.000104332 d 191 20 8.77229e-05 d 192 20 7.40686e-05 d 193 20 6.2637e-05 d 194 20 5.32e-05 d 195 20 4.53946e-05 d 196 20 3.88343e-05 d 197 20 3.31864e-05 d 198 20 2.85905e-05 d 199 20 2.45725e-05 d 200 20 2.08671e-05 d 201 20 1.77301e-05 d 202 20 1.55911e-05 d 203 20 1.40153e-05 d 204 20 1.29421e-05 d 205 20 1.18693e-05 d 206 20 1.09815e-05 d 207 20 1.03484e-05 d 208 20 9.87664e-06 d 209 20 9.14446e-06 d 210 20 8.41228e-06 d 211 20 7.68011e-06 d 212 20 6.94793e-06 d 213 20 6.21575e-06 d 214 20 5.48357e-06 d 215 20 4.7514e-06 d 216 20 4.38454e-06 d 217 20 4.04432e-06 d 218 20 3.7041e-06 d 219 20 3.36388e-06 d 220 20 3.02366e-06 d 221 20 2.68344e-06 d 222 20 2.34322e-06 d 223 20 2.15196e-06 d 224 20 2.03791e-06 d 225 20 1.92386e-06 d 226 20 1.80982e-06 d 227 20 1.69577e-06 d 228 20 1.58173e-06 d 229 20 1.46768e-06 d 230 20 1.35363e-06 d 231 20 1.23959e-06 d 232 20 1.12554e-06 d 233 20 1.0115e-06 d 234 20 8.9745e-07 d 235 20 7.83404e-07 d 236 20 6.69358e-07 d 237 20 4.76113e-07 d 238 20 -3.47071e-07 d 239 20 -1.17025e-06 d 240 20 -1.99344e-06 d 241 20 -2.81662e-06 d 242 20 0.0783754 d 243 20 0.0500262 d 244 20 -0.0659563 d 245 20 -0.120914 d 246 20 0.0815957 d 247 20 0.0154255 d 248 20 0.00347177 d 249 20 0.000840357 d 250 20 0.000214582 d 251 20 6.54655e-05 d 252 20 3.91709e-05 d 253 20 8.07396e-06 d 254 20 -4.44265e-07 d 255 20 1.74384e-05 d 256 20 -4.52725e-05 d 257 20 -0.119379 d 258 20 -0.147984 d 259 20 -0.159247 d 260 20 -0.0824604 d 261 20 0.169014 d 262 20 0.177628 d 263 20 0.0758742 d 264 20 0.010558 d 265 20 -0.0346506 d 266 20 -0.0710288 d 267 20 -0.0838952 d 268 20 -0.0599521 d 269 20 -0.034568 d 270 20 -0.0181615 d 271 20 -0.00968034 d 272 20 -0.00547115 d 273 20 -0.00333511 d 274 20 -0.00232468 d 275 20 -0.00181159 d 276 20 -0.00143841 d 277 20 -0.00116601 d 278 20 -0.000839755 d 279 20 -0.000569764 d 280 20 -0.000578683 d 281 20 -0.000490551 d 282 20 -0.000411712 d 283 20 -0.000437859 d 284 20 -0.000408185 d 285 20 -0.000356644 d 286 20 -0.000311332 d 287 20 -0.000269006 d 288 20 -0.000221396 d 289 20 -0.000210054 d 290 20 -0.0001923 d 291 20 -0.000175122 d 292 20 -0.000161039 d 293 20 -0.0001428 d 294 20 -0.000126123 d 295 20 -0.000127893 d 296 20 -8.14516e-05 d 297 20 -0.000120166 d 298 20 -0.000154909 d 299 20 -0.000112733 d 300 20 -8.40377e-05 d 301 20 -7.11342e-05 d 302 20 -8.09538e-05 d 303 20 -9.77789e-05 d 304 20 -9.82402e-05 d 305 20 -7.73531e-05 d 306 20 -5.28255e-05 d 307 20 -3.1096e-05 d 308 20 -1.87967e-05 d 309 20 -1.96552e-05 d 310 20 -4.16655e-05 d 311 20 -5.77185e-05 d 312 20 -5.24142e-05 d 313 20 -2.83153e-05 d 314 20 -1.90012e-05 d 315 20 -1.54415e-05 d 316 20 -2.52569e-05 d 317 20 -6.23747e-05 d 318 20 -0.000130543 d 319 20 -0.000149394 d 320 20 -0.000110886 d 321 20 -4.35517e-05 d 322 20 -4.17084e-05 d 323 20 -3.98651e-05 d 324 20 -3.80218e-05 d 325 20 -3.61785e-05 d 326 20 -3.43352e-05 d 327 20 -3.36249e-05 d 328 20 -3.32729e-05 d 329 20 -3.29208e-05 d 330 20 -3.25687e-05 d 331 20 -3.22166e-05 d 332 20 -3.17143e-05 d 333 20 -3.10258e-05 d 334 20 -3.03372e-05 d 335 20 -2.96486e-05 d 336 20 -2.89601e-05 d 337 20 -2.82715e-05 d 338 20 -2.75829e-05 d 339 20 -2.68944e-05 d 340 20 -2.62058e-05 d 341 20 -2.55173e-05 d 342 20 -2.48287e-05 d 343 20 -2.43043e-05 d 344 20 -2.38159e-05 d 345 20 -2.33276e-05 d 346 20 -2.28393e-05 d 347 20 -2.2351e-05 d 348 20 -2.18626e-05 d 349 20 -2.13743e-05 d 350 20 -2.0886e-05 d 351 20 -2.03977e-05 d 352 20 -1.99093e-05 d 353 20 -1.945e-05 d 354 20 -1.91122e-05 d 355 20 -1.87744e-05 d 356 20 -1.84366e-05 d 357 20 -1.80987e-05 d 358 20 -1.77609e-05 d 359 20 -1.74231e-05 d 360 20 -1.70853e-05 d 361 20 -1.67474e-05 d 1 21 1.86175 d 2 21 1.99724 d 3 21 2.17266 d 4 21 2.48439 d 5 21 3.15933 d 6 21 3.85231 d 7 21 4.38091 d 8 21 4.69033 d 9 21 4.85034 d 10 21 4.92851 d 11 21 4.96453 d 12 21 4.98188 d 13 21 4.98736 d 14 21 4.991 d 15 21 4.99482 d 16 21 4.9973 d 17 21 4.96422 d 18 21 4.89989 d 19 21 4.83907 d 20 21 4.83151 d 21 21 4.90868 d 22 21 5.04854 d 23 21 5.06104 d 24 21 5.04571 d 25 21 5.03219 d 26 21 5.03025 d 27 21 5.02273 d 28 21 5.01707 d 29 21 5.0123 d 30 21 5.0087 d 31 21 5.00611 d 32 21 5.00429 d 33 21 5.00301 d 34 21 5.00211 d 35 21 5.00148 d 36 21 5.00103 d 37 21 5.00072 d 38 21 5.0005 d 39 21 5.00035 d 40 21 5.00024 d 41 21 5.00016 d 42 21 5.00011 d 43 21 5.00007 d 44 21 5.00005 d 45 21 5.00003 d 46 21 5.00001 d 47 21 4.99999 d 48 21 4.99998 d 49 21 4.99998 d 50 21 4.99998 d 51 21 4.99998 d 52 21 4.99998 d 53 21 4.99999 d 54 21 5.0 d 55 21 5.0 d 56 21 5.00001 d 57 21 5.00001 d 58 21 5.00002 d 59 21 5.00002 d 60 21 5.00002 d 61 21 5.00002 d 62 21 5.00002 d 63 21 5.00002 d 64 21 5.00001 d 65 21 5.00001 d 66 21 5.0 d 67 21 5.0 d 68 21 5.0 d 69 21 5.0 d 70 21 5.0 d 71 21 5.0 d 72 21 4.99999 d 73 21 4.99999 d 74 21 4.99999 d 75 21 4.99999 d 76 21 4.99999 d 77 21 4.99999 d 78 21 4.99999 d 79 21 4.99999 d 80 21 4.99999 d 81 21 4.99999 d 82 21 4.99999 d 83 21 4.99999 d 84 21 4.99999 d 85 21 5.0 d 86 21 5.0 d 87 21 5.0 d 88 21 5.0 d 89 21 5.0 d 90 21 5.0 d 91 21 5.0 d 92 21 5.0 d 93 21 5.00001 d 94 21 5.00001 d 95 21 5.00001 d 96 21 5.00001 d 97 21 5.00001 d 98 21 5.00001 d 99 21 5.00001 d 100 21 5.00001 d 101 21 5.00001 d 102 21 5.00001 d 103 21 5.00001 d 104 21 5.00001 d 105 21 5.00001 d 106 21 5.00001 d 107 21 5.00001 d 108 21 5.00001 d 109 21 5.00001 d 110 21 5.00001 d 111 21 5.00001 d 112 21 5.00001 d 113 21 5.00001 d 114 21 5.00001 d 115 21 5.0 d 116 21 5.0 d 117 21 5.0 d 118 21 5.0 d 119 21 5.0 d 120 21 5.0 d 121 21 4.99981 d 122 21 5.10081 d 123 21 5.10903 d 124 21 4.98404 d 125 21 5.00999 d 126 21 5.14946 d 127 21 4.36501 d 128 21 2.23938 d 129 21 0.325144 d 130 21 0.00660272 d 131 21 -0.0102186 d 132 21 -0.0082401 d 133 21 -0.00556785 d 134 21 -0.00374178 d 135 21 -0.00264763 d 136 21 -0.00202823 d 137 21 -0.0182241 d 138 21 -0.0169551 d 139 21 -0.0150395 d 140 21 0.0103736 d 141 21 0.0877592 d 142 21 0.104382 d 143 21 0.0515938 d 144 21 0.0373818 d 145 21 0.0411547 d 146 21 0.0397009 d 147 21 0.0308946 d 148 21 0.0205793 d 149 21 0.0154037 d 150 21 0.0129191 d 151 21 0.0119327 d 152 21 0.011527 d 153 21 0.0124295 d 154 21 0.0161152 d 155 21 0.0161076 d 156 21 0.0145391 d 157 21 0.0144541 d 158 21 0.0139287 d 159 21 0.0129215 d 160 21 0.0117239 d 161 21 0.0105795 d 162 21 0.00942983 d 163 21 0.00827423 d 164 21 0.00718354 d 165 21 0.00619954 d 166 21 0.00532868 d 167 21 0.00456631 d 168 21 0.00390448 d 169 21 0.00333254 d 170 21 0.00284003 d 171 21 0.00241714 d 172 21 0.00205524 d 173 21 0.0017458 d 174 21 0.00148202 d 175 21 0.00125739 d 176 21 0.0010655 d 177 21 0.000902213 d 178 21 0.000763611 d 179 21 0.000646279 d 180 21 0.000547291 d 181 21 0.000463934 d 182 21 0.000393401 d 183 21 0.000332424 d 184 21 0.000280655 d 185 21 0.000236328 d 186 21 0.000199386 d 187 21 0.000167536 d 188 21 0.000141218 d 189 21 0.000118654 d 190 21 9.99559e-05 d 191 21 8.40479e-05 d 192 21 7.09694e-05 d 193 21 6.00188e-05 d 194 21 5.09786e-05 d 195 21 4.3502e-05 d 196 21 3.72191e-05 d 197 21 3.18114e-05 d 198 21 2.74071e-05 d 199 21 2.35539e-05 d 200 21 1.99967e-05 d 201 21 1.69871e-05 d 202 21 1.49449e-05 d 203 21 1.3451e-05 d 204 21 1.24492e-05 d 205 21 1.14256e-05 d 206 21 1.05669e-05 d 207 21 9.94487e-06 d 208 21 9.47514e-06 d 209 21 8.77318e-06 d 210 21 8.07123e-06 d 211 21 7.36927e-06 d 212 21 6.66731e-06 d 213 21 5.96536e-06 d 214 21 5.2634e-06 d 215 21 4.56144e-06 d 216 21 4.23044e-06 d 217 21 3.92649e-06 d 218 21 3.62254e-06 d 219 21 3.31858e-06 d 220 21 3.01463e-06 d 221 21 2.71068e-06 d 222 21 2.40673e-06 d 223 21 2.23063e-06 d 224 21 2.12082e-06 d 225 21 2.01102e-06 d 226 21 1.90121e-06 d 227 21 1.7914e-06 d 228 21 1.68159e-06 d 229 21 1.57178e-06 d 230 21 1.46197e-06 d 231 21 1.35216e-06 d 232 21 1.24235e-06 d 233 21 1.13255e-06 d 234 21 1.02274e-06 d 235 21 9.12929e-07 d 236 21 8.0312e-07 d 237 21 6.33171e-07 d 238 21 -1.51288e-08 d 239 21 -6.63428e-07 d 240 21 -1.31173e-06 d 241 21 -1.96003e-06 d 242 21 0.0437517 d 243 21 0.0265689 d 244 21 -0.0515377 d 245 21 -0.0658688 d 246 21 0.010727 d 247 21 -0.000511921 d 248 21 -8.36924e-05 d 249 21 2.13278e-05 d 250 21 1.45207e-05 d 251 21 4.54862e-06 d 252 21 -6.14726e-06 d 253 21 2.0062e-06 d 254 21 1.02709e-06 d 255 21 1.4152e-05 d 256 21 -3.08225e-05 d 257 21 -0.0166501 d 258 21 -0.0157139 d 259 21 -0.013957 d 260 21 0.0107537 d 261 21 0.0873717 d 262 21 0.111302 d 263 21 0.0454129 d 264 21 -0.00530142 d 265 21 -0.0468336 d 266 21 -0.0790063 d 267 21 -0.0826944 d 268 21 -0.0534753 d 269 21 -0.0288705 d 270 21 -0.0149009 d 271 21 -0.00801592 d 272 21 -0.0046342 d 273 21 -0.00291835 d 274 21 -0.00213019 d 275 21 -0.00170055 d 276 21 -0.001352 d 277 21 -0.00110593 d 278 21 -0.000742655 d 279 21 -0.000532042 d 280 21 -0.000544742 d 281 21 -0.000479206 d 282 21 -0.000407307 d 283 21 -0.000403575 d 284 21 -0.000366209 d 285 21 -0.000324161 d 286 21 -0.000286183 d 287 21 -0.000247579 d 288 21 -0.000214281 d 289 21 -0.000203435 d 290 21 -0.000186896 d 291 21 -0.000171033 d 292 21 -0.00015779 d 293 21 -0.000145259 d 294 21 -0.000128069 d 295 21 -0.000122647 d 296 21 -9.89398e-05 d 297 21 -0.000114926 d 298 21 -0.000132195 d 299 21 -0.000107872 d 300 21 -8.91015e-05 d 301 21 -7.87996e-05 d 302 21 -8.14061e-05 d 303 21 -8.9098e-05 d 304 21 -8.83368e-05 d 305 21 -7.6122e-05 d 306 21 -6.14668e-05 d 307 21 -4.75402e-05 d 308 21 -3.81855e-05 d 309 21 -3.69696e-05 d 310 21 -4.78656e-05 d 311 21 -5.61346e-05 d 312 21 -5.35007e-05 d 313 21 -4.1459e-05 d 314 21 -3.35411e-05 d 315 21 -2.52374e-05 d 316 21 -2.37479e-05 d 317 21 -4.6406e-05 d 318 21 -9.41884e-05 d 319 21 -0.000109222 d 320 21 -8.52676e-05 d 321 21 -4.25166e-05 d 322 21 -4.10125e-05 d 323 21 -3.95085e-05 d 324 21 -3.80045e-05 d 325 21 -3.65004e-05 d 326 21 -3.49964e-05 d 327 21 -3.41627e-05 d 328 21 -3.3541e-05 d 329 21 -3.29193e-05 d 330 21 -3.22976e-05 d 331 21 -3.16758e-05 d 332 21 -3.10334e-05 d 333 21 -3.03653e-05 d 334 21 -2.96971e-05 d 335 21 -2.9029e-05 d 336 21 -2.83609e-05 d 337 21 -2.76928e-05 d 338 21 -2.70246e-05 d 339 21 -2.63565e-05 d 340 21 -2.56884e-05 d 341 21 -2.50203e-05 d 342 21 -2.43521e-05 d 343 21 -2.38716e-05 d 344 21 -2.34324e-05 d 345 21 -2.29932e-05 d 346 21 -2.25539e-05 d 347 21 -2.21147e-05 d 348 21 -2.16755e-05 d 349 21 -2.12362e-05 d 350 21 -2.0797e-05 d 351 21 -2.03578e-05 d 352 21 -1.99186e-05 d 353 21 -1.95079e-05 d 354 21 -1.9217e-05 d 355 21 -1.8926e-05 d 356 21 -1.8635e-05 d 357 21 -1.8344e-05 d 358 21 -1.8053e-05 d 359 21 -1.7762e-05 d 360 21 -1.74711e-05 d 361 21 -1.71801e-05 d 1 22 1.86175 d 2 22 1.73273 d 3 22 1.42016 d 4 22 1.02483 d 5 22 0.944013 d 6 22 0.274107 d 7 22 0.0823742 d 8 22 0.0379366 d 9 22 0.020816 d 10 22 0.0132952 d 11 22 0.00955525 d 12 22 0.00717008 d 13 22 0.00592286 d 14 22 0.00437379 d 15 22 0.00383557 d 16 22 0.00273694 d 17 22 -0.0037467 d 18 22 -0.0054191 d 19 22 -0.00131454 d 20 22 0.0112179 d 21 22 0.0133918 d 22 22 0.00519747 d 23 22 -0.00260113 d 24 22 -0.00252847 d 25 22 -0.00181292 d 26 22 0.000183398 d 27 22 -0.000667607 d 28 22 -0.000750747 d 29 22 -0.000594314 d 30 22 -0.000433904 d 31 22 -0.000308985 d 32 22 -0.000217858 d 33 22 -0.000152926 d 34 22 -0.000107454 d 35 22 -7.54076e-05 d 36 22 -5.2675e-05 d 37 22 -3.66299e-05 d 38 22 -2.54341e-05 d 39 22 -1.75095e-05 d 40 22 -1.18848e-05 d 41 22 -7.97289e-06 d 42 22 -5.30239e-06 d 43 22 -3.53615e-06 d 44 22 -2.38504e-06 d 45 22 -2.40158e-06 d 46 22 -3.84485e-06 d 47 22 -5.29435e-06 d 48 22 -2.57099e-06 d 49 22 1.95189e-06 d 50 22 3.55083e-06 d 51 22 2.06179e-06 d 52 22 5.72753e-07 d 53 22 3.30469e-07 d 54 22 3.40296e-07 d 55 22 3.60221e-07 d 56 22 4.86081e-07 d 57 22 6.1194e-07 d 58 22 7.37799e-07 d 59 22 8.63659e-07 d 60 22 9.89518e-07 d 61 22 9.21274e-07 d 62 22 7.22275e-07 d 63 22 5.23276e-07 d 64 22 3.24277e-07 d 65 22 1.25278e-07 d 66 22 -5.59467e-08 d 67 22 -9.03265e-08 d 68 22 -1.24706e-07 d 69 22 -1.59086e-07 d 70 22 -1.93466e-07 d 71 22 -2.27846e-07 d 72 22 -2.62226e-07 d 73 22 -2.96605e-07 d 74 22 -3.30985e-07 d 75 22 -3.65365e-07 d 76 22 -3.99745e-07 d 77 22 -4.24266e-07 d 78 22 -3.82163e-07 d 79 22 -3.40061e-07 d 80 22 -2.97959e-07 d 81 22 -2.55857e-07 d 82 22 -2.13755e-07 d 83 22 -1.71652e-07 d 84 22 -1.2955e-07 d 85 22 -8.7448e-08 d 86 22 -4.53457e-08 d 87 22 -3.24353e-09 d 88 22 3.76901e-08 d 89 22 7.19937e-08 d 90 22 1.06297e-07 d 91 22 1.40601e-07 d 92 22 1.74904e-07 d 93 22 2.09208e-07 d 94 22 2.43512e-07 d 95 22 2.77815e-07 d 96 22 3.12119e-07 d 97 22 3.46422e-07 d 98 22 3.80726e-07 d 99 22 4.04507e-07 d 100 22 3.77191e-07 d 101 22 3.49876e-07 d 102 22 3.22561e-07 d 103 22 2.95246e-07 d 104 22 2.67931e-07 d 105 22 2.40616e-07 d 106 22 2.13301e-07 d 107 22 1.85986e-07 d 108 22 1.58671e-07 d 109 22 1.31356e-07 d 110 22 1.04041e-07 d 111 22 7.67256e-08 d 112 22 4.94105e-08 d 113 22 2.20955e-08 d 114 22 -5.21962e-09 d 115 22 -3.25347e-08 d 116 22 -5.98498e-08 d 117 22 -8.71649e-08 d 118 22 -1.1448e-07 d 119 22 -1.41795e-07 d 120 22 -1.6911e-07 d 121 22 7.87893e-06 d 122 22 0.0114592 d 123 22 -0.0245712 d 124 22 -0.111637 d 125 22 0.0961324 d 126 22 1.61168 d 127 22 3.22343 d 128 22 4.20442 d 129 22 4.53535 d 130 22 4.83834 d 131 22 4.95464 d 132 22 4.98874 d 133 22 4.99746 d 134 22 4.99883 d 135 22 4.99948 d 136 22 4.99815 d 137 22 4.98431 d 138 22 4.99298 d 139 22 4.99718 d 140 22 5.01948 d 141 22 5.04749 d 142 22 5.008 d 143 22 4.98243 d 144 22 4.98985 d 145 22 4.99781 d 146 22 4.99887 d 147 22 4.99679 d 148 22 4.99616 d 149 22 4.99743 d 150 22 4.99859 d 151 22 4.99936 d 152 22 4.99972 d 153 22 5.00058 d 154 22 5.00123 d 155 22 5.0002 d 156 22 4.99945 d 157 22 4.99983 d 158 22 4.9998 d 159 22 4.99966 d 160 22 4.99958 d 161 22 4.99956 d 162 22 4.99956 d 163 22 4.99956 d 164 22 4.99958 d 165 22 4.99961 d 166 22 4.99965 d 167 22 4.99969 d 168 22 4.99973 d 169 22 4.99977 d 170 22 4.9998 d 171 22 4.99983 d 172 22 4.99985 d 173 22 4.99987 d 174 22 4.99989 d 175 22 4.99991 d 176 22 4.99992 d 177 22 4.99993 d 178 22 4.99994 d 179 22 4.99995 d 180 22 4.99996 d 181 22 4.99997 d 182 22 4.99997 d 183 22 4.99998 d 184 22 4.99998 d 185 22 4.99998 d 186 22 4.99999 d 187 22 4.99999 d 188 22 4.99999 d 189 22 4.99999 d 190 22 4.99999 d 191 22 4.99999 d 192 22 4.99999 d 193 22 5.0 d 194 22 5.0 d 195 22 5.0 d 196 22 5.0 d 197 22 5.0 d 198 22 5.0 d 199 22 5.0 d 200 22 5.0 d 201 22 5.0 d 202 22 5.0 d 203 22 5.0 d 204 22 5.0 d 205 22 5.0 d 206 22 5.0 d 207 22 5.0 d 208 22 5.0 d 209 22 5.0 d 210 22 5.0 d 211 22 5.0 d 212 22 5.0 d 213 22 5.0 d 214 22 5.0 d 215 22 5.0 d 216 22 5.0 d 217 22 5.00001 d 218 22 5.00001 d 219 22 5.00001 d 220 22 5.00002 d 221 22 5.00002 d 222 22 5.00002 d 223 22 5.00002 d 224 22 5.00002 d 225 22 5.00002 d 226 22 5.00002 d 227 22 5.00002 d 228 22 5.00001 d 229 22 5.00001 d 230 22 5.00001 d 231 22 5.00001 d 232 22 5.00001 d 233 22 5.00001 d 234 22 5.00001 d 235 22 5.0 d 236 22 5.0 d 237 22 5.0 d 238 22 4.99999 d 239 22 4.99998 d 240 22 4.99997 d 241 22 4.99996 d 242 22 5.01454 d 243 22 4.99566 d 244 22 4.96796 d 245 22 4.99819 d 246 22 5.03232 d 247 22 5.00034 d 248 22 4.99867 d 249 22 4.99937 d 250 22 4.99977 d 251 22 4.99992 d 252 22 4.99997 d 253 22 4.99999 d 254 22 5.00001 d 255 22 5.00021 d 256 22 4.99974 d 257 22 4.98462 d 258 22 4.99301 d 259 22 4.99723 d 260 22 5.01936 d 261 22 5.04807 d 262 22 5.00929 d 263 22 4.9789 d 264 22 4.97876 d 265 22 4.98244 d 266 22 4.9863 d 267 22 4.99575 d 268 22 5.0069 d 269 22 5.00863 d 270 22 5.00624 d 271 22 5.00357 d 272 22 5.0019 d 273 22 5.00098 d 274 22 5.00048 d 275 22 5.00025 d 276 22 5.00016 d 277 22 5.00011 d 278 22 5.00013 d 279 22 5.00009 d 280 22 4.99982 d 281 22 4.99994 d 282 22 5.00005 d 283 22 4.99994 d 284 22 4.99988 d 285 22 4.99989 d 286 22 4.99997 d 287 22 5.00003 d 288 22 5.00005 d 289 22 5.00002 d 290 22 5.00001 d 291 22 5.00001 d 292 22 5.00001 d 293 22 4.99993 d 294 22 4.99999 d 295 22 5.0 d 296 22 5.00021 d 297 22 4.99997 d 298 22 4.99981 d 299 22 5.0 d 300 22 5.00009 d 301 22 5.0001 d 302 22 5.00001 d 303 22 4.99991 d 304 22 4.9999 d 305 22 5.0 d 306 22 5.00011 d 307 22 5.00017 d 308 22 5.00018 d 309 22 5.00018 d 310 22 5.00014 d 311 22 5.00007 d 312 22 4.99999 d 313 22 4.9999 d 314 22 4.9999 d 315 22 5.00001 d 316 22 5.00016 d 317 22 5.00014 d 318 22 4.99999 d 319 22 4.99993 d 320 22 4.99999 d 321 22 5.00009 d 322 22 5.00007 d 323 22 5.00006 d 324 22 5.00004 d 325 22 5.00003 d 326 22 5.00001 d 327 22 5.00001 d 328 22 5.0 d 329 22 4.99999 d 330 22 4.99998 d 331 22 4.99997 d 332 22 4.99997 d 333 22 4.99997 d 334 22 4.99998 d 335 22 4.99998 d 336 22 4.99998 d 337 22 4.99998 d 338 22 4.99999 d 339 22 4.99999 d 340 22 4.99999 d 341 22 5.0 d 342 22 5.0 d 343 22 5.0 d 344 22 5.0 d 345 22 5.0 d 346 22 5.0 d 347 22 5.00001 d 348 22 5.00001 d 349 22 5.00001 d 350 22 5.00001 d 351 22 5.00001 d 352 22 5.00002 d 353 22 5.00002 d 354 22 5.00001 d 355 22 5.00001 d 356 22 5.00001 d 357 22 5.00001 d 358 22 5.00001 d 359 22 5.00001 d 360 22 5.0 d 361 22 5.0 d 1 23 7.10441e-10 d 2 23 0.00107105 d 3 23 0.000637109 d 4 23 -0.00236346 d 5 23 -0.018079 d 6 23 -0.0120077 d 7 23 -0.00217059 d 8 23 0.00266679 d 9 23 0.00403383 d 10 23 0.00403836 d 11 23 0.00356705 d 12 23 0.00303303 d 13 23 0.00244716 d 14 23 0.00198586 d 15 23 0.0016855 d 16 23 0.00136497 d 17 23 -3.96022e-05 d 18 23 -0.000367409 d 19 23 -3.77079e-05 d 20 23 0.00194085 d 21 23 0.00506964 d 22 23 -0.0400214 d 23 23 -0.0402572 d 24 23 0.0524434 d 25 23 0.286234 d 26 23 0.803011 d 27 23 1.44795 d 28 23 2.02473 d 29 23 2.54768 d 30 23 3.02748 d 31 23 3.4415 d 32 23 3.78287 d 33 23 4.09667 d 34 23 4.35152 d 35 23 4.53987 d 36 23 4.67614 d 37 23 4.77407 d 38 23 4.84319 d 39 23 4.89227 d 40 23 4.92702 d 41 23 4.95119 d 42 23 4.96764 d 43 23 4.97846 d 44 23 4.98557 d 45 23 4.98982 d 46 23 4.99209 d 47 23 4.99371 d 48 23 4.99569 d 49 23 4.99727 d 50 23 4.99802 d 51 23 4.99834 d 52 23 4.99867 d 53 23 4.99892 d 54 23 4.99915 d 55 23 4.99936 d 56 23 4.99939 d 57 23 4.99943 d 58 23 4.99946 d 59 23 4.9995 d 60 23 4.99953 d 61 23 4.99957 d 62 23 4.9996 d 63 23 4.99963 d 64 23 4.99967 d 65 23 4.9997 d 66 23 4.99973 d 67 23 4.99974 d 68 23 4.99975 d 69 23 4.99976 d 70 23 4.99977 d 71 23 4.99978 d 72 23 4.9998 d 73 23 4.99981 d 74 23 4.99982 d 75 23 4.99983 d 76 23 4.99984 d 77 23 4.99985 d 78 23 4.99986 d 79 23 4.99986 d 80 23 4.99986 d 81 23 4.99987 d 82 23 4.99987 d 83 23 4.99988 d 84 23 4.99988 d 85 23 4.99989 d 86 23 4.99989 d 87 23 4.9999 d 88 23 4.9999 d 89 23 4.9999 d 90 23 4.9999 d 91 23 4.99991 d 92 23 4.99991 d 93 23 4.99991 d 94 23 4.99991 d 95 23 4.99992 d 96 23 4.99992 d 97 23 4.99992 d 98 23 4.99992 d 99 23 4.99993 d 100 23 4.99993 d 101 23 4.99993 d 102 23 4.99993 d 103 23 4.99993 d 104 23 4.99993 d 105 23 4.99993 d 106 23 4.99993 d 107 23 4.99994 d 108 23 4.99994 d 109 23 4.99994 d 110 23 4.99994 d 111 23 4.99994 d 112 23 4.99994 d 113 23 4.99994 d 114 23 4.99994 d 115 23 4.99995 d 116 23 4.99995 d 117 23 4.99995 d 118 23 4.99995 d 119 23 4.99995 d 120 23 4.99995 d 121 23 4.99995 d 122 23 5.00145 d 123 23 5.00659 d 124 23 5.01209 d 125 23 5.01931 d 126 23 5.00279 d 127 23 4.99273 d 128 23 4.99217 d 129 23 4.99295 d 130 23 4.99471 d 131 23 4.99594 d 132 23 4.99696 d 133 23 4.9978 d 134 23 4.99844 d 135 23 4.99891 d 136 23 4.99924 d 137 23 4.99635 d 138 23 4.99699 d 139 23 4.99813 d 140 23 5.00068 d 141 23 5.00307 d 142 23 5.0588 d 143 23 4.96365 d 144 23 4.54012 d 145 23 3.6307 d 146 23 2.35176 d 147 23 1.0322 d 148 23 0.354379 d 149 23 0.115986 d 150 23 0.0435668 d 151 23 0.0245112 d 152 23 0.020786 d 153 23 0.0164656 d 154 23 0.0118409 d 155 23 0.00849698 d 156 23 0.00597078 d 157 23 0.0040105 d 158 23 0.0026076 d 159 23 0.0016597 d 160 23 0.00118185 d 161 23 0.00121067 d 162 23 0.00153587 d 163 23 0.00174836 d 164 23 0.00136519 d 165 23 -0.000189116 d 166 23 -0.00315555 d 167 23 -0.00646603 d 168 23 -0.00898042 d 169 23 -0.010203 d 170 23 -0.0110896 d 171 23 -0.0123764 d 172 23 -0.00953841 d 173 23 -0.00225795 d 174 23 0.000818314 d 175 23 0.00152252 d 176 23 0.00150269 d 177 23 0.00119025 d 178 23 0.000767068 d 179 23 0.000308852 d 180 23 -3.79272e-05 d 181 23 -0.00019691 d 182 23 -0.000186642 d 183 23 -9.73653e-05 d 184 23 -8.49784e-06 d 185 23 2.04147e-05 d 186 23 -9.91086e-06 d 187 23 -1.55959e-05 d 188 23 -1.80499e-05 d 189 23 -1.77097e-05 d 190 23 -1.51548e-05 d 191 23 -1.1978e-05 d 192 23 -9.84916e-06 d 193 23 -1.29728e-05 d 194 23 -1.67235e-05 d 195 23 -1.74153e-05 d 196 23 -1.39958e-05 d 197 23 -5.92272e-06 d 198 23 -8.08216e-06 d 199 23 -1.53077e-05 d 200 23 -2.92531e-05 d 201 23 -3.91049e-05 d 202 23 -2.98935e-05 d 203 23 -7.32122e-06 d 204 23 3.18534e-05 d 205 23 4.39134e-05 d 206 23 4.18753e-05 d 207 23 3.22759e-05 d 208 23 1.86766e-05 d 209 23 1.58432e-05 d 210 23 1.30098e-05 d 211 23 1.01765e-05 d 212 23 7.34312e-06 d 213 23 4.50975e-06 d 214 23 1.67639e-06 d 215 23 -1.15697e-06 d 216 23 -1.23877e-06 d 217 23 -1.11991e-06 d 218 23 -1.00106e-06 d 219 23 -8.82208e-07 d 220 23 -7.63355e-07 d 221 23 -6.44502e-07 d 222 23 -5.2565e-07 d 223 23 -4.29318e-07 d 224 23 -3.44661e-07 d 225 23 -2.60004e-07 d 226 23 -1.75347e-07 d 227 23 -9.06904e-08 d 228 23 -6.03349e-09 d 229 23 7.86234e-08 d 230 23 1.6328e-07 d 231 23 2.47937e-07 d 232 23 3.32594e-07 d 233 23 4.17251e-07 d 234 23 5.01908e-07 d 235 23 5.86565e-07 d 236 23 6.71222e-07 d 237 23 7.36123e-07 d 238 23 6.43886e-07 d 239 23 5.5165e-07 d 240 23 4.59414e-07 d 241 23 3.67178e-07 d 242 23 0.000334759 d 243 23 -4.60833e-05 d 244 23 -0.00106139 d 245 23 -0.00166624 d 246 23 0.000859563 d 247 23 0.00102606 d 248 23 0.00410037 d 249 23 0.00419931 d 250 23 0.00518997 d 251 23 0.00459791 d 252 23 0.00503125 d 253 23 0.00523877 d 254 23 0.00452158 d 255 23 0.00339924 d 256 23 0.00233399 d 257 23 0.000876915 d 258 23 0.000546439 d 259 23 0.000444299 d 260 23 0.000983968 d 261 23 0.00119304 d 262 23 -0.0429422 d 263 23 -0.0403983 d 264 23 0.0534896 d 265 23 0.288013 d 266 23 0.807345 d 267 23 1.44247 d 268 23 2.03448 d 269 23 2.57021 d 270 23 3.05049 d 271 23 3.47332 d 272 23 3.8131 d 273 23 4.1009 d 274 23 4.34677 d 275 23 4.53512 d 276 23 4.67127 d 277 23 4.76531 d 278 23 4.82526 d 279 23 4.86593 d 280 23 4.89586 d 281 23 4.91904 d 282 23 4.93806 d 283 23 4.95348 d 284 23 4.96597 d 285 23 4.97629 d 286 23 4.9843 d 287 23 4.98983 d 288 23 4.99335 d 289 23 4.9957 d 290 23 4.99741 d 291 23 4.99864 d 292 23 4.99946 d 293 23 4.99994 d 294 23 5.00047 d 295 23 5.00073 d 296 23 5.00086 d 297 23 5.00092 d 298 23 5.00094 d 299 23 5.00091 d 300 23 5.00087 d 301 23 5.00081 d 302 23 5.00074 d 303 23 5.00067 d 304 23 5.00059 d 305 23 5.00052 d 306 23 5.00046 d 307 23 5.0004 d 308 23 5.00034 d 309 23 5.0003 d 310 23 5.00026 d 311 23 5.00022 d 312 23 5.00019 d 313 23 5.00016 d 314 23 5.00014 d 315 23 5.00012 d 316 23 5.0001 d 317 23 5.00009 d 318 23 5.00007 d 319 23 5.00006 d 320 23 5.00006 d 321 23 5.00005 d 322 23 5.00004 d 323 23 5.00004 d 324 23 5.00004 d 325 23 5.00003 d 326 23 5.00003 d 327 23 5.00003 d 328 23 5.00002 d 329 23 5.00002 d 330 23 5.00002 d 331 23 5.00002 d 332 23 5.00001 d 333 23 5.00001 d 334 23 5.00001 d 335 23 5.00001 d 336 23 5.00001 d 337 23 5.0 d 338 23 5.0 d 339 23 5.0 d 340 23 5.0 d 341 23 4.99999 d 342 23 4.99999 d 343 23 4.99999 d 344 23 4.99999 d 345 23 4.99999 d 346 23 4.99999 d 347 23 5.0 d 348 23 5.0 d 349 23 5.0 d 350 23 5.0 d 351 23 5.0 d 352 23 5.0 d 353 23 5.0 d 354 23 5.0 d 355 23 5.0 d 356 23 5.00001 d 357 23 5.00001 d 358 23 5.00001 d 359 23 5.00001 d 360 23 5.00002 d 361 23 5.00002 d 1 24 5.0 d 2 24 5.00284 d 3 24 5.01266 d 4 24 5.01895 d 5 24 4.98936 d 6 24 4.99575 d 7 24 4.99217 d 8 24 4.99545 d 9 24 4.99775 d 10 24 4.99894 d 11 24 4.99946 d 12 24 4.99968 d 13 24 4.99975 d 14 24 4.99977 d 15 24 4.99986 d 16 24 4.9999 d 17 24 4.99528 d 18 24 4.99808 d 19 24 5.00039 d 20 24 5.00392 d 21 24 5.00512 d 22 24 4.99985 d 23 24 4.99863 d 24 24 4.99942 d 25 24 4.99992 d 26 24 5.00017 d 27 24 4.99897 d 28 24 4.99803 d 29 24 4.99784 d 30 24 4.99739 d 31 24 4.99883 d 32 24 5.00365 d 33 24 5.00298 d 34 24 5.00133 d 35 24 5.00048 d 36 24 5.00019 d 37 24 5.00008 d 38 24 5.00005 d 39 24 5.00004 d 40 24 5.00003 d 41 24 5.00002 d 42 24 5.00002 d 43 24 5.00001 d 44 24 5.00001 d 45 24 5.00001 d 46 24 5.00001 d 47 24 5.00001 d 48 24 5.0 d 49 24 5.0 d 50 24 4.99999 d 51 24 4.99997 d 52 24 4.99995 d 53 24 4.99996 d 54 24 4.99998 d 55 24 5.0 d 56 24 5.00001 d 57 24 5.00001 d 58 24 5.00002 d 59 24 5.00002 d 60 24 5.00003 d 61 24 5.00003 d 62 24 5.00002 d 63 24 5.00002 d 64 24 5.00001 d 65 24 5.00001 d 66 24 5.0 d 67 24 5.0 d 68 24 5.0 d 69 24 5.0 d 70 24 5.0 d 71 24 4.99999 d 72 24 4.99999 d 73 24 4.99999 d 74 24 4.99999 d 75 24 4.99999 d 76 24 4.99999 d 77 24 4.99998 d 78 24 4.99999 d 79 24 4.99999 d 80 24 4.99999 d 81 24 4.99999 d 82 24 4.99999 d 83 24 4.99999 d 84 24 4.99999 d 85 24 5.0 d 86 24 5.0 d 87 24 5.0 d 88 24 5.0 d 89 24 5.0 d 90 24 5.0 d 91 24 5.0 d 92 24 5.00001 d 93 24 5.00001 d 94 24 5.00001 d 95 24 5.00001 d 96 24 5.00001 d 97 24 5.00001 d 98 24 5.00001 d 99 24 5.00002 d 100 24 5.00002 d 101 24 5.00001 d 102 24 5.00001 d 103 24 5.00001 d 104 24 5.00001 d 105 24 5.00001 d 106 24 5.00001 d 107 24 5.00001 d 108 24 5.00001 d 109 24 5.00001 d 110 24 5.00001 d 111 24 5.00001 d 112 24 5.00001 d 113 24 5.00001 d 114 24 5.00001 d 115 24 5.0 d 116 24 5.0 d 117 24 5.0 d 118 24 5.0 d 119 24 5.0 d 120 24 5.0 d 121 24 5.0 d 122 24 5.00217 d 123 24 5.00108 d 124 24 4.99547 d 125 24 4.99658 d 126 24 5.00667 d 127 24 4.99641 d 128 24 4.99532 d 129 24 4.99938 d 130 24 5.00328 d 131 24 5.00222 d 132 24 5.00114 d 133 24 5.00052 d 134 24 5.00024 d 135 24 5.00011 d 136 24 5.00009 d 137 24 4.99285 d 138 24 4.99591 d 139 24 4.99897 d 140 24 5.00403 d 141 24 5.00786 d 142 24 5.00318 d 143 24 4.99942 d 144 24 4.9992 d 145 24 4.99949 d 146 24 5.001 d 147 24 5.00408 d 148 24 5.00319 d 149 24 5.00063 d 150 24 4.99995 d 151 24 5.00014 d 152 24 4.99982 d 153 24 4.99832 d 154 24 4.99838 d 155 24 4.99865 d 156 24 4.99912 d 157 24 4.99836 d 158 24 4.99735 d 159 24 4.99606 d 160 24 4.99814 d 161 24 5.00958 d 162 24 5.02973 d 163 24 5.05293 d 164 24 5.06103 d 165 24 4.99342 d 166 24 4.80726 d 167 24 4.50744 d 168 24 4.07509 d 169 24 3.41358 d 170 24 2.37924 d 171 24 1.03194 d 172 24 0.261552 d 173 24 0.142392 d 174 24 0.0904482 d 175 24 0.0555071 d 176 24 0.0322869 d 177 24 0.018289 d 178 24 0.0113802 d 179 24 0.00875182 d 180 24 0.00757055 d 181 24 0.00629906 d 182 24 0.00523 d 183 24 0.00403349 d 184 24 0.0031953 d 185 24 0.00280864 d 186 24 0.00286119 d 187 24 0.00250389 d 188 24 0.00202815 d 189 24 0.001723 d 190 24 0.00147312 d 191 24 0.0012411 d 192 24 0.00104401 d 193 24 0.000886204 d 194 24 0.000758277 d 195 24 0.000651915 d 196 24 0.00056348 d 197 24 0.000487966 d 198 24 0.000424048 d 199 24 0.000365613 d 200 24 0.000308178 d 201 24 0.000258725 d 202 24 0.000228061 d 203 24 0.000207976 d 204 24 0.000198491 d 205 24 0.00018518 d 206 24 0.000172716 d 207 24 0.000163197 d 208 24 0.000155007 d 209 24 0.000141734 d 210 24 0.000128461 d 211 24 0.000115188 d 212 24 0.000101915 d 213 24 8.86417e-05 d 214 24 7.53686e-05 d 215 24 6.20956e-05 d 216 24 5.69164e-05 d 217 24 5.23275e-05 d 218 24 4.77385e-05 d 219 24 4.31495e-05 d 220 24 3.85605e-05 d 221 24 3.39716e-05 d 222 24 2.93826e-05 d 223 24 2.69449e-05 d 224 24 2.56224e-05 d 225 24 2.42999e-05 d 226 24 2.29774e-05 d 227 24 2.16549e-05 d 228 24 2.03324e-05 d 229 24 1.90099e-05 d 230 24 1.76873e-05 d 231 24 1.63648e-05 d 232 24 1.50423e-05 d 233 24 1.37198e-05 d 234 24 1.23973e-05 d 235 24 1.10748e-05 d 236 24 9.75232e-06 d 237 24 8.48447e-06 d 238 24 7.65129e-06 d 239 24 6.81811e-06 d 240 24 5.98494e-06 d 241 24 5.15176e-06 d 242 24 0.00056893 d 243 24 -0.00787906 d 244 24 -0.0217381 d 245 24 -0.0370066 d 246 24 -0.00770505 d 247 24 0.00659312 d 248 24 0.00975477 d 249 24 0.00949456 d 250 24 0.00777552 d 251 24 0.00655645 d 252 24 0.00568776 d 253 24 0.00508782 d 254 24 0.00458121 d 255 24 0.00410187 d 256 24 0.00365665 d 257 24 0.0015121 d 258 24 0.00160863 d 259 24 0.00263181 d 260 24 0.00638941 d 261 24 0.00772607 d 262 24 0.00225583 d 263 24 0.0010843 d 264 24 0.000882939 d 265 24 0.000801563 d 266 24 0.00075632 d 267 24 0.000554992 d 268 24 0.000435131 d 269 24 0.0003474 d 270 24 0.000217667 d 271 24 0.000491602 d 272 24 0.0012267 d 273 24 0.00250446 d 274 24 0.000212058 d 275 24 -0.0174972 d 276 24 -0.0527527 d 277 24 -0.0479071 d 278 24 0.194908 d 279 24 1.45838 d 280 24 3.40677 d 281 24 4.49242 d 282 24 4.86894 d 283 24 4.97215 d 284 24 5.01218 d 285 24 5.04342 d 286 24 5.06228 d 287 24 5.03069 d 288 24 4.87169 d 289 24 4.57056 d 290 24 4.11523 d 291 24 3.38264 d 292 24 2.19691 d 293 24 0.715839 d 294 24 0.172818 d 295 24 0.102162 d 296 24 0.0627162 d 297 24 0.0363388 d 298 24 0.020289 d 299 24 0.0119414 d 300 24 0.00826608 d 301 24 0.0066417 d 302 24 0.00549092 d 303 24 0.00492505 d 304 24 0.00439443 d 305 24 0.0037156 d 306 24 0.00306471 d 307 24 0.00247451 d 308 24 0.00195965 d 309 24 0.0014822 d 310 24 0.0010815 d 311 24 0.000904464 d 312 24 0.0010514 d 313 24 0.00152308 d 314 24 0.00120752 d 315 24 0.000228447 d 316 24 -0.00102833 d 317 24 -0.00116644 d 318 24 -0.00042067 d 319 24 4.78758e-05 d 320 24 5.09599e-05 d 321 24 -4.45756e-05 d 322 24 -3.22966e-06 d 323 24 3.81163e-05 d 324 24 7.94622e-05 d 325 24 0.000120808 d 326 24 0.000162154 d 327 24 0.000161895 d 328 24 0.000148481 d 329 24 0.000135068 d 330 24 0.000121654 d 331 24 0.000108241 d 332 24 9.81453e-05 d 333 24 9.2164e-05 d 334 24 8.61827e-05 d 335 24 8.02014e-05 d 336 24 7.42201e-05 d 337 24 6.82388e-05 d 338 24 6.22576e-05 d 339 24 5.62763e-05 d 340 24 5.0295e-05 d 341 24 4.43137e-05 d 342 24 3.83324e-05 d 343 24 3.54323e-05 d 344 24 3.321e-05 d 345 24 3.09877e-05 d 346 24 2.87654e-05 d 347 24 2.65431e-05 d 348 24 2.43209e-05 d 349 24 2.20986e-05 d 350 24 1.98763e-05 d 351 24 1.7654e-05 d 352 24 1.54317e-05 d 353 24 1.34612e-05 d 354 24 1.25441e-05 d 355 24 1.1627e-05 d 356 24 1.07099e-05 d 357 24 9.79276e-06 d 358 24 8.87564e-06 d 359 24 7.95851e-06 d 360 24 7.04139e-06 d 361 24 6.12427e-06 d 1 25 5.0 d 2 25 5.01099 d 3 25 5.00866 d 4 25 4.97845 d 5 25 4.92369 d 6 25 4.9273 d 7 25 4.97413 d 8 25 4.9929 d 9 25 4.99826 d 10 25 4.99958 d 11 25 4.99978 d 12 25 5.00005 d 13 25 4.99968 d 14 25 4.99959 d 15 25 5.00014 d 16 25 4.99979 d 17 25 4.99914 d 18 25 4.99982 d 19 25 5.00023 d 20 25 5.00295 d 21 25 5.00664 d 22 25 4.99854 d 23 25 4.99647 d 24 25 5.00438 d 25 25 5.01722 d 26 25 5.03681 d 27 25 5.04766 d 28 25 5.04799 d 29 25 5.04867 d 30 25 5.04873 d 31 25 5.04685 d 32 25 5.04413 d 33 25 5.0367 d 34 25 5.02505 d 35 25 5.01726 d 36 25 5.01183 d 37 25 5.00806 d 38 25 5.00549 d 39 25 5.00371 d 40 25 5.00246 d 41 25 5.00162 d 42 25 5.00105 d 43 25 5.00069 d 44 25 5.00045 d 45 25 5.00031 d 46 25 5.00024 d 47 25 5.00019 d 48 25 5.00012 d 49 25 5.00007 d 50 25 5.00004 d 51 25 5.00001 d 52 25 4.99998 d 53 25 4.99999 d 54 25 4.99999 d 55 25 5.0 d 56 25 5.00001 d 57 25 5.00001 d 58 25 5.00002 d 59 25 5.00002 d 60 25 5.00003 d 61 25 5.00003 d 62 25 5.00003 d 63 25 5.00002 d 64 25 5.00002 d 65 25 5.00001 d 66 25 5.00001 d 67 25 5.00001 d 68 25 5.0 d 69 25 5.0 d 70 25 5.0 d 71 25 5.0 d 72 25 5.0 d 73 25 4.99999 d 74 25 4.99999 d 75 25 4.99999 d 76 25 4.99999 d 77 25 4.99999 d 78 25 4.99999 d 79 25 4.99999 d 80 25 4.99999 d 81 25 4.99999 d 82 25 4.99999 d 83 25 4.99999 d 84 25 4.99999 d 85 25 5.0 d 86 25 5.0 d 87 25 5.0 d 88 25 5.0 d 89 25 5.0 d 90 25 5.0 d 91 25 5.0 d 92 25 5.00001 d 93 25 5.00001 d 94 25 5.00001 d 95 25 5.00001 d 96 25 5.00001 d 97 25 5.00001 d 98 25 5.00001 d 99 25 5.00002 d 100 25 5.00001 d 101 25 5.00001 d 102 25 5.00001 d 103 25 5.00001 d 104 25 5.00001 d 105 25 5.00001 d 106 25 5.00001 d 107 25 5.00001 d 108 25 5.00001 d 109 25 5.00001 d 110 25 5.00001 d 111 25 5.00001 d 112 25 5.00001 d 113 25 5.00001 d 114 25 5.00001 d 115 25 5.0 d 116 25 5.0 d 117 25 5.0 d 118 25 5.0 d 119 25 5.0 d 120 25 5.0 d 121 25 5.0 d 122 25 5.00418 d 123 25 4.99953 d 124 25 4.99152 d 125 25 4.99807 d 126 25 5.00497 d 127 25 5.00112 d 128 25 5.00055 d 129 25 5.00038 d 130 25 5.00018 d 131 25 5.00006 d 132 25 5.00006 d 133 25 5.00007 d 134 25 5.00006 d 135 25 5.00004 d 136 25 5.00004 d 137 25 4.99853 d 138 25 4.99945 d 139 25 4.99998 d 140 25 5.00304 d 141 25 5.00935 d 142 25 5.00742 d 143 25 4.99181 d 144 25 4.97421 d 145 25 4.93603 d 146 25 4.8853 d 147 25 4.8927 d 148 25 4.93984 d 149 25 4.97458 d 150 25 4.99039 d 151 25 4.99614 d 152 25 4.99801 d 153 25 4.99851 d 154 25 4.99869 d 155 25 4.99924 d 156 25 5.00108 d 157 25 5.00181 d 158 25 5.00119 d 159 25 5.00059 d 160 25 5.00031 d 161 25 5.00022 d 162 25 5.00018 d 163 25 5.00011 d 164 25 5.00001 d 165 25 5.00006 d 166 25 4.99981 d 167 25 4.99977 d 168 25 4.99982 d 169 25 5.00012 d 170 25 4.99993 d 171 25 5.00008 d 172 25 5.00043 d 173 25 5.00048 d 174 25 5.00024 d 175 25 5.00008 d 176 25 4.99984 d 177 25 4.99993 d 178 25 5.00011 d 179 25 4.99996 d 180 25 4.9998 d 181 25 4.99977 d 182 25 4.9998 d 183 25 4.99993 d 184 25 5.00008 d 185 25 5.00011 d 186 25 5.00002 d 187 25 4.99995 d 188 25 4.99989 d 189 25 4.99993 d 190 25 5.0 d 191 25 5.00007 d 192 25 5.00009 d 193 25 4.99994 d 194 25 4.99977 d 195 25 4.9997 d 196 25 4.99975 d 197 25 4.99996 d 198 25 4.99996 d 199 25 4.99988 d 200 25 4.9997 d 201 25 4.99952 d 202 25 4.9995 d 203 25 4.99956 d 204 25 4.99973 d 205 25 4.99988 d 206 25 5.00005 d 207 25 5.00025 d 208 25 5.00042 d 209 25 5.00036 d 210 25 5.00031 d 211 25 5.00025 d 212 25 5.0002 d 213 25 5.00014 d 214 25 5.00009 d 215 25 5.00003 d 216 25 5.00002 d 217 25 5.00001 d 218 25 5.00001 d 219 25 5.0 d 220 25 4.99999 d 221 25 4.99998 d 222 25 4.99998 d 223 25 4.99997 d 224 25 4.99998 d 225 25 4.99998 d 226 25 4.99998 d 227 25 4.99998 d 228 25 4.99998 d 229 25 4.99998 d 230 25 4.99998 d 231 25 4.99999 d 232 25 4.99999 d 233 25 4.99999 d 234 25 4.99999 d 235 25 4.99999 d 236 25 4.99999 d 237 25 4.99999 d 238 25 4.99999 d 239 25 4.99999 d 240 25 4.99999 d 241 25 4.99999 d 242 25 5.00284 d 243 25 5.00442 d 244 25 5.00381 d 245 25 4.98997 d 246 25 4.99092 d 247 25 5.00733 d 248 25 5.07791 d 249 25 4.98237 d 250 25 4.86434 d 251 25 4.76835 d 252 25 4.74067 d 253 25 4.79278 d 254 25 4.85094 d 255 25 4.90068 d 256 25 4.93603 d 257 25 4.95698 d 258 25 4.96984 d 259 25 4.97856 d 260 25 4.98869 d 261 25 4.99904 d 262 25 5.0005 d 263 25 4.99524 d 264 25 5.00181 d 265 25 5.01878 d 266 25 5.05177 d 267 25 5.07986 d 268 25 4.98917 d 269 25 4.56217 d 270 25 3.68 d 271 25 2.3539 d 272 25 1.18541 d 273 25 0.505772 d 274 25 0.221044 d 275 25 0.115287 d 276 25 0.0760938 d 277 25 0.0589194 d 278 25 0.0476784 d 279 25 0.0457213 d 280 25 0.0412911 d 281 25 0.033889 d 282 25 0.0259741 d 283 25 0.0191452 d 284 25 0.0139018 d 285 25 0.0100235 d 286 25 0.00711788 d 287 25 0.00497657 d 288 25 0.00349368 d 289 25 0.00250021 d 290 25 0.00176179 d 291 25 0.00121843 d 292 25 0.000838368 d 293 25 0.000582711 d 294 25 0.000423458 d 295 25 0.000294608 d 296 25 0.000201251 d 297 25 0.000133748 d 298 25 8.6227e-05 d 299 25 5.44252e-05 d 300 25 3.30514e-05 d 301 25 1.93926e-05 d 302 25 1.09814e-05 d 303 25 5.29857e-06 d 304 25 1.92247e-06 d 305 25 3.08708e-07 d 306 25 -3.74311e-07 d 307 25 -6.11121e-07 d 308 25 -7.27807e-07 d 309 25 -4.87604e-07 d 310 25 -4.80493e-07 d 311 25 -9.15925e-07 d 312 25 -2.03774e-06 d 313 25 -4.01128e-06 d 314 25 -2.46644e-06 d 315 25 2.10626e-06 d 316 25 8.22422e-06 d 317 25 1.04922e-05 d 318 25 9.83047e-06 d 319 25 7.27106e-06 d 320 25 3.29654e-06 d 321 25 -2.06736e-06 d 322 25 -2.18019e-06 d 323 25 -2.29303e-06 d 324 25 -2.40586e-06 d 325 25 -2.51869e-06 d 326 25 -2.63153e-06 d 327 25 -2.24615e-06 d 328 25 -1.70325e-06 d 329 25 -1.16036e-06 d 330 25 -6.17468e-07 d 331 25 -7.45754e-08 d 332 25 2.45198e-07 d 333 25 2.88285e-07 d 334 25 3.31373e-07 d 335 25 3.7446e-07 d 336 25 4.17548e-07 d 337 25 4.60635e-07 d 338 25 5.03723e-07 d 339 25 5.4681e-07 d 340 25 5.89898e-07 d 341 25 6.32985e-07 d 342 25 6.76073e-07 d 343 25 6.19054e-07 d 344 25 5.4001e-07 d 345 25 4.60967e-07 d 346 25 3.81923e-07 d 347 25 3.02879e-07 d 348 25 2.23836e-07 d 349 25 1.44792e-07 d 350 25 6.57488e-08 d 351 25 -1.32948e-08 d 352 25 -9.23383e-08 d 353 25 -1.6698e-07 d 354 25 -2.23206e-07 d 355 25 -2.79432e-07 d 356 25 -3.35658e-07 d 357 25 -3.91884e-07 d 358 25 -4.48109e-07 d 359 25 -5.04335e-07 d 360 25 -5.60561e-07 d 361 25 -6.16787e-07 d 1 26 1.34824 d 2 26 1.35838 d 3 26 1.36465 d 4 26 1.34675 d 5 26 1.29167 d 6 26 1.23161 d 7 26 1.2201 d 8 26 1.2185 d 9 26 1.2181 d 10 26 1.21798 d 11 26 1.21793 d 12 26 1.21788 d 13 26 1.21785 d 14 26 1.21782 d 15 26 1.21779 d 16 26 1.21776 d 17 26 1.21655 d 18 26 1.21656 d 19 26 1.21669 d 20 26 1.21871 d 21 26 1.22421 d 22 26 1.22247 d 23 26 1.21858 d 24 26 1.2228 d 25 26 1.23803 d 26 26 1.27737 d 27 26 1.10647 d 28 26 0.395248 d 29 26 0.0600669 d 30 26 0.027687 d 31 26 0.0192374 d 32 26 0.015425 d 33 26 0.0130881 d 34 26 0.00977445 d 35 26 0.00696598 d 36 26 0.00491122 d 37 26 0.00341952 d 38 26 0.00237078 d 39 26 0.00162339 d 40 26 0.00109178 d 41 26 0.000726647 d 42 26 0.000478886 d 43 26 0.00031568 d 44 26 0.000207902 d 45 26 0.000143494 d 46 26 0.000109768 d 47 26 8.62987e-05 d 48 26 5.69775e-05 d 49 26 3.36547e-05 d 50 26 2.30356e-05 d 51 26 1.86108e-05 d 52 26 1.41861e-05 d 53 26 1.08293e-05 d 54 26 7.68835e-06 d 55 26 4.79593e-06 d 56 26 4.51019e-06 d 57 26 4.22444e-06 d 58 26 3.9387e-06 d 59 26 3.65295e-06 d 60 26 3.36721e-06 d 61 26 3.04559e-06 d 62 26 2.69981e-06 d 63 26 2.35403e-06 d 64 26 2.00825e-06 d 65 26 1.66247e-06 d 66 26 1.34508e-06 d 67 26 1.26225e-06 d 68 26 1.17941e-06 d 69 26 1.09657e-06 d 70 26 1.01373e-06 d 71 26 9.30893e-07 d 72 26 8.48054e-07 d 73 26 7.65216e-07 d 74 26 6.82378e-07 d 75 26 5.9954e-07 d 76 26 5.16702e-07 d 77 26 4.37489e-07 d 78 26 3.82774e-07 d 79 26 3.2806e-07 d 80 26 2.73346e-07 d 81 26 2.18632e-07 d 82 26 1.63917e-07 d 83 26 1.09203e-07 d 84 26 5.4489e-08 d 85 26 -2.2523e-10 d 86 26 -5.49395e-08 d 87 26 -1.09654e-07 d 88 26 -1.52862e-07 d 89 26 -1.3079e-07 d 90 26 -1.08718e-07 d 91 26 -8.6646e-08 d 92 26 -6.45739e-08 d 93 26 -4.25019e-08 d 94 26 -2.04298e-08 d 95 26 1.64229e-09 d 96 26 2.37144e-08 d 97 26 4.57864e-08 d 98 26 6.78585e-08 d 99 26 8.71693e-08 d 100 26 9.30725e-08 d 101 26 9.89758e-08 d 102 26 1.04879e-07 d 103 26 1.10782e-07 d 104 26 1.16685e-07 d 105 26 1.22589e-07 d 106 26 1.28492e-07 d 107 26 1.34395e-07 d 108 26 1.40298e-07 d 109 26 1.46201e-07 d 110 26 1.52105e-07 d 111 26 1.58008e-07 d 112 26 1.63911e-07 d 113 26 1.69814e-07 d 114 26 1.75718e-07 d 115 26 1.81621e-07 d 116 26 1.87524e-07 d 117 26 1.93427e-07 d 118 26 1.9933e-07 d 119 26 2.05234e-07 d 120 26 2.11137e-07 d 121 26 2.19788e-07 d 122 26 0.000393944 d 123 26 -0.000218983 d 124 26 -0.00105784 d 125 26 0.00172403 d 126 26 -0.00027134 d 127 26 -0.000204147 d 128 26 8.79968e-06 d 129 26 5.93762e-05 d 130 26 5.83554e-05 d 131 26 4.13815e-05 d 132 26 3.71369e-05 d 133 26 3.03372e-05 d 134 26 2.25336e-05 d 135 26 1.5986e-05 d 136 26 1.07284e-05 d 137 26 -7.5239e-05 d 138 26 5.60593e-05 d 139 26 6.97571e-05 d 140 26 0.000667617 d 141 26 0.000960856 d 142 26 0.00131749 d 143 26 -0.00759564 d 144 26 -0.0217897 d 145 26 -0.0450321 d 146 26 -0.076646 d 147 26 -0.128569 d 148 26 -0.186391 d 149 26 -0.202175 d 150 26 -0.206953 d 151 26 -0.2082 d 152 26 -0.208416 d 153 26 -0.208669 d 154 26 -0.208934 d 155 26 -0.209111 d 156 26 -0.209234 d 157 26 -0.209329 d 158 26 -0.209389 d 159 26 -0.209416 d 160 26 -0.2094 d 161 26 -0.209329 d 162 26 -0.20926 d 163 26 -0.209204 d 164 26 -0.209208 d 165 26 -0.209285 d 166 26 -0.209454 d 167 26 -0.209641 d 168 26 -0.20977 d 169 26 -0.209811 d 170 26 -0.209833 d 171 26 -0.209887 d 172 26 -0.209653 d 173 26 -0.209127 d 174 26 -0.208893 d 175 26 -0.208811 d 176 26 -0.208777 d 177 26 -0.208758 d 178 26 -0.208747 d 179 26 -0.20874 d 180 26 -0.208726 d 181 26 -0.208697 d 182 26 -0.208657 d 183 26 -0.208611 d 184 26 -0.208565 d 185 26 -0.208524 d 186 26 -0.208488 d 187 26 -0.208451 d 188 26 -0.208412 d 189 26 -0.208373 d 190 26 -0.208333 d 191 26 -0.208294 d 192 26 -0.208256 d 193 26 -0.208219 d 194 26 -0.208183 d 195 26 -0.208145 d 196 26 -0.208107 d 197 26 -0.208066 d 198 26 -0.208029 d 199 26 -0.207993 d 200 26 -0.207959 d 201 26 -0.207923 d 202 26 -0.207883 d 203 26 -0.207838 d 204 26 -0.207789 d 205 26 -0.207747 d 206 26 -0.20771 d 207 26 -0.207675 d 208 26 -0.207642 d 209 26 -0.207605 d 210 26 -0.207568 d 211 26 -0.207531 d 212 26 -0.207494 d 213 26 -0.207457 d 214 26 -0.20742 d 215 26 -0.207383 d 216 26 -0.207346 d 217 26 -0.207308 d 218 26 -0.207271 d 219 26 -0.207233 d 220 26 -0.207196 d 221 26 -0.207158 d 222 26 -0.207121 d 223 26 -0.207084 d 224 26 -0.207046 d 225 26 -0.207009 d 226 26 -0.206972 d 227 26 -0.206935 d 228 26 -0.206898 d 229 26 -0.206861 d 230 26 -0.206823 d 231 26 -0.206786 d 232 26 -0.206749 d 233 26 -0.206712 d 234 26 -0.206675 d 235 26 -0.206638 d 236 26 -0.2066 d 237 26 -0.206563 d 238 26 -0.206526 d 239 26 -0.206489 d 240 26 -0.206452 d 241 26 -0.206415 d 242 26 -0.203384 d 243 26 -0.20015 d 244 26 -0.196872 d 245 26 -0.205024 d 246 26 -0.210727 d 247 26 -0.206779 d 248 26 -0.0685263 d 249 26 0.586138 d 250 26 1.4665 d 251 26 2.22945 d 252 26 2.77554 d 253 26 3.076 d 254 26 3.24926 d 255 26 3.34515 d 256 26 3.40164 d 257 26 3.43006 d 258 26 3.43713 d 259 26 3.43075 d 260 26 3.42886 d 261 26 3.4384 d 262 26 3.46567 d 263 26 3.49025 d 264 26 3.51287 d 265 26 3.53821 d 266 26 3.57841 d 267 26 3.39846 d 268 26 2.80753 d 269 26 2.22947 d 270 26 1.7549 d 271 26 1.30429 d 272 26 0.707786 d 273 26 0.303206 d 274 26 0.131352 d 275 26 0.0671706 d 276 26 0.0429955 d 277 26 0.032461 d 278 26 0.0257161 d 279 26 0.0239521 d 280 26 0.0217397 d 281 26 0.0179705 d 282 26 0.0138745 d 283 26 0.0102813 d 284 26 0.00749643 d 285 26 0.0054328 d 286 26 0.00386817 d 287 26 0.0027004 d 288 26 0.00189442 d 289 26 0.00135552 d 290 26 0.000954715 d 291 26 0.000659981 d 292 26 0.000453435 d 293 26 0.000313993 d 294 26 0.000231347 d 295 26 0.000159665 d 296 26 0.000108122 d 297 26 7.10528e-05 d 298 26 4.50233e-05 d 299 26 2.77892e-05 d 300 26 1.62765e-05 d 301 26 8.9893e-06 d 302 26 4.5471e-06 d 303 26 1.54614e-06 d 304 26 -1.6542e-07 d 305 26 -8.68508e-07 d 306 26 -1.04369e-06 d 307 26 -9.63086e-07 d 308 26 -8.44294e-07 d 309 26 -6.57339e-07 d 310 26 -7.35885e-07 d 311 26 -9.80056e-07 d 312 26 -1.39772e-06 d 313 26 -2.10199e-06 d 314 26 -1.37474e-06 d 315 26 6.13269e-07 d 316 26 3.3028e-06 d 317 26 4.60941e-06 d 318 26 4.91053e-06 d 319 26 4.14186e-06 d 320 26 2.45258e-06 d 321 26 -8.7388e-09 d 322 26 -3.59647e-07 d 323 26 -7.10554e-07 d 324 26 -1.06146e-06 d 325 26 -1.41237e-06 d 326 26 -1.76328e-06 d 327 26 -1.63073e-06 d 328 26 -1.34534e-06 d 329 26 -1.05995e-06 d 330 26 -7.74561e-07 d 331 26 -4.8917e-07 d 332 26 -2.95733e-07 d 333 26 -2.16326e-07 d 334 26 -1.3692e-07 d 335 26 -5.75135e-08 d 336 26 2.18929e-08 d 337 26 1.01299e-07 d 338 26 1.80706e-07 d 339 26 2.60112e-07 d 340 26 3.39519e-07 d 341 26 4.18925e-07 d 342 26 4.98332e-07 d 343 26 4.83984e-07 d 344 26 4.4901e-07 d 345 26 4.14035e-07 d 346 26 3.79061e-07 d 347 26 3.44087e-07 d 348 26 3.09112e-07 d 349 26 2.74138e-07 d 350 26 2.39163e-07 d 351 26 2.04189e-07 d 352 26 1.69215e-07 d 353 26 1.26002e-07 d 354 26 4.83213e-08 d 355 26 -2.9359e-08 d 356 26 -1.07039e-07 d 357 26 -1.8472e-07 d 358 26 -2.624e-07 d 359 26 -3.4008e-07 d 360 26 -4.1776e-07 d 361 26 -4.95441e-07 d 1 27 7.10441e-10 d 2 27 0.000309731 d 3 27 -0.000308186 d 4 27 -0.001694 d 5 27 -0.00360784 d 6 27 8.40909e-05 d 7 27 0.00203175 d 8 27 0.0012896 d 9 27 0.000596548 d 10 27 0.000277191 d 11 27 0.000161134 d 12 27 0.000120439 d 13 27 8.4915e-05 d 14 27 9.49929e-05 d 15 27 6.18812e-05 d 16 27 1.65433e-05 d 17 27 1.89682e-05 d 18 27 3.97578e-05 d 19 27 4.95446e-05 d 20 27 0.000225325 d 21 27 0.000214579 d 22 27 -0.00230134 d 23 27 -0.000451102 d 24 27 0.00997237 d 25 27 0.0341443 d 26 27 0.0449314 d 27 27 0.0424411 d 28 27 0.0341996 d 29 27 0.0315315 d 30 27 0.0308892 d 31 27 0.0291614 d 32 27 0.024365 d 33 27 0.0190282 d 34 27 0.0188976 d 35 27 0.017238 d 36 27 0.0138526 d 37 27 0.0105645 d 38 27 0.00778548 d 39 27 0.00561753 d 40 27 0.0039871 d 41 27 0.00279554 d 42 27 0.00194075 d 43 27 0.0013468 d 44 27 0.000934775 d 45 27 0.000664723 d 46 27 0.000498911 d 47 27 0.000377384 d 48 27 0.000254183 d 49 27 0.000163421 d 50 27 0.000120773 d 51 27 9.65058e-05 d 52 27 7.22384e-05 d 53 27 5.60316e-05 d 54 27 4.14549e-05 d 55 27 2.79516e-05 d 56 27 2.57096e-05 d 57 27 2.34677e-05 d 58 27 2.12257e-05 d 59 27 1.89837e-05 d 60 27 1.67417e-05 d 61 27 1.46737e-05 d 62 27 1.27228e-05 d 63 27 1.07719e-05 d 64 27 8.82099e-06 d 65 27 6.87009e-06 d 66 27 5.0896e-06 d 67 27 4.71705e-06 d 68 27 4.34451e-06 d 69 27 3.97196e-06 d 70 27 3.59941e-06 d 71 27 3.22686e-06 d 72 27 2.85431e-06 d 73 27 2.48176e-06 d 74 27 2.10921e-06 d 75 27 1.73666e-06 d 76 27 1.36411e-06 d 77 27 1.02855e-06 d 78 27 9.42931e-07 d 79 27 8.57316e-07 d 80 27 7.71701e-07 d 81 27 6.86086e-07 d 82 27 6.00471e-07 d 83 27 5.14856e-07 d 84 27 4.29241e-07 d 85 27 3.43626e-07 d 86 27 2.58011e-07 d 87 27 1.72396e-07 d 88 27 9.85409e-08 d 89 27 9.14091e-08 d 90 27 8.42773e-08 d 91 27 7.71456e-08 d 92 27 7.00138e-08 d 93 27 6.2882e-08 d 94 27 5.57503e-08 d 95 27 4.86185e-08 d 96 27 4.14867e-08 d 97 27 3.4355e-08 d 98 27 2.72232e-08 d 99 27 2.05821e-08 d 100 27 1.63235e-08 d 101 27 1.2065e-08 d 102 27 7.80643e-09 d 103 27 3.54786e-09 d 104 27 -7.10696e-10 d 105 27 -4.96926e-09 d 106 27 -9.22782e-09 d 107 27 -1.34864e-08 d 108 27 -1.77449e-08 d 109 27 -2.20035e-08 d 110 27 -2.62621e-08 d 111 27 -3.05206e-08 d 112 27 -3.47792e-08 d 113 27 -3.90378e-08 d 114 27 -4.32963e-08 d 115 27 -4.75549e-08 d 116 27 -5.18134e-08 d 117 27 -5.6072e-08 d 118 27 -6.03306e-08 d 119 27 -6.45891e-08 d 120 27 -6.88477e-08 d 121 27 -8.76373e-06 d 122 27 0.000131607 d 123 27 -0.00021685 d 124 27 -0.000433027 d 125 27 0.00047234 d 126 27 0.000211593 d 127 27 -0.000189601 d 128 27 3.2492e-05 d 129 27 0.000575955 d 130 27 7.72235e-05 d 131 27 -0.000285172 d 132 27 -0.000242061 d 133 27 -0.000135112 d 134 27 -3.50117e-05 d 135 27 -2.75868e-05 d 136 27 5.48974e-05 d 137 27 1.80604e-07 d 138 27 5.48911e-05 d 139 27 3.97478e-05 d 140 27 0.000192909 d 141 27 0.000297932 d 142 27 0.00402253 d 143 27 -0.0122366 d 144 27 -0.047853 d 145 27 -0.0963082 d 146 27 -0.108071 d 147 27 -0.0567275 d 148 27 -0.0239271 d 149 27 -0.0178628 d 150 27 -0.0233027 d 151 27 -0.031853 d 152 27 -0.0400843 d 153 27 -0.0482725 d 154 27 -0.0576154 d 155 27 -0.0627218 d 156 27 -0.0511236 d 157 27 -0.0279524 d 158 27 -0.0150986 d 159 27 -0.00931091 d 160 27 -0.00652876 d 161 27 -0.00479286 d 162 27 -0.00344346 d 163 27 -0.00249578 d 164 27 -0.0019532 d 165 27 -0.00157977 d 166 27 -0.00131848 d 167 27 -0.00111251 d 168 27 -0.000939229 d 169 27 -0.000797445 d 170 27 -0.000708384 d 171 27 -0.000630452 d 172 27 -0.000539722 d 173 27 -0.000508862 d 174 27 -0.000480596 d 175 27 -0.000439484 d 176 27 -0.000407217 d 177 27 -0.000363866 d 178 27 -0.000329506 d 179 27 -0.000318642 d 180 27 -0.000307362 d 181 27 -0.000286511 d 182 27 -0.000266253 d 183 27 -0.000242943 d 184 27 -0.000218107 d 185 27 -0.000204661 d 186 27 -0.00020241 d 187 27 -0.000194435 d 188 27 -0.000185062 d 189 27 -0.000173042 d 190 27 -0.000160549 d 191 27 -0.000151407 d 192 27 -0.000145626 d 193 27 -0.000145976 d 194 27 -0.000147342 d 195 27 -0.000145288 d 196 27 -0.000137979 d 197 27 -0.000124481 d 198 27 -0.000123218 d 199 27 -0.000127453 d 200 27 -0.000139006 d 201 27 -0.000145486 d 202 27 -0.000129764 d 203 27 -9.82749e-05 d 204 27 -4.72596e-05 d 205 27 -3.08671e-05 d 206 27 -3.28834e-05 d 207 27 -4.52254e-05 d 208 27 -6.25389e-05 d 209 27 -6.32516e-05 d 210 27 -6.39643e-05 d 211 27 -6.4677e-05 d 212 27 -6.53897e-05 d 213 27 -6.61023e-05 d 214 27 -6.6815e-05 d 215 27 -6.75277e-05 d 216 27 -6.61005e-05 d 217 27 -6.45173e-05 d 218 27 -6.29341e-05 d 219 27 -6.13509e-05 d 220 27 -5.97676e-05 d 221 27 -5.81844e-05 d 222 27 -5.66012e-05 d 223 27 -5.54231e-05 d 224 27 -5.4455e-05 d 225 27 -5.3487e-05 d 226 27 -5.25189e-05 d 227 27 -5.15508e-05 d 228 27 -5.05828e-05 d 229 27 -4.96147e-05 d 230 27 -4.86466e-05 d 231 27 -4.76785e-05 d 232 27 -4.67105e-05 d 233 27 -4.57424e-05 d 234 27 -4.47743e-05 d 235 27 -4.38063e-05 d 236 27 -4.28382e-05 d 237 27 -4.18821e-05 d 238 27 -4.10211e-05 d 239 27 -4.016e-05 d 240 27 -3.9299e-05 d 241 27 -3.8438e-05 d 242 27 4.29885e-05 d 243 27 5.14113e-05 d 244 27 -0.000127986 d 245 27 -0.000611463 d 246 27 -0.000149428 d 247 27 0.000882394 d 248 27 0.00297059 d 249 27 -0.00405825 d 250 27 -0.00591067 d 251 27 -0.00546997 d 252 27 -0.00158744 d 253 27 0.00190677 d 254 27 0.00298403 d 255 27 0.00268595 d 256 27 0.00196161 d 257 27 0.00130289 d 258 27 0.000783347 d 259 27 0.000520683 d 260 27 0.000565306 d 261 27 0.00053419 d 262 27 -0.00224696 d 263 27 -0.000920818 d 264 27 0.0132755 d 265 27 0.0322504 d 266 27 0.0442808 d 267 27 0.0638615 d 268 27 0.0701007 d 269 27 0.0539356 d 270 27 0.0247771 d 271 27 0.056244 d 272 27 0.294266 d 273 27 0.831368 d 274 27 1.45424 d 275 27 2.02898 d 276 27 2.54559 d 277 27 2.9937 d 278 27 3.35333 d 279 27 3.72609 d 280 27 4.06363 d 281 27 4.32789 d 282 27 4.52413 d 283 27 4.66504 d 284 27 4.7652 d 285 27 4.83637 d 286 27 4.88631 d 287 27 4.92109 d 288 27 4.94464 d 289 27 4.96046 d 290 27 4.97218 d 291 27 4.98079 d 292 27 4.98679 d 293 27 4.99076 d 294 27 4.99361 d 295 27 4.99555 d 296 27 4.99686 d 297 27 4.99783 d 298 27 4.99853 d 299 27 4.99902 d 300 27 4.99936 d 301 27 4.99959 d 302 27 4.99973 d 303 27 4.99983 d 304 27 4.9999 d 305 27 4.99993 d 306 27 4.99996 d 307 27 4.99998 d 308 27 5.0 d 309 27 5.00001 d 310 27 5.0 d 311 27 4.99999 d 312 27 4.99997 d 313 27 4.99994 d 314 27 4.99993 d 315 27 4.99994 d 316 27 4.99996 d 317 27 4.99999 d 318 27 5.00004 d 319 27 5.00006 d 320 27 5.00005 d 321 27 5.00003 d 322 27 5.00002 d 323 27 5.00001 d 324 27 5.0 d 325 27 4.99999 d 326 27 4.99999 d 327 27 4.99999 d 328 27 4.99999 d 329 27 4.99999 d 330 27 4.99999 d 331 27 4.99999 d 332 27 5.0 d 333 27 5.0 d 334 27 5.0 d 335 27 5.0 d 336 27 5.0 d 337 27 5.0 d 338 27 5.00001 d 339 27 5.00001 d 340 27 5.00001 d 341 27 5.00001 d 342 27 5.00001 d 343 27 5.00001 d 344 27 5.00001 d 345 27 5.00001 d 346 27 5.00001 d 347 27 5.00001 d 348 27 5.00001 d 349 27 5.00001 d 350 27 5.00001 d 351 27 5.0 d 352 27 5.0 d 353 27 5.0 d 354 27 5.0 d 355 27 5.0 d 356 27 4.99999 d 357 27 4.99999 d 358 27 4.99999 d 359 27 4.99999 d 360 27 4.99999 d 361 27 4.99998 d 1 28 5.0 d 2 28 4.99984 d 3 28 4.99796 d 4 28 4.99478 d 5 28 4.9889 d 6 28 4.98738 d 7 28 4.98896 d 8 28 4.99087 d 9 28 4.99262 d 10 28 4.99419 d 11 28 4.99552 d 12 28 4.99659 d 13 28 4.99743 d 14 28 4.99807 d 15 28 4.99855 d 16 28 4.9989 d 17 28 4.99894 d 18 28 4.99908 d 19 28 4.99935 d 20 28 5.00001 d 21 28 5.0007 d 22 28 5.00132 d 23 28 5.00032 d 24 28 4.99976 d 25 28 5.00134 d 26 28 5.00339 d 27 28 5.00315 d 28 28 5.00157 d 29 28 5.00091 d 30 28 5.00058 d 31 28 5.00012 d 32 28 4.99944 d 33 28 4.99886 d 34 28 4.9994 d 35 28 4.99934 d 36 28 4.99899 d 37 28 4.99876 d 38 28 4.99868 d 39 28 4.99872 d 40 28 4.99883 d 41 28 4.99898 d 42 28 4.99914 d 43 28 4.9993 d 44 28 4.99944 d 45 28 4.99956 d 46 28 4.99967 d 47 28 4.99976 d 48 28 4.99982 d 49 28 4.99986 d 50 28 4.9999 d 51 28 4.99993 d 52 28 4.99997 d 53 28 4.99997 d 54 28 4.99998 d 55 28 4.99998 d 56 28 4.99998 d 57 28 4.99998 d 58 28 4.99998 d 59 28 4.99998 d 60 28 4.99998 d 61 28 4.99998 d 62 28 4.99999 d 63 28 4.99999 d 64 28 4.99999 d 65 28 4.99999 d 66 28 5.0 d 67 28 5.0 d 68 28 5.0 d 69 28 5.0 d 70 28 5.0 d 71 28 5.0 d 72 28 5.0 d 73 28 5.0 d 74 28 5.0 d 75 28 5.0 d 76 28 5.0 d 77 28 5.0 d 78 28 5.0 d 79 28 5.0 d 80 28 5.0 d 81 28 5.0 d 82 28 5.0 d 83 28 5.0 d 84 28 5.0 d 85 28 5.0 d 86 28 5.0 d 87 28 5.0 d 88 28 5.0 d 89 28 5.0 d 90 28 5.0 d 91 28 5.0 d 92 28 5.0 d 93 28 5.0 d 94 28 5.0 d 95 28 5.0 d 96 28 5.0 d 97 28 5.0 d 98 28 5.0 d 99 28 5.0 d 100 28 5.0 d 101 28 5.0 d 102 28 5.0 d 103 28 5.0 d 104 28 5.0 d 105 28 5.0 d 106 28 5.0 d 107 28 5.0 d 108 28 5.0 d 109 28 5.0 d 110 28 5.0 d 111 28 5.0 d 112 28 5.0 d 113 28 5.0 d 114 28 5.0 d 115 28 5.0 d 116 28 5.0 d 117 28 5.0 d 118 28 5.0 d 119 28 5.0 d 120 28 5.0 d 121 28 5.00009 d 122 28 5.00028 d 123 28 5.00015 d 124 28 4.99983 d 125 28 5.00036 d 126 28 4.99996 d 127 28 4.99834 d 128 28 4.99783 d 129 28 5.00383 d 130 28 5.00734 d 131 28 5.00387 d 132 28 5.00058 d 133 28 4.99893 d 134 28 4.99836 d 135 28 4.99832 d 136 28 4.99854 d 137 28 4.99873 d 138 28 4.99905 d 139 28 4.99927 d 140 28 4.99952 d 141 28 4.99969 d 142 28 4.99834 d 143 28 4.99536 d 144 28 4.99163 d 145 28 4.99073 d 146 28 5.0053 d 147 28 5.03631 d 148 28 5.03103 d 149 28 4.9008 d 150 28 4.62503 d 151 28 4.21887 d 152 28 3.70902 d 153 28 3.09967 d 154 28 2.35791 d 155 28 1.41912 d 156 28 0.519675 d 157 28 0.210458 d 158 28 0.131362 d 159 28 0.0980819 d 160 28 0.0708209 d 161 28 0.0471701 d 162 28 0.0323272 d 163 28 0.0253535 d 164 28 0.0199144 d 165 28 0.0152615 d 166 28 0.0117228 d 167 28 0.00917696 d 168 28 0.00738117 d 169 28 0.00609292 d 170 28 0.00512664 d 171 28 0.00436184 d 172 28 0.0037961 d 173 28 0.00331639 d 174 28 0.00289006 d 175 28 0.0025477 d 176 28 0.00226529 d 177 28 0.00202925 d 178 28 0.00182793 d 179 28 0.00165474 d 180 28 0.00150531 d 181 28 0.00137529 d 182 28 0.00125983 d 183 28 0.00115603 d 184 28 0.00106455 d 185 28 0.000982977 d 186 28 0.000911255 d 187 28 0.000846819 d 188 28 0.000790092 d 189 28 0.000738698 d 190 28 0.000692816 d 191 28 0.00065107 d 192 28 0.000613595 d 193 28 0.000579642 d 194 28 0.000548935 d 195 28 0.00052106 d 196 28 0.000495598 d 197 28 0.000472174 d 198 28 0.000450849 d 199 28 0.000431118 d 200 28 0.000412667 d 201 28 0.000395868 d 202 28 0.000381319 d 203 28 0.000368487 d 204 28 0.000357327 d 205 28 0.000344212 d 206 28 0.000330334 d 207 28 0.00031622 d 208 28 0.000303298 d 209 28 0.000295809 d 210 28 0.00028832 d 211 28 0.000280831 d 212 28 0.000273342 d 213 28 0.000265853 d 214 28 0.000258364 d 215 28 0.000250875 d 216 28 0.000245118 d 217 28 0.000239488 d 218 28 0.000233857 d 219 28 0.000228227 d 220 28 0.000222596 d 221 28 0.000216966 d 222 28 0.000211336 d 223 28 0.000207047 d 224 28 0.000203455 d 225 28 0.000199863 d 226 28 0.00019627 d 227 28 0.000192678 d 228 28 0.000189085 d 229 28 0.000185493 d 230 28 0.0001819 d 231 28 0.000178308 d 232 28 0.000174716 d 233 28 0.000171123 d 234 28 0.000167531 d 235 28 0.000163938 d 236 28 0.000160346 d 237 28 0.000156835 d 238 28 0.000153973 d 239 28 0.00015111 d 240 28 0.000148248 d 241 28 0.000145385 d 242 28 0.000296579 d 243 28 -3.96718e-05 d 244 28 -0.000449085 d 245 28 0.000323433 d 246 28 0.000750086 d 247 28 0.000268264 d 248 28 0.000149028 d 249 28 -0.000100249 d 250 28 7.00956e-05 d 251 28 0.00012605 d 252 28 0.00022592 d 253 28 0.000193036 d 254 28 0.000120453 d 255 28 8.07865e-05 d 256 28 7.65771e-05 d 257 28 -3.27828e-05 d 258 28 0.000116759 d 259 28 0.000169498 d 260 28 0.000409804 d 261 28 0.000414965 d 262 28 0.00092323 d 263 28 -0.00590633 d 264 28 -0.0175477 d 265 28 -0.032433 d 266 28 -0.0559842 d 267 28 -0.0820373 d 268 28 0.0688484 d 269 28 0.626629 d 270 28 1.32929 d 271 28 2.01657 d 272 28 2.60925 d 273 28 3.12329 d 274 28 3.38952 d 275 28 3.14128 d 276 28 2.38463 d 277 28 1.23802 d 278 28 0.316019 d 279 28 0.107832 d 280 28 0.0694707 d 281 28 0.051837 d 282 28 0.035247 d 283 28 0.0209999 d 284 28 0.0116618 d 285 28 0.00967674 d 286 28 0.00789182 d 287 28 0.00574566 d 288 28 0.00386872 d 289 28 0.00258612 d 290 28 0.00167126 d 291 28 0.00104169 d 292 28 0.000641093 d 293 28 0.000401246 d 294 28 0.000277928 d 295 28 0.000171775 d 296 28 0.000102266 d 297 28 5.89376e-05 d 298 28 3.29258e-05 d 299 28 1.80463e-05 d 300 28 1.0057e-05 d 301 28 6.4571e-06 d 302 28 5.10093e-06 d 303 28 4.06791e-06 d 304 28 3.62716e-06 d 305 28 3.63321e-06 d 306 28 3.99625e-06 d 307 28 4.64368e-06 d 308 28 5.20886e-06 d 309 28 4.77728e-06 d 310 28 3.23919e-06 d 311 28 1.14113e-06 d 312 28 -1.29416e-06 d 313 28 -4.15607e-06 d 314 28 -1.88532e-06 d 315 28 5.24411e-06 d 316 28 1.38678e-05 d 317 28 1.28823e-05 d 318 28 3.6758e-06 d 319 28 -2.52285e-06 d 320 28 -3.97133e-06 d 321 28 -4.03071e-06 d 322 28 -3.37154e-06 d 323 28 -2.71238e-06 d 324 28 -2.05321e-06 d 325 28 -1.39404e-06 d 326 28 -7.34872e-07 d 327 28 -3.73325e-07 d 328 28 -1.05873e-07 d 329 28 1.61578e-07 d 330 28 4.2903e-07 d 331 28 6.96482e-07 d 332 28 8.18468e-07 d 333 28 7.60065e-07 d 334 28 7.01662e-07 d 335 28 6.43258e-07 d 336 28 5.84855e-07 d 337 28 5.26452e-07 d 338 28 4.68049e-07 d 339 28 4.09646e-07 d 340 28 3.51243e-07 d 341 28 2.9284e-07 d 342 28 2.34437e-07 d 343 28 1.71213e-07 d 344 28 1.06928e-07 d 345 28 4.2644e-08 d 346 28 -2.16403e-08 d 347 28 -8.59247e-08 d 348 28 -1.50209e-07 d 349 28 -2.14493e-07 d 350 28 -2.78778e-07 d 351 28 -3.43062e-07 d 352 28 -4.07346e-07 d 353 28 -4.55065e-07 d 354 28 -4.3348e-07 d 355 28 -4.11896e-07 d 356 28 -3.90311e-07 d 357 28 -3.68726e-07 d 358 28 -3.47141e-07 d 359 28 -3.25556e-07 d 360 28 -3.03971e-07 d 361 28 -2.82386e-07 d 1 29 0.368163 d 2 29 0.361756 d 3 29 0.327463 d 4 29 0.269513 d 5 29 0.149476 d 6 29 0.0805716 d 7 29 0.0501146 d 8 29 0.03403 d 9 29 0.0230886 d 10 29 0.0160474 d 11 29 0.0116071 d 12 29 0.00870013 d 13 29 0.00679614 d 14 29 0.00542384 d 15 29 0.00432512 d 16 29 0.00340653 d 17 29 -0.00129719 d 18 29 -0.00399429 d 19 29 -0.00318719 d 20 29 0.00443085 d 21 29 0.0150156 d 22 29 0.0334147 d 23 29 0.0132288 d 24 29 -0.0189751 d 25 29 -0.0508377 d 26 29 -0.0252174 d 27 29 -0.0142489 d 28 29 -0.00675908 d 29 29 -0.0038653 d 30 29 -0.00243423 d 31 29 -0.00168891 d 32 29 -0.00120901 d 33 29 -0.000900426 d 34 29 -0.000685575 d 35 29 -0.000557595 d 36 29 -0.000457268 d 37 29 -0.000377427 d 38 29 -0.000315269 d 39 29 -0.000266613 d 40 29 -0.000228397 d 41 29 -0.000198283 d 42 29 -0.000174248 d 43 29 -0.000154886 d 44 29 -0.00013892 d 45 29 -0.000125864 d 46 29 -0.000115189 d 47 29 -0.000105841 d 48 29 -9.66611e-05 d 49 29 -8.84262e-05 d 50 29 -8.23872e-05 d 51 29 -7.74668e-05 d 52 29 -7.25463e-05 d 53 29 -6.79992e-05 d 54 29 -6.35276e-05 d 55 29 -5.92413e-05 d 56 29 -5.68994e-05 d 57 29 -5.45574e-05 d 58 29 -5.22154e-05 d 59 29 -4.98735e-05 d 60 29 -4.75315e-05 d 61 29 -4.54981e-05 d 62 29 -4.36726e-05 d 63 29 -4.18471e-05 d 64 29 -4.00216e-05 d 65 29 -3.81961e-05 d 66 29 -3.64559e-05 d 67 29 -3.54209e-05 d 68 29 -3.43858e-05 d 69 29 -3.33508e-05 d 70 29 -3.23157e-05 d 71 29 -3.12807e-05 d 72 29 -3.02456e-05 d 73 29 -2.92105e-05 d 74 29 -2.81755e-05 d 75 29 -2.71404e-05 d 76 29 -2.61054e-05 d 77 29 -2.51232e-05 d 78 29 -2.44984e-05 d 79 29 -2.38736e-05 d 80 29 -2.32487e-05 d 81 29 -2.26239e-05 d 82 29 -2.19991e-05 d 83 29 -2.13742e-05 d 84 29 -2.07494e-05 d 85 29 -2.01246e-05 d 86 29 -1.94998e-05 d 87 29 -1.88749e-05 d 88 29 -1.82865e-05 d 89 29 -1.79044e-05 d 90 29 -1.75224e-05 d 91 29 -1.71403e-05 d 92 29 -1.67582e-05 d 93 29 -1.63762e-05 d 94 29 -1.59941e-05 d 95 29 -1.56121e-05 d 96 29 -1.523e-05 d 97 29 -1.4848e-05 d 98 29 -1.44659e-05 d 99 29 -1.41138e-05 d 100 29 -1.39075e-05 d 101 29 -1.37011e-05 d 102 29 -1.34947e-05 d 103 29 -1.32883e-05 d 104 29 -1.30819e-05 d 105 29 -1.28755e-05 d 106 29 -1.26691e-05 d 107 29 -1.24627e-05 d 108 29 -1.22563e-05 d 109 29 -1.205e-05 d 110 29 -1.18436e-05 d 111 29 -1.16372e-05 d 112 29 -1.14308e-05 d 113 29 -1.12244e-05 d 114 29 -1.1018e-05 d 115 29 -1.08116e-05 d 116 29 -1.06052e-05 d 117 29 -1.03988e-05 d 118 29 -1.01924e-05 d 119 29 -9.98605e-06 d 120 29 -9.77966e-06 d 121 29 -2.85319e-05 d 122 29 0.00281092 d 123 29 0.00180106 d 124 29 -0.000981083 d 125 29 0.00551926 d 126 29 -0.00119763 d 127 29 -0.0295069 d 128 29 -0.0367677 d 129 29 0.064749 d 130 29 0.119022 d 131 29 0.0882007 d 132 29 0.0552062 d 133 29 0.03418 d 134 29 0.0223243 d 135 29 0.015545 d 136 29 0.011949 d 137 29 0.00757134 d 138 29 0.00667655 d 139 29 0.00583243 d 140 29 0.00644443 d 141 29 0.00650959 d 142 29 -0.0302575 d 143 29 -0.0437806 d 144 29 -0.0355466 d 145 29 0.0381776 d 146 29 0.282109 d 147 29 0.674178 d 148 29 1.07582 d 149 29 1.45189 d 150 29 1.789 d 151 29 2.08649 d 152 29 2.34663 d 153 29 2.57245 d 154 29 2.81211 d 155 29 3.04778 d 156 29 3.2523 d 157 29 3.45877 d 158 29 3.65593 d 159 29 3.83396 d 160 29 3.9923 d 161 29 4.13368 d 162 29 4.25864 d 163 29 4.36719 d 164 29 4.46064 d 165 29 4.54086 d 166 29 4.60962 d 167 29 4.66835 d 168 29 4.71838 d 169 29 4.76094 d 170 29 4.79716 d 171 29 4.82796 d 172 29 4.85413 d 173 29 4.87634 d 174 29 4.89518 d 175 29 4.91116 d 176 29 4.92476 d 177 29 4.93631 d 178 29 4.94608 d 179 29 4.95434 d 180 29 4.9613 d 181 29 4.96715 d 182 29 4.97211 d 183 29 4.97638 d 184 29 4.98001 d 185 29 4.98312 d 186 29 4.98571 d 187 29 4.98795 d 188 29 4.98979 d 189 29 4.99138 d 190 29 4.99269 d 191 29 4.99381 d 192 29 4.99474 d 193 29 4.99551 d 194 29 4.99615 d 195 29 4.99668 d 196 29 4.99713 d 197 29 4.99752 d 198 29 4.99783 d 199 29 4.99811 d 200 29 4.99836 d 201 29 4.99858 d 202 29 4.99873 d 203 29 4.99884 d 204 29 4.99892 d 205 29 4.999 d 206 29 4.99907 d 207 29 4.99912 d 208 29 4.99916 d 209 29 4.99921 d 210 29 4.99926 d 211 29 4.99932 d 212 29 4.99937 d 213 29 4.99942 d 214 29 4.99948 d 215 29 4.99953 d 216 29 4.99956 d 217 29 4.99958 d 218 29 4.99961 d 219 29 4.99963 d 220 29 4.99966 d 221 29 4.99968 d 222 29 4.99971 d 223 29 4.99972 d 224 29 4.99973 d 225 29 4.99974 d 226 29 4.99975 d 227 29 4.99976 d 228 29 4.99977 d 229 29 4.99978 d 230 29 4.99979 d 231 29 4.9998 d 232 29 4.9998 d 233 29 4.99981 d 234 29 4.99982 d 235 29 4.99983 d 236 29 4.99984 d 237 29 4.99985 d 238 29 4.99986 d 239 29 4.99986 d 240 29 4.99987 d 241 29 4.99987 d 242 29 5.00498 d 243 29 5.00354 d 244 29 4.99359 d 245 29 4.98981 d 246 29 5.00498 d 247 29 5.00099 d 248 29 5.00041 d 249 29 5.00022 d 250 29 5.00015 d 251 29 5.00012 d 252 29 5.0001 d 253 29 5.00008 d 254 29 5.00005 d 255 29 5.00003 d 256 29 5.0 d 257 29 4.99431 d 258 29 4.99459 d 259 29 4.99591 d 260 29 5.00087 d 261 29 5.01029 d 262 29 5.03935 d 263 29 4.92784 d 264 29 4.51643 d 265 29 3.78356 d 266 29 2.68745 d 267 29 1.43417 d 268 29 0.583128 d 269 29 0.205094 d 270 29 0.0777337 d 271 29 0.0391566 d 272 29 0.02723 d 273 29 0.023883 d 274 29 0.018808 d 275 29 0.010165 d 276 29 0.00254623 d 277 29 -0.00377463 d 278 29 -0.0038097 d 279 29 0.00144145 d 280 29 0.00267231 d 281 29 0.00193045 d 282 29 0.00144538 d 283 29 0.00121758 d 284 29 0.00112893 d 285 29 0.00109424 d 286 29 0.0010226 d 287 29 0.000948072 d 288 29 0.000882573 d 289 29 0.000826996 d 290 29 0.000776391 d 291 29 0.000729719 d 292 29 0.000686499 d 293 29 0.000647333 d 294 29 0.000610108 d 295 29 0.000575631 d 296 29 0.000545069 d 297 29 0.000515485 d 298 29 0.000488514 d 299 29 0.000465316 d 300 29 0.000443215 d 301 29 0.000422454 d 302 29 0.00040292 d 303 29 0.00038488 d 304 29 0.000368472 d 305 29 0.000353628 d 306 29 0.000339643 d 307 29 0.000326197 d 308 29 0.000313483 d 309 29 0.000302884 d 310 29 0.000294038 d 311 29 0.000284003 d 312 29 0.000270941 d 313 29 0.000254925 d 314 29 0.000246511 d 315 29 0.000244089 d 316 29 0.000245538 d 317 29 0.000242099 d 318 29 0.000235728 d 319 29 0.000227482 d 320 29 0.000218001 d 321 29 0.000207257 d 322 29 0.000202127 d 323 29 0.000196997 d 324 29 0.000191868 d 325 29 0.000186738 d 326 29 0.000181608 d 327 29 0.00017758 d 328 29 0.000173899 d 329 29 0.000170219 d 330 29 0.000166538 d 331 29 0.000162857 d 332 29 0.000159576 d 333 29 0.00015679 d 334 29 0.000154005 d 335 29 0.000151219 d 336 29 0.000148433 d 337 29 0.000145647 d 338 29 0.000142861 d 339 29 0.000140076 d 340 29 0.00013729 d 341 29 0.000134504 d 342 29 0.000131718 d 343 29 0.000129603 d 344 29 0.000127635 d 345 29 0.000125668 d 346 29 0.0001237 d 347 29 0.000121732 d 348 29 0.000119765 d 349 29 0.000117797 d 350 29 0.000115829 d 351 29 0.000113862 d 352 29 0.000111894 d 353 29 0.000109993 d 354 29 0.000108372 d 355 29 0.000106751 d 356 29 0.00010513 d 357 29 0.000103509 d 358 29 0.000101887 d 359 29 0.000100266 d 360 29 9.86449e-05 d 361 29 9.70237e-05 d 1 30 5.0 d 2 30 4.99899 d 3 30 4.99654 d 4 30 4.99327 d 5 30 4.9863 d 6 30 4.98954 d 7 30 4.99212 d 8 30 4.99378 d 9 30 4.9951 d 10 30 4.99624 d 11 30 4.99715 d 12 30 4.99786 d 13 30 4.99839 d 14 30 4.99879 d 15 30 4.99909 d 16 30 4.99931 d 17 30 4.99922 d 18 30 4.99933 d 19 30 4.99971 d 20 30 5.00064 d 21 30 5.00084 d 22 30 5.00123 d 23 30 4.99865 d 24 30 4.99853 d 25 30 4.99983 d 26 30 5.00457 d 27 30 5.00242 d 28 30 5.00105 d 29 30 5.00062 d 30 30 5.00042 d 31 30 4.99971 d 32 30 4.9994 d 33 30 4.9992 d 34 30 4.9996 d 35 30 4.99955 d 36 30 4.99932 d 37 30 4.99918 d 38 30 4.99915 d 39 30 4.99919 d 40 30 4.99927 d 41 30 4.99937 d 42 30 4.99948 d 43 30 4.99957 d 44 30 4.99966 d 45 30 4.99974 d 46 30 4.9998 d 47 30 4.99985 d 48 30 4.99989 d 49 30 4.99992 d 50 30 4.99993 d 51 30 4.99994 d 52 30 4.99994 d 53 30 4.99996 d 54 30 4.99998 d 55 30 5.0 d 56 30 5.0 d 57 30 5.00001 d 58 30 5.00001 d 59 30 5.00001 d 60 30 5.00002 d 61 30 5.00002 d 62 30 5.00001 d 63 30 5.00001 d 64 30 5.00001 d 65 30 5.0 d 66 30 5.0 d 67 30 5.0 d 68 30 5.0 d 69 30 4.99999 d 70 30 4.99999 d 71 30 4.99999 d 72 30 4.99999 d 73 30 4.99999 d 74 30 4.99999 d 75 30 4.99999 d 76 30 4.99998 d 77 30 4.99998 d 78 30 4.99999 d 79 30 4.99999 d 80 30 4.99999 d 81 30 4.99999 d 82 30 4.99999 d 83 30 4.99999 d 84 30 4.99999 d 85 30 4.99999 d 86 30 5.0 d 87 30 5.0 d 88 30 5.0 d 89 30 5.0 d 90 30 5.0 d 91 30 5.0 d 92 30 5.00001 d 93 30 5.00001 d 94 30 5.00001 d 95 30 5.00001 d 96 30 5.00001 d 97 30 5.00001 d 98 30 5.00001 d 99 30 5.00002 d 100 30 5.00002 d 101 30 5.00001 d 102 30 5.00001 d 103 30 5.00001 d 104 30 5.00001 d 105 30 5.00001 d 106 30 5.00001 d 107 30 5.00001 d 108 30 5.00001 d 109 30 5.00001 d 110 30 5.00001 d 111 30 5.00001 d 112 30 5.00001 d 113 30 5.00001 d 114 30 5.00001 d 115 30 5.0 d 116 30 5.0 d 117 30 5.0 d 118 30 5.0 d 119 30 5.0 d 120 30 5.0 d 121 30 4.9997 d 122 30 4.99998 d 123 30 4.99954 d 124 30 4.99963 d 125 30 5.00059 d 126 30 4.99945 d 127 30 4.99732 d 128 30 4.99957 d 129 30 5.00919 d 130 30 5.00558 d 131 30 5.00033 d 132 30 4.99851 d 133 30 4.9983 d 134 30 4.99854 d 135 30 4.99871 d 136 30 4.99928 d 137 30 4.99914 d 138 30 4.99939 d 139 30 4.99952 d 140 30 4.9998 d 141 30 4.99976 d 142 30 4.99744 d 143 30 4.99598 d 144 30 4.99478 d 145 30 4.99806 d 146 30 5.01911 d 147 30 5.04602 d 148 30 5.05469 d 149 30 5.01317 d 150 30 4.89484 d 151 30 4.69655 d 152 30 4.42036 d 153 30 4.06069 d 154 30 3.60793 d 155 30 3.12531 d 156 30 2.72975 d 157 30 2.45187 d 158 30 2.25081 d 159 30 2.09841 d 160 30 1.98509 d 161 30 1.90211 d 162 30 1.84084 d 163 30 1.79411 d 164 30 1.7574 d 165 30 1.72763 d 166 30 1.70283 d 167 30 1.68188 d 168 30 1.66389 d 169 30 1.64823 d 170 30 1.63438 d 171 30 1.62201 d 172 30 1.61088 d 173 30 1.60081 d 174 30 1.59163 d 175 30 1.58323 d 176 30 1.57549 d 177 30 1.56835 d 178 30 1.56173 d 179 30 1.55558 d 180 30 1.54985 d 181 30 1.54451 d 182 30 1.53951 d 183 30 1.53479 d 184 30 1.53035 d 185 30 1.52615 d 186 30 1.5222 d 187 30 1.51845 d 188 30 1.5149 d 189 30 1.51153 d 190 30 1.50834 d 191 30 1.50529 d 192 30 1.5024 d 193 30 1.49964 d 194 30 1.497 d 195 30 1.49449 d 196 30 1.49208 d 197 30 1.48977 d 198 30 1.48755 d 199 30 1.48542 d 200 30 1.48336 d 201 30 1.48138 d 202 30 1.47948 d 203 30 1.47765 d 204 30 1.4759 d 205 30 1.47419 d 206 30 1.47255 d 207 30 1.47096 d 208 30 1.46949 d 209 30 1.46823 d 210 30 1.46696 d 211 30 1.4657 d 212 30 1.46444 d 213 30 1.46317 d 214 30 1.46191 d 215 30 1.46065 d 216 30 1.45956 d 217 30 1.4585 d 218 30 1.45743 d 219 30 1.45636 d 220 30 1.45529 d 221 30 1.45422 d 222 30 1.45315 d 223 30 1.45226 d 224 30 1.45145 d 225 30 1.45064 d 226 30 1.44983 d 227 30 1.44902 d 228 30 1.44821 d 229 30 1.4474 d 230 30 1.44659 d 231 30 1.44579 d 232 30 1.44498 d 233 30 1.44417 d 234 30 1.44336 d 235 30 1.44255 d 236 30 1.44174 d 237 30 1.44094 d 238 30 1.44019 d 239 30 1.43944 d 240 30 1.43868 d 241 30 1.43793 d 242 30 1.43765 d 243 30 1.43679 d 244 30 1.43515 d 245 30 1.43405 d 246 30 1.43478 d 247 30 1.43387 d 248 30 1.43345 d 249 30 1.43184 d 250 30 1.43086 d 251 30 1.43021 d 252 30 1.43003 d 253 30 1.42988 d 254 30 1.42944 d 255 30 1.42883 d 256 30 1.42818 d 257 30 1.42702 d 258 30 1.42642 d 259 30 1.42595 d 260 30 1.42586 d 261 30 1.42616 d 262 30 1.42783 d 263 30 1.41733 d 264 30 1.38106 d 265 30 1.30738 d 266 30 1.3877 d 267 30 2.09819 d 268 30 3.05285 d 269 30 3.58059 d 270 30 3.77601 d 271 30 3.87609 d 272 30 4.02557 d 273 30 4.24887 d 274 30 4.4608 d 275 30 4.60411 d 276 30 4.72109 d 277 30 4.8255 d 278 30 4.90465 d 279 30 4.97379 d 280 30 5.01253 d 281 30 5.01532 d 282 30 5.01239 d 283 30 5.0092 d 284 30 5.00665 d 285 30 5.00474 d 286 30 5.00333 d 287 30 5.00232 d 288 30 5.00163 d 289 30 5.00117 d 290 30 5.00082 d 291 30 5.00057 d 292 30 5.00039 d 293 30 5.00027 d 294 30 5.00019 d 295 30 5.00013 d 296 30 5.00009 d 297 30 5.00006 d 298 30 5.00004 d 299 30 5.00003 d 300 30 5.00002 d 301 30 5.00001 d 302 30 5.00001 d 303 30 5.0 d 304 30 5.0 d 305 30 5.0 d 306 30 4.99998 d 307 30 4.99995 d 308 30 4.99992 d 309 30 4.99996 d 310 30 5.00005 d 311 30 5.00012 d 312 30 5.00008 d 313 30 4.99996 d 314 30 4.9999 d 315 30 4.99985 d 316 30 4.99986 d 317 30 4.99997 d 318 30 5.00021 d 319 30 5.0003 d 320 30 5.00024 d 321 30 5.00009 d 322 30 5.00007 d 323 30 5.00005 d 324 30 5.00003 d 325 30 5.00001 d 326 30 4.99998 d 327 30 4.99998 d 328 30 4.99998 d 329 30 4.99999 d 330 30 4.99999 d 331 30 5.0 d 332 30 5.0 d 333 30 5.0 d 334 30 5.0 d 335 30 5.0 d 336 30 5.00001 d 337 30 5.00001 d 338 30 5.00001 d 339 30 5.00001 d 340 30 5.00001 d 341 30 5.00001 d 342 30 5.00002 d 343 30 5.00002 d 344 30 5.00001 d 345 30 5.00001 d 346 30 5.00001 d 347 30 5.00001 d 348 30 5.00001 d 349 30 5.00001 d 350 30 5.0 d 351 30 5.0 d 352 30 5.0 d 353 30 5.0 d 354 30 5.0 d 355 30 4.99999 d 356 30 4.99999 d 357 30 4.99999 d 358 30 4.99999 d 359 30 4.99998 d 360 30 4.99998 d 361 30 4.99998 d 1 31 7.10441e-10 d 2 31 5.70385e-05 d 3 31 0.000226143 d 4 31 0.000131916 d 5 31 -0.000887764 d 6 31 -8.01837e-05 d 7 31 -3.49653e-05 d 8 31 9.40039e-05 d 9 31 0.000118663 d 10 31 0.000108025 d 11 31 8.6059e-05 d 12 31 6.33268e-05 d 13 31 4.99295e-05 d 14 31 3.16843e-05 d 15 31 3.60692e-05 d 16 31 2.07572e-05 d 17 31 -8.6375e-05 d 18 31 3.44583e-05 d 19 31 8.07397e-05 d 20 31 0.000196296 d 21 31 0.000115615 d 22 31 -7.12768e-05 d 23 31 -0.000129812 d 24 31 -4.18679e-05 d 25 31 7.94364e-05 d 26 31 0.000182034 d 27 31 -5.41226e-05 d 28 31 -0.000451819 d 29 31 -0.000713937 d 30 31 -0.00129863 d 31 31 -0.00262186 d 32 31 -0.00213417 d 33 31 -0.00133767 d 34 31 0.000775698 d 35 31 0.000969902 d 36 31 0.000549281 d 37 31 0.000280946 d 38 31 0.000140321 d 39 31 8.6919e-05 d 40 31 7.22446e-05 d 41 31 6.5631e-05 d 42 31 6.45263e-05 d 43 31 6.63087e-05 d 44 31 7.17391e-05 d 45 31 7.59042e-05 d 46 31 7.59172e-05 d 47 31 7.03353e-05 d 48 31 6.33558e-05 d 49 31 5.31136e-05 d 50 31 4.64278e-05 d 51 31 4.40594e-05 d 52 31 4.16909e-05 d 53 31 4.05674e-05 d 54 31 3.96957e-05 d 55 31 3.87875e-05 d 56 31 3.74977e-05 d 57 31 3.62079e-05 d 58 31 3.49181e-05 d 59 31 3.36283e-05 d 60 31 3.23385e-05 d 61 31 3.12427e-05 d 62 31 3.02775e-05 d 63 31 2.93124e-05 d 64 31 2.83472e-05 d 65 31 2.7382e-05 d 66 31 2.64613e-05 d 67 31 2.59077e-05 d 68 31 2.5354e-05 d 69 31 2.48004e-05 d 70 31 2.42468e-05 d 71 31 2.36931e-05 d 72 31 2.31395e-05 d 73 31 2.25859e-05 d 74 31 2.20322e-05 d 75 31 2.14786e-05 d 76 31 2.0925e-05 d 77 31 2.03916e-05 d 78 31 1.9995e-05 d 79 31 1.95984e-05 d 80 31 1.92019e-05 d 81 31 1.88053e-05 d 82 31 1.84087e-05 d 83 31 1.80122e-05 d 84 31 1.76156e-05 d 85 31 1.7219e-05 d 86 31 1.68225e-05 d 87 31 1.64259e-05 d 88 31 1.6051e-05 d 89 31 1.57991e-05 d 90 31 1.55471e-05 d 91 31 1.52952e-05 d 92 31 1.50433e-05 d 93 31 1.47913e-05 d 94 31 1.45394e-05 d 95 31 1.42875e-05 d 96 31 1.40356e-05 d 97 31 1.37836e-05 d 98 31 1.35317e-05 d 99 31 1.32978e-05 d 100 31 1.31513e-05 d 101 31 1.30048e-05 d 102 31 1.28583e-05 d 103 31 1.27118e-05 d 104 31 1.25653e-05 d 105 31 1.24188e-05 d 106 31 1.22724e-05 d 107 31 1.21259e-05 d 108 31 1.19794e-05 d 109 31 1.18329e-05 d 110 31 1.16864e-05 d 111 31 1.15399e-05 d 112 31 1.13934e-05 d 113 31 1.12469e-05 d 114 31 1.11005e-05 d 115 31 1.0954e-05 d 116 31 1.08075e-05 d 117 31 1.0661e-05 d 118 31 1.05145e-05 d 119 31 1.0368e-05 d 120 31 1.02215e-05 d 121 31 1.76447e-05 d 122 31 7.21516e-05 d 123 31 -3.59786e-05 d 124 31 -0.000159618 d 125 31 0.000156236 d 126 31 0.000135106 d 127 31 -0.000336402 d 128 31 -0.000302283 d 129 31 0.000699323 d 130 31 0.000473866 d 131 31 -0.000156146 d 132 31 -0.000225625 d 133 31 -0.000123592 d 134 31 -3.78116e-05 d 135 31 8.47472e-06 d 136 31 2.43387e-06 d 137 31 -7.44762e-05 d 138 31 7.80111e-05 d 139 31 9.43608e-05 d 140 31 0.000170159 d 141 31 8.83919e-05 d 142 31 -0.00018802 d 143 31 -0.000373512 d 144 31 -0.000390597 d 145 31 0.000156875 d 146 31 0.0032343 d 147 31 0.00776304 d 148 31 -0.000566905 d 149 31 -0.00760695 d 150 31 -0.0159226 d 151 31 -0.0245989 d 152 31 -0.0331402 d 153 31 -0.0100902 d 154 31 0.067837 d 155 31 0.266702 d 156 31 0.910818 d 157 31 1.82282 d 158 31 2.69714 d 159 31 3.43247 d 160 31 3.98325 d 161 31 4.32893 d 162 31 4.51529 d 163 31 4.67087 d 164 31 4.79288 d 165 31 4.87574 d 166 31 4.92797 d 167 31 4.95902 d 168 31 4.97655 d 169 31 4.98622 d 170 31 4.99195 d 171 31 4.99526 d 172 31 4.99735 d 173 31 4.9991 d 174 31 4.99974 d 175 31 4.99982 d 176 31 4.99974 d 177 31 4.99961 d 178 31 4.9995 d 179 31 4.99943 d 180 31 4.9994 d 181 31 4.9994 d 182 31 4.99942 d 183 31 4.99944 d 184 31 4.99948 d 185 31 4.99952 d 186 31 4.99956 d 187 31 4.99961 d 188 31 4.99965 d 189 31 4.9997 d 190 31 4.99974 d 191 31 4.99977 d 192 31 4.99981 d 193 31 4.99983 d 194 31 4.99986 d 195 31 4.99988 d 196 31 4.9999 d 197 31 4.99991 d 198 31 4.99992 d 199 31 4.99993 d 200 31 4.99994 d 201 31 4.99995 d 202 31 4.99995 d 203 31 4.99996 d 204 31 4.99997 d 205 31 4.99997 d 206 31 4.99998 d 207 31 4.99998 d 208 31 4.99999 d 209 31 4.99999 d 210 31 4.99999 d 211 31 5.0 d 212 31 5.0 d 213 31 5.0 d 214 31 5.00001 d 215 31 5.00001 d 216 31 5.00001 d 217 31 5.00001 d 218 31 5.00001 d 219 31 5.0 d 220 31 5.0 d 221 31 5.0 d 222 31 5.0 d 223 31 5.0 d 224 31 5.0 d 225 31 5.0 d 226 31 4.99999 d 227 31 4.99999 d 228 31 4.99999 d 229 31 4.99999 d 230 31 4.99999 d 231 31 4.99999 d 232 31 4.99999 d 233 31 4.99999 d 234 31 4.99999 d 235 31 4.99999 d 236 31 4.99999 d 237 31 4.99999 d 238 31 4.99999 d 239 31 4.99999 d 240 31 4.99999 d 241 31 5.0 d 242 31 5.00019 d 243 31 4.99888 d 244 31 4.99663 d 245 31 4.99457 d 246 31 4.99902 d 247 31 5.00229 d 248 31 5.00323 d 249 31 5.00302 d 250 31 5.0023 d 251 31 5.0015 d 252 31 5.00085 d 253 31 5.00041 d 254 31 5.00013 d 255 31 4.99993 d 256 31 4.99979 d 257 31 4.99948 d 258 31 4.99954 d 259 31 4.99983 d 260 31 5.00055 d 261 31 5.00109 d 262 31 5.00009 d 263 31 4.9987 d 264 31 4.998 d 265 31 4.99755 d 266 31 4.99676 d 267 31 4.99618 d 268 31 5.01091 d 269 31 5.05272 d 270 31 5.04156 d 271 31 4.80112 d 272 31 4.27692 d 273 31 3.42343 d 274 31 2.23953 d 275 31 0.967179 d 276 31 0.429813 d 277 31 0.540757 d 278 31 1.32991 d 279 31 2.32147 d 280 31 3.14903 d 281 31 3.78143 d 282 31 4.22325 d 283 31 4.47978 d 284 31 4.59448 d 285 31 4.69875 d 286 31 4.79798 d 287 31 4.87419 d 288 31 4.92339 d 289 31 4.95249 d 290 31 4.97174 d 291 31 4.98408 d 292 31 4.99124 d 293 31 4.99478 d 294 31 4.99729 d 295 31 4.99868 d 296 31 4.9992 d 297 31 4.99941 d 298 31 4.99947 d 299 31 4.99946 d 300 31 4.99943 d 301 31 4.9994 d 302 31 4.99939 d 303 31 4.9994 d 304 31 4.99942 d 305 31 4.99946 d 306 31 4.99951 d 307 31 4.99956 d 308 31 4.99961 d 309 31 4.99967 d 310 31 4.99973 d 311 31 4.99977 d 312 31 4.9998 d 313 31 4.99981 d 314 31 4.99983 d 315 31 4.99984 d 316 31 4.99987 d 317 31 4.99992 d 318 31 5.00001 d 319 31 5.00005 d 320 31 5.00001 d 321 31 4.99994 d 322 31 4.99995 d 323 31 4.99995 d 324 31 4.99996 d 325 31 4.99996 d 326 31 4.99996 d 327 31 4.99997 d 328 31 4.99997 d 329 31 4.99997 d 330 31 4.99998 d 331 31 4.99998 d 332 31 4.99998 d 333 31 4.99998 d 334 31 4.99999 d 335 31 4.99999 d 336 31 4.99999 d 337 31 4.99999 d 338 31 5.0 d 339 31 5.0 d 340 31 5.0 d 341 31 5.00001 d 342 31 5.00001 d 343 31 5.00001 d 344 31 5.00001 d 345 31 5.00001 d 346 31 5.00001 d 347 31 5.0 d 348 31 5.0 d 349 31 5.0 d 350 31 5.0 d 351 31 5.0 d 352 31 5.0 d 353 31 5.0 d 354 31 5.0 d 355 31 4.99999 d 356 31 4.99999 d 357 31 4.99999 d 358 31 4.99999 d 359 31 4.99998 d 360 31 4.99998 d 361 31 4.99998 d 1 32 1.8179e-09 d 2 32 -5.28841e-06 d 3 32 -1.44913e-05 d 4 32 -3.62932e-05 d 5 32 -9.75719e-05 d 6 32 0.000141781 d 7 32 3.73396e-05 d 8 32 -1.65603e-05 d 9 32 -1.5271e-05 d 10 32 -6.73884e-06 d 11 32 4.40157e-06 d 12 32 -4.85345e-06 d 13 32 -1.02964e-05 d 14 32 2.03126e-05 d 15 32 -1.89457e-05 d 16 32 -8.75564e-06 d 17 32 7.67422e-06 d 18 32 4.71103e-06 d 19 32 1.29798e-05 d 20 32 6.13469e-06 d 21 32 -1.14363e-05 d 22 32 -0.0394563 d 23 32 -0.0477298 d 24 32 -0.0622012 d 25 32 -0.0519225 d 26 32 0.262499 d 27 32 0.943611 d 28 32 1.67052 d 29 32 2.31017 d 30 32 2.84028 d 31 32 3.28467 d 32 32 3.61582 d 33 32 3.85887 d 34 32 4.13011 d 35 32 4.36511 d 36 32 4.54063 d 37 32 4.67013 d 38 32 4.76408 d 39 32 4.83263 d 40 32 4.8825 d 41 32 4.91837 d 42 32 4.94373 d 43 32 4.96117 d 44 32 4.97318 d 45 32 4.98093 d 46 32 4.98562 d 47 32 4.98906 d 48 32 4.99267 d 49 32 4.99539 d 50 32 4.99666 d 51 32 4.99731 d 52 32 4.99797 d 53 32 4.99844 d 54 32 4.99887 d 55 32 4.99927 d 56 32 4.99933 d 57 32 4.99938 d 58 32 4.99944 d 59 32 4.99949 d 60 32 4.99955 d 61 32 4.9996 d 62 32 4.99965 d 63 32 4.9997 d 64 32 4.99975 d 65 32 4.9998 d 66 32 4.99985 d 67 32 4.99986 d 68 32 4.99987 d 69 32 4.99989 d 70 32 4.9999 d 71 32 4.99991 d 72 32 4.99992 d 73 32 4.99993 d 74 32 4.99995 d 75 32 4.99996 d 76 32 4.99997 d 77 32 4.99998 d 78 32 4.99998 d 79 32 4.99999 d 80 32 4.99999 d 81 32 4.99999 d 82 32 4.99999 d 83 32 5.0 d 84 32 5.0 d 85 32 5.0 d 86 32 5.0 d 87 32 5.00001 d 88 32 5.00001 d 89 32 5.00001 d 90 32 5.0 d 91 32 5.0 d 92 32 5.0 d 93 32 5.0 d 94 32 5.0 d 95 32 5.0 d 96 32 4.99999 d 97 32 4.99999 d 98 32 4.99999 d 99 32 4.99999 d 100 32 4.99999 d 101 32 4.99999 d 102 32 4.99999 d 103 32 4.99999 d 104 32 4.99999 d 105 32 4.99999 d 106 32 4.99999 d 107 32 4.99999 d 108 32 4.99999 d 109 32 4.99999 d 110 32 4.99999 d 111 32 4.99999 d 112 32 4.99999 d 113 32 4.99999 d 114 32 4.99999 d 115 32 4.99999 d 116 32 4.99999 d 117 32 4.99999 d 118 32 4.99999 d 119 32 4.99999 d 120 32 4.99999 d 121 32 4.99999 d 122 32 4.99997 d 123 32 5.00002 d 124 32 5.00004 d 125 32 5.0001 d 126 32 5.0001 d 127 32 4.99987 d 128 32 5.00009 d 129 32 5.00021 d 130 32 5.00002 d 131 32 5.00004 d 132 32 4.99988 d 133 32 5.00013 d 134 32 4.99993 d 135 32 5.00026 d 136 32 4.99973 d 137 32 5.0 d 138 32 5.00006 d 139 32 5.00009 d 140 32 5.00004 d 141 32 5.00004 d 142 32 5.04854 d 143 32 4.82711 d 144 32 4.04208 d 145 32 2.64155 d 146 32 0.838902 d 147 32 0.19014 d 148 32 0.0982549 d 149 32 0.0723197 d 150 32 0.0576863 d 151 32 0.0427644 d 152 32 0.0301979 d 153 32 0.020146 d 154 32 0.0135728 d 155 32 0.00980358 d 156 32 0.00774482 d 157 32 0.00586604 d 158 32 0.0036687 d 159 32 0.00211511 d 160 32 0.00121906 d 161 32 0.000647581 d 162 32 0.000828436 d 163 32 0.00190938 d 164 32 0.00224254 d 165 32 0.00199956 d 166 32 0.00165488 d 167 32 0.00135612 d 168 32 0.00113715 d 169 32 0.000984181 d 170 32 0.000877175 d 171 32 0.000789973 d 172 32 0.000741139 d 173 32 0.000689338 d 174 32 0.000625676 d 175 32 0.000586082 d 176 32 0.000550152 d 177 32 0.000529573 d 178 32 0.000505606 d 179 32 0.000482117 d 180 32 0.000460574 d 181 32 0.000441649 d 182 32 0.000424674 d 183 32 0.000408398 d 184 32 0.000391914 d 185 32 0.000376272 d 186 32 0.000361487 d 187 32 0.000348181 d 188 32 0.000336045 d 189 32 0.000324466 d 190 32 0.000313545 d 191 32 0.000303046 d 192 32 0.000293056 d 193 32 0.00028356 d 194 32 0.000274586 d 195 32 0.000266155 d 196 32 0.000258279 d 197 32 0.000250938 d 198 32 0.000243789 d 199 32 0.000236912 d 200 32 0.000230244 d 201 32 0.000224186 d 202 32 0.000219291 d 203 32 0.000215346 d 204 32 0.000212468 d 205 32 0.000207291 d 206 32 0.000200862 d 207 32 0.00019368 d 208 32 0.000186767 d 209 32 0.000183515 d 210 32 0.000180263 d 211 32 0.00017701 d 212 32 0.000173758 d 213 32 0.000170506 d 214 32 0.000167253 d 215 32 0.000164001 d 216 32 0.000161164 d 217 32 0.000158357 d 218 32 0.00015555 d 219 32 0.000152743 d 220 32 0.000149936 d 221 32 0.000147129 d 222 32 0.000144322 d 223 32 0.000142066 d 224 32 0.000140096 d 225 32 0.000138127 d 226 32 0.000136157 d 227 32 0.000134187 d 228 32 0.000132218 d 229 32 0.000130248 d 230 32 0.000128278 d 231 32 0.000126308 d 232 32 0.000124339 d 233 32 0.000122369 d 234 32 0.000120399 d 235 32 0.000118429 d 236 32 0.00011646 d 237 32 0.000114527 d 238 32 0.000112892 d 239 32 0.000111258 d 240 32 0.000109623 d 241 32 0.000107988 d 242 32 0.000103598 d 243 32 6.86052e-05 d 244 32 3.337e-05 d 245 32 7.00783e-05 d 246 32 0.000218764 d 247 32 0.000221318 d 248 32 0.000118593 d 249 32 -0.000113962 d 250 32 5.78552e-05 d 251 32 9.42068e-05 d 252 32 0.000237037 d 253 32 0.000171302 d 254 32 0.0001033 d 255 32 6.16066e-05 d 256 32 5.52908e-05 d 257 32 6.30233e-05 d 258 32 7.01897e-05 d 259 32 8.48573e-05 d 260 32 0.000106859 d 261 32 8.37213e-05 d 262 32 -0.0391541 d 263 32 -0.047722 d 264 32 -0.0618454 d 265 32 -0.0169804 d 266 32 0.345725 d 267 32 1.03426 d 268 32 1.74825 d 269 32 2.37152 d 270 32 2.88737 d 271 32 3.32173 d 272 32 3.66761 d 273 32 3.9707 d 274 32 4.17762 d 275 32 3.98832 d 276 32 3.30483 d 277 32 2.09737 d 278 32 0.710892 d 279 32 0.148159 d 280 32 0.0707463 d 281 32 0.0555808 d 282 32 0.045618 d 283 32 0.0319116 d 284 32 0.0199589 d 285 32 0.0133357 d 286 32 0.00898528 d 287 32 0.00586075 d 288 32 0.00375478 d 289 32 0.00245443 d 290 32 0.00156038 d 291 32 0.000962344 d 292 32 0.000590953 d 293 32 0.000375107 d 294 32 0.000250243 d 295 32 0.00015882 d 296 32 0.000100203 d 297 32 6.18122e-05 d 298 32 3.7372e-05 d 299 32 2.23009e-05 d 300 32 1.32569e-05 d 301 32 8.29437e-06 d 302 32 5.72457e-06 d 303 32 3.96832e-06 d 304 32 2.98935e-06 d 305 32 2.59699e-06 d 306 32 2.75024e-06 d 307 32 3.38689e-06 d 308 32 4.0453e-06 d 309 32 3.50095e-06 d 310 32 1.64988e-06 d 311 32 -3.84371e-07 d 312 32 -2.03828e-06 d 313 32 -3.46401e-06 d 314 32 -1.24301e-06 d 315 32 4.63458e-06 d 316 32 1.14104e-05 d 317 32 1.02619e-05 d 318 32 2.15487e-06 d 319 32 -2.98487e-06 d 320 32 -3.67221e-06 d 321 32 -2.94279e-06 d 322 32 -2.58649e-06 d 323 32 -2.23019e-06 d 324 32 -1.87389e-06 d 325 32 -1.5176e-06 d 326 32 -1.1613e-06 d 327 32 -7.92127e-07 d 328 32 -4.18889e-07 d 329 32 -4.56502e-08 d 330 32 3.27588e-07 d 331 32 7.00827e-07 d 332 32 8.79539e-07 d 333 32 8.17025e-07 d 334 32 7.5451e-07 d 335 32 6.91996e-07 d 336 32 6.29481e-07 d 337 32 5.66966e-07 d 338 32 5.04452e-07 d 339 32 4.41937e-07 d 340 32 3.79422e-07 d 341 32 3.16908e-07 d 342 32 2.54393e-07 d 343 32 1.90078e-07 d 344 32 1.25366e-07 d 345 32 6.0654e-08 d 346 32 -4.05776e-09 d 347 32 -6.87696e-08 d 348 32 -1.33481e-07 d 349 32 -1.98193e-07 d 350 32 -2.62905e-07 d 351 32 -3.27617e-07 d 352 32 -3.92329e-07 d 353 32 -4.40392e-07 d 354 32 -4.18802e-07 d 355 32 -3.97213e-07 d 356 32 -3.75624e-07 d 357 32 -3.54035e-07 d 358 32 -3.32446e-07 d 359 32 -3.10856e-07 d 360 32 -2.89267e-07 d 361 32 -2.67678e-07 d 1 33 1.10294 d 2 33 1.10297 d 3 33 1.10291 d 4 33 1.10277 d 5 33 1.10259 d 6 33 1.10294 d 7 33 1.10313 d 8 33 1.10306 d 9 33 1.10299 d 10 33 1.10296 d 11 33 1.10295 d 12 33 1.10295 d 13 33 1.10294 d 14 33 1.10294 d 15 33 1.10294 d 16 33 1.10294 d 17 33 1.10294 d 18 33 1.10294 d 19 33 1.10294 d 20 33 1.10296 d 21 33 1.10296 d 22 33 1.00547 d 23 33 0.998599 d 24 33 1.5201 d 25 33 2.49297 d 26 33 3.31258 d 27 33 3.73162 d 28 33 3.84757 d 29 33 3.92505 d 30 33 4.02965 d 31 33 4.16599 d 32 33 4.30294 d 33 33 4.41541 d 34 33 4.52886 d 35 33 4.64414 d 36 33 4.73865 d 37 33 4.81065 d 38 33 4.86391 d 39 33 4.90315 d 40 33 4.93188 d 41 33 4.95258 d 42 33 4.96726 d 43 33 4.97738 d 44 33 4.98436 d 45 33 4.98888 d 46 33 4.99162 d 47 33 4.99363 d 48 33 4.99573 d 49 33 4.99731 d 50 33 4.99804 d 51 33 4.99843 d 52 33 4.99881 d 53 33 4.99909 d 54 33 4.99934 d 55 33 4.99957 d 56 33 4.9996 d 57 33 4.99964 d 58 33 4.99967 d 59 33 4.9997 d 60 33 4.99973 d 61 33 4.99977 d 62 33 4.9998 d 63 33 4.99983 d 64 33 4.99986 d 65 33 4.99988 d 66 33 4.99991 d 67 33 4.99992 d 68 33 4.99992 d 69 33 4.99993 d 70 33 4.99994 d 71 33 4.99994 d 72 33 4.99995 d 73 33 4.99996 d 74 33 4.99996 d 75 33 4.99997 d 76 33 4.99997 d 77 33 4.99998 d 78 33 4.99998 d 79 33 4.99999 d 80 33 4.99999 d 81 33 4.99999 d 82 33 4.99999 d 83 33 5.0 d 84 33 5.0 d 85 33 5.0 d 86 33 5.00001 d 87 33 5.00001 d 88 33 5.00001 d 89 33 5.00001 d 90 33 5.00001 d 91 33 5.00001 d 92 33 5.00001 d 93 33 5.00001 d 94 33 5.00001 d 95 33 5.00001 d 96 33 5.00001 d 97 33 5.0 d 98 33 5.0 d 99 33 5.0 d 100 33 5.0 d 101 33 5.0 d 102 33 5.0 d 103 33 5.0 d 104 33 5.0 d 105 33 5.0 d 106 33 5.0 d 107 33 5.0 d 108 33 5.0 d 109 33 5.0 d 110 33 5.0 d 111 33 5.0 d 112 33 5.0 d 113 33 5.0 d 114 33 5.0 d 115 33 4.99999 d 116 33 4.99999 d 117 33 4.99999 d 118 33 4.99999 d 119 33 4.99999 d 120 33 4.99999 d 121 33 4.99999 d 122 33 5.00028 d 123 33 4.99988 d 124 33 4.99968 d 125 33 5.00019 d 126 33 4.99987 d 127 33 5.00021 d 128 33 4.99973 d 129 33 4.99977 d 130 33 4.99996 d 131 33 4.99997 d 132 33 5.0002 d 133 33 4.99957 d 134 33 5.00026 d 135 33 4.99947 d 136 33 5.00074 d 137 33 5.00003 d 138 33 4.99987 d 139 33 4.99979 d 140 33 5.00008 d 141 33 4.99997 d 142 33 5.08794 d 143 33 5.05993 d 144 33 4.76875 d 145 33 3.99197 d 146 33 3.10174 d 147 33 2.5197 d 148 33 2.21771 d 149 33 2.04 d 150 33 1.92235 d 151 33 1.83874 d 152 33 1.77592 d 153 33 1.72665 d 154 33 1.686 d 155 33 1.65276 d 156 33 1.6286 d 157 33 1.61299 d 158 33 1.60039 d 159 33 1.58934 d 160 33 1.57954 d 161 33 1.57083 d 162 33 1.56306 d 163 33 1.55604 d 164 33 1.54963 d 165 33 1.54375 d 166 33 1.53832 d 167 33 1.53331 d 168 33 1.52865 d 169 33 1.52432 d 170 33 1.52026 d 171 33 1.51645 d 172 33 1.51287 d 173 33 1.50949 d 174 33 1.50629 d 175 33 1.50327 d 176 33 1.50039 d 177 33 1.49766 d 178 33 1.49505 d 179 33 1.49257 d 180 33 1.49019 d 181 33 1.48792 d 182 33 1.48574 d 183 33 1.48365 d 184 33 1.48164 d 185 33 1.47971 d 186 33 1.47784 d 187 33 1.47604 d 188 33 1.47431 d 189 33 1.47264 d 190 33 1.47102 d 191 33 1.46945 d 192 33 1.46794 d 193 33 1.46647 d 194 33 1.46505 d 195 33 1.46367 d 196 33 1.46233 d 197 33 1.46103 d 198 33 1.45976 d 199 33 1.45853 d 200 33 1.45733 d 201 33 1.45616 d 202 33 1.45502 d 203 33 1.45392 d 204 33 1.45284 d 205 33 1.45179 d 206 33 1.45076 d 207 33 1.44975 d 208 33 1.4488 d 209 33 1.44795 d 210 33 1.44711 d 211 33 1.44626 d 212 33 1.44541 d 213 33 1.44457 d 214 33 1.44372 d 215 33 1.44287 d 216 33 1.44212 d 217 33 1.44138 d 218 33 1.44063 d 219 33 1.43989 d 220 33 1.43914 d 221 33 1.4384 d 222 33 1.43766 d 223 33 1.43701 d 224 33 1.43641 d 225 33 1.43581 d 226 33 1.43522 d 227 33 1.43462 d 228 33 1.43402 d 229 33 1.43342 d 230 33 1.43282 d 231 33 1.43223 d 232 33 1.43163 d 233 33 1.43103 d 234 33 1.43043 d 235 33 1.42984 d 236 33 1.42924 d 237 33 1.42865 d 238 33 1.42808 d 239 33 1.42752 d 240 33 1.42695 d 241 33 1.42639 d 242 33 1.42584 d 243 33 1.42529 d 244 33 1.42472 d 245 33 1.42412 d 246 33 1.42365 d 247 33 1.42326 d 248 33 1.42304 d 249 33 1.42162 d 250 33 1.42082 d 251 33 1.42032 d 252 33 1.42029 d 253 33 1.42026 d 254 33 1.41995 d 255 33 1.41947 d 256 33 1.41894 d 257 33 1.41841 d 258 33 1.4179 d 259 33 1.41742 d 260 33 1.41699 d 261 33 1.41656 d 262 33 1.32097 d 263 33 1.30963 d 264 33 1.78765 d 265 33 2.64656 d 266 33 3.35764 d 267 33 3.747 d 268 33 3.86589 d 269 33 3.94217 d 270 33 4.04185 d 271 33 4.18453 d 272 33 4.3561 d 273 33 4.53439 d 274 33 4.68621 d 275 33 4.74905 d 276 33 4.77848 d 277 33 4.84629 d 278 33 4.91261 d 279 33 4.97541 d 280 33 5.01284 d 281 33 5.01548 d 282 33 5.01248 d 283 33 5.00924 d 284 33 5.00666 d 285 33 5.00475 d 286 33 5.00334 d 287 33 5.00234 d 288 33 5.00164 d 289 33 5.00118 d 290 33 5.00083 d 291 33 5.00058 d 292 33 5.0004 d 293 33 5.00028 d 294 33 5.00019 d 295 33 5.00013 d 296 33 5.00009 d 297 33 5.00007 d 298 33 5.00004 d 299 33 5.00003 d 300 33 5.00002 d 301 33 5.00001 d 302 33 5.00001 d 303 33 5.00001 d 304 33 5.0 d 305 33 5.0 d 306 33 4.99999 d 307 33 4.99995 d 308 33 4.99992 d 309 33 4.99996 d 310 33 5.00006 d 311 33 5.00012 d 312 33 5.00009 d 313 33 4.99997 d 314 33 4.9999 d 315 33 4.99985 d 316 33 4.99986 d 317 33 4.99997 d 318 33 5.00021 d 319 33 5.00031 d 320 33 5.00024 d 321 33 5.0001 d 322 33 5.00007 d 323 33 5.00005 d 324 33 5.00003 d 325 33 5.00001 d 326 33 4.99998 d 327 33 4.99998 d 328 33 4.99999 d 329 33 4.99999 d 330 33 4.99999 d 331 33 5.0 d 332 33 5.0 d 333 33 5.0 d 334 33 5.0 d 335 33 5.0 d 336 33 5.00001 d 337 33 5.00001 d 338 33 5.00001 d 339 33 5.00001 d 340 33 5.00001 d 341 33 5.00001 d 342 33 5.00002 d 343 33 5.00002 d 344 33 5.00001 d 345 33 5.00001 d 346 33 5.00001 d 347 33 5.00001 d 348 33 5.00001 d 349 33 5.00001 d 350 33 5.00001 d 351 33 5.0 d 352 33 5.0 d 353 33 5.0 d 354 33 5.0 d 355 33 5.0 d 356 33 4.99999 d 357 33 4.99999 d 358 33 4.99999 d 359 33 4.99998 d 360 33 4.99998 d 361 33 4.99998 d 1 34 5.0 d 2 34 5.00012 d 3 34 5.00023 d 4 34 5.0003 d 5 34 4.99972 d 6 34 4.99988 d 7 34 4.99984 d 8 34 4.99991 d 9 34 4.99996 d 10 34 4.99999 d 11 34 5.00008 d 12 34 5.00009 d 13 34 4.99986 d 14 34 5.00003 d 15 34 5.00007 d 16 34 4.99995 d 17 34 4.9999 d 18 34 4.99997 d 19 34 5.00013 d 20 34 5.00014 d 21 34 5.00013 d 22 34 4.99701 d 23 34 4.99763 d 24 34 4.99742 d 25 34 4.99998 d 26 34 5.02836 d 27 34 5.07262 d 28 34 4.96856 d 29 34 4.57267 d 30 34 3.85637 d 31 34 2.79544 d 32 34 1.45942 d 33 34 0.408016 d 34 34 0.084885 d 35 34 0.0271375 d 36 34 0.0119294 d 37 34 0.00707546 d 38 34 0.0051087 d 39 34 0.00373035 d 40 34 0.00264737 d 41 34 0.00186477 d 42 34 0.00130379 d 43 34 0.000915857 d 44 34 0.000653121 d 45 34 0.000483893 d 46 34 0.000380852 d 47 34 0.000302362 d 48 34 0.000219498 d 49 34 0.000154435 d 50 34 0.000121928 d 51 34 0.000104026 d 52 34 8.61242e-05 d 53 34 7.48526e-05 d 54 34 6.49216e-05 d 55 34 5.56238e-05 d 56 34 5.29689e-05 d 57 34 5.03139e-05 d 58 34 4.7659e-05 d 59 34 4.5004e-05 d 60 34 4.23491e-05 d 61 34 4.00356e-05 d 62 34 3.79522e-05 d 63 34 3.58687e-05 d 64 34 3.37852e-05 d 65 34 3.17018e-05 d 66 34 2.97592e-05 d 67 34 2.89804e-05 d 68 34 2.82016e-05 d 69 34 2.74228e-05 d 70 34 2.66441e-05 d 71 34 2.58653e-05 d 72 34 2.50865e-05 d 73 34 2.43077e-05 d 74 34 2.35289e-05 d 75 34 2.27501e-05 d 76 34 2.19714e-05 d 77 34 2.12346e-05 d 78 34 2.07821e-05 d 79 34 2.03295e-05 d 80 34 1.98769e-05 d 81 34 1.94244e-05 d 82 34 1.89718e-05 d 83 34 1.85192e-05 d 84 34 1.80667e-05 d 85 34 1.76141e-05 d 86 34 1.71615e-05 d 87 34 1.6709e-05 d 88 34 1.62828e-05 d 89 34 1.60061e-05 d 90 34 1.57294e-05 d 91 34 1.54527e-05 d 92 34 1.5176e-05 d 93 34 1.48993e-05 d 94 34 1.46226e-05 d 95 34 1.43459e-05 d 96 34 1.40692e-05 d 97 34 1.37925e-05 d 98 34 1.35158e-05 d 99 34 1.3262e-05 d 100 34 1.31191e-05 d 101 34 1.29761e-05 d 102 34 1.28332e-05 d 103 34 1.26903e-05 d 104 34 1.25474e-05 d 105 34 1.24045e-05 d 106 34 1.22615e-05 d 107 34 1.21186e-05 d 108 34 1.19757e-05 d 109 34 1.18328e-05 d 110 34 1.16898e-05 d 111 34 1.15469e-05 d 112 34 1.1404e-05 d 113 34 1.12611e-05 d 114 34 1.11182e-05 d 115 34 1.09752e-05 d 116 34 1.08323e-05 d 117 34 1.06894e-05 d 118 34 1.05465e-05 d 119 34 1.04036e-05 d 120 34 1.02606e-05 d 121 34 1.00185e-05 d 122 34 3.8343e-05 d 123 34 -3.06781e-05 d 124 34 -0.000111758 d 125 34 0.000111673 d 126 34 0.000130815 d 127 34 -0.000210491 d 128 34 -0.000231304 d 129 34 0.000310226 d 130 34 0.000265303 d 131 34 3.0878e-05 d 132 34 -4.48405e-05 d 133 34 -1.2852e-05 d 134 34 -7.84469e-06 d 135 34 3.29986e-05 d 136 34 -1.23286e-05 d 137 34 -6.07871e-05 d 138 34 5.35082e-05 d 139 34 7.69194e-05 d 140 34 0.000126221 d 141 34 6.57178e-05 d 142 34 0.00223349 d 143 34 -0.0148854 d 144 34 -0.0476636 d 145 34 -0.0491447 d 146 34 0.220125 d 147 34 1.11174 d 148 34 2.03988 d 149 34 2.90209 d 150 34 3.61069 d 151 34 4.13554 d 152 34 4.50679 d 153 34 4.71501 d 154 34 4.83916 d 155 34 4.91027 d 156 34 4.95284 d 157 34 4.98086 d 158 34 4.99151 d 159 34 4.98651 d 160 34 4.97113 d 161 34 4.95075 d 162 34 4.93102 d 163 34 4.93683 d 164 34 4.95457 d 165 34 4.97071 d 166 34 4.98212 d 167 34 4.98948 d 168 34 4.99386 d 169 34 4.99636 d 170 34 4.99785 d 171 34 4.9987 d 172 34 4.99927 d 173 34 4.99989 d 174 34 5.00014 d 175 34 5.00007 d 176 34 4.99988 d 177 34 4.99982 d 178 34 4.99976 d 179 34 4.99973 d 180 34 4.99972 d 181 34 4.99972 d 182 34 4.99973 d 183 34 4.99974 d 184 34 4.99975 d 185 34 4.99977 d 186 34 4.99979 d 187 34 4.99981 d 188 34 4.99984 d 189 34 4.99986 d 190 34 4.99988 d 191 34 4.99989 d 192 34 4.99991 d 193 34 4.99992 d 194 34 4.99993 d 195 34 4.99994 d 196 34 4.99995 d 197 34 4.99996 d 198 34 4.99996 d 199 34 4.99997 d 200 34 4.99997 d 201 34 4.99998 d 202 34 4.99998 d 203 34 4.99998 d 204 34 4.99998 d 205 34 4.99999 d 206 34 4.99999 d 207 34 4.99999 d 208 34 4.99999 d 209 34 5.0 d 210 34 5.0 d 211 34 5.0 d 212 34 5.00001 d 213 34 5.00001 d 214 34 5.00001 d 215 34 5.00002 d 216 34 5.00001 d 217 34 5.00001 d 218 34 5.00001 d 219 34 5.00001 d 220 34 5.00001 d 221 34 5.0 d 222 34 5.0 d 223 34 5.0 d 224 34 5.0 d 225 34 5.0 d 226 34 5.0 d 227 34 5.0 d 228 34 5.0 d 229 34 4.99999 d 230 34 4.99999 d 231 34 4.99999 d 232 34 4.99999 d 233 34 4.99999 d 234 34 4.99999 d 235 34 4.99999 d 236 34 4.99999 d 237 34 4.99999 d 238 34 4.99999 d 239 34 4.99999 d 240 34 4.99999 d 241 34 5.0 d 242 34 5.00012 d 243 34 4.99946 d 244 34 4.99839 d 245 34 4.99733 d 246 34 4.99948 d 247 34 5.00114 d 248 34 5.00158 d 249 34 5.00147 d 250 34 5.00113 d 251 34 5.00073 d 252 34 5.00043 d 253 34 5.0002 d 254 34 5.00006 d 255 34 4.99995 d 256 34 4.99986 d 257 34 4.99973 d 258 34 4.99976 d 259 34 4.9999 d 260 34 5.00029 d 261 34 5.00055 d 262 34 4.99704 d 263 34 4.99734 d 264 34 4.9972 d 265 34 5.00278 d 266 34 5.03354 d 267 34 5.07184 d 268 34 4.94057 d 269 34 4.51936 d 270 34 3.75638 d 271 34 2.60982 d 272 34 1.23803 d 273 34 0.315016 d 274 34 0.0796102 d 275 34 0.0252894 d 276 34 0.0165723 d 277 34 0.0827785 d 278 34 0.491298 d 279 34 1.40686 d 280 34 2.33436 d 281 34 3.1251 d 282 34 3.7691 d 283 34 4.22201 d 284 34 4.49976 d 285 34 4.68115 d 286 34 4.80513 d 287 34 4.88509 d 288 34 4.93208 d 289 34 4.95861 d 290 34 4.97579 d 291 34 4.98655 d 292 34 4.99268 d 293 34 4.99571 d 294 34 4.99771 d 295 34 4.99881 d 296 34 4.99929 d 297 34 4.99954 d 298 34 4.99965 d 299 34 4.9997 d 300 34 4.99971 d 301 34 4.99971 d 302 34 4.99971 d 303 34 4.99971 d 304 34 4.99972 d 305 34 4.99974 d 306 34 4.99976 d 307 34 4.99978 d 308 34 4.99981 d 309 34 4.99984 d 310 34 4.99987 d 311 34 4.99989 d 312 34 4.99991 d 313 34 4.99991 d 314 34 4.99992 d 315 34 4.99992 d 316 34 4.99993 d 317 34 4.99997 d 318 34 5.00003 d 319 34 5.00006 d 320 34 5.00004 d 321 34 5.00001 d 322 34 5.0 d 323 34 4.99999 d 324 34 4.99998 d 325 34 4.99998 d 326 34 4.99997 d 327 34 4.99997 d 328 34 4.99997 d 329 34 4.99998 d 330 34 4.99998 d 331 34 4.99998 d 332 34 4.99999 d 333 34 4.99999 d 334 34 4.99999 d 335 34 4.99999 d 336 34 5.0 d 337 34 5.0 d 338 34 5.0 d 339 34 5.0 d 340 34 5.00001 d 341 34 5.00001 d 342 34 5.00001 d 343 34 5.00001 d 344 34 5.00001 d 345 34 5.00001 d 346 34 5.00001 d 347 34 5.00001 d 348 34 5.00001 d 349 34 5.0 d 350 34 5.0 d 351 34 5.0 d 352 34 5.0 d 353 34 5.0 d 354 34 5.0 d 355 34 5.0 d 356 34 4.99999 d 357 34 4.99999 d 358 34 4.99999 d 359 34 4.99999 d 360 34 4.99998 d 361 34 4.99998 d 1 35 5.0 d 2 35 5.00207 d 3 35 5.00813 d 4 35 5.01486 d 5 35 5.00156 d 6 35 5.0018 d 7 35 4.99861 d 8 35 4.99844 d 9 35 4.99888 d 10 35 4.9993 d 11 35 4.99956 d 12 35 4.99971 d 13 35 4.99979 d 14 35 4.99983 d 15 35 4.99987 d 16 35 4.99989 d 17 35 4.99671 d 18 35 4.9974 d 19 35 4.99864 d 20 35 5.00131 d 21 35 5.00377 d 22 35 5.0021 d 23 35 5.00039 d 24 35 4.99993 d 25 35 5.00004 d 26 35 5.0009 d 27 35 5.00109 d 28 35 4.99636 d 29 35 4.98617 d 30 35 4.96778 d 31 35 4.92047 d 32 35 4.89528 d 33 35 4.91112 d 34 35 4.9559 d 35 35 4.98286 d 36 35 4.99369 d 37 35 4.99812 d 38 35 4.99951 d 39 35 4.99994 d 40 35 5.00014 d 41 35 5.00008 d 42 35 4.99994 d 43 35 4.99984 d 44 35 4.99989 d 45 35 4.99998 d 46 35 5.00004 d 47 35 5.00004 d 48 35 5.00006 d 49 35 5.00005 d 50 35 5.00001 d 51 35 4.99997 d 52 35 4.99992 d 53 35 4.99993 d 54 35 4.99994 d 55 35 4.99996 d 56 35 4.99996 d 57 35 4.99996 d 58 35 4.99996 d 59 35 4.99996 d 60 35 4.99996 d 61 35 4.99996 d 62 35 4.99996 d 63 35 4.99996 d 64 35 4.99996 d 65 35 4.99996 d 66 35 4.99996 d 67 35 4.99996 d 68 35 4.99996 d 69 35 4.99997 d 70 35 4.99997 d 71 35 4.99997 d 72 35 4.99997 d 73 35 4.99997 d 74 35 4.99997 d 75 35 4.99997 d 76 35 4.99997 d 77 35 4.99997 d 78 35 4.99997 d 79 35 4.99997 d 80 35 4.99997 d 81 35 4.99997 d 82 35 4.99997 d 83 35 4.99997 d 84 35 4.99997 d 85 35 4.99997 d 86 35 4.99997 d 87 35 4.99997 d 88 35 4.99997 d 89 35 4.99997 d 90 35 4.99998 d 91 35 4.99998 d 92 35 4.99998 d 93 35 4.99998 d 94 35 4.99998 d 95 35 4.99998 d 96 35 4.99998 d 97 35 4.99998 d 98 35 4.99998 d 99 35 4.99998 d 100 35 4.99998 d 101 35 4.99998 d 102 35 4.99998 d 103 35 4.99998 d 104 35 4.99998 d 105 35 4.99998 d 106 35 4.99998 d 107 35 4.99998 d 108 35 4.99998 d 109 35 4.99998 d 110 35 4.99998 d 111 35 4.99998 d 112 35 4.99998 d 113 35 4.99998 d 114 35 4.99998 d 115 35 4.99998 d 116 35 4.99998 d 117 35 4.99998 d 118 35 4.99998 d 119 35 4.99998 d 120 35 4.99998 d 121 35 4.99998 d 122 35 5.00131 d 123 35 5.00072 d 124 35 4.9977 d 125 35 4.99811 d 126 35 5.00325 d 127 35 4.99647 d 128 35 4.98948 d 129 35 4.99459 d 130 35 5.00262 d 131 35 5.00276 d 132 35 5.00156 d 133 35 5.00072 d 134 35 5.0003 d 135 35 5.00013 d 136 35 4.99995 d 137 35 4.99668 d 138 35 4.99775 d 139 35 4.99917 d 140 35 5.00173 d 141 35 5.00386 d 142 35 5.00188 d 143 35 4.99888 d 144 35 4.99757 d 145 35 4.99951 d 146 35 5.01712 d 147 35 5.0557 d 148 35 5.07088 d 149 35 5.07704 d 150 35 5.07758 d 151 35 5.06958 d 152 35 5.04223 d 153 35 5.03331 d 154 35 5.0279 d 155 35 5.03408 d 156 35 5.07611 d 157 35 5.01911 d 158 35 4.68594 d 159 35 3.99152 d 160 35 2.92195 d 161 35 1.69878 d 162 35 0.809 d 163 35 0.344091 d 164 35 0.154663 d 165 35 0.0788717 d 166 35 0.0467212 d 167 35 0.0336168 d 168 35 0.0280514 d 169 35 0.0254947 d 170 35 0.024173 d 171 35 0.0223567 d 172 35 0.0220555 d 173 35 0.0271514 d 174 35 0.0295872 d 175 35 0.0296052 d 176 35 0.0283971 d 177 35 0.0264726 d 178 35 0.0241813 d 179 35 0.0218244 d 180 35 0.0195349 d 181 35 0.017368 d 182 35 0.0152495 d 183 35 0.013295 d 184 35 0.0115444 d 185 35 0.00996982 d 186 35 0.00857091 d 187 35 0.00733891 d 188 35 0.00627261 d 189 35 0.0053494 d 190 35 0.00456316 d 191 35 0.00388373 d 192 35 0.00331073 d 193 35 0.00282181 d 194 35 0.00240991 d 195 35 0.00206389 d 196 35 0.00177187 d 197 35 0.00152283 d 198 35 0.00131167 d 199 35 0.00112558 d 200 35 0.000954373 d 201 35 0.000805726 d 202 35 0.00069326 d 203 35 0.000600991 d 204 35 0.000525743 d 205 35 0.00047355 d 206 35 0.00044359 d 207 35 0.000434815 d 208 35 0.000436053 d 209 35 0.000402511 d 210 35 0.000368969 d 211 35 0.000335427 d 212 35 0.000301886 d 213 35 0.000268344 d 214 35 0.000234802 d 215 35 0.00020126 d 216 35 0.000184967 d 217 35 0.000169932 d 218 35 0.000154896 d 219 35 0.000139861 d 220 35 0.000124825 d 221 35 0.00010979 d 222 35 9.47546e-05 d 223 35 8.67896e-05 d 224 35 8.24901e-05 d 225 35 7.81906e-05 d 226 35 7.38911e-05 d 227 35 6.95915e-05 d 228 35 6.5292e-05 d 229 35 6.09925e-05 d 230 35 5.66929e-05 d 231 35 5.23934e-05 d 232 35 4.80939e-05 d 233 35 4.37943e-05 d 234 35 3.94948e-05 d 235 35 3.51953e-05 d 236 35 3.08957e-05 d 237 35 2.67968e-05 d 238 35 2.42936e-05 d 239 35 2.17904e-05 d 240 35 1.92872e-05 d 241 35 1.6784e-05 d 242 35 0.00125927 d 243 35 -0.00794344 d 244 35 -0.0305499 d 245 35 -0.0621697 d 246 35 -0.0463796 d 247 35 -0.0224608 d 248 35 -0.00538381 d 249 35 0.00546086 d 250 35 0.0108675 d 251 35 0.012883 d 252 35 0.0131787 d 253 35 0.0127271 d 254 35 0.0119702 d 255 35 0.0110398 d 256 35 0.0100635 d 257 35 0.00649617 d 258 35 0.00489388 d 259 35 0.00545863 d 260 35 0.0098351 d 261 35 0.0167428 d 262 35 0.0126563 d 263 35 0.00697542 d 264 35 0.00427027 d 265 35 0.00330002 d 266 35 0.00390774 d 267 35 0.00408999 d 268 35 -0.00259143 d 269 35 -0.0160578 d 270 35 -0.0451849 d 271 35 -0.0409651 d 272 35 0.1301 d 273 35 0.597429 d 274 35 1.3848 d 275 35 2.63426 d 276 35 3.81272 d 277 35 4.51373 d 278 35 4.8412 d 279 35 4.98731 d 280 35 4.88165 d 281 35 4.37165 d 282 35 3.40034 d 283 35 2.17681 d 284 35 1.12217 d 285 35 0.505129 d 286 35 0.219703 d 287 35 0.104992 d 288 35 0.0622333 d 289 35 0.0448317 d 290 35 0.0355782 d 291 35 0.0311867 d 292 35 0.0293529 d 293 35 0.0274615 d 294 35 0.0288739 d 295 35 0.0307845 d 296 35 0.0304909 d 297 35 0.029245 d 298 35 0.0273602 d 299 35 0.0251006 d 300 35 0.022697 d 301 35 0.0202765 d 302 35 0.0179357 d 303 35 0.0157106 d 304 35 0.0136562 d 305 35 0.0117951 d 306 35 0.0101273 d 307 35 0.00865784 d 308 35 0.00739394 d 309 35 0.00634364 d 310 35 0.00551356 d 311 35 0.00480538 d 312 35 0.00415747 d 313 35 0.00356084 d 314 35 0.00297585 d 315 35 0.00236711 d 316 35 0.00181853 d 317 35 0.00160713 d 318 35 0.00169822 d 319 35 0.00166542 d 320 35 0.00145504 d 321 35 0.00120252 d 322 35 0.00109259 d 323 35 0.000982658 d 324 35 0.00087273 d 325 35 0.000762802 d 326 35 0.000652874 d 327 35 0.000584068 d 328 35 0.000528263 d 329 35 0.000472458 d 330 35 0.000416653 d 331 35 0.000360848 d 332 35 0.000321155 d 333 35 0.000301442 d 334 35 0.000281729 d 335 35 0.000262016 d 336 35 0.000242303 d 337 35 0.00022259 d 338 35 0.000202877 d 339 35 0.000183164 d 340 35 0.000163451 d 341 35 0.000143738 d 342 35 0.000124025 d 343 35 0.000114582 d 344 35 0.000107399 d 345 35 0.000100216 d 346 35 9.30332e-05 d 347 35 8.58502e-05 d 348 35 7.86672e-05 d 349 35 7.14841e-05 d 350 35 6.43011e-05 d 351 35 5.7118e-05 d 352 35 4.9935e-05 d 353 35 4.35378e-05 d 354 35 4.04281e-05 d 355 35 3.73184e-05 d 356 35 3.42088e-05 d 357 35 3.10991e-05 d 358 35 2.79894e-05 d 359 35 2.48798e-05 d 360 35 2.17701e-05 d 361 35 1.86604e-05 d 1 36 7.24585e-12 d 2 36 2.21843e-05 d 3 36 3.20014e-05 d 4 36 1.25076e-05 d 5 36 -2.44947e-05 d 6 36 1.8425e-05 d 7 36 5.50546e-06 d 8 36 3.53025e-05 d 9 36 -1.07551e-05 d 10 36 -3.94383e-06 d 11 36 -2.27848e-06 d 12 36 -9.04789e-05 d 13 36 7.44215e-05 d 14 36 -2.7662e-05 d 15 36 0.000200038 d 16 36 -2.11998e-05 d 17 36 -2.09011e-05 d 18 36 2.37098e-05 d 19 36 2.18751e-05 d 20 36 -2.28422e-05 d 21 36 -6.23659e-05 d 22 36 3.58241e-05 d 23 36 1.76386e-05 d 24 36 -4.28311e-05 d 25 36 0.000355626 d 26 36 0.00156903 d 27 36 0.00100999 d 28 36 -0.0085304 d 29 36 -0.02067 d 30 36 -0.0389485 d 31 36 -0.0651568 d 32 36 -0.128475 d 33 36 -0.314362 d 34 36 -0.406837 d 35 36 -0.421558 d 36 36 -0.421277 d 37 36 -0.418176 d 38 36 -0.414481 d 39 36 -0.410845 d 40 36 -0.407348 d 41 36 -0.403971 d 42 36 -0.400716 d 43 36 -0.397582 d 44 36 -0.394563 d 45 36 -0.391658 d 46 36 -0.388866 d 47 36 -0.386178 d 48 36 -0.383585 d 49 36 -0.381094 d 50 36 -0.378789 d 51 36 -0.376569 d 52 36 -0.37435 d 53 36 -0.372256 d 54 36 -0.370188 d 55 36 -0.36815 d 56 36 -0.366422 d 57 36 -0.364694 d 58 36 -0.362967 d 59 36 -0.361239 d 60 36 -0.359511 d 61 36 -0.357888 d 62 36 -0.356334 d 63 36 -0.354781 d 64 36 -0.353227 d 65 36 -0.351674 d 66 36 -0.350152 d 67 36 -0.348888 d 68 36 -0.347625 d 69 36 -0.346361 d 70 36 -0.345098 d 71 36 -0.343834 d 72 36 -0.342571 d 73 36 -0.341307 d 74 36 -0.340044 d 75 36 -0.33878 d 76 36 -0.337517 d 77 36 -0.336279 d 78 36 -0.335215 d 79 36 -0.334152 d 80 36 -0.333088 d 81 36 -0.332024 d 82 36 -0.330961 d 83 36 -0.329897 d 84 36 -0.328833 d 85 36 -0.32777 d 86 36 -0.326706 d 87 36 -0.325642 d 88 36 -0.324601 d 89 36 -0.323683 d 90 36 -0.322766 d 91 36 -0.321849 d 92 36 -0.320932 d 93 36 -0.320014 d 94 36 -0.319097 d 95 36 -0.31818 d 96 36 -0.317263 d 97 36 -0.316345 d 98 36 -0.315428 d 99 36 -0.314545 d 100 36 -0.313825 d 101 36 -0.313106 d 102 36 -0.312387 d 103 36 -0.311667 d 104 36 -0.310948 d 105 36 -0.310228 d 106 36 -0.309509 d 107 36 -0.308789 d 108 36 -0.30807 d 109 36 -0.307351 d 110 36 -0.306631 d 111 36 -0.305912 d 112 36 -0.305192 d 113 36 -0.304473 d 114 36 -0.303754 d 115 36 -0.303034 d 116 36 -0.302315 d 117 36 -0.301595 d 118 36 -0.300876 d 119 36 -0.300157 d 120 36 -0.299437 d 121 36 -0.298716 d 122 36 -0.29798 d 123 36 -0.297329 d 124 36 -0.296691 d 125 36 -0.295837 d 126 36 -0.29516 d 127 36 -0.294725 d 128 36 -0.294044 d 129 36 -0.292917 d 130 36 -0.292351 d 131 36 -0.291965 d 132 36 -0.291365 d 133 36 -0.290687 d 134 36 -0.290027 d 135 36 -0.289376 d 136 36 -0.288772 d 137 36 -0.288193 d 138 36 -0.287505 d 139 36 -0.286892 d 140 36 -0.28626 d 141 36 -0.285714 d 142 36 -0.284545 d 143 36 -0.289246 d 144 36 -0.298717 d 145 36 -0.298492 d 146 36 -0.214163 d 147 36 0.181451 d 148 36 0.0749974 d 149 36 0.0454707 d 150 36 0.0292987 d 151 36 0.0196837 d 152 36 0.0124119 d 153 36 0.00884715 d 154 36 0.00527181 d 155 36 0.00585821 d 156 36 0.0296361 d 157 36 0.169856 d 158 36 0.361207 d 159 36 0.538856 d 160 36 0.67469 d 161 36 0.685933 d 162 36 0.392802 d 163 36 0.17772 d 164 36 0.0813085 d 165 36 0.0424601 d 166 36 0.0246654 d 167 36 0.0175258 d 168 36 0.0144256 d 169 36 0.0129859 d 170 36 0.012205 d 171 36 0.0112846 d 172 36 0.010933 d 173 36 0.0134813 d 174 36 0.0147254 d 175 36 0.0147981 d 176 36 0.0142156 d 177 36 0.0132732 d 178 36 0.0121355 d 179 36 0.0109587 d 180 36 0.00981238 d 181 36 0.00872731 d 182 36 0.00767007 d 183 36 0.00669346 d 184 36 0.00581341 d 185 36 0.00502167 d 186 36 0.00431819 d 187 36 0.00369842 d 188 36 0.00316168 d 189 36 0.00269663 d 190 36 0.00230035 d 191 36 0.00195801 d 192 36 0.00166928 d 193 36 0.00142286 d 194 36 0.00121522 d 195 36 0.00104072 d 196 36 0.000893384 d 197 36 0.000767675 d 198 36 0.000661268 d 199 36 0.000567659 d 200 36 0.000481766 d 201 36 0.000407101 d 202 36 0.000350044 d 203 36 0.000302721 d 204 36 0.000263424 d 205 36 0.000236813 d 206 36 0.00022199 d 207 36 0.000218182 d 208 36 0.000219548 d 209 36 0.0002027 d 210 36 0.000185853 d 211 36 0.000169006 d 212 36 0.000152158 d 213 36 0.000135311 d 214 36 0.000118463 d 215 36 0.000101616 d 216 36 9.33782e-05 d 217 36 8.57685e-05 d 218 36 7.81588e-05 d 219 36 7.0549e-05 d 220 36 6.29393e-05 d 221 36 5.53296e-05 d 222 36 4.77199e-05 d 223 36 4.36954e-05 d 224 36 4.15296e-05 d 225 36 3.93637e-05 d 226 36 3.71978e-05 d 227 36 3.50319e-05 d 228 36 3.28661e-05 d 229 36 3.07002e-05 d 230 36 2.85343e-05 d 231 36 2.63685e-05 d 232 36 2.42026e-05 d 233 36 2.20367e-05 d 234 36 1.98709e-05 d 235 36 1.7705e-05 d 236 36 1.55391e-05 d 237 36 1.34772e-05 d 238 36 1.22416e-05 d 239 36 1.10061e-05 d 240 36 9.77055e-06 d 241 36 8.535e-06 d 242 36 0.000631271 d 243 36 -0.00362586 d 244 36 -0.0146235 d 245 36 -0.0308486 d 246 36 -0.0237466 d 247 36 -0.0117522 d 248 36 -0.00304171 d 249 36 0.00251033 d 250 36 0.00531986 d 251 36 0.0063897 d 252 36 0.00657351 d 253 36 0.00636494 d 254 36 0.00599705 d 255 36 0.00553442 d 256 36 0.00505994 d 257 36 0.00330925 d 258 36 0.00246671 d 259 36 0.0027006 d 260 36 0.00473161 d 261 36 0.00830333 d 262 36 0.00649147 d 263 36 0.00356815 d 264 36 0.00217448 d 265 36 0.00187579 d 266 36 0.00270447 d 267 36 0.00219543 d 268 36 -0.00546118 d 269 36 -0.0179576 d 270 36 -0.0445306 d 271 36 -0.0649309 d 272 36 0.0197935 d 273 36 0.473629 d 274 36 0.87268 d 275 36 0.269542 d 276 36 0.0086094 d 277 36 0.0844602 d 278 36 0.606456 d 279 36 1.04929 d 280 36 0.906014 d 281 36 0.916205 d 282 36 0.919425 d 283 36 0.872867 d 284 36 0.556244 d 285 36 0.262457 d 286 36 0.11838 d 287 36 0.0571226 d 288 36 0.0333451 d 289 36 0.0237133 d 290 36 0.0185096 d 291 36 0.0159617 d 292 36 0.0148663 d 293 36 0.0138683 d 294 36 0.0144081 d 295 36 0.0153797 d 296 36 0.0152551 d 297 36 0.0146487 d 298 36 0.0137192 d 299 36 0.0125973 d 300 36 0.0113996 d 301 36 0.0101903 d 302 36 0.00901851 d 303 36 0.00790495 d 304 36 0.00687502 d 305 36 0.00593994 d 306 36 0.00510092 d 307 36 0.00436111 d 308 36 0.00372439 d 309 36 0.0031945 d 310 36 0.00277537 d 311 36 0.00241888 d 312 36 0.002095 d 313 36 0.00179943 d 314 36 0.00150419 d 315 36 0.00119264 d 316 36 0.00090934 d 317 36 0.000802394 d 318 36 0.000852816 d 319 36 0.000838368 d 320 36 0.000730842 d 321 36 0.000601028 d 322 36 0.000546616 d 323 36 0.000492205 d 324 36 0.000437793 d 325 36 0.000383381 d 326 36 0.000328969 d 327 36 0.00029454 d 328 36 0.000266428 d 329 36 0.000238317 d 330 36 0.000210205 d 331 36 0.000182093 d 332 36 0.000162091 d 333 36 0.000152145 d 334 36 0.000142198 d 335 36 0.000132252 d 336 36 0.000122306 d 337 36 0.000112359 d 338 36 0.000102413 d 339 36 9.24665e-05 d 340 36 8.25201e-05 d 341 36 7.25738e-05 d 342 36 6.26274e-05 d 343 36 5.78553e-05 d 344 36 5.42216e-05 d 345 36 5.05878e-05 d 346 36 4.69541e-05 d 347 36 4.33204e-05 d 348 36 3.96867e-05 d 349 36 3.60529e-05 d 350 36 3.24192e-05 d 351 36 2.87855e-05 d 352 36 2.51518e-05 d 353 36 2.19153e-05 d 354 36 2.03406e-05 d 355 36 1.8766e-05 d 356 36 1.71913e-05 d 357 36 1.56167e-05 d 358 36 1.4042e-05 d 359 36 1.24674e-05 d 360 36 1.08927e-05 d 361 36 9.31806e-06 d 1 37 5.0 d 2 37 5.01426 d 3 37 5.02852 d 4 37 5.01923 d 5 37 4.77685 d 6 37 4.56471 d 7 37 4.52338 d 8 37 4.56813 d 9 37 4.63122 d 10 37 4.693 d 11 37 4.74776 d 12 37 4.79385 d 13 37 4.83258 d 14 37 4.86358 d 15 37 4.88918 d 16 37 4.91021 d 17 37 4.90553 d 18 37 4.89733 d 19 37 4.89554 d 20 37 4.91953 d 21 37 5.00757 d 22 37 5.07101 d 23 37 5.06318 d 24 37 5.05241 d 25 37 5.05535 d 26 37 5.08042 d 27 37 5.07251 d 28 37 4.90973 d 29 37 4.56136 d 30 37 3.98637 d 31 37 3.237 d 32 37 2.67216 d 33 37 2.33678 d 34 37 2.13529 d 35 37 2.00544 d 36 37 1.91429 d 37 37 1.84638 d 38 37 1.79461 d 39 37 1.75338 d 40 37 1.71958 d 41 37 1.69175 d 42 37 1.6686 d 43 37 1.64918 d 44 37 1.63258 d 45 37 1.61836 d 46 37 1.60607 d 47 37 1.59506 d 48 37 1.58483 d 49 37 1.57575 d 50 37 1.56847 d 51 37 1.56193 d 52 37 1.55538 d 53 37 1.54968 d 54 37 1.54416 d 55 37 1.5388 d 56 37 1.53523 d 57 37 1.53165 d 58 37 1.52807 d 59 37 1.52449 d 60 37 1.52091 d 61 37 1.51771 d 62 37 1.51477 d 63 37 1.51182 d 64 37 1.50888 d 65 37 1.50593 d 66 37 1.50309 d 67 37 1.50113 d 68 37 1.49917 d 69 37 1.4972 d 70 37 1.49524 d 71 37 1.49328 d 72 37 1.49132 d 73 37 1.48935 d 74 37 1.48739 d 75 37 1.48543 d 76 37 1.48346 d 77 37 1.48157 d 78 37 1.48012 d 79 37 1.47868 d 80 37 1.47724 d 81 37 1.47579 d 82 37 1.47435 d 83 37 1.47291 d 84 37 1.47146 d 85 37 1.47002 d 86 37 1.46857 d 87 37 1.46713 d 88 37 1.46574 d 89 37 1.46462 d 90 37 1.4635 d 91 37 1.46238 d 92 37 1.46126 d 93 37 1.46014 d 94 37 1.45902 d 95 37 1.4579 d 96 37 1.45678 d 97 37 1.45567 d 98 37 1.45455 d 99 37 1.45349 d 100 37 1.45275 d 101 37 1.45201 d 102 37 1.45127 d 103 37 1.45053 d 104 37 1.44979 d 105 37 1.44905 d 106 37 1.44831 d 107 37 1.44757 d 108 37 1.44683 d 109 37 1.44609 d 110 37 1.44535 d 111 37 1.44461 d 112 37 1.44387 d 113 37 1.44313 d 114 37 1.44239 d 115 37 1.44165 d 116 37 1.44091 d 117 37 1.44017 d 118 37 1.43943 d 119 37 1.43869 d 120 37 1.43795 d 121 37 1.43721 d 122 37 1.43874 d 123 37 1.43976 d 124 37 1.43619 d 125 37 1.43182 d 126 37 1.43726 d 127 37 1.43084 d 128 37 1.42587 d 129 37 1.42383 d 130 37 1.42642 d 131 37 1.42728 d 132 37 1.42736 d 133 37 1.4271 d 134 37 1.42669 d 135 37 1.42621 d 136 37 1.42569 d 137 37 1.41703 d 138 37 1.41244 d 139 37 1.41019 d 140 37 1.41199 d 141 37 1.41833 d 142 37 1.42502 d 143 37 1.41504 d 144 37 1.37535 d 145 37 1.28381 d 146 37 1.44779 d 147 37 2.33713 d 148 37 3.25835 d 149 37 3.67554 d 150 37 3.84975 d 151 37 4.01125 d 152 37 4.2253 d 153 37 4.45433 d 154 37 4.62215 d 155 37 4.74478 d 156 37 4.82998 d 157 37 4.8868 d 158 37 4.92396 d 159 37 4.94768 d 160 37 4.96498 d 161 37 4.98537 d 162 37 5.0128 d 163 37 5.04467 d 164 37 5.06722 d 165 37 5.06535 d 166 37 5.01475 d 167 37 4.91956 d 168 37 4.80647 d 169 37 4.7242 d 170 37 4.7059 d 171 37 4.73552 d 172 37 4.76379 d 173 37 4.81684 d 174 37 4.87376 d 175 37 4.92276 d 176 37 4.96112 d 177 37 4.9884 d 178 37 5.0045 d 179 37 5.00999 d 180 37 5.00933 d 181 37 5.00619 d 182 37 5.00384 d 183 37 5.00342 d 184 37 5.00373 d 185 37 5.00362 d 186 37 5.00309 d 187 37 5.00272 d 188 37 5.00239 d 189 37 5.00204 d 190 37 5.00172 d 191 37 5.00146 d 192 37 5.00124 d 193 37 5.00105 d 194 37 5.00089 d 195 37 5.00076 d 196 37 5.00065 d 197 37 5.00057 d 198 37 5.00048 d 199 37 5.00041 d 200 37 5.00034 d 201 37 5.00028 d 202 37 5.00023 d 203 37 5.00019 d 204 37 5.00015 d 205 37 5.00015 d 206 37 5.00016 d 207 37 5.0002 d 208 37 5.00023 d 209 37 5.00021 d 210 37 5.00019 d 211 37 5.00017 d 212 37 5.00015 d 213 37 5.00012 d 214 37 5.0001 d 215 37 5.00008 d 216 37 5.00007 d 217 37 5.00006 d 218 37 5.00005 d 219 37 5.00004 d 220 37 5.00003 d 221 37 5.00002 d 222 37 5.00001 d 223 37 5.00001 d 224 37 5.00001 d 225 37 5.00001 d 226 37 5.00001 d 227 37 5.00001 d 228 37 5.00001 d 229 37 5.00002 d 230 37 5.00002 d 231 37 5.00002 d 232 37 5.00002 d 233 37 5.00002 d 234 37 5.00002 d 235 37 5.00002 d 236 37 5.00002 d 237 37 5.00002 d 238 37 5.00002 d 239 37 5.00001 d 240 37 5.00001 d 241 37 5.00001 d 242 37 5.00062 d 243 37 4.99506 d 244 37 4.9835 d 245 37 4.96726 d 246 37 4.9728 d 247 37 4.97877 d 248 37 4.98675 d 249 37 4.9966 d 250 37 5.00406 d 251 37 5.00679 d 252 37 5.00629 d 253 37 5.00561 d 254 37 5.00487 d 255 37 5.00429 d 256 37 5.00384 d 257 37 5.002 d 258 37 5.00164 d 259 37 5.00229 d 260 37 5.00484 d 261 37 5.00769 d 262 37 5.00019 d 263 37 5.00242 d 264 37 5.01319 d 265 37 5.0335 d 266 37 5.07265 d 267 37 5.10129 d 268 37 5.11485 d 269 37 5.12551 d 270 37 5.13953 d 271 37 5.16048 d 272 37 5.18862 d 273 37 5.22811 d 274 37 5.25656 d 275 37 5.25627 d 276 37 5.19975 d 277 37 4.9139 d 278 37 4.24745 d 279 37 3.43732 d 280 37 2.8202 d 281 37 2.43224 d 282 37 2.17409 d 283 37 2.01333 d 284 37 1.93951 d 285 37 1.94622 d 286 37 1.98861 d 287 37 2.02217 d 288 37 2.05383 d 289 37 2.08376 d 290 37 2.11184 d 291 37 2.13793 d 292 37 2.16191 d 293 37 2.18267 d 294 37 2.20502 d 295 37 2.22837 d 296 37 2.24958 d 297 37 2.26901 d 298 37 2.28648 d 299 37 2.302 d 300 37 2.31582 d 301 37 2.32802 d 302 37 2.33869 d 303 37 2.34795 d 304 37 2.35596 d 305 37 2.36282 d 306 37 2.3687 d 307 37 2.37371 d 308 37 2.37797 d 309 37 2.38161 d 310 37 2.38476 d 311 37 2.38743 d 312 37 2.3897 d 313 37 2.39168 d 314 37 2.39329 d 315 37 2.39463 d 316 37 2.39575 d 317 37 2.39671 d 318 37 2.39756 d 319 37 2.39835 d 320 37 2.39907 d 321 37 2.39968 d 322 37 2.39999 d 323 37 2.4003 d 324 37 2.40061 d 325 37 2.40091 d 326 37 2.40122 d 327 37 2.40142 d 328 37 2.40159 d 329 37 2.40176 d 330 37 2.40193 d 331 37 2.4021 d 332 37 2.40222 d 333 37 2.40228 d 334 37 2.40234 d 335 37 2.4024 d 336 37 2.40247 d 337 37 2.40253 d 338 37 2.40259 d 339 37 2.40265 d 340 37 2.40271 d 341 37 2.40277 d 342 37 2.40284 d 343 37 2.40287 d 344 37 2.40289 d 345 37 2.40291 d 346 37 2.40294 d 347 37 2.40296 d 348 37 2.40298 d 349 37 2.40301 d 350 37 2.40303 d 351 37 2.40305 d 352 37 2.40308 d 353 37 2.4031 d 354 37 2.40311 d 355 37 2.40312 d 356 37 2.40313 d 357 37 2.40314 d 358 37 2.40315 d 359 37 2.40316 d 360 37 2.40317 d 361 37 2.40318 d 1 38 5.0 d 2 38 5.01732 d 3 38 5.03181 d 4 38 5.05944 d 5 38 5.12686 d 6 38 5.20725 d 7 38 5.28103 d 8 38 5.31254 d 9 38 5.32901 d 10 38 5.33709 d 11 38 5.3408 d 12 38 5.34257 d 13 38 5.34311 d 14 38 5.34347 d 15 38 5.34386 d 16 38 5.34411 d 17 38 5.3406 d 18 38 5.33484 d 19 38 5.32942 d 20 38 5.32904 d 21 38 5.33644 d 22 38 5.34869 d 23 38 5.35001 d 24 38 5.34882 d 25 38 5.34758 d 26 38 5.34672 d 27 38 5.34599 d 28 38 5.34496 d 29 38 5.34364 d 30 38 5.34165 d 31 38 5.33712 d 32 38 5.33502 d 33 38 5.3366 d 34 38 5.34067 d 35 38 5.34306 d 36 38 5.34398 d 37 38 5.34434 d 38 38 5.34442 d 39 38 5.34443 d 40 38 5.34443 d 41 38 5.34441 d 42 38 5.34439 d 43 38 5.34437 d 44 38 5.34437 d 45 38 5.34438 d 46 38 5.34438 d 47 38 5.34438 d 48 38 5.34438 d 49 38 5.34438 d 50 38 5.34437 d 51 38 5.34437 d 52 38 5.34436 d 53 38 5.34436 d 54 38 5.34437 d 55 38 5.34437 d 56 38 5.34437 d 57 38 5.34437 d 58 38 5.34437 d 59 38 5.34437 d 60 38 5.34437 d 61 38 5.34437 d 62 38 5.34437 d 63 38 5.34437 d 64 38 5.34437 d 65 38 5.34437 d 66 38 5.34437 d 67 38 5.34437 d 68 38 5.34437 d 69 38 5.34437 d 70 38 5.34437 d 71 38 5.34437 d 72 38 5.34437 d 73 38 5.34437 d 74 38 5.34437 d 75 38 5.34437 d 76 38 5.34437 d 77 38 5.34437 d 78 38 5.34437 d 79 38 5.34437 d 80 38 5.34437 d 81 38 5.34437 d 82 38 5.34437 d 83 38 5.34437 d 84 38 5.34437 d 85 38 5.34437 d 86 38 5.34437 d 87 38 5.34437 d 88 38 5.34437 d 89 38 5.34437 d 90 38 5.34437 d 91 38 5.34437 d 92 38 5.34437 d 93 38 5.34437 d 94 38 5.34437 d 95 38 5.34437 d 96 38 5.34437 d 97 38 5.34437 d 98 38 5.34437 d 99 38 5.34437 d 100 38 5.34437 d 101 38 5.34437 d 102 38 5.34437 d 103 38 5.34437 d 104 38 5.34437 d 105 38 5.34437 d 106 38 5.34437 d 107 38 5.34437 d 108 38 5.34437 d 109 38 5.34437 d 110 38 5.34437 d 111 38 5.34437 d 112 38 5.34437 d 113 38 5.34437 d 114 38 5.34437 d 115 38 5.34437 d 116 38 5.34437 d 117 38 5.34437 d 118 38 5.34437 d 119 38 5.34437 d 120 38 5.34437 d 121 38 5.34437 d 122 38 5.35377 d 123 38 5.35451 d 124 38 5.34265 d 125 38 5.34488 d 126 38 5.35861 d 127 38 5.28622 d 128 38 4.90033 d 129 38 4.75027 d 130 38 4.89731 d 131 38 4.97098 d 132 38 4.99293 d 133 38 4.99832 d 134 38 4.99909 d 135 38 4.99956 d 136 38 4.99858 d 137 38 4.99829 d 138 38 4.9998 d 139 38 5.00035 d 140 38 5.0038 d 141 38 5.00989 d 142 38 5.00251 d 143 38 4.99438 d 144 38 4.9953 d 145 38 4.99761 d 146 38 4.99985 d 147 38 5.00152 d 148 38 5.0011 d 149 38 5.00046 d 150 38 4.99996 d 151 38 4.99925 d 152 38 4.99862 d 153 38 4.99919 d 154 38 4.99961 d 155 38 5.00048 d 156 38 5.00234 d 157 38 4.99654 d 158 38 4.98235 d 159 38 4.95936 d 160 38 4.83738 d 161 38 4.53021 d 162 38 4.21004 d 163 38 4.00593 d 164 38 3.91207 d 165 38 3.88059 d 166 38 3.87822 d 167 38 3.89117 d 168 38 3.91278 d 169 38 3.94044 d 170 38 3.97376 d 171 38 4.01152 d 172 38 4.05052 d 173 38 4.10679 d 174 38 4.17908 d 175 38 4.25673 d 176 38 4.33414 d 177 38 4.40875 d 178 38 4.47879 d 179 38 4.54342 d 180 38 4.60258 d 181 38 4.65595 d 182 38 4.70291 d 183 38 4.74414 d 184 38 4.78018 d 185 38 4.81185 d 186 38 4.83915 d 187 38 4.86291 d 188 38 4.88301 d 189 38 4.90048 d 190 38 4.91528 d 191 38 4.92802 d 192 38 4.9387 d 193 38 4.94777 d 194 38 4.95539 d 195 38 4.9618 d 196 38 4.96725 d 197 38 4.97195 d 198 38 4.97588 d 199 38 4.97932 d 200 38 4.98247 d 201 38 4.98512 d 202 38 4.98697 d 203 38 4.98831 d 204 38 4.98919 d 205 38 4.99015 d 206 38 4.99101 d 207 38 4.99169 d 208 38 4.99222 d 209 38 4.99282 d 210 38 4.99341 d 211 38 4.994 d 212 38 4.9946 d 213 38 4.99519 d 214 38 4.99578 d 215 38 4.99638 d 216 38 4.99667 d 217 38 4.99693 d 218 38 4.9972 d 219 38 4.99747 d 220 38 4.99773 d 221 38 4.998 d 222 38 4.99827 d 223 38 4.99841 d 224 38 4.99849 d 225 38 4.99856 d 226 38 4.99864 d 227 38 4.99872 d 228 38 4.9988 d 229 38 4.99888 d 230 38 4.99896 d 231 38 4.99904 d 232 38 4.99911 d 233 38 4.99919 d 234 38 4.99927 d 235 38 4.99935 d 236 38 4.99943 d 237 38 4.9995 d 238 38 4.99955 d 239 38 4.9996 d 240 38 4.99965 d 241 38 4.9997 d 242 38 5.00736 d 243 38 4.98252 d 244 38 4.87516 d 245 38 4.66727 d 246 38 4.49142 d 247 38 4.43103 d 248 38 4.4301 d 249 38 4.4571 d 250 38 4.49729 d 251 38 4.5407 d 252 38 4.5835 d 253 38 4.62363 d 254 38 4.66114 d 255 38 4.69577 d 256 38 4.72738 d 257 38 4.74632 d 258 38 4.75971 d 259 38 4.77576 d 260 38 4.80671 d 261 38 4.87073 d 262 38 4.91665 d 263 38 4.93252 d 264 38 4.94418 d 265 38 4.95331 d 266 38 4.96094 d 267 38 4.96727 d 268 38 4.97148 d 269 38 4.97471 d 270 38 4.97612 d 271 38 4.98276 d 272 38 5.00247 d 273 38 5.04086 d 274 38 5.08628 d 275 38 5.10673 d 276 38 5.08887 d 277 38 5.0564 d 278 38 5.02767 d 279 38 5.01336 d 280 38 4.99685 d 281 38 4.97422 d 282 38 4.90866 d 283 38 4.67035 d 284 38 4.33117 d 285 38 4.07888 d 286 38 3.94432 d 287 38 3.89105 d 288 38 3.88174 d 289 38 3.89292 d 290 38 3.91442 d 291 38 3.94564 d 292 38 3.98708 d 293 38 4.0355 d 294 38 4.09134 d 295 38 4.16315 d 296 38 4.24088 d 297 38 4.31918 d 298 38 4.39527 d 299 38 4.46693 d 300 38 4.53337 d 301 38 4.59405 d 302 38 4.6486 d 303 38 4.69693 d 304 38 4.73938 d 305 38 4.77617 d 306 38 4.80809 d 307 38 4.83551 d 308 38 4.85895 d 309 38 4.87894 d 310 38 4.89596 d 311 38 4.91081 d 312 38 4.92417 d 313 38 4.93651 d 314 38 4.94552 d 315 38 4.95198 d 316 38 4.9565 d 317 38 4.96096 d 318 38 4.96523 d 319 38 4.96972 d 320 38 4.97428 d 321 38 4.97868 d 322 38 4.98064 d 323 38 4.9826 d 324 38 4.98455 d 325 38 4.98651 d 326 38 4.98847 d 327 38 4.98967 d 328 38 4.99064 d 329 38 4.9916 d 330 38 4.99257 d 331 38 4.99353 d 332 38 4.99422 d 333 38 4.99457 d 334 38 4.99493 d 335 38 4.99528 d 336 38 4.99563 d 337 38 4.99598 d 338 38 4.99633 d 339 38 4.99668 d 340 38 4.99703 d 341 38 4.99738 d 342 38 4.99773 d 343 38 4.9979 d 344 38 4.99804 d 345 38 4.99817 d 346 38 4.9983 d 347 38 4.99843 d 348 38 4.99856 d 349 38 4.99869 d 350 38 4.99883 d 351 38 4.99896 d 352 38 4.99909 d 353 38 4.99921 d 354 38 4.99926 d 355 38 4.99931 d 356 38 4.99937 d 357 38 4.99942 d 358 38 4.99948 d 359 38 4.99953 d 360 38 4.99959 d 361 38 4.99964 d 1 39 4.49849 d 2 39 4.53282 d 3 39 4.58329 d 4 39 4.66625 d 5 39 4.83345 d 6 39 4.97823 d 7 39 5.0207 d 8 39 5.01816 d 9 39 5.01116 d 10 39 5.00595 d 11 39 5.00296 d 12 39 5.00148 d 13 39 5.00073 d 14 39 5.00062 d 15 39 5.00033 d 16 39 5.0003 d 17 39 4.99864 d 18 39 4.99661 d 19 39 4.99652 d 20 39 4.99928 d 21 39 5.00361 d 22 39 5.12573 d 23 39 5.17251 d 24 39 5.22612 d 25 39 5.33479 d 26 39 5.44503 d 27 39 5.44432 d 28 39 5.44379 d 29 39 5.44334 d 30 39 5.443 d 31 39 5.44276 d 32 39 5.44258 d 33 39 5.44246 d 34 39 5.44238 d 35 39 5.44232 d 36 39 5.44228 d 37 39 5.44225 d 38 39 5.44223 d 39 39 5.44221 d 40 39 5.4422 d 41 39 5.44219 d 42 39 5.44219 d 43 39 5.44218 d 44 39 5.44218 d 45 39 5.44218 d 46 39 5.44218 d 47 39 5.44217 d 48 39 5.44217 d 49 39 5.44217 d 50 39 5.44217 d 51 39 5.44217 d 52 39 5.44217 d 53 39 5.44217 d 54 39 5.44217 d 55 39 5.44217 d 56 39 5.44217 d 57 39 5.44217 d 58 39 5.44217 d 59 39 5.44217 d 60 39 5.44217 d 61 39 5.44217 d 62 39 5.44217 d 63 39 5.44217 d 64 39 5.44217 d 65 39 5.44217 d 66 39 5.44217 d 67 39 5.44216 d 68 39 5.44216 d 69 39 5.44216 d 70 39 5.44216 d 71 39 5.44216 d 72 39 5.44216 d 73 39 5.44216 d 74 39 5.44216 d 75 39 5.44216 d 76 39 5.44216 d 77 39 5.44216 d 78 39 5.44216 d 79 39 5.44216 d 80 39 5.44216 d 81 39 5.44216 d 82 39 5.44216 d 83 39 5.44216 d 84 39 5.44216 d 85 39 5.44216 d 86 39 5.44215 d 87 39 5.44215 d 88 39 5.44215 d 89 39 5.44215 d 90 39 5.44215 d 91 39 5.44215 d 92 39 5.44215 d 93 39 5.44215 d 94 39 5.44215 d 95 39 5.44215 d 96 39 5.44215 d 97 39 5.44215 d 98 39 5.44215 d 99 39 5.44215 d 100 39 5.44215 d 101 39 5.44215 d 102 39 5.44215 d 103 39 5.44215 d 104 39 5.44215 d 105 39 5.44215 d 106 39 5.44215 d 107 39 5.44215 d 108 39 5.44215 d 109 39 5.44215 d 110 39 5.44214 d 111 39 5.44214 d 112 39 5.44214 d 113 39 5.44214 d 114 39 5.44214 d 115 39 5.44214 d 116 39 5.44214 d 117 39 5.44214 d 118 39 5.44214 d 119 39 5.44214 d 120 39 5.44214 d 121 39 5.44212 d 122 39 5.45159 d 123 39 5.45236 d 124 39 5.44064 d 125 39 5.44307 d 126 39 5.45616 d 127 39 5.38122 d 128 39 4.77163 d 129 39 3.53297 d 130 39 2.74466 d 131 39 2.34448 d 132 39 2.11802 d 133 39 1.9783 d 134 39 1.88656 d 135 39 1.82001 d 136 39 1.77389 d 137 39 1.72955 d 138 39 1.69632 d 139 39 1.66971 d 140 39 1.6526 d 141 39 1.65236 d 142 39 1.56034 d 143 39 1.53764 d 144 39 1.97139 d 145 39 2.75096 d 146 39 3.39212 d 147 39 3.74042 d 148 39 3.82345 d 149 39 3.85696 d 150 39 3.88547 d 151 39 3.91862 d 152 39 3.9585 d 153 39 4.00467 d 154 39 4.05903 d 155 39 4.1254 d 156 39 4.19533 d 157 39 4.26791 d 158 39 4.34517 d 159 39 4.42112 d 160 39 4.49238 d 161 39 4.55807 d 162 39 4.6179 d 163 39 4.6713 d 164 39 4.71815 d 165 39 4.75889 d 166 39 4.79418 d 167 39 4.82456 d 168 39 4.85062 d 169 39 4.87291 d 170 39 4.89196 d 171 39 4.90823 d 172 39 4.92209 d 173 39 4.93388 d 174 39 4.9439 d 175 39 4.95242 d 176 39 4.95968 d 177 39 4.96585 d 178 39 4.97108 d 179 39 4.9755 d 180 39 4.97923 d 181 39 4.98237 d 182 39 4.98503 d 183 39 4.98732 d 184 39 4.98927 d 185 39 4.99094 d 186 39 4.99233 d 187 39 4.99353 d 188 39 4.99452 d 189 39 4.99538 d 190 39 4.99608 d 191 39 4.99668 d 192 39 4.99718 d 193 39 4.9976 d 194 39 4.99794 d 195 39 4.99822 d 196 39 4.99847 d 197 39 4.99867 d 198 39 4.99884 d 199 39 4.99899 d 200 39 4.99913 d 201 39 4.99924 d 202 39 4.99932 d 203 39 4.99938 d 204 39 4.99943 d 205 39 4.99947 d 206 39 4.99951 d 207 39 4.99953 d 208 39 4.99955 d 209 39 4.99958 d 210 39 4.99961 d 211 39 4.99964 d 212 39 4.99967 d 213 39 4.99969 d 214 39 4.99972 d 215 39 4.99975 d 216 39 4.99977 d 217 39 4.99978 d 218 39 4.99979 d 219 39 4.99981 d 220 39 4.99982 d 221 39 4.99983 d 222 39 4.99985 d 223 39 4.99986 d 224 39 4.99986 d 225 39 4.99987 d 226 39 4.99987 d 227 39 4.99988 d 228 39 4.99988 d 229 39 4.99988 d 230 39 4.99989 d 231 39 4.99989 d 232 39 4.9999 d 233 39 4.9999 d 234 39 4.99991 d 235 39 4.99991 d 236 39 4.99992 d 237 39 4.99992 d 238 39 4.99993 d 239 39 4.99993 d 240 39 4.99993 d 241 39 4.99994 d 242 39 5.00381 d 243 39 5.00064 d 244 39 4.99246 d 245 39 4.99823 d 246 39 5.00349 d 247 39 5.00076 d 248 39 5.00033 d 249 39 5.00015 d 250 39 5.00009 d 251 39 5.00007 d 252 39 5.00005 d 253 39 5.00004 d 254 39 5.00003 d 255 39 5.00002 d 256 39 4.99988 d 257 39 4.99732 d 258 39 4.99728 d 259 39 4.9978 d 260 39 5.00187 d 261 39 5.00927 d 262 39 5.08712 d 263 39 5.07654 d 264 39 4.92855 d 265 39 4.4863 d 266 39 3.76162 d 267 39 3.00049 d 268 39 2.49834 d 269 39 2.20883 d 270 39 2.03492 d 271 39 1.92384 d 272 39 1.84676 d 273 39 1.79021 d 274 39 1.74716 d 275 39 1.7132 d 276 39 1.68576 d 277 39 1.66309 d 278 39 1.64406 d 279 39 1.62785 d 280 39 1.61383 d 281 39 1.60162 d 282 39 1.59081 d 283 39 1.58117 d 284 39 1.57253 d 285 39 1.56473 d 286 39 1.55765 d 287 39 1.55117 d 288 39 1.54527 d 289 39 1.53988 d 290 39 1.53485 d 291 39 1.53012 d 292 39 1.5257 d 293 39 1.5216 d 294 39 1.51773 d 295 39 1.51411 d 296 39 1.51071 d 297 39 1.50746 d 298 39 1.50438 d 299 39 1.50146 d 300 39 1.49868 d 301 39 1.49603 d 302 39 1.4935 d 303 39 1.49109 d 304 39 1.48878 d 305 39 1.48657 d 306 39 1.48445 d 307 39 1.48242 d 308 39 1.48046 d 309 39 1.47858 d 310 39 1.47677 d 311 39 1.47502 d 312 39 1.47333 d 313 39 1.4717 d 314 39 1.47012 d 315 39 1.46859 d 316 39 1.46711 d 317 39 1.46568 d 318 39 1.46428 d 319 39 1.46292 d 320 39 1.4616 d 321 39 1.46034 d 322 39 1.45923 d 323 39 1.45812 d 324 39 1.45701 d 325 39 1.4559 d 326 39 1.45479 d 327 39 1.45378 d 328 39 1.45279 d 329 39 1.45181 d 330 39 1.45082 d 331 39 1.44983 d 332 39 1.44893 d 333 39 1.44813 d 334 39 1.44732 d 335 39 1.44652 d 336 39 1.44571 d 337 39 1.44491 d 338 39 1.4441 d 339 39 1.4433 d 340 39 1.44249 d 341 39 1.44169 d 342 39 1.44089 d 343 39 1.44019 d 344 39 1.43951 d 345 39 1.43883 d 346 39 1.43815 d 347 39 1.43747 d 348 39 1.4368 d 349 39 1.43612 d 350 39 1.43544 d 351 39 1.43476 d 352 39 1.43408 d 353 39 1.43342 d 354 39 1.43283 d 355 39 1.43223 d 356 39 1.43163 d 357 39 1.43104 d 358 39 1.43044 d 359 39 1.42984 d 360 39 1.42924 d 361 39 1.42865 d 1 40 5.0 d 2 40 5.01048 d 3 40 5.01221 d 4 40 4.98887 d 5 40 4.76261 d 6 40 4.54943 d 7 40 4.51564 d 8 40 4.56249 d 9 40 4.62621 d 10 40 4.68843 d 11 40 4.74374 d 12 40 4.79044 d 13 40 4.82972 d 14 40 4.86127 d 15 40 4.88724 d 16 40 4.90862 d 17 40 4.90791 d 18 40 4.89858 d 19 40 4.89589 d 20 40 4.91767 d 21 40 5.00405 d 22 40 5.16956 d 23 40 5.12391 d 24 40 4.7557 d 25 40 3.87953 d 26 40 3.01124 d 27 40 2.48482 d 28 40 2.20424 d 29 40 2.03812 d 30 40 1.92679 d 31 40 1.84956 d 32 40 1.79256 d 33 40 1.74907 d 34 40 1.71487 d 35 40 1.68724 d 36 40 1.6644 d 37 40 1.64513 d 38 40 1.6287 d 39 40 1.61446 d 40 40 1.60197 d 41 40 1.59095 d 42 40 1.58117 d 43 40 1.57245 d 44 40 1.5646 d 45 40 1.55752 d 46 40 1.55109 d 47 40 1.54516 d 48 40 1.53958 d 49 40 1.53444 d 50 40 1.53008 d 51 40 1.52606 d 52 40 1.52205 d 53 40 1.51843 d 54 40 1.5149 d 55 40 1.51146 d 56 40 1.50893 d 57 40 1.50639 d 58 40 1.50387 d 59 40 1.50133 d 60 40 1.4988 d 61 40 1.49651 d 62 40 1.49436 d 63 40 1.49222 d 64 40 1.49007 d 65 40 1.48793 d 66 40 1.48585 d 67 40 1.48433 d 68 40 1.4828 d 69 40 1.48128 d 70 40 1.47975 d 71 40 1.47823 d 72 40 1.4767 d 73 40 1.47518 d 74 40 1.47365 d 75 40 1.47213 d 76 40 1.4706 d 77 40 1.46912 d 78 40 1.46795 d 79 40 1.46678 d 80 40 1.46561 d 81 40 1.46444 d 82 40 1.46327 d 83 40 1.4621 d 84 40 1.46093 d 85 40 1.45976 d 86 40 1.45859 d 87 40 1.45741 d 88 40 1.45628 d 89 40 1.45534 d 90 40 1.45441 d 91 40 1.45347 d 92 40 1.45254 d 93 40 1.4516 d 94 40 1.45067 d 95 40 1.44973 d 96 40 1.4488 d 97 40 1.44786 d 98 40 1.44693 d 99 40 1.44604 d 100 40 1.44539 d 101 40 1.44475 d 102 40 1.4441 d 103 40 1.44345 d 104 40 1.44281 d 105 40 1.44216 d 106 40 1.44151 d 107 40 1.44086 d 108 40 1.44022 d 109 40 1.43957 d 110 40 1.43892 d 111 40 1.43828 d 112 40 1.43763 d 113 40 1.43698 d 114 40 1.43633 d 115 40 1.43569 d 116 40 1.43504 d 117 40 1.43439 d 118 40 1.43375 d 119 40 1.4331 d 120 40 1.43245 d 121 40 1.4318 d 122 40 1.43157 d 123 40 1.43089 d 124 40 1.43001 d 125 40 1.43042 d 126 40 1.42899 d 127 40 1.42439 d 128 40 1.42216 d 129 40 1.43447 d 130 40 1.44048 d 131 40 1.43705 d 132 40 1.43314 d 133 40 1.43039 d 134 40 1.42861 d 135 40 1.42739 d 136 40 1.42651 d 137 40 1.42548 d 138 40 1.42488 d 139 40 1.4243 d 140 40 1.42392 d 141 40 1.4235 d 142 40 1.32443 d 143 40 1.31149 d 144 40 1.78169 d 145 40 2.64844 d 146 40 3.43211 d 147 40 3.95252 d 148 40 4.20231 d 149 40 4.3746 d 150 40 4.49948 d 151 40 4.58929 d 152 40 4.65742 d 153 40 4.71183 d 154 40 4.77057 d 155 40 4.83196 d 156 40 4.88354 d 157 40 4.92894 d 158 40 4.96625 d 159 40 4.99235 d 160 40 5.00651 d 161 40 5.00941 d 162 40 5.00813 d 163 40 5.00689 d 164 40 5.00588 d 165 40 5.00504 d 166 40 5.00431 d 167 40 5.00368 d 168 40 5.00314 d 169 40 5.00268 d 170 40 5.00228 d 171 40 5.00194 d 172 40 5.00165 d 173 40 5.0014 d 174 40 5.00118 d 175 40 5.001 d 176 40 5.00085 d 177 40 5.00072 d 178 40 5.00061 d 179 40 5.00052 d 180 40 5.00044 d 181 40 5.00037 d 182 40 5.00031 d 183 40 5.00027 d 184 40 5.00022 d 185 40 5.00019 d 186 40 5.00016 d 187 40 5.00013 d 188 40 5.00011 d 189 40 5.00009 d 190 40 5.00008 d 191 40 5.00007 d 192 40 5.00006 d 193 40 5.00005 d 194 40 5.00004 d 195 40 5.00003 d 196 40 5.00003 d 197 40 5.00003 d 198 40 5.00002 d 199 40 5.00002 d 200 40 5.00002 d 201 40 5.00001 d 202 40 5.00001 d 203 40 5.00001 d 204 40 5.00001 d 205 40 5.00001 d 206 40 5.00001 d 207 40 5.00001 d 208 40 5.00001 d 209 40 5.00001 d 210 40 5.00001 d 211 40 5.00001 d 212 40 5.00001 d 213 40 5.0 d 214 40 5.0 d 215 40 5.0 d 216 40 5.0 d 217 40 5.0 d 218 40 4.99999 d 219 40 4.99999 d 220 40 4.99999 d 221 40 4.99998 d 222 40 4.99998 d 223 40 4.99998 d 224 40 4.99998 d 225 40 4.99998 d 226 40 4.99998 d 227 40 4.99998 d 228 40 4.99999 d 229 40 4.99999 d 230 40 4.99999 d 231 40 4.99999 d 232 40 4.99999 d 233 40 4.99999 d 234 40 5.0 d 235 40 5.0 d 236 40 5.0 d 237 40 5.0 d 238 40 5.00001 d 239 40 5.00002 d 240 40 5.00003 d 241 40 5.00004 d 242 40 5.00022 d 243 40 4.99974 d 244 40 4.99942 d 245 40 4.99997 d 246 40 5.00063 d 247 40 5.00002 d 248 40 5.00003 d 249 40 4.99994 d 250 40 4.99998 d 251 40 4.99999 d 252 40 5.0 d 253 40 5.0 d 254 40 5.0 d 255 40 5.0 d 256 40 5.0 d 257 40 4.99981 d 258 40 4.99998 d 259 40 5.00004 d 260 40 5.00036 d 261 40 5.00049 d 262 40 5.12012 d 263 40 5.16315 d 264 40 5.19712 d 265 40 5.21835 d 266 40 4.87874 d 267 40 4.10151 d 268 40 3.31555 d 269 40 2.74207 d 270 40 2.38075 d 271 40 2.15872 d 272 40 2.01614 d 273 40 1.91886 d 274 40 1.84852 d 275 40 1.79401 d 276 40 1.75052 d 277 40 1.71508 d 278 40 1.68672 d 279 40 1.66467 d 280 40 1.64602 d 281 40 1.62985 d 282 40 1.61576 d 283 40 1.60343 d 284 40 1.59256 d 285 40 1.58287 d 286 40 1.57418 d 287 40 1.56632 d 288 40 1.55922 d 289 40 1.55282 d 290 40 1.54687 d 291 40 1.54132 d 292 40 1.53618 d 293 40 1.53143 d 294 40 1.52698 d 295 40 1.52282 d 296 40 1.51895 d 297 40 1.51527 d 298 40 1.5118 d 299 40 1.50851 d 300 40 1.5054 d 301 40 1.50244 d 302 40 1.49963 d 303 40 1.49695 d 304 40 1.4944 d 305 40 1.49196 d 306 40 1.48963 d 307 40 1.4874 d 308 40 1.48527 d 309 40 1.48322 d 310 40 1.48124 d 311 40 1.47934 d 312 40 1.47751 d 313 40 1.47574 d 314 40 1.47403 d 315 40 1.47239 d 316 40 1.4708 d 317 40 1.46926 d 318 40 1.46777 d 319 40 1.46632 d 320 40 1.46491 d 321 40 1.46355 d 322 40 1.46237 d 323 40 1.4612 d 324 40 1.46002 d 325 40 1.45884 d 326 40 1.45766 d 327 40 1.45659 d 328 40 1.45555 d 329 40 1.45451 d 330 40 1.45346 d 331 40 1.45242 d 332 40 1.45147 d 333 40 1.45062 d 334 40 1.44978 d 335 40 1.44894 d 336 40 1.44809 d 337 40 1.44725 d 338 40 1.4464 d 339 40 1.44556 d 340 40 1.44472 d 341 40 1.44387 d 342 40 1.44303 d 343 40 1.4423 d 344 40 1.44159 d 345 40 1.44088 d 346 40 1.44017 d 347 40 1.43947 d 348 40 1.43876 d 349 40 1.43805 d 350 40 1.43734 d 351 40 1.43664 d 352 40 1.43593 d 353 40 1.43524 d 354 40 1.43462 d 355 40 1.434 d 356 40 1.43338 d 357 40 1.43276 d 358 40 1.43213 d 359 40 1.43151 d 360 40 1.43089 d 361 40 1.43027 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/paneset7.tcl����������������������������������������������������������������0000644�0001750�0001750�00000002073�11462120062�015601� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::paneset .ps -bg grey -width 900 -scrollcommand { .s set } blt::graph .ps.g -bg \#CCCCFF -width 600 -height 800 blt::barchart .ps.b -bg \#FFCCCC -width 700 -height 800 blt::barchart .ps.b2 -bg \#CCFFCC -width 500 -height 800 blt::tk::scrollbar .s -command { .ps view } -orient horizontal .ps add -window .ps.g -fill both .ps add -window .ps.b ;#-fill both .ps add -window .ps.b2 -fill both .ps bind Sash <Enter> { .ps sash activate current } .ps bind Sash <Leave> { .ps sash activate none } .ps bind Sash <ButtonPress-1> { %W sash anchor %x %y } .ps bind Sash <B1-Motion> { %W sash mark %x %y } .ps bind Sash <ButtonRelease-1> { %W sash set %x %y } blt::table . \ 0,0 .ps -fill both \ 1,0 .s -fill x blt::table configure . r1 -resize none focus .ps after 5000 { #.ps pane configure 1 -size { 0 10000 10 } focus . #.ps see pane2 #.ps size pane2 1i } bind .ps.g <ButtonPress-1> ".ps see pane0" bind .ps.b <ButtonPress-1> ".ps see pane1" bind .ps.b2 <ButtonPress-1> ".ps see pane2"���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabset4.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000004102�11462120062�015417� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #blt::bltdebug 100 source scripts/stipples.tcl blt::tabset .t \ -tabwidth same \ -side left \ -textside bottom \ -textside top \ -tiers 1 \ -scrollincrement 10 \ -scrollcommand { .s set } \ -rotate 0 \ -selectcommand { MakePicture .t } \ -width 500 -height 500 scrollbar .s -command { .t view } -orient horizontal option clear option add *Tabset.Tab.font -*-helvetica-bold-r-*-*-10-*-*-*-*-*-*-* set files [glob ./images/*.gif] set files [lsort $files] set vertFilter sinc set horzFilter sinc #set vertFilter none #set horzFilter none proc ResizePicture { src dest maxSize } { puts stderr "maxSize=$maxSize" set maxSize [winfo fpixels . $maxSize] set w [image width $src] set h [image height $src] puts stderr "width=$w, height=$h" set sw [expr double($maxSize) / $w] set sh [expr double($maxSize) / $h] puts stderr "sw=$sw,sh=$sh" set s [expr min($sw, $sh)] set w [expr round($s * $w)] set h [expr round($s * $h)] puts stderr "[$src configure]" $dest configure -width $w -height $h global horzFilter vertFilter $dest resample $src -filter $horzFilter } image create picture src image create picture dest label .t.label -image dest -width 500 -height 500 proc MakePicture { w index } { set file [$w tab cget $index -text] src configure -file ./images/$file.gif set width [$w cget -pagewidth] set height [$w cget -pageheight] puts stderr "pagewidth=$width, pageheight=$height" if { $width < $height } { ResizePicture src dest $width } else { ResizePicture src dest $height } .t dockall .t tab configure $index -window .t.label -padx 4m -pady 4m -fill both } blt::table . \ .t 0,0 -fill both \ .s 1,0 -fill x blt::table configure . r1 -resize none focus .t foreach f $files { src configure -file $f set f [file tail [file root $f]] set thumb [image create picture] ResizePicture src $thumb .5i .t insert end $f -image $thumb -fill both } .t focus 0 .t invoke 0 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabnotebook1.tcl������������������������������������������������������������0000755�0001750�0001750�00000003352�11462120062�016447� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl # Create a tabset widget. blt::tabset .ts -bg blue -outerpad 0 \ -highlightthickness 0 -bd 0 -gap 2 -justify left -tabwidth same # The tabset is initially empty. Insert tabs (pages) into the tabset. foreach label { First Second Third Fourth } { .ts insert end -text $label } # Tabs are referred to by their index. Tab indices can be one of the # following: # # number Position of tab the tabset's list of tabs. # @x,y Tab closest to the specified X-Y screen coordinates. # "active" Tab currently under the mouse pointer. # "focus" Tab that has focus. # "select" The currently selected tab. # "right" Next tab from "focus". # "left" Previous tab from "focus". # "up" Next tab from "focus". # "down" Previous tab from "focus". # "end" Last tab in list. # string Tab identifier. The "insert" operation returns # a unique identifier for the new tab (e.g. "tab0"). # This ID is valid for the life of the tab, even if # the tabs are moved or reordered. # Each tab has a text label and an optional Tk image. set image [image create picture -file ./images/mini-book1.gif] .ts tab configure 0 -image $image # # How to embed a widget into a page. # # 1. The widget must be a child of the tabset. set image [image create picture -file ./images/blt98.gif] label .ts.label -image $image -relief sunken -bd 2 # 2. Use the -window option to embed the widget. #.ts tab configure 0 -window .ts.label # The tearoff perforation, displayed on the selected tab, is # controlled by the tabset's -tearoff option. # # If you don't want tearoff pages, configure -tearoff to "no". .ts configure -tearoff yes blt::table . \ 0,0 .ts -fill both focus .ts ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/busy2.tcl�������������������������������������������������������������������0000755�0001750�0001750�00000013340�11462120062�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT #source scripts/demo.tcl # # Script to test the "busy" command. # # # General widget class resource attributes # option add *Button.padX 10 option add *Button.padY 2 option add *Scale.relief sunken #option add *Scale.orient horizontal option add *Entry.relief sunken option add *Frame.borderWidth 2 set visual [winfo screenvisual .] if { $visual == "staticgray" || $visual == "grayscale" } { set activeBg black set normalBg white set bitmapFg black set bitmapBg white option add *f1.background white } else { set activeBg red set normalBg springgreen set bitmapFg blue set bitmapBg green option add *Button.background khaki2 option add *Button.activeBackground khaki1 option add *Frame.background khaki2 option add *f2.tile textureBg # option add *Button.tile textureBg option add *releaseButton.background limegreen option add *releaseButton.activeBackground springgreen option add *releaseButton.foreground black option add *holdButton.background red option add *holdButton.activeBackground pink option add *holdButton.foreground black option add *f1.background springgreen } # # Instance specific widget options # option add *f1.relief sunken option add *f1.background $normalBg option add *testButton.text "Test" option add *quitButton.text "Quit" option add *newButton.text "New button" option add *holdButton.text "Hold" option add *releaseButton.text "Release" option add *buttonLabel.text "Buttons" option add *entryLabel.text "Entries" option add *scaleLabel.text "Scales" option add *textLabel.text "Text" proc LoseFocus {} { focus -force . } proc KeepRaised { w } { bindtags $w keepRaised } bind keepRaised <Visibility> { raise %W } set file ./images/chalk.gif image create picture textureBg -file $file # # This never gets used; it's reset by the Animate proc. It's # here to just demonstrate how to set busy window options via # the host window path name # #option add *f1.busyCursor bogosity # # Counter for new buttons created by the "New button" button # set numWin 0 menu .menu .menu add command -label "First" .menu add command -label "Second" .menu add command -label "Third" .menu add command -label "Fourth" . configure -menu .menu # # Create two frames. The top frame will be the host window for the # busy window. It'll contain widgets to test the effectiveness of # the busy window. The bottom frame will contain buttons to # control the testing. # frame .f1 frame .f2 # # Create some widgets to test the busy window and its cursor # label .buttonLabel button .testButton -command { puts stdout "Not busy." } button .quitButton -command { exit } entry .entry scale .scale text .text -width 20 -height 4 # # The following buttons sit in the lower frame to control the demo # button .newButton -command { global numWin incr numWin set name button#${numWin} button .f1.$name -text "$name" \ -command [list .f1 configure -bg blue] blt::table .f1 \ .f1.$name $numWin+3,0 -padx 10 -pady 10 } button .holdButton -command { if { [blt::busy isbusy .f1] == "" } { global activeBg .f1 configure -bg $activeBg } blt::busy .f1 blt::busy .#menu LoseFocus } button .releaseButton -command { if { [blt::busy isbusy .f1] == ".f1" } { blt::busy release .f1 blt::busy release .#menu } global normalBg .f1 configure -bg $normalBg } # # Notice that the widgets packed in .f1 and .f2 are not their children # blt::table .f1 \ .testButton 0,0 \ .scale 1,0 \ .entry 0,1 \ .text 1,1 -fill both \ .quitButton 2,0 blt::table .f2 \ .newButton 0,0 \ .holdButton 1,0 \ .releaseButton 2,0 blt::table configure .f1 .testButton .scale .entry .quitButton \ -padx 10 -pady 10 -fill both blt::table configure .f2 .newButton .holdButton .releaseButton \ -padx 10 -pady 10 blt::table configure .f2 c0 -resize none # # Finally, realize and map the top level window # blt::table . \ .f1 0,0 \ .f2 1,0 blt::table configure . .f1 .f2 -fill both # Initialize a list of bitmap file names which make up the animated # fish cursor. The bitmap mask files have a "m" appended to them. blt::table configure . r1 -resize none set bitmapList { left left1 mid right1 right } # # Simple cursor animation routine: Uses the "after" command to # circulate through a list of cursors every 0.075 seconds. The # first pass through the cursor list may appear sluggish because # the bitmaps have to be read from the disk. Tk's cursor cache # takes care of it afterwards. # proc StartAnimation { widget count } { global bitmapList set prefix "bitmaps/fish/[lindex $bitmapList $count]" set cursor [list @${prefix}.xbm ${prefix}m.xbm black white ] blt::busy configure $widget -cursor $cursor incr count set limit [llength $bitmapList] if { $count >= $limit } { set count 0 } global afterId set afterId($widget) [after 125 StartAnimation $widget $count] } proc StopAnimation { widget } { global afterId after cancel $afterId($widget) } proc TranslateBusy { window } { #set widget [string trimright $window "_Busy"] set widget [string trimright $window "Busy"] set widget [string trimright $widget "_"] # if { [winfo toplevel $widget] != $widget } { # set widget [string trimright $widget "."] # } return $widget } if { [info exists tcl_platform] && $tcl_platform(platform) == "unix" } { bind Busy <Map> { StartAnimation [TranslateBusy %W] 0 } bind Busy <Unmap> { StopAnimation [TranslateBusy %W] } } # # For testing, allow the top level window to be resized # wm min . 0 0 # # Force the demo to stay raised # raise . KeepRaised . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tabset3.tcl�����������������������������������������������������������������0000755�0001750�0001750�00000016743�11462120062�015434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #blt::bltdebug 100 image create picture label1 -file ./images/mini-book1.gif image create picture label2 -file ./images/mini-book2.gif image create picture testImage -file ./images/txtrflag.gif blt::tabset .t \ -textside right \ -slant both \ -side right \ -tabwidth same \ -highlightcolor yellow \ -tiers 5 \ -scrolltabs yes \ -scrollcommand { .s set } \ -scrollincrement 1 label .t.l -image testImage set font [font create -family "Arial" -size 8 -weight bold] puts stderr [font configure $font] option add *Tabset.Tab.font $font #option add *Tabset.Tab.fill both set attributes { graph1 "Graph \#1" pink graph2 "Graph \#2" lightblue graph3 "Graph \#3" orange graph5 "Graph \#5" yellow barchart2 "Barchart \#2" green } foreach { name label color } $attributes { .t insert end $name -text $label \ -selectbackground ${color}3 \ -background ${color}3 \ -activebackground ${color}2 } .t insert end Image -selectbackground salmon2 -background salmon3 \ -selectbackground salmon3 -activebackground salmon2 -window .t.l set tabLabels { Aarhus Aaron Ababa aback abaft abandon abandoned abandoning abandonment abandons abase abased abasement abasements abases abash abashed abashes abashing abasing abate abated abatement abatements abater abates abating Abba abbe abbey abbeys abbot abbots Abbott abbreviate abbreviated abbreviates abbreviating abbreviation abbreviations Abby abdomen abdomens abdominal abduct abducted abduction abductions abductor abductors abducts Abe abed Abel Abelian Abelson Aberdeen Abernathy aberrant aberration aberrations abet abets abetted abetter abetting abeyance abhor abhorred abhorrent abhorrer abhorring abhors abide abided abides abiding Abidjan Abigail Abilene abilities ability abject abjection abjections abjectly abjectness abjure abjured abjures abjuring ablate ablated ablates ablating ablation ablative ablaze able abler ablest ably Abner abnormal abnormalities abnormality abnormally Abo aboard abode abodes abolish abolished abolisher abolishers abolishes abolishing abolishment abolishments abolition abolitionist abolitionists abominable abominate aboriginal aborigine aborigines abort aborted aborting abortion abortions abortive abortively aborts Abos abound abounded abounding abounds about above aboveboard aboveground abovementioned abrade abraded abrades abrading Abraham Abram Abrams Abramson abrasion abrasions abrasive abreaction abreactions abreast abridge abridged abridges abridging abridgment abroad abrogate abrogated abrogates abrogating abrupt abruptly abruptness abscess abscessed abscesses abscissa abscissas abscond absconded absconding absconds absence absences absent absented absentee absenteeism absentees absentia absenting absently absentminded absents absinthe absolute absolutely absoluteness absolutes absolution absolve absolved absolves absolving absorb absorbed absorbency absorbent absorber absorbing absorbs absorption absorptions absorptive abstain abstained abstainer abstaining abstains abstention abstentions abstinence abstract abstracted abstracting abstraction abstractionism abstractionist abstractions abstractly abstractness abstractor abstractors abstracts abstruse abstruseness absurd absurdities absurdity absurdly Abu abundance abundant abundantly abuse abused abuses abusing abusive abut abutment abuts abutted abutter abutters abutting abysmal abysmally abyss abysses Abyssinia Abyssinian Abyssinians acacia academia academic academically academics academies academy Acadia Acapulco accede acceded accedes accelerate accelerated accelerates accelerating acceleration accelerations accelerator accelerators accelerometer accelerometers accent accented accenting accents accentual accentuate accentuated accentuates accentuating accentuation accept acceptability acceptable acceptably acceptance acceptances accepted accepter accepters accepting acceptor acceptors accepts access accessed accesses accessibility accessible accessibly accessing accession accessions accessories accessors accessory accident accidental accidentally accidently accidents acclaim acclaimed acclaiming acclaims acclamation acclimate acclimated acclimates acclimating acclimatization acclimatized accolade accolades accommodate accommodated accommodates accommodating accommodation accommodations accompanied accompanies accompaniment accompaniments accompanist accompanists accompany accompanying accomplice accomplices accomplish accomplished accomplisher accomplishers accomplishes accomplishing accomplishment accomplishments accord accordance accorded accorder accorders according accordingly accordion accordions accords accost accosted accosting accosts account accountability accountable accountably accountancy accountant accountants accounted accounting accounts Accra accredit accreditation accreditations accredited accretion accretions accrue accrued accrues accruing acculturate acculturated acculturates acculturating acculturation accumulate accumulated accumulates accumulating accumulation accumulations accumulator accumulators accuracies accuracy accurate accurately accurateness accursed accusal accusation accusations accusative accuse accused accuser accuses accusing accusingly accustom accustomed accustoming accustoms ace aces acetate acetone acetylene Achaean Achaeans ache ached aches achievable achieve achieved achievement achievements achiever achievers achieves achieving Achilles aching acid acidic acidities acidity acidly acids acidulous Ackerman Ackley acknowledge acknowledgeable acknowledged acknowledgement acknowledgements acknowledger acknowledgers acknowledges acknowledging acknowledgment acknowledgments acme acne acolyte acolytes acorn acorns acoustic acoustical acoustically acoustician acoustics acquaint acquaintance acquaintances acquainted acquainting acquaints acquiesce acquiesced acquiescence acquiescent acquiesces acquiescing acquirable acquire acquired acquires acquiring acquisition acquisitions } for { set i 0 } { $i < 500 } { incr i } { .t insert end [lindex $tabLabels $i] -state normal } blt::tk::scrollbar .s -command { .t view } -orient horizontal radiobutton .left -text "Left" -variable side -value "left" \ -command { .t configure -side $side -rotate 90 } radiobutton .right -text "Right" -variable side -value "right" \ -command { .t configure -side $side -rotate 270 } radiobutton .top -text "Top" -variable side -value "top" \ -command { .t configure -side $side -rotate 0 } radiobutton .bottom -text "Bottom" -variable side -value "bottom" \ -command { .t configure -side $side -rotate 0 } blt::table . \ .t 0,0 -fill both -cspan 2 \ .s 1,0 -fill x -cspan 2 \ .top 2,0 -cspan 2 \ .left 3,0 \ .right 3,1 \ .bottom 4,0 -cspan 2 blt::table configure . r1 r3 r4 r2 -resize none focus .t .t focus 0 if 0 { after 3000 { .t move 0 after 3 .t tab configure 3 -state disabled } } foreach file { graph1 graph2 graph3 graph5 barchart2 } { namespace eval $file { if { [string match graph* $file] } { set graph [blt::graph .t.$file] } else { set graph [blt::barchart .t.$file] } source scripts/$file.tcl .t tab configure $file -window $graph -fill both } } .top invoke �����������������������������./saods9/blt3.0.1/demos/treeview1.tcl���������������������������������������������������������������0000755�0001750�0001750�00000010552�11462120062�015772� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl proc SortColumn { column } { set old [.t sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.t sort cget -decreasing] set decreasing [expr !$decreasing] } .t sort configure -decreasing $decreasing -column $column -mode integer if { ![.t cget -flat] } { .t configure -flat yes } .t sort auto yes blt::busy hold .t update blt::busy release .t } proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } proc Find { tree parent dir } { global count set saved [pwd] cd $dir foreach f [glob -nocomplain *] { set name [file tail $f] if { [catch { file stat $f info }] != 0 } { set node [$tree insert $parent -label $name] } else { if 0 { if { $info(type) == "file" } { set info(type) [list @::blt::TreeView::openIcon $name] } else { set info(type) "@::blt::TreeView::openIcon " } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(size) [FormatSize $info(size)] set info(mode) [FormatMode $info(mode)] set node [$tree insert $parent -label $name -data [array get info]] } incr count if { [file type $f] == "directory" } { Find $tree $node $f } } cd $saved } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } button .b -font { Helvetica 11 bold } set top [GetAbsolutePath ..] set top [GetAbsolutePath "/home/gah/Azureus Downloads"] set trim "$top" set tree [blt::tree create] blt::tk::scrollbar .vs -orient vertical -command { .t yview } blt::tk::scrollbar .hs -orient horizontal -command { .t xview } blt::treeview .t \ -width 0 \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -selectmode multiple \ -separator / \ -tree $tree .t column configure treeView -text "" -edit yes #file .t column insert 0 mtime atime gid .t column insert end nlink mode type ctime uid ino size dev .t column configure uid -background \#eaeaff .t column configure mtime -hide no -bg \#ffeaea .t column configure size gid nlink uid ino dev -justify left -edit yes .t column configure size type -justify left -edit yes .t column configure treeView -hide no -edit yes \ -icon ::blt::TreeView::openIcon focus .t blt::table . \ 0,0 .t -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x blt::table configure . c1 r1 -resize none set count 0 Find $tree root $top puts "$count entries" if 0 { $tree find root -glob *.c -addtag "c_files" $tree find root -glob *.h -addtag "header_files" $tree find root -glob *.tcl -addtag "tcl_files" .t entry configure "c_files" -foreground green4 .t entry configure "header_files" -foreground cyan4 .t entry configure "tcl_files" -foreground red4 } .t column bind all <ButtonRelease-3> { %W configure -flat no } foreach column [.t column names] { .t column configure $column -command [list SortColumn $column] } # Create a second treeview that shares the same tree. if 0 { toplevel .top blt::treeview .top.t2 -tree $tree -yscrollcommand { .top.sbar set } scrollbar .top.sbar -command { .top.t2 yview } pack .top.t2 -side left -expand yes -fill both pack .top.sbar -side right -fill y } #.t style configure text -background #F8fbF8 -selectbackground #D8fbD8 .t style checkbox check \ -onvalue 100 -offvalue "50" \ -showvalue yes .t style combobox combo \ -icon ::blt::TreeView::openIcon \ -arrowrelief flat -arrowborderwidth 0 .t column configure uid -style combo .t column configure gid -style check ������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/scrollset4.tcl��������������������������������������������������������������0000644�0001750�0001750�00000002512�11462120062�016147� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl #blt::bltdebug 100 image create picture label1 -file ./images/mini-book1.gif image create picture label2 -file ./images/mini-book2.gif image create picture testImage -file ./images/txtrflag.gif blt::scrollset .ss \ -xviewcommand { .ss.t view } \ -xscrollbar .ss.xsbar \ -yscrollbar .ss.ysbar \ -window .ss.t blt::tk::scrollbar .ss.ysbar -orient vertical blt::tk::scrollbar .ss.xsbar -orient horizontal blt::tabset .ss.t \ -font { Arial 8 } \ -textside right \ -tabwidth same \ -scrollcommand { .ss set x } \ -scrollincrement 1 blt::table . \ .ss 0,0 -fill both focus .ss.t set attributes { graph1 "Graph \#1" pink graph2 "Graph \#2" lightblue graph3 "Graph \#3" orange graph5 "Graph \#5" yellow barchart2 "Barchart \#2" green } foreach { name label color } $attributes { .ss.t insert end $name -text $label } blt::tk::label .ss.t.l -image testImage .ss.t insert end Image -window .ss.t.l .ss.t focus 0 foreach file { graph1 graph2 graph3 graph5 barchart2 } { namespace eval $file { if { [string match graph* $file] } { set graph [blt::graph .ss.t.$file] } else { set graph [blt::barchart .ss.t.$file] } source scripts/$file.tcl .ss.t tab configure $file -window $graph -fill both } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/drawerset1.tcl��������������������������������������������������������������0000644�0001750�0001750�00000002646�11462120062�016142� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl blt::graph .g -bg \#CCCCFF -height 800 -width 801 set w [blt::drawerset .g -handlethickness 3 -animate yes] blt::barchart .g.b -bg \#FFCCCC -height 1600 -width 300 blt::barchart .g.b2 -bg \#CCFFCC -height 300 -width 300 blt::barchart .g.b3 -bg \#FFFFCC -height 300 -width 300 blt::barchart .g.b4 -bg \#CCFFFF -height 300 -width 300 $w add top -window .g.b -fill no \ -side top -variable top -handlecolor \#FFCCCC -showhandle no $w add left -window .g.b2 -side left -variable left -handlecolor \#CCFFCC \ -showhandle no $w add right -window .g.b3 -side right -variable right -handlecolor \#FFFFCC $w add bottom -window .g.b4 -side bottom -variable bottom \ -handlecolor \#CCFFFF -showhandle no checkbutton .left -text "L" -overrelief raised \ -variable left -indicatoron no checkbutton .right -text "R" -overrelief raised \ -variable right -indicatoron no checkbutton .top -text "T" -overrelief raised \ -variable top -indicatoron no checkbutton .bottom -text "B" -overrelief raised \ -variable bottom -indicatoron no blt::table . \ 0,0 .g -fill both -rspan 5 \ 0,1 .left \ 1,1 .right \ 2,1 .top \ 3,1 .bottom blt::table configure . r* -resize none blt::table configure . r4 -resize both puts stderr [info commands .g.*] $w open all update puts stderr drawer=$w puts stderr "left is [$w isopen left] left=$left" after 2000 { $w raise top } ������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/eps.tcl���������������������������������������������������������������������0000755�0001750�0001750�00000020552�11462120062�014647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl blt::debug watch ResizeEpsItem proc StartMove { canvas tagName x y } { SaveImageCoords $canvas $tagName $x $y $canvas itemconfigure $tagName-image -quick yes } proc EndMove { canvas tagName } { $canvas configure -cursor {} $canvas itemconfigure $tagName-image -quick no } proc MoveEpsItem { canvas tagName x y } { global lastX lastY $canvas move $tagName \ [expr $x - $lastX($tagName)] [expr $y - $lastY($tagName)] set lastX($tagName) $x set lastY($tagName) $y } proc GetEpsBBox { canvas tagName } { global left top right bottom set anchor [$canvas coords $tagName-image] set left [lindex $anchor 0] set top [lindex $anchor 1] if { [$canvas type $tagName-image] == "image" } { set image [$canvas itemcget $tagName-image -image] set width [image width $image] set height [image height $image] } else { set width [$canvas itemcget $tagName-image -width] set height [$canvas itemcget $tagName-image -height] } set right [expr $left + $width] set bottom [expr $top + $height] } proc SaveImageCoords { canvas tagName x y } { global lastX lastY set lastX($tagName) $x set lastY($tagName) $y $canvas configure -cursor sb_h_double_arrow $canvas itemconfigure $tagName-image -quick yes } array set cursors { sw bottom_left_corner ne top_right_corner se bottom_right_corner nw top_left_corner } proc StartResize { canvas tagName x y anchor } { global left top right bottom image GetEpsBBox $canvas $tagName $canvas itemconfigure $tagName-image -quick yes $canvas itemconfigure $tagName-grip -fill red $canvas create line $left $top $right $bottom \ -tags "$tagName $tagName-cross $tagName-l1" \ -fill red -width 2 $canvas create line $left $bottom $right $top \ -tags "$tagName $tagName-cross $tagName-l2" \ -fill red -width 2 $canvas raise $tagName-grip global cursors $canvas configure -cursor $cursors($anchor) global lastX lastY set lastX($tagName) $x set lastY($tagName) $y } proc EndResize { canvas tagName x y anchor } { $canvas itemconfigure $tagName-image -quick no \ -showimage yes ResizeEpsItem $canvas $anchor $tagName $x $y $canvas itemconfigure $tagName-grip -fill green $canvas delete $tagName-cross $canvas configure -cursor "" } proc ResetGrips { canvas tagName } { global gripSize global left top right bottom GetEpsBBox $canvas $tagName $canvas coords $tagName-nw \ $left $top [expr $left + $gripSize] [expr $top + $gripSize] $canvas coords $tagName-se \ [expr $right - $gripSize] [expr $bottom - $gripSize] $right $bottom $canvas coords $tagName-ne \ [expr $right - $gripSize] [expr $top + $gripSize] $right $top $canvas coords $tagName-sw \ $left $bottom [expr $left + $gripSize] [expr $bottom - $gripSize] $canvas coords $tagName-l1 $left $top $right $bottom $canvas coords $tagName-l2 $left $bottom $right $top } proc ResizeEpsItem { canvas anchor tagName x y } { global left top right bottom GetEpsBBox $canvas $tagName switch $anchor { sw { set left $x ; set bottom $y set cursor bottom_left_corner } ne { set right $x ; set top $y set cursor top_right_corner } se { set right $x ; set bottom $y set cursor bottom_right_corner } nw { set left $x ; set top $y set cursor top_left_corner } default { error "anchor can't be $anchor" } } set w [expr $right - $left] set h [expr $bottom - $top] set options "" if { $w > 1 } { append options "-width $w " } if { $h > 1 } { append options "-height $h " } $canvas coords $tagName-image $left $top eval $canvas itemconfigure $tagName-image $options GetEpsBBox $canvas $tagName ResetGrips $canvas $tagName } set numGroups 0 set id 0 proc MakeEps { canvas {epsFile ""} {imageFile ""} } { global numGroups id gripSize image set image "" if { $imageFile != "" } { set image [image create picture -file $imageFile] } set tagName "epsGroup[incr numGroups]" $canvas create eps 20 20 \ -anchor nw \ -tags "$tagName $tagName-image" \ -titlecolor white \ -titlerotate 0 \ -titleanchor nw \ -font { Courier 24 } \ -stipple BLT \ -outline orange4 \ -fill orange \ -file $epsFile \ -showimage yes \ -image $image set gripSize 8 GetEpsBBox $canvas $tagName global left top right bottom $canvas create rectangle \ $left $top [expr $left + $gripSize] [expr $top + $gripSize] \ -tags "$tagName $tagName-grip $tagName-nw" \ -fill red -outline "" $canvas create rectangle \ [expr $right - $gripSize] [expr $bottom - $gripSize] $right $bottom \ -tags "$tagName $tagName-grip $tagName-se" \ -fill red -outline "" $canvas create rectangle \ [expr $right - $gripSize] [expr $top + $gripSize] $right $top \ -tags "$tagName $tagName-grip $tagName-ne" \ -fill red -outline "" $canvas create rectangle \ $left $bottom [expr $left + $gripSize] [expr $bottom - $gripSize] \ -tags "$tagName $tagName-grip $tagName-sw" \ -fill red -outline "" $canvas bind $tagName-image <ButtonPress-1> \ "StartMove $canvas $tagName %x %y" $canvas bind $tagName-image <B1-Motion> \ "MoveEpsItem $canvas $tagName %x %y" $canvas bind $tagName <ButtonRelease-1> \ "EndMove $canvas $tagName" foreach grip { sw ne se nw } { $canvas bind $tagName-$grip <ButtonPress-1> \ "StartResize $canvas $tagName %x %y $grip" $canvas bind $tagName-$grip <B1-Motion> \ "ResizeEpsItem $canvas $grip $tagName %x %y" $canvas bind $tagName-$grip <ButtonRelease-1> \ "EndResize $canvas $tagName %x %y $grip" $canvas raise $tagName-$grip } } proc MakeImage { canvas fileName } { global numGroups id gripSize image set image "" set image [image create picture -file $fileName] set tagName "epsGroup[incr numGroups]" $canvas create image 20 20 \ -anchor nw \ -tags "$tagName $tagName-image" \ -image $image set gripSize 8 GetEpsBBox $canvas $tagName global left top right bottom $canvas create rectangle \ $left $top [expr $left + $gripSize] [expr $top + $gripSize] \ -tags "$tagName $tagName-grip $tagName-nw" \ -fill red -outline "" $canvas create rectangle \ [expr $right - $gripSize] [expr $bottom - $gripSize] $right $bottom \ -tags "$tagName $tagName-grip $tagName-se" \ -fill red -outline "" $canvas create rectangle \ [expr $right - $gripSize] [expr $top + $gripSize] $right $top \ -tags "$tagName $tagName-grip $tagName-ne" \ -fill red -outline "" $canvas create rectangle \ $left $bottom [expr $left + $gripSize] [expr $bottom - $gripSize] \ -tags "$tagName $tagName-grip $tagName-sw" \ -fill red -outline "" $canvas bind $tagName <ButtonRelease-1> \ "$canvas configure -cursor {}" $canvas bind $tagName-image <ButtonPress-1> \ "SaveImageCoords $canvas $tagName %x %y" $canvas bind $tagName-image <B1-Motion> \ "MoveEpsItem $canvas $tagName %x %y" foreach grip { sw ne se nw } { $canvas bind $tagName-$grip <ButtonPress-1> \ "StartResize $canvas $tagName %x %y $grip" $canvas bind $tagName-$grip <B1-Motion> \ "ResizeEpsItem $canvas $grip $tagName %x %y" $canvas bind $tagName-$grip <ButtonRelease-1> \ "EndResize $canvas $tagName %x %y $grip" $canvas raise $tagName-$grip } } source scripts/stipples.tcl # # Script to test the BLT "eps" canvas item. # canvas .layout -bg white button .print -text "Print" -command { wm iconify . update .layout postscript -file eps.ps wm deiconify . update } button .quit -text "Quit" -command { exit 0 } blt::table . \ 0,0 .layout -fill both -cspan 2 \ 1,0 .print \ 1,1 .quit \ blt::table configure . r1 -resize none MakeImage .layout test2.gif foreach file { ./images/out.ps xy.ps test.ps } { if { [file exists $file] } { MakeEps .layout $file } } if 0 { set image [image create picture -file testImg.jpg] .layout create eps 20 20 \ -anchor nw \ -outline blue \ -fill yellow \ -showimage yes \ -image $image } .layout create rectangle 10 10 50 50 -fill blue -outline white .layout create text 200 200 \ -text "This is a text item" \ -fill yellow \ -anchor w \ -font { Times 24 } .layout create rectangle 50 50 150 150 -fill green -outline red wm colormapwindows . .layout .layout configure -scrollregion [.layout bbox all] ������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cbutton2.tcl����������������������������������������������������������������0000644�0001750�0001750�00000021732�11462120062�015616� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set icon2 [image create picture -file images/blt98.gif] set icon [image create picture -data $imgData] set bg [blt::bgpattern create gradient -high grey100 -low grey90 \ -dir x -jitter yes -log yes -relativeto self] set image "" option add *ComboEntry.takeFocus 1 if { [file exists ../library] } { set blt_library ../library } set myIcon "" blt::combobutton .b \ -font { arial 10 } \ -image $image \ -textvariable myText1 \ -iconvariable myIcon1 \ -arrowon yes \ -menu .b.m \ -menuanchor se \ -command "puts {button pressed}" blt::combomenu .b.m \ -bg $bg \ -cursor crosshair \ -activebackground skyblue4 \ -activeforeground white \ -textvariable myText1 \ -iconvariable myIcon1 \ -font { Arial 9 bold } \ -acceleratorfont { Arial 8 } \ -disabledforeground grey35 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey35 \ -yscrollbar .b.m.ybar \ -xscrollbar .b.m.xbar blt::tk::scrollbar .b.m.xbar # -elementborderwidth 2 -borderwidth 0 blt::tk::scrollbar .b.m.ybar #-elementborderwidth 2 -borderwidth 0 set onOff 0 set wwho "" foreach item { Undo X1 Y1 Redo Cut Copy X2 Y2 Paste "Select All" X3 Y3 Find Replace } { set char [string range $item 0 0] .b.m add \ -text $item \ -type checkbutton \ -accel "Ctrl+$char" \ -underline 0 \ -tag [string tolower $char] \ -icon $icon \ -variable onOff \ -value $item \ } .b.m item configure Undo -type command .b.m item configure Cut -type command .b.m item configure Find -type cascade -menu .b.m.m #-state disabled .b.m item configure Y3 -type command -image $icon2 .b.m item configure Undo -type command .b.m item configure Paste -type separator .b.m item configure x -state disabled .b.m item configure y -type radiobutton -variable wwho .b.m item configure Y1 -state disabled set wwho Y1 blt::combomenu .b.m.m \ -bg $bg \ -textvariable myText1 \ -iconvariable myIcon1 \ -font { Arial 9 bold } \ -acceleratorfont { Arial 8 } \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -width { 0 400 } \ -height { 0 500 } \ -yscrollbar .b.m.m.ybar \ -xscrollbar .b.m.m.xbar blt::tk::scrollbar .b.m.m.xbar blt::tk::scrollbar .b.m.m.ybar set onOff 0 foreach item { Undo X1 Y1 Redo Cut Copy X2 Y2 Paste "Select All" X3 Y3 Find Replace } { set char [string range $item 0 0] .b.m.m add \ -text $item \ -type checkbutton \ -accel "Ctrl+$char" \ -accel "" \ -underline 0 \ -tag [string tolower $char] \ -icon $icon \ -variable onOff \ -value $item \ } .b.m.m item configure Undo -type command .b.m.m item configure Cut -type command .b.m.m item configure Find -type cascade -menu .b.m.m.m #-state disabled .b.m.m item configure Y3 -type command -image $icon2 .b.m.m item configure Undo -type command .b.m.m item configure Paste -type separator .b.m.m item configure x -state disabled .b.m.m item configure y -type radiobutton -variable wwho set labels { Aarhus Aaron Ababa aback abaft abandon abandoned abandoning abandonment abandons abase abased abasement abasements abases abash abashed abashes abashing abasing abate abated abatement abatements abater abates abating Abba abbe abbey abbeys abbot abbots Abbott abbreviate abbreviated abbreviates abbreviating abbreviation abbreviations Abby abdomen abdomens abdominal abduct abducted abduction abductions abductor abductors abducts Abe abed Abel Abelian Abelson Aberdeen Abernathy aberrant aberration aberrations abet abets abetted abetter abetting abeyance abhor abhorred abhorrent abhorrer abhorring abhors abide abided abides abiding Abidjan Abigail Abilene abilities ability abject abjection abjections abjectly abjectness abjure abjured abjures abjuring ablate ablated ablates ablating ablation ablative ablaze able abler ablest ably Abner abnormal abnormalities abnormality abnormally Abo aboard abode abodes abolish abolished abolisher abolishers abolishes abolishing abolishment abolishments abolition abolitionist abolitionists abominable abominate aboriginal aborigine aborigines abort aborted aborting abortion abortions abortive abortively aborts Abos abound abounded abounding abounds about above aboveboard aboveground abovementioned abrade abraded abrades abrading Abraham Abram Abrams Abramson abrasion abrasions abrasive abreaction abreactions abreast abridge abridged abridges abridging abridgment abroad abrogate abrogated abrogates abrogating abrupt abruptly abruptness abscess abscessed abscesses abscissa abscissas abscond absconded absconding absconds absence absences absent absented absentee absenteeism absentees absentia absenting absently absentminded absents absinthe absolute absolutely absoluteness absolutes absolution absolve absolved absolves absolving absorb absorbed absorbency absorbent absorber absorbing absorbs absorption absorptions absorptive abstain abstained abstainer abstaining abstains abstention abstentions abstinence abstract abstracted abstracting abstraction abstractionism abstractionist abstractions abstractly abstractness abstractor abstractors abstracts abstruse abstruseness absurd absurdities absurdity absurdly Abu abundance abundant abundantly abuse abused abuses abusing abusive abut abutment abuts abutted abutter abutters abutting abysmal abysmally abyss abysses Abyssinia Abyssinian Abyssinians acacia academia academic academically academics academies academy Acadia Acapulco accede acceded accedes accelerate accelerated accelerates accelerating acceleration accelerations accelerator accelerators accelerometer accelerometers accent accented accenting accents accentual accentuate accentuated accentuates accentuating accentuation accept acceptability acceptable acceptably acceptance acceptances accepted accepter accepters accepting acceptor acceptors accepts access accessed accesses accessibility accessible accessibly accessing accession accessions accessories accessors accessory accident accidental accidentally accidently accidents acclaim acclaimed acclaiming acclaims acclamation acclimate acclimated acclimates acclimating acclimatization acclimatized accolade accolades accommodate accommodated accommodates accommodating accommodation accommodations accompanied accompanies accompaniment accompaniments accompanist accompanists accompany accompanying accomplice accomplices accomplish accomplished accomplisher accomplishers accomplishes accomplishing accomplishment accomplishments accord accordance accorded accorder accorders according accordingly accordion accordions accords accost accosted accosting accosts account accountability accountable accountably accountancy accountant accountants accounted accounting accounts Accra accredit accreditation accreditations accredited accretion accretions accrue accrued accrues accruing acculturate acculturated acculturates acculturating acculturation accumulate accumulated accumulates accumulating accumulation accumulations accumulator accumulators accuracies accuracy accurate accurately accurateness accursed accusal accusation accusations accusative accuse accused accuser accuses accusing accusingly accustom accustomed accustoming accustoms ace aces acetate acetone acetylene Achaean Achaeans ache ached aches achievable achieve achieved achievement achievements achiever achievers achieves achieving Achilles aching acid acidic acidities acidity acidly acids acidulous Ackerman Ackley acknowledge acknowledgeable acknowledged acknowledgement acknowledgements acknowledger acknowledgers acknowledges acknowledging acknowledgment acknowledgments acme acne acolyte acolytes acorn acorns acoustic acoustical acoustically acoustician acoustics acquaint acquaintance acquaintances acquainted acquainting acquaints acquiesce acquiesced acquiescence acquiescent acquiesces acquiescing acquirable acquire acquired acquires acquiring acquisition acquisitions } blt::combomenu .b.m.m.m \ -bg $bg \ -textvariable myText1 \ -iconvariable myIcon1 \ -font { Arial 9 bold } \ -acceleratorfont { Arial 8 } \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -width { 0 400 } \ -height { 0 500 } \ -yscrollbar .b.m.m.m.ybar \ -xscrollbar .b.m.m.m.xbar .b.m.m.m listadd $labels \ -icon $icon blt::tk::scrollbar .b.m.m.m.xbar blt::tk::scrollbar .b.m.m.m.ybar blt::tk::scrollbar .s -orient vertical -command { .b xview } bind ComboEntry <3> { grab release [grab current] } blt::table . \ 0,0 .b -fill both blt::table configure . r0 -resize shrink ��������������������������������������./saods9/blt3.0.1/demos/drawer.tcl������������������������������������������������������������������0000644�0001750�0001750�00000001367�11462120062�015344� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������namespace eval blt::Drawer { set buttonPressed 0 proc Initialize {} { } } bind DrawerHandle <Enter> { if { !$blt::Drawer::buttonPressed } { %W activate } } bind DrawerHandle <Leave> { if { !$blt::Drawer::buttonPressed } { %W deactivate } } bind DrawerHandle <KeyPress-Left> { %W move -10 0 } bind DrawerHandle <KeyPress-Right> { %W move 10 0 } bind DrawerHandle <KeyPress-Up> { %W move 0 -10 } bind DrawerHandle <KeyPress-Down> { %W move 0 10 } bind DrawerHandle <ButtonPress-1> { set blt::Paneset::buttonPressed 1 %W anchor %X %Y } bind DrawerHandle <B1-Motion> { %W mark %X %Y } bind DrawerHandle <ButtonRelease-1> { set blt::Paneset::buttonPressed 0 %W set %X %Y } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tour.tcl��������������������������������������������������������������������0000755�0001750�0001750�00000010622�11462120062�015046� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish #package require BLT source scripts/demo.tcl option add *Scrollbar.relief flat set oldLabel "dummy" proc RunDemo { program } { if { ![file executable $program] } { return } set cmd [list $program -name "demo:$program" -geom -4000-4000] global programInfo if { [info exists programInfo(lastProgram)] } { set programInfo($programInfo(lastProgram)) 0 } eval bgexec programInfo($program) $cmd & set programInfo(lastProgram) $program puts stderr [.top.tab.f1 search -name demo:$program] .top.tab.f1 configure -name demo:$program } frame .top set tree [blt::tree create] blt::treeview .top.hier -separator "." -xscrollincrement 1 \ -yscrollcommand { .top.yscroll set } -xscrollcommand { .top.xscroll set } \ -separator . \ -tree $tree \ -selectcommand { set index [.top.hier curselection] if { $index != "" } { set label [.top.hier entry cget $index -label] .top.title configure -text $label .top.tab tab configure Example -window .top.tab.f1 if { $label != $oldLabel } { RunDemo $label } } } blt::tk::scrollbar .top.yscroll -command { .top.hier yview } blt::tk::scrollbar .top.xscroll -command { .top.hier xview } -orient horizontal blt::tk::label .top.mesg -relief groove -borderwidth 2 blt::tk::label .top.title -text "Synopsis" -highlightthickness 0 blt::tabset .top.tab -side bottom -outerrelief flat -outerborderwidth 0 \ -highlightthickness 0 -pageheight 4i foreach tab { "Example" "See Code" "Manual" } { .top.tab insert end $tab } set pics /DOS/f/gah/Pics set pics /home/gah/Pics image create picture dummy -file images/blt98.gif image create picture graph.img -width 50 -height 50 graph.img resample dummy dummy configure -file images/blt98.gif image create picture barchart.img -width 50 -height 50 barchart.img resample dummy .top.hier entry configure root -label "BLT" .top.hier insert end \ "Plotting" \ "Plotting.graph" \ "Plotting.graph.graph" \ "Plotting.graph.graph2" \ "Plotting.graph.graph3" \ "Plotting.graph.graph4" \ "Plotting.graph.graph5" \ "Plotting.graph.graph6" \ "Plotting.barchart" \ "Plotting.barchart.barchart1" \ "Plotting.barchart.barchart2" \ "Plotting.barchart.barchart3" \ "Plotting.barchart.barchart4" \ "Plotting.barchart.barchart5" \ "Plotting.stripchart" \ "Plotting.vector" \ "Composition" \ "Composition.htext" \ "Composition.table" \ "Composition.tabset" \ "Composition.hierbox" \ "Miscellaneous" \ "Miscellaneous.busy" \ "Miscellaneous.bgexec" \ "Miscellaneous.watch" \ "Miscellaneous.bltdebug" .top.hier open -r root .top.hier entry configure root -font *-helvetica*-bold-r-*-18-* puts stderr [$tree dump root] foreach item { "Plotting" "Composition" "Miscellaneous" } { set index [.top.hier index ".$item"] .top.hier entry configure $index -font *-helvetica*-bold-r-*-14-* } .top.hier entry configure [.top.hier index ".Plotting.graph"] \ -font *-helvetica*-bold-r-*-14-* -label "X-Y Graph" .top.hier entry configure [.top.hier index ".Plotting.barchart"] \ -font *-helvetica*-bold-r-*-14-* -label "Bar Chart" .top.hier entry configure [.top.hier index ".Plotting.stripchart"] \ -font *-helvetica*-bold-r-*-14-* -label "X-Y Graph" .top.hier entry configure [.top.hier index ".Plotting.stripchart"] \ -font *-helvetica*-bold-r-*-14-* -label "Strip Chart" .top.hier entry configure [.top.hier index ".Plotting.graph"] -icon graph.img .top.hier entry configure [.top.hier index ".Plotting.barchart"] \ -icon barchart.img blt::table .top \ 0,0 .top.hier -fill both -rspan 2 \ 0,1 .top.yscroll -fill y -rspan 2 \ 0,2 .top.mesg -padx 2 -pady { 8 2 } -fill both \ 0,2 .top.title -anchor nw -padx { 8 8 } \ 1,2 .top.tab -fill both -rspan 2 \ 2,0 .top.xscroll -fill x blt::table configure .top c1 r2 -resize none blt::table configure .top c0 -width { 3i {} } blt::table configure .top c2 -width { 4i {} } blt::table . \ .top -fill both proc DoExit { code } { global progStatus set progStatus 1 exit $code } blt::container .top.tab.f1 -relief raised -bd 2 -takefocus 0 .top.tab tab configure Example -window .top.tab.f1 if 1 { set cmd "xterm -fn fixed -geom +4000+4000" eval blt::bgexec programInfo(xterm) $cmd & set programInfo(lastProgram) xterm .top.tab.f1 configure -command $cmd } wm protocol . WM_DELETE_WINDOW { destroy . } ��������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/tv2.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000001357�11462120062�014572� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT package require Tk set a [frame .a -bg red] set tree [::blt::treeview $a.tree\ -bg blue \ -relief flat -bd 10 \ -selectmode single\ -exportselection false] $tree configure -yscrollcommand "$a.y set" -xscrollcommand "$a.x set" scrollbar $a.y -command "$tree yview" scrollbar $a.x -command "$tree xview" -orient horizontal grid $tree -row 0 -column 1 -sticky nsew grid $a.y -row 0 -column 2 -sticky ns grid $a.x -row 1 -column 1 -sticky we grid columnconfigure $a 1 -weight 1 grid rowconfigure $a 0 -weight 1 $tree configure -width 0 $tree column configure treeView -width 0 $tree insert end hello -label hello #$tree insert end a -label aaaaaaaaaaaaaaaaaaaaaaaaaaaaa pack $a -fill both -expand true ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/graph7.tcl������������������������������������������������������������������0000755�0001750�0001750�00000003532�11462120062�015247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish set blt_library ../library package require BLT set blt_library ../library set auto_path [linsert $auto_path 0 ../library] source scripts/demo.tcl image create picture bgTexture -file ./images/buckskin.gif option add *Graph.Tile bgTexture option add *Label.Tile bgTexture option add *Frame.Tile bgTexture option add *Htext.Tile bgTexture option add *TileOffset 0 option add *HighlightThickness 0 option add *Element.ScaleSymbols no option add *Element.Smooth linear option add *activeLine.Color yellow4 option add *activeLine.Fill yellow option add *activeLine.LineWidth 0 option add *Element.Pixels 3 option add *Graph.halo 7i set visual [winfo screenvisual .] if { $visual != "staticgray" } { option add *print.background yellow option add *quit.background red } proc FormatLabel { w value } { return $value } set graph .graph set s1 [image create picture -width 25 -height 25] $s1 blank 0x00000000 $s1 draw circle 12 12 5 -shadow 0 -linewidth 1 \ -fill 0x90FF0000 -antialias yes set length 2500000 blt::graph $graph -title "Scatter Plot\n$length points" -font Arial \ -plotborderwidth 1 -plotrelief solid -plotpadx 0 -plotpady 0 $graph xaxis configure \ -loose no \ -title "X Axis Label" $graph yaxis configure \ -title "Y Axis Label" $graph y2axis configure \ -title "Y2 Axis Label" $graph legend configure \ -activerelief sunken \ -background "" $graph element create line3 -symbol circle -color green4 -fill green2 \ -linewidth 0 -outlinewidth 1 -pixels 4 blt::table . .graph 0,0 -fill both update blt::vector x($length) y($length) x expr random(x) y expr random(y) x sort y $graph element configure line3 -x x -y y wm min . 0 0 Blt_ZoomStack $graph Blt_Crosshairs $graph Blt_ActiveLegend $graph Blt_ClosestPoint $graph blt::busy hold $graph update blt::busy release $graph ����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/mbar1.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000023466�11462120062�015066� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� foreach {key file} { save_as /usr/share/gtk-doc/html/pygtk/icons/stock_save_as new_tab /usr/share/gtk-doc/html/pygtk/icons/stock_new new_window /usr/share/gtk-doc/html/pygtk/icons/stock_network open_file /usr/share/gtk-doc/html/pygtk/icons/stock_open quit /usr/share/gtk-doc/html/pygtk/icons/stock_exit print /usr/share/gtk-doc/html/pygtk/icons/stock_print print_preview /usr/share/gtk-doc/html/pygtk/icons/stock_print_preview undo /usr/share/gtk-doc/html/pygtk/icons/stock_undo redo /usr/share/gtk-doc/html/pygtk/icons/stock_redo cut /usr/share/gtk-doc/html/pygtk/icons/stock_cut paste /usr/share/gtk-doc/html/pygtk/icons/stock_paste copy /usr/share/gtk-doc/html/pygtk/icons/stock_copy delete /usr/share/gtk-doc/html/pygtk/icons/stock_trash select_all /usr/share/gtk-doc/html/pygtk/icons/stock_broken_image find /usr/share/gtk-doc/html/pygtk/icons/stock_search preferences /usr/share/gtk-doc/html/pygtk/icons/stock_preferences stop /usr/share/gtk-doc/html/pygtk/icons/stock_stop reload /usr/share/gtk-doc/html/pygtk/icons/stock_refresh back /usr/share/gtk-doc/html/pygtk/icons/stock_left_arrow forward /usr/share/gtk-doc/html/pygtk/icons/stock_right_arrow home /usr/share/gtk-doc/html/pygtk/icons/stock_home } { set icon($key) [image create picture -file ${file}_24.png] } if { [file exists ../library] } { set blt_library ../library } set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } #set image [image create picture -file ~/images.jpeg] set bg [blt::bgpattern create gradient -high grey70 -low grey95 \ -jitter yes -log yes -relativeto self] set image "" blt::menubar .mbar \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 10 bold } -justify left \ .mbar add \ -text "File" \ -underline 0 \ -image $image \ -menuanchor sw \ -menu .mbar.file blt::combomenu .mbar.file \ -width -400 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.file.m add -text "New Window" -accelerator "Ctrl+N" -underline 0 \ -icon $icon(new_window) .mbar.file add -text "New Tab" -accelerator "Ctrl+T" -underline 4 \ -icon $icon(new_tab) .mbar.file add -text "Open Location..." -accelerator "Ctrl+L" -underline 5 .mbar.file add -text "Open File..." -accelerator "Ctrl+O" -underline 0 \ -icon $icon(open_file) .mbar.file add -text "Close Window" -accelerator "Ctrl+Shift+W" -underline 9 .mbar.file add -text "Close Tab" -accelerator "Ctrl+W" -underline 0 .mbar.file add -type separator .mbar.file add -text "Save Page As..." -accelerator "Ctrl+O" -underline 10 \ -icon $icon(save_as) .mbar.file add -text "Save Page As PDF..." -accelerator "Ctrl+Shift+W" -underline 15 .mbar.file add -text "Send Link..." -accelerator "Ctrl+W" -underline 1 .mbar.file add -type separator .mbar.file add -text "Page Setup..." -underline 8 .mbar.file add -text "Print Preview" -accelerator "Ctrl+Shift+W" -underline 9 \ -icon $icon(print_preview) .mbar.file add -text "Print..." -accelerator "Ctrl+P" -underline 0 \ -icon $icon(print) .mbar.file add -type separator .mbar.file add -text "Import..." -underline 0 .mbar.file add -type separator .mbar.file add -text "Work Offline" -underline 0 .mbar.file add -text "Quit" -accelerator "Ctrl+Q" -underline 0 \ -icon $icon(quit) .mbar add \ -text "Edit" \ -underline 0 \ -menuanchor nw \ -menu .mbar.edit blt::combomenu .mbar.edit \ -width -400 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.edit add -text "Undo" -accelerator "Ctrl+Z" \ -icon $icon(undo) .mbar.edit add -text "Redo" -accelerator "Ctrl+Shift+Z" \ -icon $icon(redo) .mbar.edit add -type separator .mbar.edit add -text "Cut" -accelerator "Ctrl+X" \ -icon $icon(cut) .mbar.edit add -text "Copy" -accelerator "Ctrl+C" \ -icon $icon(copy) .mbar.edit add -text "Paste" -accelerator "Ctrl+V" \ -icon $icon(paste) .mbar.edit add -text "Delete" -accelerator "Del" \ -icon $icon(delete) .mbar.edit add -type separator .mbar.edit add -text "Select All" -accelerator "Ctrl+X" \ -icon $icon(select_all) .mbar.edit add -type separator .mbar.edit add -text "Find" -accelerator "Ctrl+F" \ -icon $icon(find) .mbar.edit add -text "Find Again" -accelerator "Ctrl+G" .mbar.edit add -type separator .mbar.edit add -text "Preferences" \ -icon $icon(preferences) blt::combomenu .mbar.edit.m .mbar.edit.m add -type command -text "five" -accelerator "^A" -command "set t five" .mbar.edit.m add -type command -text "six" -accelerator "^B" -command "set t six" .mbar.edit.m add -type command -text "seven" -accelerator "^C" -command "set t seven" .mbar.edit.m add -type command -text "eight" -accelerator "^D" -command "set t eight" .mbar.edit.m add -type cascade -text "cascade" -accelerator "^E" .mbar add \ -text "View" \ -underline 0 \ -menuanchor nw \ -menu .mbar.view blt::combomenu .mbar.view \ -width -600 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.view add -type cascade -text "Toolbars" -underline 0 .mbar.view add -type checkbutton -text "Status Bar" \ -underline 4 .mbar.view add -type checkbutton -text "Sidebar" \ -underline 5 -variable sidebar .mbar.view add -type checkbutton -text "Adblock Plus: Blockable items" \ -accelerator "Ctrl+Shift+V" -underline 0 -variable adblock .mbar.view add -type separator .mbar.view add -text "Stop" -accelerator "Esc" -underline 9 \ -icon $icon(stop) .mbar.view add -text "Reload" -accelerator "Ctrl+R" -underline 0 \ -icon $icon(reload) .mbar.view add -type separator .mbar.view add -type cascade -text "Zoom" -accelerator "Ctrl+O" -underline 10 .mbar.view add -type cascade -text "Page Style" -accelerator "Ctrl+Shift+W" \ -underline 15 .mbar.view add -type cascade -text "Character Encoding" -accelerator "Ctrl+W" \ -underline 1 .mbar.view add -type separator .mbar.view add -text "Page Source" -underline 8 -accelerator "Ctrl+U" .mbar.view add -text "Full Screen" -accelerator "F11" -underline 9 .mbar add \ -text "History" \ -underline 0 \ -menuanchor nw \ -menu .mbar.history blt::combomenu .mbar.history \ -width -600 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.history add -text "Back" -accelerator "Alt+Left Arrow" \ -underline 0 -icon $icon(back) .mbar.history add -text "Forward" -accelerator "Alt+Right Arrow" \ -underline 4 -icon $icon(forward) .mbar.history add -text "Home" -accelerator "Alt+Home" \ -underline 5 -icon $icon(home) .mbar.history add -text "Show All History" -accelerator "Ctrl+Shift+H" \ -underline 0 .mbar.history add -type separator .mbar.history add -type cascade -text "Recently Closed Tabs" \ -accelerator "Ctrl+O" -underline 10 .mbar add \ -text "Bookmarks" \ -relief flat \ -activerelief raised \ -bg $bg \ -font { Arial 10 bold } -justify left \ -underline 0 \ -menuanchor nw \ -menu .mbar.bmarks blt::combomenu .mbar.bmarks \ -width -600 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.bmarks add -text "Bookmark This Page" -accelerator "Ctrl+D" \ -underline 0 -icon $icon(back) .mbar.bmarks add -text "Subscribe to This Page..." \ -underline 4 -icon $icon(forward) .mbar.bmarks add -text "Bookmark All Tabs" \ -underline 5 -icon $icon(home) .mbar.bmarks add -text "Organize Bookmarks" \ -underline 0 .mbar.bmarks add -type separator .mbar.bmarks add -type cascade -text "Bookmarks Toolbar" \ -underline 10 .mbar.bmarks add -type separator .mbar.bmarks add -type cascade -text "Recently Bookmarked" \ -underline 10 .mbar.bmarks add -type cascade -text "Recent Tags" \ -underline 10 .mbar.bmarks add -type separator .mbar.bmarks add -text "Page 1" \ -underline 10 .mbar.bmarks add -text "Page 2" \ -underline 10 .mbar add \ -text "Tools" \ -underline 0 \ -menuanchor nw \ -menu .mbar.tools blt::combomenu .mbar.tools \ -width -600 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.tools add -text "Web Search" -accelerator "Ctrl+K" \ -underline 0 .mbar.tools add -type separator .mbar.tools add -text "Downloads" -accelerator "Ctrl+Y" \ -underline 4 -icon $icon(forward) .mbar.tools add -text "Add-ons" -underline 0 .mbar.tools add -type separator .mbar.tools add -text "PDF Download - Options" -underline 0 .mbar.tools add -text "Save Images From Tabs" -underline 10 .mbar.tools add -text "Error Console" \ -accelerator "Ctrl+Shift+J" -underline 10 .mbar.tools add -text "Adblock Plus Preferences..." \ -accelerator "Ctrl+Shift+E" -underline 10 .mbar.tools add -text "Page Info" \ -accelerator "Ctrl+I" -underline 10 .mbar.tools add -type separator .mbar.tools add -text "Clear Private Data" \ -accelerator "Ctrl+Shift+Del" -underline 10 .mbar.tools add -text "Batch Download Settings" \ -underline 10 .mbar add \ -text "Help" \ -underline 0 \ -menuanchor nw \ -menu .mbar.help blt::combomenu .mbar.help \ -width -600 -font "Arial 10 bold" -acceleratorfont "Arial 10 bold" \ -bg grey85 -relief raised -bd 1 .mbar.help add -text "Help Contents" \ -underline 0 -icon $icon(back) .mbar.help add -text "Release Notes" \ -underline 4 -icon $icon(forward) .mbar.help add -text "Report Broken Website..." \ -underline 5 -icon $icon(home) .mbar.help add -text "Report Web Forgery..." \ -underline 0 .mbar.help add -type separator .mbar.help add -text "Check For Updates..." \ -underline 0 .mbar.help add -text "About..." \ -underline 0 canvas .c blt::table . \ 0,0 .mbar -fill x \ 1,0 .c -fill both blt::table configure . r0 -resize none blt::table configure . r1 -resize expand ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/picture5.tcl����������������������������������������������������������������0000644�0001750�0001750�00000000142�11462120062�015606� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� set img [image create picture] $img import ps -file sc.ps -dpi 600 $img export png -file sc2.png ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/busy1.tcl�������������������������������������������������������������������0000755�0001750�0001750�00000014006�11462120062�015120� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set image [image create picture -file images/tan_paper.gif] #set normalBg [blt::bgpattern create tile -image $image] set normalBg [blt::bgpattern create texture -high grey95 -low grey90] set activeBg [blt::bgpattern create texture -high red1 -low red2] #set normalBg grey80 #set normalBg grey80 #set activeBg grey70 # # Script to test the "busy" command. # # # General widget class resource attributes # option add *Button.padX 10 option add *Button.padY 2 option add *Scale.relief sunken #option add *Scale.orient horizontal option add *Entry.relief sunken option add *borderWidth 1 set visual [winfo screenvisual .] if { $visual == "staticgray" || $visual == "grayscale" } { set activeBg black set normalBg white set bitmapFg black set bitmapBg white option add *f1.background white } else { # set activeBg red set bitmapFg blue set bitmapBg green option add *Button.background khaki2 option add *Button.activeBackground khaki1 option add *Frame.background khaki2 option add *releaseButton.background limegreen option add *releaseButton.activeBackground springgreen option add *releaseButton.foreground black option add *holdButton.background red option add *holdButton.activeBackground pink option add *holdButton.foreground black option add *f1.background springgreen } # # Instance specific widget options # option add *f1.relief sunken option add *f1.background $normalBg option add *testButton.text "Test" option add *quitButton.text "Quit" option add *newButton.text "New\nButton" option add *holdButton.text "Hold" option add *releaseButton.text "Release" option add *buttonLabel.text "Buttons" option add *entryLabel.text "Entries" option add *scaleLabel.text "Scales" option add *textLabel.text "Text" bind keepRaised <Visibility> { raise %W } proc KeepRaised { w } { bindtags $w keepRaised } # # This never gets used; it's reset by the Animate proc. It's # here to just demonstrate how to set busy window options via # the host window path name # #option add *f1.busyCursor bogosity # # Counter for new buttons created by the "New button" button # set numWin 0 # # Create two frames. The top frame will be the host window for the # busy window. It'll contain widgets to test the effectiveness of # the busy window. The bottom frame will contain buttons to # control the testing. # blt::tk::frame .f1 -bg $normalBg blt::tk::frame .f2 -bg $normalBg # # Create some widgets to test the busy window and its cursor # label .buttonLabel blt::tk::button .testButton -command { puts stdout "Not busy." } blt::tk::button .quitButton -command { exit } entry .entry scale .scale text .text -width 20 -height 4 # # The following buttons sit in the lower frame to control the demo # blt::tk::button .newButton -command { global numWin incr numWin set name button#${numWin} blt::tk::button .f1.$name -text "$name" \ -command [list .f1 configure -bg blue] blt::table .f1 \ .f1.$name $numWin+3,0 -padx 10 -pady 10 } blt::tk::button .holdButton -command { if { [blt::busy isbusy .f1] == "" } { global activeBg .f1 configure -bg $activeBg } blt::busy .f1 focus -force . } blt::tk::button .releaseButton -command { if { [blt::busy isbusy .f1] == ".f1" } { blt::busy release .f1 } global normalBg .f1 configure -bg $normalBg } # # Notice that the widgets packed in .f1 and .f2 are not their children # blt::table .f1 \ 0,0 .testButton \ 1,0 .scale -fill y \ 0,1 .entry -fill x \ 1,1 .text -fill both \ 2,0 .quitButton -cspan 2 blt::table .f2 \ 0,0 .holdButton \ 0,1 .releaseButton \ 0,2 .newButton blt::table configure .f1 \ .testButton .scale .entry .quitButton -padx 10 -pady 10 blt::table configure .f2 \ .newButton .holdButton .releaseButton -padx 10 -pady 4 -reqwidth 1.i blt::table configure .f1 r0 r2 -resize none blt::table configure .f2 r* -resize none # # Finally, realize and map the top level window # blt::table . \ 0,0 .f1 -fill both \ 1,0 .f2 -fill both blt::table configure . r1 -resize none blt::table configure .f1 c1 -weight 2.0 # Initialize a list of bitmap file names which make up the animated # fish cursor. The bitmap mask files have a "m" appended to them. set bitmapList { left left1 mid right1 right } # # Simple cursor animation routine: Uses the "after" command to # circulate through a list of cursors every 0.075 seconds. The # first pass through the cursor list may appear sluggish because # the bitmaps have to be read from the disk. Tk's cursor cache # takes care of it afterwards. # proc StartAnimation { widget count } { global bitmapList set prefix bitmaps/fish/[lindex $bitmapList $count] set cursor [list @${prefix}.xbm ${prefix}m.xbm blue green ] blt::busy configure $widget -cursor $cursor incr count set limit [llength $bitmapList] if { $count >= $limit } { set count 0 } global afterId set afterId($widget) [after 125 StartAnimation $widget $count] } proc StopAnimation { widget } { global afterId after cancel $afterId($widget) } proc TranslateBusy { window } { set widget [string trimright $window "_Busy"] if { $widget != "." } { set widget [string trimright $widget "."] } return $widget } if { [info exists tcl_platform] && $tcl_platform(platform) == "unix" } { bind Busy <Map> { StartAnimation [TranslateBusy %W] 0 } bind Busy <Unmap> { StopAnimation [TranslateBusy %W] } } # # For testing, allow the top level window to be resized # wm min . 0 0 # # Force the demo to stay raised # raise . KeepRaised . bind .f1 <Enter> { puts stderr "Entering %W" } bind .f1 <Leave> { puts stderr "Leaving %W" } bind .f1 <B1-Leave> { puts stderr "B1 Leaving %W" } bind .f1 <B1-Enter> { puts stderr "B1 Entering %W" } bind .f1 <Motion> { puts stderr "Motion %W" } .testButton configure -font "{San Serif} 6" puts stderr [.testButton configure] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/paneset1.tcl����������������������������������������������������������������0000644�0001750�0001750�00000001002�11462120062�015562� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������package require BLT source scripts/demo.tcl blt::paneset .ps -bg grey -width 800 \ -sashthickness 3 -background red \ -sashborderwidth 1 -sashrelief sunken \ -sashpad 1 blt::graph .ps.g -bg \#CCCCFF ;#-width 300 blt::barchart .ps.b -bg \#FFCCCC ;# -width 300 blt::barchart .ps.b2 -bg \#CCFFCC ;#-width 300 .ps add -window .ps.g -fill both .ps add -window .ps.b -fill both .ps add -window .ps.b2 -fill both focus .ps blt::table . \ 0,0 .ps -fill both blt::table configure . r1 -resize none ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/treeview3.tcl���������������������������������������������������������������0000644�0001750�0001750�00000002547�11462120062�015776� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT #source scripts/demo.tcl set saved [pwd] #blt::bltdebug 100 blt::treeview .tv \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } scrollbar .vs -orient vertical -command { .tv yview } scrollbar .hs -orient horizontal -command { .tv xview } blt::table . \ 0,0 .tv -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x blt::table configure . c1 r1 -resize none proc DoFind { entry } { global fileList lappend fileList $entry #puts "$entry" if { [file type $entry] == "directory" } { foreach f [lsort [glob -nocomplain $entry/*]] { DoFind $f } } } proc Find { dir } { global fileList set fileList {} DoFind $dir return $fileList } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath .] set trim "$top" .tv configure -separator "/" -autocreate yes -trim $trim .tv entry configure root -label "$top" .tv configure -bg white -alternatebackground grey95 set fileList [Find $top] eval .tv insert end $fileList #.tv insert 0 fred focus .tv set nodes [.tv find -glob -name *.tcl] set img [image create picture -file ~/lines.gif] eval .tv entry configure $nodes -foreground red -icons $img set img [image create picture -file ~/cartoon.png] .tv entry configure 1 -icon $img cd $saved ���������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/treeview2.tcl���������������������������������������������������������������0000644�0001750�0001750�00000012012�11462120062�015761� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish set count 0 package require BLT #source scripts/demo.tcl proc SortColumn { column } { set old [.t sort cget -column] set decreasing 0 if { "$old" == "$column" } { set decreasing [.t sort cget -decreasing] set decreasing [expr !$decreasing] } .t sort configure -decreasing $decreasing -column $column -mode integer if { ![.t cget -flat] } { .t configure -flat yes } .t sort auto yes blt::busy hold .t update blt::busy release .t } proc FormatSize { size } { set string "" while { $size > 0 } { set rem [expr $size % 1000] set size [expr $size / 1000] if { $size > 0 } { set rem [format "%03d" $rem] } if { $string != "" } { set string "$rem,$string" } else { set string "$rem" } } return $string } array set modes { 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } proc FormatMode { mode } { global modes set mode [format %o [expr $mode & 07777]] set owner $modes([string index $mode 0]) set group $modes([string index $mode 1]) set world $modes([string index $mode 2]) return "${owner}${group}${world}" } proc Find { tree parent dir } { global count set saved [pwd] cd $dir foreach f [lsort [glob -nocomplain *]] { set name [file tail $f] if { [catch { file lstat $f info }] != 0 } { if { ![$tree exists $parent->"$name"] } { set node [$tree insert $parent -label $name] } } else { if 0 { if { $info(type) == "file" } { set info(type) [list @blt::TreeView::openIcon $name] } else { set info(type) "@blt::TreeView::openIcon " } } set info(mtime) [clock format $info(mtime) -format "%b %d, %Y"] set info(atime) [clock format $info(atime) -format "%b %d, %Y"] set info(ctime) [clock format $info(ctime) -format "%b %d, %Y"] set info(owner) [file attributes $name -owner] set info(group) [file attributes $name -group] set info(size) [FormatSize $info(size)] set info(mode) [file attributes $name -permissions] if { ![$tree exists $parent->"$name"] } { set node [$tree insert $parent -label $name \ -data [array get info]] } else { set node [$tree findchild $parent $name] puts "already found $f" } } incr count if { [file type $f] == "directory" } { .t entry configure $node -button yes } } cd $saved } proc GetAbsolutePath { dir } { set saved [pwd] cd $dir set path [pwd] cd $saved return $path } set top [GetAbsolutePath .] set trim "$top" set tree [blt::tree create] scrollbar .vs -orient vertical -command { .t yview } scrollbar .hs -orient horizontal -command { .t xview } proc OpenNode { tree node parent top } { if { [file type $parent] == "directory" } { blt::busy hold .t Find $tree $node $top/$parent update blt::busy release .t } } proc CloseNode { tree node } { eval $tree delete [$tree children $nodex] } blt::treeview .t \ -width 0 \ -yscrollcommand { .vs set } \ -xscrollcommand { .hs set } \ -selectmode multiple \ -separator / \ -tree $tree \ -opencommand [list OpenNode $tree %\# %P $top] \ -closecommand [list CloseNode $tree %\#] set img [image create picture -data { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM1WBrM+rAEMigJ8c3Kb3OSII6kGABhp1JnaK1VGwjwKwtvHqNzzd263M3H4n2OH1QBwGw6 nQkAOw== }] update .t column configure treeView -text "" #file .t column insert 0 mtime atime ctime .t column insert end nlink mode type owner group ino size dev .t column configure owner .t column configure mtime -hide no .t column configure size group nlink owner ino dev -justify left -edit yes .t column configure size type -justify left -edit yes .t column configure treeView -hide no -edit no -icon $img focus .t blt::table . \ 0,0 .t -fill both \ 0,1 .vs -fill y \ 1,0 .hs -fill x blt::table configure . c1 r1 -resize none puts "$count entries" #$tree find root -glob *.c -addtag "c_files" #$tree find root -glob *.h -addtag "header_files" #$tree find root -glob *.tcl -addtag "tcl_files" #.t entry configure "c_files" -foreground green4 #.t entry configure "header_files" -foreground cyan4 #.t entry configure "tcl_files" -foreground red4 .t column bind all <ButtonRelease-3> { %W configure -flat no } foreach column [.t column names] { .t column configure $column -command [list SortColumn $column] } # Create a second treeview that shares the same tree. if 0 { toplevel .top blt::treeview .top.t2 -tree $tree -yscrollcommand { .top.sbar set } scrollbar .top.sbar -command { .top.t2 yview } pack .top.t2 -side left -expand yes -fill both pack .top.sbar -side right -fill y } #.t style configure text -background #F8fbF8 -selectbackground #D8fbD8 .t style checkbox check \ -onvalue 30 -offvalue "50" \ -showvalue yes .t style combobox combo -icon $img #.t column configure owner -style combo #.t column configure group -style check ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/pushbutton1.tcl�������������������������������������������������������������0000644�0001750�0001750�00000001510�11462120062�016342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT blt::tk::pushbutton .p -text "Push" pack .p -side top set onFile ~/r7/rappture/gui/scripts/images/zoom-in.png set offFile ~/r7/rappture/gui/scripts/images/zoom-out.png set on [image create picture -file $onFile] set off [image create picture -file $offFile] blt::tk::pushbutton .p1 -variable "test" -onvalue 1 \ -onimage $on -offimage $off blt::tk::pushbutton .p2 -text "Push 2" -variable "test" -onvalue 2 blt::tk::pushbutton .p3 -text "Push 3" -variable "test" -onvalue 3 blt::tk::pushbutton .p4 -text "Push 4" -variable "test" -onvalue 4 blt::tk::pushbutton .p5 -text "Push 5" -variable "test" -onvalue 5 pack .p1 .p2 .p3 .p4 .p5 -side top blt::tk::button .b -text "Query" -command { puts stderr variable=[set [.p cget -variable]] puts stderr test=$test } pack .b puts stderr class=[winfo class .p1] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/stripchart2.tcl�������������������������������������������������������������0000755�0001750�0001750�00000027021�11462120062�016323� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl # ---------------------------------------------------------------------- # EXAMPLE: simple driver for stripchart widget # ---------------------------------------------------------------------- # Michael J. McLennan # mmclennan@lucent.com # Bell Labs Innovations for Lucent Technologies # ====================================================================== # Copyright (c) 1996 Lucent Technologies # ====================================================================== #option add *x.range 20.0 option add *Axis.tickDefault 4 option add *Axis.tickLength 5 option add *Axis.tickInterior yes option add *Axis.GridLines yes #option add *x.shiftBy 15.0 option add *bufferElements no option add *bufferGraph no option add *symbol triangle option add *Axis.lineWidth 1 #option add *Axis*Rotate 90 option add *pixels 1.25m #option add *PlotPad 25 option add *Stripchart.width 6i #option add *Smooth quadratic #option add *Stripchart.invertXY yes #option add *x.descending yes # ---------------------------------------------------------------------- # USAGE: random ?<max>? ?<min>? # # Returns a random number in the range <min> to <max>. # If <min> is not specified, the default is 0; if max is not # specified, the default is 1. # ---------------------------------------------------------------------- proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed 14823 # ---------------------------------------------------------------------- toplevel .addSource wm title .addSource "Add Source" wm group .addSource . wm withdraw .addSource wm protocol .addSource WM_DELETE_WINDOW {.addSource.controls.cancel invoke} frame .addSource.info pack .addSource.info -expand yes -fill both -padx 4 -pady 4 label .addSource.info.namel -text "Name:" entry .addSource.info.name label .addSource.info.maxl -text "Maximum:" entry .addSource.info.max label .addSource.info.minl -text "Minimum:" entry .addSource.info.min blt::table .addSource.info \ .addSource.info.namel 0,0 -anchor e \ .addSource.info.name 0,1 -fill x \ .addSource.info.maxl 1,0 -anchor e \ .addSource.info.max 1,1 -fill x \ .addSource.info.minl 2,0 -anchor e \ .addSource.info.min 2,1 -fill x frame .addSource.color pack .addSource.color -padx 8 -pady 4 frame .addSource.color.sample \ -width 30 -height 30 \ -borderwidth 2 -relief raised pack .addSource.color.sample -side top -fill both scale .addSource.color.r -label "Red" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.r -side left -fill y scale .addSource.color.g -label "Green" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.g -side left -fill y scale .addSource.color.b -label "Blue" -orient vertical \ -from 100 -to 0 -command source_color pack .addSource.color.b -side left -fill y proc source_color {args} { set r [expr round(2.55*[.addSource.color.r get])] set g [expr round(2.55*[.addSource.color.g get])] set b [expr round(2.55*[.addSource.color.b get])] set color [format "#%2.2x%2.2x%2.2x" $r $g $b] .addSource.color.sample configure -background $color } source_color frame .addSource.sep -borderwidth 1 -height 2 -relief sunken pack .addSource.sep -fill x -pady 4 frame .addSource.controls pack .addSource.controls -fill x -padx 4 -pady 4 button .addSource.controls.ok -text "OK" -command { wm withdraw .addSource set name [.addSource.info.name get] set color [.addSource.color.sample cget -background] set max [.addSource.info.max get] set min [.addSource.info.min get] if {[catch {source_create $name $color $min $max} err] != 0} { puts "error: $err" } } pack .addSource.controls.ok -side left -expand yes -padx 4 button .addSource.controls.cancel -text "Cancel" -command { wm withdraw .addSource } pack .addSource.controls.cancel -side left -expand yes -padx 4 set useAxes y proc source_create {name color min max} { global sources if {[info exists sources($name-controls)]} { error "source \"$name\" already exists" } if {$max <= $min} { error "bad range: $min - $max" } set unique 0 set win ".sources.nb.s[incr unique]" while {[winfo exists $win]} { set win ".sources.nb.s[incr unique]" } set xvname "xvector$unique" set yvname "yvector$unique" set wvname "wvector$unique" global $xvname $yvname $wvname blt::vector $xvname $yvname $wvname if {$xvname == "xvector1"} { $xvname append 0 } else { xvector1 variable thisVec $xvname append $thisVec(end) } $yvname append [random $max $min] $wvname append 0 blt::bitmap define pattern1 { {4 4} {01 02 04 08} } catch {.sc element delete $name} #set style [blt::bgpattern create solid -bg $color -opacity 90.0] .sc bar create $name \ -x $xvname \ -y $yvname \ -outline $color -fill $color if { $name != "default" } { .sc axis create $name \ -loose yes \ -title $name \ -grid yes \ -rotate 0 \ -limitscolor $color \ -limitsformat "%4.4g" \ -titlecolor ${color} .sc element configure $name -mapy $name global useAxes lappend useAxes $name set count 0 if 0 { set yUse $useAxes set y2Use {} foreach axis $useAxes { if { $count & 1 } { lappend yUse $axis .sc axis configure $axis -rotate 90 } else { lappend y2Use $axis .sc axis configure $axis -rotate -90 } incr count } .sc y2axis use $y2Use .sc yaxis use $yUse } else { .sc yaxis use $useAxes #.sc yaxis use $useAxes } } set cwin .sources.choices.rb$unique radiobutton $cwin -text $name \ -variable choices -value $win -command " foreach w \[pack slaves .sources.nb\] { pack forget \$w } pack $win -fill both " pack $cwin -anchor w frame $win pack $win -fill x label $win.limsl -text "Limits:" entry $win.lims bind $win.lims <KeyPress-Return> " .sc yaxis configure -limits {%%g} " label $win.smoothl -text "Smooth:" frame $win.smooth radiobutton $win.smooth.linear -text "Linear" \ -variable smooth -value linear -command " .sc element configure $name -smooth linear " pack $win.smooth.linear -side left radiobutton $win.smooth.step -text "Step" \ -variable smooth -value step -command " .sc element configure $name -smooth step " pack $win.smooth.step -side left radiobutton $win.smooth.natural -text "Natural" \ -variable smooth -value natural -command " .sc element configure $name -smooth natural " pack $win.smooth.natural -side left label $win.ratel -text "Sampling Rate:" scale $win.rate -orient horizontal -from 10 -to 1000 blt::table $win \ $win.smoothl 0,0 -anchor e \ $win.smooth 0,1 -fill x -padx 4 \ $win.limsl 1,0 -anchor e \ $win.lims 1,1 -fill x -padx 4 \ $win.ratel 2,0 -anchor e \ $win.rate 2,1 -fill x -padx 2 if {$unique != 1} { button $win.del -text "Delete" -command [list source_delete $name] pack $win.del -anchor w blt::table $win $win.del 3,1 -anchor e -padx 4 -pady 4 } $win.rate set 1000 catch {$win.smooth.[.sc element cget $name -smooth] invoke} mesg set sources($name-choice) $cwin set sources($name-controls) $win set sources($name-stream) [after 100 [list source_event $name 10]] set sources($name-x) $xvname set sources($name-y) $yvname set sources($name-w) $wvname set sources($name-max) $max set sources($name-min) $min set sources($name-steady) [random $max $min] $cwin invoke } proc source_delete {name} { global sources after cancel $sources($name-stream) destroy $sources($name-choice) destroy $sources($name-controls) unset sources($name-controls) set first [lindex [pack slaves .sources.choices] 0] $first invoke } proc source_event {name delay} { global sources set xv $sources($name-x) set yv $sources($name-y) set wv $sources($name-w) global $xv $yv $wv $xv variable x # set x(++end) [expr $x(end) + 0.001 * $delay] set x(++end) [expr round($x(end) + 1)] $yv variable y if {[random] > 0.97} { set y(++end) [random $sources($name-max) $sources($name-min)] } else { set y(++end) [expr $y(end)+0.1*($sources($name-steady)-$y(end))] } set val [random] if {$val > 0.95} { $wv append 2 } elseif {$val > 0.8} { $wv append 1 } else { $wv append 0 } #$wv notify now if { [$xv length] > 100 } { $xv delete 0 $yv delete 0 $wv delete 0 } update set win $sources($name-controls) set delay [$win.rate get] set sources($name-stream) [after $delay [list source_event $name $delay]] } # ---------------------------------------------------------------------- frame .mbar -borderwidth 2 -relief raised pack .mbar -fill x menubutton .mbar.main -text "Main" -menu .mbar.main.m pack .mbar.main -side left -padx 4 menu .mbar.main.m .mbar.main.m add command -label "Add Source..." -command { set x [expr [winfo rootx .]+50] set y [expr [winfo rooty .]+50] wm geometry .addSource +$x+$y wm deiconify .addSource } .mbar.main.m add separator .mbar.main.m add command -label "Quit" -command exit menubutton .mbar.prefs -text "Preferences" -menu .mbar.prefs.m pack .mbar.prefs -side left -padx 4 menu .mbar.prefs.m .mbar.prefs.m add cascade -label "Warning Symbol" -menu .mbar.prefs.m.wm menu .mbar.prefs.m.wm .mbar.prefs.m add cascade -label "Error Symbol" -menu .mbar.prefs.m.em menu .mbar.prefs.m.em foreach sym {square circle diamond plus cross triangle} { .mbar.prefs.m.wm add radiobutton -label $sym \ -variable warningsym -value $sym \ -command {.sc pen configure "warning" -symbol $warningsym} .mbar.prefs.m.em add radiobutton -label $sym \ -variable errorsym -value $sym \ -command {.sc pen configure "error" -symbol $errorsym} } catch {.mbar.prefs.m.wm invoke "circle"} catch {.mbar.prefs.m.em invoke "cross"} # ---------------------------------------------------------------------- blt::stripchart .sc -title "Stripchart" -stackaxes yes -invert no \ -bufferelements no -buffergraph no pack .sc -expand yes -fill both .sc xaxis configure -title "Time (s)" -autorange 20.0 -shiftby 15 .sc yaxis configure -title "Samples" frame .sources frame .sources.nb -borderwidth 2 -relief sunken label .sources.title -text "Sources:" frame .sources.choices -borderwidth 2 -relief groove if 0 { pack .sources -fill x -padx 10 -pady 4 pack .sources.nb -side right -expand yes -fill both -padx 4 -pady 4 pack .sources.title -side top -anchor w -padx 4 pack .sources.choices -expand yes -fill both -padx 4 -pady 4 } source_create default red 0 10 source_create temp blue3 0 10 source_create pressure green3 0 200 source_create volume orange3 0 1020 source_create power purple 0 0.01999 source_create work magenta3 0 10 Blt_ZoomStack .sc .sc axis bind all <Enter> { %W axis activate [%W axis get current] } .sc axis bind all <Leave> { %W axis deactivate [%W axis get current] } .sc axis bind Y <ButtonPress-1> { set axis [%W axis get current] %W axis configure $axis -logscale yes } .sc axis bind Y <ButtonPress-3> { set axis [%W axis get current] %W axis configure $axis -logscale no } after 5000 { puts stderr "printing stripchart" .sc postscript output sc.ps } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/winop4.tcl������������������������������������������������������������������0000644�0001750�0001750�00000003545�11462120062�015300� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl set filter sinc set shadow 8 #set imgfile ./images/sample.gif set imgfile ./images/blt98.gif #set imgfile ~/.icons/cd-player.xpm if { [llength $argv] > 0 } { set imgfile [lindex $argv 0] } if { [ file exists $imgfile] } { set src [image create picture -file $imgfile] } else { puts stderr "no image file" exit 0 } set name [file root [file tail $imgfile]] set width [image width $src] set height [image height $src] set bg [image create picture \ -width [expr $width + $shadow] \ -height [expr $height + $shadow]] $bg blank white $bg draw rectangle 4 4 [expr $width - 4] [expr $height - 4] -thickness 0 -color grey60 puts stderr "blur=[time {$bg blur $bg 8}]" #puts stderr "resample=[time {$bg resize $bg -filter gi8}]" #$bg copy $src set src $bg #$src blur $src 8 option add *Label.font *helvetica*10* option add *Label.background white label .l0 -image $src label .header0 -text "$width x $height" label .footer0 -text "100%" . configure -bg white set iw $width set ih $height set dest [image create picture -width $iw -height $ih] $dest resize $src -filter $filter label .header -text "$iw x $ih" label .footer -text "$filter" label .l1 -image $dest set filters { "bell" "bessel" "box" "bspline" "catrom" "default" "dummy" "gauss8" "gaussian" "gi" "lanczos3" "mitchell" "none" "sinc" "tent" "triangle" } proc Doit { filter } { global dest src set time [time {$dest resize $src -filter $filter}] .footer configure -text $time } set i 0 frame .f foreach f $filters { radiobutton .f.$f -variable filter -value $f -text $f \ -command "Doit $f" blt::table .f $i,0 .f.$f -anchor w incr i } blt::table . \ 0,0 .f -rspan 3 \ 0,1 .header \ 1,1 .l0 1,2 .l1 \ 2,1 .footer �����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/filmstrip1.tcl��������������������������������������������������������������0000644�0001750�0001750�00000002207�11462120062�016144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� package require BLT source scripts/demo.tcl set pictures [glob -nocomplain "*.jpg"] set autocolors { #0000cd #cd0000 #00cd00 #3a5fcd #cdcd00 #cd1076 #009acd #00c5cd #a2b5cd #7ac5cd #66cdaa #a2cd5a #cd9b9b #cdba96 #cd3333 #cd6600 #cd8c95 #cd00cd #9a32cd #6ca6cd #9ac0cd #9bcd9b #00cd66 #cdc673 #cdad00 #cd5555 #cd853f #cd7054 #cd5b45 #cd6889 #cd69c9 #551a8b } #blt::debug 100 proc Move { w pane } { # puts stderr "w=$w pane=$pane" .ss.fs see $pane } blt::scrollset .ss \ -xviewcommand { .ss.fs view } \ -xscrollbar .ss.xs \ -window .ss.fs blt::filmstrip .ss.fs -width 600 \ -scrolldelay 10 -scrollincrement 30 -animate yes \ -scrollcommand { .ss set x } blt::tk::scrollbar .ss.xs -orient horizontal -command { .ss xview } for { set i 0 } { $i < 32 } { incr i } { set color [lindex $autocolors $i] set g .ss.fs.g$i blt::graph $g -bg $color -width 500 set pane [.ss.fs add -window $g -fill x -showhandle yes] bind $g <ButtonPress-1> [list Move %W $pane] bind $g <ButtonPress-2> [list Move %W 0] bind $g <ButtonPress-3> [list Move %W end] } blt::table . \ 0,0 .ss -fill both focus .ss.fs �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/dnd2.tcl��������������������������������������������������������������������0000755�0001750�0001750�00000020652�11462120062�014710� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!../src/bltwish package require BLT source scripts/demo.tcl if { ([info exists tcl_platform]) && ($tcl_platform(platform) == "windows") } { error "This script works only under X11" } canvas .c -width 320 -height 320 -background white blt::table . .c -fill both set lastCell "" set cellWidth 1 set cellHeight 1 proc RedrawWorld { canvas } { global cells cellWidth cellHeight $canvas delete all set width [winfo width $canvas] set height [winfo height $canvas] set cellWidth [expr $width / 8] set cellHeight [expr $height / 8] for { set row 0 } { $row < 8 } { incr row } { set y [expr $row * $cellHeight] set h [expr $y + $cellHeight] for { set column 0 } { $column < 8 } { incr column } { set x [expr $column * $cellWidth] set w [expr $x + $cellWidth] $canvas create rectangle $x $y $w $h -fill white -outline "" \ -tags "$row,$column" } } for { set row 0 } { $row < 8 } { incr row } { set y [expr $row * $cellHeight] $canvas create line 0 $y $width $y } for { set column 0 } { $column < 8 } { incr column } { set x [expr $column * $cellWidth] $canvas create line $x 0 $x $height } foreach name [array names cells] { set rc [split $name ,] set row [lindex $rc 0] set column [lindex $rc 1] set x [expr ($column * $cellWidth) + 5] set y [expr ($row * $cellHeight) + 5] set w [expr $cellWidth - 10] set h [expr $cellHeight - 10] set color [lindex $cells($name) 0] set type [lindex $cells($name) 1] set pi1_2 [expr 3.14159265358979323846/180.0] set points {} switch $type { hexagon { lappend points $x [expr $y + $h/2] [expr $x + $w * 1/3] \ $y [expr $x + $w * 2/3] $y [expr $x + $w] [expr $y + $h/2] \ [expr $x + $w * 2/3] [expr $y + $h] \ [expr $x + $w * 1/3] [expr $y + $h] } parallelogram { lappend points $x [expr $y + $h * 2/3] \ [expr $x + $w * 2/3] $y \ [expr $x + $w] [expr $y + $h * 1/3] \ [expr $x + $w * 1/3] [expr $y + $h] } triangle { lappend points \ $x [expr $y + $h] \ [expr $x + $w * 1/2] $y \ [expr $x + $w] [expr $y + $h] } } eval .c create polygon $points -fill $color -outline black } } bind .c <Configure> { RedrawWorld %W } # ---------------------------------------------------------------------- # USAGE: random ?<max>? ?<min>? # # Returns a random number in the range <min> to <max>. # If <min> is not specified, the default is 0; if max is not # specified, the default is 1. # ---------------------------------------------------------------------- proc random {{max 1.0} {min 0.0}} { global randomSeed set randomSeed [expr (7141*$randomSeed+54773) % 259200] set num [expr $randomSeed/259200.0*($max-$min)+$min] return $num } set randomSeed [clock clicks] set itemTypes { parallelogram hexagon triangle } set itemTypes { hexagon triangle parallelogram } for { set i 0 } { $i < 20 } { incr i } { while { 1 } { set row [expr int([random 8])] set column [expr int([random 8])] set type [expr int([random 3])] set type [lindex $itemTypes $type] if { ![info exists cells($row,$column)] } { set r [expr int([random 256 128])] set g [expr int([random 256 128])] set b [expr int([random 256 128])] set cells($row,$column) [format "#%.2x%.2x%.2x %s" $r $g $b $type] break } } } proc ScreenToCell { widget x y } { global cellWidth cellHeight set column [expr $x / $cellWidth] set row [expr $y / $cellHeight] return $row,$column } set count 0 foreach i [winfo interps] { puts $i if { [string match "dnd2.tcl*" $i] } { incr count } } if { $count == 1 } { toplevel .info raise .info text .info.text -width 65 -height 12 -font { Helvetica 10 } -bg white \ -tabs { 0.25i } .info.text insert end { This is a more involved example of the new "dnd" command. Run this script again to get another window. You can then drag and drop symbols between the windows by clicking with the left mouse button on a symbol. It demonstates how to o Drag-and-drop on specific areas (canvas items) of a widget. o How to receive and handle Enter/Leave/Motion events in the target. o How to send drag feedback to the source. o Use a drag threshold. } button .info.quit -text "Dismiss" -command { destroy .info } blt::table .info \ 0,0 .info.text -fill both \ 1,0 .info.quit } # ----------------------------------------------------------------- # # Setup finished. Start of drag-and-drop code here. # # Set up the entire canvas as a drag&drop source. blt::dnd register .c -source yes -dragthreshold 5 -button 1 # Register code to pick up the information about a canvas item blt::dnd getdata .c color GetColor proc GetColor { widget args } { array set info $args global itemInfo set id $itemInfo($info(timestamp)) set color [$widget itemcget $id -fill] set ncoords [llength [$widget coords $id]] if { $ncoords == 6 } { set type triangle } elseif { $ncoords == 8 } { set type parallelogram } elseif { $ncoords == 12 } { set type hexagon } else { error "unknown type n=$ncoords" } return [list $color $type] } blt::dnd configure .c -package PackageSample proc PackageSample { widget args } { array set info $args # Check if we're over a canvas item set items [$widget find overlapping $info(x) $info(y) $info(x) $info(y)] set pickedItem "" foreach i $items { if { [$widget type $i] == "polygon" } { set pickedItem $i break } } if { $pickedItem == "" } { # Cancel the drag puts "Cancel the drag x=$info(x) y=$info(y)" return 0 } set fill [$widget itemcget $pickedItem -fill] set outline [$widget itemcget $pickedItem -outline] set ncoords [llength [$widget coords $pickedItem]] if { $ncoords == 6 } { set type triangle } elseif { $ncoords == 8 } { set type parallelogram } elseif { $ncoords == 12 } { set type hexagon } else { error "unknown type n=$ncoords" } set tag [ScreenToCell $widget $info(x) $info(y)] $info(token).label configure -background $fill -foreground $outline \ -text $type update idletasks update global itemInfo set itemInfo($info(timestamp)) $pickedItem return 1 } # Configure a set of animated cursors. blt::dnd configure .c -cursors { { @bitmaps/hand/hand01.xbm bitmaps/hand/hand01m.xbm black white } { @bitmaps/hand/hand02.xbm bitmaps/hand/hand02m.xbm black white } { @bitmaps/hand/hand03.xbm bitmaps/hand/hand03m.xbm black white } { @bitmaps/hand/hand04.xbm bitmaps/hand/hand04m.xbm black white } { @bitmaps/hand/hand05.xbm bitmaps/hand/hand05m.xbm black white } { @bitmaps/hand/hand06.xbm bitmaps/hand/hand06m.xbm black white } { @bitmaps/hand/hand07.xbm bitmaps/hand/hand07m.xbm black white } { @bitmaps/hand/hand08.xbm bitmaps/hand/hand08m.xbm black white } { @bitmaps/hand/hand09.xbm bitmaps/hand/hand09m.xbm black white } { @bitmaps/hand/hand10.xbm bitmaps/hand/hand10m.xbm black white } { @bitmaps/hand/hand11.xbm bitmaps/hand/hand11m.xbm black white } { @bitmaps/hand/hand12.xbm bitmaps/hand/hand12m.xbm black white } { @bitmaps/hand/hand13.xbm bitmaps/hand/hand13m.xbm black white } { @bitmaps/hand/hand14.xbm bitmaps/hand/hand14m.xbm black white } } # Create a widget to place in the drag-and-drop token set token [blt::dnd token window .c] label $token.label -bd 2 -highlightthickness 1 pack $token.label blt::dnd token configure .c \ -borderwidth 2 \ -relief raised -activerelief raised \ -outline pink -fill red \ -anchor s blt::dnd configure .c -target yes blt::dnd setdata .c color { NewObject } proc NewObject { widget args } { array set info $args set tag [ScreenToCell $widget $info(x) $info(y)] global cells if { [info exists cells($tag)] } { error "Cell already exists" } set cells($tag) $info(value) RedrawWorld $widget } blt::dnd configure .c -onmotion OnMotion -onenter OnMotion -onleave OnMotion proc OnMotion { widget args } { global cells lastCell array set info $args set tag [ScreenToCell $widget $info(x) $info(y)] if { $lastCell != "" } { $widget itemconfigure $lastCell -fill white -outline "" -width 1 \ -stipple "" } # Check that we're not over a canvas item if { ![info exists cells($tag)] } { $widget itemconfigure $tag -outline lightblue -fill lightblue \ -width 2 -stipple BLT set lastCell $tag return 1 } return 0 } ��������������������������������������������������������������������������������������./saods9/blt3.0.1/demos/cmenu.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000003412�11462120062�015160� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������set imgData { R0lGODlhEAANAMIAAAAAAH9/f///////AL+/vwAA/wAAAAAAACH5BAEAAAUALAAAAAAQAA0A AAM8WBrM+rAEQWmIb5KxiWjNInCkV32AJHRlGQBgDA7vdN4vUa8tC78qlrCWmvRKsJTquHkp ZTKAsiCtWq0JADs= } set icon [image create picture -data $imgData] set icon2 [image create picture -file images/blt98.gif] set bg [blt::bgpattern create gradient -high grey98 -low grey85 \ -dir x -jitter yes -log yes -relativeto self] blt::combomenu .m \ -bg $bg \ -textvariable myText \ -iconvariable myIcon \ -font { Arial 9 bold } \ -activebackground lightblue1 \ -acceleratorfont { Arial 8 } \ -borderwidth 2 \ -disabledforeground grey45 \ -disabledbackground grey85 \ -disabledacceleratorforeground grey45 \ -height 200 \ -relief raised #pack .m -fill both -expand yes set onOff 0 set wwho "" foreach item { Undo X1 Y1 Redo Cut Copy X2 Y2 Paste "Select All" X3 Y3 Find Replace } { set char [string range $item 0 0] .m add \ -text $item \ -type checkbutton \ -accel "Ctrl+$char" \ -underline 0 \ -tag [string tolower $char] \ -icon $icon \ -variable onOff \ -onvalue 1 -offvalue 0 -value $item } .m item configure Undo -type command .m item configure Cut -type command .m item configure Find -type cascade -state disabled .m item configure Redo -type command .m item configure Undo -type command .m item configure Paste -type separator -state disabled .m item configure x -state disabled .m item configure y -type radiobutton -variable wwho bind ComboMenu <Enter> { %W activate @%x,%y } bind ComboMenu <Leave> { %W activate "" } bind ComboMenu <Motion> { %W activate @%x,%y } bind ComboMenu <ButtonRelease-1> { %W invoke active puts text=$myText puts icon=$myIcon } bind ComboMenu <ButtonPress-1> { puts stderr [%W index next] } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/blt3.0.1/MANIFEST��������������������������������������������������������������������������0000644�0001750�0001750�00000024726�11462120062�013402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������blt2.4z blt2.4z/MANIFEST blt2.4z/INSTALL blt2.4z/cf blt2.4z/cf/config.guess blt2.4z/cf/config.sub blt2.4z/cf/install-sh blt2.4z/cf/install.sh blt2.4z/cf/ldAix blt2.4z/html blt2.4z/html/BLT.html blt2.4z/html/Makefile.vc blt2.4z/html/barchart.html blt2.4z/html/beep.html blt2.4z/html/bgexec.html blt2.4z/html/bitmap.html blt2.4z/html/bltdebug.html blt2.4z/html/busy.html blt2.4z/html/container.html blt2.4z/html/cutbuffer.html blt2.4z/html/dragdrop.html blt2.4z/html/eps.html blt2.4z/html/graph.html blt2.4z/html/hierbox.html blt2.4z/html/hiertable.html blt2.4z/html/htext.html blt2.4z/html/spline.html blt2.4z/html/stripchart.html blt2.4z/html/table.html blt2.4z/html/tabset.html blt2.4z/html/tile.html blt2.4z/html/tree.html blt2.4z/html/treeview.html blt2.4z/html/vector.html blt2.4z/html/watch.html blt2.4z/html/winop.html blt2.4z/Makefile.in blt2.4z/Makefile.vc blt2.4z/NEWS blt2.4z/PROBLEMS blt2.4z/README blt2.4z/acconfig.h blt2.4z/aclocal.m4 blt2.4z/blt.mak blt2.4z/configure blt2.4z/configure.in blt2.4z/demos blt2.4z/demos/bitmaps blt2.4z/demos/bitmaps/fish blt2.4z/demos/bitmaps/fish/left.xbm blt2.4z/demos/bitmaps/fish/left1.xbm blt2.4z/demos/bitmaps/fish/left1m.xbm blt2.4z/demos/bitmaps/fish/leftm.xbm blt2.4z/demos/bitmaps/fish/mid.xbm blt2.4z/demos/bitmaps/fish/midm.xbm blt2.4z/demos/bitmaps/fish/right.xbm blt2.4z/demos/bitmaps/fish/right1.xbm blt2.4z/demos/bitmaps/fish/right1m.xbm blt2.4z/demos/bitmaps/fish/rightm.xbm blt2.4z/demos/bitmaps/hand blt2.4z/demos/bitmaps/hand/hand01.xbm blt2.4z/demos/bitmaps/hand/hand01m.xbm blt2.4z/demos/bitmaps/hand/hand02.xbm blt2.4z/demos/bitmaps/hand/hand02m.xbm blt2.4z/demos/bitmaps/hand/hand03.xbm blt2.4z/demos/bitmaps/hand/hand03m.xbm blt2.4z/demos/bitmaps/hand/hand04.xbm blt2.4z/demos/bitmaps/hand/hand04m.xbm blt2.4z/demos/bitmaps/hand/hand05.xbm blt2.4z/demos/bitmaps/hand/hand05m.xbm blt2.4z/demos/bitmaps/hand/hand06.xbm blt2.4z/demos/bitmaps/hand/hand06m.xbm blt2.4z/demos/bitmaps/hand/hand07.xbm blt2.4z/demos/bitmaps/hand/hand07m.xbm blt2.4z/demos/bitmaps/hand/hand08.xbm blt2.4z/demos/bitmaps/hand/hand08m.xbm blt2.4z/demos/bitmaps/hand/hand09.xbm blt2.4z/demos/bitmaps/hand/hand09m.xbm blt2.4z/demos/bitmaps/hand/hand10.xbm blt2.4z/demos/bitmaps/hand/hand10m.xbm blt2.4z/demos/bitmaps/hand/hand11.xbm blt2.4z/demos/bitmaps/hand/hand11m.xbm blt2.4z/demos/bitmaps/hand/hand12.xbm blt2.4z/demos/bitmaps/hand/hand12m.xbm blt2.4z/demos/bitmaps/hand/hand13.xbm blt2.4z/demos/bitmaps/hand/hand13m.xbm blt2.4z/demos/bitmaps/hand/hand14.xbm blt2.4z/demos/bitmaps/hand/hand14m.xbm blt2.4z/demos/bitmaps/face.xbm blt2.4z/demos/bitmaps/greenback.xbm blt2.4z/demos/bitmaps/hobbes.xbm blt2.4z/demos/bitmaps/hobbes_mask.xbm blt2.4z/demos/bitmaps/sharky.xbm blt2.4z/demos/bitmaps/xbob.xbm blt2.4z/demos/Makefile.in blt2.4z/demos/Makefile.vc blt2.4z/demos/barchart1.tcl blt2.4z/demos/barchart2.tcl blt2.4z/demos/barchart3.tcl blt2.4z/demos/barchart4.tcl blt2.4z/demos/barchart5.tcl blt2.4z/demos/bgexec1.tcl blt2.4z/demos/bgexec2.tcl blt2.4z/demos/bgexec3.tcl blt2.4z/demos/bgexec4.tcl blt2.4z/demos/bgexec5.tcl blt2.4z/demos/bitmap.tcl blt2.4z/demos/bitmap2.tcl blt2.4z/demos/busy1.tcl blt2.4z/demos/busy2.tcl blt2.4z/demos/container.tcl blt2.4z/demos/container3.tcl blt2.4z/demos/dnd1.tcl blt2.4z/demos/dnd2.tcl blt2.4z/demos/dragdrop1.tcl blt2.4z/demos/dragdrop2.tcl blt2.4z/demos/eps.tcl blt2.4z/demos/graph1.tcl blt2.4z/demos/graph2.tcl blt2.4z/demos/graph3.tcl blt2.4z/demos/graph4.tcl blt2.4z/demos/graph5.tcl blt2.4z/demos/graph6.tcl blt2.4z/demos/graph7.tcl blt2.4z/demos/hierbox1.tcl blt2.4z/demos/hierbox2.tcl blt2.4z/demos/hierbox3.tcl blt2.4z/demos/hierbox4.tcl blt2.4z/demos/hiertable1.tcl blt2.4z/demos/hiertable2.tcl blt2.4z/demos/hiertable3.tcl blt2.4z/demos/htext.txt blt2.4z/demos/htext1.tcl blt2.4z/demos/spline.tcl blt2.4z/demos/stripchart1.tcl blt2.4z/demos/tabnotebook1.tcl blt2.4z/demos/tabnotebook2.tcl blt2.4z/demos/tabnotebook3.tcl blt2.4z/demos/tabset1.tcl blt2.4z/demos/tabset2.tcl blt2.4z/demos/tabset3.tcl blt2.4z/demos/tabset4.tcl blt2.4z/demos/tour.tcl blt2.4z/demos/treeview1.tcl blt2.4z/demos/winop1.tcl blt2.4z/demos/winop2.tcl blt2.4z/demos/images blt2.4z/demos/images/blt98.gif blt2.4z/demos/images/buckskin.gif blt2.4z/demos/images/chalk.gif blt2.4z/demos/images/close.gif blt2.4z/demos/images/close2.gif blt2.4z/demos/images/clouds.gif blt2.4z/demos/images/corrugated_metal.gif blt2.4z/demos/images/folder.gif blt2.4z/demos/images/jan25_palm3x_L.jpg blt2.4z/demos/images/mini-book1.gif blt2.4z/demos/images/mini-book2.gif blt2.4z/demos/images/mini-display.gif blt2.4z/demos/images/mini-doc.gif blt2.4z/demos/images/mini-filemgr.gif blt2.4z/demos/images/mini-ofolder.gif blt2.4z/demos/images/mini-windows.gif blt2.4z/demos/images/ofolder.gif blt2.4z/demos/images/open.gif blt2.4z/demos/images/open2.gif blt2.4z/demos/images/out.ps blt2.4z/demos/images/qv100.t.gif blt2.4z/demos/images/rain.gif blt2.4z/demos/images/sample.gif blt2.4z/demos/images/smblue_rock.gif blt2.4z/demos/images/stopsign.gif blt2.4z/demos/images/tan_paper.gif blt2.4z/demos/images/tan_paper2.gif blt2.4z/demos/images/txtrflag.gif blt2.4z/demos/scripts blt2.4z/demos/scripts/barchart2.tcl blt2.4z/demos/scripts/bgtest.tcl blt2.4z/demos/scripts/clone.tcl blt2.4z/demos/scripts/demo.tcl blt2.4z/demos/scripts/globe.tcl blt2.4z/demos/scripts/graph1.tcl blt2.4z/demos/scripts/graph2.tcl blt2.4z/demos/scripts/graph3.tcl blt2.4z/demos/scripts/graph5.tcl blt2.4z/demos/scripts/graph8.tcl blt2.4z/demos/scripts/page.tcl blt2.4z/demos/scripts/patterns.tcl blt2.4z/demos/scripts/ps.tcl blt2.4z/demos/scripts/send.tcl blt2.4z/demos/scripts/stipples.tcl blt2.4z/demos/scripts/xcolors.tcl blt2.4z/examples blt2.4z/examples/calendar.tcl blt2.4z/examples/form.tcl blt2.4z/examples/pareto.tcl blt2.4z/library blt2.4z/library/dd_protocols blt2.4z/library/dd_protocols/dd-color.tcl blt2.4z/library/dd_protocols/dd-file.tcl blt2.4z/library/dd_protocols/dd-number.tcl blt2.4z/library/dd_protocols/dd-text.tcl blt2.4z/library/dd_protocols/tclIndex blt2.4z/library/Makefile.in blt2.4z/library/Makefile.vc blt2.4z/library/ZoomStack.itcl blt2.4z/library/bltCanvEps.pro blt2.4z/library/bltGraph.pro blt2.4z/library/dnd.tcl blt2.4z/library/dragdrop.tcl blt2.4z/library/graph.tcl blt2.4z/library/hierbox.tcl blt2.4z/library/hiertable.tcl blt2.4z/library/pkgIndex.tcl.in blt2.4z/library/tabnotebook.tcl blt2.4z/library/tabset.tcl blt2.4z/library/tclIndex blt2.4z/library/treeview.cur blt2.4z/library/treeview.tcl blt2.4z/library/treeview.xbm blt2.4z/library/treeview_m.xbm blt2.4z/man blt2.4z/man/BLT.mann blt2.4z/man/Blt_Tree.man3 blt2.4z/man/Blt_TreeCreate.man3 blt2.4z/man/Blt_TreeCreateNode.man3 blt2.4z/man/Blt_TreeDeleteNode.man3 blt2.4z/man/Blt_TreeExists.man3 blt2.4z/man/Blt_TreeGetNode.man3 blt2.4z/man/Blt_TreeGetToken.man3 blt2.4z/man/Blt_TreeName.man3 blt2.4z/man/Blt_TreeNodeId.man3 blt2.4z/man/Blt_TreeReleaseToken.man3 blt2.4z/man/Makefile.in blt2.4z/man/barchart.mann blt2.4z/man/beep.mann blt2.4z/man/bgexec.mann blt2.4z/man/bitmap.mann blt2.4z/man/bltdebug.mann blt2.4z/man/busy.mann blt2.4z/man/container.mann blt2.4z/man/cutbuffer.mann blt2.4z/man/dragdrop.mann blt2.4z/man/eps.mann blt2.4z/man/graph.mann blt2.4z/man/hierbox.mann blt2.4z/man/hiertable.mann blt2.4z/man/htext.mann blt2.4z/man/man.macros blt2.4z/man/spline.mann blt2.4z/man/stripchart.mann blt2.4z/man/table.mann blt2.4z/man/tabset.mann blt2.4z/man/tile.mann blt2.4z/man/tree.mann blt2.4z/man/treeview.mann blt2.4z/man/vector.mann blt2.4z/man/watch.mann blt2.4z/man/winop.mann blt2.4z/src blt2.4z/src/shared blt2.4z/src/shared/Makefile.in blt2.4z/src/Makefile-cyg.in blt2.4z/src/Makefile.bc blt2.4z/src/Makefile.in blt2.4z/src/Makefile.vc blt2.4z/src/TODO blt2.4z/src/blt.h blt2.4z/src/blt.mak blt2.4z/src/bltAlloc.c blt2.4z/src/bltArrayObj.c blt2.4z/src/bltBeep.c blt2.4z/src/bltBgexec.c blt2.4z/src/bltBind.c blt2.4z/src/bltBind.h blt2.4z/src/bltBitmap.c blt2.4z/src/bltBusy.c blt2.4z/src/bltCanvEps.c blt2.4z/src/bltChain.c blt2.4z/src/bltChain.h blt2.4z/src/bltColor.c blt2.4z/src/bltConfig.c blt2.4z/src/bltConfig.h.in blt2.4z/src/bltContainer.c blt2.4z/src/bltCutbuffer.c blt2.4z/src/bltDebug.c blt2.4z/src/bltDragdrop.c blt2.4z/src/bltGrAxis.c blt2.4z/src/bltGrAxis.h blt2.4z/src/bltGrBar.c blt2.4z/src/bltGrElem.c blt2.4z/src/bltGrElem.h blt2.4z/src/bltGrGrid.c blt2.4z/src/bltGrHairs.c blt2.4z/src/bltGrLegd.c blt2.4z/src/bltGrLegd.h blt2.4z/src/bltGrLine.c blt2.4z/src/bltGrMarker.c blt2.4z/src/bltGrMisc.c blt2.4z/src/bltGrPen.c blt2.4z/src/bltGrPs.c blt2.4z/src/bltGraph.c blt2.4z/src/bltGraph.h blt2.4z/src/bltHash.c blt2.4z/src/bltHash.h.in blt2.4z/src/bltHierbox.c blt2.4z/src/bltHtext.c blt2.4z/src/bltImage.c blt2.4z/src/bltImage.h blt2.4z/src/bltInit.c blt2.4z/src/bltInt.h blt2.4z/src/bltInterp.h blt2.4z/src/bltList.c blt2.4z/src/bltList.h blt2.4z/src/bltMath.h blt2.4z/src/bltNsUtil.c blt2.4z/src/bltNsUtil.h blt2.4z/src/bltObjConfig.c blt2.4z/src/bltObjConfig.h blt2.4z/src/bltParse.c blt2.4z/src/bltPool.c blt2.4z/src/bltPool.h blt2.4z/src/bltPs.c blt2.4z/src/bltPs.h blt2.4z/src/bltScrollbar.c blt2.4z/src/bltSpline.c blt2.4z/src/bltSwitch.c blt2.4z/src/bltSwitch.h blt2.4z/src/bltTable.c blt2.4z/src/bltTable.h blt2.4z/src/bltTabnotebook.c blt2.4z/src/bltTabset.c blt2.4z/src/bltTed.c blt2.4z/src/bltText.c blt2.4z/src/bltText.h blt2.4z/src/bltTile.c blt2.4z/src/bltTile.h blt2.4z/src/bltTkInt.h blt2.4z/src/bltTree.c blt2.4z/src/bltTree.h blt2.4z/src/bltTreeCmd.c blt2.4z/src/bltTreeView.c blt2.4z/src/bltTreeView.h blt2.4z/src/bltTreeViewCmd.c blt2.4z/src/bltTreeViewColumn.c blt2.4z/src/bltTreeViewEdit.c blt2.4z/src/bltTreeViewStyle.c blt2.4z/src/bltTuple.c blt2.4z/src/bltTuple.h blt2.4z/src/bltTupleCmd.c blt2.4z/src/bltUnixDnd.c blt2.4z/src/bltUnixImage.c blt2.4z/src/bltUnixMain.c blt2.4z/src/bltUnixPipe.c blt2.4z/src/bltUtil.c blt2.4z/src/bltVecCmd.c blt2.4z/src/bltVecInt.h blt2.4z/src/bltVecMath.c blt2.4z/src/bltVecObjCmd.c blt2.4z/src/bltVector.c blt2.4z/src/bltVector.h blt2.4z/src/bltWait.h blt2.4z/src/bltWatch.c blt2.4z/src/bltWin.h blt2.4z/src/bltWinConfig.h blt2.4z/src/bltWinDde.c blt2.4z/src/bltWinDraw.c blt2.4z/src/bltWinImage.c blt2.4z/src/bltWinMain.c blt2.4z/src/bltWinPipe.c blt2.4z/src/bltWinPrnt.c blt2.4z/src/bltWinUtil.c blt2.4z/src/bltWindow.c blt2.4z/src/bltWinop.c blt2.4z/src/missing.h blt2.4z/src/pure_api.c blt2.4z/src/tkButton.c blt2.4z/src/tkConsole.c blt2.4z/src/tkFrame.c blt2.4z/src/tkMenubutton.c blt2.4z/src/tkScrollbar.c blt2.4z/win blt2.4z/win/install.tcl blt2.4z/win/README blt2.4z/win/X11 blt2.4z/win/X11/Xatom.h blt2.4z/win/X11/X.h blt2.4z/win/X11/Xfuncproto.h blt2.4z/win/X11/Xlib.h blt2.4z/win/X11/Xutil.h blt2.4z/win/X11/cursorfont.h blt2.4z/win/X11/keysym.h blt2.4z/win/X11/keysymdef.h blt2.4z/win/makedefs ������������������������������������������./saods9/make.darwinx86mountainlion�����������������������������������������������������������������0000644�0001750�0001750�00000001170�12077031450�016227� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# make sure installed: PKG_CONFIG for Xft, see notes OS = unix ARCH = darwinx86mountainlion X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -mmacosx-version-min=10.8 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz JOBS = 4 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.macosxppctiger������������������������������������������������������������������������0000644�0001750�0001750�00000001072�12127331353�014772� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxppctiger X11INCLUDE =../include/X11 export MACOSX_DEPLOYMENT_TARGET := 10.4 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 AA = -fPIC -D_MACOSX -DMAC_OSX_TK -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = echo ASTFLAGS = ac_cv_header_execinfo_h=no JOBS = 4 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/���������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�011657� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/menu.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000043771�12131573630�013357� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CreateMenuBar {} { global ds9 menu $ds9(mb) $ds9(mb) add cascade -label [msgcat::mc {File}] -menu $ds9(mb).file $ds9(mb) add cascade -label [msgcat::mc {Edit}] -menu $ds9(mb).edit $ds9(mb) add cascade -label [msgcat::mc {View}] -menu $ds9(mb).view $ds9(mb) add cascade -label [msgcat::mc {Frame}] -menu $ds9(mb).frame $ds9(mb) add cascade -label [msgcat::mc {Bin}] -menu $ds9(mb).bin $ds9(mb) add cascade -label [msgcat::mc {Zoom}] -menu $ds9(mb).zoom $ds9(mb) add cascade -label [msgcat::mc {Scale}] -menu $ds9(mb).scale $ds9(mb) add cascade -label [msgcat::mc {Color}] -menu $ds9(mb).color $ds9(mb) add cascade -label [msgcat::mc {Region}] -menu $ds9(mb).region $ds9(mb) add cascade -label [msgcat::mc {WCS}] -menu $ds9(mb).wcs $ds9(mb) add cascade -label [msgcat::mc {Analysis}] -menu $ds9(mb).analysis AppleMainMenu $ds9(mb) FileMainMenu EditMainMenu ViewMainMenu FrameMainMenu BinMainMenu ZoomMainMenu ScaleMainMenu ColorMainMenu RegionMainMenu WCSMainMenu AnalysisMainMenu switch $ds9(wm) { x11 - win32 {HelpMenu $ds9(mb)} aqua {} } } proc AppleMainMenu {mb} { global ds9 switch $ds9(wm) { x11 - win32 {} aqua { # apple menu $mb add cascade -menu $mb.apple menu $mb.apple $mb.apple add command \ -label [msgcat::mc {About SAOImage DS9}] \ -command AboutBox # help menu HelpMenu $mb } } } # CoordMenu proc CoordMenu {w varname system other sky skyformat cmd} { upvar #0 $varname var global $varname menu $w $w add radiobutton -label [msgcat::mc {WCS}] \ -variable ${varname}($system) -value wcs -command $cmd $w add cascade -label [msgcat::mc {Multiple WCS}] -menu $w.wcs menu $w.wcs foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $w.wcs add radiobutton -label "[msgcat::mc {WCS}] $l" \ -variable ${varname}($system) -value "wcs$l" -command $cmd } switch -- $other { 1 { $w add separator $w add radiobutton -label [msgcat::mc {Image}] \ -variable ${varname}($system) -value image -command $cmd $w add radiobutton -label [msgcat::mc {Physical}] \ -variable ${varname}($system) -value physical -command $cmd $w add radiobutton -label [msgcat::mc {Amplifier}] \ -variable ${varname}($system) -value amplifier -command $cmd $w add radiobutton -label [msgcat::mc {Detector}] \ -variable ${varname}($system) -value detector -command $cmd } 2 { $w add separator $w add radiobutton -label [msgcat::mc {Image}] \ -variable ${varname}($system) -value image -command $cmd } } if {$sky != {}} { $w add separator $w add radiobutton -label [msgcat::mc {FK4}] \ -variable ${varname}($sky) -value fk4 -command $cmd $w add radiobutton -label [msgcat::mc {FK5}] \ -variable ${varname}($sky) -value fk5 -command $cmd $w add radiobutton -label [msgcat::mc {ICRS}] \ -variable ${varname}($sky) -value icrs -command $cmd $w add radiobutton -label [msgcat::mc {Galactic}] \ -variable ${varname}($sky) -value galactic -command $cmd $w add radiobutton -label [msgcat::mc {Ecliptic}] \ -variable ${varname}($sky) -value ecliptic -command $cmd } if {$skyformat != {}} { $w add separator $w add radiobutton -label [msgcat::mc {Degrees}] \ -variable ${varname}($skyformat) -value degrees -command $cmd $w add radiobutton -label {Sexagesimal} \ -variable ${varname}($skyformat) -value sexagesimal -command $cmd } } proc CoordMenuButton {w varname system other sky skyformat cmd} { upvar #0 $varname var global $varname CoordMenuButtonCmd $varname $system $sky {} ttk::menubutton $w -textvariable ${varname}($system,msg) -menu $w.menu CoordMenu $w.menu $varname $system $other $sky $skyformat \ [list CoordMenuButtonCmd $varname $system $sky $cmd] } proc CoordMenuButtonCmd {varname system sky cmd} { upvar #0 $varname var global $varname set ${varname}($system,msg) [msgcat::mc $var($system)] if {$sky != {}} { switch -- $var($system) { image - physical - amplifier - detector {} default { if {[info exists var(frame)]} { if {$var(frame) != {}} { if [$var(frame) has wcs equatorial $var($system)] { set ${varname}($system,msg) [msgcat::mc $var($sky)] } } } } } } if {$cmd != {}} { eval $cmd } } proc CoordMenuEnable {w varname system other sky skyformat} { upvar #0 $varname var global $varname if {![info exists var(frame)]} { return } if {$var(frame) == {}} { return } if {[$var(frame) has wcs wcs]} { $w entryconfig [msgcat::mc {WCS}] -state normal } else { $w entryconfig [msgcat::mc {WCS}] -state disabled } $w entryconfig [msgcat::mc {Multiple WCS}] -state normal foreach ll {a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {[$var(frame) has wcs "wcs${ll}"]} { $w.wcs entryconfig "[msgcat::mc {WCS}] $ll" -state normal } else { $w.wcs entryconfig "[msgcat::mc {WCS}] $ll" -state disabled } } switch -- $other { 1 { $w entryconfig [msgcat::mc {Image}] -state normal $w entryconfig [msgcat::mc {Physical}] -state normal $w entryconfig [msgcat::mc {Amplifier}] -state normal $w entryconfig [msgcat::mc {Detector}] -state normal } 2 { $w entryconfig [msgcat::mc {Image}] -state normal } } if {$sky != {}} { if {[$var(frame) has wcs equatorial $var($system)]} { $w entryconfig [msgcat::mc {FK4}] -state normal $w entryconfig [msgcat::mc {FK5}] -state normal $w entryconfig [msgcat::mc {ICRS}] -state normal $w entryconfig [msgcat::mc {Galactic}] -state normal $w entryconfig [msgcat::mc {Ecliptic}] -state normal } else { $w entryconfig [msgcat::mc {FK4}] -state disabled $w entryconfig [msgcat::mc {FK5}] -state disabled $w entryconfig [msgcat::mc {ICRS}] -state disabled $w entryconfig [msgcat::mc {Galactic}] -state disabled $w entryconfig [msgcat::mc {Ecliptic}] -state disabled } } if {$skyformat != {}} { if {[$var(frame) has wcs celestrial $var($system)]} { $w entryconfig [msgcat::mc {Degrees}] -state normal $w entryconfig {Sexagesimal} -state normal } else { $w entryconfig [msgcat::mc {Degrees}] -state disabled $w entryconfig {Sexagesimal} -state disabled } } } proc CoordMenuReset {w varname system other sky skyformat} { upvar #0 $varname var global $varname $w entryconfig [msgcat::mc {WCS}] -state normal $w entryconfig [msgcat::mc {Multiple WCS}] -state normal foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $w.wcs entryconfig "[msgcat::mc {WCS}] $l" -state normal } switch -- $other { 1 { $w entryconfig [msgcat::mc {Image}] -state normal $w entryconfig [msgcat::mc {Physical}] -state normal $w entryconfig [msgcat::mc {Amplifier}] -state normal $w entryconfig [msgcat::mc {Detector}] -state normal } 2 { $w entryconfig [msgcat::mc {Image}] -state normal } } if {$sky != {}} { $w entryconfig [msgcat::mc {FK4}] -state normal $w entryconfig [msgcat::mc {FK5}] -state normal $w entryconfig [msgcat::mc {ICRS}] -state normal $w entryconfig [msgcat::mc {Galactic}] -state normal $w entryconfig [msgcat::mc {Ecliptic}] -state normal } if {$skyformat != {}} { $w entryconfig [msgcat::mc {Degrees}] -state normal $w entryconfig {Sexagesimal} -state normal } } # DistMenu proc DistMenu {w varname system other format cmd} { upvar #0 $varname var global $varname menu $w $w add radiobutton -label [msgcat::mc {WCS}] \ -variable ${varname}($system) -value wcs -command $cmd $w add cascade -label [msgcat::mc {Multiple WCS}] \ -menu $w.wcs menu $w.wcs foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $w.wcs add radiobutton -label "[msgcat::mc {WCS}] $l" \ -variable ${varname}($system) -value "wcs$l" -command $cmd } if {$other} { $w add separator $w add radiobutton -label [msgcat::mc {Image}] \ -variable ${varname}($system) -value image -command $cmd $w add radiobutton -label [msgcat::mc {Physical}] \ -variable ${varname}($system) -value physical -command $cmd $w add radiobutton -label [msgcat::mc {Amplifier}] \ -variable ${varname}($system) -value amplifier -command $cmd $w add radiobutton -label [msgcat::mc {Detector}] \ -variable ${varname}($system) -value detector -command $cmd } if {$format != {}} { $w add separator $w add radiobutton -label [msgcat::mc {Degrees}] \ -variable ${varname}($format) -value degrees -command $cmd $w add radiobutton -label [msgcat::mc {ArcMin}] \ -variable ${varname}($format) -value arcmin -command $cmd $w add radiobutton -label [msgcat::mc {ArcSec}] \ -variable ${varname}($format) -value arcsec -command $cmd } } proc DistMenuButton {w varname system other format cmd} { upvar #0 $varname var global $varname DistMenuButtonCmd $varname $system $format {} ttk::menubutton $w -textvariable ${varname}($system,msg) -menu $w.menu DistMenu $w.menu $varname $system $other $format \ [list DistMenuButtonCmd $varname $system $format $cmd] } proc DistMenuButtonCmd {varname system format cmd} { upvar #0 $varname var global $varname set ${varname}($system,msg) [msgcat::mc $var($system)] if {$format != {}} { switch -- $var($system) { image - physical - amplifier - detector {} default { if {[info exists var(frame)]} { if {$var(frame) != {}} { if {[$var(frame) has wcs equatorial $var($system)]} { set ${varname}($system,msg) [msgcat::mc $var($format)] } } } } } } if {$cmd != {}} { eval $cmd } } proc DistMenuEnable {w varname system other format} { upvar #0 $varname var global $varname if {![info exists var(frame)]} { return } if {$var(frame) == {}} { return } if {[$var(frame) has wcs wcs]} { $w entryconfig [msgcat::mc {WCS}] -state normal } else { $w entryconfig [msgcat::mc {WCS}] -state disabled } $w entryconfig [msgcat::mc {Multiple WCS}] -state normal foreach ll {a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {[$var(frame) has wcs "wcs${ll}"]} { $w.wcs entryconfig "[msgcat::mc {WCS}] $ll" -state normal } else { $w.wcs entryconfig "[msgcat::mc {WCS}] $ll" -state disabled } } if {$other} { $w entryconfig [msgcat::mc {Image}] -state normal $w entryconfig [msgcat::mc {Physical}] -state normal $w entryconfig [msgcat::mc {Amplifier}] -state normal $w entryconfig [msgcat::mc {Detector}] -state normal } if {$format != {}} { if {[$var(frame) has wcs celestrial $var($system)]} { $w entryconfig [msgcat::mc {Degrees}] -state normal $w entryconfig [msgcat::mc {ArcMin}] -state normal $w entryconfig [msgcat::mc {ArcSec}] -state normal } else { $w entryconfig [msgcat::mc {Degrees}] -state disabled $w entryconfig [msgcat::mc {ArcMin}] -state disabled $w entryconfig [msgcat::mc {ArcSec}] -state disabled } } } proc DistMenuReset {w varname system other format} { upvar #0 $varname var global $varname $w entryconfig [msgcat::mc {WCS}] -state normal $w entryconfig [msgcat::mc {Multiple WCS}] -state normal foreach ll {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $w.wcs entryconfig "[msgcat::mc {WCS}] $ll" -state normal } if {$other} { $w entryconfig [msgcat::mc {Image}] -state normal $w entryconfig [msgcat::mc {Physical}] -state normal $w entryconfig [msgcat::mc {Amplifier}] -state normal $w entryconfig [msgcat::mc {Detector}] -state normal } if {$format != {}} { $w entryconfig [msgcat::mc {Degrees}] -state normal $w entryconfig [msgcat::mc {ArcMin}] -state normal $w entryconfig [msgcat::mc {ArcSec}] -state normal } } # EditMenu proc EditMenu {mb varname} { upvar #0 $varname var global $varname global ds9 menu $mb.edit $mb.edit add command -label [msgcat::mc {Cut}] \ -command "EntryCut $var(top)" -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command "EntryCopy $var(top)" -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -command "EntryPaste $var(top)" -accelerator "${ds9(ctrl)}V" } # ColorMenu proc ColorMenu {w varname color cmd} { upvar #0 $varname var global $varname menu $w $w add radiobutton -label [msgcat::mc {Black}] \ -variable ${varname}($color) -value black -command $cmd $w add radiobutton -label [msgcat::mc {White}] \ -variable ${varname}($color) -value white -command $cmd $w add radiobutton -label [msgcat::mc {Red}] \ -variable ${varname}($color) -value red -command $cmd $w add radiobutton -label [msgcat::mc {Green}] \ -variable ${varname}($color) -value green -command $cmd $w add radiobutton -label [msgcat::mc {Blue}] \ -variable ${varname}($color) -value blue -command $cmd $w add radiobutton -label [msgcat::mc {Cyan}] \ -variable ${varname}($color) -value cyan -command $cmd $w add radiobutton -label [msgcat::mc {Magenta}] \ -variable ${varname}($color) -value magenta -command $cmd $w add radiobutton -label [msgcat::mc {Yellow}] \ -variable ${varname}($color) -value yellow -command $cmd $w add separator $w add command -label "[msgcat::mc {Other Color}]..." \ -command [list ColorMenuOther $varname $color $cmd] } proc ColorMenuOther {varname color cmd} { upvar #0 $varname var global $varname if {[EntryDialog [msgcat::mc {Color}] [msgcat::mc {Enter Color}] 20 ${varname}($color)]} { eval $cmd } } proc ColorMenuButton {w varname color cmd} { upvar #0 $varname var global $varname ColorMenuButtonCmd $varname $color {} ttk::menubutton $w -textvariable ${varname}($color,msg) -menu $w.menu ColorMenu $w.menu $varname $color \ [list ColorMenuButtonCmd $varname $color $cmd] } proc ColorMenuButtonCmd {varname color cmd} { upvar #0 $varname var global $varname set ${varname}($color,msg) [msgcat::mc [string totitle $var($color)]] if {$cmd != {}} { eval $cmd } } # FontMenu proc FontMenu {w varname font size weight slant cmd} { upvar #0 $varname var global $varname menu $w $w add radiobutton -label {Times} -variable ${varname}($font) \ -value times -command $cmd $w add radiobutton -label {Helvetica} -variable ${varname}($font) \ -value helvetica -command $cmd $w add radiobutton -label {Courier} -variable ${varname}($font) \ -value courier -command $cmd $w add separator $w add radiobutton -label {9} -variable ${varname}($size) \ -value 9 -command $cmd $w add radiobutton -label {10} -variable ${varname}($size) \ -value 10 -command $cmd $w add radiobutton -label {12} -variable ${varname}($size) \ -value 12 -command $cmd $w add radiobutton -label {14} -variable ${varname}($size) \ -value 14 -command $cmd $w add radiobutton -label {16} -variable ${varname}($size) \ -value 16 -command $cmd $w add radiobutton -label {20} -variable ${varname}($size) \ -value 20 -command $cmd $w add radiobutton -label {24} -variable ${varname}($size) \ -value 24 -command $cmd $w add radiobutton -label {30} -variable ${varname}($size) \ -value 30 -command $cmd $w add radiobutton -label {36} -variable ${varname}($size) \ -value 36 -command $cmd $w add radiobutton -label {72} -variable ${varname}($size) \ -value 72 -command $cmd $w add separator $w add command -label "[msgcat::mc {Other Font Size}]..." \ -command [list FontMenuSize $varname $size $cmd] $w add separator $w add radiobutton -label [msgcat::mc {Normal}] \ -variable ${varname}($weight) -value normal -command $cmd $w add radiobutton -label [msgcat::mc {Bold}] \ -variable ${varname}($weight) -value bold -command $cmd $w add separator $w add radiobutton -label [msgcat::mc {Roman}] \ -variable ${varname}($slant) -value roman -command $cmd $w add radiobutton -label [msgcat::mc {Italic}] \ -variable ${varname}($slant) -value italic -command $cmd } proc FontMenuSize {varname size cmd} { upvar #0 $varname var global $varname if {[EntryDialog [msgcat::mc {Font Size}] [msgcat::mc {Enter Font Size}] 20 ${varname}($size)]} { eval $cmd } } proc FontMenuButton {w varname font size weight slant cmd} { upvar #0 $varname var global $varname FontMenuButtonCmd $varname $font {} ttk::menubutton $w -textvariable ${varname}($font,msg) -menu $w.menu FontMenu $w.menu $varname $font $size $weight $slant \ [list FontMenuButtonCmd $varname $font $cmd] } proc FontMenuButtonCmd {varname font cmd} { upvar #0 $varname var global $varname set ${varname}($font,msg) [msgcat::mc [string totitle $var($font)]] if {$cmd != {}} { eval $cmd } } # WidthDashMenu proc WidthDashMenu {w varname width dash cmd1 cmd2} { upvar #0 $varname var global $varname menu $w $w add radiobutton -label {1} -variable ${varname}($width) \ -value 1 -command $cmd1 $w add radiobutton -label {2} -variable ${varname}($width) \ -value 2 -command $cmd1 $w add radiobutton -label {3} -variable ${varname}($width) \ -value 3 -command $cmd1 $w add radiobutton -label {4} -variable ${varname}($width) \ -value 4 -command $cmd1 if {$dash != {}} { $w add separator $w add checkbutton -label [msgcat::mc {Dash}] \ -variable ${varname}($dash) -command $cmd2 } } # Prefs proc PrefsDialogMenu {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Menus and Buttons}] lappend dprefs(tabs) [ttk::frame $w.menu] PrefsDialogFileMenu $w.menu PrefsDialogEditMenu $w.menu PrefsDialogViewMenu $w.menu PrefsDialogFrameMenu $w.menu PrefsDialogBinMenu $w.menu PrefsDialogZoomMenu $w.menu PrefsDialogScaleMenu $w.menu PrefsDialogColorMenu $w.menu PrefsDialogRegionMenu $w.menu PrefsDialogWCSMenu $w.menu PrefsDialogHelpMenu $w.menu } �������./saods9/src/buttons.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000015751�11700665566�014121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ButtonsDef {} { global pbuttons # TButtonBar class bindings ttk::copyBindings TButton TButtonBar bind TButtonBar <Enter> {} bind TButtonBar <Leave> {} ButtonsFileDef ButtonsEditDef ButtonsViewDef ButtonsFrameDef ButtonsBinDef ButtonsZoomDef ButtonsScaleDef ButtonsColorDef ButtonsRegionDef ButtonsWCSDef ButtonsHelpDef } proc CreateButtons {} { global ds9 global buttons set ds9(buttons) [ttk::frame $ds9(main).buttons] set ds9(buttons,sep) [ttk::separator $ds9(main).sbuttons -orient horizontal] set buttons(majorPrev) $ds9(buttons).file set buttons(majorCurrent) $ds9(buttons).file ttk::frame $ds9(buttons).major RadioButton $ds9(buttons).major.file \ [string tolower [msgcat::mc {File}]] \ buttons(majorCurrent) $ds9(buttons).file MajorButton RadioButton $ds9(buttons).major.edit \ [string tolower [msgcat::mc {Edit}]] \ buttons(majorCurrent) $ds9(buttons).edit MajorButton RadioButton $ds9(buttons).major.view \ [string tolower [msgcat::mc {View}]] \ buttons(majorCurrent) $ds9(buttons).view MajorButton RadioButton $ds9(buttons).major.frame \ [string tolower [msgcat::mc {Frame}]] \ buttons(majorCurrent) $ds9(buttons).frame MajorButton RadioButton $ds9(buttons).major.bin \ [string tolower [msgcat::mc {Bin}]] \ buttons(majorCurrent) $ds9(buttons).bin MajorButton RadioButton $ds9(buttons).major.zoom \ [string tolower [msgcat::mc {Zoom}]] \ buttons(majorCurrent) $ds9(buttons).zoom MajorButton RadioButton $ds9(buttons).major.scale \ [string tolower [msgcat::mc {Scale}]] \ buttons(majorCurrent) $ds9(buttons).scale MajorButton RadioButton $ds9(buttons).major.color \ [string tolower [msgcat::mc {Color}]] \ buttons(majorCurrent) $ds9(buttons).color MajorButton RadioButton $ds9(buttons).major.region \ [string tolower [msgcat::mc {Region}]] \ buttons(majorCurrent) $ds9(buttons).region MajorButton RadioButton $ds9(buttons).major.wcs \ [string tolower [msgcat::mc {WCS}]] \ buttons(majorCurrent) $ds9(buttons).wcs MajorButton RadioButton $ds9(buttons).major.help \ [string tolower [msgcat::mc {Help}]] \ buttons(majorCurrent) $ds9(buttons).help MajorButton global pbuttons array set pbuttons { major,file 1 major,edit 1 major,view 1 major,frame 1 major,bin 1 major,zoom 1 major,scale 1 major,color 1 major,region 1 major,wcs 1 major,help 1 } set buttons(major) " $ds9(buttons).major.file pbuttons(major,file) $ds9(buttons).major.edit pbuttons(major,edit) $ds9(buttons).major.view pbuttons(major,view) $ds9(buttons).major.frame pbuttons(major,frame) $ds9(buttons).major.bin pbuttons(major,bin) $ds9(buttons).major.zoom pbuttons(major,zoom) $ds9(buttons).major.scale pbuttons(major,scale) $ds9(buttons).major.color pbuttons(major,color) $ds9(buttons).major.region pbuttons(major,region) $ds9(buttons).major.wcs pbuttons(major,wcs) $ds9(buttons).major.help pbuttons(major,help) " CreateButtonsFile CreateButtonsEdit CreateButtonsView CreateButtonsFrame CreateButtonsBin CreateButtonsZoom CreateButtonsScale CreateButtonsColor CreateButtonsRegion CreateButtonsWCS CreateButtonsHelp LayoutButtons } proc ButtonButton {button text cmd} { ttk::button $button \ -class TButtonBar \ -text $text \ -command $cmd \ -width -1 \ -takefocus 0 } proc RadioButton {button text varname value cmd} { ttk::button $button \ -class TButtonBar \ -text $text \ -width -1 \ -takefocus 0 \ -command "RadioButtonSim $button $varname \{$value\} \{$cmd\}" # setup trace on $varname, so that all buttons that use this variable # will be updated when the variable is changed uplevel #0 trace variable $varname w \ [list "RadioButtonCB $button \{$value\}"] # setup <Map> event so that anytime the button is redrawn, # it is updated bind $button <Map> "ButtonMap %W $varname" } proc CheckButton {button text varname cmd} { ttk::button $button \ -class TButtonBar \ -text $text \ -width -1 \ -takefocus 0 \ -command "CheckButtonSim $button $varname \{$cmd\}" uplevel #0 trace variable $varname w [list "CheckButtonCB $button"] bind $button <Map> "ButtonMap %W $varname" } proc ButtonMap {button varname} { upvar #0 $varname var set vv $var # delay slightly, I don't know why this is needed after 10 [list set $varname $vv] } proc RadioButtonSim {button varname value cmd} { uplevel #0 [list set $varname $value] eval $cmd } proc RadioButtonCB {button value varname id op} { upvar #0 $varname var global $varname if {[$button cget -state] != {disabled}} { if {$var($id) == $value} { $button configure -state active } else { $button configure -state normal } } } proc CheckButtonSim {button varname cmd} { upvar #0 $varname var uplevel #0 [list set $varname [expr !$var]] eval $cmd } proc CheckButtonCB {button varname id op} { upvar #0 $varname var global $varname if {[$button cget -state] != {disabled}} { if {$var($id)} { $button configure -state active } else { $button configure -state normal } } } proc LayoutButtons {} { global ds9 global buttons global view pack forget $ds9(buttons).major switch $view(layout) { horizontal { $ds9(buttons) configure -width 0 pack propagate $ds9(buttons) on pack $ds9(buttons).major -side top -fill x -expand true } vertical { $ds9(buttons) configure -width 125 pack propagate $ds9(buttons) off pack $ds9(buttons).major -side top -fill x -expand true -anchor n } } UpdateButtons buttons(major) UpdateButtons buttons(file) UpdateButtons buttons(edit) UpdateButtons buttons(view) UpdateButtons buttons(frame) UpdateButtons buttons(bin) UpdateButtons buttons(zoom) UpdateButtons buttons(scale) UpdateButtons buttons(color) UpdateButtons buttons(region) UpdateButtons buttons(wcs) UpdateButtons buttons(help) MajorButton } proc MajorButton {} { global buttons global view pack forget $buttons(majorPrev) switch $view(layout) { horizontal { pack $buttons(majorCurrent) -side top -fill x -expand true } vertical { pack $buttons(majorCurrent) -side bottom -fill x -expand true -anchor s } } set buttons(majorPrev) $buttons(majorCurrent) } proc UpdateButtons {varname} { upvar #0 $varname var foreach {which what} $var { pack forget $which } foreach {which what} $var { ShowButton $which $what } } proc ShowButton {which varname} { upvar #0 $varname var global view if {$var} { switch $view(layout) { horizontal {pack $which -side left -fill both -expand true} vertical {pack $which -side top -fill both -expand true} } } } �����������������������./saods9/src/load.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000024772�12130605314�013324� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MultiLoad {{layer {}} {mode {}}} { global ds9 global current global debug if {$debug(tcl,layout)} { puts stderr "MultiLoad" } if {$layer != {} || $mode != {}} { return } if {$current(frame) != {}} { if {![$current(frame) has fits]} { return } switch -- [$current(frame) get type] { base - 3d {CreateFrame} rgb {} } } else { CreateFrame return } # go into tile mode if more than one set cnt [llength $ds9(frames)] if {$cnt > 1 && $current(display) != "tile"} { set current(display) tile DisplayMode } } proc MultiLoadBase {} { global ds9 global current global debug if {$debug(tcl,layout)} { puts stderr "MultiLoadBase" } if {$current(frame) != {}} { if {![$current(frame) has fits]} { return } CreateFrame } else { CreateFrame return } # go into tile mode if more than one set cnt [llength $ds9(frames)] if {$cnt > 1 && $current(display) != "tile"} { set current(display) tile DisplayMode } } proc MultiLoadRGB {} { global ds9 global current global debug if {$debug(tcl,layout)} { puts stderr "MultiLoadRGB" } if {$current(frame) != {}} { if {![$current(frame) has fits]} { return } CreateRGBFrame } else { CreateRGBFrame return } # go into tile mode if more than one set cnt [llength $ds9(frames)] if {$cnt > 1 && $current(display) != "tile"} { set current(display) tile DisplayMode } } # used by backup proc ProcessLoad {{err 1}} { global current global loadParam if [catch { switch -- $loadParam(load,type) { alloc - allocgz {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ \{$loadParam(file,fn)\} \ $loadParam(load,layer)} channel { fconfigure $loadParam(channel,name) -translation binary \ -encoding binary $current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(channel,name) \ $loadParam(load,layer) # clean up catch {close $loadParam(channel,name)} } mmap - mmapincr {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(load,layer)} smmap {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,header)\} \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(load,layer)} shared {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(shared,idtype) \ $loadParam(shared,id) \ $loadParam(load,layer)} sshared {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(shared,idtype) \ $loadParam(shared,hdr) \ $loadParam(shared,id) \ $loadParam(load,layer)} socket - socketgz {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(socket,id) \ $loadParam(load,layer)} var {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ \{$loadParam(file,name)\} \ $loadParam(load,type) \ $loadParam(var,name) \ $loadParam(load,layer)} photo {$current(frame) load $loadParam(file,type) \ $loadParam(file,mode) \ $loadParam(var,name) \{$loadParam(file,name)\} } } } rr] { if {$err} { Error "[msgcat::mc {Unable to load}] $loadParam(file,type) $loadParam(file,mode) $loadParam(file,name)" } return 0 } # save loadParam if {$loadParam(load,layer) == {}} { switch -- [$current(frame) get type] { base - 3d {ProcessLoadSaveParams $current(frame)} rgb { switch -- $loadParam(file,mode) { {rgb image} - {rgb cube} {ProcessLoadSaveParams $current(frame)} default { ProcessLoadSaveParams \ "$current(frame)[$current(frame) get rgb channel]" } } } } } unset loadParam return 1 } proc ProcessLoadSaveParams {varname} { global loadParam global current switch $loadParam(file,mode) { slice - {mosaic wcs} - {mosaic iraf} { # special case global $varname if {[info exists $varname]} { set varname "$varname.[$current(frame) get fits count]" } } } global $varname if [info exists $varname] { unset $varname } array set $varname [array get loadParam] # always save absolute path upvar #0 $varname var if {[file pathtype $var(file,name)] == {relative}} { set var(file,name) [file join [pwd] $var(file,name)] } } proc StartLoad {} { SetWatchCursor } proc FinishLoadPre {} { global loadParam global current global threed # generate grid so updatemenu is correct GridUpdate # generate contour so updatemenu is correct UpdateContourScale ContourUpdate # just in case, frame may have been deleted before FinishLoad during startup if {$current(frame) == {}} { return } # if header(s) were open, remove them DestroyHeader $current(frame) # Cube? if [$current(frame) has fits cube] { CubeDialog } } proc FinishLoadPost {} { UpdateDS9 UnsetWatchCursor } proc FinishLoad {} { FinishLoadPre FinishLoadPost } proc IsLocalFile {fn} { # strip any brackets set aa [string first "\[" $fn] if {$aa > 0} { set fn [string range $fn 0 [expr $aa-1]] } if {![file exists $fn]} { return 0 } if {![file isfile $fn]} { return 0 } if {[file isdirectory $fn]} { return 0 } if {[file readable $fn]} { return 1 } else { return 0 } } proc ConvertFitsFile {} { foreach t {Stdin ExternalFits GzipFile BZip2File CompressFile PackFile} { if {[$t]} { return } } } proc ConvertArrayFile {} { foreach t {Stdin GzipFile BZip2File CompressFile PackFile} { if {[$t]} { return } } } # File Types proc Stdin {} { global loadParam # find -, -[], -[foo] but not -abc if [regexp -- {^-(\[.*)?$} $loadParam(file,name)] { set loadParam(load,type) allocgz set loadParam(file,name) "stdin[string range $loadParam(file,name) 1 end]" set loadParam(file,fn) $loadParam(file,name) return 1 } elseif {[string range $loadParam(file,name) 0 4] == "stdin" || [string range $loadParam(file,name) 0 4] == "STDIN"} { set loadParam(load,type) allocgz set loadParam(file,name) "stdin[string range $loadParam(file,name) 5 end]" set loadParam(file,fn) $loadParam(file,name) return 1 } return 0 } proc BZip2File {} { global loadParam if { [regexp {(.*)\.bz2($|\[)} $loadParam(file,name) matched root] } { if [catch {set ch [open "| bunzip2 < $root.bz2 " r]}] { return 0 } set loadParam(load,type) channel set loadParam(channel,name) $ch return 1 } return 0 } proc CompressFile {} { global loadParam if { [regexp {(.*)\.Z($|\[)} $loadParam(file,name) matched root] } { if [catch {set ch [open "| uncompress < $root.Z " r]}] { return 0 } set loadParam(load,type) channel set loadParam(channel,name) $ch return 1 } return 0 } proc PackFile {} { global loadParam if { [regexp {(.*)\.z($|\[)} $loadParam(file,name) matched root] } { if [catch {set ch [open "| pcat $root.z " r]}] { return 0 } set loadParam(load,type) channel set loadParam(channel,name) $ch return 1 } return 0 } proc GzipFile {} { global loadParam set fn $loadParam(file,name) set id [string first "\[" $fn] if {$id > 0} { set fn [string range $fn 0 [expr $id-1]] } catch { set ch [open $fn r] fconfigure $ch -encoding binary -translation binary set bb [read $ch 2] close $ch binary scan $bb H4 cc if {$cc == {1f8b}} { set loadParam(load,type) allocgz set loadParam(file,fn) $loadParam(file,name) return 1 } } return 0 } proc ExternalFits {} { global loadParam global extFits foreach id [array names extFits] { if {[string match $id "$loadParam(file,name)"]} { regsub -all {\$filename} $extFits($id) "$loadParam(file,name)" \ result set cmd "| $result" if [catch {set ch [open "$cmd" r]} err] { Error "open $cmd failed: $err" return 0 } set loadParam(load,type) channel set loadParam(channel,name) $ch return 1 } } return 0 } # Preserve proc ProcessPreserveCmd {varname iname} { upvar $varname var upvar $iname i global ds9 global scale global panzoom global marker switch -- [string tolower [lindex $var $i]] { scale { incr i set scale(preserve) [FromYesNo [lindex $var $i]] PreserveScale } pan { incr i set panzoom(preserve) [FromYesNo [lindex $var $i]] PreservePan } marker - regions { incr i set marker(preserve) [FromYesNo [lindex $var $i]] MarkerPreserve } } } proc ProcessSendPreserveCmd {proc id param} { global scale global panzoom global marker switch -- [string tolower $param] { scale {$proc $id [ToYesNo $scale(preserve)]} pan {$proc $id [ToYesNo $panzoom(preserve)]} regions {$proc $id [ToYesNo $marker(preserve)]} } } # Update proc ProcessUpdateCmd {varname iname} { upvar $varname var upvar $iname i global current global ds9 if {$current(frame) == {}} { return } if {[lindex $var $i] != {} && [string range [lindex $var $i] 0 0] != {-}} { switch -- [string tolower [lindex $var $i]] { on - yes {set ds9(idletasks) 1} no - off {set ds9(idletasks) 0} now { if {[string is integer [lindex $var [expr $i+1]]]} { $current(frame) update now \ [lindex $var [expr $i+1]] \ [lindex $var [expr $i+2]] [lindex $var [expr $i+3]] \ [lindex $var [expr $i+4]] [lindex $var [expr $i+5]] incr i 5 } else { $current(frame) update now } } {} { $current(frame) update incr i -1 } default { $current(frame) update \ [lindex $var $i] \ [lindex $var [expr $i+1]] [lindex $var [expr $i+2]] \ [lindex $var [expr $i+3]] [lindex $var [expr $i+4]] incr i 4 } } } else { $current(frame) update incr i -1 } } ������./saods9/src/boxannulus.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000001473�11732433634�014607� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BoxAnnulusDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(which) boxannulus set var(proc,apply) MarkerBaseAnnulusRectApply set var(proc,close) MarkerBaseAnnulusRectClose set var(proc,generate) MarkerBaseAnnulusGenerateBox set var(proc,coordCB) MarkerBaseAnnulusRectCoordCB set var(proc,editCB) MarkerBaseAnnulusRectEditCB set var(proc,distCB) MarkerBaseAnnulusRectDistCB # base MarkerBaseAnnulusRectDialog $varname size Width Height } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/pagesetup.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000014417�11762201376�014407� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PSPageSetup {} { global ps global ed set ed(ok) 0 array set ed [array get ps] set w {.pagesetup} DialogCreate $w [msgcat::mc {Page Setup}] ed(ok) # Layout set f [ttk::labelframe $w.layout -text {Layout}] ttk::label $f.torient -text [msgcat::mc {Orientation}] ttk::radiobutton $f.portrait -text [msgcat::mc {Portrait}] \ -variable ed(orient) -value portrait ttk::radiobutton $f.landscape -text [msgcat::mc {Landscape}] \ -variable ed(orient) -value landscape ttk::label $f.tscale -text [msgcat::mc {Scale}] ttk::entry $f.scale -textvariable ed(scale) -width 7 ttk::label $f.uscale -text {%} grid $f.torient $f.portrait $f.landscape -padx 2 -pady 2 -sticky w grid $f.tscale $f.scale $f.uscale -padx 2 -pady 2 -sticky w # Page Size set f [ttk::labelframe $w.size -text {Page Size}] ttk::radiobutton $f.letter -text "[msgcat::mc {Letter}](8.5 x 11 in)"\ -variable ed(size) -value letter ttk::radiobutton $f.legal -text "[msgcat::mc {Legal}](8.5 x 14 in)"\ -variable ed(size) -value legal ttk::radiobutton $f.tabloid -text "[msgcat::mc {Tabloid}](11 x 17 in)"\ -variable ed(size) -value tabloid ttk::radiobutton $f.poster -text "[msgcat::mc {Poster}](36 x 48 in)"\ -variable ed(size) -value poster ttk::radiobutton $f.a4 -text {A4(210 x 297 mm)} \ -variable ed(size) -value a4 ttk::radiobutton $f.other -text "[msgcat::mc {Other}] (inches)" \ -variable ed(size) -value other ttk::radiobutton $f.othermm -text "[msgcat::mc {Other}] (mm)" \ -variable ed(size) -value othermm ttk::label $f.title3 -text [msgcat::mc {Width}] ttk::entry $f.width -textvariable ed(width) -width 10 ttk::label $f.title4 -text [msgcat::mc {Height}] ttk::entry $f.height -textvariable ed(height) -width 10 grid $f.letter -padx 2 -pady 2 -sticky w grid $f.legal -padx 2 -pady 2 -sticky w grid $f.tabloid -padx 2 -pady 2 -sticky w grid $f.poster -padx 2 -pady 2 -sticky w grid $f.a4 -padx 2 -pady 2 -sticky w grid $f.other $f.title3 $f.width -padx 2 -pady 2 -sticky w grid $f.othermm $f.title4 $f.height -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini grid $w.layout -sticky news grid $w.size -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok DialogDismiss $w if {$ed(ok)} { array set ps [array get ed] } set rr $ed(ok) unset ed return $rr } proc PrefsDialogPageSetup {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Page Setup}] lappend dprefs(tabs) [ttk::frame $w.pagesetup] # Layout set f [ttk::labelframe $w.pagesetup.layout -text {Layout}] ttk::label $f.torient -text [msgcat::mc {Orientation}] ttk::radiobutton $f.portrait -text [msgcat::mc {Portrait}] \ -variable pps(orient) -value portrait ttk::radiobutton $f.landscape -text [msgcat::mc {Landscape}] \ -variable pps(orient) -value landscape ttk::label $f.tscale -text [msgcat::mc {Scale}] ttk::entry $f.scale -textvariable pps(scale) -width 7 ttk::label $f.uscale -text {%} grid $f.torient $f.portrait $f.landscape -padx 2 -pady 2 -sticky w grid $f.tscale $f.scale $f.uscale -padx 2 -pady 2 -sticky w # Page Size set f [ttk::labelframe $w.pagesetup.size -text {Page Size}] ttk::radiobutton $f.letter -text "[msgcat::mc {Letter}](8.5 x 11 in)"\ -variable pps(size) -value letter ttk::radiobutton $f.legal -text "[msgcat::mc {Legal}](8.5 x 14 in)"\ -variable pps(size) -value legal ttk::radiobutton $f.tabloid -text "[msgcat::mc {Tabloid}](11 x 17 in)"\ -variable pps(size) -value tabloid ttk::radiobutton $f.poster -text "[msgcat::mc {Poster}](36 x 48 in)"\ -variable pps(size) -value poster ttk::radiobutton $f.a4 -text {A4(210 x 297 mm)} \ -variable pps(size) -value a4 ttk::radiobutton $f.other -text "[msgcat::mc {Other}] (inches)" \ -variable pps(size) -value other ttk::radiobutton $f.othermm -text "[msgcat::mc {Other}] (mm)" \ -variable pps(size) -value othermm ttk::label $f.title3 -text [msgcat::mc {Width}] ttk::entry $f.width -textvariable pps(width) -width 10 ttk::label $f.title4 -text [msgcat::mc {Height}] ttk::entry $f.height -textvariable pps(height) -width 10 grid $f.letter -padx 2 -pady 2 -sticky w grid $f.legal -padx 2 -pady 2 -sticky w grid $f.tabloid -padx 2 -pady 2 -sticky w grid $f.poster -padx 2 -pady 2 -sticky w grid $f.a4 -padx 2 -pady 2 -sticky w grid $f.other $f.title3 $f.width -padx 2 -pady 2 -sticky w grid $f.othermm $f.title4 $f.height -padx 2 -pady 2 -sticky w pack $w.pagesetup.layout $w.pagesetup.size \ -side top -fill both -expand true } # Process Cmds proc ProcessPageSetupCmd {varname iname} { upvar $varname var upvar $iname i global ds9 switch $ds9(wm) { x11 {ProcessPSPageSetupCmd var i} win32 {Win32PageSetup} aqua {MacOSXPageSetup} } } proc ProcessSendPageSetupCmd {proc id param} { global ds9 switch $ds9(wm) { x11 {ProcessSendPSPageSetupCmd $proc $id $param} win32 - aqua {} } } proc ProcessPSPageSetupCmd {varname iname} { upvar $varname var upvar $iname i global ps switch -- [string tolower [lindex $var $i]] { orientation - orient {incr i; set ps(orient) [string tolower [lindex $var $i]]} pagescale - scale {incr i; set ps(scale) [lindex $var $i]} pagesize - size {incr i; set ps(size) [string tolower [lindex $var $i]] } } } proc ProcessSendPSPageSetupCmd {proc id param} { global ps switch -- [string tolower $param] { orientation - orient {$proc $id "$ps(orient)\n"} pagescale - scale {$proc $id "$ps(scale)\n"} pagesize - size {$proc $id "$ps(size)\n"} } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/help.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000010560�12035605014�013324� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc HelpDef {} { global help global ds9 set help(refman) "$ds9(root)/doc/ref/index.html" set help(command) "$ds9(root)/doc/ref/command.html" set help(userman) "$ds9(root)/doc/user/index.html" set help(keyboard) "$ds9(root)/doc/ref/keyboard.html" set help(faq) "$ds9(root)/doc/faq.html" set help(new) "$ds9(root)/doc/new.html" set help(release) "$ds9(root)/doc/release/r7.0.html" set help(helpdesk) "$ds9(root)/doc/helpdesk.html" set help(story) "$ds9(root)/doc/story.html" set help(ack) "$ds9(root)/doc/acknowledgment.html" set help(vo) "$ds9(root)/doc/ref/vo.html" set help(about) "SAOImage DS9\nVersion $ds9(version)\n\nAuthors:\nWilliam Joye (Smithsonian Astrophysical Observatory)\nEric Mandel (Smithsonian Astrophysical Observatory)\nSteve Murray (Johns Hopkins University)\nJohn Roll (Smithsonian Astrophysical Observatory)\n\nTranslations:\nHans-Jakob Grimm (Smithsonian Astrophysical Observatory)\nAllan Hornstrup (Danmarks Tekniske Universitet)\nAlberto Martins (Universidade de Sao Paulo)\nManuel Perez Torres (Smithsonian Astrophysical Observatory)\nMasahiro Tsujimoto (Japan Aerospace Exploration Agency)\nPetr Kubánek (Institute of Physics, Prague)\nAlbert Kong (National Tsing Hua University)\nHao-Yuan Duan (National Tsing Hua University)\n\nSAOImage DS9 development has been made possible by funding from the Chandra X-ray Science Center (CXC) and the High Energy Astrophysics Science Archive Center (HEASARC). Additional funding was provided by the JWST Mission office at Space Telescope Science Institute to improve capabilities for 3-D data visualization." set help(email) "If you encounter any problems or have suggestions with ds9, please contact us at: saord@cfa.harvard.edu http://hea-www.harvard.edu/RD/ds9/ William Joye Eric Mandel Smithsonian Astrophysical Observatory Garden St. Cambridge, MA 02138 USA" set help(shortcuts) " DS9 version $ds9(version)\n\n\ Key Stroke Description\n\ ---------- -----------\n\ TAB Goto next frame\n\ DELETE Deletes selected regions\n\ R Print Mouse Coordinates and Pixel value.\n\ F Toggles Infobox freeze\n\ I Set include property for region\n\ E Set exclude property for region\n\ S Set source property for region\n\ B Set background property for region\n\ + Goto next 3D Fits Slice\n\ - Goto previous 3D Fits Slice\n\ Up Arrow Move selected regions/cursor up one pixel.\n\ Right Arrow Move selected regions/cursor right one pixel.\n\ Left Arrow Move selected regions/cursor left one pixel.\n\ Down Arrow Move selected regions/cursor down one pixel.\n\ Shift-Drag Select all regions within the indicated region.\n\ Control-Drag Selected ANNULUS Regions, will create new radii.\n " } proc HelpRef {} { global help HV hlpref [msgcat::mc {Reference Manual}] $help(refman) } proc HelpCommand {} { global help HV hlpcmd [msgcat::mc {Command}] $help(command) } proc HelpUser {} { global help HV hlpuser [msgcat::mc {User Manual}] $help(userman) } proc HelpKeyboard {} { global help HV hlpkeyboard [msgcat::mc {Keyboard Shortcuts}] $help(keyboard) } proc HelpFAQ {} { global help HV hlpfaq [msgcat::mc {FAQ}] $help(faq) } proc HelpNew {} { global help HV hlpnew [msgcat::mc {New Features}] $help(new) } proc HelpRelease {} { global help HV hlprelease [msgcat::mc {Release Notes}] $help(release) } proc HelpDesk {} { global help HV hlpdsk [msgcat::mc {Help Desk}] $help(helpdesk) } proc HelpStory {} { global help HV hlpstory [msgcat::mc {Story of SAOImage DS9}] $help(story) } proc HelpAck {} { global help HV hlpack [msgcat::mc {Acknowledgment}] $help(ack) } proc HelpVO {} { global help HV hlvo [msgcat::mc {Virtual Observatory}] $help(vo) } proc ProcessSendAboutCmd {proc id param sock fn} { global help ProcessSend $proc $id $sock $fn {.txt} "$help(about)\n" } ������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/hv.tcl���������������������������������������������������������������������������������0000644�0001750�0001750�00000063123�12131577017�013024� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc HVDef {} { global ihv set ihv(unique) 0 set ihv(windows) {} } # Public proc HV {varname title url {init {}} {sync 0}} { upvar #0 $varname var global $varname global ds9 global ihv global debug if {$debug(tcl,hv)} { puts stderr "HV $varname $title $url $init $sync" } set var(top) ".${varname}" set var(mb) ".${varname}mb" set w $var(top) set mb $var(mb) # see if we already have a window visible if {[winfo exists $w]} { raise $w } else { # add it to our xpa list lappend ihv(windows) $varname set var(widget) {} set var(status) {} set var(sync) $sync set var(frame) new set var(save) 0 set var(title) "$title" set var(copy) {} set var(search) {} set var(search,start) 0 set var(active) 0 set var(index) 0 set var(font) $ds9(times) set var(font,size) [PixelsToPoints -16] set var(font,weight) normal set var(font,slant) roman set var(init) $init set var(cookies) {} set var(images,forward) ${varname}forward set var(images,back) ${varname}back set var(images,reload) ${varname}reload set var(images,stop) ${varname}stop set var(images,gray) ${varname}gray # init some vars HVClearAll $varname set var(delete) 0 # create window Toplevel $w $mb 7 $title "HVDestroy $varname" $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {View}] -menu $mb.view $mb add cascade -label [msgcat::mc {Frame}] -menu $mb.frame menu $mb.file $mb.file add command -label [msgcat::mc {Open URL}] \ -command "HVURLDialogCmd $varname" $mb.file add command -label [msgcat::mc {Open File}] \ -command "HVFileDialogCmd $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Clear}] \ -command "HVClearCmd $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "HVDestroy $varname" menu $mb.edit $mb.edit add command -label [msgcat::mc {Cut}] \ -state disabled -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command "HVCopyCmd $varname" -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -state disabled -accelerator "${ds9(ctrl)}V" $mb.edit add separator $mb.edit add command -label "[msgcat::mc {Find}]..." \ -command "HVFindCmd $varname" -accelerator "${ds9(ctrl)}F" $mb.edit add command -label [msgcat::mc {Find Next}] \ -command "HVFindNextCmd $varname" -accelerator "${ds9(ctrl)}G" $mb.edit add separator $mb.edit add command -label [msgcat::mc {Clear Cache}] \ -command "HVClearCache $varname" menu $mb.view $mb.view add command -label [msgcat::mc {Back}] \ -command "HVBackCmd $varname" $mb.view add command -label [msgcat::mc {Forward}] \ -command "HVForwardCmd $varname" $mb.view add separator $mb.view add command -label [msgcat::mc {Stop}] \ -command "HVStopCmd $varname" $mb.view add command -label [msgcat::mc {Reload}] \ -command "HVReloadCmd $varname" $mb.view add separator $mb.view add cascade -label [msgcat::mc {Text}] \ -menu $mb.view.font $mb.view add separator $mb.view add command -label [msgcat::mc {Page Source}] \ -command "HVPageSourceCmd $varname" FontMenu $mb.view.font $varname font font,size font,weight \ font,slant [list HVFontCmd $varname] menu $mb.frame $mb.frame add checkbutton \ -label [msgcat::mc {Save Image on Download}] \ -variable ${varname}(save) $mb.frame add separator $mb.frame add radiobutton \ -label [msgcat::mc {Create New Frame on Download}] \ -variable ${varname}(frame) -value new $mb.frame add radiobutton \ -label [msgcat::mc {Use Current Frame on Download}] \ -variable ${varname}(frame) -value current image create photo $var(images,back) -data {R0lGODlhDwANAKL/AM///8DAwJD//y/I/y+X/y9n/wAAAAAAACH5BAEAAAEALAAAAAAPAA0AAAM0GLq2/qE0+AqYVFmB6eZFKEoRIAyCaaYCYWxDLM9uYBAxoe/7dA8ug3AoZOg6mRsyuUxmEgA7} image create photo $var(images,forward) -data {R0lGODlhDwANAKL/AM///8DAwJD//y/I/y+X/y9n/wAAAAAAACH5BAEAAAEALAAAAAAPAA0AAAM3GLpa/K8YSMuYlBVwV/kgCAhdsAFoig7ktA1wLA9SQdw4DkuB4f8/Ag2TMRB4GYUBmewRm09FAgA7} image create photo $var(images,stop) -data {R0lGODlhDQANALP/AP///1Lq81I5Of+EhCEAAHsAAMYAAP+UQv9zCHuMjP8AMf8AKf+MnK1CSv8QIQAAACH5BAEAAAEALAAAAAANAA0AAARWMMjUTC1J6ubOQYdiCBuIIMuiiCT1OWu6Ys05AMPC4ItBGB8dYMdI+RoHR4qY6v1CwlvRcEQ4brndwFAgJAwIRdPIzVTEYiqXJBEU1FQCW5Mg2O0ZSQQAOw==} image create photo $var(images,reload) -data {R0lGODlhDAANALP/AP///zk5OVJSUoSEhKWlpcDAwP//1v//xr3erZTOezGcEFKtSimce3NzezkxOQAAACH5BAEAAAUALAAAAAAMAA0AAARRcJBJyRilEMC5AcjQaB1wHMYkCFuXLKDQONsBLIuynEBAGAcJAnYy0AyGBOLENPg4qGUISTMdEIoEg4A6ohK6BND4YyqBqCdyve453vB44BEBADs=} image create photo $var(images,gray) -data {R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO} # Buttons set f [ttk::frame $w.buttons] ttk::button $f.back -image $var(images,back) \ -command "HVBackCmd $varname" ttk::button $f.forward -image $var(images,forward) \ -command "HVForwardCmd $varname" ttk::button $f.stop -image $var(images,stop) \ -command "HVStopCmd $varname" ttk::button $f.reload -image $var(images,reload) \ -command "HVReloadCmd $varname" pack $f.back $f.forward $f.stop $f.reload -side left # Param set f [ttk::frame $w.param] set var(widget) [html $f.html \ -yscrollcommand "$f.yscroll set" \ -xscrollcommand "$f.xscroll set" \ -padx 5 \ -pady 9 \ -formcommand "HVFormCB $varname" \ -imagecommand "HVImageCB $varname" \ -scriptcommand "HVScriptCB $varname"\ -appletcommand "HVAppletCB $varname" \ -framecommand "HVFrameCB $varname" \ -underlinehyperlinks 1 \ -bg white \ -width 640 \ -height 512 \ -fontcommand "HVFontCB $varname" \ -tablerelief raised \ ] $var(widget) token handler {NOSCRIPT} "HVNoScriptCB $varname" $var(widget) token handler {/NOSCRIPT} "HVNoScriptCB $varname" ttk::scrollbar $f.yscroll -orient vertical \ -command "$f.html yview" ttk::scrollbar $f.xscroll -orient horizontal \ -command "$f.html xview" grid $f.html $f.yscroll -sticky news grid $f.xscroll -stick news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 bind $var(widget).x <Motion> "HVMotion $varname %x %y" bind $var(widget).x <Button-1> "HVButton1 $varname %x %y" bind $var(widget).x <B1-Motion> "HVMotion1 $varname %x %y" bind $var(widget).x <ButtonRelease-1> "HVRelease1 $varname %x %y" bind $w <Up> "$f.html yview scroll -1 units" bind $w <Down> "$f.html yview scroll 1 units" bind $w <Right> "$f.html xview scroll 1 units" bind $w <Left> "$f.html xview scroll -1 units" bind $w <<Copy>> "HVCopyCmd $varname" switch $ds9(wm) { x11 { bind $w <Button-4> "HVMouseWheel $varname 1" bind $w <Button-5> "HVMouseWheel $varname -1" } win32 - aqua {bind $w <MouseWheel> "HVMouseWheel $varname %D"} } bind $w <<Find>> [list HVFindCmd $varname] bind $w <<FindNext>> [list HVFindNextCmd $varname] # Status set f [ttk::frame $w.status] ttk::label $f.status -textvariable ${varname}(status) \ -width 120 -anchor w pack $f.status -side left # Fini ttk::separator $w.sep -orient horizontal pack $w.status $w.sep -side bottom -fill x pack $w.buttons -side top -fill x pack $w.param -side top -fill both -expand true # we have a problem with the html widget. first time thur, some # structures are not allocated/initialized. if we first display # a blank page, all seems ok $var(widget) clear $var(widget) parse "<html>\n<body>\n<form method=\"get\" action=\"foo\">\n</form>\n</body>\n</html>" global debug if {$debug(tcl,idletasks)} { puts stderr "HV" } update idletasks } selection handle $w [list HVExportSelection $varname] if {$url != {}} { # no need to resolve HVLoadURL $varname $url {} $var(sync) } # windows: we're on top of the image window, so set focus to this window switch $ds9(wm) { x11 {} win32 {focus $w} aqua {} } } # Bindings proc HVMotion {varname x y} { upvar #0 $varname var global $varname global ds9 set url [$var(widget) href $x $y] if {[string length $url] > 0} { switch $ds9(wm) { x11 - win32 {$var(widget) configure -cursor hand2} aqua {$var(widget) configure -cursor pointinghand} } } else { $var(widget) configure -cursor {} } HVStatus $varname $url } proc HVButton1 {varname x y} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVButton1" } $var(widget) selection clear set var(sel,x) -1 set var(sel,y) -1 HVClearIndex $varname $var(index) set url [$var(widget) href $x $y] if {[string length $url] != 0} { HVResolveURL $varname $url } else { set var(sel,x) $x set var(sel,y) $y } } proc HVMotion1 {varname x y} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVMotion1" } if {$var(sel,x) != -1 && $var(sel,y) != -1} { $var(widget) selection set @$var(sel,x),$var(sel,y) @$x,$y } } proc HVRelease1 {varname x y} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVRelease1" } if {$var(sel,x) != -1 && $var(sel,y) != -1} { set var(copy) [$var(widget) text ascii @$var(sel,x),$var(sel,y) @$x,$y] selection own -command [list HVLostSelection $varname] $var(top) } } proc HVMouseWheel {varname cnt} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVMouseWheel" } $var(widget) yview scroll [expr -$cnt] units } # Commands proc HVClearCmd {varname} { upvar #0 $varname var global $varname # clear the widge and all images $var(widget) clear HVClearCache $varname HVClearAll $varname } proc HVCopyCmd {varname} { upvar #0 $varname var global $varname clipboard clear -displayof $var(top) clipboard append -displayof $var(top) $var(copy) } proc HVExportSelection {varname offset bytes} { upvar #0 $varname var global $varname if {$var(copy) != {}} { return [string range $var(copy) $offset [expr $offset+$bytes]] } } proc HVLostSelection {varname} { upvar #0 $varname var global $varname $var(widget) selection clear set var(copy) {} } proc HVURLDialogCmd {varname} { upvar #0 $varname var global $varname global debug set url "$var(url)" if {[EntryDialog [msgcat::mc {URL}] [msgcat::mc {Enter URL}] 80 url]} { if {[string length $url] == 0} { return } ParseURL $url r switch -- $r(scheme) { {} { # append 'http://' if needed if {[string range $r(path) 0 0] == "/"} { set url "http:/$url" } else { set url "http://$url" } if {$debug(tcl,hv)} { puts stderr "HVURLDialogCmd new $url" } } } # clear the base $var(widget) config -base {} HVClearIndex $varname 0 HVClearAll $varname # no need to resolve HVLoadURL $varname $url {} } } proc HVFileDialogCmd {varname} { upvar #0 $varname var global $varname global debug set fn [OpenFileDialog hvhtmlfbox] if {"$fn" != {}} { HVFileDialog $varname "$fn" } } proc HVFileDialog {varname fn} { upvar #0 $varname var global $varname global debug # clear the base $var(widget) config -base {} HVClearIndex $varname 0 HVClearAll $varname # no need to resolve HVLoadURL $varname "$fn" {} } proc HVBackCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVBackCmd index $var(index)" } incr ${varname}(index) -1 if {[info exists ${varname}(index,$var(index))]} { set url [lindex $var(index,$var(index)) 0] set query [lindex $var(index,$var(index)) 1] if {$debug(tcl,hv)} { puts stderr "HVBackCmd $var(index) $url $query" } # clear the base $var(widget) config -base {} # HVGotoHTML will incr the index again incr ${varname}(index) -1 # no need to resolve HVLoadURL $varname $url $query $var(sync) } else { incr ${varname}(index) } } proc HVFind {varname} { upvar #0 $varname var global $varname set toks [$var(widget) token list 1.0 end] set aa -1 set bb 0 set cc -1 set dd 0 set id -1 set ss $var(search,start) while {$ss<[llength $toks] && $cc==-1} { set pat [lindex $var(search) 0] set id [lsearch -glob -start $ss $toks "Text *$pat*"] if {$id != -1} { set ok 1 set aa $id set ss $id set tt [string first $pat [lindex [lindex $toks $aa] 1]] if {$tt != -1} { set bb $tt } for {set ii 1} {$ii<[llength $var(search)]} {incr ii} { set pat [lindex $var(search) $ii] set str [lindex [lindex $toks [expr $id+$ii*2]] 1] if {[string compare -length [string length $pat] $pat $str]} { incr ss set ok 0 break } } if {$ok} { set cc [expr $aa+([llength $var(search)]-1)*2] set tt [string last $pat [lindex [lindex $toks $cc] 1]] if {$tt != -1} { set dd [expr $tt+[string length $pat]] } } } else { break } } if {$aa == -1 || $cc == -1} { return 0 } else { set var(search,start) [expr $cc+1] $var(widget) selection set "[expr $aa+1].$bb" "[expr $cc+1].$dd" $var(widget) yview text "[expr $aa+1].$bb" return 1 } } proc HVFindCmd {varname} { upvar #0 $varname var global $varname set result "$var(search)" if {[EntryDialog [msgcat::mc {Search}] [msgcat::mc {Enter Search Expression}] 40 result]} { set var(search) "$result" set var(search,start) 0 $var(widget) selection clear if {![HVFind $varname]} { Error "$var(search) [msgcat::mc {Not Found}]" } } } proc HVFindNextCmd {varname} { upvar #0 $varname var global $varname if {$var(search,start) == 0} { HVFindCmd $varname } else { if {![HVFind $varname]} { # wrap set var(search,start) 0 if {![HVFind $varname]} { Error "$var(search) [msgcat::mc {Not Found}]" } } } } proc HVForwardCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVForwardCmd $var(index)" } incr ${varname}(index) if {[info exists ${varname}(index,$var(index))]} { set url [lindex $var(index,$var(index)) 0] set query [lindex $var(index,$var(index)) 1] if {$debug(tcl,hv)} { puts stderr "HVForwardCmd $var(index) $url $query" } # clear the base $var(widget) config -base {} # HVGotoHTML will incr the index again incr ${varname}(index) -1 # no need to resolve HVLoadURL $varname $url $query $var(sync) } else { incr ${varname}(index) -1 } } proc HVGotoCmd {varname nn} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVGotoCmd $nn" } set var(index) $nn if {[info exists ${varname}(index,$var(index))]} { set url [lindex $var(index,$var(index)) 0] set query [lindex $var(index,$var(index)) 1] if {$debug(tcl,hv)} { puts stderr "HVGotoCmd $var(index) $url $query" } # clear the base $var(widget) config -base {} # HVGotoHTML will incr the index again incr ${varname}(index) -1 # no need to resolve HVLoadURL $varname $url $query $var(sync) } else { incr ${varname}(index) } } proc HVReloadCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVReloadCmd" } # clear the base $var(widget) config -base {} # HVGotoHTML will incr the index again incr ${varname}(index) -1 # no need to resolve HVLoadURL $varname $var(url) $var(query) $var(sync) } proc HVStopCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "\n*** HVStopCmd ***\n" } HVCancel $varname } proc HVPageSourceCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVPageSourceCmd" } SimpleTextDialog ${varname}txt $var(url) 80 20 insert top $var(data) } proc HVFontCmd {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVFontCmd" } HVRefresh $varname } proc HVArchUserCmd {varname title url} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVArchUserCmd" } if {[string length $url] == 0} { return } ParseURL $url r switch -- $r(scheme) { {} { # append 'http://' if needed if {[string range $r(path) 0 0] == "/"} { set url "http:/$url" } else { set url "http://$url" } if {$debug(tcl,hv)} { puts stderr "HVArchUserCmd new $url" } } } HV $varname $title $url } proc HVAnalysisCmd {varname title url sync} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVAnalysisCmd $varname $title $url $sync" } if {[string length $url] == 0} { HV $varname "$title" {} {} $sync } else { ParseURL $url r switch -- $r(scheme) { {} { # append 'http://' if needed if {[string range $r(path) 0 0] == "/"} { set url "http:/$url" } else { set url "http://$url" } if {$debug(tcl,hv)} { puts stderr "HVAnalysisCmd new $url" } } } HV $varname "$title" $url {} $sync } } proc HVAnalysisURL {which i url sync} { set varname "at${which}${i}" global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVAnalysisURL $which $i $url" } set ${varname}(cookies) {} set ${varname}(sync) $sync HVClearAll $varname HVSetAnalysis $varname 1 $which $i HVLoadURL $varname $url {} $sync } proc HVAnalysisCancel {which i} { set varname "at${which}${i}" global $varname HVCancel $varname } # Archive Servers # Optical # Infrared # High Energy proc HVArchChandraChaser {} { global current set coord {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 degrees] set size \ [expr [lindex [$current(frame) get fits size wcs fk5 arcmin] 0]/2.] } } set l {} if {[string length $coord] != 0} { lappend l "1 lon [lindex $coord 0]" lappend l "1 lat [lindex $coord 1]" lappend l "1 radius $size" } global hvchandrachaser HV hvchandrachaser {Chandra Chaser} http://cda.harvard.edu/chaser/mainEntry.do $l } proc HVArchChandraPop {} { global current set coord {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 degrees] set size \ [expr [lindex [$current(frame) get fits size wcs fk5 arcmin] 0]/2.] } } set l {} if {[string length $coord] != 0} { lappend l "1 lon [lindex $coord 0]" lappend l "1 lat [lindex $coord 1]" lappend l "1 radius $size" lappend l "1 searchBy position" } global hvchandrapop HV hvchandrapop {Chandra Popular} http://cda.harvard.edu/pop/mainEntry.do $l } proc HVArchChandraFTP {} { global current set ra {} set dec {} set wid {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 sexagesimal] set ra [lindex $coord 0] set dec [lindex $coord 1] set wid [lindex [$current(frame) get fits size wcs fk5 degrees] 0] } } set l {} if {[string length $ra] != 0} { lappend l "1 ra \{$ra\}" lappend l "1 dec \{$dec\}" lappend l "1 wid \{$wid\}" } global hvchandraftp HV hvchandraftp {Chandra FTP} \ http://www.cfa.harvard.edu/archive/chandra/search $l } proc HVArchRosat {} { global current set ra {} set dec {} set cprd {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 sexagesimal] set ra [split [lindex $coord 0] :] set dec [split [lindex $coord 1] :] set raa "[lindex $ra 0]h[lindex $ra 1]m[lindex $ra 2]s" set decc "[lindex $dec 0]d[lindex $dec 1]m[lindex $dec 2]s" } } set l {} if {[string length $ra] != 0} { lappend l "1 lon \{$raa\}" lappend l "1 lat \{$decc\}" } lappend l "1 cprd im1 \{photon image 0.1-2.4 keV (fits)\}" global hvrosat HV hvrosat {Rosat All-Sky} \ http://www.xray.mpe.mpg.de/cgi-bin/rosat/rosat-survey $l } # Radio proc HVArchNVSS {} { global current set ra {} set dec {} set sra 1 set sdec 1 if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 sexagesimal] regsub -all {:} [lindex $coord 0] { } ra regsub -all {:} [lindex $coord 1] { } dec set s [$current(frame) get fits size wcs fk5 degrees] set sra [lindex $s 0] set sdec [lindex $s 1] if {$sra > 2} { set sra 2 } if {$sdec > 2} { set sdec 2 } } } set l {} if {[string length $ra] != 0} { lappend l "1 RA \{$ra\}" lappend l "1 Dec \{$dec\}" lappend l "1 Size \{$sra $sdec\}" } lappend l "1 Type \{image/x-fits\} \{FITS Image\}" global hvnvss HV hvnvss NVSS http://www.cv.nrao.edu/nvss/postage.shtml $l } proc HVArch4MASS {} { global current set ra {} set dec {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 sexagesimal] regsub -all {:} [lindex $coord 0] { } ra regsub -all {:} [lindex $coord 1] { } dec } } set l {} if {[string length $ra] != 0} { lappend l "1 RA \{$ra\}" lappend l "1 Dec \{$dec\}" } global hvmass4 HV hvmass4 4MASS http://www.cv.nrao.edu/4mass/findFITS.shtml $l } proc HVArchSIRTF {} { global current set ra {} set dec {} set sra 1 set sdec 1 if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 sexagesimal] regsub -all {:} [lindex $coord 0] { } ra regsub -all {:} [lindex $coord 1] { } dec set s [$current(frame) get fits size wcs fk5 arcmin] set sra [lindex $s 0] set sdec [lindex $s 1] } } set l {} if {[string length $ra] != 0} { lappend l "1 RA \{$ra\}" lappend l "1 Dec \{$dec\}" lappend l "1 Size \{$sra $sdec\}" } lappend l "1 Type \{image/x-fits\} \{FITS Image\}" global hvsirtf HV hvsirtf SIRTF http://www.cv.nrao.edu/sirtf_fls/SFpostage.shtml $l } proc HVArchFirst {} { global current set value {} set size {4.5} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set value [$current(frame) get fits center wcs fk5 sexagesimal] set size [lindex [$current(frame) get fits size wcs fk5 arcmin] 0] } } set l {} if {[string length $value] != 0} { lappend l "1 RA \{$value\}" lappend l "1 ImageSize \{$size\}" lappend l "1 ImageType \{FITS Image\}" } global hvfirst HV hvfirst First http://third.ucllnl.org/cgi-bin/firstcutout $l } # Other proc HVArchMontage {} { global current set value {} set size {} if {$current(frame) != {}} { if {[$current(frame) has wcs equatorial wcs]} { set coord [$current(frame) get fits center wcs fk5 degrees] set value "[lindex $coord 0] [lindex $coord 1] eq" set size [lindex [$current(frame) get fits size wcs fk5 degrees] 0] } } set l {} if {[string length $value] != 0} { lappend l "1 locstr \{$value\}" lappend l "1 size \{$size\}" } global hvmontage HV hvmontage {Montage} http://hachi.ipac.caltech.edu:8080/montage/ $l } # Process Cmds proc ProcessWebCmd {varname iname} { global ihv set w {hvweb} upvar $varname var upvar $iname i # determine which web browser window switch -- [string tolower [lindex $var $i]] { new { incr i set ii [lsearch $ihv(windows) $w] if {$ii>=0} { append w $ihv(unique) incr ihv(unique) } } close - clear - click {set w [lindex $ihv(windows) end]} default { set ii [lsearch $ihv(windows) [lindex $var $i]] if {$ii>=0} { set w [lindex $var $i] incr i } } } switch -- [string tolower [lindex $var $i]] { close {HVDestroy $w} clear {HVClearCmd $w} click { set vvarname $w upvar #0 $vvarname vvar global $vvarname incr i switch -- [string tolower [lindex $var $i]] { back {HVBackCmd $vvarname} forward {HVForwardCmd $vvarname} stop {HVStopCmd $vvarname} reload {HVReloadCmd $vvarname} default { set id [lindex $var $i] if {![info exists vvar(widget)]} { return } set tokens [$vvar(widget) token list 1.0 end] set cnt 0 for {set ii 0} {$ii<[llength $tokens]} {incr ii} { set tok [lindex $tokens $ii] if {[string tolower [lindex $tok 0]] == "markup" && [string tolower [lindex $tok 2]] == "href"} { set url [lindex $tok 3] incr cnt if {$cnt == $id} { HVResolveURL $vvarname [$vvar(widget) resolve $url] break; } } } } } } default { set url [lindex $var $i] if {[string length $url] == 0} { HV $w Web {} {} 1 } else { ParseURL $url r switch -- $r(scheme) { {} { # append 'http://' if needed if {[string range $r(path) 0 0] == "/"} { set url "http:/$url" } else { set url "http://$url" } } } HV $w Web $url {} 1 } } } } proc ProcessSendWebCmd {proc id param} { global ihv $proc $id "$ihv(windows)\n" } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/command.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000046307�12131577017�014032� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BadVisualError {} { global ds9 Error [msgcat::mc {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available}] exit } proc ProcessCommandLineFirst {} { global argc global argv global icolorbar global ds9 global pds9 set i 0 while {$i < $argc} { set item [lindex $argv $i] switch -- $item { -help { puts "For more information, use --help" QuitDS9 } -debug {incr i; ProcessDebugTclCmd argv i} -private {set icolorbar(private) true} -title { incr i set ds9(title) [lindex $argv $i] set t "SAOImage $ds9(title)" wm title $ds9(top) "$t" wm iconname $ds9(top) "$t" } -language { incr i set pds9(language) [lindex $argv $i] set pds9(language,name) [LanguageToName $pds9(language)] } -msg { incr i set pds9(language,dir) [lindex $argv $i] } -xpa {incr i; ProcessXPACmd argv i} } incr i } } proc ProcessCommandLine {} { global argc global argv ProcessCommand $argv $argc } proc ds9Cmd {argv} { ProcessCommand $argv [llength $argv] } proc ProcessCommand {argv argc} { global ds9 global pds9 global help global current global contour global colorbar global debug global wcs global view global grid global bin global scale global minmax global zscale global iis global file set file(type) fits set file(mode) {} set file(layer) {} set file(mosaic) wcs set load 0 set noopts 0 set i 0 # Note: -help is processed previously for fv (temporary) set item {} while {$i < $argc} { set item [lindex $argv $i] switch -- $item { -- {set noopts 1} -? - -help - --help {HelpCommand} -version { ProcessSendVersionCmd puts stdout {} QuitDS9 } -2mass {incr i; Process2MASSCmd argv i} -3d {incr i; Process3DCmd argv i} -about {ProcessSendAboutCmd puts stdout {} {} {}} -align {incr i; ProcessAlignCmd argv i} -analysis {incr i; ProcessAnalysisCmd argv i {} {}} -array {set file(type) array} -asinh {set scale(type) asinh; ChangeScale} -bg - -background {incr i; ProcessBgCmd argv i} -backup {incr i; ProcessBackupCmd argv i} -bin {incr i; ProcessBinCmd argv i} -blink {incr i; ProcessBlinkCmd argv i} -blue {set current(rgb) blue; RGBChannel} -cat - -catalog {incr i; ProcessCatalogCmd argv i} -cd {incr i; ProcessCDCmd argv i} -cmap {incr i; ProcessCmapCmd argv i} -colorbar {incr i; ProcessColorbarCmd argv i} -console {ProcessConsoleCmd argv i} -contours - -contour {incr i; ProcessContourCmd argv i} -nocontour {set contour(view) 0; ContourUpdate} -crop {incr i; ProcessCropCmd argv i} -crosshair {incr i; ProcessCrosshairCmd argv i} -cursor {incr i; ProcessCursorCmd argv i} -datacube - -cube {incr i; ProcessCubeCmd argv i} -debug {incr i; ProcessDebugCmd argv i} -dss - -dsssao {incr i; ProcessSAOCmd argv i} -dsseso {incr i; ProcessESOCmd argv i} -dssstsci {incr i; ProcessSTSCICmd argv i} -export {incr i; ProcessExportCmd argv i} -exit - -quit {ProcessQuitCmd argv i} -frame {incr i; ProcessFrameCmd argv i} -fifo { incr i set fifo [lindex $argv $i] if {$fifo!="none"} { set iis(ififo) ${fifo}i set iis(ofifo) ${fifo}o } else { set iis(ififo) none set iis(ofifo) none } } -fifo_only { set iis(port) 0 set iis(unix) none } -first {incr i; ProcessFIRSTCmd argv i} -file - -fits {set file(type) fits; CommandFitsCmd argv i} -geometry { # already processed } -gif {set file(type) gif} -green {set current(rgb) green; RGBChannel} -grid {incr i; ProcessGridCmd argv i} -nogrid {set grid(view) 0; GridUpdate} -header {incr i; ProcessHeaderCmd argv i} -height {incr i; ProcessHeightCmd argv i} -histequ {set scale(type) histequ; ChangeScale} -horzgraph { # backward compatibility set view(graph,horz) 1 UpdateView } -nohorzgraph { # backward compatibility set view(graph,horz) 0 UpdateView } -iconify {incr i; ProcessIconifyCmd argv i} -iis {incr i; ProcessIISCmd argv i} -info { # backward compatibility set view(info) 1 UpdateView } -noinfo { # backward compatibility set view(info) 0 UpdateView } -invert {set colorbar(invert) 1; InvertColorbar} -jpg - -jpeg {set file(type) jpeg} -language { # already processed incr i } -lock {incr i; ProcessLockCmd argv i} -linear {set scale(type) linear; ChangeScale} -log {set scale(type) log; ChangeScale} -lower {ProcessLowerCmd argv i} -magnifier {incr i; ProcessMagnifierCmd argv i} -nomagnifier { # backward compatibility set view(magnifier) 0 UpdateView } -mask {incr i; set file(layer) [ProcessMaskCmd argv i]} -nomask {set file(layer) {}} -match {incr i; ProcessMatchCmd argv i} -mecube {set file(type) mecube} -memf - -multiframe {set file(type) multiframe} -minmax {incr i; ProcessMinMaxCmd argv i} -minmaxmode { # backward compatibility incr i set minmax(mode) [lindex $argv $i] } -minmaxsample { # backward compatibility incr i set minmax(sample) [lindex $argv $i] } -mode {incr i; ProcessModeCmd argv i} -mosaic { set file(type) mosaic CommandMosaicCmd argv i } -mosaicimage { set file(type) mosaicimage CommandMosaicImageCmd argv i } -mosaicimageiraf { # backward compatibility set file(type) mosaicimage set file(mosaic) iraf } -mosaicimagewcs { # backward compatibility set file(type) mosaicimage set file(mosaic) wcs } -mosaicimagewfpc2 { # backward compatibility set file(type) mosaicimage set file(mosaic) wfpc2 } -mosaiciraf { # backward compatibility set file(type) mosaic set file(mosaic) iraf } -mosaicwcs { # backward compatibility set file(type) mosaic set file(mosaic) wcs } -savempeg - -movie {incr i; ProcessMovieCmd argv i} -msg { # already processed incr i } -nameserver {incr i; ProcessNRESCmd argv i} -nan {incr i; ProcessNanCmd argv i} -nrrd {set file(type) nrrd} -nvss {incr i; ProcessNVSSCmd argv i} -orient {incr i; ProcessOrientCmd argv i} -pagesetup {incr i; ProcessPageSetupCmd argv i} -pspagesetup {incr i; ProcessPSPageSetupCmd argv i} -pan {incr i; ProcessPanCmd argv i} -panner { # backward compatibility set view(panner) 1 UpdateView } -nopanner { # backward compatibility set view(panner) 0 UpdateView } -photo { # backward compatibility set file(type) tiff } -pixeltable {incr i; ProcessPixelTableCmd argv i} -nopixeltable {PixelTableDestroyDialog} -plot {incr i; ProcessPlotCmd argv i {} {}} -png {set file(type) png} -port {incr i; set iis(port) [lindex $argv $i]} -inet_only - -port_only { set iis(ififo) none set iis(ofifo) none set iis(unix) none } -pow {set scale(type) pow; ChangeScale} -prefs {incr i; ProcessPrefsCmd argv i} -preserve {incr i; ProcessPreserveCmd argv i} -print {incr i; ProcessPrintCmd argv i} -psprint {incr i; ProcessPSPrintCmd argv i} -private { #already processed } -raise {ProcessRaiseCmd argv i} -red {set current(rgb) red; RGBChannel} -region - -regions - -regionfile {incr i; ProcessRegionsCmd argv i {} {}} -restore {incr i; ProcessRestoreCmd argv i} -rgb {incr i; ProcessRGBCmd argv i} -rgbcube {set file(type) rgbcube} -srgbcube { # backward compatibility set file(type) srgbcube } -rgbimage {set file(type) rgbimage} -rgbarray {set file(type) rgbarray} -rotate {incr i; ProcessRotateCmd argv i} -samp {incr i; ProcessSAMPCmd argv i} -savefits - -save {incr i; ProcessSaveCmd argv i} -saveimage {incr i; ProcessSaveImageCmd argv i} -scale - -ztrans {incr i; ProcessScaleCmd argv i} -scalelims - -scalelimits { #backward compatibility incr i set scale(min) [lindex $argv $i] incr i set scale(max) [lindex $argv $i] ChangeScaleLimit } -scalemode { #backward compatibility incr i set scale(mode) [string tolower [lindex $argv $i]] ChangeScaleMode } -scalescope { #backward compatibility incr i set scale(scope) [string tolower [lindex $argv $i]] ChangeScaleScope } -sfits { # backward compatibility set file(type) sfits CommandSFitsCmd argv i } -shm {incr i; ProcessShmCmd argv i 1} -single {ProcessSingleCmd argv i} -sinh {set scale(type) sinh; ChangeScale} -skyview {incr i; ProcessSkyViewCmd argv i} -sleep {incr i; ProcessSleepCmd argv i} -slice {set file(mode) slice} -noslice {set file(mode) {}} -smooth {incr i; ProcessSmoothCmd argv i} -smosaic { # backward compatibility set file(type) smosaic CommandMosaicCmd argv i } -smosaiciraf { # backward compatibility set file(type) smosaic set file(mosaic) iraf } -smosaicwcs { # backward compatibility set file(type) smosaic set file(mosaic) wcs } -squared {set scale(type) squared; ChangeScale} -sqrt {set scale(type) sqrt; ChangeScale} -source {incr i; ProcessSourceCmd argv i} -tcl {incr i; set pds9(tcl) [FromYesNo [lindex $argv $i]]} -theme {incr i; ProcessThemeCmd argv i} -threads {incr i; ProcessThreadsCmd argv i} -tif - -tiff {set file(type) tiff} -tile {incr i; ProcessTileCmd argv i} -title { #already processed incr i } -unix {incr i; set iis(unix) [lindex $argv $i]} -unix_only { set iis(ififo) none set iis(ofifo) none set iis(port) 0 } -url {set file(type) url} -update {incr i; ProcessUpdateCmd argv i} -vertgraph { #backward compatibility set view(graph,vert) 1 UpdateView } -novertgraph { #backward compatibility set view(graph,vert) 0 UpdateView } -view {incr i; ProcessViewCmd argv i} -visual { #already processed } -vo {incr i; ProcessVOCmd argv i} -wcs {incr i; ProcessWCSCmd argv i {} {}} -wcsformat { #backward compatibility incr i set wcs(format,) [lindex $argv $i] } -web {incr i; ProcessWebCmd argv i} -width {incr i; ProcessWidthCmd argv i} -xpa {incr i; ProcessXPACmd argv i} -z1 { #backward compatibility incr i set scale(min) [lindex $argv $i] ChangeScaleLimit } -z2 { #backward compatibility incr i set scale(max) [lindex $argv $i] ChangeScaleLimit } -zscale {incr i; ProcessZScaleCmd argv i} -zmax {set scale(mode) zmax; ChangeScaleMode} -zoom {incr i; ProcessZoomCmd argv i} default { # allow abc, -, and -[foo] but not -abc if {!$noopts && [regexp -- {^-[a-zA-Z]+} $item]} { puts stderr "[msgcat::mc {Unknown command}]: $item" puts stderr "[msgcat::mc {For more information, use --help}]" return } if {$load == 0} { StartLoad incr load } switch $ds9(wm) { x11 - aqua {CommandLineLoad $item argv i} win32 { # if win32 and envoked via DOS shell # we must expand wildcards ourselves if {[catch {glob $item} fns]} { # cygwin/double click/DOS Shell no wildcards CommandLineLoad $item argv i } else { # DOS Shell with wildcards foreach fn $fns { CommandLineLoad $fn argv i } } } } FinishLoadPre } } incr i } if {$load != 0} { FinishLoadPost } } proc CommandLineLoad {item argvname iname} { upvar $argvname argv upvar $iname i global file global current if {$current(frame) != {}} { switch -- [$current(frame) get type] { base {CommandLineLoadBase $item $argvname $iname} rgb {CommandLineLoadRGB $item $argvname $iname} 3d {CommandLineLoad3D $item $argvname $iname} } } else { CommandLineLoadBase $item $argvname $iname } SetFileLast $file(type) $item } proc CommandLineLoadBase {item argvname iname} { upvar 2 $argvname argv upvar 2 $iname i global file global ds9 switch -- $file(type) { fits { # under windows, a double click on a # data file comes here switch $ds9(wm) { x11 {} aqua {} win32 { # normalize for "abc" but not "-abc", "-", and "-[foo]" # otherwise, things get weird if {![regexp -- {^-} $item]} { set item [file normalize [file nativename $item]] } } } MultiLoad $file(layer) $file(mode) LoadFitsFile $item $file(layer) $file(mode) } url { MultiLoad $file(layer) $file(mode) LoadURLFits $item $file(layer) $file(mode) } rgbimage { CreateRGBFrame LoadRGBImageFile $item } rgbcube { CreateRGBFrame LoadRGBCubeFile $item } mecube { MultiLoad LoadMECubeFile $item } multiframe { MultiLoad LoadMultiFrameFile $item } mosaicimage { MultiLoad $file(layer) switch -- $file(mosaic) { iraf {LoadMosaicImageIRAFFile $item $file(layer)} wfpc2 {LoadMosaicImageWFPC2File $item} default {LoadMosaicImageWCSFile $item $file(layer) $file(mosaic)} } } mosaic { switch -- $file(mosaic) { iraf {LoadMosaicIRAFFile $item $file(layer)} default {LoadMosaicWCSFile $item $file(layer) $file(mosaic)} } } sfits { #backward compatibility incr i MultiLoad $file(layer) $file(mode) LoadSFitsFile $item [lindex $argv $i] $file(layer) $file(mode) } srgbcube { #backward compatibility CreateRGBFrame incr i LoadSRGBCubeFile $item [lindex $argv $i] } smosaic { #backward compatibility incr i switch -- $file(mosaic) { iraf {LoadSMosaicIRAFFile $item [lindex $argv $i] $file(layer)} default {LoadSMosaicWCSFile $item [lindex $argv $i] $file(layer) $file(mosaic)} } } array { MultiLoad $file(layer) ImportArrayFile $item $file(layer) } rgbarray { CreateRGBFrame ImportRGBArrayFile $item } nrrd { MultiLoad $file(layer) ImportNRRDFile $item $file(layer) } gif - tiff - jpeg - png { MultiLoad {} $file(mode) ImportPhotoFile $item $file(mode) } } } proc CommandLineLoadRGB {item argvname iname} { upvar 2 $argvname argv upvar 2 $iname i global file switch -- $file(type) { fits {LoadFitsFile $item {} $file(mode)} url {LoadURLFits $item {} $file(mode)} rgbimage { MultiLoadRGB LoadRGBImageFile $item } rgbcube { MultiLoadRGB LoadRGBCubeFile $item } mecube {LoadMECubeFile $item} multiframe { # not supported } mosaicimage { switch -- $file(mosaic) { iraf {LoadMosaicImageIRAFFile $item {}} wfpc2 {LoadMosaicImageWFPC2File $item} default {LoadMosaicImageWCSFile $item {} $file(mosaic)} } } mosaic { switch -- $file(mosaic) { iraf {LoadMosaicIRAFFile $item {}} default {LoadMosaicWCSFile $item {} $file(mosaic)} } } sfits { #backward compatibility incr i LoadSFitsFile $item [lindex $argv $i] {} $file(mode) } srgbcube { #backward compatibility MultiLoadRGB incr i LoadSRGBCubeFile $item [lindex $argv $i] } smosaic { #backward compatibility incr i switch -- $file(mosaic) { iraf {LoadMosaicIRAFSFitsFile $item [lindex $argv $i] {}} default {LoadMosaicWCSSFitsFile $item [lindex $argv $i] {} $file(mosaic)} } } array {ImportArrayFile $item {}} rgbarray { MultiLoadRGB ImportRGBArrayFile $item } nrrd {ImportNRRDFile $item {}} gif - tiff - jpeg - png { MultiLoadRGB ImportPhotoFile $item $file(mode) } } } proc CommandLineLoad3D {item argvname iname} { upvar 2 $argvname argv upvar 2 $iname i global file switch -- $file(type) { fits { MultiLoad {} $file(mode) LoadFitsFile $item {} $file(mode) } url { MultiLoad {} $file(mode) LoadURLFits $item {} $file(mode) } rgbimage { CreateRGBFrame LoadRGBImageFile $item } rgbcube { CreateRGBFrame LoadRGBCubeFile $item } mecube { MultiLoad LoadMECubeFile $item } multiframe { MultiLoad LoadMultiFrameFile $item } mosaicimage { MultiLoad switch -- $file(mosaic) { iraf {LoadMosaicImageIRAFFile $item {}} wfpc2 {LoadMosaicImageWFPC2File $item} default {LoadMosaicImageWCSFile $item {} $file(mosaic)} } } mosaic { switch -- $file(mosaic) { iraf {LoadMosaicIRAFFile $item {}} default {LoadMosaicWCSFile $item {} $file(mosaic)} } } sfits { #backward compatibility incr i MultiLoad {} $file(mode) LoadSFitsFile $item [lindex $argv $i] {} $file(mode) } srgbcube { #backward compatibility CreateRGBFrame incr i LoadSRGBCubeFile $item [lindex $argv $i] } smosaic { #backward compatibility incr i switch -- $file(mosaic) { iraf {LoadMosaicIRAFSFitsFile $item [lindex $argv $i] {}} default {LoadMosaicWCSSFitsFile $item [lindex $argv $i] {} $file(mosaic)} } } array { MultiLoad ImportArrayFile $item {} } rgbarray { CreateRGBFrame ImportRGBArrayFile $item } nrrd { MultiLoad ImportNRRDFile $item {} } gif - tiff - jpeg - png { MultiLoad {} $file(mode) ImportPhotoFile $item $file(mode) } } } proc CommandFitsCmd {varname iname} { upvar $varname var upvar $iname i global file set item [string tolower [lindex $var [expr $i+1]]] switch -- $item { mosaicimage - mosaic { set file(type) $item incr i set item [string tolower [lindex $var [expr $i+1]]] switch -- $item { wfpc2 {incr i; set file(mosaic) wfpc2} default {CommandMosaicType $item $iname} } } mecube - multiframe - rgbcube - rgbimage { set file(type) $item incr i } } } proc CommandSFitsCmd {varname iname} { upvar $varname var upvar $iname i global file set item [string tolower [lindex $var [expr $i+1]]] switch -- $item { mosaic { set file(type) smosaic incr i set item [string tolower [lindex $var [expr $i+1]]] switch -- $item { wfpc2 {incr i; set file(mosaic) wfpc2} default {CommandMosaicType $item $iname} } } rgbcube { set file(type) srgbcube incr i } } } proc CommandMosaicImageCmd {varname iname} { upvar $varname var upvar $iname i global file set item [string tolower [lindex $var [expr $i+1]]] switch -- $item { wfpc2 {incr i; set file(mosaic) wfpc2} default {CommandMosaicType $item $iname} } } proc CommandMosaicCmd {varname iname} { upvar $varname var upvar $iname i global file set item [string tolower [lindex $var [expr $i+1]]] CommandMosaicType $item $iname } proc CommandMosaicType {sys iname} { upvar 2 $iname i global file switch $sys { iraf - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz { incr i set file(mosaic) $sys } default {set file(mosaic) wcs} } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotprint.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000006375�12023453610�014440� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotPSPrint {varname} { upvar #0 $varname var global $varname if {[PlotPrintDialog]} { if [catch {PlotPostScript $varname} printError] { Error "[msgcat::mc {An error has occurred while printing}] $printError" } } } proc PlotPostScript {varname} { upvar #0 $varname var global $varname global ps global ds9 global debug if {$debug(tcl,idletasks)} { puts stderr "PlotPostScript" } update idletasks # set postscript fonts $var(graph) configure \ -font "$var(titleFont) $var(titleSize) $var(titleWeight) $var(titleSlant)" $var(graph) xaxis configure \ -tickfont "$var(numlabFont) $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "$var(textlabFont) $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" $var(graph) yaxis configure \ -tickfont "$var(numlabFont) $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "$var(textlabFont) $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" set options "-decorations false" # Color switch -- $ps(color) { rgb - cmyk {append options " -greyscale no"} gray {append options " -greyscale yes"} } # Size set ww [expr [winfo width $var(top)]*$ps(scale)/100./[tk scaling]] set hh [expr [winfo height $var(top)]*$ps(scale)/100./[tk scaling]] append options " -width $ww -height $hh" # Page size switch -- $ps(size) { letter {append options " -paperwidth 8.5i -paperheight 11.i"} legal {append options " -paperwidth 8.5i -paperheight 14.i"} tabloid {append options " -paperwidth 11i -paperheight 17.i"} poster {append options " -paperwidth 36.i -paperheight 48.i"} a4 {append options " -paperwidth 195m -paperheight 282m"} other { if {$ps(width) != {} && $ps(height) != {}} { set w [expr $ps(width)] set h [expr $ps(height)] append options \ " -paperwidth [append $w i] -paperheight [append $h i]" } } othermm { if {$ps(width) != {} && $ps(height) != {}} { set w [expr $ps(width)] set h [expr $ps(height)] append options \ " -paperwidth [append $w m] -paperheight [append $h m]" } } } # Orientation switch -- $ps(orient) { portrait {append options " -landscape false"} landscape {append options " -landscape true"} } if {$ps(dest) == "file" && $ps(filename) != {}} { eval $var(graph) postscript output $ps(filename) $options } else { set ch [open "| $ps(cmd)" w] puts $ch [eval $var(graph) postscript output $options] close $ch } # reset fonts $var(graph) configure \ -font "{$ds9($var(titleFont))} $var(titleSize) $var(titleWeight) $var(titleSlant)" $var(graph) xaxis configure \ -tickfont "{$ds9($var(numlabFont))} $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "{$ds9($var(textlabFont))} $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" $var(graph) yaxis configure \ -tickfont "{$ds9($var(numlabFont))} $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "{$ds9($var(textlabFont))} $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/Makefile�������������������������������������������������������������������������������0000644�0001750�0001750�00000005646�12102563560�013345� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include SCRIPTS = \ 2mass.tcl \ 3d.tcl \ array.tcl \ analysis.tcl \ analysisparam.tcl \ annulus.tcl \ ar.tcl \ backup.tcl \ bin.tcl \ box.tcl \ boxannulus.tcl \ bpanda.tcl \ buttons.tcl \ cat.tcl \ catcds.tcl \ catcdssrch.tcl \ catcdssrchdialog.tcl \ catcmd.tcl \ catcxc.tcl \ catdialog.tcl \ catflt.tcl \ catmatch.tcl \ catned.tcl \ catopt.tcl \ catplot.tcl \ catreg.tcl \ catsdss.tcl \ catsimbad.tcl \ catskybot.tcl \ catsym.tcl \ cattsv.tcl \ catvot.tcl \ centroid.tcl \ circle.tcl \ colorbar.tcl \ comm.tcl \ command.tcl \ compass.tcl \ composite.tcl \ contour.tcl \ convert.tcl \ coord.tcl \ cpanda.tcl \ crop.tcl \ crosshair.tcl \ cube.tcl \ debug.tcl \ dialog.tcl \ ellipse.tcl \ ellipseannulus.tcl \ epanda.tcl \ error.tcl \ eso.tcl \ examine.tcl \ export.tcl \ external.tcl \ file.tcl \ fits.tcl \ first.tcl \ frame.tcl \ graph.tcl \ grid.tcl \ group.tcl \ header.tcl \ help.tcl \ http.tcl \ hv.tcl \ hvform.tcl \ hvsup.tcl \ iis.tcl \ imexam.tcl \ imgsvr.tcl \ import.tcl \ info.tcl \ layout.tcl \ line.tcl \ load.tcl \ magnifier.tcl \ marker.tcl \ markeranalysispanda.tcl \ markeranalysisplot2d.tcl \ markeranalysisplot3d.tcl \ markeranalysisradial.tcl \ markeranalysisstats.tcl \ markerbase.tcl \ markerbaseannulus.tcl \ markerbaseannulusrect.tcl \ markerbasecenter.tcl \ markerbaseline.tcl \ markerbasepanda.tcl \ markerbasepandarect.tcl \ markerdialog.tcl \ mask.tcl \ manalysis.tcl \ mbin.tcl \ mcolor.tcl \ mecube.tcl \ medit.tcl \ menu.tcl \ mfile.tcl \ mframe.tcl \ mhelp.tcl \ mosaicimage.tcl \ mosaicimageiraf.tcl \ mosaicimagewcs.tcl \ mosaicimagewfpc2.tcl \ mosaic.tcl \ mosaiciraf.tcl \ mosaicwcs.tcl \ movie.tcl \ mregion.tcl \ mscale.tcl \ multiframe.tcl \ mview.tcl \ mwcs.tcl \ mzoom.tcl \ nameres.tcl \ nrrd.tcl \ nsvr.tcl \ nvss.tcl \ pagesetup.tcl \ panner.tcl \ panzoom.tcl \ pixel.tcl \ photo.tcl \ plot.tcl \ plotbar.tcl \ plotdialog.tcl \ plotelement.tcl \ plotline.tcl \ plotprint.tcl \ plotprocess.tcl \ plotscatter.tcl \ point.tcl \ polygon.tcl \ prefs.tcl \ prefsdialog.tcl \ print.tcl \ projection.tcl \ open.tcl \ rgb.tcl \ rgbarray.tcl \ rgbcube.tcl \ rgbimage.tcl \ ruler.tcl \ samp.tcl \ sao.tcl \ save.tcl \ saveimage.tcl \ scale.tcl \ sfits.tcl \ shm.tcl \ skyview.tcl \ slider.tcl \ smosaic.tcl \ smosaiciraf.tcl \ smosaicwcs.tcl \ smooth.tcl \ source.tcl \ srgbcube.tcl \ starbase.tcl \ stdfbox.tcl \ stsci.tcl \ template.tcl \ text.tcl \ tkfbox.tcl \ url.tcl \ util.tcl \ var.tcl \ vector.tcl \ vo.tcl \ wcs.tcl \ xmfbox.tcl \ xpa.tcl INDEX = pkgIndex.tcl index : $(SCRIPTS) echo "pkg_mkIndex . $(SCRIPTS)" | ../bin/tclsh8.4 msgs : FORCE grep 'msgcat::mc' $(SCRIPTS) | cut -d[ -f2 | sed -e 's/::mc/::mcset AAA /' -e 's/]/ ""/' | sort | uniq > ../msgs/tmpl.tcl clean : FORCE $(RM) core *~ *# distclean : clean $(RM) $(INDEX) FORCE : ������������������������������������������������������������������������������������������./saods9/src/medit.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000024075�11703106714�013510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc EditMainMenu {} { global ds9 global current menu $ds9(mb).edit $ds9(mb).edit add command -label [msgcat::mc {Undo}] -command UndoFrame \ -accelerator "${ds9(ctrl)}Z" $ds9(mb).edit add separator $ds9(mb).edit add command -label [msgcat::mc {Cut}] -command CutFrame \ -accelerator "${ds9(ctrl)}X" $ds9(mb).edit add command -label [msgcat::mc {Copy}] -command CopyFrame \ -accelerator "${ds9(ctrl)}C" $ds9(mb).edit add command -label [msgcat::mc {Paste}] -command PasteFrame \ -accelerator "${ds9(ctrl)}V" $ds9(mb).edit add separator $ds9(mb).edit add radiobutton -label [msgcat::mc {None}] \ -variable current(mode) -value none -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Pointer}] \ -variable current(mode) -value pointer -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Crosshair}] \ -variable current(mode) -value crosshair -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Colorbar}] \ -variable current(mode) -value colorbar -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Pan}] \ -variable current(mode) -value pan -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Zoom}] \ -variable current(mode) -value zoom -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Rotate}] \ -variable current(mode) -value rotate -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Crop}] \ -variable current(mode) -value crop -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Catalog}] \ -variable current(mode) -value catalog -command ChangeMode $ds9(mb).edit add radiobutton -label [msgcat::mc {Examine}] \ -variable current(mode) -value examine -command ChangeMode switch $ds9(wm) { x11 - win32 { $ds9(mb).edit add separator $ds9(mb).edit add command -label "[msgcat::mc {Preferences}]..." \ -command PrefsDialog } aqua {} } # Bindings bind $ds9(top) <<Cut>> CutFrame bind $ds9(top) <<Copy>> CopyFrame bind $ds9(top) <<Paste>> PasteFrame } proc PrefsDialogEditMenu {w} { global ds9 set f [ttk::labelframe $w.medit -text [msgcat::mc {Edit}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarEdit $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add radiobutton -label [msgcat::mc {None}] \ -variable pcurrent(mode) -value none $m add radiobutton -label [msgcat::mc {Pointer}] \ -variable pcurrent(mode) -value pointer $m add radiobutton -label [msgcat::mc {Crosshair}] \ -variable pcurrent(mode) -value crosshair $m add radiobutton -label [msgcat::mc {Colorbar}] \ -variable pcurrent(mode) -value colorbar $m add radiobutton -label [msgcat::mc {Pan}] \ -variable pcurrent(mode) -value pan $m add radiobutton -label [msgcat::mc {Zoom}] \ -variable pcurrent(mode) -value zoom $m add radiobutton -label [msgcat::mc {Rotate}] \ -variable pcurrent(mode) -value rotate $m add radiobutton -label [msgcat::mc {Crop}] \ -variable pcurrent(mode) -value crop $m add radiobutton -label [msgcat::mc {Catalog}] \ -variable pcurrent(mode) -value catalog $m add radiobutton -label [msgcat::mc {Examine}] \ -variable pcurrent(mode) -value examine pack $f -side top -fill both -expand true } # Buttons proc ButtonsEditDef {} { global pbuttons array set pbuttons { edit,undo 0 edit,cut 0 edit,copy 0 edit,paste 0 edit,none 1 edit,pointer 1 edit,crosshair 1 edit,colorbar 1 edit,pan 1 edit,zoom 1 edit,rotate 1 edit,crop 1 edit,catalog 1 edit,examine 1 edit,prefs 0 } } proc CreateButtonsEdit {} { global buttons global ds9 global current ttk::frame $ds9(buttons).edit ButtonButton $ds9(buttons).edit.undo \ [string tolower [msgcat::mc {Undo}]] UndoFrame ButtonButton $ds9(buttons).edit.cut \ [string tolower [msgcat::mc {Cut}]] CutFrame ButtonButton $ds9(buttons).edit.copy \ [string tolower [msgcat::mc {Copy}]] CopyFrame ButtonButton $ds9(buttons).edit.paste \ [string tolower [msgcat::mc {Paste}]] PasteFrame RadioButton $ds9(buttons).edit.none \ [string tolower [msgcat::mc {None}]] \ current(mode) none ChangeMode RadioButton $ds9(buttons).edit.pointer \ [string tolower [msgcat::mc {Pointer}]] \ current(mode) pointer ChangeMode RadioButton $ds9(buttons).edit.crosshair \ [string tolower [msgcat::mc {Crosshair}]] \ current(mode) crosshair ChangeMode RadioButton $ds9(buttons).edit.colorbar \ [string tolower [msgcat::mc {Colorbar}]] \ current(mode) colorbar ChangeMode RadioButton $ds9(buttons).edit.pan \ [string tolower [msgcat::mc {Pan}]] \ current(mode) pan ChangeMode RadioButton $ds9(buttons).edit.zoom \ [string tolower [msgcat::mc {Zoom}]] \ current(mode) zoom ChangeMode RadioButton $ds9(buttons).edit.rotate \ [string tolower [msgcat::mc {Rotate}]] \ current(mode) rotate ChangeMode RadioButton $ds9(buttons).edit.crop \ [string tolower [msgcat::mc {Crop}]] \ current(mode) crop ChangeMode RadioButton $ds9(buttons).edit.catalog \ [string tolower [msgcat::mc {Catalog}]] \ current(mode) catalog ChangeMode RadioButton $ds9(buttons).edit.examine \ [string tolower [msgcat::mc {Examine}]] \ current(mode) examine ChangeMode ButtonButton $ds9(buttons).edit.prefs \ [string tolower [msgcat::mc {Preferences}]] PrefsDialog set buttons(edit) " $ds9(buttons).edit.undo pbuttons(edit,undo) $ds9(buttons).edit.cut pbuttons(edit,cut) $ds9(buttons).edit.copy pbuttons(edit,copy) $ds9(buttons).edit.paste pbuttons(edit,paste) $ds9(buttons).edit.none pbuttons(edit,none) $ds9(buttons).edit.pointer pbuttons(edit,pointer) $ds9(buttons).edit.crosshair pbuttons(edit,crosshair) $ds9(buttons).edit.colorbar pbuttons(edit,colorbar) $ds9(buttons).edit.pan pbuttons(edit,pan) $ds9(buttons).edit.zoom pbuttons(edit,zoom) $ds9(buttons).edit.rotate pbuttons(edit,rotate) $ds9(buttons).edit.crop pbuttons(edit,crop) $ds9(buttons).edit.catalog pbuttons(edit,catalog) $ds9(buttons).edit.examine pbuttons(edit,examine) $ds9(buttons).edit.prefs pbuttons(edit,prefs) " } proc PrefsDialogButtonbarEdit {f} { global ds9 global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Undo}] \ -variable pbuttons(edit,undo) -command {UpdateButtons buttons(edit)} $m add separator $m add checkbutton -label [msgcat::mc {Cut}] \ -variable pbuttons(edit,cut) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Copy}] \ -variable pbuttons(edit,copy) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Paste}] \ -variable pbuttons(edit,paste) -command {UpdateButtons buttons(edit)} $m add separator $m add checkbutton -label [msgcat::mc {None}] \ -variable pbuttons(edit,none) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Pointer}] \ -variable pbuttons(edit,pointer) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Crosshair}] \ -variable pbuttons(edit,crosshair) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Colorbar}] \ -variable pbuttons(edit,colorbar) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Pan}] \ -variable pbuttons(edit,pan) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Zoom}] \ -variable pbuttons(edit,zoom) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Rotate}] \ -variable pbuttons(edit,rotate) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Crop}] \ -variable pbuttons(edit,crop) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Catalog}] \ -variable pbuttons(edit,catalog) -command {UpdateButtons buttons(edit)} $m add checkbutton -label [msgcat::mc {Examine}] \ -variable pbuttons(edit,examine) -command {UpdateButtons buttons(edit)} $m add separator $m add checkbutton -label [msgcat::mc {Preferences}] \ -variable pbuttons(edit,prefs) -command {UpdateButtons buttons(edit)} } # Support proc UpdateEditMenu {} { global ds9 global current global marker global debug if {$debug(tcl,update)} { puts stderr "UpdateEditMenu" } switch -- $current(mode) { pointer { if {$current(frame) != {}} { set l [$current(frame) has marker undo] if {$l != {}} { $ds9(mb).edit entryconfig [msgcat::mc {Undo}] \ -state normal } else { $ds9(mb).edit entryconfig [msgcat::mc {Undo}] \ -state disabled } if {[$current(frame) has marker select]} { $ds9(mb).edit entryconfig [msgcat::mc {Cut}] \ -state normal $ds9(mb).edit entryconfig [msgcat::mc {Copy}] \ -state normal } else { $ds9(mb).edit entryconfig [msgcat::mc {Cut}] \ -state disabled $ds9(mb).edit entryconfig [msgcat::mc {Copy}] \ -state disabled } if {$marker(copy) != {} } { if {[$marker(copy) has marker paste]} { $ds9(mb).edit entryconfig [msgcat::mc {Paste}] \ -state normal } else { $ds9(mb).edit entryconfig [msgcat::mc {Paste}] \ -state disabled } } else { $ds9(mb).edit entryconfig [msgcat::mc {Paste}] \ -state disabled } } else { $ds9(mb).edit entryconfig [msgcat::mc {Undo}] -state disabled $ds9(mb).edit entryconfig [msgcat::mc {Cut}] -state disabled $ds9(mb).edit entryconfig [msgcat::mc {Copy}] -state disabled $ds9(mb).edit entryconfig [msgcat::mc {Paste}] -state disabled } } none - crosshair - colorbar - pan - zoom - rotate - crop - examine - catalog - imexam {$ds9(mb).edit entryconfig [msgcat::mc {Undo}] -state disabled} } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/vo.tcl���������������������������������������������������������������������������������0000644�0001750�0001750�00000031416�12124134150�013020� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc VODef {} { global ivo global pvo set ivo(top) .vo set ivo(mb) .vomb set ivo(server,host) {} set ivo(server,title) {} set ivo(server,url) {} set ivo(server,button) {} set ivo(ka,id) {} # prefs only set pvo(server) {http://cxc.harvard.edu/chandraed/list.txt} set pvo(hv) 1 # set pvo(method) xpa set pvo(method) mime set pvo(delay) 15 } proc VOKeepAlive { doka } { global ivo global pvo global xpa # if keep-alive turned off, just return if { $pvo(delay) <= 0 } return # count the connections set n 0 for {set ii 0} {$ii < [llength $ivo(server,button)]} {incr ii} { if {$ivo(b$ii)} { incr n break } } # no connections => kill existing keep-alive, if necessary if { $n == 0 } { if { $ivo(ka,id) != {} } { after cancel $ivo(ka,id) set ivo(ka,id) {} } } else { # yes connections # send a keep-alive, if necessary if { $doka } { # puts [format "send keepalive: %s (%d)" [exec date] $pvo(delay)] xpanskeepalive $xpa } # arrange for the next one set ivo(ka,id) [after [expr $pvo(delay) * 60 * 1000] VOKeepAlive 1] } } proc VOCancel {varname} { upvar #0 $varname var global $varname # set state to 0 so that we don't process the finish proc set var(active) 0 if {[info exists var(token)]} { http::reset $var(token) } } proc VODestroy {varname} { upvar #0 $varname var global $varname VOCancel $varname if {[winfo exists $var(top)]} { destroy $var(top) destroy $var(mb) } unset $varname } proc VOReset {varname} { upvar #0 $varname var global $varname set var(active) 0 if {[info exists var(token)]} { http::cleanup $var(token) unset var(token) } } proc VODone {varname} { upvar #0 $varname var global $varname VOReset $varname } proc VOCancelled {varname} { upvar #0 $varname var global $varname VOReset $varname } proc VOError {varname message} { upvar #0 $varname var global $varname Error $message VOReset $varname } proc VODialog {{sync 0}} { global ivo global pvo global ds9 if [winfo exists $ivo(top)] { raise $ivo(top) return } set varname voi upvar #0 $varname var global $varname # variables set var(top) $ivo(top) set var(mb) $ivo(mb) set var(sync) $sync # create the window set w $var(top) set mb $var(mb) Toplevel $w $mb 6 [msgcat::mc {Virtual Observatory}] "VODestroy $varname" $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command "VOApply $varname" $mb.file add command -label [msgcat::mc {Cancel}] \ -command "VOCancel $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Help Me Choose}] \ -command HelpVO $mb.file add command -label [msgcat::mc {Configure}] \ -command [list PrefsDialog http] $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "VODestroy $varname" # Sites ttk::labelframe $w.param -text [msgcat::mc {Sites}] -padding 2 # Browser set f [ttk::labelframe $w.opt -text [msgcat::mc {Browser}] -padding 2] set var(hv,button) [ttk::checkbutton $w.opt.hv \ -text [msgcat::mc {Use Internal Web Browser}] \ -variable pvo(hv) \ -command SavePrefs] ttk::radiobutton $w.opt.xpa \ -text [msgcat::mc {Connect Directly}] \ -variable pvo(method) -value xpa -command PrefsVOMethod ttk::radiobutton $w.opt.http \ -text [msgcat::mc {Connect Using Web Proxy}] \ -variable pvo(method) -value mime -command PrefsVOMethod grid $w.opt.hv -padx 2 -pady 2 -sticky w grid $w.opt.xpa $w.opt.http -padx 2 -pady 2 -sticky w set f [ttk::frame $w.buttons] ttk::button $f.help -text [msgcat::mc {Help Me Choose}] \ -command HelpVO ttk::button $f.proxy -text [msgcat::mc {Configure}] \ -command [list PrefsDialog http] ttk::button $f.close -text [msgcat::mc {Close}] \ -command "VODestroy $varname" pack $f.help $f.proxy $f.close -side left -expand true -padx 2 -pady 4 # Fini grid $w.param -sticky news grid $w.opt -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 if {[string length $ivo(server,host)] == 0} { VOApply $varname } else { set l [llength $ivo(server,host)] for {set ii 0} {$ii<$l} {incr ii} { set b [lindex $ivo(server,button) $ii] checkbutton $b -text "[lindex $ivo(server,title) $ii] ([lindex $ivo(server,url) $ii])" -variable ivo(b$ii) -command "VOCheck $varname $ii" pack $b -anchor w -padx 2 -pady 2 # update color if {$ivo(b$ii)} { $b configure -selectcolor yellow global debug if {$debug(tcl,idletasks)} { puts stderr "VODialog" } update idletasks $b configure -selectcolor green } else { $b configure -selectcolor yellow $b select global debug if {$debug(tcl,idletasks)} { puts stderr "VODialog" } update idletasks $b configure -selectcolor {} $b deselect } } } } proc VOApply {varname} { upvar #0 $varname var global $varname global ivo global pvo global xpa set w $var(top) # delete old servers for {set ii 0} {$ii < [llength $ivo(server,button)]} {incr ii} { catch {xparemote $xpa [lindex $ivo(server,host) $ii] - -proxy} catch {destroy [lindex $ivo(server,button) $ii]} catch {unset ivo(b$ii)} } set ivo(server,host) {} set ivo(server,title) {} set ivo(server,url) {} set ivo(server,button) {} VOFindServer $varname if {$var(url) != {}} { VOLoad $varname } else { # hardcode set rr {chandra-ed.cfa.harvard.edu:28571 Chandra-Ed Archive Server http://chandra-ed.cfa.harvard.edu/archive.html chandra-ed.rutgers.edu:28571 New Rutgers X-ray Analysis Server http://chandra-ed.rutgers.edu/archive.html basho.rutgers.edu:28571 Back-up Rutgers X-ray Analysis Server http://basho.rutgers.edu/archive.html} VOParse $varname $rr } # start or stop the keep-alive, as needed VOKeepAlive 0 } proc VOFindServer {varname} { upvar #0 $varname var global $varname global pvo if {[VOCheckServer $varname $pvo(server)]} { return } if {[VOCheckServer $varname {http://cxc.harvard.edu/chandraed/list.txt}]} { return } if {[VOCheckServer $varname {http://cxc.harvard.edu/chandraed/test.txt}]} { return } if {[VOCheckServer $varname {http://chandra-ed.rutgers.edu/vo/list.txt}]} { return } if {[VOCheckServer $varname {http://chandra-ed.cfa.harvard.edu/vo/list.txt}]} { return } } proc VOCheckServer {varname url} { upvar #0 $varname var global $varname ParseURL $url rr if {[checkdns $rr(authority) 3 1] == 0} { set var(url) $url return 1 } else { set var(url) {} return 0 } } proc VOLoad {varname} { upvar #0 $varname var global $varname global ihttp if {$var(sync)} { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 VOFinish $varname $var(token) } else { VOError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } else { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -command [list VOFinish $varname] \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 } else { VOError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } } proc VOFinish {varname token} { upvar #0 $varname var global $varname if {!($var(active))} { VOCancelled $varname return } upvar #0 $token t # Code set code [http::ncode $token] # Meta set meta $t(meta) # Log it HTTPLog $token # Result? switch -- $code { 200 - 203 - 503 { VOParse $varname [http::data $var(token)] VODone $varname } 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $meta { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,hv)} { puts stderr "VOFinish redirect $code to $value" } # clean up and resubmit http::cleanup $token unset var(token) set var(url) $value VOLoad $varname } } } default {VOError $varname [msgcat::mc {An error has occured while updating VO server list}]} } } proc VOParse {varname rr} { upvar #0 $varname var global $varname global ivo set w $var(top) set data [string trimright $rr \n] set lines [split $data \n] set len [llength $lines] for {set ii 0} {$ii<$len} {incr ii} { set line [lindex $lines $ii] set b "$w.param.b$ii" set ll [split $line \t] lappend ivo(server,host) [lindex $ll 0] lappend ivo(server,title) [lindex $ll 1] lappend ivo(server,url) [lindex $ll 2] lappend ivo(server,button) $b checkbutton $b -text "[lindex $ivo(server,title) $ii] ([lindex $ivo(server,url) $ii])" -variable ivo(b$ii) -command "VOCheck $varname $ii" pack $b -anchor w -padx 2 -pady 2 } } proc VOCheck {varname ii} { upvar #0 $varname var global $varname global ivo global pvo global xpa set w $var(top) set b "$w.param.b$ii" if {$ivo(b$ii)} { $b configure -selectcolor yellow global debug if {$debug(tcl,idletasks)} { puts stderr "VOCheck" } update idletasks switch $pvo(method) { mime {} xpa { if {[info exists xpa]} { if {[catch {xparemote $xpa \ [lindex $ivo(server,host) $ii] + -proxy}]} { # if xpa unavailable, switch to mime # $b configure -selectcolor {} # $b deselect # set ivo(b$ii) 0 Info [msgcat::mc {Unable to connect directly: using Web Proxy}] set pvo(method) mime } } } } $b configure -selectcolor green if {$pvo(hv)} { set url [lindex $ivo(server,url) $ii] ParseURL $url r HV "vo$ii" "$r(authority)" $url {} $var(sync) } } else { $b configure -selectcolor yellow $b select global debug if {$debug(tcl,idletasks)} { puts stderr "VOCheck" } update idletasks switch $pvo(method) { mime {} xpa { catch {xparemote $xpa [lindex $var(server,host) $ii] - -proxy} } } $b configure -selectcolor {} $b deselect } # start or stop the keep-alive, as needed VOKeepAlive 0 } proc PrefsVOMethod {} { global pvo switch $pvo(method) { mime {set pvo(hv) 1} xpa {} } } # Process Cmds proc ProcessVOCmd {varname iname} { upvar $varname var upvar $iname i set vvarname voi upvar #0 $vvarname vvar global $vvarname global ivo global pvo switch -- [string tolower [lindex $var $i]] { open {VODialog} close {VODestroy $vvarname} method { incr i set pvo(method) [lindex $var $i] } server { incr i set pvo(server) [lindex $var $i] } internal { incr i set pvo(hv) [FromYesNo [lindex $var $i]] } delay { incr i set pvo(delay) [lindex $var $i] } connect { incr i VODialog 1 # find best match set ii [lsearch $ivo(server,url) "*[lindex $var $i]*"] if {$ii>=0} { set ivo(b$ii) 1 VOCheck $vvarname $ii } } disconnect { incr i VODialog 1 # find best match set ii [lsearch $ivo(server,url) "*[lindex $var $i]*"] if {$ii>=0} { set ivo(b$ii) 0 VOCheck $vvarname $ii } } default { VODialog 1 # find best match set ii [lsearch $ivo(server,url) "*[lindex $var $i]*"] if {$ii>=0} { set ivo(b$ii) 1 VOCheck $vvarname $ii } } } } proc ProcessSendVOCmd {proc id param} { global ivo global pvo switch -- [string tolower $param] { method {$proc $id "$pvo(method)\n"} server {$proc $id "$pvo(server)\n"} internal {$proc $id [ToYesNo $pvo(hv)]} delay {$proc $id "$pvo(delay)\n"} connect { # current connections set len [llength $ivo(server,button)] set rr {} for {set ii 0} {$ii<$len} {incr ii} { if {$ivo(b$ii)} { append rr "[lindex $ivo(server,host) $ii] [lindex $ivo(server,title) $ii] [lindex $ivo(server,url) $ii] $ivo(b$ii)\n" } } $proc $id $rr } default { VODialog 1 # all possible connections set len [llength $ivo(server,button)] set rr {} for {set ii 0} {$ii<$len} {incr ii} { append rr "[lindex $ivo(server,host) $ii] [lindex $ivo(server,title) $ii] [lindex $ivo(server,url) $ii] $ivo(b$ii)\n" } $proc $id $rr } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catcdssrchdialog.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000030621�11700665566�015715� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATCDSSrchDialog {varname} { upvar #0 $varname var global $varname global ds9 global pcat global icatcdssrch global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchDialog $varname" } # main dialog set var(top) ".${varname}" set var(mb) ".${varname}mb" if [winfo exists $var(top)] { raise $var(top) return } # defaults # maybe modified if pcat(vot) set var(list,wave,param) $icatcdssrch(list,wave,param) set var(list,wave) $icatcdssrch(list,wave) set var(list,mission,param) $icatcdssrch(list,mission,param) set var(list,mission) $icatcdssrch(list,mission) set var(list,astro,param) $icatcdssrch(list,astro,param) set var(list,astro) $icatcdssrch(list,astro) # AR variables set var(status) {} set var(sync) 0 # CATCDSSrch variables set var(catdb) ${varname}catdb set var(server) $pcat(server) set var(source) {} set var(words) {} set var(wave) {} set var(mission) {} set var(astro) {} # create the window set w $var(top) set mb $var(mb) Toplevel $w $mb 7 [msgcat::mc {Search for Catalogs}] \ "CATCDSSrchDestroy $varname" # file $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Retrieve}] \ -command "CATCDSSrchApply $varname" $mb.file add command -label [msgcat::mc {Cancel}] \ -command "ARCancel $varname" $mb.file add command -label [msgcat::mc {Catalog}] \ -command "CATCDSSrchCatalog $varname" $mb.file add command -label [msgcat::mc {Clear}] \ -command "CATCDSSrchClear $varname" $mb.file add separator $mb.file add command -label "[msgcat::mc {Load}]..." \ -command "CATCDSSrchLoadFile $varname" $mb.file add command -label "[msgcat::mc {Save}]..." \ -command "CATCDSSrchSaveFile $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "CATCDSSrchDestroy $varname" # edit AREditMenu $varname # catalog server CATServerMenu $varname # Param set f [ttk::frame $w.param] ttk::frame $f.name ttk::frame $f.words ttk::frame $f.srch pack $f.name -side top -fill x -expand true pack $f.words -side top -fill x -expand true pack $f.srch -side bottom -fill both -expand true # param name ttk::label $f.name.title -text [msgcat::mc {Name or Designation}] ttk::entry $f.name.source -textvariable ${varname}(source) pack $f.name.title -side top -anchor w -padx 2 -pady 2 pack $f.name.source -side top -anchor w -padx 2 -pady 2 -fill x -expand true # param keywords ttk::label $f.words.title \ -text [msgcat::mc {Words matching title, description}] ttk::entry $f.words.key -textvariable ${varname}(words) -width 45 pack $f.words.title -side top -anchor w -padx 2 -pady 2 pack $f.words.key -side top -anchor w -padx 2 -pady 2 -fill x -expand true # param search ttk::frame $f.srch.wave ttk::frame $f.srch.mission ttk::frame $f.srch.astro pack $f.srch.wave $f.srch.mission $f.srch.astro \ -side left -fill both -expand true -padx 2 -pady 2 # param search wave ttk::frame $f.srch.wave.f ttk::label $f.srch.wave.title -text [msgcat::mc {Wavelength}] pack $f.srch.wave.title -side top -anchor w pack $f.srch.wave.f -side bottom -fill both -expand true \ -anchor w -padx 2 -pady 2 ttk::scrollbar $f.srch.wave.f.scroll \ -command [list $f.srch.wave.f.list yview] set ${varname}(listbox,wave) [listbox $f.srch.wave.f.list \ -yscroll \ [list $f.srch.wave.f.scroll set] \ -setgrid true \ -selectmode browse \ -exportselection 0 \ -listvariable ${varname}(list,wave)] grid $f.srch.wave.f.list $f.srch.wave.f.scroll -sticky news grid rowconfigure $f.srch.wave.f 0 -weight 1 grid columnconfigure $f.srch.wave.f 0 -weight 1 # param search mission ttk::frame $f.srch.mission.f ttk::label $f.srch.mission.title -text [msgcat::mc {Mission}] pack $f.srch.mission.title -side top -anchor w pack $f.srch.mission.f -side bottom -fill both -expand true \ -anchor w -padx 2 -pady 2 ttk::scrollbar $f.srch.mission.f.scroll \ -command [list $f.srch.mission.f.list yview] set ${varname}(listbox,mission) [listbox $f.srch.mission.f.list \ -yscroll \ [list $f.srch.mission.f.scroll set] \ -setgrid true \ -selectmode browse \ -exportselection 0 \ -listvariable ${varname}(list,mission)] grid $f.srch.mission.f.list $f.srch.mission.f.scroll \ -sticky news grid rowconfigure $f.srch.mission.f 0 -weight 1 grid columnconfigure $f.srch.mission.f 0 -weight 1 # param search astro ttk::frame $f.srch.astro.f ttk::label $f.srch.astro.title -text [msgcat::mc {Astronomy}] pack $f.srch.astro.title -side top -anchor w pack $f.srch.astro.f -side bottom -fill both -expand true \ -anchor w -padx 2 -pady 2 ttk::scrollbar $f.srch.astro.f.scroll \ -command [list $f.srch.astro.f.list yview] set ${varname}(listbox,astro) [listbox $f.srch.astro.f.list \ -yscroll \ [list $f.srch.astro.f.scroll set] \ -setgrid true \ -selectmode browse \ -exportselection 0 \ -listvariable ${varname}(list,astro)] grid $f.srch.astro.f.list $f.srch.astro.f.scroll -sticky news grid rowconfigure $f.srch.astro.f 0 -weight 1 grid columnconfigure $f.srch.astro.f 0 -weight 1 # Table set f [ttk::frame $w.tbl] set var(tbl) [table $f.t \ -state disabled \ -usecommand 0 \ -variable $var(catdb) \ -colorigin 1 \ -roworigin 0 \ -cols $icatcdssrch(mincols) \ -rows $icatcdssrch(minrows) \ -colstretchmode all \ -width -1 \ -height -1 \ -maxwidth 400 \ -maxheight 190 \ -titlerows 1 \ -xscrollcommand [list $f.xscroll set]\ -yscrollcommand [list $f.yscroll set]\ -selecttype row \ -selectmode extended \ -anchor w \ -font [font actual TkDefaultFont] ] ttk::scrollbar $f.yscroll -command [list $var(tbl) yview] \ -orient vertical ttk::scrollbar $f.xscroll -command [list $var(tbl) xview] \ -orient horizontal grid $var(tbl) $f.yscroll -sticky news grid $f.xscroll -stick news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Status set f [ttk::frame $w.status] ttk::label $f.title -text [msgcat::mc {Status}] ttk::label $f.item -textvariable ${varname}(status) pack $f.title $f.item -side left -anchor w -padx 2 -pady 2 # Buttons set f [ttk::frame $w.buttons] set var(apply) [ttk::button $f.apply \ -text [msgcat::mc {Retrieve}] \ -command "CATCDSSrchApply $varname"] set var(cancel) [ttk::button $f.cancel \ -text [msgcat::mc {Cancel}] \ -command "ARCancel $varname" -state disabled] ttk::button $f.catalog -text [msgcat::mc {Catalog}] \ -command "CATCDSSrchCatalog $varname" ttk::button $f.clear -text [msgcat::mc {Clear}] \ -command "CATCDSSrchClear $varname" ttk::button $f.close -text [msgcat::mc {Close}] \ -command "CATCDSSrchDestroy $varname" pack $f.apply $f.cancel $f.catalog $f.clear $f.close \ -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal ttk::separator $w.stbl -orient horizontal ttk::separator $w.sstatus -orient horizontal pack $w.buttons $w.sstatus $w.status $w.stbl -side bottom -fill x pack $w.param $w.sep -side top -fill x pack $w.tbl -side top -fill both -expand true ARStatus $varname {} # initialize $var(listbox,wave) selection set 0 $var(listbox,mission) selection set 0 $var(listbox,astro) selection set 0 $w.param.name.source select range 0 end } proc CATCDSSrchApply {varname} { upvar #0 $varname var global $varname global icatcdssrch global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchApply $varname" } set id [$var(listbox,wave) curselection] if {$id > 0} { set var(wave) [lindex $var(list,wave) $id] } else { set var(wave) {} } set id [$var(listbox,mission) curselection] if {$id > 0} { set var(mission) [lindex $var(list,mission) $id] } else { set var(mission) {} } set id [$var(listbox,astro) curselection] if {$id > 0} { set var(astro) [lindex $var(list,astro) $id] } else { set var(astro) {} } ARApply $varname ARStatus $varname [msgcat::mc {Searching for catalogs}] CATCDSSrch $varname } proc CATCDSSrchDestroy {varname} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchDestroy $varname" } if [info exists $var(catdb)] { unset $var(catdb) } ARDestroy $varname } proc CATCDSSrchConfig {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchConfig $varname" } set site [CATCDSURL $var(server)] set cgidir {viz-bin} set script {votable} set var(url) "http://$site/$cgidir/$script" set var(query) [http::formatQuery -meta.aladin all] CATCDSSrchConfigLoad $varname return } proc CATCDSSrchConfigLoad {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchConfigLoad $varname" } set var(proc,parser) CATCDSSrchConfigParse set var(proc,done) CATCDSSrchConfigDone set var(proc,load) CATCDSSrchConfigLoad CATGetURL $varname return } proc CATCDSSrchConfigDone {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchConfigDone $varname" } CATCDSSrchConfigParse } proc CATCDSSrchConfigParse {t token} { upvar #0 $t T global $t global debug global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchConfigParse" } if {$debug(tcl,cat)} { set fp [open debug.xml w] puts $fp [http::data $token] close $fp } set xml [xml::parser \ -elementstartcommand [list CATCDSSrchConfigElemStartCB $t] \ -elementendcommand [list CATCDSSrchConfigElemEndCB $t] \ -ignorewhitespace 1 \ ] set T(tree,enable) 0 set T(tree,state) {} if [catch {$xml parse [http::data $token]} err] { if {$debug(tcl,cat)} { puts stderr "CATCDSSrchConfigParse: $err" } } unset ${t}(tree,enable) unset ${t}(tree,state) $xml free } proc CATCDSSrchConfigElemStartCB {t name attlist args} { upvar #0 $t T global $t global debug # hardcoded set varname catcdssrch1 upvar #0 $varname var global $varname switch -- $name { RESOURCE { set id {} set type {} foreach {key value} $attlist { switch -- [string tolower $key] { type {set type "$value"} id {set id "$value"} } } if {[string tolower $id] == "vizier"} { set T(tree,enable) 1 set ${varname}(list,wave) [list none] set ${varname}(list,mission) [list none] set ${varname}(list,astro) [list none] } } PARAM { if {$T(tree,enable)} { set id {} set fname {} foreach {key value} $attlist { switch -- [string tolower $key] { name {set fname "$value"} id {set id "$value"} } } set T(tree,state) [string trim [string tolower $id]] switch -- $T(tree,state) { wavelength {set ${varname}(list,wave,param) $fname} mission {set ${varname}(list,mission,param) $fname} astronomy {set ${varname}(list,astro,param) $fname} } } } VALUES {} OPTION { if {$T(tree,enable)} { set item {} foreach {key value} $attlist { switch -- [string tolower $key] { value {set item "$value"} } } if {$item != {}} { global icatcdssrch switch -- $T(tree,state) { wavelength {lappend ${varname}(list,wave) $item} mission {lappend ${varname}(list,mission) $item} astronomy {lappend ${varname}(list,astro) $item} } } } } } return {} } proc CATCDSSrchConfigElemEndCB {t name args} { upvar #0 $t T global $t global debug # we can't count on this being called for all end-tags switch -- $name { RESOURCE { # ok, we're done set T(tree,enable) 0 return -code break } } return {} } ���������������������������������������������������������������������������������������������������������������./saods9/src/markerbase.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000022267�11725742035�014531� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBaseDialog {varname} { upvar #0 $varname var global $varname set tt [$var(frame) get marker $var(id) type] switch -- [lindex $tt 1] { point {set type "[string totitle [lindex $tt 0]] [string totitle [lindex $tt 1]]"} {} {set type [string totitle [lindex $tt 0]]} } # variables - some may already be initialized (compass,ruler) if {![info exists var(system)]} { set rr [$var(frame) get wcs] set var(system) [lindex $rr 0] set var(sky) [lindex $rr 1] set var(skyformat) [lindex $rr 2] } AdjustCoordSystem $varname system # init MarkerBaseTextCB $varname MarkerBaseColorCB $varname MarkerBaseLineWidthCB $varname MarkerBasePropertyCB $varname MarkerBaseFontCB $varname $var(proc,coordCB) $varname # callbacks $var(frame) marker $var(id) callback delete MarkerBaseDeleteCB $varname $var(frame) marker $var(id) callback text MarkerBaseTextCB $varname $var(frame) marker $var(id) callback color MarkerBaseColorCB $varname $var(frame) marker $var(id) callback width MarkerBaseLineWidthCB $varname $var(frame) marker $var(id) callback property MarkerBasePropertyCB $varname $var(frame) marker $var(id) callback font MarkerBaseFontCB $varname # window Toplevel $var(top) $var(mb) 6 [msgcat::mc "$type"] \ "$var(proc,close) $varname" # menus MarkerBaseMenu $varname MarkerBaseFileMenu $varname EditMenu $var(mb) $varname ColorMenu $var(mb).color $varname color [list MarkerBaseColor $varname] WidthDashMenu $var(mb).width $varname linewidth dash \ [list MarkerBaseLineWidth $varname] \ [list MarkerBaseProperty $varname dash] MarkerBasePropertyMenu $varname FontMenu $var(mb).font $varname font font,size font,weight \ font,slant [list MarkerBaseFont $varname] # Param set f [ttk::frame $var(top).param] ttk::label $f.tid -text [msgcat::mc {Number}] ttk::label $f.id -text "$var(id)" ttk::label $f.ttext -text [msgcat::mc {Text}] ttk::entry $f.text -textvariable ${varname}(text) -width 45 grid $f.tid $f.id -padx 2 -pady 2 -sticky w grid $f.ttext $f.text - - - -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $var(top).buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command "$var(proc,apply) $varname" ttk::button $f.close -text [msgcat::mc {Close}] \ -command "$var(proc,close) $varname" pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 bind $var(top) <Return> "$var(proc,apply) $varname" # Fini ttk::separator $var(top).sep -orient horizontal pack $var(top).buttons $var(top).sep -side bottom -fill x pack $var(top).param -side top -fill both -expand true # some window managers need a hint raise $var(top) } # actions proc MarkerBaseClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback delete MarkerBaseDeleteCB $var(frame) marker $var(id) delete callback text MarkerBaseTextCB $var(frame) marker $var(id) delete callback color MarkerBaseColorCB $var(frame) marker $var(id) delete callback width MarkerBaseLineWidthCB $var(frame) marker $var(id) delete callback property MarkerBasePropertyCB $var(frame) marker $var(id) delete callback font MarkerBaseFontCB MarkerBaseDeleteCB $varname unset $varname } proc MarkerBaseApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) text \{$var(text)\} UpdateRegionMenu } proc MarkerBaseColor {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) color $var(color) } proc MarkerBaseLineWidth {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) width $var(linewidth) } proc MarkerBaseProperty {varname prop} { upvar #0 $varname var global $varname $var(frame) marker $var(id) property $prop $var($prop) } proc MarkerBaseFont {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) font \ \"$var(font) $var(font,size) $var(font,weight) $var(font,slant)\" } # callbacks proc MarkerBaseDeleteCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseDeleteCB" } # variables foreach m [array names marker] { set mm [split $m ,] if {[lindex $mm 0] == $var(frame) && [lindex $mm 1] == $var(id)} { unset marker($m) } } # destroy the window and menubar if {[winfo exists $var(top)]} { destroy $var(top) destroy $var(mb) } } proc MarkerBaseTextCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseTextCB" } set var(text) [$var(frame) get marker $var(id) text] } proc MarkerBaseColorCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseColorCB" } set var(color) [$var(frame) get marker $var(id) color] } proc MarkerBaseLineWidthCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseLineWidthCB" } set var(linewidth) [$var(frame) get marker $var(id) width] } proc MarkerBasePropertyCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePropertyCB" } set var(dash) [$var(frame) get marker $var(id) property dash] set var(fixed) [$var(frame) get marker $var(id) property fixed] set var(edit) [$var(frame) get marker $var(id) property edit] set var(move) [$var(frame) get marker $var(id) property move] set var(rotate) [$var(frame) get marker $var(id) property rotate] set var(delete) [$var(frame) get marker $var(id) property delete] set var(include) [$var(frame) get marker $var(id) property include] set var(source) [$var(frame) get marker $var(id) property source] } proc MarkerBaseFontCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseFontCB" } set f [$var(frame) get marker $var(id) font] set var(font) [lindex $f 0] set var(font,size) [lindex $f 1] set var(font,weight) [lindex $f 2] set var(font,slant) [lindex $f 3] } proc MarkerBaseCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseCoordCB" } AdjustCoordSystem $varname system } # menus proc MarkerBaseMenu {varname} { upvar #0 $varname var global $varname $var(mb) add cascade -label [msgcat::mc {File}] -menu $var(mb).file $var(mb) add cascade -label [msgcat::mc {Edit}] -menu $var(mb).edit $var(mb) add cascade -label [msgcat::mc {Color}] -menu $var(mb).color $var(mb) add cascade -label [msgcat::mc {Width}] -menu $var(mb).width $var(mb) add cascade -label [msgcat::mc {Property}] -menu $var(mb).properties $var(mb) add cascade -label [msgcat::mc {Font}] -menu $var(mb).font } proc MarkerBaseFileMenu {varname} { upvar #0 $varname var global $varname menu $var(mb).file $var(mb).file add command -label [msgcat::mc {Apply}] \ -command "$var(proc,apply) $varname" $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Close}] \ -command "$var(proc,close) $varname" } proc MarkerBasePropertyMenu {varname} { upvar #0 $varname var global $varname menu $var(mb).properties $var(mb).properties add checkbutton -label [msgcat::mc {Fixed in Size}] \ -variable ${varname}(fixed) \ -command "MarkerBaseProperty $varname fixed" $var(mb).properties add separator $var(mb).properties add checkbutton -label [msgcat::mc {Can Edit}] \ -variable ${varname}(edit) \ -command "MarkerBaseProperty $varname edit" $var(mb).properties add checkbutton -label [msgcat::mc {Can Move}] \ -variable ${varname}(move) \ -command "MarkerBaseProperty $varname move" $var(mb).properties add checkbutton -label [msgcat::mc {Can Rotate}] \ -variable ${varname}(rotate) \ -command "MarkerBaseProperty $varname rotate" $var(mb).properties add checkbutton -label [msgcat::mc {Can Delete}] \ -variable ${varname}(delete) \ -command "MarkerBaseProperty $varname delete" $var(mb).properties add separator $var(mb).properties add radiobutton -label [msgcat::mc {Include}] \ -variable ${varname}(include) -value 1 \ -command "MarkerBaseProperty $varname include" $var(mb).properties add radiobutton -label [msgcat::mc {Exclude}] \ -variable ${varname}(include) -value 0 \ -command "MarkerBaseProperty $varname include" $var(mb).properties add separator $var(mb).properties add radiobutton -label [msgcat::mc {Source}] \ -variable ${varname}(source) -value 1 \ -command "MarkerBaseProperty $varname source" $var(mb).properties add radiobutton -label [msgcat::mc {Background}] \ -variable ${varname}(source) -value 0 \ -command "MarkerBaseProperty $varname source" } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/win32.tcl������������������������������������������������������������������������������0000755�0001750�0001750�00000001136�11700665572�013355� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc Win32Print {} { global ds9 # we need to be realized RealizeDS9 # need the colorbar levels updated UpdateColormapLevel if {[win32 pm print begin [winfo width $ds9(canvas)] [winfo height $ds9(canvas)] yes]} { foreach f $ds9(frames) { $f win32 print } colorbar win32 print colorbarrgb win32 print win32 pm print end } } proc Win32PageSetup {} { win32 pm pagesetup } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerbasepanda.tcl��������������������������������������������������������������������0000644�0001750�0001750�00000013124�12030663665�015526� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBasePandaDialog {varname} { upvar #0 $varname var global $varname global pmarker # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord set var(method) dist set var(init) 0 # base MarkerBaseAnnulusDialog $varname # menus MarkerBaseAnnulusMethodMenu $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisPandaDialog $varname # callbacks # $var(frame) marker $var(id) callback move $var(proc,editCB) $varname $var(frame) marker $var(id) callback edit $var(proc,editCB) $varname $var(frame) marker $var(id) callback end edit $var(proc,editCB) $varname set f $var(top).param # Angles ttk::label $f.tang1 -text [msgcat::mc {Start}] ttk::label $f.tang2 -text [msgcat::mc {End}] ttk::label $f.tangles -text [msgcat::mc {Angles}] ttk::entry $f.ang1 -textvariable ${varname}(ang1) -width 13 ttk::entry $f.ang2 -textvariable ${varname}(ang2) -width 13 ttk::label $f.uangles -text [msgcat::mc {Degrees}] ttk::label $f.tangnum -text [msgcat::mc {Number}] ttk::entry $f.angnum -textvariable ${varname}(angnum) -width 13 grid x $f.tang1 $f.tang2 -padx 2 -pady 2 -sticky w grid $f.tangles $f.ang1 $f.ang2 $f.uangles -padx 2 -pady 2 -sticky w grid $f.tangnum $f.angnum -padx 2 -pady 2 -sticky w # Radius set f [ttk::labelframe $var(top).radius -text [msgcat::mc {Radius}] \ -padding 2] set var(annulitxt) [text $f.txt \ -height 15 \ -width 15 \ -wrap none \ -font [font actual TkDefaultFont] \ -yscrollcommand [list $f.yscroll set] \ ] ttk::scrollbar $f.yscroll -command [list $var(annulitxt) yview] \ -orient vertical grid $var(annulitxt) $f.yscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Radius Fini grid $var(top).radius -row 0 -column 1 -sticky news grid rowconfigure $var(top) 0 -weight 1 grid columnconfigure $var(top) 1 -weight 1 # Angles set f [ttk::labelframe $var(top).angles -text [msgcat::mc {Angles}] \ -padding 2] set var(angtxt) [text $f.txt \ -height 15 \ -width 15 \ -wrap none \ -font [font actual TkDefaultFont] \ -yscrollcommand [list $f.yscroll set] \ ] ttk::scrollbar $f.yscroll -command [list $var(angtxt) yview] \ -orient vertical grid $var(angtxt) $f.yscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Angles Fini grid $var(top).angles -row 0 -column 2 -sticky news grid rowconfigure $var(top) 0 -weight 1 grid columnconfigure $var(top) 2 -weight 1 set var(init) 1 } # actions proc MarkerBasePandaClose {varname} { upvar #0 $varname var global $varname # $var(frame) marker $var(id) delete callback move $var(proc,editCB) $var(frame) marker $var(id) delete callback edit $var(proc,editCB) $var(frame) marker $var(id) delete callback end edit $var(proc,editCB) MarkerBaseCenterClose $varname } proc MarkerBasePandaApply {varname} { upvar #0 $varname var global $varname set levels {} regsub -all "\n" "[$var(annulitxt) get 1.0 end]" " " levels # and trim any trailing spaces set levels [string trimright $levels " "] set angles {} regsub -all "\n" "[$var(angtxt) get 1.0 end]" " " angles # and trim any trailing spaces set angles [string trimright $angles " "] if {($levels != {}) && ($angles != {})} { $var(frame) marker $var(id) $var(which) edit \ "\{$angles\}" "\{$levels\}" $var(system) $var(sky) \ $var(dcoord) $var(dformat) } MarkerBaseCenterApply $varname } proc MarkerBasePandaGenerateAngles {varname} { upvar #0 $varname var global $varname $var(angtxt) delete 1.0 end set ang1 $var(ang1) set ang2 $var(ang2) set angnum $var(angnum) if {($ang1 != {}) && ($ang2 != {}) && ($angnum != {})} { # normalize between 0 <= ang < 360 if {[::math::fuzzy::tgt $ang1 0]} { while {[::math::fuzzy::tge $ang1 360]} { set ang1 [expr $ang1-360] } } else { while {[::math::fuzzy::tlt $ang1 0]} { set ang1 [expr $ang1+360] } } if {[::math::fuzzy::tgt $ang2 0]} { while {[::math::fuzzy::tge $ang2 360]} { set ang2 [expr $ang2-360] } } else { while {[::math::fuzzy::tlt $ang2 0]} { set ang2 [expr $ang2+360] } } # with ang2 > ang1 while {[::math::fuzzy::tge $ang1 $ang2]} { set ang2 [expr $ang2+360] } for {set i 0} {$i<=$angnum} {incr i} { set v [expr ((($ang2-$ang1)/double($angnum))*$i)+$ang1] $var(angtxt) insert end "$v\n" } } } # callbacks proc MarkerBasePandaCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePandaCoordCB" } MarkerAnalysisPandaSystem $varname MarkerAnalysisStatsSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname if {$var(init)} { $var(proc,editCB) $varname } } proc MarkerBasePandaDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePandaDistCB" } $var(proc,editCB) $varname } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotline.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000024353�12132042644�014231� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotLineTool {} { global iap PlotLine $iap(tt) [msgcat::mc {Line Plot Tool}] {} {} {} 2 {} } proc PlotLine {tt wtt title xaxis yaxis dim data} { global iap # make the window name unique set ii [lsearch $iap(windows) $tt] if {$ii>=0} { append tt $iap(unique) incr iap(unique) } # set the window title if none if {$wtt == {}} { set wtt $tt } set varname $tt upvar #0 $varname var global $varname PlotLineProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogLine $varname PlotDataSet $varname $dim $data $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc PlotLineDialog {varname wtt title xaxis yaxis} { upvar #0 $varname var global $varname PlotLineProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogLine $varname } proc PlotLineProc {varname} { upvar #0 $varname var global $varname set var(proc,updategraph) PlotLineUpdateGraph set var(proc,createelement) PlotLineCreateElement set var(proc,updateelement) PlotLineUpdateElement set var(proc,highlite) PlotLineHighliteElement set var(proc,button) PlotLineButton } proc PlotDialogLine {varname} { upvar #0 $varname var global $varname global pap set var(seq) 1 set var(discrete) $pap(discrete) set var(linear) $pap(linear) set var(step) $pap(step) set var(quadratic) $pap(quadratic) set var(error) $pap(error) set var(bar) 0 # element $var(mb).element add cascade -label [msgcat::mc {Discrete}] \ -menu $var(mb).element.discrete $var(mb).element add cascade -label [msgcat::mc {Linear}] \ -menu $var(mb).element.linear $var(mb).element add cascade -label [msgcat::mc {Step}] \ -menu $var(mb).element.step $var(mb).element add cascade -label [msgcat::mc {Quadratic}] \ -menu $var(mb).element.quadratic $var(mb).element add cascade -label [msgcat::mc {Error}] \ -menu $var(mb).element.error # discrete menu $var(mb).element.discrete $var(mb).element.discrete add checkbutton -label [msgcat::mc {Show}] \ -variable ${varname}(discrete) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.discrete add separator $var(mb).element.discrete add cascade -label [msgcat::mc {Color}] \ -menu $var(mb).element.discrete.color $var(mb).element.discrete add cascade -label [msgcat::mc {Shape}] \ -menu $var(mb).element.discrete.shape ColorMenu $var(mb).element.discrete.color $varname discrete,color \ [list PlotUpdateElementDiscrete $varname] menu $var(mb).element.discrete.shape $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Circle}] \ -variable ${varname}(discrete,symbol) -value circle \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Diamond}] \ -variable ${varname}(discrete,symbol) -value diamond \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Plus}] \ -variable ${varname}(discrete,symbol) -value plus \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Cross}] \ -variable ${varname}(discrete,symbol) -value cross \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add separator $var(mb).element.discrete.shape add checkbutton \ -label [msgcat::mc {Fill}] \ -variable ${varname}(discrete,fill) \ -command [list PlotUpdateElementDiscrete $varname] # linear menu $var(mb).element.linear $var(mb).element.linear add checkbutton \ -label [msgcat::mc {Show}] \ -variable ${varname}(linear) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.linear add separator $var(mb).element.linear add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.linear.color $var(mb).element.linear add cascade \ -label [msgcat::mc {Line}] \ -menu $var(mb).element.linear.line ColorMenu $var(mb).element.linear.color $varname linear,color \ [list PlotUpdateElementLinear $varname] PlotCreateLineMenu $var(mb).element.linear.line \ ${varname}(linear,width) ${varname}(linear,dash) \ [list PlotUpdateElementLinear $varname] # step menu $var(mb).element.step $var(mb).element.step add checkbutton \ -label [msgcat::mc {Show}] \ -variable ${varname}(step) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.step add separator $var(mb).element.step add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.step.color $var(mb).element.step add cascade \ -label [msgcat::mc {Line}] \ -menu $var(mb).element.step.line ColorMenu $var(mb).element.step.color $varname step,color \ [list PlotUpdateElementStep $varname] PlotCreateLineMenu $var(mb).element.step.line \ ${varname}(step,width) ${varname}(step,dash) \ [list PlotUpdateElementStep $varname] # quadratic menu $var(mb).element.quadratic $var(mb).element.quadratic add checkbutton \ -label [msgcat::mc {Show}] \ -variable ${varname}(quadratic) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.quadratic add separator $var(mb).element.quadratic add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.quadratic.color $var(mb).element.quadratic add cascade \ -label [msgcat::mc {Line}] \ -menu $var(mb).element.quadratic.line ColorMenu $var(mb).element.quadratic.color $varname quadratic,color \ [list PlotUpdateElementQuadratic $varname] PlotCreateLineMenu $var(mb).element.quadratic.line \ ${varname}(quadratic,width) ${varname}(quadratic,dash) \ [list PlotUpdateElementQuadratic $varname] # error menu $var(mb).element.error $var(mb).element.error add checkbutton \ -label [msgcat::mc {Show}] \ -variable ${varname}(error) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.error add separator $var(mb).element.error add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.error.color $var(mb).element.error add cascade \ -label [msgcat::mc {Line}] \ -menu $var(mb).element.error.line ColorMenu $var(mb).element.error.color $varname error,color \ [list PlotUpdateElementError $varname] WidthDashMenu $var(mb).element.error.line $varname error,width {} \ [list PlotUpdateElementError $varname] {} # graph set var(graph) [blt::graph $var(top).line \ -width 600 -height 500 \ -plotrelief groove \ -plotborderwidth 2 \ ] $var(graph) legend configure -hide yes pack $var(graph) -expand yes -fill both PlotChangeMode $varname } proc PlotLineUpdateGraph {varname} { upvar #0 $varname var global $varname if {$var(graph,x,auto)} { set xmin {} set xmax {} } else { set xmin $var(graph,x,min) set xmax $var(graph,x,max) } if {$var(graph,y,auto)} { set ymin {} set ymax {} } else { set ymin $var(graph,y,min) set ymax $var(graph,y,max) } $var(graph) xaxis configure -min $xmin -max $xmax \ -descending $var(graph,x,flip) $var(graph) yaxis configure -min $ymin -max $ymax \ -descending $var(graph,y,flip) PlotUpdateGraph $varname } proc PlotLineCreateElement {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } # delete current elements set nn $var(data,current) foreach el [$var(graph) element names] { set f [split $el -] if {[lindex $f 1] == $nn} { $var(graph) element delete $el } } # discrete if {$var(discrete,fill)} { set clr $var(discrete,color) } else { set clr {} } $var(graph) element create "d-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -linewidth 0 -pixels 5 \ -symbol $var(discrete,symbol) \ -fill $clr \ -outline $var(discrete,color) \ -color $var(discrete,color) # linear if {$var(linear,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element create "l-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -smooth linear -symbol {} \ -linewidth $var(linear,width) \ -color $var(linear,color) \ -dashes $dash # step if {$var(step,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element create "s-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -smooth step -symbol {} \ -linewidth $var(step,width) \ -color $var(step,color) \ -dashes $dash # quadratic # note: quadratic does not work when flipped if {$var(quadratic,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element create "q-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -smooth quadratic -symbol {} \ -linewidth $var(quadratic,width) \ -color $var(quadratic,color) \ -dashes $dash # error if {$var(xedata) != {}} { if {[$var(xedata) length] != 0} { PlotCreateErrorX $varname } } if {$var(yedata) != {}} { if {[$var(yedata) length] != 0} { PlotCreateErrorY $varname } } # do this to force an update in case of no visible elements $var(graph) legend configure -hide yes } proc PlotLineUpdateElement {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,discrete) $var(discrete) set var($nn,linear) $var(linear) set var($nn,step) $var(step) set var($nn,quadratic) $var(quadratic) set var($nn,error) $var(error) $var(graph) element configure "d-${nn}" -hide [expr !$var(discrete)] $var(graph) element configure "l-${nn}" -hide [expr !$var(linear)] $var(graph) element configure "s-${nn}" -hide [expr !$var(step)] $var(graph) element configure "q-${nn}" -hide [expr !$var(quadratic)] foreach mk [$var(graph) marker names "m-${nn}*"] { $var(graph) marker configure $mk -hide [expr !$var(error)] } } proc PlotLineButton {varname x y} { upvar #0 $varname var global $varname } proc PlotLineHighliteElement {varname rowlist} { upvar #0 $varname var global $varname } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/info.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000074170�12005565645�013352� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CreateInfoPanel {} { global ds9 global pds9 global view global infobox # Panel Frame set ds9(panel) [ttk::frame $ds9(main).panel] set ds9(panel,sep) [ttk::separator $ds9(main).spanel -orient horizontal] # Info set ds9(info) [ttk::frame $ds9(panel).info] ttk::frame $ds9(info).dummy ttk::label $ds9(info).fileTitle -text [msgcat::mc {File}] ttk::label $ds9(info).fileValue -relief groove \ -textvariable infobox(filename) ttk::label $ds9(info).objTitle -text [msgcat::mc {Object}] ttk::label $ds9(info).objValue -relief groove \ -textvariable infobox(object) ttk::label $ds9(info).minmaxTitle \ -text "[msgcat::mc {Min}] [msgcat::mc {Max}]" ttk::label $ds9(info).minValue -relief groove \ -textvariable infobox(min) -anchor center ttk::label $ds9(info).maxValue -relief groove \ -textvariable infobox(max) -anchor center ttk::label $ds9(info).lowhighTitle \ -text "[msgcat::mc {Low}] [msgcat::mc {High}]" ttk::label $ds9(info).lowValue -relief groove \ -textvariable infobox(low) -anchor center ttk::label $ds9(info).highValue -relief groove \ -textvariable infobox(high) -anchor center ttk::label $ds9(info).valueTitle -text [msgcat::mc {Value}] ttk::label $ds9(info).value -relief groove \ -textvariable infobox(value) -anchor center ttk::label $ds9(info).valueRTitle -text [msgcat::mc {r}] ttk::label $ds9(info).valueR -relief groove \ -textvariable infobox(value,red) -anchor center ttk::label $ds9(info).valueGTitle -text [msgcat::mc {g}] ttk::label $ds9(info).valueG -relief groove \ -textvariable infobox(value,green) -anchor center ttk::label $ds9(info).valueBTitle -text [msgcat::mc {b}] ttk::label $ds9(info).valueB -relief groove \ -textvariable infobox(value,blue) -anchor center foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set infobox(wcs$ll,sys) "[msgcat::mc {WCS}] $ll" ttk::label $ds9(info).wcsLabel$ll -textvariable infobox(wcs$ll,sys) set infobox(wcs$ll,x,nm) [ttk::label $ds9(info).wcsXLabel$ll -text {}] ttk::label $ds9(info).wcsXValue$ll -relief groove \ -textvariable infobox(wcs$ll,x) -anchor center set infobox(wcs$ll,y,nm) [ttk::label $ds9(info).wcsYLabel$ll -text {}] ttk::label $ds9(info).wcsYValue$ll -relief groove \ -textvariable infobox(wcs$ll,y) -anchor center set infobox(wcs$ll,z,nm) [ttk::label $ds9(info).wcsZLabel$ll -text {}] ttk::label $ds9(info).wcsZValue$ll -relief groove \ -textvariable infobox(wcs$ll,z) -anchor center } ttk::label $ds9(info).detectorTitle -text [msgcat::mc {Detector}] ttk::label $ds9(info).detectorXLabel -text {X} ttk::label $ds9(info).detectorXValue -relief groove \ -textvariable infobox(detector,x) -anchor center ttk::label $ds9(info).detectorYLabel -text {Y} ttk::label $ds9(info).detectorYValue -relief groove \ -textvariable infobox(detector,y) -anchor center ttk::label $ds9(info).detectorZLabel -text {Z} ttk::label $ds9(info).detectorZValue -relief groove \ -textvariable infobox(detector,) -anchor center ttk::label $ds9(info).amplifierTitle -text [msgcat::mc {Amplifier}] ttk::label $ds9(info).amplifierXLabel -text {X} ttk::label $ds9(info).amplifierXValue -relief groove \ -textvariable infobox(amplifier,x) -anchor center ttk::label $ds9(info).amplifierYLabel -text {Y} ttk::label $ds9(info).amplifierYValue -relief groove \ -textvariable infobox(amplifier,y) -anchor center ttk::label $ds9(info).amplifierZLabel -text {Z} ttk::label $ds9(info).amplifierZValue -relief groove \ -textvariable infobox(amplifier,z) -anchor center ttk::label $ds9(info).physicalTitle -text [msgcat::mc {Physical}] ttk::label $ds9(info).physicalXLabel -text {X} ttk::label $ds9(info).physicalXValue -relief groove \ -textvariable infobox(physical,x) -anchor center ttk::label $ds9(info).physicalYLabel -text {Y} ttk::label $ds9(info).physicalYValue -relief groove \ -textvariable infobox(physical,y) -anchor center ttk::label $ds9(info).physicalZLabel -text {Z} ttk::label $ds9(info).physicalZValue -relief groove \ -textvariable infobox(physical,z) -anchor center ttk::label $ds9(info).imageTitle -text [msgcat::mc {Image}] ttk::label $ds9(info).imageXLabel -text {X} ttk::label $ds9(info).imageXValue -relief groove \ -textvariable infobox(image,x) -anchor center ttk::label $ds9(info).imageYLabel -text {Y} ttk::label $ds9(info).imageYValue -relief groove \ -textvariable infobox(image,y) -anchor center ttk::label $ds9(info).imageZLabel -text {Z} ttk::label $ds9(info).imageZValue -relief groove \ -textvariable infobox(image,z) -anchor center ttk::label $ds9(info).frame -textvariable infobox(frame) \ -width [expr [string length [msgcat::mc {Frame}]]+4] ttk::label $ds9(info).zoomtitle -text [msgcat::mc {x}] ttk::label $ds9(info).zoomValue -relief groove \ -textvariable infobox(zoom) -anchor center ttk::label $ds9(info).angleTitle -text {°} ttk::label $ds9(info).angleValue -relief groove \ -textvariable infobox(angle) -anchor center } proc UpdateFrameInfoBox {which} { global ds9 global view global debug if {$debug(tcl,events)} { puts stderr "UpdateFrameInfoBox" } switch -- $which { base { grid forget $ds9(info).valueRTitle $ds9(info).valueR \ $ds9(info).valueGTitle $ds9(info).valueG \ $ds9(info).valueBTitle $ds9(info).valueB switch -- $view(layout) { vertical { grid $ds9(info).value \ -row $ds9(info,row,value) \ -column 1 -padx 2 -sticky w } horizontal { grid $ds9(info).value \ -row $ds9(info,row,value) \ -column 2 -padx 2 -sticky w } } foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { grid forget $ds9(info).wcsZLabel$ll grid forget $ds9(info).wcsZValue$ll } grid forget $ds9(info).detectorZLabel $ds9(info).detectorZValue grid forget $ds9(info).amplifierZLabel $ds9(info).amplifierZValue grid forget $ds9(info).physicalZLabel $ds9(info).physicalZValue grid forget $ds9(info).imageZLabel $ds9(info).imageZValue } rgb { grid forget $ds9(info).value switch $view(layout) { vertical { grid $ds9(info).valueRTitle \ -row $ds9(info,row,value,red) \ -column 0 -sticky w grid $ds9(info).valueR -row $ds9(info,row,value,red) \ -column 1 -padx 2 -sticky w grid $ds9(info).valueGTitle \ -row $ds9(info,row,value,green) \ -column 0 -sticky w grid $ds9(info).valueG \ -row $ds9(info,row,value,green) \ -column 1 -padx 2 -sticky w grid $ds9(info).valueBTitle \ -row $ds9(info,row,value,blue) \ -column 0 -sticky w grid $ds9(info).valueB \ -row $ds9(info,row,value,blue) \ -column 1 -padx 2 -sticky w } horizontal { grid $ds9(info).valueRTitle \ -row $ds9(info,row,value,red) \ -column 1 -sticky w grid $ds9(info).valueR \ -row $ds9(info,row,value,red) \ -column 2 -padx 2 -sticky w grid $ds9(info).valueGTitle \ -row $ds9(info,row,value,green) \ -column 3 -sticky w grid $ds9(info).valueG \ -row $ds9(info,row,value,green) \ -column 4 -padx 2 -sticky w grid $ds9(info).valueBTitle \ -row $ds9(info,row,value,blue) \ -column 5 -sticky w grid $ds9(info).valueB \ -row $ds9(info,row,value,blue) \ -column 6 -padx 2 -sticky w } } foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { grid forget $ds9(info).wcsZLabel$ll grid forget $ds9(info).wcsZValue$ll } grid forget $ds9(info).detectorZLabel $ds9(info).detectorZValue grid forget $ds9(info).amplifierZLabel $ds9(info).amplifierZValue grid forget $ds9(info).physicalZLabel $ds9(info).physicalZValue grid forget $ds9(info).imageZLabel $ds9(info).imageZValue } 3d { grid forget $ds9(info).valueRTitle $ds9(info).valueR \ $ds9(info).valueGTitle $ds9(info).valueG \ $ds9(info).valueBTitle $ds9(info).valueB switch -- $view(layout) { vertical { grid $ds9(info).value -row $ds9(info,row,value) \ -column 1 -padx 2 -sticky w foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {$view(info,wcs$ll)} { grid $ds9(info).wcsZLabel$ll \ -row $ds9(info,row,wcs$ll) \ -column 0 -sticky w grid $ds9(info).wcsZValue$ll \ -row $ds9(info,row,wcs$ll) \ -column 1 -padx 2 incr row } else { grid forget $ds9(info).wcsZLabel$ll grid forget $ds9(info).wcsZValue$ll } } if {$view(info,detector)} { grid $ds9(info).detectorZLabel \ -row $ds9(info,row,detector) \ -column 0 -sticky w grid $ds9(info).detectorZValue \ -row $ds9(info,row,detector) \ -column 1 -padx 2 } else { grid forget $ds9(info).detectorZLabel \ $ds9(info).detectorZValue } if {$view(info,amplifier)} { grid $ds9(info).amplifierZLabel \ -row $ds9(info,row,amplifier) \ -column 0 -sticky w grid $ds9(info).amplifierZValue \ -row $ds9(info,row,amplifier) \ -column 1 -padx 2 } else { grid forget $ds9(info).amplifierZLabel \ $ds9(info).amplifierZValue } if {$view(info,physical)} { grid $ds9(info).physicalZLabel \ -row $ds9(info,row,physical) \ -column 0 -sticky w grid $ds9(info).physicalZValue \ -row $ds9(info,row,physical) \ -column 1 -padx 2 } else { grid forget $ds9(info).physicalZLabel \ $ds9(info).physicalZValue } if {$view(info,image)} { grid $ds9(info).imageZLabel \ -row $ds9(info,row,image) \ -column 0 -sticky w grid $ds9(info).imageZValue \ -row $ds9(info,row,image) \ -column 1 -padx 2 } else { grid forget $ds9(info).imageZLabel \ $ds9(info).imageZValue } } horizontal { grid $ds9(info).value -row $ds9(info,row,value) \ -column 2 -padx 2 -sticky w foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {$view(info,wcs$ll)} { grid $ds9(info).wcsZLabel$ll \ -row $ds9(info,row,wcs$ll) \ -column 5 -sticky w grid $ds9(info).wcsZValue$ll \ -row $ds9(info,row,wcs$ll) \ -column 6 -padx 2 incr row } else { grid forget $ds9(info).wcsZLabel$ll grid forget $ds9(info).wcsZValue$ll } } if {$view(info,detector)} { grid $ds9(info).detectorZLabel \ -row $ds9(info,row,detector) \ -column 5 -sticky w grid $ds9(info).detectorZValue \ -row $ds9(info,row,detector) \ -column 6 -padx 2 } else { grid forget $ds9(info).detectorZLabel \ $ds9(info).detectorZValue } if {$view(info,amplifier)} { grid $ds9(info).amplifierZLabel \ -row $ds9(info,row,amplifier) \ -column 5 -sticky w grid $ds9(info).amplifierZValue \ -row $ds9(info,row,amplifier) \ -column 6 -padx 2 } else { grid forget $ds9(info).amplifierZLabel \ $ds9(info).amplifierZValue } if {$view(info,physical)} { grid $ds9(info).physicalZLabel \ -row $ds9(info,row,physical) \ -column 5 -sticky w grid $ds9(info).physicalZValue \ -row $ds9(info,row,physical) \ -column 6 -padx 2 } else { grid forget $ds9(info).physicalZLabel \ $ds9(info).physicalZValue } if {$view(info,image)} { grid $ds9(info).imageZLabel \ -row $ds9(info,row,image) \ -column 5 -sticky w grid $ds9(info).imageZValue \ -row $ds9(info,row,image) \ -column 6 -padx 2 } else { grid forget $ds9(info).imageZLabel \ $ds9(info).imageZValue } } } } } } proc EnterInfoBox {which x y sys} { global infobox global ds9 global debug if {$debug(tcl,events)} { puts stderr "EnterInfoBox $which $x $y $sys" } UpdateFrameInfoBox [$which get type] UpdateWCSInfoBox $which UpdateInfoBox $which $x $y $sys set infobox(frame) "[msgcat::mc {Frame}] [string range $which 5 end]" set infobox(angle) [$which get rotate fixed] set z [$which get zoom fixed] set z1 [lindex $z 0] set z2 [lindex $z 1] if {$z1 != $z2} { set infobox(zoom) "$z1 $z2" } else { set infobox(zoom) $z1 } } proc EnterInfoBoxFrame {which} { global infobox global ds9 global debug if {$debug(tcl,events)} { puts stderr "EnterInfoBoxFrame $which" } UpdateFrameInfoBox [$which get type] UpdateWCSInfoBox $which ClearInfoBoxCoords set infobox(frame) "[msgcat::mc {Frame}] [string range $which 5 end]" set infobox(angle) [$which get rotate fixed] set z [$which get zoom fixed] set z1 [lindex $z 0] set z2 [lindex $z 1] if {$z1 != $z2} { set infobox(zoom) "$z1 $z2" } else { set infobox(zoom) $z1 } } proc LeaveInfoBox {} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "LeaveInfoBox" } ClearInfoBoxCoords } proc ClearInfoBox {} { global infobox global debug if {$debug(tcl,info)} { puts stderr "ClearInfoBox" } set infobox(filename) {} set infobox(object) {} set infobox(min) {} set infobox(max) {} set infobox(low) {} set infobox(high) {} ClearInfoBoxCoords set infobox(frame) [msgcat::mc {Frame}] set infobox(zoom) {} set infobox(angle) {} } proc ClearInfoBoxCoords {} { global infobox global debug if {$debug(tcl,info)} { puts stderr "ClearInfoBoxCoords" } set infobox(value) {} set infobox(value,red) {} set infobox(value,green) {} set infobox(value,blue) {} foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set infobox(wcs$ll,sys) "WCS $ll" $infobox(wcs$ll,x,nm) configure -text {} $infobox(wcs$ll,y,nm) configure -text {} $infobox(wcs$ll,z,nm) configure -text {} set infobox(wcs$ll,x) {} set infobox(wcs$ll,y) {} set infobox(wcs$ll,z) {} } set infobox(detector,x) {} set infobox(detector,y) {} set infobox(detector,z) {} set infobox(amplifier,x) {} set infobox(amplifier,y) {} set infobox(amplifier,z) {} set infobox(physical,x) {} set infobox(physical,y) {} set infobox(physical,z) {} set infobox(image,x) {} set infobox(image,y) {} set infobox(image,z) {} } proc RefreshInfoBox {which} { global ds9 global current global debug if {$debug(tcl,info)} { puts stderr "RefreshInfoBox" } if {$which != {}} { switch -- $current(mode) { crosshair { set coord [$which get crosshair canvas] set x [lindex $coord 0] set y [lindex $coord 1] EnterInfoBox $which $x $y canvas } none - pointer - catalog - colorbar - pan - zoom - rotate - crop - examine - imexam {EnterInfoBoxFrame $which} } } return } proc UpdateInfoBox {which x y sys} { global debug if {$debug(tcl,info)} { puts stderr "UpdateInfoBox" } global ds9 global pds9 global infobox global view global infobox $which get info $sys $x $y infobox foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {$view(info,wcs$ll)} { switch -- $infobox(wcs$ll,sys) { fk4 { $infobox(wcs$ll,x,nm) configure -text "\u03b1" \ -font "symbol $pds9(font,size)" $infobox(wcs$ll,y,nm) configure -text "\u03b4" \ -font "symbol $pds9(font,size)" } fk5 { $infobox(wcs$ll,x,nm) configure -text "\u03b1" \ -font "symbol $pds9(font,size)" $infobox(wcs$ll,y,nm) configure -text "\u03b4" \ -font "symbol $pds9(font,size)" } icrs { $infobox(wcs$ll,x,nm) configure -text "\u03b1" \ -font "symbol $pds9(font,size)" $infobox(wcs$ll,y,nm) configure -text "\u03b4" \ -font "symbol $pds9(font,size)" } galactic { $infobox(wcs$ll,x,nm) configure -text {l} \ -font "{$ds9(times)} $pds9(font,size) normal italic" $infobox(wcs$ll,y,nm) configure -text {b} \ -font "{$ds9(times)} $pds9(font,size) normal italic" } ecliptic { $infobox(wcs$ll,x,nm) configure -text "\u03bb" \ -font "symbol $pds9(font,size)" $infobox(wcs$ll,y,nm) configure -text "\u03b2" \ -font "symbol $pds9(font,size)" } {} { set infobox(wcs$ll,sys) "WCS $ll" $infobox(wcs$ll,x,nm) configure -text {} $infobox(wcs$ll,y,nm) configure -text {} } default { $infobox(wcs$ll,x,nm) configure -text {} $infobox(wcs$ll,y,nm) configure -text {} } } } } } proc LayoutInfoPanel {} { global ds9 global view # reset grid columnconfigure $ds9(info) 7 -weight 0 if {$ds9(row) > -1} { grid rowconfigure $ds9(info) $ds9(row) -weight 0 set ds9(row) -1 } # layout switch $view(layout) { vertical {LayoutInfoPanelVert} horizontal {LayoutInfoPanelHorz} } } proc LayoutInfoPanelHorz {} { global ds9 global view set ww 11 set xx 40 set row 0 grid columnconfigure $ds9(info) 7 -weight 1 # filename if {$view(info,filename)} { $ds9(info).fileValue configure -width $xx grid $ds9(info).fileTitle -row $row -column 0 -sticky w grid $ds9(info).fileValue -row $row -column 2 -padx 2 \ -sticky ew -columnspan 6 incr row } else { grid forget $ds9(info).fileTitle grid forget $ds9(info).fileValue } # object if {$view(info,object)} { $ds9(info).objValue configure -width $xx grid $ds9(info).objTitle -row $row -column 0 -sticky w grid $ds9(info).objValue -row $row -column 2 -padx 2 \ -sticky ew -columnspan 6 incr row } else { grid forget $ds9(info).objTitle grid forget $ds9(info).objValue } # minmax if {$view(info,minmax)} { $ds9(info).minValue configure -width $ww $ds9(info).maxValue configure -width $ww grid $ds9(info).minmaxTitle -row $row -column 0 -sticky w grid $ds9(info).minValue -row $row -column 2 -padx 2 -sticky w grid $ds9(info).maxValue -row $row -column 4 -padx 2 -sticky w incr row } else { grid forget $ds9(info).minmaxTitle grid forget $ds9(info).minValue grid forget $ds9(info).maxValue } # lowhigh if {$view(info,lowhigh)} { $ds9(info).lowValue configure -width $ww $ds9(info).highValue configure -width $ww grid $ds9(info).lowhighTitle -row $row -column 0 -sticky w grid $ds9(info).lowValue -row $row -column 2 -padx 2 -sticky w grid $ds9(info).highValue -row $row -column 4 -padx 2 -sticky w incr row } else { grid forget $ds9(info).lowhighTitle grid forget $ds9(info).lowValue grid forget $ds9(info).highValue } # value $ds9(info).value configure -width $ww $ds9(info).valueR configure -width $ww $ds9(info).valueG configure -width $ww $ds9(info).valueB configure -width $ww grid $ds9(info).valueTitle -row $row -column 0 -sticky w set ds9(info,row,value) $row set ds9(info,row,value,red) $row set ds9(info,row,value,green) $row set ds9(info,row,value,blue) $row incr row UpdateFrameInfoBox base # wcs foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { $ds9(info).wcsLabel$ll configure -width $ww $ds9(info).wcsXValue$ll configure -width $ww $ds9(info).wcsYValue$ll configure -width $ww $ds9(info).wcsZValue$ll configure -width $ww if {$view(info,wcs$ll)} { grid $ds9(info).wcsLabel$ll -row $row -column 0 -sticky w grid $ds9(info).wcsXLabel$ll -row $row -column 1 -sticky w grid $ds9(info).wcsXValue$ll -row $row -column 2 -padx 2 grid $ds9(info).wcsYLabel$ll -row $row -column 3 -sticky w grid $ds9(info).wcsYValue$ll -row $row -column 4 -padx 2 set ds9(info,row,wcs$ll) $row incr row } else { grid forget $ds9(info).wcsLabel$ll grid forget $ds9(info).wcsXLabel$ll grid forget $ds9(info).wcsXValue$ll grid forget $ds9(info).wcsYLabel$ll grid forget $ds9(info).wcsYValue$ll } } # detector if {$view(info,detector)} { $ds9(info).detectorXValue configure -width $ww $ds9(info).detectorYValue configure -width $ww $ds9(info).detectorZValue configure -width $ww grid $ds9(info).detectorTitle -row $row -column 0 -sticky w grid $ds9(info).detectorXLabel -row $row -column 1 -sticky w grid $ds9(info).detectorXValue -row $row -column 2 -padx 2 grid $ds9(info).detectorYLabel -row $row -column 3 -sticky w grid $ds9(info).detectorYValue -row $row -column 4 -padx 2 set ds9(info,row,detector) $row incr row } else { grid forget $ds9(info).detectorTitle grid forget $ds9(info).detectorXLabel grid forget $ds9(info).detectorXValue grid forget $ds9(info).detectorYLabel grid forget $ds9(info).detectorYValue } # amplifier if {$view(info,amplifier)} { $ds9(info).amplifierXValue configure -width $ww $ds9(info).amplifierYValue configure -width $ww $ds9(info).amplifierZValue configure -width $ww grid $ds9(info).amplifierTitle -row $row -column 0 -sticky w grid $ds9(info).amplifierXLabel -row $row -column 1 -sticky w grid $ds9(info).amplifierXValue -row $row -column 2 -padx 2 grid $ds9(info).amplifierYLabel -row $row -column 3 -sticky w grid $ds9(info).amplifierYValue -row $row -column 4 -padx 2 set ds9(info,row,amplifier) $row incr row } else { grid forget $ds9(info).amplifierTitle grid forget $ds9(info).amplifierXLabel grid forget $ds9(info).amplifierXValue grid forget $ds9(info).amplifierYLabel grid forget $ds9(info).amplifierYValue } # physical if {$view(info,physical)} { $ds9(info).physicalXValue configure -width $ww $ds9(info).physicalYValue configure -width $ww $ds9(info).physicalZValue configure -width $ww grid $ds9(info).physicalTitle -row $row -column 0 -sticky w grid $ds9(info).physicalXLabel -row $row -column 1 -sticky w grid $ds9(info).physicalXValue -row $row -column 2 -padx 2 grid $ds9(info).physicalYLabel -row $row -column 3 -sticky w grid $ds9(info).physicalYValue -row $row -column 4 -padx 2 set ds9(info,row,physical) $row incr row } else { grid forget $ds9(info).physicalTitle grid forget $ds9(info).physicalXLabel grid forget $ds9(info).physicalXValue grid forget $ds9(info).physicalYLabel grid forget $ds9(info).physicalYValue } # image if {$view(info,image)} { $ds9(info).imageXValue configure -width $ww $ds9(info).imageYValue configure -width $ww $ds9(info).imageZValue configure -width $ww grid $ds9(info).imageTitle -row $row -column 0 -sticky w grid $ds9(info).imageXLabel -row $row -column 1 -sticky w grid $ds9(info).imageXValue -row $row -column 2 -padx 2 grid $ds9(info).imageYLabel -row $row -column 3 -sticky w grid $ds9(info).imageYValue -row $row -column 4 -padx 2 set ds9(info,row,image) $row incr row } else { grid forget $ds9(info).imageTitle grid forget $ds9(info).imageXLabel grid forget $ds9(info).imageXValue grid forget $ds9(info).imageYLabel grid forget $ds9(info).imageYValue } # frame, zoom, angle if {$view(info,frame)} { $ds9(info).zoomValue configure -width $ww $ds9(info).angleValue configure -width $ww grid $ds9(info).frame -row $row -column 0 -sticky w grid $ds9(info).zoomtitle -row $row -column 1 -sticky w grid $ds9(info).zoomValue -row $row -column 2 -padx 2 -sticky w grid $ds9(info).angleValue -row $row -column 4 -padx 2 -sticky w grid $ds9(info).angleTitle -row $row -column 5 -sticky w incr row } else { grid forget $ds9(info).frame grid forget $ds9(info).zoomtitle grid forget $ds9(info).zoomValue grid forget $ds9(info).angleTitle grid forget $ds9(info).angleValue } # dummy grid forget $ds9(info).dummy } proc LayoutInfoPanelVert {} { global ds9 global view set ww 13 set row 0 # filename if {$view(info,filename)} { $ds9(info).fileValue configure -width $ww grid $ds9(info).fileTitle -row $row -column 1 -sticky w incr row grid $ds9(info).fileValue -row $row -column 1 -padx 2 -sticky w incr row } else { grid forget $ds9(info).fileTitle grid forget $ds9(info).fileValue } # object if {$view(info,object)} { $ds9(info).objValue configure -width $ww grid $ds9(info).objTitle -row $row -column 1 -sticky w incr row grid $ds9(info).objValue -row $row -column 1 -padx 2 -sticky w incr row } else { grid forget $ds9(info).objTitle grid forget $ds9(info).objValue } # minmax if {$view(info,minmax)} { $ds9(info).minValue configure -width $ww $ds9(info).maxValue configure -width $ww grid $ds9(info).minmaxTitle -row $row -column 1 -sticky w incr row grid $ds9(info).minValue -row $row -column 1 -padx 2 -sticky w incr row grid $ds9(info).maxValue -row $row -column 1 -padx 2 -sticky w incr row } else { grid forget $ds9(info).minmaxTitle grid forget $ds9(info).minValue grid forget $ds9(info).maxValue } # lowhigh if {$view(info,lowhigh)} { $ds9(info).lowValue configure -width $ww $ds9(info).highValue configure -width $ww grid $ds9(info).lowhighTitle -row $row -column 1 -sticky w incr row grid $ds9(info).lowValue -row $row -column 1 -padx 2 -sticky w incr row grid $ds9(info).highValue -row $row -column 1 -padx 2 -sticky w incr row } else { grid forget $ds9(info).lowhighTitle grid forget $ds9(info).lowValue grid forget $ds9(info).highValue } # value $ds9(info).value configure -width $ww $ds9(info).valueR configure -width $ww $ds9(info).valueG configure -width $ww $ds9(info).valueB configure -width $ww grid $ds9(info).valueTitle -row $row -column 1 -sticky w incr row set ds9(info,row,value) $row set ds9(info,row,value,red) $row incr row set ds9(info,row,value,green) $row incr row set ds9(info,row,value,blue) $row incr row UpdateFrameInfoBox base # wcs foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { $ds9(info).wcsLabel$ll configure -width $ww $ds9(info).wcsXValue$ll configure -width $ww $ds9(info).wcsYValue$ll configure -width $ww $ds9(info).wcsZValue$ll configure -width $ww if {$view(info,wcs$ll)} { grid $ds9(info).wcsLabel$ll -row $row -column 1 -sticky ew incr row grid $ds9(info).wcsXLabel$ll -row $row -column 0 -sticky e grid $ds9(info).wcsXValue$ll -row $row -column 1 -padx 2 incr row grid $ds9(info).wcsYLabel$ll -row $row -column 0 -sticky e grid $ds9(info).wcsYValue$ll -row $row -column 1 -padx 2 incr row set ds9(info,row,wcs$ll) $row incr row } else { grid forget $ds9(info).wcsLabel$ll grid forget $ds9(info).wcsXLabel$ll grid forget $ds9(info).wcsXValue$ll grid forget $ds9(info).wcsYLabel$ll grid forget $ds9(info).wcsYValue$ll } } # detector if {$view(info,detector)} { $ds9(info).detectorXValue configure -width $ww $ds9(info).detectorYValue configure -width $ww $ds9(info).detectorZValue configure -width $ww grid $ds9(info).detectorTitle -row $row -column 1 -sticky ew incr row grid $ds9(info).detectorXLabel -row $row -column 0 -sticky e grid $ds9(info).detectorXValue -row $row -column 1 -padx 2 incr row grid $ds9(info).detectorYLabel -row $row -column 0 -sticky e grid $ds9(info).detectorYValue -row $row -column 1 -padx 2 incr row set ds9(info,row,detector) $row incr row } else { grid forget $ds9(info).detectorTitle grid forget $ds9(info).detectorXLabel grid forget $ds9(info).detectorXValue grid forget $ds9(info).detectorYLabel grid forget $ds9(info).detectorYValue } # amplifier if {$view(info,amplifier)} { $ds9(info).amplifierXValue configure -width $ww $ds9(info).amplifierYValue configure -width $ww $ds9(info).amplifierZValue configure -width $ww grid $ds9(info).amplifierTitle -row $row -column 1 -sticky ew incr row grid $ds9(info).amplifierXLabel -row $row -column 0 -sticky e grid $ds9(info).amplifierXValue -row $row -column 1 -padx 2 incr row grid $ds9(info).amplifierYLabel -row $row -column 0 -sticky e grid $ds9(info).amplifierYValue -row $row -column 1 -padx 2 incr row set ds9(info,row,amplifier) $row incr row } else { grid forget $ds9(info).amplifierTitle grid forget $ds9(info).amplifierXLabel grid forget $ds9(info).amplifierXValue grid forget $ds9(info).amplifierYLabel grid forget $ds9(info).amplifierYValue } # physical if {$view(info,physical)} { $ds9(info).physicalXValue configure -width $ww $ds9(info).physicalYValue configure -width $ww $ds9(info).physicalZValue configure -width $ww grid $ds9(info).physicalTitle -row $row -column 1 -sticky ew incr row grid $ds9(info).physicalXLabel -row $row -column 0 -sticky e grid $ds9(info).physicalXValue -row $row -column 1 -padx 2 incr row grid $ds9(info).physicalYLabel -row $row -column 0 -sticky e grid $ds9(info).physicalYValue -row $row -column 1 -padx 2 incr row set ds9(info,row,physical) $row incr row } else { grid forget $ds9(info).physicalTitle grid forget $ds9(info).physicalXLabel grid forget $ds9(info).physicalXValue grid forget $ds9(info).physicalYLabel grid forget $ds9(info).physicalYValue } # image if {$view(info,image)} { $ds9(info).imageXValue configure -width $ww $ds9(info).imageYValue configure -width $ww $ds9(info).imageZValue configure -width $ww grid $ds9(info).imageTitle -row $row -column 1 -sticky ew incr row grid $ds9(info).imageXLabel -row $row -column 0 -sticky e grid $ds9(info).imageXValue -row $row -column 1 -padx 2 incr row grid $ds9(info).imageYLabel -row $row -column 0 -sticky e grid $ds9(info).imageYValue -row $row -column 1 -padx 2 incr row set ds9(info,row,image) $row incr row } else { grid forget $ds9(info).imageTitle grid forget $ds9(info).imageXLabel grid forget $ds9(info).imageXValue grid forget $ds9(info).imageYLabel grid forget $ds9(info).imageYValue } # frame, zoom, angle if {$view(info,frame)} { $ds9(info).zoomValue configure -width $ww $ds9(info).angleValue configure -width $ww grid $ds9(info).frame -row $row -column 1 -sticky ew incr row grid $ds9(info).zoomtitle -row $row -column 0 -sticky e grid $ds9(info).zoomValue -row $row -column 1 -padx 2 incr row grid $ds9(info).angleTitle -row $row -column 0 -sticky e grid $ds9(info).angleValue -row $row -column 1 -padx 2 incr row } else { grid forget $ds9(info).frame grid forget $ds9(info).zoomtitle grid forget $ds9(info).zoomValue grid forget $ds9(info).angleTitle grid forget $ds9(info).angleValue } # dummy global ds9 set ds9(row) $row grid $ds9(info).dummy -row $row -column 1 grid rowconfigure $ds9(info) $row -weight 1 } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/crop.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000025036�11752764467�013372� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CropDef {} { global crop global icrop set icrop(top) .cr set icrop(mb) .crmb set crop(lock) none set crop(system) wcs set crop(sky) fk5 set crop(skyformat) degrees set crop(dcoord) wcs set crop(dformat) degrees set crop(rcoord) wcs } proc CropReset {} { global current if {$current(frame) != {}} { $current(frame) crop UpdateCrop $current(frame) } } proc ButtonCrop {which x y} { global rgb RGBEvalLock rgb(lock,crop) $which [list $which crop begin $x $y] } proc MotionCrop {which x y} { $which crop motion $x $y } proc ReleaseCrop {which x y} { global rgb RGBEvalLock rgb(lock,crop) $which [list $which crop end $x $y] UpdateCrop $which } proc ButtonCrop3d {which x y zz} { $which crop 3d begin $x $y $zz } proc MotionCrop3d {which x y zz} { $which crop 3d motion $x $y $zz } proc ReleaseCrop3d {which x y zz} { $which crop 3d end $x $y $zz UpdateCrop $which } proc UpdateCrop {which} { global current global debug if {$debug(tcl,update)} { puts stderr "UpdateCrop" } LockCrop $which UpdateGraphXAxis $which UpdateCropDialog UpdateCubeDialog UpdateScaleDialog UpdateMain GridUpdateZoom } proc CropDialog {} { global crop global icrop global dcrop global ds9 global current # see if we already have a window visible if [winfo exists $icrop(top)] { raise $icrop(top) return } # create the window set w $icrop(top) set mb $icrop(mb) Toplevel $w $mb 6 [msgcat::mc {Crop Parameters}] \ CropDestroyDialog # for CoordMenuButton set crop(frame) $current(frame) $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command CropApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Reset}] -command CropReset $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command CropDestroyDialog EditMenu $mb icrop # Param set f [ttk::frame $w.param] ttk::label $f.title -text [msgcat::mc {Center}] ttk::entry $f.x -textvariable dcrop(x) -width 14 ttk::entry $f.y -textvariable dcrop(y) -width 14 set dcrop(cb) $f.center CoordMenuButton $dcrop(cb) crop system 1 sky skyformat UpdateCropDialog ttk::label $f.stitle -text [msgcat::mc {Size}] ttk::entry $f.w -textvariable dcrop(w) -width 14 ttk::entry $f.h -textvariable dcrop(h) -width 14 set dcrop(db) $f.size DistMenuButton $dcrop(db) crop dcoord 1 dformat UpdateCropDialog ttk::label $f.rtitle -text [msgcat::mc {3D}] ttk::entry $f.from -textvariable dcrop(zmin) -width 14 ttk::entry $f.to -textvariable dcrop(zmax) -width 14 set dcrop(rb) $f.range CoordMenuButton $dcrop(rb) crop rcoord 2 {} {} UpdateCropDialog grid $f.title $f.x $f.y $dcrop(cb) -padx 2 -pady 2 grid $f.stitle $f.w $f.h $dcrop(db) -padx 2 -pady 2 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command CropApplyDialog ttk::button $f.reset -text [msgcat::mc {Reset}] -command CropReset ttk::button $f.close -text [msgcat::mc {Close}] \ -command CropDestroyDialog pack $f.apply $f.reset $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true $w.param.x select range 0 end UpdateCropDialog } proc CropApplyDialog {} { global crop global icrop global dcrop global current if {$current(frame) != {}} { $current(frame) crop center $dcrop(x) $dcrop(y) \ $crop(system) $crop(sky) \ $dcrop(w) $dcrop(h) $crop(dcoord) $crop(dformat) if {[$current(frame) has fits cube]} { $current(frame) crop 3d $dcrop(zmin) $dcrop(zmax) $crop(rcoord) } UpdateCrop $current(frame) } } proc CropDestroyDialog {} { global icrop global dcrop if {[winfo exists $icrop(top)]} { destroy $icrop(top) destroy $icrop(mb) } unset dcrop } proc UpdateCropMenu {} { # can be changed by wcs SetCoordSystem crop system sky skyformat } proc UpdateCropDialog {} { global crop global icrop global dcrop global current global debug if {$debug(tcl,update)} { puts stderr "UpdateCropDialog" } if {![winfo exists $icrop(top)]} { return } set w $icrop(top) if {$current(frame) != {}} { set crop(frame) $current(frame) if {[$current(frame) has fits]} { # now make sure we have the coord systems AdjustCoordSystem crop system CoordMenuEnable $dcrop(cb).menu crop system 1 sky skyformat CoordMenuButtonCmd crop system sky {} AdjustCoordSystem crop dcoord DistMenuEnable $dcrop(db).menu crop dcoord 1 dformat DistMenuButtonCmd crop dcoord dformat {} AdjustCoordSystem3d crop rcoord CoordMenuEnable $dcrop(rb).menu crop rcoord 2 {} {} CoordMenuButtonCmd crop rcoord {} {} set rr [$current(frame) get crop center \ $crop(system) $crop(sky) $crop(skyformat) \ $crop(dcoord) $crop(dformat)] set dcrop(x) [lindex $rr 0] set dcrop(y) [lindex $rr 1] set dcrop(w) [lindex $rr 2] set dcrop(h) [lindex $rr 3] if {[$current(frame) has fits cube]} { set ss [$current(frame) get crop 3d $crop(rcoord)] set dcrop(zmin) [lindex $ss 0] set dcrop(zmax) [lindex $ss 1] grid $w.param.rtitle $w.param.from $w.param.to $dcrop(rb) \ -padx 2 -pady 2 } else { set dcrop(zmin) {} set dcrop(zmax) {} grid forget $w.param.rtitle $w.param.from $w.param.to $dcrop(rb) } return } } grid forget $w.param.rtitle $w.param.from $w.param.to $dcrop(rb) CoordMenuReset $dcrop(cb).menu crop system 1 sky skyformat DistMenuReset $dcrop(db).menu crop dcoord 1 dformat CoordMenuReset $dcrop(rb).menu crop rcoord 2 {} {} set dcrop(x) {} set dcrop(y) {} set dcrop(w) {} set dcrop(h) {} set dcrop(zmin) {} set dcrop(zmax) {} } proc MatchCropCurrent {sys} { global current if {$current(frame) != {}} { MatchCrop $current(frame) $sys } } proc MatchCrop {which sys} { global ds9 global rgb # make sure matrices have been updated RealizeDS9 set tt [$which has crop] set datasec [$which get datasec] if {$tt} { switch -- $sys { image - physical - amplifier - detector { set rr [$which get crop center $sys fk5 degrees $sys degrees] set r(x) [lindex $rr 0] set r(y) [lindex $rr 1] set r(w) [lindex $rr 2] set r(h) [lindex $rr 3] set qq [$which get crop 3d image] foreach ff $ds9(frames) { if {$ff != $which} { RGBEvalLock rgb(lock,crop) $ff [list $ff datasec $datasec] RGBEvalLock rgb(lock,crop) $ff [list $ff crop center $r(x) $r(y) $sys fk5 $r(w) $r(h) $sys degrees] RGBEvalLock rgb(lock,crop) $ff [list $ff crop 3d $qq image] } } } wcs { set ss [lindex [$which get wcs] 0] if {[$which has wcs $ss]} { set rr [$which get crop center $ss fk5 degrees $ss degrees] set r(x) [lindex $rr 0] set r(y) [lindex $rr 1] set r(w) [lindex $rr 2] set r(h) [lindex $rr 3] set qq [$which get crop 3d $ss] foreach ff $ds9(frames) { if {$ff != $which} { if {[$ff has wcs $ss]} { RGBEvalLock rgb(lock,crop) $ff [list $ff crop center $r(x) $r(y) $ss fk5 $r(w) $r(h) $ss degrees] RGBEvalLock rgb(lock,crop) $ff [list $ff crop 3d $qq $ss] } } } } } } } else { foreach ff $ds9(frames) { if {$ff != $which} { RGBEvalLock rgb(lock,crop) $ff [list $ff crop] RGBEvalLock rgb(lock,crop) $ff [list $ff crop 3d] } } } } proc LockCropCurrent {} { global current if {$current(frame) != {}} { LockCrop $current(frame) } } proc LockCrop {which} { global crop switch -- $crop(lock) { none {} default {MatchCrop $which $crop(lock)} } } proc CropBackup {ch which} { switch [$which get type] { base - 3d {CropBackupBase $ch $which} rgb {CropBackupRGB $ch $which} } } proc CropBackupBase {ch which} { if {[$which has crop]} { set rr [$which get crop physical fk5 degrees] puts $ch "$which crop $rr physical fk5" if {[$which has fits cube]} { set ss [$which get crop 3d image] puts $ch "$which crop 3d $ss image" } } } proc CropBackupRGB {ch which} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" CropBackupBase $ch $which } $which rgb channel $sav puts $ch "$which rgb channel $sav" } # Process Cmds proc ProcessCropCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 global crop global current switch -- [string tolower [lindex $var $i]] { match { incr i MatchCropCurrent [lindex $var $i] } lock { incr i set crop(lock) [lindex $var $i] LockCropCurrent } open {CropDialog} close {CropDestroyDialog} reset {CropReset} 3d { incr i 1 set zmin [lindex $var [expr $i+0]] set zmax [lindex $var [expr $i+1]] set sys [lindex $var [expr $i+2]] incr i 1 incr i [FixSpecSystem sys physical] $current(frame) crop 3d $zmin $zmax $sys } default { set x [lindex $var [expr $i+0]] set y [lindex $var [expr $i+1]] set w [lindex $var [expr $i+2]] set h [lindex $var [expr $i+3]] set sys [lindex $var [expr $i+4]] set sky [lindex $var [expr $i+5]] set dformat [lindex $var [expr $i+6]] incr i 3 incr i [FixSpec sys sky dformat physical fk5 degrees] $current(frame) crop center $x $y $sys $sky $w $h $sys $dformat } } } proc ProcessSendCropCmd {proc id param} { global crop global current switch -- [string tolower [lindex $param 0]] { lock {$proc $id "$crop(lock)\n"} 3d { set sys [lindex $param 1] FixSpecSystem sys physical if {$current(frame) != {}} { $proc $id "[$current(frame) get crop 3d $sys]\n" } } default { set sys [lindex $param 0] set sky [lindex $param 1] set format [lindex $param 2] set dformat [lindex $param 3] FixSpec sys sky format physical fk5 degrees if {$current(frame) != {}} { $proc $id "[$current(frame) get crop center $sys $sky $format $sys $dformat]\n" } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/tkfbox.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000152021�11613627653�013706� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# tkfbox.tcl -- # # Implements the "TK" standard file selection dialog box. This # dialog box is used on the Unix platforms whenever the tk_strictMotif # flag is not set. # # The "TK" standard file selection dialog box is similar to the # file selection dialog box on Win95(TM). The user can navigate # the directories by clicking on the folder icons or by # selecting the "Directory" option menu. The user can select # files by clicking on the file icons or by entering a filename # in the "Filename:" entry. # # RCS: @(#) $Id: tkfbox.tcl,v 1.4 2011/07/26 21:20:43 joye Exp $ # # Copyright (c) 1994-1998 Sun Microsystems, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # package require Ttk #---------------------------------------------------------------------- # # I C O N L I S T # # This is a pseudo-widget that implements the icon list inside the # ::tk::dialog::file:: dialog box. # #---------------------------------------------------------------------- # ::tk::IconList -- # # Creates an IconList widget. # proc ::tk::IconList {w args} { IconList_Config $w $args IconList_Create $w } proc ::tk::IconList_Index {w i} { upvar #0 ::tk::$w data ::tk::$w:itemList itemList if {![info exists data(list)]} { set data(list) {} } switch -regexp -- $i { "^-?[0-9]+$" { if {$i < 0} { set i 0 } if {$i >= [llength $data(list)]} { set i [expr {[llength $data(list)] - 1}] } return $i } "^active$" { return $data(index,active) } "^anchor$" { return $data(index,anchor) } "^end$" { return [llength $data(list)] } "@-?[0-9]+,-?[0-9]+" { foreach {x y} [scan $i "@%d,%d"] { break } set item [$data(canvas) find closest \ [$data(canvas) canvasx $x] [$data(canvas) canvasy $y]] return [lindex [$data(canvas) itemcget $item -tags] 1] } } } proc ::tk::IconList_Selection {w op args} { upvar ::tk::$w data switch -exact -- $op { "anchor" { if {[llength $args] == 1} { set data(index,anchor) [tk::IconList_Index $w [lindex $args 0]] } else { return $data(index,anchor) } } "clear" { if {[llength $args] == 2} { foreach {first last} $args { break } } elseif {[llength $args] == 1} { set first [set last [lindex $args 0]] } else { error "wrong # args: should be [lindex [info level 0] 0] path\ clear first ?last?" } set first [IconList_Index $w $first] set last [IconList_Index $w $last] if {$first > $last} { set tmp $first set first $last set last $tmp } set ind 0 foreach item $data(selection) { if { $item >= $first } { set first $ind break } incr ind } set ind [expr {[llength $data(selection)] - 1}] for {} {$ind >= 0} {incr ind -1} { set item [lindex $data(selection) $ind] if { $item <= $last } { set last $ind break } } if { $first > $last } { return } set data(selection) [lreplace $data(selection) $first $last] event generate $w <<ListboxSelect>> IconList_DrawSelection $w } "includes" { set index [lsearch -exact $data(selection) [lindex $args 0]] return [expr {$index != -1}] } "set" { if { [llength $args] == 2 } { foreach {first last} $args { break } } elseif { [llength $args] == 1 } { set last [set first [lindex $args 0]] } else { error "wrong # args: should be [lindex [info level 0] 0] path\ set first ?last?" } set first [IconList_Index $w $first] set last [IconList_Index $w $last] if { $first > $last } { set tmp $first set first $last set last $tmp } for {set i $first} {$i <= $last} {incr i} { lappend data(selection) $i } set data(selection) [lsort -integer -unique $data(selection)] event generate $w <<ListboxSelect>> IconList_DrawSelection $w } } } proc ::tk::IconList_CurSelection {w} { upvar ::tk::$w data return $data(selection) } proc ::tk::IconList_DrawSelection {w} { upvar ::tk::$w data upvar ::tk::$w:itemList itemList $data(canvas) delete selection $data(canvas) itemconfigure selectionText -fill black $data(canvas) dtag selectionText set cbg [ttk::style lookup TEntry -selectbackground focus] set cfg [ttk::style lookup TEntry -selectforeground focus] foreach item $data(selection) { set rTag [lindex [lindex $data(list) $item] 2] foreach {iTag tTag text serial} $itemList($rTag) { break } set bbox [$data(canvas) bbox $tTag] $data(canvas) create rect $bbox -fill $cbg -outline $cbg \ -tags selection $data(canvas) itemconfigure $tTag -fill $cfg -tags selectionText } $data(canvas) lower selection return } proc ::tk::IconList_Get {w item} { upvar ::tk::$w data upvar ::tk::$w:itemList itemList set rTag [lindex [lindex $data(list) $item] 2] foreach {iTag tTag text serial} $itemList($rTag) { break } return $text } # ::tk::IconList_Config -- # # Configure the widget variables of IconList, according to the command # line arguments. # proc ::tk::IconList_Config {w argList} { # 1: the configuration specs # set specs { {-command "" "" ""} {-multiple "" "" "0"} } # 2: parse the arguments # tclParseConfigSpec ::tk::$w $specs "" $argList } # ::tk::IconList_Create -- # # Creates an IconList widget by assembling a canvas widget and a # scrollbar widget. Sets all the bindings necessary for the IconList's # operations. # proc ::tk::IconList_Create {w} { upvar ::tk::$w data ttk::frame $w ttk::entry $w.cHull -takefocus 0 -cursor {} set data(sbar) [ttk::scrollbar $w.cHull.sbar -orient horizontal -takefocus 0] catch {$data(sbar) configure -highlightthickness 0} set data(canvas) [canvas $w.cHull.canvas -highlightthick 0 \ -width 400 -height 120 -takefocus 1 -background white] pack $data(sbar) -side bottom -fill x -padx 2 -in $w.cHull -pady {0 2} pack $data(canvas) -expand yes -fill both -padx 2 -pady {2 0} pack $w.cHull -expand yes -fill both -ipadx 2 -ipady 2 $data(sbar) configure -command [list $data(canvas) xview] $data(canvas) configure -xscrollcommand [list $data(sbar) set] # Initializes the max icon/text width and height and other variables # set data(maxIW) 1 set data(maxIH) 1 set data(maxTW) 1 set data(maxTH) 1 set data(numItems) 0 set data(noScroll) 1 set data(selection) {} set data(index,anchor) "" set fg [option get $data(canvas) foreground Foreground] if {$fg eq ""} { set data(fill) black } else { set data(fill) $fg } # Creates the event bindings. # bind $data(canvas) <Configure> [list tk::IconList_Arrange $w] bind $data(canvas) <1> [list tk::IconList_Btn1 $w %x %y] bind $data(canvas) <B1-Motion> [list tk::IconList_Motion1 $w %x %y] bind $data(canvas) <B1-Leave> [list tk::IconList_Leave1 $w %x %y] bind $data(canvas) <Control-1> [list tk::IconList_CtrlBtn1 $w %x %y] bind $data(canvas) <Shift-1> [list tk::IconList_ShiftBtn1 $w %x %y] bind $data(canvas) <B1-Enter> [list tk::CancelRepeat] bind $data(canvas) <ButtonRelease-1> [list tk::CancelRepeat] bind $data(canvas) <Double-ButtonRelease-1> \ [list tk::IconList_Double1 $w %x %y] bind $data(canvas) <Control-B1-Motion> {;} bind $data(canvas) <Shift-B1-Motion> \ [list tk::IconList_ShiftMotion1 $w %x %y] bind $data(canvas) <Up> [list tk::IconList_UpDown $w -1] bind $data(canvas) <Down> [list tk::IconList_UpDown $w 1] bind $data(canvas) <Left> [list tk::IconList_LeftRight $w -1] bind $data(canvas) <Right> [list tk::IconList_LeftRight $w 1] bind $data(canvas) <Return> [list tk::IconList_ReturnKey $w] bind $data(canvas) <KeyPress> [list tk::IconList_KeyPress $w %A] bind $data(canvas) <Control-KeyPress> ";" bind $data(canvas) <Alt-KeyPress> ";" bind $data(canvas) <FocusIn> [list tk::IconList_FocusIn $w] bind $data(canvas) <FocusOut> [list tk::IconList_FocusOut $w] return $w } # ::tk::IconList_AutoScan -- # # This procedure is invoked when the mouse leaves an entry window # with button 1 down. It scrolls the window up, down, left, or # right, depending on where the mouse left the window, and reschedules # itself as an "after" command so that the window continues to scroll until # the mouse moves back into the window or the mouse button is released. # # Arguments: # w - The IconList window. # proc ::tk::IconList_AutoScan {w} { upvar ::tk::$w data variable ::tk::Priv if {![winfo exists $w]} return set x $Priv(x) set y $Priv(y) if {$data(noScroll)} { return } if {$x >= [winfo width $data(canvas)]} { $data(canvas) xview scroll 1 units } elseif {$x < 0} { $data(canvas) xview scroll -1 units } elseif {$y >= [winfo height $data(canvas)]} { # do nothing } elseif {$y < 0} { # do nothing } else { return } IconList_Motion1 $w $x $y set Priv(afterId) [after 50 [list tk::IconList_AutoScan $w]] } # Deletes all the items inside the canvas subwidget and reset the IconList's # state. # proc ::tk::IconList_DeleteAll {w} { upvar ::tk::$w data upvar ::tk::$w:itemList itemList $data(canvas) delete all unset -nocomplain data(selected) data(rect) data(list) itemList set data(maxIW) 1 set data(maxIH) 1 set data(maxTW) 1 set data(maxTH) 1 set data(numItems) 0 set data(noScroll) 1 set data(selection) {} set data(index,anchor) "" $data(sbar) set 0.0 1.0 $data(canvas) xview moveto 0 } # Adds an icon into the IconList with the designated image and text # proc ::tk::IconList_Add {w image items} { upvar ::tk::$w data upvar ::tk::$w:itemList itemList upvar ::tk::$w:textList textList foreach text $items { set iTag [$data(canvas) create image 0 0 -image $image -anchor nw \ -tags [list icon $data(numItems) item$data(numItems)]] set tTag [$data(canvas) create text 0 0 -text $text -anchor nw \ -font $data(font) -fill $data(fill) \ -tags [list text $data(numItems) item$data(numItems)]] set rTag [$data(canvas) create rect 0 0 0 0 -fill "" -outline "" \ -tags [list rect $data(numItems) item$data(numItems)]] foreach {x1 y1 x2 y2} [$data(canvas) bbox $iTag] { break } set iW [expr {$x2 - $x1}] set iH [expr {$y2 - $y1}] if {$data(maxIW) < $iW} { set data(maxIW) $iW } if {$data(maxIH) < $iH} { set data(maxIH) $iH } foreach {x1 y1 x2 y2} [$data(canvas) bbox $tTag] { break } set tW [expr {$x2 - $x1}] set tH [expr {$y2 - $y1}] if {$data(maxTW) < $tW} { set data(maxTW) $tW } if {$data(maxTH) < $tH} { set data(maxTH) $tH } lappend data(list) [list $iTag $tTag $rTag $iW $iH $tW \ $tH $data(numItems)] set itemList($rTag) [list $iTag $tTag $text $data(numItems)] set textList($data(numItems)) [string tolower $text] incr data(numItems) } } # Places the icons in a column-major arrangement. # proc ::tk::IconList_Arrange {w} { upvar ::tk::$w data if {![info exists data(list)]} { if {[info exists data(canvas)] && [winfo exists $data(canvas)]} { set data(noScroll) 1 $data(sbar) configure -command "" } return } set W [winfo width $data(canvas)] set H [winfo height $data(canvas)] set pad [expr {[$data(canvas) cget -highlightthickness] + \ [$data(canvas) cget -bd]}] if {$pad < 2} { set pad 2 } incr W -[expr {$pad*2}] incr H -[expr {$pad*2}] set dx [expr {$data(maxIW) + $data(maxTW) + 8}] if {$data(maxTH) > $data(maxIH)} { set dy $data(maxTH) } else { set dy $data(maxIH) } incr dy 2 set shift [expr {$data(maxIW) + 4}] set x [expr {$pad * 2}] set y [expr {$pad * 1}] ; # Why * 1 ? set usedColumn 0 foreach sublist $data(list) { set usedColumn 1 foreach {iTag tTag rTag iW iH tW tH} $sublist { break } set i_dy [expr {($dy - $iH)/2}] set t_dy [expr {($dy - $tH)/2}] $data(canvas) coords $iTag $x [expr {$y + $i_dy}] $data(canvas) coords $tTag [expr {$x + $shift}] [expr {$y + $t_dy}] $data(canvas) coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}] incr y $dy if {($y + $dy) > $H} { set y [expr {$pad * 1}] ; # *1 ? incr x $dx set usedColumn 0 } } if {$usedColumn} { set sW [expr {$x + $dx}] } else { set sW $x } if {$sW < $W} { $data(canvas) configure -scrollregion [list $pad $pad $sW $H] $data(sbar) configure -command "" $data(canvas) xview moveto 0 set data(noScroll) 1 } else { $data(canvas) configure -scrollregion [list $pad $pad $sW $H] $data(sbar) configure -command [list $data(canvas) xview] set data(noScroll) 0 } set data(itemsPerColumn) [expr {($H-$pad)/$dy}] if {$data(itemsPerColumn) < 1} { set data(itemsPerColumn) 1 } IconList_DrawSelection $w } # Gets called when the user invokes the IconList (usually by double-clicking # or pressing the Return key). # proc ::tk::IconList_Invoke {w} { upvar ::tk::$w data if {$data(-command) ne "" && [llength $data(selection)]} { uplevel #0 $data(-command) } } # ::tk::IconList_See -- # # If the item is not (completely) visible, scroll the canvas so that # it becomes visible. proc ::tk::IconList_See {w rTag} { upvar ::tk::$w data upvar ::tk::$w:itemList itemList if {$data(noScroll)} { return } set sRegion [$data(canvas) cget -scrollregion] if {$sRegion eq ""} { return } if { $rTag < 0 || $rTag >= [llength $data(list)] } { return } set bbox [$data(canvas) bbox item$rTag] set pad [expr {[$data(canvas) cget -highlightthickness] + \ [$data(canvas) cget -bd]}] set x1 [lindex $bbox 0] set x2 [lindex $bbox 2] incr x1 -[expr {$pad * 2}] incr x2 -[expr {$pad * 1}] ; # *1 ? set cW [expr {[winfo width $data(canvas)] - $pad*2}] set scrollW [expr {[lindex $sRegion 2]-[lindex $sRegion 0]+1}] set dispX [expr {int([lindex [$data(canvas) xview] 0]*$scrollW)}] set oldDispX $dispX # check if out of the right edge # if {($x2 - $dispX) >= $cW} { set dispX [expr {$x2 - $cW}] } # check if out of the left edge # if {($x1 - $dispX) < 0} { set dispX $x1 } if {$oldDispX ne $dispX} { set fraction [expr {double($dispX)/double($scrollW)}] $data(canvas) xview moveto $fraction } } proc ::tk::IconList_Btn1 {w x y} { upvar ::tk::$w data focus $data(canvas) set i [IconList_Index $w @$x,$y] if {$i eq ""} { return } IconList_Selection $w clear 0 end IconList_Selection $w set $i IconList_Selection $w anchor $i } proc ::tk::IconList_CtrlBtn1 {w x y} { upvar ::tk::$w data if { $data(-multiple) } { focus $data(canvas) set i [IconList_Index $w @$x,$y] if {$i eq ""} { return } if { [IconList_Selection $w includes $i] } { IconList_Selection $w clear $i } else { IconList_Selection $w set $i IconList_Selection $w anchor $i } } } proc ::tk::IconList_ShiftBtn1 {w x y} { upvar ::tk::$w data if { $data(-multiple) } { focus $data(canvas) set i [IconList_Index $w @$x,$y] if {$i eq ""} { return } if {[IconList_Index $w anchor] eq ""} { IconList_Selection $w anchor $i } IconList_Selection $w clear 0 end IconList_Selection $w set anchor $i } } # Gets called on button-1 motions # proc ::tk::IconList_Motion1 {w x y} { variable ::tk::Priv set Priv(x) $x set Priv(y) $y set i [IconList_Index $w @$x,$y] if {$i eq ""} { return } IconList_Selection $w clear 0 end IconList_Selection $w set $i } proc ::tk::IconList_ShiftMotion1 {w x y} { upvar ::tk::$w data variable ::tk::Priv set Priv(x) $x set Priv(y) $y set i [IconList_Index $w @$x,$y] if {$i eq ""} { return } IconList_Selection $w clear 0 end IconList_Selection $w set anchor $i } proc ::tk::IconList_Double1 {w x y} { upvar ::tk::$w data if {[llength $data(selection)]} { IconList_Invoke $w } } proc ::tk::IconList_ReturnKey {w} { IconList_Invoke $w } proc ::tk::IconList_Leave1 {w x y} { variable ::tk::Priv set Priv(x) $x set Priv(y) $y IconList_AutoScan $w } proc ::tk::IconList_FocusIn {w} { upvar ::tk::$w data $w.cHull state focus if {![info exists data(list)]} { return } if {[llength $data(selection)]} { IconList_DrawSelection $w } } proc ::tk::IconList_FocusOut {w} { $w.cHull state !focus IconList_Selection $w clear 0 end } # ::tk::IconList_UpDown -- # # Moves the active element up or down by one element # # Arguments: # w - The IconList widget. # amount - +1 to move down one item, -1 to move back one item. # proc ::tk::IconList_UpDown {w amount} { upvar ::tk::$w data if {![info exists data(list)]} { return } set curr [tk::IconList_CurSelection $w] if { [llength $curr] == 0 } { set i 0 } else { set i [tk::IconList_Index $w anchor] if {$i eq ""} { return } incr i $amount } IconList_Selection $w clear 0 end IconList_Selection $w set $i IconList_Selection $w anchor $i IconList_See $w $i } # ::tk::IconList_LeftRight -- # # Moves the active element left or right by one column # # Arguments: # w - The IconList widget. # amount - +1 to move right one column, -1 to move left one column. # proc ::tk::IconList_LeftRight {w amount} { upvar ::tk::$w data if {![info exists data(list)]} { return } set curr [IconList_CurSelection $w] if { [llength $curr] == 0 } { set i 0 } else { set i [IconList_Index $w anchor] if {$i eq ""} { return } incr i [expr {$amount*$data(itemsPerColumn)}] } IconList_Selection $w clear 0 end IconList_Selection $w set $i IconList_Selection $w anchor $i IconList_See $w $i } #---------------------------------------------------------------------- # Accelerator key bindings #---------------------------------------------------------------------- # ::tk::IconList_KeyPress -- # # Gets called when user enters an arbitrary key in the listbox. # proc ::tk::IconList_KeyPress {w key} { variable ::tk::Priv append Priv(ILAccel,$w) $key IconList_Goto $w $Priv(ILAccel,$w) catch { after cancel $Priv(ILAccel,$w,afterId) } set Priv(ILAccel,$w,afterId) [after 500 [list tk::IconList_Reset $w]] } proc ::tk::IconList_Goto {w text} { upvar ::tk::$w data upvar ::tk::$w:textList textList if {![info exists data(list)]} { return } if {$text eq "" || $data(numItems) == 0} { return } if {[llength [IconList_CurSelection $w]]} { set start [IconList_Index $w anchor] } else { set start 0 } set theIndex -1 set less 0 set len [string length $text] set len0 [expr {$len-1}] set i $start # Search forward until we find a filename whose prefix is a # case-insensitive match with $text while {1} { if {[string equal -nocase -length $len0 $textList($i) $text]} { set theIndex $i break } incr i if {$i == $data(numItems)} { set i 0 } if {$i == $start} { break } } if {$theIndex > -1} { IconList_Selection $w clear 0 end IconList_Selection $w set $theIndex IconList_Selection $w anchor $theIndex IconList_See $w $theIndex } } proc ::tk::IconList_Reset {w} { variable ::tk::Priv unset -nocomplain Priv(ILAccel,$w) } #---------------------------------------------------------------------- # # F I L E D I A L O G # #---------------------------------------------------------------------- namespace eval ::tk::dialog {} namespace eval ::tk::dialog::file { namespace import -force ::tk::msgcat::* set ::tk::dialog::file::showHiddenBtn 0 set ::tk::dialog::file::showHiddenVar 1 } # ::tk::dialog::file:: -- # # Implements the TK file selection dialog. This dialog is used when # the tk_strictMotif flag is set to false. This procedure shouldn't # be called directly. Call tk_getOpenFile or tk_getSaveFile instead. # # Arguments: # type "open" or "save" # args Options parsed by the procedure. # proc ::tk::dialog::file:: {type args} { variable ::tk::Priv set dataName __tk_filedialog upvar ::tk::dialog::file::$dataName data Config $dataName $type $args if {$data(-parent) eq "."} { set w .$dataName } else { set w $data(-parent).$dataName } # (re)create the dialog box if necessary # if {![winfo exists $w]} { Create $w TkFDialog } elseif {[winfo class $w] ne "TkFDialog"} { destroy $w Create $w TkFDialog } else { set data(dirMenuBtn) $w.contents.f1.menu set data(dirMenu) $w.contents.f1.menu.menu set data(upBtn) $w.contents.f1.up set data(icons) $w.contents.icons set data(ent) $w.contents.f2.ent set data(typeMenuLab) $w.contents.f2.lab2 set data(typeMenuBtn) $w.contents.f2.menu set data(typeMenu) $data(typeMenuBtn).m set data(okBtn) $w.contents.f2.ok set data(cancelBtn) $w.contents.f2.cancel set data(hiddenBtn) $w.contents.f2.hidden SetSelectMode $w $data(-multiple) } if {$::tk::dialog::file::showHiddenBtn} { $data(hiddenBtn) configure -state normal grid $data(hiddenBtn) } else { $data(hiddenBtn) configure -state disabled grid remove $data(hiddenBtn) } # Make sure subseqent uses of this dialog are independent [Bug 845189] unset -nocomplain data(extUsed) # Dialog boxes should be transient with respect to their parent, # so that they will always stay on top of their parent window. However, # some window managers will create the window as withdrawn if the parent # window is withdrawn or iconified. Combined with the grab we put on the # window, this can hang the entire application. Therefore we only make # the dialog transient if the parent is viewable. if {[winfo viewable [winfo toplevel $data(-parent)]]} { wm transient $w $data(-parent) } # Add traces on the selectPath variable # trace add variable data(selectPath) write \ [list ::tk::dialog::file::SetPath $w] $data(dirMenuBtn) configure \ -textvariable ::tk::dialog::file::${dataName}(selectPath) # Cleanup previous menu # $data(typeMenu) delete 0 end $data(typeMenuBtn) configure -state normal -text "" # Initialize the file types menu # if {[llength $data(-filetypes)]} { # Default type and name to first entry set initialtype [lindex $data(-filetypes) 0] set initialTypeName [lindex $initialtype 0] if {$data(-typevariable) ne ""} { upvar #0 $data(-typevariable) typeVariable if {[info exists typeVariable]} { set initialTypeName $typeVariable } } foreach type $data(-filetypes) { set title [lindex $type 0] set filter [lindex $type 1] $data(typeMenu) add command -label $title \ -command [list ::tk::dialog::file::SetFilter $w $type] # string first avoids glob-pattern char issues if {[string first ${initialTypeName} $title] == 0} { set initialtype $type } } SetFilter $w $initialtype $data(typeMenuBtn) configure -state normal $data(typeMenuLab) configure -state normal } else { set data(filter) "*" $data(typeMenuBtn) configure -state disabled -takefocus 0 $data(typeMenuLab) configure -state disabled } UpdateWhenIdle $w # Withdraw the window, then update all the geometry information # so we know how big it wants to be, then center the window in the # display and de-iconify it. ::tk::PlaceWindow $w widget $data(-parent) wm title $w $data(-title) # Set a grab and claim the focus too. ::tk::SetFocusGrab $w $data(ent) $data(ent) delete 0 end $data(ent) insert 0 $data(selectFile) $data(ent) selection range 0 end $data(ent) icursor end # Wait for the user to respond, then restore the focus and # return the index of the selected button. Restore the focus # before deleting the window, since otherwise the window manager # may take the focus away so we can't redirect it. Finally, # restore any grab that was in effect. vwait ::tk::Priv(selectFilePath) ::tk::RestoreFocusGrab $w $data(ent) withdraw # Cleanup traces on selectPath variable # foreach trace [trace info variable data(selectPath)] { trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1] } $data(dirMenuBtn) configure -textvariable {} return $Priv(selectFilePath) } # ::tk::dialog::file::Config -- # # Configures the TK filedialog according to the argument list # proc ::tk::dialog::file::Config {dataName type argList} { upvar ::tk::dialog::file::$dataName data set data(type) $type # 0: Delete all variable that were set on data(selectPath) the # last time the file dialog is used. The traces may cause troubles # if the dialog is now used with a different -parent option. foreach trace [trace info variable data(selectPath)] { trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1] } # 1: the configuration specs # set specs { {-defaultextension "" "" ""} {-filetypes "" "" ""} {-initialdir "" "" ""} {-initialfile "" "" ""} {-parent "" "" "."} {-title "" "" ""} {-typevariable "" "" ""} } # The "-multiple" option is only available for the "open" file dialog. # if {$type eq "open"} { lappend specs {-multiple "" "" "0"} } # 2: default values depending on the type of the dialog # if {![info exists data(selectPath)]} { # first time the dialog has been popped up set data(selectPath) [pwd] set data(selectFile) "" } # 3: parse the arguments # tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList if {$data(-title) eq ""} { if {$type eq "open"} { set data(-title) [mc "Open"] } else { set data(-title) [mc "Save As"] } } # 4: set the default directory and selection according to the -initial # settings # if {$data(-initialdir) ne ""} { # Ensure that initialdir is an absolute path name. if {[file isdirectory $data(-initialdir)]} { set old [pwd] cd $data(-initialdir) set data(selectPath) [pwd] cd $old } else { set data(selectPath) [pwd] } } set data(selectFile) $data(-initialfile) # 5. Parse the -filetypes option # set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)] if {![winfo exists $data(-parent)]} { error "bad window path name \"$data(-parent)\"" } # Set -multiple to a one or zero value (not other boolean types # like "yes") so we can use it in tests more easily. if {$type eq "save"} { set data(-multiple) 0 } elseif {$data(-multiple)} { set data(-multiple) 1 } else { set data(-multiple) 0 } } proc ::tk::dialog::file::Create {w class} { set dataName [lindex [split $w .] end] upvar ::tk::dialog::file::$dataName data variable ::tk::Priv global tk_library toplevel $w -class $class if {[tk windowingsystem] eq "x11"} {wm attributes $w -type dialog} pack [ttk::frame $w.contents] -expand 1 -fill both #set w $w.contents # f1: the frame with the directory option menu # set f1 [ttk::frame $w.contents.f1] bind [::tk::AmpWidget ttk::label $f1.lab -text [mc "&Directory:"]] \ <<AltUnderlined>> [list focus $f1.menu] set data(dirMenuBtn) $f1.menu if {![info exists data(selectPath)]} { set data(selectPath) "" } set data(dirMenu) $f1.menu.menu ttk::menubutton $f1.menu -menu $data(dirMenu) -direction flush \ -textvariable [format %s(selectPath) ::tk::dialog::file::$dataName] [menu $data(dirMenu) -tearoff 0] add radiobutton -label "" -variable \ [format %s(selectPath) ::tk::dialog::file::$dataName] set data(upBtn) [ttk::button $f1.up] if {![info exists Priv(updirImage)]} { set Priv(updirImage) [image create bitmap -data { #define updir_width 28 #define updir_height 16 static char updir_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x07, 0x00, 0x01, 0x90, 0x0f, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0xfe, 0x07, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0xf0, 0xff, 0xff, 0x01};}] } $data(upBtn) configure -image $Priv(updirImage) $f1.menu configure -takefocus 1;# -highlightthickness 2 pack $data(upBtn) -side right -padx 4 -fill both pack $f1.lab -side left -padx 4 -fill both pack $f1.menu -expand yes -fill both -padx 4 # data(icons): the IconList that list the files and directories. # if {$class eq "TkFDialog"} { if { $data(-multiple) } { set fNameCaption [mc "File &names:"] } else { set fNameCaption [mc "File &name:"] } set fTypeCaption [mc "Files of &type:"] set iconListCommand [list ::tk::dialog::file::OkCmd $w] } else { set fNameCaption [mc "&Selection:"] set iconListCommand [list ::tk::dialog::file::chooseDir::DblClick $w] } set data(icons) [::tk::IconList $w.contents.icons \ -command $iconListCommand -multiple $data(-multiple)] bind $data(icons) <<ListboxSelect>> \ [list ::tk::dialog::file::ListBrowse $w] # f2: the frame with the OK button, cancel button, "file name" field # and file types field. # set f2 [ttk::frame $w.contents.f2] bind [::tk::AmpWidget ttk::label $f2.lab -text $fNameCaption -anchor e]\ <<AltUnderlined>> [list focus $f2.ent] # -pady 0 set data(ent) [ttk::entry $f2.ent] # The font to use for the icons. The default Canvas font on Unix # is just deviant. set ::tk::$w.contents.icons(font) [$data(ent) cget -font] # Make the file types bits only if this is a File Dialog if {$class eq "TkFDialog"} { set data(typeMenuLab) [::tk::AmpWidget ttk::label $f2.lab2 \ -text $fTypeCaption -anchor e] # -pady [$f2.lab cget -pady] set data(typeMenuBtn) [ttk::menubutton $f2.menu \ -menu $f2.menu.m] # -indicatoron 1 set data(typeMenu) [menu $data(typeMenuBtn).m -tearoff 0] # $data(typeMenuBtn) configure -takefocus 1 -relief raised -anchor w bind $data(typeMenuLab) <<AltUnderlined>> [list \ focus $data(typeMenuBtn)] } # The hidden button is displayed when ::tk::dialog::file::showHiddenBtn # is true. Create it disabled so the binding doesn't trigger if it # isn't shown. if {$class eq "TkFDialog"} { set text [mc "Show &Hidden Files and Directories"] } else { set text [mc "Show &Hidden Directories"] } set data(hiddenBtn) [::tk::AmpWidget ttk::checkbutton $f2.hidden \ -text $text -state disabled \ -variable ::tk::dialog::file::showHiddenVar \ -command [list ::tk::dialog::file::UpdateWhenIdle $w]] # -anchor w -padx 3 # the okBtn is created after the typeMenu so that the keyboard traversal # is in the right order, and add binding so that we find out when the # dialog is destroyed by the user (added here instead of to the overall # window so no confusion about how much <Destroy> gets called; exactly # once will do). [Bug 987169] set data(okBtn) [::tk::AmpWidget ttk::button $f2.ok \ -text [mc "&OK"] -default active];# -pady 3] bind $data(okBtn) <Destroy> [list ::tk::dialog::file::Destroyed $w] set data(cancelBtn) [::tk::AmpWidget ttk::button $f2.cancel \ -text [mc "&Cancel"] -default normal];# -pady 3] # grid the widgets in f2 # grid $f2.lab $f2.ent $data(okBtn) -padx 4 -pady 3 -sticky ew grid configure $f2.ent -padx 2 if {$class eq "TkFDialog"} { grid $data(typeMenuLab) $data(typeMenuBtn) $data(cancelBtn) \ -padx 4 -sticky ew grid configure $data(typeMenuBtn) -padx 0 grid $data(hiddenBtn) -columnspan 2 -padx 4 -sticky ew } else { grid $data(hiddenBtn) - $data(cancelBtn) -padx 4 -sticky ew } grid columnconfigure $f2 1 -weight 1 # Pack all the frames together. We are done with widget construction. # pack $f1 -side top -fill x -pady 4 pack $f2 -side bottom -pady 4 -fill x pack $data(icons) -expand yes -fill both -padx 4 -pady 1 # Set up the event handlers that are common to Directory and File Dialogs # wm protocol $w WM_DELETE_WINDOW [list ::tk::dialog::file::CancelCmd $w] $data(upBtn) configure -command [list ::tk::dialog::file::UpDirCmd $w] $data(cancelBtn) configure -command [list ::tk::dialog::file::CancelCmd $w] bind $w <KeyPress-Escape> [list $data(cancelBtn) invoke] bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A] # Set up event handlers specific to File or Directory Dialogs # if {$class eq "TkFDialog"} { bind $data(ent) <Return> [list ::tk::dialog::file::ActivateEnt $w] $data(okBtn) configure -command [list ::tk::dialog::file::OkCmd $w] bind $w <Alt-t> [format { if {[%s cget -state] eq "normal"} { focus %s } } $data(typeMenuBtn) $data(typeMenuBtn)] } else { set okCmd [list ::tk::dialog::file::chooseDir::OkCmd $w] bind $data(ent) <Return> $okCmd $data(okBtn) configure -command $okCmd bind $w <Alt-s> [list focus $data(ent)] bind $w <Alt-o> [list $data(okBtn) invoke] } bind $w <Alt-h> [list $data(hiddenBtn) invoke] bind $data(ent) <Tab> [list ::tk::dialog::file::CompleteEnt $w] # Build the focus group for all the entries # ::tk::FocusGroup_Create $w ::tk::FocusGroup_BindIn $w $data(ent) [list \ ::tk::dialog::file::EntFocusIn $w] ::tk::FocusGroup_BindOut $w $data(ent) [list \ ::tk::dialog::file::EntFocusOut $w] } # ::tk::dialog::file::SetSelectMode -- # # Set the select mode of the dialog to single select or multi-select. # # Arguments: # w The dialog path. # multi 1 if the dialog is multi-select; 0 otherwise. # # Results: # None. proc ::tk::dialog::file::SetSelectMode {w multi} { set dataName __tk_filedialog upvar ::tk::dialog::file::$dataName data if { $multi } { set fNameCaption [mc "File &names:"] } else { set fNameCaption [mc "File &name:"] } set iconListCommand [list ::tk::dialog::file::OkCmd $w] ::tk::SetAmpText $w.contents.f2.lab $fNameCaption ::tk::IconList_Config $data(icons) \ [list -multiple $multi -command $iconListCommand] return } # ::tk::dialog::file::UpdateWhenIdle -- # # Creates an idle event handler which updates the dialog in idle # time. This is important because loading the directory may take a long # time and we don't want to load the same directory for multiple times # due to multiple concurrent events. # proc ::tk::dialog::file::UpdateWhenIdle {w} { upvar ::tk::dialog::file::[winfo name $w] data if {[info exists data(updateId)]} { return } else { set data(updateId) [after idle [list ::tk::dialog::file::Update $w]] } } # ::tk::dialog::file::Update -- # # Loads the files and directories into the IconList widget. Also # sets up the directory option menu for quick access to parent # directories. # proc ::tk::dialog::file::Update {w} { # This proc may be called within an idle handler. Make sure that the # window has not been destroyed before this proc is called if {![winfo exists $w]} { return } set class [winfo class $w] if {($class ne "TkFDialog") && ($class ne "TkChooseDir")} { return } set dataName [winfo name $w] upvar ::tk::dialog::file::$dataName data variable ::tk::Priv global tk_library unset -nocomplain data(updateId) if {![info exists Priv(folderImage)]} { set Priv(folderImage) [image create photo -data { R0lGODlhEAAMAKEAAAD//wAAAPD/gAAAACH5BAEAAAAALAAAAAAQAAwAAAIghINhyycvVFsB QtmS3rjaH1Hg141WaT5ouprt2HHcUgAAOw==}] set Priv(fileImage) [image create photo -data { R0lGODlhDAAMAKEAALLA3AAAAP//8wAAACH5BAEAAAAALAAAAAAMAAwAAAIgRI4Ha+IfWHsO rSASvJTGhnhcV3EJlo3kh53ltF5nAhQAOw==}] } set folder $Priv(folderImage) set file $Priv(fileImage) set appPWD [pwd] if {[catch { cd $data(selectPath) }]} { # We cannot change directory to $data(selectPath). $data(selectPath) # should have been checked before ::tk::dialog::file::Update is called, so # we normally won't come to here. Anyways, give an error and abort # action. tk_messageBox -type ok -parent $w -icon warning -message \ [mc "Cannot change to the directory \"%1\$s\".\nPermission denied." $data(selectPath)] cd $appPWD return } # Turn on the busy cursor. BUG?? We haven't disabled X events, though, # so the user may still click and cause havoc ... # set entCursor [$data(ent) cget -cursor] set dlgCursor [$w cget -cursor] $data(ent) configure -cursor watch $w configure -cursor watch update idletasks ::tk::IconList_DeleteAll $data(icons) set showHidden $::tk::dialog::file::showHiddenVar # Make the dir list # Using -directory [pwd] is better in some VFS cases. set cmd [list glob -tails -directory [pwd] -type d -nocomplain *] if {$showHidden} { lappend cmd .* } set dirs [lsort -dictionary -unique [eval $cmd]] set dirList {} foreach d $dirs { if {$d eq "." || $d eq ".."} { continue } lappend dirList $d } ::tk::IconList_Add $data(icons) $folder $dirList if {$class eq "TkFDialog"} { # Make the file list if this is a File Dialog, selecting all # but 'd'irectory type files. # set cmd [list glob -tails -directory [pwd] \ -type {f b c l p s} -nocomplain] if {$data(filter) eq "*"} { lappend cmd * if {$showHidden} { lappend cmd .* } } else { eval [list lappend cmd] $data(filter) } set fileList [lsort -dictionary -unique [eval $cmd]] ::tk::IconList_Add $data(icons) $file $fileList } ::tk::IconList_Arrange $data(icons) # Update the Directory: option menu # set list "" set dir "" foreach subdir [file split $data(selectPath)] { set dir [file join $dir $subdir] lappend list $dir } $data(dirMenu) delete 0 end set var [format %s(selectPath) ::tk::dialog::file::$dataName] foreach path $list { $data(dirMenu) add command -label $path -command [list set $var $path] } # Restore the PWD to the application's PWD # cd $appPWD if {$class eq "TkFDialog"} { # Restore the Open/Save Button if this is a File Dialog # if {$data(type) eq "open"} { ::tk::SetAmpText $data(okBtn) [mc "&Open"] } else { ::tk::SetAmpText $data(okBtn) [mc "&Save"] } } # turn off the busy cursor. # $data(ent) configure -cursor $entCursor $w configure -cursor $dlgCursor } # ::tk::dialog::file::SetPathSilently -- # # Sets data(selectPath) without invoking the trace procedure # proc ::tk::dialog::file::SetPathSilently {w path} { upvar ::tk::dialog::file::[winfo name $w] data trace remove variable data(selectPath) write [list ::tk::dialog::file::SetPath $w] set data(selectPath) $path trace add variable data(selectPath) write [list ::tk::dialog::file::SetPath $w] } # This proc gets called whenever data(selectPath) is set # proc ::tk::dialog::file::SetPath {w name1 name2 op} { if {[winfo exists $w]} { upvar ::tk::dialog::file::[winfo name $w] data UpdateWhenIdle $w # On directory dialogs, we keep the entry in sync with the currentdir. if {[winfo class $w] eq "TkChooseDir"} { $data(ent) delete 0 end $data(ent) insert end $data(selectPath) } } } # This proc gets called whenever data(filter) is set # proc ::tk::dialog::file::SetFilter {w type} { upvar ::tk::dialog::file::[winfo name $w] data upvar ::tk::$data(icons) icons set data(filterType) $type set data(filter) [lindex $type 1] $data(typeMenuBtn) configure -text [lindex $type 0] ;#-indicatoron 1 # If we aren't using a default extension, use the one suppled # by the filter. if {![info exists data(extUsed)]} { if {[string length $data(-defaultextension)]} { set data(extUsed) 1 } else { set data(extUsed) 0 } } if {!$data(extUsed)} { # Get the first extension in the list that matches {^\*\.\w+$} # and remove all * from the filter. set index [lsearch -regexp $data(filter) {^\*\.\w+$}] if {$index >= 0} { set data(-defaultextension) \ [string trimleft [lindex $data(filter) $index] "*"] } else { # Couldn't find anything! Reset to a safe default... set data(-defaultextension) "" } } $icons(sbar) set 0.0 0.0 UpdateWhenIdle $w } # tk::dialog::file::ResolveFile -- # # Interpret the user's text input in a file selection dialog. # Performs: # # (1) ~ substitution # (2) resolve all instances of . and .. # (3) check for non-existent files/directories # (4) check for chdir permissions # (5) conversion of environment variable references to their # contents (once only) # # Arguments: # context: the current directory you are in # text: the text entered by the user # defaultext: the default extension to add to files with no extension # expandEnv: whether to expand environment variables (yes by default) # # Return vaue: # [list $flag $directory $file] # # flag = OK : valid input # = PATTERN : valid directory/pattern # = PATH : the directory does not exist # = FILE : the directory exists by the file doesn't # exist # = CHDIR : Cannot change to the directory # = ERROR : Invalid entry # # directory : valid only if flag = OK or PATTERN or FILE # file : valid only if flag = OK or PATTERN # # directory may not be the same as context, because text may contain # a subdirectory name # proc ::tk::dialog::file::ResolveFile {context text defaultext {expandEnv 1}} { set appPWD [pwd] set path [JoinFile $context $text] # If the file has no extension, append the default. Be careful not # to do this for directories, otherwise typing a dirname in the box # will give back "dirname.extension" instead of trying to change dir. if { ![file isdirectory $path] && ([file ext $path] eq "") && ![string match {$*} [file tail $path]] } then { set path "$path$defaultext" } # we want to strip any filtering/ext/blocking instructions # from the file name set aa [string first "\[" $path] if {$aa > 0} { set fn [string range $path 0 [expr $aa-1]] } else { set fn $path } if {[catch {file exists $fn}]} { # This "if" block can be safely removed if the following code # stop generating errors. # # file exists ~nonsuchuser # return [list ERROR $path ""] } if {[file exists $fn]} { if {[file isdirectory $path]} { if {[catch {cd $path}]} { return [list CHDIR $path ""] } set directory [pwd] set file "" set flag OK cd $appPWD } else { if {[catch {cd [file dirname $path]}]} { return [list CHDIR [file dirname $path] ""] } set directory [pwd] set file [file tail $path] set flag OK cd $appPWD } } else { set dirname [file dirname $path] if {[file exists $dirname]} { if {[catch {cd $dirname}]} { return [list CHDIR $dirname ""] } set directory [pwd] cd $appPWD set file [file tail $path] # It's nothing else, so check to see if it is an env-reference if {$expandEnv && [string match {$*} $file]} { set var [string range $file 1 end] if {[info exist ::env($var)]} { return [ResolveFile $context $::env($var) $defaultext 0] } } if {[regexp {[*?]} $file]} { set flag PATTERN } else { set flag FILE } } else { set directory $dirname set file [file tail $path] set flag PATH # It's nothing else, so check to see if it is an env-reference if {$expandEnv && [string match {$*} $file]} { set var [string range $file 1 end] if {[info exist ::env($var)]} { return [ResolveFile $context $::env($var) $defaultext 0] } } } } return [list $flag $directory $file] } # Gets called when the entry box gets keyboard focus. We clear the selection # from the icon list . This way the user can be certain that the input in the # entry box is the selection. # proc ::tk::dialog::file::EntFocusIn {w} { upvar ::tk::dialog::file::[winfo name $w] data if {[$data(ent) get] ne ""} { $data(ent) selection range 0 end $data(ent) icursor end } else { $data(ent) selection clear } if {[winfo class $w] eq "TkFDialog"} { # If this is a File Dialog, make sure the buttons are labeled right. if {$data(type) eq "open"} { ::tk::SetAmpText $data(okBtn) [mc "&Open"] } else { ::tk::SetAmpText $data(okBtn) [mc "&Save"] } } } proc ::tk::dialog::file::EntFocusOut {w} { upvar ::tk::dialog::file::[winfo name $w] data $data(ent) selection clear } # Gets called when user presses Return in the "File name" entry. # proc ::tk::dialog::file::ActivateEnt {w} { upvar ::tk::dialog::file::[winfo name $w] data set text [$data(ent) get] if {$data(-multiple)} { foreach t $text { VerifyFileName $w $t } } else { VerifyFileName $w $text } } # Verification procedure # proc ::tk::dialog::file::VerifyFileName {w filename} { upvar ::tk::dialog::file::[winfo name $w] data set list [ResolveFile $data(selectPath) $filename $data(-defaultextension)] foreach {flag path file} $list { break } switch -- $flag { OK { if {$file eq ""} { # user has entered an existing (sub)directory set data(selectPath) $path $data(ent) delete 0 end } else { SetPathSilently $w $path if {$data(-multiple)} { lappend data(selectFile) $file } else { set data(selectFile) $file } Done $w } } PATTERN { set data(selectPath) $path set data(filter) $file } FILE { if {$data(type) eq "open"} { tk_messageBox -icon warning -type ok -parent $w \ -message [mc "File \"%1\$s\" does not exist." \ [file join $path $file]] $data(ent) selection range 0 end $data(ent) icursor end } else { SetPathSilently $w $path if {$data(-multiple)} { lappend data(selectFile) $file } else { set data(selectFile) $file } Done $w } } PATH { tk_messageBox -icon warning -type ok -parent $w \ -message [mc "Directory \"%1\$s\" does not exist." $path] $data(ent) selection range 0 end $data(ent) icursor end } CHDIR { tk_messageBox -type ok -parent $w -icon warning -message \ [mc "Cannot change to the directory\ \"%1\$s\".\nPermission denied." $path] $data(ent) selection range 0 end $data(ent) icursor end } ERROR { tk_messageBox -type ok -parent $w -icon warning -message \ [mc "Invalid file name \"%1\$s\"." $path] $data(ent) selection range 0 end $data(ent) icursor end } } } # Gets called when user presses the Alt-s or Alt-o keys. # proc ::tk::dialog::file::InvokeBtn {w key} { upvar ::tk::dialog::file::[winfo name $w] data if {[$data(okBtn) cget -text] eq $key} { $data(okBtn) invoke } } # Gets called when user presses the "parent directory" button # proc ::tk::dialog::file::UpDirCmd {w} { upvar ::tk::dialog::file::[winfo name $w] data if {$data(selectPath) ne "/"} { set data(selectPath) [file dirname $data(selectPath)] } } # Join a file name to a path name. The "file join" command will break # if the filename begins with ~ # proc ::tk::dialog::file::JoinFile {path file} { if {[string match {~*} $file] && [file exists $path/$file]} { return [file join $path ./$file] } else { return [file join $path $file] } } # Gets called when user presses the "OK" button # proc ::tk::dialog::file::OkCmd {w} { upvar ::tk::dialog::file::[winfo name $w] data set filenames {} foreach item [::tk::IconList_CurSelection $data(icons)] { lappend filenames [::tk::IconList_Get $data(icons) $item] } if {([llength $filenames] && !$data(-multiple)) || \ ($data(-multiple) && ([llength $filenames] == 1))} { set filename [lindex $filenames 0] set file [JoinFile $data(selectPath) $filename] if {[file isdirectory $file]} { ListInvoke $w [list $filename] return } } ActivateEnt $w } # Gets called when user presses the "Cancel" button # proc ::tk::dialog::file::CancelCmd {w} { upvar ::tk::dialog::file::[winfo name $w] data variable ::tk::Priv bind $data(okBtn) <Destroy> {} set Priv(selectFilePath) "" } # Gets called when user destroys the dialog directly [Bug 987169] # proc ::tk::dialog::file::Destroyed {w} { upvar ::tk::dialog::file::[winfo name $w] data variable ::tk::Priv set Priv(selectFilePath) "" } # Gets called when user browses the IconList widget (dragging mouse, arrow # keys, etc) # proc ::tk::dialog::file::ListBrowse {w} { upvar ::tk::dialog::file::[winfo name $w] data set text {} foreach item [::tk::IconList_CurSelection $data(icons)] { lappend text [::tk::IconList_Get $data(icons) $item] } if {[llength $text] == 0} { return } if {$data(-multiple)} { set newtext {} foreach file $text { set fullfile [JoinFile $data(selectPath) $file] if { ![file isdirectory $fullfile] } { lappend newtext $file } } set text $newtext set isDir 0 } else { set text [lindex $text 0] set file [JoinFile $data(selectPath) $text] set isDir [file isdirectory $file] } if {!$isDir} { $data(ent) delete 0 end $data(ent) insert 0 $text if {[winfo class $w] eq "TkFDialog"} { if {$data(type) eq "open"} { ::tk::SetAmpText $data(okBtn) [mc "&Open"] } else { ::tk::SetAmpText $data(okBtn) [mc "&Save"] } } } elseif {[winfo class $w] eq "TkFDialog"} { ::tk::SetAmpText $data(okBtn) [mc "&Open"] } } # Gets called when user invokes the IconList widget (double-click, # Return key, etc) # proc ::tk::dialog::file::ListInvoke {w filenames} { upvar ::tk::dialog::file::[winfo name $w] data if {[llength $filenames] == 0} { return } set file [JoinFile $data(selectPath) [lindex $filenames 0]] set class [winfo class $w] if {$class eq "TkChooseDir" || [file isdirectory $file]} { set appPWD [pwd] if {[catch {cd $file}]} { tk_messageBox -type ok -parent $w -icon warning -message \ [mc "Cannot change to the directory \"%1\$s\".\nPermission denied." $file] } else { cd $appPWD set data(selectPath) $file } } else { if {$data(-multiple)} { set data(selectFile) $filenames } else { set data(selectFile) $file } Done $w } } # ::tk::dialog::file::Done -- # # Gets called when user has input a valid filename. Pops up a # dialog box to confirm selection when necessary. Sets the # tk::Priv(selectFilePath) variable, which will break the "vwait" # loop in ::tk::dialog::file:: and return the selected filename to the # script that calls tk_getOpenFile or tk_getSaveFile # proc ::tk::dialog::file::Done {w {selectFilePath ""}} { upvar ::tk::dialog::file::[winfo name $w] data variable ::tk::Priv if {$selectFilePath eq ""} { if {$data(-multiple)} { set selectFilePath {} foreach f $data(selectFile) { lappend selectFilePath [JoinFile $data(selectPath) $f] } } else { set selectFilePath [JoinFile $data(selectPath) $data(selectFile)] } set Priv(selectFile) $data(selectFile) set Priv(selectPath) $data(selectPath) if {($data(type) eq "save") && [file exists $selectFilePath]} { set reply [tk_messageBox -icon warning -type yesno -parent $w \ -message [mc "File \"%1\$s\" already exists.\nDo you want\ to overwrite it?" $selectFilePath]] if {$reply eq "no"} { return } } if {[info exists data(-typevariable)] && $data(-typevariable) ne "" && [info exists data(-filetypes)] && [llength $data(-filetypes)] && [info exists data(filterType)] && $data(filterType) ne ""} { upvar #0 $data(-typevariable) typeVariable set typeVariable [lindex $data(filterType) 0] } } bind $data(okBtn) <Destroy> {} set Priv(selectFilePath) $selectFilePath } proc ::tk::dialog::file::CompleteEnt {w} { upvar ::tk::dialog::file::[winfo name $w] data set f [$data(ent) get] if {$data(-multiple)} { if {[catch {llength $f} len] || $len != 1} { return -code break } set f [lindex $f 0] } # Get list of matching filenames and dirnames set globF [list glob -tails -directory $data(selectPath) \ -type {f b c l p s} -nocomplain] set globD [list glob -tails -directory $data(selectPath) -type d \ -nocomplain *] if {$data(filter) eq "*"} { lappend globF * if {$::tk::dialog::file::showHiddenVar} { lappend globF .* lappend globD .* } if {[winfo class $w] eq "TkFDialog"} { set files [lsort -dictionary -unique [{*}$globF]] } else { set files {} } set dirs [lsort -dictionary -unique [{*}$globD]] } else { if {$::tk::dialog::file::showHiddenVar} { lappend globD .* } if {[winfo class $w] eq "TkFDialog"} { set files [lsort -dictionary -unique [{*}$globF {*}$data(filter)]] } else { set files {} } set dirs [lsort -dictionary -unique [{*}$globD]] } # Filter specials set dirs [lsearch -all -not -exact -inline $dirs .] set dirs [lsearch -all -not -exact -inline $dirs ..] set dirs2 {} foreach d $dirs {lappend dirs2 $d/} set targets [concat \ [lsearch -glob -all -inline $files $f*] \ [lsearch -glob -all -inline $dirs2 $f*]] if {[llength $targets] == 1} { # We have a winner! set f [lindex $targets 0] } elseif {$f in $targets || [llength $targets] == 0} { if {[string length $f] > 0} { bell } return } elseif {[llength $targets] > 1} { # Multiple possibles if {[string length $f] == 0} { return } set t0 [lindex $targets 0] for {set len [string length $t0]} {$len>0} {} { set allmatch 1 foreach s $targets { if {![string equal -length $len $s $t0]} { set allmatch 0 break } } incr len -1 if {$allmatch} break } set f [string range $t0 0 $len] } if {$data(-multiple)} { set f [list $f] } $data(ent) delete 0 end $data(ent) insert 0 $f return -code break } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/slider.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000003412�11723501752�013663� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc slider {w from to label varname cmd {num {5}} {width {7}}} { ttk::frame $w ttk::scale $w.slider \ -length 300 \ -orient horizontal \ -variable $varname \ -takefocus 0 \ -command [list SliderCmd $w $varname $cmd] ttk::label $w.label -text $label ttk::entry $w.entry -textvariable $varname -width $width grid $w.label -sticky w -columnspan $num grid $w.slider -row 1 -columnspan $num -padx 2 -pady 2 -sticky news grid $w.entry -row 1 -column $num -padx 2 -pady 2 for {set ii 0} {$ii<$num} {incr ii} { ttk::label $w.t$ii -width $width -anchor center grid $w.t$ii -row 2 -column $ii grid columnconfigure $w $ii -weight 1 } grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 grid rowconfigure $w 2 -weight 1 bind $w.entry <Return> $cmd SliderMinMax $w $from $to $num return $w } proc SliderMinMax {w from to num} { $w.slider configure -from $from -to $to if {$from == $to} { for {set ii 0} {$ii<$num} {incr ii} { $w.t$ii configure -text {} } } else { for {set ii 0} {$ii<$num} {incr ii} { set vv [expr ($to*1.-$from)/($num-1)*$ii + $from] if {[string is integer $from] && [string is integer $to]} { set vv [expr int($vv)] } else { set vv [format {%.5g} $vv] } $w.t$ii configure -text $vv } } } proc SliderCmd {w varname cmd vv} { upvar $varname var set from [$w.slider cget -from] set to [$w.slider cget -to] if {[string is integer $from] && [string is integer $to]} { set var [expr int($vv)] } if {$cmd != {}} { eval $cmd } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/rgb.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000017771�12021722227�013162� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc RGBDef {} { global rgb global irgb set irgb(top) .rgb set irgb(mb) .rgbmb set rgb(red) 1 set rgb(green) 1 set rgb(blue) 1 set rgb(system) wcs set rgb(lock,wcs) 0 set rgb(lock,crop) 0 set rgb(lock,slice) 0 set rgb(lock,bin) 0 set rgb(lock,scale) 0 set rgb(lock,colorbar) 0 set rgb(lock,smooth) 0 } proc RGBEvalLockCurrent {varname cmd} { global current global rgb global crop global cube global bin global scale global colorbar global smooth RGBEvalLock $varname $current(frame) $cmd } proc RGBEvalLock {varname which cmd} { upvar $varname var global rgb global crop global cube global bin global scale global colorbar global smooth if {$var && [$which get type] == {rgb}} { set ch [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc eval $cmd } $which rgb channel $ch } else { eval $cmd } } proc RGBEvalLockColorbar {cmd} { global current global scale global rgb if {$rgb(lock,colorbar) && [$current(frame) get type] == {rgb}} { set ch $current(rgb) foreach c {red green blue} { colorbarrgb rgb channel $c eval $cmd } set current(rgb) $ch colorbarrgb rgb channel $current(rgb) } else { eval $cmd } } proc RGBChannel {} { global current if {$current(frame) != {}} { if {[$current(frame) get type] == {rgb}} { colorbarrgb rgb channel $current(rgb) } $current(frame) rgb channel $current(rgb) UpdateDS9 } } proc RGBView {} { global current global rgb if {$current(frame) != {}} { $current(frame) rgb view $rgb(red) $rgb(green) $rgb(blue) } } proc RGBSystem {} { global current global rgb if {$current(frame) != {}} { $current(frame) rgb system $rgb(system) } } # used by backup proc RGBDialog {} { global rgb global irgb global current global ds9 # see if we already have a window visible if [winfo exists $irgb(top)] { raise $irgb(top) return } # create the rgb window set w $irgb(top) set mb $irgb(mb) Toplevel $w $mb 6 [msgcat::mc {RGB}] RGBDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Align}] -menu $mb.align $mb add cascade -label [msgcat::mc {Lock}] -menu $mb.lock menu $mb.file $mb.file add command -label [msgcat::mc {Close}] -command RGBDestroyDialog CoordMenu $mb.align rgb system 1 {} {} RGBSystem menu $mb.lock $mb.lock add checkbutton -label [msgcat::mc {WCS}] \ -variable rgb(lock,wcs) $mb.lock add checkbutton -label [msgcat::mc {Crop}] \ -variable rgb(lock,crop) $mb.lock add checkbutton -label [msgcat::mc {Slice}] \ -variable rgb(lock,slice) $mb.lock add checkbutton -label [msgcat::mc {Bin}] \ -variable rgb(lock,bin) $mb.lock add checkbutton -label [msgcat::mc {Scale}] \ -variable rgb(lock,scale) $mb.lock add checkbutton -label [msgcat::mc {Colorbar}] \ -variable rgb(lock,colorbar) $mb.lock add checkbutton -label [msgcat::mc {Smooth}] \ -variable rgb(lock,smooth) # Param set f [ttk::frame $w.param] ttk::label $f.currenttitle -text [msgcat::mc {Current}] ttk::label $f.viewtitle -text [msgcat::mc {View}] ttk::label $f.redtitle -text [msgcat::mc {Red}] ttk::label $f.bluetitle -text [msgcat::mc {Blue}] ttk::label $f.greentitle -text [msgcat::mc {Green}] ttk::radiobutton $f.redcurrent -variable current(rgb) \ -value red -command RGBChannel ttk::radiobutton $f.greencurrent -variable current(rgb) \ -value green -command RGBChannel ttk::radiobutton $f.bluecurrent -variable current(rgb) \ -value blue -command RGBChannel ttk::checkbutton $f.redview -variable rgb(red) -command RGBView ttk::checkbutton $f.greenview -variable rgb(green) -command RGBView ttk::checkbutton $f.blueview -variable rgb(blue) -command RGBView grid x $f.currenttitle $f.viewtitle -padx 2 -pady 2 -sticky w grid $f.redtitle $f.redcurrent $f.redview -padx 2 -pady 2 -sticky w grid $f.greentitle $f.greencurrent $f.greenview -padx 2 -pady 2 -sticky w grid $f.bluetitle $f.bluecurrent $f.blueview -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.close -text [msgcat::mc {Close}] \ -command RGBDestroyDialog pack $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true } proc RGBDestroyDialog {} { global irgb if {[winfo exists $irgb(top)]} { destroy $irgb(top) destroy $irgb(mb) } } proc UpdateRGBMenu {} { # can be changed by wcs SetCoordSystem rgb system {} {} } proc UpdateRGBDialog {} { global rgb global irgb global current global debug if {$debug(tcl,update)} { puts stderr "UpdateRGBDialog" } if {![winfo exists $irgb(top)]} { return } if {$current(frame) != {}} { set rgb(frame) $current(frame) if {[$current(frame) has fits]} { # now make sure we have the coord systems AdjustCoordSystem rgb system CoordMenuEnable $irgb(mb).align rgb system 1 {} {} } else { CoordMenuReset $irgb(mb).align rgb system 1 {} {} } } if {$current(frame) != {}} { set current(rgb) [$current(frame) get rgb channel] set r [$current(frame) get rgb view] set rgb(red) [lindex $r 0] set rgb(green) [lindex $r 1] set rgb(blue) [lindex $r 2] set rgb(system) [$current(frame) get rgb system] } } proc RGBBackup {ch which} { puts $ch "$which rgb channel [$which get rgb channel]" puts $ch "$which rgb view [$which get rgb view]" puts $ch "$which rgb system [$which get rgb system]" } # Process Cmds proc ProcessRGBCmd {varname iname} { upvar $varname var upvar $iname i global current global rgb RGBDialog switch -- [string tolower [lindex $var $i]] { open {} close {RGBDestroyDialog} red - green - blue { set current(rgb) [string tolower [lindex $var $i]] RGBChannel } channel { incr i set current(rgb) [string tolower [lindex $var $i]] RGBChannel } lock { incr i set item [string tolower [lindex $var $i]] incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set rr [FromYesNo [lindex $var $i]] } else { set rr 1 incr i -1 } switch -- $item { wcs {set rgb(lock,wcs) $rr} crop {set rgb(lock,crop) $rr} slice {set rgb(lock,slice) $rr} bin {set rgb(lock,bin) $rr} scale {set rgb(lock,scale) $rr} color - colormap - colorbar {set rgb(lock,colorbar) $rr} smooth {set rgb(lock,smooth) $rr} } } system { incr i set rgb(system) [string tolower [lindex $var $i]] RGBSystem } view { set w [lindex $var [expr $i+1]] set yesno [lindex $var [expr $i+2]] switch -- [string tolower $w] { red {set rgb(red) [FromYesNo $yesno]; RGBView} green {set rgb(green) [FromYesNo $yesno]; RGBView} blue {set rgb(blue) [FromYesNo $yesno]; RGBView} } incr i 2 } default { CreateRGBFrame incr i -1 } } } proc ProcessSendRGBCmd {proc id param} { global current global rgb switch -- [lindex $param 0] { channel {$proc $id "$current(rgb)\n"} lock { switch -- [string tolower [lindex $param 1]] { wcs {$proc $id [ToYesNo $rgb(lock,wcs)]} crop {$proc $id [ToYesNo $rgb(lock,crop)]} slice {$proc $id [ToYesNo $rgb(lock,slice)]} bin {$proc $id [ToYesNo $rgb(lock,bin)]} scale {$proc $id [ToYesNo $rgb(lock,scale)]} colorbar {$proc $id [ToYesNo $rgb(lock,colorbar)]} smooth {$proc $id [ToYesNo $rgb(lock,smooth)]} } } system {$proc $id "$rgb(system)\n"} view { switch -- [lindex $param 1] { red {$proc $id [ToYesNo $rgb(red)]} green {$proc $id [ToYesNo $rgb(green)]} blue {$proc $id [ToYesNo $rgb(blue)]} } } } } �������./saods9/src/movie.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000027511�12072576157�013537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MovieDef {} { global imovie global movie global tcl_platform set imovie(top) .moviestatus set imovie(mb) .moviestatusmb set movie(action) slice # must be >=5, or sometimes will generate bad data set movie(quality) 5 set movie(num) 24 set movie(az,from) 45 set movie(az,to) -45 set movie(el,from) 30 set movie(el,to) 30 set movie(sl,from) 1 set movie(sl,to) 1 set movie(repeat) oscillate set movie(repeat,num) 0 set movie(status) 0 set movie(abort) 0 set aa [msgcat::mc {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.}] set bb [msgcat::mc {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.}] switch $tcl_platform(os) { Darwin { switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 10 - 11 {set movie(error) $bb} 8 - 9 - default {set movie(error) $aa} } } default {set movie(error) $aa} } } proc MovieDialog {} { global movie global mpegfbox global ed global current set w {.movie} set ed(ok) 0 set ed(action) $movie(action) DialogCreate $w [msgcat::mc {Create Movie}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.title -text [msgcat::mc {Format}] ttk::radiobutton $f.slice -text {Slice Movie} \ -variable ed(action) -value slice ttk::radiobutton $f.frame -text {Frames Movie} \ -variable ed(action) -value frame ttk::radiobutton $f.3d -text {3D Movie} \ -variable ed(action) -value 3d grid $f.slice -padx 2 -pady 2 -sticky w grid $f.frame -padx 2 -pady 2 -sticky w grid $f.3d -padx 2 -pady 2 -sticky w switch [$current(frame) get type] { base - rgb {$f.3d configure -state disabled} 3d {$f.3d configure -state normal} } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set movie(action) $ed(action) set fn [SaveFileDialog mpegfbox] if {$fn != {}} { set ok 1 switch $movie(action) { slice - frame {} 3d {set ok [Movie3dDialog]} } if {$ok} { Movie $fn } } } set rr $ed(ok) unset ed return $rr } proc Movie {fn} { global ds9 global movie global current if {$fn == {} || ![$current(frame) has fits]} { return } # besure we are on top raise $ds9(top) # we need single mode if {$ds9(display) != {single}} { set modesav $ds9(display) set current(display) single DisplayMode } switch $movie(action) { slice {MovieSlice $fn} frame {MovieFrame $fn} 3d {Movie3d $fn} } if {[info exists modesav]} { set current(display) $modesav DisplayMode } } proc MovieSlice {fn} { global current global movie global cube set depth [$current(frame) get fits depth $cube(axis)] set slice [$current(frame) get fits slice $cube(axis)] if {$cube(axis)==2} { set ss [$current(frame) get crop 3d image] set from [lindex $ss 0] set to [lindex $ss 1] } else { set from 1 set to [$current(frame) get fits depth $cube(axis)] } # loop thru cube set movie(first) 1 for {set ii $from} {$ii <= $to} {incr ii} { $current(frame) update fits slice $cube(axis) $ii if {[MoviePhoto $fn]} { break } } mpeg close # reset current slice $current(frame) update fits slice $cube(axis) $slice } proc MovieFrame {fn} { global ds9 global current global movie # loop thru all active frames set movie(first) 1 set framesav $current(frame) foreach ff $ds9(active) { set ds9(next) $ff GotoFrame if {[MoviePhoto $fn]} { break } } mpeg close set ds9(next) $framesav GotoFrame } proc Movie3d {fn} { global movie global current global cube set slice [$current(frame) get fits slice $cube(axis)] set vp [$current(frame) get 3d view] set azincr [expr 1.*($movie(az,to)-$movie(az,from))/$movie(num)] set elincr [expr 1.*($movie(el,to)-$movie(el,from))/$movie(num)] set slincr [expr 1.*($movie(sl,to)-$movie(sl,from))/$movie(num)] # loop over az/el/slice set movie(status) 0 set movie(abort) 0 set movie(first) 1 set az $movie(az,from) set el $movie(el,from) set sl $movie(sl,from) for {set rr 0} {$rr<=$movie(repeat,num)} {incr rr} { for {set nn 0} {$nn<=$movie(num)} {incr nn} { MovieStatusDialog if {$movie(abort)} { break } set movie(status) [expr 1.*$nn/$movie(num)*100] update idletasks $current(frame) 3d view $az $el $current(frame) update fits slice $cube(axis) [expr int($sl)] if {[MoviePhoto $fn]} { break } set az [expr $az+$azincr] set el [expr $el+$elincr] set sl [expr $sl+$slincr] } switch $movie(repeat) { repeat { set az $movie(az,from) set el $movie(el,from) set sl $movie(sl,from) } oscillate { set azincr [expr -$azincr] set elincr [expr -$elincr] set slincr [expr -$slincr] } } } mpeg close MovieStatusDestroyDialog # reset $current(frame) 3d view $vp $current(frame) update fits slice $cube(axis) $slice Update3DDialog UpdateCubeDialog } # Support proc MoviePhoto {fn} { global ds9 global movie global current # yes, we need this UpdateDS9 RealizeDS9 set rr [catch {image create photo -format window -data $ds9(canvas)} ph] if {$rr} { Error $movie(error) return $rr } if {$movie(first)} { set w [image width $ph] set h [image height $ph] mpeg create "$fn" $w $h 25 1 $movie(quality) set movie(first) 0 } mpeg add $ph image delete $ph return 0 } proc Movie3dDialog {} { global movie global ed2 global current global cube set w {.movie3d} set ed2(ok) 0 set ed2(num) $movie(num) set ed2(az,from) $movie(az,from) set ed2(az,to) $movie(az,to) set ed2(el,from) $movie(el,from) set ed2(el,to) $movie(el,to) set ed2(sl,from) [$current(frame) get fits slice $cube(axis)] set ed2(sl,to) $ed2(sl,from) set ed2(repeat) $movie(repeat) set ed2(repeat,num) $movie(repeat,num) DialogCreate $w [msgcat::mc {Save 3D Movie}] ed2(ok) # Param set f [ttk::frame $w.param] ttk::label $f.tnum -text [msgcat::mc {Number}] ttk::entry $f.num -textvariable ed2(num) -width 7 ttk::label $f.tframes -text [msgcat::mc {Frames}] ttk::label $f.taz -text [msgcat::mc {Azimuth}] ttk::label $f.tazfrom -text [msgcat::mc {From}] ttk::entry $f.azfrom -textvariable ed2(az,from) -width 7 ttk::label $f.tazto -text [msgcat::mc {To}] ttk::entry $f.azto -textvariable ed2(az,to) -width 7 ttk::label $f.tel -text [msgcat::mc {Elevation}] ttk::label $f.telfrom -text [msgcat::mc {From}] ttk::entry $f.elfrom -textvariable ed2(el,from) -width 7 ttk::label $f.telto -text [msgcat::mc {To}] ttk::entry $f.elto -textvariable ed2(el,to) -width 7 ttk::label $f.tsl -text [msgcat::mc {Slice}] ttk::label $f.tslfrom -text [msgcat::mc {From}] ttk::entry $f.slfrom -textvariable ed2(sl,from) -width 7 ttk::label $f.tslto -text [msgcat::mc {To}] ttk::entry $f.slto -textvariable ed2(sl,to) -width 7 ttk::radiobutton $f.repeat -text [msgcat::mc {Repeat}] \ -variable ed2(repeat) -value repeat ttk::radiobutton $f.oscillate -text [msgcat::mc {Oscillate}] \ -variable ed2(repeat) -value oscillate ttk::entry $f.repeatnum -textvariable ed2(repeat,num) -width 7 ttk::label $f.ttimes -text [msgcat::mc {Times}] grid $f.tnum x $f.num $f.tframes -padx 2 -pady 2 -sticky w grid $f.taz $f.tazfrom $f.azfrom $f.tazto $f.azto -padx 2 -pady 2 -sticky w grid $f.tel $f.telfrom $f.elfrom $f.telto $f.elto -padx 2 -pady 2 -sticky w grid $f.tsl $f.tslfrom $f.slfrom $f.tslto $f.slto -padx 2 -pady 2 -sticky w grid $f.oscillate x $f.repeatnum $f.ttimes -padx 2 -pady 2 -sticky w grid $f.repeat -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set movie(num) $ed2(num) set movie(az,from) $ed2(az,from) set movie(az,to) $ed2(az,to) set movie(el,from) $ed2(el,from) set movie(el,to) $ed2(el,to) set movie(sl,from) $ed2(sl,from) set movie(sl,to) $ed2(sl,to) set movie(repeat) $ed2(repeat) set movie(repeat,num) $ed2(repeat,num) } set rr $ed2(ok) unset ed2 return $rr } proc MovieStatusDialog {} { global imovie global movie # see if we already have a window visible if [winfo exists $imovie(top)] { raise $imovie(top) return } # create the 3d window set w $imovie(top) set mb $imovie(mb) Toplevel $w $mb 6 [msgcat::mc {Movie}] MovieStatusDestroyDialog raise $imovie(top) # Status set f [ttk::frame $w.param] ttk::label $f.tstatus -text [msgcat::mc {Status}] ttk::progressbar $f.status -variable movie(status) -length 350 grid $f.tstatus $f.status -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.abort -text [msgcat::mc {Abort}] \ -command MovieStatusAbortDialog pack $f.abort -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill x } proc MovieStatusDestroyDialog {} { global movie global imovie if {[winfo exists $imovie(top)]} { destroy $imovie(top) destroy $imovie(mb) } } proc MovieStatusAbortDialog {} { global movie set movie(abort) 1 } # Process Cmds proc ProcessMovieCmd {varname iname} { upvar $varname var upvar $iname i global movie # we need to be realized # already implemented # ProcessRealizeDS9 set item [string tolower [lindex $var $i]] switch -- $item { slice - frame - 3d { set movie(action) $item incr i } default { # backward compatibility set movie(action) frame } } set fn [lindex $var $i] set go 1 while {$go} { incr i set item [string tolower [lindex $var $i]] switch -- $item { number { incr i set movie(num) [lindex $var $i] } azfrom { incr i set movie(az,from) [lindex $var $i] } azto { incr i set movie(az,to) [lindex $var $i] } elfrom { incr i set movie(el,from) [lindex $var $i] } elto { incr i set movie(el,to) [lindex $var $i] } slfrom { incr i set movie(sl,from) [lindex $var $i] } slto { incr i set movie(sl,to) [lindex $var $i] } oscillate { incr i set movie(repeat) oscillate set movie(repeat,num) [lindex $var $i] } repeat { incr i set movie(repeat) repeat set movie(repeat,num) [lindex $var $i] } default { incr i -1 set go 0 } } } Movie $fn } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/open.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000005336�12124134150�013337� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc Open {fn format layer mode sys} { if {$fn == {}} { return } StartLoad switch -- $format { fits {LoadFitsFile $fn $layer $mode} mosaicimagewcs {LoadMosaicImageWCSFile $fn $layer $sys} mosaicimageiraf {LoadMosaicImageIRAFFile $fn $layer} mosaicimagewfpc2 {LoadMosaicImageWFPC2File $fn} mosaicwcs {LoadMosaicWCSFile $fn $layer $sys} mosaiciraf {LoadMosaicIRAFFile $fn $layer} mecube {LoadMECubeFile $fn} multiframe {LoadMultiFrameFile $fn} rgbimage {LoadRGBImageFile $fn} rgbcube {LoadRGBCubeFile $fn} } FinishLoad } # Support proc OpenDialog {format {layer {}} {mode {}}} { global current global fitsfbox set fn [OpenFileDialog fitsfbox] # just in case (could be invoked via a menu keyshortcut) if {$current(frame) == {}} { CreateFrame } set sys wcs if {$fn != {}} { set ok 1 switch -- $format { mosaicimagewcs {set ok [MosaicWCSDialog sys]} mosaicwcs {set ok [MosaicWCSDialog sys]} } if {$ok} { switch -- $layer { mask {set ok [MaskLoad]} } } if {$ok} { Open $fn $format $layer $mode $sys } } } proc MosaicWCSDialog {varname} { upvar $varname var global ed set w {.wcs} set ed(ok) 0 set ed(sys) wcs set ed(label) WCS DialogCreate $w [msgcat::mc {Load Mosaic}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.title -text [msgcat::mc {Select Coordinate System }] ttk::menubutton $f.sys -textvariable ed(label) \ -menu $f.sys.m -width 10 menu $f.sys.m $f.sys.m add radiobutton -label [msgcat::mc {WCS}] \ -variable ed(sys) -value "wcs" -command [list set ed(label) WCS] $f.sys.m add separator foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $f.sys.m add radiobutton -variable ed(sys) \ -label "[msgcat::mc {WCS}] $l" \ -value "wcs$l" \ -command [list set ed(label) "[msgcat::mc {WCS}] $l"] } grid $f.title $f.sys # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set var $ed(sys) } set rr $ed(ok) unset ed return $rr } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/composite.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000006162�11700665566�014421� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CompositeDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set var(global) [$var(frame) get marker $var(id) composite global] # procs set var(proc,apply) CompositeApply set var(proc,close) CompositeClose set var(proc,coordCB) CompositeCoordCB # base MarkerBaseCenterDialog $varname # init MarkerBaseCenterRotateCB $varname # callbacks $var(frame) marker $var(id) callback rotate CompositeRotateCB $varname set f $var(top).param # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] ttk::label $f.tcomp -text [msgcat::mc {Angle Complement}] ttk::label $f.comp -textvariable ${varname}(comp) -width 13 -anchor w ttk::label $f.ucomp -text [msgcat::mc {Degrees}] # Global ttk::label $f.tglobal -text [msgcat::mc {Global Properties}] ttk::checkbutton $f.global -variable ${varname}(global) \ -command "CompositeGlobal $varname" grid $f.tangle $f.angle x $f.uangle -padx 2 -pady 2 -sticky w grid $f.tcomp $f.comp x $f.ucomp -padx 2 -pady 2 -sticky w grid $f.tglobal $f.global -padx 2 -pady 2 -sticky w CompositeCompAngle $varname } # actions proc CompositeClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback rotate CompositeRotateCB MarkerBaseCenterClose $varname } proc CompositeApply {varname} { upvar #0 $varname var global $varname CompositeRotate $varname MarkerBaseCenterApply $varname } proc CompositeRotate {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) angle $var(angle) $var(system) $var(sky) CompositeCompAngle $varname } proc CompositeCompAngle {varname} { upvar #0 $varname var global $varname set comp [expr 360-$var(angle)] if {[::math::fuzzy::tge $comp 360]} { set comp [expr $comp - 360] } if {[::math::fuzzy::tlt $comp 0]} { set comp [expr $comp + 360] } set var(comp) $comp } proc CompositeGlobal {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) composite global $var(global) } # callbacks proc CompositeCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "CompositeCoordCB" } MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } proc CompositeRotateCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "CompositeRotateCB" } set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] CompositeCompAngle $varname } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/url.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000011445�12131577017�013211� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc OpenURLFits {{layer {}} {mode {}}} { global fitsurl set url $fitsurl if {[EntryDialog [msgcat::mc {URL}] [msgcat::mc {Enter URL}] 80 url]} { StartLoad LoadURLFits $url $layer $mode FinishLoad set fitsurl $url } } proc LoadURLFits {url layer mode} { if {[string length $url] == 0} { return } ParseURL $url r switch -- $r(scheme) { ftp {LoadURLFitsFTP $r(authority) $r(path) $layer $mode} file {LoadURLFitsFile $r(path) $layer $mode} http - default {LoadURLFitsHTTP $url $layer $mode} } } proc LoadURLFitsFTP {host path layer mode} { global loadParam global ds9 global debug set ftp [ftp::Open $host "ftp" "-ds9@" -mode passive] if {$ftp > -1} { set fn "$ds9(tmpdir)/[file tail $path]" set ftp::VERBOSE $debug(tcl,ftp) set "ftp::ftp${ftp}(Output)" FTPLog ftp::Type $ftp binary if [ftp::Get $ftp $path $fn] { LoadURLFitsFile $fn $layer $mode } ftp::Close $ftp if [file exists $fn] { catch {file delete -force $fn} } } } proc LoadURLFitsFile {fn layer mode} { global loadParam # alloc it because we can't assume it will last set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $loadParam(file,name) set loadParam(load,layer) $layer ProcessLoad } proc LoadURLFitsHTTP {url layer mode} { global ds9 global ihttp ParseURL $url r set fn "$ds9(tmpdir)/[file tail $r(path)]" set code 200 set meta {} set mime "application/fits" set encoding {} set ch [open $fn w] set token [http::geturl $url \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -channel $ch \ -binary 1 \ -headers "[ProxyHTTP]"] # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} catch {close $ch} upvar #0 $token t # Code set code [http::ncode $token] # Meta set meta $t(meta) # Mime-type # we want to strip and extra info after ';' regexp -nocase {([^;])*} $t(type) mime # Content-Encoding foreach {name value} $meta { if {[regexp -nocase ^content-encoding $name]} { switch -- [string tolower $value] { gzip - x-gzip {set encoding gzip} compress - bzip2 {set encoding bzip2} Z {set encoding compress} pack - z {set encoding pack} default {} } } } HTTPLog $token # Result? switch -- $code { 200 {} default { Error "HTTP [msgcat::mc {Error}] $code" return } } http::cleanup $token global debug if {$debug(tcl,hv)} { puts stderr "Load HTTP: fn $fn : code $code : meta $meta : mime $mime : encoding $encoding" } # NOTE: error notices may come as text/html switch -- [string tolower $mime] { "text/plain" {} "image/fits" - "application/fits" {} "application/fits-image" - "application/fits-table" - "application/fits-group" {} "image/x-fits" - "binary/x-fits" - "application/x-fits" {} "image/x-gfits" - "binary/x-gfits" - "image/gz-fits" - "display/gz-fits" {set encoding gzip} "image/bz2-fits" - "display/bz2-fits" {set encoding bzip2} "image/x-cfits" - "binary/x-cfits" {set encoding compress} "image/x-zfits" - "binary/x-zfits" {set encoding pack} default { Error "[msgcat::mc {File not Found or Unable to load FITS data MIME type}] $mime" return } } # alloc it because we are going to delete it after load StartLoad global loadParam set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $loadParam(file,name) set loadParam(load,layer) $layer # may have to convert the file, based on content-encoding switch -- "$encoding" { bzip2 { catch {set ch [open "| bunzip2 < $fn " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } compress { catch {set ch [open "| uncompress < $fn " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } pack { catch {set ch [open "| pcat $fn " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } } ProcessLoad FinishLoad if {[file exists $fn]} { catch {file delete -force $fn} } } proc ProcessURLFitsCmd {varname iname} { upvar $varname var upvar $iname i set layer {} set mode {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i set mode slice } } LoadURLFits [lindex $var $i] $layer $mode } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/panzoom.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000045574�12117712633�014103� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PanZoomDef {} { global panzoom global ipanzoom global ppanzoom global tcl_platform set ipanzoom(top) .pz set ipanzoom(mb) .pzmb set ipanzoom(speed) 512 set ipanzoom(x) 0 set ipanzoom(last) {0 0} set ipanzoom(state) 1 set panzoom(preserve) 0 set panzoom(lock) none # set via wcs() set panzoom(system) wcs set panzoom(sky) fk5 set panzoom(skyformat) degrees set ppanzoom(preserve) $panzoom(preserve) # prefs only set ppanzoom(mode) click set ppanzoom(wheel) 1 set ppanzoom(wheel,factor) 1.2 # special case switch -- $tcl_platform(os) { Darwin { switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 11 {set ppanzoom(wheel,factor) 1.01} } } } } # Pan proc CenterCurrentFrame {} { global current CenterFrame $current(frame) } proc CenterAllFrame {} { global ds9 foreach f $ds9(frames) { CenterFrame $f } } proc CenterFrame {which} { if {$which != {}} { $which center UpdatePan $which UpdateZoomMenu } } proc Pan {x y sys {sky {}}} { global current if {$current(frame) != {}} { switch -- $sys { canvas {$current(frame) pan $x $y} default {$current(frame) pan $sys $sky $x $y} } UpdatePan $current(frame) } } proc PanTo {x y sys sky} { global current PanToFrame $current(frame) $x $y $sys $sky } proc PanToFrame {which x y sys sky} { global current if {$which != {}} { $which pan to $sys $sky $x $y UpdatePan $which } } proc ButtonPan {which x y} { global ppanzoom switch -- $ppanzoom(mode) { click {} drag {$which pan motion begin $x $y} panzoom {} } } proc MotionPan {which x y} { global ppanzoom switch -- $ppanzoom(mode) { click {} drag {$which pan motion $x $y} panzoom {} } } proc ReleasePan {which x y} { global panzoom global ipanzoom global ppanzoom global current switch -- $ppanzoom(mode) { click {$which pan to $x $y} drag {$which pan motion end $x $y} panzoom { if {$ipanzoom(last) != "$x $y"} { set ipanzoom(state) 1 } switch -- $ipanzoom(state) { 1 { $which pan to $x $y $which update set cc [$which get cursor canvas] set xx [expr int([lindex $cc 0])] set yy [expr int([lindex $cc 1])] $which warp to $xx $yy set ipanzoom(last) "$xx $yy" set z [$current(frame) get zoom] if {$z < 2} { set ipanzoom(state) 2 } elseif {$z < 4} { set ipanzoom(state) 3 } elseif {$z < 8} { set ipanzoom(state) 4 } else { set ipanzoom(state) 5 } } 2 { $which zoom to 2 2 about $x $y set ipanzoom(state) 3 } 3 { $which zoom to 4 4 about $x $y set ipanzoom(state) 4 } 4 { $which zoom to 8 8 about $x $y set ipanzoom(state) 5 } 5 { $which zoom to 1 1 about $x $y set ipanzoom(state) 2 } } if {$which == $current(frame)} { set current(zoom) [$current(frame) get zoom] } } } UpdatePan $which } proc PreservePan {} { global current global panzoom if {$current(frame) != {}} { $current(frame) pan preserve $panzoom(preserve) } } proc UpdatePan {which} { LockFrame $which UpdateGraphXAxis $which UpdatePanZoomDialog SAMPSendCoordPointAtSkyCmd $which } # Zoom proc ZoomToFit {} { global current global grid if {$current(frame) != {}} { # we need to update the grid because titles are zoom dependant if {$grid(view) && $grid(type) == "publication"} { # recalculate to make room for labels $current(frame) zoom to fit .8 set current(zoom) [$current(frame) get zoom] } else { $current(frame) zoom to fit set current(zoom) [$current(frame) get zoom] } UpdateZoom $current(frame) } } proc ChangeZoom {} { global current if {$current(frame) != {}} { $current(frame) zoom to $current(zoom) UpdateZoom $current(frame) } } proc Zoom {zx zy} { global current if {$current(frame) != {}} { ZoomFrame $current(frame) $zx $zy } } proc ZoomFrame {which zx zy} { global current $which zoom $zx $zy if {$which == $current(frame)} { set current(zoom) [$current(frame) get zoom] } UpdateZoom $which } proc ButtonZoom {which x y} { global current $which zoom 2 2 about $x $y if {$current(frame) == $which} { set current(zoom) [$current(frame) get zoom] } UpdateZoom $which } proc ShiftZoom {which} { global current $which zoom .5 .5 if {$current(frame) == $which} { set current(zoom) [$current(frame) get zoom] } UpdateZoom $which } proc UpdateZoom {which} { LockFrame $which UpdateGraphXAxis $which UpdatePanZoomDialog GridUpdateZoom RefreshInfoBox $which } # Orient proc ChangeOrient {} { global current if {$current(frame) != {}} { $current(frame) orient $current(orient) UpdateRotate $current(frame) } } # Rotate proc Rotate {value} { global current if {$current(frame) != {}} { $current(frame) rotate $value set current(rotate) [$current(frame) get rotate] UpdateRotate $current(frame) } } proc ChangeRotate {} { global current if {$current(frame) != {}} { $current(frame) rotate to $current(rotate) UpdateRotate $current(frame) } } proc ButtonRotate {which x y} { global ipanzoom $which rotate motion begin set ipanzoom(x) $x } proc MotionRotate {which x y} { global current global ipanzoom global icursor $which rotate motion [expr double($ipanzoom(x)-$x)/$ipanzoom(speed) * 180.] if {$current(frame) == $which} { set current(rotate) [$which get rotate fixed] } RefreshInfoBox $which } proc ReleaseRotate {which x y} { global current $which rotate motion end if {$current(frame) == $which} { set current(rotate) [$which get rotate fixed] } UpdateRotate $which } proc UpdateRotate {which} { LockFrame $which UpdateGraphXAxis $which UpdatePanZoomDialog RefreshInfoBox $which } proc PanZoomDialog {} { global panzoom global ipanzoom global dpanzoom global ds9 global current # see if we already have a window visible if [winfo exists $ipanzoom(top)] { raise $ipanzoom(top) return } # create the window set w $ipanzoom(top) set mb $ipanzoom(mb) Toplevel $w $mb 6 [msgcat::mc {Pan Zoom Rotate Parameters}] \ PanZoomDestroyDialog # for CoordMenuButton set panzoom(frame) $current(frame) $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Pan}] -menu $mb.pan $mb add cascade -label [msgcat::mc {Zoom}] -menu $mb.zoom $mb add cascade -label [msgcat::mc {Orientation}] -menu $mb.orient $mb add cascade -label [msgcat::mc {Rotate}] -menu $mb.rotate menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command PanZoomApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command PanZoomDestroyDialog EditMenu $mb ipanzoom menu $mb.pan $mb.pan add command -label [msgcat::mc {Center Image}] \ -command CenterCurrentFrame menu $mb.zoom $mb.zoom add checkbutton -label [msgcat::mc {Align}] \ -variable current(align) -command AlignWCSFrame $mb.zoom add separator $mb.zoom add command -label [msgcat::mc {Zoom In}] -command {Zoom 2 2} $mb.zoom add command -label [msgcat::mc {Zoom Out}] -command {Zoom .5 .5} $mb.zoom add separator $mb.zoom add command -label [msgcat::mc {Zoom to Fit Frame}] \ -command ZoomToFit $mb.zoom add separator $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/32" \ -variable current(zoom) -value { 0.03125 0.03125 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/16" \ -variable current(zoom) -value { 0.0625 0.0625 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/8" \ -variable current(zoom) -value { 0.125 0.125 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/4" \ -variable current(zoom) -value { 0.25 0.25 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/2" \ -variable current(zoom) -value { 0.5 0.5 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 1" \ -variable current(zoom) -value { 1 1 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 2" \ -variable current(zoom) -value { 2 2 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 4" \ -variable current(zoom) -value { 4 4 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 8" \ -variable current(zoom) -value { 8 8 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 16" \ -variable current(zoom) -value { 16 16 } -command ChangeZoom $mb.zoom add radiobutton -label "[msgcat::mc {Zoom}] 32" \ -variable current(zoom) -value { 32 32 } -command ChangeZoom menu $mb.orient $mb.orient add radiobutton -label [msgcat::mc {None}] \ -variable current(orient) -value none -command ChangeOrient $mb.orient add radiobutton -label "[msgcat::mc {Invert}] X" \ -variable current(orient) -value x -command ChangeOrient $mb.orient add radiobutton -label "[msgcat::mc {Invert}] Y" \ -variable current(orient) -value y -command ChangeOrient $mb.orient add radiobutton -label "[msgcat::mc {Invert}] XY" \ -variable current(orient) -value xy -command ChangeOrient menu $mb.rotate $mb.rotate add radiobutton -label "0 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 0 -command ChangeRotate $mb.rotate add radiobutton -label "90 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 90 -command ChangeRotate $mb.rotate add radiobutton -label "180 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 180 -command ChangeRotate $mb.rotate add radiobutton -label "270 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 270 -command ChangeRotate # Param set f [ttk::frame $w.param] ttk::label $f.zoomtitle -text [msgcat::mc {Zoom}] ttk::entry $f.zoomx -textvariable dpanzoom(zoom,x) -width 14 ttk::entry $f.zoomy -textvariable dpanzoom(zoom,y) -width 14 ttk::label $f.rottitle -text [msgcat::mc {Rotate}] ttk::entry $f.rotvalue -textvariable dpanzoom(rotate) -width 14 ttk::label $f.rottitle2 -text [msgcat::mc {Degrees}] ttk::label $f.pantitle -text [msgcat::mc {Pan}] ttk::entry $f.panx -textvariable dpanzoom(x) -width 14 ttk::entry $f.pany -textvariable dpanzoom(y) -width 14 set dpanzoom(cb) $f.pansystem CoordMenuButton $dpanzoom(cb) panzoom system 1 sky skyformat \ UpdatePanZoomDialog grid $f.zoomtitle $f.zoomx $f.zoomy -padx 2 -pady 2 grid $f.rottitle $f.rotvalue $f.rottitle2 -padx 2 -pady 2 -sticky w grid $f.pantitle $f.panx $f.pany $f.pansystem -padx 2 -pady 2 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command PanZoomApplyDialog ttk::button $f.close -text [msgcat::mc {Close}] \ -command PanZoomDestroyDialog pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true $w.param.zoomx select range 0 end UpdatePanZoomDialog } proc PanZoomApplyDialog {} { global panzoom global ipanzoom global dpanzoom global current if {$current(frame) != {}} { set current(zoom) "$dpanzoom(zoom,x) $dpanzoom(zoom,y)" set current(rotate) $dpanzoom(rotate) $current(frame) zoom to $current(zoom) about \ $panzoom(system) $panzoom(sky) $dpanzoom(x) $dpanzoom(y) $current(frame) rotate to $current(rotate) LockFrameCurrent UpdateGraphXAxis $current(frame) UpdatePanZoomDialog GridUpdateZoom RefreshInfoBox $current(frame) UpdateZoomMenu SAMPSendCoordPointAtSkyCmd $current(frame) } } proc PanZoomDestroyDialog {} { global ipanzoom global dpanzoom if {[winfo exists $ipanzoom(top)]} { destroy $ipanzoom(top) destroy $ipanzoom(mb) } unset dpanzoom } proc UpdatePanZoomMenu {} { # can be changed by wcs SetCoordSystem panzoom system sky skyformat } proc UpdatePanZoomDialog {} { global panzoom global ipanzoom global dpanzoom global current global debug if {$debug(tcl,update)} { puts stderr "UpdatePanZoomDialog" } if {![winfo exists $ipanzoom(top)]} { return } if {$current(frame) != {}} { set panzoom(frame) $current(frame) if {[$current(frame) has fits]} { # now make sure we have the coord systems AdjustCoordSystem panzoom system CoordMenuEnable $dpanzoom(cb).menu panzoom system 1 sky skyformat CoordMenuButtonCmd panzoom system sky {} } else { CoordMenuReset $dpanzoom(cb).menu panzoom system 1 sky skyformat } } if {$current(frame) != {}} { set zz [$current(frame) get zoom] set dpanzoom(zoom,x) [lindex $zz 0] set dpanzoom(zoom,y) [lindex $zz 1] set dpanzoom(rotate) [$current(frame) get rotate] set coord [$current(frame) get cursor $panzoom(system) \ $panzoom(sky) $panzoom(skyformat)] set dpanzoom(x) [lindex $coord 0] set dpanzoom(y) [lindex $coord 1] } else { set dpanzoom(zoom,x) {} set dpanzoom(zoom,y) {} set dpanzoom(rotate) {} set dpanzoom(x) {} set dpanzoom(y) {} } } # Other proc AlignWCSFrame {} { global current global ds9 if {$current(frame) != {}} { $current(frame) wcs align $current(align) LockFrameCurrent UpdateGraphXAxis $current(frame) UpdatePanZoomDialog } } proc MatchFrameCurrent {sys} { global current if {$current(frame) != {}} { MatchFrame $current(frame) $sys } } proc MatchFrame {which sys} { global ds9 global current # NO-make sure matrices have been updated # really messes up mousewheel events, just assume all is good # RealizeDS9 switch -- $sys { image - physical - amplifier - detector { set current(align) 0 $which wcs align 0 set pan [$which get cursor $sys scientific] set zoom [$which get zoom] set rotate [$which get rotate] set orient [$which get orient] foreach ff $ds9(frames) { if {$ff != $which} { $ff pan to $sys $pan $ff zoom to $zoom $ff rotate to $rotate $ff orient $orient $ff wcs align 0 } } } wcs { set www [$which get wcs] set sys [lindex $www 0] set sky [lindex $www 1] if {[$which has wcs $sys]} { set current(align) 1 $which wcs align 1 set align [$which get wcs align pointer] set pan [$which get cursor $sys FK5 scientific] set zoom [$which get zoom] set rotate [$which get rotate] set orient [$which get orient] foreach ff $ds9(frames) { if {$ff != $which} { if {[$ff has wcs $sys]} { $ff pan to $sys FK5 $pan $ff zoom to $zoom $ff rotate to $rotate $ff orient $orient $ff wcs align $align } } } } } } } proc LockFrameCurrent {} { global current if {$current(frame) != {}} { LockFrame $current(frame) } } proc LockFrame {which} { global panzoom switch -- $panzoom(lock) { none {} default {MatchFrame $which $panzoom(lock)} } } # Backup proc PanZoomBackup {ch which} { puts $ch "$which pan preserve [$which get pan preserve]" puts $ch "$which pan to physical [$which get cursor physical]" # this must come after pan to puts $ch "$which 3d view point [$which get 3d view point]" puts $ch "$which zoom to [$which get zoom]" puts $ch "$which rotate to [$which get rotate]" puts $ch "$which orient [$which get orient]" puts $ch "$which wcs align [$which get wcs align]" } # Process Cmds proc ProcessPanCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { open {PanZoomDialog} close {PanZoomDestroyDialog} to { set x [lindex $var [expr $i+1]] set y [lindex $var [expr $i+2]] set sys [lindex $var [expr $i+3]] set sky [lindex $var [expr $i+4]] set format {} incr i 2 incr i [FixSpec sys sky format physical fk5 degrees] PanTo $x $y $sys $sky } default { set x [lindex $var [expr $i+0]] set y [lindex $var [expr $i+1]] set sys [lindex $var [expr $i+2]] set sky [lindex $var [expr $i+3]] set format {} incr i 1 incr i [FixSpec sys sky format physical fk5 degrees] Pan $x $y $sys $sky } } } proc ProcessSendPanCmd {proc id param} { global current set sys [lindex $param 0] set sky [lindex $param 1] set format [lindex $param 2] FixSpec sys sky format physical fk5 degrees if {$current(frame) != {}} { $proc $id "[$current(frame) get cursor $sys $sky $format]\n" } } proc ProcessZoomCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 global current switch -- [string tolower [lindex $var $i]] { open {PanZoomDialog} close {PanZoomDestroyDialog} to { switch -- [string tolower [lindex $var [expr $i+1]]] { fit { ZoomToFit incr i } default { set z1 [lindex $var [expr $i+1]] set z2 [lindex $var [expr $i+2]] if {[string is double $z2] && $z2 != {}} { set current(zoom) " $z1 $z2 " incr i 2 } else { set current(zoom) " $z1 $z1 " incr i } ChangeZoom } } } default { set z1 [lindex $var $i] set z2 [lindex $var [expr $i+1]] if {[string is double $z2] && $z2 != {}} { Zoom $z1 $z2 incr i } else { Zoom $z1 $z1 } } } } proc ProcessSendZoomCmd {proc id param} { global current set z1 [lindex $current(zoom) 0] set z2 [lindex $current(zoom) 1] if {$z1 != $z2} { $proc $id "$current(zoom)\n" } else { $proc $id "$z1\n" } } proc ProcessOrientCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 global current switch -- [string tolower [lindex $var $i]] { open {PanZoomDialog} close {PanZoomDestroyDialog} default { set current(orient) [string tolower [lindex $var $i]] ChangeOrient } } } proc ProcessSendOrientCmd {proc id param} { global current $proc $id "$current(orient)\n" } proc ProcessRotateCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 global current switch -- [string tolower [lindex $var $i]] { open {PanZoomDialog} close {PanZoomDestroyDialog} to { set current(rotate) [lindex $var [expr $i+1]] ChangeRotate incr i } default {Rotate [lindex $var $i]} } } proc ProcessSendRotateCmd {proc id param} { global current $proc $id "$current(rotate)\n" } ������������������������������������������������������������������������������������������������������������������������������������./saods9/src/smosaiciraf.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000002374�12125367635�014716� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadSMosaicIRAFFile {hdr fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic iraf} set loadParam(load,type) smmap set loadParam(file,name) $fn set loadParam(file,header) $hdr set loadParam(load,layer) $layer ProcessLoad } proc ProcessSMosaicIRAFCmd {varname iname sock fn layer} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } set opt [lindex $var $i] if {$opt != {}} { incr i } else { set opt wcs } StartLoad if {$sock != {}} { # xpa if {0} { # not supported } else { LoadSMosaicIRAFFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $opt } } else { # comm if {0} { # not supported } else { LoadSMosaicIRAFFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $opt } } FinishLoad } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotscatter.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000016354�12132042644�014751� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotScatterTool {} { global iap PlotScatter $iap(tt) [msgcat::mc {Scatter Plot Tool}] {} {} {} 2 {} } proc PlotScatter {tt wtt title xaxis yaxis dim data} { global iap # make the window name unique set ii [lsearch $iap(windows) $tt] if {$ii>=0} { append tt $iap(unique) incr iap(unique) } # set the window title if none if {$wtt == {}} { set wtt $tt } set varname $tt upvar #0 $varname var global $varname PlotScatterProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogScatter $varname PlotDataSet $varname $dim $data $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc PlotScatterDialog {varname wtt title xaxis yaxis} { upvar #0 $varname var global $varname PlotScatterProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogScatter $varname } proc PlotScatterProc {varname} { upvar #0 $varname var global $varname set var(proc,updategraph) PlotScatterUpdateGraph set var(proc,createelement) PlotScatterCreateElement set var(proc,updateelement) PlotScatterUpdateElement set var(proc,highlite) PlotScatterHighliteElement set var(proc,button) PlotScatterButton } proc PlotDialogScatter {varname} { upvar #0 $varname var global $varname global pap set var(seq) 0 set var(discrete) 1 set var(linear) 0 set var(step) 0 set var(quadratic) 0 set var(error) $pap(error) set var(bar) 0 # element $var(mb).element add cascade -label [msgcat::mc {Discrete}] \ -menu $var(mb).element.discrete $var(mb).element add cascade -label [msgcat::mc {Error}] \ -menu $var(mb).element.error # discrete menu $var(mb).element.discrete $var(mb).element.discrete add checkbutton -label [msgcat::mc {Show}] \ -variable ${varname}(discrete) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.discrete add separator $var(mb).element.discrete add cascade -label [msgcat::mc {Color}] \ -menu $var(mb).element.discrete.color $var(mb).element.discrete add cascade -label [msgcat::mc {Shape}] \ -menu $var(mb).element.discrete.shape ColorMenu $var(mb).element.discrete.color $varname discrete,color \ [list PlotUpdateElementDiscrete $varname] menu $var(mb).element.discrete.shape $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Circle}] \ -variable ${varname}(discrete,symbol) -value circle \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Diamond}] \ -variable ${varname}(discrete,symbol) -value diamond \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Plus}] \ -variable ${varname}(discrete,symbol) -value plus \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add radiobutton \ -label [msgcat::mc {Cross}] \ -variable ${varname}(discrete,symbol) -value cross \ -command [list PlotUpdateElementDiscrete $varname] $var(mb).element.discrete.shape add separator $var(mb).element.discrete.shape add checkbutton \ -label [msgcat::mc {Fill}] \ -variable ${varname}(discrete,fill) \ -command [list PlotUpdateElementDiscrete $varname] # error menu $var(mb).element.error $var(mb).element.error add checkbutton \ -label [msgcat::mc {Show}] \ -variable ${varname}(error) \ -command [list $var(proc,updateelement) $varname] $var(mb).element.error add separator $var(mb).element.error add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.error.color $var(mb).element.error add cascade \ -label [msgcat::mc {Line}] \ -menu $var(mb).element.error.line ColorMenu $var(mb).element.error.color $varname error,color \ [list PlotUpdateElementError $varname] WidthDashMenu $var(mb).element.error.line $varname error,width {} \ [list PlotUpdateElementError $varname] {} # graph set var(graph) [blt::graph $var(top).scatter \ -width 600 -height 500 \ -plotrelief groove \ -plotborderwidth 2 \ ] $var(graph) legend configure -hide yes pack $var(graph) -expand yes -fill both PlotChangeMode $varname } proc PlotScatterUpdateGraph {varname} { upvar #0 $varname var global $varname if {$var(graph,x,auto)} { set xmin {} set xmax {} } else { set xmin $var(graph,x,min) set xmax $var(graph,x,max) } if {$var(graph,y,auto)} { set ymin {} set ymax {} } else { set ymin $var(graph,y,min) set ymax $var(graph,y,max) } $var(graph) xaxis configure -min $xmin -max $xmax \ -descending $var(graph,x,flip) $var(graph) yaxis configure -min $ymin -max $ymax \ -descending $var(graph,y,flip) PlotUpdateGraph $varname } proc PlotScatterCreateElement {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } # delete current elements set nn $var(data,current) foreach el [$var(graph) element names] { set f [split $el -] if {[lindex $f 1] == $nn} { $var(graph) element delete $el } } if {$var(discrete,fill)} { set clr $var(discrete,color) } else { set clr {} } $var(graph) element create "d-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -linewidth 0 -pixels 5 \ -symbol $var(discrete,symbol) \ -fill $clr \ -outline $var(discrete,color) \ -color $var(discrete,color) # error if {$var(xedata) != {}} { if {[$var(xedata) length] != 0} { PlotCreateErrorX $varname } } if {$var(yedata) != {}} { if {[$var(yedata) length] != 0} { PlotCreateErrorY $varname } } # do this to force an update in case of no visible elements $var(graph) legend configure -hide yes } proc PlotScatterUpdateElement {varname} { upvar #0 $varname var global $varname set nn $var(data,current) set var($nn,discrete) $var(discrete) set var($nn,error) $var(error) $var(graph) element configure "d-${nn}" -hide [expr !$var(discrete)] foreach mk [$var(graph) marker names "m-${nn}*"] { $var(graph) marker configure $mk -hide [expr !$var(error)] } } proc PlotScatterButton {varname x y} { upvar #0 $varname var global $varname if {$var(data,total) == 0} { return } if {$var(callback) == {}} { return } # warning: uses d-1 set rr [$var(graph) element closest $x $y] set el [lindex $rr 1] set row [lindex $rr 3] if {$row != {}} { if {$el == {d-1}} { $var(graph) element deactivate d-1 $var(graph) element activate d-1 $row # rows start at 1 eval "$var(callback) [expr $row+1]" } } else { $var(graph) element deactivate d-1 eval "$var(callback) {}" } } proc PlotScatterHighliteElement {varname rowlist} { upvar #0 $varname var global $varname # warning: uses d-1 if {$var(data,total) == 0} { return } if {$var(discrete)} { $var(graph) element deactivate d-1 if {$rowlist != {}} { # can have multiple rows eval "$var(graph) element activate d-1 $rowlist" } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/nrrd.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000005167�12130604640�013350� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ImportNRRDFile {fn layer} { global loadParam set loadParam(file,type) nrrd set loadParam(file,mode) {} set loadParam(load,layer) $layer # find stdin if {[string range $fn 0 4] == "stdin" || [string range $fn 0 4] == "STDIN" || [string range $fn 0 0] == "-"} { set loadParam(load,type) alloc set loadParam(file,name) stdin set loadParam(file,fn) $loadParam(file,name) } else { set loadParam(load,type) mmap set loadParam(file,name) $fn } ProcessLoad } proc ImportNRRDAlloc {path fn layer} { global loadParam set loadParam(file,type) nrrd set loadParam(file,mode) {} set loadParam(load,type) alloc set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc ImportNRRDSocket {sock fn layer} { global loadParam set loadParam(file,type) nrrd set loadParam(file,mode) {} set loadParam(load,type) socket set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc ExportNRRDFile {fn opt} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save nrrd file "\{$fn\}" $opt } proc ExportNRRDSocket {sock opt} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save nrrd socket $sock $opt } proc ProcessNRRDCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![ImportNRRDSocket $sock $param $layer]} { InitError xpa ImportNRRDFile $param $layer } } else { # comm if {$fn != {}} { ImportNRRDAlloc $fn $param $layer } else { ImportNRRDFile $param $layer } } FinishLoad } proc ProcessSendNRRDCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } set opt [string tolower [lindex $param 0]] if {$sock != {}} { # xpa ExportNRRDSocket $sock $opt } elseif {$fn != {}} { # comm ExportNRRDFile $fn $opt $proc $id {} $fn } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/ellipseannulus.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000001510�11732434434�015443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc EllipseAnnulusDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(which) ellipseannulus set var(proc,apply) MarkerBaseAnnulusRectApply set var(proc,close) MarkerBaseAnnulusRectClose set var(proc,generate) MarkerBaseAnnulusGenerateEllipse set var(proc,coordCB) MarkerBaseAnnulusRectCoordCB set var(proc,editCB) MarkerBaseAnnulusRectEditCB set var(proc,distCB) MarkerBaseAnnulusRectDistCB # base MarkerBaseAnnulusRectDialog $varname radius Major Minor } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/var.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000000773�12122671221�013171� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadVar {varname fn layer mode} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) var set loadParam(var,name) $varname set loadParam(file,name) "$fn" # mask not supported set loadParam(load,layer) {} ProcessLoad } �����./saods9/src/3d.tcl���������������������������������������������������������������������������������0000644�0001750�0001750�00000026530�12012240446�012705� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc 3DDef {} { global threed global ithreed global pthreed set ithreed(top) .threed set ithreed(mb) .threedmb set ithreed(status) 0 set threed(az) 0 set threed(el) 0 set threed(scale) 1 set threed(method) mip set threed(highlite) 1 set threed(highlite,color) cyan set threed(border) 1 set threed(border,color) blue set threed(compass) 0 set threed(compass,color) green array set pthreed [array get threed] unset pthreed(az) unset pthreed(el) } # used by backup proc 3DDialog {} { global threed global ithreed global ds9 # see if we already have a window visible if [winfo exists $ithreed(top)] { raise $ithreed(top) return } # create the 3d window set w $ithreed(top) set mb $ithreed(mb) Toplevel $w $mb 6 [msgcat::mc {3D}] 3DDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Method}] -menu $mb.method $mb add cascade -label [msgcat::mc {Highlite}] -menu $mb.highlite $mb add cascade -label [msgcat::mc {Border}] -menu $mb.border # $mb add cascade -label [msgcat::mc {Compass}] -menu $mb.compass menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command 3DApplyDialog $mb.file add command -label [msgcat::mc {Reset}] -command 3DResetDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command 3DDestroyDialog menu $mb.method $mb.method add radiobutton -label [msgcat::mc {MIP}] \ -variable threed(method) -value {mip} -command 3DRenderMethod $mb.method add radiobutton -label [msgcat::mc {AIP}] \ -variable threed(method) -value {aip} -command 3DRenderMethod menu $mb.highlite $mb.highlite add checkbutton -label [msgcat::mc {Show}] \ -variable threed(highlite) -command 3DHighlite $mb.highlite add separator $mb.highlite add cascade -label [msgcat::mc {Color}] \ -menu $mb.highlite.color ColorMenu $mb.highlite.color threed highlite,color 3DHighliteColor menu $mb.border $mb.border add checkbutton -label [msgcat::mc {Show}] \ -variable threed(border) -command 3DBorder $mb.border add separator $mb.border add cascade -label [msgcat::mc {Color}] \ -menu $mb.border.color ColorMenu $mb.border.color threed border,color 3DBorderColor menu $mb.compass $mb.compass add checkbutton -label [msgcat::mc {Show}] -variable threed(compass) -command 3DCompass $mb.compass add separator $mb.compass add cascade -label [msgcat::mc {Color}] -menu $mb.compass.color ColorMenu $mb.compass.color threed compass,color 3DCompassColor # Param set f [ttk::frame $w.param] slider $f.elslider -90. 90. [msgcat::mc {Elevation}] threed(el) \ [list 3DViewPoint] slider $f.azslider -180. 180. [msgcat::mc {Azimuth}] threed(az) \ [list 3DViewPoint] grid $f.azslider -padx 2 -pady 2 -sticky ew grid $f.elslider -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # for order of focus raise $f.elslider # Scale set f [ttk::frame $w.scale] ttk::label $f.tscale -text [msgcat::mc {Z Axis Scale}] ttk::entry $f.scale -textvariable threed(scale) -width 7 grid $f.tscale $f.scale -padx 2 -pady 2 -sticky ew # Status set f [ttk::frame $w.status] ttk::label $f.tstatus -text [msgcat::mc {Status}] ttk::progressbar $f.status -variable ithreed(status) -length 350 grid $f.tstatus $f.status -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command 3DApplyDialog ttk::button $f.reset -text [msgcat::mc {Reset}] -command 3DResetDialog ttk::button $f.close -text [msgcat::mc {Close}] -command 3DDestroyDialog pack $f.apply $f.reset $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal ttk::separator $w.sep2 -orient horizontal ttk::separator $w.sep3 -orient horizontal pack $w.buttons $w.sep $w.status $w.sep2 -side bottom -fill x pack $w.param $w.sep3 $w.scale -side top -fill x Update3DDialog } proc 3DDestroyDialog {} { global threed global ithreed if {[winfo exists $ithreed(top)]} { destroy $ithreed(top) destroy $ithreed(mb) } } proc 3DApplyDialog {} { global threed global current global grid if {$current(frame) != {}} { $current(frame) 3d view $threed(az) $threed(el) $current(frame) 3d scale $threed(scale) if {$grid(view)} { GridUpdate } } } proc 3DResetDialog {} { global threed set threed(az) 0 set threed(el) 0 3DViewPoint set threed(scale) 1 3DScale } proc Update3DDialog {} { global threed global ithreed global current global debug if {$debug(tcl,update)} { puts stderr "Update3DDialog" } set w $ithreed(top) if {[winfo exists $ithreed(top)] && $current(frame) != {}} { set rr [$current(frame) get 3d view] set threed(az) [lindex $rr 0] set threed(el) [lindex $rr 1] set threed(scale) [$current(frame) get 3d scale] set threed(method) [$current(frame) get 3d method] set threed(highlite) [$current(frame) get 3d highlite] set threed(highlite,color) [$current(frame) get 3d highlite color] set threed(border) [$current(frame) get 3d border] set threed(border,color) [$current(frame) get 3d border color] set threed(compass) [$current(frame) get 3d compass] set threed(compass,color) [$current(frame) get 3d compass color] } } proc 3DBackup {ch which} { puts $ch "$which 3d view [$which get 3d view]" puts $ch "$which 3d scale [$which get 3d scale]" puts $ch "$which 3d method [$which get 3d method]" puts $ch "$which 3d highlite [$which get 3d highlite]" puts $ch "$which 3d border [$which get 3d border]" puts $ch "$which 3d compass [$which get 3d compass]" } proc 3DViewPoint {} { global threed global current global grid if {$current(frame) != {}} { $current(frame) 3d view $threed(az) $threed(el) if {$grid(view)} { GridUpdate } } } proc 3DScale {} { global threed global current global grid if {$current(frame) != {}} { $current(frame) 3d scale $threed(scale) if {$grid(view)} { GridUpdate } } } proc 3DRenderMethod {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d method $threed(method) } } proc 3DHighlite {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d highlite $threed(highlite) } } proc 3DHighliteColor {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d highlite color $threed(highlite,color) } } proc 3DBorder {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d border $threed(border) } } proc 3DBorderColor {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d border color $threed(border,color) } } proc 3DCompass {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d compass $threed(compass) } } proc 3DCompassColor {} { global threed global current if {$current(frame) != {}} { $current(frame) 3d compass color $threed(compass,color) } } # Prefs proc PrefsDialog3d {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {3D}] lappend dprefs(tabs) [ttk::frame $w.threed] set f [ttk::labelframe $w.threed.misc -text [msgcat::mc {Method}]] ttk::menubutton $f.method -textvariable pthreed(method) -menu $f.method.menu grid $f.method -padx 2 -pady 2 -sticky w set m $f.method.menu menu $m $m add radiobutton -label [msgcat::mc {MIP}] \ -variable pthreed(method) -value {mip} $m add radiobutton -label [msgcat::mc {AIP}] \ -variable pthreed(method) -value {aip} set f [ttk::labelframe $w.threed.highlite -text [msgcat::mc {Highlite}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pthreed(highlite) ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color pthreed highlite,color {} grid $f.show -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w set f [ttk::labelframe $w.threed.border -text [msgcat::mc {Border}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pthreed(border) ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color pthreed border,color {} grid $f.show -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w # set f [ttk::labelframe $w.threed.compass -text [msgcat::mc {Compass}]] # ttk::checkbutton $f.show -text [msgcat::mc {Show}] -variable pthreed(compass) # ttk::label $f.tcolor -text [msgcat::mc {Color}] # ColorMenuButton $f.color pthreed compass,color {} grid $f.show -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w pack $w.threed.misc $w.threed.highlite $w.threed.border \ -side top -fill both -expand true } proc Process3DCmd {varname iname} { upvar $varname var upvar $iname i global threed 3DDialog switch -- [string tolower [lindex $var $i]] { open {} close {3DDestroyDialog} az { incr i set threed(az) [lindex $var $i] 3DViewPoint } el { incr i set threed(el) [lindex $var $i] 3DViewPoint } vp { incr i set threed(az) [lindex $var $i] incr i set threed(el) [lindex $var $i] 3DViewPoint } scale { incr i set threed(scale) [lindex $var $i] 3DScale } method { incr i set threed(method) [lindex $var $i] 3DRenderMethod } highlite { incr i switch [string tolower [lindex $var $i]] { color { incr i set threed(highlite,color) [lindex $var $i] 3DHighliteColor } default { set threed(highlite) [FromYesNo [lindex $var $i]] 3DHighlite } } } border { incr i switch [string tolower [lindex $var $i]] { color { incr i set threed(border,color) [lindex $var $i] 3DBorderColor } default { set threed(border) [FromYesNo [lindex $var $i]] 3DBorder } } } compass { incr i switch [string tolower [lindex $var $i]] { color { incr i set threed(compass,color) [lindex $var $i] 3DCompassColor } default { set threed(compass) [FromYesNo [lindex $var $i]] 3DCompass } } } default {Create3DFrame; incr i -1} } } proc ProcessSend3DCmd {proc id param} { global threed switch -- [string tolower [lindex $param 0]] { az {$proc $id "$threed(az)\n"} el {$proc $id "$threed(el)\n"} vp {$proc $id "$threed(az) $threed(el)\n"} scale {$proc $id "$threed(scale)\n"} method {$proc $id "$threed(method)\n"} highlite { switch [string tolower [lindex $param 1]] { color {$proc $id "$threed(highlite,color)\n"} default {$proc $id "$threed(highlite)\n"} } } border { switch [string tolower [lindex $param 1]] { color {$proc $id "$threed(border,color)\n"} default {$proc $id "$threed(border)\n"} } } compass { switch [string tolower [lindex $param 1]] { color {$proc $id "$threed(compass,color)\n"} default {$proc $id "$threed(compass)\n"} } } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mscale.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000042370�11723251046�013651� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menu proc ScaleMainMenu {} { global ds9 menu $ds9(mb).scale $ds9(mb).scale add radiobutton -label [msgcat::mc {Linear}] \ -variable scale(type) -command ChangeScale -value linear $ds9(mb).scale add radiobutton -label [msgcat::mc {Log}] \ -variable scale(type) -command ChangeScale -value log $ds9(mb).scale add radiobutton -label [msgcat::mc {Power}] \ -variable scale(type) -command ChangeScale -value pow $ds9(mb).scale add radiobutton -label [msgcat::mc {Square Root}] \ -variable scale(type) -command ChangeScale -value sqrt $ds9(mb).scale add radiobutton -label [msgcat::mc {Squared}] \ -variable scale(type) -command ChangeScale -value squared $ds9(mb).scale add radiobutton -label {ASINH} \ -variable scale(type) -command ChangeScale -value asinh $ds9(mb).scale add radiobutton -label {SINH} \ -variable scale(type) -command ChangeScale -value sinh $ds9(mb).scale add radiobutton \ -label [msgcat::mc {Histogram Equalization}] \ -variable scale(type) -command ChangeScale -value histequ $ds9(mb).scale add separator $ds9(mb).scale add command -label "[msgcat::mc {Log Exponent}]..." \ -command ScaleLogDialog $ds9(mb).scale add separator $ds9(mb).scale add radiobutton -label [msgcat::mc {Min Max}] \ -variable scale(mode) -command ChangeScaleMode -value minmax $ds9(mb).scale add radiobutton -label {99.5%} \ -variable scale(mode) -command ChangeScaleMode -value 99.5 $ds9(mb).scale add radiobutton -label {99%} \ -variable scale(mode) -command ChangeScaleMode -value 99 $ds9(mb).scale add radiobutton -label {98%} \ -variable scale(mode) -command ChangeScaleMode -value 98 $ds9(mb).scale add radiobutton -label {97%} \ -variable scale(mode) -command ChangeScaleMode -value 97 $ds9(mb).scale add radiobutton -label {96%} \ -variable scale(mode) -command ChangeScaleMode -value 96 $ds9(mb).scale add radiobutton -label {95%} \ -variable scale(mode) -command ChangeScaleMode -value 95 $ds9(mb).scale add radiobutton -label {92.5%} \ -variable scale(mode) -command ChangeScaleMode -value 92.5 $ds9(mb).scale add radiobutton -label {90%} \ -variable scale(mode) -command ChangeScaleMode -value 90 $ds9(mb).scale add radiobutton -label {ZScale} \ -variable scale(mode) -command ChangeScaleMode -value zscale $ds9(mb).scale add radiobutton -label {ZMax} \ -variable scale(mode) -command ChangeScaleMode -value zmax $ds9(mb).scale add radiobutton -label [msgcat::mc {User}] \ -variable scale(mode) -command ChangeScaleMode -value user $ds9(mb).scale add separator $ds9(mb).scale add cascade -label [msgcat::mc {Scope}] \ -menu $ds9(mb).scale.scope $ds9(mb).scale add cascade -label [msgcat::mc {Min Max}] \ -menu $ds9(mb).scale.minmax $ds9(mb).scale add command -label {ZScale...} -command ZScaleDialog $ds9(mb).scale add separator $ds9(mb).scale add checkbutton -label "[msgcat::mc {Use}] DATASEC" \ -variable scale(datasec) -command ChangeDATASEC $ds9(mb).scale add separator $ds9(mb).scale add command -label "[msgcat::mc {Scale Parameters}]..." \ -command ScaleDialog menu $ds9(mb).scale.scope $ds9(mb).scale.scope add radiobutton -label [msgcat::mc {Global}] \ -variable scale(scope) -command ChangeScaleScope -value global $ds9(mb).scale.scope add radiobutton -label [msgcat::mc {Local}] \ -variable scale(scope) -command ChangeScaleScope -value local menu $ds9(mb).scale.minmax $ds9(mb).scale.minmax add radiobutton -label [msgcat::mc {Automatic}] \ -variable minmax(mode) -value auto -command ChangeMinMax $ds9(mb).scale.minmax add radiobutton -label [msgcat::mc {Scan}] \ -variable minmax(mode) -value scan -command ChangeMinMax $ds9(mb).scale.minmax add radiobutton -label [msgcat::mc {Sample}] \ -variable minmax(mode) -value sample -command ChangeMinMax $ds9(mb).scale.minmax add radiobutton -label {DATAMIN DATAMAX} \ -variable minmax(mode) -value datamin -command ChangeMinMax $ds9(mb).scale.minmax add radiobutton -label {IRAF-MIN IRAF-MAX} \ -variable minmax(mode) -value irafmin -command ChangeMinMax $ds9(mb).scale.minmax add separator $ds9(mb).scale.minmax add command \ -label "[msgcat::mc {Sample Parameters}]..." -command MinMaxDialog } proc PrefsDialogScaleMenu {w} { set f [ttk::labelframe $w.mscale -text [msgcat::mc {Scale}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarScale $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 -sticky w set m $f.menu.menu menu $m $m add radiobutton -label [msgcat::mc {Linear}] \ -variable pscale(type) -value linear $m add radiobutton -label [msgcat::mc {Log}] \ -variable pscale(type) -value log $m add radiobutton -label [msgcat::mc {Power}] \ -variable pscale(type) -value pow $m add radiobutton -label [msgcat::mc {Square Root}]\ -variable pscale(type) -value sqrt $m add radiobutton -label [msgcat::mc {Squared}] \ -variable pscale(type) -value squared $m add radiobutton -label {ASINH} \ -variable pscale(type) -value asinh $m add radiobutton -label {SINH} \ -variable pscale(type) -value sinh $m add radiobutton -label [msgcat::mc {Histogram Equalization}] \ -variable pscale(type) -value histequ $m add separator $m add radiobutton -label [msgcat::mc {Min Max}] \ -variable pscale(mode) -value minmax $m add radiobutton -label {99.5%} -variable pscale(mode) -value 99.5 $m add radiobutton -label {99%} -variable pscale(mode) -value 99 $m add radiobutton -label {98%} -variable pscale(mode) -value 98 $m add radiobutton -label {97%} -variable pscale(mode) -value 97 $m add radiobutton -label {96%} -variable pscale(mode) -value 96 $m add radiobutton -label {95%} -variable pscale(mode) -value 95 $m add radiobutton -label {92.5%} -variable pscale(mode) -value 92.5 $m add radiobutton -label {90%} -variable pscale(mode) -value 90 $m add radiobutton -label {ZScale} -variable pscale(mode) -value zscale $m add radiobutton -label {ZMax} -variable pscale(mode) -value zmax $m add radiobutton -label [msgcat::mc {User}] \ -variable pscale(mode) -value user $m add separator $m add cascade -label [msgcat::mc {Scope}] -menu $m.scope $m add cascade -label [msgcat::mc {Min Max}] -menu $m.minmax $m add separator $m add checkbutton -label "[msgcat::mc {Use}] DATASEC" \ -variable pscale(datasec) menu $m.scope $m.scope add radiobutton -label [msgcat::mc {Global}] \ -variable pscale(scope) -value global $m.scope add radiobutton -label [msgcat::mc {Local}] \ -variable pscale(scope) -value local menu $m.minmax $m.minmax add radiobutton -label [msgcat::mc {Automatic}] \ -variable pminmax(mode) -value auto $m.minmax add radiobutton -label [msgcat::mc {Scan}] \ -variable pminmax(mode) -value scan $m.minmax add radiobutton -label [msgcat::mc {Sample}] \ -variable pminmax(mode) -value sample $m.minmax add radiobutton -label {DATAMIN DATAMAX} \ -variable pminmax(mode) -value datamin $m.minmax add radiobutton -label {IRAF-MIN IRAF-MAX} \ -variable pminmax(mode) -value irafmin pack $f -side top -fill both -expand true } proc PrefsDialogScale {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Scale}] lappend dprefs(tabs) [ttk::frame $w.scale] # Log set f [ttk::labelframe $w.scale.log -text [msgcat::mc {Log Exponent}]] ttk::entry $f.log -textvariable pscale(log) -width 10 grid $f.log -padx 2 -pady 2 -sticky w # MinMax set f [ttk::labelframe $w.scale.minmax \ -text [msgcat::mc {Min Max Parameters}]] slider $f.ssample 0 1000 [msgcat::mc {Sample Increment}] \ pminmax(sample) {} grid $f.ssample -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Zscale set f [ttk::labelframe $w.scale.zscale \ -text [msgcat::mc {ZScale Parameters}]] slider $f.scontrast 0. 1. [msgcat::mc {Contrast}] \ pzscale(contrast) {} slider $f.ssize 0 1000 [msgcat::mc {Number of Samples}] \ pzscale(sample) {} slider $f.sline 0 500 [msgcat::mc {Samples per Line}] \ pzscale(line) {} grid $f.scontrast -padx 2 -pady 2 -sticky ew grid $f.ssize -padx 2 -pady 2 -sticky ew grid $f.sline -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 pack $w.scale.log $w.scale.minmax $w.scale.zscale \ -side top -fill both -expand true } # Buttons proc ButtonsScaleDef {} { global pbuttons array set pbuttons { scale,linear 1 scale,log 1 scale,pow 1 scale,sqrt 1 scale,squared 1 scale,asinh 1 scale,sinh 1 scale,hist 1 scale,minmax 1 scale,995 0 scale,99 0 scale,98 0 scale,97 0 scale,96 0 scale,95 0 scale,925 0 scale,90 0 scale,zscale 1 scale,zmax 0 scale,user 0 scale,datasec 0 scale,params 0 } } proc CreateButtonsScale {} { global buttons global ds9 global scale ttk::frame $ds9(buttons).scale RadioButton $ds9(buttons).scale.linear \ [string tolower [msgcat::mc {Linear}]] \ scale(type) linear ChangeScale RadioButton $ds9(buttons).scale.log \ [string tolower [msgcat::mc {Log}]] \ scale(type) log ChangeScale RadioButton $ds9(buttons).scale.pow \ [string tolower [msgcat::mc {Power}]] \ scale(type) pow ChangeScale RadioButton $ds9(buttons).scale.sqrt \ [string tolower [msgcat::mc {Square Root}]] \ scale(type) sqrt ChangeScale RadioButton $ds9(buttons).scale.squared \ [string tolower [msgcat::mc {Squared}]] \ scale(type) squared ChangeScale RadioButton $ds9(buttons).scale.asinh \ [string tolower {ASINH}] \ scale(type) asinh ChangeScale RadioButton $ds9(buttons).scale.sinh \ [string tolower {SINH}] \ scale(type) sinh ChangeScale RadioButton $ds9(buttons).scale.hist \ [string tolower [msgcat::mc {Histogram}]] \ scale(type) histequ ChangeScale RadioButton $ds9(buttons).scale.minmax \ [string tolower [msgcat::mc {Min Max}]] \ scale(mode) minmax ChangeScaleMode RadioButton $ds9(buttons).scale.995 {99.5%} scale(mode) 99.5 ChangeScaleMode RadioButton $ds9(buttons).scale.99 {99%} scale(mode) 99 ChangeScaleMode RadioButton $ds9(buttons).scale.98 {98%} scale(mode) 98 ChangeScaleMode RadioButton $ds9(buttons).scale.97 {97%} scale(mode) 97 ChangeScaleMode RadioButton $ds9(buttons).scale.96 {96%} scale(mode) 96 ChangeScaleMode RadioButton $ds9(buttons).scale.95 {95%} scale(mode) 95 ChangeScaleMode RadioButton $ds9(buttons).scale.925 {92.5%} scale(mode) 92.5 ChangeScaleMode RadioButton $ds9(buttons).scale.90 {90%} scale(mode) 90 ChangeScaleMode RadioButton $ds9(buttons).scale.zscale {zscale} \ scale(mode) zscale ChangeScaleMode RadioButton $ds9(buttons).scale.zmax {zmax} \ scale(mode) zmax ChangeScaleMode RadioButton $ds9(buttons).scale.user \ [string tolower [msgcat::mc {User}]] \ scale(mode) user ChangeScaleMode CheckButton $ds9(buttons).scale.datasec {datasec} \ scale(datasec) ChangeDATASEC ButtonButton $ds9(buttons).scale.params \ [string tolower [msgcat::mc {Parameters}]] ScaleDialog set buttons(scale) " $ds9(buttons).scale.linear pbuttons(scale,linear) $ds9(buttons).scale.log pbuttons(scale,log) $ds9(buttons).scale.pow pbuttons(scale,pow) $ds9(buttons).scale.sqrt pbuttons(scale,sqrt) $ds9(buttons).scale.squared pbuttons(scale,squared) $ds9(buttons).scale.asinh pbuttons(scale,asinh) $ds9(buttons).scale.sinh pbuttons(scale,sinh) $ds9(buttons).scale.hist pbuttons(scale,hist) $ds9(buttons).scale.minmax pbuttons(scale,minmax) $ds9(buttons).scale.995 pbuttons(scale,995) $ds9(buttons).scale.99 pbuttons(scale,99) $ds9(buttons).scale.98 pbuttons(scale,98) $ds9(buttons).scale.97 pbuttons(scale,97) $ds9(buttons).scale.96 pbuttons(scale,96) $ds9(buttons).scale.95 pbuttons(scale,95) $ds9(buttons).scale.925 pbuttons(scale,925) $ds9(buttons).scale.90 pbuttons(scale,90) $ds9(buttons).scale.zscale pbuttons(scale,zscale) $ds9(buttons).scale.zmax pbuttons(scale,zmax) $ds9(buttons).scale.user pbuttons(scale,user) $ds9(buttons).scale.datasec pbuttons(scale,datasec) $ds9(buttons).scale.params pbuttons(scale,params) " } proc PrefsDialogButtonbarScale {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Linear}] \ -variable pbuttons(scale,linear) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {Log}] \ -variable pbuttons(scale,log) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {Power}] \ -variable pbuttons(scale,pow) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {Square Root}] \ -variable pbuttons(scale,sqrt) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {Squared}] \ -variable pbuttons(scale,squared) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {ASINH} \ -variable pbuttons(scale,asinh) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {SINH} \ -variable pbuttons(scale,sinh) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {Histogram Equalization}] \ -variable pbuttons(scale,hist) -command {UpdateButtons buttons(scale)} $m add separator $m add checkbutton -label [msgcat::mc {Min Max}] \ -variable pbuttons(scale,minmax) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {99.5%} \ -variable pbuttons(scale,995) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {99%} \ -variable pbuttons(scale,99) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {98%} \ -variable pbuttons(scale,98) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {97%} \ -variable pbuttons(scale,97) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {96%} \ -variable pbuttons(scale,96) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {95%} \ -variable pbuttons(scale,95) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {92.5%} \ -variable pbuttons(scale,925) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {90%} \ -variable pbuttons(scale,90) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {ZScale} \ -variable pbuttons(scale,zscale) -command {UpdateButtons buttons(scale)} $m add checkbutton -label {ZMax} \ -variable pbuttons(scale,zmax) -command {UpdateButtons buttons(scale)} $m add checkbutton -label [msgcat::mc {User}] \ -variable pbuttons(scale,user) -command {UpdateButtons buttons(scale)} $m add separator $m add checkbutton -label "[msgcat::mc {Use}] DATASEC" \ -variable pbuttons(scale,datasec) -command {UpdateButtons buttons(scale)} $m add separator $m add checkbutton -label "[msgcat::mc {Scale Parameters}]..." \ -variable pbuttons(scale,params) -command {UpdateButtons buttons(scale)} } # Support proc UpdateScaleMenu {} { global ds9 global current global scale global debug if {$debug(tcl,update)} { puts stderr "UpdateScaleMenu" } if {$current(frame) != {}} { if {![$current(frame) has iis]} { $ds9(mb) entryconfig [msgcat::mc {Scale}] -state normal set scale(type) [$current(frame) get colorscale] set scale(log) [$current(frame) get colorscale log] set scale(scope) [$current(frame) get clip scope] set scale(mode) [$current(frame) get clip mode] set scale(datasec) [$current(frame) get datasec] set scale(preserve) [$current(frame) get clip preserve] set minmax(mode) [$current(frame) get clip minmax mode] set minmax(sample) [$current(frame) get clip minmax sample] set zscale(contrast) [$current(frame) get clip zscale contrast] set zscale(sample) [$current(frame) get clip zscale sample] set zscale(line) [$current(frame) get clip zscale line] # Scope switch -- [$current(frame) get type] { base - rgb { if {[$current(frame) has fits]} { if {[$current(frame) has fits mosaic] || \ [$current(frame) has fits cube]} { $ds9(mb).scale entryconfig [msgcat::mc {Scope}] \ -state normal } else { $ds9(mb).scale entryconfig [msgcat::mc {Scope}] \ -state disabled } } else { $ds9(mb).scale entryconfig [msgcat::mc {Scope}] \ -state normal } } 3d { $ds9(mb).scale entryconfig [msgcat::mc {Scope}] \ -state disabled } } # DATAMIN/MAX IRAFMIN/MAX if {[$current(frame) has fits]} { if [$current(frame) has datamin] { $ds9(mb).scale.minmax entryconfig {DATAMIN DATAMAX} \ -state normal } else { $ds9(mb).scale.minmax entryconfig {DATAMIN DATAMAX} \ -state disabled } if [$current(frame) has irafmin] { $ds9(mb).scale.minmax entryconfig {IRAF-MIN IRAF-MAX} \ -state normal } else { $ds9(mb).scale.minmax entryconfig {IRAF-MIN IRAF-MAX} \ -state disabled } } else { $ds9(mb).scale.minmax entryconfig {DATAMIN DATAMAX} \ -state normal $ds9(mb).scale.minmax entryconfig {IRAF-MIN IRAF-MAX} \ -state normal } } else { $ds9(mb) entryconfig [msgcat::mc {Scale}] -state disabled } } else { $ds9(mb) entryconfig [msgcat::mc {Scale}] -state disabled } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/sfits.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000002223�12125367635�013537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadSFitsFile {hdr fn layer mode} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) smmap set loadParam(file,name) $fn set loadParam(file,header) $hdr set loadParam(load,layer) $layer ProcessLoad } proc ProcessSFitsCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} set mode {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i set mode slice } } StartLoad if {$sock != {}} { # xpa if {0} { # not supported } else { LoadSFitsFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $mode } } else { # comm if {0} { # not supported } else { LoadSFitsFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $mode } } FinishLoad } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaicwcs.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000005357�12132024702�014371� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMosaicWCSFile {fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic $sys] set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer ConvertFitsFile ProcessLoad } proc LoadMosaicWCSAlloc {path fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic $sys] set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc LoadMosaicWCSSocket {sock fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic $sys] set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc SaveMosaicWCSFile {fn opt} { global current puts stderr "$fn $opt" if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } if {$opt == {}} { set opt 1 } $current(frame) save fits mosaic file "\{$fn\}" $opt } proc SaveMosaicWCSSocket {sock opt} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } if {$opt == {}} { set opt 1 } $current(frame) save fits mosaic socket $sock $opt } proc ProcessMosaicWCSCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } if {[string range [lindex $var $i] 0 2] == {wcs}} { set opt [lindex $var $i] incr i } else { set opt wcs } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMosaicWCSSocket $sock $param $layer $opt]} { InitError xpa LoadMosaicWCSFile $param $layer $opt } } else { # comm if {$fn != {}} { LoadMosaicWCSAlloc $fn $param $layer $opt } else { LoadMosaicWCSFile $param $layer $opt } } FinishLoad } proc ProcessSendMosaicWCSCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } set opt [lindex $param 0] if {$sock != {}} { # xpa SaveMosaicWCSSocket $sock $opt } elseif {$fn != {}} { # comm SaveMosaicWCSFile $fn $opt $proc $id {} $fn } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mbin.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000031430�11714566604�013336� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menu proc BinMainMenu {} { global ds9 menu $ds9(mb).bin $ds9(mb).bin add radiobutton -label [msgcat::mc {Average}] \ -variable bin(function) -value average -command ChangeBinFunction $ds9(mb).bin add radiobutton -label [msgcat::mc {Sum}] \ -variable bin(function) -value sum -command ChangeBinFunction $ds9(mb).bin add separator $ds9(mb).bin add command -label [msgcat::mc {Block In}] \ -command {Bin .5 .5} $ds9(mb).bin add command -label [msgcat::mc {Block Out}] \ -command {Bin 2 2} $ds9(mb).bin add separator $ds9(mb).bin add command -label [msgcat::mc {Block to Fit Frame}] \ -command BinToFit $ds9(mb).bin add separator $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 1" \ -variable bin(factor) -value { 1 1 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 2" \ -variable bin(factor) -value { 2 2 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 4" \ -variable bin(factor) -value { 4 4 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 8" \ -variable bin(factor) -value { 8 8 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 16" \ -variable bin(factor) -value { 16 16 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 32" \ -variable bin(factor) -value { 32 32 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 64" \ -variable bin(factor) -value { 64 64 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 128" \ -variable bin(factor) -value { 128 128 } -command ChangeBinFactor $ds9(mb).bin add radiobutton -label "[msgcat::mc {Block}] 256" \ -variable bin(factor) -value { 256 256 } -command ChangeBinFactor $ds9(mb).bin add separator $ds9(mb).bin add radiobutton -label {128x128} \ -variable bin(buffersize) -value 128 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {256x256} \ -variable bin(buffersize) -value 256 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {512x512} \ -variable bin(buffersize) -value 512 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {1024x1024} \ -variable bin(buffersize) -value 1024 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {2048x2048} \ -variable bin(buffersize) -value 2048 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {4096x4096} \ -variable bin(buffersize) -value 4096 -command ChangeBinBufferSize $ds9(mb).bin add radiobutton -label {8192x8192} \ -variable bin(buffersize) -value 8192 -command ChangeBinBufferSize $ds9(mb).bin add separator $ds9(mb).bin add command -label "[msgcat::mc {Binning Parameters}]..." \ -command BinDialog } proc PrefsDialogBinMenu {w} { set f [ttk::labelframe $w.mbin -text [msgcat::mc {Bin}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarBin $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add radiobutton -label [msgcat::mc {Average}] \ -variable pbin(function) -value average $m add radiobutton -label [msgcat::mc {Sum}] \ -variable pbin(function) -value sum $m add separator $m add radiobutton -label "[msgcat::mc {Block}] 1" \ -variable pbin(factor) -value { 1 1 } $m add radiobutton -label "[msgcat::mc {Block}] 2" \ -variable pbin(factor) -value { 2 2 } $m add radiobutton -label "[msgcat::mc {Block}] 4" \ -variable pbin(factor) -value { 4 4 } $m add radiobutton -label "[msgcat::mc {Block}] 8" \ -variable pbin(factor) -value { 8 8 } $m add radiobutton -label "[msgcat::mc {Block}] 16" \ -variable pbin(factor) -value { 16 16 } $m add radiobutton -label "[msgcat::mc {Block}] 32" \ -variable pbin(factor) -value { 32 32 } $m add radiobutton -label "[msgcat::mc {Block}] 64" \ -variable pbin(factor) -value { 64 64 } $m add radiobutton -label "[msgcat::mc {Block}] 128" \ -variable pbin(factor) -value { 128 128 } $m add radiobutton -label "[msgcat::mc {Block}] 256" \ -variable pbin(factor) -value { 256 256 } $m add separator $m add radiobutton -label {128x128} -variable pbin(buffersize) -value 128 $m add radiobutton -label {256x256} -variable pbin(buffersize) -value 256 $m add radiobutton -label {512x512} -variable pbin(buffersize) -value 512 $m add radiobutton -label {1024x1204} -variable pbin(buffersize) -value 1024 $m add radiobutton -label {2048x2048} -variable pbin(buffersize) -value 2048 $m add radiobutton -label {4096x4096} -variable pbin(buffersize) -value 4096 $m add radiobutton -label {8192x8192} -variable pbin(buffersize) -value 8192 pack $f -side top -fill both -expand true } proc PrefsDialogBin {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Bin}] lappend dprefs(tabs) [ttk::frame $w.bin] # Mouse set f [ttk::labelframe $w.bin.mouse -text [msgcat::mc {Mouse Wheel Bin}]] ttk::checkbutton $f.click -text [msgcat::mc {Enable}] \ -variable pbin(wheel) ttk::label $f.title2 -text [msgcat::mc {Factor}] ttk::entry $f.factor -textvariable pbin(wheel,factor) -width 10 grid $f.click $f.title2 $f.factor -padx 2 -pady 2 -sticky w pack $w.bin.mouse -side top -fill both -expand true } # Buttons proc ButtonsBinDef {} { global pbuttons array set pbuttons { bin,average 0 bin,sum 0 bin,in 1 bin,out 1 bin,fit 1 bin,1 1 bin,2 1 bin,4 1 bin,8 1 bin,16 1 bin,32 1 bin,64 1 bin,128 0 bin,256 0 bin,128x 0 bin,256x 0 bin,512x 0 bin,1024x 0 bin,2048x 0 bin,4096x 0 bin,8192x 0 bin,params 0 } } proc CreateButtonsBin {} { global buttons global ds9 ttk::frame $ds9(buttons).bin RadioButton $ds9(buttons).bin.average \ [string tolower [msgcat::mc {Average}]] \ bin(function) average ChangeBinFunction RadioButton $ds9(buttons).bin.sum \ [string tolower [msgcat::mc {Sum}]] \ bin(function) sum ChangeBinFunction ButtonButton $ds9(buttons).bin.in {-} {Bin .5 .5} ButtonButton $ds9(buttons).bin.out {+} {Bin 2 2} ButtonButton $ds9(buttons).bin.fit \ [string tolower [msgcat::mc {To Fit}]] BinToFit RadioButton $ds9(buttons).bin.1 \ "[string tolower [msgcat::mc {Block}]] 1" \ bin(factor) { 1 1 } ChangeBinFactor RadioButton $ds9(buttons).bin.2 \ "[string tolower [msgcat::mc {Block}]] 2" \ bin(factor) { 2 2 } ChangeBinFactor RadioButton $ds9(buttons).bin.4 \ "[string tolower [msgcat::mc {Block}]] 4" \ bin(factor) { 4 4 } ChangeBinFactor RadioButton $ds9(buttons).bin.8 \ "[string tolower [msgcat::mc {Block}]] 8" \ bin(factor) { 8 8 } ChangeBinFactor RadioButton $ds9(buttons).bin.16 \ "[string tolower [msgcat::mc {Block}]] 16" \ bin(factor) { 16 16 } ChangeBinFactor RadioButton $ds9(buttons).bin.32 \ "[string tolower [msgcat::mc {Block}]] 32" \ bin(factor) { 32 32 } ChangeBinFactor RadioButton $ds9(buttons).bin.64 \ "[string tolower [msgcat::mc {Block}]] 64" \ bin(factor) { 64 64 } ChangeBinFactor RadioButton $ds9(buttons).bin.128 \ "[string tolower [msgcat::mc {Block}]] 128" \ bin(factor) { 128 128 } ChangeBinFactor RadioButton $ds9(buttons).bin.256 \ "[string tolower [msgcat::mc {Block}]] 256" \ bin(factor) { 256 256 } ChangeBinFactor RadioButton $ds9(buttons).bin.128x {128x128} \ bin(buffersize) 128 ChangeBinBufferSize RadioButton $ds9(buttons).bin.256x {256x256} \ bin(buffersize) 256 ChangeBinBufferSize RadioButton $ds9(buttons).bin.512x {512x512} \ bin(buffersize) 512 ChangeBinBufferSize RadioButton $ds9(buttons).bin.1024x {1024x1024} \ bin(buffersize) 1024 ChangeBinBufferSize RadioButton $ds9(buttons).bin.2048x {2048x2048} \ bin(buffersize) 2048 ChangeBinBufferSize RadioButton $ds9(buttons).bin.4096x {4096x4096} \ bin(buffersize) 4096 ChangeBinBufferSize RadioButton $ds9(buttons).bin.8192x {8192x8192} \ bin(buffersize) 8192 ChangeBinBufferSize ButtonButton $ds9(buttons).bin.params \ [string tolower [msgcat::mc {Parameters}]] BinDialog set buttons(bin) " $ds9(buttons).bin.average pbuttons(bin,average) $ds9(buttons).bin.sum pbuttons(bin,sum) $ds9(buttons).bin.in pbuttons(bin,in) $ds9(buttons).bin.out pbuttons(bin,out) $ds9(buttons).bin.fit pbuttons(bin,fit) $ds9(buttons).bin.1 pbuttons(bin,1) $ds9(buttons).bin.2 pbuttons(bin,2) $ds9(buttons).bin.4 pbuttons(bin,4) $ds9(buttons).bin.8 pbuttons(bin,8) $ds9(buttons).bin.16 pbuttons(bin,16) $ds9(buttons).bin.32 pbuttons(bin,32) $ds9(buttons).bin.64 pbuttons(bin,64) $ds9(buttons).bin.128 pbuttons(bin,128) $ds9(buttons).bin.256 pbuttons(bin,256) $ds9(buttons).bin.128x pbuttons(bin,128x) $ds9(buttons).bin.256x pbuttons(bin,256x) $ds9(buttons).bin.512x pbuttons(bin,512x) $ds9(buttons).bin.1024x pbuttons(bin,1024x) $ds9(buttons).bin.2048x pbuttons(bin,2048x) $ds9(buttons).bin.4096x pbuttons(bin,4096x) $ds9(buttons).bin.8192x pbuttons(bin,8192x) $ds9(buttons).bin.params pbuttons(bin,params) " } proc PrefsDialogButtonbarBin {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Average}] \ -variable pbuttons(bin,average) -command {UpdateButtons buttons(bin)} $m add checkbutton -label [msgcat::mc {Sum}] \ -variable pbuttons(bin,sum) -command {UpdateButtons buttons(bin)} $m add separator $m add checkbutton -label [msgcat::mc {Block In}] \ -variable pbuttons(bin,in) -command {UpdateButtons buttons(bin)} $m add checkbutton -label [msgcat::mc {Block Out}] \ -variable pbuttons(bin,out) -command {UpdateButtons buttons(bin)} $m add separator $m add checkbutton -label [msgcat::mc {Block to Fit Frame}] \ -variable pbuttons(bin,fit) -command {UpdateButtons buttons(bin)} $m add separator $m add checkbutton -label "[msgcat::mc {Block}] 1" \ -variable pbuttons(bin,1) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 2" \ -variable pbuttons(bin,2) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 4" \ -variable pbuttons(bin,4) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 8" \ -variable pbuttons(bin,8) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 16" \ -variable pbuttons(bin,16) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 32" \ -variable pbuttons(bin,32) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 64" \ -variable pbuttons(bin,64) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 128" \ -variable pbuttons(bin,128) -command {UpdateButtons buttons(bin)} $m add checkbutton -label "[msgcat::mc {Block}] 256" \ -variable pbuttons(bin,256) -command {UpdateButtons buttons(bin)} $m add separator $m add checkbutton -label {128x128} \ -variable pbuttons(bin,128x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {256x256} \ -variable pbuttons(bin,256x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {512x512} \ -variable pbuttons(bin,512x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {1024x1204} \ -variable pbuttons(bin,1024x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {2048x2048} \ -variable pbuttons(bin,2048x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {4096x4096} \ -variable pbuttons(bin,4096x) -command {UpdateButtons buttons(bin)} $m add checkbutton -label {8192x8192} \ -variable pbuttons(bin,8192x) -command {UpdateButtons buttons(bin)} $m add separator $m add checkbutton -label "[msgcat::mc {Binning Parameters}]..." \ -variable pbuttons(bin,params) -command {UpdateButtons buttons(bin)} } # Support proc UpdateBinMenu {} { global ds9 global current global bin global debug if {$debug(tcl,update)} { puts stderr "UpdateBinMenu" } if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {[$current(frame) has fits bin]} { $ds9(mb) entryconfig [msgcat::mc {Bin}] -state normal } else { $ds9(mb) entryconfig [msgcat::mc {Bin}] -state disabled } } else { $ds9(mb) entryconfig [msgcat::mc {Bin}] -state normal } set bin(function) [$current(frame) get bin function] set bin(factor) "[$current(frame) get bin factor]" set bin(depth) [$current(frame) get bin depth] set bin(buffersize) [$current(frame) get bin buffer size] } else { $ds9(mb) entryconfig [msgcat::mc {Bin}] -state disabled } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catned.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000007437�11700665566�013663� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATNED {varname} { upvar #0 $varname var global $varname global pcat global debug if {$debug(tcl,cat)} { puts stderr "CATNED $varname" } # parser if {$pcat(vot)} { set var(proc,parser) CATVOTParse } else { set var(proc,reader) CATNEDReader } # query switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { switch -- $var(sky) { fk4 - fk5 - icrs {set xx [h2d [Sex2H $var(x)]]} galactic - ecliptic {set xx [Sex2D $var(x)]} } set yy [Sex2D $var(y)] } } switch -- $var(rformat) { degrees { set ww $var(width) set hh $var(height) } arcmin { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } arcsec { set ww [expr $var(width)/60./60.] set hh [expr $var(height)/60./60.] } } set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] if {$pcat(vot)} { set out "xml_main" } else { set out "ascii_tab" } switch -- $var(sky) { fk4 { set sky "Equatorial" set eq "B1950.0" } fk5 - icrs { set sky "Equatorial" set eq "J2000.0" } galactic { set sky "Galactic" set eq {} } ecliptic { set sky "Ecliptic" set eq {} } } switch -- $var(psky) { fk4 { set psky "Equatorial" set peq "B1950.0" } fk5 - icrs { set psky "Equatorial" set peq "J2000.0" } galactic { set psky "Galactic" set peq {} } ecliptic { set psky "Ecliptic" set peq {} } } # url set var(query) {} set query [http::formatQuery search_type "Near Position Search" RA $xx DEC $yy SR $rr of $out in_csys $sky in_equinox $eq out_csys $psky out_equinox $peq] set var(url) "http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?$query" if {$pcat(vot)} { CATLoad $varname } else { CATLoadIncr $varname } } proc CATNEDReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) 1 } 1 { # process header if {[gets $sock line] == -1} { set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) -1 return $result } set result [string length "$line"] # start of data? if {[string range $line 0 2] == {No.}} { # cols incr ${t}(HLines) set n $T(HLines) set T(H_$n) $line set T(Header) [split $T(H_$n) "\t"] # dashes set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 2 } } 2 { # process table if {[gets $sock line] == -1} { set T(state) 0 } else { set result [string length "$line"] set line [string trim $line] if {$line != {}} { # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line "\t"] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } } } } return $result } proc CATNEDAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for NED This research has made use of the NASA/IPAC Extragalactic Database (NED) which is operated by the Jet Propulsion Laboratory, California Institute of Technology, under contract with the National Aeronautics and Space Administration. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/cattsv.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000005611�11700665566�013721� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATTSVRead {t fn} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { puts stderr "CATTSVRead" } if {$fn == {}} { return } catch { set fp [open $fn r] # init db set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 # ok, get first non comment line while (true) { if {[gets $fp line] == -1} { return } # skip any comments if {[string range $line 0 0] != "#"} { break; } } # reduce number of spaces regsub -all { +} $line { } line # strip any quotes regsub -all {\"} $line {} line # determine separator if {[llength [split $line "\t"]] > 1} { set ss "\t" } elseif {[llength [split $line ","]] > 1} { set ss "," } elseif {[llength [split $line ":"]] > 1} { set ss ":" } else { set ss " " } # determine header set first {} set foo [split $line $ss] if {([string is integer [lindex $foo 0]] || [string is double [lindex $foo 0]]) && ([string is integer [lindex $foo 1]] || [string is double [lindex $foo 1]])} { # determine num cols set cnt [llength $foo] # we need to build an header set first $line set line "X${ss}Y" for {set ii 2} {$ii<$cnt} {incr ii} { append line "${ss}column[expr $ii+3]" } } # process header # cols incr ${t}(HLines) set n $T(HLines) set T(H_$n) $line set T(Header) [split $T(H_$n) $ss] # dashes set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t # process table if {$first == {}} { gets $fp line } else { set line $first } while {![eof $fp]} { # skip any comments if {[string range $line 0 0] == "#"} { set line {} } # reduce number of spaces regsub -all { +} $line { } line set line [string trim $line] # do we have something? if {$line != {}} { # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line $ss] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } gets $fp line } close $fp } } proc CATTSVWrite {t fn} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { puts stderr "CATTSVWrite" } if {$fn == {}} { return } set fp [open $fn w] set nr $T(Nrows) set nc $T(Ncols) # header for {set cc 1} {$cc < $nc} {incr cc} { puts -nonewline $fp "[lindex $T(Header) [expr $cc-1]]\t" } puts $fp "[lindex $T(Header) [expr $nc-1]]" # data for {set rr 1} {$rr <= $nr} {incr rr} { for {set cc 1} {$cc < $nc} {incr cc} { puts -nonewline $fp "$T($rr,$cc)\t" } puts $fp "$T($rr,$nc)" } close $fp } �����������������������������������������������������������������������������������������������������������������������./saods9/src/examine.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000017246�12077601007�014036� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ExamineDef {} { global pexamine # prefs only set pexamine(mode) new set pexamine(zoom) 4 } proc ButtonExamine {which x y} { if {![$which has fits]} { return } switch -- [$which get type] { base {ButtonExamineBase $which $x $y} rgb {ButtonExamineRGB $which $x $y} 3d {ButtonExamine3D $which $x $y} } } proc ButtonExamineBase {which x y} { global current global ds9 global pexamine # this code will not handle mosaics. # current coord set coord [$which get coordinates $x $y physical] # find filename/slice set fn [$which get fits file name full canvas $x $y] for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { set slice($ii) [$which get fits slice $ii] } # so the new frame will have all of the parent frame when created set ds9(next) $which GotoFrame # create frame if needed switch -- $pexamine(mode) { new {CreateFrame} one { if {[info exists pexamine(one)]} { if {$which == $pexamine(one)} { # do nothing, we clicked in the examine frame return } DeleteSingleFrame $pexamine(one) CreateFrame set pexamine(one) $current(frame) } else { CreateFrame set pexamine(one) $current(frame) } } } # go to tile mode in case set current(display) tile DisplayMode # load data LoadFitsFile $fn {} {} RealizeDS9 # set slice for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { $current(frame) update fits slice $ii $slice($ii) } # zoom to about if {[$current(frame) has fits bin]} { set bf "[$current(frame) get bin factor]" set bx [expr [lindex $bf 0]/$pexamine(zoom)] set by [expr [lindex $bf 1]/$pexamine(zoom)] $current(frame) bin factor to $bx $by about \ [lindex $coord 0] [lindex $coord 1] } else { $current(frame) zoom $pexamine(zoom) $pexamine(zoom) \ about physical [lindex $coord 0] [lindex $coord 1] } # back to original frame set ds9(next) $which GotoFrame # update any dialogs UpdateDS9 } proc ButtonExamineRGB {which x y} { global current global ds9 global pexamine # this code is far from perfect. It assumes data is loaded into the red # and it is the keychannel. Furthermore, it assumes either images or bin # tables are loaded into each channel, but not both. # this code will not handle mosaics. # save current channel set channel [$which get rgb channel] # current coord $which rgb channel red set coord [$which get coordinates $x $y physical] # find filename/slice foreach cc {red green blue} { $which rgb channel $cc set fn($cc) [$which get fits file name full canvas $x $y] for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { set slice($cc,$ii) [$which get fits slice $ii] } } # so the new frame will have all of the parent frame when created set ds9(next) $which GotoFrame # create frame if needed switch -- $pexamine(mode) { new {CreateRGBFrame} one { if {[info exists pexamine(one)]} { if {$which == $pexamine(one)} { # do nothing, we clicked in the examine frame return } DeleteSingleFrame $pexamine(one) CreateRGBFrame set pexamine(one) $current(frame) } else { CreateRGBFrame set pexamine(one) $current(frame) } } } # go to tile mode in case set current(display) tile DisplayMode # load data foreach cc {red green blue} { $current(frame) rgb channel $cc if {$fn($cc) != {}} { LoadFitsFile $fn($cc) {} {} } } RealizeDS9 # set slice foreach cc {red green blue} { $current(frame) rgb channel $cc for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { $current(frame) update fits slice $ii $slice($cc,$ii) } } # zoom to about $current(frame) rgb channel red if {[$current(frame) has fits bin]} { foreach cc {red green blue} { $which rgb channel $cc $current(frame) rgb channel $cc set bf "[$current(frame) get bin factor]" set bx [expr [lindex $bf 0]/$pexamine(zoom)] set by [expr [lindex $bf 1]/$pexamine(zoom)] $current(frame) bin factor to $bx $by about \ [lindex $coord 0] [lindex $coord 1] } } else { $current(frame) zoom $pexamine(zoom) $pexamine(zoom) \ about image [lindex $coord 0] [lindex $coord 1] } # set channel $current(frame) rgb channel $channel # back to original frame set ds9(next) $which GotoFrame $current(frame) rgb channel $channel # update any dialogs UpdateDS9 } proc ButtonExamine3D {which x y} { global current global ds9 global pexamine # this code will not handle mosaics. # current coord set coord [$which get coordinates $x $y physical] # find filename/slice set fn [$which get fits file name full canvas $x $y] for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { set slice($ii) [$which get fits slice $ii] } # and 3d info set rr [$current(frame) get 3d view] set az [lindex $rr 0] set el [lindex $rr 1] set method [$current(frame) get 3d method] # so the new frame will have all of the parent frame when created set ds9(next) $which GotoFrame # create frame if needed switch -- $pexamine(mode) { new {Create3DFrame} one { if {[info exists pexamine(one)]} { if {$which == $pexamine(one)} { # do nothing, we clicked in the examine frame return } DeleteSingleFrame $pexamine(one) Create3DFrame set pexamine(one) $current(frame) } else { Create3DFrame set pexamine(one) $current(frame) } } } # go to tile mode in case set current(display) tile DisplayMode # load data LoadFitsFile $fn {} {} RealizeDS9 # set slice for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { $current(frame) update fits slice $ii $slice($ii) } # zoom to about if {[$current(frame) has fits bin]} { set bf "[$current(frame) get bin factor]" set bx [expr [lindex $bf 0]/$pexamine(zoom)] set by [expr [lindex $bf 1]/$pexamine(zoom)] $current(frame) bin factor to $bx $by about \ [lindex $coord 0] [lindex $coord 1] } else { $current(frame) zoom $pexamine(zoom) $pexamine(zoom) \ about physical [lindex $coord 0] [lindex $coord 1] } # set 3d $current(frame) 3d view $az $el $current(frame) 3d method $method # back to original frame set ds9(next) $which GotoFrame # update any dialogs UpdateDS9 } # Prefs proc PrefsDialogExamine {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Examine}] lappend dprefs(tabs) [ttk::frame $w.examine] # Examine set f [ttk::labelframe $w.examine.mode -text [msgcat::mc {Mode}]] ttk::radiobutton $f.new -text [msgcat::mc {New Frame each Time}] \ -variable pexamine(mode) -value new ttk::radiobutton $f.one -text [msgcat::mc {Examine Frame}] \ -variable pexamine(mode) -value one grid $f.new -padx 2 -pady 2 -sticky w grid $f.one -padx 2 -pady 2 -sticky w set f [ttk::labelframe $w.examine.mag -text [msgcat::mc {Magnification}]] ttk::radiobutton $f.x1 -text {1x} -variable pexamine(zoom) -value 1 ttk::radiobutton $f.x2 -text {2x} -variable pexamine(zoom) -value 2 ttk::radiobutton $f.x4 -text {4x} -variable pexamine(zoom) -value 4 ttk::radiobutton $f.x8 -text {8x} -variable pexamine(zoom) -value 8 ttk::radiobutton $f.x16 -text {16x} -variable pexamine(zoom) -value 16 grid $f.x1 $f.x2 $f.x4 $f.x8 $f.x16 -padx 2 -pady 2 -sticky w pack $w.examine.mode $w.examine.mag -side top -fill both -expand true } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/polygon.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000003610�12007016100�014050� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PolygonDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(proc,apply) PolygonApply set var(proc,close) PolygonClose set var(proc,coordCB) PolygonCoordCB # base MarkerBaseCenterDialog $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisPlot3dDialog $varname # init MarkerBaseCenterRotateCB $varname # callbacks $var(frame) marker $var(id) callback rotate MarkerBaseCenterRotateCB $varname set f $var(top).param # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w } # actions proc PolygonClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBaseCenterClose $varname } proc PolygonApply {varname} { upvar #0 $varname var global $varname MarkerBaseCenterRotate $varname MarkerBaseCenterApply $varname } # callbacks proc PolygonCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "PolygonCoordCB" } MarkerAnalysisStatsSystem $varname MarkerAnalysisPlot3dSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } ������������������������������������������������������������������������������������������������������������������������./saods9/src/mhelp.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000011505�11772152030�013503� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menu proc HelpMenu {mb} { global ds9 $mb add cascade -label [msgcat::mc {Help}] -menu $mb.help menu $mb.help $mb.help add command -label [msgcat::mc {Reference Manual}]\ -command HelpRef $mb.help add command -label [msgcat::mc {User Manual}]\ -command HelpUser $mb.help add command -label [msgcat::mc {Mouse & Keyboard}] \ -command HelpKeyboard $mb.help add separator $mb.help add command -label [msgcat::mc {FAQ}] \ -command HelpFAQ $mb.help add command -label [msgcat::mc {New Features}] \ -command HelpNew $mb.help add command -label [msgcat::mc {Release Notes}] \ -command HelpRelease $mb.help add command -label [msgcat::mc {Help Desk}] \ -command HelpDesk $mb.help add separator $mb.help add command -label [msgcat::mc {Story of SAOImage DS9}] \ -command HelpStory $mb.help add command -label [msgcat::mc {Acknowledgment}] \ -command HelpAck switch $ds9(wm) { x11 - win32 { $mb.help add separator $mb.help add command \ -label "[msgcat::mc {About SAOImage DS9}]..." \ -command AboutBox } aqua {} } } proc PrefsDialogHelpMenu {w} { set f [ttk::labelframe $w.mhelp -text [msgcat::mc {Help}]] PrefsDialogButtonbarHelp $f.buttonbar grid $f.buttonbar -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } # Buttons proc ButtonsHelpDef {} { global pbuttons array set pbuttons { help,ref 1 help,user 1 help,keyboard 1 help,faq 0 help,new 0 help,release 1 help,desk 1 help,story 0 help,ack 1 help,about 1 } } proc CreateButtonsHelp {} { global buttons global ds9 ttk::frame $ds9(buttons).help ButtonButton $ds9(buttons).help.ref \ [string tolower [msgcat::mc {Reference}]] HelpRef ButtonButton $ds9(buttons).help.user \ [string tolower [msgcat::mc {User}]] HelpUser ButtonButton $ds9(buttons).help.keyboard \ [string tolower [msgcat::mc {Keyboard}]] HelpKeyboard ButtonButton $ds9(buttons).help.faq \ [string tolower [msgcat::mc {FAQ}]] HelpFAQ ButtonButton $ds9(buttons).help.new \ [string tolower [msgcat::mc {New Features}]] HelpNew ButtonButton $ds9(buttons).help.release \ [string tolower [msgcat::mc {Release}]] HelpRelease ButtonButton $ds9(buttons).help.desk \ [string tolower [msgcat::mc {Help Desk}]] HelpDesk ButtonButton $ds9(buttons).help.story \ [string tolower [msgcat::mc {Story}]] HelpStory ButtonButton $ds9(buttons).help.ack \ [string tolower [msgcat::mc {Acknowledgment}]] HelpAck ButtonButton $ds9(buttons).help.about \ [string tolower [msgcat::mc {About}]] AboutBox set buttons(help) " $ds9(buttons).help.ref pbuttons(help,ref) $ds9(buttons).help.user pbuttons(help,user) $ds9(buttons).help.keyboard pbuttons(help,keyboard) $ds9(buttons).help.faq pbuttons(help,faq) $ds9(buttons).help.new pbuttons(help,new) $ds9(buttons).help.release pbuttons(help,release) $ds9(buttons).help.desk pbuttons(help,desk) $ds9(buttons).help.story pbuttons(help,story) $ds9(buttons).help.ack pbuttons(help,ack) $ds9(buttons).help.about pbuttons(help,about) " } proc PrefsDialogButtonbarHelp {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Reference Manual}]\ -variable pbuttons(help,ref) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {User Manual}]\ -variable pbuttons(help,user) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {Keyboard Shortcuts}] \ -variable pbuttons(help,keyboard) -command {UpdateButtons buttons(help)} $m add separator $m add checkbutton -label [msgcat::mc {FAQ}] \ -variable pbuttons(help,faq) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {New Features}] \ -variable pbuttons(help,new) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {Release Notes}] \ -variable pbuttons(help,release) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {Help Desk}] \ -variable pbuttons(help,desk) -command {UpdateButtons buttons(help)} $m add separator $m add checkbutton -label [msgcat::mc {Story of SAOImage DS9}] \ -variable pbuttons(help,story) -command {UpdateButtons buttons(help)} $m add checkbutton -label [msgcat::mc {Acknowledgment}] \ -variable pbuttons(help,ack) -command {UpdateButtons buttons(help)} $m add separator $m add checkbutton -label "[msgcat::mc {About SAOImage DS9}]..." \ -variable pbuttons(help,about) -command {UpdateButtons buttons(help)} } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catflt.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000005627�11700665566�013701� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATFltSort {varname} { upvar #0 $varname var global $varname global $var(catdb) global $var(tbldb) upvar #0 $var(catdb) src upvar #0 $var(tbldb) dest # create header set dest(Header) $src(Header) starbase_colmap dest set dest(Ndshs) [llength $dest(Header)] set dest(Nrows) 0 set dest(HLines) $src(HLines) set dest(Dashes) $src(Dashes) # optional if {[info exists src(DataType)]} { set dest(DataType) $src(DataType) } if {[info exists src(Id)]} { set dest(Id) $src(Id) } if {[info exists src(ArraySize)]} { set dest(ArraySize) $src(ArraySize) } if {[info exists src(Width)]} { set dest(Width) $src(Width) } if {[info exists src(Precision)]} { set dest(Precision) $src(Precision) } if {[info exists src(Unit)]} { set dest(Unit) $src(Unit) } if {[info exists src(Ref)]} { set dest(Ref) $src(Ref) } if {[info exists src(Ucd)]} { set dest(Ucd) $src(Ucd) } if {[info exists src(Description)]} { set dest(Description) $src(Description) } for {set ii 1} {$ii<=$src(HLines)} {incr ii} { set dest(H_$ii) $src(H_$ii) } for {set jj 1} {$jj<=$src(Ncols)} {incr jj} { set dest(0,$jj) $src(0,$jj) } # sort? set order {} if {$var(sort) != {}} { set col $src($var(sort)) for {set ii 1} {$ii<=$src(Nrows)} {incr ii} { lappend order "[list $ii $src($ii,$col)]" } # try to identify type if [string is double $src(1,$col)] { # first try as real, if error, then ascii if [catch {lsort $var(sort,dir) -real -index 1 $order} oo] { set oo [lsort $var(sort,dir) -ascii -index 1 $order] } set order $oo } else { set order [lsort $var(sort,dir) -ascii -index 1 $order] } } else { for {set ii 1} {$ii<=$src(Nrows)} {incr ii} { lappend order "[list $ii {}]" } } # data set kk 0 for {set ii 1} {$ii<=$src(Nrows)} {incr ii} { set id [lindex [lindex $order [expr $ii-1]] 0] # now filter set pass 1 if {$var(filter) != {}} { # eval all colnames foreach col $src(Header) { set col [string trim $col] set val $src($id,$src($col)) # here's a tough one-- # what to do if the column is blank # for now, just set it to '0' if {[string trim "$val"] == {}} { set val 0 } eval "set \{$col\} \{$val\}" } # subst any columv vars if [catch {subst $var(filter)} ff] { return 0 } # evaluate filter if [catch {expr $ff} result] { return 0 } # do we keep the row? if {!$result} { set pass 0 } } if {$pass} { incr kk for {set jj 1} {$jj<=$src(Ncols)} {incr jj} { set dest($kk,$jj) $src($id,$jj) } } } # success set dest(Nrows) $kk return 1 } ���������������������������������������������������������������������������������������������������������./saods9/src/util.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000072710�12132042644�013360� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CurrentDef {} { global current global pcurrent global ds9 set current(frame) {} set current(ext) {} set current(colorbar) {} set current(cursor) {} set current(rgb) red set current(display) single set current(mode) pointer set current(zoom) { 1 1 } set current(rotate) 0 set current(orient) none set current(align) 0 set pcurrent(display) $current(display) set pcurrent(mode) $current(mode) set pcurrent(zoom) $current(zoom) set pcurrent(rotate) $current(rotate) set pcurrent(orient) $current(orient) set pcurrent(align) $current(align) } proc CursorDef {} { global icursor set icursor(save) {} set icursor(count) 0 set icursor(id) 0 set icursor(timer) 0 set icursor(timer,abort) 0 } proc UpdateDS9Static {} { # This routine is only called when an frame is added or deleted # we only change menu items which require at least one frame global debug if {$debug(tcl,update)} { puts stderr "UpdateDS9Static begin..." } UpdateFileMenuStatic UpdateFrameMenuStatic UpdateZoomMenuStatic UpdateAnalysisMenuStatic if {$debug(tcl,update)} { puts stderr "UpdateDS9Static end...\n" } } proc UpdateDS9 {} { global ds9 global current # This routine is called when ever there is a state change within ds9 # for example, a image is loaded, current(frame) is changed, etc global debug if {$debug(tcl,update)} { puts stderr "UpdateDS9 begin..." } UpdateFileMenu UpdateEditMenu UpdateFrameMenu UpdateBinMenu UpdateZoomMenu UpdateScaleMenu UpdateColorMenu UpdateRegionMenu # wcs(system) set here UpdateWCSMenu UpdateAnalysisMenu UpdateMaskMenu UpdateContourMenu UpdateGridMenu UpdateSmoothMenu UpdateCubeMenu UpdateRGBMenu UpdatePanZoomMenu UpdateBinDialog UpdatePanZoomDialog UpdateCropDialog UpdateScaleDialog UpdateColorDialog UpdateWCSDialog UpdateGroupDialog UpdateCATDialog UpdateCentroidDialog UpdateCubeDialog UpdateRGBDialog Update3DDialog UpdateContourDialog UpdateGridDialog UpdateGraphXAxis $current(frame) UpdateGraphYAxis $current(frame) RefreshInfoBox $current(frame) UpdateColormapLevel if {$debug(tcl,update)} { puts stderr "UpdateDS9 end...\n" } } # changes to other dialogs can affect the infobox and pixeltable proc UpdateMain {} { global current global debug if {$debug(tcl,update)} { puts stderr "UpdateMain" } RefreshInfoBox $current(frame) UpdateColormapLevel switch -- $current(mode) { crosshair { if {$current(frame) != {}} { set coord [$current(frame) get crosshair canvas] set x [lindex $coord 0] set y [lindex $coord 1] # just in case we hae a mosaic UpdateColormapLevelMosaic $current(frame) $x $y canvas UpdatePixelTableDialog $current(frame) $x $y canvas UpdateGraph $current(frame) $x $y canvas } } none - pointer - catalog - colorbar - pan - zoom - rotate - crop - examine - imexam {} } } proc ProcessSend {proc id sock fn ext rr} { if {$sock != {}} { # not implemented } elseif {$fn != {}} { append fn $ext set ch [open $fn w] puts $ch $rr close $ch $proc $id {} $fn } else { $proc $id $rr } } proc Toplevel {w mb style title proc} { global ds9 toplevel $w switch $ds9(wm) { x11 - win32 {} aqua { switch $style { 6 {::tk::unsupported::MacWindowStyle style $w document "closeBox collapseBox"} 7 {::tk::unsupported::MacWindowStyle style $w document "closeBox fullZoom collapseBox resizable"} } bind $w <$ds9(ctrl)-`> "lower $w" } } wm title $w $title wm iconname $w $title wm group $w $ds9(top) wm protocol $w WM_DELETE_WINDOW $proc $w configure -menu $mb menu $mb AppleMainMenu $mb global pds9 if {$pds9(dialog,center)} { DialogCenter $w } } proc GetFileURL {url fname} { upvar $fname fn ParseURL $url rr switch -- $rr(scheme) { ftp {GetFileFTP $rr(authority) $rr(path) $fn} file {set fn $rr(path)} http - default {GetFileHTTP $url $fn} } } proc GetFileFTP {host path fn} { global debug set ftp [ftp::Open $host {ftp} {-ds9@} -mode passive] if {$ftp > -1} { set ftp::VERBOSE $debug(tcl,ftp) set "ftp::ftp${ftp}(Output)" FTPLog ftp::Type $ftp binary ftp::Get $ftp $path $fn ftp::Close $ftp # clear error from tcllib ftp global errorInfo set errorInfo {} } } proc GetFileHTTP {url fn} { global ihttp set ch [open $fn w] if [catch {http::geturl $url \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -channel $ch \ -binary 1 \ -headers "[ProxyHTTP]"} token] { close $ch return } # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} close $ch if {[info exists token]} { HTTPLog $token http::cleanup $token } } proc SourceInitFile {ext} { global ds9 global env foreach ff {{.} {}} { set fn $ff$ds9(app)$ext foreach dir [list {.} [GetEnvHome] {/usr/local/lib} {/opt/local/lib}] { set ff [file join $dir $fn] if [file exist $ff] { # can't make this a debug command line option # prefs set before options parsed if [catch {source $ff}] { Error "[msgcat::mc {An error has occured while executing}] $ff. [msgcat::mc {DS9 will complete the initialization process}]" return 0 } return 1 } } } return 0 } proc DeleteInitFile {ext} { global ds9 global env foreach ff {{.} {}} { set fn $ff$ds9(app)$ext foreach dir [list {.} [GetEnvHome]] { set ff [file join $dir $fn] if [file exist $ff] { catch {file delete -force $ff} return } } } } proc LanguageToName {which} { switch $which { locale {return {Locale}} cs {return "\u010Cesky"} da {return {Dansk}} de {return {Deutsch}} en {return {English}} es {return {Español}} fr {return {Français}} ja {return [encoding convertfrom euc-jp "\xc6\xfc\xcb\xdc\xb8\xec"]} pt {return {Português}} zh {return [encoding convertfrom big5 "\xA4\xA4\xA4\xE5"]} } } proc SetLanguage {ll} { global ds9 global pds9 set pds9(language,name) [LanguageToName $ll] set x 0 msgcat::mclocale $ll msgcat::mcload [file join $::tk_library msgs] # we need to find if we support this language if [msgcat::mcload [file join $ds9(root) msgs]] { incr x } if {$pds9(language,dir) != {}} { if [msgcat::mcload $pds9(language,dir)] { incr x } } # if english, always return found if {[string equal [string range $ll 0 1] {en}]} { incr x } if {$x} { return 1 } else { return 0 } } proc GetEnvHome {} { global env # return current directory by default set home {} global tcl_platform switch $tcl_platform(platform) { unix { if [info exists env(HOME)] { set home $env(HOME) } } windows { if {[info exists env(HOME)]} { set hh [file normalize [file nativename $env(HOME)]] if [file isdirectory $hh] { set home $hh } } # this is just a backup, the above should always work if {$home == {} && [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { set home "$env(HOMEDRIVE)$env(HOMEPATH)" } } } # if there is a problem, just return current directory if {![file isdirectory $home]} { set home {.} } return $home } proc InitTempDir {} { global ds9 global env # check environment vars first # windows is very picky as to file name format if [info exists env(TEMP)] { set ds9(tmpdir) [file normalize [file nativename $env(TEMP)]] } elseif [info exists env(TMP)] { set ds9(tmpdir) [file normalize [file nativename $env(TMP)]] } # nothing so far, go with defaults if {$ds9(tmpdir) == {}} { global tcl_platform switch $tcl_platform(platform) { unix {set ds9(tmpdir) "/tmp"} windows {set ds9(tmpdir) "C:/WINDOWS/Temp"} } } # see if it is valid, else current directory if {![file isdirectory $ds9(tmpdir)]} { set ds9(tmpdir) {.} } } proc tmpnam {base ext} { global ds9 for {set ii 0} {$ii<10} {incr ii} { set fn "$ds9(tmpdir)/$base[clock clicks]$ext" if {![file exists $fn]} { return $fn } } # give up return $ds9(tmpdir)/$base$ext } # which compiler do we use for filtering? proc InitFilterCompiler {} { global ds9 global env global tcl_platform global argv0 # if the user did not explicitly specify one ... if {![info exists env(FILTER_CC)]} { switch -- $tcl_platform(os) { Darwin { if {![file exists /usr/bin/gcc]} { # pcc is hardwired to be installed in /tmp set pccroot "/tmp/pcc" set pcc "$pccroot/bin/pcc" # always install pcc at startup # we don't want old versions of pcc around after upgrades switch -- $tcl_platform(machine) { {Power Macintosh} {set machine ppc} i386 - default {set machine i386} } switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 8 {set os tiger} 9 {set os leopard} 10 - 11 - default {set os snowleopard} } set tar "pcc-$machine-$os.tar.gz" if [file readable "$ds9(root)/$tar"] { catch { zvfs::filecopy "$ds9(root)/$tar" "/tmp/$tar" exec tar xfPz /tmp/$tar -C /tmp exec rm -f /tmp/$tar } } if {[file exists $pcc]} { set env(FILTER_CC) $pcc set env(FILTER_CFLAGS) "-isystem $pccroot/lib/pcc" set env(PATH) "$pccroot/bin:$env(PATH)" } } } "Windows NT" { set tcc [file join [file dirname $argv0] tcc/tcc.exe] if [file exists $tcc] { set env(FILTER_CC) [file nativename [file attributes [file normalize $tcc] -shortname]] set env(FILTER_TMPDIR) [file nativename [file attributes [file normalize $ds9(tmpdir)] -shortname]] } } } } } proc ToYesNo {value} { if {$value == 1} { return "yes\n" } else { return "no\n" } } proc FromYesNo {value} { set v [string tolower $value] if {$v == "no" || $v == "false" || $v == "off" || $v == 0} { return 0 } else { return 1 } } proc ProcessRealizeDS9 {} { global ds9 global current # this can really slow down scripts so use ds9(last) # to remember last update if {$ds9(last) != $current(frame)} { RealizeDS9 set ds9(last) $current(frame) } } proc RealizeDS9 {} { # this has to come first, to realize the canvas global debug if {$debug(tcl,idletasks)} { puts stderr "RealizeDS9" } # update all frames global ds9 foreach ff $ds9(frames) { $ff update now } # idletasks fails for windows. we need to process all events to make # sure all windows are realized # update idletasks update } proc Sex2H {str} { scan $str "%d:%d:%f" h m s return [expr $h+($m/60.)+($s/(60.*60.))] } proc Sex2Hs {str} { scan $str "%d %d %f" h m s return [expr $h+($m/60.)+($s/(60.*60.))] } proc Sex2D {str} { set sign 1 set degree 0 set min 0 set sec 0 scan $str "%d:%f:%f" degree min sec if {$degree != 0} { if {$degree < 0} { set sign -1 } } else { if {[string range $str 0 0] == {-}} { set sign -1 } } return [expr $sign * (abs($degree)+($min/60.)+($sec/(60.*60.)))] } proc PixelsToPoints {size} { if {$size < 0} { set size [expr int(abs($size)/[tk scaling]+.5)] } return $size } proc SetCursor {cursor} { global ds9 global iis global current # if init phase, don't change cursor if {$ds9(init)} { return } # if iis cursor mode, don't change cursor if {$iis(state)} { return } if {($current(cursor) != $cursor)} { set current(cursor) $cursor if {$cursor != {}} { $ds9(canvas) configure -cursor $cursor } else { $ds9(canvas) configure -cursor {} } } } proc SetWatchCursor {} { global ds9 global icursor # if init phase, don't change cursor if {$ds9(init)} { return } # don't change cursor/update if {!$ds9(idletasks)} { return } global debug if {$debug(tcl,watch)} { puts stderr "SetWatchCursor Start $icursor(count)" } if {$icursor(count) == 0} { set icursor(save) [$ds9(canvas) cget -cursor] $ds9(canvas) configure -cursor {} $ds9(main) configure -cursor watch global debug if {$debug(tcl,idletasks)} { puts stderr "SetWatchCursor" } update idletasks } incr icursor(count) if {$debug(tcl,watch)} { puts stderr "SetWatchCursor End $icursor(count)" } } proc UnsetWatchCursor {} { global ds9 global icursor # if init phase, don't change cursor if {$ds9(init)} { return } # don't change cursor/update if {!$ds9(idletasks)} { return } global debug if {$debug(tcl,watch)} { puts stderr "UnsetWatchCursor Start $icursor(count)" } if {$icursor(count)>0} { incr icursor(count) -1 } if {$icursor(count) == 0} { $ds9(main) configure -cursor {} $ds9(canvas) configure -cursor $icursor(save) global debug if {$debug(tcl,idletasks)} { puts stderr "UnsetWatchCursor" } update idletasks } if {$debug(tcl,watch)} { puts stderr "UnsetWatchCursor End $icursor(count)" } } proc CursorTimer {} { global ds9 global icursor switch -- $icursor(timer) { 0 { set icursor(timer,abort) 0 set icursor(timer) 0 set icursor(id) 0 $ds9(canvas) configure -cursor {} } 1 { $ds9(canvas) configure -cursor circle set icursor(timer) 2 set icursor(id) [after 1000 CursorTimer] } 2 { $ds9(canvas) configure -cursor dot set icursor(timer) 1 set icursor(id) [after 1000 CursorTimer] } } } proc AboutBox {} { global help global ds9 global ed set w {.abt} set ed(ok) 0 DialogCreate $w [msgcat::mc {About SAOImage DS9}] ed(ok) # Param set f [frame $w.param -background white] canvas $f.c -background white -height 450 -width 550 pack $f.c -fill both -expand true # can't use -file for zvfs # set ed(sun) [image create photo -format gif -file $ds9(root)/doc/sun.gif] set ch [open $ds9(root)/doc/sun.gif r] fconfigure $ch -translation binary -encoding binary set dd [read $ch] close $ch unset ch set ed(sun) [image create photo -format gif -data "$dd"] unset dd $f.c create image 0 0 -image $ed(sun) -anchor nw $f.c create text 120 22 -text $help(about) -anchor nw -width 400 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active pack $f.ok -padx 2 -pady 2 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w image delete $ed(sun) unset ed } proc QuitDS9 {} { global ds9 # shutdown SAMP global samp if [info exists samp] { catch {SAMPDisconnect} } # close IIS ports catch {IISClose} # close out XPA global xpa if [info exists xpa] { catch {xpafree $xpa} } # close all HV windows, they may have tmp files global ihv foreach hh $ihv(windows) { if [winfo exists $hh] { catch {HVDestroy $hh} } } focus {} exit } proc OpenSource {} { set filename [OpenFileDialog tclfbox] if {$filename != {}} { uplevel #0 "source \{$filename\}" } } proc OpenConsole {} { if {[winfo exists ".tkcon"]} { tkcon show } else { set ::tkcon::OPT(exec) {} tkcon::Init } } proc ToggleBindEvents {} { global ds9 if {$ds9(freeze)} { set ds9(freeze) 0 BindEventsCanvas BindEventsPanner } else { set ds9(freeze) 1 UnBindEventsCanvas UnBindEventsPanner } } proc ChangeMode {} { global ds9 global current bind $ds9(canvas) <Button-1> {} bind $ds9(canvas) <B1-Motion> {} bind $ds9(canvas) <ButtonRelease-1> {} foreach f $ds9(frames) { $f crosshair off } UpdateRegionMenu foreach f $ds9(frames) { $f marker catalog unselect all $f marker catalog unhighlite all $f marker unselect all $f marker unhighlite all } RefreshInfoBox $current(frame) PixelTableClearDialog ClearGraphData switch -- $current(mode) { none - pointer - catalog {SetCursor {}} crosshair { foreach f $ds9(frames) { $f crosshair on } SetCursor crosshair } colorbar {SetCursor center_ptr} zoom {SetCursor sizing} pan {SetCursor fleur} rotate {SetCursor exchange} crop {SetCursor {}} examine {SetCursor target} imexam {} } } proc PrefsTheme {} { global ds9 global pds9 if {[lsearch [ttk::style theme names] $pds9(theme)] < 0} { set pds9(theme) native } switch $pds9(theme) { native { switch $ds9(wm) { x11 {ttk::style theme use default} win32 {ttk::style theme use xpnative} aqua {} } } default {ttk::style theme use $pds9(theme)} } # set bg for non ttk widgets set ds9(app,bg) [ttk::style lookup "." -background] option add {*Bbutton.Background} $ds9(app,bg) option add {*Radiobutton.Background} $ds9(app,bg) option add {*Checkbutton.Background} $ds9(app,bg) option add {*Text.Background} $ds9(app,bg) option add {*Listbox.Background} $ds9(app,bg) option add {*Scale.Background} $ds9(app,bg) option add {*Menu.background} $ds9(app,bg) option add {*Table.Background} $ds9(app,bg) option add {*Graph.Background} $ds9(app,bg) option add {*Barchart.Background} $ds9(app,bg) } proc PrefsDefaultFont {} { global ds9 global pds9 font configure TkDefaultFont -family $ds9($pds9(font)) \ -size $pds9(font,size) -weight $pds9(font,weight) \ -slant $pds9(font,slant) font configure TkMenuFont -family $ds9($pds9(font)) \ -size $pds9(font,size) -weight $pds9(font,weight) \ -slant $pds9(font,slant) font configure TkTextFont -family $ds9($pds9(font)) \ -size $pds9(font,size) -weight $pds9(font,weight) \ -slant $pds9(font,slant) UpdateScaleDialogFont UpdateGraphFont } proc PrefsResetDefaultFont {} { global pds9 eval font configure TkDefaultFont [font actual DefaultFont] eval font configure TkMenuFont [font actual DefaultMenuFont] eval font configure TkTextFont [font actual DefaultTextFont] set pds9(font) helvetica set pds9(font,size) [PixelsToPoints [font configure TkDefaultFont -size]] set pds9(font,weight) [font configure TkDefaultFont -weight] set pds9(font,slant) [font configure TkDefaultFont -slant] FontMenuButtonCmd pds9 font {} } proc PrefsResetDefaultTextFont {} { global pds9 set pds9(text,font) courier set pds9(text,font,size) [PixelsToPoints [font actual TkFixedFont -size]] set pds9(text,font,weight) [font actual TkFixedFont -weight] set pds9(text,font,slant) [font actual TkFixedFont -slant] FontMenuButtonCmd pds9 text,font {} } proc PrefsBgColor {} { global ds9 global pds9 foreach ff $ds9(frames) { $ff bg color $pds9(bg) } } proc PrefsNanColor {} { global ds9 global pds9 foreach ff $ds9(frames) { $ff nan color $pds9(nan) } } proc PrefsThreads {} { global ds9 global pds9 foreach ff $ds9(frames) { $ff threads $pds9(threads) } return true } proc DisplayLog {item} { SimpleTextDialog ftptxt [msgcat::mc {Message Log}] 80 40 append bottom $item } proc ParseURL {url varname} { upvar $varname r set r(scheme) {} set r(authority) {} set r(path) {} set r(query) {} set r(fragment) {} set exp {^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?} if {![regexp -nocase $exp $url x a r(scheme) c r(authority) r(path) f r(query) h r(fragment)]} { return 0 } # check for windows disk drives global tcl_platform switch $tcl_platform(platform) { unix {} windows { switch -- $r(scheme) { {} - ftp - http - file { if [regexp {/([A-Z]:)(/.*)} $r(path) a b c] { set r(path) "$b$c" } } default { set r(path) "$r(scheme):$r(path)" set r(scheme) {} } } } } return 1 } proc BreakUp {str} { set r {} set l [string length $str] for {set i 0} {$i < $l} {incr i} { set c [string index $str $i] append r $c if {$c=="\}"} { append r "\n" } } return $r } proc InPath {which} { global env global tcl_platform switch $tcl_platform(platform) { unix { set target ${which} set paths [split $env(PATH) :] } windows { set target ${which}.exe set paths [split $env(PATH) \;] } } foreach p $paths { if {[file executable [file join $p $target]]} { return 1 } } return 0 } proc FTPLog {s msg state} { global debug if {$debug(tcl,ftp)} { DisplayLog "$s $msg $state\n" } } proc HTTPLog {token} { global debug if {$debug(tcl,http)} { upvar #0 $token t DisplayLog "url: $t(url)\n" DisplayLog "http: $t(http)\n" DisplayLog "type: $t(type)\n" DisplayLog "currentsize: $t(currentsize)\n" DisplayLog "totalsize: $t(totalsize)\n" DisplayLog "status: $t(status)\n" if [info exists t(error)] { DisplayLog "error: $t(error)\n" } DisplayLog "meta: [BreakUp $t(meta)]\n" } } proc ConfigHTTP {} { global phttp # set the User-Agent http::config -useragent ds9 # set the proxy if requested if {$phttp(proxy)} { http::config -proxyhost $phttp(proxy,host) -proxyport $phttp(proxy,port) } } proc ProxyHTTP {} { global phttp set auth {} if {$phttp(proxy) && $phttp(auth)} { set auth [list "Proxy-Authorization" [concat "Basic" [base64::encode $phttp(auth,user):$phttp(auth,passwd)]]] } return $auth } proc ValidFits {filename} { if {$filename == {}} { return 0 } # determine if its a fits file # first, strip the filename if {![regexp -nocase {(.*)(\[.*\])} $filename foo base ext]} { set base $filename set ext {} } set fd [open $base] if {$fd != {}} { set l [read $fd 9] close $fd } if {$l == "SIMPLE ="} { return 1 } else { return 0 } } proc FixSpec {sysname skyname formatname defsys defsky defformat} { upvar $sysname sys upvar $skyname sky upvar $formatname format set rr 0 switch -- $sys { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {incr rr} fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic { set format $sky set sky $sys set sys wcs } default { set format $sky set sky $sys set sys $defsys } } switch -- $sky { fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic {incr rr} default { set format $sky set sky $defsky } } switch -- $format { degrees - arcmin - arcsec - sexagesimal {incr rr} default { set format $defformat } } return $rr } proc FixSpecSystem {sysname defsys} { upvar $sysname sys set rr 0 switch -- $sys { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {incr rr} default { set sys $defsys } } return $rr } proc DS9Backup {ch which} { global pds9 puts $ch "$which bg color $pds9(bg)" puts $ch "$which nan color $pds9(nan)" } # Process Cmds proc ProcessPrefsCmd {varname iname} { upvar $varname var upvar $iname i global pds9 switch -- [string tolower [lindex $var $i]] { clear {ClearPrefs} bgcolor { # backward compatibility incr i set pds9(bg) [lindex $var $i] PrefsBgColor } nancolor { # backward compatibility incr i set pds9(nan) [lindex $var $i] PrefsNanColor } threads { # backward compatibility incr i set pds9(threads) [lindex $var $i] PrefsThreads } } } proc ProcessSendPrefsCmd {proc id param} { global pds9 # backward compatibility switch -- [string tolower [lindex $param 0]] { bgcolor {$proc $id "$pds9(bg)\n"} nancolor {$proc $id "$pds9(nan)\n"} threads {$proc $id "$pds9(threads)\n"} } } proc ProcessBgCmd {varname iname} { upvar $varname var upvar $iname i global pds9 set pds9(bg) [lindex $var $i] PrefsBgColor } proc ProcessSendBgCmd {proc id param} { global pds9 $proc $id "$pds9(bg)\n" } proc ProcessNanCmd {varname iname} { upvar $varname var upvar $iname i global pds9 set pds9(nan) [lindex $var $i] PrefsNanColor } proc ProcessSendNanCmd {proc id param} { global pds9 $proc $id "$pds9(nan)\n" } proc ProcessThreadsCmd {varname iname} { upvar $varname var upvar $iname i global pds9 set pds9(threads) [lindex $var $i] PrefsThreads } proc ProcessSendThreadsCmd {proc id param} { global pds9 $proc $id "$pds9(threads)\n" } proc ProcessCDCmd {varname iname} { upvar $varname var upvar $iname i cd [lindex $var $i] } proc ProcessSendCDCmd {proc id param} { $proc $id "[pwd]\n" } proc ProcessConsoleCmd {varname iname} { upvar $varname var upvar $iname i OpenConsole # ignore error message about ActiveTcl global ds9 InitError $ds9(msg,src) } proc ProcessCursorCmd {varname iname} { upvar $varname var upvar $iname i global current if {$current(frame) != {}} { set x [lindex $var $i] incr i set y [lindex $var $i] switch -- $current(mode) { none {$current(frame) warp $x $y} pointer {MarkerArrowKey $current(frame) $x $y} catalog {MarkerArrowKey $current(frame) $x $y} crosshair {ArrowKeyCrosshair $current(frame) $x $y} colorbar {} pan {Pan $x $y canvas} zoom - rotate - crop - examine - imexam {} } } } proc ProcessSendDataCmd {proc id param sock fn} { global cube global blink global current if {$current(frame) != {}} { set sys [lindex $param 0] set sky [lindex $param 1] set x [lindex $param 2] set y [lindex $param 3] set w [lindex $param 4] set h [lindex $param 5] set strip [lindex $param 6] switch -- $sys { image - physical - detector - amplifier { set strip $h set h $w set w $y set y $x set x $sky set sky fk5 } fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic { set strip $h set h $w set w $y set y $x set x $sky set sky $sys set sys wcs } } set strip [FromYesNo $strip] $current(frame) get data $sys $sky $x $y $w $h rr set ss {} foreach ii [array names rr] { if {$strip} { append ss "$rr($ii)\n" } else { append ss "$ii = $rr($ii)\n" } } ProcessSend $proc $id $sock $fn {.dat} $ss } } proc ProcessIconifyCmd {varname iname} { upvar $varname var upvar $iname i global ds9 switch -- [string tolower [lindex $var $i]] { yes - true - on - 1 {wm iconify $ds9(top)} no - false - off - 0 {wm deiconify $ds9(top)} default { wm iconify $ds9(top) incr i -1 } } } proc ProcessSendIconifyCmd {proc id param} { global ds9 if {[wm state $ds9(top)] == "normal"} { $proc $id "no\n" } else { $proc $id "yes\n" } } proc ProcessLowerCmd {varname iname} { upvar $varname var upvar $iname i global ds9 lower $ds9(top) } proc ProcessModeCmd {varname iname} { upvar $varname var upvar $iname i global current set current(mode) [string tolower [lindex $var $i]] ChangeMode } proc ProcessQuitCmd {varname iname} { upvar $varname var upvar $iname i QuitDS9 } proc ProcessSendModeCmd {proc id param} { global current $proc $id "$current(mode)\n" } proc ProcessRaiseCmd {varname iname} { upvar $varname var upvar $iname i global ds9 raise $ds9(top) } proc ProcessSleepCmd {varname iname} { upvar $varname var upvar $iname i # yes, we need this UpdateDS9 RealizeDS9 set sec 1 if {[lindex $var $i] != {} && [string range [lindex $var $i] 0 0] != {-}} { set sec [lindex $var $i] } else { incr i -1 } after [expr int($sec*1000)] } proc ProcessSourceCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized # you never know what someone will try to do ProcessRealizeDS9 set fn [lindex $var $i] uplevel #0 "source $fn" } proc ProcessTclCmd {varname iname buf fn} { upvar $varname var upvar $iname i global pds9 if {!$pds9(tcl)} { Error [msgcat::mc {Executing TCL code is not enabled}] return } if {$buf != {}} { uplevel #0 $buf } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set cmd [read $ch] close $ch uplevel #0 $cmd } } elseif {[lindex $var $i] != {}} { # special case uplevel #0 $var } } proc ProcessThemeCmd {varname iname} { upvar $varname var upvar $iname i global pds9 set pds9(theme) [string tolower [lindex $var $i]] PrefsTheme } proc ProcessSendThemeCmd {proc id param} { global pds9 $proc $id "$pds9(theme)\n" } proc ProcessSendVersionCmd {proc id param} { global ds9 $proc $id "$ds9(title) [lindex $ds9(version) 0]\n" } proc XMLQuote {val} { return [string map {& &amp; < &lt; > &gt; \' &apos; \" &quot;} $val] } proc XMLUnQuote {val} { return [string map {&amp; & &lt; < &gt; > &apos; \' &quot; \"} $val] } ��������������������������������������������������������./saods9/src/file.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000015636�12131601440�013320� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # backward compatibility proc ProcessFileCmd {varname iname sock ch fn} { upvar $varname var upvar $iname i set vvar $var set ii $i set zero $i set one [expr $i+1] set two [expr $i+2] set three [expr $i+3] switch -- [string tolower [lindex $var $zero]] { new { switch -- [string tolower [lindex $var $one]] { slice {ProcessFitsCmd vvar ii $sock $fn} fits { set vvar [lreplace $var $one $one] ProcessFitsCmd vvar ii $sock $fn } sfits { set vvar [lreplace $var $one $one] ProcessSFitsCmd vvar ii $sock $fn } rgbimage { set vvar [lreplace $var $one $one] ProcessRGBImageCmd vvar ii $sock $fn } rgbcube { set vvar [lreplace $var $one $one] ProcessRGBCubeCmd vvar ii $sock $fn } srgbcube { set vvar [lreplace $var $one $one] ProcessSRGBCubeCmd vvar ii $sock $fn } mecube { set vvar [lreplace $var $one $one] ProcessMECubeCmd vvar ii $sock $fn } memf - multiframe { set vvar [lreplace $var $one $one] ProcessMultiFrameCmd vvar ii $sock $fn } mosaicimage { set vvar [lreplace $var $one $one] ProcessMosaicImageCmd vvar ii $sock $fn } mosaicimagewcs { set vvar [lreplace $var $one $one] ProcessMosaicImageWCSCmd vvar ii $sock $fn } mosaicimageiraf { set vvar [lreplace $var $one $one] ProcessMosaicImageIRAFCmd vvar ii $sock $fn } mosaicimagewfpc2 { set vvar [lreplace $var $one $one] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn } mosaic { set vvar [lreplace $var $one $one] ProcessMosaicCmd vvar ii $sock $fn } mosaicwcs { set vvar [lreplace $var $one $one] ProcessMosaicWCSCmd vvar ii $sock $fn } mosaiciraf { set vvar [lreplace $var $one $one] ProcessMosaicIRAFCmd vvar ii $sock $fn } smosaic { set vvar [lreplace $var $one $one] ProcessSMosaicCmd vvar ii $sock $fn } smosaicwcs { set vvar [lreplace $var $one $one] ProcessSMosaicWCSCmd vvar ii $sock $fn } smosaiciraf { set vvar [lreplace $var $one $one] ProcessSMosaicIRAFCmd vvar ii $sock $fn } url { set vvar [lreplace $var $one $one] ProcessURLFitsCmd vvar ii } array { set vvar [lreplace $var $one $one] ProcessArrayCmd vvar ii $sock $fn } rgbarray { set vvar [lreplace $var $one $one] ProcessRGBArrayCmd vvar ii $sock $fn } photo { set vvar [lreplace $var $one $one] ProcessTIFFCmd vvar ii $ch $fn } default {ProcessFitsCmd vvar ii $sock $fn} } } mask { switch -- [string tolower [lindex $var $one]] { fits { set vvar [lreplace $var $one $one] ProcessFitsCmd vvar ii $sock $fn } sfits { set vvar [lreplace $var $one $one] ProcessSFitsCmd vvar ii $sock $fn } mosaicimage { set vvar [lreplace $var $one $one] ProcessMosaicImageCmd vvar ii $sock $fn } mosaicimagewcs { set vvar [lreplace $var $one $one] ProcessMosaicImageWCSCmd vvar ii $sock $fn } mosaicimageiraf { set vvar [lreplace $var $one $one] ProcessMosaicImageIRAFCmd vvar ii $sock $fn } mosaicimagewfpc2 { set vvar [lreplace $var $one $one] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn } mosaic { set vvar [lreplace $var $one $one] ProcessMosaicCmd vvar ii $sock $fn } mosaicwcs { set vvar [lreplace $var $one $one] ProcessMosaicWCSCmd vvar ii $sock $fn } mosaiciraf { set vvar [lreplace $var $one $one] ProcessMosaicIRAFCmd vvar ii $sock $fn } smosaic { set vvar [lreplace $var $one $one] ProcessSMosaicCmd vvar ii $sock $fn } smosaicwcs { set vvar [lreplace $var $one $one] ProcessSMosaicWCSCmd vvar ii $sock $fn } smosaiciraf { set vvar [lreplace $var $one $one] ProcessSMosaicIRAFCmd vvar ii $sock $fn } array { set vvar [lreplace $var $one $one] ProcessArrayCmd vvar ii $sock $fn } default {ProcessFitsCmd vvar ii $sock $fn} } } slice {ProcessFitsCmd vvar ii $sock $fn} fits { set vvar [lreplace $var $zero $zero] ProcessFitsCmd vvar ii $sock $fn } sfits { set vvar [lreplace $var $zero $zero] ProcessSFitsCmd vvar ii $sock $fn } rgbimage { set vvar [lreplace $var $zero $zero] ProcessRGBImageCmd vvar ii $sock $fn } rgbcube { set vvar [lreplace $var $zero $zero] ProcessRGBCubeCmd vvar ii $sock $fn } srgbcube { set vvar [lreplace $var $zero $zero] ProcessSRGBCubeCmd vvar ii $sock $fn } mecube { set vvar [lreplace $var $zero $zero] ProcessMECubeCmd vvar ii $sock $fn } memf - multiframe { set vvar [lreplace $var $zero $zero] ProcessMultiFrameCmd vvar ii $sock $fn } mosaicimage { set vvar [lreplace $var $zero $zero] ProcessMosaicImageCmd vvar ii $sock $fn } mosaicimagewcs { set vvar [lreplace $var $zero $zero] ProcessMosaicImageWCSCmd vvar ii $sock $fn } mosaicimageiraf { set vvar [lreplace $var $zero $zero] ProcessMosaicImageIRAFCmd vvar ii $sock $fn } mosaicimagewfpc2 { set vvar [lreplace $var $zero $zero] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn } mosaic { set vvar [lreplace $var $zero $zero] ProcessMosaicCmd vvar ii $sock $fn } mosaicwcs { set vvar [lreplace $var $zero $zero] ProcessMosaicWCSCmd vvar ii $sock $fn } mosaiciraf { set vvar [lreplace $var $zero $zero] ProcessMosaicIRAFCmd vvar ii $sock $fn } smosaic { set vvar [lreplace $var $zero $zero] ProcessSMosaicCmd vvar ii $sock $fn } smosaicwcs { set vvar [lreplace $var $zero $zero] ProcessSMosaicWCSCmd vvar ii $sock $fn } smosaiciraf { set vvar [lreplace $var $zero $zero] ProcessSMosaicIRAFCmd vvar ii $sock $fn } url { set vvar [lreplace $var $zero $zero] ProcessURLFitsCmd vvar ii } array { set vvar [lreplace $var $zero $zero] ProcessArrayCmd vvar ii $sock $fn } rgbarray { set vvar [lreplace $var $zero $zero] ProcessRGBArrayCmd vvar ii $sock $fn } photo { set vvar [lreplace $var $zero $zero] ProcessTIFFCmd vvar ii $ch $fn } save { set which image set fn {} switch -- [string tolower [lindex $var $one]] { resample { set which resample switch -- [string tolower [lindex $var $two]] { gz { # ignore set fn [lindex $var $three] } default {set fn [lindex $var $two]} } } gz { # ignore set fn [lindex $var $two] } default {set fn [lindex $var $one]} } SaveFitsFile $which $fn } default {ProcessFitsCmd vvar ii $sock $fn} } } proc ProcessSendFileCmd {proc id param} { global current if {$current(frame) != {}} { $proc $id "[$current(frame) get fits file name full]\n" } } ��������������������������������������������������������������������������������������������������./saods9/src/markeranalysispanda.tcl����������������������������������������������������������������0000644�0001750�0001750�00000006267�12064702421�016440� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerAnalysisPandaDialog {varname} { upvar #0 $varname var global $varname set id $var(id) set frame $var(frame) set vvarname panda${id}${frame} upvar #0 $vvarname vvar global $vvarname set var(panda) [info exists ${vvarname}(top)] $var(mb).analysis add checkbutton -label [msgcat::mc {Radial Profile}] \ -variable ${varname}(panda) \ -command "MarkerAnalysisPandaCmd $varname" } proc MarkerAnalysisPandaCmd {varname} { upvar #0 $varname var global $varname MarkerAnalysisPanda $var(frame) $var(id) $var(panda) } proc MarkerAnalysisPanda {frame id panda} { $frame marker $id analysis panda $panda if {$panda} { MarkerAnalysisPandaCB $frame $id set vvarname panda${id}${frame} upvar #0 $vvarname vvar global $vvarname PlotRaise $vvarname } else { MarkerAnalysisPandaDeleteCB $frame $id } } proc MarkerAnalysisPandaSystem {varname} { upvar #0 $varname var global $varname if {[info exists var(panda)]} { if {$var(panda)} { MarkerAnalysisPandaCB $var(frame) $var(id) MarkerAnalysisPandaAxisTitle $var(frame) $var(id) } } } # hardcoded marker.C proc MarkerAnalysisPandaCB {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set vvarname panda${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists var(system)]} { set vvar(system) $var(system) set sys $var(system) } elseif {[info exists vvar(system)]} { set sys $vvar(system) } else { global wcs set vvar(system) $wcs(system) set sys $wcs(system) } if {![PlotPing $vvarname]} { set tt [string totitle [$frame get marker $id type]] PlotLineDialog $vvarname $tt $tt $sys {} MarkerAnalysisPandaAxisTitle $frame $id } PlotClearData $vvarname PlotDataSet $vvarname 3 [$frame get marker $id analysis panda $sys] $vvar(proc,updategraph) $vvarname PlotStats $vvarname PlotList $vvarname } proc MarkerAnalysisPandaDeleteCB {frame id} { # this routine could be called by the region # after the dialog has been deleted set vvarname panda${id}${frame} upvar #0 $vvarname vvar global $vvarname PlotDestroy $vvarname } proc MarkerAnalysisPandaAxisTitle {frame id} { set vvarname panda${id}${frame} upvar #0 $vvarname vvar global $vvarname switch -- $vvar(system) { image - physical - amplifier - detector { set xtitle "Avg Radius (pixels)" set ytitle "Surface Brightness (cnts/pixels**2)" } default { if {[$frame has wcs equatorial $vvar(system)]} { set xtitle "Avg Radius (arcsecs)" set ytitle "Surface Brightness (cnts/arcsec**2)" } else { set xtitle "Avg Radius (pixels)" set ytitle "Surface Brightness (cnts/pixels**2)" } } } # set for plot code set vvar(graph,xaxis) $xtitle set vvar(graph,yaxis) $ytitle # update now (may not make it into plot code) $vvar(graph) xaxis configure -title $vvar(graph,xaxis) $vvar(graph) yaxis configure -title $vvar(graph,yaxis) } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catskybot.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000007724�11771107171�014416� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATSkyBot {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSkyBot $varname" } CATSkyBotVOT $varname } proc CATSkyBotVOT {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSkyBotVOT $varname" } set var(proc,parser) CATVOTParse # coord (degrees) switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { switch -- $var(sky) { fk4 - fk5 - icrs {set xx [h2d [Sex2H $var(x)]]} galactic - ecliptic {set xx [Sex2D $var(x)]} } set yy [Sex2D $var(y)] } } # size (arcmin) switch $var(rformat) { degrees { set ww $var(width) set hh $var(height) } arcmin { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } arcsec { set ww [expr $var(width)/60./60.] set hh [expr $var(height)/60./60.] } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] # output if {$var(allcols)} { set type 3 } else { set type 2 } # figure out a epoch (DATE-OBS, then DATE) global current set epoch [string trim [$current(frame) get fits header 1 keyword DATE-OBS]] if {$epoch == {}} { set epoch [string trim [$current(frame) get fits header 1 keyword DATE_OBS]] } if {$epoch == {}} { set epoch [string trim [$current(frame) get fits header 1 keyword DATE]] } if {$epoch == {}} { ARError $varname [msgcat::mc {Unable to determine date of observation}] return } # do we have a time? else check UT, UTC-OBS, UTIME, TIME-OBS set ut {} if {[string first {T} $epoch] == -1} { set ut [string trim [$current(frame) get fits header 1 keyword UT]] if {$ut == {}} { set ut [string trim [$current(frame) get fits header 1 keyword UTC-OBS]] } if {$ut == {}} { set ut [string trim [$current(frame) get fits header 1 keyword UTIME]] } if {$ut == {}} { set ut [string trim [$current(frame) get fits header 1 keyword TIME-OBS]] } if {$ut == {}} { set ut [string trim [$current(frame) get fits header 1 keyword TIME_OBS]] } if {$ut != {}} { append epoch "T$ut" } else { ARError $varname [msgcat::mc {Unable to determine time of observation}] return } } # do we finally have a date with time? set dt [split $epoch {T}] set dd [lindex $dt 0] set tt [lindex $dt 1] if {$tt != {}} { # do we have EXPTIME or EXP_TIME? set exp [string trim [$current(frame) get fits header 1 keyword EXPTIME]] if {$exp == {}} { set exp [string trim [$current(frame) get fits header 1 keyword EXP_TIME]] } if {$exp != {} && [string is double $exp]} { # ok, rebuild epoch set ttt [split $tt {:}] set total [expr [lindex $ttt 0]*60.*60. + [lindex $ttt 1]*60. + [lindex $ttt 2] + [expr $exp/2.]] set hh [format "%02d" [expr int($total/60./60.)]] set total [expr $total - $hh*60.*60.] set mm [format "%02d" [expr int($total/60.)]] set ss [format "%02.1f" [expr $total - $mm*60.]] set epoch "${dd}T${hh}:${mm}:${ss}" } } # query set var(query) [http::formatQuery EPOCH $epoch RA $xx DEC $yy SR $rr VERB $type -mime votable -loc $var(loc) -filter=0] set var(url) "http://vo.imcce.fr/webservices/skybot/skybotconesearch_query.php" CATLoad $varname } proc CATSkyBotAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for SkyBot Request for Acknowledgment of Use of SkyBot If SkyBoT was helpful for your research work, the following acknowledgment would be appreciated: "This research has made use of IMCCE's SkyBoT VO tool", or cite the following article 2006ASPC..351..367B. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } ��������������������������������������������./saods9/src/nameres.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000013645�12102534471�014040� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc NRESDef {} { global nres global inres global pnres set inres(top) .nres set inres(mb) .nresmb # set via wcs() set nres(system) wcs set nres(sky) fk5 set nres(skyformat) degrees # prefs only set pnres(server) simbad-cds } proc NRESApply {varname sync} { upvar #0 $varname var global $varname set var(sync) $sync ARApply $varname if {$var(name)!={}} { NSVRServer $varname } else { ARStatus $varname "Please specify an Object Name" ARReset $varname } } proc NRESDialog {} { global nres global inres global ds9 global pds9 if [winfo exists $inres(top)] { raise $inres(top) return } set varname dnres upvar #0 $varname var global $varname # AR variables ARInit $varname {} # Variables set var(top) $inres(top) set var(mb) $inres(mb) set var(system) $nres(system) set var(sky) $nres(sky) set var(skyformat) $nres(skyformat) # create the window set w $var(top) set mb $var(mb) Toplevel $w $mb 6 [msgcat::mc {Name Resolution}] "ARDestroy $varname" # file $mb add cascade -label File -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Retrieve}] \ -command "NRESApply $varname 0" $mb.file add command -label [msgcat::mc {Cancel}] \ -command "ARCancel $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Pan To}] \ -command "NRESPan $varname" $mb.file add command -label [msgcat::mc {Crosshair To}] \ -command "NRESCrosshair $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "ARDestroy $varname" # edit AREditMenu $varname # name server NSVRServerMenu $varname # Param set f [ttk::frame $w.param] ttk::label $f.nametitle -text [msgcat::mc {Object}] ttk::entry $f.name -textvariable ${varname}(name) -width 48 ttk::label $f.sky -textvariable ${varname}(sky) -anchor w set var(xname) [ttk::label $f.xtitle -text {} -width 1] ttk::label $f.x -textvariable ${varname}(x) -width 14 -relief groove set var(yname) [ttk::label $f.ytitle -text {} -width 1] ttk::label $f.y -textvariable ${varname}(y) -width 14 -relief groove ARSkyFormat $f.skyformat $varname grid $f.nametitle x $f.name - - - - -padx 2 -pady 2 -sticky w grid $f.sky $f.xtitle $f.x $f.ytitle $f.y $f.skyformat \ -padx 2 -pady 2 -sticky w # Status set f [ttk::frame $w.status] ttk::label $f.tstatus -text [msgcat::mc {Status}] ttk::label $f.status -textvariable ${varname}(status) grid $f.tstatus $f.status -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] set var(apply) [ttk::button $f.apply -text [msgcat::mc {Retrieve}] \ -command "NRESApply $varname 0"] set var(cancel) [ttk::button $f.cancel -text [msgcat::mc {Cancel}] \ -command "ARCancel $varname" -state disabled] ttk::button $f.close -text [msgcat::mc {Close}] \ -command "ARDestroy $varname" pack $f.apply $f.cancel $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal ttk::separator $w.sep2 -orient horizontal pack $w.buttons $w.sep $w.status $w.sep2 -side bottom -fill x pack $w.param -side top -fill both -expand true ARCoord $varname ARStatus $varname {} } proc NRESPan {varname} { upvar #0 $varname var global $varname if {($var(x) != {}) && ($var(y) != {})} { PanTo $var(x) $var(y) $var(system) $var(sky) } } proc NRESCrosshair {varname} { upvar #0 $varname var global $varname global current if {($current(frame) != {})} { if {[$current(frame) has wcs equatorial $var(system)]} { if {($var(x) != {}) && ($var(y) != {})} { set current(mode) crosshair ChangeMode $current(frame) crosshair \ $var(system) $var(sky) $var(x) $var(y) } } } } # Prefs proc PrefsDialogNRES {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Name Server}] lappend dprefs(tabs) [ttk::frame $w.namesvr] set f [ttk::labelframe $w.namesvr.params -text [msgcat::mc {Name Server}]] ttk::label $f.tsvr -text [msgcat::mc {Default}] ttk::menubutton $f.svr -textvariable pnres(server) -menu $f.svr.menu menu $f.svr.menu NSVRServerMenuItems $f.svr.menu grid $f.tsvr $f.svr -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } # Process Cmds proc ProcessNRESCmd {varname iname} { upvar $varname var upvar $iname i set vvarname dnres upvar #0 $vvarname vvar global $vvarname global nres global pnres NRESDialog switch -- [string tolower [lindex $var $i]] { {} - open {} close {ARDestroy $vvarname} server { incr i set pnres(server) [lindex $var $i] } pan {NRESPan $vvarname} crosshair {NRESCrosshair $vvarname} format - skyformat { incr i switch -- [string tolower [lindex $var $i]] { deg - degree - degrees { set vvar(skyformat) degrees set vvar(skyformat,msg) $vvar(skyformat) } default { set vvar(skyformat) [string tolower [lindex $var $i]] set vvar(skyformat,msg) $vvar(skyformat) } } } name { incr i set vvar(name) [lindex $var $i] NRESApply $vvarname 1 } default { set vvar(name) [lindex $var $i] NRESApply $vvarname 1 } } } proc ProcessSendNRESCmd {proc id param} { global nres global pnres global dnres NRESDialog switch -- [string tolower [lindex $param 0]] { server {$proc $id "$pnres(server)\n"} format - skyformat {$proc $id "$dnres(skyformat)\n"} name - {} {$proc $id "$dnres(name)\n"} default { set dnres(name) [lindex $param 0] NRESApply dnres 1 $proc $id "$dnres(x) $dnres(y)\n" } } } �������������������������������������������������������������������������������������������./saods9/src/ar.tcl���������������������������������������������������������������������������������0000644�0001750�0001750�00000011072�11700665566�013015� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ARInit {varname next} { upvar #0 $varname var global $varname set var(sync) 0 set var(proc,next) $next set var(name) {} set var(x) {} set var(y) {} set var(status) {} } proc ARApply {varname} { upvar #0 $varname var global $varname ARStatus $varname {} $var(mb).file entryconfig [msgcat::mc {Retrieve}] -state disabled $var(mb).file entryconfig [msgcat::mc {Cancel}] -state normal $var(apply) configure -state disabled $var(cancel) configure -state normal } proc ARCancel {varname} { upvar #0 $varname var global $varname # set state to 0 so that we don't process the finish proc set var(active) 0 if {[info exists var(token)]} { http::reset $var(token) } } proc ARDestroy {varname} { upvar #0 $varname var global $varname ARCancel $varname if {[winfo exists $var(top)]} { destroy $var(top) destroy $var(mb) } unset $varname } proc ARReset {varname} { upvar #0 $varname var global $varname set var(active) 0 if {[info exists var(token)]} { http::cleanup $var(token) unset var(token) } $var(mb).file entryconfig [msgcat::mc {Retrieve}] -state normal $var(mb).file entryconfig [msgcat::mc {Cancel}] -state disabled $var(apply) configure -state normal $var(cancel) configure -state disabled } proc ARDone {varname} { upvar #0 $varname var global $varname set var(status) {Done} ARReset $varname } proc ARCancelled {varname} { upvar #0 $varname var global $varname set var(status) {Cancelled} ARReset $varname } proc ARError {varname message} { upvar #0 $varname var global $varname set var(status) $message ARReset $varname } proc ARStatus {varname message} { upvar #0 $varname var global $varname set var(status) $message } proc ARClear {varname} { upvar #0 $varname var global $varname set var(name) {} set var(x) {} set var(y) {} set var(status) {} } proc ARCoord {varname} { upvar #0 $varname var global $varname global ds9 global pds9 switch -- $var(sky) { fk4 - fk5 - icrs { $var(xname) configure -text "\u03b1" \ -font "symbol $pds9(font,size)" $var(yname) configure -text "\u03b4" \ -font "symbol $pds9(font,size)" } galactic { $var(xname) configure -text {l} \ -font "{$ds9(times)} $pds9(font,size) normal italic" $var(yname) configure -text {b} \ -font "{$ds9(times)} $pds9(font,size) normal italic" } ecliptic { $var(xname) configure -text "\u03bb" \ -font "symbol $pds9(font,size)" $var(yname) configure -text "\u03b2" \ -font "symbol $pds9(font,size)" } } } proc AREditMenu {varname} { upvar #0 $varname var global $varname global ds9 $var(mb) add cascade -label [msgcat::mc {Edit}] -menu $var(mb).edit EditMenu $var(mb) $varname $var(mb).edit add separator $var(mb).edit add command -label [msgcat::mc {Clear}] \ -command "ARClear $varname" } proc ARSkyFormat {w varname} { upvar #0 $varname var global $varname set ${varname}(skyformat,msg) [msgcat::mc $var(skyformat)] ttk::menubutton $w -textvariable ${varname}(skyformat,msg) -menu $w.menu menu $w.menu $w.menu add radiobutton -label [msgcat::mc {Degrees}] \ -variable ${varname}(skyformat) -value degrees \ -command "ARSkyFormatMenu $varname" $w.menu add radiobutton -label {Sexagesimal} \ -variable ${varname}(skyformat) -value sexagesimal \ -command "ARSkyFormatMenu $varname" } proc ARSkyFormatMenu {varname} { upvar #0 $varname var global $varname set ${varname}(skyformat,msg) $var(skyformat) } proc ARRFormat {w varname} { upvar #0 $varname var global $varname set ${varname}(rformat,msg) [msgcat::mc $var(rformat)] ttk::menubutton $w -textvariable ${varname}(rformat,msg) -menu $w.menu menu $w.menu $w.menu add radiobutton -label [msgcat::mc {Degrees}] \ -variable ${varname}(rformat) -value degrees \ -command "ARRFormatMenu $varname" $w.menu add radiobutton -label [msgcat::mc {ArcMin}] \ -variable ${varname}(rformat) -value arcmin \ -command "ARRFormatMenu $varname" $w.menu add radiobutton -label [msgcat::mc {ArcSec}] \ -variable ${varname}(rformat) -value arcsec \ -command "ARRFormatMenu $varname" } proc ARRFormatMenu {varname} { upvar #0 $varname var global $varname set ${varname}(rformat,msg) $var(rformat) } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/sao.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000007025�11727463046�013176� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SAODef {} { global sao global isao set isao(top) .sao set isao(mb) .saomb set sao(sky) fk5 set sao(rformat) arcmin set sao(width) 15 set sao(height) 15 set sao(mode) new set sao(save) 0 set sao(valid) 0 set sao(survey) dss } proc SAODialog {} { global sao global isao global wcs if [winfo exists $isao(top)] { raise $isao(top) return } set varname dsao upvar #0 $varname var global $varname set var(top) $isao(top) set var(mb) $isao(mb) set var(sky) $sao(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $sao(rformat) set var(width) $sao(width) set var(height) $sao(height) set var(mode) $sao(mode) set var(save) $sao(save) set var(valid) $sao(valid) set var(survey) $sao(survey) set w $var(top) IMGSVRInit $varname "SAO-DSS [msgcat::mc {Server}]" SAOExec SAOAck IMGSVRUpdate $varname 1 } proc SAOExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set compress no set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set compress gzip set var(fn) [tmpnam ds9sao ".fits.gz"] } # skyformat switch -- $var(skyformat) { degrees { set xx [uformat d h: $var(x)] set yy [uformat d d: $var(y)] } sexagesimal { set xx $var(x) set yy $var(y) } } # size - convert to arcmin switch -- $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } if {$ww>60} { set ww 60 } if {$hh>60} { set hh 60 } # query set var(query) [http::formatQuery r $xx d $yy e J2000 w $ww h $ww c $compress] set var(url) "http://www.cfa.harvard.edu/archive/dss" IMGSVRLoad $varname } proc SAOAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the DSS-SAO The Digitized Sky Surveys were produced at the Space Telescope Science Institute under U.S. Government grant NAG W-2166. The images of these surveys are based on photographic data obtained using the Oschin Schmidt Telescope on Palomar Mountain and the UK Schmidt Telescope. The plates were processed into the present compressed digital form with the permission of these institutions. The Oschin Schmidt Telescope is operated by the California Institute of Technology and Palomar Observatory. The UK Schmidt Telescope was operated by the Royal Observatory Edinburgh, with funding from the UK Science and Engineering Research Council (later the UK Particle Physics and Astronomy Research Council), until 1988 June, and thereafter by the Anglo-Australian Observatory. The blue plates of the southern Sky Atlas and its Equatorial Extension (together known as the SERC-J), as well as the Equatorial Red (ER), and the Second Epoch [red] Survey (SES) were all taken with the UK Schmidt. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessSAOCmd {varname iname} { upvar $varname var upvar $iname i SAODialog IMGSVRProcessCmd $varname $iname dsao } proc ProcessSendSAOCmd {proc id param} { SAODialog IMGSVRProcessSendCmd $proc $id $param dsao } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markeranalysisplot3d.tcl���������������������������������������������������������������0000644�0001750�0001750�00000011662�12064702421�016555� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerAnalysisPlot3dDialog {varname} { upvar #0 $varname var global $varname global marker set id $var(id) set frame $var(frame) set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname set var(plot3d) [info exists ${vvarname}(top)] set var(method) average $var(mb).analysis add checkbutton -label [msgcat::mc {Plot 3D}] \ -variable ${varname}(plot3d) \ -command "MarkerAnalysisPlot3dCmd $varname" $var(mb).analysis add separator $var(mb).analysis add cascade \ -label [msgcat::mc {Method}] \ -menu $var(mb).analysis.method menu $var(mb).analysis.method $var(mb).analysis.method add radiobutton \ -label [msgcat::mc {Average}] \ -variable ${varname}(method) -value average \ -command "MarkerAnalysisPlot3dMethod $varname" $var(mb).analysis.method add radiobutton \ -label [msgcat::mc {Sum}] \ -variable ${varname}(method) -value sum \ -command "MarkerAnalysisPlot3dMethod $varname" } # support proc MarkerAnalysisPlot3dCmd {varname} { upvar #0 $varname var global $varname MarkerAnalysisPlot3d $var(frame) $var(id) $var(plot3d) } proc MarkerAnalysisPlot3d {frame id plot} { $frame marker $id analysis plot3d $plot if {$plot} { MarkerAnalysisPlot3dCB $frame $id set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname PlotRaise $vvarname } else { MarkerAnalysisPlot3dDeleteCB $frame $id } } proc MarkerAnalysisPlot3dMethod {varname} { upvar #0 $varname var global $varname if {[info exists var(plot3d)]} { if {$var(plot3d)} { MarkerAnalysisPlot3dCB $var(frame) $var(id) MarkerAnalysisPlot3dYAxisTitle $var(frame) $var(id) } } } proc MarkerAnalysisPlot3dSystem {varname} { upvar #0 $varname var global $varname if {[info exists var(plot3d)]} { if {$var(plot3d)} { MarkerAnalysisPlot3dCB $var(frame) $var(id) MarkerAnalysisPlot3dXAxisTitle $var(frame) $var(id) } } } # hardcoded marker.C proc MarkerAnalysisPlot3dCB {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists var(system)]} { set vvar(system) $var(system) set sys $var(system) } elseif {[info exists vvar(system)]} { set sys $vvar(system) } else { global wcs set vvar(system) $wcs(system) set sys $wcs(system) } if {[info exists var(method)]} { set vvar(method) $var(method) set method $var(method) } elseif {[info exists vvar(method)]} { set method $vvar(method) } else { set vvar(method) average set method average } set xdata plot3d${id}${frame}x set ydata plot3d${id}${frame}y global $xdata $ydata if {[PlotPing $vvarname]} { $frame get marker $id analysis plot3d $xdata $ydata $sys $method PlotStats $vvarname PlotList $vvarname } else { set tt [string totitle [$frame get marker $id type]] PlotLineDialog $vvarname $tt $tt $sys Counts MarkerAnalysisPlot3dXAxisTitle $frame $id MarkerAnalysisPlot3dYAxisTitle $frame $id set vvar(manage) 0 set vvar(dim) xy set vvar(xdata) $xdata set vvar(ydata) $ydata set vvar(xedata) {} set vvar(yedata) {} blt::vector create $xdata $ydata $frame get marker $id analysis plot3d $xdata $ydata $sys $method PlotExternal $vvarname $vvar(proc,createelement) $vvarname $vvar(proc,updateelement) $vvarname $vvar(proc,updategraph) $vvarname PlotStats $vvarname PlotList $vvarname } } # hardcoded marker.C proc MarkerAnalysisPlot3dDeleteCB {frame id} { # this routine could be called by the region # after the dialog has been deleted set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname # clear any errors global errorInfo set errorInfo {} PlotDestroy $vvarname } proc MarkerAnalysisPlot3dXAxisTitle {frame id} { set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname switch -- $vvar(system) { image - physical - amplifier - detector {set title "$vvar(system)"} default { set w [string range $vvar(system) 3 3] set tt [string trim [$frame get fits header 1 keyword \{CTYPE3$w\}]] if {$tt != {}} { set title "$tt" } else { set title "$vvar(system)" } } } # set for plot code set vvar(graph,xaxis) $title # update now (may not make it into plot code) $vvar(graph) xaxis configure -title $vvar(graph,xaxis) } proc MarkerAnalysisPlot3dYAxisTitle {frame id} { set vvarname plot3d${id}${frame} upvar #0 $vvarname vvar global $vvarname # set for plot code set vvar(graph,yaxis) "Counts [string totitle $vvar(method)]" # update now (may not make it into plot code) $vvar(graph) yaxis configure -title $vvar(graph,yaxis) } ������������������������������������������������������������������������������./saods9/src/photo.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000013502�12131065211�013520� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ImportPhotoFile {fn mode} { global loadParam set loadParam(file,type) photo set loadParam(file,mode) $mode set loadParam(load,type) photo # find stdin if {[string range $fn 0 4] == "stdin" || [string range $fn 0 4] == "STDIN" || [string range $fn 0 0] == "-"} { fconfigure stdin -translation binary -encoding binary if {[catch {image create photo -data [read -nonewline stdin]} ph]} { Error [msgcat::mc {An error has occurred while reading image.}] return } set loadParam(file,name) stdin } else { if {[catch {image create photo -file $fn} ph]} { Error [msgcat::mc {An error has occurred while reading image.}] return } set loadParam(file,name) $fn } set loadParam(var,name) $ph # mask not supported set loadParam(load,layer) {} ProcessLoad image delete $ph } proc ImportPhotoAlloc {path fn mode} { global loadParam set loadParam(file,type) photo set loadParam(file,mode) $mode set loadParam(load,type) photo if {[catch {image create photo -file $path} ph]} { Error [msgcat::mc {An error has occurred while reading image.}] return } set loadParam(file,name) $fn set loadParam(var,name) $ph # mask not supported set loadParam(load,layer) {} ProcessLoad image delete $ph } proc ImportPhotoSocket {ch fn mode} { global loadParam set loadParam(file,type) photo set loadParam(file,mode) $mode set loadParam(load,type) photo set loadParam(file,name) $fn fconfigure $ch -translation binary -encoding binary if {[catch {image create photo -data [read $ch]} ph]} { Error [msgcat::mc {An error has occurred while reading image.}] return 0 } set loadParam(var,name) $ph # mask not supported set loadParam(load,layer) {} set rr [ProcessLoad 0] image delete $ph return $rr } proc ExportPhotoFile {fn format opt} { global export global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } if {[catch {image create photo} ph]} { Error [msgcat::mc {An error has occurred while creating image.}] return } $current(frame) save photo $ph set ff $format switch -- $format { jpeg { if {$opt == {}} { set opt $export(jpeg,quality) } set ff [list $format -quality $opt] } tiff { if {$opt == {}} { set opt $export(tiff,compress) } set ff [list $format -compression $opt] } } if {[catch {$ph write $fn -format $ff}]} { Error [msgcat::mc {An error has occurred while writing image.}] } image delete $ph } proc ExportPhotoSocket {ch format opt} { global export global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } if {[catch {image create photo} ph]} { Error [msgcat::mc {An error has occurred while creating image.}] return } $current(frame) save photo $ph fconfigure $ch -translation binary -encoding binary set ff $format switch -- $format { jpeg { if {$opt == {}} { set opt $export(jpeg,quality) } set ff [list $format -quality $opt] } tiff { if {$opt == {}} { set opt $export(tiff,compress) } set ff [list $format -compression $opt] } } if {[catch {$ph data -format $ff} data]} { Error [msgcat::mc {An error has occurred while writing image.}] return } puts -nonewline $ch [base64::decode $data] image delete $ph } # Process Cmds proc ProcessGIFCmd {varname iname ch fn} { upvar $varname var upvar $iname i ProcessPhotoCmd $varname $iname $ch $fn } proc ProcessJPEGCmd {varname iname ch fn} { upvar $varname var upvar $iname i ProcessPhotoCmd $varname $iname $ch $fn } proc ProcessPNGCmd {varname iname ch fn} { upvar $varname var upvar $iname i ProcessPhotoCmd $varname $iname $ch $fn } proc ProcessTIFFCmd {varname iname ch fn} { upvar $varname var upvar $iname i ProcessPhotoCmd $varname $iname $ch $fn } proc ProcessPhotoCmd {varname iname ch fn} { upvar 2 $varname var upvar 2 $iname i global loadParam global current set mode {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i # not supported } slice { incr i set mode slice } } set param [lindex $var $i] StartLoad if {$ch != {}} { # xpa global ds9 switch $ds9(wm) { x11 - aqua { if {![ImportPhotoSocket $ch $param $mode]} { InitError xpa ImportPhotoFile $param $mode } } win32 {ImportPhotoFile $param $mode} } } else { # comm if {$fn != {}} { ImportPhotoAlloc $fn $param $mode } else { ImportPhotoFile $param $mode } } FinishLoad } proc ProcessSendGIFCmd {proc id param ch fn} { global current ProcessSendPhotoCmd gif $proc $id $param $ch $fn } proc ProcessSendJPEGCmd {proc id param ch fn} { global current ProcessSendPhotoCmd jpeg $proc $id $param $ch $fn } proc ProcessSendPNGCmd {proc id param ch fn} { global current ProcessSendPhotoCmd png $proc $id $param $ch $fn } proc ProcessSendTIFFCmd {proc id param ch fn} { global current ProcessSendPhotoCmd tiff $proc $id $param $ch $fn } proc ProcessSendPhotoCmd {format proc id param ch fn} { global current global export if {$current(frame) == {}} { return } set opt [string tolower [lindex $param 0]] if {$ch != {}} { # xpa global ds9 switch $ds9(wm) { x11 - aqua {ExportPhotoSocket $ch $format $opt} win32 {} } } elseif {$fn != {}} { # comm ExportPhotoFile $fn $format $opt $proc $id {} $fn } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotelement.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000011716�12033123212�014721� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotCreateErrorX {varname} { upvar #0 $varname var global $varname set nn $var(data,current) set err {} # delete markers foreach mk [$var(graph) marker names "m-${nn}-x*"] { $var(graph) marker delete $mk } global $var(xdata) $var(ydata) $var(xedata) set ll [$var(xdata) length] set xx [$var(xdata) range] set yy [$var(ydata) range] set xe [$var(xedata) range] for {set ii 0} {$ii<$ll} {incr ii} { set x [lindex $xx $ii] set y [lindex $yy $ii] set e [lindex $xe $ii] $var(graph) marker create line \ -name "m-${nn}-x${ii}" \ -coords "[expr $x+$e] $y [expr $x-$e] $y" \ -linewidth $var(error,width) \ -outline $var(error,color) } } proc PlotCreateErrorY {varname} { upvar #0 $varname var global $varname set nn $var(data,current) set err {} # delete markers foreach mk [$var(graph) marker names "m-${nn}-y*"] { $var(graph) marker delete $mk } global $var(xdata) $var(ydata) $var(yedata) set ll [$var(xdata) length] set xx [$var(xdata) range] set yy [$var(ydata) range] set ye [$var(yedata) range] for {set ii 0} {$ii<$ll} {incr ii} { set x [lindex $xx $ii] set y [lindex $yy $ii] set e [lindex $ye $ii] $var(graph) marker create line \ -name "m-${nn}-y${ii}" \ -coords "$x [expr $y-$e] $x [expr $y+$e] " \ -linewidth $var(error,width) \ -outline $var(error,color) } } proc PlotUpdateElementDiscrete {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,discrete,color) $var(discrete,color) set var($nn,discrete,symbol) $var(discrete,symbol) set var($nn,discrete,fill) $var(discrete,fill) if {$var(discrete)} { if {$var(discrete,fill)} { set clr $var(discrete,color) } else { set clr {} } $var(graph) element configure "d-${nn}" \ -outline $var(discrete,color) -color $var(discrete,color) \ -symbol $var(discrete,symbol) -fill $clr } } proc PlotUpdateElementLinear {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,linear,color) $var(linear,color) set var($nn,linear,width) $var(linear,width) if {$var(linear)} { if {$var(linear,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element configure "l-${nn}" \ -linewidth $var(linear,width) -dashes $dash \ -color $var(linear,color) } } proc PlotUpdateElementStep {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,step,color) $var(step,color) set var($nn,step,width) $var(step,width) if {$var(step)} { if {$var(step,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element configure "s-${nn}" \ -linewidth $var(step,width) -dashes $dash \ -color $var(step,color) } } proc PlotUpdateElementQuadratic {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,quadratic,color) $var(quadratic,color) set var($nn,quadratic,width) $var(quadratic,width) if {$var(quadratic)} { if {$var(quadratic,dash) == {yes}} { set dash {8 3} } else { set dash { } } $var(graph) element configure "q-${nn}" \ -linewidth $var(quadratic,width) -dashes $dash \ -color $var(quadratic,color) } } proc PlotUpdateElementBar {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,bar,color) $var(bar,color) if {$var(bar)} { switch $var(bar,color) { black {set clr "#000001"} default {set clr $var(bar,color)} } $var(graph) element configure "b-${nn}" \ -foreground $clr -background $clr } } proc PlotUpdateElementError {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } set nn $var(data,current) set var($nn,error,color) $var(error,color) set var($nn,error,width) $var(error,width) foreach mk [$var(graph) marker names "m-${nn}*"] { $var(graph) marker configure $mk \ -linewidth $var(error,width) \ -outline $var(error,color) } } proc PlotHighliteElement {varname rowlist} { upvar #0 $varname var global $varname # rowlist starts at 1 set result {} foreach rr $rowlist { append result "[expr $rr-1] " } $var(proc,highlite) $varname $result } ��������������������������������������������������./saods9/src/rgbarray.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000007051�12130604640�014206� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ImportRGBArrayFile {fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d {return} rgb {} } set loadParam(file,type) array set loadParam(file,mode) {rgb cube} set loadParam(load,type) mmapincr # if no zdim is present, insert one set exp {.*\[.*zdim[ ]*=[ ]*[0-9]+} if {![regexp $exp $fn]} { set i [string last "\]" $fn] set fn "[string range $fn 0 [expr $i-1]],zdim=3\]" } set loadParam(file,name) $fn # mask not supported set loadParam(load,layer) {} # check for stdin/gz ConvertArrayFile ProcessLoad } proc ImportRGBArrayAlloc {path fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d {return} rgb {} } set loadParam(file,type) array set loadParam(file,mode) {rgb cube} set loadParam(load,type) allocgz # if no zdim is present, insert one set exp {.*\[.*zdim[ ]*=[ ]*[0-9]+} if {![regexp $exp $fn]} { set i [string last "\]" $fn] set fn "[string range $fn 0 [expr $i-1]],zdim=3\]" } if {![regexp $exp $path]} { set i [string last "\]" $path] set path "[string range $path 0 [expr $i-1]],zdim=3\]" } set loadParam(file,name) $fn set loadParam(file,fn) $path # mask not supported set loadParam(load,layer) {} ProcessLoad } proc ImportRGBArraySocket {sock fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d {return} rgb {} } set loadParam(file,type) array set loadParam(file,mode) {rgb cube} set loadParam(load,type) socketgz # if no zdim is present, insert one set exp {.*\[.*zdim[ ]*=[ ]*[0-9]+} if {![regexp $exp $fn]} { set i [string last "\]" $fn] set fn "[string range $fn 0 [expr $i-1]],zdim=3\]" } set loadParam(file,name) $fn set loadParam(socket,id) $sock # mask not supported set loadParam(load,layer) {} return [ProcessLoad 0] } proc ExportRGBArrayFile {fn opt} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save array rgb cube file "\{$fn\}" $opt } proc ExportRGBArraySocket {sock opt} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save array rgb cube socket $sock $opt } proc ProcessRGBArrayCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current switch -- [string tolower [lindex $var $i]] { new { incr i CreateRGBFrame } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![ImportRGBArraySocket $sock $param]} { InitError xpa ImportRGBArrayFile $param } } else { # comm if {$fn != {}} { ImportRGBArrayAlloc $fn $param } else { ImportRGBArrayFile $param } } FinishLoad } proc ProcessSendRGBArrayCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } set opt [string tolower [lindex $param 0]] if {$sock != {}} { # xpa ExportRGBArraySocket $sock $opt } elseif {$fn != {}} { # comm ExportRGBArrayFile $fn $opt $proc $id {} $fn } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaicimagewcs.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000005252�12130604726�015376� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMosaicImageWCSFile {fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic image $sys] set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer ConvertFitsFile ProcessLoad } proc LoadMosaicImageWCSAlloc {path fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic image $sys] set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc LoadMosaicImageWCSSocket {sock fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic image $sys] set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc SaveMosaicImageWCSFile {fn} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits mosaic image file "\{$fn\}" } proc SaveMosaicImageWCSSocket {sock} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits mosaic image socket $sock } proc ProcessMosaicImageWCSCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } if {[string range [lindex $var $i] 0 2] == {wcs}} { set opt [lindex $var $i] incr i } else { set opt wcs } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMosaicImageWCSSocket $sock $param $layer $opt]} { InitError xpa LoadMosaicImageWCSFile $param $layer $opt } } else { # comm if {$fn != {}} { LoadMosaicImageWCSAlloc $fn $param $layer $opt } else { LoadMosaicImageWCSFile $param $layer $opt } } FinishLoad } proc ProcessSendMosaicImageWCSCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } if {$sock != {}} { # xpa SaveMosaicImageWCSSocket $sock } elseif {$fn != {}} { # comm SaveMosaicImageWCSFile $fn $proc $id {} $fn } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/graph.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000025150�11700665567�013517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc GraphDef {} { global igraph global pgraph set igraph(horz,id) 0 set igraph(vert,id) 0 set igraph(size) 150 set igraph(gap,x) 50 set igraph(gap,y) 25 set igraph(x,min) 0 set igraph(x,max) 10 set igraph(y,min) 1 set igraph(y,max) 100 global graphHorzX graphHorzY global graphVertX graphVertY global histX histY blt::vector create graphHorzX graphHorzY blt::vector create graphVertX graphVertY blt::vector create histX histY # prefs only set pgraph(horz,grid) 1 set pgraph(horz,log) false set pgraph(vert,grid) 1 set pgraph(vert,log) false } proc CreateGraphs {} { global igraph global ds9 global canvas # Horizontal Graph set ds9(graph,horz) [blt::graph $ds9(main).horz \ -width $canvas(width) -height $igraph(size) \ -takefocus 0 \ -background $ds9(bg) \ -plotrelief groove \ -plotborderwidth 2 \ -plotbackground $ds9(bg) \ -font [font actual TkDefaultFont] \ ] # we need to manually set the element foreground color, i.e. use graph fg set fgcolor [$ds9(graph,horz) cget -foreground] $ds9(graph,horz) legend configure -hide yes $ds9(graph,horz) crosshairs configure -color green $ds9(graph,horz) xaxis configure -hide no -showticks no $ds9(graph,horz) x2axis configure -hide yes $ds9(graph,horz) yaxis configure -hide yes $ds9(graph,horz) y2axis configure -hide no \ -tickfont [font actual TkDefaultFont] $ds9(graph,horz) element create line1 -xdata graphHorzX -ydata graphHorzY \ -color $fgcolor -symbol {} bind $ds9(graph,horz) <Enter> [list EnterGraph $ds9(graph,horz) 1] bind $ds9(graph,horz) <Leave> [list LeaveGraph $ds9(graph,horz)] bind $ds9(graph,horz) <Button-1> \ [list MotionGraph $ds9(graph,horz) %x %y 1] bind $ds9(graph,horz) <B1-Motion> \ [list MotionGraph $ds9(graph,horz) %x %y 1] bind $ds9(graph,horz) <Up> [list ArrowKeyGraph $ds9(graph,horz) 0 -1 1] bind $ds9(graph,horz) <Down> [list ArrowKeyGraph $ds9(graph,horz) 0 1 1] bind $ds9(graph,horz) <Left> [list ArrowKeyGraph $ds9(graph,horz) -1 0 1] bind $ds9(graph,horz) <Right> [list ArrowKeyGraph $ds9(graph,horz) 1 0 1] # Vertical Graph set ds9(graph,vert) [blt::graph $ds9(main).vert \ -width $igraph(size) -height $canvas(height) \ -invertxy yes \ -takefocus 0 \ -background $ds9(bg) \ -plotrelief groove \ -plotborderwidth 2 \ -plotbackground $ds9(bg) ] $ds9(graph,vert) legend configure -hide yes $ds9(graph,vert) crosshairs configure -color green $ds9(graph,vert) xaxis configure -hide yes -descending yes $ds9(graph,vert) x2axis configure -hide no -descending yes -showticks no $ds9(graph,vert) yaxis configure -hide no -descending yes \ -tickfont [font actual TkDefaultFont] $ds9(graph,vert) y2axis configure -hide yes -descending yes $ds9(graph,vert) element create line1 -xdata graphVertX -ydata graphVertY \ -color $fgcolor -symbol {} bind $ds9(graph,vert) <Enter> [list EnterGraph $ds9(graph,vert) 0] bind $ds9(graph,vert) <Leave> [list LeaveGraph $ds9(graph,vert)] bind $ds9(graph,vert) <Button-1> \ [list MotionGraph $ds9(graph,vert) %x %y 0] bind $ds9(graph,vert) <B1-Motion> \ [list MotionGraph $ds9(graph,vert) %x %y 0] bind $ds9(graph,vert) <Up> [list ArrowKeyGraph $ds9(graph,vert) 0 -1 0] bind $ds9(graph,vert) <Down> [list ArrowKeyGraph $ds9(graph,vert) 0 1 0] bind $ds9(graph,vert) <Left> [list ArrowKeyGraph $ds9(graph,vert) -1 0 0] bind $ds9(graph,vert) <Right> [list ArrowKeyGraph $ds9(graph,vert) 1 0 0] UpdateGraphGrid } proc UpdateGraphFont {} { global ds9 $ds9(graph,horz) y2axis configure -tickfont [font actual TkDefaultFont] $ds9(graph,vert) yaxis configure -tickfont [font actual TkDefaultFont] } proc UpdateGraphGrid {} { global pgraph global ds9 $ds9(graph,horz) xaxis configure -grid $pgraph(horz,grid) -tickdefault 4 $ds9(graph,horz) y2axis configure -grid $pgraph(horz,grid) $ds9(graph,vert) x2axis configure -grid $pgraph(vert,grid) $ds9(graph,vert) yaxis configure -grid $pgraph(vert,grid) -tickdefault 4 } proc UpdateGraphXAxis {which} { global ds9 global view # don't update if {!$ds9(idletasks)} { return } global debug if {$debug(tcl,update)} { puts stderr "UpdateGraphXAxis" } if {$view(graph,horz) || $view(graph,vert)} { global debug if {$debug(tcl,idletasks)} { puts stderr "UpdateGraphXAxis" } update idletasks } if {$view(graph,horz)} { UpdateGraphXAxisHV $which $ds9(graph,horz) graphHorzX graphHorzY 1 } if {$view(graph,vert)} { UpdateGraphXAxisHV $which $ds9(graph,vert) graphVertX graphVertY 0 } } proc UpdateGraphXAxisHV {which what vectorX vectorY cut} { global igraph global graphHorzX graphHorzY global graphVertX graphVertY if {$which != {}} { set xMin [expr "$$vectorX\(min\)"] set xMax [expr "$$vectorX\(max\)"] $what xaxis configure -min $xMin -max $xMax $what x2axis configure -min $xMin -max $xMax } else { $what xaxis configure -min $igraph(x,min) -max $igraph(x,max) $what x2axis configure -min $igraph(x,min) -max $igraph(x,max) } } proc UpdateGraphYAxis {which} { global pgraph global ds9 global view # don't update if {!$ds9(idletasks)} { return } global debug if {$debug(tcl,update)} { puts stderr "UpdateGraphYAxis" } if {$view(graph,horz) || $view(graph,vert)} { global debug if {$debug(tcl,idletasks)} { puts stderr "UpdateGraphYAxis" } update idletasks } if {$view(graph,horz)} { UpdateGraphYAxisHV $which $ds9(graph,horz) $pgraph(horz,log) } if {$view(graph,vert)} { UpdateGraphYAxisHV $which $ds9(graph,vert) $pgraph(vert,log) } } proc UpdateGraphYAxisHV {which what log} { global igraph if {$which != {}} { set minmax [$which get clip] set yMin [lindex $minmax 0] set yMax [lindex $minmax 1] if {$yMin >= $yMax} { set yMax [expr $yMin + 1] } $what yaxis configure -min $yMin -max $yMax -logscale $log -tickdefault 4 $what y2axis configure -min $yMin -max $yMax -logscale $log -tickdefault 4 } else { $what yaxis configure -min $igraph(y,min) -max $igraph(y,max) \ -logscale $log -tickdefault 4 $what y2axis configure -min $igraph(y,min) -max $igraph(y,max) \ -logscale $log -tickdefault 4 } } proc ShowGraphData {which} { global ds9 global view if {$view(graph,horz)} { ShowGraphDataHV $which $ds9(graph,horz) } if {$view(graph,vert)} { ShowGraphDataHV $which $ds9(graph,vert) } } proc ShowGraphDataHV {which what} { if {$which != {}} { if {[$which has fits]} { $what element configure line1 -hide no } else { $what element configure line1 -hide yes } } else { $what element configure line1 -hide yes } } proc ClearGraphData {} { global ds9 global view if {$view(graph,horz)} { $ds9(graph,horz) element configure line1 -hide yes } if {$view(graph,vert)} { $ds9(graph,vert) element configure line1 -hide yes } } proc UpdateGraph {which x y sys} { global ds9 global view if {[$which has fits]} { if {$view(graph,horz)} { $which get horizontal cut graphHorzX graphHorzY $x $y $sys $ds9(graph,horz) element configure line1 -hide no } if {$view(graph,vert)} { $which get vertical cut graphVertX graphVertY $x $y $sys $ds9(graph,vert) element configure line1 -hide no } } } proc EnterGraph {which horz} { global current focus $which $which crosshairs on if {$current(frame) != {} && $current(mode) == "crosshair"} { set cursor [$which crosshairs cget -position] scan $cursor "@%d,%d" x y set coord [$current(frame) get crosshair canvas] set X [lindex $coord 0] set Y [lindex $coord 1] if {$horz} { EnterInfoBox $current(frame) $x $Y canvas UpdatePixelTableDialog $current(frame) $x $Y canvas } else { EnterInfoBox $current(frame) $X $y canvas UpdatePixelTableDialog $current(frame) $X $y canvas } } } proc LeaveGraph {which} { focus {} $which crosshairs off LeaveInfoBox PixelTableClearDialog } proc MotionGraph {which x y horz} { global current $which crosshairs configure -position "@$x,$y" if {$current(frame) != {} && $current(mode) == "crosshair"} { set coord [$current(frame) get crosshair canvas] set X [lindex $coord 0] set Y [lindex $coord 1] if {$horz} { UpdateInfoBox $current(frame) $x $Y canvas UpdatePixelTableDialog $current(frame) $x $Y canvas } else { UpdateInfoBox $current(frame) $X $y canvas UpdatePixelTableDialog $current(frame) $X $y canvas } } } proc ArrowKeyGraph {which x y horz} { set cursor [$which crosshairs cget -position] scan $cursor "@%d,%d" cx cy set cx [expr $cx+$x] set cy [expr $cy+$y] MotionGraph $which $cx $cy $horz } proc LayoutGraphs {} { global igraph global ds9 global canvas global view global colorbar global icolorbar set cbh [expr $view(colorbar) && \ [string equal $colorbar(orientation) {horizontal}]] set cbv [expr $view(colorbar) && \ [string equal $colorbar(orientation) {vertical}]] set grh [expr $view(graph,horz)] set grv [expr $view(graph,vert)] if {$grh} { set xx 0 set yy [expr $canvas(height) + $canvas(gap)] if {$cbh} { incr yy $icolorbar(horizontal,height) } if {$grv && !$cbh} { incr yy $igraph(gap,y) } if {$igraph(horz,id) == 0} { set igraph(horz,id) [$ds9(canvas) create window $xx $yy \ -window $ds9(graph,horz) -anchor nw] } else { $ds9(canvas) coords $igraph(horz,id) $xx $yy } set ww [expr $canvas(width)+$igraph(gap,x)] $ds9(graph,horz) configure -width $ww } else { if {$igraph(horz,id)>0} { $ds9(canvas) delete $igraph(horz,id) set igraph(horz,id) 0 } } if {$grv} { set yy 0 set xx [expr $canvas(width) + $canvas(gap)] if {$cbv} { incr xx $icolorbar(vertical,width) } if {$grh && !$cbv} { incr xx $igraph(gap,x) } if {$igraph(vert,id) == 0} { set igraph(vert,id) [$ds9(canvas) create window $xx $yy \ -window $ds9(graph,vert) -anchor nw] } else { $ds9(canvas) coords $igraph(vert,id) $xx $yy } set hh [expr $canvas(height)+$igraph(gap,y)] $ds9(graph,vert) configure -height $hh } else { if {$igraph(vert,id)>0} { $ds9(canvas) delete $igraph(vert,id) set igraph(vert,id) 0 } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/centroid.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000005654�11723251046�014220� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CentroidDef {} { global centroid global icentroid set icentroid(top) .centroid set icentroid(mb) .centroidmb } proc CentroidDialog {} { global centroid global icentroid global ds9 # see if we already have a window visible if [winfo exists $icentroid(top)] { raise $icentroid(top) return } # create the window set w $icentroid(top) set mb $icentroid(mb) Toplevel $w $mb 6 [msgcat::mc {Centroid Parameters}] CentroidDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command CentroidApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command CentroidDestroyDialog EditMenu $mb icentroid UpdateCentroidDialog # Param set f [ttk::frame $w.param] slider $f.islider 1 100 [msgcat::mc {Iteration}] \ marker(centroid,iteration) [list CentroidApplyDialog] slider $f.rslider 0 50 [msgcat::mc {Radius}] \ marker(centroid,radius) [list CentroidApplyDialog] grid $f.islider -padx 2 -pady 2 -sticky ew grid $f.rslider -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command CentroidApplyDialog ttk::button $f.close -text [msgcat::mc {Close}] \ -command CentroidDestroyDialog pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true } proc CentroidDestroyDialog {} { global icentroid if {[winfo exists $icentroid(top)]} { destroy $icentroid(top) destroy $icentroid(mb) } } proc CentroidApplyDialog {} { global current global marker if {$current(frame) != {}} { $current(frame) marker centroid radius $marker(centroid,radius) $current(frame) marker centroid iteration $marker(centroid,iteration) } } proc UpdateCentroidDialog {} { global centroid global icentroid global current global marker global debug if {$debug(tcl,update)} { puts stderr "UpdateCentroidDialog" } if {[winfo exists $icentroid(top)]} { if {$current(frame) != {}} { set marker(centroid,radius) \ [$current(frame) get marker centroid radius] set marker(centroid,iteration) \ [$current(frame) get marker centroid iteration] } } } proc CentroidBackup {ch which} { puts $ch "$which marker centroid radius [$which get marker centroid radius]" puts $ch "$which marker centroid iteration [$which get marker centroid iteration]" } ������������������������������������������������������������������������������������./saods9/src/grid.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000122154�12036024216�013324� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc GridDef {} { global igrid global grid set igrid(top) .grid set igrid(mb) .gridmb set grid(view) 0 GridDefault } proc GridDefault {} { global grid set grid(type) analysis set grid(system) wcs set grid(sky) fk5 set grid(skyformat) sexagesimal set grid(grid) 1 set grid(grid,color) blue set grid(grid,width) 1 set grid(grid,style) 0 set grid(grid,gap1) {} set grid(grid,gap2) {} set grid(grid,gap3) {} set grid(grid,gapunit1) {} set grid(grid,gapunit2) {} set grid(grid,gapunit3) {} set grid(axes) 1 set grid(axes,color) red set grid(axes,width) 1 set grid(axes,style) 0 set grid(axes,type) interior set grid(axes,origin) lll set grid(tick) 1 set grid(tick,color) white set grid(tick,width) 1 set grid(tick,style) 0 set grid(border) 1 set grid(border,color) blue set grid(border,width) 1 set grid(border,style) 0 set grid(format1) {} set grid(format2) {} set grid(numlab) 1 set grid(numlab,font) helvetica set grid(numlab,size) 10 set grid(numlab,weight) normal set grid(numlab,slant) roman set grid(numlab,color) green set grid(numlab,gap1) {} set grid(numlab,gap2) {} set grid(numlab,gap3) {} set grid(numlab,type) interior set grid(numlab,vertical) 0 set grid(title) 1 set grid(title,text) {} set grid(title,def) 1 set grid(title,gap) {} set grid(title,font) helvetica set grid(title,size) 12 set grid(title,weight) normal set grid(title,slant) roman set grid(title,color) black set grid(textlab) 1 set grid(textlab,text1) {} set grid(textlab,text2) {} set grid(textlab,def1) 1 set grid(textlab,def2) 1 set grid(textlab,gap1) {} set grid(textlab,gap2) {} set grid(textlab,font) helvetica set grid(textlab,size) 10 set grid(textlab,weight) normal set grid(textlab,slant) roman set grid(textlab,color) black } proc GridUpdate {} { global grid global current if {$current(frame) != {}} { GridAdjustOptions if {$grid(view) && [$current(frame) has fits]} { $current(frame) grid create $grid(system) $grid(sky) \ $grid(skyformat) $grid(type) \ [GridBuildOptions] "\"[array get grid]\"" } else { $current(frame) grid delete } } } proc GridUpdateZoom {} { global grid if {$grid(type) == "publication"} { GridUpdate } } proc GridAdjustOptions {} { global grid global current if {$current(frame) != {}} { if {[$current(frame) has fits]} { # change values if needed for coordmenu AdjustCoordSystem grid system } } set grid(grid,gapunit1) pixels set grid(grid,gapunit2) pixels set grid(grid,gapunit3) pixels # adjust units switch -- $grid(system) { image - physical - amplifier - detector {} default { if {$current(frame) != {}} { if {[$current(frame) has wcs celestrial $grid(system)]} { set grid(grid,gapunit1) degrees set grid(grid,gapunit2) degrees } if {[$current(frame) has wcs 3d $grid(system)]} { set tt [string trim [$current(frame) get fits header 1 keyword CTYPE3]] if {$tt != {}} { set grid(grid,gapunit3) $tt } } } } } } proc GridBuildOptions {} { global grid global current set opt "\"" # Grid append opt " Grid=$grid(grid)," append opt " Colour(grid)=[GridColor2Ast $grid(grid,color)]," append opt " Width(grid)=$grid(grid,width)," append opt " Style(grid)=$grid(grid,style)," # Axes append opt " DrawAxes=$grid(axes)," append opt " Colour(axes)=[GridColor2Ast $grid(axes,color)]," append opt " Width(axes)=$grid(axes,width)," append opt " Style(axes)=$grid(axes,style)," # Format if {$grid(format1) != {}} { append opt " Format(1)=$grid(format1)," } else { set ff [GridDefaultFormat1] if {$ff != {}} { append opt " Format(1)=$ff," } } if {$grid(format2) != {}} { append opt " Format(2)=$grid(format2)," } else { set ff [GridDefaultFormat2] if {$ff != {}} { append opt " Format(2)=$ff," } } # Ticks if {!$grid(tick)} { append opt " MajTickLen=0," append opt " MinTick(1)=0," append opt " MinTick(2)=0," switch -- $grid(type) { analysis {} publication { switch -- [$current(frame) get type] { base - rgb {} 3d {append opt " MinTick(3)=0,"} } } } } append opt " Colour(ticks)=[GridColor2Ast $grid(tick,color)]," append opt " Width(ticks)=$grid(tick,width)," append opt " Style(ticks)=$grid(tick,style)," # Border append opt " Border=$grid(border)," append opt " Colour(border)=[GridColor2Ast $grid(border,color)]," append opt " Width(border)=$grid(border,width)," append opt " Style(border)=$grid(border,style)," # Labels append opt " Labelling=$grid(axes,type)," switch -- [$current(frame) get type] { base - rgb {append opt " LabelUp=$grid(numlab,vertical),"} 3d {append opt " LabelUp=1,"} } # NumLab append opt " NumLab=$grid(numlab)," set opt "$opt Font(numlab)=[GridFont2Ast $grid(numlab,font) $grid(numlab,weight) $grid(numlab,slant)]," append opt " Size(numlab)=$grid(numlab,size)," append opt " Colour(numlab)=[GridColor2Ast $grid(numlab,color)]," # TextLab switch -- $grid(type) { analysis {append opt " TextLab=0,"} publication { switch -- [$current(frame) get type] { base - rgb {append opt " TextLab=$grid(textlab),"} 3d {append opt " TextLab=0,"} } } } if {!$grid(textlab,def1)} { append opt " Label(1)=[GridStripComma $grid(textlab,text1)] ," } if {!$grid(textlab,def2)} { append opt " Label(2)=[GridStripComma $grid(textlab,text2)] ," } set opt "$opt Font(textlab)=[GridFont2Ast $grid(textlab,font) $grid(textlab,weight) $grid(textlab,slant)]," append opt " Size(textlab)=$grid(textlab,size)," append opt " Colour(textlab)=[GridColor2Ast $grid(textlab,color)]," # Title switch -- $grid(type) { analysis {append opt " DrawTitle=0,"} publication { switch -- [$current(frame) get type] { base - rgb {append opt " DrawTitle=$grid(title),"} 3d {append opt " DrawTitle=0,"} } } } if {$grid(title,def)} { set t [GridStripComma "[$current(frame) get fits object name]"] if {$t != {}} { append opt " Title=$t ," } } else { set t [GridStripComma "$grid(title,text)"] if {$t != {}} { append opt " Title=$t ," } } set opt "$opt Font(title)=[GridFont2Ast $grid(title,font) $grid(title,weight) $grid(title,slant)]," append opt " Size(title)=$grid(title,size)," append opt " Colour(title)=[GridColor2Ast $grid(title,color)]," # Grid Spacing if {$grid(grid,gap1) != {}} { if {$grid(grid,gapunit1) == "degrees"} { append opt " Gap(1)=[expr 3.14159/180.*$grid(grid,gap1)]," } else { append opt " Gap(1)=$grid(grid,gap1)," } } if {$grid(grid,gap2) != {}} { if {$grid(grid,gapunit2) == "degrees"} { append opt " Gap(2)=[expr 3.14159/180.*$grid(grid,gap2)]," } else { append opt " Gap(2)=$grid(grid,gap2)," } } switch -- [$current(frame) get type] { base - rgb {} 3d { if {$grid(grid,gap3) != {}} { if {$grid(grid,gapunit3) == "degrees"} { append opt " Gap(3)=[expr 3.14159/180.*$grid(grid,gap3)]," } else { append opt " Gap(3)=$grid(grid,gap3)," } } } } # axes numerics set flip 0 set numx 0 set numy 0 switch -- $grid(type) { analysis { switch -- [$current(frame) get type] { base - rgb { set numx -.03 set numy -.03 } 3d {} } } publication { switch -- [$current(frame) get type] { base - rgb { set numx -.02 set numy -.01 switch -- $grid(axes,type) { interior {} exterior { switch -- $grid(numlab,type) { interior {} exterior {set flip 1} } } } } 3d {} } } } # override if {$grid(numlab,gap1) != {}} { set numx [expr -$grid(numlab,gap1)/100.] } if {$grid(numlab,gap2) != {}} { set numy [expr -$grid(numlab,gap2)/100.] } if {$grid(numlab,gap3) != {}} { set numy [expr -$grid(numlab,gap3)/100.] } if {$flip} { set numx [expr -$numx] set numy [expr -$numy] } append opt " NumLabGap(1)=$numx," append opt " NumLabGap(2)=$numy," # Label gaps switch -- $grid(type) { analysis { set axisx 0 set axisy 0 set title 0 } publication { if {$grid(textlab,gap1) != {}} { set axisx [expr $grid(textlab,gap1)/100.] } else { set axisx 0 } if {$grid(textlab,gap2) != {}} { set axisy [expr $grid(textlab,gap2)/100.] } else { set axisy .1 } if {$grid(title,gap) != {}} { set title [expr $grid(title,gap)/100.] } else { set title .30 } } } append opt " TextLabGap(1)=$axisx," append opt " TextLabGap(2)=$axisy," append opt " TitleGap=[expr -1-$title]," # Orientation switch -- [$current(frame) get type] { base - rgb { append opt " Edge(1)=top," append opt " Edge(2)=left," } 3d { switch -- $grid(type) { analysis { append opt " Edge(1)=bottom," append opt " Edge(2)=left," } publication { append opt " RootCorner=$grid(axes,origin)," } } } } # 3D Normal switch -- $grid(type) { analysis {} publication { switch -- [$current(frame) get type] { base - rgb {} 3d {append opt " Norm(1)=0, Norm(2)=0, Norm(3)=-1,"} } } } # The End append opt " \"" global debug if {$debug(tcl,grid)} { puts stderr "GridBuildOptions" puts stderr "$opt" } return $opt } proc GridAst2Color {ast} { switch -- $ast { 0 {return {black}} 1 {return white} 2 {return red} 3 {return green} 4 {return blue} 5 {return cyan} 6 {return magenta} 7 {return yellow} 16777215 {return {white}} 16711680 {return {red}} 65280 {return {green}} 255 {return {blue}} 65535 {return {cyan}} 16711935 {return {magenta}} 16776960 {return {yellow}} default {return "#[format %x $ast]"} } } proc GridColor2Ast {which} { switch -- $which { black {return [expr 0x000000]} white {return [expr 0xffffff]} red {return [expr 0xff0000]} green {return [expr 0x00ff00]} blue {return [expr 0x0000ff]} cyan {return [expr 0x00ffff]} magenta {return [expr 0xff00ff]} yellow {return [expr 0xffff00]} default { if {[string range $which 0 0] == "#"} { return [expr 0x[string range $which 1 end]] } else { return [expr $which] } } } } proc GridAst2Font {ast fnvar fwvar fsvar} { upvar $fnvar fn upvar $fwvar fw upvar $fsvar fs switch -- $ast { 0 - 2 - 3 {set fn "helvetica"; set fw "normal"; set fs "roman"} 1 {set fn "times"; set fw "normal"; set fs "roman"} 4 {set fn "courier"; set fw "normal"; set fs "roman"} 10 - 12 - 13 {set fn "helvetica"; set fw "bold"; set fs "roman"} 11 {set fn "times"; set fw "bold"; set fs "roman"} 14 {set fn "courier"; set fw "bold"; set fs "roman"} 20 - 22 - 23 {set fn "helvetica"; set fw "normal"; set fs "italic"} 21 {set fn "times"; set fw "normal"; set fs "italic"} 24 {set fn "courier"; set fw "normal"; set fs "italic"} 30 - 32 - 33 {set fn "helvetica"; set fw "bold"; set fs "italic"} 31 {set fn "times"; set fw "bold"; set fs "italic"} 34 {set fn "courier"; set fw "bold"; set fs "italic"} default {set fn "helvetica"; set fw "normal"; set fs "roman"} } } proc GridFont2Ast {fn fw fs} { if {$fn == "times" && $fw == "normal" && $fs == "roman"} { return 1; } elseif {$fn == "helvetica" && $fw == "normal" && $fs == "roman"} { return 2; } elseif {$fn == "courier" && $fw == "normal" && $fs == "roman"} { return 4; } elseif {$fn == "times" && $fw == "bold" && $fs == "roman"} { return 11; } elseif {$fn == "helvetica" && $fw == "bold" && $fs == "roman"} { return 12; } elseif {$fn == "courier" && $fw == "bold" && $fs == "roman"} { return 14; } elseif {$fn == "times" && $fw == "normal" && $fs == "italic"} { return 21; } elseif {$fn == "helvetica" && $fw == "normal" && $fs == "italic"} { return 22; } elseif {$fn == "courier" && $fw == "normal" && $fs == "italic"} { return 24; } elseif {$fn == "times" && $fw == "bold" && $fs == "italic"} { return 31; } elseif {$fn == "helvetica" && $fw == "bold" && $fs == "italic"} { return 32; } elseif {$fn == "courier" && $fw == "bold" && $fs == "italic"} { return 34; } else { return 2; } } proc GridDialog {} { global igrid global grid global current global ds9 # see if we already have a window visible if [winfo exists $igrid(top)] { raise $igrid(top) return } # create the window set w $igrid(top) set mb $igrid(mb) Toplevel $w $mb 6 [msgcat::mc {Coordinate Grid Parameters}] \ GridDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Type}] -menu $mb.type $mb add cascade -label [msgcat::mc {Coordinate}] -menu $mb.coord $mb add cascade -label [msgcat::mc {Grid}] -menu $mb.grid $mb add cascade -label [msgcat::mc {Axes}] -menu $mb.axes $mb add cascade -label [msgcat::mc {Numerics}] -menu $mb.numlab $mb add cascade -label [msgcat::mc {Labels}] -menu $mb.textlab $mb add cascade -label [msgcat::mc {Tickmarks}] -menu $mb.tick $mb add cascade -label [msgcat::mc {Title}] -menu $mb.title $mb add cascade -label [msgcat::mc {Border}] -menu $mb.border # File menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command GridApplyDialog $mb.file add command -label [msgcat::mc {Reset}] -command GridResetDialog $mb.file add command -label [msgcat::mc {Clear}] -command GridClearDialog $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Configuration}]..." \ -command GridLoadDialog $mb.file add command -label "[msgcat::mc {Save Configuration}]..." \ -command GridSaveDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command GridDestroyDialog # Edit EditMenu $mb igrid # Type menu $mb.type $mb.type add radiobutton -label [msgcat::mc {Analysis}] \ -variable grid(type) -value analysis -command GridApplyDialog $mb.type add radiobutton -label [msgcat::mc {Publication}] \ -variable grid(type) -value publication -command GridApplyDialog $mb.type add separator $mb.type add radiobutton -label [msgcat::mc {Interior Axes}] \ -variable grid(axes,type) -value interior -command GridApplyDialog $mb.type add radiobutton -label [msgcat::mc {Exterior Axes}] \ -variable grid(axes,type) -value exterior -command GridApplyDialog $mb.type add separator $mb.type add radiobutton -label [msgcat::mc {Interior Numerics}] \ -variable grid(numlab,type) -value interior -command GridApplyDialog $mb.type add radiobutton -label [msgcat::mc {Exterior Numerics}] \ -variable grid(numlab,type) -value exterior -command GridApplyDialog $mb.type add separator $mb.type add checkbutton -label [msgcat::mc {Vertical Text}] \ -variable grid(numlab,vertical) -command GridApplyDialog # Coordinate CoordMenu $mb.coord grid system 1 sky skyformat GridApplyDialog # Grid menu $mb.grid $mb.grid add checkbutton -label [msgcat::mc {Show}] \ -variable grid(grid) -command GridApplyDialog $mb.grid add separator $mb.grid add cascade -label [msgcat::mc {Color}] -menu $mb.grid.color $mb.grid add cascade -label [msgcat::mc {Line}] -menu $mb.grid.line ColorMenu $mb.grid.color grid grid,color GridApplyDialog GridCreateLineMenu $mb.grid.line grid,width grid,style # Axes menu $mb.axes $mb.axes add checkbutton -label [msgcat::mc {Show}] \ -variable grid(axes) -command GridApplyDialog $mb.axes add separator $mb.axes add cascade -label [msgcat::mc {Color}] -menu $mb.axes.color $mb.axes add cascade -label [msgcat::mc {Line}] -menu $mb.axes.line $mb.axes add separator $mb.axes add cascade -label [msgcat::mc {Origin}] -menu $mb.axes.origin ColorMenu $mb.axes.color grid axes,color GridApplyDialog GridCreateLineMenu $mb.axes.line axes,width axes,style menu $mb.axes.origin $mb.axes.origin add radiobutton -label [msgcat::mc {Lower Left Front}] \ -variable grid(axes,origin) -value lll -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Lower Right Front}] \ -variable grid(axes,origin) -value ull -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Upper Right Front}] \ -variable grid(axes,origin) -value uul -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Upper Left Front}] \ -variable grid(axes,origin) -value lul -command GridApplyDialog $mb.axes.origin add separator $mb.axes.origin add radiobutton -label [msgcat::mc {Lower Left Back}] \ -variable grid(axes,origin) -value llu -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Lower Right Back}] \ -variable grid(axes,origin) -value ulu -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Upper Right Back}] \ -variable grid(axes,origin) -value uuu -command GridApplyDialog $mb.axes.origin add radiobutton -label [msgcat::mc {Upper Left Back}] \ -variable grid(axes,origin) -value luu -command GridApplyDialog # Numerics menu $mb.numlab $mb.numlab add checkbutton -label [msgcat::mc {Show}] \ -variable grid(numlab) -command GridApplyDialog $mb.numlab add separator $mb.numlab add cascade -label [msgcat::mc {Color}] \ -menu $mb.numlab.color $mb.numlab add cascade -label [msgcat::mc {Font}] \ -menu $mb.numlab.font ColorMenu $mb.numlab.color grid numlab,color GridApplyDialog FontMenu $mb.numlab.font \ grid numlab,font numlab,size numlab,weight numlab,slant \ GridApplyDialog # Labels menu $mb.textlab $mb.textlab add checkbutton -label [msgcat::mc {Show}] \ -variable grid(textlab) -command GridApplyDialog $mb.textlab add separator $mb.textlab add cascade -label [msgcat::mc {Color}] \ -menu $mb.textlab.color $mb.textlab add cascade -label [msgcat::mc {Font}] \ -menu $mb.textlab.font ColorMenu $mb.textlab.color grid textlab,color GridApplyDialog FontMenu $mb.textlab.font \ grid textlab,font textlab,size textlab,weight textlab,slant \ GridApplyDialog # Tickmarks menu $mb.tick $mb.tick add checkbutton -label [msgcat::mc {Show}] \ -variable grid(tick) -command GridApplyDialog $mb.tick add separator $mb.tick add cascade -label [msgcat::mc {Color}] \ -menu $mb.tick.color $mb.tick add cascade -label [msgcat::mc {Line}] \ -menu $mb.tick.line ColorMenu $mb.tick.color grid tick,color GridApplyDialog GridCreateLineMenu $mb.tick.line tick,width tick,style # Title menu $mb.title $mb.title add checkbutton -label [msgcat::mc {Show}] \ -variable grid(title) -command GridApplyDialog $mb.title add separator $mb.title add cascade -label [msgcat::mc {Color}] -menu $mb.title.color $mb.title add cascade -label [msgcat::mc {Font}] -menu $mb.title.font ColorMenu $mb.title.color grid title,color GridApplyDialog FontMenu $mb.title.font \ grid title,font title,size title,weight title,slant \ GridApplyDialog # Border menu $mb.border $mb.border add checkbutton -label [msgcat::mc {Show}] \ -variable grid(border) -command GridApplyDialog $mb.border add separator $mb.border add cascade -label [msgcat::mc {Color}] -menu $mb.border.color $mb.border add cascade -label [msgcat::mc {Line}] -menu $mb.border.line ColorMenu $mb.border.color grid border,color GridApplyDialog GridCreateLineMenu $mb.border.line border,width border,style # Labels set f [ttk::labelframe $w.label -text [msgcat::mc {Labels}] -padding 2] ttk::label $f.label -text [msgcat::mc {Title}] ttk::entry $f.title -textvariable grid(title,text) \ -width 60 ttk::checkbutton $f.default -text [msgcat::mc {Default}] \ -variable grid(title,def) -command GridApplyDialog ttk::label $f.label1 -text "[msgcat::mc {Axis}] 1" ttk::entry $f.title1 -textvariable grid(textlab,text1) \ -width 60 ttk::checkbutton $f.default1 -text [msgcat::mc {Default}] \ -variable grid(textlab,def1) -command GridApplyDialog ttk::label $f.label2 -text "[msgcat::mc {Axis}] 2" ttk::entry $f.title2 -textvariable grid(textlab,text2) \ -width 60 ttk::checkbutton $f.default2 -text [msgcat::mc {Default}] \ -variable grid(textlab,def2) -command GridApplyDialog grid $f.label $f.title $f.default -padx 2 -pady 2 -sticky ew grid $f.label1 $f.title1 $f.default1 -padx 2 -pady 2 -sticky ew grid $f.label2 $f.title2 $f.default2 -padx 2 -pady 2 -sticky ew grid columnconfigure $f 1 -weight 1 # Params set f [ttk::labelframe $w.param -text [msgcat::mc {Spacing}] -padding 2] ttk::label $f.lspace -text "[msgcat::mc {Label}] %" ttk::label $f.ngap -text "[msgcat::mc {Numerics}] %" ttk::label $f.lformat -text [msgcat::mc {Format}] ttk::label $f.lgap -text [msgcat::mc {Grid Gap}] ttk::label $f.titlet -text [msgcat::mc {Title}] ttk::entry $f.spacet -textvariable grid(title,gap) \ -width 8 ttk::label $f.title1 -text "[msgcat::mc {Axis}] 1" ttk::entry $f.tspace1 -textvariable grid(textlab,gap1) -width 8 ttk::entry $f.nspace1 -textvariable grid(numlab,gap1) -width 8 ttk::entry $f.format1 -textvariable grid(format1) -width 8 ttk::entry $f.gap1 -textvariable grid(grid,gap1) -width 8 ttk::label $f.gapunit1 -textvariable grid(grid,gapunit1) ttk::label $f.title2 -text "[msgcat::mc {Axis}] 2" ttk::entry $f.tspace2 -textvariable grid(textlab,gap2) -width 8 ttk::entry $f.nspace2 -textvariable grid(numlab,gap2) -width 8 ttk::entry $f.format2 -textvariable grid(format2) -width 8 ttk::entry $f.gap2 -textvariable grid(grid,gap2) -width 8 ttk::label $f.gapunit2 -textvariable grid(grid,gapunit2) ttk::label $f.title3 -text "[msgcat::mc {Axis}] 3" ttk::entry $f.nspace3 -textvariable grid(numlab,gap3) -width 8 ttk::entry $f.format3 -textvariable grid(format3) -width 8 ttk::entry $f.gap3 -textvariable grid(grid,gap3) -width 8 ttk::label $f.gapunit3 -textvariable grid(grid,gapunit3) grid x $f.lspace $f.ngap $f.lformat $f.lgap -padx 2 -pady 2 -sticky w grid $f.titlet $f.spacet -padx 2 -pady 2 -sticky w grid $f.title1 $f.tspace1 $f.nspace1 $f.format1 $f.gap1 $f.gapunit1 \ -padx 2 -pady 2 -sticky w grid $f.title2 $f.tspace2 $f.nspace2 $f.format2 $f.gap2 $f.gapunit2 \ -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command GridApplyDialog ttk::button $f.reset -text [msgcat::mc {Reset}] -command GridResetDialog ttk::button $f.clear -text [msgcat::mc {Clear}] -command GridClearDialog ttk::button $f.close -text [msgcat::mc {Close}] -command GridDestroyDialog pack $f.apply $f.reset $f.clear $f.close -side left -expand true \ -padx 2 -pady 4 bind $w <Return> "GridApplyDialog" # Fini grid $w.label -sticky news grid $w.param -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 # some window managers need a hint raise $w UpdateGridDialog } proc GridApplyDialog {} { global grid set grid(view) 1 GridUpdate } proc GridResetDialog {} { GridDefault GridUpdate } proc GridClearDialog {} { global grid set grid(view) 0 GridUpdate } proc GridDestroyDialog {} { global igrid if {[winfo exists $igrid(top)]} { destroy $igrid(top) destroy $igrid(mb) } } proc UpdateGridMenu {} { global grid global current global wcs global debug if {$debug(tcl,update)} { puts stderr "UpdateGridMenu" } if {($current(frame) == {})} { return } # set menu if {[$current(frame) has fits]} { set grid(view) [$current(frame) has grid] } # reassign system and format if {[$current(frame) has fits] && [$current(frame) has grid]} { set ll [$current(frame) get grid] set grid(system) [lindex $ll 0] set grid(sky) [lindex $ll 1] set grid(skyformat) [lindex $ll 2] set grid(type) [lindex $ll 3] # fix for grids create with old backup command if {[$current(frame) get grid var] == {}} { $current(frame) grid delete $current(frame) grid create $grid(system) $grid(sky) \ $grid(skyformat) $grid(type) \ [GridBuildOptions] "\"[array get grid]\"" } array set grid [$current(frame) get grid var] } else { # can be changed by wcs SetCoordSystem grid system sky skyformat } } proc UpdateGridDialog {} { global current global igrid global grid set mb $igrid(mb) global debug if {$debug(tcl,update)} { puts stderr "UpdateGridDialog" } GridAdjustOptions if {[winfo exists $igrid(top)]} { set f $igrid(top).label set g $igrid(top).param if {$current(frame) != {}} { switch -- [$current(frame) get type] { base - rgb { $mb entryconfig [msgcat::mc {Labels}] -state normal $mb entryconfig [msgcat::mc {Title}] -state normal $mb.type entryconfig [msgcat::mc {Interior Numerics}] \ -state normal $mb.type entryconfig [msgcat::mc {Exterior Numerics}] \ -state normal $mb.type entryconfig [msgcat::mc {Vertical Text}] \ -state normal $mb.axes entryconfig [msgcat::mc {Origin}] \ -state disable $f.label configure -state normal $f.title configure -state normal $f.default configure -state normal $f.label1 configure -state normal $f.title1 configure -state normal $f.default1 configure -state normal $f.label2 configure -state normal $f.title2 configure -state normal $f.default2 configure -state normal $g.lspace configure -state normal $g.spacet configure -state normal $g.tspace1 configure -state normal $g.tspace2 configure -state normal grid forget $g.title3 $g.nspace3 $g.format3 $g.gap3 \ $g.gapunit3 } 3d { $mb entryconfig [msgcat::mc {Labels}] -state disabled $mb entryconfig [msgcat::mc {Title}] -state disabled $mb.type entryconfig [msgcat::mc {Interior Numerics}] \ -state disabled $mb.type entryconfig [msgcat::mc {Exterior Numerics}] \ -state disabled $mb.type entryconfig [msgcat::mc {Vertical Text}] \ -state disabled $mb.axes entryconfig [msgcat::mc {Origin}] -state normal $f.label configure -state disabled $f.title configure -state disabled $f.default configure -state disabled $f.label1 configure -state disabled $f.title1 configure -state disabled $f.default1 configure -state disabled $f.label2 configure -state disabled $f.title2 configure -state disabled $f.default2 configure -state disabled $g.lspace configure -state disabled $g.spacet configure -state disabled $g.tspace1 configure -state disabled $g.tspace2 configure -state disabled grid $g.title3 x $g.nspace3 $g.format3 $g.gap3 $g.gapunit3 \ -padx 2 -pady 2 -sticky w } } set grid(frame) $current(frame) if {[$current(frame) has fits]} { CoordMenuEnable $igrid(mb).coord grid system 1 sky skyformat } else { CoordMenuReset $igrid(mb).coord grid system 1 sky skyformat } } } } proc GridCreateLineMenu {which width dash} { global igrid global grid WidthDashMenu $which grid $width $dash GridApplyDialog GridApplyDialog } proc GridLoadDialog {} { GridLoad [OpenFileDialog gridfbox] } proc GridLoad {filename} { global grid if {$filename != {}} { source $filename } # backward compatibility FixFontVar grid(numlab,weight) grid(numlab,slant) grid(numlab,style) FixFontVar grid(textlab,weight) grid(textlab,slant) grid(textlab,style) FixFontVar grid(title,weight) grid(title,slant) grid(title,style) set grid(view) 1 GridUpdate } proc GridSaveDialog {} { GridSave [SaveFileDialog gridfbox] } proc GridSave {filename} { global grid if {$filename != {}} { set file [open $filename w] puts $file "global grid" puts $file "array set grid \{ [array get grid] \}" close $file } } proc GridStripComma {str} { # strip ',' set t {} regsub -all "," "$str" " " t return $t } proc GridDefaultFormat1 {} { global grid global current switch $grid(system) { image - physical - detector - amplifier {return {}} default { if {[$current(frame) has wcs equatorial $grid(system)]} { switch $grid(sky) { fk4 - fk5 - icrs { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {hms.1}} hms {return {lhms.1}} } } galactic - ecliptic { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {dms.1}} hms {return {ldms}} } } } return {} } if {[$current(frame) has wcs celestrial $grid(system)]} { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {dms.1}} hms {return {ldms}} } return {} } } } } proc GridDefaultFormat2 {} { global grid global current switch $grid(system) { image - physical - detector - amplifier {return {}} default { if {[$current(frame) has wcs equatorial $grid(system)]} { switch $grid(sky) { fk4 - fk5 - icrs { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {dms.1}} hms {return {ldms.1}} } } galactic - ecliptic { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {dms.1}} hms {return {ldms}} } } } return {} } if {[$current(frame) has wcs celestrial $grid(system)]} { switch $grid(skyformat) { degrees {return {d.3}} sexagesimal {return {dms.1}} hms {return {ldms}} } return {} } } } } proc GridBackup {ch which} { global grid if [$which has grid] { set ll [$which get grid] set system [lindex $ll 0] set sky [lindex $ll 1] set skyformat [lindex $ll 2] set type [lindex $ll 3] set opts [$which get grid option] set vars [array get grid] puts $ch "$which grid create $system $sky $skyformat $type \{\"$opts\"\} \{\"$vars\"\}" } } # Process Cmds proc ProcessGridCmd {varname iname} { upvar $varname var upvar $iname i global grid switch -- [string tolower [lindex $var $i]] { open {GridDialog} close {GridDestroyDialog} yes - true - on - 1 - no - false - off - 0 { set grid(view) [FromYesNo [lindex $var $i]] GridUpdate } type { incr i switch -- [string tolower [lindex $var $i]] { axes { # backward compatible incr i; set grid(axes,type) [lindex $var $i] } numerics { # backward compatible incr i; set grid(numlab,type) [lindex $var $i] } default {set grid(type) [lindex $var $i]} } GridUpdate } system {incr i; set grid(system) [lindex $var $i]; GridUpdate} sky {incr i set grid(sky) [string tolower [lindex $var $i]] GridUpdate } skyformat { incr i switch -- [string tolower [lindex $var $i]] { deg - degree - degrees {set grid(skyformat) degrees} default {set grid(skyformat) [string tolower [lindex $var $i]]} } GridUpdate } grid { incr i switch -- [string tolower [lindex $var $i]] { color {incr i; set grid(grid,color) [lindex $var $i]} width {incr i; set grid(grid,width) [lindex $var $i]} style {incr i; set grid(grid,style) [lindex $var $i]} gap1 {incr i; set grid(grid,gap1) [lindex $var $i]} gap2 {incr i; set grid(grid,gap2) [lindex $var $i]} gap3 {incr i; set grid(grid,gap3) [lindex $var $i]} default {set grid(grid) [FromYesNo [lindex $var $i]]} } GridUpdate } axes { incr i switch -- [string tolower [lindex $var $i]] { color {incr i; set grid(axes,color) [lindex $var $i]} width {incr i; set grid(axes,width) [lindex $var $i]} style {incr i; set grid(axes,style) [lindex $var $i]} type {incr i; set grid(axes,type) [lindex $var $i]} origin {incr i; set grid(axes,origin) [lindex $var $i]} default {set grid(axes) [FromYesNo [lindex $var $i]]} } GridUpdate } format1 { incr i; set grid(format1) [lindex $var $i] GridUpdate } format2 { incr i; set grid(format2) [lindex $var $i] GridUpdate } tickmark - tickmarks - tick { incr i switch -- [string tolower [lindex $var $i]] { color {incr i; set grid(tick,color) [lindex $var $i]} width {incr i; set grid(tick,width) [lindex $var $i]} style {incr i; set grid(tick,style) [lindex $var $i]} default {set grid(tick) [FromYesNo [lindex $var $i]]} } GridUpdate } border { incr i switch -- [string tolower [lindex $var $i]] { color {incr i; set grid(border,color) [lindex $var $i]} width {incr i; set grid(border,width) [lindex $var $i]} style {incr i; set grid(border,style) [lindex $var $i]} default {set grid(border) [FromYesNo [lindex $var $i]]} } GridUpdate } numeric - numerics - numlab { incr i switch -- [string tolower [lindex $var $i]] { font {incr i; set grid(numlab,font) [lindex $var $i]} fontsize {incr i; set grid(numlab,size) [lindex $var $i]} fontweight {incr i; set grid(numlab,weight) [lindex $var $i]} fontslant {incr i; set grid(numlab,slant) [lindex $var $i]} fontstyle { incr i switch [lindex $var $i] { normal { set grid(numlab,weight) normal set grid(numlab,slant) roman } bold { set grid(numlab,weight) bold set grid(numlab,slant) roman } italic { set grid(numlab,weight) normal set grid(numlab,slant) italic } } } color {incr i; set grid(numlab,color) [lindex $var $i]} gap1 {incr i; set grid(numlab,gap1) [lindex $var $i]} gap2 {incr i; set grid(numlab,gap2) [lindex $var $i]} gap3 {incr i; set grid(numlab,gap3) [lindex $var $i]} type {incr i; set grid(numlab,type) [lindex $var $i]} vertical {incr i; set grid(numlab,vertical) [FromYesNo [lindex $var $i]]} default {set grid(numlab) [FromYesNo [lindex $var $i]]} } GridUpdate } title { incr i switch -- [string tolower [lindex $var $i]] { text {incr i; set grid(title,text) [lindex $var $i]} def {incr i; set grid(title,def) [FromYesNo [lindex $var $i]]} gap {incr i; set grid(title,gap) [lindex $var $i]} font {incr i; set grid(title,font) [lindex $var $i]} fontsize {incr i; set grid(title,size) [lindex $var $i]} fontweight {incr i; set grid(title,weight) [lindex $var $i]} fontslant {incr i; set grid(title,slant) [lindex $var $i]} fontstyle { incr i switch [lindex $var $i] { normal { set grid(title,weight) normal set grid(title,slant) roman } bold { set grid(title,weight) bold set grid(title,slant) roman } italic { set grid(title,weight) normal set grid(title,slant) italic } } } color {incr i; set grid(title,color) [lindex $var $i]} default {set grid(title) [FromYesNo [lindex $var $i]]} } GridUpdate } label - labels - textlab { incr i switch -- [string tolower [lindex $var $i]] { text1 {incr i; set grid(textlab,text1) [lindex $var $i]} text2 {incr i; set grid(textlab,text2) [lindex $var $i]} def1 {incr i; set grid(textlab,def1) [FromYesNo [lindex $var $i]]} def2 {incr i; set grid(textlab,def2) [FromYesNo [lindex $var $i]]} gap1 {incr i; set grid(textlab,gap1) [lindex $var $i]} gap2 {incr i; set grid(textlab,gap2) [lindex $var $i]} font {incr i; set grid(textlab,font) [lindex $var $i]} fontsize {incr i; set grid(textlab,size) [lindex $var $i]} fontweight {incr i; set grid(textlab,weight) [lindex $var $i]} fontslant {incr i; set grid(textlab,slant) [lindex $var $i]} fontstyle { incr i switch [lindex $var $i] { normal { set grid(textlab,weight) normal set grid(textlab,slant) roman } bold { set grid(textlab,weight) bold set grid(textlab,slant) roman } italic { set grid(textlab,weight) normal set grid(textlab,slant) italic } } } color {incr i; set grid(textlab,color) [lindex $var $i]} default {set grid(textlab) [FromYesNo [lindex $var $i]]} } GridUpdate } view { # backward compatable incr i switch -- [string tolower [lindex $var $i]] { grid {incr i; set grid(grid) [FromYesNo [lindex $var $i]]} axes { incr i switch -- [string tolower [lindex $var $i]] { numbers {incr i; set grid(numlab) \ [FromYesNo [lindex $var $i]]} tickmarks {incr i; set grid(tick) \ [FromYesNo [lindex $var $i]]} label {incr i; set grid(textlab) \ [FromYesNo [lindex $var $i]]} default {set grid(axes) [FromYesNo [lindex $var $i]]} } } title {incr i; set grid(title) [FromYesNo [lindex $var $i]]} border {incr i; set grid(border) [FromYesNo [lindex $var $i]]} vertical { incr i set grid(numlab,vertical) [FromYesNo [lindex $var $i]] } } GridUpdate } reset {GridResetDialog} load { incr i set fn [lindex $var $i] FileLast gridfbox $fn GridLoad $fn } save { incr i set fn [lindex $var $i] FileLast gridfbox $fn GridSave $fn } default { set grid(view) 1 GridUpdate incr i -1 } } } proc ProcessSendGridCmd {proc id param} { global grid switch -- [lindex $param 0] { type { switch -- [lindex $param 1] { axes { # backward compatible $proc $id "$grid(axes,type)\n" } numerics { # backward compatible $proc $id "$grid(numlab,type)\n" } default {$proc $id "$grid(type)\n"} } } system {$proc $id "$grid(system)\n"} sky {$proc $id "$grid(sky)\n"} skyformat {$proc $id "$grid(skyformat)\n"} grid { switch -- [lindex $param 1] { color {$proc $id "$grid(grid,color)\n"} width {$proc $id "$grid(grid,width)\n"} style {$proc $id "$grid(grid,style)\n"} gap1 {$proc $id "$grid(grid,gap1)\n"} gap2 {$proc $id "$grid(grid,gap2)\n"} gap3 {$proc $id "$grid(grid,gap3)\n"} default {$proc $id [ToYesNo $grid(grid)]} } } axes { switch -- [lindex $param 1] { color {$proc $id "$grid(axes,color)\n"} width {$proc $id "$grid(axes,width)\n"} style {$proc $id "$grid(axes,style)\n"} type {$proc $id "$grid(axes,type)\n"} origin {$proc $id "$grid(axes,origin)\n"} default {$proc $id [ToYesNo $grid(axes)]} } } format1 {$proc $id "$grid(format1)\n"} format2 {$proc $id "$grid(format2)\n"} tickmark - tickmarks - tick { switch -- [lindex $param 1] { color {$proc $id "$grid(tick,color)\n"} width {$proc $id "$grid(tick,width)\n"} style {$proc $id "$grid(tick,style)\n"} default {$proc $id [ToYesNo $grid(tick)]} } } border { switch -- [lindex $param 1] { color {$proc $id "$grid(border,color)\n"} width {$proc $id "$grid(border,width)\n"} style {$proc $id "$grid(border,style)\n"} default {$proc $id [ToYesNo $grid(border)]} } } numeric - numerics - numlab { switch -- [lindex $param 1] { font {$proc $id "$grid(numlab,font)\n"} fontsize {$proc $id "$grid(numlab,size)\n"} fontstyle - fontweight {$proc $id "$grid(numlab,weight)\n"} fontslant {$proc $id "$grid(numlab,slant)\n"} color {$proc $id "$grid(numlab,color)\n"} gap1 {$proc $id "$grid(numlab,gap1)\n"} gap2 {$proc $id "$grid(numlab,gap2)\n"} gap3 {$proc $id "$grid(numlab,gap3)\n"} type {$proc $id "$grid(numlab,type)\n"} vertical {$proc $id "$grid(numlab,vertical)\n"} default {$proc $id [ToYesNo $grid(numlab)]} } } title { switch -- [lindex $param 1] { text {$proc $id "$grid(title,text)\n"} def {$proc $id [ToYesNo $grid(title,def)]} gap {$proc $id "$grid(title,gap)\n"} font {$proc $id "$grid(title,font)\n"} fontsize {$proc $id "$grid(title,size)\n"} fontstyle - fontweight {$proc $id "$grid(title,weight)\n"} fontslant {$proc $id "$grid(title,slant)\n"} color {$proc $id "$grid(title,color)\n"} default {$proc $id [ToYesNo $grid(title)]} } } label - labels - textlab { switch -- [lindex $param 1] { text1 {$proc $id "$grid(textlab,text1)\n"} text2 {$proc $id "$grid(textlab,text2)\n"} def1 {$proc $id [ToYesNo $grid(textlab,def1)]} def2 {$proc $id [ToYesNo $grid(textlab,def2)]} gap1 {$proc $id "$grid(textlab,gap1)\n"} gap2 {$proc $id "$grid(textlab,gap2)\n"} font {$proc $id "$grid(textlab,font)\n"} fontsize {$proc $id "$grid(textlab,size)\n"} fontstyle - fontweight {$proc $id "$grid(textlab,weight)\n"} fontslant {$proc $id "$grid(textlab,slant)\n"} color {$proc $id "$grid(textlab,color)\n"} default {$proc $id [ToYesNo $grid(textlab)]} } } view { # backward compatible switch -- [lindex $param 1] { grid {$proc $id [ToYesNo $grid(grid)]} axes { switch -- [lindex $param 2] { numbers {$proc $id [ToYesNo $grid(numlab)]} tickmarks {$proc $id [ToYesNo $grid(tick)]} label {$proc $id [ToYesNo $grid(textlab)]} default {$proc $id [ToYesNo $grid(axes)]} } } title {$proc $id [ToYesNo $grid(title)]} border {$proc $id [ToYesNo $grid(border)]} vertical {$proc $id [ToYesNo $grid(numlab,vertical)]} } } default {$proc $id [ToYesNo $grid(view)]} } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/panner.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000014604�11772655401�013676� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CreatePanner {} { global ipanner global ds9 set ds9(panner) [canvas $ds9(panel).pan -width $ipanner(size) \ -height $ipanner(size) \ -relief groove \ -borderwidth 2 \ -highlightthickness 0 \ -insertofftime 0 \ -takefocus 0] $ds9(panner) create panner$ds9(visual) \ -width $ipanner(size) \ -height $ipanner(size) \ -command panner \ -tag panner \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) } proc PannerDef {} { global ipanner global ppanner set ipanner(size) 128 # prefs only set ppanner(compass) 1 } proc InitPanner {} { global ds9 global ppanner # other bindings BindEventsPanner bind $ds9(panner) <Tab> [list NextFrame] bind $ds9(panner) <Shift-Tab> [list PrevFrame] switch $ds9(wm) { x11 {bind $ds9(panner) <ISO_Left_Tab> [list PrevFrame]} aqua {} win32 {} } switch $ds9(wm) { x11 - aqua { bind $ds9(panner) <Enter> [list focus $ds9(panner)] bind $ds9(panner) <Leave> [list focus {}] } win32 { bind $ds9(panner) <Button> [list focus $ds9(panner)] bind $ds9(panner) <KeyPress> [list focus $ds9(panner)] bind $ds9(panner) <Leave> [list focus {}] } } # compass panner compass $ppanner(compass) } proc BindEventsPanner {} { global ds9 $ds9(panner) bind panner <Enter> [list EnterPanner %x %y] $ds9(panner) bind panner <Leave> [list LeavePanner] $ds9(panner) bind panner <Motion> [list MotionPanner %x %y] $ds9(panner) bind panner <Button-1> [list Button1Panner %x %y] $ds9(panner) bind panner <B1-Motion> [list Motion1Panner %x %y] $ds9(panner) bind panner <ButtonRelease-1> [list Release1Panner %x %y] switch $ds9(wm) { x11 - win32 { $ds9(panner) bind panner <ButtonRelease-2> \ [list Release2Panner %x %y] } aqua { $ds9(panner) bind panner <ButtonRelease-3> \ [list Release2Panner %x %y] } } $ds9(panner) bind panner <Up> [list ArrowKeyPanner 0 -1] $ds9(panner) bind panner <Down> [list ArrowKeyPanner 0 1] $ds9(panner) bind panner <Left> [list ArrowKeyPanner -1 0] $ds9(panner) bind panner <Right> [list ArrowKeyPanner 1 0] } proc UnBindEventsPanner {} { global ds9 $ds9(panner) bind panner <Enter> {} $ds9(panner) bind panner <Leave> {} $ds9(panner) bind panner <Motion> {} $ds9(panner) bind panner <Button-1> {} $ds9(panner) bind panner <B1-Motion> {} $ds9(panner) bind panner <ButtonRelease-1> {} switch $ds9(wm) { x11 - win32 {$ds9(panner) bind panner <ButtonRelease-2> {}} aqua {$ds9(panner) bind panner <ButtonRelease-3> {}} } $ds9(panner) bind panner <Up> {} $ds9(panner) bind panner <Down> {} $ds9(panner) bind panner <Left> {} $ds9(panner) bind panner <Right> {} } proc EnterPanner {x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "EnterPanner" } switch $ds9(wm) { x11 - aqua { focus $ds9(panner) $ds9(panner) focus panner } win32 {} } if {$current(frame) != {}} { EnterInfoBox $current(frame) $x $y panner UpdatePixelTableDialog $current(frame) $x $y panner UpdateGraph $current(frame) $x $y panner } } proc LeavePanner {} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "LeavePanner" } panner highlite off switch $ds9(wm) { x11 - aqua { $ds9(panner) focus {} focus {} } win32 {} } LeaveInfoBox PixelTableClearDialog ClearGraphData } proc MotionPanner {x y} { global current global debug if {$debug(tcl,events)} { puts stderr "MotionPanner" } panner highlite $x $y if {$current(frame) != {}} { UpdateColormapLevelMosaic $current(frame) $x $y panner UpdateInfoBox $current(frame) $x $y panner UpdatePixelTableDialog $current(frame) $x $y panner UpdateGraph $current(frame) $x $y panner } } proc Button1Panner {x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "Button1Panner" } panner pan begin $x $y } proc Motion1Panner {x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "Motion1Panner" } panner pan motion $x $y if {$current(frame) != {}} { UpdateColormapLevelMosaic $current(frame) $x $y panner UpdateInfoBox $current(frame) $x $y panner UpdatePixelTableDialog $current(frame) $x $y panner UpdateGraph $current(frame) $x $y panner } } proc Release1Panner {x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "Release1Panner" } if {$current(frame) != {}} { panner pan end $x $y $current(frame) pan bbox [panner get bbox] UpdateColormapLevelMosaic $current(frame) $x $y panner UpdateInfoBox $current(frame) $x $y panner UpdatePixelTableDialog $current(frame) $x $y panner UpdateGraph $current(frame) $x $y panner LockFrameCurrent UpdateGraphXAxis $current(frame) UpdatePanZoomDialog SAMPSendCoordPointAtSkyCmd $current(frame) } } proc Release2Panner {x y} { global ds9 global current if {$current(frame) != {}} { panner pan to $x $y $current(frame) pan bbox [panner get bbox] UpdateColormapLevelMosaic $current(frame) $x $y panner UpdateInfoBox $current(frame) $x $y panner UpdatePixelTableDialog $current(frame) $x $y panner UpdateGraph $current(frame) $x $y panner LockFrameCurrent UpdateGraphXAxis $current(frame) UpdatePanZoomDialog SAMPSendCoordPointAtSkyCmd $current(frame) } } proc ArrowKeyPanner {x y} { global current panner warp $x $y SAMPSendCoordPointAtSkyCmd $current(frame) } proc PannerBackup {ch} { global ppanner puts $ch "panner compass $ppanner(compass)" } # Prefs proc PrefsDialogPanner {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Panner}] lappend dprefs(tabs) [ttk::frame $w.panner] set f [ttk::labelframe $w.panner.param -text [msgcat::mc {Panner}]] ttk::checkbutton $f.compass \ -text [msgcat::mc {Show Compass}] \ -variable ppanner(compass) -command PrefsPannerCompass grid $f.compass -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } proc PrefsPannerCompass {} { global ppanner panner compass $ppanner(compass) } ����������������������������������������������������������������������������������������������������������������������������./saods9/src/catopt.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000002316�11700665566�013706� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # sample CATKeyCB # Allow the user to define callbacks to be called when # the user presses a key with selected regions while in edit mode. if {0} { # add to CATReg # callback=key CATKeyCB {${varname}.\${ii}.a} proc CATKeyCB {tag id} { global icat global debug if {$debug(tcl,cat)} { puts stderr "CATKeyCB $tag $id" } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] set key [lindex $t 2] upvar #0 $varname var global $varname global $var(tbldb) if {![info exists ${varname}(top)]} { return } if {$icat(key) == $key} { switch -- $key { a { puts stderr "Key: $key $row" return # column name 'TooManySrcs' set tcol [starbase_colnum $var(tbldb) {TooManySrcs}] # toggle between '0' and '1' set tt [starbase_get $var(tbldb) $row $tcol] if {$tt == {1}} { starbase_set $var(tbldb) $row $tcol {0} } else { starbase_set $var(tbldb) $row $tcol {1} } lappend icat(key,update) [list $varname $row] } } } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mecube.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000004515�12130604547�013645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMECubeFile {fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {ext cube} set loadParam(load,type) mmapincr set loadParam(file,name) $fn # mask not supported set loadParam(load,layer) {} ConvertFitsFile ProcessLoad } proc LoadMECubeAlloc {path fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {ext cube} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path # mask not supported set loadParam(load,layer) {} ProcessLoad } proc LoadMECubeSocket {sock fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {ext cube} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock # mask not supported set loadParam(load,layer) {} return [ProcessLoad 0] } proc SaveMECubeFile {fn} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits ext cube file "\{$fn\}" } proc SaveMECubeSocket {sock} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits ext cube socket $sock } proc ProcessMECubeCmd {varname iname sock fn} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMECubeSocket $sock $param]} { InitError xpa LoadMECubeFile $param } } else { # comm if {$fn != {}} { LoadMECubeAlloc $fn $param } else { LoadMECubeFile $param } } FinishLoad } proc ProcessSendMECubeCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } if {$sock != {}} { # xpa SaveMECubeSocket $sock } elseif {$fn != {}} { # comm SaveMECubeFile $fn $proc $id {} $fn } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/hvsup.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000127652�12131355477�013570� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc HVCancel {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVCancel" } # set state to 0 so that we don't process the finish proc set var(active) 0 # stop any refresh if {$var(refresh,id)>0} { after cancel $var(refresh,id) set var(refresh,id) 0 } # analysis if {$var(analysis)} { AnalysisTaskEnd $var(analysis,which) $var(analysis,i) HVSetAnalysis $varname 0 {} 0 } # clean up HVClearTmpFile $varname if {[info exists var(token)]} { http::reset $var(token) } if {[info exists var(widget)]} { $var(widget) configure -cursor {} } } proc HVDestroy {varname} { upvar #0 $varname var global $varname global ihv global debug if {$debug(tcl,hv)} { puts stderr "HVDestroy" } HVCancel $varname # clear the widge and all images $var(widget) clear # clear image cache foreach x [array names $varname "images,*"] { image delete $var($x) unset ${varname}($x) } # clear cache HVClearCache $varname # destroy the window and menubar if {[winfo exists $var(top)]} { destroy $var(top) destroy $var(mb) } # delete it from the xpa list set ii [lsearch $ihv(windows) $varname] if {$ii>=0} { set ihv(windows) [lreplace $ihv(windows) $ii $ii] } # clear varname unset $varname } proc HVReset {varname} { upvar #0 $varname var global $varname set var(active) 0 if {[info exists var(token)]} { global debug if {$debug(tcl,hv)} { puts stderr "HVReset ***cleanup***" } http::cleanup $var(token) unset var(token) } } proc HVDone {varname} { upvar #0 $varname var global $varname HVStatus $varname {} HVReset $varname } proc HVCancelled {varname} { upvar #0 $varname var global $varname HVStatus $varname {} HVReset $varname } proc HVError {varname err} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVError $err" } HVReset $varname Error $err } proc HVStatus {varname message} { upvar #0 $varname var global $varname set var(status) $message } proc HVResolveURL {varname url} { upvar #0 $varname var global $varname global debug global pvo if {$debug(tcl,hv)} { puts stderr "HVResolveURL $varname $url" } set sync $var(sync) # sub xpa method set exp {%40%40XPA_METHOD%40%40|@@XPA_METHOD@@} if {[regexp $exp $url]} { regsub -all $exp $url [XPAMethod] url if {$debug(tcl,hv)} { puts stderr "HVResolveURL XPA_METHOD $url" } } # sub vo method set exp {%40%40VO_METHOD%40%40|@@VO_METHOD@@} if {[regexp $exp $url]} { regsub -all $exp $url $pvo(method) url if {$debug(tcl,hv)} { puts stderr "HVResolveURL VO_METHOD $url" } } # if pvo(method) is xpa, HV has to be async if {$pvo(method) == {xpa}} { set sync 0 } # some old sites have a problem with '?' in the query not encoded ParseURL $url rr if {$rr(query) != {}} { if {[regsub -all {\?} $rr(query) {%25} query]} { set newurl "$rr(scheme)://$rr(authority)$rr(path)?$query" if {$rr(fragment) != {}} { append newurl "#$rr(fragment)" } HVLoadURL $varname $newurl {} $sync } else { HVLoadURL $varname $url {} $sync } } else { HVLoadURL $varname $url {} $sync } } # this is the main entry point, everybody calls here proc HVLoadURL {varname url query {sync 0}} { upvar #0 $varname var global $varname # this assumes the url has been already resolved global debug if {$debug(tcl,hv)} { puts stderr "HVLoadURL $varname $url $query $sync" } # do we have anything? if {$url == {}} { return } HVStatus $varname {} # parse url ParseURL $url r if {$debug(tcl,hv)} { puts stderr "HVLoadURL |$r(scheme)|$r(authority)|$r(path)|$r(query)|$r(fragment)|$query|" } switch -- $r(scheme) { file - {} {HVProcessURLFile $varname $url $query r} ftp {HVProcessURLFTP $varname $url $query r} http {HVProcessURLHTTP $varname $url $query r $sync} default {HVError $varname "[msgcat::mc {Sorry, DS9 does not support}] $r(scheme)"} } } proc HVProcessURLFile {varname url query rr} { upvar #0 $varname var global $varname upvar $rr r global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVProcessURLFile" } if [file exists $r(path)] { if [file isdirectory $r(path)] { HVSetURL $varname $url {} {} HVSetResult $varname 200 "text/html" HVSetData $varname \ [HVFileHtmlList $r(path) [HVDirList $r(path)]] {} set var(delete) 0 HVParse $varname } else { HVSetURL $varname $url {} $r(fragment) set var(delete) 0 HVLoadFile $varname $r(path) } } } proc HVProcessURLFTP {varname url query rr} { upvar #0 $varname var global $varname upvar $rr r global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVProcessURLFTP" } set fn "$ds9(tmpdir)/[file tail $r(path)]" set ftp [ftp::Open $r(authority) "ftp" "-ds9@" -mode passive] if {$ftp > -1} { # first try to get as file set ftp::VERBOSE $debug(tcl,ftp) set "ftp::ftp${ftp}(Output)" FTPLog ftp::Type $ftp binary if [ftp::Get $ftp $r(path) "$fn"] { ftp::Close $ftp if {$debug(tcl,hv)} { puts stderr "HVProcessURLFTP get $fn" } HVSetURL $varname $url {} $r(fragment) set var(delete) 1 HVLoadFile $varname "$fn" HVClearTmpFile $varname } else { # from the prev attempt catch {file delete -force "$fn"} if {$debug(tcl,hv)} { puts stderr "HVProcessURLFTP list" } # now as a directory set list [ftp::List $ftp $r(path)] ftp::Close $ftp HVSetURL $varname $url {} {} HVSetResult $varname 200 "text/html" HVSetData $varname [HVFTPHtmlList $r(authority) $r(path) $list] {} set var(delete) 0 HVParse $varname } } } proc HVProcessURLHTTP {varname url query rr sync} { upvar #0 $varname var global $varname upvar $rr r global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTP" } # stop any refresh if [info exists ${varname}(refresh,id)] { if {$var(refresh,id)>0} { after cancel $var(refresh,id) } } # do we already have it in cache? if {[info exists ${varname}(cache,file,$url,$query)]} { # has it expired? if {($var(cache,expire,$url,$query) == 0) || ($var(cache,expire,$url,$query) > [clock seconds])} { # just in case if [file exists $var(cache,file,$url,$query)] { # ok, to it if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTP found $url at $var(cache,file,$url,$query)" } HVSetURL $varname $url $query $r(fragment) set var(delete) 0 HVSetResult $varname 200 $var(cache,mime,$url,$query) HVSetData $varname {} $var(cache,file,$url,$query) HVParse $varname return } } # expired or invalid, clean up if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTP expired or invalid $var(cache,file,$url,$query)" } catch {file delete $var(cache,file,$url,$query)} unset var(cache,file,$url,$query) unset var(cache,mime,$url,$query) unset var(cache,expire,$url,$query) } HVSetURL $varname $url $query $r(fragment) HVSetResult $varname {} {} HVSetData $varname {} {} set var(ch) {} # do we have html? if so, use a var ParseURL $url r # geturl as file set var(fn) [tmpnam ds9 .http] if [catch {open "$var(fn)" w} ${varname}(ch)] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } # disable timeouts for analysis global ihttp set timeout $ihttp(timeout) if {$var(analysis)} { set timeout 0 } if {$sync} { if {![catch {set var(token) [http::geturl $url \ -protocol 1.0 \ -query "$query" \ -timeout $timeout \ -headers "[HVHTTPHeader $varname]" \ -progress [list HVProgress $varname] \ -binary 1 \ -channel $var(ch)] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 set var(delete) 1 HVProcessURLHTTPFinish $varname $var(token) } else { catch {close $var(ch)} HVError $varname "[msgcat::mc {Unable to locate URL}] $url" } } else { if {![catch {set var(token) [http::geturl $url \ -protocol 1.0 \ -query "$query" \ -timeout $timeout \ -headers "[HVHTTPHeader $varname]" \ -progress [list HVProgress $varname] \ -binary 1 \ -channel $var(ch) \ -command [list HVProcessURLHTTPFinish $varname]] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 set var(delete) 1 } else { catch {close $var(ch)} HVError $varname "[msgcat::mc {Unable to locate URL}] $url" } } } proc HVProcessURLHTTPFinish {varname token} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTPFinish" } catch {close $var(ch)} if {!($var(active))} { HVCancelled $varname return } upvar #0 $token t # Code set var(code) [http::ncode $token] # Meta set var(meta) $t(meta) # Cache defaults set var(cache) 1 set var(cache,images) 1 set var(expire) 0 HVParseMeta $varname # Log it HTTPLog $token # Result? switch -- $var(code) { 200 - 203 - 404 - 503 { if {$var(cache)} { if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTPFinish cacheing:$var(url),$var(query):$var(fn)" } set url $var(url) set query $var(query) set var(cache,file,$url,$query) $var(fn) set var(cache,mime,$url,$query) $var(mime) set var(cache,expire,$url,$query) $var(expire) set var(delete) 0 } HVParse $varname HVDone $varname } 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $var(meta) { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,hv)} { puts stderr "HVProcessURLHTTPFinish redirect $var(code) to $value" } # clean up and resubmit http::cleanup $token unset var(token) HVClearTmpFile $varname if [info exists var(widget)] { HVLoadURL $varname [$var(widget) resolve $value] {} $var(sync) } else { HVLoadURL $varname $value {} $var(sync) } } } } default {HVError $varname "HTTP [msgcat::mc {Error}] $var(code)"} } } proc HVHTTPHeader {varname} { upvar #0 $varname var global $varname set domain {} ParseURL $var(url) rr regexp {[^:]*} $rr(authority) domain set result "[ProxyHTTP]" foreach cc $var(cookies) { if {$domain == [lindex $cc 2]} { append result " Cookie [lindex $cc 0]=[lindex $cc 3]" } } global debug if {$debug(tcl,hv)} { puts stderr "HVHTTPHeader:$result" } return $result } proc HVParseMeta {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseMeta: $var(meta)" } foreach {name value} $var(meta) { switch -- [string tolower $name] { content-type { regexp -nocase {([^;]*);?(.*)} $value foo \ ${varname}(mime) ${varname}(mime,param) set var(mime) [string tolower $var(mime)] } content-length {} content-encoding { switch -- [string tolower $value] { gzip - x-gzip {set var(encoding) gzip} bzip2 {set var(encoding) bzip2} compress - Z {set var(encoding) compress} pack - z {set var(encoding) pack} default {} } } content-transfer-encoding { switch -- [string tolower $value] { binary - base64 {set var(transfer) [string tolower $value]} default {} } } refresh { set f [split $value \;] set var(refresh,time) [lindex $f 0] set var(refresh,url) [string range [lindex $f 1] 4 end] if {$var(refresh,url) != {} & $var(refresh,time) != {}} { set var(refresh,id) [after [expr $var(refresh,time)*1000] "HVLoadURL $varname \{$var(refresh,url)\} {} $var(sync)"] } else { set var(refresh,id) 0 } } expires { if {[catch {set ss [clock scan $value]}]} { set var(cache) 0 } else { set var(cache) 1 set var(expire) $ss } } cache-control { foreach cc [split $value {,}] { foreach {nn vv} [split $cc {=}] { switch $nn { public {set var(cache) 1} private {set var(cache) 1} no-cache {set var(cache) 0} no-store {set var(cache) 1} s-maxage - min-fresh - max-age { set var(cache) 1 set var(expire) \ [expr [file mtime $var(fn)]+$vv] } max-stale {} no-transform {} only-if-cached {} cache-extension {} must-revalidate {} proxy-revalidate {} } } } } pragma { switch $value { no-cache {set var(cache) 0} } } last-modified { } if-none-match { } set-cookie { set cname {} set cpath {/} set cdomain {} set cvalue {} ParseURL $var(url) rr regexp {[^:]*} $rr(authority) cdomain foreach cc [split $value {;}] { foreach {nn vv} [split $cc {=}] { switch [string tolower [string trim $nn]] { httponly {} expires {} path {set cpath $vv} domain {set cdomain $vv} {} {append cvalue {=}} default { if {$nn != {}} { set cname $nn set cvalue $vv } } } } } if {$cname != {}} { lappend ${varname}(cookies) [list $cname $cpath $cdomain $cvalue] } } } } if {$debug(tcl,hv)} { puts stderr "HVParseMeta Content-Type:$var(mime):$var(mime,param):" puts stderr "HVParseMeta Content-Encoding:$var(encoding):" puts stderr "HVParseMeta Content-Transfer-Encoding:$var(transfer):" puts stderr "HVParseMeta Refresh:$var(refresh,time):$var(refresh,url):" puts stderr "HVParseMeta Cache:$var(cache)" puts stderr "HVParseMeta Expires:$var(expire)" puts stderr "HVParseMeta Cookies:$var(cookies)" } } proc HVLoadFile {varname path} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVLoadFile $path" } HVSetResult $varname 200 {} HVSetData $varname {} $path # content-encoding switch -- [string tolower [file extension $path]] { .gz { set path [file rootname $path] set var(encoding) gzip } .bz2 { set path [file rootname $path] set var(encoding) bzip2 } .Z { set path [file rootname $path] set var(encoding) compress } .z { set path [file rootname $path] set var(encoding) pack } } switch -- [string tolower [file extension $path]] { .html - .htm {set var(mime) "text/html"} .gif {set var(mime) "image/gif"} .jpeg - .jpg {set var(mime) "image/jpeg"} .tiff - .tif {set var(mime) "image/tiff"} .png {set var(mime) "image/png"} .fits - .fit - .fts {set var(mime) "image/fits"} .ftz - .fits.gz - .fgz { set var(mime) "image/fits" set var(encoding) "gzip" } .text - .txt {set var(mime) "text/plain"} .multi { set var(mime) "multipart/mixed" set var(xpa,target) "*:*" if [file exists "$path"] { set ch [open "$path" r] if {[gets $ch line] >= 0} { set var(mime,param) "Content-Type: multipart/mixed; Boundary=[string range $line 2 end]" } catch {close $ch} } } .sao {set var(mime) "text/x-cmap-sao"} default { switch -- $var(encoding) { gzip - bzip2 - compress - pack {set var(mime) "application/octet-stream"} default {set var(mime) "text/plain"} } } } HVParse $varname } proc HVParse {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParse" } switch -- $var(mime) { "multipart/alternative" - "multipart/parallel" - "multipart/digest" - "multipart/related" - "multipart/signed" - "multipart/encrypted" - "multipart/report" {} "multipart/x-mixed-replace" - "multipart/mixed" { HVParseMulti $varname HVClearCache $varname } default {HVParseSingle $varname} } if {$var(analysis)} { AnalysisTaskEnd $var(analysis,which) $var(analysis,i) HVSetAnalysis $varname 0 {} 0 } } proc HVParseMulti {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseMulti" } # do it now, to be restored later if [info exists var(index)] { incr ${varname}(index) set var(index,$var(index)) "$var(url) $var(query)" set index $var(index) } set fn $var(fn) set del $var(delete) if [file exists "$var(fn)"] { if [catch {open "$var(fn)" r} ch] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } } set boundary [HVParseMimeParam $varname "boundary"] if {[string equal "$boundary" {}]} { HVError $varname [msgcat::mc {Invalid formated multipart/mixed mime type message}] return } set state 1 set var(ch) {} HVSetResult $varname 200 {} HVSetData $varname {} {} while {[gets $ch line] >= 0} { if {$debug(tcl,hv)} { # puts stderr "HVParseMulti $state:$line" } switch -- $state { 1 { # boundary if {[string equal "--$boundary" $line]} { set state 2 } } 2 { # header if {[string length $line] == 0} { HVParseMeta $varname # save to a file set var(fn) [tmpnam ds9 .http] set var(delete) 1 if [catch {open "$var(fn)" w} ${varname}(ch)] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } switch $var(transfer) { binary - base64 { fconfigure $var(ch) \ -translation binary -encoding binary } } set state 3 } else { if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { lappend var(meta) $key [string trim $value] } } } 3 { # body if {[string equal "--$boundary" $line]} { catch {close $var(ch)} HVParseSingle $varname HVClearTmpFile $varname set var(ch) {} HVSetResult $varname 200 {} # we want to preserve var(text) # HVSetData $varname {} {} set var(data) {} set var(fn) {} set state 2 } elseif {[string equal "--$boundary--" $line]} { catch {close $var(ch)} catch {close $ch} HVParseSingle $varname HVClearTmpFile $varname # reset file values set var(fn) $fn set var(delete) $del if [info exists var(index)] { # reset index set var(index) $index HVClearIndex $varname $index } return } else { switch $var(transfer) { binary {puts -nonewline $var(ch) $line} base64 { puts -nonewline $var(ch) [base64::decode $line] } default {puts $var(ch) $line} } } } } } # clean up catch {close $ch} set var(fn) $fn } proc HVParseSingle {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseSingle $var(url)" } switch -- $var(mime) { "text/html" - "text/plain" - "application/octet-stream" { # its never fails, someone can't get there mime types correct. # Override the mime type based on path ParseURL $var(url) r set path [file tail $r(path)] # set content-encoding switch -- [file extension $path] { .gz { set path [file rootname $path] set var(encoding) gzip } .bz2 { set path [file rootname $path] set var(encoding) bzip2 } .Z { set path [file rootname $path] set var(encoding) compress } .z { set path [file rootname $path] set var(encoding) pack } } # set Content-Type switch -- [file extension $path] { .html - .htm {set var(mime) "text/html"} .gif {set var(mime) "image/gif"} .jpeg - .jpg {set var(mime) "image/jpeg"} .tiff - .tif {set var(mime) "image/tiff"} .png {set var(mime) "image/png"} .fits - .fit - .fts {set var(mime) "image/fits"} .ftz - .fgz { set var(mime) "image/fits" set var(encoding) "gzip" } .xml - .vot - .votable {set var(mime) "text/xml"} .text - .txt {set var(mime) "text/plain"} .sao {set var(mime) "text/x-cmap-sao"} } } } switch -- $var(mime) { "text/html" {HVParseHTML $varname} "text/plain" {HVParseText $varname} "application/octet-stream" {HVParseSave $varname} "image/gif" - "image/jpeg" - "image/tiff" - "image/png" {HVParseImg $varname} "image/fits" - "application/fits" {HVParseFITS $varname} "application/fits-image" - "application/fits-table" - "application/fits-group" {HVParseFITS $varname} "image/x-fits" - "binary/x-fits" - "application/x-fits" {HVParseFITS $varname} "image/x-gfits" - "binary/x-gfits" - "image/gz-fits" - "application/x-gzip" - "display/gz-fits" { set var(encoding) gzip HVParseFITS $varname } "image/bz2-fits" - "display/bz2-fits" { set var(encoding) bzip2 HVParseFITS $varname } "image/x-cfits" - "binary/x-cfits" { set var(encoding) compress HVParseFITS $varname } "image/x-zfits" - "binary/x-zfits" { set var(encoding) pack HVParseFITS $varname } "image/fits-hcompress" - "image/x-fits-h" {HVParseFITS $varname} "text/xml" - "application/xml" - "application/x-votable+xml" {HVParseVOT $varname} "x-xpa/xpaget" {} "x-xpa/xpaset" {HVParseXPASet $varname} "x-xpa/xpainfo" {} "x-xpa/xpaaccess" {} "text/x-cmap-sao" {HVParseColormap $varname} default {HVParseSave $varname} } } proc HVParseText {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseText" } if {[string length $var(data)] == 0} { if [file exists "$var(fn)"] { if [catch {open "$var(fn)" r} ch] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } set var(data) [read $ch] close $ch } } if {$var(analysis)} { if {$debug(tcl,hv)} { puts stderr "HVParseText Analysis" } AnalysisProcessGetURL $var(analysis,which) $var(analysis,i) $var(data) } else { append var(text) $var(data) set var(data) \ "<html>\n<body>\n$var(text)\n</body>\n</html>" HVSetResult $varname 200 "text/html" HVParseHTML $varname } HVClearCache $varname } proc HVParseHTML {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseHTML" } if {[string length $var(data)] == 0} { if [file exists "$var(fn)"] { if [catch {open "$var(fn)" r} ch] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } set var(data) [read $ch] close $ch } } # check for HTTP-EQUIV if {[HVParseHTTP-EQUIV $varname]} { return } # figure out the base # we don't want any query or fragments ParseURL $var(url) r set base {} # scheme switch $r(scheme) { http {append base "$r(scheme)://"} ftp {} file {} } # authority if {[string length $r(authority)] != 0} { append base "$r(authority)" } # path if {[string length $r(path)] != 0} { append base "$r(path)" } else { append base "/" } # query if {[string length $r(query)] != 0} { append base "?$r(query)" } $var(widget) config -base $base if {$debug(tcl,hv)} { DumpURL r puts stderr "HVParseHTML base [$var(widget) cget -base]" } # we have a valid html $var(widget) clear # fix forms with no action HVFixHTMLForm $varname # and now, parse it $var(widget) parse $var(data) HVGotoHTML $varname } proc HVParseHTTP-EQUIV {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseHTTP-EQUIV" } if {[regexp {<HEAD>(.*)</HEAD>} $var(data) foo head]} { if {[regexp {<META HTTP-EQUIV} $head foo]} { # do it now, to be restored later if [info exists var(index)] { incr ${varname}(index) set var(index,$var(index)) "$var(url) $var(query)" set index $var(index) } set fn $var(fn) set del $var(delete) set data $var(data) # init HVSetResult $varname 200 {} HVSetData $varname {} {} # header foreach {line} [split $head "\n"] { set line [string trim $line] set line [string trim $line "<>"] set exp {META HTTP-EQUIV=(.*) CONTENT=(.*)} if [regexp $exp $line foo key value] { if {$key != {} && $value != {}} { lappend var(meta) \ [string trim $key {"}] [string trim $value {"}] } } } # data if {[regexp {<BODY>(.*)</BODY>} $data foo body]} { set var(fn) [tmpnam ds9 .http] set var(delete) 1 if [catch {open "$var(fn)" w} ch] { HVError $varname "[msgcat::mc {Unable to open file}] $var(fn)" return } HVParseMeta $varname switch $var(transfer) { binary { fconfigure $ch -translation binary -encoding binary puts -nonewline $ch $body } base64 { fconfigure $ch -translation binary -encoding binary puts -nonewline $ch [base64::decode $body] } default {puts -nonewline $ch $body} } catch {close $ch} HVParse $varname HVClearTmpFile $varname } # reset file values set var(fn) $fn set var(delete) $del if [info exists var(index)] { # reset index set var(index) $index HVClearIndex $varname $index } return 1 } } return 0 } proc HVParseImg {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseImg $var(url)" } if {$var(save)} { switch -- $var(mime) { "image/gif" {set fn [SaveFileDialog giffbox]} "image/jpeg" {set fn [SaveFileDialog jpegfbox]} "image/tiff" {set fn [SaveFileDialog tifffbox]} "image/png" {set fn [SaveFileDialog pngfbox]} } if {[string length "$fn"] != 0} { if {![catch {file rename -force "$var(fn)" "$fn"}]} { set var(fn) "$fn" set var(delete) 0 } } } switch -- $var(frame) { new {MultiLoadBase} current {} } ImportPhotoFile $var(fn) {} HVClearTmpFile $varname HVClearAll $varname HVUpdateDialog $varname } proc HVParseFITS {varname} { upvar #0 $varname var global $varname global ds9 global debug if {$var(save)} { switch -- $var(encoding) { gzip {FileLast savefitsfbox "ds9.fits.gz"} bzip2 {FileLast savefitsfbox "ds9.fits.bz2"} compress {FileLast savefitsfbox "ds9.fits.Z"} pack {FileLast savefitsfbox "ds9.fits.z"} default {FileLast savefitsfbox "ds9.fits"} } set fn [SaveFileDialog savefitsfbox] if {[string length "$fn"] != 0} { if {![catch {file rename -force "$var(fn)" "$fn"}]} { set var(fn) "$fn" set var(delete) 0 } } } switch -- $var(frame) { new {MultiLoadBase} current {} } StartLoad global loadParam set loadParam(load,type) allocgz set loadParam(load,layer) {} set loadParam(file,type) fits set loadParam(file,mode) {} set loadParam(file,name) "$var(fn)" set loadParam(file,fn) $loadParam(file,name) # may have to convert the file, based on content-encoding switch -- "$var(encoding)" { bzip2 { catch {set ch [open "| bunzip2 < $var(fn) " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } compress { catch {set ch [open "| uncompress < $var(fn) " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } pack { catch {set ch [open "| pcat $var(fn) " r]} set loadParam(load,type) channel set loadParam(channel,name) $ch } } ProcessLoad FinishLoad HVClearTmpFile $varname HVClearAll $varname HVUpdateDialog $varname } proc HVParseColormap {varname} { upvar #0 $varname var global $varname global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVParseColormap" } set fn [HVParseMimeParam $varname "name"] if {$fn == {}} { ParseURL $var(url) r set fn [file tail $r(path)] } if {![catch {file rename -force $var(fn) $ds9(tmpdir)/$fn}]} { LoadColormapFile $ds9(tmpdir)/$fn } HVClearAll $varname HVUpdateDialog $varname } proc HVParseVOT {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseVOT" } if [file exists "$var(fn)"] { CATVOTFile "$var(fn)" } HVClearTmpFile $varname HVClearAll $varname HVUpdateDialog $varname } proc HVParseSave {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVParseSave" } set fn [HVParseMimeParam $varname "name"] if {$fn == {}} { ParseURL $var(url) r set fn [file tail $r(path)] } FileLast savefitsfbox $fn set fn [SaveFileDialog savefitsfbox] if {[string length "$fn"] != 0} { if {![catch {file rename -force "$var(fn)" "$fn"}]} { set var(delete) 0 } } HVClearAll $varname HVUpdateDialog $varname } proc HVParseXPASet {varname} { upvar #0 $varname var global $varname global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVParseXPASet: [HVParseMimeParam $varname paramlist]" } if [info exists var(xpa,target)] { set target $var(xpa,target) } else { set target [HVParseMimeParam $varname target] } if {$target == "$ds9(title)" || $target == "DS9:*" || $target == "DS9:$ds9(title)" || $target == "*:$ds9(title)" || $target == "*:*" || $target == [XPAMethod]} { InitError hv CommSet $var(fn) [HVParseMimeParam $varname paramlist] } else { HVError $varname "[msgcat::mc {Unable to match target with XPA Mime request}] $url" } } proc HVGotoHTML {varname} { upvar #0 $varname var global $varname incr ${varname}(index) set var(index,$var(index)) "$var(url) $var(query)" global debug if {$debug(tcl,hv)} { puts stderr "HVGotoHTML $var(index) |$var(url)|$var(query)|$var(fragment)|" } if {[string length $var(fragment)] != 0} { if {$debug(tcl,idletasks)} { puts stderr "HVGotoHTML" } update idletasks $var(widget) yview $var(fragment) } else { $var(widget) yview moveto 0 } HVUpdateDialog $varname } proc HVClearCache {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVClearCache $varname" } foreach x [array names $varname "cache,file,*"] { catch {file delete $var($x)} } foreach x [array names $varname "cache,*"] { unset ${varname}($x) } } proc HVClearIndex {varname n} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVClearIndex $varname $n" } foreach x [array names $varname "index,*"] { set f [split $x ,] if {[lindex $f 1] > $n} { unset ${varname}($x) } } set var(index) $n } proc HVClearTmpFile {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVClearTmpFile" } if {$var(delete) && [string length "$var(fn)"] != 0} { if [file exists "$var(fn)"] { if {$debug(tcl,hv)} { puts stderr "HVClearTmpFile delete $var(fn)" } file delete "$var(fn)" } set var(fn) {} set var(delete) 0 } } proc HVUpdateDialog {varname} { upvar #0 $varname var global $varname # in case we've set the cursor $var(widget) configure -cursor {} global debug if {$debug(tcl,hv)} { puts stderr "HVUpdateDialog\n" } set id $var(index) set id [incr id -1] if {[info exists ${varname}(index,$id)]} { $var(mb).view entryconfig [msgcat::mc {Back}] -state normal } else { $var(mb).view entryconfig [msgcat::mc {Back}] -state disabled } set id $var(index) set id [incr id 1] if {[info exists ${varname}(index,$id)]} { $var(mb).view entryconfig [msgcat::mc {Forward}] -state normal } else { $var(mb).view entryconfig [msgcat::mc {Forward}] -state disabled } } proc HVRefresh {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVRefresh" } set var(delete) 0 HVParse $varname } proc HVProgress {varname token totalsize currentsize} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVProgress:$varname" } if {$totalsize != 0} { HVStatus $varname "$currentsize bytes of $totalsize bytes [expr int(double($currentsize)/$totalsize*100)]%" } else { HVStatus $varname "$currentsize bytes" } } proc HVFTPHtmlList {host path list} { global debug if {$debug(tcl,hv)} { puts stderr "HVFTPHtmlList $host $path" } if {[string range $path end end] != "/"} { append path {/} } set html {} append html "<html>\n" append html "<head>\n" append html "<title>Index of $path on $host</title>\n" append html "</head>\n" append html "<body>\n" append html "<h1>Index on $path on $host</h1>\n" append html "<hr>\n" append html "<pre>\n" foreach l $list { switch -- [llength $l] { 8 {set offset 4} 9 {set offset 5} 10 {set offset 4} 11 {set offset 5} default {set offset 5} } set ii [lindex $l [expr $offset+3]] switch -- [string range $l 0 0] { d { set new "<a href=\"ftp://$host$path$ii/\">$ii</A>" } l { set new "<a href=\"ftp://$host$path$ii\">$ii</A>" } default { set new "<a href=\"ftp://$host$path$ii\">$ii</A>" } } regsub $ii $l $new l append html "$l\n" } append html "</pre>\n" append html "</hr>\n" append html "</body>\n" return $html } proc HVFileHtmlList {path list} { global debug if {$debug(tcl,hv)} { puts stderr "HVFileHtmlList $path" } if {[string range $path end end] != "/"} { append path {/} } set html {} append html "<html>\n" append html "<head>\n" append html "<title>Index of $path</title>\n" append html "</head>\n" append html "<body>\n" append html "<h1>Index on $path</h1>\n" append html "<hr>\n" append html "<pre>\n" foreach l $list { switch -- [llength $l] { 8 {set offset 4} 9 {set offset 5} 10 {set offset 4} 11 {set offset 5} default {set offset 5} } set ii [lindex $l [expr $offset+3]] switch -- [string range $l 0 0] { d { set new "<a href=\"file:$path$ii/\">$ii</A>" } l { set new "<a href=\"file:$path$ii\">$ii</A>" } default { set new "<a href=\"file:$path$ii\">$ii</A>" } } regsub $ii $l $new l append html "$l\n" } append html "</pre>\n" append html "</hr>\n" append html "</body>\n" return $html } proc HVDirList {path} { global debug if {$debug(tcl,hv)} { puts stderr "HVDirList $path" } return [split [exec ls -l $path] \n] } proc HVSetURL {varname url query fragment} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVSetURL $url $query $fragment" } set var(url) $url set var(query) $query set var(fragment) $fragment } proc HVSetResult {varname code mime} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVSetResult $code $mime" } set var(code) $code set var(meta) {} set var(mime) $mime set var(mime,param) {} set var(cache) 0 set var(cache,images) 1 set var(expire) 0 set var(encoding) {} set var(transfer) {} set var(refresh,time) 0 set var(refresh,url) {} set var(refresh,id) 0 } proc HVSetData {varname data fn} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVSetData $fn" } set var(data) $data set var(text) {} set var(fn) "$fn" } proc HVSetAnalysis {varname aa which ii} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVSetAnalysis" } set var(analysis) $aa set var(analysis,which) $which set var(analysis,i) $ii } proc HVClearAll {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVClearAll" } HVSetURL $varname {} {} {} HVSetResult $varname {} {} HVSetData $varname {} {} HVSetAnalysis $varname 0 {} 0 } # CallBacks proc HVImageCB {varname args} { upvar #0 $varname var global $varname global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVImageCB $varname args: $args" } set url [lindex $args 0] if {$debug(tcl,hv)} { puts stderr "HVImageCB url: $url" } # do we have anything? if {[string length $url] == 0} { return } # do we have a width/height? set aa [lindex $args 3] set width [HVattrs width $aa 0] set height [HVattrs height $aa 0] set src [HVattrs src $aa 0] # check for percent (100%) in width/height if {![string is integer $width]} { set width 0 } if {![string is integer $height]} { set height 0 } if {$debug(tcl,hv)} { puts stderr "HVImageCB src: $width $height $src" } # we have a problem in that htmlwidget will not properly resolve a windows # file name, there for we may have a bad file name url # double check with the src attribute global tcl_platform switch $tcl_platform(platform) { unix {} windows { ParseURL $url r switch -- $r(scheme) { {} - file { if {![file exists $url]} { # bad, try src if [file exists $src] { set url $src } } } } } } set img [HVImageURL $varname $url $width $height] if {[string length $img] != 0} { return $img } else { if {$debug(tcl,hv)} { puts stderr "HVImageCB FAIL $url" } return $var(images,gray) } } proc HVImageURL {varname url width height} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVImageURL $varname $url $width $height" } # do we already have the image? if {[info exists ${varname}(images,$url)]} { if {$debug(tcl,hv)} { puts stderr "HVImageURL found image a $url" } return $var(images,$url) } ParseURL $url r set fn {} switch -- $r(scheme) { {} - file { if [file exists $r(path)] { # can't use -file for zvfs # catch {image create photo -file $r(path)} img set ch [open $r(path) r] fconfigure $ch -translation binary -encoding binary set dd [read $ch] close $ch unset ch catch {image create photo -data "$dd"} img unset dd } } ftp { set fn [tmpnam ds9 [file extension $r(path)]] set ftp [ftp::Open $r(authority) "ftp" "-ds9@" -mode passive] if {$ftp > -1} { set ftp::VERBOSE $debug(tcl,ftp) set "ftp::ftp${ftp}(Output)" FTPLog ftp::Type $ftp binary if [ftp::Get $ftp $r(path) "$fn"] { ftp::Close $ftp if {[file size "$fn"] == 0} { catch {file delete -force "$fn"} return {} } if {[catch {image create photo -file "$fn"} img]} { catch {file delete -force "$fn"} return {} } } } } http { set ch {} set fn [tmpnam ds9 [file extension $r(path)]] for {set ii 5} {$ii>0} {incr ii -1} { if [catch {open "$fn" w} ch] { HVError $varname "[msgcat::mc {Unable to open file}] $fn" return {} } global ihttp if [catch {set token \ [http::geturl $url \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -progress [list HVProgress $varname] \ -channel $ch \ -binary 1 \ -headers "[HVHTTPHeader $varname]" \ ]}] { # if there is a problem, just bail set ii 0 continue } # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} catch {close $ch} upvar #0 $token t set code [http::ncode $token] set meta $t(meta) # result? switch -- $code { 200 - 203 - 503 {set ii 0} 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $meta { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,hv)} { puts stderr "HVImageURL redirect $code to $value" } # clean up and resubmit set url $value http::cleanup $token catch {file delete -force "$fn"} } } } default { # in general, we don't want to know about this if {$debug(tcl,hv)} { puts stderr "HVImageURL HTTP Error: $code" } set ii 0 } } } catch {http::cleanup $token} if {[file size "$fn"] == 0} { catch {file delete -force "$fn"} return {} } if {[catch {image create photo -file "$fn"} img]} { catch {file delete -force "$fn"} return {} } } } # do we have an img? if {![info exists img]} { return {} } if {$debug(tcl,hv)} { puts stderr "HVImageURL got image $img" } # adjust image size if needed if {$width != 0 || $height != 0} { set iw [image width $img] set ih [image height $img] set doit 1 # check for one dimension of 0. calculate to maintain aspect ratio if {$width == 0} { set width [expr $iw*$height/$ih] # see if we have a bad resample dimension set wf [expr double($iw)*$height/$ih] if {$width != $wf} { if {$debug(tcl,hv)} { puts stderr "HVImageURL abort resample image $img width $wf" } set doit 0 } } if {$height == 0} { set height [expr $ih*$width/$iw] # see if we have a bad resample dimension set hf [expr double($ih)*$width/$iw] if {$height != $hf} { if {$debug(tcl,hv)} { puts stderr "HVImageURL abort resample image $img height $hf" } set doit 0 } } # check to resample if {$doit && ($width != $iw || $height != $ih)} { if {$debug(tcl,hv)} { puts stderr "HVImageURL resample image $iw->$width $ih->$height" } set img2 \ [image create photo -width $width -height $height] if {[catch {blt::winop image resample $img $img2 box} ]} { # just use existing img if {$debug(tcl,hv)} { puts stderr "HVImageURL error resample image $img" } } else { set tmp $img set img $img2 catch {image delete $tmp} } } } # delete any tmp files if {"$fn" != {}} { catch {file delete -force "$fn"} } if {$var(cache,images)} { set var(images,$url) $img } return $img } proc HVFontCB {varname sz args} { upvar #0 $varname var global $varname global ds9 global debug if {$debug(tcl,hv)} { puts stderr "HVFontCB $varname $sz $args" } set family $ds9($var(font)) set size $var(font,size) set weight $var(font,weight) set slant $var(font,slant) global ds9 foreach ff [concat [lindex $args 0]] { switch -- $ff { fixed { set family [font configure TkFixedFont -family] set size [PixelsToPoints [font configure TkFixedFont -size]] } bold {set weight bold} italic {set slant italic} } } switch -- $sz { 1 {incr size -3} 2 {incr size -2} 3 {} 4 {incr size 6} 5 {incr size 12} 6 {incr size 24} 7 {incr size 36} } if {$debug(tcl,hv)} { puts stderr "HVFontCB \{$family\} $size $weight $slant" } return "\{$family\} $size $weight $slant" } proc HVNoScriptCB {varname n tag args} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { # puts stderr "HVNoScriptCB $varname $n $tag $args" } } proc HVScriptCB {varname args} { upvar #0 $varname var global debug if {$debug(tcl,hv)} { # puts stderr "HVScriptCB $varname $args" } } proc HVFrameCB {varname args} { upvar #0 $varname var global $varname if {$debug(tcl,hv)} { puts stderr "HVFrameCB $varname $args" } } proc HVAppletCB {varname w args} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVAppletCB $varname $w $args" } } proc HVParseMimeParam {varname key} { upvar #0 $varname var global $varname foreach {pp} [split $var(mime,param) {;}] { set id [string first {=} $pp] set name [string trim [string range $pp 0 [expr $id-1]]] set value [string trim [string range $pp [expr $id+1] end]] if {[string equal -nocase $name $key]} { return [string trim $value {"'}] } } return {} } ��������������������������������������������������������������������������������������./saods9/src/xpa.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000127753�12131601440�013175� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc InitXPA {} { global pds9 global env if {!$pds9(xpa)} { return } if {[info exists env(XPA_METHOD)]} { if {$env(XPA_METHOD) != {local}} { if {[checkdns {} 5]} { set env(XPA_METHOD) local Error [msgcat::mc {XPA unable to verify hostname, setting XPA_METHOD to LOCAL}] } } } else { if {[checkdns {} 5]} { set env(XPA_METHOD) local Error [msgcat::mc {XPA unable to verify hostname, setting XPA_METHOD to LOCAL}] } } catch {CreateXPA} UpdateFileMenu } proc CreateXPA {} { global xpa global ds9 set xpa [xpacmdnew "DS9" $ds9(title)] xpacmdadd $xpa 2mass \ {} \ XPASend2MASS {} {} \ XPARcvd2MASS {} "fillbuf=false" xpacmdadd $xpa 3d \ {} \ XPASend3D {} {} \ XPARcvd3D {} "fillbuf=false" xpacmdadd $xpa about \ {} \ XPASendAbout {} {} \ {} {} {} xpacmdadd $xpa align \ {} \ XPASendAlign {} {} \ XPARcvdAlign {} {} xpacmdadd $xpa analysis \ {} \ XPASendAnalysis {} {} \ XPARcvdAnalysis {} {} xpacmdadd $xpa array \ {} \ XPASendArray {} {} \ XPARcvdArray {} "fillbuf=false" xpacmdadd $xpa background \ {} \ XPASendBg {} {} \ XPARcvdBg {} {} xpacmdadd $xpa backup \ {} \ {} {} {} \ XPARcvdBackup {} {} xpacmdadd $xpa bg \ {} \ XPASendBg {} {} \ XPARcvdBg {} {} xpacmdadd $xpa blink \ {} \ XPASendBlink {} {} \ XPARcvdBlink {} "fillbuf=false" xpacmdadd $xpa bin \ {} \ XPASendBin {} {} \ XPARcvdBin {} "fillbuf=false" xpacmdadd $xpa cat \ {} \ XPASendCAT {} {} \ XPARcvdCAT {} "fillbuf=false" xpacmdadd $xpa catalog \ {} \ XPASendCAT {} {} \ XPARcvdCAT {} "fillbuf=false" xpacmdadd $xpa cd \ {} \ XPASendCD {} {} \ XPARcvdCD {} "fillbuf=false" xpacmdadd $xpa cmap \ {} \ XPASendCmap {} {} \ XPARcvdCmap {} "fillbuf=false" xpacmdadd $xpa colorbar \ {} \ XPASendColorbar {} {} \ XPARcvdColorbar {} "fillbuf=false" xpacmdadd $xpa console \ {} \ {} {} {} \ XPARcvdConsole {} "fillbuf=false" xpacmdadd $xpa contour \ {} \ XPASendContour {} {} \ XPARcvdContour {} "fillbuf=false" xpacmdadd $xpa contours \ {} \ XPASendContour {} {} \ XPARcvdContour {} "fillbuf=false" xpacmdadd $xpa crop \ {} \ XPASendCrop {} {} \ XPARcvdCrop {} "fillbuf=false" xpacmdadd $xpa crosshair \ {} \ XPASendCrosshair {} {} \ XPARcvdCrosshair {} "fillbuf=false" xpacmdadd $xpa cube \ {} \ XPASendCube {} {} \ XPARcvdCube {} "fillbuf=false" xpacmdadd $xpa cursor \ {} \ {} {} {} \ XPARcvdCursor {} "fillbuf=false" xpacmdadd $xpa data \ {} \ XPASendData {} {} \ {} {} {} xpacmdadd $xpa datacube \ {} \ XPASendCube {} {} \ XPARcvdCube {} "fillbuf=false" xpacmdadd $xpa dss \ {} \ XPASendSAO {} {} \ XPARcvdSAO {} "fillbuf=false" xpacmdadd $xpa dsssao \ {} \ XPASendSAO {} {} \ XPARcvdSAO {} "fillbuf=false" xpacmdadd $xpa dsseso \ {} \ XPASendESO {} {} \ XPARcvdESO {} "fillbuf=false" xpacmdadd $xpa dssstsci \ {} \ XPASendSTSCI {} {} \ XPARcvdSTSCI {} "fillbuf=false" xpacmdadd $xpa exit \ {} \ {} {} {} \ XPARcvdExit {} "fillbuf=false" xpacmdadd $xpa export \ {} \ {} {} {} \ XPARcvdExport {} "fillbuf=false" xpacmdadd $xpa file \ {} \ XPASendFile {} {} \ XPARcvdFile {} "fillbuf=false" xpacmdadd $xpa first \ {} \ XPASendFIRST {} {} \ XPARcvdFIRST {} "fillbuf=false" xpacmdadd $xpa fits \ {} \ XPASendFits {} "fillbuf=false" \ XPARcvdFits {} "fillbuf=false" xpacmdadd $xpa frame \ {} \ XPASendFrame {} {} \ XPARcvdFrame {} "fillbuf=false" xpacmdadd $xpa gif \ {} \ XPASendGIF {} {} \ XPARcvdGIF {} "fillbuf=false" xpacmdadd $xpa grid \ {} \ XPASendGrid {} {} \ XPARcvdGrid {} "fillbuf=false" xpacmdadd $xpa header \ {} \ {} {} {} \ XPARcvdHeader {} "fillbuf=false" xpacmdadd $xpa height \ {} \ XPASendHeight {} {} \ XPARcvdHeight {} "fillbuf=false" xpacmdadd $xpa iconify \ {} \ XPASendIconify {} {} \ XPARcvdIconify {} "fillbuf=false" xpacmdadd $xpa iis \ {} \ XPASendIIS {} {} \ XPARcvdIIS {} "fillbuf=false" xpacmdadd $xpa imexam \ {} \ XPASendImexam {} {} \ {} {} {} xpacmdadd $xpa jpg \ {} \ XPASendJPEG {} {} \ XPARcvdJPEG {} "fillbuf=false" xpacmdadd $xpa jpeg \ {} \ XPASendJPEG {} {} \ XPARcvdJPEG {} "fillbuf=false" xpacmdadd $xpa lock \ {} \ XPASendLock {} {} \ XPARcvdLock {} "fillbuf=false" xpacmdadd $xpa lower \ {} \ {} {} {} \ XPARcvdLower {} "fillbuf=false" xpacmdadd $xpa magnifier \ {} \ XPASendMagnifier {} {} \ XPARcvdMagnifier {} "fillbuf=false" xpacmdadd $xpa mask \ {} \ XPASendMask {} {} \ XPARcvdMask {} "fillbuf=false" xpacmdadd $xpa match \ {} \ {} {} {} \ XPARcvdMatch {} "fillbuf=false" xpacmdadd $xpa mecube \ {} \ XPASendMECube {} "fillbuf=false" \ XPARcvdMECube {} "fillbuf=false" xpacmdadd $xpa memf \ {} \ {} {} {} \ XPARcvdMultiFrame {} "fillbuf=false" xpacmdadd $xpa minmax \ {} \ XPASendMinMax {} {} \ XPARcvdMinMax {} "fillbuf=false" xpacmdadd $xpa mode \ {} \ XPASendMode {} {} \ XPARcvdMode {} "fillbuf=false" xpacmdadd $xpa mosaic \ {} \ XPASendMosaic {} {} \ XPARcvdMosaic {} "fillbuf=false" xpacmdadd $xpa mosaicimage \ {} \ XPASendMosaicImage {} {} \ XPARcvdMosaicImage {} "fillbuf=false" # backward compatibility xpacmdadd $xpa mosaicwcs \ {} \ XPASendMosaicWCS {} {} \ XPARcvdMosaicWCS {} "fillbuf=false" # backward compatibility xpacmdadd $xpa mosaiciraf \ {} \ {} {} {} \ XPARcvdMosaicIRAF {} "fillbuf=false" # backward compatibility xpacmdadd $xpa mosaicimagewcs \ {} \ XPASendMosaicImageWCS {} {} \ XPARcvdMosaicImageWCS {} "fillbuf=false" # backward compatibility xpacmdadd $xpa mosaicimageiraf \ {} \ {} {} {} \ XPARcvdMosaicImageIRAF {} "fillbuf=false" # backward compatibility xpacmdadd $xpa mosaicimagewfpc2 \ {} \ {} {} {} \ XPARcvdMosaicImageWFPC2 {} "fillbuf=false" xpacmdadd $xpa multiframe \ {} \ {} {} {} \ XPARcvdMultiFrame {} "fillbuf=false" xpacmdadd $xpa movie \ {} \ {} {} {} \ XPARcvdMovie {} "fillbuf=false" xpacmdadd $xpa nameserver \ {} \ XPASendNRES {} {} \ XPARcvdNRES {} "fillbuf=false" xpacmdadd $xpa nan \ {} \ XPASendNan {} {} \ XPARcvdNan {} {} xpacmdadd $xpa nrrd \ {} \ XPASendNRRD {} {} \ XPARcvdNRRD {} "fillbuf=false" xpacmdadd $xpa nvss \ {} \ XPASendNVSS {} {} \ XPARcvdNVSS {} "fillbuf=false" xpacmdadd $xpa orient \ {} \ XPASendOrient {} {} \ XPARcvdOrient {} "fillbuf=false" xpacmdadd $xpa {page setup} \ {} \ XPASendPageSetup {} {} \ XPARcvdPageSetup {} "fillbuf=false" xpacmdadd $xpa pagesetup \ {} \ XPASendPageSetup {} {} \ XPARcvdPageSetup {} "fillbuf=false" xpacmdadd $xpa pspagesetup \ {} \ XPASendPSPageSetup {} {} \ XPARcvdPSPageSetup {} "fillbuf=false" xpacmdadd $xpa pan \ {} \ XPASendPan {} {} \ XPARcvdPan {} "fillbuf=false" xpacmdadd $xpa pixeltable \ {} \ XPASendPixelTable {} {} \ XPARcvdPixelTable {} "fillbuf=false" xpacmdadd $xpa plot \ {} \ XPASendPlot {} {} \ XPARcvdPlot {} {} xpacmdadd $xpa png \ {} \ XPASendPNG {} {} \ XPARcvdPNG {} "fillbuf=false" xpacmdadd $xpa prefs \ {} \ XPASendPrefs {} {} \ XPARcvdPrefs {} "fillbuf=false" xpacmdadd $xpa preserve \ {} \ XPASendPreserve {} {} \ XPARcvdPreserve {} "fillbuf=false" xpacmdadd $xpa print \ {} \ XPASendPrint {} {} \ XPARcvdPrint {} "fillbuf=false" xpacmdadd $xpa psprint \ {} \ XPASendPSPrint {} {} \ XPARcvdPSPrint {} "fillbuf=false" xpacmdadd $xpa quit \ {} \ {} {} {} \ XPARcvdExit {} "fillbuf=false" xpacmdadd $xpa raise \ {} \ {} {} {} \ XPARcvdRaise {} "fillbuf=false" xpacmdadd $xpa region \ {} \ XPASendRegions {} {} \ XPARcvdRegions {} "fillbuf=false" xpacmdadd $xpa regions \ {} \ XPASendRegions {} {} \ XPARcvdRegions {} "fillbuf=false" xpacmdadd $xpa restore \ {} \ {} {} {} \ XPARcvdRestore {} {} xpacmdadd $xpa rgb \ {} \ XPASendRGB {} {} \ XPARcvdRGB {} "fillbuf=false" xpacmdadd $xpa rgbarray \ {} \ XPASendRGBArray {} {} \ XPARcvdRGBArray {} "fillbuf=false" xpacmdadd $xpa rgbcube \ {} \ XPASendRGBCube {} {} \ XPARcvdRGBCube {} "fillbuf=false" xpacmdadd $xpa rgbimage \ {} \ XPASendRGBImage {} {} \ XPARcvdRGBImage {} "fillbuf=false" xpacmdadd $xpa rotate \ {} \ XPASendRotate {} {} \ XPARcvdRotate {} "fillbuf=false" xpacmdadd $xpa samp \ {} \ {} {} {} \ XPARcvdSAMP {} "fillbuf=false" xpacmdadd $xpa save \ {} \ {} {} {} \ XPARcvdSave {} "fillbuf=false" xpacmdadd $xpa saveimage \ {} \ {} {} {} \ XPARcvdSaveImage {} "fillbuf=false" # backward compatibility xpacmdadd $xpa savefits \ {} \ {} {} {} \ XPARcvdSave {} "fillbuf=false" # backward compatibility xpacmdadd $xpa savempeg \ {} \ {} {} {} \ XPARcvdMovie {} "fillbuf=false" xpacmdadd $xpa scale \ {} \ XPASendScale {} {} \ XPARcvdScale {} "fillbuf=false" # backward compatibility xpacmdadd $xpa sfits \ {} \ {} {} {} \ XPARcvdSFits {} "fillbuf=false" xpacmdadd $xpa single \ {} \ XPASendSingle {} {} \ XPARcvdSingle {} "fillbuf=false" xpacmdadd $xpa shm \ {} \ XPASendShm {} {} \ XPARcvdShm {} "fillbuf=false" xpacmdadd $xpa skyview \ {} \ XPASendSkyView {} {} \ XPARcvdSkyView {} "fillbuf=false" xpacmdadd $xpa sleep \ {} \ {} {} {} \ XPARcvdSleep {} "fillbuf=false" xpacmdadd $xpa slice \ {} \ XPASendCube {} {} \ XPARcvdCube {} "fillbuf=false" # backward compatibility xpacmdadd $xpa smosaic \ {} \ {} {} {} \ XPARcvdSMosaic {} "fillbuf=false" # backward compatibility xpacmdadd $xpa smosaicwcs \ {} \ {} {} {} \ XPARcvdSMosaicWCS {} "fillbuf=false" # backward compatibility xpacmdadd $xpa smosaiciraf \ {} \ {} {} {} \ XPARcvdSMosaicIRAF {} "fillbuf=false" xpacmdadd $xpa smooth \ {} \ XPASendSmooth {} {} \ XPARcvdSmooth {} "fillbuf=false" xpacmdadd $xpa source \ {} \ {} {} {} \ XPARcvdSource {} "fillbuf=false" # backward compatibility xpacmdadd $xpa srgbcube \ {} \ {} {} {} \ XPARcvdSRGBCube {} "fillbuf=false" xpacmdadd $xpa tcl \ {} \ {} {} {} \ XPARcvdTcl {} {} xpacmdadd $xpa theme \ {} \ XPASendTheme {} {} \ XPARcvdTheme {} "fillbuf=false" xpacmdadd $xpa threads \ {} \ XPASendThreads {} {} \ XPARcvdThreads {} {} xpacmdadd $xpa tif \ {} \ XPASendTIFF {} {} \ XPARcvdTIFF {} "fillbuf=false" xpacmdadd $xpa tiff \ {} \ XPASendTIFF {} {} \ XPARcvdTIFF {} "fillbuf=false" xpacmdadd $xpa tile \ {} \ XPASendTile {} {} \ XPARcvdTile {} "fillbuf=false" xpacmdadd $xpa update \ {} \ {} {} {} \ XPARcvdUpdate {} "fillbuf=false" xpacmdadd $xpa url \ {} \ {} {} {} \ XPARcvdURLFits {} {} xpacmdadd $xpa version \ {} \ XPASendVersion {} {} \ {} {} {} xpacmdadd $xpa view \ {} \ XPASendView {} {} \ XPARcvdView {} "fillbuf=false" xpacmdadd $xpa vo \ {} \ XPASendVO {} {} \ XPARcvdVO {} "fillbuf=false" xpacmdadd $xpa wcs \ {} \ XPASendWCS {} {} \ XPARcvdWCS {} "fillbuf=false" xpacmdadd $xpa web \ {} \ XPASendWeb {} {} \ XPARcvdWeb {} "fillbuf=false" xpacmdadd $xpa width \ {} \ XPASendWidth {} {} \ XPARcvdWidth {} "fillbuf=false" xpacmdadd $xpa zscale \ {} \ XPASendZScale {} {} \ XPARcvdZScale {} "fillbuf=false" xpacmdadd $xpa zoom \ {} \ XPASendZoom {} {} \ XPARcvdZoom {} "fillbuf=false" } proc XPASend2MASS {xpa cdata param} { InitError xpa catch {ProcessSend2MASSCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvd2MASS {xpa cdata param buf len} { XPADebug "XPARcvd2MASS" $param InitError xpa catch {set i 0; Process2MASSCmd param i} XPACatchError $xpa } proc XPASend3D {xpa cdata param} { InitError xpa catch {ProcessSend3DCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvd3D {xpa cdata param buf len} { XPADebug "XPARcvd3D" $param InitError xpa catch {set i 0; Process3DCmd param i} XPACatchError $xpa } proc XPASendAbout {xpa cdata param} { InitError xpa catch {ProcessSendAboutCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPASendAlign {xpa cdata param} { InitError xpa catch {ProcessSendAlignCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdAlign {xpa cdata param buf len} { XPADebug "XPARcvdAlign" $param InitError xpa catch {set i 0; ProcessAlignCmd param i} XPACatchError $xpa } proc XPASendAnalysis {xpa cdata param} { InitError xpa catch {ProcessSendAnalysisCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPARcvdAnalysis {xpa cdata param buf len} { XPADebug "XPARcvdAnalysis" $param InitError xpa catch {set i 0; ProcessAnalysisCmd param i $buf {}} XPACatchError $xpa } proc XPASendArray {xpa cdata param} { InitError xpa catch {ProcessSendArrayCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdArray {xpa cdata param buf len} { XPADebug "XPARcvdArray" $param InitError xpa catch {set i 0; ProcessArrayCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendBg {xpa cdata param} { InitError xpa catch {ProcessSendBgCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdBg {xpa cdata param buf len} { XPADebug "XPARcvdBg" $param InitError xpa catch {set i 0; ProcessBgCmd param i} XPACatchError $xpa } proc XPARcvdBackup {xpa cdata param buf len} { XPADebug "XPARcvdBackup" $param InitError xpa catch {set i 0; ProcessBackupCmd param i} XPACatchError $xpa } proc XPASendBlink {xpa cdata param} { InitError xpa catch {ProcessSendBlinkCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdBlink {xpa cdata param buf len} { XPADebug "XPARcvdBlink" $param InitError xpa catch {set i 0; ProcessBlinkCmd param i} XPACatchError $xpa } proc XPASendBin {xpa cdata param} { InitError xpa catch {ProcessSendBinCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdBin {xpa cdata param buf len} { XPADebug "XPARcvdBin" $param InitError xpa catch {set i 0; ProcessBinCmd param i} XPACatchError $xpa } proc XPASendCAT {xpa cdata param} { InitError xpa catch {ProcessSendCatalogCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPARcvdCAT {xpa cdata param buf len} { XPADebug "XPARcvdCat" $param InitError xpa catch {set i 0; ProcessCatalogCmd param i} XPACatchError $xpa } proc XPASendCD {xpa cdata param} { InitError xpa catch {ProcessSendCDCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdCD {xpa cdata param buf len} { XPADebug "XPARcvdCD" $param InitError xpa catch {set i 0; ProcessCDCmd param i} XPACatchError $xpa } proc XPARcvdConsole {xpa cdata param buf len} { XPADebug "XPARcvdConsole" $param InitError xpa catch {set i 0; ProcessConsoleCmd param i} XPACatchError $xpa } proc XPASendContour {xpa cdata param} { InitError xpa catch {ProcessSendContourCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPARcvdContour {xpa cdata param buf len} { XPADebug "XPARcvdContour" $param InitError xpa catch {set i 0; ProcessContourCmd param i} XPACatchError $xpa } proc XPASendCmap {xpa cdata param} { InitError xpa catch {ProcessSendCmapCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdCmap {xpa cdata param buf len} { XPADebug "XPARcvdCmap" $param InitError xpa catch {set i 0; ProcessCmapCmd param i} XPACatchError $xpa } proc XPASendColorbar {xpa cdata param} { InitError xpa catch {ProcessSendColorbarCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdColorbar {xpa cdata param buf len} { XPADebug "XPARcvdColorbar" $param InitError xpa catch {set i 0; ProcessColorbarCmd param i} XPACatchError $xpa } proc XPASendCrop {xpa cdata param} { InitError xpa catch {ProcessSendCropCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdCrop {xpa cdata param buf len} { XPADebug "XPARcvdCrop" $param InitError xpa catch {set i 0; ProcessCropCmd param i} XPACatchError $xpa } proc XPASendCrosshair {xpa cdata param} { InitError xpa catch {ProcessSendCrosshairCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdCrosshair {xpa cdata param buf len} { XPADebug "XPARcvdCrosshair" $param InitError xpa catch {set i 0; ProcessCrosshairCmd param i} XPACatchError $xpa } proc XPASendCube {xpa cdata param} { InitError xpa catch {ProcessSendCubeCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdCube {xpa cdata param buf len} { XPADebug "XPARcvdCube" $param InitError xpa catch {set i 0; ProcessCubeCmd param i} XPACatchError $xpa } proc XPARcvdCursor {xpa cdata param buf len} { XPADebug "XPARcvdCursor" $param InitError xpa catch {set i 0; ProcessCursorCmd param i} XPACatchError $xpa } proc XPASendData {xpa cdata param} { InitError xpa catch {ProcessSendDataCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPASendSAO {xpa cdata param} { InitError xpa catch {ProcessSendSAOCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdSAO {xpa cdata param buf len} { XPADebug "XPARcvdSAO" $param InitError xpa catch {set i 0; ProcessSAOCmd param i} XPACatchError $xpa } proc XPASendESO {xpa cdata param} { InitError xpa catch {ProcessSendESOCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdESO {xpa cdata param buf len} { XPADebug "XPARcvdESO" $param InitError xpa catch {set i 0; ProcessESOCmd param i} XPACatchError $xpa } proc XPASendSTSCI {xpa cdata param} { InitError xpa catch {ProcessSendSTSCICmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdSTSCI {xpa cdata param buf len} { XPADebug "XPARcvdSTSCI" $param InitError xpa catch {set i 0; ProcessSTSCICmd param i} XPACatchError $xpa } proc XPARcvdExit {xpa cdata param buf len} { XPADebug "XPARcvdExit" $param InitError xpa catch {set i 0; ProcessQuitCmd param i} XPACatchError $xpa } proc XPARcvdExport {xpa cdata param buf len} { XPADebug "XPARcvdExport" $param InitError xpa catch {set i 0; ProcessExportCmd param i} XPACatchError $xpa } proc XPASendFile {xpa cdata param} { InitError xpa catch {ProcessSendFileCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdFile {xpa cdata param buf len} { XPADebug "XPARcvdFile" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessFileCmd param i [xparec $xpa datafd] [xparec $xpa datachan] {}} win32 {ProcessFileCmd param i [xparec $xpa datafd] dummy {}} } } XPACatchError $xpa } proc XPASendFIRST {xpa cdata param} { InitError xpa catch {ProcessSendFIRSTCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdFIRST {xpa cdata param buf len} { XPADebug "XPARcvdFIRST" $param InitError xpa catch {set i 0; ProcessFIRSTCmd param i} XPACatchError $xpa } proc XPASendFits {xpa cdata param} { InitError xpa catch {ProcessSendFitsCmd xpasetbuf $xpa $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdFits {xpa cdata param buf len} { XPADebug "XPARcvdFits" $param InitError xpa catch {set i 0; ProcessFitsCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendFrame {xpa cdata param} { InitError xpa catch {ProcessSendFrameCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdFrame {xpa cdata param buf len} { XPADebug "XPARcvdFrame" $param InitError xpa catch {set i 0; ProcessFrameCmd param i} XPACatchError $xpa } proc XPASendGIF {xpa cdata param} { InitError xpa catch { global ds9 switch $ds9(wm) { x11 - aqua {ProcessSendGIFCmd {} {} $param [xparec $xpa datachan] {}} win32 {ProcessSendGIFCmd {} {} $param dummy {}} } } XPACatchError $xpa } proc XPARcvdGIF {xpa cdata param buf len} { XPADebug "XPARcvdGIF" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessGIFCmd param i [xparec $xpa datachan] {}} win32 {ProcessGIFCmd param i dummy {}} } } XPACatchError $xpa } proc XPASendGrid {xpa cdata param} { InitError xpa catch {ProcessSendGridCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdGrid {xpa cdata param buf len} { XPADebug "XPARcvdGrid" $param InitError xpa catch {set i 0; ProcessGridCmd param i} XPACatchError $xpa } proc XPARcvdHeader {xpa cdata param buf len} { XPADebug "XPARcvdHeader" $param InitError xpa catch {set i 0; ProcessHeaderCmd param i} XPACatchError $xpa } proc XPASendHeight {xpa cdata param} { InitError xpa catch {ProcessSendHeightCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdHeight {xpa cdata param buf len} { XPADebug "XPARcvdHeight" $param InitError xpa catch {set i 0; ProcessHeightCmd param i} XPACatchError $xpa } proc XPASendIconify {xpa cdata param} { InitError xpa catch {ProcessSendIconifyCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdIconify {xpa cdata param buf len} { XPADebug "XPARcvdIconify" $param InitError xpa catch {set i 0; ProcessIconifyCmd param i} XPACatchError $xpa } proc XPASendIIS {xpa cdata param} { InitError xpa catch {ProcessSendIISCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdIIS {xpa cdata param buf len} { XPADebug "XPARcvdIIS" $param InitError xpa catch {set i 0; ProcessIISCmd param i} XPACatchError $xpa } proc XPASendImexam {xpa cdata param} { InitError xpa catch {ProcessSendImexamCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPASendJPEG {xpa cdata param} { InitError xpa catch { global ds9 switch $ds9(wm) { x11 - aqua {ProcessSendJPEGCmd {} {} $param [xparec $xpa datachan] {}} win32 {ProcessSendJPEGCmd {} {} $param dummy {}} } } XPACatchError $xpa } proc XPARcvdJPEG {xpa cdata param buf len} { XPADebug "XPARcvdJPEG" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessJPEGCmd param i [xparec $xpa datachan] {}} win32 {ProcessJPEGCmd param i dummy {}} } } XPACatchError $xpa } proc XPASendLock {xpa cdata param} { InitError xpa catch {ProcessSendLockCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdLock {xpa cdata param buf len} { XPADebug "XPARcvdLock" $param InitError xpa catch {set i 0; ProcessLockCmd param i} XPACatchError $xpa } proc XPARcvdLower {xpa cdata param buf len} { XPADebug "XPARcvdLower" $param InitError xpa catch {set i 0; ProcessLowerCmd param i} XPACatchError $xpa } proc XPASendMagnifier {xpa cdata param} { InitError xpa catch {ProcessSendMagnifierCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdMagnifier {xpa cdata param buf len} { XPADebug "XPARcvdMagnifier" $param InitError xpa catch {set i 0; ProcessMagnifierCmd param i} XPACatchError $xpa } proc XPASendMask {xpa cdata param} { InitError xpa catch {ProcessSendMaskCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdMask {xpa cdata param buf len} { XPADebug "XPARcvdMask" $param InitError xpa catch {set i 0; ProcessMaskCmd param i} XPACatchError $xpa } proc XPARcvdMatch {xpa cdata param buf len} { XPADebug "XPARcvdMatch" $param InitError xpa catch {set i 0; ProcessMatchCmd param i} XPACatchError $xpa } proc XPASendMECube {xpa cdata param} { InitError xpa catch {ProcessSendMECubeCmd xpasetbuf $xpa $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdMECube {xpa cdata param buf len} { XPADebug "XPARcvdMECube" $param InitError xpa catch {set i 0; ProcessMECubeCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendMinMax {xpa cdata param} { InitError xpa catch {ProcessSendMinMaxCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdMinMax {xpa cdata param buf len} { XPADebug "XPARcvdMinMax" $param InitError xpa catch {set i 0; ProcessMinMaxCmd param i} XPACatchError $xpa } proc XPASendMode {xpa cdata param} { InitError xpa catch {ProcessSendModeCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdMode {xpa cdata param buf len} { XPADebug "XPARcvdMode" $param InitError xpa catch {set i 0; ProcessModeCmd param i} XPACatchError $xpa } proc XPASendMosaic {xpa cdata param} { InitError xpa catch {ProcessSendMosaicCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdMosaic {xpa cdata param buf len} { XPADebug "XPARcvdMosaic" $param InitError xpa catch {set i 0; ProcessMosaicCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendMosaicImage {xpa cdata param} { InitError xpa catch {ProcessSendMosaicImageCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdMosaicImage {xpa cdata param buf len} { XPADebug "XPARcvdMosaicImage" $param InitError xpa catch {set i 0; ProcessMosaicImageCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPASendMosaicWCS {xpa cdata param} { InitError xpa catch {ProcessSendMosaicWCSCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdMosaicWCS {xpa cdata param buf len} { XPADebug "XPARcvdMosaicWCS" $param InitError xpa catch {set i 0; ProcessMosaicWCSCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdMosaicIRAF {xpa cdata param buf len} { XPADebug "XPARcvdMosaicIRAF" $param InitError xpa catch {set i 0; ProcessMosaicIRAFCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPASendMosaicImageWCS {xpa cdata param} { InitError xpa catch {ProcessSendMosaicImageWCSCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdMosaicImageWCS {xpa cdata param buf len} { XPADebug "XPARcvdMosaicImageWCS" $param InitError xpa catch {set i 0; ProcessMosaicImageWCSCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdMosaicImageIRAF {xpa cdata param buf len} { XPADebug "XPARcvdMosaicImageIRAF" $param InitError xpa catch {set i 0; ProcessMosaicImageIRAFCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdMosaicImageWFPC2 {xpa cdata param buf len} { XPADebug "XPARcvdMosaicImageWFPC2" $param InitError xpa catch {set i 0; ProcessMosaicImageWFPC2Cmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdMovie {xpa cdata param buf len} { XPADebug "XPARcvdMovie" $param InitError xpa catch {set i 0; ProcessMovieCmd param i} XPACatchError $xpa } proc XPARcvdMultiFrame {xpa cdata param buf len} { XPADebug "XPARcvdMultiFrame" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessMultiFrameCmd param i [xparec $xpa datachan] {}} win32 {ProcessMultiFrameCmd param i dummy {}} } } XPACatchError $xpa } proc XPASendNan {xpa cdata param} { InitError xpa catch {ProcessSendNanCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdNan {xpa cdata param buf len} { XPADebug "XPARcvdNan" $param InitError xpa catch {set i 0; ProcessNanCmd param i} XPACatchError $xpa } proc XPASendNRES {xpa cdata param} { InitError xpa catch {ProcessSendNRESCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdNRES {xpa cdata param buf len} { XPADebug "XPARcvdNRES" $param InitError xpa catch {set i 0; ProcessNRESCmd param i} XPACatchError $xpa } proc XPASendNRRD {xpa cdata param} { InitError xpa catch {ProcessSendNRRDCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdNRRD {xpa cdata param buf len} { XPADebug "XPARcvdNRRD" $param InitError xpa catch {set i 0; ProcessNRRDCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendNVSS {xpa cdata param} { InitError xpa catch {ProcessSendNVSSCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdNVSS {xpa cdata param buf len} { XPADebug "XPARcvdNVSS" $param InitError xpa catch {set i 0; ProcessNVSSCmd param i} XPACatchError $xpa } proc XPASendOrient {xpa cdata param} { InitError xpa catch {ProcessSendOrientCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdOrient {xpa cdata param buf len} { XPADebug "XPARcvdOrient" $param InitError xpa catch {set i 0; ProcessOrientCmd param i} XPACatchError $xpa } proc XPASendPageSetup {xpa cdata param} { InitError xpa catch {ProcessSendPageSetupCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPageSetup {xpa cdata param buf len} { XPADebug "XPARcvdPageSetup" $param InitError xpa catch {set i 0; ProcessPageSetupCmd param i} XPACatchError $xpa } proc XPASendPSPageSetup {xpa cdata param} { InitError xpa catch {ProcessSendPSPageSetupCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPSPageSetup {xpa cdata param buf len} { XPADebug "XPARcvdPSPageSetup" $param InitError xpa catch {set i 0; ProcessPSPageSetupCmd param i} XPACatchError $xpa } proc XPASendPan {xpa cdata param} { InitError xpa catch {ProcessSendPanCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPan {xpa cdata param buf len} { XPADebug "XPARcvdPan" $param InitError xpa catch {set i 0; ProcessPanCmd param i} XPACatchError $xpa } proc XPASendPixelTable {xpa cdata param} { InitError xpa catch {ProcessSendPixelTableCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPARcvdPixelTable {xpa cdata param buf len} { XPADebug "XPARcvdPixelTable" $param InitError xpa catch {set i 0; ProcessPixelTableCmd param i} XPACatchError $xpa } proc XPASendPlot {xpa cdata param} { InitError xpa catch {ProcessSendPlotCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPlot {xpa cdata param buf len} { XPADebug "XPARcvdPlot" $param InitError xpa catch {set i 0; ProcessPlotCmd param i $buf {}} XPACatchError $xpa } proc XPASendPNG {xpa cdata param} { InitError xpa catch { global ds9 switch $ds9(wm) { x11 - aqua {ProcessSendPNGCmd {} {} $param [xparec $xpa datachan] {}} win32 {ProcessSendPNGCmd {} {} $param dummy {}} } } XPACatchError $xpa } proc XPARcvdPNG {xpa cdata param buf len} { XPADebug "XPARcvdPNG" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessPNGCmd param i [xparec $xpa datachan] {}} win32 {ProcessPNGCmd param i dummy {}} } } XPACatchError $xpa } proc XPASendPrefs {xpa cdata param} { InitError xpa catch {ProcessSendPrefsCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPrefs {xpa cdata param buf len} { XPADebug "XPARcvdPrefs" $param InitError xpa catch {set i 0; ProcessPrefsCmd param i} XPACatchError $xpa } proc XPASendPreserve {xpa cdata param} { InitError xpa catch {ProcessSendPreserveCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPreserve {xpa cdata param buf len} { XPADebug "XPARcvdPreserve" $param InitError xpa catch {set i 0; ProcessPreserveCmd param i} XPACatchError $xpa } proc XPASendPrint {xpa cdata param} { InitError xpa catch {ProcessSendPrintCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPrint {xpa cdata param buf len} { XPADebug "XPARcvdPrint" $param InitError xpa catch {set i 0; ProcessPrintCmd param i} XPACatchError $xpa } proc XPASendPSPrint {xpa cdata param} { InitError xpa catch {ProcessSendPSPrintCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdPSPrint {xpa cdata param buf len} { XPADebug "XPARcvdPSPrint" $param InitError xpa catch {set i 0; ProcessPSPrintCmd param i} XPACatchError $xpa } proc XPARcvdRaise {xpa cdata param buf len} { XPADebug "XPARcvdRaise" $param InitError xpa catch {set i 0; ProcessRaiseCmd param i} XPACatchError $xpa } proc XPASendRegions {xpa cdata param} { InitError xpa catch {ProcessSendRegionsCmd xpasetbuf $xpa $param {} {}} XPACatchError $xpa } proc XPARcvdRegions {xpa cdata param buf len} { XPADebug "XPARcvdRegions" $param InitError xpa catch {set i 0; ProcessRegionsCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdRestore {xpa cdata param buf len} { XPADebug "XPARcvdRestore" $param InitError xpa catch {set i 0; ProcessRestoreCmd param i} XPACatchError $xpa } proc XPASendRGB {xpa cdata param} { InitError xpa catch {ProcessSendRGBCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdRGB {xpa cdata param buf len} { XPADebug "XPARcvdRGB" $param InitError xpa catch {set i 0; ProcessRGBCmd param i} XPACatchError $xpa } proc XPASendRGBArray {xpa cdata param} { InitError xpa catch {ProcessSendRGBArrayCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdRGBArray {xpa cdata param buf len} { XPADebug "XPARcvdRGBArray" $param InitError xpa catch {set i 0; ProcessRGBArrayCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendRGBCube {xpa cdata param} { InitError xpa catch {ProcessSendRGBCubeCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdRGBCube {xpa cdata param buf len} { XPADebug "XPARcvdRGBCube" $param InitError xpa catch {set i 0; ProcessRGBCubeCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendRGBImage {xpa cdata param} { InitError xpa catch {ProcessSendRGBImageCmd {} {} $param [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdRGBImage {xpa cdata param buf len} { XPADebug "XPARcvdRGBImage" $param InitError xpa catch {set i 0; ProcessRGBImageCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendRotate {xpa cdata param} { InitError xpa catch {ProcessSendRotateCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdRotate {xpa cdata param buf len} { XPADebug "XPARcvdRotate" $param InitError xpa catch {set i 0; ProcessRotateCmd param i} XPACatchError $xpa } proc XPARcvdSAMP {xpa cdata param buf len} { XPADebug "XPARcvdSamp" $param InitError xpa catch {set i 0; ProcessSAMPCmd param i} XPACatchError $xpa } proc XPARcvdSave {xpa cdata param buf len} { XPADebug "XPARcvdSave" $param InitError xpa catch {set i 0; ProcessSaveCmd param i} XPACatchError $xpa } proc XPARcvdSaveImage {xpa cdata param buf len} { XPADebug "XPARcvdSaveImage" $param InitError xpa catch {set i 0; ProcessSaveImageCmd param i} XPACatchError $xpa } proc XPASendScale {xpa cdata param} { InitError xpa catch {ProcessSendScaleCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdScale {xpa cdata param buf len} { XPADebug "XPARcvdScale" $param InitError xpa catch {set i 0; ProcessScaleCmd param i} XPACatchError $xpa } # backward compatibility proc XPARcvdSFits {xpa cdata param buf len} { XPADebug "XPARcvdSFits" $param InitError xpa catch {set i 0; ProcessSFitsCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendSingle {xpa cdata param} { InitError xpa catch {ProcessSendSingleCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdSingle {xpa cdata param buf len} { XPADebug "XPARcvdSingle" $param InitError xpa catch {set i 0; ProcessSingleCmd param i} XPACatchError $xpa } proc XPASendShm {xpa cdata param} { InitError xpa catch {ProcessSendShmCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdShm {xpa cdata param buf len} { XPADebug "XPARcvdShm" $param InitError xpa catch {set i 0; ProcessShmCmd param i 0} XPACatchError $xpa } proc XPASendSkyView {xpa cdata param} { InitError xpa catch {ProcessSendSkyViewCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdSkyView {xpa cdata param buf len} { XPADebug "XPARcvdSkyView" $param InitError xpa catch {set i 0; ProcessSkyViewCmd param i} XPACatchError $xpa } proc XPARcvdSleep {xpa cdata param buf len} { XPADebug "XPARcvdSleep" $param InitError xpa catch {set i 0; ProcessSleepCmd param i} XPACatchError $xpa } # backward compatibility proc XPARcvdSMosaic {xpa cdata param buf len} { XPADebug "XPARcvdSMosaic" $param InitError xpa catch {set i 0; ProcessSMosaicCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdSMosaicWCS {xpa cdata param buf len} { XPADebug "XPARcvdSMosaicWCS" $param InitError xpa catch {set i 0; ProcessSMosaicWCSCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } # backward compatibility proc XPARcvdSMosaicIRAF {xpa cdata param buf len} { XPADebug "XPARcvdSMosaicIRAF" $param InitError xpa catch {set i 0; ProcessSMosaicIRAFCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendSmooth {xpa cdata param} { InitError xpa catch {ProcessSendSmoothCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdSmooth {xpa cdata param buf len} { XPADebug "XPARcvdSmooth" $param InitError xpa catch {set i 0; ProcessSmoothCmd param i} XPACatchError $xpa } proc XPARcvdSource {xpa cdata param buf len} { XPADebug "XPARcvdSource" $param InitError xpa catch {set i 0; ProcessSourceCmd param i} XPACatchError $xpa } # backward compatibility proc XPARcvdSRGBCube {xpa cdata param buf len} { XPADebug "XPARcvdSRGBCube" $param InitError xpa catch {set i 0; ProcessSRGBCubeCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPARcvdTcl {xpa cdata param buf len} { XPADebug "XPARcvdTcl" $param InitError xpa catch {set i 0; ProcessTclCmd param i $buf {}} XPACatchError $xpa } proc XPASendTheme {xpa cdata param} { InitError xpa catch {ProcessSendThemeCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdTheme {xpa cdata param buf len} { XPADebug "XPARcvdTheme" $param InitError xpa catch {set i 0; ProcessThemeCmd param i} XPACatchError $xpa } proc XPASendThreads {xpa cdata param} { InitError xpa catch {ProcessSendThreadsCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdThreads {xpa cdata param buf len} { XPADebug "XPARcvdThreads" $param InitError xpa catch {set i 0; ProcessThreadsCmd param i} XPACatchError $xpa } proc XPASendTIFF {xpa cdata param} { InitError xpa catch { global ds9 switch $ds9(wm) { x11 - aqua {ProcessSendTIFFCmd {} {} $param [xparec $xpa datachan] {}} win32 {ProcessSendTIFFCmd {} {} $param dummy {}} } } XPACatchError $xpa } proc XPARcvdTIFF {xpa cdata param buf len} { XPADebug "XPARcvdTIFF" $param InitError xpa catch { set i 0 global ds9 switch $ds9(wm) { x11 - aqua {ProcessTIFFCmd param i [xparec $xpa datachan] {}} win32 {ProcessTIFFCmd param i dummy {}} } } XPACatchError $xpa } proc XPASendTile {xpa cdata param} { InitError xpa catch {ProcessSendTileCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdTile {xpa cdata param buf len} { XPADebug "XPARcvdTile" $param InitError xpa catch {set i 0; ProcessTileCmd param i} XPACatchError $xpa } proc XPARcvdUpdate {xpa cdata param buf len} { XPADebug "XPARcvdUpdate" $param InitError xpa catch {set i 0; ProcessUpdateCmd param i} XPACatchError $xpa } proc XPARcvdURLFits {xpa cdata param buf len} { XPADebug "XPARcvdURLFits" $param InitError xpa catch {set i 0; ProcessURLFitsCmd param i} XPACatchError $xpa } proc XPASendVersion {xpa cdata param} { InitError xpa catch {ProcessSendVersionCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPASendView {xpa cdata param} { InitError xpa catch {ProcessSendViewCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdView {xpa cdata param buf len} { XPADebug "XPARcvdView" $param InitError xpa catch {set i 0; ProcessViewCmd param i} XPACatchError $xpa } proc XPASendVO {xpa cdata param} { InitError xpa catch {ProcessSendVOCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdVO {xpa cdata param buf len} { XPADebug "XPARcvdVO" $param InitError xpa catch {set i 0; ProcessVOCmd param i} # someone is setting the error state InitError xpa } proc XPASendWCS {xpa cdata param} { InitError xpa catch {ProcessSendWCSCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdWCS {xpa cdata param buf len} { XPADebug "XPARcvdWCS" $param InitError xpa catch {set i 0; ProcessWCSCmd param i [xparec $xpa datafd] {}} XPACatchError $xpa } proc XPASendWeb {xpa cdata param} { InitError xpa catch {ProcessSendWebCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdWeb {xpa cdata param buf len} { XPADebug "XPARcvdWeb" $param InitError xpa catch {set i 0; ProcessWebCmd param i} # someone is setting an error state InitError xpa } proc XPASendWidth {xpa cdata param} { InitError xpa catch {ProcessSendWidthCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdWidth {xpa cdata param buf len} { XPADebug "XPARcvdWidth" $param InitError xpa catch {set i 0; ProcessWidthCmd param i} XPACatchError $xpa } proc XPASendZoom {xpa cdata param} { InitError xpa catch {ProcessSendZoomCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdZoom {xpa cdata param buf len} { XPADebug "XPARcvdZoom" $param InitError xpa catch {set i 0; ProcessZoomCmd param i} XPACatchError $xpa } proc XPASendZScale {xpa cdata param} { InitError xpa catch {ProcessSendZScaleCmd xpasetbuf $xpa $param} XPACatchError $xpa } proc XPARcvdZScale {xpa cdata param buf len} { XPADebug "XPARcvdZScale" $param InitError xpa catch {set i 0; ProcessZScaleCmd param i} XPACatchError $xpa } proc XPAConnect {} { global xpa if [info exists xpa] { catch {xpafree $xpa} unset xpa } InitXPA UpdateFileMenu } proc XPADisconnect {} { global xpa if [info exists xpa] { if [catch {xpafree $xpa} result] { Error "$result" } unset xpa } else { Error "[msgcat::mc {XPA not initialized}]" } UpdateFileMenu } proc XPAInfo {} { global xpa if [info exists xpa] { set r {} append r "[format "XPA_VERSION:\t%s" [xparec $xpa version]]\n" append r "[format "XPA_CLASS:\t%s" [xparec $xpa class]]\n" append r "[format "XPA_NAME:\t%s" [xparec $xpa name]]\n" append r "[format "XPA_METHOD:\t%s" [xparec $xpa method]]\n" SimpleTextDialog xpatxt "[msgcat::mc {XPA Information}]" \ 80 20 append bottom $r } else { Error "[msgcat::mc {XPA not initialized}]" } } # unwind xpa errors # requires catch {} to allow a check to take place proc XPADebug {which param} { global debug if {$debug(tcl,xpa)} { puts stderr "$which $param" } } proc XPACatchError {xpa} { global ds9 global icursor global errorInfo if {$errorInfo != {} || $ds9(msg) != {}} { if {$ds9(msg) != {}} { xpaerror $xpa $ds9(msg) } else { xpaerror $xpa [lindex [split $errorInfo "\n"] 0] } InitError xpa # reset cursor set icursor(count) 0 UnsetWatchCursor } } proc XPAMethod {} { global xpa if {[info exists xpa]} { return [xparec $xpa method] } else { return {} } } # Process Cmds proc ProcessXPACmd {varname iname} { upvar $varname var upvar $iname i global ds9 global pds9 global env switch -- [string tolower [lindex $var $i]] { unix - inet - local - localhost {set env(XPA_METHOD) [lindex $var $i]} noxpans {set env(XPA_NSREGISTER) false} tcl {incr i; set pds9(tcl) [FromYesNo [lindex $var $i]]} yes - true - on - 1 - no - false - off - 0 {set pds9(xpa) [FromYesNo [lindex $var $i]]} } } ���������������������./saods9/src/iis.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000013214�11717006414�013164� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc IISDef {} { global iis # all internal set iis(state) 0 set iis(width) 512 set iis(height) 512 set iis(x) -1 set iis(y) -1 set iis(frame) {} set iis(ififo) "/dev/imt1i" set iis(ofifo) "/dev/imt1o" set iis(port) 5137 set iis(unix) "/tmp/.IMT%d" } proc IISInit {} { global iis iis open $iis(ififo) $iis(ofifo) $iis(port) $iis(unix) } proc IISClose {} { iis close } proc IISDebug {} { global debug iis debug $debug(iis) } # Callbacks proc IISInitializeCmd {w h} { global iis # default frame size set iis(width) $w set iis(height) $h } proc IISInitFrameCmd {which} { } proc IISSetDisplayFrameCmd {which w h} { global iis IISGotoFrame $which IISLoadFrame $which } proc IISSetRefFrameCmd {which} { global iis global ds9 if {[lsearch $ds9(frames) Frame$which] == -1} { return {[NOSUCHFRAME]} } if {[Frame$which has iis]} { return {} } set filename [Frame$which get iis file name $iis(x) $iis(y)] if {![string equal [string index $filename 0] "/"] } { set filename [file join [pwd] $filename] } return "$filename 1. 0. 0. 1. 0. 0. 1. 32767. 1." } proc IISEraseFrameCmd {which} { Frame$which iis erase IISResetTimer $which } proc IISMessageCmd {message} { global current $current(frame) iis message "\"$message\"" RefreshInfoBox $current(frame) } proc IISWritePixelsCmd {which ptr x y dx dy} { Frame$which iis set $ptr $x $y $dx $dy IISResetTimer $which } proc IISReadPixelsCmd {which ptr x y dx dy} { global current if {$which > 0} { Frame$which get iis $ptr $x $y $dx $dy } else { $current(frame) get iis $ptr $x $y $dx $dy } IISResetTimer $which } proc IISWCSCmd {which a b c d e f z1 z2 zt} { # if there is a change in config, we are not told until now if {$which > 0} { IISLoadFrame $which Frame$which iis wcs $a $b $c $d $e $f $z1 $z2 $zt } } proc IISSetCursorPosCmd {x y} { global current $current(frame) iis cursor $x $y image } proc IISGetCursorPosCmd {} { global current if {[$current(frame) has iis]} { # assume frame name 'Framexxx' set num [string range $current(frame) 5 end] return "[$current(frame) get iis cursor] $num" } else { # default to first frame return "1 1 0" } } proc IISCursorModeCmd {state} { global iis global current global icursor global ds9 if {$state != $iis(state)} { if {$iis(frame) == {}} { set which $current(frame) } else { set which $iis(frame) } set iis(state) $state $which iis cursor mode $state if {$state} { bind $ds9(canvas) <Key> [list IISCursorKey %K %A %x %y] bind $ds9(canvas) <f> {} UnBindEventsFrameKey $which if {$icursor(timer,abort)} { set icursor(timer,abort) 0 set icursor(timer) 1 } else { set icursor(timer) 1 CursorTimer } } else { bind $ds9(canvas) <Key> {} bind $ds9(canvas) <f> {ToggleBindEvents} BindEventsFrameKey $which set icursor(timer,abort) 1 set icursor(timer) 0 set iis(frame) [lindex [$ds9(canvas) gettags current] 0] } } } proc IISLoadFrame {which} { global iis global ds9 if {$which > 0} { if {(![Frame$which has iis]) || \ ([Frame$which get iis width] != $iis(width)) || \ ([Frame$which get iis height] != $iis(height))} { StartLoad Frame$which iis new $iis(width) $iis(height) FinishLoad } else { # make sure any previous data is rendered Frame$which update now } } } proc IISGotoFrame {which} { global current if {$which > 0} { if {$current(frame) != "Frame$which"} { CreateGotoFrame $which base } } } proc IISResetTimer {which} { global iis if {![info exists iis(timer$which)]} { after 500 IISTimer $which } set iis(timer$which) 1 } proc IISTimer {which} { global iis if {$iis(timer$which)} { after 500 IISTimer $which set iis(timer$which) 0 } else { if {$which > 0} { Frame$which iis update } unset iis(timer$which) } } proc IISCursorKey {sym key x y} { global current global iis global ds9 set iis(x) $x set iis(y) $y set which [lindex [$ds9(canvas) gettags current] 0] if {$which != {}} { switch -- $sym { Up {$which warp 0 -1} Down {$which warp 0 1} Left {$which warp -1 0} Right {$which warp 1 0} default { if {$key!={}} { set num [string range $which end end] set coord [$which get coordinates $x $y image] if {$coord == {}} { switch -- $key { : - q {set coord "0 0"} default {return} } } $which iis cursor $x $y canvas iis retcur [lindex $coord 0] [lindex $coord 1] $key $num } } } } } # Cmds proc ProcessIISCmd {varname iname} { upvar $varname var upvar $iname i global current switch -- [string tolower [lindex $var $i]] { filename { if [string is integer [lindex $var [expr $i+2]]] { if {$current(frame) != {}} { $current(frame) iis set file name \ [lindex $var [expr $i+1]] [lindex $var [expr $i+2]] } incr i 2 } else { if {$current(frame) != {}} { $current(frame) iis set file name [lindex $var [expr $i+1]] } incr i } } } } proc ProcessSendIISCmd {proc id param} { global current switch -- [string tolower [lindex $param 0]] { filename { if {$current(frame) != {}} { $proc $id \ "[$current(frame) get iis file name [lindex $param 1]]\n" } } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catcds.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000011703�11700665566�013655� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATCDS {varname} { upvar #0 $varname var global $varname global pcat global debug if {$debug(tcl,cat)} { puts stderr "CATCDS $varname" } # go for votable or tsv if {$pcat(vot)} { set var(proc,parser) CATVOTParse } else { set var(proc,reader) CATCDSReader } # url set site [CATCDSURL $var(server)] set cgidir {viz-bin} if {$pcat(vot)} { set script {votable} } else { set script {asu-tsv} } set var(url) "http://$site/$cgidir/$script" # query switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { switch -- $var(sky) { fk4 - fk5 - icrs {set xx [h2d [Sex2H $var(x)]]} galactic - ecliptic {set xx [Sex2D $var(x)]} } set yy [Sex2D $var(y)] } } if {$yy>0} { set yy "+$yy" } switch -- $var(sky) { fk4 {set eq "B1950"} fk5 - icrs {set eq "J2000"} galactic {set eq "Gal"} ecliptic {set eq "Ecl"} } switch -- $var(rformat) { degrees {set cr "-c.rd"} arcmin {set cr "-c.rm"} arcsec {set cr "-c.rs"} } set ww $var(width) set hh $var(height) set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] set query [http::formatQuery -source $var(catalog) -c $xx$yy -c.eq $eq $cr $rr -oc.form dec] if {$pcat(vot)} { append query "&[http::formatQuery -out.form VOTable]" } else { append query "&[http::formatQuery -out.form Tab-Separated-Values]" } switch -- $var(psky) { fk4 {append query "&[http::formatQuery -out.add _RAB,_DEB]"} fk5 - icrs {append query "&[http::formatQuery -out.add _RAJ,_DEJ]"} galactic {append query "&[http::formatQuery -out.add _GLON,_GLAT]"} ecliptic {append query "&[http::formatQuery -out.add _ELON,_ELAT]"} } # options if {!$var(allrows)} { append query "&-out.max=$var(max)" } if {$var(allcols)} { append query "&-out.all" } # url?query set var(query) $query if {$pcat(vot)} { CATLoad $varname } else { CATLoadIncr $varname } } proc CATCDSReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) 1 } 1 { # process header incr ${t}(HLines) set n $T(HLines) if {[gets $sock line] == -1} { set T(state) -1 set T(HLines) [expr $T(HLines) - 1] set T(Nrows) 0 set T(Ncols) 0 return 0 } set result [string length "$line"] set T(H_$n) $line if {[regexp -- {^ *(-)+ *(\t *(-)+ *)*} $line]} { # remove units line, but save first unset T(H_$n) incr ${t}(HLines) -1 incr n -1 set units $T(H_$n) set T(H_$n) $line # clean up header column name set hh $T(H_[expr $n-1]) regsub -all {\[} $hh {} hh regsub -all {\]} $hh {} hh set T(H_[expr $n-1]) $hh # cols set T(Header) [split $T(H_[expr $n-1]) "\t"] set T(Unit) [split $units "\t"] set T(Dashes) [split $T(H_$n) "\t"] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 2 } } 2 { # process table if {[gets $sock line] == -1} { set T(state) 0 } else { set result [string length "$line"] set line [string trim $line] if {$line != {}} { # check for beginning of another table if {[string range $line 0 0] == "#"} { set T(state) 3 return $result } # check for garbage at start of line if {![string is double [lindex $line 0]]} { set T(state) 3 return $result } # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line "\t"] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } } } 3 { # finished, eat everything else if {[gets $sock line] == -1} { set T(state) 0 } } } return $result } proc CATCDSURL {server} { switch -- $server { cds {return {vizier.u-strasbg.fr}} sao {return {vizier.cfa.harvard.edu}} cadc {return {vizier.hia.nrc.ca}} adac {return {vizier.nao.ac.jp}} iucaa {return {vizier.iucaa.ernet.in}} inasan {return {vizier.inasan.ru}} bejing {return {data.bao.ac.cn}} cambridge {return {vizier.ast.cam.ac.uk}} ukirt {return {www.ukirt.jach.hawaii.edu}} } } proc CATCDSAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for CDS This research has made use of the VizieR catalogue access tool, CDS, Strasbourg, France. VizieR is a joint effort of CDS (Centre de Données astronomiques de Strasbourg) and ESA-ESRIN (Information Systems Division). } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } �������������������������������������������������������������./saods9/src/convert.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000011567�11757225306�014100� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 set M_PI 3.14159265358979323846 # hours to degrees proc h2d {h} { return [expr ($h + 0.0) * 15.0] } # degrees to hours proc d2h {d} { return [expr ($d + 0.0) / 15.0] } # degrees to radians -- returns 0 <= r < PI proc d2r {d} { global M_PI while {[::math::fuzzy::tge $d 360.0]} { set d [expr $d - 360.0] } return [expr ($d + 0.0) * ($M_PI / 360.0)] } # radians to degrees -- returns 0 <= d < PI proc r2d {r} { global M_PI while {[::math::fuzzy::tge $r $M_PI]} { set r [expr $r - $M_PI] } return [expr ($r + 0.0) * (360.0 / $M_PI)] } # # strtod -- convert string to double # # Supports sexagesimal values: # 12:30:45.6 12h30m45.6s 12d30m45.6s "12 30 45.6" # Supports 12.5d (degrees) 12.5r (radians) # # A hidden global _strtod returns the number of arguments in the input. # if this value is 3 or 4, then hms or dms was input. This can be used # to determine that hms was input for ra so that you can convert hours # to degrees. # # set _strtod 0 proc strtod {d} { global _strtod set d [string trim $d] set d [string trimleft $d 0] if { $d == {} } { set d 0 } if { [string first - $d] >= 0 } { set sign "-" regsub -all -- "-" $d {} d } elseif { [string first + $d] >= 0 } { set sign {} regsub -all -- {\+} $d {} d } else { set sign {} } regsub -all {[ \t]*[hms][ \t]*} $d ":" d set arglist [split $d ": "] set _strtod 0 foreach arg $arglist { set args($_strtod) [string trimleft $arg 0] if { $args($_strtod) == {} } { set args($_strtod) 0 } incr _strtod } switch $_strtod { 2 { error "ERROR: strtod h:m:s|d:m:s|d" } 3 { set d [expr double($args(0)) + 0.0]; set m [expr double($args(1)) + 0.0]; set s [expr double($args(2)) + 0.0]; } 4 { set d [expr double($args(0)) + 0.0]; set m [expr double($args(1)) + 0.0]; set s [expr double($args(2)) + 0.0]; } default { set c [string range $d end end] if { $c == "r" } { set d [string trimright $d r] set d [r2d $d] } elseif { $c == "d" } { set d [string trimright $d d] } set m 0 set s 0 } } set val [expr $d + ($m / 60.0) + ($s / 3600.0)] # we don't want this. it rounds off to a precision of 6, which can # cause problems with h:m:s to degree convertions # set val [format "%s%g" $sign $val] set val "$sign$val" return $val } # # _uformat -- primative unit format converter to convert a float to a string # output format can be: # # or : (output in sexagesimal) or d (output in decimal) # proc _uformat {oformat value} { if { $value < 0.0 } { set sign "-" set d [expr -$value] } else { set sign {} set d $value } switch $oformat { {#} { set m [expr ($d - (int($d))) * 60] if { $m < 0 } { set m 0.0 } set s [expr ($m - (int($m))) * 60] if { $s < 0 } { set s 0.0 } return [format "%s%d %d %.3f" \ $sign [expr int($d)] [expr int($m)] $s] } : { set m [expr ($d - (int($d))) * 60] if { $m < 0 } { set m 0.0 } set s [expr ($m - (int($m))) * 60] if { $s < 0 } { set s 0.0 } return [format "%s%d:%d:%.3f" \ $sign [expr int($d)] [expr int($m)] $s] } d { return [format "%s%f" $sign $d] } } } # # uformat -- unit format converter # # uformat input_format output_format value # # where input format can be: # h (hours) d (degrees) m (minutes) s (seconds) # and output format can be the same, with a suffix of: # # or : (output in sexagesimal) or d (output in decimal) # proc uformat {iformat oformat value} { set itype [string index $iformat 0] set otype [string index $oformat 0] set oform [string index $oformat 1] if { $oform == {} } { set oform d } set value [strtod $value] switch $itype { h { switch $otype { h {return [_uformat $oform $value]} d {return [_uformat $oform [h2d $value]]} m {return [_uformat $oform [h2d $value]*60]} s {return [_uformat $oform [h2d $value]*60*60]} } } d { switch $otype { h {return [_uformat $oform [d2h $value]]} d {return [_uformat $oform $value]} m {return [_uformat $oform [expr $value*60]]} s {return [_uformat $oform [expr $value*60*60]]} } } m { switch $otype { h {return [_uformat $oform [d2h $value/60]]} d {return [_uformat $oform [expr $value/60]]} m {return [_uformat $oform $value]} s {return [_uformat $oform [expr $value*60]]} } } s { switch $otype { h {return [_uformat $oform [h2d $value/60/60]]} d {return [_uformat $oform [expr $value/60/60]]} m {return [_uformat $oform [expr $value/60]]} s {return [_uformat $oform $value]} } } } } �����������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaic.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000001436�12122425713�013654� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProcessMosaicCmd {varname iname sock fn} { upvar $varname var upvar $iname i set vvar $var set ii $i switch -- [string tolower [lindex $var $i]] { iraf { incr ii ProcessMosaicIRAFCmd vvar ii $sock $fn } wfpc2 {} default {ProcessMosaicWCSCmd vvar ii $sock $fn} } } proc ProcessSendMosaicCmd {proc id param sock fn} { switch -- [string tolower [lindex $param 0]] { iraf {} wfpc2 {} wcs { set param [lindex $param 1 end] ProcessSendMosaicWCSCmd $proc $id $param $sock $fn } default {ProcessSendMosaicWCSCmd $proc $id $param $sock $fn} } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/rgbcube.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000005563�12130604640�014014� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadRGBCubeFile {fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb cube} set loadParam(load,type) mmapincr set loadParam(file,name) $fn # mask not supported set loadParam(load,layer) {} ConvertFitsFile ProcessLoad } proc LoadRGBCubeAlloc {path fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb cube} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path # mask not supported set loadParam(load,layer) {} ProcessLoad } proc LoadRGBCubeSocket {sock fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb cube} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock # mask not supported set loadParam(load,layer) {} return [ProcessLoad 0] } proc SaveRGBCubeFile {fn} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits rgb cube file "\{$fn\}" } proc SaveRGBCubeSocket {sock} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits rgb cube socket $sock } proc ProcessRGBCubeCmd {varname iname sock fn} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { new { incr i CreateRGBFrame } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadRGBCubeSocket $sock $param]} { InitError xpa LoadRGBCubeFile $param } } else { # comm if {$fn != {}} { LoadRGBCubeAlloc $fn $param } else { LoadRGBCubeFile $param } } FinishLoad } proc ProcessSendRGBCubeCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } if {$sock != {}} { # xpa SaveRGBCubeSocket $sock } elseif {$fn != {}} { # comm SaveRGBCubeFile $fn $proc $id {} $fn } } ���������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/ds9.tcl��������������������������������������������������������������������������������0000755�0001750�0001750�00000025054�12132042644�013104� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" proc DS9Def {} { global ds9 global pds9 set ds9(title) "$ds9(app)" set ds9(version) {7.2} set ds9(top) . set ds9(mb) .mb set ds9(visual) {} set ds9(depth) 8 set ds9(FTY_MAXAXES) 10 set ds9(helvetica) [font configure TkDefaultFont -family] set ds9(courier) [font configure TkFixedFont -family] set ds9(times) times # These look better if normal weight font configure TkCaptionFont -weight normal font configure TkHeadingFont -weight normal eval font create DefaultFont [font actual TkDefaultFont] eval font create DefaultMenuFont [font actual TkMenuFont] eval font create DefaultTextFont [font actual TkTextFont] set ds9(main) {} set ds9(image) {} set ds9(canvas) {} set ds9(panel) {} set ds9(info) {} set ds9(panner) {} set ds9(magnifier) {} set ds9(buttons) {} set ds9(graph,sp) {} set ds9(graph,horz) {} set ds9(graph,vert) {} set ds9(frames) {} set ds9(active) {} set ds9(active,num) 0 set ds9(lock) 0 set ds9(next) {} set ds9(next,num) 1 set ds9(last) {} set ds9(event,opendoc) {} set ds9(event,printdoc) {} set ds9(dialog,dir) {} set ds9(tmpdir) {} switch $ds9(wm) { x11 - win32 { set ds9(menu,start) 1 } aqua { set ds9(menu,start) 0 } } set ds9(menu,size,frame,goto) [expr $ds9(menu,start)+0] set ds9(menu,size,frame,active) [expr $ds9(menu,start)+3] set ds9(menu,size,analysis) [expr $ds9(menu,start)+31] set ds9(menu,size,wrap) 20 set ds9(display) single set ds9(bg) white set ds9(array,x) 512 set ds9(array,y) 512 set ds9(array,bitpix) -32 set ds9(array,skip) 0 set ds9(array,arch) bigendian set ds9(idletasks) 1 set ds9(row) -1 set ds9(freeze) 0 set ds9(b1) 0 set ds9(b2) 0 set ds9(b3) 0 set ds9(sb1) 0 set ds9(sb2) 0 set ds9(sb3) 0 set ds9(cb1) 0 set ds9(cb2) 0 set ds9(cb3) 0 set ds9(csb1) 0 set ds9(csb2) 0 set ds9(csb3) 0 set ds9(modifier) 0 set ds9(ext,file) ".$ds9(app).fil" set ds9(ext,alt) ".$ds9(app).file" set ds9(msg) {} set ds9(msg,level) info set ds9(msg,src) {} set ds9(msg,timeout) 1000 set ds9(prefs) 0 switch $ds9(wm) { x11 { set ds9(ctrl) "Control-" set ds9(shiftctrl) "Shift-Control-" } win32 { set ds9(ctrl) "Control-" set ds9(shiftctrl) "Shift-Control-" } aqua { set ds9(ctrl) "Command-" set ds9(shiftctrl) "Shift-Command-" } } # prefs only set pds9(font) helvetica set pds9(font,size) [PixelsToPoints [font configure TkDefaultFont -size]] set pds9(font,weight) [font configure TkDefaultFont -weight] set pds9(font,slant) [font configure TkDefaultFont -slant] set pds9(text,font) courier set pds9(text,font,size) [PixelsToPoints [font actual TkFixedFont -size]] set pds9(text,font,weight) [font actual TkFixedFont -weight] set pds9(text,font,slant) [font actual TkFixedFont -slant] set pds9(backup) 1 set pds9(automarker) 1 set pds9(tcl) 0 set pds9(xpa) 1 set pds9(samp) 1 set pds9(confirm) 1 set pds9(bg) white set pds9(nan) white switch $ds9(wm) { x11 {set pds9(dialog) motif} win32 {set pds9(dialog) native} aqua {set pds9(dialog) native} } set pds9(dialog,center) 0 set pds9(dialog,all) 0 set pds9(language) locale set pds9(language,name) [LanguageToName $pds9(language)] set pds9(language,dir) {} set pds9(theme) native set pds9(threads) 8 } # who are we? set ds9(app) [file rootname [file tail $argv0]] # if we have a problem at this point, dump simple message and exit if {[catch {tk windowingsystem} ds9(wm)]} { puts stderr "Unable to initialize window system." exit } # Styles set ds9(app,bg) [ttk::style lookup "." -background] switch $ds9(wm) { x11 { # change just default style ttk::style theme settings default \ [list ; ttk::style configure TLabel -borderwidth 2 -padding 1; ttk::style configure TEntry -fieldbackground $ds9(app,bg) -padding 1; ] } win32 {} aqua {} } # set to absolute path so that if -cd command is used, # so we can still find our files set ds9(root) "[pwd]/zvfsmntpt" # tcl modules if {![namespace exists msgcat]} { source $ds9(root)/tcl8/8.5/msgcat-1.4.3.tm } if {![namespace exists http]} { source $ds9(root)/tcl8/8.4/http-2.7.5.tm } source $ds9(root)/tk8.5/tearoff.tcl source $ds9(root)/tk8.5/comdlg.tcl source $ds9(root)/tk8.5/focus.tcl source $ds9(root)/tk8.5/msgbox.tcl source $ds9(root)/tcllib1.14/base64/base64.tcl source $ds9(root)/tcllib1.14/log/log.tcl source $ds9(root)/tcllib1.14/ftp/ftp.tcl source $ds9(root)/tcllib1.14/textutil/repeat.tcl source $ds9(root)/tcllib1.14/textutil/tabify.tcl source $ds9(root)/tcllib1.14/math/fuzzy.tcl source $ds9(root)/tkcon2.5/tkcon.tcl source $ds9(root)/xmlrpc0.3/xmlrpc.tcl source $ds9(root)/blt3.0/graph.tcl source $ds9(root)/src/source.tcl # fix ::tk and msgcat rename ::tk::msgcat::mc {} rename ::tk::msgcat::mcmax {} namespace import ::msgcat::mc namespace import ::msgcat::mcmax ::msgcat::mcload [file join $::tk_library msgs] # fix ::tk::dialog::file set ::tk::dialog::file::showHiddenVar 0 set ::tk::dialog::file::showHiddenBtn 1 # Define Variables DS9Def 2MASSDef 3DDef AnalysisDef BinDef BlinkDef ButtonsDef CanvasDef CATDef CATSymDef CATCDSSrchDef CentroidDef ColorbarDef ContourDef CoordDef CrosshairDef CubeDef CurrentDef CursorDef DebugDef ESODef ExamineDef ExportDef FIRSTDef GraphDef GridDef GroupDef HelpDef HTTPDef HVDef IISDef ImexamDef MagnifierDef MarkerDef MaskDef MinMaxDef MovieDef NRESDef NVSSDef PannerDef PanZoomDef CropDef PixelDef PlotDef PrefsDef PSDef RGBDef SAMPDef SAODef SaveDef SaveImageDef ScaleDef SkyViewDef SmoothDef STSCIDef TemplateDef TileDef ViewDef VODef WCSDef ZScaleDef # let's start set ds9(init) 1 # set up signal trap # not supported under windows switch $tcl_platform(platform) { unix {signal add SIGINT QuitDS9} windows {} } # set the appname tk appname $ds9(app) # environment vars # we don't want to see any error messages if xpa is not available if { [info exists env(XPA_VERBOSITY)] == 0 } { set env(XPA_VERBOSITY) 0 } # set filter ptype to contained (default is process) set env(FILTER_PTYPE) c # set filter error proc so it will not kill ds9 set env(GERROR) 0 # Events switch $ds9(wm) { x11 {} win32 {} aqua { event add <<Redo>> <Command-Key-Z> bind $ds9(top) <$ds9(ctrl)-`> "lower $ds9(top)" } } event add <<Open>> <${ds9(ctrl)}o> event add <<PageSetup>> <${ds9(ctrl)}P> event add <<Print>> <${ds9(ctrl)}p> event add <<SelectAll>> <${ds9(ctrl)}a> event add <<Find>> <${ds9(ctrl)}f> event add <<FindNext>> <${ds9(ctrl)}g> # Init Temporary Dir before prefs InitTempDir # Init the filter compiler InitFilterCompiler # Load any preferences here, before we do any real work LoadPrefs # adjust default canvas size based on layout switch $view(layout) { horizontal { set canvas(width) 680 set canvas(height) 450 } vertical { set canvas(width) 540 set canvas(height) 646 } } switch $ds9(wm) { x11 - win32 {} aqua { ::tk::unsupported::MacWindowStyle style $ds9(top) document "closeBox fullZoom collapseBox resizable" # we need to map the top window so we can get the proper truecolor masks update idletasks } } # We want to withdraw the window til everything is ready to go wm withdraw $ds9(top) wm title $ds9(top) "SAOImage $ds9(title)" wm iconname $ds9(top) "SAOImage $ds9(title)" wm protocol $ds9(top) WM_DELETE_WINDOW QuitDS9 $ds9(top) configure -menu $ds9(mb) # Theme PrefsTheme # we need to set certain variables before anything else # such as color, title, language ProcessCommandLineFirst # initialize language switch $pds9(language) { locale { switch $ds9(wm) { aqua { foreach ll [MacOSXGetLocale] { if {[SetLanguage $ll]} { break } } } x11 { foreach ee {LC_MESSAGES LC_ALL LANG} { if {[info exists env($ee)]} { set ll [string tolower [string range $env($ee) 0 1]] if {[SetLanguage $ll]} { break } } } } win32 {} } } default {SetLanguage $pds9(language)} } # set the visual set ds9(visual) [winfo visual .] set ds9(depth) [winfo depth .] switch $ds9(wm) { x11 { if {$ds9(depth)==15} { set ds9(depth) 16 } if {$ds9(depth)==32} { set ds9(depth) 24 } } win32 { if {$ds9(depth)==32} { set ds9(depth) 24 } } aqua { if {$ds9(depth)==15} { set ds9(depth) 16 } } } switch -- $ds9(visual)$ds9(depth) { pseudocolor8 {} truecolor8 {} truecolor16 {} truecolor24 {} default {BadVisualError} } # create our main frame set ds9(main) [ttk::frame ${ds9(top)}ds9] pack $ds9(main) -fill both -expand true # Create image canvas CreateCanvas # Create Colorbar-- Create this first, so in case of a private colormap, # gui colors will be allocated in the new colormap, not the default colormap CreateColorbar # Create other parts of the display CreateMenuBar CreateInfoPanel CreatePanner CreateMagnifier CreateButtons CreateGraphs # Make sure that the wm knows when to swap in the colormap (if needed) wm colormapwindows . "$ds9(main) $ds9(canvas)" # Initialize the display InitColorbar InitPanner InitDialogBox # Set our current state of things ChangeMode # force a update, then layout update ConfigureView # our first frame CreateFrame # do this last so we don't get an ConfigureView event InitCanvas # ok, ready to show the window wm deiconify $ds9(top) update # Init external File Formats # we want this before processing the command line InitExternalFile # Init analysis file formats InitAnalysisFile # Configure HTTP ConfigHTTP # SAMP InitSAMP # XPA InitXPA # and process any command line items # we want to see something before any fits files are loaded ProcessCommandLine # Initialize IIS # after command line options to set port/fifo/unix... catch {IISInit} # any os events received? switch $ds9(wm) { x11 {} win32 {} aqua { MacOSXOpenDocEvent 0 MacOSXPrintDocEvent 1 } } # Load any initalization tcl code SourceInitFile {.ini} # do we have the correct prefs file? CheckPrefs # any post-prefs work? PostPrefs # kludge for aqua. We need to trigger the trap to update buttons vars switch $ds9(wm) { x11 - win32 {} aqua { set current(display) $current(display) set colorbar(map) $colorbar(map) } } # start error monitor after $ds9(msg,timeout) [list ErrorTimer] # ok, we're done set ds9(init) 0 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/prefsdialog.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000022055�12132042644�014677� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PrefsDialog {{which {}}} { global ds9 global iprefs global dprefs # see if we already have a window visible if [winfo exists $iprefs(top)] { raise $iprefs(top) return } # create the window set w $iprefs(top) set mb $iprefs(mb) Toplevel $w $mb 6 [msgcat::mc {Preferences}] PrefsDialogSave $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label [msgcat::mc {Clear Preferences}] \ -command PrefsDialogClear $mb.file add separator $mb.file add command -label [msgcat::mc {Save}] -command PrefsDialogSave $mb.file add command -label [msgcat::mc {Close}] -command PrefsDialogClose EditMenu $mb iprefs # List set f [ttk::frame $w.param] ttk::scrollbar $f.scroll -command [list $f.box yview] set dprefs(list) [listbox $f.box \ -yscroll [list $f.scroll set] \ -selectmode browse \ -setgrid true \ ] grid $f.box $f.scroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 2 -weight 1 bind $dprefs(list) <<ListboxSelect>> [list PrefsDialogListUpdate] set dprefs(tab) $f set dprefs(tabs) {} PrefsDialogGeneral PrefsDialogStartup PrefsDialogMenu PrefsDialogPanner PrefsDialogMagnifier PrefsDialog3d PrefsDialogGraph PrefsDialogScale PrefsDialogColor PrefsDialogBin PrefsDialogZoom PrefsDialogRegion PrefsDialogAnnulus PrefsDialogPanda PrefsDialogAnalysis PrefsDialogPixelTable PrefsDialogContour PrefsDialogSmooth PrefsDialogCatalog PrefsDialogNRES PrefsDialogPlot PrefsDialogVO PrefsDialogPrint PrefsDialogPageSetup PrefsDialogCoord PrefsDialogExamine PrefsDialogHTTP # Buttons set f [ttk::frame $w.buttons] ttk::button $f.save -text [msgcat::mc {Save}] \ -command PrefsDialogSave ttk::button $f.close -text [msgcat::mc {Close}] \ -command PrefsDialogClose ttk::button $f.clear -text [msgcat::mc {Clear Preferences}] \ -command PrefsDialogClear pack $f.clear $f.save $f.close \ -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -fill both -expand true # http is hard coded to be last switch $which { http {$dprefs(list) selection set end} default {$dprefs(list) selection set 0} } PrefsDialogListUpdate } proc PrefsDialogListUpdate {} { global dprefs set which [$dprefs(list) curselection] if {$which == {}} { set which 0 } foreach tab $dprefs(tabs) { grid forget $tab } grid [lindex $dprefs(tabs) $which] -row 0 -column 2 -sticky new } proc PrefsDialogSave {} { global iprefs if {[winfo exists $iprefs(top)]} { destroy $iprefs(top) destroy $iprefs(mb) } SavePrefs } proc PrefsDialogClose {} { global iprefs global dprefs if {[winfo exists $iprefs(top)]} { destroy $iprefs(top) destroy $iprefs(mb) } unset dprefs } proc PrefsDialogClear {} { global iprefs global dprefs global pds9 if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message [msgcat::mc {Clear Preferences?}]] != {ok}} { return } } ClearPrefs PrefsDialogClose } # Pref Frames proc PrefsDialogGeneral {} { global dprefs global ds9 global pds9 global pmagnifier set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {General}] lappend dprefs(tabs) [ttk::frame $w.general] # General set f [ttk::labelframe $w.general.misc -text [msgcat::mc {General}]] ttk::checkbutton $f.backup \ -text [msgcat::mc {Always save files during Backup}] \ -variable pds9(backup) ttk::checkbutton $f.auto -text [msgcat::mc {Autoload FITS Regions}] \ -variable pds9(automarker) ttk::checkbutton $f.confirm \ -text [msgcat::mc {Enable Confirmation Dialogs}] \ -variable pds9(confirm) ttk::label $f.tthreads -text [msgcat::mc {Number of Threads}] ttk::entry $f.threads -textvariable pds9(threads) \ -validate focusout -validatecommand PrefsThreads -width 8 grid $f.backup -padx 2 -pady 2 -sticky w grid $f.auto -padx 2 -pady 2 -sticky w grid $f.confirm -padx 2 -pady 2 -sticky w grid $f.tthreads $f.threads -padx 2 -pady 2 -sticky w # Theme set f [ttk::labelframe $w.general.theme -text [msgcat::mc {Theme}]] ttk::menubutton $f.theme -textvariable pds9(theme) -menu $f.theme.menu set m $f.theme.menu menu $m $m add radiobutton -label [msgcat::mc {Native}] \ -variable pds9(theme) -value native -command PrefsTheme $m add separator foreach tt [ttk::style theme names] { $m add radiobutton -label $tt -variable pds9(theme) -value $tt \ -command PrefsTheme } grid $f.theme -padx 2 -pady 2 -sticky w # Language set f [ttk::labelframe $w.general.lang -text [msgcat::mc {Language}]] ttk::menubutton $f.lang -textvariable pds9(language,name) -menu $f.lang.menu set m $f.lang.menu menu $m $m add radiobutton -label [LanguageToName locale] \ -variable pds9(language,name) -command "set pds9(language) locale" $m add separator $m add radiobutton -label [LanguageToName cs] \ -variable pds9(language,name) -command "set pds9(language) cs" $m add radiobutton -label [LanguageToName da] \ -variable pds9(language,name) -command "set pds9(language) da" $m add radiobutton -label [LanguageToName de] \ -variable pds9(language,name) -command "set pds9(language) de" $m add radiobutton -label [LanguageToName en] \ -variable pds9(language,name) -command "set pds9(language) en" $m add radiobutton -label [LanguageToName es] \ -variable pds9(language,name) -command "set pds9(language) es" $m add radiobutton -label [LanguageToName fr] \ -variable pds9(language,name) -command "set pds9(language) fr" $m add radiobutton -label [LanguageToName ja] \ -variable pds9(language,name) -command "set pds9(language) ja" $m add radiobutton -label [LanguageToName pt] \ -variable pds9(language,name) -command "set pds9(language) pt" $m add radiobutton -label [LanguageToName zh] \ -variable pds9(language,name) -command "set pds9(language) zh" grid $f.lang -padx 2 -pady 2 -sticky w # GUI Font set f [ttk::labelframe $w.general.font -text [msgcat::mc {GUI Font}]] FontMenuButton $f.font pds9 font \ font,size font,weight font,slant PrefsDefaultFont ttk::button $f.reset -text [msgcat::mc {Reset}] \ -command PrefsResetDefaultFont grid $f.font $f.reset -padx 2 -pady 2 -sticky w # Text Font set f [ttk::labelframe $w.general.textfont -text [msgcat::mc {Text Font}]] FontMenuButton $f.textfont pds9 text,font \ text,font,size text,font,weight text,font,slant {} ttk::button $f.textreset -text [msgcat::mc {Reset}] \ -command PrefsResetDefaultTextFont grid $f.textfont $f.textreset -padx 2 -pady 2 -sticky w # Color set f [ttk::labelframe $w.general.color -text [msgcat::mc {Color}]] ttk::label $f.tbg -text [msgcat::mc {Background Color}] ColorMenuButton $f.bg pds9 bg PrefsBgColor ttk::label $f.tnan -text [msgcat::mc {Blank/Inf/NaN Color}] ColorMenuButton $f.nan pds9 nan PrefsNanColor grid $f.tbg $f.bg -padx 2 -pady 2 -sticky w grid $f.tnan $f.nan -padx 2 -pady 2 -sticky w # Dialog Box set f [ttk::labelframe $w.general.box -text [msgcat::mc {Dialog Box}]] ttk::radiobutton $f.motif -text {Motif} -variable pds9(dialog) \ -value motif ttk::radiobutton $f.windows -text {Windows} -variable pds9(dialog) \ -value windows grid $f.motif $f.windows -padx 2 -pady 2 -sticky w switch $ds9(wm) { x11 {} win32 - aqua { ttk::radiobutton $f.native -text [msgcat::mc {Native Dialog}] \ -variable pds9(dialog) -value native grid $f.native -row 0 -column 2 -padx 2 -pady 2 -sticky w } } ttk::checkbutton $f.center -text [msgcat::mc {Center Non-modal Dialogs}] \ -variable pds9(dialog,center) ttk::checkbutton $f.all -text [msgcat::mc {Default All Files}] \ -variable pds9(dialog,all) grid $f.center - -padx 2 -pady 2 -sticky w grid $f.all - -padx 2 -pady 2 -sticky w pack $w.general.misc $w.general.theme $w.general.lang \ $w.general.font $w.general.textfont \ $w.general.color $w.general.box \ -side top -fill both -expand true } proc PrefsDialogStartup {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Startup}] lappend dprefs(tabs) [ttk::frame $w.startup] set f [ttk::labelframe $w.startup.params -text [msgcat::mc {At Startup}]] ttk::checkbutton $f.xpa -text [msgcat::mc {Initialize XPA}] \ -variable pds9(xpa) ttk::checkbutton $f.samp -text [msgcat::mc {Connect SAMP}] \ -variable pds9(samp) grid $f.xpa -padx 2 -pady 2 -sticky w grid $f.samp -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true -anchor nw } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotdialog.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000036205�12132042644�014540� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotDialog {varname wtt title xaxis yaxis} { upvar #0 $varname var global $varname global ds9 global pap if {[PlotRaise $varname]} { return } # add it to our xpa list global iap lappend iap(windows) $varname set var(top) ".${varname}" set var(mb) ".${varname}mb" set var(stats) 0 set var(list) 0 set var(mode) zoom set var(callback) {} set var(data,total) 0 set var(data,current) 0 set var(xdata) {} set var(ydata) {} set var(xedata) {} set var(yedata) {} set var(graph,title) "$title" set var(graph,xaxis) "$xaxis" set var(graph,yaxis) "$yaxis" set var(graph,x,auto) 1 set var(graph,x,min) {} set var(graph,x,max) {} set var(graph,y,auto) 1 set var(graph,y,min) {} set var(graph,y,max) {} # can be turned off for external line plots set var(graph,format) 1 set var(graph,x,format) {} set var(graph,y,format) {} set var(graph,x,grid) $pap(graph,x,grid) set var(graph,x,log) $pap(graph,x,log) set var(graph,x,flip) $pap(graph,x,flip) set var(graph,y,grid) $pap(graph,y,grid) set var(graph,y,log) $pap(graph,y,log) set var(graph,y,flip) $pap(graph,y,flip) set var(titleFont) $pap(titleFont) set var(titleSize) $pap(titleSize) set var(titleWeight) $pap(titleWeight) set var(titleSlant) $pap(titleSlant) set var(textlabFont) $pap(textlabFont) set var(textlabSize) $pap(textlabSize) set var(textlabWeight) $pap(textlabWeight) set var(textlabSlant) $pap(textlabSlant) set var(numlabFont) $pap(numlabFont) set var(numlabSize) $pap(numlabSize) set var(numlabWeight) $pap(numlabWeight) set var(numlabSlant) $pap(numlabSlant) set var(discrete,symbol) $pap(discrete,symbol) set var(discrete,fill) $pap(discrete,fill) set var(discrete,color) $pap(discrete,color) set var(linear,width) $pap(linear,width) set var(linear,color) $pap(linear,color) set var(linear,dash) $pap(linear,dash) set var(step,width) $pap(step,width) set var(step,color) $pap(step,color) set var(step,dash) $pap(step,dash) set var(quadratic,width) $pap(quadratic,width) set var(quadratic,color) $pap(quadratic,color) set var(quadratic,dash) $pap(quadratic,dash) set var(error,width) $pap(error,width) set var(error,color) $pap(error,color) set var(bar,color) $pap(bar,color) # create window Toplevel $var(top) $var(mb) 7 $wtt [list PlotDestroy $varname] $var(mb) add cascade -label [msgcat::mc {File}] -menu $var(mb).file $var(mb) add cascade -label [msgcat::mc {Edit}] -menu $var(mb).edit $var(mb) add cascade -label [msgcat::mc {Graph}] -menu $var(mb).graph $var(mb) add cascade -label [msgcat::mc {Element}] -menu $var(mb).element $var(mb) add cascade -label [msgcat::mc {Dataset}] -menu $var(mb).dataset menu $var(mb).file $var(mb).file add command -label "[msgcat::mc {Load Data}]..." \ -command [list PlotLoadData $varname] $var(mb).file add command -label "[msgcat::mc {Save Data}]..." \ -command [list PlotSaveData $varname] $var(mb).file add command -label [msgcat::mc {Clear Data}] \ -command [list PlotClearData $varname] $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Duplicate Data}] \ -command [list PlotDupData $varname 1] $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Statistics}] \ -command "set ${varname}(stats) 1; PlotStats $varname" $var(mb).file add command -label [msgcat::mc {List Data}] \ -command "set ${varname}(list) 1; PlotList $varname" $var(mb).file add separator $var(mb).file add command -label "[msgcat::mc {Load Configuration}]..." \ -command [list PlotLoadConfig $varname] $var(mb).file add command -label "[msgcat::mc {Save Configuration}]..." \ -command [list PlotSaveConfig $varname] $var(mb).file add separator switch $ds9(wm) { x11 { $var(mb).file add command \ -label "[msgcat::mc {Page Setup}]..." \ -command PSPageSetup $var(mb).file add command -label "[msgcat::mc {Print}]..." \ -command [list PlotPSPrint $varname] } win32 - aqua { $var(mb).file add command \ -label "[msgcat::mc {Postscript Page Setup}]..." \ -command PSPageSetup $var(mb).file add command \ -label "[msgcat::mc {Postscript Print}]..." \ -command [list PlotPSPrint $varname] } } $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Close}] \ -command [list PlotDestroy $varname] menu $var(mb).edit $var(mb).edit add command -label [msgcat::mc {Cut}] \ -state disabled -accelerator "${ds9(ctrl)}X" $var(mb).edit add command -label [msgcat::mc {Copy}] \ -state disabled -accelerator "${ds9(ctrl)}C" $var(mb).edit add command -label [msgcat::mc {Paste}] \ -state disabled -accelerator "${ds9(ctrl)}V" $var(mb).edit add command -label [msgcat::mc {Clear}] \ -state disabled $var(mb).edit add separator $var(mb).edit add radiobutton -label [msgcat::mc {Pointer}] \ -variable ${varname}(mode) -value pointer \ -command [list PlotChangeMode $varname] $var(mb).edit add radiobutton -label [msgcat::mc {Zoom}] \ -variable ${varname}(mode) -value zoom \ -command [list PlotChangeMode $varname] # Graph menu $var(mb).graph $var(mb).graph add cascade -label [msgcat::mc {Axes}] \ -menu $var(mb).graph.axes $var(mb).graph add cascade -label [msgcat::mc {Font}] \ -menu $var(mb).graph.font $var(mb).graph add separator $var(mb).graph add command -label "[msgcat::mc {Range}]..." \ -command [list PlotRangeDialog $varname] $var(mb).graph add command -label "[msgcat::mc {Title}]..." \ -command [list PlotTitleDialog $varname] menu $var(mb).graph.axes $var(mb).graph.axes add checkbutton -label [msgcat::mc {X Grid}] \ -variable ${varname}(graph,x,grid) \ -command [list $var(proc,updategraph) $varname] $var(mb).graph.axes add checkbutton -label [msgcat::mc {Log}] \ -variable ${varname}(graph,x,log) \ -command [list $var(proc,updategraph) $varname] $var(mb).graph.axes add checkbutton -label [msgcat::mc {Flip}] \ -variable ${varname}(graph,x,flip) \ -command [list $var(proc,updategraph) $varname] $var(mb).graph.axes add separator $var(mb).graph.axes add checkbutton -label [msgcat::mc {Y Grid}] \ -variable ${varname}(graph,y,grid) \ -command [list $var(proc,updategraph) $varname] $var(mb).graph.axes add checkbutton -label [msgcat::mc {Log}] \ -variable ${varname}(graph,y,log) \ -command [list $var(proc,updategraph) $varname] $var(mb).graph.axes add checkbutton -label [msgcat::mc {Flip}] \ -variable ${varname}(graph,y,flip) \ -command [list $var(proc,updategraph) $varname] menu $var(mb).graph.font $var(mb).graph.font add cascade -label [msgcat::mc {Axes Number}] \ -menu $var(mb).graph.font.numlab $var(mb).graph.font add cascade -label [msgcat::mc {Axes Title}] \ -menu $var(mb).graph.font.textlab $var(mb).graph.font add cascade -label [msgcat::mc {Title}] \ -menu $var(mb).graph.font.title FontMenu $var(mb).graph.font.numlab $varname numlabFont numlabSize \ numlabWeight numlabSlant [list $var(proc,updategraph) $varname] FontMenu $var(mb).graph.font.textlab $varname textlabFont textlabSize \ textlabWeight textlabSlant [list $var(proc,updategraph) $varname] FontMenu $var(mb).graph.font.title $varname titleFont titleSize \ titleWeight titleSlant [list $var(proc,updategraph) $varname] # element menu $var(mb).element # dataset menu $var(mb).dataset } proc PlotChangeMode {varname} { upvar #0 $varname var global $varname global ds9 blt::RemoveBindTag $var(graph) zoom-$var(graph) bind $var(graph) <1> {} switch $var(mode) { pointer {bind $var(graph) <1> [list PlotButton $varname %x %y]} zoom { switch $ds9(wm) { x11 - win32 {Blt_ZoomStack $var(graph) -mode release} aqua {Blt_ZoomStack $var(graph) -mode release "ButtonPress-1" "ButtonPress-2"} } } } } proc PlotCreateLineMenu {which var1 var2 cmd} { menu $which $which add radiobutton -label 1 -variable $var1 -value 1 -command $cmd $which add radiobutton -label 2 -variable $var1 -value 2 -command $cmd $which add radiobutton -label 3 -variable $var1 -value 3 -command $cmd $which add radiobutton -label 4 -variable $var1 -value 4 -command $cmd $which add separator $which add checkbutton -label [msgcat::mc {Dash}] -variable $var2 \ -onvalue {yes} -offvalue {no} -command $cmd } proc PlotLineSymbolMenu {which var} { menu $which $which add radiobutton -label [msgcat::mc {Circle}] \ -variable $var -value circle $which add radiobutton -label [msgcat::mc {Diamond}] \ -variable $var -value diamond $which add radiobutton -label [msgcat::mc {Plus}] \ -variable $var -value plus $which add radiobutton -label [msgcat::mc {Cross}] \ -variable $var -value cross } proc PlotLineWidthMenu {which var} { menu $which $which add radiobutton -label 0 -variable $var -value 0 $which add radiobutton -label 1 -variable $var -value 1 $which add radiobutton -label 2 -variable $var -value 2 $which add radiobutton -label 3 -variable $var -value 3 } proc PlotLineDashMenu {which var} { menu $which $which add radiobutton -label [msgcat::mc {No}] -variable $var \ -value no $which add radiobutton -label [msgcat::mc {Yes}] -variable $var \ -value yes } proc PlotDataFormatDialog {xarname} { upvar $xarname xar global ed set w {.apdata} set ed(ok) 0 set ed(dim) $xar DialogCreate $w [msgcat::mc {Data Format}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.title -text [msgcat::mc {Data Format}] ttk::radiobutton $f.xy -text {X Y} -variable ed(dim) -value xy ttk::radiobutton $f.xyex -text {X Y XErr} -variable ed(dim) -value xyex ttk::radiobutton $f.xyey -text {X Y YErr} -variable ed(dim) -value xyey ttk::radiobutton $f.xyexey -text {X Y XErr YErr} -variable ed(dim) \ -value xyexey grid $f.title -padx 2 -pady 2 -sticky w grid $f.xy -padx 2 -pady 2 -sticky w grid $f.xyex -padx 2 -pady 2 -sticky w grid $f.xyey -padx 2 -pady 2 -sticky w grid $f.xyexey -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) $w.param.xy DialogDismiss $w if {$ed(ok)} { set xar $ed(dim) } set rr $ed(ok) unset ed return $rr } proc PlotRangeDialog {varname} { upvar #0 $varname var global $varname global ed set w {.aptitle} set ed(ok) 0 set ed(x,auto) $var(graph,x,auto) set ed(x,min) $var(graph,x,min) set ed(x,max) $var(graph,x,max) set ed(x,format) $var(graph,x,format) set ed(y,auto) $var(graph,y,auto) set ed(y,min) $var(graph,y,min) set ed(y,max) $var(graph,y,max) set ed(y,format) $var(graph,y,format) DialogCreate $w [msgcat::mc {Range}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.t -text [msgcat::mc {Axis}] ttk::label $f.tto -text [msgcat::mc {To}] ttk::label $f.tfrom -text [msgcat::mc {From}] ttk::label $f.tformat -text [msgcat::mc {Format}] ttk::label $f.tauto -text [msgcat::mc {Automatic}] ttk::label $f.x -text [msgcat::mc {X}] ttk::entry $f.xmin -textvariable ed(x,min) -width 12 ttk::entry $f.xmax -textvariable ed(x,max) -width 12 ttk::entry $f.xformat -textvariable ed(format,x) -width 8 ttk::checkbutton $f.xauto -variable ed(x,auto) ttk::label $f.y -text [msgcat::mc {Y}] ttk::entry $f.ymin -textvariable ed(y,min) -width 12 ttk::entry $f.ymax -textvariable ed(y,max) -width 12 ttk::entry $f.yformat -textvariable ed(format,y) -width 8 ttk::checkbutton $f.yauto -variable ed(y,auto) grid $f.t $f.tfrom $f.tto $f.tformat $f.tauto -padx 2 -pady 2 -sticky w grid $f.x $f.xmin $f.xmax $f.xformat $f.xauto -padx 2 -pady 2 -sticky w grid $f.y $f.ymin $f.ymax $f.yformat $f.yauto -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) $w.param.xmin DialogDismiss $w if {$ed(ok)} { set var(graph,x,auto) $ed(x,auto) set var(graph,x,min) $ed(x,min) set var(graph,x,max) $ed(x,max) set var(graph,x,format) $ed(x,format) set var(graph,y,auto) $ed(y,auto) set var(graph,y,min) $ed(y,min) set var(graph,y,max) $ed(y,max) set var(graph,y,format) $ed(y,format) $var(proc,updategraph) $varname } set rr $ed(ok) unset ed return $rr } proc PlotTitleDialog {varname} { upvar #0 $varname var global $varname global ed set w {.aptitle} set ed(ok) 0 set ed(title) $var(graph,title) set ed(xaxis) $var(graph,xaxis) set ed(yaxis) $var(graph,yaxis) DialogCreate $w [msgcat::mc {Title}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.label -text [msgcat::mc {Plot Title}] ttk::entry $f.title -textvariable ed(title) -width 30 ttk::label $f.xlabel -text [msgcat::mc {X Axis Title}] ttk::entry $f.xtitle -textvariable ed(xaxis) -width 30 ttk::label $f.ylabel -text [msgcat::mc {Y Axis Title}] ttk::entry $f.ytitle -textvariable ed(yaxis) -width 30 grid $f.label $f.title -padx 2 -pady 2 -sticky ew grid $f.xlabel $f.xtitle -padx 2 -pady 2 -sticky ew grid $f.ylabel $f.ytitle -padx 2 -pady 2 -sticky ew grid columnconfigure $f 1 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) $w.param.title DialogDismiss $w if {$ed(ok)} { set var(graph,title) $ed(title) set var(graph,xaxis) $ed(xaxis) set var(graph,yaxis) $ed(yaxis) $var(proc,updategraph) $varname } set rr $ed(ok) unset ed return $rr } proc PlotButton {varname x y} { upvar #0 $varname var global $varname $var(proc,button) $varname $x $y } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerbaseannulusrect.tcl��������������������������������������������������������������0000644�0001750�0001750�00000012475�12010024005�016767� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBaseAnnulusRectDialog {varname unit major minor} { upvar #0 $varname var global $varname global pmarker set unit2 [string totitle $unit] # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord set var(method) dist # base MarkerBaseAnnulusDialog $varname # menus MarkerBaseAnnulusMethodMenu $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisRadialDialog $varname # callbacks # $var(frame) marker $var(id) callback move $var(proc,editCB) $varname $var(frame) marker $var(id) callback edit $var(proc,editCB) $varname $var(frame) marker $var(id) callback end edit $var(proc,editCB) $varname $var(frame) marker $var(id) callback rotate MarkerBaseCenterRotateCB $varname set f $var(top).param # Radius ttk::label $f.majorTitle -text $major ttk::label $f.minorTitle -text $minor ttk::label $f.outerTitle -text [msgcat::mc "Outer"] ttk::entry $f.radius1 -textvariable ${varname}(radius1) -width 13 ttk::entry $f.radius2 -textvariable ${varname}(radius2) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list $var(proc,distCB) $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat ttk::label $f.innerTitle -text [msgcat::mc "Inner"] ttk::entry $f.radius3 -textvariable ${varname}(radius3) -width 13 # Annulus ttk::label $f.tannuli -text [msgcat::mc {Annuli}] ttk::entry $f.vannuli -textvariable ${varname}(annuli) -width 13 # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.vangle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid x $f.majorTitle $f.minorTitle -padx 2 -pady 2 -sticky w grid $f.outerTitle $f.radius1 $f.radius2 $f.uradius \ -padx 2 -pady 2 -sticky w grid $f.innerTitle $f.radius3 -padx 2 -pady 2 -sticky w grid $f.tannuli $f.vannuli -padx 2 -pady 2 -sticky w grid $f.tangle $f.vangle $f.uangle -padx 2 -pady 2 -sticky w # Annuli set f [ttk::labelframe $var(top).annuli -text [msgcat::mc {Annuli}] \ -padding 2] set var(annulitxt) [text $f.txt \ -height 10 \ -width 15 \ -wrap none \ -font [font actual TkDefaultFont] \ -yscrollcommand [list $f.yscroll set] \ ] ttk::scrollbar $f.yscroll -command [list $var(annulitxt) yview] \ -orient vertical grid $var(annulitxt) $f.yscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Fini grid $var(top).annuli -row 0 -column 1 -sticky news grid rowconfigure $var(top) 0 -weight 1 grid columnconfigure $var(top) 1 -weight 1 # init - do this last $var(proc,distCB) $varname MarkerBaseCenterRotateCB $varname } # actions proc MarkerBaseAnnulusRectClose {varname} { upvar #0 $varname var global $varname # $var(frame) marker $var(id) delete callback move $var(proc,editCB) $var(frame) marker $var(id) delete callback edit $var(proc,editCB) $var(frame) marker $var(id) delete callback end edit $var(proc,editCB) $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBaseCenterClose $varname } proc MarkerBaseAnnulusRectApply {varname} { upvar #0 $varname var global $varname set levels {} regsub -all "\n" "[$var(annulitxt) get 1.0 end]" " " levels # and trim any trailing spaces set levels [string trimright $levels " "] if {$levels != {}} { $var(frame) marker $var(id) $var(which) radius "\{$levels\}" \ $var(dcoord) $var(dformat) } MarkerBaseCenterRotate $varname MarkerBaseCenterApply $varname } # callbacks proc MarkerBaseAnnulusRectCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseAnnulusRectCoordCB" } MarkerAnalysisRadialSystem $varname MarkerAnalysisStatsSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } proc MarkerBaseAnnulusRectEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseAnnulusRectEditCB" } set t [$var(frame) get marker $var(id) $var(which) radius \ $var(dcoord) $var(dformat)] set last [llength $t] set var(annuli) [expr $last/2-1] set var(radius1) [lindex $t [expr $last-2]] set var(radius2) [lindex $t [expr $last-1]] set var(radius3) [lindex $t 0] $var(annulitxt) delete 1.0 end $var(annulitxt) insert end "$t" } proc MarkerBaseAnnulusRectDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseAnnulusRectDistCB" } $var(proc,editCB) $varname } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/magnifier.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000010551�11700665570�014350� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CreateMagnifier {} { global imagnifier global ds9 set ds9(magnifier) [canvas $ds9(panel).mag -width $imagnifier(size) \ -height $imagnifier(size) \ -relief groove \ -borderwidth 2 \ -highlightthickness 0 \ -insertofftime 0 \ -takefocus 0] $ds9(magnifier) create magnifier$ds9(visual) \ -width $imagnifier(size) \ -height $imagnifier(size) \ -command magnifier \ -tag magnifier \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) } proc MagnifierDef {} { global imagnifier global pmagnifier set imagnifier(size) 128 # prefs only set pmagnifier(cursor) 1 set pmagnifier(zoom) 4 set pmagnifier(region) 1 set pmagnifier(color) white } proc UpdateMagnifier {which x y} { global view if {$view(magnifier)} { $which magnifier update $x $y } } proc MagnifierFrameBackup {ch which} { global pmagnifier puts $ch "$which magnifier graphics $pmagnifier(region)" puts $ch "$which magnifier cursor $pmagnifier(cursor)" puts $ch "$which magnifier zoom $pmagnifier(zoom)" puts $ch "$which magnifier color $pmagnifier(color)" } # Prefs Cmds proc MagnifierRegion {} { global pmagnifier global ds9 foreach f $ds9(frames) { $f magnifier graphics $pmagnifier(region) } } proc MagnifierCursor {} { global pmagnifier global ds9 foreach f $ds9(frames) { $f magnifier cursor $pmagnifier(cursor) } } proc MagnifierZoom {} { global pmagnifier global ds9 foreach f $ds9(frames) { $f magnifier zoom $pmagnifier(zoom) } } proc MagnifierColor {} { global pmagnifier global ds9 foreach f $ds9(frames) { $f magnifier color $pmagnifier(color) } } # Prefs proc PrefsDialogMagnifier {} { global dprefs global pmagnifier set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Magnifier}] lappend dprefs(tabs) [ttk::frame $w.magnifier] set f [ttk::labelframe $w.magnifier.param -text [msgcat::mc {Magnifier}]] ttk::label $f.tshow -text [msgcat::mc {Show}] ttk::checkbutton $f.graphics -text [msgcat::mc {Graphics}] \ -variable pmagnifier(region) -command MagnifierRegion ttk::checkbutton $f.cursor -text [msgcat::mc {Cursor}] \ -variable pmagnifier(cursor) -command MagnifierCursor ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color pmagnifier color MagnifierColor ttk::label $f.tx -text [msgcat::mc {Magnification}] ttk::radiobutton $f.x1 -text {1x} \ -variable pmagnifier(zoom) -value 1 -command MagnifierZoom ttk::radiobutton $f.x2 -text {2x} \ -variable pmagnifier(zoom) -value 2 -command MagnifierZoom ttk::radiobutton $f.x4 -text {4x} \ -variable pmagnifier(zoom) -value 4 -command MagnifierZoom ttk::radiobutton $f.x8 -text {8x} \ -variable pmagnifier(zoom) -value 8 -command MagnifierZoom ttk::radiobutton $f.x16 -text {16x} \ -variable pmagnifier(zoom) -value 16 -command MagnifierZoom grid $f.tshow $f.graphics - $f.cursor - -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color - - -padx 2 -pady 2 -sticky w grid $f.tx $f.x1 $f.x2 $f.x4 $f.x8 $f.x16 -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } # Process Cmds proc ProcessMagnifierCmd {varname iname} { upvar $varname var upvar $iname i global pmagnifier global view switch -- [string tolower [lindex $var $i]] { color { incr i set pmagnifier(color) [lindex $var $i] MagnifierColor } zoom { incr i set pmagnifier(zoom) [lindex $var $i] MagnifierZoom } cursor { incr i set pmagnifier(cursor) [FromYesNo [lindex $var $i]] MagnifierCursor } region { incr i set pmagnifier(region) [FromYesNo [lindex $var $i]] MagnifierRegion } default { # backward compatibility set view(magnifier) 1 UpdateView incr i -1 } } } proc ProcessSendMagnifierCmd {proc id param} { global pmagnifier switch -- [string tolower [lindex $param 0]] { color {$proc $id "$pmagnifier(color)\n"} zoom {$proc $id "$pmagnifier(zoom)\n"} cursor {$proc $id [ToYesNo $pmagnifier(cursor)]} region {$proc $id [ToYesNo $pmagnifier(region)]} } } �������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/line.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000005312�12007011531�013314� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LineDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set arrows [$var(frame) get marker $var(id) line arrow] set var(p1arrow) [lindex $arrows 0] set var(p2arrow) [lindex $arrows 1] # procs set var(which) line set var(proc,apply) LineApply set var(proc,coordCB) LineCoordCB set var(proc,editCB) LineEditCB set var(proc,distCB) LineDistCB # base MarkerBaseLineDialog $varname 375 150 # raise plot? global marker set var(plot2d) $marker(plot2d) # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis # plot2d MarkerAnalysisPlot2dDialog $varname set f $var(top).param # Arrows ttk::label $f.tarrow -text [msgcat::mc {Arrow}] ttk::checkbutton $f.p1arrow -variable ${varname}(p1arrow) \ -text [msgcat::mc {Left}] -command "LineArrow $varname" ttk::checkbutton $f.p2arrow -variable ${varname}(p2arrow) \ -text [msgcat::mc {Right}] -command "LineArrow $varname" grid $f.tarrow $f.p1arrow $f.p2arrow -padx 2 -pady 2 -sticky w } # actions proc LineApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) line point $var(system) $var(sky) \ $var(x) $var(y) $var(x2) $var(y2) MarkerBaseLineApply $varname } # support proc LineArrow {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) line arrow $var(p1arrow) $var(p2arrow) } # callbacks proc LineCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "LineCoordCB" } MarkerAnalysisPlot2dSystem $varname MarkerBaseCoordCB $varname LineEditCB $varname } proc LineEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "LineEditCB" } MarkerBaseLineEditCB $varname set var(dist) [$var(frame) get marker $var(id) line length \ $var(dcoord) $var(dformat)] set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] } proc LineDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "LineDistCB" } set var(dist) [$var(frame) get marker $var(id) line length \ $var(dcoord) $var(dformat)] } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/epanda.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000001717�11732434434�013641� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc EpandaDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(which) epanda set var(proc,apply) MarkerBasePandaRectApply set var(proc,close) MarkerBasePandaRectClose set var(proc,generate) EpandaGenerate set var(proc,coordCB) MarkerBasePandaRectCoordCB set var(proc,editCB) MarkerBasePandaRectEditCB set var(proc,distCB) MarkerBasePandaRectDistCB # base panda rect dialog MarkerBasePandaRectDialog $varname } # actions proc EpandaGenerate {varname} { upvar #0 $varname var global $varname MarkerBaseAnnulusGenerateEllipse $varname MarkerBasePandaGenerateAngles $varname } �������������������������������������������������./saods9/src/catmatch.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000041141�12035363452�014166� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATMatchFrame {} { global icat global current # find all cats for frame set cats {} foreach varname $icat(cats) { upvar #0 $varname var global $varname if {$var(frame) == $current(frame)} { lappend cats $varname } } if {[llength $cats] < 2} { Warning [msgcat::mc {At least 2 different catalogs are required}] return } if {[CATMatchDialog $cats]} { if {$icat(match1) != {} && $icat(match2) != {} && $icat(match1) != $icat(match2)} { CATMatch $current(frame) $icat(match1) $icat(match2) } else { Warning [msgcat::mc {At least 2 different catalogs are required}] } } } proc CATMatchDialog {cats} { global ds9 global ed global icat set w {.catmat} set mb {.catmatmb} set ed(top) $w set ed(mb) $mb set ed(ok) 0 set ed(match1) [lindex $cats 0] set varname $ed(match1) upvar #0 $varname var global $varname set ed(match1,msg) $var(title) set ed(match2) [lindex $cats 1] set varname $ed(match2) upvar #0 $varname var global $varname set ed(match2,msg) $var(title) set ed(error) $icat(error) set ed(rformat) $icat(eformat) set ed(function) $icat(function) set ed(unique) $icat(unique) set ed(return) $icat(return) DialogCreate $w [msgcat::mc {Match}] ed(ok) $w configure -menu $mb menu $mb # file $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command {set ed(ok) 1} $mb.file add command -label [msgcat::mc {Cancel}] -command {set ed(ok) 0} # edit $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit EditMenu $mb ed # param set f [ttk::frame $w.param] ttk::label $f.tmatch -text [msgcat::mc {Match}] ttk::menubutton $f.match1 -textvariable ed(match1,msg) -menu $f.match1.menu ttk::label $f.tand -text [msgcat::mc {and}] ttk::menubutton $f.match2 -textvariable ed(match2,msg) -menu $f.match2.menu CATMatchDialogCatsMenu $f match1 $cats CATMatchDialogCatsMenu $f match2 $cats ttk::label $f.terror -text [msgcat::mc {Error}] ttk::entry $f.error -textvariable ed(error) -width 14 ARRFormat $f.eformat ed ttk::label $f.tfunction -text [msgcat::mc {Function}] ttk::menubutton $f.function -textvariable ed(function,msg) \ -menu $f.function.menu menu $f.function.menu -tearoff 0 $f.function.menu add radiobutton -variable ed(function) \ -label "1 [msgcat::mc {and}] 2" \ -value 1and2 -command [list CATMatchDialogFunctionMenu $f] $f.function.menu add radiobutton -variable ed(function) \ -label "1 [msgcat::mc {not}] 2" \ -value 1not2 -command [list CATMatchDialogFunctionMenu $f] $f.function.menu add radiobutton -variable ed(function) \ -label "2 [msgcat::mc {not}] 1" \ -value 2not1 -command [list CATMatchDialogFunctionMenu $f] ttk::checkbutton $f.unique -text [msgcat::mc {Unique}] -variable ed(unique) ttk::label $f.treturn -text [msgcat::mc {Return}] ttk::menubutton $f.return -textvariable ed(return,msg) \ -menu $f.return.menu menu $f.return.menu -tearoff 0 $f.return.menu add radiobutton -variable ed(return) \ -label "1 [msgcat::mc {and}] 2" \ -value 1and2 -command [list CATMatchDialogReturnMenu $f] $f.return.menu add radiobutton -variable ed(return) \ -label "1 [msgcat::mc {only}]" \ -value 1only -command [list CATMatchDialogReturnMenu $f] $f.return.menu add radiobutton -variable ed(return) \ -label "2 [msgcat::mc {only}]" \ -value 2only -command [list CATMatchDialogReturnMenu $f] grid $f.tmatch $f.match1 $f.tand $f.match2 -padx 2 -pady 2 -sticky ew grid $f.terror $f.error x $f.eformat -padx 2 -pady 2 -sticky w grid $f.tfunction $f.function x $f.unique -padx 2 -pady 2 -sticky ew grid $f.treturn $f.return -padx 2 -pady 2 -sticky ew # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.param -side top -fill both -expand true pack $w.buttons $w.sep -side bottom -fill x CATMatchDialogFunctionMenu $w.param CATMatchDialogReturnMenu $w.param DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok if {$ed(ok)} { set icat(match1) $ed(match1) set icat(match2) $ed(match2) set icat(error) $ed(error) set icat(eformat) $ed(rformat) set icat(function) $ed(function) set icat(unique) $ed(unique) set icat(return) $ed(return) } DialogDismiss $w destroy $mb set rr $ed(ok) unset ed return $rr } proc CATMatchDialogFunctionMenu {f} { global ed switch $ed(function) { 1and2 { $f.unique configure -state normal $f.return configure -state normal set ed(function,msg) "1 [msgcat::mc {and}] 2" } 1not2 { $f.unique configure -state disabled $f.return configure -state disabled set ed(function,msg) "1 [msgcat::mc {not}] 2" } 2not1 { $f.unique configure -state disabled $f.return configure -state disabled set ed(function,msg) "2 [msgcat::mc {not}] 1" } } } proc CATMatchDialogReturnMenu {f} { global ed switch $ed(return) { 1and2 { set ed(return,msg) "1 [msgcat::mc {and}] 2" } 1only { set ed(return,msg) "1 [msgcat::mc {only}]" } 2only { set ed(return,msg) "2 [msgcat::mc {only}]" } } } proc CATMatchDialogCatsMenu {f which cats} { global ed set m $f.$which.menu menu $m -tearoff 0 foreach varname $cats { upvar #0 $varname var global $varname $m add radiobutton -variable ed($which) -label $var(title) \ -value $varname -command [list set ed($which,msg) $var(title)] } } proc CATMatch {frame varname1 varname2} { global icat global debug if {$debug(tcl,cat)} { puts stderr "CATMatch $frame $varname1 $varname2" } upvar #0 $varname1 var1 global $varname1 global $var1(tbldb) set t1 $var1(tbldb) upvar #0 $t1 T1 upvar #0 $varname2 var2 global $varname2 global $var2(tbldb) set t2 $var2(tbldb) upvar #0 $t2 T2 if {![CATValidDB $var1(tbldb)] || ![CATValidDB $var2(tbldb)]} { return } if {$T1(Nrows)==0 || $T2(Nrows)==0} { Warning [msgcat::mc {Match Catalog requires at least 1 row per catalog}] return } # cat1 set nrows1 [starbase_nrows $var1(tbldb)] set cols1 [starbase_columns $var1(tbldb)] set colx1 [starbase_colnum $var1(tbldb) $var1(colx)] set coly1 [starbase_colnum $var1(tbldb) $var1(coly)] set nrows2 [starbase_nrows $var2(tbldb)] set cols2 [starbase_columns $var2(tbldb)] set colx2 [starbase_colnum $var2(tbldb) $var2(colx)] set coly2 [starbase_colnum $var2(tbldb) $var2(coly)] global xx1 yy1 global xx2 yy2 global rr set xx1 {} set yy1 {} set xx2 {} set yy2 {} set rr {} for {set ii 1} {$ii <= $nrows1} {incr ii} { lappend xx1 [starbase_get $var1(tbldb) $ii $colx1] lappend yy1 [starbase_get $var1(tbldb) $ii $coly1] } for {set jj 1} {$jj <= $nrows2} {incr jj} { lappend xx2 [starbase_get $var2(tbldb) $jj $colx2] lappend yy2 [starbase_get $var2(tbldb) $jj $coly2] } global current $current(frame) match xx1 yy1 $var1(system) $var1(sky) \ xx2 yy2 $var2(system) $var2(sky) \ $icat(error) $var1(system) $icat(eformat) rr switch $icat(function) { 1and2 { if {$icat(unique)} { set aa [lsort -index 0 -integer -unique $rr] set rr [lsort -index 1 -integer -unique $aa] } else { set rr [lsort -index 0 -integer $rr] } } 1not2 {} 2not1 {} } if {[llength $rr] == 0} { Info [msgcat::mc {No Items Found}] return } switch $icat(function) { 1and2 { switch $icat(return) { 1and2 {CATMatchAnd1and2 $varname1 $varname2 rr} 1only {CATMatchAnd1only $varname1 $varname2 rr} 2only {CATMatchAnd2only $varname1 $varname2 rr} } } 1not2 {CATMatchNot $varname1 $varname2 rr} 2not1 {CATMatchNot $varname2 $varname1 rr} } } proc CATMatchAnd1and2 {varname1 varname2 rrname} { upvar $rrname rr upvar #0 $varname1 var1 global $varname1 global $var1(tbldb) set t1 $var1(tbldb) upvar #0 $t1 T1 upvar #0 $varname2 var2 global $varname2 global $var2(tbldb) set t2 $var2(tbldb) upvar #0 $t2 T2 set varname [CATDialog catmatch {} {} {} none] upvar #0 $varname var global $varname global $var(catdb) set db $var(catdb) upvar #0 $db T ARStatus $varname [msgcat::mc {Loading Catalog}] CATOff $varname CATSet $varname {} "$var1(catalog) and $var2(catalog)" \ "$var1(title) and $var2(title)" set var(name) {} set var(x) {} set var(y) {} set var(width) {} set var(height) {} # required set T(Header) $T1(Header) foreach ll $T2(Header) { # make cols unique lappend T(Header) "2_$ll" } set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(Header) {-}] set T(Ndshs) [expr $T1(Ndshs)+$T2(Ndshs)] set T(H_1) $T(Header) set T(H_2) $T(Dashes) set T(HLines) 2 set T(Nrows) 0 starbase_colmap T # optional if {[info exists ${t1}(DataType)]} { set T(DataType) $T1(DataType) if {[info exists ${t2}(DataType)]} { append T(DataType) " $T2(DataType)" } } if {[info exists ${t1}(Id)]} { set T(Id) $T1(Id) if {[info exists ${t2}(Id)]} { append T(Id) " $T2(Id)" } } if {[info exists ${t1}(ArraySize)]} { set T(ArraySize) $T1(ArraySize) if {[info exists ${t2}(ArraySize)]} { append T(ArraySize) " $T2(ArraySize)" } } if {[info exists ${t1}(Width)]} { set T(Width) $T1(Width) if {[info exists ${t2}(Width)]} { append T(Width) " $T2(Width)" } } if {[info exists ${t1}(Precision)]} { set T(Precision) $T1(Precision) if {[info exists ${t2}(Precision)]} { append T(Precision) " $T2(Precision)" } } if {[info exists ${t1}(Unit)]} { set T(Unit) "$T1(Unit) " if {[info exists ${t2}(Unit)]} { append T(Unit) " $T2(Unit)" } } if {[info exists ${t1}(Ref)]} { set T(Ref) $T1(Ref) if {[info exists ${t2}(Ref)]} { append T(Ref) " $T2(Ref)" } } if {[info exists ${t1}(Ucd)]} { set T(Ucd) $T1(Ucd) if {[info exists ${t2}(Ucd)]} { append T(Ucd) " $T2(Ucd)" } } if {[info exists ${t1}(Description)]} { set T(Description) $T1(Description) if {[info exists ${t2}(Description)]} { append T(Description) " $T2(Description)" } } set ll 0 foreach {r1 r2} [join $rr] { incr ll for {set ii 1} {$ii<=$T1(Ncols)} {incr ii} { set T($ll,$ii) $T1($r1,$ii) } for {set jj 1} {$jj<=$T2(Ncols)} {incr jj} { set T($ll,[expr $ii+$jj-1]) $T2($r2,$jj) } incr T(Nrows) } ARDone $varname CATLoadDone $varname } proc CATMatchAnd1only {varname1 varname2 rrname} { upvar $rrname rr upvar #0 $varname1 var1 global $varname1 global $var1(tbldb) set t1 $var1(tbldb) upvar #0 $t1 T1 upvar #0 $varname2 var2 global $varname2 global $var2(tbldb) set t2 $var2(tbldb) upvar #0 $t2 T2 set varname [CATDialog catmatch {} {} {} none] upvar #0 $varname var global $varname global $var(catdb) set db $var(catdb) upvar #0 $db T ARStatus $varname [msgcat::mc {Loading Catalog}] CATOff $varname CATSet $varname {} "$var1(catalog) and $var2(catalog)" \ "$var1(title) and $var2(title)" set var(name) {} set var(x) {} set var(y) {} set var(width) {} set var(height) {} # required set T(Header) $T1(Header) set T(Dashes) $T1(Dashes) set T(Ndshs) $T1(Ndshs) set T(HLines) $T1(HLines) for {set ii 1} {$ii<=$T1(HLines)} {incr ii} { set T(H_$ii) $T1(H_$ii) } set T(Nrows) 0 starbase_colmap T # optional if {[info exists ${t1}(DataType)]} { set T(DataType) $T1(DataType) } if {[info exists ${t1}(Id)]} { set T(Id) $T1(Id) } if {[info exists ${t1}(ArraySize)]} { set T(ArraySize) $T1(ArraySize) } if {[info exists ${t1}(Width)]} { set T(Width) $T1(Width) } if {[info exists ${t1}(Precision)]} { set T(Precision) $T1(Precision) } if {[info exists ${t1}(Unit)]} { set T(Unit) $T1(Unit) } if {[info exists ${t1}(Ref)]} { set T(Ref) $T1(Ref) } if {[info exists ${t1}(Ucd)]} { set T(Ucd) $T1(Ucd) } if {[info exists ${t1}(Description)]} { set T(Description) $T1(Description) } set ll 0 foreach {r1 r2} [join $rr] { incr ll for {set ii 1} {$ii<=$T1(Ncols)} {incr ii} { set T($ll,$ii) $T1($r1,$ii) } incr T(Nrows) } ARDone $varname CATLoadDone $varname } proc CATMatchAnd2only {varname1 varname2 rrname} { upvar $rrname rr upvar #0 $varname1 var1 global $varname1 global $var1(tbldb) set t1 $var1(tbldb) upvar #0 $t1 T1 upvar #0 $varname2 var2 global $varname2 global $var2(tbldb) set t2 $var2(tbldb) upvar #0 $t2 T2 set varname [CATDialog catmatch {} {} {} none] upvar #0 $varname var global $varname global $var(catdb) set db $var(catdb) upvar #0 $db T ARStatus $varname [msgcat::mc {Loading Catalog}] CATOff $varname CATSet $varname {} "$var1(catalog) and $var2(catalog)" \ "$var1(title) and $var2(title)" set var(name) {} set var(x) {} set var(y) {} set var(width) {} set var(height) {} # required set T(Header) $T2(Header) set T(Dashes) $T2(Dashes) set T(Ndshs) $T2(Ndshs) set T(HLines) $T2(HLines) for {set ii 1} {$ii<=$T2(HLines)} {incr ii} { set T(H_$ii) $T2(H_$ii) } set T(Nrows) 0 starbase_colmap T # optional if {[info exists ${t2}(DataType)]} { set T(DataType) $T2(DataType) } if {[info exists ${t2}(Id)]} { set T(Id) $T2(Id) } if {[info exists ${t2}(ArraySize)]} { set T(ArraySize) $T2(ArraySize) } if {[info exists ${t2}(Width)]} { set T(Width) $T2(Width) } if {[info exists ${t2}(Precision)]} { set T(Precision) $T2(Precision) } if {[info exists ${t2}(Unit)]} { set T(Unit) $T2(Unit) } if {[info exists ${t2}(Ref)]} { set T(Ref) $T2(Ref) } if {[info exists ${t2}(Ucd)]} { set T(Ucd) $T2(Ucd) } if {[info exists ${t2}(Description)]} { set T(Description) $T2(Description) } set ll 0 foreach {r1 r2} [join $rr] { incr ll for {set ii 1} {$ii<=$T2(Ncols)} {incr ii} { set T($ll,$ii) $T2($r2,$ii) } incr T(Nrows) } ARDone $varname CATLoadDone $varname } proc CATMatchNot {varname1 varname2 rrname} { upvar $rrname rr upvar #0 $varname1 var1 global $varname1 global $var1(tbldb) set t1 $var1(tbldb) upvar #0 $t1 T1 upvar #0 $varname2 var2 global $varname2 global $var2(tbldb) set t2 $var2(tbldb) upvar #0 $t2 T2 set varname [CATDialog catmatch {} {} {} none] upvar #0 $varname var global $varname global $var(catdb) set db $var(catdb) upvar #0 $db T ARStatus $varname [msgcat::mc {Loading Catalog}] CATOff $varname CATSet $varname {} "$var1(catalog) and not $var2(catalog)" \ "$var1(title) and not $var2(title)" set var(name) {} set var(x) {} set var(y) {} set var(width) {} set var(height) {} # required set T(Header) $T1(Header) set T(Dashes) $T1(Dashes) set T(Ndshs) $T1(Ndshs) set T(HLines) $T1(HLines) for {set ii 1} {$ii<=$T1(HLines)} {incr ii} { set T(H_$ii) $T1(H_$ii) } set T(Nrows) 0 starbase_colmap T # optional if {[info exists ${t1}(DataType)]} { set T(DataType) $T1(DataType) } if {[info exists ${t1}(Id)]} { set T(Id) $T1(Id) } if {[info exists ${t1}(ArraySize)]} { set T(ArraySize) $T1(ArraySize) } if {[info exists ${t1}(Width)]} { set T(Width) $T1(Width) } if {[info exists ${t1}(Precision)]} { set T(Precision) $T1(Precision) } if {[info exists ${t1}(Unit)]} { set T(Unit) $T1(Unit) } if {[info exists ${t1}(Ref)]} { set T(Ref) $T1(Ref) } if {[info exists ${t1}(Ucd)]} { set T(Ucd) $T1(Ucd) } if {[info exists ${t1}(Description)]} { set T(Description) $T1(Description) } set ss {} foreach {r1 r2} [join $rr] { lappend ss $r1 } set ss [lsort -integer -unique $ss] set ll 0 for {set jj 1} {$jj<=$T1(Nrows)} {incr jj} { if {[lsearch -integer -sorted $ss $jj] == -1} { incr ll for {set ii 1} {$ii<=$T1(Ncols)} {incr ii} { set T($ll,$ii) $T1($jj,$ii) } incr T(Nrows) } } ARDone $varname CATLoadDone $varname } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/stdfbox.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000025330�12131577017�014056� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # do this after the language has been defined and the prefs sourced proc InitDialogBox {} { global ds9 global pds9 global env switch $ds9(wm) { x11 {} win32 {set ds9(dialog,dir) [GetEnvHome]} aqua { switch -- $pds9(dialog) { native {} motif - windows { # try to determine if invoked from # command line or double click if {![info exists env(TERM)]} { set ds9(dialog,dir) [GetEnvHome] } } } } } global fitsurl set fitsurl {} global fitsfbox set fitsfbox(file) {ds9.fits} set fitsfbox(types) [list \ [list {FITS} {*.fits}] \ [list {FITS} {*.FITS}] \ [list {FITS} {*.fit}] \ [list {FITS} {*.FIT}] \ [list {FITS} {*.fts}] \ [list {FITS} {*.FTS}] \ [list {FITS} {*.ds}] \ [list {FITS} {*.DS}] \ [list {FITS} {*.fits.gz}] \ [list {FITS} {*.fits.bz2}] \ [list {FITS} {*.fits.Z}] \ [list {FITS} {*.fits.z}] \ [list {FITS} {*.fitz}] \ [list {FITS} {*.FITZ}] \ [list {FITS} {*.ftz}] \ [list {FITS} {*.FTZ}] \ [list {FITS} {*.fz}] \ [list {FITS} {*.FZ}] \ ] global savefitsfbox set savefitsfbox(file) {ds9.fits} set savefitsfbox(types) [list \ [list {FITS} {*.fits}] \ [list {FITS} {*.fit}] \ [list {FITS} {*.fts}] \ [list {FITS} {*.fits.gz}] \ [list {FITS} {*.fits.bz2}] \ [list {FITS} {*.fits.Z}] \ [list {FITS} {*.fits.z}] \ ] global epsfbox set epsfbox(file) {ds9.eps} set epsfbox(types) [list \ [list {EPS} {*.eps}] \ ] global arrayfbox set arrayfbox(file) {ds9.arr} set arrayfbox(types) [list \ [list [::msgcat::mc {Array}] {*.arr}] \ ] global rgbarrayfbox set rgbarrayfbox(file) {ds9.rgb} set rgbarrayfbox(types) [list \ [list [::msgcat::mc {RGB Array}] {*.rgb}] \ ] global nrrdfbox set nrrdfbox(file) {ds9.nrrd} set nrrdfbox(types) [list \ [list {NRRD} {*.nrrd}] \ ] global giffbox set giffbox(file) {ds9.gif} set giffbox(types) [list \ [list {GIF} {*.gif}] \ ] global jpegfbox set jpegfbox(file) {ds9.jpeg} set jpegfbox(types) [list \ [list {JPEG} {*.jpeg}] \ [list {JPEG} {*.jpg}] \ ] global tifffbox set tifffbox(file) {ds9.tiff} set tifffbox(types) [list \ [list {TIFF} {*.tiff}] \ [list {TIFF} {*.tif}] \ ] global pngfbox set pngfbox(file) {ds9.png} set pngfbox(types) [list \ [list {PNG} {*.png}] \ ] global mpegfbox set mpegfbox(file) {ds9.mpeg} set mpegfbox(types) [list \ [list {MPEG} {*.mpeg}] \ [list {MPEG} {*.mpg}] \ ] global pixelfbox set pixelfbox(file) {ds9.pix} set pixelfbox(types) [list \ [list {PIX} {*.pix}] \ ] global markerfbox set markerfbox(file) {ds9.reg} set markerfbox(types) [list \ [list {REG} {*.reg}] \ [list {FITS} {*.fits}] \ [list {XML} {*.xml}] \ ] global templatefbox set templatefbox(file) {ds9.tpl} set templatefbox(types) \ [list [list {TPL} {*.tpl}] [list [::msgcat::mc {All}] {*}] ] global colorbarfbox set colorbarfbox(file) {ds9.sao} set colorbarfbox(types) [list \ [list [::msgcat::mc {Colormap}] {*.sao}] \ [list [::msgcat::mc {Colormap}] {*.lut}] \ ] global contrastbiasfbox set contrastbiasfbox(file) {ds9.cb} set contrastbiasfbox(types) [list \ [list {CB} {*.cb}] \ ] global colortagfbox set colortagfbox(file) {ds9.tag} set colortagfbox(types) [list \ [list {Colortag} {*.tag}] \ ] global pssavfbox set pssavfbox(file) {ds9.ps} set pssavfbox(types) [list \ [list {PS} {*.ps}] \ ] global prsavfbox set prsavfbox(file) {ds9.txt} set prsavfbox(types) [list \ [list {TXT} {*.txt}] \ ] global contourfbox set contourfbox(file) {ds9.con} set contourfbox(types) [list \ [list {CON} {*.con}] \ ] global contourlevfbox set contourlevfbox(file) {ds9.lev} set contourlevfbox(types) [list \ [list {LEV} {*.lev}] \ ] global gridfbox set gridfbox(file) {ds9.grd} set gridfbox(types) [list \ [list {GRD} {*.grd}] \ ] global catfbox set catfbox(file) {ds9.cat} set catfbox(types) [list \ [list [::msgcat::mc {Catalog}] {*.cat}] \ [list [::msgcat::mc {Catalog}] {*.rdb}] \ ] global cattsvfbox set cattsvfbox(file) {ds9.tsv} set cattsvfbox(types) [list \ [list [::msgcat::mc {Catalog}] {*.tsv}] \ [list [::msgcat::mc {Catalog}] {*.csv}] \ ] global catvotfbox set catvotfbox(file) {ds9.xml} set catvotfbox(types) [list \ [list [::msgcat::mc {Catalog}] {*.xml}] \ [list [::msgcat::mc {Catalog}] {*.vot}] \ [list [::msgcat::mc {Catalog}] {*.votable}] \ ] global catfltfbox set catfltfbox(file) {ds9.flt} set catfltfbox(types) [list \ [list {FLT} {*.flt}] \ ] global catsymfbox set catsymfbox(file) {ds9.sym} set catsymfbox(types) [list \ [list {SYM} {*.sym}] \ ] global catcdssrchfbox set catcdssrchfbox(file) {ds9.cds} set catcdssrchfbox(types) [list \ [list {CDS} {*.cds}] \ ] global analysisfbox set analysisfbox(file) {ds9.ans} set analysisfbox(types) [list \ [list [::msgcat::mc {Analysis}] {*.ans}] \ [list [::msgcat::mc {Analysis}] {*.ds9}] \ ] global analysisparamfbox set analysisparamfbox(file) {} set analysisparamfbox(types) [list \ ] global apsavfbox set apsavfbox(file) {ds9.ps} set apsavfbox(types) [list \ [list {PS} {*.ps}] \ ] global apdatafbox set apdatafbox(file) {ds9.dat} set apdatafbox(types) [list \ [list {DAT} {*.dat}] \ ] global apconfigfbox set apconfigfbox(file) {ds9.plt} set apconfigfbox(types) [list \ [list {PLT} {*.plt}] \ ] global textfbox set textfbox(file) {ds9.txt} set textfbox(types) [list \ [list {TXT} {*.txt}] \ ] global tclfbox set tclfbox(file) {ds9.tcl} set tclfbox(types) [list \ [list {TCL} {*.tcl}] \ ] global hvhtmlfbox set hvhtmlfbox(file) {ds9.html} set hvhtmlfbox(types) [list \ [list {HTML} {*.html}] \ [list {HTML} {*.htm}] \ ] global wcsfbox set wcsfbox(file) {ds9.wcs} set wcsfbox(types) [list \ [list {WCS} {*.wcs}] \ ] global backupfbox set backupfbox(file) {ds9.bck} set backupfbox(types) [list \ [list {BCK} {*.bck}] \ ] } proc SetFileLast {format item} { global fitsfbox global epsfbox global arrayfbox global rgbarrayfbox global nrrdfbox global giffbox global tifffbox global jpegfbox global pngfbox global mpegfbox switch $format { fits {FileLast fitsfbox $item} eps {FileLast epsfbox $item} rgbarray {FileLast rgbarrayfbox $item} nrrd {FileLast nrrdfbox $item} gif {FileLast giffbox $item} tiff {FileLast tifffbox $item} jpeg {FileLast jpegfbox $item} png {FileLast pngfbox $item} mpeg {FileLast mpegfbox $item} } } proc ExtToFormat {fn} { switch -- [file extension $fn] { .fits - .FITS - .fit - .FIT - .fts - .FTS - .ds - .DS - .fits.gz - .fits.bz2 - .fits.Z - .fits.z - .fitz - .FITZ - .ftz - .FTZ - .fz - .FZ {return fits} .arr - .array {return array} .rgb {return rgbarray} .nrrd {return nrrd} .eps - .epsf {return eps} .gif - .giff {return gif} .jpg - .jpeg {return jpeg} .tif - .tiff {return tiff} .png {return png} .mpg - .mpeg {return mpeg} } } # used by backup proc OpenFileDialog {varname} { return [FileDialog $varname tk_getOpenFile] } proc SaveFileDialog {varname} { return [FileDialog $varname tk_getSaveFile] } proc FileDialog {varname which} { global pds9 switch -- $pds9(dialog) { motif {return [FileDialogMotif $varname $which]} windows {return [FileDialogWindows $varname $which]} native {return [FileDialogNative $varname $which]} } } proc FileDialogMotif {varname which} { upvar #0 $varname var global ds9 global pds9 switch -- $which { tk_getOpenFile {set type open} tk_getSaveFile {set type save} } if {$pds9(dialog,all)} { set types [linsert $var(types) 0 [list [::msgcat::mc {All}] {*}]] } else { set types [linsert $var(types) end [list [::msgcat::mc {All}] {*}]] } set result [::tk::MotifFDialog $type \ -filetypes $types \ -initialdir $ds9(dialog,dir) \ -initialfile $var(file) \ -parent $ds9(top)] if {$result != {}} { set var(file) [file tail $result] set ds9(dialog,dir) [file dirname $result] } return $result } proc FileDialogWindows {varname which} { upvar #0 $varname var global ds9 global pds9 switch -- $which { tk_getOpenFile {set type open} tk_getSaveFile {set type save} } if {$pds9(dialog,all)} { set types [linsert $var(types) 0 [list [::msgcat::mc {All}] {*}]] } else { set types [linsert $var(types) end [list [::msgcat::mc {All}] {*}]] } set result [::tk::dialog::file:: $type \ -filetypes $types \ -initialdir $ds9(dialog,dir) \ -initialfile $var(file) \ -parent $ds9(top)] if {$result != {}} { set var(file) [file tail $result] set ds9(dialog,dir) [file dirname $result] } return $result } proc FileDialogNative {varname which} { upvar #0 $varname var global ds9 global pds9 if {$pds9(dialog,all)} { set types [linsert $var(types) 0 [list [::msgcat::mc {All}] {*}]] } else { set types [linsert $var(types) end [list [::msgcat::mc {All}] {*}]] } if [catch {$which \ -filetypes $types \ -initialdir $ds9(dialog,dir) \ -initialfile $var(file) \ -parent $ds9(top)} result] { # must have a bad file name, just clear and try again set var(file) {} set ds9(dialog,dir) {} if [catch {$which \ -filetypes $types \ -parent $ds9(top)} result] { #ok, something is really wrong catch {$which -parent $ds9(top)} result } } if {$result != {}} { set var(file) [file tail $result] set ds9(dialog,dir) [file dirname $result] } return $result } proc FileLast {varname fn} { upvar #0 $varname var set var(file) [file tail $fn] } proc FileLastFull {varname fn} { upvar #0 $varname var global ds9 set var(file) [file tail $fn] set ds9(dialog,dir) [file dirname $fn] } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catcmd.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000034101�12033376422�013632� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Table Commands proc CATSelectCmd {varname ss rc} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSelectCmd $varname $ss $rc" } if {$var(edit)} { CATSelectEditCmd $varname $ss $rc } else { CATSelectBrowseCmd $varname $ss $rc } } proc CATSelectEditCmd {varname ss rc} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSelectEditCmd $varname $rc" } if {![$var(frame) has fits]} { return } $var(frame) marker catalog $varname unselect set last [lindex [split $ss ,] 0] set next [lindex [split $rc ,] 0] if {[string is integer -strict $last]} { CATGenerateUpdate $varname $last } if {[string is integer -strict $next]} { set mk "\{${varname}.${next}\}" CATPanTo $varname $mk $var(frame) marker catalog $mk select } } proc CATSelectBrowseCmd {varname ss rc} { upvar #0 $varname var global $varname # starts at 1 global debug if {$debug(tcl,cat)} { puts stderr "CATSelectBrowseCmd $varname" } global $var(catdb) if {![CATValidDB $var(catdb)]} { return } if {![$var(frame) has fits]} { return } $var(frame) marker catalog $varname unhighlite # init timer vars set var(blink,count) 0 set var(blink,marker) {} # now see the current selection set last [lindex [split $ss ,] 0] set row [lindex [split $rc ,] 0] # needed for plot, status, samp # starts at 0 set rowlist {} foreach sel [$var(tbl) curselection] { set rr [lindex [split $sel ,] 0] lappend rowlist $rr } set rowlist [lsort -unique $rowlist] foreach rr $rowlist { lappend ${varname}(blink,marker) "\{${varname}.${rr}\}" } # status CATStatusRows $varname $rowlist # plot if {$var(plot)} { PlotHighliteElement $var(plot,var) $rowlist } # samp SAMPSendTableRowListCmd $varname $rowlist # panto CATPanTo $varname [lindex $var(blink,marker) 0] # start timer, if needed if {!$var(blink)} { set var(blink) 1 CATSelectTimer $varname } } proc CATSelectRows {varname src rowlist} { upvar #0 $varname var global $varname # just in case? set rowlist [lsort -unique $rowlist] # rows start at 1 global debug if {$debug(tcl,cat)} { puts stderr "CATSelectRows $varname $src $rowlist" } if {![info exists ${varname}(top)]} { return } global $var(catdb) if {![CATValidDB $var(catdb)]} { return } # rowlist can be empty if {$rowlist == {}} { if [info exists ${varname}(tbl)] { $var(tbl) selection clear all } $var(frame) marker catalog $varname unhighlite return } if [info exists ${varname}(tbl)] { $var(tbl) selection clear all foreach rr $rowlist { $var(tbl) selection set $rr,1 } $var(tbl) see [lindex $rowlist 0],1 } $var(frame) marker catalog $varname unhighlite # init timer vars set var(blink,count) 0 set var(blink,marker) {} foreach rr $rowlist { lappend ${varname}(blink,marker) "\{${varname}.${rr}\}" } # status CATStatusRows $varname $rowlist # source of call switch $src { samp { if {$var(plot)} { PlotHighliteElement $var(plot,var) $rowlist } } plot { SAMPSendTableRowListCmd $varname $rowlist } } # panto CATPanTo $varname [lindex $var(blink,marker) 0] # start timer, if needed if {!$var(blink)} { set var(blink) 1 CATSelectTimer $varname } } proc CATPanTo {varname mk} { upvar #0 $varname var global $varname if {![$var(frame) has fits]} { return } # pan to first region if {$var(panto) && $mk != {}} { set tt [$var(frame) get marker catalog $mk tag] if {$tt!={}} { set cc [$var(frame) get marker catalog $tt center \ $var(psystem) $var(psky)] PanToFrame $var(frame) [lindex $cc 0] [lindex $cc 1] \ $var(psystem) $var(psky) } } } proc CATSelectTimer {varname} { upvar #0 $varname var global $varname switch -- $var(blink) { 0 { set var(blink) 0 set var(blink,count) 0 set var(blink,marker) {} } 1 { foreach mm $var(blink,marker) { if {[$var(frame) has fits]} { $var(frame) marker catalog $mm highlite } } incr ${varname}(blink,count) if {$var(blink,count) < 5} { set var(blink) 2 } else { set var(blink) 0 } after 250 [list CATSelectTimer $varname] } 2 { foreach mm $var(blink,marker) { if {[$var(frame) has fits]} { $var(frame) marker catalog $mm unhighlite } } set var(blink) 1 after 250 [list CATSelectTimer $varname] } } } # Marker Callbacks # call backs can't call other procs proc CATHighliteCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATHighliteCB $tag $id" } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] upvar #0 $varname var global $varname if {![info exists ${varname}(top)]} { return } if {!$var(blink)} { if [info exists ${varname}(tbl)] { $var(tbl) selection set $row,1 $var(tbl) see $row,1 } } } proc CATUnhighliteCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATUnhighliteCB $tag $id" } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] upvar #0 $varname var global $varname if {![info exists ${varname}(top)]} { return } if {!$var(blink)} { if [info exists ${varname}(tbl)] { $var(tbl) selection clear $row,1 } } } proc CATEditCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATEditCB $tag $id" } if {![$var(frame) has fits]} { return } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] set szcol [lindex $t 2] set sz2col [lindex $t 3] set units [lindex $t 4] set angcol [lindex $t 5] upvar #0 $varname var global $varname global $var(tbldb) if {![info exists ${varname}(top)]} { return } # shape set shape [$var(frame) get marker catalog $id type] # skyformat switch -- $units { degrees - arcmin - arcsec { set skyformat $units } default { set skyformat degrees } } # get center and format switch $shape { circle { if {$szcol>0} { set rr [$var(frame) get marker catalog $id $shape radius \ $var(psystem) $skyformat] starbase_set $var(tbldb) $row $szcol $rr } } ellipse - box { if {$szcol>0 && $sz2col>0} { set rr [$var(frame) get marker catalog $id $shape radius \ $var(psystem) $skyformat] starbase_set $var(tbldb) $row $szcol [lindex $rr 0] starbase_set $var(tbldb) $row $sz2col [lindex $rr 1] } } vector { if {$szcol>0} { set ll [$var(frame) get marker catalog $id $shape length \ $var(psystem) $skyformat] starbase_set $var(tbldb) $row $szcol $ll } if {$angcol>0} { set ang [$var(frame) get marker catalog $id angle \ $var(psystem) $p(sky)] starbase_set $var(tbldb) $row $angcol $ang } } default {} } } proc CATMoveCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATMoveCB $tag $id" } if {![$var(frame) has fits]} { return } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] upvar #0 $varname var global $varname global $var(tbldb) if {![info exists ${varname}(top)]} { return } # center set coord [$var(frame) get marker catalog $id center \ $var(psystem) $var(sky) degrees] starbase_set $var(tbldb) $row [starbase_colnum $var(tbldb) $var(colx)] \ [lindex $coord 0] starbase_set $var(tbldb) $row [starbase_colnum $var(tbldb) $var(coly)] \ [lindex $coord 1] } proc CATRotateCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATRotateCB $tag $id" } global debug if {$debug(tcl,cat)} { puts stderr "CATMoveCB $tag $id" } if {![$var(frame) has fits]} { return } set t [split $tag .] set varname [lindex $t 0] set row [lindex $t 1] set angcol [lindex $t 2] upvar #0 $varname var global $varname global $var(tbldb) if {![info exists ${varname}(top)]} { return } # shape set shape [$var(frame) get marker catalog $id type] # get center and format switch $shape { ellipse - box { if {$angcol>0} { set ang [$var(frame) get marker catalog $id angle \ $var(psystem) $var(sky)] starbase_set $var(tbldb) $row $angcol $ang } } default {} } } proc CATDeleteCB {tag id} { global debug if {$debug(tcl,cat)} { puts stderr "CATDeleteCB $tag $id" } } # Tcl Commands proc CATButton {which x y} { global imarker global debug if {$debug(tcl,cat)} { puts stderr "CATButton $which $x $y" } # if nothing is loaded, abort if {![$which has fits]} { return } # see if we are on a handle set h [$which get marker catalog handle $x $y] set id [lindex $h 0] set imarker(handle) [lindex $h 1] if {$imarker(handle)} { $which marker catalog $id edit begin $imarker(handle) set imarker(motion) beginEdit return } # else, see if we are on a segment of a polygon set h [$which get marker catalog polygon segment $x $y] set id [lindex $h 0] set segment [lindex $h 1] if {$segment} { $which marker catalog $id create polygon vertex $segment $x $y $which marker catalog $id edit begin $imarker(handle) set imarker(handle) [expr 4+$segment+1] set imarker(motion) beginEdit return } # else, see if we are on a marker set id [$which get marker catalog id $x $y] if {$id != 0} { # select if {[$which get marker catalog $id property select]} { $which marker catalog select only $x $y $which marker catalog move begin $x $y set imarker(motion) beginMove return } # highlite if {[$which get marker catalog $id property highlite]} { $which marker catalog $id highlite only $which marker catalog $id move back set imarker(motion) none return } } # see if any markers are selected if {[$which get marker catalog select number]>0} { $which marker catalog unselect all set imarker(motion) none return } # see if any markers are selected if {[$which get marker catalog highlite number]>0} { $which marker catalog unhighlite all set imarker(motion) none return } set imarker(motion) none set imarker(handle) -1 } proc CATShift {which x y} { global imarker global debug if {$debug(tcl,cat)} { puts stderr "CATShift $which $x $y" } # if nothing is loaded, abort if {![$which has fits]} { return } # see if we are on a handle set h [$which get marker catalog handle $x $y] set id [lindex $h 0] set imarker(handle) [lindex $h 1] if {$imarker(handle)} { $which marker catalog $id rotate begin set imarker(motion) beginRotate return } # else, see if we are on a marker if {[$which marker catalog select toggle $x $y]} { $which marker catalog move begin $x $y set imarker(motion) beginMove return } if {[$which marker catalog highlite toggle $x $y]} { set imarker(motion) none return } # else, start a region select $which region catalog select begin $x $y # $which region catalog highlite begin $x $y set imarker(motion) shiftregion } proc CATMotion {which x y} { global imarker global debug if {$debug(tcl,cat)} { puts stderr "CATMotion $which $x $y" } # if nothing is loaded, abort if {![$which has fits]} { return } switch -- $imarker(motion) { none {} beginMove - move { $which marker catalog move motion $x $y set imarker(motion) move } beginEdit - edit { $which marker catalog edit motion $x $y $imarker(handle) set imarker(motion) edit } beginRotate - rotate { $which marker catalog rotate motion $x $y $imarker(handle) set imarker(motion) rotate } region - shiftregion { $which region catalog select motion $x $y # $which region catalog highlite motion $x $y } } } proc CATRelease {which x y} { global imarker global samp global debug if {$debug(tcl,cat)} { puts stderr "CATRelease $which $x $y" } # if nothing is loaded, abort if {![$which has fits]} { return } switch -- $imarker(motion) { none {} beginMove - beginRotate {} beginEdit {} move {$which marker catalog move end} edit {$which marker catalog edit end} rotate {$which marker catalog rotate end} region { $which region catalog select end $which region catalog catalog highlite end } shiftregion { $which region catalog select shift end $which region catalog highlite shift end } } set imarker(motion) none set imarker(handle) -1 # plot, stats, samp set rr {} foreach mm [$which get marker catalog highlite] { lappend rr [string trim [lindex [$which get marker catalog $mm tag] 1]] } if {$rr != {}} { set rr [lsort $rr] set varname {} set rowlist {} foreach ss $rr { set tt [split $ss {.}] set varr [lindex $tt 0] set row [lindex $tt 1] if {$varname != $varr} { # dump what we have if {$varname != {}} { upvar #0 $varname var global $varname # status CATStatusRows $varname $rowlist # plot if {$var(plot)} { PlotHighliteElement $var(plot,var) $rowlist } # samp if {[info exists samp]} { if {$samp(apps,votable) != {}} { SAMPSendTableRowListCmd $varname $rowlist } } } # now a new list set varname $varr set rowlist {} } lappend rowlist $row } if {$varname != {}} { upvar #0 $varname var global $varname # status CATStatusRows $varname $rowlist #plot if {$var(plot)} { PlotHighliteElement $var(plot,var) $rowlist } # samp if {[info exists samp]} { if {$samp(apps,votable) != {}} { SAMPSendTableRowListCmd $varname $rowlist } } } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/imexam.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000004302�11704633511�013656� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ImexamDef {} { global imexam set imexam(button) 0 set imexam(key) 0 set imexam(any) 0 set imexam(frame) {} set imexam(x) {} set imexam(y) {} set imexam(event) {} set imexam(mode) {} } # Cmds proc ProcessSendImexamCmd {proc id param} { global imexam global icursor global current set imexam(frame) {} set imexam(x) {} set imexam(y) {} set imexam(event) {} set imexam(mode) $current(mode) set current(mode) imexam set imexam(button) 0 set imexam(key) 0 set imexam(any) 0 # turn on blinking cursor set icursor(timer) 1 CursorTimer switch -- [string tolower [lindex $param 0]] { key { set imexam(key) 1 set varname {imexam(key)} set param [lreplace $param 0 0] } any { set imexam(any) 1 set varname {imexam(any)} set param [lreplace $param 0 0] } default { set imexam(button) 1 set varname {imexam(button)} } } switch -- [string tolower [lindex $param 0]] { value - data { vwait $varname set w [lindex $param 1] set h [lindex $param 2] if {$w == {}} { set w 1 } if {$h == {}} { set h 1 } $proc $id "$imexam(event) [$imexam(frame) get data canvas $imexam(x) $imexam(y) $w $h]\n" } coordinate { set sys [lindex $param 1] set sky [lindex $param 2] set skyformat [lindex $param 3] switch -- $skyformat { {} {set skyformat degrees} } switch -- $sky { {} {set sky fk5} } switch -- $sys { {} {set sys physical} fk4 - fk5 - icrs - galactic - ecliptic {set sky $sys; set sys wcs} } vwait $varname $proc $id "$imexam(event) [$imexam(frame) get coordinates $imexam(x) $imexam(y) $sys $sky $skyformat]\n" } } # turn off blinking cursor set icursor(timer) 0 set current(mode) $imexam(mode) set imexam(button) 0 set imexam(key) 0 set imexam(frame) {} set imexam(x) {} set imexam(y) {} set imexam(event) {} set imexam(mode) {} } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/group.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000011367�12131573630�013543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc GroupDef {} { global igroup global dgroup set igroup(top) .grp set igroup(mb) .grpmb set dgroup(list) {} } proc GroupCreate {} { global current if {$current(frame) != {}} { set name [$current(frame) get marker tag default name] if {[EntryDialog [msgcat::mc {New Group}] [msgcat::mc {Enter Group Name}] 30 name]} { $current(frame) marker tag "\{$name\}" UpdateGroupDialog } } } proc GroupCreateSilent {} { global current if {$current(frame) != {}} { set name [$current(frame) get marker tag default name] $current(frame) marker tag "\{$name\}" UpdateGroupDialog } } proc GroupDialog {} { global ds9 global igroup global dgroup # see if we already have a window visible if [winfo exists $igroup(top)] { raise $igroup(top) return } # create the window set w $igroup(top) set mb $igroup(mb) Toplevel $w $mb 6 [msgcat::mc {Groups}] GroupDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Update Group}] \ -command GroupUpdateDialog $mb.file add separator $mb.file add command -label [msgcat::mc {New Group}] \ -command GroupCreate $mb.file add command -label [msgcat::mc {Edit Group Name}] \ -command GroupEditDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Delete Group}] \ -command GroupDeleteDialog $mb.file add command -label [msgcat::mc {Delete All Groups}] \ -command GroupDeleteAllDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command GroupDestroyDialog # List set f [ttk::frame $w.param] ttk::scrollbar $f.scroll -command [list $f.box yview] -orient vertical set dgroup(list) [listbox $f.box \ -yscroll [list $f.scroll set] \ -setgrid true \ -selectmode single \ ] grid $f.box $f.scroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 bind $dgroup(list) <<ListboxSelect>> GroupButtonDialog # Buttons set f [ttk::frame $w.buttons] ttk::button $f.update -text [msgcat::mc {Update}] \ -command GroupUpdateDialog ttk::button $f.close -text [msgcat::mc {Close}] \ -command GroupDestroyDialog pack $f.update $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -fill both -expand true UpdateGroupDialog } proc GroupButtonDialog {} { global dgroup global current if {$current(frame) != {}} { $current(frame) marker unselect all set i [$dgroup(list) curselection] if {[string length $i] != 0} { $current(frame) marker "\{[$dgroup(list) get $i]\}" select } } } proc GroupDestroyDialog {} { global igroup if {[winfo exists $igroup(top)]} { destroy $igroup(top) destroy $igroup(mb) } } proc GroupUpdateDialog {} { global dgroup global current if {$current(frame) != {}} { set ll [$dgroup(list) curselection] if {[string length $ll] != 0} { $current(frame) marker tag update "\{[$dgroup(list) get $ll]\}" } } } proc GroupEditDialog {} { global dgroup global current if {$current(frame) != {}} { set i [$dgroup(list) curselection] if {[string length $i] != 0} { set which [$dgroup(list) get $i] if {[EntryDialog [msgcat::mc {Group Name}] [msgcat::mc {Enter Group Name}] 40 which]} { $current(frame) marker tag edit "\{[$dgroup(list) get $i]\}" "\{$which\}" UpdateGroupDialog } } } } proc GroupDeleteDialog {} { global dgroup global current if {$current(frame) != {}} { set i [$dgroup(list) curselection] if {[string length $i] != 0} { set which [$dgroup(list) get $i] $current(frame) marker tag delete "\{$which\}" UpdateGroupDialog } } } proc GroupDeleteAllDialog {} { global current global pds9 if {$current(frame) != {}} { if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message \ [msgcat::mc {Delete All Groups?}]] != {ok}} { return } } $current(frame) marker tag delete all UpdateGroupDialog } } proc UpdateGroupDialog {} { global igroup global dgroup global current global debug if {$debug(tcl,update)} { puts stderr "UpdateGroupDialog" } if {[winfo exists $igroup(top)]} { # clear the list $dgroup(list) delete 0 end if {$current(frame) != {}} { set grps [lsort [$current(frame) get marker tag all]] foreach f $grps { $dgroup(list) insert end $f } } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/http.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000003403�11774401250�013356� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc HTTPDef {} { global ihttp global phttp # 1 minute set ihttp(timeout) 60000 # prefs only set phttp(proxy) 0 set phttp(proxy,host) {} set phttp(proxy,port) {} set phttp(auth) 0 set phttp(auth,user) {} set phttp(auth,passwd) {} } proc PrefsDialogHTTP {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {HTTP}] lappend dprefs(tabs) [ttk::frame $w.http] set f [ttk::labelframe $w.http.params -text [msgcat::mc {HTTP}]] ttk::label $f.tproxy -text [msgcat::mc {Use Proxy}] ttk::checkbutton $f.proxy -variable phttp(proxy) ttk::label $f.thost -text [msgcat::mc {Proxy Host}] ttk::entry $f.host -textvariable phttp(proxy,host) -width 50 ttk::label $f.tport -text [msgcat::mc {Proxy Port}] ttk::entry $f.port -textvariable phttp(proxy,port) -width 10 ttk::label $f.tauth -text [msgcat::mc {Use Authentication}] ttk::checkbutton $f.auth -variable phttp(auth) ttk::label $f.tuser -text [msgcat::mc {Username}] ttk::entry $f.user -textvariable phttp(auth,user) -width 30 ttk::label $f.tpasswd -text [msgcat::mc {Password}] ttk::entry $f.passwd -textvariable phttp(auth,passwd) -show "*" -width 10 grid $f.tproxy $f.proxy -padx 2 -pady 2 -sticky w grid $f.thost $f.host -padx 2 -pady 2 -sticky w grid $f.tport $f.port -padx 2 -pady 2 -sticky w grid $f.tauth $f.auth -padx 2 -pady 2 -sticky w grid $f.tuser $f.user -padx 2 -pady 2 -sticky w grid $f.tpasswd $f.passwd -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plot.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000073672�12030640106�013363� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotDef {} { global pap global iap set iap(tt) {ap} set iap(windows) {} set iap(unique) 0 set pap(graph,x,grid) 1 set pap(graph,x,log) 0 set pap(graph,x,flip) 0 set pap(graph,y,grid) 1 set pap(graph,y,log) 0 set pap(graph,y,flip) 0 set pap(titleFont) helvetica set pap(titleSize) 12 set pap(titleWeight) normal set pap(titleSlant) roman set pap(textlabFont) helvetica set pap(textlabSize) 9 set pap(textlabWeight) normal set pap(textlabSlant) roman set pap(numlabFont) helvetica set pap(numlabSize) 9 set pap(numlabWeight) normal set pap(numlabSlant) roman set pap(discrete) 0 set pap(discrete,symbol) circle set pap(discrete,fill) 1 set pap(discrete,color) red set pap(linear) 1 set pap(linear,width) 1 set pap(linear,color) black set pap(linear,dash) no set pap(step) 0 set pap(step,width) 1 set pap(step,color) black set pap(step,dash) no set pap(quadratic) 0 set pap(quadratic,width) 1 set pap(quadratic,color) black set pap(quadratic,dash) no set pap(error) 1 set pap(error,width) 1 set pap(error,color) red set pap(bar) 0 set pap(bar,color) black } proc PlotAxisFormat {varname axis w nn} { upvar #0 $varname var global $varname return [format $var(graph,$axis,format) $nn] } proc PlotClearData {varname} { upvar #0 $varname var global $varname global ds9 if {$var(data,total) == 0} { return } # first set can be external set clear $var(1,manage) for {set nn 1} {$nn<=$var(data,total)} {incr nn} { if {$var($nn,manage)} { # delete elements foreach el [$var(graph) element names] { set f [split $el -] if {[lindex $f 1] == $nn} { $var(graph) element delete $el } } # delete markers foreach mk [$var(graph) marker names "m-${nn}*"] { $var(graph) marker delete $mk } # destroy vectors blt::vector destroy $var($nn,xdata) $var($nn,ydata) switch $var($nn,dim) { xy {} xyxe {blt::vector destroy $var($nn,xedata)} xyye {blt::vector destroy $var($nn,yedata)} xyxeye {blt::vector destroy $var($nn,xedata) $var($nn,yedata)} } foreach x [array names $varname] { set f [split $x ,] if {([lindex $f 0] == $nn)} { unset ${varname}($x) } } } } if {$clear} { set var(data,total) 0 set var(data,current) 0 set var(xdata) {} set var(ydata) {} set var(xedata) {} set var(yedata) {} # reset other variables set var(graph,title) {} set var(graph,xaxis) {} set var(graph,yaxis) {} set var(graph,x,auto) 1 set var(graph,x,min) {} set var(graph,x,max) {} set var(graph,y,auto) 1 set var(graph,y,min) {} set var(graph,y,max) {} $var(mb).dataset delete $ds9(menu,start) end $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } else { set var(data,total) 1 set var(data,current) 1 $var(mb).dataset delete [expr $ds9(menu,start)+1] end PlotCurrentData $varname $var(proc,updategraph) $varname } } proc PlotCurrentData {varname} { upvar #0 $varname var global $varname if {$var(data,total) > 0} { set nn $var(data,current) set var(manage) $var($nn,manage) set var(dim) $var($nn,dim) set var(xdata) $var($nn,xdata) set var(ydata) $var($nn,ydata) set var(xedata) $var($nn,xedata) set var(yedata) $var($nn,yedata) set var(discrete) $var($nn,discrete) set var(discrete,symbol) $var($nn,discrete,symbol) set var(discrete,fill) $var($nn,discrete,fill) set var(discrete,color) $var($nn,discrete,color) set var(linear) $var($nn,linear) set var(linear,width) $var($nn,linear,width) set var(linear,color) $var($nn,linear,color) set var(linear,dash) $var($nn,linear,dash) set var(step) $var($nn,step) set var(step,width) $var($nn,step,width) set var(step,color) $var($nn,step,color) set var(step,dash) $var($nn,step,dash) set var(quadratic) $var($nn,quadratic) set var(quadratic,width) $var($nn,quadratic,width) set var(quadratic,color) $var($nn,quadratic,color) set var(quadratic,dash) $var($nn,quadratic,dash) set var(error) $var($nn,error) set var(error,width) $var($nn,error,width) set var(error,color) $var($nn,error,color) set var(bar) $var($nn,bar) set var(bar,color) $var($nn,bar,color) } PlotStats $varname PlotList $varname } proc PlotDataSet {varname dim data} { upvar #0 $varname var global $varname switch -- $dim { 4 { # first data set PlotDataSetOne $varname "4.1" $data # set color set dc $var(discrete,color) set lc $var(linear,color) set sc $var(step,color) set qc $var(quadratic,color) set var(discrete,color) [PlotNextColor $var(discrete,color)] set var(linear,color) [PlotNextColor $var(linear,color)] set var(step,color) [PlotNextColor $var(step,color)] set var(quadratic,color) [PlotNextColor $var(quadratic,color)] # second data set PlotDataSetOne $varname "4.2" $data # rest colors set var(discrete,color) $dc set var(linear,color) $lc set var(step,color) $sc set var(quadratic,color) $qc } 5 { # first data set PlotDataSetOne $varname "5.1" $data # set color set dc $var(discrete,color) set lc $var(linear,color) set sc $var(step,color) set qc $var(quadratic,color) set var(discrete,color) [PlotNextColor $var(discrete,color)] set var(linear,color) [PlotNextColor $var(linear,color)] set var(step,color) [PlotNextColor $var(step,color)] set var(quadratic,color) [PlotNextColor $var(quadratic,color)] # second data set PlotDataSetOne $varname "5.2" $data # rest colors set var(discrete,color) $dc set var(linear,color) $lc set var(step,color) $sc set var(quadratic,color) $qc } default {PlotDataSetOne $varname $dim $data} } } proc PlotDataSetOne {varname dim data} { upvar #0 $varname var global $varname # look for no data if {[string length $data] == 0} { return } # total length set ll [llength $data] set ii 0 while {$ii<$ll} { # incr count incr ${varname}(data,total) set nn $var(data,total) set var(data,current) $nn # new vector names set xdata ap${varname}xx${nn} set ydata ap${varname}yy${nn} set xedata ap${varname}xe${nn} set yedata ap${varname}ye${nn} # basics xy set var(manage) 1 set var(xdata) $xdata set var(ydata) $ydata global $var(xdata) $var(ydata) blt::vector create $var(xdata) $var(ydata) # substitute all separtors regsub -all {[\n\r\t, ]+} $data { } data # remove all non-numeric data regsub -all {[^0-9.e\- ]+} $data {} data set ox [lindex $data $ii] set x {} set y {} set xe {} set ye {} switch -- $dim { 2 - xy { set var(dim) xy set var(xedata) {} set var(yedata) {} for {} {$ii<$ll} {incr ii 2} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] } } $var(xdata) set $x $var(ydata) set $y } xyex { set var(dim) xyxe set var(xedata) $xedata set var(yedata) {} global $var(xedata) blt::vector create $var(xedata) for {} {$ii<$ll} {incr ii 3} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend xe [lindex $data [expr $ii+2]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend xe [lindex $data [expr $ii+2]] } } $var(xdata) set $x $var(ydata) set $y $var(xedata) set $xe } 3 - xyey { set var(dim) xyye set var(xedata) {} set var(yedata) $yedata global $var(yedata) blt::vector create $var(yedata) for {} {$ii<$ll} {incr ii 3} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } } $var(xdata) set $x $var(ydata) set $y $var(yedata) set $ye } xyexey { set var(dim) xyxeye set var(xedata) $xedata set var(yedata) $yedata global $var(xedata) $var(yedata) blt::vector create $var(xedata) $var(yedata) for {} {$ii<$ll} {incr ii 4} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend xe [lindex $data [expr $ii+2]] lappend ye [lindex $data [expr $ii+3]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend xe [lindex $data [expr $ii+2]] lappend ye [lindex $data [expr $ii+3]] } } $var(xdata) set $x $var(ydata) set $y $var(xedata) set $xe $var(yedata) set $ye } 4.1 { set var(dim) xyye set var(xedata) {} set var(yedata) $yedata global $var(yedata) blt::vector create $var(yedata) for {} {$ii<$ll} {incr ii 4} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } } $var(xdata) set $x $var(ydata) set $y $var(yedata) set $ye } 4.2 { set var(dim) xy set var(xedata) {} set var(yedata) {} for {} {$ii<$ll} {incr ii 4} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+3]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+3]] } } $var(xdata) set $x $var(ydata) set $y } 5.1 { set var(dim) xyye set var(xedata) {} set var(yedata) $yedata global $var(yedata) blt::vector create $var(yedata) for {} {$ii<$ll} {incr ii 5} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+1]] lappend ye [lindex $data [expr $ii+2]] } } $var(xdata) set $x $var(ydata) set $y $var(yedata) set $ye } 5.2 { set var(dim) xyye set var(xedata) {} set var(yedata) $yedata global $var(yedata) blt::vector create $var(yedata) for {} {$ii<$ll} {incr ii 5} { set tx [lindex $data $ii] if {$var(seq)} { if {$ox<=$tx} { set ox $tx lappend x $tx lappend y [lindex $data [expr $ii+3]] lappend ye [lindex $data [expr $ii+4]] } else { break } } else { lappend x $tx lappend y [lindex $data [expr $ii+3]] lappend ye [lindex $data [expr $ii+4]] } } $var(xdata) set $x $var(ydata) set $y $var(yedata) set $ye } } # set menu options set var($nn,manage) 1 set var($nn,dim) $var(dim) set var($nn,xdata) $var(xdata) set var($nn,ydata) $var(ydata) set var($nn,xedata) $var(xedata) set var($nn,yedata) $var(yedata) set var($nn,discrete) $var(discrete) set var($nn,discrete,symbol) $var(discrete,symbol) set var($nn,discrete,fill) $var(discrete,fill) set var($nn,discrete,color) $var(discrete,color) set var($nn,linear) $var(linear) set var($nn,linear,width) $var(linear,width) set var($nn,linear,color) $var(linear,color) set var($nn,linear,dash) $var(linear,dash) set var($nn,step) $var(step) set var($nn,step,width) $var(step,width) set var($nn,step,color) $var(step,color) set var($nn,step,dash) $var(step,dash) set var($nn,quadratic) $var(quadratic) set var($nn,quadratic,width) $var(quadratic,width) set var($nn,quadratic,color) $var(quadratic,color) set var($nn,quadratic,dash) $var(quadratic,dash) set var($nn,error) $var(error) set var($nn,error,width) $var(error,width) set var($nn,error,color) $var(error,color) set var($nn,bar) $var(bar) set var($nn,bar,color) $var(bar,color) # update data set menu $var(mb).dataset add radiobutton -label "[msgcat::mc {Dataset}] $nn" \ -variable ${varname}(data,current) -value $nn \ -command [list PlotCurrentData $varname] $var(proc,createelement) $varname $var(proc,updateelement) $varname } } proc PlotDupData {varname mm} { upvar #0 $varname var global $varname if {$var(data,total) == 0} { return } # incr count incr ${varname}(data,total) set nn $var(data,total) set pp [expr $nn-1] # new vector names set var($nn,xdata) ap${varname}xx${nn} set var($nn,ydata) ap${varname}yy${nn} set var($nn,xedata) ap${varname}xe${nn} set var($nn,yedata) ap${varname}ye${nn} global $var($mm,xdata) $var($mm,ydata) $var($mm,xedata) $var($mm,yedata) global $var($nn,xdata) $var($nn,ydata) $var($nn,xedata) $var($nn,yedata) $var($mm,xdata) dup $var($nn,xdata) $var($mm,ydata) dup $var($nn,ydata) if {$var($mm,xedata) != {}} { $var($mm,xedata) dup $var($nn,xedata) } else { set var($nn,xedata) {} } if {$var($mm,yedata) != {}} { $var($mm,yedata) dup $var($nn,yedata) } else { set var($nn,yedata) {} } # set menu options set var($nn,manage) 1 set var($nn,dim) $var($mm,dim) set var($nn,discrete) $var($mm,discrete) set var($nn,discrete,symbol) $var($mm,discrete,symbol) set var($nn,discrete,fill) $var($mm,discrete,fill) set var($nn,discrete,color) [PlotNextColor $var($pp,discrete,color)] set var($nn,linear) $var($mm,linear) set var($nn,linear,width) $var($mm,linear,width) set var($nn,linear,color) [PlotNextColor $var($pp,linear,color)] set var($nn,linear,dash) $var($mm,linear,dash) set var($nn,step) $var($mm,step) set var($nn,step,width) $var($mm,step,width) set var($nn,step,color) [PlotNextColor $var($pp,step,color)] set var($nn,step,dash) $var($mm,step,dash) set var($nn,quadratic) $var($mm,quadratic) set var($nn,quadratic,width) $var($mm,quadratic,width) set var($nn,quadratic,color) [PlotNextColor $var($pp,quadratic,color)] set var($nn,quadratic,dash) $var($mm,quadratic,dash) set var($nn,error) $var($mm,error) set var($nn,error,width) $var($mm,error,width) set var($nn,error,color) $var($mm,error,color) set var($nn,bar) $var($mm,bar) set var($nn,bar,color) [PlotNextColor $var($pp,bar,color)] # update data set menu $var(mb).dataset add radiobutton -label "[msgcat::mc {Dataset}] $nn" \ -variable ${varname}(data,current) -value $nn \ -command [list PlotCurrentData $varname] # make current set var(data,current) $nn set var(manage) $var($nn,manage) set var(dim) $var($nn,dim) set var(xdata) $var($nn,xdata) set var(ydata) $var($nn,ydata) set var(xedata) $var($nn,xedata) set var(yedata) $var($nn,yedata) set var(discrete) $var($nn,discrete) set var(discrete,symbol) $var($nn,discrete,symbol) set var(discrete,fill) $var($nn,discrete,fill) set var(discrete,color) $var($nn,discrete,color) set var(linear) $var($nn,linear) set var(linear,width) $var($nn,linear,width) set var(linear,color) $var($nn,linear,color) set var(linear,dash) $var($nn,linear,dash) set var(step) $var($nn,step) set var(step,width) $var($nn,step,width) set var(step,color) $var($nn,step,color) set var(step,dash) $var($nn,step,dash) set var(quadratic) $var($nn,quadratic) set var(quadratic,width) $var($nn,quadratic,width) set var(quadratic,color) $var($nn,quadratic,color) set var(quadratic,dash) $var($nn,quadratic,dash) set var(error) $var($nn,error) set var(error,width) $var($nn,error,width) set var(error,color) $var($nn,error,color) set var(bar) $var($nn,bar) set var(bar,color) $var($nn,bar,color) $var(proc,createelement) $varname $var(proc,updateelement) $varname $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc PlotDestroy {varname} { upvar #0 $varname var global $varname global iap # see if it still is around if {![PlotPing $varname]} { return } for {set nn 1} {$nn<=$var(data,total)} {incr nn} { if {$var($nn,manage)} { switch $var($nn,dim) { xy { blt::vector destroy $var($nn,xdata) $var($nn,ydata) } xyxe { blt::vector destroy $var($nn,xdata) $var($nn,ydata) \ $var($nn,xedata) } xyye { blt::vector destroy $var($nn,xdata) $var($nn,ydata) \ $var($nn,yedata) } xyxeye { blt::vector destroy $var($nn,xdata) $var($nn,ydata) \ $var($nn,xedata) $var($nn,yedata) } } } } # in the rare case where the user has start a zoom, then closes the dialog # we must clean up his mess global zoomInfo if [info exists zoomInfo($var(graph),corner)] { if {$zoomInfo($var(graph),corner) == {B}} { blt::SetZoomPoint $var(graph) 0 0 } } destroy $var(top) destroy $var(mb) # stats window? if {$var(stats)} { SimpleTextDestroy "${varname}stats" } # list window? if {$var(list)} { SimpleTextDestroy "${varname}list" } # delete it from the xpa list set ii [lsearch $iap(windows) $varname] if {$ii>=0} { set iap(windows) [lreplace $iap(windows) $ii $ii] } unset $varname } proc PlotExternal {varname} { upvar #0 $varname var global $varname # incr count incr ${varname}(data,total) set nn $var(data,total) set var(data,current) $nn # set menu options set var($nn,manage) $var(manage) set var($nn,dim) $var(dim) set var($nn,xdata) $var(xdata) set var($nn,ydata) $var(ydata) set var($nn,xedata) $var(xedata) set var($nn,yedata) $var(yedata) set var($nn,discrete) $var(discrete) set var($nn,discrete,symbol) $var(discrete,symbol) set var($nn,discrete,fill) $var(discrete,fill) set var($nn,discrete,color) $var(discrete,color) set var($nn,linear) $var(linear) set var($nn,linear,width) $var(linear,width) set var($nn,linear,color) $var(linear,color) set var($nn,linear,dash) $var(linear,dash) set var($nn,step) $var(step) set var($nn,step,width) $var(step,width) set var($nn,step,color) $var(step,color) set var($nn,step,dash) $var(step,dash) set var($nn,quadratic) $var(quadratic) set var($nn,quadratic,width) $var(quadratic,width) set var($nn,quadratic,color) $var(quadratic,color) set var($nn,quadratic,dash) $var(quadratic,dash) set var($nn,error) $var(error) set var($nn,error,width) $var(error,width) set var($nn,error,color) $var(error,color) set var($nn,bar) $var(bar) set var($nn,bar,color) $var(bar,color) # update data set menu $var(mb).dataset add radiobutton -label "[msgcat::mc {Dataset}] $nn" \ -variable ${varname}(data,current) -value $nn \ -command "PlotCurrentData $varname" } proc PlotList {varname} { upvar #0 $varname var global $varname if {!$var(list)} { return } set rr {} if {$var(xdata) != {}} { global $var(xdata) $var(ydata) $var(xedata) $var(yedata) set ll [$var(xdata) length] set xx [$var(xdata) range] set yy [$var(ydata) range] switch $var(dim) { xy { for {set ii 0} {$ii<$ll} {incr ii} { append rr "[lindex $xx $ii] [lindex $yy $ii]\n" } } xyxe { set xe [$var(xedata) range] for {set ii 0} {$ii<$ll} {incr ii} { append rr "[lindex $xx $ii] [lindex $yy $ii] [lindex $xe $ii]\n" } } xyye { set ye [$var(yedata) range] for {set ii 0} {$ii<$ll} {incr ii} { append rr "[lindex $xx $ii] [lindex $yy $ii] [lindex $ye $ii]\n" } } xyxeye { set xe [$var(xedata) range] set ye [$var(yedata) range] for {set ii 0} {$ii<$ll} {incr ii} { append rr "[lindex $xx $ii] [lindex $yy $ii] [lindex $xe $ii] [lindex $ye $ii]\n" } } } } SimpleTextDialog "${varname}list" [msgcat::mc {Data}] 40 20 insert top $rr PlotListDestroyCB $varname } proc PlotListDestroyCB {varname} { upvar #0 $varname var global $varname set var(list) 0 } proc PlotLoadConfig {varname} { upvar #0 $varname var global $varname PlotLoadConfigFile $varname [OpenFileDialog apconfigfbox] } proc PlotLoadConfigFile {varname filename} { upvar #0 $varname var global $varname if {$filename != {}} { source $filename array set $varname [array get analysisplot] unset analysisplot # backward compatibility if {[info exists var(grid)]} { set var(graph,x,grid) $var(grid) set var(graph,y,grid) $var(grid) unset var(grid) } if {[info exists var(format)]} { set var(graph,format) $var(format) set var(graph,x,format) $var(format,x) set var(graph,y,format) $var(format,y) unset var(format) unset var(format,x) unset var(format,y) } if {[info exists var(grid,log)]} { switch $var(grid,log) { linearlinear { set var(graph,x,log) 0 set var(graph,y,log) 0 } linearlog { set var(graph,x,log) 0 set var(graph,y,log) 1 } loglinear { set var(graph,x,log) 1 set var(graph,y,log) 0 } loglog { set var(graph,x,log) 1 set var(graph,y,log) 1 } } unset var(grid,log) } $var(proc,updategraph) $varname } } proc PlotLoadData {varname} { upvar #0 $varname var global $varname set filename [OpenFileDialog apdatafbox] if {$filename != {}} { set dim xy if {[PlotDataFormatDialog dim]} { PlotLoadDataFile $varname $filename $dim } } } proc PlotLoadDataFile {varname filename dim} { upvar #0 $varname var global $varname set ch [open $filename] set data [read $ch] close $ch PlotRaise $varname PlotDataSet $varname $dim $data $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc PlotNextColor {which} { switch -- $which { black {return white} white {return red} red {return green} green {return blue} blue {return cyan} cyan {return magenta} magenta {return yellow} yellow {return black} } } proc PlotPing {varname} { upvar #0 $varname var global $varname if {[info exists var(top)]} { if {[winfo exists $var(top)]} { return 1 } } return 0 } proc PlotRaise {varname} { upvar #0 $varname var global $varname if {[PlotPing $varname]} { raise $var(top) return 1 } return 0 } proc PlotSaveConfig {varname} { upvar #0 $varname var global $varname PlotSaveConfigFile $varname [SaveFileDialog apconfigfbox] } proc PlotSaveConfigFile {varname filename} { upvar #0 $varname var global $varname if {$filename == {}} { return } set ch [open $filename w] set analysisplot(graph,x,grid) $var(graph,x,grid) set analysisplot(graph,x,log) $var(graph,x,log) set analysisplot(graph,x,flip) $var(graph,x,flip) set analysisplot(graph,y,grid) $var(graph,y,grid) set analysisplot(graph,y,log) $var(graph,y,log) set analysisplot(graph,y,flip) $var(graph,y,flip) set analysisplot(titleFont) $var(titleFont) set analysisplot(titleSize) $var(titleSize) set analysisplot(titleWeight) $var(titleWeight) set analysisplot(titleSlant) $var(titleSlant) set analysisplot(textlabFont) $var(textlabFont) set analysisplot(textlabSize) $var(textlabSize) set analysisplot(textlabWeight) $var(textlabWeight) set analysisplot(textlabSlant) $var(textlabSlant) set analysisplot(numlabFont) $var(numlabFont) set analysisplot(numlabSize) $var(numlabSize) set analysisplot(numlabWeight) $var(numlabWeight) set analysisplot(numlabSlant) $var(numlabSlant) set analysisplot(graph,x,format) $var(graph,x,format) set analysisplot(graph,y,format) $var(graph,y,format) set analysisplot(discrete) $var(discrete) set analysisplot(discrete,symbol) $var(discrete,symbol) set analysisplot(discrete,fill) $var(discrete,fill) set analysisplot(discrete,color) $var(discrete,color) set analysisplot(linear) $var(linear) set analysisplot(linear,width) $var(linear,width) set analysisplot(linear,color) $var(linear,color) set analysisplot(linear,dash) $var(linear,dash) set analysisplot(step) $var(step) set analysisplot(step,width) $var(step,width) set analysisplot(step,color) $var(step,color) set analysisplot(step,dash) $var(step,dash) set analysisplot(quadratic) $var(quadratic) set analysisplot(quadratic,width) $var(quadratic,width) set analysisplot(quadratic,color) $var(quadratic,color) set analysisplot(quadratic,dash) $var(quadratic,dash) set analysisplot(error) $var(error) set analysisplot(error,width) $var(error,width) set analysisplot(error,color) $var(error,color) set analysisplot(bar) $var(bar) set analysisplot(bar,color) $var(bar,color) puts $ch "array set analysisplot \{ [array get analysisplot] \}" close $ch } proc PlotSaveData {varname} { upvar #0 $varname var global $varname if {$var(xdata) == {}} { return } PlotSaveDataFile $varname [SaveFileDialog apdatafbox] } proc PlotSaveDataFile {varname filename} { upvar #0 $varname var global $varname if {$var(xdata) == {}} { return } if {$filename == {}} { return } global $var(xdata) $var(ydata) $var(xedata) $var(yedata) set ll [$var(xdata) length] set xx [$var(xdata) range] set yy [$var(ydata) range] set ch [open $filename w] switch $var(dim) { xy { for {set ii 0} {$ii<$ll} {incr ii} { puts $ch "[lindex $xx $ii] [lindex $yy $ii]" } } xyxe { set xe [$var(xedata) range] for {set ii 0} {$ii<$ll} {incr ii} { puts $ch "[lindex $xx $ii] [lindex $yy $ii] [lindex $xe $ii]" } } xyye { set ye [$var(yedata) range] for {set ii 0} {$ii<$ll} {incr ii} { puts $ch "[lindex $xx $ii] [lindex $yy $ii] [lindex $ye $ii]" } } xyxeye { set xe [$var(xedata) range] set ye [$var(yedata) range] for {set ii 0} {$ii<$ll} {incr ii} { puts $ch "[lindex $xx $ii] [lindex $yy $ii] [lindex $xe $ii] [lindex $ye $ii]" } } } close $ch PlotRaise $varname } proc PlotStats {varname} { upvar #0 $varname var global $varname if {!$var(stats)} { return } set min {} set max {} set mean {} set median {} set varr {} set sdev {} if {$var(ydata) != {}} { if {[$var(ydata) length] > 0} { set min [format "%6.3f" [blt::vector expr min($var(ydata))]] set max [format "%6.3f" [blt::vector expr max($var(ydata))]] set mean [format "%6.3f" [blt::vector expr mean($var(ydata))]] set median [format "%6.3f" [blt::vector expr median($var(ydata))]] set varr [format "%6.3f" [expr [blt::vector expr var($var(ydata))]]] set sdev [format "%6.3f" [expr [blt::vector expr sdev($var(ydata))]]] } } set rr {} append rr "min $min\n" append rr "max $max\n" append rr "mean $mean\n" append rr "median $median\n" append rr "var $varr\n" append rr "sdev $sdev\n" SimpleTextDialog "${varname}stats" [msgcat::mc {Statistics}] 40 20 insert top $rr PlotStatsDestroyCB $varname } proc PlotStatsDestroyCB {varname} { upvar #0 $varname var global $varname set var(stats) 0 } proc PlotTitle {varname title xaxis yaxis} { upvar #0 $varname var global $varname set var(graph,title) "$title" set var(graph,xaxis) "$xaxis" set var(graph,yaxis) "$yaxis" } proc PlotUpdateGraph {varname} { upvar #0 $varname var global $varname global ds9 if {$var(graph,format)} { if {$var(graph,x,format) != {}} { $var(graph) xaxis configure -command [list PlotAxisFormat $varname x] } else { $var(graph) xaxis configure -command {} } if {$var(graph,y,format) != {}} { $var(graph) yaxis configure -command [list PlotAxisFormat $varname y] } else { $var(graph) yaxis configure -command {} } } # Menus if {$var(xdata) != {}} { $var(mb).file entryconfig "[msgcat::mc {Save Data}]..." -state normal $var(mb).file entryconfig [msgcat::mc {Clear Data}] -state normal $var(mb).file entryconfig [msgcat::mc {Statistics}] -state normal $var(mb).file entryconfig [msgcat::mc {List Data}] -state normal if {$var(1,manage)} { $var(mb).file entryconfig [msgcat::mc {Duplicate Data}] \ -state disabled } else { $var(mb).file entryconfig [msgcat::mc {Duplicate Data}] \ -state normal } } else { $var(mb).file entryconfig "[msgcat::mc {Save Data}]..." -state disabled $var(mb).file entryconfig [msgcat::mc {Clear Data}] -state disabled $var(mb).file entryconfig [msgcat::mc {Duplicate Data}] -state disabled $var(mb).file entryconfig [msgcat::mc {Statistics}] -state disabled $var(mb).file entryconfig [msgcat::mc {List Data}] -state disabled } # Graph $var(graph) configure -plotpadx 0 -plotpady 0 \ -title $var(graph,title) \ -font "{$ds9($var(titleFont))} $var(titleSize) $var(titleWeight) $var(titleSlant)" $var(graph) xaxis configure \ -grid $var(graph,x,grid) -logscale $var(graph,x,log) \ -title $var(graph,xaxis) \ -tickfont "{$ds9($var(numlabFont))} $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "{$ds9($var(textlabFont))} $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" $var(graph) yaxis configure \ -grid $var(graph,y,grid) -logscale $var(graph,y,log) \ -title $var(graph,yaxis) \ -tickfont "{$ds9($var(numlabFont))} $var(numlabSize) $var(numlabWeight) $var(numlabSlant)" \ -titlefont "{$ds9($var(textlabFont))} $var(textlabSize) $var(textlabWeight) $var(textlabSlant)" # windows: we're on top of the image window, so set focus to this window switch $ds9(wm) { x11 {} win32 {focus $var(top)} aqua {} } } ����������������������������������������������������������������������./saods9/src/box.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000006107�12007016077�013172� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BoxDialog {varname} { upvar #0 $varname var global $varname global pmarker # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord # procs set var(proc,apply) BoxApply set var(proc,close) BoxClose set var(proc,coordCB) BoxCoordCB # base MarkerBaseCenterDialog $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisPlot3dDialog $varname # init BoxEditCB $varname MarkerBaseCenterRotateCB $varname # callbacks $var(frame) marker $var(id) callback edit BoxEditCB $varname $var(frame) marker $var(id) callback rotate \ MarkerBaseCenterRotateCB $varname set f $var(top).param # Radius ttk::label $f.tradius -text Size ttk::entry $f.radius1 -textvariable ${varname}(radius1) -width 13 ttk::entry $f.radius2 -textvariable ${varname}(radius2) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list BoxEditCB $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid $f.tradius $f.radius1 $f.radius2 $f.uradius -padx 2 -pady 2 -sticky w grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w } # actions proc BoxClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback edit BoxEditCB $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBaseCenterClose $varname } proc BoxApply {varname} { upvar #0 $varname var global $varname if {$var(radius1) != {} && $var(radius2) !={}} { $var(frame) marker $var(id) box radius \ $var(radius1) $var(radius2) $var(dcoord) $var(dformat) } MarkerBaseCenterRotate $varname MarkerBaseCenterApply $varname } # callbacks proc BoxCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "BoxCoordCB" } MarkerAnalysisStatsSystem $varname MarkerAnalysisPlot3dSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } proc BoxEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "BoxEditCB" } set r [$var(frame) get marker $var(id) box radius \ $var(dcoord) $var(dformat)] set var(radius1) [lindex $r 0] set var(radius2) [lindex $r 1] } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markeranalysisstats.tcl����������������������������������������������������������������0000644�0001750�0001750�00000003707�12010543762�016511� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerAnalysisStatsDialog {varname} { upvar #0 $varname var global $varname set frame $var(frame) set id $var(id) set vvarname stats${id}${frame} upvar #0 $vvarname vvar global $vvarname set var(stats) [info exists ${vvarname}(top)] $var(mb).analysis add checkbutton \ -label [msgcat::mc {Statistics}] \ -variable ${varname}(stats) \ -command "MarkerAnalysisStatsCmd $varname" } proc MarkerAnalysisStatsCmd {varname} { upvar #0 $varname var global $varname MarkerAnalysisStats $var(frame) $var(id) $var(stats) } proc MarkerAnalysisStats {frame id stats} { $frame marker $id analysis stats $stats if {$stats} { MarkerAnalysisStatsCB $frame $id } else { MarkerAnalysisStatsDeleteCB $frame $id } } proc MarkerAnalysisStatsSystem {varname} { upvar #0 $varname var global $varname if {[info exists var(stats)]} { if {$var(stats)} { MarkerAnalysisStatsCB $var(frame) $var(id) } } } # hardcoded marker.C proc MarkerAnalysisStatsCB {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set vvarname stats${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists var(system)]} { set vvar(system) $var(system) set sys $var(system) } elseif {[info exists vvar(system)]} { set sys $vvar(system) } else { global wcs set sys $wcs(system) } set tt [string totitle [$frame get marker $id type]] set rr [$frame get marker $id analysis stats $sys] SimpleTextDialog $vvarname $tt 80 20 insert top $rr } proc MarkerAnalysisStatsDeleteCB {frame id} { set vvarname stats${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists $vvarname]} { SimpleTextDestroy $vvarname } } ���������������������������������������������������������./saods9/src/mwcs.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000007660�11700665571�013370� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menu proc WCSMainMenu {} { global ds9 global wcs CoordMenu $ds9(mb).wcs wcs system 0 sky skyformat UpdateWCS $ds9(mb).wcs add separator $ds9(mb).wcs add command -label "[msgcat::mc {WCS Parameters}]..." \ -command WCSDialog } proc UpdateWCSMenu {} { global wcs global ds9 global current global bin global debug if {$debug(tcl,update)} { puts stderr "UpdateWCSMenu" } if {$current(frame) != {}} { $ds9(mb) entryconfig [msgcat::mc {WCS}] -state normal set ww [$current(frame) get wcs] set wcs(system) [lindex $ww 0] set wcs(sky) [lindex $ww 1] set wcs(skyformat) [lindex $ww 2] set wcs(frame) $current(frame) if {[$current(frame) has fits]} { CoordMenuEnable $ds9(mb).wcs wcs system 0 sky skyformat } else { CoordMenuReset $ds9(mb).wcs wcs system 0 sky skyformat } UpdateWCSInfoBox $current(frame) } else { $ds9(mb) entryconfig [msgcat::mc {WCS}] -state disabled } } proc PrefsDialogWCSMenu {w} { set f [ttk::labelframe $w.mwcs -text [msgcat::mc {WCS}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarWCS $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 -sticky w CoordMenu $f.menu.menu pwcs system 0 sky skyformat {} pack $f -side top -fill both -expand true } # Buttons proc ButtonsWCSDef {} { global pbuttons array set pbuttons { wcs,fk4 1 wcs,fk5 1 wcs,icrs 1 wcs,galactic 1 wcs,ecliptic 1 wcs,degrees 1 wcs,sexagesimal 1 } } proc CreateButtonsWCS {} { global buttons global ds9 global wcs ttk::frame $ds9(buttons).wcs RadioButton $ds9(buttons).wcs.fk4 {fk4} \ wcs(sky) fk4 UpdateWCS RadioButton $ds9(buttons).wcs.fk5 {fk5} \ wcs(sky) fk5 UpdateWCS RadioButton $ds9(buttons).wcs.icrs \ [string tolower [msgcat::mc {ICRS}]] \ wcs(sky) icrs UpdateWCS RadioButton $ds9(buttons).wcs.galactic \ [string tolower [msgcat::mc {Galactic}]] \ wcs(sky) galactic UpdateWCS RadioButton $ds9(buttons).wcs.ecliptic \ [string tolower [msgcat::mc {Ecliptic}]] \ wcs(sky) ecliptic UpdateWCS RadioButton $ds9(buttons).wcs.degrees \ [string tolower [msgcat::mc {Degrees}]] \ wcs(skyformat) degrees UpdateWCS RadioButton $ds9(buttons).wcs.sexagesimal {sexagesimal} \ wcs(skyformat) sexagesimal UpdateWCS set buttons(wcs) " $ds9(buttons).wcs.fk4 pbuttons(wcs,fk4) $ds9(buttons).wcs.fk5 pbuttons(wcs,fk5) $ds9(buttons).wcs.icrs pbuttons(wcs,icrs) $ds9(buttons).wcs.galactic pbuttons(wcs,galactic) $ds9(buttons).wcs.ecliptic pbuttons(wcs,ecliptic) $ds9(buttons).wcs.degrees pbuttons(wcs,degrees) $ds9(buttons).wcs.sexagesimal pbuttons(wcs,sexagesimal) " } proc PrefsDialogButtonbarWCS {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {FK4}] \ -variable pbuttons(wcs,fk4) -command {UpdateButtons buttons(wcs)} $m add checkbutton -label [msgcat::mc {FK5}] \ -variable pbuttons(wcs,fk5) -command {UpdateButtons buttons(wcs)} $m add checkbutton -label [msgcat::mc {ICRS}] \ -variable pbuttons(wcs,icrs) -command {UpdateButtons buttons(wcs)} $m add checkbutton -label [msgcat::mc {Galactic}] \ -variable pbuttons(wcs,galactic) -command {UpdateButtons buttons(wcs)} $m add checkbutton -label [msgcat::mc {Ecliptic}] \ -variable pbuttons(wcs,ecliptic) -command {UpdateButtons buttons(wcs)} $m add separator $m add checkbutton -label [msgcat::mc {Degrees}] \ -variable pbuttons(wcs,degrees) -command {UpdateButtons buttons(wcs)} $m add checkbutton -label [msgcat::mc {Sexagesimal}] \ -variable pbuttons(wcs,sexagesimal) -command {UpdateButtons buttons(wcs)} } ��������������������������������������������������������������������������������./saods9/src/bpanda.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000001700�11732434434�013626� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BpandaDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(which) bpanda set var(proc,apply) MarkerBasePandaRectApply set var(proc,close) MarkerBasePandaRectClose set var(proc,generate) BpandaGenerate set var(proc,coordCB) MarkerBasePandaRectCoordCB set var(proc,editCB) MarkerBasePandaRectEditCB set var(proc,distCB) MarkerBasePandaRectDistCB # base panda rect dialog MarkerBasePandaRectDialog $varname } proc BpandaGenerate {varname} { upvar #0 $varname var global $varname MarkerBaseAnnulusGenerateBox $varname MarkerBasePandaGenerateAngles $varname } ����������������������������������������������������������������./saods9/src/imgsvr.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000030777�12131563555�013731� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc IMGSVRInit {varname title exec ack} { upvar #0 $varname var global $varname global ds9 global pds9 # AR variables ARInit $varname IMGSVRServer # IMG variables set var(proc,exec) $exec set var(proc,ack) $ack set var(current) {} set var(frame) {} set var(rgb) {} # create the window set w $var(top) set mb $var(mb) Toplevel $w $mb 6 $title "ARDestroy $varname" $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Retrieve}] \ -command "IMGSVRApply $varname 0" $mb.file add command -label [msgcat::mc {Cancel}] \ -command "ARCancel $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Update from Current Frame}] \ -command "IMGSVRUpdate $varname 1" $mb.file add command \ -label [msgcat::mc {Update from Current Crosshair}] \ -command "IMGSVRCrosshair $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Acknowledgment}] \ -command "IMGSVRAck $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "ARDestroy $varname" AREditMenu $varname NSVRServerMenu $varname $mb add cascade -label [msgcat::mc {Preferences}] -menu $mb.prefs menu $mb.prefs $mb.prefs add checkbutton -label [msgcat::mc {Save Image on Download}] \ -variable ${varname}(save) $mb.prefs add separator $mb.prefs add radiobutton -label [msgcat::mc {New Frame}] \ -variable ${varname}(mode) -value new $mb.prefs add radiobutton -label [msgcat::mc {Current Frame}] \ -variable ${varname}(mode) -value current # Param set f [ttk::frame $w.param] ttk::label $f.nametitle -text [msgcat::mc {Object}] ttk::entry $f.name -textvariable ${varname}(name) -width 50 ttk::label $f.sky -textvariable ${varname}(sky) -anchor w set var(xname) [ttk::label $f.xtitle -text {} -width 1] ttk::entry $f.x -textvariable ${varname}(x) -width 14 set var(yname) [ttk::label $f.ytitle -text {} -width 1] ttk::entry $f.y -textvariable ${varname}(y) -width 14 ARSkyFormat $f.skyformat $varname ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::entry $f.w -textvariable ${varname}(width) -width 14 ttk::label $f.htitle -text [msgcat::mc {Height}] ttk::entry $f.h -textvariable ${varname}(height) -width 14 ARRFormat $f.format $varname grid $f.nametitle x $f.name - - - - -padx 2 -pady 2 -sticky ew grid $f.sky $f.xtitle $f.x $f.ytitle $f.y $f.skyformat \ -padx 2 -pady 2 -sticky w grid $f.wtitle x $f.w $f.htitle $f.h $f.format -padx 2 -pady 2 -sticky w # Status set f [ttk::frame $w.status] ttk::label $f.title -text [msgcat::mc {Status}] ttk::label $f.item -textvariable ${varname}(status) grid $f.title $f.item -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] set var(apply) [ttk::button $f.apply -text [msgcat::mc {Retrieve}] \ -command "IMGSVRApply $varname 0"] set var(cancel) [ttk::button $f.cancel -text [msgcat::mc {Cancel}] \ -command "ARCancel $varname" -state disabled] ttk::button $f.close -text [msgcat::mc {Close}] \ -command "ARDestroy $varname" pack $f.apply $f.cancel $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal ttk::separator $w.sep2 -orient horizontal pack $w.buttons $w.sep $w.status $w.sep2 -side bottom -fill x pack $w.param -side top -fill both -expand true ARCoord $varname ARStatus $varname {} } proc IMGSVRApply {varname sync} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRApply $varname $sync" } set var(sync) $sync ARApply $varname set var(frame) {} set var(rgb) {} if {($var(name) != {})} { set var(sky) fk5 ARCoord $varname # remember where we are global current switch -- $var(mode) { current { set var(frame) $current(frame) set var(rgb) $current(rgb) } new {} } NSVRServer $varname } else { IMGSVRServer $varname } } proc IMGSVRAck {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRAck $varname" } eval "$var(proc,ack) $varname" } proc IMGSVRUpdate {varname force} { upvar #0 $varname var global $varname global current global wcs global debug if {$debug(tcl,image)} { puts stderr "IMGSVRUpdate $varname $force" } if {$debug(tcl,update)} { puts stderr "IMGSVRUpdate" } if {[winfo exists $var(top)]} { set var(name) {} if {$current(frame) != {} } { set fn [$current(frame) get fits file name] if {($fn != $var(current)) || $force} { set var(current) $fn if {[$current(frame) has wcs equatorial $wcs(system)]} { set coord [$current(frame) get fits center \ $wcs(system) $var(sky) $var(skyformat)] set var(x) [lindex $coord 0] set var(y) [lindex $coord 1] set size [$current(frame) get fits size \ $wcs(system) $var(sky) $var(rformat)] set var(width) [lindex $size 0] set var(height) [lindex $size 1] return } } } else { set var(x) {} set var(y) {} set var(width) {} set var(height) {} } } } proc IMGSVRCrosshair {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRCrosshair $varname" } global current global wcs if {[winfo exists $var(top)]} { set var(name) {} if {$current(frame) != {} } { if {[$current(frame) has wcs equatorial $wcs(system)]} { set coord [$current(frame) get crosshair \ $wcs(system) $var(sky) $var(skyformat)] set var(x) [lindex $coord 0] set var(y) [lindex $coord 1] return } } set var(x) {} set var(y) {} } } proc IMGSVRServer {varname} { upvar #0 $varname var global $varname global current global debug if {$debug(tcl,image)} { puts stderr "IMGSVRServer $varname" } if {($var(x) != {}) && ($var(y) != {})} { switch -- $var(mode) { new {MultiLoadBase} current {} } # remember where we are if {$var(frame) == {}} { set var(frame) $current(frame) } if {$var(rgb) == {}} { set var(rgb) $current(rgb) } ARStatus $varname "Contacting Image Server" eval "$var(proc,exec) $varname" } else { ARStatus $varname "Please specify Coordinates" ARReset $varname } } proc IMGSVRLoad {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRLoad $varname $var(url) $var(query)" } set var(ch) [open "$var(fn)" w] global ihttp if {$var(sync)} { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -channel $var(ch) \ -progress \ [list IMGSVRProgress $varname] \ -binary 1 \ -headers "[ProxyHTTP]" \ -query "$var(query)"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 IMGSVRLoadFinish $varname $var(token) } else { catch {close $var(ch)} ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } else { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -channel $var(ch) \ -command \ [list IMGSVRLoadFinish $varname] \ -progress \ [list IMGSVRProgress $varname] \ -binary 1 \ -headers "[ProxyHTTP]" \ -query "$var(query)"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 } else { catch {close $var(ch)} ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } } proc IMGSVRLoadFinish {varname token} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRLoadFinish $varname" } global current global ds9 global loadParam catch {close $var(ch)} if {!($var(active))} { ARCancelled $varname return } upvar #0 $token t # Code set code [http::ncode $token] # Meta set meta $t(meta) # Log it HTTPLog $token # Result? switch -- $code { 200 - 203 - 404 - 503 {IMGSVRParse $varname} 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $meta { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,hv)} { puts stderr "IMGSVRLoadFinish redirect $code to $value" } # clean up and resubmit http::cleanup $token unset var(token) set var(url) $value IMGSVRLoad $varname } } } default {ARError $varname "[msgcat::mc {Error code was returned}] $code"} } } proc IMGSVRParse {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "IMGSVRParse $varname" } global current global ds9 global loadParam # do we check for valid FITS? if {$var(valid)} { if {![ValidFits $var(fn)]} { ARError $varname "[msgcat::mc {No data available at }] $var(x) $var(y)" return } } # goto to frame if {$var(frame) != {}} { if {$current(frame) != $var(frame)} { set ds9(next) $var(frame) GotoFrame } } # got to channel if {$var(rgb) != {}} { if {$current(rgb) != $var(rgb)} { set current(rgb) $var(rgb) RGBChannel } } StartLoad # alloc it because we are going to delete it after load set loadParam(load,type) allocgz set loadParam(load,layer) {} set loadParam(file,type) fits set loadParam(file,mode) {} set loadParam(file,name) $var(fn) set loadParam(file,fn) $loadParam(file,name) ProcessLoad if {!$var(save)} { if {[file exists $var(fn)]} { catch {file delete -force $var(fn)} } } FinishLoad ARDone $varname } proc IMGSVRProgress {varname token totalsize currentsize} { upvar #0 $varname var global $varname # sometimes we get nothing if {$totalsize == {} || $currentsize == {}} { ARStatus $varname {} } elseif {$totalsize != 0} { ARStatus $varname "$currentsize bytes of $totalsize bytes [expr int(double($currentsize)/$totalsize*100)]%" } else { ARStatus $varname "$currentsize bytes" } } proc IMGSVRProcessCmd {varname iname vvarname} { upvar 2 $varname var upvar 2 $iname i upvar #0 $vvarname vvar switch -- [string tolower [lindex $var $i]] { {} { if {$vvar(name) != {} || ($vvar(x) != {} && $vvar(y) != {})} { IMGSVRApply $vvarname 1 } } open {} close {ARDestroy $vvarname} save { incr i set vvar(save) [FromYesNo [lindex $var $i]] } frame { incr i set vvar(mode) [string tolower [lindex $var $i]] } survey { incr i set vvar(survey) [lindex $var $i] } size { incr i set vvar(width) [lindex $var $i] incr i set vvar(height) [lindex $var $i] incr i if {[lindex $var $i] != {} && \ [string range [lindex $var $i] 0 0] != {-}} { set vvar(rformat) [lindex $var $i] set vvar(rformat,msg) $vvar(rformat) } else { incr i -1 } } update { incr i switch [string tolower [lindex $var $i]] { frame {IMGSVRUpdate $vvarname 1} crosshair {IMGSVRCrosshair $vvarname} } IMGSVRApply $vvarname 1 } coord { incr i set vvar(x) [lindex $var $i] incr i set vvar(y) [lindex $var $i] incr i if {[lindex $var $i] != {} && \ [string range [lindex $var $i] 0 0] != {-}} { set vvar(skyformat) [lindex $var $i] set vvar(skyformat,msg) $vvar(skyformat) } else { incr i -1 } IMGSVRApply $vvarname 1 } name { incr i set vvar(name) [lindex $var $i] if {$vvar(name) != {}} { IMGSVRApply $vvarname 1 } } default { set vvar(name) [lindex $var $i] if {$vvar(name) != {}} { IMGSVRApply $vvarname 1 } } } } proc IMGSVRProcessSendCmd {proc id param vvarname} { upvar #0 $vvarname vvar switch -- [string tolower [lindex $param 0]] { save {$proc $id [ToYesNo $vvar(save)]} frame {$proc $id "$vvar(mode)\n"} survey {$proc $id "$vvar(survey)\n"} size {$proc $id "$vvar(width) $vvar(height) $vvar(rformat)\n"} coord {$proc $id "$vvar(x) $vvar(y) $vvar(skyformat)\n"} name - default {$proc $id "$vvar(name)\n"} } } �./saods9/src/layout.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000052775�12010014162�013716� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CanvasDef {} { global canvas global ds9 set canvas(width) 680 set canvas(height) 450 set canvas(gap) 4 switch $ds9(wm) { x11 { # this is not fool proof. it does not take into account redirecting # the DISPLAY. There must be a better way. global tcl_platform switch -- $tcl_platform(os) { Darwin {set canvas(gap,bottom) 14} default {set canvas(gap,bottom) 0} } } win32 {set canvas(gap,bottom) 0} aqua {set canvas(gap,bottom) 14} } } proc BlinkDef {} { global blink global iblink global pblink set iblink(id) 0 set iblink(index) -1 set blink(interval) 500 array set pblink [array get blink] } proc TileDef {} { global tile global itile global ptile set itile(top) .tile set itile(mb) .tilemb set tile(mode) grid set tile(grid,row) 10 set tile(grid,col) 10 set tile(grid,mode) automatic set tile(grid,gap) 4 array set ptile [array get tile] } proc ViewDef {} { global view global pview set view(layout) horizontal set view(info) 1 set view(panner) 1 set view(magnifier) 1 set view(buttons) 1 set view(colorbar) 1 set view(graph,horz) 0 set view(graph,vert) 0 set view(info,filename) 1 set view(info,object) 1 set view(info,minmax) 0 set view(info,lowhigh) 0 set view(info,wcs) 1 foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { set "view(info,wcs$l)" 0 } set view(info,detector) 0 set view(info,amplifier) 0 set view(info,physical) 1 set view(info,image) 1 set view(info,frame) 1 array set pview [array get view] } # canvas proc CreateCanvas {} { global ds9 global canvas LayoutViewAdjust diff set ww [expr $canvas(width)+$diff(x)] set hh [expr $canvas(height)+$diff(y)] global debug if {$debug(tcl,layout)} { puts stderr "CreateCanvas $canvas(width) $canvas(height) ${ww}x${hh}" } set ds9(image) [ttk::frame $ds9(main).f] set ds9(canvas) [canvas $ds9(image).c -width $ww -height $hh \ -highlightthickness 0 -insertofftime 0 -bg $ds9(bg)] grid rowconfigure $ds9(image) 0 -weight 1 grid columnconfigure $ds9(image) 0 -weight 1 grid $ds9(canvas) -row 0 -column 0 -sticky news # extra space for window tab if {$canvas(gap,bottom)>0} { set f [frame $ds9(image).b -width 1 -height $canvas(gap,bottom) \ -bg $ds9(bg)] grid $f -row 1 -column 0 -sticky ew } # needed to realize window so Layout routines will work grid $ds9(image) } proc InitCanvas {} { global ds9 # Bindings bind $ds9(canvas) <Tab> [list NextFrame] bind $ds9(canvas) <Shift-Tab> [list PrevFrame] switch $ds9(wm) { x11 {bind $ds9(canvas) <ISO_Left_Tab> [list PrevFrame]} aqua {} win32 {} } bind $ds9(canvas) <Configure> [list ConfigureView] switch $ds9(wm) { x11 - aqua { bind $ds9(canvas) <Enter> [list focus $ds9(canvas)] bind $ds9(canvas) <Leave> [list focus {}] } win32 { bind $ds9(canvas) <KeyPress> [list focus $ds9(canvas)] bind $ds9(canvas) <Button> [list focus $ds9(canvas)] bind $ds9(canvas) <Leave> [list focus {}] } } switch $ds9(wm) { x11 {} win32 - aqua {bind $ds9(canvas) <MouseWheel> [list MouseWheelFrame %x %y %D]} } # backward compatible bindings switch $ds9(wm) { x11 - win32 { bind $ds9(canvas) <Button-3> {Button3Canvas %x %y} bind $ds9(canvas) <B3-Motion> {Motion3Canvas %x %y} bind $ds9(canvas) <ButtonRelease-3> {Release3Canvas %x %y} } aqua { # swap button-2 and button-3 on the mighty mouse bind $ds9(canvas) <Button-2> {Button3Canvas %x %y} bind $ds9(canvas) <B2-Motion> {Motion3Canvas %x %y} bind $ds9(canvas) <ButtonRelease-2> {Release3Canvas %x %y} # x11 command key emulation bind $ds9(canvas) <Command-Button-1> {Button3Canvas %x %y} bind $ds9(canvas) <Command-B1-Motion> {Motion3Canvas %x %y} bind $ds9(canvas) <Command-ButtonRelease-1> {Release3Canvas %x %y} } } # freeze bind $ds9(canvas) <f> {ToggleBindEvents} } proc Button3Canvas {x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "Button3Canvas" } set ds9(b3) 1 Button3Colorbar $x $y } proc Motion3Canvas {x y} { global debug if {$debug(tcl,events)} { puts stderr "Motion3Canvas" } Motion3Colorbar $x $y } proc Release3Canvas {x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "Release3Canvas" } set ds9(b3) 0 Release3Colorbar $x $y } proc UnBindEventsCanvas {} { global ds9 foreach f $ds9(active) { UnBindEventsFrame $f } } proc BindEventsCanvas {} { global ds9 global current switch -- $ds9(display) { single - blink {BindEventsFrame $current(frame)} tile { foreach f $ds9(active) { BindEventsFrame $f } } } } # view proc ConfigureView {} { global ds9 global canvas global debug if {$debug(tcl,layout)} { puts stderr "ConfigureView old $canvas(width) $canvas(height)" } # calculate ds9(canvas) size LayoutViewAdjust diff # adjust window size set canvas(width) [expr [winfo width $ds9(canvas)]-$diff(x)] set canvas(height) [expr [winfo height $ds9(canvas)]-$diff(y)] if {$debug(tcl,layout)} { puts stderr "ConfigureView new $canvas(width) $canvas(height)" } LayoutView } proc UpdateView {} { global ds9 global canvas # note: assume canvas(width) and canvas(height) have been set to desired # values. global debug if {$debug(tcl,layout)} { puts stderr "UpdateView to $canvas(width) x $canvas(height)" } # save current size set wo [winfo width $ds9(top)] set ho [winfo height $ds9(top)] # calculate ds9(canvas) size LayoutViewAdjust diff # adjust window size set ww [expr $canvas(width)+$diff(x)] set hh [expr $canvas(height)+$diff(y)] # determine how much to change set wc [winfo width $ds9(canvas)] set hc [winfo height $ds9(canvas)] set wt [winfo width $ds9(top)] set ht [winfo height $ds9(top)] if {$debug(tcl,layout)} { puts stderr "UpdateView before ds9(top) $wt x $ht" } set w [expr $ww - $wc + $wt] set h [expr $hh - $hc + $ht] if {$debug(tcl,layout)} { puts stderr "UpdateView after ds9(top) $w x $h" } # change window size wm geometry $ds9(top) ${w}x${h} LayoutView } proc LayoutView {} { global view global debug if {$debug(tcl,layout)} { puts stderr "LayoutView" } switch $view(layout) { horizontal {LayoutViewHorz} vertical {LayoutViewVert} } LayoutInfoPanel LayoutButtons LayoutFrames LayoutColorbar LayoutGraphs } proc LayoutViewAdjust {varname} { upvar $varname var global debug if {$debug(tcl,layout)} { puts stderr "LayoutViewAdjust" } global view global colorbar global icolorbar global igraph global canvas global ds9 set var(x) 0 set var(y) 0 set cbh [expr $view(colorbar) && \ [string equal $colorbar(orientation) {horizontal}]] set cbv [expr $view(colorbar) && \ [string equal $colorbar(orientation) {vertical}]] set grh $view(graph,horz) set grv $view(graph,vert) if {$colorbar(numerics)} { # ww horizontal: tickgap # hh vertical: approx number of numerals to display switch $ds9(wm) { x11 { set ww 15 set hh 8 } win32 { set ww 20 set hh 6 } aqua { set ww 10 set hh 5 } } # actual ascent is ~1.2 * font,size set icolorbar(horizontal,height) \ [expr int($colorbar(size) + $colorbar(font,size)*1.2 + $ww)] set icolorbar(vertical,width) \ [expr $colorbar(size) + $colorbar(font,size)*$hh] } else { set icolorbar(horizontal,height) [expr $colorbar(size) +2] set icolorbar(vertical,width) [expr $colorbar(size) +2] } # basics if {$cbh} { incr var(y) $icolorbar(horizontal,height) } if {$cbv} { incr var(x) $icolorbar(vertical,width) } if {$grh} { incr var(y) $igraph(size) } if {$grv} { incr var(x) $igraph(size) } # canvas gap if {$cbh || $grh} { incr var(y) $canvas(gap) } if {$cbv || $grv} { incr var(x) $canvas(gap) } # graph gap if {$grv && !$cbh} { incr var(y) $igraph(gap,y) } if {$grh && !$cbv} { incr var(x) $igraph(gap,x) } global debug if {$debug(tcl,layout)} { puts stderr "LayoutViewAdjust $var(x) $var(y)" } } proc LayoutOrient {} { global ds9 global canvas global debug if {$debug(tcl,layout)} { puts stderr "LayoutOrient" } # save original canvas size set ww $canvas(width) set hh $canvas(height) # horizontal grid rowconfigure $ds9(main) 4 -weight 0 grid columnconfigure $ds9(main) 0 -weight 0 # vertical grid rowconfigure $ds9(main) 0 -weight 0 grid columnconfigure $ds9(main) 4 -weight 0 grid forget $ds9(panel) grid forget $ds9(panel,sep) grid forget $ds9(buttons) grid forget $ds9(buttons,sep) grid forget $ds9(image) pack forget $ds9(info) pack forget $ds9(panner) pack forget $ds9(magnifier) UpdateView update # restore original canvas size set canvas(width) $ww set canvas(height) $hh UpdateView } proc LayoutViewHorz {} { global ds9 global current global view # canvas grid rowconfigure $ds9(main) 4 -weight 1 grid columnconfigure $ds9(main) 0 -weight 1 grid $ds9(image) -row 4 -column 0 -sticky news # info panel if {$view(info) || $view(magnifier) || $view(panner)} { grid $ds9(panel) -row 0 -column 0 -sticky ew -columnspan 3 $ds9(panel,sep) configure -orient horizontal grid $ds9(panel,sep) -row 1 -column 0 -sticky ew -columnspan 3 } else { grid forget $ds9(panel) grid forget $ds9(panel,sep) } if {$view(info)} { pack $ds9(info) -side left -anchor nw -padx 2 -pady 2 \ -fill x -expand true } else { pack forget $ds9(info) } if {$view(panner)} { pack $ds9(panner) -side right -padx 2 -pady 2 } else { pack forget $ds9(panner) } if {$view(magnifier)} { pack $ds9(magnifier) -side right -padx 2 -pady 2 if {$view(panner)} { pack $ds9(magnifier) -before $ds9(panner) } } else { pack forget $ds9(magnifier) } # buttons if {$view(buttons)} { grid $ds9(buttons) -row 2 -sticky ew -columnspan 3 $ds9(buttons,sep) configure -orient horizontal grid $ds9(buttons,sep) -row 3 -column 0 -sticky ew -columnspan 3 } else { grid forget $ds9(buttons) grid forget $ds9(buttons,sep) } } proc LayoutViewVert {} { global ds9 global current global view # canvas grid rowconfigure $ds9(main) 0 -weight 1 grid columnconfigure $ds9(main) 4 -weight 1 grid $ds9(image) -row 0 -column 4 -sticky news # info panel if {$view(info) || $view(magnifier) || $view(panner)} { grid $ds9(panel) -row 0 -column 0 -sticky ns $ds9(panel,sep) configure -orient vertical grid $ds9(panel,sep) -row 0 -column 1 -sticky ns } else { grid forget $ds9(panel) grid forget $ds9(panel,sep) } if {$view(magnifier)} { pack $ds9(magnifier) -side top -padx 2 -pady 2 } else { pack forget $ds9(magnifier) } if {$view(info)} { pack $ds9(info) -side top -padx 2 -pady 2 -fill y -expand true if {$view(magnifier)} { pack $ds9(info) -after $ds9(magnifier) } } else { pack forget $ds9(info) } if {$view(panner)} { pack $ds9(panner) -side bottom -padx 2 -pady 2 } else { pack forget $ds9(panner) } # buttons if {$view(buttons)} { grid $ds9(buttons) -row 0 -column 2 -sticky ns $ds9(buttons,sep) configure -orient vertical grid $ds9(buttons,sep) -row 0 -column 3 -sticky ns } else { grid forget $ds9(buttons) grid forget $ds9(buttons,sep) } } proc LayoutFrames {} { global ds9 global current global tile global view global colorbar # turn everything off foreach f $ds9(frames) { $f hide $f highlite off $f panner off $f magnifier off UnBindEventsFrame $f } if {$ds9(active,num) > 0} { switch -- $ds9(display) { single {TileOne} tile { switch -- $tile(mode) { row {TileRect 1 $ds9(active,num) $tile(grid,gap)} column {TileRect $ds9(active,num) 1 $tile(grid,gap)} grid { switch -- $tile(grid,mode) { automatic { TileRect [expr int(sqrt($ds9(active,num)-1))+1] \ [expr int(sqrt($ds9(active,num))+.5)] \ $tile(grid,gap) } manual { TileRect \ $tile(grid,col) \ $tile(grid,row) \ $tile(grid,gap) } } } } } blink {TileOne} } } else { set current(frame) {} set ds9(next) {} # panner if {$view(panner)} { panner clear } # magnifier if {$view(magnifier)} { magnifier clear } # process proper colorbar switch -- $ds9(visual) { pseudocolor { colorbar show set current(colorbar) colorbar set colorbar(map) [colorbar get name] set colorbar(invert) [colorbar get invert] } truecolor { colorbar show colorbarrgb hide $ds9(canvas) raise colorbar colorbarrgb set current(colorbar) colorbar set colorbar(map) [colorbar get name] set colorbar(invert) [colorbar get invert] } } # update menus/dialogs UpdateDS9 } } # This procedure is called when we have only 1 frames to display proc TileOne {} { global ds9 global view global current global canvas global colorbar set ww $canvas(width) set hh $canvas(height) set xx 0 set yy 0 foreach f $ds9(active) { $f configure -x $xx -y $yy -width $ww -height $hh -anchor nw } # only show the current frame $current(frame) show FrameToFront } proc TileRect {numx numy gap} { global view global canvas set ww $canvas(width) set hh $canvas(height) set w [expr int(($ww-$gap*($numx-1))/$numx)] set h [expr int(($hh-$gap*($numy-1))/$numy)] for {set jj 0} {$jj<$numy} {incr jj} { for {set ii 0} {$ii<$numx} {incr ii} { set c [expr $jj*$numx + $ii] set x($c) [expr ($w+$gap)*$ii] set y($c) [expr ($h+$gap)*$jj] } } TileIt $w $h x y [expr $numx*$numy] } proc TileIt {ww hh xx yy nn} { upvar $xx x upvar $yy y global ds9 global current set i 0 foreach f $ds9(active) { if {$i<$nn} { $f configure -x $x($i) -y $y($i) -width $ww -height $hh -anchor nw $f show $ds9(canvas) raise $f if {!$ds9(freeze)} { BindEventsFrame $f } } incr i } # if manual grid, current frame could be not included if {$current(frame) != {}} { $current(frame) colorbar tag "\{[$current(colorbar) get tag]\}" } if {$ds9(active,num) > $nn} { set current(frame) [lindex $ds9(active) 0] } FrameToFront } proc DisplayDefaultDialog {} { global canvas global ed set w {.defdpy} set ed(ok) 0 set ed(x) $canvas(width) set ed(y) $canvas(height) DialogCreate $w [msgcat::mc {Display Size}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.xTitle -text {X} ttk::label $f.yTitle -text {Y} ttk::entry $f.x -textvariable ed(x) -width 10 ttk::entry $f.y -textvariable ed(y) -width 10 ttk::label $f.xunit -text [msgcat::mc {Pixels}] ttk::label $f.yunit -text [msgcat::mc {Pixels}] grid $f.xTitle $f.x $f.xunit -padx 2 -pady 2 -sticky w grid $f.yTitle $f.y $f.yunit -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w $w.param.x select range 0 end DialogWait $w ed(ok) $w.param.x DialogDismiss $w if {$ed(ok)} { set canvas(width) $ed(x) set canvas(height) $ed(y) UpdateView } set rr $ed(ok) unset ed return $rr } # Process Cmds proc ProcessHeightCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized # can't use ProcessRealize RealizeDS9 global canvas set canvas(height) [lindex $var $i] UpdateView } proc ProcessSendHeightCmd {proc id param} { global canvas $proc $id "$canvas(height)\n" } proc ProcessWidthCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized # can't use ProcessRealize RealizeDS9 global canvas set canvas(width) [lindex $var $i] UpdateView } proc ProcessSendWidthCmd {proc id param} { global canvas $proc $id "$canvas(width)\n" } proc ProcessViewCmd {varname iname} { upvar $varname var upvar $iname i global view global rgb set item [string tolower [lindex $var $i]] switch -- $item { layout { incr i set item [string tolower [lindex $var $i]] switch -- $item { horizontal - vertical {set view(layout) $item; LayoutOrient} } } horizontal - vertical { # backward compatibility set view(layout) $item LayoutOrient } default { set yesno [lindex $var [expr $i+1]] switch -- $yesno { 1 - 0 - yes - no - on - off - true - false {incr i} default { set yesno 1 } } switch -- $item { info - panner - magnifier - buttons - colorbar {set view($item) [FromYesNo $yesno]} colorbarnumerics { # backward compatibility set colorbar(numerics) [FromYesNo $yesno] } graph { incr i set item [string tolower [lindex $var $i]] switch -- $item { horizontal { set yesno [lindex $var [expr $i+1]] switch -- $yesno { 1 - 0 - yes - no - on - off - true - false {incr i} default { set yesno 1 } } set view(graph,horz) [FromYesNo $yesno] } vertical { set yesno [lindex $var [expr $i+1]] switch -- $yesno { 1 - 0 - yes - no - on - off - true - false {incr i} default { set yesno 1 } } set view(graph,vert) [FromYesNo $yesno] } } } horzgraph { # backward compatibility set view(graph,horz) [FromYesNo $yesno] } vertgraph { # backward compatibility set view(graph,vert) [FromYesNo $yesno] } filename - object - minmax - lowhigh - frame - detector - amplifier - physical - image - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {set view(info,$item) [FromYesNo $yesno]} red - green - blue {set rgb($item) [FromYesNo $yesno]; RGBView} } UpdateView } } } proc ProcessSendViewCmd {proc id param} { global view switch -- [string tolower [lindex $param 0]] { layout {$proc $id "$view(layout)\n"} info {$proc $id [ToYesNo $view(info)]} panner {$proc $id [ToYesNo $view(panner)]} magnifier {$proc $id [ToYesNo $view(magnifier)]} buttons {$proc $id [ToYesNo $view(buttons)]} colorbar {$proc $id [ToYesNo $view(colorbar)]} colorbarnumerics { # backward compatibility $proc $id [ToYesNo $colorbar(numerics)] } graph { switch -- [string tolower [lindex $param 1]] { horizontal {$proc $id [ToYesNo $view(graph,horz)]} vertical {$proc $id [ToYesNo $view(graph,vert)]} } } horzgraph { # backward compatibility $proc $id [ToYesNo $view(graph,horz)] } vertgraph { # backward compatibility $proc $id [ToYesNo $view(graph,vert)] } filename {$proc $id [ToYesNo $view(info,filename)]} object {$proc $id [ToYesNo $view(info,object)]} minmax {$proc $id [ToYesNo $view(info,minmax)]} lowhigh {$proc $id [ToYesNo $view(info,lowhigh)]} frame {$proc $id [ToYesNo $view(info,frame)]} detector {$proc $id [ToYesNo $view(info,detector)]} amplifier {$proc $id [ToYesNo $view(info,amplifier)]} physical {$proc $id [ToYesNo $view(info,physical)]} image {$proc $id [ToYesNo $view(info,image)]} wcs {$proc $id [ToYesNo $view(info,wcs)]} wcsa {$proc $id [ToYesNo $view(info,wcsa)]} wcsb {$proc $id [ToYesNo $view(info,wcsb)]} wcsc {$proc $id [ToYesNo $view(info,wcsc)]} wcsd {$proc $id [ToYesNo $view(info,wcsd)]} wcse {$proc $id [ToYesNo $view(info,wcse)]} wcsf {$proc $id [ToYesNo $view(info,wcsf)]} wcsg {$proc $id [ToYesNo $view(info,wcsg)]} wcsh {$proc $id [ToYesNo $view(info,wcsh)]} wcsi {$proc $id [ToYesNo $view(info,wcsi)]} wcsj {$proc $id [ToYesNo $view(info,wcsj)]} wcsk {$proc $id [ToYesNo $view(info,wcsk)]} wcsl {$proc $id [ToYesNo $view(info,wcsl)]} wcsm {$proc $id [ToYesNo $view(info,wcsm)]} wcsn {$proc $id [ToYesNo $view(info,wcsn)]} wcso {$proc $id [ToYesNo $view(info,wcso)]} wcsp {$proc $id [ToYesNo $view(info,wcsp)]} wcsq {$proc $id [ToYesNo $view(info,wcsq)]} wcsr {$proc $id [ToYesNo $view(info,wcsr)]} wcss {$proc $id [ToYesNo $view(info,wcss)]} wcst {$proc $id [ToYesNo $view(info,wcst)]} wcsu {$proc $id [ToYesNo $view(info,wcsu)]} wcsv {$proc $id [ToYesNo $view(info,wcsv)]} wcsw {$proc $id [ToYesNo $view(info,wcsw)]} wcsx {$proc $id [ToYesNo $view(info,wcsx)]} wcsy {$proc $id [ToYesNo $view(info,wcsy)]} wcsz {$proc $id [ToYesNo $view(info,wcsz)]} default { # backward compatibility $proc $id "$view(layout)\n" } } } ���./saods9/src/save.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000011350�12132024702�013325� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SaveDef {} { global savefits set savefits(type) image set savefits(mosaic) 1 } proc Save {format fn} { global savefits switch -- $format { fits {SaveFitsFile $savefits(type) $fn} sfits {} rgbimage {SaveRGBImageFile $fn} rgbcube {SaveRGBCubeFile $fn} srgbcube {} mecube {SaveMECubeFile $fn} multiframe {} mosaicimage - mosaicimagewcs {SaveMosaicImageWCSFile $fn} mosaicimageiraf {} mosaicimagewfpc {} mosaic - mosaicwcs {SaveMosaicWCSFile $fn $savefits(mosaic)} mosaiciraf {} smosaicwcs {} smosaiciraf {} } } # Process Cmds proc ProcessSaveCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 set format {} set fn [lindex $var $i] if {$fn == {}} { return } switch -- $fn { fits - sfits - rgbimage - rgbcube - srgbcube - mecube - multiframe - mosaicimagewcs - mosaicimageiraf - mosaicimagewfpc - mosaicwcs - mosaiciraf - smosaicwcs - smosaiciraf { set format $fn set fn {} incr i } mosaicimage - mosaic { set format $fn set fn {} incr i # eat any wcs if {[string range [lindex $var $i] 0 2] == {wcs}} { incr i } } } # one last time if {$fn == {}} { set fn [lindex $var $i] if {$fn == {}} { return } } if {$format == {}} { set format [ExtToFormat $fn] } global savefits set param [string tolower [lindex $var [expr $i+1]]] switch $format { fits { switch $param { slice - image - table { set savefits(type) $param incr i } default {set savefits(type) image} } } mosaic - mosaiciraf - mosaicwcs { if {[string is integer -strict $param]} { set savefits(mosaic) $param incr i } } } global savefitsfbox FileLast savefitsfbox $fn Save $format $fn } # Support proc SaveDialog {format} { global savefits global current set fn [SaveFileDialog savefitsfbox] set which image if {$fn != {}} { set ok 1 if {$current(frame) != {}} { switch -- $format { fits { if {[$current(frame) has fits bin]} { set ok [SaveParams savefits] } } slice { set format fits set savefits(type) slice } mosaicwcs - mosaiciraf { if {[$current(frame) has fits mosaic]} { set ok [SaveMosaicParams savefits] } } } } if {$ok} { Save $format $fn } } } proc SaveParams {varname} { upvar $varname var global ed2 set w {.savefits} set ed2(ok) 0 set ed2(type) $var(type) DialogCreate $w {Fits} ed2(ok) # Param set f [ttk::frame $w.param] ttk::label $f.tfits -text [msgcat::mc {Fits}] ttk::radiobutton $f.image -text [msgcat::mc {Image}] \ -variable ed2(type) -value image ttk::radiobutton $f.table -text {Table} \ -variable ed2(type) -value table grid $f.tfits $f.image $f.table -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set var(type) $ed2(type) } set rr $ed2(ok) unset ed2 return $rr } proc SaveMosaicParams {varname} { upvar $varname var global ed2 set w {.savefits} set ed2(ok) 0 set ed2(mosaic) $var(mosaic) DialogCreate $w {Mosaic} ed2(ok) # Param set f [ttk::frame $w.param] ttk::label $f.tmosaic -text [msgcat::mc {Mosaic}] ttk::entry $f.mosaic -textvariable ed2(mosaic) -width 8 grid $f.tmosaic $f.mosaic -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set var(mosaic) $ed2(mosaic) } set rr $ed2(ok) unset ed2 return $rr } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mfile.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000060150�12131563555�013502� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc FileMainMenu {} { global ds9 menu $ds9(mb).file $ds9(mb).file add command -label "[msgcat::mc {Open}]..." \ -command [list OpenDialog fits] -accelerator "${ds9(ctrl)}O" $ds9(mb).file add cascade -label [msgcat::mc {Open as}] \ -menu $ds9(mb).file.open $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Save}]..." \ -command [list SaveDialog fits] -accelerator "${ds9(ctrl)}S" $ds9(mb).file add cascade -label [msgcat::mc {Save as}] \ -menu $ds9(mb).file.save $ds9(mb).file add separator $ds9(mb).file add cascade -label [msgcat::mc {Import}] \ -menu $ds9(mb).file.import $ds9(mb).file add cascade -label [msgcat::mc {Export}] \ -menu $ds9(mb).file.export $ds9(mb).file add separator $ds9(mb).file add cascade -label [msgcat::mc {Save Image}] \ -menu $ds9(mb).file.saveimage $ds9(mb).file add command -label "[msgcat::mc {Create Movie}]..." \ -command MovieDialog $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Backup}]..." \ -command BackupDialog $ds9(mb).file add command -label "[msgcat::mc {Restore}]..." \ -command RestoreDialog $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Display Header}]..." \ -command DisplayHeaderMenu $ds9(mb).file add cascade -label [msgcat::mc {Preserve During Load}] \ -menu $ds9(mb).file.preserve $ds9(mb).file add separator $ds9(mb).file add cascade -label [msgcat::mc {XPA}] \ -menu $ds9(mb).file.xpa $ds9(mb).file add cascade -label [msgcat::mc {SAMP}] \ -menu $ds9(mb).file.samp $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Open TCL Console}]..." \ -command OpenConsole $ds9(mb).file add command -label "[msgcat::mc {Source TCL}]..." \ -command OpenSource $ds9(mb).file add separator switch $ds9(wm) { x11 { $ds9(mb).file add command -label "[msgcat::mc {Page Setup}]..." \ -command PSPageSetup -accelerator "${ds9(shiftctrl)}P" $ds9(mb).file add command -label "[msgcat::mc {Print}]..." \ -command PSPrint -accelerator "${ds9(ctrl)}P" } win32 { $ds9(mb).file add command \ -label "[msgcat::mc {Postscript Page Setup}]..." \ -command PSPageSetup $ds9(mb).file add command \ -label "[msgcat::mc {Postscript Print}]..." \ -command PSPrint $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Page Setup}]..." \ -command Win32PageSetup -accelerator "${ds9(shiftctrl)}P" $ds9(mb).file add command -label "[msgcat::mc {Print}]..." \ -command Win32Print -accelerator "${ds9(ctrl)}P" } aqua { $ds9(mb).file add command \ -label "[msgcat::mc {Postscript Page Setup}]..." \ -command PSPageSetup $ds9(mb).file add command \ -label "[msgcat::mc {Postscript Print}]..." \ -command PSPrint $ds9(mb).file add separator $ds9(mb).file add command -label "[msgcat::mc {Page Setup}]..." \ -command MacOSXPageSetup -accelerator "${ds9(shiftctrl)}P" $ds9(mb).file add command -label "[msgcat::mc {Print}]..." \ -command MacOSXPrint -accelerator "${ds9(ctrl)}P" } } switch $ds9(wm) { x11 - win32 { $ds9(mb).file add separator $ds9(mb).file add command \ -label [msgcat::mc {Exit}] -command QuitDS9 } aqua {} } # File Open Menu menu $ds9(mb).file.open $ds9(mb).file.open add command -label "[msgcat::mc {Slice}]..." \ -command [list OpenDialog fits {} slice] $ds9(mb).file.open add separator $ds9(mb).file.open add command \ -label "[msgcat::mc {RGB Image}]..." \ -command [list OpenDialog rgbimage] $ds9(mb).file.open add command \ -label "[msgcat::mc {RGB Cube}]..."\ -command [list OpenDialog rgbcube] $ds9(mb).file.open add separator $ds9(mb).file.open add command \ -label "[msgcat::mc {Multiple Extension Cube}]..." \ -command [list OpenDialog mecube] $ds9(mb).file.open add command \ -label "[msgcat::mc {Multiple Extension Frames}]..." \ -command [list OpenDialog multiframe] $ds9(mb).file.open add separator $ds9(mb).file.open add command \ -label "[msgcat::mc {Mosaic WCS}]..." \ -command [list OpenDialog mosaicimagewcs] $ds9(mb).file.open add command \ -label "[msgcat::mc {Mosaic WCS Segment}]..." \ -command [list OpenDialog mosaicwcs] $ds9(mb).file.open add command \ -label "[msgcat::mc {Mosaic IRAF}]..." \ -command [list OpenDialog mosaicimageiraf] $ds9(mb).file.open add command \ -label "[msgcat::mc {Mosaic IRAF Segment}]..." \ -command [list OpenDialog mosaiciraf] $ds9(mb).file.open add command \ -label "[msgcat::mc {Mosaic WFPC2}]..." \ -command [list OpenDialog mosaicimagewfpc2] $ds9(mb).file.open add separator $ds9(mb).file.open add command \ -label "[msgcat::mc {URL}]..." \ -command [list OpenURLFits] # File Save Menu menu $ds9(mb).file.save $ds9(mb).file.save add command -label "[msgcat::mc {Slice}]..." \ -command [list SaveDialog slice] $ds9(mb).file.save add separator $ds9(mb).file.save add command \ -label "[msgcat::mc {RGB Image}]..." \ -command [list SaveDialog rgbimage] $ds9(mb).file.save add command \ -label "[msgcat::mc {RGB Cube}]..."\ -command [list SaveDialog rgbcube] $ds9(mb).file.save add separator $ds9(mb).file.save add command \ -label "[msgcat::mc {Multiple Extension Cube}]..." \ -command [list SaveDialog mecube] $ds9(mb).file.save add separator $ds9(mb).file.save add command \ -label "[msgcat::mc {Mosaic WCS}]..." \ -command [list SaveDialog mosaicimagewcs] $ds9(mb).file.save add command \ -label "[msgcat::mc {Mosaic WCS Segment}]..." \ -command [list SaveDialog mosaicwcs] # File Import Menu menu $ds9(mb).file.import $ds9(mb).file.import add cascade -label [msgcat::mc {Slice}] \ -menu $ds9(mb).file.import.slice $ds9(mb).file.import add separator $ds9(mb).file.import add command -label "[msgcat::mc {Array}]..." \ -command [list ImportDialog array] $ds9(mb).file.import add command -label {NRRD...} \ -command [list ImportDialog nrrd] $ds9(mb).file.import add separator $ds9(mb).file.import add command -label "[msgcat::mc {RGB Array}]..." \ -command [list ImportDialog rgbarray] $ds9(mb).file.import add separator $ds9(mb).file.import add command -label {GIF...} \ -command [list ImportDialog gif] $ds9(mb).file.import add command -label {TIFF...} \ -command [list ImportDialog tiff] $ds9(mb).file.import add command -label {JPEG...} \ -command [list ImportDialog jpeg] $ds9(mb).file.import add command -label {PNG...} \ -command [list ImportDialog png] # File Import Slice Menu menu $ds9(mb).file.import.slice $ds9(mb).file.import.slice add command -label {GIF...} \ -command [list ImportDialog gif {} slice] $ds9(mb).file.import.slice add command -label {TIFF...} \ -command [list ImportDialog tiff {} slice] $ds9(mb).file.import.slice add command -label {JPEG...} \ -command [list ImportDialog jpeg {} slice] $ds9(mb).file.import.slice add command -label {PNG...} \ -command [list ImportDialog png {} slice] # File Export Menu menu $ds9(mb).file.export $ds9(mb).file.export add command -label "[msgcat::mc {Array}]..." \ -command [list ExportDialog array] $ds9(mb).file.export add command -label {NRRD...} \ -command [list ExportDialog nrrd] $ds9(mb).file.export add separator $ds9(mb).file.export add command -label "[msgcat::mc {RGB Array}]..." \ -command [list ExportDialog rgbarray] $ds9(mb).file.export add separator $ds9(mb).file.export add command -label {GIF...} \ -command [list ExportDialog gif] $ds9(mb).file.export add command -label {TIFF...} \ -command [list ExportDialog tiff] $ds9(mb).file.export add command -label {JPEG...} \ -command [list ExportDialog jpeg] $ds9(mb).file.export add command -label {PNG...} \ -command [list ExportDialog png] # File Saveimage Menu menu $ds9(mb).file.saveimage $ds9(mb).file.saveimage add command -label {FITS...} \ -command [list SaveImageDialog fits] $ds9(mb).file.saveimage add command -label {EPS...} \ -command [list SaveImageDialog eps] $ds9(mb).file.saveimage add command -label {GIF...} \ -command [list SaveImageDialog gif] $ds9(mb).file.saveimage add command -label {TIFF...} \ -command [list SaveImageDialog tiff] $ds9(mb).file.saveimage add command -label {JPEG...} \ -command [list SaveImageDialog jpeg] $ds9(mb).file.saveimage add command -label {PNG...} \ -command [list SaveImageDialog png] # File Preserve Menu menu $ds9(mb).file.preserve $ds9(mb).file.preserve add checkbutton -label [msgcat::mc {Scale}] \ -variable scale(preserve) -command PreserveScale $ds9(mb).file.preserve add checkbutton -label [msgcat::mc {Pan}] \ -variable panzoom(preserve) -command PreservePan $ds9(mb).file.preserve add checkbutton -label [msgcat::mc {Region}] \ -variable marker(preserve) -command MarkerPreserve menu $ds9(mb).file.samp $ds9(mb).file.samp add command -label [msgcat::mc {Connect}] \ -command SAMPConnect $ds9(mb).file.samp add command -label [msgcat::mc {Disconnect}] \ -command SAMPDisconnect $ds9(mb).file.samp add separator $ds9(mb).file.samp add cascade -label [msgcat::mc {Image}] \ -menu $ds9(mb).file.samp.image $ds9(mb).file.samp add cascade -label [msgcat::mc {Table}] \ -menu $ds9(mb).file.samp.table menu $ds9(mb).file.samp.image $ds9(mb).file.samp.image add command -label [msgcat::mc {Broadcast}] \ -command "SAMPSendImageLoadFits {}" $ds9(mb).file.samp.image add separator menu $ds9(mb).file.samp.table $ds9(mb).file.samp.table add command -label [msgcat::mc {Broadcast}] \ -command "SAMPSendTableLoadFits {}" $ds9(mb).file.samp.table add separator menu $ds9(mb).file.xpa $ds9(mb).file.xpa add command -label "[msgcat::mc {Information}]..." \ -command XPAInfo $ds9(mb).file.xpa add separator $ds9(mb).file.xpa add command -label [msgcat::mc {Connect}] \ -command XPAConnect $ds9(mb).file.xpa add command -label [msgcat::mc {Disconnect}] \ -command XPADisconnect # Bindings bind $ds9(top) <<Open>> [list OpenDialog fits] switch $ds9(wm) { x11 { bind $ds9(top) <<PageSetup>> PSPageSetup bind $ds9(top) <<Print>> PSPrint } win32 { bind $ds9(top) <<PageSetup>> Win32PageSetup bind $ds9(top) <<Print>> Win32Print } aqua { bind $ds9(top) <<PageSetup>> MacOSXPageSetup bind $ds9(top) <<Print>> MacOSXPrint } } } proc PrefsDialogFileMenu {w} { set f [ttk::labelframe $w.mfile -text [msgcat::mc {File}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarFile $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add cascade -label [msgcat::mc {Preserve During Load}] \ -menu $m.preserve global pscale global ppanzoom global pmarker menu $m.preserve $m.preserve add checkbutton -label [msgcat::mc {Scale}] \ -variable pscale(preserve) $m.preserve add checkbutton -label [msgcat::mc {Pan}] \ -variable ppanzoom(preserve) $m.preserve add checkbutton -label [msgcat::mc {Region}] \ -variable pmarker(preserve) pack $f -side top -fill both -expand true } # Buttons proc ButtonsFileDef {} { global pbuttons array set pbuttons { file,open 1 file,save 1 file,movie 0 file,backup 0 file,restore 0 file,header 1 file,xpa,info 0 file,samp,image 0 file,samp,table 0 file,console 0 file,tcl 0 file,pspage 0 file,psprint 0 file,page 1 file,print 1 file,exit 1 } } proc CreateButtonsFile {} { global ds9 global buttons ttk::frame $ds9(buttons).file ButtonButton $ds9(buttons).file.open \ [string tolower [msgcat::mc {Open}]] \ [list OpenDialog fits] ButtonButton $ds9(buttons).file.save \ [string tolower [msgcat::mc {Save}]] \ [list SaveDialog fits] ButtonButton $ds9(buttons).file.movie \ [string tolower [msgcat::mc {Create Movie}]] MovieDialog ButtonButton $ds9(buttons).file.backup \ [string tolower [msgcat::mc {Backup}]] BackupDialog ButtonButton $ds9(buttons).file.restore \ [string tolower [msgcat::mc {Restore}]] RestoreDialog ButtonButton $ds9(buttons).file.header \ [string tolower [msgcat::mc {Header}]] DisplayHeaderMenu ButtonButton $ds9(buttons).file.xpainfo \ [string tolower {XPA Info}] XPAInfo ButtonButton $ds9(buttons).file.sampimage \ [string tolower [msgcat::mc {SAMP Image}]] "SAMPSendImageLoadFits {}" ButtonButton $ds9(buttons).file.samptable \ [string tolower [msgcat::mc {SAMP Table}]] "SAMPSendTableLoadFits {}" ButtonButton $ds9(buttons).file.console \ [string tolower [msgcat::mc {Console}]] OpenConsole ButtonButton $ds9(buttons).file.tcl \ [string tolower {TCL}] OpenSource ButtonButton $ds9(buttons).file.pspage \ [string tolower [msgcat::mc {PS Page Setup}]] PSPageSetup ButtonButton $ds9(buttons).file.psprint \ [string tolower [msgcat::mc {PS Print}]] PSPrint switch $ds9(wm) { x11 { ButtonButton $ds9(buttons).file.page \ [string tolower [msgcat::mc {Page Setup}]] PSPageSetup ButtonButton $ds9(buttons).file.print \ [string tolower [msgcat::mc {Print}]] PSPrint } win32 { ButtonButton $ds9(buttons).file.page \ [string tolower [msgcat::mc {Page Setup}]] Win32PageSetup ButtonButton $ds9(buttons).file.print \ [string tolower [msgcat::mc {Print}]] Win32Print } aqua { ButtonButton $ds9(buttons).file.page \ [string tolower [msgcat::mc {Page Setup}]] MacOSXPageSetup ButtonButton $ds9(buttons).file.print \ [string tolower [msgcat::mc {Print}]] MacOSXPrint } } ButtonButton $ds9(buttons).file.exit \ [string tolower [msgcat::mc {Exit}]] QuitDS9 set buttons(file) " $ds9(buttons).file.open pbuttons(file,open) $ds9(buttons).file.save pbuttons(file,save) $ds9(buttons).file.movie pbuttons(file,movie) $ds9(buttons).file.backup pbuttons(file,backup) $ds9(buttons).file.restore pbuttons(file,restore) $ds9(buttons).file.header pbuttons(file,header) $ds9(buttons).file.xpainfo pbuttons(file,xpa,info) $ds9(buttons).file.sampimage pbuttons(file,samp,image) $ds9(buttons).file.samptable pbuttons(file,samp,table) $ds9(buttons).file.console pbuttons(file,console) $ds9(buttons).file.tcl pbuttons(file,tcl) $ds9(buttons).file.pspage pbuttons(file,pspage) $ds9(buttons).file.psprint pbuttons(file,psprint) $ds9(buttons).file.page pbuttons(file,page) $ds9(buttons).file.print pbuttons(file,print) $ds9(buttons).file.exit pbuttons(file,exit) " } proc PrefsDialogButtonbarFile {f} { global buttons global pbuttons global ds9 ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label "[msgcat::mc {Open}]..." \ -variable pbuttons(file,open) -command {UpdateButtons buttons(file)} $m add checkbutton -label "[msgcat::mc {Save}]..." \ -variable pbuttons(file,save) -command {UpdateButtons buttons(file)} $m add separator $m add checkbutton -label "[msgcat::mc {Create Movie}]..." \ -variable pbuttons(file,movie) -command {UpdateButtons buttons(file)} $m add separator $m add checkbutton -label "[msgcat::mc {Backup}]..." \ -variable pbuttons(file,backup) -command {UpdateButtons buttons(file)} $m add checkbutton -label "[msgcat::mc {Restore}]..." \ -variable pbuttons(file,restore) -command {UpdateButtons buttons(file)} $m add separator $m add checkbutton -label "[msgcat::mc {Display Header}]..." \ -variable pbuttons(file,header) -command {UpdateButtons buttons(file)} $m add separator $m add cascade -label [msgcat::mc {XPA}] -menu $m.xpa $m add cascade -label [msgcat::mc {SAMP}] -menu $m.samp $m add separator $m add checkbutton -label "[msgcat::mc {Open TCL Console}]..." \ -variable pbuttons(file,console) -command {UpdateButtons buttons(file)} $m add checkbutton -label "[msgcat::mc {Source TCL}]..." \ -variable pbuttons(file,tcl) -command {UpdateButtons buttons(file)} $m add separator switch $ds9(wm) { x11 { $m add checkbutton \ -label "[msgcat::mc {Page Setup}]..." \ -variable pbuttons(file,page) \ -command {UpdateButtons buttons(file)} $m add checkbutton \ -label "[msgcat::mc {Print}]..." \ -variable pbuttons(file,print) \ -command {UpdateButtons buttons(file)} } win32 - aqua { $m add checkbutton \ -label "[msgcat::mc {Postscript Page Setup}]..." \ -variable pbuttons(file,pspage) \ -command {UpdateButtons buttons(file)} $m add checkbutton \ -label "[msgcat::mc {Postscript Print}]..." \ -variable pbuttons(file,psprint) \ -command {UpdateButtons buttons(file)} $m add separator $m add checkbutton \ -label "[msgcat::mc {Page Setup}]..." \ -variable pbuttons(file,page) \ -command {UpdateButtons buttons(file)} $m add checkbutton \ -label "[msgcat::mc {Print}]..." \ -variable pbuttons(file,print) \ -command {UpdateButtons buttons(file)} } } $m add separator $m add checkbutton -label [msgcat::mc {Exit}] \ -variable pbuttons(file,exit) -command {UpdateButtons buttons(filew)} menu $m.xpa $m.xpa add checkbutton -label "[msgcat::mc {Information}]..." \ -variable pbuttons(file,xpa,info) \ -command {UpdateButtons buttons(file)} menu $m.samp $m.samp add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(file,samp,image) \ -command {UpdateButtons buttons(file)} $m.samp add checkbutton -label [msgcat::mc {Table}] \ -variable pbuttons(file,samp,table) \ -command {UpdateButtons buttons(file)} } # Support proc UpdateFileMenuStatic {} { global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateFileMenuStatic" } if {$ds9(active,num) > 0} { $ds9(mb).file entryconfig "[msgcat::mc {Open}]..." \ -state normal $ds9(mb).file entryconfig [msgcat::mc {Open as}] \ -state normal $ds9(mb).file entryconfig [msgcat::mc {Import}] \ -state normal $ds9(buttons).file.open configure -state normal } else { $ds9(mb).file entryconfig "[msgcat::mc {Open}]..." \ -state disabled $ds9(mb).file entryconfig [msgcat::mc {Open as}] \ -state disabled $ds9(mb).file entryconfig [msgcat::mc {Import}] \ -state disabled $ds9(buttons).file.open configure -state disabled } } proc UpdateFileMenu {} { global ds9 global current global samp global xpa global debug if {$debug(tcl,update)} { puts stderr "UpdateFileMenu" } set mm $ds9(mb).file set bb $ds9(buttons).file if {$current(frame) != {}} { if {[$current(frame) has fits]} { $mm entryconfig "[msgcat::mc {Save}]..." -state normal $mm entryconfig [msgcat::mc {Save as}] -state normal $mm entryconfig [msgcat::mc {Export}] -state normal $mm entryconfig [msgcat::mc {Save Image}] -state normal $mm entryconfig "[msgcat::mc {Create Movie}]..." -state normal $mm entryconfig "[msgcat::mc {Display Header}]..." -state normal if {[$current(frame) has fits mosaic]} { $mm.save entryconfig "[msgcat::mc {Mosaic WCS}]..." -state normal $mm.save entryconfig "[msgcat::mc {Mosaic WCS Segment}]..." -state normal } else { $mm.save entryconfig "[msgcat::mc {Mosaic WCS}]..." -state disabled $mm.save entryconfig "[msgcat::mc {Mosaic WCS Segment}]..." -state disabled } $bb.save configure -state normal $bb.movie configure -state normal $bb.header configure -state normal } else { $mm entryconfig "[msgcat::mc {Save}]..." -state disabled $mm entryconfig [msgcat::mc {Save as}] -state disabled $mm entryconfig [msgcat::mc {Export}] -state disabled $mm entryconfig [msgcat::mc {Save Image}] -state disabled $mm entryconfig "[msgcat::mc {Create Movie}]..." -state disabled $mm entryconfig "[msgcat::mc {Display Header}]..." -state disabled $bb.save configure -state disabled $bb.movie configure -state disabled $bb.header configure -state disabled } switch -- [$current(frame) get type] { base { $mm.open entryconfig \ "[msgcat::mc {RGB Image}]..." -state disabled $mm.open entryconfig \ "[msgcat::mc {RGB Cube}]..." -state disabled $mm.save entryconfig \ "[msgcat::mc {RGB Image}]..." -state disabled $mm.save entryconfig \ "[msgcat::mc {RGB Cube}]..." -state disabled $mm.import entryconfig \ "[msgcat::mc {RGB Array}]..." -state disabled $mm.export entryconfig \ "[msgcat::mc {RGB Array}]..." -state disabled } rgb { $mm.open entryconfig \ "[msgcat::mc {RGB Image}]..." -state normal $mm.open entryconfig \ "[msgcat::mc {RGB Cube}]..." -state normal $mm.save entryconfig \ "[msgcat::mc {RGB Image}]..." -state normal $mm.save entryconfig \ "[msgcat::mc {RGB Cube}]..." -state normal $mm.import entryconfig \ "[msgcat::mc {RGB Array}]..." -state normal $mm.export entryconfig \ "[msgcat::mc {RGB Array}]..." -state normal } 3d { $mm.open entryconfig \ "[msgcat::mc {RGB Image}]..." -state disabled $mm.open entryconfig \ "[msgcat::mc {RGB Cube}]..." -state disabled $mm.save entryconfig \ "[msgcat::mc {RGB Image}]..." -state disabled $mm.save entryconfig \ "[msgcat::mc {RGB Cube}]..." -state disabled $mm.import entryconfig \ "[msgcat::mc {RGB Array}]..." -state disabled $mm.export entryconfig \ "[msgcat::mc {RGB Array}]..." -state disabled } } if {[info exists samp]} { set ss [expr $ds9(menu,start)+2] if {[$current(frame) has fits]} { $mm.samp entryconfig [msgcat::mc {Image}] \ -state normal if {[$mm.samp.image index end] >= $ss} { $mm.samp.image delete $ss end } foreach args $samp(apps,image) { foreach {id name} $args { $mm.samp.image add command -label $name \ -command "SAMPSendImageLoadFits $id" } } $bb.sampimage configure -state normal if {[$current(frame) has fits bin]} { $mm.samp entryconfig [msgcat::mc {Table}] -state normal if {[$mm.samp.table index end] >= $ss} { $mm.samp.table delete $ss end } foreach args $samp(apps,table) { foreach {id name} $args { $mm.samp.table add command -label $name \ -command "SAMPSendTableLoadFits $id" } } $bb.samptable configure -state normal } else { $mm.samp entryconfig [msgcat::mc {Table}] -state disabled $bb.samptable configure -state disabled } } else { $mm.samp entryconfig [msgcat::mc {Image}] -state disabled $mm.samp entryconfig [msgcat::mc {Table}] -state disabled $bb.sampimage configure -state disabled $bb.samptable configure -state disabled } } else { $mm.samp entryconfig [msgcat::mc {Image}] -state disabled $mm.samp entryconfig [msgcat::mc {Table}] -state disabled $bb.sampimage configure -state disabled $bb.samptable configure -state disabled } } else { $mm entryconfig "[msgcat::mc {Save}]..." -state disabled $mm entryconfig [msgcat::mc {Save as}] -state disabled $mm entryconfig [msgcat::mc {Export}] -state disabled $mm entryconfig [msgcat::mc {Save Image}] -state disabled $mm entryconfig "[msgcat::mc {Create Movie}]..." -state disabled $mm entryconfig "[msgcat::mc {Display Header}]..." -state disabled $bb.save configure -state disabled $bb.movie configure -state disabled $bb.header configure -state disabled $mm.samp entryconfig [msgcat::mc {Image}] -state disabled $mm.samp entryconfig [msgcat::mc {Table}] -state disabled $bb.sampimage configure -state disabled $bb.samptable configure -state disabled } # XPA if [info exists xpa] { $mm.xpa entryconfig "[msgcat::mc {Information}]..." -state normal $mm.xpa entryconfig [msgcat::mc {Disconnect}] -state normal } else { $mm.xpa entryconfig "[msgcat::mc {Information}]..." -state disabled $mm.xpa entryconfig [msgcat::mc {Disconnect}] -state disabled } # SAMP if {[info exists samp]} { $mm.samp entryconfig [msgcat::mc {Connect}] -state disabled $mm.samp entryconfig [msgcat::mc {Disconnect}] -state normal } else { $mm.samp entryconfig [msgcat::mc {Connect}] -state normal $mm.samp entryconfig [msgcat::mc {Disconnect}] -state disabled } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mask.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000016177�12123112767�013347� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MaskDef {} { global mask global imask global pmask set imask(top) .msk set imask(mb) .mskmb set mask(color) red set mask(mark) 1 set mask(transparency) 0 array set pmask [array get mask] } proc MaskTransparency {} { global mask global current if {$current(frame) != {}} { $current(frame) mask transparency $mask(transparency) } } proc MaskClear {} { global current if {$current(frame) != {}} { $current(frame) mask clear } } proc MaskDialog {} { global mask global imask global current global ds9 # see if we already have a ctr window visible if [winfo exists $imask(top)] { raise $imask(top) return } # create the mask window set w $imask(top) set mb $imask(mb) Toplevel $w $mb 6 [msgcat::mc {Mask Parameters}] MaskDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label "[msgcat::mc {Open}]..." \ -command [list OpenDialog fits mask] $mb.file add cascade -label [msgcat::mc {Open as}] \ -menu $mb.file.open $mb.file add separator $mb.file add cascade -label [msgcat::mc {Import}] \ -menu $mb.file.import $mb.file add separator $mb.file add command -label [msgcat::mc {Apply}] -command MaskApplyDialog $mb.file add command -label [msgcat::mc {Clear}] -command MaskClear $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command MaskDestroyDialog menu $mb.file.open $mb.file.open add command \ -label "[msgcat::mc {Mosaic WCS}]..." \ -command [list OpenDialog mosaicimagewcs mask] $mb.file.open add command \ -label "[msgcat::mc {Mosaic WCS Segment}]..." \ -command [list OpenDialog mosaicwcs mask] $mb.file.open add command \ -label "[msgcat::mc {Mosaic IRAF}]..." \ -command [list OpenDialog mosaicimageiraf mask] $mb.file.open add command \ -label "[msgcat::mc {Mosaic IRAF Segment}]..." \ -command [list OpenDialog mosaiciraf mask] menu $mb.file.import $mb.file.import add command \ -label "[msgcat::mc {Array}]..." \ -command [list ImportDialog array mask] $mb.file.import add command \ -label "[msgcat::mc {NRRD}]..." \ -command [list ImportDialog nrrd mask] EditMenu $mb imask # Param set f [ttk::frame $w.param] slider $f.slider 0. 100. [msgcat::mc {Transparency}] \ mask(transparency) [list MaskTransparency] grid $f.slider -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command MaskApplyDialog ttk::button $f.clear -text [msgcat::mc {Clear}] -command MaskClear ttk::button $f.close -text [msgcat::mc {Close}] -command MaskDestroyDialog pack $f.apply $f.clear $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true } proc MaskApplyDialog {} { global mask MaskTransparency } proc MaskDestroyDialog {} { global imask if {[winfo exists $imask(top)]} { destroy $imask(top) destroy $imask(mb) } } proc UpdateMaskMenu {} { global mask global current global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateMaskMenu" } if {$current(frame) == {}} { return } set mask(color) [$current(frame) get mask color] set mask(mark) [$current(frame) get mask mark] set mask(transparency) [$current(frame) get mask transparency] switch -- [$current(frame) get type] { base { switch -- $ds9(visual) { pseudocolor { $ds9(mb).analysis entryconfig \ "[msgcat::mc {Mask Parameters}]..." -state disabled } truecolor { $ds9(mb).analysis entryconfig \ "[msgcat::mc {Mask Parameters}]..." -state normal } } } 3d - rgb { $ds9(mb).analysis entryconfig \ "[msgcat::mc {Mask Parameters}]..." -state disabled } } } proc MaskLoad {} { global current global mask set rr [MaskParamsDialog] if {$current(frame) != {}} { if {$rr} { $current(frame) mask color $mask(color) $current(frame) mask mark $mask(mark) } } return $rr } proc MaskParamsDialog {} { global mask global ed set w {.mskd} set ed(ok) 0 set ed(color) $mask(color) set ed(mark) $mask(mark) DialogCreate $w [msgcat::mc {Mask Parameters}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.colortitle -text [msgcat::mc {Color}] ColorMenuButton $f.colorbutton ed color {} ttk::label $f.marktitle -text [msgcat::mc {Block}] ttk::radiobutton $f.markz -text [msgcat::mc {Zero}] \ -variable ed(mark) -value 0 ttk::radiobutton $f.marknz -text [msgcat::mc {Non-zero}] \ -variable ed(mark) -value 1 ttk::label $f.marktitle2 -text [msgcat::mc {Value}] grid $f.colortitle $f.colorbutton - -padx 2 -pady 2 -sticky w grid $f.marktitle $f.markz $f.marknz $f.marktitle2 -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set mask(color) [string tolower $ed(color)] set mask(mark) $ed(mark) } set rr $ed(ok) unset ed return $rr } proc MaskBackup {ch which} { puts $ch "$which mask color [$which get mask color]" puts $ch "$which mask mark [$which get mask mark]" puts $ch "$which mask transparency [$which get mask transparency]" } proc ProcessMaskCmd {varname iname} { upvar $varname var upvar $iname i global mask global current set rr {} switch -- [string tolower [lindex $var $i]] { open {MaskDialog} close {MaskDestroyDialog} color { incr i set mask(color) [lindex $var $i] if {$current(frame) != {}} { $current(frame) mask color $mask(color) } } mark { incr i set mask(mark) [lindex $var $i] if {$current(frame) != {}} { $current(frame) mask mark $mask(mark) } } transparency { incr i set mask(transparency) [lindex $var $i] if {$current(frame) != {}} { $current(frame) mask transparency $mask(transparency) } MaskTransparency } clear { MaskClear } default { set rr mask incr i -1 } } return $rr } proc ProcessSendMaskCmd {proc id param} { global mask switch -- [string tolower $param] { color {$proc $id "$mask(color)\n"} mark {$proc $id "$mask(mark)\n"} transparency {$proc $id "$mask(transparency)\n"} } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/marker.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000126362�12131573630�013672� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerDef {} { global marker global imarker global pmarker set imarker(id) -1 set imarker(x) -1 set imarker(y) -1 set imarker(motion) none set imarker(handle) -1 set marker(show) 1 set marker(show,text) 1 set marker(centroid,auto) 0 set marker(centroid,iteration) 30 set marker(centroid,radius) 10 set marker(shape) circle set marker(color) green set marker(dashlist) {8 3} set marker(width) 1 set marker(dash) 0 set marker(fixed) 0 set marker(edit) 1 set marker(move) 1 set marker(rotate) 1 set marker(delete) 1 set marker(include) 1 set marker(source) 1 set marker(font) helvetica set marker(font,size) 10 set marker(font,weight) normal set marker(font,slant) roman set marker(preserve) 0 set marker(plot2d) 0 set marker(plot3d) 1 set marker(copy) {} set marker(copy,system) {} set marker(maxdialog) 48 set marker(load) current set marker(format) ds9 # these are only used for save/load/list and are set from current wcs values set marker(system) physical set marker(sky) fk5 set marker(skyformat) degrees set marker(strip) 0 array set pmarker [array get marker] unset pmarker(copy) unset pmarker(copy,system) unset pmarker(maxdialog) unset pmarker(load) unset pmarker(system) unset pmarker(sky) unset pmarker(skyformat) unset pmarker(strip) set pmarker(dformat) degrees set pmarker(circle,radius) 20 set pmarker(annulus,inner) 15 set pmarker(annulus,outer) 30 set pmarker(annulus,annuli) 1 set pmarker(panda,inner) 15 set pmarker(panda,outer) 30 set pmarker(panda,annuli) 1 set pmarker(panda,ang1) 0 set pmarker(panda,ang2) 360 set pmarker(panda,angnum) 4 set pmarker(ellipse,radius1) 40 set pmarker(ellipse,radius2) 20 set pmarker(ellipseannulus,radius1) 40 set pmarker(ellipseannulus,radius2) 20 set pmarker(ellipseannulus,radius3) 60 set pmarker(ellipseannulus,annuli) 1 set pmarker(epanda,radius1) 40 set pmarker(epanda,radius2) 20 set pmarker(epanda,radius3) 60 set pmarker(epanda,annuli) 1 set pmarker(epanda,ang1) 0 set pmarker(epanda,ang2) 360 set pmarker(epanda,angnum) 4 set pmarker(box,radius1) 80 set pmarker(box,radius2) 40 set pmarker(boxannulus,radius1) 80 set pmarker(boxannulus,radius2) 40 set pmarker(boxannulus,radius3) 120 set pmarker(boxannulus,annuli) 1 set pmarker(bpanda,radius1) 80 set pmarker(bpanda,radius2) 40 set pmarker(bpanda,radius3) 120 set pmarker(bpanda,annuli) 1 set pmarker(bpanda,ang1) 0 set pmarker(bpanda,ang2) 360 set pmarker(bpanda,angnum) 4 set pmarker(polygon,width) 20 set pmarker(polygon,height) 20 set pmarker(projection,thick) 0 set pmarker(compass,radius) 40 set pmarker(point,size) 11 } # procs shared between pointer and catalog mode proc MarkerControl {which x y} { global imarker global current # if nothing is loaded, abort if {![$which has fits]} { return } # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set id [$which get marker $current(mode) id $x $y] if {$id} { # are we on a selected annulus? if {[$which get marker $current(mode) select $x $y] == $id} { switch -- [$which get marker $current(mode) $id type] { annulus { set imarker(handle) \ [$which marker $current(mode) $id create annulus radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } panda { set imarker(handle) \ [$which marker $current(mode) $id create panda radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } ellipseannulus { set imarker(handle) \ [$which marker $current(mode) $id create ellipseannulus radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } epanda { set imarker(handle) \ [$which marker $current(mode) $id create epanda radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } boxannulus { set imarker(handle) \ [$which marker $current(mode) $id create boxannulus radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } bpanda { set imarker(handle) \ [$which marker $current(mode) $id create bpanda radius $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } } } } } proc MarkerControlShift {which x y} { global imarker global current # if nothing is loaded, abort if {![$which has fits]} { return } # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set id [$which get marker $current(mode) id $x $y] if {$id} { # are we on a selected annulus? if {[$which get marker $current(mode) select $x $y] == $id} { switch -- [$which get marker $current(mode) $id type] { panda { set imarker(handle) \ [$which marker $current(mode) $id create panda angle $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } epanda { set imarker(handle) \ [$which marker $current(mode) $id create epanda angle $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } bpanda { set imarker(handle) \ [$which marker $current(mode) $id create bpanda angle $x $y] $which marker $current(mode) $id edit begin $imarker(handle) set imarker(motion) edit } } } } } proc MarkerCursor {which x y handleCursor overCursor} { global current # if nothing is loaded, abort if {![$which has fits]} { return } # are we over any selected marker handles? # remember, handles are outside of a marker set h [$which get marker $current(mode) handle $x $y] set id [lindex $h 0] set handle [lindex $h 1] if {$handle} { if {$handle < 5} { # edit/rotate handle SetCursor $handleCursor } else { # polygon/annulus vertex SetCursor dotbox } return } # else, see if we are on a segement of a polygon set h [$which get marker $current(mode) polygon segment $x $y] if {[lindex $h 0]} { SetCursor draped_box return } # are we over a marker? set id [$which get marker $current(mode) select $x $y] if {$id} { # are we on a selected annulus and control key down? switch -- [$which get marker $current(mode) $id type] { annulus - panda - ellipseannulus - epanda - boxannulus - bpanda {SetCursor $overCursor} default {SetCursor fleur} } return } # else, set no cursor SetCursor {} } proc MarkerArrowKey {which x y} { global current $which warp $x $y $which marker $current(mode) move $x $y } # Marker only proc MarkerButton {which x y} { global marker global imarker global itemplate global ds9 # if nothing is loaded, abort if {![$which has fits]} { return } # see if we are on a handle set h [$which get marker handle $x $y] set id [lindex $h 0] set imarker(handle) [lindex $h 1] if {$imarker(handle)} { $which marker $id edit begin $imarker(handle) set imarker(motion) beginEdit return } # else, see if we are on a segment of a polygon set h [$which get marker polygon segment $x $y] set id [lindex $h 0] set segment [lindex $h 1] if {$segment} { $which marker $id create polygon vertex $segment $x $y $which marker $id edit begin $imarker(handle) set imarker(handle) [expr 4+$segment+1] set imarker(motion) beginEdit return } # else, see if we are on a marker if {[$which get marker id $x $y]} { $which marker select only $x $y $which marker move begin $x $y set imarker(motion) beginMove UpdateRegionMenu return } # see if any markers are selected if {[$which get marker select number]>0} { $which marker unselect all set imarker(motion) none UpdateRegionMenu return } # else, create a marker set imarker(handle) 0 set imarker(motion) none switch -- $marker(shape) { circle - annulus - panda - ellipse - ellipseannulus - epanda - box - boxannulus - bpanda - polygon - line - vector - text - ruler - compass - projection - {circle point} - {box point} - {diamond point} - {cross point} - {x point} - {arrow point} - {boxcircle point} {MarkerCreateShape $which $x $y} default { set fn "$ds9(root)/template/$itemplate($marker(shape))" set ch [open $fn r] global vardata set vardata [read $ch] close $ch $which marker create template var vardata $x $y } } } proc MarkerShift {which x y} { global imarker # if nothing is loaded, abort if {![$which has fits]} { return } # see if we are on a handle set h [$which get marker handle $x $y] set id [lindex $h 0] set imarker(handle) [lindex $h 1] if {$imarker(handle)} { $which marker $id rotate begin set imarker(motion) beginRotate return } # else, see if we are on a marker if {[$which marker select toggle $x $y]} { UpdateRegionMenu $which marker move begin $x $y set imarker(motion) beginMove return } # else, start a region select $which region select begin $x $y set imarker(motion) shiftregion } proc MarkerMotion {which x y} { global imarker # if nothing is loaded, abort if {![$which has fits]} { return } switch -- $imarker(motion) { none {} beginCreate - create { $which marker edit motion $x $y $imarker(handle) set imarker(motion) create } beginMove - move { $which marker move motion $x $y set imarker(motion) move } beginEdit - edit { $which marker edit motion $x $y $imarker(handle) set imarker(motion) edit } beginRotate - rotate { $which marker rotate motion $x $y $imarker(handle) set imarker(motion) rotate } region - shiftregion {$which region select motion $x $y} } } proc MarkerRelease {which x y} { global marker global imarker global current # if nothing is loaded, abort if {![$which has fits]} { return } switch -- $imarker(motion) { none {} beginCreate { # the user has just clicked, so resize to make visible or delete # assumes imarker(id) from create $which marker edit end MarkerDefault $which if {$imarker(id)>=0} { if {$marker(centroid,auto)} { $which marker centroid $imarker(id) } MarkerReleaseCB $which } set imarker(id) -1 set imarker(x) -1 set imarker(y) -1 } create { $which marker edit end # determine if this is an accident and just create the default set diffx [expr $x-$imarker(x)] set diffy [expr $y-$imarker(y)] if {[expr sqrt($diffx*$diffx + $diffy*$diffy)]<2} { MarkerDefault $which } if {$imarker(id)>=0} { if {$marker(centroid,auto)} { $which marker centroid $imarker(id) } MarkerReleaseCB $which } set imarker(id) -1 set imarker(x) -1 set imarker(y) -1 } beginMove - beginRotate {} beginEdit {} move { $which marker move end if {$marker(centroid,auto)} { $which marker centroid } } edit { $which marker edit end if {$marker(centroid,auto)} { $which marker centroid } } rotate { $which marker rotate end if {$marker(centroid,auto)} { $which marker centroid } } region {$which region select end} shiftregion {$which region select shift end} } set imarker(motion) none set imarker(handle) -1 } proc MarkerReleaseCB {which} { global marker global imarker global current # special callbacks switch [$which get marker $imarker(id) type] { projection {MarkerAnalysisPlot2d $which $imarker(id) 1} line - vector { if {$marker(plot2d)} { MarkerAnalysisPlot2d $which $imarker(id) 1 } } circle - ellipse - box - polygon - point { if {$marker(plot3d) && [$current(frame) has fits cube]} { MarkerAnalysisPlot3d $which $imarker(id) 1 } } } } proc MarkerDouble {which x y} { global imarker # if nothing is loaded, abort if {![$which has fits]} { return } set id [$which get marker id $x $y] if {$id} { if {[$which get marker $id PROPERTY SELECT]} { MarkerDialog $which $id switch [$which get marker $id type] { projection - line - vector - circle - ellipse - box - polygon - point { set vvarname proj${id}${which} upvar #0 $vvarname vvar global $vvarname PlotRaise $vvarname } } } } } proc MarkerCreateShape {which x y} { global marker global imarker global pmarker global current global wcs # for compass/ruler global ed set ed(system) $wcs(system) set ed(sky) $wcs(sky) set ed(format) degrees AdjustCoordSystem ed system set cmd "$which marker create $marker(shape) $x $y" switch -- $marker(shape) { circle {append cmd " 0"} annulus {append cmd " .001 .002 $pmarker(annulus,annuli)"} panda {append cmd " $pmarker(panda,ang1) $pmarker(panda,ang2) $pmarker(panda,angnum) .001 .002 $pmarker(panda,annuli)"} ellipse {append cmd " 0 0"} ellipseannulus {append cmd " .001 .001 .002 $pmarker(ellipseannulus,annuli)"} epanda {append cmd " $pmarker(epanda,ang1) $pmarker(epanda,ang2) $pmarker(epanda,angnum) .001 .001 .002 $pmarker(epanda,annuli)"} box {append cmd " 0 0"} boxannulus {append cmd " .002 .002 .004 $pmarker(boxannulus,annuli)"} bpanda {append cmd " $pmarker(bpanda,ang1) $pmarker(bpanda,ang2) $pmarker(bpanda,angnum) .001 .001 .002 $pmarker(bpanda,annuli)"} polygon {append cmd " .001 .001"} line {append cmd " $x $y"} vector {append cmd " $x $y"} text { set txt "Region" set r [EntryDialog "Text Region" "Enter Text:" 40 txt] if {$r == 1 && $txt != {}} { append cmd " 0 text = \{\{$txt\}\}" } else { return } } ruler {append cmd " $x $y $ed(system) $ed(sky) $ed(system) $ed(format)"} compass {append cmd " 15 $ed(system) $ed(sky) "} projection {append cmd " $x $y $pmarker(projection,thick) "} {circle point} - {box point} - {diamond point} - {cross point} - {x point} - {arrow point} - {boxcircle point} {append cmd " $pmarker(point,size)"} } append cmd " color = $marker(color)" append cmd " width = $marker(width)" append cmd " font = \{\"$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\"\}" append cmd " dash = $marker(dash)" append cmd " fixed = $marker(fixed)" append cmd " edit = $marker(edit)" append cmd " move = $marker(move)" append cmd " rotate = $marker(rotate)" append cmd " delete = $marker(delete)" append cmd " include = $marker(include)" append cmd " source = $marker(source)" $which marker unselect all set imarker(id) [eval $cmd] set imarker(motion) beginCreate set imarker(x) $x set imarker(y) $y switch -- $marker(shape) { circle - annulus - panda - ellipse - ellipseannulus - epanda - box - boxannulus - bpanda - compass - polygon { set imarker(handle) 1 $which marker $imarker(id) edit begin $imarker(handle) } line - vector - ruler - projection { set imarker(handle) 2 $which marker $imarker(id) edit begin $imarker(handle) } } } proc MarkerDefault {which} { global imarker global pmarker global current # scale the default size to take into account the current set z1 double([lindex $current(zoom) 0]) set z2 double([lindex $current(zoom) 1]) if {$z1>$z2} { set zz $z1 } else { set zz $z2 } set item [$which get marker $imarker(id) type] switch -- $item { circle { $which marker $imarker(id) circle radius \ [expr ($pmarker(circle,radius)/$zz)] \ image degrees } annulus { $which marker $imarker(id) annulus radius \ [expr ($pmarker(annulus,inner)/$zz)] \ [expr ($pmarker(annulus,outer)/$zz)] \ $pmarker(annulus,annuli) image degrees } panda { $which marker $imarker(id) panda edit \ $pmarker(panda,ang1) $pmarker(panda,ang2) \ $pmarker(panda,angnum) \ [expr ($pmarker(panda,inner)/$zz)] \ [expr ($pmarker(panda,outer)/$zz)] \ $pmarker(panda,annuli) image } ellipse { $which marker $imarker(id) ellipse radius \ [expr ($pmarker(ellipse,radius1)/$z1)] \ [expr ($pmarker(ellipse,radius2)/$z2)] \ image degrees } ellipseannulus { $which marker $imarker(id) ellipseannulus radius \ [expr ($pmarker(ellipseannulus,radius1)/$z1)] \ [expr ($pmarker(ellipseannulus,radius2)/$z2)] \ [expr ($pmarker(ellipseannulus,radius3)/$z1)] \ $pmarker(ellipseannulus,annuli) image } epanda { $which marker $imarker(id) epanda edit \ $pmarker(epanda,ang1) $pmarker(epanda,ang2) \ $pmarker(epanda,angnum) \ [expr ($pmarker(epanda,radius1)/$z1)] \ [expr ($pmarker(epanda,radius2)/$z2)] \ [expr ($pmarker(epanda,radius3)/$z1)] \ $pmarker(epanda,annuli) image } box { $which marker $imarker(id) box radius \ [expr ($pmarker(box,radius1)/$z1)] \ [expr ($pmarker(box,radius2)/$z2)] \ image degrees } boxannulus { $which marker $imarker(id) boxannulus radius \ [expr ($pmarker(boxannulus,radius1)/$z1)] \ [expr ($pmarker(boxannulus,radius2)/$z2)] \ [expr ($pmarker(boxannulus,radius3)/$z1)] \ $pmarker(boxannulus,annuli) image } bpanda { $which marker $imarker(id) bpanda edit \ $pmarker(bpanda,ang1) $pmarker(bpanda,ang2) \ $pmarker(bpanda,angnum) \ [expr ($pmarker(bpanda,radius1)/$z1)] \ [expr ($pmarker(bpanda,radius2)/$z2)] \ [expr ($pmarker(bpanda,radius3)/$z1)] \ $pmarker(bpanda,annuli) image } compass { $which marker $imarker(id) compass radius \ $pmarker(compass,radius) image degrees } polygon { $which marker $imarker(id) polygon reset \ [expr ($pmarker(polygon,width)/$z1)] \ [expr ($pmarker(polygon,height)/$z2)] \ image degrees } line - vector - ruler - projection { $which marker $imarker(id) delete set imarker(id) -1 set imarker(x) -1 set imarker(y) -1 } } } proc MarkerDeleteKey {which x y} { # if nothing is loaded, abort if {![$which has fits]} { return } # see if we are on a polygon set h [$which get marker handle $x $y] set id [lindex $h 0] set handle [lindex $h 1] set t [$which get marker $id type] switch -- $t { polygon - annulus - panda - ellipseannulus - epanda - boxannulus - bpanda { if {$handle > 4} { switch -- $t { polygon {$which marker $id delete polygon vertex $handle} annulus {$which marker $id delete annulus $handle} panda {$which marker $id delete panda $handle} ellipseannulus {$which marker $id delete \ ellipseannulus $handle} epanda {$which marker $id delete epanda $handle} boxannulus {$which marker $id delete boxannulus $handle} bpanda {$which marker $id delete bpanda $handle} } } else { # delete polygon $which marker delete UpdateGroupDialog } } default { # delete marker $which marker delete UpdateGroupDialog } } } proc MarkerShow {} { global current global marker if {$current(frame) != {}} { $current(frame) marker show $marker(show) } } proc MarkerShowText {} { global current global marker if {$current(frame) != {}} { $current(frame) marker show text $marker(show,text) } } proc MarkerPreserve {} { global current global marker if {$current(frame) != {}} { $current(frame) marker preserve $marker(preserve) } } proc MarkerCentroid {} { global current if {$current(frame) != {}} { $current(frame) marker centroid } } proc MarkerCentroidAuto {} { global current global marker if {$current(frame) != {}} { $current(frame) marker centroid auto $marker(centroid,auto) } } proc MarkerCentroidRadius {} { global current global marker if {$current(frame) != {}} { $current(frame) marker centroid radius $marker(centroid,radius) } } proc MarkerCentroidIteration {} { global current global marker if {$current(frame) != {}} { $current(frame) marker centroid iteration $marker(centroid,iteration) } } proc MarkerFront {} { global current if {$current(frame) != {}} { $current(frame) marker move front } } proc MarkerBack {} { global current if {$current(frame) != {}} { $current(frame) marker move back $current(frame) marker unselect all } } proc MarkerSelectAll {} { global current if {$current(frame) != {}} { $current(frame) marker select all } UpdateEditMenu } proc MarkerUnselectAll {} { global current if {$current(frame) != {}} { $current(frame) marker unselect all } UpdateEditMenu } proc MarkerSelectInvert {} { global current if {$current(frame) != {}} { $current(frame) marker select toggle } UpdateEditMenu } proc MarkerDeleteSelect {} { global current if {$current(frame) != {}} { $current(frame) marker delete UpdateGroupDialog } UpdateEditMenu } proc MarkerDeleteAllMenu {} { global current global pds9 if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message [msgcat::mc {Delete All Regions?}]] != {ok}} { return } } MarkerDeleteAll } proc MarkerDeleteAll {} { global current if {$current(frame) != {}} { $current(frame) marker delete all UpdateGroupDialog } UpdateEditMenu } proc MarkerColor {} { global current global marker if {$current(frame) != {}} { $current(frame) marker color $marker(color) } } proc MarkerWidth {} { global current global marker if {$current(frame) != {}} { $current(frame) marker width $marker(width) } } proc MarkerProp {prop} { global current global marker if {$current(frame) != {}} { $current(frame) marker property $prop $marker($prop) } } proc MarkerFont {} { global current global marker if {$current(frame) != {}} { $current(frame) marker font \"$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\" } } proc MarkerList {} { global current global marker if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } if [MarkerSaveDialog [msgcat::mc {List Regions}]] { SimpleTextDialog markertxt [msgcat::mc {Region}] 80 20 insert top \ [$current(frame) marker list $marker(format) $marker(system) \ $marker(sky) $marker(skyformat) $marker(strip)] } } proc MarkerLoad {} { global ds9 global current global marker if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } set fns [OpenFileDialog markerfbox] if {$fns != {}} { if [MarkerLoadDialog] { switch -- $marker(load) { current {set frames $current(frame)} all {set frames $ds9(frames)} } MarkerLoadFrames $fns $frames \ $marker(format) $marker(system) $marker(sky) } } } proc MarkerLoadFrames {str frames format sys sky} { if {$str == {}} { return } if {[catch {glob $str} fns]} { # reset errors, we don't want to hear about it InitError tcl # could be an unique name, i.e. foo[bar], just try to load foreach fr $frames { if {[catch {MarkerLoadFile $str $fr $format $sys $sky}]} { return } } } else { foreach fn $fns { foreach fr $frames { if {[catch {MarkerLoadFile $fn $fr $format $sys $sky}]} { return } } } } } proc MarkerLoadFile {filename which format sys sky} { global current global marker if {$filename == {}} { return } if {![$which has fits]} { return } # determine if its a fits file # first, strip the filename if {![regexp -nocase {(.*)(\[.*\])} $filename foo base ext]} { set base $filename set ext {} } if {[catch {open $base} fd]} { Error [msgcat::mc {Unable to load region file}] return -code error } set ll [read $fd 9] close $fd # is it a fits file? if {$ll == "SIMPLE ="} { # see if we need to add an extension if {$ext == {}} { set filename "$base\[REGION\]" } # open it if [catch {$which marker load fits "\{$filename\}" $marker(color) $marker(dashlist) $marker(width) "\{$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\}"}] { if {$ext == {}} { # ok now try the first extension set filename "$base\[1\]" if [catch {$which marker load fits "\{$filename\}" $marker(color) $marker(dashlist) $marker(width) "\{$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\}"}] { Error [msgcat::mc {Unable to load region file}] return -code error } # reset errors, we don't want to hear about it InitError tcl } else { Error [msgcat::mc {Unable to load region file}] return -code error } } } else { # no, its ascii if [catch {$which marker load $format "\{$filename\}" $sys $sky}] { Error [msgcat::mc {Unable to load region file}] return -code error } } UpdateGroupDialog } proc MarkerSave {} { global current global marker if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } set filename [SaveFileDialog markerfbox] if {$filename == {}} { return } if [MarkerSaveDialog [msgcat::mc {Save Regions}]] { $current(frame) marker save "\{$filename\}" \ $marker(format) $marker(system) $marker(sky) \ $marker(skyformat) $marker(strip) } } proc MarkerInfo {} { global current global marker global pds9 if {$current(frame) != {}} { set ll [$current(frame) get marker select] if {$ll != {}} { set ii 0 foreach dd $ll { incr ii if {$ii > $marker(maxdialog)} { return } MarkerDialog $current(frame) $dd } } else { if {$pds9(confirm)} { tk_messageBox -type ok -icon info -message [msgcat::mc {Please Select a Region}] } } } } proc MarkerDialog {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set var(frame) $frame set var(id) $id set var(top) ".${varname}" set var(mb) ".${varname}mb" switch -- [$frame get marker $id type] { circle {CircleDialog $varname} annulus {AnnulusDialog $varname} panda {PandaDialog $varname} ellipse {EllipseDialog $varname} ellipseannulus {EllipseAnnulusDialog $varname} epanda {EpandaDialog $varname} box {BoxDialog $varname} boxannulus {BoxAnnulusDialog $varname} bpanda {BpandaDialog $varname} polygon {PolygonDialog $varname} line {LineDialog $varname} vector {VectorDialog $varname} text {TextDialog $varname} ruler {RulerDialog $varname} compass {CompassDialog $varname} projection {ProjectionDialog $varname} point {PointDialog $varname} composite {CompositeDialog $varname} } } proc MarkerCopy {} { global current global marker global wcs if {$current(frame) != {}} { $current(frame) marker copy set marker(copy) $current(frame) set marker(copy,system) $wcs(system) } UpdateEditMenu } proc MarkerCut {} { global current global marker global wcs if {$current(frame) != {}} { $current(frame) marker cut set marker(copy) $current(frame) set marker(copy,system) $wcs(system) } UpdateEditMenu UpdateGroupDialog } proc MarkerUndo {} { global current if {$current(frame) != {}} { $current(frame) marker undo } UpdateEditMenu UpdateGroupDialog } proc MarkerPaste {} { global current global marker global wcs # if nothing is loaded, abort if {$current(frame) == {}} { return } if {$marker(copy) == {} || $marker(copy,system) == {}} { return } if {(![$current(frame) has fits]) || (![$marker(copy) has fits])} { return } # same frame? if {$current(frame) == $marker(copy)} { # use internal $current(frame) marker paste } else { global cmd # do we have a valid wcs? if {[$marker(copy) has wcs $marker(copy,system)] && [$current(frame) has wcs $wcs(system)]} { # do we have an equatorial wcs? if {[$marker(copy) has wcs equatorial $marker(copy,system)] && [$current(frame) has wcs equatorial $wcs(system)]} { # then use wcs set cmd "[$marker(copy) marker paste $marker(copy,system) $wcs(system)]" } else { # mix of equatorial and non-equatorial wcs, use physical set cmd "[$marker(copy) marker paste physical physical]" } } else { # default, use physical set cmd "[$marker(copy) marker paste physical physical]" } $current(frame) marker command ds9 var cmd unset cmd } UpdateEditMenu UpdateGroupDialog } proc CompositeCreate {} { global current global marker if {$current(frame) != {}} { set cmd "$current(frame) marker create composite" append cmd " color = $marker(color)" append cmd " width = $marker(width)" append cmd " font = \{\"$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\"\}" append cmd " dash = $marker(dash)" append cmd " edit = $marker(edit)" append cmd " move = $marker(move)" append cmd " rotate = $marker(rotate)" append cmd " delete = $marker(delete)" append cmd " fixed = $marker(fixed)" append cmd " include = $marker(include)" append cmd " source = $marker(source)" eval $cmd } } proc CompositeDelete {} { global current if {$current(frame) != {}} { $current(frame) marker composite delete } } proc MarkerBackup {ch which fdir rdir} { if {[$which get marker number] > 0} { set fn $fdir/ds9.reg set rfn $rdir/ds9.reg catch {file delete -force $fn} if [$which has wcs equatorial wcs] { $which marker save \"$fn\" ds9 wcs fk5 degrees 0 } else { $which marker save \"$fn\" ds9 physical fk5 degrees 0 } puts $ch "$which marker load ds9 \{\"$rfn\"\}" } } # Process Cmds proc ProcessRegionsCmd {varname iname sock fn} { upvar $varname var upvar $iname i global ds9 global current global marker # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { show { incr i set marker(show) [FromYesNo [lindex $var $i]] MarkerShow } showtext { incr i set marker(show,text) [FromYesNo [lindex $var $i]] MarkerShowText } getinfo {MarkerInfo} centroid { incr i switch -- [string tolower [lindex $var $i]] { auto { incr i set marker(centroid,auto) [FromYesNo [lindex $var $i]] MarkerCentroidAuto } radius { incr i set marker(centroid,radius) [lindex $var $i] MarkerCentroidRadius } iteration { incr i set marker(centroid,iteration) [lindex $var $i] MarkerCentroidIteration } default { incr i -1 MarkerCentroid } } } autocentroid { # backward compatibilty incr i set marker(centroid,auto) [FromYesNo [lindex $var $i]] MarkerCentroidAuto } movefront {MarkerFront} moveback {MarkerBack} move { incr i switch -- [string tolower [lindex $var $i]] { front {MarkerFront} back {MarkerBack} } } selectall {MarkerSelectAll} selectnone {MarkerUnselectAll} select { incr i switch -- [string tolower [lindex $var $i]] { group { # backward compatibility, use group <> select incr i if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker "\{[lindex $var $i]\}" select } } } all {MarkerSelectAll} none {MarkerUnselectAll} invert {MarkerSelectInvert} } } deleteall {MarkerDeleteAll} delete { incr i switch -- [string tolower [lindex $var $i]] { select {MarkerDeleteSelect} all {MarkerDeleteAll} } } format { incr i set marker(format) [string tolower [lindex $var $i]] } coord - system { # for backward compatibility incr i switch -- [string tolower [lindex $var $i]] { fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic { incr i set marker(system) wcs set marker(sky) [string tolower [lindex $var $i]] } default {set marker(system) [string tolower [lindex $var $i]]} } } sky { incr i set marker(sky) [string tolower [lindex $var $i]] } coordformat - skyformat { incr i switch -- [string tolower [lindex $var $i]] { deg - degree - degrees {set marker(skyformat) degrees} default { set marker(skyformat) [string tolower [lindex $var $i]] } } } strip { incr i set marker(strip) [FromYesNo [lindex $var $i]] } delim { incr i if {[lindex $var $i] != "nl"} { set marker(strip) 1 } else { set marker(strip) 0 } } shape { incr i set marker(shape) [string tolower [lindex $var $i]] } color { incr i set marker(color) [string tolower [lindex $var $i]] MarkerColor } width { incr i set marker(width) [lindex $var $i] MarkerWidth } fixed { incr i set marker(fixed) [FromYesNo [lindex $var $i]] MarkerProp fixed } edit { incr i set marker(edit) [FromYesNo [lindex $var $i]] MarkerProp edit } rotate { incr i set marker(rotate) [FromYesNo [lindex $var $i]] MarkerProp rotate } delete { incr i set marker(delete) [FromYesNo [lindex $var $i]] MarkerProp delete } include { set marker(include) 1 MarkerProp include } exclude { set marker(include) 0 MarkerProp include } source { set marker(source) 1 MarkerProp source } background { set marker(source) 0 MarkerProp source } tag - tags - group - groups { incr i if {[string tolower [lindex $var $i]] == {new}} { if {$current(frame) != {}} { if {[$current(frame) has fits]} { set name [$current(frame) get marker tag default name] $current(frame) marker tag "\{$name\}" UpdateGroupDialog } } } else { set tag "\{[lindex $var $i]\}" incr i switch -- [string tolower [lindex $var $i]] { new { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker tag $tag UpdateGroupDialog } } } update { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker tag update $tag UpdateGroupDialog } } } delete { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag delete UpdateGroupDialog } } } select { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag select } } } color { incr i if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag color \ [string tolower [lindex $var $i]] } } } copy { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag copy } } } cut { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag cut } } } font { incr i if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag font \ "\{[lindex $var $i]\}" } } } move { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag move \ [lindex $var [expr $i+1]] \ [lindex $var [expr $i+2]] } } incr i 2 } movefront { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag move front } } } moveback { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag move back } } } property { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker $tag property \ [lindex $var [expr $i+1]] \ [lindex $var [expr $i+2]] } } incr i 2 } } } } copy {MarkerCopy} cut {MarkerCut} paste { set marker(paste,system) [string tolower [lindex $var [expr $i+1]]] switch -- $marker(paste,system) { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {} default {set marker(paste,system) wcs} } # backward compatibility if {[string range [lindex $var [expr $i+2]] 0 0] == {-}} { incr i 1 } else { incr i 2 } MarkerPaste } undo {MarkerUndo} composite {CompositeCreate} desolve - dissove {CompositeDelete} template { incr i set ff [lindex $var $i] incr i switch -- [string tolower [lindex $var $i]] { at { incr i set ra [lindex $var $i] incr i set dec [lindex $var $i] incr i set sys [string tolower [lindex $var $i]] incr i set sky [string tolower [lindex $var $i]] switch -- $sys { fk4 - fk5 - icrs - galatic - ecliptic { set sky $sys set sys wcs incr i -1 } } LoadTemplateMarkerAt $ff $ra $dec $sys $sky FileLast templatefbox $ff } default { LoadTemplateMarker $ff FileLast templatefbox $ff incr i -1 } } } savetemplate { incr i set ff [lindex $var $i] if {$ff != {}} { if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker save template "\{$ff\}" } } FileLast templatefbox $ff } } command { incr i if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker command $marker(format) \ "\{[lindex $var $i]\}" } } UpdateGroupDialog } list { incr i switch -- [string tolower [lindex $var $i]] { close {SimpleTextDestroy markertxt} default { if {$current(frame) != {}} { if {[$current(frame) has fits]} { SimpleTextDialog markertxt [msgcat::mc {Region}] \ 80 20 insert top \ [$current(frame) marker list $marker(format) \ $marker(system) $marker(sky) \ $marker(skyformat) $marker(strip)] } } incr i -1 } } } save { incr i set ff [lindex $var $i] if {$ff == {}} { return } if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker save "\{$ff\}" \ $marker(format) $marker(system) $marker(sky) \ $marker(skyformat) $marker(strip) } } FileLast markerfbox $ff } file - load { incr i switch -- [string tolower [lindex $var $i]] { all { incr i set frames $ds9(frames) } default { set frames $current(frame) } } MarkerLoadFrames [lindex $var $i] $frames \ $marker(format) $marker(system) $marker(sky) } default { set format $marker(format) set sys $marker(system) set sky $marker(sky) while {[string range [lindex $var $i] 0 0] == "-"} { switch -- [string tolower [lindex $var $i]] { -format { incr i set format [lindex $var $i] } -sys - -coord - -system { incr i # for backward compatibility switch -- [lindex $var $i] { fk4 - fk5 - icrs - galactic - ecliptic { set sys wcs set sky [lindex $var $i] } default { set sys [lindex $var $i] } } } -sky { incr i set sky [lindex $var $i] } default { Error "Illegal option: [lindex $var $i]" return } } incr i } if {$sock != {}} { # xpa path if {[lindex $var $i] != {}} { MarkerLoadFrames [lindex $var $i] $current(frame) \ $format $sys $sky } else { # fits regions files not supported if {$current(frame) != {}} { if {[$current(frame) has fits]} { $current(frame) marker load $format $sock $sys $sky } } UpdateGroupDialog } } elseif {$fn != {}} { # samp path if {[lindex $var $i] != {}} { MarkerLoadFrames [lindex $var $i] $current(frame) \ $format $sys $sky } else { MarkerLoadFrames $fn $current(frame) \ $format $sys $sky } } else { # this will open a fits regions file MarkerLoadFrames [lindex $var $i] $current(frame) \ $format $sys $sky } } } } proc ProcessSendRegionsCmd {proc id param sock fn} { global current global marker if {$current(frame) == {}} { return } switch -- [lindex $param 0] { show {$proc $id [ToYesNo $marker(show)]} showtext {$proc $id [ToYesNo $marker(show,text)]} centroid { switch -- [lindex $param 1] { auto {$proc $id [ToYesNo $marker(centroid,auto)]} radius {$proc $id "$marker(centroid,radius)\n"} iteration {$proc $id "$marker(centroid,iteration)\n"} } } autocentroid {$proc $id [ToYesNo $marker(centroid,auto)]} format {$proc $id "$marker(format)\n"} coord - system {$proc $id "$marker(system)\n"} sky {$proc $id "$marker(sky)\n"} coordformat - skyformat {$proc $id "$marker(skyformat)\n"} strip {$proc $id [ToYesNo $marker(strip)]} delim { if {$marker(strip)} { $proc $id "semicolon\n" } else { $proc $id "nl\n" } } shape {$proc $id "$marker(shape)\n"} color {$proc $id "$marker(color)\n"} width {$proc $id "$marker(width)\n"} tag - tags - group - groups {$proc $id "[lsort [$current(frame) get marker tag all]]\n"} default { set format $marker(format) set sys $marker(system) set sky $marker(sky) set skyformat $marker(skyformat) set strip $marker(strip) set select {} set props {} set tags {} set i 0 set l [llength $param] while {$i < $l} { switch -- [lindex $param $i] { -format {incr i; set format [lindex $param $i]} -sys - -coord - -system { incr i # for backward compatibility switch -- [lindex $param $i] { fk4 - fk5 - icrs - galactic - ecliptic { set sys wcs set sky [lindex $param $i] } default {set sys [lindex $param $i]} } } -sky {incr i; set sky [lindex $param $i]} -coordformat - -skyformat { incr i switch -- [lindex $param $i] { deg - degree - degrees {set skyformat degrees} default {set skyformat [lindex $param $i]} } } -strip { incr i; set strip [FromYesNo [lindex $param $i]] } -delim { incr i; if {[lindex $param $i] != "nl"} { set strip 1 } else { set strip 0 } } include {append props " include = 1"} exclude {append props " include = 0"} source {append props " source = 1"} background {append props " source = 0"} selected {set select "select"} -prop { append props " [lindex $param [expr $i+1]] = [lindex $param [expr $i+2]]" incr i 2 } -tag - -group { incr i append tags "tag = \{[lindex $param $i]\}" } } incr i } switch -- $format { xml {set ext {.xml}} default {set ext {.rgn}} } ProcessSend $proc $id $sock $fn $ext \ [$current(frame) marker list $select $format \ $sys $sky $skyformat $strip $props $tags] } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mframe.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000134631�12033632634�013657� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc FrameMainMenu {} { global ds9 global current menu $ds9(mb).frame $ds9(mb).frame add command -label [msgcat::mc {New Frame}] \ -command CreateFrame $ds9(mb).frame add command -label [msgcat::mc {New Frame RGB}] \ -command CreateRGBFrame $ds9(mb).frame add command -label [msgcat::mc {New Frame 3D}] \ -command Create3DFrame $ds9(mb).frame add separator $ds9(mb).frame add command -label [msgcat::mc {Delete Frame}] \ -command DeleteCurrentFrame $ds9(mb).frame add command -label [msgcat::mc {Delete All Frames}] \ -command DeleteAllFramesMenu $ds9(mb).frame add separator $ds9(mb).frame add command -label [msgcat::mc {Clear Frame}] \ -command ClearCurrentFrame $ds9(mb).frame add command -label [msgcat::mc {Reset Frame}] \ -command ResetCurrentFrame $ds9(mb).frame add command -label [msgcat::mc {Refresh Frame}] \ -command UpdateCurrentFrame $ds9(mb).frame add separator $ds9(mb).frame add radiobutton -label [msgcat::mc {Single Frame}] \ -variable current(display) -value single -command DisplayMode $ds9(mb).frame add radiobutton -label [msgcat::mc {Tile Frames}] \ -variable current(display) -value tile -command DisplayMode $ds9(mb).frame add radiobutton -label [msgcat::mc {Blink Frames}] \ -variable current(display) -value blink -command DisplayMode $ds9(mb).frame add separator $ds9(mb).frame add cascade -label [msgcat::mc {Match}] \ -menu $ds9(mb).frame.match $ds9(mb).frame add cascade -label [msgcat::mc {Lock}] \ -menu $ds9(mb).frame.lock $ds9(mb).frame add separator $ds9(mb).frame add cascade -label [msgcat::mc {Goto Frame}] \ -menu $ds9(mb).frame.goto $ds9(mb).frame add cascade -label [msgcat::mc {Show/Hide Frames}] \ -menu $ds9(mb).frame.active $ds9(mb).frame add cascade -label [msgcat::mc {Move Frame}] \ -menu $ds9(mb).frame.move $ds9(mb).frame add separator $ds9(mb).frame add command -label [msgcat::mc {First Frame}] \ -command FirstFrame $ds9(mb).frame add command -label [msgcat::mc {Previous Frame}] \ -command PrevFrame $ds9(mb).frame add command -label [msgcat::mc {Next Frame}] \ -command NextFrame $ds9(mb).frame add command -label [msgcat::mc {Last Frame}] \ -command LastFrame $ds9(mb).frame add separator $ds9(mb).frame add command -label "[msgcat::mc {Cube}]..." \ -command CubeDialog $ds9(mb).frame add command -label "[msgcat::mc {RGB}]..." \ -command RGBDialog $ds9(mb).frame add command -label "[msgcat::mc {3D}]..." \ -command 3DDialog $ds9(mb).frame add separator $ds9(mb).frame add cascade -label [msgcat::mc {Frame Parameters}] \ -menu $ds9(mb).frame.params # match menu $ds9(mb).frame.match $ds9(mb).frame.match add cascade -label [msgcat::mc {Frame}] \ -menu $ds9(mb).frame.match.frame $ds9(mb).frame.match add cascade -label [msgcat::mc {Crosshair}] \ -menu $ds9(mb).frame.match.crosshair $ds9(mb).frame.match add cascade -label [msgcat::mc {Crop}] \ -menu $ds9(mb).frame.match.crop $ds9(mb).frame.match add command -label [msgcat::mc {Slice}] \ -command MatchCubeCurrent $ds9(mb).frame.match add command -label [msgcat::mc {Bin}] \ -command MatchBinCurrent $ds9(mb).frame.match add command -label [msgcat::mc {Scale}] \ -command MatchScaleCurrent $ds9(mb).frame.match add command -label [msgcat::mc {Colorbar}] \ -command MatchColorCurrent $ds9(mb).frame.match add command -label [msgcat::mc {Smooth}] \ -command MatchSmoothCurrent menu $ds9(mb).frame.match.frame $ds9(mb).frame.match.frame add command -label [msgcat::mc {WCS}] \ -command {MatchFrameCurrent wcs} $ds9(mb).frame.match.frame add separator $ds9(mb).frame.match.frame add command -label [msgcat::mc {Image}] \ -command {MatchFrameCurrent image} $ds9(mb).frame.match.frame add command -label [msgcat::mc {Physical}] \ -command {MatchFrameCurrent physical} $ds9(mb).frame.match.frame add command -label [msgcat::mc {Amplifier}] \ -command {MatchFrameCurrent amplifier} $ds9(mb).frame.match.frame add command -label [msgcat::mc {Detector}] \ -command {MatchFrameCurrent detector} menu $ds9(mb).frame.match.crosshair $ds9(mb).frame.match.crosshair add command -label [msgcat::mc {WCS}] \ -command {MatchCrosshairCurrent wcs} $ds9(mb).frame.match.crosshair add separator $ds9(mb).frame.match.crosshair add command -label [msgcat::mc {Image}] \ -command {MatchCrosshairCurrent image} $ds9(mb).frame.match.crosshair add command -label [msgcat::mc {Physical}] \ -command {MatchCrosshairCurrent physical} $ds9(mb).frame.match.crosshair add command -label [msgcat::mc {Amplifier}] \ -command {MatchCrosshairCurrent amplifier} $ds9(mb).frame.match.crosshair add command -label [msgcat::mc {Detector}] \ -command {MatchCrosshairCurrent detector} menu $ds9(mb).frame.match.crop $ds9(mb).frame.match.crop add command -label [msgcat::mc {WCS}] \ -command {MatchCropCurrent wcs} $ds9(mb).frame.match.crop add separator $ds9(mb).frame.match.crop add command -label [msgcat::mc {Image}] \ -command {MatchCropCurrent image} $ds9(mb).frame.match.crop add command -label [msgcat::mc {Physical}] \ -command {MatchCropCurrent physical} $ds9(mb).frame.match.crop add command -label [msgcat::mc {Amplifier}] \ -command {MatchCropCurrent amplifier} $ds9(mb).frame.match.crop add command -label [msgcat::mc {Detector}] \ -command {MatchCropCurrent detector} # lock menu $ds9(mb).frame.lock $ds9(mb).frame.lock add cascade -label [msgcat::mc {Frame}] \ -menu $ds9(mb).frame.lock.frame $ds9(mb).frame.lock add cascade -label [msgcat::mc {Crosshair}] \ -menu $ds9(mb).frame.lock.crosshair $ds9(mb).frame.lock add cascade -label [msgcat::mc {Crop}] \ -menu $ds9(mb).frame.lock.crop $ds9(mb).frame.lock add checkbutton -label [msgcat::mc {Slice}] \ -variable cube(lock) -command {LockCubeCurrent} $ds9(mb).frame.lock add checkbutton -label [msgcat::mc {Bin}] \ -variable bin(lock) -command {LockBinCurrent} $ds9(mb).frame.lock add checkbutton -label [msgcat::mc {Scale}] \ -variable scale(lock) -command {LockScaleCurrent} $ds9(mb).frame.lock add checkbutton -label [msgcat::mc {Colorbar}] \ -variable colorbar(lock) -command {LockColorCurrent} $ds9(mb).frame.lock add checkbutton -label [msgcat::mc {Smooth}] \ -variable smooth(lock) -command {LockSmoothCurrent} menu $ds9(mb).frame.lock.frame $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {None}] \ -variable panzoom(lock) -value none -command LockFrameCurrent $ds9(mb).frame.lock.frame add separator $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {WCS}] \ -variable panzoom(lock) -value wcs -command LockFrameCurrent $ds9(mb).frame.lock.frame add separator $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {Image}] \ -variable panzoom(lock) -value image -command LockFrameCurrent $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {Physical}] \ -variable panzoom(lock) -value physical -command LockFrameCurrent $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {Amplifier}] \ -variable panzoom(lock) -value amplifier -command LockFrameCurrent $ds9(mb).frame.lock.frame add radiobutton -label [msgcat::mc {Detector}] \ -variable panzoom(lock) -value detector -command LockFrameCurrent menu $ds9(mb).frame.lock.crosshair $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {None}] -variable crosshair(lock) \ -value none -command LockCrosshairCurrent $ds9(mb).frame.lock.crosshair add separator $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {WCS}] -variable crosshair(lock) \ -value wcs -command LockCrosshairCurrent $ds9(mb).frame.lock.crosshair add separator $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {Image}] -variable crosshair(lock) \ -value image -command LockCrosshairCurrent $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {Physical}] -variable crosshair(lock) \ -value physical -command LockCrosshairCurrent $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {Amplifier}] -variable crosshair(lock) \ -value amplifier -command LockCrosshairCurrent $ds9(mb).frame.lock.crosshair add radiobutton \ -label [msgcat::mc {Detector}] -variable crosshair(lock) \ -value detector -command LockCrosshairCurrent menu $ds9(mb).frame.lock.crop $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {None}] \ -variable crop(lock) -value none -command LockCropCurrent $ds9(mb).frame.lock.crop add separator $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {WCS}] \ -variable crop(lock) -value wcs -command LockCropCurrent $ds9(mb).frame.lock.crop add separator $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {Image}] \ -variable crop(lock) -value image -command LockCropCurrent $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {Physical}] \ -variable crop(lock) -value physical -command LockCropCurrent $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {Amplifier}] \ -variable crop(lock) -value amplifier -command LockCropCurrent $ds9(mb).frame.lock.crop add radiobutton -label [msgcat::mc {Detector}] \ -variable crop(lock) -value detector -command LockCropCurrent # active menu $ds9(mb).frame.active $ds9(mb).frame.active add command -label [msgcat::mc {Show All}] \ -command ActiveFrameAll $ds9(mb).frame.active add command -label [msgcat::mc {Hide All}] \ -command ActiveFrameNone $ds9(mb).frame.active add separator # move menu $ds9(mb).frame.move $ds9(mb).frame.move add command -label [msgcat::mc {First}] \ -command MoveFirstFrame $ds9(mb).frame.move add command -label [msgcat::mc {Back}] \ -command MovePrevFrame $ds9(mb).frame.move add command -label [msgcat::mc {Forward}] \ -command MoveNextFrame $ds9(mb).frame.move add command -label [msgcat::mc {Last}] \ -command MoveLastFrame menu $ds9(mb).frame.goto # params menu $ds9(mb).frame.params $ds9(mb).frame.params add cascade -label [msgcat::mc {Tile}] \ -menu $ds9(mb).frame.params.tile $ds9(mb).frame.params add cascade -label [msgcat::mc {Blink Interval}] \ -menu $ds9(mb).frame.params.blink $ds9(mb).frame.params add command -label [msgcat::mc {Display Size}] \ -command DisplayDefaultDialog menu $ds9(mb).frame.params.tile $ds9(mb).frame.params.tile add radiobutton -label [msgcat::mc {Grid}] \ -variable tile(mode) -value grid -command DisplayMode $ds9(mb).frame.params.tile add radiobutton -label [msgcat::mc {Columns}] \ -variable tile(mode) -value column -command DisplayMode $ds9(mb).frame.params.tile add radiobutton -label [msgcat::mc {Rows}] \ -variable tile(mode) -value row -command DisplayMode $ds9(mb).frame.params.tile add separator $ds9(mb).frame.params.tile add command \ -label "[msgcat::mc {Tile Parameters}]..." -command TileDialog menu $ds9(mb).frame.params.blink $ds9(mb).frame.params.blink add radiobutton \ -label ".125 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 125 $ds9(mb).frame.params.blink add radiobutton \ -label ".25 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 250 $ds9(mb).frame.params.blink add radiobutton \ -label ".5 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 500 $ds9(mb).frame.params.blink add radiobutton \ -label "1 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 1000 $ds9(mb).frame.params.blink add radiobutton \ -label "2 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 2000 $ds9(mb).frame.params.blink add radiobutton \ -label "4 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 4000 $ds9(mb).frame.params.blink add radiobutton \ -label "8 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 8000 } proc PrefsDialogFrameMenu {w} { set f [ttk::labelframe $w.mframe -text [msgcat::mc {Frame}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarFrame $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add radiobutton -label [msgcat::mc {Single Frame}] \ -variable pcurrent(display) -value single $m add radiobutton -label [msgcat::mc {Tile Frames}] \ -variable pcurrent(display) -value tile $m add radiobutton -label [msgcat::mc {Blink Frames}] \ -variable pcurrent(display) -value blink $m add separator $m add cascade -label [msgcat::mc {Frame Parameters}] \ -menu $m.params menu $m.params $m.params add cascade -label [msgcat::mc {Tile}] \ -menu $m.params.tile $m.params add cascade -label [msgcat::mc {Blink Interval}] \ -menu $m.params.blink menu $m.params.tile $m.params.tile add radiobutton -label [msgcat::mc {Grid}] \ -variable ptile(mode) -value grid $m.params.tile add radiobutton -label [msgcat::mc {Columns}] \ -variable ptile(mode) -value column $m.params.tile add radiobutton -label [msgcat::mc {Rows}] \ -variable ptile(mode) -value row menu $m.params.blink $m.params.blink add radiobutton -label ".125 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 125 $m.params.blink add radiobutton -label ".25 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 250 $m.params.blink add radiobutton -label ".5 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 500 $m.params.blink add radiobutton -label "1 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 1000 $m.params.blink add radiobutton -label "2 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 2000 $m.params.blink add radiobutton -label "4 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 4000 $m.params.blink add radiobutton -label "8 [msgcat::mc {Seconds}]" \ -variable pblink(interval) -value 8000 pack $f -side top -fill both -expand true } # Buttons proc ButtonsFrameDef {} { global pbuttons array set pbuttons { frame,new 1 frame,newrgb 1 frame,new3d 1 frame,delete 1 frame,deleteall 0 frame,clear 1 frame,reset 0 frame,refresh 0 frame,single 1 frame,tile 1 frame,blink 1 frame,match,cube 0 frame,match,bin 0 frame,match,scale 0 frame,match,color 0 frame,match,smooth 0 frame,match,frame,wcs 0 frame,match,frame,image 0 frame,match,frame,physical 0 frame,match,frame,detector 0 frame,match,frame,amplifier 0 frame,match,crosshair,wcs 0 frame,match,crosshair,image 0 frame,match,crosshair,physical 0 frame,match,crosshair,detector 0 frame,match,crosshair,amplifier 0 frame,match,crop,wcs 0 frame,match,crop,image 0 frame,match,crop,physical 0 frame,match,crop,detector 0 frame,match,crop,amplifier 0 frame,lock,cube 0 frame,lock,bin 0 frame,lock,scale 0 frame,lock,color 0 frame,lock,smooth 0 frame,lock,frame,none 0 frame,lock,frame,wcs 0 frame,lock,frame,image 0 frame,lock,frame,physical 0 frame,lock,frame,detector 0 frame,lock,frame,amplifier 0 frame,lock,crosshair,none 0 frame,lock,crosshair,wcs 0 frame,lock,crosshair,image 0 frame,lock,crosshair,physical 0 frame,lock,crosshair,detector 0 frame,lock,crosshair,amplifier 0 frame,lock,crop,none 0 frame,lock,crop,wcs 0 frame,lock,crop,image 0 frame,lock,crop,physical 0 frame,lock,crop,detector 0 frame,lock,crop,amplifier 0 frame,movefirst 0 frame,moveprev 0 frame,movenext 0 frame,movelast 0 frame,first 1 frame,prev 1 frame,next 1 frame,last 1 frame,cube 0 frame,rgb 0 frame,3d 0 frame,size 0 } } proc CreateButtonsFrame {} { global buttons global ds9 global current ttk::frame $ds9(buttons).frame ButtonButton $ds9(buttons).frame.new \ [string tolower [msgcat::mc {New}]] CreateFrame ButtonButton $ds9(buttons).frame.newrgb \ [string tolower [msgcat::mc {New RGB}]] CreateRGBFrame ButtonButton $ds9(buttons).frame.new3d \ [string tolower [msgcat::mc {New 3D}]] Create3DFrame ButtonButton $ds9(buttons).frame.delete \ [string tolower [msgcat::mc {Delete}]] DeleteCurrentFrame ButtonButton $ds9(buttons).frame.deleteall \ [string tolower [msgcat::mc {Delete All}]] DeleteAllFramesMenu ButtonButton $ds9(buttons).frame.clear \ [string tolower [msgcat::mc {Clear}]] ClearCurrentFrame ButtonButton $ds9(buttons).frame.reset \ [string tolower [msgcat::mc {Reset}]] ResetCurrentFrame ButtonButton $ds9(buttons).frame.refresh \ [string tolower [msgcat::mc {Refresh}]] UpdateCurrentFrame RadioButton $ds9(buttons).frame.single \ [string tolower [msgcat::mc {Single}]] \ current(display) single DisplayMode RadioButton $ds9(buttons).frame.tile \ [string tolower [msgcat::mc {Tile}]] \ current(display) tile DisplayMode RadioButton $ds9(buttons).frame.blink \ [string tolower [msgcat::mc {Blink}]] \ current(display) blink DisplayMode ButtonButton $ds9(buttons).frame.matchcube \ [string tolower [msgcat::mc {Match Slice}]] MatchCubeCurrent ButtonButton $ds9(buttons).frame.matchbin \ [string tolower [msgcat::mc {Match Bin}]] MatchBinCurrent ButtonButton $ds9(buttons).frame.matchscale \ [string tolower [msgcat::mc {Match Scale}]] MatchScaleCurrent ButtonButton $ds9(buttons).frame.matchcolor \ [string tolower [msgcat::mc {Match Color}]] MatchColorCurrent ButtonButton $ds9(buttons).frame.matchsmooth \ [string tolower [msgcat::mc {Match Smooth}]] MatchSmoothCurrent ButtonButton $ds9(buttons).frame.matchframewcs \ [string tolower [msgcat::mc {Match Frame WCS}]] \ {MatchFrameCurrent wcs} ButtonButton $ds9(buttons).frame.matchframeimage \ [string tolower [msgcat::mc {Match Frame Image}]] \ {MatchFrameCurrent image} ButtonButton $ds9(buttons).frame.matchframephysical \ [string tolower [msgcat::mc {Match Frame Physical}]] \ {MatchFrameCurrent physical} ButtonButton $ds9(buttons).frame.matchframedetector \ [string tolower [msgcat::mc {Match Frame Detector}]] \ {MatchFrameCurrent detector} ButtonButton $ds9(buttons).frame.matchframeamplifier \ [string tolower [msgcat::mc {Match Frame Amplifier}]] \ {MatchFrameCurrent amplifier} ButtonButton $ds9(buttons).frame.matchcrosshairwcs \ [string tolower [msgcat::mc {Match Crosshair WCS}]] \ {MatchCrosshairCurrent wcs} ButtonButton $ds9(buttons).frame.matchcrosshairimage \ [string tolower [msgcat::mc {Match Crosshair Image}]] \ {MatchCrosshairCurrent image} ButtonButton $ds9(buttons).frame.matchcrosshairphysical \ [string tolower [msgcat::mc {Match Crosshair Physical}]] \ {MatchCrosshairCurrent physical} ButtonButton $ds9(buttons).frame.matchcrosshairdetector \ [string tolower [msgcat::mc {Match Crosshair Detector}]] \ {MatchCrosshairCurrent detector} ButtonButton $ds9(buttons).frame.matchcrosshairamplifier \ [string tolower [msgcat::mc {Match Crosshair Amplifier}]] \ {MatchCrosshairCurrent amplifier} ButtonButton $ds9(buttons).frame.matchcropwcs \ [string tolower [msgcat::mc {Match Crop WCS}]] \ {MatchCropCurrent wcs} ButtonButton $ds9(buttons).frame.matchcropimage \ [string tolower [msgcat::mc {Match Crop Image}]] \ {MatchCropCurrent image} ButtonButton $ds9(buttons).frame.matchcropphysical \ [string tolower [msgcat::mc {Match Crop Physical}]] \ {MatchCropCurrent physical} ButtonButton $ds9(buttons).frame.matchcropdetector \ [string tolower [msgcat::mc {Match Crop Detector}]] \ {MatchCropCurrent detector} ButtonButton $ds9(buttons).frame.matchcropamplifier \ [string tolower [msgcat::mc {Match Crop Amplifier}]] \ {MatchCropCurrent amplifier} CheckButton $ds9(buttons).frame.lockcube \ [string tolower [msgcat::mc {Lock Slice}]] cube(lock) LockCubeCurrent CheckButton $ds9(buttons).frame.lockbin \ [string tolower [msgcat::mc {Lock Bin}]] bin(lock) LockBinCurrent CheckButton $ds9(buttons).frame.lockscale \ [string tolower [msgcat::mc {Lock Scale}]] scale(lock) LockScaleCurrent CheckButton $ds9(buttons).frame.lockcolor \ [string tolower [msgcat::mc {Lock Color}]] color(lock) LockColorCurrent CheckButton $ds9(buttons).frame.locksmooth \ [string tolower [msgcat::mc {Lock Smooth}]] smooth(lock) LockSmoothCurrent RadioButton $ds9(buttons).frame.lockframenone \ [string tolower [msgcat::mc {Lock Frame None}]] \ panzoom(lock) none LockFrameCurrent RadioButton $ds9(buttons).frame.lockframewcs \ [string tolower [msgcat::mc {Lock Frame WCS}]] \ panzoom(lock) wcs LockFrameCurrent RadioButton $ds9(buttons).frame.lockframeimage \ [string tolower [msgcat::mc {Lock Frame Image}]] \ panzoom(lock) image LockFrameCurrent RadioButton $ds9(buttons).frame.lockframephysical \ [string tolower [msgcat::mc {Lock Frame Physical}]] \ panzoom(lock) physical LockFrameCurrent RadioButton $ds9(buttons).frame.lockframedetector \ [string tolower [msgcat::mc {Lock Frame Detector}]] \ panzoom(lock) detector LockFrameCurrent RadioButton $ds9(buttons).frame.lockframeamplifier \ [string tolower [msgcat::mc {Lock Frame Amplifier}]] \ panzoom(lock) amplifier LockFrameCurrent RadioButton $ds9(buttons).frame.lockcrosshairnone \ [string tolower [msgcat::mc {Lock Crosshair None}]] \ crosshair(lock) none LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcrosshairwcs \ [string tolower [msgcat::mc {Lock Crosshair WCS}]] \ crosshair(lock) wcs LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcrosshairimage \ [string tolower [msgcat::mc {Lock Crosshair Image}]] \ crosshair(lock) image LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcrosshairphysical \ [string tolower [msgcat::mc {Lock Crosshair Physical}]] \ crosshair(lock) physical LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcrosshairdetector \ [string tolower [msgcat::mc {Lock Crosshair Detector}]] \ crosshair(lock) detector LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcrosshairamplifier \ [string tolower [msgcat::mc {Lock Crosshair Amplifier}]] \ crosshair(lock) amplifier LockCrosshairCurrent RadioButton $ds9(buttons).frame.lockcropnone \ [string tolower [msgcat::mc {Lock Crop None}]] \ crop(lock) none LockCropCurrent RadioButton $ds9(buttons).frame.lockcropwcs \ [string tolower [msgcat::mc {Lock Crop WCS}]] \ crop(lock) wcs LockCropCurrent RadioButton $ds9(buttons).frame.lockcropimage \ [string tolower [msgcat::mc {Lock Crop Image}]] \ crop(lock) image LockCropCurrent RadioButton $ds9(buttons).frame.lockcropphysical \ [string tolower [msgcat::mc {Lock Crop Physical}]] \ crop(lock) physical LockCropCurrent RadioButton $ds9(buttons).frame.lockcropdetector \ [string tolower [msgcat::mc {Lock Crop Detector}]] \ crop(lock) detector LockCropCurrent RadioButton $ds9(buttons).frame.lockcropamplifier \ [string tolower [msgcat::mc {Lock Crop Amplifier}]] \ crop(lock) amplifier LockCropCurrent ButtonButton $ds9(buttons).frame.movefirst \ [string tolower [msgcat::mc {Move First}]] MoveFirstFrame ButtonButton $ds9(buttons).frame.moveprev \ [string tolower [msgcat::mc {Move Back}]] MovePrevFrame ButtonButton $ds9(buttons).frame.movenext \ [string tolower [msgcat::mc {Move Forward}]] MoveNextFrame ButtonButton $ds9(buttons).frame.movelast \ [string tolower [msgcat::mc {Move Last}]] MoveLastFrame ButtonButton $ds9(buttons).frame.first \ [string tolower [msgcat::mc {First}]] FirstFrame ButtonButton $ds9(buttons).frame.prev \ [string tolower [msgcat::mc {Previous}]] PrevFrame ButtonButton $ds9(buttons).frame.next \ [string tolower [msgcat::mc {Next}]] NextFrame ButtonButton $ds9(buttons).frame.last \ [string tolower [msgcat::mc {Last}]] LastFrame ButtonButton $ds9(buttons).frame.cube \ [string tolower [msgcat::mc {Cube}]] CubeDialog ButtonButton $ds9(buttons).frame.rgb \ [string tolower [msgcat::mc {RGB}]] RGBDialog ButtonButton $ds9(buttons).frame.3d \ [string tolower [msgcat::mc {3D}]] 3DDialog ButtonButton $ds9(buttons).frame.size \ [string tolower [msgcat::mc {Size}]] DisplayDefaultDialog set buttons(frame) " $ds9(buttons).frame.new pbuttons(frame,new) $ds9(buttons).frame.newrgb pbuttons(frame,newrgb) $ds9(buttons).frame.new3d pbuttons(frame,new3d) $ds9(buttons).frame.delete pbuttons(frame,delete) $ds9(buttons).frame.deleteall pbuttons(frame,deleteall) $ds9(buttons).frame.clear pbuttons(frame,clear) $ds9(buttons).frame.reset pbuttons(frame,reset) $ds9(buttons).frame.refresh pbuttons(frame,refresh) $ds9(buttons).frame.single pbuttons(frame,single) $ds9(buttons).frame.tile pbuttons(frame,tile) $ds9(buttons).frame.blink pbuttons(frame,blink) $ds9(buttons).frame.matchcube pbuttons(frame,match,cube) $ds9(buttons).frame.matchbin pbuttons(frame,match,bin) $ds9(buttons).frame.matchscale pbuttons(frame,match,scale) $ds9(buttons).frame.matchcolor pbuttons(frame,match,color) $ds9(buttons).frame.matchsmooth pbuttons(frame,match,smooth) $ds9(buttons).frame.matchframewcs pbuttons(frame,match,frame,wcs) $ds9(buttons).frame.matchframeimage pbuttons(frame,match,frame,image) $ds9(buttons).frame.matchframephysical pbuttons(frame,match,frame,physical) $ds9(buttons).frame.matchframedetector pbuttons(frame,match,frame,detector) $ds9(buttons).frame.matchframeamplifier pbuttons(frame,match,frame,amplifier) $ds9(buttons).frame.matchcrosshairwcs pbuttons(frame,match,crosshair,wcs) $ds9(buttons).frame.matchcrosshairimage pbuttons(frame,match,crosshair,image) $ds9(buttons).frame.matchcrosshairphysical pbuttons(frame,match,crosshair,physical) $ds9(buttons).frame.matchcrosshairdetector pbuttons(frame,match,crosshair,detector) $ds9(buttons).frame.matchcrosshairamplifier pbuttons(frame,match,crosshair,amplifier) $ds9(buttons).frame.matchcropwcs pbuttons(frame,match,crop,wcs) $ds9(buttons).frame.matchcropimage pbuttons(frame,match,crop,image) $ds9(buttons).frame.matchcropphysical pbuttons(frame,match,crop,physical) $ds9(buttons).frame.matchcropdetector pbuttons(frame,match,crop,detector) $ds9(buttons).frame.matchcropamplifier pbuttons(frame,match,crop,amplifier) $ds9(buttons).frame.lockcube pbuttons(frame,lock,cube) $ds9(buttons).frame.lockbin pbuttons(frame,lock,bin) $ds9(buttons).frame.lockscale pbuttons(frame,lock,scale) $ds9(buttons).frame.lockcolor pbuttons(frame,lock,color) $ds9(buttons).frame.locksmooth pbuttons(frame,lock,smooth) $ds9(buttons).frame.lockframenone pbuttons(frame,lock,frame,none) $ds9(buttons).frame.lockframewcs pbuttons(frame,lock,frame,wcs) $ds9(buttons).frame.lockframeimage pbuttons(frame,lock,frame,image) $ds9(buttons).frame.lockframephysical pbuttons(frame,lock,frame,physical) $ds9(buttons).frame.lockframedetector pbuttons(frame,lock,frame,detector) $ds9(buttons).frame.lockframeamplifier pbuttons(frame,lock,frame,amplifier) $ds9(buttons).frame.lockcrosshairnone pbuttons(frame,lock,crosshair,none) $ds9(buttons).frame.lockcrosshairwcs pbuttons(frame,lock,crosshair,wcs) $ds9(buttons).frame.lockcrosshairimage pbuttons(frame,lock,crosshair,image) $ds9(buttons).frame.lockcrosshairphysical pbuttons(frame,lock,crosshair,physical) $ds9(buttons).frame.lockcrosshairdetector pbuttons(frame,lock,crosshair,detector) $ds9(buttons).frame.lockcrosshairamplifier pbuttons(frame,lock,crosshair,amplifier) $ds9(buttons).frame.lockcropnone pbuttons(frame,lock,crop,none) $ds9(buttons).frame.lockcropwcs pbuttons(frame,lock,crop,wcs) $ds9(buttons).frame.lockcropimage pbuttons(frame,lock,crop,image) $ds9(buttons).frame.lockcropphysical pbuttons(frame,lock,crop,physical) $ds9(buttons).frame.lockcropdetector pbuttons(frame,lock,crop,detector) $ds9(buttons).frame.lockcropamplifier pbuttons(frame,lock,crop,amplifier) $ds9(buttons).frame.movefirst pbuttons(frame,movefirst) $ds9(buttons).frame.moveprev pbuttons(frame,moveprev) $ds9(buttons).frame.movenext pbuttons(frame,movenext) $ds9(buttons).frame.movelast pbuttons(frame,movelast) $ds9(buttons).frame.first pbuttons(frame,first) $ds9(buttons).frame.prev pbuttons(frame,prev) $ds9(buttons).frame.next pbuttons(frame,next) $ds9(buttons).frame.last pbuttons(frame,last) $ds9(buttons).frame.cube pbuttons(frame,cube) $ds9(buttons).frame.rgb pbuttons(frame,rgb) $ds9(buttons).frame.3d pbuttons(frame,3d) $ds9(buttons).frame.size pbuttons(frame,size) " } proc PrefsDialogButtonbarFrame {f} { global buttons global pbuttons global ds9 ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {New Frame}] \ -variable pbuttons(frame,new) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {New Frame RGB}] \ -variable pbuttons(frame,newrgb) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {New Frame 3D}] \ -variable pbuttons(frame,new3d) -command {UpdateButtons buttons(frame)} $m add separator $m add checkbutton -label [msgcat::mc {Delete Frame}] \ -variable pbuttons(frame,delete) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Delete All Frames}] \ -variable pbuttons(frame,deleteall) -command {UpdateButtons buttons(frame)} $m add separator $m add checkbutton -label [msgcat::mc {Clear Frame}] \ -variable pbuttons(frame,clear) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Reset Frame}] \ -variable pbuttons(frame,reset) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Refresh Frame}] \ -variable pbuttons(frame,refresh) -command {UpdateButtons buttons(frame)} $m add separator $m add checkbutton -label [msgcat::mc {Single Frame}] \ -variable pbuttons(frame,single) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Tile Frames}] \ -variable pbuttons(frame,tile) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Blink Frames}] \ -variable pbuttons(frame,blink) -command {UpdateButtons buttons(frame)} $m add separator $m add cascade -label [msgcat::mc {Match}] -menu $m.match $m add cascade -label [msgcat::mc {Lock}] -menu $m.lock $m add separator $m add cascade -label [msgcat::mc {Move Frame}] -menu $m.move $m add separator $m add checkbutton -label [msgcat::mc {First Frame}] \ -variable pbuttons(frame,first) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Previous Frame}] \ -variable pbuttons(frame,prev) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Next Frame}] \ -variable pbuttons(frame,next) -command {UpdateButtons buttons(frame)} $m add checkbutton -label [msgcat::mc {Last Frame}] \ -variable pbuttons(frame,last) -command {UpdateButtons buttons(frame)} $m add separator $m add checkbutton -label "[msgcat::mc {Cube}]..." \ -variable pbuttons(frame,cube) -command {UpdateButtons buttons(frame)} $m add checkbutton -label "[msgcat::mc {RGB}]..." \ -variable pbuttons(frame,rgb) -command {UpdateButtons buttons(frame)} $m add checkbutton -label "[msgcat::mc {3D}]..." \ -variable pbuttons(frame,3d) -command {UpdateButtons buttons(frame)} $m add separator $m add cascade -label [msgcat::mc {Frame Parameters}] -menu $m.params # match menu $m.match $m.match add cascade -label [msgcat::mc {Frame}] \ -menu $m.match.frame $m.match add cascade -label [msgcat::mc {Crosshair}] \ -menu $m.match.crosshair $m.match add cascade -label [msgcat::mc {Crop}] \ -menu $m.match.crop $m.match add checkbutton -label [msgcat::mc {Slice}] \ -variable pbuttons(frame,match,cube) \ -command {UpdateButtons buttons(frame)} $m.match add checkbutton -label [msgcat::mc {Bin}] \ -variable pbuttons(frame,match,bin) \ -command {UpdateButtons buttons(frame)} $m.match add checkbutton -label [msgcat::mc {Scale}] \ -variable pbuttons(frame,match,scale) \ -command {UpdateButtons buttons(frame)} $m.match add checkbutton -label [msgcat::mc {Color}] \ -variable pbuttons(frame,match,color) \ -command {UpdateButtons buttons(frame)} $m.match add checkbutton -label [msgcat::mc {Smooth}] \ -variable pbuttons(frame,match,smooth) \ -command {UpdateButtons buttons(frame)} menu $m.match.frame $m.match.frame add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,match,frame,wcs) \ -command {UpdateButtons buttons(frame)} $m.match.frame add separator $m.match.frame add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,match,frame,image) \ -command {UpdateButtons buttons(frame)} $m.match.frame add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,match,frame,physical) \ -command {UpdateButtons buttons(frame)} $m.match.frame add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,match,frame,detector) \ -command {UpdateButtons buttons(frame)} $m.match.frame add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,match,frame,amplifier) \ -command {UpdateButtons buttons(frame)} menu $m.match.crosshair $m.match.crosshair add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,match,crosshair,wcs) \ -command {UpdateButtons buttons(frame)} $m.match.crosshair add separator $m.match.crosshair add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,match,crosshair,image) \ -command {UpdateButtons buttons(frame)} $m.match.crosshair add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,match,crosshair,physical) \ -command {UpdateButtons buttons(frame)} $m.match.crosshair add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,match,crosshair,detector) \ -command {UpdateButtons buttons(frame)} $m.match.crosshair add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,match,crosshair,amplifier) \ -command {UpdateButtons buttons(frame)} menu $m.match.crop $m.match.crop add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,match,crop,wcs) \ -command {UpdateButtons buttons(frame)} $m.match.crop add separator $m.match.crop add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,match,crop,image) \ -command {UpdateButtons buttons(frame)} $m.match.crop add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,match,crop,physical) \ -command {UpdateButtons buttons(frame)} $m.match.crop add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,match,crop,detector) \ -command {UpdateButtons buttons(frame)} $m.match.crop add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,match,crop,amplifier) \ -command {UpdateButtons buttons(frame)} # lock menu $m.lock $m.lock add cascade -label [msgcat::mc {Frame}] \ -menu $m.lock.frame $m.lock add cascade -label [msgcat::mc {Crosshair}] \ -menu $m.lock.crosshair $m.lock add cascade -label [msgcat::mc {Crop}] \ -menu $m.lock.crop $m.lock add checkbutton -label [msgcat::mc {Slice}] \ -variable pbuttons(frame,lock,cube) \ -command {UpdateButtons buttons(frame)} $m.lock add checkbutton -label [msgcat::mc {Bin}] \ -variable pbuttons(frame,lock,bin) \ -command {UpdateButtons buttons(frame)} $m.lock add checkbutton -label [msgcat::mc {Scale}] \ -variable pbuttons(frame,lock,scale) \ -command {UpdateButtons buttons(frame)} $m.lock add checkbutton -label [msgcat::mc {Color}] \ -variable pbuttons(frame,lock,color) \ -command {UpdateButtons buttons(frame)} $m.lock add checkbutton -label [msgcat::mc {Smooth}] \ -variable pbuttons(frame,lock,smooth) \ -command {UpdateButtons buttons(frame)} menu $m.lock.frame $m.lock.frame add checkbutton -label [msgcat::mc {None}] \ -variable pbuttons(frame,lock,frame,none) \ -command {UpdateButtons buttons(frame)} $m.lock.frame add separator $m.lock.frame add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,lock,frame,wcs) \ -command {UpdateButtons buttons(frame)} $m.lock.frame add separator $m.lock.frame add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,lock,frame,image) \ -command {UpdateButtons buttons(frame)} $m.lock.frame add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,lock,frame,physical) \ -command {UpdateButtons buttons(frame)} $m.lock.frame add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,lock,frame,detector) \ -command {UpdateButtons buttons(frame)} $m.lock.frame add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,lock,frame,amplifier) \ -command {UpdateButtons buttons(frame)} menu $m.lock.crosshair $m.lock.crosshair add checkbutton -label [msgcat::mc {None}] \ -variable pbuttons(frame,lock,crosshair,none) \ -command {UpdateButtons buttons(frame)} $m.lock.crosshair add separator $m.lock.crosshair add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,lock,crosshair,wcs) \ -command {UpdateButtons buttons(frame)} $m.lock.crosshair add separator $m.lock.crosshair add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,lock,crosshair,image) \ -command {UpdateButtons buttons(frame)} $m.lock.crosshair add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,lock,crosshair,physical) \ -command {UpdateButtons buttons(frame)} $m.lock.crosshair add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,lock,crosshair,detector) \ -command {UpdateButtons buttons(frame)} $m.lock.crosshair add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,lock,crosshair,amplifier) \ -command {UpdateButtons buttons(frame)} menu $m.lock.crop $m.lock.crop add checkbutton -label [msgcat::mc {None}] \ -variable pbuttons(frame,lock,crop,none) \ -command {UpdateButtons buttons(frame)} $m.lock.crop add separator $m.lock.crop add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(frame,lock,crop,wcs) \ -command {UpdateButtons buttons(frame)} $m.lock.crop add separator $m.lock.crop add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(frame,lock,crop,image) \ -command {UpdateButtons buttons(frame)} $m.lock.crop add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(frame,lock,crop,physical) \ -command {UpdateButtons buttons(frame)} $m.lock.crop add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(frame,lock,crop,detector) \ -command {UpdateButtons buttons(frame)} $m.lock.crop add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(frame,lock,crop,amplifier) \ -command {UpdateButtons buttons(frame)} # move menu $m.move $m.move add checkbutton -label [msgcat::mc {First}] \ -variable pbuttons(frame,movefirst) \ -command {UpdateButtons buttons(frame)} $m.move add checkbutton -label [msgcat::mc {Back}] \ -variable pbuttons(frame,moveprev) \ -command {UpdateButtons buttons(frame)} $m.move add checkbutton -label [msgcat::mc {Forward}] \ -variable pbuttons(frame,movenext) \ -command {UpdateButtons buttons(frame)} $m.move add checkbutton -label [msgcat::mc {Last}] \ -variable pbuttons(frame,movelast) \ -command {UpdateButtons buttons(frame)} # params menu $m.params $m.params add checkbutton -label [msgcat::mc {Display Size}] \ -variable pbuttons(frame,size) -command {UpdateButtons buttons(frame)} } # Support proc UpdateFrameMenuStatic {} { global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateFrameMenuStatic" } switch -- $ds9(visual) { pseudocolor { $ds9(mb).frame entryconfig [msgcat::mc {New Frame RGB}] \ -state disabled $ds9(buttons).frame.newrgb configure -state disabled } truecolor { $ds9(mb).frame entryconfig [msgcat::mc {New Frame RGB}] \ -state normal $ds9(buttons).frame.newrgb configure -state normal } } if {$ds9(active,num) > 0} { $ds9(mb).frame entryconfig [msgcat::mc {Delete Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Delete All Frames}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Clear Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Reset Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Refresh Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Single Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Tile Frames}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Blink Frames}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Match}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Lock}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Move Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {First Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Previous Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Next Frame}] -state normal $ds9(mb).frame entryconfig [msgcat::mc {Last Frame}] -state normal $ds9(buttons).frame.delete configure -state normal $ds9(buttons).frame.deleteall configure -state normal $ds9(buttons).frame.clear configure -state normal $ds9(buttons).frame.reset configure -state normal $ds9(buttons).frame.refresh configure -state normal $ds9(buttons).frame.single configure -state normal $ds9(buttons).frame.tile configure -state normal $ds9(buttons).frame.blink configure -state normal $ds9(buttons).frame.movefirst configure -state normal $ds9(buttons).frame.moveprev configure -state normal $ds9(buttons).frame.movenext configure -state normal $ds9(buttons).frame.movelast configure -state normal $ds9(buttons).frame.first configure -state normal $ds9(buttons).frame.prev configure -state normal $ds9(buttons).frame.next configure -state normal $ds9(buttons).frame.last configure -state normal } else { $ds9(mb).frame entryconfig [msgcat::mc {Delete Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Delete All Frames}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Clear Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Reset Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Refresh Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Single Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Tile Frames}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Blink Frames}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Match}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Lock}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Move Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {First Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Previous Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Next Frame}] -state disabled $ds9(mb).frame entryconfig [msgcat::mc {Last Frame}] -state disabled $ds9(buttons).frame.delete configure -state disabled $ds9(buttons).frame.deleteall configure -state disabled $ds9(buttons).frame.clear configure -state disabled $ds9(buttons).frame.reset configure -state disabled $ds9(buttons).frame.refresh configure -state disabled $ds9(buttons).frame.single configure -state disabled $ds9(buttons).frame.tile configure -state disabled $ds9(buttons).frame.blink configure -state disabled $ds9(buttons).frame.movefirst configure -state disabled $ds9(buttons).frame.moveprev configure -state disabled $ds9(buttons).frame.movenext configure -state disabled $ds9(buttons).frame.movelast configure -state disabled $ds9(buttons).frame.first configure -state disabled $ds9(buttons).frame.prev configure -state disabled $ds9(buttons).frame.next configure -state disabled $ds9(buttons).frame.last configure -state disabled } } proc UpdateFrameMenu {} { global ds9 global current global debug if {$debug(tcl,update)} { puts stderr "UpdateFrameMenu" } if {$current(frame) != {}} { $ds9(mb).frame entryconfig "[msgcat::mc {Cube}]..." \ -state normal $ds9(buttons).frame.cube configure -state normal switch -- [$current(frame) get type] { base { $ds9(mb).frame entryconfig "[msgcat::mc {RGB}]..." \ -state disabled $ds9(mb).frame entryconfig "[msgcat::mc {3D}]..." \ -state normal $ds9(buttons).frame.rgb configure -state disabled $ds9(buttons).frame.3d configure -state normal } rgb { $ds9(mb).frame entryconfig "[msgcat::mc {RGB}]..." \ -state normal $ds9(mb).frame entryconfig "[msgcat::mc {3D}]..." \ -state disabled $ds9(buttons).frame.rgb configure -state normal $ds9(buttons).frame.3d configure -state disabled } 3d { $ds9(mb).frame entryconfig "[msgcat::mc {RGB}]..." \ -state disabled $ds9(mb).frame entryconfig "[msgcat::mc {3D}]..." \ -state normal $ds9(buttons).frame.rgb configure -state disabled $ds9(buttons).frame.3d configure -state normal } } } else { $ds9(mb).frame entryconfig "[msgcat::mc {Cube}]..." \ -state disabled $ds9(mb).frame entryconfig "[msgcat::mc {RGB}]..." \ -state disabled $ds9(mb).frame entryconfig "[msgcat::mc {3D}]..." \ -state disabled $ds9(buttons).frame.cube configure -state disabled $ds9(buttons).frame.rgb configure -state disabled $ds9(buttons).frame.3d configure -state disabled } } proc UpdateFrameMenuItems {} { global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateFrameMenuItems" } # Goto Frame Menu if {[$ds9(mb).frame.goto index end] >= $ds9(menu,size,frame,goto)} { $ds9(mb).frame.goto delete $ds9(menu,size,frame,goto) end } set cnt $ds9(menu,size,frame,goto) foreach f $ds9(frames) { set which "[msgcat::mc {Frame}] [string range $f 5 end]" $ds9(mb).frame.goto add radiobutton -label $which \ -variable ds9(next) -value $f -command GotoFrame # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 1 $ds9(mb).frame.goto entryconfig $which -columnbreak 1 } } # Active Frame Menu if {[$ds9(mb).frame.active index end] >= $ds9(menu,size,frame,active)} { $ds9(mb).frame.active delete $ds9(menu,size,frame,active) end } set cnt $ds9(menu,size,frame,active) foreach f $ds9(frames) { set which "[msgcat::mc {Frame}] [string range $f 5 end]" $ds9(mb).frame.active add checkbutton -label $which \ -variable active($f) -command UpdateActiveFrames # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 1 $ds9(mb).frame.active entryconfig $which -columnbreak 1 } } } �������������������������������������������������������������������������������������������������������./saods9/src/cpanda.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000006116�12004565227�013633� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PandaDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(which) panda set var(proc,apply) PandaApply set var(proc,close) PandaClose set var(proc,generate) PandaGenerate set var(proc,coordCB) PandaCoordCB set var(proc,editCB) PandaEditCB set var(proc,distCB) PandaDistCB # base panda dialog MarkerBasePandaDialog $varname set f $var(top).param # Radius ttk::label $f.tinner -text [msgcat::mc {Inner}] ttk::label $f.touter -text [msgcat::mc {Outer}] ttk::label $f.tradius -text [msgcat::mc {Radius}] ttk::entry $f.inner -textvariable ${varname}(inner) -width 13 ttk::entry $f.outer -textvariable ${varname}(outer) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list $var(proc,distCB) $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat # Annuli ttk::label $f.tannuli -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable ${varname}(annuli) -width 13 grid x $f.tinner $f.touter -padx 2 -pady 2 -sticky w grid $f.tradius $f.inner $f.outer $f.uradius -padx 2 -pady 2 -sticky w grid $f.tannuli $f.annuli -padx 2 -pady 2 -sticky w # init - do this last PandaDistCB $varname } # actions proc PandaClose {varname} { upvar #0 $varname var global $varname MarkerBasePandaClose $varname } proc PandaApply {varname} { upvar #0 $varname var global $varname MarkerBasePandaApply $varname } proc PandaGenerate {varname} { upvar #0 $varname var global $varname MarkerBaseAnnulusGenerateCircle $varname MarkerBasePandaGenerateAngles $varname } # callbacks proc PandaCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "PandaCoordCB" } MarkerBasePandaCoordCB $varname } proc PandaEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "PandaEditCB" } set t [$var(frame) get marker $var(id) panda radius \ $var(dcoord) $var(dformat)] set last [expr [llength $t]-1] set var(inner) [lindex $t 0] set var(outer) [lindex $t $last] set var(annuli) $last $var(annulitxt) delete 1.0 end $var(annulitxt) insert end "$t" set a [$var(frame) get marker $var(id) panda angle $var(system) $var(sky)] set last [expr [llength $a]-1] set var(ang1) [lindex $a 0] set var(ang2) [lindex $a $last] set var(angnum) $last $var(angtxt) delete 1.0 end $var(angtxt) insert end "$a" } proc PandaDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "PandaDistCB" } MarkerBasePandaDistCB $varname } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/circle.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000004630�12007016077�013642� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CircleDialog {varname} { upvar #0 $varname var global $varname global pmarker # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord # procs set var(proc,apply) CircleApply set var(proc,close) CircleClose set var(proc,coordCB) CircleCoordCB # base MarkerBaseCenterDialog $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisPlot3dDialog $varname # init CircleEditCB $varname # callbacks $var(frame) marker $var(id) callback edit CircleEditCB $varname set f $var(top).param # Radius ttk::label $f.tradius -text [msgcat::mc {Radius}] ttk::entry $f.radius -textvariable ${varname}(radius) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list CircleEditCB $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat grid $f.tradius $f.radius $f.uradius -padx 2 -pady 2 -sticky w } # actions proc CircleClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback edit CircleEditCB MarkerBaseCenterClose $varname } proc CircleApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) circle radius $var(radius) \ $var(dcoord) $var(dformat) MarkerBaseCenterApply $varname } # callbacks proc CircleCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "CircleCoordCB" } MarkerAnalysisStatsSystem $varname MarkerAnalysisPlot3dSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname } proc CircleEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "CircleEditCB" } set var(radius) [$var(frame) get marker $var(id) circle radius \ $var(dcoord) $var(dformat)] } ��������������������������������������������������������������������������������������������������������./saods9/src/ruler.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000005323�11732665742�013547� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc RulerDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set s [$var(frame) get marker $var(id) ruler system] set var(system) [lindex $s 0] set var(sky) [lindex $s 1] set var(skyformat) degrees set var(dcoord) [lindex $s 2] set var(dformat) [lindex $s 3] # procs set var(which) ruler set var(proc,apply) RulerApply set var(proc,coordCB) RulerCoordCB set var(proc,editCB) RulerEditCB set var(proc,distCB) RulerDistCB # base MarkerBaseLineDialog $varname 375 200 set f $var(top).param # Axis Length ttk::label $f.tlen -text [msgcat::mc {Axis Length}] ttk::label $f.rx -textvariable ${varname}(distx) -relief groove -width 12 ttk::label $f.ry -textvariable ${varname}(disty) -relief groove -width 12 ttk::label $f.ulen -textvariable ${varname}(dcoord,msg) grid $f.tlen $f.rx $f.ry $f.ulen -padx 2 -pady 2 -sticky w } # actions proc RulerApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) ruler point $var(system) $var(sky) \ $var(x) $var(y) $var(x2) $var(y2) MarkerBaseLineApply $varname } # callbacks proc RulerCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "RulerCoordCB" } MarkerBaseCoordCB $varname $var(frame) marker $var(id) ruler system $var(system) $var(sky) \ $var(dcoord) $var(dformat) RulerEditCB $varname } proc RulerEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "RulerEditCB" } MarkerBaseLineEditCB $varname set d [$var(frame) get marker $var(id) ruler length \ $var(dcoord) $var(dformat)] set var(dist) [lindex $d 0] set var(distx) [lindex $d 1] set var(disty) [lindex $d 2] set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] } proc RulerDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "RulerDistCB" } $var(frame) marker $var(id) ruler system $var(system) $var(sky) \ $var(dcoord) $var(dformat) set d [$var(frame) get marker $var(id) ruler length \ $var(dcoord) $var(dformat)] set var(dist) [lindex $d 0] set var(distx) [lindex $d 1] set var(disty) [lindex $d 2] } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/nsvr.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000013545�11700665571�013406� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc NSVRServer {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "NSVRServer $varname" } global nres global pnres ARStatus $varname "Looking up $var(name)" set ss [split $pnres(server) {-}] switch -- [lindex $ss 1] { eso - sao {set var(url) {http://vizier.cfa.harvard.edu/viz-bin/nph-sesame}} cds {set var(url) {http://cdsweb.u-strasbg.fr/cgi-bin/nph-sesame}} } append ${varname}(url) {/-ox} switch -- [lindex $ss 0] { ned {append ${varname}(url) {/N}} simbad {append ${varname}(url) {/S}} vizier {append ${varname}(url) {/V}} } set var(query) [http::formatQuery $var(name)] NSVRLoad $varname } proc NSVRLoad {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "NSVRLoad $varname $var(url) $var(query)" } set var(ra) {} set var(dec) {} set var(pos) {} global ihttp # -query will not work, do it manually if {$var(sync)} { if {![catch {set var(token) [http::geturl $var(url)?$var(query) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 NSVRLoadFinish $varname $var(token) } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } else { if {![catch {set var(token) [http::geturl $var(url)?$var(query) \ -protocol 1.0 \ -timeout $ihttp(timeout) \ -command \ [list NSVRLoadFinish $varname] \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } } proc NSVRLoadFinish {varname token} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "NSVRLoadFinish $varname" } if {!($var(active))} { ARCancelled $varname return } upvar #0 $token t # Code set code [http::ncode $token] # Meta set meta $t(meta) # Log it HTTPLog $token # Result? switch -- $code { 200 - 203 - 404 - 503 {NSVRSESAME $varname} 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $meta { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,image)} { puts stderr "NSVRLoadFinish redirect $code to $value" } # clean up and resubmit http::cleanup $token unset var(token) # strip query from url set var(url) [lindex [split $value {?}] 0] NSVRLoad $varname } } } default {ARError $varname "[msgcat::mc {Error code was returned}] $code"} } } proc NSVRSESAME {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "NSVRSESAME $varname" } set pp [xml::parser \ -characterdatacommand [list NSVRSESAMECharCB $varname]\ -elementstartcommand [list NSVRSESAMEElemStartCB $varname] \ -elementendcommand [list NSVRSESAMEElemEndCB $varname] \ -ignorewhitespace 1 \ ] set var(parse) {} if {[catch {$pp parse [http::data $var(token)]} err]} { $pp free NSVRParse $varname {} {} return } switch -- $var(skyformat) { degrees { if {$var(ra) != {} && $var(dec) != {}} { NSVRParse $varname $var(ra) $var(dec) } else { NSVRParse $varname {} {} } } sexagesimal { if {$var(pos) != {}} { # can have extra space chars, must clean up set ss [split [string trim $var(pos)]] NSVRParse $varname [lindex $ss 0] [lindex $ss end] } else { NSVRParse $varname {} {} } } } } proc NSVRSESAMECharCB {t data} { upvar #0 $t T global $t set state [lindex $T(parse) end] set prev [lindex $T(parse) end-1] switch -- $state { jpos { set T(pos) $data } jradeg { set T(ra) $data } jdedeg { set T(dec) $data } } return {} } proc NSVRSESAMEElemStartCB {t name attlist args} { upvar #0 $t T global $t lappend ${t}(parse) $name return {} } proc NSVRSESAMEElemEndCB {t name args} { upvar #0 $t T global $t set ${t}(parse) [lreplace $T(parse) end end] return {} } proc NSVRParse {varname x y} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "NSVRParse $varname $x $y" } set var(x) $x set var(y) $y if {($var(x) == {}) || ($var(y) == {})} { set var(x) {} set var(y) {} ARStatus $varname "$var(name) not found" ARReset $varname } else { if {$var(proc,next) != {}} { if {[info exists var(token)]} { http::cleanup $var(token) unset var(token) } eval $var(proc,next) $varname } else { ARDone $varname } } } proc NSVRServerMenu {varname} { upvar #0 $varname var global $varname $var(mb) add cascade -label [msgcat::mc {Name Server}] -menu $var(mb).name menu $var(mb).name NSVRServerMenuItems $var(mb).name } proc NSVRServerMenuItems {mm} { global nres $mm add radiobutton -label {NED@SAO} -variable pnres(server) \ -value ned-sao $mm add radiobutton -label {NED@CDS} -variable pnres(server) \ -value ned-cds $mm add separator $mm add radiobutton -label {SIMBAD@SAO} -variable pnres(server) \ -value simbad-sao $mm add radiobutton -label {SIMBAD@CDS} -variable pnres(server) \ -value simbad-cds $mm add separator $mm add radiobutton -label {VIZIER@SAO} -variable pnres(server) \ -value vizier-sao $mm add radiobutton -label {VIZIER@CDS} -variable pnres(server) \ -value vizier-cds } �����������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaicimagewfpc2.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000003473�12130604726�015626� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMosaicImageWFPC2File {fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image wfpc2} set loadParam(load,type) mmapincr set loadParam(file,name) $fn # mask not supported set loadParam(load,layer) {} ConvertFitsFile ProcessLoad } proc LoadMosaicImageWFPC2Alloc {path fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image wfpc2} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path # mask not supported set loadParam(load,layer) {} ProcessLoad } proc LoadMosaicImageWFPC2Socket {sock fn} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image wfpc2} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock # mask not supported set loadParam(load,layer) {} return [ProcessLoad 0] } proc ProcessMosaicImageWFPC2Cmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMosaicImageWFPC2Socket $sock $param]} { InitError xpa LoadMosaicImageWFPC2File $param } } else { # comm if {$fn != {}} { LoadMosaicImageWFPC2Alloc $fn $param } else { LoadMosaicImageWFPC2File $param } } FinishLoad } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/manalysis.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000051252�12033123212�014370� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc AnalysisMainMenu {} { global ds9 # WARNING: this is a variable length menu. # Be sure to update ds9(menu,size,analysis) menu $ds9(mb).analysis $ds9(mb).analysis add command -label "[msgcat::mc {Pixel Table}]..." \ -command PixelTableDialog $ds9(mb).analysis add separator $ds9(mb).analysis add command -label "[msgcat::mc {Mask Parameters}]..." \ -command MaskDialog $ds9(mb).analysis add separator $ds9(mb).analysis add checkbutton -label [msgcat::mc {Contours}] \ -variable contour(view) -command ContourUpdate $ds9(mb).analysis add command -label "[msgcat::mc {Contour Parameters}]..."\ -command ContourDialog $ds9(mb).analysis add separator $ds9(mb).analysis add checkbutton -label [msgcat::mc {Coordinate Grid}] \ -variable grid(view) -command GridUpdate $ds9(mb).analysis add command \ -label "[msgcat::mc {Coordinate Grid Parameters}]..." \ -command GridDialog $ds9(mb).analysis add separator $ds9(mb).analysis add checkbutton -label [msgcat::mc {Smooth}] \ -variable smooth(view) -command SmoothUpdate $ds9(mb).analysis add command -label "[msgcat::mc {Smooth Parameters}]..." \ -command SmoothDialog $ds9(mb).analysis add separator $ds9(mb).analysis add command -label "[msgcat::mc {Name Resolution}]..." \ -command NRESDialog $ds9(mb).analysis add separator $ds9(mb).analysis add cascade -label [msgcat::mc {Image Servers}] \ -menu $ds9(mb).analysis.image $ds9(mb).analysis add cascade -label [msgcat::mc {Archives}] \ -menu $ds9(mb).analysis.arch $ds9(mb).analysis add cascade -label [msgcat::mc {Catalogs}] \ -menu $ds9(mb).analysis.cat $ds9(mb).analysis add separator $ds9(mb).analysis add command -label "[msgcat::mc {Catalog Tool}]..." \ -command CATTool $ds9(mb).analysis add command -label "[msgcat::mc {Line Plot Tool}]..." \ -command PlotLineTool $ds9(mb).analysis add command -label "[msgcat::mc {Bar Plot Tool}]..." \ -command PlotBarTool $ds9(mb).analysis add command -label "[msgcat::mc {Scatter Plot Tool}]..." \ -command PlotScatterTool $ds9(mb).analysis add separator $ds9(mb).analysis add command -label "[msgcat::mc {Virtual Observatory}]..."\ -command VODialog $ds9(mb).analysis add command -label "[msgcat::mc {Web Browser}]..." \ -command {HV web Web {}} $ds9(mb).analysis add separator $ds9(mb).analysis add checkbutton \ -label [msgcat::mc {Analysis Command Log}] \ -variable panalysis(log) $ds9(mb).analysis add separator $ds9(mb).analysis add command \ -label "[msgcat::mc {Load Analysis Commands}]..." \ -command OpenAnalysisMenu $ds9(mb).analysis add command \ -label [msgcat::mc {Clear Analysis Commands}] \ -command ClearAnalysisMenu menu $ds9(mb).analysis.image $ds9(mb).analysis.image add command \ -label {SAO-DSS} -command SAODialog $ds9(mb).analysis.image add command \ -label {ESO-DSS I/II} -command ESODialog $ds9(mb).analysis.image add command \ -label {STSCI-DSS I/II} -command STSCIDialog $ds9(mb).analysis.image add command \ -label {IPAC-2MASS} -command 2MASSDialog $ds9(mb).analysis.image add command \ -label {NRAO-VLA FIRST} -command FIRSTDialog $ds9(mb).analysis.image add command \ -label {NRAO-NVSS} -command NVSSDialog $ds9(mb).analysis.image add command \ -label {HEASARC-SkyView} -command SkyViewDialog menu $ds9(mb).analysis.cat $ds9(mb).analysis.cat add command \ -label [msgcat::mc {Search for Catalogs}] \ -command "CATCDSSrchDialog catcdssrch1" $ds9(mb).analysis.cat add command -label [msgcat::mc {Clear All}] \ -command CATClearFrame $ds9(mb).analysis.cat add command -label [msgcat::mc {Match}] \ -command CATMatchFrame $ds9(mb).analysis.cat add separator CATCatalogMenu # Analysis Archive Menu menu $ds9(mb).analysis.arch $ds9(mb).analysis.arch add command -label {NVO Image Mosaic Service} \ -command HVArchMontage $ds9(mb).analysis.arch add separator $ds9(mb).analysis.arch add cascade -label {Chandra} \ -menu $ds9(mb).analysis.arch.chandra $ds9(mb).analysis.arch add command -label {ROSAT All-Sky (MPE/MPG)} \ -command HVArchRosat $ds9(mb).analysis.arch add separator $ds9(mb).analysis.arch add command -label {NVSS (NRAO)} \ -command HVArchNVSS $ds9(mb).analysis.arch add command -label {4MASS (NRAO)} \ -command HVArch4MASS $ds9(mb).analysis.arch add command -label {SIRTF FLS/VLA (NRAO)} \ -command HVArchSIRTF $ds9(mb).analysis.arch add command -label {VLA First (NRAO)} \ -command HVArchFirst menu $ds9(mb).analysis.arch.chandra $ds9(mb).analysis.arch.chandra add command \ -label {Chaser (NASA/SAO)} -command HVArchChandraChaser $ds9(mb).analysis.arch.chandra add command \ -label {Fast Image (NASA/SAO)} -command HVArchChandraPop $ds9(mb).analysis.arch.chandra add command \ -label {Public FTP (SAO)} -command HVArchChandraFTP menu $ds9(mb).analysis.arch.simbad $ds9(mb).analysis.arch.simbad add command -label {SAO} \ -command HVArchSIMBADSAO $ds9(mb).analysis.arch.simbad add command -label {CDS} \ -command HVArchSIMBADCDS menu $ds9(mb).analysis.arch.ads $ds9(mb).analysis.arch.ads add command -label {SAO} \ -command HVArchADSSAO $ds9(mb).analysis.arch.ads add command -label {CDS} \ -command HVArchADSCDS } proc UpdateAnalysisMenuStatic {} { global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateAnalysisMenuStatic" } if {$ds9(active,num) > 0} { $ds9(mb) entryconfig [msgcat::mc {Analysis}] -state normal } else { $ds9(mb) entryconfig [msgcat::mc {Analysis}] -state disabled } } proc UpdateAnalysisMenu {} { global ds9 global current global ianalysis global debug if {$debug(tcl,update)} { puts stderr "UpdateAnalysisMenu" } if {$current(frame) != {}} { for {set ii 0} {$ii<$ianalysis(menu,count)} {incr ii} { if {[$current(frame) has fits]} { set fn [$current(frame) get fits file name 1] } else { set fn {none} } # disable by default $ianalysis(menu,$ii,parent) entryconfig $ianalysis(menu,$ii,item) \ -state disabled foreach tt $ianalysis(menu,$ii,template) { if {[regexp ".$tt" $fn]} { $ianalysis(menu,$ii,parent) entryconfig \ $ianalysis(menu,$ii,item) -state normal break } } } } } proc PrefsDialogAnalysis {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Analysis}] lappend dprefs(tabs) [ttk::frame $w.analysis] set f [ttk::labelframe $w.analysis.file \ -text [msgcat::mc {Analysis File}]] ttk::checkbutton $f.auto -text [msgcat::mc {Autoload}] \ -variable panalysis(autoload) ttk::entry $f.pre -textvariable panalysis(user) -width 60 ttk::button $f.browse -text [msgcat::mc {Browse}] \ -command "AnalysisPrefOpen panalysis(user)" ttk::entry $f.pre2 -textvariable panalysis(user2) -width 60 ttk::button $f.browse2 -text [msgcat::mc {Browse}] \ -command "AnalysisPrefOpen panalysis(user2)" ttk::entry $f.pre3 -textvariable panalysis(user3) -width 60 ttk::button $f.browse3 -text [msgcat::mc {Browse}] \ -command "AnalysisPrefOpen panalysis(user3)" ttk::entry $f.pre4 -textvariable panalysis(user4) -width 60 ttk::button $f.browse4 -text [msgcat::mc {Browse}] \ -command "AnalysisPrefOpen panalysis(user4)" grid $f.auto -padx 2 -pady 2 -sticky w grid $f.pre $f.browse -padx 2 -pady 2 -sticky w grid $f.pre2 $f.browse2 -padx 2 -pady 2 -sticky w grid $f.pre3 $f.browse3 -padx 2 -pady 2 -sticky w grid $f.pre4 $f.browse4 -padx 2 -pady 2 -sticky w set f [ttk::labelframe $w.analysis.log -text [msgcat::mc {Analysis Log}]] ttk::checkbutton $f.log -text [msgcat::mc {Show Command}] \ -variable panalysis(log) grid $f.log -padx 2 -pady 2 -sticky w pack $w.analysis.file $w.analysis.log -side top -fill both -expand true } proc PrefsDialogPixelTable {} { global dprefs global ppixel set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Pixel Table}] lappend dprefs(tabs) [ttk::frame $w.pixel] set f [ttk::labelframe $w.pixel.param -text [msgcat::mc {Pixel Table}]] ttk::label $f.tsize -text [msgcat::mc {Size}] PrefsDialogPixelTableButtonCmd $ppixel(size) ttk::menubutton $f.size -textvariable dprefs(pixeltable,msg) \ -menu $f.size.menu global ipixel set m $f.size.menu menu $m for {set ii 3} {$ii<=$ipixel(max)} {incr ii 2} { $m add radiobutton -label "${ii}x${ii}" -variable ppixel(size) \ -value $ii -command [list PrefsDialogPixelTableButtonCmd $ii] } grid $f.tsize $f.size -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } proc PrefsDialogPixelTableButtonCmd {ii} { global dprefs global pixel set dprefs(pixeltable,msg) "${ii}x${ii}" } proc PrefsDialogContour {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Contours}] lappend dprefs(tabs) [ttk::frame $w.contour] set f [ttk::labelframe $w.contour.param -text [msgcat::mc {Contours}]] ttk::label $f.mtitle -text [msgcat::mc {Method}] ttk::menubutton $f.method -textvariable pcontour(method) \ -menu $f.method.menu global pcontour ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pcontour color {} ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::menubutton $f.width -textvariable pcontour(width) -menu $f.width.menu WidthDashMenu $f.width.menu pcontour width dash {} {} grid $f.mtitle $f.method -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color -padx 2 -pady 2 -sticky w grid $f.wtitle $f.width -padx 2 -pady 2 -sticky w set m $f.method.menu menu $m $m add radiobutton -label [msgcat::mc {Block}] \ -variable pcontour(method) -value block $m add radiobutton -label [msgcat::mc {Smooth}] \ -variable pcontour(method) -value smooth pack $f -side top -fill both -expand true } proc PrefsDialogSmooth {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Smooth}] lappend dprefs(tabs) [ttk::frame $w.smooth] set f [ttk::labelframe $w.smooth.param -text [msgcat::mc {Smooth}]] ttk::label $f.title -text [msgcat::mc {Function}] ttk::menubutton $f.function -textvariable psmooth(function) \ -menu $f.function.menu menu $f.function.menu $f.function.menu add radiobutton -label [msgcat::mc {Boxcar}] \ -variable psmooth(function) -value boxcar $f.function.menu add radiobutton -label [msgcat::mc {Tophat}] \ -variable psmooth(function) -value tophat $f.function.menu add radiobutton -label [msgcat::mc {Gaussian}] \ -variable psmooth(function) -value gaussian grid $f.title $f.function -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } proc PrefsDialogCatalog {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Catalogs}] lappend dprefs(tabs) [ttk::frame $w.cat] # Catalog set f [ttk::labelframe $w.cat.param -text [msgcat::mc {Catalogs}]] ttk::label $f.stitle -text [msgcat::mc {Server}] ttk::menubutton $f.svr -textvariable pcat(server) -menu $f.svr.menu ttk::label $f.shtitle -text [msgcat::mc {Shape}] ttk::menubutton $f.shape -textvariable pcat(sym,shape) -menu $f.shape.menu ttk::checkbutton $f.vot -variable pcat(vot) \ -text [msgcat::mc {Download VOTABLE format if available}] ttk::label $f.loctitle -text [msgcat::mc {IAU Location Code}] ttk::entry $f.loc -textvariable pcat(loc) -width 7 global pcat ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pcat sym,color {} ttk::label $f.ftitle -text [msgcat::mc {Font}] FontMenuButton $f.font pcat sym,font sym,font,size \ sym,font,weight, sym,font,slant {} menu $f.svr.menu $f.svr.menu add radiobutton -label {CDS} \ -variable pcat(server) -value cds $f.svr.menu add radiobutton -label {SAO} \ -variable pcat(server) -value sao $f.svr.menu add radiobutton -label {CADC} \ -variable pcat(server) -value cadc $f.svr.menu add radiobutton -label {ADAC} \ -variable pcat(server) -value adac $f.svr.menu add radiobutton -label {IUCAA} \ -variable pcat(server) -value iucaa $f.svr.menu add radiobutton -label {BEJING} \ -variable pcat(server) -value bejing $f.svr.menu add radiobutton -label {CAMBRIDGE UK} \ -variable pcat(server) -value cambridge $f.svr.menu add radiobutton -label {UKIRT HAWAII} \ -variable pcat(server) -value ukirt menu $f.shape.menu $f.shape.menu add radiobutton -label [msgcat::mc {Circle}] \ -variable pcat(sym,shape) -value circle $f.shape.menu add radiobutton -label [msgcat::mc {Ellipse}] \ -variable pcat(sym,shape) -value ellipse $f.shape.menu add radiobutton -label [msgcat::mc {Box}] \ -variable pcat(sym,shape) -value box $f.shape.menu add radiobutton -label [msgcat::mc {Text}] \ -variable pcat(sym,shape) -value text $f.shape.menu add cascade -label [msgcat::mc {Point}] \ -menu $f.shape.menu.point menu $f.shape.menu.point $f.shape.menu.point add radiobutton -label [msgcat::mc {Circle}] \ -variable pcat(sym,shape) -value {circle point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Box}] \ -variable pcat(sym,shape) -value {box point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Diamond}] \ -variable pcat(sym,shape) -value {diamond point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Cross}] \ -variable pcat(sym,shape) -value {cross point} $f.shape.menu.point add radiobutton -label [msgcat::mc {X}] \ -variable pcat(sym,shape) -value {x point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Arrow}] \ -variable pcat(sym,shape) -value {arrow point} $f.shape.menu.point add radiobutton -label [msgcat::mc {BoxCircle}] \ -variable pcat(sym,shape) -value {boxcircle point} $f.shape.menu.point add separator grid $f.stitle $f.svr -padx 2 -pady 2 -sticky w grid $f.shtitle $f.shape -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color -padx 2 -pady 2 -sticky w grid $f.ftitle $f.font -padx 2 -pady 2 -sticky w grid $f.loctitle - - $f.loc -padx 2 -pady 2 -sticky w grid $f.vot - - - -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } proc PrefsDialogPlot {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Plot}] lappend dprefs(tabs) [ttk::frame $w.plot] # Grid set f [ttk::labelframe $w.plot.grid -text [msgcat::mc {Grid}]] ttk::checkbutton $f.x -text [msgcat::mc {X Axis}] \ -variable pap(grid,x) ttk::radiobutton $f.xlinear -text [msgcat::mc {Linear}] \ -variable pap(grid,xlog) -value 0 ttk::radiobutton $f.xlog -text [msgcat::mc {Log}] \ -variable pap(grid,xlog) -value 1 ttk::checkbutton $f.y -text [msgcat::mc {Y Axis}] \ -variable pap(grid,y) ttk::radiobutton $f.ylinear -text [msgcat::mc {Linear}] \ -variable pap(grid,ylog) -value 0 ttk::radiobutton $f.ylog -text [msgcat::mc {Log}] \ -variable pap(grid,ylog) -value 1 grid $f.x $f.xlinear $f.xlog -padx 2 -pady 2 -sticky w grid $f.y $f.ylinear $f.ylog -padx 2 -pady 2 -sticky w # Font set f [ttk::labelframe $w.plot.font -text [msgcat::mc {Font}]] ttk::label $f.tnumlab -text [msgcat::mc {Axis Numbers}] FontMenuButton $f.numlab pap \ numlabFont numlabSize numlabWeight numlabSlant {} ttk::label $f.ttextlab -text [msgcat::mc {Axis Label}] FontMenuButton $f.textlab pap \ textlabFont textlabSize textlabWeight textlabSlant {} ttk::label $f.ttitle -text [msgcat::mc {Title}] FontMenuButton $f.title pap \ titleFont titleSize titleWeight titleSlant {} grid $f.tnumlab $f.numlab $f.ttextlab $f.textlab $f.ttitle $f.title \ -padx 2 -pady 2 -sticky w # Discrete set f [ttk::labelframe $w.plot.discrete -text [msgcat::mc {Discrete}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pap(discrete) ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pap discrete,color {} ttk::label $f.stitle -text [msgcat::mc {Symbol}] ttk::menubutton $f.symbol -textvariable pap(discrete,symbol) \ -menu $f.symbol.menu ttk::checkbutton $f.fill -text [msgcat::mc {Fill}] \ -variable pap(discrete,fill) grid $f.show -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color $f.stitle $f.symbol $f.fill \ -padx 2 -pady 2 -sticky w PlotLineSymbolMenu $f.symbol.menu pap(discrete,symbol) # Line set f [ttk::labelframe $w.plot.linear -text [msgcat::mc {Linear}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pap(linear) ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pap linear,color {} ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::menubutton $f.width -textvariable pap(linear,width) -menu $f.width.menu ttk::label $f.dtitle -text [msgcat::mc {Dash}] ttk::menubutton $f.dash -textvariable pap(linear,dash) -menu $f.dash.menu grid $f.show -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color $f.wtitle $f.width $f.dtitle $f.dash \ -padx 2 -pady 2 -sticky w PlotLineWidthMenu $f.width.menu pap(linear,width) PlotLineDashMenu $f.dash.menu pap(linear,dash) # Step set f [ttk::labelframe $w.plot.step -text [msgcat::mc {Step}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pap(step) ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pap step,color {} ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::menubutton $f.width -textvariable pap(step,width) -menu $f.width.menu ttk::label $f.dtitle -text [msgcat::mc {Dash}] ttk::menubutton $f.dash -textvariable pap(step,dash) -menu $f.dash.menu grid $f.show -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color $f.wtitle $f.width $f.dtitle $f.dash \ -padx 2 -pady 2 -sticky w PlotLineWidthMenu $f.width.menu pap(step,width) PlotLineDashMenu $f.dash.menu pap(step,dash) # Quadratic set f [ttk::labelframe $w.plot.quadratic -text [msgcat::mc {Quadratic}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pap(quadratic) ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pap quadratic,color {} ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::menubutton $f.width -textvariable pap(quadratic,width) \ -menu $f.width.menu ttk::label $f.dtitle -text [msgcat::mc {Dash}] ttk::menubutton $f.dash -textvariable pap(quadratic,dash) -menu $f.dash.menu grid $f.show -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color $f.wtitle $f.width $f.dtitle $f.dash \ -padx 2 -pady 2 -sticky w PlotLineWidthMenu $f.width.menu pap(quadratic,width) PlotLineDashMenu $f.dash.menu pap(quadratic,dash) # Error set f [ttk::labelframe $w.plot.error -text [msgcat::mc {Error}]] ttk::checkbutton $f.show -text [msgcat::mc {Show}] \ -variable pap(error) ttk::label $f.ctitle -text [msgcat::mc {Color}] ColorMenuButton $f.color pap error,color {} ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::menubutton $f.width -textvariable pap(error,width) -menu $f.width.menu grid $f.show -padx 2 -pady 2 -sticky w grid $f.ctitle $f.color $f.wtitle $f.width \ -padx 2 -pady 2 -sticky w PlotLineWidthMenu $f.width.menu pap(error,width) pack $w.plot.grid $w.plot.font $w.plot.discrete $w.plot.linear \ $w.plot.step $w.plot.quadratic $w.plot.error \ -side top -fill both -expand true } proc PrefsDialogVO {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {VO}] lappend dprefs(tabs) [ttk::frame $w.vo] # Browser set f [ttk::labelframe $w.vo.browser -text [msgcat::mc {Browser}]] ttk::checkbutton $f.web -text [msgcat::mc {Use Internal Web Browser}] \ -variable pvo(hv) ttk::radiobutton $f.xpa -text [msgcat::mc {Connect Directly}] \ -variable pvo(method) -value xpa -command PrefsVOMethod ttk::radiobutton $f.mime -text [msgcat::mc {Connect Using Web Proxy}] \ -variable pvo(method) -value mime -command PrefsVOMethod grid $f.web -padx 2 -pady 2 -sticky w grid $f.xpa $f.mime -padx 2 -pady 2 -sticky w # Server set f [ttk::labelframe $w.vo.server -text [msgcat::mc {VO Server}]] ttk::label $f.stitle -text [msgcat::mc {Default}] ttk::entry $f.server -textvariable pvo(server) -width 50 grid $f.stitle $f.server -padx 2 -pady 2 -sticky w # Keep-Alive set f [ttk::labelframe $w.vo.keep -text [msgcat::mc {Keep-Alive}]] ttk::label $f.dtitle -text [msgcat::mc {Minutes}] ttk::entry $f.delay -textvariable pvo(delay) -width 5 grid $f.dtitle $f.delay -padx 2 -pady 2 -sticky w pack $w.vo.browser $w.vo.server $w.vo.keep -side top -fill both -expand true } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerbasecenter.tcl�������������������������������������������������������������������0000644�0001750�0001750�00000004167�11700665570�015732� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBaseCenterDialog {varname} { upvar #0 $varname var global $varname # variables set var(x) 0 set var(y) 0 # base MarkerBaseDialog $varname # init MarkerBaseCenterMoveCB $varname # callbacks $var(frame) marker $var(id) callback move MarkerBaseCenterMoveCB $varname set f $var(top).param # Center ttk::label $f.tcenter -text [msgcat::mc {Center}] ttk::entry $f.centerx -textvariable ${varname}(x) -width 13 ttk::entry $f.centery -textvariable ${varname}(y) -width 13 CoordMenuButton $f.ucenter $varname system 1 sky skyformat \ [list $var(proc,coordCB) $varname] CoordMenuEnable $f.ucenter.menu $varname system 1 sky skyformat grid $f.tcenter $f.centerx $f.centery $f.ucenter -padx 2 -pady 2 -sticky w } proc MarkerBaseCenterClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback move MarkerBaseCenterMoveCB MarkerBaseClose $varname } proc MarkerBaseCenterApply {varname} { upvar #0 $varname var global $varname if {$var(x) != {} && $var(y) != {}} { $var(frame) marker $var(id) move to $var(system) $var(sky) \ $var(x) $var(y) } MarkerBaseApply $varname } proc MarkerBaseCenterRotate {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) angle $var(angle) $var(system) $var(sky) } # callbacks proc MarkerBaseCenterMoveCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseCenterMoveCB" } set center [$var(frame) get marker $var(id) center $var(system) $var(sky) \ $var(skyformat)] set var(x) [lindex $center 0] set var(y) [lindex $center 1] } proc MarkerBaseCenterRotateCB {varname {dummy {}}} { upvar #0 $varname var global $varname set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/stsci.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000012105�11700665572�013533� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc STSCIDef {} { global stsci global istsci set istsci(top) .stsci set istsci(mb) .stscimb set stsci(sky) fk5 set stsci(rformat) arcmin set stsci(width) 15 set stsci(height) 15 set stsci(mode) new set stsci(save) 0 set stsci(valid) 0 set stsci(survey) {all} } proc STSCIDialog {} { global stsci global istsci global wcs if [winfo exists $istsci(top)] { raise $istsci(top) return } set varname dstscii upvar #0 $varname var global $varname set var(top) $istsci(top) set var(mb) $istsci(mb) set var(sky) $stsci(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $stsci(rformat) set var(width) $stsci(width) set var(height) $stsci(height) set var(mode) $stsci(mode) set var(save) $stsci(save) set var(valid) $stsci(valid) set var(survey) $stsci(survey) set w $var(top) IMGSVRInit $varname "STSCI-DSS [msgcat::mc {Server}]" STSCIExec STSCIAck menu $var(mb).survey $var(mb) add cascade -label Survey -menu $var(mb).survey $var(mb).survey add radiobutton -label {POSS2/UKSTU Red} \ -variable ${varname}(survey) -value poss2ukstu_red $var(mb).survey add radiobutton -label {POSS2/UKSTU Infrared} \ -variable ${varname}(survey) -value poss2ukstu_ir $var(mb).survey add radiobutton -label {POSS2/UKSTU Blue} \ -variable ${varname}(survey) -value poss2ukstu_blue $var(mb).survey add radiobutton \ -label {POSS1 (First Generation) Blue} \ -variable ${varname}(survey) -value poss1_blue $var(mb).survey add radiobutton \ -label {POSS1 (First Generation) Red} \ -variable ${varname}(survey) -value poss1_red $var(mb).survey add radiobutton \ -label {Best of a combined list of all plates} \ -variable ${varname}(survey) -value all $var(mb).survey add radiobutton \ -label {Quick-V Survey} \ -variable ${varname}(survey) -value quickv $var(mb).survey add radiobutton \ -label {HST Phase 2 Target Positioning (GSC 2)} \ -variable ${varname}(survey) -value phase2_gsc2 $var(mb).survey add radiobutton \ -label {HST Phase 2 Target Positioning (GSC 1)} \ -variable ${varname}(survey) -value phase2_gsc1 IMGSVRUpdate $varname 1 } proc STSCIExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set compress none set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set compress gz set var(fn) [tmpnam ds9stsci ".fits.gz"] } # size - convert to arcmin switch -- $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } if {$ww>60} { set ww 60 } if {$hh>60} { set hh 60 } # query set var(query) [http::formatQuery r $var(x) d $var(y) e J2000 w $ww h $hh f fits c $compress v $var(survey)] set var(url) "http://stdatu.stsci.edu/cgi-bin/dss_search" IMGSVRLoad $varname } proc STSCIAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the DSS-STSCI The Digitized Sky Surveys were produced at the Space Telescope Science Institute under U.S. Government grant NAG W-2166. The images of these surveys are based on photographic data obtained using the Oschin Schmidt Telescope on Palomar Mountain and the UK Schmidt Telescope. The plates were processed into the present compressed digital form with the permission of these institutions. The National Geographic Society - Palomar Observatory Sky Atlas (POSS-I) was made by the California Institute of Technology with grants from the National Geographic Society. The Second Palomar Observatory Sky Survey (POSS-II) was made by the California Institute of Technology with funds from the National Science Foundation, the National Geographic Society, the Sloan Foundation, the Samuel Oschin Foundation, and the Eastman Kodak Corporation. The Oschin Schmidt Telescope is operated by the California Institute of Technology and Palomar Observatory. The UK Schmidt Telescope was operated by the Royal Observatory Edinburgh, with funding from the UK Science and Engineering Research Council (later the UK Particle Physics and Astronomy Research Council), until 1988 June, and thereafter by the Anglo-Australian Observatory. The blue plates of the southern Sky Atlas and its Equatorial Extension (together known as the SERC-J), as well as the Equatorial Red (ER), and the Second Epoch [red] Survey (SES) were all taken with the UK Schmidt. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessSTSCICmd {varname iname} { upvar $varname var upvar $iname i STSCIDialog IMGSVRProcessCmd $varname $iname dstscii } proc ProcessSendSTSCICmd {proc id param} { STSCIDialog IMGSVRProcessSendCmd $proc $id $param dstscii } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/bin.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000051401�12021722227�013144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BinDef {} { global bin global ibin global pbin global tcl_platform set ibin(top) .bl set ibin(mb) .blmb set bin(lock) 0 set bin(function) sum set bin(factor) { 1 1 } set bin(depth) 1 set bin(buffersize) 1024 array set pbin [array get bin] # prefs only set pbin(wheel) 0 set pbin(wheel,factor) 1.2 # special case switch -- $tcl_platform(os) { Darwin { switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 11 {set pbin(wheel,factor) 1.01} } } } } proc Bin {bx by} { global current if {$current(frame) != {}} { BinFrame $current(frame) $bx $by } } proc BinFrame {which bx by} { global bin global current global rgb RGBEvalLock rgb(lock,bin) $which [list $which bin factor $bx $by] if {$which == $current(frame)} { set bin(factor) "[$current(frame) get bin factor]" } UpdateBin } proc BinAbout {x y} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin about $x $y] UpdateBin } } proc BinAboutCenter {} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin about center] UpdateBin } } proc BinCols {x y z} { global bin global current global rgb if {$current(frame) != {}} { if {![$current(frame) has bin column $x]} { Error "[msgcat::mc {Invalid Column Name}] $x" return } if {![$current(frame) has bin column $y]} { Error "[msgcat::mc {Invalid Column Name}] $y" return } if {$z!={""}} { if {![$current(frame) has bin column $z]} { Error "[msgcat::mc {Invalid Column Name}] $z" return } } RGBEvalLockCurrent rgb(lock,bin) "$current(frame) bin cols \{$x\} \{$y\} \{$z\}" UpdateBin } } proc BinFilter {str} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) "$current(frame) bin filter \{\{$str\}\}" UpdateBin } } proc BinToFit {} { global current global bin global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin to fit] set bin(factor) "[$current(frame) get bin factor]" UpdateBin } } proc ChangeBinFactor {} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin factor to $bin(factor)] UpdateBin } } proc ChangeBinDepth {} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin depth $bin(depth)] UpdateBin } } proc ChangeBinFunction {} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin function $bin(function)] UpdateBin } } proc ChangeBinBufferSize {} { global bin global current global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,bin) [list $current(frame) bin buffer size $bin(buffersize)] UpdateBin } } proc UpdateBin {} { global current global debug if {$debug(tcl,update)} { puts stderr "UpdateBin" } LockBinCurrent UpdateBinDialog UpdateCropDialog UpdateScaleDialog UpdateContourDialog UpdateGraphXAxis $current(frame) UpdateMain } proc BinDialog {} { global bin global ibin global dbin global ds9 # see if we already have a window visible if [winfo exists $ibin(top)] { raise $ibin(top) return } # create the window set w $ibin(top) set mb $ibin(mb) Toplevel $w $mb 6 [msgcat::mc {Binning Parameters}] BinDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Method}] -menu $mb.method $mb add cascade -label [msgcat::mc {Block}] -menu $mb.block $mb add cascade -label [msgcat::mc {Buffer}] -menu $mb.buffer menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command BinApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Update Filter}] \ -command BinUpdateFilterDialog $mb.file add command -label [msgcat::mc {Clear Filter}] \ -command BinClearFilterDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command BinDestroyDialog EditMenu $mb ibin menu $mb.method $mb.method add radiobutton -label [msgcat::mc {Average}] \ -variable bin(function) -value average -command ChangeBinFunction $mb.method add radiobutton -label [msgcat::mc {Sum}] \ -variable bin(function) -value sum -command ChangeBinFunction menu $mb.block $mb.block add command -label [msgcat::mc {Block In}] \ -command {Bin .5 .5} $mb.block add command -label [msgcat::mc {Block Out}] \ -command {Bin 2 2} $mb.block add separator $mb.block add command -label [msgcat::mc {Block to Fit Frame}] \ -command BinToFit $mb.block add separator $mb.block add radiobutton -label "[msgcat::mc {Block}] 1" \ -variable bin(factor) -value { 1 1 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 2" \ -variable bin(factor) -value { 2 2 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 4" \ -variable bin(factor) -value { 4 4 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 8" \ -variable bin(factor) -value { 8 8 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 16" \ -variable bin(factor) -value { 16 16 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 32" \ -variable bin(factor) -value { 32 32 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 64" \ -variable bin(factor) -value { 64 64 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 128" \ -variable bin(factor) -value { 128 128 } -command ChangeBinFactor $mb.block add radiobutton -label "[msgcat::mc {Block}] 256" \ -variable bin(factor) -value { 256 256 } -command ChangeBinFactor menu $mb.buffer $mb.buffer add radiobutton -label {128x128} \ -variable bin(buffersize) -value 128 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {256x256} \ -variable bin(buffersize) -value 256 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {512x512} \ -variable bin(buffersize) -value 512 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {1024x1024} \ -variable bin(buffersize) -value 1024 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {2048x2048} \ -variable bin(buffersize) -value 2048 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {4096x4096} \ -variable bin(buffersize) -value 4096 -command ChangeBinBufferSize $mb.buffer add radiobutton -label {8192x8192} \ -variable bin(buffersize) -value 8192 -command ChangeBinBufferSize # Columns set f [ttk::labelframe $w.cols -text [msgcat::mc {Bin Columns}] -padding 2] ttk::label $f.title -text [msgcat::mc {Column}] ttk::label $f.titlefactor -text [msgcat::mc {Block}] ttk::label $f.titlemin -text [msgcat::mc {Min}] ttk::label $f.titlemax -text [msgcat::mc {Max}] ttk::menubutton $f.x -textvariable dbin(xcol) -menu $f.x.m -width 10 ttk::entry $f.xfactor -textvariable dbin(factor,x) -width 8 ttk::label $f.xmin -textvariable dbin(xcol,min) -width 12 -relief groove ttk::label $f.xmax -textvariable dbin(xcol,max) -width 12 -relief groove ttk::menubutton $f.y -textvariable dbin(ycol) -menu $f.y.m -width 10 ttk::entry $f.yfactor -textvariable dbin(factor,y) -width 8 ttk::label $f.ymin -textvariable dbin(ycol,min) -width 12 -relief groove ttk::label $f.ymax -textvariable dbin(ycol,max) -width 12 -relief groove grid $f.title $f.titlefactor $f.titlemin $f.titlemax -padx 2 -pady 2 grid $f.x $f.xfactor $f.xmin $f.xmax -padx 2 -pady 2 grid $f.y $f.yfactor $f.ymin $f.ymax -padx 2 -pady 2 # Center set f [ttk::labelframe $w.center -text [msgcat::mc {Bin Center}] -padding 2] ttk::entry $f.x -textvariable dbin(x) -width 12 ttk::entry $f.y -textvariable dbin(y) -width 12 ttk::checkbutton $f.auto -text [msgcat::mc {or center of data}] \ -variable dbin(auto) grid $f.x $f.y $f.auto -padx 2 -pady 2 # Filter set f [ttk::labelframe $w.filter -text [msgcat::mc {Bin Filter}] -padding 2] set dbin(filter,entry) \ [ttk::entry $f.filter -textvariable dbin(filter) -width 40] grid $f.filter -padx 2 -pady 2 # Bin 3rd Column set f [ttk::labelframe $w.z -text [msgcat::mc {Bin 3rd Column}] -padding 2] ttk::label $f.title -text [msgcat::mc {Column}] ttk::label $f.titledepth -text [msgcat::mc {Depth}] ttk::label $f.titlemin -text [msgcat::mc {Min}] ttk::label $f.titlemax -text [msgcat::mc {Max}] ttk::menubutton $f.z -textvariable dbin(zcol) -menu $f.z.m -width 10 ttk::entry $f.depth -textvariable dbin(depth) -width 8 ttk::entry $f.min -textvariable dbin(zcol,min) -width 12 ttk::entry $f.max -textvariable dbin(zcol,max) -width 12 grid $f.title $f.titledepth $f.titlemin $f.titlemax -padx 2 -pady 2 grid $f.z $f.depth $f.min $f.max -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command BinApplyDialog ttk::button $f.update -text [msgcat::mc {Update Filter}] \ -command BinUpdateFilterDialog ttk::button $f.clear -text [msgcat::mc {Clear Filter}] \ -command BinClearFilterDialog ttk::button $f.close -text [msgcat::mc {Close}] -command BinDestroyDialog pack $f.apply $f.update $f.clear $f.close \ -side left -expand true -padx 2 -pady 4 # Fini grid $w.cols -sticky news grid $w.center -sticky news grid $w.filter -sticky news grid $w.z -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid rowconfigure $w 2 -weight 1 grid rowconfigure $w 3 -weight 1 grid columnconfigure $w 0 -weight 1 $w.cols.xfactor select range 0 end set dbin(auto) 0 set dbin(minmax) 1 UpdateBinDialog } proc PopUp {b m l cmd} { global ds9 destroy $m menu $m -tearoff 0 set cnt -1 for {set ii 0} {$ii<[llength $l]} {incr ii} { $m add command -label [lindex $l $ii] \ -command "global dbin;set $b [lindex $l $ii]; $cmd" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $m entryconfig $ii -columnbreak 1 } } } proc BlankPopUp {m} { destroy $m menu $m -tearoff 0 } proc UpdateBinDialog {} { global bin global ibin global dbin global current global debug if {$debug(tcl,update)} { puts stderr "UpdateBinDialog" } if {![winfo exists $ibin(top)]} { return } if {$current(frame) == {}} { return } set w $ibin(top) if {[$current(frame) has fits bin]} { set bf "[$current(frame) get bin factor]" set dbin(factor,x) [lindex $bf 0] set dbin(factor,y) [lindex $bf 1] set cols [$current(frame) get bin cols] set colslist "[$current(frame) get bin list]" set dbin(xcol) [lindex $cols 0] set dbin(ycol) [lindex $cols 1] PopUp dbin(xcol) $w.cols.x.m $colslist UpdateXCol PopUp dbin(ycol) $w.cols.y.m $colslist UpdateYCol set mm [$current(frame) get bin cols minmax \{$dbin(xcol)\}] set dbin(xcol,min) [lindex $mm 0] set dbin(xcol,max) [lindex $mm 1] set mm [$current(frame) get bin cols minmax \{$dbin(ycol)\}] set dbin(ycol,min) [lindex $mm 0] set dbin(ycol,max) [lindex $mm 1] set cursor [$current(frame) get bin cursor] set dbin(x) [lindex $cursor 0] set dbin(y) [lindex $cursor 1] set dbin(filter) [$current(frame) get bin filter] set dbin(depth) [$current(frame) get bin depth] set dbin(zcol) [lindex $cols 2] PopUp dbin(zcol) $w.z.z.m $colslist UpdateZCol set mm [$current(frame) get bin cols dim \{$dbin(zcol)\}] set dbin(zcol,min) [lindex $mm 0] set dbin(zcol,max) [lindex $mm 1] } else { set dbin(factor,x) {} set dbin(factor,y) {} set dbin(xcol) {} set dbin(xcol,min) {} set dbin(xcol,max) {} set dbin(ycol) {} set dbin(ycol,min) {} set dbin(ycol,max) {} set dbin(x) {} set dbin(y) {} set dbin(filter) {} set dbin(depth) {} set dbin(zcol) {} set dbin(zcol,min) {} set dbin(zcol,max) {} BlankPopUp $w.cols.x.m BlankPopUp $w.cols.y.m BlankPopUp $w.z.z.m } } proc UpdateXCol {} { global current global dbin if {$current(frame) != {} && [$current(frame) has fits bin] && $dbin(xcol) != {}} { set mm [$current(frame) get bin cols minmax \{$dbin(xcol)\}] set dbin(xcol,min) [lindex $mm 0] set dbin(xcol,max) [lindex $mm 1] } else { set dbin(xcol,min) {} set dbin(xcol,max) {} } } proc UpdateYCol {} { global current global dbin if {$current(frame) != {} && [$current(frame) has fits bin] && $dbin(ycol) != {}} { set mm [$current(frame) get bin cols minmax \{$dbin(ycol)\}] set dbin(ycol,min) [lindex $mm 0] set dbin(ycol,max) [lindex $mm 1] } else { set dbin(ycol,min) {} set dbin(ycol,max) {} } } proc UpdateZCol {} { global current global dbin if {$current(frame) != {} && [$current(frame) has fits bin] && $dbin(zcol) != {}} { if {$dbin(minmax)} { set mm [$current(frame) get bin cols dim \{$dbin(zcol)\}] set dbin(zcol,min) [lindex $mm 0] set dbin(zcol,max) [lindex $mm 1] } } else { set dbin(zcol,min) {} set dbin(zcol,max) {} } } proc BinApplyDialog {} { global bin global dbin global current global rgb if {$current(frame) == {}} { # reset set dbin(auto) 0 return } # clean up filter if needed set dbin(filter) [string trimleft $dbin(filter)] set dbin(filter) [string trimright $dbin(filter)] # delete any markers if needed if {[$current(frame) has fits bin]} { set foo [$current(frame) get bin cols] set xcol [lindex $foo 0] set ycol [lindex $foo 1] if {$xcol != $dbin(xcol) || $ycol != $dbin(ycol)} { $current(frame) marker delete all } } if {$dbin(depth)>1} { CubeDialog if {$dbin(auto)} { if {$dbin(factor,x) != {} && $dbin(factor,y) != {} && $dbin(depth) != {} && $dbin(zcol,min) != {} && $dbin(zcol,max) != {} && $dbin(xcol) != {} && $dbin(ycol) != {} && $dbin(zcol) != {}} { RGBEvalLockCurrent rgb(lock,bin) \ [list $current(frame) bin to $dbin(factor,x) $dbin(factor,y) $dbin(depth) $dbin(zcol,min) $dbin(zcol,max) about center \{$dbin(xcol)\} \{$dbin(ycol)\} \{$dbin(zcol)\} \{$dbin(filter)\}] } } else { if {$dbin(factor,x) != {} && $dbin(factor,y) != {} && $dbin(depth) != {} && $dbin(zcol,min) != {} && $dbin(zcol,max) != {} && $dbin(x) != {} && $dbin(y) != {} && $dbin(xcol) != {} && $dbin(ycol) != {} && $dbin(zcol) != {}} { RGBEvalLockCurrent rgb(lock,bin) \ [list $current(frame) bin to $dbin(factor,x) $dbin(factor,y) $dbin(depth) $dbin(zcol,min) $dbin(zcol,max) about $dbin(x) $dbin(y) \{$dbin(xcol)\} \{$dbin(ycol)\} \{$dbin(zcol)\} \{$dbin(filter)\}] } } } else { if {$dbin(auto)} { if {$dbin(factor,x) != {} && $dbin(factor,y) != {} && $dbin(xcol) != {} && $dbin(ycol) != {}} { RGBEvalLockCurrent rgb(lock,bin) \ [list $current(frame) bin to $dbin(factor,x) $dbin(factor,y) about center \{$dbin(xcol)\} \{$dbin(ycol)\} \{$dbin(filter)\}] } } else { if {$dbin(factor,x) != {} && $dbin(factor,y) != {} && $dbin(x) != {} && $dbin(y) != {} && $dbin(xcol) != {} && $dbin(ycol) != {}} { RGBEvalLockCurrent rgb(lock,bin) \ [list $current(frame) bin to $dbin(factor,x) $dbin(factor,y) about $dbin(x) $dbin(y) \{$dbin(xcol)\} \{$dbin(ycol)\} \{$dbin(filter)\}] } } } UpdateCubeDialog UpdateCropDialog UpdateScaleMenu UpdateScaleDialog UpdateBinMenu UpdateBin # reset set dbin(auto) 0 } proc BinUpdateFilterDialog {} { global dbin global current $dbin(filter,entry) delete 0 end if {$current(frame) != {}} { $dbin(filter,entry) insert 0 \ [$current(frame) marker list ds9 physical fk5 degrees yes] } } proc BinClearFilterDialog {} { global dbin $dbin(filter,entry) delete 0 end } proc BinDestroyDialog {} { global ibin global dbin if {[winfo exists $ibin(top)]} { destroy $ibin(top) destroy $ibin(mb) } unset dbin } proc MatchBinCurrent {} { global current if {$current(frame) != {}} { MatchBin $current(frame) } } proc MatchBin {which} { global ds9 global rgb set factor [$which get bin factor] set depth [$which get bin depth] set filter [$which get bin filter] set size [$which get bin buffer size] set function [$which get bin function] set cols [$which get bin cols] foreach ff $ds9(frames) { if {$ff != $which} { RGBEvalLock rgb(lock,bin) $ff [list $ff bin factor to $factor] RGBEvalLock rgb(lock,bin) $ff [list $ff bin depth $depth] RGBEvalLock rgb(lock,bin) $ff "$ff bin filter \{\{$filter\}\}" RGBEvalLock rgb(lock,bin) $ff [list $ff bin buffer size $size] RGBEvalLock rgb(lock,bin) $ff [list $ff bin function $function] RGBEvalLock rgb(lock,bin) $ff "$ff bin cols \{\{[lindex $cols 0]\}\} \{\{[lindex $cols 1]\}\} \{\{[lindex $cols 2]\}\}" } } } proc LockBinCurrent {} { global current if {$current(frame) != {}} { LockBin $current(frame) } } proc LockBin {which} { global bin if {$bin(lock)} { MatchBin $which } } proc BinBackup {ch which} { switch [$which get type] { base - 3d {BinBackupBase $ch $which} rgb {BinBackupRGB $ch $which} } } proc BinBackupBase {ch which} { puts $ch "$which bin factor to [$which get bin factor]" puts $ch "$which bin depth [$which get bin depth]" puts $ch "$which bin filter \{\"[$which get bin filter]\"\}" puts $ch "$which bin buffer size [$which get bin buffer size]" set pos [$which get bin cursor] if {$pos != {}} { puts $ch "$which bin about $pos" } puts $ch "$which bin function [$which get bin function]" set cols [$which get bin cols] if {$cols != {}} { puts $ch "$which bin cols \{\"[lindex $cols 0]\"\} \{\"[lindex $cols 1]\"\} \{\"[lindex $cols 2]\"\} " } } proc BinBackupRGB {ch which} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" BinBackupBase $ch $which } $which rgb channel $sav puts $ch "$which rgb channel $sav" } # Process Cmds proc ProcessBinCmd {varname iname} { upvar $varname var upvar $iname i global bin switch -- [string tolower [lindex $var $i]] { close {BinDestroyDialog} open {BinDialog} match {MatchBinCurrent} lock { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set bin(lock) [FromYesNo [lindex $var $i]] } else { set bin(lock) 1 incr i -1 } LockBinCurrent } about { incr i switch [lindex $var $i] { center { BinAboutCenter } default { BinAbout [lindex $var [expr $i+0]] [lindex $var [expr $i+1]] incr i } } } buffersize { incr i set bin(buffersize) [lindex $var $i] ChangeBinBufferSize } cols { BinCols \"[lindex $var [expr $i+1]]\" \"[lindex $var [expr $i+2]]\" \"\" incr i 2 } colsz { BinCols \"[lindex $var [expr $i+1]]\" \"[lindex $var [expr $i+2]]\" \"[lindex $var [expr $i+3]]\" incr i 3 } factor { incr i set bx [lindex $var $i] set by [lindex $var [expr $i+1]] # note: the spaces are needed so that the menus are in sync if {$by != {} && [string is double $by]} { set bin(factor) " $bx $by " incr i } else { set bin(factor) " $bx $bx " } ChangeBinFactor } depth { incr i set bin(depth) [lindex $var $i] ChangeBinDepth } filter { incr i BinFilter [lindex $var $i] } function { incr i set bin(function) [string tolower [lindex $var $i]] ChangeBinFunction } to { # eat the 'fit' incr i BinToFit } } } proc ProcessSendBinCmd {proc id param} { global bin global current switch -- [string tolower [lindex $param 0]] { lock {$proc $id [ToYesNo $bin(lock)]} about { if {$current(frame) != {}} { $proc $id "[$current(frame) get bin cursor]\n" } } buffersize {$proc $id "$bin(buffersize)\n"} cols { if {$current(frame) != {}} { $proc $id "[$current(frame) get bin cols]\n" } } factor {$proc $id "$bin(factor)\n"} depth {$proc $id "$bin(depth)\n"} filter { if {$current(frame) != {}} { $proc $id "[$current(frame) get bin filter]\n" } } function {$proc $id "$bin(function)\n"} } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaicimageiraf.tcl��������������������������������������������������������������������0000644�0001750�0001750�00000003453�12130604726�015524� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMosaicImageIRAFFile {fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image iraf} set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer ConvertFitsFile ProcessLoad } proc LoadMosaicImageIRAFAlloc {path fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image iraf} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc LoadMosaicImageIRAFSocket {sock fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic image iraf} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc ProcessMosaicImageIRAFCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMosaicImageIRAFSocket $sock $param $layer]} { InitError xpa LoadMosaicImageIRAFFile $param $layer } } else { # comm if {$fn != {}} { LoadMosaicImageIRAFAlloc $fn $param $layer } else { LoadMosaicImageIRAFFile $param $layer } } FinishLoad } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/point.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000005635�12007016100�013523� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PointDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # procs set var(proc,apply) PointApply set var(proc,close) PointClose set var(proc,coordCB) PointCoordCB # base MarkerBaseCenterDialog $varname # menus $var(mb) add cascade -label [msgcat::mc {Shape}] -menu $var(mb).shape menu $var(mb).shape $var(mb).shape add radiobutton -label [msgcat::mc {Circle}] \ -variable ${varname}(shape) -value circle \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {Box}] \ -variable ${varname}(shape) -value box \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {Diamond}] \ -variable ${varname}(shape) -value diamond \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {Cross}] \ -variable ${varname}(shape) -value cross \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {X}] \ -variable ${varname}(shape) -value x \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {Arrow}] \ -variable ${varname}(shape) -value arrow \ -command "PointShape $varname" $var(mb).shape add radiobutton -label [msgcat::mc {BoxCircle}] \ -variable ${varname}(shape) -value boxcircle \ -command "PointShape $varname" # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis # plot3d MarkerAnalysisPlot3dDialog $varname # init set var(shape) [$var(frame) get marker $var(id) point shape] set var(size) [$var(frame) get marker $var(id) point size] set f $var(top).param # size ttk::label $f.tsize -text [msgcat::mc {Size}] ttk::entry $f.size -textvariable ${varname}(size) -width 13 ttk::label $f.usize -text [msgcat::mc {Pixels}] grid $f.tsize $f.size $f.usize -padx 2 -pady 2 -sticky w } # actions proc PointClose {varname} { upvar #0 $varname var global $varname MarkerBaseCenterClose $varname } proc PointApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) point size $var(size) MarkerBaseCenterApply $varname } # callbacks proc PointCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "PointCoordCB" } MarkerAnalysisPlot3dSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname } # support proc PointShape {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) point shape $var(shape) } ���������������������������������������������������������������������������������������������������./saods9/src/smooth.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000014204�12021722227�013705� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SmoothDef {} { global smooth global ismooth global psmooth set ismooth(top) .sm set ismooth(mb) .smmb set smooth(lock) 0 set smooth(view) 0 set smooth(function) gaussian set smooth(radius) 3 array set psmooth [array get smooth] } proc SmoothUpdate {} { global smooth global current global rgb SetWatchCursor if {$current(frame) != {}} { if {$smooth(view)} { RGBEvalLockCurrent rgb(lock,smooth) [list $current(frame) smooth $smooth(function) $smooth(radius)] } else { RGBEvalLockCurrent rgb(lock,smooth) [list $current(frame) smooth delete] } } LockSmoothCurrent UpdateContourDialog UpdateScaleDialog UpdateGraphXAxis $current(frame) UpdateMain UnsetWatchCursor } proc SmoothDialog {} { global ds9 global smooth global ismooth # see if we already have a window visible if [winfo exists $ismooth(top)] { raise $ismooth(top) return } # create the window set w $ismooth(top) set mb $ismooth(mb) Toplevel $w $mb 6 [msgcat::mc {Smooth Parameters}] SmoothDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command SmoothApplyDialog $mb.file add command -label [msgcat::mc {Clear}] -command SmoothOffDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command SmoothDestroyDialog EditMenu $mb ismooth # Function set f [ttk::labelframe $w.func -text [msgcat::mc {Function}] -padding 2] ttk::radiobutton $f.boxcar -text [msgcat::mc {Boxcar}] \ -variable smooth(function) -value boxcar ttk::radiobutton $f.tophat -text [msgcat::mc {Tophat}] \ -variable smooth(function) -value tophat ttk::radiobutton $f.gaussian -text [msgcat::mc {Gaussian}] \ -variable smooth(function) -value gaussian grid $f.boxcar $f.tophat $f.gaussian -padx 2 -pady 2 # Kernal set f [ttk::labelframe $w.rad -text [msgcat::mc {Kernel}] -padding 2] slider $f.slider 1 20 {Radius} smooth(radius) {} grid $f.slider -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command SmoothApplyDialog ttk::button $f.clear -text [msgcat::mc {Clear}] -command SmoothOffDialog ttk::button $f.close -text [msgcat::mc {Close}] -command SmoothDestroyDialog pack $f.apply $f.clear $f.close -side left -expand true -padx 2 -pady 4 # Fini grid $w.func -sticky news grid $w.rad -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 } proc SmoothApplyDialog {} { global smooth set smooth(view) 1 SmoothUpdate } proc SmoothDestroyDialog {} { global ismooth if {[winfo exists $ismooth(top)]} { destroy $ismooth(top) destroy $ismooth(mb) } } proc SmoothOffDialog {} { global smooth set smooth(view) 0 SmoothUpdate } proc UpdateSmoothMenu {} { global smooth global current global debug if {$debug(tcl,update)} { puts stderr "UpdateSmoothMenu" } if {$current(frame) != {}} { set smooth(view) [$current(frame) has smooth] set smooth(function) [$current(frame) get smooth function] set smooth(radius) [$current(frame) get smooth radius] } else { set smooth(view) 0 set smooth(function) gaussian set smooth(radius) 3 } } proc MatchSmoothCurrent {} { global current if {$current(frame) != {}} { MatchSmooth $current(frame) } } proc MatchSmooth {which} { global ds9 global rgb set view [$which has smooth] set function [$which get smooth function] set radius [$which get smooth radius] foreach ff $ds9(frames) { if {$ff != $which} { if {$view} { RGBEvalLock rgb(lock,smooth) $ff [list $ff smooth $function $radius] } else { RGBEvalLock rgb(lock,smooth) $ff [list $ff smooth delete] } } } } proc LockSmoothCurrent {} { global current if {$current(frame) != {}} { LockSmooth $current(frame) } } proc LockSmooth {which} { global smooth if {$smooth(lock)} { MatchSmooth $which } } proc SmoothBackup {ch which} { switch [$which get type] { base - 3d {SmoothBackupBase $ch $which} rgb {SmoothBackupRGB $ch $which} } } proc SmoothBackupBase {ch which} { if [$which has smooth] { set function [$which get smooth function] set radius [$which get smooth radius] puts $ch "$which smooth $function $radius" } } proc SmoothBackupRGB {ch which} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" SmoothBackupBase $ch $which } $which rgb channel $sav puts $ch "$which rgb channel $sav" } # Process Cmds proc ProcessSmoothCmd {varname iname} { upvar $varname var upvar $iname i global smooth switch -- [string tolower [lindex $var $i]] { open {SmoothDialog} close {SmoothDestroyDialog} match {MatchSmoothCurrent} lock { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set smooth(lock) [FromYesNo [lindex $var $i]] } else { set smooth(lock) 1 incr i -1 } LockSmoothCurrent } radius { incr i set smooth(radius) [lindex $var $i] SmoothUpdate } function { incr i set smooth(function) [lindex $var $i] SmoothUpdate } yes - true - on - 1 - no - false - off - 0 { set smooth(view) [FromYesNo [lindex $var $i]] SmoothUpdate } default { set smooth(view) 1 SmoothUpdate incr i -1 } } } proc ProcessSendSmoothCmd {proc id param} { global smooth switch -- [lindex $param 0] { lock {$proc $id [ToYesNo $smooth(lock)]} function {$proc $id "$smooth(function)\n"} radius {$proc $id "$smooth(radius)\n"} default {$proc $id [ToYesNo $smooth(view)]} } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/template.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000006774�11700665572�014240� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc TemplateDef {} { global itemplate # chandra set itemplate(chandra,acis,acis-i) {chandra/acis/acis-i.tpl} set itemplate(chandra,acis,acis-s) {chandra/acis/acis-s.tpl} set itemplate(chandra,acis,acis-is) {chandra/acis/acis-is.tpl} set itemplate(chandra,acis,acis-si) {chandra/acis/acis-si.tpl} set itemplate(chandra,hrc,hrc-i) {chandra/hrc/hrc-i.tpl} set itemplate(chandra,hrc,hrc-s) {chandra/hrc/hrc-s.tpl} # xmm set itemplate(xmm,epicmos1) {xmm/epicmos1.tpl} set itemplate(xmm,epicmos2) {xmm/epicmos2.tpl} set itemplate(xmm,epicpn) {xmm/epicpn.tpl} # heasarc # suzaku set itemplate(heasarc,suzaku,hxd) {heasarc/suzaku/hxd.tpl} set itemplate(heasarc,suzaku,xis) {heasarc/suzaku/xis.tpl} set itemplate(heasarc,suzaku,xrs) {heasarc/suzaku/xrs.tpl} # mmt # megacam set itemplate(mmt,megacam,megacam-amp) {mmt/megacam/megacam-amp.tpl} set itemplate(mmt,megacam,megacam-amp-guide) {mmt/megacam/megacam-amp-guide.tpl} set itemplate(mmt,megacam,megacam-chip) {mmt/megacam/megacam-chip.tpl} set itemplate(mmt,megacam,megacam-chip-guide) {mmt/megacam/megacam-chip-guide.tpl} # hecto set itemplate(mmt,hecto,hectospec) {mmt/hecto/hectospec.tpl} set itemplate(mmt,hecto,hectochelle) {mmt/hecto/hectochelle.tpl} # mmirs set itemplate(mmt,mmirs,image) {mmt/mmirs/image.tpl} set itemplate(mmt,mmirs,longslit) {mmt/mmirs/longslit.tpl} set itemplate(mmt,mmirs,mask) {mmt/mmirs/mask.tpl} # others set itemplate(mmt,swirc) {mmt/swirc.tpl} set itemplate(mmt,binospec) {mmt/binospec.tpl} } proc CreateFOVMenu {} { global ds9 global itemplate global marker set mm $ds9(mb).region.fov menu $mm set l0 {} set l1 {} set l2 {} foreach t [lsort [array names itemplate]] { set tt [split $t ","] set t0 [lindex $tt 0] set t1 [lindex $tt 1] set t2 [lindex $tt 2] if {$l0 != $t0} { menu $mm.$t0 $mm add cascade -label [string toupper $t0] -menu $mm.$t0 set l0 $t0 set l1 {} set l2 {} } if {$l1 != $t1} { if {$t2 != {}} { menu $mm.$t0.$t1 $mm.$t0 add cascade -label [string toupper $t1] \ -menu $mm.$t0.$t1 set l1 $t1 set l2 {} } else { $mm.$t0 add radiobutton \ -label [string toupper $t1] -variable marker(shape) \ -value $t continue } } $mm.$t0.$t1 add radiobutton -label [string toupper $t2] \ -variable marker(shape) -value $t } } proc OpenTemplateMarker {} { LoadTemplateMarker [OpenFileDialog templatefbox] } proc LoadTemplateMarker {fn} { global ds9 global current if {$current(frame) != {} && $fn != {}} { set cc [$ds9(canvas) coords $current(frame)] set ww [lindex [$current(frame) configure -width] 4] set hh [lindex [$current(frame) configure -height] 4] set xx [expr [lindex $cc 0]+$ww/2.0] set yy [expr [lindex $cc 1]+$hh/2.0] catch {$current(frame) marker create template "\{$fn\}" $xx $yy} } } proc LoadTemplateMarkerAt {fn ra dec sys sky} { global current if {$current(frame) != {} && $fn != {}} { catch {$current(frame) marker create template "\{$fn\}" $sys $sky $ra $dec} } } proc SaveAsTemplateMarker {} { global current if {$current(frame) != {}} { set fn [SaveFileDialog templatefbox] if {$fn != {}} { $current(frame) marker save template "\{$fn\}" } } } ����./saods9/src/mcolor.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000032700�11752033675�013704� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus # Default colormap names # [msgcat::mc {grey}] # [msgcat::mc {red}] # [msgcat::mc {green}] # [msgcat::mc {blue}] # [msgcat::mc {heat}] # [msgcat::mc {cool}] # [msgcat::mc {rainbow}] # [msgcat::mc {standard}] # [msgcat::mc {staircase}] # [msgcat::mc {color}] proc ColorMainMenu {} { global colorbar global icolorbar global ds9 menu $ds9(mb).color set id [colorbar list id] # base foreach jj $id { set name [colorbar get name $jj] $ds9(mb).color add radiobutton \ -label [msgcat::mc $name] \ -variable colorbar(map) -value $name \ -command "ChangeColormapID $jj" incr icolorbar(count) } # no contrib set icolorbar(contrib) $icolorbar(count) # no user set icolorbar(user) $icolorbar(contrib) $ds9(mb).color add separator $ds9(mb).color add cascade -label [msgcat::mc {Contributed}] \ -menu $ds9(mb).color.contrib $ds9(mb).color add cascade -label [msgcat::mc {User}] \ -menu $ds9(mb).color.user $ds9(mb).color add separator $ds9(mb).color add checkbutton -label [msgcat::mc {Invert Colormap}] \ -variable colorbar(invert) -command InvertColorbar $ds9(mb).color add command -label [msgcat::mc {Reset Colormap}] \ -command ResetColormap $ds9(mb).color add separator $ds9(mb).color add cascade -label [msgcat::mc {Colorbar}] \ -menu $ds9(mb).color.colorbar $ds9(mb).color add separator $ds9(mb).color add command -label "[msgcat::mc {Colormap Parameters}]..." \ -command ColormapDialog menu $ds9(mb).color.contrib menu $ds9(mb).color.user menu $ds9(mb).color.colorbar $ds9(mb).color.colorbar add cascade -label [msgcat::mc {Orientation}] \ -menu $ds9(mb).color.colorbar.orient $ds9(mb).color.colorbar add cascade -label [msgcat::mc {Numerics}] \ -menu $ds9(mb).color.colorbar.numerics $ds9(mb).color.colorbar add cascade -label [msgcat::mc {Font}] \ -menu $ds9(mb).color.colorbar.cb $ds9(mb).color.colorbar add separator $ds9(mb).color.colorbar add command \ -label "[msgcat::mc {Size}]..." \ -command ColorbarSizeDialog $ds9(mb).color.colorbar add command \ -label "[msgcat::mc {Number of Ticks}]..." \ -command TicksDialog menu $ds9(mb).color.colorbar.orient $ds9(mb).color.colorbar.orient add radiobutton \ -label [msgcat::mc {Horizontal}] -variable colorbar(orientation) \ -value horizontal -command UpdateView $ds9(mb).color.colorbar.orient add radiobutton \ -label [msgcat::mc {Vertical}] -variable colorbar(orientation) \ -value vertical -command UpdateView menu $ds9(mb).color.colorbar.numerics $ds9(mb).color.colorbar.numerics add checkbutton \ -label [msgcat::mc {Show}] -variable colorbar(numerics) \ -command UpdateView $ds9(mb).color.colorbar.numerics add separator $ds9(mb).color.colorbar.numerics add radiobutton \ -label [msgcat::mc {Space Equal Value}] -variable colorbar(space) \ -value 1 -command UpdateView $ds9(mb).color.colorbar.numerics add radiobutton \ -label [msgcat::mc {Space Equal Distance}] -variable colorbar(space) \ -value 0 -command UpdateView FontMenu $ds9(mb).color.colorbar.cb colorbar font font,size font,weight \ font,slant UpdateView CreateContribColorMenu } proc CreateContribColorMenu {} { global ds9 global icolorbar foreach fn $icolorbar(contrib,fn) { set ch [open "$ds9(root)/cmaps/$fn" r] global vardata set vardata [read $ch] close $ch colorbar load var "\{$fn\}" vardata set id [colorbar get id] set map [colorbar get name] incr icolorbar(user) incr icolorbar(count) $ds9(mb).color.contrib add radiobutton \ -label "$map" \ -variable map \ -command [list ChangeColormapID $id] } } proc PrefsDialogColorMenu {w} { global colorbar global icolorbar global pcolorbar set f [ttk::labelframe $w.mcolor -text [msgcat::mc {Color}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarColor $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 -sticky w set m $f.menu.menu menu $m set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $m add radiobutton -label [msgcat::mc $name] \ -variable pcolorbar(map) -value $name } # no contrib # no user $m add separator $m add checkbutton -label [msgcat::mc {Invert Colormap}] \ -variable pcolorbar(invert) $m add separator $m add cascade -label [msgcat::mc {Colorbar}] -menu $m.colorbar menu $m.colorbar $m.colorbar add cascade -label [msgcat::mc {Orientation}] \ -menu $m.colorbar.orient $m.colorbar add cascade -label [msgcat::mc {Numerics}] \ -menu $m.colorbar.numerics $m.colorbar add cascade -label [msgcat::mc {Font}] \ -menu $m.colorbar.cb menu $m.colorbar.orient $m.colorbar.orient add radiobutton -label [msgcat::mc {Horizontal}] \ -variable pcolorbar(orientation) -value horizontal $m.colorbar.orient add radiobutton -label [msgcat::mc {Vertical}] \ -variable pcolorbar(orientation) -value vertical menu $m.colorbar.numerics $m.colorbar.numerics add checkbutton -label [msgcat::mc {Show}] \ -variable pcolorbar(numerics) $m.colorbar.numerics add separator $m.colorbar.numerics add radiobutton \ -label [msgcat::mc {Space Equal Value}] \ -variable pcolorbar(space) -value 1 $m.colorbar.numerics add radiobutton \ -label [msgcat::mc {Space Equal Distance}] \ -variable pcolorbar(space) -value 0 FontMenu $m.colorbar.cb pcolorbar font font,size font,weight \ font,slant {} pack $f -side top -fill both -expand true } proc PrefsDialogColor {} { global dprefs global colorbar global icolorbar global pcolorbar set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Color}] lappend dprefs(tabs) [ttk::frame $w.color] set f [ttk::labelframe $w.color.colorbar -text [msgcat::mc {Colorbar}]] ttk::label $f.tsize -text [msgcat::mc {Colorbar Size}] ttk::entry $f.size -textvariable pcolorbar(size) -width 10 ttk::label $f.tticks -text [msgcat::mc {Number of Ticks}] ttk::entry $f.ticks -textvariable pcolorbar(ticks) -width 10 ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color pcolorbar tag {} grid $f.tsize $f.size -padx 2 -pady 2 -sticky w grid $f.tticks $f.ticks -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w pack $f -side top -fill both -expand true } # Buttons proc ButtonsColorDef {} { global pbuttons # we have a chicken or the egg problem # the colorbar has not been defined yet, but we must define vars # before prefs are processed, so hard code all default cmaps array set pbuttons { color,grey 1 color,red 0 color,green 0 color,blue 0 color,a 1 color,b 1 color,bb 1 color,he 1 color,i8 1 color,aips0 1 color,sls 0 color,hsv 0 color,heat 1 color,cool 1 color,rainbow 1 color,standard 0 color,staircase 0 color,color 0 color,invert 0 color,reset 0 color,horz 0 color,vert 0 color,numerics 0 color,numvalue 0 color,numspace 0 color,params 0 } } proc CreateButtonsColor {} { global buttons global ds9 global colorbar global icolorbar ttk::frame $ds9(buttons).color set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] RadioButton $ds9(buttons).color.$name [msgcat::mc $name] \ colorbar(map) $name "ChangeColormapID $jj" } # no contrib # no user CheckButton $ds9(buttons).color.invert \ [string tolower [msgcat::mc {Invert}]] colorbar(invert) InvertColorbar ButtonButton $ds9(buttons).color.reset \ [string tolower [msgcat::mc {Reset}]] ResetColormap RadioButton $ds9(buttons).color.horz \ [string tolower [msgcat::mc {Horizontal}]] \ colorbar(orientation) horizontal UpdateView RadioButton $ds9(buttons).color.vert \ [string tolower [msgcat::mc {Vertical}]] \ colorbar(orientation) vertical UpdateView CheckButton $ds9(buttons).color.numerics \ [string tolower [msgcat::mc {Numerics}]] \ colorbar(numerics) UpdateView RadioButton $ds9(buttons).color.numvalue \ [string tolower [msgcat::mc {Value}]] \ colorbar(space) 1 UpdateView RadioButton $ds9(buttons).color.numspace \ [string tolower [msgcat::mc {Distance}]] \ colorbar(space) 0 UpdateView ButtonButton $ds9(buttons).color.params \ [string tolower [msgcat::mc {Parameters}]] ColormapDialog set buttons(color) {} set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] append buttons(color) "$ds9(buttons).color.$name pbuttons(color,$name) " } # no contrib # no user append buttons(color) "$ds9(buttons).color.invert pbuttons(color,invert) " append buttons(color) "$ds9(buttons).color.reset pbuttons(color,reset) " append buttons(color) "$ds9(buttons).color.horz pbuttons(color,horz) " append buttons(color) "$ds9(buttons).color.vert pbuttons(color,vert) " append buttons(color) "$ds9(buttons).color.numerics pbuttons(color,numerics) " append buttons(color) "$ds9(buttons).color.numvalue pbuttons(color,numvalue) " append buttons(color) "$ds9(buttons).color.numspace pbuttons(color,numspace) " append buttons(color) "$ds9(buttons).color.params pbuttons(color,params) " } proc PrefsDialogButtonbarColor {f} { global icolorbar global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $m add checkbutton -label [msgcat::mc $name] \ -variable pbuttons(color,$name) \ -command {UpdateButtons buttons(color)} } # no contrib # no user $m add separator $m add checkbutton -label [msgcat::mc {Invert Colormap}] \ -variable pbuttons(color,invert) \ -command {UpdateButtons buttons(color)} $m add checkbutton -label [msgcat::mc {Reset Colormap}] \ -variable pbuttons(color,reset) \ -command {UpdateButtons buttons(color)} $m add separator $m add cascade -label [msgcat::mc {Colorbar}] -menu $m.colorbar $m add separator $m add checkbutton -label "[msgcat::mc {Colormap Parameters}]..." \ -variable pbuttons(color,params) \ -command {UpdateButtons buttons(color)} menu $m.colorbar $m.colorbar add cascade -label [msgcat::mc {Orientation}] \ -menu $m.colorbar.orient $m.colorbar add cascade -label [msgcat::mc {Numerics}] \ -menu $m.colorbar.numerics menu $m.colorbar.orient $m.colorbar.orient add checkbutton -label [msgcat::mc {Horizontal}] \ -variable pbuttons(color,horz) \ -command {UpdateButtons buttons(color)} $m.colorbar.orient add checkbutton -label [msgcat::mc {Vertical}] \ -variable pbuttons(color,vert) \ -command {UpdateButtons buttons(color)} menu $m.colorbar.numerics $m.colorbar.numerics add checkbutton -label [msgcat::mc {Show}] \ -variable pbuttons(color,numerics) \ -command {UpdateButtons buttons(color)} $m.colorbar.numerics add separator $m.colorbar.numerics add checkbutton -label [msgcat::mc {Equal Value}] \ -variable pbuttons(color,numvalue) \ -command {UpdateButtons buttons(color)} $m.colorbar.numerics add checkbutton -label [msgcat::mc {Equal Spacing}] \ -variable pbuttons(color,numspace) \ -command {UpdateButtons buttons(color)} } # Support proc UpdateColorMenu {} { global icolorbar global ds9 global current global buttons global debug if {$debug(tcl,update)} { puts stderr "UpdateColorMenu" } if {$current(frame) != {}} { switch [$current(frame) get type] { base - 3d { # menus # base for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $ds9(mb).color entryconfig $ii -state normal } $ds9(mb).color entryconfig [msgcat::mc {Contributed}] \ -state normal $ds9(mb).color entryconfig [msgcat::mc {User}] \ -state normal # buttons set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $ds9(buttons).color.$name configure -state normal } } rgb { # menus # base for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $ds9(mb).color entryconfig $ii -state disabled } $ds9(mb).color entryconfig [msgcat::mc {Contributed}] \ -state disabled $ds9(mb).color entryconfig [msgcat::mc {User}] \ -state disable # buttons set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $ds9(buttons).color.$name configure -state disabled } } } } else { # menus # base for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $ds9(mb).color entryconfig $ii -state normal } $ds9(mb).color entryconfig [msgcat::mc {Contributed}] -state normal $ds9(mb).color entryconfig [msgcat::mc {User}] -state normal # buttons set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $ds9(buttons).color.$name configure -state normal } } } ����������������������������������������������������������������./saods9/src/contour.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000065125�12131573627�014107� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ContourDef {} { global contour global icontour global pcontour set icontour(top) .ct set icontour(mb) .ctmb set contour(view) 0 set contour(copy) {} set contour(scale) linear set contour(log) 1000 set contour(mode) minmax set contour(min) {} set contour(max) {} # used for command line options set contour(init,scale) 0 set contour(init,mode) 0 set contour(init,limits) 0 set contour(method) block set contour(color) green set contour(width) 1 set contour(dash) 0 set contour(smooth) 4 set contour(numlevel) 5 set pcontour(method) $contour(method) set pcontour(color) $contour(color) set pcontour(width) $contour(width) set pcontour(dash) $contour(dash) set pcontour(smooth) $contour(smooth) set pcontour(numlevel) $contour(numlevel) } # special kludge to work around a infinit loop caused by cube.tcl and idletasks proc ContourUpdate {} { SetWatchCursor ContourUpdateNow UnsetWatchCursor } proc ContourUpdateNow {} { global contour global icontour global dcontour global current if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {$contour(view)} { ContourCheckParams if {[winfo exists $icontour(top)]} { set levels [$dcontour(txt) get 1.0 end] # remove endl and trim regsub -all "\n" $levels " " levels set levels [string trimright $levels " "] if {$levels == {}} { ContourGenerateDialog set levels [$dcontour(txt) get 1.0 end] # remove endl and trim regsub -all "\n" $levels " " levels set levels [string trimright $levels " "] } if {$levels != {}} { $current(frame) contour create \ $contour(color) $contour(width) $contour(dash) \ $contour(method) $contour(numlevel) \ $contour(smooth) \ $contour(scale) $contour(log) $contour(mode) \ $contour(min) $contour(max) \ "\"$levels\"" } } else { set contour(scale) [$current(frame) get colorscale] set contour(log) [$current(frame) get colorscale log] set contour(mode) [$current(frame) get clip mode] set limits [$current(frame) get clip $contour(mode)] set contour(min) [lindex $limits 0] set contour(max) [lindex $limits 1] $current(frame) contour create \ $contour(color) $contour(width) $contour(dash) \ $contour(method) $contour(numlevel) \ $contour(smooth) \ $contour(scale) $contour(log) $contour(mode) \ $contour(min) $contour(max) \ "{}" } } else { $current(frame) contour delete } } } } proc ContourCheckParams {} { global contour if {$contour(smooth) < 1} { set contour(smooth) 1 } if {$contour(numlevel) < 1} { set contour(numlevel) 1 } } proc ContourDialog {} { global contour global icontour global dcontour global current global ds9 # see if we already have a ctr window visible if [winfo exists $icontour(top)] { raise $icontour(top) return } # create the contour window set w $icontour(top) set mb $icontour(mb) Toplevel $w $mb 6 [msgcat::mc {Contour Parameters}] ContourDestroyDialog # local variables $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Color}] -menu $mb.color $mb add cascade -label [msgcat::mc {Width}] -menu $mb.width $mb add cascade -label [msgcat::mc {Scale}] -menu $mb.scale $mb add cascade -label [msgcat::mc {Limits}] -menu $mb.limit $mb add cascade -label [msgcat::mc {Method}] -menu $mb.method menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command ContourApplyDialog $mb.file add command -label [msgcat::mc {Generate}] \ -command ContourGenerateDialog $mb.file add command -label [msgcat::mc {Clear}] \ -command ContourOffDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Copy Contours}] \ -command ContourCCopyDialog $mb.file add command -label "[msgcat::mc {Paste Contours}]..." \ -command ContourCPasteDialog $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Contours}]..." \ -command ContourLoadDialog $mb.file add command -label "[msgcat::mc {Save Contours}]..." \ -command ContourSaveDialog $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Contour Levels}]..." \ -command ContourLoadLevels $mb.file add command -label "[msgcat::mc {Save Contour Levels}]..." \ -command ContourSaveLevels $mb.file add separator $mb.file add command -label [msgcat::mc {Convert to Polygons}] \ -command Contour2Polygons $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command ContourDestroyDialog menu $mb.edit $mb.edit add command -label [msgcat::mc {Cut}] \ -command ContourCutDialog -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command ContourCopyDialog -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -command ContourPasteDialog -accelerator "${ds9(ctrl)}V" ColorMenu $mb.color contour color ContourColorDialog WidthDashMenu $mb.width contour width dash \ ContourWidthDialog ContourDashDialog menu $mb.scale $mb.scale add radiobutton -label [msgcat::mc {Linear}] \ -variable contour(scale) -value linear $mb.scale add radiobutton -label [msgcat::mc {Log}] \ -variable contour(scale) -value log $mb.scale add radiobutton -label [msgcat::mc {Power}] \ -variable contour(scale) -value pow $mb.scale add radiobutton -label [msgcat::mc {Square Root}] \ -variable contour(scale) -value sqrt $mb.scale add radiobutton -label [msgcat::mc {Squared}] \ -variable contour(scale) -value squared $mb.scale add radiobutton -label {ASINH} \ -variable contour(scale) -value asinh $mb.scale add radiobutton -label {SINH} \ -variable contour(scale) -value sinh $mb.scale add radiobutton \ -label [msgcat::mc {Histogram Equalization}] \ -variable contour(scale) -value histequ $mb.scale add separator $mb.scale add command -label "[msgcat::mc {Log Exponent}]..." \ -command ContourLogDialog menu $mb.limit $mb.limit add radiobutton -label [msgcat::mc {Min Max}] \ -variable contour(mode) -value minmax -command ContourModeDialog $mb.limit add separator $mb.limit add radiobutton -label {99.5%} \ -variable contour(mode) -value 99.5 -command ContourModeDialog $mb.limit add radiobutton -label {99%} \ -variable contour(mode) -value 99 -command ContourModeDialog $mb.limit add radiobutton -label {98%} \ -variable contour(mode) -value 98 -command ContourModeDialog $mb.limit add radiobutton -label {95%} \ -variable contour(mode) -value 95 -command ContourModeDialog $mb.limit add radiobutton -label {90%} \ -variable contour(mode) -value 90 -command ContourModeDialog $mb.limit add separator $mb.limit add radiobutton -label {ZScale} \ -variable contour(mode) -value zscale -command ContourModeDialog $mb.limit add radiobutton -label {ZMax} \ -variable contour(mode) -value zmax -command ContourModeDialog $mb.limit add radiobutton -label [msgcat::mc {User}] \ -variable contour(mode) -value user -command ContourModeDialog menu $mb.method $mb.method add radiobutton -label [msgcat::mc {Block}] \ -variable contour(method) -value block $mb.method add radiobutton -label [msgcat::mc {Smooth}] \ -variable contour(method) -value smooth # Param set f [ttk::labelframe $w.param -text [msgcat::mc {Contour}] -padding 2] slider $f.nslider 0 50 [msgcat::mc {Levels}] contour(numlevel) {} slider $f.rslider 0 32 [msgcat::mc {Smoothness}] contour(smooth) {} ttk::label $f.title -text [msgcat::mc {Limits}] ttk::label $f.ltitle -text [msgcat::mc {Low}] ttk::entry $f.low -textvariable contour(min) -width 10 ttk::label $f.htitle -text [msgcat::mc {High}] ttk::entry $f.high -textvariable contour(max) -width 10 grid $f.nslider -columnspan 6 -padx 2 -pady 2 grid $f.rslider -columnspan 6 -padx 2 -pady 2 grid $f.title $f.ltitle $f.low $f.htitle $f.high -padx 2 -pady 2 # Levels set f [ttk::labelframe $w.levels -text [msgcat::mc {Levels}] -padding 2] set dcontour(txt) [text $f.text \ -wrap none \ -width 15 \ -height 10 \ -font [font actual TkDefaultFont] \ -yscrollcommand [list $f.yscroll set] \ ] ttk::scrollbar $f.yscroll -command [list $dcontour(txt) yview] \ -orient vertical grid $f.text $f.yscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command ContourApplyDialog ttk::button $f.generate -text [msgcat::mc {Generate}] \ -command ContourGenerateDialog ttk::button $f.clear -text [msgcat::mc {Clear}] \ -command ContourOffDialog ttk::button $f.close -text [msgcat::mc {Close}] \ -command ContourDestroyDialog pack $f.apply $f.generate $f.clear $f.close \ -side left -expand true -padx 2 -pady 4 # Fini grid $w.param $w.levels -sticky news grid $w.buttons - -sticky ew grid rowconfigure $w 0 -weight 1 grid columnconfigure $w 1 -weight 1 UpdateContourDialog } proc ContourApplyDialog {} { global contour set contour(view) 1 ContourUpdate } proc ContourDestroyDialog {} { global contour global icontour global dcontour if {[winfo exists $icontour(top)]} { destroy $icontour(top) destroy $icontour(mb) } unset dcontour } proc ContourGenerateDialog {} { global contour global dcontour global current ContourCheckParams $dcontour(txt) delete 1.0 end if {$current(frame) != {}} { if {([$current(frame) has fits]) && ($contour(min) != {}) && ($contour(max) != {})} { set ll [$current(frame) get colorscale level $contour(numlevel) \ $contour(min) $contour(max) \ $contour(scale) $contour(log)] regsub -all " " "$ll" "\n" ll $dcontour(txt) insert end "$ll" } } } proc ContourOffDialog {} { global contour global current set contour(view) 0 if {$current(frame) != {}} { $current(frame) contour delete all } UpdateContourDialog } proc ContourCutDialog {} { global icontour global dcontour if {[winfo exists $icontour(top)]} { set w [focus -displayof $icontour(top)] if {$w == $dcontour(txt)} { tk_textCut $w } else { EntryCut $icontour(top) } } } proc ContourCopyDialog {} { global icontour global dcontour if {[winfo exists $icontour(top)]} { set w [focus -displayof $icontour(top)] if {$w == $dcontour(txt)} { tk_textCopy $w } else { EntryCopy $icontour(top) } } } proc ContourPasteDialog {} { global icontour global dcontour if {[winfo exists $icontour(top)]} { set w [focus -displayof $icontour(top)] if {$w == $dcontour(txt)} { tk_textPaste $w } else { EntryPaste $icontour(top) } } } proc ContourCCopyDialog {} { global contour global current set contour(copy) $current(frame) UpdateContourDialog } proc ContourCPasteDialog {} { global contour global current if {$current(frame) != {} && $contour(copy) != {}} { ContourParamsDialog paste {} } } proc ContourColorDialog {} { global contour global current if {$current(frame) != {}} { $current(frame) contour color $contour(color) } } proc ContourWidthDialog {} { global contour global current if {$current(frame) != {}} { $current(frame) contour width $contour(width) } } proc ContourDashDialog {} { global contour global current if {$current(frame) != {}} { $current(frame) contour dash $contour(dash) } } proc ContourModeDialog {} { global current global contour if {$current(frame) != {}} { set limits [$current(frame) get clip $contour(mode)] set contour(min) [lindex $limits 0] set contour(max) [lindex $limits 1] } } proc ContourLoadLevels {} { set fn [OpenFileDialog contourlevfbox] ContourLoadLevelsNow $fn } proc ContourLoadLevelsNow {fn} { global dcontour if {$fn != {}} { set id [open $fn r] $dcontour(txt) delete 1.0 end $dcontour(txt) insert end [read $id] close $id } } proc ContourSaveLevels {} { set fn [SaveFileDialog contourlevfbox] ContourSaveLevelsNow $fn } proc ContourSaveLevelsNow {fn} { global dcontour if {$fn != {}} { set id [open $fn w] puts -nonewline $id "[$dcontour(txt) get 1.0 end]" close $id } } proc ContourSaveDialog {} { global current set fn [SaveFileDialog contourfbox] if {$fn != {}} { if {$current(frame) != {}} { ContourParamsDialog save $fn } } } proc ContourLoadDialog {} { global current set fn [OpenFileDialog contourfbox] if {$fn != {}} { if {$current(frame) != {}} { ContourParamsDialog load $fn } } } proc Contour2Polygons {} { global current global contour if {$current(frame) != {}} { $current(frame) contour create polygon \ color = $contour(color) width = $contour(width) $current(frame) contour delete } } proc UpdateContourMenu {} { global contour global current global debug if {$debug(tcl,update)} { puts stderr "UpdateContourMenu" } if {($current(frame) == {})} { return } if {[$current(frame) has fits]} { set contour(view) [$current(frame) has contour] } if {[$current(frame) has fits] && [$current(frame) has contour]} { set contour(method) [$current(frame) get contour method] set contour(color) [$current(frame) get contour color] set contour(width) [$current(frame) get contour width] set contour(dash) [$current(frame) get contour dash] set contour(numlevel) [$current(frame) get contour number level] set contour(smooth) [$current(frame) get contour smooth] } UpdateContourScale } proc UpdateContourScale {} { global contour global current global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateContourScale" } if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {[$current(frame) has contour]} { set contour(scale) [$current(frame) get contour colorscale] set contour(log) [$current(frame) get contour colorscale log] set contour(mode) [$current(frame) get contour clip mode] set limits [$current(frame) get contour clip] set contour(min) [lindex $limits 0] set contour(max) [lindex $limits 1] } else { if {!($ds9(init) && $contour(init,scale))} { set contour(scale) [$current(frame) get colorscale] set contour(log) [$current(frame) get colorscale log] } if {!($ds9(init) && $contour(init,mode))} { set contour(mode) [$current(frame) get clip mode] } if {!($ds9(init) && $contour(init,limits))} { set limits [$current(frame) get clip $contour(mode)] set contour(min) [lindex $limits 0] set contour(max) [lindex $limits 1] } } } } } proc UpdateContourDialog {} { global contour global icontour global dcontour global current global debug if {$debug(tcl,update)} { puts stderr "UpdateContourDialog" } if {[winfo exists $icontour(top)]} { if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {[$current(frame) has contour]} { set levels [$current(frame) get contour level] regsub -all "\n" "$levels" " " levels set levels [join $levels "\n"] if {$levels != {}} { $dcontour(txt) delete 1.0 end $dcontour(txt) insert end $levels } else { ContourGenerateDialog } } else { ContourGenerateDialog } } } } } proc ContourLogDialog {} { global contour EntryDialog [msgcat::mc {Scale}] [msgcat::mc {Log Exponent}] 10 contour(log) } proc ContourParamsDialog {action fn} { global ds9 global current global contour global ed global wcs set w {.ctld} set ed(ok) 0 set ed(system) wcs set ed(sky) fk5 set ed(color) green set ed(width) 1 set ed(dash) 0 set ed(frame) $current(frame) SetCoordSystem ed system sky {} AdjustCoordSystem ed system DialogCreate $w [msgcat::mc {Contour Parameters}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.coordtitle -text [msgcat::mc {Coordinate System}] switch -- $action { paste { CoordMenuButton $f.coordbutton ed system 1 {} {} {} CoordMenuEnable $f.coordbutton.menu ed system 1 {} {} } load - save { CoordMenuButton $f.coordbutton ed system 1 sky {} {} CoordMenuEnable $f.coordbutton.menu ed system 1 sky {} } } ttk::label $f.colortitle -text [msgcat::mc {Color}] ColorMenuButton $f.colorbutton ed color {} ttk::label $f.widthtitle -text [msgcat::mc {Width}] ttk::menubutton $f.widthbutton -textvariable ed(width) \ -menu $f.widthbutton.menu WidthDashMenu $f.widthbutton.menu ed width dash {} {} grid $f.coordtitle $f.coordbutton -padx 2 -pady 2 -sticky w if {$action != "save"} { grid $f.colortitle $f.colorbutton -padx 2 -pady 2 -sticky w grid $f.widthtitle $f.widthbutton -padx 2 -pady 2 -sticky w } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set ed(color) [string tolower $ed(color)] switch -- $action { paste { if {$current(frame) == $contour(copy)} { set sys image set ed(system) image } else { switch -- $ed(system) { image - physical - detector - amplifier {set sys $ed(system)} default {set sys [lindex [$contour(copy) get wcs] 0]} } } set ptr [$contour(copy) contour copy $sys fk5] if {$ptr != {}} { $current(frame) contour paste $ed(color) \ $ed(width) $ed(dash) $ptr $ed(system) fk5 } } load { switch -- $ed(system) { image - physical - detector - amplifier {set sys $ed(system)} default {set sys [lindex [$current(frame) get wcs] 0]} } $current(frame) contour load $ed(color) $ed(width) $ed(dash) \ "\{$fn\}" $sys $ed(sky) } save { switch -- $ed(system) { image - physical - detector - amplifier {set sys $ed(system)} default {set sys [lindex [$current(frame) get wcs] 0]} } $current(frame) contour save "\{$fn\}" $sys $ed(sky) } } UpdateContourDialog } set rr $ed(ok) unset ed return $rr } proc ContourBackup {ch which fdir rdir} { switch [$which get type] { base - 3d {ContourBackupBase $ch $which $fdir $rdir} rgb {ContourBackupRGB $ch $which $fdir $rdir} } } proc ContourBackupBase {ch which fdir rdir} { if [$which has contour] { set color [$which get contour color] set width [$which get contour width] set dash [$which get contour dash] set method [$which get contour method] set numlevel [$which get contour number level] set smooth [$which get contour smooth] set scale [$which get contour colorscale] set log [$which get contour colorscale log] set mode [$which get contour clip mode] set limits [$which get contour clip] set levels [$which get contour level] puts $ch "$which contour create $color $width $dash $method $numlevel $smooth $scale $log $mode $limits \{\"$levels\"\}" } # delete old contours foreach ff [glob -directory $fdir -nocomplain "aux*.con"] { catch {file delete -force $ff} } $which contour aux head set ii 0 while {[$which has contour aux]} { set fn $fdir/aux${ii}.con set rfn $rdir/aux${ii}.con set color [$which get contour aux color] set width [$which get contour aux width] set dash [$which get contour aux dash] $which contour aux save \"$fn\" physical fk5 puts $ch "$which contour load $color $width $dash \{\"$rfn\"\} physical fk5" incr ii $which contour aux next } } proc ContourBackupRGB {ch which fdir rdir} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" ContourBackupBase $ch $which $fdir $rdir } $which rgb channel $sav puts $ch "$which rgb channel $sav" } proc ProcessContourCmd {varname iname} { upvar $varname var upvar $iname i global contour global current # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { open {ContourDialog} close {ContourDestroyDialog} clear {ContourOffDialog} load { incr i set fn [lindex $var $i] incr i set sys [lindex $var $i] incr i set sky [lindex $var $i] incr i set color [lindex $var $i] incr i set width [lindex $var $i] incr i set dash [lindex $var $i] incr i [ProcessContourFix sys sky color width dash] if {$fn != {}} { $current(frame) contour load \ $color $width $dash "\{$fn\}" $sys $sky } FileLast contourfbox $fn UpdateContourDialog } save { incr i set fn [lindex $var $i] incr i set sys [lindex $var $i] incr i set sky [lindex $var $i] incr i set color {} incr i set width {} incr i set dash {} incr i [ProcessContourFix sys sky color width dash] if {$fn != {}} { $current(frame) contour save "\{$fn\}" $sys $sky } FileLast contourfbox $fn } convert {Contour2Polygons} loadlevels { ContourDialog incr i ContourLoadLevelsNow [lindex $var $i] ContourUpdate } savelevels { ContourDialog incr i ContourSaveLevelsNow [lindex $var $i] } copy {ContourCCopyDialog} paste { incr i set sys [lindex $var $i] incr i set sky [lindex $var $i] incr i set color [lindex $var $i] incr i set width [lindex $var $i] incr i set dash [lindex $var $i] incr i [ProcessContourFix sys sky color width dash] if {$current(frame) != {} && $contour(copy) != {}} { set ptr [$contour(copy) contour copy $sys $sky] if {$ptr != {}} { $current(frame) contour paste \ $color $width $dash $ptr $sys $sky } } } color { incr i set contour(color) [lindex $var $i] ContourColorDialog } width { incr i set contour(width) [lindex $var $i] ContourWidthDialog } dash { incr i set contour(dash) [FromYesNo [lindex $var $i]] ContourDashDialog } smooth { ContourDialog incr i set contour(smooth) [lindex $var $i] ContourGenerateDialog ContourUpdate } method { ContourDialog incr i set contour(method) [lindex $var $i] ContourGenerateDialog ContourUpdate } nlevels { ContourDialog incr i set contour(numlevel) [lindex $var $i] ContourGenerateDialog ContourUpdate } scale { set contour(init,scale) 1 ContourDialog incr i set contour(scale) [string tolower [lindex $var $i]] ContourGenerateDialog ContourUpdate } log { set contour(init,scale) 1 ContourDialog incr i switch -- [string tolower [lindex $var $i]] { exp { incr i set contour(log) [string tolower [lindex $var $i]] } default { incr i -1 set contour(log) [string tolower [lindex $var $i]] } } ContourGenerateDialog ContourUpdate } mode { set contour(init,mode) 1 ContourDialog incr i set contour(mode) [lindex $var $i] ContourModeDialog ContourGenerateDialog ContourUpdate } limits { set contour(init,limits) 1 ContourDialog incr i set contour(min) [lindex $var $i] incr i set contour(max) [lindex $var $i] ContourGenerateDialog ContourUpdate } levels { ContourDialog global dcontour $dcontour(txt) delete 1.0 end incr i $dcontour(txt) insert end [lindex $var $i] ContourUpdate } generate { ContourDialog ContourGenerateDialog ContourUpdate } yes - true - on - 1 - no - false - off - 0 { set contour(view) [FromYesNo [lindex $var $i]] ContourUpdate } default { set contour(view) 1 ContourUpdate incr i -1 } } } proc ProcessContourFix {sysname skyname colorname widthname dashname} { upvar $sysname sys upvar $skyname sky upvar $colorname color upvar $widthname width upvar $dashname dash set rr 0 switch -- $sys { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {} default { set dash $width set width $color set color $sky set sky $sys set sys wcs incr rr -1 } } switch -- $sky { fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic {} default { set dash $width set width $color set color $sky set sky fk5 incr rr -1 } } switch -- $color { white - black - red - green - blue - cyan - magenta - yellow {} default { if {[string range $color 0 0] != "#"} { set dash $width set width $color set color green incr rr -1 } } } if {![string is integer $width] || $width == {}} { set dash $width set width 1 incr rr -1 } switch -- $dash { yes - no - on - off - true - false - 0 - 1 {set dash [FromYesNo $dash]} default { set dash 0 incr rr -1 } } return $rr } proc ProcessSendContourCmd {proc id param sock fn} { global contour switch -- [lindex $param 0] { {} {$proc $id [ToYesNo $contour(view)]} color {$proc $id "$contour(color)\n"} width {$proc $id "$contour(width)\n"} dash {$proc $id [ToYesNo $contour(dash)]} smooth {$proc $id "$contour(smooth)\n"} method {$proc $id "$contour(method)\n"} nlevels {$proc $id "$contour(numlevel)\n"} scale {$proc $id "$contour(scale)\n"} log - {log exp} {$proc $id "$contour(log)\n"} mode {$proc $id "$contour(mode)\n"} limits {$proc $id "$contour(min) $contour(max)\n"} levels { global dcontour ContourDialog $proc $id "[$dcontour(txt) get 1.0 end]" } default { global current if {$current(frame) != {}} { ProcessSend $proc $id $sock $fn {.con} \ [$current(frame) get contour [lindex $param 0] [lindex $param 1]] } } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/export.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000016247�12100604045�013721� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ExportDef {} { global export set export(array,endian) native set export(nrrd,endian) native set export(jpeg,quality) 75 set export(tiff,compress) none } proc Export {fn format} { global export switch $format { array {ExportArrayFile $fn $export(array,endian)} rgbarray {ExportRGBArrayFile $fn $export(array,endian)} nrrd {ExportNRRDFile $fn $export(nrrd,endian)} gif {ExportPhotoFile $fn $format {}} tiff {ExportPhotoFile $fn $format $export(tiff,compress)} jpeg {ExportPhotoFile $fn $format $export(jpeg,quality)} png {ExportPhotoFile $fn $format {}} } } # Process Cmds proc ProcessExportCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 set format {} set fn [lindex $var $i] if {$fn == {}} { return } switch -- $fn { array - rgbarray - nrrd - gif - tiff - jpeg - png { set format $fn set fn {} incr i } jpg { set format jpeg set fn {} incr i } tif { set format tiff set fn {} incr i } } # one last time if {$fn == {}} { set fn [lindex $var $i] if {$fn == {}} { return } } if {$format == {}} { set format [ExtToFormat $fn] } global export set param [string tolower [lindex $var [expr $i+1]]] switch $format { array - rgbarray { switch $param { native - big - bigendian - little - littleendian { set export(array,endian) $param incr i } } } nrrd { switch $param { native - big - bigendian - little - littleendian { set export(nrrd,endian) $param incr i } } } gif {} jpeg { if {$param != {} && [string is integer $param]} { set export(jpeg,quality) $param incr i } } tiff { switch $param { none - jpeg - packbits - deflate { set export(tiff,compress) $param incr i } } } png {} } global arrayfbox global rgbarrayfbox global nrrdfbox global giffbox global jpegfbox global tifffbox global pngfbox switch -- $format { array {FileLast arrayfbox $fn} rgbarray {FileLast rgbarrayfbox $fn} nrrd {FileLast nrrdfbox $fn} gif {FileLast giffbox $fn} jpeg {FileLast jpegfbox $fn} tiff {FileLast tifffbox $fn} png {FileLast pngfbox $fn} } Export $fn $format } # Support proc ExportDialog {format} { global export global arrayfbox global rgbarrayfbox global nrrdfbox global giffbox global jpegfbox global tifffbox global pngfbox switch -- $format { array {set fn [SaveFileDialog arrayfbox]} rgbarray {set fn [SaveFileDialog rgbarrayfbox]} nrrd {set fn [SaveFileDialog nrrdfbox]} gif {set fn [SaveFileDialog giffbox]} jpeg {set fn [SaveFileDialog jpegfbox]} tiff {set fn [SaveFileDialog tifffbox]} png {set fn [SaveFileDialog pngfbox]} } if {$fn != {}} { set ok 1 switch -- $format { array {set ok [ArrayExportDialog export(array,endian)]} rgbarray {} nrrd {set ok [ArrayExportDialog export(nrrd,endian)]} gif {} jpeg {set ok [JPEGExportDialog export(jpeg,quality)]} tiff {set ok [TIFFExportDialog export(tiff,compress)]} png {} } if {$ok} { Export $fn $format } } } proc ArrayExportDialog {varname} { upvar $varname var global ed2 set w {.arr} set ed2(ok) 0 set ed2(arch) $var DialogCreate $w [msgcat::mc {Export Array}] ed2(ok) # Arch set f [ttk::labelframe $w.arch -text [msgcat::mc {Architecture}] -padding 2] ttk::radiobutton $f.native -text {Native} -variable ed2(arch) \ -value native ttk::radiobutton $f.big -text {Big-Endian} -variable ed2(arch) \ -value big ttk::radiobutton $f.little -text {Little-Endian} -variable ed2(arch) \ -value little grid $f.native -padx 2 -pady 2 -sticky w grid $f.big -padx 2 -pady 2 -sticky w grid $f.little -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini grid $w.arch -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set var $ed2(arch) } set rr $ed2(ok) unset ed2 return $rr } proc TIFFExportDialog {varname} { upvar $varname var global ed2 set w {.savetiff} set ed2(ok) 0 set ed2(compress) $var DialogCreate $w {TIFF} ed2(ok) # Param set f [ttk::frame $w.param] ttk::label $f.title -text [msgcat::mc {Compression}] ttk::radiobutton $f.none -text [msgcat::mc {None}] \ -variable ed2(compress) -value none ttk::radiobutton $f.jpeg -text {JPEG} \ -variable ed2(compress) -value jpeg ttk::radiobutton $f.packbits -text {Packbits} \ -variable ed2(compress) -value packbits ttk::radiobutton $f.deflate -text {Deflate} \ -variable ed2(compress) -value deflate grid $f.title -padx 2 -pady 2 -sticky w grid $f.none -padx 2 -pady 2 -sticky w grid $f.jpeg -padx 2 -pady 2 -sticky w grid $f.packbits -padx 2 -pady 2 -sticky w grid $f.deflate -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set var $ed2(compress) } set rr $ed2(ok) unset ed2 return $rr } proc JPEGExportDialog {varname} { upvar $varname var global ed2 set w {.savejpeg} set ed2(ok) 0 set ed2(quality) $var DialogCreate $w {JPEG} ed2(ok) # Param set f [ttk::frame $w.param] slider $f.squality 0 100 [msgcat::mc {JPEG Quality Factor}] \ ed2(quality) {} grid $f.squality -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed2(ok) DialogDismiss $w if {$ed2(ok)} { set var $ed2(quality) } set rr $ed2(ok) unset ed2 return $rr } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/error.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000003054�12114224330�013521� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # capture general errors # this only captures gui errors, not xpa errors proc bgerror {err} { global icursor tk_messageBox -type ok -icon error \ -message "[msgcat::mc {An internal error has been detected}] $err" # reset cursor set icursor(count) 0 UnsetWatchCursor } # force capture xpa/samp/hv/interactive errors proc InitError {which} { global ds9 set ds9(msg) {} set ds9(msg,level) info set ds9(msg,src) $which global errorInfo set errorInfo {} } proc Info {message} { ProcessMessage info $message } proc Warning {message} { ProcessMessage warning $message } # used by backup proc Error {message} { ProcessMessage error $message } proc ProcessMessage {level message} { global ds9 global pds9 set ds9(msg,level) $level switch -- $ds9(msg,src) { xpa - hv - samp {set ds9(msg) $message} default { if {$pds9(confirm)} { tk_messageBox -message $message -type ok -icon $level } } } } # here is where errors from within the canvas widgets # will try to get our attention. # XPA, HV, and SAMP will have already seen any problems proc ErrorTimer {} { global ds9 global pds9 if {$ds9(msg) != {}} { if {$pds9(confirm)} { tk_messageBox -message $ds9(msg) -type ok -icon $ds9(msg,level) } InitError tcl } # set again after $ds9(msg,timeout) ErrorTimer } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/dialog.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000031304�12131573630�013637� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc DialogCreate {top title varname} { global ds9 eval {toplevel $top} switch $ds9(wm) { x11 - win32 {} aqua { ::tk::unsupported::MacWindowStyle style $top document "closeBox fullZoom collapseBox resizable" bind $top <$ds9(ctrl)-`> "lower $top" } } wm title $top "$title" wm iconname $top "$title" upvar #0 varname var wm protocol $top WM_DELETE_WINDOW "set $varname 1" } proc DialogCenter {w} { global debug if {$debug(tcl,idletasks)} { puts stderr "DialogCenter" } global ds9 ::tk::PlaceWindow $w widget $ds9(top) } proc DialogWait {top varname {focus {}}} { upvar $varname var if {[string length $focus] == 0} { set focus $top } set old [focus -displayof $top] focus $focus catch {tkwait visibility $top} catch {grab $top} tkwait variable $varname catch {grab release $top} focus $old # reset errorInfo global errorInfo set errorInfo {} } proc DialogDismiss {w} { destroy $w } # Simple List Box proc SLBDialog {varname title width} { upvar $varname var global ed set w {.slb} set ed(ok) 0 DialogCreate $w $title ed(ok) # Lists set f [ttk::frame $w.ed] ttk::scrollbar $f.scroll -command "$f.box yview" set ed(listbox) [listbox $f.box \ -yscroll "$f.scroll set" \ -setgrid 1 \ -selectmode single] grid $f.box $f.scroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] \ -command {set ed(ok) 1} ttk::button $f.cancel -text [msgcat::mc {Cancel}] \ -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.ed -side top -fill both -expand true # init for {set i 1} {$i <= $var(count)} {incr i} { $w.ed.box insert end $var($i,item) } $w.ed.box selection set 0 bind $w <Double-1> {set ed(ok) 1} bind $w <Return> {set ed(ok) 1} bind $w <Up> "SLBArrow $ed(listbox) -1" bind $w <Down> "SLBArrow $ed(listbox) 1" DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok if {$ed(ok)} { set i [expr [$ed(listbox) curselection]+1] if {$i > 0 && $i <= $var(count)} { set var(item) $var($i,item) set var(value) $var($i,value) } } DialogDismiss $w set rr $ed(ok) unset ed return $rr } proc SLBArrow {lb dir} { set which [$lb curselection] if {$which == {}} { set which 0 } set end [$lb index end] $lb selection clear 0 end incr which $dir if {$which < 0} { set which 0 } if {$which >= $end} { set which [expr $end -1] } $lb selection set $which } # Entry Dialog proc EntryDialog {title message size varname} { upvar $varname var global ds9 global ed set w {.entry} set mb {.entrymb} set ed(top) $w set ed(ok) 0 set ed(text) $var DialogCreate $w $title ed(ok) $w configure -menu $mb menu $mb $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit EditMenu $mb ed # Param set f [ttk::frame $w.param] ttk::label $f.title -text $message ttk::entry $f.txt -textvariable ed(text) -width $size if {$size < 30} { grid $f.title $f.txt -padx 2 -pady 2 } else { grid $f.title -padx 2 -pady 2 -sticky w grid $f.txt -padx 2 -pady 2 } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w $w.param.txt select range 0 end DialogWait $w ed(ok) $w.param.txt if {$ed(ok)} { set var $ed(text) } DialogDismiss $w destroy $mb set rr $ed(ok) unset ed return $rr } # Entry Cut/Copy/Paste proc EntryCut {top} { set w [focus -displayof $top] if {![catch {set data [string range [$w get] [$w index sel.first] [expr {[$w index sel.last] - 1}]]}]} { clipboard clear -displayof $w clipboard append -displayof $w $data $w delete sel.first sel.last } } proc EntryCopy {top} { set w [focus -displayof $top] if {![catch {set data [string range [$w get] [$w index sel.first] [expr {[$w index sel.last] - 1}]]}]} { clipboard clear -displayof $w clipboard append -displayof $w $data } } proc EntryPaste {top} { set w [focus -displayof $top] catch {$w delete sel.first sel.last} if {![catch {$w insert insert [GetSelection $w]}]} { tk::EntrySeeInsert $w } } proc GetSelection {w} { if { ![catch {selection get -displayof $w -type UTF8_STRING} txt] || ![catch {selection get -displayof $w} txt] || ![catch {selection get -displayof $w -selection CLIPBOARD} txt] } { return $txt } } # Simple Text Dialog proc SimpleTextDialog {varname title width height action pos txt {destroyCB {}} {destroyParam {}}} { upvar #0 $varname var global $varname global ds9 global pds9 set var(top) ".${varname}" set var(mb) ".${varname}mb" if {[winfo exists $var(top)]} { raise $var(top) } else { # create window Toplevel $var(top) $var(mb) 7 $title "SimpleTextDestroy $varname" set var(search) {} set var(destroyCB) $destroyCB set var(destroyParam) $destroyParam set var(font) $pds9(text,font) set var(font,size) $pds9(text,font,size) set var(font,weight) $pds9(text,font,weight) set var(font,slant) $pds9(text,font,slant) $var(mb) add cascade -label [msgcat::mc {File}] -menu $var(mb).file menu $var(mb).file $var(mb).file add command -label "[msgcat::mc {Save}]..." \ -command "SimpleTextSave $varname" $var(mb).file add separator switch $ds9(wm) { x11 { $var(mb).file add command -label "[msgcat::mc {Print}]..." \ -command "SimpleTextPrint $varname" } win32 { $var(mb).file add command \ -label "[msgcat::mc {Page Setup}]..." \ -command "SimpleTextPageSetup $varname" $var(mb).file add command -label "[msgcat::mc {Print}]..." \ -command "SimpleTextPrint $varname" } aqua {} } $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Close}] \ -command "SimpleTextDestroy $varname" $var(mb) add cascade -label [msgcat::mc {Edit}] -menu $var(mb).edit menu $var(mb).edit $var(mb).edit add command -label [msgcat::mc {Cut}] \ -command "SimpleTextCut $varname" -accelerator "${ds9(ctrl)}X" $var(mb).edit add command -label [msgcat::mc {Copy}] \ -command "SimpleTextCopy $varname" -accelerator "${ds9(ctrl)}C" $var(mb).edit add command -label [msgcat::mc {Paste}] \ -state disabled -accelerator "${ds9(ctrl)}V" $var(mb).edit add command -label [msgcat::mc {Clear}] \ -command "SimpleTextClear $varname" $var(mb).edit add separator $var(mb).edit add command -label [msgcat::mc {Select All}] \ -command "SimpleTextSelectAll $varname" $var(mb).edit add command -label [msgcat::mc {Select None}] \ -command "SimpleTextSelectNone $varname" $var(mb).edit add separator $var(mb).edit add command -label "[msgcat::mc {Find}]..." \ -command "SimpleTextFind $varname" -accelerator "${ds9(ctrl)}F" $var(mb).edit add command -label [msgcat::mc {Find Next}] \ -command "SimpleTextFindNext $varname" -accelerator "${ds9(ctrl)}G" $var(mb) add cascade -label [msgcat::mc {Font}] -menu $var(mb).font FontMenu $var(mb).font $varname font font,size font,weight font,slant \ [list SimpleTextFont $varname] # create the text and scroll widgets set var(text) [text $var(top).text -height $height -width $width \ -wrap none \ -yscrollcommand [list $var(top).yscroll set] \ -xscrollcommand [list $var(top).xscroll set] \ ] ttk::scrollbar $var(top).yscroll -command [list $var(text) yview] \ -orient vertical ttk::scrollbar $var(top).xscroll -command [list $var(text) xview] \ -orient horizontal grid $var(text) $var(top).yscroll -sticky news grid $var(top).xscroll -stick news grid rowconfigure $var(top) 0 -weight 1 grid columnconfigure $var(top) 0 -weight 1 bind $var(top) <<Find>> [list SimpleTextFind $varname] bind $var(top) <<FindNext>> [list SimpleTextFindNext $varname] # some window managers need a hint raise $var(top) } $var(text) configure -state normal if {$action != {append}} { $var(text) delete 1.0 end } $var(text) insert end "$txt" switch -- $pos { top {$var(text) see 1.0} bottom {$var(text) see end} } # windows: we're on top of the image window, so set focus to this window switch $ds9(wm) { x11 {} win32 {focus $var(top)} aqua {} } SimpleTextFont $varname } proc SimpleTextDestroy {varname} { upvar #0 $varname var global $varname if {$var(destroyCB) != {}} { eval $var(destroyCB) $var(destroyParam) } if {[winfo exists $var(top)]} { destroy $var(top) destroy $var(mb) } unset $varname } proc SimpleTextFont {varname} { upvar #0 $varname var global $varname global ds9 $var(text) configure -font \ "{$ds9($var(font))} $var(font,size) $var(font,weight) $var(font,slant)" } proc SimpleTextCut {varname} { upvar #0 $varname var global $varname tk_textCut $var(text) } proc SimpleTextCopy {varname} { upvar #0 $varname var global $varname tk_textCopy $var(text) } proc SimpleTextClear {varname} { upvar #0 $varname var global $varname $var(text) configure -state normal $var(text) delete 1.0 end $var(text) configure -state disabled } proc SimpleTextSelectAll {varname} { upvar #0 $varname var global $varname $var(text) tag add sel 1.0 end } proc SimpleTextSelectNone {varname} { upvar #0 $varname var global $varname $var(text) tag remove sel 1.0 end } proc SimpleTextFind {varname} { upvar #0 $varname var global $varname $var(text) tag remove sel 1.0 end set result "$var(search)" if {[EntryDialog [msgcat::mc {Search}] [msgcat::mc {Enter Search Expression}] 40 result]} { set var(search) "$result" set start [$var(text) search -nocase -count cnt \ -regexp -- $result 1.0 end] if {$start != {}} { $var(text) tag add sel $start "$start + $cnt chars" $var(text) see $start } else { Error "$var(search) [msgcat::mc {Not Found}]" } } } proc SimpleTextFindNext {varname} { upvar #0 $varname var global $varname if {$var(search) != {}} { if {[$var(text) tag ranges sel] != {}} { set ss {sel.last} } else { set ss {1.0} } set start [$var(text) search -nocase -count cnt \ -regexp -- $var(search) $ss end] if {$start != {}} { $var(text) tag remove sel 1.0 end $var(text) tag add sel $start "$start + $cnt chars" $var(text) see $start } else { # wrap set start [$var(text) search -nocase -count cnt \ -regexp -- $var(search) 1.0 end] if {$start != {}} { $var(text) tag remove sel 1.0 end $var(text) tag add sel $start "$start + $cnt chars" $var(text) see $start } else { Error "$var(search) [msgcat::mc {Not Found}]" } } } } proc SimpleTextPrint {varname} { upvar #0 $varname var global $varname global ds9 switch $ds9(wm) { x11 {SimpleTextPSPrint $varname} win32 {win32 pm print text [$var(text) get 1.0 end]} aqua {macosx pm print text [$var(text) get 1.0 end]} } } proc SimpleTextPSPrint {varname} { upvar #0 $varname var global $varname global ps if {[PRPrintDialog]} { if {$ps(dest) == "file"} { catch {set ch [open "| cat > $ps(filename,txt)" w]} } else { catch {set ch [open "| $ps(cmd)" w]} } if {$ch != {}} { puts -nonewline $ch [$var(text) get 1.0 end] close $ch } else { Error [msgcat::mc {An error has occurred while printing}] return } } } proc SimpleTextPageSetup {varname} { upvar #0 $varname var global $varname global ds9 switch $ds9(wm) { x11 {} win32 {win32 pm pagesetup} aqua {macosx pm pagesetup} } } proc SimpleTextSave {varname} { upvar #0 $varname var global $varname set filename [SaveFileDialog textfbox] if {$filename != {}} { if {[catch {set ch [open "| cat > \"$filename\"" w]}]} { Error [msgcat::mc {An error has occurred while saving}] return } puts -nonewline $ch [$var(text) get 1.0 end] close $ch } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerbaseline.tcl���������������������������������������������������������������������0000644�0001750�0001750�00000005523�12005561301�015360� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBaseLineDialog {varname width height} { upvar #0 $varname var global $varname global pmarker # variables - some may already initialized (ruler) if {![info exists ${varname}(dcoord)]} { set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) } AdjustCoordSystem $varname dcoord # procs set var(proc,close) MarkerBaseLineClose # base MarkerBaseDialog $varname # init $var(proc,distCB) $varname # callbacks $var(frame) marker $var(id) callback move "$var(proc,editCB)" $varname $var(frame) marker $var(id) callback edit "$var(proc,editCB)" $varname set f $var(top).param # Points ttk::label $f.title -text [msgcat::mc {Points}] ttk::entry $f.x -textvariable ${varname}(x) -width 13 ttk::entry $f.y -textvariable ${varname}(y) -width 13 CoordMenuButton $f.coord $varname system 1 sky skyformat \ [list $var(proc,coordCB) $varname] CoordMenuEnable $f.coord.menu $varname system 1 sky skyformat ttk::entry $f.x2 -textvariable ${varname}(x2) -width 13 ttk::entry $f.y2 -textvariable ${varname}(y2) -width 13 # Length ttk::label $f.dtitle -text [msgcat::mc {Length}] ttk::label $f.dist -textvariable ${varname}(dist) \ -relief groove -width 12 DistMenuButton $f.udist $varname dcoord 1 dformat \ [list $var(proc,distCB) $varname] DistMenuEnable $f.udist.menu $varname dcoord 1 dformat # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::label $f.angle -textvariable ${varname}(angle) \ -relief groove -width 12 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid $f.title $f.x $f.y $f.coord -padx 2 -pady 2 -sticky w grid x $f.x2 $f.y2 -padx 2 -pady 2 -sticky w grid $f.dtitle $f.dist $f.udist -padx 2 -pady 2 -sticky w grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w } proc MarkerBaseLineClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback move "$var(proc,editCB)" $var(frame) marker $var(id) delete callback edit "$var(proc,editCB)" MarkerBaseClose $varname } proc MarkerBaseLineApply {varname} { upvar #0 $varname var global $varname MarkerBaseApply $varname } proc MarkerBaseLineEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBaseLineEditCB" } set p [$var(frame) get marker $var(id) $var(which) point $var(system) \ $var(sky) $var(skyformat)] set var(x) [lindex $p 0] set var(y) [lindex $p 1] set var(x2) [lindex $p 2] set var(y2) [lindex $p 3] } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markeranalysisradial.tcl���������������������������������������������������������������0000644�0001750�0001750�00000007600�12065130320�016573� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerAnalysisRadialDialog {varname} { upvar #0 $varname var global $varname set id $var(id) set frame $var(frame) set vvarname radial${id}${frame} upvar #0 $vvarname vvar global $vvarname set var(radial) [info exists ${vvarname}(top)] $var(mb).analysis add checkbutton -label [msgcat::mc {Radial Profile}] \ -variable ${varname}(radial) \ -command "MarkerAnalysisRadialCmd $varname" } proc MarkerAnalysisRadialCmd {varname} { upvar #0 $varname var global $varname MarkerAnalysisRadial $var(frame) $var(id) $var(radial) } proc MarkerAnalysisRadial {frame id radial} { $frame marker $id analysis radial $radial if {$radial} { MarkerAnalysisRadialCB $frame $id set vvarname radial${id}${frame} upvar #0 $vvarname vvar global $vvarname PlotRaise $vvarname } else { MarkerAnalysisRadialDeleteCB $frame $id } } proc MarkerAnalysisRadialSystem {varname} { upvar #0 $varname var global $varname if {[info exists var(radial)]} { if {$var(radial)} { MarkerAnalysisRadialCB $var(frame) $var(id) MarkerAnalysisRadialAxisTitle $var(frame) $var(id) } } } # hardcoded marker.C proc MarkerAnalysisRadialCB {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set vvarname radial${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists var(system)]} { set vvar(system) $var(system) set sys $var(system) } elseif {[info exists vvar(system)]} { set sys $vvar(system) } else { global wcs set vvar(system) $wcs(system) set sys $wcs(system) } set xdata radial${id}${frame}x set ydata radial${id}${frame}y set yedata radial${id}${frame}ye global $xdata $ydata $yedata if {[PlotPing $vvarname]} { $frame get marker $id analysis radial $xdata $ydata $yedata $sys PlotCreateErrorY $vvarname PlotStats $vvarname PlotList $vvarname } else { set tt [string totitle [$frame get marker $id type]] PlotLineDialog $vvarname $tt $tt $sys {} MarkerAnalysisRadialAxisTitle $frame $id set vvar(manage) 0 set vvar(dim) xyye set vvar(xdata) $xdata set vvar(ydata) $ydata set vvar(xedata) {} set vvar(yedata) $yedata blt::vector create $xdata $ydata $yedata $frame get marker $id analysis radial $xdata $ydata $yedata $sys PlotExternal $vvarname $vvar(proc,createelement) $vvarname $vvar(proc,updateelement) $vvarname $vvar(proc,updategraph) $vvarname PlotStats $vvarname PlotList $vvarname } } proc MarkerAnalysisRadialDeleteCB {frame id} { # this routine could be called by the region # after the dialog has been deleted set vvarname radial${id}${frame} upvar #0 $vvarname vvar global $vvarname # clear any errors global errorInfo set errorInfo {} PlotDestroy $vvarname } proc MarkerAnalysisRadialAxisTitle {frame id} { set vvarname radial${id}${frame} upvar #0 $vvarname vvar global $vvarname switch -- $vvar(system) { image - physical - amplifier - detector { set xtitle "Avg Radius (pixels)" set ytitle "Surface Brightness (cnts/pixels**2)" } default { if {[$frame has wcs equatorial $vvar(system)]} { set xtitle "Avg Radius (arcsecs)" set ytitle "Surface Brightness (cnts/arcsec**2)" } else { set xtitle "Avg Radius (pixels)" set ytitle "Surface Brightness (cnts/pixels**2)" } } } # set for plot code set vvar(graph,xaxis) $xtitle set vvar(graph,yaxis) $ytitle # update now (may not make it into plot code) $vvar(graph) xaxis configure -title $vvar(graph,xaxis) $vvar(graph) yaxis configure -title $vvar(graph,yaxis) $vvar(graph) xaxis configure -title $xtitle $vvar(graph) yaxis configure -title $ytitle } ��������������������������������������������������������������������������������������������������������������������������������./saods9/src/eso.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000010743�11700665567�013206� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ESODef {} { global eso global ieso set ieso(top) .eso set ieso(mb) .esomb set eso(sky) fk5 set eso(rformat) arcmin set eso(width) 15 set eso(height) 15 set eso(mode) new set eso(save) 0 set eso(valid) 0 set eso(survey) {DSS1} } proc ESODialog {} { global eso global ieso global wcs if [winfo exists $ieso(top)] { raise $ieso(top) return } set varname deso upvar #0 $varname var global $varname set var(top) $ieso(top) set var(mb) $ieso(mb) set var(sky) $eso(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $eso(rformat) set var(width) $eso(width) set var(height) $eso(height) set var(survey) $eso(survey) set var(mode) $eso(mode) set var(save) $eso(save) set var(valid) $eso(valid) set w $var(top) IMGSVRInit $varname "ESO-DSS [msgcat::mc {Server}]" ESOExec ESOAck $var(mb) add cascade -label Survey -menu $var(mb).survey menu $var(mb).survey # these must be Caps, the server will not accept lower case $var(mb).survey add radiobutton -label {DSS1} \ -variable ${varname}(survey) -value DSS1 $var(mb).survey add radiobutton -label {DSS2-red} \ -variable ${varname}(survey) -value DSS2-red $var(mb).survey add radiobutton -label {DSS2-blue} \ -variable ${varname}(survey) -value DSS2-blue $var(mb).survey add radiobutton -label {DSS2-infrared} \ -variable ${varname}(survey) -value DSS2-infrared IMGSVRUpdate $varname 1 } proc ESOExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set mime "application/x-fits" set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set mime "display/gz-fits" set var(fn) [tmpnam ds9eso ".fits.gz"] } # size - convert to arcmin switch -- $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } if {$ww>60} { set ww 60 } if {$hh>60} { set hh 60 } # query set query [http::formatQuery ra $var(x) dec $var(y) equinox J2000 x $ww y $hh mime-type $mime Sky-Survey $var(survey)] set var(query) {} # Load image # we can't use -query because eso needs a GET not a POST set var(url) "http://archive.eso.org/dss/dss?$query" IMGSVRLoad $varname } proc ESOAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the ESO The Digitized Sky Surveys were produced at the Space Telescope Science Institute under U.S. Government grant NAG W-2166. The images of these surveys are based on photographic data obtained using the Oschin Schmidt Telescope on Palomar Mountain and the UK Schmidt Telescope. The plates were processed into the present compressed digital form with the permission of these institutions. The National Geographic Society - Palomar Observatory Sky Atlas (POSS-I) was made by the California Institute of Technology with grants from the National Geographic Society. The Second Palomar Observatory Sky Survey (POSS-II) was made by the California Institute of Technology with funds from the National Science Foundation, the National Geographic Society, the Sloan Foundation, the Samuel Oschin Foundation, and the Eastman Kodak Corporation. The Oschin Schmidt Telescope is operated by the California Institute of Technology and Palomar Observatory. The UK Schmidt Telescope was operated by the Royal Observatory Edinburgh, with funding from the UK Science and Engineering Research Council (later the UK Particle Physics and Astronomy Research Council), until 1988 June, and thereafter by the Anglo-Australian Observatory. The blue plates of the southern Sky Atlas and its Equatorial Extension (together known as the SERC-J), as well as the Equatorial Red (ER), and the Second Epoch [red] Survey (SES) were all taken with the UK Schmidt. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessESOCmd {varname iname} { upvar $varname var upvar $iname i ESODialog IMGSVRProcessCmd $varname $iname deso } proc ProcessSendESOCmd {proc id param} { ESODialog IMGSVRProcessSendCmd $proc $id $param deso } �����������������������������./saods9/src/macosx.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000003575�12077601007�013702� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # ::tk::mac::OpenApplication # ::tk::mac::ReopenApplication proc ::tk::mac::OpenDocument {args} { global ds9 set ds9(event,opendoc) $args if {!$ds9(init)} { MacOSXOpenDocEvent 1 } } proc ::tk::mac::PrintDocument {args} { global ds9 set ds9(event,printdoc) $args if {!$ds9(init)} { MacOSXPrintDocEvent 0 } } proc ::tk::mac::ShowPreferences {} { PrefsDialog } proc ::tk::mac::Quit {args} { QuitDS9 } proc MacOSXOpenDocEvent {fc} { global ds9 if {$ds9(event,opendoc) != {}} { StartLoad foreach f $ds9(event,opendoc) { MultiLoad LoadFitsFile $f {} {} FileLastFull fitsfbox $f } FinishLoad } } proc MacOSXPrintDocEvent {bye} { global ds9 if {$ds9(event,printdoc) != {}} { set fc 0 foreach f $ds9(event,printdoc) { RealizeDS9 StartLoad MultiLoad LoadFitsFile $f {} {} FileLastFull fitsfbox $f FinishLoad MacOSXPrintPre } if {$bye} { Quit } } } proc MacOSXGetLocale {} { return [macosx locale] } proc MacOSXPrint {} { global ds9 # we need to be realized RealizeDS9 # need the colorbar levels updated UpdateColormapLevel if {[macosx pm print begin [winfo width $ds9(canvas)] [winfo height $ds9(canvas)] yes]} { foreach f $ds9(frames) { $f macosx print } colorbar macosx print colorbarrgb macosx print macosx pm print end } } proc MacOSXPrintPre {} { global ds9 if {[macosx pm print begin [winfo width $ds9(canvas)] [winfo height $ds9(canvas)] no]} { foreach f $ds9(frames) { $f macosx print } colorbar macosx print colorbarrgb macosx print macosx pm print end } } proc MacOSXPageSetup {} { macosx pm pagesetup } �����������������������������������������������������������������������������������������������������������������������������������./saods9/src/import.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000013157�12123112767�013721� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc Import {fn format layer mode} { global current if {$fn == {}} { return } StartLoad switch -- $format { array {ImportArrayFile $fn $layer} rgbarray { switch -- [$current(frame) get type] { base - 3d {CreateRGBFrame} rgb {} } ImportRGBArrayFile $fn } nrrd {ImportNRRDFile $fn $layer} gif - tiff - jpeg - png {ImportPhotoFile $fn $mode} } FinishLoad } # Support proc ImportDialog {format {layer {}} {mode {}}} { global arrayfbox global rgbarrayfbox global nrrdfbox global giffbox global jpegfbox global tifffbox global pngfbox switch -- $format { array {set fn [OpenFileDialog arrayfbox]} rgbarray {set fn [OpenFileDialog rgbarrayfbox]} nrrd {set fn [OpenFileDialog nrrdfbox]} gif {set fn [OpenFileDialog giffbox]} jpeg {set fn [OpenFileDialog jpegfbox]} tiff {set fn [OpenFileDialog tifffbox]} png {set fn [OpenFileDialog pngfbox]} } if {$fn != {}} { set ok 1 switch -- $format { array { # do we have an array spec tag'd on if {![regexp -nocase {(.*)(\[.*\])} $fn foo base ext]} { set ext {} set ok [ArrayImportDialog 1 ext] if {$ok} { append fn "$ext" } } } rgbarray { # do we have an array spec tag'd on if {![regexp -nocase {(.*)(\[.*\])} $fn foo base ext]} { set ext {} set ok [ArrayImportDialog 3 ext] if {$ok} { append fn "$ext" } } } nrrd - gif - jpeg - tiff - png {} } if {$ok} { Import $fn $format $layer $mode } } } proc ArrayImportDialog {depth varname} { upvar $varname var global env global ed global ds9 set w {.arr} set ed(ok) 0 set ed(x) $ds9(array,x) set ed(y) $ds9(array,y) set ed(z) $depth set ed(bitpix) $ds9(array,bitpix) set ed(skip) $ds9(array,skip) set ed(arch) $ds9(array,arch) if {[info exists env(DS9_ARRAY)]} { if {[regexp {.*(dims.?=)([0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(x) $item set ed(y) $item } if {[regexp {.*(dim.?=)([0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(x) $item set ed(y) $item } if {[regexp {.*(xdim.?=)([0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(x) $item } if {[regexp {.*(ydim.?=)([0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(y) $item } if {[regexp {.*(zdim.?=)([0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(z) $item } if {[regexp {.*(bitpix.?=)(-?[0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(bitpix) $item } if {[regexp {.*(skip.?=)(-?[0-9]+)} $env(DS9_ARRAY) foo f1 item]} { set ed(skip) $item } if {[regexp {.*arch.?=bigendian} $env(DS9_ARRAY) foo item]} { set ed(arch) $item } if {[regexp {.*arch.?=littleendian} $env(DS9_ARRAY) foo item]} { set ed(arch) $item } } DialogCreate $w [msgcat::mc {Import Array}] ed(ok) # Dim set f [ttk::labelframe $w.dim -text [msgcat::mc {Dimension}] -padding 2] ttk::entry $f.x -textvariable ed(x) -width 6 ttk::entry $f.y -textvariable ed(y) -width 6 ttk::entry $f.z -textvariable ed(z) -width 6 grid $f.x $f.y $f.z -padx 2 -pady 2 -sticky w # Bitpix set f [ttk::labelframe $w.bitpix -text [msgcat::mc {Pixel Size}] -padding 2] ttk::radiobutton $f.char -text {Char} -variable ed(bitpix) -value 8 ttk::radiobutton $f.short -text {Short} -variable ed(bitpix) -value 16 ttk::radiobutton $f.ushort -text {UShort} -variable ed(bitpix) -value -16 ttk::radiobutton $f.long -text {Long} -variable ed(bitpix) -value 32 ttk::radiobutton $f.float -text {Float} -variable ed(bitpix) -value -32 ttk::radiobutton $f.double -text {Double} -variable ed(bitpix) -value -64 grid $f.char -padx 2 -pady 2 -sticky w grid $f.short $f.ushort $f.long -padx 2 -pady 2 -sticky w grid $f.float $f.double -padx 2 -pady 2 -sticky w # Skip set f [ttk::labelframe $w.skip -text [msgcat::mc {Header}] -padding 2] ttk::label $f.t1 -text [msgcat::mc {Skip First}] ttk::label $f.t2 -text [msgcat::mc {Bytes}] ttk::entry $f.skip -textvariable ed(skip) -width 6 grid $f.t1 $f.skip $f.t2 -padx 2 -pady 2 -sticky w # Arch set f [ttk::labelframe $w.arch -text [msgcat::mc {Architecture}] -padding 2] ttk::radiobutton $f.big -text {Big-Endian} -variable ed(arch) \ -value bigendian ttk::radiobutton $f.little -text {Little-Endian} -variable ed(arch) \ -value littleendian grid $f.big $f.little -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini grid $w.dim -sticky news grid $w.bitpix -sticky news grid $w.skip -sticky news grid $w.arch -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid rowconfigure $w 2 -weight 1 grid rowconfigure $w 3 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set ds9(array,x) $ed(x) set ds9(array,y) $ed(y) set ds9(array,bitpix) $ed(bitpix) set ds9(array,skip) $ed(skip) set ds9(array,arch) $ed(arch) set var "\[xdim=$ed(x),ydim=$ed(y),zdim=$ed(z),bitpix=$ed(bitpix),skip=$ed(skip),arch=$ed(arch)\]" } set rr $ed(ok) unset ed return $rr } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/cat.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000106012�12102534471�013144� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATDef {} { global cat global icat global pcat global wcs set icat(cats) {} set icat(rformat) arcmin set icat(width) 15 set icat(height) 15 set icat(max) 5000 set icat(allrows) 1 set icat(allcols) 0 set icat(show) 1 set icat(edit) 0 set icat(panto) 1 set icat(minrows) 20 set icat(mincols) 10 set icat(key) {} set icat(key,update) {} set icat(match1) {} set icat(match2) {} set icat(return) 1and2 set icat(error) 5 set icat(eformat) arcsec set icat(function) 1and2 set icat(unique) 1 set icat(def) { \ {- {Database} db} \ {{NED} catned ned ned} \ {{SIMBAD} catsimbad simbad simbad} \ {{DENIS} catdenis cds {B/denis}} \ {{SkyBot} catskybot skybot skybot} \ {- {Optical} opt} \ {{ASCC-2.5} catascss cds {I/280A/ascc01}} \ {{Carlsberg Meridian 14} catcmc cds {I/304}}\ {{GSC 1.2} catgsc1 cds {I/254/out}} \ {{GSC 2.2} catgsc2 cds {I/271/out}} \ {{GSC 2.3} catgsc3 cds {I/305/out}} \ {{AC 2000.2} catac cds {I/275/ac2002}} \ {{NOMAD} catnomad cds {I/297/out}} \ {{PPMX} catppmx cds {I/312}} \ {{SAO J2000} catsao cds {I/131A/sao}} \ {{SDSS Release 5} catsdss5 cds {II/276}} \ {{SDSS Release 6} catsdss6 cds {II/282}} \ {{SDSS Release 7} catsdss7 cds {II/294}} \ {{SDSS Release 8} catsdss8 cds {II/306}} \ {{Tycho-2} cattycho cds {I/259/tyc2}} \ {{USNO-A2.0} catua2 cds {I/252/out}} \ {{USNO-B1.0} catub1 cds {I/284/out}} \ {{USNO UCAC2} catucac2 cds {I/289/out}} \ {{USNO UCAC2 Bright Star Sup} catucac2sup cds {I/294A}} \ {{USNO UCAC3} catucac3 cds {I/315}} \ {- {Infrared} ir} \ {{2MASS Point Sources} cat2mass cds {II/246/out}}\ {{IRAS Point Sources} catiras cds {II/125}}\ {- {High Energy} hea} \ {{Chandra Source} catcsc cxc {Current Release}} {{2XMMi Source} catxmm cds {IX/40/xmm2is}} \ {{Second ROSAT PSPC} catrosat cds {IX/30}} \ {- {Radio} radio} \ {{FIRST Survey} catfirst cds {VIII/71/first}} \ {{NVSS} catnvss cds {VIII/65/nvss}} \ {- {Observation Logs} log} \ {{Chandra Archive} catchandralog cds {B/chandra/chandra}} \ {{CFHT Exposures} catcfhtlog cds {B/cfht/chfht}} \ {{ESO Science Archive} catesolog cds {B/eso/safcat}} \ {{HST Archive} cathstlog cds {B/hst/hstlog}} \ {{XMM Observation} catxmmlog cds {B/xmm/xmmlog}} \ } set cat(id) 0 set cat(sym,font,msg) {} # prefs only set pcat(server) cds set pcat(loc) 500 set pcat(sym,shape) {circle point} set pcat(sym,color) green set pcat(sym,units) physical set pcat(sym,font) helvetica set pcat(sym,font,size) 10 set pcat(sym,font,weight) normal set pcat(sym,font,slant) roman set pcat(vot) 1 } # Load via HTTP proc CATGetURL {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATGetURL $varname $var(url)?$var(query)" } ARStatus $varname [msgcat::mc {Loading}] global ihttp if {$var(sync)} { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -query $var(query) \ -timeout $ihttp(timeout) \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 CATGetURLFinish $varname $var(token) } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } else { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -query $var(query) \ -timeout $ihttp(timeout) \ -command \ [list CATGetURLFinish $varname] \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } } proc CATGetURLIncr {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATGetURLIncr $varname $var(url)?$var(query)" } ARStatus $varname [msgcat::mc {Loading}] global ihttp if {$var(sync)} { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -query $var(query) \ -timeout $ihttp(timeout) \ -handler \ [list $var(proc,reader) $var(catdb)] \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 CATGetURLFinish $varname $var(token) } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } else { if {![catch {set var(token) [http::geturl $var(url) \ -protocol 1.0 \ -query $var(query) \ -timeout $ihttp(timeout) \ -handler \ [list $var(proc,reader) $var(catdb)] \ -command \ [list CATGetURLFinish $varname] \ -headers "[ProxyHTTP]"] }]} { # reset errorInfo (may be set in http::geturl) global errorInfo set errorInfo {} set var(active) 1 } else { ARError $varname "[msgcat::mc {Unable to locate URL}] $var(url)" } } } proc CATGetURLFinish {varname token} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATGetURLFinish $varname" } if {!($var(active))} { ARCancelled $varname return } upvar #0 $token t # Code set code [http::ncode $token] # Meta set meta $t(meta) # Log it HTTPLog $token # Result? switch -- $code { {} - 200 - 203 - 404 - 503 { if [info exist ${varname}(proc,parser)] { eval [list $var(proc,parser) $var(catdb) $token] } ARDone $varname eval $var(proc,done) $varname } 201 - 300 - 301 - 302 - 303 - 305 - 307 { foreach {name value} $meta { if {[regexp -nocase ^location$ $name]} { global debug if {$debug(tcl,cat)} { puts stderr "CATGetURLFinish redirect $code to $value" } # clean up and resubmit http::cleanup $token unset var(token) set var(url) $value eval $var(proc,load) $varname } } } default {ARError $varname "[msgcat::mc {Error code was returned}] $code"} } } proc CATLoad {varname} { upvar #0 $varname var global $varname # clear previous db global $var(catdb) if [info exists $var(catdb)] { unset $var(catdb) } global debug if {$debug(tcl,cat)} { puts stderr "CATLoad $varname $var(url)?$var(query)" } set var(proc,done) CATLoadDone set var(proc,load) CATLoad CATGetURL $varname return } proc CATLoadIncr {varname} { upvar #0 $varname var global $varname # clear previous db global $var(catdb) if [info exists $var(catdb)] { unset $var(catdb) } global debug if {$debug(tcl,cat)} { puts stderr "CATLoadIncr $varname $var(url)?$var(query)" } set var(proc,done) CATLoadDone set var(proc,load) CATLoadIncr CATGetURLIncr $varname return } proc CATLoadDone {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATLoadDone $varname" } CATSortMenu $varname CATConfigCols $varname CATColsMenu $varname CATTable $varname CATDialogUpdate $varname } # Load via File proc CATLoadSBFile {varname} { upvar #0 $varname var global $varname set fn [OpenFileDialog catfbox] if {$fn != {}} { CATLoadFn $varname $fn starbase_read } } proc CATLoadVOTFile {varname} { upvar #0 $varname var global $varname set fn [OpenFileDialog catvotfbox] if {$fn != {}} { CATLoadFn $varname $fn CATVOTRead } } proc CATLoadTSVFile {varname} { upvar #0 $varname var global $varname set fn [OpenFileDialog cattsvfbox] if {$fn != {}} { CATLoadFn $varname $fn CATTSVRead } } # used by backup proc CATLoadFn {varname fn reader} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATLoadFn $varname $fn $reader" } ARStatus $varname [msgcat::mc {Loading Catalog}] CATOff $varname CATSet $varname {} {} $fn set var(name) {} set var(x) {} set var(y) {} set var(width) {} set var(height) {} if {[file exists $fn]} { $reader $var(catdb) $fn } else { Error "[msgcat::mc {Unable to open file}] $fn" return } ARDone $varname CATLoadDone $varname } # Save via File proc CATSaveSBFile {varname} { set fn [SaveFileDialog catfbox] CATSaveFn $varname $fn starbase_write } proc CATSaveVOTFile {varname} { set fn [SaveFileDialog catvotfbox] CATSaveFn $varname $fn CATVOTWrite } proc CATSaveTSVFile {varname} { set fn [SaveFileDialog cattsvfbox] CATSaveFn $varname $fn CATTSVWrite } proc CATSaveFn {varname fn writer} { upvar #0 $varname var global $varname global $var(tbldb) if {$fn == {}} { return } # do we have a db? if {![CATValidDB $var(tbldb)]} { return } ARStatus $varname [msgcat::mc {Writing Catalog}] $writer $var(tbldb) $fn ARDone $varname } # Other procedures proc CATStatusRows {varname rowlist} { upvar #0 $varname var global $varname # rowlist start at 1 if {[llength $rowlist]>0} { ARStatus $varname "[msgcat::mc {Row}] [join $rowlist {,}]" } else { ARStatus $varname {} } } proc CATOff {varname} { upvar #0 $varname var global $varname global $var(catdb) if [info exists $var(catdb)] { unset $var(catdb) } global $var(tbldb) if [info exists $var(tbldb)] { unset $var(tbldb) } set db $var(tbldb) set ${db}(Nrows) {} $var(tbl) selection clear all if {[$var(frame) has fits]} { $var(frame) marker catalog $varname delete } CATSortMenu $varname CATColsMenu $varname set var(filter) {} set var(sort) {} set var(colx) {} set var(coly) {} set var(blink) 0 # plot window? if {$var(plot)} { PlotDestroy $var(plot,var) set var(plot) 0 set var(plot,var) {} set var(plot,x) {} set var(plot,xerr) {} set var(plot,y) {} set var(plot,yerr) {} } CATDialogUpdate $varname } # used by backup proc CATTable {varname} { upvar #0 $varname var global $varname global $var(catdb) global icat global debug if {$debug(tcl,cat)} { puts stderr "CATTable $varname" } if {![CATValidDB $var(catdb)]} { return } # delete any previous tbldb set db ${varname}tbldb global $db if [info exists $db] { unset $db } # clear the selection $var(tbl) selection clear all # clear regions if {[$var(frame) has fits]} { $var(frame) marker catalog $varname delete } if {$var(filter) == {} && $var(sort) == {}} { set var(tbldb) $var(catdb) } else { set var(tbldb) ${varname}tbldb global $var(tbldb) if {![CATFltSort $varname]} { Error "[msgcat::mc {Unable to evaluate filter}] $var(filter)" if [info exists $var(tbldb)] { unset $var(tbldb) } set var(tbldb) $var(catdb) } } global $var(tbldb) $var(tbl) configure -variable $var(tbldb) $var(found) configure -textvariable ${var(tbldb)}(Nrows) # starbase_writefp $var(catdb) stdout # starbase_writefp $var(tbldb) stdout if {[starbase_nrows $var(tbldb)] == 0} { ARStatus $varname [msgcat::mc {No Items Found}] return } set nc [starbase_ncols $var(tbldb)] if { $nc > $icat(mincols)} { $var(tbl) configure -cols $nc } else { $var(tbl) configure -cols $icat(mincols) } # add header set nr [expr [starbase_nrows $var(tbldb)]+1] if {$nr > $icat(minrows)} { $var(tbl) configure -rows $nr } else { $var(tbl) configure -rows $icat(minrows) } CATGenerate $varname # regenerate the plot if needed if {$var(plot)} { CATPlotGenerate $varname } set nr [starbase_nrows $var(tbldb)] if {$nr >= $var(max) && !$var(allrows)} { ARStatus $varname "$nr [msgcat::mc {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed}]" } } proc CATGenerate {varname} { upvar #0 $varname var global $varname global $var(tbldb) global debug if {$debug(tcl,cat)} { puts stderr "CATGenerate $varname" } # do we have a db? if {![CATValidDB $var(tbldb)]} { return } ARStatus $varname [msgcat::mc {Plotting Regions}] # delete any previous if {[$var(frame) has fits]} { $var(frame) marker catalog $varname delete } if {$var(show)} { global reg set reg {} CATReg $varname {} 1 reg if {[$var(frame) has fits]} { if {[catch {$var(frame) marker catalog command ds9 var reg}]} { ARError $varname "[msgcat::mc {Internal Parse Error}]" return } } } ARStatus $varname {Done} } proc CATGenerateRegions {varname} { upvar #0 $varname var global $varname global $var(tbldb) global debug if {$debug(tcl,cat)} { puts stderr "CATGenerateRegions $varname" } # do we have a db? if {![CATValidDB $var(tbldb)]} { return } ARStatus $varname [msgcat::mc {Generating Regions}] global reg set reg {} CATReg $varname {} 0 reg if {[$var(frame) has fits]} { if {[catch {$var(frame) marker command ds9 var reg}]} { ARError $varname "[msgcat::mc {Internal Parse Error}]" return } } ARStatus $varname {Done} } proc CATGenerateUpdate {varname row} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATGenerateUpdate $varname $row" } if {![$var(frame) has fits]} { return } set id [$var(frame) get marker catalog "\{${varname}.${row}\}" id] set sel [$var(frame) get marker catalog $id select] set hh [$var(frame) get marker catalog $id highlite] $var(frame) marker catalog "\{${varname}.${row}\}" delete global reg set reg {} CATReg $varname $row 1 reg if {$reg != {}} { $var(frame) marker catalog command ds9 var reg set id [$var(frame) get marker catalog "\{${varname}.${row}\}" id] if {$sel} { $var(frame) marker catalog "\{${varname}.${row}\}" select } if {$hh} { $var(frame) marker catalog "\{${varname}.${row}\}" highlite } } unset reg } proc CATSet {varname format catalog title} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSet $varname :$format:$catalog:$title:" } set var(format) $format set var(catalog) $catalog set var(title) $title set var(filter) {} set var(colx) {} set var(coly) {} set var(sort) {} set var(sort,dir) "-increasing" } proc CATValidDB {varname} { upvar #0 $varname var global $varname if {[info exists var(Nrows)] && [info exists var(Ncols)] && [info exists var(HLines)] && [info exists var(Header)]} { return 1 } else { return 0 } } proc CATCatalogMenu {} { global icat global ds9 set mm "$ds9(mb).analysis.cat" set nn {} foreach ff $icat(def) { set ll [lindex $ff 0] set ww [lindex $ff 1] set ss [lindex $ff 2] set cc [lindex $ff 3] if {$ll != {-}} { $mm.$nn add command -label $ll \ -command [list CATDialog $ww $ss $cc $ll apply] } else { set nn "$ss" menu $mm.$nn $mm add cascade -label $ww -menu $mm.$nn } } } proc CATServerMenu {varname} { upvar #0 $varname var global $varname $var(mb) add cascade -label [msgcat::mc {Catalog Server}] \ -menu $var(mb).server menu $var(mb).server $var(mb).server add radiobutton -label {CDS, Strasbourg France} \ -variable ${varname}(server) -value cds $var(mb).server add radiobutton -label {CFA, Boston USA} \ -variable ${varname}(server) -value sao $var(mb).server add radiobutton -label {CADC, Canada} \ -variable ${varname}(server) -value cadc $var(mb).server add radiobutton -label {ADAC, Tokyo Japan} \ -variable ${varname}(server) -value adac $var(mb).server add radiobutton -label {IUCAA, Pune India} \ -variable ${varname}(server) -value iucaa $var(mb).server add radiobutton -label {INASAN, Russia} \ -variable ${varname}(server) -value inasan $var(mb).server add radiobutton -label {BEJING, China} \ -variable ${varname}(server) -value bejing $var(mb).server add radiobutton -label {CAMBRIDGE, UK} \ -variable ${varname}(server) -value cambridge $var(mb).server add radiobutton -label {UKIRT, Hawaii USA} \ -variable ${varname}(server) -value ukirt } proc CATSortMenu {varname} { upvar #0 $varname var global $varname global $var(catdb) global ds9 set m $var(sortmenu).menu catch {destroy $m} menu $m -tearoff 0 $m add command -label {} -command "CATSortCmd $varname {}" if [CATValidDB $var(catdb)] { set cnt -1 foreach col [starbase_columns $var(catdb)] { $m add command -label $col -command "CATSortCmd $varname \{$col\}" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $m entryconfig $col -columnbreak 1 } } } } proc CATSortCmd {varname val} { upvar #0 $varname var global $varname set ${varname}(sort) $val CATTable $varname } # backward backup compatibility version 6.1 proc CATRADECMenu {varname} { CATColsMenu $varname } # used by backup proc CATColsMenu {varname} { upvar #0 $varname var global $varname global $var(catdb) global ds9 set m $var(ramenu).menu catch {destroy $m} menu $m -tearoff 0 if [CATValidDB $var(catdb)] { set cnt -1 foreach col [starbase_columns $var(catdb)] { $m add command -label $col -command "CATColXCmd $varname \{$col\}" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $m entryconfig $col -columnbreak 1 } } } set m $var(decmenu).menu catch {destroy $m} menu $m -tearoff 0 if [CATValidDB $var(catdb)] { set cnt -1 foreach col [starbase_columns $var(catdb)] { $m add command -label $col -command "CATColYCmd $varname \{$col\}" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $m entryconfig $col -columnbreak 1 } } } } proc CATColXCmd {varname val} { upvar #0 $varname var global $varname set ${varname}(colx) $val CATGenerate $varname } proc CATColYCmd {varname val} { upvar #0 $varname var global $varname set ${varname}(coly) $val CATGenerate $varname } proc CATColsCmd {varname} { upvar #0 $varname var global $varname CATColsUpdate $varname CATGenerate $varname } proc CATConfigCols {varname} { upvar #0 $varname var global $varname global $var(catdb) set var(colx) {} set var(coly) {} if {![CATValidDB $var(catdb)]} { return } if {[starbase_ncols $var(catdb)] < 2} { return } # determine psystem/psky if present in cat header # psystem has already been adjusted based on loaded fits at menu creation switch -- $var(psystem) { image - physical - amplifier - detector { set cols { "X" "Y" } foreach {colx coly} $cols { if {!([lsearch [starbase_columns $var(catdb)] $colx] == -1) && !([lsearch [starbase_columns $var(catdb)] $coly] == -1)} { set var(colx) $colx set var(coly) $coly return } # try lower case set colx [string tolower $colx] set coly [string tolower $coly] if {!([lsearch [starbase_columns $var(catdb)] $colx] == -1) && !([lsearch [starbase_columns $var(catdb)] $coly] == -1)} { set var(colx) $colx set var(coly) $coly return } } # default set var(colx) [starbase_colname $var(catdb) 1] set var(coly) [starbase_colname $var(catdb) 2] return } default { if {![$var(frame) has wcs equatorial $var(psystem)]} { # linear set var(colx) [starbase_colname $var(catdb) 1] set var(coly) [starbase_colname $var(catdb) 2] return } else { if {![catch {starbase_hdrget $var(catdb) equinox} sys]} { switch -- $sys { 1950.0 - B1950 { set var(psystem) wcs set var(psky) fk4 } 2000.0 - J2000 { set var(psystem) wcs set var(psky) fk5 } } } switch -- $var(psky) { fk5 - icrs { set cols { "_RAJ2000" "_DEJ2000" "RAJ2000" "DEJ2000" "RA_J2000" "DEC_J2000" "RA (J2000)" "Dec (J2000)" "RA" "DEC" "RA" "DECL" "RA" "Dec" "RA(deg)" "DEC(deg)" } if {[CATConfigColsSearch $varname $cols]} { return } # next, look for an UCD (via VOTABLE) set db $var(catdb) upvar #0 $db T for {set cc 0} {$cc < $T(Ncols)} {incr cc} { if {[info exists ${db}(Ucd)]} { switch -- [string tolower [string range [lindex $T(Ucd) $cc] 0 8]] { pos.eq.ra {set var(colx) [lindex $T(Header) $cc]} pos.eq.de {set var(coly) [lindex $T(Header) $cc]} } } } if {$var(colx) != {} && $var(coly) != {}} { return } } fk4 { set cols { "_RAB1950" "_DEB1950" "RA_B1950" "DEC_B1950" "RA (B1950)" "Dec (1950)" "RA" "DEC" "RA" "DECL" "RA" "Dec" "RA(deg)" "DEC(deg)" } if {[CATConfigColsSearch $varname $cols]} { return } } galactic { set cols { "_GLON" "_GLAT" "LON" "LAT" "LON.Gal(deg)" "LAT.Gal(deg)" } if {[CATConfigColsSearch $varname $cols]} { return } } ecliptic { set cols { "_ELON" "_ELAT" "LON.Ecl(deg)" "LAT.Ecl(deg)" } if {[CATConfigColsSearch $varname $cols]} { return } } } # default set var(colx) [starbase_colname $var(catdb) 1] set var(coly) [starbase_colname $var(catdb) 2] } } } } proc CATConfigColsSearch {varname cols} { upvar #0 $varname var global $varname global $var(catdb) foreach {colx coly} $cols { if {!([lsearch [starbase_columns $var(catdb)] $colx] == -1) && !([lsearch [starbase_columns $var(catdb)] $coly] == -1)} { set var(colx) $colx set var(coly) $coly return 1 } # try lower case set colx [string tolower $colx] set coly [string tolower $coly] if {!([lsearch [starbase_columns $var(catdb)] $colx] == -1) && !([lsearch [starbase_columns $var(catdb)] $coly] == -1)} { set var(colx) $colx set var(coly) $coly return 1 } } return 0 } # Other interface proc CATTool {} { CATDialog cattool {} {} {} none } proc CATClearFrame {} { global current if {$current(frame) != {}} { $current(frame) marker catalog delete all } } proc CATUpdateWCS {} { global icat global current if {$current(frame) != {}} { $current(frame) marker catalog delete all foreach varname $icat(cats) { upvar #0 $varname var global $varname CATGenerate $varname # regenerate the plot if needed if {$var(plot)} { CATPlotGenerate $varname } } } } proc CATBackup {ch which fdir rdir} { global icat foreach varname $icat(cats) { upvar #0 $varname var global $varname if {$var(frame) == $which} { set catdb ${varname}catdb global $catdb puts $ch "CATDialog $varname {} {} {} none" if {[starbase_nrows $var(catdb)]>500} { # external file set fn $fdir/${varname}.cat set rfn $rdir/${varname}.cat catch {file delete -force $fn} CATSaveFn $varname "$fn" CATVOTWrite puts $ch "CATLoadFn $varname \"$rfn\" CATVOTRead" } else { # internal var puts $ch "global $catdb" puts $ch "array set $catdb \{ [array get $catdb] \}" } puts $ch "global $varname" puts $ch "array set $varname \{ [array get $varname] \}" set symdb ${varname}symdb global $symdb puts $ch "global $symdb" puts $ch "array set $symdb \{ [array get $symdb] \}" puts $ch "CATColsMenu $varname" puts $ch "CATTable $varname" } } } # Process Cmds proc ProcessCatalogCmd {varname iname} { upvar $varname var upvar $iname i global icat # we need to be realized ProcessRealizeDS9 set item [string tolower [lindex $var $i]] switch -- $item { {} { # blank CATTool return } file - import - load { # load incr i set reader CATVOTRead switch -- [lindex $var $i] { xml - vot {incr i; set reader CATVOTRead} sb - starbase {incr i; set reader starbase_read} csv - tsv {incr i; set reader CATTSVRead} } set fn [lindex $var $i] if {$fn != {}} { CATDialog cattool {} {} {} none CATLoadFn [lindex $icat(cats) end] $fn $reader FileLast catfbox $fn } return } allcols - allrows - cancel - clear - close - coordinate - crosshair - dec - edit - export - filter - header - hide - location - match - maxrows - name - panto - plot - print - psky - psystem - ra - retrieve - samp - save - server - show - size - sky - skyformat - sort - symbol - system - update - x - y {ProcessCatalog $varname $iname [lindex $icat(cats) end]} default { # existing cat or load new one? set ref $item # backward compatibility if {[string range $ref 0 2] == {cat}} { set ref [string range $ref 3 end] } incr i set item [string tolower [lindex $var $i]] switch -- $item { file - import - load { # processed above incr i -1 return } allcols - allrows - cancel - clear - close - coordinate - crosshair - dec - edit - export - filter - header - hide - location - match - maxrows - name - panto - plot - print - psky - psystem - ra - retrieve - samp - save - server - show - size - sky - skyformat - sort - symbol - system - update - x - y {ProcessCatalog $varname $iname cat${ref}} default { # ok, new catalog incr i -1 set item [string tolower [lindex $var $i]] # another command if {[string range $item 0 0] == "-"} { CATTool incr i -1 return } # backward compatibility switch $item { cds {incr i; set item [string tolower [lindex $var $i]]} cxc {set item csc} } # see if its from our list of cats foreach mm $icat(def) { set ll [lindex $mm 0] set ww [lindex $mm 1] set ss [lindex $mm 2] set cc [lindex $mm 3] if {$ll != {-} && "cat${item}" == $ww} { CATDialog $ww $ss $cc $ll sync return } } # not a default, assume other name CATDialog catcds cds $item $item sync } } } } } proc ProcessCatalog {varname iname cvarname} { upvar 2 $varname var upvar 2 $iname i global icat global pcat global current # we should have a catalog now global $cvarname upvar #0 $cvarname cvar if {![info exists cvar(top)]} { Error "[msgcat::mc {Unable to find catalog window}] $cvarname" return } if {![winfo exists $cvar(top)]} { Error "[msgcat:: mc {Unable to find catalog window}] $cvarname" return } # now, process it set item [string tolower [lindex $var $i]] switch -- $item { allrows {set cvar(allrows) 1} allcols {set cvar(allcols) 1} cancel {ARCancel $cvarname} clear {CATOff $cvarname} close {CATDestroy $cvarname} coordinate { incr i set cvar(x) [lindex $var $i] incr i set cvar(y) [lindex $var $i] incr i set cvar(sky) [lindex $var $i] } crosshair {CATCrosshair $cvarname} edit { incr i set cvar(edit) [FromYesNo [lindex $var $i]] CATEdit $cvarname } export - save { incr i set writer CATVOTWrite switch -- [lindex $var $i] { xml - vot {incr i; set writer CATVOTWrite} sb - starbase {incr i; set writer starbase_write} csv - tsv {incr i; set writer CATTSVWrite} } set fn [lindex $var $i] CATSaveFn $cvarname $fn $writer FileLast catfbox $fn } filter { incr i set item [lindex $var $i] switch -- $item { load { incr i set fn [lindex $var $i] if [catch {open $fn r} fp] { Error "[msgcat::mc {Unable to open file}] $fn: $fp" return } set flt [read -nonewline $fp] catch {regsub {\n} $flt " " $flt} set cvar(filter) [string trim $flt] catch {close $fp} } default { set cvar(filter) $item } } CATTable $cvarname } header {CATHeader $cvarname} hide { set cvar(show) 0 CATGenerate $cvarname } location { incr i set cvar(loc) [lindex $var $i] CATGenerate $cvarname } match { incr i set item [lindex $var $i] switch -- $item { error { incr i set icat(error) [lindex $var $i] incr i set icat(eformat) [lindex $var $i] } function {incr i; set icat(function) [lindex $var $i]} unique {incr i; set icat(unique) [FromYesNo [lindex $var $i]]} return {incr i; set icat(return) [lindex $var $i]} default { set icat(match1) "cat[lindex $var $i]" incr i set icat(match2) "cat[lindex $var $i]" CATMatch $current(frame) $icat(match1) $icat(match2) } } } maxrows { incr i set cvar(max) [lindex $var $i] } name { incr i set cvar(name) [lindex $var $i] } panto { incr i set cvar(panto) [FromYesNo [lindex $var $i]] } plot { incr i set cvar(plot,x) [lindex $var $i] incr i set cvar(plot,y) [lindex $var $i] incr i set cvar(plot,xerr) [lindex $var $i] incr i set cvar(plot,yerr) [lindex $var $i] CATPlotGenerate $cvarname } print {CATPrint $cvarname} psky { incr i set cvar(psky) [lindex $var $i] CATGenerate $cvarname } psystem { incr i set cvar(psystem) [lindex $var $i] CATGenerate $cvarname } retrieve - retreive {CATApply $cvarname 1} samp { global ds9 global samp incr i switch -- [string tolower [lindex $var $i]] { send { incr i set name [string tolower [lindex $var $i]] if [info exists samp] { foreach arg $samp(apps,votable) { foreach {key val} $arg { if {[string tolower $val] == $name} { SAMPSendTableLoadVotable $key $cvarname break } } } } else { Error [msgcat::mc {SAMP: not connected}] } } broadcast {SAMPSendTableLoadVotable {} $cvarname} default { SAMPSendTableLoadVotable {} $cvarname incr i -1 } } } server { incr i set $cvar(server) [lindex $var $i] } size { incr i set cvar(width) [lindex $var $i] incr i set cvar(height) [lindex $var $i] incr i set cvar(rformat) [lindex $var $i] set cvar(rformat,msg) $cvar(rformat) } show { set cvar(show) 1 CATGenerate $cvarname } sky { incr i set cvar(sky) [lindex $var $i] CoordMenuButtonCmd $cvarname system sky \ [list CATWCSMenuUpdate $cvarname] } skyformat { incr i set cvar(skyformat) [lindex $var $i] } sort { incr i set cvar(sort) [lindex $var $i] incr i switch -- [lindex $var $i] { incr { set cvar(sort,dir) "-increasing" } decr { set cvar(sort,dir) "-decreasing" } } CATTable $cvarname } symbol { global $cvar(symdb) set row 1 incr i if {[string is integer [lindex $var $i]]} { set row [lindex $var $i] incr i } switch -- [lindex $var $i] { add { set row [expr [starbase_nrows $cvar(symdb)]+1] starbase_rowins $cvar(symdb) $row starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) shape] $pcat(sym,shape) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) color] $pcat(sym,color) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) font] $pcat(sym,font) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontsize] \ $pcat(sym,font,size) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontweight] \ $pcat(sym,font,weight) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontslant] \ $pcat(sym,font,slant) starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) units] $pcat(sym,units) CATGenerate $cvarname } angle { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) angle] [lindex $var $i] CATGenerate $cvarname } color { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) color] [lindex $var $i] CATGenerate $cvarname } condition { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) condition] \ [lindex $var $i] CATGenerate $cvarname } font { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) font] [lindex $var $i] CATGenerate $cvarname } fontsize { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontsize] [lindex $var $i] CATGenerate $cvarname } fontweight { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontweight] \ [lindex $var $i] CATGenerate $cvarname } fontslant { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) fontslant] \ [lindex $var $i] CATGenerate $cvarname } load { incr i set fn [lindex $var $i] if {[file exists $fn]} { starbase_read $cvar(symdb) $fn CATGenerate $cvarname } else { Error "[msgcat::mc {Unable to open file}] $fn" return } } remove { starbase_rowdel $cvar(symdb) $row CATGenerate $cvarname } save { incr i starbase_write $cvar(symdb) [lindex $var $i] } size { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) size] [lindex $var $i] CATGenerate $cvarname } size2 { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) size2] [lindex $var $i] CATGenerate $cvarname } shape { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) shape] [lindex $var $i] CATGenerate $cvarname } text { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) text] [lindex $var $i] CATGenerate $cvarname } units { incr i starbase_set $cvar(symdb) $row \ [starbase_colnum $cvar(symdb) units] [lindex $var $i] CATGenerate $cvarname } } } system { incr i set cvar(system) [lindex $var $i] CoordMenuButtonCmd $cvarname system sky \ [list CATWCSMenuUpdate $cvarname] } update {CATUpdate $cvarname} x - ra { incr i set cvar(colx) [lindex $var $i] CATGenerate $cvarname } y - dec { incr i set cvar(coly) [lindex $var $i] CATGenerate $cvarname } } } proc ProcessSendCatalogCmd {proc id param sock fn} { global icat set cc [lindex $icat(cats) end] switch -- [string tolower [lindex $param 0]] { header {} default { set cc [lindex $param 0] set param [lreplace $param 0 0] } } switch -- [string tolower [lindex $param 0]] { {} {$proc $id "$icat(cats)\n"} header {ProcessSend $proc $id $sock $fn {.txt} "[CATGetHeader $cc]\n"} } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/skyview.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000013011�11741077672�014107� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SkyViewDef {} { global skyview global iskyview set iskyview(top) .skyview set iskyview(mb) .skyviewmb set skyview(sky) fk5 set skyview(rformat) arcsec set skyview(width) 300 set skyview(height) 300 set skyview(mode) new set skyview(save) 0 set skyview(valid) 0 set skyview(survey) sdssi } proc SkyViewDialog {} { global skyview global iskyview global wcs if [winfo exists $iskyview(top)] { raise $iskyview(top) return } global debug if {$debug(tcl,image)} { puts stderr "SkyViewDialog" } set varname dskyview upvar #0 $varname var global $varname set var(top) $iskyview(top) set var(mb) $iskyview(mb) set var(sky) $skyview(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $skyview(rformat) set var(width) $skyview(width) set var(height) $skyview(height) set var(mode) $skyview(mode) set var(save) $skyview(save) set var(valid) $skyview(valid) set var(survey) $skyview(survey) set w $var(top) IMGSVRInit $varname "HEASARC-SkyView [msgcat::mc {Server}]" \ SkyViewExec SkyViewAck menu $var(mb).survey $var(mb) add cascade -label Survey -menu $var(mb).survey $var(mb).survey add cascade -label {Optical} \ -menu $var(mb).survey.opt $var(mb).survey add cascade -label {Infrared} \ -menu $var(mb).survey.ir $var(mb).survey add cascade -label {CMB} \ -menu $var(mb).survey.cmb set f $var(mb).survey.opt menu $f $f add radiobutton -label {SDSSi} \ -variable ${varname}(survey) -value sdssi $f add radiobutton -label {SDSSr} \ -variable ${varname}(survey) -value sdssr $f add radiobutton -label {SDSSg} \ -variable ${varname}(survey) -value sdssg $f add radiobutton -label {SDSSu} \ -variable ${varname}(survey) -value sdssu $f add radiobutton -label {SDSSz} \ -variable ${varname}(survey) -value sdssz set f $var(mb).survey.ir menu $f $f add radiobutton -label {WISE 3.4} \ -variable ${varname}(survey) -value wise3.4 $f add radiobutton -label {WISE 4.6} \ -variable ${varname}(survey) -value wise4.6 $f add radiobutton -label {WISE 12} \ -variable ${varname}(survey) -value wise12 $f add radiobutton -label {WISE 22} \ -variable ${varname}(survey) -value wise22 set f $var(mb).survey.cmb menu $f $f add radiobutton -label {WMAP Ka} \ -variable ${varname}(survey) -value wmapka $f add radiobutton -label {WMAP K} \ -variable ${varname}(survey) -value wmapk $f add radiobutton -label {WMAP Q} \ -variable ${varname}(survey) -value wmapq $f add radiobutton -label {WMAP V} \ -variable ${varname}(survey) -value wmapv $f add radiobutton -label {WMAP W} \ -variable ${varname}(survey) -value wmapw $f add separator $f add radiobutton -label {COBE DIRBE/AAM} \ -variable ${varname}(survey) -value cobeaam $f add radiobutton -label {COBE DIRBE/ZSMA} \ -variable ${varname}(survey) -value cobezsma $f add radiobutton -label {COBE DIRBE (Old)} \ -variable ${varname}(survey) -value cobe IMGSVRUpdate $varname 1 } proc SkyViewExec {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "SkyViewExec $varname" } if {$var(save)} { set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set var(fn) [tmpnam ds9skyview ".fits"] } # skyformat switch -- $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { set xx [h2d [Sex2H $var(x)]] set yy [Sex2D $var(y)] } } # size - convert to arcsec switch -- $var(rformat) { degrees { set ww $var(width) set hh $var(height) } arcmin { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } arcsec { set ww [expr $var(width)/60./60.] set hh [expr $var(height)/60./60.] } } if {$ww>5} { set ww 5 } if {$hh>5} { set hh 5 } # now average set rr [expr ($ww+$hh)/2.] # query switch $var(survey) { wmapka - wmapk - wmapq - wmapv - wmapw - cobeaam - cobezsma - cobe { set var(query) [http::formatQuery Position $xx,$yy Survey $var(survey) Return FITS] } default { set var(query) [http::formatQuery Position $xx,$yy Survey $var(survey) Size $ww,$hh Return FITS] } } set var(url) "http://skyview.gsfc.nasa.gov/cgi-bin/images" IMGSVRLoad $varname } proc SkyViewAck {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,image)} { puts stderr "SkyViewAck $varname" } set msg {Acknowledgments for the DSS-SAO SkyView was developed and is maintained under NASA ADP Grant NAS5-32068 with P.I. Thomas A. McGlynn under the auspices of the High Energy Astrophysics Science Archive Research Center (HEASARC) at the GSFC Laboratory for High Energy Astrophysics. We gratefully acknowledge the support of NASA and the contributors of SkyView data surveys. Maintained by: Laura McDonald lmm@skyview.gsfc.nasa.gov } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessSkyViewCmd {varname iname} { upvar $varname var upvar $iname i SkyViewDialog IMGSVRProcessCmd $varname $iname dskyview } proc ProcessSendSkyViewCmd {proc id param} { SkyViewDialog IMGSVRProcessSendCmd $proc $id $param dskyview } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catsym.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000036366�12024712502�013707� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATSymDef {} { global icatsym set icatsym(minrows) 8 set icatsym(mincols) 8 } proc CATSymDialog {parent} { upvar #0 $parent pvar global $parent set varname $pvar(symdl) upvar #0 $varname var global $varname global ds9 global icatsym # main dialog set var(top) ".${varname}" set var(mb) ".${varname}mb" if [winfo exists $var(top)] { raise $var(top) return } # variables set var(parent) $parent set var(symdb) $pvar(symdb) global $var(symdb) set var(row) 1 # initialize if {$var(row) <= [starbase_nrows $var(symdb)]} { set var(condition) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) condition]] set var(shape) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) shape]] set var(color) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) color]] set var(font) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) font]] set var(font,size) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontsize]] set var(font,weight) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontweight]] set var(font,slant) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontslant]] set var(text) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) text]] set var(size) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size]] set var(size2) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size2]] set var(units) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) units]] set var(angle) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) angle]] } # create the window set w $var(top) set mb $var(mb) Toplevel $w $mb 7 [msgcat::mc {Symbol Editor}] "CATSymDestroy $varname" # menu $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command "CATSymApply $varname" $mb.file add separator $mb.file add command -label "[msgcat::mc {Save}]..." \ -command "CATSymSave $varname" $mb.file add command -label "[msgcat::mc {Load}]..." \ -command "CATSymLoad $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Add}] \ -command "CATSymAdd $varname" $mb.file add command -label [msgcat::mc {Delete}] \ -command "CATSymRemove $varname" $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command "CATSymDestroy $varname" # Param set f [ttk::frame $w.param] ttk::label $f.tcondition -text [msgcat::mc {If}] ttk::entry $f.condition -textvariable ${varname}(condition) -width 40 ttk::button $f.bcondition -text [msgcat::mc {Edit}] \ -command "CATEditDialog $varname condition $pvar(catdb)" ttk::label $f.tthen -text [msgcat::mc {Then}] ttk::label $f.tshape -text [msgcat::mc {Shape}] ttk::menubutton $f.shape -textvariable ${varname}(shape) -menu $f.shape.menu ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color $varname color {} ttk::label $f.tfont -text [msgcat::mc {Font}] FontMenuButton $f.font $varname font font,size font,weight font,slant {} ttk::label $f.ttext -text [msgcat::mc {Text}] ttk::entry $f.text -textvariable ${varname}(text) -width 40 ttk::button $f.btext -text [msgcat::mc {Edit}] \ -command "CATEditDialog $varname text $pvar(catdb)" ttk::label $f.tsize -text [msgcat::mc {Size/Radius}] ttk::entry $f.size -textvariable ${varname}(size) -width 40 ttk::button $f.bsize -text [msgcat::mc {Edit}] \ -command "CATEditDialog $varname size $pvar(catdb)" ttk::label $f.tsize2 -text "[msgcat::mc {Size/Radius}] 2" ttk::entry $f.size2 -textvariable ${varname}(size2) -width 40 ttk::button $f.bsize2 -text [msgcat::mc {Edit}] \ -command "CATEditDialog $varname size2 $pvar(catdb)" ttk::label $f.tunits -text [msgcat::mc {Units}] tk_optionMenu $f.units ${varname}(units) \ image physical degrees arcmin arcsec $f.units.menu configure ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 40 ttk::button $f.bangle -text [msgcat::mc {Edit}] \ -command "CATEditDialog $varname angle $pvar(catdb)" menu $f.shape.menu $f.shape.menu add radiobutton -label [msgcat::mc {Circle}] \ -variable ${varname}(shape) -value {circle} $f.shape.menu add radiobutton -label [msgcat::mc {Ellipse}] \ -variable ${varname}(shape) -value {ellipse} $f.shape.menu add radiobutton -label [msgcat::mc {Box}] \ -variable ${varname}(shape) -value {box} $f.shape.menu add radiobutton -label [msgcat::mc {Vector}] \ -variable ${varname}(shape) -value {vector} $f.shape.menu add radiobutton -label [msgcat::mc {Text}] \ -variable ${varname}(shape) -value {text} $f.shape.menu add cascade -label [msgcat::mc {Point}] \ -menu $f.shape.menu.point menu $f.shape.menu.point $f.shape.menu.point add radiobutton -label [msgcat::mc {Circle}] \ -variable ${varname}(shape) -value {circle point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Box}] \ -variable ${varname}(shape) -value {box point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Diamond}] \ -variable ${varname}(shape) -value {diamond point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Cross}] \ -variable ${varname}(shape) -value {cross point} $f.shape.menu.point add radiobutton -label [msgcat::mc {X}] \ -variable ${varname}(shape) -value {x point} $f.shape.menu.point add radiobutton -label [msgcat::mc {Arrow}] \ -variable ${varname}(shape) -value {arrow point} $f.shape.menu.point add radiobutton -label [msgcat::mc {BoxCircle}] \ -variable ${varname}(shape) -value {boxcircle point} grid $f.tcondition $f.condition $f.bcondition -padx 2 -pady 2 -sticky w grid $f.tthen -padx 2 -pady 2 -sticky w grid $f.tshape $f.shape -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w grid $f.tfont $f.font -padx 2 -pady 2 -sticky w grid $f.ttext $f.text $f.btext -padx 2 -pady 2 -sticky w grid $f.tsize $f.size $f.bsize -padx 2 -pady 2 -sticky w grid $f.tsize2 $f.size2 $f.bsize2 -padx 2 -pady 2 -sticky w grid $f.tunits $f.units -padx 2 -pady 2 -sticky w grid $f.tangle $f.angle $f.bangle -padx 2 -pady 2 -sticky w # Table set f [ttk::frame $w.tbl] set var(tbl) [table $f.t \ -state disabled \ -usecommand 0 \ -variable $var(symdb) \ -colorigin 1 \ -roworigin 0 \ -cols $icatsym(mincols) \ -rows $icatsym(minrows) \ -width -1 \ -height -1 \ -maxwidth 550 \ -maxheight 300 \ -titlerows 1 \ -xscrollcommand [list $f.xscroll set]\ -yscrollcommand [list $f.yscroll set]\ -selecttype row \ -selectmode single \ -anchor w \ -font [font actual TkDefaultFont] \ -browsecommand [list CATSymSelectCB $varname] ] ttk::scrollbar $f.yscroll -command [list $var(tbl) yview] -orient vertical ttk::scrollbar $f.xscroll -command [list $var(tbl) xview] -orient horizontal grid $var(tbl) $f.yscroll -sticky news grid $f.xscroll -stick news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command "CATSymApply $varname" ttk::button $f.add -text [msgcat::mc {Add}] \ -command "CATSymAdd $varname" ttk::button $f.remove -text [msgcat::mc {Delete}] \ -command "CATSymRemove $varname" ttk::button $f.close -text [msgcat::mc {Close}] \ -command "CATSymDestroy $varname" pack $f.apply $f.add $f.remove $f.close \ -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sparam -orient horizontal ttk::separator $w.sstatus -orient horizontal pack $w.buttons $w.sstatus -side bottom -fill x pack $w.param $w.sparam -side top -fill x pack $w.tbl -side top -fill both -expand true CATSymTable $varname $var(tbl) selection set $var(row),1 } proc CATSymDestroy {varname} { upvar #0 $varname var global $varname destroy $var(top) destroy $var(mb) unset var } proc CATSymApply {varname} { upvar #0 $varname var global $varname global $var(symdb) if {$var(row) != {}} { if {$var(row) <= [starbase_nrows $var(symdb)]} { starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) condition] $var(condition) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) shape] $var(shape) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) color] $var(color) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) font] $var(font) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontsize] $var(font,size) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontweight] $var(font,weight) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontslant] $var(font,slant) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) text] $var(text) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size] $var(size) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size2] $var(size2) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) units] $var(units) starbase_set $var(symdb) $var(row) \ [starbase_colnum $var(symdb) angle] $var(angle) } } CATSymUpdate $varname } proc CATSymAdd {varname} { upvar #0 $varname var global $varname global $var(symdb) global pcat set row [expr [starbase_nrows $var(symdb)]+1] starbase_rowins $var(symdb) $row starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) shape] $pcat(sym,shape) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) color] $pcat(sym,color) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) font] $pcat(sym,font) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) fontsize] $pcat(sym,font,size) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) fontweight] $pcat(sym,font,weight) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) fontslant] $pcat(sym,font,slant) starbase_set $var(symdb) $row \ [starbase_colnum $var(symdb) units] $pcat(sym,units) $var(tbl) selection clear all $var(tbl) selection set $row,1 $var(tbl) see $row,1 CATSymSelectCB $varname CATSymTable $varname } proc CATSymRemove {varname} { upvar #0 $varname var global $varname global $var(symdb) set ss "[$var(tbl) curselection]" set var(row) [string trim [lindex [split $ss ,] 0]] if {$var(row) != {}} { set nr [starbase_nrows $var(symdb)] if {$nr > 1 && $var(row) <= $nr} { starbase_rowdel $var(symdb) $var(row) set var(row) {} } } CATSymClear $varname CATSymTable $varname } proc CATSymSave {varname} { upvar #0 $varname var global $varname global $var(symdb) set fn [SaveFileDialog catsymfbox] if {$fn != {}} { starbase_write $var(symdb) $fn } } proc CATSymLoad {varname} { upvar #0 $varname var global $varname global $var(symdb) set fn [OpenFileDialog catsymfbox] if {$fn != {}} { if {[file exists $fn]} { if [info exists $var(symdb)] { unset $var(symdb) } starbase_read $var(symdb) $fn CATSymUpdate $varname } else { Error "[msgcat::mc {Unable to open file}] $fn" return } } } proc CATSymClear {varname} { upvar #0 $varname var global $varname $var(tbl) selection clear all set var(row) {} set var(condition) {} set var(shape) {} set var(color) {} set var(font) {} set var(font,size) {} set var(font,weight) {} set var(font,slant) {} set var(text) {} set var(size) {} set var(size2) {} set var(units) {} set var(angle) {} } # Support proc CATSymDBInit {varname} { upvar #0 $varname var global $varname global $var(symdb) global pcat if [info exists $var(symdb)] { unset $var(symdb) } starbase_new $var(symdb) condition shape color \ font fontsize fontweight fontslant text size size2 units angle starbase_rowins $var(symdb) 1 starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) shape] $pcat(sym,shape) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) color] $pcat(sym,color) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) font] $pcat(sym,font) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) fontsize] $pcat(sym,font,size) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) fontweight] $pcat(sym,font,weight) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) fontslant] $pcat(sym,font,slant) starbase_set $var(symdb) 1 \ [starbase_colnum $var(symdb) units] $pcat(sym,units) } proc CATSymUpdate {varname} { upvar #0 $varname var global $varname CATGenerate $var(parent) } proc CATSymTable {varname} { upvar #0 $varname var global $varname global $var(symdb) global icatsym set nc [starbase_ncols $var(symdb)] if { $nc > $icatsym(mincols)} { $var(tbl) configure -cols $nc } else { $var(tbl) configure -cols $icatsym(mincols) } # add header row set nr [expr [starbase_nrows $var(symdb)]+1] if {$nr > $icatsym(minrows)} { $var(tbl) configure -rows $nr } else { $var(tbl) configure -rows $icatsym(minrows) } } proc CATSymSelectCB {varname} { upvar #0 $varname var global $varname global $var(symdb) set ss "[$var(tbl) curselection]" set var(row) [string trim [lindex [split $ss ,] 0]] if {$var(row) != {}} { if {$var(row) <= [starbase_nrows $var(symdb)]} { set var(condition) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) condition]] set var(shape) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) shape]] set var(color) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) color]] set var(font) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) font]] set var(font,size) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontsize]] set var(font,weight) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontweight]] set var(font,slant) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) fontslant]] set var(text) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) text]] set var(size) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size]] set var(size2) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) size2]] set var(units) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) units]] set var(angle) [starbase_get $var(symdb) $var(row) \ [starbase_colnum $var(symdb) angle]] return } } CATSymClear $varname } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotprocess.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000035442�12027150001�014747� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProcessPlotCmd {xarname iname buf fn} { upvar $xarname xar upvar $iname i global iap set varname $iap(tt) set id 0 # check for next command line option if {[string range [lindex $xar $i] 0 0] != {-}} { # determine which plot switch -- [string tolower [lindex $xar $i]] { {} - bar - scatter - new {} data - load - save - clear - loadconfig - saveconfig - print - page - pagesetup - close - graph - font - dataset - view - color - line { set varname [lindex $iap(windows) end] set id [lsearch $iap(windows) $varname] } default { set varname [lindex $xar $i] set id [lsearch $iap(windows) $varname] incr i } } } # we better have a tt by now if {$id == -1} { Error "[msgcat::mc {Unable to find plot window}] $varname" return } upvar #0 $varname var global $varname # check for next command line option if {[string range [lindex $xar $i] 0 0] != {-}} { # now, process plot command switch -- [string tolower [lindex $xar $i]] { {} - bar - scatter { if {$buf != {}} { ProcessPlotNew $varname $xarname $iname $buf } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set txt [read $ch] close $ch ProcessPlotNew $varname $xarname $iname $txt } } else { ProcessPlotNew $varname $xarname $iname {} } } new { incr i switch -- [lindex $xar $i] { name { set varname [lindex $xar [expr $i+1]] incr i 2 } } if {$buf != {}} { ProcessPlotNew $varname $xarname $iname $buf } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set txt [read $ch] close $ch ProcessPlotNew $varname $xarname $iname $txt } } else { ProcessPlotNew $varname $xarname $iname {} } } data { incr i if {$buf != {}} { ProcessPlotData $varname $xarname $iname $buf } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set txt [read $ch] close $ch ProcessPlotData $varname $xarname $iname $txt } } } load { set ff [lindex $xar [expr $i+1]] set dim [lindex $xar [expr $i+2]] incr i 2 PlotLoadDataFile $varname $ff $dim FileLast apdatafbox $ff } save { incr i set ff [lindex $xar $i] PlotSaveDataFile $varname $ff FileLast apdatafbox $ff } clear { PlotClearData $varname } loadconfig { incr i set ff [lindex $xar $i] PlotLoadConfigFile $varname $ff FileLast apconfigfbox $ff } saveconfig { incr i set ff [lindex $xar $i] PlotSaveConfigFile $varname $ff FileLast apconfigfbox $ff } print { incr i ProcessPlotPrint $varname $xarname $iname } page - pagesetup { incr i ProcessPlotPageSetup $varname $xarname $iname } close { PlotDestroy $varname } graph { incr i ProcessPlotGraph $varname $xarname $iname } font { incr i ProcessPlotFont $varname $xarname $iname } dataset { incr i PlotProcessDataset $varname $xarname $iname } view { incr i PlotProcessView $varname $xarname $iname } color { incr i PlotProcessColor $varname $xarname $iname } line { incr i PlotProcessLine $varname $xarname $iname } } } else { ProcessPlotNew $varname $xarname $iname {} } } proc ProcessSendPlotCmd {proc id param} { global iap $proc $id "$iap(windows)\n" } proc ProcessPlotNew {varname xarname iname buf} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i # check for next command line option if {[string range [lindex $xar $i] 0 0] != {-}} { switch -- [string tolower [lindex $xar $i]] { line {incr i; ProcessPlotNewOne line $varname $xarname $iname $buf} bar {incr i;ProcessPlotNewOne bar $varname $xarname $iname $buf} scatter {incr i;ProcessPlotNewOne scatter $varname $xarname $iname $buf} default {ProcessPlotNewOne line $varname $xarname $iname $buf} } } else { PlotLine $varname {} {} {} {} xy $buf incr i -1 } } proc ProcessPlotNewOne {which varname xarname iname buf} { upvar #0 $varname var global $varname upvar 3 $xarname xar upvar 3 $iname i if {[string range [lindex $xar $i] 0 0] != {-}} { switch -- [string tolower [lindex $xar $i]] { stdin {incr i; AnalysisPlotStdin $which $varname {} $buf} {} { switch $which { line {PlotLine $varname {} {} {} {} xy $buf} bar {PlotBar $varname {} {} {} {} xy $buf} scatter {PlotScatter $varname {} {} {} {} xy $buf} } } default { switch $which { line { PlotLine $varname {} \ [lindex $xar $i] \ [lindex $xar [expr $i+1]] \ [lindex $xar [expr $i+2]] \ [lindex $xar [expr $i+3]] \ $buf } bar { PlotBar $varname {} \ [lindex $xar $i] \ [lindex $xar [expr $i+1]] \ [lindex $xar [expr $i+2]] \ [lindex $xar [expr $i+3]] \ $buf } scatter { PlotScatter $varname {} \ [lindex $xar $i] \ [lindex $xar [expr $i+1]] \ [lindex $xar [expr $i+2]] \ [lindex $xar [expr $i+3]] \ $buf } } incr i 3 } } } else { switch $which { line {PlotLine $varname {} {} {} {} xy $buf} bar {PlotBar $varname {} {} {} {} xy $buf} scatter {PlotScatter $varname {} {} {} {} xy $buf} } incr i -1 } } proc ProcessPlotData {varname xarname iname buf} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i PlotRaise $varname PlotDataSet $varname [lindex $xar $i] $buf $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc ProcessPlotPrint {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i global ps global current switch -- [string tolower [lindex $xar $i]] { destination {incr i; set ps(dest) [lindex $xar $i]} command {incr i; set ps(cmd) [lindex $xar $i]} filename {incr i; set ps(filename) [lindex $xar $i] } palette - color {incr i; set ps(color) [lindex $xar $i] } {} {PlotPostScript $varname} default {incr i -1; PlotPostScript $varname} } } proc ProcessPlotPageSetup {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i global ps switch -- [string tolower [lindex $xar $i]] { orientation - orient {incr i; set ps(orient) [lindex $xar $i]} pagesize - size {incr i; set ps(size) [lindex $xar $i] } } } proc ProcessPlotGraph {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i switch -- [string tolower [lindex $xar $i]] { scale { # backward compatibility incr i switch -- [string tolower [lindex $xar $i]] { linearlinear { set var(graph,x,log) 0 set var(graph,y,log) 0 } linearlog { set var(graph,x,log) 0 set var(graph,y,log) 1 } loglinear { set var(graph,x,log) 1 set var(graph,y,log) 0 } loglog { set var(graph,x,log) 1 set var(graph,y,log) 1 } } $var(proc,updategraph) $varname } grid { incr i; switch -- [string tolower [lindex $xar $i]] { x { incr i; set var(graph,x,grid) [FromYesNo [lindex $xar $i]] } y { incr i; set var(graph,y,grid) [FromYesNo [lindex $xar $i]] } default { # backward compatibility set var(graph,y,grid) [FromYesNo [lindex $xar $i]] set var(graph,x,grid) [FromYesNo [lindex $xar $i]] } } $var(proc,updategraph) $varname } log { incr i; switch -- [string tolower [lindex $xar $i]] { x { incr i; set var(graph,x,log) [FromYesNo [lindex $xar $i]] } y { incr i; set var(graph,y,log) [FromYesNo [lindex $xar $i]] } } $var(proc,updategraph) $varname } flip { incr i; switch -- [string tolower [lindex $xar $i]] { x { incr i; set var(graph,x,flip) [FromYesNo [lindex $xar $i]] } y { incr i; set var(graph,y,flip) [FromYesNo [lindex $xar $i]] } } $var(proc,updategraph) $varname } format { incr i switch -- [string tolower [lindex $xar $i]] { x {incr i; set var(graph,x,format) [lindex $xar $i]} y {incr i; set var(graph,y,format) [lindex $xar $i]} } $var(proc,updategraph) $varname } range { incr i switch -- [string tolower [lindex $xar $i]] { x { incr i switch -- [string tolower [lindex $xar $i]] { auto {incr i; set var(graph,x,auto) \ [FromYesNo [lindex $xar $i]]} min {incr i; set var(graph,x,min) [lindex $xar $i]} max {incr i; set var(graph,x,max) [lindex $xar $i]} } } y { incr i switch -- [string tolower [lindex $xar $i]] { auto {incr i; set var(graph,y,auto) \ [FromYesNo [lindex $xar $i]]} min {incr i; set var(graph,y,min) [lindex $xar $i]} max {incr i; set var(graph,y,max) [lindex $xar $i]} } } } $var(proc,updategraph) $varname } labels { incr i switch -- [string tolower [lindex $xar $i]] { title {incr i; set var(graph,title) [lindex $xar $i]} xaxis {incr i; set var(graph,xaxis) [lindex $xar $i]} yaxis {incr i; set var(graph,yaxis) [lindex $xar $i]} } $var(proc,updategraph) $varname } } } proc ProcessPlotFont {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i switch -- [string tolower [lindex $xar $i]] { numbers { incr i switch -- [string tolower [lindex $xar $i]] { font {incr i; set var(numlabFont) [lindex $xar $i]} size {incr i; set var(numlabSize) [lindex $xar $i]} weight {incr i; set var(numlabWeight) [lindex $xar $i]} slant {incr i; set var(numlabSlant) [lindex $xar $i]} style { incr i switch [string tolower [lindex $xar $i]] { normal { set var(numlabWeight) normal set var(numlabSlant) roman } bold { set var(numlabWeight) bold set var(numlabSlant) roman } italic { set var(numlabWeight) normal set var(numlabSlant) italic } } } } } labels { incr i switch -- [string tolower [lindex $xar $i]] { font {incr i; set var(textlabFont) [lindex $xar $i]} size {incr i; set var(textlabSize) [lindex $xar $i]} weight {incr i; set var(textlabWeight) [lindex $xar $i]} slant {incr i; set var(textlabSlant) [lindex $xar $i]} style { incr i switch [string tolower [lindex $xar $i]] { normal { set var(textlabWeight) normal set var(textlabSlant) roman } bold { set var(textlabWeight) bold set var(textlabSlant) roman } italic { set var(textlabWeight) normal set var(textlabSlant) italic } } } } } title { incr i switch -- [string tolower [lindex $xar $i]] { font {incr i; set var(titleFont) [lindex $xar $i]} size {incr i; set var(titleSize) [lindex $xar $i]} weight {incr i; set var(titleWeight) [lindex $xar $i]} slant {incr i; set var(titleSlant) [lindex $xar $i]} style { incr i switch [string tolower [lindex $xar $i]] { normal { set var(titleWeight) normal set var(titleSlant) roman } bold { set var(titleWeight) bold set var(titleSlant) roman } italic { set var(titleWeight) normal set var(titleSlant) italic } } } } } } $var(proc,updategraph) $varname } proc PlotProcessDataset {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i set var(data,current) [lindex $xar $i] PlotCurrentData $varname } proc PlotProcessView {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i switch -- [string tolower [lindex $xar $i]] { discrete {incr i; set var(discrete) [FromYesNo [lindex $xar $i]]} line - linear {incr i; set var(linear) [FromYesNo [lindex $xar $i]]} step {incr i; set var(step) [FromYesNo [lindex $xar $i]]} quadratic {incr i; set var(quadratic) [FromYesNo [lindex $xar $i]]} error - errorbar {incr i; set var(error) [FromYesNo [lindex $xar $i]]} } $var(proc,updateelement) $varname } proc PlotProcessColor {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i switch -- [string tolower [lindex $xar $i]] { discrete { incr i set var(discrete,color) [lindex $xar $i] PlotUpdateElementDiscrete $varname } line - linear { incr i set var(linear,color) [lindex $xar $i] PlotUpdateElementLinear $varname } step { incr i set var(step,color) [lindex $xar $i] PlotUpdateElementStep $varname } quadratic { incr i set var(quadratic,color) [lindex $xar $i] PlotUpdateElementQuadratic $varname } error - errorbar { incr i set var(error,color) [lindex $xar $i] PlotUpdateElementError $varname } bar { incr i set var(bar,color) [lindex $xar $i] PlotUpdateElementBar $varname } } } proc PlotProcessLine {varname xarname iname} { upvar #0 $varname var global $varname upvar 2 $xarname xar upvar 2 $iname i switch -- [string tolower [lindex $xar $i]] { discrete { incr i switch -- [string tolower [lindex $xar $i]] { symbol { incr i set var(discrete,symbol) [lindex $xar $i] } fill { incr i set var(linear,fill) [lindex $xar $i]} default { set var(discrete,symbol) [lindex $xar $i] } } PlotUpdateElementDiscrete $varname } line - linear { incr i switch -- [string tolower [lindex $xar $i]] { width {incr i; set var(linear,width) [lindex $xar $i]} dash { incr i set var(linear,dash) [lindex $xar $i]} } PlotUpdateElementLinear $varname } step { incr i switch -- [string tolower [lindex $xar $i]] { width {incr i; set var(step,width) [lindex $xar $i]} dash { incr i set var(step,dash) [lindex $xar $i]} } PlotUpdateElementStep $varname } quadratic { incr i switch -- [string tolower [lindex $xar $i]] { width {incr i; set var(quadratic,width) [lindex $xar $i]} dash { incr i set var(quadratic,dash) [lindex $xar $i]} } PlotUpdateElementQuadratic $varname } error - errorbar { incr i switch -- [string tolower [lindex $xar $i]] { width {incr i; set var(error,width) [lindex $xar $i]} style { # backward compatibility incr i; } } PlotUpdateElementError $varname } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/smosaic.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000001110�12107476366�014041� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProcessSMosaicCmd {varname iname sock fn} { upvar $varname var upvar $iname i set vvar $var set ii $i switch -- [string tolower [lindex $var $i]] { iraf { incr ii ProcessSMosaicIRAFCmd vvar ii $sock $fn } {} { set vvar [linsert $var $i wcs] ProcessSMosaicWCSCmd vvar ii $sock $fn } default {ProcessSMosaicWCSCmd vvar ii $sock $fn} } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/first.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000010637�11700665567�013551� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc FIRSTDef {} { global first global ifirst set ifirst(top) .first set ifirst(mb) .firstmb set first(sky) fk5 set first(rformat) arcmin set first(width) 15 set first(height) 15 set first(mode) new set first(save) 0 set first(valid) 1 set first(survey) first } proc FIRSTDialog {} { global first global ifirst global wcs if [winfo exists $ifirst(top)] { raise $ifirst(top) return } set varname dfirst upvar #0 $varname var global $varname set var(top) $ifirst(top) set var(mb) $ifirst(mb) set var(sky) $first(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $first(rformat) set var(width) $first(width) set var(height) $first(height) set var(mode) $first(mode) set var(save) $first(save) set var(valid) $first(valid) set var(survey) $first(survey) set w $var(top) IMGSVRInit $varname "VLA-FIRST [msgcat::mc {Server}]" FIRSTExec FIRSTAck IMGSVRUpdate $varname 1 } proc FIRSTExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set var(fn) [tmpnam ds9first ".fits"] } # skyformat switch -- $var(skyformat) { degrees { set xx [uformat d h: $var(x)] set yy [uformat d d: $var(y)] } sexagesimal { set xx $var(x) set yy $var(y) } } # size - convert to arcmin switch -- $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] if {$rr>60} { set rr 60 } set var(query) [http::formatQuery .submit "Extract the Cutout" RA "$xx $yy" Equinox J2000 ImageSize $rr MaxInt 10 .cgifields ImageType ImageType "FITS Image"] set var(url) "http://third.ucllnl.org/cgi-bin/firstcutout" IMGSVRLoad $varname } proc FIRSTAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the VLA FIRST This major undertaking has received the generous technical and scientific support of many individuals. The NRAO staff has provided extremely valuable assistance in many aspects of the observations themselves and in the area of software support; in particular, we are grateful to Rick Perley, Ken Sowinski, Barry Clark, and Bill Cotton in this regard. The support of the NRAO Director, Paul van den Bout, and the yeoman service provided by Frazer Owen as Chair of the Survey Oversight Committee are also greatly appreciated. We also thank the members of the Oversight Committee (Ken Chambers, Eric Feigelson, Jackie Hewitt, Gillian Knapp, and Rogier Windhorst) for their time and wise counsel in this enterprise. Acknowledgment is also due our colleagues who are involved in the ongoing FIRST effort, including Richard McMahon and Isobel Hook. This work is supported in part under the auspices of the Department of Energy by Lawrence Livermore National Laboratory under contract No. W-7405-ENG-48 and the Institute for Geophysics and Planetary Physics, whose director Charles Alcock has been particularly supportive. We also acknowledge a generous planning grant from the CalSpace Institute; support from the STScI archive group, STScI director Bob Williams, and the STScI Director's Discretionary Research Fund; computing resources from Columbia University; a grant from the National Science Foundation; a gift of computing equipment from Sun Microsystems; a NATO travel grant to support our collaboration with Richard McMahon; and an award from the National Geographic Society which, in the spirit of their support 40 years ago for the Palomar Observatory Sky Survey, will be providing funds to continue our charting of the Universe. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessFIRSTCmd {varname iname} { upvar $varname var upvar $iname i FIRSTDialog IMGSVRProcessCmd $varname $iname dfirst } proc ProcessSendFIRSTCmd {proc id param} { FIRSTDialog IMGSVRProcessSendCmd $proc $id $param dfirst } �������������������������������������������������������������������������������������������������./saods9/src/markerbaseannulus.tcl������������������������������������������������������������������0000644�0001750�0001750�00000017220�11700665570�016131� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBaseAnnulusDialog {varname} { upvar #0 $varname var global $varname set t [$var(frame) get marker $var(id) type] switch -- $t { ellipseannulus {set type "Ellipse Annulus"} boxannulus {set type "Box Annulus"} default {set type [string totitle $t]} } # variables set rr [$var(frame) get wcs] set var(system) [lindex $rr 0] set var(sky) [lindex $rr 1] set var(skyformat) [lindex $rr 2] AdjustCoordSystem $varname system set var(x) 0 set var(y) 0 # init MarkerBaseTextCB $varname MarkerBaseColorCB $varname MarkerBaseLineWidthCB $varname MarkerBasePropertyCB $varname MarkerBaseFontCB $varname $var(proc,coordCB) $varname MarkerBaseCenterMoveCB $varname # callbacks $var(frame) marker $var(id) callback delete MarkerBaseDeleteCB $varname $var(frame) marker $var(id) callback text MarkerBaseTextCB $varname $var(frame) marker $var(id) callback color MarkerBaseColorCB $varname $var(frame) marker $var(id) callback width MarkerBaseLineWidthCB $varname $var(frame) marker $var(id) callback property MarkerBasePropertyCB $varname $var(frame) marker $var(id) callback font MarkerBaseFontCB $varname $var(frame) marker $var(id) callback move MarkerBaseCenterMoveCB $varname # window Toplevel $var(top) $var(mb) 6 [msgcat::mc "$type"] \ "$var(proc,close) $varname" # menus MarkerBaseMenu $varname MarkerBaseAnnulusFileMenu $varname EditMenu $var(mb) $varname ColorMenu $var(mb).color $varname color [list MarkerBaseColor $varname] WidthDashMenu $var(mb).width $varname linewidth dash \ [list MarkerBaseLineWidth $varname] \ [list MarkerBaseProperty $varname dash] MarkerBasePropertyMenu $varname FontMenu $var(mb).font $varname font font,size font,weight \ font,slant [list MarkerBaseFont $varname] # Param set f [ttk::labelframe $var(top).param -text [msgcat::mc "Parameters"] \ -padding 2] ttk::label $f.tid -text [msgcat::mc {Number}] ttk::label $f.id -text "$var(id)" ttk::label $f.ttext -text [msgcat::mc {Text}] ttk::entry $f.text -textvariable ${varname}(text) -width 45 ttk::label $f.tcenter -text [msgcat::mc {Center}] ttk::entry $f.centerx -textvariable ${varname}(x) -width 13 ttk::entry $f.centery -textvariable ${varname}(y) -width 13 CoordMenuButton $f.ucenter $varname system 1 sky skyformat \ [list $var(proc,coordCB) $varname] CoordMenuEnable $f.ucenter.menu $varname system 1 sky skyformat grid $f.tid $f.id -padx 2 -pady 2 -sticky w grid $f.ttext $f.text - - - -padx 2 -pady 2 -sticky w grid $f.tcenter $f.centerx $f.centery $f.ucenter \ -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $var(top).buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command "$var(proc,apply) $varname" ttk::button $f.generate -text [msgcat::mc {Generate}] \ -command "$var(proc,generate) $varname" ttk::button $f.close -text [msgcat::mc {Close}] \ -command "$var(proc,close) $varname" pack $f.apply $f.generate $f.close -side left -expand true -padx 2 -pady 4 bind $var(top) <Return> "$var(proc,apply) $varname" # Fini grid $var(top).param -sticky news grid $var(top).buttons - - -sticky ew # some window managers need a hint raise $var(top) } proc MarkerBaseAnnulusFileMenu {varname} { upvar #0 $varname var global $varname menu $var(mb).file $var(mb).file add command -label [msgcat::mc {Apply}] \ -command "$var(proc,apply) $varname" $var(mb).file add command -label [msgcat::mc {Generate}] \ -command "$var(proc,generate) $varname" $var(mb).file add separator $var(mb).file add command -label [msgcat::mc {Close}] \ -command "$var(proc,close) $varname" } proc MarkerBaseAnnulusMethodMenu {varname} { upvar #0 $varname var global $varname $var(mb) add cascade -label [msgcat::mc {Method}] -menu $var(mb).method menu $var(mb).method $var(mb).method add radiobutton -label [msgcat::mc {Equal Distance}] \ -variable ${varname}(method) -value dist $var(mb).method add radiobutton -label [msgcat::mc {Equal Area}] \ -variable ${varname}(method) -value area } proc MarkerBaseAnnulusGenerateCircle {varname} { upvar #0 $varname var global $varname $var(annulitxt) delete 1.0 end if {$var(annuli) < 1} { set var(annuli) 1 } set inner $var(inner) set outer $var(outer) set annuli $var(annuli) if {($inner != {}) && ($outer != {}) && ($annuli != {})} { switch -- $var(method) { dist { for {set i 0} {$i<=$annuli} {incr i} { $var(annulitxt) insert end \ "[expr ((($outer-$inner)/double($annuli))*$i)+$inner]\n" } } area { set pi 3.14159265358979323846 set area [expr $pi*(($outer*$outer)-($inner*$inner))/$annuli] set r0 $inner $var(annulitxt) insert end "$r0\n" for {set i 0} {$i<$annuli} {incr i} { set r1 [expr sqrt(($area+($pi*$r0*$r0))/$pi)] $var(annulitxt) insert end \ [format "%.4f\n" $r1] set r0 $r1 } } } } } proc MarkerBaseAnnulusGenerateEllipse {varname} { upvar #0 $varname var global $varname $var(annulitxt) delete 1.0 end if {$var(annuli) < 1} { set var(annuli) 1 } set radius1 $var(radius1) set radius2 $var(radius2) set radius3 $var(radius3) set annuli $var(annuli) if {($radius1 != {}) && ($radius2 != {}) && \ ($radius3 != {}) && ($annuli != {})} { switch -- $var(method) { dist { for {set i 0} {$i<=$annuli} {incr i} { set major [expr ((($radius1-$radius3)/double($annuli))*$i)\ +$radius3] set minor [expr $major*$radius2/$radius1] $var(annulitxt) insert end "$major $minor\n" } } area { set pi 3.14159265358979323846 set r [expr double($radius2)/$radius1] set area [expr $pi*(($radius1*$radius2)-($radius3*$radius3*$r))\ /$annuli] set major0 $radius3 set minor0 [expr $radius3*$r] $var(annulitxt) insert end "$major0 $minor0\n" for {set i 0} {$i<$annuli} {incr i} { set major1 [expr sqrt(($area+($pi*$major0*$minor0)) / \ ($pi*$r))] set minor1 [expr $major1*$r] $var(annulitxt) insert end \ [format "%.4f %.4f\n" $major1 $minor1] set major0 $major1 set minor0 $minor1 } } } } } proc MarkerBaseAnnulusGenerateBox {varname} { upvar #0 $varname var global $varname $var(annulitxt) delete 1.0 end if {$var(annuli) < 1} { set var(annuli) 1 } set radius1 $var(radius1) set radius2 $var(radius2) set radius3 $var(radius3) set annuli $var(annuli) if {($radius1 != {}) && ($radius2 != {}) && \ ($radius3 != {}) && ($annuli != {})} { if {$radius1<=0} { set radius1 1 } if {$radius2<=0} { set radius2 1 } switch -- $var(method) { dist { for {set i 0} {$i<=$annuli} {incr i} { set major [expr ((($radius1-$radius3)/$annuli)*$i)+$radius3] set minor [expr $major*$radius2/$radius1] $var(annulitxt) insert end "$major $minor\n" } } area { set r [expr double($radius2)/$radius1] set area [expr (($radius1*$radius2)-($radius3*$radius3*$r)) \ /$annuli] set major0 $radius3 set minor0 [expr $radius3*$r] $var(annulitxt) insert end "$major0 $minor0\n" for {set i 0} {$i<$annuli} {incr i} { set major1 [expr sqrt(($area+($major0*$minor0))/$r)] set minor1 [expr $major1*$r] $var(annulitxt) insert end \ [format "%.4f %.4f\n" $major1 $minor1] set major0 $major1 set minor0 $minor1 } } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/xmfbox.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000063366�11614614056�013723� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# xmfbox.tcl -- # # Implements the "Motif" style file selection dialog for the # Unix platform. This implementation is used only if the # "::tk_strictMotif" flag is set. # # RCS: @(#) $Id: xmfbox.tcl,v 1.9 2011/07/29 20:29:34 joye Exp $ # # Copyright (c) 1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Scriptics Corporation # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. namespace eval ::tk::dialog {} namespace eval ::tk::dialog::file {} # ::tk::MotifFDialog -- # # Implements a file dialog similar to the standard Motif file # selection box. # # Arguments: # type "open" or "save" # args Options parsed by the procedure. # # Results: # When -multiple is set to 0, this returns the absolute pathname # of the selected file. (NOTE: This is not the same as a single # element list.) # # When -multiple is set to > 0, this returns a Tcl list of absolute # pathnames. The argument for -multiple is ignored, but for consistency # with Windows it defines the maximum amount of memory to allocate for # the returned filenames. proc ::tk::MotifFDialog {type args} { variable ::tk::Priv set dataName __tk_filedialog upvar ::tk::dialog::file::$dataName data set w [MotifFDialog_Create $dataName $type $args] # Set a grab and claim the focus too. ::tk::SetFocusGrab $w $data(sEnt) $data(sEnt) selection range 0 end # Wait for the user to respond, then restore the focus and # return the index of the selected button. Restore the focus # before deleting the window, since otherwise the window manager # may take the focus away so we can't redirect it. Finally, # restore any grab that was in effect. vwait ::tk::Priv(selectFilePath) set result $Priv(selectFilePath) ::tk::RestoreFocusGrab $w $data(sEnt) withdraw return $result } # ::tk::MotifFDialog_Create -- # # Creates the Motif file dialog (if it doesn't exist yet) and # initialize the internal data structure associated with the # dialog. # # This procedure is used by ::tk::MotifFDialog to create the # dialog. It's also used by the test suite to test the Motif # file dialog implementation. User code shouldn't call this # procedure directly. # # Arguments: # dataName Name of the global "data" array for the file dialog. # type "Save" or "Open" # argList Options parsed by the procedure. # # Results: # Pathname of the file dialog. proc ::tk::MotifFDialog_Create {dataName type argList} { upvar ::tk::dialog::file::$dataName data MotifFDialog_Config $dataName $type $argList if {$data(-parent) eq "."} { set w .$dataName } else { set w $data(-parent).$dataName } # (re)create the dialog box if necessary # if {![winfo exists $w]} { MotifFDialog_BuildUI $w } elseif {[winfo class $w] ne "TkMotifFDialog"} { destroy $w MotifFDialog_BuildUI $w } else { set data(fEnt) $w.top.f1.ent set data(dList) $w.top.f2.a.l set data(fList) $w.top.f2.b.l set data(sEnt) $w.top.f3.ent set data(okBtn) $w.bot.ok set data(filterBtn) $w.bot.filter set data(cancelBtn) $w.bot.cancel } MotifFDialog_SetListMode $w # Dialog boxes should be transient with respect to their parent, # so that they will always stay on top of their parent window. However, # some window managers will create the window as withdrawn if the parent # window is withdrawn or iconified. Combined with the grab we put on the # window, this can hang the entire application. Therefore we only make # the dialog transient if the parent is viewable. if {[winfo viewable [winfo toplevel $data(-parent)]] } { wm transient $w $data(-parent) } MotifFDialog_FileTypes $w MotifFDialog_Update $w # Withdraw the window, then update all the geometry information # so we know how big it wants to be, then center the window in the # display (Motif style) and de-iconify it. ::tk::PlaceWindow $w widget $data(-parent) wm title $w $data(-title) return $w } # ::tk::MotifFDialog_FileTypes -- # # Checks the -filetypes option. If present this adds a list of radio- # buttons to pick the file types from. # # Arguments: # w Pathname of the tk_get*File dialogue. # # Results: # none proc ::tk::MotifFDialog_FileTypes {w} { upvar ::tk::dialog::file::[winfo name $w] data set f $w.top.f3.types destroy $f # No file types: use "*" as the filter and display no radio-buttons if {$data(-filetypes) eq ""} { set data(filter) * return } # The filetypes radiobuttons # set data(fileType) $data(-defaulttype) # Default type to first entry set initialTypeName [lindex $data(-filetypes) 0 0] if {$data(-typevariable) ne ""} { upvar #0 $data(-typevariable) typeVariable if {[info exist typeVariable]} { set initialTypeName $typeVariable } } set ix 0 set data(fileType) 0 foreach fltr $data(-filetypes) { set fname [lindex $fltr 0] if {[string first $initialTypeName $fname] == 0} { set data(fileType) $ix break } incr ix } MotifFDialog_SetFilter $w [lindex $data(-filetypes) $data(fileType)] #don't produce radiobuttons for only one filetype if {[llength $data(-filetypes)] == 1} { return } ttk::frame $f set cnt 0 if {$data(-filetypes) ne {}} { foreach type $data(-filetypes) { set title [lindex [lindex $type 0] 0] set filter [lindex $type 1] ttk::radiobutton $f.b$cnt \ -text $title \ -variable ::tk::dialog::file::[winfo name $w](fileType) \ -value $cnt \ -command [list tk::MotifFDialog_SetFilter $w $type] pack $f.b$cnt -side left incr cnt } } $f.b$data(fileType) invoke pack $f -side bottom -fill both return } # This proc gets called whenever data(filter) is set # proc ::tk::MotifFDialog_SetFilter {w type} { upvar ::tk::dialog::file::[winfo name $w] data variable ::tk::Priv set data(filter) [lindex $type 1] set Priv(selectFileType) [lindex [lindex $type 0] 0] MotifFDialog_Update $w } # ::tk::MotifFDialog_Config -- # # Iterates over the optional arguments to determine the option # values for the Motif file dialog; gives default values to # unspecified options. # # Arguments: # dataName The name of the global variable in which # data for the file dialog is stored. # type "Save" or "Open" # argList Options parsed by the procedure. proc ::tk::MotifFDialog_Config {dataName type argList} { upvar ::tk::dialog::file::$dataName data set data(type) $type # 1: the configuration specs # set specs { {-defaultextension "" "" ""} {-filetypes "" "" ""} {-initialdir "" "" ""} {-initialfile "" "" ""} {-parent "" "" "."} {-title "" "" ""} {-typevariable "" "" ""} } if {$type eq "open"} { lappend specs {-multiple "" "" "0"} } set data(-multiple) 0 # 2: default values depending on the type of the dialog # if {![info exists data(selectPath)]} { # first time the dialog has been popped up set data(selectPath) [pwd] set data(selectFile) "" } # 3: parse the arguments # tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList if {$data(-title) eq ""} { if {$type eq "open"} { if {$data(-multiple) != 0} { set data(-title) "[mc {Open Multiple Files}]" } else { set data(-title) [mc "Open"] } } else { set data(-title) [mc "Save As"] } } # 4: set the default directory and selection according to the -initial # settings # if {$data(-initialdir) ne ""} { if {[file isdirectory $data(-initialdir)]} { # set data(selectPath) [lindex [glob $data(-initialdir)] 0] set old [pwd] cd $data(-initialdir) set data(selectPath) [pwd] cd $old } else { set data(selectPath) [pwd] } # Convert the initialdir to an absolute path name. set old [pwd] cd $data(selectPath) set data(selectPath) [pwd] cd $old } set data(selectFile) $data(-initialfile) # 5. Parse the -filetypes option. It is not used by the motif # file dialog, but we check for validity of the value to make sure # the application code also runs fine with the TK file dialog. # set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)] if {![info exists data(filter)]} { set data(filter) * } if {![winfo exists $data(-parent)]} { error "bad window path name \"$data(-parent)\"" } } # ::tk::MotifFDialog_BuildUI -- # # Builds the UI components of the Motif file dialog. # # Arguments: # w Pathname of the dialog to build. # # Results: # None. proc ::tk::MotifFDialog_BuildUI {w} { set dataName [lindex [split $w .] end] upvar ::tk::dialog::file::$dataName data # Create the dialog toplevel and internal frames. # toplevel $w -class TkMotifFDialog set top [ttk::frame $w.top -relief raised -borderwidth 1] set bot [ttk::frame $w.bot -relief raised -borderwidth 1] pack $w.bot -side bottom -fill x pack $w.top -side top -expand yes -fill both set f1 [ttk::frame $top.f1] set f2 [ttk::frame $top.f2] set f3 [ttk::frame $top.f3] pack $f1 -side top -fill x pack $f3 -side bottom -fill x pack $f2 -expand yes -fill both set f2a [ttk::frame $f2.a] set f2b [ttk::frame $f2.b] grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \ -sticky news grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \ -sticky news grid rowconfigure $f2 0 -minsize 0 -weight 1 grid columnconfigure $f2 0 -minsize 0 -weight 1 grid columnconfigure $f2 1 -minsize 150 -weight 2 # The Filter box # bind [::tk::AmpWidget ttk::label $f1.lab -text [mc "Fil&ter:"] -anchor w] \ <<AltUnderlined>> [list focus $f1.ent] ttk::entry $f1.ent pack $f1.lab -side top -fill x -padx 6 -pady 4 pack $f1.ent -side top -fill x -padx 4 -pady 0 set data(fEnt) $f1.ent # The file and directory lists # set data(dList) [MotifFDialog_MakeSList $w $f2a \ [mc "&Directory:"] DList] set data(fList) [MotifFDialog_MakeSList $w $f2b \ [mc "Fi&les:"] FList] # The Selection box # bind [::tk::AmpWidget ttk::label $f3.lab -text [mc "&Selection:"] -anchor w] \ <<AltUnderlined>> [list focus $f3.ent] ttk::entry $f3.ent pack $f3.lab -side top -fill x -padx 6 -pady 0 pack $f3.ent -side top -fill x -padx 4 -pady 4 set data(sEnt) $f3.ent # The buttons # set maxWidth [::tk::mcmaxamp &OK &Filter &Cancel] set maxWidth [expr {$maxWidth<6?6:$maxWidth}] set data(okBtn) [::tk::AmpWidget ttk::button $bot.ok -text [mc "&OK"] \ -width $maxWidth \ -command [list tk::MotifFDialog_OkCmd $w]] set data(filterBtn) [::tk::AmpWidget ttk::button $bot.filter -text [mc "&Filter"] \ -width $maxWidth \ -command [list tk::MotifFDialog_FilterCmd $w]] set data(cancelBtn) [::tk::AmpWidget ttk::button $bot.cancel -text [mc "&Cancel"] \ -width $maxWidth \ -command [list tk::MotifFDialog_CancelCmd $w]] pack $bot.ok $bot.filter $bot.cancel -padx 10 -pady 10 -expand yes \ -side left # Create the bindings: # bind $w <Alt-Key> [list ::tk::AltKeyInDialog $w %A] bind $data(fEnt) <Return> [list tk::MotifFDialog_ActivateFEnt $w] bind $data(sEnt) <Return> [list tk::MotifFDialog_ActivateSEnt $w] bind $w <Escape> [list tk::MotifFDialog_CancelCmd $w] bind $w.bot <Destroy> {set ::tk::Priv(selectFilePath) {}} wm protocol $w WM_DELETE_WINDOW [list tk::MotifFDialog_CancelCmd $w] } proc ::tk::MotifFDialog_SetListMode {w} { upvar ::tk::dialog::file::[winfo name $w] data if {$data(-multiple) != 0} { set selectmode extended } else { set selectmode browse } set f $w.top.f2.b $f.l configure -selectmode $selectmode } # ::tk::MotifFDialog_MakeSList -- # # Create a scrolled-listbox and set the keyboard accelerator # bindings so that the list selection follows what the user # types. # # Arguments: # w Pathname of the dialog box. # f Frame widget inside which to create the scrolled # listbox. This frame widget already exists. # label The string to display on top of the listbox. # under Sets the -under option of the label. # cmdPrefix Specifies procedures to call when the listbox is # browsed or activated. proc ::tk::MotifFDialog_MakeSList {w f label cmdPrefix} { bind [::tk::AmpWidget ttk::label $f.lab -text $label -anchor w] \ <<AltUnderlined>> [list focus $f.l] listbox $f.l -width 12 -height 5 -exportselection 0\ -xscrollcommand [list $f.h set] -yscrollcommand [list $f.v set] ttk::scrollbar $f.v -orient vertical -takefocus 0 -command [list $f.l yview] ttk::scrollbar $f.h -orient horizontal -takefocus 0 -command [list $f.l xview] grid $f.lab -row 0 -column 0 -sticky news -rowspan 1 -columnspan 2 \ -padx 2 -pady 2 grid $f.l -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news grid $f.v -row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news grid $f.h -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news grid rowconfigure $f 0 -weight 0 -minsize 0 grid rowconfigure $f 1 -weight 1 -minsize 0 grid columnconfigure $f 0 -weight 1 -minsize 0 # bindings for the listboxes # set list $f.l bind $list <<ListboxSelect>> [list tk::MotifFDialog_Browse$cmdPrefix $w] bind $list <Double-ButtonRelease-1> \ [list tk::MotifFDialog_Activate$cmdPrefix $w] bind $list <Return> "tk::MotifFDialog_Browse$cmdPrefix [list $w]; \ tk::MotifFDialog_Activate$cmdPrefix [list $w]" bindtags $list [list Listbox $list [winfo toplevel $list] all] ListBoxKeyAccel_Set $list return $f.l } # ::tk::MotifFDialog_InterpFilter -- # # Interpret the string in the filter entry into two components: # the directory and the pattern. If the string is a relative # pathname, give a warning to the user and restore the pattern # to original. # # Arguments: # w pathname of the dialog box. # # Results: # A list of two elements. The first element is the directory # specified # by the filter. The second element is the filter # pattern itself. proc ::tk::MotifFDialog_InterpFilter {w} { upvar ::tk::dialog::file::[winfo name $w] data set text [string trim [$data(fEnt) get]] # Perform tilde substitution # set badTilde 0 if {[string index $text 0] eq "~"} { set list [file split $text] set tilde [lindex $list 0] if {[catch {set tilde [glob $tilde]}]} { set badTilde 1 } else { set text [eval file join [concat $tilde [lrange $list 1 end]]] } } # If the string is a relative pathname, combine it # with the current selectPath. set relative 0 if {[file pathtype $text] eq "relative"} { set relative 1 } elseif {$badTilde} { set relative 1 } if {$relative} { tk_messageBox -icon warning -type ok \ -message "\"$text\" must be an absolute pathname" $data(fEnt) delete 0 end $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \ $data(filter)] return [list $data(selectPath) $data(filter)] } set resolved [::tk::dialog::file::JoinFile [file dirname $text] [file tail $text]] if {[file isdirectory $resolved]} { set dir $resolved set fil $data(filter) } else { set dir [file dirname $resolved] set fil [file tail $resolved] } return [list $dir $fil] } # ::tk::MotifFDialog_Update # # Load the files and synchronize the "filter" and "selection" fields # boxes. # # Arguments: # w pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_Update {w} { upvar ::tk::dialog::file::[winfo name $w] data $data(fEnt) delete 0 end $data(fEnt) insert 0 \ [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)] $data(sEnt) delete 0 end $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \ $data(selectFile)] MotifFDialog_LoadFiles $w } # ::tk::MotifFDialog_LoadFiles -- # # Loads the files and directories into the two listboxes according # to the filter setting. # # Arguments: # w pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_LoadFiles {w} { upvar ::tk::dialog::file::[winfo name $w] data $data(dList) delete 0 end $data(fList) delete 0 end set appPWD [pwd] if {[catch {cd $data(selectPath)}]} { cd $appPWD $data(dList) insert end ".." return } # Make the dir and file lists # # For speed we only have one glob, which reduces the file system # calls (good for slow NFS networks). # # We also do two smaller sorts (files + dirs) instead of one large sort, # which gives a small speed increase. # set top 0 set dlist "" set flist "" foreach f [glob -nocomplain .* *] { if {[file isdir ./$f]} { lappend dlist $f } else { foreach pat $data(filter) { if {[string match $pat $f]} { if {[string match .* $f]} { incr top } lappend flist $f break } } } } eval [list $data(dList) insert end] [lsort -dictionary $dlist] eval [list $data(fList) insert end] [lsort -dictionary $flist] # The user probably doesn't want to see the . files. We adjust the view # so that the listbox displays all the non-dot files $data(fList) yview $top cd $appPWD } # ::tk::MotifFDialog_BrowseDList -- # # This procedure is called when the directory list is browsed # (clicked-over) by the user. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_BrowseDList {w} { upvar ::tk::dialog::file::[winfo name $w] data focus $data(dList) if {[$data(dList) curselection] eq ""} { return } set subdir [$data(dList) get [$data(dList) curselection]] if {$subdir eq ""} { return } $data(fList) selection clear 0 end set list [MotifFDialog_InterpFilter $w] set data(filter) [lindex $list 1] switch -- $subdir { . { set newSpec [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)] } .. { set newSpec [::tk::dialog::file::JoinFile [file dirname $data(selectPath)] \ $data(filter)] } default { set newSpec [::tk::dialog::file::JoinFile [::tk::dialog::file::JoinFile \ $data(selectPath) $subdir] $data(filter)] } } $data(fEnt) delete 0 end $data(fEnt) insert 0 $newSpec } # ::tk::MotifFDialog_ActivateDList -- # # This procedure is called when the directory list is activated # (double-clicked) by the user. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_ActivateDList {w} { upvar ::tk::dialog::file::[winfo name $w] data if {[$data(dList) curselection] eq ""} { return } set subdir [$data(dList) get [$data(dList) curselection]] if {$subdir eq ""} { return } $data(fList) selection clear 0 end switch -- $subdir { . { set newDir $data(selectPath) } .. { set newDir [file dirname $data(selectPath)] } default { set newDir [::tk::dialog::file::JoinFile $data(selectPath) $subdir] } } set data(selectPath) $newDir MotifFDialog_Update $w if {$subdir ne ".."} { $data(dList) selection set 0 $data(dList) activate 0 } else { $data(dList) selection set 1 $data(dList) activate 1 } } # ::tk::MotifFDialog_BrowseFList -- # # This procedure is called when the file list is browsed # (clicked-over) by the user. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_BrowseFList {w} { upvar ::tk::dialog::file::[winfo name $w] data focus $data(fList) set data(selectFile) "" foreach item [$data(fList) curselection] { lappend data(selectFile) [$data(fList) get $item] } if {[llength $data(selectFile)] == 0} { return } $data(dList) selection clear 0 end $data(fEnt) delete 0 end $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \ $data(filter)] # $data(fEnt) xview end # if it's a multiple selection box, just put in the filenames # otherwise put in the full path as usual $data(sEnt) delete 0 end if {$data(-multiple) != 0} { $data(sEnt) insert 0 $data(selectFile) } else { $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \ [lindex $data(selectFile) 0]] } # $data(sEnt) xview end } # ::tk::MotifFDialog_ActivateFList -- # # This procedure is called when the file list is activated # (double-clicked) by the user. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_ActivateFList {w} { upvar ::tk::dialog::file::[winfo name $w] data if {[$data(fList) curselection] eq ""} { return } set data(selectFile) [$data(fList) get [$data(fList) curselection]] if {$data(selectFile) eq ""} { return } else { MotifFDialog_ActivateSEnt $w } } # ::tk::MotifFDialog_ActivateFEnt -- # # This procedure is called when the user presses Return inside # the "filter" entry. It updates the dialog according to the # text inside the filter entry. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_ActivateFEnt {w} { upvar ::tk::dialog::file::[winfo name $w] data set list [MotifFDialog_InterpFilter $w] set data(selectPath) [lindex $list 0] set data(filter) [lindex $list 1] MotifFDialog_Update $w } # ::tk::MotifFDialog_ActivateSEnt -- # # This procedure is called when the user presses Return inside # the "selection" entry. It sets the ::tk::Priv(selectFilePath) # variable so that the vwait loop in tk::MotifFDialog will be # terminated. # # Arguments: # w The pathname of the dialog box. # # Results: # None. proc ::tk::MotifFDialog_ActivateSEnt {w} { variable ::tk::Priv upvar ::tk::dialog::file::[winfo name $w] data set selectFilePath [string trim [$data(sEnt) get]] if {$selectFilePath eq ""} { MotifFDialog_FilterCmd $w return } if {$data(-multiple) == 0} { set selectFilePath [list $selectFilePath] } if {[file isdirectory [lindex $selectFilePath 0]]} { set data(selectPath) [lindex [glob $selectFilePath] 0] set data(selectFile) "" MotifFDialog_Update $w return } set newFileList "" foreach item $selectFilePath { if {[file pathtype $item] ne "absolute"} { set item [file join $data(selectPath) $item] } elseif {![file exists [file dirname $item]]} { tk_messageBox -icon warning -type ok \ -message [mc {Directory "%1$s" does not exist.} \ [file dirname $item]] return } # we want to strip any filtering/ext/blocking instructions # from the file name set aa [string first "\[" $item] if {$aa > 0} { set fn [string range $item 0 [expr $aa-1]] } else { set fn $item } if {![file exists $fn]} { if {$data(type) eq "open"} { tk_messageBox -icon warning -type ok \ -message [mc {File "%1$s" does not exist.} $fn] return } } elseif {$data(type) eq "save"} { set message [format %s%s \ [mc "File \"%1\$s\" already exists.\n\n" $selectFilePath] \ [mc {Replace existing file?}]] set answer [tk_messageBox -icon warning -type yesno \ -message $message] if {$answer eq "no"} { return } } lappend newFileList $item } # Return selected filter if {[info exists data(-typevariable)] && $data(-typevariable) ne "" && [info exists data(-filetypes)] && $data(-filetypes) ne ""} { upvar #0 $data(-typevariable) typeVariable set typeVariable [lindex $data(-filetypes) $data(fileType) 0] } if {$data(-multiple) != 0} { set Priv(selectFilePath) $newFileList } else { set Priv(selectFilePath) [lindex $newFileList 0] } # Set selectFile and selectPath to first item in list set Priv(selectFile) [file tail [lindex $newFileList 0]] set Priv(selectPath) [file dirname [lindex $newFileList 0]] } proc ::tk::MotifFDialog_OkCmd {w} { upvar ::tk::dialog::file::[winfo name $w] data MotifFDialog_ActivateSEnt $w } proc ::tk::MotifFDialog_FilterCmd {w} { upvar ::tk::dialog::file::[winfo name $w] data MotifFDialog_ActivateFEnt $w } proc ::tk::MotifFDialog_CancelCmd {w} { variable ::tk::Priv set Priv(selectFilePath) "" set Priv(selectFile) "" set Priv(selectPath) "" } proc ::tk::ListBoxKeyAccel_Set {w} { bind Listbox <Any-KeyPress> "" bind $w <Destroy> [list tk::ListBoxKeyAccel_Unset $w] bind $w <Any-KeyPress> [list tk::ListBoxKeyAccel_Key $w %A] } proc ::tk::ListBoxKeyAccel_Unset {w} { variable ::tk::Priv catch {after cancel $Priv(lbAccel,$w,afterId)} unset -nocomplain Priv(lbAccel,$w) Priv(lbAccel,$w,afterId) } # ::tk::ListBoxKeyAccel_Key-- # # This procedure maintains a list of recently entered keystrokes # over a listbox widget. It arranges an idle event to move the # selection of the listbox to the entry that begins with the # keystrokes. # # Arguments: # w The pathname of the listbox. # key The key which the user just pressed. # # Results: # None. proc ::tk::ListBoxKeyAccel_Key {w key} { variable ::tk::Priv if { $key eq "" } { return } append Priv(lbAccel,$w) $key ListBoxKeyAccel_Goto $w $Priv(lbAccel,$w) catch { after cancel $Priv(lbAccel,$w,afterId) } set Priv(lbAccel,$w,afterId) [after 500 \ [list tk::ListBoxKeyAccel_Reset $w]] } proc ::tk::ListBoxKeyAccel_Goto {w string} { variable ::tk::Priv set string [string tolower $string] set end [$w index end] set theIndex -1 for {set i 0} {$i < $end} {incr i} { set item [string tolower [$w get $i]] if {[string compare $string $item] >= 0} { set theIndex $i } if {[string compare $string $item] <= 0} { set theIndex $i break } } if {$theIndex >= 0} { $w selection clear 0 end $w selection set $theIndex $theIndex $w activate $theIndex $w see $theIndex event generate $w <<ListboxSelect>> } } proc ::tk::ListBoxKeyAccel_Reset {w} { variable ::tk::Priv unset -nocomplain Priv(lbAccel,$w) } proc ::tk_getFileType {} { variable ::tk::Priv return $Priv(selectFileType) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/annulus.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000011121�12010024005�014037� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc AnnulusDialog {varname} { upvar #0 $varname var global $varname global pmarker # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord set var(method) dist # procs set var(which) annulus set var(proc,apply) AnnulusApply set var(proc,close) AnnulusClose set var(proc,generate) AnnulusGenerate set var(proc,coordCB) AnnulusCoordCB set var(proc,editCB) AnnulusEditCB set var(proc,distCB) AnnulusDistCB # base MarkerBaseAnnulusDialog $varname # menus MarkerBaseAnnulusMethodMenu $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisRadialDialog $varname # callbacks $var(frame) marker $var(id) callback edit AnnulusEditCB $varname $var(frame) marker $var(id) callback end edit AnnulusEditCB $varname set f $var(top).param # Annuli ttk::label $f.tinner -text [msgcat::mc {Inner}] ttk::label $f.touter -text [msgcat::mc {Outer}] ttk::label $f.tradius -text [msgcat::mc {Radius}] ttk::entry $f.inner -textvariable ${varname}(inner) -width 13 ttk::entry $f.outer -textvariable ${varname}(outer) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list AnnulusDistCB $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat ttk::label $f.tannuli -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable ${varname}(annuli) -width 13 grid x $f.tinner $f.touter -padx 2 -pady 2 -sticky w grid $f.tradius $f.inner $f.outer $f.uradius -padx 2 -pady 2 -sticky w grid $f.tannuli $f.annuli -padx 2 -pady 2 -sticky w # Radius set f [ttk::labelframe $var(top).radius -text [msgcat::mc {Radius}] \ -padding 2] set var(annulitxt) [text $f.txt \ -height 10 \ -width 15 \ -wrap none \ -font [font actual TkDefaultFont] \ -yscrollcommand [list $f.yscroll set] \ ] ttk::scrollbar $f.yscroll -command [list $var(annulitxt) yview] \ -orient vertical grid $var(annulitxt) $f.yscroll -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Radius Fini grid $var(top).radius -row 0 -column 1 -sticky news grid rowconfigure $var(top) 0 -weight 1 grid columnconfigure $var(top) 1 -weight 1 # init - do this last AnnulusDistCB $varname } # actions proc AnnulusClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback edit AnnulusEditCB $var(frame) marker $var(id) delete callback end edit AnnulusEditCB MarkerBaseCenterClose $varname } proc AnnulusApply {varname} { upvar #0 $varname var global $varname set levels {} regsub -all "\n" "[$var(annulitxt) get 1.0 end]" " " levels # and trim any trailing spaces set levels [string trimright $levels " "] if {$levels != {}} { $var(frame) marker $var(id) annulus radius "\{$levels\}" \ $var(dcoord) $var(dformat) } MarkerBaseCenterApply $varname } proc AnnulusGenerate {varname} { upvar #0 $varname var global $varname MarkerBaseAnnulusGenerateCircle $varname } # callbacks proc AnnulusCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "AnnulusCoordCB" } MarkerAnalysisRadialSystem $varname MarkerAnalysisStatsSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname } proc AnnulusEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "AnnulusEditCB" } set t [$var(frame) get marker $var(id) annulus radius \ $var(dcoord) $var(dformat)] set last [expr [llength $t]-1] set var(inner) [lindex $t 0] set var(outer) [lindex $t $last] set var(annuli) $last $var(annulitxt) delete 1.0 end $var(annulitxt) insert end "$t" } proc AnnulusDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "AnnulusDistCB" } AnnulusEditCB $varname } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/array.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000006017�12130604547�013522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ImportArrayFile {fn layer} { global loadParam set loadParam(file,type) array set loadParam(file,mode) {} set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer # check for stdin/gz ConvertArrayFile ProcessLoad } proc ImportArrayAlloc {path fn layer} { global loadParam set loadParam(file,type) array set loadParam(file,mode) {} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc ImportArraySocket {sock fn layer} { global loadParam set loadParam(file,type) array set loadParam(file,mode) {} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc ExportArrayFile {fn opt} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save array file "\{$fn\}" $opt } proc ExportArraySocket {sock opt} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save array socket $sock $opt } proc ProcessArrayCmd {varname iname sock fn} { upvar $varname var upvar $iname i if {[ProcessArrayBackwardCmd $varname $iname $sock $fn]} { return } global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not suppported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![ImportArraySocket $sock $param $layer]} { InitError xpa ImportArrayFile $param $layer } } else { # comm if {$fn != {}} { ImportArrayAlloc $fn $param $layer } else { ImportArrayFile $param $layer } } FinishLoad } proc ProcessSendArrayCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } set opt [string tolower [lindex $param 0]] if {$sock != {}} { # xpa ExportArraySocket $sock $opt } elseif {$fn != {}} { # comm ExportArrayFile $fn $opt $proc $id {} $fn } } # backward compatibility proc ProcessArrayBackwardCmd {varname iname sock fn} { upvar 2 $varname var upvar 2 $iname i set vvar $var set ii $i switch -- [string tolower [lindex $var $i]] { rgb { set vvar [lreplace $var 0 0] ProcessRGBArrayCmd vvar ii $sock $fn return 1 } new { switch -- [string tolower [lindex $var [expr $i+1]]] { rgb { set vvar [lreplace $var 1 1] ProcessRGBArrayCmd vvar ii $sock $fn return 1 } } } } return 0 } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/text.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000004057�11700665572�013401� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc TextDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set var(canrotate) [$var(frame) get marker $var(id) text rotate] # procs set var(which) text set var(proc,apply) TextApply set var(proc,close) TextClose set var(proc,coordCB) TextCoordCB # base MarkerBaseCenterDialog $varname # init MarkerBaseCenterRotateCB $varname # callbacks $var(frame) marker $var(id) callback rotate MarkerBaseCenterRotateCB \ $varname set f $var(top).param # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] # Rotate ttk::label $f.trotate -text [msgcat::mc {Rotate}] ttk::checkbutton $f.rotate -variable ${varname}(canrotate) \ -command "TextRotate $varname" grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w grid $f.trotate $f.rotate -padx 2 -pady 2 -sticky w } # actions proc TextClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBaseCenterClose $varname } proc TextApply {varname} { upvar #0 $varname var global $varname MarkerBaseCenterRotate $varname MarkerBaseCenterApply $varname } proc TextRotate {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) text rotate $var(canrotate) } # callbacks proc TextCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "TextCoordCB" } MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/backup.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000043134�12122652122�013643� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc BackupDialog {} { set fn [SaveFileDialog backupfbox] if {[string length $fn] != 0} { Backup $fn } } proc Backup {fn} { global ds9 global current switch $ds9(wm) { x11 - aqua {} win32 {set fn [file normalize [file nativename $fn]]} } # script, always overwrite if present if {[catch {set ch [open $fn w]}]} { Error [msgcat::mc {An error has occurred during backup}] return } # aux directory, create if needed set dir "${fn}.dir" if [file exists $dir] { if {![file isdirectory $dir]} { Error [msgcat::mc {An error has occurred during backup}] return } } else { if [catch {file mkdir $dir}] { Error [msgcat::mc {An error has occurred during backup}] return } } # update any tags if {$current(frame) != {}} { $current(frame) colorbar tag "\{[$current(colorbar) get tag]\}" } # check for newer backup version puts $ch "global ds9" puts $ch "set vv [lindex $ds9(version) 0]" puts $ch "\# this is a check for to ensure a match between the" puts $ch "\# current ds9 version matches the prefs version" puts $ch "switch -- \[string compare \$vv \[lindex \$ds9(version)\ 0\]\] {" puts $ch " -1 {" puts $ch " if {\[tk_messageBox -type yesno -icon question -message \[msgcat::mc {DS9 has detected an older backup file, do you wish to continue?}\]\] == {no}} {" puts $ch " return" puts $ch " }" puts $ch " }" puts $ch " 0 {}" puts $ch " 1 {" puts $ch " tk_messageBox -type ok -icon warning -message \[msgcat::mc {DS9 has detected a newer version of a backup file and therefore will not process this file.}\]" puts $ch " return" puts $ch " }" puts $ch "}" # and file find proc puts $ch "proc BackupFindFile {varname} {" puts $ch " upvar \$varname var" puts $ch "" puts $ch " set id \[string first \"\\\[\" \$var(file,name)\]" puts $ch " if {\$id > 0} {" puts $ch " set fn \[string range \$var(file,name) 0 \[expr \$id-1\]\]" puts $ch " set ext \[string range \$var(file,name) \$id end\]" puts $ch " } else {" puts $ch " set fn \$var(file,name)" puts $ch " set ext {}" puts $ch " }" puts $ch "" puts $ch " if {!\[file exists \$fn\]} {" puts $ch " Error \"\[msgcat::mc {Unable to load}\] \$fn\"" puts $ch " global fitsfbox" puts $ch " set fn \[OpenFileDialog fitsfbox\]" puts $ch " if {\$fn == {}} {" puts $ch " Error \[msgcat::mc {An error has occurred during restore}\]" puts $ch " return 0" puts $ch " }" puts $ch " if {!\[file exists \$fn\]} {" puts $ch " Error \[msgcat::mc {An error has occurred during restore}\]" puts $ch " return 0" puts $ch " }" puts $ch " set var(file,name) \"\$fn\$ext\"" puts $ch " }" puts $ch "" puts $ch " return 1" puts $ch "}" # Panner PannerBackup $ch # Colorbar ColorbarBackupCmaps $ch $dir switch -- $ds9(visual) { pseudocolor { ColorbarBackup $ch colorbar } truecolor { ColorbarBackup $ch colorbar ColorbarBackup $ch colorbarrgb } } # Frames foreach ff $ds9(frames) { if {![$ff has iis]} { BackupFrame $ch $ff $dir } } # Geometry BackupGUI $ch # all done close $ch } proc RestoreDialog {} { set fn [OpenFileDialog backupfbox] if {[string length $fn] != 0} { Restore $fn } } proc Restore {fn} { global ds9 if {[string length $fn] == 0} { return } switch $ds9(wm) { x11 - aqua {} win32 {set fn [file normalize [file nativename $fn]]} } # clear all frames DeleteAllFrames # kill all dialogs foreach dlg [list dtwomass dsao deso dstsci dfirst dnvss dskyview] { global $dlg if [array exists $dlg] { ARDestroy $dlg } } # kill all cats global icat foreach varname $icat(cats) { CATDestroy $varname } # kill all plots global iap foreach varname $iap(windows) { PlotDestroy $varname } set dir [file dirname $fn] set ffn [lindex [file split $fn] end] set cd [pwd] cd $dir # fix a problem with 6.1.2 global prefs set rr $prefs(version) # and load the world if {[catch {source $ffn}]} { Error [msgcat::mc {An error has occurred during restore}] global debug if {$debug(tcl,restore)} { global errorInfo puts stderr "$errorInfo" } return } # historical note, vv contains version number of save set originator if {![info exists vv]} { set vv [lindex $ds9(version) 0] } # fix 6.1.2 if {$vv == {6.1.2}} { set prefs(version) $rr } # fix any prefs FixPrefs $vv # return to start dir cd $cd # and update it UpdateGraphGrid LayoutOrient UpdateActiveFrames ChangeMode UpdateDS9 } proc BackupFrame {ch which dir} { set fdir [file join $dir $which] set rdir "./[lindex [file split $dir] end]/$which" # create dir if needed if {![file isdirectory $fdir]} { if [catch {file mkdir $fdir}] { Error [msgcat::mc {An error has occurred during backup}] return } } # frame set type [$which get type] puts $ch "CreateNameNumberFrame $which $type" switch -- $type { base {BackupFrameLoad $ch $which $fdir $rdir {}} 3d { BackupFrameLoad $ch $which $fdir $rdir {} puts $ch "3DDialog" } rgb { foreach cc {{} red green blue} { BackupFrameLoad $ch $which $fdir $rdir $cc } puts $ch "RGBDialog" } } MagnifierFrameBackup $ch $which ColorFrameBackup $ch $which ColormapFrameBackup $ch $which DS9Backup $ch $which CubeBackup $ch $which RGBBackup $ch $which 3DBackup $ch $which BinBackup $ch $which ScaleBackup $ch $which PanZoomBackup $ch $which CropBackup $ch $which MarkerBackup $ch $which $fdir $rdir CentroidBackup $ch $which WCSBackup $ch $which $fdir $rdir MaskBackup $ch $which SmoothBackup $ch $which ContourBackup $ch $which $fdir $rdir GridBackup $ch $which CATBackup $ch $which $fdir $rdir } proc BackupFrameLoad {ch which fdir rdir channel} { set base $which$channel set seq 1 set varname $base global $varname if {![info exists $varname]} { # special case set varname "$base.$seq" global $varname } while {[info exists $varname]} { if {$channel != {}} { puts $ch "$which rgb channel $channel" } array set param [array get $varname] switch $param(load,type) { mmap - mmapincr - smmap - shared - sshared { if {![BackupFrameLoadMMap param $fdir $rdir]} { Error [msgcat::mc {An error has occurred during backup}] return } } alloc - allocgz { if {![BackupFrameLoadMMap param $fdir $rdir]} { BackupFrameLoadAlloc $which param $fdir $rdir } } channel - socket - socketgz - var {BackupFrameLoadAlloc $which param $fdir $rdir} photo { if {[BackupFrameLoadMMap param $fdir $rdir]} { puts $ch "global bcktmp" puts $ch "if {\[catch {image create photo -file $param(file,name)} bcktmp\]} {" puts $ch "Error \[msgcat::mc {An error has occurred during restore}\]" puts $ch "return" puts $ch "}" } else { BackupFrameLoadAlloc $which param $fdir $rdir } } } puts $ch "global loadParam" puts $ch "array set loadParam \[list [array get param]\]" switch $param(load,type) { photo { puts $ch "set loadParam(var,name) \$bcktmp" } } puts $ch "if \[BackupFindFile loadParam\] {" puts $ch " ProcessLoad" puts $ch "}" switch $param(load,type) { photo { puts $ch "image delete \$bcktmp" } } incr seq set varname "$base.$seq" global $varname } } proc BackupFrameLoadMMap {varname fdir rdir} { upvar $varname param global pds9 set id [string first "\[" $param(file,name)] if {$id > 0} { set fn [string range $param(file,name) 0 [expr $id-1]] set ext [string range $param(file,name) $id end] } else { set fn $param(file,name) set ext {} } if {![file exists $fn]} { return 0 } # special case, we use 'stdin' for input from stdin, ignore if {$fn == {stdin}} { return 0 } if {$pds9(backup)} { # look for sym links switch [file type $fn] { file {} link {set fn [file readlink $fn]} default { return 0 } } set src [lindex [file split $fn] end] if {![file exists [file join $fdir $src]]} { if {[catch {file copy $fn $fdir}]} { return 0 } } set param(file,name) "$rdir/[lindex [file split $fn] end]$ext" } else { if {[file pathtype $param(file,name)] == {relative}} { set param(file,name) [file join [pwd] $param(file,name)] } } return 1 } proc BackupFrameLoadAlloc {which varname fdir rdir} { upvar $varname param set ff [$which get fits file name root base] set id [string first "\[" $ff] if {$id > 0} { set fn [string range $ff 0 [expr $id-1]] } else { set fn $ff } if {$ff == {}} { set ff ds9.fits set fn ds9.fits } set ffn [file join $fdir $fn] switch $param(file,type) { fits { switch $param(file,mode) { {} { if [$which has fits bin] { $which save fits table file \"$ffn\" } else { $which save fits image file \"$ffn\" } } {rgb cube} {$which save fits rgb cube file \"$ffn\"} {rgb image} {$which save fits rgb image file \"$ffn\"} {ext cube} {$which save fits image file \"$ffn\"} default { if {[string range $param(file,mode) 0 5] == {mosaic}} { $which save fits mosaic image file "\{$ffn\}" } } } } array { switch $param(file,mode) { {} {$which save fits image file \"$ffn\"} {rgb cube} {$which save fits rgb cube file \"$ffn\"} } } nrrd {$which save fits image file \"$ffn\"} photo { switch -- [$which get type] { base - 3d {$which save fits image file \"$ffn\"} rgb { $which save fits rgb cube file \"$ffn\" set param(file,mode) {rgb cube} } } } } set param(load,type) mmapincr set param(file,type) fits # use $fn as we are not saving multiple extentions if present set param(file,name) "[file join $rdir $fn]" } proc BackupGUI {ch} { # Basic global pds9 puts $ch "global pds9" puts $ch "array set pds9 \{ [array get pds9] \}" global current puts $ch "global current" puts $ch "array set current \{ [array get current] \}" global pcurrent puts $ch "global pcurrent" puts $ch "array set pcurrent \{ [array get pcurrent] \}" global view puts $ch "global view" puts $ch "array set view \{ [array get view] \}" global pview puts $ch "global pview" puts $ch "array set pview \{ [array get pview] \}" global canvas puts $ch "global canvas" puts $ch "array set canvas \{ [array get canvas] \}" global phttp puts $ch "global phttp" puts $ch "array set phttp \{ [array get phttp] \}" global pbuttons puts $ch "global pbuttons" puts $ch "array set pbuttons \{ [array get pbuttons] \}" global ppanner puts $ch "global ppanner" puts $ch "array set ppanner \{ [array get ppanner] \}" global pmagnifier puts $ch "global pmagnifier" puts $ch "array set pmagnifier \{ [array get pmagnifier] \}" global colorbar puts $ch "global colorbar" puts $ch "array set colorbar \{ [array get colorbar] \}" global saveimage puts $ch "global saveimage" puts $ch "array set saveimage \{ [array get saveimage] \}" # don't save prefs(version), keep the current, not the save set version # removed after 6.1.2 # global prefs # puts $ch "global prefs" # puts $ch "array set prefs \{ [array get prefs] \}" global debug puts $ch "global debug" puts $ch "array set debug \{ [array get debug] \}" # File global ps puts $ch "global ps" puts $ch "array set ps \{ [array get ps] \}" global pps puts $ch "global pps" puts $ch "array set pps \{ [array get pps] \}" # Frame global rgb puts $ch "global rgb" puts $ch "array set rgb \{ [array get rgb] \}" global threed puts $ch "global threed" puts $ch "array set threed \{ [array get threed] \}" global blink puts $ch "global blink" puts $ch "array set blink \{ [array get blink] \}" global pblink puts $ch "global pblink" puts $ch "array set pblink \{ [array get pblink] \}" global tile puts $ch "global tile" puts $ch "array set tile \{ [array get tile] \}" global ptile puts $ch "global ptile" puts $ch "array set ptile \{ [array get ptile] \}" global crosshair puts $ch "global crosshair" puts $ch "array set crosshair \{ [array get crosshair] \}" global cube puts $ch "global cube" puts $ch "array set cube \{ [array get cube] \}" # Bin global bin puts $ch "global bin" puts $ch "array set bin \{ [array get bin] \}" global pbin puts $ch "global pbin" puts $ch "array set pbin \{ [array get pbin] \}" # Zoom global panzoom puts $ch "global panzoom" puts $ch "array set panzoom \{ [array get panzoom] \}" global ppanzoom puts $ch "global ppanzoom" puts $ch "array set ppanzoom \{ [array get ppanzoom] \}" # Crop global crop puts $ch "global crop" puts $ch "array set crop \{ [array get crop] \}" # Scale global scale puts $ch "global scale" puts $ch "array set scale \{ [array get scale] \}" global pscale puts $ch "global pscale" puts $ch "array set pscale \{ [array get pscale] \}" global minmax puts $ch "global minmax" puts $ch "array set minmax \{ [array get minmax] \}" global pminmax puts $ch "global pminmax" puts $ch "array set pminmax \{ [array get pminmax] \}" global zscale puts $ch "global zscale" puts $ch "array set zscale \{ [array get zscale] \}" global pzscale puts $ch "global pzscale" puts $ch "array set pzscale \{ [array get pzscale] \}" # Region global marker puts $ch "global marker" puts $ch "array set marker \{ [array get marker] \}" global pmarker puts $ch "global pmarker" puts $ch "array set pmarker \{ [array get pmarker] \}" global centroid puts $ch "global centroid" puts $ch "array set centroid \{ [array get centroid] \}" # WCS global wcs puts $ch "global wcs" puts $ch "array set wcs \{ [array get wcs] \}" global pwcs puts $ch "global pwcs" puts $ch "array set pwcs \{ [array get pwcs] \}" # Analysis global pgraph puts $ch "global pgraph" puts $ch "array set pgraph \{ [array get pgraph] \}" global pcoord puts $ch "global pcoord" puts $ch "array set pcoord \{ [array get pcoord] \}" global pexamine puts $ch "global pexamine" puts $ch "array set pexamine \{ [array get pexamine] \}" global pixel puts $ch "global pixel" puts $ch "array set pixel \{ [array get pixel] \}" global mask puts $ch "global mask" puts $ch "array set mask \{ [array get mask] \}" global pmask puts $ch "global pmask" puts $ch "array set pmask \{ [array get pmask] \}" global contour puts $ch "global contour" puts $ch "array set contour \{ [array get contour] \}" global pcontour puts $ch "global pcontour" puts $ch "array set pcontour \{ [array get pcontour] \}" global grid puts $ch "global grid" puts $ch "array set grid \{ [array get grid] \}" global smooth puts $ch "global smooth" puts $ch "array set smooth \{ [array get smooth] \}" global psmooth puts $ch "global psmooth" puts $ch "array set psmooth \{ [array get psmooth] \}" global nres puts $ch "global nres" puts $ch "array set nres \{ [array get nres] \}" global pnres puts $ch "global pnres" puts $ch "array set pnres \{ [array get pnres] \}" global sao puts $ch "global sao" puts $ch "array set sao \{ [array get sao] \}" global eso puts $ch "global eso" puts $ch "array set eso \{ [array get eso] \}" global stsci puts $ch "global stsci" puts $ch "array set stsci \{ [array get stsci] \}" global twomass puts $ch "global twomass" puts $ch "array set twomass \{ [array get twomass] \}" global first puts $ch "global first" puts $ch "array set first \{ [array get first] \}" global nvss puts $ch "global nvss" puts $ch "array set nvss \{ [array get nvss] \}" global skyview puts $ch "global skyview" puts $ch "array set skyview \{ [array get skyview] \}" global cat puts $ch "global cat" puts $ch "array set cat \{ [array get cat] \}" global pcat puts $ch "global pcat" puts $ch "array set pcat \{ [array get pcat] \}" global pvo puts $ch "global pvo" puts $ch "array set pvo \{ [array get pvo] \}" global pap puts $ch "global pap" puts $ch "array set pap \{ [array get pap] \}" global panalysis puts $ch "global panalysis" puts $ch "array set panalysis \{ [array get panalysis] \}" global active puts $ch "global active" puts $ch "array set active \{ [array get active] \}" } proc ProcessBackupCmd {varname iname} { upvar $varname var upvar $iname i set fn [lindex $var $i] if {$fn != {}} { FileLast backupfbox $fn Backup $fn } else { Error [msgcat::mc {Unable to open file}] } } proc ProcessRestoreCmd {varname iname} { upvar $varname var upvar $iname i set fn [lindex $var $i] if {$fn != {}} { FileLast backupfbox $fn Restore $fn } else { Error [msgcat::mc {Unable to open file}] } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catcxc.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000017615�11700665566�013671� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATCXC {varname} { upvar #0 $varname var global $varname global pcat global debug if {$debug(tcl,cat)} { puts stderr "CATCXC $varname" } # go for votable or tsv if {$pcat(vot)} { CATCXCVOT $varname } else { CATCXCTSV $varname } } proc CATCXCVOT {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATCXCVOT $varname" } set var(proc,parser) CATVOTParse # coord (degrees) switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { set xx [h2d [Sex2H $var(x)]] set yy [Sex2D $var(y)] } } # size (arcmin) switch $var(rformat) { degrees { set ww $var(width) set hh $var(height) } arcmin { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } arcsec { set ww [expr $var(width)/60./60.] set hh [expr $var(height)/60./60.] } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] # output if {$var(allcols)} { set type 3 } else { set type 2 } # query set var(query) [http::formatQuery RA $xx DEC $yy SR $rr VERB $type] set var(url) "http://cda.cfa.harvard.edu/cscvo/coneSearch" CATLoad $varname } proc CATCXCTSV {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATCXCTSV $varname" } set var(proc,reader) CATCXCReader # coord (degrees) switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { switch -- $var(sky) { fk4 - fk5 - icrs {set xx [h2d [Sex2H $var(x)]]} galactic - ecliptic {set xx [Sex2D $var(x)]} } set yy [Sex2D $var(y)] } } # size (arcmin) switch $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] # output if {$var(allcols)} { set type observation } else { set type master } # query set var(query) "ra=$xx&dec=$yy&sr=$rr&type=$type" # rows if {!$var(allrows)} { append var(query) "&rows=$var(max)" } set var(url) "http://cda.cfa.harvard.edu/cscds9/coneSearch" CATLoadIncr $varname } proc CATCXCReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) 1 } 1 { # process header if {[gets $sock line] == -1} { set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) -1 return $result } set result [string length "$line"] incr ${t}(HLines) set n $T(HLines) set T(H_$n) $line if {[regexp -- {^ *(-)+ *(\t *(-)+ *)*} $line]} { # clean up header column name set hh $T(H_[expr $n-1]) regsub -all {\[} $hh {} hh regsub -all {\]} $hh {} hh set T(H_[expr $n-1]) $hh # cols set T(Header) [split $T(H_[expr $n-1]) "\t"] set T(Dashes) [split $T(H_$n) "\t"] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 2 # these are hard coded set T(Id) $T(Header) set T(DataType) {} set T(ArraySize) {} set T(Unit) {} set T(Ucd) {} # name lappend T(DataType) {char} lappend T(ArraySize) {*} lappend T(Unit) {} lappend T(Ucd) {} # ra lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {pos.eq.ra;meta.main} # dec lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {pos.eq.dec;meta.main} # err_ellipse_r0 lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # err_ellipse_r1 lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # err_ellipse_ang lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {} # conf_flag lappend T(DataType) {boolean} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # extent_flag lappend T(DataType) {boolean} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # sat_src_flag lappend T(DataType) {boolean} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # flux_aper90_b lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # flux_aper90_hilim_b lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # flux_aper90_lolim_b lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # significance lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # hard_hm lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # hard_ms lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # var_intra_index_b lappend T(DataType) {int} lappend T(ArraySize) {} lappend T(Unit) {} # var_inter_index_b lappend T(DataType) {int} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} if {[llength $T(Header)] > 17} { # obsid lappend T(DataType) {int} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # ra_aper lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {} # dec_aper lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {} # mjr_axis_aper lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # mnr_axis_aper lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {} lappend T(Ucd) {} # pos_angle_aper lappend T(DataType) {float} lappend T(ArraySize) {} lappend T(Unit) {deg} lappend T(Ucd) {} } } } 2 { # process table if {[gets $sock line] == -1} { set T(state) 0 } else { set result [string length "$line"] set line [string trim $line] if {$line != {}} { # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line "\t"] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } } } } return $result } proc CATCXCAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for CXC Request for Acknowledgment of Use of the Chandra Source Catalog Users are kindly requested to acknowledge in the acknowledgment section of any resulting publications their use of the Chandra Source Catalog. This will help us greatly to keep track of catalog usage, information that is essential for providing full accountability of our work and services, as well as for planning future services. The following language is suggested: This research has made use of data obtained from the Chandra Source Catalog, provided by the Chandra X-ray Center (CXC) as part of the Chandra Data Archive. We would like to remind you that it is also very helpful for us if you could include Dataset Identifiers in the manuscript. The Dataset Identifier for the Chandra Source Catalog is: ADS/Sa.CXO#CSC } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } �������������������������������������������������������������������������������������������������������������������./saods9/src/shm.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000014543�12122671221�013170� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProcessShmCmd {varname iname ml} { upvar $varname var upvar $iname i global loadParam global current global ds9 StartLoad set done 0 while {!$done} { # defaults set loadParam(load,type) shared set loadParam(file,type) fits set loadParam(file,mode) {} # mask not supported set loadParam(load,layer) {} set nn [lindex $var [expr $i+4]] if {$nn == {} || [string range $nn 0 0] == "-"} { set def 1 } else { set def 0 } switch -- [lindex $var $i] { key - shmid { if {$ml} { MultiLoad } set loadParam(shared,idtype) [lindex $var $i] set loadParam(shared,id) [lindex $var [expr $i+1]] set loadParam(file,name) [lindex $var [expr $i+2]] incr i 2 } fits { if {$ml} { MultiLoad } set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } sfits { if {$ml} { MultiLoad } set loadParam(load,type) sshared set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,hdr) [lindex $var [expr $i+2]] set loadParam(shared,id) [lindex $var [expr $i+3]] set loadParam(file,name) [lindex $var [expr $i+4]] incr i 4 } mosaicimage { if {$ml} { MultiLoad } if {$def} { set loadParam(file,mode) {mosaic image iraf} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } else { set loadParam(file,mode) \ [list mosaic image [lindex $var [expr $i+1]]] set loadParam(shared,idtype) [lindex $var [expr $i+2]] set loadParam(shared,id) [lindex $var [expr $i+3]] set loadParam(file,name) [lindex $var [expr $i+4]] incr i 4 } } mosaic { if {$def} { set loadParam(file,mode) {mosaic iraf} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } else { set loadParam(file,mode) \ [list mosaic [lindex $var [expr $i+1]]] set loadParam(shared,idtype) [lindex $var [expr $i+2]] set loadParam(shared,id) [lindex $var [expr $i+3]] set loadParam(file,name) [lindex $var [expr $i+4]] incr i 4 } } smosaic { set loadParam(load,type) sshared set loadParam(file,mode) \ [list mosaic [lindex $var [expr $i+1]]] set loadParam(shared,idtype) [lindex $var [expr $i+2]] set loadParam(shared,hdr) [lindex $var [expr $i+3]] set loadParam(shared,id) [lindex $var [expr $i+4]] set loadParam(file,name) [lindex $var [expr $i+5]] incr i 5 } mosaicimageiraf { # backward compatibility if {$ml} { MultiLoad } set loadParam(file,mode) {mosaic image iraf} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } mosaiciraf { # backward compatibility set loadParam(file,mode) {mosaic iraf} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } mosaicimagewcs { # backward compatibility if {$ml} { MultiLoad } set loadParam(file,mode) {mosaic image wcs} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } mosaicwcs { # backward compatibility set loadParam(file,mode) {mosaic wcs} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } mosaicimagewfpc2 { # backward compatibility if {$ml} { MultiLoad } set loadParam(file,mode) {mosaic image wfpc2} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } rgbcube { if {$ml} { CreateRGBFrame } set loadParam(file,mode) {rgb cube} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } srgbcube { if {$ml} { CreateRGBFrame } set loadParam(load,type) sshared set loadParam(file,mode) {rgb cube} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,hdr) [lindex $var [expr $i+2]] set loadParam(shared,id) [lindex $var [expr $i+3]] set loadParam(file,name) [lindex $var [expr $i+4]] incr i 4 } rgbimage { if {$ml} { CreateRGBFrame } set loadParam(file,mode) {rgb image} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } rgbarray { if {$ml} { CreateRGBFrame } set loadParam(file,type) array set loadParam(file,mode) {rgb cube} set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } array { if {$ml} { MultiLoad } set loadParam(file,type) array set loadParam(shared,idtype) [lindex $var [expr $i+1]] set loadParam(shared,id) [lindex $var [expr $i+2]] set loadParam(file,name) [lindex $var [expr $i+3]] incr i 3 } default { if {$ml} { MultiLoad } set loadParam(shared,idtype) key set loadParam(shared,id) [lindex $var $i] set loadParam(file,name) [lindex $var [expr $i+1]] incr i 1 } } ProcessLoad # more to come? incr i if {([lindex $var $i] == "-shm") || ([lindex $var $i] == "shm")} { set done 0 incr i } else { set done 1 incr i -1 } } FinishLoad } proc ProcessSendShmCmd {proc id param} { global current if {$current(frame) != {}} { $proc $id "[$current(frame) get fits file name full]\n" } } �������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/pixel.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000013122�11700665571�013526� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PixelDef {} { global pixel global ipixel global dpixel global ppixel set ipixel(top) .pixel set ipixel(mb) .pixelmb set ipixel(max) 13 set pixel(size) 5 array set ppixel [array get pixel] set dpixel(copy) {} set dpixel(tbl) {} } proc UpdatePixelTableDialog {which x y sys} { global pixel global ipixel global dpixel if {[winfo exists $ipixel(top)]} { $which get pixel table $sys $x $y $pixel(size) $pixel(size) dpixel } } proc PixelTableDialog {} { global pixel global ipixel global dpixel global ds9 if {[winfo exists $ipixel(top)]} { raise $ipixel(top) return } # create the pixel table window set w $ipixel(top) set mb $ipixel(mb) Toplevel $w $mb 6 [msgcat::mc {Pixel Table}] PixelTableDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Size}] -menu $mb.size menu $mb.file $mb.file add command -label "[msgcat::mc {Save}]..." \ -command PixelTableSaveDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command PixelTableDestroyDialog menu $mb.edit $mb.edit add command -label [msgcat::mc {Cut}] \ -state disabled -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command PixelTableCopyDialog -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -state disabled -accelerator "${ds9(ctrl)}V" menu $mb.size for {set ii 3} {$ii<=$ipixel(max)} {incr ii 2} { $mb.size add radiobutton -label "${ii}x${ii}" -variable pixel(size) \ -value $ii -command PixelTableConfigure } set f [ttk::frame $w.tbl] set dpixel(tbl) [table $f.t \ -state disabled \ -anchor w \ -font [font actual TkDefaultFont] \ -variable dpixel \ -usecommand 0 \ -maxwidth 1200 \ ] $dpixel(tbl) tag col coord 0 $dpixel(tbl) tag row coord 0 $dpixel(tbl) tag configure coord -foreground blue $dpixel(tbl) tag configure center -foreground red grid $f.t -sticky news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 set f [ttk::frame $w.buttons] ttk::button $w.buttons.close -text [msgcat::mc {Close}] \ -command PixelTableDestroyDialog pack $w.buttons.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.tbl -side top -fill both -expand true selection handle $w PixelTableExportSelection PixelTableConfigure # dummy info for {set jj 0} {$jj<=$pixel(size)} {incr jj} { for {set ii 0} {$ii<=$pixel(size)} {incr ii} { set dpixel($ii,$jj) {} } } } proc PixelTableDestroyDialog {} { global ipixel global dpixel if {[winfo exists $ipixel(top)]} { destroy $ipixel(top) destroy $ipixel(mb) } if {[info exists dpixel]} { unset dpixel } } proc PixelTableCopyDialog {} { global ipixel global dpixel set dpixel(copy) [PixelTableRender] selection own -command PixelTableLostSelection $ipixel(top) clipboard clear clipboard append $dpixel(copy) } proc PixelTableClearDialog {} { global pixel global ipixel global dpixel global dpixel if {[winfo exists $ipixel(top)]} { for {set jj 0} {$jj<=$pixel(size)} {incr jj} { for {set ii 0} {$ii<=$pixel(size)} {incr ii} { set dpixel($ii,$jj) {} } } } } proc PixelTableSaveDialog {} { set filename [SaveFileDialog pixelfbox] if {$filename != {}} { set file [open $filename w] puts -nonewline $file [PixelTableRender] close $file } } # support proc PixelTableConfigure {} { global pixel global ipixel global dpixel set ss [expr $pixel(size)+1] $dpixel(tbl) configure -rows $ss -cols $ss for {set ii 1} {$ii<=$ipixel(max)} {incr ii} { $dpixel(tbl) tag cell {} $ii,$ii } set hh [expr int($ss/2.)] $dpixel(tbl) tag cell center $hh,$hh } proc PixelTableRender {} { global pixel global dpixel set rr {} # col header append rr " " for {set ii 1} {$ii<=$pixel(size)} {incr ii} { set msg [format "%12s" $dpixel(0,${ii})] append rr "$msg" } append rr "\n" append rr " " for {set ii 1} {$ii<=$pixel(size)} {incr ii} { append rr " -----------" } append rr "\n" # body for {set jj 1} {$jj<=$pixel(size)} {incr jj} { set msg [format "%10s" $dpixel(${jj},0)] append rr "$msg |" for {set ii 1} {$ii<=$pixel(size)} {incr ii} { set msg [format "%12.11s" $dpixel($jj,$ii)] append rr "$msg" } append rr "\n" } return $rr } proc PixelTableExportSelection {offset bytes} { global dpixel if {$dpixel(copy) != {}} { return [string range $dpixel(copy) $offset [expr $offset+$bytes]] } } proc PixelTableLostSelection {} { global dpixel set dpixel(copy) {} } # Process Cmds proc ProcessPixelTableCmd {varname iname} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { open - yes - true - on - 1 {PixelTableDialog} close - no - false - off - 0 {PixelTableDestroyDialog} default { PixelTableDialog incr i -1 } } } proc ProcessSendPixelTableCmd {proc id param sock fn} { PixelTableDialog ProcessSend $proc $id $sock $fn {.txt} [PixelTableRender] } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/colorbar.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000102750�12131573627�014215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ColorbarDef {} { global colorbar global icolorbar global pcolorbar global ds9 set icolorbar(top) .clrbar set icolorbar(mb) .clrbarmb set icolorbar(vertical,width) 75 set icolorbar(horizontal,height) 45 set icolorbar(num) 1024 set icolorbar(start) $ds9(menu,start) set icolorbar(count) 0 set icolorbar(contrib) 0 set icolorbar(user) 0 set icolorbar(private) false set icolorbar(contrib,fn) [list cubehelix0.sao cubehelix1.sao] set colorbar(lock) 0 set colorbar(size) 20 set colorbar(ticks) 11 set colorbar(map) grey set colorbar(invert) 0 set colorbar(numerics) 1 set colorbar(space) 0 set colorbar(orientation) horizontal set colorbar(tag) red set colorbar(font) helvetica set colorbar(font,size) 9 set colorbar(font,weight) normal set colorbar(font,slant) roman array set pcolorbar [array get colorbar] } proc CreateColorbar {} { global icolorbar global ds9 global canvas global view switch -- $ds9(visual) { pseudocolor { $ds9(canvas) create colorbar$ds9(visual)$ds9(depth) \ -private $icolorbar(private) \ -tag colorbar \ -anchor nw \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) # And set the two windows that where created before the # colorbar was created, to the new colormap colorbar colormap window "$ds9(main)" $ds9(canvas) bind colorbar <Motion> [list MotionColorbar %x %y] $ds9(canvas) bind colorbar <Enter> [list EnterColorbar %x %y] $ds9(canvas) bind colorbar <Leave> [list LeaveColorbar] $ds9(canvas) bind colorbar <Button-1> [list Button1Colorbar %x %y] $ds9(canvas) bind colorbar <B1-Motion> [list Motion1Colorbar %x %y] $ds9(canvas) bind colorbar <ButtonRelease-1> [list Release1Colorbar %x %y] $ds9(canvas) bind colorbar <Key> [list KeyColorbar %K %A %x %y] $ds9(canvas) bind colorbar <KeyRelease> [list KeyReleaseColorbar %K %A %x %y] } truecolor { $ds9(canvas) create colorbar$ds9(visual)$ds9(depth) \ -colors 2048 \ -tag colorbar \ -anchor nw \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) $ds9(canvas) bind colorbar <Motion> [list MotionColorbar %x %y] $ds9(canvas) bind colorbar <Enter> [list EnterColorbar %x %y] $ds9(canvas) bind colorbar <Leave> [list LeaveColorbar] $ds9(canvas) bind colorbar <Button-1> [list Button1Colorbar %x %y] $ds9(canvas) bind colorbar <B1-Motion> [list Motion1Colorbar %x %y] $ds9(canvas) bind colorbar <ButtonRelease-1> \ [list Release1Colorbar %x %y] $ds9(canvas) bind colorbar <Double-1> [list Double1Colorbar %x %y] $ds9(canvas) bind colorbar <Double-ButtonRelease-1> \ [list DoubleRelease1Colorbar %x %y] $ds9(canvas) bind colorbar <Key> [list KeyColorbar %K %A %x %y] $ds9(canvas) bind colorbar <KeyRelease> \ [list KeyReleaseColorbar %K %A %x %y] $ds9(canvas) create colorbarrgb$ds9(visual)$ds9(depth) \ -colors 2048 \ -tag colorbarrgb \ -anchor nw \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) $ds9(canvas) bind colorbarrgb <Motion> [list MotionColorbar %x %y] $ds9(canvas) bind colorbarrgb <Enter> [list EnterColorbar %x %y] $ds9(canvas) bind colorbarrgb <Leave> [list LeaveColorbar] } } LayoutColorbar } proc InitColorbar {} { global colorbar global current set current(colorbar) colorbar $current(colorbar) map "{$colorbar(map)}" $current(colorbar) invert $colorbar(invert) } proc ResetColormap {} { global colorbar global current global rgb $current(colorbar) reset if {$current(frame) != {} } { RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap [$current(colorbar) get colormap]] set colorbar(invert) [$current(colorbar) get invert] } LockColorCurrent UpdateColorDialog } proc LoadColormap {} { LoadColormapFile [OpenFileDialog colorbarfbox] } # used by backup proc LoadColormapFile {filename} { global colorbar global icolorbar global current global ds9 if {$filename != {}} { colorbar load "\{$filename\}" set id [colorbar get id] set colorbar(map) [colorbar get name] $ds9(mb).color.user add radiobutton \ -label "$colorbar(map)" \ -variable colorbar(map) \ -command [list ChangeColormapID $id] if {[winfo exists $icolorbar(top)]} { $icolorbar(mb).colormap.user add radiobutton \ -label "$colorbar(map)" \ -variable colorbar(map) \ -command [list ChangeColormapID $id] } incr icolorbar(count) ChangeColormapID $id } } proc SaveColormap {} { FileLast colorbarfbox [colorbar get file name] SaveColormapFile [SaveFileDialog colorbarfbox] } proc SaveColormapFile {filename} { if {$filename != {}} { colorbar save "\{$filename\}" } } proc LoadContrastBias {} { global dcolorbar set filename [OpenFileDialog contrastbiasfbox] if {$filename != {}} { if {![catch {set ch [open $filename r]}]} { set ll [gets $ch] close $ch set dcolorbar(contrast) [lindex $ll 0] set dcolorbar(bias) [lindex $ll 1] ApplyColormap } } } proc SaveContrastBias {} { global dcolorbar set filename [SaveFileDialog contrastbiasfbox] if {$filename != {}} { if {![catch {set ch [open $filename w]}]} { puts $ch "$dcolorbar(contrast) $dcolorbar(bias)" close $ch } } } proc EnterColorbar {x y} { global current global ds9 global debug if {$debug(tcl,events)} { puts stderr "EnterColorbar" } # check to see if this event was generated while processing other events if {$ds9(b1) || $ds9(sb1) || $ds9(cb1) || $ds9(csb1) || $ds9(b2) || $ds9(b3)} { return } $ds9(canvas) focus $current(colorbar) switch -- $current(colorbar) { colorbar {UpdateFrameInfoBox base} colorbarrgb {UpdateFrameInfoBox rgb} } } proc LeaveColorbar {} { global current global ds9 global debug if {$debug(tcl,events)} { puts stderr "LeaveColorbar" } # check to see if this event was generated while processing other events if {$ds9(b1) || $ds9(sb1) || $ds9(cb1) || $ds9(csb1) || $ds9(b2) || $ds9(b3)} { return } $ds9(canvas) focus {} ClearInfoBoxCoords } proc MotionColorbar {x y} { global current global infobox global debug if {$debug(tcl,events)} { puts stderr "MotionColorbar $x $y" } switch -- $current(colorbar) { colorbar { set infobox(value) [$current(colorbar) get value $x $y] } colorbarrgb { set vv [$current(colorbar) get value $x $y] switch -- $current(rgb) { red {set infobox(value,red) $vv} green {set infobox(value,green) $vv} blue {set infobox(value,blue) $vv} } } } } proc KeyColorbar {K A x y} { global current global debug if {$debug(tcl,events)} { puts stderr "KeyColorbar $K $A $x $y" } switch -- $current(mode) { colorbar { switch -- $K { Delete - BackSpace { $current(colorbar) tag delete $x $y if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } } } } } proc KeyReleaseColorbar {K A x y} { global current global debug if {$debug(tcl,events)} { puts stderr "KeyColorbarRelease $K $A $x $y" } switch -- $current(mode) { colorbar { } } } proc Button1Colorbar {x y} { global icolorbar global colorbar global ds9 global current global icursor global debug if {$debug(tcl,events)} { puts stderr "Button1Colorbar" } # let others know that the mouse is down set ds9(b1) 1 # turn off blinking cursor if {$icursor(timer)} { catch {after cancel $icursor(id)} set icursor(id) 0 } switch -- $current(mode) { colorbar { # are we on a tag? else create $current(colorbar) tag edit begin $x $y $colorbar(tag) } } } proc Motion1Colorbar {x y} { global icolorbar global current global ds9 global debug if {$debug(tcl,events)} { puts stderr "Motion1Colorbar" } # abort if we are here by accident (such as a double click) if {($ds9(b1) == 0) && ($ds9(sb1) == 0) && ($ds9(cb1) == 0) && ($ds9(csb1) == 0)} { return } switch -- $current(mode) { colorbar { $current(colorbar) tag edit motion $x $y if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } } } proc Release1Colorbar {x y} { global icolorbar global current global icursor global ds9 global debug if {$debug(tcl,events)} { puts stderr "Release1Colorbar" } # abort if we are here by accident (such as a double click) if {($ds9(b1) == 0) && ($ds9(sb1) == 0) && ($ds9(cb1) == 0) && ($ds9(csb1) == 0)} { return } # and turn on blinking cursor if needed if {$icursor(timer)} { CursorTimer } switch -- $current(mode) { colorbar { $current(colorbar) tag edit end $x $y if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } } # let others know that the mouse is up set ds9(b1) 0 set ds9(sb1) 0 set ds9(cb1) 0 set ds9(csb1) 0 } proc Double1Colorbar {x y} { global current global debug if {$debug(tcl,events)} { puts stderr "Double1Colorbar" } switch -- $current(mode) { colorbar { ColorTagDialog $x $y } } } proc DoubleRelease1Colorbar {x y} { global current global debug if {$debug(tcl,events)} { puts stderr "DoubleRelease1Colorbar" } switch -- $current(mode) { colorbar { } } } proc Button3Colorbar {x y} { global icolorbar global current global rgb global icursor # turn off blinking cursor if {$icursor(timer)} { catch {after cancel $icursor(id)} set icursor(id) 0 } if {$current(frame) != {}} { # we need to hold the current frame, since we may be blinking set icolorbar(frame) $current(frame) $icolorbar(frame) colormap begin } } proc Motion3Colorbar {x y} { global icolorbar global current global canvas # X sets bias set bias [expr double($x)/$canvas(width)] # Y sets contrast set contrast [expr double($y)/$canvas(height) * 10] RGBEvalLockColorbar [list $current(colorbar) adjust $contrast $bias] if {$icolorbar(frame) != {}} { # only update the current colorbar frame $icolorbar(frame) colormap motion [$current(colorbar) get colormap] } UpdateColorDialog } proc Release3Colorbar {x y} { global icolorbar global current global rgb global icursor # and turn on blinking cursor if needed if {$icursor(timer)} { CursorTimer } # only update the current colorbar frame if {$icolorbar(frame) != {}} { $icolorbar(frame) colormap end set icolorbar(frame) {} } LockColorCurrent UpdateColorDialog } proc ChangeColormapID {id} { global colorbar global current colorbar map $id if {$current(frame) != {} } { $current(frame) colormap [colorbar get colormap] set colorbar(map) [colorbar get name] set colorbar(invert) [colorbar get invert] } LockColorCurrent UpdateColorDialog } proc MatchColorCurrent {} { global current if {$current(frame) != {}} { MatchColor $current(frame) } } proc MatchColor {which} { global ds9 global current global colorbar set tt [$which get type] foreach ff $ds9(frames) { if {$ff != $which} { switch -- [$ff get type] { base - 3d { if {$tt != {rgb}} { $ff colormap [colorbar get colormap] } } rgb { if {$tt == {rgb}} { $ff colormap [colorbarrgb get colormap] } } } } } } proc LockColorCurrent {} { global current if {$current(frame) != {}} { LockColor $current(frame) } } proc LockColor {which} { global colorbar if {$colorbar(lock)} { MatchColor $which } } proc InvertColorbar {} { global colorbar global current $current(colorbar) invert $colorbar(invert) if {$current(frame) != {} } { $current(frame) colormap [$current(colorbar) get colormap] } LockColorCurrent UpdateColorDialog } proc UpdateColormapLevel {} { global icolorbar global current global debug if {$debug(tcl,update)} { puts stderr "UpdateColormapLevel" } if {$current(frame) != {}} { $current(colorbar) colormap level \ [$current(frame) get colormap level $icolorbar(num)] } else { $current(colorbar) colormap level } } proc UpdateColormapLevelMosaic {which x y sys} { global icolorbar global current global current global scale global debug if {$debug(tcl,update)} { puts stderr "UpdateColormapLevelMosaic" } if {$current(frame) == {}} { $current(colorbar) colormap level return } if {($current(frame) == $which) && ($scale(scope) == "local") && [$which has fits mosaic]} { set ext [$which get fits ext $sys $x $y] if {$current(ext) != $ext} { $current(colorbar) colormap level \ [$current(frame) get colormap level $icolorbar(num) $sys $x $y] } set current(ext) $ext } else { set current(ext) {} } } proc ColorFrameBackup {ch which} { puts $ch "$which colorbar tag \"\{[$which get colorbar tag]\}\"" puts $ch "colorbar tag \"\{[$which get colorbar tag]\}\"" } proc ColorbarSizeDialog {} { global colorbar global ds9 switch $ds9(wm) { x11 - win32 { if {[EntryDialog [msgcat::mc {Colorbar}] [msgcat::mc {Size}] 10 colorbar(size)]} { UpdateView } } aqua { # we have a race condition here. the main window needs focus # back from the dialog before UpdateView is run, otherwise, # our pretty blue buttons are not activated if {[EntryDialog [msgcat::mc {Colorbar}] [msgcat::mc {Size}] 10 colorbar(size)]} { after 100 UpdateView } } } } proc TicksDialog {} { global colorbar global ds9 switch $ds9(wm) { x11 - win32 { if {[EntryDialog [msgcat::mc {Colorbar}] [msgcat::mc {Number of Ticks}] 10 colorbar(ticks)]} { UpdateView } } aqua { # we have a race condition here. the main window needs focus # back from the dialog before UpdateView is run, otherwise, # our pretty blue buttons are not activated if {[EntryDialog [msgcat::mc {Colorbar}] [msgcat::mc {Number of Ticks}] 10 colorbar(ticks)]} { after 100 UpdateView } } } } proc OpenColorTag {} { LoadColorTag [OpenFileDialog colortagfbox] } proc LoadColorTag {fn} { global current if {$fn != {}} { $current(colorbar) tag load "\{$fn\}" if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } } proc SaveColorTag {} { global current set fn [SaveFileDialog colortagfbox] if {$fn != {}} { $current(colorbar) tag save "\{$fn\}" } } proc DeleteColorTag {} { global current $current(colorbar) tag delete if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } proc ColorTagDialog {x y} { global ds9 global current global colorbar global ed set w {.ctagd} set rr [$current(colorbar) get tag $x $y] set ed(ok) 0 set ed(id) [lindex $rr 0] set ed(start) [lindex $rr 1] set ed(stop) [lindex $rr 2] set ed(color) [lindex $rr 3] DialogCreate $w [msgcat::mc {Color}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.tstart -text [msgcat::mc {Start}] ttk::entry $f.start -textvariable ed(start) -width 10 ttk::label $f.tstop -text [msgcat::mc {Stop}] ttk::entry $f.stop -textvariable ed(stop) -width 10 ttk::label $f.tcolor -text [msgcat::mc {Color}] ColorMenuButton $f.color ed color {} grid $f.tstart $f.start -padx 2 -pady 2 -sticky w grid $f.tstop $f.stop -padx 2 -pady 2 -sticky w grid $f.tcolor $f.color -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { $current(colorbar) tag $ed(id) $ed(start) $ed(stop) $ed(color) if {$current(frame) != {}} { $current(frame) colormap [$current(colorbar) get colormap] } } set rr $ed(ok) unset ed return $rr } proc ColormapDialog {} { global colorbar global icolorbar global dcolorbar global ds9 # see if we already have a window visible if [winfo exists $icolorbar(top)] { raise $icolorbar(top) return } # create the window set w $icolorbar(top) set mb $icolorbar(mb) Toplevel $w $mb 6 [msgcat::mc {Colormap Parameters}] ColormapDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Colormap}] -menu $mb.colormap $mb add cascade -label [msgcat::mc {Color}] -menu $mb.color menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command ApplyColormap $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Colormap}]..." \ -command LoadColormap $mb.file add command -label "[msgcat::mc {Save Colormap}]..." \ -command SaveColormap $mb.file add separator $mb.file add command -label "[msgcat::mc {Download Colormap}]..." \ -command {HV cpt CPT-CITY http://soliton.vm.bytemark.co.uk/pub/cpt-city} $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Contrast/Bias}]..."\ -command LoadContrastBias $mb.file add command -label "[msgcat::mc {Save Contrast/Bias}]..." \ -command SaveContrastBias $mb.file add separator $mb.file add command -label "[msgcat::mc {Load Color Tags}]..."\ -command OpenColorTag $mb.file add command -label "[msgcat::mc {Save Color Tags}]..." \ -command SaveColorTag $mb.file add command -label "[msgcat::mc {Delete Color Tags}]..." \ -command DeleteColorTag $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command ColormapDestroyDialog EditMenu $mb icolorbar ColorMenu $mb.color colorbar tag {} menu $mb.colormap menu $mb.colormap.contrib menu $mb.colormap.user set id [colorbar list id] # base for {set ii 0} {$ii<$icolorbar(contrib)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $mb.colormap add radiobutton \ -label [msgcat::mc $name] \ -variable colorbar(map) -value $name \ -command "ChangeColormapID $jj" } # contrib for {set ii $icolorbar(contrib)} {$ii<$icolorbar(user)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $mb.colormap.contrib add radiobutton \ -label [msgcat::mc $name] \ -variable colorbar(map) -value $name \ -command "ChangeColormapID $jj" } # user for {set ii $icolorbar(user)} {$ii<$icolorbar(count)} {incr ii} { set jj [lindex $id $ii] set name [colorbar get name $jj] $mb.colormap.user add radiobutton \ -label [msgcat::mc $name] \ -variable colorbar(map) -value $name \ -command "ChangeColormapID $jj" } $mb.colormap add separator $mb.colormap add cascade -label [msgcat::mc {Contributed}] \ -menu $mb.colormap.contrib $mb.colormap add cascade -label [msgcat::mc {User}] \ -menu $mb.colormap.user $mb.colormap add separator $mb.colormap add checkbutton \ -label [msgcat::mc {Invert Colormap}] \ -variable colorbar(invert) -command InvertColorbar $mb.colormap add command -label [msgcat::mc {Reset Colormap}] \ -command ResetColormap UpdateColorDialog # Param set f [ttk::frame $w.param] slider $f.cslider 0. 10. [msgcat::mc {Contrast}] \ dcolorbar(contrast) [list AdjustColormap] slider $f.bslider 0. 1. [msgcat::mc {Bias}] \ dcolorbar(bias) [list AdjustColormap] grid $f.cslider -padx 2 -pady 2 -sticky ew grid $f.bslider -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 bind $f.cslider.slider <Button-1> BeginAdjustColormap bind $f.cslider.slider <ButtonRelease-1> EndAdjustColormap bind $f.bslider.slider <Button-1> BeginAdjustColormap bind $f.bslider.slider <ButtonRelease-1> EndAdjustColormap # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] \ -command ApplyColormap ttk::button $f.close -text [msgcat::mc {Close}] \ -command ColormapDestroyDialog pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true } proc ColormapDestroyDialog {} { global icolorbar global dcolorbar if {[winfo exists $icolorbar(top)]} { destroy $icolorbar(top) destroy $icolorbar(mb) } unset dcolorbar } proc ApplyColormap {} { global dcolorbar global current global rgb RGBEvalLockColorbar [list $current(colorbar) adjust $dcolorbar(contrast) $dcolorbar(bias)] if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap [$current(colorbar) get colormap]] LockColorCurrent } } proc BeginAdjustColormap {} { global icolorbar global current global rgb set icolorbar(adjustok) 1 if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap begin] } } proc AdjustColormap {} { global icolorbar global dcolorbar global current global rgb if {[info exists icolorbar(adjustok)]} { RGBEvalLockColorbar [list $current(colorbar) adjust $dcolorbar(contrast) $dcolorbar(bias)] if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap motion [$current(colorbar) get colormap]] } } } proc EndAdjustColormap {} { global icolorbar global current global rgb if {[info exists icolorbar(adjustok)]} { unset icolorbar(adjustok) if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap end] LockColorCurrent } } } proc UpdateColorDialog {} { global icolorbar global dcolorbar global current global debug if {$debug(tcl,update)} { puts stderr "UpdateColorDialog" } if {[winfo exists $icolorbar(top)]} { set dcolorbar(contrast) [$current(colorbar) get contrast] set dcolorbar(bias) [$current(colorbar) get bias] if {$current(frame) != {}} { switch -- [$current(frame) get type] { base - 3d { $icolorbar(mb).file entryconfig \ "[msgcat::mc {Load Colormap}]..." -state normal $icolorbar(mb).file entryconfig \ "[msgcat::mc {Save Colormap}]..." -state normal for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $icolorbar(mb).colormap entryconfig $ii -state normal } $icolorbar(mb).colormap entryconfig \ [msgcat::mc {Contributed}] -state normal $icolorbar(mb).colormap entryconfig \ [msgcat::mc {User}] -state normal } rgb { $icolorbar(mb).file entryconfig \ "[msgcat::mc {Load Colormap}]..." -state disabled $icolorbar(mb).file entryconfig \ "[msgcat::mc {Save Colormap}]..." -state disabled for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $icolorbar(mb).colormap entryconfig $ii -state disabled } $icolorbar(mb).colormap entryconfig \ [msgcat::mc {Contributed}] -state disabled $icolorbar(mb).colormap entryconfig \ [msgcat::mc {User}] -state disabled } } } else { $icolorbar(mb).file entryconfig \ "[msgcat::mc {Load Colormap}]..." -state normal $icolorbar(mb).file entryconfig \ "[msgcat::mc {Save Colormap}]..." -state normal for {set ii $icolorbar(start)} {$ii<=$icolorbar(contrib)} {incr ii} { $icolorbar(mb).colormap entryconfig $ii -state normal } $icolorbar(mb).colormap entryconfig [msgcat::mc {Contributed}] \ -state normal $icolorbar(mb).colormap entryconfig [msgcat::mc {User}] \ -state normal } } } proc LayoutColorbar {} { global colorbar global icolorbar global ds9 global canvas colorbar configure \ -size $colorbar(size) \ -ticks $colorbar(ticks) \ -numerics $colorbar(numerics) \ -space $colorbar(space) \ -font $colorbar(font) \ -fontsize $colorbar(font,size) \ -fontweight $colorbar(font,weight) \ -fontslant $colorbar(font,slant) \ if {$ds9(visual) == {truecolor}} { colorbarrgb configure \ -size $colorbar(size) \ -ticks $colorbar(ticks) \ -numerics $colorbar(numerics) \ -space $colorbar(space) \ -font $colorbar(font) \ -fontsize $colorbar(font,size) \ -fontweight $colorbar(font,weight) \ -fontslant $colorbar(font,slant) \ } switch -- $colorbar(orientation) { horizontal { set xx 0 set yy [expr $canvas(height) + $canvas(gap)] colorbar configure -x $xx -y $yy \ -width $canvas(width) \ -height $icolorbar(horizontal,height) \ -orientation 0 if {$ds9(visual) == {truecolor}} { colorbarrgb configure -x $xx -y $yy \ -width $canvas(width) \ -height $icolorbar(horizontal,height) \ -orientation 0 } } vertical { set xx [expr $canvas(width) + $canvas(gap)] set yy 0 colorbar configure -x $xx -y $yy \ -width $icolorbar(vertical,width) \ -height $canvas(height) \ -orientation 1 if {$ds9(visual) == {truecolor}} { colorbarrgb configure -x $xx -y $yy \ -width $icolorbar(vertical,width) \ -height $canvas(height) \ -orientation 1 } } } } proc ColorbarBackup {ch which} { global colorbar puts $ch "$which configure -size $colorbar(size)" puts $ch "$which configure -ticks $colorbar(ticks)" puts $ch "$which configure -numerics $colorbar(numerics)" puts $ch "$which configure -space $colorbar(space)" switch $colorbar(orientation) { horizontal {puts $ch "$which configure -orientation 0"} vertical {puts $ch "$which configure -orientation 1"} } puts $ch "$which configure -font $colorbar(font)" puts $ch "$which configure -fontsize $colorbar(font,size)" puts $ch "$which configure -fontweight $colorbar(font,weight)" puts $ch "$which configure -fontslant $colorbar(font,slant)" puts $ch "$which colorbar [$which get colorbar]" puts $ch "$which tag \"\{[$which get tag]\}\"" } proc ColormapFrameBackup {ch which} { switch -- [$which get type] { base - 3d { puts $ch "set sav \[colorbar get colorbar\]" puts $ch "colorbar colorbar [$which get colorbar]" puts $ch "$which colormap \[colorbar get colormap\]" puts $ch "colorbar colorbar \$sav" } rgb { puts $ch "set sav \[colorbarrgb get colorbar\]" puts $ch "colorbarrgb colorbar [$which get colorbar]" puts $ch "$which colormap \[colorbarrgb get colormap\]" puts $ch "colorbarrgb colorbar \$sav" } } } proc ColorbarBackupCmaps {ch dir} { global icolorbar set rdir "./[lindex [file split $dir] end]" # delete old cmaps foreach ff [glob -directory $dir -nocomplain "*.sao"] { catch {file delete -force $ff} } foreach ff [glob -directory $dir -nocomplain "*.lut"] { catch {file delete -force $ff} } # save any loaded cmaps set id [colorbar list id] if {$icolorbar(user)<[llength $id]} { for {set ii $icolorbar(user)} {$ii<[llength $id]} {incr ii} { set which [lindex $id $ii] set nn [lindex [file split [colorbar get file name $which]] end] colorbar save $which \"[file join $dir $nn]\" puts $ch "LoadColormapFile \"[file join $rdir $nn]\"" } } } # Process Cmds proc ProcessCmapCmd {varname iname} { upvar $varname var upvar $iname i global colorbar global current global ds9 global current global rgb # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { open {ColormapDialog} close {ColormapDestroyDialog} match { # backward compatibility MatchColorCurrent } lock { # backward compatibility incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set colorbar(lock) [FromYesNo [lindex $var $i]] } else { set colorbar(lock) 1 incr i -1 } LockColorCurrent } load - file { incr i set fn [lindex $var $i] LoadColormapFile $fn FileLast colormapfbox $fn } save { incr i set fn [lindex $var $i] SaveColormapFile $fn FileLast colormapfbox $fn } invert { incr i set colorbar(invert) [FromYesNo [lindex $var $i]] InvertColorbar } tag { incr i set item [string tolower [lindex $var $i]] switch $item { load {incr i; LoadColorTag [lindex $var $i]} save {incr i; $current(colorbar) tag save [lindex $var $i]} delete {DeleteColorTag} } } value { incr i set c [lindex $var $i] incr i set b [lindex $var $i] if {$current(frame) != {}} { RGBEvalLockColorbar [list $current(colorbar) adjust $c $b] RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap begin] RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap motion [$current(colorbar) get colormap]] RGBEvalLockCurrent rgb(lock,colorbar) [list $current(frame) colormap end] } LockColorCurrent UpdateColorDialog } default { switch -- [$current(frame) get type] { base - 3d { set cmap [lindex $var $i] # common variants on spellings switch -- [string tolower $cmap] { gray {set cmap grey} } set id [colorbar list id] set found 0 foreach ii $id { set title [colorbar get name $ii] if {[string equal -nocase $title $cmap]} { set colorbar(map) $title colorbar map "{$colorbar(map)}" $current(frame) colormap [colorbar get colormap] set colorbar(invert) [colorbar get invert] set found 1 break } } if {!$found} { Error "[msgcat::mc {Unknown Colormap}] $cmap" } } rgb {} } LockColorCurrent UpdateColorDialog } } } proc ProcessSendCmapCmd {proc id param} { global colorbar global current switch -- [string tolower $param] { file {$proc $id "[$current(colorbar) get file name]\n"} invert {$proc $id [ToYesNo $colorbar(invert)]} value {$proc $id "[$current(colorbar) get contrast] [$current(colorbar) get bias]\n"} lock {$proc $id [ToYesNo $colorbar(lock)]} {} {$proc $id "[$current(colorbar) get name]\n"} } } proc ProcessColorbarCmd {varname iname} { upvar $varname var upvar $iname i global colorbar global view set item [string tolower [lindex $var $i]] switch -- $item { match { # backward compatibility MatchColorCurrent } lock { # backward compatibility incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set colorbar(lock) [FromYesNo [lindex $var $i]] } else { set colorbar(lock) 1 incr i -1 } LockColorCurrent } numerics { incr i set yesno [string tolower [lindex $var $i]] set colorbar(numerics) [FromYesNo $yesno] UpdateView } space { incr i switch -- [string tolower [lindex $var $i]] { value {set item 1} default {set item 0} } set colorbar(space) $item UpdateView } font { incr i set item [string tolower [lindex $var $i]] set colorbar(font) $item UpdateView } fontsize { incr i set item [lindex $var $i] set colorbar(font,size) $item UpdateView } fontweight { incr i set item [string tolower [lindex $var $i]] set colorbar(font,weight) $item UpdateView } fontslant { incr i set item [string tolower [lindex $var $i]] set colorbar(font,slant) $item UpdateView } fontstyle { # backward compatibility incr i set item [string tolower [lindex $var $i]] switch $item { normal { set colorbar(font,weight) normal set colorbar(font,slant) roman } bold { set colorbar(font,weight) bold set colorbar(font,slant) roman } italic { set colorbar(font,weight) normal set colorbar(font,slant) italic } } UpdateView } orientation { incr i set item [string tolower [lindex $var $i]] set colorbar(orientation) $item UpdateView } vertical - horizontal { set colorbar(orientation) $item UpdateView } size { incr i set item [lindex $var $i] set colorbar(size) $item UpdateView } ticks { incr i set item [lindex $var $i] set colorbar(ticks) $item UpdateView } default { set yesno [string tolower [lindex $var $i]] set view(colorbar) [FromYesNo $yesno] UpdateView } } } proc ProcessSendColorbarCmd {proc id param} { global colorbar global view switch -- [string tolower [lindex $param 0]] { lock { #backward compatibility $proc $id [ToYesNo $colorbar(lock)] } orientation {$proc $id "$colorbar(orientation)\n"} numerics {$proc $id [ToYesNo $colorbar(numerics)]} space { if {$colorbar(space)} { $proc $id "value\n" } else { $proc $id "distance\n" } } font {$proc $id "$colorbar(font)\n"} fontsize {$proc $id "$colorbar(font,size)\n"} fontstyle - fontweight {$proc $id "$colorbar(font,weight)\n"} fontslant {$proc $id "$colorbar(font,slant)\n"} size {$proc $id "$colorbar(size)\n"} ticks {$proc $id "$colorbar(ticks)\n"} default {$proc $id [ToYesNo $view(colorbar)]} } } ������������������������./saods9/src/fits.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000020165�12131563555�013355� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadFitsFile {fn layer mode} { global loadParam global current global pds9 global marker set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer ConvertFitsFile # save load type, since ProcessLoad will clear loadParam if {$loadParam(load,type) == "mmapincr"} { set mmap 1 } else { set mmap 0 } ProcessLoad # now autoload markers if {$pds9(automarker) && $mmap} { # now, load fits[REGION] if present set id [string first "\[" $fn] if {$id > 0} { set base [string range $fn 0 [expr $id-1]] } else { set base $fn } set reg "${base}\[REGION\]" if {[$current(frame) fitsy has ext "\"$reg\""]} { RealizeDS9 catch { $current(frame) marker load fits "\"$reg\"" $marker(color) $marker(dashlist) $marker(width) "\{$marker(font) $marker(font,size) $marker(font,weight) $marker(font,slant)\}" } } } } proc LoadFitsAlloc {path fn layer mode} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc LoadFitsSocket {sock fn layer mode} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) $mode set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc SaveFitsFile {which fn} { global current if {$fn == {} || $current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits $which file "\{$fn\}" } proc SaveFitsSocket {which sock} { global current if {$current(frame) == {}} { return } if {![$current(frame) has fits]} { return } $current(frame) save fits $which socket $sock } proc ProcessFitsCmd {varname iname sock fn} { upvar $varname var upvar $iname i if {[ProcessFitsBackwardCmd $varname $iname $sock $fn]} { return } global loadParam global current set layer {} set mode {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i set mode slice } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadFitsSocket $sock $param $layer $mode]} { InitError xpa LoadFitsFile $param $layer $mode } } else { # comm if {$fn != {}} { LoadFitsAlloc $fn $param $layer $mode } else { LoadFitsFile $param $layer $mode } } FinishLoad } proc ProcessSendFitsCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } set which image switch -- [string tolower [lindex $param 0]] { width { $proc $id "[$current(frame) get fits width]\n" return } height { $proc $id "[$current(frame) get fits height]\n" return } depth { $proc $id "[$current(frame) get fits depth 2]\n" return } bitpix { $proc $id "[$current(frame) get fits bitpix]\n" return } size { set sys [lindex $param 1] set sky [lindex $param 2] set format [lindex $param 3] if {$sys == {} && $sky == {} && $format == {}} { $proc $id "[$current(frame) get fits size]\n" } else { FixSpec sys sky format image fk5 degrees $proc $id "[$current(frame) get fits size $sys $sky $format]\n" } return } header { switch -- [llength $param] { 1 {ProcessSend $proc $id {} $fn {.txt} "[$current(frame) get fits header 1]\n"} 2 {ProcessSend $proc $id {} $fn {.txt} "[$current(frame) get fits header [lindex $param 1]]\n"} 3 {$proc $id "[string trim [$current(frame) get fits header 1 keyword [lindex $param 2]]]\n"} 4 {$proc $id "[string trim [$current(frame) get fits header [lindex $param 1] keyword [lindex $param 3]]]\n"} } return } type { if {[$current(frame) has fits bin]} { $proc $id "table\n" } else { $proc $id "image\n" } return } table {set which table} image {} slice {set which slice} resample {set which resample} } if {$sock != {}} { # xpa SaveFitsSocket $which $sock } elseif {$fn != {}} { # comm SaveFitsFile $which $fn $proc $id {} $fn } } # backward compatibility proc ProcessFitsBackwardCmd {varname iname sock fn} { upvar 2 $varname var upvar 2 $iname i set vvar $var set ii $i switch -- [string tolower [lindex $var $i]] { new { switch -- [string tolower [lindex $var [expr $i+1]]] { rgbimage { set vvar [lreplace $var 1 1] ProcessRGBImageCmd vvar ii $sock $fn return 1 } rgbcube { set vvar [lreplace $var 1 1] ProcessRGBCubeCmd vvar ii $sock $fn return 1 } datacube - mecube - medatacube { set vvar [lreplace $var 1 1] ProcessMECubeCmd vvar ii $sock $fn return 1 } mosaicimage { set vvar [lreplace $var 1 1] ProcessMosaicImageCmd vvar ii $sock $fn return 1 } mosaicimagewcs { set vvar [lreplace $var 1 1] ProcessMosaicImageWCSCmd vvar ii $sock $fn return 1 } mosaicimageiraf { set vvar [lreplace $var 1 1] ProcessMosaicImageIRAFCmd vvar ii $sock $fn return 1 } mosaicimagewfpc2 { set vvar [lreplace $var 1 1] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn return 1 } mosaic { set vvar [lreplace $var 1 1] ProcessMosaicCmd vvar ii $sock $fn return 1 } mosaicwcs { set vvar [lreplace $var 1 1] ProcessMosaicWCSCmd vvar ii $sock $fn return 1 } mosaiciraf { set vvar [lreplace $var 1 1] ProcessMosaicIRAFCmd vvar ii $sock $fn return 1 } } } mask { switch -- [string tolower [lindex $var [expr $i+1]]] { mosaicimage { set vvar [lreplace $var 1 1] ProcessMosaicImageCmd vvar ii $sock $fn return 1 } mosaicimagewcs { set vvar [lreplace $var 1 1] ProcessMosaicImageWCSCmd vvar ii $sock $fn return 1 } mosaicimageiraf { set vvar [lreplace $var 1 1] ProcessMosaicImageIRAFCmd vvar ii $sock $fn return 1 } mosaicimagewfpc2 { set vvar [lreplace $var 1 1] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn return 1 } mosaic { set vvar [lreplace $var 1 1] ProcessMosaicCmd vvar ii $sock $fn return 1 } mosaicwcs { set vvar [lreplace $var 1 1] ProcessMosaicWCSCmd vvar ii $sock $fn return 1 } mosaiciraf { set vvar [lreplace $var 1 1] ProcessMosaicIRAFCmd vvar ii $sock $fn return 1 } } } datacube - mecube - medatacube { set vvar [lreplace $var 0 0] ProcessMECubeCmd vvar ii $sock $fn return 1 } memf - multiframe { set vvar [lreplace $var 0 0] ProcessMultiFrameCmd vvar ii $sock $fn return 1 } rgbimage { set vvar [lreplace $var 0 0] ProcessRGBImageCmd vvar ii $sock $fn return 1 } rgbcube { set vvar [lreplace $var 0 0] ProcessRGBCubeCmd vvar ii $sock $fn return 1 } mosaicimage { set vvar [lreplace $var 0 0] ProcessMosaicImageCmd vvar ii $sock $fn return 1 } mosaicimagewcs { set vvar [lreplace $var 0 0] ProcessMosaicImageWCSCmd vvar ii $sock $fn return 1 } mosaicimageiraf { set vvar [lreplace $var 0 0] ProcessMosaicImageIRAFCmd vvar ii $sock $fn return 1 } mosaicimagewfpc2 { set vvar [lreplace $var 0 0] ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn return 1 } mosaic { set vvar [lreplace $var 0 0] ProcessMosaicCmd vvar ii $sock $fn return 1 } mosaicwcs { set vvar [lreplace $var 0 0] ProcessMosaicWCSCmd vvar ii $sock $fn return 1 } mosaiciraf { set vvar [lreplace $var 0 0] ProcessMosaicIRAFCmd vvar ii $sock $fn return 1 } } return 0 } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/smosaicwcs.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000002377�12125367635�014574� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadSMosaicWCSFitsFile {hdr fn layer sys} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) [list mosaic $sys] set loadParam(load,type) smmap set loadParam(file,name) $fn set loadParam(file,header) $hdr set loadParam(load,layer) $layer ProcessLoad } proc ProcessSMosaicWCSCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } set opt [lindex $var $i] if {$opt != {}} { incr i } else { set opt wcs } StartLoad if {$sock != {}} { # xpa if {0} { # not supported } else { LoadSMosaicWCSFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $opt } } else { # comm if {0} { # not supported } else { LoadSMosaicWCSFile [lindex $var $i] [lindex $var [expr $i+1]] \ $layer $opt } } FinishLoad } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/compass.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000004705�11700665566�014065� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CompassDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set arrows [$var(frame) get marker $var(id) compass arrow] set var(narrow) [lindex $arrows 0] set var(earrow) [lindex $arrows 1] set labels [$var(frame) get marker $var(id) compass label] set var(north) [lindex $labels 0] set var(east) [lindex $labels 1] set s [$var(frame) get marker $var(id) compass system] set var(system) [lindex $s 0] set var(sky) [lindex $s 1] set var(skyformat) degrees # procs set var(which) compass set var(proc,apply) CompassApply set var(proc,close) CompassClose set var(proc,coordCB) CompassCoordCB # base MarkerBaseCenterDialog $varname set f $var(top).param # Labels ttk::label $f.ntitle -text [msgcat::mc {North}] ttk::entry $f.north -textvariable ${varname}(north) -width 13 ttk::checkbutton $f.narrow -variable ${varname}(narrow) \ -text [msgcat::mc {Arrow}] -command "CompassArrow $varname" ttk::label $f.etitle -text [msgcat::mc {East}] ttk::entry $f.east -textvariable ${varname}(east) -width 13 ttk::checkbutton $f.earrow -variable ${varname}(earrow) \ -text [msgcat::mc {Arrow}] -command "CompassArrow $varname" grid $f.ntitle $f.north $f.narrow -padx 2 -pady 2 -sticky w grid $f.etitle $f.east $f.earrow -padx 2 -pady 2 -sticky w } # actions proc CompassClose {varname} { upvar #0 $varname var global $varname MarkerBaseCenterClose $varname } proc CompassApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) compass label "\{$var(north)\}" "\{$var(east)\}" MarkerBaseCenterApply $varname } proc CompassArrow {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) compass arrow $var(narrow) $var(earrow) } # callbacks proc CompassCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "CompassCoordCB" } MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname $var(frame) marker $var(id) compass system $var(system) $var(sky) } �����������������������������������������������������������./saods9/src/mosaicimage.tcl������������������������������������������������������������������������0000644�0001750�0001750�00000001575�12130626345�014666� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProcessMosaicImageCmd {varname iname sock fn} { upvar $varname var upvar $iname i set vvar $var set ii $i switch -- [string tolower [lindex $var $i]] { iraf { incr ii ProcessMosaicImageIRAFCmd vvar ii $sock $fn } wfpc2 { incr ii ProcessMosaicImageWFPC2Cmd vvar ii $sock $fn } default {ProcessMosaicImageWCSCmd vvar ii $sock $fn} } } proc ProcessSendMosaicImageCmd {proc id param sock fn} { switch -- [string tolower [lindex $param 0]] { iraf {} wfpc2 {} wcs { set param [lindex $param 1 end] ProcessSendMosaicImageWCSCmd $proc $id $param $sock $fn } default {ProcessSendMosaicImageWCSCmd $proc $id $param $sock $fn} } } �����������������������������������������������������������������������������������������������������������������������������������./saods9/src/prefs.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000055207�12117712633�013531� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PrefsDef {} { global prefs global iprefs global ds9 set iprefs(top) .pf set iprefs(mb) .pfmb set iprefs(tabs) {} set prefs(version) [lindex $ds9(version) 0] } proc LoadPrefs {} { global ds9 global prefs set ds9(prefs) [SourceInitFile {.prf}] if {$ds9(prefs)} { FixPrefs $prefs(version) } } proc PostPrefs {} { global ds9 if {$ds9(prefs)} { PrefsDefaultFont set ds9(prefs) 0 } } proc CheckPrefs {} { global ds9 global prefs if {[string compare $prefs(version) [lindex $ds9(version) 0]] == -1} { if {[tk_messageBox -type yesno -icon question \ -message [msgcat::mc {DS9 has detected an older preferences file, do you wish to update?}]] \ == {yes}} { SavePrefs } } } proc ClearPrefs {} { DeleteInitFile {.prf} Info [msgcat::mc {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect}] } proc SavePrefs {} { global ds9 # make sure old prefs files are removed DeleteInitFile {.prf} # open prefs file if {[catch {set ch [open [file join [GetEnvHome] ".$ds9(app).prf"] w]}]} { Error [msgcat::mc {An error has occurred while saving}] return } puts $ch "global ds9" puts $ch "global prefs" puts $ch "set prefs(version) [lindex $ds9(version) 0]" # check for wrong prefs puts $ch "\# this is a check for to ensure a match between the" puts $ch "\# current ds9 version matches the prefs version" puts $ch "if {\[string compare \$prefs(version) \[lindex \$ds9(version)\ 0\]] == 1} {" puts $ch " tk_messageBox -type ok -icon warning -message \"\[msgcat::mc {DS9 has detected a newer version of a preferences file and therefore will not process this file.}\]\"" puts $ch " return" puts $ch "}" # Basic global pds9 puts $ch "global pds9" puts $ch "array set pds9 \{ [array get pds9] \}" global current global pcurrent puts $ch "global current" puts $ch "global pcurrent" puts $ch "array set pcurrent \{ [array get pcurrent] \}" puts $ch {array set current [array get pcurrent]} global view global pview puts $ch "global view" puts $ch "global pview" puts $ch "array set pview \{ [array get pview] \}" puts $ch {array set view [array get pview]} global phttp puts $ch "global phttp" puts $ch "array set phttp \{ [array get phttp] \}" global pbuttons puts $ch "global pbuttons" puts $ch "array set pbuttons \{ [array get pbuttons] \}" global ppanner puts $ch "global ppanner" puts $ch "array set ppanner \{ [array get ppanner] \}" global pmagnifier puts $ch "global pmagnifier" puts $ch "array set pmagnifier \{ [array get pmagnifier] \}" # File global ps global pps puts $ch "global ps" puts $ch "global pps" puts $ch "array set pps \{ [array get pps] \}" puts $ch {array set ps [array get pps]} global pr global ppr puts $ch "global pr" puts $ch "global ppr" puts $ch "array set ppr \{ [array get ppr] \}" puts $ch {array set pr [array get ppr]} # Frame global blink global pblink puts $ch "global blink" puts $ch "global pblink" puts $ch "array set pblink \{ [array get pblink] \}" puts $ch {array set blink [array get pblink]} global tile global ptile puts $ch "global tile" puts $ch "global ptile" puts $ch "array set ptile \{ [array get ptile] \}" puts $ch {array set tile [array get ptile]} global threed global pthreed puts $ch "global threed" puts $ch "global pthreed" puts $ch "array set pthreed \{ [array get pthreed] \}" puts $ch {array set threed [array get pthreed]} # Bin global bin global pbin puts $ch "global bin" puts $ch "global pbin" puts $ch "array set pbin \{ [array get pbin] \}" puts $ch {array set bin [array get pbin]} # Zoom global panzoom global ppanzoom puts $ch "global panzoom" puts $ch "global ppanzoom" puts $ch "array set ppanzoom \{ [array get ppanzoom] \}" puts $ch {array set panzoom [array get ppanzoom]} # Scale global scale global pscale puts $ch "global scale" puts $ch "global pscale" puts $ch "array set pscale \{ [array get pscale] \}" puts $ch {array set scale [array get pscale]} global minmax global pminmax puts $ch "global minmax" puts $ch "global pminmax" puts $ch "array set pminmax \{ [array get pminmax] \}" puts $ch {array set minmax [array get pminmax]} global zscale global pzscale puts $ch "global zscale" puts $ch "global pzscale" puts $ch "array set pzscale \{ [array get pzscale] \}" puts $ch {array set zscale [array get pzscale]} # Region global marker global pmarker puts $ch "global marker" puts $ch "global pmarker" puts $ch "array set pmarker \{ [array get pmarker] \}" puts $ch {array set marker [array get pmarker]} # WCS global wcs global pwcs puts $ch "global wcs" puts $ch "global pwcs" puts $ch "array set pwcs \{ [array get pwcs] \}" puts $ch {array set wcs [array get pwcs]} # Analysis global pgraph puts $ch "global pgraph" puts $ch "array set pgraph \{ [array get pgraph] \}" global pcoord puts $ch "global pcoord" puts $ch "array set pcoord \{ [array get pcoord] \}" global pexamine puts $ch "global pexamine" puts $ch "array set pexamine \{ [array get pexamine] \}" global pixel global ppixel puts $ch "global pixel" puts $ch "global ppixel" puts $ch "array set ppixel \{ [array get ppixel] \}" puts $ch {array set pixel [array get ppixel]} global mask global pmask puts $ch "global mask" puts $ch "global pmask" puts $ch "array set pmask \{ [array get pmask] \}" puts $ch {array set mask [array get pmask]} global contour global pcontour puts $ch "global contour" puts $ch "global pcontour" puts $ch "array set pcontour \{ [array get pcontour] \}" puts $ch {array set contour [array get pcontour]} global smooth global psmooth puts $ch "global smooth" puts $ch "global psmooth" puts $ch "array set psmooth \{ [array get psmooth] \}" puts $ch {array set smooth [array get psmooth]} global nres global pnres puts $ch "global nres" puts $ch "global pnres" puts $ch "array set nres \{ [array get pnres] \}" puts $ch {array set nres [array get pnres]} global pcat puts $ch "global pcat" puts $ch "array set pcat \{ [array get pcat] \}" global pvo puts $ch "global pvo" puts $ch "array set pvo \{ [array get pvo] \}" global pap puts $ch "global pap" puts $ch "array set pap \{ [array get pap] \}" global panalysis puts $ch "global panalysis" puts $ch "array set panalysis \{ [array get panalysis] \}" # Other puts $ch "" puts $ch "\# Colorbar prefs" global colorbar global pcolorbar puts $ch "global colorbar" puts $ch "global pcolorbar" puts $ch "array set pcolorbar \{ [array get pcolorbar] \}" puts $ch {array set colorbar [array get pcolorbar]} # and close close $ch } # Backward Compatibility proc FixVar {varname ovarname} { global aa bb set aa $varname set bb $ovarname uplevel #0 { if [info exists $bb] { set $aa [expr $$bb] unset $bb } } } proc FixVarRm {ovarname} { global aa set aa $ovarname uplevel #0 { if [info exists $aa] { unset $aa } } } proc FixFontVar {weightname slantname stylename} { global aa bb cc set aa $weightname set bb $slantname set cc $stylename uplevel #0 { if [info exists $cc] { switch [expr $$cc] { normal { set $aa normal set $bb roman } bold { set $aa bold set $bb roman } italic { set $aa normal set $bb italic } } unset $cc } } } # we only support 6.x and higher proc FixPrefs {version} { set major [lindex [split $version {.}] 0] if {$major == {5}} { set version 5.x } switch $version { 5.x { FixPrefs5.xto6.0 FixPrefs6.0to6.1 FixPrefs6.1to6.2 FixPrefs6.2to7.0 } 6.0 { FixPrefs6.0to6.1 FixPrefs6.1to6.2 FixPrefs6.2to7.0 } 6.1 - 6.1.1 - 6.1.2 { FixPrefs6.1to6.2 FixPrefs6.2to7.0 } 6.2 { FixPrefs6.2to7.0 } 7.0 { FixPrefs7.0to7.1 } 7.1 { FixPrefs7.1to7.2 } } } proc FixPrefs7.1to7.2 {} { FixVar pbuttons(file,xpa,info) pbuttons(file,xpa) FixVar pcurrent(align) pwcs(align) } proc FixPrefs7.0to7.1 {} { global pap if {[info exists pap(grid)]} { set pap(grid,x) $pap(grid) set pap(grid,y) $pap(grid) switch $pap(grid,log) { linearlinear { set pap(grid,xlog) 0 set pap(grid,ylog) 0 } linearlog { set pap(grid,xlog) 0 set pap(grid,ylog) 1 } loglinear { set pap(grid,xlog) 1 set pap(grid,ylog) 0 } loglog { set pap(grid,xlog) 1 set pap(grid,ylog) 1 } } unset pap(grid) unset pap(grid,log) } } proc FixPrefs6.2to7.0 {} { global ps global pps switch $pps(scale) { scaled - fixed { set ps(scale) 100 set pps(scale) 100 } } global colorbar global pcolorbar set colorbar(map) [string tolower $colorbar(map)] set pcolorbar(map) [string tolower $pcolorbar(map)] FixVar pbuttons(frame,match,frame,wcs) pbuttons(frame,matchframe,wcs) FixVar pbuttons(frame,match,frame,image) pbuttons(frame,matchframe,image) FixVar pbuttons(frame,match,frame,physical) pbuttons(frame,matchframe,physical) FixVar pbuttons(frame,match,frame,amplifier) pbuttons(frame,matchframe,amplifier) FixVar pbuttons(frame,match,frame,detector) pbuttons(frame,matchframe,detector) FixVar pbuttons(bin,match) pbuttons(frame,matchbin) FixVar pbuttons(scale,match) pbuttons(frame,matchscale) FixVar pbuttons(color,match) pbuttons(frame,matchcolor) FixVar ppanner(compass) ppanner(compass,image) FixVarRm ppanner(compass,wcs,system) FixVarRm ppanner(compass,wcs,sky) global pmarker FixVarRm pmarker(dialog,system) FixVarRm pmarker(dialog,sky) FixVarRm pmarker(dialog,skyformat) FixVarRm pmarker(dialog,dist,system) FixVarRm pmarker(dialog,dist,format) # mousewheel MacOSX Lion global tcl_platform global ppanzoom global pbin switch -- $tcl_platform(os) { Darwin { switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 11 { set ppanzoom(wheel,factor) 1.01 set pbin(wheel,factor) 1.01 } } } } global pcoord FixVarRm pcoord(sky) FixVarRm pcoord(skyformat) } proc FixPrefs6.1to6.2 {} { FixVar pbuttons(frame,matchframe,wcs) pbuttons(frame,matchframe) global pds9 switch -- $pds9(font) { helvetica - courier - times {} default {set pds9(font) helvetica} } switch -- $pds9(font,size) { 10 {set pds9(font,size) 9} } FixVar pmarker(centroid,auto) pmarker(autocentroid) FixVarRm marker(autocentroid) FixFontVar pds9(font,weight) pds9(font,slant) pds9(font,style) FixFontVar pmarker(font,weight) pmarker(font,slant) pmarker(font,style) FixFontVar pcolorbar(font,weight) pcolorbar(font,slant) \ pcolorbar(font,style) } proc FixPrefs6.0to6.1 {} { # ds9 FixVar pds9(automarker) ds9(automarker) FixVar pds9(xpa) ds9(xpa) FixVar pds9(samp) ds9(samp,auto) FixVar pds9(confirm) ds9(confirm) FixVar pds9(bg) ds9(bg,color) FixVar pds9(nan) ds9(nan,color) FixVar pds9(dialog) ds9(dialog) FixVar pds9(language) ds9(language) FixVar pds9(language,name) ds9(language,name) FixVar pds9(language,dir) ds9(language,dir) FixVar pds9(font) ds9(font) FixVar pds9(font,size) ds9(font,size) FixVar pds9(font,style) ds9(font,style) FixVar pcurrent(display) ds9(display,user) FixVar pcurrent(mode) pds9(mode) # note: versions 5.3 to 6.0 have array set ds9 [array get pds9] # which will set following ds9(var), so delete FixVarRm ds9(samp) FixVarRm ds9(backup) FixVarRm ds9(tcl) FixVarRm ds9(nan) # which will overwrite the following ds9(var), so reset global ds9 set ds9(bg) white # analysis FixVar panalysis(user) ds9(analysis,user) FixVar panalysis(user2) ds9(analysis,user2) FixVar panalysis(user3) ds9(analysis,user3) FixVar panalysis(user4) ds9(analysis,user4) global analysis catch {unset analysis} # magnifier FixVar pmagnifier(region) magnifier(region) FixVar pmagnifier(zoom) magnifier(zoom) FixVar pmagnifier(cursor) magnifier(cursor) global magnifier catch {unset magnifier} # panner FixVar ppanner(compass,image) panner(compass,image) FixVar ppanner(compass,wcs) panner(compass,wcs) FixVar ppanner(compass,wcs,system) panner(compass,wcs,system) FixVar ppanner(compass,wcs,sky) panner(compass,wcs,sky) global panner catch {unset panner} # examine FixVar pexamine(mode) examine(mode) FixVar pexamine(zoom) examine(zoom) global examine catch {unset examine} # vo FixVar pvo(server) vo(server) FixVar pvo(hv) vo(hv) FixVar pvo(method) vo(method) FixVar pvo(delay) vo(delay) global vo catch {unset vo} # http FixVar phttp(proxy) http(proxy) FixVar phttp(proxy,host) http(proxy,host) FixVar phttp(proxy,port) http(proxy,port) FixVar phttp(auth) http(auth) FixVar phttp(auth,user) http(auth,user) FixVar phttp(auth,passwd) http(auth,passwd) global http catch {unset http} # nres FixVar pnres(server) nres(server) # graph FixVar pgraph(horz,grid) graph(horz,grid) FixVar pgraph(horz,log) graph(horz,log) FixVar pgraph(vert,grid) graph(vert,grid) FixVar pgraph(vert,log) graph(vert,log) global graph catch {unset graph} # cat FixVar pcat(server) cat(server) FixVar pcat(sym,shape) cat(sym,shape) FixVar pcat(sym,color) cat(sym,color) FixVar pcat(vot) cat(vot) # contour FixVarRm pcontour(color,msg) # coords global coord catch {unset coord} # scale FixVarRm pscale(min) FixVarRm pscale(max) FixVarRm pscale(xaxis) FixVarRm pscale(yaxis) # marker FixVarRm pmarker(maxdialog) FixVarRm pmarker(load) FixVarRm pmarker(paste,system) FixVarRm pmarker(paste,sky) FixVarRm pmarker(system) FixVarRm pmarker(sky) FixVarRm pmarker(skyformat) FixVarRm pmarker(strip) FixVarRm marker(dialog,system) FixVarRm marker(dialog,sky) FixVarRm marker(dialog,skyformat) FixVarRm marker(dialog,dist,system) FixVarRm marker(dialog,dist,format) FixVarRm marker(circle,radius) FixVarRm marker(annulus,inner) FixVarRm marker(annulus,outer) FixVarRm marker(annulus,annuli) FixVarRm marker(panda,inner) FixVarRm marker(panda,outer) FixVarRm marker(panda,annuli) FixVarRm marker(panda,ang1) FixVarRm marker(panda,ang2) FixVarRm marker(panda,angnum) FixVarRm marker(ellipse,radius1) FixVarRm marker(ellipse,radius2) FixVarRm marker(ellipseannulus,radius1) FixVarRm marker(ellipseannulus,radius2) FixVarRm marker(ellipseannulus,radius3) FixVarRm marker(ellipseannulus,annuli) FixVarRm marker(epanda,radius1) FixVarRm marker(epanda,radius2) FixVarRm marker(epanda,radius3) FixVarRm marker(epanda,annuli) FixVarRm marker(epanda,ang1) FixVarRm marker(epanda,ang2) FixVarRm marker(epanda,angnum) FixVarRm marker(box,radius1) FixVarRm marker(box,radius2) FixVarRm marker(boxannulus,radius1) FixVarRm marker(boxannulus,radius2) FixVarRm marker(boxannulus,radius3) FixVarRm marker(boxannulus,annuli) FixVarRm marker(bpanda,radius1) FixVarRm marker(bpanda,radius2) FixVarRm marker(bpanda,radius3) FixVarRm marker(bpanda,annuli) FixVarRm marker(bpanda,ang1) FixVarRm marker(bpanda,ang2) FixVarRm marker(bpanda,angnum) FixVarRm marker(polygon,width) FixVarRm marker(polygon,height) FixVarRm marker(projection,thick) FixVarRm marker(compass,radius) FixVarRm marker(point,size) } proc FixPrefs5.xto6.0 {} { FixVar pap(grid) prefs(ap,grid) FixVar pap(grid,log) prefs(ap,grid,log) FixVar pap(discrete) prefs(ap,discrete) FixVar pap(discrete,symbol) prefs(ap,discrete,symbol) FixVar pap(discrete,color) prefs(ap,discrete,color) FixVar pap(linear) prefs(ap,linear) FixVar pap(linear,width) prefs(ap,linear,width) FixVar pap(linear,color) prefs(ap,linear,color) FixVar pap(linear,dash) prefs(ap,linear,dash) FixVar pap(step) prefs(ap,step) FixVar pap(step,width) prefs(ap,step,width) FixVar pap(step,color) prefs(ap,step,color) FixVar pap(step,dash) prefs(ap,step,dash) FixVar pap(quadratic) prefs(ap,quadratic) FixVar pap(quadratic,width) prefs(ap,quadratic,width) FixVar pap(quadratic,color) prefs(ap,quadratic,color) FixVar pap(quadratic,dash) prefs(ap,quadratic,dash) FixVar pap(error,width) prefs(ap,error,width) FixVar pap(error,color) prefs(ap,error,color) FixVar pap(error,style) prefs(ap,error,style) FixVar pap(titleFont) prefs(ap,titleFont) FixVar pap(titleSize) prefs(ap,titleSize) FixVar pap(titleStyle) prefs(ap,titleStyle) FixVar pap(textlabFont) prefs(ap,textlabFont) FixVar pap(textlabSize) prefs(ap,textlabSize) FixVar pap(textlabStyle) prefs(ap,textlabStyle) FixVar pap(numlabFont) prefs(ap,numlabFont) FixVar pap(numlabSize) prefs(ap,numlabSize) FixVar pap(numlabStyle) prefs(ap,numlabStyle) FixVar pcurrent(zoom) prefs(zoom) FixVar pcurrent(orient) prefs(orient) FixVar pcurrent(rotate) prefs(rotate) FixVar panalysis(log) prefs(analysis,log) FixVar pds9(mode) prefs(ds9,mode) FixVar pblink(interval) prefs(blink,interval) FixVar ptile(mode) prefs(tile,mode) FixVar pcolorbar(map) prefs(colorbar,map) FixVar pcolorbar(invert) prefs(colorbar,invert) FixVar pmarker(shape) prefs(marker,shape) FixVar pmarker(color) prefs(marker,color) FixVar pmarker(width) prefs(marker,width) FixVar pmarker(fixed) prefs(marker,fixed) FixVar pmarker(edit) prefs(marker,edit) FixVar pmarker(move) prefs(marker,move) FixVar pmarker(rotate) prefs(marker,rotate) FixVar pmarker(delete) prefs(marker,delete) FixVar pmarker(include) prefs(marker,include) FixVar pmarker(source) prefs(marker,source) FixVar pmarker(font) prefs(marker,font) FixVar pmarker(font,size) prefs(marker,font,size) FixVar pmarker(font,style) prefs(marker,font,style) FixVar pmarker(format) prefs(marker,format) FixVar pmarker(strip) prefs(marker,strip) FixVar pmarker(system) prefs(marker,system) FixVar pmarker(sky) prefs(marker,sky) FixVar pmarker(skyformat) prefs(marker,skyformat) FixVarRm prefs(marker,wcs) FixVarRm marker(wcs) FixVarRm marker(polygon,width) FixVarRm marker(polygon,height) FixVar pmarker(dialog,system) marker(dialog,system) FixVar pmarker(dialog,sky) marker(dialog,sky) FixVar pmarker(dialog,skyformat) marker(dialog,skyformat) FixVar pmarker(dialog,dist,system) marker(dialog,dist,system) FixVar pmarker(dialog,dist,format) marker(dialog,dist,format) FixVar pmarker(circle,radius) marker(circle,radius) FixVar pmarker(annulus,inner) marker(annulus,inner) FixVar pmarker(annulus,outer) marker(annulus,outer) FixVar pmarker(annulus,annuli) marker(annulus,annuli) FixVar pmarker(panda,inner) marker(panda,inner) FixVar pmarker(panda,outer) marker(panda,outer) FixVar pmarker(panda,annuli) marker(panda,annuli) FixVar pmarker(panda,ang1) marker(panda,ang1) FixVar pmarker(panda,ang2) marker(panda,ang2) FixVar pmarker(panda,angnum) marker(panda,angnum) FixVar pmarker(ellipse,radius1) marker(ellipse,radius1) FixVar pmarker(ellipse,radius2) marker(ellipse,radius2) FixVar pmarker(ellipseannulus,radius1) marker(ellipseannulus,radius1) FixVar pmarker(ellipseannulus,radius2) marker(ellipseannulus,radius2) FixVar pmarker(ellipseannulus,radius3) marker(ellipseannulus,radius3) FixVar pmarker(ellipseannulus,annuli) marker(ellipseannulus,annuli) FixVar pmarker(epanda,radius1) marker(epanda,radius1) FixVar pmarker(epanda,radius2) marker(epanda,radius2) FixVar pmarker(epanda,radius3) marker(epanda,radius3) FixVar pmarker(epanda,annuli) marker(epanda,annuli) FixVar pmarker(epanda,ang1) marker(epanda,ang1) FixVar pmarker(epanda,ang2) marker(epanda,ang2) FixVar pmarker(epanda,angnum) marker(epanda,angnum) FixVar pmarker(box,radius1) marker(box,radius1) FixVar pmarker(box,radius2) marker(box,radius2) FixVar pmarker(boxannulus,radius1) marker(boxannulus,radius1) FixVar pmarker(boxannulus,radius2) marker(boxannulus,radius2) FixVar pmarker(boxannulus,radius3) marker(boxannulus,radius3) FixVar pmarker(boxannulus,annuli) marker(boxannulus,annuli) FixVar pmarker(bpanda,radius1) marker(bpanda,radius1) FixVar pmarker(bpanda,radius2) marker(bpanda,radius2) FixVar pmarker(bpanda,radius3) marker(bpanda,radius3) FixVar pmarker(bpanda,annuli) marker(bpanda,annuli) FixVar pmarker(bpanda,ang1) marker(bpanda,ang1) FixVar pmarker(bpanda,ang2) marker(bpanda,ang2) FixVar pmarker(bpanda,angnum) marker(bpanda,angnum) FixVar pmarker(projection,thick) marker(projection,thick) FixVar pmarker(point,size) marker(point,size) # buttons global buttons global pbuttons if [info exists buttons(file,about)] { foreach nn [array names buttons] { set aa [split $nn ,] if {[lindex $aa 1] != {}} { switch [lindex $aa 0] { file - edit - view - frame - bin - zoom - scale - color - region - wcs - help { set pbuttons($nn) $buttons($nn) unset buttons($nn) } } } } FixVar pbuttons(scale,995) buttons(scale,99.5) FixVar pbuttons(scale,925) buttons(scale,92.5) FixVar pbuttons(zoom,i32) buttons(zoom,1/32) FixVar pbuttons(zoom,i16) buttons(zoom,1/16) FixVar pbuttons(zoom,i8) buttons(zoom,1/8) FixVar pbuttons(zoom,i4) buttons(zoom,1/4) FixVar pbuttons(zoom,i2) buttons(zoom,1/2) FixVarRm pbuttons(scale,92.5) FixVarRm pbuttons(scale,99.5) FixVarRm pbuttons(zoom,1/32) FixVarRm pbuttons(zoom,1/16) FixVarRm pbuttons(zoom,1/8) FixVarRm pbuttons(zoom,1/4) FixVarRm pbuttons(zoom,1/2) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/srgbcube.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000002366�12125367635�014213� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadSRGBCubeFile {hdr fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb cube} set loadParam(load,type) smmap set loadParam(file,name) $fn set loadParam(file,header) $hdr # mask not supported set loadParam(load,layer) {} ProcessLoad } proc ProcessSRGBCubeCmd {varname iname sock fn} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { new { incr i CreateRGBFrame } mask { incr i # not supported } slice { incr i # not supported } } StartLoad if {$sock != {}} { # xpa if {0} { # not supported } else { LoadSRGBCubeFile [lindex $var $i] [lindex $var [expr $i+1]] } } else { # comm if {0} { # not supported } else { LoadSRGBCubeFile [lindex $var $i] [lindex $var [expr $i+1]] } } FinishLoad } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/nvss.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000011020�11700665571�013371� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc NVSSDef {} { global nvss global invss set invss(top) .nvss set invss(mb) .nvssmb set nvss(sky) fk5 set nvss(rformat) arcmin set nvss(width) 15 set nvss(height) 15 set nvss(mode) new set nvss(save) 0 set nvss(valid) 1 set nvss(survey) nvss } proc NVSSDialog {} { global nvss global invss global wcs if [winfo exists $invss(top)] { raise $invss(top) return } set varname dnvss upvar #0 $varname var global $varname set var(top) $invss(top) set var(mb) $invss(mb) set var(sky) $nvss(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $nvss(rformat) set var(width) $nvss(width) set var(height) $nvss(height) set var(mode) $nvss(mode) set var(save) $nvss(save) set var(valid) $nvss(valid) set var(survey) $nvss(survey) set w $var(top) IMGSVRInit $varname "NVSS [msgcat::mc {Server}]" NVSSExec NVSSAck IMGSVRUpdate $varname 1 } proc NVSSExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set var(fn) [tmpnam ds9nvss ".fits"] } # skyformat switch -- $var(skyformat) { degrees { set xx [uformat d h: $var(x)] set yy [uformat d d: $var(y)] } sexagesimal { set xx $var(x) set yy $var(y) } } regsub -all {:} $xx { } xx regsub -all {:} $yy { } yy # size - convert to arcmin switch -- $var(rformat) { degrees { set ww [expr $var(width)] set hh [expr $var(height)] } arcmin { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } arcsec { set ww [expr $var(width)/60./60.] set hh [expr $var(height)/60./60.] } } set var(query) [http::formatQuery submit Submit! Equinox J2000 PolType I RA $xx Dec $yy Size "$ww $hh" Cells "15.0 15.0" MAPROJ SIN Type image/x-fits rotate "0.0"] # set var(query) [http::formatQuery .submit "Extract the Cutout" RA "$xx $yy" Equinox J2000 ImageSize $rr MaxInt 10 .cgifields ImageType ImageType "FITS Image"] set var(url) "http://www.cv.nrao.edu/cgi-bin/postage.pl" IMGSVRLoad $varname } proc NVSSAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the NRAO VLA Sky Survey This major undertaking has received the generous technical and scientific support of many individuals. The NRAO staff has provided extremely valuable assistance in many aspects of the observations themselves and in the area of software support; in particular, we are grateful to Rick Perley, Ken Sowinski, Barry Clark, and Bill Cotton in this regard. The support of the NRAO Director, Paul van den Bout, and the yeoman service provided by Frazer Owen as Chair of the Survey Oversight Committee are also greatly appreciated. We also thank the members of the Oversight Committee (Ken Chambers, Eric Feigelson, Jackie Hewitt, Gillian Knapp, and Rogier Windhorst) for their time and wise counsel in this enterprise. Acknowledgment is also due our colleagues who are involved in the ongoing NVSS effort, including Richard McMahon and Isobel Hook. This work is supported in part under the auspices of the Department of Energy by Lawrence Livermore National Laboratory under contract No. W-7405-ENG-48 and the Institute for Geophysics and Planetary Physics, whose director Charles Alcock has been particularly supportive. We also acknowledge a generous planning grant from the CalSpace Institute; support from the STScI archive group, STScI director Bob Williams, and the STScI Director's Discretionary Research Fund; computing resources from Columbia University; a grant from the National Science Foundation; a gift of computing equipment from Sun Microsystems; a NATO travel grant to support our collaboration with Richard McMahon; and an award from the National Geographic Society which, in the spirit of their support 40 years ago for the Palomar Observatory Sky Survey, will be providing funds to continue our charting of the Universe. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc ProcessNVSSCmd {varname iname} { upvar $varname var upvar $iname i NVSSDialog IMGSVRProcessCmd $varname $iname dnvss } proc ProcessSendNVSSCmd {proc id param} { NVSSDialog IMGSVRProcessSendCmd $proc $id $param dnvss } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/print.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000040756�12064434004�013543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PSDef {} { global ds9 global ps global pps set ps(dest) printer set ps(cmd) {lp} set ps(filename) {ds9.ps} set ps(filename,txt) {ds9.txt} set ps(color) rgb set ps(level) 2 set ps(resolution) 150 set ps(orient) portrait set ps(scale) 100 set ps(size) letter set ps(width) 8.5 set ps(height) 11 array set pps [array get ps] } # Print procs proc PSPrint {} { if {[PSPrintDialog ps]} { if [catch {PostScript} printError] { Error "[msgcat::mc {An error has occurred while printing}] $printError" } } } proc PostScript {} { global ds9 global ps global view global canvas global colorbar global current # we need to be realized RealizeDS9 # need the colorbar levels updated UpdateColormapLevel set options " " # Orientation switch -- $ps(orient) { portrait {append options " -rotate false"} landscape {append options " -rotate true"} } # Page size switch -- $ps(size) { letter {PostScriptPageSize 4.25i 5.5i 7.5i 10.i options} legal {PostScriptPageSize 4.25i 7.i 7.5i 13.i options} tabloid {PostScriptPageSize 5.5i 8.5i 10.i 16.i options} poster {PostScriptPageSize 18.i 24.i 35.i 47.i options} a4 {PostScriptPageSize 105m 148.5m 185m 272m options} other { if {$ps(width) != {} && $ps(height) != {}} { set x [expr double($ps(width))/2.] set y [expr double($ps(height))/2.] set w [expr $ps(width)-1.] set h [expr $ps(height)-1.] PostScriptPageSize [append x i] [append y i] \ [append w i] [append h i] options } } othermm { if {$ps(width) != {} && $ps(height) != {}} { set x [expr double($ps(width))/2.] set y [expr double($ps(height))/2.] set w [expr $ps(width)-1.] set h [expr $ps(height)-1.] PostScriptPageSize [append x m] [append y m] \ [append w m] [append h m] options } } } # Printer vs File set channel {} switch -- $ps(dest) { "file" { append options " -file \{$ps(filename)\}" } "printer" { set channel [open "| $ps(cmd)" w] append options " -channel $channel" } } # set color specific postscript options switch -- $ds9(visual) { pseudocolor { colorbar postscript level $ps(level) colorbar postscript colorspace $ps(color) colorbar postscript resolution $ps(resolution) } truecolor { colorbar postscript level $ps(level) colorbar postscript colorspace $ps(color) colorbar postscript resolution $ps(resolution) colorbarrgb postscript level $ps(level) colorbarrgb postscript colorspace $ps(color) colorbarrgb postscript resolution $ps(resolution) } } # set frame specific postscript options foreach f $ds9(frames) { $f postscript level $ps(level) $f postscript colorspace $ps(color) $f postscript resolution $ps(resolution) } # setting the scale for one widget sets it for the entire print run # reduce slightly to make room for numerics if {$current(frame) != {}} { $current(frame) postscript scale [expr .95*$ps(scale)/100.] } # graphs if {$view(graph,vert)} { $ds9(graph,vert) configure -plotbackground white -bg white } if {$view(graph,horz)} { $ds9(graph,horz) configure -plotbackground white -bg white } # now invoke canvas postscript command if [catch {eval $ds9(canvas) postscript $options} rr] { Error "[msgcat::mc {A postscript generation error has occurred}] $rr" } switch -- $ps(dest) { "file" {} "printer" { if {$channel != {}} { close $channel } } } # reset graphs if {$view(graph,vert)} { $ds9(graph,vert) configure -plotbackground $ds9(bg) -bg $ds9(bg) } if {$view(graph,horz)} { $ds9(graph,horz) configure -plotbackground $ds9(bg) -bg $ds9(bg) } } proc EPS {fn} { global ds9 global ps global view global canvas global colorbar global current # we need to be realized RealizeDS9 # need the colorbar levels updated UpdateColormapLevel set color rgb set level 2 set resolution 72 set options {} # Page size set width [winfo width $ds9(canvas)] set height [winfo height $ds9(canvas)] append options " -pagex 0 -pagey 0 -pageanchor sw" if ($width>$height) { append options " -pagewidth $width" } else { append options " -pageheight $height" } # File append options " -file \{$fn\}" # set color specific postscript options switch -- $ds9(visual) { pseudocolor { colorbar postscript level $level colorbar postscript colorspace $color colorbar postscript resolution $resolution } truecolor { colorbar postscript level $level colorbar postscript colorspace $color colorbar postscript resolution $resolution colorbarrgb postscript level $level colorbarrgb postscript colorspace $color colorbarrgb postscript resolution $resolution } } # set frame specific postscript options foreach f $ds9(frames) { $f postscript level $level $f postscript colorspace $color $f postscript resolution $resolution } # setting the scale for one widget sets it for the entire print run if {$current(frame) != {}} { $current(frame) postscript scale 1.0 } # graphs if {$view(graph,vert)} { $ds9(graph,vert) configure -plotbackground white -bg white } if {$view(graph,horz)} { $ds9(graph,horz) configure -plotbackground white -bg white } # now invoke canvas postscript command if [catch {eval $ds9(canvas) postscript $options} rr] { Error "[msgcat::mc {A postscript generation error has occurred}] $rr" } # reset graphs if {$view(graph,vert)} { $ds9(graph,vert) configure -plotbackground $ds9(bg) -bg $ds9(bg) } if {$view(graph,horz)} { $ds9(graph,horz) configure -plotbackground $ds9(bg) -bg $ds9(bg) } } proc PostScriptPageSize {x y w h optname} { upvar $optname options global ds9 global ps append options " -pagex $x -pagey $y" set width [winfo width $ds9(canvas)] set height [winfo height $ds9(canvas)] set wo [string trim $w "icmp"] set ho [string trim $h "icmp"] switch -- $ps(orient) { portrait { if {[expr double($wo)/$width] < [expr double($ho)/$height]} { append options " -pagewidth $w" } else { append options " -pageheight $h" } } landscape { if {[expr double($wo)/$width] > [expr double($ho)/$height]} { append options " -pageheight $w" } else { append options " -pagewidth $h" } } } } # Print Dialog procs proc PSPrintDialog {which} { global ps global ed set ed(ok) 0 array set ed [array get ps] set w {.print} DialogCreate $w [msgcat::mc {Print}] ed(ok) # PrintTo set f [ttk::labelframe $w.pt -text [msgcat::mc {Print To}]] ttk::radiobutton $f.printer -text [msgcat::mc {Printer}] \ -variable ed(dest) -value printer ttk::label $f.tcmd -text [msgcat::mc {Command}] ttk::entry $f.cmd -textvariable ed(cmd) -width 20 ttk::radiobutton $f.file -text [msgcat::mc {File}] \ -variable ed(dest) -value file ttk::label $f.tname -text [msgcat::mc {Name}] ttk::entry $f.name -textvariable ed(filename) -width 20 ttk::button $f.browse -text [msgcat::mc {Browse}] \ -command "PSPrintBrowse ed(filename)" grid $f.printer $f.tcmd $f.cmd -padx 2 -pady 2 -sticky ew grid $f.file $f.tname $f.name $f.browse -padx 2 -pady 2 -sticky ew grid columnconfigure $f 2 -weight 1 # Options set f [ttk::labelframe $w.ps -text [msgcat::mc {Postscript}]] ttk::label $f.color -text [msgcat::mc {Color}] ttk::radiobutton $f.rgb -text [msgcat::mc {RGB}] \ -variable ed(color) -value rgb ttk::radiobutton $f.cmyk -text [msgcat::mc {CMYK}] \ -variable ed(color) -value cmyk ttk::radiobutton $f.gray -text [msgcat::mc {Grayscale}] \ -variable ed(color) -value gray ttk::label $f.level -text [msgcat::mc {Level}] ttk::radiobutton $f.level1 -text "[msgcat::mc {Level}] 1" \ -variable ed(level) -value 1 ttk::radiobutton $f.level2 -text "[msgcat::mc {Level}] 2" \ -variable ed(level) -value 2 ttk::radiobutton $f.level3 -text "[msgcat::mc {Level}] 3" \ -variable ed(level) -value 3 ttk::label $f.dpi -text [msgcat::mc {DPI}] tk_optionMenu $f.resolution ed(resolution) 53 72 75 150 300 600 grid $f.color $f.rgb $f.cmyk $f.gray -padx 2 -pady 2 -sticky w grid $f.level $f.level3 $f.level2 $f.level1 -padx 2 -pady 2 -sticky w grid $f.dpi $f.resolution -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini grid $w.pt -sticky news grid $w.ps -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok DialogDismiss $w if {$ed(ok)} { array set ps [array get ed] } set rr $ed(ok) unset ed return $rr } proc PSPrintBrowse {varname} { upvar $varname var FileLastFull pssavfbox $var set var [SaveFileDialog pssavfbox] } # Used for plots proc PlotPrintDialog {} { global ps global ed set ed(ok) 0 array set ed [array get ps] set w {.print} DialogCreate $w [msgcat::mc {Print}] ed(ok) # PrintTo set f [ttk::labelframe $w.pt -text [msgcat::mc {Print To}]] ttk::radiobutton $f.printer -text [msgcat::mc {Printer}] \ -variable ed(dest) -value printer ttk::label $f.tcmd -text [msgcat::mc {Command}] ttk::entry $f.cmd -textvariable ed(cmd) -width 20 ttk::radiobutton $f.file -text [msgcat::mc {File}] \ -variable ed(dest) -value file ttk::label $f.tname -text [msgcat::mc {Name}] ttk::entry $f.name -textvariable ed(filename) -width 20 ttk::button $f.browse -text [msgcat::mc {Browse}] \ -command "PlotPrintBrowse ed(filename)" grid $f.printer $f.tcmd $f.cmd -padx 2 -pady 2 -sticky ew grid $f.file $f.tname $f.name $f.browse -padx 2 -pady 2 -sticky ew grid columnconfigure $f 2 -weight 1 # Options set f [ttk::labelframe $w.ps -text [msgcat::mc {Postscript}]] ttk::label $f.color -text [msgcat::mc {Color}] ttk::radiobutton $f.rgb -text [msgcat::mc {RGB}] \ -variable ed(color) -value rgb ttk::radiobutton $f.gray -text [msgcat::mc {Grayscale}] \ -variable ed(color) -value gray grid $f.color $f.rgb $f.gray -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini grid $w.pt -sticky news grid $w.ps -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok DialogDismiss $w if {$ed(ok)} { array set ps [array get ed] } set rr $ed(ok) unset ed return $rr } proc PlotPrintBrowse {varname} { upvar $varname var FileLastFull apsavfbox $var set var [SaveFileDialog apsavfbox] } # Used for SimpleText and Catalog proc PRPrintDialog {} { global ps global ed set ed(ok) 0 array set ed [array get ps] set w {.print} DialogCreate $w [msgcat::mc {Print}] ed(ok) # PrintTo set f [ttk::labelframe $w.pt -text [msgcat::mc {Print To}]] ttk::radiobutton $f.printer -text [msgcat::mc {Printer}] \ -variable ed(dest) -value printer ttk::label $f.tcmd -text [msgcat::mc {Command}] ttk::entry $f.cmd -textvariable ed(cmd) -width 20 ttk::radiobutton $f.file -text [msgcat::mc {File}] \ -variable ed(dest) -value file ttk::label $f.tname -text [msgcat::mc {Name}] ttk::entry $f.name -textvariable ed(filename,txt) -width 20 ttk::button $f.browse -text [msgcat::mc {Browse}] \ -command "PRPrintBrowse ed(filename,txt)" grid $f.printer $f.tcmd $f.cmd -padx 2 -pady 2 -sticky ew grid $f.file $f.tname $f.name $f.browse -padx 2 -pady 2 -sticky ew grid columnconfigure $f 2 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini grid $w.pt -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid columnconfigure $w 0 -weight 1 DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok DialogDismiss $w if {$ed(ok)} { array set ps [array get ed] } set rr $ed(ok) unset ed return $rr } proc PRPrintBrowse {varname} { upvar $varname var FileLastFull prsavfbox $var set var [SaveFileDialog prsavfbox] } proc PrefsDialogPrint {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Postscript}] lappend dprefs(tabs) [ttk::frame $w.print] # PrintTo set f [ttk::labelframe $w.print.printto -text [msgcat::mc {Print To}]] ttk::radiobutton $f.printer -text [msgcat::mc {Printer}] \ -variable pps(dest) -value printer ttk::label $f.tcmd -text [msgcat::mc {Command}] ttk::entry $f.cmd -textvariable pps(cmd) -width 20 ttk::radiobutton $f.file -text [msgcat::mc {File}] \ -variable pps(dest) -value file ttk::label $f.tname -text [msgcat::mc {Name}] ttk::entry $f.name -textvariable pps(filename) -width 20 ttk::button $f.browse -text [msgcat::mc {Browse}] \ -command "PSPrintBrowse pps(filename)" grid $f.printer $f.tcmd $f.cmd -padx 2 -pady 2 -sticky w grid $f.file $f.tname $f.name $f.browse -padx 2 -pady 2 -sticky w # Options set f [ttk::labelframe $w.print.ps -text [msgcat::mc {Postscript}]] ttk::label $f.color -text [msgcat::mc {Color}] ttk::radiobutton $f.rgb -text [msgcat::mc {RGB}] \ -variable pps(color) -value rgb ttk::radiobutton $f.cmyk -text [msgcat::mc {CMYK}] \ -variable pps(color) -value cmyk ttk::radiobutton $f.gray -text [msgcat::mc {Grayscale}] \ -variable pps(color) -value gray ttk::label $f.level -text [msgcat::mc {Level}] ttk::radiobutton $f.level1 -text "[msgcat::mc {Level}] 1" \ -variable pps(level) -value 1 ttk::radiobutton $f.level2 -text "[msgcat::mc {Level}] 2" \ -variable pps(level) -value 2 ttk::radiobutton $f.level3 -text "[msgcat::mc {Level}] 3" \ -variable pps(level) -value 3 ttk::label $f.dpi -text [msgcat::mc {DPI}] tk_optionMenu $f.resolution pps(resolution) 53 72 75 150 300 600 grid $f.color $f.rgb $f.cmyk $f.gray -padx 2 -pady 2 -sticky w grid $f.level $f.level3 $f.level2 $f.level1 -padx 2 -pady 2 -sticky w grid $f.dpi $f.resolution -padx 2 -pady 2 -sticky w pack $w.print.printto $w.print.ps \ -side top -fill both -expand true } # Process Cmds proc ProcessPrintCmd {varname iname} { upvar $varname var upvar $iname i global ds9 switch $ds9(wm) { x11 {ProcessPSPrintCmd var i} win32 {Win32Print} aqua {MacOSXPrint} } } proc ProcessSendPrintCmd {proc id param} { global ds9 switch $ds9(wm) { x11 {ProcessSendPSPrintCmd $proc $id $param} win32 - aqua {} } } proc ProcessPSPrintCmd {varname iname} { upvar $varname var upvar $iname i global ps switch -- [string tolower [lindex $var $i]] { destination {incr i; set ps(dest) [lindex $var $i]} command {incr i; set ps(cmd) [lindex $var $i]} filename {incr i; set ps(filename) [lindex $var $i]} palette - color {incr i; set ps(color) [lindex $var $i]} level {incr i; set ps(level) [lindex $var $i]} interpolate {incr i} resolution {incr i; set ps(resolution) [lindex $var $i]} {} {PostScript} default {incr i -1; PostScript} } } proc ProcessSendPSPrintCmd {proc id param} { global ps switch -- [string tolower $param] { destination {$proc $id "$ps(dest)\n"} command {$proc $id "$ps(cmd)\n"} filename {$proc $id "$ps(filename)\n"} palette - color {$proc $id "$ps(color)\n"} level {$proc $id "$ps(level)\n"} interpolate {$proc $id "0\n"} resolution {$proc $id "$ps(resolution)\n"} } } ������������������./saods9/src/comm.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000023427�12131601440�013331� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # used to access ProcessSend*Cmd via tcl proc CommReturn {id rr} { return "$id $rr" } proc CommSet {fn paramlist} { global debug if {$debug(tcl,hv) || $debug(tcl,samp)} { puts stderr "CommSet:$fn:$paramlist" } set cmd [lindex $paramlist 0] set param [lrange $paramlist 1 end] set len 0 set i 0 catch { switch -- $cmd { 2mass {Process2MASSCmd param i} 3d {Process3DCmd param i} about {} align {ProcessAlignCmd param i} analysis {ProcessAnalysisCmd param i {} $fn} array {ProcessArrayCmd param i {} $fn} bg - background {ProcessBgCmd param i} backup {ProcessBackupCmd param i} blink {ProcessBlinkCmd param i} bin {ProcessBinCmd param i} cat - catalog {ProcessCatalogCmd param i} cd {ProcessCDCmd param i} cmap {ProcessCmapCmd param i} colorbar {ProcessColorbarCmd param i} console {ProcessConsoleCmd param i} contours - contour {ProcessContourCmd param i} crop {ProcessCropCmd param i} crosshair {ProcessCrosshairCmd param i} cursor {ProcessCursorCmd param i} data {} datacube - cube {ProcessCubeCmd param i} dss - dsssao {ProcessSAOCmd param i} dsseso {ProcessESOCmd param i} dssstsci {ProcessSTSCICmd param i} export {ProcessExportCmd param i} file {ProcessFileCmd param i {} {} {}} first {ProcessFIRSTCmd param i} fits {ProcessFitsCmd param i {} $fn} frame {ProcessFrameCmd param i} gif {ProcessGIFCmd param i {} $fn} grid {ProcessGridCmd param i} header {ProcessHeaderCmd param i} height {ProcessHeightCmd param i} iconify {ProcessIconifyCmd param i} iis {ProcessIISCmd param i} imexam {} jpg - jpeg {ProcessJPEGCmd param i {} $fn} lock {ProcessLockCmd param i} lower {ProcessLowerCmd param i} magnifier {ProcessMagnifierCmd param i} mask {ProcessMaskCmd param i} match {ProcessMatchCmd param i} mecube {ProcessMECubeCmd param i {} $fn} minmax {ProcessMinMaxCmd param i} mode {ProcessModeCmd param i} mosaic {ProcessMosaicCmd param i {} $fn} mosaicimage {ProcessMosaicImageCmd param i {} $fn} mosaicwcs { # backward compatibility ProcessMosaicWCSCmd param i {} $fn } mosaiciraf { # backward compatibility ProcessMosaicIRAFCmd param i {} $fn } mosaicimagewcs { # backward compatibility ProcessMosaicImageWCSCmd param i {} $fn } mosaicimageiraf { # backward compatibility ProcessMosaicImageIRAFCmd param i {} $fn } mosaicimagewfpc2 { # backward compatibility ProcessMosaicImageWFPC2Cmd param i {} $fn } savempeg - movie {ProcessMovieCmd param i} memf - multiframe {ProcessMultiFrameCmd param i {} $fn} nameserver {ProcessNRESCmd param i} nan {ProcessNanCmd param i} nrrd {ProcessNRRDCmd param i {} $fn} nvss {ProcessNVSSCmd param i} orient {ProcessOrientCmd param i} {page setup} - pagesetup {ProcessPageSetupCmd param i} pspagesetup {ProcessPSPageSetupCmd param i} pan {ProcessPanCmd param i} pixeltable {ProcessPixelTableCmd param i} plot {ProcessPlotCmd param i {} $fn} png {ProcessPNGCmd param i {} $fn} prefs {ProcessPrefsCmd param i} preserve {ProcessPreserveCmd param i} print {ProcessPrintCmd param i} psprint {ProcessPSPrintCmd param i} exit - quit {ProcessQuitCmd param i} raise {ProcessRaiseCmd param i} restore {ProcessRestoreCmd param i} region - regions {ProcessRegionsCmd param i {} $fn} rgb {ProcessRGBCmd param i} rgbarray {ProcessRGBArrayCmd param i {} $fn} rgbcube {ProcessRGBCubeCmd param i {} $fn} rgbimage {ProcessRGBImageCmd param i {} $fn} rotate {ProcessRotateCmd param i} samp {ProcessSAMPCmd param i} savefits - save {ProcessSaveCmd param i} saveimage {ProcessSaveImageCmd param i} scale {ProcessScaleCmd param i} sfits { # backward compatibility ProcessSFitsCmd param i {} $fn } single {ProcessSingleCmd param i} shm {ProcessShmCmd param i 0} skyview {ProcessSkyViewCmd param i} sleep {ProcessSleepCmd param i} smosaic { # backward compatibility ProcessSMosaicCmd param i {} $fn } smosaicwcs { # backward compatibility ProcessSMosaicWCSCmd param i {} $fn } smosaiciraf { # backward compatibility ProcessSMosaicIRAFCmd param i {} $fn } smooth {ProcessSmoothCmd param i} source {ProcessSourceCmd param i} srgbcube {ProcessSRGBCubeCmd param i {} $fn} tcl {ProcessTclCmd param i {} $fn} theme {ProcessThemeCmd param i} threads {ProcessThreadsCmd param i} tif - tiff {ProcessTIFFCmd param i {} $fn} tile {ProcessTileCmd param i} update {ProcessUpdateCmd param i} url {ProcessURLFitsCmd param i} version {} view {ProcessViewCmd param i} vo {ProcessVOCmd param i} wcs {ProcessWCSCmd param i {} $fn} web {ProcessWebCmd param i} width {ProcessWidthCmd param i} xpa {ProcessXPACmd param i} zoom {ProcessZoomCmd param i} zscale {ProcessZScaleCmd param i} default {Error "[msgcat::mc {Unknown command}]: $cmd"} } } } proc CommGet {proc id paramlist fn} { global debug if {$debug(tcl,samp)} { puts stderr "CommGet:$proc:$id:$paramlist:$fn" } set cmd [lindex $paramlist 0] set param [lrange $paramlist 1 end] catch { switch -- $cmd { 2mass {ProcessSend2MASSCmd $proc $id $param} 3d {ProcessSend3DCmd $proc $id $param} about {ProcessSendAboutCmd $proc $id $param {} $fn} align {ProcessSendAlignCmd $proc $id $param} analysis {ProcessSendAnalysisCmd $proc $id $param {} $fn} array {ProcessSendArrayCmd $proc $id $param {} $fn} bg - background {ProcessSendBgCmd $proc $id $param} blink {ProcessSendBlinkCmd $proc $id $param} bin {ProcessSendBinCmd $proc $id $param} cat - catalog {ProcessSendCatalogCmd $proc $id $param {} $fn} cd {ProcessSendCDCmd $proc $id $param} cmap {ProcessSendCmapCmd $proc $id $param} colorbar {ProcessSendColorbarCmd $proc $id $param} console {} contours - contour {ProcessSendContourCmd $proc $id $param {} $fn} crop {ProcessSendCropCmd $proc $id $param} crosshair {ProcessSendCrosshairCmd $proc $id $param} cursor {} data {ProcessSendDataCmd $proc $id $param {} $fn} datacube - cube {ProcessSendCubeCmd $proc $id $param} dss - dsssao {ProcessSendSAOCmd $proc $id $param} dsseso {ProcessSendESOCmd $proc $id $param} dssstsci {ProcessSendSTSCICmd $proc $id $param} exit {} export {} file {ProcessSendFileCmd $proc $id $param} first {ProcessSendFIRSTCmd $proc $id $param} fits {ProcessSendFitsCmd $proc $id $param {} $fn} frame {ProcessSendFrameCmd $proc $id $param} gif {ProcessSendGIFCmd $proc $id $param {} $fn} grid {ProcessSendGridCmd $proc $id $param} header {} height {ProcessSendHeightCmd $proc $id $param} iconify {ProcessSendIconifyCmd $proc $id $param} iis {ProcessSendIISCmd $proc $id $param} imexam {ProcessSendImexamCmd $proc $id $param} jpg - jpeg {ProcessSendJPEGCmd $proc $id $param {} $fn} lock {ProcessSendLockCmd $proc $id $param} lower {} magnifier {ProcessSendMagnifierCmd $proc $id $param} mask {ProcessSendMaskCmd $proc $id $param} match {} mecube {ProcessSendMECubeCmd $proc $id $param {} $fn} minmax {ProcessSendMinMaxCmd $proc $id $param} mode {ProcessSendModeCmd $proc $id $param} mosaic {ProcessSendMosaicCmd $proc $id $param {} $fn} mosaicimage {ProcessSendMosaicImageCmd $proc $id $param {} $fn} mosaicwcs { # backward compatibility ProcessSendMosaicWCSCmd $proc $id $param {} $fn } mosaiciraf { # backward compatibility } mosaicimagewcs { # backward compatibility ProcessSendMosaicImageWCSCmd $proc $id $param {} $fn } mosaicimageiraf { # backward compatibility } mosaicimagewfpc2 { # backward compatibility } savempeg - movie {} memf - multiframe {} nameserver {ProcessSendNRESCmd $proc $id $param} nan {ProcessSendNanCmd $proc $id $param} nrrd {ProcessSendNRRDCmd $proc $id $param {} $fn} nvss {ProcessSendNVSSCmd $proc $id $param} orient {ProcessSendOrientCmd $proc $id $param} {page setup} - pagesetup {ProcessSendPageSetupCmd $proc $id $param} pan {ProcessSendPanCmd $proc $id $param} pixeltable {ProcessSendPixelTableCmd $proc $id $param {} $fn} plot {ProcessSendPlotCmd $proc $id $param} png {ProcessSendPNGCmd $proc $id $param {} $fn} prefs {ProcessSendPrefsCmd $proc $id $param} preserve {ProcessSendPreserveCmd $proc $id $param} pspagesetup {ProcessSendPSPageSetupCmd $proc $id $param} print {ProcessSendPrintCmd $proc $id $param} psprint {ProcessSendPSPrintCmd $proc $id $param} exit - quit {} raise {} region - regions {ProcessSendRegionsCmd $proc $id $param {} $fn} rgb {ProcessSendRGBCmd $proc $id $param} rgbarray {ProcessSendRGBArrayCmd $proc $id $param {} $fn} rgbcube {ProcessSendRGBCubeCmd $proc $id $param {} $fn} rgbimage {ProcessSendRGBImageCmd $proc $id $param {} $fn} rotate {ProcessSendRotateCmd $proc $id $param} samp {} savefits - save {} saveimage {} scale {ProcessSendScaleCmd $proc $id $param} sfits { # backward compatibility } single {ProcessSendSingleCmd $proc $id $param} shm {ProcessSendShmCmd $proc $id $param} skyview {ProcessSendSkyViewCmd $proc $id $param} smosaic { # backward compatibility } smosaiciraf { # backward compatibility } smosaicwcs { # backward compatibility } smooth {ProcessSendSmoothCmd $proc $id $param} source {} srgbcube {} tcl {} theme {ProcessSendThemeCmd $proc $id $param} threads {ProcessSendThreadsCmd $proc $id $param} tif - tiff {ProcessSendTIFFCmd $proc $id $param {} $fn} tile {ProcessSendTileCmd $proc $id $param} update {} url {} version {ProcessSendVersionCmd $proc $id $param} view {ProcessSendViewCmd $proc $id $param} vo {ProcessSendVOCmd $proc $id $param} wcs {ProcessSendWCSCmd $proc $id $param} web {ProcessSendWebCmd $proc $id $param} width {ProcessSendWidthCmd $proc $id $param} xpa {} zscale {ProcessSendZScaleCmd $proc $id $param} zoom {ProcessSendZoomCmd $proc $id $param} default { Error "[msgcat::mc {Unknown command}]: $cmd" $proc $id {} } } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/vector.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000010226�12007011531�013667� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc VectorDialog {varname} { upvar #0 $varname var global $varname global pmarker # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord set var(arrow) [$var(frame) get marker $var(id) vector arrow] # procs set var(which) vector set var(proc,apply) VectorApply set var(proc,close) VectorClose set var(proc,coordCB) VectorCoordCB set var(proc,editCB) VectorEditCB set var(proc,distCB) VectorDistCB # base MarkerBaseDialog $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis # plot2d MarkerAnalysisPlot2dDialog $varname # raise plot? global marker set var(plot2d) $marker(plot2d) # init VectorDistCB $varname # callbacks $var(frame) marker $var(id) callback move "VectorEditCB" $varname $var(frame) marker $var(id) callback edit "VectorEditCB" $varname set f $var(top).param # Point ttk::label $f.tpt -text [msgcat::mc {Point}] ttk::entry $f.x -textvariable ${varname}(x) -width 13 ttk::entry $f.y -textvariable ${varname}(y) -width 13 CoordMenuButton $f.upt $varname system 1 sky skyformat \ [list $var(proc,coordCB) $varname] # Length ttk::label $f.tdist -text [msgcat::mc {Length}] ttk::entry $f.dist -textvariable ${varname}(dist) -width 13 DistMenuButton $f.udist $varname dcoord 1 dformat \ [list VectorDistCB $varname] DistMenuEnable $f.udist.menu $varname dcoord 1 dformat # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] # Arrow ttk::label $f.tarrow -text [msgcat::mc {Arrow}] ttk::checkbutton $f.arrow -variable ${varname}(arrow) \ -command "VectorArrow $varname" grid $f.tpt $f.x $f.y $f.upt -padx 2 -pady 2 -sticky w grid $f.tdist $f.dist $f.udist -padx 2 -pady 2 -sticky w grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w grid $f.tarrow $f.arrow -padx 2 -pady 2 -sticky w } # actions proc VectorClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback move "VectorEditCB" $var(frame) marker $var(id) delete callback edit "VectorEditCB" MarkerBaseClose $varname } proc VectorApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) vector point $var(system) $var(sky) \ $var(x) $var(y) $var(dcoord) $var(dformat) $var(dist) $var(angle) MarkerBaseLineApply $varname } proc VectorArrow {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) vector arrow $var(arrow) } # callbacks proc VectorCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "VectorCoordCB" } MarkerAnalysisPlot2dSystem $varname MarkerBaseCoordCB $varname VectorEditCB $varname } proc VectorEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "VectorEditCB" } set p [$var(frame) get marker $var(id) vector point \ $var(system) $var(sky) $var(skyformat)] set var(x) [lindex $p 0] set var(y) [lindex $p 1] set var(dist) [$var(frame) get marker $var(id) vector length \ $var(dcoord) $var(dformat)] set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] } proc VectorDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "VectorDistCB" } set var(dist) [$var(frame) get marker $var(id) vector length \ $var(dcoord) $var(dformat)] } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/plotbar.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000010771�12132042644�014045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc PlotBarTool {} { global iap PlotBar $iap(tt) [msgcat::mc {Bar Plot Tool}] {} {} {} 2 {} } proc PlotBar {tt wtt title xaxis yaxis dim data} { global iap # make the window name unique set ii [lsearch $iap(windows) $tt] if {$ii>=0} { append tt $iap(unique) incr iap(unique) } # set the window title if none if {$wtt == {}} { set wtt $tt } set varname $tt upvar #0 $varname var global $varname PlotBarProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogBar $varname PlotDataSet $varname $dim $data $var(proc,updategraph) $varname PlotStats $varname PlotList $varname } proc PlotBarDialog {varname wtt title xaxis yaxis} { upvar #0 $varname var global $varname PlotBarProc $varname PlotDialog $varname $wtt $title $xaxis $yaxis PlotDialogBar $varname } proc PlotBarProc {varname} { upvar #0 $varname var global $varname set var(proc,updategraph) PlotBarUpdateGraph set var(proc,createelement) PlotBarCreateElement set var(proc,updateelement) PlotBarUpdateElement set var(proc,highlite) PlotBarHighliteElement set var(proc,button) PlotBarButton } proc PlotDialogBar {varname} { upvar #0 $varname var global $varname set var(seq) 1 set var(discrete) 0 set var(linear) 0 set var(step) 0 set var(quadratic) 0 set var(error) 0 set var(bar) 1 # bar $var(mb).element add checkbutton -label [msgcat::mc {Show}] \ -variable ${varname}(bar) \ -command [list $var(proc,updateelement) $varname] $var(mb).element add separator $var(mb).element add cascade \ -label [msgcat::mc {Color}] \ -menu $var(mb).element.color ColorMenu $var(mb).element.color $varname bar,color \ [list PlotUpdateElementBar $varname] # graph set var(graph) [blt::barchart $var(top).bar \ -width 600 -height 500 \ -plotrelief groove \ -plotborderwidth 2 \ ] $var(graph) xaxis configure -grid no -stepsize 0 $var(graph) yaxis configure -grid yes $var(graph) legend configure -hide yes pack $var(graph) -expand yes -fill both PlotChangeMode $varname } proc PlotBarUpdateGraph {varname} { upvar #0 $varname var global $varname if {$var(graph,x,auto)} { set xmin {} set xmax {} } else { set xmin $var(graph,x,min) set xmax $var(graph,x,max) } if {$var(xdata) != {}} { if {$var(graph,x,auto)} { set xxmin [blt::vector expr min($var(xdata))] set xxmax [blt::vector expr max($var(xdata))] } else { set xxmin $var(graph,x,min) set xxmax $var(graph,x,max) } set xmin [expr $xxmin-$var(barwidth)/2.] set xmax [expr $xxmax+$var(barwidth)/2.] } if {$var(graph,y,auto)} { set ymin {} set ymax {} } else { set ymin $var(graph,y,min) set ymax $var(graph,y,max) } $var(graph) xaxis configure -min $xmin -max $xmax \ -descending $var(graph,x,flip) $var(graph) yaxis configure -min $ymin -max $ymax \ -descending $var(graph,y,flip) PlotUpdateGraph $varname } proc PlotBarCreateElement {varname} { upvar #0 $varname var global $varname # warning: uses current vars if {$var(data,total) == 0} { return } # delete current elements set nn $var(data,current) foreach el [$var(graph) element names] { set f [split $el -] if {[lindex $f 1] == $nn} { $var(graph) element delete $el } } global $var(xdata) $var(ydata) set aa [blt::vector expr min($var(xdata))] set bb [blt::vector expr max($var(xdata))] set var(barwidth) [expr abs(1.0*($bb-$aa) / ([$var(xdata) length]-1))] switch $var(bar,color) { black {set clr "#000001"} default {set clr $var(bar,color)} } $var(graph) element create "b-${nn}" \ -xdata $var(xdata) -ydata $var(ydata) \ -relief flat -barwidth $var(barwidth) \ -foreground $clr -background $clr # do this to force an update in case of no visible elements $var(graph) legend configure -hide yes } proc PlotBarUpdateElement {varname} { upvar #0 $varname var global $varname set nn $var(data,current) set var($nn,bar) $var(bar) $var(graph) element configure "b-${nn}" -hide [expr !$var(bar)] } proc PlotBarButton {varname x y} { upvar #0 $varname var global $varname } proc PlotBarHighliteElement {varname rowlist} { upvar #0 $varname var global $varname } �������./saods9/src/source.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000014135�12102563560�013702� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 source $ds9(root)/src/2mass.tcl source $ds9(root)/src/3d.tcl source $ds9(root)/src/array.tcl source $ds9(root)/src/analysis.tcl source $ds9(root)/src/analysisparam.tcl source $ds9(root)/src/annulus.tcl source $ds9(root)/src/ar.tcl source $ds9(root)/src/backup.tcl source $ds9(root)/src/bin.tcl source $ds9(root)/src/box.tcl source $ds9(root)/src/boxannulus.tcl source $ds9(root)/src/bpanda.tcl source $ds9(root)/src/buttons.tcl source $ds9(root)/src/cat.tcl source $ds9(root)/src/catcds.tcl source $ds9(root)/src/catcdssrch.tcl source $ds9(root)/src/catcdssrchdialog.tcl source $ds9(root)/src/catcmd.tcl source $ds9(root)/src/catcxc.tcl source $ds9(root)/src/catdialog.tcl source $ds9(root)/src/catflt.tcl source $ds9(root)/src/catmatch.tcl source $ds9(root)/src/catned.tcl source $ds9(root)/src/catopt.tcl source $ds9(root)/src/catplot.tcl source $ds9(root)/src/catreg.tcl source $ds9(root)/src/catsdss.tcl source $ds9(root)/src/catsimbad.tcl source $ds9(root)/src/catskybot.tcl source $ds9(root)/src/catsym.tcl source $ds9(root)/src/cattsv.tcl source $ds9(root)/src/catvot.tcl source $ds9(root)/src/centroid.tcl source $ds9(root)/src/circle.tcl source $ds9(root)/src/colorbar.tcl source $ds9(root)/src/comm.tcl source $ds9(root)/src/command.tcl source $ds9(root)/src/compass.tcl source $ds9(root)/src/composite.tcl source $ds9(root)/src/contour.tcl source $ds9(root)/src/convert.tcl source $ds9(root)/src/coord.tcl source $ds9(root)/src/cpanda.tcl source $ds9(root)/src/crop.tcl source $ds9(root)/src/crosshair.tcl source $ds9(root)/src/cube.tcl source $ds9(root)/src/debug.tcl source $ds9(root)/src/dialog.tcl source $ds9(root)/src/ellipse.tcl source $ds9(root)/src/ellipseannulus.tcl source $ds9(root)/src/epanda.tcl source $ds9(root)/src/error.tcl source $ds9(root)/src/eso.tcl source $ds9(root)/src/examine.tcl source $ds9(root)/src/export.tcl source $ds9(root)/src/external.tcl source $ds9(root)/src/file.tcl source $ds9(root)/src/fits.tcl source $ds9(root)/src/first.tcl source $ds9(root)/src/frame.tcl source $ds9(root)/src/graph.tcl source $ds9(root)/src/grid.tcl source $ds9(root)/src/group.tcl source $ds9(root)/src/header.tcl source $ds9(root)/src/help.tcl source $ds9(root)/src/http.tcl source $ds9(root)/src/hv.tcl source $ds9(root)/src/hvform.tcl source $ds9(root)/src/hvsup.tcl source $ds9(root)/src/iis.tcl source $ds9(root)/src/imexam.tcl source $ds9(root)/src/imgsvr.tcl source $ds9(root)/src/import.tcl source $ds9(root)/src/info.tcl source $ds9(root)/src/layout.tcl source $ds9(root)/src/line.tcl source $ds9(root)/src/load.tcl source $ds9(root)/src/magnifier.tcl source $ds9(root)/src/marker.tcl source $ds9(root)/src/markeranalysispanda.tcl source $ds9(root)/src/markeranalysisplot2d.tcl source $ds9(root)/src/markeranalysisplot3d.tcl source $ds9(root)/src/markeranalysisradial.tcl source $ds9(root)/src/markeranalysisstats.tcl source $ds9(root)/src/markerbase.tcl source $ds9(root)/src/markerbaseannulus.tcl source $ds9(root)/src/markerbaseannulusrect.tcl source $ds9(root)/src/markerbasecenter.tcl source $ds9(root)/src/markerbaseline.tcl source $ds9(root)/src/markerbasepanda.tcl source $ds9(root)/src/markerbasepandarect.tcl source $ds9(root)/src/markerdialog.tcl source $ds9(root)/src/mask.tcl source $ds9(root)/src/manalysis.tcl source $ds9(root)/src/mbin.tcl source $ds9(root)/src/mcolor.tcl source $ds9(root)/src/mecube.tcl source $ds9(root)/src/medit.tcl source $ds9(root)/src/menu.tcl source $ds9(root)/src/mfile.tcl source $ds9(root)/src/mframe.tcl source $ds9(root)/src/mhelp.tcl source $ds9(root)/src/mosaicimage.tcl source $ds9(root)/src/mosaicimageiraf.tcl source $ds9(root)/src/mosaicimagewcs.tcl source $ds9(root)/src/mosaicimagewfpc2.tcl source $ds9(root)/src/mosaic.tcl source $ds9(root)/src/mosaiciraf.tcl source $ds9(root)/src/mosaicwcs.tcl source $ds9(root)/src/movie.tcl source $ds9(root)/src/mregion.tcl source $ds9(root)/src/mscale.tcl source $ds9(root)/src/multiframe.tcl source $ds9(root)/src/mview.tcl source $ds9(root)/src/mwcs.tcl source $ds9(root)/src/mzoom.tcl source $ds9(root)/src/nameres.tcl source $ds9(root)/src/nsvr.tcl source $ds9(root)/src/nrrd.tcl source $ds9(root)/src/nvss.tcl source $ds9(root)/src/open.tcl source $ds9(root)/src/pagesetup.tcl source $ds9(root)/src/panner.tcl source $ds9(root)/src/panzoom.tcl source $ds9(root)/src/photo.tcl source $ds9(root)/src/pixel.tcl source $ds9(root)/src/plot.tcl source $ds9(root)/src/plotbar.tcl source $ds9(root)/src/plotdialog.tcl source $ds9(root)/src/plotelement.tcl source $ds9(root)/src/plotline.tcl source $ds9(root)/src/plotprint.tcl source $ds9(root)/src/plotprocess.tcl source $ds9(root)/src/plotscatter.tcl source $ds9(root)/src/point.tcl source $ds9(root)/src/polygon.tcl source $ds9(root)/src/prefs.tcl source $ds9(root)/src/prefsdialog.tcl source $ds9(root)/src/print.tcl source $ds9(root)/src/projection.tcl source $ds9(root)/src/rgb.tcl source $ds9(root)/src/rgbarray.tcl source $ds9(root)/src/rgbcube.tcl source $ds9(root)/src/rgbimage.tcl source $ds9(root)/src/ruler.tcl source $ds9(root)/src/samp.tcl source $ds9(root)/src/sao.tcl source $ds9(root)/src/save.tcl source $ds9(root)/src/saveimage.tcl source $ds9(root)/src/scale.tcl source $ds9(root)/src/sfits.tcl source $ds9(root)/src/shm.tcl source $ds9(root)/src/skyview.tcl source $ds9(root)/src/slider.tcl source $ds9(root)/src/smosaic.tcl source $ds9(root)/src/smosaiciraf.tcl source $ds9(root)/src/smosaicwcs.tcl source $ds9(root)/src/smooth.tcl source $ds9(root)/src/srgbcube.tcl source $ds9(root)/src/starbase.tcl source $ds9(root)/src/stdfbox.tcl source $ds9(root)/src/stsci.tcl source $ds9(root)/src/template.tcl source $ds9(root)/src/text.tcl source $ds9(root)/src/tkfbox.tcl source $ds9(root)/src/url.tcl source $ds9(root)/src/util.tcl source $ds9(root)/src/var.tcl source $ds9(root)/src/vector.tcl source $ds9(root)/src/vo.tcl source $ds9(root)/src/wcs.tcl source $ds9(root)/src/xmfbox.tcl source $ds9(root)/src/xpa.tcl switch [tk windowingsystem] { x11 {} win32 {source $ds9(root)/src/win32.tcl} aqua {source $ds9(root)/src/macosx.tcl} } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catsimbad.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000011031�11700665566�014335� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATSIMBAD {varname} { upvar #0 $varname var global $varname global pcat global debug if {$debug(tcl,cat)} { puts stderr "CATSIMBAD $varname" } # parser if {$pcat(vot)} { set var(proc,parser) CATSIMBADParse } else { set var(proc,reader) CATSIMBADReader } # query set qq {} if {$pcat(vot)} { append qq "output script=off\n" append qq "output console=off\n" } if {$pcat(vot)} { append qq "votable v1 " } else { append qq "format object f1 " } switch -- $var(psky) { fk4 {set psky "FK4;1950;1950"} fk5 {set psky "FK5;2000;2000"} icrs {set psky "ICRS"} galactic {set psky "GAL"} ecliptic {set psky "ECL"} } if {$pcat(vot)} { append qq "{ coo(d;$psky), main_id, otype(S), pmra, pmdec, plx, z_value, flux(B), flux(V), sp }\n" append qq "votable open v1\n" } else { append qq {"%COO(d;A)\t%COO(d;D)\t%IDLIST(1)\t%OTYPE(S)\t%PM(A)\t%PM(D)\t%PLX(V)\t%RV(Z)\t%FLUXLIST(B;F)\t%FLUXLIST(V;F)\t%SP(S)\n"} append qq "\n" } switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { switch -- $var(sky) { fk4 - fk5 - icrs {set xx [h2d [Sex2H $var(x)]]} galactic - ecliptic {set xx [Sex2D $var(x)]} } set yy [Sex2D $var(y)] } } append qq "query coo $xx " if {$yy>0} { append qq "+$yy" } else { append qq "$yy" } set ww $var(width) set hh $var(height) set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] append qq " radius=$rr" switch -- $var(rformat) { degrees {append qq "d"} arcmin {append qq "m"} arcsec {append qq "s"} } switch -- $var(sky) { fk4 {append qq " frame=FK4 epoch=B1950 equinox=1950"} fk5 {append qq " frame=FK5 epoch=J2000 equinox=2000"} icrs {append qq " frame=ICRS"} galactic {append qq " frame=GAL"} ecliptic {append qq " frame=ECL"} } if {$pcat(vot)} { append qq "\nvotable close\n" } else { append qq "\n" } # url set var(url) "http://simbad.u-strasbg.fr/simbad/sim-script" set var(query) [http::formatQuery script $qq] if {$pcat(vot)} { CATLoad $varname } else { CATLoadIncr $varname } } proc CATSIMBADParse {t token} { upvar #0 $t T global $t global debug # we can't trust simbad to turn off any error messages variable $token upvar 0 $token state set id [string first {<?xml} $state(body)] set ${token}(body) [string range $state(body) $id end] CATVOTParse $t $token } proc CATSIMBADReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) 1 } 1 { # process header if {[gets $sock line] == -1} { set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) -1 return $result } set result [string length "$line"] # error? if {[string range $line 0 8] == {::error::}} { set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) -1 return $result } # start of data? if {[string range $line 0 7] == {::data::}} { # cols set line "RA\tDEC\tIdentifier\tObject\tPMRA\tPMDEC\tPX\tRV(z)\tB\tV\tSpectralType" incr ${t}(HLines) set n $T(HLines) set T(H_$n) $line set T(Header) [split $T(H_$n) "\t"] # dashes set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 2 } } 2 { # process table if {[gets $sock line] == -1} { set T(state) 0 } else { set result [string length "$line"] set line [string trim $line] if {$line != {}} { # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line "\t"] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } } } } return $result } proc CATSIMBADAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for SIMBAD This research has made use of the SIMBAD database, operated at CDS, Strasbourg, France. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/multiframe.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000006335�12131065211�014542� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMultiFrameFile {fn} { set path {} if {[string range $fn 0 4] == "stdin" || [string range $fn 0 4] == "STDIN" || [string range $fn 0 0] == "-"} { set path [tmpnam ds9 {.fits}] catch { set ch [open "$path" w] fconfigure stdin -translation binary -encoding binary fconfigure $ch -translation binary -encoding binary puts -nonewline $ch [read stdin] close $ch } } LoadMultiFrameAlloc $path $fn } proc LoadMultiFrameSocket {sock fn} { global loadParam global current global ds9 set path [tmpnam ds9 {.fits}] catch { set ch [open "$path" w] fconfigure $ch -translation binary -encoding binary fconfigure $sock -translation binary -encoding binary puts -nonewline $ch [read $sock] close $ch } return [LoadMultiFrameAlloc $path $fn] } proc LoadMultiFrameAlloc {path fn} { global loadParam global current global ds9 set ext 0 set cnt 0 set did 0 set need 0 # start with new frame? if {$current(frame) != {}} { switch -- [$current(frame) get type] { base { if [$current(frame) has fits] { CreateFrame set did 1 } } rgb - 3d { CreateFrame set did 1 } } } else { CreateFrame } while {1} { # create a new frame if {$need} { CreateFrame set did 1 } # ProcessLoad will clear loadParam each time set loadParam(file,type) fits set loadParam(file,mode) {} if {$path != {}} { set loadParam(load,type) allocgz set loadParam(file,name) "stdin\[$ext\]" set loadParam(file,fn) "$path\[$ext\]" } else { set loadParam(load,type) mmapincr set loadParam(file,name) "$fn\[$ext\]" } set loadParam(load,layer) {} if {![ProcessLoad 0]} { if {$ext} { InitError xpa if {$did} { DeleteCurrentFrame incr ds9(next,num) -1 } if {!$cnt} { Error "[msgcat::mc {Unable to load}] $loadParam(file,type) $loadParam(file,mode) $loadParam(file,name)" return 0 } break; } } else { # ignore any bin tables if {![$current(frame) has fits bin]} { incr cnt set need 1 } else { set need 0 } } incr ext } if {$path != {}} { catch {file delete -force $path} } # go into tile mode if more than one if {$cnt && $current(display) != "tile"} { set current(display) tile DisplayMode } return 1 } proc ProcessMultiFrameCmd {varname iname sock fn} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { new { incr i # not supported } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa global ds9 switch $ds9(wm) { x11 - aqua { if {![LoadMultiFrameSocket $sock $param]} { InitError xpa LoadMultiFrameFile $param } } win32 {LoadMultiFrameFile $param} } } else { # comm if {$fn != {}} { LoadMultiFrameAlloc $fn $param } else { LoadMultiFrameFile $param } } FinishLoad } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markeranalysisplot2d.tcl���������������������������������������������������������������0000644�0001750�0001750�00000014032�12064702421�016546� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # support proc MarkerAnalysisPlot2dDialog {varname} { upvar #0 $varname var global $varname global marker set id $var(id) set frame $var(frame) set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname set var(plot2d) [info exists ${vvarname}(top)] set var(method) average $var(mb).analysis add checkbutton -label [msgcat::mc {Plot 2D}] \ -variable ${varname}(plot2d) \ -command "MarkerAnalysisPlot2dCmd $varname" $var(mb).analysis add separator $var(mb).analysis add cascade \ -label [msgcat::mc {Method}] \ -menu $var(mb).analysis.method menu $var(mb).analysis.method $var(mb).analysis.method add radiobutton \ -label [msgcat::mc {Average}] \ -variable ${varname}(method) -value average \ -command "MarkerAnalysisPlot2dMethod $varname" $var(mb).analysis.method add radiobutton \ -label [msgcat::mc {Sum}] \ -variable ${varname}(method) -value sum \ -command "MarkerAnalysisPlot2dMethod $varname" } proc MarkerAnalysisPlot2dCmd {varname} { upvar #0 $varname var global $varname MarkerAnalysisPlot2d $var(frame) $var(id) $var(plot2d) } proc MarkerAnalysisPlot2d {frame id plot} { $frame marker $id analysis plot2d $plot if {$plot} { MarkerAnalysisPlot2dCB $frame $id set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname PlotRaise $vvarname } else { MarkerAnalysisPlot2dDeleteCB $frame $id } } proc MarkerAnalysisPlot2dMethod {varname} { upvar #0 $varname var global $varname if {[info exists var(plot2d)]} { if {$var(plot2d)} { MarkerAnalysisPlot2dCB $var(frame) $var(id) MarkerAnalysisPlot2dYAxisTitle $var(frame) $var(id) } } } proc MarkerAnalysisPlot2dSystem {varname} { upvar #0 $varname var global $varname if {[info exists var(plot2d)]} { if {$var(plot2d)} { MarkerAnalysisPlot2dCB $var(frame) $var(id) MarkerAnalysisPlot2dXAxisTitle $var(frame) $var(id) } } } # hardcoded marker.C proc MarkerAnalysisPlot2dCB {frame id} { set varname "mk${frame}-${id}" global $varname upvar #0 $varname var set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname if {[info exists var(system)]} { set vvar(system) $var(system) set sys $var(system) } elseif {[info exists vvar(system)]} { set sys $vvar(system) } else { global wcs set vvar(system) $wcs(system) set sys $wcs(system) } if {[info exists var(sky)]} { set vvar(sky) $var(sky) set sky $var(sky) } elseif {[info exists vvar(sky)]} { set sky $vvar(sky) } else { global wcs set sky $wcs(sky) } if {[info exists var(method)]} { set vvar(method) $var(method) set method $var(method) } elseif {[info exists vvar(method)]} { set method $vvar(method) } else { set vvar(method) average set method average } set xdata plot2d${id}${frame}x set ydata plot2d${id}${frame}y set xcdata plot2d${id}${frame}xc set ycdata plot2d${id}${frame}yc global $xdata $ydata $xcdata $ycdata if {[PlotPing $vvarname]} { $frame get marker $id analysis plot2d $xdata $ydata $xcdata $ycdata \ $sys $sky $method PlotStats $vvarname PlotList $vvarname } else { set tt [string totitle [$frame get marker $id type]] PlotLineDialog $vvarname $tt $tt $sys Counts MarkerAnalysisPlot2dXAxisTitle $frame $id MarkerAnalysisPlot2dYAxisTitle $frame $id # setup our own formatting set vvar(graph,format) 0 set vvar(xcdata) $xcdata set vvar(ycdata) $ycdata $vvar(graph) xaxis configure \ -command "MarkerAnalysisPlot2dXAxis $frame $id" set vvar(manage) 0 set vvar(dim) xy set vvar(xdata) $xdata set vvar(ydata) $ydata set vvar(xedata) {} set vvar(yedata) {} blt::vector create $xdata $ydata $xcdata $ycdata $frame get marker $id analysis plot2d $xdata $ydata $xcdata $ycdata \ $sys $sky $method PlotExternal $vvarname $vvar(proc,createelement) $vvarname $vvar(proc,updateelement) $vvarname $vvar(proc,updategraph) $vvarname PlotStats $vvarname PlotList $vvarname } } proc MarkerAnalysisPlot2dDeleteCB {frame id} { # this routine could be called by the region # after the dialog has been deleted set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname set xcdata plot2d${id}${frame}xc set ycdata plot2d${id}${frame}yc # clear extra vectors global $xcdata $ycdata catch {blt::vector destroy $xcdata $ycdata} # clear any errors global errorInfo set errorInfo {} PlotDestroy $vvarname } proc MarkerAnalysisPlot2dXAxisTitle {frame id} { set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname switch -- $vvar(system) { image - physical - amplifier - detector {set title "$vvar(system)"} default { if {[$frame has wcs equatorial $vvar(system)]} { set title "$vvar(system)" } else { set title "[$frame get wcs name $vvar(system)]" } } } # set for plot code set vvar(graph,xaxis) $title # update now (may not make it into plot code) $vvar(graph) xaxis configure -title $vvar(graph,xaxis) } proc MarkerAnalysisPlot2dYAxisTitle {frame id} { set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname # set for plot code set vvar(graph,yaxis) "Counts [string totitle $vvar(method)]" # update now (may not make it into plot code) $vvar(graph) yaxis configure -title $vvar(graph,yaxis) } proc MarkerAnalysisPlot2dXAxis {frame id w xx} { set vvarname plot2d${id}${frame} upvar #0 $vvarname vvar global $vvarname set x [expr $xx-1] global $vvar(xcdata) $vvar(ycdata) # sometimes, $x equals $vvar(xcdata) length set ll [$vvar(xcdata) length] if {($ll>=1) && ($x>=0) && ($x<$ll)} { set a [format "%6.3f" [expr "$$vvar(xcdata)\($x\)"]] set b [format "%6.3f" [expr "$$vvar(ycdata)\($x\)"]] return "$a\n$b" } else { return {} } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catsdss.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000007654�11700665566�014072� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATSDSS {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATSDSS $varname" } set var(proc,reader) CATSDSSReader # coord (degrees) switch $var(skyformat) { degrees { set xx $var(x) set yy $var(y) } sexagesimal { set xx [h2d [Sex2H $var(x)]] set yy [Sex2D $var(y)] } } # size (arcmin) switch $var(rformat) { degrees { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcmin { set ww $var(width) set hh $var(height) } arcsec { set ww [expr $var(width)/60.] set hh [expr $var(height)/60.] } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] set query {} append query "ra=$xx&" append query "dec=$yy&" append query "radius=$rr&" # append query "min_ra=[expr $xx-$ww/2.]&max_ra=[expr $xx+$ww/2.]&" # append query "min_dec=[expr $yy-$hh/2.]&max_dec=[expr $yy+$hh/2.]&" # output if {$var(allrows)} { append query "entries=all&" } else { append query "topnum=$var(max)&" } append query "format=csv&" set var(url) "http://cas.sdss.org/astrodr${var(catalog)}/en/tools/search/x_radial.asp?$query" set var(query) {} CATLoadIncr $varname } proc CATSDSSReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(state) 1 } 1 { # process header if {[gets $sock line] == -1} { return } if {[string equal $line "No objects have been found"]} { return } # cols incr ${t}(HLines) set n $T(HLines) set result [string length "$line"] set T(H_$n) $line set T(Header) [split $T(H_$n) ","] # dashes set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 2 } 2 { # process table if {[gets $sock line] == -1} { set T(state) 0 } else { set result [string length "$line"] set line [string trim $line] if {$line != {}} { # ok, save it incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols $t] set c 1 foreach val [split $line ","] { set T($r,$c) $val incr c } for {} {$c <= $NCols} {incr c} { set T($r,$c) {} } } } } } return $result } proc CATSDSSAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for SDSS Funding for the Sloan Digital Sky Survey (SDSS) has been provided by the Alfred P. Sloan Foundation, the Participating Institutions, the National Aeronautics and Space Administration, the National Science Foundation, the U.S. Department of Energy, the Japanese Monbukagakusho, and the Max Planck Society. The SDSS Web site is http://www.sdss.org/. The SDSS is managed by the Astrophysical Research Consortium (ARC) for the Participating Institutions. The Participating Institutions are The University of Chicago, Fermilab, the Institute for Advanced Study, the Japan Participation Group, The Johns Hopkins University, the Korean Scientist Group, Los Alamos National Laboratory, the Max-Planck-Institute for Astronomy (MPIA), the Max-Planck-Institute for Astrophysics (MPA), New Mexico State University, University of Pittsburgh, University of Portsmouth, Princeton University, the United States Naval Observatory, and the University of Washington. } SimpleTextDialog ${varname}ack [msgcat::mc {Acknowledgment}] 80 10 insert top $msg } ������������������������������������������������������������������������������������./saods9/src/catvot.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000021132�12035363452�013700� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATVOTParse {t token} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { set fp [open debug.xml w] puts $fp [http::data $token] close $fp } set xml [xml::parser \ -characterdatacommand [list CATVOTCharCB $t] \ -elementstartcommand [list CATVOTElemStartCB $t] \ -elementendcommand [list CATVOTElemEndCB $t] \ -ignorewhitespace 1 \ ] set T(tree,state) {} set T(tree,prev) {} if [catch {$xml parse [http::data $token]} err] { if {$debug(tcl,cat)} { puts stderr "CATVOTParse: $err" } } $xml free } proc CATVOTRead {t fn} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { puts stderr "CATVOTRead" } if {$fn == {}} { return } catch { set fp [open $fn r] set xml [xml::parser \ -characterdatacommand [list CATVOTCharCB $t]\ -elementstartcommand [list CATVOTElemStartCB $t] \ -elementendcommand [list CATVOTElemEndCB $t] \ -ignorewhitespace 1 \ ] set T(tree,state) {} set T(tree,prev) {} if {[catch {$xml parse [read $fp]} err]} { if {$debug(tcl,cat)} { puts stderr "CATVOTRead: $err" } } $xml free close $fp } } proc CATVOTWrite {t fn} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { puts stderr "CATVOTWriteFile" } if {$fn == {}} { return } set fp [open $fn w] set nr $T(Nrows) set nc $T(Ncols) puts $fp {<?xml version="1.0" encoding="UTF-8"?>} puts $fp {<VOTABLE version="1.1">} puts $fp {<RESOURCE>} puts $fp {<TABLE>} # header puts -nonewline $fp {<DESCRIPTION>} set nh [expr $T(HLines)-1] for {set hh 1} {$hh < $nh} {incr hh} { puts $fp [XMLQuote "$T(H_$hh)"] } puts $fp {</DESCRIPTION>} # cols for {set cc 1} {$cc <= $nc} {incr cc} { puts -nonewline $fp {<FIELD } # required puts -nonewline $fp "name=\"[XMLQuote [lindex $T(Header) [expr $cc-1]]]\" " # required if {[info exists ${t}(DataType)]} { puts -nonewline $fp "datatype=\"[XMLQuote [lindex $T(DataType) [expr $cc-1]]]\" " } else { puts -nonewline $fp "datatype=\"char\" arraysize=\"*\" " } if {[info exists ${t}(Id)]} { if {[lindex $T(Id) [expr $cc-1]] != {}} { puts -nonewline $fp "ID=\"[XMLQuote [lindex $T(Id) [expr $cc-1]]]\" " } } if {[info exists ${t}(ArraySize)]} { if {[lindex $T(ArraySize) [expr $cc-1]] != {}} { puts -nonewline $fp "arraysize=\"[XMLQuote [lindex $T(ArraySize) [expr $cc-1]]]\" " } } if {[info exists ${t}(Width)]} { if {[lindex $T(Width) [expr $cc-1]] != {}} { puts -nonewline $fp "width=\"[XMLQuote [lindex $T(Width) [expr $cc-1]]]\" " } } if {[info exists ${t}(Precision)]} { if {[lindex $T(Precision) [expr $cc-1]] != {}} { puts -nonewline $fp "precision=\"[XMLQuote [lindex $T(Precision) [expr $cc-1]]]\" " } } if {[info exists ${t}(Unit)]} { if {[lindex $T(Unit) [expr $cc-1]] != {}} { puts -nonewline $fp "unit=\"[XMLQuote [lindex $T(Unit) [expr $cc-1]]]\" " } } if {[info exists ${t}(Ref)]} { if {[lindex $T(Ref) [expr $cc-1]] != {}} { puts -nonewline $fp "ref=\"[XMLQuote [lindex $T(Ref) [expr $cc-1]]]\" " } } if {[info exists ${t}(Ucd)]} { if {[lindex $T(Ucd) [expr $cc-1]] != {}} { puts -nonewline $fp "ucd=\"[XMLQuote [lindex $T(Ucd) [expr $cc-1]]]\" " } } puts $fp {>} if {[info exists ${t}(Description)]} { if {[lindex $T(Description) [expr $cc-1]] != {}} { puts -nonewline $fp {<DESCRIPTION>} puts -nonewline $fp "[XMLQuote [lindex $T(Description) [expr $cc-1]]]" puts $fp {</DESCRIPTION>} } } puts $fp {</FIELD>} } # data puts $fp {<DATA>} puts $fp {<TABLEDATA>} for {set rr 1} {$rr <= $nr} {incr rr} { puts -nonewline $fp {<TR>} for {set cc 1} {$cc <= $nc} {incr cc} { puts -nonewline $fp "<TD>[XMLQuote $T($rr,$cc)]</TD>" } puts $fp {</TR>} } # clean up puts $fp {</TABLEDATA>} puts $fp {</DATA>} puts $fp {</TABLE>} puts $fp {</RESOURCE>} puts $fp {</VOTABLE>} close $fp } # Callbacks proc CATVOTCharCB {t data} { upvar #0 $t T global $t global debug switch -- $T(tree,state) { TD { set r $T(Nrows) set c $T(cnt) set T($r,$c) [string trim $data] } DESCRIPTION { set data [string trim $data] if {$data != {}} { switch -- $T(tree,prev) { VOTABLE - RESOURCE - TABLE { foreach ll [split [string trim $data] "\n"] { incr ${t}(HLines) set n $T(HLines) if {[string range $ll 0 0] == {#}} { set T(H_$n) "$ll" } else { set T(H_$n) "# $ll" } } } FIELD { set T(Description) \ [lreplace $T(Description) end end $data] } } } } } # sometimes, we get a bogus call, (ignore whitespace does not work) set T(tree,state) {} return {} } proc CATVOTElemStartCB {t name attlist args} { upvar #0 $t T global $t global debug switch -- $name { VOTABLE { # init db set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 set T(tree,prev) $name } FIELD { set fname {} set id {} set datatype {} set arraysize {} set width {} set precision {} set unit {} set ref {} set ucd {} foreach {key value} $attlist { switch -- [string tolower $key] { name {set fname "$value"} id {set id "$value"} datatype {set datatype $value} arraysize {set arraysize $value} width {set width $value} precision {set precision $value} unit {set unit "$value"} ref {set ref "$value"} ucd {set ucd "$value"} } } lappend ${t}(Header) "$fname" lappend ${t}(Id) "$id" lappend ${t}(DataType) $datatype lappend ${t}(ArraySize) $arraysize lappend ${t}(Width) $width lappend ${t}(Precision) $precision lappend ${t}(Unit) "$unit" lappend ${t}(Ref) "$ref" lappend ${t}(Ucd) "$ucd" # filled in later lappend ${t}(Description) {} set T(tree,prev) $name } TABLEDATA { # ok, we now need to build the header incr ${t}(HLines) set n $T(HLines) set T(H_$n) [join $T(Header)] set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Header)] incr ${t}(HLines) set n $T(HLines) set T(H_$n) [join $T(Dashes)] starbase_colmap $t } TR { incr ${t}(Nrows) set T(cnt) 0 } TD { incr ${t}(cnt) set r $T(Nrows) set c $T(cnt) set T($r,$c) {} } RESOURCE - TABLE { set T(tree,prev) $name } FIELDref - DESCRIPTION - COOSYS - PARAM - PARAMref - INFO - LINK - GROUP - DATA - BINARY - STREAM - FITS - VALUES - MIN - MAX - OPTION - DEFINITIONS {} default {return -code error} } set ${t}(tree,state) $name return {} } proc CATVOTElemEndCB {t name args} { upvar #0 $t T global $t global debug # we can't count on this being called for all end-tags switch -- $name { TABLEDATA { # ok, we're done return -code break } VOTABLE - FIELD - FIELDref - TR - TD - RESOURCE - TABLE - DESCRIPTION - COOSYS - PARAM - PARAMref - INFO - LINK - GROUP - DATA - BINARY - STREAM - FITS - VALUES - MIN - MAX - OPTION - DEFINITIONS {} default {return -code error} } return {} } # SAMP proc CATVOTURL {url catalog title} { if {[string length $url] == 0} { return } ParseURL $url r switch -- $r(scheme) { ftp {CATVOTFTP $r(authority) $r(path)} file {CATVOTFile $r(path)} http - default {CATVOTHTTP $url $catalog $title} } } proc CATVOTFTP {host path} { global loadParam global ds9 global debug set ftp [ftp::Open $host "ftp" "-ds9@" -mode passive] if {$ftp > -1} { set fn "$ds9(tmpdir)/[file tail $path]" set ftp::VERBOSE $debug(tcl,ftp) set "ftp::ftp${ftp}(Output)" FTPLog ftp::Type $ftp binary if [ftp::Get $ftp $path $fn] { CATVOTFile $fn } ftp::Close $ftp if [file exists $fn] { catch {file delete -force $fn} } } } proc CATVOTHTTP {url catalog title} { global icat CATDialog catvot {} $catalog $title none set varname [lindex $icat(cats) end] upvar #0 $varname var global $varname set ${varname}(query) {} set ${varname}(url) $url set ${varname}(proc,parser) CATVOTParse CATLoad $varname } proc CATVOTFile {fn} { global icat CATDialog catvot {} {} {} none if {$fn != {}} { CATLoadFn [lindex $icat(cats) end] $fn CATVOTRead } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/hvform.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000031547�12131577017�013715� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc HVFormCB {varname n cmd args} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVFormCB $varname $n $cmd $args" } switch -- [string tolower $cmd] { form {HVFormForm $varname $n args} flush {HVFormFlush $varname $n args} input {HVFormInput $varname $n args} select {HVFormSelect $varname $n args} textarea {HVFormTextArea $varname $n args} } } proc HVFormForm {varname n a} { upvar #0 $varname var global $varname upvar $a args global debug if {$debug(tcl,hv)} { puts stderr "HVFormForm $n $args" } # try to clean up lose vars from previous forms HVFormFlush $varname $n {} set aa [lindex $args 2] set var(form,$n,action) [lindex $args 0] set var(form,$n,method) [HVattrs method $aa get] if {$debug(tcl,hv)} { puts stderr "HVFormForm method $var(form,$n,method)" puts stderr "HVFormForm action $var(form,$n,action)" } } proc HVFormFlush {varname n a} { upvar #0 $varname var global $varname upvar $a args global debug if {$debug(tcl,hv)} { puts stderr "HVFormFlush $n" } # unset all var(form,$n,*) foreach x [array names $varname "form,$n,*"] { unset ${varname}($x) } bind $var(top) <Return> {} } proc HVFormInput {varname n a} { upvar #0 $varname var global $varname upvar $a args global debug set path [lindex $args 0] set attrs [lindex $args 1] if {$debug(tcl,hv)} { puts stderr "HVFormInput $n $path $attrs" } set id [lindex [split $path .] end] set type [HVattrs type $attrs {}] set disabled [HVattrs disabled $attrs normal] set readonly [HVattrs readonly $attrs normal] switch -- [string tolower $type] { checkbox { set name [HVattrs name $attrs var] set value [HVattrs value $attrs on] set checked [HVattrs checked $attrs nochecked] set var(form,$n,name,$id) $name if {$checked != "nochecked"} { set var(form,$n,var,$id) $value } else { set var(form,$n,var,$id) {} } set var(form,$n,init,$id) $$var(form,$n,var,$id) ttk::checkbutton $path -variable ${varname}(form,$n,var,$id) \ -onvalue $value -offvalue {} -state $disabled } radio { set name [HVattrs name $attrs var] # we need this so that all share the same variable set id $name set value [HVattrs value $attrs on] set checked [HVattrs checked $attrs nochecked] set var(form,$n,name,$id) $name if {$checked != "nochecked"} { set var(form,$n,var,$id) $value set var(form,$n,init,$id) $var(form,$n,var,$id) } # override init value foreach f $var(init) { if {$n == [lindex $f 0] && $name == [lindex $f 1] && $value == [lindex $f 2]} { set var(form,$n,var,$id) $value set var(form,$n,init,$id) $var(form,$n,var,$id) } } ttk::radiobutton $path -variable ${varname}(form,$n,var,$id) \ -value $value -state $disabled } button { set name [HVattrs name $attrs submit] set value [HVattrs value $attrs "Submit"] ttk::button $path -text $value \ -command "HVSubmitForm $varname $n \{$name\} \{$value\}" } submit { set name [HVattrs name $attrs submit] set value [HVattrs value $attrs "Submit"] ttk::button $path -text $value \ -command "HVSubmitForm $varname $n \{$name\} \{$value\}" bind $var(top) <Return> \ "HVSubmitForm $varname $n \{$name\} \{$value\}" } reset { set name [HVattrs name $attrs reset] set value [HVattrs value $attrs "Reset"] ttk::button $path -text $value -command "HVResetForm $varname $n" } image { set name [HVattrs name $attrs submit] set value [HVattrs value $attrs "Submit"] set src [HVattrs src $attrs {}] set img [HVImageCB $varname [$var(widget) resolve $src]] if {$img != "$var(images,gray)"} { ttk::button $path -image $img \ -command "HVSubmitForm $varname $n \{$name\} \{$value\}" } else { ttk::button $path -text $value -state $disabled \ -command "HVSubmitForm $varname $n \{$name\} \{$value\}" } return } hidden { set name [HVattrs name $attrs var] set value [HVattrs value $attrs {}] set var(form,$n,name,$id) $name set var(form,$n,var,$id) $value } password { set name [HVattrs name $attrs var] set value [HVattrs value $attrs {}] set size [HVattrs size $attrs 20] set var(form,$n,name,$id) $name set var(form,$n,var,$id) $value set var(form,$n,init,$id) $var(form,$n,var,$id) ttk::entry $path -textvariable ${varname}(form,$n,var,$id) \ -width $size -show "*" -state $readonly } file { set name [HVattrs name $attrs var] set value [HVattrs value $attrs {}] set size [HVattrs size $attrs 20] set var(form,$n,name,$id) $name set var(form,$n,var,$id) [HVInitVar $varname $n $name $value] set var(form,$n,init,$id) $var(form,$n,var,$id) ttk::entry $path -textvariable ${varname}(form,$n,var,$id) \ -width $size -state $readonly } text - default { set name [HVattrs name $attrs var] set value [HVattrs value $attrs {}] set size [HVattrs size $attrs 20] set var(form,$n,name,$id) $name set var(form,$n,var,$id) [HVInitVar $varname $n $name $value] set var(form,$n,init,$id) $var(form,$n,var,$id) ttk::entry $path -textvariable ${varname}(form,$n,var,$id) \ -width $size -state $readonly } } } proc HVFormSelect {varname n a} { upvar #0 $varname var global $varname upvar $a args global ds9 global debug set path [lindex $args 0] set attrs [lindex $args 1] set choices [lindex $args 2] set initial [lindex $args 3] if {$debug(tcl,hv)} { puts stderr "HVFormSelect :$n:$path:$attrs:$choices:$initial:" } set id [lindex [split $path .] end] set name [HVattrs name $attrs var] set size [HVattrs size $attrs 0] set multiple [HVattrs multiple $attrs single] if {[string length $multiple] == 0} { set multiple multiple } switch -- $multiple { single { set var(form,$n,name,$id) $name ttk::menubutton $path -textvariable ${varname}(form,$n,single,$id) \ -menu $path.m menu $path.m -tearoff 0 set l 0 set first 1 foreach f $choices { set i [lindex $f 0] set v [lindex $f 1] set m [lindex $f 2] if {[string length $v] == 0} { set v $m } if {$i || $first} { set var(form,$n,var,$id) $v set var(form,$n,init,$id) $v set var(form,$n,single,$id) $m set var(form,$n,singleinit,$id) $m set first 0 } if {[string length $m]>$l} { set l [string length $m] } $path.m add command -label $m -command \ "upvar #0 $varname var; set var(form,$n,var,$id) \"$v\"; set var(form,$n,single,$id) \"$m\"" } # override init value foreach f $var(init) { if {$n == [lindex $f 0] && $name == [lindex $f 1]} { set v [lindex $f 2] set m [lindex $f 3] set var(form,$n,var,$id) $v set var(form,$n,init,$id) $v set var(form,$n,single,$id) $m set var(form,$n,singleinit,$id) $m } } $path configure -width $l } multiple { set var(form,$n,name,$id) $name set var(form,$n,multivar,$id) {} set var(form,$n,multiinit,$id) {} set var(form,$n,multimenu,$id) {} set l 0 set long {} set ii 0 foreach f $choices { if [lindex $f 0] { lappend var(form,$n,multiinit,$id) $ii } set foo [lindex $f 1] if {[string length $foo] == 0} { set foo [lindex $f 2] } lappend var(form,$n,multivar,$id) $foo lappend var(form,$n,multimenu,$id) [lindex $f 2] set m [lindex $f 2] if {[string length $m]>$l} { set long $m set l [string length $m] } incr ii } set var(form,$n,multiple,$id) $path # we have a problem # the frame we create will not resize itself based on the # interior size of the listbox and the scrollbar # so, we need to set the frame size by hand set font "$ds9($var(font)) $var(font,size) $var(font,weight) $var(font,slant)" ttk::frame $path ttk::scrollbar $path.scroll -command "$path.list yview" listbox $path.list -selectmode multiple \ -width 0 -height $size \ -listvar ${varname}(form,$n,multimenu,$id) \ -font $font \ -yscroll "$path.scroll set" \ -exportselection false set w [expr [font measure $font $long]+30] set h [expr $size*[font metrics $font -linespace]] $path configure -width $w -height $h pack $path.list $path.scroll -side left -fill y -expand 1 foreach ii $var(form,$n,multiinit,$id) { $path.list selection set $ii } } } } proc HVFormTextArea {varname n a} { upvar #0 $varname var global $varname upvar $a args set path [lindex $args 0] set attrs [lindex $args 1] set initial [string range [lindex $args 2] 1 end] global debug if {$debug(tcl,hv)} { puts stderr "HVFormTextArea $n $path $attrs $initial" } set id [lindex [split $path .] end] set name [HVattrs name $attrs var] set rows [HVattrs rows $attrs 4] set cols [HVattrs cols $attrs 20] set readonly [HVattrs disabled $attrs normal] # update initial set initial [HVInitVar $varname $n $name $initial] text $path -height $rows -width $cols -wrap none -state $readonly $path insert end $initial set var(form,$n,name,$id) $name set var(form,$n,var,$id) $initial set var(form,$n,init,$id) $var(form,$n,var,$id) set var(form,$n,textarea,$id) $path } proc HVattrs {k l def} { # break list up into key/value pairs set key {} set value {} set w 1 foreach f $l { if {$w} { lappend key [string tolower $f] set w 0 } else { lappend value $f set w 1 } } set a [lsearch -exact $key [string tolower $k]] if {$a>=0} { return [lindex $value $a] } else { return $def } } proc HVSubmitForm {varname n name value} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVSubmitForm $n" } bind $var(top) <Return> {} # update textareas foreach x [array names $varname "form,$n,textarea,*"] { set f [split $x ,] set id [lindex $f 3] set path $var($x) set var(form,$n,var,$id) [$path get 1.0 end] } set query {} # append button name=value append query "[http::formatQuery $name $value]&" # append normal vars foreach x [array names $varname "form,$n,var,*"] { set f [split $x ,] set id [lindex $f 3] set v [string trim $var($x)] if {[string length $v] != 0} { append query "[http::formatQuery $var(form,$n,name,$id) $v]&" } } # append multiple select foreach x [array names $varname "form,$n,multiple,*"] { set f [split $x ,] set id [lindex $f 3] set path $var($x) set iii [$path.list curselection] foreach ii $iii { set v [string trim [lindex $var(form,$n,multivar,$id) $ii]] if {[string length $v] != 0} { append query "[http::formatQuery $var(form,$n,name,$id) $v]&" } } } # remove last '&' set query [string trimright $query &] HVClearIndex $varname $var(index) # and do it # already resolved switch -- [string tolower $var(form,$n,method)] { get {HVLoadURL $varname "$var(form,$n,action)?$query" {} $var(sync)} post {HVLoadURL $varname "$var(form,$n,action)" "$query" $var(sync)} } } proc HVResetForm {varname n} { upvar #0 $varname var global $varname global debug if {$debug(tcl,hv)} { puts stderr "HVResetForm $n" } foreach x [array names $varname "form,$n,init,*"] { set f [split $x ,] set var(form,$n,var,[lindex $f 3]) $var($x) } #update single select foreach x [array names $varname "form,$n,singleinit,*"] { set f [split $x ,] set var(form,$n,single,[lindex $f 3]) $var($x) } # update multiple select foreach x [array names $varname "form,$n,multiinit,*"] { set f [split $x ,] set path $var(form,$n,multiple,[lindex $f 3]) $path.list selection clear 0 foreach ii $var($x) { $path.list selection set $ii } } # update textareas foreach x [array names $varname "form,$n,textarea,*"] { set f [split $x ,] set path $var($x) $path delete 1.0 end $path insert end $var(form,$n,init,[lindex $f 3]) } } proc HVInitVar {varname n name def} { upvar #0 $varname var global $varname foreach f $var(init) { if {$n == [lindex $f 0] && $name == [lindex $f 1]} { return [lindex $f 2] } } return $def } proc HVFixHTMLForm {varname} { upvar #0 $varname var global $varname global debug if [regexp -nocase {<form [^>]*} $var(data) r] { if {![regexp -nocase {action=} $r]} { if {$debug(tcl,hv)} { puts stderr "HVFixFormHTML action fixed" } set rr "$r action=[$var(widget) cget -base]" regsub -nocase {<form [^>]*} $var(data) $rr var(data) } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/projection.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000005774�12007011531�014555� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ProjectionDialog {varname} { upvar #0 $varname var global $varname # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(tcoord) [lindex $rr 0] set var(tformat) degrees AdjustCoordSystem $varname tcoord # procs set var(which) projection set var(proc,apply) ProjectionApply set var(proc,coordCB) ProjectionCoordCB set var(proc,editCB) ProjectionEditCB set var(proc,distCB) ProjectionDistCB # base MarkerBaseLineDialog $varname 500 200 # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis # plot2d MarkerAnalysisPlot2dDialog $varname # init ProjectionThickCB $varname set f $var(top).param # Thick ttk::label $f.tthick -text [msgcat::mc {Thickness}] ttk::entry $f.thick -textvariable ${varname}(thick) -width 13 DistMenuButton $f.uthick $varname tcoord 1 tformat \ [list ProjectionThickCB $varname] DistMenuEnable $f.uthick.menu $varname tcoord 1 tformat grid $f.tthick $f.thick $f.uthick -padx 2 -pady 2 -sticky w } # actions proc ProjectionApply {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) projection $var(system) $var(sky) \ $var(x) $var(y) $var(x2) $var(y2) \ $var(thick) $var(tcoord) $var(tformat) MarkerBaseLineApply $varname } # callbacks proc ProjectionCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "ProjectionCoordCB" } MarkerAnalysisPlot2dSystem $varname MarkerBaseCoordCB $varname ProjectionEditCB $varname } proc ProjectionEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "ProjectionEditCB" } MarkerBaseLineEditCB $varname set var(dist) [$var(frame) get marker $var(id) projection length \ $var(dcoord) $var(dformat)] set var(thick) [$var(frame) get marker $var(id) projection thick \ $var(tcoord) $var(tformat)] set var(angle) [$var(frame) get marker $var(id) angle \ $var(system) $var(sky)] } proc ProjectionDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "ProjectionDistCB" } set var(dist) [$var(frame) get marker $var(id) projection length \ $var(dcoord) $var(dformat)] } proc ProjectionThickCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "ProjectionThickCB" } set var(thick) [$var(frame) get marker $var(id) projection thick \ $var(tcoord) $var(tformat)] } ����./saods9/src/rgbimage.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000006303�12130604640�014151� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadRGBImageFile {fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb image} set loadParam(load,type) mmapincr set loadParam(file,name) $fn # mask not supported set loadParam(load,layer) {} ConvertFitsFile ProcessLoad } proc LoadRGBImageAlloc {path fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb image} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path # mask not supported set loadParam(load,layer) {} ProcessLoad } proc LoadRGBImageSocket {sock fn} { global loadParam global current switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to load RGB image into a non-rgb frame}] return } rgb {} } set loadParam(file,type) fits set loadParam(file,mode) {rgb image} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock # mask not supported set loadParam(load,layer) {} return [ProcessLoad 0] } proc SaveRGBImageFile {fn} { global current if {$fn == {} || $current(frame) == {}} { return } switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to save RGB image from a non-rgb frame}] return } rgb {} } if {![$current(frame) has fits]} { return } $current(frame) save fits rgb image file "\{$fn\}" } proc SaveRGBImageSocket {sock} { global current if {$current(frame) == {}} { return } switch -- [$current(frame) get type] { base - 3d { Error [msgcat::mc {Unable to save RGB image from a non-rgb frame}] return } rgb {} } if {![$current(frame) has fits]} { return } $current(frame) save fits rgb image socket $sock } proc ProcessRGBImageCmd {varname iname sock fn} { upvar $varname var upvar $iname i switch -- [string tolower [lindex $var $i]] { new { incr i CreateRGBFrame } mask { incr i # not supported } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadRGBImageSocket $sock $param]} { InitError xpa LoadRGBImageFile $param } } else { # comm if {$fn != {}} { LoadRGBImageAlloc $fn $param } else { LoadRGBImageFile $param } } FinishLoad } proc ProcessSendRGBImageCmd {proc id param sock fn} { global current if {$current(frame) == {}} { return } if {$sock != {}} { # xpa SaveRGBImageSocket $sock } elseif {$fn != {}} { # comm SaveRGBImageFile $fn $proc $id {} $fn } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/coord.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000011567�11713017520�013513� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CoordDef {} { global pcoord # prefs only set pcoord(filename) 0 set pcoord(value) 1 set pcoord(image) 1 set pcoord(physical) 0 set pcoord(amplifier) 0 set pcoord(detector) 0 set pcoord(wcs) 1 foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { set "pcoord(wcs$l)" 0 } } proc SetCoordSystem {varname system sky skyformat} { upvar #0 $varname var global $varname global current switch $var(system) { image - physical - detector - amplifier {} default { if {$current(frame) != {}} { set rr [$current(frame) get wcs] set var($system) [lindex $rr 0] if {$sky != {}} { set var($sky) [lindex $rr 1] } if {$skyformat != {}} { set var($skyformat) [lindex $rr 2] } } } } } proc AdjustCoordSystem {varname system} { upvar #0 $varname var global $varname global current switch -- $var($system) { image - physical - amplifier - detector {} wcs { if {$current(frame) != {}} { if {![$current(frame) has wcs $var($system)]} { set ${varname}($system) physical } } } default { if {$current(frame) != {}} { if {![$current(frame) has wcs $var($system)]} { if [$current(frame) has wcs wcs] { set ${varname}($system) wcs } else { set ${varname}($system) physical } } } } } } proc AdjustCoordSystem3d {varname system} { upvar #0 $varname var global $varname global current switch -- $var($system) { image {} wcs { if {$current(frame) != {}} { if {![$current(frame) has wcs $var($system)]} { set ${varname}($system) image } } } default { if {$current(frame) != {}} { if {![$current(frame) has wcs $var($system)]} { if [$current(frame) has wcs wcs] { set ${varname}($system) wcs } else { set ${varname}($system) image } } } } } } proc DisplayCoordDialog {which x y} { global pcoord global wcs set r {} if {$pcoord(filename)} { append r "[$which get fits file name full]" } foreach l {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {"$pcoord(wcs$l)" && [$which has wcs "wcs$l"]} { set cd "[$which get coordinates $x $y wcs$l $wcs(sky) $wcs(skyformat)]" if [$which has wcs equatorial "wcs$l"] { append r " [lindex $cd 0] [lindex $cd 1] $wcs(sky)" } else { set name [$which get wcs name "wcs$l"] if {$name != {}} { append r " [lindex $cd 0] [lindex $cd 1] $name" } else { append r " [lindex $cd 0] [lindex $cd 1] [lindex $cd 3]" } } } } if {$pcoord(detector) && [$which has detector]} { append r " [$which get coordinates $x $y detector] detector" } if {$pcoord(amplifier) && [$which has amplifier]} { append r " [$which get coordinates $x $y amplifier] amplifier" } if {$pcoord(physical) && [$which has physical]} { append r " [$which get coordinates $x $y physical] physical" } if {$pcoord(image)} { append r " [$which get coordinates $x $y image]" } if {$pcoord(value)} { append r " [$which get value canvas $x $y]" } append r " \n" SimpleTextDialog coordtxt [msgcat::mc {Coordinates}] 80 20 append bottom "$r" } proc PrefsDialogCoord {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Print Coordinates}] lappend dprefs(tabs) [ttk::frame $w.coord] # Print set f [ttk::labelframe $w.coord.print -text [msgcat::mc {Print}]] ttk::checkbutton $f.filename -text [msgcat::mc {Filename}] \ -variable pcoord(filename) ttk::checkbutton $f.value -text [msgcat::mc {Value}] \ -variable pcoord(value) ttk::checkbutton $f.wcs -text [msgcat::mc {WCS}] -variable pcoord(wcs) ttk::menubutton $f.mwcs -text [msgcat::mc {Multiple WCS}] -menu $f.mwcs.menu ttk::checkbutton $f.image -text [msgcat::mc {Image}] \ -variable pcoord(image) ttk::checkbutton $f.physical -text [msgcat::mc {Physical}] \ -variable pcoord(physical) ttk::checkbutton $f.amplifier -text [msgcat::mc {Amplifier}] \ -variable pcoord(amplifier) ttk::checkbutton $f.detector -text [msgcat::mc {Detector}] \ -variable pcoord(detector) set m $f.mwcs.menu menu $m foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $m add checkbutton -label "[msgcat::mc {WCS}] $l" \ -variable "pcoord(wcs$l)" } grid $f.filename -padx 2 -pady 2 -sticky w grid $f.value -padx 2 -pady 2 -sticky w grid $f.wcs $f.mwcs -padx 2 -pady 2 -sticky w grid $f.image -padx 2 -pady 2 -sticky w grid $f.physical -padx 2 -pady 2 -sticky w grid $f.amplifier -padx 2 -pady 2 -sticky w grid $f.detector -padx 2 -pady 2 -sticky w pack $w.coord.print -side top -fill both -expand true } �����������������������������������������������������������������������������������������������������������������������������������������./saods9/src/frame.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000143410�12117712633�013476� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Public Procedures proc CreateFrame {} { CreateNamedFrame base } proc CreateRGBFrame {} { CreateNamedFrame rgb RGBDialog } proc Create3DFrame {} { CreateNamedFrame 3d 3DDialog } proc CreateNamedFrame {type} { global ds9 # find the first open slot set num $ds9(next,num) while {1} { set which "Frame$num" if {[lsearch $ds9(frames) $which]==-1} { CreateNameNumberFrame $which $type set ds9(next,num) [expr $num+1] return } incr num } } proc CreateGotoFrame {num type} { global ds9 global active set which "Frame$num" if {[lsearch $ds9(frames) $which]==-1} { CreateNameNumberFrame $which $type set ds9(next,num) [expr $num+1] } else { if {$active($which)==0} { set active($which) 1 UpdateActiveFrames } set ds9(next) $which GotoFrame } } # used by backup proc CreateNameNumberFrame {which type} { global ds9 global pds9 global active global current global ipanner global ppanner global imagnifier global pmagnifier global bin global wcs global colorbar global scale global minmax global zscale global marker global centroid global panzoom global smooth global pthreed global threed set ds9(next) $which # update frame lists lappend ds9(frames) $ds9(next) lappend ds9(active) $ds9(next) set ds9(active,num) [llength $ds9(active)] set active($ds9(next)) 1 # and create the frame switch -- $ds9(visual) { pseudocolor { switch -- $type { base { $ds9(canvas) create frame$ds9(visual)$ds9(depth) \ -command $ds9(next) $ds9(next) colormap [colorbar get colormap] } rgb - 3d { Error [msgcat::mc {Unable to create RGB or 3D frame with pseudocolor visual}] } } } truecolor { switch -- $type { base { $ds9(canvas) create frame$ds9(visual)$ds9(depth) \ -command $ds9(next) $ds9(next) colormap [colorbar get colormap] } rgb { $ds9(canvas) create framergb$ds9(visual)$ds9(depth) \ -command $ds9(next) $ds9(next) colormap [colorbarrgb get colormap] } 3d { $ds9(canvas) create frame3d$ds9(visual)$ds9(depth) \ -command $ds9(next) $ds9(next) colormap [colorbar get colormap] } } } } $ds9(next) configure -x 0 -y 0 \ -anchor nw \ -tag $ds9(next) \ -helvetica $ds9(helvetica) \ -courier $ds9(courier) \ -times $ds9(times) $ds9(next) panner 'panner' $ipanner(size) $ipanner(size) $ds9(next) magnifier 'magnifier' $imagnifier(size) $imagnifier(size) $ds9(next) magnifier zoom $pmagnifier(zoom) $ds9(next) magnifier graphics $pmagnifier(region) $ds9(next) magnifier cursor $pmagnifier(cursor) $ds9(next) zoom to $current(zoom) $ds9(next) rotate to $current(rotate) $ds9(next) orient $current(orient) $ds9(next) wcs align $current(align) $ds9(next) pan preserve $panzoom(preserve) # set so prefs (pwcs) will work # may cause other problems, but can't remember why $ds9(next) wcs $wcs(system) $wcs(sky) $wcs(skyformat) $ds9(next) datasec $scale(datasec) $ds9(next) bg color $pds9(bg) $ds9(next) nan color $pds9(nan) $ds9(next) threads $pds9(threads) $ds9(next) marker show $marker(show) $ds9(next) marker show text $marker(show,text) $ds9(next) marker centroid auto $marker(centroid,auto) $ds9(next) marker centroid radius $marker(centroid,radius) $ds9(next) marker centroid iteration $marker(centroid,iteration) $ds9(next) marker preserve $marker(preserve) # Frame type items switch -- [$ds9(next) get type] { base - rgb {} 3d { $ds9(next) 3d method $pthreed(method) $ds9(next) 3d border $pthreed(border) $ds9(next) 3d border color $pthreed(border,color) $ds9(next) 3d compass $pthreed(compass) $ds9(next) 3d compass color $pthreed(compass,color) $ds9(next) 3d highlite $pthreed(highlite) $ds9(next) 3d highlite color $pthreed(highlite,color) } } # channel dependent items switch -- [$ds9(next) get type] { base - 3d { $ds9(next) colorscale $scale(type) $ds9(next) colorscale log $scale(log) $ds9(next) clip scope $scale(scope) $ds9(next) clip mode $scale(mode) $ds9(next) clip user $scale(min) $scale(max) $ds9(next) clip preserve $scale(preserve) $ds9(next) clip minmax mode $minmax(mode) $ds9(next) clip minmax sample $minmax(sample) $ds9(next) clip zscale contrast $zscale(contrast) $ds9(next) clip zscale sample $zscale(sample) $ds9(next) clip zscale line $zscale(line) $ds9(next) bin function $bin(function) $ds9(next) bin factor to $bin(factor) $ds9(next) bin depth $bin(depth) $ds9(next) bin buffer size $bin(buffersize) if {$smooth(view)} { $ds9(next) smooth $smooth(function) $smooth(radius) } } rgb { foreach c {red green blue} { $ds9(next) rgb channel $c $ds9(next) colorscale $scale(type) $ds9(next) colorscale log $scale(log) $ds9(next) clip scope $scale(scope) $ds9(next) clip mode $scale(mode) $ds9(next) clip user $scale(min) $scale(max) $ds9(next) clip preserve $scale(preserve) $ds9(next) datasec $scale(datasec) $ds9(next) clip minmax mode $minmax(mode) $ds9(next) clip minmax sample $minmax(sample) $ds9(next) clip zscale contrast $zscale(contrast) $ds9(next) clip zscale sample $zscale(sample) $ds9(next) clip zscale line $zscale(line) $ds9(next) bin function $bin(function) $ds9(next) bin factor to $bin(factor) $ds9(next) bin depth $bin(depth) $ds9(next) bin buffer size $bin(buffersize) if {$smooth(view)} { $ds9(next) smooth $smooth(function) $smooth(radius) } } $ds9(next) rgb channel red } } if {$current(mode) == {crosshair}} { $ds9(next) crosshair on } UpdateFrameMenuItems UpdateDS9Static if {$current(frame) != {}} { $current(frame) colorbar tag "\{[$current(colorbar) get tag]\}" } set current(frame) $ds9(next) set ds9(next) {} DisplayMode } proc DeleteAllFramesMenu {} { global pds9 if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message [msgcat::mc {Delete All Frames?}]] != {ok}} { return } } DeleteAllFrames } proc DeleteCurrentFrame {} { global current if {$current(frame) != {}} { DeleteSingleFrame $current(frame) } } proc DeleteAllFrames {} { global ds9 foreach ff $ds9(frames) { DeleteFrame $ff } set ds9(next,num) 1 UpdateFrameMenuItems UpdateActiveFrames UpdateDS9Static ClearInfoBox PixelTableClearDialog ClearGraphData } proc DeleteSingleFrame {which} { DeleteFrame $which UpdateFrameMenuItems UpdateActiveFrames UpdateDS9Static PixelTableClearDialog ClearGraphData } proc DeleteFrame {which} { global ds9 global active global current global contour global marker # clear any loaded images ClearFrame $which # contour copy if {$contour(copy) == $which} { set contour(copy) {} } # marker copy if {$marker(copy) == $which} { set marker(copy) {} } # delete canvas widget $ds9(canvas) delete $which # setup for next frame set ii [lsearch $ds9(active) $which] if {$ii>0} { set ds9(next) [lindex $ds9(active) [expr $ii-1]] set ds9(active) [lreplace $ds9(active) $ii $ii] set ds9(active,num) [llength $ds9(active)] unset active($which) } else { set ds9(next) {} } # delete it from the frame list set ii [lsearch $ds9(frames) $which] set ds9(frames) [lreplace $ds9(frames) $ii $ii] } proc UpdateCurrentFrame {} { global current UpdateFrame $current(frame) } proc UpdateAllFrame {} { global ds9 foreach f $ds9(frames) { UpdateFrame $f } } proc UpdateFrame {which} { if {$which != {}} { $which update } } # Event Processing proc BindEventsFrame {which} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "BindEventsFrame $which" } $ds9(canvas) bind $which <Motion> [list MotionFrame $which %x %y] $ds9(canvas) bind $which <Shift-Motion> \ [list ShiftMotionFrame $which %x %y] $ds9(canvas) bind $which <Control-Motion> \ [list ControlMotionFrame $which %x %y] $ds9(canvas) bind $which <Enter> [list EnterFrame $which %x %y] $ds9(canvas) bind $which <Leave> [list LeaveFrame $which] $ds9(canvas) bind $which <Button-1> [list Button1Frame $which %x %y] $ds9(canvas) bind $which <Shift-Button-1> \ [list ShiftButton1Frame $which %x %y] $ds9(canvas) bind $which <Control-Button-1> \ [list ControlButton1Frame $which %x %y] $ds9(canvas) bind $which <Control-Shift-Button-1> \ [list ControlShiftButton1Frame $which %x %y] $ds9(canvas) bind $which <B1-Motion> [list Motion1Frame $which %x %y] $ds9(canvas) bind $which <ButtonRelease-1> \ [list Release1Frame $which %x %y] $ds9(canvas) bind $which <Double-1> [list Double1Frame $which %x %y] $ds9(canvas) bind $which <Double-ButtonRelease-1> \ [list DoubleRelease1Frame $which %x %y] switch $ds9(wm) { x11 - win32 { $ds9(canvas) bind $which <Button-2> \ [list Button2Frame $which %x %y] $ds9(canvas) bind $which <Shift-Button-2> \ [list ShiftButton2Frame $which %x %y] $ds9(canvas) bind $which <B2-Motion> \ [list Motion2Frame $which %x %y] $ds9(canvas) bind $which <ButtonRelease-2> \ [list Release2Frame $which %x %y] } aqua { # swap button-2 and button-3 on the mighty mouse $ds9(canvas) bind $which <Button-3> \ [list Button2Frame $which %x %y] $ds9(canvas) bind $which <Shift-Button-3> \ [list ShiftButton2Frame $which %x %y] $ds9(canvas) bind $which <B3-Motion> \ [list Motion2Frame $which %x %y] $ds9(canvas) bind $which <ButtonRelease-3> \ [list Release2Frame $which %x %y] # x11 option key emulation $ds9(canvas) bind $which <Option-Button-1> \ [list Button2Frame $which %x %y] $ds9(canvas) bind $which <Option-B1-Motion> \ [list Motion2Frame $which %x %y] $ds9(canvas) bind $which <Option-ButtonRelease-1> \ [list Release2Frame $which %x %y] # x11 command key emulation # we need this to eat the Button-1 events # so it passes to the canvas $ds9(canvas) bind $which <Command-Button-1> {set foo bar} $ds9(canvas) bind $which <Command-B1-Motion> {set foo bar} $ds9(canvas) bind $which <Command-ButtonRelease-1> {set foo bar} } } switch $ds9(wm) { x11 { $ds9(canvas) bind $which <Button-4> \ [list Button4Frame $which %x %y] $ds9(canvas) bind $which <Button-5> \ [list Button5Frame $which %x %y] } win32 - aqua {} } BindEventsFrameKey $which } proc BindEventsFrameKey {which} { global ds9 global ianalysis global debug if {$debug(tcl,events)} { puts stderr "BindEventsFrameKey $which" } $ds9(canvas) bind $which <Key> [list KeyFrame $which %K %A %x %y] $ds9(canvas) bind $which <KeyRelease> \ [list KeyReleaseFrame $which %K %A %x %y] for {set i 0} {$i<$ianalysis(bind,count)} {incr i} { $ds9(canvas) bind $which "$ianalysis(bind,$i,item)" \ [list AnalysisTask $i bind $which %x %y] } } proc UnBindEventsFrame {which} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "UnBindEventsFrame $which" } $ds9(canvas) bind $which <Button-4> {} $ds9(canvas) bind $which <Button-5> {} $ds9(canvas) bind $which <Motion> {} $ds9(canvas) bind $which <Shift-Motion> {} $ds9(canvas) bind $which <Control-Motion> {} $ds9(canvas) bind $which <Enter> {} $ds9(canvas) bind $which <Leave> {} $ds9(canvas) bind $which <Button-1> {} $ds9(canvas) bind $which <Shift-Button-1> {} $ds9(canvas) bind $which <Control-Button-1> {} $ds9(canvas) bind $which <Control-Shift-Button-1> {} $ds9(canvas) bind $which <B1-Motion> {} $ds9(canvas) bind $which <ButtonRelease-1> {} $ds9(canvas) bind $which <Double-1> {} $ds9(canvas) bind $which <Double-ButtonRelease-1> {} switch $ds9(wm) { x11 - win32 { $ds9(canvas) bind $which <Button-2> {} $ds9(canvas) bind $which <Shift-Button-2> {} $ds9(canvas) bind $which <B2-Motion> {} $ds9(canvas) bind $which <ButtonRelease-2> {} } aqua { $ds9(canvas) bind $which <Command-Button-1> {} $ds9(canvas) bind $which <Command-B1-Motion> {} $ds9(canvas) bind $which <Command-ButtonRelease-1> {} $ds9(canvas) bind $which <Button-3> {} $ds9(canvas) bind $which <Shift-Button-3> {} $ds9(canvas) bind $which <B3-Motion> {} $ds9(canvas) bind $which <ButtonRelease-3> {} $ds9(canvas) bind $which <Option-Button-1> {} $ds9(canvas) bind $which <Option-B1-Motion> {} $ds9(canvas) bind $which <Option-ButtonRelease-1> {} } } switch $ds9(wm) { x11 { $ds9(canvas) bind $which <Button-4> {} $ds9(canvas) bind $which <Button-5> {} } win32 - aqua {} } UnBindEventsFrameKey $which } proc UnBindEventsFrameKey {which} { global ds9 global ianalysis global debug if {$debug(tcl,events)} { puts stderr "UnBindEventsFrameKey $which" } $ds9(canvas) bind $which <Key> {} $ds9(canvas) bind $which <KeyRelease> {} for {set i 0} {$i<$ianalysis(bind,count)} {incr i} { $ds9(canvas) bind $which "$ianalysis(bind,$i,item)" {} } } proc EnterFrame {which x y} { global ds9 global current global view global debug if {$debug(tcl,events)} { puts stderr "EnterFrame" } # check to see if this event was generated while processing other events if {$ds9(b1) || $ds9(sb1) || $ds9(cb1) || $ds9(csb1) || $ds9(b2) || $ds9(b3)} { return } $ds9(canvas) focus $which switch -- $current(mode) { crosshair { set coord [$which get crosshair canvas] set x [lindex $coord 0] set y [lindex $coord 1] } none - pointer - catalog - colorbar - pan - zoom - rotate - crop - examine - imexam {} } EnterInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas UpdateGraphXAxis $which UpdateGraphYAxis $which UpdateMagnifier $which $x $y if {$view(magnifier)} { # don't turn on the magnifier until we've finished the init process # this a real problem with 3d frames if {!$ds9(init)} { $which magnifier on } } UpdateEditMenu } proc LeaveFrame {which} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "LeaveFrame" } # check to see if this event was generated while processing other events if {$ds9(b1) || $ds9(sb1) || $ds9(cb1) || $ds9(csb1) || $ds9(b2) || $ds9(b3)} { return } $ds9(canvas) focus {} switch -- $current(mode) { crosshair {} none - pointer - catalog - colorbar - pan - zoom - rotate - crop - examine - imexam { LeaveInfoBox PixelTableClearDialog ClearGraphData } } $which magnifier off magnifier clear } proc MotionFrame {which x y} { global debug if {$debug(tcl,events)} { puts stderr "MotionFrame" } DoMotion $which $x $y sizing fleur } proc ShiftMotionFrame {which x y} { global debug if {$debug(tcl,events)} { puts stderr "ShiftMotionFrame" } DoMotion $which $x $y exchange fleur } proc ControlMotionFrame {which x y} { global debug if {$debug(tcl,events)} { puts stderr "ControlMotionFrame" } DoMotion $which $x $y sizing draped_box } proc DoMotion {which x y cursor1 cursor2} { global ds9 global current # if button 3 is down, ignore this event, we are doing something already if {$ds9(b3) || $ds9(b2)} { return } switch -- $current(mode) { crosshair {} pointer - catalog { if {$which == $current(frame)} { MarkerCursor $which $x $y $cursor1 $cursor2 } UpdateColormapLevelMosaic $which $x $y canvas UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas } none - colorbar - pan - zoom - rotate - crop - examine - imexam { UpdateColormapLevelMosaic $which $x $y canvas UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas } } UpdateMagnifier $which $x $y } proc Button1Frame {which x y} { global ds9 global current global imarker global imexam global debug if {$debug(tcl,events)} { puts stderr "Button1Frame" } # let others know that the mouse is down set ds9(b1) 1 switch -- $current(mode) { none { if {$which == $current(frame)} { } else { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set ds9(next) $which GotoFrame } UpdateMagnifier $which $x $y } pointer { if {$which == $current(frame)} { MarkerButton $which $x $y } else { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set ds9(next) $which GotoFrame } UpdateMagnifier $which $x $y } catalog { if {$which == $current(frame)} { CATButton $which $x $y } else { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set ds9(next) $which GotoFrame } UpdateMagnifier $which $x $y } crosshair { ButtonCrosshair $which $x $y UpdateColormapLevelMosaic $which $x $y canvas UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas UpdateMagnifier $which $x $y } colorbar { Button3Colorbar $x $y } pan { ButtonPan $which $x $y UpdateMagnifier $which $x $y } zoom { ButtonZoom $which $x $y UpdateMagnifier $which $x $y } rotate {ButtonRotate $which $x $y} crop { ButtonCrop $which $x $y UpdateMagnifier $which $x $y } examine {ButtonExamine $which $x $y} imexam { if {$imexam(button) || $imexam(any)} { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 set imexam(frame) $which set imexam(x) $x set imexam(y) $y if {$imexam(any)} { set imexam(event) {<1>} } set imexam(button) 0 set imexam(any) 0 } } } } proc ShiftButton1Frame {which x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "ShiftButton1Frame" } # let others know that the mouse is down set ds9(sb1) 1 switch -- $current(mode) { none {} pointer { if {$which == $current(frame)} { MarkerShift $which $x $y } UpdateMagnifier $which $x $y } catalog { if {$which == $current(frame)} { CATShift $which $x $y } UpdateMagnifier $which $x $y } crosshair {} colorbar {} pan {} zoom {ShiftZoom $which} rotate - crop { ButtonCrop3d $which $x $y 0 UpdateMagnifier $which $x $y } examine - imexam {} } } proc ControlButton1Frame {which x y} { global ds9 global current global imarker global debug if {$debug(tcl,events)} { puts stderr "ControlButton1Frame" } # let others know that the mouse is down set ds9(cb1) 1 switch -- $current(mode) { none {} pointer - catalog { if {$which == $current(frame)} { MarkerControl $which $x $y } else { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 } UpdateMagnifier $which $x $y } crosshair - colorbar - pan - zoom - rotate - crop { ButtonCrop3d $which $x $y 1 UpdateMagnifier $which $x $y } examine - imexam {} } } proc ControlShiftButton1Frame {which x y} { global ds9 global current global imarker global debug if {$debug(tcl,events)} { puts stderr "ControlShiftButton1Frame" } # let others know that the mouse is down set ds9(csb1) 1 switch -- $current(mode) { none {} pointer - catalog { if {$which == $current(frame)} { MarkerControlShift $which $x $y } else { # we need this cause MarkerMotion maybe called, # and we don't want it set imarker(motion) none set imarker(handle) -1 } UpdateMagnifier $which $x $y } crosshair - colorbar - pan - zoom - rotate - crop - examine - imexam {} } } proc Motion1Frame {which x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "Motion1Frame" } # abort if we are here by accident (such as a double click) if {($ds9(b1) == 0) && ($ds9(sb1) == 0) && ($ds9(cb1) == 0) && ($ds9(csb1) == 0)} { return } switch -- $current(mode) { none {UpdateMagnifier $which $x $y} pointer { if {$which == $current(frame)} { MarkerMotion $which $x $y } UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas UpdateMagnifier $which $x $y } catalog { if {$which == $current(frame)} { CATMotion $which $x $y } UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas UpdateMagnifier $which $x $y } crosshair { if {$ds9(b1)} { ButtonCrosshair $which $x $y UpdateColormapLevelMosaic $which $x $y canvas UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas UpdateMagnifier $which $x $y } } colorbar { if {$ds9(b1)} { Motion3Colorbar $x $y } } pan { if {$ds9(b1)} { MotionPan $which $x $y UpdateMagnifier $which $x $y } } zoom {UpdateMagnifier $which $x $y} rotate { if {$ds9(b1)} { MotionRotate $which $x $y } } crop { if {$ds9(b1)} { MotionCrop $which $x $y } if {$ds9(sb1)} { MotionCrop3d $which $x $y 0 } if {$ds9(cb1)} { MotionCrop3d $which $x $y 1 } UpdateMagnifier $which $x $y } examine {} imexam {} } } proc Release1Frame {which x y} { global ds9 global current global debug if {$debug(tcl,events)} { puts stderr "Release1Frame" } # abort if we are here by accident (such as a double click) if {($ds9(b1) == 0) && ($ds9(sb1) == 0) && ($ds9(cb1) == 0) && ($ds9(csb1) == 0)} { return } switch -- $current(mode) { none {} pointer { if {$which == $current(frame)} { MarkerRelease $which $x $y } } catalog { if {$which == $current(frame)} { CATRelease $which $x $y } } crosshair { if {$ds9(b1)} { ButtonCrosshair $which $x $y UpdateColormapLevelMosaic $which $x $y canvas UpdateInfoBox $which $x $y canvas UpdatePixelTableDialog $which $x $y canvas UpdateGraph $which $x $y canvas } } colorbar { if {$ds9(b1)} { Release3Colorbar $x $y } } pan { if {$ds9(b1)} { ReleasePan $which $x $y } } zoom {} rotate { if {$ds9(b1)} { ReleaseRotate $which $x $y } } crop { if {$ds9(b1)} { ReleaseCrop $which $x $y } if {$ds9(sb1)} { ReleaseCrop3d $which $x $y 0 } if {$ds9(cb1)} { ReleaseCrop3d $which $x $y 1 } } examine {} imexam {} } # let others know that the mouse is up set ds9(b1) 0 set ds9(sb1) 0 set ds9(cb1) 0 set ds9(csb1) 0 UpdateEditMenu UpdateMagnifier $which $x $y } proc Double1Frame {which x y} { global current global debug if {$debug(tcl,events)} { puts stderr "Double1Frame" } switch -- $current(mode) { pointer { if {$which == $current(frame)} { MarkerDouble $which $x $y UpdateMagnifier $which $x $y } } crop - none - catalog - crosshair - colorbar - pan - zoom - rotate - examine - imexam {} } } proc DoubleRelease1Frame {which x y} { global current global debug if {$debug(tcl,events)} { puts stderr "DoubleRelease1Frame" } switch -- $current(mode) { none - pointer - catalog - crosshair - colorbar - pan - zoom - rotate - crop - examine - imexam {} } UpdateEditMenu UpdateMagnifier $which $x $y } proc Button2Frame {which x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "Button2Frame" } set ds9(b2) 1 ButtonPan $which $x $y } proc ShiftButton2Frame {which x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "ShiftButton2Frame" } set ds9(sb2) 1 } proc Motion2Frame {which x y} { global debug if {$debug(tcl,events)} { puts stderr "Motion2Frame" } MotionPan $which $x $y } proc Release2Frame {which x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "Release2Frame" } ReleasePan $which $x $y # let others know that the mouse is up set ds9(b2) 0 set ds9(sb2) 0 } proc Button4Frame {which x y} { global ppanzoom global pbin global debug if {$debug(tcl,events)} { puts stderr "Button4Frame $which $x $y" } if {[$which has fits bin]} { if {$pbin(wheel)} { set zz $pbin(wheel,factor) BinFrame $which $zz $zz return } } if {$ppanzoom(wheel)} { set zz [expr 1./$ppanzoom(wheel,factor)] ZoomFrame $which $zz $zz } } proc Button5Frame {which x y} { global ppanzoom global pbin global debug if {$debug(tcl,events)} { puts stderr "Button5Frame $which $x $y" } if {[$which has fits bin]} { if {$pbin(wheel)} { set zz [expr 1./$pbin(wheel,factor)] BinFrame $which $zz $zz return } } if {$ppanzoom(wheel)} { set zz $ppanzoom(wheel,factor) ZoomFrame $which $zz $zz } } # used by aqua and win32 proc MouseWheelFrame {X Y dd} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "MouseWheel" } set id [$ds9(canvas) find closest $X $Y] set which [lindex [$ds9(canvas) gettags $id] 0] if {[string equal -length 5 {Frame} $which]} { set orig [$ds9(canvas) coords $which] set x [expr $X-int([lindex $orig 0])] set y [expr $Y-int([lindex $orig 1])] if {$dd>0} { Button5Frame $which $x $y } else { Button4Frame $which $x $y } } } proc KeyFrame {which K A x y} { global ds9 global current global imexam global debug if {$debug(tcl,events)} { puts stderr "KeyFrame $which $K $A $x $y" } if {$K == {Control_R} || $K == {Control_L} || $K == {Meta_R} || $K == {Meta_L} || $K == {Alt_R} || $K == {Alt_L} || $K == {Super_R} || $K == {Super_L}} { set ds9(modifier) 1 return } # modal bindings switch -- $current(mode) { none { switch -- $K { c { if {!$ds9(modifier)} { DisplayCoordDialog $which $x $y } } plus {CubeNext} minus {CubePrev} Up - k {$which warp 0 -1} Down - j {$which warp 0 1} Left - h {$which warp -1 0} Right - l {$which warp 1 0} } } pointer { switch -- $K { c { if {!$ds9(modifier)} { DisplayCoordDialog $which $x $y } } plus {CubeNext} minus {CubePrev} Delete - BackSpace {MarkerDeleteKey $which $x $y} Up - k {MarkerArrowKey $which 0 -1} Down - j {MarkerArrowKey $which 0 1} Left - h {MarkerArrowKey $which -1 0} Right - l {MarkerArrowKey $which 1 0} i {$which marker property include 1 $x $y} e {$which marker property include 0 $x $y} s {$which marker property source 1 $x $y} b {$which marker property source 0 $x $y} g {GroupCreate} G {GroupCreateSilent} } } catalog { switch -- $K { Up - k {MarkerArrowKey $which 0 -1} Down - j {MarkerArrowKey $which 0 1} Left - h {MarkerArrowKey $which -1 0} Right - l {MarkerArrowKey $which 1 0} } CATKey $which $K } crosshair { switch -- $K { c { if {!$ds9(modifier)} { DisplayCoordDialog $which $x $y } } plus {CubeNext} minus {CubePrev} Up - k {ArrowKeyCrosshair $which 0 -1} Down - j {ArrowKeyCrosshair $which 0 1} Left - h {ArrowKeyCrosshair $which -1 0} Right - l {ArrowKeyCrosshair $which 1 0} } } colorbar {} pan { switch -- $K { Up - k {Pan 0 1 canvas} Down - j {Pan 0 -1 canvas} Left - h {Pan 1 0 canvas} Right - l {Pan -1 0 canvas} } UpdateMagnifier $which $x $y } zoom {} rotate {} crop {} examine {} imexam { if {$imexam(key) || $imexam(any)} { set imexam(frame) $which set imexam(x) $x set imexam(y) $y set imexam(event) $K set imexam(key) 0 set imexam(any) 0 } } } UpdateEditMenu } proc KeyReleaseFrame {which K A x y} { global ds9 global debug if {$debug(tcl,events)} { puts stderr "KeyReleaseFrame $which $K $A $x $y" } if {$K == {Control_R} || $K == {Control_L} || $K == {Meta_R} || $K == {Meta_L} || $K == {Alt_R} || $K == {Alt_L} || $K == {Super_R} || $K == {Super_L}} { set ds9(modifier) 0 } } # Other Public Routines proc CopyFrame {} { global current switch -- $current(mode) { pointer {MarkerCopy} } } proc CutFrame {} { global current switch -- $current(mode) { pointer {MarkerCut} } } proc PasteFrame {} { global current switch -- $current(mode) { pointer {MarkerPaste} } } proc UndoFrame {} { global current switch -- $current(mode) { pointer {MarkerUndo} } } proc FirstFrame {} { global ds9 set ds9(next) [lindex $ds9(active) 0] GotoFrame } proc PrevFrame {} { global ds9 global current set ii [lsearch $ds9(active) $current(frame)] if {$ii>0} { set ds9(next) [lindex $ds9(active) [expr $ii-1]] } else { set ds9(next) [lindex $ds9(active) [expr $ds9(active,num)-1]] } GotoFrame } proc NextFrame {} { global ds9 global current set ii [lsearch $ds9(active) $current(frame)] if {$ii < [expr $ds9(active,num)-1]} { set ds9(next) [lindex $ds9(active) [expr $ii+1]] } else { set ds9(next) [lindex $ds9(active) 0] } GotoFrame } proc LastFrame {} { global ds9 set ds9(next) [lindex $ds9(active) [expr $ds9(active,num)-1]] GotoFrame } proc MoveFirstFrame {} { global ds9 global current set i [lsearch $ds9(frames) $current(frame)] set ds9(frames) [lreplace $ds9(frames) $i $i] set ds9(frames) [linsert $ds9(frames) 0 $current(frame)] UpdateFrameMenuItems UpdateActiveFrames } proc MovePrevFrame {} { global ds9 global current set i [lsearch $ds9(frames) $current(frame)] set ds9(frames) [lreplace $ds9(frames) $i $i] if {$i>0} { set ds9(frames) [linsert $ds9(frames) [expr $i-1] $current(frame)] } else { set ds9(frames) [linsert $ds9(frames) end $current(frame)] } UpdateFrameMenuItems UpdateActiveFrames } proc MoveNextFrame {} { global ds9 global current set i [lsearch $ds9(frames) $current(frame)] set ds9(frames) [lreplace $ds9(frames) $i $i] set last [llength $ds9(frames)] if {$i<$last} { set ds9(frames) [linsert $ds9(frames) [expr $i+1] $current(frame)] } else { set ds9(frames) [linsert $ds9(frames) 0 $current(frame)] } UpdateFrameMenuItems UpdateActiveFrames } proc MoveLastFrame {} { global ds9 global current set i [lsearch $ds9(frames) $current(frame)] set ds9(frames) [lreplace $ds9(frames) $i $i] set ds9(frames) [linsert $ds9(frames) end $current(frame)] UpdateFrameMenuItems UpdateActiveFrames } proc UpdateActiveFrames {} { global ds9 global active global current global debug if {$debug(tcl,update)} { puts stderr "UpdateActiveFrames" } # reset active list set ds9(active) {} set ds9(active,num) 0 foreach f $ds9(frames) { if {$active($f)} { lappend ds9(active) $f $ds9(mb).frame.goto entryconfig \ "[msgcat::mc {Frame}] [string range $f 5 end]" -state normal } else { $ds9(mb).frame.goto entryconfig \ "[msgcat::mc {Frame}] [string range $f 5 end]" -state disabled } } set ds9(active,num) [llength $ds9(active)] # New layout if needed if {$ds9(active,num) > 0} { if {[lsearch $ds9(active) $current(frame)] == -1} { if {$ds9(next) != {}} { set current(frame) $ds9(next) } else { set current(frame) [lindex $ds9(active) 0] set ds9(next) $current(frame) } } } DisplayMode } proc ActiveFrameAll {} { global ds9 global active foreach f $ds9(frames) { set active($f) 1 } UpdateActiveFrames } proc ActiveFrameNone {} { global ds9 global active foreach f $ds9(frames) { set active($f) 0 } UpdateActiveFrames } proc GotoFrame {} { global ds9 global current global active if {$current(frame) != {} && $current(frame) != $ds9(next)} { $current(frame) highlite off $current(frame) panner off switch -- $ds9(display) { blink - single { $current(frame) hide UnBindEventsFrame $current(frame) } tile {} } } if {$current(frame) != $ds9(next)} { if {$current(frame) != {}} { $current(frame) colorbar tag "\{[$current(colorbar) get tag]\}" } set current(frame) $ds9(next) set ds9(next) {} FrameToFront } } proc DisplayMode {} { global ds9 global current global tile global blink global iblink switch -- $current(display) { single {set ds9(display) $current(display)} tile { if {$ds9(active,num) > 1} { set ds9(display) $current(display) } else { switch -- $tile(grid,mode) { automatic {set ds9(display) single} manual {set ds9(display) $current(display)} } } } blink { if {$ds9(active,num) > 1} { set ds9(display) $current(display) } else { set ds9(display) single } } } switch -- $ds9(display) { single - tile { # turn off blink if on if {$iblink(id)>0} { after cancel $iblink(id) set iblink(id) 0 set iblink(index) -1 } LayoutFrames } blink { # ignore if we are already blinking if {$iblink(id)==0} { LayoutFrames BlinkTimer } } } } proc BlinkTimer {} { global blink global iblink global ds9 if {$ds9(active,num) > 0} { incr iblink(index) if {$iblink(index) >= $ds9(active,num)} { set iblink(index) 0 } set ds9(next) [lindex $ds9(active) $iblink(index)] GotoFrame } set iblink(id) [after $blink(interval) BlinkTimer] } proc ResetCurrentFrame {} { global current ResetFrame $current(frame) } proc ResetAllFrame {} { global ds9 foreach f $ds9(frames) { ResetFrame $f } } proc ResetFrame {which} { if {$which != {}} { if [$which has iis] { IISCursorModeCmd 0 } $which reset RefreshInfoBox $which PixelTableClearDialog ClearGraphData LockFrame $which UpdatePanZoomDialog UpdateCropDialog GridUpdateZoom UpdateZoomMenu UpdateScaleMenu UpdateScaleDialog UpdateGraphXAxis $which UpdateGraphYAxis $which SAMPSendCoordPointAtSkyCmd $which } } proc ClearCurrentFrame {} { global current ClearFrame $current(frame) ClearInfoBox PixelTableClearDialog ClearGraphData UpdateDS9 } proc ClearAllFrame {} { global ds9 foreach f $ds9(frames) { ClearFrame $f } ClearInfoBox PixelTableClearDialog ClearGraphData UpdateDS9 } proc ClearFrame {which} { if {$which == {}} { return } DestroyHeader $which $which clear # delete saved loadParams foreach cc {{} red green blue} { set varname $which$cc global $varname if [info exists $varname] { unset $varname } } } # Private Procedures proc FrameToFront {} { global ds9 global current global view global colorbar global blink set which $current(frame) # process proper colorbar switch -- $ds9(visual) { pseudocolor { if {$view(colorbar)} { colorbar show } else { colorbar hide } set current(colorbar) colorbar colorbar colorbar [$which get colorbar] colorbar tag "\{[$which get colorbar tag]\}" set colorbar(map) [colorbar get name] } truecolor { switch -- [$which get type] { base - 3d { if {$view(colorbar)} { colorbar show } else { colorbar hide } colorbarrgb hide set current(colorbar) colorbar colorbar colorbar [$which get colorbar] colorbar tag "\{[$which get colorbar tag]\}" set colorbar(map) [colorbar get name] $ds9(canvas) raise colorbar colorbarrgb } rgb { colorbar hide if {$view(colorbar)} { colorbarrgb show } else { colorbarrgb hide } set current(colorbar) colorbarrgb colorbarrgb colorbar [$which get colorbar] colorbarrgb rgb channel [$which get rgb channel] $ds9(canvas) raise colorbarrgb colorbar } } } } set colorbar(invert) [$current(colorbar) get invert] $ds9(canvas) raise $which $which show switch -- $ds9(display) { single - blink { if {!$ds9(freeze)} { BindEventsFrame $which } } tile {$which highlite on} } if {$view(panner)} { $which panner on } UpdateDS9 } proc TileDialog {} { global tile global itile global dtile global ds9 # see if we already have a window visible if [winfo exists $itile(top)] { raise $itile(top) return } # create window set w $itile(top) set mb $itile(mb) Toplevel $w $mb 6 [msgcat::mc {Tile Parameters}] TileDestroyDialog set dtile(mode) $tile(grid,mode) set dtile(row) $tile(grid,row) set dtile(col) $tile(grid,col) set dtile(gap) $tile(grid,gap) $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command TileApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command TileDestroyDialog EditMenu $mb itile # Grid set f [ttk::labelframe $w.grid -text [msgcat::mc {Grid}] -padding 2] ttk::radiobutton $f.auto -text [msgcat::mc {Automatic}] \ -variable dtile(mode) -value automatic ttk::radiobutton $f.manual -text [msgcat::mc {Manual}] \ -variable dtile(mode) -value manual grid $f.auto $f.manual -padx 2 -pady 2 -sticky w # Layout set f [ttk::labelframe $w.layout -text [msgcat::mc {Layout}] -padding 2] ttk::label $f.tcol -text [msgcat::mc {Columns}] ttk::label $f.trow -text [msgcat::mc {Rows}] ttk::entry $f.col -textvariable dtile(col) -width 6 ttk::label $f.tx -text {x} ttk::entry $f.row -textvariable dtile(row) -width 6 grid $f.tcol x $f.trow -padx 2 -pady 2 -sticky w grid $f.col $f.tx $f.row -padx 2 -pady 2 -sticky w # Gap set f [ttk::labelframe $w.gap -text [msgcat::mc {Gap}] -padding 2] ttk::entry $f.gap -textvariable dtile(gap) -width 6 ttk::label $f.ugap -text [msgcat::mc {Pixels}] grid $f.gap - $f.ugap -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command TileApplyDialog ttk::button $f.close -text [msgcat::mc {Close}] -command TileDestroyDialog pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 # Fini grid $w.grid -sticky news grid $w.layout -sticky news grid $w.gap -sticky news grid $w.buttons -sticky ew grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 1 -weight 1 grid rowconfigure $w 2 -weight 1 grid columnconfigure $w 0 -weight 1 } proc TileDestroyDialog {} { global itile global dtile if {[winfo exists $itile(top)]} { destroy $itile(top) destroy $itile(mb) } unset dtile } proc TileApplyDialog {} { global tile global dtile set tile(mode) grid set tile(grid,mode) $dtile(mode) set tile(grid,row) $dtile(row) set tile(grid,col) $dtile(col) set tile(grid,gap) $dtile(gap) DisplayMode } # Process Cmds proc ProcessFrameCmd {varname iname} { upvar $varname var upvar $iname i global current global active global panzoom catch { switch -- [string tolower [lindex $var $i]] { match { incr i MatchFrameCurrent [lindex $var $i] } lock { incr i set panzoom(lock) [lindex $var $i] LockFrameCurrent } center { incr i switch -- [lindex $var $i] { all {CenterAllFrame} {} {CenterCurrentFrame; incr i -1} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" CenterFrame $f } else { CenterCurrentFrame; incr i -1 } } } } clear { incr i switch -- [lindex $var $i] { all {ClearAllFrame} {} {ClearCurrentFrame; incr i -1} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" ClearFrame $f } else { ClearCurrentFrame; incr i -1 } } } } delete { incr i switch -- [lindex $var $i] { all {DeleteAllFrames} {} {DeleteCurrentFrame; incr i -1} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" DeleteSingleFrame $f } else { DeleteCurrentFrame; incr i -1 } } } } new { incr i switch -- [lindex $var $i] { rgb {CreateRGBFrame} 3d {Create3DFrame} default {CreateFrame; incr i -1} } } reset { incr i switch -- [lindex $var $i] { all {ResetAllFrame} {} {ResetCurrentFrame; incr i -1} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" ResetFrame $f } else { ResetCurrentFrame; incr i -1 } } } } refresh { incr i switch -- [lindex $var $i] { all {UpdateAllFrame} {} {UpdateCurrentFrame; incr i -1} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" UpdateFrame $f } else { UpdateCurrentFrame; incr i -1 } } } } hide { incr i switch -- [lindex $var $i] { all {ActiveFrameNone} {} { set active($current(frame)) 0 UpdateActiveFrames incr i -1 } default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" set active($f) 0 UpdateActiveFrames } else { set active($current(frame)) 0 UpdateActiveFrames incr i -1 } } } } show { incr i switch -- [lindex $var $i] { all {ActiveFrameAll} default { if [string is integer [lindex $var $i]] { set f "Frame[lindex $var $i]" set active($f) 1 UpdateActiveFrames } else { incr i -1 } } } } move { incr i switch -- [lindex $var $i] { first {MoveFirstFrame} back {MovePrevFrame} forward {MoveNextFrame} last {MoveLastFrame} } } first {FirstFrame} prev {PrevFrame} next {NextFrame} last {LastFrame} frameno {incr i; CreateGotoFrame [lindex $var $i] base} default {CreateGotoFrame [lindex $var $i] base} } } } proc ProcessSendFrameCmd {proc id param} { global ds9 global current global rgb global panzoom switch -- [lindex $param 0] { lock {$proc $id "$panzoom(lock)\n"} active { set r {} foreach f $ds9(active) { append r "[string range $f 5 end] " } $proc $id "$r\n" } all { set r {} foreach f $ds9(frames) { append r "[string range $f 5 end] " } $proc $id "$r\n" } has { if {$current(frame) == {}} { Error [msgcat::mc {No current frame}] return } switch [lindex $param 1] { amplifier - datamin - datasec - detector - grid - iis - irafmin - physical - smooth {$proc $id [ToYesNo [$current(frame) has [lindex $param 1]]]} contour { switch [lindex $param 2] { aux {$proc $id [ToYesNo [$current(frame) has contour aux]]} default {$proc $id [ToYesNo [$current(frame) has contour]]} } } fits { switch [lindex $param 2] { bin - cube - mosaic {$proc $id [ToYesNo [$current(frame) has fits [lindex $param 2]]]} default {$proc $id [ToYesNo [$current(frame) has fits]]} } } marker { switch [lindex $param 2] { highlite - paste - select - undo {$proc $id [ToYesNo [$current(frame) has marker [lindex $param 2]]]} } } system {$proc $id [ToYesNo [$current(frame) has system [lindex $param 2]]]} wcs { switch [lindex $param 2] { equatorial - linear {$proc $id [ToYesNo [$current(frame) has wcs [lindex $param 2] [lindex $param 3]]]} default {$proc $id [ToYesNo [$current(frame) has wcs [lindex $param 2]]]} } } } } default {$proc $id "[string range $current(frame) 5 end]\n"} } } proc ProcessSingleCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 global current set current(display) single DisplayMode } proc ProcessSendSingleCmd {proc id param} { global current if {$current(display) == "single"} { $proc $id [ToYesNo 1] } else { $proc $id [ToYesNo 0] } } proc ProcessTileCmd {varname iname} { upvar $varname var upvar $iname i global current global tile switch -- [string tolower [lindex $var $i]] { mode { incr i set tile(mode) [lindex $var $i] } grid { incr i switch -- [string tolower [lindex $var $i]] { mode { incr i set tile(grid,mode) [lindex $var $i] } layout { incr i set tile(grid,col) [lindex $var $i] incr i set tile(grid,row) [lindex $var $i] set tile(grid,mode) {manual} } gap { incr i set tile(grid,gap) [lindex $var $i] } default { if {[string range [lindex $var $i] 0 0] != {-}} { set tile(mode) grid } else { incr i -1 } } } } column { set tile(mode) column } row { set tile(mode) row } yes - true - on - 1 - no - false - off - 0 { if {[FromYesNo [lindex $var $i]]} { set current(display) tile } else { set current(display) single } } default { set current(display) tile incr i -1 } } DisplayMode } proc ProcessSendTileCmd {proc id param} { global current global tile switch -- [lindex $param 0] { mode {$proc $id "$tile(mode)\n"} grid { switch -- [lindex $param 1] { mode {$proc $id "$tile(grid,mode)\n"} layout {$proc $id "$tile(grid,col) $tile(grid,row)\n"} gap {$proc $id "$tile(grid,gap)\n"} } } default { if {$current(display)=="tile"} { $proc $id [ToYesNo 1] } else { $proc $id [ToYesNo 0] } } } } proc ProcessBlinkCmd {varname iname} { upvar $varname var upvar $iname i global current global blink switch -- [string tolower [lindex $var $i]] { interval { incr i set blink(interval) [expr int([lindex $var $i]*1000)] } yes - true - on - 1 - no - false - off - 0 { if {[FromYesNo [lindex $var $i]]} { set current(display) blink } else { set current(display) single } } default { set current(display) blink incr i -1 } } DisplayMode } proc ProcessSendBlinkCmd {proc id param} { global current global blink switch -- [lindex $param 0] { interval {$proc $id "[expr $blink(interval)/1000.]\n"} default { if {$current(display) == {blink}} { $proc $id [ToYesNo 1] } else { $proc $id [ToYesNo 0] } } } } proc ProcessLockCmd {varname iname} { upvar $varname var upvar $iname i global panzoom global crop global crosshair global cube global bin global scale global colorbar global smooth # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { frame - frames { incr i set panzoom(lock) [lindex $var $i] LockFrameCurrent } crosshair - crosshairs { incr i set crosshair(lock) [lindex $var $i] LockCrosshairCurrent } crop { incr i set crop(lock) [lindex $var $i] LockCropCurrent } slice - cube - datacube { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set cube(lock) [FromYesNo [lindex $var $i]] } else { set cube(lock) 1 incr i -1 } LockCubeCurrent } bin { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set bin(lock) [FromYesNo [lindex $var $i]] } else { set bin(lock) 1 incr i -1 } LockBinCurrent } scale - scales { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set scale(lock) [FromYesNo [lindex $var $i]] } else { set scale(lock) 1 incr i -1 } LockScaleCurrent } color - colormap - colorbar - colorbars { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set colorbar(lock) [FromYesNo [lindex $var $i]] } else { set colorbar(lock) 1 incr i -1 } LockColorCurrent } smooth { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set smooth(lock) [FromYesNo [lindex $var $i]] } else { set smooth(lock) 1 incr i -1 } LockSmoothCurrent } } } proc ProcessSendLockCmd {proc id param} { global panzoom global crop global crosshair global cube global bin global scale global colorbar global smooth switch -- [lindex $param 0] { frame - frames {$proc $id "$panzoom(lock)\n"} crosshair - crosshairs {$proc $id "$crosshair(lock)\n"} crop {$proc $id "$crop(lock)\n"} slice - cube - datacube {$proc $id [ToYesNo $cube(lock)]} bin {$proc $id [ToYesNo $bin(lock)]} scale - scales {$proc $id [ToYesNo $scale(lock)]} color - colormap - colorbar - colorbars {$proc $id [ToYesNo $colorbar(lock)]} smooth {$proc $id [ToYesNo $smooth(lock)]} } } proc ProcessMatchCmd {varname iname} { upvar $varname var upvar $iname i global current # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { frame - frames { incr i MatchFrameCurrent [lindex $var $i] } crosshair - crosshairs { incr i MatchCrosshairCurrent [lindex $var $i] } crop { incr i MatchCropCurrent [lindex $var $i] } slice - cube - datacube {MatchCubeCurrent} bin {MatchBinCurrent} scale - scales {MatchScaleCurrent} color - colormap - colorbar - colorbars {MatchColorCurrent} smooth {MatchSmoothCurrent} } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerdialog.tcl�����������������������������������������������������������������������0000644�0001750�0001750�00000020422�11700665570�015046� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerLoadDialog {} { global marker global ed global current global wcs set w {.mkd} set ed(ok) 0 set ed(format) $marker(format) set ed(load) $marker(load) set ed(frame) $current(frame) set ed(system) $wcs(system) set ed(sky) $wcs(sky) set ed(skyformat) $wcs(skyformat) AdjustCoordSystem ed system DialogCreate $w [msgcat::mc {Load Regions}] ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.formattitle -text [msgcat::mc {Format}] set m $f.formatbutton.menu ttk::menubutton $f.formatbutton -textvariable ed(format) -menu $m ttk::label $f.coordtitle -text [msgcat::mc {Coordinate System}] set ed(cb) $f.coordbutton CoordMenuButton $ed(cb) ed system 1 sky skyformat {} ttk::radiobutton $f.current -text [msgcat::mc {Load into Current Frame}] \ -variable ed(load) -value current ttk::radiobutton $f.all -text [msgcat::mc {Load into All Frames}] \ -variable ed(load) -value all menu $m $m add radiobutton -label {DS9/Funtools} -variable ed(format) -value ds9 \ -command UpdateMarkerLoadDialog $m add radiobutton -label {XML} -variable ed(format) -value xml \ -command UpdateMarkerLoadDialog $m add radiobutton -label {CIAO} -variable ed(format) -value ciao \ -command UpdateMarkerLoadDialog $m add radiobutton -label {SAOtng} -variable ed(format) -value saotng \ -command UpdateMarkerLoadDialog $m add radiobutton -label {SAOimage} -variable ed(format) -value saoimage \ -command UpdateMarkerLoadDialog $m add radiobutton -label {IRAF PROS} -variable ed(format) -value pros \ -command UpdateMarkerLoadDialog $m add radiobutton -label {X Y} -variable ed(format) -value xy \ -command UpdateMarkerLoadDialog grid $f.formattitle $f.formatbutton -padx 2 -pady 2 -sticky w grid $f.coordtitle $f.coordbutton -padx 2 -pady 2 -sticky w grid $f.current - -padx 2 -pady 2 -sticky w grid $f.all - -padx 2 -pady 2 -sticky w # Button set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true UpdateMarkerLoadDialog DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set marker(format) $ed(format) set marker(system) $ed(system) set marker(sky) $ed(sky) set marker(skyformat) $ed(skyformat) set marker(load) $ed(load) } set rr $ed(ok) unset ed return $rr } proc UpdateMarkerLoadDialog {} { global ed global current set mm $ed(cb).menu set ed(frame) $current(frame) CoordMenuEnable $mm ed system 1 sky skyformat switch -- $ed(format) { xy {$ed(cb) configure -state normal} default {$ed(cb) configure -state disabled} } AdjustCoordSystem ed system CoordMenuButtonCmd ed system sky {} } proc MarkerSaveDialog {title} { global marker global ed global current global wcs set w {.mkd} set ed(ok) 0 set ed(format) $marker(format) set ed(frame) $current(frame) set ed(system) $wcs(system) set ed(sky) $wcs(sky) set ed(skyformat) $wcs(skyformat) AdjustCoordSystem ed system DialogCreate $w $title ed(ok) # Param set f [ttk::frame $w.param] ttk::label $f.formattitle -text [msgcat::mc {Format}] set m $f.formatbutton.menu ttk::menubutton $f.formatbutton -textvariable ed(format) -menu $m ttk::label $f.coordtitle -text [msgcat::mc {Coordinate System}] set ed(cb) $f.coordbutton CoordMenuButton $ed(cb) ed system 1 sky skyformat UpdateMarkerSaveDialog menu $m $m add radiobutton -label {DS9/Funtools} -variable ed(format) -value ds9 \ -command UpdateMarkerSaveDialog $m add radiobutton -label {XML} -variable ed(format) -value xml \ -command UpdateMarkerSaveDialog $m add radiobutton -label {CIAO} -variable ed(format) -value ciao \ -command UpdateMarkerSaveDialog $m add radiobutton -label {SAOtng} -variable ed(format) -value saotng \ -command UpdateMarkerSaveDialog $m add radiobutton -label {SAOimage} -variable ed(format) -value saoimage \ -command UpdateMarkerSaveDialog $m add radiobutton -label {IRAF PROS} -variable ed(format) -value pros \ -command UpdateMarkerSaveDialog $m add radiobutton -label {X Y} -variable ed(format) -value xy \ -command UpdateMarkerSaveDialog grid $f.formattitle $f.formatbutton -padx 2 -pady 2 -sticky w grid $f.coordtitle $f.coordbutton -padx 2 -pady 2 -sticky w # Button set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true UpdateMarkerSaveDialog DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { set marker(format) $ed(format) set marker(system) $ed(system) set marker(sky) $ed(sky) set marker(skyformat) $ed(skyformat) } set rr $ed(ok) unset ed return $rr } proc UpdateMarkerSaveDialog {} { global ed global current set mm $ed(cb).menu set ed(frame) $current(frame) CoordMenuEnable $mm ed system 1 sky skyformat switch -- $ed(format) { ds9 - xml - xy {} ciao { switch -- $ed(system) { detector - amplifier - physical - image {set ed(system) physical} wcs - default {set ed(system) wcs} } set ed(sky) fk5 set ed(skyformat) sexagesimal $mm entryconfig [msgcat::mc {Multiple WCS}] -state disabled $mm entryconfig [msgcat::mc {Image}] -state disabled $mm entryconfig [msgcat::mc {Amplifier}] -state disabled $mm entryconfig [msgcat::mc {Detector}] -state disabled $mm entryconfig [msgcat::mc {FK4}] -state disabled $mm entryconfig [msgcat::mc {ICRS}] -state disabled $mm entryconfig [msgcat::mc {Galactic}] -state disabled $mm entryconfig [msgcat::mc {Ecliptic}] -state disabled $mm entryconfig [msgcat::mc {Degrees}] -state disabled } saotng { switch -- $ed(system) { detector - amplifier - image - physical {set ed(system) image} wcs - default {set ed(system) wcs} } $mm entryconfig [msgcat::mc {Multiple WCS}] -state disabled $mm entryconfig [msgcat::mc {Physical}] -state disabled $mm entryconfig [msgcat::mc {Amplifier}] -state disabled $mm entryconfig [msgcat::mc {Detector}] -state disabled } saoimage { set ed(system) image $mm entryconfig [msgcat::mc {WCS}] -state disabled $mm entryconfig [msgcat::mc {Multiple WCS}] -state disabled $mm entryconfig [msgcat::mc {Physical}] -state disabled $mm entryconfig [msgcat::mc {Amplifier}] -state disabled $mm entryconfig [msgcat::mc {Detector}] -state disabled $mm entryconfig [msgcat::mc {FK4}] -state disabled $mm entryconfig [msgcat::mc {FK5}] -state disabled $mm entryconfig [msgcat::mc {ICRS}] -state disabled $mm entryconfig [msgcat::mc {Galactic}] -state disabled $mm entryconfig [msgcat::mc {Ecliptic}] -state disabled $mm entryconfig [msgcat::mc {Degrees}] -state disabled $mm entryconfig {Sexagesimal} -state disabled } pros { switch -- $ed(system) { detector - physical - amplifier {set ed(system) physical} image {} wcs - default {set ed(system) wcs} } if {$ed(sky) == {icrs}} { set ed(sky) fk5 } $mm entryconfig [msgcat::mc {Multiple WCS}] -state disabled $mm entryconfig [msgcat::mc {Amplifier}] -state disabled $mm entryconfig [msgcat::mc {Detector}] -state disabled $mm entryconfig [msgcat::mc {ICRS}] -state disabled } } AdjustCoordSystem ed system CoordMenuButtonCmd ed system sky {} } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/header.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000006122�11756761313�013641� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc DisplayHeaderMenu {} { global current set last {} set prim {} set cnt [$current(frame) get fits count] if {$cnt > 0} { set slb(count) 0 for {set ii 1} {$ii <= $cnt} {incr ii} { set fn [$current(frame) get fits file name $ii] set xten [string trim [$current(frame) get fits header $ii keyword {XTENSION}]] if {$xten != {}} { set b [string first {[} $fn] set pn [string range $fn 0 [expr $b-1]] if {$b > 0 && $pn != $prim} { incr slb(count) set slb($slb(count),item) $pn set slb($slb(count),value) "-$ii" set prim $pn } } if {$fn != $last && $fn != $prim} { incr slb(count) set slb($slb(count),item) $fn set slb($slb(count),value) $ii set last $fn } } if {$slb(count) == 1} { DisplayHeader $current(frame) 1 $fn } else { if [SLBDialog slb {Select Header} 40] { DisplayHeader $current(frame) $slb(value) $slb(item) } } } } proc DisplayHeader {frame which title} { global current set varname "hd[string range $frame end end]-$which" upvar #0 $varname var global $varname SimpleTextDialog $varname $title 80 40 insert top \ [$current(frame) get fits header $which] # create a special text tag for keywords $var(text) tag configure keyword -foreground blue # color tag keywords set stop [$var(text) index end] for {set ii 1.0} {$ii<$stop} {set ii [expr $ii+1]} { $var(text) tag add keyword $ii "$ii +8 chars" } } proc DestroyHeader {frame} { global st set ttt "hd[string range $frame end end]" foreach x [array names st] { set f [split $x ,] if {[lindex $f 1] == "top"} { set varname [lindex $f 0] upvar #0 $varname var global $varname set fff [split $tt :] if {[lindex $fff 0] == $ttt} { if {[info exists $varname] && [winfo exists ${varname}(top)]} { SimpleTextDestroy $varname } } } } } proc ProcessHeaderCmd {varname iname} { upvar $varname var upvar $iname i set item [string tolower [lindex $var $i]] switch -- $item { close - save {incr i} } if {[lindex $var $i] != {} && [string is integer [lindex $var $i]]} { set jj [lindex $var $i] incr i } else { set jj 1 } global current if {$current(frame) != {}} { switch -- $item { close { set vvarname "hd[string range $current(frame) end end]-$jj" upvar #0 $vvarname vvar global $vvarname if {[info exists vvar(top)]} { SimpleTextDestroy $vvarname } incr i -1 } save { set fn [lindex $var $i] if {$fn != {}} { if {[catch {set ch [open "| cat > \"$fn\"" w]}]} { Error [msgcat::mc {An error has occurred while saving}] return } puts -nonewline $ch [$current(frame) get fits header $jj] close $ch } } default { catch {DisplayHeader $current(frame) $jj \ [$current(frame) get fits file name $jj]} incr i -1 } } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/debug.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000015357�11704100267�013475� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc DebugDef {} { global debug set debug(tcl,events) 0 set debug(tcl,update) 0 set debug(tcl,idletasks) 0 set debug(tcl,layout) 0 set debug(tcl,info) 0 set debug(tcl,marker) 0 set debug(tcl,watch) 0 set debug(tcl,hv) 0 set debug(tcl,cat) 0 set debug(tcl,samp) 0 set debug(tcl,grid) 0 set debug(tcl,restore) 0 set debug(tcl,http) 0 set debug(tcl,ftp) 0 set debug(tcl,xpa) 0 set debug(tcl,image) 0 set debug(saotk,ast) 0 set debug(saotk,mosaic) 0 set debug(saotk,parser) 0 set debug(saotk,perf) 0 set debug(saotk,wcs) 0 set debug(saotk,bin) 0 set debug(saotk,compress) 0 set debug(saotk,gz) 0 set debug(saotk,rgb) 0 set debug(saotk,crop) 0 set debug(iis) 0 } proc Debug {which varname} { upvar $varname var global current if {$current(frame) != {}} { $current(frame) debug $which $var } } proc DebugMenu {} { global ds9 global debug if {[winfo exists $ds9(mb).debug]} { return } $ds9(mb) add cascade -label {Debug} -menu $ds9(mb).debug menu $ds9(mb).debug $ds9(mb).debug add cascade -label {Tcl} -menu $ds9(mb).debug.tcl $ds9(mb).debug add cascade -label {SAOTk} -menu $ds9(mb).debug.saotk $ds9(mb).debug add cascade -label {IIS} -menu $ds9(mb).debug.iis menu $ds9(mb).debug.tcl $ds9(mb).debug.tcl add checkbutton -label {Events} \ -variable debug(tcl,events) $ds9(mb).debug.tcl add checkbutton -label {Update} \ -variable debug(tcl,update) $ds9(mb).debug.tcl add checkbutton -label {Idletasks} \ -variable debug(tcl,idletasks) $ds9(mb).debug.tcl add checkbutton -label {Layout} \ -variable debug(tcl,layout) $ds9(mb).debug.tcl add checkbutton -label {Info} \ -variable debug(tcl,info) $ds9(mb).debug.tcl add checkbutton -label {Marker} \ -variable debug(tcl,marker) $ds9(mb).debug.tcl add checkbutton -label {Watch} \ -variable debug(tcl,watch) $ds9(mb).debug.tcl add checkbutton -label {HV} \ -variable debug(tcl,hv) $ds9(mb).debug.tcl add checkbutton -label {Catalog} \ -variable debug(tcl,cat) $ds9(mb).debug.tcl add checkbutton -label {SAMP} \ -variable debug(tcl,samp) $ds9(mb).debug.tcl add checkbutton -label {Grid} \ -variable debug(tcl,grid) $ds9(mb).debug.tcl add checkbutton -label {Restore} \ -variable debug(tcl,restore) $ds9(mb).debug.tcl add checkbutton -label {HTTP} \ -variable debug(tcl,http) $ds9(mb).debug.tcl add checkbutton -label {FTP} \ -variable debug(tcl,ftp) $ds9(mb).debug.tcl add checkbutton -label {XPA} \ -variable debug(tcl,xpa) $ds9(mb).debug.tcl add checkbutton -label {IMAGE} \ -variable debug(tcl,image) menu $ds9(mb).debug.saotk $ds9(mb).debug.saotk add checkbutton -label {AST} \ -variable debug(saotk,ast) \ -command "Debug ast debug(saotk,ast)" $ds9(mb).debug.saotk add checkbutton -label {Mosaic} \ -variable debug(saotk,mosaic) \ -command "Debug mosaic debug(saotk,mosaic)" $ds9(mb).debug.saotk add checkbutton -label {Parser} \ -variable debug(saotk,parser) \ -command "Debug parser debug(saotk,parser)" $ds9(mb).debug.saotk add checkbutton -label {Perf} \ -variable debug(saotk,perf) \ -command "Debug perf debug(saotk,perf)" $ds9(mb).debug.saotk add checkbutton -label {WCS} \ -variable debug(saotk,wcs) \ -command "Debug wcs debug(saotk,wcs)" $ds9(mb).debug.saotk add checkbutton -label {Bin} \ -variable debug(saotk,bin) \ -command "Debug bin debug(saotk,bin)" $ds9(mb).debug.saotk add checkbutton -label {Compress} \ -variable debug(saotk,compress) \ -command "Debug compress debug(saotk,compress)" $ds9(mb).debug.saotk add checkbutton -label {GZ} \ -variable debug(saotk,gz) \ -command "Debug gz debug(saotk,gz)" $ds9(mb).debug.saotk add checkbutton -label {RGB} \ -variable debug(saotk,rgb) \ -command "Debug rgb debug(saotk,rgb)" $ds9(mb).debug.saotk add checkbutton -label {Crop} \ -variable debug(saotk,crop) \ -command "Debug crop debug(saotk,crop)" menu $ds9(mb).debug.iis $ds9(mb).debug.iis add checkbutton -label {IIS} \ -variable debug(iis) -command IISDebug } proc DumpURL {varname} { upvar $varname r puts stderr "r(scheme)=$r(scheme)" puts stderr "r(authority)=$r(authority)" puts stderr "r(path)=$r(path)" puts stderr "r(query)=$r(query)" puts stderr "r(fragment)=$r(fragment)" } proc DumpCallStack {} { for {set x [expr [info level]-1]} {$x>0} {incr x -1} { puts stderr "$x: [info level $x]" } } proc DumpArray {varname} { upvar $varname var global $varname foreach f [array names $varname] { puts stderr "${varname}($f) = $var($f)" } } # Process Cmds proc ProcessDebugTclCmd {varname iname} { upvar $varname var upvar $iname i # default debug dialog if {[info proc bgerror] != {}} { rename bgerror {} } global debug switch -- [string tolower [lindex $var $i]] { events {set debug(tcl,events) 1} update {set debug(tcl,update) 1} idletasks {set debug(tcl,idletasks) 1} layout {set debug(tcl,layout) 1} info {set debug(tcl,info) 1} marker {set debug(tcl,marker) 1} watch {set debug(tcl,watch) 1} hv {set debug(tcl,hv) 1} cat {set debug(tcl,cat) 1} samp {set debug(tcl,samp) 1} grid {set debug(tcl,grid) 1} restore {set debug(tcl,restore) 1} http {set debug(tcl,http) 1} ftp {set debug(tcl,ftp) 1} xpa {set debug(tcl,xpa) 1} image { set debug(tcl,hv) 1 set debug(tcl,http) 1 set debug(tcl,image) 1 } } } proc ProcessDebugCmd {varname iname} { upvar $varname var upvar $iname i DebugMenu global debug switch -- [string tolower [lindex $var $i]] { ast { set debug(saotk,ast) 1 Debug ast debug(saotk,ast) } mosaic { set debug(saotk,mosaic) 1 Debug mosaic debug(saotk,mosaic) } parser { set debug(saotk,parser) 1 Debug parser debug(saotk,parser) } perf { set debug(saotk,perf) 1 Debug perf debug(saotk,perf) } wcs { set debug(saotk,wcs) 1 Debug wcs debug(saotk,wcs) } bin { set debug(saotk,bin) 1 Debug bin debug(saotk,bin) } compress { set debug(saotk,compress) 1 Debug compress debug(saotk,compress) } gz { set debug(saotk,gz) 1 Debug gz debug(saotk,gz) } iis { set debug(iis) 1 IISDebug } rgb { set debug(saotk,rgb) 1 Debug rgb debug(saotk,rgb) } crop { set debug(saotk,crop) 1 Debug crop debug(saotk,crop) } events - update - idletasks - layout - info - marker - watch - hv - cat - samp - grid - restore - http - ftp - xpa - image {} default { incr ${iname} -1 } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/saveimage.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000011236�12132024702�014333� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SaveImageDef {} { global saveimage set saveimage(jpeg,quality) 75 set saveimage(tiff,compress) none global tcl_platform set aa [msgcat::mc {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.}] set bb [msgcat::mc {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.}] switch $tcl_platform(os) { Darwin { switch [lindex [split $tcl_platform(osVersion) {.}] 0] { 10 - 11 {set saveimage(error) $bb} 8 - 9 - default {set saveimage(error) $aa} } } default {set saveimage(error) $aa} } } proc SaveImageDialog {format} { global saveimage global fitsfbox global epsfbox global giffbox global jpegfbox global tifffbox global pngfbox switch -- $format { fits {set fn [SaveFileDialog fitsfbox]} eps {set fn [SaveFileDialog epsfbox]} gif {set fn [SaveFileDialog giffbox]} jpeg {set fn [SaveFileDialog jpegfbox]} tiff {set fn [SaveFileDialog tifffbox]} png {set fn [SaveFileDialog pngfbox]} } if {$fn != {}} { set ok 1 switch -- $format { fits - eps - gif - png {} jpeg {set ok [JPEGExportDialog saveimage(jpeg,quality)]} tiff {set ok [TIFFExportDialog saveimage(tiff,compress)]} } if {$ok} { SaveImage $fn $format } } } proc SaveImage {fn format} { global ds9 global current global saveimage global cube if {$fn == {} || ![$current(frame) has fits]} { return } # besure we are on top raise $ds9(top) # and no highlite $current(frame) highlite off # and refresh screen RealizeDS9 switch -- $format { fits {$current(frame) save fits resample file "\{$fn\}"} eps {EPS $fn} gif - tiff - jpeg - png {SaveImagePhoto $fn $format} } # reset switch -- $ds9(display) { single - blink {} tile {$current(frame) highlite on} } # and refresh screen RealizeDS9 } # Support proc SaveImagePhoto {fn format} { global ds9 global saveimage set rr [catch {image create photo -format window -data $ds9(canvas)} ph] if {$rr != 0} { Error $saveimage(error) return $rr } switch -- $format { gif - png {$ph write $fn -format $format} jpeg {$ph write $fn \ -format [list $format -quality $saveimage(jpeg,quality)]} tiff {$ph write $fn \ -format [list $format -compression $saveimage(tiff,compress)]} } image delete $ph return 0 } # Process Cmds proc ProcessSaveImageCmd {varname iname} { upvar $varname var upvar $iname i # we need to be realized ProcessRealizeDS9 set format {} set param {} set fn [lindex $var $i] if {$fn == {}} { return } # backward compatibility switch $fn { fits - eps - gif - tiff - jpeg - png { set format $fn set fn {} incr i } jpg { set format jpeg set fn {} incr i } tif { set format tiff set fn {} incr i } mpeg { # backward compatibility global movie incr i set fn [lindex $var $i] if {[string is integer -strict $fn]} { incr i set fn [lindex $var $i] } set movie(action) slice Movie $fn } } # try again if {$fn == {}} { set fn [lindex $var $i] if {$fn == {}} { return } if {[string is integer -strict $fn] || $fn == {none} || $fn == {jpeg} || $fn == {backbits} || $fn == {deflate}} { set param $fn set fn {} incr i } } # one last time if {$fn == {}} { set fn [lindex $var $i] if {$fn == {}} { return } } global saveimage if {$format == {}} { set format [ExtToFormat $fn] } if {$param == {}} { set param [string tolower [lindex $var [expr $i+1]]] switch $format { fits - eps - gif - png {} jpeg { if {[string is integer -strict $param]} { set saveimage(jpeg,quality) $param incr i } } tiff { switch $param { none - jpeg - packbits - deflate { set saveimage(tiff,compress) $param incr i } } } } } global fitsfbox global epsfbox global giffbox global jpegfbox global tifffbox global pngfbox switch -- $format { fits {FileLast fitsfbox $fn} eps {FileLast epsfbox $fn} gif {FileLast giffbox $fn} jpeg {FileLast jpegfbox $fn} tiff {FileLast tifffbox $fn} png {FileLast pngfbox $fn} } SaveImage $fn $format } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/ellipse.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000006211�12007016100�014016� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc EllipseDialog {varname} { upvar #0 $varname var global $varname global pmarker # see if we already have a header window visible if [winfo exists $var(top)] { raise $var(top) return } # variables set rr [$var(frame) get wcs] set var(dcoord) [lindex $rr 0] set var(dformat) $pmarker(dformat) AdjustCoordSystem $varname dcoord # procs set var(proc,apply) EllipseApply set var(proc,close) EllipseClose set var(proc,coordCB) EllipseCoordCB # base MarkerBaseCenterDialog $varname # analysis $var(mb) add cascade -label [msgcat::mc {Analysis}] -menu $var(mb).analysis menu $var(mb).analysis MarkerAnalysisStatsDialog $varname MarkerAnalysisPlot3dDialog $varname # init EllipseEditCB $varname MarkerBaseCenterRotateCB $varname # callbacks $var(frame) marker $var(id) callback edit EllipseEditCB $varname $var(frame) marker $var(id) callback rotate \ MarkerBaseCenterRotateCB $varname set f $var(top).param # Radius ttk::label $f.tradius -text Radius ttk::entry $f.radius1 -textvariable ${varname}(radius1) -width 13 ttk::entry $f.radius2 -textvariable ${varname}(radius2) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list EllipseEditCB $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid $f.tradius $f.radius1 $f.radius2 $f.uradius -padx 2 -pady 2 -sticky w grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w } # actions proc EllipseClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback edit EllipseEditCB $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBaseCenterClose $varname } proc EllipseApply {varname} { upvar #0 $varname var global $varname if {$var(radius1) != {} && $var(radius2) !={}} { $var(frame) marker $var(id) ellipse radius \ $var(radius1) $var(radius2) $var(dcoord) $var(dformat) } MarkerBaseCenterRotate $varname MarkerBaseCenterApply $varname } # callbacks proc EllipseCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "EllipseCoordCB" } MarkerAnalysisStatsSystem $varname MarkerAnalysisPlot3dSystem $varname MarkerBaseCoordCB $varname MarkerBaseCenterMoveCB $varname MarkerBaseCenterRotateCB $varname } proc EllipseEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "EllipseEditCB" } set r [$var(frame) get marker $var(id) ellipse radius \ $var(dcoord) $var(dformat)] set var(radius1) [lindex $r 0] set var(radius2) [lindex $r 1] } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mregion.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000123520�12032640000�014024� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc RegionMainMenu {} { global ds9 global marker menu $ds9(mb).region $ds9(mb).region add command -label "[msgcat::mc {Get Information}]..." \ -command MarkerInfo $ds9(mb).region add separator $ds9(mb).region add cascade -label [msgcat::mc {Shape}] \ -menu $ds9(mb).region.shape $ds9(mb).region add cascade -label [msgcat::mc {Composite Region}] \ -menu $ds9(mb).region.composite $ds9(mb).region add cascade -label [msgcat::mc {Instrument FOV}] \ -menu $ds9(mb).region.fov $ds9(mb).region add cascade -label [msgcat::mc {Template}] \ -menu $ds9(mb).region.template $ds9(mb).region add separator $ds9(mb).region add cascade -label [msgcat::mc {Color}] \ -menu $ds9(mb).region.color $ds9(mb).region add cascade -label [msgcat::mc {Width}] \ -menu $ds9(mb).region.width $ds9(mb).region add cascade -label [msgcat::mc {Properties}] \ -menu $ds9(mb).region.properties $ds9(mb).region add cascade -label [msgcat::mc {Font}] \ -menu $ds9(mb).region.font $ds9(mb).region add separator $ds9(mb).region add command -label [msgcat::mc {Centroid}] \ -command MarkerCentroid $ds9(mb).region add command -label [msgcat::mc {Move to Front}] \ -command MarkerFront $ds9(mb).region add command -label [msgcat::mc {Move to Back}] \ -command MarkerBack $ds9(mb).region add separator $ds9(mb).region add command -label [msgcat::mc {Select All}] \ -command MarkerSelectAll -accelerator "${ds9(ctrl)}A" $ds9(mb).region add command -label [msgcat::mc {Select None}] \ -command MarkerUnselectAll $ds9(mb).region add command -label [msgcat::mc {Invert Selection}] \ -command MarkerSelectInvert $ds9(mb).region add separator $ds9(mb).region add command -label [msgcat::mc {Delete Selected Regions}] \ -command MarkerDeleteSelect $ds9(mb).region add command -label [msgcat::mc {Delete All Regions}] \ -command MarkerDeleteAllMenu $ds9(mb).region add separator $ds9(mb).region add command -label [msgcat::mc {New Group}] \ -command GroupCreate $ds9(mb).region add command -label "[msgcat::mc {Groups}]..." \ -command GroupDialog $ds9(mb).region add separator $ds9(mb).region add command -label "[msgcat::mc {List Regions}]..." \ -command MarkerList $ds9(mb).region add command -label "[msgcat::mc {Load Regions}]..." \ -command MarkerLoad $ds9(mb).region add command -label "[msgcat::mc {Save Regions}]..." \ -command MarkerSave $ds9(mb).region add separator $ds9(mb).region add cascade -label [msgcat::mc {Region Parameters}] \ -menu $ds9(mb).region.params menu $ds9(mb).region.shape $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Circle}] \ -variable marker(shape) -value circle $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Ellipse}] \ -variable marker(shape) -value ellipse $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Box}] \ -variable marker(shape) -value box $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Polygon}] \ -variable marker(shape) -value polygon $ds9(mb).region.shape add separator $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Line}] \ -variable marker(shape) -value line $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Vector}] \ -variable marker(shape) -value vector $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Projection}] \ -variable marker(shape) -value projection $ds9(mb).region.shape add separator $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Text}] \ -variable marker(shape) -value text $ds9(mb).region.shape add cascade -label [msgcat::mc {Point}] \ -menu $ds9(mb).region.shape.point $ds9(mb).region.shape add separator $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Ruler}] \ -variable marker(shape) -value ruler $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Compass}] \ -variable marker(shape) -value compass $ds9(mb).region.shape add separator $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Annulus}] \ -variable marker(shape) -value annulus $ds9(mb).region.shape add radiobutton \ -label [msgcat::mc {Elliptical Annulus}] \ -variable marker(shape) -value ellipseannulus $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Box Annulus}] \ -variable marker(shape) -value boxannulus $ds9(mb).region.shape add separator $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Panda}] \ -variable marker(shape) -value panda $ds9(mb).region.shape add radiobutton \ -label [msgcat::mc {Elliptical Panda}]\ -variable marker(shape) -value epanda $ds9(mb).region.shape add radiobutton -label [msgcat::mc {Box Panda}] \ -variable marker(shape) -value bpanda menu $ds9(mb).region.shape.point $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {Circle}] \ -variable marker(shape) -value {circle point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {Box}] \ -variable marker(shape) -value {box point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {Diamond}] \ -variable marker(shape) -value {diamond point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {Cross}] \ -variable marker(shape) -value {cross point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {X}] \ -variable marker(shape) -value {x point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {Arrow}] \ -variable marker(shape) -value {arrow point} $ds9(mb).region.shape.point add radiobutton -label [msgcat::mc {BoxCircle}]\ -variable marker(shape) -value {boxcircle point} menu $ds9(mb).region.composite $ds9(mb).region.composite add command -label [msgcat::mc {Create}] \ -command CompositeCreate $ds9(mb).region.composite add command -label [msgcat::mc {Dissolve}] \ -command CompositeDelete CreateFOVMenu menu $ds9(mb).region.template $ds9(mb).region.template add command -label "[msgcat::mc {Load}]..." \ -command OpenTemplateMarker $ds9(mb).region.template add command -label "[msgcat::mc {Save}]..." \ -command SaveAsTemplateMarker ColorMenu $ds9(mb).region.color marker color MarkerColor WidthDashMenu $ds9(mb).region.width marker width dash \ MarkerWidth [list MarkerProp dash] menu $ds9(mb).region.properties $ds9(mb).region.properties add checkbutton \ -label [msgcat::mc {Fixed in Size}] \ -variable marker(fixed) -command {MarkerProp fixed} $ds9(mb).region.properties add separator $ds9(mb).region.properties add checkbutton \ -label [msgcat::mc {Can Edit}] \ -variable marker(edit) -command {MarkerProp edit} $ds9(mb).region.properties add checkbutton \ -label [msgcat::mc {Can Move}] \ -variable marker(move) -command {MarkerProp move} $ds9(mb).region.properties add checkbutton \ -label [msgcat::mc {Can Rotate}] \ -variable marker(rotate) -command {MarkerProp rotate} $ds9(mb).region.properties add checkbutton \ -label [msgcat::mc {Can Delete}] \ -variable marker(delete) -command {MarkerProp delete} $ds9(mb).region.properties add separator $ds9(mb).region.properties add radiobutton \ -label [msgcat::mc {Include}] \ -variable marker(include) -value 1 -command {MarkerProp include} $ds9(mb).region.properties add radiobutton \ -label [msgcat::mc {Exclude}] \ -variable marker(include) -value 0 -command {MarkerProp include} $ds9(mb).region.properties add separator $ds9(mb).region.properties add radiobutton \ -label [msgcat::mc {Source}] \ -variable marker(source) -value 1 -command {MarkerProp source} $ds9(mb).region.properties add radiobutton \ -label [msgcat::mc {Background}] \ -variable marker(source) -value 0 -command {MarkerProp source} FontMenu $ds9(mb).region.font marker font font,size font,weight \ font,slant MarkerFont menu $ds9(mb).region.params $ds9(mb).region.params add checkbutton \ -label [msgcat::mc {Show}] \ -variable marker(show) -command MarkerShow $ds9(mb).region.params add checkbutton \ -label [msgcat::mc {Show Text}] \ -variable marker(show,text) -command MarkerShowText $ds9(mb).region.params add separator $ds9(mb).region.params add checkbutton -label [msgcat::mc {Auto Plot 2D}] \ -variable marker(plot2d) $ds9(mb).region.params add checkbutton -label [msgcat::mc {Auto Plot 3D}] \ -variable marker(plot3d) $ds9(mb).region.params add separator $ds9(mb).region.params add checkbutton \ -label [msgcat::mc {Auto Centroid}] \ -variable marker(centroid,auto) -command MarkerCentroidAuto $ds9(mb).region.params add command \ -label "[msgcat::mc {Centroid Parameters}]..." \ -command CentroidDialog # Bindings bind $ds9(top) <<SelectAll>> MarkerSelectAll } proc PrefsDialogRegionMenu {w} { set f [ttk::labelframe $w.mregion -text [msgcat::mc {Region}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarRegion $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 -sticky w set m $f.menu.menu menu $m $m add cascade -label [msgcat::mc {Shape}] -menu $m.shape $m add separator $m add cascade -label [msgcat::mc {Color}] -menu $m.color $m add cascade -label [msgcat::mc {Width}] -menu $m.width $m add cascade -label [msgcat::mc {Properties}] -menu $m.properties $m add cascade -label [msgcat::mc {Font}] -menu $m.font $m add separator $m add cascade -label [msgcat::mc {Region Parameters}] -menu $m.params menu $m.shape $m.shape add radiobutton -label [msgcat::mc {Circle}] \ -variable pmarker(shape) -value circle $m.shape add radiobutton -label [msgcat::mc {Ellipse}] \ -variable pmarker(shape) -value ellipse $m.shape add radiobutton -label [msgcat::mc {Box}] \ -variable pmarker(shape) -value box $m.shape add radiobutton -label [msgcat::mc {Polygon}] \ -variable pmarker(shape) -value polygon $m.shape add separator $m.shape add radiobutton -label [msgcat::mc {Line}] \ -variable pmarker(shape) -value line $m.shape add radiobutton -label [msgcat::mc {Vector}] \ -variable pmarker(shape) -value vector $m.shape add radiobutton -label [msgcat::mc {Projection}] \ -variable pmarker(shape) -value projection $m.shape add separator $m.shape add radiobutton -label [msgcat::mc {Text}] \ -variable pmarker(shape) -value text $m.shape add cascade -label [msgcat::mc {Point}] \ -menu $m.shape.point $m.shape add separator $m.shape add radiobutton -label [msgcat::mc {Ruler}] \ -variable pmarker(shape) -value ruler $m.shape add radiobutton -label [msgcat::mc {Compass}] \ -variable pmarker(shape) -value compass $m.shape add separator $m.shape add radiobutton -label [msgcat::mc {Annulus}] \ -variable pmarker(shape) -value annulus $m.shape add radiobutton -label [msgcat::mc {Elliptical Annulus}] \ -variable pmarker(shape) -value ellipseannulus $m.shape add radiobutton -label [msgcat::mc {Box Annulus}] \ -variable pmarker(shape) -value boxannulus $m.shape add separator $m.shape add radiobutton -label [msgcat::mc {Panda}] \ -variable pmarker(shape) -value panda $m.shape add radiobutton -label [msgcat::mc {Elliptical Panda}] \ -variable pmarker(shape) -value epanda $m.shape add radiobutton -label [msgcat::mc {Box Panda}] \ -variable pmarker(shape) -value bpanda menu $m.shape.point $m.shape.point add radiobutton -label [msgcat::mc {Circle}] \ -variable pmarker(shape) -value {circle point} $m.shape.point add radiobutton -label [msgcat::mc {Box}] \ -variable pmarker(shape) -value {box point} $m.shape.point add radiobutton -label [msgcat::mc {Diamond}] \ -variable pmarker(shape) -value {diamond point} $m.shape.point add radiobutton -label [msgcat::mc {Cross}] \ -variable pmarker(shape) -value {cross point} $m.shape.point add radiobutton -label [msgcat::mc {X}] \ -variable pmarker(shape) -value {x point} $m.shape.point add radiobutton -label [msgcat::mc {Arrow}] \ -variable pmarker(shape) -value {arrow point} $m.shape.point add radiobutton -label [msgcat::mc {BoxCircle}]\ -variable pmarker(shape) -value {boxcircle point} ColorMenu $m.color pmarker color {} WidthDashMenu $m.width pmarker width dash {} {} menu $m.properties $m.properties add checkbutton -label [msgcat::mc {Fixed in Size}] \ -variable pmarker(fixed) $m.properties add separator $m.properties add checkbutton -label [msgcat::mc {Can Edit}] \ -variable pmarker(edit) $m.properties add checkbutton -label [msgcat::mc {Can Move}] \ -variable pmarker(move) $m.properties add checkbutton -label [msgcat::mc {Can Rotate}] \ -variable pmarker(rotate) $m.properties add checkbutton -label [msgcat::mc {Can Delete}] \ -variable pmarker(delete) $m.properties add separator $m.properties add radiobutton -label [msgcat::mc {Include}] \ -variable pmarker(include) -value 1 $m.properties add radiobutton -label [msgcat::mc {Exclude}] \ -variable pmarker(include) -value 0 $m.properties add separator $m.properties add radiobutton -label [msgcat::mc {Source}] \ -variable pmarker(source) -value 1 $m.properties add radiobutton -label [msgcat::mc {Background}] \ -variable pmarker(source) -value 0 FontMenu $m.font pmarker font font,size font,weight font,slant {} menu $m.params $m.params add checkbutton -label [msgcat::mc {Show}] \ -variable pmarker(show) $m.params add checkbutton -label [msgcat::mc {Show Text}] \ -variable pmarker(show,text) $m.params add separator $m.params add checkbutton -label [msgcat::mc {Auto Centroid}] \ -variable pmarker(centroid,auto) pack $f -side top -fill both -expand true } proc PrefsDialogRegion {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Region}] lappend dprefs(tabs) [ttk::frame $w.region] # Format set f [ttk::labelframe $w.region.format -text [msgcat::mc {Default Format}]] ttk::menubutton $f.format -textvariable pmarker(format) \ -menu $f.format.menu grid $f.format -padx 2 -pady 2 -sticky w menu $f.format.menu $f.format.menu add radiobutton -label {DS9/Funtools} \ -variable pmarker(format) -value ds9 $f.format.menu add radiobutton -label {XML} \ -variable pmarker(format) -value xml $f.format.menu add radiobutton -label {CIAO} \ -variable pmarker(format) -value ciao $f.format.menu add radiobutton -label {SAOtng} \ -variable pmarker(format) -value saotng $f.format.menu add radiobutton -label {SAOimage} \ -variable pmarker(format) -value saoimage $f.format.menu add radiobutton -label {IRAF PROS} \ -variable pmarker(format) -value pros $f.format.menu add radiobutton -label {X Y} \ -variable pmarker(format) -value xy # Length set f [ttk::labelframe $w.region.dformat \ -text [msgcat::mc {Default Length}]] ttk::menubutton $f.dformat -textvariable pmarker(dformat) \ -menu $f.dformat.menu grid $f.dformat -padx 2 -pady 2 -sticky w menu $f.dformat.menu $f.dformat.menu add radiobutton -label {Degrees} \ -variable pmarker(dformat) -value degrees $f.dformat.menu add radiobutton -label {ArcMin} \ -variable pmarker(dformat) -value arcmin $f.dformat.menu add radiobutton -label {ArcSec} \ -variable pmarker(dformat) -value arcsec # Centroid set f [ttk::labelframe $w.region.centroid -text [msgcat::mc {Centroid}]] ttk::label $f.ititle -text [msgcat::mc {Iteration}] ttk::entry $f.iteration -textvariable pmarker(centroid,iteration) -width 10 ttk::label $f.rtitle -text [msgcat::mc {Radius}] ttk::entry $f.radius -textvariable pmarker(centroid,radius) -width 10 grid $f.ititle $f.iteration $f.rtitle $f.radius -padx 2 -pady 2 -sticky w # Plots set f [ttk::labelframe $w.region.plot -text [msgcat::mc {Auto Plot}]] ttk::checkbutton $f.2d -text [msgcat::mc {2D}] -variable pmarker(plot2d) ttk::checkbutton $f.3d -text [msgcat::mc {3D}] -variable pmarker(plot3d) grid $f.2d -padx 2 -pady 2 -sticky w grid $f.3d -padx 2 -pady 2 -sticky w # Circle set f [ttk::labelframe $w.region.circle -text [msgcat::mc {Circle}]] ttk::label $f.title -text [msgcat::mc {Radius}] ttk::entry $f.radius -textvariable pmarker(circle,radius) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] grid $f.title $f.radius $f.unit -padx 2 -pady 2 -sticky w # Ellipse set f [ttk::labelframe $w.region.ellipse -text [msgcat::mc {Ellipse}]] ttk::label $f.title -text "Radius 1" ttk::entry $f.radius1 -textvariable pmarker(ellipse,radius1) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.title2 -text "Radius 2" ttk::entry $f.radius2 -textvariable pmarker(ellipse,radius2) -width 10 ttk::label $f.unit2 -text [msgcat::mc {Image}] grid $f.title $f.radius1 $f.unit -padx 2 -pady 2 -sticky w grid $f.title2 $f.radius2 $f.unit2 -padx 2 -pady 2 -sticky w # Box set f [ttk::labelframe $w.region.box -text [msgcat::mc {Box}]] ttk::label $f.title -text "Size 1" ttk::entry $f.radius1 -textvariable pmarker(box,radius1) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.title2 -text "Size 2" ttk::entry $f.radius2 -textvariable pmarker(box,radius2) -width 10 ttk::label $f.unit2 -text [msgcat::mc {Image}] grid $f.title $f.radius1 $f.unit -padx 2 -pady 2 -sticky w grid $f.title2 $f.radius2 $f.unit2 -padx 2 -pady 2 -sticky w # Projection set f [ttk::labelframe $w.region.projection -text [msgcat::mc {Projection}]] ttk::label $f.title -text [msgcat::mc {Thickness}] ttk::entry $f.thick -textvariable pmarker(projection,thick) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] grid $f.title $f.thick $f.unit -padx 2 -pady 2 -sticky w # Point set f [ttk::labelframe $w.region.point -text [msgcat::mc {Point}]] ttk::label $f.title -text [msgcat::mc {Size}] ttk::entry $f.size -textvariable pmarker(point,size) -width 10 ttk::label $f.unit -text [msgcat::mc {Pixels}] grid $f.title $f.size $f.unit -padx 2 -pady 2 -sticky w pack $w.region.format $w.region.dformat $w.region.centroid $w.region.plot \ $w.region.circle $w.region.ellipse \ $w.region.box $w.region.projection $w.region.point \ -side top -fill both -expand true } proc PrefsDialogAnnulus {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Annulus}] lappend dprefs(tabs) [ttk::frame $w.annulus] # Annulus set f [ttk::labelframe $w.annulus.annulus -text [msgcat::mc {Annulus}]] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::label $f.radiusTitle -text [msgcat::mc {Radius}] ttk::entry $f.inner -textvariable pmarker(annulus,inner) -width 10 ttk::entry $f.outer -textvariable pmarker(annulus,outer) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(annulus,annuli) -width 10 grid x $f.innerTitle $f.outerTitle -padx 2 -pady 2 -sticky w grid $f.radiusTitle $f.inner $f.outer $f.unit -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w # Ellipse Annulus set f [ttk::labelframe $w.annulus.ellipseannulus \ -text [msgcat::mc {Elliptical Annulus}]] ttk::label $f.majorTitle -text [msgcat::mc {Major}] ttk::label $f.minorTitle -text [msgcat::mc {Minor}] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::entry $f.radius1 -textvariable pmarker(ellipseannulus,radius1) \ -width 10 ttk::entry $f.radius2 -textvariable pmarker(ellipseannulus,radius2) \ -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::entry $f.radius3 -textvariable pmarker(ellipseannulus,radius3) \ -width 10 ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(ellipseannulus,annuli) -width 10 grid x $f.majorTitle $f.minorTitle -padx 2 -pady 2 -sticky w grid $f.innerTitle $f.radius1 $f.radius2 $f.unit -padx 2 -pady 2 -sticky w grid $f.outerTitle $f.radius3 -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w # Box Annulus set f [ttk::labelframe $w.annulus.boxannulus \ -text [msgcat::mc {Box Annulus}]] ttk::label $f.majorTitle -text [msgcat::mc {Width}] ttk::label $f.minorTitle -text [msgcat::mc {Height}] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::entry $f.radius1 -textvariable pmarker(boxannulus,radius1) -width 10 ttk::entry $f.radius2 -textvariable pmarker(boxannulus,radius2) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::entry $f.radius3 -textvariable pmarker(boxannulus,radius3) -width 10 ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(boxannulus,annuli) -width 10 grid x $f.majorTitle $f.minorTitle -padx 2 -pady 2 -sticky w grid $f.innerTitle $f.radius1 $f.radius2 $f.unit -padx 2 -pady 2 -sticky w grid $f.outerTitle $f.radius3 -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w pack $w.annulus.annulus $w.annulus.ellipseannulus $w.annulus.boxannulus \ -side top -fill both -expand true } proc PrefsDialogPanda {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Panda}] lappend dprefs(tabs) [ttk::frame $w.panda] # Panda set f [ttk::labelframe $w.panda.panda -text [msgcat::mc {Panda}]] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::label $f.radiusTitle -text [msgcat::mc {Radius}] ttk::entry $f.inner -textvariable pmarker(panda,inner) -width 10 ttk::entry $f.outer -textvariable pmarker(panda,outer) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(panda,annuli) -width 10 grid x $f.innerTitle $f.outerTitle -padx 2 -pady 2 -sticky w grid $f.radiusTitle $f.inner $f.outer $f.unit -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w ttk::label $f.ang1Title -text [msgcat::mc {Start}] ttk::label $f.ang2Title -text [msgcat::mc {Stop}] ttk::label $f.angTitle -text [msgcat::mc {Angles}] ttk::entry $f.ang1 -textvariable pmarker(panda,ang1) -width 10 ttk::entry $f.ang2 -textvariable pmarker(panda,ang2) -width 10 ttk::label $f.angunit -text [msgcat::mc {Degrees}] ttk::label $f.angnumTitle -text [msgcat::mc {Number}] ttk::entry $f.angnum -textvariable pmarker(panda,angnum) -width 10 grid x $f.ang1Title $f.ang2Title -padx 2 -pady 2 -sticky w grid $f.angTitle $f.ang1 $f.ang2 $f.angunit -padx 2 -pady 2 -sticky w grid $f.angnumTitle $f.angnum -padx 2 -pady 2 -sticky w # Elliptical Panda set f [ttk::labelframe $w.panda.epanda \ -text [msgcat::mc {Elliptical Panda}]] ttk::label $f.majorTitle -text [msgcat::mc {Major}] ttk::label $f.minorTitle -text [msgcat::mc {Minor}] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::entry $f.radius1 -textvariable pmarker(epanda,radius1) -width 10 ttk::entry $f.radius2 -textvariable pmarker(epanda,radius2) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::entry $f.radius3 -textvariable pmarker(epanda,radius3) -width 10 ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(epanda,annuli) -width 10 grid x $f.majorTitle $f.minorTitle -padx 2 -pady 2 -sticky w grid $f.innerTitle $f.radius1 $f.radius2 $f.unit -padx 2 -pady 2 -sticky w grid $f.outerTitle $f.radius3 -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w ttk::label $f.ang1Title -text [msgcat::mc {Start}] ttk::label $f.ang2Title -text [msgcat::mc {Stop}] ttk::label $f.angTitle -text [msgcat::mc {Angles}] ttk::entry $f.ang1 -textvariable pmarker(epanda,ang1) -width 10 ttk::entry $f.ang2 -textvariable pmarker(epanda,ang2) -width 10 ttk::label $f.angunit -text [msgcat::mc {Degrees}] ttk::label $f.angnumTitle -text [msgcat::mc {Number}] ttk::entry $f.angnum -textvariable pmarker(epanda,angnum) -width 10 grid x $f.ang1Title $f.ang2Title -padx 2 -pady 2 -sticky w grid $f.angTitle $f.ang1 $f.ang2 $f.angunit -padx 2 -pady 2 -sticky w grid $f.angnumTitle $f.angnum -padx 2 -pady 2 -sticky w # Default Box Panda set f [ttk::labelframe $w.panda.bpanda -text [msgcat::mc {Box Panda}]] ttk::label $f.majorTitle -text [msgcat::mc {Major}] ttk::label $f.minorTitle -text [msgcat::mc {Minor}] ttk::label $f.innerTitle -text [msgcat::mc {Inner}] ttk::entry $f.radius1 -textvariable pmarker(bpanda,radius1) -width 10 ttk::entry $f.radius2 -textvariable pmarker(bpanda,radius2) -width 10 ttk::label $f.unit -text [msgcat::mc {Image}] ttk::label $f.outerTitle -text [msgcat::mc {Outer}] ttk::entry $f.radius3 -textvariable pmarker(bpanda,radius3) -width 10 ttk::label $f.annuliTitle -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable pmarker(bpanda,annuli) -width 10 grid x $f.majorTitle $f.minorTitle -padx 2 -pady 2 -sticky w grid $f.innerTitle $f.radius1 $f.radius2 $f.unit -padx 2 -pady 2 -sticky w grid $f.outerTitle $f.radius3 -padx 2 -pady 2 -sticky w grid $f.annuliTitle $f.annuli -padx 2 -pady 2 -sticky w ttk::label $f.ang1Title -text [msgcat::mc {Start}] ttk::label $f.ang2Title -text [msgcat::mc {Stop}] ttk::label $f.angTitle -text [msgcat::mc {Angles}] ttk::entry $f.ang1 -textvariable pmarker(bpanda,ang1) -width 10 ttk::entry $f.ang2 -textvariable pmarker(bpanda,ang2) -width 10 ttk::label $f.angunit -text [msgcat::mc {Degrees}] ttk::label $f.angnumTitle -text [msgcat::mc {Number}] ttk::entry $f.angnum -textvariable pmarker(bpanda,angnum) -width 10 grid x $f.ang1Title $f.ang2Title -padx 2 -pady 2 -sticky w grid $f.angTitle $f.ang1 $f.ang2 $f.angunit -padx 2 -pady 2 -sticky w grid $f.angnumTitle $f.angnum -padx 2 -pady 2 -sticky w pack $w.panda.panda $w.panda.epanda $w.panda.bpanda \ -side top -fill both -expand true } # Buttons proc ButtonsRegionDef {} { global pbuttons array set pbuttons { region,info 1 region,circle 0 region,ellipse 0 region,box 0 region,polygon 0 region,line 0 region,vector 0 region,projection 0 region,text 0 region,point 0 region,ruler 0 region,compass 0 region,annulus 0 region,ellipseannulus 0 region,boxannulus 0 region,panda 0 region,epanda 0 region,bpanda 0 region,create 0 region,dissolve 0 region,loadtemplate 0 region,savetemplate 0 region,centroid 0 region,front 1 region,back 1 region,all 1 region,none 1 region,invert 0 region,delete 1 region,deleteall 0 region,newgroup 0 region,group 0 region,list 1 region,load 1 region,save 1 region,show 0 region,showtext 0 region,autocentroid 0 } } proc CreateButtonsRegion {} { global buttons global ds9 ttk::frame $ds9(buttons).region ButtonButton $ds9(buttons).region.info \ [string tolower [msgcat::mc {Information}]] MarkerInfo RadioButton $ds9(buttons).region.circle \ [string tolower [msgcat::mc {Circle}]] \ marker(shape) circle {} RadioButton $ds9(buttons).region.ellipse \ [string tolower [msgcat::mc {Ellipse}]] \ marker(shape) ellipse {} RadioButton $ds9(buttons).region.box \ [string tolower [msgcat::mc {Box}]] \ marker(shape) box {} RadioButton $ds9(buttons).region.polygon \ [string tolower [msgcat::mc {Polygon}]] \ marker(shape) polygon {} RadioButton $ds9(buttons).region.line \ [string tolower [msgcat::mc {Line}]] \ marker(shape) line {} RadioButton $ds9(buttons).region.vector \ [string tolower [msgcat::mc {Vector}]] \ marker(shape) vector {} RadioButton $ds9(buttons).region.projection \ [string tolower [msgcat::mc {Projection}]] \ marker(shape) projection {} RadioButton $ds9(buttons).region.text \ [string tolower [msgcat::mc {Text}]] \ marker(shape) text {} RadioButton $ds9(buttons).region.point \ [string tolower [msgcat::mc {Point}]] \ marker(shape) {circle point} {} RadioButton $ds9(buttons).region.ruler \ [string tolower [msgcat::mc {Ruler}]] \ marker(shape) ruler {} RadioButton $ds9(buttons).region.compass \ [string tolower [msgcat::mc {Compass}]] \ marker(shape) compass {} RadioButton $ds9(buttons).region.annulus \ [string tolower [msgcat::mc {Annulus}]] \ marker(shape) annulus {} RadioButton $ds9(buttons).region.ellipseannulus \ [string tolower [msgcat::mc {Elliptical Annulus}]] \ marker(shape) ellipseannulus {} RadioButton $ds9(buttons).region.boxannulus \ [string tolower [msgcat::mc {Box Annulus}]] \ marker(shape) boxannulus {} RadioButton $ds9(buttons).region.panda \ [string tolower [msgcat::mc {Panda}]] \ marker(shape) panda {} RadioButton $ds9(buttons).region.epanda \ [string tolower [msgcat::mc {Ellipse Panda}]] \ marker(shape) epanda {} RadioButton $ds9(buttons).region.bpanda \ [string tolower [msgcat::mc {Box Panda}]] \ marker(shape) bpanda {} ButtonButton $ds9(buttons).region.create \ [string tolower [msgcat::mc {Composite}]] CompositeCreate ButtonButton $ds9(buttons).region.dissolve \ [string tolower [msgcat::mc {Dissolve}]] CompositeDelete ButtonButton $ds9(buttons).region.loadtemplate \ [string tolower [msgcat::mc {Load Template}]] OpenTemplateMarker ButtonButton $ds9(buttons).region.savetemplate \ [string tolower [msgcat::mc {Save Template}]] SaveAsTemplateMarker ButtonButton $ds9(buttons).region.centroid \ [string tolower [msgcat::mc {Centroid}]] MarkerCentroid ButtonButton $ds9(buttons).region.front \ [string tolower [msgcat::mc {Front}]] MarkerFront ButtonButton $ds9(buttons).region.back \ [string tolower [msgcat::mc {Back}]] MarkerBack ButtonButton $ds9(buttons).region.all \ [string tolower [msgcat::mc {All}]] MarkerSelectAll ButtonButton $ds9(buttons).region.none \ [string tolower [msgcat::mc {None}]] MarkerUnselectAll ButtonButton $ds9(buttons).region.invert \ [string tolower [msgcat::mc {Invert}]] MarkerSelectInvert ButtonButton $ds9(buttons).region.delete \ [string tolower [msgcat::mc {Delete}]] MarkerDeleteSelect ButtonButton $ds9(buttons).region.deleteall \ [string tolower [msgcat::mc {Delete All}]] MarkerDeleteAllMenu ButtonButton $ds9(buttons).region.newgroup \ [string tolower [msgcat::mc {New Group}]] GroupCreate ButtonButton $ds9(buttons).region.group \ [string tolower [msgcat::mc {Groups}]] GroupDialog ButtonButton $ds9(buttons).region.list \ [string tolower [msgcat::mc {List}]] MarkerList ButtonButton $ds9(buttons).region.load \ [string tolower [msgcat::mc {Load}]] MarkerLoad ButtonButton $ds9(buttons).region.save \ [string tolower [msgcat::mc {Save}]] MarkerSave CheckButton $ds9(buttons).region.show \ [string tolower [msgcat::mc {Show}]] \ marker(show) MarkerShow CheckButton $ds9(buttons).region.showtext \ [string tolower [msgcat::mc {Show Text}]] \ marker(show,text) MarkerShowText CheckButton $ds9(buttons).region.autocentroid \ [string tolower [msgcat::mc {Auto Centroid}]] \ marker(centroid,auto) MarkerCentroidAuto set buttons(region) " $ds9(buttons).region.info pbuttons(region,info) $ds9(buttons).region.circle pbuttons(region,circle) $ds9(buttons).region.ellipse pbuttons(region,ellipse) $ds9(buttons).region.box pbuttons(region,box) $ds9(buttons).region.polygon pbuttons(region,polygon) $ds9(buttons).region.line pbuttons(region,line) $ds9(buttons).region.vector pbuttons(region,vector) $ds9(buttons).region.projection pbuttons(region,projection) $ds9(buttons).region.text pbuttons(region,text) $ds9(buttons).region.point pbuttons(region,point) $ds9(buttons).region.ruler pbuttons(region,ruler) $ds9(buttons).region.compass pbuttons(region,compass) $ds9(buttons).region.annulus pbuttons(region,annulus) $ds9(buttons).region.ellipseannulus pbuttons(region,ellipseannulus) $ds9(buttons).region.boxannulus pbuttons(region,boxannulus) $ds9(buttons).region.panda pbuttons(region,panda) $ds9(buttons).region.epanda pbuttons(region,epanda) $ds9(buttons).region.bpanda pbuttons(region,bpanda) $ds9(buttons).region.create pbuttons(region,create) $ds9(buttons).region.dissolve pbuttons(region,dissolve) $ds9(buttons).region.loadtemplate pbuttons(region,loadtemplate) $ds9(buttons).region.savetemplate pbuttons(region,savetemplate) $ds9(buttons).region.centroid pbuttons(region,centroid) $ds9(buttons).region.front pbuttons(region,front) $ds9(buttons).region.back pbuttons(region,back) $ds9(buttons).region.all pbuttons(region,all) $ds9(buttons).region.none pbuttons(region,none) $ds9(buttons).region.invert pbuttons(region,invert) $ds9(buttons).region.delete pbuttons(region,delete) $ds9(buttons).region.deleteall pbuttons(region,deleteall) $ds9(buttons).region.newgroup pbuttons(region,newgroup) $ds9(buttons).region.group pbuttons(region,group) $ds9(buttons).region.list pbuttons(region,list) $ds9(buttons).region.load pbuttons(region,load) $ds9(buttons).region.save pbuttons(region,save) $ds9(buttons).region.show pbuttons(region,show) $ds9(buttons).region.showtext pbuttons(region,showtext) $ds9(buttons).region.autocentroid pbuttons(region,autocentroid) " } proc PrefsDialogButtonbarRegion {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label "[msgcat::mc {Get Information}]..." \ -variable pbuttons(region,info) \ -command {UpdateButtons buttons(region)} $m add separator $m add cascade -label [msgcat::mc {Shape}] -menu $m.shape $m add cascade -label [msgcat::mc {Composite Region}] -menu $m.composite $m add cascade -label [msgcat::mc {Template}] -menu $m.template $m add separator $m add checkbutton -label [msgcat::mc {Centroid}] \ -variable pbuttons(region,centroid) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label [msgcat::mc {Move to Front}] \ -variable pbuttons(region,front) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label [msgcat::mc {Move to Back}] \ -variable pbuttons(region,back) \ -command {UpdateButtons buttons(region)} $m add separator $m add checkbutton -label [msgcat::mc {Select All}] \ -variable pbuttons(region,all) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label [msgcat::mc {Select None}] \ -variable pbuttons(region,none) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label [msgcat::mc {Invert Selection}] \ -variable pbuttons(region,invert) \ -command {UpdateButtons buttons(region)} $m add separator $m add checkbutton -label [msgcat::mc {Delete Selected Regions}] \ -variable pbuttons(region,delete) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label [msgcat::mc {Delete All Regions}] \ -variable pbuttons(region,deleteall) \ -command {UpdateButtons buttons(region)} $m add separator $m add checkbutton -label [msgcat::mc {New Group}] \ -variable pbuttons(region,newgroup) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label "[msgcat::mc {Groups}]..." \ -variable pbuttons(region,group) \ -command {UpdateButtons buttons(region)} $m add separator $m add checkbutton -label "[msgcat::mc {List Regions}]..." \ -variable pbuttons(region,list) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label "[msgcat::mc {Load Regions}]..." \ -variable pbuttons(region,load) \ -command {UpdateButtons buttons(region)} $m add checkbutton -label "[msgcat::mc {Save Regions}]..." \ -variable pbuttons(region,save) \ -command {UpdateButtons buttons(region)} $m add separator $m add cascade -label [msgcat::mc {Region Parameters}] -menu $m.params menu $m.shape $m.shape add checkbutton -label [msgcat::mc {Circle}] \ -variable pbuttons(region,circle) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Ellipse}] \ -variable pbuttons(region,ellipse) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Box}] \ -variable pbuttons(region,box) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Polygon}] \ -variable pbuttons(region,polygon) \ -command {UpdateButtons buttons(region)} $m.shape add separator $m.shape add checkbutton -label [msgcat::mc {Line}] \ -variable pbuttons(region,line) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Vector}] \ -variable pbuttons(region,vector) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Projection}] \ -variable pbuttons(region,projection) \ -command {UpdateButtons buttons(region)} $m.shape add separator $m.shape add checkbutton -label [msgcat::mc {Text}] \ -variable pbuttons(region,text) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Point}] \ -variable pbuttons(region,point) \ -command {UpdateButtons buttons(region)} $m.shape add separator $m.shape add checkbutton -label [msgcat::mc {Ruler}] \ -variable pbuttons(region,ruler) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Compass}] \ -variable pbuttons(region,compass) \ -command {UpdateButtons buttons(region)} $m.shape add separator $m.shape add checkbutton -label [msgcat::mc {Annulus}] \ -variable pbuttons(region,annulus) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Elliptical Annulus}] \ -variable pbuttons(region,ellipseannulus) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Box Annulus}] \ -variable pbuttons(region,boxannulus) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Panda}] \ -variable pbuttons(region,panda) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Elliptical Panda}]\ -variable pbuttons(region,epanda) \ -command {UpdateButtons buttons(region)} $m.shape add checkbutton -label [msgcat::mc {Box Panda}] \ -variable pbuttons(region,bpanda) \ -command {UpdateButtons buttons(region)} menu $m.composite $m.composite add checkbutton -label [msgcat::mc {Create}] \ -variable pbuttons(region,create) \ -command {UpdateButtons buttons(region)} $m.composite add checkbutton -label [msgcat::mc {Dissolve}] \ -variable pbuttons(region,dissolve) \ -command {UpdateButtons buttons(region)} menu $m.template $m.template add checkbutton -label "[msgcat::mc {Load}]..." \ -variable pbuttons(region,loadtemplate) \ -command {UpdateButtons buttons(region)} $m.template add checkbutton -label "[msgcat::mc {Save}]..." \ -variable pbuttons(region,savetemplate) \ -command {UpdateButtons buttons(region)} menu $m.params $m.params add checkbutton -label [msgcat::mc {Show}] \ -variable pbuttons(region,show) \ -command {UpdateButtons buttons(region)} $m.params add checkbutton -label [msgcat::mc {Show Text}] \ -variable pbuttons(region,showtext) \ -command {UpdateButtons buttons(region)} $m.params add separator $m.params add checkbutton -label [msgcat::mc {Auto Centroid}] \ -variable pbuttons(region,autocentroid) \ -command {UpdateButtons buttons(region)} } # Support proc UpdateRegionMenu {} { global current global marker global pmarker global ds9 if {$current(frame) != {}} { $ds9(mb) entryconfig [msgcat::mc {Region}] -state normal set marker(show) [$current(frame) get marker show] set marker(show,text) [$current(frame) get marker show text] set marker(centroid,auto) [$current(frame) get marker centroid auto] set marker(preserve) [$current(frame) get marker preserve] switch -- $current(mode) { pointer { if {[$current(frame) get marker select number] == 1} { set marker(color) \ [$current(frame) get marker color] set marker(width) \ [$current(frame) get marker width] set marker(dash) \ [$current(frame) get marker property dash] set marker(fixed) \ [$current(frame) get marker property fixed] set marker(edit) \ [$current(frame) get marker property edit] set marker(move) \ [$current(frame) get marker property move] set marker(rotate) \ [$current(frame) get marker property rotate] set marker(delete) \ [$current(frame) get marker property delete] set marker(include) \ [$current(frame) get marker property include] set marker(source) \ [$current(frame) get marker property source] set f [$current(frame) get marker font] set marker(font) [lindex $f 0] set marker(font,size) [lindex $f 1] set marker(font,weight) [lindex $f 2] set marker(font,slant) [lindex $f 3] } else { # defaults set marker(color) $pmarker(color) set marker(width) $pmarker(width) set marker(dash) $pmarker(dash) set marker(fixed) $pmarker(fixed) set marker(edit) $pmarker(edit) set marker(move) $pmarker(move) set marker(rotate) $pmarker(rotate) set marker(delete) $pmarker(delete) set marker(include) $pmarker(include) set marker(source) $pmarker(source) set marker(font) $pmarker(font) set marker(font,size) $pmarker(font,size) set marker(font,weight) $pmarker(font,weight) set marker(font,slant) $pmarker(font,slant) } } } } else { $ds9(mb) entryconfig [msgcat::mc {Region}] -state disabled } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/starbase.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000025445�11700665572�014225� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # #### # # starbase.tcl -- Tcl interface to starbase # # #### # Starbase Tables Interface # set starbase_debug 0 proc Starbase {} { global Starbase return $Starbase(version) } set Starbase(version) "Starbase Tcl Driver 1.0" proc starbase_nrows { D } { upvar $D data; return $data(Nrows) } proc starbase_ncols { D } { upvar $D data; return $data(Ncols) } proc starbase_get { D row col } { upvar $D data; return $data($row,$col) } proc starbase_set { D row col val } { upvar $D data; set data($row,$col) $val; } proc starbase_colname { D num } { upvar $D data; return $data(0,$num) } #proc starbase_columns { D } { upvar $D data; return $data(Header) } proc starbase_colnum { D name } { upvar $D data; return $data($name) } proc starbase_columns {t} { upvar $t T set row {} set Ncols $T(Ncols) for { set c 1 } { $c <= $Ncols } { incr c } { lappend row $T(0,$c) } return $row } proc starbase_init { t } { upvar t T set T(Nrows) 0 set T(Ncols) 0 set T(Header) "" } # Set up a starbase data array for use with ted # proc starbase_driver { Dr } { upvar $Dr driver set driver(nrows) starbase_nrows set driver(ncols) starbase_ncols set driver(get) starbase_get set driver(set) starbase_set set driver(colname) starbase_colname set driver(colnum) starbase_colnum set driver(columns) starbase_columns set driver(colins) starbase_colins set driver(coldel) starbase_coldel set driver(colapp) starbase_colapp set driver(rowins) starbase_rowins set driver(rowdel) starbase_rowdel set driver(rowapp) starbase_rowapp } starbase_driver Starbase proc starbase_new { t args } { upvar $t T set T(Header) $args set T(Ndshs) [llength $T(Header)] set T(HLines) 2 starbase_colmap T set T(Nrows) 0 } proc starbase_colmap { h } { upvar $h H set c 0 foreach column $H(Header) { incr c set column [string trim $column] set H($column) $c set H(0,$c) $column } set H(Ncols) $c } proc starbase_coldel { t here } { upvar $t T set Ncols $T(Ncols) set T(Header) [lreplace $T(Header) [expr $here - 1] [expr $here - 1] starbase_colmap T for { set row 1 } { $row <= $T(Nrows) } { incr row } { for { set col $here } { $col < $Ncols } { incr col } { if { [catch { set val $T($row,[expr $col + 1]) }] } { set T($row,$col) "" } else { set T($row,$col) $val } } } } proc starbase_colins { t name here } { upvar $t T if { [info exists $T(Header)] == 0 } { set T(Header) $name } else { set T(Header) [linsert $T(Header) [expr $here - 1] $name] } starbase_colmap T for { set row 1 } { $row <= $T(Nrows) } { incr row } { for { set col $T(Ncol) } { $col > $here } { incr col -1 } { if { [catch { set val $T($row,[expr $col - 1]) }] } { set T($row,$col) "" } else { set T($row,$col) $val } } } for { set row 1 } { $row <= $T(Nrows) } { incr row } { set T($row,$here) "" } } proc starbase_header { h fp } { upvar $h H global starbase_line set N 1 if { [info exists starbase_line] } { set line $starbase_line set n 1 set H(H_$n) $line if { [regexp -- {^ *(-)+ *(\t *(-)+ *)*} $line] } break if { $n >= 2 } { set ind [string first "\t" $H(H_[expr $n-1])] if { $ind >= 0 } { set name [string range $H(H_[expr $n-1]) 0 [expr $ind - 1]] incr ind set H(H_$name) [string range $H(H_[expr $n-1]) $ind end] set H(N_$name) [expr $n-1] } # set l [split $H(H_[expr $n-1]) "\t"] # if { [llength $l] > 1 } { # set name [lindex $l 0] # set H(H_$name) [lrange $l 1 end] # set H(N_$name) [expr $n-1] # } } unset starbase_line set N 2 } for { set n $N } { [set eof [gets $fp line]] != -1 } { incr n } { set H(H_$n) $line if { [regexp -- {^ *(-)+ *(\t *(-)+ *)*} $line] } break if { $n >= 2 } { set ind [string first "\t" $H(H_[expr $n-1])] if { $ind >= 0 } { set name [string range $H(H_[expr $n-1]) 0 [expr $ind - 1]] incr ind set H(H_$name) [string range $H(H_[expr $n-1]) $ind end] set H(N_$name) [expr $n-1] } # set l [split $H(H_[expr $n-1]) "\t"] # if { [llength $l] > 1 } { # set name [lindex $l 0] # set H(H_$name) [lrange $l 1 end] # set H(N_$name) [expr $n-1] # } } } if { $eof == -1 } { error "ERROR: in starbase_header: unexpected eof" } set H(H_$n) $line set H(HLines) $n set H(Header) [split $H(H_[expr $n-1]) "\t"] set H(Dashes) [split $H(H_$n) "\t"] set H(Ndshs) [llength $H(Dashes)] starbase_colmap H return H(Header) } proc starbase_hdrget { h name } { upvar $h H return $H(H_$name) } proc starbase_hdrset { h name value } { upvar #0 $h H if { ![info exists H(H_$name)] } { set n [incr H(HLines)] set H(H_[expr $n-0]) $H(H_[expr $n-1]) set H(H_[expr $n-1]) $H(H_[expr $n-2]) set H(N_$name) [expr $n-2] } set H(H_$name) $value set H(H_$H(N_$name)) "$name $value" } proc starbase_hdrput { h fp } { upvar $h H if { ![info exists H(HLines)] || ($H(HLines) == 0) } { return } set nl [expr $H(HLines) - 2] for { set l 1 } { $l <= $nl } { incr l } { puts $fp $H(H_$l) } if { ![info exists H(Ncols)] || ($H(Ncols) == 0) } { return } set nc $H(Ncols) for { set c 1 } { $c <= $nc } { incr c } { puts -nonewline $fp "$H(0,$c)" if { $c != $nc } { puts -nonewline $fp "\t" } else { puts -nonewline $fp "\n" } } for { set c 1 } { $c <= $nc } { incr c } { set len [string length $H(0,$c)] for { set d 1 } { $d <= $len } { incr d } { puts -nonewline $fp "-" } if { $c != $nc } { puts -nonewline $fp "\t" } else { puts -nonewline $fp "\n" } } } proc starbase_hdrput_ { h varname } { upvar $h H upvar $varname var if { ![info exists H(HLines)] || ($H(HLines) == 0) } { return } set nl [expr $H(HLines) - 2] for { set l 1 } { $l <= $nl } { incr l } { append var "$H(H_$l)\n" } if { ![info exists H(Ncols)] || ($H(Ncols) == 0) } { return } set nc $H(Ncols) for { set c 1 } { $c <= $nc } { incr c } { append var "$H(0,$c)" if { $c != $nc } { append var "\t" } else { append var "\n" } } for { set c 1 } { $c <= $nc } { incr c } { set len [string length $H(0,$c)] for { set d 1 } { $d <= $len } { incr d } { append var "-" } if { $c != $nc } { append var "\t" } else { append var "\n" } } } proc starbase_readfp { t fp } { upvar $t T starbase_header T $fp set NCols [starbase_ncols T] for { set r 1 } { [gets $fp line] != -1 } { incr r } { if { [string index $line 0] == "\f" } { global starbase_line set starbase_line [string range $line 1 end] break } set c 1 foreach val [split $line "\t"] { set T($r,$c) [string trim $val] incr c } for { } { $c <= $NCols } { incr c } { set T($r,$c) {} } } set T(Nrows) [expr $r-1] } proc starbase_read { t file } { upvar $t T set fp [open $file] starbase_readfp T $fp close $fp set T(filename) $file } proc starbase_writefp { t fp } { upvar $t T starbase_hdrput T $fp if { ![info exists T(Nrows)] || ($T(Nrows) == 0) } { return } set nr $T(Nrows) set nc $T(Ncols) for { set r 1 } { $r <= $nr } { incr r } { for { set c 1 } { $c < $nc } { incr c } { if { [catch { set val $T($r,$c) }] } { set val "" } puts -nonewline $fp "$val " } if { [catch { set val $T($r,$c) }] } { set val "" } puts $fp $val } } proc starbase_write { t file } { upvar $t T set fp [open $file w] starbase_writefp T $fp close $fp } proc starbase_write_ { t } { upvar $t T set rr {} starbase_hdrput_ T rr if { ![info exists T(Nrows)] || ($T(Nrows) == 0) } { return } set nr $T(Nrows) set nc $T(Ncols) for { set r 1 } { $r <= $nr } { incr r } { for { set c 1 } { $c < $nc } { incr c } { if { [catch { set val $T($r,$c) }] } { set val "" } append rr "$val " } if { [catch { set val $T($r,$c) }] } { set val "" } append rr "$val\n" } return $rr } proc starbase_rowins { t row } { upvar $t T incr T(Nrows) set nr $T(Nrows) set nc $T(Ncols) for { set r $nr } { $r > $row } { set r [expr $r-1] } { for { set c 1 } { $c <= $nc } { incr c } { if { [catch { set val $T([expr $r-1],$c) }] } { set val "" } set T($r,$c) $val } } for { set c 1 } { $c <= $nc } { incr c } { set T($r,$c) "" } } proc starbase_rowdel { t row } { upvar $t T incr T(Nrows) -1 set nr $T(Nrows) set nc $T(Ncols) for { set r $row } { $r <= $nr } { incr r } { for { set c 1 } { $c <= $nc } { incr c } { if { [catch { set val $T([expr $r+1],$c) }] } { set val "" } set T($r,$c) $val } } for { set c 1 } { $c <= $nc } { incr c } { set T($r,$c) "" } } proc starbase_httpreader { t wait sock http } { global $t global starbase_debug upvar #0 $wait W upvar #0 $t T set T(http) $http if { ![info exists T(state)] } { error "ERROR: starbase_httpreader not properly initialized" } switch -- $T(state) { 0 { fconfigure $sock -blocking 1 set T(state) 1 set T(Nrows) 0 set T(HLines) 0 } 1 { incr ${t}(HLines) set n $T(HLines) if { [gets $sock line] == -1 } { set T(state) -1 set T(HLines) [expr $T(HLines) - 1] set T(Nrows) 0 return } set T(H_$n) $line set l [split $line] if { [llength $l] > 1 } { set T(H_[lindex $l 0]) [lrange $l 1 end] } set T(H_$n) $line if { [regexp -- {^ *(-)+ *(\t *(-)+ *)*} $line] } { set T(Header) [split $T(H_[expr $n-1]) "\t"] set T(Dashes) [split $T(H_$n) "\t"] set T(Ndshs) [llength $T(Dashes)] starbase_colmap T set T(state) 2 } } 2 { if { [gets $sock line] == -1 } { set T(state) 0 } else { if { $starbase_debug } { puts [format "starbase_httpreader: %s" $line] } incr ${t}(Nrows) set r $T(Nrows) set NCols [starbase_ncols T] set c 1 foreach val [split $line "\t"] { set T($r,$c) $val incr c } for { } { $c <= $NCols } { incr c } { set T($r,$c) {} } } } default { error "ERROR: unknown switch in starbase_httpreader" } } } proc starbase_cancel { t wait http } { upvar #0 $wait W upvar #0 $t T # set T(state) 0 set W 1 } proc starbase_http { t url wait } { upvar #0 $t T set T(state) 0 set T(http) [http::geturl $url \ -handler [list starbase_httpreader $t $wait] \ -command [list starbase_cancel $t $wait]] } proc starbase_httpkill { t } { upvar #0 $t T http::reset $T(http) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catcdssrch.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000024557�12035363452�014537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATCDSSrchDef {} { global icatcdssrch set icatcdssrch(minrows) 11 set icatcdssrch(mincols) 2 set icatcdssrch(list,wave,param) {-kw.Wavelength} set icatcdssrch(list,wave) [list none Radio IR optical UV EUV X-ray Gamma-ray] set icatcdssrch(list,mission,param) {-kw.Mission} set icatcdssrch(list,mission) [list none ANS ASCA BeppoSAX CGRO Chandra COBE Copernicus Einstein EUVE EXOSAT FAUST FUSE GINGA GRANAT HEAO Hipparcos HST HUT INTEGRAL IRAS ISO IUE MSX OAO-2 ORFEUS ROSAT RXTE SAS-1 SAS-2 SIRTF SMM SOHO Swift TD1 UIT ULYSSES WMAP WUPPE XMM] set icatcdssrch(list,astro,param) {-kw.Astronomy} set icatcdssrch(list,astro) [list none Abundances Ages AGN Associations Atomic_Data Binaries:cataclysmic Binaries:eclipsing Binaries:spectroscopic BL_Lac_objects Blue_objects Clusters_of_galaxies Constellations Diameters Earth Ephemerides Equivalent_widths Extinction Galaxies Galaxies:Markarian Galaxies:spectra Globular_Clusters Gravitational_lensing HII_regions Interstellar_Medium Magnetic_fields Masers Masses Models Multiple_Stars Nebulae Nonstellar Novae Obs_Log Open_Clusters Orbits Parallaxes Photometry Photometry:intermediate-band Photometry:narrow-band Photometry:surface Photometry:wide-band Planetary_Nebulae Planets+Asteroids Polarization Positional_Data Proper_Motions Pulsars QSOs Redshifts Rotational_Velocities Seyfert_Galaxies Spectral_Classification Spectrophotometry Spectroscopy Stars Stars:early-typeStars:Emission Stars:late-type Stars:peculiar Stars:variable Stars:white_dwarf Stars:WR Sun SuperNovae SuperNovae_Remnants Velocities YSOs] } proc CATCDSSrchLoadFile {varname} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchLoad $varname" } if [info exists $var(catdb)] { unset $var(catdb) } set fn [OpenFileDialog catcdssrchfbox] if {$fn != {}} { if {[file exists $fn]} { starbase_read $var(catdb) $fn } else { Error "[msgcat::mc {Unable to open file}] $fn" return } CATCDSSrchTable $varname } } proc CATCDSSrchSaveFile {varname} { upvar #0 $varname var global $varname global $var(catdb) set fn [SaveFileDialog catcdssrchfbox] if {$fn != {}} { starbase_write $var(catdb) $fn } } proc CATCDSSrchClear {varname} { upvar #0 $varname var global $varname global $var(catdb) if [info exists $var(catdb)] { unset $var(catdb) } } proc CATCDSSrchCatalog {varname} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchCatalog $varname" } set row 0 foreach ss [$var(tbl) curselection] { set rr [lindex [split $ss ,] 0] if {$rr != $row} { set id [starbase_get $var(catdb) $rr 1] set title [starbase_get $var(catdb) $rr 2] if {$id != {}} { # can't use id, it may have / or + CATDialog catcds cds $id $title apply } set row $rr } } } proc CATCDSSrch {varname} { upvar #0 $varname var global $varname global pcat global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrch $varname" } # go for votable or tsv if {$pcat(vot)} { set var(proc,parser) CATCDSSrchVOTParse } else { set var(proc,reader) CATCDSSrchReader } #url set site [CATCDSURL $var(server)] set cgidir {viz-bin} if {$pcat(vot)} { set script {votable} } else { set script {asu-tsv} } set var(url) "http://$site/$cgidir/$script" # defaults set query {-meta} append query "&[http::formatQuery -out.max 1000]" if {$pcat(vot)} { append query "&[http::formatQuery -out.form VOTable]" } else { append query "&[http::formatQuery -out.form Tab-Separated-Values]" } if {$var(source) != {}} { append query "&[http::formatQuery -source $var(source)]" } if {$var(words) !={}} { append query "&[http::formatQuery -words $var(words)]" } if {$var(wave) !={}} { append query "&[http::formatQuery $var(list,wave,param) $var(wave)]" } if {$var(mission) !={}} { append query "&[http::formatQuery $var(list,mission,param) $var(mission)]" } if {$var(astro) !={}} { append query "&[http::formatQuery $var(list,astro,param) $var(astro)]" } set var(query) $query if {$pcat(vot)} { CATCDSSrchLoad $varname } else { CATCDSSrchLoadIncr $varname } } proc CATCDSSrchLoad {varname} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchLoad $varname" } if [info exists $var(catdb)] { unset $var(catdb) } set var(proc,done) CATCDSSrchDone set var(proc,load) CATCDSSrchLoad CATGetURL $varname return } proc CATCDSSrchLoadIncr {varname} { upvar #0 $varname var global $varname global $var(catdb) global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchLoadIncr $varname" } if [info exists $var(catdb)] { unset $var(catdb) } set var(proc,done) CATCDSSrchDone set var(proc,load) CATCDSSrchLoadIncr CATGetURLIncr $varname return } proc CATCDSSrchDone {varname} { upvar #0 $varname var global $varname CATCDSSrchTable $varname } proc CATCDSSrchReader {t sock token} { upvar #0 $t T global $t set result 0 if { ![info exists ${t}(state)] } { set T(state) 0 } switch -- $T(state) { 0 { # init db fconfigure $sock -blocking 1 set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 # create header incr ${t}(HLines) set n $T(HLines) set T(H_$n) "Resource\tDescription" set T(Header) [split $T(H_$n) "\t"] incr ${t}(HLines) set n $T(HLines) set T(H_$n) "--------\t-----------" set T(Dashes) [split $T(H_$n) "\t"] set T(Ndshs) [llength $T(Dashes)] starbase_colmap $t set T(state) 1 } 1 { # process RESOURCE if {[gets $sock line] == -1} { set T(state) 0 return $result } set result [string length "$line"] set line [string trim $line] if {$line != {}} { switch -- [string range $line 0 4] { "#RESO" { incr ${t}(Nrows) set r $T(Nrows) set T($r,1) {} set T($r,2) {} set T(state) 2 } } } } 2 { # process Description if {[gets $sock line] == -1} { set T(state) 0 return $result } set result [string length "$line"] set line [string trim $line] set r $T(Nrows) if {$line != {}} { switch -- [string range $line 0 4] { "#Name" { set T($r,1) [string trim [lindex [split $line {:}] 1]] set T(state) 3 } } } } 3 { # new style process description if {[gets $sock line] == -1} { set T(state) 0 return $result } set result [string length "$line"] set line [string trim $line] if {$line != {}} { switch -- [string range $line 0 4] { "#Titl" { # eat it } default { set r $T(Nrows) if {$r>0} { set val [string trim [string range $line 5 end]] catch {set T($r,2) "$val"} set T(state) 1 } } } } } } return $result } proc CATCDSSrchVOTParse {t token} { upvar #0 $t T global $t global debug if {$debug(tcl,cat)} { set fp [open debug.xml w] puts $fp [http::data $token] close $fp } set xml [xml::parser \ -characterdatacommand [list CATCDSSrchVOTCharCB $t] \ -elementstartcommand [list CATCDSSrchVOTElemStartCB $t] \ -elementendcommand [list CATCDSSrchVOTElemEndCB $t] \ -ignorewhitespace 1 \ ] set T(tree,state) {} set T(tree,prev) {} if [catch {$xml parse [http::data $token]} err] { if {$debug(tcl,cat)} { puts stderr "CATCDSSrchVOTParse: $err" } } $xml free } proc CATCDSSrchVOTCharCB {t data} { upvar #0 $t T global $t global debug switch -- $T(tree,state) { DESCRIPTION { set data [string trim $data] if {$data != {}} { switch -- $T(tree,prev) { RESOURCE { set r $T(Nrows) set T($r,2) [lindex [split $data "\n"] 0] set T(tree,prev) {} } } } } } # sometimes, we get a bogus call, (ignore whitespace does not work) set T(tree,state) {} return {} } proc CATCDSSrchVOTElemStartCB {t name attlist args} { upvar #0 $t T global $t global debug switch -- $name { VOTABLE { # init db set T(Nrows) 0 set T(Ncols) 0 set T(Header) {} set T(HLines) 0 # create header incr ${t}(HLines) set n $T(HLines) set T(H_$n) "Resource\tDescription" set T(Header) [split $T(H_$n) "\t"] incr ${t}(HLines) set n $T(HLines) set T(H_$n) "--------\t-----------" set T(Dashes) [regsub -all {[A-Za-z0-9]} $T(H_$n) {-}] set T(Ndshs) [llength $T(Header)] starbase_colmap $t } RESOURCE { set fname {} set id {} set type {} foreach {key value} $attlist { switch -- [string tolower $key] { name {set fname "$value"} id {set id "$value"} type {set type $value} } } incr ${t}(Nrows) set r $T(Nrows) set T($r,1) $fname set T($r,2) {} set T(tree,prev) $name } } set ${t}(tree,state) $name return {} } proc CATCDSSrchVOTElemEndCB {t name args} { upvar #0 $t T global $t global debug # we can't count on this being called for all end-tags switch -- $name { VOTABLE { # ok, we're done return -code break } } return {} } proc CATCDSSrchTable {varname} { upvar #0 $varname var global $varname global $var(catdb) global icatcdssrch global debug if {$debug(tcl,cat)} { puts stderr "CATCDSSrchTable $varname" } # starbase_writefp $var(catdb) stdout global $var(catdb) $var(tbl) configure -variable $var(catdb) if {[starbase_nrows $var(catdb)] == 0} { ARStatus $varname [msgcat::mc {No Items Found}] return } set nc [starbase_ncols $var(catdb)] $var(tbl) configure -cols $nc # add header row set nr [expr [starbase_nrows $var(catdb)]+1] if {$nr > $icatcdssrch(minrows)} { $var(tbl) configure -rows $nr } else { $var(tbl) configure -rows $icatcdssrch(minrows) } ARStatus $varname "[starbase_nrows $var(catdb)] [msgcat::mc {Items Found}]" } �������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/scale.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000063350�12131573630�013475� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc ScaleDef {} { global scale global iscale global pscale set iscale(top) .scale set iscale(mb) .scalemb set scale(min) 1 set scale(max) 100 set scale(xaxis) full set scale(yaxis) log set scale(preserve) 0 set scale(lock) 0 set scale(type) linear set scale(log) 1000 set scale(mode) minmax set scale(scope) local set scale(datasec) 1 set pscale(preserve) $scale(preserve) set pscale(type) $scale(type) set pscale(log) $scale(log) set pscale(mode) $scale(mode) set pscale(scope) $scale(scope) set pscale(datasec) $scale(datasec) } proc MinMaxDef {} { global minmax global pminmax set minmax(mode) auto set minmax(sample) 25 array set pminmax [array get minmax] } proc ZScaleDef {} { global zscale global pzscale set zscale(contrast) .25 set zscale(sample) 600 set zscale(line) 120 array set pzscale [array get zscale] } proc ChangeDATASEC {} { global current global scale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) datasec $scale(datasec)] UpdateScale } } proc ChangeScale {} { global current global scale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) colorscale log $scale(log)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) colorscale $scale(type)] UpdateScale } } proc ChangeScaleMode {} { global current global scale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip mode $scale(mode)] UpdateScale } } proc ChangeScaleLimit {} { global current global scale global rgb if {$current(frame) != {}} { set scale(mode) user RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip user $scale(min) $scale(max)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip mode $scale(mode)] UpdateScale } } proc ChangeScaleScope {} { global current global scale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip scope $scale(scope)] UpdateScale } } proc PreserveScale {} { global current global scale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip preserve $scale(preserve)] UpdateScale } } proc ChangeMinMax {} { global current global minmax global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip minmax mode $minmax(mode)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip minmax sample $minmax(sample)] UpdateScale } } proc ChangeZScale {} { global current global zscale global rgb if {$current(frame) != {}} { RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip zscale contrast $zscale(contrast)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip zscale sample $zscale(sample)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip zscale line $zscale(line)] UpdateScale } } proc UpdateScale {} { global current global debug if {$debug(tcl,update)} { puts stderr "UpdateScale" } LockScaleCurrent UpdateScaleMenu UpdateScaleDialog UpdateContourScale UpdateGraphYAxis $current(frame) UpdateMain } proc ScaleDialog {} { global scale global iscale global dscale global current global ds9 global minmax global canvas # see if we already have a window visible if [winfo exists $iscale(top)] { raise $iscale(top) return } # create the window set w $iscale(top) set mb $iscale(mb) Toplevel $w $mb 6 [msgcat::mc {Scale Parameters}] ScaleDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Scale}] -menu $mb.scale $mb add cascade -label [msgcat::mc {Limits}] -menu $mb.limit $mb add cascade -label [msgcat::mc {Scope}] -menu $mb.scope $mb add cascade -label [msgcat::mc {Min Max}] -menu $mb.minmax $mb add cascade -label [msgcat::mc {Parameters}] -menu $mb.param $mb add cascade -label [msgcat::mc {Graph}] -menu $mb.graph menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command ScaleApplyDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command ScaleDestroyDialog EditMenu $mb iscale menu $mb.scale $mb.scale add radiobutton -label [msgcat::mc {Linear}] \ -variable scale(type) -command ChangeScale -value linear $mb.scale add radiobutton -label [msgcat::mc {Log}] \ -variable scale(type) -command ChangeScale -value log $mb.scale add radiobutton -label [msgcat::mc {Power}] \ -variable scale(type) -command ChangeScale -value pow $mb.scale add radiobutton -label [msgcat::mc {Square Root}] \ -variable scale(type) -command ChangeScale -value sqrt $mb.scale add radiobutton -label [msgcat::mc {Squared}] \ -variable scale(type) -command ChangeScale -value squared $mb.scale add radiobutton -label {ASINH} \ -variable scale(type) -command ChangeScale -value asinh $mb.scale add radiobutton -label {SINH} \ -variable scale(type) -command ChangeScale -value sinh $mb.scale add radiobutton -label [msgcat::mc {Histogram Equalization}] \ -variable scale(type) -command ChangeScale -value histequ $mb.scale add separator $mb.scale add command -label "[msgcat::mc {Log Exponent}]..." \ -command ScaleLogDialog menu $mb.limit $mb.limit add radiobutton -label [msgcat::mc {Min Max}] \ -variable scale(mode) -command ChangeScaleMode -value minmax $mb.limit add separator $mb.limit add radiobutton -label {99.5%} \ -variable scale(mode) -command ChangeScaleMode -value 99.5 $mb.limit add radiobutton -label {99%} \ -variable scale(mode) -command ChangeScaleMode -value 99 $mb.limit add radiobutton -label {98%} \ -variable scale(mode) -command ChangeScaleMode -value 98 $mb.limit add radiobutton -label {97%} \ -variable scale(mode) -command ChangeScaleMode -value 97 $mb.limit add radiobutton -label {96%} \ -variable scale(mode) -command ChangeScaleMode -value 96 $mb.limit add radiobutton -label {95%} \ -variable scale(mode) -command ChangeScaleMode -value 95 $mb.limit add radiobutton -label {92.5%} \ -variable scale(mode) -command ChangeScaleMode -value 92.5 $mb.limit add radiobutton -label {90%} \ -variable scale(mode) -command ChangeScaleMode -value 90 $mb.limit add separator $mb.limit add radiobutton -label {ZScale} \ -variable scale(mode) -command ChangeScaleMode -value zscale $mb.limit add radiobutton -label {ZMax} \ -variable scale(mode) -command ChangeScaleMode -value zmax $mb.limit add radiobutton -label [msgcat::mc {User}] \ -variable scale(mode) -command ChangeScaleMode -value user menu $mb.scope $mb.scope add radiobutton -label [msgcat::mc {Global}] \ -variable scale(scope) -command ChangeScaleScope -value global $mb.scope add radiobutton -label [msgcat::mc {Local}] \ -variable scale(scope) -command ChangeScaleScope -value local menu $mb.minmax $mb.minmax add radiobutton -label [msgcat::mc {Automatic}] \ -variable minmax(mode) -value auto -command ChangeMinMax $mb.minmax add radiobutton -label [msgcat::mc {Scan}] \ -variable minmax(mode) -value scan -command ChangeMinMax $mb.minmax add radiobutton -label [msgcat::mc {Sample}] \ -variable minmax(mode) -value sample -command ChangeMinMax $mb.minmax add radiobutton -label {DATAMIN DATAMAX} \ -variable minmax(mode) -value datamin -command ChangeMinMax $mb.minmax add radiobutton -label {IRAF-MIN IRAF-MAX} \ -variable minmax(mode) -value irafmin -command ChangeMinMax $mb.minmax add separator $mb.minmax add command -label "[msgcat::mc {Sample Parameters}]..." \ -command MinMaxDialog menu $mb.param $mb.param add checkbutton -label "[msgcat::mc {Use}] DATASEC" \ -variable scale(datasec) -command ChangeDATASEC $mb.param add separator $mb.param add command -label {ZScale...} -command ZScaleDialog menu $mb.graph $mb.graph add radiobutton -label [msgcat::mc {Linear}] \ -value linear -variable scale(yaxis) -command ScaleYAxisDialog $mb.graph add radiobutton -label [msgcat::mc {Log}] \ -value log -variable scale(yaxis) -command ScaleYAxisDialog $mb.graph add separator $mb.graph add radiobutton -label [msgcat::mc {Full Range}] \ -value full -variable scale(xaxis) -command ScaleXAxisDialog $mb.graph add radiobutton -label [msgcat::mc {Current Range}] \ -value current -variable scale(xaxis) -command ScaleXAxisDialog # Param set f [ttk::frame $w.param] # Graph set dscale(hist) [blt::barchart $f.chart \ -width 500 -height 200 \ -title [msgcat::mc {Pixel Distribution}] \ -plotrelief groove \ -plotborderwidth 2 \ -font [font actual TkDefaultFont] \ ] $dscale(hist) legend configure -hide yes $dscale(hist) xaxis configure -hide yes -grid no -ticklength 3 \ -tickfont [font actual TkDefaultFont] $dscale(hist) yaxis configure -hide yes -grid yes -ticklength 3 \ -tickfont [font actual TkDefaultFont] set dscale(xdata) histX set dscale(ydata) histY blt::vector create $dscale(xdata) $dscale(ydata) $dscale(hist) element create bar1 \ -xdata $dscale(xdata) -ydata $dscale(ydata) \ -relief flat -foreground #000001 -background #000001 # Cut Lines $dscale(hist) marker bind min <B1-Motion> \ [list ScaleMotionDialog %x %y dscale(min)] $dscale(hist) marker bind max <B1-Motion> \ [list ScaleMotionDialog %x %y dscale(max)] $dscale(hist) marker bind up <ButtonRelease-1> ScaleReleaseDialog set dscale(histmin) [$dscale(hist) marker create line -element bar1 \ -outline red -bindtags [list min up]] set dscale(histmax) [$dscale(hist) marker create line -element bar1 \ -outline green -bindtags [list max up]] # Cut Levels ttk::label $f.title -text [msgcat::mc {Limits}] ttk::label $f.ltitle -text [msgcat::mc {Low}] ttk::entry $f.lvalue -textvariable dscale(min) -width 13 ttk::label $f.htitle -text [msgcat::mc {High}] ttk::entry $f.hvalue -textvariable dscale(max) -width 13 pack $dscale(hist) -fill both -expand true pack $f.title $f.ltitle $f.lvalue $f.htitle $f.hvalue \ -side left -padx 2 -pady 2 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command ScaleApplyDialog ttk::button $f.close -text [msgcat::mc {Close}] -command ScaleDestroyDialog pack $f.apply $f.close -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true UpdateScaleDialog } proc ScaleApplyDialog {} { global scale global dscale global current global rgb if {$current(frame) != {} && $dscale(min) != {} && $dscale(max) != {}} { $dscale(hist) marker configure $dscale(histmin) \ -coords "$dscale(min) -Inf $dscale(min) Inf" $dscale(hist) marker configure $dscale(histmax) \ -coords "$dscale(max) -Inf $dscale(max) Inf" set scale(min) $dscale(min) set scale(max) $dscale(max) set scale(mode) user RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip user $scale(min) $scale(max)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip mode $scale(mode)] UpdateScale } } proc ScaleDestroyDialog {} { global scale global iscale global dscale if {[winfo exists $iscale(top)]} { destroy $iscale(top) destroy $iscale(mb) } blt::vector destroy $dscale(xdata) $dscale(ydata) unset dscale } proc ScaleMotionDialog {x y varname} { upvar $varname var global scale global dscale set var [lindex [$dscale(hist) invtransform $x $y] 0] if {$dscale(min) > $dscale(max)} { if {$varname == "dscale(min)"} { set var $dscale(max) } else { set var $dscale(min) } } $dscale(hist) marker configure $dscale(histmin) \ -coords "$dscale(min) -Inf $dscale(min) Inf" $dscale(hist) marker configure $dscale(histmax) \ -coords "$dscale(max) -Inf $dscale(max) Inf" } proc ScaleReleaseDialog {} { global scale global dscale global current global rgb if {$current(frame) != {} && $dscale(min) != {} && $dscale(max) != {}} { set scale(min) $dscale(min) set scale(max) $dscale(max) set scale(mode) user RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip user $scale(min) $scale(max)] RGBEvalLockCurrent rgb(lock,scale) [list $current(frame) clip mode $scale(mode)] UpdateScale ScaleXAxisDialog } } proc UpdateScaleDialog {} { global scale global iscale global dscale global current global debug if {$debug(tcl,update)} { puts stderr "UpdateScaleDialog" } if {![winfo exists $iscale(top)]} { return } set dscale(min) {} set dscale(max) {} if {$current(frame) != {}} { set limits [$current(frame) get clip] set dscale(min) [lindex $limits 0] set dscale(max) [lindex $limits 1] if {[$current(frame) has fits] & ![$current(frame) has iis]} { set limits [$current(frame) get minmax] set dscale(minmin) [lindex $limits 0] set dscale(minmax) [lindex $limits 1] $current(frame) get histogram $dscale(xdata) $dscale(ydata) # we seem to need to do this so that the min/max values are known blt::vector expr min($dscale(ydata)) blt::vector expr max($dscale(ydata)) $dscale(hist) element configure bar1 -hide no set stepsize [format "%.4g" \ [expr ($dscale(minmin)-$dscale(minmax))/4.]] $dscale(hist) xaxis configure -hide no -stepsize $stepsize $dscale(hist) yaxis configure -hide no -min 1 $dscale(hist) marker configure $dscale(histmin) \ -coords "$dscale(min) -Inf $dscale(min) Inf" $dscale(hist) marker configure $dscale(histmax) \ -coords "$dscale(max) -Inf $dscale(max) Inf" if {[$current(frame) has fits mosaic] || \ [$current(frame) has fits cube]} { $iscale(mb) entryconfig [msgcat::mc {Scope}] -state normal } else { $iscale(mb) entryconfig [msgcat::mc {Scope}] -state disabled } if [$current(frame) has datamin] { $iscale(mb).minmax \ entryconfig {DATAMIN DATAMAX} -state normal } else { $iscale(mb).minmax \ entryconfig {DATAMIN DATAMAX} -state disabled } if [$current(frame) has irafmin] { $iscale(mb).minmax \ entryconfig {IRAF-MIN IRAF-MAX} -state normal } else { $iscale(mb).minmax \ entryconfig {IRAF-MIN IRAF-MAX} -state disabled } ScaleYAxisDialog ScaleXAxisDialog return } } $dscale(hist) element configure bar1 -hide yes $dscale(hist) xaxis configure -hide yes $dscale(hist) yaxis configure -hide yes $iscale(mb) entryconfig [msgcat::mc {Scope}] -state normal $iscale(mb).minmax entryconfig {DATAMIN DATAMAX} -state normal $iscale(mb).minmax entryconfig {IRAF-MIN IRAF-MAX} -state normal } proc UpdateScaleDialogFont {} { global iscale global dscale if {![winfo exists $iscale(top)]} { return } $dscale(hist) configure -font [font actual TkDefaultFont] $dscale(hist) xaxis configure -tickfont [font actual TkDefaultFont] $dscale(hist) yaxis configure -tickfont [font actual TkDefaultFont] } proc ScaleYAxisDialog {} { global scale global dscale switch -- $scale(yaxis) { linear {$dscale(hist) yaxis configure -logscale 0 -min 0} log {$dscale(hist) yaxis configure -logscale 1 -min 1} } } proc ScaleXAxisDialog {} { global scale global dscale switch -- $scale(xaxis) { full { set width [expr abs(1.0*($dscale(minmax)-$dscale(minmin))/ \ [$dscale(xdata) length])] $dscale(hist) element configure bar1 -barwidth $width $dscale(hist) xaxis configure \ -min [expr $dscale(minmin)-$width] \ -max [expr $dscale(minmax)+$width] } current { set width [expr abs(1.0*($dscale(max)-$dscale(min))/ \ [$dscale(xdata) length])] $dscale(hist) element configure bar1 -barwidth $width if {[expr abs($dscale(max)-$dscale(min)) > 0]} { set diff [expr $dscale(max)-$dscale(min)] set per .10 set a [expr $dscale(min)-($diff*$per)] set b [expr $dscale(max)+($diff*$per)] $dscale(hist) xaxis configure -min $a -max $b } } } } proc ScaleLogDialog {} { global scale if {[EntryDialog [msgcat::mc {Scale}] [msgcat::mc {Log Exponent}] 10 scale(log)]} { ChangeScale } } proc MinMaxDialog {} { global minmax if {[MinMaxTemplate minmax]} { ChangeMinMax } } proc MinMaxTemplate {varname} { upvar $varname var global $varname global ed set w {.sample} set ed(ok) 0 array set ed [array get ${varname}] DialogCreate $w [msgcat::mc {Sample Parameters}] ed(ok) # Param set f [ttk::frame $w.param] slider $f.ssample 0 1000 [msgcat::mc {Sample Increment}] ed(sample) {} grid $f.ssample -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { if {$ed(sample) == 0} { set ed(sample) 1 } array set ${varname} [array get ed] } set rr $ed(ok) unset ed return $rr } proc ZScaleDialog {} { global zscale if {[ZScaleTemplate zscale]} { ChangeZScale } } proc ZScaleTemplate {varname} { upvar $varname var global $varname global ed set w {.zscale} set ed(ok) 0 array set ed [array get ${varname}] DialogCreate $w "ZScale [msgcat::mc {Parameters}]" ed(ok) # Param set f [ttk::frame $w.param] slider $f.scontrast 0. 1. [msgcat::mc {Contrast}] ed(contrast) {} slider $f.ssize 0 1000 [msgcat::mc {Number of Samples}] ed(sample) {} slider $f.sline 0 500 [msgcat::mc {Samples per Line}] ed(line) {} grid $f.scontrast -padx 2 -pady 2 -sticky ew grid $f.ssize -padx 2 -pady 2 -sticky ew grid $f.sline -padx 2 -pady 2 -sticky ew grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) DialogDismiss $w if {$ed(ok)} { if {$ed(line) == 0} { set ed(line) 1 } array set ${varname} [array get ed] } set rr $ed(ok) unset ed return $rr } proc MatchScaleCurrent {} { global current if {$current(frame) != {}} { MatchScale $current(frame) } } proc MatchScale {which} { global ds9 global rgb set type [$which get colorscale] set log [$which get colorscale log] set limits [$which get clip] set mode [$which get clip mode] set scope [$which get clip scope] set mmmode [$which get clip minmax mode] set mmsample [$which get clip minmax sample] set zscontrast [$which get clip zscale contrast] set zssample [$which get clip zscale sample] set zsline [$which get clip zscale line] set preserve [$which get clip preserve] foreach ff $ds9(frames) { if {$ff != $which} { RGBEvalLock rgb(lock,scale) $ff [list $ff colorscale $type] RGBEvalLock rgb(lock,scale) $ff [list $ff colorscale log $log] RGBEvalLock rgb(lock,scale) $ff [list $ff clip user $limits] RGBEvalLock rgb(lock,scale) $ff [list $ff clip mode $mode] RGBEvalLock rgb(lock,scale) $ff [list $ff clip scope $scope] RGBEvalLock rgb(lock,scale) $ff [list $ff clip minmax mode $mmmode] RGBEvalLock rgb(lock,scale) $ff [list $ff clip minmax sample $mmsample] RGBEvalLock rgb(lock,scale) $ff [list $ff clip zscale contrast $zscontrast] RGBEvalLock rgb(lock,scale) $ff [list $ff clip zscale sample $zssample] RGBEvalLock rgb(lock,scale) $ff [list $ff clip zscale line $zsline] RGBEvalLock rgb(lock,scale) $ff [list $ff clip preserve $preserve] } } } proc LockScaleCurrent {} { global current if {$current(frame) != {}} { LockScale $current(frame) } } proc LockScale {which} { global scale if {$scale(lock)} { MatchScale $which } } proc ScaleBackup {ch which} { switch -- [$which get type] { base - 3d {ScaleBackupBase $ch $which} rgb {ScaleBackupRGB $ch $which} } } proc ScaleBackupBase {ch which} { puts $ch "$which colorscale [$which get colorscale]" puts $ch "$which colorscale log [$which get colorscale log]" puts $ch "$which datasec [$which get datasec]" puts $ch "$which clip user [$which get clip]" puts $ch "$which clip mode [$which get clip mode]" puts $ch "$which clip scope [$which get clip scope]" puts $ch "$which clip minmax mode [$which get clip minmax mode]" puts $ch "$which clip minmax sample [$which get clip minmax sample]" puts $ch "$which clip zscale contrast [$which get clip zscale contrast]" puts $ch "$which clip zscale sample [$which get clip zscale sample]" puts $ch "$which clip zscale line [$which get clip zscale line]" puts $ch "$which clip preserve [$which get clip preserve]" } proc ScaleBackupRGB {ch which} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" ScaleBackupBase $ch $which } $which rgb channel $sav puts $ch "$which rgb channel $sav" } # Process Cmds proc ProcessScaleCmd {varname iname} { upvar $varname var upvar $iname i global scale switch -- [string tolower [lindex $var $i]] { match {MatchScaleCurrent} lock { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set scale(lock) [FromYesNo [lindex $var $i]] } else { set scale(lock) 1 incr i -1 } LockScaleCurrent } open {ScaleDialog} close {ScaleDestroyDialog} linear - pow - sqrt - squared - asinh - sinh - histequ { set scale(type) [string tolower [lindex $var $i]] ChangeScale } log { incr i switch -- [string tolower [lindex $var $i]] { exp { incr i set scale(log) [string tolower [lindex $var $i]] ChangeScale } default { incr i -1 set scale(type) [string tolower [lindex $var $i]] ChangeScale } } } datasec { incr i set scale(datasec) [FromYesNo [lindex $var $i]] ChangeDATASEC } limits { incr i set scale(min) [lindex $var $i] incr i set scale(max) [lindex $var $i] ChangeScaleLimit } minmax - zscale - zmax - user { set scale(mode) [string tolower [lindex $var $i]] ChangeScaleMode } mode { incr i set scale(mode) [string tolower [lindex $var $i]] ChangeScaleMode } local - global { set scale(scope) [string tolower [lindex $var $i]] ChangeScaleScope } scope { incr i set scale(scope) [string tolower [lindex $var $i]] ChangeScaleScope } } } proc ProcessSendScaleCmd {proc id param} { global current global scale switch -- [string tolower $param] { lock {$proc $id [ToYesNo $scale(lock)]} datasec {$proc $id "$scale(datasec)\n"} limits { if {$current(frame) != {}} { set lims [$current(frame) get clip] $proc $id "[lindex $lims 0] [lindex $lims 1]\n" } } mode {$proc $id "$scale(mode)\n"} scope {$proc $id "$scale(scope)\n"} log - {log exp} {$proc $id "$scale(log)\n"} default {$proc $id "$scale(type)\n"} } } proc ProcessMinMaxCmd {varname iname} { upvar $varname var upvar $iname i global minmax global scale switch -- [string tolower [lindex $var $i]] { auto - scan - sample - datamin - irafmin { set minmax(mode) [string tolower [lindex $var $i]] ChangeMinMax } mode { incr i set minmax(mode) [string tolower [lindex $var $i]] ChangeMinMax } interval { incr i set minmax(sample) [lindex $var $i] ChangeMinMax } default { # for backward compatibility set scale(mode) minmax ChangeScaleMode incr i -1 } } } proc ProcessSendMinMaxCmd {proc id param} { global minmax switch -- [string tolower $param] { mode {$proc $id "$minmax(mode)\n"} interval {$proc $id "$minmax(sample)\n"} default { # for backward compatibility $proc $id "$minmax(mode)\n" } } } proc ProcessZScaleCmd {varname iname} { upvar $varname var upvar $iname i global zscale global scale switch -- [string tolower [lindex $var $i]] { contrast { incr i set zscale(contrast) [lindex $var $i] ChangeZScale } sample { incr i set zscale(sample) [lindex $var $i] ChangeZScale } line { incr i set zscale(line) [lindex $var $i] ChangeZScale } default { # for backward compatibility set scale(mode) zscale ChangeScaleMode incr i -1 } } } proc ProcessSendZScaleCmd {proc id param} { global zscale switch -- [string tolower $param] { contrast {$proc $id "$zscale(contrast)\n"} sample {$proc $id "$zscale(sample)\n"} line {$proc $id "$zscale(line)\n"} } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/crosshair.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000007052�11757735115�014413� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CrosshairDef {} { global crosshair set crosshair(lock) none } proc ButtonCrosshair {which x y} { global ds9 global crosshair $which crosshair canvas $x $y LockCrosshair $which } proc ArrowKeyCrosshair {which x y} { global ds9 global crosshair $which crosshair warp $x $y LockCrosshair $which set coord [$which get crosshair canvas] set X [lindex $coord 0] set Y [lindex $coord 1] UpdateColormapLevelMosaic $which $X $Y canvas UpdateInfoBox $which $X $Y canvas UpdatePixelTableDialog $which $X $Y canvas UpdateGraph $which $X $Y canvas } proc MatchCrosshairCurrent {sys} { global current if {$current(frame) != {}} { MatchCrosshair $current(frame) $sys } } proc MatchCrosshair {which sys} { global crosshair global ds9 global current if {$current(mode) != {crosshair}} { return } switch -- $sys { image - physical - amplifier - detector { set coord [$which get crosshair $sys scientific] foreach ff $ds9(frames) { if {$ff != $which} { $ff crosshair $sys $coord } } } wcs { set ss [lindex [$which get wcs] 0] if {[$which has wcs $ss]} { set coord [$which get crosshair $ss scientific] foreach ff $ds9(frames) { if {$ff != $which} { if {[$ff has wcs $ss]} { $ff crosshair $ss $coord } } } } } } } proc LockCrosshairCurrent {} { global current if {$current(frame) != {}} { LockCrosshair $current(frame) } } proc LockCrosshair {which} { global crosshair switch -- $crosshair(lock) { none {} default {MatchCrosshair $which $crosshair(lock)} } } proc ProcessCrosshairCmd {varname iname} { upvar $varname var upvar $iname i global current global ds9 global crosshair # we need to be realized ProcessRealizeDS9 switch -- [string tolower [lindex $var $i]] { match { incr i MatchCrosshairCurrent [lindex $var $i] } lock { incr i set crosshair(lock) [lindex $var $i] LockCrosshairCurrent } default { set x [lindex $var [expr $i+0]] set y [lindex $var [expr $i+1]] set sys [lindex $var [expr $i+2]] set sky [lindex $var [expr $i+3]] set format {} incr i 1 incr i [FixSpec sys sky format physical fk5 degrees] set current(mode) crosshair ChangeMode if {$current(frame) != {}} { $current(frame) crosshair $sys $sky $x $y set coord [$current(frame) get crosshair canvas] UpdateColormapLevelMosaic $current(frame) \ [lindex $coord 0] [lindex $coord 1] canvas UpdateInfoBox $current(frame) \ [lindex $coord 0] [lindex $coord 1] canvas if {$crosshair(lock) != "none"} { set coord [$current(frame) get crosshair $crosshair(lock) scientific] foreach f $ds9(frames) { if {$f != $current(frame) && [$f has system $crosshair(lock)]} { $f crosshair $crosshair(lock) $coord } } } } } } } proc ProcessSendCrosshairCmd {proc id param} { global crosshair global current switch -- [string tolower $param] { lock {$proc $id "$crosshair(lock)\n"} default { set sys [lindex $param 0] set sky [lindex $param 1] set format [lindex $param 2] FixSpec sys sky format physical fk5 degrees if {$current(frame) != {}} { $proc $id "[$current(frame) get crosshair $sys $sky $format]\n" } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/analysisparam.tcl����������������������������������������������������������������������0000644�0001750�0001750�00000010665�11700665566�015266� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc AnalysisParam {strname param} { upvar $strname str global ianalysis global ed global ds9 global pds9 # find it for {set i 0} {$i<$ianalysis(param,count)} {incr i} { if {$ianalysis(param,$i) == "$param"} { break } } if {$i == $ianalysis(param,count)} { return } set w {.param} set ed(ok) 0 DialogCreate $w $param ed(ok) # Param set f [ttk::frame $w.param] for {set j 0} {$j<$ianalysis(param,$i,count)} {incr j} { set ianalysis(param,$i,$j,value) $ianalysis(param,$i,$j,last) ttk::label $f.l$j -text "$ianalysis(param,$i,$j,title)" switch -- $ianalysis(param,$i,$j,type) { entry { ttk::entry $f.a$j \ -textvariable ianalysis(param,$i,$j,value) \ -width 40 } checkbox { ttk::checkbutton $f.a$j -text {} \ -variable ianalysis(param,$i,$j,value) } menu { set l [split $ianalysis(param,$i,$j,default) |] ttk::menubutton $f.a$j \ -text "$ianalysis(param,$i,$j,value)" \ -menu $f.a$j.menu set m [menu $f.a$j.menu] for {set k 0} {$k<[llength $l]} {incr k} { $m add command -label [lindex $l $k] \ -command "AnalysisParamMenu ianalysis(param,$i,$j,value) [lindex $l $k] $f.a$j" } } } ttk::label $f.i$j -text "$ianalysis(param,$i,$j,info)" \ -font "{$ds9(times)} $pds9(font,size) normal italic" grid $f.l$j $f.a$j $f.i$j -padx 2 -pady 2 -sticky w } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok DialogDismiss $w if {$ed(ok)} { for {set j 0} {$j<$ianalysis(param,$i,count)} {incr j} { set exp "\\\$$ianalysis(param,$i,$j,var)" if {[regexp $exp $str]} { regsub -all $exp $str "$ianalysis(param,$i,$j,value)" str } set ianalysis(param,$i,$j,last) $ianalysis(param,$i,$j,value) } } set rr $ed(ok) unset ed return $rr } proc AnalysisParamMenu {varname value menu} { upvar $varname var set var $value $menu configure -text $value } proc ParseIRAFParam {filename} { global ianalysis global env # we are only concerned with unix like os set uparm {} if {[info exists env(UPARM)]} { set uparm "$env(UPARM)/$filename" } set iraf {} if {[info exists env(HOME)]} { set iraf "$env(HOME)/$filename" } if {[file exists "$filename"]} { catch {set ch [open "$filename"]} } elseif {[file exists "$uparm"]} { catch {set ch [open "$uparm"]} } elseif {[file exists "$iraf"]} { catch {set ch [open "$iraf"]} } else { return } set i $ianalysis(param,count) while {[gets $ch line] >= 0} { set exp {([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*)} if {[regexp $exp $line foo p1 p2 p3 p4 p5 p6 p7]} { if {$p1 != {mode}} { regsub -all {\"} $p4 {} p4 regsub -all {\"} $p7 {} p7 set j $ianalysis(param,$i,count) set ianalysis(param,$i,$j,var) "$p1" if {$p3 == {h}} { set ianalysis(param,$i,$j,title) "(${p1})" } else { set ianalysis(param,$i,$j,title) "$p1" } set ianalysis(param,$i,$j,info) "$p7" incr ianalysis(param,$i,count) switch -- $p2 { b { set ianalysis(param,$i,$j,type) checkbox set ianalysis(param,$i,$j,default) [FromYesNo $p4] set ianalysis(param,$i,$j,last) [FromYesNo $p4] set ianalysis(param,$i,$j,value) [FromYesNo $p4] } s { if {$p5 != {}} { set ianalysis(param,$i,$j,type) menu set ianalysis(param,$i,$j,default) "$p5" } else { set ianalysis(param,$i,$j,type) entry set ianalysis(param,$i,$j,default) "$p4" } set ianalysis(param,$i,$j,last) "$p4" set ianalysis(param,$i,$j,value) "$p4" } default { set ianalysis(param,$i,$j,type) entry set ianalysis(param,$i,$j,default) "$p4" set ianalysis(param,$i,$j,last) "$p4" set ianalysis(param,$i,$j,value) "$p4" } } } } } close $ch } ���������������������������������������������������������������������������./saods9/src/mview.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000032164�11700665571�013543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc ViewMainMenu {} { global ds9 menu $ds9(mb).view $ds9(mb).view add radiobutton -label [msgcat::mc {Horizontal Layout}] \ -variable view(layout) -value horizontal -command {LayoutOrient} $ds9(mb).view add radiobutton -label [msgcat::mc {Vertical Layout}] \ -variable view(layout) -value vertical -command {LayoutOrient} $ds9(mb).view add separator $ds9(mb).view add checkbutton -label [msgcat::mc {Information Panel}] \ -variable view(info) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Panner}] \ -variable view(panner) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Magnifier}] \ -variable view(magnifier) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Buttons}] \ -variable view(buttons) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Colorbar}] \ -variable view(colorbar) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Horizontal Graph}] \ -variable view(graph,horz) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Vertical Graph}] \ -variable view(graph,vert) -command UpdateView $ds9(mb).view add separator $ds9(mb).view add checkbutton -label [msgcat::mc {Filename}] \ -variable view(info,filename) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Object}] \ -variable view(info,object) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Min Max}] \ -variable view(info,minmax) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Low High}] \ -variable view(info,lowhigh) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Frame Information}] \ -variable view(info,frame) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {WCS}] \ -variable view(info,wcs) -command UpdateView $ds9(mb).view add cascade -label [msgcat::mc {Multiple WCS}] \ -menu $ds9(mb).view.mwcs $ds9(mb).view add checkbutton -label [msgcat::mc {Image}] \ -variable view(info,image) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Physical}] \ -variable view(info,physical) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Amplifier}] \ -variable view(info,amplifier) -command UpdateView $ds9(mb).view add checkbutton -label [msgcat::mc {Detector}] \ -variable view(info,detector) -command UpdateView # View Info Panel WCS menu $ds9(mb).view.mwcs foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $ds9(mb).view.mwcs add checkbutton \ -label "[msgcat::mc {WCS}] $l" \ -variable "view(info,wcs$l)" \ -command UpdateView } } proc PrefsDialogViewMenu {w} { set f [ttk::labelframe $w.mview -text [msgcat::mc {View}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarView $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add radiobutton -label [msgcat::mc {Horizontal Layout}] \ -variable pview(layout) -value horizontal $m add radiobutton -label [msgcat::mc {Vertical Layout}] \ -variable pview(layout) -value vertical $m add separator $m add checkbutton -label [msgcat::mc {Information Panel}] \ -variable pview(info) $m add checkbutton -label [msgcat::mc {Panner}] \ -variable pview(panner) $m add checkbutton -label [msgcat::mc {Magnifier}] \ -variable pview(magnifier) $m add checkbutton -label [msgcat::mc {Buttons}] \ -variable pview(buttons) $m add checkbutton -label [msgcat::mc {Colorbar}] \ -variable pview(colorbar) $m add checkbutton -label [msgcat::mc {Horizontal Graph}] \ -variable pview(graph,horz) $m add checkbutton -label [msgcat::mc {Vertical Graph}] \ -variable pview(graph,vert) $m add separator $m add checkbutton -label [msgcat::mc {Filename}] \ -variable pview(info,filename) $m add checkbutton -label [msgcat::mc {Object}] \ -variable pview(info,object) $m add checkbutton -label [msgcat::mc {Min Max}] \ -variable pview(info,minmax) $m add checkbutton -label [msgcat::mc {Low High}] \ -variable pview(info,lowhigh) $m add checkbutton -label [msgcat::mc {Frame Information}]\ -variable pview(info,frame) $m add checkbutton -label [msgcat::mc {WCS}] \ -variable pview(info,wcs) $m add cascade -label [msgcat::mc {Multiple WCS}] -menu $m.wcs $m add checkbutton -label [msgcat::mc {Image}] \ -variable pview(info,image) $m add checkbutton -label [msgcat::mc {Physical}] \ -variable pview(info,physical) $m add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pview(info,amplifier) $m add checkbutton -label [msgcat::mc {Detector}] \ -variable pview(info,detector) menu $m.wcs foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $m.wcs add checkbutton -label "[msgcat::mc {WCS}] $l" \ -variable "pview(info,wcs$l)" } pack $f -side top -fill both -expand true } proc PrefsDialogGraph {} { global dprefs global ds9 global pds9 global pmagnifier global current set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Graphs}] lappend dprefs(tabs) [ttk::frame $w.graph] set f [ttk::labelframe $w.graph.horz -text [msgcat::mc {Horizontal}]] ttk::label $f.htitle -text [msgcat::mc {Default}] ttk::checkbutton $f.hgrid -text [msgcat::mc {Grid}] \ -variable pgraph(horz,grid) -command UpdateGraphGrid ttk::radiobutton $f.hlinear -text [msgcat::mc {Linear}] \ -variable pgraph(horz,log) -value false \ -command "UpdateGraphYAxis $current(frame)" ttk::radiobutton $f.hlog -text [msgcat::mc {Log}] \ -variable pgraph(horz,log) -value true \ -command "UpdateGraphYAxis $current(frame)" grid $f.htitle $f.hgrid $f.hlinear $f.hlog -padx 2 -pady 2 -sticky w set f [ttk::labelframe $w.graph.vert -text [msgcat::mc {Vertical}]] ttk::label $f.vtitle -text [msgcat::mc {Default}] ttk::checkbutton $f.vgrid -text [msgcat::mc {Grid}] \ -variable pgraph(vert,grid) -command UpdateGraphGrid ttk::radiobutton $f.vlinear -text [msgcat::mc {Linear}] \ -variable pgraph(vert,log) -value false \ -command "UpdateGraphYAxis $current(frame)" ttk::radiobutton $f.vlog -text [msgcat::mc {Log}] \ -variable pgraph(vert,log) -value true \ -command "UpdateGraphYAxis $current(frame)" grid $f.vtitle $f.vgrid $f.vlinear $f.vlog -padx 2 -pady 2 -sticky w pack $w.graph.horz $w.graph.vert -side top -fill both -expand true } # Buttons proc ButtonsViewDef {} { global pbuttons array set pbuttons { view,horizontal 0 view,vertical 0 view,info 1 view,panner 1 view,magnifier 1 view,buttons 1 view,colorbar 1 view,graphhorz 1 view,graphvert 1 view,filename 0 view,object 0 view,minmax 0 view,lowhigh 0 view,frame 0 view,wcs 0 view,image 0 view,physical 0 view,amplifier 0 view,detector 0 } } proc CreateButtonsView {} { global buttons global ds9 global view ttk::frame $ds9(buttons).view RadioButton $ds9(buttons).view.horizontal \ [string tolower [msgcat::mc {Layout Horz}]] \ view(layout) horizontal {LayoutOrient} RadioButton $ds9(buttons).view.vertical \ [string tolower [msgcat::mc {Layout Vert}]] \ view(layout) vertical {LayoutOrient} CheckButton $ds9(buttons).view.info \ [string tolower [msgcat::mc {Information}]] \ view(info) UpdateView CheckButton $ds9(buttons).view.panner \ [string tolower [msgcat::mc {Panner}]] \ view(panner) UpdateView CheckButton $ds9(buttons).view.magnifier \ [string tolower [msgcat::mc {Magnifier}]] \ view(magnifier) UpdateView CheckButton $ds9(buttons).view.buttons \ [string tolower [msgcat::mc {Buttons}]] \ view(buttons) UpdateView CheckButton $ds9(buttons).view.colorbar \ [string tolower [msgcat::mc {Colorbar}]] \ view(colorbar) UpdateView CheckButton $ds9(buttons).view.graphhorz \ [string tolower [msgcat::mc {Graph Horz}]] \ view(graph,horz) UpdateView CheckButton $ds9(buttons).view.graphvert \ [string tolower [msgcat::mc {Graph Vert}]] \ view(graph,vert) UpdateView CheckButton $ds9(buttons).view.filename \ [string tolower [msgcat::mc {Filename}]] \ view(info,filename) UpdateView CheckButton $ds9(buttons).view.object \ [string tolower [msgcat::mc {Object}]] \ view(info,object) UpdateView CheckButton $ds9(buttons).view.minmax \ [string tolower [msgcat::mc {Min Max}]] \ view(info,minmax) UpdateView CheckButton $ds9(buttons).view.lowhigh \ [string tolower [msgcat::mc {Low High}]] \ view(info,lowhigh) UpdateView CheckButton $ds9(buttons).view.frame \ [string tolower [msgcat::mc {Frame}]] \ view(info,frame) UpdateView CheckButton $ds9(buttons).view.wcs \ [string tolower [msgcat::mc {WCS}]] \ view(info,wcs) UpdateView CheckButton $ds9(buttons).view.image \ [string tolower [msgcat::mc {Image}]] \ view(info,image) UpdateView CheckButton $ds9(buttons).view.physical \ [string tolower [msgcat::mc {Physical}]] \ view(info,physical) UpdateView CheckButton $ds9(buttons).view.amplifier \ [string tolower [msgcat::mc {Amplifier}]] \ view(info,amplifier) UpdateView CheckButton $ds9(buttons).view.detector \ [string tolower [msgcat::mc {Detector}]] \ view(info,detector) UpdateView set buttons(view) " $ds9(buttons).view.horizontal pbuttons(view,horizontal) $ds9(buttons).view.vertical pbuttons(view,vertical) $ds9(buttons).view.info pbuttons(view,info) $ds9(buttons).view.panner pbuttons(view,panner) $ds9(buttons).view.magnifier pbuttons(view,magnifier) $ds9(buttons).view.buttons pbuttons(view,buttons) $ds9(buttons).view.colorbar pbuttons(view,colorbar) $ds9(buttons).view.graphhorz pbuttons(view,graphhorz) $ds9(buttons).view.graphvert pbuttons(view,graphvert) $ds9(buttons).view.filename pbuttons(view,filename) $ds9(buttons).view.object pbuttons(view,object) $ds9(buttons).view.minmax pbuttons(view,minmax) $ds9(buttons).view.lowhigh pbuttons(view,lowhigh) $ds9(buttons).view.frame pbuttons(view,frame) $ds9(buttons).view.wcs pbuttons(view,wcs) $ds9(buttons).view.image pbuttons(view,image) $ds9(buttons).view.physical pbuttons(view,physical) $ds9(buttons).view.amplifier pbuttons(view,amplifier) $ds9(buttons).view.detector pbuttons(view,detector) " } proc PrefsDialogButtonbarView {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Horizontal Layout}] \ -variable pbuttons(view,horizontal) \ -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Vertical Layout}] \ -variable pbuttons(view,vertical) \ -command {UpdateButtons buttons(view)} $m add separator $m add checkbutton -label [msgcat::mc {Information Panel}] \ -variable pbuttons(view,info) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Panner}] \ -variable pbuttons(view,panner) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Magnifier}] \ -variable pbuttons(view,magnifier) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Buttons}] \ -variable pbuttons(view,buttons) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Colorbar}] \ -variable pbuttons(view,colorbar) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Horizontal Graph}] \ -variable pbuttons(view,graphhorz) \ -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Vertical Graph}] \ -variable pbuttons(view,graphvert) \ -command {UpdateButtons buttons(view)} $m add separator $m add checkbutton -label [msgcat::mc {Filename}] \ -variable pbuttons(view,filename) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Object}] \ -variable pbuttons(view,object) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Min Max}] \ -variable pbuttons(view,minmax) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Low High}] \ -variable pbuttons(view,lowhigh) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Frame Information}] \ -variable pbuttons(view,frame) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {WCS}] \ -variable pbuttons(view,wcs) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Image}] \ -variable pbuttons(view,image) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Physical}] \ -variable pbuttons(view,physical) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Amplifier}] \ -variable pbuttons(view,amplifier) -command {UpdateButtons buttons(view)} $m add checkbutton -label [msgcat::mc {Detector}] \ -variable pbuttons(view,detector) -command {UpdateButtons buttons(view)} } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catplot.tcl����������������������������������������������������������������������������0000644�0001750�0001750�00000013336�12132042644�014050� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CATPlot {varname} { upvar #0 $varname var global $varname # do we have a db? if {![CATValidDB $var(tbldb)]} { return } if {$var(plot,x) == {}} { set var(plot,x) "\$$var(colx)" } if {$var(plot,y) == {}} { set var(plot,y) "\$$var(coly)" } if {[CATPlotDialog $varname]} { if {$var(plot,x) != {} && $var(plot,y) != {}} { CATPlotGenerate $varname } } } proc CATPlotGenerate {varname} { upvar #0 $varname var global $varname if {$var(plot,xerr) == {} && $var(plot,yerr) == {}} { set dim xy } elseif {$var(plot,xerr) != {} && $var(plot,yerr) == {}} { set dim xyex } elseif {$var(plot,xerr) == {} && $var(plot,yerr) != {}} { set dim xyey } else { set dim xyexey } global $var(tbldb) set nrows [starbase_nrows $var(tbldb)] set cols [starbase_columns $var(tbldb)] set rr {} for {set ii 1} {$ii <= $nrows} {incr ii} { foreach col $cols { set val [starbase_get $var(tbldb) $ii \ [starbase_colnum $var(tbldb) $col]] # here's a tough one-- what to do if the col is blank # for now, just set it to '0' if {[string trim "$val"] == {}} { set val 0 } eval "set \{$col\} \{$val\}" } switch $dim { xy {append rr [subst "$var(plot,x), $var(plot,y)\n"]} xyex {append rr [subst "$var(plot,x), $var(plot,y), $var(plot,xerr)\n"]} xyey {append rr [subst "$var(plot,x), $var(plot,y), $var(plot,yerr)\n"]} xyexey {append rr [subst "$var(plot,x), $var(plot,y), $var(plot,xerr), $var(plot,yerr)\n"]} } } set xtitle [regsub -all {\$*} $var(plot,x) {}] set ytitle [regsub -all {\$*} $var(plot,y) {}] set vvarname plot${varname} upvar #0 $vvarname vvar global $vvarname if {![PlotPing $vvarname]} { PlotScatterDialog $vvarname $var(title) {} {} {} set vvar(callback) "CATSelectRows $varname plot" set var(plot) 1 set var(plot,var) $vvarname } PlotClearData $vvarname PlotDataSet $vvarname $dim $rr PlotTitle $vvarname $var(title) $xtitle $ytitle $vvar(proc,updategraph) $vvarname PlotStats $vvarname PlotList $vvarname } proc CATPlotDialog {varname} { upvar #0 $varname var global $varname global ds9 global ed2 set w ".${varname}plot" set mb ".${varname}plotmb" set ed2(ok) 0 set ed2(x) $var(plot,x) set ed2(xerr) $var(plot,xerr) set ed2(y) $var(plot,y) set ed2(yerr) $var(plot,yerr) DialogCreate $w [msgcat::mc {Plot}] ed2(ok) $w configure -menu $mb menu $mb # file $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command {set ed2(ok) 1} $mb.file add command -label [msgcat::mc {Cancel}] -command {set ed2(ok) 0} # edit $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit EditMenu $mb $varname # param set f [ttk::frame $w.param] ttk::label $f.taxis -text {Axis} ttk::label $f.terr -text {Error} ttk::label $f.tx -text {X} ttk::entry $f.x -textvariable ed2(x) -width 21 ttk::button $f.bx -text [msgcat::mc {Edit}] \ -command "CATEditDialog ed2 x $var(catdb)" ttk::entry $f.xerr -textvariable ed2(xerr) -width 21 ttk::button $f.bxerr -text [msgcat::mc {Edit}] \ -command "CATEditDialog ed2 xerr $var(catdb)" ttk::menubutton $f.mx -text {Cols} -menu $f.mx.menu ttk::menubutton $f.mxerr -text {Cols} -menu $f.mxerr.menu CATPlotDialogColsMenu $varname $f.mx x CATPlotDialogColsMenu $varname $f.mxerr xerr ttk::label $f.ty -text {Y} ttk::entry $f.y -textvariable ed2(y) -width 21 ttk::button $f.by -text [msgcat::mc {Edit}] \ -command "CATEditDialog ed2 y $var(catdb)" ttk::entry $f.yerr -textvariable ed2(yerr) -width 21 ttk::button $f.byerr -text [msgcat::mc {Edit}] \ -command "CATEditDialog ed2 yerr $var(catdb)" ttk::menubutton $f.my -text {Cols} -menu $f.my.menu ttk::menubutton $f.myerr -text {Cols} -menu $f.myerr.menu CATPlotDialogColsMenu $varname $f.my y CATPlotDialogColsMenu $varname $f.myerr yerr grid x $f.taxis x $f.terr -padx 2 -pady 2 -sticky ew grid $f.tx $f.x $f.bx $f.xerr $f.bxerr -padx 2 -pady 2 -sticky ew grid x $f.mx x $f.mxerr -padx 2 -pady 2 -sticky ew grid $f.ty $f.y $f.by $f.yerr $f.byerr -padx 2 -pady 2 -sticky ew grid x $f.my x $f.myerr -padx 2 -pady 2 -sticky ew # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed2(ok) 1} \ -default active ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed2(ok) 0} pack $f.ok $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed2(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.param -side top -fill both -expand true pack $w.buttons $w.sep -side bottom -fill x DialogCenter $w DialogWait $w ed2(ok) $w.buttons.ok if {$ed2(ok)} { set var(plot,x) $ed2(x) set var(plot,xerr) $ed2(xerr) set var(plot,y) $ed2(y) set var(plot,yerr) $ed2(yerr) } DialogDismiss $w destroy $mb set rr $ed2(ok) unset ed2 return $rr } proc CATPlotDialogColsMenu {varname f ww} { upvar #0 $varname var global $varname global $var(catdb) global ed2 global ds9 set m $f.menu menu $m -tearoff 0 if [CATValidDB $var(catdb)] { set cnt -1 foreach col [starbase_columns $var(catdb)] { $m add command -label $col -command "set ed2($ww) \\$$col" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $m entryconfig $col -columnbreak 1 } } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/markerbasepandarect.tcl����������������������������������������������������������������0000644�0001750�0001750�00000006734�11700665570�016415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc MarkerBasePandaRectDialog {varname} { upvar #0 $varname var global $varname # base panda dialog MarkerBasePandaDialog $varname # callbacks $var(frame) marker $var(id) callback rotate \ MarkerBaseCenterRotateCB $varname set f $var(top).param # Radius ttk::label $f.tmajor -text [msgcat::mc {Major}] ttk::label $f.tminor -text [msgcat::mc {Minor}] ttk::label $f.touter -text [msgcat::mc {Outer}] ttk::entry $f.radius1 -textvariable ${varname}(radius1) -width 13 ttk::entry $f.radius2 -textvariable ${varname}(radius2) -width 13 DistMenuButton $f.uradius $varname dcoord 1 dformat \ [list $var(proc,distCB) $varname] DistMenuEnable $f.uradius.menu $varname dcoord 1 dformat ttk::label $f.tinner -text [msgcat::mc {Inner}] ttk::entry $f.radius3 -textvariable ${varname}(radius3) -width 13 # Annuli ttk::label $f.tannuli -text [msgcat::mc {Annuli}] ttk::entry $f.annuli -textvariable ${varname}(annuli) -width 13 grid x $f.tmajor $f.tminor -padx 2 -pady 2 -sticky w grid $f.touter $f.radius1 $f.radius2 $f.uradius -padx 2 -pady 2 -sticky w grid $f.tinner $f.radius3 -padx 2 -pady 2 -sticky w grid $f.tannuli $f.annuli -padx 2 -pady 2 -sticky w # Angle ttk::label $f.tangle -text [msgcat::mc {Angle}] ttk::entry $f.angle -textvariable ${varname}(angle) -width 13 ttk::label $f.uangle -text [msgcat::mc {Degrees}] grid $f.tangle $f.angle $f.uangle -padx 2 -pady 2 -sticky w # init - do this last $var(proc,distCB) $varname MarkerBaseCenterRotateCB $varname } # actions proc MarkerBasePandaRectClose {varname} { upvar #0 $varname var global $varname $var(frame) marker $var(id) delete callback rotate MarkerBaseCenterRotateCB MarkerBasePandaClose $varname } proc MarkerBasePandaRectApply {varname} { upvar #0 $varname var global $varname MarkerBasePandaApply $varname MarkerBaseCenterRotate $varname } # callbacks proc MarkerBasePandaRectCoordCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePandaRectCoordCB" } MarkerBasePandaCoordCB $varname MarkerBaseCenterRotateCB $varname } proc MarkerBasePandaRectEditCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePandaRectEditCB" } set t [$var(frame) get marker $var(id) epanda radius \ $var(dcoord) $var(dformat)] set last [llength $t] set var(annuli) [expr $last/2-1] set var(radius1) [lindex $t [expr $last-2]] set var(radius2) [lindex $t [expr $last-1]] set var(radius3) [lindex $t 0] $var(annulitxt) delete 1.0 end $var(annulitxt) insert end "$t" set a [$var(frame) get marker $var(id) $var(which) angle \ $var(system) $var(sky)] set last [expr [llength $a]-1] set var(ang1) [lindex $a 0] set var(ang2) [lindex $a $last] set var(angnum) $last $var(angtxt) delete 1.0 end $var(angtxt) insert end "$a" } proc MarkerBasePandaRectDistCB {varname {dummy {}}} { upvar #0 $varname var global $varname global debug if {$debug(tcl,marker)} { puts stderr "MarkerBasePandaRectDistCB" } MarkerBasePandaDistCB $varname } ������������������������������������./saods9/src/cube.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000037436�11773370443�013342� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc CubeDef {} { global icube global cube set icube(top) .cube set icube(mb) .cubemb set icube(id) 0 set cube(lock) 0 # needs work, at high values, but cropped, causes problems # set cube(format) {%.5g} set cube(axis) 2 set cube(system) wcs } proc MatchCubeCurrent {} { global current if {$current(frame) != {}} { MatchCube $current(frame) } } proc MatchCube {which} { global cube global ds9 global rgb set naxes [$which get fits naxes] for {set ii 2} {$ii<=$naxes} {incr ii} { set slice($ii) [$which get fits slice $ii] } foreach ff $ds9(frames) { if {$ff != $which} { for {set ii 2} {$ii<=$naxes} {incr ii} { RGBEvalLock rgb(lock,slice) $ff "$ff update fits slice $ii $slice($ii)" } } } } proc LockCubeCurrent {} { global current if {$current(frame) != {}} { LockCube $current(frame) } } proc LockCube {which} { global cube if {$cube(lock)} { MatchCube $which } } proc CubeSlice {slice} { global dcube global cube global current global rgb global infobox RGBEvalLockCurrent rgb(lock,slice) "$current(frame) update fits slice $cube(axis) $slice" set dcube(slice,$cube(axis)) $slice set dcube(wcs,$cube(axis)) [CubeGetSliceCoord $slice $cube(system) $cube(axis)] set infobox(filename) [$current(frame) get fits file name root base] } proc CubeGetSliceCoord {slice sys ii} { global current global cube set rr [$current(frame) get coordinates from $slice $sys $ii] switch $sys { image {} default { # set rr [format $cube(format) $rr] } } return $rr } proc CubeStop {} { global icube if {$icube(id)>0} { after cancel $icube(id) set icube(id) 0 } } proc CubePlay {} { global icube if {$icube(id) == 0} { CubeTimer } } proc CubeTimer {} { global icube global dcube global cube global current global blink global rgb if {$current(frame) != {}} { if {[$current(frame) has fits]} { set slice [$current(frame) get fits slice $cube(axis)] if {$cube(axis)==2} { # get cropped version set ss [$current(frame) get crop 3d image] set first [lindex $ss 0] set last [lindex $ss 1] } else { set first 1 set last [$current(frame) get fits depth $cube(axis)] } if {$slice == $last} { set slice $first } else { set slice [expr $slice+1] } CubeSlice $slice } else { set dcube(slice,$cube(axis)) 1 set dcube(wcs,$cube(axis)) 1 } UpdateCube } set icube(id) [after $blink(interval) CubeTimer] } proc CubeFirst {} { global dcube global cube global current global rgb CubeStop if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {$cube(axis)==2} { # get cropped version set ss [$current(frame) get crop 3d image] set first [lindex $ss 0] } else { set first 1 } CubeSlice $first } else { set dcube(slice,$cube(axis)) 1 set dcube(wcs,$cube(axis)) 1 } UpdateCube } } proc CubePrev {} { global dcube global cube global current global rgb CubeStop if {$current(frame) != {}} { if {[$current(frame) has fits]} { set slice [$current(frame) get fits slice $cube(axis)] if {$cube(axis)==2} { # get cropped version set ss [$current(frame) get crop 3d image] set first [lindex $ss 0] set last [lindex $ss 1] } else { set first 1 set last [$current(frame) get fits depth $cube(axis)] } if {$slice == $first} { set slice $last } else { set slice [expr $slice-1] } CubeSlice $slice } else { set dcube(slice,$cube(axis)) 1 set dcube(wcs,$cube(axis)) 1 } UpdateCube } } proc CubeNext {} { global dcube global cube global current global rgb CubeStop if {$current(frame) != {}} { if {[$current(frame) has fits]} { set slice [$current(frame) get fits slice $cube(axis)] if {$cube(axis)==2} { # get cropped version set ss [$current(frame) get crop 3d image] set first [lindex $ss 0] set last [lindex $ss 1] } else { set first 1 set last [$current(frame) get fits depth $cube(axis)] } if {$slice == $last} { set slice $first } else { set slice [expr $slice+1] } CubeSlice $slice } else { set dcube(slice,$cube(axis)) 1 set dcube(wcs,$cube(axis)) 1 } UpdateCube } } proc CubeLast {} { global dcube global cube global current global rgb CubeStop if {$current(frame) != {}} { if {[$current(frame) has fits]} { if {$cube(axis)==2} { # get cropped version set ss [$current(frame) get crop 3d image] set last [lindex $ss 1] } else { set last [$current(frame) get fits depth $cube(axis)] } CubeSlice $last } else { set dcube(slice,$cube(axis)) 1 set dcube(wcs,$cube(axis)) 1 } UpdateCube } } proc CubeApply {ii} { global dcube global cube global current global rgb global infobox CubeStop if {$current(frame) != {}} { if {[$current(frame) has fits]} { # set dcube(wcs,$ii) [format $cube(format) $dcube(wcs,$ii)] set ss [expr int([$current(frame) get coordinates to $dcube(wcs,$ii) $cube(system) $cube(axis)]+.5)] if {$ss<1} { set ss 1 } set depth [$current(frame) get fits depth $ii] if {$ss>$depth} { set ss $depth } set dcube(slice,$ii) $ss RGBEvalLockCurrent rgb(lock,slice) "$current(frame) update fits slice $ii $ss" set infobox(filename) [$current(frame) get fits file name root base] } else { set dcube(slice,$cube(axis)) 1 } UpdateCube } } proc UpdateCube {} { LockCubeCurrent UpdateMain } # used by backup proc CubeDialog {} { global icube global dcube global cube global current global ds9 global blink # see if we already have a window visible if [winfo exists $icube(top)] { raise $icube(top) return } # create the cube window set w $icube(top) set mb $icube(mb) Toplevel $w $mb 6 [msgcat::mc {Cube}] CubeDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {Interval}] -menu $mb.blink $mb add cascade -label [msgcat::mc {Coordinate}] -menu $mb.coord menu $mb.file $mb.file add command -label [msgcat::mc {First}] -command CubeFirst $mb.file add command -label [msgcat::mc {Previous}] -command CubePrev $mb.file add command -label [msgcat::mc {Stop}] -command CubeStop $mb.file add command -label [msgcat::mc {Play}] -command CubePlay $mb.file add command -label [msgcat::mc {Next}] -command CubeNext $mb.file add command -label [msgcat::mc {Last}] -command CubeLast $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command CubeDestroyDialog EditMenu $mb icube menu $mb.blink $mb.blink add radiobutton -label ".125 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 125 $mb.blink add radiobutton -label ".25 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 250 $mb.blink add radiobutton -label ".5 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 500 $mb.blink add radiobutton -label "1 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 1000 $mb.blink add radiobutton -label "2 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 2000 $mb.blink add radiobutton -label "4 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 4000 $mb.blink add radiobutton -label "8 [msgcat::mc {Seconds}]" \ -variable blink(interval) -value 8000 CoordMenu $mb.coord cube system 2 {} {} UpdateCubeDialog # Param set f [ttk::frame $w.param] set dcube(taxis) [ttk::label $f.taxis -text [msgcat::mc {Axis}]] set dcube(tslice) [ttk::label $f.tslice -text [msgcat::mc {Slice}]] set dcube(twcs) [ttk::label $f.twcs -textvariable dcube(vcoord) \ -anchor center] for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { set dcube(chk,$ii) [ttk::radiobutton $f.chk$ii \ -text [expr $ii+1] \ -variable cube(axis) \ -value $ii] set dcube(lslice,$ii) [ttk::label $f.slice$ii \ -textvariable dcube(slice,$ii) \ -width 3 -anchor center] set dcube(sslice,$ii) [slider $f.scale$ii 0 100 {} \ dcube(wcs,$ii) [list CubeApply $ii] 4 10] } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.first -text [msgcat::mc {First}] -width -6 -command CubeFirst ttk::button $f.prev -text [msgcat::mc {Previous}] -width -6 \ -command CubePrev ttk::button $f.stop -text [msgcat::mc {Stop}] -width -6 -command CubeStop ttk::button $f.play -text [msgcat::mc {Play}] -width -6 -command CubePlay ttk::button $f.next -text [msgcat::mc {Next}] -width -6 -command CubeNext ttk::button $f.last -text [msgcat::mc {Last}] -width -6 -command CubeLast pack $f.first $f.prev $f.stop $f.play $f.next $f.last \ -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.sep -orient horizontal pack $w.buttons $w.sep -side bottom -fill x pack $w.param -side top -fill both -expand true UpdateCubeDialog } proc CubeDestroyDialog {} { global icube global dcube CubeStop if {[winfo exists $icube(top)]} { destroy $icube(top) destroy $icube(mb) } unset dcube } proc UpdateCubeMenu {} { # can be changed by wcs SetCoordSystem cube system {} {} } proc UpdateCubeDialog {} { global icube global dcube global cube global current global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateCubeDialog" } CubeStop if {![winfo exists $icube(top)]} { return } # get number of axes if {$current(frame) != {}} { set naxes [$current(frame) get fits naxes] } else { set naxes 2 } if {$current(frame) != {}} { set cube(frame) $current(frame) if {[$current(frame) has fits]} { # now make sure we have the coord systems AdjustCoordSystem3d cube system CoordMenuEnable $icube(mb).coord cube system 2 {} {} } else { CoordMenuReset $icube(mb).coord cube system 2 {} {} } } for {set ii 2} {$ii<=$naxes} {incr ii} { set depth 1 set dcube(from,$ii) 1 set dcube(to,$ii) 1 if {$current(frame) != {}} { if {[$current(frame) has fits]} { set depth [$current(frame) get fits depth $ii] if {$ii==2 && [$current(frame) has fits cube]} { # get cropped version set ss [$current(frame) get crop 3d $cube(system)] set dcube(from,$ii) [lindex $ss 0] set dcube(to,$ii) [lindex $ss 1] } else { set dcube(from,$ii) [$current(frame) get coordinates from 1 $cube(system) $ii] set dcube(to,$ii) [$current(frame) get coordinates from $depth $cube(system) $ii] } } } } # forget everything grid forget $dcube(tslice) $dcube(taxis) $dcube(twcs) for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { grid forget $dcube(chk,$ii) $dcube(sslice,$ii) $dcube(lslice,$ii) } if {$naxes == 2} { # special case grid columnconfigure $icube(top).param 1 -weight 1 grid columnconfigure $icube(top).param 2 -weight 0 grid $dcube(tslice) $dcube(twcs) -padx 2 -pady 2 -sticky ew grid $dcube(lslice,2) $dcube(sslice,2) -padx 2 -pady 2 -sticky ew } else { # show it grid columnconfigure $icube(top).param 1 -weight 0 grid columnconfigure $icube(top).param 2 -weight 1 grid $dcube(taxis) $dcube(tslice) $dcube(twcs) \ -padx 2 -pady 2 -sticky ew for {set ii 2} {$ii<=$naxes} {incr ii} { grid $dcube(chk,$ii) $dcube(lslice,$ii) \ $dcube(sslice,$ii) -padx 2 -pady 2 -sticky ew } } # set intervals for {set ii 2} {$ii<=$naxes} {incr ii} { switch $cube(system) { image { set dcube(from,$ii) [expr int($dcube(from,$ii))] set dcube(to,$ii) [expr int($dcube(to,$ii))] set dcube(vcoord) $cube(system) } default { # set dcube(from,$ii) [format $cube(format) $dcube(from,$ii)] # set dcube(to,$ii) [format $cube(format) $dcube(to,$ii)] set dcube(vcoord) $cube(system) if {$current(frame) != {}} { if {[$current(frame) has fits]} { set w [string range $cube(system) 3 3] set key "CTYPE[expr $cube(axis)+1]$w" set tt [string trim [$current(frame) get fits header 1 keyword \{$key\}]] if {$tt != {}} { set dcube(vcoord) $tt } } } } } SliderMinMax $dcube(sslice,$ii) $dcube(from,$ii) $dcube(to,$ii) 4 } # reset cube(axis) if needed if {$cube(axis) > $naxes} { set cube(axis) $naxes if {$cube(axis) < 2} { set cube(axis) 2 } } # we must do this after the scale has been configured for {set ii 2} {$ii<=$naxes} {incr ii} { set dcube(slice,$ii) 1 set dcube(wcs,$ii) 1 if {$current(frame) != {}} { if {[$current(frame) has fits]} { set slice [$current(frame) get fits slice $ii] set dcube(slice,$ii) $slice set dcube(wcs,$ii) [CubeGetSliceCoord $slice $cube(system) $ii] } } } } proc CubeBackup {ch which} { switch [$which get type] { base - 3d {CubeBackupBase $ch $which} rgb {CubeBackupRGB $ch $which} } } proc CubeBackupBase {ch which} { global ds9 if [$which has fits cube] { for {set ii 2} {$ii<$ds9(FTY_MAXAXES)} {incr ii} { set depth [$which get fits depth $ii] if {$depth>1} { puts $ch "$which update fits slice $ii [$which get fits slice $ii]" } else { break } } puts $ch "CubeDialog" } } proc CubeBackupRGB {ch which} { set sav [$which get rgb channel] foreach cc {red green blue} { $which rgb channel $cc puts $ch "$which rgb channel $cc" CubeBackupBase $ch $which } $which rgb channel $sav puts $ch "$which rgb channel $sav" } # Process Cmds proc ProcessCubeCmd {varname iname} { upvar $varname var upvar $iname i global cube global dcube global blink global current global rgb CubeDialog switch -- [string tolower [lindex $var $i]] { match {MatchCubeCurrent} lock { incr i if {!([string range [lindex $var $i] 0 0] == "-")} { set cube(lock) [FromYesNo [lindex $var $i]] } else { set cube(lock) 1 incr i -1 } LockCubeCurrent } open {} close {CubeDestroyDialog} play {CubePlay} stop {CubeStop} next {CubeNext} prev {CubePrev} first {CubeFirst} last {CubeLast} interval { incr i set blink(interval) [expr int([lindex $var $i]*1000)] } axis { incr i; set item [lindex $var $i] if {[string is integer $item]} { set cube(axis) [expr $item-1] if {$cube(axis) < 2} { set cube(axis) 2 } } } default { # defaults set ss [lindex $var $i] set sys image set axis 2 # sys set item [lindex $var [expr $i+1]] if {$item != {}} { if {!([string range $item 0 0] == "-")} { incr i if {[string is integer $item]} { set axis [expr $item-1] } else { set sys $item } # axis set item [lindex $var [expr $i+1]] if {$item != {}} { if {!([string range $item 0 0] == "-")} { incr i if {[string is integer $item]} { set axis [expr $item-1] } } } } } if {[string is double $ss]} { set dcube(wcs,$axis) $ss set cube(system) $sys set cube(axis) $axis if {$cube(axis) < 2} { set cube(axis) 2 } CubeApply $cube(axis) } } } } proc ProcessSendCubeCmd {proc id param} { global cube global current global blink switch -- [string tolower [lindex $param 0]] { lock {$proc $id [ToYesNo $cube(lock)]} interval {$proc $id "[expr $blink(interval)/1000.]\n"} axis {$proc $id "$cube(axis)\n"} default { if {$current(frame) != {}} { $proc $id "[$current(frame) get fits slice $cube(axis)]\n" } else { $proc $id "1\n" } } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catreg.tcl�����������������������������������������������������������������������������0000644�0001750�0001750�00000023300�11741372167�013652� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # catreg -- convert catalog table into region string proc CATReg {varname row interactive resultname} { upvar $resultname result upvar #0 $varname var global $varname global $var(tbldb) global $var(symdb) # init result set result {} # How to process each field of a filter # ------------------------------------- # condition: subst/expr # shape: constant # color: constant # font: constant # fontsize: constant # fontweight: constant # fontslant: constant # text: subst # size1: expr # size2: expr # angle: expr # valid cols? if {$var(colx) == {} || $var(coly) == {}} { return } set colx [starbase_colnum $var(tbldb) $var(colx)] set coly [starbase_colnum $var(tbldb) $var(coly)] # do we have formats for colx and coly? if [catch {starbase_hdrget $var(tbldb) UFMT} ff] { set ff {} global errorInfo set errorInfo {} } set xformat [lindex $ff 0] set yformat [lindex $ff 1] # else, do we have T(Units), i.e. votable set db $var(tbldb) upvar #0 $db T if [info exists T(Unit)] { set xformat [string trim [lindex $T(Unit) [expr $colx-1]] {"}] set yformat [string trim [lindex $T(Unit) [expr $coly-1]] {"}] } # process prologue append result "# Region file format: DS9 version 4.0\n" # for speed... # tbldb set nrows [starbase_nrows $var(tbldb)] set cols [starbase_columns $var(tbldb)] # system switch $var(psystem) { image - physical - detector - amplifier {set sys $var(psystem)} default {set sys "$var(psystem); $var(psky)"} } # symdb set snrows [starbase_nrows $var(symdb)] set sncond [starbase_colnum $var(symdb) condition] set snshape [starbase_colnum $var(symdb) shape] set sncolor [starbase_colnum $var(symdb) color] set snfont [starbase_colnum $var(symdb) font] set snfontsize [starbase_colnum $var(symdb) fontsize] set snfontweight [starbase_colnum $var(symdb) fontweight] set snfontslant [starbase_colnum $var(symdb) fontslant] set sntext [starbase_colnum $var(symdb) text] set snsize [starbase_colnum $var(symdb) size] set snsize2 [starbase_colnum $var(symdb) size2] set snunits [starbase_colnum $var(symdb) units] set snangle [starbase_colnum $var(symdb) angle] # for each row in the catalog table ... if {[string is integer -strict $row]} { set start $row set end $row } else { set start 1 set end $nrows } # look for need to eval colnames (only used for conditionals and text set doEval 0 for {set jj 1} {$jj <= $snrows} {incr jj} { set cond [starbase_get $var(symdb) $jj $sncond] set text [starbase_get $var(symdb) $jj $sntext] set sz [starbase_get $var(symdb) $jj $snsize] set sz2 [starbase_get $var(symdb) $jj $snsize2] set angle [starbase_get $var(symdb) $jj $snangle] if {$cond!={} || $text!={} || $sz!={} || $sz2!={} || $angle!={}} { set doEval 1 } } for {set ii $start} {$ii <= $end} {incr ii} { if {$doEval} { # define each colunm variable foreach col $cols { set val [starbase_get $var(tbldb) $ii \ [starbase_colnum $var(tbldb) $col]] # here's a tough one-- what to do if the col is blank # for now, just set it to '0' if {[string trim "$val"] == {}} { set val 0 } eval "set \{$col\} \{$val\}" } } # look through each filter for {set jj 1} {$jj <= $snrows} {incr jj} { # eval condition set cond [starbase_get $var(symdb) $jj $sncond] if {$cond != {}} { set found 0 # subst any column vars if [catch {subst $cond} cc] { Error "Unable to evaluate condition $cc" return } # evaluate filter if [catch {expr $cc} found] { Error "Unable to evaluate condition $cc" return } } else { set found 1 } # if not true, goto the next filter if {!$found} { continue } # shape set shape [starbase_get $var(symdb) $jj $snshape] if {$shape == {}} { set shape circle } # xx set xx [starbase_get $var(tbldb) $ii $colx] switch $xformat { {h:m:s} - {d:m:s} {set xx [uformat $xformat d $xx]} } # yy set yy [starbase_get $var(tbldb) $ii $coly] if {$yformat == {d:m:s}} { set yy [uformat $yformat d $yy] } # size/angle set szcol {} set sz2col {} set angcol {} set units [starbase_get $var(symdb) $jj $snunits] switch -- $units { image {set unitval i} physical {set unitval p} degrees {set unitval d} arcmin {set unitval {'}} arcsec {set unitval {"}} default {set unitval p} } switch -- $shape { text - point - {circle point} - {box point} - {diamond point} - {cross point} - {x point} - {arrow point} - {boxcircle point} {set size {}} circle { set sz [starbase_get $var(symdb) $jj $snsize] set szcolnm [string range $sz 1 end] if {[lsearch -exact $cols $szcolnm] != -1} { set szcol [starbase_colnum $var(tbldb) $szcolnm] } if {$sz != {}} { if [catch {expr $sz} ss] { Error "Unable to evaluate size $sz" return } else { set sz $ss } } else { set sz 5 } set size "${sz}${unitval}" } vector { set sz [starbase_get $var(symdb) $jj $snsize] set szcolnm [string range $sz 1 end] if {[lsearch -exact $cols $szcolnm] != -1} { set szcol [starbase_colnum $var(tbldb) $szcolnm] } if {$sz != {}} { if [catch {expr $sz} ss] { Error "Unable to evaluate size $sz" return } else { set sz $ss } } else { set sz 5 } set angle [starbase_get $var(symdb) $jj $snangle] set angcolnm [string range $angle 1 end] if {[lsearch -exact $cols $angcolnm] != -1} { set angcol [starbase_colnum $var(tbldb) $angcolnm] } if {$angle != {}} { if [catch {expr $angle} aa] { Error "Unable to evaluate angle $angle" return } else { set angle $aa } } else { set angle 0 } set size "${sz}${unitval} ${angle}" } ellipse - box { # size set sz [starbase_get $var(symdb) $jj $snsize] set szcolnm [string range $sz 1 end] if {[lsearch -exact $cols $szcolnm] != -1} { set szcol [starbase_colnum $var(tbldb) $szcolnm] } if {$sz != {}} { if [catch {expr $sz} ss] { Error "Unable to evaluate size $sz" return } else { set sz $ss } } else { set sz 5 } # size2 set sz2 [starbase_get $var(symdb) $jj $snsize2] set sz2colnm [string range $sz2 1 end] if {[lsearch -exact $cols $sz2colnm] != -1} { set sz2col [starbase_colnum $var(tbldb) $sz2colnm] } if {$sz2 != {}} { if [catch {expr $sz2} ss] { Error "Unable to evaluate size $sz2" return } else { set sz2 $ss } } else { set sz2 5 } # angle set angle [starbase_get $var(symdb) $jj $snangle] set angcolnm [string range $angle 1 end] if {[lsearch -exact $cols $angcolnm] != -1} { set angcol [starbase_colnum $var(tbldb) $angcolnm] } if {$angle != {}} { if [catch {expr $angle} aa] { Error "Unable to evaluate angle $angle" return } else { set angle $aa } } else { set angle 0 } # put it all together set size "${sz}${unitval} ${sz2}${unitval} ${angle}" } } # color set color [starbase_get $var(symdb) $jj $sncolor] if {$color == {}} { set color green } #font set font [starbase_get $var(symdb) $jj $snfont] if {$font == {}} { set font helvetica } set fontsize [starbase_get $var(symdb) $jj $snfontsize] if {$fontsize == {}} { set fontsize 10 } set fontweight [starbase_get $var(symdb) $jj $snfontweight] if {$fontweight == {}} { set fontweight normal } set fontslant [starbase_get $var(symdb) $jj $snfontslant] if {$fontslant == {}} { set fontslant roman } # text set text [starbase_get $var(symdb) $jj $sntext] if {$text != {}} { if [catch {subst $text} tt] { Error "Unable to evaluate text $text" return } else { set text $tt } } if {$shape == {text} && $text == {}} { set text "$ii" } # final substitution and append result # init result for substitutions if {$interactive} { if {$var(edit)} { set template "\${sys};\${shape}(\${xx} \${yy} \${size}) # color=\${color} font=\{${font} ${fontsize} ${fontweight} ${fontslant}\} text=\{\${text}\} tag={${varname}} tag={${varname}.\${ii}} select=1 edit=1 move=1 rotate=1 delete=1 highlite=0 callback=select CATHighliteCB {${varname}.\${ii}} callback=unselect CATUnhighliteCB {${varname}.\${ii}} callback=edit CATEditCB {${varname}.\${ii}.\${szcol}.\${sz2col}.\${units}.\${angcol}} callback=move CATMoveCB {${varname}.\${ii}} callback=rotate CATRotateCB {${varname}.\${ii}.\${angcol}} callback=delete CATDeleteCB {${varname}.\${ii}}\n" } else { set template "\${sys};\${shape}(\${xx} \${yy} \${size}) # color=\${color} font=\{${font} ${fontsize} ${fontweight} ${fontslant}\} text=\{\${text}\} tag={${varname}} tag={${varname}.\${ii}} select=0 edit=0 move=0 rotate=0 delete=1 highlite=1 callback=delete CATDeleteCB {${varname}.\${ii}} callback=highlite CATHighliteCB {${varname}.\${ii}} callback=unhighlite CATUnhighliteCB {${varname}.\${ii}}\n" } } else { set template "\${sys};\${shape}(\${xx} \${yy} \${size}) # color=\${color} text=\{\${text}\} tag=$varname\n" } append result [subst $template] # ok, we are done break } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/2mass.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000006355�11700665565�013447� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc 2MASSDef {} { global twomass global itwomass set itwomass(top) .twomass set itwomass(mb) .twomassmb set twomass(sky) fk5 set twomass(rformat) arcmin set twomass(width) 15 set twomass(height) 15 set twomass(mode) new set twomass(save) 0 set twomass(valid) 0 set twomass(survey) j } proc 2MASSDialog {} { global twomass global itwomass global wcs if [winfo exists $itwomass(top)] { raise $itwomass(top) return } set varname dtwomass upvar #0 $varname var global $varname set var(top) $itwomass(top) set var(mb) $itwomass(mb) set var(sky) $twomass(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $twomass(rformat) set var(width) $twomass(width) set var(height) $twomass(height) set var(mode) $twomass(mode) set var(save) $twomass(save) set var(valid) $twomass(valid) set var(survey) $twomass(survey) IMGSVRInit $varname "IPAC-2MASS [msgcat::mc {Server}]" 2MASSExec 2MASSAck $var(mb) add cascade -label Survey -menu $var(mb).survey menu $var(mb).survey $var(mb).survey add radiobutton -label {2MASS (J Band)} \ -variable ${varname}(survey) -value j $var(mb).survey add radiobutton -label {2MASS (H Band)} \ -variable ${varname}(survey) -value h $var(mb).survey add radiobutton -label {2MASS (K Band)} \ -variable ${varname}(survey) -value k IMGSVRUpdate $varname 1 } proc 2MASSExec {varname} { upvar #0 $varname var global $varname if {$var(save)} { set var(fn) [SaveFileDialog savefitsfbox] if {$var(fn) == {}} { return } } else { set var(fn) [tmpnam ds92mass {.fits.gz}] } # size - convert to arcsec switch -- $var(rformat) { degrees { set ww [expr $var(width)*60.*60.] set hh [expr $var(height)*60.*60.] } arcmin { set ww [expr $var(width)*60.] set hh [expr $var(height)*60.] } arcsec { set ww $var(width) set hh $var(height) } } # now to radius set rr [expr sqrt($ww*$ww+$hh*$hh)/2.] if {$rr>1024} { set rr 1024 } set foo "$var(x) $var(y)" set var(query) [http::formatQuery objstr $foo size $rr band $var(survey)] set var(url) "http://irsa.ipac.caltech.edu/cgi-bin/Oasis/2MASSImg/nph-2massimg" IMGSVRLoad $varname } proc 2MASSAck {varname} { upvar #0 $varname var global $varname set msg {Acknowledgments for the 2MASS This publication makes use of data products from the Two Micron All Sky Survey, which is a joint project of the University of Massachusetts and the Infrared Processing and Analysis Center/California Institute of Technology, funded by the National Aeronautics and Space Administration and the National Science Foundation. } SimpleTextDialog "${varname}ack" [msgcat::mc {Acknowledgment}] 80 40 insert top $msg } # Process Cmds proc Process2MASSCmd {varname iname} { upvar $varname var upvar $iname i 2MASSDialog IMGSVRProcessCmd $varname $iname dtwomass } proc ProcessSend2MASSCmd {proc id param} { 2MASSDialog IMGSVRProcessSendCmd $proc $id $param dtwomass } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/wcs.tcl��������������������������������������������������������������������������������0000644�0001750�0001750�00000074547�12132024702�013204� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc WCSDef {} { global wcs global pwcs global iwcs set iwcs(top) .wcs set iwcs(mb) .wcsmb set wcs(system) wcs set wcs(sky) fk5 set wcs(skyformat) sexagesimal array set pwcs [array get wcs] } proc UpdateWCS {} { global wcs global ds9 global current # frame if {$current(frame) != {}} { $current(frame) wcs $wcs(system) $wcs(sky) $wcs(skyformat) AlignWCSFrame set wcs(frame) $current(frame) if {[$current(frame) has fits]} { CoordMenuEnable $ds9(mb).wcs wcs system 0 sky skyformat } else { CoordMenuReset $ds9(mb).wcs wcs system 0 sky skyformat } UpdateWCSInfoBox $current(frame) } # grid global grid set grid(system) $wcs(system) set grid(sky) $wcs(sky) set grid(skyformat) $wcs(skyformat) GridUpdate # panzoom dialog global panzoom set panzoom(system) $wcs(system) set panzoom(sky) $wcs(sky) set panzoom(skyformat) $wcs(skyformat) UpdatePanZoomDialog # crop dialog global crop set crop(system) $wcs(system) set crop(sky) $wcs(sky) set crop(skyformat) $wcs(skyformat) set crop(dcoord) $wcs(system) set crop(dformat) $wcs(skyformat) UpdateCropDialog # cube global cube set cube(system) $wcs(system) UpdateCubeDialog # rgb global rgb set rgb(system) $wcs(system) RGBSystem # regions global marker set marker(system) $wcs(system) set marker(sky) $wcs(sky) set marker(skyformat) $wcs(skyformat) } proc UpdateWCSInfoBox {which} { global wcs global view # if one wcs coord system is visible, change it set cnt 0 set vv {} foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { if {$view(info,wcs$ll)} { incr cnt set vv wcs$ll } } if {$cnt == 1} { set ww [lindex [$which get wcs] 0] if {$view(info,$vv) != $view(info,$ww)} { foreach ll {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set view(info,wcs$ll) 0 } set view(info,$ww) 1 LayoutInfoPanel } } } proc WCSBackup {ch which fdir rdir} { puts $ch "$which wcs [$which get wcs]" if {[$which has wcs alt]} { set fn $fdir/ds9.wcs set rfn $rdir/ds9.wcs catch {file delete -force $fn} WCSToVar [$which get fits header wcs 1] WCSSaveFile $fn puts $ch "WCSLoadFile $rfn" puts $ch "$which wcs replace text 1 \\\{\[WCSFromVar\]\\\}" } } proc WCSDialog {} { global wcs global iwcs global dwcs global ds9 # see if we already have a window visible if [winfo exists $iwcs(top)] { raise $iwcs(top) return } # create the window set w $iwcs(top) set mb $iwcs(mb) # vars set dwcs(system) $wcs(system) set dwcs(ext) 1 set dwcs(prev) {} Toplevel $w $mb 6 [msgcat::mc {WCS Parameters}] WCSDestroyDialog $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit $mb add cascade -label [msgcat::mc {WCS}] -menu $mb.wcs $mb add cascade -label [msgcat::mc {Extention}] -menu $mb.ext menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] -command WCSApplyDialog $mb.file add command -label [msgcat::mc {Reset}] -command WCSResetDialog $mb.file add separator $mb.file add command -label "[msgcat::mc {Load}]..." -command WCSLoadDialog $mb.file add command -label "[msgcat::mc {Save}]..." -command WCSSaveDialog $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] -command WCSDestroyDialog EditMenu $mb iwcs menu $mb.wcs $mb.wcs add radiobutton -label [msgcat::mc {WCS}] \ -variable dwcs(system) -value wcs -command ConfigWCSDialog $mb.wcs add separator foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { $mb.wcs add radiobutton -label "[msgcat::mc {WCS}] $l" \ -variable dwcs(system) -value "wcs$l" -command ConfigWCSDialog } # configured later menu $mb.ext # Param set tt [ttk::notebook $w.param] set base [ttk::frame $tt.base] set pv00 [ttk::frame $tt.pv00] set pv12 [ttk::frame $tt.pv12] set pv24 [ttk::frame $tt.pv24] set ab0 [ttk::frame $tt.ab0] set ab2 [ttk::frame $tt.ab2] set ab4 [ttk::frame $tt.ab4] set apbp0 [ttk::frame $tt.apbp0] set apbp2 [ttk::frame $tt.apbp2] set apbp4 [ttk::frame $tt.apbp4] $tt add $base -text {Keyword} $tt add $pv00 -text {PVi_00} $tt add $pv12 -text {PVi_12} $tt add $pv24 -text {PVi_24} $tt add $ab0 -text {A_0} $tt add $ab2 -text {A_2} $tt add $ab4 -text {A_4} $tt add $apbp0 -text {AP_0} $tt add $apbp2 -text {AP_2} $tt add $apbp4 -text {AP_4} $tt select $base label $base.tmjdobs -text "MJD-OBS" ttk::entry $base.mjdobs -textvariable dwcs(mjd-obs) -width 14 label $base.tdateobs -text "DATE-OBS" ttk::entry $base.dateobs -textvariable dwcs(date-obs) -width 14 label $base.tdate -text "DATE" ttk::entry $base.date -textvariable dwcs(date) -width 14 label $base.tepoch -text "EPOCH" ttk::entry $base.epoch -textvariable dwcs(epoch) -width 14 foreach aa {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set bb [string toupper $aa] label $base.twcsname${aa} -text "WCSNAME${bb}" ttk::entry $base.wcsname${aa} \ -textvariable dwcs(wcsname${aa}) -width 14 label $base.tradesys${aa} -text "RADESYS${bb}" ttk::entry $base.radesys${aa} \ -textvariable dwcs(radesys${aa}) -width 14 label $base.tequinox${aa} -text "EQUINOX${bb}" ttk::entry $base.equinox${aa} \ -textvariable dwcs(equinox${aa}) -width 14 ttk::label $base.tlatpole${aa} -text "LATPOLE${bb}" ttk::entry $base.latpole${aa} \ -textvariable dwcs(latpole${aa}) -width 14 ttk::label $base.tlonpole${aa} -text "LONPOLE${bb}" ttk::entry $base.lonpole${aa} \ -textvariable dwcs(lonpole${aa}) -width 14 for {set ii 1} {$ii<=2} {incr ii} { ttk::label $base.tctype${ii}${aa} -text "CTYPE${ii}${bb}" ttk::entry $base.ctype${ii}${aa} \ -textvariable dwcs(ctype${ii}${aa}) -width 14 ttk::label $base.tcrpix${ii}${aa} -text "CRPIX${ii}${bb}" ttk::entry $base.crpix${ii}${aa} \ -textvariable dwcs(crpix${ii}${aa}) -width 14 ttk::label $base.tcrval${ii}${aa} -text "CRVAL${ii}${bb}" ttk::entry $base.crval${ii}${aa} \ -textvariable dwcs(crval${ii}${aa}) -width 14 ttk::label $base.tcunit${ii}${aa} -text "CUNIT${ii}${bb}" ttk::entry $base.cunit${ii}${aa} \ -textvariable dwcs(cunit${ii}${aa}) -width 14 ttk::label $base.tcdelt${ii}${aa} -text "CDELT${ii}${bb}" ttk::entry $base.cdelt${ii}${aa} \ -textvariable dwcs(cdelt${ii}${aa}) -width 14 for {set jj 1} {$jj<=2} {incr jj} { ttk::label $base.tcd${ii}_${jj}${aa} -text "CD${ii}_${jj}${bb}" ttk::entry $base.cd${ii}_${jj}${aa} \ -textvariable dwcs(cd${ii}_${jj}${aa}) -width 14 } for {set jj 1} {$jj<=2} {incr jj} { ttk::label $base.tpc${ii}_${jj}${aa} \ -text "PC${ii}_${jj}${bb}" ttk::entry $base.pc${ii}_${jj}${aa} \ -textvariable dwcs(pc${ii}_${jj}${aa}) -width 14 } for {set mm 0} {$mm<12} {incr mm} { ttk::label $pv00.tpv${ii}_${mm}${aa} \ -text "PV${ii}_${mm}${bb}" ttk::entry $pv00.pv${ii}_${mm}${aa} \ -textvariable dwcs(pv${ii}_${mm}${aa}) -width 14 } for {set mm 12} {$mm<24} {incr mm} { ttk::label $pv12.tpv${ii}_${mm}${aa} \ -text "PV${ii}_${mm}${bb}" ttk::entry $pv12.pv${ii}_${mm}${aa} \ -textvariable dwcs(pv${ii}_${mm}${aa}) -width 14 } for {set mm 24} {$mm<36} {incr mm} { ttk::label $pv24.tpv${ii}_${mm}${aa} \ -text "PV${ii}_${mm}${bb}" ttk::entry $pv24.pv${ii}_${mm}${aa} \ -textvariable dwcs(pv${ii}_${mm}${aa}) -width 14 } } } # only in primary ttk::label $ab0.ta -text "A_ORDER" ttk::entry $ab0.a -textvariable dwcs(a_order) -width 14 for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab0.ta_${mm}_${nn} -text "A_${mm}_${nn}" ttk::entry $ab0.a_${mm}_${nn} \ -textvariable dwcs(a_${mm}_${nn}) -width 14 } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab2.ta_${mm}_${nn} -text "A_${mm}_${nn}" ttk::entry $ab2.a_${mm}_${nn} \ -textvariable dwcs(a_${mm}_${nn}) -width 14 } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab4.ta_${mm}_${nn} -text "A_${mm}_${nn}" ttk::entry $ab4.a_${mm}_${nn} \ -textvariable dwcs(a_${mm}_${nn}) -width 14 } } ttk::label $ab0.tb -text "B_ORDER" ttk::entry $ab0.b -textvariable dwcs(b_order) -width 14 for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab0.tb_${mm}_${nn} -text "B_${mm}_${nn}" ttk::entry $ab0.b_${mm}_${nn} \ -textvariable dwcs(b_${mm}_${nn}) -width 14 } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab2.tb_${mm}_${nn} -text "B_${mm}_${nn}" ttk::entry $ab2.b_${mm}_${nn} \ -textvariable dwcs(b_${mm}_${nn}) -width 14 } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $ab4.tb_${mm}_${nn} -text "B_${mm}_${nn}" ttk::entry $ab4.b_${mm}_${nn} \ -textvariable dwcs(b_${mm}_${nn}) -width 14 } } ttk::label $apbp0.tap -text "AP_ORDER" ttk::entry $apbp0.ap -textvariable dwcs(ap_order) -width 14 for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp0.tap_${mm}_${nn} -text "AP_${mm}_${nn}" ttk::entry $apbp0.ap_${mm}_${nn} \ -textvariable dwcs(ap_${mm}_${nn}) -width 14 } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp2.tap_${mm}_${nn} -text "AP_${mm}_${nn}" ttk::entry $apbp2.ap_${mm}_${nn} \ -textvariable dwcs(ap_${mm}_${nn}) -width 14 } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp4.tap_${mm}_${nn} -text "AP_${mm}_${nn}" ttk::entry $apbp4.ap_${mm}_${nn} \ -textvariable dwcs(ap_${mm}_${nn}) -width 14 } } ttk::label $apbp0.tbp -text "BP_ORDER" ttk::entry $apbp0.bp -textvariable dwcs(bp_order) -width 14 for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp0.tbp_${mm}_${nn} -text "BP_${mm}_${nn}" ttk::entry $apbp0.bp_${mm}_${nn} \ -textvariable dwcs(bp_${mm}_${nn}) -width 14 } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp2.tbp_${mm}_${nn} -text "BP_${mm}_${nn}" ttk::entry $apbp2.bp_${mm}_${nn} \ -textvariable dwcs(bp_${mm}_${nn}) -width 14 } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { ttk::label $apbp4.tbp_${mm}_${nn} -text "BP_${mm}_${nn}" ttk::entry $apbp4.bp_${mm}_${nn} \ -textvariable dwcs(bp_${mm}_${nn}) -width 14 } } # Buttons set f [ttk::frame $w.buttons] ttk::button $f.apply -text [msgcat::mc {Apply}] -command WCSApplyDialog ttk::button $f.reset -text [msgcat::mc {Reset}] -command WCSResetDialog ttk::button $f.close -text [msgcat::mc {Close}] -command WCSDestroyDialog pack $f.apply $f.reset $f.close -side left -expand true -padx 2 -pady 4 # Fini pack $w.buttons -side bottom -fill x pack $w.param -side top -fill both -expand true ConfigWCSDialog UpdateWCSDialog } proc WCSApplyDialog {} { global dwcs global current global rgb if {$current(frame) != {}} { RGBEvalLock rgb(lock,wcs) $current(frame) "$current(frame) wcs replace text $dwcs(ext) \{\{[WCSFromVar]\}\}" UpdateWCS CATUpdateWCS } } proc WCSResetDialog {} { global dwcs global current global rgb if {$current(frame) != {}} { RGBEvalLock rgb(lock,wcs) $current(frame) [list $current(frame) wcs reset $dwcs(ext)] UpdateWCS CATUpdateWCS UpdateWCSDialog } } proc WCSDestroyDialog {} { global iwcs global dwcs if {[winfo exists $iwcs(top)]} { destroy $iwcs(top) destroy $iwcs(mb) } unset dwcs } proc WCSSaveDialog {} { global dwcs set fn [SaveFileDialog wcsfbox] WCSSaveFile $fn } # used by backup proc WCSSaveFile {fn} { if [catch {open $fn w} fp] { Error "[msgcat::mc {Unable to open file}] $fn: $fp" return } puts $fp [WCSFromVar] catch {close $fp} } proc WCSLoadDialog {} { global dwcs set fn [OpenFileDialog wcsfbox] WCSLoadFile $fn } # used by backup proc WCSLoadFile {fn} { if {$fn != {}} { if [catch {open $fn r} fp] { Error "[msgcat::mc {Unable to open file}] $fn: $fp" return } WCSToVar [read -nonewline $fp] catch {close $fp} } } proc UpdateWCSDialog {} { global iwcs global current global debug if {$debug(tcl,update)} { puts stderr "UpdateWCSDialog" } if {![winfo exists $iwcs(top)]} { return } ConfigWCSDialogExtMenu UpdateWCSVars } proc UpdateWCSVars {} { global dwcs global current if {$current(frame) != {}} { if {[$current(frame) has fits]} { WCSToVar [$current(frame) get fits header wcs $dwcs(ext)] return } } WCSToVar {} } proc ConfigWCSDialog {{force {0}}} { global wcs global iwcs global dwcs global current global debug if {$debug(tcl,update)} { puts stderr "ConfigWCSDialog" } if {![winfo exists $iwcs(top)]} { return } # do we need to re-grid wcs vars? if {!$force && $dwcs(prev) == $dwcs(system)} { return } set tt $iwcs(top).param set base $tt.base set pv00 $tt.pv00 set pv12 $tt.pv12 set pv24 $tt.pv24 set ab0 $tt.ab0 set ab2 $tt.ab2 set ab4 $tt.ab4 set apbp0 $tt.apbp0 set apbp2 $tt.apbp2 set apbp4 $tt.apbp4 grid forget $base.tmjdobs $base.mjdobs grid forget $base.tdateobs $base.dateobs grid forget $base.tdate $base.date grid forget $base.tepoch $base.epoch # forget current sys vars set aa [string tolower [string range $dwcs(prev) 3 3]] grid forget $base.twcsname${aa} $base.wcsname${aa} grid forget $base.tradesys${aa} $base.radesys${aa} grid forget $base.tequinox${aa} $base.equinox${aa} grid forget $base.tlatpole${aa} $base.latpole${aa} grid forget $base.tlonpole${aa} $base.lonpole${aa} for {set ii 1} {$ii<=2} {incr ii} { grid forget $base.tctype${ii}${aa} $base.ctype${ii}${aa} grid forget $base.tcunit${ii}${aa} $base.cunit${ii}${aa} grid forget $base.tcrpix${ii}${aa} $base.crpix${ii}${aa} grid forget $base.tcrval${ii}${aa} $base.crval${ii}${aa} grid forget $base.tcdelt${ii}${aa} $base.cdelt${ii}${aa} for {set jj 1} {$jj<=2} {incr jj} { grid forget $base.tcd${ii}_${jj}${aa} $base.cd${ii}_${jj}${aa} grid forget $base.tpc${ii}_${jj}${aa} $base.pc${ii}_${jj}${aa} } for {set mm 0} {$mm<12} {incr mm} { grid forget $pv00.tpv${ii}_${mm}${aa} $pv00.pv${ii}_${mm}${aa} } for {set mm 12} {$mm<24} {incr mm} { grid forget $pv12.tpv${ii}_${mm}${aa} $pv12.pv${ii}_${mm}${aa} } for {set mm 24} {$mm<36} {incr mm} { grid forget $pv24.tpv${ii}_${mm}${aa} $pv24.pv${ii}_${mm}${aa} } } # only in primary grid forget $ab0.ta $ab0.a for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab0.ta_${mm}_${nn} $ab0.a_${mm}_${nn} } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab2.ta_${mm}_${nn} $ab2.a_${mm}_${nn} } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab4.ta_${mm}_${nn} $ab4.a_${mm}_${nn} } } grid forget $ab0.tb $ab0.b for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab0.tb_${mm}_${nn} $ab0.b_${mm}_${nn} } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab2.tb_${mm}_${nn} $ab2.b_${mm}_${nn} } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $ab4.tb_${mm}_${nn} $ab4.b_${mm}_${nn} } } grid forget $apbp0.tap $apbp0.ap for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp0.tap_${mm}_${nn} $apbp0.ap_${mm}_${nn} } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp2.tap_${mm}_${nn} $apbp2.ap_${mm}_${nn} } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp4.tap_${mm}_${nn} $apbp4.ap_${mm}_${nn} } } grid forget $apbp0.tbp $apbp0.bp for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp0.tbp_${mm}_${nn} $apbp0.bp_${mm}_${nn} } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp2.tbp_${mm}_${nn} $apbp2.bp_${mm}_${nn} } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid forget $apbp4.tbp_${mm}_${nn} $apbp4.bp_${mm}_${nn} } } # display new sys vars set dwcs(prev) $dwcs(system) set aa [string tolower [string range $dwcs(system) 3 3]] grid $base.twcsname${aa} $base.wcsname${aa} -padx 2 -pady 2 -sticky w grid $base.tradesys${aa} $base.radesys${aa} -padx 2 -pady 2 -sticky w grid $base.tequinox${aa} $base.equinox${aa} \ $base.tepoch $base.epoch -padx 2 -pady 2 -sticky w grid $base.tmjdobs $base.mjdobs -padx 2 -pady 2 -sticky w grid $base.tdateobs $base.dateobs \ $base.tdate $base.date -padx 2 -pady 2 -sticky w grid $base.tctype1${aa} $base.ctype1${aa} \ $base.tctype2${aa} $base.ctype2${aa} -padx 2 -pady 2 -sticky w grid $base.tcrpix1${aa} $base.crpix1${aa} \ $base.tcrpix2${aa} $base.crpix2${aa} -padx 2 -pady 2 -sticky w grid $base.tcrval1${aa} $base.crval1${aa} \ $base.tcrval2${aa} $base.crval2${aa} -padx 2 -pady 2 -sticky w grid $base.tcunit1${aa} $base.cunit1${aa} \ $base.tcunit2${aa} $base.cunit2${aa} -padx 2 -pady 2 -sticky w grid $base.tcdelt1${aa} $base.cdelt1${aa} \ $base.tcdelt2${aa} $base.cdelt2${aa} -padx 2 -pady 2 -sticky w grid $base.tcd1_1${aa} $base.cd1_1${aa} \ $base.tcd2_1${aa} $base.cd2_1${aa} -padx 2 -pady 2 -sticky w grid $base.tcd1_2${aa} $base.cd1_2${aa} \ $base.tcd2_2${aa} $base.cd2_2${aa} -padx 2 -pady 2 -sticky w grid $base.tpc1_1${aa} $base.pc1_1${aa} \ $base.tpc2_1${aa} $base.pc2_1${aa} -padx 2 -pady 2 -sticky w grid $base.tpc1_2${aa} $base.pc1_2${aa} \ $base.tpc2_2${aa} $base.pc2_2${aa} -padx 2 -pady 2 -sticky w grid $base.tlatpole${aa} $base.latpole${aa} \ $base.tlonpole${aa} $base.lonpole${aa} -padx 2 -pady 2 -sticky w for {set mm 0} {$mm<12} {incr mm} { grid $pv00.tpv1_${mm}${aa} $pv00.pv1_${mm}${aa} \ $pv00.tpv2_${mm}${aa} $pv00.pv2_${mm}${aa} \ -padx 2 -pady 2 -sticky w } for {set mm 12} {$mm<24} {incr mm} { grid $pv12.tpv1_${mm}${aa} $pv12.pv1_${mm}${aa} \ $pv12.tpv2_${mm}${aa} $pv12.pv2_${mm}${aa} \ -padx 2 -pady 2 -sticky w } for {set mm 24} {$mm<36} {incr mm} { grid $pv24.tpv1_${mm}${aa} $pv24.pv1_${mm}${aa} \ $pv24.tpv2_${mm}${aa} $pv24.pv2_${mm}${aa} \ -padx 2 -pady 2 -sticky w } # only in primary grid $ab0.ta $ab0.a $ab0.tb $ab0.b -padx 2 -pady 2 -sticky w for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $ab0.ta_${mm}_${nn} $ab0.a_${mm}_${nn} \ $ab0.tb_${mm}_${nn} $ab0.b_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $ab2.ta_${mm}_${nn} $ab2.a_${mm}_${nn} \ $ab2.tb_${mm}_${nn} $ab2.b_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $ab4.ta_${mm}_${nn} $ab4.a_${mm}_${nn} \ $ab4.tb_${mm}_${nn} $ab4.b_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } grid $apbp0.tap $apbp0.ap $apbp0.tbp $apbp0.bp -padx 2 -pady 2 -sticky w for {set mm 0} {$mm<2} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $apbp0.tap_${mm}_${nn} $apbp0.ap_${mm}_${nn} \ $apbp0.tbp_${mm}_${nn} $apbp0.bp_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } for {set mm 2} {$mm<4} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $apbp2.tap_${mm}_${nn} $apbp2.ap_${mm}_${nn} \ $apbp2.tbp_${mm}_${nn} $apbp2.bp_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } for {set mm 4} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { grid $apbp4.tap_${mm}_${nn} $apbp4.ap_${mm}_${nn} \ $apbp4.tbp_${mm}_${nn} $apbp4.bp_${mm}_${nn} \ -padx 2 -pady 2 -sticky w } } } proc ConfigWCSDialogExtMenu {} { global iwcs global dwcs global ds9 global current $iwcs(mb).ext delete $ds9(menu,start) end set dwcs(ext) 1 set nn 0 set last {} set cnt [$current(frame) get fits count] for {set ii 1} {$ii <= $cnt} {incr ii} { set fn [$current(frame) get fits file name $ii] if {$fn != $last} { incr nn set item($nn) $fn set val($nn) $ii set last $fn } } if {$nn > 1} { $iwcs(mb) entryconfig [msgcat::mc {Extention}] -state normal for {set ii 1} {$ii<=$nn} {incr ii} { $iwcs(mb).ext add radiobutton -label $item($ii) \ -variable dwcs(ext) -value $val($ii) -command UpdateWCSVars } } else { $iwcs(mb) entryconfig [msgcat::mc {Extention}] -state disabled } } # used by backup proc WCSToVar {txt} { global wcs global dwcs global iwcs # clear all set dwcs(mjd-obs) {} set dwcs(date-obs) {} set dwcs(date) {} set dwcs(epoch) {} foreach aa {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set dwcs(wcsname${aa}) {} set dwcs(radesys${aa}) {} set dwcs(equinox${aa}) {} set dwcs(latpole${aa}) {} set dwcs(lonpole${aa}) {} for {set ii 1} {$ii<=2} {incr ii} { set dwcs(ctype${ii}${aa}) {} set dwcs(cunit${ii}${aa}) {} set dwcs(crpix${ii}${aa}) {} set dwcs(crval${ii}${aa}) {} set dwcs(cdelt${ii}${aa}) {} for {set jj 1} {$jj<=2} {incr jj} { set dwcs(cd${ii}_${jj}${aa}) {} set dwcs(pc${ii}_${jj}${aa}) {} } for {set mm 0} {$mm<36} {incr mm} { set dwcs(pv${ii}_${mm}${aa}) {} } } } # primary only set dwcs(a_order) {} for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { set dwcs(a_${mm}_${nn}) {} } } set dwcs(b_order) {} for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { set dwcs(b_${mm}_${nn}) {} } } set dwcs(ap_order) {} for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { set dwcs(ap_${mm}_${nn}) {} } } set dwcs(bp_order) {} for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { set dwcs(bp_${mm}_${nn}) {} } } set lines [split $txt "\n"] # check for fits header, do it the hard way if {[llength $lines] == 1} { set lines {} while {"$txt" != {}} { lappend lines "[string range $txt 0 79]" set txt "[string replace $txt 0 79]" } } for {set ll 0} {$ll<[llength $lines]} {incr ll} { set line [lindex $lines $ll] set pp [split $line {=}] set key [string tolower [string trim [lindex $pp 0]]] # drop comments # some keywords can have '/' in the value (such as a date) # try the easy approach first set ee [lindex $pp 1] set dd [split $ee {/}] switch [llength $dd] { 0 - 1 - 2 {set aa [lindex $dd 0]} default { set ff [string first { /} $ee] if {$ff > 0} { set aa [string range $ee 0 $ff] } else { set aa [lindex $dd 0] } } } # drop any white space set bb [string trim $aa] # drop any single quotes set cc [string trim $bb {'}] # drop any white space set val [string trim $cc] # sanity check if {$key == {longpole}} { set key lonpole } if {$key == {radecsys}} { set key radesys } switch [string range $key 0 6] { mjd-obs - date-ob { set dwcs($key) $val } } switch [string range $key 0 5] { wcsnam - radesy - equino - latpol - lonpol - ctype1 - ctype2 - cunit1 - cunit2 - crpix1 - crpix2 - crval1 - crval2 - cdelt1 - cdelt2 - a_orde - b_orde - ap_ord - bp_ord { set dwcs($key) $val } } switch [string range $key 0 3] { epoc - date - cd1_ - cd1_ - cd2_ - cd2_ - pc1_ - pc1_ - pc2_ - pc2_ - pv1_ - pv2_ { set dwcs($key) $val } } switch [string range $key 0 2] { ap_ - bp_ { set dwcs($key) $val } } switch [string range $key 0 1] { a_ - b_ { set dwcs($key) $val } } } } # used by backup proc WCSFromVar {} { global wcs global dwcs global iwcs set rr {} if {$dwcs(mjd-obs) != {}} { append rr "MJD-OBS = $dwcs(mjd-obs)\n" } if {$dwcs(date-obs) != {}} { append rr "DATE-OBS = '$dwcs(date-obs)'\n" } if {$dwcs(date) != {}} { append rr "DATE = '$dwcs(date)'\n" } if {$dwcs(epoch) != {}} { append rr "EPOCH = $dwcs(epoch)\n" } foreach aa {{} a b c d e f g h i j k l m n o p q r s t u v w x y z} { set bb [string toupper $aa] if {$dwcs(wcsname${aa}) != {}} { append rr "WCSNAME${bb} = '$dwcs(wcsname${aa})'\n" } if {$dwcs(radesys${aa}) != {}} { append rr "RADESYS${bb} = '$dwcs(radesys${aa})'\n" } if {$dwcs(equinox${aa}) != {}} { append rr "EQUINOX${bb} = $dwcs(equinox${aa})\n" } if {$dwcs(latpole${aa}) != {}} { append rr "LATPOLE${bb} = $dwcs(latpole${aa})\n" } if {$dwcs(lonpole${aa}) != {}} { append rr "LONPOLE${bb} = $dwcs(lonpole${aa})\n" } for {set ii 1} {$ii<=2} {incr ii} { if {$dwcs(ctype${ii}${aa}) != {}} { append rr "CTYPE${ii}${bb} = '$dwcs(ctype${ii}${aa})'\n" } if {$dwcs(cunit${ii}${aa}) != {}} { append rr "CUNIT${ii}${bb} = '$dwcs(cunit${ii}${aa})'\n" } if {$dwcs(crpix${ii}${aa}) != {}} { append rr "CRPIX${ii}${bb} = $dwcs(crpix${ii}${aa})\n" } if {$dwcs(crval${ii}${aa}) != {}} { append rr "CRVAL${ii}${bb} = $dwcs(crval${ii}${aa})\n" } if {$dwcs(cdelt${ii}${aa}) != {}} { append rr "CDELT${ii}${bb} = $dwcs(cdelt${ii}${aa})\n" } for {set jj 1} {$jj<=2} {incr jj} { if {$dwcs(cd${ii}_${jj}${aa}) != {}} { append rr "CD${ii}_${jj}${bb} = $dwcs(cd${ii}_${jj}${aa})\n" } if {$dwcs(pc${ii}_${jj}${aa}) != {}} { append rr "PC${ii}_${jj}${bb} = $dwcs(pc${ii}_${jj}${aa})\n" } } for {set mm 0} {$mm<36} {incr mm} { if {$dwcs(pv${ii}_${mm}${aa}) != {}} { append rr "PV${ii}_${mm}${bb} = $dwcs(pv${ii}_${mm}${aa})\n" } } } } if {$dwcs(a_order) != {}} { append rr "A_ORDER = $dwcs(a_order)\n" } for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { if {$dwcs(a_${mm}_${nn}) != {}} { append rr "A_${mm}_${nn} = $dwcs(a_${mm}_${nn})\n" } } } if {$dwcs(b_order) != {}} { append rr "B_ORDER = $dwcs(b_order)\n" } for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { if {$dwcs(b_${mm}_${nn}) != {}} { append rr "B_${mm}_${nn} = $dwcs(b_${mm}_${nn})\n" } } } if {$dwcs(ap_order) != {}} { append rr "AP_ORDER = $dwcs(ap_order)\n" } for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { if {$dwcs(ap_${mm}_${nn}) != {}} { append rr "AP_${mm}_${nn} = $dwcs(ap_${mm}_${nn})\n" } } } if {$dwcs(bp_order) != {}} { append rr "BP_ORDER = $dwcs(bp_order)\n" } for {set mm 0} {$mm<6} {incr mm} { for {set nn 0} {$nn<6} {incr nn} { if {$dwcs(bp_${mm}_${nn}) != {}} { append rr "BP_${mm}_${nn} = $dwcs(bp_${mm}_${nn})\n" } } } return $rr } # Process Cmds proc ProcessWCSCmd {varname iname sock fn} { upvar $varname var upvar $iname i global wcs global current global rgb set item [string tolower [lindex $var $i]] switch -- $item { open {WCSDialog} close {WCSDestroyDialog} system { incr i set wcs(system) [string tolower [lindex $var $i]] UpdateWCS } sky { incr i set wcs(sky) [string tolower [lindex $var $i]] UpdateWCS } format - skyformat { incr i switch -- [string tolower [lindex $var $i]] { deg - degree - degrees {set wcs(skyformat) degrees} default {set wcs(skyformat) [string tolower [lindex $var $i]]} } UpdateWCS } align { incr i set current(align) [FromYesNo [lindex $var $i]] AlignWCSFrame } reset { set ext 1 set nn [lindex $var [expr $i+1]] if {[string is integer -strict $nn]} { incr i set ext $nn } RGBEvalLock rgb(lock,wcs) $current(frame) [list $current(frame) wcs reset $ext] UpdateWCS } replace - append { set ext 1 set nn [lindex $var [expr $i+1]] if {[string is integer -strict $nn]} { incr i set ext $nn } if {$sock != {}} { incr i if {[lindex $var $i] == {}} { RGBEvalLock rgb(lock,wcs) $current(frame) [list $current(frame) wcs $item $ext $sock] incr i -1 } else { RGBEvalLock rgb(lock,wcs) $current(frame) "$current(frame) wcs $item $ext \{\{[lindex $var $i]\}\}" } } elseif {$fn != {}} { RGBEvalLock rgb(lock,wcs) $current(frame) "$current(frame) wcs $item $ext \{\{$fn\}\}" } else { incr i if {[lindex $var $i] == "file"} { incr i } RGBEvalLock rgb(lock,wcs) $current(frame) "$current(frame) wcs $item $ext \{\{[lindex $var $i]\}\}" } UpdateWCS } fk4 - fk5 - icrs - galactic - ecliptic { set wcs(sky) $item UpdateWCS } degrees - sexagesimal { set wcs(skyformat) $item UpdateWCS } wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz { set wcs(system) $item UpdateWCS } } } proc ProcessSendWCSCmd {proc id param} { global current global wcs switch -- [string tolower $param] { align {$proc $id [ToYesNo $current(align)]} system {$proc $id "$wcs(system)\n"} sky {$proc $id "$wcs(sky)\n"} format - skyformat {$proc $id "$wcs(skyformat)\n"} default {$proc $id "$wcs(system)\n"} } } # backward compatibilty proc ProcessAlignCmd {varname iname} { upvar $varname var upvar $iname i global current switch -- [string tolower [lindex $var $i]] { yes - true - on - 1 - no - false - off - 0 { set current(align) [FromYesNo [lindex $var $i]] AlignWCSFrame } default { set current(align) 1 AlignWCSFrame incr i -1 } } } proc ProcessSendAlignCmd {proc id param} { global current $proc $id [ToYesNo $current(align)] } ���������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/external.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000002373�11700665567�014242� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc InitExternalFile {} { global ds9 if {[file exists "./$ds9(ext,file)"]} { ProcessExternalFile "./$ds9(ext,file)" } elseif {[file exists "./$ds9(ext,alt)"]} { ProcessExternalFile "./$ds9(ext,alt)" } elseif {[file exists "~/$ds9(ext,file)"]} { ProcessExternalFile "~/$ds9(ext,file)" } elseif {[file exists "~/$ds9(ext,alt)"]} { ProcessExternalFile "~/$ds9(ext,alt)" } } proc ProcessExternalFile {fn} { global extFits set status 1 if [file exists "$fn"] { set id [open $fn r] while {[gets $id line] >= 0} { # empty line if {[string length $line] == 0} continue # comments if {[string range $line 0 0] == "\#"} continue # else switch -- $status { 1 { # eat the line set template {} set status 2 } 2 { set template "$line" set status 3 } 3 { # eat the line set status 4 } 4 { if {"$template" != {} && "$line" != {}} { foreach t $template { set extFits($t) "$line" } } set status 1 } } } close $id } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mzoom.tcl������������������������������������������������������������������������������0000644�0001750�0001750�00000037223�12117712633�013551� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # Menus proc ZoomMainMenu {} { global ds9 menu $ds9(mb).zoom $ds9(mb).zoom add command -label [msgcat::mc {Center Image}] \ -command CenterCurrentFrame $ds9(mb).zoom add separator $ds9(mb).zoom add checkbutton -label [msgcat::mc {Align}] \ -variable current(align) -command AlignWCSFrame $ds9(mb).zoom add separator $ds9(mb).zoom add command -label [msgcat::mc {Zoom In}] \ -command {Zoom 2 2} $ds9(mb).zoom add command -label [msgcat::mc {Zoom Out}] \ -command {Zoom .5 .5} $ds9(mb).zoom add separator $ds9(mb).zoom add command -label [msgcat::mc {Zoom to Fit Frame}] \ -command ZoomToFit $ds9(mb).zoom add separator $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/32" \ -variable current(zoom) -value { 0.03125 0.03125 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/16" \ -variable current(zoom) -value { 0.0625 0.0625 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/8" \ -variable current(zoom) -value { 0.125 0.125 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/4" \ -variable current(zoom) -value { 0.25 0.25 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1/2" \ -variable current(zoom) -value { 0.5 0.5 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 1" \ -variable current(zoom) -value { 1 1 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 2" \ -variable current(zoom) -value { 2 2 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 4" \ -variable current(zoom) -value { 4 4 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 8" \ -variable current(zoom) -value { 8 8 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 16" \ -variable current(zoom) -value { 16 16 } -command ChangeZoom $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Zoom}] 32" \ -variable current(zoom) -value { 32 32 } -command ChangeZoom $ds9(mb).zoom add separator $ds9(mb).zoom add radiobutton -label [msgcat::mc {None}] \ -variable current(orient) -value none -command ChangeOrient $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Invert}] X" \ -variable current(orient) -value x -command ChangeOrient $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Invert}] Y" \ -variable current(orient) -value y -command ChangeOrient $ds9(mb).zoom add radiobutton -label "[msgcat::mc {Invert}] XY" \ -variable current(orient) -value xy -command ChangeOrient $ds9(mb).zoom add separator $ds9(mb).zoom add radiobutton -label "0 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 0 -command ChangeRotate $ds9(mb).zoom add radiobutton -label "90 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 90 -command ChangeRotate $ds9(mb).zoom add radiobutton -label "180 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 180 -command ChangeRotate $ds9(mb).zoom add radiobutton -label "270 [msgcat::mc {Degrees}]" \ -variable current(rotate) -value 270 -command ChangeRotate $ds9(mb).zoom add separator $ds9(mb).zoom add command -label "[msgcat::mc {Crop Parameters}]..." \ -command CropDialog $ds9(mb).zoom add separator $ds9(mb).zoom add command \ -label "[msgcat::mc {Pan Zoom Rotate Parameters}]..." \ -command PanZoomDialog } proc PrefsDialogZoomMenu {w} { set f [ttk::labelframe $w.mzoom -text [msgcat::mc {Zoom}]] ttk::menubutton $f.menu -text [msgcat::mc {Menu}] -menu $f.menu.menu PrefsDialogButtonbarZoom $f.buttonbar grid $f.menu $f.buttonbar -padx 2 -pady 2 set m $f.menu.menu menu $m $m add checkbutton -label [msgcat::mc {Align}] \ -variable pcurrent(align) $m add separator $m add radiobutton -label "[msgcat::mc {Zoom}] 1/32" \ -variable pcurrent(zoom) -value { 0.03125 0.03125 } $m add radiobutton -label "[msgcat::mc {Zoom}] 1/16" \ -variable pcurrent(zoom) -value { 0.0625 0.0625 } $m add radiobutton -label "[msgcat::mc {Zoom}] 1/8" \ -variable pcurrent(zoom) -value { 0.125 0.125 } $m add radiobutton -label "[msgcat::mc {Zoom}] 1/4" \ -variable pcurrent(zoom) -value { 0.25 0.25 } $m add radiobutton -label "[msgcat::mc {Zoom}] 1/2" \ -variable pcurrent(zoom) -value { 0.5 0.5 } $m add radiobutton -label "[msgcat::mc {Zoom}] 1" \ -variable pcurrent(zoom) -value { 1 1 } $m add radiobutton -label "[msgcat::mc {Zoom}] 2" \ -variable pcurrent(zoom) -value { 2 2 } $m add radiobutton -label "[msgcat::mc {Zoom}] 4" \ -variable pcurrent(zoom) -value { 4 4 } $m add radiobutton -label "[msgcat::mc {Zoom}] 8" \ -variable pcurrent(zoom) -value { 8 8 } $m add radiobutton -label "[msgcat::mc {Zoom}] 16" \ -variable pcurrent(zoom) -value { 16 16 } $m add radiobutton -label "[msgcat::mc {Zoom}] 32" \ -variable pcurrent(zoom) -value { 32 32 } $m add separator $m add radiobutton -label [msgcat::mc {None}] \ -variable pcurrent(orient) -value none $m add radiobutton -label "[msgcat::mc {Invert}] X" \ -variable pcurrent(orient) -value x $m add radiobutton -label "[msgcat::mc {Invert}] Y" \ -variable pcurrent(orient) -value y $m add radiobutton -label "[msgcat::mc {Invert}] XY" \ -variable pcurrent(orient) -value xy $m add separator $m add radiobutton -label "0 [msgcat::mc {Degrees}]" \ -variable pcurrent(rotate) -value 0 $m add radiobutton -label "90 [msgcat::mc {Degrees}]" \ -variable pcurrent(rotate) -value 90 $m add radiobutton -label "180 [msgcat::mc {Degrees}]" \ -variable pcurrent(rotate) -value 180 $m add radiobutton -label "270 [msgcat::mc {Degrees}]" \ -variable pcurrent(rotate) -value 270 pack $f -side top -fill both -expand true } proc PrefsDialogZoom {} { global dprefs set w $dprefs(tab) $dprefs(list) insert end [msgcat::mc {Zoom}] lappend dprefs(tabs) [ttk::frame $w.zoom] # PanZoom set f [ttk::labelframe $w.zoom.panzoom -text [msgcat::mc {Pan Zoom}]] ttk::radiobutton $f.click -text [msgcat::mc {Click to Center}] \ -variable ppanzoom(mode) -value click ttk::radiobutton $f.drag -text [msgcat::mc {Drag to Center}] \ -variable ppanzoom(mode) -value drag ttk::radiobutton $f.panzoom -text [msgcat::mc {Pan then Zoom}] \ -variable ppanzoom(mode) -value panzoom grid $f.click $f.drag $f.panzoom -padx 2 -pady 2 -sticky w # Mouse set f [ttk::labelframe $w.zoom.mouse -text [msgcat::mc {Mouse Wheel Zoom}]] ttk::checkbutton $f.click -text [msgcat::mc {Enable}] \ -variable ppanzoom(wheel) ttk::label $f.title2 -text [msgcat::mc {Factor}] ttk::entry $f.factor -textvariable ppanzoom(wheel,factor) -width 10 grid $f.click $f.title2 $f.factor -padx 2 -pady 2 -sticky w pack $w.zoom.panzoom $w.zoom.mouse -side top -fill both -expand true } # Buttons proc ButtonsZoomDef {} { global pbuttons array set pbuttons { zoom,center 0 zoom,align 0 zoom,in 1 zoom,out 1 zoom,fit 1 zoom,i32 0 zoom,i16 0 zoom,i8 1 zoom,i4 1 zoom,i2 1 zoom,1 1 zoom,2 1 zoom,4 1 zoom,8 1 zoom,16 0 zoom,32 0 zoom,none 0 zoom,x 0 zoom,y 0 zoom,xy 0 zoom,0 0 zoom,90 0 zoom,180 0 zoom,270 0 zoom,crop 0 zoom,params 0 } } proc CreateButtonsZoom {} { global buttons global ds9 ttk::frame $ds9(buttons).zoom ButtonButton $ds9(buttons).zoom.center \ [string tolower [msgcat::mc {Center}]] CenterCurrentFrame CheckButton $ds9(buttons).zoom.align \ [msgcat::mc {Align}] current(align) AlignWCSFrame ButtonButton $ds9(buttons).zoom.in {-} {Zoom .5 .5} ButtonButton $ds9(buttons).zoom.out {+} {Zoom 2 2} ButtonButton $ds9(buttons).zoom.fit \ [string tolower [msgcat::mc {To Fit}]] ZoomToFit RadioButton $ds9(buttons).zoom.i32 \ "[string tolower [msgcat::mc {Zoom}]] 1/32" \ current(zoom) { 0.03125 0.03125 } ChangeZoom RadioButton $ds9(buttons).zoom.i16 \ "[string tolower [msgcat::mc {Zoom}]] 1/16" \ current(zoom) { 0.0625 0.0625 } ChangeZoom RadioButton $ds9(buttons).zoom.i8 \ "[string tolower [msgcat::mc {Zoom}]] 1/8" \ current(zoom) { 0.125 0.125 } ChangeZoom RadioButton $ds9(buttons).zoom.i4 \ "[string tolower [msgcat::mc {Zoom}]] 1/4" \ current(zoom) { 0.25 0.25 } ChangeZoom RadioButton $ds9(buttons).zoom.i2 \ "[string tolower [msgcat::mc {Zoom}]] 1/2" \ current(zoom) { 0.5 0.5 } ChangeZoom RadioButton $ds9(buttons).zoom.1 \ "[string tolower [msgcat::mc {Zoom}]] 1" \ current(zoom) { 1 1 } ChangeZoom RadioButton $ds9(buttons).zoom.2 \ "[string tolower [msgcat::mc {Zoom}]] 2" \ current(zoom) { 2 2 } ChangeZoom RadioButton $ds9(buttons).zoom.4 \ "[string tolower [msgcat::mc {Zoom}]] 4" \ current(zoom) { 4 4 } ChangeZoom RadioButton $ds9(buttons).zoom.8 \ "[string tolower [msgcat::mc {Zoom}]] 8" \ current(zoom) { 8 8 } ChangeZoom RadioButton $ds9(buttons).zoom.16 \ "[string tolower [msgcat::mc {Zoom}]] 16" \ current(zoom) { 16 16 } ChangeZoom RadioButton $ds9(buttons).zoom.32 \ "[string tolower [msgcat::mc {Zoom}]] 32" \ current(zoom) { 32 32 } ChangeZoom RadioButton $ds9(buttons).zoom.none \ [string tolower [msgcat::mc {None}]] \ current(orient) none ChangeOrient RadioButton $ds9(buttons).zoom.x {x} current(orient) x ChangeOrient RadioButton $ds9(buttons).zoom.y {y} current(orient) y ChangeOrient RadioButton $ds9(buttons).zoom.xy {xy} current(orient) xy ChangeOrient RadioButton $ds9(buttons).zoom.0 {0} current(rotate) 0 ChangeRotate RadioButton $ds9(buttons).zoom.90 {90} current(rotate) 90 ChangeRotate RadioButton $ds9(buttons).zoom.180 {180} current(rotate) 180 ChangeRotate RadioButton $ds9(buttons).zoom.270 {270} current(rotate) 270 ChangeRotate ButtonButton $ds9(buttons).zoom.crop \ [string tolower [msgcat::mc {Crop}]] CropDialog ButtonButton $ds9(buttons).zoom.params \ [string tolower [msgcat::mc {Parameters}]] PanZoomDialog set buttons(zoom) " $ds9(buttons).zoom.center pbuttons(zoom,center) $ds9(buttons).zoom.align pbuttons(zoom,align) $ds9(buttons).zoom.in pbuttons(zoom,in) $ds9(buttons).zoom.out pbuttons(zoom,out) $ds9(buttons).zoom.fit pbuttons(zoom,fit) $ds9(buttons).zoom.i32 pbuttons(zoom,i32) $ds9(buttons).zoom.i16 pbuttons(zoom,i16) $ds9(buttons).zoom.i8 pbuttons(zoom,i8) $ds9(buttons).zoom.i4 pbuttons(zoom,i4) $ds9(buttons).zoom.i2 pbuttons(zoom,i2) $ds9(buttons).zoom.1 pbuttons(zoom,1) $ds9(buttons).zoom.2 pbuttons(zoom,2) $ds9(buttons).zoom.4 pbuttons(zoom,4) $ds9(buttons).zoom.8 pbuttons(zoom,8) $ds9(buttons).zoom.16 pbuttons(zoom,16) $ds9(buttons).zoom.32 pbuttons(zoom,32) $ds9(buttons).zoom.none pbuttons(zoom,none) $ds9(buttons).zoom.x pbuttons(zoom,x) $ds9(buttons).zoom.y pbuttons(zoom,y) $ds9(buttons).zoom.xy pbuttons(zoom,xy) $ds9(buttons).zoom.0 pbuttons(zoom,0) $ds9(buttons).zoom.90 pbuttons(zoom,90) $ds9(buttons).zoom.180 pbuttons(zoom,180) $ds9(buttons).zoom.270 pbuttons(zoom,270) $ds9(buttons).zoom.crop pbuttons(zoom,crop) $ds9(buttons).zoom.params pbuttons(zoom,params) " } proc PrefsDialogButtonbarZoom {f} { global buttons global pbuttons ttk::menubutton $f -text [msgcat::mc {Buttonbar}] -menu $f.menu set m $f.menu menu $m $m add checkbutton -label [msgcat::mc {Center Image}] \ -variable pbuttons(zoom,center) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label [msgcat::mc {Align}] \ -variable pbuttons(zoom,align) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label [msgcat::mc {Zoom In}] \ -variable pbuttons(zoom,in) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label [msgcat::mc {Zoom Out}] \ -variable pbuttons(zoom,out) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label [msgcat::mc {Zoom to Fit Frame}] \ -variable pbuttons(zoom,fit) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label "[msgcat::mc {Zoom}] 1/32" \ -variable pbuttons(zoom,i32) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 1/16" \ -variable pbuttons(zoom,i16) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 1/8" \ -variable pbuttons(zoom,i8) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 1/4" \ -variable pbuttons(zoom,i4) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 1/2" \ -variable pbuttons(zoom,i2) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 1" \ -variable pbuttons(zoom,1) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 2" \ -variable pbuttons(zoom,2) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 4" \ -variable pbuttons(zoom,4) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 8" \ -variable pbuttons(zoom,8) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 16" \ -variable pbuttons(zoom,16) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Zoom}] 32" \ -variable pbuttons(zoom,32) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label [msgcat::mc {None}] \ -variable pbuttons(zoom,none) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Invert}] X" \ -variable pbuttons(zoom,x) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Invert}] Y" \ -variable pbuttons(zoom,y) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "[msgcat::mc {Invert}] XY" \ -variable pbuttons(zoom,xy) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label "0 [msgcat::mc {Degrees}]" \ -variable pbuttons(zoom,0) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "90 [msgcat::mc {Degrees}]" \ -variable pbuttons(zoom,90) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "180 [msgcat::mc {Degrees}]" \ -variable pbuttons(zoom,180) -command {UpdateButtons buttons(zoom)} $m add checkbutton -label "270 [msgcat::mc {Degrees}]" \ -variable pbuttons(zoom,270) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label "[msgcat::mc {Crop Parameters}]..." \ -variable pbuttons(zoom,crop) -command {UpdateButtons buttons(zoom)} $m add separator $m add checkbutton -label "[msgcat::mc {Pan Zoom Rotate Parameters}]..." \ -variable pbuttons(zoom,params) -command {UpdateButtons buttons(zoom)} } # Support proc UpdateZoomMenuStatic {} { global ds9 global debug if {$debug(tcl,update)} { puts stderr "UpdateZoomMenuStatic" } if {$ds9(active,num) > 0} { $ds9(mb) entryconfig [msgcat::mc {Zoom}] -state normal } else { $ds9(mb) entryconfig [msgcat::mc {Zoom}] -state disabled } } proc UpdateZoomMenu {} { global ds9 global current global panzoom global debug if {$debug(tcl,update)} { puts stderr "UpdateZoomMenu" } if {$current(frame) == {}} { $ds9(mb).zoom entryconfig [msgcat::mc {Align}] -state disabled } else { $ds9(mb).zoom entryconfig [msgcat::mc {Align}] -state normal set panzoom(preserve) [$current(frame) get pan preserve] set current(zoom) [$current(frame) get zoom] set current(rotate) [$current(frame) get rotate] set current(orient) [$current(frame) get orient] set current(align) [$current(frame) get wcs align] } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/analysis.tcl���������������������������������������������������������������������������0000644�0001750�0001750�00000120124�12131573627�014230� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc AnalysisDef {} { global ianalysis global panalysis global ds9 set ianalysis(menu,count) 0 set ianalysis(menu,hmenu,count) 0 set ianalysis(menu,hmenu) {} set ianalysis(bind,count) 0 set ianalysis(param,count) 0 set ianalysis(param,seq) 0 set ianalysis(file) ".$ds9(app).ans" set ianalysis(alt) ".$ds9(app).analysis" # prefs only set panalysis(log) 0 set panalysis(autoload) 1 set panalysis(user) {} set panalysis(user2) {} set panalysis(user3) {} set panalysis(user4) {} } proc OpenAnalysisMenu {} { set fn [OpenFileDialog analysisfbox] if {$fn != {}} { ProcessAnalysisFile $fn } } proc ClearAnalysisMenu {} { global pds9 if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message [msgcat::mc {Clear External Analysis Commands?}]] != {ok}} { return } } ClearAnalysis } # Analysis Menu Delete proc ClearAnalysis {} { global ds9 global ianalysis # is something loaded? if {$ianalysis(menu,count) == 0} { return } # delete cascade menus for {set i 0} {$i<$ianalysis(menu,hmenu,count)} {incr i} { destroy [lindex $ianalysis(menu,hmenu) $i] } set ianalysis(menu,hmenu) {} set ianalysis(menu,hmenu,count) 0 # clear menu $ds9(mb).analysis delete $ds9(menu,size,analysis) end for {set i 0} {$i<$ianalysis(menu,count)} {incr i} { unset ianalysis(menu,$i,parent) unset ianalysis(menu,$i,item) unset ianalysis(menu,$i,template) unset ianalysis(menu,$i,cmd) unset ianalysis(menu,$i,inuse) unset ianalysis(menu,$i,var) } set ianalysis(menu,count) 0 # clear all bindings, first foreach f $ds9(frames) { for {set i 0} {$i<$ianalysis(bind,count)} {incr i} { $ds9(canvas) bind $f "$ianalysis(bind,$i,item)" {} } } # clear bindings for {set i 0} {$i<$ianalysis(bind,count)} {incr i} { unset ianalysis(bind,$i,item) unset ianalysis(bind,$i,template) unset ianalysis(bind,$i,cmd) unset ianalysis(bind,$i,inuse) } set ianalysis(bind,count) 0 # clear params for {set i 0} {$i<$ianalysis(param,count)} {incr i} { for {set j 0} {$j<$ianalysis(param,$i,count)} {incr j} { unset ianalysis(param,$i,$j,var) unset ianalysis(param,$i,$j,type) unset ianalysis(param,$i,$j,title) unset ianalysis(param,$i,$j,default) unset ianalysis(param,$i,$j,last) unset ianalysis(param,$i,$j,value) unset ianalysis(param,$i,$j,info) } unset ianalysis(param,$i,count) unset ianalysis(param,$i) } set ianalysis(param,count) 0 } proc InitAnalysisFile {} { global ianalysis global panalysis global ds9 set done {} # autoload if {$panalysis(autoload)} { foreach dir [list {.} "[GetEnvHome]/bin" {/usr/local/bin} {/opt/local/bin} {/soft/saord/bin}] { foreach fn [glob -directory $dir -nocomplain "*.ds9"] { if {[file exists $fn]} { ProcessAnalysisFile $fn lappend done $fn } } } } # default name ds9.ans # backward compatible ds9.analysis foreach ff {{.} {~}} { foreach gg {{} {.}} { foreach ext {{ans} {analysis}} { set fn "$ff/$gg$ds9(app).$ext" if {[file exists $fn]} { if {[lsearch $done $fn] == -1} { ProcessAnalysisFile $fn lappend done $fn } } } } } # user specified foreach ii {{user} {user2} {user3} {user4}} { if {[info exists panalysis($ii)]} { set fn $panalysis($ii) if {[file exists $fn]} { if {[lsearch $done $fn] == -1} { ProcessAnalysisFile $fn lappend done $fn } } } } UpdateAnalysisMenu } proc ProcessAnalysisFile {fn} { global env if {[file exists "$fn"]} { set ch [open $fn r] set data [read $ch] ProcessAnalysis data close $ch # add directory to path set env(PATH) "[file dirname $fn]:$env(PATH)" } else { Error "[msgcat::mc {Unable to open file}] $fn" } } proc ProcessAnalysis {varname} { upvar $varname var global ds9 global ianalysis set state 1 set baseparent $ds9(mb).analysis set currentparent $baseparent set parentstack $baseparent $baseparent add separator set lines [split $var \n] set l [llength $lines] for {set ii 0} {$ii<$l} {incr ii} { set line [string trim [lindex $lines $ii]] # eat empty lines and comments for all except help if {$state != 6} { # empty line if {[string length $line] == 0} continue # comments if {[string range $line 0 0] == "\#"} continue # strip any end of line comments set id [string first "\#" $line] if {$id > 0} { set line [string range $line 0 [expr $id-1]] } } switch -- $state { 1 { # param if {[lindex $line 0] == {param}} { if {[lindex $line 1] != {}} { set ianalysis(param,$ianalysis(param,count)) \ [lindex $line 1] set ianalysis(param,$ianalysis(param,count),count) 0 set state 5 } continue } # help if {[lindex $line 0] == {help}} { set id [string first " " $line] if {$id > 0} { set item [string range $line [expr $id+1] end] } else { set item Help } set i $ianalysis(menu,count) set ianalysis(menu,$i,parent) $currentparent set ianalysis(menu,$i,item) $item set ianalysis(menu,$i,template) {*} set ianalysis(menu,$i,cmd) {help} set ianalysis(menu,$i,inuse) 0 set ianalysis(menu,$i,var) {} $currentparent add command -label $item \ -command [list AnalysisTask $i menu] set state 6 continue } # hmenu if {[lindex $line 0] == {hmenu}} { set id [string first " " $line] if {$id > 0} { set item [string range $line [expr $id+1] end] } else { set item Tasks } # make the menu label unique set nmenu "$currentparent.hmenu$ianalysis(menu,hmenu,count)" lappend ianalysis(menu,hmenu) $nmenu incr ianalysis(menu,hmenu,count) menu $nmenu $currentparent add cascade -label "$item" -menu $nmenu set currentparent $nmenu lappend parentstack $currentparent continue } # end hmenu if {[lindex $line 0] == {endhmenu} || [lindex $line 0] == {end}} { set parentstack [lreplace $parentstack end end] set currentparent [lindex $parentstack end] continue } if {[lindex $line 0] == {---}} { $currentparent add separator continue } # assume new command set item "$line" set template {} set type {} set cmd {} set state 2 } 2 { set template "$line" set state 3 } 3 { set type "$line" set state 4 } 4 { set cmd "$line" if {$item != {} && $template != {} && $type != {} && $cmd != {}} { switch -- [lindex $type 0] { bind { set b [lindex $type 1] if {$b != {}} { set i $ianalysis(bind,count) set ianalysis(bind,$i,item) "<$b>" set ianalysis(bind,$i,template) "$template" set ianalysis(bind,$i,cmd) "$cmd" set ianalysis(bind,$i,inuse) 0 incr ianalysis(bind,count) } } web { set i $ianalysis(menu,count) set ianalysis(menu,$i,parent) $currentparent set ianalysis(menu,$i,item) $item set ianalysis(menu,$i,template) "$template" set ianalysis(menu,$i,cmd) {web} set ianalysis(menu,$i,inuse) 0 set ianalysis(menu,$i,var) "$cmd" $currentparent add command -label "$item" \ -command [list AnalysisTask $i menu] incr ianalysis(menu,count) } default { set i $ianalysis(menu,count) set ianalysis(menu,$i,parent) $currentparent set ianalysis(menu,$i,item) "$item" set ianalysis(menu,$i,template) "$template" set ianalysis(menu,$i,cmd) "$cmd" set ianalysis(menu,$i,inuse) 0 set ianalysis(menu,$i,var) {} $currentparent add check -label "$item" \ -command [list AnalysisTask $i menu] \ -variable ianalysis(menu,$i,inuse) \ -selectcolor green incr ianalysis(menu,count) } } } set state 1 } 5 { # end param if {[lindex $line 0] == {endparam} || [lindex $line 0] == {end}} { incr ianalysis(param,count) set state 1 continue } if {[string range $line 0 0] == {@}} { ParseIRAFParam [string range $line 1 end] continue } set i $ianalysis(param,count) set j $ianalysis(param,$i,count) set ianalysis(param,$i,$j,var) [lindex $line 0] set ianalysis(param,$i,$j,type) [lindex $line 1] set ianalysis(param,$i,$j,title) [lindex $line 2] # default can contain the full menu 'aaa|bbb|ccc' set ianalysis(param,$i,$j,default) [lindex $line 3] # set last to first item set ianalysis(param,$i,$j,last) \ [lindex [split [lindex $line 3] |] 0] # and set value to last set ianalysis(param,$i,$j,value) \ $ianalysis(param,$i,$j,last) set ianalysis(param,$i,$j,info) [lindex $line 4] incr ianalysis(param,$i,count) } 6 { # end help if {[lindex $line 0] == {endhelp} || [lindex $line 0] == {end}} { incr ianalysis(menu,count) set state 1 continue } set i $ianalysis(menu,count) append ianalysis(menu,$i,var) "$line\n" } } } # events UnBindEventsCanvas BindEventsCanvas UpdateAnalysisMenu } proc AnalysisTask {i which {frame {}} {x 0} {y 0} {sync 0}} { global ianalysis switch -- $ianalysis($which,$i,cmd) { help { AnalysisText "at${which}${i}" $ianalysis($which,$i,item) \ $ianalysis($which,$i,var) insert } web {AnalysisWebDoit $i $which $frame $x $y $sync} default {AnalysisTaskDoit $i $which $frame $x $y $sync} } } proc AnalysisWebDoit {i which frame x y sync} { global ianalysis global panalysis set cmd "$ianalysis($which,$i,var)" # do select macro expansion # escaped macros SetEscapedMacros cmd # $xpa_method ParseXPAMethodMacro cmd # $xpa ParseXPAMacro cmd # $vo_method ParseVOMethodMacro cmd # $xdim,$ydim,$bitpix ParseXYBitpixMacro cmd # $filename[$regions] ParseFilenameRegionMacro cmd # $filename ParseFilenameMacro cmd # $filedialog ParseFileDialogMacro cmd # $regions ParseRegionMacro cmd # $env ParseEnvMacro cmd # $cen ParsePanMacro cmd # $value ParseValueMacro cmd $frame $x $y # $x,$y ParseXYMacro cmd $frame $x $y # $z ParseZMacro cmd $frame # escaped macros UnsetEscapedMacros cmd if {$panalysis(log)} { SimpleTextDialog acmd [msgcat::mc {Analysis Commands}] 80 20 append bottom "$cmd\n" } HVAnalysisCmd "at${which}${i}" "$ianalysis($which,$i,item)" "$cmd" $sync } proc AnalysisTaskDoit {i which frame x y sync} { global ianalysis global current global pds9 if {[info exists ianalysis($which,$i,pid)]} { set ianalysis($which,$i,inuse) 1 if {$pds9(confirm)} { if {[tk_messageBox -type okcancel -icon question -message [msgcat::mc {This analysis task is already running. Do you wish to kill it?}]] != {ok}} { return } } if {[info exists ianalysis($which,$i,pid)]} { if {$ianalysis($which,$i,pid)>0} { eval "exec kill -9 $ianalysis($which,$i,pid)" } else { HVAnalysisCancel $which $i } } return } # don't turn on til task has started set ianalysis($which,$i,inuse) 0 set ianalysis($which,$i,start) {} set ianalysis($which,$i,start,fn) {} set ianalysis($which,$i,start,url) {} set ianalysis($which,$i,finish) {} set ianalysis($which,$i,result) {} set ianalysis($which,$i,plot,title) {} set ianalysis($which,$i,plot,xaxis) {} set ianalysis($which,$i,plot,yaxis) {} set ianalysis($which,$i,plot,dim) 2 set ianalysis($which,$i,image) {} set cmd $ianalysis($which,$i,cmd) # escaped macros SetEscapedMacros cmd # $data ParseDataMacro cmd $which $i # $xpa_method ParseXPAMethodMacro cmd # $xpa ParseXPAMacro cmd # $vo_method ParseVOMethodMacro cmd # $xdim,$ydim,$bitpix ParseXYBitpixMacro cmd # $filename[$regions] ParseFilenameRegionMacro cmd # $filename ParseFilenameMacro cmd # $filedialog ParseFileDialogMacro cmd # $regions ParseRegionMacro cmd # $env ParseEnvMacro cmd # $cen ParsePanMacro cmd # $value ParseValueMacro cmd $frame $x $y # $x,$y ParseXYMacro cmd $frame $x $y # $z ParseZMacro cmd $frame # $message if {![ParseMessageMacro cmd]} { AnalysisTaskEnd $which $i return } # $entry if {![ParseEntryMacro cmd]} { AnalysisTaskEnd $which $i return } # $param if {![ParseParamMacro cmd]} { AnalysisTaskEnd $which $i return } # $text ParseTextMacro cmd $which $i # $plot ParsePlotMacro cmd $which $i # $null ParseNullMacro cmd $which $i # $url ParseURLMacro cmd $which $i # $geturl # do this next to last ParseGetURLMacro cmd $which $i # $image # do this last ParseImageMacro cmd $which $i # escaped macros UnsetEscapedMacros cmd # ok, we are off and running set ianalysis($which,$i,inuse) 1 switch -- $ianalysis($which,$i,start) { geturl { AnalysisGetURL $which $i $sync } default { AnalysisPipe $which $i $cmd $sync } } } proc AnalysisPipe {which i cmd sync} { global ianalysis global panalysis global current switch -- $ianalysis($which,$i,start) { data {$current(frame) save fits image file "\{$ianalysis($which,$i,start,fn)\}"} url {GetFileURL $ianalysis($which,$i,start,url) ianalysis($which,$i,start,fn)} } # last step, change all '][' into ',' so that multiple filters work right regsub -all {\]\[} $cmd "," cmd # log the command, if necessary if {$panalysis(log)} { SimpleTextDialog acmd [msgcat::mc {Analysis Commands}] 80 20 append bottom "$cmd\n" } switch -- $ianalysis($which,$i,finish) { null { # nothing is returned, so there is aways an error, # however, the command will be executed. catch {open "| $cmd"} global errorInfo set errorInfo {} AnalysisTaskEnd $which $i return } default { if {[catch {set ch [open "| $cmd"]}]} { Error [msgcat::mc {An error has occurred invoking the Analysis task}] AnalysisTaskEnd $which $i return } set ianalysis($which,$i,pid) [pid $ch] switch -- $ianalysis($which,$i,finish) { image { switch -- $ianalysis($which,$i,image) { new {CreateFrame} rgb {CreateRGBFrame} 3d {Create3DFrame} current {} } global loadParam set loadParam(load,type) channel set loadParam(load,layer) {} set loadParam(channel,name) $ch set loadParam(file,type) fits set loadParam(file,mode) {} set loadParam(file,name) \ "[string tolower [lindex $ianalysis($which,$i,item) 0]].fits" StartLoad ProcessLoad FinishLoad AnalysisTaskEnd $which $i } default { if {$sync} { AnalysisReaderAppend $ch $which $i AnalysisReaderFinish $ch $which $i } else { fileevent $ch readable \ [list AnalysisReader $ch $which $i] fconfigure $ch -blocking 0 -buffering none } } } } } } proc AnalysisReader {ch which i} { global ianalysis if {[eof $ch]} { AnalysisReaderFinish $ch $which $i return } AnalysisReaderAppend $ch $which $i } proc AnalysisReaderAppend {ch which i} { global ianalysis set r [read $ch] # for real-time update switch -- $ianalysis($which,$i,finish) { text { AnalysisText "at${which}${i}" $ianalysis($which,$i,item) $r append global debug if {$debug(tcl,idletasks)} { puts stderr "AnalysisReader" } update idletasks } } append ianalysis($which,$i,result) $r } proc AnalysisReaderFinish {ch which i} { global ianalysis catch {close $ch} switch -- $ianalysis($which,$i,finish) { null - image - text {} plot { PlotLine "at${which}${i}" \ $ianalysis($which,$i,item) \ $ianalysis($which,$i,plot,title) \ $ianalysis($which,$i,plot,xaxis) \ $ianalysis($which,$i,plot,yaxis) \ $ianalysis($which,$i,plot,dim) \ $ianalysis($which,$i,result) } plotstdin { AnalysisPlotStdin line "at${which}${i}" $ianalysis($which,$i,item) \ $ianalysis($which,$i,result) } default {puts stdout $ianalysis($which,$i,result)} } AnalysisTaskEnd $which $i } proc AnalysisPlotStdin {type w wtt result} { # if no result, just return if {$result == {}} { return } # check for $ERROR set id [string first {$ERROR} $result] if {$id >= 0} { AnalysisText "${w}e" $wtt \ [string range $result [expr $id+1] end] append return } # check for ERROR: set id [string first {ERROR:} $result] if {$id >= 0} { AnalysisText "${w}e" $wtt [string range $result $id end] append return } # check for $BEGINTEXT/$ENDTEXT # assume each is followed by a \n, so skip it if {[string range $result 0 9] == {$BEGINTEXT}} { set eid [string first {$ENDTEXT} $result] if {$eid > 0} { AnalysisText "${w}t" $wtt \ [string range $result 11 [expr $eid-1]] append set result [string range $result [expr $eid+9] end] } else { # looks like all text AnalysisText "${w}t" $wtt [string range $result 11 end] append return } } # now find the title, x axis label, y axis label, and dimension set id [string first "\n" $result] set tt [string range $result 0 $id] set rr [string range $result [expr $id+1] end] set l [llength $tt] set t [join [lrange $tt 0 [expr $l-4]]] set x [lindex $tt [expr $l-3]] set y [lindex $tt [expr $l-2]] set d [lindex $tt [expr $l-1]] if {$d != {} && $rr != {}} { switch $type { line {PlotLine $w $wtt $t $x $y $d $rr} bar {PlotBar $w $wtt $t $x $y $d $rr} scatter {PlotScatter $w $wtt $t $x $y $d $rr} } } else { Error "[msgcat::mc {Error}] [string range $tt 0 40]" } } proc AnalysisGetURL {which i sync} { global ianalysis global panalysis if {![ParseURL $ianalysis($which,$i,start,url) r]} { Error [msgcat::mc {An error has occurred invoking the Analysis task}] AnalysisTaskEnd $which $i return } # format all spaces and brackets set url {} regsub -all { } $ianalysis($which,$i,start,url) "%20" url regsub -all {\[} $url "%5B" url regsub -all {\]} $url "%5D" url if {$panalysis(log)} { SimpleTextDialog acmd [msgcat::mc {Analysis Commands}] 80 20 append bottom "$url\n" } set ianalysis($which,$i,pid) -1 HVAnalysisURL $which $i $url $sync } proc AnalysisProcessGetURL {which i result} { global ianalysis set ianalysis($which,$i,result) $result switch -- $ianalysis($which,$i,finish) { text {AnalysisText "at${which}${i}" $ianalysis($which,$i,item) \ $ianalysis($which,$i,result) append} plot {PlotLine "at${which}${i}" \ $ianalysis($which,$i,item) \ $ianalysis($which,$i,plot,title) \ $ianalysis($which,$i,plot,xaxis) \ $ianalysis($which,$i,plot,yaxis) \ $ianalysis($which,$i,plot,dim) \ $ianalysis($which,$i,result)} plotstdin {AnalysisPlotStdin line "at${which}${i}" \ $ianalysis($which,$i,item) \ $ianalysis($which,$i,result)} image { set fn "[string tolower [lindex $ianalysis($which,$i,item) 0]].fits" LoadVar result $fn {} {} } default {Error $ianalysis($which,$i,result)} } } proc AnalysisTaskEnd {which i} { global ianalysis set ianalysis($which,$i,inuse) 0 if {$ianalysis($which,$i,start,fn) != {}} { if {[file exists $ianalysis($which,$i,start,fn)]} { catch {file delete -force $ianalysis($which,$i,start,fn)} } } if {[info exists ianalysis($which,$i,pid)]} { unset ianalysis($which,$i,pid) } unset ianalysis($which,$i,start) unset ianalysis($which,$i,start,fn) unset ianalysis($which,$i,start,url) unset ianalysis($which,$i,finish) unset ianalysis($which,$i,result) unset ianalysis($which,$i,plot,title) unset ianalysis($which,$i,plot,xaxis) unset ianalysis($which,$i,plot,yaxis) unset ianalysis($which,$i,plot,dim) unset ianalysis($which,$i,image) } proc SetEscapedMacros {cmdname} { upvar $cmdname cmd global xpa set seq "WaJaWaJaW" if {[regexp {\$\$} $cmd]} { # fill with tempory sequence regsub -all {\$\$} $cmd $seq cmd } } proc UnsetEscapedMacros {cmdname} { upvar $cmdname cmd global xpa set seq "WaJaWaJaW" if {[regexp $seq $cmd]} { # reset to $ regsub -all $seq $cmd {\$} cmd } } proc ParseDataMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\$data.?\|} if {[regexp $exp $cmd]} { set ianalysis($which,$i,start) data set ianalysis($which,$i,start,fn) [tmpnam ds9ans {.fits}] regsub $exp $cmd "cat \{$ianalysis($which,$i,start,fn)\} |" cmd } } proc ParseVOMethodMacro {cmdname} { upvar $cmdname cmd global pvo if {[regexp {\$vo_method} $cmd]} { regsub -all {\$vo_method} $cmd $pvo(method) cmd } } proc ParseXPAMethodMacro {cmdname} { upvar $cmdname cmd global ds9 if {[regexp {\$xpa_method} $cmd]} { regsub -all {\$xpa_method} $cmd [XPAMethod] cmd } } proc ParseXPAMacro {cmdname} { upvar $cmdname cmd global ds9 if {[regexp {\$xpa} $cmd]} { regsub -all {\$xpa} $cmd $ds9(title) cmd } } proc ParseXYBitpixMacro {cmdname} { upvar $cmdname cmd global current if {$current(frame) != {}} { if {[regexp {\$width} $cmd]} { regsub -all {\$width} $cmd [$current(frame) get fits width] cmd } if {[regexp {\$height} $cmd]} { regsub -all {\$height} $cmd [$current(frame) get fits height] cmd } if {[regexp {\$depth} $cmd]} { regsub -all {\$depth} $cmd [$current(frame) get fits depth 2] cmd } if {[regexp {\$bitpix} $cmd]} { regsub -all {\$bitpix} $cmd [$current(frame) get fits bitpix] cmd } if {[regexp {\$xdim} $cmd]} { regsub -all {\$xdim} $cmd [$current(frame) get fits width] cmd } if {[regexp {\$ydim} $cmd]} { regsub -all {\$ydim} $cmd [$current(frame) get fits height] cmd } } } proc ParseFilenameRegionMacro {cmdname} { upvar $cmdname cmd global current set exp {(\$filename)\[(\$regions\(([^)]*)\))\]} while {[regexp $exp $cmd foo fn reg pp]} { set type ds9 set prop {} set sys physical set sky fk5 set format degrees # default for mosaics if {$current(frame) != {}} { if {[$current(frame) has fits mosaic]} { set sys wcs } } foreach p [split $pp ,] { switch -- $p { ds9 - ciao - saotng - saoimage - pros - xy {set type $p} include {append prop {include = yes }} exclude {append prop {include = no }} source {append prop {source = yes }} background {append prop {source = no }} image - physical - detector - amplifier wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {set sys $p} fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic { if {"$sys"=="physical"} { set sys wcs } set sky $p } hms {set format sexagesimal} sexagesimal - degrees {set format $p} } } SubstFilenameRegion cmd $exp $type $prop $sys $sky $format } set exp {(\$filename)\[(\$regions)\]} while {[regexp $exp $cmd foo fn reg]} { set type ds9 set prop {} set sys physical set sky fk5 set format degrees # default for mosaics if {$current(frame) != {}} { if {[$current(frame) has fits mosaic]} { set sys wcs } } SubstFilenameRegion cmd $exp $type $prop $sys $sky $format } } proc SubstFilenameRegion {cmdname exp type prop sys sky format} { upvar $cmdname cmd global current global ianalysis set fn [$current(frame) get fits file name full] set region [string trimright [$current(frame) marker list $type $sys $sky $format yes $prop] ";"] if {$region != {}} { set sub {} foreach f $fn { append sub "$f\[$region\] " } } else { set sub $fn } # substitute # ok, we need to check the length if {[string length $region] > 256} { # since we are writing to a file, # we don't have to worry about quoting # special characters set fn [tmpnam ds9ans {.reg}] incr ianalysis(param,seq) if {![catch {set ch [open "$fn" w]}]} { puts $ch "$sub" close $ch } regsub $exp $cmd "\@$fn" cmd } else { CleanFileName sub regsub $exp $cmd $sub cmd } } proc ParseFilenameMacro {cmdname} { upvar $cmdname cmd global current set exp {\$filename\(([^)]*)\)} if {[regexp $exp $cmd foo pp]} { switch $pp { root - root,base { set sub [join [$current(frame) get fits file name root base]] CleanFileName sub regsub -all $exp $cmd $sub cmd } full - full,base { set sub [join [$current(frame) get fits file name full base]] CleanFileName sub regsub -all $exp $cmd $sub cmd } root,3d { set sub [join [$current(frame) get fits file name root 3d]] CleanFileName sub regsub -all $exp $cmd $sub cmd } full,3d { set sub [join [$current(frame) get fits file name full 3d]] CleanFileName sub regsub -all $exp $cmd $sub cmd } } } set exp {\$filename} if {[regexp $exp $cmd]} { set sub [join [$current(frame) get fits file name full]] CleanFileName sub regsub -all $exp $cmd $sub cmd } } proc ParseFileDialogMacro {cmdname} { upvar $cmdname cmd global current set exp {\$filedialog\(open\)} if {[regexp $exp $cmd]} { set sub [OpenFileDialog analysisparamfbox] regsub -all $exp $cmd $sub cmd } set exp {\$filedialog\(save\)} if {[regexp $exp $cmd]} { set sub [SaveFileDialog analysisparamfbox] regsub -all $exp $cmd $sub cmd } } proc CleanFileName {varname} { upvar $varname sub # we have to quote {"}, else problems down the road regsub -all {\"} $sub {\\"} sub # we have to quote {&}, else problems down the road regsub -all {\&} $sub {\\&} sub } proc ParseRegionMacro {cmdname} { global current upvar $cmdname cmd set exp {\$regions\(([^)]*)\)} while {[regexp $exp $cmd foo pp]} { set type ds9 set prop {} set sys physical set sky fk5 set format degrees # default for mosaics if {$current(frame) != {}} { if {[$current(frame) has fits mosaic]} { set sys wcs } } foreach p [split $pp ,] { switch -- $p { ds9 - ciao - saotng - saoimage - pros - xy {set type $p} include {append prop {include = yes }} exclude {append prop {include = no }} source {append prop {source = yes }} background {append prop {source = no }} image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {set sys $p} fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic { if {"$sys"=="physical"} { set sys wcs } set sky $p } hms {set format sexagesimal} sexagesimal - degrees {set format $p} } } SubstRegion cmd $exp $type $prop $sys $sky $format } # SAOtng format set exp {\$((|include|exclude|source|background)_)?regions(_(|degrees|hms|pixels))?} while {[regexp $exp $cmd foo a prop b sys]} { # check valid props switch -- $prop { include {set prop {include = yes}} exclude {set prop {include = no}} source {set prop {source = yes}} background {set prop {source = no}} default {set prop {}} } # check valid coordinate systems set sky fk5 switch -- $sys { degrees {set sys wcs; set format degrees} hms {set sys wcs; set format sexagesimal} pixels - default {set sys physical; set format degrees} } SubstRegion cmd $exp ds9 $prop $sys $sky $format } } proc SubstRegion {cmdname exp type prop sys sky format} { upvar $cmdname cmd global current global ianalysis # get any regions set region [string trimright [$current(frame) marker list $type $sys $sky $format yes $prop] ";"] # substitute # ok, we need to check the length if {[string length $region] > 8192} { # since we are writing to a file, we don't have to worry about quoting # special characters set fn [tmpnam ds9ans {.reg}] incr ianalysis(param,seq) if {![catch {set ch [open "$fn" w]}]} { puts $ch "$region" close $ch } regsub $exp $cmd "\@$fn" cmd } else { # we have to quote {"}, else problems down the road regsub -all {\"} $region {\\"} region # we have to quote {&}, else problems down the road regsub -all {\&} $region {\\&} region regsub $exp $cmd $region cmd } } proc ParseEnvMacro {cmdname} { upvar $cmdname cmd global env set exp {\$env\(([^)]*)\)} if {[regexp $exp $cmd foo ee]} { if [info exists env($ee)] { regsub -all $exp $cmd "$env($ee)" cmd } else { regsub -all $exp $cmd {} cmd } } } proc ParsePanMacro {cmdname} { global current upvar $cmdname cmd set exp {\$pan\(([^)]*)\)} if {[regexp $exp $cmd foo pp]} { set sys physical set sky fk5 set format degrees foreach p [split $pp ,] { switch -- $p { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {set sys $p} fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic {set sky $p; set sys wcs} hms {set format sexagesimal} sexagesimal - degrees {set format $p} } } set coord [$current(frame) get cursor $sys $sky $format] regsub -all $exp $cmd "[lindex $coord 0],[lindex $coord 1]" cmd return } # no args set exp {\$pan} if {[regexp $exp $cmd foo1]} { set coord [$current(frame) get cursor physical] regsub -all $exp $cmd "[lindex $coord 0],[lindex $coord 1]" cmd } } proc ParseValueMacro {cmdname frame x y} { upvar $cmdname cmd # menu items will not have a frame arg if {$frame == {}} { return } set exp1 {\$value} if {[regexp $exp1 $cmd foo]} { set vv [$frame get value canvas $x $y] regsub -all $exp1 $cmd "$vv" cmd } } proc ParseXYMacro {cmdname frame x y} { upvar $cmdname cmd # menu items will not have a frame arg if {$frame == {}} { return } set exp1 {\$x\(([^)]*)\)} set exp2 {\$y\(([^)]*)\)} if {[regexp $exp1 $cmd foo pp] && [regexp $exp2 $cmd foo2 pp2]} { set sys physical set sky fk5 set format degrees foreach p [split $pp ,] { switch -- $p { image - physical - detector - amplifier - wcs - wcsa - wcsb - wcsc - wcsd - wcse - wcsf - wcsg - wcsh - wcsi - wcsj - wcsk - wcsl - wcsm - wcsn - wcso - wcsp - wcsq - wcsr - wcss - wcst - wcsu - wcsv - wcsw - wcsx - wcsy - wcsz {set sys $p} fk4 - b1950 - fk5 - j2000 - icrs - galactic - ecliptic {set sky $p; set sys wcs} hms {set format sexagesimal} sexagesimal - degrees {set format $p} } } switch -- $sys { image - physical - detector - amplifier {set coord [$frame get coordinates $x $y $sys]} default {set coord [$frame get coordinates $x $y $sys $sky $format]} } regsub -all $exp1 $cmd [lindex $coord 0] cmd regsub -all $exp2 $cmd [lindex $coord 1] cmd return } # no args set exp1 {\$x} set exp2 {\$y} if {[regexp $exp1 $cmd foo1] && [regexp $exp2 $cmd foo2]} { set coord [$frame get coordinates $x $y physical] regsub -all $exp1 $cmd [lindex $coord 0] cmd regsub -all $exp2 $cmd [lindex $coord 1] cmd } } proc ParseZMacro {cmdname frame} { upvar $cmdname cmd # menu items will not have a frame arg if {$frame == {}} { return } set sl [$frame get fits slice] # args set exp1 {\$z\(([^)]*)\)} if {[regexp $exp1 $cmd foo pp]} { set sys $pp set coord [$frame get coordinates $sl $sys 2] regsub -all $exp1 $cmd "$coord" cmd return } # no args set exp1 {\$z} if {[regexp $exp1 $cmd foo1]} { set coord [$frame get coordinates $sl image 2] regsub -all $exp1 $cmd "$coord" cmd } } proc ParseMessageMacro {cmdname} { upvar $cmdname cmd # two args set exp {\|?.?\$message\((ok|okcancel|yesno),([^)]*)\).?\|?} while {[regexp $exp $cmd foo type message]} { regsub $exp $cmd {} cmd if {![AnalysisMessage $type $message]} { return 0 } } # one args set exp {\|?.?\$message\(([^)]*)\).?\|?} while {[regexp $exp $cmd foo message]} { regsub $exp $cmd {} cmd AnalysisMessage ok $message } return 1 } proc ParseEntryMacro {cmdname} { upvar $cmdname cmd # one args set exp {\|?.?\$entry\(([^)]*)\).?\|?} while {[regexp $exp $cmd foo message]} { set result {} if {![AnalysisEntry $message result]} { return 0 } regsub $exp $cmd $result cmd } return 1 } proc ParseParamMacro {cmdname} { upvar $cmdname cmd global ianalysis set exp {\$param\(([^)]*)\).?;?} while {[regexp $exp $cmd foo param]} { regsub $exp $cmd {} cmd if {![AnalysisParam cmd $param]} { return 0 } } return 1 } proc ParseTextMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp1 {\|.?\$text} set exp2 {\|\&.?\$text} if {[regexp $exp1 $cmd]} { regsub $exp1 $cmd {} cmd set ianalysis($which,$i,finish) text } elseif {[regexp $exp2 $cmd]} { regsub $exp2 $cmd { 2>@ stdout} cmd set ianalysis($which,$i,finish) text } } proc ParseNullMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\|.?\$null} if {[regexp $exp $cmd]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) null } } proc ParsePlotMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\|.?\$plot\(([^,]+),([^,]+),([^,]+),([^)]+)\)} if {[regexp $exp $cmd foo \ ianalysis($which,$i,plot,title) \ ianalysis($which,$i,plot,xaxis) \ ianalysis($which,$i,plot,yaxis) \ ianalysis($which,$i,plot,dim)]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) plot } set exp {\|.?\$plot\(stdin\)} if {[regexp $exp $cmd]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) plotstdin } set exp {\|.?\$plot} if {[regexp $exp $cmd]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) plot } } proc ParseURLMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\$url\((.*)\) \|} if {[regexp $exp $cmd foo ianalysis($which,$i,start,url)]} { set ianalysis($which,$i,start) url set ianalysis($which,$i,start,fn) [tmpnam ds9ans {.fits}] regsub $exp $cmd "cat \{$ianalysis($which,$i,start,fn)\} |" cmd } } proc ParseGetURLMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\$geturl\((.*)\)} if {[regexp $exp $cmd foo ianalysis($which,$i,start,url)]} { set ianalysis($which,$i,start) geturl set ianalysis($which,$i,start,fn) [tmpnam ds9ans {.fits}] regsub $exp $cmd {} cmd } } proc ParseImageMacro {cmdname which i} { upvar $cmdname cmd global ianalysis set exp {\|.?\$image\(([^)]*)\)} if {[regexp $exp $cmd foo ianalysis($which,$i,image)]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) image } set exp {\|.?\$image} if {[regexp $exp $cmd]} { regsub $exp $cmd {} cmd set ianalysis($which,$i,finish) image } } proc AnalysisText {tt title txt method} { if {$txt != {} && $txt != "\n"} { SimpleTextDialog ${tt}txt $title 80 20 $method bottom $txt } } proc AnalysisMessage {type message} { if {$type == {}} { set type ok } switch -- [tk_messageBox -message $message -type $type] { ok {return 1} yes {return 1} cancel {return 0} default {return 0} } } proc AnalysisEntry {message resultvar} { upvar $resultvar result return [EntryDialog [msgcat::mc {Entry}] $message 60 result] } proc AnalysisPrefOpen {varname} { upvar $varname var FileLastFull analysisfbox $var set var [OpenFileDialog analysisfbox] } # Cmds proc ProcessAnalysisCmd {varname iname buf fn} { upvar $varname var upvar $iname i global ianalysis switch -- [string tolower [lindex $var $i]] { message { incr i switch [string tolower [lindex $var $i]] { ok - okcancel - retrycancel - yesno - yesnocancel { AnalysisMessage [lindex $var $i] [lindex $var [expr $i+1]] incr i } default { AnalysisMessage ok [lindex $var $i] } } } text { if {$buf != {}} { AnalysisText apXPA Analysis $buf append } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set txt [read $ch] close $ch AnalysisText apXPA Analysis $txt append } } else { incr i AnalysisText apXPA Analysis [lindex $var $i] append } } plot { # for backward compatibility # used by chandra-ed # use xpa plot instead incr i if {$buf != {}} { ProcessAnalysisPlotCmd $varname $iname $buf } elseif {$fn != {}} { if {[file exists $fn]} { set ch [open $fn r] set rr [read $ch] close $ch ProcessAnalysisPlotCmd $varname $iname $rr } } else { ProcessAnalysisPlotCmd $varname $iname {} } } load { if {$buf != {}} { ProcessAnalysis buf } elseif {$fn != {}} { ProcessAnalysisFile $fn } else { incr i ProcessAnalysisFile [lindex $var $i] } } clear { ClearAnalysis incr i switch -- [lindex $var $i] { load { if {$buf != {}} { ProcessAnalysis buf } elseif {$fn != {}} { ProcessAnalysisFile $fn } else { incr i ProcessAnalysisFile [lindex $var $i] } } default {incr i -1} } } task { incr i if {[string is integer [lindex $var $i]]} { AnalysisTask [lindex $var $i] menu } else { # invoke by name for {set ii 0} {$ii<$ianalysis(menu,count)} {incr ii} { if {[string equal -nocase \ $ianalysis(menu,$ii,item) [lindex $var $i]]} { AnalysisTask $ii menu } } } } default { if {[string is integer [lindex $var $i]]} { AnalysisTask [lindex $var $i] menu } else { ProcessAnalysisFile [lindex $var $i] } } } } proc ProcessAnalysisPlotCmd {varname iname buf} { upvar 2 $varname var upvar 2 $iname i global iap switch -- [string tolower [lindex $var $i]] { stdin {AnalysisPlotStdin line $iap(tt) {} $buf} default { PlotLine $iap(tt) Plot \ [lindex $var [expr $i+0]] \ [lindex $var [expr $i+1]] \ [lindex $var [expr $i+2]] \ [lindex $var [expr $i+3]] \ $buf incr i 3 } } } proc ProcessSendAnalysisCmd {proc id param sock fn} { global ianalysis set result {} switch -- [string tolower [lindex $param 0]] { entry { AnalysisEntry [lrange $param 1 end] result append result "\n" $proc $id $result } task { # invoke by name for {set ii 0} {$ii<$ianalysis(menu,count)} {incr ii} { append result "$ii $ianalysis(menu,$ii,item)\n" } $proc $id $result } default { for {set i 0} {$i<$ianalysis(menu,count)} {incr i} { append result "\#$i menu" append result "\n$ianalysis(menu,$i,item)" append result "\n$ianalysis(menu,$i,template)" if {$ianalysis(menu,$i,cmd) != {web}} { append result "\nmenu" append result "\n$ianalysis(menu,$i,cmd)" } else { append result "\n$ianalysis(menu,$i,cmd)" append result "\n$ianalysis(menu,$i,var)" } append result "\n\n" } for {set i 0} {$i<$ianalysis(bind,count)} {incr i} { set key [string range $ianalysis(bind,$i,item) 1 1] append result "\#$i bind" append result "\nbind key $ianalysis(bind,$i,item)" append result "\n$ianalysis(bind,$i,template)" append result "\nbind $key" append result "\n$ianalysis(bind,$i,cmd)" append result "\n\n" } ProcessSend $proc $id $sock $fn {.ans} $result } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/catdialog.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000107252�12131622107�014327� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 # used by backup proc CATDialog {varname format catalog title action} { global cat global icat global pcat global ds9 global pds9 global wcs # first determine if aready in use, then increment if {[lsearch $icat(cats) $varname] >= 0} { incr cat(id) append varname $cat(id) } upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATDialog $varname:$format:$catalog:$title:$action" } # main dialog set var(top) ".${varname}" set var(mb) ".${varname}mb" if [winfo exists $var(top)] { raise $var(top) return } global current if {$current(frame) == {}} { return } # AR variables ARInit $varname CATServer # CAT variables lappend icat(cats) $varname set var(catdb) ${varname}catdb set var(tbldb) ${varname}tbldb set var(symdb) ${varname}symdb set var(symdl) ${varname}symdl set var(fltdl) ${varname}fltdl set var(frame) $current(frame) set var(server) $pcat(server) set var(loc) $pcat(loc) set var(system) $wcs(system) set var(sky) $wcs(sky) set var(skyformat) $wcs(skyformat) set var(rformat) $icat(rformat) set var(width) $icat(width) set var(height) $icat(height) set var(max) $icat(max) set var(allrows) $icat(allrows) set var(allcols) $icat(allcols) set var(show) $icat(show) set var(edit) $icat(edit) set var(panto) $icat(panto) set var(psystem) $var(system) set var(psky) $var(sky) set var(blink) 0 set var(blink,count) 0 set var(blink,marker) {} set var(plot) 0 set var(plot,var) {} set var(plot,x) {} set var(plot,xerr) {} set var(plot,y) {} set var(plot,yerr) {} CATSet $varname $format $catalog $title CATSymDBInit $varname # create the window set w $var(top) set mb $var(mb) if {$title!= {}} { set tt $title } else { set tt [msgcat::mc {Catalog Tool}] } Toplevel $w $mb 7 $tt "CATDestroy $varname" $mb add cascade -label [msgcat::mc {File}] -menu $mb.file $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit CATServerMenu $varname NSVRServerMenu $varname $mb add cascade -label [msgcat::mc {Symbol}] -menu $mb.symbol $mb add cascade -label [msgcat::mc {Preferences}] -menu $mb.prefs # file menu $mb.file $mb.file add command -label "[msgcat::mc {Load}]..." \ -command [list CATLoadVOTFile $varname] $mb.file add command -label "[msgcat::mc {Save}]..." \ -command [list CATSaveVOTFile $varname] $mb.file add separator $mb.file add cascade -label [msgcat::mc {Import}] -menu $mb.file.import $mb.file add cascade -label [msgcat::mc {Export}] -menu $mb.file.export $mb.file add separator $mb.file add command -label [msgcat::mc {Retrieve}] \ -command [list CATApply $varname 0] $mb.file add command -label [msgcat::mc {Cancel}] \ -command [list ARCancel $varname] $mb.file add separator $mb.file add command -label [msgcat::mc {Filter}] \ -command [list CATTable $varname] $mb.file add command -label [msgcat::mc {Clear}] \ -command [list CATOff $varname] $mb.file add separator $mb.file add checkbutton -label [msgcat::mc {Show}] \ -variable ${varname}(show) -command [list CATGenerate $varname] $mb.file add checkbutton -label [msgcat::mc {Edit}] \ -variable ${varname}(edit) -command [list CATEdit $varname] $mb.file add separator $mb.file add cascade -label [msgcat::mc {SAMP}] -menu $mb.file.samp $mb.file add command -label [msgcat::mc {Plot}] \ -command [list CATPlot $varname] $mb.file add separator $mb.file add command -label "[msgcat::mc {Display Header}]..." \ -command [list CATHeader $varname] $mb.file add command -label [msgcat::mc {Acknowledgment}] \ -command [list CATAck $varname] $mb.file add separator $mb.file add command -label [msgcat::mc {Update from Current Frame}] \ -command [list CATUpdate $varname] $mb.file add command \ -label [msgcat::mc {Update from Current Crosshair}] \ -command [list CATCrosshair $varname] $mb.file add separator $mb.file add command -label [msgcat::mc {Copy to Regions}] \ -command [list CATGenerateRegions $varname] $mb.file add separator switch $ds9(wm) { x11 {} win32 - aqua { $mb.file add command -label "[msgcat::mc {Page Setup}]..." \ -command "CATPageSetup $varname" } } $mb.file add command -label "[msgcat::mc {Print}]..." \ -command [list CATPrint $varname] $mb.file add separator $mb.file add command -label [msgcat::mc {Close}] \ -command [list CATDestroy $varname] # Import menu $mb.file.import $mb.file.import add command -label "[msgcat::mc {Starbase}]..." \ -command [list CATLoadSBFile $varname] $mb.file.import add command -label "[msgcat::mc {Tab-Separated-Value}]..." \ -command [list CATLoadTSVFile $varname] # Export menu $mb.file.export $mb.file.export add command -label "[msgcat::mc {Starbase}]..." \ -command [list CATSaveSBFile $varname] $mb.file.export add command -label "[msgcat::mc {Tab-Separated-Value}]..." \ -command [list CATSaveTSVFile $varname] # SAMP menu $mb.file.samp $mb.file.samp add command -label [msgcat::mc {Connect}] \ -command SAMPConnect $mb.file.samp add command -label [msgcat::mc {Disconnect}] \ -command SAMPDisconnect $mb.file.samp add separator $mb.file.samp add cascade -label [msgcat::mc {Send}] \ -menu $mb.file.samp.send menu $mb.file.samp.send $mb.file.samp.send add command -label [msgcat::mc {Broadcast}] \ -command [list SAMPSendTableLoadVotable {} $varname] $mb.file.samp.send add separator # edit menu $mb.edit $mb.edit add command -label [msgcat::mc {Cut}] \ -command "CATCut $varname" -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command "CATCopy $varname" -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -command "EntryPaste $var(top)" -accelerator "${ds9(ctrl)}V" $mb.edit add separator $mb.edit add command -label [msgcat::mc {Clear}] \ -command [list ARClear $varname] # symbol global $var(symdb) set flt $var(symdb) set sn [starbase_colnum $var(symdb) shape] set cn [starbase_colnum $var(symdb) color] set fn [starbase_colnum $var(symdb) font] set fs [starbase_colnum $var(symdb) fontsize] set fw [starbase_colnum $var(symdb) fontweight] set fl [starbase_colnum $var(symdb) fontslant] menu $mb.symbol $mb.symbol add cascade -label [msgcat::mc {Shape}] -menu $mb.symbol.shape $mb.symbol add cascade -label [msgcat::mc {Color}] -menu $mb.symbol.color $mb.symbol add cascade -label [msgcat::mc {Font}] -menu $mb.symbol.font $mb.symbol add separator $mb.symbol add command -label "[msgcat::mc {Advanced}]..." \ -command [list CATSymDialog $varname] menu $mb.symbol.shape $mb.symbol.shape add radiobutton -label [msgcat::mc {Circle}] \ -variable ${flt}(1,$sn) -value circle \ -command [list CATGenerate $varname] $mb.symbol.shape add radiobutton -label [msgcat::mc {Ellipse}] \ -variable ${flt}(1,$sn) -value ellipse \ -command [list CATGenerate $varname] $mb.symbol.shape add radiobutton -label [msgcat::mc {Box}] \ -variable ${flt}(1,$sn) -value box \ -command [list CATGenerate $varname] $mb.symbol.shape add radiobutton -label [msgcat::mc {Text}] \ -variable ${flt}(1,$sn) -value text \ -command [list CATGenerate $varname] $mb.symbol.shape add cascade -label [msgcat::mc {Point}] \ -menu $mb.symbol.shape.point menu $mb.symbol.shape.point $mb.symbol.shape.point add radiobutton -label [msgcat::mc {Circle}] \ -variable ${flt}(1,$sn) -value {circle point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {Box}] \ -variable ${flt}(1,$sn) -value {box point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {Diamond}] \ -variable ${flt}(1,$sn) -value {diamond point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {Cross}] \ -variable ${flt}(1,$sn) -value {cross point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {X}] \ -variable ${flt}(1,$sn) -value {x point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {Arrow}] \ -variable ${flt}(1,$sn) -value {arrow point} \ -command [list CATGenerate $varname] $mb.symbol.shape.point add radiobutton -label [msgcat::mc {BoxCircle}]\ -variable ${flt}(1,$sn) -value {boxcircle point} \ -command [list CATGenerate $varname] ColorMenu $mb.symbol.color $flt 1,$cn [list CATGenerate $varname] FontMenu $mb.symbol.font $flt 1,$fn 1,$fs 1,$fw 1,$fl \ [list CATGenerate $varname] menu $mb.prefs $mb.prefs add checkbutton -label [msgcat::mc {Pan To}] \ -variable ${varname}(panto) $mb.prefs add separator $mb.prefs add checkbutton -label [msgcat::mc {All Rows}] \ -variable ${varname}(allrows) $mb.prefs add checkbutton -label [msgcat::mc {All Columns}] \ -variable ${varname}(allcols) # Catalog set f [ttk::labelframe $w.cat -text [msgcat::mc {Catalog}] -padding 2] ttk::label $f.ttitle -text [msgcat::mc {Name}] ttk::label $f.title -textvariable ${varname}(title) \ -relief groove -width 60 -anchor w ttk::label $f.tcat -text [msgcat::mc {Identification}] ttk::label $f.cat -textvariable ${varname}(catalog) \ -relief groove -width 60 -anchor w ttk::label $f.tref -text [msgcat::mc {Reference}] ttk::label $f.ref -text [string range $varname 3 end] \ -relief groove -width 13 -anchor w ttk::label $f.loctitle -text [msgcat::mc {IAU Location Code}] ttk::entry $f.loc -textvariable ${varname}(loc) -width 7 grid $f.ttitle $f.title -padx 2 -pady 2 -sticky w grid $f.tcat $f.cat -padx 2 -pady 2 -sticky w grid $f.tref $f.ref -padx 2 -pady 2 -sticky w grid $f.loctitle $f.loc -padx 2 -pady 2 -sticky w # Object set f [ttk::labelframe $w.obj -text [msgcat::mc {Object}] -padding 2] ttk::label $f.nametitle -text [msgcat::mc {Name}] ttk::entry $f.name -textvariable ${varname}(name) -width 60 set var(xname) [ttk::label $f.xtitle -text {} -width 1] ttk::entry $f.x -textvariable ${varname}(x) -width 14 set var(yname) [ttk::label $f.ytitle -text {} -width 1] ttk::entry $f.y -textvariable ${varname}(y) -width 14 CoordMenuButton $f.coord $varname system 0 sky skyformat \ [list CATWCSMenuUpdate $varname] CoordMenuEnable $f.coord.menu $varname system 0 sky skyformat ttk::button $f.update -text [msgcat::mc {Update}] \ -command [list CATUpdate $varname] ttk::label $f.wtitle -text [msgcat::mc {Width}] ttk::entry $f.w -textvariable ${varname}(width) -width 14 ttk::label $f.htitle -text [msgcat::mc {Height}] ttk::entry $f.h -textvariable ${varname}(height) -width 14 ARRFormat $f.rformat $varname grid $f.nametitle $f.name - - - - -padx 2 -pady 2 -sticky w grid $f.xtitle $f.x $f.ytitle $f.y $f.coord $f.update \ -padx 2 -pady 2 -sticky w grid $f.wtitle $f.w $f.htitle $f.h $f.rformat -padx 2 -pady 2 -sticky w # Param set f [ttk::labelframe $w.param -text [msgcat::mc {Table}] -padding 2] ttk::label $f.mfilter -text [msgcat::mc {Filter}] ttk::entry $f.filter -textvariable ${varname}(filter) -width 50 ttk::button $f.bfilter -text [msgcat::mc {Edit}] \ -command [list CATEditDialog $varname filter $var(catdb)] ttk::label $f.msort -text [msgcat::mc {Sort}] set var(sortmenu) [ttk::menubutton $f.sort \ -textvariable ${varname}(sort) \ -menu $f.sort.menu -width 14] ttk::radiobutton $f.isort -text [msgcat::mc {Increase}] \ -variable ${varname}(sort,dir) -value "-increasing" \ -command [list CATTable $varname] ttk::radiobutton $f.dsort -text [msgcat::mc {Decrease}] \ -variable ${varname}(sort,dir) -value "-decreasing" \ -command [list CATTable $varname] ttk::label $f.mtitle -text [msgcat::mc {Max Rows}] ttk::entry $f.max -textvariable ${varname}(max) -width 14 ttk::label $f.ftitle -text [msgcat::mc {Found}] set var(found) [ttk::label $f.found \ -width 14 -relief groove -anchor w] set var(raname) [ttk::label $f.ra -text {} -width 3] set var(ramenu) [ttk::menubutton $f.ram -textvariable \ ${varname}(colx) -menu $f.ram.menu -width 14] set var(decname) [ttk::label $f.dec -text {} -width 3] set var(decmenu) [ttk::menubutton $f.decm -textvariable \ ${varname}(coly) -menu $f.decm.menu -width 14] CoordMenuButton $f.pcoord $varname psystem 1 psky {} \ [list CATColsCmd $varname] CoordMenuEnable $f.pcoord.menu $varname psystem 1 psky {} grid $f.mfilter $f.filter - - $f.bfilter \ -padx 2 -pady 2 -sticky w grid $f.msort $f.sort $f.isort $f.dsort \ -padx 2 -pady 2 -sticky w grid $f.mtitle $f.max $f.ftitle $f.found \ -padx 2 -pady 2 -sticky w grid $var(raname) $var(ramenu) $var(decname) $var(decmenu) $f.pcoord \ -padx 2 -pady 2 -sticky w # Table set f [ttk::frame $w.tbl] set var(tbl) [table $f.t \ -state disabled \ -usecommand 0 \ -variable $var(tbldb) \ -colorigin 1 \ -roworigin 0 \ -cols $icat(mincols) \ -rows $icat(minrows) \ -width -1 \ -height -1 \ -maxwidth 300 \ -maxheight 300 \ -titlerows 1 \ -xscrollcommand [list $f.xscroll set]\ -yscrollcommand [list $f.yscroll set]\ -selecttype row \ -selectmode extended \ -anchor w \ -font [font actual TkDefaultFont] \ -browsecommand [list CATSelectCmd $varname %s %S] \ ] ttk::scrollbar $f.yscroll -command [list $var(tbl) yview] -orient vertical ttk::scrollbar $f.xscroll -command [list $var(tbl) xview] -orient horizontal grid $var(tbl) $f.yscroll -sticky news grid $f.xscroll -stick news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Status set f [ttk::frame $w.status] ttk::label $f.title -text [msgcat::mc {Status}] ttk::label $f.item -textvariable ${varname}(status) grid $f.title $f.item -padx 2 -pady 2 -sticky w # Buttons set f [ttk::frame $w.buttons] ButtonButton $f.load [msgcat::mc {Load}] [list CATLoadVOTFile $varname] ButtonButton $f.save [msgcat::mc {Save}] [list CATSaveVOTFile $varname] set var(apply) [ttk::button $f.apply \ -text [msgcat::mc {Retrieve}] \ -command "CATApply $varname 0"] set var(cancel) [ttk::button $f.cancel -text \ [msgcat::mc {Cancel}] \ -command "ARCancel $varname" -state disabled] ttk::button $f.filter -text [msgcat::mc {Filter}] \ -command [list CATTable $varname] ttk::button $f.clear -text [msgcat::mc {Clear}] \ -command [list CATOff $varname] set var(samp) [ttk::button $f.samp \ -text [msgcat::mc {SAMP}] \ -command "SAMPSendTableLoadVotable {} $varname"] ttk::button $f.plot -text [msgcat::mc {Plot}] \ -command [list CATPlot $varname] ttk::button $f.close -text [msgcat::mc {Close}] \ -command [list CATDestroy $varname] pack $f.apply $f.cancel $f.filter $f.clear $f.samp $f.plot $f.close \ -side left -expand true -padx 2 -pady 4 # Fini ttk::separator $w.stbl -orient horizontal ttk::separator $w.sstatus -orient horizontal pack $w.buttons $w.sstatus $w.status $w.stbl -side bottom -fill x pack $w.cat $w.obj $w.param -side top -fill x pack $w.tbl -side top -fill both -expand true # needs to go after sort menu button is defined CATSortMenu $varname CATColsMenu $varname CATColsUpdate $varname switch $var(format) { cds {$mb entryconfig [msgcat::mc {Catalog Server}] -state normal} cxc - ned - skybot - sdss - simbad { $mb entryconfig [msgcat::mc {Catalog Server}] -state disabled } } ARCoord $varname CATUpdate $varname CATDialogUpdate $varname ARStatus $varname {} switch -- $action { apply {CATApply $varname 0} sync {CATApply $varname 1} none {} } # return the actual varname return $varname } proc CATDialogUpdate {varname} { upvar #0 $varname var global $varname global ds9 global samp global debug if {$debug(tcl,cat)} { puts stderr "CATDialogUpdate $varname" } # do we have a db? if {[CATValidDB $var(tbldb)]} { $var(mb).file entryconfig [msgcat::mc {Filter}] -state normal $var(mb).file entryconfig [msgcat::mc {Clear}] -state normal $var(mb).file entryconfig [msgcat::mc {Plot}] -state normal $var(mb).file entryconfig "[msgcat::mc {Display Header}]..." \ -state normal $var(mb).file entryconfig [msgcat::mc {Copy to Regions}] -state normal $var(mb).file entryconfig "[msgcat::mc {Print}]..." -state normal $var(top).buttons.filter configure -state normal $var(top).buttons.clear configure -state normal $var(top).buttons.plot configure -state normal } else { $var(mb).file entryconfig [msgcat::mc {Filter}] -state disabled $var(mb).file entryconfig [msgcat::mc {Clear}] -state disabled $var(mb).file entryconfig [msgcat::mc {Plot}] -state disabled $var(mb).file entryconfig "[msgcat::mc {Display Header}]..." \ -state disabled $var(mb).file entryconfig [msgcat::mc {Copy to Regions}] -stat disabled $var(mb).file entryconfig "[msgcat::mc {Print}]..." -state disabled $var(top).buttons.filter configure -state disabled $var(top).buttons.clear configure -state disabled $var(top).buttons.plot configure -state disabled } set m $var(mb).file.samp set ss [expr $ds9(menu,start)+2] if {[info exists samp]} { # menu $m entryconfig [msgcat::mc {Send}] -state normal $m entryconfig [msgcat::mc {Connect}] -state disabled $m entryconfig [msgcat::mc {Disconnect}] -state normal if {[$m.send index end] >= $ss} { $m.send delete $ss end } foreach args $samp(apps,votable) { foreach {id name} $args { $m.send add command -label $name \ -command "SAMPSendTableLoadVotable $id $varname" } } # button $var(samp) configure -state normal } else { # menu $m entryconfig [msgcat::mc {Send}] -state disabled $m entryconfig [msgcat::mc {Connect}] -state normal $m entryconfig [msgcat::mc {Disconnect}] -state disabled # button $var(samp) configure -state disabled } } proc CATAck {varname} { upvar #0 $varname var global $varname switch $var(format) { cds {CATCDSAck $varname} cxc {CATCXCAck $varname} ned {CATNEDAck $varname} skybot {CATSkyBotAck $varname} sdss {CATSDSSAck $varname} simbad {CATSIMBADAck $varname} } } proc CATApply {varname sync} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATApply $varname $sync" } if {$var(catalog) == {}} { Error [msgcat::mc {No Catalog specified}] return } set var(sync) $sync ARApply $varname if {$var(name) != {}} { set var(sky) fk5 CoordMenuButtonCmd $varname system sky {} CATWCSMenuUpdate $varname NSVRServer $varname } else { CATServer $varname } } proc CATCopy {varname} { upvar #0 $varname var global $varname set w [focus -displayof $var(top)] if {$w == $var(tbl)} { CATCopyTable $varname } else { EntryCopy $var(top) } } proc CATCopyTable {varname} { upvar #0 $varname var global $varname set w [focus -displayof $var(top)] set sel [$var(tbl) curselection] set data {} set row [lindex [split [lindex $sel 0] ,] 0] foreach ss $sel { set rr [lindex [split $ss ,] 0] if {$rr != $row} { append data "\n" set row $rr } else { if {$data != {}} { append data "\t" } } append data "[$var(tbl) get $ss]" } append data "\n" clipboard clear -displayof $w clipboard append -displayof $w $data } proc CATCut {varname} { upvar #0 $varname var global $varname set w [focus -displayof $var(top)] if {$w == $var(tbl)} { CATCopyTable $varname } else { EntryCut $var(top) } } proc CATCrosshair {varname} { upvar #0 $varname var global $varname if {![$var(frame) has fits]} { return } if {[$var(frame) has wcs equatorial $var(system)]} { set coord [$var(frame) get crosshair \ $var(system) $var(sky) $var(skyformat)] set var(x) [lindex $coord 0] set var(y) [lindex $coord 1] set var(name) {} } } proc CATDestroy {varname} { upvar #0 $varname var global $varname global $var(catdb) global $var(tbldb) global $var(symdb) global $var(symdl) global icat global debug if {$debug(tcl,cat)} { puts stderr "CATDestroy $varname" } # stop timer if needed if {$var(blink)} { set var(blink) 0 after cancel [list CATSelectTimer $varname] } # unhighlite any makers if {[$var(frame) has fits]} { $var(frame) marker catalog $varname unhighlite } upvar #0 $var(symdl) svar if [info exists svar(top)] { if [winfo exists $svar(top)] { CATSymDestroy $var(symdl) } } if [info exists $var(symdb)] { unset $var(symdb) } if [info exists $var(tbldb)] { unset $var(tbldb) } if [info exists $var(catdb)] { unset $var(catdb) } set i [lsearch $icat(cats) $varname] if {$i>=0} { set icat(cats) [lreplace $icat(cats) $i $i] } # plot window? if {$var(plot)} { PlotDestroy $var(plot,var) } ARDestroy $varname } proc CATEdit {varname} { upvar #0 $varname var global $varname global $var(tbldb) if {![$var(frame) has fits]} { return } $var(frame) marker catalog unselect all $var(frame) marker catalog unhighlite all CATGenerate $varname # regenerate the plot if needed if {$var(plot)} { CATPlotGenerate $varname } if {$var(edit)} { $var(tbl) configure \ -state normal \ -selectmode single } else { $var(tbl) configure \ -state disabled \ -selectmode extended } } proc CATGetHeader {varname} { upvar #0 $varname var global $varname global $var(tbldb) set t $var(tbldb) upvar #0 $t T if [CATValidDB $var(tbldb)] { set hdr {} # header set nl [expr $T(HLines)-2] for {set ll 1} {$ll <= $nl} {incr ll} { append hdr "$T(H_$ll)\n" } append hdr "\n" # dump cols stats set nc $T(Ncols) for {set cc 1} {$cc <= $nc} {incr cc} { append hdr "# name=[lindex $T(Header) [expr $cc-1]] " if {[info exists ${t}(DataType)]} { append hdr "datatype=[lindex $T(DataType) [expr $cc-1]] " } if {[info exists ${t}(Id)]} { if {[lindex $T(Id) [expr $cc-1]] != {}} { append hdr "id=[lindex $T(Id) [expr $cc-1]] " } } if {[info exists ${t}(ArraySize)]} { if {[lindex $T(ArraySize) [expr $cc-1]] != {}} { append hdr "arraysize=[lindex $T(ArraySize) [expr $cc-1]] " } } if {[info exists ${t}(Width)]} { if {[lindex $T(Width) [expr $cc-1]] != {}} { append hdr "width=[lindex $T(Width) [expr $cc-1]] " } } if {[info exists ${t}(Precision)]} { if {[lindex $T(Precision) [expr $cc-1]] != {}} { append hdr "precision=[lindex $T(Precision) [expr $cc-1]] " } } if {[info exists ${t}(Unit)]} { if {[lindex $T(Unit) [expr $cc-1]] != {}} { append hdr "unit=[lindex $T(Unit) [expr $cc-1]] " } } if {[info exists ${t}(Ref)]} { if {[lindex $T(Ref) [expr $cc-1]] != {}} { append hdr "ref=[lindex $T(Ref) [expr $cc-1]] " } } if {[info exists ${t}(Ucd)]} { if {[lindex $T(Ucd) [expr $cc-1]] != {}} { append hdr "ucd=[lindex $T(Ucd) [expr $cc-1]] " } } if {[info exists ${t}(Description)]} { if {[lindex $T(Description) [expr $cc-1]] != {}} { append hdr "[lindex $T(Description) [expr $cc-1]] " } } append hdr "\n" } return $hdr } return {} } proc CATHeader {varname} { upvar #0 $varname var global $varname global $var(tbldb) SimpleTextDialog ${varname}hdr "$var(title) [msgcat::mc {Header}]" \ 80 20 insert top [CATGetHeader $varname] } proc CATKey {which key} { global icat global ds9 set icat(key) $key set icat(key,update) {} $which marker catalog key foreach rr $icat(key,update) { eval "CATGenerateUpdate [lindex $rr 0] [lindex $rr 1]" } set icat(key) {} set icat(key,update) {} } proc CATPageSetup {varname} { upvar #0 $varname var global $varname global ds9 switch $ds9(wm) { x11 {} win32 {win32 pm pagesetup} aqua {macosx pm pagesetup} } } proc CATPrint {varname} { upvar #0 $varname var global $varname global $var(tbldb) global ds9 switch $ds9(wm) { x11 {CATPSPrint $varname} win32 {win32 pm print text [::textutil::tabify::untabify2 [starbase_write_ $var(tbldb)] 12]} aqua {macosx pm print text [::textutil::tabify::untabify2 [starbase_write_ $var(tbldb)] 12]} } } proc CATPSPrint {varname} { upvar #0 $varname var global $varname global $var(tbldb) global ps if {[PRPrintDialog]} { if {$ps(dest) == "file"} { catch {set ch [open "| cat > $ps(filename,txt)" w]} } else { catch {set ch [open "| $ps(cmd)" w]} } if {$ch != {}} { starbase_writefp $var(tbldb) $ch close $ch } else { Error [msgcat::mc {An error has occurred while printing}] return } } } proc CATServer {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATServer $varname" } if {($var(x) != {}) && ($var(y) != {}) && ($var(width) != {}) && ($var(height) != {})} { ARStatus $varname "Searching [string range $var(title) 0 50]" switch $var(format) { cds {CATCDS $varname} cxc {CATCXC $varname} ned {CATNED $varname} skybot {CATSkyBot $varname} sdss {CATSDSS $varname} simbad {CATSIMBAD $varname} } } else { ARStatus $varname [msgcat::mc {Please specify width, height, and either name or (ra,dec)}] $var(mb).file entryconfig [msgcat::mc {Retrieve}] -state normal $var(mb).file entryconfig [msgcat::mc {Cancel}] -state disabled $var(apply) configure -state normal $var(cancel) configure -state disabled } } proc CATUpdate {varname} { upvar #0 $varname var global $varname global debug if {$debug(tcl,cat)} { puts stderr "CATUpdate $varname" } if {![$var(frame) has fits]} { return } if {[$var(frame) has wcs equatorial $var(system)]} { set coord [$var(frame) get fits center \ $var(system) $var(sky) $var(skyformat)] set var(x) [lindex $coord 0] set var(y) [lindex $coord 1] set size [$var(frame) get fits size \ $var(system) $var(sky) $var(rformat)] set var(width) [lindex $size 0] set var(height) [lindex $size 1] set var(name) {} } } proc CATWCSMenuUpdate {varname} { upvar #0 $varname var global $varname ARCoord $varname set var(psystem) $var(system) set var(psky) $var(sky) CoordMenuButtonCmd $varname psystem psky {} CATColsUpdate $varname } proc CATColsUpdate {varname} { upvar #0 $varname var global $varname global ds9 global pds9 switch $var(psystem) { image - physical - detector - amplifier { $var(raname) configure -text {X} \ -font [font actual TkDefaultFont] $var(decname) configure -text {Y} \ -font [font actual TkDefaultFont] } default { if {[$var(frame) has wcs equatorial $var(psystem)]} { switch $var(psky) { fk4 - fk5 - icrs { $var(raname) configure -text "\u03b1" \ -font "symbol $pds9(font,size)" $var(decname) configure -text "\u03b4" \ -font "symbol $pds9(font,size)" } galactic { $var(raname) configure -text {l} \ -font "{$ds9(times)} $pds9(font,size) normal italic" $var(decname) configure -text {b} \ -font "{$ds9(times)} $pds9(font,size) normal italic" } ecliptic { $var(raname) configure -text "\u03bb" \ -font "symbol $pds9(font,size)" $var(decname) configure -text "\u03b2" \ -font "symbol $pds9(font,size)" } } } else { $var(raname) configure -text {X} \ -font [font actual TkDefaultFont] $var(decname) configure -text {Y} \ -font [font actual TkDefaultFont] } } } } # Edit Dialog proc CATEditDialog {varname which db} { upvar #0 $varname var global $varname global ds9 global ed set w ".${varname}edit" set mb ".${varname}editmb" set ed(ok) 0 set ed(text) $w.param.txt DialogCreate $w [msgcat::mc {Edit}] ed(ok) $w configure -menu $mb menu $mb # file $mb add cascade -label [msgcat::mc {File}] -menu $mb.file menu $mb.file $mb.file add command -label [msgcat::mc {Apply}] \ -command {set ed(ok) 1} $mb.file add command -label [msgcat::mc {Clear}] \ -command CATEditClear $mb.file add separator $mb.file add command -label "[msgcat::mc {Load}]..." \ -command CATEditLoad $mb.file add command -label "[msgcat::mc {Save}]..." \ -command CATEditSave $mb.file add separator $mb.file add command -label [msgcat::mc {Cancel}] \ -command {set ed(ok) 0} # edit $mb add cascade -label [msgcat::mc {Edit}] -menu $mb.edit menu $mb.edit $mb.edit add command -label [msgcat::mc {Undo}] \ -command "$ed(text) edit undo" -accelerator "${ds9(ctrl)}Z" $mb.edit add command -label [msgcat::mc {Redo}] \ -command "$ed(text) edit redo" -accelerator "${ds9(shiftctrl)}Z" $mb.edit add separator $mb.edit add command -label [msgcat::mc {Cut}] \ -command "tk_textCut $ed(text)" -accelerator "${ds9(ctrl)}X" $mb.edit add command -label [msgcat::mc {Copy}] \ -command "tk_textCopy $ed(text)" -accelerator "${ds9(ctrl)}C" $mb.edit add command -label [msgcat::mc {Paste}] \ -command "tk_textPaste $ed(text)" -accelerator "${ds9(ctrl)}V" global $db # column $mb add cascade -label [msgcat::mc {Column}] -menu $mb.col if [info exists $mb.col] { destroy $mb.col) } menu $mb.col if [CATValidDB $db] { set cnt -1 foreach col [starbase_columns $db] { $mb.col add command -label "$col" \ -command "$ed(text) insert insert \{\$$col\}" # wrap if needed incr cnt if {$cnt>=$ds9(menu,size,wrap)} { set cnt 0 $mb.col entryconfig $col -columnbreak 1 } } } # operator $mb add cascade -label [msgcat::mc {Operator}] -menu $mb.op menu $mb.op $mb.op add command -label {-} \ -command "$ed(text) insert insert {-}" $mb.op add command -label {!} \ -command "$ed(text) insert insert {!}" $mb.op add command -label {(} \ -command "$ed(text) insert insert {(}" $mb.op add command -label {)} \ -command "$ed(text) insert insert {)}" $mb.op add separator $mb.op add command -label {*} \ -command "$ed(text) insert insert {*}" $mb.op add command -label {/} \ -command "$ed(text) insert insert {/}" $mb.op add command -label {%} \ -command "$ed(text) insert insert {%}" $mb.op add command -label {+} \ -command "$ed(text) insert insert {+}" $mb.op add command -label {-} \ -command "$ed(text) insert insert {-}" $mb.op add separator $mb.op add command -label {<} \ -command "$ed(text) insert insert {<}" $mb.op add command -label {>} \ -command "$ed(text) insert insert {>}" $mb.op add command -label {<=} \ -command "$ed(text) insert insert {<=}" $mb.op add command -label {>=} \ -command "$ed(text) insert insert {>=}" $mb.op add command -label {==} \ -command "$ed(text) insert insert {==}" $mb.op add command -label {!=} \ -command "$ed(text) insert insert {!=}" $mb.op add separator $mb.op add command -label {&&} \ -command "$ed(text) insert insert {&&}" $mb.op add command -label {||} \ -command "$ed(text) insert insert {||}" # operator $mb add cascade -label [msgcat::mc {Math Function}] -menu $mb.math menu $mb.math $mb.math add command -label {acos} \ -command "$ed(text) insert insert {acos()}" $mb.math add command -label {asin} \ -command "$ed(text) insert insert {asin()}" $mb.math add command -label {atan} \ -command "$ed(text) insert insert {atan()}" $mb.math add command -label {atan2} \ -command "$ed(text) insert insert {atan2(,)}" $mb.math add command -label {ceil} \ -command "$ed(text) insert insert {ceil()}" $mb.math add command -label {cos} \ -command "$ed(text) insert insert {cos()}" $mb.math add command -label {cosh} \ -command "$ed(text) insert insert {cosh()}" $mb.math add command -label {exp} \ -command "$ed(text) insert insert {exp()}" $mb.math add command -label {floor} \ -command "$ed(text) insert insert {floor()}" $mb.math add command -label {fmod} \ -command "$ed(text) insert insert {fmod(,)}" $mb.math add command -label {hypot} \ -command "$ed(text) insert insert {hypot(,)}" $mb.math add command -label {log} \ -command "$ed(text) insert insert {log()}" $mb.math add command -label {log10} \ -command "$ed(text) insert insert {log10()}" $mb.math add command -label {pow} \ -command "$ed(text) insert insert {pow(,)}" $mb.math add command -label {sin} \ -command "$ed(text) insert insert {sin()}" $mb.math add command -label {sinh} \ -command "$ed(text) insert insert {sinh()}" $mb.math add command -label {sqrt} \ -command "$ed(text) insert insert {sqrt()}" $mb.math add command -label {tan} \ -command "$ed(text) insert insert {tan()}" $mb.math add command -label {tanh} \ -command "$ed(text) insert insert {tanh()}" $mb.math add command -label {abs} \ -command "$ed(text) insert insert {abs()}" $mb.math add command -label {double} \ -command "$ed(text) insert insert {double()}" $mb.math add command -label {int} \ -command "$ed(text) insert insert {int()}" $mb.math add command -label {round} \ -command "$ed(text) insert insert {round()}" # Text set f [ttk::frame $w.param] text $f.txt \ -height 10 \ -width 60 \ -yscrollcommand "$f.yscroll set" \ -xscrollcommand "$f.xscroll set" \ -undo true \ -wrap none ttk::scrollbar $f.yscroll -command [list $ed(text) yview] \ -orient vertical ttk::scrollbar $f.xscroll -command [list $ed(text) xview] \ -orient horizontal grid $ed(text) $f.yscroll -sticky news grid $f.xscroll -stick news grid rowconfigure $f 0 -weight 1 grid columnconfigure $f 0 -weight 1 # Buttons set f [ttk::frame $w.buttons] ttk::button $f.ok -text [msgcat::mc {OK}] -command {set ed(ok) 1} \ -default active ttk::button $f.clear -text [msgcat::mc {Clear}] -command CATEditClear ttk::button $f.cancel -text [msgcat::mc {Cancel}] -command {set ed(ok) 0} pack $f.ok $f.clear $f.cancel -side left -expand true -padx 2 -pady 4 bind $w <Return> {set ed(ok) 1} # Fini ttk::separator $w.sep -orient horizontal pack $w.param -side top -fill both -expand true pack $w.buttons $w.sep -side bottom -fill x $ed(text) insert end $var($which) $ed(text) see end DialogCenter $w DialogWait $w ed(ok) $w.buttons.ok if {$ed(ok)} { set flt [$ed(text) get 1.0 end] catch {regsub {\n} $flt " " flt} set var($which) [string trim $flt] } DialogDismiss $w destroy $mb set rr $ed(ok) unset ed return $rr } proc CATEditClear {} { global ed $ed(text) delete 1.0 end } proc CATEditSave {} { global ed set fn [SaveFileDialog catfltfbox] if {$fn != {}} { if [catch {open $fn w} fp] { Error "[msgcat::mc {Unable to open file}] $fn: $fp" return } set flt [$ed(text) get 1.0 end] catch {regsub {\n} $flt " " flt} puts $fp [string trim $flt] catch {close $fp} } } proc CATEditLoad {} { global ed set fn [OpenFileDialog catfltfbox] if {$fn != {}} { if [catch {open $fn r} fp] { Error "[msgcat::mc {Unable to open file}] $fn: $fp" return } $ed(text) delete 1.0 end $ed(text) insert end [read -nonewline $fp] $ed(text) see end catch {close $fp} } } proc UpdateCATDialog {} { global icat foreach varname $icat(cats) { CATDialogUpdate $varname } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/mosaiciraf.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000003361�12130604762�014517� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc LoadMosaicIRAFFile {fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic iraf} set loadParam(load,type) mmapincr set loadParam(file,name) $fn set loadParam(load,layer) $layer ConvertFitsFile ProcessLoad } proc LoadMosaicIRAFAlloc {path fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic iraf} set loadParam(load,type) allocgz set loadParam(file,name) $fn set loadParam(file,fn) $path set loadParam(load,layer) $layer ProcessLoad } proc LoadMosaicIRAFSocket {sock fn layer} { global loadParam set loadParam(file,type) fits set loadParam(file,mode) {mosaic iraf} set loadParam(load,type) socketgz set loadParam(file,name) $fn set loadParam(socket,id) $sock set loadParam(load,layer) $layer return [ProcessLoad 0] } proc ProcessMosaicIRAFCmd {varname iname sock fn} { upvar $varname var upvar $iname i global loadParam global current set layer {} switch -- [string tolower [lindex $var $i]] { new { incr i CreateFrame } mask { incr i set layer mask } slice { incr i # not supported } } set param [lindex $var $i] StartLoad if {$sock != {}} { # xpa if {![LoadMosaicIRAFSocket $sock $param $layer]} { InitError xpa LoadMosaicIRAFFile $param $layer } } else { # comm if {$fn != {}} { LoadMosaicIRAFAlloc $fn $param $layer } else { LoadMosaicIRAFFile $param $layer } } FinishLoad } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/src/samp.tcl�������������������������������������������������������������������������������0000644�0001750�0001750�00000103245�12126364474�013354� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1999-2012 # Smithsonian Astrophysical Observatory, Cambridge, MA, USA # For conditions of distribution and use, see copyright notice in "copyright" package provide DS9 1.0 proc SAMPDef {} { global isamp set isamp(timeout) 1000 } proc InitSAMP {} { global pds9 if {$pds9(samp)} { catch {SAMPConnect 0} } } # Cmds proc SAMPConnect {{verbose 1}} { global ds9 global isamp global samp global sampmap # connected? if [info exists samp] { if {$verbose} { Error [msgcat::mc {SAMP: already connected}] } return } # reset samp array catch {unset samp} set samp(apps,image) {} set samp(apps,table) {} set samp(apps,votable) {} # these are to try to prevent feedback problems with # other probgrams set samp(rcvd,lock) 0 set samp(send,lock) 0 # delete any old tmp files SAMPDelTmpFiles # can we find a hub? if {![SAMPParseHub]} { if {$verbose} { Error [msgcat::mc {SAMP: unable to locate HUB}] } catch {unset samp} return } # register set params [list "string $samp(secret)"] if {![SAMPSend {samp.hub.register} $params rr]} { if {$verbose} { Error [msgcat::mc {SAMP: internal error}] } catch {unset samp} return } set rr [lindex $rr 1] foreach ff $rr { foreach {key val} $ff { switch -- $key { samp.hub-id {set samp(hub) $val} samp.self-id {set samp(self) $val} samp.private-key {set samp(private) $val} } } } # declare metadata catch {unset sampmap} set sampmap(samp.name) {string "SAOImage DS9"} set sampmap(samp.description.text) {string "SAOImage DS9 is an astronomical visualization application"} set sampmap(samp.icon.url) {string "http://hea-www.harvard.edu/RD/ds9/sun.gif"} set sampmap(samp.documentation.url) {string "http://hea-www.harvard.edu/RD/ds9/ref/index.html"} set sampmap(home.page) {string "http://hea-www.harvard.edu/RD/ds9/"} set sampmap(author.name) {string "William Joye"} set sampmap(author.email) {string "saord@cfa.harvard.edu"} set sampmap(author.affiliation) {string "Smithsonian Astrophysical Observatory"} set sampmap(ds9.version) "string \"$ds9(version)\"" set param1 [list "string $samp(private)"] set param2 [list "struct sampmap"] set params "$param1 $param2" if {![SAMPSend {samp.hub.declareMetadata} $params rr]} { if {$verbose} { Error [msgcat::mc {SAMP: internal error}] } catch {unset samp} return } # who are we set samp(port) [lindex [fconfigure [xmlrpc::serve 0] -sockname] 2] set samp(home) "[info hostname]:$samp(port)" # callback set param1 [list "string $samp(private)"] set param2 [list "string http://$samp(home)"] set params "$param1 $param2" if {![SAMPSend {samp.hub.setXmlrpcCallback} $params rr]} { if {$verbose} { Error [msgcat::mc {SAMP: internal error}] } catch {unset samp} return } # declare subscriptions catch {unset sampmap} set sampmap(samp.app.ping) {struct mapPing} set sampmap(samp.hub.event.shutdown) {struct mapShutdown} set sampmap(samp.hub.event.register) {struct mapRegister} set sampmap(samp.hub.event.unregister) {struct mapUnregister} set sampmap(samp.hub.disconnect) {struct mapDisconnect} set sampmap(image.load.fits) {struct mapImageLoadFits} set sampmap(table.load.fits) {struct mapTableLoadFits} set sampmap(table.load.votable) {struct mapTableLoadVotable} set sampmap(table.highlight.row) {struct mapTableHighlightRow} set sampmap(table.select.rowList) {struct mapTableSelectRowList} set sampmap(coord.pointAt.sky) {struct mapCoordPointAtSky} set sampmap(client.env.get) {struct mapClientEnvGet} set sampmap(ds9.get) {struct mapDS9Get} set sampmap(ds9.set) {struct mapDS9Set} set param1 [list "string $samp(private)"] set param2 [list "struct sampmap"] set params "$param1 $param2" if {![SAMPSend {samp.hub.declareSubscriptions} $params rr]} { if {$verbose} { Error [msgcat::mc {SAMP: internal error}] } catch {unset samp} return } after $isamp(timeout) SAMPUpdate } proc SAMPDisconnect {} { global ds9 global samp # connected? if {![info exists samp]} { Error [msgcat::mc {SAMP: not connected}] return } # disconnect if {[info exists samp(private)]} { set params [list "string $samp(private)"] set rr {} SAMPSend {samp.hub.unregister} $params rr SAMPShutdown } UpdateFileMenu UpdateCATDialog } proc SAMPSendImageLoadFits {id} { global ds9 global current global isamp global samp global sampmap global sampmap2 global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendImageLoadFits" } # connected? if {![info exists samp]} { Error [msgcat::mc {SAMP: not connected}] return } # are we locked? if {$samp(rcvd,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Rcvd locked" } return } # got something to send? if {![$current(frame) has fits]} { return } # save current frame set fn [tmpnam ds9samp {.fits}] catch {$current(frame) save fits image file "\{$fn\}"} # name to use set fnb [$current(frame) get fits file name root base] if [regexp {(.*)\[.*\]} $fnb aa bb] { set fnb $bb } # cmd catch {unset sampmap} set sampmap(samp.mtype) {string "image.load.fits"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(url) "string \"[XMLQuote file://localhost/$fn]\"" set sampmap2(name) "string \"[XMLQuote $fnb]\"" set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendTableLoadFits {id} { global ds9 global current global isamp global samp global sampmap global sampmap2 global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendTableLoadFits" } # connected? if {![info exists samp]} { Error [msgcat::mc {SAMP: not connected}] return } # are we locked? if {$samp(rcvd,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Rcvd locked" } return } # got something to send? if {![$current(frame) has fits] && [$current(frame) has fits bin]} { return } # save current frame set fn [tmpnam ds9samp {.fits}] catch {$current(frame) save fits table file "\{$fn\}"} # name to use set fnb [$current(frame) get fits file name root base] if [regexp {(.*)\[.*\]} $fnb aa bb] { set fnb $bb } # cmd catch {unset sampmap} set sampmap(samp.mtype) {string "table.load.fits"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(url) "string \"[XMLQuote file://localhost/$fn]\"" set sampmap2(name) "string \"[XMLQuote $fnb]\"" set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendTableLoadVotable {id varname} { global ds9 global isamp global samp global sampmap global sampmap2 upvar #0 $varname var global $varname global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendTableLoadVotable $id $varname" } # connected? if {![info exists samp]} { Error [msgcat::mc {SAMP: not connected}] return } # are we locked? if {$samp(rcvd,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Rcvd locked" } return } # remember set samp(icat,$varname$samp(port)) $varname set samp(ocat,$varname) $varname$samp(port) # save votable set fn [tmpnam ds9samp {.xml}] CATSaveFn $varname $fn CATVOTWrite # cmd catch {unset sampmap} set sampmap(samp.mtype) {string "table.load.votable"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(url) "string \"[XMLQuote file://localhost/$fn]\"" set sampmap2(table-id) "string [XMLQuote $varname$samp(port)]" set sampmap2(name) "string \"[XMLQuote $var(title)]\"" set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendTableHighlightRow {id varname row} { global isamp global samp global sampmap global sampmap2 # row starts at 1 upvar #0 $varname var global $varname global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendTableHighlightRow $samp(ocat,$varname) $row" } catch {unset sampmap} set sampmap(samp.mtype) {string "table.highlight.row"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(table-id) "string [XMLQuote $samp(ocat,$varname)]" set sampmap2(row) "string [XMLQuote [expr $row-1]]" set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendTableSelectRowList {id varname rows} { global isamp global samp global sampmap global sampmap2 # rows start at 1 upvar #0 $varname var global $varname global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendTableSelectRowList $samp(ocat,$varname) $rows" } catch {unset sampmap} set sampmap(samp.mtype) {string "table.select.rowList"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(table-id) "string [XMLQuote $samp(ocat,$varname)]" set ss {} foreach rr $rows { lappend ss "string [expr $rr-1]" } set sampmap2(row-list) [list array $ss] set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendTableRowListCmd {varname rowlist} { global ds9 global samp # connected? if {![info exists samp]} { return } if {$samp(apps,votable) == {}} { return } # are we good? if {![info exists samp(ocat,$varname)]} { return } # are we locked? if {$samp(rcvd,lock)} { global debug if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Rcvd locked" } return } switch -- [llength $rowlist] { 0 {} 1 {SAMPSendTableHighlightRow {} $varname $rowlist} default {SAMPSendTableSelectRowList {} $varname $rowlist} } } proc SAMPSendCoordPointAtSky {id coord} { global isamp global samp global sampmap global sampmap2 global debug if {$debug(tcl,samp)} { puts stderr "SAMPSendCoordPointAtSky $id $coord" } catch {unset sampmap} set sampmap(samp.mtype) {string "coord.pointAt.sky"} set sampmap(samp.params) {struct sampmap2} catch {unset sampmap2} set sampmap2(ra) "string [XMLQuote [lindex $coord 0]]" set sampmap2(dec) "string [XMLQuote [lindex $coord 1]]" set param1 [list "string $samp(private)"] if {$id != {}} { set param2 [list "string $id"] } else { set param2 {} } set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {$id != {}} { SAMPSend {samp.hub.notify} $params rr } else { SAMPSend {samp.hub.notifyAll} $params rr } # set lock set samp(send,lock) 1 after $isamp(timeout) SAMPClearSendLock } proc SAMPSendCoordPointAtSkyCmd {which} { global ds9 global samp # connected? if {![info exists samp]} { return } # are we locked? if {$samp(rcvd,lock)} { global debug if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Rcvd locked" } return } if {$samp(apps,image) == {} || $samp(apps,table) == {}} { return } if [$which has wcs equatorial wcs] { set coord [$which get coordinates [$which get cursor canvas] wcs fk5 degrees] if {$coord != {}} { SAMPSendCoordPointAtSky {} "$coord" } } } # Support proc SAMPShutdown {} { global ds9 global samp # delete any files SAMPDelTmpFiles # close the server socket if still up catch {close $xmlrpc::acceptfd} # update the menus set samp(apps,image) {} set samp(apps,table) {} set samp(apps,votable) {} UpdateFileMenu UpdateCATDialog # unset samp array catch {unset samp} } proc SAMPUpdate {} { # this routine is run after a delay since it needs to # call the hub for metadata # connected? we might have already disconnected. global samp if {![info exists samp]} { return } global debug if {$debug(tcl,samp)} { puts stderr "SAMPUpdate" } # image fits set param1 [list "string $samp(private)"] set param2 [list "string image.load.fits"] set params "$param1 $param2" if {![SAMPSend {samp.hub.getSubscribedClients} $params rr]} { return } set samp(apps,image) {} foreach arg [lindex $rr 1] { foreach {key val} $arg { if {$key != {}} { lappend samp(apps,image) [list $key [SAMPGetAppName $key]] } } } # table fits set param1 [list "string $samp(private)"] set param2 [list "string table.load.fits"] set params "$param1 $param2" if {![SAMPSend {samp.hub.getSubscribedClients} $params rr]} { return } set samp(apps,table) {} foreach arg [lindex $rr 1] { foreach {key val} $arg { if {$key != {}} { lappend samp(apps,table) [list $key [SAMPGetAppName $key]] } } } # votable set param1 [list "string $samp(private)"] set param2 [list "string table.load.votable"] set params "$param1 $param2" if {![SAMPSend {samp.hub.getSubscribedClients} $params rr]} { return } set samp(apps,votable) {} foreach arg [lindex $rr 1] { foreach {key val} $arg { if {$key != {}} { lappend samp(apps,votable) [list $key [SAMPGetAppName $key]] } } } if {$debug(tcl,samp)} { puts stderr "SAMPUpdate: image apps: $samp(apps,image)" puts stderr "SAMPUpdate: table apps: $samp(apps,table)" puts stderr "SAMPUpdate: votable apps: $samp(apps,votable)" } UpdateFileMenu UpdateCATDialog } proc SAMPSend {method params resultVar} { upvar $resultVar result global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPSend: $method $params" } if {[catch {set result [xmlrpc::call $samp(url) $samp(method) $method $params]}]} { if {$debug(tcl,samp)} { puts stderr "SAMPSend Error: $result" } return 0 } # reset error if needed # xmlrpc leaves error msgs InitError samp if {$debug(tcl,samp)} { puts stderr "SAMPSend Result: $result" } return 1 } proc SAMPReply {msgid status {result {}} {url {}} {error {}}} { global samp global sampmap global sampmap2 global sampmap3 global debug if {$debug(tcl,samp)} { puts stderr "SAMPReply:$msgid:$status:$result:$url:$error:" } catch {unset sampmap} catch {unset sampmap2} catch {unset sampmap3} switch -- $status { OK { set sampmap(samp.status) {string "samp.ok"} set sampmap(samp.result) {struct sampmap2} if {$result != {}} { set sampmap2(value) "string \"[XMLQuote $result]\"" } if {$url != {}} { set sampmap2(url) "string \"[XMLQuote $url]\"" } } WARNING { set sampmap(samp.status) {string "samp.warning"} set sampmap(samp.result) {struct sampmap2} set sampmap(samp.error) {struct sampmap3} if {$result != {}} { set sampmap2(value) "string \"[XMLQuote $result]\"" } if {$url != {}} { set sampmap2(url) "string \"[XMLQuote $url]\"" } set sampmap3(samp.errortxt) "string \"[XMLQuote $error]\"" } ERROR { set sampmap(samp.status) {string "samp.error"} set sampmap(samp.error) {struct sampmap3} set sampmap3(samp.errortxt) "string \"[XMLQuote $error]\"" } } set param1 [list "string $samp(private)"] set param2 [list "string $msgid"] set param3 [list "struct sampmap"] set params "$param1 $param2 $param3" if {![SAMPSend {samp.hub.reply} $params rr]} { return } } proc SAMPClearSendLock {} { global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPClearSendLock" } set samp(send,lock) 0 } # receiveNotification(string sender-id, map message) proc samp.client.receiveNotification {args} { global debug if {$debug(tcl,samp)} { puts stderr "SAMPReceivedNotification: $args" } set secret [lindex $args 0] set id [lindex $args 1] set map [lindex $args 2] set mtype {} set params {} foreach mm $map { foreach {key val} $mm { switch -- $key { samp.mtype {set mtype $val} samp.params {set params $val} } } } switch -- $mtype { samp.hub.event.shutdown { SAMPRcvdEventShutdown params } samp.hub.event.register { SAMPRcvdEventRegister params } samp.hub.event.unregister { SAMPRcvdEventUnregister params } samp.hub.disconnect { SAMPRcvdDisconnect params } image.load.fits { SAMPRcvdImageLoadFits params } table.load.fits { SAMPRcvdTableLoadFits params } table.load.votable { SAMPRcvdTableLoadVotable params } table.highlight.row { SAMPRcvdTableHighlightRow params } table.select.rowList { SAMPRcvdTableSelectRowList params } coord.pointAt.sky { SAMPRcvdCoordPointAtSky params } ds9.set { SAMPRcvdDS9Set {} params } default { if {$debug(tcl,samp)} { puts stderr "SAMP samp.client.receiveNotification: bad mtype $mtype" } } } return {string OK} } # receiveCall(string sender-id, string msg-id, map message) proc samp.client.receiveCall {args} { global debug if {$debug(tcl,samp)} { puts stderr "SAMPReceivedCall: $args" } set secret [lindex $args 0] set id [lindex $args 1] set msgid [lindex $args 2] set map [lindex $args 3] set mtype {} set params {} foreach mm $map { foreach {key val} $mm { switch -- $key { samp.mtype {set mtype $val} samp.params {set params $val} } } } switch -- $mtype { samp.app.ping { SAMPReply $msgid OK } image.load.fits { SAMPRcvdImageLoadFits params SAMPReply $msgid OK } table.load.fits { SAMPRcvdTableLoadFits params SAMPReply $msgid OK } table.load.votable { SAMPRcvdTableLoadVotable params SAMPReply $msgid OK } table.highlight.row { SAMPRcvdTableHighlightRow params SAMPReply $msgid OK } table.select.rowList { SAMPRcvdTableSelectRowList params SAMPReply $msgid OK } coord.pointAt.sky { SAMPRcvdCoordPointAtSky params SAMPReply $msgid OK } client.env.get { SAMPRcvdClientEnvGet $msgid params } ds9.get { SAMPRcvdDS9Get $msgid params } ds9.set { SAMPRcvdDS9Set $msgid params } default { SAMPReply $msgid ERROR {} {} "[msgcat::mc {Unknown command}]: $mtype" if {$debug(tcl,samp)} { puts stderr "SAMP samp.client.receiveCall: bad mtype $mtype" } } } return {string OK} } # receiveResponse(string responder-id, string msg-tag, map response) proc samp.client.receiveResponse {args} { global debug if {$debug(tcl,samp)} { puts stderr "SAMPReceivedResponse: $args" } set msgtag [lindex $args 0] set value [lindex $args 1] set map [lindex $args 2] return {string OK} } # Support proc SAMPParseHub {} { global samp global env set fn {} if {[info exists env(SAMP_HUB)]} { if {$env(SAMP_HUB) != {}} { set exp {std-lockurl:(.*)} if {[regexp $exp $env(SAMP_HUB) dummy url]} { ParseURL $url rr switch -- $rr(scheme) { ftp { set fn [tmpnam ds9samp {.samp}] GetFileFTP $rr(authority) $rr(path) $fn } file {set fn $rr(path)} http - default { set fn [tmpnam ds9samp {.samp}] GetFileHTTP $url $fn } } } } } if {$fn == {}} { # look in home directory for .samp global tcl_platform switch $tcl_platform(platform) { unix { set fn [file join [GetEnvHome] {.samp}] } windows { set fn [file join "$env(HOMEDRIVE)$env(HOMEPATH)" {.samp}] } } } # no hub to be found if {![file exist $fn]} { return 0 } set samp(secret) {} set samp(url) {} set samp(metod) {} set fp [open $fn r] while {1} { if {[gets $fp line] == -1} { break } # skip any comments if {[string range $line 0 0] == "#"} { continue; } if {[regexp -nocase {samp.secret=(.*)} $line foo ss]} { set samp(secret) $ss } if {[regexp -nocase {samp.hub.xmlrpc.url=(.*)} $line foo url]} { if [ParseURL $url r] { set samp(url) $r(scheme)://$r(authority) set samp(method) [string range $r(path) 1 end] } } } catch {close $fp} if {$samp(secret) == {} || $samp(url) == {}} { SAMPDelTmpFiles return 0 } global debug if {$debug(tcl,samp)} { puts stderr "SAMPParseHub: $samp(secret) $samp(url) $samp(method)" } return 1 } proc SAMPGetAppName {id} { global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPGetAppName: $id" } set param1 [list "string $samp(private)"] set param2 [list "string $id"] set params "$param1 $param2" if {![SAMPSend {samp.hub.getMetadata} $params rr]} { return } set name {} foreach arg [lindex $rr 1] { foreach {key val} $arg { switch -- $key { samp.name {set name [XMLUnQuote $val]} } } } return $name } # CallBacks # Hub proc SAMPRcvdEventShutdown {varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdEventShutdown: $args" } SAMPShutdown } proc SAMPRcvdEventRegister {varname} { upvar $varname args global isamp global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdEventRegister: $args" } foreach arg $args { foreach {key val} $arg { switch -- $key { id { # check to see if its just us if {$samp(self) == $val} { return } } } } } # wait after $isamp(timeout) SAMPUpdate } proc SAMPRcvdEventUnregister {varname} { upvar $varname args global isamp global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdEventUnregister: $args" } foreach arg $args { foreach {key val} $arg { switch -- $key { id { # check to see if its just us if {$samp(self) == $val} { return } } } } } # wait after $isamp(timeout) SAMPUpdate } proc SAMPRcvdDisconnect {varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdDisconnect: $args" } set msg {} foreach arg $args { foreach {key val} $arg { switch -- $key { reason {set msg [XMLUnQuote $val]} } } } SAMPShutdown } # HTTPClient proc SAMPRcvdImageLoadFits {varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdImageLoadFits: $args" } global current global samp # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set imageid {} set name {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} image-id {set imageid [XMLUnQuote $val]} name {set name [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdImageLoadFits: $url $imageid $name" } if {$url != {}} { MultiLoad LoadURLFits $url {} {} } } proc SAMPRcvdTableLoadFits {varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableLoadFits: $args" } global current global samp # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set imageid {} set name {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} image-id {set imageid [XMLUnQuote $val]} name {set name [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableLoadFits: $url $imageid $name" } if {$url != {}} { MultiLoad LoadURLFits $url {} {} } } proc SAMPRcvdTableLoadVotable {varname} { upvar $varname args global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableLoadVotable: $args" } # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set tabid {} set name {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} table-id {set tabid [XMLUnQuote $val]} name {set name [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableLoadVotable: $url $tabid $name" } global icat if {$url != {}} { CATVOTURL $url $name $tabid if {$tabid != {}} { set catid [lindex $icat(cats) end] set samp(icat,$tabid) $catid set samp(ocat,$catid) $tabid } } } proc SAMPRcvdTableHighlightRow {varname} { upvar $varname args global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableHighlightRow: $args" } # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set tabid {} set row {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} table-id {set tabid [XMLUnQuote $val]} row {set row [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableHighlightRow: $url $tabid $row" } if {$tabid != {} && $row != {}} { if [info exists samp(icat,$tabid)] { CATSelectRows $samp(icat,$tabid) samp [expr $row+1] } } } proc SAMPRcvdTableSelectRowList {varname} { upvar $varname args global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableSelectRowList: $args" } # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set tabid {} set rowlist {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} table-id {set tabid [XMLUnQuote $val]} row-list { foreach rr [XMLUnQuote $val] { lappend rowlist [expr $rr+1] } } } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdTableSelectRowList: $url $tabid $rowlist" } if {$tabid != {} && [llength $rowlist] != 0} { if [info exists samp(icat,$tabid)] { CATSelectRows $samp(icat,$tabid) samp $rowlist } } } proc SAMPRcvdCoordPointAtSky {varname} { upvar $varname args global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdCoordPointAtSky: $args" } # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set ra {} set dec {} foreach arg $args { foreach {key val} $arg { switch -- $key { ra {set ra [XMLUnQuote $val]} dec {set dec [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdCoordPointAtSky: $ra $dec" } global current if {$ra != {} && $dec != {} && [$current(frame) has wcs equatorial wcs]} { set samp(rcvd,lock) 1 PanTo $ra $dec wcs fk5 set samp(rcvd,lock) 0 } } proc SAMPRcvdClientEnvGet {msgid varname} { upvar $varname args global samp global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdClientEnvGet: $msgid $args" } # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set name {} foreach arg $args { foreach {key val} $arg { switch -- $key { name {set name [XMLUnQuote $val]} } } } if {$debug(tcl,samp)} { puts stderr "SAMPRcvdClientEnvGet: $name" } global env if {[catch {set rr $env($name)}]} { SAMPReply $msgid ERROR {} {} [lindex [split $errorInfo "\n"] 0] global errorInfo set errorInfo {} } else { SAMPReply $msgid OK $rr } } proc SAMPRcvdDS9Set {msgid varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdDS9Set: $msgid $args" } global current global samp # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set cmd {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} cmd {set cmd [XMLUnQuote $val]} } } } set fn {} InitError samp if {$url != {}} { set fn [tmpnam ds9samp {.http}] GetFileURL $url fn } CommSet $fn $cmd if {$msgid != {}} { SAMPRcvdDS9SetReply $msgid } } proc SAMPRcvdDS9SetReply {msgid} { global ds9 global icursor global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdDS9SetReply: $msgid" } global errorInfo if {$errorInfo != {} || $ds9(msg) != {}} { if {$ds9(msg) != {}} { switch $ds9(msg,level) { info - warning {SAMPReply $msgid OK $ds9(msg)} error - fatal {SAMPReply $msgid ERROR {} {} $ds9(msg)} } } else { SAMPReply $msgid ERROR {} {} [lindex [split $errorInfo "\n"] 0] } InitError samp # reset cursor set icursor(count) 0 UnsetWatchCursor } else { SAMPReply $msgid OK } } proc SAMPRcvdDS9Get {msgid varname} { upvar $varname args global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdDS9Get: $args" } global current global samp # are we locked? if {$samp(send,lock)} { if {$debug(tcl,samp)} { puts stderr "SAMP: ABORT Send locked" } return } set url {} set cmd {} foreach arg $args { foreach {key val} $arg { switch -- $key { url {set url [XMLUnQuote $val]} cmd {set cmd [XMLUnQuote $val]} } } } set fn [tmpnam ds9samp {}] InitError samp CommGet SAMPRcvdDS9GetReply $msgid $cmd $fn } proc SAMPRcvdDS9GetReply {msgid msg {fn {}}} { global ds9 global icursor global debug if {$debug(tcl,samp)} { puts stderr "SAMPRcvdDS9GetReply: $msgid $msg $fn" } global errorInfo if {$errorInfo != {} || $ds9(msg) != {}} { if {$ds9(msg) != {}} { switch $ds9(msg,level) { info - warning {SAMPReply $msgid OK $ds9(msg)} error - fatal {SAMPReply $msgid ERROR {} {} $ds9(msg)} } } else { SAMPReply $msgid ERROR {} {} [lindex [split $errorInfo "\n"] 0] } InitError samp # reset cursor set icursor(count) 0 UnsetWatchCursor } else { # be sure to white space any newlines, backslashes, and trim set value [string trim [string map {\n { } \\ {}} $msg]] # create url set url {} if {$fn != {}} { set url "file://localhost/$fn" } SAMPReply $msgid OK $value $url } } proc SAMPDelTmpFiles {} { global ds9 # delete any previous files foreach fn [glob -directory $ds9(tmpdir) -nocomplain {ds9samp*}] { catch {file delete -force "$fn"} } } # Cmds proc ProcessSAMPCmd {varname iname} { upvar $varname var upvar $iname i global samp global ds9 global env # we need to be realized ProcessRealizeDS9 SAMPUpdate switch -- [string tolower [lindex $var $i]] { send { incr i switch -- [string tolower [lindex $var $i]] { image { incr i set name [string tolower [lindex $var $i]] if [info exists samp] { foreach arg $samp(apps,image) { foreach {key val} $arg { if {[string tolower $val] == $name} { SAMPSendImageLoadFits $key break } } } } else { Error [msgcat::mc {SAMP: not connected}] } } table { incr i set name [string tolower [lindex $var $i]] if [info exists samp] { foreach arg $samp(apps,table) { foreach {key val} $arg { if {[string tolower $val] == $name} { SAMPSendTableLoadFits $key break } } } } else { Error [msgcat::mc {SAMP: not connected}] } } default { set name [string tolower [lindex $var $i]] if [info exists samp] { foreach arg $samp(apps,image) { foreach {key val} $arg { if {[string tolower $val] == $name} { SAMPSendImageLoadFits $key break } } } } else { Error [msgcat::mc {SAMP: not connected}] } } } } broadcast { incr i switch -- [string tolower [lindex $var $i]] { image {SAMPSendImageLoadFits {}} table {SAMPSendTableLoadFits {}} default { incr i -1 SAMPSendImageLoadFits {} } } } default { if {[FromYesNo [lindex $var $i]]} { SAMPConnect } else { SAMPDisconnect } } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.macosxtiger���������������������������������������������������������������������������0000644�0001750�0001750�00000000145�11260736452�014275� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxtiger ZCAT = gzcat CODESIGN = echo FILTERCOMPILER = pcc-i386-tiger.tar.gz ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/macosx/������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012362� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/macosx/macosxlib.C�������������������������������������������������������������������������0000644�0001750�0001750�00000006466�11700667477�014515� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <limits.h> #include "tkmacosx.h" #include "macosxlib.h" void macosxBegin() { if (tkmacosx) tkmacosx->begin(); } void macosxEnd() { if (tkmacosx) tkmacosx->end(); } void macosxColor(XColor* clr) { if (clr) { float red = clr->red/float(USHRT_MAX); float green = clr->green/float(USHRT_MAX); float blue = clr->blue/float(USHRT_MAX); if (tkmacosx) tkmacosx->color(red,green,blue); } } void macosxWidth(float ww) { if (tkmacosx) tkmacosx->width(ww); } void macosxDash(float* d, int n) { if (tkmacosx) tkmacosx->dash(d,n); } void macosxFont(const char* f, float s) { if (tkmacosx) tkmacosx->font(f,s); } void macosxClip(Vector v, Vector s) { if (tkmacosx) { Vector vv1 = v*tkmacosx->getCanvasToPage(); Vector vv2 = (v+s)*tkmacosx->getCanvasToPage(); Vector ss = vv2-vv1; tkmacosx->clip(vv1[0],vv1[1],ss[0],ss[1]); } } void macosxDrawText(Vector v, float ang, const char* text) { if (tkmacosx) { Vector vv = v*tkmacosx->getCanvasToPage(); tkmacosx->drawText(vv[0], vv[1], ang, text); } } void macosxDrawLine(Vector v0, Vector v1) { if (tkmacosx) { Vector vv0 = v0*tkmacosx->getCanvasToPage(); Vector vv1 = v1*tkmacosx->getCanvasToPage(); int n = 2; float x[2]; float y[2]; x[0] = vv0[0]; y[0] = vv0[1]; x[1] = vv1[0]; y[1] = vv1[1]; tkmacosx->drawLines(x,y,n); } } void macosxDrawLines(Vector* v, int n) { if (tkmacosx) { float xx[n]; float yy[n]; for(int ii=0; ii<n; ii++) { Vector vv = v[ii]*tkmacosx->getCanvasToPage(); xx[ii] = vv[0]; yy[ii] = vv[1]; } tkmacosx->drawLines(xx,yy,n); } } void macosxDrawRect(Vector v, Vector s) { if (tkmacosx) { Vector vv1 = v*tkmacosx->getCanvasToPage(); tkmacosx->drawRect(vv1[0], vv1[1], s[0], s[1]); } } void macosxDrawArc(Vector v, float rad, float ang1, float ang2) { if (tkmacosx) { Vector vv = v*tkmacosx->getCanvasToPage(); tkmacosx->drawArc(vv[0], vv[1], rad, ang1, ang2); } } void macosxDrawCurve(Vector v0, Vector t0, Vector t1, Vector v1) { if (tkmacosx) { Vector vv0 = v0*tkmacosx->getCanvasToPage(); Vector tt0 = t0*tkmacosx->getCanvasToPage(); Vector tt1 = t1*tkmacosx->getCanvasToPage(); Vector vv1 = v1*tkmacosx->getCanvasToPage(); tkmacosx->drawCurve(vv0[0], vv0[1], tt0[0], tt0[1], tt1[0], tt1[1], vv1[0], vv1[1]); } } void macosxFillPolygon(Vector* v, int n) { if (tkmacosx) { float xx[n]; float yy[n]; for(int ii=0; ii<n; ii++) { Vector vv = v[ii]*tkmacosx->getCanvasToPage(); xx[ii] = vv[0]; yy[ii] = vv[1]; } tkmacosx->fillPolygon(xx,yy,n); } } void macosxBitmapCreate(void* img, int width, int height, const Vector& v, const Vector& s) { if (tkmacosx) { Vector vv1 = v*tkmacosx->getCanvasToPage(); Vector vv2 = (v+s)*tkmacosx->getCanvasToPage(); Vector ss = vv2-vv1; tkmacosx->bitmapCreate(img, width, height, vv1[0], vv1[1], ss[0], ss[1]); } } void macosxGetMasks(unsigned long* red, unsigned long* green, unsigned long* blue, unsigned long* alpha) { if (tkmacosx) tkmacosx->getMasks(red,green,blue,alpha); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/macosx/Makefile����������������������������������������������������������������������������0000644�0001750�0001750�00000001203�11516404165�014034� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include include ../make.pkgs CXXFLAGS = $(CXXOPT) -I../include -I../saotk/vector \ -I../$(TKDIR)/generic -I../$(TKDIR)/win \ -I$(X11INCLUDE) SRC = tkmacosx.C \ macosxlib.C \ xxlib.C \ OBJS = $(SRC:%.C=%.o) INCLS = macosxlib.h \ xxlib.h LIB = libxxlib.a all : $(LIB) install : all cp $(INCLS) ../include/. cp $(LIB) ../lib/. $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.so *.a FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/macosx/tkmacosx.C��������������������������������������������������������������������������0000644�0001750�0001750�00000047707�11700667477�014370� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> using namespace std; #include <string.h> #include "tkmacosx.h" #include <tkMacOSX.h> #include <tkMacOSXInt.h> extern "C" { int Tkmacosx_Init(Tcl_Interp* interp); int TkmacosxCmd(ClientData data, Tcl_Interp *interp, int argc, const char* argv[]); } TkMacosx* tkmacosx=NULL; int Tkmacosx_Init(Tcl_Interp* interp) { // Define Package Name if (Tcl_PkgProvide(interp, "tkmacosx", "1.0") == TCL_ERROR) return TCL_ERROR; // Commands Tcl_CreateCommand(interp, "macosx", TkmacosxCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); tkmacosx = new TkMacosx(interp); if (tkmacosx) return TCL_OK; else return TCL_ERROR; } int TkmacosxCmd(ClientData data,Tcl_Interp *interp,int argc,const char* argv[]) { if (argc>=2) { if (!strncmp(argv[1], "pm", 2)) return tkmacosx->pm(argc, argv); if (!strncmp(argv[1], "locale", 2)) return tkmacosx->locale(argc, argv); else { Tcl_AppendResult(interp, "tkmacosx: unknown command: ", argv[1], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkmacosx ?pm?locale?", NULL); return TCL_ERROR; } } TkMacosx::TkMacosx(Tcl_Interp* intp) { interp = intp; showDialog = 0; status = noErr; pageFormat = kPMNoPageFormat; printSettings = kPMNoPrintSettings; printSession = NULL; context = NULL; } TkMacosx::~TkMacosx() { if (pageFormat != kPMNoPageFormat) PMRelease(pageFormat); if (printSettings != kPMNoPrintSettings) PMRelease(printSettings); } // Locale int TkMacosx::locale(int argc, const char* argv[]) { CFPropertyListRef preferences = CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication); if (preferences && CFGetTypeID(preferences) == CFArrayGetTypeID()) { CFArrayRef prefArray = (CFArrayRef)preferences; int nn = CFArrayGetCount (prefArray); char buf[256]; for (int ii=0; ii<nn; ii++) { CFTypeRef element = CFArrayGetValueAtIndex (prefArray, ii); if (element && CFGetTypeID(element) == CFStringGetTypeID() && CFStringGetCString ((CFStringRef)element, buf, sizeof(buf), kCFStringEncodingASCII)); Tcl_AppendResult(interp, buf, " ", NULL); } CFRelease(preferences); } return TCL_OK; } // Image Print Mangager int TkMacosx::pm(int argc, const char* argv[]) { if (argc >= 3) { if (!strncmp(argv[2], "print", 3)) return tkmacosx->pmPrint(argc, argv); else if (!strncmp(argv[2], "pagesetup", 3)) return tkmacosx->pmPageSetup(); else { Tcl_AppendResult(interp, "tkmacosx pm: unknown command: ", argv[2], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkmacosx pm ?print?pagesetup?", NULL); return TCL_ERROR; } return TCL_OK; } int TkMacosx::pmPrint(int argc, const char* argv[]) { if (argc >= 4) { if (!strncmp(argv[3], "begin", 3)) return tkmacosx->pmPrintBegin(argc, argv); else if (!strncmp(argv[3], "end", 3)) return tkmacosx->pmPrintEnd(); else if (!strncmp(argv[3], "text", 3)) return tkmacosx->pmPrintText(argc, argv); else { Tcl_AppendResult(interp, "tkmacosx pm print: unknown command: ", argv[2], NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "usage: tkmacosx pm print: ?begin?end?text?", NULL); return TCL_ERROR; } return TCL_OK; } int TkMacosx::pmPrintBegin(int argc, const char* argv[]) { // canvas width and height double width =0; double height =0; if (argc >= 7) { string w(argv[4]); istringstream ww(w); ww >> width; string h(argv[5]); istringstream hh(h); hh >> height; if (width <=0 || height <=0) { Tcl_AppendResult(interp, "Invalid width or height.", NULL); return TCL_ERROR; } if (!strncmp(argv[6], "yes", 2)) showDialog = 1; else if (!strncmp(argv[6], "no", 2)) showDialog = 0; } else { Tcl_AppendResult(interp, "usage: tkmacosx pm print begin: ?width height yes|no?", NULL); return TCL_ERROR; } Vector canvas(width,height); // print session status = PMCreateSession(&printSession); if (status != noErr) goto error; // pagesetup if (pageFormat == kPMNoPageFormat) { status = PMCreatePageFormat(&pageFormat); if (status != noErr) goto error; if (pageFormat != kPMNoPageFormat) { status = PMSessionDefaultPageFormat(printSession, pageFormat); if (status != noErr) goto error; } } else { status = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean); if (status != noErr) goto error; } status = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean); if (status != noErr) goto error; // printsettings if (printSettings == kPMNoPrintSettings) { status = PMCreatePrintSettings(&printSettings); if (status != noErr) goto error; if (printSettings != kPMNoPrintSettings) { status = PMSessionDefaultPrintSettings(printSession, printSettings); if (status != noErr) goto error; } } else { status = PMSessionValidatePrintSettings(printSession, printSettings, kPMDontWantBoolean); if (status != noErr) goto error; } // range status = PMSetPageRange(printSettings, 1, 1); if (status != noErr) goto error; // dialog if (showDialog) { Boolean rr; status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &rr); if (status != noErr) goto error; // user clicked cancel if (!rr) { Tcl_AppendResult(interp, "0", NULL); goto done; } } // print loop { CFStringRef jobName = CFSTR("SAOImage DS9"); status = PMPrintSettingsSetJobName(printSettings, jobName); if (status != noErr) goto error; } // set pages { UInt32 firstPage =0; UInt32 lastPage =0; status = PMGetFirstPage(printSettings, &firstPage); if (status != noErr) goto error; status = PMGetLastPage(printSettings, &lastPage); if (status != noErr) goto error; if (1 < lastPage) lastPage = 1; status = PMSetFirstPage(printSettings, firstPage, false); if (status != noErr) goto error; status = PMSetLastPage(printSettings, lastPage, false); if (status != noErr) goto error; } status = PMSessionBeginCGDocument(printSession, printSettings, pageFormat); if (status != noErr) goto error; status = PMSessionBeginPage(printSession, pageFormat, NULL); if (status != noErr) goto error; status = PMSessionGetCGGraphicsContext(printSession, &context); if (status != noErr) goto error; { PMRect pageRect; status = PMGetAdjustedPageRect(pageFormat, &pageRect); if (status != noErr) goto error; PMRect paperRect; status = PMGetAdjustedPaperRect(pageFormat, &paperRect); if (status != noErr) goto error; double scale; status = PMGetScale(pageFormat, &scale); if (status != noErr) goto error; PMOrientation orient; status = PMGetOrientation(pageFormat, &orient); if (status != noErr) goto error; Matrix orientation; switch (orient) { case kPMPortrait: case kPMLandscape: break; case kPMReverseLandscape: orientation = FlipX(); break; } // build context transformation matrix Vector page(pageRect.right-pageRect.left,pageRect.bottom-pageRect.top); Vector paper(paperRect.right-paperRect.left, paperRect.bottom-paperRect.top); Vector origin(pageRect.left,pageRect.top); float ss; if (page[0]/canvas[0] < page[1]/canvas[1]) ss = page[0]/canvas[0]*.95; else ss = page[1]/canvas[1]*.95; Vector cp = page/2; CGContextTranslateCTM(context, cp[0], cp[1]); CGContextScaleCTM(context, ss, ss); CGContextScaleCTM(context, scale/100, scale/100); CGContextTranslateCTM(context, -cp[0], -cp[1]); // build coordinate matrix canvasToPage = Translate(-canvas/2) * FlipY() * orientation * Translate(paper/2) * Translate(origin); } // ok, we are good for go Tcl_AppendResult(interp, "1", NULL); done: return TCL_OK; error: cerr << "PM Error Code: " << status << endl; return TCL_ERROR; } int TkMacosx::pmPrintEnd() { status = PMSessionEndPage(printSession); if (status != noErr) goto error; status = PMSessionEndDocument(printSession); if (status != noErr) goto error; status = PMSessionError(printSession); if (status != noErr) goto error; done: PMRelease(printSession); printSession = NULL; return TCL_OK; error: cerr << "PM Error Code: " << status << endl; PMRelease(printSession); printSession = NULL; return TCL_ERROR; } int TkMacosx::pmPrintText(int argc, const char* argv[]) { const int fontSize =12; const float margin =36; float top; float left; float bottom; float right; UInt32 firstPage =1; UInt32 currentPage =1; UInt32 maxPage; UInt32 lastPage; int numLines =1; float xx; float yy; char* ss; char* st; char* sstr; char* estr; // text if (argc >= 5) ; else { Tcl_AppendResult(interp, "usage: tkmacosx pm print text: ?text?", NULL); return TCL_ERROR; } if (!argv[4]) goto error; // dup text sstr = new char[strlen(argv[4])+1]; estr = sstr; if (!sstr) goto error; strcpy(sstr,argv[4]); sstr[strlen(argv[4])] = '\0'; // sub ends for \n and count lines while (estr && *estr) { if (*estr == '\n') { *estr = '\0'; numLines++; } estr++; } // print session status = PMCreateSession(&printSession); if (status != noErr) goto error; // pagesetup if (pageFormat == kPMNoPageFormat) { status = PMCreatePageFormat(&pageFormat); if (status != noErr) goto error; if (pageFormat != kPMNoPageFormat) { status = PMSessionDefaultPageFormat(printSession, pageFormat); if (status != noErr) goto error; } } else { status = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean); if (status != noErr) goto error; } status = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean); if (status != noErr) goto error; // printsettings if (printSettings == kPMNoPrintSettings) { status = PMCreatePrintSettings(&printSettings); if (status != noErr) goto error; if (printSettings != kPMNoPrintSettings) { status = PMSessionDefaultPrintSettings(printSession, printSettings); if (status != noErr) goto error; } } else { status = PMSessionValidatePrintSettings(printSession, printSettings, kPMDontWantBoolean); if (status != noErr) goto error; } // calc page size PMRect pageRect; status = PMGetAdjustedPageRect(pageFormat, &pageRect); if (status != noErr) goto error; PMRect paperRect; status = PMGetAdjustedPaperRect(pageFormat, &paperRect); if (status != noErr) goto error; double scale; status = PMGetScale(pageFormat, &scale); if (status != noErr) goto error; PMOrientation orient; status = PMGetOrientation(pageFormat, &orient); if (status != noErr) goto error; top =pageRect.top + margin; left =pageRect.left + margin; bottom =pageRect.bottom - margin; right =pageRect.right - margin; // calc range maxPage = int(numLines / int((bottom-top)/fontSize) ) +1; lastPage =maxPage; status = PMSetPageRange(printSettings, firstPage, lastPage); if (status != noErr) goto error; // dialog { Boolean rr; status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &rr); if (status != noErr) goto error; // user clicked cancel if (!rr) { Tcl_AppendResult(interp, "0", NULL); goto done; } } // job name { CFStringRef jobName = CFSTR("SAOImage DS9"); status = PMSetJobNameCFString(printSettings, jobName); if (status != noErr) goto error; } // get pages status = PMGetFirstPage(printSettings, &firstPage); if (status != noErr) goto error; status = PMGetLastPage(printSettings, &lastPage); if (status != noErr) goto error; // check pages if (firstPage < 1) firstPage =1; if (firstPage > maxPage) firstPage = maxPage; if (lastPage < firstPage) lastPage = firstPage; if (lastPage > maxPage) lastPage = maxPage; // set pages status = PMSetFirstPage(printSettings, firstPage, false); if (status != noErr) goto error; status = PMSetLastPage(printSettings, lastPage, false); if (status != noErr) goto error; // start status = PMSessionBeginCGDocument(printSession, printSettings, pageFormat); if (status != noErr) goto error; // loop over pages xx = left; yy = top; ss = sstr; st = sstr; while (currentPage <= lastPage) { status = PMSessionBeginPage(printSession, pageFormat, NULL); if (status != noErr) goto error; status = PMSessionGetCGGraphicsContext(printSession, &context); if (status != noErr) goto error; // set context CGContextSelectFont(context, "Courier", fontSize, kCGEncodingMacRoman); CGContextSetRGBFillColor(context,0,0,0,1); CGContextSetTextDrawingMode (context, kCGTextFill); // matrix Vector paper(paperRect.right-paperRect.left, paperRect.bottom-paperRect.top); Matrix mm = Translate(-paper/2) * Translate(0,fontSize) * FlipY() * Translate(paper/2); // line by line while (ss < estr) { Vector vv = Vector(xx,yy) * mm; CGContextShowTextAtPoint (context, vv[0], vv[1], ss, strlen(ss)); while (*st++); ss = st; yy += fontSize; if (yy > bottom) { yy = top; break; } } status = PMSessionEndPage(printSession); if (status != noErr) goto error; currentPage++; } status = PMSessionEndDocument(printSession); if (status != noErr) goto error; status = PMSessionError(printSession); if (status != noErr) goto error; done: if (printSession) PMRelease(printSession); printSession = NULL; if (sstr) delete sstr; return TCL_OK; error: cerr << "PM Error Code: " << status << endl; if (printSession) PMRelease(printSession); printSession = NULL; if (sstr) delete sstr; return TCL_ERROR; } int TkMacosx::pmPageSetup() { // print session status = PMCreateSession(&printSession); if (status != noErr) goto error; // pagesetup if (pageFormat == kPMNoPageFormat) { status = PMCreatePageFormat(&pageFormat); if (status != noErr) goto error; if (pageFormat != kPMNoPageFormat) { status = PMSessionDefaultPageFormat(printSession, pageFormat); if (status != noErr) goto error; } } else { status = PMSessionValidatePageFormat(printSession, pageFormat, kPMDontWantBoolean); if (status != noErr) goto error; } Boolean rr; status = PMSessionPageSetupDialog(printSession, pageFormat, &rr); if (status != noErr) goto error; done: PMRelease(printSession); printSession = NULL; return TCL_OK; error: cerr << "PM Error Code: " << status << endl; PMRelease(printSession); printSession = NULL; return TCL_ERROR; } // drawing routines void TkMacosx::begin() { CGContextSaveGState(context); } void TkMacosx::end() { CGContextRestoreGState(context); } void TkMacosx::color(float red, float green, float blue) { CGContextSetRGBStrokeColor(context,red,green,blue,1); CGContextSetRGBFillColor(context,red,green,blue,1); } void TkMacosx::width(float ww) { CGContextSetLineWidth(context,ww); } void TkMacosx::dash(float* dd, int nn) { CGContextSetLineDash(context,0,dd,nn); } void TkMacosx::font(const char* font, float size) { CGContextSelectFont(context, font, size, kCGEncodingMacRoman); } void TkMacosx::clip(float x, float y, float w, float h) { CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(x,y,w,h)); CGContextClosePath(context); CGContextClip(context); } void TkMacosx::drawText(float x, float y, float angle, const char* text) { CGAffineTransform mm = CGAffineTransformMakeRotation(angle); CGContextSetTextMatrix(context, mm); CGContextSetTextDrawingMode (context, kCGTextFill); CGContextShowTextAtPoint (context, x, y, text, strlen(text)); } void TkMacosx::drawLines(float* x, float* y, int n) { CGContextBeginPath(context); CGContextMoveToPoint(context, x[0], y[0]); for (int ii=1; ii<n; ii++) CGContextAddLineToPoint(context, x[ii], y[ii]); CGContextStrokePath(context); } void TkMacosx::drawRect(float x, float y, float w, float h) { CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(x,y,w,h)); CGContextStrokePath(context); } void TkMacosx::drawArc(float x, float y, float rad, float ang1, float ang2) { CGContextBeginPath(context); CGContextAddArc(context, x, y, rad, ang1, ang2, 0); CGContextStrokePath(context); } void TkMacosx::drawCurve(float x0, float y0, float u0, float v0, float u1, float v1, float x1, float y1) { CGContextBeginPath(context); CGContextMoveToPoint(context, x0, y0); CGContextAddCurveToPoint(context, u0, v0, u1, v1, x1, y1); CGContextStrokePath(context); } void TkMacosx::fillPolygon(float* x, float* y, int n) { CGContextBeginPath(context); CGContextMoveToPoint(context, x[0], y[0]); for (int ii=1; ii<n; ii++) CGContextAddLineToPoint(context, x[ii], y[ii]); CGContextAddLineToPoint(context, x[0], y[0]); CGContextEOFillPath(context); } void TkMacosx::bitmapCreate(void* data, int width, int height, float x, float y, float w, float h) { CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGContextRef bm = CGBitmapContextCreate(data, width, height, 8, width*4, cs, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); CGImageRef img = CGBitmapContextCreateImage(bm); CGContextDrawImage(context, CGRectMake(x,y,w,h), img); if (img) CGImageRelease(img); if (bm) CGContextRelease(bm); if (cs) CGColorSpaceRelease(cs); } void TkMacosx::getMasks(unsigned long* red, unsigned long* green, unsigned long* blue, unsigned long* alpha) { // init *red = 0; *blue = 0; *green = 0; *alpha = 0; Tk_Window tkwin = Tk_MainWindow(interp); if (!tkwin) return; TkWindowPrivate* ptr = ((TkWindow *) (tkwin))->privatePtr; if (!ptr) return; GWorldPtr gw = ptr->grafPtr; if (!gw) return; PixMapHandle ph = GetGWorldPixMap(gw); if (!ph) return; PixMap* pm = *ph; switch (pm->pixelFormat) { case k16BE555PixelFormat: // 0x10 *red = 0x00007C00; *green = 0x000003E0; *blue = 0x0000001F; *alpha = 0x00000000; return; case k16LE555PixelFormat: // 'L555' *red = 0x00007C00; *green = 0x000003E0; *blue = 0x0000001F; *alpha = 0x00000000; return; case k16BE565PixelFormat: // 'B565' *red = 0x0000F800; *green = 0x000007E0; *blue = 0x0000001F; *alpha = 0x00000000; return; case k16LE565PixelFormat: // 'L565' *red = 0x0000F800; *green = 0x000007E0; *blue = 0x0000001F; *alpha = 0x00000000; return; case k24RGBPixelFormat: // 0x18 *red = 0x00FF0000; *green = 0x0000FF00; *blue = 0x000000FF; *alpha = 0x00000000; return; case k24BGRPixelFormat: // '24BG' *red = 0x00FF0000; *green = 0x0000FF00; *blue = 0x000000FF; *alpha = 0x00000000; return; case k32ARGBPixelFormat: // 0x20 *alpha = 0xFF000000; *red = 0x00FF0000; *green = 0x0000FF00; *blue = 0x000000FF; return; case k32BGRAPixelFormat: // 'BGRA' *alpha = 0xFF000000; *red = 0x00FF0000; *green = 0x0000FF00; *blue = 0x000000FF; return; case k32ABGRPixelFormat: // 'ABGR' *red = 0x000000FF; *green = 0x0000FF00; *blue = 0x00FF0000; *alpha = 0xFF000000; return; case k32RGBAPixelFormat: // 'RGBA' *red = 0x000000FF; *green = 0x0000FF00; *blue = 0x00FF0000; *alpha = 0xFF000000; return; } } ���������������������������������������������������������./saods9/macosx/tkmacosx.h��������������������������������������������������������������������������0000644�0001750�0001750�00000002777�11700667477�014433� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __tkmacosx_h__ #define __tkmacosx_h__ #include <tk.h> #include <Carbon/Carbon.h> #include "vector.h" class TkMacosx { private: Tcl_Interp* interp; int showDialog; OSStatus status; PMPageFormat pageFormat; PMPrintSettings printSettings; PMPrintSession printSession; CGContextRef context; Matrix canvasToPage; int pmPrint(int, const char**); int pmPrintBegin(int, const char**); int pmPrintEnd(); int pmPrintText(int, const char**); int pmPageSetup(); public: TkMacosx(Tcl_Interp*); ~TkMacosx(); int pm(int, const char**); int locale(int, const char**); const Matrix& getCanvasToPage() {return canvasToPage;} void begin(); void end(); void color(float,float,float); void width(float); void dash(float*,int); void font(const char*, float); void clip(float, float, float, float); void drawText(float, float, float, const char*); void drawLines(float*, float*, int); void drawRect(float, float, float, float); void drawArc(float, float, float, float, float); void drawCurve(float, float, float, float, float, float, float, float); void fillPolygon(float*, float*, int); void bitmapCreate(void*, int, int, float, float, float, float); void getMasks(unsigned long* red, unsigned long* green, unsigned long* blue, unsigned long* alpha); }; extern TkMacosx* tkmacosx; #endif �./saods9/macosx/macosxlib.h�������������������������������������������������������������������������0000644�0001750�0001750�00000001607�11700667477�014552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __macosxlib_h__ #define __macosxlib_h__ #include "vector.h" void macosxBegin(); void macosxEnd(); void macosxColor(XColor*); void macosxWidth(float); void macosxDash(float*,int); void macosxFont(const char*, float); void macosxClip(Vector, Vector); void macosxDrawText(Vector, float, const char*); void macosxDrawLine(Vector, Vector); void macosxDrawLines(Vector*, int); void macosxDrawRect(Vector, Vector); void macosxDrawArc(Vector, float, float, float); void macosxDrawCurve(Vector, Vector, Vector, Vector); void macosxFillPolygon(Vector*, int); void macosxBitmapCreate(void*, int, int, const Vector&, const Vector&); void macosxGetMasks(unsigned long* red, unsigned long* green, unsigned long* blue); #endif �������������������������������������������������������������������������������������������������������������������������./saods9/macosx/xxlib.C�����������������������������������������������������������������������������0000644�0001750�0001750�00000022500�11700667477�013645� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include <iostream> #include <sstream> #include <iomanip> using namespace std; #include <tcl.h> #include <tk.h> #include <Xlib.h> #include <tkMacOSX.h> #include <tkMacOSXInt.h> #include <tkMacOSXFont.h> #include <tkMacOSXPrivate.h> #include "vector.h" #define RGBFLOATRED(c) ((c).red / 65535.0) #define RGBFLOATGREEN(c) ((c).green / 65535.0) #define RGBFLOATBLUE(c) ((c).blue / 65535.0) char* XImageData(XImage* ximage) { GWorldPtr gw = TkMacOSXGetDrawablePort((Pixmap)(ximage->obdata)); PixMapHandle ph = GetGWorldPixMap(gw); PixMap* pm = *ph; return GetPixBaseAddr(ph); } void DrawRotString(Display* display, Drawable drawable, GC gc, Tk_Font font, double angle, const Vector& v, const char* text, Widget* parent) { MacDrawable* macWin = (MacDrawable*)drawable; TkMacOSXDrawingContext dc; TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc); // undo the xform in TkMacOSXSetupDrawingContext CGContextConcatCTM(dc.context, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, dc.portBounds.bottom - dc.portBounds.top)); CGAffineTransform mm = CGAffineTransformMakeRotation(angle); CGContextSetTextMatrix(dc.context, mm); // map to window space Vector center = Vector((dc.portBounds.right-dc.portBounds.left)/2., (dc.portBounds.bottom-dc.portBounds.top)/2.); Vector vv = v * Translate(-center) * Translate(macWin->xOff, macWin->yOff) * FlipY() * Translate(center); // draw it TkFont* fontPtr = (TkFont*)font; Tcl_DString ds; Tcl_DStringInit(&ds); int size = Tk_PostscriptFontName(font, &ds); CGContextSelectFont(dc.context, Tcl_DStringValue(&ds), size, kCGEncodingMacRoman); Tcl_DStringFree(&ds); CGContextShowTextAtPoint (dc.context, vv[0], vv[1], text, strlen(text)); // done TkMacOSXRestoreDrawingContext(&dc); } extern "C" { void XDrawString(Display* display, Drawable drawable, GC gc, int x, int y, _Xconst char* str, int length) { DrawRotString(display, drawable, gc, (Tk_Font)gc->font, 0, Vector(x,y), str); //Tk_DrawChars(display, drawable, gc, (Tk_Font)gc->font, str, length, x, y); } // Pixmap Suite Pixmap XCreatePixmap(Display* display, Drawable drawable, unsigned int width, unsigned int height, unsigned int depth) { Tk_GetPixmap(display, drawable, width, height, depth); } // XImage Suite XImage* XXCreateImage(Display* display, Visual* visual, unsigned int depth, int format, int offset, char* data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line) { XImage* ximage = XCreateImage(display, visual, depth, format, offset, data, width, height, bitmap_pad, bytes_per_line); GWorldPtr gw = (GWorldPtr)data; PixMapHandle ph = GetGWorldPixMap(gw); PixMap* pm = *ph; // now correct it ximage->bytes_per_line = (pm->rowBytes & 0x3fff); switch (depth) { case 1: ximage->bits_per_pixel = 1; ximage->bitmap_unit = 8; ximage->bitmap_pad = 1; break; case 8: ximage->bits_per_pixel = 8; ximage->bitmap_unit = 8; ximage->bitmap_pad = 8; break; case 15: ximage->bits_per_pixel = 16; ximage->bitmap_unit = 32; ximage->bitmap_pad = 32; break; case 16: ximage->bits_per_pixel = 16; ximage->bitmap_unit = 32; ximage->bitmap_pad = 32; break; case 24: ximage->bits_per_pixel = 24; ximage->bitmap_unit = 32; ximage->bitmap_pad = 32; break; case 32: ximage->bits_per_pixel = 32; ximage->bitmap_unit = 32; ximage->bitmap_pad = 32; break; } switch (pm->pixelFormat) { case k16BE555PixelFormat: // 0x10 ximage->bitmap_bit_order = MSBFirst; ximage->byte_order = MSBFirst; break; case k16LE555PixelFormat: // 'L555' ximage->bitmap_bit_order = LSBFirst; ximage->byte_order = LSBFirst; break; case k16BE565PixelFormat: // 'B565' ximage->bitmap_bit_order = MSBFirst; ximage->byte_order = MSBFirst; break; case k16LE565PixelFormat: // 'L565' ximage->bitmap_bit_order = LSBFirst; ximage->byte_order = LSBFirst; break; case k24RGBPixelFormat: // 0x18 ximage->bitmap_bit_order = MSBFirst; ximage->byte_order = MSBFirst; break; case k24BGRPixelFormat: // '24BG' ximage->bitmap_bit_order = LSBFirst; ximage->byte_order = LSBFirst; break; case k32ARGBPixelFormat: // 0x20 ximage->bitmap_bit_order = MSBFirst; ximage->byte_order = MSBFirst; break; case k32BGRAPixelFormat: // 'BGRA' ximage->bitmap_bit_order = LSBFirst; ximage->byte_order = LSBFirst; break; case k32ABGRPixelFormat: // 'ABGR' ximage->bitmap_bit_order = MSBFirst; ximage->byte_order = MSBFirst; break; case k32RGBAPixelFormat: // 'RGBA' ximage->bitmap_bit_order = LSBFirst; ximage->byte_order = LSBFirst; break; default: cerr << "MacOSX Internal Error: XXCreateImage: pixelFormat " << hex << pm->pixelFormat << " not implemented" << endl; break; } return ximage; } XImage *XXGetImage(Display *display, Drawable drawable, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format) { if (width ==0 || height ==0) { cerr << "MacOSX Internal Error: XXGetImage: width/height is zero" << endl; return NULL; } if (format != ZPixmap) { cerr << "MacOSX Internal Error: XXGetImage: illegal format" << endl; return NULL; } if (!TkMacOSXGetDrawablePort(drawable)) { cerr << "MacOSX Internal Error: XXGetImage: bad drawable" << endl; return NULL; } // get pixmap Pixmap pixmap = Tk_GetPixmap(display, drawable, width, height, 32); if (!pixmap) { cerr << "MacOSX Internal Error: XXGetImage: bad pixmap" << endl; return NULL; } // get gc GC gc; Tk_Window win = (Tk_Window)((MacDrawable *) drawable)->winPtr; if (win) { XGCValues values; gc = Tk_GetGC(win, 0, &values); } else gc = XCreateGC(display, pixmap, 0, NULL); // populate pixmap XCopyArea(display, drawable, pixmap, gc, x, y, width, height, 0, 0); if (win) Tk_FreeGC(display, gc); else XFreeGC(display, gc); GWorldPtr gw = TkMacOSXGetDrawablePort(pixmap); PixMapHandle ph = GetGWorldPixMap(gw); PixMap* pm = *ph; int depth = pm->pixelSize; int bitmap_pad = depth; // will be reset int bytes_per_line = width; // will be reset XImage* image = XXCreateImage(display, NULL, depth, format, 0, (char*)TkMacOSXGetDrawablePort(pixmap), width, height, bitmap_pad, bytes_per_line); // needed by tk image->obdata = (XPointer)pixmap; return image; } void XSetClipRectangles(Display* display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle* r, int n, int ordering) { // clear it TkpClipMask *clip_mask = (TkpClipMask*)gc->clip_mask; if (clip_mask && clip_mask->type == TKP_CLIP_REGION) TkpReleaseRegion(clip_mask->value.region); // new region TkRegion clipRgn = TkCreateRegion(); // clip origin not used, but set anyways gc->clip_x_origin = clip_x_origin; gc->clip_y_origin = clip_y_origin; for (int ii =0; ii<n; ii++) TkUnionRectWithRegion(&r[ii], clipRgn, clipRgn); // and set it TkSetRegion(display, gc, clipRgn); } Bool XXQueryPointer(Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, unsigned int* mask_return) { XQueryPointer(display, w, root_return, child_return, root_x_return, root_y_return, win_x_return, win_y_return, mask_return); // flag root for XXWarpPointer *root_return = 1; *child_return = NULL; } void XXWarpPointer(Display* display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y) { // we have a special mode, root=1, from XXQueryPointer CGPoint pt; if (dest_w == None) { Point ppt; GetGlobalMouse(&ppt); pt.x = dest_x+ppt.h; pt.y = dest_y+ppt.v; } else if (dest_w == 1) { pt.x = dest_x; pt.y = dest_y; } else { Point ppt; MacDrawable* macPtr = (MacDrawable*)dest_w; ppt.h = dest_x+macPtr->xOff; ppt.v = dest_y+macPtr->yOff; CGrafPtr port = TkMacOSXGetDrawablePort(dest_w); QDLocalToGlobalPoint(port, &ppt); pt.x = ppt.h; pt.y = ppt.v; } // we can't use the following, we want a mouse event generated. // CGWarpMouseCursorPosition(pt); // and we can't use the following, its buggy as all get out // CGPostMouseEvent(pt, true, 1, false); CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); CGEventRef ev = CGEventCreateMouseEvent(src,kCGEventMouseMoved,pt,kCGMouseButtonLeft); // bug in tiger, reset event type CGEventSetType(ev,kCGEventMouseMoved); CGEventPost(kCGSessionEventTap,ev); CFRelease(ev); CFRelease(src); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/macosx/xxlib.h�����������������������������������������������������������������������������0000644�0001750�0001750�00000003067�11700667477�013721� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __xxlib_h__ #define __xxlib_h__ #include <tcl.h> #include <tk.h> // direct X11 to Tk char* XImageData(XImage* ximage); extern "C" { // available in blt/src/bltMacOSX.c void XPutImage(Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); void XFreePixmap(Display*, Pixmap); // New Routines void XDrawString(Display* display, Drawable drawable, GC gc, int x, int y, _Xconst char* str, int length); Pixmap XCreatePixmap(Display* display, Drawable drawable, unsigned int width, unsigned int height, unsigned int depth); void XSetClipRectangles(Display* display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle* r, int n, int ordering); // Redefined Routines XImage *XXGetImage(Display *display, Drawable drawable, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format); Bool XXQueryPointer(Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, unsigned int* mask_return); void XXWarpPointer(Display* display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinx86lion�������������������������������������������������������������������������0000644�0001750�0001750�00000001160�12077031450�014453� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# make sure installed: PKG_CONFIG for Xft, see notes OS = unix ARCH = darwinx86lion X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -mmacosx-version-min=10.7 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz JOBS = 4 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/��������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�012041� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/zh.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000106476�12132042644�013221� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset zh {2D} ::msgcat::mcset zh {3D} ::msgcat::mcset zh {A postscript generation error has occurred} ::msgcat::mcset zh {AIP} ::msgcat::mcset zh {Abort} ::msgcat::mcset zh {About SAOImage DS9} ::msgcat::mcset zh {About} [encoding convertfrom big5 "\xC3\xF6 \xA9\xF3"] ::msgcat::mcset zh {Acknowledgment} ::msgcat::mcset zh {Add} ::msgcat::mcset zh {Advanced} ::msgcat::mcset zh {Align} [encoding convertfrom big5 "\xB9\xEF \xBB\xF4 \xA4\xE8 \xA6\xEC"] ::msgcat::mcset zh {All Columns} ::msgcat::mcset zh {All Rows} ::msgcat::mcset zh {All} ::msgcat::mcset zh {Always save files during Backup} ::msgcat::mcset zh {Amplifier} ::msgcat::mcset zh {An error has occured while updating VO server list} ::msgcat::mcset zh {An error has occurred during backup} ::msgcat::mcset zh {An error has occurred during restore} ::msgcat::mcset zh {An error has occurred invoking the Analysis task} ::msgcat::mcset zh {An error has occurred while creating image.} ::msgcat::mcset zh {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset zh {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset zh {An error has occurred while printing} ::msgcat::mcset zh {An error has occurred while reading image.} ::msgcat::mcset zh {An error has occurred while saving} ::msgcat::mcset zh {An error has occurred while writing image.} ::msgcat::mcset zh {An internal error has been detected} ::msgcat::mcset zh {Analysis Command Log} ::msgcat::mcset zh {Analysis Commands} ::msgcat::mcset zh {Analysis File} ::msgcat::mcset zh {Analysis Log} ::msgcat::mcset zh {Analysis} [encoding convertfrom big5 "\xA4\xC0 \xAA\x52"] ::msgcat::mcset zh {Angle Complement} ::msgcat::mcset zh {Angles} ::msgcat::mcset zh {Angle} ::msgcat::mcset zh {Annuli} ::msgcat::mcset zh {Annulus} [encoding convertfrom big5 "\xB6\xEA \xB0\xE9"] ::msgcat::mcset zh {Apply} ::msgcat::mcset zh {ArcMin} ::msgcat::mcset zh {ArcSec} ::msgcat::mcset zh {Architecture} ::msgcat::mcset zh {Archives} [encoding convertfrom big5 "\xBD\x75 \xA4\x57 \xB8\xEA \xAE\xC6"] ::msgcat::mcset zh {Array} ::msgcat::mcset zh {Arrow} ::msgcat::mcset zh {Astronomy} ::msgcat::mcset zh {At Startup} ::msgcat::mcset zh {At least 2 different catalogs are required} ::msgcat::mcset zh {Auto Centroid} ::msgcat::mcset zh {Auto Plot 2D} ::msgcat::mcset zh {Auto Plot 3D} ::msgcat::mcset zh {Auto Plot} ::msgcat::mcset zh {Autoload FITS Regions} ::msgcat::mcset zh {Autoload} ::msgcat::mcset zh {Automatic} ::msgcat::mcset zh {Average} ::msgcat::mcset zh {Axes Number} ::msgcat::mcset zh {Axes Title} ::msgcat::mcset zh {Axes} ::msgcat::mcset zh {Axis Label} ::msgcat::mcset zh {Axis Length} ::msgcat::mcset zh {Axis Numbers} ::msgcat::mcset zh {Axis} ::msgcat::mcset zh {Azimuth} ::msgcat::mcset zh {Background Color} ::msgcat::mcset zh {Background} ::msgcat::mcset zh {Backup} ::msgcat::mcset zh {Back} ::msgcat::mcset zh {Bar Plot Tool} ::msgcat::mcset zh {Bias} ::msgcat::mcset zh {Bin 3rd Column} ::msgcat::mcset zh {Bin Center} ::msgcat::mcset zh {Bin Columns} ::msgcat::mcset zh {Bin Filter} ::msgcat::mcset zh {Binning Parameters} ::msgcat::mcset zh {Bin} ::msgcat::mcset zh {Black} [encoding convertfrom big5 "\xB6\xC2 \xA6\xE2"] ::msgcat::mcset zh {Blank/Inf/NaN Color} ::msgcat::mcset zh {Blink Frames} ::msgcat::mcset zh {Blink Interval} ::msgcat::mcset zh {Blink} ::msgcat::mcset zh {Block In} ::msgcat::mcset zh {Block Out} ::msgcat::mcset zh {Block to Fit Frame} ::msgcat::mcset zh {Block} ::msgcat::mcset zh {Blue} ::msgcat::mcset zh {Bold} ::msgcat::mcset zh {Border} ::msgcat::mcset zh {Box Annulus} [encoding convertfrom big5 "\xA4\xE8 \xA7\xCE \xB0\xE9"] ::msgcat::mcset zh {Box Panda} ::msgcat::mcset zh {BoxCircle} ::msgcat::mcset zh {Boxcar} ::msgcat::mcset zh {Box} [encoding convertfrom big5 "\xA4\xE8 \xA7\xCE"] ::msgcat::mcset zh {Broadcast} ::msgcat::mcset zh {Browser} ::msgcat::mcset zh {Browse} ::msgcat::mcset zh {Buffer} ::msgcat::mcset zh {Buttonbar} ::msgcat::mcset zh {Buttons} [encoding convertfrom big5 "\xAB\xF6 \xB6\x73 \xA6\x43"] ::msgcat::mcset zh {Bytes} ::msgcat::mcset zh {CMYK} ::msgcat::mcset zh {Can Delete} [encoding convertfrom big5 "\xA5\x69 \xA5\x48 \xA7\x52 \xB0\xA3"] ::msgcat::mcset zh {Can Edit} [encoding convertfrom big5 "\xA5\x69 \xA5\x48 \xBD\x73 \xBF\xE8"] ::msgcat::mcset zh {Can Move} [encoding convertfrom big5 "\xA5\x69 \xA5\x48 \xB2\xBE \xB0\xCA"] ::msgcat::mcset zh {Can Rotate} [encoding convertfrom big5 "\xA5\x69 \xA5\x48 \xB1\xDB \xC2\xE0"] ::msgcat::mcset zh {Cancel} ::msgcat::mcset zh {Catalog Server} ::msgcat::mcset zh {Catalog Tool} ::msgcat::mcset zh {Catalogs} [encoding convertfrom big5 "\xB8\xEA \xAE\xC6 \xAA\xED"] ::msgcat::mcset zh {Catalog} ::msgcat::mcset zh {Center Image} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xB8\x6D \xA4\xA4"] ::msgcat::mcset zh {Center Non-modal Dialogs} ::msgcat::mcset zh {Center} ::msgcat::mcset zh {Centroid Parameters} [encoding convertfrom big5 "\xA4\xA4 \xA4\xDF \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Centroid} ::msgcat::mcset zh {Circle} [encoding convertfrom big5 "\xB6\xEA \xA7\xCE"] ::msgcat::mcset zh {Clear All} ::msgcat::mcset zh {Clear Analysis Commands} ::msgcat::mcset zh {Clear Cache} ::msgcat::mcset zh {Clear Data} ::msgcat::mcset zh {Clear External Analysis Commands?} ::msgcat::mcset zh {Clear Filter} ::msgcat::mcset zh {Clear Frame} [encoding convertfrom big5 "\xB2\x4D \xB0\xA3 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Clear Preferences?} ::msgcat::mcset zh {Clear Preferences} ::msgcat::mcset zh {Clear} [encoding convertfrom big5 "\xB2\x4D \xB0\xA3"] ::msgcat::mcset zh {Click to Center} ::msgcat::mcset zh {Close} ::msgcat::mcset zh {Colorbar Size} ::msgcat::mcset zh {Colorbar} [encoding convertfrom big5 "\xA6\xE2 \xB6\xA5 \xB9\xCF \xA8\xD2"] ::msgcat::mcset zh {Colormap Parameters} [encoding convertfrom big5 "\xC3\x43 \xA6\xE2 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Colormap} ::msgcat::mcset zh {Color} [encoding convertfrom big5 "\xC3\x43 \xA6\xE2"] ::msgcat::mcset zh {Columns} [encoding convertfrom big5 "\xA4\xE8 \xA6\xEC"] ::msgcat::mcset zh {Column} ::msgcat::mcset zh {Command} ::msgcat::mcset zh {Compass} ::msgcat::mcset zh {Composite Region} [encoding convertfrom big5 "\xB2\x56 \xA6\x58 \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Composite} ::msgcat::mcset zh {Compression} ::msgcat::mcset zh {Configure} ::msgcat::mcset zh {Connect Directly} ::msgcat::mcset zh {Connect SAMP} ::msgcat::mcset zh {Connect Using Web Proxy} ::msgcat::mcset zh {Connect} ::msgcat::mcset zh {Console} ::msgcat::mcset zh {Contour Parameters} [encoding convertfrom big5 "\xB5\xA5 \xAD\xC8 \xBD\x75 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Contours} [encoding convertfrom big5 "\xB5\xA5 \xAD\xC8 \xBD\x75"] ::msgcat::mcset zh {Contour} ::msgcat::mcset zh {Contrast} ::msgcat::mcset zh {Contributed} ::msgcat::mcset zh {Convert to Polygons} ::msgcat::mcset zh {Coordinate Grid Parameters} [encoding convertfrom big5 "\xAE\x79 \xBC\xD0 \xAE\xE6 \xBD\x75 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Coordinate Grid} [encoding convertfrom big5 "\xAE\x79 \xBC\xD0 \xAE\xE6 \xBD\x75"] ::msgcat::mcset zh {Coordinate System} ::msgcat::mcset zh {Coordinates} ::msgcat::mcset zh {Coordinate} ::msgcat::mcset zh {Copy Contours} ::msgcat::mcset zh {Copy to Regions} ::msgcat::mcset zh {Copy} ::msgcat::mcset zh {Create Movie} ::msgcat::mcset zh {Create New Frame on Download} ::msgcat::mcset zh {Create} [encoding convertfrom big5 "\xBB\x73 \xB3\x79"] ::msgcat::mcset zh {Crop Parameters} ::msgcat::mcset zh {Crop} ::msgcat::mcset zh {Crosshair To} ::msgcat::mcset zh {Crosshair} ::msgcat::mcset zh {Cross} ::msgcat::mcset zh {Cube} ::msgcat::mcset zh {Current Frame} ::msgcat::mcset zh {Current Range} ::msgcat::mcset zh {Current} ::msgcat::mcset zh {Cursor} ::msgcat::mcset zh {Cut} ::msgcat::mcset zh {Cyan} [encoding convertfrom big5 "\xAB\x43 \xA6\xE2"] ::msgcat::mcset zh {DPI} ::msgcat::mcset zh {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset zh {DS9 has detected a newer version of a preferences file and therefore will not process this file.} ::msgcat::mcset zh {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset zh {DS9 has detected an older preferences file, do you wish to update?} ::msgcat::mcset zh {DS9 will complete the initialization process} ::msgcat::mcset zh {Dash} [encoding convertfrom big5 "\xB5\xEA \xBD\x75"] ::msgcat::mcset zh {Data Format} ::msgcat::mcset zh {Dataset} ::msgcat::mcset zh {Data} ::msgcat::mcset zh {Decrease} ::msgcat::mcset zh {Default All Files} ::msgcat::mcset zh {Default Format} ::msgcat::mcset zh {Default Length} ::msgcat::mcset zh {Default} ::msgcat::mcset zh {Degrees} ::msgcat::mcset zh {Delete All Frames?} ::msgcat::mcset zh {Delete All Frames} [encoding convertfrom big5 "\xA7\x52 \xB0\xA3 \xA9\xD2 \xA6\xB3 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Delete All Groups?} ::msgcat::mcset zh {Delete All Groups} ::msgcat::mcset zh {Delete All Regions?} ::msgcat::mcset zh {Delete All Regions} [encoding convertfrom big5 "\xA7\x52 \xB0\xA3 \xA5\xEF \xB3\xA1 \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Delete All} ::msgcat::mcset zh {Delete Color Tags} ::msgcat::mcset zh {Delete Frame} [encoding convertfrom big5 "\xA7\x52 \xB0\xA3 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Delete Group} ::msgcat::mcset zh {Delete Selected Regions} [encoding convertfrom big5 "\xA7\x52 \xB0\xA3 \xBF\xEF \xA8\xFA \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Delete} [encoding convertfrom big5 "\xA7\x52 \xB0\xA3"] ::msgcat::mcset zh {Depth} ::msgcat::mcset zh {Detector} ::msgcat::mcset zh {Dialog Box} ::msgcat::mcset zh {Diamond} ::msgcat::mcset zh {Dimension} ::msgcat::mcset zh {Disconnect} ::msgcat::mcset zh {Discrete} ::msgcat::mcset zh {Display Header} ::msgcat::mcset zh {Display Size} ::msgcat::mcset zh {Dissolve} [encoding convertfrom big5 "\xB8\xD1 \xB4\xB2"] ::msgcat::mcset zh {Distance} ::msgcat::mcset zh {Download Colormap} ::msgcat::mcset zh {Download VOTABLE format if available} ::msgcat::mcset zh {Drag to Center} ::msgcat::mcset zh {Duplicate Data} ::msgcat::mcset zh {East} ::msgcat::mcset zh {Ecliptic} ::msgcat::mcset zh {Edit Group Name} ::msgcat::mcset zh {Edit} [encoding convertfrom big5 "\xBD\x73 \xBF\xE8"] ::msgcat::mcset zh {Element} ::msgcat::mcset zh {Elevation} ::msgcat::mcset zh {Ellipse Panda} ::msgcat::mcset zh {Ellipse} [encoding convertfrom big5 "\xBE\xF2 \xB6\xEA \xA7\xCE"] ::msgcat::mcset zh {Elliptical Annulus} [encoding convertfrom big5 "\xBE\xF2 \xB6\xEA \xB0\xE9"] ::msgcat::mcset zh {Elliptical Panda} ::msgcat::mcset zh {Enable Confirmation Dialogs} ::msgcat::mcset zh {Enable} ::msgcat::mcset zh {End} ::msgcat::mcset zh {Enter Color} ::msgcat::mcset zh {Enter Font Size} ::msgcat::mcset zh {Enter Group Name} ::msgcat::mcset zh {Enter Search Expression} ::msgcat::mcset zh {Enter URL} ::msgcat::mcset zh {Entry} ::msgcat::mcset zh {Equal Area} ::msgcat::mcset zh {Equal Distance} ::msgcat::mcset zh {Equal Spacing} ::msgcat::mcset zh {Equal Value} ::msgcat::mcset zh {Error code was returned} ::msgcat::mcset zh {Error} ::msgcat::mcset zh {Examine Frame} ::msgcat::mcset zh {Examine} [encoding convertfrom big5 "\xA9\xF1 \xA4\x6A \xC0\xCB \xB5\xF8"] ::msgcat::mcset zh {Exclude} ::msgcat::mcset zh {Executing TCL code is not enabled} ::msgcat::mcset zh {Exit} [encoding convertfrom big5 "\xC2\xF7 \xB6\x7D"] ::msgcat::mcset zh {Export Array} ::msgcat::mcset zh {Export} ::msgcat::mcset zh {Extention} ::msgcat::mcset zh {Exterior Axes} ::msgcat::mcset zh {Exterior Numerics} ::msgcat::mcset zh {FAQ} ::msgcat::mcset zh {FK4} ::msgcat::mcset zh {FK5} ::msgcat::mcset zh {Factor} ::msgcat::mcset zh {File not Found or Unable to load FITS data MIME type} ::msgcat::mcset zh {Filename} [encoding convertfrom big5 "\xC0\xC9 \xAE\xD7 \xA6\x57 \xBA\xD9"] ::msgcat::mcset zh {File} [encoding convertfrom big5 "\xC0\xC9 \xAE\xD7"] ::msgcat::mcset zh {Fill} ::msgcat::mcset zh {Filter} ::msgcat::mcset zh {Find Next} ::msgcat::mcset zh {Find} ::msgcat::mcset zh {First Frame} [encoding convertfrom big5 "\xB3\xCC \xA4\x57 \xBC\x68 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {First} ::msgcat::mcset zh {Fits} ::msgcat::mcset zh {Fixed in Size} [encoding convertfrom big5 "\xA9\x54 \xA9\x77 \xA4\x6A \xA4\x70"] ::msgcat::mcset zh {Flip} ::msgcat::mcset zh {Font} ::msgcat::mcset zh {For more information, use --help} ::msgcat::mcset zh {Format} ::msgcat::mcset zh {Forward} ::msgcat::mcset zh {Found} ::msgcat::mcset zh {Frame Information} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1 \xB8\xEA \xB0\x54"] ::msgcat::mcset zh {Frame Parameters} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Frames} ::msgcat::mcset zh {Frame} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {From} ::msgcat::mcset zh {Front} ::msgcat::mcset zh {Full Range} ::msgcat::mcset zh {Function} ::msgcat::mcset zh {GUI Font} ::msgcat::mcset zh {Galactic} ::msgcat::mcset zh {Gap} ::msgcat::mcset zh {Gaussian} ::msgcat::mcset zh {General} ::msgcat::mcset zh {Generate} ::msgcat::mcset zh {Generating Regions} ::msgcat::mcset zh {Get Information} [encoding convertfrom big5 "\xB8\xFC \xA4\x4A \xB0\x54 \xAE\xA7"] ::msgcat::mcset zh {Global Properties} ::msgcat::mcset zh {Global} ::msgcat::mcset zh {Goto Frame} [encoding convertfrom big5 "\xA8\xEC \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Graph Horz} ::msgcat::mcset zh {Graph Vert} ::msgcat::mcset zh {Graphics} ::msgcat::mcset zh {Graphs} ::msgcat::mcset zh {Graph} ::msgcat::mcset zh {Grayscale} ::msgcat::mcset zh {Green} ::msgcat::mcset zh {Grid Gap} ::msgcat::mcset zh {Grid} ::msgcat::mcset zh {Groups} ::msgcat::mcset zh {HTTP} ::msgcat::mcset zh {Header} ::msgcat::mcset zh {Height} ::msgcat::mcset zh {Help Desk} ::msgcat::mcset zh {Help Me Choose} ::msgcat::mcset zh {Help} [encoding convertfrom big5 "\xBB\xA1 \xA9\xFA"] ::msgcat::mcset zh {Hide All} [encoding convertfrom big5 "\xC1\xF4 \xC2\xC3 \xA5\xFE \xB3\xA1"] ::msgcat::mcset zh {Highlite} ::msgcat::mcset zh {High} ::msgcat::mcset zh {Histogram Equalization} ::msgcat::mcset zh {Histogram} ::msgcat::mcset zh {Horizontal Graph} ::msgcat::mcset zh {Horizontal Layout} ::msgcat::mcset zh {Horizontal} [encoding convertfrom big5 "\xA4\xF4 \xA5\xAD"] ::msgcat::mcset zh {IAU Location Code} ::msgcat::mcset zh {ICRS} ::msgcat::mcset zh {Identification} ::msgcat::mcset zh {If} ::msgcat::mcset zh {Image Servers} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xA4\x55 \xB8\xFC"] ::msgcat::mcset zh {Image} ::msgcat::mcset zh {Import Array} ::msgcat::mcset zh {Import} ::msgcat::mcset zh {Include} ::msgcat::mcset zh {Increase} ::msgcat::mcset zh {Information Panel} [encoding convertfrom big5 "\xB8\xEA \xB0\x54 \xA6\x43"] ::msgcat::mcset zh {Information} [encoding convertfrom big5 "\xB8\xEA \xB0\x54"] ::msgcat::mcset zh {Initialize XPA} ::msgcat::mcset zh {Inner} ::msgcat::mcset zh {Instrument FOV} ::msgcat::mcset zh {Interior Axes} ::msgcat::mcset zh {Interior Numerics} ::msgcat::mcset zh {Internal Parse Error} ::msgcat::mcset zh {Interval} ::msgcat::mcset zh {Invalid Column Name} ::msgcat::mcset zh {Invalid formated multipart/mixed mime type message} ::msgcat::mcset zh {Invert Colormap} [encoding convertfrom big5 "\xA6\xE2 \xB1\x6D \xA4\xCF \xA6\x56"] ::msgcat::mcset zh {Invert Selection} [encoding convertfrom big5 "\xA4\xCF \xA6\x56 \xBF\xEF \xA8\xFA"] ::msgcat::mcset zh {Invert} ::msgcat::mcset zh {Italic} ::msgcat::mcset zh {Items Found} ::msgcat::mcset zh {Iteration} ::msgcat::mcset zh {JPEG Quality Factor} ::msgcat::mcset zh {Keep-Alive} ::msgcat::mcset zh {Kernel} ::msgcat::mcset zh {Keyboard Shortcuts} ::msgcat::mcset zh {Keyboard} ::msgcat::mcset zh {Labels} ::msgcat::mcset zh {Label} ::msgcat::mcset zh {Landscape} ::msgcat::mcset zh {Language} ::msgcat::mcset zh {Last Frame} [encoding convertfrom big5 "\xB3\xCC \xA9\xB3 \xBC\x68 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Last} ::msgcat::mcset zh {Layout Horz} ::msgcat::mcset zh {Layout Vert} ::msgcat::mcset zh {Layout} ::msgcat::mcset zh {Left} ::msgcat::mcset zh {Legal} ::msgcat::mcset zh {Length} ::msgcat::mcset zh {Letter} ::msgcat::mcset zh {Levels} ::msgcat::mcset zh {Level} ::msgcat::mcset zh {Limits} ::msgcat::mcset zh {Line Plot Tool} ::msgcat::mcset zh {Linear} [encoding convertfrom big5 "\xBD\x75 \xA9\xCA"] ::msgcat::mcset zh {Line} [encoding convertfrom big5 "\xAA\xBD \xBD\x75"] ::msgcat::mcset zh {List Data} ::msgcat::mcset zh {List Regions} [encoding convertfrom big5 "\xA6\x43 \xA5\x58 \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {List} ::msgcat::mcset zh {Load Analysis Commands} ::msgcat::mcset zh {Load Color Tags} ::msgcat::mcset zh {Load Colormap} ::msgcat::mcset zh {Load Configuration} ::msgcat::mcset zh {Load Contour Levels} ::msgcat::mcset zh {Load Contours} ::msgcat::mcset zh {Load Contrast/Bias} ::msgcat::mcset zh {Load Data} ::msgcat::mcset zh {Load Mosaic} ::msgcat::mcset zh {Load Regions} [encoding convertfrom big5 "\xB8\xFC \xA4\x4A \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Load Template} ::msgcat::mcset zh {Load into All Frames} ::msgcat::mcset zh {Load into Current Frame} ::msgcat::mcset zh {Loading Catalog} ::msgcat::mcset zh {Loading} ::msgcat::mcset zh {Load} [encoding convertfrom big5 "\xB8\xFC \xA4\x4A"] ::msgcat::mcset zh {Local} ::msgcat::mcset zh {Lock Bin} ::msgcat::mcset zh {Lock Color} ::msgcat::mcset zh {Lock Crop Amplifier} ::msgcat::mcset zh {Lock Crop Detector} ::msgcat::mcset zh {Lock Crop Image} ::msgcat::mcset zh {Lock Crop None} ::msgcat::mcset zh {Lock Crop Physical} ::msgcat::mcset zh {Lock Crop WCS} ::msgcat::mcset zh {Lock Crosshair Amplifier} ::msgcat::mcset zh {Lock Crosshair Detector} ::msgcat::mcset zh {Lock Crosshair Image} ::msgcat::mcset zh {Lock Crosshair None} ::msgcat::mcset zh {Lock Crosshair Physical} ::msgcat::mcset zh {Lock Crosshair WCS} ::msgcat::mcset zh {Lock Frame Amplifier} ::msgcat::mcset zh {Lock Frame Detector} ::msgcat::mcset zh {Lock Frame Image} ::msgcat::mcset zh {Lock Frame None} ::msgcat::mcset zh {Lock Frame Physical} ::msgcat::mcset zh {Lock Frame WCS} ::msgcat::mcset zh {Lock Scale} ::msgcat::mcset zh {Lock Slice} ::msgcat::mcset zh {Lock Smooth} ::msgcat::mcset zh {Lock} ::msgcat::mcset zh {Log Exponent} ::msgcat::mcset zh {Log} [encoding convertfrom big5 "\xB9\xEF \xBC\xC6"] ::msgcat::mcset zh {Low High} ::msgcat::mcset zh {Lower Left Back} ::msgcat::mcset zh {Lower Left Front} ::msgcat::mcset zh {Lower Right Back} ::msgcat::mcset zh {Lower Right Front} ::msgcat::mcset zh {Low} ::msgcat::mcset zh {MIP} ::msgcat::mcset zh {Magenta} [encoding convertfrom big5 "\xAC\xF5 \xB5\xB5 \xA6\xE2"] ::msgcat::mcset zh {Magnification} ::msgcat::mcset zh {Magnifier} [encoding convertfrom big5 "\xA9\xF1 \xA4\x6A \xC3\xE8 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Major} ::msgcat::mcset zh {Manual} ::msgcat::mcset zh {Mask Parameters} ::msgcat::mcset zh {Match Bin} ::msgcat::mcset zh {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset zh {Match Color} ::msgcat::mcset zh {Match Crop Amplifier} ::msgcat::mcset zh {Match Crop Detector} ::msgcat::mcset zh {Match Crop Image} ::msgcat::mcset zh {Match Crop Physical} ::msgcat::mcset zh {Match Crop WCS} ::msgcat::mcset zh {Match Crosshair Amplifier} ::msgcat::mcset zh {Match Crosshair Detector} ::msgcat::mcset zh {Match Crosshair Image} ::msgcat::mcset zh {Match Crosshair Physical} ::msgcat::mcset zh {Match Crosshair WCS} ::msgcat::mcset zh {Match Frame Amplifier} ::msgcat::mcset zh {Match Frame Detector} ::msgcat::mcset zh {Match Frame Image} ::msgcat::mcset zh {Match Frame Physical} ::msgcat::mcset zh {Match Frame WCS} ::msgcat::mcset zh {Match Scale} ::msgcat::mcset zh {Match Slice} ::msgcat::mcset zh {Match Smooth} ::msgcat::mcset zh {Match} ::msgcat::mcset zh {Math Function} ::msgcat::mcset zh {Max Rows} ::msgcat::mcset zh {Max} ::msgcat::mcset zh {Menus and Buttons} ::msgcat::mcset zh {Menu} ::msgcat::mcset zh {Message Log} ::msgcat::mcset zh {Method} ::msgcat::mcset zh {Min Max Parameters} ::msgcat::mcset zh {Min Max} ::msgcat::mcset zh {Minor} ::msgcat::mcset zh {Minutes} ::msgcat::mcset zh {Min} ::msgcat::mcset zh {Mission} ::msgcat::mcset zh {Mode} ::msgcat::mcset zh {Mosaic IRAF Segment} ::msgcat::mcset zh {Mosaic IRAF} ::msgcat::mcset zh {Mosaic WCS Segment} ::msgcat::mcset zh {Mosaic WCS} ::msgcat::mcset zh {Mosaic WFPC2} ::msgcat::mcset zh {Mosaic} ::msgcat::mcset zh {Mouse & Keyboard} ::msgcat::mcset zh {Mouse Wheel Bin} ::msgcat::mcset zh {Mouse Wheel Zoom} ::msgcat::mcset zh {Move Back} ::msgcat::mcset zh {Move First} ::msgcat::mcset zh {Move Forward} ::msgcat::mcset zh {Move Frame} [encoding convertfrom big5 "\xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1 \xB6\xB6 \xA7\xC7"] ::msgcat::mcset zh {Move Last} ::msgcat::mcset zh {Move to Back} ::msgcat::mcset zh {Move to Front} ::msgcat::mcset zh {Movie} ::msgcat::mcset zh {Multiple Extension Cube} ::msgcat::mcset zh {Multiple Extension Frames} ::msgcat::mcset zh {Multiple WCS} ::msgcat::mcset zh {NRRD} ::msgcat::mcset zh {Name Resolution} ::msgcat::mcset zh {Name Server} ::msgcat::mcset zh {Name or Designation} ::msgcat::mcset zh {Name} ::msgcat::mcset zh {Native Dialog} ::msgcat::mcset zh {Native} ::msgcat::mcset zh {New 3D} ::msgcat::mcset zh {New Features} ::msgcat::mcset zh {New Frame 3D} ::msgcat::mcset zh {New Frame RGB} ::msgcat::mcset zh {New Frame each Time} ::msgcat::mcset zh {New Frame} [encoding convertfrom big5 "\xB7\x73 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {New Group} ::msgcat::mcset zh {New RGB} ::msgcat::mcset zh {New} ::msgcat::mcset zh {Next Frame} [encoding convertfrom big5 "\xAB\xE1 \xA4\x40 \xBC\x68 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Next} ::msgcat::mcset zh {No Catalog specified} ::msgcat::mcset zh {No Items Found} ::msgcat::mcset zh {No current frame} ::msgcat::mcset zh {No data available at } ::msgcat::mcset zh {Non-zero} ::msgcat::mcset zh {None} ::msgcat::mcset zh {Normal} ::msgcat::mcset zh {North} ::msgcat::mcset zh {Not Found} ::msgcat::mcset zh {No} ::msgcat::mcset zh {Number of Samples} ::msgcat::mcset zh {Number of Threads} ::msgcat::mcset zh {Number of Ticks} ::msgcat::mcset zh {Number} ::msgcat::mcset zh {Numerics} [encoding convertfrom big5 "\xBC\xC6 \xAD\xC8"] ::msgcat::mcset zh {OK} ::msgcat::mcset zh {Object} [encoding convertfrom big5 "\xA4\xD1 \xC5\xE9 \xA6\x57 \xBA\xD9"] ::msgcat::mcset zh {Open File} ::msgcat::mcset zh {Open TCL Console} ::msgcat::mcset zh {Open URL} ::msgcat::mcset zh {Open as} ::msgcat::mcset zh {Open} [encoding convertfrom big5 "\xB6\x7D \xB1\xD2"] ::msgcat::mcset zh {Operator} ::msgcat::mcset zh {Orientation} [encoding convertfrom big5 "\xA4\xE8 \xA6\x56"] ::msgcat::mcset zh {Origin} ::msgcat::mcset zh {Oscillate} ::msgcat::mcset zh {Other Color} ::msgcat::mcset zh {Other Font Size} ::msgcat::mcset zh {Other} [encoding convertfrom big5 "\xA8\xE4 \xA5\xA6"] ::msgcat::mcset zh {Outer} ::msgcat::mcset zh {PS Page Setup} ::msgcat::mcset zh {PS Print} ::msgcat::mcset zh {Page Setup} ::msgcat::mcset zh {Page Source} ::msgcat::mcset zh {Pan To} ::msgcat::mcset zh {Pan Zoom Rotate Parameters} [encoding convertfrom big5 "\xC1\x59 \xA9\xF1 \xB1\xDB \xC2\xE0 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Pan Zoom} ::msgcat::mcset zh {Pan then Zoom} ::msgcat::mcset zh {Panda} ::msgcat::mcset zh {Panner} [encoding convertfrom big5 "\xC1\x59 \xB9\xCF"] ::msgcat::mcset zh {Pan} ::msgcat::mcset zh {Parameters} ::msgcat::mcset zh {Password} ::msgcat::mcset zh {Paste Contours} ::msgcat::mcset zh {Paste} ::msgcat::mcset zh {Physical} ::msgcat::mcset zh {Pixel Distribution} ::msgcat::mcset zh {Pixel Size} ::msgcat::mcset zh {Pixel Table} ::msgcat::mcset zh {Pixels} ::msgcat::mcset zh {Play} ::msgcat::mcset zh {Please Select a Region} ::msgcat::mcset zh {Please specify width, height, and either name or (ra,dec)} ::msgcat::mcset zh {Plot 2D} ::msgcat::mcset zh {Plot 3D} ::msgcat::mcset zh {Plot Title} ::msgcat::mcset zh {Plotting Regions} ::msgcat::mcset zh {Plot} ::msgcat::mcset zh {Plus} ::msgcat::mcset zh {Pointer} ::msgcat::mcset zh {Points} ::msgcat::mcset zh {Point} ::msgcat::mcset zh {Polygon} [encoding convertfrom big5 "\xA6\x68 \xA8\xA4 \xA7\xCE"] ::msgcat::mcset zh {Portrait} ::msgcat::mcset zh {Poster} ::msgcat::mcset zh {Postscript Page Setup} ::msgcat::mcset zh {Postscript Print} ::msgcat::mcset zh {Postscript} ::msgcat::mcset zh {Power} [encoding convertfrom big5 "\xAB\xFC \xBC\xC6"] ::msgcat::mcset zh {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} ::msgcat::mcset zh {Preferences} [encoding convertfrom big5 "\xB0\xBE \xA6\x6E \xB3\x5D \xA9\x77"] ::msgcat::mcset zh {Preserve During Load} ::msgcat::mcset zh {Previous Frame} [encoding convertfrom big5 "\xAB\x65 \xA4\x40 \xBC\x68 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Previous} ::msgcat::mcset zh {Print Coordinates} ::msgcat::mcset zh {Print To} ::msgcat::mcset zh {Printer} ::msgcat::mcset zh {Print} [encoding convertfrom big5 "\xA6\x43 \xA6\x4C"] ::msgcat::mcset zh {Projection} ::msgcat::mcset zh {Properties} [encoding convertfrom big5 "\xA6\x43 \xA6\x4C"] ::msgcat::mcset zh {Property} ::msgcat::mcset zh {Proxy Host} ::msgcat::mcset zh {Proxy Port} ::msgcat::mcset zh {Publication} ::msgcat::mcset zh {Quadratic} ::msgcat::mcset zh {RGB Array} ::msgcat::mcset zh {RGB Cube} ::msgcat::mcset zh {RGB Image} ::msgcat::mcset zh {RGB} ::msgcat::mcset zh {Radial Profile} ::msgcat::mcset zh {Radius} ::msgcat::mcset zh {Range} ::msgcat::mcset zh {Redo} ::msgcat::mcset zh {Red} ::msgcat::mcset zh {Reference Manual} ::msgcat::mcset zh {Reference} ::msgcat::mcset zh {Refresh Frame} [encoding convertfrom big5 "\xAD\xAB \xB7\x73 \xBE\xE3 \xB2\x7A \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Refresh} ::msgcat::mcset zh {Region Parameters} [encoding convertfrom big5 "\xB0\xCF \xB0\xEC \xB0\xD1\xBC\xC6"] ::msgcat::mcset zh {Region} [encoding convertfrom big5 "\xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Release Notes} ::msgcat::mcset zh {Release} ::msgcat::mcset zh {Reload} ::msgcat::mcset zh {Repeat} ::msgcat::mcset zh {Reset Colormap} [encoding convertfrom big5 "\xAD\xAB \xB3\x5D \xC3\x43 \xA6\xF2"] ::msgcat::mcset zh {Reset Frame} [encoding convertfrom big5 "\xAD\xAB \xB3\x5D \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Reset} ::msgcat::mcset zh {Restore} ::msgcat::mcset zh {Retrieve} ::msgcat::mcset zh {Return} ::msgcat::mcset zh {Right} ::msgcat::mcset zh {Roman} ::msgcat::mcset zh {Rotate} [encoding convertfrom big5 "\xB1\xDB \xC2\xE0"] ::msgcat::mcset zh {Rows} ::msgcat::mcset zh {Row} ::msgcat::mcset zh {Ruler} [encoding convertfrom big5 "\xA4\xD8 \xB3\x57"] ::msgcat::mcset zh {SAMP Image} ::msgcat::mcset zh {SAMP Table} ::msgcat::mcset zh {SAMP: already connected} ::msgcat::mcset zh {SAMP: internal error} ::msgcat::mcset zh {SAMP: not connected} ::msgcat::mcset zh {SAMP: unable to locate HUB} ::msgcat::mcset zh {SAMP} ::msgcat::mcset zh {Sample Increment} ::msgcat::mcset zh {Sample Parameters} ::msgcat::mcset zh {Samples per Line} ::msgcat::mcset zh {Sample} ::msgcat::mcset zh {Save 3D Movie} ::msgcat::mcset zh {Save Color Tags} ::msgcat::mcset zh {Save Colormap} ::msgcat::mcset zh {Save Configuration} ::msgcat::mcset zh {Save Contour Levels} ::msgcat::mcset zh {Save Contours} ::msgcat::mcset zh {Save Contrast/Bias} ::msgcat::mcset zh {Save Data} ::msgcat::mcset zh {Save Image on Download} ::msgcat::mcset zh {Save Image} [encoding convertfrom big5 "\xC0\x78 \xA6\x73 \xBC\x76 \xB9\xB3"] ::msgcat::mcset zh {Save Regions} [encoding convertfrom big5 "\xC0\x78 \xA6\x73 \xB0\xCF \xB0\xEC"] ::msgcat::mcset zh {Save Template} ::msgcat::mcset zh {Save as} ::msgcat::mcset zh {Save} [encoding convertfrom big5 "\xC0\x78 \xA6\x73"] ::msgcat::mcset zh {Scale Parameters} [encoding convertfrom big5 "\xA6\xE2 \xB6\xA5 \xB0\xD1 \xBC\xC6"] ::msgcat::mcset zh {Scale} [encoding convertfrom big5 "\xA6\xE2 \xB6\xA5"] ::msgcat::mcset zh {Scan} ::msgcat::mcset zh {Scatter Plot Tool} ::msgcat::mcset zh {Scope} ::msgcat::mcset zh {Search for Catalogs} ::msgcat::mcset zh {Searching for catalogs} ::msgcat::mcset zh {Seconds} ::msgcat::mcset zh {Select All} [encoding convertfrom big5 "\xBF\xEF \xA8\xFA \xA5\xFE \xB3\xA1"] ::msgcat::mcset zh {Select Coordinate System } ::msgcat::mcset zh {Select None} [encoding convertfrom big5 "\xA8\xFA \xAE\xF8 \xBF\xEF \xA8\xFA"] ::msgcat::mcset zh {Send} ::msgcat::mcset zh {Server} ::msgcat::mcset zh {Sexagesimal} ::msgcat::mcset zh {Shape} [encoding convertfrom big5 "\xA7\xCE \xAA\xAC"] ::msgcat::mcset zh {Show All} [encoding convertfrom big5 "\xC5\xE3 \xA5\xDC \xA5\xFE \xB3\xA1"] ::msgcat::mcset zh {Show Command} ::msgcat::mcset zh {Show Compass} ::msgcat::mcset zh {Show Text} ::msgcat::mcset zh {Show/Hide Frames} ::msgcat::mcset zh {Show} [encoding convertfrom big5 "\xC5\xE3 \xA5\xDC"] ::msgcat::mcset zh {Single Frame} [encoding convertfrom big5 "\xB3\xE6 \xA4\x40 \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Single} [encoding convertfrom big5 "\xB3\xE6 \xA4\x40"] ::msgcat::mcset zh {Sites} ::msgcat::mcset zh {Size/Radius} ::msgcat::mcset zh {Size} ::msgcat::mcset zh {Skip First} ::msgcat::mcset zh {Slice} ::msgcat::mcset zh {Smooth Parameters} ::msgcat::mcset zh {Smoothness} ::msgcat::mcset zh {Smooth} ::msgcat::mcset zh {Sorry, DS9 does not support} ::msgcat::mcset zh {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} ::msgcat::mcset zh {Sort} ::msgcat::mcset zh {Source TCL} ::msgcat::mcset zh {Source} ::msgcat::mcset zh {Space Equal Distance} ::msgcat::mcset zh {Space Equal Value} ::msgcat::mcset zh {Spacing} ::msgcat::mcset zh {Square Root} ::msgcat::mcset zh {Squared} ::msgcat::mcset zh {Starbase} ::msgcat::mcset zh {Startup} ::msgcat::mcset zh {Start} ::msgcat::mcset zh {Statistics} ::msgcat::mcset zh {Status} ::msgcat::mcset zh {Step} ::msgcat::mcset zh {Stop} ::msgcat::mcset zh {Story of SAOImage DS9} ::msgcat::mcset zh {Story} ::msgcat::mcset zh {Sum} ::msgcat::mcset zh {Symbol Editor} ::msgcat::mcset zh {Symbol} ::msgcat::mcset zh {Tab-Separated-Value} ::msgcat::mcset zh {Table} ::msgcat::mcset zh {Tabloid} ::msgcat::mcset zh {Template} [encoding convertfrom big5 "\xBC\xCB \xA5\xBB"] ::msgcat::mcset zh {Text Font} ::msgcat::mcset zh {Text} [encoding convertfrom big5 "\xA4\xE5 \xA6\x72"] ::msgcat::mcset zh {Theme} ::msgcat::mcset zh {Then} ::msgcat::mcset zh {Thickness} ::msgcat::mcset zh {This analysis task is already running. Do you wish to kill it?} ::msgcat::mcset zh {Tickmarks} ::msgcat::mcset zh {Tile Frames} [encoding convertfrom big5 "\xA6\x58 \xAD\xAB \xBC\x76 \xB9\xB3 \xB5\xF8 \xB5\xA1"] ::msgcat::mcset zh {Tile Parameters} ::msgcat::mcset zh {Tile} [encoding convertfrom big5 "\xA6\x58 \xAD\xAB"] ::msgcat::mcset zh {Times} ::msgcat::mcset zh {Title} ::msgcat::mcset zh {To Fit} ::msgcat::mcset zh {Tophat} ::msgcat::mcset zh {To} ::msgcat::mcset zh {Transparency} ::msgcat::mcset zh {Type} ::msgcat::mcset zh {URL} ::msgcat::mcset zh {Unable to connect directly: using Web Proxy} ::msgcat::mcset zh {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset zh {Unable to determine date of observation} ::msgcat::mcset zh {Unable to determine time of observation} ::msgcat::mcset zh {Unable to evaluate filter} ::msgcat::mcset zh {Unable to find catalog window} ::msgcat::mcset zh {Unable to find plot window} ::msgcat::mcset zh {Unable to load RGB image into a non-rgb frame} ::msgcat::mcset zh {Unable to load region file} ::msgcat::mcset zh {Unable to load} ::msgcat::mcset zh {Unable to locate URL} ::msgcat::mcset zh {Unable to match target with XPA Mime request} ::msgcat::mcset zh {Unable to open file} ::msgcat::mcset zh {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset zh {Undo} ::msgcat::mcset zh {Unique} ::msgcat::mcset zh {Units} ::msgcat::mcset zh {Unknown Colormap} ::msgcat::mcset zh {Unknown command} ::msgcat::mcset zh {Update Filter} ::msgcat::mcset zh {Update Group} ::msgcat::mcset zh {Update from Current Crosshair} ::msgcat::mcset zh {Update from Current Frame} ::msgcat::mcset zh {Update} ::msgcat::mcset zh {Upper Left Back} ::msgcat::mcset zh {Upper Left Front} ::msgcat::mcset zh {Upper Right Back} ::msgcat::mcset zh {Upper Right Front} ::msgcat::mcset zh {Use Authentication} ::msgcat::mcset zh {Use Current Frame on Download} ::msgcat::mcset zh {Use Internal Web Browser} ::msgcat::mcset zh {Use Proxy} ::msgcat::mcset zh {User Manual} ::msgcat::mcset zh {Username} ::msgcat::mcset zh {User} ::msgcat::mcset zh {Use} ::msgcat::mcset zh {VO Server} ::msgcat::mcset zh {VO} ::msgcat::mcset zh {Value} ::msgcat::mcset zh {Vector} [encoding convertfrom big5 "\xA6\x56 \xB6\x71"] ::msgcat::mcset zh {Vertical Graph} ::msgcat::mcset zh {Vertical Layout} ::msgcat::mcset zh {Vertical Text} ::msgcat::mcset zh {Vertical} [encoding convertfrom big5 "\xAB\xAB \xAA\xBD"] ::msgcat::mcset zh {View} [encoding convertfrom big5 "\xC0\xCB \xB5\xF8"] ::msgcat::mcset zh {Virtual Observatory} ::msgcat::mcset zh {WCS Parameters} ::msgcat::mcset zh {WCS} [encoding convertfrom big5 "\xA7\x79 \xBC\xD0"] ::msgcat::mcset zh {Wavelength} ::msgcat::mcset zh {Web Browser} ::msgcat::mcset zh {White} [encoding convertfrom big5 "\xA5\xD5 \xA6\xE2"] ::msgcat::mcset zh {Width} [encoding convertfrom big5 "\xBC\x65 \xAB\xD7"] ::msgcat::mcset zh {Words matching title, description} ::msgcat::mcset zh {Writing Catalog} ::msgcat::mcset zh {X Axis Title} ::msgcat::mcset zh {X Axis} ::msgcat::mcset zh {X Grid} ::msgcat::mcset zh {XPA Information} ::msgcat::mcset zh {XPA not initialized} ::msgcat::mcset zh {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset zh {XPA} ::msgcat::mcset zh {X} ::msgcat::mcset zh {Y Axis Title} ::msgcat::mcset zh {Y Axis} ::msgcat::mcset zh {Y Grid} ::msgcat::mcset zh {Yellow} [encoding convertfrom big5 "\xB6\xC0 \xA6\xE2"] ::msgcat::mcset zh {Yes} ::msgcat::mcset zh {Y} ::msgcat::mcset zh {Z Axis Scale} ::msgcat::mcset zh {ZScale Parameters} ::msgcat::mcset zh {Zero} ::msgcat::mcset zh {Zoom In} [encoding convertfrom big5 "\xA9\xF1 \xA4\x6A"] ::msgcat::mcset zh {Zoom Out} [encoding convertfrom big5 "\xC1\x59 \xA4\x70"] ::msgcat::mcset zh {Zoom to Fit Frame} [encoding convertfrom big5 "\xC1\x59 \xA9\xF1 \xA8\xEC \xB5\xF8 \xB5\xA1 \xA4\x6A \xA4\x70"] ::msgcat::mcset zh {Zoom} [encoding convertfrom big5 "\xC1\x59 \xA9\xF1"] ::msgcat::mcset zh {and} ::msgcat::mcset zh {blue} [encoding convertfrom big5 "\xC2\xC5"] ::msgcat::mcset zh {b} ::msgcat::mcset zh {color} ::msgcat::mcset zh {cool} ::msgcat::mcset zh {green} [encoding convertfrom big5 "\xBA\xF1"] ::msgcat::mcset zh {grey} [encoding convertfrom big5 "\xA6\xC7"] ::msgcat::mcset zh {g} ::msgcat::mcset zh {heat} ::msgcat::mcset zh {not} ::msgcat::mcset zh {only} ::msgcat::mcset zh {or center of data} ::msgcat::mcset zh {rainbow} ::msgcat::mcset zh {red} [encoding convertfrom big5 "\xAC\xF5"] ::msgcat::mcset zh {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} ::msgcat::mcset zh {r} ::msgcat::mcset zh {staircase} ::msgcat::mcset zh {standard} ::msgcat::mcset zh {x} ::msgcat::mcset zh {} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/ja.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000214450�12132042644�013162� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset ja {2D} ::msgcat::mcset ja {3D} [encoding convertfrom euc-jp "\x33\xbc\xa1\xb8\xb5"] ::msgcat::mcset ja {A postscript generation error has occurred} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xb9\xa5\xc8\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xba\xee\xc0\xae\xa4\xcb\xbc\xba\xc7\xd4\xa4\xb7\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {AIP} ::msgcat::mcset ja {Abort} ::msgcat::mcset ja {About SAOImage DS9} [encoding convertfrom euc-jp "\x53\x41\x4f\x49\x6d\x61\x67\x65\x20\x44\x53\x39\x20\xa4\xcb\xa4\xc4\xa4\xa4\xa4\xc6"] ::msgcat::mcset ja {About} [encoding convertfrom euc-jp "\x44\x53\x39\x20\xa4\xcb\xa4\xc4\xa4\xa4\xa4\xc6"] ::msgcat::mcset ja {Acknowledgment} [encoding convertfrom euc-jp "\xbc\xd5\xbc\xad"] ::msgcat::mcset ja {Add} [encoding convertfrom euc-jp "\xc4\xc9\xb2\xc3"] ::msgcat::mcset ja {Advanced} [encoding convertfrom euc-jp "\xb9\xe2\xc5\xd9\xa4\xca\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Align} [encoding convertfrom euc-jp "\xc0\xb0\xce\xf3"] ::msgcat::mcset ja {All Columns} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xce\xf3"] ::msgcat::mcset ja {All Rows} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xb9\xd4"] ::msgcat::mcset ja {All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6"] ::msgcat::mcset ja {Always save files during Backup} ::msgcat::mcset ja {Amplifier} [encoding convertfrom euc-jp "\xc1\xfd\xc9\xfd\xb4\xef\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {An error has occured while updating VO server list} [encoding convertfrom euc-jp "\xb2\xbe\xc1\xdb\xc5\xb7\xca\xb8\xc2\xe6\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc\xa4\xce\xa5\xea\xa5\xb9\xa5\xc8\xb9\xb9\xbf\xb7\xa4\xcb\xbc\xba\xc7\xd4\xa4\xb7\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {An error has occurred during backup} ::msgcat::mcset ja {An error has occurred during restore} ::msgcat::mcset ja {An error has occurred invoking the Analysis task} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf\xa5\xbf\xa5\xb9\xa5\xaf\xa4\xce\xb5\xaf\xc6\xb0\xa4\xcb\xbc\xba\xc7\xd4\xa4\xb7\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {An error has occurred while creating image.} ::msgcat::mcset ja {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset ja {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset ja {An error has occurred while printing} [encoding convertfrom euc-jp "\xb0\xf5\xba\xfe\xa4\xcb\xbc\xba\xc7\xd4\xa4\xb7\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {An error has occurred while reading image.} ::msgcat::mcset ja {An error has occurred while saving} [encoding convertfrom euc-jp "\xca\xdd\xc2\xb8\xa4\xcb\xbc\xba\xc7\xd4\xa4\xb7\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {An error has occurred while writing image.} ::msgcat::mcset ja {An internal error has been detected} ::msgcat::mcset ja {Analysis Command Log} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9\xa4\xce\xb5\xad\xcf\xbf"] ::msgcat::mcset ja {Analysis Commands} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9"] ::msgcat::mcset ja {Analysis File} ::msgcat::mcset ja {Analysis Log} ::msgcat::mcset ja {Analysis} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf"] ::msgcat::mcset ja {Angle Complement} [encoding convertfrom euc-jp "\xca\xe4\xb3\xd1"] ::msgcat::mcset ja {Angles} [encoding convertfrom euc-jp "\xb3\xd1\xc5\xd9"] ::msgcat::mcset ja {Angle} [encoding convertfrom euc-jp "\xb3\xd1\xc5\xd9"] ::msgcat::mcset ja {Annuli} [encoding convertfrom euc-jp "\xc3\xe6\xc8\xb4\xa4\xad\xb1\xdf"] ::msgcat::mcset ja {Annulus} [encoding convertfrom euc-jp "\xc3\xe6\xc8\xb4\xa4\xad\xb1\xdf"] ::msgcat::mcset ja {Apply} [encoding convertfrom euc-jp "\xc5\xac\xcd\xd1"] ::msgcat::mcset ja {ArcMin} [encoding convertfrom euc-jp "\xca\xac"] ::msgcat::mcset ja {ArcSec} [encoding convertfrom euc-jp "\xc9\xc3"] ::msgcat::mcset ja {Architecture} [encoding convertfrom euc-jp "\xa5\xa2\xa1\xbc\xa5\xad\xa5\xc6\xa5\xaf\xa5\xc1\xa5\xe3"] ::msgcat::mcset ja {Archives} [encoding convertfrom euc-jp "\xa5\xa2\xa1\xbc\xa5\xab\xa5\xa4\xa5\xd6"] ::msgcat::mcset ja {Array} ::msgcat::mcset ja {Arrow} [encoding convertfrom euc-jp "\xcc\xf0\xb0\xf5"] ::msgcat::mcset ja {Astronomy} [encoding convertfrom euc-jp "\xc5\xb7\xca\xb8\xb3\xd8"] ::msgcat::mcset ja {At Startup} ::msgcat::mcset ja {At least 2 different catalogs are required} ::msgcat::mcset ja {Auto Centroid} [encoding convertfrom euc-jp "\xbc\xab\xc6\xb0\xc3\xe6\xbf\xb4\xb9\xe7\xa4\xef\xa4\xbb"] ::msgcat::mcset ja {Auto Plot 2D} ::msgcat::mcset ja {Auto Plot 3D} ::msgcat::mcset ja {Auto Plot} ::msgcat::mcset ja {Autoload FITS Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xce\xbc\xab\xc6\xb0\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Autoload} ::msgcat::mcset ja {Automatic} [encoding convertfrom euc-jp "\xbc\xab\xc6\xb0"] ::msgcat::mcset ja {Average} [encoding convertfrom euc-jp "\xca\xbf\xb6\xd1"] ::msgcat::mcset ja {Axes Number} ::msgcat::mcset ja {Axes Title} ::msgcat::mcset ja {Axes} [encoding convertfrom euc-jp "\xbc\xb4"] ::msgcat::mcset ja {Axis Label} [encoding convertfrom euc-jp "\xbc\xb4\xa4\xce\xa5\xe9\xa5\xd9\xa5\xeb"] ::msgcat::mcset ja {Axis Length} [encoding convertfrom euc-jp "\xbc\xb4\xa4\xce\xc4\xb9\xa4\xb5"] ::msgcat::mcset ja {Axis Numbers} [encoding convertfrom euc-jp "\xbc\xb4\xa4\xce\xbf\xf4\xc3\xcd"] ::msgcat::mcset ja {Axis} [encoding convertfrom euc-jp "\xbc\xb4"] ::msgcat::mcset ja {Azimuth} [encoding convertfrom euc-jp "\xca\xfd\xb0\xcc\xb3\xd1"] ::msgcat::mcset ja {Background Color} [encoding convertfrom euc-jp "\xc7\xd8\xb7\xca\xbf\xa7"] ::msgcat::mcset ja {Background} [encoding convertfrom euc-jp "\xa5\xd0\xa5\xc3\xa5\xaf\xa5\xb0\xa5\xe9\xa5\xa6\xa5\xf3\xa5\xc9\xce\xce\xb0\xe8"] ::msgcat::mcset ja {Backup} ::msgcat::mcset ja {Back} [encoding convertfrom euc-jp "\xc1\xb0"] ::msgcat::mcset ja {Bar Plot Tool} ::msgcat::mcset ja {Bias} [encoding convertfrom euc-jp "\xa5\xd0\xa5\xa4\xa5\xa2\xa5\xb9"] ::msgcat::mcset ja {Bin 3rd Column} [encoding convertfrom euc-jp "\xc2\xe8\xa3\xb3\xa4\xce\xce\xf3\xa4\xf2\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1"] ::msgcat::mcset ja {Bin Center} [encoding convertfrom euc-jp "\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1\xa4\xce\xc3\xe6\xbf\xb4"] ::msgcat::mcset ja {Bin Columns} [encoding convertfrom euc-jp "\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1\xa4\xb9\xa4\xeb\xce\xf3"] ::msgcat::mcset ja {Bin Filter} [encoding convertfrom euc-jp "\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1\xa4\xce\xb9\xca\xa4\xea\xb9\xfe\xa4\xdf\xbe\xf2\xb7\xef"] ::msgcat::mcset ja {Binning Parameters} [encoding convertfrom euc-jp "\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Bin} [encoding convertfrom euc-jp "\xa5\xd3\xa5\xf3\xa4\xde\xa4\xc8\xa4\xe1"] ::msgcat::mcset ja {Black} [encoding convertfrom euc-jp "\xb9\xf5\xbf\xa7"] ::msgcat::mcset ja {Blank/Inf/NaN Color} [encoding convertfrom euc-jp "\xcc\xa4\xc4\xea\xb5\xc1\xc3\xcd\x28\x42\x6c\x61\x6e\x6b\x2f\x49\x6e\x66\x2f\x4e\x61\x4e\x29\xa4\xce\xbf\xa7"] ::msgcat::mcset ja {Blink Frames} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xa5\xd6\xa5\xea\xa5\xf3\xa5\xaf"] ::msgcat::mcset ja {Blink Interval} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xea\xa5\xf3\xa5\xaf\xa4\xce\xb4\xd6\xb3\xd6"] ::msgcat::mcset ja {Blink} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xea\xa5\xf3\xa5\xaf"] ::msgcat::mcset ja {Block In} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xed\xa5\xc3\xa5\xaf\xa4\xf2\xba\xd9\xa4\xab\xa4\xaf"] ::msgcat::mcset ja {Block Out} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xed\xa5\xc3\xa5\xaf\xa4\xf2\xb9\xd3\xa4\xaf"] ::msgcat::mcset ja {Block to Fit Frame} [encoding convertfrom euc-jp "\xc1\xb4\xc2\xce\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Block} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xed\xa5\xc3\xa5\xaf"] ::msgcat::mcset ja {Blue} [encoding convertfrom euc-jp "\xc0\xc4\xbf\xa7"] ::msgcat::mcset ja {Bold} [encoding convertfrom euc-jp "\xc2\xc0\xbb\xfa"] ::msgcat::mcset ja {Border} [encoding convertfrom euc-jp "\xcf\xc8\xc0\xfe"] ::msgcat::mcset ja {Box Annulus} [encoding convertfrom euc-jp "\xc3\xe6\xc8\xb4\xa4\xad\xbb\xcd\xb3\xd1\xb7\xc1"] ::msgcat::mcset ja {Box Panda} [encoding convertfrom euc-jp "\xc9\xf4\xca\xac\xbb\xcd\xb3\xd1\xb7\xc1"] ::msgcat::mcset ja {BoxCircle} ::msgcat::mcset ja {Boxcar} [encoding convertfrom euc-jp "\xa5\xdc\xa5\xc3\xa5\xaf\xa5\xb9\xa5\xab\xa1\xbc"] ::msgcat::mcset ja {Box} [encoding convertfrom euc-jp "\xbb\xcd\xb3\xd1\xb7\xc1"] ::msgcat::mcset ja {Broadcast} ::msgcat::mcset ja {Browser} ::msgcat::mcset ja {Browse} [encoding convertfrom euc-jp "\xbb\xb2\xbe\xc8"] ::msgcat::mcset ja {Buffer} [encoding convertfrom euc-jp "\xa5\xd0\xa5\xc3\xa5\xd5\xa5\xa1"] ::msgcat::mcset ja {Buttonbar} [encoding convertfrom euc-jp "\xa5\xdc\xa5\xbf\xa5\xf3\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Buttons} [encoding convertfrom euc-jp "\xa5\xdc\xa5\xbf\xa5\xf3"] ::msgcat::mcset ja {Bytes} [encoding convertfrom euc-jp "\xa5\xd0\xa5\xa4\xa5\xc8"] ::msgcat::mcset ja {CMYK} [encoding convertfrom euc-jp "\x43\x4d\x59\x4b\xbf\xa7"] ::msgcat::mcset ja {Can Delete} [encoding convertfrom euc-jp "\xba\xef\xbd\xfc\xb2\xc4"] ::msgcat::mcset ja {Can Edit} [encoding convertfrom euc-jp "\xca\xd4\xbd\xb8\xb2\xc4"] ::msgcat::mcset ja {Can Move} [encoding convertfrom euc-jp "\xb0\xdc\xc6\xb0\xb2\xc4"] ::msgcat::mcset ja {Can Rotate} [encoding convertfrom euc-jp "\xb2\xf3\xc5\xbe\xb2\xc4"] ::msgcat::mcset ja {Cancel} [encoding convertfrom euc-jp "\xbc\xe8\xa4\xea\xbe\xc3\xa4\xb7"] ::msgcat::mcset ja {Catalog Server} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xb8\xa1\xba\xf7\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Catalog Tool} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa5\xc4\xa1\xbc\xa5\xeb"] ::msgcat::mcset ja {Catalogs} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0"] ::msgcat::mcset ja {Catalog} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0"] ::msgcat::mcset ja {Center Image} [encoding convertfrom euc-jp "\xa5\xa4\xa5\xe1\xa1\xbc\xa5\xb8\xa4\xf2\xc3\xe6\xbf\xb4\xa4\xcb"] ::msgcat::mcset ja {Center Non-modal Dialogs} ::msgcat::mcset ja {Center} [encoding convertfrom euc-jp "\xc3\xe6\xbf\xb4"] ::msgcat::mcset ja {Centroid Parameters} [encoding convertfrom euc-jp "\xc3\xe6\xbf\xb4\xb9\xe7\xa4\xef\xa4\xbb\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Centroid} ::msgcat::mcset ja {Circle} [encoding convertfrom euc-jp "\xb1\xdf"] ::msgcat::mcset ja {Clear All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear Analysis Commands} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear Cache} [encoding convertfrom euc-jp "\xa5\xad\xa5\xe3\xa5\xc3\xa5\xb7\xa5\xe5\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear Data} [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear External Analysis Commands?} [encoding convertfrom euc-jp "\xb3\xb0\xc9\xf4\xb2\xf2\xc0\xcf\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9\xa4\xf2\xbe\xc3\xb5\xee\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Clear Filter} [encoding convertfrom euc-jp "\xb9\xca\xa4\xea\xb9\xfe\xa4\xdf\xbe\xf2\xb7\xef\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear Preferences?} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa4\xf2\xbe\xc3\xb5\xee\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Clear Preferences} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Clear} [encoding convertfrom euc-jp "\xa5\xaf\xa5\xea\xa5\xa2"] ::msgcat::mcset ja {Click to Center} [encoding convertfrom euc-jp "\xa5\xaf\xa5\xea\xa5\xc3\xa5\xaf\xb0\xcc\xc3\xd6\xa4\xf2\xc3\xe6\xbf\xb4"] ::msgcat::mcset ja {Close} [encoding convertfrom euc-jp "\xca\xc4\xa4\xb8\xa4\xeb"] ::msgcat::mcset ja {Colorbar Size} ::msgcat::mcset ja {Colorbar} [encoding convertfrom euc-jp "\xc7\xdb\xbf\xa7\xcb\xc0"] ::msgcat::mcset ja {Colormap Parameters} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Colormap} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4"] ::msgcat::mcset ja {Color} [encoding convertfrom euc-jp "\xbf\xa7"] ::msgcat::mcset ja {Columns} [encoding convertfrom euc-jp "\xce\xf3"] ::msgcat::mcset ja {Column} [encoding convertfrom euc-jp "\xce\xf3"] ::msgcat::mcset ja {Command} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9"] ::msgcat::mcset ja {Compass} [encoding convertfrom euc-jp "\xca\xfd\xb0\xcc\xbc\xa7\xc0\xd0"] ::msgcat::mcset ja {Composite Region} [encoding convertfrom euc-jp "\xca\xa3\xb9\xe7\xce\xce\xb0\xe8"] ::msgcat::mcset ja {Composite} ::msgcat::mcset ja {Compression} [encoding convertfrom euc-jp "\xb0\xb5\xbd\xcc"] ::msgcat::mcset ja {Configure} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Connect Directly} [encoding convertfrom euc-jp "\xc4\xbe\xc0\xdc\xc0\xdc\xc2\xb3"] ::msgcat::mcset ja {Connect SAMP} ::msgcat::mcset ja {Connect Using Web Proxy} [encoding convertfrom euc-jp "\x57\x65\x62\x20\xa5\xd7\xa5\xed\xa5\xad\xa5\xb7\xa4\xf2\xb2\xf0\xa4\xb7\xa4\xc6\xc0\xdc\xc2\xb3"] ::msgcat::mcset ja {Connect} [encoding convertfrom euc-jp "\xc0\xdc\xc2\xb3"] ::msgcat::mcset ja {Console} ::msgcat::mcset ja {Contour Parameters} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Contours} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2"] ::msgcat::mcset ja {Contour} ::msgcat::mcset ja {Contrast} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xe9\xa5\xb9\xa5\xc8"] ::msgcat::mcset ja {Contributed} ::msgcat::mcset ja {Convert to Polygons} [encoding convertfrom euc-jp "\xc2\xbf\xb3\xd1\xb7\xc1\xa4\xcb\xca\xd1\xb4\xb9"] ::msgcat::mcset ja {Coordinate Grid Parameters} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8\xa5\xb0\xa5\xea\xa5\xc3\xa5\xc9\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Coordinate Grid} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8\xa5\xb0\xa5\xea\xa5\xc3\xa5\xc9"] ::msgcat::mcset ja {Coordinate System} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8\xb7\xcf"] ::msgcat::mcset ja {Coordinates} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Coordinate} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Copy Contours} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa4\xf2\xa5\xb3\xa5\xd4\xa1\xbc"] ::msgcat::mcset ja {Copy to Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xcb\xa5\xb3\xa5\xd4\xa1\xbc"] ::msgcat::mcset ja {Copy} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xd4\xa1\xbc"] ::msgcat::mcset ja {Create Movie} ::msgcat::mcset ja {Create New Frame on Download} [encoding convertfrom euc-jp "\xa5\xc0\xa5\xa6\xa5\xf3\xa5\xed\xa1\xbc\xa5\xc9\xbb\xfe\xa4\xcb\xbf\xb7\xa4\xb7\xa4\xa4\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xba\xee\xc0\xae"] ::msgcat::mcset ja {Create} [encoding convertfrom euc-jp "\xba\xee\xc0\xae"] ::msgcat::mcset ja {Crop Parameters} ::msgcat::mcset ja {Crop} ::msgcat::mcset ja {Crosshair To} [encoding convertfrom euc-jp "\xa4\xbd\xa4\xb3\xa4\xcb\xbd\xbd\xbb\xfa\xc0\xfe"] ::msgcat::mcset ja {Crosshair} [encoding convertfrom euc-jp "\xbd\xbd\xbb\xfa\xa5\xab\xa1\xbc\xa5\xbd\xa5\xeb"] ::msgcat::mcset ja {Cross} [encoding convertfrom euc-jp "\xbd\xbd\xbb\xfa"] ::msgcat::mcset ja {Cube} ::msgcat::mcset ja {Current Frame} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xc3\xe6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Current Range} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xc3\xe6\xa4\xce\xc8\xcf\xb0\xcf"] ::msgcat::mcset ja {Current} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xc3\xe6"] ::msgcat::mcset ja {Cursor} [encoding convertfrom euc-jp "\xa5\xab\xa1\xbc\xa5\xbd\xa5\xeb"] ::msgcat::mcset ja {Cut} [encoding convertfrom euc-jp "\xc0\xda\xa4\xea\xbc\xe8\xa4\xea"] ::msgcat::mcset ja {Cyan} [encoding convertfrom euc-jp "\xbf\xe5\xbf\xa7"] ::msgcat::mcset ja {DPI} ::msgcat::mcset ja {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset ja {DS9 has detected a newer version of a preferences file and therefore will not process this file.} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xce\xa5\xd0\xa1\xbc\xa5\xb8\xa5\xe7\xa5\xf3\xa4\xac\xbf\xb7\xa4\xb7\xa4\xb9\xa4\xae\xa4\xeb\xa4\xce\xa4\xc7\xa1\xa2\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xde\xa4\xba\xa4\xcb\xb5\xaf\xc6\xb0\xa4\xb7\xa4\xde\xa4\xb9\xa1\xa3"] ::msgcat::mcset ja {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset ja {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom euc-jp "\xb8\xc5\xa4\xa4\xa5\xd0\xa1\xbc\xa5\xb8\xa5\xe7\xa5\xf3\xa4\xce\xc0\xdf\xc4\xea\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3\xb9\xb9\xbf\xb7\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {DS9 will complete the initialization process} [encoding convertfrom euc-jp "\xbd\xe9\xb4\xfc\xb2\xbd\xa4\xf2\xb4\xb0\xce\xbb\xa4\xb7\xa4\xde\xa4\xb9\xa1\xa3"] ::msgcat::mcset ja {Dash} [encoding convertfrom euc-jp "\xc7\xcb\xc0\xfe"] ::msgcat::mcset ja {Data Format} [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xb7\xc1\xbc\xb0"] ::msgcat::mcset ja {Dataset} [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xa5\xbb\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Data} ::msgcat::mcset ja {Decrease} [encoding convertfrom euc-jp "\xb9\xdf\xbd\xe7"] ::msgcat::mcset ja {Default All Files} ::msgcat::mcset ja {Default Format} ::msgcat::mcset ja {Default Length} ::msgcat::mcset ja {Default} [encoding convertfrom euc-jp "\xc9\xb8\xbd\xe0"] ::msgcat::mcset ja {Degrees} [encoding convertfrom euc-jp "\xc5\xd9"] ::msgcat::mcset ja {Delete All Frames?} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbe\xc3\xb5\xee\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Delete All Frames} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete All Groups?} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xa4\xf2\xbe\xc3\xb5\xee\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Delete All Groups} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete All Regions?} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xce\xce\xb0\xe8\xa4\xf2\xbe\xc3\xb5\xee\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Delete All Regions} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xce\xce\xb0\xe8\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete Color Tags} ::msgcat::mcset ja {Delete Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete Group} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xa4\xf2\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Delete Selected Regions} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xa4\xb7\xa4\xbf\xce\xce\xb0\xe8\xa4\xf2\xba\xef\xbd\xfc"] ::msgcat::mcset ja {Delete} [encoding convertfrom euc-jp "\xbe\xc3\xb5\xee"] ::msgcat::mcset ja {Depth} [encoding convertfrom euc-jp "\xbf\xbc\xa4\xb5"] ::msgcat::mcset ja {Detector} [encoding convertfrom euc-jp "\xb8\xa1\xbd\xd0\xb4\xef\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Dialog Box} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xc3\xa5\xd7\xa5\xa2\xa5\xc3\xa5\xd7\xa5\xe1\xa5\xcb\xa5\xe5\xa1\xbc"] ::msgcat::mcset ja {Diamond} [encoding convertfrom euc-jp "\xc9\xa9\xb7\xc1"] ::msgcat::mcset ja {Dimension} [encoding convertfrom euc-jp "\xbc\xa1\xb8\xb5"] ::msgcat::mcset ja {Disconnect} [encoding convertfrom euc-jp "\xc0\xdc\xc2\xb3\xbd\xaa\xce\xbb"] ::msgcat::mcset ja {Discrete} ::msgcat::mcset ja {Display Header} ::msgcat::mcset ja {Display Size} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xa4\xa5\xba\xa4\xf2\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Dissolve} [encoding convertfrom euc-jp "\xca\xac\xb2\xf2"] ::msgcat::mcset ja {Distance} ::msgcat::mcset ja {Download Colormap} ::msgcat::mcset ja {Download VOTABLE format if available} [encoding convertfrom euc-jp "\x56\x4f\x54\x41\x42\x4c\x45\x20\xb7\xc1\xbc\xb0\xa4\xac\xa4\xa2\xa4\xec\xa4\xd0\xa5\xc0\xa5\xa6\xa5\xf3\xa5\xed\xa1\xbc\xa5\xc9"] ::msgcat::mcset ja {Drag to Center} [encoding convertfrom euc-jp "\xc3\xe6\xbf\xb4\xa4\xcb\xa5\xc9\xa5\xe9\xa5\xc3\xa5\xb0"] ::msgcat::mcset ja {Duplicate Data} ::msgcat::mcset ja {East} [encoding convertfrom euc-jp "\xc5\xec"] ::msgcat::mcset ja {Ecliptic} [encoding convertfrom euc-jp "\xb2\xab\xc6\xbb\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Edit Group Name} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xcc\xbe\xa4\xf2\xca\xd1\xb9\xb9"] ::msgcat::mcset ja {Edit} [encoding convertfrom euc-jp "\xca\xd4\xbd\xb8"] ::msgcat::mcset ja {Element} ::msgcat::mcset ja {Elevation} [encoding convertfrom euc-jp "\xb9\xe2\xc5\xd9"] ::msgcat::mcset ja {Ellipse Panda} [encoding convertfrom euc-jp "\xc9\xf4\xca\xac\xc2\xca\xb1\xdf"] ::msgcat::mcset ja {Ellipse} [encoding convertfrom euc-jp "\xc2\xca\xb1\xdf"] ::msgcat::mcset ja {Elliptical Annulus} [encoding convertfrom euc-jp "\xc3\xe6\xc8\xb4\xa4\xad\xc2\xca\xb1\xdf"] ::msgcat::mcset ja {Elliptical Panda} [encoding convertfrom euc-jp "\xc3\xe6\xc8\xb4\xa4\xad\xc9\xf4\xca\xac\xc2\xca\xb1\xdf"] ::msgcat::mcset ja {Enable Confirmation Dialogs} [encoding convertfrom euc-jp "\xb3\xce\xc7\xa7\xa5\xe1\xa5\xc3\xa5\xbb\xa1\xbc\xa5\xb8\xa4\xf2\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Enable} ::msgcat::mcset ja {End} [encoding convertfrom euc-jp "\xbd\xaa\xce\xbb"] ::msgcat::mcset ja {Enter Color} [encoding convertfrom euc-jp "\xbf\xa7\xa4\xf2\xc6\xfe\xce\xcf"] ::msgcat::mcset ja {Enter Font Size} ::msgcat::mcset ja {Enter Group Name} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xcc\xbe\xa4\xf2\xc6\xfe\xce\xcf"] ::msgcat::mcset ja {Enter Search Expression} [encoding convertfrom euc-jp "\xb8\xa1\xba\xf7\xbe\xf2\xb7\xef\xa4\xf2\xc6\xfe\xce\xcf"] ::msgcat::mcset ja {Enter URL} ::msgcat::mcset ja {Entry} ::msgcat::mcset ja {Equal Area} [encoding convertfrom euc-jp "\xc5\xf9\xcc\xcc\xc0\xd1"] ::msgcat::mcset ja {Equal Distance} [encoding convertfrom euc-jp "\xc5\xf9\xb5\xf7\xce\xa5"] ::msgcat::mcset ja {Equal Spacing} ::msgcat::mcset ja {Equal Value} ::msgcat::mcset ja {Error code was returned} [encoding convertfrom euc-jp "\xa5\xa8\xa5\xe9\xa1\xbc\xa5\xb3\xa1\xbc\xa5\xc9\xa4\xac\xca\xd6\xa4\xb5\xa4\xec\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {Error} [encoding convertfrom euc-jp "\xa5\xa8\xa5\xe9\xa1\xbc"] ::msgcat::mcset ja {Examine Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbe\xdc\xba\xd9\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Examine} [encoding convertfrom euc-jp "\xbe\xdc\xba\xd9\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Exclude} [encoding convertfrom euc-jp "\xb3\xb0\xc2\xa6"] ::msgcat::mcset ja {Executing TCL code is not enabled} [encoding convertfrom euc-jp "\x54\x43\x4c\x20\xa5\xb3\xa1\xbc\xa5\xc9\xa4\xce\xbc\xc2\xb9\xd4\xa4\xac\xb5\xf6\xb2\xc4\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xbb\xa4\xf3"] ::msgcat::mcset ja {Exit} [encoding convertfrom euc-jp "\xbd\xaa\xce\xbb"] ::msgcat::mcset ja {Export Array} ::msgcat::mcset ja {Export} ::msgcat::mcset ja {Extention} ::msgcat::mcset ja {Exterior Axes} [encoding convertfrom euc-jp "\xbc\xb4\xa4\xf2\xb3\xb0\xc2\xa6\xa4\xcb"] ::msgcat::mcset ja {Exterior Numerics} [encoding convertfrom euc-jp "\xbf\xf4\xc3\xcd\xa4\xf2\xb3\xb0\xc2\xa6\xa4\xcb"] ::msgcat::mcset ja {FAQ} [encoding convertfrom euc-jp "\xa4\xe8\xa4\xaf\xa4\xa2\xa4\xeb\xbc\xc1\xcc\xe4\xa4\xc8\xc5\xfa\xa4\xa8"] ::msgcat::mcset ja {FK4} ::msgcat::mcset ja {FK5} ::msgcat::mcset ja {Factor} ::msgcat::mcset ja {File not Found or Unable to load FITS data MIME type} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3\xa4\xde\xa4\xbf\xa4\xcf\xa1\xa2\x46\x49\x54\x53\x20\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xac\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xe1\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Filename} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xcc\xbe"] ::msgcat::mcset ja {File} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb"] ::msgcat::mcset ja {Fill} ::msgcat::mcset ja {Filter} [encoding convertfrom euc-jp "\xb9\xca\xa4\xea\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Find Next} [encoding convertfrom euc-jp "\xbc\xa1\xa4\xf2\xb8\xa1\xba\xf7"] ::msgcat::mcset ja {Find} [encoding convertfrom euc-jp "\xb8\xa1\xba\xf7"] ::msgcat::mcset ja {First Frame} [encoding convertfrom euc-jp "\xba\xc7\xbd\xe9\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {First} [encoding convertfrom euc-jp "\xba\xc7\xbd\xe9"] ::msgcat::mcset ja {Fits} ::msgcat::mcset ja {Fixed in Size} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xa4\xa5\xba\xb8\xc7\xc4\xea"] ::msgcat::mcset ja {Flip} ::msgcat::mcset ja {Font} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa9\xa5\xf3\xa5\xc8"] ::msgcat::mcset ja {For more information, use --help} [encoding convertfrom euc-jp "\xbe\xdc\xa4\xb7\xa4\xaf\xa4\xcf\x20\x2d\x2d\x68\x65\x6c\x70\x20\xa5\xaa\xa5\xd7\xa5\xb7\xa5\xe7\xa5\xf3\xa4\xc7\xa1\xa3"] ::msgcat::mcset ja {Format} [encoding convertfrom euc-jp "\xb7\xc1\xbc\xb0"] ::msgcat::mcset ja {Forward} [encoding convertfrom euc-jp "\xbc\xa1"] ::msgcat::mcset ja {Found} ::msgcat::mcset ja {Frame Information} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xce\xbe\xf0\xca\xf3"] ::msgcat::mcset ja {Frame Parameters} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Frames} ::msgcat::mcset ja {Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {From} ::msgcat::mcset ja {Front} [encoding convertfrom euc-jp "\xc1\xb4\xcc\xcc"] ::msgcat::mcset ja {Full Range} [encoding convertfrom euc-jp "\xc1\xb4\xc8\xcf\xb0\xcf"] ::msgcat::mcset ja {Function} [encoding convertfrom euc-jp "\xb4\xd8\xbf\xf4"] ::msgcat::mcset ja {GUI Font} ::msgcat::mcset ja {Galactic} [encoding convertfrom euc-jp "\xb6\xe4\xb2\xcf\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Gap} ::msgcat::mcset ja {Gaussian} [encoding convertfrom euc-jp "\xa5\xac\xa5\xa6\xa5\xb7\xa5\xa2\xa5\xf3"] ::msgcat::mcset ja {General} [encoding convertfrom euc-jp "\xb0\xec\xc8\xcc"] ::msgcat::mcset ja {Generate} [encoding convertfrom euc-jp "\xc0\xb8\xc0\xae"] ::msgcat::mcset ja {Generating Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xf2\xba\xee\xc0\xae\xc3\xe6"] ::msgcat::mcset ja {Get Information} [encoding convertfrom euc-jp "\xbe\xf0\xca\xf3\xa4\xf2\xbc\xe8\xc6\xc0"] ::msgcat::mcset ja {Global Properties} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xed\xa1\xbc\xa5\xd0\xa5\xeb\xa5\xd7\xa5\xed\xa5\xd1\xa5\xc6\xa5\xa3"] ::msgcat::mcset ja {Global} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xed\xa1\xbc\xa5\xd0\xa5\xeb"] ::msgcat::mcset ja {Goto Frame} [encoding convertfrom euc-jp "\xbb\xd8\xc4\xea\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Graph Horz} [encoding convertfrom euc-jp "\xb2\xa3\xc3\xc7\xcc\xcc\xbf\xde"] ::msgcat::mcset ja {Graph Vert} [encoding convertfrom euc-jp "\xbd\xc4\xc3\xc7\xcc\xcc\xbf\xde"] ::msgcat::mcset ja {Graphics} ::msgcat::mcset ja {Graphs} ::msgcat::mcset ja {Graph} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xe9\xa5\xd5"] ::msgcat::mcset ja {Grayscale} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xec\xa1\xbc\xa5\xb9\xa5\xb1\xa1\xbc\xa5\xeb"] ::msgcat::mcset ja {Green} [encoding convertfrom euc-jp "\xce\xd0\xbf\xa7"] ::msgcat::mcset ja {Grid Gap} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xea\xa5\xc3\xa5\xc9\xa4\xce\xb4\xd6\xb3\xd6"] ::msgcat::mcset ja {Grid} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xea\xa5\xc3\xa5\xc9"] ::msgcat::mcset ja {Groups} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7"] ::msgcat::mcset ja {HTTP} [encoding convertfrom euc-jp "\x48\x54\x54\x50"] ::msgcat::mcset ja {Header} [encoding convertfrom euc-jp "\xa5\xd8\xa5\xc3\xa5\xc0"] ::msgcat::mcset ja {Height} [encoding convertfrom euc-jp "\xb9\xe2\xa4\xb5"] ::msgcat::mcset ja {Help Desk} [encoding convertfrom euc-jp "\xa5\xd8\xa5\xeb\xa5\xd7\xa5\xc7\xa5\xb9\xa5\xaf"] ::msgcat::mcset ja {Help Me Choose} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xa4\xce\xa5\xd2\xa5\xf3\xa5\xc8"] ::msgcat::mcset ja {Help} [encoding convertfrom euc-jp "\xa5\xd8\xa5\xeb\xa5\xd7"] ::msgcat::mcset ja {Hide All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xc8\xf3\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Highlite} ::msgcat::mcset ja {High} [encoding convertfrom euc-jp "\xbe\xe5\xb8\xc2"] ::msgcat::mcset ja {Histogram Equalization} [encoding convertfrom euc-jp "\xa5\xd2\xa5\xb9\xa5\xc8\xa5\xb0\xa5\xe9\xa5\xe0\xc5\xf9\xca\xac\xc9\xdb"] ::msgcat::mcset ja {Histogram} [encoding convertfrom euc-jp "\xa5\xd2\xa5\xb9\xa5\xc8\xa5\xb0\xa5\xe9\xa5\xe0"] ::msgcat::mcset ja {Horizontal Graph} [encoding convertfrom euc-jp "\xb2\xa3\xc3\xc7\xcc\xcc"] ::msgcat::mcset ja {Horizontal Layout} [encoding convertfrom euc-jp "\xb2\xe8\xc1\xfc\xa4\xce\xbe\xe5\xa4\xcb\xc7\xdb\xc3\xd6"] ::msgcat::mcset ja {Horizontal} ::msgcat::mcset ja {IAU Location Code} ::msgcat::mcset ja {ICRS} [encoding convertfrom euc-jp "\xb9\xf1\xba\xdd\xc5\xb7\xca\xb8\xbd\xe0\xb5\xf2\xb7\xcf"] ::msgcat::mcset ja {Identification} [encoding convertfrom euc-jp "\xc6\xb1\xc4\xea"] ::msgcat::mcset ja {If} [encoding convertfrom euc-jp "\xa4\xe2\xa4\xb7"] ::msgcat::mcset ja {Image Servers} [encoding convertfrom euc-jp "\xa5\xa4\xa5\xe1\xa1\xbc\xa5\xb8\xb8\xa1\xba\xf7\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Image} [encoding convertfrom euc-jp "\xcf\xc0\xcd\xfd\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Import Array} ::msgcat::mcset ja {Import} ::msgcat::mcset ja {Include} [encoding convertfrom euc-jp "\xc6\xe2\xc2\xa6"] ::msgcat::mcset ja {Increase} [encoding convertfrom euc-jp "\xbe\xba\xbd\xe7"] ::msgcat::mcset ja {Information Panel} [encoding convertfrom euc-jp "\xbe\xf0\xca\xf3\xa5\xd1\xa5\xcd\xa5\xeb"] ::msgcat::mcset ja {Information} [encoding convertfrom euc-jp "\xbe\xf0\xca\xf3"] ::msgcat::mcset ja {Initialize XPA} [encoding convertfrom euc-jp "\x58\x50\x41\x20\xa4\xf2\xbd\xe9\xb4\xfc\xb2\xbd"] ::msgcat::mcset ja {Inner} [encoding convertfrom euc-jp "\xc6\xe2\xb7\xc2"] ::msgcat::mcset ja {Instrument FOV} [encoding convertfrom euc-jp "\xb8\xa1\xbd\xd0\xb4\xef\xa4\xce\xbb\xeb\xcc\xee"] ::msgcat::mcset ja {Interior Axes} [encoding convertfrom euc-jp "\xbc\xb4\xa4\xf2\xc6\xe2\xc2\xa6\xa4\xcb"] ::msgcat::mcset ja {Interior Numerics} [encoding convertfrom euc-jp "\xbf\xf4\xc3\xcd\xa4\xf2\xc6\xe2\xc2\xa6\xa4\xcb"] ::msgcat::mcset ja {Internal Parse Error} [encoding convertfrom euc-jp "\xc6\xe2\xc9\xf4\xb2\xf2\xbc\xe1\xa5\xa8\xa5\xe9\xa1\xbc"] ::msgcat::mcset ja {Interval} [encoding convertfrom euc-jp "\xb4\xd6\xb3\xd6"] ::msgcat::mcset ja {Invalid Column Name} ::msgcat::mcset ja {Invalid formated multipart/mixed mime type message} ::msgcat::mcset ja {Invert Colormap} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4\xa4\xf2\xc8\xbf\xc5\xbe"] ::msgcat::mcset ja {Invert Selection} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xa4\xf2\xc8\xbf\xc5\xbe"] ::msgcat::mcset ja {Invert} [encoding convertfrom euc-jp "\xc8\xbf\xc5\xbe"] ::msgcat::mcset ja {Italic} [encoding convertfrom euc-jp "\xa5\xa4\xa5\xbf\xa5\xea\xa5\xc3\xa5\xaf"] ::msgcat::mcset ja {Items Found} ::msgcat::mcset ja {Iteration} [encoding convertfrom euc-jp "\xb7\xab\xa4\xea\xca\xd6\xa4\xb7"] ::msgcat::mcset ja {JPEG Quality Factor} [encoding convertfrom euc-jp "\x4a\x50\x45\x47\xa4\xce\xc9\xca\xbc\xc1"] ::msgcat::mcset ja {Keep-Alive} ::msgcat::mcset ja {Kernel} ::msgcat::mcset ja {Keyboard Shortcuts} [encoding convertfrom euc-jp "\xa5\xb7\xa5\xe7\xa1\xbc\xa5\xc8\xa5\xab\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Keyboard} [encoding convertfrom euc-jp "\xa5\xad\xa1\xbc\xa5\xdc\xa1\xbc\xa5\xc9"] ::msgcat::mcset ja {Labels} [encoding convertfrom euc-jp "\xa5\xe9\xa5\xd9\xa5\xeb"] ::msgcat::mcset ja {Label} [encoding convertfrom euc-jp "\xa5\xe9\xa5\xd9\xa5\xeb"] ::msgcat::mcset ja {Landscape} [encoding convertfrom euc-jp "\xb2\xa3\xc4\xb9"] ::msgcat::mcset ja {Language} [encoding convertfrom euc-jp "\xb8\xc0\xb8\xec"] ::msgcat::mcset ja {Last Frame} [encoding convertfrom euc-jp "\xba\xc7\xb8\xe5\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Last} [encoding convertfrom euc-jp "\xba\xc7\xb8\xe5"] ::msgcat::mcset ja {Layout Horz} [encoding convertfrom euc-jp "\xb2\xa3\xc7\xdb\xc3\xd6"] ::msgcat::mcset ja {Layout Vert} [encoding convertfrom euc-jp "\xbd\xc4\xc7\xdb\xc3\xd6"] ::msgcat::mcset ja {Layout} ::msgcat::mcset ja {Left} ::msgcat::mcset ja {Legal} [encoding convertfrom euc-jp "\xa5\xea\xa1\xbc\xa5\xac\xa5\xeb"] ::msgcat::mcset ja {Length} [encoding convertfrom euc-jp "\xc4\xb9\xa4\xb5"] ::msgcat::mcset ja {Letter} [encoding convertfrom euc-jp "\xa5\xec\xa5\xbf\xa1\xbc"] ::msgcat::mcset ja {Levels} [encoding convertfrom euc-jp "\xa5\xec\xa5\xd9\xa5\xeb"] ::msgcat::mcset ja {Level} [encoding convertfrom euc-jp "\xa5\xec\xa5\xd9\xa5\xeb"] ::msgcat::mcset ja {Limits} [encoding convertfrom euc-jp "\xbe\xe5\xb2\xbc\xb8\xc2"] ::msgcat::mcset ja {Line Plot Tool} ::msgcat::mcset ja {Linear} [encoding convertfrom euc-jp "\xc0\xfe\xb7\xc1"] ::msgcat::mcset ja {Line} [encoding convertfrom euc-jp "\xc0\xfe"] ::msgcat::mcset ja {List Data} ::msgcat::mcset ja {List Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xf2\xce\xf3\xb5\xf3"] ::msgcat::mcset ja {List} [encoding convertfrom euc-jp "\xce\xf3\xb5\xf3"] ::msgcat::mcset ja {Load Analysis Commands} [encoding convertfrom euc-jp "\xb2\xf2\xc0\xcf\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Color Tags} ::msgcat::mcset ja {Load Colormap} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Configuration} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Contour Levels} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa5\xec\xa5\xd9\xa5\xeb\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Contours} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Contrast/Bias} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xe9\xa5\xb9\xa5\xc8\xa1\xa6\xa5\xd0\xa5\xa4\xa5\xa2\xa5\xb9\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Data} [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Mosaic} [encoding convertfrom euc-jp "\xa5\xe2\xa5\xb6\xa5\xa4\xa5\xaf\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load Template} [encoding convertfrom euc-jp "\xbf\xf7\xb7\xc1\xa4\xce\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load into All Frames} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xcb\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Load into Current Frame} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xc3\xe6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xcb\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Loading Catalog} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa4\xf2\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf\xc3\xe6"] ::msgcat::mcset ja {Loading} [encoding convertfrom euc-jp "\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf\xc3\xe6"] ::msgcat::mcset ja {Load} [encoding convertfrom euc-jp "\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Local} [encoding convertfrom euc-jp "\xa5\xed\xa1\xbc\xa5\xab\xa5\xeb"] ::msgcat::mcset ja {Lock Bin} ::msgcat::mcset ja {Lock Color} ::msgcat::mcset ja {Lock Crop Amplifier} ::msgcat::mcset ja {Lock Crop Detector} ::msgcat::mcset ja {Lock Crop Image} ::msgcat::mcset ja {Lock Crop None} ::msgcat::mcset ja {Lock Crop Physical} ::msgcat::mcset ja {Lock Crop WCS} ::msgcat::mcset ja {Lock Crosshair Amplifier} ::msgcat::mcset ja {Lock Crosshair Detector} ::msgcat::mcset ja {Lock Crosshair Image} ::msgcat::mcset ja {Lock Crosshair None} ::msgcat::mcset ja {Lock Crosshair Physical} ::msgcat::mcset ja {Lock Crosshair WCS} ::msgcat::mcset ja {Lock Frame Amplifier} ::msgcat::mcset ja {Lock Frame Detector} ::msgcat::mcset ja {Lock Frame Image} ::msgcat::mcset ja {Lock Frame None} ::msgcat::mcset ja {Lock Frame Physical} ::msgcat::mcset ja {Lock Frame WCS} ::msgcat::mcset ja {Lock Scale} ::msgcat::mcset ja {Lock Slice} ::msgcat::mcset ja {Lock Smooth} ::msgcat::mcset ja {Lock} [encoding convertfrom euc-jp "\xb8\xc7\xc4\xea"] ::msgcat::mcset ja {Log Exponent} ::msgcat::mcset ja {Log} [encoding convertfrom euc-jp "\xc2\xd0\xbf\xf4"] ::msgcat::mcset ja {Low High} [encoding convertfrom euc-jp "\xbe\xe5\xb8\xc2\xa1\xa6\xb2\xbc\xb8\xc2"] ::msgcat::mcset ja {Lower Left Back} ::msgcat::mcset ja {Lower Left Front} ::msgcat::mcset ja {Lower Right Back} ::msgcat::mcset ja {Lower Right Front} ::msgcat::mcset ja {Low} [encoding convertfrom euc-jp "\xb2\xbc\xb8\xc2"] ::msgcat::mcset ja {MIP} ::msgcat::mcset ja {Magenta} [encoding convertfrom euc-jp "\xc5\xed\xbf\xa7"] ::msgcat::mcset ja {Magnification} ::msgcat::mcset ja {Magnifier} [encoding convertfrom euc-jp "\xb3\xc8\xc2\xe7\xbf\xde"] ::msgcat::mcset ja {Major} [encoding convertfrom euc-jp "\xc4\xb9\xbc\xb4"] ::msgcat::mcset ja {Manual} [encoding convertfrom euc-jp "\xbc\xea\xc6\xb0"] ::msgcat::mcset ja {Mask Parameters} [encoding convertfrom euc-jp "\xa5\xde\xa5\xb9\xa5\xaf\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Match Bin} ::msgcat::mcset ja {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset ja {Match Color} ::msgcat::mcset ja {Match Crop Amplifier} ::msgcat::mcset ja {Match Crop Detector} ::msgcat::mcset ja {Match Crop Image} ::msgcat::mcset ja {Match Crop Physical} ::msgcat::mcset ja {Match Crop WCS} ::msgcat::mcset ja {Match Crosshair Amplifier} ::msgcat::mcset ja {Match Crosshair Detector} ::msgcat::mcset ja {Match Crosshair Image} ::msgcat::mcset ja {Match Crosshair Physical} ::msgcat::mcset ja {Match Crosshair WCS} ::msgcat::mcset ja {Match Frame Amplifier} ::msgcat::mcset ja {Match Frame Detector} ::msgcat::mcset ja {Match Frame Image} ::msgcat::mcset ja {Match Frame Physical} ::msgcat::mcset ja {Match Frame WCS} ::msgcat::mcset ja {Match Scale} ::msgcat::mcset ja {Match Slice} ::msgcat::mcset ja {Match Smooth} ::msgcat::mcset ja {Match} ::msgcat::mcset ja {Math Function} [encoding convertfrom euc-jp "\xb4\xd8\xbf\xf4"] ::msgcat::mcset ja {Max Rows} [encoding convertfrom euc-jp "\xba\xc7\xc2\xe7\xb9\xd4\xbf\xf4"] ::msgcat::mcset ja {Max} [encoding convertfrom euc-jp "\xba\xc7\xc2\xe7"] ::msgcat::mcset ja {Menus and Buttons} ::msgcat::mcset ja {Menu} [encoding convertfrom euc-jp "\xa5\xe1\xa5\xcb\xa5\xe5\xa1\xbc"] ::msgcat::mcset ja {Message Log} [encoding convertfrom euc-jp "\xa5\xe1\xa5\xc3\xa5\xbb\xa1\xbc\xa5\xb8\xa4\xce\xb5\xad\xcf\xbf"] ::msgcat::mcset ja {Method} [encoding convertfrom euc-jp "\xb7\xd7\xbb\xbb\xcb\xa1"] ::msgcat::mcset ja {Min Max Parameters} [encoding convertfrom euc-jp "\xba\xc7\xc2\xe7\xa1\xa6\xba\xc7\xbe\xae\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Min Max} [encoding convertfrom euc-jp "\xba\xc7\xc2\xe7\xa1\xa6\xba\xc7\xbe\xae"] ::msgcat::mcset ja {Minor} [encoding convertfrom euc-jp "\xc3\xbb\xbc\xb4"] ::msgcat::mcset ja {Minutes} ::msgcat::mcset ja {Min} [encoding convertfrom euc-jp "\xba\xc7\xbe\xae"] ::msgcat::mcset ja {Mission} [encoding convertfrom euc-jp "\xa5\xdf\xa5\xc3\xa5\xb7\xa5\xe7\xa5\xf3"] ::msgcat::mcset ja {Mode} ::msgcat::mcset ja {Mosaic IRAF Segment} ::msgcat::mcset ja {Mosaic IRAF} ::msgcat::mcset ja {Mosaic WCS Segment} ::msgcat::mcset ja {Mosaic WCS} ::msgcat::mcset ja {Mosaic WFPC2} ::msgcat::mcset ja {Mosaic} ::msgcat::mcset ja {Mouse & Keyboard} ::msgcat::mcset ja {Mouse Wheel Bin} ::msgcat::mcset ja {Mouse Wheel Zoom} ::msgcat::mcset ja {Move Back} [encoding convertfrom euc-jp "\xc1\xb0\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move First} [encoding convertfrom euc-jp "\xba\xc7\xbd\xe9\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move Forward} [encoding convertfrom euc-jp "\xbc\xa1\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move Last} [encoding convertfrom euc-jp "\xba\xc7\xb8\xe5\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move to Back} [encoding convertfrom euc-jp "\xc7\xd8\xcc\xcc\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Move to Front} [encoding convertfrom euc-jp "\xc1\xb0\xcc\xcc\xa4\xcb\xb0\xdc\xc6\xb0"] ::msgcat::mcset ja {Movie} ::msgcat::mcset ja {Multiple Extension Cube} ::msgcat::mcset ja {Multiple Extension Frames} ::msgcat::mcset ja {Multiple WCS} [encoding convertfrom euc-jp "\xca\xa3\xbf\xf4\x57\x43\x53"] ::msgcat::mcset ja {NRRD} ::msgcat::mcset ja {Name Resolution} [encoding convertfrom euc-jp "\xcc\xbe\xc1\xb0\xa4\xc7\xb8\xa1\xba\xf7"] ::msgcat::mcset ja {Name Server} [encoding convertfrom euc-jp "\xc5\xb7\xc2\xce\xcc\xbe\xb8\xa1\xba\xf7\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Name or Designation} [encoding convertfrom euc-jp "\xc5\xb7\xc2\xce\xcc\xbe"] ::msgcat::mcset ja {Name} ::msgcat::mcset ja {Native Dialog} ::msgcat::mcset ja {Native} ::msgcat::mcset ja {New 3D} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\x33\x44"] ::msgcat::mcset ja {New Features} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\xb5\xa1\xc7\xbd"] ::msgcat::mcset ja {New Frame 3D} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\x33\x44\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {New Frame RGB} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\x52\x47\x42\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {New Frame each Time} [encoding convertfrom euc-jp "\xcb\xe8\xb2\xf3\xbf\xb7\xa4\xb7\xa4\xa4\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xba\xee\xc0\xae"] ::msgcat::mcset ja {New Frame} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {New Group} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7"] ::msgcat::mcset ja {New RGB} [encoding convertfrom euc-jp "\xbf\xb7\xa4\xb7\xa4\xa4\x20\x52\x47\x42"] ::msgcat::mcset ja {New} [encoding convertfrom euc-jp "\xbf\xb7\xb5\xac"] ::msgcat::mcset ja {Next Frame} [encoding convertfrom euc-jp "\xbc\xa1\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Next} [encoding convertfrom euc-jp "\xbf\xca\xa4\xe0"] ::msgcat::mcset ja {No Catalog specified} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa4\xac\xbb\xd8\xc4\xea\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {No Items Found} [encoding convertfrom euc-jp "\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3\xa4\xc7\xa4\xb7\xa4\xbf\xa1\xa3"] ::msgcat::mcset ja {No current frame} ::msgcat::mcset ja {No data available at } [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3\x20\x3a\x20"] ::msgcat::mcset ja {Non-zero} [encoding convertfrom euc-jp "\xc8\xf3\xce\xed\xc3\xcd"] ::msgcat::mcset ja {None} [encoding convertfrom euc-jp "\xa4\xca\xa4\xb7"] ::msgcat::mcset ja {Normal} [encoding convertfrom euc-jp "\xc9\xb8\xbd\xe0"] ::msgcat::mcset ja {North} [encoding convertfrom euc-jp "\xcb\xcc"] ::msgcat::mcset ja {Not Found} ::msgcat::mcset ja {No} [encoding convertfrom euc-jp "\xa4\xa4\xa4\xa4\xa4\xa8"] ::msgcat::mcset ja {Number of Samples} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xf3\xa5\xd7\xa5\xeb\xa4\xce\xbf\xf4"] ::msgcat::mcset ja {Number of Threads} ::msgcat::mcset ja {Number of Ticks} ::msgcat::mcset ja {Number} [encoding convertfrom euc-jp "\xc8\xd6\xb9\xe6"] ::msgcat::mcset ja {Numerics} [encoding convertfrom euc-jp "\xbf\xf4\xc3\xcd"] ::msgcat::mcset ja {OK} [encoding convertfrom euc-jp "\xce\xbb\xb2\xf2"] ::msgcat::mcset ja {Object} [encoding convertfrom euc-jp "\xc5\xb7\xc2\xce\xcc\xbe"] ::msgcat::mcset ja {Open File} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xf2\xb3\xab\xa4\xaf"] ::msgcat::mcset ja {Open TCL Console} [encoding convertfrom euc-jp "\x54\x43\x4c\x20\xa5\xb3\xa5\xf3\xa5\xbd\xa1\xbc\xa5\xeb\xa4\xf2\xb3\xab\xa4\xaf"] ::msgcat::mcset ja {Open URL} [encoding convertfrom euc-jp "\x55\x52\x4c\x20\xa4\xf2\xb3\xab\xa4\xaf"] ::msgcat::mcset ja {Open as} ::msgcat::mcset ja {Open} [encoding convertfrom euc-jp "\xb3\xab\xa4\xaf"] ::msgcat::mcset ja {Operator} [encoding convertfrom euc-jp "\xb1\xe9\xbb\xbb\xbb\xd2"] ::msgcat::mcset ja {Orientation} [encoding convertfrom euc-jp "\xca\xfd\xb8\xfe"] ::msgcat::mcset ja {Origin} ::msgcat::mcset ja {Oscillate} ::msgcat::mcset ja {Other Color} ::msgcat::mcset ja {Other Font Size} ::msgcat::mcset ja {Other} [encoding convertfrom euc-jp "\xa4\xbd\xa4\xce\xc2\xbe"] ::msgcat::mcset ja {Outer} [encoding convertfrom euc-jp "\xb3\xb0\xb7\xc2"] ::msgcat::mcset ja {PS Page Setup} [encoding convertfrom euc-jp "\x50\x53\xa5\xda\xa1\xbc\xa5\xb8\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {PS Print} [encoding convertfrom euc-jp "\x50\x53\xb0\xf5\xba\xfe"] ::msgcat::mcset ja {Page Setup} [encoding convertfrom euc-jp "\xa5\xda\xa1\xbc\xa5\xb8\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Page Source} [encoding convertfrom euc-jp "\xa5\xda\xa1\xbc\xa5\xb8\xa4\xce\xa5\xbd\xa1\xbc\xa5\xb9"] ::msgcat::mcset ja {Pan To} [encoding convertfrom euc-jp "\xa4\xbd\xa4\xb3\xa4\xcb\xa5\xd1\xa5\xf3"] ::msgcat::mcset ja {Pan Zoom Rotate Parameters} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xf3\xa1\xa6\xa5\xba\xa1\xbc\xa5\xe0\xa1\xa6\xb2\xf3\xc5\xbe\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Pan Zoom} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xf3\xa1\xa6\xa5\xba\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Pan then Zoom} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xf3\xa4\xce\xa4\xc1\xa5\xba\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Panda} [encoding convertfrom euc-jp "\xc9\xf4\xca\xac\xb1\xdf"] ::msgcat::mcset ja {Panner} [encoding convertfrom euc-jp "\xc1\xb4\xc2\xce\xbf\xde"] ::msgcat::mcset ja {Pan} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xf3"] ::msgcat::mcset ja {Parameters} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xe9\xa5\xe1\xa1\xbc\xa5\xbf"] ::msgcat::mcset ja {Password} [encoding convertfrom euc-jp "\xa5\xd1\xa5\xb9\xa5\xef\xa1\xbc\xa5\xc9"] ::msgcat::mcset ja {Paste Contours} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa4\xf2\xc5\xbd\xa4\xea\xc9\xd5\xa4\xb1"] ::msgcat::mcset ja {Paste} [encoding convertfrom euc-jp "\xc5\xbd\xa4\xea\xc9\xd5\xa4\xb1"] ::msgcat::mcset ja {Physical} [encoding convertfrom euc-jp "\xca\xaa\xcd\xfd\xba\xc2\xc9\xb8"] ::msgcat::mcset ja {Pixel Distribution} [encoding convertfrom euc-jp "\xa5\xd4\xa5\xaf\xa5\xbb\xa5\xeb\xc9\xd1\xc5\xd9\xca\xac\xc9\xdb"] ::msgcat::mcset ja {Pixel Size} [encoding convertfrom euc-jp "\xa5\xd4\xa5\xaf\xa5\xbb\xa5\xeb\xa5\xb5\xa5\xa4\xa5\xba"] ::msgcat::mcset ja {Pixel Table} [encoding convertfrom euc-jp "\xa5\xd4\xa5\xaf\xa5\xbb\xa5\xeb\xc9\xbd"] ::msgcat::mcset ja {Pixels} [encoding convertfrom euc-jp "\xa5\xd4\xa5\xaf\xa5\xbb\xa5\xeb"] ::msgcat::mcset ja {Play} [encoding convertfrom euc-jp "\xba\xc6\xc0\xb8"] ::msgcat::mcset ja {Please Select a Region} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xf2\xbb\xd8\xc4\xea\xa4\xb7\xa4\xc6\xa4\xaf\xa4\xc0\xa4\xb5\xa4\xa4\xa1\xa3"] ::msgcat::mcset ja {Please specify width, height, and either name or (ra,dec)} [encoding convertfrom euc-jp "\xc9\xfd\xa1\xa2\xb9\xe2\xa4\xb5\xa1\xa2\xcc\xbe\xc1\xb0\xa4\xe2\xa4\xb7\xa4\xaf\xa4\xcf\x20\x28\x72\x61\x2c\x64\x65\x63\x29\x20\xa4\xf2\xbb\xd8\xc4\xea\xa4\xb7\xa4\xc6\xa4\xaf\xa4\xc0\xa4\xb5\xa4\xa4\xa1\xa3"] ::msgcat::mcset ja {Plot 2D} ::msgcat::mcset ja {Plot 3D} ::msgcat::mcset ja {Plot Title} [encoding convertfrom euc-jp "\xa5\xbf\xa5\xa4\xa5\xc8\xa5\xeb\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Plotting Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xf2\xa5\xd7\xa5\xed\xa5\xc3\xa5\xc8\xa4\xb7\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9"] ::msgcat::mcset ja {Plot} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xed\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Plus} [encoding convertfrom euc-jp "\xa1\xdc"] ::msgcat::mcset ja {Pointer} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xa4\xa5\xf3\xa5\xbf"] ::msgcat::mcset ja {Points} [encoding convertfrom euc-jp "\xc5\xc0"] ::msgcat::mcset ja {Point} [encoding convertfrom euc-jp "\xc5\xc0"] ::msgcat::mcset ja {Polygon} [encoding convertfrom euc-jp "\xc2\xbf\xb3\xd1\xb7\xc1"] ::msgcat::mcset ja {Portrait} [encoding convertfrom euc-jp "\xbd\xc4\xc4\xb9"] ::msgcat::mcset ja {Poster} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xb9\xa5\xbf\xa1\xbc"] ::msgcat::mcset ja {Postscript Page Setup} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xb9\xa5\xc8\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xa5\xda\xa1\xbc\xa5\xb8\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Postscript Print} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xb9\xa5\xc8\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xb0\xf5\xba\xfe"] ::msgcat::mcset ja {Postscript} [encoding convertfrom euc-jp "\xa5\xdd\xa5\xb9\xa5\xc8\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8"] ::msgcat::mcset ja {Power} [encoding convertfrom euc-jp "\xd1\xd1\xbe\xe8"] ::msgcat::mcset ja {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa4\xcf\xbd\xe9\xb4\xfc\xb2\xbd\xa4\xb5\xa4\xec\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3\xca\xd1\xb9\xb9\xa4\xf2\xcd\xad\xb8\xfa\xa4\xcb\xa4\xb9\xa4\xeb\xa4\xcb\xa4\xcf\xa1\xa2\x44\x53\x39\xa4\xf2\xba\xc6\xb5\xaf\xc6\xb0\xa4\xb7\xa4\xc6\xa4\xaf\xa4\xc0\xa4\xb5\xa4\xa4\xa1\xa3"] ::msgcat::mcset ja {Preferences} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Preserve During Load} [encoding convertfrom euc-jp "\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf\xc3\xe6\xa4\xcb\xca\xdd\xbb\xfd"] ::msgcat::mcset ja {Previous Frame} [encoding convertfrom euc-jp "\xc1\xb0\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Previous} [encoding convertfrom euc-jp "\xcc\xe1\xa4\xeb"] ::msgcat::mcset ja {Print Coordinates} [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8\xa4\xf2\xb0\xf5\xba\xfe"] ::msgcat::mcset ja {Print To} [encoding convertfrom euc-jp "\xbd\xd0\xce\xcf\xc0\xe8"] ::msgcat::mcset ja {Printer} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xea\xa5\xf3\xa5\xbf"] ::msgcat::mcset ja {Print} [encoding convertfrom euc-jp "\xb0\xf5\xba\xfe"] ::msgcat::mcset ja {Projection} [encoding convertfrom euc-jp "\xc0\xda\xc3\xc7\xcc\xcc"] ::msgcat::mcset ja {Properties} [encoding convertfrom euc-jp "\xc2\xb0\xc0\xad"] ::msgcat::mcset ja {Property} [encoding convertfrom euc-jp "\xc2\xb0\xc0\xad"] ::msgcat::mcset ja {Proxy Host} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xed\xa5\xad\xa5\xb7\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Proxy Port} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xed\xa5\xad\xa5\xb7\xa5\xdd\xa1\xbc\xa5\xc8"] ::msgcat::mcset ja {Publication} [encoding convertfrom euc-jp "\xcf\xc0\xca\xb8"] ::msgcat::mcset ja {Quadratic} ::msgcat::mcset ja {RGB Array} ::msgcat::mcset ja {RGB Cube} ::msgcat::mcset ja {RGB Image} ::msgcat::mcset ja {RGB} [encoding convertfrom euc-jp "\x52\x47\x42\xbf\xa7"] ::msgcat::mcset ja {Radial Profile} ::msgcat::mcset ja {Radius} [encoding convertfrom euc-jp "\xc8\xbe\xb7\xc2"] ::msgcat::mcset ja {Range} ::msgcat::mcset ja {Redo} [encoding convertfrom euc-jp "\xa4\xe2\xa4\xa6\xb0\xec\xc5\xd9"] ::msgcat::mcset ja {Red} [encoding convertfrom euc-jp "\xc0\xd6\xbf\xa7"] ::msgcat::mcset ja {Reference Manual} [encoding convertfrom euc-jp "\xa5\xea\xa5\xd5\xa5\xa1\xa5\xec\xa5\xf3\xa5\xb9\xa5\xde\xa5\xcb\xa5\xe5\xa5\xa2\xa5\xeb"] ::msgcat::mcset ja {Reference} [encoding convertfrom euc-jp "\xa5\xea\xa5\xd5\xa5\xa1\xa5\xec\xa5\xf3\xa5\xb9"] ::msgcat::mcset ja {Refresh Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xba\xc6\xc9\xc1\xb2\xe8"] ::msgcat::mcset ja {Refresh} [encoding convertfrom euc-jp "\xba\xc6\xc9\xc1\xb2\xe8"] ::msgcat::mcset ja {Region Parameters} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Region} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8"] ::msgcat::mcset ja {Release Notes} [encoding convertfrom euc-jp "\xa5\xea\xa5\xea\xa1\xbc\xa5\xb9\xa5\xce\xa1\xbc\xa5\xc8"] ::msgcat::mcset ja {Release} [encoding convertfrom euc-jp "\xa5\xea\xa5\xea\xa1\xbc\xa5\xb9"] ::msgcat::mcset ja {Reload} [encoding convertfrom euc-jp "\xba\xc6\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xdf"] ::msgcat::mcset ja {Repeat} ::msgcat::mcset ja {Reset Colormap} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4\xa4\xf2\xa5\xea\xa5\xbb\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Reset Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xa5\xea\xa5\xbb\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Reset} [encoding convertfrom euc-jp "\xa5\xea\xa5\xbb\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {Restore} ::msgcat::mcset ja {Retrieve} [encoding convertfrom euc-jp "\xb8\xa1\xba\xf7"] ::msgcat::mcset ja {Return} ::msgcat::mcset ja {Right} ::msgcat::mcset ja {Roman} ::msgcat::mcset ja {Rotate} [encoding convertfrom euc-jp "\xb2\xf3\xc5\xbe"] ::msgcat::mcset ja {Rows} [encoding convertfrom euc-jp "\xb9\xd4"] ::msgcat::mcset ja {Row} ::msgcat::mcset ja {Ruler} [encoding convertfrom euc-jp "\xa4\xe2\xa4\xce\xa4\xb5\xa4\xb7"] ::msgcat::mcset ja {SAMP Image} ::msgcat::mcset ja {SAMP Table} ::msgcat::mcset ja {SAMP: already connected} [encoding convertfrom euc-jp "\x53\x41\x4d\x50\x3a\x20\xc0\xdc\xc2\xb3\xa4\xba\xa4\xdf"] ::msgcat::mcset ja {SAMP: internal error} [encoding convertfrom euc-jp "\x53\x41\x4d\x50\x3a\x20\xc6\xe2\xc9\xf4\xa5\xa8\xa5\xe9\xa1\xbc"] ::msgcat::mcset ja {SAMP: not connected} [encoding convertfrom euc-jp "\x53\x41\x4d\x50\x3a\x20\xcc\xa4\xc0\xdc\xc2\xb3"] ::msgcat::mcset ja {SAMP: unable to locate HUB} [encoding convertfrom euc-jp "\x53\x41\x4d\x50\x3a\x20\x48\x55\x42\x20\xa4\xf2\xb8\xab\xa4\xc4\xa4\xb1\xa4\xe9\xa4\xec\xa4\xde\xa4\xbb\xa4\xf3"] ::msgcat::mcset ja {SAMP} [encoding convertfrom euc-jp "\x53\x41\x4d\x50"] ::msgcat::mcset ja {Sample Increment} [encoding convertfrom euc-jp "\xa4\xc8\xa4\xd0\xa4\xb7\xc6\xc9\xa4\xdf\xa4\xce\xb4\xd6\xb3\xd6"] ::msgcat::mcset ja {Sample Parameters} [encoding convertfrom euc-jp "\xa4\xc8\xa4\xd0\xa4\xb7\xc6\xc9\xa4\xdf\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Samples per Line} [encoding convertfrom euc-jp "\xa3\xb1\xb9\xd4\xa4\xa2\xa4\xbf\xa4\xea\xa4\xce\xa5\xb5\xa5\xf3\xa5\xd7\xa5\xeb"] ::msgcat::mcset ja {Sample} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xf3\xa5\xd7\xa5\xeb"] ::msgcat::mcset ja {Save 3D Movie} ::msgcat::mcset ja {Save Color Tags} ::msgcat::mcset ja {Save Colormap} [encoding convertfrom euc-jp "\xbf\xa7\xc4\xb4\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Configuration} [encoding convertfrom euc-jp "\xc0\xdf\xc4\xea\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Contour Levels} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa5\xec\xa5\xd9\xa5\xeb\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Contours} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xa2\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Contrast/Bias} [encoding convertfrom euc-jp "\xa5\xb3\xa5\xf3\xa5\xc8\xa5\xe9\xa5\xb9\xa5\xc8\xa1\xa6\xa5\xd0\xa5\xa4\xa5\xa2\xa5\xb9\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Data} [encoding convertfrom euc-jp "\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Image on Download} ::msgcat::mcset ja {Save Image} [encoding convertfrom euc-jp "\xa5\xa4\xa5\xe1\xa1\xbc\xa5\xb8\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Regions} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save Template} [encoding convertfrom euc-jp "\xbf\xf7\xb7\xc1\xa4\xf2\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Save as} ::msgcat::mcset ja {Save} [encoding convertfrom euc-jp "\xca\xdd\xc2\xb8"] ::msgcat::mcset ja {Scale Parameters} [encoding convertfrom euc-jp "\xa5\xb9\xa5\xb1\xa1\xbc\xa5\xeb\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Scale} [encoding convertfrom euc-jp "\xa5\xb9\xa5\xb1\xa1\xbc\xa5\xeb"] ::msgcat::mcset ja {Scan} [encoding convertfrom euc-jp "\xa5\xb9\xa5\xad\xa5\xe3\xa5\xf3"] ::msgcat::mcset ja {Scatter Plot Tool} ::msgcat::mcset ja {Scope} [encoding convertfrom euc-jp "\xa5\xb9\xa5\xb3\xa1\xbc\xa5\xd7"] ::msgcat::mcset ja {Search for Catalogs} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa4\xf2\xb8\xa1\xba\xf7"] ::msgcat::mcset ja {Searching for catalogs} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa4\xf2\xb8\xa1\xba\xf7\xc3\xe6"] ::msgcat::mcset ja {Seconds} [encoding convertfrom euc-jp "\xc9\xc3"] ::msgcat::mcset ja {Select All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xc1\xaa\xc2\xf2"] ::msgcat::mcset ja {Select Coordinate System } [encoding convertfrom euc-jp "\xba\xc2\xc9\xb8\xb7\xcf\xa4\xf2\xc1\xaa\xc2\xf2"] ::msgcat::mcset ja {Select None} [encoding convertfrom euc-jp "\xc1\xaa\xc2\xf2\xa4\xf2\xb2\xf2\xbd\xfc"] ::msgcat::mcset ja {Send} [encoding convertfrom euc-jp "\xc1\xf7\xbf\xae"] ::msgcat::mcset ja {Server} [encoding convertfrom euc-jp "\xa5\xb5\xa1\xbc\xa5\xd0\xa1\xbc"] ::msgcat::mcset ja {Sexagesimal} [encoding convertfrom euc-jp "\xbb\xfe\xca\xac\xc9\xc3"] ::msgcat::mcset ja {Shape} [encoding convertfrom euc-jp "\xb7\xc1"] ::msgcat::mcset ja {Show All} [encoding convertfrom euc-jp "\xc1\xb4\xa4\xc6\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Show Command} ::msgcat::mcset ja {Show Compass} ::msgcat::mcset ja {Show Text} [encoding convertfrom euc-jp "\xca\xb8\xbb\xfa\xa4\xf2\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Show/Hide Frames} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xce\xc9\xbd\xbc\xa8\x2f\xc8\xf3\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Show} [encoding convertfrom euc-jp "\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Single Frame} [encoding convertfrom euc-jp "\xc3\xb1\xb0\xec\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {Single} [encoding convertfrom euc-jp "\xc3\xb1\xb0\xec"] ::msgcat::mcset ja {Sites} ::msgcat::mcset ja {Size/Radius} [encoding convertfrom euc-jp "\xc2\xe7\xa4\xad\xa4\xb5\x2f\xc8\xbe\xb7\xc2"] ::msgcat::mcset ja {Size} [encoding convertfrom euc-jp "\xc2\xe7\xa4\xad\xa4\xb5"] ::msgcat::mcset ja {Skip First} ::msgcat::mcset ja {Slice} ::msgcat::mcset ja {Smooth Parameters} [encoding convertfrom euc-jp "\xca\xbf\xb3\xea\xb2\xbd\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Smoothness} ::msgcat::mcset ja {Smooth} [encoding convertfrom euc-jp "\xca\xbf\xb3\xea\xb2\xbd"] ::msgcat::mcset ja {Sorry, DS9 does not support} [encoding convertfrom euc-jp "\x44\x53\x39\x20\xa4\xc7\xa5\xb5\xa5\xdd\xa1\xbc\xa5\xc8\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} [encoding convertfrom euc-jp "\x44\x53\x39\x20\xa4\xcf\x20\x50\x73\x65\x75\x64\x6f\x63\x6f\x6c\x6f\x72\x38\x2c\x20\x54\x72\x75\x65\x63\x6f\x6c\x6f\x72\x38\x2c\x20\x54\x72\x75\x65\x63\x6f\x6c\x6f\x72\x31\x36\x2c\x20\x54\x72\x75\x65\x63\x6f\x6c\x6f\x72\x32\x34\x20\xa4\xce\xa4\xa4\xa4\xba\xa4\xec\xa4\xab\xa4\xce\xc9\xbd\xbc\xa8\xa4\xac\xc9\xac\xcd\xd7\xa4\xc7\xa4\xb9\xa1\xa3"] ::msgcat::mcset ja {Sort} [encoding convertfrom euc-jp "\xca\xc2\xa4\xd9\xc2\xd8\xa4\xa8"] ::msgcat::mcset ja {Source TCL} [encoding convertfrom euc-jp "\x54\x43\x4c\x20\xa4\xf2\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xe0"] ::msgcat::mcset ja {Source} [encoding convertfrom euc-jp "\xa5\xbd\xa1\xbc\xa5\xb9\xce\xce\xb0\xe8"] ::msgcat::mcset ja {Space Equal Distance} ::msgcat::mcset ja {Space Equal Value} ::msgcat::mcset ja {Spacing} ::msgcat::mcset ja {Square Root} [encoding convertfrom euc-jp "\xca\xbf\xca\xfd\xba\xac"] ::msgcat::mcset ja {Squared} [encoding convertfrom euc-jp "\xca\xbf\xca\xfd"] ::msgcat::mcset ja {Starbase} ::msgcat::mcset ja {Startup} ::msgcat::mcset ja {Start} [encoding convertfrom euc-jp "\xb3\xab\xbb\xcf"] ::msgcat::mcset ja {Statistics} ::msgcat::mcset ja {Status} [encoding convertfrom euc-jp "\xbe\xf5\xc2\xd6"] ::msgcat::mcset ja {Step} [encoding convertfrom euc-jp "\xa5\xb9\xa5\xc6\xa5\xc3\xa5\xd7"] ::msgcat::mcset ja {Stop} [encoding convertfrom euc-jp "\xbd\xaa\xce\xbb"] ::msgcat::mcset ja {Story of SAOImage DS9} ::msgcat::mcset ja {Story} ::msgcat::mcset ja {Sum} [encoding convertfrom euc-jp "\xb9\xe7\xb7\xd7"] ::msgcat::mcset ja {Symbol Editor} [encoding convertfrom euc-jp "\xb5\xad\xb9\xe6\xa4\xce\xca\xd4\xbd\xb8"] ::msgcat::mcset ja {Symbol} [encoding convertfrom euc-jp "\xb5\xad\xb9\xe6"] ::msgcat::mcset ja {Tab-Separated-Value} [encoding convertfrom euc-jp "\xa5\xbf\xa5\xd6\xca\xac\xb3\xe4\xb5\xad\xcb\xa1"] ::msgcat::mcset ja {Table} ::msgcat::mcset ja {Tabloid} [encoding convertfrom euc-jp "\xa5\xbf\xa5\xd6\xa5\xed\xa5\xa4\xa5\xc9"] ::msgcat::mcset ja {Template} [encoding convertfrom euc-jp "\xbf\xf7\xb7\xc1"] ::msgcat::mcset ja {Text Font} ::msgcat::mcset ja {Text} [encoding convertfrom euc-jp "\xca\xb8\xbb\xfa"] ::msgcat::mcset ja {Theme} ::msgcat::mcset ja {Then} [encoding convertfrom euc-jp "\xa4\xca\xa4\xe9"] ::msgcat::mcset ja {Thickness} [encoding convertfrom euc-jp "\xc2\xc0\xa4\xb5"] ::msgcat::mcset ja {This analysis task is already running. Do you wish to kill it?} [encoding convertfrom euc-jp "\xa4\xb3\xa4\xce\xb2\xf2\xc0\xcf\xa5\xbf\xa5\xb9\xa5\xaf\xa4\xcf\xa4\xb9\xa4\xc7\xa4\xcb\xbc\xc2\xb9\xd4\xc3\xe6\xa4\xc7\xa4\xb9\xa1\xa3\xc3\xe6\xc3\xc7\xa4\xb7\xa4\xde\xa4\xb9\xa4\xab\x3f"] ::msgcat::mcset ja {Tickmarks} [encoding convertfrom euc-jp "\xcc\xdc\xc0\xb9\xa4\xea"] ::msgcat::mcset ja {Tile Frames} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xca\xc2\xa4\xd9\xa4\xeb"] ::msgcat::mcset ja {Tile Parameters} [encoding convertfrom euc-jp "\xca\xc2\xa4\xd9\xca\xfd\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Tile} [encoding convertfrom euc-jp "\xca\xc2\xa4\xd9\xa4\xc6\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Times} ::msgcat::mcset ja {Title} [encoding convertfrom euc-jp "\xa5\xbf\xa5\xa4\xa5\xc8\xa5\xeb"] ::msgcat::mcset ja {To Fit} [encoding convertfrom euc-jp "\xb2\xe8\xcc\xcc\xb0\xec\xc7\xd5"] ::msgcat::mcset ja {Tophat} [encoding convertfrom euc-jp "\xa5\xc8\xa5\xc3\xa5\xd7\xa5\xcf\xa5\xc3\xa5\xc8"] ::msgcat::mcset ja {To} ::msgcat::mcset ja {Transparency} [encoding convertfrom euc-jp "\xc6\xa9\xcc\xc0"] ::msgcat::mcset ja {Type} [encoding convertfrom euc-jp "\xbc\xef\xce\xe0"] ::msgcat::mcset ja {URL} ::msgcat::mcset ja {Unable to connect directly: using Web Proxy} ::msgcat::mcset ja {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset ja {Unable to determine date of observation} ::msgcat::mcset ja {Unable to determine time of observation} ::msgcat::mcset ja {Unable to evaluate filter} [encoding convertfrom euc-jp "\xb9\xca\xa4\xea\xb9\xfe\xa4\xdf\xbe\xf2\xb7\xef\xa4\xac\xc9\xbe\xb2\xc1\xa4\xc7\xa4\xad\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to find catalog window} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa5\xa6\xa5\xa3\xa5\xf3\xa5\xc9\xa5\xa6\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to find plot window} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xed\xa5\xc3\xa5\xc8\xa5\xa6\xa5\xa3\xa5\xf3\xa5\xc9\xa5\xa6\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to load RGB image into a non-rgb frame} [encoding convertfrom euc-jp "\x52\x42\x47\xa5\xa4\xa5\xe1\xa1\xbc\xa5\xb8\xa4\xf2\xc8\xf3\x52\x47\x42\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xcb\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xe1\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to load region file} [encoding convertfrom euc-jp "\xce\xce\xb0\xe8\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xf2\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xe1\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to load} [encoding convertfrom euc-jp "\xc6\xc9\xa4\xdf\xb9\xfe\xa4\xe1\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to locate URL} [encoding convertfrom euc-jp "\x55\x52\x4c\xa4\xf2\xc6\xc3\xc4\xea\xa4\xc7\xa4\xad\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to match target with XPA Mime request} ::msgcat::mcset ja {Unable to open file} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xa1\xa5\xa4\xa5\xeb\xa4\xf2\xb3\xab\xa4\xb1\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset ja {Undo} [encoding convertfrom euc-jp "\xa4\xe4\xa4\xea\xc4\xbe\xa4\xb7"] ::msgcat::mcset ja {Unique} ::msgcat::mcset ja {Units} [encoding convertfrom euc-jp "\xc3\xb1\xb0\xcc"] ::msgcat::mcset ja {Unknown Colormap} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xdd\xa1\xbc\xa5\xc8\xa4\xb5\xa4\xec\xa4\xca\xa4\xa4\xc7\xdb\xbf\xa7"] ::msgcat::mcset ja {Unknown command} [encoding convertfrom euc-jp "\xa5\xb5\xa5\xdd\xa1\xbc\xa5\xc8\xa4\xb5\xa4\xec\xa4\xca\xa4\xa4\xa5\xb3\xa5\xde\xa5\xf3\xa5\xc9"] ::msgcat::mcset ja {Update Filter} [encoding convertfrom euc-jp "\xb8\xa1\xba\xf7\xbe\xf2\xb7\xef\xa4\xf2\xb9\xb9\xbf\xb7"] ::msgcat::mcset ja {Update Group} [encoding convertfrom euc-jp "\xa5\xb0\xa5\xeb\xa1\xbc\xa5\xd7\xa4\xf2\xb9\xb9\xbf\xb7"] ::msgcat::mcset ja {Update from Current Crosshair} [encoding convertfrom euc-jp "\xb8\xbd\xba\xdf\xa4\xce\xbd\xbd\xbb\xfa\xa5\xab\xa1\xbc\xa5\xbd\xa5\xeb\xb0\xcc\xc3\xd6\xa4\xab\xa4\xe9\xb9\xb9\xbf\xb7"] ::msgcat::mcset ja {Update from Current Frame} [encoding convertfrom euc-jp "\xb8\xbd\xba\xdf\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xab\xa4\xe9\xb9\xb9\xbf\xb7"] ::msgcat::mcset ja {Update} [encoding convertfrom euc-jp "\xb9\xb9\xbf\xb7"] ::msgcat::mcset ja {Upper Left Back} ::msgcat::mcset ja {Upper Left Front} ::msgcat::mcset ja {Upper Right Back} ::msgcat::mcset ja {Upper Right Front} ::msgcat::mcset ja {Use Authentication} [encoding convertfrom euc-jp "\xc7\xa7\xbe\xda\xa4\xf2\xbb\xc8\xcd\xd1"] ::msgcat::mcset ja {Use Current Frame on Download} [encoding convertfrom euc-jp "\xa5\xc0\xa5\xa6\xa5\xf3\xa5\xed\xa1\xbc\xa5\xc9\xbb\xfe\xa4\xcb\xc1\xaa\xc2\xf2\xc3\xe6\xa4\xce\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xa4\xf2\xbb\xc8\xcd\xd1"] ::msgcat::mcset ja {Use Internal Web Browser} [encoding convertfrom euc-jp "\xc6\xe2\xc9\xf4\xa5\xd6\xa5\xe9\xa5\xa6\xa5\xb6\xa4\xf2\xbb\xc8\xcd\xd1"] ::msgcat::mcset ja {Use Proxy} [encoding convertfrom euc-jp "\xa5\xd7\xa5\xed\xa5\xad\xa5\xb7\xa4\xf2\xbb\xc8\xcd\xd1"] ::msgcat::mcset ja {User Manual} [encoding convertfrom euc-jp "\xa5\xe6\xa1\xbc\xa5\xb6\xa1\xbc\xa5\xde\xa5\xcb\xa5\xe5\xa5\xa2\xa5\xeb"] ::msgcat::mcset ja {Username} [encoding convertfrom euc-jp "\xa5\xe6\xa1\xbc\xa5\xb6\xa1\xbc\xcc\xbe"] ::msgcat::mcset ja {User} [encoding convertfrom euc-jp "\xa5\xe6\xa1\xbc\xa5\xb6\xa1\xbc"] ::msgcat::mcset ja {Use} [encoding convertfrom euc-jp "\xbb\xc8\xcd\xd1"] ::msgcat::mcset ja {VO Server} ::msgcat::mcset ja {VO} [encoding convertfrom euc-jp "\xb2\xbe\xc1\xdb\xc5\xb7\xca\xb8\xc2\xe6"] ::msgcat::mcset ja {Value} [encoding convertfrom euc-jp "\xc3\xcd"] ::msgcat::mcset ja {Vector} [encoding convertfrom euc-jp "\xa5\xd9\xa5\xaf\xa5\xc8\xa5\xeb"] ::msgcat::mcset ja {Vertical Graph} [encoding convertfrom euc-jp "\xbd\xc4\xc3\xc7\xcc\xcc"] ::msgcat::mcset ja {Vertical Layout} [encoding convertfrom euc-jp "\xb2\xe8\xcc\xcc\xa4\xce\xba\xb8\xa4\xcb\xc7\xdb\xc3\xd6"] ::msgcat::mcset ja {Vertical Text} ::msgcat::mcset ja {Vertical} ::msgcat::mcset ja {View} [encoding convertfrom euc-jp "\xc9\xbd\xbc\xa8"] ::msgcat::mcset ja {Virtual Observatory} [encoding convertfrom euc-jp "\xb2\xbe\xc1\xdb\xc5\xb7\xca\xb8\xc2\xe6"] ::msgcat::mcset ja {WCS Parameters} ::msgcat::mcset ja {WCS} ::msgcat::mcset ja {Wavelength} [encoding convertfrom euc-jp "\xc7\xc8\xc4\xb9"] ::msgcat::mcset ja {Web Browser} [encoding convertfrom euc-jp "\xa5\xd6\xa5\xe9\xa5\xa6\xa5\xb6"] ::msgcat::mcset ja {White} [encoding convertfrom euc-jp "\xc7\xf2\xbf\xa7"] ::msgcat::mcset ja {Width} [encoding convertfrom euc-jp "\xc9\xfd"] ::msgcat::mcset ja {Words matching title, description} ::msgcat::mcset ja {Writing Catalog} [encoding convertfrom euc-jp "\xa5\xab\xa5\xbf\xa5\xed\xa5\xb0\xa4\xf2\xbd\xf1\xa4\xad\xbd\xd0\xa4\xb7\xc3\xe6"] ::msgcat::mcset ja {X Axis Title} ::msgcat::mcset ja {X Axis} ::msgcat::mcset ja {X Grid} ::msgcat::mcset ja {XPA Information} [encoding convertfrom euc-jp "\x58\x50\x41\xa4\xce\xbe\xf0\xca\xf3"] ::msgcat::mcset ja {XPA not initialized} [encoding convertfrom euc-jp "\x58\x50\x41\x20\xa4\xac\xbd\xe9\xb4\xfc\xb2\xbd\xa4\xb5\xa4\xec\xa4\xc6\xa4\xa4\xa4\xde\xa4\xbb\xa4\xf3\xa1\xa3"] ::msgcat::mcset ja {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset ja {XPA} [encoding convertfrom euc-jp "\x58\x50\x41"] ::msgcat::mcset ja {X} ::msgcat::mcset ja {Y Axis Title} ::msgcat::mcset ja {Y Axis} ::msgcat::mcset ja {Y Grid} ::msgcat::mcset ja {Yellow} [encoding convertfrom euc-jp "\xb2\xab\xbf\xa7"] ::msgcat::mcset ja {Yes} [encoding convertfrom euc-jp "\xa4\xcf\xa4\xa4"] ::msgcat::mcset ja {Y} ::msgcat::mcset ja {Z Axis Scale} ::msgcat::mcset ja {ZScale Parameters} [encoding convertfrom euc-jp "\x5a\xa5\xb9\xa5\xb1\xa1\xbc\xa5\xeb\xa4\xce\xc0\xdf\xc4\xea"] ::msgcat::mcset ja {Zero} [encoding convertfrom euc-jp "\xce\xed"] ::msgcat::mcset ja {Zoom In} [encoding convertfrom euc-jp "\xb3\xc8\xc2\xe7"] ::msgcat::mcset ja {Zoom Out} [encoding convertfrom euc-jp "\xbd\xcc\xbe\xae"] ::msgcat::mcset ja {Zoom to Fit Frame} [encoding convertfrom euc-jp "\xa5\xd5\xa5\xec\xa1\xbc\xa5\xe0\xb0\xec\xc7\xd5\xa4\xcb\xb3\xc8\xc2\xe7"] ::msgcat::mcset ja {Zoom} [encoding convertfrom euc-jp "\xa5\xba\xa1\xbc\xa5\xe0"] ::msgcat::mcset ja {and} ::msgcat::mcset ja {blue} ::msgcat::mcset ja {b} ::msgcat::mcset ja {color} ::msgcat::mcset ja {cool} ::msgcat::mcset ja {green} ::msgcat::mcset ja {grey} ::msgcat::mcset ja {g} ::msgcat::mcset ja {heat} ::msgcat::mcset ja {not} ::msgcat::mcset ja {only} ::msgcat::mcset ja {or center of data} [encoding convertfrom euc-jp "\xa4\xe2\xa4\xb7\xa4\xaf\xa4\xcf\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xce\xc3\xe6\xbf\xb4"] ::msgcat::mcset ja {rainbow} ::msgcat::mcset ja {red} ::msgcat::mcset ja {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom euc-jp "\xb9\xd4\xa4\xce\xa5\xc7\xa1\xbc\xa5\xbf\xa4\xac\xa5\xc0\xa5\xa6\xa5\xf3\xa5\xed\xa1\xbc\xa5\xc9\xa4\xb5\xa4\xec\xa4\xde\xa4\xb7\xa4\xbf\xa1\xa3\xa4\xb5\xa4\xe9\xa4\xcb\xa5\xc0\xa5\xa6\xa5\xf3\xa5\xed\xa1\xbc\xa5\xc9\xa4\xb9\xa4\xeb\xbe\xec\xb9\xe7\xa4\xcf\xa1\xa2\xba\xc7\xc2\xe7\xb9\xd4\xbf\xf4\xa4\xf2\xc0\xdf\xc4\xea\xa4\xb7\xa4\xca\xa4\xaa\xa4\xb7\xa4\xc6\xa4\xaf\xa4\xc0\xa4\xb5\xa4\xa4\xa1\xa3"] ::msgcat::mcset ja {r} ::msgcat::mcset ja {staircase} ::msgcat::mcset ja {standard} ::msgcat::mcset ja {x} ::msgcat::mcset ja {} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/es.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000122526�12132042644�013201� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset es {2D} ::msgcat::mcset es {3D} ::msgcat::mcset es {A postscript generation error has occurred} [encoding convertfrom iso8859-1 {Un error ha ocurrido en la generación del fichero postscript}] ::msgcat::mcset es {AIP} ::msgcat::mcset es {Abort} ::msgcat::mcset es {About SAOImage DS9} {Acerca de SAOImage DS9} ::msgcat::mcset es {About} {Acerca de} ::msgcat::mcset es {Acknowledgment} {Reconocimientos} ::msgcat::mcset es {Add} {Agregar} ::msgcat::mcset es {Advanced} {Avanzado} ::msgcat::mcset es {Align} {Alinear} ::msgcat::mcset es {All Columns} {Todas las columnas} ::msgcat::mcset es {All Rows} {Todas las filas} ::msgcat::mcset es {All} {Todas} ::msgcat::mcset es {Always save files during Backup} ::msgcat::mcset es {Amplifier} {Amplificador} ::msgcat::mcset es {An error has occured while updating VO server list} {Un error ha ocurrido mientras se actualizaba la lista del servidor del Observatorio Virtual} ::msgcat::mcset es {An error has occurred during backup} ::msgcat::mcset es {An error has occurred during restore} ::msgcat::mcset es {An error has occurred invoking the Analysis task} [encoding convertfrom iso8859-1 {Un error ha ocurrido mientras se invocaba la tarea de análisis}] ::msgcat::mcset es {An error has occurred while creating image.} ::msgcat::mcset es {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset es {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset es {An error has occurred while printing} {Un error ha ocurrido al imprimir} ::msgcat::mcset es {An error has occurred while reading image.} ::msgcat::mcset es {An error has occurred while saving} {Un error ha ocurrido al guardar} ::msgcat::mcset es {An error has occurred while writing image.} ::msgcat::mcset es {An internal error has been detected} ::msgcat::mcset es {Analysis Command Log} [encoding convertfrom iso8859-1 {Log de instrucciones de análisis}] ::msgcat::mcset es {Analysis Commands} [encoding convertfrom iso8859-1 {Comandos de análisis}] ::msgcat::mcset es {Analysis File} ::msgcat::mcset es {Analysis Log} ::msgcat::mcset es {Analysis} [encoding convertfrom iso8859-1 {Análisis}] ::msgcat::mcset es {Angle Complement} [encoding convertfrom iso8859-1 {Ángulo complementario}] ::msgcat::mcset es {Angles} [encoding convertfrom iso8859-1 {Ángulos}] ::msgcat::mcset es {Angle} [encoding convertfrom iso8859-1 {Ángulo}] ::msgcat::mcset es {Annuli} [encoding convertfrom iso8859-1 {Ánulos}] ::msgcat::mcset es {Annulus} {Corona} ::msgcat::mcset es {Apply} {Aplicar} ::msgcat::mcset es {ArcMin} {MinArc} ::msgcat::mcset es {ArcSec} {SegArc} ::msgcat::mcset es {Architecture} {Arquitectura} ::msgcat::mcset es {Archives} {Archivos} ::msgcat::mcset es {Array} ::msgcat::mcset es {Arrow} {Flecha} ::msgcat::mcset es {Astronomy} ::msgcat::mcset es {At Startup} ::msgcat::mcset es {At least 2 different catalogs are required} ::msgcat::mcset es {Auto Centroid} {Auto Centroide} ::msgcat::mcset es {Auto Plot 2D} ::msgcat::mcset es {Auto Plot 3D} ::msgcat::mcset es {Auto Plot} ::msgcat::mcset es {Autoload FITS Regions} {Autocargar regiones FITS} ::msgcat::mcset es {Autoload} ::msgcat::mcset es {Automatic} [encoding convertfrom iso8859-1 {Automático}] ::msgcat::mcset es {Average} {Promedio} ::msgcat::mcset es {Axes Number} ::msgcat::mcset es {Axes Title} ::msgcat::mcset es {Axes} {Ejes} ::msgcat::mcset es {Axis Label} [encoding convertfrom iso8859-1 {Nombre del eje}] ::msgcat::mcset es {Axis Length} {Longitud del eje} ::msgcat::mcset es {Axis Numbers} [encoding convertfrom iso8859-1 {Números de los ejes}] ::msgcat::mcset es {Axis} {Eje} ::msgcat::mcset es {Azimuth} ::msgcat::mcset es {Background Color} {Color de fondo} ::msgcat::mcset es {Background} {Fondo} ::msgcat::mcset es {Backup} ::msgcat::mcset es {Back} [encoding convertfrom iso8859-1 {Para atrás}] ::msgcat::mcset es {Bar Plot Tool} ::msgcat::mcset es {Bias} ::msgcat::mcset es {Bin 3rd Column} {Bin tercera columna} ::msgcat::mcset es {Bin Center} {Centro del bin} ::msgcat::mcset es {Bin Columns} {Columnas del bin} ::msgcat::mcset es {Bin Filter} {Filtro del bin} ::msgcat::mcset es {Binning Parameters} [encoding convertfrom iso8859-1 {Parámetros de resolución}] ::msgcat::mcset es {Bin} ::msgcat::mcset es {Black} {Negro} ::msgcat::mcset es {Blank/Inf/NaN Color} {Color en blanco/Inf/NaN} ::msgcat::mcset es {Blink Frames} {Parpadear Marcos} ::msgcat::mcset es {Blink Interval} {Intervalo de parpadeo} ::msgcat::mcset es {Blink} {Parpadear} ::msgcat::mcset es {Block In} {Bin a} ::msgcat::mcset es {Block Out} {Bin de} ::msgcat::mcset es {Block to Fit Frame} [encoding convertfrom iso8859-1 {Bin para encajar la imagen en el marco}] ::msgcat::mcset es {Block} {Bin} ::msgcat::mcset es {Blue} {Azul} ::msgcat::mcset es {Bold} {Negrilla} ::msgcat::mcset es {Border} {Borde} ::msgcat::mcset es {Box Annulus} {Caja con caja inscrita} ::msgcat::mcset es {Box Panda} {Caja con caja inscrita segmetada} ::msgcat::mcset es {BoxCircle} ::msgcat::mcset es {Boxcar} ::msgcat::mcset es {Box} {Casilla} ::msgcat::mcset es {Broadcast} ::msgcat::mcset es {Browser} ::msgcat::mcset es {Browse} ::msgcat::mcset es {Buffer} ::msgcat::mcset es {Buttonbar} ::msgcat::mcset es {Buttons} {Teclas} ::msgcat::mcset es {Bytes} ::msgcat::mcset es {CMYK} ::msgcat::mcset es {Can Delete} {Puede suprimir} ::msgcat::mcset es {Can Edit} {Puede editar} ::msgcat::mcset es {Can Move} {Puede mover} ::msgcat::mcset es {Can Rotate} {Puede rotar} ::msgcat::mcset es {Cancel} {Cancelar} ::msgcat::mcset es {Catalog Server} [encoding convertfrom iso8859-1 {Servidor de catálogo}] ::msgcat::mcset es {Catalog Tool} [encoding convertfrom iso8859-1 {Herramienta de catálogo}] ::msgcat::mcset es {Catalogs} [encoding convertfrom iso8859-1 {Catálogos}] ::msgcat::mcset es {Catalog} [encoding convertfrom iso8859-1 {Catálogo}] ::msgcat::mcset es {Center Image} {Centrar imagen} ::msgcat::mcset es {Center Non-modal Dialogs} ::msgcat::mcset es {Center} {Centrar} ::msgcat::mcset es {Centroid Parameters} [encoding convertfrom iso8859-1 {Párametros del centroide}] ::msgcat::mcset es {Centroid} {Centroide} ::msgcat::mcset es {Circle} [encoding convertfrom iso8859-1 {Círculo}] ::msgcat::mcset es {Clear All} {Despejar todos} ::msgcat::mcset es {Clear Analysis Commands} {Borrar las instrucciones de análisis} ::msgcat::mcset es {Clear Cache} {Limpiar cache} ::msgcat::mcset es {Clear Data} {Limpiar de datos} ::msgcat::mcset es {Clear External Analysis Commands?} [encoding convertfrom iso8859-1 {¿Borrar las instrucciones externas de análisis?}] ::msgcat::mcset es {Clear Filter} {Borrar filtro} ::msgcat::mcset es {Clear Frame} {Despejar marco} ::msgcat::mcset es {Clear Preferences?} [encoding convertfrom iso8859-1 {¿Limpiar las preferencias?}] ::msgcat::mcset es {Clear Preferences} {Limpiar las preferencias} ::msgcat::mcset es {Clear} {Vaciar} ::msgcat::mcset es {Click to Center} {Clic para centrar} ::msgcat::mcset es {Close} {Cerrar} ::msgcat::mcset es {Colorbar Size} ::msgcat::mcset es {Colorbar} {Barra de colores} ::msgcat::mcset es {Colormap Parameters} [encoding convertfrom iso8859-1 {Parámetros del mapa de colores}] ::msgcat::mcset es {Colormap} {Mapa de colores} ::msgcat::mcset es {Color} ::msgcat::mcset es {Columns} {Columnas} ::msgcat::mcset es {Column} {Columna} ::msgcat::mcset es {Command} ::msgcat::mcset es {Compass} [encoding convertfrom iso8859-1 {Compás}] ::msgcat::mcset es {Composite Region} ::msgcat::mcset es {Composite} {Compuesto} ::msgcat::mcset es {Compression} [encoding convertfrom iso8859-1 {Compresión}] ::msgcat::mcset es {Configure} {Configurar} ::msgcat::mcset es {Connect Directly} {Conecta directamente} ::msgcat::mcset es {Connect SAMP} ::msgcat::mcset es {Connect Using Web Proxy} {Conecta, usa Web Proxy} ::msgcat::mcset es {Connect} ::msgcat::mcset es {Console} ::msgcat::mcset es {Contour Parameters} [encoding convertfrom iso8859-1 {Parámetros de contorno}] ::msgcat::mcset es {Contours} {Contornos} ::msgcat::mcset es {Contour} ::msgcat::mcset es {Contrast} {Contraste} ::msgcat::mcset es {Contributed} ::msgcat::mcset es {Convert to Polygons} [encoding convertfrom iso8859-1 {Convertir a polígonos}] ::msgcat::mcset es {Coordinate Grid Parameters} [encoding convertfrom iso8859-1 {Parámetros de la cuadrícula de coordenadas}] ::msgcat::mcset es {Coordinate Grid} [encoding convertfrom iso8859-1 {Cuadrícula de coordenadas}] ::msgcat::mcset es {Coordinate System} {Sistema de coordenadas} ::msgcat::mcset es {Coordinates} {Coordenadas} ::msgcat::mcset es {Coordinate} {Coordenada} ::msgcat::mcset es {Copy Contours} {Copiar contornos} ::msgcat::mcset es {Copy to Regions} {Copiar a regiones} ::msgcat::mcset es {Copy} {Copiar} ::msgcat::mcset es {Create Movie} ::msgcat::mcset es {Create New Frame on Download} {Crear un nuevo marco al transferir} ::msgcat::mcset es {Create} ::msgcat::mcset es {Crop Parameters} ::msgcat::mcset es {Crop} ::msgcat::mcset es {Crosshair To} {Localizar con punto de mira} ::msgcat::mcset es {Crosshair} {Punto de mira} ::msgcat::mcset es {Cross} {Cruz} ::msgcat::mcset es {Cube} ::msgcat::mcset es {Current Frame} {Marco actual} ::msgcat::mcset es {Current Range} {Rango actual} ::msgcat::mcset es {Current} {Actual} ::msgcat::mcset es {Cursor} ::msgcat::mcset es {Cut} {Corte} ::msgcat::mcset es {Cyan} {Cian} ::msgcat::mcset es {DPI} ::msgcat::mcset es {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset es {DS9 has detected a newer version of a preferences file and therefore will not process this file.} [encoding convertfrom iso8859-1 {DS9 ha detectado un fichero de preferencias más actual y, por tanto, no procesará este fichero.}] ::msgcat::mcset es {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset es {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-1 {DS9 ha detectado un fichero de preferencias más antiguo, ¿Desea actualizarlo?}] ::msgcat::mcset es {DS9 will complete the initialization process} [encoding convertfrom iso8859-1 {DS9 completará el proceso de inicialización}] ::msgcat::mcset es {Dash} [encoding convertfrom iso8859-1 {Guión}] ::msgcat::mcset es {Data Format} {Formato de los datos} ::msgcat::mcset es {Dataset} {Conjunto de datos} ::msgcat::mcset es {Data} ::msgcat::mcset es {Decrease} [encoding convertfrom iso8859-1 {Disminución}] ::msgcat::mcset es {Default All Files} ::msgcat::mcset es {Default Format} ::msgcat::mcset es {Default Length} ::msgcat::mcset es {Default} {Por defecto} ::msgcat::mcset es {Degrees} {Grados} ::msgcat::mcset es {Delete All Frames?} [encoding convertfrom iso8859-1 {¿Borrar todos los marcos?}] ::msgcat::mcset es {Delete All Frames} {Borrar todos los marcos} ::msgcat::mcset es {Delete All Groups?} [encoding convertfrom iso8859-1 {¿Borrar todos los grupos?}] ::msgcat::mcset es {Delete All Groups} {Borrar todos los grupos} ::msgcat::mcset es {Delete All Regions?} [encoding convertfrom iso8859-1 {¿Borrar todas las regiones?}] ::msgcat::mcset es {Delete All Regions} {Borrar todas las regiones} ::msgcat::mcset es {Delete All} ::msgcat::mcset es {Delete Color Tags} ::msgcat::mcset es {Delete Frame} {Borrar marco} ::msgcat::mcset es {Delete Group} {Borrar grupo} ::msgcat::mcset es {Delete Selected Regions} {Borrar regiones seleccionadas} ::msgcat::mcset es {Delete} {Borrar} ::msgcat::mcset es {Depth} {Profundidad} ::msgcat::mcset es {Detector} ::msgcat::mcset es {Dialog Box} [encoding convertfrom iso8859-1 {Caja de diálogo}] ::msgcat::mcset es {Diamond} {Diamante} ::msgcat::mcset es {Dimension} [encoding convertfrom iso8859-1 {Dimensión}] ::msgcat::mcset es {Disconnect} ::msgcat::mcset es {Discrete} {Discreto} ::msgcat::mcset es {Display Header} ::msgcat::mcset es {Display Size} [encoding convertfrom iso8859-1 {Mostrar el tamaño}] ::msgcat::mcset es {Dissolve} {Disolver} ::msgcat::mcset es {Distance} ::msgcat::mcset es {Download Colormap} ::msgcat::mcset es {Download VOTABLE format if available} ::msgcat::mcset es {Drag to Center} {Arrastrar para centrar} ::msgcat::mcset es {Duplicate Data} ::msgcat::mcset es {East} {Este} ::msgcat::mcset es {Ecliptic} [encoding convertfrom iso8859-1 {Eclíptica}] ::msgcat::mcset es {Edit Group Name} {Editar el nombre del grupo} ::msgcat::mcset es {Edit} {Editar} ::msgcat::mcset es {Element} ::msgcat::mcset es {Elevation} [encoding convertfrom iso8859-1 {Elevación}] ::msgcat::mcset es {Ellipse Panda} {Elipse con elipse inscrita segmentada} ::msgcat::mcset es {Ellipse} {Elipse} ::msgcat::mcset es {Elliptical Annulus} {Elipse con elipse inscrita} ::msgcat::mcset es {Elliptical Panda} [encoding convertfrom iso8859-1 {Elipse con elipse inscrita segmentada}] ::msgcat::mcset es {Enable Confirmation Dialogs} [encoding convertfrom iso8859-1 {Habilitar los diálogos de confirmación}] ::msgcat::mcset es {Enable} ::msgcat::mcset es {End} ::msgcat::mcset es {Enter Color} {Entrar color} ::msgcat::mcset es {Enter Font Size} ::msgcat::mcset es {Enter Group Name} {Entrar nombre de grupo} ::msgcat::mcset es {Enter Search Expression} [encoding convertfrom iso8859-1 {Entrar expresión de búsqueda}] ::msgcat::mcset es {Enter URL} ::msgcat::mcset es {Entry} {Entrada} ::msgcat::mcset es {Equal Area} {Misma área} ::msgcat::mcset es {Equal Distance} {Misma distancia} ::msgcat::mcset es {Equal Spacing} ::msgcat::mcset es {Equal Value} ::msgcat::mcset es {Error code was returned} [encoding convertfrom iso8859-1 {Error de código fue regresado}] ::msgcat::mcset es {Error} ::msgcat::mcset es {Examine Frame} {Examinar marco} ::msgcat::mcset es {Examine} {Examinar} ::msgcat::mcset es {Exclude} {Excluir} ::msgcat::mcset es {Executing TCL code is not enabled} ::msgcat::mcset es {Exit} {Salir} ::msgcat::mcset es {Export Array} ::msgcat::mcset es {Export} ::msgcat::mcset es {Extention} ::msgcat::mcset es {Exterior Axes} {Ejes exteriores} ::msgcat::mcset es {Exterior Numerics} {Numeración exterior} ::msgcat::mcset es {FAQ} ::msgcat::mcset es {FK4} ::msgcat::mcset es {FK5} ::msgcat::mcset es {Factor} ::msgcat::mcset es {File not Found or Unable to load FITS data MIME type} {Fichero no hallado o incapaz de cargar datos FITS de tipo MIME} ::msgcat::mcset es {Filename} {Nombre del fichero} ::msgcat::mcset es {File} {Fichero} ::msgcat::mcset es {Fill} ::msgcat::mcset es {Filter} {Filtro} ::msgcat::mcset es {Find Next} {Hallar la siguiente} ::msgcat::mcset es {Find} {Hallar} ::msgcat::mcset es {First Frame} {Primer Marco} ::msgcat::mcset es {First} {Primer} ::msgcat::mcset es {Fits} ::msgcat::mcset es {Fixed in Size} [encoding convertfrom iso8859-1 {Fijado en tamaño}] ::msgcat::mcset es {Flip} ::msgcat::mcset es {Font} {Fuente} ::msgcat::mcset es {For more information, use --help} ::msgcat::mcset es {Format} {Formato} ::msgcat::mcset es {Forward} {Hacia adelante} ::msgcat::mcset es {Found} {Hallado} ::msgcat::mcset es {Frame Information} [encoding convertfrom iso8859-1 {Información del marco}] ::msgcat::mcset es {Frame Parameters} ::msgcat::mcset es {Frames} ::msgcat::mcset es {Frame} {Marco} ::msgcat::mcset es {From} ::msgcat::mcset es {Front} {Al frente} ::msgcat::mcset es {Full Range} {Rango completo} ::msgcat::mcset es {Function} [encoding convertfrom iso8859-1 {Función}] ::msgcat::mcset es {GUI Font} ::msgcat::mcset es {Galactic} [encoding convertfrom iso8859-1 {Galáctico}] ::msgcat::mcset es {Gap} ::msgcat::mcset es {Gaussian} {Gausiana} ::msgcat::mcset es {General} ::msgcat::mcset es {Generate} {Generar} ::msgcat::mcset es {Generating Regions} {Generando regiones} ::msgcat::mcset es {Get Information} [encoding convertfrom iso8859-1 {Obtener información}] ::msgcat::mcset es {Global Properties} ::msgcat::mcset es {Global} ::msgcat::mcset es {Goto Frame} ::msgcat::mcset es {Graph Horz} ::msgcat::mcset es {Graph Vert} ::msgcat::mcset es {Graphics} [encoding convertfrom iso8859-1 {Gráficos}] ::msgcat::mcset es {Graphs} ::msgcat::mcset es {Graph} [encoding convertfrom iso8859-1 {Gráfica}] ::msgcat::mcset es {Grayscale} {Escala de grises} ::msgcat::mcset es {Green} {Verde} ::msgcat::mcset es {Grid Gap} [encoding convertfrom iso8859-1 {Espaciado de la cuadrícula}] ::msgcat::mcset es {Grid} [encoding convertfrom iso8859-1 {Cuadrícula}] ::msgcat::mcset es {Groups} {Grupos} ::msgcat::mcset es {HTTP} ::msgcat::mcset es {Header} {Cabecera} ::msgcat::mcset es {Height} {Altura} ::msgcat::mcset es {Help Desk} {Mesa de ayuda} ::msgcat::mcset es {Help Me Choose} {Ayudame a escoger} ::msgcat::mcset es {Help} {Ayuda} ::msgcat::mcset es {Hide All} {Ocultar todos} ::msgcat::mcset es {Highlite} ::msgcat::mcset es {High} {Alto} ::msgcat::mcset es {Histogram Equalization} [encoding convertfrom iso8859-1 {Ecualización de histograma}] ::msgcat::mcset es {Histogram} {Histograma} ::msgcat::mcset es {Horizontal Graph} [encoding convertfrom iso8859-1 {Gráfica horizontal}] ::msgcat::mcset es {Horizontal Layout} [encoding convertfrom iso8859-1 {Distribución horizontal}] ::msgcat::mcset es {Horizontal} ::msgcat::mcset es {IAU Location Code} ::msgcat::mcset es {ICRS} ::msgcat::mcset es {Identification} {Identificación} ::msgcat::mcset es {If} {Si} ::msgcat::mcset es {Image Servers} {Servidores de imagen} ::msgcat::mcset es {Image} {Imagen} ::msgcat::mcset es {Import Array} ::msgcat::mcset es {Import} ::msgcat::mcset es {Include} {Incluir} ::msgcat::mcset es {Increase} {Aumento} ::msgcat::mcset es {Information Panel} [encoding convertfrom iso8859-1 {Panel de información}] ::msgcat::mcset es {Information} [encoding convertfrom iso8859-1 {Información}] ::msgcat::mcset es {Initialize XPA} {Inicializar XPA} ::msgcat::mcset es {Inner} {Interior} ::msgcat::mcset es {Instrument FOV} {Campo visual del instrumento} ::msgcat::mcset es {Interior Axes} {Ejes interiores} ::msgcat::mcset es {Interior Numerics} [encoding convertfrom iso8859-1 {Numeración interior}] ::msgcat::mcset es {Internal Parse Error} ::msgcat::mcset es {Interval} {Intervalo} ::msgcat::mcset es {Invalid Column Name} ::msgcat::mcset es {Invalid formated multipart/mixed mime type message} ::msgcat::mcset es {Invert Colormap} {Invertir mapa de colores} ::msgcat::mcset es {Invert Selection} [encoding convertfrom iso8859-1 {Invertir selección}] ::msgcat::mcset es {Invert} {Invertir} ::msgcat::mcset es {Italic} [encoding convertfrom iso8859-1 {Itálica}] ::msgcat::mcset es {Items Found} [encoding convertfrom iso8859-1 {Artículos hallados}] ::msgcat::mcset es {Iteration} [encoding convertfrom iso8859-1 {Iteración}] ::msgcat::mcset es {JPEG Quality Factor} {Factor de calidad JPEG} ::msgcat::mcset es {Keep-Alive} ::msgcat::mcset es {Kernel} ::msgcat::mcset es {Keyboard Shortcuts} {Atajos con el teclado} ::msgcat::mcset es {Keyboard} {Teclado} ::msgcat::mcset es {Labels} {Etiquetas} ::msgcat::mcset es {Label} {Etiqueta} ::msgcat::mcset es {Landscape} {Apaisado} ::msgcat::mcset es {Language} {Idioma} ::msgcat::mcset es {Last Frame} [encoding convertfrom iso8859-1 {Último marco}] ::msgcat::mcset es {Last} [encoding convertfrom iso8859-1 {Último}] ::msgcat::mcset es {Layout Horz} ::msgcat::mcset es {Layout Vert} ::msgcat::mcset es {Layout} ::msgcat::mcset es {Left} ::msgcat::mcset es {Legal} ::msgcat::mcset es {Length} {Longitud} ::msgcat::mcset es {Letter} ::msgcat::mcset es {Levels} {Niveles} ::msgcat::mcset es {Level} {Nivel} ::msgcat::mcset es {Limits} [encoding convertfrom iso8859-1 {Límites}] ::msgcat::mcset es {Line Plot Tool} ::msgcat::mcset es {Linear} {Lineal} ::msgcat::mcset es {Line} [encoding convertfrom iso8859-1 {Línea}] ::msgcat::mcset es {List Data} ::msgcat::mcset es {List Regions} {Listar regiones} ::msgcat::mcset es {List} {Listar} ::msgcat::mcset es {Load Analysis Commands} [encoding convertfrom iso8859-1 {Cargar las instrucciones de análisis}] ::msgcat::mcset es {Load Color Tags} ::msgcat::mcset es {Load Colormap} {Cargar mapa de colores} ::msgcat::mcset es {Load Configuration} [encoding convertfrom iso8859-1 {Cargar configuración}] ::msgcat::mcset es {Load Contour Levels} {Cargar niveles de contorno} ::msgcat::mcset es {Load Contours} {Cargar contornos} ::msgcat::mcset es {Load Contrast/Bias} {Cargar contraste/Bias} ::msgcat::mcset es {Load Data} {Cargar datos} ::msgcat::mcset es {Load Mosaic} {Cargar mosaico} ::msgcat::mcset es {Load Regions} {Cargar regiones} ::msgcat::mcset es {Load Template} {Cargar modelo} ::msgcat::mcset es {Load into All Frames} ::msgcat::mcset es {Load into Current Frame} ::msgcat::mcset es {Loading Catalog} ::msgcat::mcset es {Loading} ::msgcat::mcset es {Load} {Cargar} ::msgcat::mcset es {Local} ::msgcat::mcset es {Lock Bin} ::msgcat::mcset es {Lock Color} ::msgcat::mcset es {Lock Crop Amplifier} ::msgcat::mcset es {Lock Crop Detector} ::msgcat::mcset es {Lock Crop Image} ::msgcat::mcset es {Lock Crop None} ::msgcat::mcset es {Lock Crop Physical} ::msgcat::mcset es {Lock Crop WCS} ::msgcat::mcset es {Lock Crosshair Amplifier} ::msgcat::mcset es {Lock Crosshair Detector} ::msgcat::mcset es {Lock Crosshair Image} ::msgcat::mcset es {Lock Crosshair None} ::msgcat::mcset es {Lock Crosshair Physical} ::msgcat::mcset es {Lock Crosshair WCS} ::msgcat::mcset es {Lock Frame Amplifier} ::msgcat::mcset es {Lock Frame Detector} ::msgcat::mcset es {Lock Frame Image} ::msgcat::mcset es {Lock Frame None} ::msgcat::mcset es {Lock Frame Physical} ::msgcat::mcset es {Lock Frame WCS} ::msgcat::mcset es {Lock Scale} ::msgcat::mcset es {Lock Slice} ::msgcat::mcset es {Lock Smooth} ::msgcat::mcset es {Lock} {Bloquear} ::msgcat::mcset es {Log Exponent} ::msgcat::mcset es {Log} ::msgcat::mcset es {Low High} {Bajo Alto} ::msgcat::mcset es {Lower Left Back} ::msgcat::mcset es {Lower Left Front} ::msgcat::mcset es {Lower Right Back} ::msgcat::mcset es {Lower Right Front} ::msgcat::mcset es {Low} {Bajo} ::msgcat::mcset es {MIP} ::msgcat::mcset es {Magenta} ::msgcat::mcset es {Magnification} ::msgcat::mcset es {Magnifier} {Ventanilla magnificadora} ::msgcat::mcset es {Major} {Mayor} ::msgcat::mcset es {Manual} ::msgcat::mcset es {Mask Parameters} [encoding convertfrom iso8859-1 {Parámetros de mascara}] ::msgcat::mcset es {Match Bin} ::msgcat::mcset es {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset es {Match Color} ::msgcat::mcset es {Match Crop Amplifier} ::msgcat::mcset es {Match Crop Detector} ::msgcat::mcset es {Match Crop Image} ::msgcat::mcset es {Match Crop Physical} ::msgcat::mcset es {Match Crop WCS} ::msgcat::mcset es {Match Crosshair Amplifier} ::msgcat::mcset es {Match Crosshair Detector} ::msgcat::mcset es {Match Crosshair Image} ::msgcat::mcset es {Match Crosshair Physical} ::msgcat::mcset es {Match Crosshair WCS} ::msgcat::mcset es {Match Frame Amplifier} ::msgcat::mcset es {Match Frame Detector} ::msgcat::mcset es {Match Frame Image} ::msgcat::mcset es {Match Frame Physical} ::msgcat::mcset es {Match Frame WCS} ::msgcat::mcset es {Match Scale} ::msgcat::mcset es {Match Slice} ::msgcat::mcset es {Match Smooth} ::msgcat::mcset es {Match} ::msgcat::mcset es {Math Function} [encoding convertfrom iso8859-1 {Función matemática}] ::msgcat::mcset es {Max Rows} [encoding convertfrom iso8859-1 {Máx filas}] ::msgcat::mcset es {Max} [encoding convertfrom iso8859-1 {Máx}] ::msgcat::mcset es {Menus and Buttons} ::msgcat::mcset es {Menu} ::msgcat::mcset es {Message Log} ::msgcat::mcset es {Method} [encoding convertfrom iso8859-1 {Método}] ::msgcat::mcset es {Min Max Parameters} ::msgcat::mcset es {Min Max} [encoding convertfrom iso8859-1 {Mín Máx}] ::msgcat::mcset es {Minor} {Menor} ::msgcat::mcset es {Minutes} ::msgcat::mcset es {Min} [encoding convertfrom iso8859-1 {Mín}] ::msgcat::mcset es {Mission} [encoding convertfrom iso8859-1 {Misión}] ::msgcat::mcset es {Mode} ::msgcat::mcset es {Mosaic IRAF Segment} ::msgcat::mcset es {Mosaic IRAF} ::msgcat::mcset es {Mosaic WCS Segment} ::msgcat::mcset es {Mosaic WCS} ::msgcat::mcset es {Mosaic WFPC2} ::msgcat::mcset es {Mosaic} ::msgcat::mcset es {Mouse & Keyboard} ::msgcat::mcset es {Mouse Wheel Bin} ::msgcat::mcset es {Mouse Wheel Zoom} ::msgcat::mcset es {Move Back} [encoding convertfrom iso8859-1 {Mover atrás}] ::msgcat::mcset es {Move First} {Mover al primero} ::msgcat::mcset es {Move Forward} {Mover adelante} ::msgcat::mcset es {Move Frame} ::msgcat::mcset es {Move Last} [encoding convertfrom iso8859-1 {Mover al Último}] ::msgcat::mcset es {Move to Back} [encoding convertfrom iso8859-1 {Poner detrás}] ::msgcat::mcset es {Move to Front} {Poner delante} ::msgcat::mcset es {Movie} ::msgcat::mcset es {Multiple Extension Cube} ::msgcat::mcset es {Multiple Extension Frames} ::msgcat::mcset es {Multiple WCS} [encoding convertfrom iso8859-1 {Múltiple WCS}] ::msgcat::mcset es {NRRD} ::msgcat::mcset es {Name Resolution} [encoding convertfrom iso8859-1 {Conversión a coordenadas}] ::msgcat::mcset es {Name Server} {Nombre del servidor} ::msgcat::mcset es {Name or Designation} [encoding convertfrom iso8859-1 {Nombre o designación}] ::msgcat::mcset es {Name} ::msgcat::mcset es {Native Dialog} [encoding convertfrom iso8859-1 {Diálogo nativo}] ::msgcat::mcset es {Native} ::msgcat::mcset es {New 3D} {Nuevo 3D} ::msgcat::mcset es {New Features} [encoding convertfrom iso8859-1 {Nuevas características}] ::msgcat::mcset es {New Frame 3D} {Nuevo Marco 3D} ::msgcat::mcset es {New Frame RGB} {Nuevo marco RGB} ::msgcat::mcset es {New Frame each Time} {Nuevo marco cada vez} ::msgcat::mcset es {New Frame} {Nuevo marco} ::msgcat::mcset es {New Group} {Nuevo grupo} ::msgcat::mcset es {New RGB} {Nuevo RGB} ::msgcat::mcset es {New} {Nuevo} ::msgcat::mcset es {Next Frame} {Siguiente Marco} ::msgcat::mcset es {Next} {Siguiente} ::msgcat::mcset es {No Catalog specified} [encoding convertfrom iso8859-1 {No se ha especificado el catálogo}] ::msgcat::mcset es {No Items Found} [encoding convertfrom iso8859-1 {Artículos no encontrados}] ::msgcat::mcset es {No current frame} ::msgcat::mcset es {No data available at } {No hay datos disponibles en} ::msgcat::mcset es {Non-zero} {No nulo} ::msgcat::mcset es {None} {Nada} ::msgcat::mcset es {Normal} ::msgcat::mcset es {North} {Norte} ::msgcat::mcset es {Not Found} ::msgcat::mcset es {No} ::msgcat::mcset es {Number of Samples} [encoding convertfrom iso8859-1 {Número de muestreos}] ::msgcat::mcset es {Number of Threads} ::msgcat::mcset es {Number of Ticks} ::msgcat::mcset es {Number} [encoding convertfrom iso8859-1 {Número}] ::msgcat::mcset es {Numerics} [encoding convertfrom iso8859-1 {Numeración}] ::msgcat::mcset es {OK} {Vale} ::msgcat::mcset es {Object} {Objeto} ::msgcat::mcset es {Open File} {Abrir fichero} ::msgcat::mcset es {Open TCL Console} {Abrir consola TCL} ::msgcat::mcset es {Open URL} {Abrir URL} ::msgcat::mcset es {Open as} ::msgcat::mcset es {Open} {Abrir} ::msgcat::mcset es {Operator} {Operador} ::msgcat::mcset es {Orientation} [encoding convertfrom iso8859-1 {Orientación}] ::msgcat::mcset es {Origin} ::msgcat::mcset es {Oscillate} ::msgcat::mcset es {Other Color} ::msgcat::mcset es {Other Font Size} ::msgcat::mcset es {Other} {Otro} ::msgcat::mcset es {Outer} {Exterior} ::msgcat::mcset es {PS Page Setup} [encoding convertfrom iso8859-1 {Setup para Página PS}] ::msgcat::mcset es {PS Print} {Imprimir PS} ::msgcat::mcset es {Page Setup} [encoding convertfrom iso8859-1 {Formato de página}] ::msgcat::mcset es {Page Source} [encoding convertfrom iso8859-1 {Fuente HTML de la página}] ::msgcat::mcset es {Pan To} {Trasladar a} ::msgcat::mcset es {Pan Zoom Rotate Parameters} [encoding convertfrom iso8859-1 {Parámetros de traslación, Zoom y rotación}] ::msgcat::mcset es {Pan Zoom} ::msgcat::mcset es {Pan then Zoom} [encoding convertfrom iso8859-1 {Trasladar y después Zoom}] ::msgcat::mcset es {Panda} {Corona segmentada} ::msgcat::mcset es {Panner} [encoding convertfrom iso8859-1 {Ventanilla panorámica}] ::msgcat::mcset es {Pan} {Trasladar} ::msgcat::mcset es {Parameters} [encoding convertfrom iso8859-1 {Parámetros}] ::msgcat::mcset es {Password} [encoding convertfrom iso8859-1 {Contraseña}] ::msgcat::mcset es {Paste Contours} {Pegar contornos} ::msgcat::mcset es {Paste} {Pegar} ::msgcat::mcset es {Physical} [encoding convertfrom iso8859-1 {Física}] ::msgcat::mcset es {Pixel Distribution} [encoding convertfrom iso8859-1 {Distribución por píxeles}] ::msgcat::mcset es {Pixel Size} [encoding convertfrom iso8859-1 {Tamaño del píxel}] ::msgcat::mcset es {Pixel Table} [encoding convertfrom iso8859-1 {Tabla en píxeles}] ::msgcat::mcset es {Pixels} [encoding convertfrom iso8859-1 {Píxeles}] ::msgcat::mcset es {Play} ::msgcat::mcset es {Please Select a Region} ::msgcat::mcset es {Please specify width, height, and either name or (ra,dec)} {Por farvor, especifique el ancho, altura, y nombre o (A.R.,Dec.)} ::msgcat::mcset es {Plot 2D} ::msgcat::mcset es {Plot 3D} ::msgcat::mcset es {Plot Title} [encoding convertfrom iso8859-1 {Título de la gráfica}] ::msgcat::mcset es {Plotting Regions} {Dibujando regiones} ::msgcat::mcset es {Plot} ::msgcat::mcset es {Plus} [encoding convertfrom iso8859-1 {Más}] ::msgcat::mcset es {Pointer} {Indicador} ::msgcat::mcset es {Points} [encoding convertfrom iso8859-1 {Posición}] ::msgcat::mcset es {Point} [encoding convertfrom iso8859-1 {Posición}] ::msgcat::mcset es {Polygon} [encoding convertfrom iso8859-1 {Polígono}] ::msgcat::mcset es {Portrait} ::msgcat::mcset es {Poster} [encoding convertfrom iso8859-1 {Póster}] ::msgcat::mcset es {Postscript Page Setup} [encoding convertfrom iso8859-1 {Setup para Página Postscript}] ::msgcat::mcset es {Postscript Print} {Imprimir Postscript} ::msgcat::mcset es {Postscript} ::msgcat::mcset es {Power} {Potencia} ::msgcat::mcset es {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} {Las preferencias han sido restauradas a sus valores por defecto. Por favor reanude DS9 para que estos cambios tengan efecto.} ::msgcat::mcset es {Preferences} {Preferencias} ::msgcat::mcset es {Preserve During Load} {Conservar mientras se carga} ::msgcat::mcset es {Previous Frame} {Marco Previo} ::msgcat::mcset es {Previous} {Previo} ::msgcat::mcset es {Print Coordinates} {Imprimir coordenadas} ::msgcat::mcset es {Print To} {Imprimir en} ::msgcat::mcset es {Printer} {Impresora} ::msgcat::mcset es {Print} {Imprimir} ::msgcat::mcset es {Projection} [encoding convertfrom iso8859-1 {Proyección}] ::msgcat::mcset es {Properties} {Propiedades} ::msgcat::mcset es {Property} {Propiedad} ::msgcat::mcset es {Proxy Host} ::msgcat::mcset es {Proxy Port} ::msgcat::mcset es {Publication} [encoding convertfrom iso8859-1 {Publicación}] ::msgcat::mcset es {Quadratic} [encoding convertfrom iso8859-1 {Cuadrático}] ::msgcat::mcset es {RGB Array} ::msgcat::mcset es {RGB Cube} ::msgcat::mcset es {RGB Image} ::msgcat::mcset es {RGB} ::msgcat::mcset es {Radial Profile} ::msgcat::mcset es {Radius} {Radio} ::msgcat::mcset es {Range} ::msgcat::mcset es {Redo} {Rehacer} ::msgcat::mcset es {Red} {Rojo} ::msgcat::mcset es {Reference Manual} {Manual de referencia} ::msgcat::mcset es {Reference} {Manual} ::msgcat::mcset es {Refresh Frame} {Refrescar marco} ::msgcat::mcset es {Refresh} {Refrescar} ::msgcat::mcset es {Region Parameters} ::msgcat::mcset es {Region} [encoding convertfrom iso8859-1 {Región}] ::msgcat::mcset es {Release Notes} [encoding convertfrom iso8859-1 {Notas de esta versión}] ::msgcat::mcset es {Release} [encoding convertfrom iso8859-1 {Versión}] ::msgcat::mcset es {Reload} {Recargar} ::msgcat::mcset es {Repeat} ::msgcat::mcset es {Reset Colormap} {Restaurar el mapa de colores} ::msgcat::mcset es {Reset Frame} {Restaurar Marco} ::msgcat::mcset es {Reset} ::msgcat::mcset es {Restore} ::msgcat::mcset es {Retrieve} {Localizar y leer} ::msgcat::mcset es {Return} ::msgcat::mcset es {Right} ::msgcat::mcset es {Roman} ::msgcat::mcset es {Rotate} {Rotar} ::msgcat::mcset es {Rows} {Filas} ::msgcat::mcset es {Row} ::msgcat::mcset es {Ruler} {Regla} ::msgcat::mcset es {SAMP Image} ::msgcat::mcset es {SAMP Table} ::msgcat::mcset es {SAMP: already connected} ::msgcat::mcset es {SAMP: internal error} ::msgcat::mcset es {SAMP: not connected} ::msgcat::mcset es {SAMP: unable to locate HUB} ::msgcat::mcset es {SAMP} ::msgcat::mcset es {Sample Increment} {Incremento en el muestreo} ::msgcat::mcset es {Sample Parameters} [encoding convertfrom iso8859-1 {Parámetros de muestreo}] ::msgcat::mcset es {Samples per Line} [encoding convertfrom iso8859-1 {Muestreos por línea}] ::msgcat::mcset es {Sample} {Muestreo} ::msgcat::mcset es {Save 3D Movie} ::msgcat::mcset es {Save Color Tags} ::msgcat::mcset es {Save Colormap} {Guardar mapa de colores} ::msgcat::mcset es {Save Configuration} [encoding convertfrom iso8859-1 {Guardar configuración}] ::msgcat::mcset es {Save Contour Levels} {Guardar niveles de contorno} ::msgcat::mcset es {Save Contours} {Guardar contornos} ::msgcat::mcset es {Save Contrast/Bias} {Guardar contraste/Bias} ::msgcat::mcset es {Save Data} {Guardar datos} ::msgcat::mcset es {Save Image on Download} ::msgcat::mcset es {Save Image} {Guardar imagen} ::msgcat::mcset es {Save Regions} {Guardar regiones} ::msgcat::mcset es {Save Template} {Guardar modelo} ::msgcat::mcset es {Save as} ::msgcat::mcset es {Save} {Guardar} ::msgcat::mcset es {Scale Parameters} [encoding convertfrom iso8859-1 {Párametros de escala}] ::msgcat::mcset es {Scale} {Escala} ::msgcat::mcset es {Scan} {Escanear} ::msgcat::mcset es {Scatter Plot Tool} ::msgcat::mcset es {Scope} {Alcance} ::msgcat::mcset es {Search for Catalogs} [encoding convertfrom iso8859-1 {Buscar por catálogos}] ::msgcat::mcset es {Searching for catalogs} [encoding convertfrom iso8859-1 {Buscando por catálogos}] ::msgcat::mcset es {Seconds} {Segundos} ::msgcat::mcset es {Select All} {Seleccionar todos} ::msgcat::mcset es {Select Coordinate System } {Seleccionar el sistema de coordenadas} ::msgcat::mcset es {Select None} {Seleccionar nada} ::msgcat::mcset es {Send} ::msgcat::mcset es {Server} {Servidor} ::msgcat::mcset es {Sexagesimal} ::msgcat::mcset es {Shape} {Forma} ::msgcat::mcset es {Show All} {Mostrarlos todos} ::msgcat::mcset es {Show Command} ::msgcat::mcset es {Show Compass} ::msgcat::mcset es {Show Text} {Mostrar Texto} ::msgcat::mcset es {Show/Hide Frames} {Mostar/ocultar marcos} ::msgcat::mcset es {Show} {Mostrar} ::msgcat::mcset es {Single Frame} [encoding convertfrom iso8859-1 {Un único marco}] ::msgcat::mcset es {Single} [encoding convertfrom iso8859-1 {Único}] ::msgcat::mcset es {Sites} ::msgcat::mcset es {Size/Radius} [encoding convertfrom iso8859-1 {Tamaño/Radio}] ::msgcat::mcset es {Size} [encoding convertfrom iso8859-1 {Tamaño}] ::msgcat::mcset es {Skip First} {Omitir primeros} ::msgcat::mcset es {Slice} ::msgcat::mcset es {Smooth Parameters} [encoding convertfrom iso8859-1 {Parámetros de suavizado}] ::msgcat::mcset es {Smoothness} ::msgcat::mcset es {Smooth} {Suavizar} ::msgcat::mcset es {Sorry, DS9 does not support} {Lo siento, DS9 no admite} ::msgcat::mcset es {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} {Lo siento, DS9 requiere tener disponible a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual} ::msgcat::mcset es {Sort} {Clasificar} ::msgcat::mcset es {Source TCL} [encoding convertfrom iso8859-1 {Leer código TCL}] ::msgcat::mcset es {Source} {Fuente} ::msgcat::mcset es {Space Equal Distance} ::msgcat::mcset es {Space Equal Value} ::msgcat::mcset es {Spacing} {Espaciado} ::msgcat::mcset es {Square Root} [encoding convertfrom iso8859-1 {Raíz cuadrada}] ::msgcat::mcset es {Squared} {Al cuadrado} ::msgcat::mcset es {Starbase} ::msgcat::mcset es {Startup} ::msgcat::mcset es {Start} {Empezar} ::msgcat::mcset es {Statistics} ::msgcat::mcset es {Status} {Estado} ::msgcat::mcset es {Step} {Escalonado} ::msgcat::mcset es {Stop} {Parar} ::msgcat::mcset es {Story of SAOImage DS9} ::msgcat::mcset es {Story} ::msgcat::mcset es {Sum} {Suma} ::msgcat::mcset es {Symbol Editor} [encoding convertfrom iso8859-1 {Editor de símbolos}] ::msgcat::mcset es {Symbol} [encoding convertfrom iso8859-1 {Símbolo}] ::msgcat::mcset es {Tab-Separated-Value} ::msgcat::mcset es {Table} ::msgcat::mcset es {Tabloid} ::msgcat::mcset es {Template} ::msgcat::mcset es {Text Font} ::msgcat::mcset es {Text} {Texto} ::msgcat::mcset es {Theme} ::msgcat::mcset es {Then} {Entonces} ::msgcat::mcset es {Thickness} {Grosor} ::msgcat::mcset es {This analysis task is already running. Do you wish to kill it?} [encoding convertfrom iso8859-1 {Esta tarea para el análisis ya está siendo ejecutada. ¿Desea interrumpirla?}] ::msgcat::mcset es {Tickmarks} {Marcas} ::msgcat::mcset es {Tile Frames} {Alicatar los marcos} ::msgcat::mcset es {Tile Parameters} [encoding convertfrom iso8859-1 {Parámetros de alicatado}] ::msgcat::mcset es {Tile} {Tejar} ::msgcat::mcset es {Times} ::msgcat::mcset es {Title} [encoding convertfrom iso8859-1 {Título}] ::msgcat::mcset es {To Fit} {Para encajar} ::msgcat::mcset es {Tophat} ::msgcat::mcset es {To} {A} ::msgcat::mcset es {Transparency} ::msgcat::mcset es {Type} {Clase} ::msgcat::mcset es {URL} ::msgcat::mcset es {Unable to connect directly: using Web Proxy} ::msgcat::mcset es {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset es {Unable to determine date of observation} ::msgcat::mcset es {Unable to determine time of observation} ::msgcat::mcset es {Unable to evaluate filter} {Incapaz de evaluar el filtro} ::msgcat::mcset es {Unable to find catalog window} [encoding convertfrom iso8859-1 {Incapaz de hallar la ventana de catálogo}] ::msgcat::mcset es {Unable to find plot window} [encoding convertfrom iso8859-1 {Incapaz de hallar la ventana gráfica}] ::msgcat::mcset es {Unable to load RGB image into a non-rgb frame} {Incapaz de cargar imagen RGB en un marco no RGB} ::msgcat::mcset es {Unable to load region file} ::msgcat::mcset es {Unable to load} {Incapaz de cargar} ::msgcat::mcset es {Unable to locate URL} {Incapaz de localizar URL} ::msgcat::mcset es {Unable to match target with XPA Mime request} ::msgcat::mcset es {Unable to open file} {Incapaz de abrir fichero} ::msgcat::mcset es {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset es {Undo} {Deshacer} ::msgcat::mcset es {Unique} ::msgcat::mcset es {Units} {Unidades} ::msgcat::mcset es {Unknown Colormap} ::msgcat::mcset es {Unknown command} ::msgcat::mcset es {Update Filter} ::msgcat::mcset es {Update Group} {Actualizar grupo} ::msgcat::mcset es {Update from Current Crosshair} {Actualizar a partir del punto de mira actual} ::msgcat::mcset es {Update from Current Frame} {Actualizar a partir del marco actual} ::msgcat::mcset es {Update} {Actualizar} ::msgcat::mcset es {Upper Left Back} ::msgcat::mcset es {Upper Left Front} ::msgcat::mcset es {Upper Right Back} ::msgcat::mcset es {Upper Right Front} ::msgcat::mcset es {Use Authentication} [encoding convertfrom iso8859-1 {Usa autenticación}] ::msgcat::mcset es {Use Current Frame on Download} {Usar marco actual al transferir} ::msgcat::mcset es {Use Internal Web Browser} {Usar Web Browser interno} ::msgcat::mcset es {Use Proxy} {Usar Proxy} ::msgcat::mcset es {User Manual} ::msgcat::mcset es {Username} {Nombre de usuario} ::msgcat::mcset es {User} {Usuario} ::msgcat::mcset es {Use} {Usa} ::msgcat::mcset es {VO Server} ::msgcat::mcset es {VO} ::msgcat::mcset es {Value} {Valor} ::msgcat::mcset es {Vector} ::msgcat::mcset es {Vertical Graph} [encoding convertfrom iso8859-1 {Gráfica vertical}] ::msgcat::mcset es {Vertical Layout} [encoding convertfrom iso8859-1 {Distribución vertical}] ::msgcat::mcset es {Vertical Text} {Texto vertical} ::msgcat::mcset es {Vertical} ::msgcat::mcset es {View} {Ver} ::msgcat::mcset es {Virtual Observatory} {Observatorio Virtual} ::msgcat::mcset es {WCS Parameters} ::msgcat::mcset es {WCS} ::msgcat::mcset es {Wavelength} {Longitud de onda} ::msgcat::mcset es {Web Browser} ::msgcat::mcset es {White} {Blanco} ::msgcat::mcset es {Width} {Ancho} ::msgcat::mcset es {Words matching title, description} [encoding convertfrom iso8859-1 {Palabras que coincidan con el título, descripción}] ::msgcat::mcset es {Writing Catalog} ::msgcat::mcset es {X Axis Title} ::msgcat::mcset es {X Axis} ::msgcat::mcset es {X Grid} ::msgcat::mcset es {XPA Information} [encoding convertfrom iso8859-1 {Información XPA}] ::msgcat::mcset es {XPA not initialized} {XPA no inicializado} ::msgcat::mcset es {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset es {XPA} ::msgcat::mcset es {X} ::msgcat::mcset es {Y Axis Title} ::msgcat::mcset es {Y Axis} ::msgcat::mcset es {Y Grid} ::msgcat::mcset es {Yellow} {Amarillo} ::msgcat::mcset es {Yes} [encoding convertfrom iso8859-1 {Sí}] ::msgcat::mcset es {Y} ::msgcat::mcset es {Z Axis Scale} ::msgcat::mcset es {ZScale Parameters} [encoding convertfrom iso8859-1 {Parámetros de la escala Z}] ::msgcat::mcset es {Zero} ::msgcat::mcset es {Zoom In} {Aumentar} ::msgcat::mcset es {Zoom Out} {Reducir} ::msgcat::mcset es {Zoom to Fit Frame} {Zoom para encajar en el marco} ::msgcat::mcset es {Zoom} {Zoom} ::msgcat::mcset es {and} ::msgcat::mcset es {blue} ::msgcat::mcset es {b} ::msgcat::mcset es {color} ::msgcat::mcset es {cool} ::msgcat::mcset es {green} ::msgcat::mcset es {grey} {gris} ::msgcat::mcset es {g} ::msgcat::mcset es {heat} ::msgcat::mcset es {not} ::msgcat::mcset es {only} ::msgcat::mcset es {or center of data} {o centro de los datos} ::msgcat::mcset es {rainbow} ::msgcat::mcset es {red} ::msgcat::mcset es {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom iso8859-1 {Filas de datos transferidas. Puede que haya más disponibles. Quizá quiera ajustar el máximo permitido.}] ::msgcat::mcset es {r} ::msgcat::mcset es {staircase} ::msgcat::mcset es {standard} [encoding convertfrom iso8859-1 {estándar}] ::msgcat::mcset es {x} ::msgcat::mcset es {} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/pt.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000116122�12132042644�013210� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset pt {2D} ::msgcat::mcset pt {3D} ::msgcat::mcset pt {A postscript generation error has occurred} {Um erro ocorreu ao gerar o postscript} ::msgcat::mcset pt {AIP} ::msgcat::mcset pt {Abort} ::msgcat::mcset pt {About SAOImage DS9} {Sobre o SAOImage DS9} ::msgcat::mcset pt {About} {Sobre} ::msgcat::mcset pt {Acknowledgment} [encoding convertfrom iso8859-1 {Créditos}] ::msgcat::mcset pt {Add} {Adicionar} ::msgcat::mcset pt {Advanced} [encoding convertfrom iso8859-1 {Avançado}] ::msgcat::mcset pt {Align} {Alinhar} ::msgcat::mcset pt {All Columns} {Todas as colunas} ::msgcat::mcset pt {All Rows} {Todas as linhas} ::msgcat::mcset pt {All} {Tudo} ::msgcat::mcset pt {Always save files during Backup} ::msgcat::mcset pt {Amplifier} {Aplificador} ::msgcat::mcset pt {An error has occured while updating VO server list} {Um erro ocorreu ao atualizar a lista de servidores VO} ::msgcat::mcset pt {An error has occurred during backup} ::msgcat::mcset pt {An error has occurred during restore} ::msgcat::mcset pt {An error has occurred invoking the Analysis task} [encoding convertfrom iso8859-1 {Um erro ocorreu ao chamar a tarefa de Análise}] ::msgcat::mcset pt {An error has occurred while creating image.} ::msgcat::mcset pt {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset pt {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset pt {An error has occurred while printing} {Um erro ocorreu ao imprimir} ::msgcat::mcset pt {An error has occurred while reading image.} ::msgcat::mcset pt {An error has occurred while saving} {Um erro ocorreu ao salvar} ::msgcat::mcset pt {An error has occurred while writing image.} ::msgcat::mcset pt {An internal error has been detected} ::msgcat::mcset pt {Analysis Command Log} [encoding convertfrom iso8859-1 {Registro de Comandos de Análise}] ::msgcat::mcset pt {Analysis Commands} ::msgcat::mcset pt {Analysis File} ::msgcat::mcset pt {Analysis Log} ::msgcat::mcset pt {Analysis} [encoding convertfrom iso8859-1 {Análise}] ::msgcat::mcset pt {Angle Complement} [encoding convertfrom iso8859-1 {Complemento do ângulo}] ::msgcat::mcset pt {Angles} [encoding convertfrom iso8859-1 {Ângulos}] ::msgcat::mcset pt {Angle} [encoding convertfrom iso8859-1 {Ângulo}] ::msgcat::mcset pt {Annuli} {Annuli} ::msgcat::mcset pt {Annulus} {Annulus} ::msgcat::mcset pt {Apply} {Aplicar} ::msgcat::mcset pt {ArcMin} ::msgcat::mcset pt {ArcSec} ::msgcat::mcset pt {Architecture} {Arquitetura} ::msgcat::mcset pt {Archives} {Arquivos} ::msgcat::mcset pt {Array} ::msgcat::mcset pt {Arrow} {Seta} ::msgcat::mcset pt {Astronomy} ::msgcat::mcset pt {At Startup} ::msgcat::mcset pt {At least 2 different catalogs are required} ::msgcat::mcset pt {Auto Centroid} ::msgcat::mcset pt {Auto Plot 2D} ::msgcat::mcset pt {Auto Plot 3D} ::msgcat::mcset pt {Auto Plot} ::msgcat::mcset pt {Autoload FITS Regions} [encoding convertfrom iso8859-1 {Auto-carregar regiões FITS}] ::msgcat::mcset pt {Autoload} ::msgcat::mcset pt {Automatic} [encoding convertfrom iso8859-1 {Automático}] ::msgcat::mcset pt {Average} [encoding convertfrom iso8859-1 {Média}] ::msgcat::mcset pt {Axes Number} ::msgcat::mcset pt {Axes Title} ::msgcat::mcset pt {Axes} {Eixos} ::msgcat::mcset pt {Axis Label} {Legendas dos eixos} ::msgcat::mcset pt {Axis Length} {Tamanho do eixo} ::msgcat::mcset pt {Axis Numbers} [encoding convertfrom iso8859-1 {Numeração do eixo}] ::msgcat::mcset pt {Axis} {Eixo} ::msgcat::mcset pt {Azimuth} ::msgcat::mcset pt {Background Color} {Cor de fundo} ::msgcat::mcset pt {Background} {Fundo} ::msgcat::mcset pt {Backup} ::msgcat::mcset pt {Back} {Anterior} ::msgcat::mcset pt {Bar Plot Tool} ::msgcat::mcset pt {Bias} ::msgcat::mcset pt {Bin 3rd Column} {Bin terceira coluna} ::msgcat::mcset pt {Bin Center} {Centro do Bin} ::msgcat::mcset pt {Bin Columns} {Binar colunas} ::msgcat::mcset pt {Bin Filter} {Filtro do Bin} ::msgcat::mcset pt {Binning Parameters} [encoding convertfrom iso8859-1 {Parâmetros de Binning}] ::msgcat::mcset pt {Bin} ::msgcat::mcset pt {Black} {Preto} ::msgcat::mcset pt {Blank/Inf/NaN Color} {Cor Preto/Inf/NaN} ::msgcat::mcset pt {Blink Frames} {Blinkar quadros} ::msgcat::mcset pt {Blink Interval} {Intervalo de Blink} ::msgcat::mcset pt {Blink} ::msgcat::mcset pt {Block In} {Bin em} ::msgcat::mcset pt {Block Out} {Bin partir} ::msgcat::mcset pt {Block to Fit Frame} {Bin para ajustar ao Frame} ::msgcat::mcset pt {Block} {Bin} ::msgcat::mcset pt {Blue} {Azul} ::msgcat::mcset pt {Bold} {Negrito} ::msgcat::mcset pt {Border} {Borda} ::msgcat::mcset pt {Box Annulus} {Annulus da Caixa} ::msgcat::mcset pt {Box Panda} {Panda Caixa} ::msgcat::mcset pt {BoxCircle} ::msgcat::mcset pt {Boxcar} ::msgcat::mcset pt {Box} {Caixa} ::msgcat::mcset pt {Broadcast} ::msgcat::mcset pt {Browser} ::msgcat::mcset pt {Browse} {Navegar} ::msgcat::mcset pt {Buffer} ::msgcat::mcset pt {Buttonbar} ::msgcat::mcset pt {Buttons} {Botoes} ::msgcat::mcset pt {Bytes} ::msgcat::mcset pt {CMYK} ::msgcat::mcset pt {Can Delete} {Pode Apagar} ::msgcat::mcset pt {Can Edit} {Pode Editar} ::msgcat::mcset pt {Can Move} {Pode Mover} ::msgcat::mcset pt {Can Rotate} {Pode Rodar} ::msgcat::mcset pt {Cancel} {Cancelar} ::msgcat::mcset pt {Catalog Server} [encoding convertfrom iso8859-1 {Servidor do Catálogo}] ::msgcat::mcset pt {Catalog Tool} [encoding convertfrom iso8859-1 {Ferramenta de Catálogos}] ::msgcat::mcset pt {Catalogs} [encoding convertfrom iso8859-1 {Catálogos}] ::msgcat::mcset pt {Catalog} [encoding convertfrom iso8859-1 {Catálogo}] ::msgcat::mcset pt {Center Image} {Centralizar Imagem} ::msgcat::mcset pt {Center Non-modal Dialogs} ::msgcat::mcset pt {Center} {Centro} ::msgcat::mcset pt {Centroid Parameters} ::msgcat::mcset pt {Centroid} ::msgcat::mcset pt {Circle} {Circulo} ::msgcat::mcset pt {Clear All} {Limpar tudo} ::msgcat::mcset pt {Clear Analysis Commands} [encoding convertfrom iso8859-1 {Limpar Comandos de Análise}] ::msgcat::mcset pt {Clear Cache} {Limpar cache} ::msgcat::mcset pt {Clear Data} {Limpar dados} ::msgcat::mcset pt {Clear External Analysis Commands?} {Limpar Comandos de Análise Externos?} ::msgcat::mcset pt {Clear Filter} {Limpar Filtro} ::msgcat::mcset pt {Clear Frame} {Limpar Frame} ::msgcat::mcset pt {Clear Preferences?} [encoding convertfrom iso8859-1 {Limpar preferências?}] ::msgcat::mcset pt {Clear Preferences} [encoding convertfrom iso8859-1 {Limpar preferências}] ::msgcat::mcset pt {Clear} {Limpar} ::msgcat::mcset pt {Click to Center} {Clique para centralizar} ::msgcat::mcset pt {Close} {Fechar} ::msgcat::mcset pt {Colorbar Size} ::msgcat::mcset pt {Colorbar} {Barra de Cores} ::msgcat::mcset pt {Colormap Parameters} [encoding convertfrom iso8859-1 {Parâmetros do Mapa de Cores}] ::msgcat::mcset pt {Colormap} {Mapa de Cores} ::msgcat::mcset pt {Color} {Cor} ::msgcat::mcset pt {Columns} {Colunas} ::msgcat::mcset pt {Column} {Coluna} ::msgcat::mcset pt {Command} ::msgcat::mcset pt {Compass} {Compasso} ::msgcat::mcset pt {Composite Region} ::msgcat::mcset pt {Composite} ::msgcat::mcset pt {Compression} [encoding convertfrom iso8859-1 {Compressão}] ::msgcat::mcset pt {Configure} {Configurar} ::msgcat::mcset pt {Connect Directly} {Conectar diretamente} ::msgcat::mcset pt {Connect SAMP} ::msgcat::mcset pt {Connect Using Web Proxy} {Connectar usando Proxy Web} ::msgcat::mcset pt {Connect} ::msgcat::mcset pt {Console} ::msgcat::mcset pt {Contour Parameters} [encoding convertfrom iso8859-1 {Parâmetros de contorno}] ::msgcat::mcset pt {Contours} {Contornos} ::msgcat::mcset pt {Contour} ::msgcat::mcset pt {Contrast} {Contraste} ::msgcat::mcset pt {Contributed} ::msgcat::mcset pt {Convert to Polygons} [encoding convertfrom iso8859-1 {Converter para polígonos}] ::msgcat::mcset pt {Coordinate Grid Parameters} [encoding convertfrom iso8859-1 {Parâmetros do Grid de Coordenadas}] ::msgcat::mcset pt {Coordinate Grid} {Grid de Coordenadas} ::msgcat::mcset pt {Coordinate System} {Sistema de Coordenadas} ::msgcat::mcset pt {Coordinates} ::msgcat::mcset pt {Coordinate} {Coordenada} ::msgcat::mcset pt {Copy Contours} {Copiar Contornos} ::msgcat::mcset pt {Copy to Regions} [encoding convertfrom iso8859-1 {Copiar para Regiões}] ::msgcat::mcset pt {Copy} {Copiar} ::msgcat::mcset pt {Create Movie} ::msgcat::mcset pt {Create New Frame on Download} {Criar novo Frame ao carregar} ::msgcat::mcset pt {Create} ::msgcat::mcset pt {Crop Parameters} ::msgcat::mcset pt {Crop} ::msgcat::mcset pt {Crosshair To} {Cruz para} ::msgcat::mcset pt {Crosshair} {Cruz} ::msgcat::mcset pt {Cross} {Cruz} ::msgcat::mcset pt {Cube} ::msgcat::mcset pt {Current Frame} {Frame atual} ::msgcat::mcset pt {Current Range} {Intervalo atual} ::msgcat::mcset pt {Current} {Atual} ::msgcat::mcset pt {Cursor} ::msgcat::mcset pt {Cut} {Cortar} ::msgcat::mcset pt {Cyan} {Ciano} ::msgcat::mcset pt {DPI} ::msgcat::mcset pt {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset pt {DS9 has detected a newer version of a preferences file and therefore will not process this file.} [encoding convertfrom iso8859-1 {O DS9 detectou uma nova versão de um arquivo de preferências e logo não processará esse arquivo.}] ::msgcat::mcset pt {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset pt {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-1 {O DS9 detectou um arquivo de preferências antigo, você deseja atualizar?}] ::msgcat::mcset pt {DS9 will complete the initialization process} [encoding convertfrom iso8859-1 {O DS9 completou o processo de inicialização}] ::msgcat::mcset pt {Dash} [encoding convertfrom iso8859-1 {Traço}] ::msgcat::mcset pt {Data Format} {Formato de dados} ::msgcat::mcset pt {Dataset} {Conjunto de dados} ::msgcat::mcset pt {Data} ::msgcat::mcset pt {Decrease} {Diminuir} ::msgcat::mcset pt {Default All Files} ::msgcat::mcset pt {Default Format} ::msgcat::mcset pt {Default Length} ::msgcat::mcset pt {Default} [encoding convertfrom iso8859-1 {Padrão}] ::msgcat::mcset pt {Degrees} {Graus} ::msgcat::mcset pt {Delete All Frames?} {Apagar todos Frames?} ::msgcat::mcset pt {Delete All Frames} {Apagar todos Frames} ::msgcat::mcset pt {Delete All Groups?} {Apagar todos os grupos?} ::msgcat::mcset pt {Delete All Groups} {Apagar todos os grupos} ::msgcat::mcset pt {Delete All Regions?} {Apagar todas as Regiões?} ::msgcat::mcset pt {Delete All Regions} {Apagar todas as Regiões} ::msgcat::mcset pt {Delete All} ::msgcat::mcset pt {Delete Color Tags} ::msgcat::mcset pt {Delete Frame} {Apague o Frame} ::msgcat::mcset pt {Delete Group} {Apague o Grupo} ::msgcat::mcset pt {Delete Selected Regions} [encoding convertfrom iso8859-1 {Apagar Regiões Selecionadas}] ::msgcat::mcset pt {Delete} {Apagar} ::msgcat::mcset pt {Depth} {Profundidade} ::msgcat::mcset pt {Detector} ::msgcat::mcset pt {Dialog Box} {Box de dialog} ::msgcat::mcset pt {Diamond} {Diamante} ::msgcat::mcset pt {Dimension} [encoding convertfrom iso8859-1 {Dimensão}] ::msgcat::mcset pt {Disconnect} ::msgcat::mcset pt {Discrete} {Discreto} ::msgcat::mcset pt {Display Header} ::msgcat::mcset pt {Display Size} {Mostar tamanho} ::msgcat::mcset pt {Dissolve} ::msgcat::mcset pt {Distance} ::msgcat::mcset pt {Download Colormap} ::msgcat::mcset pt {Download VOTABLE format if available} ::msgcat::mcset pt {Drag to Center} {Arrate para centralizar} ::msgcat::mcset pt {Duplicate Data} ::msgcat::mcset pt {East} {Leste} ::msgcat::mcset pt {Ecliptic} {Ecliptico} ::msgcat::mcset pt {Edit Group Name} {Editar nome do Grupo} ::msgcat::mcset pt {Edit} {Editar} ::msgcat::mcset pt {Element} ::msgcat::mcset pt {Elevation} ::msgcat::mcset pt {Ellipse Panda} ::msgcat::mcset pt {Ellipse} {Elipse} ::msgcat::mcset pt {Elliptical Annulus} {Annulus Elipse} ::msgcat::mcset pt {Elliptical Panda} [encoding convertfrom iso8859-1 {Panda Elíptico}] ::msgcat::mcset pt {Enable Confirmation Dialogs} {} ::msgcat::mcset pt {Enable} ::msgcat::mcset pt {End} {Fim} ::msgcat::mcset pt {Enter Color} ::msgcat::mcset pt {Enter Font Size} ::msgcat::mcset pt {Enter Group Name} {Entre o nome do Grupo} ::msgcat::mcset pt {Enter Search Expression} ::msgcat::mcset pt {Enter URL} ::msgcat::mcset pt {Entry} ::msgcat::mcset pt {Equal Area} [encoding convertfrom iso8859-1 {Área Igual}] ::msgcat::mcset pt {Equal Distance} [encoding convertfrom iso8859-1 {Distância Igual}] ::msgcat::mcset pt {Equal Spacing} ::msgcat::mcset pt {Equal Value} ::msgcat::mcset pt {Error code was returned} [encoding convertfrom iso8859-1 {Retornou código de erro}] ::msgcat::mcset pt {Error} {Erro} ::msgcat::mcset pt {Examine Frame} {Examinar Frame} ::msgcat::mcset pt {Examine} {Examinar} ::msgcat::mcset pt {Exclude} {Excluir} ::msgcat::mcset pt {Executing TCL code is not enabled} ::msgcat::mcset pt {Exit} {Sair} ::msgcat::mcset pt {Export Array} ::msgcat::mcset pt {Export} ::msgcat::mcset pt {Extention} ::msgcat::mcset pt {Exterior Axes} {Eixos exteriores} ::msgcat::mcset pt {Exterior Numerics} [encoding convertfrom iso8859-1 {Numeração exterior}] ::msgcat::mcset pt {FAQ} ::msgcat::mcset pt {FK4} ::msgcat::mcset pt {FK5} ::msgcat::mcset pt {Factor} ::msgcat::mcset pt {File not Found or Unable to load FITS data MIME type} [encoding convertfrom iso8859-1 {Arquivo não encontrado ou incapaz de carregar dados FITS do tipo MIME}] ::msgcat::mcset pt {Filename} {Nome de Arquivo} ::msgcat::mcset pt {File} {Arquivo} ::msgcat::mcset pt {Fill} ::msgcat::mcset pt {Filter} {Filtro} ::msgcat::mcset pt {Find Next} [encoding convertfrom iso8859-1 {Encontrar próximo}] ::msgcat::mcset pt {Find} {Encontrado} ::msgcat::mcset pt {First Frame} ::msgcat::mcset pt {First} {Primeiro} ::msgcat::mcset pt {Fits} ::msgcat::mcset pt {Fixed in Size} {Fixa em tamanho} ::msgcat::mcset pt {Flip} ::msgcat::mcset pt {Font} {Fonte} ::msgcat::mcset pt {For more information, use --help} ::msgcat::mcset pt {Format} {Formato} ::msgcat::mcset pt {Forward} {Frente} ::msgcat::mcset pt {Found} {Encontrado} ::msgcat::mcset pt {Frame Information} [encoding convertfrom iso8859-1 {Informação do Frame}] ::msgcat::mcset pt {Frame Parameters} ::msgcat::mcset pt {Frames} ::msgcat::mcset pt {Frame} {Frame} ::msgcat::mcset pt {From} ::msgcat::mcset pt {Front} {Frente} ::msgcat::mcset pt {Full Range} {Intervalo completo} ::msgcat::mcset pt {Function} [encoding convertfrom iso8859-1 {Função}] ::msgcat::mcset pt {GUI Font} ::msgcat::mcset pt {Galactic} [encoding convertfrom iso8859-1 {Galáctico}] ::msgcat::mcset pt {Gap} ::msgcat::mcset pt {Gaussian} {Gaussiano} ::msgcat::mcset pt {General} {Geral} ::msgcat::mcset pt {Generate} {Gerar} ::msgcat::mcset pt {Generating Regions} [encoding convertfrom iso8859-1 {Gerando regiões}] ::msgcat::mcset pt {Get Information} [encoding convertfrom iso8859-1 {Obter informações}] ::msgcat::mcset pt {Global Properties} ::msgcat::mcset pt {Global} ::msgcat::mcset pt {Goto Frame} ::msgcat::mcset pt {Graph Horz} ::msgcat::mcset pt {Graph Vert} ::msgcat::mcset pt {Graphics} [encoding convertfrom iso8859-1 {Gráficos}] ::msgcat::mcset pt {Graphs} ::msgcat::mcset pt {Graph} [encoding convertfrom iso8859-1 {Gráfico}] ::msgcat::mcset pt {Grayscale} {Tons de cinza} ::msgcat::mcset pt {Green} {Verde} ::msgcat::mcset pt {Grid Gap} ::msgcat::mcset pt {Grid} {Grade} ::msgcat::mcset pt {Groups} {Grupos} ::msgcat::mcset pt {HTTP} ::msgcat::mcset pt {Header} [encoding convertfrom iso8859-1 {Cabeçário}] ::msgcat::mcset pt {Height} {Altura} ::msgcat::mcset pt {Help Desk} {Centro de ajuda} ::msgcat::mcset pt {Help Me Choose} {Ajude-me escolher} ::msgcat::mcset pt {Help} {Ajuda} ::msgcat::mcset pt {Hide All} {Esconda tudo} ::msgcat::mcset pt {Highlite} ::msgcat::mcset pt {High} {Alto} ::msgcat::mcset pt {Histogram Equalization} [encoding convertfrom iso8859-1 {Equalização de Histograma}] ::msgcat::mcset pt {Histogram} {Histograma} ::msgcat::mcset pt {Horizontal Graph} [encoding convertfrom iso8859-1 {Gráfico Horizontal}] ::msgcat::mcset pt {Horizontal Layout} {Layout Horizontal} ::msgcat::mcset pt {Horizontal} ::msgcat::mcset pt {IAU Location Code} ::msgcat::mcset pt {ICRS} ::msgcat::mcset pt {Identification} [encoding convertfrom iso8859-1 {Identificação}] ::msgcat::mcset pt {If} {Se} ::msgcat::mcset pt {Image Servers} {Servidores de Imagem} ::msgcat::mcset pt {Image} {Imagem} ::msgcat::mcset pt {Import Array} ::msgcat::mcset pt {Import} ::msgcat::mcset pt {Include} {Incluir} ::msgcat::mcset pt {Increase} {Aumento} ::msgcat::mcset pt {Information Panel} [encoding convertfrom iso8859-1 {Painel de informação}] ::msgcat::mcset pt {Information} [encoding convertfrom iso8859-1 {Informação}] ::msgcat::mcset pt {Initialize XPA} {Inicialize XPA} ::msgcat::mcset pt {Inner} {Interno} ::msgcat::mcset pt {Instrument FOV} {FOV do instrumento} ::msgcat::mcset pt {Interior Axes} {Eixos Interiores} ::msgcat::mcset pt {Interior Numerics} [encoding convertfrom iso8859-1 {Numeração Interior}] ::msgcat::mcset pt {Internal Parse Error} ::msgcat::mcset pt {Interval} {Intervalo} ::msgcat::mcset pt {Invalid Column Name} ::msgcat::mcset pt {Invalid formated multipart/mixed mime type message} [encoding convertfrom iso8859-1 {Mensagem tipo MIME multiparte/mista em formato inválido}] ::msgcat::mcset pt {Invert Colormap} {Inverter mapa de cores} ::msgcat::mcset pt {Invert Selection} [encoding convertfrom iso8859-1 {Inverter Seleção}] ::msgcat::mcset pt {Invert} {Inverter} ::msgcat::mcset pt {Italic} [encoding convertfrom iso8859-1 {Itálico}] ::msgcat::mcset pt {Items Found} [encoding convertfrom iso8859-1 {Ítens Encontrados}] ::msgcat::mcset pt {Iteration} ::msgcat::mcset pt {JPEG Quality Factor} {Fator de qualidade JPEG} ::msgcat::mcset pt {Keep-Alive} ::msgcat::mcset pt {Kernel} ::msgcat::mcset pt {Keyboard Shortcuts} {Atalhos do teclado} ::msgcat::mcset pt {Keyboard} {Teclado} ::msgcat::mcset pt {Labels} {Legendas} ::msgcat::mcset pt {Label} {Legenda} ::msgcat::mcset pt {Landscape} {Paisagem} ::msgcat::mcset pt {Language} [encoding convertfrom iso8859-1 {Língua}] ::msgcat::mcset pt {Last Frame} ::msgcat::mcset pt {Last} [encoding convertfrom iso8859-1 {Último}] ::msgcat::mcset pt {Layout Horz} ::msgcat::mcset pt {Layout Vert} ::msgcat::mcset pt {Layout} ::msgcat::mcset pt {Left} ::msgcat::mcset pt {Legal} ::msgcat::mcset pt {Length} {Comprimento} ::msgcat::mcset pt {Letter} {Carta} ::msgcat::mcset pt {Levels} [encoding convertfrom iso8859-1 {Níveis}] ::msgcat::mcset pt {Level} {Nível} ::msgcat::mcset pt {Limits} {Limiter} ::msgcat::mcset pt {Line Plot Tool} ::msgcat::mcset pt {Linear} ::msgcat::mcset pt {Line} {Linha} ::msgcat::mcset pt {List Data} ::msgcat::mcset pt {List Regions} [encoding convertfrom iso8859-1 {Listar Regiões}] ::msgcat::mcset pt {List} {Listar} ::msgcat::mcset pt {Load Analysis Commands} [encoding convertfrom iso8859-1 {Ler Comandos de Análise}] ::msgcat::mcset pt {Load Color Tags} ::msgcat::mcset pt {Load Colormap} {Carregar Mapa de Cores} ::msgcat::mcset pt {Load Configuration} [encoding convertfrom iso8859-1 {Carregar Configuração}] ::msgcat::mcset pt {Load Contour Levels} [encoding convertfrom iso8859-1 {Carregar Níveis de Contorno}] ::msgcat::mcset pt {Load Contours} {Carregar Contornos} ::msgcat::mcset pt {Load Contrast/Bias} {Carregar Contraste/Bias} ::msgcat::mcset pt {Load Data} {Carregar Dados} ::msgcat::mcset pt {Load Mosaic} {Carregar Mosaico} ::msgcat::mcset pt {Load Regions} [encoding convertfrom iso8859-1 {Carregar Regiões}] ::msgcat::mcset pt {Load Template} {Carregar Template} ::msgcat::mcset pt {Load into All Frames} ::msgcat::mcset pt {Load into Current Frame} ::msgcat::mcset pt {Loading Catalog} ::msgcat::mcset pt {Loading} ::msgcat::mcset pt {Load} {Carregar} ::msgcat::mcset pt {Local} ::msgcat::mcset pt {Lock Bin} ::msgcat::mcset pt {Lock Color} ::msgcat::mcset pt {Lock Crop Amplifier} ::msgcat::mcset pt {Lock Crop Detector} ::msgcat::mcset pt {Lock Crop Image} ::msgcat::mcset pt {Lock Crop None} ::msgcat::mcset pt {Lock Crop Physical} ::msgcat::mcset pt {Lock Crop WCS} ::msgcat::mcset pt {Lock Crosshair Amplifier} ::msgcat::mcset pt {Lock Crosshair Detector} ::msgcat::mcset pt {Lock Crosshair Image} ::msgcat::mcset pt {Lock Crosshair None} ::msgcat::mcset pt {Lock Crosshair Physical} ::msgcat::mcset pt {Lock Crosshair WCS} ::msgcat::mcset pt {Lock Frame Amplifier} ::msgcat::mcset pt {Lock Frame Detector} ::msgcat::mcset pt {Lock Frame Image} ::msgcat::mcset pt {Lock Frame None} ::msgcat::mcset pt {Lock Frame Physical} ::msgcat::mcset pt {Lock Frame WCS} ::msgcat::mcset pt {Lock Scale} ::msgcat::mcset pt {Lock Slice} ::msgcat::mcset pt {Lock Smooth} ::msgcat::mcset pt {Lock} {Travar} ::msgcat::mcset pt {Log Exponent} ::msgcat::mcset pt {Log} ::msgcat::mcset pt {Low High} {Baixo Alto} ::msgcat::mcset pt {Lower Left Back} ::msgcat::mcset pt {Lower Left Front} ::msgcat::mcset pt {Lower Right Back} ::msgcat::mcset pt {Lower Right Front} ::msgcat::mcset pt {Low} {Baixo} ::msgcat::mcset pt {MIP} ::msgcat::mcset pt {Magenta} {Magenta} ::msgcat::mcset pt {Magnification} ::msgcat::mcset pt {Magnifier} {Lente} ::msgcat::mcset pt {Major} ::msgcat::mcset pt {Manual} ::msgcat::mcset pt {Mask Parameters} [encoding convertfrom iso8859-1 {Parâmetros da máscara}] ::msgcat::mcset pt {Match Bin} ::msgcat::mcset pt {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset pt {Match Color} ::msgcat::mcset pt {Match Crop Amplifier} ::msgcat::mcset pt {Match Crop Detector} ::msgcat::mcset pt {Match Crop Image} ::msgcat::mcset pt {Match Crop Physical} ::msgcat::mcset pt {Match Crop WCS} ::msgcat::mcset pt {Match Crosshair Amplifier} ::msgcat::mcset pt {Match Crosshair Detector} ::msgcat::mcset pt {Match Crosshair Image} ::msgcat::mcset pt {Match Crosshair Physical} ::msgcat::mcset pt {Match Crosshair WCS} ::msgcat::mcset pt {Match Frame Amplifier} ::msgcat::mcset pt {Match Frame Detector} ::msgcat::mcset pt {Match Frame Image} ::msgcat::mcset pt {Match Frame Physical} ::msgcat::mcset pt {Match Frame WCS} ::msgcat::mcset pt {Match Scale} ::msgcat::mcset pt {Match Slice} ::msgcat::mcset pt {Match Smooth} ::msgcat::mcset pt {Match} ::msgcat::mcset pt {Math Function} [encoding convertfrom iso8859-1 {Função Matemática}] ::msgcat::mcset pt {Max Rows} [encoding convertfrom iso8859-1 {Máximas linhas}] ::msgcat::mcset pt {Max} [encoding convertfrom iso8859-1 {Máximo}] ::msgcat::mcset pt {Menus and Buttons} ::msgcat::mcset pt {Menu} ::msgcat::mcset pt {Message Log} ::msgcat::mcset pt {Method} [encoding convertfrom iso8859-1 {Método}] ::msgcat::mcset pt {Min Max Parameters} ::msgcat::mcset pt {Min Max} [encoding convertfrom iso8859-1 {Min Máx}] ::msgcat::mcset pt {Minor} {Menor} ::msgcat::mcset pt {Minutes} ::msgcat::mcset pt {Min} ::msgcat::mcset pt {Mission} [encoding convertfrom iso8859-1 {Missão}] ::msgcat::mcset pt {Mode} ::msgcat::mcset pt {Mosaic IRAF Segment} ::msgcat::mcset pt {Mosaic IRAF} ::msgcat::mcset pt {Mosaic WCS Segment} ::msgcat::mcset pt {Mosaic WCS} ::msgcat::mcset pt {Mosaic WFPC2} ::msgcat::mcset pt {Mosaic} ::msgcat::mcset pt {Mouse & Keyboard} ::msgcat::mcset pt {Mouse Wheel Bin} ::msgcat::mcset pt {Mouse Wheel Zoom} ::msgcat::mcset pt {Move Back} ::msgcat::mcset pt {Move First} ::msgcat::mcset pt {Move Forward} ::msgcat::mcset pt {Move Frame} ::msgcat::mcset pt {Move Last} ::msgcat::mcset pt {Move to Back} [encoding convertfrom iso8859-1 {Move para trás}] ::msgcat::mcset pt {Move to Front} {Mover para frente} ::msgcat::mcset pt {Movie} ::msgcat::mcset pt {Multiple Extension Cube} ::msgcat::mcset pt {Multiple Extension Frames} ::msgcat::mcset pt {Multiple WCS} {Multiplos WCS} ::msgcat::mcset pt {NRRD} ::msgcat::mcset pt {Name Resolution} {Resolver o Nome} ::msgcat::mcset pt {Name Server} {Servidor de Nomes} ::msgcat::mcset pt {Name or Designation} [encoding convertfrom iso8859-1 {Nome ou designação}] ::msgcat::mcset pt {Name} ::msgcat::mcset pt {Native Dialog} {Dialog Nativo} ::msgcat::mcset pt {Native} ::msgcat::mcset pt {New 3D} ::msgcat::mcset pt {New Features} {Novo} ::msgcat::mcset pt {New Frame 3D} ::msgcat::mcset pt {New Frame RGB} {Novo Frame RGB} ::msgcat::mcset pt {New Frame each Time} ::msgcat::mcset pt {New Frame} {Novo frame} ::msgcat::mcset pt {New Group} {Novo grupo} ::msgcat::mcset pt {New RGB} {Novo RGB} ::msgcat::mcset pt {New} {Novo} ::msgcat::mcset pt {Next Frame} ::msgcat::mcset pt {Next} [encoding convertfrom iso8859-1 {Próximo}] ::msgcat::mcset pt {No Catalog specified} [encoding convertfrom iso8859-1 {Nenhum catálogo especificado}] ::msgcat::mcset pt {No Items Found} [encoding convertfrom iso8859-1 {Nenhum ítem encontrado}] ::msgcat::mcset pt {No current frame} ::msgcat::mcset pt {No data available at } [encoding convertfrom iso8859-1 {Nenhum dado disponível em }] ::msgcat::mcset pt {Non-zero} ::msgcat::mcset pt {None} {Nenhum} ::msgcat::mcset pt {Normal} ::msgcat::mcset pt {North} {Norte} ::msgcat::mcset pt {Not Found} ::msgcat::mcset pt {No} {Não} ::msgcat::mcset pt {Number of Samples} ::msgcat::mcset pt {Number of Threads} ::msgcat::mcset pt {Number of Ticks} ::msgcat::mcset pt {Number} [encoding convertfrom iso8859-1 {Número}] ::msgcat::mcset pt {Numerics} ::msgcat::mcset pt {OK} ::msgcat::mcset pt {Object} {Objeto} ::msgcat::mcset pt {Open File} {Abrir Arquivo} ::msgcat::mcset pt {Open TCL Console} ::msgcat::mcset pt {Open URL} {Abrir URL} ::msgcat::mcset pt {Open as} ::msgcat::mcset pt {Open} {Abrir} ::msgcat::mcset pt {Operator} {Operador} ::msgcat::mcset pt {Orientation} [encoding convertfrom iso8859-1 {Orientação}] ::msgcat::mcset pt {Origin} ::msgcat::mcset pt {Oscillate} ::msgcat::mcset pt {Other Color} ::msgcat::mcset pt {Other Font Size} ::msgcat::mcset pt {Other} {Outro} ::msgcat::mcset pt {Outer} {Fora} ::msgcat::mcset pt {PS Page Setup} ::msgcat::mcset pt {PS Print} ::msgcat::mcset pt {Page Setup} [encoding convertfrom iso8859-1 {Configuracoes de página}] ::msgcat::mcset pt {Page Source} [encoding convertfrom iso8859-1 {Fonte da página}] ::msgcat::mcset pt {Pan To} ::msgcat::mcset pt {Pan Zoom Rotate Parameters} ::msgcat::mcset pt {Pan Zoom} ::msgcat::mcset pt {Pan then Zoom} ::msgcat::mcset pt {Panda} {Panda} ::msgcat::mcset pt {Panner} ::msgcat::mcset pt {Pan} ::msgcat::mcset pt {Parameters} [encoding convertfrom iso8859-1 {Parâmetros}] ::msgcat::mcset pt {Password} {Senha} ::msgcat::mcset pt {Paste Contours} {Colar Contornos} ::msgcat::mcset pt {Paste} {Colar} ::msgcat::mcset pt {Physical} [encoding convertfrom iso8859-1 {Físico}] ::msgcat::mcset pt {Pixel Distribution} [encoding convertfrom iso8859-1 {Distribuição de Pixels}] ::msgcat::mcset pt {Pixel Size} {Tamanho do Pixel} ::msgcat::mcset pt {Pixel Table} {Tabela de Pixels} ::msgcat::mcset pt {Pixels} ::msgcat::mcset pt {Play} {Execute} ::msgcat::mcset pt {Please Select a Region} ::msgcat::mcset pt {Please specify width, height, and either name or (ra,dec)} ::msgcat::mcset pt {Plot 2D} ::msgcat::mcset pt {Plot 3D} ::msgcat::mcset pt {Plot Title} [encoding convertfrom iso8859-1 {Título}] ::msgcat::mcset pt {Plotting Regions} ::msgcat::mcset pt {Plot} ::msgcat::mcset pt {Plus} {Mais} ::msgcat::mcset pt {Pointer} {Ponteiro} ::msgcat::mcset pt {Points} {Pntos} ::msgcat::mcset pt {Point} {Ponto} ::msgcat::mcset pt {Polygon} [encoding convertfrom iso8859-1 {Polígono}] ::msgcat::mcset pt {Portrait} {Retrato} ::msgcat::mcset pt {Poster} ::msgcat::mcset pt {Postscript Page Setup} ::msgcat::mcset pt {Postscript Print} ::msgcat::mcset pt {Postscript} ::msgcat::mcset pt {Power} [encoding convertfrom iso8859-1 {Potência}] ::msgcat::mcset pt {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} ::msgcat::mcset pt {Preferences} [encoding convertfrom iso8859-1 {Preferências}] ::msgcat::mcset pt {Preserve During Load} {Preservar durante a carga} ::msgcat::mcset pt {Previous Frame} ::msgcat::mcset pt {Previous} {Anterior} ::msgcat::mcset pt {Print Coordinates} {Imprimir Coordenadas} ::msgcat::mcset pt {Print To} {Imprimir Para} ::msgcat::mcset pt {Printer} {Impressora} ::msgcat::mcset pt {Print} {Imprimir} ::msgcat::mcset pt {Projection} [encoding convertfrom iso8859-1 {Projeção}] ::msgcat::mcset pt {Properties} {Propriedades} ::msgcat::mcset pt {Property} {Propriedade} ::msgcat::mcset pt {Proxy Host} {Host Proxy} ::msgcat::mcset pt {Proxy Port} {Porta do Proxy} ::msgcat::mcset pt {Publication} [encoding convertfrom iso8859-1 {Publicação}] ::msgcat::mcset pt {Quadratic} [encoding convertfrom iso8859-1 {Quadrático}] ::msgcat::mcset pt {RGB Array} ::msgcat::mcset pt {RGB Cube} ::msgcat::mcset pt {RGB Image} ::msgcat::mcset pt {RGB} ::msgcat::mcset pt {Radial Profile} ::msgcat::mcset pt {Radius} {Raio} ::msgcat::mcset pt {Range} ::msgcat::mcset pt {Redo} {Refazer} ::msgcat::mcset pt {Red} {Vermelho} ::msgcat::mcset pt {Reference Manual} [encoding convertfrom iso8859-1 {Manual de referência}] ::msgcat::mcset pt {Reference} [encoding convertfrom iso8859-1 {Referência}] ::msgcat::mcset pt {Refresh Frame} {Recarregar Frame} ::msgcat::mcset pt {Refresh} ::msgcat::mcset pt {Region Parameters} ::msgcat::mcset pt {Region} [encoding convertfrom iso8859-1 {Região}] ::msgcat::mcset pt {Release Notes} [encoding convertfrom iso8859-1 {Notas das Versão}] ::msgcat::mcset pt {Release} [encoding convertfrom iso8859-1 {Versão}] ::msgcat::mcset pt {Reload} {Recarregar} ::msgcat::mcset pt {Repeat} ::msgcat::mcset pt {Reset Colormap} {Reiniciar mapa de cores} ::msgcat::mcset pt {Reset Frame} {Reiniciar Frame} ::msgcat::mcset pt {Reset} ::msgcat::mcset pt {Restore} ::msgcat::mcset pt {Retrieve} {Receber} ::msgcat::mcset pt {Return} ::msgcat::mcset pt {Right} ::msgcat::mcset pt {Roman} ::msgcat::mcset pt {Rotate} {Rodar} ::msgcat::mcset pt {Rows} {Linhas} ::msgcat::mcset pt {Row} ::msgcat::mcset pt {Ruler} [encoding convertfrom iso8859-1 {Régua}] ::msgcat::mcset pt {SAMP Image} ::msgcat::mcset pt {SAMP Table} ::msgcat::mcset pt {SAMP: already connected} ::msgcat::mcset pt {SAMP: internal error} ::msgcat::mcset pt {SAMP: not connected} ::msgcat::mcset pt {SAMP: unable to locate HUB} ::msgcat::mcset pt {SAMP} ::msgcat::mcset pt {Sample Increment} {Incremento da Amostra} ::msgcat::mcset pt {Sample Parameters} [encoding convertfrom iso8859-1 {Parâmetros da Amostra}] ::msgcat::mcset pt {Samples per Line} {Amostras por Linha} ::msgcat::mcset pt {Sample} {Amostra} ::msgcat::mcset pt {Save 3D Movie} ::msgcat::mcset pt {Save Color Tags} ::msgcat::mcset pt {Save Colormap} {Salvar Mapa de Cores} ::msgcat::mcset pt {Save Configuration} [encoding convertfrom iso8859-1 {Salvar Configuração}] ::msgcat::mcset pt {Save Contour Levels} {Salvar Níveis de Contorno} ::msgcat::mcset pt {Save Contours} {Salvar Contornos} ::msgcat::mcset pt {Save Contrast/Bias} {Salvar Contraste/Bias} ::msgcat::mcset pt {Save Data} {Salvar Dados} ::msgcat::mcset pt {Save Image on Download} ::msgcat::mcset pt {Save Image} {Salvar Imagem} ::msgcat::mcset pt {Save Regions} [encoding convertfrom iso8859-1 {Salvar Regiões}] ::msgcat::mcset pt {Save Template} ::msgcat::mcset pt {Save as} ::msgcat::mcset pt {Save} {Salvar} ::msgcat::mcset pt {Scale Parameters} [encoding convertfrom iso8859-1 {Parâmetros da Escala}] ::msgcat::mcset pt {Scale} {Escala} ::msgcat::mcset pt {Scan} ::msgcat::mcset pt {Scatter Plot Tool} ::msgcat::mcset pt {Scope} {Escopo} ::msgcat::mcset pt {Search for Catalogs} [encoding convertfrom iso8859-1 {Buscar Catálogos}] ::msgcat::mcset pt {Searching for catalogs} [encoding convertfrom iso8859-1 {Buscando Catálogos}] ::msgcat::mcset pt {Seconds} {Segundos} ::msgcat::mcset pt {Select All} {Selecionar tudo} ::msgcat::mcset pt {Select Coordinate System } {Selecionar Sistema de Coordenadas} ::msgcat::mcset pt {Select None} {Selecionar Nada} ::msgcat::mcset pt {Send} ::msgcat::mcset pt {Server} {Servidor} ::msgcat::mcset pt {Sexagesimal} ::msgcat::mcset pt {Shape} {Formato} ::msgcat::mcset pt {Show All} {Mostre todos} ::msgcat::mcset pt {Show Command} ::msgcat::mcset pt {Show Compass} ::msgcat::mcset pt {Show Text} ::msgcat::mcset pt {Show/Hide Frames} {Mostra/Esconde Frames} ::msgcat::mcset pt {Show} {Mostrar} ::msgcat::mcset pt {Single Frame} [encoding convertfrom iso8859-1 {Frame Único}] ::msgcat::mcset pt {Single} [encoding convertfrom iso8859-1 {Único}] ::msgcat::mcset pt {Sites} ::msgcat::mcset pt {Size/Radius} {Tamanho/Raio} ::msgcat::mcset pt {Size} {Tamanho} ::msgcat::mcset pt {Skip First} {Pular Primeiro} ::msgcat::mcset pt {Slice} ::msgcat::mcset pt {Smooth Parameters} [encoding convertfrom iso8859-1 {Parâmetros da Suavização}] ::msgcat::mcset pt {Smoothness} ::msgcat::mcset pt {Smooth} {Suavizar} ::msgcat::mcset pt {Sorry, DS9 does not support} [encoding convertfrom iso8859-1 {Perdão, o DS9 não suporta}] ::msgcat::mcset pt {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} [encoding convertfrom iso8859-1 {Perdão, o DS9 requer um visual Pesudocolor8, Truecolor8, Truecolor16, Truecolor24 acessível}] ::msgcat::mcset pt {Sort} {Organizar} ::msgcat::mcset pt {Source TCL} [encoding convertfrom iso8859-1 {Código TCL}] ::msgcat::mcset pt {Source} {Fonte} ::msgcat::mcset pt {Space Equal Distance} ::msgcat::mcset pt {Space Equal Value} ::msgcat::mcset pt {Spacing} [encoding convertfrom iso8859-1 {Espaçamento}] ::msgcat::mcset pt {Square Root} {Raiz Quadrada} ::msgcat::mcset pt {Squared} {Quadrado} ::msgcat::mcset pt {Starbase} ::msgcat::mcset pt {Startup} ::msgcat::mcset pt {Start} {Iniciar} ::msgcat::mcset pt {Statistics} ::msgcat::mcset pt {Status} {Estado} ::msgcat::mcset pt {Step} {Passo} ::msgcat::mcset pt {Stop} {Parar} ::msgcat::mcset pt {Story of SAOImage DS9} ::msgcat::mcset pt {Story} ::msgcat::mcset pt {Sum} {Soma} ::msgcat::mcset pt {Symbol Editor} ::msgcat::mcset pt {Symbol} [encoding convertfrom iso8859-1 {Símbolo}] ::msgcat::mcset pt {Tab-Separated-Value} ::msgcat::mcset pt {Table} ::msgcat::mcset pt {Tabloid} [encoding convertfrom iso8859-1 {Tablóide}] ::msgcat::mcset pt {Template} ::msgcat::mcset pt {Text Font} ::msgcat::mcset pt {Text} {Texto} ::msgcat::mcset pt {Theme} ::msgcat::mcset pt {Then} [encoding convertfrom iso8859-1 {Então}] ::msgcat::mcset pt {Thickness} {Expessura} ::msgcat::mcset pt {This analysis task is already running. Do you wish to kill it?} [encoding convertfrom iso8859-1 {Esta análise já está sendo executada. Você deseja parar?}] ::msgcat::mcset pt {Tickmarks} ::msgcat::mcset pt {Tile Frames} ::msgcat::mcset pt {Tile Parameters} ::msgcat::mcset pt {Tile} ::msgcat::mcset pt {Times} ::msgcat::mcset pt {Title} [encoding convertfrom iso8859-1 {Título}] ::msgcat::mcset pt {To Fit} ::msgcat::mcset pt {Tophat} ::msgcat::mcset pt {To} {Para} ::msgcat::mcset pt {Transparency} ::msgcat::mcset pt {Type} {Tipo} ::msgcat::mcset pt {URL} ::msgcat::mcset pt {Unable to connect directly: using Web Proxy} ::msgcat::mcset pt {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset pt {Unable to determine date of observation} ::msgcat::mcset pt {Unable to determine time of observation} ::msgcat::mcset pt {Unable to evaluate filter} {Incapaz de calcular filtro} ::msgcat::mcset pt {Unable to find catalog window} [encoding convertfrom iso8859-1 {Incapaz de encontrar janela do catálogo}] ::msgcat::mcset pt {Unable to find plot window} [encoding convertfrom iso8859-1 {Incapaz de encontrar janela de gráfico}] ::msgcat::mcset pt {Unable to load RGB image into a non-rgb frame} [encoding convertfrom iso8859-1 {Incapaz de carregar imagem RGB em um frame não RGB}] ::msgcat::mcset pt {Unable to load region file} ::msgcat::mcset pt {Unable to load} {Incapaz de carregar} ::msgcat::mcset pt {Unable to locate URL} {Incapaz de localizar URL} ::msgcat::mcset pt {Unable to match target with XPA Mime request} ::msgcat::mcset pt {Unable to open file} {Incapaz de abrir arquivo} ::msgcat::mcset pt {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset pt {Undo} {Voltar} ::msgcat::mcset pt {Unique} ::msgcat::mcset pt {Units} {Unidades} ::msgcat::mcset pt {Unknown Colormap} ::msgcat::mcset pt {Unknown command} ::msgcat::mcset pt {Update Filter} ::msgcat::mcset pt {Update Group} {Atualizar Grupo} ::msgcat::mcset pt {Update from Current Crosshair} {Atualizar da Cruz Atual} ::msgcat::mcset pt {Update from Current Frame} {Atualizar do Frame Atual} ::msgcat::mcset pt {Update} {Atualizar} ::msgcat::mcset pt {Upper Left Back} ::msgcat::mcset pt {Upper Left Front} ::msgcat::mcset pt {Upper Right Back} ::msgcat::mcset pt {Upper Right Front} ::msgcat::mcset pt {Use Authentication} [encoding convertfrom iso8859-1 {Utilizar Autenticação}] ::msgcat::mcset pt {Use Current Frame on Download} {Utilizar Frame Atual ao Descarregar} ::msgcat::mcset pt {Use Internal Web Browser} {Utilizar Navegador Web Interno} ::msgcat::mcset pt {Use Proxy} {Utilizar Proxy} ::msgcat::mcset pt {User Manual} ::msgcat::mcset pt {Username} [encoding convertfrom iso8859-1 {Nome de usuário}] ::msgcat::mcset pt {User} [encoding convertfrom iso8859-1 {Usuário}] ::msgcat::mcset pt {Use} {Usar} ::msgcat::mcset pt {VO Server} ::msgcat::mcset pt {VO} ::msgcat::mcset pt {Value} {Valor} ::msgcat::mcset pt {Vector} {Vetor} ::msgcat::mcset pt {Vertical Graph} [encoding convertfrom iso8859-1 {Gráfico Vertical}] ::msgcat::mcset pt {Vertical Layout} {Layout Vertical} ::msgcat::mcset pt {Vertical Text} {Texto Vertical} ::msgcat::mcset pt {Vertical} ::msgcat::mcset pt {View} {Visualizar} ::msgcat::mcset pt {Virtual Observatory} [encoding convertfrom iso8859-1 {Observatório Virtual}] ::msgcat::mcset pt {WCS Parameters} ::msgcat::mcset pt {WCS} ::msgcat::mcset pt {Wavelength} {Comprimento de Onda} ::msgcat::mcset pt {Web Browser} {Navegador Web} ::msgcat::mcset pt {White} {Branco} ::msgcat::mcset pt {Width} {Largura} ::msgcat::mcset pt {Words matching title, description} ::msgcat::mcset pt {Writing Catalog} ::msgcat::mcset pt {X Axis Title} ::msgcat::mcset pt {X Axis} ::msgcat::mcset pt {X Grid} ::msgcat::mcset pt {XPA Information} [encoding convertfrom iso8859-1 {Informação sobre o XPA}] ::msgcat::mcset pt {XPA not initialized} [encoding convertfrom iso8859-1 {XPA não inicializado}] ::msgcat::mcset pt {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset pt {XPA} ::msgcat::mcset pt {X} ::msgcat::mcset pt {Y Axis Title} ::msgcat::mcset pt {Y Axis} ::msgcat::mcset pt {Y Grid} ::msgcat::mcset pt {Yellow} {Amarelo} ::msgcat::mcset pt {Yes} {Sim} ::msgcat::mcset pt {Y} ::msgcat::mcset pt {Z Axis Scale} ::msgcat::mcset pt {ZScale Parameters} [encoding convertfrom iso8859-1 {Parâmetros da escala Z}] ::msgcat::mcset pt {Zero} ::msgcat::mcset pt {Zoom In} {Aumentar} ::msgcat::mcset pt {Zoom Out} {Diminuir} ::msgcat::mcset pt {Zoom to Fit Frame} {Aumentar para tamanho do Frame} ::msgcat::mcset pt {Zoom} {Fator} ::msgcat::mcset pt {and} ::msgcat::mcset pt {blue} ::msgcat::mcset pt {b} ::msgcat::mcset pt {color} ::msgcat::mcset pt {cool} ::msgcat::mcset pt {green} ::msgcat::mcset pt {grey} ::msgcat::mcset pt {g} ::msgcat::mcset pt {heat} ::msgcat::mcset pt {not} ::msgcat::mcset pt {only} ::msgcat::mcset pt {or center of data} {ou centro dos dados} ::msgcat::mcset pt {rainbow} ::msgcat::mcset pt {red} ::msgcat::mcset pt {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom iso8859-1 {colunas de dados foram descarregadas. Mais podem estar disponíveis. Você pode querer ajustar o máximo permitido}] ::msgcat::mcset pt {r} ::msgcat::mcset pt {staircase} ::msgcat::mcset pt {standard} ::msgcat::mcset pt {x} ::msgcat::mcset pt {} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/da.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000115412�12132042644�013152� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset da {2D} ::msgcat::mcset da {3D} ::msgcat::mcset da {A postscript generation error has occurred} [encoding convertfrom iso8859-1 {En fejl er opstået under postscript generering}] ::msgcat::mcset da {AIP} ::msgcat::mcset da {Abort} ::msgcat::mcset da {About SAOImage DS9} {Om SAOImage DS9} ::msgcat::mcset da {About} {Om} ::msgcat::mcset da {Acknowledgment} {Tak} ::msgcat::mcset da {Add} [encoding convertfrom iso8859-1 {Tilføj}] ::msgcat::mcset da {Advanced} {Avanceret} ::msgcat::mcset da {Align} {Juster} ::msgcat::mcset da {All Columns} {Alle søjler} ::msgcat::mcset da {All Rows} [encoding convertfrom iso8859-1 {Alle rækker}] ::msgcat::mcset da {All} {Alle} ::msgcat::mcset da {Always save files during Backup} ::msgcat::mcset da {Amplifier} [encoding convertfrom iso8859-1 {Forstærker}] ::msgcat::mcset da {An error has occured while updating VO server list} [encoding convertfrom iso8859-1 {Fejl opstået mens VO server listen blev opdateret}] ::msgcat::mcset da {An error has occurred during backup} ::msgcat::mcset da {An error has occurred during restore} ::msgcat::mcset da {An error has occurred invoking the Analysis task} [encoding convertfrom iso8859-1 {Fejl opstået ved kald til analyse program}] ::msgcat::mcset da {An error has occurred while creating image.} ::msgcat::mcset da {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset da {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset da {An error has occurred while printing} [encoding convertfrom iso8859-1 {Fejl opstået under udskrivning}] ::msgcat::mcset da {An error has occurred while reading image.} ::msgcat::mcset da {An error has occurred while saving} [encoding convertfrom iso8859-1 {Fejl opstået under gemning}] ::msgcat::mcset da {An error has occurred while writing image.} ::msgcat::mcset da {An internal error has been detected} ::msgcat::mcset da {Analysis Command Log} {Analyse kommando logbog} ::msgcat::mcset da {Analysis Commands} [encoding convertfrom iso8859-1 {Analyse muligheder}] ::msgcat::mcset da {Analysis File} ::msgcat::mcset da {Analysis Log} ::msgcat::mcset da {Analysis} {Analyse} ::msgcat::mcset da {Angle Complement} [encoding convertfrom iso8859-1 {Komplementærvinkel}] ::msgcat::mcset da {Angles} {Vinkler} ::msgcat::mcset da {Angle} {Vinkel} ::msgcat::mcset da {Annuli} {Ringforme} ::msgcat::mcset da {Annulus} {Ringform} ::msgcat::mcset da {Apply} {Anvend} ::msgcat::mcset da {ArcMin} {Bueminutter} ::msgcat::mcset da {ArcSec} {Buesekunder} ::msgcat::mcset da {Architecture} {Arkitektur} ::msgcat::mcset da {Archives} {Arkiver} ::msgcat::mcset da {Array} ::msgcat::mcset da {Arrow} {Pil} ::msgcat::mcset da {Astronomy} ::msgcat::mcset da {At Startup} ::msgcat::mcset da {At least 2 different catalogs are required} ::msgcat::mcset da {Auto Centroid} {Automatisk centroide} ::msgcat::mcset da {Auto Plot 2D} ::msgcat::mcset da {Auto Plot 3D} ::msgcat::mcset da {Auto Plot} ::msgcat::mcset da {Autoload FITS Regions} [encoding convertfrom iso8859-1 {Indlæs automatisk FITS regioner}] ::msgcat::mcset da {Autoload} ::msgcat::mcset da {Automatic} {Automatisk} ::msgcat::mcset da {Average} [encoding convertfrom iso8859-1 {Middelværdi}] ::msgcat::mcset da {Axes Number} ::msgcat::mcset da {Axes Title} ::msgcat::mcset da {Axes} {Akser} ::msgcat::mcset da {Axis Label} {Akse tekster} ::msgcat::mcset da {Axis Length} [encoding convertfrom iso8859-1 {Akse længde}] ::msgcat::mcset da {Axis Numbers} {Akse tal} ::msgcat::mcset da {Axis} {Akser} ::msgcat::mcset da {Azimuth} ::msgcat::mcset da {Background Color} {Baggrunds farve} ::msgcat::mcset da {Background} {Baggrund} ::msgcat::mcset da {Backup} ::msgcat::mcset da {Back} {Tilbage} ::msgcat::mcset da {Bar Plot Tool} ::msgcat::mcset da {Bias} {Bias} ::msgcat::mcset da {Bin 3rd Column} [encoding convertfrom iso8859-1 {Bin 3dje søjle}] ::msgcat::mcset da {Bin Center} {Bin center} ::msgcat::mcset da {Bin Columns} [encoding convertfrom iso8859-1 {Bin søjler}] ::msgcat::mcset da {Bin Filter} {Bin filter} ::msgcat::mcset da {Binning Parameters} {Parameter binning} ::msgcat::mcset da {Bin} {Bin} ::msgcat::mcset da {Black} {Sort} ::msgcat::mcset da {Blank/Inf/NaN Color} {Blank/Inf/NaN farve} ::msgcat::mcset da {Blink Frames} {Blink rammer} ::msgcat::mcset da {Blink Interval} {Blinke interval} ::msgcat::mcset da {Blink} {Blink} ::msgcat::mcset da {Block In} {Bin ind} ::msgcat::mcset da {Block Out} {Bin ud} ::msgcat::mcset da {Block to Fit Frame} {Bin og tilpas ramme} ::msgcat::mcset da {Block} {Bin} ::msgcat::mcset da {Blue} [encoding convertfrom iso8859-1 {Blå}] ::msgcat::mcset da {Bold} {Fed} ::msgcat::mcset da {Border} {Kant} ::msgcat::mcset da {Box Annulus} {Kasseformet ringform} ::msgcat::mcset da {Box Panda} {Kasseformet panda} ::msgcat::mcset da {BoxCircle} ::msgcat::mcset da {Boxcar} {Kvadratisk kernel} ::msgcat::mcset da {Box} {Kasse} ::msgcat::mcset da {Broadcast} ::msgcat::mcset da {Browser} ::msgcat::mcset da {Browse} ::msgcat::mcset da {Buffer} ::msgcat::mcset da {Buttonbar} ::msgcat::mcset da {Buttons} {Knapper} ::msgcat::mcset da {Bytes} ::msgcat::mcset da {CMYK} ::msgcat::mcset da {Can Delete} [encoding convertfrom iso8859-1 {Må slette}] ::msgcat::mcset da {Can Edit} [encoding convertfrom iso8859-1 {Må redigere}] ::msgcat::mcset da {Can Move} [encoding convertfrom iso8859-1 {Må flytte}] ::msgcat::mcset da {Can Rotate} [encoding convertfrom iso8859-1 {Må rotere}] ::msgcat::mcset da {Cancel} {Slet} ::msgcat::mcset da {Catalog Server} {Katalog server} ::msgcat::mcset da {Catalog Tool} {Katalog funktion} ::msgcat::mcset da {Catalogs} {Kataloger} ::msgcat::mcset da {Catalog} {Katalog} ::msgcat::mcset da {Center Image} {Centrer billedet} ::msgcat::mcset da {Center Non-modal Dialogs} ::msgcat::mcset da {Center} {Centrer} ::msgcat::mcset da {Centroid Parameters} ::msgcat::mcset da {Centroid} {Centroide} ::msgcat::mcset da {Circle} {Cirkel} ::msgcat::mcset da {Clear All} {Fjern alt} ::msgcat::mcset da {Clear Analysis Commands} {Fjern analyse funktioner} ::msgcat::mcset da {Clear Cache} [encoding convertfrom iso8859-1 {Tøm cache}] ::msgcat::mcset da {Clear Data} {Fjern data} ::msgcat::mcset da {Clear External Analysis Commands?} [encoding convertfrom iso8859-1 {Ryd ekstern analyse kommandoer?}] ::msgcat::mcset da {Clear Filter} {Fjern filter} ::msgcat::mcset da {Clear Frame} {Ryd ramme} ::msgcat::mcset da {Clear Preferences?} {Nulstil foretrukne?} ::msgcat::mcset da {Clear Preferences} {Nulstil foretrukne} ::msgcat::mcset da {Clear} {Fjern} ::msgcat::mcset da {Click to Center} {Klik for centrering} ::msgcat::mcset da {Close} {Luk} ::msgcat::mcset da {Colorbar Size} ::msgcat::mcset da {Colorbar} {Farvekode} ::msgcat::mcset da {Colormap Parameters} {Farvetabel parametre} ::msgcat::mcset da {Colormap} {Farvetabel} ::msgcat::mcset da {Color} {Farve} ::msgcat::mcset da {Columns} [encoding convertfrom iso8859-1 {Søjler}] ::msgcat::mcset da {Column} [encoding convertfrom iso8859-1 {Søjle}] ::msgcat::mcset da {Command} ::msgcat::mcset da {Compass} {Kompas} ::msgcat::mcset da {Composite Region} ::msgcat::mcset da {Composite} {Sammensat} ::msgcat::mcset da {Compression} {Komprimer} ::msgcat::mcset da {Configure} {Konfigurer} ::msgcat::mcset da {Connect Directly} {Tilslut direkte} ::msgcat::mcset da {Connect SAMP} ::msgcat::mcset da {Connect Using Web Proxy} {Tilslut via web proxy} ::msgcat::mcset da {Connect} ::msgcat::mcset da {Console} {konsol} ::msgcat::mcset da {Contour Parameters} {Kontur parametre} ::msgcat::mcset da {Contours} {Konturer} ::msgcat::mcset da {Contour} {Konturer} ::msgcat::mcset da {Contrast} {Kontrast} ::msgcat::mcset da {Contributed} ::msgcat::mcset da {Convert to Polygons} {Omdan til poygoner} ::msgcat::mcset da {Coordinate Grid Parameters} {Koordinatnetparametre} ::msgcat::mcset da {Coordinate Grid} {Koordinatnet} ::msgcat::mcset da {Coordinate System} {Koordinat system} ::msgcat::mcset da {Coordinates} {Koordinater} ::msgcat::mcset da {Coordinate} {Koordinat} ::msgcat::mcset da {Copy Contours} {Kopier konturer} ::msgcat::mcset da {Copy to Regions} {kopier til regioner} ::msgcat::mcset da {Copy} {Kopier} ::msgcat::mcset da {Create Movie} ::msgcat::mcset da {Create New Frame on Download} {Dan en ny ramme under hentning} ::msgcat::mcset da {Create} ::msgcat::mcset da {Crop Parameters} ::msgcat::mcset da {Crop} ::msgcat::mcset da {Crosshair To} [encoding convertfrom iso8859-1 {Trådkors til}] ::msgcat::mcset da {Crosshair} [encoding convertfrom iso8859-1 {Trådkors}] ::msgcat::mcset da {Cross} {Kryds} ::msgcat::mcset da {Cube} ::msgcat::mcset da {Current Frame} {Denne ramme} ::msgcat::mcset da {Current Range} {Dette interval} ::msgcat::mcset da {Current} {Denne} ::msgcat::mcset da {Cursor} ::msgcat::mcset da {Cut} [encoding convertfrom iso8859-1 {Beskær}] ::msgcat::mcset da {Cyan} {Cyan} ::msgcat::mcset da {DPI} ::msgcat::mcset da {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset da {DS9 has detected a newer version of a preferences file and therefore will not process this file.} ::msgcat::mcset da {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset da {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-1 {DS9 har fundet en ældre fil med foretrukne indstillinger, ønsker du at opdatere?}] ::msgcat::mcset da {DS9 will complete the initialization process} [encoding convertfrom iso8859-1 {DS9 vil fuldføre initialiserings processen}] ::msgcat::mcset da {Dash} {streg} ::msgcat::mcset da {Data Format} {Dataformat} ::msgcat::mcset da {Dataset} [encoding convertfrom iso8859-1 {Datasæt}] ::msgcat::mcset da {Data} ::msgcat::mcset da {Decrease} {Aftag} ::msgcat::mcset da {Default All Files} ::msgcat::mcset da {Default Format} ::msgcat::mcset da {Default Length} ::msgcat::mcset da {Default} {Standard} ::msgcat::mcset da {Degrees} {Grader} ::msgcat::mcset da {Delete All Frames?} {Slet alle rammer?} ::msgcat::mcset da {Delete All Frames} {Slet alle rammer} ::msgcat::mcset da {Delete All Groups?} {Slet alle grupper?} ::msgcat::mcset da {Delete All Groups} {Slet alle grupper} ::msgcat::mcset da {Delete All Regions?} {Slet alle områder?} ::msgcat::mcset da {Delete All Regions} {Slet alle områder} ::msgcat::mcset da {Delete All} {Slet alt} ::msgcat::mcset da {Delete Color Tags} ::msgcat::mcset da {Delete Frame} {Slet denne ramme} ::msgcat::mcset da {Delete Group} {Slet gruppe} ::msgcat::mcset da {Delete Selected Regions} [encoding convertfrom iso8859-1 {Slet valgte områder}] ::msgcat::mcset da {Delete} {Slet} ::msgcat::mcset da {Depth} {Dybde} ::msgcat::mcset da {Detector} {Detektor} ::msgcat::mcset da {Dialog Box} {Dialog vindue} ::msgcat::mcset da {Diamond} {Ruder} ::msgcat::mcset da {Dimension} {Dimension} ::msgcat::mcset da {Disconnect} ::msgcat::mcset da {Discrete} {Diskrete} ::msgcat::mcset da {Display Header} ::msgcat::mcset da {Display Size} [encoding convertfrom iso8859-1 {Vis størrelse}] ::msgcat::mcset da {Dissolve} [encoding convertfrom iso8859-1 {Opløs}] ::msgcat::mcset da {Distance} ::msgcat::mcset da {Download Colormap} ::msgcat::mcset da {Download VOTABLE format if available} ::msgcat::mcset da {Drag to Center} [encoding convertfrom iso8859-1 {Træk til center}] ::msgcat::mcset da {Duplicate Data} ::msgcat::mcset da {East} [encoding convertfrom iso8859-1 {Øst}] ::msgcat::mcset da {Ecliptic} {Ekliptisk} ::msgcat::mcset da {Edit Group Name} {Rediger gruppe navn} ::msgcat::mcset da {Edit} {Rediger} ::msgcat::mcset da {Element} ::msgcat::mcset da {Elevation} {Stigning} ::msgcat::mcset da {Ellipse Panda} {Ellipse Panda} ::msgcat::mcset da {Ellipse} {Ellipse} ::msgcat::mcset da {Elliptical Annulus} {Elliptisk ringform} ::msgcat::mcset da {Elliptical Panda} {Elliptisk pandaform} ::msgcat::mcset da {Enable Confirmation Dialogs} [encoding convertfrom iso8859-1 {Aktiver bekræftelsesdialoger}] ::msgcat::mcset da {Enable} ::msgcat::mcset da {End} {Afslut} ::msgcat::mcset da {Enter Color} {Angiv farve} ::msgcat::mcset da {Enter Font Size} ::msgcat::mcset da {Enter Group Name} {Indtast gruppenavn} ::msgcat::mcset da {Enter Search Expression} [encoding convertfrom iso8859-1 {Angiv søgeudtryk}] ::msgcat::mcset da {Enter URL} ::msgcat::mcset da {Entry} ::msgcat::mcset da {Equal Area} {Samme areal} ::msgcat::mcset da {Equal Distance} {Samme afstand} ::msgcat::mcset da {Equal Spacing} ::msgcat::mcset da {Equal Value} ::msgcat::mcset da {Error code was returned} {Fejlkode blev returneret} ::msgcat::mcset da {Error} {Fejl} ::msgcat::mcset da {Examine Frame} [encoding convertfrom iso8859-1 {Undersøg ramme}] ::msgcat::mcset da {Examine} [encoding convertfrom iso8859-1 {Undersøg}] ::msgcat::mcset da {Exclude} {Udelad} ::msgcat::mcset da {Executing TCL code is not enabled} ::msgcat::mcset da {Exit} {Luk} ::msgcat::mcset da {Export Array} ::msgcat::mcset da {Export} ::msgcat::mcset da {Extention} ::msgcat::mcset da {Exterior Axes} {Udvendige akser} ::msgcat::mcset da {Exterior Numerics} {Udvendige tal} ::msgcat::mcset da {FAQ} [encoding convertfrom iso8859-1 {Ofte Stillede Spørgsmål}] ::msgcat::mcset da {FK4} ::msgcat::mcset da {FK5} ::msgcat::mcset da {Factor} ::msgcat::mcset da {File not Found or Unable to load FITS data MIME type} [encoding convertfrom iso8859-1 {Filen blev ikke fundet, eller det var ikke muligt at åbne FITS data MIME filtype}] ::msgcat::mcset da {Filename} {Filnavn} ::msgcat::mcset da {File} {Fil} ::msgcat::mcset da {Fill} ::msgcat::mcset da {Filter} {Filter} ::msgcat::mcset da {Find Next} [encoding convertfrom iso8859-1 {Find næste}] ::msgcat::mcset da {Find} {Find} ::msgcat::mcset da {First Frame} [encoding convertfrom iso8859-1 {Første ramme}] ::msgcat::mcset da {First} [encoding convertfrom iso8859-1 {Første}] ::msgcat::mcset da {Fits} ::msgcat::mcset da {Fixed in Size} [encoding convertfrom iso8859-1 {Fastlåst størrelse}] ::msgcat::mcset da {Flip} ::msgcat::mcset da {Font} {Skrifttype} ::msgcat::mcset da {For more information, use --help} ::msgcat::mcset da {Format} {Format} ::msgcat::mcset da {Forward} {Videre} ::msgcat::mcset da {Found} {Fundet} ::msgcat::mcset da {Frame Information} {Information for ramme} ::msgcat::mcset da {Frame Parameters} ::msgcat::mcset da {Frames} ::msgcat::mcset da {Frame} {Ramme} ::msgcat::mcset da {From} ::msgcat::mcset da {Front} {Foran} ::msgcat::mcset da {Full Range} {Hele intervallet} ::msgcat::mcset da {Function} {Funktion} ::msgcat::mcset da {GUI Font} ::msgcat::mcset da {Galactic} {Galaktisk} ::msgcat::mcset da {Gap} ::msgcat::mcset da {Gaussian} {Gaussisk} ::msgcat::mcset da {General} {Generel} ::msgcat::mcset da {Generate} {Opret} ::msgcat::mcset da {Generating Regions} [encoding convertfrom iso8859-1 {danner områder}] ::msgcat::mcset da {Get Information} {Hent information} ::msgcat::mcset da {Global Properties} ::msgcat::mcset da {Global} {Global} ::msgcat::mcset da {Goto Frame} [encoding convertfrom iso8859-1 {Gå til ramme}] ::msgcat::mcset da {Graph Horz} {vandret graf} ::msgcat::mcset da {Graph Vert} {lodret graf} ::msgcat::mcset da {Graphics} {Grafisk} ::msgcat::mcset da {Graphs} ::msgcat::mcset da {Graph} {graf} ::msgcat::mcset da {Grayscale} [encoding convertfrom iso8859-1 {Gråskala}] ::msgcat::mcset da {Green} [encoding convertfrom iso8859-1 {Grøn}] ::msgcat::mcset da {Grid Gap} {Mellemrum i nettet} ::msgcat::mcset da {Grid} {Net} ::msgcat::mcset da {Groups} {Gupper} ::msgcat::mcset da {HTTP} {HTTP} ::msgcat::mcset da {Header} {Hovede} ::msgcat::mcset da {Height} [encoding convertfrom iso8859-1 {Højde}] ::msgcat::mcset da {Help Desk} [encoding convertfrom iso8859-1 {Hjælp}] ::msgcat::mcset da {Help Me Choose} [encoding convertfrom iso8859-1 {Hjælp mig at vælge}] ::msgcat::mcset da {Help} [encoding convertfrom iso8859-1 {Hjælp}] ::msgcat::mcset da {Hide All} {Gem alle} ::msgcat::mcset da {Highlite} ::msgcat::mcset da {High} [encoding convertfrom iso8859-1 {Høj}] ::msgcat::mcset da {Histogram Equalization} {Histogram udligning} ::msgcat::mcset da {Histogram} {Histogram} ::msgcat::mcset da {Horizontal Graph} {Vandret graf} ::msgcat::mcset da {Horizontal Layout} {Vandret layout} ::msgcat::mcset da {Horizontal} ::msgcat::mcset da {IAU Location Code} ::msgcat::mcset da {ICRS} ::msgcat::mcset da {Identification} {Identifikation} ::msgcat::mcset da {If} {Hvis} ::msgcat::mcset da {Image Servers} {Billed servere} ::msgcat::mcset da {Image} {Billed} ::msgcat::mcset da {Import Array} ::msgcat::mcset da {Import} ::msgcat::mcset da {Include} {Inkluder} ::msgcat::mcset da {Increase} [encoding convertfrom iso8859-1 {Forøg}] ::msgcat::mcset da {Information Panel} {Informations panel} ::msgcat::mcset da {Information} {Information} ::msgcat::mcset da {Initialize XPA} {Initialiser XPA} ::msgcat::mcset da {Inner} {Indre} ::msgcat::mcset da {Instrument FOV} {Instrument FOV} ::msgcat::mcset da {Interior Axes} {Indre akser} ::msgcat::mcset da {Interior Numerics} {Indre tal} ::msgcat::mcset da {Internal Parse Error} ::msgcat::mcset da {Interval} {Interval} ::msgcat::mcset da {Invalid Column Name} ::msgcat::mcset da {Invalid formated multipart/mixed mime type message} {Forkert formatteret opdelt eller blandet mime type meddelelse} ::msgcat::mcset da {Invert Colormap} {Vend farvetabel} ::msgcat::mcset da {Invert Selection} {Inverter valg} ::msgcat::mcset da {Invert} {Inverter} ::msgcat::mcset da {Italic} {Kursiv} ::msgcat::mcset da {Items Found} {Emner fundet} ::msgcat::mcset da {Iteration} ::msgcat::mcset da {JPEG Quality Factor} {JPEG kvalitetsfaktor} ::msgcat::mcset da {Keep-Alive} ::msgcat::mcset da {Kernel} ::msgcat::mcset da {Keyboard Shortcuts} {Tastatur genveje} ::msgcat::mcset da {Keyboard} {Tastatur} ::msgcat::mcset da {Labels} {Etiketter} ::msgcat::mcset da {Label} {Etikette} ::msgcat::mcset da {Landscape} {Landskab} ::msgcat::mcset da {Language} {Sprog} ::msgcat::mcset da {Last Frame} {Sidste ramme} ::msgcat::mcset da {Last} {Sidste} ::msgcat::mcset da {Layout Horz} ::msgcat::mcset da {Layout Vert} ::msgcat::mcset da {Layout} ::msgcat::mcset da {Left} ::msgcat::mcset da {Legal} ::msgcat::mcset da {Length} [encoding convertfrom iso8859-1 {Længde}] ::msgcat::mcset da {Letter} ::msgcat::mcset da {Levels} {Niveauer} ::msgcat::mcset da {Level} {Niveau} ::msgcat::mcset da {Limits} [encoding convertfrom iso8859-1 {Grænser}] ::msgcat::mcset da {Line Plot Tool} ::msgcat::mcset da {Linear} [encoding convertfrom iso8859-1 {Lineær}] ::msgcat::mcset da {Line} {Linie} ::msgcat::mcset da {List Data} ::msgcat::mcset da {List Regions} [encoding convertfrom iso8859-1 {Vis områder}] ::msgcat::mcset da {List} {Liste} ::msgcat::mcset da {Load Analysis Commands} [encoding convertfrom iso8859-1 {Indlæs analyse funktioner}] ::msgcat::mcset da {Load Color Tags} ::msgcat::mcset da {Load Colormap} [encoding convertfrom iso8859-1 {Indlæs farvekort}] ::msgcat::mcset da {Load Configuration} [encoding convertfrom iso8859-1 {Indlæs konfiguration}] ::msgcat::mcset da {Load Contour Levels} [encoding convertfrom iso8859-1 {Indlæs konturniveauer}] ::msgcat::mcset da {Load Contours} [encoding convertfrom iso8859-1 {indlæs konturer}] ::msgcat::mcset da {Load Contrast/Bias} [encoding convertfrom iso8859-1 {Indlæs kontrast/bias}] ::msgcat::mcset da {Load Data} [encoding convertfrom iso8859-1 {Indlæs data}] ::msgcat::mcset da {Load Mosaic} [encoding convertfrom iso8859-1 {Indlæs mosaik}] ::msgcat::mcset da {Load Regions} [encoding convertfrom iso8859-1 {Indlæs områder}] ::msgcat::mcset da {Load Template} [encoding convertfrom iso8859-1 {Indlæs skabelon}] ::msgcat::mcset da {Load into All Frames} ::msgcat::mcset da {Load into Current Frame} ::msgcat::mcset da {Loading Catalog} ::msgcat::mcset da {Loading} ::msgcat::mcset da {Load} [encoding convertfrom iso8859-1 {Indlæs}] ::msgcat::mcset da {Local} {Lokal} ::msgcat::mcset da {Lock Bin} ::msgcat::mcset da {Lock Color} ::msgcat::mcset da {Lock Crop Amplifier} ::msgcat::mcset da {Lock Crop Detector} ::msgcat::mcset da {Lock Crop Image} ::msgcat::mcset da {Lock Crop None} ::msgcat::mcset da {Lock Crop Physical} ::msgcat::mcset da {Lock Crop WCS} ::msgcat::mcset da {Lock Crosshair Amplifier} ::msgcat::mcset da {Lock Crosshair Detector} ::msgcat::mcset da {Lock Crosshair Image} ::msgcat::mcset da {Lock Crosshair None} ::msgcat::mcset da {Lock Crosshair Physical} ::msgcat::mcset da {Lock Crosshair WCS} ::msgcat::mcset da {Lock Frame Amplifier} ::msgcat::mcset da {Lock Frame Detector} ::msgcat::mcset da {Lock Frame Image} ::msgcat::mcset da {Lock Frame None} ::msgcat::mcset da {Lock Frame Physical} ::msgcat::mcset da {Lock Frame WCS} ::msgcat::mcset da {Lock Scale} ::msgcat::mcset da {Lock Slice} ::msgcat::mcset da {Lock Smooth} ::msgcat::mcset da {Lock} [encoding convertfrom iso8859-1 {Lås}] ::msgcat::mcset da {Log Exponent} ::msgcat::mcset da {Log} ::msgcat::mcset da {Low High} [encoding convertfrom iso8859-1 {Lav høj}] ::msgcat::mcset da {Lower Left Back} ::msgcat::mcset da {Lower Left Front} ::msgcat::mcset da {Lower Right Back} ::msgcat::mcset da {Lower Right Front} ::msgcat::mcset da {Low} {lav} ::msgcat::mcset da {MIP} ::msgcat::mcset da {Magenta} ::msgcat::mcset da {Magnification} ::msgcat::mcset da {Magnifier} [encoding convertfrom iso8859-1 {Forstørrelse}] ::msgcat::mcset da {Major} ::msgcat::mcset da {Manual} ::msgcat::mcset da {Mask Parameters} {Maske parametre} ::msgcat::mcset da {Match Bin} ::msgcat::mcset da {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset da {Match Color} ::msgcat::mcset da {Match Crop Amplifier} ::msgcat::mcset da {Match Crop Detector} ::msgcat::mcset da {Match Crop Image} ::msgcat::mcset da {Match Crop Physical} ::msgcat::mcset da {Match Crop WCS} ::msgcat::mcset da {Match Crosshair Amplifier} ::msgcat::mcset da {Match Crosshair Detector} ::msgcat::mcset da {Match Crosshair Image} ::msgcat::mcset da {Match Crosshair Physical} ::msgcat::mcset da {Match Crosshair WCS} ::msgcat::mcset da {Match Frame Amplifier} ::msgcat::mcset da {Match Frame Detector} ::msgcat::mcset da {Match Frame Image} ::msgcat::mcset da {Match Frame Physical} ::msgcat::mcset da {Match Frame WCS} ::msgcat::mcset da {Match Scale} ::msgcat::mcset da {Match Slice} ::msgcat::mcset da {Match Smooth} ::msgcat::mcset da {Match} ::msgcat::mcset da {Math Function} {Matematisk funktion} ::msgcat::mcset da {Max Rows} {Maks antal rækker} ::msgcat::mcset da {Max} {Maks} ::msgcat::mcset da {Menus and Buttons} ::msgcat::mcset da {Menu} ::msgcat::mcset da {Message Log} ::msgcat::mcset da {Method} {Metode} ::msgcat::mcset da {Min Max Parameters} {Min Max parametre} ::msgcat::mcset da {Min Max} {Min Maks} ::msgcat::mcset da {Minor} ::msgcat::mcset da {Minutes} ::msgcat::mcset da {Min} ::msgcat::mcset da {Mission} ::msgcat::mcset da {Mode} ::msgcat::mcset da {Mosaic IRAF Segment} ::msgcat::mcset da {Mosaic IRAF} ::msgcat::mcset da {Mosaic WCS Segment} ::msgcat::mcset da {Mosaic WCS} ::msgcat::mcset da {Mosaic WFPC2} ::msgcat::mcset da {Mosaic} ::msgcat::mcset da {Mouse & Keyboard} ::msgcat::mcset da {Mouse Wheel Bin} ::msgcat::mcset da {Mouse Wheel Zoom} ::msgcat::mcset da {Move Back} {flyt tilbage} ::msgcat::mcset da {Move First} {flyt forrest} ::msgcat::mcset da {Move Forward} {flyt frem} ::msgcat::mcset da {Move Frame} ::msgcat::mcset da {Move Last} {flyt sidst} ::msgcat::mcset da {Move to Back} {Bag} ::msgcat::mcset da {Move to Front} {Foran} ::msgcat::mcset da {Movie} ::msgcat::mcset da {Multiple Extension Cube} ::msgcat::mcset da {Multiple Extension Frames} ::msgcat::mcset da {Multiple WCS} {Multipel WCS} ::msgcat::mcset da {NRRD} ::msgcat::mcset da {Name Resolution} [encoding convertfrom iso8859-1 {Navnesøgning}] ::msgcat::mcset da {Name Server} {Navneserver} ::msgcat::mcset da {Name or Designation} {navn eller beskrivelse} ::msgcat::mcset da {Name} ::msgcat::mcset da {Native Dialog} {Oprindelig dialog} ::msgcat::mcset da {Native} ::msgcat::mcset da {New 3D} {Ny 3D} ::msgcat::mcset da {New Features} {Nye egenskaber} ::msgcat::mcset da {New Frame 3D} {Ny ramme 3D} ::msgcat::mcset da {New Frame RGB} {Ny ramme (RGB)} ::msgcat::mcset da {New Frame each Time} {Ny ramme hver gang} ::msgcat::mcset da {New Frame} {Ny ramme} ::msgcat::mcset da {New Group} {Ny gruppe} ::msgcat::mcset da {New RGB} {Ny RGB} ::msgcat::mcset da {New} {Ny} ::msgcat::mcset da {Next Frame} [encoding convertfrom iso8859-1 {Næste ramme}] ::msgcat::mcset da {Next} [encoding convertfrom iso8859-1 {Næste}] ::msgcat::mcset da {No Catalog specified} {Intet katalog er specificeret} ::msgcat::mcset da {No Items Found} {Ingen emner er fundet} ::msgcat::mcset da {No current frame} ::msgcat::mcset da {No data available at } {Ingen data tilgængelige ved } ::msgcat::mcset da {Non-zero} {ikke-nul} ::msgcat::mcset da {None} [encoding convertfrom iso8859-1 {Ingen}] ::msgcat::mcset da {Normal} {Normal} ::msgcat::mcset da {North} {Nord} ::msgcat::mcset da {Not Found} ::msgcat::mcset da {No} {Nej} ::msgcat::mcset da {Number of Samples} {Antal} ::msgcat::mcset da {Number of Threads} ::msgcat::mcset da {Number of Ticks} ::msgcat::mcset da {Number} {Antal} ::msgcat::mcset da {Numerics} {Talværdier} ::msgcat::mcset da {OK} ::msgcat::mcset da {Object} {Objekt} ::msgcat::mcset da {Open File} {Åben fil} ::msgcat::mcset da {Open TCL Console} [encoding convertfrom iso8859-1 {Åben TCL konsol}] ::msgcat::mcset da {Open URL} [encoding convertfrom iso8859-1 {Åben URL}] ::msgcat::mcset da {Open as} ::msgcat::mcset da {Open} [encoding convertfrom iso8859-1 {Åben}] ::msgcat::mcset da {Operator} ::msgcat::mcset da {Orientation} {Orientering} ::msgcat::mcset da {Origin} ::msgcat::mcset da {Oscillate} ::msgcat::mcset da {Other Color} ::msgcat::mcset da {Other Font Size} ::msgcat::mcset da {Other} {Anden} ::msgcat::mcset da {Outer} {Ydre} ::msgcat::mcset da {PS Page Setup} {PS side opsætning} ::msgcat::mcset da {PS Print} {PS udskrift} ::msgcat::mcset da {Page Setup} [encoding convertfrom iso8859-1 {Side opsætning}] ::msgcat::mcset da {Page Source} {Side kilde} ::msgcat::mcset da {Pan To} {Flyt til} ::msgcat::mcset da {Pan Zoom Rotate Parameters} [encoding convertfrom iso8859-1 {Flyt Zoom Rotér parametre}] ::msgcat::mcset da {Pan Zoom} {Flyt Zoom} ::msgcat::mcset da {Pan then Zoom} {Flyt og derefter zoom} ::msgcat::mcset da {Panda} ::msgcat::mcset da {Panner} {Oversigtskort} ::msgcat::mcset da {Pan} {Flyt} ::msgcat::mcset da {Parameters} {Parametre} ::msgcat::mcset da {Password} {Kodeord} ::msgcat::mcset da {Paste Contours} {Indsæt konturer} ::msgcat::mcset da {Paste} [encoding convertfrom iso8859-1 {Sæt ind}] ::msgcat::mcset da {Physical} {Fysisk} ::msgcat::mcset da {Pixel Distribution} {Pixelfordeling} ::msgcat::mcset da {Pixel Size} [encoding convertfrom iso8859-1 {Pixelstørrelse}] ::msgcat::mcset da {Pixel Table} {Pixel tabel} ::msgcat::mcset da {Pixels} {Pixler} ::msgcat::mcset da {Play} {Afspil} ::msgcat::mcset da {Please Select a Region} ::msgcat::mcset da {Please specify width, height, and either name or (ra,dec)} [encoding convertfrom iso8859-1 {angiv venligst bredde, højde, og enten navn eller (ra,dec)}] ::msgcat::mcset da {Plot 2D} ::msgcat::mcset da {Plot 3D} ::msgcat::mcset da {Plot Title} {Plot titel} ::msgcat::mcset da {Plotting Regions} [encoding convertfrom iso8859-1 {Plotte områder}] ::msgcat::mcset da {Plot} ::msgcat::mcset da {Plus} ::msgcat::mcset da {Pointer} {Pegepil} ::msgcat::mcset da {Points} {Punkter} ::msgcat::mcset da {Point} {Punkt} ::msgcat::mcset da {Polygon} {Polygon} ::msgcat::mcset da {Portrait} [encoding convertfrom iso8859-1 {Portræt}] ::msgcat::mcset da {Poster} {Plakat} ::msgcat::mcset da {Postscript Page Setup} [encoding convertfrom iso8859-1 {Postscript side opsætning}] ::msgcat::mcset da {Postscript Print} {Postscript udskriv} ::msgcat::mcset da {Postscript} ::msgcat::mcset da {Power} {Potenslov} ::msgcat::mcset da {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} [encoding convertfrom iso8859-1 {Foretrukne er sat til standardværdier. Start ds9 igen for at få ændringerne implementeret}] ::msgcat::mcset da {Preferences} {Foretrukne} ::msgcat::mcset da {Preserve During Load} [encoding convertfrom iso8859-1 {Bevar under indlæsning}] ::msgcat::mcset da {Previous Frame} [encoding convertfrom iso8859-1 {Foregående ramme}] ::msgcat::mcset da {Previous} [encoding convertfrom iso8859-1 {Foregående}] ::msgcat::mcset da {Print Coordinates} {Udskriv koordinater} ::msgcat::mcset da {Print To} {Udskriv til} ::msgcat::mcset da {Printer} {Printer} ::msgcat::mcset da {Print} {Udskriv} ::msgcat::mcset da {Projection} {Projektion} ::msgcat::mcset da {Properties} {Egenskaber} ::msgcat::mcset da {Property} {Egenskab} ::msgcat::mcset da {Proxy Host} ::msgcat::mcset da {Proxy Port} ::msgcat::mcset da {Publication} {Publikation} ::msgcat::mcset da {Quadratic} {Kvadratisk} ::msgcat::mcset da {RGB Array} ::msgcat::mcset da {RGB Cube} ::msgcat::mcset da {RGB Image} ::msgcat::mcset da {RGB} ::msgcat::mcset da {Radial Profile} ::msgcat::mcset da {Radius} ::msgcat::mcset da {Range} ::msgcat::mcset da {Redo} {Gentag sidste} ::msgcat::mcset da {Red} [encoding convertfrom iso8859-1 {Rød}] ::msgcat::mcset da {Reference Manual} ::msgcat::mcset da {Reference} ::msgcat::mcset da {Refresh Frame} {Opdater ramme} ::msgcat::mcset da {Refresh} {Opdater} ::msgcat::mcset da {Region Parameters} ::msgcat::mcset da {Region} [encoding convertfrom iso8859-1 {Område}] ::msgcat::mcset da {Release Notes} {Frigvelsesnoter} ::msgcat::mcset da {Release} {Frigivelsesnoter} ::msgcat::mcset da {Reload} {Genhent} ::msgcat::mcset da {Repeat} ::msgcat::mcset da {Reset Colormap} {Nulstil farvetabel} ::msgcat::mcset da {Reset Frame} {Nulstil ramme} ::msgcat::mcset da {Reset} {Nulstil} ::msgcat::mcset da {Restore} ::msgcat::mcset da {Retrieve} {Hent} ::msgcat::mcset da {Return} ::msgcat::mcset da {Right} ::msgcat::mcset da {Roman} ::msgcat::mcset da {Rotate} {Roter} ::msgcat::mcset da {Rows} [encoding convertfrom iso8859-1 {Rækker}] ::msgcat::mcset da {Row} ::msgcat::mcset da {Ruler} {Lineal} ::msgcat::mcset da {SAMP Image} ::msgcat::mcset da {SAMP Table} ::msgcat::mcset da {SAMP: already connected} ::msgcat::mcset da {SAMP: internal error} ::msgcat::mcset da {SAMP: not connected} ::msgcat::mcset da {SAMP: unable to locate HUB} ::msgcat::mcset da {SAMP} ::msgcat::mcset da {Sample Increment} {Udvalgs stigning} ::msgcat::mcset da {Sample Parameters} {Udvalgs parametre} ::msgcat::mcset da {Samples per Line} {Udvalg per linie} ::msgcat::mcset da {Sample} {Udvalg} ::msgcat::mcset da {Save 3D Movie} ::msgcat::mcset da {Save Color Tags} ::msgcat::mcset da {Save Colormap} {gem farvekort} ::msgcat::mcset da {Save Configuration} {Gem konfiguration} ::msgcat::mcset da {Save Contour Levels} {Gem konturniveauer} ::msgcat::mcset da {Save Contours} {Gem konturer} ::msgcat::mcset da {Save Contrast/Bias} {Gem kontrast/bias} ::msgcat::mcset da {Save Data} {Gem data} ::msgcat::mcset da {Save Image on Download} ::msgcat::mcset da {Save Image} {Gem billede} ::msgcat::mcset da {Save Regions} [encoding convertfrom iso8859-1 {Gem områder}] ::msgcat::mcset da {Save Template} {Gem skabelon} ::msgcat::mcset da {Save as} ::msgcat::mcset da {Save} {Gem} ::msgcat::mcset da {Scale Parameters} {Skala parametre} ::msgcat::mcset da {Scale} {Skala} ::msgcat::mcset da {Scan} {skan} ::msgcat::mcset da {Scatter Plot Tool} ::msgcat::mcset da {Scope} [encoding convertfrom iso8859-1 {Gældende}] ::msgcat::mcset da {Search for Catalogs} [encoding convertfrom iso8859-1 {søg efter kataloger}] ::msgcat::mcset da {Searching for catalogs} [encoding convertfrom iso8859-1 {søger efter kataloger}] ::msgcat::mcset da {Seconds} {Sekunder} ::msgcat::mcset da {Select All} [encoding convertfrom iso8859-1 {Vælg alle}] ::msgcat::mcset da {Select Coordinate System } [encoding convertfrom iso8859-1 {vælg koordinat system}] ::msgcat::mcset da {Select None} [encoding convertfrom iso8859-1 {Vælg ingen}] ::msgcat::mcset da {Send} ::msgcat::mcset da {Server} {Server} ::msgcat::mcset da {Sexagesimal} ::msgcat::mcset da {Shape} {Form} ::msgcat::mcset da {Show All} {Vis alle} ::msgcat::mcset da {Show Command} ::msgcat::mcset da {Show Compass} ::msgcat::mcset da {Show Text} {Vis tekst} ::msgcat::mcset da {Show/Hide Frames} {Vis/skjul rammer} ::msgcat::mcset da {Show} {Vis} ::msgcat::mcset da {Single Frame} {Enkel ramme} ::msgcat::mcset da {Single} {Enkel} ::msgcat::mcset da {Sites} ::msgcat::mcset da {Size/Radius} [encoding convertfrom iso8859-1 {Størrelse/Radius}] ::msgcat::mcset da {Size} {Størrelse} ::msgcat::mcset da {Skip First} [encoding convertfrom iso8859-1 {Overspring første}] ::msgcat::mcset da {Slice} ::msgcat::mcset da {Smooth Parameters} {Udglatningsparametre} ::msgcat::mcset da {Smoothness} ::msgcat::mcset da {Smooth} {Udglat} ::msgcat::mcset da {Sorry, DS9 does not support} [encoding convertfrom iso8859-1 {DS9 understøtter ikke}] ::msgcat::mcset da {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} {DS9 kræver enten Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual er tilgængelig} ::msgcat::mcset da {Sort} {Sorter} ::msgcat::mcset da {Source TCL} {Kilde TCL} ::msgcat::mcset da {Source} {Kilde} ::msgcat::mcset da {Space Equal Distance} ::msgcat::mcset da {Space Equal Value} ::msgcat::mcset da {Spacing} {Mellemrum} ::msgcat::mcset da {Square Root} {Kvadratrod} ::msgcat::mcset da {Squared} {Kvadratisk} ::msgcat::mcset da {Starbase} ::msgcat::mcset da {Startup} ::msgcat::mcset da {Start} ::msgcat::mcset da {Statistics} ::msgcat::mcset da {Status} ::msgcat::mcset da {Step} {Trin} ::msgcat::mcset da {Stop} ::msgcat::mcset da {Story of SAOImage DS9} ::msgcat::mcset da {Story} ::msgcat::mcset da {Sum} ::msgcat::mcset da {Symbol Editor} ::msgcat::mcset da {Symbol} ::msgcat::mcset da {Tab-Separated-Value} ::msgcat::mcset da {Table} ::msgcat::mcset da {Tabloid} ::msgcat::mcset da {Template} ::msgcat::mcset da {Text Font} ::msgcat::mcset da {Text} {Tekst} ::msgcat::mcset da {Theme} ::msgcat::mcset da {Then} [encoding convertfrom iso8859-1 {Så}] ::msgcat::mcset da {Thickness} {Tykkelse} ::msgcat::mcset da {This analysis task is already running. Do you wish to kill it?} {Denne analyseopgave kører allerede - skal den stoppes?} ::msgcat::mcset da {Tickmarks} {Afmærkninger} ::msgcat::mcset da {Tile Frames} {Mosaik rammer} ::msgcat::mcset da {Tile Parameters} {Mosaik parametre} ::msgcat::mcset da {Tile} {Mosaik} ::msgcat::mcset da {Times} ::msgcat::mcset da {Title} {Titel} ::msgcat::mcset da {To Fit} {Tilpas} ::msgcat::mcset da {Tophat} ::msgcat::mcset da {To} {Til} ::msgcat::mcset da {Transparency} ::msgcat::mcset da {Type} ::msgcat::mcset da {URL} ::msgcat::mcset da {Unable to connect directly: using Web Proxy} ::msgcat::mcset da {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset da {Unable to determine date of observation} ::msgcat::mcset da {Unable to determine time of observation} ::msgcat::mcset da {Unable to evaluate filter} {kan ikke bestemme filter} ::msgcat::mcset da {Unable to find catalog window} {Kan ikke finde katalog vinduet} ::msgcat::mcset da {Unable to find plot window} {kan ikke finde plotte vinduet} ::msgcat::mcset da {Unable to load RGB image into a non-rgb frame} {Kan ikke hente et RGB billede ind i en ikke-RGB ramme} ::msgcat::mcset da {Unable to load region file} ::msgcat::mcset da {Unable to load} {Kan ikke hente} ::msgcat::mcset da {Unable to locate URL} {Kan ikke finde URL} ::msgcat::mcset da {Unable to match target with XPA Mime request} ::msgcat::mcset da {Unable to open file} [encoding convertfrom iso8859-1 {Kan ikke åbne fil}] ::msgcat::mcset da {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset da {Undo} {Fortryd} ::msgcat::mcset da {Unique} ::msgcat::mcset da {Units} {Enheder} ::msgcat::mcset da {Unknown Colormap} ::msgcat::mcset da {Unknown command} ::msgcat::mcset da {Update Filter} ::msgcat::mcset da {Update Group} {Opdater gruppe} ::msgcat::mcset da {Update from Current Crosshair} [encoding convertfrom iso8859-1 {Opdater fra nuværende trådkors}] ::msgcat::mcset da {Update from Current Frame} [encoding convertfrom iso8859-1 {Opdater fra nuværende ramme}] ::msgcat::mcset da {Update} {Opdater} ::msgcat::mcset da {Upper Left Back} ::msgcat::mcset da {Upper Left Front} ::msgcat::mcset da {Upper Right Back} ::msgcat::mcset da {Upper Right Front} ::msgcat::mcset da {Use Authentication} [encoding convertfrom iso8859-1 {Anvend bekræftelse}] ::msgcat::mcset da {Use Current Frame on Download} {Brug nuværende ramme til download} ::msgcat::mcset da {Use Internal Web Browser} {Brug intern web browser} ::msgcat::mcset da {Use Proxy} {Anvend proxy} ::msgcat::mcset da {User Manual} ::msgcat::mcset da {Username} {Brugernavn} ::msgcat::mcset da {User} {Brugerdefineret} ::msgcat::mcset da {Use} {Anvend} ::msgcat::mcset da {VO Server} ::msgcat::mcset da {VO} ::msgcat::mcset da {Value} [encoding convertfrom iso8859-1 {Værdi}] ::msgcat::mcset da {Vector} {Vektor} ::msgcat::mcset da {Vertical Graph} {Lodret graf} ::msgcat::mcset da {Vertical Layout} {Lodret layoyt} ::msgcat::mcset da {Vertical Text} {Lodret tekst} ::msgcat::mcset da {Vertical} ::msgcat::mcset da {View} {Vis} ::msgcat::mcset da {Virtual Observatory} {Virtuelt Observatorium} ::msgcat::mcset da {WCS Parameters} ::msgcat::mcset da {WCS} ::msgcat::mcset da {Wavelength} [encoding convertfrom iso8859-1 {Bølgelængde}] ::msgcat::mcset da {Web Browser} ::msgcat::mcset da {White} {Hvid} ::msgcat::mcset da {Width} {Bredde} ::msgcat::mcset da {Words matching title, description} {Ord tilpasset titel, beskrivelse } ::msgcat::mcset da {Writing Catalog} ::msgcat::mcset da {X Axis Title} ::msgcat::mcset da {X Axis} ::msgcat::mcset da {X Grid} ::msgcat::mcset da {XPA Information} {XPA information} ::msgcat::mcset da {XPA not initialized} {XPA ikke startet} ::msgcat::mcset da {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset da {XPA} ::msgcat::mcset da {X} ::msgcat::mcset da {Y Axis Title} ::msgcat::mcset da {Y Axis} ::msgcat::mcset da {Y Grid} ::msgcat::mcset da {Yellow} {Gul} ::msgcat::mcset da {Yes} {Ja} ::msgcat::mcset da {Y} ::msgcat::mcset da {Z Axis Scale} ::msgcat::mcset da {ZScale Parameters} ::msgcat::mcset da {Zero} {Nul} ::msgcat::mcset da {Zoom In} {Zoom ind} ::msgcat::mcset da {Zoom Out} {Zoom ud} ::msgcat::mcset da {Zoom to Fit Frame} {Zoom til vindue} ::msgcat::mcset da {Zoom} ::msgcat::mcset da {and} ::msgcat::mcset da {blue} ::msgcat::mcset da {b} ::msgcat::mcset da {color} ::msgcat::mcset da {cool} ::msgcat::mcset da {green} ::msgcat::mcset da {grey} [encoding convertfrom iso8859-1 {grå}] ::msgcat::mcset da {g} ::msgcat::mcset da {heat} ::msgcat::mcset da {not} ::msgcat::mcset da {only} ::msgcat::mcset da {or center of data} {eller center for data} ::msgcat::mcset da {rainbow} {regnbue} ::msgcat::mcset da {red} ::msgcat::mcset da {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom iso8859-1 {rækker af data er blevet hentet. Der kan være flere tilgængelige. Du bør måske ændre det maksimalt tilladte antal}] ::msgcat::mcset da {r} ::msgcat::mcset da {staircase} {trappe} ::msgcat::mcset da {standard} ::msgcat::mcset da {x} ::msgcat::mcset da {} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/fr.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000112144�12132042644�013174� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset fr {2D} ::msgcat::mcset fr {3D} ::msgcat::mcset fr {A postscript generation error has occurred} [encoding convertfrom iso8859-1 {Une erreur de génération de postscript s'est produite}] ::msgcat::mcset fr {AIP} ::msgcat::mcset fr {Abort} ::msgcat::mcset fr {About SAOImage DS9} [encoding convertfrom iso8859-1 {À propos de SAOImage DS9}] ::msgcat::mcset fr {About} [encoding convertfrom iso8859-1 {À propos de}] ::msgcat::mcset fr {Acknowledgment} {Remerciement} ::msgcat::mcset fr {Add} {Ajouter} ::msgcat::mcset fr {Advanced} [encoding convertfrom iso8859-1 {Avancé}] ::msgcat::mcset fr {Align} {Aligner} ::msgcat::mcset fr {All Columns} {Toutes les colonnes} ::msgcat::mcset fr {All Rows} [encoding convertfrom iso8859-1 {Toutes les rangées}] ::msgcat::mcset fr {All} {Tous} ::msgcat::mcset fr {Always save files during Backup} ::msgcat::mcset fr {Amplifier} {Amplificateur} ::msgcat::mcset fr {An error has occured while updating VO server list} [encoding convertfrom iso8859-1 {Une erreur s'est produite tout en mettant à jour la liste de serveur de VO}] ::msgcat::mcset fr {An error has occurred during backup} ::msgcat::mcset fr {An error has occurred during restore} ::msgcat::mcset fr {An error has occurred invoking the Analysis task} [encoding convertfrom iso8859-1 {Une erreur s'est produite en invoquant la tâche d'analyse}] ::msgcat::mcset fr {An error has occurred while creating image.} ::msgcat::mcset fr {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset fr {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset fr {An error has occurred while printing} {Une erreur s'est produite pendant l'impression} ::msgcat::mcset fr {An error has occurred while reading image.} ::msgcat::mcset fr {An error has occurred while saving} {Une erreur s'est produite pendant la sauvegarde} ::msgcat::mcset fr {An error has occurred while writing image.} ::msgcat::mcset fr {An internal error has been detected} ::msgcat::mcset fr {Analysis Command Log} {Enregistrement des commandes d'analyse} ::msgcat::mcset fr {Analysis Commands} ::msgcat::mcset fr {Analysis File} ::msgcat::mcset fr {Analysis Log} ::msgcat::mcset fr {Analysis} {Analyse} ::msgcat::mcset fr {Angle Complement} [encoding convertfrom iso8859-1 {Complément d'angle}] ::msgcat::mcset fr {Angles} {Angles} ::msgcat::mcset fr {Angle} {Angle} ::msgcat::mcset fr {Annuli} {Anneaux} ::msgcat::mcset fr {Annulus} {Anneau} ::msgcat::mcset fr {Apply} {Appliquer} ::msgcat::mcset fr {ArcMin} ::msgcat::mcset fr {ArcSec} ::msgcat::mcset fr {Architecture} ::msgcat::mcset fr {Archives} ::msgcat::mcset fr {Array} ::msgcat::mcset fr {Arrow} [encoding convertfrom iso8859-1 {Flèche}] ::msgcat::mcset fr {Astronomy} ::msgcat::mcset fr {At Startup} ::msgcat::mcset fr {At least 2 different catalogs are required} ::msgcat::mcset fr {Auto Centroid} ::msgcat::mcset fr {Auto Plot 2D} ::msgcat::mcset fr {Auto Plot 3D} ::msgcat::mcset fr {Auto Plot} ::msgcat::mcset fr {Autoload FITS Regions} [encoding convertfrom iso8859-1 {Autochargement des régions FITS}] ::msgcat::mcset fr {Autoload} ::msgcat::mcset fr {Automatic} {Automatique} ::msgcat::mcset fr {Average} {Moyenne} ::msgcat::mcset fr {Axes Number} ::msgcat::mcset fr {Axes Title} ::msgcat::mcset fr {Axes} ::msgcat::mcset fr {Axis Label} {Nom de l'axe} ::msgcat::mcset fr {Axis Length} {Longueur de l'axe} ::msgcat::mcset fr {Axis Numbers} [encoding convertfrom iso8859-1 {Échelle de l'axe}] ::msgcat::mcset fr {Axis} {Axe} ::msgcat::mcset fr {Azimuth} ::msgcat::mcset fr {Background Color} {Couleur de fond} ::msgcat::mcset fr {Background} {Fond} ::msgcat::mcset fr {Backup} ::msgcat::mcset fr {Back} {Retour} ::msgcat::mcset fr {Bar Plot Tool} ::msgcat::mcset fr {Bias} {Biais} ::msgcat::mcset fr {Bin 3rd Column} [encoding convertfrom iso8859-1 {3ème colonne de bin}] ::msgcat::mcset fr {Bin Center} {Centre de bin} ::msgcat::mcset fr {Bin Columns} {Colonnes de bin} ::msgcat::mcset fr {Bin Filter} {Filtre de bin} ::msgcat::mcset fr {Binning Parameters} [encoding convertfrom iso8859-1 {Paramètres de bin}] ::msgcat::mcset fr {Bin} ::msgcat::mcset fr {Black} {Noir} ::msgcat::mcset fr {Blank/Inf/NaN Color} {Blanc/Inf/NaN Couleur} ::msgcat::mcset fr {Blink Frames} [encoding convertfrom iso8859-1 {Clignotement des fenêtres}] ::msgcat::mcset fr {Blink Interval} {Intervalle de clignotement} ::msgcat::mcset fr {Blink} {Clignotement} ::msgcat::mcset fr {Block In} [encoding convertfrom iso8859-1 {Bin à}] ::msgcat::mcset fr {Block Out} {Bin de} ::msgcat::mcset fr {Block to Fit Frame} [encoding convertfrom iso8859-1 {Bin pour adapter l'image dans la fenêtre}] ::msgcat::mcset fr {Block} {Bin} ::msgcat::mcset fr {Blue} {Bleu} ::msgcat::mcset fr {Bold} {Gras} ::msgcat::mcset fr {Border} {Bordure} ::msgcat::mcset fr {Box Annulus} [encoding convertfrom iso8859-1 {Anneau de boîte}] ::msgcat::mcset fr {Box Panda} ::msgcat::mcset fr {BoxCircle} ::msgcat::mcset fr {Boxcar} ::msgcat::mcset fr {Box} [encoding convertfrom iso8859-1 {Boîte}] ::msgcat::mcset fr {Broadcast} ::msgcat::mcset fr {Browser} ::msgcat::mcset fr {Browse} {Parcourir} ::msgcat::mcset fr {Buffer} {Tampon} ::msgcat::mcset fr {Buttonbar} ::msgcat::mcset fr {Buttons} {Boutons} ::msgcat::mcset fr {Bytes} {Octets} ::msgcat::mcset fr {CMYK} ::msgcat::mcset fr {Can Delete} {Peut effacer} ::msgcat::mcset fr {Can Edit} [encoding convertfrom iso8859-1 {Peut éditer}] ::msgcat::mcset fr {Can Move} [encoding convertfrom iso8859-1 {Peut déplacer}] ::msgcat::mcset fr {Can Rotate} {Peut tourner} ::msgcat::mcset fr {Cancel} {Annuler} ::msgcat::mcset fr {Catalog Server} {Serveur de catalogue} ::msgcat::mcset fr {Catalog Tool} {Outil de catalogue} ::msgcat::mcset fr {Catalogs} {Catalogues} ::msgcat::mcset fr {Catalog} {Catalogue} ::msgcat::mcset fr {Center Image} {Centrer l'image} ::msgcat::mcset fr {Center Non-modal Dialogs} ::msgcat::mcset fr {Center} {Centrer} ::msgcat::mcset fr {Centroid Parameters} ::msgcat::mcset fr {Centroid} ::msgcat::mcset fr {Circle} {Cercle} ::msgcat::mcset fr {Clear All} {Tout effacer} ::msgcat::mcset fr {Clear Analysis Commands} {Effacer les commandes d'analyse} ::msgcat::mcset fr {Clear Cache} {Effacer le cache} ::msgcat::mcset fr {Clear Data} [encoding convertfrom iso8859-1 {Effacer les données}] ::msgcat::mcset fr {Clear External Analysis Commands?} {Effacer les commandes d'analyse externes ?} ::msgcat::mcset fr {Clear Filter} {Effacer le filtre} ::msgcat::mcset fr {Clear Frame} [encoding convertfrom iso8859-1 {Effacer la fenêtre}] ::msgcat::mcset fr {Clear Preferences?} [encoding convertfrom iso8859-1 {Effacer les préférences ?}] ::msgcat::mcset fr {Clear Preferences} [encoding convertfrom iso8859-1 {Effacer les préférences}] ::msgcat::mcset fr {Clear} {Effacer} ::msgcat::mcset fr {Click to Center} {Cliquer pour centrer} ::msgcat::mcset fr {Close} {Fermer} ::msgcat::mcset fr {Colorbar Size} ::msgcat::mcset fr {Colorbar} {Barre de couleurs} ::msgcat::mcset fr {Colormap Parameters} [encoding convertfrom iso8859-1 {Paramètres de carte de couleurs}] ::msgcat::mcset fr {Colormap} {Carte de couleurs} ::msgcat::mcset fr {Color} {Couleur} ::msgcat::mcset fr {Columns} {Colonnes} ::msgcat::mcset fr {Column} {Colonne} ::msgcat::mcset fr {Command} ::msgcat::mcset fr {Compass} {Boussole} ::msgcat::mcset fr {Composite Region} ::msgcat::mcset fr {Composite} ::msgcat::mcset fr {Compression} ::msgcat::mcset fr {Configure} {Configurer} ::msgcat::mcset fr {Connect Directly} {Connexion directe} ::msgcat::mcset fr {Connect SAMP} ::msgcat::mcset fr {Connect Using Web Proxy} {Connexion par proxy web} ::msgcat::mcset fr {Connect} ::msgcat::mcset fr {Console} ::msgcat::mcset fr {Contour Parameters} [encoding convertfrom iso8859-1 {Paramètres de contour}] ::msgcat::mcset fr {Contours} ::msgcat::mcset fr {Contour} ::msgcat::mcset fr {Contrast} {Contraste} ::msgcat::mcset fr {Contributed} ::msgcat::mcset fr {Convert to Polygons} {Convertir en polygones} ::msgcat::mcset fr {Coordinate Grid Parameters} [encoding convertfrom iso8859-1 {Paramètres de grille de coordonnées}] ::msgcat::mcset fr {Coordinate Grid} [encoding convertfrom iso8859-1 {Grille de coordonnées}] ::msgcat::mcset fr {Coordinate System} [encoding convertfrom iso8859-1 {Système de coordonnées}] ::msgcat::mcset fr {Coordinates} ::msgcat::mcset fr {Coordinate} [encoding convertfrom iso8859-1 {Coordonnée}] ::msgcat::mcset fr {Copy Contours} {Copier les contours} ::msgcat::mcset fr {Copy to Regions} [encoding convertfrom iso8859-1 {Copier vers Régions}] ::msgcat::mcset fr {Copy} {Copier} ::msgcat::mcset fr {Create Movie} ::msgcat::mcset fr {Create New Frame on Download} [encoding convertfrom iso8859-1 {Créer une nouvelle fenêtre au téléchargement}] ::msgcat::mcset fr {Create} ::msgcat::mcset fr {Crop Parameters} ::msgcat::mcset fr {Crop} ::msgcat::mcset fr {Crosshair To} [encoding convertfrom iso8859-1 {Réticule vers}] ::msgcat::mcset fr {Crosshair} [encoding convertfrom iso8859-1 {Réticule}] ::msgcat::mcset fr {Cross} {Croisement} ::msgcat::mcset fr {Cube} ::msgcat::mcset fr {Current Frame} {Fenêtre courante} ::msgcat::mcset fr {Current Range} {Intervalle courant} ::msgcat::mcset fr {Current} {Courant} ::msgcat::mcset fr {Cursor} {Curseur} ::msgcat::mcset fr {Cut} {Couper} ::msgcat::mcset fr {Cyan} ::msgcat::mcset fr {DPI} ::msgcat::mcset fr {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset fr {DS9 has detected a newer version of a preferences file and therefore will not process this file.} [encoding convertfrom iso8859-1 {DS9 a détecté une version plus recente du fichier de préférences et donc ne la prendra pas en compte.}] ::msgcat::mcset fr {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset fr {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-1 {DS9 a détecté une vielle version du fichier de préférences, voulez vous la mettre à jour ?}] ::msgcat::mcset fr {DS9 will complete the initialization process} {DS9 va terminer le processus d'initialisation} ::msgcat::mcset fr {Dash} {Tiret} ::msgcat::mcset fr {Data Format} [encoding convertfrom iso8859-1 {Format de données}] ::msgcat::mcset fr {Dataset} [encoding convertfrom iso8859-1 {Ensemble de données}] ::msgcat::mcset fr {Data} ::msgcat::mcset fr {Decrease} {Diminuer} ::msgcat::mcset fr {Default All Files} ::msgcat::mcset fr {Default Format} ::msgcat::mcset fr {Default Length} ::msgcat::mcset fr {Default} {Defaut} ::msgcat::mcset fr {Degrees} [encoding convertfrom iso8859-1 {Degrés}] ::msgcat::mcset fr {Delete All Frames?} [encoding convertfrom iso8859-1 {Supprimer toutes les fenêtres ?}] ::msgcat::mcset fr {Delete All Frames} [encoding convertfrom iso8859-1 {Supprimer toutes les fenêtres}] ::msgcat::mcset fr {Delete All Groups?} {Supprimer tous les groupes ?} ::msgcat::mcset fr {Delete All Groups} {Supprimer tous les groupes} ::msgcat::mcset fr {Delete All Regions?} [encoding convertfrom iso8859-1 {Supprimer toutes les régions ?}] ::msgcat::mcset fr {Delete All Regions} [encoding convertfrom iso8859-1 {Supprimer toutes les régions}] ::msgcat::mcset fr {Delete All} ::msgcat::mcset fr {Delete Color Tags} ::msgcat::mcset fr {Delete Frame} [encoding convertfrom iso8859-1 {Supprimer la fenêtre}] ::msgcat::mcset fr {Delete Group} {Supprimer le groupe} ::msgcat::mcset fr {Delete Selected Regions} [encoding convertfrom iso8859-1 {Supprimer les régions séléctionnées}] ::msgcat::mcset fr {Delete} {Supprimer} ::msgcat::mcset fr {Depth} {Profondeur} ::msgcat::mcset fr {Detector} {Detecteur} ::msgcat::mcset fr {Dialog Box} [encoding convertfrom iso8859-1 {Boîte de dialogue}] ::msgcat::mcset fr {Diamond} {Losange} ::msgcat::mcset fr {Dimension} {Dimention} ::msgcat::mcset fr {Disconnect} ::msgcat::mcset fr {Discrete} {Discret} ::msgcat::mcset fr {Display Header} ::msgcat::mcset fr {Display Size} {Afficher la taille} ::msgcat::mcset fr {Dissolve} ::msgcat::mcset fr {Distance} ::msgcat::mcset fr {Download Colormap} ::msgcat::mcset fr {Download VOTABLE format if available} ::msgcat::mcset fr {Drag to Center} {Glisser au centre} ::msgcat::mcset fr {Duplicate Data} ::msgcat::mcset fr {East} {Est} ::msgcat::mcset fr {Ecliptic} {Ecliptiques} ::msgcat::mcset fr {Edit Group Name} {Editer le nom du groupe} ::msgcat::mcset fr {Edit} [encoding convertfrom iso8859-1 {Édition}] ::msgcat::mcset fr {Element} ::msgcat::mcset fr {Elevation} ::msgcat::mcset fr {Ellipse Panda} {Ellipse Panda} ::msgcat::mcset fr {Ellipse} {Ellipse} ::msgcat::mcset fr {Elliptical Annulus} {Anneau elliptique} ::msgcat::mcset fr {Elliptical Panda} {Panda elliptique} ::msgcat::mcset fr {Enable Confirmation Dialogs} {Utiliser les dialogues de confirmation} ::msgcat::mcset fr {Enable} ::msgcat::mcset fr {End} {Fin} ::msgcat::mcset fr {Enter Color} ::msgcat::mcset fr {Enter Font Size} ::msgcat::mcset fr {Enter Group Name} {Entrer le nom du groupe} ::msgcat::mcset fr {Enter Search Expression} ::msgcat::mcset fr {Enter URL} ::msgcat::mcset fr {Entry} ::msgcat::mcset fr {Equal Area} {Egale surface} ::msgcat::mcset fr {Equal Distance} {Egale distance} ::msgcat::mcset fr {Equal Spacing} ::msgcat::mcset fr {Equal Value} ::msgcat::mcset fr {Error code was returned} [encoding convertfrom iso8859-1 {Un code d'erreur a été renvoyé}] ::msgcat::mcset fr {Error} {Erreur} ::msgcat::mcset fr {Examine Frame} [encoding convertfrom iso8859-1 {Examiner la fenêtre}] ::msgcat::mcset fr {Examine} {Examiner} ::msgcat::mcset fr {Exclude} {Exclure} ::msgcat::mcset fr {Executing TCL code is not enabled} ::msgcat::mcset fr {Exit} {Sortie} ::msgcat::mcset fr {Export Array} ::msgcat::mcset fr {Export} ::msgcat::mcset fr {Extention} ::msgcat::mcset fr {Exterior Axes} {Axes exterieurs} ::msgcat::mcset fr {Exterior Numerics} {Chiffres exterieurs} ::msgcat::mcset fr {FAQ} {Foire-Aux-Questions} ::msgcat::mcset fr {FK4} ::msgcat::mcset fr {FK5} ::msgcat::mcset fr {Factor} ::msgcat::mcset fr {File not Found or Unable to load FITS data MIME type} [encoding convertfrom iso8859-1 {Fichier non trouvé, ou impossible d'utiliser le type MIME des données FITS}] ::msgcat::mcset fr {Filename} {NomDuFichier} ::msgcat::mcset fr {File} {Fichier} ::msgcat::mcset fr {Fill} ::msgcat::mcset fr {Filter} {Filtre} ::msgcat::mcset fr {Find Next} {Trouver le suivant} ::msgcat::mcset fr {Find} {Trouver} ::msgcat::mcset fr {First Frame} [encoding convertfrom iso8859-1 {Première fenêtre}] ::msgcat::mcset fr {First} {Premier} ::msgcat::mcset fr {Fits} ::msgcat::mcset fr {Fixed in Size} [encoding convertfrom iso8859-1 {Taille fixée}] ::msgcat::mcset fr {Flip} ::msgcat::mcset fr {Font} {Police} ::msgcat::mcset fr {For more information, use --help} ::msgcat::mcset fr {Format} ::msgcat::mcset fr {Forward} {En avant} ::msgcat::mcset fr {Found} {Trouvé} ::msgcat::mcset fr {Frame Information} [encoding convertfrom iso8859-1 {Information de la fenêtre }] ::msgcat::mcset fr {Frame Parameters} ::msgcat::mcset fr {Frames} ::msgcat::mcset fr {Frame} [encoding convertfrom iso8859-1 {Fenêtre}] ::msgcat::mcset fr {From} ::msgcat::mcset fr {Front} {Avant} ::msgcat::mcset fr {Full Range} ::msgcat::mcset fr {Function} {Fonction} ::msgcat::mcset fr {GUI Font} ::msgcat::mcset fr {Galactic} {Galactiques} ::msgcat::mcset fr {Gap} ::msgcat::mcset fr {Gaussian} {Gaussien} ::msgcat::mcset fr {General} [encoding convertfrom iso8859-1 {Général}] ::msgcat::mcset fr {Generate} [encoding convertfrom iso8859-1 {Générer}] ::msgcat::mcset fr {Generating Regions} [encoding convertfrom iso8859-1 {Création des régions}] ::msgcat::mcset fr {Get Information} [encoding convertfrom iso8859-1 {Récuperer l'information}] ::msgcat::mcset fr {Global Properties} ::msgcat::mcset fr {Global} {Global} ::msgcat::mcset fr {Goto Frame} [encoding convertfrom iso8859-1 {Aller à la fenêtre}] ::msgcat::mcset fr {Graph Horz} ::msgcat::mcset fr {Graph Vert} ::msgcat::mcset fr {Graphics} {Graphiques} ::msgcat::mcset fr {Graphs} ::msgcat::mcset fr {Graph} {Graph} ::msgcat::mcset fr {Grayscale} {Niveaux de gris} ::msgcat::mcset fr {Green} {Vert} ::msgcat::mcset fr {Grid Gap} {Espacement de la grille} ::msgcat::mcset fr {Grid} {Grille} ::msgcat::mcset fr {Groups} {Groupes} ::msgcat::mcset fr {HTTP} ::msgcat::mcset fr {Header} [encoding convertfrom iso8859-1 {Entête}] ::msgcat::mcset fr {Height} {Hauteur} ::msgcat::mcset fr {Help Desk} {Contacts} ::msgcat::mcset fr {Help Me Choose} {Aider moi} ::msgcat::mcset fr {Help} {Aide} ::msgcat::mcset fr {Hide All} {Cacher tous} ::msgcat::mcset fr {Highlite} ::msgcat::mcset fr {High} {Haut} ::msgcat::mcset fr {Histogram Equalization} {Egalisation via Histogramme} ::msgcat::mcset fr {Histogram} {Histogramme} ::msgcat::mcset fr {Horizontal Graph} {Graphique Horizontal} ::msgcat::mcset fr {Horizontal Layout} {Mise en page Horizontale} ::msgcat::mcset fr {Horizontal} ::msgcat::mcset fr {IAU Location Code} ::msgcat::mcset fr {ICRS} ::msgcat::mcset fr {Identification} ::msgcat::mcset fr {If} {Si} ::msgcat::mcset fr {Image Servers} {Serveurs d'image} ::msgcat::mcset fr {Image} ::msgcat::mcset fr {Import Array} ::msgcat::mcset fr {Import} ::msgcat::mcset fr {Include} {Inclure} ::msgcat::mcset fr {Increase} {Augmenter} ::msgcat::mcset fr {Information Panel} {Panneau de reseignement} ::msgcat::mcset fr {Information} {Reseignement} ::msgcat::mcset fr {Initialize XPA} {Initialiser XPA} ::msgcat::mcset fr {Inner} [encoding convertfrom iso8859-1 {Intérieur}] ::msgcat::mcset fr {Instrument FOV} {Profondeur de champ de l'instrument} ::msgcat::mcset fr {Interior Axes} [encoding convertfrom iso8859-1 {Axes intérieur}] ::msgcat::mcset fr {Interior Numerics} [encoding convertfrom iso8859-1 {Chiffres intérieur}] ::msgcat::mcset fr {Internal Parse Error} ::msgcat::mcset fr {Interval} {Intervalle} ::msgcat::mcset fr {Invalid Column Name} ::msgcat::mcset fr {Invalid formated multipart/mixed mime type message} {Message invalide de genre mixte/multipart} ::msgcat::mcset fr {Invert Colormap} {Plan de couleur inverti} ::msgcat::mcset fr {Invert Selection} {Selection inverti} ::msgcat::mcset fr {Invert} {Invertir} ::msgcat::mcset fr {Italic} {Italique} ::msgcat::mcset fr {Items Found} [encoding convertfrom iso8859-1 {Articles trouvés}] ::msgcat::mcset fr {Iteration} ::msgcat::mcset fr {JPEG Quality Factor} [encoding convertfrom iso8859-1 {Le facteur de qualité JPEG}] ::msgcat::mcset fr {Keep-Alive} ::msgcat::mcset fr {Kernel} ::msgcat::mcset fr {Keyboard Shortcuts} {Raccourcis du clavier} ::msgcat::mcset fr {Keyboard} {Clavier} ::msgcat::mcset fr {Labels} {Étiquettes} ::msgcat::mcset fr {Label} {Étiquette} ::msgcat::mcset fr {Landscape} {Paysage} ::msgcat::mcset fr {Language} {Langue} ::msgcat::mcset fr {Last Frame} [encoding convertfrom iso8859-1 {Dernière fenêtre}] ::msgcat::mcset fr {Last} {Dernier} ::msgcat::mcset fr {Layout Horz} ::msgcat::mcset fr {Layout Vert} ::msgcat::mcset fr {Layout} ::msgcat::mcset fr {Left} ::msgcat::mcset fr {Legal} {Legale} ::msgcat::mcset fr {Length} {Longeur} ::msgcat::mcset fr {Letter} {Lettre} ::msgcat::mcset fr {Levels} {Niveaux} ::msgcat::mcset fr {Level} {Niveau} ::msgcat::mcset fr {Limits} {Limites} ::msgcat::mcset fr {Line Plot Tool} ::msgcat::mcset fr {Linear} [encoding convertfrom iso8859-1 {Linéaire}] ::msgcat::mcset fr {Line} {Ligne} ::msgcat::mcset fr {List Data} ::msgcat::mcset fr {List Regions} [encoding convertfrom iso8859-1 {Énumérer les régions}] ::msgcat::mcset fr {List} [encoding convertfrom iso8859-1 {Énumérer}] ::msgcat::mcset fr {Load Analysis Commands} {Charger le commandes d'analyse} ::msgcat::mcset fr {Load Color Tags} ::msgcat::mcset fr {Load Colormap} {Charger le plan de couleur} ::msgcat::mcset fr {Load Configuration} {Charger la configuration} ::msgcat::mcset fr {Load Contour Levels} {Charger les niveaux de contour} ::msgcat::mcset fr {Load Contours} {Charger les contours} ::msgcat::mcset fr {Load Contrast/Bias} {Charger le contraste/inclination} ::msgcat::mcset fr {Load Data} [encoding convertfrom iso8859-1 {Charger les données}] ::msgcat::mcset fr {Load Mosaic} [encoding convertfrom iso8859-1 {Charger le mosaïque}] ::msgcat::mcset fr {Load Regions} [encoding convertfrom iso8859-1 {Charger les régions}] ::msgcat::mcset fr {Load Template} {Charger le patron} ::msgcat::mcset fr {Load into All Frames} ::msgcat::mcset fr {Load into Current Frame} ::msgcat::mcset fr {Loading Catalog} ::msgcat::mcset fr {Loading} ::msgcat::mcset fr {Load} {Charger} ::msgcat::mcset fr {Local} {Locale} ::msgcat::mcset fr {Lock Bin} ::msgcat::mcset fr {Lock Color} ::msgcat::mcset fr {Lock Crop Amplifier} ::msgcat::mcset fr {Lock Crop Detector} ::msgcat::mcset fr {Lock Crop Image} ::msgcat::mcset fr {Lock Crop None} ::msgcat::mcset fr {Lock Crop Physical} ::msgcat::mcset fr {Lock Crop WCS} ::msgcat::mcset fr {Lock Crosshair Amplifier} ::msgcat::mcset fr {Lock Crosshair Detector} ::msgcat::mcset fr {Lock Crosshair Image} ::msgcat::mcset fr {Lock Crosshair None} ::msgcat::mcset fr {Lock Crosshair Physical} ::msgcat::mcset fr {Lock Crosshair WCS} ::msgcat::mcset fr {Lock Frame Amplifier} ::msgcat::mcset fr {Lock Frame Detector} ::msgcat::mcset fr {Lock Frame Image} ::msgcat::mcset fr {Lock Frame None} ::msgcat::mcset fr {Lock Frame Physical} ::msgcat::mcset fr {Lock Frame WCS} ::msgcat::mcset fr {Lock Scale} ::msgcat::mcset fr {Lock Slice} ::msgcat::mcset fr {Lock Smooth} ::msgcat::mcset fr {Lock} {Verrouiller} ::msgcat::mcset fr {Log Exponent} ::msgcat::mcset fr {Log} ::msgcat::mcset fr {Low High} {Haut bas} ::msgcat::mcset fr {Lower Left Back} ::msgcat::mcset fr {Lower Left Front} ::msgcat::mcset fr {Lower Right Back} ::msgcat::mcset fr {Lower Right Front} ::msgcat::mcset fr {Low} {Bas} ::msgcat::mcset fr {MIP} ::msgcat::mcset fr {Magenta} ::msgcat::mcset fr {Magnification} ::msgcat::mcset fr {Magnifier} {Magnificateur} ::msgcat::mcset fr {Major} {Majeure} ::msgcat::mcset fr {Manual} ::msgcat::mcset fr {Mask Parameters} [encoding convertfrom iso8859-1 {Paramètres de masque}] ::msgcat::mcset fr {Match Bin} ::msgcat::mcset fr {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset fr {Match Color} ::msgcat::mcset fr {Match Crop Amplifier} ::msgcat::mcset fr {Match Crop Detector} ::msgcat::mcset fr {Match Crop Image} ::msgcat::mcset fr {Match Crop Physical} ::msgcat::mcset fr {Match Crop WCS} ::msgcat::mcset fr {Match Crosshair Amplifier} ::msgcat::mcset fr {Match Crosshair Detector} ::msgcat::mcset fr {Match Crosshair Image} ::msgcat::mcset fr {Match Crosshair Physical} ::msgcat::mcset fr {Match Crosshair WCS} ::msgcat::mcset fr {Match Frame Amplifier} ::msgcat::mcset fr {Match Frame Detector} ::msgcat::mcset fr {Match Frame Image} ::msgcat::mcset fr {Match Frame Physical} ::msgcat::mcset fr {Match Frame WCS} ::msgcat::mcset fr {Match Scale} ::msgcat::mcset fr {Match Slice} ::msgcat::mcset fr {Match Smooth} ::msgcat::mcset fr {Match} ::msgcat::mcset fr {Math Function} {Fonction mathématique} ::msgcat::mcset fr {Max Rows} [encoding convertfrom iso8859-1 {Maximum de rangées}] ::msgcat::mcset fr {Max} {Maximum} ::msgcat::mcset fr {Menus and Buttons} ::msgcat::mcset fr {Menu} ::msgcat::mcset fr {Message Log} ::msgcat::mcset fr {Method} [encoding convertfrom iso8859-1 {Méthode}] ::msgcat::mcset fr {Min Max Parameters} ::msgcat::mcset fr {Min Max} ::msgcat::mcset fr {Minor} {Mineure} ::msgcat::mcset fr {Minutes} ::msgcat::mcset fr {Min} {Minimum} ::msgcat::mcset fr {Mission} ::msgcat::mcset fr {Mode} ::msgcat::mcset fr {Mosaic IRAF Segment} ::msgcat::mcset fr {Mosaic IRAF} ::msgcat::mcset fr {Mosaic WCS Segment} ::msgcat::mcset fr {Mosaic WCS} ::msgcat::mcset fr {Mosaic WFPC2} ::msgcat::mcset fr {Mosaic} ::msgcat::mcset fr {Mouse & Keyboard} ::msgcat::mcset fr {Mouse Wheel Bin} ::msgcat::mcset fr {Mouse Wheel Zoom} ::msgcat::mcset fr {Move Back} ::msgcat::mcset fr {Move First} ::msgcat::mcset fr {Move Forward} ::msgcat::mcset fr {Move Frame} ::msgcat::mcset fr {Move Last} ::msgcat::mcset fr {Move to Back} [encoding convertfrom iso8859-1 {Bouger vers arrière}] ::msgcat::mcset fr {Move to Front} {Bouger vers le devant} ::msgcat::mcset fr {Movie} ::msgcat::mcset fr {Multiple Extension Cube} ::msgcat::mcset fr {Multiple Extension Frames} ::msgcat::mcset fr {Multiple WCS} ::msgcat::mcset fr {NRRD} ::msgcat::mcset fr {Name Resolution} [encoding convertfrom iso8859-1 {Nom de la résolution}] ::msgcat::mcset fr {Name Server} {Nom du Serveur} ::msgcat::mcset fr {Name or Designation} [encoding convertfrom iso8859-1 {Nom ou Désignation}] ::msgcat::mcset fr {Name} ::msgcat::mcset fr {Native Dialog} ::msgcat::mcset fr {Native} ::msgcat::mcset fr {New 3D} ::msgcat::mcset fr {New Features} {Nouvelles options} ::msgcat::mcset fr {New Frame 3D} ::msgcat::mcset fr {New Frame RGB} [encoding convertfrom iso8859-1 {Nouvelle fenêtre RGB}] ::msgcat::mcset fr {New Frame each Time} [encoding convertfrom iso8859-1 {Nouvelle fenêtre à chaque fois}] ::msgcat::mcset fr {New Frame} [encoding convertfrom iso8859-1 {Nouvelle fenêtre}] ::msgcat::mcset fr {New Group} {Nouveau groupe} ::msgcat::mcset fr {New RGB} {Nouveau RGB} ::msgcat::mcset fr {New} {Nouveau} ::msgcat::mcset fr {Next Frame} [encoding convertfrom iso8859-1 {Fenêtre suivante}] ::msgcat::mcset fr {Next} {Suivant} ::msgcat::mcset fr {No Catalog specified} [encoding convertfrom iso8859-1 {Pas de Catalogue spécifié}] ::msgcat::mcset fr {No Items Found} [encoding convertfrom iso8859-1 {Pas trouvé}] ::msgcat::mcset fr {No current frame} ::msgcat::mcset fr {No data available at } [encoding convertfrom iso8859-1 {pas de donnée disponible à}] ::msgcat::mcset fr {Non-zero} ::msgcat::mcset fr {None} {Rien} ::msgcat::mcset fr {Normal} ::msgcat::mcset fr {North} {Nord} ::msgcat::mcset fr {Not Found} ::msgcat::mcset fr {No} {Non} ::msgcat::mcset fr {Number of Samples} [encoding convertfrom iso8859-1 {Nombre d'échantillons}] ::msgcat::mcset fr {Number of Threads} ::msgcat::mcset fr {Number of Ticks} ::msgcat::mcset fr {Number} {Nombre} ::msgcat::mcset fr {Numerics} {Chiffres} ::msgcat::mcset fr {OK} ::msgcat::mcset fr {Object} {Objet} ::msgcat::mcset fr {Open File} {Ouvrir fichier} ::msgcat::mcset fr {Open TCL Console} ::msgcat::mcset fr {Open URL} {Ouvrir un URL} ::msgcat::mcset fr {Open as} ::msgcat::mcset fr {Open} {Ouvrir} ::msgcat::mcset fr {Operator} {Operateur} ::msgcat::mcset fr {Orientation} ::msgcat::mcset fr {Origin} ::msgcat::mcset fr {Oscillate} ::msgcat::mcset fr {Other Color} ::msgcat::mcset fr {Other Font Size} ::msgcat::mcset fr {Other} {Autre} ::msgcat::mcset fr {Outer} {Externe} ::msgcat::mcset fr {PS Page Setup} ::msgcat::mcset fr {PS Print} ::msgcat::mcset fr {Page Setup} {Configurer la Page} ::msgcat::mcset fr {Page Source} {Source de la Page} ::msgcat::mcset fr {Pan To} ::msgcat::mcset fr {Pan Zoom Rotate Parameters} ::msgcat::mcset fr {Pan Zoom} ::msgcat::mcset fr {Pan then Zoom} ::msgcat::mcset fr {Panda} ::msgcat::mcset fr {Panner} ::msgcat::mcset fr {Pan} ::msgcat::mcset fr {Parameters} [encoding convertfrom iso8859-1 {Paramètres}] ::msgcat::mcset fr {Password} {Mot de passe} ::msgcat::mcset fr {Paste Contours} {Coller les contours} ::msgcat::mcset fr {Paste} {Coller} ::msgcat::mcset fr {Physical} {Physique} ::msgcat::mcset fr {Pixel Distribution} {Distribution des pixels} ::msgcat::mcset fr {Pixel Size} {Taille des pixels} ::msgcat::mcset fr {Pixel Table} {Table des pixels} ::msgcat::mcset fr {Pixels} ::msgcat::mcset fr {Play} {Jouer} ::msgcat::mcset fr {Please Select a Region} ::msgcat::mcset fr {Please specify width, height, and either name or (ra,dec)} {Specifiez largeur, longeur, et autre noms possibles ou (ra,dec)} ::msgcat::mcset fr {Plot 2D} ::msgcat::mcset fr {Plot 3D} ::msgcat::mcset fr {Plot Title} {Ecrire le titre} ::msgcat::mcset fr {Plotting Regions} [encoding convertfrom iso8859-1 {Tracer les régions}] ::msgcat::mcset fr {Plot} {Dessiner} ::msgcat::mcset fr {Plus} ::msgcat::mcset fr {Pointer} {Pointeur} ::msgcat::mcset fr {Points} ::msgcat::mcset fr {Point} ::msgcat::mcset fr {Polygon} {Polygone} ::msgcat::mcset fr {Portrait} ::msgcat::mcset fr {Poster} ::msgcat::mcset fr {Postscript Page Setup} ::msgcat::mcset fr {Postscript Print} ::msgcat::mcset fr {Postscript} ::msgcat::mcset fr {Power} {Puissance} ::msgcat::mcset fr {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} [encoding convertfrom iso8859-1 {Les préférences ont été re-initialisées à leur valeurs de défaut. Re-initaliser DS9 pour que ces changements prennent effet}] ::msgcat::mcset fr {Preferences} [encoding convertfrom iso8859-1 {Préférences}] ::msgcat::mcset fr {Preserve During Load} [encoding convertfrom iso8859-1 {Préserver pendant le chargement}] ::msgcat::mcset fr {Previous Frame} [encoding convertfrom iso8859-1 {Fenêtre précédente}] ::msgcat::mcset fr {Previous} [encoding convertfrom iso8859-1 {Précédent}] ::msgcat::mcset fr {Print Coordinates} {Imprimer les coordonnees} ::msgcat::mcset fr {Print To} {Imprimer dans} ::msgcat::mcset fr {Printer} {L'imprimante} ::msgcat::mcset fr {Print} {Imprimer} ::msgcat::mcset fr {Projection} ::msgcat::mcset fr {Properties} [encoding convertfrom iso8859-1 {Propriétés}] ::msgcat::mcset fr {Property} [encoding convertfrom iso8859-1 {Propriété}] ::msgcat::mcset fr {Proxy Host} ::msgcat::mcset fr {Proxy Port} ::msgcat::mcset fr {Publication} ::msgcat::mcset fr {Quadratic} ::msgcat::mcset fr {RGB Array} ::msgcat::mcset fr {RGB Cube} ::msgcat::mcset fr {RGB Image} ::msgcat::mcset fr {RGB} ::msgcat::mcset fr {Radial Profile} ::msgcat::mcset fr {Radius} ::msgcat::mcset fr {Range} ::msgcat::mcset fr {Redo} {Refaire} ::msgcat::mcset fr {Red} ::msgcat::mcset fr {Reference Manual} ::msgcat::mcset fr {Reference} ::msgcat::mcset fr {Refresh Frame} ::msgcat::mcset fr {Refresh} ::msgcat::mcset fr {Region Parameters} ::msgcat::mcset fr {Region} [encoding convertfrom iso8859-1 {Région}] ::msgcat::mcset fr {Release Notes} ::msgcat::mcset fr {Release} ::msgcat::mcset fr {Reload} ::msgcat::mcset fr {Repeat} ::msgcat::mcset fr {Reset Colormap} ::msgcat::mcset fr {Reset Frame} ::msgcat::mcset fr {Reset} ::msgcat::mcset fr {Restore} ::msgcat::mcset fr {Retrieve} ::msgcat::mcset fr {Return} ::msgcat::mcset fr {Right} ::msgcat::mcset fr {Roman} ::msgcat::mcset fr {Rotate} ::msgcat::mcset fr {Rows} ::msgcat::mcset fr {Row} ::msgcat::mcset fr {Ruler} ::msgcat::mcset fr {SAMP Image} ::msgcat::mcset fr {SAMP Table} ::msgcat::mcset fr {SAMP: already connected} ::msgcat::mcset fr {SAMP: internal error} ::msgcat::mcset fr {SAMP: not connected} ::msgcat::mcset fr {SAMP: unable to locate HUB} ::msgcat::mcset fr {SAMP} ::msgcat::mcset fr {Sample Increment} ::msgcat::mcset fr {Sample Parameters} ::msgcat::mcset fr {Samples per Line} ::msgcat::mcset fr {Sample} ::msgcat::mcset fr {Save 3D Movie} ::msgcat::mcset fr {Save Color Tags} ::msgcat::mcset fr {Save Colormap} ::msgcat::mcset fr {Save Configuration} ::msgcat::mcset fr {Save Contour Levels} ::msgcat::mcset fr {Save Contours} ::msgcat::mcset fr {Save Contrast/Bias} ::msgcat::mcset fr {Save Data} ::msgcat::mcset fr {Save Image on Download} ::msgcat::mcset fr {Save Image} ::msgcat::mcset fr {Save Regions} ::msgcat::mcset fr {Save Template} ::msgcat::mcset fr {Save as} ::msgcat::mcset fr {Save} {Enregistrer} ::msgcat::mcset fr {Scale Parameters} ::msgcat::mcset fr {Scale} ::msgcat::mcset fr {Scan} ::msgcat::mcset fr {Scatter Plot Tool} ::msgcat::mcset fr {Scope} ::msgcat::mcset fr {Search for Catalogs} ::msgcat::mcset fr {Searching for catalogs} ::msgcat::mcset fr {Seconds} ::msgcat::mcset fr {Select All} ::msgcat::mcset fr {Select Coordinate System } ::msgcat::mcset fr {Select None} ::msgcat::mcset fr {Send} ::msgcat::mcset fr {Server} ::msgcat::mcset fr {Sexagesimal} ::msgcat::mcset fr {Shape} ::msgcat::mcset fr {Show All} {Montrer tous} ::msgcat::mcset fr {Show Command} ::msgcat::mcset fr {Show Compass} ::msgcat::mcset fr {Show Text} ::msgcat::mcset fr {Show/Hide Frames} [encoding convertfrom iso8859-1 {Montrer/Cacher les fenêtres}] ::msgcat::mcset fr {Show} ::msgcat::mcset fr {Single Frame} ::msgcat::mcset fr {Single} ::msgcat::mcset fr {Sites} ::msgcat::mcset fr {Size/Radius} ::msgcat::mcset fr {Size} ::msgcat::mcset fr {Skip First} ::msgcat::mcset fr {Slice} ::msgcat::mcset fr {Smooth Parameters} ::msgcat::mcset fr {Smoothness} ::msgcat::mcset fr {Smooth} ::msgcat::mcset fr {Sorry, DS9 does not support} ::msgcat::mcset fr {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} ::msgcat::mcset fr {Sort} ::msgcat::mcset fr {Source TCL} ::msgcat::mcset fr {Source} ::msgcat::mcset fr {Space Equal Distance} ::msgcat::mcset fr {Space Equal Value} ::msgcat::mcset fr {Spacing} ::msgcat::mcset fr {Square Root} ::msgcat::mcset fr {Squared} ::msgcat::mcset fr {Starbase} ::msgcat::mcset fr {Startup} ::msgcat::mcset fr {Start} ::msgcat::mcset fr {Statistics} ::msgcat::mcset fr {Status} ::msgcat::mcset fr {Step} ::msgcat::mcset fr {Stop} ::msgcat::mcset fr {Story of SAOImage DS9} ::msgcat::mcset fr {Story} ::msgcat::mcset fr {Sum} ::msgcat::mcset fr {Symbol Editor} ::msgcat::mcset fr {Symbol} ::msgcat::mcset fr {Tab-Separated-Value} ::msgcat::mcset fr {Table} ::msgcat::mcset fr {Tabloid} ::msgcat::mcset fr {Template} ::msgcat::mcset fr {Text Font} ::msgcat::mcset fr {Text} {Texte} ::msgcat::mcset fr {Theme} ::msgcat::mcset fr {Then} ::msgcat::mcset fr {Thickness} ::msgcat::mcset fr {This analysis task is already running. Do you wish to kill it?} ::msgcat::mcset fr {Tickmarks} ::msgcat::mcset fr {Tile Frames} ::msgcat::mcset fr {Tile Parameters} ::msgcat::mcset fr {Tile} ::msgcat::mcset fr {Times} ::msgcat::mcset fr {Title} ::msgcat::mcset fr {To Fit} {Adapter} ::msgcat::mcset fr {Tophat} ::msgcat::mcset fr {To} ::msgcat::mcset fr {Transparency} ::msgcat::mcset fr {Type} ::msgcat::mcset fr {URL} ::msgcat::mcset fr {Unable to connect directly: using Web Proxy} ::msgcat::mcset fr {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset fr {Unable to determine date of observation} ::msgcat::mcset fr {Unable to determine time of observation} ::msgcat::mcset fr {Unable to evaluate filter} ::msgcat::mcset fr {Unable to find catalog window} ::msgcat::mcset fr {Unable to find plot window} ::msgcat::mcset fr {Unable to load RGB image into a non-rgb frame} ::msgcat::mcset fr {Unable to load region file} ::msgcat::mcset fr {Unable to load} ::msgcat::mcset fr {Unable to locate URL} ::msgcat::mcset fr {Unable to match target with XPA Mime request} ::msgcat::mcset fr {Unable to open file} ::msgcat::mcset fr {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset fr {Undo} [encoding convertfrom iso8859-1 {Défaire}] ::msgcat::mcset fr {Unique} ::msgcat::mcset fr {Units} ::msgcat::mcset fr {Unknown Colormap} ::msgcat::mcset fr {Unknown command} ::msgcat::mcset fr {Update Filter} ::msgcat::mcset fr {Update Group} ::msgcat::mcset fr {Update from Current Crosshair} ::msgcat::mcset fr {Update from Current Frame} ::msgcat::mcset fr {Update} ::msgcat::mcset fr {Upper Left Back} ::msgcat::mcset fr {Upper Left Front} ::msgcat::mcset fr {Upper Right Back} ::msgcat::mcset fr {Upper Right Front} ::msgcat::mcset fr {Use Authentication} ::msgcat::mcset fr {Use Current Frame on Download} ::msgcat::mcset fr {Use Internal Web Browser} ::msgcat::mcset fr {Use Proxy} ::msgcat::mcset fr {User Manual} ::msgcat::mcset fr {Username} ::msgcat::mcset fr {User} ::msgcat::mcset fr {Use} ::msgcat::mcset fr {VO Server} ::msgcat::mcset fr {VO} ::msgcat::mcset fr {Value} ::msgcat::mcset fr {Vector} ::msgcat::mcset fr {Vertical Graph} ::msgcat::mcset fr {Vertical Layout} ::msgcat::mcset fr {Vertical Text} ::msgcat::mcset fr {Vertical} ::msgcat::mcset fr {View} {Affichage} ::msgcat::mcset fr {Virtual Observatory} ::msgcat::mcset fr {WCS Parameters} ::msgcat::mcset fr {WCS} ::msgcat::mcset fr {Wavelength} ::msgcat::mcset fr {Web Browser} ::msgcat::mcset fr {White} ::msgcat::mcset fr {Width} ::msgcat::mcset fr {Words matching title, description} ::msgcat::mcset fr {Writing Catalog} ::msgcat::mcset fr {X Axis Title} ::msgcat::mcset fr {X Axis} ::msgcat::mcset fr {X Grid} ::msgcat::mcset fr {XPA Information} ::msgcat::mcset fr {XPA not initialized} ::msgcat::mcset fr {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset fr {XPA} ::msgcat::mcset fr {X} ::msgcat::mcset fr {Y Axis Title} ::msgcat::mcset fr {Y Axis} ::msgcat::mcset fr {Y Grid} ::msgcat::mcset fr {Yellow} ::msgcat::mcset fr {Yes} ::msgcat::mcset fr {Y} ::msgcat::mcset fr {Z Axis Scale} ::msgcat::mcset fr {ZScale Parameters} ::msgcat::mcset fr {Zero} ::msgcat::mcset fr {Zoom In} ::msgcat::mcset fr {Zoom Out} ::msgcat::mcset fr {Zoom to Fit Frame} ::msgcat::mcset fr {Zoom} ::msgcat::mcset fr {and} ::msgcat::mcset fr {blue} ::msgcat::mcset fr {b} ::msgcat::mcset fr {color} ::msgcat::mcset fr {cool} ::msgcat::mcset fr {green} ::msgcat::mcset fr {grey} ::msgcat::mcset fr {g} ::msgcat::mcset fr {heat} ::msgcat::mcset fr {not} ::msgcat::mcset fr {only} ::msgcat::mcset fr {or center of data} ::msgcat::mcset fr {rainbow} ::msgcat::mcset fr {red} ::msgcat::mcset fr {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} ::msgcat::mcset fr {r} ::msgcat::mcset fr {staircase} ::msgcat::mcset fr {standard} ::msgcat::mcset fr {x} ::msgcat::mcset fr {} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/de.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000114154�12132042644�013160� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset de {2D} ::msgcat::mcset de {3D} ::msgcat::mcset de {A postscript generation error has occurred} {Beim Erstellen von Postscript ist ein Fehler aufgetreten} ::msgcat::mcset de {AIP} ::msgcat::mcset de {Abort} ::msgcat::mcset de {About SAOImage DS9} [encoding convertfrom iso8859-1 {Über SAOImage DS9}] ::msgcat::mcset de {About} [encoding convertfrom iso8859-1 {Über}] ::msgcat::mcset de {Acknowledgment} {Danksagung} ::msgcat::mcset de {Add} [encoding convertfrom iso8859-1 {Hinzufügen}] ::msgcat::mcset de {Advanced} {Erweitert} ::msgcat::mcset de {Align} {Ausrichten} ::msgcat::mcset de {All Columns} {Alle spalten} ::msgcat::mcset de {All Rows} {Alle zeilen} ::msgcat::mcset de {All} {Alles} ::msgcat::mcset de {Always save files during Backup} ::msgcat::mcset de {Amplifier} [encoding convertfrom iso8859-1 {Verstärker}] ::msgcat::mcset de {An error has occured while updating VO server list} {Beim Update der VO Serverliste ist ein Fehler aufgetreten} ::msgcat::mcset de {An error has occurred during backup} ::msgcat::mcset de {An error has occurred during restore} ::msgcat::mcset de {An error has occurred invoking the Analysis task} {Beim Aufrufen des Analysetasks ist ein Fehler aufgetreten} ::msgcat::mcset de {An error has occurred while creating image.} ::msgcat::mcset de {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} ::msgcat::mcset de {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} ::msgcat::mcset de {An error has occurred while printing} {Beim Drucken ist ein Fehler aufgetreten} ::msgcat::mcset de {An error has occurred while reading image.} ::msgcat::mcset de {An error has occurred while saving} {Beim Speichern ist ein Fehler aufgetreten} ::msgcat::mcset de {An error has occurred while writing image.} ::msgcat::mcset de {An internal error has been detected} ::msgcat::mcset de {Analysis Command Log} {Analysebefehlslog} ::msgcat::mcset de {Analysis Commands} ::msgcat::mcset de {Analysis File} ::msgcat::mcset de {Analysis Log} ::msgcat::mcset de {Analysis} {Analyse} ::msgcat::mcset de {Angle Complement} {Komplementwinkel} ::msgcat::mcset de {Angles} {Winkel} ::msgcat::mcset de {Angle} {Winkel} ::msgcat::mcset de {Annuli} {Kreisringe} ::msgcat::mcset de {Annulus} {Kreisring} ::msgcat::mcset de {Apply} {Anwenden} ::msgcat::mcset de {ArcMin} {Bogenminute} ::msgcat::mcset de {ArcSec} {Bogensekunde} ::msgcat::mcset de {Architecture} {Architektur} ::msgcat::mcset de {Archives} {Archive} ::msgcat::mcset de {Array} ::msgcat::mcset de {Arrow} {Pfeil} ::msgcat::mcset de {Astronomy} ::msgcat::mcset de {At Startup} ::msgcat::mcset de {At least 2 different catalogs are required} ::msgcat::mcset de {Auto Centroid} ::msgcat::mcset de {Auto Plot 2D} ::msgcat::mcset de {Auto Plot 3D} ::msgcat::mcset de {Auto Plot} ::msgcat::mcset de {Autoload FITS Regions} {FITS-Regionen autom. laden} ::msgcat::mcset de {Autoload} ::msgcat::mcset de {Automatic} {Automatisch} ::msgcat::mcset de {Average} {Mitteln} ::msgcat::mcset de {Axes Number} ::msgcat::mcset de {Axes Title} ::msgcat::mcset de {Axes} {Achsen} ::msgcat::mcset de {Axis Label} {Achsenbeschriftung} ::msgcat::mcset de {Axis Length} [encoding convertfrom iso8859-1 {Achsenlänge}] ::msgcat::mcset de {Axis Numbers} {Achsenziffern} ::msgcat::mcset de {Axis} {Achse} ::msgcat::mcset de {Azimuth} ::msgcat::mcset de {Background Color} {Hintergrundfarbe} ::msgcat::mcset de {Background} {Hintergrund} ::msgcat::mcset de {Backup} ::msgcat::mcset de {Back} [encoding convertfrom iso8859-1 {Zurück}] ::msgcat::mcset de {Bar Plot Tool} ::msgcat::mcset de {Bias} ::msgcat::mcset de {Bin 3rd Column} {Bin 3. Spalte} ::msgcat::mcset de {Bin Center} {Bin Zentrum} ::msgcat::mcset de {Bin Columns} {Bin Spalten} ::msgcat::mcset de {Bin Filter} ::msgcat::mcset de {Binning Parameters} {Binparameter} ::msgcat::mcset de {Bin} ::msgcat::mcset de {Black} {Schwarz} ::msgcat::mcset de {Blank/Inf/NaN Color} {Leer/Inf/Nan Farbe} ::msgcat::mcset de {Blink Frames} {Blinkende rahmen} ::msgcat::mcset de {Blink Interval} {Blinkinterval} ::msgcat::mcset de {Blink} {Blinken} ::msgcat::mcset de {Block In} {Bin ein} ::msgcat::mcset de {Block Out} {Bin aus} ::msgcat::mcset de {Block to Fit Frame} {Bin an rahmen anpassen} ::msgcat::mcset de {Block} {Bin} ::msgcat::mcset de {Blue} {Blau} ::msgcat::mcset de {Bold} {Fett} ::msgcat::mcset de {Border} {Begrenzung} ::msgcat::mcset de {Box Annulus} {Viereck ring} ::msgcat::mcset de {Box Panda} {Viereckiger panda} ::msgcat::mcset de {BoxCircle} ::msgcat::mcset de {Boxcar} ::msgcat::mcset de {Box} {Viereck} ::msgcat::mcset de {Broadcast} ::msgcat::mcset de {Browser} ::msgcat::mcset de {Browse} [encoding convertfrom iso8859-1 {Auswählen}] ::msgcat::mcset de {Buffer} {Puffer} ::msgcat::mcset de {Buttonbar} ::msgcat::mcset de {Buttons} [encoding convertfrom iso8859-1 {Schaltflächen}] ::msgcat::mcset de {Bytes} ::msgcat::mcset de {CMYK} ::msgcat::mcset de {Can Delete} {Kann löschen} ::msgcat::mcset de {Can Edit} {Kann bearbeiten} ::msgcat::mcset de {Can Move} {Kann bewegen} ::msgcat::mcset de {Can Rotate} {Kann rotieren} ::msgcat::mcset de {Cancel} {Abbrechen} ::msgcat::mcset de {Catalog Server} {Katalogserver} ::msgcat::mcset de {Catalog Tool} {Katalogwerkzeug} ::msgcat::mcset de {Catalogs} {Kataloge} ::msgcat::mcset de {Catalog} {Katalog} ::msgcat::mcset de {Center Image} {Bild zentrieren} ::msgcat::mcset de {Center Non-modal Dialogs} ::msgcat::mcset de {Center} {Mittelpunkt} ::msgcat::mcset de {Centroid Parameters} ::msgcat::mcset de {Centroid} ::msgcat::mcset de {Circle} {Kreis} ::msgcat::mcset de {Clear All} [encoding convertfrom iso8859-1 {Alle löschen}] ::msgcat::mcset de {Clear Analysis Commands} [encoding convertfrom iso8859-1 {Analysebefehle löschen}] ::msgcat::mcset de {Clear Cache} [encoding convertfrom iso8859-1 {Cache löschen}] ::msgcat::mcset de {Clear Data} [encoding convertfrom iso8859-1 {Daten löschen}] ::msgcat::mcset de {Clear External Analysis Commands?} [encoding convertfrom iso8859-1 {Externe Analysebefehle löschen?}] ::msgcat::mcset de {Clear Filter} [encoding convertfrom iso8859-1 {Filter löschen}] ::msgcat::mcset de {Clear Frame} {Rahmen freigeben} ::msgcat::mcset de {Clear Preferences?} [encoding convertfrom iso8859-1 {Voreinstellungen löschen?}] ::msgcat::mcset de {Clear Preferences} [encoding convertfrom iso8859-1 {Voreinstellungen löschen}] ::msgcat::mcset de {Clear} [encoding convertfrom iso8859-1 {Löschen}] ::msgcat::mcset de {Click to Center} {Klicken zum Zentrieren} ::msgcat::mcset de {Close} [encoding convertfrom iso8859-1 {Schließen}] ::msgcat::mcset de {Colorbar Size} ::msgcat::mcset de {Colorbar} {Farbbalken} ::msgcat::mcset de {Colormap Parameters} {Farbpalettenparameter} ::msgcat::mcset de {Colormap} ::msgcat::mcset de {Color} {Farbe} ::msgcat::mcset de {Columns} {Spalten} ::msgcat::mcset de {Column} {Spalte} ::msgcat::mcset de {Command} ::msgcat::mcset de {Compass} {Kompass} ::msgcat::mcset de {Composite Region} ::msgcat::mcset de {Composite} ::msgcat::mcset de {Compression} {Kompression} ::msgcat::mcset de {Configure} {Konfigurieren} ::msgcat::mcset de {Connect Directly} {Direkt verbinden} ::msgcat::mcset de {Connect SAMP} ::msgcat::mcset de {Connect Using Web Proxy} [encoding convertfrom iso8859-1 {Für Verbindung Webproxy verwenden}] ::msgcat::mcset de {Connect} ::msgcat::mcset de {Console} ::msgcat::mcset de {Contour Parameters} {Konturenparameter} ::msgcat::mcset de {Contours} {Konturen} ::msgcat::mcset de {Contour} ::msgcat::mcset de {Contrast} {Kontrast} ::msgcat::mcset de {Contributed} ::msgcat::mcset de {Convert to Polygons} {Zu Polygonen konvertieren} ::msgcat::mcset de {Coordinate Grid Parameters} {Koordinatennetzparameter} ::msgcat::mcset de {Coordinate Grid} {Koordinatennetz} ::msgcat::mcset de {Coordinate System} {Koordinatensystem} ::msgcat::mcset de {Coordinates} ::msgcat::mcset de {Coordinate} {Koordinaten} ::msgcat::mcset de {Copy Contours} {Konturen kopieren} ::msgcat::mcset de {Copy to Regions} {Zu Regionen kopieren} ::msgcat::mcset de {Copy} {Kopieren} ::msgcat::mcset de {Create Movie} ::msgcat::mcset de {Create New Frame on Download} {Neuen rahmen bei Download} ::msgcat::mcset de {Create} ::msgcat::mcset de {Crop Parameters} ::msgcat::mcset de {Crop} ::msgcat::mcset de {Crosshair To} {Fadenkreuz auf} ::msgcat::mcset de {Crosshair} {Fadenkreuz} ::msgcat::mcset de {Cross} {Kreuz} ::msgcat::mcset de {Cube} ::msgcat::mcset de {Current Frame} {Aktueller rahmen} ::msgcat::mcset de {Current Range} {Aktueller bereich} ::msgcat::mcset de {Current} {Aktuell} ::msgcat::mcset de {Cursor} {Zeiger} ::msgcat::mcset de {Cut} {Ausschneiden} ::msgcat::mcset de {Cyan} {Zyan} ::msgcat::mcset de {DPI} ::msgcat::mcset de {DS9 has detected a newer version of a backup file and therefore will not process this file.} ::msgcat::mcset de {DS9 has detected a newer version of a preferences file and therefore will not process this file.} {DS9 had eine neuere Einstellungsdatei erkannt und wird deshalb die Datei nicht verarbeiten} ::msgcat::mcset de {DS9 has detected an older backup file, do you wish to continue?} ::msgcat::mcset de {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-1 {DS9 hat ein ältere Einstellungsdatei erkannt, möchten Sie aktualisieren?}] ::msgcat::mcset de {DS9 will complete the initialization process} [encoding convertfrom iso8859-1 {DS9 wird den Initialisierungsprozeß vervollständigen}] ::msgcat::mcset de {Dash} {Gestrichelt} ::msgcat::mcset de {Data Format} {Datenformat} ::msgcat::mcset de {Dataset} {Datensatz} ::msgcat::mcset de {Data} ::msgcat::mcset de {Decrease} {Absteigend} ::msgcat::mcset de {Default All Files} ::msgcat::mcset de {Default Format} ::msgcat::mcset de {Default Length} ::msgcat::mcset de {Default} {Standard} ::msgcat::mcset de {Degrees} {Grad} ::msgcat::mcset de {Delete All Frames?} [encoding convertfrom iso8859-1 {Alle rahmen löschen?}] ::msgcat::mcset de {Delete All Frames} [encoding convertfrom iso8859-1 {Alle rahmen löschen}] ::msgcat::mcset de {Delete All Groups?} [encoding convertfrom iso8859-1 {Alle Gruppen löschen?}] ::msgcat::mcset de {Delete All Groups} [encoding convertfrom iso8859-1 {Alle Gruppen löschen}] ::msgcat::mcset de {Delete All Regions?} [encoding convertfrom iso8859-1 {Alle Regionen löschen?}] ::msgcat::mcset de {Delete All Regions} [encoding convertfrom iso8859-1 {Alle Regionen löschen}] ::msgcat::mcset de {Delete All} ::msgcat::mcset de {Delete Color Tags} ::msgcat::mcset de {Delete Frame} [encoding convertfrom iso8859-1 {Rahmen löschen}] ::msgcat::mcset de {Delete Group} [encoding convertfrom iso8859-1 {Gruppe löschen}] ::msgcat::mcset de {Delete Selected Regions} [encoding convertfrom iso8859-1 {Ausgewählte Regionen löschen}] ::msgcat::mcset de {Delete} [encoding convertfrom iso8859-1 {Löschen}] ::msgcat::mcset de {Depth} {Tiefe} ::msgcat::mcset de {Detector} {Detektor} ::msgcat::mcset de {Dialog Box} {Dialogbox} ::msgcat::mcset de {Diamond} {Raute} ::msgcat::mcset de {Dimension} ::msgcat::mcset de {Disconnect} ::msgcat::mcset de {Discrete} {Diskret} ::msgcat::mcset de {Display Header} ::msgcat::mcset de {Display Size} [encoding convertfrom iso8859-1 {Größe zeigen}] ::msgcat::mcset de {Dissolve} ::msgcat::mcset de {Distance} ::msgcat::mcset de {Download Colormap} ::msgcat::mcset de {Download VOTABLE format if available} ::msgcat::mcset de {Drag to Center} {Ziehen zum zentrieren} ::msgcat::mcset de {Duplicate Data} ::msgcat::mcset de {East} {Osten} ::msgcat::mcset de {Ecliptic} {Ekliptisch} ::msgcat::mcset de {Edit Group Name} {Gruppenname bearbeiten} ::msgcat::mcset de {Edit} {Bearbeiten} ::msgcat::mcset de {Element} ::msgcat::mcset de {Elevation} ::msgcat::mcset de {Ellipse Panda} {Ellipsen Panda} ::msgcat::mcset de {Ellipse} ::msgcat::mcset de {Elliptical Annulus} {Elliptischer Kreisring} ::msgcat::mcset de {Elliptical Panda} {Elliptischer Panda} ::msgcat::mcset de {Enable Confirmation Dialogs} [encoding convertfrom iso8859-1 {Bestätigungsdialoge einschalten}] ::msgcat::mcset de {Enable} ::msgcat::mcset de {End} {Ende} ::msgcat::mcset de {Enter Color} ::msgcat::mcset de {Enter Font Size} ::msgcat::mcset de {Enter Group Name} {Gruppenname eingeben} ::msgcat::mcset de {Enter Search Expression} ::msgcat::mcset de {Enter URL} ::msgcat::mcset de {Entry} ::msgcat::mcset de {Equal Area} [encoding convertfrom iso8859-1 {Gleiche Fläche}] ::msgcat::mcset de {Equal Distance} {Gleicher Abstand} ::msgcat::mcset de {Equal Spacing} ::msgcat::mcset de {Equal Value} ::msgcat::mcset de {Error code was returned} [encoding convertfrom iso8859-1 {Fehlercode wurde zurückgegeben}] ::msgcat::mcset de {Error} {Fehler} ::msgcat::mcset de {Examine Frame} {Rahmen inspizieren} ::msgcat::mcset de {Examine} {Inspizieren} ::msgcat::mcset de {Exclude} {Ausschliessen} ::msgcat::mcset de {Executing TCL code is not enabled} ::msgcat::mcset de {Exit} [encoding convertfrom iso8859-1 {Schließen}] ::msgcat::mcset de {Export Array} ::msgcat::mcset de {Export} ::msgcat::mcset de {Extention} ::msgcat::mcset de {Exterior Axes} [encoding convertfrom iso8859-1 {Äußere Achsen}] ::msgcat::mcset de {Exterior Numerics} [encoding convertfrom iso8859-1 {Äußere Ziffern}] ::msgcat::mcset de {FAQ} ::msgcat::mcset de {FK4} ::msgcat::mcset de {FK5} ::msgcat::mcset de {Factor} ::msgcat::mcset de {File not Found or Unable to load FITS data MIME type} [encoding convertfrom iso8859-1 {Datei nicht gefunden oder nicht möglich FITS-Daten MIME-Type zu laden}] ::msgcat::mcset de {Filename} {Dateiname} ::msgcat::mcset de {File} {Datei} ::msgcat::mcset de {Fill} ::msgcat::mcset de {Filter} ::msgcat::mcset de {Find Next} [encoding convertfrom iso8859-1 {Nächsten finden}] ::msgcat::mcset de {Find} {Suchen} ::msgcat::mcset de {First Frame} {Erster rahmen} ::msgcat::mcset de {First} {Erster} ::msgcat::mcset de {Fits} ::msgcat::mcset de {Fixed in Size} [encoding convertfrom iso8859-1 {Feste Größe}] ::msgcat::mcset de {Flip} ::msgcat::mcset de {Font} ::msgcat::mcset de {For more information, use --help} ::msgcat::mcset de {Format} ::msgcat::mcset de {Forward} [encoding convertfrom iso8859-1 {Vorwärts}] ::msgcat::mcset de {Found} {Gefunden} ::msgcat::mcset de {Frame Information} {Rahmeninformation} ::msgcat::mcset de {Frame Parameters} ::msgcat::mcset de {Frames} ::msgcat::mcset de {Frame} {Rahmen} ::msgcat::mcset de {From} ::msgcat::mcset de {Front} {Vor} ::msgcat::mcset de {Full Range} {Ganzer Bereich} ::msgcat::mcset de {Function} {Funktion} ::msgcat::mcset de {GUI Font} ::msgcat::mcset de {Galactic} {Galaktisch} ::msgcat::mcset de {Gap} ::msgcat::mcset de {Gaussian} {Gauss} ::msgcat::mcset de {General} {Allgemein} ::msgcat::mcset de {Generate} {Herstellen} ::msgcat::mcset de {Generating Regions} {Regionen erstellen} ::msgcat::mcset de {Get Information} {Informationen} ::msgcat::mcset de {Global Properties} ::msgcat::mcset de {Global} ::msgcat::mcset de {Goto Frame} ::msgcat::mcset de {Graph Horz} ::msgcat::mcset de {Graph Vert} ::msgcat::mcset de {Graphics} {Grafik} ::msgcat::mcset de {Graphs} ::msgcat::mcset de {Graph} ::msgcat::mcset de {Grayscale} {Graustufen} ::msgcat::mcset de {Green} [encoding convertfrom iso8859-1 {Grün}] ::msgcat::mcset de {Grid Gap} {Gitterabstand} ::msgcat::mcset de {Grid} {Gitter} ::msgcat::mcset de {Groups} {Gruppen} ::msgcat::mcset de {HTTP} ::msgcat::mcset de {Header} {Dateikopf} ::msgcat::mcset de {Height} [encoding convertfrom iso8859-1 {Höhe}] ::msgcat::mcset de {Help Desk} {Hilfestelle} ::msgcat::mcset de {Help Me Choose} [encoding convertfrom iso8859-1 {Hilf mir auswählen}] ::msgcat::mcset de {Help} {Hilfe} ::msgcat::mcset de {Hide All} {Alle verstecken} ::msgcat::mcset de {Highlite} ::msgcat::mcset de {High} {Hoch} ::msgcat::mcset de {Histogram Equalization} {Histogrammausgleich} ::msgcat::mcset de {Histogram} {Histogramm} ::msgcat::mcset de {Horizontal Graph} {Horizontaldarstellung} ::msgcat::mcset de {Horizontal Layout} {Horizontales Layout} ::msgcat::mcset de {Horizontal} ::msgcat::mcset de {IAU Location Code} ::msgcat::mcset de {ICRS} ::msgcat::mcset de {Identification} {Kennzeichnung} ::msgcat::mcset de {If} {Wenn} ::msgcat::mcset de {Image Servers} {Bildserver} ::msgcat::mcset de {Image} {Bild} ::msgcat::mcset de {Import Array} ::msgcat::mcset de {Import} ::msgcat::mcset de {Include} {Einschliessen} ::msgcat::mcset de {Increase} {Aufsteigend} ::msgcat::mcset de {Information Panel} {Informationsfeld} ::msgcat::mcset de {Information} {Informations} ::msgcat::mcset de {Initialize XPA} {XPA initialisieren} ::msgcat::mcset de {Inner} {Innerer} ::msgcat::mcset de {Instrument FOV} {Instrumentensichtfeld} ::msgcat::mcset de {Interior Axes} {Innere Achsen} ::msgcat::mcset de {Interior Numerics} {Innere Ziffern} ::msgcat::mcset de {Internal Parse Error} ::msgcat::mcset de {Interval} {Intervall} ::msgcat::mcset de {Invalid Column Name} ::msgcat::mcset de {Invalid formated multipart/mixed mime type message} [encoding convertfrom iso8859-1 {Ungültig formatierter multipart/mixed MIME-Type}] ::msgcat::mcset de {Invert Colormap} {Farbpalette invertieren} ::msgcat::mcset de {Invert Selection} {Auswahl umkehren} ::msgcat::mcset de {Invert} {Invertieren} ::msgcat::mcset de {Italic} {Kursiv} ::msgcat::mcset de {Items Found} ::msgcat::mcset de {Iteration} ::msgcat::mcset de {JPEG Quality Factor} [encoding convertfrom iso8859-1 {JPEG Qualitätsfaktor}] ::msgcat::mcset de {Keep-Alive} ::msgcat::mcset de {Kernel} ::msgcat::mcset de {Keyboard Shortcuts} {Tastatur-Shortcuts} ::msgcat::mcset de {Keyboard} {Tastatur} ::msgcat::mcset de {Labels} {Beschriftung} ::msgcat::mcset de {Label} ::msgcat::mcset de {Landscape} {Horizontal} ::msgcat::mcset de {Language} {Sprache} ::msgcat::mcset de {Last Frame} {Letzter rahmen} ::msgcat::mcset de {Last} {Letzter} ::msgcat::mcset de {Layout Horz} ::msgcat::mcset de {Layout Vert} ::msgcat::mcset de {Layout} ::msgcat::mcset de {Left} ::msgcat::mcset de {Legal} ::msgcat::mcset de {Length} [encoding convertfrom iso8859-1 {Länge}] ::msgcat::mcset de {Letter} ::msgcat::mcset de {Levels} {Niveaus} ::msgcat::mcset de {Level} {Niveau} ::msgcat::mcset de {Limits} {Grenzen} ::msgcat::mcset de {Line Plot Tool} ::msgcat::mcset de {Linear} ::msgcat::mcset de {Line} {Linie} ::msgcat::mcset de {List Data} ::msgcat::mcset de {List Regions} {Regionen auflisten} ::msgcat::mcset de {List} {Auflisten} ::msgcat::mcset de {Load Analysis Commands} {Analysebefehle laden} ::msgcat::mcset de {Load Color Tags} ::msgcat::mcset de {Load Colormap} {Farbpalette laden} ::msgcat::mcset de {Load Configuration} {Konfiguration laden} ::msgcat::mcset de {Load Contour Levels} {Kontourniveaus laden} ::msgcat::mcset de {Load Contours} {Konturen laden} ::msgcat::mcset de {Load Contrast/Bias} {Kontrast/Bias laden} ::msgcat::mcset de {Load Data} {Daten laden} ::msgcat::mcset de {Load Mosaic} {Mosaic laden} ::msgcat::mcset de {Load Regions} {Regionen laden} ::msgcat::mcset de {Load Template} {Vorlage laden} ::msgcat::mcset de {Load into All Frames} ::msgcat::mcset de {Load into Current Frame} ::msgcat::mcset de {Loading Catalog} ::msgcat::mcset de {Loading} ::msgcat::mcset de {Load} {Laden} ::msgcat::mcset de {Local} {Lokal} ::msgcat::mcset de {Lock Bin} ::msgcat::mcset de {Lock Color} ::msgcat::mcset de {Lock Crop Amplifier} ::msgcat::mcset de {Lock Crop Detector} ::msgcat::mcset de {Lock Crop Image} ::msgcat::mcset de {Lock Crop None} ::msgcat::mcset de {Lock Crop Physical} ::msgcat::mcset de {Lock Crop WCS} ::msgcat::mcset de {Lock Crosshair Amplifier} ::msgcat::mcset de {Lock Crosshair Detector} ::msgcat::mcset de {Lock Crosshair Image} ::msgcat::mcset de {Lock Crosshair None} ::msgcat::mcset de {Lock Crosshair Physical} ::msgcat::mcset de {Lock Crosshair WCS} ::msgcat::mcset de {Lock Frame Amplifier} ::msgcat::mcset de {Lock Frame Detector} ::msgcat::mcset de {Lock Frame Image} ::msgcat::mcset de {Lock Frame None} ::msgcat::mcset de {Lock Frame Physical} ::msgcat::mcset de {Lock Frame WCS} ::msgcat::mcset de {Lock Scale} ::msgcat::mcset de {Lock Slice} ::msgcat::mcset de {Lock Smooth} ::msgcat::mcset de {Lock} {Arretieren} ::msgcat::mcset de {Log Exponent} ::msgcat::mcset de {Log} ::msgcat::mcset de {Low High} {Niedrig Hoch} ::msgcat::mcset de {Lower Left Back} ::msgcat::mcset de {Lower Left Front} ::msgcat::mcset de {Lower Right Back} ::msgcat::mcset de {Lower Right Front} ::msgcat::mcset de {Low} {Niedrig} ::msgcat::mcset de {MIP} ::msgcat::mcset de {Magenta} ::msgcat::mcset de {Magnification} ::msgcat::mcset de {Magnifier} [encoding convertfrom iso8859-1 {Vergrößerungsglas}] ::msgcat::mcset de {Major} [encoding convertfrom iso8859-1 {Groß}] ::msgcat::mcset de {Manual} {Manuell} ::msgcat::mcset de {Mask Parameters} {Maskenparameter} ::msgcat::mcset de {Match Bin} ::msgcat::mcset de {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset de {Match Color} ::msgcat::mcset de {Match Crop Amplifier} ::msgcat::mcset de {Match Crop Detector} ::msgcat::mcset de {Match Crop Image} ::msgcat::mcset de {Match Crop Physical} ::msgcat::mcset de {Match Crop WCS} ::msgcat::mcset de {Match Crosshair Amplifier} ::msgcat::mcset de {Match Crosshair Detector} ::msgcat::mcset de {Match Crosshair Image} ::msgcat::mcset de {Match Crosshair Physical} ::msgcat::mcset de {Match Crosshair WCS} ::msgcat::mcset de {Match Frame Amplifier} ::msgcat::mcset de {Match Frame Detector} ::msgcat::mcset de {Match Frame Image} ::msgcat::mcset de {Match Frame Physical} ::msgcat::mcset de {Match Frame WCS} ::msgcat::mcset de {Match Scale} ::msgcat::mcset de {Match Slice} ::msgcat::mcset de {Match Smooth} ::msgcat::mcset de {Match} ::msgcat::mcset de {Math Function} {Math. Funktion} ::msgcat::mcset de {Max Rows} {Max. Reihen} ::msgcat::mcset de {Max} ::msgcat::mcset de {Menus and Buttons} ::msgcat::mcset de {Menu} ::msgcat::mcset de {Message Log} ::msgcat::mcset de {Method} {Methode} ::msgcat::mcset de {Min Max Parameters} ::msgcat::mcset de {Min Max} ::msgcat::mcset de {Minor} {Gering} ::msgcat::mcset de {Minutes} ::msgcat::mcset de {Min} ::msgcat::mcset de {Mission} ::msgcat::mcset de {Mode} ::msgcat::mcset de {Mosaic IRAF Segment} ::msgcat::mcset de {Mosaic IRAF} ::msgcat::mcset de {Mosaic WCS Segment} ::msgcat::mcset de {Mosaic WCS} ::msgcat::mcset de {Mosaic WFPC2} ::msgcat::mcset de {Mosaic} ::msgcat::mcset de {Mouse & Keyboard} ::msgcat::mcset de {Mouse Wheel Bin} ::msgcat::mcset de {Mouse Wheel Zoom} ::msgcat::mcset de {Move Back} ::msgcat::mcset de {Move First} ::msgcat::mcset de {Move Forward} ::msgcat::mcset de {Move Frame} ::msgcat::mcset de {Move Last} ::msgcat::mcset de {Move to Back} {Nach hinten} ::msgcat::mcset de {Move to Front} {Nach vorne} ::msgcat::mcset de {Movie} ::msgcat::mcset de {Multiple Extension Cube} ::msgcat::mcset de {Multiple Extension Frames} ::msgcat::mcset de {Multiple WCS} {Mehrere WCS} ::msgcat::mcset de {NRRD} ::msgcat::mcset de {Name Resolution} {Namensbestimmung} ::msgcat::mcset de {Name Server} ::msgcat::mcset de {Name or Designation} {Name oder Bezeichnung} ::msgcat::mcset de {Name} ::msgcat::mcset de {Native Dialog} {Systemnativer Dialog} ::msgcat::mcset de {Native} ::msgcat::mcset de {New 3D} ::msgcat::mcset de {New Features} {Neue Eigenschaften} ::msgcat::mcset de {New Frame 3D} ::msgcat::mcset de {New Frame RGB} {Neuer RGB rahmen} ::msgcat::mcset de {New Frame each Time} {Neuer rahmen jedes Mal} ::msgcat::mcset de {New Frame} {Neuer rahmen} ::msgcat::mcset de {New Group} {Neue Gruppe} ::msgcat::mcset de {New RGB} {Neu RGB} ::msgcat::mcset de {New} {Neu} ::msgcat::mcset de {Next Frame} [encoding convertfrom iso8859-1 {Nächster rahmen}] ::msgcat::mcset de {Next} [encoding convertfrom iso8859-1 {Nächster}] ::msgcat::mcset de {No Catalog specified} {Keine Katalog spezifiziert} ::msgcat::mcset de {No Items Found} {Keine Objekte gefunden} ::msgcat::mcset de {No current frame} ::msgcat::mcset de {No data available at } [encoding convertfrom iso8859-1 {Keine Daten verfügbar bei }] ::msgcat::mcset de {Non-zero} ::msgcat::mcset de {None} {Kein} ::msgcat::mcset de {Normal} ::msgcat::mcset de {North} {Norden} ::msgcat::mcset de {Not Found} ::msgcat::mcset de {No} {Nein} ::msgcat::mcset de {Number of Samples} {Anzahl der Stichproben} ::msgcat::mcset de {Number of Threads} ::msgcat::mcset de {Number of Ticks} ::msgcat::mcset de {Number} {Zahl} ::msgcat::mcset de {Numerics} ::msgcat::mcset de {OK} ::msgcat::mcset de {Object} {Objekt} ::msgcat::mcset de {Open File} [encoding convertfrom iso8859-1 {Datei öffnen}] ::msgcat::mcset de {Open TCL Console} ::msgcat::mcset de {Open URL} [encoding convertfrom iso8859-1 {URL Öffnen}] ::msgcat::mcset de {Open as} ::msgcat::mcset de {Open} [encoding convertfrom iso8859-1 {Öffnen}] ::msgcat::mcset de {Operator} ::msgcat::mcset de {Orientation} {Orientierung} ::msgcat::mcset de {Origin} ::msgcat::mcset de {Oscillate} ::msgcat::mcset de {Other Color} ::msgcat::mcset de {Other Font Size} ::msgcat::mcset de {Other} {Andere} ::msgcat::mcset de {Outer} [encoding convertfrom iso8859-1 {Äußerer}] ::msgcat::mcset de {PS Page Setup} ::msgcat::mcset de {PS Print} ::msgcat::mcset de {Page Setup} {Seitensetup} ::msgcat::mcset de {Page Source} {Seitenquelle} ::msgcat::mcset de {Pan To} {Ausrichten auf} ::msgcat::mcset de {Pan Zoom Rotate Parameters} {Ausrichten zoomen rotieren} ::msgcat::mcset de {Pan Zoom} ::msgcat::mcset de {Pan then Zoom} {Ausrichten dann Zoomen} ::msgcat::mcset de {Panda} ::msgcat::mcset de {Panner} [encoding convertfrom iso8859-1 {Übersichtsfeld}] ::msgcat::mcset de {Pan} {Ausrichtung} ::msgcat::mcset de {Parameters} {Parameter} ::msgcat::mcset de {Password} {Passwort} ::msgcat::mcset de {Paste Contours} [encoding convertfrom iso8859-1 {Konturen einfügen}] ::msgcat::mcset de {Paste} [encoding convertfrom iso8859-1 {Einfügen}] ::msgcat::mcset de {Physical} {Physikalisch} ::msgcat::mcset de {Pixel Distribution} {Pixelverteilung} ::msgcat::mcset de {Pixel Size} [encoding convertfrom iso8859-1 {Pixelgröße}] ::msgcat::mcset de {Pixel Table} {Pixeltabelle} ::msgcat::mcset de {Pixels} {Pixel} ::msgcat::mcset de {Play} {Abspielen} ::msgcat::mcset de {Please Select a Region} ::msgcat::mcset de {Please specify width, height, and either name or (ra,dec)} [encoding convertfrom iso8859-1 {Bitte Weite, Höhe und entweder Namen oder (RA,Dec) angeben}] ::msgcat::mcset de {Plot 2D} ::msgcat::mcset de {Plot 3D} ::msgcat::mcset de {Plot Title} {Titel drucken} ::msgcat::mcset de {Plotting Regions} {Regionen drucken} ::msgcat::mcset de {Plot} ::msgcat::mcset de {Plus} ::msgcat::mcset de {Pointer} {Zeiger} ::msgcat::mcset de {Points} {Punkte} ::msgcat::mcset de {Point} {Punkt} ::msgcat::mcset de {Polygon} ::msgcat::mcset de {Portrait} {Vertikal} ::msgcat::mcset de {Poster} ::msgcat::mcset de {Postscript Page Setup} ::msgcat::mcset de {Postscript Print} ::msgcat::mcset de {Postscript} ::msgcat::mcset de {Power} {Exp} ::msgcat::mcset de {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} [encoding convertfrom iso8859-1 {Einstellungen wurden auf die Standardwerte zurückgesetzt. Starten Sie DS9 bitte neu, um die Änderungen zu übernehmen}] ::msgcat::mcset de {Preferences} {Einstellungen} ::msgcat::mcset de {Preserve During Load} {Beim Laden beibehalten} ::msgcat::mcset de {Previous Frame} {Vorheriger rahmen} ::msgcat::mcset de {Previous} {Vorheriger} ::msgcat::mcset de {Print Coordinates} {Koordinaten drucken} ::msgcat::mcset de {Print To} {Drucken} ::msgcat::mcset de {Printer} {Drucker} ::msgcat::mcset de {Print} {Drucken} ::msgcat::mcset de {Projection} {Projektion} ::msgcat::mcset de {Properties} {Eigenschaften} ::msgcat::mcset de {Property} {Eigenschaften} ::msgcat::mcset de {Proxy Host} ::msgcat::mcset de {Proxy Port} ::msgcat::mcset de {Publication} [encoding convertfrom iso8859-1 {Veröffentlichung}] ::msgcat::mcset de {Quadratic} {Quadratisch} ::msgcat::mcset de {RGB Array} ::msgcat::mcset de {RGB Cube} ::msgcat::mcset de {RGB Image} ::msgcat::mcset de {RGB} ::msgcat::mcset de {Radial Profile} ::msgcat::mcset de {Radius} ::msgcat::mcset de {Range} ::msgcat::mcset de {Redo} {Wiederholen} ::msgcat::mcset de {Red} {Rot} ::msgcat::mcset de {Reference Manual} {Referenzhandbuch} ::msgcat::mcset de {Reference} {Referenz} ::msgcat::mcset de {Refresh Frame} {Rahmen erneuern} ::msgcat::mcset de {Refresh} ::msgcat::mcset de {Region Parameters} ::msgcat::mcset de {Region} ::msgcat::mcset de {Release Notes} {Versionshinweise} ::msgcat::mcset de {Release} {Version} ::msgcat::mcset de {Reload} {Wieder laden} ::msgcat::mcset de {Repeat} ::msgcat::mcset de {Reset Colormap} [encoding convertfrom iso8859-1 {Farbpalette zurücksetzen}] ::msgcat::mcset de {Reset Frame} [encoding convertfrom iso8859-1 {Rahmen zurücksetzen}] ::msgcat::mcset de {Reset} ::msgcat::mcset de {Restore} ::msgcat::mcset de {Retrieve} {Suchen} ::msgcat::mcset de {Return} ::msgcat::mcset de {Right} ::msgcat::mcset de {Roman} ::msgcat::mcset de {Rotate} {Rotieren} ::msgcat::mcset de {Rows} {Reihen} ::msgcat::mcset de {Row} ::msgcat::mcset de {Ruler} {Lineal} ::msgcat::mcset de {SAMP Image} ::msgcat::mcset de {SAMP Table} ::msgcat::mcset de {SAMP: already connected} ::msgcat::mcset de {SAMP: internal error} ::msgcat::mcset de {SAMP: not connected} ::msgcat::mcset de {SAMP: unable to locate HUB} ::msgcat::mcset de {SAMP} ::msgcat::mcset de {Sample Increment} {Stichprobeninkrement} ::msgcat::mcset de {Sample Parameters} {Stichprobenparameter} ::msgcat::mcset de {Samples per Line} {Stichproben pro Linie} ::msgcat::mcset de {Sample} {Stichprobe} ::msgcat::mcset de {Save 3D Movie} ::msgcat::mcset de {Save Color Tags} ::msgcat::mcset de {Save Colormap} {Farbpalette speichern} ::msgcat::mcset de {Save Configuration} {Konfiguration speichern} ::msgcat::mcset de {Save Contour Levels} {Konturniveaus speichern} ::msgcat::mcset de {Save Contours} {Konturen speichern} ::msgcat::mcset de {Save Contrast/Bias} {Kontrast/Bias speichern} ::msgcat::mcset de {Save Data} {Daten speichern} ::msgcat::mcset de {Save Image on Download} ::msgcat::mcset de {Save Image} {Bild speichern} ::msgcat::mcset de {Save Regions} {Regionen speichern} ::msgcat::mcset de {Save Template} {Vorlage speichern} ::msgcat::mcset de {Save as} ::msgcat::mcset de {Save} {Speichern} ::msgcat::mcset de {Scale Parameters} {Skalierungsparameter} ::msgcat::mcset de {Scale} {Skalierung} ::msgcat::mcset de {Scan} {Abtastung} ::msgcat::mcset de {Scatter Plot Tool} ::msgcat::mcset de {Scope} {Anwendungsbereich} ::msgcat::mcset de {Search for Catalogs} {Nach Katalogen suchen} ::msgcat::mcset de {Searching for catalogs} {Suche nach Katalogen} ::msgcat::mcset de {Seconds} {Sekunden} ::msgcat::mcset de {Select All} [encoding convertfrom iso8859-1 {Alle auswählen}] ::msgcat::mcset de {Select Coordinate System } [encoding convertfrom iso8859-1 {Koordinatensystem auswählen}] ::msgcat::mcset de {Select None} [encoding convertfrom iso8859-1 {Nichts auswählen}] ::msgcat::mcset de {Send} ::msgcat::mcset de {Server} ::msgcat::mcset de {Sexagesimal} ::msgcat::mcset de {Shape} {Form} ::msgcat::mcset de {Show All} {Alle zeigen} ::msgcat::mcset de {Show Command} ::msgcat::mcset de {Show Compass} ::msgcat::mcset de {Show Text} ::msgcat::mcset de {Show/Hide Frames} {Rahmen zeigen/verstecken} ::msgcat::mcset de {Show} ::msgcat::mcset de {Single Frame} {Einzelner rahmen} ::msgcat::mcset de {Single} {Einzeln} ::msgcat::mcset de {Sites} ::msgcat::mcset de {Size/Radius} [encoding convertfrom iso8859-1 {Größe/Radius}] ::msgcat::mcset de {Size} [encoding convertfrom iso8859-1 {Größe}] ::msgcat::mcset de {Skip First} [encoding convertfrom iso8859-1 {Erste überspringen}] ::msgcat::mcset de {Slice} ::msgcat::mcset de {Smooth Parameters} [encoding convertfrom iso8859-1 {Glättungsparameter}] ::msgcat::mcset de {Smoothness} ::msgcat::mcset de {Smooth} [encoding convertfrom iso8859-1 {Glätten}] ::msgcat::mcset de {Sorry, DS9 does not support} [encoding convertfrom iso8859-1 {Sorry, DS9 unterstützt nicht}] ::msgcat::mcset de {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} [encoding convertfrom iso8859-1 {Sorry, DS9 benötigt Pseudocolor8, Truecolor8, Truecolor16, Truecolor24}] ::msgcat::mcset de {Sort} {Sortieren} ::msgcat::mcset de {Source TCL} ::msgcat::mcset de {Source} {Quelle} ::msgcat::mcset de {Space Equal Distance} ::msgcat::mcset de {Space Equal Value} ::msgcat::mcset de {Spacing} {Intervall} ::msgcat::mcset de {Square Root} {Wurzel} ::msgcat::mcset de {Squared} {Quadratisch} ::msgcat::mcset de {Starbase} ::msgcat::mcset de {Startup} ::msgcat::mcset de {Start} ::msgcat::mcset de {Statistics} ::msgcat::mcset de {Status} ::msgcat::mcset de {Step} {Stufe} ::msgcat::mcset de {Stop} ::msgcat::mcset de {Story of SAOImage DS9} ::msgcat::mcset de {Story} ::msgcat::mcset de {Sum} {Summieren} ::msgcat::mcset de {Symbol Editor} ::msgcat::mcset de {Symbol} ::msgcat::mcset de {Tab-Separated-Value} ::msgcat::mcset de {Table} ::msgcat::mcset de {Tabloid} ::msgcat::mcset de {Template} ::msgcat::mcset de {Text Font} ::msgcat::mcset de {Text} ::msgcat::mcset de {Theme} ::msgcat::mcset de {Then} {dann} ::msgcat::mcset de {Thickness} {Dicke} ::msgcat::mcset de {This analysis task is already running. Do you wish to kill it?} [encoding convertfrom iso8859-1 {Diese Analyse läuft bereits. Soll sie beendet werden?}] ::msgcat::mcset de {Tickmarks} {Achsenstriche} ::msgcat::mcset de {Tile Frames} {Gekachelte rahmen} ::msgcat::mcset de {Tile Parameters} ::msgcat::mcset de {Tile} {Kacheln} ::msgcat::mcset de {Times} ::msgcat::mcset de {Title} {Titel} ::msgcat::mcset de {To Fit} {Anpassen} ::msgcat::mcset de {Tophat} ::msgcat::mcset de {To} {Nach} ::msgcat::mcset de {Transparency} ::msgcat::mcset de {Type} {Typ} ::msgcat::mcset de {URL} ::msgcat::mcset de {Unable to connect directly: using Web Proxy} ::msgcat::mcset de {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset de {Unable to determine date of observation} ::msgcat::mcset de {Unable to determine time of observation} ::msgcat::mcset de {Unable to evaluate filter} [encoding convertfrom iso8859-1 {Nicht möglich Filter zu evaluieren}] ::msgcat::mcset de {Unable to find catalog window} [encoding convertfrom iso8859-1 {Nicht möglich Katalogfenster zu finden}] ::msgcat::mcset de {Unable to find plot window} [encoding convertfrom iso8859-1 {Nicht möglich Plotfenster zu finden}] ::msgcat::mcset de {Unable to load RGB image into a non-rgb frame} [encoding convertfrom iso8859-1 {Nicht möglich RGB-Bild in nicht-RGB-rahmen zu laden}] ::msgcat::mcset de {Unable to load region file} ::msgcat::mcset de {Unable to load} [encoding convertfrom iso8859-1 {Nicht möglich zu laden}] ::msgcat::mcset de {Unable to locate URL} [encoding convertfrom iso8859-1 {Nicht möglich URL zu finden}] ::msgcat::mcset de {Unable to match target with XPA Mime request} ::msgcat::mcset de {Unable to open file} [encoding convertfrom iso8859-1 {Nicht möglich Datei zu öffnen}] ::msgcat::mcset de {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset de {Undo} [encoding convertfrom iso8859-1 {Rückgängig}] ::msgcat::mcset de {Unique} ::msgcat::mcset de {Units} {Einheiten} ::msgcat::mcset de {Unknown Colormap} ::msgcat::mcset de {Unknown command} ::msgcat::mcset de {Update Filter} ::msgcat::mcset de {Update Group} {Gruppe aktualisieren} ::msgcat::mcset de {Update from Current Crosshair} {Vom aktuellen Fadenkreuz aktualisieren} ::msgcat::mcset de {Update from Current Frame} {Vom aktuellen rahmen aktualisieren} ::msgcat::mcset de {Update} {Aktualisieren} ::msgcat::mcset de {Upper Left Back} ::msgcat::mcset de {Upper Left Front} ::msgcat::mcset de {Upper Right Back} ::msgcat::mcset de {Upper Right Front} ::msgcat::mcset de {Use Authentication} {Authentifizierung verwenden} ::msgcat::mcset de {Use Current Frame on Download} {Aktuellen rahmen bei Download verwenden} ::msgcat::mcset de {Use Internal Web Browser} {Internen Webbrowser verwenden} ::msgcat::mcset de {Use Proxy} {Proxy verwenden} ::msgcat::mcset de {User Manual} ::msgcat::mcset de {Username} {Login} ::msgcat::mcset de {User} {Benutzer} ::msgcat::mcset de {Use} {Benutze} ::msgcat::mcset de {VO Server} ::msgcat::mcset de {VO} ::msgcat::mcset de {Value} {Wert} ::msgcat::mcset de {Vector} {Vektor} ::msgcat::mcset de {Vertical Graph} {Vertikaldarstellung} ::msgcat::mcset de {Vertical Layout} {Vertikales layout} ::msgcat::mcset de {Vertical Text} {Vertikaler text} ::msgcat::mcset de {Vertical} ::msgcat::mcset de {View} {Ansicht} ::msgcat::mcset de {Virtual Observatory} ::msgcat::mcset de {WCS Parameters} ::msgcat::mcset de {WCS} ::msgcat::mcset de {Wavelength} [encoding convertfrom iso8859-1 {Wellenlänge}] ::msgcat::mcset de {Web Browser} {Webbrowser} ::msgcat::mcset de {White} [encoding convertfrom iso8859-1 {Weiß}] ::msgcat::mcset de {Width} {Breite} ::msgcat::mcset de {Words matching title, description} {Worte im Titel, Bezeichnung} ::msgcat::mcset de {Writing Catalog} ::msgcat::mcset de {X Axis Title} ::msgcat::mcset de {X Axis} ::msgcat::mcset de {X Grid} ::msgcat::mcset de {XPA Information} ::msgcat::mcset de {XPA not initialized} {XPA nicht initialisiert} ::msgcat::mcset de {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset de {XPA} ::msgcat::mcset de {X} ::msgcat::mcset de {Y Axis Title} ::msgcat::mcset de {Y Axis} ::msgcat::mcset de {Y Grid} ::msgcat::mcset de {Yellow} {Gelb} ::msgcat::mcset de {Yes} {Ja} ::msgcat::mcset de {Y} ::msgcat::mcset de {Z Axis Scale} ::msgcat::mcset de {ZScale Parameters} ::msgcat::mcset de {Zero} ::msgcat::mcset de {Zoom In} {Hineinzoomen} ::msgcat::mcset de {Zoom Out} {Herauszoomen} ::msgcat::mcset de {Zoom to Fit Frame} {An Fenster anpassen} ::msgcat::mcset de {Zoom} ::msgcat::mcset de {and} ::msgcat::mcset de {blue} ::msgcat::mcset de {b} ::msgcat::mcset de {color} ::msgcat::mcset de {cool} ::msgcat::mcset de {green} ::msgcat::mcset de {grey} ::msgcat::mcset de {g} ::msgcat::mcset de {heat} ::msgcat::mcset de {not} ::msgcat::mcset de {only} ::msgcat::mcset de {or center of data} {oder Zentrum der Daten} ::msgcat::mcset de {rainbow} ::msgcat::mcset de {red} ::msgcat::mcset de {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom iso8859-1 {Datenreihen wurden heruntergeladen. Mehr sind vielleicht verfügbar. Sie können die maximale Anzahl anpassen.}] ::msgcat::mcset de {r} ::msgcat::mcset de {staircase} ::msgcat::mcset de {standard} ::msgcat::mcset de {x} ::msgcat::mcset de {} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/msgs/cs.msg��������������������������������������������������������������������������������0000644�0001750�0001750�00000132444�12132042644�013177� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������::msgcat::mcset cs {2D} ::msgcat::mcset cs {3D} ::msgcat::mcset cs {A postscript generation error has occurred} [encoding convertfrom iso8859-2 {Chyba pøi generování postscriptu}] ::msgcat::mcset cs {AIP} ::msgcat::mcset cs {Abort} [encoding convertfrom iso8859-2 {Pøeru¹it}] ::msgcat::mcset cs {About SAOImage DS9} [encoding convertfrom iso8859-2 {O programu SAOImage DS9}] ::msgcat::mcset cs {About} [encoding convertfrom iso8859-2 {O programu}] ::msgcat::mcset cs {Acknowledgment} [encoding convertfrom iso8859-2 {Podìkování}] ::msgcat::mcset cs {Add} [encoding convertfrom iso8859-2 {Pøidat}] ::msgcat::mcset cs {Advanced} [encoding convertfrom iso8859-2 {Dal¹í nastavení}] ::msgcat::mcset cs {Align} [encoding convertfrom iso8859-2 {Zarovnat}] ::msgcat::mcset cs {All Columns} [encoding convertfrom iso8859-2 {V¹echny sloupce}] ::msgcat::mcset cs {All Rows} [encoding convertfrom iso8859-2 {V¹echny øádky}] ::msgcat::mcset cs {All} [encoding convertfrom iso8859-2 {V¹e}] ::msgcat::mcset cs {Always save files during Backup} [encoding convertfrom iso8859-2 {V¾dy ulo¾it soubory pøi zálohování}] ::msgcat::mcset cs {Amplifier} [encoding convertfrom iso8859-2 {Zesilovaè}] ::msgcat::mcset cs {An error has occured while updating VO server list} [encoding convertfrom iso8859-2 {Chyba pøi aktualizaci seznamu VO serverù}] ::msgcat::mcset cs {An error has occurred during backup} [encoding convertfrom iso8859-2 {Chyba pøi poøizování zálohy}] ::msgcat::mcset cs {An error has occurred during restore} [encoding convertfrom iso8859-2 {Chyba pøi obnovì zálohy}] ::msgcat::mcset cs {An error has occurred invoking the Analysis task} [encoding convertfrom iso8859-2 {Chyba pøi spou¹tìní Analýzy}] ::msgcat::mcset cs {An error has occurred while creating image.} [encoding convertfrom iso8859-2 {Chyba pøi vytváøení obrázku.}] ::msgcat::mcset cs {An error has occurred while creating the image. Please be sure that the ds9 window is in the upper left corner of the default screen and the entire window is visible.} [encoding convertfrom iso8859-2 {Chyba pøi vytváøení obrázku. Prosím ujistìte se ¾e okno s DS9tkou je ve vrchním levém rohu výchozí obrazovky a ¾e je celé viditelné.}] ::msgcat::mcset cs {An error has occurred while creating the image. Please be sure that the entire image window is visible on the screen.} [encoding convertfrom iso8859-2 {Chyba pøi vytváøení obrázku. Prosím ujistìte se na obrazovce je zobrazené celé okno s obrázkem}] ::msgcat::mcset cs {An error has occurred while printing} [encoding convertfrom iso8859-2 {Pøi tisku se vyskytla chyba}] ::msgcat::mcset cs {An error has occurred while reading image.} [encoding convertfrom iso8859-2 {Chyba pøi ètení obrázku.}] ::msgcat::mcset cs {An error has occurred while saving} [encoding convertfrom iso8859-2 {Chyba pøi ukládání souboru}] ::msgcat::mcset cs {An error has occurred while writing image.} ::msgcat::mcset cs {An internal error has been detected} [encoding convertfrom iso8859-2 {Byla detekována vnitøní chyba programu}] ::msgcat::mcset cs {Analysis Command Log} [encoding convertfrom iso8859-2 {Poøizovat záznam analytických pøíkazù}] ::msgcat::mcset cs {Analysis Commands} [encoding convertfrom iso8859-2 {Analytické pøíkazy}] ::msgcat::mcset cs {Analysis File} [encoding convertfrom iso8859-2 {Analytický soubor}] ::msgcat::mcset cs {Analysis Log} [encoding convertfrom iso8859-2 {Záznam èinnosti analytický pøíkazù}] ::msgcat::mcset cs {Analysis} [encoding convertfrom iso8859-2 {Analýza}] ::msgcat::mcset cs {Angle Complement} [encoding convertfrom iso8859-2 {Doplnìk úhlu}] ::msgcat::mcset cs {Angles} [encoding convertfrom iso8859-2 {Úhly}] ::msgcat::mcset cs {Angle} [encoding convertfrom iso8859-2 {Úhel}] ::msgcat::mcset cs {Annuli} [encoding convertfrom iso8859-2 {Kruhù}] ::msgcat::mcset cs {Annulus} [encoding convertfrom iso8859-2 {Kruh}] ::msgcat::mcset cs {Apply} [encoding convertfrom iso8859-2 {Pou¾ít}] ::msgcat::mcset cs {ArcMin} [encoding convertfrom iso8859-2 {úhlových minut}] ::msgcat::mcset cs {ArcSec} [encoding convertfrom iso8859-2 {úhlových sekund}] ::msgcat::mcset cs {Architecture} [encoding convertfrom iso8859-2 {Architektura}] ::msgcat::mcset cs {Archives} [encoding convertfrom iso8859-2 {Achívy}] ::msgcat::mcset cs {Array} ::msgcat::mcset cs {Arrow} [encoding convertfrom iso8859-2 {©ipka}] ::msgcat::mcset cs {Astronomy} [encoding convertfrom iso8859-2 {Astronomie}] ::msgcat::mcset cs {At Startup} [encoding convertfrom iso8859-2 {Pøi spu¹tìní}] ::msgcat::mcset cs {At least 2 different catalogs are required} ::msgcat::mcset cs {Auto Centroid} [encoding convertfrom iso8859-2 {Automatické centrování}] ::msgcat::mcset cs {Auto Plot 2D} [encoding convertfrom iso8859-2 {Automatický 2D graf}] ::msgcat::mcset cs {Auto Plot 3D} [encoding convertfrom iso8859-2 {Automatický 3D graf}] ::msgcat::mcset cs {Auto Plot} [encoding convertfrom iso8859-2 {Automatický graf}] ::msgcat::mcset cs {Autoload FITS Regions} [encoding convertfrom iso8859-2 {Automaticky nahrát FITS oblasti}] ::msgcat::mcset cs {Autoload} [encoding convertfrom iso8859-2 {Automatické nahrávání}] ::msgcat::mcset cs {Automatic} [encoding convertfrom iso8859-2 {Automatické}] ::msgcat::mcset cs {Average} [encoding convertfrom iso8859-2 {Prùmìr}] ::msgcat::mcset cs {Axes Number} ::msgcat::mcset cs {Axes Title} ::msgcat::mcset cs {Axes} [encoding convertfrom iso8859-2 {Osy}] ::msgcat::mcset cs {Axis Label} [encoding convertfrom iso8859-2 {Popisek osy}] ::msgcat::mcset cs {Axis Length} [encoding convertfrom iso8859-2 {Délka osy}] ::msgcat::mcset cs {Axis Numbers} [encoding convertfrom iso8859-2 {Èíslování osy}] ::msgcat::mcset cs {Axis} [encoding convertfrom iso8859-2 {Osy}] ::msgcat::mcset cs {Azimuth} [encoding convertfrom iso8859-2 {Azimut}] ::msgcat::mcset cs {Background Color} [encoding convertfrom iso8859-2 {Barva pozadí}] ::msgcat::mcset cs {Background} [encoding convertfrom iso8859-2 {Pozadí}] ::msgcat::mcset cs {Backup} [encoding convertfrom iso8859-2 {Záloha}] ::msgcat::mcset cs {Back} [encoding convertfrom iso8859-2 {Zpìt}] ::msgcat::mcset cs {Bar Plot Tool} ::msgcat::mcset cs {Bias} ::msgcat::mcset cs {Bin 3rd Column} [encoding convertfrom iso8859-2 {Binuj tøetí sloupec}] ::msgcat::mcset cs {Bin Center} [encoding convertfrom iso8859-2 {Binuj støed}] ::msgcat::mcset cs {Bin Columns} [encoding convertfrom iso8859-2 {Binuj sloupce}] ::msgcat::mcset cs {Bin Filter} [encoding convertfrom iso8859-2 {Filtr binování}] ::msgcat::mcset cs {Binning Parameters} [encoding convertfrom iso8859-2 {Parametry binování}] ::msgcat::mcset cs {Bin} ::msgcat::mcset cs {Black} [encoding convertfrom iso8859-2 {Èerná}] ::msgcat::mcset cs {Blank/Inf/NaN Color} [encoding convertfrom iso8859-2 {Barva nedefinovaných pixelù}] ::msgcat::mcset cs {Blink Frames} [encoding convertfrom iso8859-2 {Problikávej snímky}] ::msgcat::mcset cs {Blink Interval} [encoding convertfrom iso8859-2 {Interval problikávání snímkù}] ::msgcat::mcset cs {Blink} [encoding convertfrom iso8859-2 {Problikávat}] ::msgcat::mcset cs {Block In} [encoding convertfrom iso8859-2 {Zmen¹it}] ::msgcat::mcset cs {Block Out} [encoding convertfrom iso8859-2 {Zvìt¹it}] ::msgcat::mcset cs {Block to Fit Frame} [encoding convertfrom iso8859-2 {Na velikost snímku}] ::msgcat::mcset cs {Block} ::msgcat::mcset cs {Blue} [encoding convertfrom iso8859-2 {Modrá}] ::msgcat::mcset cs {Bold} [encoding convertfrom iso8859-2 {Tuènì}] ::msgcat::mcset cs {Border} [encoding convertfrom iso8859-2 {Okraj}] ::msgcat::mcset cs {Box Annulus} ::msgcat::mcset cs {Box Panda} ::msgcat::mcset cs {BoxCircle} ::msgcat::mcset cs {Boxcar} ::msgcat::mcset cs {Box} [encoding convertfrom iso8859-2 {Obdélník}] ::msgcat::mcset cs {Broadcast} ::msgcat::mcset cs {Browser} [encoding convertfrom iso8859-2 {Prohlí¾eè}] ::msgcat::mcset cs {Browse} [encoding convertfrom iso8859-2 {Prohlí¾et}] ::msgcat::mcset cs {Buffer} ::msgcat::mcset cs {Buttonbar} ::msgcat::mcset cs {Buttons} [encoding convertfrom iso8859-2 {Tlaèítka}] ::msgcat::mcset cs {Bytes} ::msgcat::mcset cs {CMYK} ::msgcat::mcset cs {Can Delete} ::msgcat::mcset cs {Can Edit} ::msgcat::mcset cs {Can Move} ::msgcat::mcset cs {Can Rotate} ::msgcat::mcset cs {Cancel} [encoding convertfrom iso8859-2 {Zru¹it}] ::msgcat::mcset cs {Catalog Server} [encoding convertfrom iso8859-2 {Katalogový server}] ::msgcat::mcset cs {Catalog Tool} [encoding convertfrom iso8859-2 {Katalogový nástroj}] ::msgcat::mcset cs {Catalogs} [encoding convertfrom iso8859-2 {Katalogy}] ::msgcat::mcset cs {Catalog} [encoding convertfrom iso8859-2 {Katalog}] ::msgcat::mcset cs {Center Image} [encoding convertfrom iso8859-2 {Vycentruj obrázek}] ::msgcat::mcset cs {Center Non-modal Dialogs} ::msgcat::mcset cs {Center} [encoding convertfrom iso8859-2 {Støed}] ::msgcat::mcset cs {Centroid Parameters} [encoding convertfrom iso8859-2 {Parametry centroidu}] ::msgcat::mcset cs {Centroid} [encoding convertfrom iso8859-2 {Vystøedit}] ::msgcat::mcset cs {Circle} [encoding convertfrom iso8859-2 {Kru¾nice}] ::msgcat::mcset cs {Clear All} [encoding convertfrom iso8859-2 {Vyma¾ v¹e}] ::msgcat::mcset cs {Clear Analysis Commands} [encoding convertfrom iso8859-2 {Vyma¾ analytické pøíkazy}] ::msgcat::mcset cs {Clear Cache} ::msgcat::mcset cs {Clear Data} ::msgcat::mcset cs {Clear External Analysis Commands?} ::msgcat::mcset cs {Clear Filter} [encoding convertfrom iso8859-2 {Vynuluvoat filtr}] ::msgcat::mcset cs {Clear Frame} [encoding convertfrom iso8859-2 {Vyèistit snímek}] ::msgcat::mcset cs {Clear Preferences?} [encoding convertfrom iso8859-2 {Smazat nastavení?}] ::msgcat::mcset cs {Clear Preferences} [encoding convertfrom iso8859-2 {Smazat nastavení}] ::msgcat::mcset cs {Clear} [encoding convertfrom iso8859-2 {Vyèistit}] ::msgcat::mcset cs {Click to Center} [encoding convertfrom iso8859-2 {Klinout na centrování}] ::msgcat::mcset cs {Close} [encoding convertfrom iso8859-2 {Zavøít}] ::msgcat::mcset cs {Colorbar Size} [encoding convertfrom iso8859-2 {Velikost colorbaru}] ::msgcat::mcset cs {Colorbar} [encoding convertfrom iso8859-2 {©kálování barev}] ::msgcat::mcset cs {Colormap Parameters} ::msgcat::mcset cs {Colormap} ::msgcat::mcset cs {Color} [encoding convertfrom iso8859-2 {Barva}] ::msgcat::mcset cs {Columns} [encoding convertfrom iso8859-2 {Sloupce}] ::msgcat::mcset cs {Column} [encoding convertfrom iso8859-2 {Sploupec}] ::msgcat::mcset cs {Command} [encoding convertfrom iso8859-2 {Pøíkaz}] ::msgcat::mcset cs {Compass} [encoding convertfrom iso8859-2 {Kompas}] ::msgcat::mcset cs {Composite Region} [encoding convertfrom iso8859-2 {Spojit oblasti}] ::msgcat::mcset cs {Composite} ::msgcat::mcset cs {Compression} [encoding convertfrom iso8859-2 {Komprese}] ::msgcat::mcset cs {Configure} [encoding convertfrom iso8859-2 {Konfigurace}] ::msgcat::mcset cs {Connect Directly} ::msgcat::mcset cs {Connect SAMP} ::msgcat::mcset cs {Connect Using Web Proxy} ::msgcat::mcset cs {Connect} [encoding convertfrom iso8859-2 {Pøipoji}] ::msgcat::mcset cs {Console} ::msgcat::mcset cs {Contour Parameters} [encoding convertfrom iso8859-2 {Parametry obrysu}] ::msgcat::mcset cs {Contours} [encoding convertfrom iso8859-2 {Obrysy}] ::msgcat::mcset cs {Contour} [encoding convertfrom iso8859-2 {Obrys}] ::msgcat::mcset cs {Contrast} [encoding convertfrom iso8859-2 {Kontrast}] ::msgcat::mcset cs {Contributed} ::msgcat::mcset cs {Convert to Polygons} [encoding convertfrom iso8859-2 {Zmìnit na obdélníky}] ::msgcat::mcset cs {Coordinate Grid Parameters} [encoding convertfrom iso8859-2 {Nastavení møí¾ky}] ::msgcat::mcset cs {Coordinate Grid} [encoding convertfrom iso8859-2 {Møí¾ka}] ::msgcat::mcset cs {Coordinate System} [encoding convertfrom iso8859-2 {Systém koordinátù}] ::msgcat::mcset cs {Coordinates} [encoding convertfrom iso8859-2 {Koordináty}] ::msgcat::mcset cs {Coordinate} [encoding convertfrom iso8859-2 {Koordinát}] ::msgcat::mcset cs {Copy Contours} ::msgcat::mcset cs {Copy to Regions} [encoding convertfrom iso8859-2 {Kopíruj do oblastí}] ::msgcat::mcset cs {Copy} [encoding convertfrom iso8859-2 {Kopíruj}] ::msgcat::mcset cs {Create Movie} [encoding convertfrom iso8859-2 {Vytvoøit video}] ::msgcat::mcset cs {Create New Frame on Download} ::msgcat::mcset cs {Create} [encoding convertfrom iso8859-2 {Vytvoøit}] ::msgcat::mcset cs {Crop Parameters} [encoding convertfrom iso8859-2 {Parametry oøezávání}] ::msgcat::mcset cs {Crop} [encoding convertfrom iso8859-2 {Výøez}] ::msgcat::mcset cs {Crosshair To} [encoding convertfrom iso8859-2 {Zamìøovaè na}] ::msgcat::mcset cs {Crosshair} [encoding convertfrom iso8859-2 {Zamìøovaè}] ::msgcat::mcset cs {Cross} [encoding convertfrom iso8859-2 {Køí¾}] ::msgcat::mcset cs {Cube} [encoding convertfrom iso8859-2 {Krychle}] ::msgcat::mcset cs {Current Frame} [encoding convertfrom iso8859-2 {Souèasný obrázek}] ::msgcat::mcset cs {Current Range} [encoding convertfrom iso8859-2 {Souèasný rozsah}] ::msgcat::mcset cs {Current} [encoding convertfrom iso8859-2 {Souèasný}] ::msgcat::mcset cs {Cursor} [encoding convertfrom iso8859-2 {Kurzor}] ::msgcat::mcset cs {Cut} [encoding convertfrom iso8859-2 {Vyøíznout}] ::msgcat::mcset cs {Cyan} [encoding convertfrom iso8859-2 {Azurová}] ::msgcat::mcset cs {DPI} ::msgcat::mcset cs {DS9 has detected a newer version of a backup file and therefore will not process this file.} [encoding convertfrom iso8859-2 {Program na¹el novou verzi zálo¾ního souboru a tedy tento soubor nebude zpracován.}] ::msgcat::mcset cs {DS9 has detected a newer version of a preferences file and therefore will not process this file.} [encoding convertfrom iso8859-2 {Konfiguraèní soubor je pro novìj¹í verzi DS9, a tedy nebude zpracován.}] ::msgcat::mcset cs {DS9 has detected an older backup file, do you wish to continue?} [encoding convertfrom iso8859-2 {DS9 detekovala starou verzi zálo¾ního souboru, chcete pokraèovat?}] ::msgcat::mcset cs {DS9 has detected an older preferences file, do you wish to update?} [encoding convertfrom iso8859-2 {Starý konfiguraèní soubor, chcete ho zaktualizovat?}] ::msgcat::mcset cs {DS9 will complete the initialization process} [encoding convertfrom iso8859-2 {DS9 dokonèí inticializaèní proces}] ::msgcat::mcset cs {Dash} ::msgcat::mcset cs {Data Format} [encoding convertfrom iso8859-2 {Formát dat}] ::msgcat::mcset cs {Dataset} [encoding convertfrom iso8859-2 {Soubor dat}] ::msgcat::mcset cs {Data} ::msgcat::mcset cs {Decrease} [encoding convertfrom iso8859-2 {Zmen¹it}] ::msgcat::mcset cs {Default All Files} [encoding convertfrom iso8859-2 {Vychozí pro v¹echny soubory}] ::msgcat::mcset cs {Default Format} ::msgcat::mcset cs {Default Length} ::msgcat::mcset cs {Default} [encoding convertfrom iso8859-2 {Výchozí}] ::msgcat::mcset cs {Degrees} [encoding convertfrom iso8859-2 {Stupnì}] ::msgcat::mcset cs {Delete All Frames?} [encoding convertfrom iso8859-2 {Smazat v¹echny snímky?}] ::msgcat::mcset cs {Delete All Frames} [encoding convertfrom iso8859-2 {Smazat v¹echny snímky}] ::msgcat::mcset cs {Delete All Groups?} [encoding convertfrom iso8859-2 {Smazat v¹echny skupiny?}] ::msgcat::mcset cs {Delete All Groups} [encoding convertfrom iso8859-2 {Smazat v¹echny skupiny}] ::msgcat::mcset cs {Delete All Regions?} [encoding convertfrom iso8859-2 {Smazat v¹echny oblasti?}] ::msgcat::mcset cs {Delete All Regions} [encoding convertfrom iso8859-2 {Smazat v¹echny oblasti}] ::msgcat::mcset cs {Delete All} [encoding convertfrom iso8859-2 {Smazat v¹e}] ::msgcat::mcset cs {Delete Color Tags} ::msgcat::mcset cs {Delete Frame} [encoding convertfrom iso8859-2 {Smazat snímek}] ::msgcat::mcset cs {Delete Group} [encoding convertfrom iso8859-2 {Smazat skupiny}] ::msgcat::mcset cs {Delete Selected Regions} [encoding convertfrom iso8859-2 {Smazat vybrané oblasti}] ::msgcat::mcset cs {Delete} [encoding convertfrom iso8859-2 {Smazat}] ::msgcat::mcset cs {Depth} [encoding convertfrom iso8859-2 {Hloubka}] ::msgcat::mcset cs {Detector} [encoding convertfrom iso8859-2 {Detektor}] ::msgcat::mcset cs {Dialog Box} [encoding convertfrom iso8859-2 {Dialogové okno}] ::msgcat::mcset cs {Diamond} [encoding convertfrom iso8859-2 {Diamant}] ::msgcat::mcset cs {Dimension} [encoding convertfrom iso8859-2 {Rozmìr}] ::msgcat::mcset cs {Disconnect} ::msgcat::mcset cs {Discrete} ::msgcat::mcset cs {Display Header} ::msgcat::mcset cs {Display Size} [encoding convertfrom iso8859-2 {Velikost displeje}] ::msgcat::mcset cs {Dissolve} ::msgcat::mcset cs {Distance} [encoding convertfrom iso8859-2 {Vzdálenost}] ::msgcat::mcset cs {Download Colormap} ::msgcat::mcset cs {Download VOTABLE format if available} ::msgcat::mcset cs {Drag to Center} ::msgcat::mcset cs {Duplicate Data} ::msgcat::mcset cs {East} [encoding convertfrom iso8859-2 {Východ}] ::msgcat::mcset cs {Ecliptic} [encoding convertfrom iso8859-2 {Ekliptikální}] ::msgcat::mcset cs {Edit Group Name} ::msgcat::mcset cs {Edit} [encoding convertfrom iso8859-2 {Úpravy}] ::msgcat::mcset cs {Element} ::msgcat::mcset cs {Elevation} ::msgcat::mcset cs {Ellipse Panda} ::msgcat::mcset cs {Ellipse} [encoding convertfrom iso8859-2 {Elipsa}] ::msgcat::mcset cs {Elliptical Annulus} ::msgcat::mcset cs {Elliptical Panda} ::msgcat::mcset cs {Enable Confirmation Dialogs} ::msgcat::mcset cs {Enable} [encoding convertfrom iso8859-2 {Povolit}] ::msgcat::mcset cs {End} [encoding convertfrom iso8859-2 {Ukonèit}] ::msgcat::mcset cs {Enter Color} [encoding convertfrom iso8859-2 {Zadejte barvu}] ::msgcat::mcset cs {Enter Font Size} ::msgcat::mcset cs {Enter Group Name} ::msgcat::mcset cs {Enter Search Expression} ::msgcat::mcset cs {Enter URL} ::msgcat::mcset cs {Entry} ::msgcat::mcset cs {Equal Area} ::msgcat::mcset cs {Equal Distance} ::msgcat::mcset cs {Equal Spacing} ::msgcat::mcset cs {Equal Value} ::msgcat::mcset cs {Error code was returned} ::msgcat::mcset cs {Error} ::msgcat::mcset cs {Examine Frame} ::msgcat::mcset cs {Examine} [encoding convertfrom iso8859-2 {Prozkoumat}] ::msgcat::mcset cs {Exclude} ::msgcat::mcset cs {Executing TCL code is not enabled} ::msgcat::mcset cs {Exit} [encoding convertfrom iso8859-2 {Ukonèi}] ::msgcat::mcset cs {Export Array} ::msgcat::mcset cs {Export} [encoding convertfrom iso8859-2 {Ulo¾it jako}] ::msgcat::mcset cs {Extention} ::msgcat::mcset cs {Exterior Axes} ::msgcat::mcset cs {Exterior Numerics} ::msgcat::mcset cs {FAQ} ::msgcat::mcset cs {FK4} ::msgcat::mcset cs {FK5} ::msgcat::mcset cs {Factor} [encoding convertfrom iso8859-2 {Faktor}] ::msgcat::mcset cs {File not Found or Unable to load FITS data MIME type} [encoding convertfrom iso8859-2 {Soubor nenalezen nebo není mo¾né nahrát daný FITS MIME typ}] ::msgcat::mcset cs {Filename} [encoding convertfrom iso8859-2 {Název souboru}] ::msgcat::mcset cs {File} [encoding convertfrom iso8859-2 {Soubor}] ::msgcat::mcset cs {Fill} ::msgcat::mcset cs {Filter} [encoding convertfrom iso8859-2 {Filtr}] ::msgcat::mcset cs {Find Next} [encoding convertfrom iso8859-2 {Najít dal¹í}] ::msgcat::mcset cs {Find} [encoding convertfrom iso8859-2 {Najít}] ::msgcat::mcset cs {First Frame} [encoding convertfrom iso8859-2 {První snímek}] ::msgcat::mcset cs {First} [encoding convertfrom iso8859-2 {První}] ::msgcat::mcset cs {Fits} ::msgcat::mcset cs {Fixed in Size} ::msgcat::mcset cs {Flip} ::msgcat::mcset cs {Font} [encoding convertfrom iso8859-2 {Znak}] ::msgcat::mcset cs {For more information, use --help} [encoding convertfrom iso8859-2 {Pro více informací, pou¾ijte --help}] ::msgcat::mcset cs {Format} [encoding convertfrom iso8859-2 {Formát}] ::msgcat::mcset cs {Forward} [encoding convertfrom iso8859-2 {Vpøed}] ::msgcat::mcset cs {Found} [encoding convertfrom iso8859-2 {Nalezeno}] ::msgcat::mcset cs {Frame Information} [encoding convertfrom iso8859-2 {Informace o snímku}] ::msgcat::mcset cs {Frame Parameters} [encoding convertfrom iso8859-2 {Parametry snímku}] ::msgcat::mcset cs {Frames} [encoding convertfrom iso8859-2 {Snímky}] ::msgcat::mcset cs {Frame} [encoding convertfrom iso8859-2 {Snímek}] ::msgcat::mcset cs {From} [encoding convertfrom iso8859-2 {Od}] ::msgcat::mcset cs {Front} [encoding convertfrom iso8859-2 {První}] ::msgcat::mcset cs {Full Range} [encoding convertfrom iso8859-2 {Plný rozsah}] ::msgcat::mcset cs {Function} [encoding convertfrom iso8859-2 {Funkce}] ::msgcat::mcset cs {GUI Font} [encoding convertfrom iso8859-2 {Font GUI}] ::msgcat::mcset cs {Galactic} [encoding convertfrom iso8859-2 {Galaktické}] ::msgcat::mcset cs {Gap} ::msgcat::mcset cs {Gaussian} ::msgcat::mcset cs {General} ::msgcat::mcset cs {Generate} [encoding convertfrom iso8859-2 {Vygeneruj}] ::msgcat::mcset cs {Generating Regions} ::msgcat::mcset cs {Get Information} [encoding convertfrom iso8859-2 {Získej informace}] ::msgcat::mcset cs {Global Properties} ::msgcat::mcset cs {Global} ::msgcat::mcset cs {Goto Frame} [encoding convertfrom iso8859-2 {Bì¾ na snímek}] ::msgcat::mcset cs {Graph Horz} ::msgcat::mcset cs {Graph Vert} ::msgcat::mcset cs {Graphics} ::msgcat::mcset cs {Graphs} [encoding convertfrom iso8859-2 {Grafy}] ::msgcat::mcset cs {Graph} [encoding convertfrom iso8859-2 {Graf}] ::msgcat::mcset cs {Grayscale} [encoding convertfrom iso8859-2 {Stupnì ¹edi}] ::msgcat::mcset cs {Green} [encoding convertfrom iso8859-2 {Zelená}] ::msgcat::mcset cs {Grid Gap} ::msgcat::mcset cs {Grid} [encoding convertfrom iso8859-2 {Møí¾ka}] ::msgcat::mcset cs {Groups} [encoding convertfrom iso8859-2 {Skupiny}] ::msgcat::mcset cs {HTTP} ::msgcat::mcset cs {Header} [encoding convertfrom iso8859-2 {Hlavièka}] ::msgcat::mcset cs {Height} [encoding convertfrom iso8859-2 {Vý¹ka}] ::msgcat::mcset cs {Help Desk} [encoding convertfrom iso8859-2 {Podpora}] ::msgcat::mcset cs {Help Me Choose} ::msgcat::mcset cs {Help} [encoding convertfrom iso8859-2 {Nápovìda}] ::msgcat::mcset cs {Hide All} [encoding convertfrom iso8859-2 {Skryj v¹echny}] ::msgcat::mcset cs {Highlite} ::msgcat::mcset cs {High} [encoding convertfrom iso8859-2 {Vysoký}] ::msgcat::mcset cs {Histogram Equalization} [encoding convertfrom iso8859-2 {Vyrovnání histogramu}] ::msgcat::mcset cs {Histogram} ::msgcat::mcset cs {Horizontal Graph} [encoding convertfrom iso8859-2 {Horizontální graf}] ::msgcat::mcset cs {Horizontal Layout} [encoding convertfrom iso8859-2 {Horizontální rozlo¾ení}] ::msgcat::mcset cs {Horizontal} ::msgcat::mcset cs {IAU Location Code} ::msgcat::mcset cs {ICRS} ::msgcat::mcset cs {Identification} ::msgcat::mcset cs {If} ::msgcat::mcset cs {Image Servers} [encoding convertfrom iso8859-2 {Obrázkové servery}] ::msgcat::mcset cs {Image} [encoding convertfrom iso8859-2 {Obrázek}] ::msgcat::mcset cs {Import Array} ::msgcat::mcset cs {Import} ::msgcat::mcset cs {Include} ::msgcat::mcset cs {Increase} ::msgcat::mcset cs {Information Panel} [encoding convertfrom iso8859-2 {Informaèní panel}] ::msgcat::mcset cs {Information} [encoding convertfrom iso8859-2 {Detaily}] ::msgcat::mcset cs {Initialize XPA} ::msgcat::mcset cs {Inner} ::msgcat::mcset cs {Instrument FOV} [encoding convertfrom iso8859-2 {Zorné pole dalekohledù}] ::msgcat::mcset cs {Interior Axes} ::msgcat::mcset cs {Interior Numerics} ::msgcat::mcset cs {Internal Parse Error} ::msgcat::mcset cs {Interval} ::msgcat::mcset cs {Invalid Column Name} ::msgcat::mcset cs {Invalid formated multipart/mixed mime type message} ::msgcat::mcset cs {Invert Colormap} ::msgcat::mcset cs {Invert Selection} [encoding convertfrom iso8859-2 {Vybrat doplnìk}] ::msgcat::mcset cs {Invert} [encoding convertfrom iso8859-2 {Pøeklopit}] ::msgcat::mcset cs {Italic} [encoding convertfrom iso8859-2 {Kurzíva}] ::msgcat::mcset cs {Items Found} ::msgcat::mcset cs {Iteration} ::msgcat::mcset cs {JPEG Quality Factor} [encoding convertfrom iso8859-2 {Kvalita JPEGu}] ::msgcat::mcset cs {Keep-Alive} ::msgcat::mcset cs {Kernel} [encoding convertfrom iso8859-2 {Kernel}] ::msgcat::mcset cs {Keyboard Shortcuts} [encoding convertfrom iso8859-2 {Klávesnicové zkratky}] ::msgcat::mcset cs {Keyboard} [encoding convertfrom iso8859-2 {Klávesnice}] ::msgcat::mcset cs {Labels} [encoding convertfrom iso8859-2 {Oznaèení}] ::msgcat::mcset cs {Label} [encoding convertfrom iso8859-2 {Oznaèení}] ::msgcat::mcset cs {Landscape} [encoding convertfrom iso8859-2 {Horizontálnì}] ::msgcat::mcset cs {Language} [encoding convertfrom iso8859-2 {Jazyk}] ::msgcat::mcset cs {Last Frame} [encoding convertfrom iso8859-2 {Poslední snímek}] ::msgcat::mcset cs {Last} [encoding convertfrom iso8859-2 {Poslední}] ::msgcat::mcset cs {Layout Horz} ::msgcat::mcset cs {Layout Vert} ::msgcat::mcset cs {Layout} [encoding convertfrom iso8859-2 {Rozvr¾ení}] ::msgcat::mcset cs {Left} [encoding convertfrom iso8859-2 {Vlevo}] ::msgcat::mcset cs {Legal} ::msgcat::mcset cs {Length} [encoding convertfrom iso8859-2 {Délka}] ::msgcat::mcset cs {Letter} ::msgcat::mcset cs {Levels} [encoding convertfrom iso8859-2 {Úrovnì}] ::msgcat::mcset cs {Level} [encoding convertfrom iso8859-2 {Úroveò}] ::msgcat::mcset cs {Limits} ::msgcat::mcset cs {Line Plot Tool} ::msgcat::mcset cs {Linear} [encoding convertfrom iso8859-2 {Linární}] ::msgcat::mcset cs {Line} ::msgcat::mcset cs {List Data} ::msgcat::mcset cs {List Regions} [encoding convertfrom iso8859-2 {Seznam oblastí}] ::msgcat::mcset cs {List} [encoding convertfrom iso8859-2 {Seznam}] ::msgcat::mcset cs {Load Analysis Commands} [encoding convertfrom iso8859-2 {Nahrát analytické pøíkazy}] ::msgcat::mcset cs {Load Color Tags} ::msgcat::mcset cs {Load Colormap} ::msgcat::mcset cs {Load Configuration} [encoding convertfrom iso8859-2 {Nahraj konfiguraci}] ::msgcat::mcset cs {Load Contour Levels} ::msgcat::mcset cs {Load Contours} ::msgcat::mcset cs {Load Contrast/Bias} ::msgcat::mcset cs {Load Data} ::msgcat::mcset cs {Load Mosaic} ::msgcat::mcset cs {Load Regions} [encoding convertfrom iso8859-2 {Nahrát oblasti}] ::msgcat::mcset cs {Load Template} ::msgcat::mcset cs {Load into All Frames} ::msgcat::mcset cs {Load into Current Frame} ::msgcat::mcset cs {Loading Catalog} ::msgcat::mcset cs {Loading} ::msgcat::mcset cs {Load} [encoding convertfrom iso8859-2 {Nahrát}] ::msgcat::mcset cs {Local} ::msgcat::mcset cs {Lock Bin} ::msgcat::mcset cs {Lock Color} ::msgcat::mcset cs {Lock Crop Amplifier} ::msgcat::mcset cs {Lock Crop Detector} ::msgcat::mcset cs {Lock Crop Image} ::msgcat::mcset cs {Lock Crop None} ::msgcat::mcset cs {Lock Crop Physical} ::msgcat::mcset cs {Lock Crop WCS} ::msgcat::mcset cs {Lock Crosshair Amplifier} ::msgcat::mcset cs {Lock Crosshair Detector} ::msgcat::mcset cs {Lock Crosshair Image} ::msgcat::mcset cs {Lock Crosshair None} ::msgcat::mcset cs {Lock Crosshair Physical} ::msgcat::mcset cs {Lock Crosshair WCS} ::msgcat::mcset cs {Lock Frame Amplifier} ::msgcat::mcset cs {Lock Frame Detector} ::msgcat::mcset cs {Lock Frame Image} ::msgcat::mcset cs {Lock Frame None} ::msgcat::mcset cs {Lock Frame Physical} ::msgcat::mcset cs {Lock Frame WCS} ::msgcat::mcset cs {Lock Scale} ::msgcat::mcset cs {Lock Slice} ::msgcat::mcset cs {Lock Smooth} ::msgcat::mcset cs {Lock} [encoding convertfrom iso8859-2 {Synchronizovat}] ::msgcat::mcset cs {Log Exponent} [encoding convertfrom iso8859-2 {Numerus logaritmu}] ::msgcat::mcset cs {Log} [encoding convertfrom iso8859-2 {Logaritmické}] ::msgcat::mcset cs {Low High} [encoding convertfrom iso8859-2 {Nejmen¹í Nejvìt¹í}] ::msgcat::mcset cs {Lower Left Back} ::msgcat::mcset cs {Lower Left Front} ::msgcat::mcset cs {Lower Right Back} ::msgcat::mcset cs {Lower Right Front} ::msgcat::mcset cs {Low} ::msgcat::mcset cs {MIP} ::msgcat::mcset cs {Magenta} ::msgcat::mcset cs {Magnification} ::msgcat::mcset cs {Magnifier} [encoding convertfrom iso8859-2 {Zvìt¹ovaè}] ::msgcat::mcset cs {Major} ::msgcat::mcset cs {Manual} ::msgcat::mcset cs {Mask Parameters} [encoding convertfrom iso8859-2 {Nastavení masky}] ::msgcat::mcset cs {Match Bin} [encoding convertfrom iso8859-2 {Zarovnat bin}] ::msgcat::mcset cs {Match Catalog requires at least 1 row per catalog} ::msgcat::mcset cs {Match Color} [encoding convertfrom iso8859-2 {Sladit barvu}] ::msgcat::mcset cs {Match Crop Amplifier} ::msgcat::mcset cs {Match Crop Detector} ::msgcat::mcset cs {Match Crop Image} ::msgcat::mcset cs {Match Crop Physical} ::msgcat::mcset cs {Match Crop WCS} ::msgcat::mcset cs {Match Crosshair Amplifier} ::msgcat::mcset cs {Match Crosshair Detector} ::msgcat::mcset cs {Match Crosshair Image} ::msgcat::mcset cs {Match Crosshair Physical} ::msgcat::mcset cs {Match Crosshair WCS} ::msgcat::mcset cs {Match Frame Amplifier} ::msgcat::mcset cs {Match Frame Detector} ::msgcat::mcset cs {Match Frame Image} ::msgcat::mcset cs {Match Frame Physical} ::msgcat::mcset cs {Match Frame WCS} ::msgcat::mcset cs {Match Scale} [encoding convertfrom iso8859-2 {Zarovnat ¹kálování}] ::msgcat::mcset cs {Match Slice} ::msgcat::mcset cs {Match Smooth} ::msgcat::mcset cs {Match} [encoding convertfrom iso8859-2 {Zarovnat}] ::msgcat::mcset cs {Math Function} ::msgcat::mcset cs {Max Rows} ::msgcat::mcset cs {Max} ::msgcat::mcset cs {Menus and Buttons} ::msgcat::mcset cs {Menu} [encoding convertfrom iso8859-2 {Nabídka}] ::msgcat::mcset cs {Message Log} ::msgcat::mcset cs {Method} ::msgcat::mcset cs {Min Max Parameters} ::msgcat::mcset cs {Min Max} [encoding convertfrom iso8859-2 {Minimum Maximum}] ::msgcat::mcset cs {Minor} ::msgcat::mcset cs {Minutes} ::msgcat::mcset cs {Min} ::msgcat::mcset cs {Mission} ::msgcat::mcset cs {Mode} ::msgcat::mcset cs {Mosaic IRAF Segment} ::msgcat::mcset cs {Mosaic IRAF} ::msgcat::mcset cs {Mosaic WCS Segment} ::msgcat::mcset cs {Mosaic WCS} ::msgcat::mcset cs {Mosaic WFPC2} ::msgcat::mcset cs {Mosaic} ::msgcat::mcset cs {Mouse & Keyboard} [encoding convertfrom iso8859-2 {My¹ a klávesnice}] ::msgcat::mcset cs {Mouse Wheel Bin} ::msgcat::mcset cs {Mouse Wheel Zoom} ::msgcat::mcset cs {Move Back} ::msgcat::mcset cs {Move First} ::msgcat::mcset cs {Move Forward} ::msgcat::mcset cs {Move Frame} [encoding convertfrom iso8859-2 {Pøesunout snímek}] ::msgcat::mcset cs {Move Last} ::msgcat::mcset cs {Move to Back} [encoding convertfrom iso8859-2 {Pøesunout vzad}] ::msgcat::mcset cs {Move to Front} [encoding convertfrom iso8859-2 {Pøesunout vpøed}] ::msgcat::mcset cs {Movie} ::msgcat::mcset cs {Multiple Extension Cube} ::msgcat::mcset cs {Multiple Extension Frames} ::msgcat::mcset cs {Multiple WCS} [encoding convertfrom iso8859-2 {Multi WCS}] ::msgcat::mcset cs {NRRD} ::msgcat::mcset cs {Name Resolution} [encoding convertfrom iso8859-2 {Vyhledání objektu}] ::msgcat::mcset cs {Name Server} ::msgcat::mcset cs {Name or Designation} ::msgcat::mcset cs {Name} [encoding convertfrom iso8859-2 {Název}] ::msgcat::mcset cs {Native Dialog} ::msgcat::mcset cs {Native} ::msgcat::mcset cs {New 3D} ::msgcat::mcset cs {New Features} [encoding convertfrom iso8859-2 {Nové vlasnosti}] ::msgcat::mcset cs {New Frame 3D} [encoding convertfrom iso8859-2 {Nový 3D snímek}] ::msgcat::mcset cs {New Frame RGB} [encoding convertfrom iso8859-2 {Nový barevný RGB snímek}] ::msgcat::mcset cs {New Frame each Time} ::msgcat::mcset cs {New Frame} [encoding convertfrom iso8859-2 {Nový snímek}] ::msgcat::mcset cs {New Group} [encoding convertfrom iso8859-2 {Nová skupina}] ::msgcat::mcset cs {New RGB} [encoding convertfrom iso8859-2 {Nový RGB}] ::msgcat::mcset cs {New} [encoding convertfrom iso8859-2 {Nový}] ::msgcat::mcset cs {Next Frame} [encoding convertfrom iso8859-2 {Dal¹í snímek}] ::msgcat::mcset cs {Next} [encoding convertfrom iso8859-2 {Dal¹í}] ::msgcat::mcset cs {No Catalog specified} ::msgcat::mcset cs {No Items Found} ::msgcat::mcset cs {No current frame} ::msgcat::mcset cs {No data available at } ::msgcat::mcset cs {Non-zero} ::msgcat::mcset cs {None} [encoding convertfrom iso8859-2 {Nic}] ::msgcat::mcset cs {Normal} ::msgcat::mcset cs {North} [encoding convertfrom iso8859-2 {Sever}] ::msgcat::mcset cs {Not Found} ::msgcat::mcset cs {No} [encoding convertfrom iso8859-2 {Ne}] ::msgcat::mcset cs {Number of Samples} ::msgcat::mcset cs {Number of Threads} ::msgcat::mcset cs {Number of Ticks} ::msgcat::mcset cs {Number} [encoding convertfrom iso8859-2 {Èíslo}] ::msgcat::mcset cs {Numerics} ::msgcat::mcset cs {OK} [encoding convertfrom iso8859-2 {Budi¾}] ::msgcat::mcset cs {Object} [encoding convertfrom iso8859-2 {Objekt}] ::msgcat::mcset cs {Open File} [encoding convertfrom iso8859-2 {Otevøít soubor}] ::msgcat::mcset cs {Open TCL Console} [encoding convertfrom iso8859-2 {Otevøít konzoly TCL}] ::msgcat::mcset cs {Open URL} [encoding convertfrom iso8859-2 {Otevøít URL}] ::msgcat::mcset cs {Open as} ::msgcat::mcset cs {Open} [encoding convertfrom iso8859-2 {Otevøít}] ::msgcat::mcset cs {Operator} ::msgcat::mcset cs {Orientation} ::msgcat::mcset cs {Origin} ::msgcat::mcset cs {Oscillate} ::msgcat::mcset cs {Other Color} ::msgcat::mcset cs {Other Font Size} ::msgcat::mcset cs {Other} ::msgcat::mcset cs {Outer} ::msgcat::mcset cs {PS Page Setup} ::msgcat::mcset cs {PS Print} ::msgcat::mcset cs {Page Setup} [encoding convertfrom iso8859-2 {Vlastnosti tisku}] ::msgcat::mcset cs {Page Source} ::msgcat::mcset cs {Pan To} ::msgcat::mcset cs {Pan Zoom Rotate Parameters} [encoding convertfrom iso8859-2 {Parametry prohlí¾ení a zvìt¹ení}] ::msgcat::mcset cs {Pan Zoom} ::msgcat::mcset cs {Pan then Zoom} ::msgcat::mcset cs {Panda} ::msgcat::mcset cs {Panner} [encoding convertfrom iso8859-2 {Náhled snímku}] ::msgcat::mcset cs {Pan} [encoding convertfrom iso8859-2 {Posun}] ::msgcat::mcset cs {Parameters} ::msgcat::mcset cs {Password} ::msgcat::mcset cs {Paste Contours} ::msgcat::mcset cs {Paste} [encoding convertfrom iso8859-2 {Vlo¾it}] ::msgcat::mcset cs {Physical} [encoding convertfrom iso8859-2 {Fyzické}] ::msgcat::mcset cs {Pixel Distribution} ::msgcat::mcset cs {Pixel Size} ::msgcat::mcset cs {Pixel Table} [encoding convertfrom iso8859-2 {Pixel tabulka}] ::msgcat::mcset cs {Pixels} ::msgcat::mcset cs {Play} ::msgcat::mcset cs {Please Select a Region} ::msgcat::mcset cs {Please specify width, height, and either name or (ra,dec)} ::msgcat::mcset cs {Plot 2D} ::msgcat::mcset cs {Plot 3D} ::msgcat::mcset cs {Plot Title} ::msgcat::mcset cs {Plotting Regions} ::msgcat::mcset cs {Plot} ::msgcat::mcset cs {Plus} ::msgcat::mcset cs {Pointer} [encoding convertfrom iso8859-2 {Ukazatel}] ::msgcat::mcset cs {Points} ::msgcat::mcset cs {Point} ::msgcat::mcset cs {Polygon} ::msgcat::mcset cs {Portrait} ::msgcat::mcset cs {Poster} ::msgcat::mcset cs {Postscript Page Setup} ::msgcat::mcset cs {Postscript Print} ::msgcat::mcset cs {Postscript} ::msgcat::mcset cs {Power} [encoding convertfrom iso8859-2 {Mocninové}] ::msgcat::mcset cs {Preferences have been reset to the default values. Please restart DS9 for these changes to take effect} ::msgcat::mcset cs {Preferences} [encoding convertfrom iso8859-2 {Nastavení}] ::msgcat::mcset cs {Preserve During Load} [encoding convertfrom iso8859-2 {Zachovej pøi otevøení}] ::msgcat::mcset cs {Previous Frame} [encoding convertfrom iso8859-2 {Pøede¹lí snímek}] ::msgcat::mcset cs {Previous} [encoding convertfrom iso8859-2 {Pøedchozí}] ::msgcat::mcset cs {Print Coordinates} ::msgcat::mcset cs {Print To} ::msgcat::mcset cs {Printer} ::msgcat::mcset cs {Print} [encoding convertfrom iso8859-2 {Vytisknout}] ::msgcat::mcset cs {Projection} ::msgcat::mcset cs {Properties} [encoding convertfrom iso8859-2 {Vlastnosti}] ::msgcat::mcset cs {Property} ::msgcat::mcset cs {Proxy Host} ::msgcat::mcset cs {Proxy Port} ::msgcat::mcset cs {Publication} ::msgcat::mcset cs {Quadratic} ::msgcat::mcset cs {RGB Array} ::msgcat::mcset cs {RGB Cube} ::msgcat::mcset cs {RGB Image} ::msgcat::mcset cs {RGB} ::msgcat::mcset cs {Radial Profile} ::msgcat::mcset cs {Radius} ::msgcat::mcset cs {Range} ::msgcat::mcset cs {Redo} ::msgcat::mcset cs {Red} ::msgcat::mcset cs {Reference Manual} [encoding convertfrom iso8859-2 {Seznam pøíkazù}] ::msgcat::mcset cs {Reference} ::msgcat::mcset cs {Refresh Frame} [encoding convertfrom iso8859-2 {Obnov snímek}] ::msgcat::mcset cs {Refresh} ::msgcat::mcset cs {Region Parameters} [encoding convertfrom iso8859-2 {Parametry oblastí}] ::msgcat::mcset cs {Region} [encoding convertfrom iso8859-2 {Oblasti}] ::msgcat::mcset cs {Release Notes} [encoding convertfrom iso8859-2 {Informace o vydání}] ::msgcat::mcset cs {Release} ::msgcat::mcset cs {Reload} ::msgcat::mcset cs {Repeat} ::msgcat::mcset cs {Reset Colormap} ::msgcat::mcset cs {Reset Frame} [encoding convertfrom iso8859-2 {Vynulovat nastavení snímku}] ::msgcat::mcset cs {Reset} ::msgcat::mcset cs {Restore} [encoding convertfrom iso8859-2 {Obnovit}] ::msgcat::mcset cs {Retrieve} ::msgcat::mcset cs {Return} ::msgcat::mcset cs {Right} ::msgcat::mcset cs {Roman} ::msgcat::mcset cs {Rotate} {Rotovat} ::msgcat::mcset cs {Rows} ::msgcat::mcset cs {Row} ::msgcat::mcset cs {Ruler} ::msgcat::mcset cs {SAMP Image} ::msgcat::mcset cs {SAMP Table} ::msgcat::mcset cs {SAMP: already connected} ::msgcat::mcset cs {SAMP: internal error} ::msgcat::mcset cs {SAMP: not connected} ::msgcat::mcset cs {SAMP: unable to locate HUB} ::msgcat::mcset cs {SAMP} ::msgcat::mcset cs {Sample Increment} ::msgcat::mcset cs {Sample Parameters} ::msgcat::mcset cs {Samples per Line} ::msgcat::mcset cs {Sample} ::msgcat::mcset cs {Save 3D Movie} ::msgcat::mcset cs {Save Color Tags} ::msgcat::mcset cs {Save Colormap} ::msgcat::mcset cs {Save Configuration} ::msgcat::mcset cs {Save Contour Levels} ::msgcat::mcset cs {Save Contours} ::msgcat::mcset cs {Save Contrast/Bias} ::msgcat::mcset cs {Save Data} ::msgcat::mcset cs {Save Image on Download} ::msgcat::mcset cs {Save Image} [encoding convertfrom iso8859-2 {Ulo¾it snímek}] ::msgcat::mcset cs {Save Regions} [encoding convertfrom iso8859-2 {Ulo¾it oblasti}] ::msgcat::mcset cs {Save Template} [encoding convertfrom iso8859-2 {Ulo¾it ¹ablony}] ::msgcat::mcset cs {Save as} ::msgcat::mcset cs {Save} [encoding convertfrom iso8859-2 {Ulo¾it}] ::msgcat::mcset cs {Scale Parameters} [encoding convertfrom iso8859-2 {Parametry ¹kálování}] ::msgcat::mcset cs {Scale} [encoding convertfrom iso8859-2 {©kálování}] ::msgcat::mcset cs {Scan} ::msgcat::mcset cs {Scatter Plot Tool} ::msgcat::mcset cs {Scope} ::msgcat::mcset cs {Search for Catalogs} ::msgcat::mcset cs {Searching for catalogs} ::msgcat::mcset cs {Seconds} ::msgcat::mcset cs {Select All} [encoding convertfrom iso8859-2 {Vybrat v¹echny}] ::msgcat::mcset cs {Select Coordinate System } ::msgcat::mcset cs {Select None} [encoding convertfrom iso8859-2 {Zru¹it výbìr}] ::msgcat::mcset cs {Send} ::msgcat::mcset cs {Server} ::msgcat::mcset cs {Sexagesimal} [encoding convertfrom iso8859-2 {©edesátkové}] ::msgcat::mcset cs {Shape} [encoding convertfrom iso8859-2 {Tvar}] ::msgcat::mcset cs {Show All} [encoding convertfrom iso8859-2 {Zobrazit v¹e}] ::msgcat::mcset cs {Show Command} ::msgcat::mcset cs {Show Compass} ::msgcat::mcset cs {Show Text} ::msgcat::mcset cs {Show/Hide Frames} [encoding convertfrom iso8859-2 {Zobrazit/skrýt snímky}] ::msgcat::mcset cs {Show} ::msgcat::mcset cs {Single Frame} [encoding convertfrom iso8859-2 {Jeden snímek}] ::msgcat::mcset cs {Single} [encoding convertfrom iso8859-2 {jeden}] ::msgcat::mcset cs {Sites} ::msgcat::mcset cs {Size/Radius} ::msgcat::mcset cs {Size} ::msgcat::mcset cs {Skip First} ::msgcat::mcset cs {Slice} ::msgcat::mcset cs {Smooth Parameters} [encoding convertfrom iso8859-2 {Nastavení vyhlazení}] ::msgcat::mcset cs {Smoothness} ::msgcat::mcset cs {Smooth} [encoding convertfrom iso8859-2 {Vyhlazení}] ::msgcat::mcset cs {Sorry, DS9 does not support} ::msgcat::mcset cs {Sorry, DS9 requires a Pseudocolor8, Truecolor8, Truecolor16, Truecolor24 visual be available} ::msgcat::mcset cs {Sort} ::msgcat::mcset cs {Source TCL} ::msgcat::mcset cs {Source} ::msgcat::mcset cs {Space Equal Distance} ::msgcat::mcset cs {Space Equal Value} ::msgcat::mcset cs {Spacing} ::msgcat::mcset cs {Square Root} [encoding convertfrom iso8859-2 {Odmocninové}] ::msgcat::mcset cs {Squared} ::msgcat::mcset cs {Starbase} ::msgcat::mcset cs {Startup} ::msgcat::mcset cs {Start} ::msgcat::mcset cs {Statistics} ::msgcat::mcset cs {Status} ::msgcat::mcset cs {Step} ::msgcat::mcset cs {Stop} ::msgcat::mcset cs {Story of SAOImage DS9} [encoding convertfrom iso8859-2 {Pøíbìh SAOImage DS9}] ::msgcat::mcset cs {Story} ::msgcat::mcset cs {Sum} ::msgcat::mcset cs {Symbol Editor} ::msgcat::mcset cs {Symbol} ::msgcat::mcset cs {Tab-Separated-Value} ::msgcat::mcset cs {Table} ::msgcat::mcset cs {Tabloid} ::msgcat::mcset cs {Template} [encoding convertfrom iso8859-2 {©ablona}] ::msgcat::mcset cs {Text Font} ::msgcat::mcset cs {Text} ::msgcat::mcset cs {Theme} ::msgcat::mcset cs {Then} ::msgcat::mcset cs {Thickness} ::msgcat::mcset cs {This analysis task is already running. Do you wish to kill it?} ::msgcat::mcset cs {Tickmarks} ::msgcat::mcset cs {Tile Frames} [encoding convertfrom iso8859-2 {Snímky do dla¾dic}] ::msgcat::mcset cs {Tile Parameters} [encoding convertfrom iso8859-2 {Parametry dla¾dic}] ::msgcat::mcset cs {Tile} [encoding convertfrom iso8859-2 {Dla¾dice}] ::msgcat::mcset cs {Times} ::msgcat::mcset cs {Title} ::msgcat::mcset cs {To Fit} [encoding convertfrom iso8859-2 {pøizpùsobit}] ::msgcat::mcset cs {Tophat} ::msgcat::mcset cs {To} ::msgcat::mcset cs {Transparency} ::msgcat::mcset cs {Type} ::msgcat::mcset cs {URL} ::msgcat::mcset cs {Unable to connect directly: using Web Proxy} ::msgcat::mcset cs {Unable to create RGB or 3D frame with pseudocolor visual} ::msgcat::mcset cs {Unable to determine date of observation} ::msgcat::mcset cs {Unable to determine time of observation} ::msgcat::mcset cs {Unable to evaluate filter} ::msgcat::mcset cs {Unable to find catalog window} ::msgcat::mcset cs {Unable to find plot window} ::msgcat::mcset cs {Unable to load RGB image into a non-rgb frame} ::msgcat::mcset cs {Unable to load region file} ::msgcat::mcset cs {Unable to load} ::msgcat::mcset cs {Unable to locate URL} ::msgcat::mcset cs {Unable to match target with XPA Mime request} ::msgcat::mcset cs {Unable to open file} ::msgcat::mcset cs {Unable to save RGB image from a non-rgb frame} ::msgcat::mcset cs {Undo} [encoding convertfrom iso8859-2 {Zpìt}] ::msgcat::mcset cs {Unique} ::msgcat::mcset cs {Units} ::msgcat::mcset cs {Unknown Colormap} ::msgcat::mcset cs {Unknown command} ::msgcat::mcset cs {Update Filter} ::msgcat::mcset cs {Update Group} ::msgcat::mcset cs {Update from Current Crosshair} ::msgcat::mcset cs {Update from Current Frame} ::msgcat::mcset cs {Update} ::msgcat::mcset cs {Upper Left Back} ::msgcat::mcset cs {Upper Left Front} ::msgcat::mcset cs {Upper Right Back} ::msgcat::mcset cs {Upper Right Front} ::msgcat::mcset cs {Use Authentication} ::msgcat::mcset cs {Use Current Frame on Download} ::msgcat::mcset cs {Use Internal Web Browser} ::msgcat::mcset cs {Use Proxy} ::msgcat::mcset cs {User Manual} [encoding convertfrom iso8859-2 {U¾ivatelský manuál}] ::msgcat::mcset cs {Username} ::msgcat::mcset cs {User} [encoding convertfrom iso8859-2 {U¾ivatelské}] ::msgcat::mcset cs {Use} [encoding convertfrom iso8859-2 {Pou¾ívat}] ::msgcat::mcset cs {VO Server} ::msgcat::mcset cs {VO} ::msgcat::mcset cs {Value} [encoding convertfrom iso8859-2 {Hodnota}] ::msgcat::mcset cs {Vector} ::msgcat::mcset cs {Vertical Graph} [encoding convertfrom iso8859-2 {Vertikální graf}] ::msgcat::mcset cs {Vertical Layout} [encoding convertfrom iso8859-2 {Vertikální rozlo¾ení}] ::msgcat::mcset cs {Vertical Text} ::msgcat::mcset cs {Vertical} ::msgcat::mcset cs {View} [encoding convertfrom iso8859-2 {Zobrazit}] ::msgcat::mcset cs {Virtual Observatory} [encoding convertfrom iso8859-2 {Virtuální Observatoø}] ::msgcat::mcset cs {WCS Parameters} [encoding convertfrom iso8859-2 {Detaily WCS}] ::msgcat::mcset cs {WCS} ::msgcat::mcset cs {Wavelength} ::msgcat::mcset cs {Web Browser} [encoding convertfrom iso8859-2 {Prohlí¾eè}] ::msgcat::mcset cs {White} ::msgcat::mcset cs {Width} [encoding convertfrom iso8859-2 {Tlou¹»ka}] ::msgcat::mcset cs {Words matching title, description} ::msgcat::mcset cs {Writing Catalog} ::msgcat::mcset cs {X Axis Title} ::msgcat::mcset cs {X Axis} ::msgcat::mcset cs {X Grid} ::msgcat::mcset cs {XPA Information} ::msgcat::mcset cs {XPA not initialized} [encoding convertfrom iso8859-2] ::msgcat::mcset cs {XPA unable to verify hostname, setting XPA_METHOD to LOCAL} ::msgcat::mcset cs {XPA} ::msgcat::mcset cs {X} ::msgcat::mcset cs {Y Axis Title} ::msgcat::mcset cs {Y Axis} ::msgcat::mcset cs {Y Grid} ::msgcat::mcset cs {Yellow} [encoding convertfrom iso8859-2 {®lutá}] ::msgcat::mcset cs {Yes} [encoding convertfrom iso8859-2 {Ano}] ::msgcat::mcset cs {Y} ::msgcat::mcset cs {Z Axis Scale} ::msgcat::mcset cs {ZScale Parameters} [encoding convertfrom iso8859-2 {Parametry ZScale}] ::msgcat::mcset cs {Zero} [encoding convertfrom iso8859-2 {Nula}] ::msgcat::mcset cs {Zoom In} [encoding convertfrom iso8859-2 {Zvìt¹it}] ::msgcat::mcset cs {Zoom Out} [encoding convertfrom iso8859-2 {Zmen¹it}] ::msgcat::mcset cs {Zoom to Fit Frame} [encoding convertfrom iso8859-2 {Pøizpùsobit velikosti snímku}] ::msgcat::mcset cs {Zoom} [encoding convertfrom iso8859-2 {Zvìt¹ení}] ::msgcat::mcset cs {and} ::msgcat::mcset cs {blue} [encoding convertfrom iso8859-2 {modrá}] ::msgcat::mcset cs {b} ::msgcat::mcset cs {color} [encoding convertfrom iso8859-2 {barva}] ::msgcat::mcset cs {cool} [encoding convertfrom iso8859-2 {chlad}] ::msgcat::mcset cs {green} [encoding convertfrom iso8859-2 {zelená}] ::msgcat::mcset cs {grey} [encoding convertfrom iso8859-2 {¹edá}] ::msgcat::mcset cs {g} ::msgcat::mcset cs {heat} [encoding convertfrom iso8859-2 {horko}] ::msgcat::mcset cs {not} ::msgcat::mcset cs {only} ::msgcat::mcset cs {or center of data} ::msgcat::mcset cs {rainbow} [encoding convertfrom iso8859-2 {duha}] ::msgcat::mcset cs {red} [encoding convertfrom iso8859-2 {èervená}] ::msgcat::mcset cs {rows of data have been downloaded. More may be available. You may wish to adjust the maximum allowed} [encoding convertfrom iso8859-2 {øádkù dat. Více jich mù¾e být k dispozici. Zkuste zmìnit povolené maximum}] ::msgcat::mcset cs {r} ::msgcat::mcset cs {staircase} [encoding convertfrom iso8859-2 {schodi¹tì}] ::msgcat::mcset cs {standard} ::msgcat::mcset cs {x} ::msgcat::mcset cs {} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.macosxsnowleopard���������������������������������������������������������������������0000644�0001750�0001750�00000001051�11773331763�015522� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxsnowleopard DEPENDS = yes X11INCLUDE =../include/X11 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -mmacosx-version-min=10.6 AA = -fPIC -D_MACOSX -DMAC_OSX_TK -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz JOBS = 4 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/util/��������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201303�012044� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/util/mergedict.tcl�������������������������������������������������������������������������0000644�0001750�0001750�00000002452�10660664756�014552� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# usage: mergedict <##> set mm [lindex $argv 0] set enc [lindex $argv 1] set fn "msgs/${mm}.msg" # read in original msg file if {[catch {open $fn r} id]} { puts "Error: can't open $fn for reading" return } fconfigure $id -encoding $enc set orgmsg {} while {[gets $id line] >= 0} { lappend orgmsg $line } set orgmsg [lsort -unique $orgmsg] catch {close $id} # read current msgs set curmsg {} while {[gets stdin line] >= 0} { set exp {.*msgcat::mc {([^\}]*)}} if [regexp $exp $line foo aa] { lappend curmsg "::msgcat::mcset $mm {$aa} " } } set curmsg [lsort -unique $curmsg] # now merge original against current set mermsg {} foreach ll $curmsg { set ii [lsearch -glob $orgmsg "$ll*"] if {$ii != -1} { lappend mermsg [lindex $orgmsg $ii] } else { lappend mermsg $ll } } set mermsg [lsort -unique $mermsg] # now find unused entries in original foreach ll $orgmsg { set ii [lsearch -exact $mermsg $ll] if {$ii == -1} { if {[string range $ll 0 0] != {#}} { lappend mermsg "# $ll" } else { lappend mermsg "$ll" } } } set mermsg [lsort -unique $mermsg] # write new msg file if {[catch {open $fn w} id]} { puts "Error: can't open $fn for writing" return } fconfigure $id -encoding $enc foreach ll $mermsg { puts $id $ll } catch {close $id} ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinx86leopard����������������������������������������������������������������������0000644�0001750�0001750�00000001166�11773331763�015162� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinx86leopard X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation export MACOSX_DEPLOYMENT_TARGET := 10.5 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-leopard.tar.gz JOBS = 4 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/notes.txt����������������������������������������������������������������������������������0000644�0001750�0001750�00000052167�12132057400�013001� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Ports: porter MacOSX 10.4, MacOSX 10.5, MacOSX 10.6 duet MacOSX 10.7 marmite CentOS-5.5 bokhara fc8 64 xebec solaris 10 Install HEAD: solaris shanti cp -p build/solaris/ds9 /rom-48/hea0/soft/saord/bin/. linux shanti cp -p build/linux/ds9 /rom-48/hea1/soft/Linux/i686/saord/bin/. linux64 shanti cp -p build/linux64/ds9 /rom-48/hea1/soft/Linux/x86_64/saord/bin/. MacOSX 10.5 shanti cp -p build/darwinleopard/ds9 /rom-48/hea1/soft/saord/Leopard_i386/bin/. cp -p build/darwinleopard/ds9.zip /rom-48/hea1/soft/saord/Leopard_i386/bin/. Web: /proj/webhead/RD/ds9 macports- for doc html2ps sudo port install wget sudo port install ImageMagick for darwin lion/mountainlion % sudo port install pkgconfig #install ~/lib/pkgconfig/xft.pc #set PKG_CONFIG_PATH) % PKG_CONFIG_PATH=$HOME/lib/pkgconfig:/usr/X11/lib/pkgconfig apple.com: http://www.apple.com/downloads/ Submit Downloads Source: ast http://starlink.jach.hawaii.edu/starlink/AST wcssubs ftp://cfa-ftp.harvard.edu/pub/gsc/WCSTools funtools /data/mmti/CVSROOT pcc http://pcc.ludd.ltu.se/ http://pcc.ludd.ltu.se/ftp/pub/pcc/ http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/ tcc http://bellard.org/tcc/ Build: # cvs- back out changes cvs update -j 1.5 -j 1.4 foo.c # reset sticky tag cvs update -A HTML Comment: <!-- something --> Future: MacOSX Aqua XPAInfo Astrometry.net Tutorials Catalog To Image/3d cube Editing (add/delete) Button/GUI editor 1D SpecFrame 3D Cube Reorder Axes VO Image Archive VO/Chandra Footprint server FOV (http://aladin.u-strasbg.fr/java/FOVs.xml) Illustrate mode Remote Observing Non-Model File Browser FITS structure viewer 2D surface plot Windows64 (not yet! lack of cygwin support) List -7.3 marker analysis- background subtraction TAB WCS Save- ZPX/TNX (PCOUNT?) Edit Keywords (crop) DETSIZE DETSECT CCDSUM LTMV ATMV DTMV DATASEC CRPIX tests smosaic Mask- add mosaicimagewfpc2 photo Slice- add mosaicimagewcs mosaicimageiraf mosaicimagewfpc2 mosaicwcs mosaiciraf array nrrd Fits Sample data needed compress-float/double table wmap mosaicwcs mosaiciraf mosaicwfpc2 fix cleanup frame.C vs frame3d.C crop- recal LTM/V, DATASEC keywords undo UpdateDS9Static file frame zoom analysis nrrd hex ascii bz2 wcs compass region issue (Gabrial Bihanin) scale compass with zoom add compass length to dialog ps center vs ll -1 for other pagesize (margins) DASCH saveimage chops last line (window) iis wcs (values on colorbar) imexam (check against) Imexam/FWHM/surface plot (Paul Weissman) scale width of wcs values in infobox (John Davis) 3d- segv when start with image mail bag darwin 64/ast issue (extention_11.fits.gz) grid publication bug (Kshitiz Mallick) polar coordinates (Jonathan) windows 7 64 bit standard dialog causes crashes (Achim Tappe) windows 7 64 bit drag and drop segv (Wayne Rosing) horz/vert cut across mosaic (Brian) scale parameter dialog (Terry) fits cube->multiple fits (Bill Pense) bin to fit (Diab) windows save jpg (Steve Pravdo) Alexey skybot segv prefs- turn off major buttons update menu (gui) help pages rgb analysis stats fitsy++ map.C change like strm.C (nrrd) rm dataSize_/dataSkip_/dataManage_? bin table- if no TLMIN/MAX, scan data 3d crop by value shift crop with -az pan problem (IFU) marker analysis cleanup c code bkgd substract catalog match- unique closest match error cols histogram plot marker analysis mosaic rgb 3d graphs stacked datasets mosaic rgb 3d FFMpeg Radio getValue()? BUNIT (JY/BEAM) BMAJ-major (fwhm) BMIN-minor BPA-angle or HISTORY AIPS CLEAN BMAJ= 1.2500E-02 BMIN= 1.2500E-02 BPA= 0.00 take average of 3rd axis/area=JY/BEAM tck/tk 8.6 update blt? upgrade tkhtml? blt x11 only windows macosx update install page 3D compass arrows numerics doc bin-3rd axis reset after apply 3rd axis cut 2d image vo ddt- samp to ds9 native plot print win32 macosx photo wcs 3D other lock frame (pan problem) compass grids rotate text ps text over grid SIP prefs for AUTOSCAN value keyContext vs context vs currentContext mosaics macros $url() | $image(3d) Magnifier- bitbit off by .5? magnifier cursor panner/widget blank issue while rotating: only at vp=0,0 and depth=1 wcszoom for point regions zoom[0]!=zoom[1] panner arrows (see marker arrows) config instead of forget? (layout vert) special modes +-x frames, updated as current slice moves line cut down 3rd axis-> new image markers compass arrows other windows- astAnnul too slow (for large data cubes) analysis: compress fits warp cursor weirdness (framebase) check saveas fits (LTMV?) smooth smooth over crop only use threads regions cleanup- CB procs tcl rm var(proc,distCB), var(proc,editCB) line/projection/ruler annulus/ellipse annulus/box annulus panda/bpanda/epanda vector projection drop frametruecolor colormap begin/motion/end? (lock colorbar) rotate begin/motion/end? analysis.sh- add filename tests move filter strings from file.C to fitsimage.C image[ext][sec] table[ext][filter][slicefilter] crop2d fix -crop x y w h wcs galatic arcsec issue GUI cross mosaic edges dialog (for each mosaic) cleanup refreshinfobox clearinfobox clearpixeltable cleargraph updatestatic? tile mode grid axis build pcc for lion -structure check tcl/tk lib for zip dir absolute dir for mount point (alexeys problem with ssh mounted disks, can we use /tmp?) tcl/tk lib encodings help fov source ?.tcl (ds9.tcl) SIGBUS- look for EXC_BAD_ACCESS also -64 bit FITS Fitsy++ fits keywords (test64bit.fits) clean up configure mods (use autoreconf) blt html tclxml tcllib zip macosx tk generic/tkEvent macosx/tkMacOSXDraw.c blt w==0 xlib/X11/Xlib.h -Bugs [ds9|?]parser.Y allow 1e-01" and 1e-01' for vvalue toggle frame (with mosaics) infobox blinks out iraf lines adjust cmap with red bg (seeing white) when rebin, update wcs param dialog plot xerr yerr problems check for nan preserve scale bscale/bzero bscale=-1 issue cygwin/iraf windows problem (return filename in cygwin format) Fix updating graphs while rotate/zoom/pan Panzoom- update dialog while rotate/zoom/pan small pixel problem (Alexander Menshchikov) make sure image server dialogs are below when saveas bin bin table 3d, smooth, rebin rgb, current blue, cut paste regions display header mosaic (one line if all the same) -MacOSX drag-out image,text load contour dialog (focus on ok after menu change) -Windows ::ttk::checkbutton vo.tcl (tri state check) clip regions glob? screen aspect ratio print dpi (for text) variable dashed lines display print $ds9 -url 'ftp://sao-ftp/foo.fits' analysis tasks will not abort start on other drives than C:/flash drives -Analysis return which button from xpa analysis message ProcessAnalysisCmd- tests/analysis.sh group macro expansion add/replace mouse button analysis bindings. $web(http:chandra-ed.harvard.edu/rebin.html?$XPA_METHOD) marker analysis support($region (select)) sort param variables to fix $sub vs $subimage problem check 'open | ' fork/exec? $(shell variable) macro -Analysis Plot sort data when loading user data crosshairs with x,y,value display x axis- end points with reasonable values one/multiple window options better bltGraph.pro fix -Backup masks (per context: filename,color,mark) problem alloc/channel/socket/var loads mosaicimage iraf/wfpc2 mosaic iraf -Binning dialog specify buffersize dialog specify weight col bin from dialog, option to ignore bin center (Diab) bin (disregard TDMIN/TDMAX checkbox) Diab binning center with bin<1 DS9_BINKEY rm cols restriction or define DS9_FILTER bin data cube- auto title add file[bin][filter] (depth, function, block, etc) binning-- too many updateClip() calls why scan each time bin? can we save min/max? bin add x:diminsion,y:diminsion to parser (ciao like syntax) -Blink blink mode with fast flash select which frames to blink non-modal dialog (simular to ximtool) -Catalog NonFK5 sky_in sky_out ICRS Comments --- ------ ------- ---- -------- NED yes yes no SIMBAD yes yes yes CDS yes yes no (no ecl) CXC no no no SKYBOT no no no scatter chart for catalogs clear/delete frame, close all catalogs load catalog via stdin delete frame/delete dialog new catalog delete region/row add region/row filter local catalog at load -Comm event feedback via xpa/samp -Contours contour copy/paste? (save in var?) dashed for neg clip contours to mosaic segment clip overlay contours to image boundries -Crop crop in WCS -Examine only works for files xpa imexam return frame # (patrick broos) -Fits blocking gzip/compress/pack- use magic number instead of file ext gzip fits in/out (buffer size?) reorder x/y/z data cube- data/DHT33_carina.fits hduname support TNULLn ascii/binary tables FITS compression long long -Graphs (Horz/Vert) MacOSX print Windows print postscript print set range limits don't clip numbers on ends large numbers (500000 verse 5e5) -GUI tcl var for each (like hv) analysis markers full frame view (short cut)? buttons reorder cursor-to dialog menus params via shortcuts language textvariable color (plot.tcl) dlabel,clabel,dist,system,sky,skyformat get panner to generate 'EnterPanner' events during blink annotate frames with user specified name prefs 2/3 button mouse -HV http://tkhtml.tcl.tk/index.html history/clear history multipart mime- push no terminating str ftp soft links textarea with scrollbars print -IRAF problem with 'display dev$pix 1 select_frame-' imexamine problem with frames 10-16 -Masks bin table: block in/out -Printing Annotate prints with title/footnotes -Regions line/vector/projection/ruler- coordinates diffs,angle,length clip to image renderXText- clip to widget regions tests for -format/-system/-sky projection region- add bin size option new copy/paste regions: copy into tcl var (both physical and wcs) regions std dialog send/receive samp votable votable- composite ds9parser- parse (hh mm ss [+-]dd mm ss) projection delete/composite undelete/desolve no update default coordinate systems for plots specify method FITS Regions add HDUCLAS1 add MFORM1 support add WCS support gz fits use current properties XPA/SAMP control over existing regions change colors/properties change default shape sizes return ids when create select last region created groups- new/delete xy,saoimage,ciao-- use current shape,color,properties Tests point region # pointsize= composite # composite = 1 text # textrotate = yes mosaic/analysis regions macro for non-wcs -Scale Lupton (2004) (STIFF program within the ASTROMATIC package) -WCS add RADESYS: FK4-NO-E/GAPPT/SUPERGALACTIC/HELIOECLIPTIC menus solar SOLX/SOLY,HPLN/HPLT,HGLN/HGLT,HRLN/HRLT wcs editor- astrometry.net header define keywords ----- ------ -------- TAN old SCAMP PVx_y TPV new SCAMP PVx_y xxx generic PVx_y xxx autoastrom QVx_y ZPX IRAF WATx_ TNX IRAF WATx_ TAN-SIP SIP A_x_y,B_x_y,AP_x_y,BP_x_y,A_ORDER,B_ORDER AP_ORDER,BP_ORDER,A_DMAX,B_DMAX TAN SAO Plate COx_y Problem FITS WCS Files wcssubs ast wcslib ------- --- ------ COD/COE/COO/COP (bad, yes, yes) HPX (HEALPix) (no, yes, yes) DSS (SAO) (yes, yes, no) TNX (NOAO TAN + params) (yes , yes, no) ZPX (NOAO ZPN + params) (yes , yes, no) TAN---RA-SIP (SIRTF) (yes, yes, no) SCAMP (SAO TAN + PV) (yes, yes(PV->QV), no) TPV (NOAO TAN + PV) (yes, yes(PV->QV), no) AUTOASTROM (xxx + QV) (no, yes, no) WCSDEP (yes, no, no) STScI DSS wcen.fits.gz OLD SCAMP (PVx_30) ac42227_00_01ww_tnx.fits ngc6819.fits TAN+PV (PVx_20) paucam_0_0_t7_0_science.fits TAN+ PV2_1=0 PV2_2=0 IC2395_ch1_merged.fits IC2395_ch2_merged.fits IC2395_ch3_merged.fits IC2395_ch4_merged.fits SAGE_LMC_MIPS24_E12.fits g180p00r45b120pm.fits a68.fits n132d_s18_7_LL_Cont_15mic.fits ZPN+PV (PV2_1,PV2_3,PV2_5) ABELL0586.0750.fits D4.0705.fits EGS1.1193.fits LSSTtest.2124.fits UKIDDS_K_3219_606_17_67_3.fits rcs2_m3.2540.fits TNX (WATx_yyy) 30s_01.fits cal000277b.fits mscred.fits obj094.fits obj269z.fits westphal_Rs.wcs.fits ZPX (WATx_yyy) E5.3090.fits E5.3075.fits TAN-SIP (A_,B_,AP_,BP) sst.fits mos8.fits (no reverse) SAO PLT (COx_13) ac.fits crts_short.fits (bad?) WCSDEP ngc6819.fits HPX wmap_ilc_3yr_v2-HPX.fits TAB sparse.fits GLON-ZEA South_galactic.fits g000p00r2.fits North_galactic.fits -bad SFD_dust_4096_ngp.fits RA-CAR CAR_model.fits car_01.fits GLON-CAR GLM_00350+0115_mosaic_I4_cutout_14706.fits GLM_03350+0000_mosaic_I1_cutout_10617.fits GP_343.5_+0.0_A.fits fermi_counts_gps_bin_1.00.fits gc_energybin07_fadapt10_smajor030.fits gc_energybin07_fadapt10_smajor100.fits msxmapA-1a.fits msxmapA-2.fits eta.fits rmon_msxmapA.fits iras_hires_band3.fits msx327p5.fits msxmapA-1.fits -old style (linear wcs) Wco_DHT2001.fits total_hi.fits xLON/xLAT- bad worldtopo.multi.fits 'TLON-CAR' IRAF obj011.fits oct12_096.4.fits CROTA1 AXJ165420_GAIA.fits SKYBOT ggg.fits.gz Languages: Dansk Allan Hornstrup allan@dsri.dk Español Manuel Perez Torres mpereztorres@cfa Portuguese Alberto Krone-Martins krone@obs.u-bordeaux1.fr Japanese Masahiro Tsujimoto tsujimot@astro.psu.edu Chinese Junfeng Wang jwang@head.cfa.harvard.edu Chinese Albert Kong akong@space.mit.edu Français (a-c) Jean-Baptiste Marquette marquett@iap.fr Français (d-h) Jean-Francois Sygnet sygnet@iap.fr Français (i-m) Elaine Fortin elaine_fortin@harvard.edu Français (n-p) Anne Lemiere alemiere@head.cfa.harvard.edu Français *(q-t) Jean-Francois Sygnet sygnet@iap.fr Français *(u-z) Ilana Harrus imh@milkyway.gsfc.nasa.gov Notes: fonts render/print/ps linux render native, PS base macsox render native, print native, PS base win32 render native, print native, PS base where ds9: TkDefaultFont horz/vert graph: TkDefaultFont scale dialog: TkDefaultFont hv: hv(font) tktable: TkDefaultFont panner: ds9(helvetica) plot: ap(titlefont)/ap(numlabfont)/ap(textlabfont) colorbar: colorbar(font) grid: opts= titlefont/numlabfont/textlabfont marker: str Types (*no save, **no save,no alloc) fits sfits** rgbimage rgbcube srgbcube** mecube multiframe* mosaicimagewcs mosaicimageiraf* mosaicimagewfpc* mosaicwcs mosaiciraf* smosaicwcs** smosaiciraf** array rgbarray nrrd gif jpeg tiff png loadParam(file,type) FITS ARRAY loadParam(file,mode) {} {data cube} {mosaic image iraf} {mosaic image} {mosaic image wcs} {mosaic wcs} {mosaic image wfpc2} {rgb image} {rgb cube} loadParam(load,type) alloc allocgz channel mmap mmapincr smmap shared sshared socket socketgz var Fitsy++ Memory modes strm (alloc) allocgz channel (socket) socketgz map (mmap) share var smap smmap sshare mapincr mmapincr funtools LAUNCH_ROUTINE: V f|F p|P FILTER_PTYPE: c IRAF Graphcap :DD=node!imtool,fifo\:/dev/imt1i\:/dev/imt1o,512,512:tc=iism70: :DD=node!imtool,inet\:5137,512,512:tc=iism70: :DD=node!imtool,unix\:/tmp/.IMT%d,512,512:tc=iism70: IRAF Colors: 202 = black 203 = white 204 = red 205 = green 206 = blue 207 = yellow 208 = cyan 209 = magenta 210 = coral (255 127 80) 211 = maroon (176 48 96) 212 = orange (255 165 0) 213 = khaki (240 230 140) 214 = orchid (218 112 214) 215 = turquoise (64 224 208) 216 = violet (238 130 238) 217 = wheat (245 222 179) 218-254 = reserved for use by other windows 255 = black (sunview foreground color) Word Length ***i386 char 1 short 2 int 4 long int 4 long 4 long long 8 void* 4 ***x86_64 char 1 short 2 int 4 long int 8 long 8 long long 8 void* 8 ***solaris char 1 short 2 int 4 long int 4 long 4 long long 8 void* 4 ***solaris64 char 1 short 2 int 4 long int 8 long 8 long long 8 void* 8 ***ppc char 1 short 2 int 4 long int 4 long 4 long long 8 void* 4 ***pcc64 char 1 short 2 int 4 long int 8 long 8 long long 8 void* 8 WCS Keywords WCSNAME WCSNAMEa TWCSn TWCSna CTYPEi CTYPEia TCTYPn TCTYna CUNITi CUNITia TCUNIn TCUNna CRPIXi CRPIXia TCRPXn TCRPna CRVALi CRVALia TCRVLn TCRVna CDELTi CDELTia TCDLTn TCDEna CROTAi CROTAia TCROTn PCi_j PCi_ja TPn_k TPn_ka CDi_j CDi_ja TCn_k TCn_ka PVi_m PVi_ma TVn_m TVn_ma PSi_m PSi_ma TSn_m TSn_ma MACOSX enum { k1MonochromePixelFormat = 0x00000001, /* 1 bit indexed*/ k2IndexedPixelFormat = 0x00000002, /* 2 bit indexed*/ k4IndexedPixelFormat = 0x00000004, /* 4 bit indexed*/ k8IndexedPixelFormat = 0x00000008, /* 8 bit indexed*/ k16BE555PixelFormat = 0x00000010, /* 16 bit BE rgb 555 (Mac)*/ k24RGBPixelFormat = 0x00000018, /* 24 bit rgb */ k32ARGBPixelFormat = 0x00000020, /* 32 bit argb (Mac)*/ k1IndexedGrayPixelFormat = 0x00000021, /* 1 bit indexed gray*/ k2IndexedGrayPixelFormat = 0x00000022, /* 2 bit indexed gray*/ k4IndexedGrayPixelFormat = 0x00000024, /* 4 bit indexed gray*/ k8IndexedGrayPixelFormat = 0x00000028 /* 8 bit indexed gray*/ }; enum { k16LE555PixelFormat = 'L555', /* 16 bit LE rgb 555 (PC)*/ k16LE5551PixelFormat = '5551', /* 16 bit LE rgb 5551*/ k16BE565PixelFormat = 'B565', /* 16 bit BE rgb 565*/ k16LE565PixelFormat = 'L565', /* 16 bit LE rgb 565*/ k24BGRPixelFormat = '24BG', /* 24 bit bgr */ k32BGRAPixelFormat = 'BGRA', /* 32 bit bgra (Matrox)*/ k32ABGRPixelFormat = 'ABGR', /* 32 bit abgr */ k32RGBAPixelFormat = 'RGBA', /* 32 bit rgba */ kYUVSPixelFormat = 'yuvs', /* YUV 4:2:2 byte ordering 16-unsigned = 'YUY2'*/ kYUVUPixelFormat = 'yuvu', /* YUV 4:2:2 byte ordering 16-signed*/ kYVU9PixelFormat = 'YVU9', /* YVU9 Planar 9*/ kYUV411PixelFormat = 'Y411', /* YUV 4:1:1 Interleaved 16*/ kYVYU422PixelFormat = 'YVYU', /* YVYU 4:2:2 byte ordering 16*/ kUYVY422PixelFormat = 'UYVY', /* UYVY 4:2:2 byte ordering 16*/ kYUV211PixelFormat = 'Y211', /* YUV 2:1:1 Packed 8*/ k2vuyPixelFormat = '2vuy' /* UYVY 4:2:2 byte ordering 16*/ }; x11 image ps pagesetup ps print plot ps pagesetup ps print simple text ps print win32/macosx image ps pagesetup ps print native pagesetup print plot ps pagesetup ps print native pagesetup print simple text native pagesetup native print AST David Berry GPLv2 http://starlink.jach.hawaii.edu/starlink/AST BLT George A Howlett OpenSource www.sourceforge.net/projects/blt/files CheckDNS SAO GPLv2 http://hea-www.harvard.edu/RD/ds9/ FunTools SAO LGPLv2.1 https://www.cfa.harvard.edu/~john/funtools/ HCompress Richard White/STScI OpenSource/NASA http://www.stsci.edu/software/hcompress.html HTMLWidget D. Richard Hipp GPLv2 http://www.hwaci.com/drh/ IIS NOAO OpenSource/IRAF PLIO NOAO OpenSource/IRAF RICE Richard White/STScI OpenSource/NASA SAOtk SAO GPLv2 http://hea-www.harvard.edu/RD/ds9/ Signal_Ext Michael Schwartz OpenSource http://www.nyx.net/~mschwart Tcl University of California/Sun Microsystems/Scripts OpenSource http://sourceforge.net/projects/tcl/files/Tcl/ Tcllib Ajuba Solutions and other parties OpenSource http://tcllib.sourceforge.net/ tclxml ANU/CSIRO/Zveno Pty Ltd/Explain OpenSource http://www.explain.com.au/ Tk University of California/Sun Microsystems/Scripts OpenSource http://sourceforge.net/projects/tcl/files/Tk/ TkCon Jeffrey Hobbs OpenSource TKIMG Various Authors OpenSource http://sourceforge.net/projects/tkimg/ ezMPEG Ingo Oppermann GPLv2 tkmpeg SAO GPLv2 http://hea-www.harvard.edu/RD/ds9/ TkTable Jeffrey Hobbs GPLv2 http://sourceforge.net/projects/tktable/ WCSTools SAO LGPLv2.1 http://tdc-www.cfa.harvard.edu/wcstools/ xmlrpc Eric Yeh GPLv2 xpa SAO LGPLv2.1 http://hea-www.harvard.edu/RD/ds9/ zip Info-ZIP OpenSource http://www.info-zip.org/ zlib Jean-loup Gailly and Mark Adler OpenSource http://zlib.net/ zvfs Richard Hipp OpenSource http://www.hwaci.com/drh/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinppctiger������������������������������������������������������������������������0000644�0001750�0001750�00000001217�12127331353�014765� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinppctiger X11INCLUDE=/usr/X11R6/include X11LIB = /usr/X11R6/lib EXTTCLFLAGS=--disable-corefoundation export MACOSX_DEPLOYMENT_TARGET := 10.4 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = echo ZIPFILE = ds9.zip ASTFLAGS = star_cv_cnf_trail_type=int ac_cv_header_execinfo_h=no JOBS = 4 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.source��������������������������������������������������������������������������������0000644�0001750�0001750�00000000000�10720664337�013240� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/���������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�011635� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/�����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�012412� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/how.html���������������������������������������������������������������������������0000644�0001750�0001750�00000020363�11763212355�014120� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Color</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> How it Works</h3> <blockquote> <p><b>Table of Contents</b></p> <a href="#How">How DS9 Renders an Image</a><br> <a href="#Scales">Scales</a><br> <a href="#Smoothing">Smoothing</a><br> <a href="#Contours">Contours</a><br> <a href="#LargeFiles">Large Files</a><br> <p><b><a name="How"></a>How DS9 renders an image</b></p> <p>Here is a short description on how DS9 decides to paint a pixel a color on the the screen, give an data value... you need a color scale, a contrast/bias pair for the colorscale, clip values for the data, a scale distribution, and finally, the value of the pixel in question.</p> <blockquote> <p>Step 1. Select a color scale. A color scale is defined as a number of colors (RGB triplets). The number of RGB triplets can vary from just a few to over 200. DS9 contains a number of predefined color scales (Gray, A, B, I8, ...) or the user may load his own color scale.</p> <p>Step 2. Apply a contrast/bias pair. This step takes the result of step 1 and creates a new array with the contrast/bias applied. The length of the new array will between 200 (for pseudocolor) and 4096 (for truecolor).</p> <p>Step 3. Calculate the data clip values (low/high data values). The min/max data values may be used or an algorithm may be used to determine the clip data values.</p> <p>Step 4. Apply the scale distribution. This involves taking the result of step 2, and creating yet another array, this time of size 16384, redistributing the colors, based on the scale algorithm selected (see <a href="Scales">Scales</a>).</p> <p>Step 5. Based on your data clip values, and the value of the pixel you have, index into the result of step 4, and you have an index into lookup table (for pseudocolor) and an RGB pair (for truecolor and postscript).</p> </blockquote> <p><b><a name="Scales"></a>Scales</b></p> <p>The <tt>log</tt> function is defined as the following:</p> <blockquote> <p><b><img src="img/log.png" alt="log equation" width="78" height="32"></b></p> </blockquote> <p>as <i>x</i> goes from 0 to 1. The user may specify an exponent <i>a</i> to change the distribution of colors within the colorbar. The default value of <i>a</i> is 1000. Typically, optical images respond well at 1000, IR images as low as 100, and high energy bin tables up to 10000. A value of 10000 closely matches the <b><tt>log</tt></b> function of SAOImage as defined as the following:</p> <blockquote> <p><b><img src="img/saolog.png" alt="SAOImage log equation" width="65" height="34"></b></p> </blockquote> <p>The <tt>pow</tt> function is defined as the following:</p> <blockquote> <p><b><img src="img/pow.png" alt="pow equation" width="51" height="30"></b></p> </blockquote> <p>as <i>x</i> goes from 0 to 1. The user may specify an exponent <i>a</i> to change the distribution of colors within the colorbar. The default value of <i>a</i> is 1000.</p> <p>The <tt>sqrt</tt> scale function is defined as the following:</p> <blockquote><img src="img/sqrt.png" alt="sqrt equation" width="42" height="21"><br> </blockquote> <p>as <i>x</i> goes from 0 to 1. </p> <p>The <tt>square</tt> scale function is defined as the following:</p> <blockquote><img src="img/square.png" alt="square equation" width="35" height="21"><br> </blockquote> <p>as <i>x</i> goes from 0 to 1.<br> </p> <p>The <tt>asinh</tt> scale function is defined as the following:</p> <blockquote><img alt="asinh" src="img/asinh.png" width="80" height="29"><br> </blockquote> <p>as <i>x</i> goes from 0 to 1. </p> <p>The <tt>sinh</tt> scale function is defined as the following:</p> <blockquote><img alt="sinh" src="img/sinh.png" width="69" height="29"><br> </blockquote> <p>as <i>x</i> goes from 0 to 1. </p> <p>The <tt>histogram equalization</tt> scale function distributes colors based on the frequency of each data value.</p> <p><b><a name="Smoothing"></a>Smoothing</b></p> <p>The user may select one of three types of smoothing kernels. The parameter, <i>r</i> or <tt>kernel radius</tt>, is defined as the following:</p> <blockquote> Boxcar function, where the width = 2<i>r</i>+1<br> Tophat function, where the radius = <i>r</i> and the diameter of kernel is 2<i>r</i>+1<br> Gaussian function, defined as: <blockquote><img src="img/gauss.png" alt="Gaussian Equation" width="173" height="38"><br> </blockquote> where the mean = 0 and sigma =<i> r</i>/2, and the diameter of kernel is 2<i>r</i>+1 </blockquote> <p><b><a name="Contours"></a>Contours</b></p> <p>The contour algorithm is from an unknown author and originally came from FV. The difference between the two modes are:<tt><br> </tt></p> <blockquote><tt>block</tt> : the image is blocked down before the contour is generated <br> <tt>smooth</tt> : the image is smoothed via a Gaussian kernel before the contour is generated. </blockquote> <p><tt>block</tt> mode is faster as the smoothing parameter increases. Inversely, <tt>smooth</tt> mode is much slower as the smoothing parameter increases.</p> <p><b><a name="LargeFiles"></a>Large Files</b></p> There are several factors that determine if DS9 will be able to load a large file.<br> <p>32 bit OS vs 64 bit OS : to address very large files, you may need to use an 64 bit OS with a 64bit version of DS9. 32bit apps can address up to 4Gb of address space. However, depending on the OS, this limit may be less. Linux for example, the limit appears to be ~3GB (the OS and shared libs eat up a lot of address space). Under 64bit Solaris, 32bit ds9 has a full 4Gb of space. MacOSX appears to have a limit ~3Gb. Under windows, ~2Gb.</p> <p>Large File Support: is the ability to sequence thru files larger than 4Gb. DS9 is compiled with LFS.</p> <p>File system: the OS file system must be able to support files larger than 4Gb. Most recent file systems fully support 4GB&gt;.</p> <p>Memory Management: There are a number of memory management techniques supported in DS9 that will greatly affect the ability and speed of loading large files:</p> <blockquote> <tt>$ ds9 foo.fits # uses mmap</tt><br> <tt>$ cat foo.fits | ds9 - # allocates memory</tt> <br> <tt>$ xpaset -p ds9 file foo.fits # uses mmap</tt> <br> <tt>$ xpaset -p ds9 fits foo.fits # allocates memory</tt><br> </blockquote> <p>Memory Map (<tt>mmap</tt>) is very fast, limit is memory address space (see above). Allocate is very slow, limit is amount of physical memory + swap partition.</p> <p>Scanning Data: DS9 needs to determine the min and max data values to correctly display your image. For large files, this can take time. You have several options available under the <tt>Scale</tt> menu:</p> <blockquote>Scan Data - reads all data<br> Sample Data - samples every x values (much faster)<br> Use FITS keyword DATAMIN/MAX or IRAFMIN/MAX - great if in the header, bad because they are always wrong.<br> </blockquote> <p>The best thing to do is to use sample data, and set the data sample between 10 and 100.</p> </blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/vo.html����������������������������������������������������������������������������0000644�0001750�0001750�00000006320�11426327731�013745� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Virtual Observatory</title> </head> <body alink="#ff0000" bgcolor="#ffffff" vlink="#551a8b" text="#000000" link="#0000ff"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Virtual Observatory Reference</h3> <blockquote> <p><b>Summary</b></p> <p>Use the Web proxy connection if your firewall does not allow your computer to connect directly to external computers. In this case, you also must use DS9's internal browser.</p> <p><b>Details</b></p> <p>When you click on one of the Virtual Observatory servers in the VO list, DS9 will attempt to connect to that server and (if the internal Web display is enabled) display its Web page. The square box to the left of the server name turns yellow while the connection is being established and then green to signal success. </p> <p>A direct connection is fast and flexible. Among other things, it allows you to perform analysis on your own local data (the VO server will retrieve the image from DS9) and also allows you to use an external browser to load images. </p> <p>Some system managers configure their firewall explicitly to prevent computers in their care from making a direct connection to an external host. Instead, they only allow external access through a Web proxy<br> server (such as SOCKS). If you are using a computer behind a restricted firewall of this sort, then DS9 will not be able to connect directly to a VO server. The yellow box will not turn green and eventually DS9 will display an error message. </p> <p>In this case, you can choose to have DS9 communicate with the VO servers through your Web proxy server. DS9 will use your proxy to send its commands and retrieve its data and analysis results, rather than doing this directly. Note that the following restrictions apply:<br> </p> <blockquote> <i>The transfer of data is slower.<br> You must use the internal Web browser for loading images, etc.<br> You cannot perform analysis on local data.<br> There is a (large but finite) restriction on the number of annuli, and number of polygon points you can specify in a region, as well as the total number of regions allowed.</i><br> </blockquote> <p>If your computer and firewall have been configured to require use of a Web proxy server, you will have to tell DS9 about this server. Click the <b>Configure Web Proxy</b> button and type the relevant information into the boxes. (Your systems administrator will be able to tell you the details.) At this point, you should be able to connect to a VO server successfully. Please let us know if you have problems! </p> <blockquote> <p> <i>A final note: you may, of course, choose to use the Web proxy even if your computer and firewall are configured to allow direct connections. In this case, there is no need to configure the proxy server.<br> </i></p> </blockquote> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/print.html�������������������������������������������������������������������������0000644�0001750�0001750�00000004120�11426312317�014443� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Printing</title> </head> <body alink="#ff0000" bgcolor="#ffffff" vlink="#551a8b" text="#000000" link="#0000ee"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Printing</h3> <blockquote> <p>DS9 provides strong Postscript printing support. This is not a screen capture method, but a full level 1 and level 2 postscript driver. The postscript images generated are detailed and accurate as possible, given the resolution of the data, and the printing resolution. </p> <p><b> Postscript Level</b></p> <blockquote> <p> Level 1-- The postscript generated consist of a color lookup table and image data, encoded in <tt>ASCIIHEX</tt>. All line graphics and text are postscript elements.</p> <p> Level 2-- The postscript generated consist of a color lookup table and image data, compressed with RLE, and encoded in <tt>ASCIIHEX85. </tt>All line graphics and text are postscript elements.</p> </blockquote> <p><b> Postscript Color Model</b></p> <p>DS9 supports three color models for level 2 postscript. All three color models generate approximately the same size files. </p> <blockquote><tt> RGB<br> CMYK<br> Grayscale<br> </tt></blockquote> <p><b> Resolution</b></p> <p>Most printers dither to achieve various levels of gray or color. So a 300 dpi printer's affective resolution may only be 53 dpi after dithering. This is fine for analysis and proofs. On the other hand, when generating images for publication, color separation is used to achieve the full resolution of the printer . A 150 dpi CMYK image will generate four 150 dpi images (one for each color). In general, select the lowest resolution possible,&nbsp; as postscript file size grows by the square of the increase.</p> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/gui.html���������������������������������������������������������������������������0000644�0001750�0001750�00000006655�11763203427�014117� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Graphical User Interface</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ff" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" width="100" height="98"> The Graphical User Interface</h3> <blockquote> <p>DS9's GUI as been designed and implemented for ease of use. It is composed of a menu bar, information panel, panner, magnifier, button control panel, display frames, horizontal and vertical graphs, and a colorbar. The user may reconfigure the display by showing or hiding one or more of the elements. See <a href="prefs.html">Preferences</a> for more details. </p> <p><b> Menu bar</b></p> <a href="mfile.html">File</a><br> <a href="medit.html">Edit</a><br> <a href="mview.html">View</a><br> <a href="mframe.html">Frame</a><br> <a href="mbin.html">Bin</a><br> <a href="mzoom.html">Zoom</a><br> <a href="mscale.html">Scale</a><br> <a href="mcolor.html">Color</a><br> <a href="mregion.html">Region</a><br> <a href="mwcs.html">WCS</a><br> <a href="manalysis.html">Analysis</a><br> <a href="mhelp.html">Help</a> <p><b> Tear off Menus</b></p> <p>All DS9 menus can be used as a floating tool palette. To 'tear off' a menu, select the dashed line which is the first item of each menu. At this point, the menu will become its own window, which now can be managed by the user. Mblockquotetiple copies of the same menu can be created. </p> <p><b> Information Panel</b></p> <p>The Information panel displays information about the current data values. The information displayed is configurable via the preferences. </p> <p><b> Panner</b></p> <p>The Panner allows the user to view the entire frame, along with the current viewing bounding box, image cursor, and wcs cursor. To pan the current frame, click and drag the viewing bounding box. </p> <p><b> Magnifier</b></p> <p>The Magnifier displays a magnified view of the current mouse cursor location. The Magnifier cursor outlines the size and orientation of one pixel, given the current frame zoom and orientation. </p> <p><b> Button Control Panel</b></p> <p>The Button Control panel provides duplicate menu functionality for ease of use. </p> <p><b> Frames</b></p> <p>FITS images are displayed in Frames. Frames may be viewed one at a time, or all at once in Tile mode. Only one frame is the Current Frame, as indicated by the Blue Border, while in Tile mode. Most functions act only on the Current Frame. </p> <p><b> Graphs</b></p> <p>Horizontal and Vertical graphs are available to display a cut through the current frame data. While the mouse cursor is in a graph, the information panel reflects the current data values. Graphs are not available while in Tile Mode. </p> <p><b> Colorbar</b></p> <p>The Colorbar displays the current colormap and current bias and contrast settings. </p> </blockquote> </body> </html> �����������������������������������������������������������������������������������./saods9/doc/ref/index.html�������������������������������������������������������������������������0000644�0001750�0001750�00000007560�12071072130�014422� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Reference Manual</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Reference Manual</h3> <blockquote> <p>DS9 is&nbsp; the next version of the popular <a href="http://hea-www.harvard.edu/RD/saotng/">SAOtng</a> display program. It is a Tk/Tcl application which utilizes the SAOtk widget set. It also incorporates the new X Public Access (<a href="http://hea-www.harvard.edu/RD/xpa/">XPA</a>) mechanism to allow external processes to access and control its data, GUI functions, and algorithms. DS9&nbsp; supports the direct display of FITS images and binary tables, multiple frame buffers, region cursor manipulation, many scale algorithms and colormaps, and easy communication with external analysis tasks. It is highly configurable and extensible to meet the evolving needs of the astronomical community. </p> <p>DS9 supports advanced features such as multiple frame buffers, mosaic images, tiling, blinking, geometric markers, colormap manipulation, scaling, arbitrary zoom, rotation, pan, and a variety of coordinate systems (including Image, Physical, Detector, and WCS). DS9 also supports FTP and HTTP access. The GUI for DS9 is user configurable.</p> <table align="center" border="0" cellpadding="4" cellspacing="2" height="25%" width="75%"> <tbody> <tr> <td align="center" valign="middle"> <a href="how.html">How It Works</a></td> <td align="center" valign="top"><a href="backup.html">Backup and Restore</a></td> <td align="center" valign="middle"> <a href="file.html">File Formats</a></td> </tr> <tr> <td align="center" valign="middle"> <a href="keyboard.html">Mouse and Keyboard</a> </td> <td align="center" valign="top"><a href="grid.html">Coordinate Grids</a></td> <td align="center" valign="middle"> <a href="prefs.html">Preferences</a></td> </tr> <tr> <td align="center" valign="middle"> <a href="command.html">Command Line Options</a> </td> <td align="center" valign="top"><a href="catalog.html">Catalogs</a></td> <td align="center" valign="middle"> <a href="3d.html">3-D Frames</a></td> </tr> <tr> <td align="center" valign="middle"> <a href="xpa.html">XPA Access Points</a> </td> <td align="center" valign="top"><a href="colorbar.html">Colorbar</a><br> </td> <td align="center" valign="middle"> <a href="contour.html">Contours</a></td> </tr> <tr> <td align="center" valign="top"> <a href="samp.html">SAMP<br> </a> </td> <td align="center" valign="top"><a href="print.html">Printing</a></td> <td align="center" valign="top"> <a href="iraf.html">IRAF Support</a></td> </tr> <tr> <td align="center" valign="middle"> <a href="region.html">Regions</a> </td> <td align="center" valign="top"><a href="analysis.html">Analysis</a></td> <td align="center" valign="middle"> <a href="bin.html">Binning</a><br> </td> </tr> </tbody> </table> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/samp.html��������������������������������������������������������������������������0000644�0001750�0001750�00000362553�12131601437�014266� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>SAMP</title> </head> <body alink="#ff0000" link="#0000ff" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAMP</h3> <blockquote> <p>SAMP is a messaging protocol that enables astronomy software tools to interoperate and communicate. Broadly speaking, SAMP is an abstract framework for loosely-coupled, asynchronous, RPC-like and/or event-based communication, based on a central service providing multi-directional publish/subscribe message brokering. The message semantics are extensible and use structured but weakly-typed data. For more information on SAMP, please click <a href="http://www.ivoa.net/Documents/latest/SAMP.html">here</a>.</p> <p>The samp implementation for DS9 is based on the <a href="xpa.html">XPA</a> model with 2 private calls:</p> <tt> ds9.get<br> &nbsp;&nbsp;&nbsp; Arguments<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cmd (string) required<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; url (string) optional<br> &nbsp;&nbsp;&nbsp; Returned value<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; OK (samp.result map)<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; value (string) optional<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; url (string) optional<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ERROR (samp.error map)<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samp.errortxt (string)<br> &nbsp;<br> ds9.set<br> &nbsp;&nbsp;&nbsp; Arguments<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cmd (string) required<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; url (string) optional<br> &nbsp;&nbsp;&nbsp; Returned value<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; OK<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ERROR (samp.error map)<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; samp.errortxt (string)<br> </tt> <p><tt>ds9.set</tt> maybe called via notification, call and call/wait. <tt>ds9.get</tt> can only be called via call and call/wait. Most of the <tt>ds9.get</tt> calls return a value string, but a few will return a url instead.</p> <tt> <a href="#2mass">2mass</a><br> <a href="3d">3d</a><br> <a href="#about">about</a><br> <a href="#analysis">analysis</a><br> <a href="#array">array</a><br> <a href="#background">background</a><br> <a href="#backup">backup</a><br> <a href="#bin">bin</a><br> <a href="#blink">blink</a><br> <a href="#catalog">catalog</a><br> <a href="#cd">cd</a><br> <a href="#cmap">cmap</a><br> <a href="#colorbar">colorbar</a><br> <a href="#console">console</a><br> <a href="#contour">contour</a><br> <a href="crop">crop</a><br> <a href="#crosshair">crosshair</a><br> <a href="#cube">cube</a><br> <a href="#cursor">cursor</a><br> <a href="#data">data</a><br> <a href="#dsssao">dsssao</a><br> <a href="#dsseso">dsseso</a><br> <a href="#dssstsci">dssstsci</a><br> <a href="#exit">exit</a><br> <a href="#export">export</a><br> <a href="#first">first</a><br> <a href="#fits">fits</a><br> <a href="#frame">frame</a><br> <a href="#gif">gif</a><br> <a href="#grid">grid</a><br> <a href="#header">header</a><br> <a href="#height">height</a><br> <a href="#iconify">iconify</a><br> <a href="#iis">iis</a><br> <a href="#image">image</a><br> <a href="#imexam">imexam</a><br> <a href="#jpeg">jpeg</a><br> <a href="#lock">lock</a><br> <a href="#lower">lower</a><br> <a href="#magnifier">magnifier</a><br> <a href="#mask">mask</a><br> <a href="#match">match</a><br> <a href="#mecube">mecube</a><br> <a href="#minmax">minmax</a><br> <a href="#mode">mode</a><br> <a href="#mosaic">mosaic</a><br> <a href="#mosaicimage">mosaicimage</a><br> <a href="#movie">movie</a><br> <a href="#multiframe">multiframe</a><br> <a href="#nameserver">nameserver</a><br> <a href="#nan">nan</a><br> <a href="#nrrd">nrrd</a><br> <a href="#nvss">nvss</a><br> <a href="#orient">orient</a><br> <a href="#pagesetup">pagesetup</a><br> <a href="#pan">pan</a><br> <a href="#pixeltable">pixeltable</a><br> <a href="#plot">plot</a><br> <a href="#png">png</a><br> <a href="#prefs">prefs</a><br> <a href="#preserve">preserve</a><br> <a href="#psprint">psprint</a><br> <a href="#print">print</a><br> <a href="#exit">quit</a><br> <a href="#raise">raise</a><br> <a href="#regions">regions</a><br> <a href="#restore">restore</a><br> <a href="#rgb">rgb</a><br> <a href="#rgbarray">rgbarray</a><br> <a href="#rgbcube">rgbcube</a><br> <a href="#rgbimage">rgbimage</a><br> <a href="#rotate">rotate</a><br> <a href="#save">save</a><br> <a href="#saveimage">saveimage</a><br> <a href="xpa.html#scale">scale</a><br> <a href="#shm">shm</a><br> <a href="#single">single</a><br> <a href="#skyview">skyview</a><br> <a href="#sleep">sleep</a><br> <a href="#smooth">smooth</a><br> <a href="#source">source</a><br> <a href="#theme">theme</a><br> <a href="#threads">threads</a><br> <a href="#tcl">tcl</a><br> <a href="#tiff">tiff</a><br> <a href="#tile">tile</a><br> <a href="#update">update</a><br> <a href="#url">url</a><br> <a href="#version">version</a><br> <a href="#view">view</a><br> <a href="#vo">vo</a><br> <a href="#wcs">wcs</a><br> <a href="#web">web</a><br> <a href="#width">width</a><br> <a href="#zscale">zscale</a><br> <a href="#zoom">zoom</a><br> </tt> <p><b> <a name="2mass"></a>2mass</b></p> <p>Support for 2MASS Digital Sky Survey.</p> <tt> Syntax: <br> 2mass []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp;&nbsp; [survey j|h|k]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> 2mass name <br> 2mass coord <br> 2mass size<br> 2mass save<br> 2mass frame<br> 2mass survey <br> ds9.set(string cmd)<br> 2mass<br> 2mass m31 <br> 2mass name m31 <br> 2mass coord 00:42:44.404 +41:16:08.78 sexagesimal<br> 2mass size 60 60 arcmin<br> 2mass save yes<br> 2mass frame current<br> 2mass update frame<br> 2mass survey j<br> 2mass open<br> 2mass close<br> </tt> <p><b> <a name="3d"></a>3d</b></p> <p>Support for 3D frame.</p> <tt> Syntax: <br> </tt><tt>3d []<br> &nbsp;&nbsp; [vp &lt;az&gt; &lt;el&gt;]<br> &nbsp;&nbsp; [az &lt;az&gt;]<br> &nbsp;&nbsp; [el &lt;el&gt;]<br> &nbsp;&nbsp; [scale &lt;scale&gt;]<br> &nbsp;&nbsp; [method mip|aip]<br> </tt><tt>&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp; [border color &lt;color&gt;]<br> </tt><tt></tt><tt>&nbsp;&nbsp; [highlite yes|no]<br> &nbsp;&nbsp; [hightlite color &lt;color&gt;]<br> </tt><tt>&nbsp;&nbsp; [open|close]</tt><tt><br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> </tt><tt>3d vp<br> 3d az<br> 3d el<br> 3d scale<br> 3d method<br> </tt><tt>3d border<br> 3d border color<br> </tt> <tt> </tt><tt>3d highlite<br> 3d highlite color<br> </tt> <tt> ds9.set(string cmd)<br> </tt><tt>3d # create new 3D frame<br> 3d vp 45 30<br> 3d az 45<br> 3d el 30<br> 3d scale 10<br> 3d method mip<br> </tt><tt>3d border yes<br> 3d border color red<br> </tt><tt></tt><tt>3d highlite yes<br> 3d highlite color red<br> 3d open<br> 3d close</tt><br> <p><b><a name="about"></a>about</b></p> <p>Get DS9 credits.</p> <tt> Syntax: <br> about <br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> about<br> </tt> <p><b> <a name="align"></a>align</b></p> <p>Controls the World Coordinate System alignment for the current frame.</p> <tt> Syntax: <br> align []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd) <br> </tt>align<br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>align yes</tt><br> <p><b> <a name="analysis"></a>analysis</b></p> <p>Control external analysis tasks. Tasks are numbered as they are loaded, starting with 0. Can also be used to display a message and display text in the text dialog window. </p> <tt> Syntax: <br> analysis [&lt;task number&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [task &lt;task number&gt;|&lt;task name&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear][load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [message ok|okcancel|yesno &lt;message&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [entry &lt;message&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [text]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> analysis<br> analysis task<br> analysis entry Please enter something<br> analysis entry okcancel Please enter something<br> ds9.set(string cmd)<br> analysis 0 # invoke first analysis task<br> analysis task 0<br> analysis task foobar<br> analysis task {foo bar}<br> analysis my.ans<br> analysis load my.ans <br> analysis clear <br> analysis clear load my.ans<br> analysis message ok {This is a message}<br> analysis text {this is text}<br> ds9.set(string cmd, string url)<br> analysis load <br> analysis text</tt><b><br> </b> <p><b> <a name="array"></a>array</b></p> <p>Load raw data array into current frame.<br> </p> <tt> Syntax:<br> array [native|big|little]<br> array [new|mask] [[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],zdim=&lt;z&gt;,bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string url = ds9.get(string cmd)<br> </tt>array<br> array little<br> </tt><tt><tt>ds9.set(string command, string url)<br> </tt>array foo.arr[dim=512,bitpix=-32,endian=little]<br> array new foo.arr[dim=512,bitpix=</tt><tt>-32,endian=little]</tt><br> <tt><tt>array mask foo.arr[dim=512,bitpix=</tt></tt><tt>-32,endian=little]</tt><tt><br> </tt> <p><b> <a name="background"></a>bg<br> background</b></p> <p>Set image background color. </p> <tt> Syntax: <br> bg &lt;color&gt;<br> &nbsp;<br> Example:<br> </tt><tt>string url = ds9.get(string cmd)</tt><tt><br> bg<br> </tt><tt>ds9.set(string cmd)<br> </tt><tt>bg red</tt><tt><br> <tt>bg red</tt></tt><br> <p><b> <a name="backup"></a>backup</b></p> <p>Create a backup save set. </p> <tt> Syntax: <br> backup &lt;filename&gt;<br> &nbsp;<br> Example:<br> </tt><tt>ds9.set(string cmd)<br> </tt><tt>backup ds9.bck</tt><br> <p><b> <a name="bin"></a>bin</b></p> <p>Controls binning factor, binning buffer size, and&nbsp; binning function for binning FITS bin tables. The access point blocking is provided for backward compatibility. </p> <tt> Syntax: <br> bin [about &lt;x&gt; &lt;y&gt;]<br> &nbsp;&nbsp;&nbsp; [about center]<br> &nbsp;&nbsp;&nbsp; [buffersize &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp; [cols &lt;x&gt; &lt;y&gt;]<br> &nbsp;&nbsp;&nbsp; [colsz &lt;x&gt; &lt;y&gt; &lt;z&gt;]<br> &nbsp;&nbsp;&nbsp; [factor &lt;value&gt; [&lt;vector&gt;]]<br> &nbsp;&nbsp;&nbsp; [depth &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp; [filter &lt;string&gt;] <br> &nbsp;&nbsp;&nbsp; [function average|sum] <br> &nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> bin about<br> bin buffersize<br> bin cols<br> bin factor<br> bin depth<br> bin filter<br> bin function<br> bin smooth<br> bin smooth function<br> bin smooth radius<br> bin lock<br> ds9.set(string cmd)<br> bin about 4096 4096<br> bin about center<br> bin buffersize 512<br> bin cols detx dety<br> bin colsz detx dety time<br> bin factor 4<br> bin factor 4 2<br> bin depth 10<br> bin filter {pha &gt; 5}<br> bin filter {}<br> bin function sum<br> bin to fit<br> bin match<br> bin lock yes<br> bin open<br> bin close<br> </tt> <p><b> <a name="blink"></a>blink</b></p> <p>Blink mode parameters. Interval is in seconds. <br> </p> <tt> Syntax: <br> blink []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> blink<br> blink interval<br> ds9.set(string cmd)<br> blink<br> blink yes<br> blink interval 1<br> </tt> <p><b> <a name="catalog"></a>catalog<br> cat<br> </b></p> <p>Support for catalogs. The first three commands will create a new catalog search. All other commands operated on the last search created, unless indicated otherwise.</p> <tt> Syntax:<br> </tt><tt>catalog []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ned|simbad|denis|skybot]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ascss|cmc|gsc1|gsc2|gsc3|ac|nomad|ppmx|sao|sdss5|sdss6|</tt><tt>sdss7|sdss8|</tt><tt>tycho|ua2|ub1|ucac2]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [2mass|iras]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [csc|xmm|rosat]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [first|nvss]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [chandralog|cfhtlog|esolog|stlog|xmmlog]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [cds &lt;catalogname&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cds &lt;catalogid&gt;]<br> <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [import sb|tsv &lt;filename&gt;]<br> <br> </tt><tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [allcols]<br> </tt><tt>&nbsp;</tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [allrows]<br> &nbsp;</tt><tt>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [cancel]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [clear]<br> </tt><tt>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [close]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [coordinate &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [crosshair]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [dec &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [edit yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [export sb|tsv &lt;filename&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter &lt;string&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [header]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [hide]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [location &lt;code&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [match &lt;ref&gt; &lt;ref&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match error &lt;value&gt; degrees|arcmin|arcsec]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match function 1and2|1not2|2not1]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match return 1and2|1only|2only]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match unique yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [maxrows &lt;number&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [name &lt;object&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [panto yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [plot &lt;xcol&gt; &lt;ycol&gt; &lt;xerrcol&gt; &lt;yerrcol&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [print]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psky &lt;skyframe&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psystem &lt;coordsys&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [ra &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [retrieve]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp broadcast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp send &lt;application&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [save &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [server cds|sao|cadc|adac|iucaa|bejing|cambridge|ukirt]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [show]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]</tt><br> <tt> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sky &lt;skyframe&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [skyformat &lt;skyformat&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sort &lt;col&gt; incr|decr]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] condition|shape|color|text|font|fontsize|fontweight|fontslant &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] text|size|size2|units|angle &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol shape {circle point}|{box point}|{diamond point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {cross point}|{x point}|{arrow point}|{boxcircle point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; circle|ellipse|box|text]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol add| [#] remove]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol save|load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [system &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [update]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [x &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [y &lt;col&gt;]</tt><br> <tt> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> catalog<br> catalog header<br> <br> ds9.set(string cmd)<br> </tt><tt>catalog<br> catalog 2mass<br> catalog cds 2mass<br> catalog cds </tt><tt>{I/252}</tt><br> <tt> <br> </tt><tt>catalog load foo.xml<br> catalog import tsv foo.tsv<br> <br> </tt><tt>catalog allrows<br> catalog allcols<br> </tt><tt>catalog cancel<br> </tt><tt>catalog clear<br> </tt><tt>catalog close<br> </tt><tt>catalog coordinate 202.48 47.21 fk5<br> </tt><tt>catalog crosshair<br> </tt><tt>catalog dec DEC<br> </tt><tt>catalog edit yes<br> </tt><tt>catalog export tsv bar.tsv<br> </tt><tt>catalog filter {$Jmag&gt;10}<br> catalog filter load foo.flt<br> catalog header<br> </tt><tt>catalog hide<br> </tt><tt>catalog location 500</tt><br> <tt>catalog match error 2 arcsec<br> catalog match function 1and2<br> catalog match unique no<br> catalog match return 1only<br> catalog match 2mass csc<br> </tt><tt>catalog maxrows 2000<br> </tt><tt>catalog name m51<br> catalog panto no<br> </tt><tt>catalog plot </tt><tt>{$Jmag} {$Hmag} {$e_Jmag} {$e_Hmag}</tt><tt><br> </tt><tt>catalog print</tt><br> <tt>catalog psky fk5</tt><br> <tt>catalog psystem wcs</tt><br> <tt>catalog ra RA</tt><br> <tt>catalog retrieve<br> </tt><tt> catalog samp broadcast<br> catalog samp send aladin<br> catalog save foo.xml<br> </tt><tt>catalog server sao<br> </tt><tt>catalog show</tt><br> <tt> catalog size 1 1 degrees</tt><br> <tt>catalog symbol condition </tt><tt>{$Jmag&gt;15}</tt><br> <tt> catalog symbol 2 shape </tt><tt>{boxcircle point}</tt><br> <tt> catalog symbol color red<br> catalog symbol font times<br> </tt><tt>catalog symbol fontsize 14<br> </tt><tt>catalog symbol fontweight bold<br> </tt><tt>catalog symbol fontslant italic<br> </tt><tt>catalog symbol add<br> catalog symbol 2 remove<br> catalog symbol load foo.sym<br> catalog symbol save bar.sym</tt><tt><br> catalog sky fk5<br> catalog skyformat degrees<br> </tt><tt>catalog sort {Jmag} incr<br> </tt><tt>catalog system wcs</tt><tt><br> </tt><tt>catalog update<br> </tt><tt>catalog x RA<br> catalog y DEC</tt><br> <p><b><a name="cd"></a>cd</b></p> <p>Sets/Returns the current working directory. </p> <tt> Syntax: <br> cd [&lt;directory&gt;] <br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> cd<br> ds9.set(string cmd)<br> cd /home/mrbill<br> </tt> <p><b> <a name="cmap"></a>cmap</b></p> <p>Controls the colormap for the current frame. The colormap name is not case sensitive. A valid contrast value is&nbsp; from 0 to 10 and bias value from 0 to 1. </p> <tt> Syntax: <br> cmap [&lt;colormap&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [file]<br> &nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [invert yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [value &lt;constrast&gt; &lt;bias&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [tag [load|save] &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [tag delete]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> cmap <br> cmap file <br> cmap invert <br> cmap value <br> </tt><tt>cmap lock</tt><br> <tt> ds9.set(string cmd)<br> cmap Heat <br> cmap load foo.sao <br> cmap save bar.sao<br> cmap invert yes <br> cmap value 5 .5<br> </tt><tt>cmap tag load foo.tag<br> cmap tag save foo.tag<br> cmap tag delete</tt><br> <tt>cmap match<br> cmap lock yes</tt><br> <tt> cmap open<br> cmap close<br> </tt> <p><b><a name="colorbar"></a>colorbar</b></p> <p>Controls colorbar parameters.</p> <tt> Syntax: <br> colorbar []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [horizontal|vertical]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [orientation horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [space value|distance] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [size]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ticks]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> colorbar<br> colorbar orientation<br> colorbar numerics<br> colorbar space<br> colorbar font<br> colorbar fontsize<br> colorbar fontweight<br> colorbar fontslant<br> colorbar size<br> colorbar ticks<br> ds9.set(string cmd)<br> colorbar yes<br> colorbar vertical<br> colorbar orientation vertical<br> colorbar numerics yes<br> colorbar space value<br> colorbar font times<br> colorbar fontsize 14<br> colorbar fontwieght bold<br> colorbar fontslant italic<br> colorbar size 20<br> colorbar ticks 11<br> </tt> <p><b> <a name="console"></a>console</b></p> <p>Display tcl console window.</p> <tt> Syntax: <br> -console<br> &nbsp;<br> Example:<br> ds9.set(string cmd)<br> console<br> </tt> <p><b> <a name="contour"></a>contour</b></p> <p>Controls contours in the current frame. </p> <tt> Syntax: <br> contour []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;coordsys&gt; [&lt;skyframe&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [generate]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [convert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [loadlevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [savelevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [paste &lt;coordsys&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [dash yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [smooth &lt;smooth&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [method block|smooth]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [nlevels &lt;number of levels&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale linear|log|pow|squared|sqrt|asinh|sinh|histequ]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ]scale log exp &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [limits &lt;min&gt; &lt;max&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [levels &lt;value value value...&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> contour<br> contour color<br> contour width<br> contour dash<br> contour smooth<br> contour method<br> contour nlevels<br> contour scale<br> contour log exp<br> contour mode<br> contour limits<br> contour levels<br> string url = ds9.get(string cmd)<br> contour wcs fk5<br> ds9.set(string cmd)<br> contour<br> contour yes<br> contour clear<br> contour generate<br> contour load ds9.con wcs fk5 yellow 2 no # solid line<br> contour load ds9.con wcs fk5 red 2 yes # dashed line<br> contour save ds9.con wcs fk5<br> contour convert<br> contour loadlevels ds9.lev<br> contour savelevels ds9.lev<br> contour copy<br> contour paste wcs red 2 no<br> contour color yellow<br> contour width 2<br> contour dash yes<br> contour smooth 5<br> contour method smooth<br> contour nlevels 10<br> contour scale sqrt<br> contour log exp 1000<br> contour mode zscale<br> contour limits 1 100<br> contour levels "{1 10 100 1000}"<br> contour open<br> contour close<br> </tt> <p><b><a name="crop"></a>crop</b> </p> <p>Set current image display area. </p> <tt> Syntax: <br> crop [&lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt; [&lt;coordsys&gt;][&lt;skyframe&gt;][&lt;skyformat&gt;][degrees|arcmin|arcsec]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]</tt><tt><br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> </tt><tt>crop # get crop in physical coords <br> </tt><tt>crop wcs galactic sexagesimal arcsec<br> crop lock<br> </tt><tt>ds9.set(string cmd)</tt><br> <tt> crop 40 30 10 20 # set crop in physical coords<br> crop +104:51:06.915 +68:33:40.761&nbsp; 28.144405 22.000204 wcs galactic arcsec<br> crop match wcs<br> crop lock wcs</tt><br> <p><b> <a name="crosshair"></a>crosshair</b></p> <p>Controls the current position of the crosshair in the current frame. DS9 is placed in crosshair mode when the crosshair is set. </p> <tt> Syntax: <br> crosshair [&lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;]] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> crosshair # get crosshair in physical coords <br> crosshair wcs fk4 sexagesimal # get crosshair in wcs coords <br> crosshair lock<br> ds9.set(string cmd)<br> crosshair 100 100 physical # set crosshair in physical <br> crosshair 345 58.8 wcs fk5 # set crosshair in wcs coords <br> crosshair 23:01:00 +58:52:51 wcs fk5<br> crosshair match wcs<br> crosshair lock wcs<br> </tt> <p><b><a name="cube"></a>cube<br> </b></p> <p>Controls FITS cube. </p> <tt> Syntax: <br> cube [play|stop|next|prev|first|last]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;slice&gt; [&lt;coordsys&gt;][&lt;axis&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;numeric&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [axis &lt;axis&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> cube<br> cube interval<br> cube lock<br> ds9.set(string cmd)<br> cube play<br> cube last<br> cube 3<br> cube 4.5 wcs 3<br> cube interval 2<br> cube axis 3<br> cube match<br> cube lock yes<br> cube open<br> cube close</tt><br> <p><b> <a name="cursor"></a>cursor</b></p> <p>Move mouse pointer or crosshair in image pixels in the current frame. Note, this will move selected Regions also. </p> <tt> Syntax: <br> cursor [&lt;x&gt; &lt;y&gt;] <br> &nbsp;<br> Example:<br> ds9.set(string cmd)<br> cursor 10 10<br> </tt> <p><b><a name="data"></a>data</b></p> <p>Return an array of data values given a lower left corner and a width and height in specified coordinate system. The last argument of yes indicates to strip the coordinates from the output and just list the data values. The default is yes.<br> </p> <tt> Syntax: <br> data [&lt;coordsys&gt; [&lt;skyframe&gt;] &lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt; [yes|no]]<br> &nbsp;<br> Example:<br> string url = ds9.get(string cmd) <br> data image 450 520 3 3 yes<br> data physical 899 1039 6 6 no<br> data fk5 202.47091 47.196811 0.00016516669 0.00016516669 no<br> data wcs fk5 13:29:53.018 +47:11:48.52 0.00016516669 0.00016516669 no</tt><tt><br> </tt> <p><b> <a name="dsssao"></a>dsssao<br> dss<br> </b></p> <p>Support for Digital Sky Survey at SAO. </p> <tt> Syntax:<br> dsssao []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> dsssao name <br> dsssao coord <br> dsssao size<br> dsssao save<br> dsssao frame<br> ds9.set(string cmd)<br> dsssao<br> dsssao m31 <br> dsssao name m31 <br> dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal<br> dsssao size 60 60 arcmin<br> dsssao save yes<br> dsssao frame current<br> dsssao update frame<br> dsssao open<br> dsssao close<br> </tt> <p><b> <a name="dsseso"></a>dsseso</b></p> <p>Support for Digital Sky Survey at ESO. </p> <tt> Syntax:<br> dsseso []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp; &nbsp; &nbsp; [survey DSS1|DSS2-red|DSS2-blue|DSS2-infrared]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> dsseso name <br> dsseso coord <br> dsseso size<br> dsseso save<br> dsseso frame<br> dsseso survey<br> ds9.set(string cmd)<br> dsseso<br> dsseso m31 <br> dsseso name m31 <br> dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal<br> dsseso size 60 60 arcmin<br> dsseso save yes<br> dsseso frame current<br> dsseso update frame<br> dsseso survey DSS2-red <br> dsseso open<br> dsseso close<br> </tt> <p><b> <a name="dssstsci"></a>dssstsci</b></p> <p>Support for Digital Sky Survey at STSCI.</p> <tt> Syntax:<br> dssstsci []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss2ukstu_red|poss2ukstu_ir|poss2ukstu_blue] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss1_blue|poss1_red]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey all|quickv|phase2_gsc2|phase2_gsc1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> dssstsci name <br> dssstsci coord <br> dssstsci size<br> dssstsci save<br> dssstsci frame<br> dssstsci survey<br> ds9.set(string cmd)<br> dssstsci<br> dssstsci m31 <br> dssstsci name m31 <br> dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal<br> dssstsci size 60 60 arcmin<br> dssstsci save yes<br> dssstsci frame current<br> dssstsci update frame<br> dssstsci survey all<br> dssstsci open<br> dssstsci close<br> </tt> <p><b> <a name="exit"></a>exit<br> quit<br> </b></p> <p>Quits DS9. </p> <tt> Syntax: <br> exit<br> quit<br> &nbsp;<br> Example:<br> ds9.set(string cmd)<br> exit</tt><br> <p><b> <a name="export"></a>export<br> </b></p> <p>Export loaded image data of current frame in specified image format. Optional parameters: array endian, nrrd endian, jpeg quality (1-100) and tiff compression method.</p> <tt> Syntax: </tt><tt><br> </tt><tt> export </tt><tt>[array|nrrd|gif|tiff|jpeg|png] </tt><tt>&lt;filename&gt;</tt><tt><br> </tt><tt>export array &lt;filename&gt;</tt><tt> </tt><tt>little</tt><tt><br> </tt><tt>export nrrd &lt;filename&gt; </tt><tt>little</tt><tt><br> </tt><tt> </tt><tt>export jpeg &lt;filename&gt;</tt><tt> [1-100]</tt><tt><br> </tt><tt> </tt><tt>export tiff &lt;filename</tt><tt>&gt;</tt><tt> [none|jpeg|packbits|deflate]</tt><br> <tt> &nbsp;<br> Example: <br> </tt><tt><tt><tt>ds9.set (string cmd)<br> </tt>export array foo.arr little</tt></tt><br> <tt><tt>export nrrd foo.nrrd little</tt></tt><br> <tt><tt><tt><tt>export tiff foo.tiff jpeg</tt></tt></tt><br> export jpeg foo.jpeg 75<br> export png foo.png</tt><tt></tt><tt><br> </tt> <p><b> <a name="first"></a>first</b></p> <p>Support for VLA First Sky Survey. </p> <tt> Syntax:<br> first []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> first name <br> first coord <br> first size<br> first save<br> first frame<br> ds9.set(string cmd)<br> first<br> first m31 <br> first name m31 <br> first coord 00:42:44.404 +41:16:08.78 sexagesimal<br> first size 60 60 arcmin<br> first save yes<br> first frame current<br> first update frame <br> first open<br> first close<br> </tt> <p><b> <a name="fits"></a>fits</b></p> <p>Load a FITS image into the current frame or query the currently loaded image.<br> </p> <tt> Syntax: <br> fits </tt><tt><tt>[new|mask|slice] [&lt;filename&gt;]</tt><tt><br> </tt>&nbsp;&nbsp;&nbsp;&nbsp; [width|height|depth|bitpix|type]<br> &nbsp; &nbsp;&nbsp; [size [wcs|wcsa...wcsz] [fk4|fk5|icrs|galactic|ecliptic] [degrees|arcmin|arcsecs]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[header [&lt;ext&gt;] [keyword &lt;string&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [image|table|slice]</tt><tt><br> &nbsp;<br> Example: </tt><br> <tt><tt>string value = ds9.get(string cmd)</tt><br> fits<br> fits width<br> fits height<br> fits depth<br> fits bitpix</tt><br> <tt>fits type </tt><br> <tt><tt>fits size<br> </tt> fits size wcs fk5 arcmin<br> fits header # primary<br> fits header 2 # hdu 2<br> fits header -2 # hdu 2 with inherit<br> fits header keyword "'BITPIX'"<br> fits header 1 keyword "'BITPIX'"</tt><br> <tt><tt>fits image<br> fits table</tt></tt><tt><br> fits slice<br> ds9.set(string cmd, string url)</tt><tt><tt><br> </tt> fits foo.fits<br> fits new foo.fits<br> fits bar.fits[bin=detx,dety]<br> fits slice foo.fits<br> fits mask foo.fits<br> fits <br> fits new<br> fits -[bin=detx,dety]<br> fits slice<br> fits mask</tt> <p>Syntax: <br> </p> <tt> fits [size|width|height|depth|bitpix]<br> &nbsp; &nbsp;&nbsp; [size [wcs|wcsa...wcsz] [fk4|fk5|icrs|galactic|ecliptic] [degrees|arcmin|arcsecs]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [type]<br> &nbsp;&nbsp;&nbsp; &nbsp;[header [&lt;ext&gt;] [keyword &lt;string&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [image|table|resample] [gz] <br> &nbsp;&nbsp;&nbsp;&nbsp; [new|mask][&lt;options&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new][slice &lt;options&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[new][mecube &lt;options&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new|mask][mosaicimage [iraf|wcs|wcsa...wcsz|wfpc2] &lt;options&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new|mask][mosaic [iraf|wcs|wcsa...wcsz] &lt;options&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new][rgbcube &lt;options&gt;]<br> &nbsp; &nbsp; &nbsp;[new][rgbimage &lt;options&gt;]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> fits size<br> fits width<br> fits height<br> fits depth<br> fits bitpix<br> fits size wcs fk5 arcmin<br> fits type <br> fits header keyword "'BITPIX'"<br> fits header 1 keyword "'BITPIX'"<br> string url = ds9.get(string cmd)<br> fits<br> fits image<br> fits image gz<br> fits table<br> fits table gz<br> fits resample<br> fits resample gz<br> fits header # primary<br> fits header 2 # hdu 2<br> fits header -2 # hdu 2 with inherit<br> ds9.set(string cmd, string url)<br> fits <br> fits [2] <br> fits new [bin=detx,dety]<br> fits slice<br> fits mecube <br> fits mosaicimage iraf<br> fits mosaicimage wcs<br> fits mosaicimage wcsa<br> fits mosaicimage wfpc2<br> fits mosaic iraf<br> fits mosaic wcs<br> fits rgbcube<br> fits rgbimage </tt> <p><b> <a name="frame"></a>frame</b></p> <p>Controls frame functions. Frames may be created, deleted, reset, and centered. While return the current frame number. If you goto a frame that does not exists, it will be created. If the frame is hidden, it will be shown. The 'frameno' option is available for backward compatibility. </p> <tt> Syntax: <br> frame [center [#|all]]<br> &nbsp; &nbsp; &nbsp; [clear [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [new [rgb|3d]]<br> &nbsp; &nbsp; &nbsp; [delete [#|all]] <br> &nbsp; &nbsp; &nbsp; [reset [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [refresh [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [hide [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [show [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move first]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move forward]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move last]<br> &nbsp; &nbsp; &nbsp; [first]<br> &nbsp;&nbsp;&nbsp; &nbsp; [prev]<br> &nbsp; &nbsp; &nbsp; [next]<br> &nbsp; &nbsp; &nbsp; [last]<br> &nbsp; &nbsp; &nbsp; [frameno #]<br> &nbsp;&nbsp;&nbsp; &nbsp; [#]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has [amplifier|datamin|datasec|detector|grid|iis|irafmin|physical|smooth]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has contour [aux]]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has fits [ |bin|cube|mosaic]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has marker [highlite|paste|select|undo]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has wcs [&lt;wcssys&gt;|equatorial &lt;wcssys&gt;|linear &lt;wcssys&gt;]]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> frame # returns the id of the current frame <br> frame frameno # returns the id of the current frame <br> frame all # returns the id of all frames <br> frame active # returns the id of all active frames<br> frame lock<br> frame has amplifier<br> frame has datamin<br> frame has datasec<br> frame has detector<br> frame has grid<br> frame has iis<br> frame has irafmin<br> frame has physical<br> frame has smooth<br> frame has contour<br> frame has contour aux<br> frame has fits<br> frame has fits bin<br> frame has fits cube<br> frame has fits mosaic<br> frame has marker highlite<br> frame has marker paste<br> frame has marker select<br> frame has marker undo<br> frame has system physical<br> frame has wcs wcsa<br> frame has wcs equatorial wcsa<br> frame has wcs linear wcsa<br> ds9.set(string cmd)<br> frame center # center current frame<br> frame center 1 # center 'Frame1' <br> frame center all # center all frames <br> frame clear # clear current frame<br> frame new # create new frame <br> frame new rgb # create new rgb frame<br> frame delete # delete current frame <br> frame reset # reset current frame <br> frame refresh # refresh current frame <br> frame hide # hide current frame <br> frame show 1 # show frame 'Frame1'<br> frame move first # move frame to first in order<br> frame move back # move frame back in order<br> frame move forward # move frame forward in order<br> frame move last # move frame to last in order<br> frame first # goto first frame <br> frame prev # goto prev frame <br> frame next # goto next frame<br> frame last # goto last frame<br> frame frameno 4 # goto frame 'Frame4', create if needed<br> frame 3 # goto frame 'Frame3', create if needed <br> frame match wcs<br> frame lock wcs</tt><br> <p><b> <a name="gif"></a>gif</b></p> <p>Load GIF image into current frame.<br> </p> <tt> Syntax:<br> gif [new|slice] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>gif</tt><br> <tt><tt>ds9.set(string cmd)<br> </tt>gif foo.gif</tt><br> <tt><tt>gif new foo.gif<br> </tt></tt><tt><tt><tt>gif slice foo.gif<br> </tt></tt>gif</tt><br> <tt><tt>gif</tt><tt> new<br> </tt>gif</tt><tt> slice</tt> <p><b> <a name="grid"></a>grid</b></p> <p> Controls coordinate grid. For grid numeric format syntax,&nbsp; click <a href="grid.html#Format">here</a>.</p> <tt> Syntax: <br> grid&nbsp; []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [type analysis|publication] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [system &lt;coordsys&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sky &lt;skyframe&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat &lt;skyformat&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes type interior|exterior]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes origin lll|llu|lul|luu|ull|ulu|uul|uuu]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp; [format1 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format2 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics type interior|exterior]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics vertical yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title text &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title def yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title gap &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text1 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def1 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text2 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def2 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [reset]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> string value = ds9.get(string cmd)<br> grid <br> grid type <br> grid system <br> grid sky <br> grid skyformat <br> grid grid <br> grid grid color <br> grid grid width <br> grid grid style <br> grid grid gap1 <br> grid grid gap2 <br> grid axes <br> grid axes color <br> grid axes width <br> grid axes style <br> grid axes type <br> grid axes origin<br> grid format1<br> grid format2<br> grid tickmarks <br> grid tickmarks color <br> grid tickmarks width <br> grid tickmarks style <br> grid border <br> grid border color <br> grid border width <br> grid border style <br> grid numerics <br> grid numerics font <br> grid numerics fontsize <br> grid numerics fontweight<br> grid numerics fontslant<br> grid numerics color <br> grid numerics gap1 <br> grid numerics gap2 <br> grid numerics type <br> grid numerics vertical <br> grid title <br> grid title text<br> grid title def <br> grid title gap <br> grid title font <br> grid title fontsize <br> grid title fontweight<br> grid title fontslant<br> grid title color <br> grid labels <br> grid labels text1 <br> grid labels def1 <br> grid labels gap1 <br> grid labels text2 <br> grid labels def2 <br> grid labels gap2 <br> grid labels font <br> grid labels fontsize <br> grid labels fontweight<br> grid labels fontslant<br> grid labels color <br> ds9.set(string cmd)<br> grid <br> grid yes<br> grid type analysis <br> grid system wcs <br> grid sky fk5 <br> grid skyformat degrees<br> grid grid yes<br> grid grid color red<br> grid grid width 2<br> grid grid style 1<br> grid grid gap1 10<br> grid grid gap2 10<br> grid axes yes<br> grid axes color red<br> grid axes width 2<br> grid axes style 1<br> grid axes type exterior<br> grid axes origin lll<br> grid format1 d.2<br> grid format2 d.2<br> grid tickmarks yes<br> grid tickmarks color red<br> grid tickmarks width 2<br> grid tickmarks style 1<br> grid border yes<br> grid border color red<br> grid border width 2<br> grid border style 1<br> grid numerics yes<br> grid numerics font courier<br> grid numerics fontsize 12<br> grid numerics fontweight bold<br> grid numerics fontslant italic<br> grid numerics color red<br> grid numerics gap1 10<br> grid numerics gap2 10<br> grid numerics type exterior<br> grid numerics vertical yes<br> grid title yes<br> grid title text {Hello World}<br> grid title def yes<br> grid title gap 10<br> grid title fontsize 12<br> grid title font courier<br> grid title fontweight bold<br> grid title fontslant italic<br> grid title color red<br> grid labels yes<br> grid labels text1 {Hello World}<br> grid labels def1 yes<br> grid labels gap1 10<br> grid labels text2 {Hello World}<br> grid labels def2 yes<br> grid labels gap2 10<br> grid labels font courier<br> grid labels fontsize 12<br> grid labels fontweight bold<br> grid labels fontslant italic<br> grid labels color red<br> grid reset<br> grid load foo.grd <br> grid save foo.grd<br> grid open<br> grid close<br> </tt> <p><b> <a name="header"></a>header</b></p> <p>Display current fits header dialog. Optional extension number maybe specified. Please note, this differs from samp fits header.</p> <tt> Syntax: <br> header [&lt;ext&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [close [&lt;ext&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save [&lt;ext&gt;] &lt;filename&gt;]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> header<br> header 2<br> header close<br> </tt> <p><b> <a name="height"></a>height</b></p> <p>Set the height of the image display window. </p> <tt> Syntax: <br> height [&lt;value&gt;]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> height<br> ds9.set(string cmd)<br> height 512<br> </tt> <p><b> <a name="iconify"></a>iconify</b></p> <p>Toggles iconification. </p> <tt> Syntax: <br> iconify []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> iconify <br> ds9.set(string cmd)<br> iconify<br> iconify yes<br> </tt> <p><b><a name="iis"></a>iis</b></p> <p>Set/Get IIS Filename. Optional mosaic number maybe supplied.</p> <tt> Syntax: <br> iis [filename &lt;filename&gt; [#]]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> iis filename<br> iis filename 4<br> ds9.set(string cmd)<br> iis filename foo.fits<br> iis filename bar.fits 4</tt><br> <p><b><a name="imexam"></a>imexam</b></p> <p>Interactive examine function. A blinking cursor will indicate to the user to click on a point on an image. The specified information will be returned at that time.</p> <tt> Syntax: <br> imexam [] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [key] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [any] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [] [data [width][height]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [key] [data [width][height]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [any] [data [width][height]]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> imexam coordinate image<br> imexam key coordinate image # return coordinate and key event<br> imexam any coordinate image # return coordinate and key/mouse event<br> imexam coordinate wcs fk5 degrees<br> imexam coordinate wcs galactic sexagesimal<br> imexam coordinate fk5<br> imexam data # return data value<br> imexam key data # return data value and key event<br> imexam any data # return data value and key/mouse event<br> imexam data 3 3 # return all data in 3x3 box about selected point</tt><br> <p><b> <a name="jpeg"></a>jpeg</b></p> <p>Load JPEG image into current frame. Optional parameters: <tt>jpeg </tt>quality (1-100) </p> <tt> Syntax:<br> jpeg [new|slice] [&lt;filename&gt;] [1-100]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>jpeg</tt><br> <tt><tt>jpeg 100</tt><br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>jpeg foo.jpeg</tt><br> <tt><tt>jpeg new foo.jpeg<br> </tt></tt><tt><tt><tt>jpeg slice foo.jpeg<br> </tt></tt>jpeg</tt><br> <tt><tt>jpeg</tt><tt> new<br> </tt>jpeg</tt><tt> slice</tt> <p><b> <a name="lock"></a>lock</b></p> <p>Lock all other frames to the current frame. </p> <tt> Syntax: <br> </tt><tt>lock</tt><tt> </tt><tt>[frame &lt;coordsys&gt;|none]<br> &nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;|none] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [crop &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [slice [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [bin [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [scale [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [colorbar [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [smooth [yes|no]]</tt><tt><br> &nbsp; </tt><tt><br> Example:<br> </tt><tt>string value = ds9.get(string cmd) <br> </tt><tt>lock frame<br> lock crosshair<br> </tt><tt>lock crop</tt><br> <tt> lock slice</tt><br> <tt> lock bin<br> lock scale<br> lock color</tt><tt>bar<br> lock smooth<br> </tt><tt>ds9.set(string cmd)<br> </tt><tt>lock frame wcs</tt><tt><br> </tt><tt>lock crosshair wcs<br> </tt><tt>lock crop yes</tt><br> <tt>lock slice yes</tt><br> <tt> lock bin yes<br> </tt><tt>lock scale yes<br> </tt><tt>lock colorbar yes</tt><tt><br> lock smooth yes<br> </tt> <p><b> <a name="lower"></a>lower</b></p> <p>Lower in the window stacking order. </p> <tt> Syntax: <br> lower <br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> lower</tt><tt><br> </tt> <p><b> <a name="magnifier"></a>magnifier</b></p> <p>Controls the magnifier settings. </p> <tt> Syntax: <br> magnifier [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [zoom &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cursor yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [region yes|no]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> magnifier color<br> magnifier zoom<br> magnifier cursor<br> magnifier region<br> ds9.set(string cmd)<br> magnifier color yellow<br> magnifier zoom 2<br> magnifier cursor no<br> magnifier region no<br> </tt> <p><b><a name="mask"></a>mask<br> </b></p> <p>Controls mask parameters. </p> <tt> Syntax: <br> mask [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [mark 1|0]<br> &nbsp;&nbsp;&nbsp;&nbsp; [transparency &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> mask color<br> mask mark<br> mask transparency<br> ds9.set(string cmd)<br> mask color red<br> mask mark 0<br> mask transparency 50<br> mask clear<br> mask open<br> mask close<br> </tt> <p><b> <a name="match"></a>match</b></p> <p>Match all other frames to the current frame. </p> <tt> Syntax: <br> </tt><tt>match </tt><tt>[frame &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crop &lt;coordsys&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [slice]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [bin]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [smooth]</tt><tt><br> </tt><tt>&nbsp; <br> Example:<br> ds9.set(string cmd)<br> </tt><tt>match frame wcs <br> </tt><tt>match crosshair wcs<br> </tt><tt>match crop wcs</tt><br> <tt> match slice<br> match bin<br> match scale<br> match color</tt><tt>bar<br> match smooth</tt><br> <p><b> <a name="mecube"></a>mecube</b></p> <p>Load FITS multiple extension file as data cube.<br> </p> <tt> Syntax:<br> mecube [new] [&lt;filename&gt;]<br> &nbsp;<br> Example: </tt><br> <tt>string value = ds9.get(string cmd)</tt><tt><tt><br> </tt>mecube<br> </tt><tt><tt><tt>ds9.set(string cmd)<br> </tt></tt>mecube foo.fits</tt><br> <tt><tt>mecube new foo.fits<br> </tt>mecube</tt><br> <tt>mecube</tt><tt> new</tt> <p><b> <a name="minmax"></a>minmax</b></p> <p>This is how DS9 determines&nbsp; the min and max data values from the data. <tt>SCAN</tt> will scan all data. <tt>SAMPLE</tt> will sample the data every n samples. <tt>DATAMIN</tt> and <tt>IRAFMIN</tt> will use the values of the keywords if present. In general, it is recommended to use <tt>SCAN</tt> unless your computer is slow or your data files are very large. Select the increment&nbsp; interval for determining the min and max data values during sampling. The larger the interval, the quicker the process. </p> <tt> Syntax: <br> minmax [auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;] <br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> minmax mode <br> minmax interval <br> ds9.set(string cmd)<br> minmax scan <br> minmax mode scan<br> minmax interval 10 </tt> <p><b> <a name="mode"></a>mode</b></p> <p>Controls the first mouse button mode. </p> <tt> Syntax: <br> mode [none|pointer|crosshair|colorbar|pan|zoom|rotate|catalog|examine] <br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> mode <br> ds9.set(string cmd)<br> mode crosshair</tt><br> <p><b> <a name="mosaic"></a>mosaic</b></p> <p>Load FITS mosaic segment into current frame.</p> <tt> Syntax:<br> mosaic [wcs|wcsa...wcsz|iraf] [new|mask] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>mosaic</tt><tt><br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>mosaic foo.fits</tt><br> <tt><tt>mosaic wcs foo.fits</tt></tt><br> <tt><tt>mosaic wcs new foo.fits</tt></tt><br> <tt><tt>mosaic wcs mask foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>mosaic</tt><br> <tt><tt>mosaic wcs<br> mosaic wcs</tt><tt> new<br> </tt>mosaic wcs</tt><tt> mask<br> </tt> <p><b> <a name="mosaicimage"></a>mosaicimage</b></p> <p>Load FITS mosaic image into current frame.</p> <tt> Syntax:<br> mosaicimage [wcs|wcsa...wcsz|iraf|wfpc2] [new|mask] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>mosaicimage</tt><tt><br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>mosaicimage foo.fits</tt><br> <tt><tt>mosaicimage wcs foo.fits</tt></tt><br> <tt><tt>mosaicimage wcs new foo.fits</tt></tt><br> <tt><tt>mosaicimage wcs mask foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>mosaicimage</tt><br> <tt><tt>mosaicimage wcs<br> mosaicimage wcs new</tt><tt><br> </tt>mosaicimage wcs mask</tt> <p><b><a name="movie"></a>movie</b></p> <p>Create mpeg1 movie from snap shots of the DS9 window. A <tt>slice</tt> movie cycles though all slices of a cube. A <tt>frame</tt> movie cycles through all active frames. A <tt>3d</tt> movie cycles through specified viewing angles. The default is <tt>frame</tt>. Optional parameters for <tt>3d</tt>: number of frames, azimuth from/to, elevation from/to, slice from/to, oscillate/repeat times.</p> <tt> Syntax:<br> movie </tt><tt>[slice|frame|3d] </tt><tt>&lt;filename&gt;<br> </tt><tt>movie 3d &lt;filename&gt; [number|azfrom|azto|elfrom|elto|slfrom|slto|oscillate|repeat &lt;#&gt;]</tt><br> <tt> &nbsp;<br> Example:<br> ds9.set(string cmd)<br> movie slice ds9.mpg<br> </tt><tt>movie 3d ds9.mpg number 10 azfrom -60 azto 60 oscillate 1</tt><br> <p><b> <a name="multiframe"></a>multiframe</b></p> <p>Load FITS multiple extension file as multiple images.<br> </p> <tt> Syntax:<br> multiframe [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>multiframe foo.fits</tt><tt><tt><br> </tt>multiframe</tt><br> <p><b> <a name="nameserver"></a>nameserver</b></p> <p>Support Name Server functions. Coordinates are in fk5. </p> <tt> Syntax: <br> nameserver [&lt;object&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [server ned-sao|ned-eso|simbad-sao|simbad-eso]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pan]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crosshair]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> nameserver<br> nameserver server<br> nameserver skyformat<br> nameserver m31<br> ds9.set(string cmd)<br> nameserver m31 <br> nameserver name m31 <br> nameserver server ned-sao <br> nameserver skyformat sexagesimal<br> nameserver pan<br> nameserver crosshair<br> nameserver open<br> nameserver close<br> </tt> <p><b> <a name="nan"></a>nan</b></p> <p>Set image not-a-number color. </p> <tt> Syntax: <br> nan &lt;color&gt;<br> &nbsp;<br> Example:<br> </tt><tt>string value = ds9.get(string cmd)<br> nan</tt><br> <tt>ds9.set(string cmd)<br> nan red</tt><br> <p><b> <a name="nrrd"></a>nrrd</b></p> <p>Load an NRRD (Nearly Raw Raster Data) file. Optional parameter: array endian.<br> </p> <tt> Syntax: <br> nrrd [&lt;filename&gt;] [little|big]<br> &nbsp;<br> Example:<br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>nrrd</tt><br> <tt><tt>nrrd big<br> </tt></tt><tt><tt><tt>ds9.set(string cmd</tt><tt>, string url</tt><tt>)<br> </tt>nrrd foo.nrrd</tt></tt><br> <tt><tt><tt><tt>nrrd new foo.nrrd</tt></tt></tt></tt><br> <tt><tt><tt><tt><tt><tt>nrrd mask foo.nrrd<br> </tt></tt></tt></tt></tt>nrrd</tt><br> <tt>nrrd</tt><tt> new<br> nrrd mask</tt><br> <p><b> <a name="nvss"></a>nvss</b></p> <p>Support for NRAO VLA Sky Survey.</p> <tt> Syntax: <br> nvss []<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> nvss name <br> nvss coord <br> nvss size<br> nvss save<br> nvss frame<br> ds9.set(string cmd)<br> nvss<br> nvss m31 <br> nvss name m31 <br> nvss coord 00:42:44.404 +41:16:08.78 sexagesimal<br> nvss size 60 60 arcmin<br> nvss save yes<br> nvss frame current<br> nvss update frame<br> nvss open<br> nvss close<br> </tt> <p><b> <a name="orient"></a>orient</b></p> <p>Controls the orientation of the current frame. </p> <tt> Syntax: <br> orient [none|x|y|xy] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> orient <br> ds9.set(string cmd)<br> orient xy<br> orient open<br> orient close<br> </tt> <p><b> <a name="pagesetup"></a>pagesetup</b></p> <p>Controls Page Setup options. </p> <tt> Syntax: <br> pagesetup [orient portrait|landscape]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale &lt;numeric&gt;]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size letter|legal|tabloid|poster|a4]</tt><br> <tt> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> pagesetup orient<br> pagesetup scale <br> pagesetup size <br> ds9.set(string cmd)<br> pagesetup orient portrait <br> pagesetup scale 50<br> pagesetup size poster<br> </tt> <p><b> <a name="pan"></a>pan</b></p> <p>Controls the current image cursor location for the current frame. </p> <tt> Syntax: <br> pan [&lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;]] <br> &nbsp;&nbsp;&nbsp; [to &lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;] <br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;&nbsp;&nbsp; [close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> pan # get current image coords <br> pan wcs fk4 sexagesimal # get current wcs coords <br> ds9.set(string cmd)<br> pan 200 200 image # pan relative <br> pan to 400 400 physical # pan to physical coords <br> pan to 13:29:55 47:11:50 wcs fk5 # pan to wcs coords<br> pan open<br> pan close<br> </tt> <p><b> <a name="pixeltable"></a>pixeltable</b></p> <p>Display/Hide the pixel table. </p> <tt> Syntax: <br> pixeltable []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [yes|open] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [no|close]<br> &nbsp;<br> Example:<br> string url = ds9.get(string cmd)<br> pixeltable <br> ds9.set(string cmd)<br> pixeltable<br> pixeltable yes<br> pixeltable open<br> pixeltable close<br> </tt> <p><b> <a name="plot"></a>plot</b></p> <p>Display and configure data plots. All plot commands take an optional second command, the plot name. Use xpaget plot to retrieve all plot names. If no plot name is specified, the last plot created is assumed. Plot data is assumed to be a pair of coordinates, with optional error values. The follow are valid data descriptions:</p> <blockquote>xy &nbsp;&nbsp; &nbsp; &nbsp; x and y coordinates<br> xyex&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with x errors<br> xyey&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with y errors<br> xyexey&nbsp;&nbsp;&nbsp; x,y coordinates with both x and y errors<br> </blockquote> <p>To create a new plot, use the plot new command. If the second arg is stdin, the title, x axis title, y axis title, and dimension are assumed to be on the first line of the data. </p> <tt> Syntax: <br> # create new empty plot window<br> plot [bar|scatter]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new [name &lt;plotname&gt;] [line|bar|scatter]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new [name &lt;plotname&gt;] </tt><tt>[line|bar|scatter] </tt><tt>&lt;title&gt; &lt;xaxis label&gt; &lt;yaxis label&gt; </tt><tt>xy|xyex|xyey|xyexey</tt><tt>]<br> <br> # create new plot with data<br> plot [new [name &lt;plotname&gt;] </tt><tt>[line|bar|scatter] </tt><tt>stdin]<br> &nbsp;&nbsp;&nbsp; &nbsp;[new [name &lt;plotname&gt;] </tt><tt>[line|bar|scatter] </tt><tt>&lt;title&gt; &lt;xaxis label&gt; &lt;yaxis label&gt; xy|xyex|xyey|xyexey]<br> <br> # load additional dataset into an existing plot<br> plot [&lt;plotname&gt;] [data xy|xyex|xyey|xyexey]<br> <br> # edit existing plot<br> plot [&lt;plotname&gt;] [close]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [load &lt;filename&gt; xy|xyex|xyey|xyexey]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [save &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [loadconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [saveconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [print]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [print destination printer|file] <br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print command &lt;command&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print filename &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print color rgb|gray]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup orient portrait|landscape]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup size letter|legal|tabloid|poster|a4]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph grid x|y yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [graph log x|y yes|no]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph flip x|y yes|no]</tt><br> <tt> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y auto yes|no]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y min &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y max &lt;value&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph format x|y &lt;value&gt;]</tt><br> <tt> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph labels title|xaxis|yaxis &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title font times|helvetica|courier]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title size &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title weight normal|bold]<br> &nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [font numbers|labels|title slant roman|italic]<br> <br> # edit current dataset<br> plot [&lt;plotname&gt;] [dataset #]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [view discrete|linear|step|quadratic|error yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [color discrete|linear|step|quadratic|error|bar &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line discrete circle|diamond|plus|cross]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line linear|step|quadratic|error width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line linear|step|quadratic dash yes|no]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [line error style 1|2]<br> &nbsp;<br> Example: <br> # return all plotnames<br> string value = ds9.get(string cmd)<br> plot<br> <br> # create new empty plot window<br> ds9.set(string cmd)<br> plot<br> plot scatter<br> plot new<br> plot new bar<br> plot new name foo<br> plot new name foo scatter<br> <br> # create new plot with data<br> ds9.set(string cmd, string url)<br> plot new stdin <br> plot new name foo stdin<br> plot new "{The Title}" "{X}" "{Y}" xy<br> plot new name foo "{The Title}" "{X}" "{Y}" xy<br> <br> # load additional dataset into an existing plot<br> ds9.set(string cmd, string url)<br> plot data xy # plot additional data<br> plot foo data xy # plot additional data<br> <br> # edit existing plot<br> ds9.set(string cmd)<br> plot close # close last plot<br> plot foo close # close plot foo<br> plot clear # clear all datasets<br> ds9.set(string cmd)<br> plot load foo.dat xy # load new dataset with dimension xy<br> plot save bar.dat # save current dataset<br> plot loadconfig foo.plt # load plot configuration <br> plot saveconfig bar.plt # save current plot configuration<br> ds9.set(string cmd)<br> plot print<br> plot print destination file<br> plot print command "lp"<br> plot print filename "foo.ps"<br> plot print color gray<br> plot pagesetup orient portrait<br> plot pagesetup size letter<br> ds9.set(string cmd)<br> plot graph grid type bar<br> plot graph grid x yes<br> plot graph log x yes<br> </tt><tt>plot graph flip x yes</tt><br> <tt> plot graph range x auto yes<br> plot graph range x min 0<br> plot graph range x max 100<br> plot graph range y auto yes<br> plot graph range y min 0<br> plot graph range y max 100<br> </tt><tt>plot graph format y %e</tt><br> <tt> plot graph labels title "{The Title}"<br> plot graph labels xaxis "{X}"<br> plot graph labels yaxis "{Y}"<br> ds9.set(string cmd)<br> plot font numbers font times<br> plot font numbers size 12<br> plot font numbers style bold<br> plot font labels font times<br> plot font title font times<br> <br> # edit current dataset<br> ds9.set(string cmd)<br> plot dataset 2 # set current dataset to the second dataset loaded<br> plot view discrete yes<br> plot color discrete red<br> plot line discrete cross<br> plot line step width 2<br> plot line step dash yes<br> plot line error style 2</tt><br> <p><b><b><a name="png"></a></b>png</b></p> <p>Load PNG image into current frame.<br> </p> <tt> Syntax:<br> png [new|slice] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>png</tt><br> <tt><tt>ds9.set(string cmd)<br> </tt>png foo.png</tt><br> <tt><tt>png new foo.png<br> </tt></tt><tt><tt><tt>png slice foo.png<br> </tt></tt>png</tt><br> <tt><tt>png</tt><tt> new<br> </tt>png</tt><tt> slice</tt><br> <p><b> <a name="prefs"></a>prefs</b></p> <p>Controls various preference settings. </p> <tt> Syntax: <br> prefs clear<br> &nbsp; <br> Example:<br> ds9.set(string cmd)<br> prefs clear<br> <br> </tt><b><a name="preserve"></a>preserve</b> <p>Preserve the follow attributes while loading a new image. </p> <tt> Syntax: <br> preserve [scale yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [pan yes|no]<br> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; [regions yes|no]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd) <br> preserve scale<br> preserve pan<br> preserve regions<br> ds9.set(string cmd)<br> preserve scale yes<br> preserve pan yes<br> preserve regions yes<br> </tt> <p><b><a name="psprint"></a>psprint</b></p> <p>For MacOSX and Windows, invokes postscript printing. For all others, same as print. Please see <a href="command.html#print">print</a> for further details.</p> <p><b> <a name="print"></a>print</b></p> <p>Controls printing. Use print option to set printing options. Use print to actually print. </p> <tt> Syntax: <br> print [destination printer|file] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;command&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [filename &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color rgb|cmyk|gray] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [level 1|2] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [resolution 53|72|75|150|300|600] <br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd) <br> print destination <br> print command <br> print filename <br> print color<br> print level <br> print resolution <br> ds9.set(string cmd)<br> print <br> print destination file <br> print command '{gv -}' <br> print filename foo.ps <br> print color cmyk <br> print level 2 <br> print resolution 75 </tt> <p><b> <a name="raise"></a>raise</b></p> <p>Raise in the window stacking order. </p> <tt> Syntax: <br> raise <br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> raise </tt> <p><b> <a name="regions"></a>regions</b></p> <p>Controls regions in the current frame. </p> <tt> Syntax: <br> regions&nbsp;[&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load [all] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [list [close]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [show yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [showtext yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid auto yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid radius &lt;value&gt;|iteration &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [getinfo]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move front] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select all]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select none] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select invert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [delete all] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [delete select] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format ds9|xml|ciao|saotng|saoimage|pros|xy] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [system image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sky fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [strip yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [shape &lt;shape&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color &amp;ltcolor&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [fixed|edit|rotate|delete yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [include|exclude|source|background]</tt><br> <tt> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [delim [nl|&lt;char&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;marker command&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [composite]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [dissolve]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [template &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [template &lt;filename&gt; at &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [savetemplate &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [groups] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group new]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; new]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; update]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; select]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; color &lt;color&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; copy] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; delete] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; font &lt;font&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; move &lt;int&gt; &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; movefront] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; moveback] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; property &lt;property&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [paste image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [undo]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [include|exclude|source|background|selected]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-format ds9|ciao|saotng|saoimage|pros|xy]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-system image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-sky fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-delim [nl|&lt;char&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-prop select|edit|move|rotate|delete|fixed|include|source 1|0] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-group &lt;tag&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-strip yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-wcs yes|no]<br> &nbsp;<br> Example: <br> string url = ds9.get(string cmd)<br> regions<br> regions -format ds9 -system wcs -sky fk5 -skyformat sexagesimal -prop edit 1 -group foo <br> string value = ds9.get(string cmd) <br> regions show<br> regions showtext<br> regions centroid<br> regions centroid auto<br> regions centroid radius<br> regions centroid iteration<br> regions selected<br> regions format <br> regions system <br> regions sky <br> regions skyformat <br> regions strip<br> regions shape <br> regions color <br> regions width<br> regions delim<br> regions source <br> regions background <br> regions include <br> regions exclude <br> regions selected<br> regions groups<br> ds9.set(string cmd, string url)<br> regions -format xy -system wcs -sky fk5<br> regions -format ds9<br> ds9.set(string cmd)<br> regions foo.reg <br> regions -format ciao bar.reg # load as ciao format<br> regions foo.fits # FITS regions files do not need a format specification<br> regions load foo.reg # load foo.reg into current frame<br> regions load all foo.reg # load foo.reg into all frames<br> regions load *.reg# expand *.reg and load into current frame<br> regions load all *.reg # expand *.reg and load into all frames<br> regions save foo.reg<br> regions list <br> regions list close<br> regions show yes<br> regions showtext no<br> regions centroid<br> regions centroid auto yes<br> regions centroid radius 10<br> regions centroid iteration 20<br> regions getinfo<br> regions move back <br> regions move front <br> regions select all <br> regions select none <br> regions select invert<br> regions delete all <br> regions delete select <br> regions format ds9 <br> regions system wcs<br> regions sky fk5 <br> regions skyformat degrees <br> regions delim nl <br> regions strip yes<br> regions shape ellipse <br> regions color red <br> regions width 3<br> regions edit yes<br> regions include<br> regions command "circle 100 100 20 # color=red"<br> regions composite<br> regions dissolve<br> regions template foo.tpl<br> regions template foo.tpl at 13:29:55.92 +47:12:48.02 fk5<br> regions savetemplate foo.tpl<br> regions group new<br> regions group foo new<br> regions group foo update<br> regions group foo select<br> regions group foo color red<br> regions group foo copy<br> regions group foo delete<br> regions group foo cut<br> regions group foo font 'times 14 bold'<br> regions group foo move 100 100 <br> regions group foo movefront <br> regions group foo moveback <br> regions group foo property delete no <br> regions copy<br> regions cut<br> regions paste wcs<br> regions undo<br> </tt> <p><b> <a name="restore"></a>restore</b></p> <p>Restore DS9 to a previous state from a backup save set. </p> <tt> Syntax: <br> restore &lt;filename&gt;<br> &nbsp;<br> Example:<br> restore ds9.bck</tt><br> <p><b> <a name="rgb"></a>rgb</b></p> <p>Create RGB frame and control RGB frame parameters.</p> <tt> Syntax: <br> rgb&nbsp; []<br> &nbsp;&nbsp;&nbsp; &nbsp;[red|green|blue]<br> &nbsp;&nbsp;&nbsp; &nbsp;[channel [red|green|blue]]<br> &nbsp;&nbsp; &nbsp; [view [red|green|blue] [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[lock wcs|crop|slice|bin|scale|colorbar|smooth [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> rgb channel<br> </tt><tt>rgb lock wcs</tt><br> <tt>rgb lock crop</tt><br> <tt>rgb lock slice</tt><br> <tt> rgb lock bin<br> rgb lock scale<br> rgb lock colorbar<br> rgb lock smooth<br> rgb system<br> rgb view red<br> rgb view green<br> rgb view blue<br> ds9.set(string cmd)<br> rgb # create new rgb frame<br> rgb red # set current channel to red<br> rgb channel red # set current channel to red<br> rgb view blue no # turn off blue channel<br> rgb system wcs # set rgb coordinate system<br> </tt><tt>rgb lock wcs yes</tt><br> <tt>rgb lock crop yes</tt><br> <tt>rgb lock slice yes</tt><br> <tt>rgb lock bin yes</tt><br> <tt> rgb lock scale yes<br> rgb lock colorbar yes<br> rgb lock smooth yes<br> rgb open<br> rgb close</tt><br> <p><b> <a name="rgbarray"></a>rgbarray</b></p> <p>Load raw data array cube into rgb frame.<br> </p> <tt> Syntax:<br> rgbarray [native|big|little]<br> rgbarray [new|mask] [[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],[zdim=3],bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> </tt><tt><tt><tt>string value = ds9.get(string cmd)<br> </tt></tt>rgbarray<br> rgbarray little<br> </tt><tt><tt><tt>ds9.set(string cmd)<br> </tt></tt>rgbarray foo.arr[dim=512,zdim=3,bitpix=-32,endian=little]<br> rgbarray new foo.arr[dim=512,zdim=3,bitpix=</tt><tt>-32,endian=little]</tt><br> <p><b> <a name="rgbcube"></a>rgbcube</b></p> <p>Load FITS rgbcube into rgb frame.<br> </p> <tt> Syntax:<br> rgbcube [new] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>rgbcube<br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>rgbcube foo.fits</tt><br> <tt><tt>rgbcube new foo.fits<br> </tt>rgbcube</tt><br> <tt>rgbcube</tt><tt> new</tt><br> <p><b> <a name="rgbimage"></a>rgbimage</b></p> <p>Load FITS rgbimage into rgb frame.<br> </p> <tt> Syntax:<br> rgbimage [new] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> </tt><tt><tt><tt>string value = ds9.get(string cmd)<br> </tt></tt>rgbimage<br> </tt><tt><tt><tt>ds9.set(string cmd)<br> </tt></tt>rgbimage foo.fits</tt><br> <tt><tt>rgbimage new foo.fits<br> </tt>rgbimage</tt><br> <tt>rgbimage</tt><tt> new</tt> <p><b> <a name="rotate"></a>rotate</b></p> <p>Controls the rotation angle (in degrees) of the current frame. </p> <tt> Syntax: <br> rotate [&lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> rotate <br> ds9.set(string cmd)<br> rotate 45 <br> rotate to 30<br> rotate open<br> rotate close</tt><br> <p><b> <a name="save"></a>save<br> </b></p> <p>Save loaded image data of current frame as FITS.</p> <tt> Syntax: <br> save </tt><tt>[fits|rgbimage|rgbcube|mecube|mosaic|mosaicimage] &lt;filename&gt; [image|table|slice]</tt> <br> <tt> &nbsp;<br> Example: <br> </tt><tt><tt>ds9.set(string cmd) <br> </tt>save foo.fits</tt><br> <tt>save fits foo.fits image</tt><br> <tt>save fits foo.fits table<br> save fits foo.fits slice</tt><br> <tt>save rgbimage foo.fits<br> </tt><tt>save rgbcube foo.fits</tt><br> <tt>save mecube foo.fits</tt><br> <tt>save mosaic foo.fits</tt><br> <tt>save mosaicimage foo.fits</tt><br> <p><b> <a name="saveimage"></a>saveimage</b></p> <tt></tt> <p>Create a snap shot of the current DS9 window and save in specified image format. If no format specified, the file name extension is used to determine the output format. Optional parameters: <tt>jpeg</tt> quality (1-100) and <tt>tiff</tt> compression method. </p> <tt> Syntax: <br> saveimage </tt><tt>[fits|eps|gif|tiff|jpeg|png] </tt><tt>&lt;filename&gt;<br> saveimage &lt;filename&gt;.jpeg [1-100]<br> saveimage &lt;filename&gt;.tiff [none|jpeg|packbits|deflate]<br> &nbsp;<br> Example:<br> ds9.set(string cmd) <br> saveimage ds9.tiff<br> saveimage jpeg ds9.jpeg 75</tt><tt></tt><br> <p><b> <a name="scale"></a>scale</b></p> <p>Controls the limits and color scale distribution. </p> <tt> Syntax: <br> scale [linear|log|pow|sqrt|squared|asinh|sinh|histequ]<br> &nbsp; &nbsp; &nbsp; [log exp &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [datasec yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [limits &lt;minvalue&gt; &lt;maxvalue&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scope local|global]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> scale<br> scale log exp <br> scale datasec <br> scale limits <br> scale mode <br> scale scope <br> scale lock<br> ds9.set(string cmd)<br> scale linear<br> scale log exp 100<br> scale datasec yes <br> scale histequ <br> scale limits 1 100 <br> scale mode zscale <br> scale mode 99.5 <br> scale scope local<br> scale match<br> scale lock yes<br> scale open<br> scale close<br> </tt> <p><b> <a name="shm"></a>shm</b></p> <p>Load a shared memory segment into the current frame. </p> <tt> Syntax: <br> shm [&lt;key&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [key &lt;key&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [shmid &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [fits [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaicimage [iraf|wcs|wcsa...wcsz|wfpc2] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaicimagenext [wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaic [iraf|wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [rgbcube [key|shmid] &lt;id&gt; [&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; [rgbimage [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [rgbarray [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;,zdim=3],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;&nbsp;&nbsp; [array [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;&nbsp;&nbsp; [startload|finishload]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> shm <br> ds9.set(string cmd)<br> shm 102 <br> shm key 102<br> shm shmid 102 foo<br> shm fits key 100 foo <br> shm mosaicimage iraf key 100 foo <br> shm mosaicimage wcs key 100 foo <br> shm mosaicimage wcsa key 100 foo <br> shm mosaicimage wfpc2 key 100 foo <br> shm mosaicimagenext wcs key 100 foo<br> shm mosaic iraf key 100 foo <br> shm mosaic wcs key 100 foo <br> shm rgbcube key 100 foo <br> shm rgbimage key 100 foo<br> shm rgbarray key 100 [dim=200,zdim=3,bitpix=-32]<br> shm array shmid 102 [dim=32,bitpix=-32]<br> shm startload # start a multiple load sequence without updating the display<br> shm finishload # finish multiple load sequence<br> </tt> <p><b> <a name="single"></a>single</b></p> <p>Select Single Display mode </p> <tt> Syntax: <br> single <br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> single <br> ds9.set(string cmd)<br> single<br> </tt> <p><b><a name="skyview"></a>skyview </b></p> <p>Support for SkyView image server at HEASARC. </p> <p> </p> <tt> Syntax: <br> skyview []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [survey sdssi|sdssr|sdssg|sdssu|sdssg] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> skyview name <br> skyview coord <br> skyview size<br> skyview save<br> skyview frame<br> skyview survey<br> ds9.set(string cmd)<br> skyview<br> skyview m31 <br> skyview name m31 <br> skyview coord 00:42:44.404 +41:16:08.78 sexagesimal<br> skyview size 60 60 arcmin<br> skyview save yes<br> skyview frame current<br> skyview update frame<br> skyview survey sdssi<br> skyview open<br> skyview close<br> </tt> <p><b><a name="sleep"></a>sleep </b></p> <p>Delays execution for specified number of seconds. Default is 1 second. </p> <p> </p> <tt> Syntax: <br> sleep [#]<br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> sleep<br> sleep 2<br> </tt> <p><b><a name="smooth"></a>smooth</b></p> <p>Smooth current image or set smooth parameters.</p> <tt> Syntax:<br> smooth []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [function boxcar|tophat|gaussian]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [radius &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> smooth<br> smooth function<br> smooth radius<br> smooth lock<br> ds9.set(string cmd)<br> smooth<br> smooth yes<br> smooth function tophat<br> smooth radius 4<br> smooth open<br> smooth close<br> smooth match<br> smooth lock yes<br> </tt> <p><b> <a name="source"></a>source</b></p> <p>Source TCL code from a file. </p> <tt> Syntax: <br> source [filename] <br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> source foo.tcl </tt> <p><b> <a name="tcl"></a>tcl</b></p> <p>Execute one tcl command. Must be enabled via the -tcl command line option.</p> <tt> Syntax: <br> tcl [&lt;tcl command&gt;] <br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> tcl puts "Hello, World"<br> ds9.set(string cmd, string url)<br> </tt> <p><b> <a name="theme"></a>theme</b></p> <p>Select GUI theme. Use <tt>native</tt> for the recommended theme for your platform. Note: not all themes are available on all platforms.<br> </p> <tt> Syntax:<br> theme [native|clam|alt|default|classic|aqua|vista|win|xp] <br> &nbsp;<br> Example: <br> </tt><tt>string value = ds9.get(string cmd)<br> </tt><tt>theme</tt><br> <tt>ds9.set(string cmd)<br> </tt><tt>theme clam<br> </tt> <p><b> <a name="threads"></a>threads</b></p> <p>Set number of process threads for functions which are multi-threaded. </p> <tt> Syntax:<br> threads #<br> &nbsp;<br> Example: <br> </tt><tt>string value = ds9.get(string cmd)<br> </tt><tt>threads</tt><br> <tt>ds9.set(string cmd)<br> </tt><tt>threads 8</tt><br> <p><b> <a name="tiff"></a>tiff</b></p> <p>Load TIFF image into current frame. Optional parameters: <tt>tiff </tt>compression method. </p> <tt> Syntax:<br> tiff [new|slice] [&lt;filename&gt;] [none|jpeg|packbits|deflate]<br> &nbsp;<br> Example: <br> </tt><tt><tt>string value = ds9.get(string cmd)<br> </tt>tiff</tt><br> <tt><tt>tiff jpeg</tt><br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>tiff foo.tiff<br> tiff new foo.tiff<br> tiff slice foo.tiff</tt><tt><tt><br> </tt>tiff<br> tiff new<br> tiff slice</tt><br> <p><b> <a name="tile"></a>tile</b></p> <p>Controls the tile display mode. </p> <tt> Syntax: <br> tile []<br> &nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [mode grid|column|row] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid mode [automatic|manual]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid layout &lt;col&gt; &lt;row&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid gap &lt;pixels&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [row] <br> &nbsp;&nbsp;&nbsp;&nbsp; [column] <br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> tile <br> tile mode <br> tile grid mode <br> tile grid layout <br> tile grid gap <br> ds9.set(string cmd)<br> tile<br> tile yes <br> tile mode row <br> tile grid <br> tile grid mode manual <br> tile grid layout 5 5 <br> tile grid gap 10 <br> tile row <br> tile column </tt> <p><b> <a name="update"></a>update</b></p> <p>Updates the current frame or region of frame. In the second form, the first argument is the number of the fits HDU (starting with 1) and the remaining args are a bounding box in IMAGE coordinates. By default, the screen is updated the next available idle cycle. However, you may force an immediate update by specifying the NOW option. </p> <tt> Syntax: <br> update [] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [# x1 y1 x2 y2] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now # x1 y1 x2 y2]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [on]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[off] <br> &nbsp;<br> Example: <br> ds9.set(string cmd)<br> update <br> update 1 100 100 300 400 <br> update now <br> update now 1 100 100 300 400<br> update off # delay refresh of the screen while loading files<br> update on # be sure to turn it on when you are finished loading</tt><br> <p><b> <a name="url"></a>url</b></p> <p>Load FITS from URL into the current frame</p> <tt> Syntax: <br> url &lt;url&gt;<br> &nbsp;<br> Example: <br> </tt><tt><tt>ds9.set(string cmd)<br> </tt>url http://foo.bar.edu/foo.fits </tt> <p><b> <a name="version"></a>version</b></p> <p>Returns the current version of DS9. </p> <tt> Syntax: <br> version <br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> version </tt> <p><b> <a name="view"></a>view</b></p> <p>Controls the GUI. </p> <tt> Syntax: <br> view&nbsp; [layout horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [info yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [panner yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [magnifier yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [buttons yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar numerics yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [graph horizontal|vertical yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [filename yes|no[<br> &nbsp;&nbsp;&nbsp; &nbsp; [object yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [minmax yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [lowhigh yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [frame yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [image|physical|wcs|wcsa...wcsz yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [red yes|no]<br> &nbsp; &nbsp; &nbsp; [green yes|no]<br> &nbsp; &nbsp; &nbsp; [blue yes|no]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> view layout<br> view info <br> view panner<br> view magnifier<br> view buttons<br> view colorbar<br> view graph horizontal<br> view filename<br> view object<br> view minmax<br> view lowhigh<br> view frame<br> view image<br> view wcsa<br> view red<br> ds9.set(string cmd)<br> view layout vertical<br> view info yes<br> view panner yes<br> view magnifier yes<br> view buttons yes<br> view colorbar yes<br> view graph horizontal yes<br> view filename yes<br> view object yes<br> view minmax yes<br> view lowhigh yes<br> view frame yes <br> view wcsa yes<br> view red yes<br> view green no<br> view blue yes<br> </tt> <p><b> <a name="vo"></a>vo</b></p> <p>Invoke an connection to a Virtual Observatory site. </p> <tt> Syntax: <br> vo [method xpa|mime]<br> &nbsp;&nbsp; [server &lt;url&gt;]<br> &nbsp;&nbsp; [internal yes|no]<br> &nbsp;&nbsp; [delay #]<br> &nbsp;&nbsp; [&lt;url&gt;]<br> &nbsp;&nbsp; [connect &lt;url&gt;]<br> &nbsp;&nbsp; [disconnect &lt;url&gt;]<br> &nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> vo<br> vo method<br> vo server<br> vo internal<br> vo delay<br> vo connect<br> ds9.set(string cmd)<br> vo method xpa<br> vo server "http://foo.bar.edu/list.txt"<br> vo internal yes<br> vo delay 15<br> vo chandra-ed<br> vo connect chandra-ed<br> vo disconnect chandra-ed<br> vo open<br> vo close<br> </tt> <p><b> <a name="wcs"></a>wcs</b></p> <p>Controls the World Coordinate System for the current frame. If the wcs system, skyframe, or skyformat is modified, the info panel, compass, grid, and alignment will be modified accordingly. Also, using this access point, a new WCS specification can be loaded and used by the current image regardless of the WCS that was contained in the image file. WCS specification can be sent to DS9 as an ASCII file . Please see <a href="file.html#WCS">WCS</a> for more information. </p> <tt> Syntax: <br> wcs [[system] wcs|wcsa...wcsz] <br> &nbsp;&nbsp;&nbsp; [[sky] fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp; [[skyformat] degrees|sexagesimal] <br> &nbsp;&nbsp;&nbsp; [align yes|no] <br> &nbsp;&nbsp;&nbsp; [reset [#]] <br> &nbsp;&nbsp;&nbsp; [replace [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; [append [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> string value = ds9.get(string cmd)<br> wcs <br> wcs system <br> wcs sky <br> wcs skyformat <br> wcs align <br> ds9.set(string cmd)<br> wcs wcs <br> wcs system wcs<br> </tt><tt>wcs fk5<br> </tt><tt>wcs sky fk5<br> </tt><tt>wcs sexagesimal <br> </tt><tt>wcs skyformat sexagesimal <br> wcs align yes <br> wcs reset <br> wcs reset 3<br> wcs replace foo.wcs <br> wcs replace 3 foo.wcs <br> wcs append foo.wcs <br> wcs append 3 foo.wcs <br> ds9.set(string cmd, string url)<br> wcs replace <br> wcs append<br> wcs open<br> wcs close<br> </tt> <p><b> <a name="web"></a>web</b></p> <p>Display specified URL in the web display. </p> <tt> Syntax:<br> web [new|&lt;webname&gt;] [&lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [click back|forward|stop|reload|#]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [clear]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> web <br> ds9.set(string cmd)<br> web www.cnn.com<br> web new www.cnn.com<br> web hvweb www.apple.com<br> web click back<br> web click 2<br> web clear<br> web close<br> </tt> <p><b> <a name="width"></a>width</b></p> <p>Set the width of the image display window.</p> <tt> Syntax: <br> width [&lt;value&gt;]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> width<br> ds9.set(string cmd)<br> width 512<br> </tt> <p><b> <a name="zscale"></a>zscale</b></p> <p>Set Scale Limits based&nbsp; on the <i>IRAF</i> algorithm. </p> <tt> Syntax: <br> zscale []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [contrast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sample]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [line]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd)<br> zscale contrast<br> zscale sample<br> zscale line<br> ds9.set(string cmd)<br> zscale<br> zscale contrast .25<br> zscale sample 600<br> zscale line 120<br> </tt> <p><b> <a name="zoom"></a>zoom</b></p> <p>Controls the current zoom value for the current frame. </p> <tt> Syntax: <br> zoom [&lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;value&gt; &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt; &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> string value = ds9.get(string cmd) <br> zoom <br> ds9.set(string cmd)<br> zoom 2 <br> zoom 2 4<br> zoom to 4 <br> zoom to 2 4<br> zoom to fit<br> zoom open<br> zoom close<br> </tt> </blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/3d.html����������������������������������������������������������������������������0000644�0001750�0001750�00000010243�11763203427�013625� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>3D</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> 3-D Frames<br> </h3> <blockquote> <p>Previous versions of SAOImage DS9 would allow users to load 3-D data into the traditional 2-D frames, and would allow users to step through successive z-dimension pixel slices of the data cube. To visualize the 3-D data in DS9 v. 7.0, a new module, encompassed by the new <tt>Frame 3D</tt> option, allows users to load and view data cubes in multiple dimensions.<br> </p> <p>The new module implements a simple ray-trace algorithm. For each pixel on the screen, a ray is projected back into the view volume, based on the current viewing parameters, returning a data value if the ray intersects the FITS data cube. To determine the value returned, there are 2 methods available, Maximum Intensity Projection (MIP) and Average Intensity Projection (AIP). MIP returns the maximum value encountered, AIP returns an average of all values encountered. At this point, normal DS9 operations are applied, such as scaling, clipping and applying a color map.<br> </p> <p>Rendering time is independent upon the actual data cube size. Instead, the time it takes to render is based on how many rays are needed to project the data cube upon the screen in the view volume and the current zoom factor. The new module requires no special hardware or graphical processor unit (GPU) and the rendering time is adequate for interactive GUI manipulation on most computers. The rendering engine is developed using the POSIX thread library, allowing multiple light weight processes to be spawned to complete an image in parallel. The number of threads actually generated is a user specified parameter. Since all modern hardware contain multiple CPU cores, the default value is 8 threads. For larger work stations, this number can be increase. For every doubling in the number of CPU cores available, rendering times decrease approximately 75%.<br> </p> <blockquote><tt>Example:</tt><br> <tt># create 3d frame, load fits file</tt><br> <tt> # set view angle to az 45 el 30 deg</tt><br> <tt> # set rendering method to Average Intensity Projection</tt><br> <br> <tt>% ds9 -3d mycube.fits </tt><tt>-3d vp 45 30 </tt><tt>-3d method aip</tt><br> <br> <tt>% xpaset -p ds9 3d</tt><br> <tt> % xpaset -p ds9 file mycube.fits</tt><br> <tt> % xpaset -p ds9 3d vp 45 30</tt><br> <tt> % xpaset -p ds9 3d method aip</tt></blockquote> <blockquote> </blockquote> All 2-D graphics, regions, cross hairs, contours, and coordinate grids, are applied to the current slice, which is selected by the user. When the user wishes to match or lock a 2-D image and to a 3-D data cube, the current slice is used to determine the rendering solution. The user can crop the data cube for all 3 axes via the command line or the GUI. The new module also supports FITS event files binned into a data cube.<br> <br> All printing support has been extended to the new 3-D module. The user may generate 3-D images in Postscript, JPEG, TIFF, and other formats, just as in the 2-D case. Furthermore, native printing is supported for the Windows version.<br> <br> DS9 analysis macros have been enhanced to fully support the new 3-D module, allowing the user to invoke external analysis tasks based on the current view parameters and to return results back into DS9 in the form of text, plot, 2-D image, or 3-D image. </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/catalog.html�����������������������������������������������������������������������0000644�0001750�0001750�00000016505�11763207065�014742� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Catalogs</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Catalogs</h3> <blockquote> <p>DS9 provides full support for loading, displaying, filtering, and saving catalogs. DS9 allows you to overlay symbols from multiple catalogs on the current image.</p> <p>Local and on-line catalog access is supported. Most major catalogs can be retrieved from online servers. Both the CDS and SDSS catalog servers are now supported. Local catalog files in starbase (rdb) or CSV (with or without header) are supported.</p> <p>On-line catalogs are available via services provided by the VizieR catalog access tool, CDS, Strasbourg, France (VizieR is a joint effort of the Centre de Donnees Astronomiques de Strasbourg and ESA-ESRIN Information Systems Division) and by the Sloan Digital Sky Survey.</p> <p>A selection of popular catalogs is provided in the Analysis menu. In addition, you can search for other catalogs based on title, keywords, mission, wavelength, and object type.</p> <p>When a catalog is overlayed on an image, each displayed catalog symbol consists of a shape, color, and text. An advanced symbol editor is available that allows you to specify the shape, size, color, and text of each symbol, based on catalog column values. These symbol expressions can be saved for future use.</p> <p>Along with the overlay display, a catalog list is provided in a separate window. It displays the column values for each catalog object. The catalog list can be sorted and filtered, and the catalog display will be automatically updated. Advanced filtering options are available. Catalogs can be loaded and saved as local files in ASCII Starbase format. Each catalog contains header information which can be displayed. The list can be printed separately from the image.</p> <p>An interactive connection between the displayed catalog symbols and the catalog list is provided. When you select one or more rows within the catalog list, the corresponding symbols are highlighted on the image display. Conversely, selecting multiple symbols on the image display will highlight the corresponding rows within the catalog list. Catalog symbols can be converted to regions for use with analysis tasks.</p> <p><b>Filter Option</b></p> <p>The catalog list can be sorted and filtered, and the catalog display will be automatically updated. A filter is conditional expression, when evaluated for each row of the catalog, if true, the row is displayed, and if false, the row is not displayed. The conditional expression can be any valid TCL expression. The value of a column may be indicated with <tt>$&lt;column name&gt;</tt>.</p> <blockquote> <tt>$_RAJ2000&gt;180. &amp;&amp; $_RAJ2000&lt;270.</tt><br> <tt>$Jmag&gt;11</tt><br> <tt>log($Kmag*10)&lt;.3</tt> </blockquote> <p><b>Advanced Symbol Editor</b></p> <p>An advanced symbol editor is available that allows you to specify the shape, size, color, and text of each symbol, based on catalog column values. For each row of the catalog, one or more conditional expressions are evaluated. For the first expression to evaluate true, a given symbol is displayed, with the specified shape, color, size and text properties. As with the filter, the value of a particular column can be indicated as <tt>$&lt;column name&gt;.</tt></p> <p>For the condition entry, the expression you type in is automatically evaluated via TCL <tt>expr</tt> after macro expansion.</p> <blockquote> <tt>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# always</tt><br> <tt>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# never</tt><br> <tt>true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# always</tt><br> <tt>false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# never</tt><br> <tt>$Jmag&gt;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# conditional</tt><br> <tt>sin($Jmag)&gt;.5 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # conditional</tt><br> <tt>[string equal $Class SNR]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# conditional</tt><br> <tt>[regexp {*SNR*} $Class]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# conditional</tt><br> </blockquote> <p>For the size, size2, and angle entries, the expression you type in is also automatically evaluated via TCL <tt>expr</tt> after macro expansion.</p> <blockquote> <tt>2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# value of '2' is used</tt><br> <tt>$Jmag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# value of column Jmag is used</tt><br> <tt>$Jmag/2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# value of column Jmag div 2 is used</tt><br> <tt>(4+2)/3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# value of '2' is used</tt><br> </blockquote> <p>For the text portion, this is not true. It is assumed to be text, unless you explicitly use an <tt>expr </tt>operator.</p> <blockquote> <tt>foo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# will put 'foo' above the symbol</tt><br> <tt>$Jmag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# will put the value of column Jmag above the symbol</tt><br> <tt>(4+2)/3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# will put the text '(4+2)/3' above the symbol</tt><br> <tt>[expr (4+2)/3]&nbsp;&nbsp;# will put the text '2' above the symbol</tt><br> <tt>[expr $Jmag/2.]&nbsp;# will take the value of Jmag and div by 2</tt><br> </blockquote> <p>And finally, one special case for shape = text and text = empty. In this case, the row number is displayed. </p> &nbsp; </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/region.html������������������������������������������������������������������������0000644�0001750�0001750�00000070425�11734375671�014623� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Regions</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> </head> <body text="#000000" vlink="#551a8b" alink="#ff0000" bgcolor="#ffffff" link="#0000ff"> <h3><img alt="" src="../sun.gif" width="100" align="middle" height="98"> Regions</h3> <blockquote> <p>Regions provide a means for marking particular areas of an image for further analysis. Regions may also be used for presentation purposes. DS9 supports a number of region descriptions, each of which may be edited, moved, rotated, displayed, saved and loaded, via the GUI and XPA.</p> <a href="#RegionDescriptions">Region Descriptions</a><br> <a href="#RegionProperties">Region Properties</a><br> <a href="#RegionFileFormat">Region File Format</a><br> <a href="#CompositeRegion">Composite Region</a><br> <a href="#TemplateRegion">Template Region</a><br> <a href="#ExternalRegionFiles">External Region Files</a><br> <p><b> <a name="RegionDescriptions"></a>Region Descriptions</b></p> <p><tt>Circle<br> Usage: circle x y radius<br> </tt></p> <p><tt>Ellipse<br> Usage: ellipse x y radius radius angle<br> </tt></p> <p><tt>Box <br> Usage: box x y width height angle<br> </tt></p> <p><tt>Polygon <br> Usage: polygon x1 y1 x2 y2 x3 y3 ...<br> </tt></p> <p><tt>Point <br> Usage: point x y # point=[circle|box|diamond|cross|x|arrow|boxcircle] [size]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; circle point x y&nbsp;</tt></p> <p><tt>Line <br> Usage: line x1 y1 x2 y2 # line=[0|1] [0|1] </tt></p> <p><tt>Vector <br> Usage: vector x1 y1 length angle # vector=[0|1] </tt></p> <p><tt>Text <br> Usage: text x y # text={Your Text Here}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text x y {Your Text Here} </tt></p> <p><tt>Ruler <br> Usage: ruler x1 y1 x2 y2 # ruler=[pixels|degrees|arcmin|arcsec]</tt></p> <p><tt>Compass <br> Usage: compass x1 y1 length # compass=&lt;coordinate system&gt; &lt;north label&gt; &lt;east label&gt; [0|1] [0|1] </tt></p> <p><tt>Projection <br> Usage: projection x1 y1 x2 y2 width</tt></p> <p><tt>Annulus <br> Usage: annulus x y inner outer n=# <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; annulus x y r1 r2 r3... </tt></p> <p><tt>Ellipse Annulus <br> Usage: ellipse x y r11 r12 r21 r22 n=# [angle]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ellipse x y r11 r12 r21 r22 r31 r32 ... [angle] </tt></p> <p><tt>Box Annulus <br> Usage: box x y w1 h1 w2 h2 [angle] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; box x y w1 h1 w2 h2 w3 h3 ... [angle] </tt></p> <p><tt>Panda <br> Usage: panda x y startangle stopangle nangle inner outer nradius</tt></p> <p><tt>Epanda <br> Usage: epanda x y startangle stopangle nangle inner outer nradius [angle]</tt></p> <p><tt>Bpanda <br> Usage: bpanda x y startangle stopangle nangle inner outer nradius [angle]</tt></p> <p><tt>Composite<br> Usage: # composite x y angle</tt></p> <p><b> <a name="RegionProperties"></a>Region Properties</b></p> <p>Each region has a number of properties associated with the region, which indicates how the region is to be rendered or manipulated. Properties are defined for a region in the comment section of the region description. The exception is the Include/Exclude property. It is set via '+' or '-' preceding the region. In addition, the Line, Point, and Ruler regions have unique properties, not shared by others. Not all properties are available via the GUI or are applicable for all regions. </p> <blockquote> <p><b> Text</b></p> <p>All regions may have text associated with them. Use the text property to set the text. Strings may be quoted with " or ' or {}. For best results, use {}. </p> <tt>Example: circle(100,100,20) # text = {This message has both a " and ' in it}</tt> <p><b> Color</b></p> <p>The color property specifies the color of the region when rendered. The follow 8 colors are supported: </p> <tt>Example: circle(100,100,20) # color = green</tt><br> <p><b>Dash List</b></p> <p>Sets dashed line parameters. This does not render the region in dashed lines.</p> <tt>Example: circle(100,100,20) # dashlist = 8 3</tt><br> <p><b>Width</b></p> <p>Sets the line width used to render the region.</p> <tt>Example: circle(100,100,20) # width = 2</tt><br> <p><b>Font</b></p> <p>The font property specifies the font family, size, weight, and slant of any text to be displayed along with the region. </p> <tt>Example: circle(100,100,20) # font="times 12 bold italic"</tt> <p><b> Can Select</b></p> <p>The Select property specifies if the user is allowed to select (hence, edit) the region via the GUI. For Regions used for catalogs and such, it is desirable that the user is unable to edit, move, or delete the region.<br> </p> <tt>Example: circle(100,100,20) # select = 1</tt><br> <p><b>Can Highlite</b></p> The Highlite property specifies if the edit handles become visible when the region is selected.<br> <tt>Example: circle(100,100,20) # hightlite = 1</tt><br> <p><b>Dash</b></p> <p>Render region using dashed lines using current <tt>dashlist</tt> value.</p> <tt>Example: circle(100,100,20) # dash = 1</tt><br> <p><b>Fixed in Size</b></p> <p>The Fixed in Size property specifies that the region does not change in size as the image magnification factor changes. This allows the user to build complex pointer type regions. </p> <tt>Example: circle(100,100,20) # fixed = 1</tt> <p><b> Can Edit</b></p> <p>The Edit property specifies if the user is allowed to edit the region via the GUI. </p> <tt>Example: circle(100,100,20) # edit = 1</tt> <p><b> Can Move</b></p> <p>The Move property specifies if the user is allowed to move the region via the GUI. </p> <tt>Example: circle(100,100,20) # move = 1</tt> <p><b> Can Rotate</b></p> <p>The Rotate property specifies if the user is allowed to rotate the region via the GUI. </p> <tt>Example: circle(100,100,20) # rotate = 1</tt> <p><b> Can Delete</b></p> <p>The Delete property specifies if the user is allowed to delete the region via the GUI. </p> <tt>Example: circle(100,100,20) # delete = 1</tt> <p><b> Include/Exclude</b></p> <p>The Include/Exclude properties flags the region with a boolean <tt>NOT </tt>for later analysis. Use '+' for include (default), '-' for exclude. </p> <tt>Example: -circle(100,100,20)<br> </tt> <p><b>Source/Background</b></p> <p>The Source/Background properties flag the region for use with other analysis applications. The default is <tt>source</tt></p> <tt>Example: circle(100,100,20) # source<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;circle(200,200,10) # background</tt><br> <p><b>Tag</b></p> <p>All regions may have zero or more tags associated with it, which may be used for grouping and searching. </p> <tt>Example:&nbsp; circle(100,100,20) # tag = {Group 1} tag = {Group 2}</tt> <p><b> Line</b></p> <p>The line region may be rendered with arrows, one at each end. To indicate arrows, use the line property. A '1' indicates an arrow, '0' indicates no arrow. </p> <tt>Example: line(100,100,200,200) # line= 1 1</tt> <p><b> Ruler</b></p> <p>The ruler region may display information in 'pixels', 'degrees', 'arcmin', or 'arcsec'. Use the ruler property to indicate which format to display distances in. </p> <tt>Example: ruler(100,100,200,200) # ruler=arcmin</tt> <p><b> Point</b></p> <p>Point regions have an associated type and size. Use the point property to set the point type. </p> <tt>Example: point(100,100) # point=diamond 31</tt> <p><b> Default Properties</b></p> <p>The default properties are: </p> <blockquote> <tt>text={}</tt> <br> <tt>color=green</tt> <br> <tt>font="helvetica 10 normal roman"</tt> <br> <tt>select=1</tt> <br> <tt>edit=1</tt> <br> <tt>move=1</tt> <br> <tt>delete=1</tt> <br> <tt>highlite=1</tt> <br> <tt>include=1</tt> <br> <tt>fixed=0</tt> </blockquote> </blockquote> <p><b><a name="RegionFileFormat"></a>Region File Format</b></p> <blockquote> <p><b> Syntax</b></p> <p>Region arguments may be separated with either a comma or space. Optional parentheses may be used a the beginning and end of a description. </p> <blockquote> <tt>circle 100 100 10</tt> <br> <tt>circle(100 100 10)</tt> <br> <tt>circle(100,100,10)</tt> </blockquote> <p><b> Comments</b></p> <p>All lines that begin with <tt>#</tt> are comments and will be ignored.</p> <blockquote> <tt># This is a comment</tt> </blockquote> <p><b> Delimiter</b></p> <p>All lines may be delimited with either a new-line or semi-colon. </p> <blockquote> <tt>circle 100 100 10</tt> <br> <tt>ellipse 200 200 20 40 ; box 300 300 20 40</tt> </blockquote> <p><b> Header</b></p> <p>A DS9 region file may start with the following optional header: </p> <blockquote> <tt># Region file format: DS9 version 4.0</tt> </blockquote> <p><b> Global Properties</b></p> <p>Global properties affect all regions unless a local property is specified. The <tt>global</tt> keyword is first, followed by a list of keyword = value pairs. Multiple global property lines may be used within a region file. </p> <blockquote> <tt>global color=green font="helvetica 10 normal roman" edit=1 move=1 delete=1 highlite=1 include=1 wcs=wcs</tt> </blockquote> <p><b> Local Properties</b></p> <p>Local properties start with a # after a region description and only affect the region it is specified with. </p> <blockquote> <tt>physical;circle(504,513,20) # color=red text={This is a Circle}</tt> </blockquote> <p><b> Coordinate Systems</b></p> <p>For each region, it is important to specify the coordinate system used to interpret the region, i.e., to set the context in which the position and size values are interpreted. For this purpose, the following keywords are recognized: </p> <blockquote> <tt>PHYSICAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pixel coords of original file using LTM/LTV</tt> <br> <tt>IMAGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pixel coords of current file</tt> <br> <tt>FK4, B1950&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # sky coordinate systems</tt> <br> <tt>FK5, J2000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # sky coordinate systems</tt> <br> <tt>GALACTIC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # sky coordinate systems</tt> <br> <tt>ECLIPTIC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # sky coordinate systems</tt> <br> <tt>ICRS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # currently same as J2000</tt> <br> <tt>LINEAR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # linear wcs as defined in file</tt> <br> <tt>AMPLIFIER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # mosaic coords of original file using ATM/ATV</tt> <br> <tt>DETECTOR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # mosaic coords of original file usingDTM/DTV</tt> </blockquote> <p><b> Mosaic Images</b></p> <p>While some coordinate systems are unique across mosaic images, others coordinate systems, such as <tt>image</tt>, or <tt>physical</tt> , are valid on a per segment basis. In this case, use <tt>tile</tt> to specify which header to use in all coordinate conversions. The default is the first header, or <tt>tile 1</tt>. </p> <tt>Example: tile 2;fk5;point(100,100)</tt> <p><b> Multiple WCS</b></p> <p>If an image has multiple wcs's defined, use <tt>wcs#</tt> to specify which wcs to use for all wcs references. Valid values are <tt>wcs, wcsa, wcsb, wcsc... wcsz.</tt><br> <tt>Example: wcsa;linear;point(100,100) # point=diamond</tt></p> <p><b> Specifying Positions and Sizes</b></p> <p>The arguments to region shapes can be floats or integers describing positions and sizes. They can be specified as pure numbers or using explicit formatting directives: </p> <blockquote> <p><b>position arguments</b> </p> <tt>[num]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # context-dependent (see below)</tt> <br> <tt>[num]d&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # degrees</tt> <br> <tt>[num]r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radians</tt> <br> <tt>[num]p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # physical pixels</tt> <br> <tt>[num]i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # image pixels</tt> <br> <tt>[num]:[num]:[num]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # hms for 'odd' position arguments</tt> <br> <tt>[num]:[num]:[num]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # dms for 'even' position arguments</tt> <br> <tt>[num]h[num]m[num]s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # explicit hms</tt> <br> <tt>[num]d[num]m[num]s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # explicit dms</tt> <p><b>size arguments</b> </p> <tt>[num]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # context-dependent (see below)</tt> <br> <tt>[num]"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # arc sec</tt> <br> <tt>[num]'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # arc min</tt> <br> <tt>[num]d&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # degrees</tt> <br> <tt>[num]r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # radians</tt> <br> <tt>[num]p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # physical pixels</tt> <br> <tt>[num]i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # image pixels</tt> <p></p> </blockquote> <p>When a "pure number" (i.e. one without a format directive such as 'd' for 'degrees') is specified, its interpretation depends on the context defined by the 'coordsys' keyword. In general, the rule is: </p> <p><i>All pure numbers have implied units corresponding to the current coordinate system.</i> </p> <p>If no such system is explicitly specified, the default system is implicitly assumed to be <tt>PHYSICAL</tt>. In practice this means that for <tt>IMAGE</tt> and <tt>PHYSICAL</tt> systems, pure numbers are pixels. Otherwise, for all systems other than linear, pure numbers are degrees. For <tt>LINEAR</tt> systems, pure numbers are in the units of the linear system. This rule covers both positions and sizes. The input values to each shape can be specified in several coordinate systems including: </p> <blockquote> <tt>IMAGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pixel coords of current file</tt> <br> <br> <tt>LINEAR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # linear wcs as defined in file</tt> <p><tt>FK4, B1950&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # sky coordinate systems</tt> <br> <tt>FK5, J2000</tt> <br> <tt>GALACTIC</tt> <br> <tt>ECLIPTIC</tt> <br> <tt>ICRS</tt> <br> <tt>PHYSICAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pixel coords of original file using LTM/LTV</tt> <br> <tt>AMPLIFIER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # mosaic coords of original file using ATM/ATV</tt> <br> <tt>DETECTOR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # mosaic coords of original file using DTM/DTV</tt><br> <br> <tt>WCS,WCSA-WCSZ&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; # specify which WCS system to be used for <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # linear and sky coordinate systems<br> </tt></p> </blockquote> <p>If no coordinate system is specified, <tt>PHYSICAL</tt> is assumed. <tt>PHYSICAL</tt> or a World Coordinate System such as <tt>J2000</tt> is preferred and most general. The coordinate system specifier should appear at the beginning of the region description, on a separate line (in a file), or followed by a new-line or semicolon; e.g., </p> <blockquote> <tt>image; circle 100 100 10</tt> <br> <tt>physical; ellipse 200 200 10 20</tt> <br> <tt>fk5; point 30 50</tt><br> <tt>wcsa; fk4; point 202 47</tt><br> <tt>wcsp; linear; point 100 100</tt><br> </blockquote> <p>The use of celestial input units automatically implies WORLD coordinates of the reference image. Thus, if the world coordinate system of the reference image is <tt>J2000</tt>, then</p> <blockquote> <tt>circle 10:10:0 20:22:0 3'</tt> </blockquote> <p>is equivalent to: <br> </p> <blockquote> <tt>j2000; circle 10:10:0 20:22:0 3'</tt> </blockquote> <p>Note that by using units as described above, you may mix coordinate systems within a region specifier; e.g., </p> <blockquote> <tt>physical; circle 6500 9320 3'<br> </tt></blockquote> <p>Note that, for regions which accept a rotation angle such as: </p> <blockquote> <tt>ellipse (x, y, r1, r2, angle)<br> box(x, y, w, h, angle)</tt> <p></p> </blockquote> <p>the angle is relative to the specified coordinate system. In particular, if the region is specified in WCS coordinates, the angle is related to the WCS system, not x/y image coordinate axis. For WCS systems with no rotation, this obviously is not an issue. However, some images do define an implicit rotation (e.g., by using a non-zero CROTA value in the WCS parameters) and for these images, the angle will be relative to the WCS axes. In such case, a region specification such as:</p> <blockquote> <tt>fk4;ellipse(22:59:43.985, +58:45:26.92,320", 160", 30)</tt> </blockquote> <p>will not, in general, be the same region specified as:</p> <blockquote> <tt>physical;ellipse(465, 578, 40, 20, 30)</tt> </blockquote> <p>even when positions and sizes match. The angle is relative to WCS axes in the first case, and relative to physical x,y axes in the second.</p> </blockquote> <p><b><a name="CompositeRegion"></a>Composite Region</b></p> <p>A Composite Region is a region which is a collection of other regions, which share common properties. A composite region is composed of a center point and a rotation angle, of which all its members are rendered in reference to. A composite region is defined by the # composite x y angle declaration followed by a number of regions who are or'd together. A composite region is manipulated as a single region within ds9. A composite region maybe created from the current selection of regions by selecting the Create Composite Region menu option. Likewise, a composite region can be dissolved by selecting the Dissolve Composite Region menu option.</p> <p><b> <a name="TemplateRegion"></a>Template Region</b></p> <p>A Template Region is a special form of a region which is saved in a special wcs coordinate system WCS0. WCS0 indicates that the ra and dec values are relative to the current WCS location, not absolute. A template region can be loaded at any location into any fits image which contains a valid wcs. For example, a user may create a series of regions, which represent an instrument template. Then, by selecting the Save As Template menu option, a template region saved. The user may now load this templated into any other fits image which contains a valid WCS. </p> <p><b> <a name="ExternalRegionFiles"></a>External Region Files</b></p> <p>DS9 can read and write a number of region file formats. Not all formats support all the functionality of DS9 regions. Therefore, the user may loose some information when writing and then reading back from a region file in a format other that DS9. On output, the regions <a href="mregion.html#FileFormat">File Format</a> menu or the <a href="xpa.html#regions">XPA</a> regions point is used specify the output coordinate system and format. On input, the menu or xpa point is used only for the <tt>X Y </tt>format. For all other formats, the input coordinate system is specified in the regions file itself. </p> <blockquote> <p><b> <a name="FUNTools"></a><a href="http://hea-www.harvard.edu/RD/funtools/regions.html">Funtools</a></b><tt></tt><br> </p> <blockquote> <tt>TEXT is ignored<br> </tt> <tt>VECTOR is ignored</tt> <br> <tt>PROJECTION is ignored</tt><tt></tt><br> <tt>RULER is ignored</tt><br> <tt>COMPASS is ignored<br> FIELD is ignored<br> PIE is ignored<br> </tt> <tt> All properties are ignored</tt><br> </blockquote> <a name="Ciao"></a>CIAO <blockquote> <tt> All point regions are translated as POINT</tt><br> <tt>BOX is translated as ROTBOX<br> </tt> <tt>LINE is ignored</tt><br> <tt>VECTOR is ignored</tt> <br> <tt>RULER is ignored</tt><br> <tt>COMPASS is ignored</tt><br> <tt>TEXT is ignored</tt><tt></tt><br> <tt>PROJECTION is ignored</tt><tt></tt><br> <tt>ELLIPSE ANNULUS is ignored</tt><br> <tt>BOX ANNULUS is ignored</tt><br> <tt>PANDA is translated as PIE</tt><br> <tt>EPANDA is ignored</tt><br> <tt>BPANDA is ignored</tt><br> <tt> All properties are ignored</tt><br> </blockquote> <a name="SAOimage"></a><a href="http://tdc-www.harvard.edu/software/saoimage/saoimage.region.html">SAOimage</a> <blockquote> <tt> All point regions are translated as </tt><tt>POINT</tt><tt></tt><br> <tt>LINE is ignored</tt><br> <tt>VECTOR is ignored</tt> <br> <tt>TEXT is ignored</tt><br> <tt>PROJECTION ignored</tt><br> <tt>PROJECTION3D is ignored</tt><br> <tt>RULER is ignored</tt><br> <tt>COMPASS is ignored</tt><br> <tt>PANDA is ignored</tt><br> <tt>EPANDA is ignored</tt><br> <tt>BPANDA is ignored</tt><br> <tt> All properties are ignored</tt><br> </blockquote> <a name="IRAFPROS"></a>IRAF PROS <blockquote> <tt> All point regions are translated as </tt><tt>POINT</tt><tt></tt><br> <tt>LINE is ignored</tt><br> <tt>VECTOR is ignored</tt> <br> <tt>TEXT is ignored</tt><br> <tt>RULER is ignored</tt><br> <tt>COMPASS is ignored</tt><br> <tt>PROJECTION ignored</tt><br> <tt>PROJECTION3D is ignored</tt><br> <tt>PANDA is ignored</tt><br> <tt>EPANDA is ignored</tt><br> <tt>BPANDA is ignored</tt><br> <tt> All properties are ignored</tt><br> </blockquote> <a name="FITSREGIONBinaryTable"></a>FITS REGION Binary Table <blockquote> <tt> Read Only. DS9 currently can not write in this format.</tt><br> <tt>POINT is translated into BOX CIRCLE POINT</tt><br> <tt>ROTBOX is translated into BOX</tt><br> <tt>RECTANGLE is translated into BOX</tt><br> <tt>ROTRECTANGLE is translated into a BOX</tt><br> <tt>PIE is translated into PANDA</tt><br> <tt> The follow regions are not supported</tt> <blockquote> <tt>ELLIPTANNULUS</tt><br> <tt>SECTOR</tt><br> <tt>DIAMOND</tt><br> <tt>RHOMBUS</tt><br> <tt>ROTDIAMOND</tt><br> <tt>ROTRHOMBUS</tt><br> </blockquote> </blockquote> <a name="XY"></a>X Y <br> <p>This format consists of a number of coordinate pairs, one per line. The coordinate format for both input and output is specified via the Save Regions Parameters menu or <a href="xpa.html#regions">XPA</a> regions point. The first two coordinates are read, the rest of the line is ignored. The comment character '#' may be used at the beginning of line and the line is ignored. This format is very useful for reading in coordinates from other external analysis programs, such as IRAF. </p> <blockquote> <tt>Example:</tt> <tt># this is a comment</tt> <br> <tt>physical # this overrides the specified coordinate system</tt><br> <tt>300 300</tt> <br> <tt>400 400 # this is a comment</tt> <br> </blockquote> </blockquote> </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/backup.html������������������������������������������������������������������������0000644�0001750�0001750�00000005350�11763212355�014567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Backup</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Backup and Restore</h3> <blockquote> <p>DS9 now supports Backup and Restore. When a backup is invoked, DS9 will save in a backup save set all files needed to restore DS9 to that state, including geometry, data files, colormaps, catalogs, contours, and regions.<br> </p> <p><b>Backup Save Set</b></p> <p>A backup save set consists of a text file, called a backup script, and an optional directory, which will contain auxiliary data files needed to restore DS9 to a previous state. The backup file and the auxiliary directory maybe moved across file systems, or even platforms, but must remain together in the same directory. <br> </p> <p><b>Image data files</b></p> <p>By default, all data image files are save within the backup save set. However, the user has the option, via the Preferences, to only save only an absolute pathname to the data file, and not the data file itself. This option will dramatically reduce the size of a backup save set, but will restrict the usage to a particular file system and platform.<br> </p> <p>Image files that have been loaded into DS9 via XPA, SAMP, or from URL will always be saved into the save set.<br> </p> <p><b>Caveats</b></p> <p>There are several caveats in the usage of Backup and Restore. In particular:<br> </p> <blockquote> <p> <tt>Currently, there is no support for masks.<br> External Analysis menus will not be saved.<br> Plot Tool windows will not be saved.<br> IIS frames (IRAF) will not be saved.<br> SAMP and XPA sessions will not be saved.</tt></p> </blockquote> <p>And finally, if the image data had been loaded into DS9 via XPA, SAMP, or from a URL, the following complex load operations are not supported:</p> <blockquote> <tt>Open Mosaic IRAF Image<br> Open Mosaic IRAF Segment Open Mosaic WCS Image<br> Open Mosaic WCS Segment Open Mosaic WFPC2 Open RGB Fits Image Open RGB Fits Cube Open RGB Array Open Multi Ext Data Cube Open Multi Ext Multiple Frames </tt></blockquote> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/bin.html���������������������������������������������������������������������������0000644�0001750�0001750�00000004036�12071072130�014056� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Bin</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Binning</h3> <blockquote> <p>To create an image from a FITS Bin Table, the user needs to specify a binning factor, binning buffer size, and the binning function.<br> </p> <p>The Binning (or Block) Factor is defined as the following: A value greater or equal to zero. This value indicates the number of pixel values that will fall into a particular bin.<br> </p> <p>The Bin Buffer Size is overall size of the image generated. This has no relation to min and max values of the columns used to create the image. <br> </p> <p>The Bin Function is defined as the following: Average - all pixel values that fall into one pixel bin are averaged. Sum - all pixel values that fall into one pixel bin are summed.<br> </p> <p>Bin to Fit Frame will calculate a bin block factor as a power of 2 that will allow the entire data space to be displayed in the current frame. </p> <p>By default, DS9 will bin about the center of the image. To determine the center of the image, DS9 will look for the following keywords in order:</p> <blockquote> <tt>TDMIN/TDMAX<br> TLMIN/TLMAX<br> TALEN<br> AXLEN</tt> </blockquote> <p>If no valid keywords are found, DS9 will define the center as the middle of the possible data space based on the coordinate data type.</p> <br> <p><br> </p> <blockquote> </blockquote> <p><br> </p> <br> </blockquote> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/prefs.html�������������������������������������������������������������������������0000644�0001750�0001750�00000003145�11426312317�014434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Preferences</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ff" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Preferences</h3> <blockquote> <p>Allows the user to customize the appearance and behavior of the GUI . Please note: some preferences take effect immediately, while others require DS9 to be restarted. Changes to the preferences can be saved by selecting the <tt>Save</tt> button<tt>. </tt>Use the <tt>Clear Preferences </tt>button to restore default settings.</p> <p>User preferences are stored in <tt>.ds9.prf</tt>. DO NOT EDIT this file, since it will be deleted or overwritten by DS9. At startup time, DS9 will search for a preferences file in the following directories, in order, <tt>./, $HOME, /usr/local/lib, /opt/local/lib</tt>. </p> <p>Users may have several different preference files. DS9 looks for a preference file with its own name. By default, if the application is named <tt>ds9</tt>, it will look for <tt>.ds9.prf.</tt> However, if the DS9 application is named <tt>foo</tt>, then DS9 will look for <tt>.foo.prf.</tt> In this manner, the user can have several predefined preference files that are activated by invoking DS9 with a different application names. </p> </blockquote> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/keyboard.html����������������������������������������������������������������������0000644�0001750�0001750�00000021573�11763203427�015127� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Mouse and Keyboard</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Mouse and Keyboard</h3> <blockquote> <p><b> Mouse Buttons</b></p> <p>The following table contains the event bindings for the mouse buttons. </p> <center> <table nosave="" border="1" width="75%"> <tbody> <tr> <td> <center>Mouse Button</center> </td> <td> <center>Description</center> </td> </tr> <tr> <td><font face="Courier New,Courier">Button 1</font></td> <td>Depends on current MODE, which may be selected by the <a href="medit.html">EDIT</a> menu option.<br> In Crosshair mode, will move current crosshair.<br> In Colorbar mode, will change contrast and bias of colormap.<br> In Pan mode, will move or pan to clicked location.<br> In Zoom mode, will zoom about clicked location.<br> In Rotate mode, will rotate image about center.<br> In Crop mode, will select 2-D crop region. For 3-D <i>Shift-click</i> will edit front clip plane, <i>Control-click</i> will edit back clip plane.<br> In Catalog mode, will select catalog regions.<br> In examine mode, will follow IRAF examine protocol.<br> </td> </tr> <tr> <td><font face="Courier New,Courier">Button 2</font></td> <td>Pan mode: will move or pan to clicked location. Behavior depends on the PAN preference settings.</td> </tr> <tr> <td><font face="Courier New,Courier">Button 3</font></td> <td>Colorbar mode: will change the contrast and bias of the colormap.</td> </tr> </tbody> </table> </center> <p><b>Greek and other special characters.</b> </p> <p>The concept of a separate <tt>SYMBOL</tt> font is no longer implemented with the latest OS font and scripting support, especially with scalable anti-alias fonts such as Xft for Linux. Most newer fonts (if not all) now have greek characters as part of the font. The greek characters start at unicode \u0391 for 'A' and \u03b1 for 'a'. Each OS has a tool used to build and copy a string of characters. Then use the Edit:Paste menu of DS9 to insert the character string.</p> <blockquote> <p>Linux- Gnome: <b>gucharmap<br> </b>Linux- KDE: <b>kcharselect<br> </b>MacOSX: <b>Character Viewer</b> (Select <tt>Edit:Special Characters</tt>) Now click and drag the characters to a terminal window. Then select the string and select <tt>Edit:Copy</tt>.<br> Windows: <b>Character Map</b> (from <tt>Start</tt> button, select <tt>All Programs</tt>, <tt>Accessories</tt>, <tt>System Tools</tt> and then <tt>Character Map</tt>)</p> </blockquote> <p><b>Keyboard Shortcuts</b></p> <p>The following table contains the list of keyboard shortcuts and the resulting action taken.&nbsp; </p> <center> <table nosave="" border="1" width="75%"> <tbody> <tr> <td align="center"> Key Stroke </td> <td> <center>Description</center> </td> </tr> <tr> <td align="center"><tt>TAB</tt></td> <td><font face="Courier New,Courier">G</font>oto next frame</td> </tr> <tr> <td align="center" valign="top"><tt>Shift-TAB</tt><br> </td> <td valign="top">Goto previous frame<br> </td> </tr> <tr> <td align="center"><tt>DELETE</tt></td> <td>Deletes selected regions</td> </tr> <tr> <td align="center">c<br> </td> <td>Print Mouse Coordinates and Pixel value.</td> </tr> <tr> <td align="center">f<br> </td> <td>Toggles Infobox freeze</td> </tr> <tr> <td align="center">i<br> </td> <td>Set include property for region</td> </tr> <tr> <td align="center">e<br> </td> <td>Set exclude property for region</td> </tr> <tr> <td align="center">s<br> </td> <td>Set source property for region</td> </tr> <tr> <td align="center">b<br> </td> <td>Set background property for region</td> </tr> <tr> <td align="center">g<br> </td> <td>Create a new group</td> </tr> <tr> <td align="center"><tt>Shift-g</tt></td> <td>Create a new group with default name</td> </tr> <tr> <td align="center"><tt>+</tt></td> <td>Goto next 3D Fits Slice</td> </tr> <tr> <td align="center"><tt>-</tt></td> <td>Goto previous 3D Fits Slice</td> </tr> <tr> <td align="center"><tt>Up Arrow<br> k<br> </tt></td> <td>Will move selected regions up one pixel. <br> In Pointer mode, will move the cursor up one pixel. <br> In Crosshair mode, will move the crosshair up one pixel. <br> In Pan mode, will pan the image up one pixel.</td> </tr> <tr nosave=""> <td align="center"><tt>Right</tt><font face="Courier New,Courier"> </font><tt>Arrow<br> l<br> </tt></td> <td nosave="">Will move selected regions to the right one pixel. <br> In Pointer mode, will move the cursor to the right one pixel. <br> In Crosshair mode, will move the crosshair to the right one pixel. <br> In Pan mode, will pan the image to the right one pixel.</td> </tr> <tr> <td align="center"><tt>Left</tt><font face="Courier New,Courier"> </font><tt>Arrow<br> h<br> </tt></td> <td>Will move selected regions to the left one pixel. <br> In Pointer mode, will move the cursor to the left one pixel. <br> In Crosshair mode, will move the crosshair to the left one pixel. <br> In Pan mode, will pan the image to the left one pixel.</td> </tr> <tr> <td align="center"><tt>Down</tt><font face="Courier New,Courier"> </font><tt>Arrow<br> j<br> </tt></td> <td>Will move selected regions down one pixel. <br> In Pointer mode, will move the cursor up down one pixel. <br> In Crosshair mode, will also move the crosshair down one pixel. <br> In Pan mode, will pan the image down one pixel.</td> </tr> <tr> <td align="center"><tt>Shift</tt><font face="Courier New,Courier">-</font><tt>Drag</tt></td> <td>In Pointer mode, will select all regions within the indicated region.<br> In Crop mode, for 3D frame, will move front crop plane forward.<br> </td> </tr> <tr> <td align="center"><tt>Control-Drag</tt></td> <td>In Poiner mode, on selected <tt>ANNULUS</tt> Regions, will create new radii.<br> In Crop mode, for 3D frame, will move back crop plane backward.<br> </td> </tr> <tr> <td align="center" valign="top"><tt>Command-`</tt><br> </td> <td valign="top">Rotate thur all open windows<br> </td> </tr> </tbody> </table> </center> </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/analysis.html����������������������������������������������������������������������0000644�0001750�0001750�00000112216�11710605202�015132� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Analysis</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Analysis</h3> <blockquote> <p>Each file type known to DS9 can have user-defined analysis commands associated with it. These analysis commands are defined at start-up time , or loaded by the user, by means of an ASCII analysis description file. The analysis commands are available for execution, either via the <i>Analysis Menu </i>or the XPA point <i>Analysis</i>. In addition, commands may be <i>bound</i> to events, such as keystrokes or mouse clicks. This type of command is called a bind command.<br> </p> <p>DS9 searches for an analysis file named <tt>ds9.ans</tt> or <tt>ds9.analysis</tt> in the current directory and <tt>$HOME</tt> to be loaded at startup. In addition, DS9 will search the following directories for any analysis files to be loaded at startup in the form of <tt>*.ds9</tt>: the current directory, <tt>$HOME/bin</tt>, <tt>/usr/local/bin</tt>, <tt>/opt/local/bin</tt>, and <tt>/soft/saord/bin</tt>. Finally, the user may specify analysis files to be loaded at startup in the preferences analysis panel. The user may also load or clear current analysis commands via command line options or the <i>Analysis m</i>enu<i>.</i></p> <p>When activated, either from the menu, XPA, or bound event, an analysis command first is macro-expanded to fill in user-defined arguments and then is executed externally. Results may be displayed in a separate text window, plot window, or in a image frame. </p> <a href="#Syntax">Syntax</a> <br> <a href="#CommandType">Command Type</a> <br> <a href="#Macros">Macros</a> <br> <a href="#Help">Help</a> <br> <a href="#Web"> </a><a href="#Parameters">Parameters</a> <br> <a href="#HierarchicalMenus">Hierarchical Menus</a> <br> <a href="#Sample">Sample</a> <p><b><a name="Syntax"></a>Syntax</b></p> The analysis file that defines the known analysis commands consists of one or more file descriptors, each of which has the following format: <blockquote> <tt>Menu label to be used</tt> <br> <tt>A space separated list of file templates</tt> <br> <tt>Command type [menu | bind &lt;event&gt;]</tt> <br> <tt>The command line for the analysis program</tt> </blockquote> <p>Task names may contain space characters. All lines may be indented. Also, the '#' character is a comment character. A separator can be inserted in the menu by specifying the following sequence '---'.</p> <tt>Example:</tt> <blockquote> <tt># this will insert a menu separator</tt> <br> <tt>---</tt> </blockquote> <p><b><a name="CommandType"></a>Command Type</b></p> <p>The third line indicates the type of command. </p> <blockquote> <p><b>menu</b></p> <p>A <tt>menu</tt> command creates an menu option under the <i>Analysis </i>menu option, and can be invoked by the user via the GUI or XPA.</p> <tt>Example:</tt> <blockquote> <tt># Menu command example</tt><br> <tt>My Analysis Task</tt><br> <tt> </tt><tt>*.fits</tt> <br> <tt>menu</tt> <br> <tt>$data | doit | $text</tt> </blockquote> <p><b>bind</b></p> <p>A <tt>bind</tt> command is a command that is bound to an event. When the event occurs, the command is executed. Types of events available include all TK events, including all <i>keystrokes</i> and <i>mouse clicks.</i> If a command is bound to an event other that a <i>keystroke</i>, care must be taken to not to interfere with other internal DS9 events. </p> <p>To bind to a key stroke, use the following command type:</p> <blockquote> <tt>bind &lt;keystroke&gt; </tt><br> </blockquote> <tt>Example:</tt> <blockquote> <tt># Bind command example</tt><br> <tt>Print coordinates</tt><br> <tt>*.fits</tt><br> <tt>bind x</tt><br> <tt>echo "$x $y" | $text</tt><br> </blockquote> <p><b>web</b></p> <p>A <tt>web</tt> command allows the user to invoke the internal web browser from the analysis menu.</p> <tt>Example:</tt> <blockquote> <tt> # web command example<br> HTTP based<br> *<br> web<br> http://hea-www.harvard.edu/RD/ds9/ref/index.html<br> <br> File based<br> *<br> web<br> file:/home/joye/index.html<br> </tt> </blockquote> </blockquote> <p><b><a name="Macros"></a>Macros</b></p> <p>The following macros are macro-expanded to fill in user-defined arguments before the command is executed. Strings that contain $&lt;macroname&gt; that user does not want to be expanded may be escaped by using $$&lt;macroname&gt;. All strings that contain $&lt;string&gt; &nbsp;that are not a macro name will not be affected.</p> <p>For example:</p> <blockquote> <tt>echo "$$data $foo" | $text</tt><br> </blockquote> <p>will display a text dialog that contains "$data $foo"</p> <p><b>$width<br> $height<br> $depth</b></p> <p>Substitute the width, height, or depth of the data file in the command line. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $width</tt><br> <tt>&nbsp;&nbsp;&nbsp; $height</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "$width $height $depth" | $text</tt> <br> <p><b>$bitpix</b></p> <p>Substitute the bitpix of the data file in the command line. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $bitpix</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "$bitpix" | $text</tt> <p><b>$data</b></p> <p>Data from the current frame becomes the input data to the command string. This data is in the form of a FITS image. This macro can only used at the beginning of the command string. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $data</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $data | dosomething | $text</tt> <p><b>$entry</b></p> <p>Display an entry modal dialog. The returned string is substituted. If <tt>cancel</tt> is selected, the command line is not executed. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $entry(&lt;message&gt;)</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "$entry(Enter something here)" | $text</tt> <p><b>$env</b></p> <p>Substitute the value of a shell environment variable. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $env(&lt;shell variable&gt;)</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "$env(PATH)" | $text</tt> <p><b>$filedialog</b></p> <p>Display the standard file dialog. Substitutes the returned pathname. Argument specifies if an open file or save file dialog is invoked.</p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $filedialog([open|save])</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "$filedialog(open)" | $text</tt><br> <p><b>$filename</b></p> <p>Substitute the filename of the data file in the command line. A full filename includes any absolute or relative path. A root filename contains no path. A (2D) subsection defines a subimage from <tt>xmin,ymin</tt> to <tt>xmax,ymax</tt>. For Frame3D, a 2D subsection will also include the current slice (PLANE=) parameter if not 1. A 3D subsection defines a subimage from <tt>xmin,ymin,zmin</tt> to <tt>xmax,ymax,zmax</tt> and no PLANE parameter.<br> </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $filename # filename with extname, (2d) subsections, filters</tt><br> <tt>&nbsp;&nbsp;&nbsp; $filename(root|root,base) # root filename with </tt><tt>with extname, </tt><tt>no subsections, no filters)</tt> <br> <tt>&nbsp; &nbsp; $filename(full|full,base) # full filename </tt><tt>with extname, </tt><tt>no subsections, no filters)</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $filename(root,3d) # root filename </tt><tt>with extname,</tt><tt> 3d subsections, filters)</tt> <br> <tt>&nbsp; &nbsp; $filename(full,3d) # full filename </tt><tt>with extname,</tt><tt> 3d subsections, filters)</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; dosomething $filename | $text</tt> <br> <tt>&nbsp;&nbsp;&nbsp; dosomething $filename(root) | $text<br> </tt><tt>&nbsp;&nbsp;&nbsp; dosomething $filename(full,3d) | $text</tt> <br> <p><b>$filename[$regions]</b></p> <p>Combination of <tt>$filename </tt>and <tt>$regions </tt>macros. Generates a series of filenames, each with a region. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $filename[$regions]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $filename[$regions(&lt;options&gt;)]</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; dosomething $filename[$regions] | $text</tt> <p><b>$geturl</b></p> <p>This macro differs from all other macros, including $<tt>url</tt>, in that no subprocess pipe is created. Only HTTP is supported. The contents of the url are retrieved and sent to $<tt>text</tt>, $<tt>plot</tt>, or $<tt>image.</tt> No other processing is allowed. The primary purpose of this macro is to support external analysis for the Windows platform, which has no subprocess support. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $geturl(http://&lt;hostname&gt;:&lt;port&gt;/&lt;query&gt;)</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $geturl(http://foo.bar.edu/foo.html) | $text</tt><br> <p><b>$image</b></p> <p>The resulting image data is display in a DS9 frame. This macro should be the last macro of a command line. Optional parameter indicates if a new frame and what type of frame is created for the new data. The macro is removed from the command line before execution. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $image</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $image([new|rgb|3d|current])</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; doit | $image(new)</tt> <p><b>$message</b></p> <p>Display a message dialog box, with option buttons.&nbsp; After displaying the message, the macro is removed from the command line before execution. If <tt>cancel</tt> or <tt>no</tt> is selected, the command line is not executed. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $message(&lt;message&gt;)</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $message([ok|okcancel|yesno],&lt;message&gt;)</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $message(okcancel,This is a Message)| doit | $text</tt> <p><b>$null</b></p> <p>Expect no output or results from analysis task. Note: no error message will be returned if the analysis task fails to execute correctly. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $null</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo "Hello, world" &gt; foo | $null</tt> <p><b>$pan</b></p> <p>Substitute current pan location of the particular data file are returned. The default coordinate system is <tt>physical</tt>. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $pan<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $pan(&lt;coordinate system&gt;,&lt;format&gt;)</tt> <br> <p>where:</p> <tt>&nbsp;&nbsp;&nbsp; coordinate system = [image|physical|detector|amplifier|wcs|wcsa...wcsz]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky frame&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [fk4|fk5|icrs|galactic|ecliptic]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky format&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [hms|sexagesimal|degrees]</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo $pan(fk5,sexagesimal) | $text</tt><br> <p><b>$plot</b></p> <p>Display data in plot window. This macro should be the last macro of a command line. The data is read via <tt>STDIN</tt> and consist of a pair of coordinates, with option error values. (<tt>xy, xyex, xyey, xyexe</tt>y) Default dimension is <tt>xy.</tt> The macro is removed from the command line before execution. </p> <p>For <tt>$plot(stdin)</tt> only: </p> <p>The title, x axis label, and y axis label are assumed to be on the first line of input, delimited with a new-line. However, if the data starts with $<tt>BEGINTEXT</tt>, all text between $<tt>BEGINTEXT</tt> and $<tt>ENDTEXT</tt> will be removed from the data and displayed in a separate text dialog window, with the remaining data, including the title, x axis label, and y axis label, will be displayed in a plot window. Furthermore, if the data contains the string $<tt>ERROR,</tt> an error is assumed to have occurred and a text dialog window is displayed only. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $plot</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $plot(,,,)</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $plot(&lt;title&gt;,&lt;x axis label&gt;,&lt;y axis label&gt;,[xy|xyex|xyey|xyexey])</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $plot(stdin)</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; doit | $plot(This is aTitle,X Axis,Y Axis)<br> </tt> <tt>&nbsp;&nbsp;&nbsp; doit | $plot(stdin)</tt> <p><b>$regions</b></p> <p>Substitute region definition in specified region format, coordinate system, and coordinate format. The default coordinate system is <tt>physical</tt>, default coordinate format <tt>degrees</tt>, and default region format <tt>DS9</tt>. Arguments may appear in any order, as long as they are separated by ',' and no spaces. If one or&nbsp; more properties are specified, only regions with all of the specified properties will be substituted. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $regions</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $regions(&lt;options&gt;)</tt> <p>where options are one of the following: </p> <tt>&nbsp;&nbsp;&nbsp; regions format&nbsp;&nbsp;&nbsp; = [ds9|ciao|saotng|saoimage|pros|xy]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [include|exclude|source|background]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; coordinate system = [image|physical|detector|amplifier|wcs]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky frame&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [fk4|fk5|icrs|galactic|ecliptic]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky format&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [sexagesimal|degrees]</tt> <p>also, the old <i>SAOTNG</i> formats are also supported: </p> <tt>&nbsp;&nbsp;&nbsp; $regions_pixels</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $regions_degrees</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $regions_hms</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $include_regions</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $include_regions_pixels</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $include_regions_degrees</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $include_regions_hms</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $exclude_regions</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $exclude_regions_pixels</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $exclude_regions_degrees</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $exclude_regions_hms<br> </tt> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; dosomething $regions | $text</tt> <br> <tt>&nbsp;&nbsp;&nbsp; dosomething $regions(pros) | $text</tt> <br> <tt>&nbsp;&nbsp;&nbsp; dosomething $regions(source,wcs,fk5) | $text</tt> <br> <tt>&nbsp;&nbsp;&nbsp; dosomething $regions(saotng,background,exclude,ecliptic,sexagesimal) | $text</tt> <p><b>$text</b></p> <p>Display text in a text dialog window. This macro should be the last macro of a command line. To display text from only STDOUT use '|' as the pipe command. To display text from both STDOUT and STDERR, use '|&amp;' as the pipe command. No parameters are required. The macro is removed from the command line before execution. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $text</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; doit | $text # stdout<br> &nbsp;&nbsp;&nbsp; doit |&amp; $text # stdout and stderr<br> </tt> <p><b>$url</b></p> <p>URLs are processed and stored in a temporary file. Only HTTP and anonymous FTP are supported. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $url(http://&lt;hostname&gt;:&lt;port&gt;/&lt;query&gt;)</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $url(ftp://&lt;hostname&gt;/&lt;filename&gt;)</tt><br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $url(http://legacy.gsfc.nasa.gov/rosat/data/p000s26b.img.Z) | uncompress | $image</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $url(ftp://legacy.gsfc.nasa.gov/rosat/data/hri/images/rh100193_img.fits) | $image<br> </tt> <p><b>$vo_method</b></p> <p>Returns the vo method. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $vo_method</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo '$vo_method' | $text</tt><br> <p><b>$value<br> </b></p> <p>Substitute the value at the location of the cursor of an bind event.<br> </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $value<br> <br> Example:<br> &nbsp;&nbsp;&nbsp; echo "$value" | $text</tt><br> <p><b>$x<br> $y<br> $z<br> </b></p> <p>Substitute coordinates of an bind event. When a bind event is triggered, the <i>x,y </i>coordinates of the mouse of the particular data file are returned. The default coordinate system is <tt>physical</tt>. This macro is only available for bind commands. For datacubes, the z coordinate is returned based on the current slice selected.<br> </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $x</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $x(&lt;coordinate system&gt;,&lt;format&gt;)</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $y</tt> <br> <tt>&nbsp;&nbsp;&nbsp; $y(&lt;coordinate system&gt;,&lt;format&gt;)<br> &nbsp;&nbsp;&nbsp; $z<br> &nbsp;&nbsp;&nbsp; $z(&lt;coordinate system&gt;)<br> </tt> <p>where:</p> <tt>&nbsp;&nbsp;&nbsp; coordinate system = [image|physical|detector|amplifier|wcs|wcsa...wcsz]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky frame&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [fk4|fk5|icrs|galactic|ecliptic]</tt> <br> <tt>&nbsp;&nbsp;&nbsp; sky format&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = [hms|sexagesimal|degrees]</tt> <br> <br> <tt>Example:<br> </tt><tt>&nbsp;&nbsp;&nbsp; echo "$x $y" | $text<br> &nbsp;&nbsp;&nbsp; echo "$x $y $z" | $text<br> &nbsp;&nbsp;&nbsp; echo "$x(fk5,sexagesimal) $y(fk5,sexagesimal)" | $text<br> </tt><tt>&nbsp;&nbsp;&nbsp; echo "$x(wcs) $y(wcs) $z(wcs)" | $text</tt><br> <p><b>$xpa</b></p> <p>Returns the xpa access point name. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $xpa</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo '$xpa' | $text</tt> <p><b>$xpa_method</b></p> <p>Returns the xpa method. </p> <tt>Syntax:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; $xpa_method</tt> <br> <br> <tt>Example:<br> </tt> <tt>&nbsp;&nbsp;&nbsp; echo '$xpa_method' | $text</tt> <p><b><a name="Help"></a>Help</b></p> <p>The user may define his own <tt>HELP</tt> message. This message will be available to the user as a menu item. An optional label maybe specified. The default label is <tt>Help</tt>. When invoked, an text dialog window will appear, containing the message. Multiple <tt>HELP</tt> items maybe defined within a menu or across hierarchical menus. </p> <tt>Example:</tt> <blockquote><tt>help Main Help</tt> <br> <tt>A help message may contain</tt> <br> <tt>multiple lines of description of the tasks</tt> <br> <tt>in the menu or menus</tt> <br> <tt>endhelp</tt> </blockquote> <p><b><a name="Parameters"></a>Parameters</b></p> <p>The user may define his own macros or parameters to be evaluated before the command line is executed. To do this, the user defines a param segment that is referenced in the command line. The param definition has the follow format: </p> <blockquote> <tt>param &lt;name&gt;</tt> <br> <tt>&lt;variable&gt; &lt;entry | checkbox | menu&gt; &lt;title&gt; &lt;default&gt; &lt;{comment}&gt;</tt> <br> <tt>...</tt> <br> <tt>endparam</tt> </blockquote> <p>or </p> <blockquote> <tt>param &lt;name&gt;</tt> <br> <tt>@&lt;iraf param filename&gt;</tt> <br> <tt>end</tt> </blockquote> <p>The definition either consisted of a number of variables, one per row, or the name of a IRAF style parameter file. DS9 will look for the IRAF parameter file in: </p> <blockquote> <tt>./&lt;filename&gt;</tt> <br> <tt>$UPARM/&lt;filename&gt;</tt> <br> <tt>$HOME/iraf/&lt;filename&gt;</tt> </blockquote> <tt>Example:<br> </tt> <blockquote> <tt>param foobar</tt> <br> <tt>var1 entry {Variable 1} default {this is a entry}</tt> <br> <tt>var2 checkbox {Variable 2} 1 {this is a checkbox}</tt> <br> <tt>var3 menu {Variable 3} AAA|BBB|CCC {this is a menu}</tt> <br> <tt>endparam</tt> </blockquote> <p>To use parameters, specify the param name at the beginning of your command line: </p> <blockquote> <tt>Parameter Test</tt> <br> <tt>*</tt> <br> <tt>menu</tt> <br> <tt>$param(foobar); echo "$var1 $var2 $var3" | $text</tt> </blockquote> <p>When the menu item is selected, the user will be presented with a dialog box that contains <i>entry, checkbox, or menu </i>choices for each variable specified. If the user clicks ok, the values are substituted in the command line before execution. </p> <p><b><a name="HierarchicalMenus"></a>Hierarchical Menus</b></p> <p>The user may define hierarchical menus. Use this to organized crowded menus. To do this, frame menu entries with <tt>hmenu &lt;label&gt; </tt>and <tt>endhmenu</tt>. Hierarchical menu labels may contain spaces. Multiple levels maybe implemented. </p> <tt>Example:<br> </tt> <blockquote> <tt>hmenu Stuff</tt> <br> <tt>&nbsp;&nbsp;&nbsp; hello</tt> <br> <tt>&nbsp;&nbsp;&nbsp; *</tt> <br> <tt>&nbsp;&nbsp;&nbsp; menu</tt> <br> <tt>&nbsp;&nbsp;&nbsp; echo "Hello" | $text</tt> <p><tt>&nbsp;&nbsp;&nbsp; world</tt> <br> <tt>&nbsp;&nbsp;&nbsp; *</tt> <br> <tt>&nbsp;&nbsp;&nbsp; menu</tt> <br> <tt>&nbsp;&nbsp;&nbsp; echo "World" | $text</tt> </p> <p><tt>&nbsp;&nbsp;&nbsp; hmenu More Stuff</tt> <br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hello world</tt> <br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</tt> <br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menu</tt> <br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Hello World" | $text</tt> <br> <tt>&nbsp;&nbsp;&nbsp; endhmenu</tt> <br> <tt>endhmenu</tt></p> </blockquote> <p>Will create an hierarchical menu with two members, <tt>hello</tt> and <tt>world</tt>. </p> <p><b><a name="Sample"></a>Sample</b></p> <tt>#<br> # Analysis command descriptions:<br> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; menu label<br> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file templates<br> #&nbsp;&nbsp;&nbsp; menu/bind<br> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; analysis command line<br> <br> param foo<br> &nbsp;&nbsp;&nbsp; var1 entry entry 40 {this is a entry}<br> &nbsp;&nbsp;&nbsp; var2 checkbox checkbox 1 {this is a checkbox}<br> &nbsp;&nbsp;&nbsp; var3 menu menu AAA|BBB|CCC {this is a menu}<br> endparam<br> <br> param bar<br> &nbsp;&nbsp;&nbsp; @analysis.par<br> endparam<br> <br> param foobar<br> &nbsp;&nbsp;&nbsp; @tvdisply.par<br> endparam<br> <br> param ltc<br> &nbsp;&nbsp;&nbsp; bins entry "Enter number of [t1:t2:]bins" 0 "('0' for default number of bins)"<br> endparam<br> <br> # Help Main Help<br> <br> help Main Help<br> These menus contain a test for each possible feature<br> <br> supported by the ds9 (blank line above)<br> endhelp<br> ---<br> <br> hmenu Test Web<br> &nbsp;&nbsp;&nbsp; help Web Help<br> &nbsp;&nbsp;&nbsp; Help for web features<br> &nbsp;&nbsp;&nbsp; endhelp<br> <br> &nbsp;&nbsp;&nbsp; Web Test url<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; web<br> &nbsp;&nbsp;&nbsp; http://hea-www.harvard.edu/RD/ds9/<br> <br> &nbsp;&nbsp;&nbsp; Web Test file<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; web<br> &nbsp;&nbsp;&nbsp; file:/home/joye/saods9/ds9/tests/hv.html<br> endhmenu<br> <br> hmenu Test Basics<br> &nbsp;&nbsp;&nbsp; help Basic Help<br> &nbsp;&nbsp;&nbsp; Help for basic features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test escape char # this is a comment<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "this is not a macro $$xpa" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test pass thru # this is a comment<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "this is not a macro $foo" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $xpa # this is a comment<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $xpa | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $xpa_method<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $xpa_method | $text<br> </tt><tt><br> &nbsp;&nbsp;&nbsp; Test $vo_method<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $vo_method | $text<br> <br> </tt><tt>&nbsp;&nbsp;&nbsp; Test $filename<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $filename | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $filename(root)<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $filename(root) | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $xdim $ydim $bitpix<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$xdim $ydim $bitpix" | $text<br> <br> </tt><tt>&nbsp;&nbsp;&nbsp; Test $xcen $ycen<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$xcen $ycen" | $text<br> <br> </tt><tt>&nbsp;&nbsp;&nbsp; Test $env<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo $env(PATH) | $text<br> endhmenu<br> <br> hmenu Test Regions<br> &nbsp;&nbsp;&nbsp; help Regions Help<br> &nbsp;&nbsp;&nbsp; Help for regions features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $regions<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$regions ds9_s:$regions(ds9,source,image) ciao_b:$regions(ciao,background) saotng_i:$regions(saotng,include,wcs,fk5) pros_e:$regions(pros,exclude,wcs,fk5,sexagesimal) xy_be:$regions(xy,background,exclude,wcs,fk4,hms)" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $regions wcs<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$regions(ds9,wcs) $regions(ds9,wcs,fk5,sexagesimal) $regions(ds9,wcsa) " | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $include_regions_pixels<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "ds9_s: $source_regions ds9_b: $background_regions_pixels ds9_i: $include_regions_degrees ds9_e: $exclude_regions_hms" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $filename $regions<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$filename[$regions]" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $filename $regions()<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$filename[$regions()]" | $text<br> endhmenu<br> <br> hmenu Test Output<br> &nbsp;&nbsp;&nbsp; help Output Help<br> &nbsp;&nbsp;&nbsp; Help for output features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $null<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "This is Text" &gt; /dev/null | $null<br> <br> &nbsp;&nbsp;&nbsp; Test $text<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "This is Text" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $text stderr<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; ls foofoofoo | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $plot<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xy.dat | $plot<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(title,x,y,xyey)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xye.dat | $plot(Title,X Axis,Y Axis,xyey)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(title,x,y,xyexey)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xyee.dat | $plot(Title,X Axis,Y Axis,xyexey)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(title,x,y,4)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xyey.dat | $plot(Title,X Axis,Y Axis,4)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(title,x,y,5)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xyeye.dat | $plot(Title,X Axis,Y Axis,5)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(stdin)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xye.stdin.dat | $plot(stdin)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(stdin) text<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xye.stdin.text.dat | $plot(stdin)<br> <br> &nbsp;&nbsp;&nbsp; Test $plot(stdin) error<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat xy.stdin.error.dat | $plot(stdin)<br> <br> &nbsp;&nbsp;&nbsp; Test $data<br> &nbsp;&nbsp;&nbsp; *.fits<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $data | $image(new)<br> <br> &nbsp;&nbsp;&nbsp; Test $image<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; cat img16.fits | $image<br> endhmenu<br> <br> hmenu Test Dialogs<br> &nbsp;&nbsp;&nbsp; help Dialogs Help<br> &nbsp;&nbsp;&nbsp; Help for dialog features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $message(message)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $message(ok,This is a Message) | echo "hello" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $message(ok,message)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $message(ok,This is a Message) | echo "World" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $entry(message)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; echo "$entry(Enter Something)" | $text<br> endhmenu<br> <br> hmenu Test Params<br> &nbsp;&nbsp;&nbsp; help Param Help<br> &nbsp;&nbsp;&nbsp; Help for param features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $param<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $param(foo); echo "$var1 $var2 $var3" | $text<br> <br> &nbsp;&nbsp;&nbsp; Test $param @file<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $param(bar); echo "$var1 $var2 $var3" | $text<br> endhmenu<br> <br> hmenu Test Network<br> &nbsp;&nbsp;&nbsp; help Network Help<br> &nbsp;&nbsp;&nbsp; Help for network features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $url(http://)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $url(http://legacy.gsfc.nasa.gov/FTP/rosat/data/cdrom/vol1/IMAGES/00h/p000s26b.img.Z) | gunzip | $image<br> <br> &nbsp;&nbsp;&nbsp; Test $url(ftp://)<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $url(ftp://legacy.gsfc.nasa.gov/rosat/data/hri/images/fits/rh100193_img.fits) | $image<br> <br> &nbsp;&nbsp;&nbsp; Test $geturl $text<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $geturl(http://hea-www.harvard.edu/RD/saord-cgi/funtools?funcnts+$filename+$regions(source,,)+$regions(background,,))|$text<br> <br> &nbsp;&nbsp;&nbsp; Test $geturl $plotstd<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $param(ltc); $geturl(http://hea-www.harvard.edu/RD/saord-cgi/funtools?funhist_plot+$filename[$regions]+time+$bins)|$plot(stdin)<br> endhmenu<br> <br> hmenu Test Other<br> &nbsp;&nbsp;&nbsp; help Other Help<br> &nbsp;&nbsp;&nbsp; Help for other features<br> &nbsp;&nbsp;&nbsp; endhelp<br> &nbsp;&nbsp;&nbsp; ---<br> &nbsp;&nbsp;&nbsp; Test $param @tvdisply<br> &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; $param(foobar); echo "$frame $erase" | $text<br> <br> &nbsp;&nbsp;&nbsp; hmenu Test MultiLevel<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; test<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; menu<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "Hello World" | $text<br> &nbsp;&nbsp;&nbsp; endhmenu<br> endhmenu<br> <br> $x $y<br> *.fits<br> bind x<br> echo "$x $y" | $text<br> <br> $x(fk5,hms) $y(fk5,hms)<br> *.fits<br> bind y<br> echo "$x(fk5,hms) $y(fk5,hms)" | $text<br> <br> $x(wcs,fk5,hms) $y(wcs,fk5,hms)<br> *.fits<br> bind z<br> echo "$x(wcs,fk5,hms) $y(wcs,fk5,hms)" | $text<br> </tt> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013166� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/sqrt.png�����������������������������������������������������������������������0000644�0001750�0001750�00000015423�11343045612�014703� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���*������0ï|#��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi��!IDATH ÕVÍ+´Qÿ͘òµ"c§,䫱ÀB& ²UvjÊÇÙÀØ`E„b…‰|D¤(LÓL¦°’¢4Ì Î{Ï}›k>ßyƈÞ[Ïóœ{îïž{î9¿{î£#Ñð íüüëëëšV®¬¬„^ò›A^¯¼87½^¯éGô§ÛÆÆ544$´ì¯DtooÂQQ­¯ÿÆQÇ_뮾Çü4xzzBjjªf“?ÑÃÃCTUU%ä$ïæÇý ?Ce¸Ýn,//ãèèH¥Äåra~~^õ“b9êñx°¸¸ˆÙÙYµÄþþ¾Ô±Bq”9szz ‹ÅƒÁ€‹‹ 9annÝÝݸ¿¿1¢¬… }}}HOOÓþíþ‹Ÿ¼““ âúú———X[[ÃËË VWW? XÞÜÜ„Ùl†ÓéDQQ‘T³£ÓÓÓhnnÀb~ù¶ÉÊÊŠ:ζ'&&°»»uœ7’£³³ó^u?>>H€ijjJ MNN*Y‹pvvFÃÃÃ$œ÷÷÷Óèèhˆ.¼S]]MuuuájŠ8L)))hjjÂöö¶ÜÍÎÎŽ¦H~n]ðI§“×b[[[ßcñ3xniiipWÉ% á뇽½½RætÄk̳òòrù0ïa2™ÀiµÛí¨­­i‚éöðð�‘ø|>¤¥¥)lTGëëëeA¶Z­èèè`Žs'^ËÈÈP‘B¬¬¬È~¼úùöö&±333ÈÏÏ—»¢¢(((�G*¢1OÅÉ¥ñññˆ±D777$•Sbñsii‰DÆhhhˆžŸŸ%¶¤¤„Z[[illŒÞßߥ.ª£<ÒÒÒB~¿_‚’yåååÑÝÝÕÔÔàh„)›ÍF]]]t{{«Æøöôô ŽÒEuTÔ-ºººR d„ööveff’àÝ—M©S/Ãëë«,º\ðËÊÊ×’˜§\?¿r¿‡¬Øbnn.ÒÂÂB@õ-߃ƒÊÉɉ[?ã-¦RÏ<¥!>áq‘%þ¤­­­„çOød«(PF”¢����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/asinh.png����������������������������������������������������������������������0000644�0001750�0001750�00000017336�11763207066�015032� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���P������=×ë��þiCCPICC Profile��X…•Y8•áÛÞ3{ï½÷Þ›ì=[ÇÇ(£”Š¢$ddB( #$¡’•$”"*…dÄ÷’úÿ¿ÿ¸¾ë{®ëyßß¹ßû¹Ÿû¹Ÿç½Çyà¨%„†!è�&Eí÷ð¹ºíåÃŽ4 Ô€Èˆá¡ú¶¶–à¿¶C�Ú¾¿Þ–õßùþc£÷ò'�ÙÂØÓ+œ ãZ� ÄPr�èmyB‡"B·qŒ™È°‚0¾º}ã†mìùwïð8ÚÂx� jì �~¦óE}a94Ô�`H^þ$˜•Æ:D?‚�0TppÈ6> c1Ï’ãû¿dzþ•I øþſײÓ(ŒüÃCƒÑÿOsüß-8(òÏ<p§t°€ï,°Ý Æ0fƒqªŸ·™å.½,4ÂÀ~—Þìaæ¸m#úEš:íâ™È@'}sÁx#0Äb›¶‚äimc à ÷þ–‰P‰ñstÙå±ôò62†1|Š®äû?ü~áQè11~†ÖøæÛûMãdyg-°ˆï =Ûó Àøzh„­ãî\=¤ ëݵ ÞûMìwñšwøÎzwæŠðs4ý-I€ß2‘\>þ&f¿u@Êù‘MÿÐõBƒvÎ4<éHŽ´ß¶ƒŒ}¼IN»2‘É^#‹ß6Aæ@�dà < ü|À£Ý+L'ÁW"Ap'óÑþy‚þ€îGO¡_¢'ЯþrþáþÀ ¾ÿ¡ÿ‰î�bÀgXª7ÿ3Š¥ƒÒDYÂW=¸+ ÔPêžõÌßÿ«Õo]}á±Ò»ƒ]í£þY{wÿò¿Œñü;âßu2ïw¤îrÈUÉÍÊmüÿcŒ1FSŒ FyYƒì@¶!»ÍÈ»€ù�Ù€ìFÞ߯ÿ2 a×*äõZÀ3zƒÈ_¤ÿ¨Qä_Ž]*2°ßᄟùÿÁyGkÿ“ wOXR�üÌâïÿXZ¶®2Ê�¥ Û¶1ŠÅ¤QJ°ÅõQºð(ÃTõ{•>;¶ŒÚYK ø�ãàïÃÛÝ0$4šìïëÁ§{Ko)>3QFŠOAN^lûÞ߯ö¢ýŽO…XzÿA ¹€ìÖÿ ±�Ô ÂnÔâ4!Ø/Љð “IŽúMCm_ЀЧŸö‚@ ÖS¨�M Œ9°ŽÀ „­ë‚a8p$‚.‚Kà2(×À pÜÍ  <Ï@x ^ƒ 0 æÀøÖ!ÂBxˆb‡x!aHR€Ô Ȳ„ì!7Èò…HP$€R tèTU@·¡F¨ ê‚ú¡WÐ$4 }‡ÖH5‚ ÁAÈ"Ôú „#â�†ˆAœD¤"rňëˆzDââ%b1‡XF$’É”Fª! ‘6ȽH$y™ŒÌB#«‘MðY|œ@Î#WQ#Š% ï¤)Ê ED…¡Ž¢Î¢.¡®¡êQP/P“¨Ô&æBK¢5ÐfhW´/ú:….CסÃïó4úƒaÁˆbTáÓî† ÀÄbÎb 071­˜~Ì;Ì2‹eÇJbµ±6X6›ˆÍÅ^Ç>À`§±?)¨(x)(L(öR((²(*)Z((>R¬ãèpÂ8 œ Î ;»ŠkÂõâ¦që”ô”¢”Ú”Ž””Ç)s(«)SŽQ.RQQ P©SÙQùS£Ê¡ºEÕI5IµJÍ@-AmH½Ÿ:’:•ºœº•úõ"Áëá÷â#ð©ø üCü8þ' # M<MM=Í�ÍZ­0­>íAÚÚ,ÚÚ^Úy:!î(]]#Ý0Ý2=#½<½ }0ýYúJú.ú,ƒƒ1ƒÃI††‡ ‚Œ†ŒDÆŒW3N3a˜D™Ì˜˜R˜n0õ0-030+1;3fÎc¾Ï<Á‚da1c b9Ïr‡eˆe•›UŸÕ›õ k5ë�ë '››7[2ÛM¶—lkì|ìÆììØï²¿á@qHpØqâ(äxÌ1ÏÉÄ©ÉIäLæ¼Ã9Ê…à’à²çŠå*áêæZææáÞÃÊËý{ž‡…G'€'“§…g–—‘W‡×Ÿ7“÷ï'>f>}¾ ¾¾G| ü\ü¦ü‘üEü=üë¢N 7ÞR ª úf ¶ .ñ Y Å U ã„Õ„ý„³…;„WDDE\D’DîŠÌˆ²‰š‰ÆˆV‰Ž‰áÅtÅÂÄŠÅÅ1âjâââ} e ?‰<‰^I„¤Š¤¿dd¿ZJ]Š$U,5,M-­/%]%=)Ã"c)“ sW括ì^Ù ²²›rÊrArWå^Ë3È›Ë'È7ÉWP *ä) *âMã¿)I*y+*(3*[)')·+ÿRQU!«T«Ìª ©z¨æ««1©ÙªUëTG«¨Ç«7«¯j¨hDhÜÑøª)­¨Y©9£%ªå­uUë¶€6A»H{B‡OÇCçŠÎ„.¿.A·XwJOPÏK¯L¸~€þuý/rdƒ:ƒC Ã#†­FH£=FÉF=Æ ÆNÆ—ŒÇML|MªLö(ï‰ÝÓjŠ6µ0½`:lÆmF4«0[0W5?bþÈ‚ÚÂÁâ’Å”¥„%Ù²É aen•a5f-lM²¾klÌl2lÞØŠÚ†ÙÞ³ÃØÙÚåÙ}°—·³ïp`tpw¨tøáhàxÞñµ“˜S¤S»3­ó~ç ç#—t— WY×#®ÏÜ8ÜüÝöb÷:ï-Û»¼ÏxßÅ}Óû•÷'î: zà𮃃Þw§u'¸×x =\<*=66„b²§™g¾çјMœóÒóÊôšõÖöN÷þè£í“î3ã«í›á;ë§ë—å7ïoèÉÿ[€iÀ倕@›ÀòÀ­ — ›ÁÁÁ$R éQOÈáþPÉÐÄЉ0°‹a d rY8~ ¼!‚ Nr»#Å"OENFéDåEý<ä|¨æ0ýaÒáîh‰è3ÑcLbJcQ±ÄØö8þ¸ãq“Gô…ŽzmŒ??}lϱkÇ)ž —ž°tÂåDÓIî“ÇN¾;µçTU"M"9q8I3éòiÔiÿÓ=gÏäžÙLöJ~š"—’•²q–xöé9ùs9ç¶R}R{Ϋœ/Lä‘Ò†.è^¸–NŸ“þ.Ã*£>“/39sé¢ûÅ®,¥¬ËÙ”Ù‘Ù9–9 ¹B¹i¹—ü.½Ì3È»™Ï•&¥À«` P¯°ú2÷å”ËkWü¯Œí)ª/)Î*Á”D•|¸ê|µ£T­´¢Œ£,¥ìW9©|âšýµGª•\•ç«U‘U³×÷_ï»at£¡Zººè&ËÍ”[àVä­O·=nݱ¸Ó^£VS]+\›_ÇX—\ÕG×/Üõ»;ÑàÖÐßhÞØÞ¤ÙTwOæ^y3sÞ}æûç[([N¶l=ˆy°ÜÚ:ßæÛö®Ý½ýõCׇƒìõ<¶xÜùÄäÉÃýŽÚÍ]]OÕžÞ}¦ò¬¾[¹»î¹ò󺕞ú^ÕÞ†>õ¾¦~­þ–ݶF/ž š >{iý²ÈihdxÿðĈ×ÈÌ« WßF£F×_C%¿¡{“5Î5^üVüíÍ •‰û“F“ÝSS¯ßßͽ¿1}òþCÖGÞ3 3ͳ&³}Ÿö}šž [ŸOüLÿ9ÿ‹Ø—Ú¯z_»\¦¿‘¿m}?»È¾X¾¤´Ô¾l»<þ#øÇúJòOöŸ×VÕV;Ö\Ö>®ÚÀnäüÿÕ´i±9¶¼µJ vR$Ü>>�|/‡ë7�û� ¤ù]í6$œ| v²i5pŽéÖÐMâÌ@‰¢:Ñ)Ìl+E .òÕ)êL|9Í0;½7C ÄìÆr›’ÝãçnQÞ�¾(þhxÁ3BÂy"Å¢eb¥â¥W$s¥Ò¤“dâe£å¢ä£â+íU–UA«¼Q­SKU÷×0ÑÒBhMi·ë”èžÒ Ðw4Ð1”4b7Æo˜|ÝóÑô­Ùkó‹!Ë!«ëa›AÛvöƒŽ#Noœß»Ì¹.ºmîÃí§?@Î΃ŽÀàÉDdóâòðó•óÓð· ˆ,zü)„6T)̉žq3²+jêÐz4SŒT¬Iœû‘è£ñ7Ž=9þ6áçIúS‰In§ÉgÎ%W¥tŸýžÊuÞ2íè…ÚôùLÑ‹îYÙsV.‰ç¹åŸ.¸[8}…¡H·8°äÜÕÒÒ–²áòïøJ‰*Óë¾7’ª+n>»õõkn­O]J}õÝž†ù&Š{üÍj÷­[œØ·Zµ™µ=Ô{¤õXí‰b‡l§dwׯӡg7»Ÿïë‘éÙêíé»Ôï3 ð¼¬™1:l3"÷ŠþÕâèÐ릱+oǃß:NhNòOa§æßõ½¯Îù÷ñÀŒÖ,çìê§¡¹šù󟿘|åÿºµ°ù]tÑméâòØŠÂόխõÈÅÍC[[;#3œ#ºƒ<0)Cg y„+b�y�Ο ÑvFÌ{ì}ŠR\eU>õCü­]<ý#F$“.s,K5ë[v&8*s%q—ótðNñ}áÿ 0(x_¨Tø¬H¨¨µ˜¨Ø†xD¾¤¯”‚Ôªt«L¢¬•¯ÜŠ|¯B™b¬’¥2‡ò{•*ÕP5µïê·4Â5uµ˜µ¾kê4èæëÅë4P3¤4ì7J5Ö7^0y°çºiYºy²E’e’U²ušMŽíe»rûj‡«Ž±NÖÎÎ?]^¸Öºåï=·ïÌþsrÞpoô¸M¸æYDÌõJ÷>ë“è{Ü/ÎÿP@x`h)8ˆâêæOŠéÈCчD'Ä$Åž‹Ë<Rp´<¾æXÛñ¾„©˧p‰<I*§mÏ&'¦½îUêrÃÙt«Œ€Ì„‹³*²›sús§/­çÓˆê^v¹Zt¦¸¢¤óêL®\üšyE`åÙª×{o,Üd¸¥tÛéNdÍÅÚšºþúÏ ØFþ&{vÍž÷ÃZŽ=8ßš×VÞ~ûaÓ£6Ø_õt¼èììjyZûìzwÙó+=ù½¹}9ýÙy/® 6¼ìz5üid}ÿšwLþѸË[òDödëÔì{ÆiÝAsg:f—ç„æ~®üJ¹pê;ûb÷ráJòjêzé¯îÝýgZ 4@Ô°ȇVàý çÖƒ(2šý ÓŒ­ ¨Ã½¤\¢fÂKÓ8ÒÆÐз0¼eB1K°X°ú²Å²ÇsÄrÆpÅpGòózòÙñk p ül:*,+<.’"ª&:)–(.!þDÂSbC2SJJªCš(dòe5d_Ê…Êãå+L¦”„•^(ŸPQP™T½ ¦¯¶ ~YÃVhÞÐÚ§ÓnÔñ×åÔíÕ;¥¯­¿lpÓ0ÈHÒè“q…‰ß1ØO”™y› ›¿·(±$XñX½±.´!Ø Ù~²»mã`ìÈè8étËù¨‹•+§ë'·Æ½§÷¹ìÞ¿tàÑÁ,÷�]+aÁó±Ü+ÑÛÛÇÈWÈé7åßp%0>è`°:‰‰ô5¤;´2,™n!ɹ5z¨ùpAt\ÌÞX•8ú¸¯GF¾Œï?öüø³„Î';Nu$v$=9ýðL{òÃ”Ž³ÏÏ ¥NœŸK[¾°–¾ž± G×¹¬ñìÞœ–ܺK}ys˜BÁ˺WöEÃq³öjwéTÙÚ5æ ÅJǪÃ× o<©ž»Åp[íŽ{MbmuÝPýfƒh£}ÓÑ{•ÍÃ-¨Š­„¶´öև󙞨wè<Ú•G´þîï=æ½¥ý˜ ¯^Ú uؾz3Æ;^;ùpš<ÛÿåÙ’Öêæöþÿþl»aT�(éÀE�[� á:s�Úø7�Gu€ÐSm�ÙÍýXÀÄ\Y‚°©Ýà H²üá*°j‚†¡%Ba‡G\D4!&8¤2Ò ™ìEQÀ5øTj ­‰>†îÀÐa`®c6±vØ2ì…E% ÀQÚR>¡Ò¥j¤V¦®Á+âëh4hZiMi{é\é¦èIôk §Y˘T™:™÷1e9ÉÊÁz—Í‘m‘=“C…ãç.®.î0NžÇ¼a|‚|oø³àˆå,Â!òŽY$qUñU‰Û’RÂRï¤¯ÊøÈJÊ.É=OUpWTR¢Vú Ü®rEõ˜AÝHC\“Vó'œ?÷é<н¥wU?×à‚áY£$ã“#{™†šùšï·°µ4²Rµ–°á¶¥·£´Ç:`qNÔÎ .œ®"nŠ{ ÷9í÷?0Û½Åã«'?ÑÑë´w‹Ï’Ÿ„¿gÀ¥ÀÁ`’YHb胰ÕpÕˆC‘÷!ÛFŬÄÙ¹Ït,&y"ó”XbËiç3 )çÎɤö¥E¦se¬^ü”=‘;ž÷±`õ [±ÞÕ²âkµ•®¿¬þxëg e÷]¹F£{®÷ƒœh+|xÿñd'åSµîÀž¢¾Ñü/C†ÛG9Æ¢ÆG&uß]ÿÀ5£ù ?7ü9ë«ùÂâ÷´%áåÛ+*?ë×ä×Ëqm¦îøF Làø 2À Ð ÞMˆR…ì  ( *Z¡qhÁ ×÷ÞˆÄÄ(”Gº#Ï#ÛK( ”7ªõ­Š>Àˆ`â1cXl=ÅqŠe\0n®†ŸRQ=¢6£Ä{ãÑ\¢Õ¢¦ ¦ô b ­Œ˜L·˜I,¬¼¬OØHìLì÷8œXÎ\\kÜ%<Ö<ë¼U|'ø½L%…¨„¦…›DN‹Ú‰±ˆˆçH%m¥d¥é¥—eFeÛä*å/*œP$+•TÌTõÔÔÔå5¤5%´ÄµÅu$ueõ”õµ L í™ÄîI1Í3«2o¶xn9nõÍeËn'e¯çàìì”è\ärßõµÛú>®ýº¼&»7y,xŠ=½ò½G}Yý\ü³Fƒx‚=I!ßÂɇÃ["1Q¶‡òÏĨƞŽ{}T6þÔ±7 *'2N~OtHj8ל’²v.8u*mß…¡Œ}™3Y‡s(s¯äiæ¹"\4Pr¼T¹lîZ{eÞõˆjë[¢w š×uuwÓƒîéÝGµ<mMoß÷HôñRG{WÆ3Ÿçê½´}Ê=‡x†G_e¿v|Ã0Þ7‘6e÷žizäcö¬Î§‘yÂ瑯: Ùߦy–l—cä¯Ôÿ|¾:¶6»þ}ãç¯Íÿè€$0DpdƒÛ  L€ˆ’€L O(~÷[  !а„ßü|DâRÞý‹È%Ê•ŒêCs¢Ñ1²˜B,#6•‚‘¢§{ECÅKÕEƒ—ÃÏÑTÑúÓñÐÐg1¸2ò2~bjd¾ÀÈjÊ&ÊŽeŸáèæ¼Å•ÉÇãÇëÂgÁo( #¨-d(l%â*ê%&/‘*Y U%Ý,Ó/;+VR4Q RÎVy¨º Î£a©£uM{X£§ª`PdøÚ˜ÍÄuO¾é;s%8˳V°9mûÖ^Õ!Ýñ³³•Ëm7޽Éû¶ÄÜðˆ$<% xÅxÂyæ9ÿ¹@‹ $ÆøÐ9²sx[¤DTœazÇôÆyop¬;ÁãįS%I¶§&û¤ 3MmJ“½PšÁ™Å˜}>—åRq¾LAãeƒ+]Å6%ƒ¥®e¯¯yU|©Š¹©Îº%r»¡Æ¢v¢>ªßXrO³y°…ÔŠk+}høhêIB§P׳g±Ïe{fúÊ•‡0Ãc¯î¼Vk×xÛ8©<uã=ÿtÚ‡µÏÙŽ9 ¸ÖˆûBújµ ²ðéÛÍïn‹ˆÅ«KÊKO––8üX1_¹ÿSögñ*íjôêÔšåZí:Ûú‘õÉ ãò_¿ü~umJl&mNonm︢ÂNø€¨ àdb|kkQ é�üº°µµ^¼µõ«.6Æ�h úýÝe'ÖÐß·:<çŽýë÷ÿêéÜ€�³‚��� pHYs�� �� �šœ��†IDAThí˜[HT]Ç©M¡‰ä-º`ˆ"R ©•¥()©TAô’e¡R/>T‘"aF¡hdhÊôÒŒB6™¯e:Ìx™QGçæìï!:_~ŽZ™“|ôƒÙkï³öÿ¬³÷:kŸeBÁ_~·?-àwSSSÃçÏŸìgbb‚²²2ìvûœãþW¼téAAA-Ø—§§'©©©äåå1×&]R™S,€ÃáÀd2Ͱ×ÖÖ266Fll¬d›Í—Åbù!=k×®eÓ¦M\½zuöAb ‘œœ,fí;vì•••ÓìSSS"$$DtuuI¶G‰ÈÈH1::*ÙEnn®¨©©§N‹e^MÂÏÏOF§ýK*€‡cÞ1ÇŽ›ÀçÏŸ ©=99)L&“ðððø-ÈCCCB! Eaaá銎ŽåååNû\²…[ZZ¨­­¥²²’©©)�4 r¹œû÷ï£Õjxýú5!P©T¼y󆺺:®\¹‚Íf“üÙívîܹCII 6›ææfÖ­['õ¯\¹OOOÜÝÝ%Û‹/ðððÀ××€mÛ¶QYY €Éd¢¾¾«ÕÊøø8MMMÓôoذW¯^9½·Eààà GŽaß¾}hµZ®_¿@NNééé„……ÑÝÝF£!77—–– —/_æâÅ‹ÒÐÐÀÍ›7%ŸõõõlÞ¼™§OŸríÚ5ŒF#2™lNïß¿' @jûùùÑÓÓ€N§ãÆTWWS^^Nkkë´k½½½vê×ã—¢òøúúr÷î]4 ½½½’Ý`0““C~~>2™ ///‚ƒƒX½z5áááxyyGJJ Òµ‰‰‰ÄÄİgÏš››Ù²e ãããsê°Z­¸¹ý»^ÜÝÝq8�³ÿ~ÊËËQ*•ÓV.€ÍfÃÇÇÇ©ßE_Bªªªx÷î’說*´Z-ááátuuÍéãû›ý777±±±ô÷÷;ó ƒÔ6„……Ií5kÖ`·Ûg ¯¯˜˜§~=€r¹œööv§•mmmTWW“ŸŸOqq1ð5ØâFQQQ„††¢V«g“ÀØØ˜´RÛÛÛ9xð ð5šÍf4 V«•¡¡!é:‹ÅBOOpêwÑJcc#YYY˜L&”J%oß¾¥¨¨ˆ'Ož`µZ9tè?~¤³³•JÅÀÀ�mmm¨Õjôz=*•ŠŽŽ>|ø€Z­F¥R1<<ŒJ¥B­Vc0(**¢¢¢øºåär9‹…BÙlF&“QZZÊ… P*•´··söìYŽ?Nii)éééìÞ½›ÜÜ\–/_.éøð!§OŸÆßßßù þÐ{|LNN »Ý.„Âl6 !¾–ƒAX­Öß6OAAhnnžsŒÕj###Rûûúnrrršžþþ~‘••%iwÆ’ªâË—/ ö366&JJJ„Íf›sÜ2!¦'½^‚ÀÀ@àk~ÐétÒò/ӑʘÁÁAîÝ»ÇùóçÙ¹s'? ¸¸˜sçΡÓéèèè˜×áöíÛñðð ¥¥¹\¾xÊÿ ÑÑѤ¥¥ßÐßߟììl¼¼¼ÈÌÌD¯×@vv6 …777âããçu®×ëgO¸ÿGþ»§GGGÅŠ+DYY™d+((XpNY,‡Ðëõ?tŽ^ f”1ÞÞÞÄÇÇ£P(�èîî&""ÂåöGèéé!33“ljÑht¹§G¹¤¤$nß¾ €B¡ ;;!'Nœ˜×aQQ«V­ú½*gáÓ§Oܺu €´´4ž={ÆÞ½{]2÷7œÒ»ví¢··¥RI\\œd7›Íóþ\IJJŠôßßߟ„„—Î8/¤'&&„»»»8s挋3ÊÏÓÑÑ!222DRR’ô­Ï•ÌZHGEE ­VëJ-¿L__ŸHMM'OžtùÜNØÔÔ$êêê\­eA´¶¶Š¤¤$—Ï;#êt:^¾|IFF†ëóÉ!==ÝåóJG¹7ÃÖ­[ÉËË›öñq©’’’ÂúõëINNÆf³qôèQ–-[æR R�<x€L&û#OñWq8F|||þØŸñ1á/?ÇÒß§Kœ�¶ïZ”ྼ����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/saolog.png���������������������������������������������������������������������0000644�0001750�0001750�00000016633�11343045612�015202� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���A���"����—´±��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi��©IDAThåY[HU]/yI3QQ*‰}(Ê A ‚·Á$!#í¢ tAMÅß$ôÁDBA%Â+š%"=„¦jâTÓÌï–ºþõ-þ½ÿs<ÛŽžŸóú6k­™µÖž=kfÖÌl Æþç`iNß¿»»KZ,­®®Ò«W¯¨¹¹™~ýú¥ESm�M0˜™™a·oßf 2;kkkìÆìû÷ïlxxX‹&OR¡c6šàããC‘‘‘Z‡[SSCäêêJ—.]". úðáƒÖ5f#¥yûö-]¸pA&ùùùQGGýüù“èÙ³g´¿¿O………ÔÓÓ#Ï;ØáÊr¥5¶Ö™Ù`~~žNž<)såääDÀÙØØ7zôèùûûÓ½{÷ÈÙÙYž'uVVV¨¬¬Œfgg©ªªJBë´ÿ‰©»»[0Bx”ÀÞÞ^ËîííÉB±°° ÐÐPrtt$OOO¥ådeeE^^^422¢H—&—/_hccƒÜÜÜèâÅ‹‚ôƒË—/ÓÜÜœL†ÄÇÇ‹ñÎÎŽ0‹ÉÉI™~°-²³³;ˆÖ›Ä'lnnRZZá$a¿–––-žóçÏËL®i¿>”5×'‚uß¾}£ÖÖVÊÍÍôÏŸ?k­“7<bÇ$š””Düú#*îíí­Ã>paaAР1ДsçÎQQQUTT­­-UWWÓââ"egg [‡>}š xÖ×מ„çÈ Â5ûÛ-úúúØ™3gØëׯYKK ãÞü·ó %¶µµ‰8q¿9äm^¾|©7¾0º&ŒÓõë×)..N îzœžÚ ™—!ûÝ'ðˆ>}úDÅÅÅT[[K[[[†ðiИ⇉‰ ‚‰ЛÈjá···…½CÔàÑ$BPƒQcî¡c𾸂$À½>55% ÿÈVvŒpXuuu”ŸŸOÁÁÁ"FÇ———S^^žÌïìJ’ÎÕ«WÉÚÚZø¤¿æ Äbcc{²`¯" ½ÿ¾¸q×ÙÙ)„©ú�šd®¶(ïò…úw‡1LLd÷ìrÿOìèøÄÛ8qœ>`llLäô‡JÑHÄËËËZ»£–€45A6ÍMÃÃÃéÅ‹aÀ$¸Ѓ4§)öKJJ)¯¡€üáÍ›7tóæMêïï§S§N‰­*++iii‰rrr(55•RRR(((ÈÐ×h­ÓÑPáñr—`F3ÍÅ}¯ïÑÚÝ€Òߨ¨(òððWC0pØ8¤ÐÈEˆ©J6ÎÆ™a?V"›wöìYÆë�â]¼þ òéÅ_¿~eüb¼ð*¡Û£æ)Šš€Lµ½¬¬,Õ„ýo6Rª0!µÆµ®½½½B›GGG•È:8EŸ€²wAA¹»»ë,Pñüùs‘cß§OŸ*n¯TaÂDÍÒ›´¦ƒ`zzZBému„€h^8==]ïbC' ï‡Ó …T}ÿ •?~üEø hªÏ(­ÐGýᨠÁ××WHðÊ•+ÂuƒãÎkooˆˆˆ'B‰hV™\\\(11‘ºººDY™aff¦Ò2Ãp’GilldMMMÒÐ(íÇÙµk׿aØÝ»w/©+¾çÝ»wìÎ;Œ§Þ Á€§à¬´´”Õ××3J$à×&ãQªx$ZMǪ‰Wê›4‹Œ‰‰!Ô¡maaa¢lØÑý³*99Y”í€A %JsÈ]¤‚®„Wl•$c,gŒ ‰íqÂÐcÁq4AñŠT”– È[·nÑ“'OD4úþýûc9¯ã¼ÿ4à<Ñòÿ™z—šÔÀ ˜Ã¿Å'NèeÎTL.S}ØqÞcRs8c¦œûi­¾¹âóÁ����IEND®B`‚�����������������������������������������������������������������������������������������������������./saods9/doc/ref/img/gauss.png����������������������������������������������������������������������0000644�0001750�0001750�00000022173�11345516007�015037� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���­���&���¶ØX��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi�� ‰IDATxíœÌE€¤¨H¬X¡Q#MP”"½†ºŠÔ"UŠ)"U:J€�¡ƒR JGA©*¢H±�*m|ßÈ.·ûßÞ­ÿÿ½—ÜíÎÌ›²³oÞ¼6›A ¨$$g f c59Ôä ˜Hm”áÔ©SjìØ±*VÛž={Ô¢E‹¢ô´éÛM’hÓw~Më§OŸV/¾ø¢jß¾½Ê!CÐ/_¾¬† ¦|ðAÕ¼ysõÃ?Å —yòäIÕ¹sgõÀ˜>/\¸`ª/^\åÈ‘CMž<9\ñ_ŽL›ÿ3pþüyÿÈW06l¨wîܲÞôéÓõÊ•+µ«nܸ±®]»vH|¯Â~ýúé/¿üR gÕ… Ö#GŽt 6kÖLöÙg޼DK°]%ÁÇ üñÇZ¸”.Z´¨ì«([¶lÑ%K–¼šáqHÔŸ~ú©.T¨¦wö¥K—ô®]»l„×_]?õÔSvš› è5j8ò-‘|n†3fTÕ«WW?þø£Ïÿ ½ÿþûª\¹raë”)SÆÆùùçŸUÕªUí47ÂáÕ‰'yîc”bg?~\U«VÍNsƒØ =l[ŽJq–H­Ï’%K•9sfŸØWÑd+V·ÜrËÕ ¹CÎ\½zµúúë¯Mþ²eËÔŸþiã7Tƒ ²ÓÜ HõêÕËλxñ¢Ú±c‡Ú¼y³Éûþûï Ž…ð믿*ä[M¬,sµÆBÝD…$Ѧó›ûý÷ßU¦L™½œ={VýòË/êùçŸWóçÏWß}÷!dfΜ©ºvíªnºé&GwBDE;M›6U(q({o¿ý¶A#¥bôèÑ)?¸q¶lÙLÿî6%íœÍ8µÈY)&<ކç{(yóæ5ÄXáÆoTuëÖUÏ<óŒEI,XÐøá‡Jdf…¦;v̘©~úé's×îß¿¿)k×®ªT©’Áß¶m›ºÿþûUÍš5MÙ»ï¾k,X þúë/ÓîܹMˆŒ!Q!îˆ.÷<x°¥"QçÕ÷C=䨶­8åµ×^k‹kÖ¬1œW0ƒ'5j” €ºùæ›Õõ×_¯öíÛ§J—.mÊ!Hà‰'žPk×®UçÎ3òë€ÔºuëÔ|`ÊEtØgY�0„ûî»Ï”'â_Ü-²Ä’÷qRÇܦM›ÊåK—.5öØ 6¨G}TåÊ•K½õÖ[vUdh¸.?@¬ ê‹/¾Põë×·q¸©X±¢8p bq°ªT©¢*W®lãäÏŸ_]sÍ5vzÓ¦M†#³$,Ä£¹Cä@-JO\ íÌ™3zâĉZ^¶N¦1/ù‘]µp>ƒ>cÆ -N-Ï´S¶lY‡™Ê«ÍÏ?ÿ\?ýôÓ)б?üðþÇÓ¨Q#½{÷îíÄC†(ú£>Ò¢djL…\ƒA\Úiã‘hƒMžß<‘+u—.]4/b|÷~Û ÄÛ¾}»–])0Ëó~öìÙzîܹžå±.Kˆ¾ãŽ;´¸›õ#<¢9tHq'$ì–bàlõbèWÂe‚ˆ¸u懻Ÿ3gŽ‘Mïºë.#÷†ÃG?¸í¶Û¢C¸:Ñ.ÇÅü^¬X1#§{õŸ$Z¯™‰p>f&b"÷Üs1¥‰xá«ÉR¥Jù‹%Ê#ã´”Q¯±d€ÿzÆ*_äG…‰ÓL¬é'xå…^p8üÖ‹õóÑ¿{ì± øo¼a¼v¡ÆwœÍÂ… •ÈzÆl#²M ã|¨Št[*Û{8pãø­®Ýh”»Ç>Ý}à„9zôhX‚¥^\rZ÷E#;Ôò(á÷Çx 0øçÉ“Ç!«ŸÌKû $‰öÊb&PÀpŸ3gÎ+%ÿ\béСƒ ˜ÁÈ/Z¸zì±Ç8ÑHÐwŸ>}±-Z´PÏ>ûl4º«>þ×D‹ ¿ÿwÞ©²fÍòňÖ8ðLáz%F ÚA'xÑ&ïÞ½»:xð zòÉ'ÕâÅ‹£nøí·ßÔ¼yóÌ"gþˆ­¸îºëŒ§…˜÷BÎeZ DKtQ«V­mJ@²zíµ×ÔþýûùîŠS‘"ELö”)S 1¸qb•æÄÀí·ßnw±öíÛ×¥¹Ep ÏG0‰hy‘ÄЯðt M@æÃëe£eË–Æ#I«D¸çÁe wç—/_^}ûí·fÑ´mÛÖ¸¤áþì¡�·¬¿­‡B7eMš4±½ƒElïÞ½Æ>–/_>9ôæ›oû"6A¶ÆP ‘öjÉ’%¡P⢌½Ç\±{öì©p£¾üòË .Šh-Bá!p©zɼéù(w€8è² ,K{)ïYœ†`é£@ªB… &Ê 7ôŠ+ìÀ¯1`¦KË.åà´hpl�Áâò3i¯Î#•OT+6ÒÀB‹£ÙZµj)äÓ­[·š‰&Hî�ûÌqùˆ#B¹Ÿ¶Bá`EaçClY¿~½Ù‚K”(aΙQ8‹‰×€" s 8=1Áá8l`¯{t ¬¡ˆc?´–Íêq¯l¯ŽÒ’ÿꫯšøQéŸû!;ÁòåË —œ0a‚’£(f'ñK°D 7N 2$䤦e>¨ ó Ì ‚¸ ÜÆ¢ÑºukÓ42%Db…)¦µ??õ9!q&¤Ò§Õ¦Ž‰“÷Á)v5]/pˆ mܸѬîÀеO>ùĸ ½!%5ø¬Y³ŒH‚|”Þ€˜C)âñoeAv„N:©ìÙ³+8î7ß|£î½÷Þˆ®Š× ¸á†LTŠÄ!‡ Í)%Ljär/ÐHJâ�L“–,jµˆÍ H0Ž3fŒUôŠâÛ»woG» ÌcüøñFÉãÝ Â{.Ñ>|ØÄ~vìØÑÑ ò^àqGá•DjVšà3/!`iŽëŽöÖç¿Í#–ôî»ïV 4°«Â= ”ÆÍ $~˜›�ÆøÕW_…ª’ê2‚Á_zé%»>òŠ$ïQ†9BÇ™É ‡wÞyÇÆMë ï9˜%Å:IÁ‚ úf2Ÿáh…ùv!–ÖQ äfÚ Ý`DKÙr´TÔ²íXYé~}î¹çô+¯¼b÷#îD-+Y gÑ2v~¤n”¢…L“b6ÒrËD_EªH´#U Qš¦Äb åeja(ZÃM8ã: ´~¢ D¢KÓóBH(t,úLô-–»?Ñ ´ˆ”zÒ¤Iv^$nä$†E׳)›he¥h9©I‚æì< ¦ slÚ$"ü'\CKDyÈ´¼jÕ*Í$�¼0&…I 4PÎT™˜X± h9C¥åa$»ˆH[¢dé=zh‘ÁµìzZ¶ßˆ´®Þ…ˆ%ZÒ5 Ú „ŒbÉâ—“%ZÌ~ö;sã¦6-œZwëÖMË™7Ï&ÖX6‘íP`98t豺OtºY{jÒÖÈù&�­ÔÚHÉàÀ8ƒ‹S @(¢ÛÇ®QP8@SÞ,òëÔ©cðùS»Ø‘£ ¬Ä:‹¾Ñ8ÉÜë™$ä%Œí@ !y5’š|0Œãöƒé„qà°àÄ)md*“‰äüZ<gøQNh‹ú˜†ø6ÑBÿˆÑL›6Í(U±èïžœÂ0+lÖ0¡ ¡—ž<8B|•¹5Pö”-^‹æ´D!\GÑìˆï½÷žÙ–(Dî:t¨'ßÐÇ·ÓÉ›?Èб�1³jñ”iaN懬l‰‹îñ8ì´éÁÐþ0—à9S¬(>´†©Æ ؈9Ëï¶£q¢±ÃM«ˆ‘àK)œFµ�;ÐÅ*K^ýÍÀ­·Þê1ÂXˆ£Ø§±óÃíùe7§WZì¾Z¶yÓ<Ú1üÜ@9š£h³tã J ßÐ"뚨I¬ƒÍ‘ÁA±“¯ªXÕ“×ÿè ¤PÄ"¼€ìædÛ6—Ïýðq äV',€ƒÖ«WÏŽSE Áˆ>uêT³ùŒœ£;~8,Š"îX8¯˜]ÌwÒÃØo1yˆÑB`ˆ¸?þøc%²©¯ " c7 `tFä Ú ÀýG ÙIøÌ@Ôˆ–éÄ5 Ñq~Êú„Ïÿcš“OÉHwE,p°˜¨ˆÄ,•„ä ¤vþœ—ªàe§¿����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/pow.png������������������������������������������������������������������������0000644�0001750�0001750�00000015471�11343041232�014514� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���3������“&Â��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi��GIDATX íW»K;AþŒ¯ˆ±´Ö? "(Q¬AÐ2Xø(-b“ "6‚•b)"øÄFI â „¤H@PÁˆ…’ø@ÝßÎÂ-âm wä."¿ãöf³ßÎ|³syŒ þˆ8þã?˜ßêÍœzæööSSSX__ÇÍÍ úûû‘L&ÓžUFzSÈ¥°¶¶6¶²²Â8 åVH?22Â&&&”ýš² í1ØÔÑÐЀp8Œ *­º\.”––âååEÙ¯)m ³ããcœŸŸ# iö‰DP^^Žëëk©ûÞ(++ƒÓéü®Ö}Ûæíí ÃÃÃ(..ñdtt¸¿¿ÇÕÕz{{±··‡³³3Ý(lÃã---p»ÝxzzBSS¶¶¶077‡öövôõõáèèÕÕÕ"Hz^__`4òXõŽF£Œo’}||ÝÝÝlss3­¹¥¥%ÖÓÓ#žýý}9nrr’ËoUÃò@ü¨­­…ÃáÀÉÉ …GÞßßQP 7ïõzA±<ÌêêêpzzŠ™™|~~"??_€RI ‹‰¤AÉ#§†<rWÚÞ,u<>> òS ÎPv²BlcÅÆUkêÂ,‘HàîîNŽ¥òâ'×Ê¿ !H©pyy@�ÛÛÛb{óóóðûýàååeÆ-××× bÙ©æ²Zˆ“ÂŒSQQº¨l�y¨²²RèvvvD6¢û!“Ð<Z+'ò=_s²2NTFù^“ééi­ù«ß:ÎP¦!7H¨vª©©ÉÉA5*ÃìëÄÖÖV,,,¢ðã.Áààà×aÊöìì,¨ÊÍ…(Á477 Òïî±Qî+S .šlPUM¿ÏÏÏ _â"A*•bü¦fcccªî¬ëxAɆ††ØÅÅãY”ñljʆŽ3t%%%‚'>ŸÏðᘙ ªªÍ¬£¬šùŸ[[[3u:F'­ªZ_çºýƒÁ ºººLŽÑIªªš²'UÕFE‚©ªªÿ×Àââ"xü]ÇôølTÕšqYh®®®¢¨¨ZŸmïlUÕŒm;·Ð 3 mضô?ֺݻŒ0ùÌ����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/sinh.png�����������������������������������������������������������������������0000644�0001750�0001750�00000017130�11763207066�014661� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���E������üP¡³��þiCCPICC Profile��X…•Y8•áÛÞ3{ï½÷Þ›ì=[ÇÇ(£”Š¢$ddB( #$¡’•$”"*…dÄ÷’úÿ¿ÿ¸¾ë{®ëyßß¹ßû¹Ÿû¹Ÿç½Çyà¨%„†!è�&Eí÷ð¹ºíåÃŽ4 Ô€Èˆá¡ú¶¶–à¿¶C�Ú¾¿Þ–õßùþc£÷ò'�ÙÂØÓ+œ ãZ� ÄPr�èmyB‡"B·qŒ™È°‚0¾º}ã†mìùwïð8ÚÂx� jì �~¦óE}a94Ô�`H^þ$˜•Æ:D?‚�0TppÈ6> c1Ï’ãû¿dzþ•I øþſײÓ(ŒüÃCƒÑÿOsüß-8(òÏ<p§t°€ï,°Ý Æ0fƒqªŸ·™å.½,4ÂÀ~—Þìaæ¸m#úEš:íâ™È@'}sÁx#0Äb›¶‚äimc à ÷þ–‰P‰ñstÙå±ôò62†1|Š®äû?ü~áQè11~†ÖøæÛûMãdyg-°ˆï =Ûó Àøzh„­ãî\=¤ ëݵ ÞûMìwñšwøÎzwæŠðs4ý-I€ß2‘\>þ&f¿u@Êù‘MÿÐõBƒvÎ4<éHŽ´ß¶ƒŒ}¼IN»2‘É^#‹ß6Aæ@�dà < ü|À£Ý+L'ÁW"Ap'óÑþy‚þ€îGO¡_¢'ЯþrþáþÀ ¾ÿ¡ÿ‰î�bÀgXª7ÿ3Š¥ƒÒDYÂW=¸+ ÔPêžõÌßÿ«Õo]}á±Ò»ƒ]í£þY{wÿò¿Œñü;âßu2ïw¤îrÈUÉÍÊmüÿcŒ1FSŒ FyYƒì@¶!»ÍÈ»€ù�Ù€ìFÞ߯ÿ2 a×*äõZÀ3zƒÈ_¤ÿ¨Qä_Ž]*2°ßᄟùÿÁyGkÿ“ wOXR�üÌâïÿXZ¶®2Ê�¥ Û¶1ŠÅ¤QJ°ÅõQºð(ÃTõ{•>;¶ŒÚYK ø�ãàïÃÛÝ0$4šìïëÁ§{Ko)>3QFŠOAN^lûÞ߯ö¢ýŽO…XzÿA ¹€ìÖÿ ±�Ô ÂnÔâ4!Ø/Љð “IŽúMCm_ЀЧŸö‚@ ÖS¨�M Œ9°ŽÀ „­ë‚a8p$‚.‚Kà2(×À pÜÍ  <Ï@x ^ƒ 0 æÀøÖ!ÂBxˆb‡x!aHR€Ô Ȳ„ì!7Èò…HP$€R tèTU@·¡F¨ ê‚ú¡WÐ$4 }‡ÖH5‚ ÁAÈ"Ôú „#â�†ˆAœD¤"rňëˆzDââ%b1‡XF$’É”Fª! ‘6ȽH$y™ŒÌB#«‘MðY|œ@Î#WQ#Š% ï¤)Ê ED…¡Ž¢Î¢.¡®¡êQP/P“¨Ô&æBK¢5ÐfhW´/ú:….CסÃïó4úƒaÁˆbTáÓî† ÀÄbÎb 071­˜~Ì;Ì2‹eÇJbµ±6X6›ˆÍÅ^Ç>À`§±?)¨(x)(L(öR((²(*)Z((>R¬ãèpÂ8 œ Î ;»ŠkÂõâ¦që”ô”¢”Ú”Ž””Ç)s(«)SŽQ.RQQ P©SÙQùS£Ê¡ºEÕI5IµJÍ@-AmH½Ÿ:’:•ºœº•úõ"Áëá÷â#ð©ø üCü8þ' # M<MM=Í�ÍZ­0­>íAÚÚ,ÚÚ^Úy:!î(]]#Ý0Ý2=#½<½ }0ýYúJú.ú,ƒƒ1ƒÃI††‡ ‚Œ†ŒDÆŒW3N3a˜D™Ì˜˜R˜n0õ0-030+1;3fÎc¾Ï<Á‚da1c b9Ïr‡eˆe•›UŸÕ›õ k5ë�ë '››7[2ÛM¶—lkì|ìÆììØï²¿á@qHpØqâ(äxÌ1ÏÉÄ©ÉIäLæ¼Ã9Ê…à’à²çŠå*áêæZææáÞÃÊËý{ž‡…G'€'“§…g–—‘W‡×Ÿ7“÷ï'>f>}¾ ¾¾G| ü\ü¦ü‘üEü=üë¢N 7ÞR ª úf ¶ .ñ Y Å U ã„Õ„ý„³…;„WDDE\D’DîŠÌˆ²‰š‰ÆˆV‰Ž‰áÅtÅÂÄŠÅÅ1âjâââ} e ?‰<‰^I„¤Š¤¿dd¿ZJ]Š$U,5,M-­/%]%=)Ã"c)“ sW括ì^Ù ²²›rÊrArWå^Ë3È›Ë'È7ÉWP *ä) *âMã¿)I*y+*(3*[)')·+ÿRQU!«T«Ìª ©z¨æ««1©ÙªUëTG«¨Ç«7«¯j¨hDhÜÑøª)­¨Y©9£%ªå­uUë¶€6A»H{B‡OÇCçŠÎ„.¿.A·XwJOPÏK¯L¸~€þuý/rdƒ:ƒC Ã#†­FH£=FÉF=Æ ÆNÆ—ŒÇML|MªLö(ï‰ÝÓjŠ6µ0½`:lÆmF4«0[0W5?bþÈ‚ÚÂÁâ’Å”¥„%Ù²É aen•a5f-lM²¾klÌl2lÞØŠÚ†ÙÞ³ÃØÙÚåÙ}°—·³ïp`tpw¨tøáhàxÞñµ“˜S¤S»3­ó~ç ç#—t— WY×#®ÏÜ8ÜüÝöb÷:ï-Û»¼ÏxßÅ}Óû•÷'î: zà𮃃Þw§u'¸×x =\<*=66„b²§™g¾çјMœóÒóÊôšõÖöN÷þè£í“î3ã«í›á;ë§ë—å7ïoèÉÿ[€iÀ倕@›ÀòÀ­ — ›ÁÁÁ$R éQOÈáþPÉÐÄЉ0°‹a d rY8~ ¼!‚ Nr»#Å"OENFéDåEý<ä|¨æ0ýaÒáîh‰è3ÑcLbJcQ±ÄØö8þ¸ãq“Gô…ŽzmŒ??}lϱkÇ)ž —ž°tÂåDÓIî“ÇN¾;µçTU"M"9q8I3éòiÔiÿÓ=gÏäžÙLöJ~š"—’•²q–xöé9ùs9ç¶R}R{Ϋœ/Lä‘Ò†.è^¸–NŸ“þ.Ã*£>“/39sé¢ûÅ®,¥¬ËÙ”Ù‘Ù9–9 ¹B¹i¹—ü.½Ì3È»™Ï•&¥À«` P¯°ú2÷å”ËkWü¯Œí)ª/)Î*Á”D•|¸ê|µ£T­´¢Œ£,¥ìW9©|âšýµGª•\•ç«U‘U³×÷_ï»at£¡Zººè&ËÍ”[àVä­O·=nݱ¸Ó^£VS]+\›_ÇX—\ÕG×/Üõ»;ÑàÖÐßhÞØÞ¤ÙTwOæ^y3sÞ}æûç[([N¶l=ˆy°ÜÚ:ßæÛö®Ý½ýõCׇƒìõ<¶xÜùÄäÉÃýŽÚÍ]]OÕžÞ}¦ò¬¾[¹»î¹ò󺕞ú^ÕÞ†>õ¾¦~­þ–ݶF/ž š >{iý²ÈihdxÿðĈ×ÈÌ« WßF£F×_C%¿¡{“5Î5^üVüíÍ •‰û“F“ÝSS¯ßßͽ¿1}òþCÖGÞ3 3ͳ&³}Ÿö}šž [ŸOüLÿ9ÿ‹Ø—Ú¯z_»\¦¿‘¿m}?»È¾X¾¤´Ô¾l»<þ#øÇúJòOöŸ×VÕV;Ö\Ö>®ÚÀnäüÿÕ´i±9¶¼µJ vR$Ü>>�|/‡ë7�û� ¤ù]í6$œ| v²i5pŽéÖÐMâÌ@‰¢:Ñ)Ìl+E .òÕ)êL|9Í0;½7C ÄìÆr›’ÝãçnQÞ�¾(þhxÁ3BÂy"Å¢eb¥â¥W$s¥Ò¤“dâe£å¢ä£â+íU–UA«¼Q­SKU÷×0ÑÒBhMi·ë”èžÒ Ðw4Ð1”4b7Æo˜|ÝóÑô­Ùkó‹!Ë!«ëa›AÛvöƒŽ#Noœß»Ì¹.ºmîÃí§?@Î΃ŽÀàÉDdóâòðó•óÓð· ˆ,zü)„6T)̉žq3²+jêÐz4SŒT¬Iœû‘è£ñ7Ž=9þ6áçIúS‰In§ÉgÎ%W¥tŸýžÊuÞ2íè…ÚôùLÑ‹îYÙsV.‰ç¹åŸ.¸[8}…¡H·8°äÜÕÒÒ–²áòïøJ‰*Óë¾7’ª+n>»õõkn­O]J}õÝž†ù&Š{üÍj÷­[œØ·Zµ™µ=Ô{¤õXí‰b‡l§dwׯӡg7»Ÿïë‘éÙêíé»Ôï3 ð¼¬™1:l3"÷ŠþÕâèÐ릱+oǃß:NhNòOa§æßõ½¯Îù÷ñÀŒÖ,çìê§¡¹šù󟿘|åÿºµ°ù]tÑméâòØŠÂόխõÈÅÍC[[;#3œ#ºƒ<0)Cg y„+b�y�Ο ÑvFÌ{ì}ŠR\eU>õCü­]<ý#F$“.s,K5ë[v&8*s%q—ótðNñ}áÿ 0(x_¨Tø¬H¨¨µ˜¨Ø†xD¾¤¯”‚Ôªt«L¢¬•¯ÜŠ|¯B™b¬’¥2‡ò{•*ÕP5µïê·4Â5uµ˜µ¾kê4èæëÅë4P3¤4ì7J5Ö7^0y°çºiYºy²E’e’U²ušMŽíe»rûj‡«Ž±NÖÎÎ?]^¸Öºåï=·ïÌþsrÞpoô¸M¸æYDÌõJ÷>ë“è{Ü/ÎÿP@x`h)8ˆâêæOŠéÈCчD'Ä$Åž‹Ë<Rp´<¾æXÛñ¾„©˧p‰<I*§mÏ&'¦½îUêrÃÙt«Œ€Ì„‹³*²›sús§/­çÓˆê^v¹Zt¦¸¢¤óêL®\üšyE`åÙª×{o,Üd¸¥tÛéNdÍÅÚšºþúÏ ØFþ&{vÍž÷ÃZŽ=8ßš×VÞ~ûaÓ£6Ø_õt¼èììjyZûìzwÙó+=ù½¹}9ýÙy/® 6¼ìz5üid}ÿšwLþѸË[òDödëÔì{ÆiÝAsg:f—ç„æ~®üJ¹pê;ûb÷ráJòjêzé¯îÝýgZ 4@Ô°ȇVàý çÖƒ(2šý ÓŒ­ ¨Ã½¤\¢fÂKÓ8ÒÆÐз0¼eB1K°X°ú²Å²ÇsÄrÆpÅpGòózòÙñk p ül:*,+<.’"ª&:)–(.!þDÂSbC2SJJªCš(dòe5d_Ê…Êãå+L¦”„•^(ŸPQP™T½ ¦¯¶ ~YÃVhÞÐÚ§ÓnÔñ×åÔíÕ;¥¯­¿lpÓ0ÈHÒè“q…‰ß1ØO”™y› ›¿·(±$XñX½±.´!Ø Ù~²»mã`ìÈè8étËù¨‹•+§ë'·Æ½§÷¹ìÞ¿tàÑÁ,÷�]+aÁó±Ü+ÑÛÛÇÈWÈé7åßp%0>è`°:‰‰ô5¤;´2,™n!ɹ5z¨ùpAt\ÌÞX•8ú¸¯GF¾Œï?öüø³„Î';Nu$v$=9ýðL{òÃ”Ž³ÏÏ ¥NœŸK[¾°–¾ž± G×¹¬ñìÞœ–ܺK}ys˜BÁ˺WöEÃq³öjwéTÙÚ5æ ÅJǪÃ× o<©ž»Åp[íŽ{MbmuÝPýfƒh£}ÓÑ{•ÍÃ-¨Š­„¶´öև󙞨wè<Ú•G´þîï=æ½¥ý˜ ¯^Ú uؾz3Æ;^;ùpš<ÛÿåÙ’Öêæöþÿþl»aT�(éÀE�[� á:s�Úø7�Gu€ÐSm�ÙÍýXÀÄ\Y‚°©Ýà H²üá*°j‚†¡%Ba‡G\D4!&8¤2Ò ™ìEQÀ5øTj ­‰>†îÀÐa`®c6±vØ2ì…E% ÀQÚR>¡Ò¥j¤V¦®Á+âëh4hZiMi{é\é¦èIôk §Y˘T™:™÷1e9ÉÊÁz—Í‘m‘=“C…ãç.®.î0NžÇ¼a|‚|oø³àˆå,Â!òŽY$qUñU‰Û’RÂRï¤¯ÊøÈJÊ.É=OUpWTR¢Vú Ü®rEõ˜AÝHC\“Vó'œ?÷é<н¥wU?×à‚áY£$ã“#{™†šùšï·°µ4²Rµ–°á¶¥·£´Ç:`qNÔÎ .œ®"nŠ{ ÷9í÷?0Û½Åã«'?ÑÑë´w‹Ï’Ÿ„¿gÀ¥ÀÁ`’YHb胰ÕpÕˆC‘÷!ÛFŬÄÙ¹Ït,&y"ó”XbËiç3 )çÎɤö¥E¦se¬^ü”=‘;ž÷±`õ [±ÞÕ²âkµ•®¿¬þxëg e÷]¹F£{®÷ƒœh+|xÿñd'åSµîÀž¢¾Ñü/C†ÛG9Æ¢ÆG&uß]ÿÀ5£ù ?7ü9ë«ùÂâ÷´%áåÛ+*?ë×ä×Ëqm¦îøF Làø 2À Ð ÞMˆR…ì  ( *Z¡qhÁ ×÷ÞˆÄÄ(”Gº#Ï#ÛK( ”7ªõ­Š>Àˆ`â1cXl=ÅqŠe\0n®†ŸRQ=¢6£Ä{ãÑ\¢Õ¢¦ ¦ô b ­Œ˜L·˜I,¬¼¬OØHìLì÷8œXÎ\\kÜ%<Ö<ë¼U|'ø½L%…¨„¦…›DN‹Ú‰±ˆˆçH%m¥d¥é¥—eFeÛä*å/*œP$+•TÌTõÔÔÔå5¤5%´ÄµÅu$ueõ”õµ L í™ÄîI1Í3«2o¶xn9nõÍeËn'e¯çàìì”è\ärßõµÛú>®ýº¼&»7y,xŠ=½ò½G}Yý\ü³Fƒx‚=I!ßÂɇÃ["1Q¶‡òÏĨƞŽ{}T6þÔ±7 *'2N~OtHj8ל’²v.8u*mß…¡Œ}™3Y‡s(s¯äiæ¹"\4Pr¼T¹lîZ{eÞõˆjë[¢w š×uuwÓƒîéÝGµ<mMoß÷HôñRG{WÆ3Ÿçê½´}Ê=‡x†G_e¿v|Ã0Þ7‘6e÷žizäcö¬Î§‘yÂ瑯: Ùߦy–l—cä¯Ôÿ|¾:¶6»þ}ãç¯Íÿè€$0DpdƒÛ  L€ˆ’€L O(~÷[  !а„ßü|DâRÞý‹È%Ê•ŒêCs¢Ñ1²˜B,#6•‚‘¢§{ECÅKÕEƒ—ÃÏÑTÑúÓñÐÐg1¸2ò2~bjd¾ÀÈjÊ&ÊŽeŸáèæ¼Å•ÉÇãÇëÂgÁo( #¨-d(l%â*ê%&/‘*Y U%Ý,Ó/;+VR4Q RÎVy¨º Î£a©£uM{X£§ª`PdøÚ˜ÍÄuO¾é;s%8˳V°9mûÖ^Õ!Ýñ³³•Ëm7޽Éû¶ÄÜðˆ$<% xÅxÂyæ9ÿ¹@‹ $ÆøÐ9²sx[¤DTœazÇôÆyop¬;ÁãįS%I¶§&û¤ 3MmJ“½PšÁ™Å˜}>—åRq¾LAãeƒ+]Å6%ƒ¥®e¯¯yU|©Š¹©Îº%r»¡Æ¢v¢>ªßXrO³y°…ÔŠk+}høhêIB§P׳g±Ïe{fúÊ•‡0Ãc¯î¼Vk×xÛ8©<uã=ÿtÚ‡µÏÙŽ9 ¸ÖˆûBújµ ²ðéÛÍïn‹ˆÅ«KÊKO––8üX1_¹ÿSögñ*íjôêÔšåZí:Ûú‘õÉ ãò_¿ü~umJl&mNonm︢ÂNø€¨ àdb|kkQ é�üº°µµ^¼µõ«.6Æ�h úýÝe'ÖÐß·:<çŽýë÷ÿêéÜ€�³‚��� pHYs�� �� �šœ���IDATX…í™_H“ÿÇ_Î¥F“H]›)‰H7Ù’’%HH e„þ]Hbñ@aË®ª‘vEQØEÀ.¬ f‰9–Íb–VfY”S ·¹é°[Ûçwѯ‡ösº¯öø á÷†çâs>çsÞ‡óœÏÙ9Ïâ„‚ÿ#ª¿íÀL188È­[·¦uæÉ“'tttÄVs_¾|’$‰P(4í³µµµâÅ‹Sêü• „Ãa1<<SÏçóMƒA±~ýzár¹"än·[ƒÁ˜6ƒÁ (,,£££“êü•ëÓÖÖFYYÙ”:×®]Ã`0Lß¼y“ôôtÒÒÒ�ðù|H’Dee%ÙÙÙ¼yófJ»jµ£ÑH]]ÝäJ1C;K‡ÃSî;±|ùò òââbqîÜ9yÝÜÜ,gÈÉ“'EMMMLî{÷¬¬I÷ÿ•Lijj¢±±‘ææf�FFF¸{÷.�n·›7nðõëWL&ííígß¿Éd’ dGGK–,‘÷‹ŠŠP«Õ�„B!¶mÛ€›ÍF?�V«•P(@ff&}}} EõwÖƒòøñc>}úDii)oß¾%ÓØØHUU�]]]ìÝ»—––V®\III â¿]‚×륳³ƒÁ@qq1@€ÑÑQ"8œN'’$ÑÐÐ Èåra·Û9räwîÜÁjµâ÷ûHNNÀãñDw:f®ý!,‹X¶l™hjjcccB!z{{å«1>>.~wC«Õ §Ó)‡ÈÌÌ”åééébppPèt:qýúõ <###âÀÂ`0DÈ´Z­øøñc„î»wï ¢ú<ë™b49sæ åååH’S?>>žp8<A®R©‡Ãäçç3000aáÂ…˜L&ùº�Ì›7!‹-ŠÐD¯×“‘‘Õ‡YJKK Û·o§§§«ÕJ__âg+0#{ååå<þ<êÞØØ7n”×÷ïßgëÖ­<}ú”ááaYÞÞÞΞ={&åPÏȳi```€'NPRRBqq1z½ž+W®044Dgg§\ìl6IIIx<ÚÚÚðù|¸ÝnºººBàv»±X,ìܹ“K—.144„N§ãСC¼~ýš]»vñãÇΟ?O}}=v»cÇŽ‘˜˜ÈéÓ§¹xñ"©©©„ÃaÌf3 “;=³JñÏ …D0G1›ýýýâàÁƒòÚãñˆ@ ¯ý~¿—׿7µµµ¢µµuJûqBÌÍðóçÏ<{öŒÝ»wÿã3="%%…¼¼¼)õ&Åår!„`ñâÅ�|ûö §ÓIvvö \Ÿ›kʯ&êøñã¬]»–‡p᪫«q:twwÇ4¸fÍÔj5/_¾”´¹€U«V±iÓ&à· ¤¥¥!I , ²²—Ë…V«E’$Ìf3*•Š‚‚‚˜Æ].—<—ÌYüo‘ñù|"11Q\½zU–:ujÚÅPID›“ü~ÿ¬ñMèS’““)((Àl6?gÜÜÜýeôôô°cÇŽˆI‡ŠŠ <xÀþýûùðáƒâ¼Qû”¢¢"._¾ €ÙlF’$„ìÛ·/¦Áºº:4"Îeddðýû÷ˆ·ººšÂÂB¶lÙŠ+¨¨¨ µµU¾_ˆÚÑFúúúhjjbݺu²Üï÷Ç|”Drr2III²Û·o“ŸŸ@NN¯^½Âáp(Ê5S ñññ˜ÍfùcL\\õõõŠ’O^¯ÇQÈSSSéííeéÒ¥ŠñDÍ”ùóç“››ËáÇ#R@�ø94þÂdäŸ jPìv;555èt:EÉþZ­Fƒ×ë•e£££äää(Ê3!(N§›ÍFii©¢DJ@¥RQVV†Ýn;m%¯üVS²²²ÈËËcõêÕ=zTQ’™¢³³“îînôz=6l@§ÓqöìYªªªÐh4X,ùWRIȳOCC lÞ¼Yq’ÙÀðð0)))ÄÅÅ)n{ÎNɳ‰9û·élâ?³@,ˤ$ñØ����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/square.png���������������������������������������������������������������������0000644�0001750�0001750�00000015313�11343045612�015210� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���#������ÌúWé��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi��ÙIDATH ÍU=H²Q~ü²¨–(²¡† Ð²l«©2 *\'‹Öµ"°Ÿ5Z ÊņÀ)Šh¨AÁÁ@Dú¢†&E‹¨†z¿÷x_-}¿šÞ¾;Ü{î9çÞûÜsžs¯Fþ“öç7p„Ãa˜Ífô÷÷c{{»"£f+‹Âúúºðüü,œŸŸ ÂÅÅC€š@è¬T*%¼¾¾ÊÇNOO GGG<×–b¤ŽÔÝÝýé ÇÇG ³îW8#¡9==Åüü<t:Ý¿¿Çíí-æææ$lP3DŽ|>/x½^™7"(–5Ô4Òé4âñ8ÚÛÛå<ÞÜÜ ‹Áf³•nð)›Í‚Ò000€ÑÑQ¼¿¿c]]]p»Ý¨¯¯‡F£ÁÇDZ¹¹ L.—C4Åââ"´Z-‰¹··Ç¡|xx€Ïçû†ÃáÀÛÛ¯ßÚÚB&“ÁÕÕVWWqyy‰¡¡!X,–Oûtvv¢¹¹¹F²ž±óõõ5zzzXMyÝÝÝÅÔÔ”ä¦8£©©‰í°Z­ðx<Kz½^q*J{rr’QžœœÈ`ŒF#êêê …þ¹ÙW#½²Ôžžž¾B~¥]SSƒ‰‰ ²# þ("ìü¥£’•Êö‹©ê´"2ä5>>Ž &5åyaaåÞÞÞª›”+#‘G–tÄ1"¬øì—»(ÊUÁŒŒŒ€½³³ƒ™™^LÌ_YYQÜH2ˆ ‹t ’éQ[ZZâª!"÷õõqIþåcU0&“  §º££CöŸ•e%Áår¡¥¥µµµX^^æj* \΃j¥µœ!GâÍØØœN§Ò:E=q„K%NÒ´¶¶†ÖÖVØívÖ)uò;SîpxxºEHÍ&G&™LâååD@zôÔ—æOAìÄð â÷.øý~I¥ú(§éîîŽÿ‹¶¶653ó鬿0`ý´#Ø~n����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/img/log.png������������������������������������������������������������������������0000644�0001750�0001750�00000017234�11343041232�014467� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���N��� ���¼TN7��­iCCPICC Profile��xíZgTM³î™M°»äœ—œa ’sÎ 9çœ%ƒ’$H*‚ˆ(’$Š‘¤((#‚*‚Š€Ä;àëýÎ=ßù~ÝûïÚçÌ̳ÕÕÕ½Ss¦kê)�DK½"#Ca�@XxL”µ¡ÉÑÉ™„{ €ô€  ¼|¢#µ­¬Ì•ÿЖGm¤HîØr®x™.÷0Ôõrm¶¨—ÿôGL…L�d…~cßìý'ìàø˜ÈDçðö ôBú¡*KDÙZë"ø�Ä€]Lùr{ïbº©ìå��Û¢Oòò @0;ío콃É;8Î'�±ÏެK9°¾~Ñ>�Ct|}£}Â�¦��Ö ‹@úEwOd2V9€ÀνC®Hó¹�€r�¸cÿ’…Pß�oοdBˆŽ"DÎü/ÙëÝû 1?Šö—“Ý5u�À¼ÛÞþ!„ØDô7 ··×ÏnooÖ�€z @w¨OlTÜ®.@ï\0�h�#âAnÀD€$Š@h}`,-pîÀ‚0âA2H‡@>(�ÇA¨çÀEÐ ÚÀpô€»`<ÏÁk0¦Á°�~‚u‚p¢‡X!nH‡d %HÒ‡L!kÈ ò„ü¡0(J†2 <¨:UCuP tê†îA¡—Ð4-Bk0 `F˜„¥`EX 6m`WØŽ„á ø|®†àø6<?ƒÇá/ð¼Â£˜P$”8J¥ƒ2G9¡üP‘¨dTªU…jDu¡î ž¢Þ¡fQ«h4šÍ–@+£ жh/t:‡.EŸG_F÷¢Ÿ ÇÑóè ÃŽÁ(b 1ö?L &SŒ©Á´cú0#˜˜X–+€ÝƒÕÇÚc° Ø\l¶{;ŒÀ~Ç¡pL8aœ2Π王ÄeàNàêp×qø÷¸%  i  {Š`ŠŠ"Šó×(†)>P¬P)y)(M)=)c)ó(«(;(‡('(—ñD<^o‰÷Ã'ã‹ðñÝøøy†ÀE'˜|û Å„Bá á‘H ªí‰áÄlb5ñq„ø• KE¢R¡²¥ §Ê¡:KuƒêÕ"5‘Z˜Z‡Ú:º˜úõ õG˜†›F…Æž&Šæ(MÍ=š)Zˆ–›V•Ö‘6޶˜¶•v˜vŽO'Bg@çK—AWM×M7N·EÏE¯FïBŸD_FßEÿŠþƒ2ƒCCÃu†7 Œ\ŒŒŒiŒgû§™pL¢L¦LaLLmLÏ™V˜Ù™Õ™=™3˜/02ϳгìaqb9Àr–å.ËVVyV'Ö¬5¬÷X¿²1°)±¹³e²Õ³=f[fçb×ef/`¿ÂþŽË!ÉaË‘ÌQÃ1Äñƒ“ƒS—3”³„ó&çG.j.E.O®<®v®1n,7™Û™;“»™û%ŠG’Ç‘'ƒ§™ç M"“\HÙ¤vÒ;^<¯"¯ï1Þ¼3|L|:|‘||ƒ|«ü‚ü6üiü—øÇˆ*A'î ü´Ìlœ¢ÒŠªF Ë û Ÿ^q9"rKdA”OÔN4[´KtNŒGÌZ,KìªØ¬8·¸µø!ñkâó|öy·%–$E%Ý%‹%ïInJÉII‘z&MÖ–Ž—n–ž"s­É¹äòª Y&@¦Ræ…,¬‘ìAÙ«²‹rbr>r§åžËÓÈɧËß_ÞCÞ¼§vϸ»‚BÂ"VQG1E±Kñ§’ŒR˜R½ÒGe~eOå å×*,*¶*E*T©TMUsUÔ°jzjj½êº–zªúmõ- [[ššš©šÝZ@K[+]«_£m¨£=¨CÔ±Ð)ÔÑeÖuÔ-×}§Ç«ç§W§7§OÖÑ¿ª¿a ee0hHmhcxÊð¿QÑ%£ŸÆªÆiÆ&Ô&v&å&“¦b¦ûL¯š3#³³—æ$ó@óVó5 ‹ÃÏ-¹-,[-×­ô­ŽY½Ú+°7|o—5ÚÚÒºÌzÚFÆ&Ùæž-£­§m“í/;»"»q{ û$ûFo‡‡-G3Ç2Ç'%§CNÏœcœû\\|\Ú\Q®6®5®KnznÇÝ>º+ºçº¿öðHñxìÉçã9àÅæêuÛ›ÞÛϻˇèãésÙ—Â×Õ·ÕãçìwÉíïä)�àЈ t l ¢ òê ¦ ö ¾ÂÒÊ:Æ–ö<\*<;|"B%¢8âk¤aduäú>û}-Q„(ÿ¨žhÎè„è‘é˜ü˜O±º±U±qNqñ ñ‘ñà ⠹ Ÿõk’à$ϤÛû¹÷Øÿ6Y-¹<yý€Ëë))É)oSÕSϤnô<؛Ɵ–•ö)Ý8½!ƒ:#2c$S!óTæF–gVß!áCù‡¾eÛf_ÍáÊIËù˜k–ۚǜ—œ7™o”ß|˜ñðþÓGŒŽ\:Êr4åèô1óc\Yó…ö…·‹DŠ ‹ÖŠ}‹–(–T'=>qÂäDÇIÒÉü“+¥Þ¥Ã§TN/£/K)›-w(ï?-sº²‚X‘XñéŒÝ™¾J™Êª*šªUsÕ.ÕCgUÎÖ×°×äÕ¬ >÷¦Ö¬öÆy©ó•h/¤_Xªó«{yÑäâzéú³ L 9 ëšì›†š5›Û/‰\ªh¡kÉnÙhÝ×ú©Í­m¤Ý¸ýöe…ËMåô¹W +‰W¯]}ßåÜõôšéµþë×¯Ü ß¨¿)póÌ-¶[Å·©oçv£»S»×zâz{Ãzgúüû&û=úßÞqº3z׿î“‹÷LîÝ¿oxÿî þ`ÿîPï=µö ë ÷>Ò}Ô÷XïñÝ'†Oî=5yú`Äbäñ3›g£ÏŸ¿u|á÷bæeØËÅW±¯Ö^§¾A½ÉyKý¶xŒmìÌ;wõã2ãW&4&î¼7{?2é<9ù!øÃ÷©¤ix:ÿ#ÃÇÓŸ?]ú¬ô¹wÆlfô‹ç—/³±³Ûsy_™¿VÏKÌ_ý¦÷íñ‚ëÂÌbìwøû±œ?ê——îü´ùù~9bykåð*Çjý/å_÷לÖ>¯'lPlœÚݼ¶eºõv;üo,ð7ø üþÆc¿±ÀßXào^ào^ào^ào^ào^ào^ào^àÿo^ Ò+Êk7@!gØáf¾#<•�   þ·ý¿y”ßÑ@!¤Ð±„Bx ‹ð 5`Ò:a¸EFõ ý1$Ìl?®‰âe+~ˆ°L%MíOÓB‡¢·d8ǸÆlÁr†õ »4Ç>ήq’¯'_…@§à#¡Âë¢Ôbâ{$ %¥ü¥cÈereÉÉï)R8¬˜®” ¤â¨j FVg×€5f4iujŸÖÉÐ Ò³ÔW4à1Ä.½1¾cÒbZa–ožddébe¾WÛZÑFÚVØŽdÏéÀâÈäÄèÌèÂäÊêÆéÎë!ì)å¥è­ícîëäàp(ðdP]𵇡ïÖ#‘¤} QfÑ>1I±…quñ·ž%Î™ˆ§h¦ÚôOKHÏË(Ïl̺yèaöÛœ¹Üõ|ÂaŽ#âGÕŽYxFeW”´<ñáäæ)Ö2¹r«Óa‡ÏÔWÞ¯ú|–¢Føœamàùœ ë/Î6%šÌ›Ã.min}Ø6wß!Ò©Åëê®Òk­×oLÜ\¾ïæì‘èUéÓï7¿cs×~ÀîžÍ}óAý!ÕÒIÃ4Û>?yrýiõHÖ³Àç&£¢/(^L¿ìyuúuÜ«·bc¨±±wWÆ 'BßLòNn|x9Õ>}ôcÐ'ƒÏ3˜™Ï_žÌvÏu~혿ýmdáÇwÞ.KU?VÌV[Ö8Ös7ÁVÊöö®ÿ©Â; 0†pDå0œ¯¢rЂè!LÖG¦à¡dÂs”‰ÎTÔ4‹tdú`†&ÆYfaWÖ¶[ìŸ8±\BÜJ<f$g^¾Hþ8ý‚©BéÂé"é¢b©â$$÷IH;“Md”dyä°rŸåïí©U8¨è¤$­ +?W©SMT3QçPŸÕ¸¡yDËC[V¥3ª[¯—¢ok nˆ2|ktŸØdŸ©µ™œ9‹ù¦Å´å°U×ÞZëb›tÛ(;o{=G'gv¢Ë¶ëw·i$üгǫӻÑç¬o™_‘ÿ‘€ÜÀ¬ Ìà¬ìÐü°‚ð•‘öµE݈ˆ‰}7ÿ3$ö3%“ˆ¦È§ª4H³LwÌðÎ ÉŠ=t0ûpÎÉÜÚ¼öüÞÃ#G¦® IE{ŠÍJ|Ž'(:ÙPÚj¬lù4M…È­J§ª¨êü³çjnž{Q»xªNô¢Q}@CncSÓHóF‹p«M[Z{ËåñNš+šWû*® ^_¾ÉsËðvhwAO[owðwÔïÙÞL:ú òaóðõGŸ>yóôÃÈ—g‹ÏWF7_¢_^3¾áy+9¦ñÎf<d"÷}Ãä“ÓâÝ?•|~ø7«;—öµ{~{A{1óûý%ÚŸÎ˵+K¿ô×J×ç6u·ÎìúÀäÆ1´‚¯ T‚p~.p?J uí„þ…©ÅºâH¸oC”ÍøRB61™*Ž:’&€Ö‹Î‰ÞœA“Q”‰‰i‰ù)K#k›3»ûÇ}Γ\>ÜÒÜk<ý¤£¼Ž|||3üÍÑ‚Š‚+BÂûD$DÞ‹–ˆˆý¯”0–X,‘R–z-½ŸÌN¾"c'³ {XND®WÞM~uO±‚”Â}E?%H©BYUù…J¬*ƒj«š•Ú¼úa !Í-¢V“¶…ö¢N‰®²î¸Þ!}iýW™†²†ï uš\4u7c2{`ži¡n±bÙf¾W|ïŒõ›�[Û»ûp²Ã’c—Sгž ¥Ë#×nîîBîóW<ӽ̼Y½§|Ú|Óü¬ýùýWÖ%;„È…Ò†.„= o8™´Ï3Ê Z2†)f;v&îY|wBSbyRÞþÄäà®)©ÚåÓDÓ¹33 YpÖú¡¥ìùœ™Üi$Ó?qxüÈøÑ‰c >~-úY¼yœâÓIþR¹SúeNåá§UT¹Yù®>+Vãp.§öÖùÕ:Å‹Iõ=Ä&çæ†K[­¶mM—):|;û¯ uå][¼á|óîmÅîæ^‰¾ËwÌî.ß»6Xþ vxì‰éÈÂèÈ«•1ß÷Ä©…Ú¯n‹m˺ëÔ;þÿͧïì X�N,�àø�V�òÜ>ý ÂÍŸÀŠ �[e„Z? …�…dý÷þÁÈcí‡<='A ¸&æ™’„ /h?tj…†¡Y˜à ø0Ü›(!Ô^T ¡iÑúßÛ‰^ÄHaÂ0͘E„ÃMFvjœ î"nœ¢†bƒÒ‘²ÏŠOÁ$Øúˆ Ä&*aªsÔ‚Ôu4R4´Ú´èÜéè3¶³•Ñ”ñS&3?s?‹?+žõ›Û{-‡Ç:çE.n÷Už7éoÂ(®ów씜ªFžËo¢—Œĵ%ðÏ$«¤Â¥ÕÉÔä÷2²ùr>òê{Øö¬*¼T¼¦T©œ­©êªfª®¦AÖÒâÑf×aÕeÕãÐ'’TLLÌÌó-ª,;¬†ö~°^·e´“²7qðwÌt:‹ð^Sn8w kÏ$¯ïG>~bþ.G{‚VB¤CƒÂjÃ?Dòïó‹ª^ŒUËŽMNJÞ?r@2%/uy/]ÉäË*ÊÆæ¤ænæ<‚?ZV Sø¨8æ8éÄHéÑ2ËÓ¬Ÿ+oWWÔ¤Õ†]ðºèÒàÖx)±µ°½¥ãùUpMú†÷­Òî§}ÔwÌŽÝö€s8ðñ•ŠçŽ/j_ͽ}ç4‘4™;uècÔg‹/³¯¾æ“[xú=èǯŸ™+øÕâ5æõ’Mš­C»ïN ¬@ÈÕH-Â(XDj„ mÈ JD¼ß=‘E¶Cª*á»ð7;ʪC|Ï€6Cg£û1hŒ&óˆõŶà�n/®·ðñ플” ”ïñæø[9B#QŒØH%Gu“Ú”zŒ&ŠO[K§K÷>›A‚á9c*“8Ó+æ\–¯¬UlvìöŽDNYÎ9®:n?žiRoŸ<ßÿ @©` ª0ðG‘nÑr±q EI6Éu©qé~r½Ll¼œ‡¼ÑYNEJÅe¥iåQ•{ª7Õ.«7iÔiÖj×®ÓiÒíл¥?dðÚpÖhË„ÁTÜLÏÜÝ"ɲԪsï¨õŠ-›ª½‡C¦c½Óç_®ünîû=.z¾òÆûhøFû5øO’‚܃+BÆÃøÃƒ"Z#×¢ô£ bÆâÄâãî$Ñï÷Hn<°šªw°0m,C,3!k ›%'8÷V>Óáð#CÇÄ Ž®û”Œœ0<Ù}J½ìÖi½ŠáJתù³YçHµÝ|/RÕ_k mæ»4ÖZÑîÕ!Ú¹tµïZÉ€[ªÝ´=ú:îdXÝg|ó lØö1áÉ­‘ðç£w_F¾f}Ó34N7Ñ5é=Eœîøä1Cñ¥uÎyúV·hù}i©tYueüWÆºÐÆÀ–ÿ®ÿù�¹ <ß :H²‡’ Jè43ÃÚp8|~ŒÂ¢4PûQ×QÛHGú=Fñ÷V[ÃàBq/( )®SÊS¶ã•ðýÂwb •&ÕwêFšZe:âã^†óŒL©ÌÑ,¡¬Ál¡ìÑ9 ¹.p÷ðLðB|‚ü¦Q‚åBýÂó¢ìbFâñu’o¥éÈÆ2²·å6÷h ‘Æe¢ŠƒjÚ }Ír­:ºúDƒpÃce“j3¼y´Å˜•áÞVÛL»yGÇ^gI—SnX÷)/;ï_¿K‚ÁL!ÇÂðá‡"Ñû2£Ñ1Ùq„ø‚D–¤ÊdÑ—Sµ>Lw͘ÍÚŸM•S™'›çˆãѹ‚Ô"†âóÇ•O<(õ8õ½<³‚ùL]•rõ½ûs“çC/ü¸_¿Ú×´x)¨å]›u{o‡LgåUBWܵ‰&7Ûnstgô|é³îïºË3pèÞÜàޡ·é&Ÿè>=;²õÜa´áÅÚ+í×ioºÞμ#Ž O¨¼×˜Ôø =Å9µ9ýêcç¤Ï3ðL×—ÈYÒìÐ\üWÖ¯]óŽó‹ßòH ­‹º‹#ßݾþýcuéÀOègæ2z9k³’³Š_=ò‹êWîv-cmc=výë†ÿÆëM‹ÍÞ-…­ºmöí#;þÿ]ƒµ³�¼nDhDÉLWo÷çÿÝ),4©óÚmôÈ™j±SÛÅŒŸ}½ôL‘+'rlE†îÖÁ!:»_¸ "ÛÁáÞ–ÿ` ÿ(k#c!«ÈŒìudŒ•í?ò”¤@] y‰_´þ;UÁ^&H  FämQ±Öv@pwtœ>‚i<•hëðÎ’¯ŸÞ?rö20þ­ÓÅïÌň|€ñ…D˜î¬™ V�¦ ÙIc‘Š/?ŽÔ„™!ßezÿœ%?ðBzâ¾hä}ûÁaȈdL‚Iÿèéþ›Ä`w\�2îZ$!õeÈlæü= ™óÍ à‹à?r/d޾ÕE{¥ÿkÎ?;övWCn Ï7þ¬ -„–EïAë ÕÑhe@B3£Ù$Z­„ÖFk¢U‘>e`�¦ËÖ¸c?¬Í?®4"QÅ>éÝùïÞzý®vÐÿþ·€ á¹+sV€ÔOîÖ"w`?öÚAÝn;@ÿ³Åø%ìÔ ݈ÈĨ €À’6R5é'A2÷‘’ É’eÈà¿�‹hþv|Èœi��ªIDAThíYiHT_?.•-f XQJ&õ¡=+¢ °l!Û´B30 "¢"JÛDêCF–¡´H}È 2H­ @MͲ2‚V ÚWÊl%o÷wâ]fÆ™÷Þ8¾ùÛŸÌ̹÷ž»{ιçþÆGH¢ä¶|Ýîñu(//§êêjËg?zô(½{÷Îpž¿BqÅÅÅtçÎ=z´á†<HHH ŒŒ úøñ£þPpU«éׯ_âÕ«W-šæáÇ"&&¦E}Ívjjj²•‡$æÏŸoWçX°ÜâÞ¼yCñññ´cÇýtѺuëVZ°`‹VϪŸ?N«W¯¦ÌÌL»"##éñãÇTYYiWo[°\q={ö¤qãÆÙÎišÿþý;µŠ‹6444›700:uêD˜Ç‘Ž9âX­Êþгñññ±½¦¦†îÝ»G4gÎòóóãöëׯÓíÛ·©}ûö4räHzñâo*$$Ä®? ¯_¿¦[·nÑÀÉßߟúõëGµµµÔ½{w £+W®Ð°aèC‡Ü‡y[‚â°†Ÿ?ÚV3ß·o_:qâD³z­Âr‹Ó&Ò~aAöK–,!XÁŒ3HÆÞTVV%&&Ò©S§hÛ¶môôéSîEÚÚqû?žâââX7!.U«VÑÙ³géòåËôùógÛnnñPêû÷ï]öñŠÅÙξ}ûv*,,䪤¤$Ú´i§×®]£Î;s}ll,ݼy“k@P�\ «ÌÍÍ¥ .pm°NXbéúõëiÀ€| °ÀcÇŽ±ÜÛ·o);;›ù¡C‡ÒäÉ“™wõ+ìÚµ««fòºÅÉÛ•|}ÿL‹ßˆˆBÝÌ™3Ù½®^½Jò&¥eË–ÑàÁƒ©K—.Êò°‹ôôt¶*ð—.]¢ððpVÊ P°v�pÓnݺñá@ã;vìq]zöì >Ü¥Œ×-±n„S}úô‰FŒÁ§»nÝ:ÞtZZi›[´h!&"^»òóó9.åääÐĉÙ¥ÛæÎKH–a-C† áúíÙ³‡’““Áš"$Û›7ov)k¹â'p­#˜¿|ù’öîÝKpѨ¨(zôè­\¹’úôéîk‚›ÁbÆŒÃqéHJJ ­X±‚7EAnÒ¤IJOž<¡Ó§O³ráöÁÁÁ´fÍvsðzˆ‚`H?07õ°ô)S¦pÙé—cbç2â»wïŠ>¨éNž<)êëëÅýû÷Å7Ä„´4n—Á^>|˜yô•ñŠù¯_¿Š?~ð§±±Q%­Xñî2O¦­Û7Z› yˆsçÎ i•¬¼ýû÷ [eœ?^TUUY¾Ö¼¼<u0z“ù ÑÖ‘飪W¯^\-Ïn·°’×pÞ7E~瘆X9¿»c+Åáº>~ü8mÙ²…ÆŽK%%%<Ö®]»8H"F!O2¢Q£Fñ-WWWGgΜ1ÿ«ÚqË"ï©Ë¡GünC`NMM%XžKxË•––r aæé„~ëOŽ~ŒÀ*ó!ÝF5íܹSñÿ˜?h–�ã©Ë‚•äí§r®¶nEF`§YÒÌ>•«Ú ã9rèÐ!®‚á®RÏ*—²•uäwïÞÍ9c½Õe$¿�–/_îr*€”H²#áá 5³8 6aÂN,ËÊÊ(::ZÿíÛ72ú(a7 &òííf7G"-Ó]¥A°]»vœp#¡ö˜œÅ¬/_¾™M‹µk×:knõ:$›@\¥e·hìÅ‹ÛÅd£A$( ***ŒÄtÛZÞ‰xKnذÁãƒ13€·ÁN#ÒÌšÆ8@<ÀÃz÷îmfŒV‘ñ؉Å”f6ÔÌâèʧ Íž=ÛLKd¬;µÅ”šœÞ¯²¸þýû3þˆgãÆz},o³ ìÔnRjrz¿JqH#ð6œ5k–ž¼WÚôÀ΃’-Ø9hÐ vjïk=°0)ÍlR¹ê¼yóÚ„Ò°h ìÔ6 AAAœ‡áY°@%R ìÔävâÍ ËÚ·oŸ;µv`pøÏÃ#Ò½s½Ô(ÿh .œ2‰T°/^2glK´$AO!+¦N*$È)€ÏÉ?uÄ´iÓÔj¥×ˆ¥K— ù÷ž ¯¾öàÁ1}út%ÛR¦ÍàqŽhm°ã›)×â¬Üfçl±ž‚fAJgs;Ö)<Î#÷Rç¶vþ‚tใ"—ü����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/contour.html�����������������������������������������������������������������������0000644�0001750�0001750�00000005204�11426312317�015004� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Contours</title> </head> <body link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000" bgcolor="#ffffff"> <h3><img alt="" src="../sun.gif" height="98" width="100" align="middle"> Contours</h3> <blockquote> <p>DS9 can create and display contours as an overlay on an image. The Display Contours menu is used to display contours. To create, copy, paste,&nbsp; and configure contours, use the Contour Parameters menu.</p> <p><b>Contour Parameters </b></p> <p>When creating a new contour, a dialog box appears, in which the user selects the number of contour levels, smoothness, and the distribution of the contours. </p> <p><b> Contour Levels</b></p> <p>Specifies the number of contour levels to be generated. A typical number is between 1 and 10. Note: large numbers of contours can take a long time to generate. </p> <p><b> Contour Smoothness</b></p> <p>Specifies how smooth the contours are. A smoothness level of 1 will evaluate the contour at each image pixel. A level of 2 will evaluate the contour at every other pixel. The larger the number, the quicker the contour will be generated, and the less detail will be available. </p> <p><b> Contour Scale</b></p> <p>Specifies the distribution of the contour levels. A linear distribution will have equal spacing between contours, Log and Ln will be weighted at one end. There are two ways to indicate the contour scale, Use Frame Scale (automatic) and manual </p> <blockquote> <p><b> Use Frame Scale</b></p> <p>Use the color scale that the image is currently being displayed in. Therefor there is a one-to-one match between the image color scale distribution and the contour levels. </p> <p><b>Manual</b/></p> <p>Manually indicate upper and lower levels and a distribution for the contour levels. The contours generated will not be matched to the image color scale distribution.</p> </blockquote> <p><b> Contour Method</b></p> <p>There are two methods that are available to calculate the contour lines. The first, BLOCK, blocks down the image, by the smoothness factor, before contours are calculated. As a result, the larger the smoothness, the faster the result. The second method, SMOOTH, smooths the image before calculating contours. As a result, the larger the smoothness, the slower the result. </p> </blockquote> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/colorbar.html����������������������������������������������������������������������0000644�0001750�0001750�00000007110�11763212355�015121� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Color</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" width="100" height="98"> Colorbar<br> </h3> <blockquote> <p><b>Color Tags</b></p> <p>The purpose of color tags are to highlight (or hide) certain values of data, regardless of the color map selected. The user creates, edits, and deletes color tags via the GUI. To create a color tag, enter the Colorbar Mode, and click once on the colorbar. This creates a default color tag. Click and drag to change the values. Click and drag on one side to increase or decrease the value. Double click to manually edit the values and color. Place the cursor over the color tag and press the delete key to delete it. From the color parameters dialog, the user can load, save, and delete all color tags for that frame.<br> </p> <p><b>Visuals</b></p> <p>DS9 supports a number of color environments. Not all color environments, or visuals, are available on most machines. In fact, you may be restricted to one or two, base on the color graphics hardware your computer has. A color visual is composed of two parts, the color model and the bit depth. Pseudo color uses a color lookup table to derive the correct color, True color uses the value directly as a RGB triplet, to derive the correct color. The follow is a list of the color visuals DS9 currently supports:</p> <blockquote> <tt>pseudo color, 8 bit<br> true color, 8 bit <br> true color, 15 bit <br> true color, 16 bit <br> true color, 24 bit</tt> </blockquote> <p> You can use the <tt>xdpyinfo</tt> command to see if one of these visual are available. NOTE: Linux Users-- if your desired visual is not available, use the Xconfigarator command (Red Hat) or similar command under other versions of linux, to configure your X window visuals.</p> <p>When DS9 is invoked, by default, it will use the default visual. You can find out what the default visual is by using the <tt>xdpyinfo</tt> command. You can also force DS9 to use another visual by command line option. If you specify a visual, and it is not available, DS9 will exit with an error message. </p> <blockquote><tt>$ds9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # default visual, default depth<br> $ds9 -visual pseudo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pseudo color, default depth <br> $ds9 -visual pseudocolor&nbsp; # pseudo color, default depth <br> $ds9 -visual pseudocolor8 # pseudo color 8 <br> $ds9 -visual true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # true color, default depth <br> $ds9 -visual truecolor&nbsp;&nbsp;&nbsp; # true color, default depth <br> $ds9 -visual truecolor8&nbsp;&nbsp; # true color 8 <br> $ds9 -visual truecolor16&nbsp; # true color 16 <br> $ds9 -visual truecolor24&nbsp; # true color 24</tt> </blockquote> </blockquote> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/grid.html��������������������������������������������������������������������������0000644�0001750�0001750�00000011340�12071072130�014227� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Coordinate Grids</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Coordinate Grids</h3> <blockquote> <p>DS9 can create and display coordinate grids as an overlay on an image. The Display Coordinate Grid Menu is used to display grids. A coordinate grid is composed of Grid Lines, Axes, Border, and Title. Axes include tick marks, title, and numbers. The appearance of the coordinate grid is specified by parameters. These parameters may be configured via the Coordinate Grid Parameters dialog box. In addition to the axes titles and the grid title, the following menus are available. </p> <p><b><a name="Format"></a>Numeric Formats</b></p> <p>The user may specify custom numeric formats for either axes. The format specification can be empty (default) or a print function, based on the selected coordinate system:<br> </p> <blockquote> <tt>image</tt><br> <tt>physical</tt><br> <tt>detector</tt><br> <tt>amplifier</tt><br> <tt>wcs linear</tt><br> <tt>wcs equatorial</tt><br> </blockquote> <p>The format specification string to be passed to the C "printf" function (e.g. "%%1.7G") in order to format a single coordinate value.</p> <p>The Format string supplied should contain one or more of the following characters. These may occur in any order, but the following is recommended for clarity:</p> <blockquote> "": Indicates that a plus sign should be prefixed to positive values. By default, no plus sign is used.<br> "z": Indicates that leading zeros should be prefixed to the value so that the first field is of constant width, as would be required in a fixed-width table (leading zeros are always prefixed to any fields that follow). By default, no leading zeros are added.<br> "i": Use the standard ISO field separator (a colon) between fields. This is the default behaviour.<br> "b": Use a blank to separate fields.<br> "l": Use a letter ("h"/"d", "m" or "s" as appropriate) to separate fields.<br> "g": Use a letter and symbols to separate fields ("h"/"d", "m" or "s", etc, as appropriate), but include escape sequences in the formatted value so that the Plot class will draw the separators as small super-scripts.<br> "d": Include a degrees field. Expressing the angle purely in degrees is also the default if none of "h", "m", "s" or "t" are given.<br> "h": Express the angle as a time and include an hours field (where 24 hours correspond to 360 degrees). Expressing the angle purely in hours is also the default if "t" is given without either "m" or "s".<br> "m": Include a minutes field. By default this is not included.<br> "s": Include a seconds field. By default this is not included. This request is ignored if "d" or "h" is given, unless a minutes field is also included.<br> "t": Express the angle as a time (where 24 hours correspond to 360 degrees). This option is ignored if either "d" or "h" is given and is intended for use where the value is to be expressed purely in minutes and/or seconds of time (with no hours field). If "t" is given without "d", "h", "m" or "s" being present, then it is equivalent to "h".<br> ".": Indicates that decimal places are to be given for the final field in the formatted string (whichever field this is). The "." should be followed immediately by an unsigned integer which gives the number of decimal places required, or by an asterisk. If an asterisk is supplied, a default number of decimal places is used which is based on the value of the Digits attribute.<br> </blockquote> <p>All of the above format specifiers are case-insensitive. If several characters make conflicting requests (e.g. if both "i" and "b" appear), then the character occurring last takes precedence, except that "d" and "h" always override "t".</p> <p>The default formats are <tt>d.3</tt> for degrees and <tt>hms.1</tt> / <tt>dms.1</tt> / <tt>ldms.1</tt> for sexagesimal.<br> </p> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/xpa.html���������������������������������������������������������������������������0000644�0001750�0001750�00000401730�12131601437�014105� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>XPA Access Points</title> </head> <body alink="#ff0000" link="#0000ff" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> XPA Access Points</h3> <blockquote> <p>The <a href="http://hea-www.harvard.edu/RD/xpa/index.html">XPA </a> messaging system provides seamless communication between DS9 and other Unix programs, including X programs, Perl, <a href="http://space.mit.edu/cxc/software/slang/modules/xpa/"> S-Lang,</a> and Tcl/Tk. It also provides an easy way for users to communicate with DS9 by executing XPA client commands in the shell or by utilizing such commands in scripts. Because XPA works both at the programming level and the shell level, it is a powerful tool for unifying any analysis environment.</p> <tt> <a href="#2mass">2mass</a><br> <a href="#3d">3d</a><br> <a href="#about">about</a><br> <a href="#align">align</a><br> <a href="#analysis">analysis</a><br> <a href="#array">array</a><br> <a href="#background"><tt><tt>background</tt></tt></a><br> <a href="#backup">backup</a><br> <a href="#bin">bin</a><br> <a href="#blink">blink</a><br> <a href="#catalog">catalog</a><br> <a href="#cd">cd</a><br> <a href="#cmap">cmap</a><br> <a href="#colorbar">colorbar</a><br> <a href="#console">console</a><br> <a href="#contour">contour</a><br> <a href="crop">crop</a><br> <a href="#crosshair">crosshair</a><br> <a href="#cube">cube</a></tt><br> <tt> <a href="#cursor">cursor</a><br> <a href="#data">data</a><br> <a href="#dsssao">dsssao</a><br> <a href="#dsseso">dsseso</a><br> <a href="#dssstsci">dssstsci</a><br> <a href="#exit">exit</a><br> <a href="#export">export</a><br> <a href="#first">first</a><br> <a href="#fits">fits</a><br> <a href="#frame">frame</a><br> <a href="#gif">gif</a><br> <a href="#grid">grid</a><br> <a href="#header">header</a><br> <a href="#height">height</a><br> <a href="#iconify">iconify</a><br> <a href="#iis">iis</a><br> <a href="#image">image</a><br> <a href="#imexam">imexam</a><br> <a href="#jpeg">jpeg</a><br> <a href="#lock">lock</a><br> <a href="#lower">lower</a><br> <a href="#magnifier">magnifier</a><br> <a href="#mask">mask</a><br> <a href="#match">match</a><br> <a href="#mecube">mecube</a><br> <a href="#minmax">minmax</a><br> <a href="#mode">mode</a><br> <a href="#mosaic">mosaic</a><br> <a href="#mosaicimage">mosaicimage</a><br> <a href="#movie">movie</a><br> <a href="#multiframe">multiframe</a><br> <a href="#nameserver">nameserver</a><br> <a href="#nrrd">nrrd</a><br> <a href="#nvss">nvss</a><br> <a href="#orient">orient</a><br> <a href="#pagesetup">pagesetup</a><br> <a href="#pan">pan</a><br> <a href="#pixeltable">pixeltable</a><br> <a href="#plot">plot</a><br> <a href="#png">png</a><br> <a href="#prefs">prefs</a><br> <a href="#preserve">preserve</a><br> <a href="#print">psprint</a><br> <a href="#print">print</a><br> <a href="#exit">quit</a><br> <a href="#raise">raise</a><br> <a href="#regions">regions</a><br> <a href="#restore">restore</a><br> <a href="#rgb">rgb</a><br> <a href="#rgbarray">rgbarray</a><br> <a href="#rgbcube">rgbcube</a><br> <a href="#rgbimage">rgbimage</a><br> <a href="#rotate">rotate</a><br> <a href="#save">save</a><br> <a href="#saveimage">saveimage</a><br> <a href="xpa.html#scale">scale</a><br> <a href="#shm">shm</a><br> <a href="#single">single</a><br> <a href="#skyview">skyview</a><br> <a href="#sleep">sleep</a><br> <a href="#smooth">smooth</a><br> <a href="#source">source</a><br> <a href="#tcl">tcl</a><br> <a href="#theme">theme</a><br> <a href="#threads">threads</a><br> <a href="#tile">tile</a><br> <a href="#update">update</a></tt><br> <tt><tt><a href="#url">url</a><br> </tt><a href="#version">version</a><br> <a href="#view">view</a><br> <a href="#vo">vo</a><br> <a href="#wcs">wcs</a><br> <a href="#web">web</a><br> <a href="#width">width</a><br> <a href="#zscale">zscale</a><br> <a href="#zoom">zoom</a><br> </tt> <p><b> <a name="2mass"></a>2mass</b></p> <p> Support for 2MASS Digital Sky Survey.</p> <tt> Syntax: <br> 2mass []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp;&nbsp; [survey j|h|k]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> </tt><tt>&nbsp; <br> Example:<br> $xpaget ds9 2mass name <br> $xpaget ds9 2mass coord <br> $xpaget ds9 2mass size<br> $xpaget ds9 2mass save<br> $xpaget ds9 2mass frame<br> $xpaget ds9 2mass survey <br> $xpaset -p ds9 2mass<br> </tt><tt>$xpaset -p ds9 2mass m31<br> $xpaset -p ds9 2mass name m31 <br> $xpaset -p ds9 2mass coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 2mass size 60 60 arcmin<br> $xpaset -p ds9 2mass save yes<br> $xpaset -p ds9 2mass frame current<br> $xpaset -p ds9 2mass update frame<br> $xpaset -p ds9 2mass survey j<br> </tt><tt>$xpaset -p ds9 2mass open<br> $xpaset -p ds9 2mass close</tt><br> <p><b> <a name="3d"></a>3d</b></p> <p> Support for 3D frame.</p> <tt> Syntax: <br> 3d []<br> &nbsp;&nbsp; [vp &lt;az&gt; &lt;el&gt;]<br> &nbsp;&nbsp; [az &lt;az&gt;]<br> &nbsp;&nbsp; [el &lt;el&gt;]<br> &nbsp;&nbsp; [scale &lt;scale&gt;]<br> &nbsp;&nbsp; [method mip|aip]<br> </tt><tt>&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp; [border color &lt;color&gt;]</tt><br> <tt> </tt><tt></tt><tt>&nbsp;&nbsp; [highlite yes|no]<br> &nbsp;&nbsp; [highlite color &lt;color&gt;]<br> </tt><tt>&nbsp;&nbsp; [open|close]<br> </tt><tt>&nbsp; <br> Example:<br> $xpaget ds9 3d vp<br> $xpaget ds9 3d az<br> $xpaget ds9 3d el<br> $xpaget ds9 3d scale<br> $xpaget ds9 3d method<br> </tt><tt>$xpaget ds9 3d border<br> $xpaget ds9 3d border color</tt><br> <tt></tt><tt>$xpaget ds9 3d highlite<br> $xpaget ds9 3d highlite color<br> $xpaset -p ds9 3d # create new 3D frame<br> $xpaset -p ds9 3d vp 45 30<br> $xpaset -p ds9 3d az 45<br> $xpaset -p ds9 3d el 30<br> $xpaset -p ds9 3d scale 10<br> $xpaset -p ds9 3d method mip<br> </tt><tt>$xpaset -p ds9 3d border yes<br> $xpaset -p ds9 3d border color red</tt><br> <tt></tt><tt>$xpaset -p ds9 3d highlite yes<br> $xpaset -p ds9 3d highlite color red<br> $xpaset -p ds9 3d open<br> $xpaset -p ds9 3d close<br> </tt> <p><b><a name="about"></a>about</b></p> <p>Get DS9 credits. </p> <tt> Syntax: <br> about <br> &nbsp;<br> Example: <br> $xpaget ds9 about<br> </tt> <p><b> <a name="align"></a>align</b></p> <p>Controls the World Coordinate System alignment for the current frame.</p> <tt> Syntax: <br> align []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;<br> Example: <br> $xpaget ds9 align<br> $xpaset -p ds9 align yes<br> </tt> <p><b> <a name="analysis"></a>analysis</b></p> <p>Control external analysis tasks. Tasks are numbered as they are loaded, starting with 0. Can also be used to display a message and display text in the text dialog window. </p> <tt> Syntax: <br> analysis [&lt;task number&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [task &lt;task number&gt;|&lt;task name&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear][load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [message ok|okcancel|yesno &lt;message&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [entry &lt;message&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [text]<br> &nbsp;<br> Example: <br> $xpaget ds9 analysis<br> $xpaget ds9 analysis task<br> $xpaget ds9 analysis entry 'Please enter something'<br> $xpaget ds9 analysis entry okcancel 'Please enter something'<br> $xpaset -p ds9 analysis 0 # invoke first analysis task<br> $xpaset -p ds9 analysis task 0<br> $xpaset -p ds9 analysis task foobar<br> $xpaset -p ds9 analysis "{foo bar}"<br> $xpaset -p ds9 analysis my.ans<br> $xpaset -p ds9 analysis load my.ans <br> $xpaset -p ds9 analysis clear <br> $xpaset -p ds9 analysis clear load my.ans<br> $xpaset -p ds9 analysis message ok {This is a message}<br> $xpaset -p ds9 analysis text {this is text}<br> $cat my.ans | xpaset ds9 analysis load <br> $cat foo.txt | xpaset ds9 analysis text <br> </tt> <p><b> <a name="array"></a>array</b></p> <p>Load raw data array into current frame.<br> </p> <tt> Syntax:<br> array [native|big|little]<br> array [new|mask] [[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],zdim=&lt;z&gt;,bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> $xpaget ds9 array &gt; foo.arr<br> $xpaget ds9 array little &gt; foo.arr<br> $xpaset -p ds9 array foo.arr[dim=512,bitpix=-32,endian=little]<br> $xpaset -p ds9 array new foo.arr[dim=512,bitpix=</tt><tt>-32,endian=little]</tt><br> <tt><tt>$xpaset -p ds9 array mask foo.arr[dim=512,bitpix=</tt></tt><tt>-32,endian=little]</tt><br> <tt>$cat foo.arr | xpaset ds9 array [dim=512,bitpix=-32,endian=little]</tt><br> <tt>$cat foo.arr | xpaset ds9 array new [dim=512,bitpix=-32,endian=little]</tt><br> <tt>$cat foo.arr | xpaset ds9 array mask [dim=512,bitpix=-32,endian=little]</tt> <tt> </tt> <p><b> <a name="background"></a>bg<br> background</b></p> <p>Set image background color. </p> <tt> Syntax: <br> bg &lt;color&gt;<br> &nbsp;<br> Example:<br> $xpaget ds9 bg</tt><tt><br> <tt>$xpaset -p ds9 bg red</tt><tt></tt><tt></tt><br> </tt> <p><b> <a name="backup"></a>backup</b></p> <p>Create a backup save set. </p> <tt> Syntax: <br> backup &lt;filename&gt;<br> &nbsp;<br> Example:<br> $xpaset -p ds9 backup ds9.bck</tt><br> <p><b> <a name="bin"></a>bin</b></p> <p>Controls binning factor, binning buffer size, and&nbsp; binning function for binning FITS bin tables. The access point blocking is provided for backward compatibility. </p> <tt> Syntax: <br> bin [about &lt;x&gt; &lt;y&gt;]<br> &nbsp;&nbsp;&nbsp; [about center]<br> &nbsp;&nbsp;&nbsp; [buffersize &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp; [cols &lt;x&gt; &lt;y&gt;]<br> &nbsp;&nbsp;&nbsp; [colsz &lt;x&gt; &lt;y&gt; &lt;z&gt;]<br> &nbsp;&nbsp;&nbsp; [factor &lt;value&gt; [&lt;vector&gt;]]<br> &nbsp;&nbsp;&nbsp; [depth &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp; [filter &lt;string&gt;] <br> &nbsp;&nbsp;&nbsp; [function average|sum] <br> &nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 bin about<br> $xpaget ds9 bin buffersize<br> $xpaget ds9 bin cols<br> $xpaget ds9 bin factor<br> $xpaget ds9 bin depth<br> $xpaget ds9 bin filter<br> $xpaget ds9 bin function<br> $xpaget ds9 bin smooth<br> $xpaget ds9 bin smooth function<br> $xpaget ds9 bin smooth radius<br> $xpaget ds9 bin lock<br> $xpaset -p ds9 bin about 4096 4096<br> $xpaset -p ds9 bin about center<br> $xpaset -p ds9 bin buffersize 512<br> $xpaset -p ds9 bin cols detx dety<br> $xpaset -p ds9 bin colsz detx dety time<br> $xpaset -p ds9 bin factor 4<br> $xpaset -p ds9 bin factor 4 2<br> $xpaset -p ds9 bin depth 10<br> $xpaset -p ds9 bin filter '{pha &gt; 5}'<br> $xpaset -p ds9 bin filter ''<br> $xpaset -p ds9 bin function sum<br> $xpaset -p ds9 bin to fit<br> $xpaset -p ds9 bin match<br> $xpaset -p ds9 bin lock yes<br> $xpaset -p ds9 bin open<br> $xpaset -p ds9 bin close</tt><tt><br> </tt> <p><b> <a name="blink"></a>blink</b></p> <p>Blink mode parameters. Interval is in seconds. <br> </p> <tt> Syntax: <br> blink []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 blink<br> $xpaget ds9 blink interval<br> $xpaset -p ds9 blink<br> $xpaset -p ds9 blink yes<br> $xpaset -p ds9 blink interval 1<br> </tt> <p><b> <a name="catalog"></a>catalog<br> cat<br> </b></p> <p>Support for catalogs. The first three commands will create a new catalog search. All other commands operated on the last search created, unless indicated otherwise.</p> <tt> Syntax: <br> catalog []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ned|simbad|denis|skybot]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ascss|cmc|gsc1|gsc2|gsc3|ac|nomad|ppmx|sao|sdss5|sdss6|</tt><tt>sdss7|sdss8|</tt><tt>tycho|ua2|ub1|ucac2]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [2mass|iras]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [csc|xmm|rosat]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [first|nvss]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [chandralog|cfhtlog|esolog|stlog|xmmlog]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [cds &lt;catalogname&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cds &lt;catalogid&gt;]<br> <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [import sb|tsv &lt;filename&gt;]<br> <br> </tt><tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [allcols]<br> </tt><tt>&nbsp;</tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [allrows]<br> &nbsp;</tt><tt>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [cancel]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [clear]<br> </tt><tt>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [close]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [coordinate &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [crosshair]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [dec &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [edit yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [export sb|tsv &lt;filename&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter &lt;string&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [header]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [hide]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [location &lt;code&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [match &lt;ref&gt; &lt;ref&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match error &lt;value&gt; degrees|arcmin|arcsec]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match function 1and2|1not2|2not1]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match return 1and2|1only|2only]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match unique yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [maxrows &lt;number&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [name &lt;object&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [panto yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [plot &lt;xcol&gt; &lt;ycol&gt; &lt;xerrcol&gt; &lt;yerrcol&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [print]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psky &lt;skyframe&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psystem &lt;coordsys&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [ra &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [retrieve]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp broadcast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp send &lt;application&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [save &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [server cds|sao|cadc|adac|iucaa|bejing|cambridge|ukirt]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [show]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]</tt><br> <tt> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sky &lt;skyframe&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [skyformat &lt;skyformat&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sort &lt;col&gt; incr|decr]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] condition|shape|color|text|font|fontsize|fontweight|fontslant &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] text|size|size2|units|angle &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol shape {circle point}|{box point}|{diamond point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {cross point}|{x point}|{arrow point}|{boxcircle point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; circle|ellipse|box|text]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol add| [#] remove]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol save|load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [system &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [update]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [x &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [y &lt;col&gt;]</tt><tt></tt><br> <tt> &nbsp;<br> Example: <br> $xpaget ds9 catalog<br> </tt><tt>$xpaget ds9 catalog header</tt><br> <tt><br> $xpaset -p ds9 catalog<br> $xpaset -p ds9 catalog 2mass<br> $xpaset -p ds9 catalog cds 2mass<br> $xpaset -p ds9 catalog cds "I/252"<br> <br> </tt><tt>$xpaset -p ds9 catalog load foo.xml<br> $xpaset -p ds9 catalog import tsv foo.tsv<br> <br> </tt><tt>$xpaset -p ds9 catalog allrows<br> $xpaset -p ds9 catalog allcols<br> </tt><tt>$xpaset -p ds9 catalog cancel<br> </tt><tt>$xpaset -p ds9 catalog clear<br> </tt><tt>$xpaset -p ds9 catalog close<br> </tt><tt>$xpaset -p ds9 catalog coordinate 202.48 47.21 fk5<br> </tt><tt>$xpaset -p ds9 catalog crosshair<br> </tt><tt>$xpaset -p ds9 catalog dec DEC<br> </tt><tt>$xpaset -p ds9 catalog edit yes<br> </tt><tt>$xpaset -p ds9 catalog export tsv bar.tsv<br> </tt><tt>$xpaset -p ds9 catalog filter '$Jmag&gt;10'<br> $xpaset -p ds9 catalog filter load foo.flt<br> $xpaset -p ds9 catalog header<br> </tt><tt>$xpaset -p ds9 catalog hide<br> </tt><tt>$xpaset -p ds9 catalog location 500</tt><br> <tt>$xpaset -p ds9 catalog match error 2 arcsec<br> $xpaset -p ds9 catalog match function 1and2<br> $xpaset -p ds9 catalog match unique no<br> $xpaset -p ds9 catalog match return 1only<br> $xpaset -p ds9 catalog match 2mass csc<br> </tt><tt>$xpaset -p ds9 catalog maxrows 2000<br> </tt><tt>$xpaset -p ds9 catalog name m51<br> $xpaset -p ds9 catalog panto no<br> </tt><tt>$xpaset -p ds9 catalog plot '$Jmag' '$Hmag' '$e_Jmag' '$e_Hmag'<br> </tt><tt>$xpaset -p ds9 catalog print</tt><br> <tt>$xpaset -p ds9 catalog psky fk5</tt><br> <tt>$xpaset -p ds9 catalog psystem wcs</tt><br> <tt>$xpaset -p ds9 catalog ra RA</tt><br> <tt>$xpaset -p ds9 catalog retrieve<br> </tt><tt> $xpaset -p ds9 catalog samp broadcast<br> $xpaset -p ds9 catalog samp send aladin<br> $xpaset -p ds9 catalog save foo.xml<br> </tt><tt>$xpaset -p ds9 catalog server sao<br> </tt><tt>$xpaset -p ds9 catalog show</tt><br> <tt>$xpaset -p ds9 catalog size 1 1 degrees</tt><br> <tt>$xpaset -p ds9 catalog symbol condition '$Jmag&gt;15'<br> $xpaset -p ds9 catalog symbol 2 shape "boxcircle point"<br> $xpaset -p ds9 catalog symbol color red<br> $xpaset -p ds9 catalog symbol font times<br> </tt><tt>$xpaset -p ds9 catalog symbol fontsize 14<br> </tt><tt>$xpaset -p ds9 catalog symbol fontweight bold<br> </tt><tt>$xpaset -p ds9 catalog symbol fontslant italic<br> </tt><tt>$xpaset -p ds9 catalog symbol add<br> $xpaset -p ds9 catalog symbol 2 remove<br> $xpaset -p ds9 catalog symbol load foo.sym<br> $xpaset -p ds9 catalog symbol save bar.sym</tt><tt><br> $xpaset -p ds9 catalog sky fk5<br> $xpaset -p ds9 catalog skyformat degrees<br> </tt><tt>$xpaset -p ds9 catalog sort "Jmag" incr<br> </tt><tt>$xpaset -p ds9 catalog system wcs</tt><tt><br> </tt><tt>$xpaset -p ds9 catalog update<br> </tt><tt>$xpaset -p ds9 catalog x RA<br> $xpaset -p ds9 catalog y DEC</tt><tt></tt><br> <p><b> <a name="cd"></a>cd</b></p> <p>Sets/Returns the current working directory. </p> <tt> Syntax: <br> cd [&lt;directory&gt;] <br> &nbsp;<br> Example: <br> $xpaget ds9 cd<br> $xpaset -p ds9 cd /home/mrbill<br> </tt> <p><b> <a name="cmap"></a>cmap</b></p> <p>Controls the colormap for the current frame. The colormap name is not case sensitive. A valid contrast value is&nbsp; from 0 to 10 and bias value from 0 to 1. </p> <tt> Syntax: <br> cmap [&lt;colormap&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [file]<br> &nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [invert yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [value &lt;constrast&gt; &lt;bias&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [tag [load|save] &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [tag delete]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 cmap <br> $xpaget ds9 cmap file <br> $xpaget ds9 cmap invert <br> $xpaget ds9 cmap value <br> </tt><tt>$xpaget ds9 cmap lock</tt><br> <tt> $xpaset -p ds9 cmap Heat <br> $xpaset -p ds9 cmap load foo.sao <br> </tt><tt>$xpaset -p ds9 cmap save bar.sao <br> </tt><tt>$xpaset -p ds9 cmap invert yes <br> $xpaset -p ds9 cmap value 5 .5<br> $xpaset -p ds9 cmap tag load foo.tag<br> $xpaset -p ds9 cmap tag save foo.tag<br> $xpaset -p ds9 cmap tag delete<br> </tt><tt>$xpaset -p ds9 cmap match<br> $xpaset -p ds9 cmap lock yes</tt><br> <tt> $xpaset -p ds9 cmap open<br> $xpaset -p ds9 cmap close<br> </tt> <p><b> <a name="colorbar"></a>colorbar<br> </b></p> <p>Controls colorbar parameters.</p> <tt> Syntax: <br> colorbar []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [horizontal|vertical]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [orientation horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [space value|distance] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [size]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ticks]<br> &nbsp;<br> Example: <br> $xpaget ds9 colorbar<br> $xpaget ds9 colorbar orientation<br> $xpaget ds9 colorbar numerics<br> $xpaget ds9 colorbar space<br> $xpaget ds9 colorbar font<br> $xpaget ds9 colorbar fontsize<br> $xpaget ds9 colorbar fontweight<br> $xpaget ds9 colorbar fontslant<br> $xpaget ds9 colorbar size<br> $xpaget ds9 colorbar ticks<br> $xpaset -p ds9 colorbar yes<br> $xpaset -p ds9 colorbar vertical<br> $xpaset -p ds9 colorbar orientation vertical<br> $xpaset -p ds9 colorbar numerics yes<br> $xpaset -p ds9 colorbar space value<br> $xpaset -p ds9 colorbar font times<br> $xpaset -p ds9 colorbar fontsize 14<br> $xpaset -p ds9 colorbar fontweight bold<br> $xpaset -p ds9 colorbar fontslant italic<br> $xpaset -p ds9 colorbar size 20<br> $xpaset -p ds9 colorbar ticks 11<br> </tt> <p><b> <a name="console"></a>console</b></p> <p>Display tcl console window.</p> <tt> Syntax: <br> -console<br> &nbsp;<br> Example:<br> $xpaset -p ds9 console<br> </tt> <p><b> <a name="contour"></a>contour<br> </b></p> <p>Controls contours in the current frame. </p> <tt> Syntax: <br> contour []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;coordsys&gt; [&lt;skyframe&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [generate]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [convert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [loadlevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [savelevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [paste &lt;coordsys&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [dash yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [smooth &lt;smooth&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [method block|smooth]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [nlevels &lt;number of levels&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale linear|log|pow|squared|sqrt|asinh|sinh|histequ]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [log exp &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [limits &lt;min&gt; &lt;max&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [levels &lt;value value value...&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 contour<br> $xpaget ds9 contour wcs fk5<br> $xpaget ds9 contour color<br> $xpaget ds9 contour width<br> $xpaget ds9 contour dash<br> $xpaget ds9 contour smooth<br> $xpaget ds9 contour method<br> $xpaget ds9 contour nlevels<br> $xpaget ds9 contour scale<br> $xpaget ds9 contour log exp<br> $xpaget ds9 contour mode<br> $xpaget ds9 contour limits<br> $xpaget ds9 contour levels<br> $xpaset -p ds9 contour<br> $xpaset -p ds9 contour yes<br> $xpaset -p ds9 contour clear<br> $xpaset -p ds9 contour generate<br> $xpaset -p ds9 contour load ds9.con wcs fk5 yellow 2 no # solid line<br> $xpaset -p ds9 contour load ds9.con wcs fk5 red 2 yes # dashed line<br> $xpaset -p ds9 contour save ds9.con wcs fk5<br> $xpaset -p ds9 contour convert<br> $xpaset -p ds9 contour loadlevels ds9.lev<br> $xpaset -p ds9 contour savelevels ds9.lev<br> $xpaset -p ds9 contour copy<br> $xpaset -p ds9 contour paste wcs red 2 no<br> $xpaset -p ds9 contour color yellow<br> $xpaset -p ds9 contour width 2<br> $xpaset -p ds9 contour dash yes<br> $xpaset -p ds9 contour smooth 5<br> $xpaset -p ds9 contour method smooth<br> $xpaset -p ds9 contour nlevels 10<br> $xpaset -p ds9 contour scale sqrt<br> $xpaset -p ds9 contour log exp 1000<br> $xpaset -p ds9 contour mode zscale<br> $xpaset -p ds9 contour limits 1 100<br> $xpaset -p ds9 contour levels "{1 10 100 1000}"<br> $xpaset -p ds9 contour open<br> $xpaset -p ds9 contour close<br> </tt> <p><b><a name="crop"></a>crop</b> </p> <p>Set current image display area. </p> <tt> Syntax: <br> crop [&lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt; [&lt;coordsys&gt;][&lt;skyframe&gt;][&lt;skyformat&gt;][degrees|arcmin|arcsec] <br> &nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]<br> &nbsp;<br> Example: <br> $xpaget ds9 crop # get crop in physical coords <br> $xpaget ds9 crop wcs galactic sexagesimal arcsec<br> $xpaget ds9 crop lock<br> $xpaset -p ds9 crop 40 30 10 20 # set crop in physical coords<br> $xpaset -p ds9 crop +104:51:06.915 +68:33:40.761&nbsp; 28.144405 22.000204 wcs galactic arcsec<br> $xpaset -p ds9 crop match wcs<br> $xpaset -p ds9 crop lock wcs</tt><br> <p><b> <a name="crosshair"></a>crosshair</b></p> <p>Controls the current position of the crosshair in the current frame. DS9 is placed in crosshair mode when the crosshair is set. </p> <tt> Syntax: <br> crosshair [&lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]<br> &nbsp;<br> Example: <br> $xpaget ds9 crosshair # get crosshair in physical coords <br> $xpaget ds9 crosshair wcs fk4 sexagesimal # get crosshair in wcs coords <br> $xpaget ds9 crosshair lock<br> $xpaset -p ds9 crosshair 100 100 physical # set crosshair in physical <br> $xpaset -p ds9 crosshair 345 58.8 wcs fk5 # set crosshair in wcs coords <br> $xpaset -p ds9 crosshair 23:01:00 +58:52:51 wcs fk5<br> $xpaset -p ds9 crosshair match wcs<br> $xpaset -p ds9 crosshair lock wcs<br> </tt> <p><b> <a name="cube"></a>cube<br> </b></p> <p>Controls FITS cube dialog. </p> <tt> Syntax: <br> cube [play|stop|next|prev|first|last]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;slice&gt; [&lt;coordsys&gt;][&lt;axis&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;numeric&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [axis &lt;axis&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $xpaget ds9 cube<br> $xpaget ds9 cube interval<br> $xpaget ds9 cube axis<br> $xpaget ds9 cube lock<br> $xpaset -p ds9 cube play<br> $xpaset -p ds9 cube last<br> $xpaset -p ds9 cube 3<br> $xpaset -p ds9 cube 4.4 wcs 3<br> $xpaset -p ds9 cube interval 2<br> $xpaset -p ds9 cube axis 3<br> $xpaset -p ds9 cube match<br> $xpaset -p ds9 cube lock yes<br> $xpaset -p ds9 cube open<br> $xpaset -p ds9 cube close</tt><br> <p><b> <a name="cursor"></a>cursor</b></p> <p>Move mouse pointer or crosshair in image pixels in the current frame. Note, this will move selected Regions also. </p> <tt> Syntax: <br> cursor [&lt;x&gt; &lt;y&gt;] <br> &nbsp;<br> Example: <br> $xpaset -p ds9 cursor 10 10<br> </tt> <p><b> <a name="data"></a>data</b></p> <p>Return an array of data values given a lower left corner and a width and height in specified coordinate system. The last argument of yes indicates to strip the coordinates from the output and just list the data values. The default is yes.</p> <tt> Syntax: <br> data [&lt;coordsys&gt; [&lt;skyframe&gt;] &lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt; [yes|no]]<br> &nbsp;<br> Example: <br> $xpaget ds9 data image 450 520 3 3 yes<br> $xpaget ds9 data physical 899 1039 6 6 no<br> $xpaget ds9 data fk5 202.47091 47.196811 0.00016516669 0.00016516669 no<br> $xpaget ds9 data wcs fk5 13:29:53.018 +47:11:48.52 0.00016516669 0.00016516669 no</tt><tt><br> </tt> <p><b> <a name="dsssao"></a>dsssao<br> dss<br> </b></p> <p>Support for Digital Sky Survey at SAO. </p> <tt> Syntax:<br> dsssao []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $xpaget ds9 dsssao name <br> $xpaget ds9 dsssao coord <br> $xpaget ds9 dsssao size<br> $xpaget ds9 dsssao save<br> $xpaget ds9 dsssao frame<br> $xpaset -p ds9 dsssao<br> $xpaset -p ds9 dsssao m31 <br> $xpaset -p ds9 dsssao name m31 <br> $xpaset -p ds9 dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 dsssao size 60 60 arcmin<br> $xpaset -p ds9 dsssao save yes<br> $xpaset -p ds9 dsssao frame current<br> $xpaset -p ds9 dsssao update frame<br> $xpaset -p ds9 dsssao open<br> </tt><tt>$xpaset -p ds9 dsssao close</tt><br> <p><b> <a name="dsseso"></a>dsseso</b></p> <p>Support for Digital Sky Survey at ESO. </p> <tt> Syntax:<br> dsseso []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp; &nbsp; &nbsp; [survey DSS1|DSS2-red|DSS2-blue|DSS2-infrared]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 dsseso name <br> $xpaget ds9 dsseso coord <br> $xpaget ds9 dsseso size<br> $xpaget ds9 dsseso save<br> $xpaget ds9 dsseso frame<br> $xpaget ds9 dsseso survey<br> $xpaset -p ds9 dsseso<br> $xpaset -p ds9 dsseso m31 <br> $xpaset -p ds9 dsseso name m31 <br> $xpaset -p ds9 dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 dsseso size 60 60 arcmin<br> $xpaset -p ds9 dsseso save yes<br> $xpaset -p ds9 dsseso frame current<br> $xpaset -p ds9 dsseso update frame<br> $xpaset -p ds9 dsseso survey DSS2-red <br> $xpaset -p ds9 dsseso open<br> </tt><tt>$xpaset -p ds9 dsseso close</tt><br> <p><b> <a name="dssstsci"></a>dssstsci</b></p> <p>Support for Digital Sky Survey at STSCI.</p> <tt> Syntax:<br> dssstsci []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss2ukstu_red|poss2ukstu_ir|poss2ukstu_blue] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss1_blue|poss1_red]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey all|quickv|phase2_gsc2|phase2_gsc1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example:<br> $xpaget ds9 dssstsci name <br> $xpaget ds9 dssstsci coord <br> $xpaget ds9 dssstsci size<br> $xpaget ds9 dssstsci save<br> $xpaget ds9 dssstsci frame<br> $xpaget ds9 dssstsci survey<br> $xpaset -p ds9 dssstsci<br> $xpaset -p ds9 dssstsci m31 <br> $xpaset -p ds9 dssstsci name m31 <br> $xpaset -p ds9 dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 dssstsci size 60 60 arcmin<br> $xpaset -p ds9 dssstsci save yes<br> $xpaset -p ds9 dssstsci frame current<br> $xpaset -p ds9 dssstsci update frame<br> $xpaset -p ds9 dssstsci survey all<br> $xpaset -p ds9 dssstsci open<br> $xpaset -p ds9 dssstsci close<br> </tt> <p><b> <a name="exit"></a>exit<br> quit<br> </b></p> <p>Quits DS9. </p> <tt> Syntax: <br> exit<br> quit<br> &nbsp;<br> Example: <br> $xpaset -p ds9 exit<br> </tt> <p><b> <a name="export"></a>export<br> </b></p> <p>Export loaded image data of current frame in specified image format. Optional parameters: array endian, nrrd endian, jpeg quality (1-100) and tiff compression method.</p> <tt> Syntax: </tt><tt><br> </tt><tt> export </tt><tt>[array|nrrd|gif|tiff|jpeg|png] </tt><tt>&lt;filename&gt;</tt><tt><br> </tt><tt>export array &lt;filename&gt;</tt><tt> </tt><tt>little</tt><tt><br> </tt><tt>export nrrd &lt;filename&gt; </tt><tt>little</tt><tt><br> </tt><tt> </tt><tt>export jpeg &lt;filename&gt;</tt><tt> [1-100]</tt><tt><br> </tt><tt> </tt><tt>export tiff &lt;filename</tt><tt>&gt;</tt><tt> [none|jpeg|packbits|deflate]</tt><br> <tt> &nbsp;<br> Example: <br> </tt><tt><tt>$xpaset -p ds9 export array foo.arr little</tt></tt><br> <tt><tt>$xpaset -p ds9 export nrrd foo.nrrd little</tt></tt><br> <tt><tt><tt><tt>$xpaset -p ds9 export tiff foo.tiff jpeg</tt></tt></tt><br> $xpaset -p ds9 export jpeg foo.jpeg 75<br> $xpaset -p ds9 export png foo.png</tt><tt><br> </tt> <p><b> <a name="first"></a>first</b></p> <p>Support for VLA First Sky Survey. </p> <tt> Syntax:<br> first []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 first name <br> $xpaget ds9 first coord <br> $xpaget ds9 first size<br> $xpaget ds9 first save<br> $xpaget ds9 first frame<br> $xpaset -p ds9 first<br> $xpaset -p ds9 first m31 <br> $xpaset -p ds9 first name m31 <br> $xpaset -p ds9 first coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 first size 60 60 arcmin<br> $xpaset -p ds9 first save yes<br> $xpaset -p ds9 first frame current<br> $xpaset -p ds9 first update frame<br> $xpaset -p ds9 first open<br> </tt><tt>$xpaset -p ds9 first close</tt><br> <p><b> <a name="fits"></a>fits</b></p> <p>Load a FITS image into the current frame or query the currently loaded image.<br> </p> <tt> Syntax: <br> fits </tt><tt><tt>[new|mask|slice] [&lt;filename&gt;]</tt><tt><br> </tt>&nbsp;&nbsp;&nbsp;&nbsp; [width|height|depth|bitpix|type]<br> &nbsp; &nbsp;&nbsp; [size [wcs|wcsa...wcsz] [fk4|fk5|icrs|galactic|ecliptic] [degrees|arcmin|arcsecs]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[header [&lt;ext&gt;] [keyword &lt;string&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [image|table|slice]</tt><tt><br> &nbsp;<br> Example: <br> $xpaget ds9 fits &gt; foo.fits<br> $xpaget ds9 fits width<br> $xpaget ds9 fits height<br> $xpaget ds9 fits depth<br> $xpaget ds9 fits bitpix</tt><br> <tt>$xpaget ds9 fits type </tt><br> <tt><tt>$xpaget ds9 fits size<br> </tt> $xpaget ds9 fits size wcs fk5 arcmin<br> $xpaget ds9 fits header # primary<br> $xpaget ds9 fits header 2 # hdu 2<br> $xpaget ds9 fits header -2 # hdu 2 with inherit<br> $xpaget ds9 fits header keyword "'BITPIX'"<br> $xpaget ds9 fits header 1 keyword "'BITPIX'"</tt><br> <tt><tt>$xpaget ds9 fits image &gt; foo.fits<br> $xpaget ds9 fits table &gt; bar.fits<br> $xpaget ds9 fits slice &gt; foo.fits<br> </tt> $xpaset -p ds9 fits foo.fits<br> $xpaset -p ds9 fits new foo.fits<br> $xpaset -p ds9 fits bar.fits[bin=detx,dety]<br> $xpaset -p ds9 fits slice foo.fits<br> $xpaset -p ds9 fits mask foo.fits<br> $cat foo.fits | xpaset ds9 fits <br> $cat foo.fits | xpaset ds9 fits new<br> $cat bar.fits | xpaset ds9 fits -[bin=detx,dety]<br> $cat foo.fits | xpaset ds9 fits slice<br> $cat foo.fits | xpaset ds9 fits mask<br> </tt> <p><b> <a name="frame"></a>frame</b></p> <p>Controls frame functions. Frames may be created, deleted, reset, and centered. While return the current frame number. If you goto a frame that does not exists, it will be created. If the frame is hidden, it will be shown. The 'frameno' option is available for backward compatibility. </p> <tt> Syntax: <br> frame [center [#|all]]<br> &nbsp; &nbsp; &nbsp; [clear [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [new [rgb|3d]]<br> &nbsp; &nbsp; &nbsp; [delete [#|all]] <br> &nbsp; &nbsp; &nbsp; [reset [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [refresh [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [hide [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [show [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move first]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move forward]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move last]<br> &nbsp; &nbsp; &nbsp; [first]<br> &nbsp;&nbsp;&nbsp; &nbsp; [prev]<br> &nbsp; &nbsp; &nbsp; [next]<br> &nbsp; &nbsp; &nbsp; [last]<br> &nbsp; &nbsp; &nbsp; [frameno #]<br> &nbsp;&nbsp;&nbsp; &nbsp; [#]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has [amplifier|datamin|datasec|detector|grid|iis|irafmin|physical|smooth]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has contour [aux]]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has fits [bin|cube|mosaic]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has marker [highlite|paste|select|undo]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [has wcs [&lt;wcssys&gt;|equatorial &lt;wcssys&gt;|linear &lt;wcssys&gt;]]<br> &nbsp;<br> Example: <br> $xpaget ds9 frame # returns the id of the current frame <br> $xpaget ds9 frame frameno # returns the id of the current frame <br> $xpaget ds9 frame all # returns the id of all frames <br> $xpaget ds9 frame active # returns the id of all active frames<br> </tt><tt>$xpaget ds9 frame lock</tt><br> <tt> $xpaget ds9 frame has amplifier<br> $xpaget ds9 frame has datamin<br> $xpaget ds9 frame has datasec<br> $xpaget ds9 frame has detector<br> $xpaget ds9 frame has grid<br> $xpaget ds9 frame has iis<br> $xpaget ds9 frame has irafmin<br> $xpaget ds9 frame has physical<br> $xpaget ds9 frame has smooth<br> $xpaget ds9 frame has contour<br> $xpaget ds9 frame has contour aux<br> $xpaget ds9 frame has fits<br> $xpaget ds9 frame has fits bin<br> $xpaget ds9 frame has fits cube<br> $xpaget ds9 frame has fits mosaic<br> $xpaget ds9 frame has marker highlite<br> $xpaget ds9 frame has marker paste<br> $xpaget ds9 frame has marker select<br> $xpaget ds9 frame has marker undo<br> $xpaget ds9 frame has system physical<br> $xpaget ds9 frame has wcs wcsa<br> $xpaget ds9 frame has wcs equatorial wcsa<br> $xpaget ds9 frame has wcs linear wcsa<br> $xpaset -p ds9 frame center # center current frame<br> $xpaset -p ds9 frame center 1 # center 'Frame1' <br> $xpaset -p ds9 frame center all # center all frames <br> $xpaset -p ds9 frame clear # clear current frame<br> $xpaset -p ds9 frame new # create new frame <br> $xpaset -p ds9 frame new rgb # create new rgb frame<br> $xpaset -p ds9 frame delete # delete current frame <br> $xpaset -p ds9 frame reset # reset current frame <br> $xpaset -p ds9 frame refresh # refresh current frame <br> $xpaset -p ds9 frame hide # hide current frame <br> $xpaset -p ds9 frame show 1 # show frame 'Frame1'<br> $xpaset -p ds9 frame move first # move frame to first in order<br> $xpaset -p ds9 frame move back # move frame back in order<br> $xpaset -p ds9 frame move forward # move frame forward in order<br> $xpaset -p ds9 frame move last # move frame to last in order<br> $xpaset -p ds9 frame first # goto first frame <br> $xpaset -p ds9 frame prev # goto prev frame <br> $xpaset -p ds9 frame next # goto next frame<br> $xpaset -p ds9 frame last # goto last frame<br> $xpaset -p ds9 frame frameno 4 # goto frame 'Frame4', create if needed<br> $xpaset -p ds9 frame 3 # goto frame 'Frame3', create if needed <br> $xpaset -p ds9 frame match wcs<br> $xpaset -p ds9 frame lock wcs</tt><br> <p><b> <a name="gif"></a>gif</b></p> <p>Load GIF image into current frame.<br> </p> <tt> Syntax:<br> gif [new|slice] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 gif &gt; foo.gif</tt><br> <tt>$xpaset -p ds9 gif foo.gif</tt><br> <tt><tt>$xpaset -p ds9 gif new foo.gif<br> </tt></tt><tt><tt><tt>$xpaset -p ds9 gif slice foo.gif<br> </tt></tt>$cat foo.gif | xpaset ds9 gif # not available windows</tt> <br> <tt><tt>$cat foo.gif | xpaset ds9 gif</tt><tt> new # not available windows<br> </tt>$cat foo.gif | xpaset ds9 gif</tt><tt> slice</tt><tt><tt><tt> # not available windows</tt></tt></tt> <p><b> <a name="grid"></a>grid</b></p> <p> Controls coordinate grid. For grid numeric format syntax,&nbsp; click <a href="grid.html#Format">here</a>.</p> <tt> Syntax: <br> grid&nbsp; []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [type analysis|publication] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [system &lt;coordsys&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sky &lt;skyframe&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat &lt;skyformat&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes type interior|exterior]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes origin lll|llu|lul|luu|ull|ulu|uul|uuu]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format1 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format2 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics type interior|exterior]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics vertical yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title text &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title def yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title gap &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text1 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def1 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text2 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def2 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [reset]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 grid <br> $xpaget ds9 grid type <br> $xpaget ds9 grid system <br> $xpaget ds9 grid sky <br> $xpaget ds9 grid skyformat <br> $xpaget ds9 grid grid <br> $xpaget ds9 grid grid color <br> $xpaget ds9 grid grid width <br> $xpaget ds9 grid grid style <br> $xpaget ds9 grid grid gap1 <br> $xpaget ds9 grid grid gap2 <br> $xpaget ds9 grid axes <br> $xpaget ds9 grid axes color <br> $xpaget ds9 grid axes width <br> $xpaget ds9 grid axes style <br> $xpaget ds9 grid axes type <br> $xpaget ds9 grid axes origin<br> $xpaget ds9 grid format1<br> $xpaget ds9 grid format2<br> $xpaget ds9 grid tickmarks <br> $xpaget ds9 grid tickmarks color <br> $xpaget ds9 grid tickmarks width <br> $xpaget ds9 grid tickmarks style <br> $xpaget ds9 grid border <br> $xpaget ds9 grid border color <br> $xpaget ds9 grid border width <br> $xpaget ds9 grid border style <br> $xpaget ds9 grid numerics <br> $xpaget ds9 grid numerics font <br> $xpaget ds9 grid numerics fontsize <br> $xpaget ds9 grid numerics fontweight<br> $xpaget ds9 grid numerics fontslant<br> $xpaget ds9 grid numerics color <br> $xpaget ds9 grid numerics gap1 <br> $xpaget ds9 grid numerics gap2 <br> $xpaget ds9 grid numerics type <br> $xpaget ds9 grid numerics vertical <br> $xpaget ds9 grid title <br> $xpaget ds9 grid title text<br> $xpaget ds9 grid title def <br> $xpaget ds9 grid title gap <br> $xpaget ds9 grid title font <br> $xpaget ds9 grid title fontsize <br> $xpaget ds9 grid title fontweight<br> $xpaget ds9 grid title fontslant<br> $xpaget ds9 grid title color <br> $xpaget ds9 grid labels <br> $xpaget ds9 grid labels text1 <br> $xpaget ds9 grid labels def1 <br> $xpaget ds9 grid labels gap1 <br> $xpaget ds9 grid labels text2 <br> $xpaget ds9 grid labels def2 <br> $xpaget ds9 grid labels gap2 <br> $xpaget ds9 grid labels font <br> $xpaget ds9 grid labels fontsize <br> $xpaget ds9 grid labels fontweight<br> $xpaget ds9 grid labels fontslant<br> $xpaget ds9 grid labels color <br> $xpaset -p ds9 grid <br> $xpaset -p ds9 grid yes<br> $xpaset -p ds9 grid type analysis <br> $xpaset -p ds9 grid system wcs <br> $xpaset -p ds9 grid sky fk5 <br> $xpaset -p ds9 grid skyformat degrees<br> $xpaset -p ds9 grid grid yes<br> $xpaset -p ds9 grid grid color red<br> $xpaset -p ds9 grid grid width 2<br> $xpaset -p ds9 grid grid style 1<br> $xpaset -p ds9 grid grid gap1 10<br> $xpaset -p ds9 grid grid gap2 10<br> $xpaset -p ds9 grid axes yes<br> $xpaset -p ds9 grid axes color red<br> $xpaset -p ds9 grid axes width 2<br> $xpaset -p ds9 grid axes style 1<br> $xpaset -p ds9 grid axes type exterior<br> $xpaset -p ds9 grid axes origin lll<br> $xpaset -p ds9 grid format1 d.2<br> $xpaset -p ds9 grid format2 d.2<br> $xpaset -p ds9 grid tickmarks yes<br> $xpaset -p ds9 grid tickmarks color red<br> $xpaset -p ds9 grid tickmarks width 2<br> $xpaset -p ds9 grid tickmarks style 1<br> $xpaset -p ds9 grid border yes<br> $xpaset -p ds9 grid border color red<br> $xpaset -p ds9 grid border width 2<br> $xpaset -p ds9 grid border style 1<br> $xpaset -p ds9 grid numerics yes<br> $xpaset -p ds9 grid numerics font courier<br> $xpaset -p ds9 grid numerics fontsize 12<br> $xpaset -p ds9 grid numerics fontweight bold<br> $xpaset -p ds9 grid numerics fontslant italic<br> $xpaset -p ds9 grid numerics color red<br> $xpaset -p ds9 grid numerics gap1 10<br> $xpaset -p ds9 grid numerics gap2 10<br> $xpaset -p ds9 grid numerics type exterior<br> $xpaset -p ds9 grid numerics vertical yes<br> $xpaset -p ds9 grid title yes<br> $xpaset -p ds9 grid title text {Hello World}<br> $xpaset -p ds9 grid title def yes<br> $xpaset -p ds9 grid title gap 10<br> $xpaset -p ds9 grid title font courier<br> $xpaset -p ds9 grid title fontsize 12<br> $xpaset -p ds9 grid title fontweight bold<br> $xpaset -p ds9 grid title fontslant italic<br> $xpaset -p ds9 grid title color red<br> $xpaset -p ds9 grid labels yes<br> $xpaset -p ds9 grid labels text1 {Hello World}<br> $xpaset -p ds9 grid labels def1 yes<br> $xpaset -p ds9 grid labels gap1 10<br> $xpaset -p ds9 grid labels text2 {Hello World}<br> $xpaset -p ds9 grid labels def2 yes<br> $xpaset -p ds9 grid labels gap2 10<br> $xpaset -p ds9 grid labels font courier<br> $xpaset -p ds9 grid labels fontsize 12<br> $xpaset -p ds9 grid labels fontweight boldj<br> $xpaset -p ds9 grid labels fontslant italic<br> $xpaset -p ds9 grid labels color red<br> $xpaset -p ds9 grid reset<br> $xpaset -p ds9 grid load foo.grd <br> $xpaset -p ds9 grid save foo.grd<br> $xpaset -p ds9 grid open<br> $xpaset -p ds9 grid close<br> </tt> <p><b> <a name="header"></a>header</b></p> <p>Display current fits header dialog. Optional extension number maybe specified. Please note, this differs from xpa fits header.</p> <tt> Syntax: <br> header [&lt;ext&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [close [&lt;ext&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save [&lt;ext&gt;] &lt;filename&gt;]<br> &nbsp;<br> Example:<br> $xpaset -p ds9 header<br> $xpaset -p ds9 header 2<br> $xpaset -p ds9 header close<br> $xpaset -p ds9 header save 1 foo.txt<br> </tt> <p><b> <a name="height"></a>height</b></p> <p>Set the height of the image display window. </p> <tt> Syntax: <br> height [&lt;value&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 height<br> $xpaset -p ds9 height 512<br> </tt> <p><b> <a name="iconify"></a>iconify</b></p> <p>Toggles iconification. </p> <tt> Syntax: <br> iconify []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;<br> Example: <br> $xpaget ds9 iconify <br> $xpaset -p ds9 iconify<br> $xpaset -p ds9 iconify yes<br> </tt> <p><b> <a name="iis"></a>iis</b></p> <p>Set/Get IIS Filename. Optional mosaic number maybe supplied.</p> <tt> Syntax: <br> iis [filename &lt;filename&gt; [#]]<br> &nbsp;<br> Example: <br> $xpaget ds9 iis filename<br> $xpaget ds9 iis filename 4<br> $xpaset -p ds9 iis filename foo.fits<br> $xpaset -p ds9 iis filename bar.fits 4</tt><br> <p><b> <a name="imexam"></a>imexam</b></p> <p>Interactive examine function. A blinking cursor will indicate to the user to click on a point on an image. The specified information will be returned at that time.</p> <tt> Syntax: <br> imexam [] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [key] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [any] [coordinate &lt;coordsys&gt; [&lt;skyframe&gt;] [&lt;skyformat&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [] [data [width][height]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [key] [data [width][height]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [any] [data [width][height]]<br> &nbsp;<br> Example: <br> $xpaget ds9 imexam coordinate image<br> $xpaget ds9 imexam key coordinate image # return coordinate and key event<br> $xpaget ds9 imexam any coordinate image # return coordinate and key/mouse event<br> $xpaget ds9 imexam coordinate wcs fk5 degrees<br> $xpaget ds9 imexam coordinate wcs galactic sexagesimal<br> $xpaget ds9 imexam coordinate fk5<br> $xpaget ds9 imexam data # return data value<br> $xpaget ds9 imexam key data # return data value and key event<br> $xpaget ds9 imexam any data # return data value and key/mouse event<br> $xpaget ds9 imexam data 3 3 # return all data in 3x3 box about selected point</tt><br> <p><b> <a name="jpeg"></a>jpeg</b></p> <p>Load JPEG image into current frame. Optional parameters: <tt>jpeg </tt>quality (1-100) </p> <tt> Syntax:<br> jpeg [new|slice] [&lt;filename&gt;] [1-100]<br> &nbsp;<br> Example: <br> $xpaget ds9 jpeg &gt; foo.jpeg</tt><br> <tt><tt>$xpaget ds9 jpeg 100 &gt; foo.jpeg</tt><br> $xpaset -p ds9 jpeg foo.jpeg</tt><br> <tt><tt>$xpaset -p ds9 jpeg new foo.jpeg<br> </tt></tt><tt><tt><tt>$xpaset -p ds9 jpeg slice foo.jpeg<br> </tt></tt>$cat foo.jpeg | xpaset ds9 jpeg </tt><tt><tt><tt> # not available windows</tt></tt></tt><br> <tt><tt>$cat foo.jpeg | xpaset ds9 jpeg</tt><tt> new</tt></tt><tt><tt><tt><tt> # not available windows</tt></tt><br> </tt>$cat foo.jpeg | xpaset ds9 jpeg</tt><tt> slice </tt><tt><tt><tt> # not available windows</tt></tt></tt> <p><b> <a name="lock"></a>lock</b></p> <p>Lock all other frames to the current frame. </p> <tt> Syntax: <br> lock</tt><tt> </tt><tt>[frame &lt;coordsys&gt;|none]<br> &nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;|none] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [crop &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp; [slice [yes|no]]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [bin [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [scale [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [colorbar [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [smooth [yes|no]]</tt><br> <tt>&nbsp;<br> Example:<br> $xpaget -p ds9 lock frame<br> $xpaget -p ds9 lock crosshair<br> </tt><tt>$xpaget -p ds9 lock crop</tt><br> <tt> $xpaget -p ds9 lock slice</tt><br> <tt> $xpaget -p ds9 lock bin<br> $xpaget -p ds9 lock scale<br> $xpaget -p ds9 lock colorbar <br> $xpaget -p ds9 lock smooth<br> $xpaset -p ds9 lock frame wcs</tt><tt><br> </tt><tt>$xpaset -p ds9 lock crosshair wcs<br> </tt><tt>$xpaset -p ds9 lock crop wcs</tt><br> <tt>$xpaset -p ds9 lock slice yes</tt><br> <tt> $xpaset -p ds9 lock bin yes<br> </tt><tt>$xpaset -p ds9 lock scale yes<br> </tt><tt>$xpaset -p ds9 lock colorbar yes<br> $xpaset -p ds9 lock smooth yes<br> </tt> <p><b> <a name="lower"></a>lower</b></p> <p>Lower in the window stacking order. </p> <tt> Syntax: <br> lower <br> &nbsp;<br> Example: <br> $xpaset -p ds9 lower</tt><tt><br> </tt> <p><b> <a name="magnifier"></a>magnifier</b></p> <p>Controls the magnifier settings. </p> <tt> Syntax: <br> magnifier [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [zoom &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cursor yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [region yes|no]<br> &nbsp;<br> Example: <br> $xpaget ds9 magnifier color<br> $xpaget ds9 magnifier zoom<br> $xpaget ds9 magnifier cursor<br> $xpaget ds9 magnifier region<br> $xpaset -p ds9 magnifier color yellow<br> $xpaset -p ds9 magnifier zoom 2<br> $xpaset -p ds9 magnifier cursor no<br> $xpaset -p ds9 magnifier region no</tt><br> <p><b> <a name="mask"></a>mask<br> </b></p> <p>Controls mask parameters. </p> <tt> Syntax: <br> mask [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [mark 1|0]<br> &nbsp;&nbsp;&nbsp;&nbsp; [transparency &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example:<br> $xpaget ds9 mask color<br> $xpaget ds9 mask mark<br> $xpaget ds9 mask transparency<br> $xpaset -p ds9 mask color red<br> $xpaset -p ds9 mask mark 0<br> $xpaset -p ds9 mask transparency 50<br> $xpaset -p ds9 mask clear<br> $xpaset -p ds9 mask open<br> $xpaset -p ds9 mask close<br> </tt> <p><b> <a name="match"></a>match</b></p> <p>Match all other frames to the current frame. </p> <tt> Syntax: <br> </tt><tt>match </tt><tt>[frame &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crop &lt;coordsys&gt;]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [slice]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [bin]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar]<br> &nbsp;&nbsp;&nbsp; &nbsp; [smooth]</tt><br> <tt> <br> Example: <br> $xpaset -p ds9 match frame wcs <br> </tt><tt>$xpaset -p ds9 match crosshair wcs<br> </tt><tt>$xpaset -p ds9 match crop wcs</tt><br> <tt>$xpaset -p ds9 match slice</tt><tt><br> $xpaset -p ds9 match bin<br> $xpaset -p ds9 match scale<br> $xpaset -p ds9 match colorbar<br> $xpaset -p ds9 match smooth</tt><br> <p><b> <a name="mecube"></a>mecube</b></p> <p>Load FITS multiple extension file as data cube.<br> </p> <tt> Syntax:<br> mecube [new] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 mecube &gt; foo.fits<br> $xpaset -p ds9 mecube foo.fits</tt><br> <tt><tt>$xpaset -p ds9 mecube new foo.fits<br> </tt>$cat foo.fits | xpaset ds9 mecube</tt><br> <tt>$cat foo.fits | xpaset ds9 mecube</tt><tt> new</tt> <p><b> <a name="minmax"></a>minmax</b></p> <p>This is how DS9 determines&nbsp; the min and max data values from the data. <tt>SCAN</tt> will scan all data. <tt>SAMPLE</tt> will sample the data every n samples. <tt>DATAMIN</tt> and <tt>IRAFMIN</tt> will use the values of the keywords if present. In general, it is recommended to use <tt>SCAN</tt> unless your computer is slow or your data files are very large. Select the increment&nbsp; interval for determining the min and max data values during sampling. The larger the interval, the quicker the process. </p> <tt> Syntax: <br> minmax [auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;] <br> &nbsp;<br> Example: <br> $xpaget ds9 minmax mode <br> $xpaget ds9 minmax interval <br> $xpaset -p ds9 minmax scan <br> $xpaset -p ds9 minmax mode scan<br> $xpaset -p ds9 minmax interval 10 </tt> <p><b> <a name="mode"></a>mode</b></p> <p>Controls the first mouse button mode. </p> <tt> Syntax: <br> mode [none|pointer|crosshair|colorbar|pan|zoom|rotate|catalog|examine] <br> &nbsp;<br> Example: <br> $xpaget ds9 mode <br> $xpaset -p ds9 mode crosshair</tt><br> <p><b> <a name="mosaic"></a>mosaic</b></p> <p>Load FITS mosaic segment into current frame.</p> <tt> Syntax:<br> mosaic [wcs|wcsa...wcsz|iraf] [new|mask] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 mosaic &gt; foo.fits</tt><tt><br> $xpaset -p ds9 mosaic foo.fits</tt><br> <tt><tt>$xpaset -p ds9 mosaic wcs foo.fits</tt></tt><br> <tt><tt>$xpaset -p ds9 mosaic wcs new foo.fits</tt></tt><br> <tt><tt>$xpaset -p ds9 mosaic wcs mask foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>$cat foo.fits | xpaset ds9 mosaic</tt><br> <tt><tt>$cat foo.fits | xpaset ds9 mosaic wcs<br> $cat foo.fits | xpaset ds9 mosaic wcs</tt><tt> new<br> </tt>$cat foo.fits | xpaset ds9 mosaic wcs</tt><tt> mask<br> </tt> <p><b> <a name="mosaicimage"></a>mosaicimage</b></p> <p>Load FITS mosaic image into current frame.</p> <tt> Syntax:<br> mosaicimage [wcs|wcsa...wcsz|iraf|wfpc2] [new|mask] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 mosaicimage &gt; foo.fits</tt><tt><br> $xpaset -p ds9 mosaicimage foo.fits</tt><br> <tt><tt>$xpaset -p ds9 mosaicimage wcs foo.fits</tt></tt><br> <tt><tt>$xpaset -p ds9 mosaicimage wcs new foo.fits</tt></tt><br> <tt><tt>$xpaset -p ds9 mosaicimage wcs mask foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>$cat foo.fits | xpaset ds9 mosaicimage</tt><br> <tt><tt>$cat foo.fits | xpaset ds9 mosaicimage wcs<br> $cat foo.fits | xpaset ds9 mosaicimage wcs new</tt><tt><br> </tt>$cat foo.fits | xpaset ds9 mosaicimage wcs mask</tt><tt></tt><br> <p><b> <a name="movie"></a>movie<br> savempeg<br> </b></p> <p>Create mpeg1 movie from snap shots of the DS9 window. A <tt>slice</tt> movie cycles though all slices of a cube. A <tt>frame</tt> movie cycles through all active frames. A <tt>3d</tt> movie cycles through specified viewing angles. The default is <tt>frame</tt>. Optional parameters for <tt>3d</tt>: number of frames, azimuth from/to, elevation from/to, slice from/to, oscillate/repeat times.</p> <tt> Syntax:<br> movie </tt><tt>[slice|frame|3d] </tt><tt>&lt;filename&gt;<br> </tt><tt>movie 3d &lt;filename&gt; [number|azfrom|azto|elfrom|elto|slfrom|slto|oscillate|repeat &lt;#&gt;]</tt><br> <tt> &nbsp;<br> Example:<br> $xpaset -p ds9 movie slice ds9.mpg<br> </tt><tt>$xpaset -p ds9 movie 3d ds9.mpg number 10 azfrom -60 azto 60 oscillate 1</tt><br> <p><b> <a name="multiframe"></a>multiframe</b></p> <p>Load FITS multiple extension file as multiple images.<br> </p> <tt> Syntax:<br> multiframe [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaset -p ds9 multiframe foo.fits</tt><tt><tt><br> </tt>$cat foo.fits | xpaset ds9 multiframe</tt><tt><tt><tt> # not available windows</tt></tt></tt><br> <p><b> <a name="nameserver"></a>nameserver</b></p> <p>Support Name Server functions. Coordinates are in fk5. </p> <tt> Syntax: <br> nameserver [&lt;object&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [server ned-sao|ned-eso|simbad-sao|simbad-eso]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pan]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crosshair] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> $xpaget ds9 nameserver<br> $xpaget ds9 nameserver server<br> $xpaget ds9 nameserver skyformat<br> $xpaget ds9 nameserver m31<br> $xpaset -p ds9 nameserver m31 <br> $xpaset -p ds9 nameserver name m31 <br> $xpaset -p ds9 nameserver server ned-sao <br> $xpaset -p ds9 nameserver skyformat sexagesimal<br> $xpaset -p ds9 nameserver pan<br> $xpaset -p ds9 nameserver crosshair<br> $xpaset -p ds9 nameserver open<br> $xpaset -p ds9 nameserver close<br> </tt> <p><b> <a name="nan"></a>nan</b></p> <p>Set image not-a-number color. </p> <tt> Syntax: <br> nan &lt;color&gt;<br> &nbsp;<br> Example:<br> $xpaget ds9 nan<br> $xpaset -p ds9 nan red</tt><tt><br> </tt> <p><b> <a name="nrrd"></a>nrrd</b></p> <p>Load an NRRD (Nearly Raw Raster Data) file. Optional parameter: array endian.<br> </p> <tt> Syntax: <br> nrrd [&lt;filename&gt;] [little|big]<br> &nbsp;<br> Example:<br> $xpaget ds9 nrrd</tt><br> <tt><tt>$xpaget ds9 nrrd big<br> $xpaset -p ds9 nrrd foo.nrrd</tt></tt><br> <tt><tt><tt><tt>$xpaset -p ds9 nrrd new foo.nrrd</tt></tt></tt></tt><br> <tt><tt><tt><tt><tt><tt>$xpaset -p ds9 nrrd mask foo.nrrd<br> </tt></tt></tt></tt></tt>$cat foo.nrrd | xpaset ds9 nrrd</tt><br> <tt>$cat foo.nrrd | xpaset ds9 nrrd</tt><tt> new<br> $cat foo.nrrd | xpaset ds9 nrrd mask</tt> <p><b> <a name="nvss"></a>nvss</b></p> <p>Support for NRAO VLA Sky Survey.</p> <tt> Syntax: <br> nvss []<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 nvss name <br> $xpaget ds9 nvss coord <br> $xpaget ds9 nvss size<br> $xpaget ds9 nvss save<br> $xpaget ds9 nvss frame<br> $xpaset -p ds9 nvss<br> $xpaset -p ds9 nvss m31 <br> $xpaset -p ds9 nvss name m31 <br> $xpaset -p ds9 nvss coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 nvss size 60 60 arcmin<br> $xpaset -p ds9 nvss save yes<br> $xpaset -p ds9 nvss frame current<br> $xpaset -p ds9 nvss update frame<br> $xpaset -p ds9 nvss open<br> </tt><tt>$xpaset -p ds9 nvss close</tt><br> <p><b> <a name="orient"></a>orient</b></p> <p>Controls the orientation of the current frame. </p> <tt> Syntax: <br> orient [none|x|y|xy] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 orient <br> $xpaset -p ds9 orient xy<br> $xpaset -p ds9 orient open<br> $xpaset -p ds9 orient close<br> </tt> <p><b> <a name="pagesetup"></a>pagesetup</b></p> <p>Controls Page Setup options.<br> </p> <tt> Syntax: <br> pagesetup [orient portrait|landscape] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale &lt;numberic&gt;]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size letter|legal|tabloid|poster|a4]</tt><tt></tt><br> <tt> &nbsp;<br> Example: <br> $xpaget ds9 pagesetup orient<br> $xpaget ds9 pagesetup scale <br> $xpaget ds9 pagesetup size <br> $xpaset -p ds9 pagesetup orient portrait <br> $xpaset -p ds9 pagesetup scale 50<br> $xpaset -p ds9 pagesetup size poster<br> </tt> <p><b> <a name="pan"></a>pan</b></p> <p>Controls the current image cursor location for the current frame. </p> <tt> Syntax: <br> pan [&lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;]] <br> &nbsp;&nbsp;&nbsp; [to &lt;x&gt; &lt;y&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;] <br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp; <br> Example: <br> $xpaget ds9 pan # get current image coords <br> $xpaget ds9 pan wcs fk4 sexagesimal # get current wcs coords <br> $xpaset -p ds9 pan 200 200 image # pan relative <br> $xpaset -p ds9 pan to 400 400 physical # pan to physical coords <br> $xpaset -p ds9 pan to 13:29:55 47:11:50 wcs fk5 # pan to wcs coords<br> $xpaset -p ds9 pan open<br> $xpaset -p ds9 pan close<br> </tt> <p><b> <a name="pixeltable"></a>pixeltable</b></p> <p>Display/Hide the pixel table. </p> <tt> Syntax: <br> pixeltable []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [yes|open]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [no|close]<br> &nbsp;<br> Example: <br> $xpaget ds9 pixeltable <br> $xpaset -p ds9 pixeltable<br> $xpaset -p ds9 pixeltable yes<br> $xpaset -p ds9 pixeltable open<br> $xpaset -p ds9 pixeltable close</tt><br> <tt></tt> <p><b> <a name="plot"></a>plot</b></p> <p>Display and configure data plots. All plot commands take an optional second command, the plot name. Use xpaget plot to retrieve all plot names. If no plot name is specified, the last plot created is assumed. Plot data is assumed to be a pair of coordinates, with optional error values. The follow are valid data descriptions:</p> <blockquote>xy &nbsp;&nbsp; &nbsp; &nbsp; x and y coordinates<br> xyex&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with x errors<br> xyey&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with y errors<br> xyexey&nbsp;&nbsp;&nbsp; x,y coordinates with both x and y errors<br> </blockquote> <p>To create a new plot, use the plot new command. If the second arg is stdin, the title, x axis title, y axis title, and dimension are assumed to be on the first line of the data. </p> <tt> Syntax: <br> # create new empty plot window<br> plot [bar|scatter]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new [name &lt;plotname&gt;] [line|bar|scatter]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [new [name &lt;plotname&gt;] [line|bar|scatter] &lt;title&gt; &lt;xaxis label&gt; &lt;yaxis label&gt; </tt><tt>xy|xyex|xyey|xyexey</tt><tt>]<br> <br> # create new plot with data<br> plot [new [name &lt;plotname&gt;] </tt><tt>[line|bar|scatter] </tt><tt>stdin]<br> &nbsp;&nbsp;&nbsp; &nbsp;[new [name &lt;plotname&gt;] [line|bar|scatter] &lt;title&gt; &lt;xaxis label&gt; &lt;yaxis label&gt; xy|xyex|xyey|xyexey]<br> <br> # load dataset into an existing plot<br> plot [&lt;plotname&gt;] [data xy|xyex|xyey|xyexey]<br> <br> # edit existing plot<br> plot [&lt;plotname&gt;] [close]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [load &lt;filename&gt; xy|xyex|xyey|xyexey]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [save &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [loadconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [saveconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [print]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [print destination printer|file] <br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print command &lt;command&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print filename &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [print color rgb|gray]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup orient portrait|landscape]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup size letter|legal|tabloid|poster|a4]</tt><tt></tt><br> <tt> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph grid x|y yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [graph log x|y yes|no]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph flip x|y yes|no]</tt><br> <tt> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y auto yes|no]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y min &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph range x|y max &lt;value&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph format x|y &lt;value&gt;]</tt><br> <tt> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [graph labels title|xaxis|yaxis &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title font times|helvetica|courier]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title size &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp;[&lt;plotname&gt;] [font numbers|labels|title weight normal|bold]<br> &nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [font numbers|labels|title slant roman|italic]<br> <br> # edit current dataset<br> plot [&lt;plotname&gt;] [dataset #]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [view discrete|linear|step|quadratic|error yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [color discrete|linear|step|quadratic|error|bar &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line discrete circle|diamond|plus|cross]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line linear|step|quadratic|error width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[&lt;plotname&gt;] [line linear|step|quadratic dash yes|no]<br> &nbsp;<br> Example: <br> # return all plotnames<br> $xpaget ds9 plot<br> <br> # create new empty plot window<br> $xpaset -p ds9 plot<br> $xpaset -p ds9 scatter<br> $xpaset -p ds9 plot new<br> $xpaset -p ds9 plot new bar<br> $xpaset -p ds9 plot new name foo<br> $xpaset -p ds9 plot new name foo scatter<br> <br> # create new plot with data<br> $cat foo.dat | xpaset ds9 plot new stdin <br> $cat foo.dat | xpaset ds9 plot new name foo stdin<br> $cat bar.dat | xpaset ds9 plot new "{The Title}" "{X}" "{Y}" xy<br> $cat bar.dat | xpaset ds9 plot new name foo "{The Title}" "{X}" "{Y}" xy<br> <br> # load additional dataset into an existing plot<br> $cat bar.dat | xpaset ds9 plot data xy # plot additional data<br> $cat bar.dat | xpaset ds9 plot foo data xy # plot additional data<br> <br> # edit existing plot<br> $xpaset -p ds9 plot close # close last plot<br> $xpaset -p ds9 plot foo close # close plot foo<br> $xpaset -p ds9 plot clear # clear all datasets<br> $xpaset -p ds9 plot load foo.dat xy # load new dataset with dimension xy<br> $xpaset -p ds9 plot save bar.dat # save current dataset<br> $xpaset -p ds9 plot loadconfig foo.plt # load plot configuration <br> $xpaset -p ds9 plot saveconfig bar.plt # save current plot configuration<br> $xpaset -p ds9 plot print<br> $xpaset -p ds9 plot print destination file<br> $xpaset -p ds9 plot print command "lp"<br> $xpaset -p ds9 plot print filename "foo.ps"<br> $xpaset -p ds9 plot print color rgb<br> $xpaset -p ds9 plot pagesetup orient portrait<br> $xpaset -p ds9 plot pagesetup size letter<br> $xpaset -p ds9 plot graph type bar<br> $xpaset -p ds9 plot graph grid x yes<br> $xpaset -p ds9 plot graph log x yes</tt><br> <tt>$xpaset -p ds9 plot graph flip x yes</tt><br> <tt> $xpaset -p ds9 plot graph range x auto yes<br> $xpaset -p ds9 plot graph range x min 0<br> $xpaset -p ds9 plot graph range x max 100<br> $xpaset -p ds9 plot graph range y auto yes<br> $xpaset -p ds9 plot graph range y min 0<br> $xpaset -p ds9 plot graph range y max 100<br> </tt><tt>$xpaset -p ds9 plot graph format y %e</tt><br> <tt> $xpaset -p ds9 plot graph labels title {The Title}<br> $xpaset -p ds9 plot graph labels xaxis {X}<br> $xpaset -p ds9 plot graph labels yaxis {Y}<br> $xpaset -p ds9 plot font numbers font times<br> $xpaset -p ds9 plot font numbers size 12<br> $xpaset -p ds9 plot font numbers weight bold<br> $xpaset -p ds9 plot font numbers slant italic<br> $xpaset -p ds9 plot font labels font times<br> $xpaset -p ds9 plot font title font times<br> <br> # edit current dataset<br> $xpaset -p ds9 plot dataset 2 # set current dataset to the second dataset loaded<br> $xpaset -p ds9 plot view discrete yes<br> $xpaset -p ds9 plot color discrete red<br> $xpaset -p ds9 plot line discrete cross<br> $xpaset -p ds9 plot line step width 2<br> $xpaset -p ds9 plot line step dash yes<br> $xpaset -p ds9 plot line error style 2</tt><br> <p><b><b><a name="png"></a></b>png</b></p> <p>Load PNG image into current frame.<br> </p> <tt> Syntax:<br> png [new|slice] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 png &gt; foo.png</tt><br> <tt>$xpaset -p ds9 png foo.png</tt><br> <tt><tt>$xpaset -p ds9 png new foo.png<br> </tt></tt><tt><tt><tt>$xpaset -p ds9 png slice foo.png<br> </tt></tt>$cat foo.png | xpaset ds9 png</tt><tt><tt><tt> # not available windows</tt></tt></tt><br> <tt><tt>$cat foo.png | xpaset ds9 png</tt><tt> new </tt></tt><tt><tt><tt><tt> # not available windows</tt></tt><br> </tt>$cat foo.png | xpaset ds9 png</tt><tt> slice</tt><tt><tt><tt> # not available windows</tt></tt></tt> <p><b> <a name="prefs"></a>prefs</b></p> <p>Controls various preference settings. </p> <tt> Syntax: <br> prefs&nbsp;clear<br> &nbsp; <br> Example: <br> $xpaset -p ds9 prefs clear</tt> <p><b><a name="preserve"></a>preserve</b> </p> <p>Preserve the follow attributes while loading a new image. </p> <tt> Syntax: <br> preserve [scale yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [pan yes|no]<br> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; [regions yes|no]<br> &nbsp;<br> Example: <br> $xpaget ds9 preserve scale<br> $xpaget ds9 preserve pan<br> $xpaget ds9 preserve regions<br> $xpaset -p ds9 preserve scale yes<br> $xpaset -p ds9 preserve pan yes<br> $xpaset -p ds9 preserve regions yes<br> </tt> <p><b> <a name="psprint"></a>psprint</b></p> <p>For MacOSX and Windows, invokes postscript printing. For all others, same as print. Please see <a href="command.html#print">print</a> for further details.</p> <p><b> <a name="print"></a>print</b></p> <p>Controls printing. Use print option to set printing options. Use print to actually print. </p> <tt> Syntax: <br> print [destination printer|file] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;command&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [filename &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color rgb|cmyk|gray] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [level 1|2] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [resolution 53|72|75|150|300|600] <br> &nbsp;<br> Example: <br> $xpaget ds9 print destination <br> $xpaget ds9 print command <br> $xpaget ds9 print filename <br> $xpaget ds9 print color<br> $xpaget ds9 print level <br> $xpaget ds9 print resolution <br> $xpaset -p ds9 print <br> $xpaset -p ds9 print destination file <br> $xpaset -p ds9 print command '{gv -}' <br> $xpaset -p ds9 print filename foo.ps <br> $xpaset -p ds9 print color cmyk <br> $xpaset -p ds9 print level 2 <br> $xpaset -p ds9 print resolution 75 </tt> <p><b> <a name="raise"></a>raise</b></p> <p>Raise in the window stacking order. </p> <tt> Syntax: <br> raise <br> &nbsp;<br> Example: <br> $xpaset -p ds9 raise </tt> <p><b> <a name="regions"></a>regions</b></p> <p>Controls regions in the current frame. </p> <tt> Syntax: <br> regions&nbsp;[&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load [all] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [list [close]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [show yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [showtext yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid auto yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid radius &lt;value&gt;|iteration &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [getinfo]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move front] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select all]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select none] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select invert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [delete all] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [delete select] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format ds9|xml|ciao|saotng|saoimage|pros|xy] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [system image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sky fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [strip yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [shape &lt;shape&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color &amp;ltcolor&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [fixed|edit|rotate|delete yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [include|exclude|source|background]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [delim [nl|&lt;char&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;marker command&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [composite]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [dissolve]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [template &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [template &lt;filename&gt; at &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [savetemplate &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [groups] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group new]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; new]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; update]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; select]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; color &amp;ltcolor&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; copy] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; delete] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; font &lt;font&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; move &lt;int&gt; &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; movefront] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; moveback] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [group &lt;tag&gt; property &lt;property&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [paste image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [undo]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-format ds9|ciao|saotng|saoimage|pros|xy]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-system image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-sky fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-delim [nl|&lt;char&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-prop select|edit|move|rotate|delete|fixed|include|source 1|0] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-group &lt;tag&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-strip yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [-wcs yes|no]<br> &nbsp;<br> Example: <br> $xpaget ds9 regions<br> $xpaget ds9 regions -format ds9 -system wcs -sky fk5 -skyformat sexagesimal -prop edit 1 -group foo <br> $xpaget ds9 regions show<br> $xpaget ds9 regions showtext<br> $xpaget ds9 regions centroid auto<br> $xpaget ds9 regions centroid radius<br> $xpaget ds9 regions centroid iteration<br> $xpaget ds9 regions selected<br> $xpaget ds9 regions format <br> $xpaget ds9 regions system <br> $xpaget ds9 regions sky <br> $xpaget ds9 regions skyformat <br> $xpaget ds9 regions strip<br> $xpaget ds9 regions shape <br> $xpaget ds9 regions color <br> $xpaget ds9 regions width<br> $xpaget ds9 regions delim<br> $xpaget ds9 regions source <br> $xpaget ds9 regions background <br> $xpaget ds9 regions include <br> $xpaget ds9 regions exclude <br> $xpaget ds9 regions selected<br> $xpaget ds9 regions groups<br> $cat foo.reg | xpaset ds9 regions -format xy -system wcs -sky fk5<br> $cat bar.reg | xpaset ds9 regions -format ds9<br> $echo "image; circle 100 100 20" | xpaset ds9 regions <br> $echo "image; circle 100 100 20" | xpaset ds9 regions<br> $echo "fk5; circle 13:29:55 47:11:50 .5'" | xpaset ds9 regions <br> $echo "physical; ellipse 100 100 20 40" | xpaset ds9 regions <br> $echo "box 100 100 20 40 25" | xpaset ds9 regions <br> $echo "image; line 100 100 200 400" | xpaset ds9 regions <br> $echo "physical; ruler 200 300 200 400" | xpaset ds9 regions <br> $echo "image; text 100 100 # text={Hello, World}" | xpaset ds9 regions <br> $echo "fk4; boxcircle point 13:29:55 47:11:50" | xpaset ds9 regions <br> $xpaset -p ds9 regions foo.reg <br> $xpaset -p ds9 regions -format ciao bar.reg # load as ciao format<br> $xpaset -p ds9 regions foo.fits # FITS regions files do not need a format specification<br> $xpaset -p ds9 regions load foo.reg # load foo.reg into current frame<br> $xpaset -p ds9 regions load all foo.reg # load foo.reg into all frames<br> $xpaset -p ds9 regions load '*.reg'# expand *.reg and load into current frame<br> $xpaset -p ds9 regions load all '*.reg' # expand *.reg and load into all frames<br> $xpaset -p ds9 regions save foo.reg<br> $xpaset -p ds9 regions list <br> $xpaset -p ds9 regions list close<br> $xpaset -p ds9 regions show yes<br> $xpaset -p ds9 regions showtext no<br> $xpaset -p ds9 regions centroid<br> $xpaset -p ds9 regions centroid auto yes<br> $xpaset -p ds9 regions centroid radius 10<br> $xpaset -p ds9 regions centroid iteration 20<br> $xpaset -p ds9 regions getinfo<br> $xpaset -p ds9 regions move back <br> $xpaset -p ds9 regions move front <br> $xpaset -p ds9 regions select all <br> $xpaset -p ds9 regions select none <br> $xpaset -p ds9 regions select invert<br> $xpaset -p ds9 regions delete all <br> $xpaset -p ds9 regions delete select <br> $xpaset -p ds9 regions format ds9 <br> $xpaset -p ds9 regions system wcs<br> $xpaset -p ds9 regions sky fk5 <br> $xpaset -p ds9 regions skyformat degrees <br> $xpaset -p ds9 regions delim nl <br> $xpaset -p ds9 regions strip yes<br> $xpaset -p ds9 regions shape ellipse <br> $xpaset -p ds9 regions color red <br> $xpaset -p ds9 regions width 3<br> $xpaset -p ds9 regions edit yes<br> $xpaset -p ds9 regions include<br> $xpaset -p ds9 regions command '{circle 100 100 20 # color=red}'<br> $xpaset -p ds9 regions composite<br> $xpaset -p ds9 regions dissolve<br> $xpaset -p ds9 regions template foo.tpl<br> $xpaset -p ds9 regions template foo.tpl at 13:29:55.92 +47:12:48.02 fk5<br> $xpaset -p ds9 regions savetemplate foo.tpl<br> $xpaset -p ds9 regions group new<br> $xpaset -p ds9 regions group foo new<br> </tt><tt>$xpaset -p ds9 regions group foo update</tt><br> <tt>$xpaset -p ds9 regions group foo select</tt><br> <tt>$xpaset -p ds9 regions group foo color red<br> $xpaset -p ds9 regions group foo copy<br> $xpaset -p ds9 regions group foo delete<br> $xpaset -p ds9 regions group foo cut<br> $xpaset -p ds9 regions group foo font {times 14 bold}<br> $xpaset -p ds9 regions group foo move 100 100 <br> $xpaset -p ds9 regions group foo movefront <br> $xpaset -p ds9 regions group foo moveback <br> $xpaset -p ds9 regions group foo property delete no <br> <br> $xpaset -p ds9 regions copy<br> $xpaset -p ds9 regions cut<br> $xpaset -p ds9 regions paste wcs<br> $xpaset -p ds9 regions undo<br> </tt> <p><b> <a name="restore"></a>restore</b></p> <p>Restore DS9 to a previous state from a backup save set. </p> <tt> Syntax: <br> restore &lt;filename&gt;<br> &nbsp;<br> Example:<br> $xpaset -p ds9 restore ds9.bck</tt><br> <p><b> <a name="rgb"></a>rgb</b></p> <p>Create RGB frame and control RGB frame parameters.</p> <tt> Syntax: <br> rgb&nbsp; []<br> &nbsp;&nbsp;&nbsp; &nbsp;[red|green|blue]<br> &nbsp;&nbsp;&nbsp; &nbsp;[channel [red|green|blue]]<br> &nbsp;&nbsp; &nbsp; [view [red|green|blue] [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[lock wcs|crop|slice|bin|scale|colorbar|smooth [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $xpaget ds9 rgb channel<br> </tt><tt>$xpaget ds9 rgb lock wcs</tt><br> <tt>$xpaget ds9 rgb lock crop</tt><br> <tt>$xpaget ds9 rgb lock slice</tt><br> <tt> $xpaget ds9 rgb lock bin<br> $xpaget ds9 rgb lock scale<br> $xpaget ds9 rgb lock colorbar<br> $xpaget ds9 rgb lock smooth<br> $xpaget ds9 rgb system<br> $xpaget ds9 rgb view red<br> $xpaget ds9 rgb view green<br> $xpaget ds9 rgb view blue<br> $xpaset -p ds9 rgb # create new rgb frame<br> $xpaset -p ds9 rgb red # set current channel to red<br> $xpaset -p ds9 rgb channel red # set current channel to red<br> $xpaset -p ds9 rgb view blue no # turn off blue channel<br> $xpaset -p ds9 rgb system wcs # set rgb coordinate system<br> </tt><tt>$xpaset -p ds9 rgb lock wcs yes</tt><br> <tt>$xpaset -p ds9 rgb lock crop yes</tt><br> <tt>$xpaset -p ds9 rgb lock slice yes</tt><br> <tt>$xpaset -p ds9 rgb lock bin yes</tt><br> <tt> $xpaset -p ds9 rgb lock scale yes<br> $xpaset -p ds9 rgb lock colorbar yes<br> $xpaset -p ds9 rgb lock smooth yes<br> $xpaset -p ds9 rgb open<br> $xpaset -p ds9 rgb close</tt><br> <p><b> <a name="rgbarray"></a>rgbarray</b></p> <p>Load raw data array cube into rgb frame.<br> </p> <tt> Syntax:<br> rgbarray [native|big|little]<br> rgbarray [new|mask] [[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],[zdim=3],bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> $xpaget ds9 rgbarray &gt; foo.arr<br> $xpaget ds9 rgbarray little &gt; foo.arr<br> $xpaset -p ds9 rgbarray foo.arr[dim=512,zdim=3,bitpix=-32,endian=little]<br> $xpaset -p ds9 rgbarray new foo.arr[dim=512,zdim=3,bitpix=</tt><tt>-32,endian=little]</tt><br> <tt>$cat foo.arr | xpaset ds9 rgbarray [dim=512,zdim=3,bitpix=-32,endian=little]</tt><br> <tt>$cat foo.arr | xpaset ds9 rgbarray new [dim=512,zdim=3,bitpix=-32,endian=little]</tt><br> <p><b> <a name="rgbcube"></a>rgbcube</b></p> <p>Load FITS rgbcube into rgb frame.<br> </p> <tt> Syntax:<br> rgbcube [new] [&lt;filename&gt;]<br> <br> Example: <br> $xpaget ds9 rgbcube &gt; foo.fits<br> $xpaset -p ds9 rgbcube foo.fits</tt><br> <tt><tt>$xpaset -p ds9 rgbcube new foo.fits<br> </tt>$cat foo.fits | xpaset ds9 rgbcube</tt><br> <tt>$cat foo.fits | xpaset ds9 rgbcube</tt><tt> new</tt><br> <p><b> <a name="rgbimage"></a>rgbimage</b></p> <p>Load FITS rgbimage into rgb frame.<br> </p> <tt> Syntax:<br> rgbimage [new] [&lt;filename&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 rgbimage &gt; foo.fits<br> $xpaset -p ds9 rgbimage foo.fits</tt><br> <tt><tt>$xpaset -p ds9 rgbimage new foo.fits<br> </tt>$cat foo.fits | xpaset ds9 rgbimage</tt><br> <tt>$cat foo.fits | xpaset ds9 rgbimage</tt><tt> new<br> </tt> <p><b> <a name="rotate"></a>rotate</b></p> <p>Controls the rotation angle (in degrees) of the current frame. </p> <tt> Syntax: <br> rotate [&lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> $xpaget ds9 rotate <br> $xpaset -p ds9 rotate 45 <br> $xpaset -p ds9 rotate to 30<br> $xpaset -p ds9 rotate open<br> $xpaset -p ds9 rotate close<br> </tt> <p><b> <a name="save"></a>save<br> </b></p> <p>Save loaded image data of current frame as FITS.</p> <tt> Syntax: <br> save </tt><tt>[fits|rgbimage|rgbcube|mecube|mosaic|mosaicimage] &lt;filename&gt; [image|table|slice]</tt> <br> <tt> &nbsp;<br> Example: <br> $xpaset -p ds9 save foo.fits</tt><br> <tt>$xpaset -p ds9 save fits foo.fits image</tt><br> <tt>$xpaset -p ds9 save fits foo.fits table<br> $xpaset -p ds9 save fits foo.fits slice</tt><br> <tt>$xpaset -p ds9 save rgbimage foo.fits<br> </tt><tt>$xpaset -p ds9 save rgbcube foo.fits</tt><br> <tt>$xpaset -p ds9 save mecube foo.fits</tt><br> <tt>$xpaset -p ds9 save mosaic foo.fits</tt><br> <tt>$xpaset -p ds9 save mosaicimage foo.fits</tt><br> <p><b> <a name="saveimage"></a>saveimage<br> </b></p> <tt></tt> <p>Create a snap shot of the current DS9 window and save in specified image format. If no format specified, the file name extension is used to determine the output format. Optional parameters: <tt>jpeg </tt>quality (1-100) and <tt>tiff </tt>compression method. </p> <tt> Syntax: <br> saveimage </tt><tt>[fits|eps|gif|tiff|jpeg|png] </tt><tt>&lt;filename&gt;<br> saveimage &lt;filename&gt;.jpeg [1-100]<br> saveimage &lt;filename&gt;.tiff [none|jpeg|packbits|deflate]<br> &nbsp;<br> Example: <br> $xpaset -p ds9 saveimage ds9.tiff<br> $xpaset -p ds9 saveimage jpeg ds9.jpeg 75</tt><tt></tt><br> <p><b> <a name="scale"></a>scale</b></p> <p>Controls the limits and color scale distribution. </p> <tt> Syntax: <br> scale [linear|log|pow|sqrt|squared|asinh|sinh|histequ]<br> &nbsp; &nbsp; &nbsp; [log exp &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [datasec yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [limits &lt;minvalue&gt; &lt;maxvalue&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scope local|global] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; &nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> $xpaget ds9 scale<br> $xpaget ds9 scale log exp <br> $xpaget ds9 scale datasec <br> $xpaget ds9 scale limits <br> $xpaget ds9 scale mode <br> $xpaget ds9 scale scope <br> $xpaget ds9 scale lock<br> $xpaset -p ds9 scale linear<br> $xpaset -p ds9 scale log 100<br> $xpaset -p ds9 scale datasec yes <br> $xpaset -p ds9 scale histequ <br> $xpaset -p ds9 scale limits 1 100 <br> $xpaset -p ds9 scale mode zscale <br> $xpaset -p ds9 scale mode 99.5 <br> $xpaset -p ds9 scale scope local<br> $xpaset -p ds9 scale match<br> $xpaset -p ds9 scale lock yes<br> $xpaset -p ds9 scale open<br> $xpaset -p ds9 scale close<br> </tt> <p><b> <a name="shm"></a>shm</b></p> <p>Load a shared memory segment into the current frame. </p> <tt> Syntax: <br> shm [&lt;key&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [key &lt;key&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [shmid &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [fits [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaicimage [iraf|wcs|wcsa...wcsz|wfpc2] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaicimagenext [wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [mosaic [iraf|wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp; [rgbcube [key|shmid] &lt;id&gt; [&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; [rgbimage [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; [rgbarray [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;,zdim=3],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;&nbsp;&nbsp; [array [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;&nbsp;&nbsp; [startload|finishload]<br> &nbsp;<br> Example: <br> $xpaget ds9 shm <br> $xpaset -p ds9 shm 102 <br> $xpaset -p ds9 shm key 102<br> $xpaset -p ds9 shm shmid 102 foo<br> $xpaset -p ds9 shm fits key 100 foo <br> $xpaset -p ds9 shm mosaicimage iraf key 100 foo <br> $xpaset -p ds9 shm mosaicimage wcs key 100 foo <br> $xpaset -p ds9 shm mosaicimage wcsa key 100 foo <br> $xpaset -p ds9 shm mosaicimage wfpc2 key 100 foo <br> $xpaset -p ds9 shm mosaicimagenext wcs key 100 foo<br> $xpaset -p ds9 shm mosaic iraf key 100 foo <br> $xpaset -p ds9 shm mosaic wcs key 100 foo <br> $xpaset -p ds9 shm rgbcube key 100 foo <br> $xpaset -p ds9 shm rgbimage key 100 foo<br> $xpaset -p ds9 shm rgbarray key 100 [dim=200,zdim=3,bitpix=-32]<br> $xpaset -p ds9 shm array shmid 102 [dim=32,bitpix=-32]<br> $xpaset -p ds9 shm startload # start a multiple load sequence without updating the display<br> $xpaset -p ds9 shm finishload # finish multiple load sequence<br> </tt> <p><b> <a name="single"></a>single</b></p> <p>Select Single Display mode </p> <tt> Syntax: <br> single <br> &nbsp;<br> Example: <br> $xpaget ds9 single <br> $xpaset -p ds9 single<br> </tt> <p><b> <a name="skyview"></a>skyview </b></p> <p>Support for SkyView image server at HEASARC. </p> <tt> Syntax: <br> skyview []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [survey sdssi|sdssr|sdssg|sdssu|sdssg] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> $xpaget ds9 skyview name <br> $xpaget ds9 skyview coord <br> $xpaget ds9 skyview size<br> $xpaget ds9 skyview save<br> $xpaget ds9 skyview frame<br> $xpaget ds9 skyview survey<br> $xpaset -p ds9 skyview<br> $xpaset -p ds9 skyview m31 <br> $xpaset -p ds9 skyview name m31 <br> $xpaset -p ds9 skyview coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $xpaset -p ds9 skyview size 60 60 arcmin<br> $xpaset -p ds9 skyview save yes<br> $xpaset -p ds9 skyview frame current<br> $xpaset -p ds9 skyview update frame<br> $xpaset -p ds9 skyview survey sdssi<br> $xpaset -p ds9 skyview open<br> </tt><tt>$xpaset -p ds9 skyview close</tt><br> <p><b> <a name="sleep"></a>sleep </b></p> <p>Delays execution for specified number of seconds. Default is 1 second. <br> </p> <tt> Syntax: <br> sleep [#]<br> &nbsp;<br> Example: <br> $xpaset -p ds9 sleep<br> $xpaset -p ds9 sleep 2<br> </tt> <p><b> <a name="smooth"></a>smooth</b></p> <p>Smooth current image or set smooth parameters.</p> <tt> Syntax:<br> smooth []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [function boxcar|tophat|gaussian]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [radius &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [lock [yes|no]]<br> <br> Example:<br> $xpaget ds9 smooth<br> $xpaget ds9 smooth function<br> $xpaget ds9 smooth radius<br> $xpaget ds9 smooth lock<br> $xpaset -p ds9 smooth<br> $xpaset -p ds9 smooth yes<br> $xpaset -p ds9 smooth function tophat<br> $xpaset -p ds9 smooth radius 4<br> $xpaset -p ds9 smooth open<br> $xpaset -p ds9 smooth close<br> $xpaset -p ds9 smooth match<br> $xpaset -p ds9 smooth lock yes<br> </tt> <p><b> <a name="source"></a>source</b></p> <p>Source TCL code from a file. </p> <tt> Syntax: <br> source [filename] <br> &nbsp;<br> Example: <br> $xpaset -p ds9 source foo.tcl </tt> <p><b> <a name="tcl"></a>tcl</b></p> <p>Execute one tcl command. Must be enabled via the -tcl command line option.</p> <tt> Syntax: <br> tcl [&lt;tcl command&gt;] <br> &nbsp;<br> Example: <br> $echo 'puts "Hello, World"' | xpaset ds9 tcl<br> $xpaset -p ds9 tcl 'puts "Hello, World"'<br> </tt> <p><b> <a name="theme"></a>theme</b></p> <p>Select GUI theme. Use <tt>native</tt> for the recommended theme for your platform. Note: not all themes are available on all platforms.<br> </p> <tt> Syntax:<br> theme [native|clam|alt|default|classic|aqua|vista|win|xp] <br> &nbsp;<br> Example: <br> $xpaget ds9 theme<br> $xpaset -p ds9 theme clam<br> </tt> <p><b> <a name="threads"></a>threads</b></p> <p>Set number of process threads for functions which are multi-threaded.<br> </p> <tt> Syntax:<br> threads #<br> &nbsp;<br> Example: <br> $xpaget ds9 threads<br> $xpaset -p ds9 threads 8</tt><br> <p><b> <a name="tiff"></a>tiff</b></p> <p>Load TIFF image into current frame. Optional parameters: <tt>tiff </tt>compression method. </p> <tt> Syntax:<br> tiff [new|slice] [&lt;filename&gt;] [none|jpeg|packbits|deflate]<br> &nbsp;<br> Example: <br> $xpaget ds9 tiff &gt; foo.tiff</tt><br> <tt><tt>$xpaget ds9 tiff jpeg &gt; foo.tiff</tt><br> $xpaset -p ds9 tiff foo.tiff</tt><br> <tt><tt>$xpaset -p ds9 tiff new foo.tiff<br> </tt></tt><tt><tt><tt>$xpaset -p ds9 tiff slice foo.tiff<br> </tt></tt>$cat foo.tiff | xpaset ds9 tiff</tt><tt><tt><tt> # not available windows</tt></tt></tt><br> <tt><tt>$cat foo.tiff | xpaset ds9 tiff</tt><tt> new</tt></tt><tt><tt><tt><tt> # not available windows</tt></tt><br> </tt>$cat foo.tiff | xpaset ds9 tiff</tt><tt> slice</tt><tt><tt><tt> # not available windows</tt></tt></tt> <p><b> <a name="tile"></a>tile</b></p> <p>Controls the tile display mode. </p> <tt> Syntax: <br> tile []<br> &nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [mode grid|column|row] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid mode [automatic|manual]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid layout &lt;col&gt; &lt;row&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [grid gap &lt;pixels&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [row] <br> &nbsp;&nbsp;&nbsp;&nbsp; [column] <br> &nbsp;<br> Example: <br> $xpaget ds9 tile <br> $xpaget ds9 tile mode <br> $xpaget ds9 tile grid mode <br> $xpaget ds9 tile grid layout <br> $xpaget ds9 tile grid gap <br> $xpaset -p ds9 tile<br> $xpaset -p ds9 tile yes <br> $xpaset -p ds9 tile mode row <br> $xpaset -p ds9 tile grid <br> $xpaset -p ds9 tile grid mode manual <br> $xpaset -p ds9 tile grid layout 5 5 <br> $xpaset -p ds9 tile grid gap 10 <br> $xpaset -p ds9 tile row <br> $xpaset -p ds9 tile column </tt> <p><b> <a name="update"></a>update</b></p> <p>Updates the current frame or region of frame. In the second form, the first argument is the number of the fits HDU (starting with 1) and the remaining args are a bounding box in IMAGE coordinates. By default, the screen is updated the next available idle cycle. However, you may force an immediate update by specifying the NOW option. </p> <tt> Syntax: <br> update [] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [# x1 y1 x2 y2] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now # x1 y1 x2 y2]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [on]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[off] <br> &nbsp;<br> Example: <br> $xpaset -p ds9 update <br> $xpaset -p ds9 update 1 100 100 300 400 <br> $xpaset -p ds9 update now <br> $xpaset -p ds9 update now 1 100 100 300 400<br> $xpaset -p ds9 update off # delay refresh of the screen while loading files<br> $xpaset -p ds9 update on # be sure to turn it on when you are finished loading</tt><br> <p><b> <a name="url"></a>url</b></p> <p>Load FITS from URL into the current frame</p> <tt> Syntax: <br> url &lt;url&gt;<br> &nbsp;<br> Example: <br> $xpaset -p ds9 url http://foo.bar.edu/foo.fits <br> </tt> <p><b> <a name="version"></a>version</b></p> <p>Returns the current version of DS9. </p> <tt> Syntax: <br> version <br> &nbsp;<br> Example: <br> $xpaget ds9 version </tt> <p><b> <a name="view"></a>view</b></p> <p>Controls the GUI. </p> <tt> Syntax: <br> view&nbsp; [layout horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [info yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [panner yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [magnifier yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [buttons yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar numerics yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [graph horizontal|vertical yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [filename yes|no[<br> &nbsp;&nbsp;&nbsp; &nbsp; [object yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [minmax yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [lowhigh yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [frame yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [image|physical|wcs|wcsa...wcsz yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [red yes|no]<br> &nbsp; &nbsp; &nbsp; [green yes|no]<br> &nbsp; &nbsp; &nbsp; [blue yes|no]<br> &nbsp;<br> Example: <br> $xpaget ds9 view layout<br> $xpaget ds9 view info <br> $xpaget ds9 view panner<br> $xpaget ds9 view magnifier<br> $xpaget ds9 view buttons<br> $xpaget ds9 view colorbar<br> $xpaget ds9 view graph horizontal<br> $xpaget ds9 view filename<br> $xpaget ds9 view object<br> $xpaget ds9 view minmax<br> $xpaget ds9 view lowhigh<br> $xpaget ds9 view frame<br> $xpaget ds9 view image<br> $xpaget ds9 view wcsa<br> $xpaget ds9 view red<br> $xpaset -p ds9 view layout vertical<br> $xpaset -p ds9 view info yes<br> $xpaset -p ds9 view panner yes<br> $xpaset -p ds9 view magnifier yes<br> $xpaset -p ds9 view buttons yes<br> $xpaset -p ds9 view colorbar yes<br> $xpaset -p ds9 view graph horizontal yes<br> $xpaset -p ds9 view filename yes<br> $xpaset -p ds9 view object yes<br> $xpaset -p ds9 view minmax yes<br> $xpaset -p ds9 view lowhigh yes<br> $xpaset -p ds9 view frame yes <br> $xpaset -p ds9 view wcsa yes<br> $xpaset -p ds9 view red yes<br> $xpaset -p ds9 view green no<br> $xpaset -p ds9 view blue yes<br> </tt> <p><b> <a name="vo"></a>vo</b></p> <p>Invoke an connection to a Virtual Observatory site. </p> <tt> Syntax: <br> vo [method xpa|mime]<br> &nbsp;&nbsp; [server &lt;url&gt;]<br> &nbsp;&nbsp; [internal yes|no]<br> &nbsp;&nbsp; [delay #]<br> &nbsp;&nbsp; [&lt;url&gt;]<br> &nbsp;&nbsp; [connect &lt;url&gt;]<br> &nbsp;&nbsp; [disconnect &lt;url&gt;]<br> &nbsp;&nbsp; [open|close]<br> <br> Example:<br> $xpaget ds9 vo <br> $xpaget ds9 vo method<br> $xpaget ds9 vo server<br> $xpaget ds9 vo internal<br> $xpaget ds9 vo delay<br> $xpaget ds9 vo connect<br> $xpaset -p ds9 vo method xpa<br> $xpaset -p ds9 vo server "http://foo.bar.edu/list.txt"<br> $xpaset -p ds9 vo internal yes<br> $xpaset -p ds9 vo delay 15 # keep-alive delay<br> $xpaset -p ds9 vo chandra-ed<br> $xpaset -p ds9 vo connect chandra-ed<br> $xpaset -p ds9 vo disconnect chandra-ed<br> $xpaset -p ds9 vo open<br> $xpaset -p ds9 vo close<br> </tt> <p><b> <a name="wcs"></a>wcs</b></p> <p>Controls the World Coordinate System for the current frame. If the wcs system, skyframe, or skyformat is modified, the info panel, compass, grid, and alignment will be modified accordingly. Also, using this access point, a new WCS specification can be loaded and used by the current image regardless of the WCS that was contained in the image file. WCS specification can be sent to DS9 as an ASCII file . Please see <a href="file.html#WCS">WCS</a> for more information. </p> <tt> Syntax: <br> wcs [[system] wcs|wcsa...wcsz] <br> &nbsp;&nbsp;&nbsp; [[sky] fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp; [[skyformat] degrees|sexagesimal] <br> &nbsp;&nbsp;&nbsp; [align yes|no] <br> &nbsp;&nbsp;&nbsp; [reset [#]] <br> &nbsp;&nbsp;&nbsp; [replace [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; [append [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp; [open|close]<br> <br> Example: <br> $xpaget ds9 wcs <br> $xpaget ds9 wcs system <br> $xpaget ds9 wcs sky <br> $xpaget ds9 wcs skyformat <br> $xpaget ds9 wcs align <br> $xpaset -p ds9 wcs wcs <br> $xpaset -p ds9 wcs system wcs<br> $xpaset -p ds9 wcs fk5 <br> </tt><tt>$xpaset -p ds9 wcs sky fk5 <br> </tt><tt>$xpaset -p ds9 wcs sexagesimal <br> </tt><tt>$xpaset -p ds9 wcs skyformat sexagesimal <br> $xpaset -p ds9 wcs align yes<br> $xpaset -p ds9 wcs reset<br> $xpaset -p ds9 wcs reset 3<br> $xpaset -p ds9 wcs replace foo.wcs<br> $xpaset -p ds9 wcs replace 3 foo.wcs <br> $xpaset -p ds9 wcs append foo.wcs<br> $xpaset -p ds9 wcs append 3 foo.wcs <br> $cat foo.wcs | xpaset ds9 wcs replace <br> $cat foo.wcs | xpaset ds9 wcs append <br> $echo "OBJECT = 'foobar'" | xpaset ds9 wcs append<br> $xpaset -p ds9 open<br> $xpaset -p ds9 close<br> </tt> <p><b> <a name="web"></a>web</b></p> <p>Display specified URL in the web display. </p> <tt> Syntax:<br> web [new|&lt;webname&gt;] [&lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [click back|forward|stop|reload|#]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [clear]<br> &nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [close]<br> &nbsp;<br> Example: <br> $xpaget ds9 web <br> $xpaset -p ds9 web www.cnn.com<br> $xpaset -p ds9 web new www.cnn.com<br> $xpaset -p ds9 web hvweb www.apple.com<br> $xpaset -p ds9 web click back<br> $xpaset -p ds9 web click 2<br> $xpaset -p ds9 web clear<br> $xpaset -p ds9 web close<br> </tt> <p><b> <a name="width"></a>width</b></p> <p>Set the width of the image display window.</p> <tt> Syntax: <br> width [&lt;value&gt;]<br> &nbsp;<br> Example: <br> $xpaget ds9 width<br> $xpaset -p ds9 width 512<br> </tt> <p><b> <a name="zscale"></a>zscale</b></p> <p>Set Scale Limits based&nbsp; on the <i>IRAF</i> algorithm. </p> <tt> Syntax: <br> zscale []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [contrast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sample]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [line]<br> &nbsp;<br> Example:<br> $xpaget ds9 zscale contrast<br> $xpaget ds9 zscale sample<br> $xpaget ds9 zscale line<br> $xpaset -p ds9 zscale<br> $xpaset -p ds9 zscale contrast .25<br> $xpaset -p ds9 zscale sample 600<br> $xpaset -p ds9 zscale line 120<br> </tt> <p><b> <a name="zoom"></a>zoom</b></p> <p>Controls the current zoom value for the current frame. </p> <tt> Syntax: <br> zoom [&lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;value&gt; &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt; &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $xpaget ds9 zoom <br> $xpaset -p ds9 zoom 2 <br> $xpaset -p ds9 zoom 2 4<br> $xpaset -p ds9 zoom to 4 <br> $xpaset -p ds9 zoom to 2 4<br> $xpaset -p ds9 zoom to fit<br> $xpaset -p ds9 zoom open<br> $xpaset -p ds9 zoom close<br> </tt> </blockquote> </body> </html> ����������������������������������������./saods9/doc/ref/command.html�����������������������������������������������������������������������0000644�0001750�0001750�00000333534�12131601437�014741� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Command Line Options</title> </head> <body alink="#ff0000" link="#0000ff" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Command Line Options</h3> <blockquote> <p>DS9 will process each command line option, one at a time, as the last step in the initialization process. Therefore, it is possible to use command line options as a little script. For example, the following command line option is used:</p> <tt>$ds9 -tile foo.fits -cmap Heat -zscale bar.fits -cmap I8</tt> <p>First DS9 is put in tile mode, then <tt>foo.fits</tt> is loaded. Then the colormap for <tt>foo.fits</tt> is changed to <tt>Heat</tt> and the scale changed to <tt>zscale</tt>. Next, <tt>bar.fits</tt> is loaded and the colormap for <tt>bar.fits</tt> is changed to <tt>I8.</tt> </p> <tt> <a href="#2mass">2mass</a><br> <a href="#3d">3d</a><br> <a href="#about">about</a><br> <a href="#align">align</a><br> <a href="#analysis">analysis</a><br> <a href="#array">array</a><br> <a href="asinh">asinh</a><br> <a href="#background">background</a><br> <a href="#backup">backup</a><br> <a href="#bin">bin</a><br> <a href="#blink">blink</a><br> <a href="#blue">blue</a><br> <a href="#catalog">catalog</a><br> <a href="#cd">cd</a><br> <a href="#cmap">cmap</a><br> <a href="#colorbar">colorbar</a><br> <a href="#console">console</a><br> <a href="#contour">contour</a><br> <a href="crop">crop</a><br> <a href="#crosshair">crosshair</a><br> <a href="#cube">cube</a><br> <a href="#cursor">cursor</a><br> <a href="#dsssao">dsssao</a><br> <a href="#dsseso">dsseso</a><br> <a href="#dssstsci">dssstsci</a><br> <a href="#exit">exit</a><br> <a href="#export">export</a><br> <a href="#fifo">fifo</a><br> <a href="#fifo_only">fifo_only</a><br> <a href="#first">first</a><br> <a href="command.html#fits">fits</a><br> <a href="#frame">frame</a><br> <a href="#geometry">geometry</a><br> <a href="#gif">gif</a><br> <a href="#green">green</a><br> <a href="#geometry">grid</a><br> <a href="#header">header</a><br> <a href="#height">height</a><br> <a href="#help">help</a><br> <a href="#histequ">histequ</a><br> <a href="#iconify">iconify</a><br> <a href="#import">import</a><br> <a href="#inet_only">inet_only</a><br> <a href="#invert">invert</a><br> <a href="#iis">iis</a><br> <a href="#jpeg">jpeg</a><br> <a href="#language">language</a><br> <a href="#linear">linear</a><br> <a href="#lock">lock</a><br> <a href="#log">log</a><br> <a href="#lower">lower</a><br> <a href="#magnifier">magnifier</a><br> <a href="#mask">mask</a><br> <a href="#match">match</a><br> <a href="#mecube">mecube</a><br> <a href="#minmax">minmax</a><br> <a href="#mode">mode</a><br> </tt><tt><a href="#mode"><tt></tt></a><tt><a href="#mosaic">mosaic</a></tt><br> <a href="#mosaicimage">mosaicimage</a><br> <a href="#movie">movie</a></tt><br> <tt><tt><a href="file:///Users/joye/saods9/doc/ref/command.html#msg">msg</a><br> </tt><a href="#multiframe">multiframe</a><br> <a href="#nameserver">nameserver</a><br> <a href="#nan">nan</a><br> <a href="#nrrd">nrrd</a><br> <a href="#nvss">nvss</a><br> <a href="#orient">orient</a><br> <a href="#pagesetup">pagesetup</a><br> <a href="#pan">pan</a><br> <a href="#pixeltable">pixeltable</a><br> <a href="#plot">plot</a><br> <a href="#png">png</a><br> <a href="#prefs">prefs</a><br> <a href="#preserve">preserve</a><br> <a href="#psprint">psprint</a><br> <a href="#print">print</a><br> <a href="#private">private</a><br> <a href="#port">port</a><br> <a href="#port_only">port_only</a><br> <a href="#pow">pow</a><br> <a href="#exit">quit</a><br> <a href="#raise">raise</a><br> <a href="#regions">regions</a><br> </tt><tt><a href="#red">red</a><br> </tt><tt><a href="#restore">restore</a><br> <a href="#rgb">rgb</a><br> <a href="#rgbarray">rgbarray</a><br> <a href="#rgbcube">rgbcube</a><br> <a href="#rgbimage">rgbimage</a><br> <a href="#rotate">rotate</a><br> <a href="#samp">samp</a><br> <a href="#save">save</a><br> <a href="#saveimage">saveimage</a><br> <a href="#scale">scale</a><br> <a href="#shm">shm</a><br> <a href="#single">single</a><br> <a href="sinh">sinh</a><br> <a href="#skyview">skyview</a><br> <a href="#sleep">sleep</a><br> <a href="#slice">slice</a><br> <a href="#smooth">smooth</a><br> <a href="#squared">squared</a><br> <a href="#sqrt">sqrt</a><br> <a href="#source">source</a><br> <a href="#tcl">tcl</a><br> <a href="#theme">theme</a><br> <a href="#threads">threads</a><br> <a href="#tiff">tiff</a><br> <a href="#tile">tile</a><br> <a href="#title">title</a><br> <a href="#unix">unix</a><br> <a href="#unix_only">unix_only</a><br> <a href="#update">update</a><br> <a href="#url">url</a><br> <a href="#version">version</a><br> <a href="#view">view</a><br> <a href="#visual">visual</a><br> <a href="#vo">vo</a><br> <a href="#wcs">wcs</a><br> <a href="#web">web</a><br> <a href="#width">width</a><br> <a href="#xpa">xpa</a><br> <a href="#zmax">zmax</a><br> <a href="#zoom">zoom</a><br> <a href="#zscale">zscale</a><br> </tt> <p><b><a name="2mass"></a>2mass </b></p> <p>Support for 2MASS Digital Sky Survey.</p> <tt> Syntax: <br> -2mass []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp; &nbsp; [survey j|h|k] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -2mass<br> $ds9 -2mass m31 <br> $ds9 -2mass name m31 <br> $ds9 -2mass coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -2mass size 60 60 arcmin<br> $ds9 -2mass save yes<br> $ds9 -2mass frame current<br> $ds9 -2mass update frame<br> $ds9 -2mass survey j<br> $ds9 -2mass open<br> $ds9 -2mass close<br> </tt> <p><b><a name="3d"></a>3d </b></p> <p>Support for 3D frame.</p> <tt> Syntax: <br> </tt><tt>-3d []<br> &nbsp;&nbsp;&nbsp; [vp &lt;az&gt; &lt;el&gt;]<br> &nbsp;&nbsp;&nbsp; [az &lt;az&gt;]<br> &nbsp;&nbsp;&nbsp; [el &lt;el&gt;]<br> &nbsp;&nbsp;&nbsp; [scale &lt;scale&gt;]<br> &nbsp;&nbsp;&nbsp; [method mip|aip]<br> </tt><tt>&nbsp;&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp;&nbsp; [border color]<br> </tt><tt></tt><tt>&nbsp;&nbsp;&nbsp; [highlite yes|no]<br> &nbsp;&nbsp;&nbsp; [highlite color]<br> </tt><tt>&nbsp;&nbsp;&nbsp; [open|close]<br> </tt><tt>&nbsp; <br> Example:<br> $ds9 -3d # create new 3D frame<br> $ds9 -3d vp 45 30<br> $ds9 -3d az 45<br> $ds9 -3d el 30<br> $ds9 -3d scale 10<br> $ds9 -3d method mip<br> </tt><tt>$ds9 -3d border yes<br> $ds9 -3d border color red<br> </tt> <tt></tt><tt>$ds9 -3d highlite yes<br> $ds9 -3d highlite color red<br> </tt> <tt>$ds9 -3d open<br> $ds9 -3d close</tt><br> <p><b><a name="about"></a>about</b></p> <p>Get DS9 credits.</p> <tt> Syntax: <br> -about <br> &nbsp;<br> Example: <br> $ds9 -about<br> </tt> <p><b> <a name="align"></a>align</b></p> <p>Controls the World Coordinate System alignment for the current frame.</p> <tt> Syntax: <br> -align [yes|no]<br> &nbsp;<br> Example: <br> $ds9 -align yes <br> </tt> <p><b> <a name="analysis"></a>analysis</b></p> <p>Control external analysis tasks. Tasks are numbered as they are loaded, starting with 0. Can also be used to display a message and display text in the text dialog window. </p> <tt> Syntax: <br> -analysis [&lt;task number&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [task &lt;task number&gt;|&lt;task name&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear][load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [message ok|okcancel|yesno &lt;message&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [entry &lt;message&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [text]<br> &nbsp;<br> Example:<br> $ds9 -analysis 0 # invoke first analysis task<br> $ds9 -analysis task 0<br> </tt><tt>$ds9 -analysis task foobar<br> </tt><tt>$ds9 -analysis task "{foo bar}"<br> $ds9 -analysis my.ans<br> $ds9 -analysis load my.ans <br> $ds9 -analysis clear <br> $ds9 -analysis clear load my.ans<br> $ds9 -analysis message '{This is a message}'<br> $ds9 -analysis message okcancel '{This is a message}'<br> $ds9 -analysis text '{This is text}';<br> </tt> <p><b> <a name="array"></a>array</b></p> <p>Load raw data array into current frame.<br> </p> <tt> Syntax:<br> -array &lt;filename&gt;[[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],zdim=&lt;z&gt;,bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> $ds9 -array foo.arr[dim=512,bitpix=-32,endian=little]</tt><br> <tt>$cat foo.arr | ds9 -array -[dim=512,bitpix=-32,endian=little]</tt><br> <p><b> <a name="array"></a>array</b></p> <p>Load an array. </p> <tt> Syntax: <br> -array &lt;filename&gt;[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],zdim=&lt;z&gt;,bitpix=&lt;b&gt;,skip=&lt;s&gt;,arch=[little|big]]<br> &nbsp;<br> Example:<br> $ds9 -array bar.arr[xdim=512,ydim=512,zdim=1,bitpix=16] # load 512x512 short</tt><br> <tt><tt>$cat bar.arr | ds9 -array -[xdim=512,ydim=512,zdim=1,bitpix=16]<br> </tt>$ds9 -array bar.arr[dim=256,bitpix=-32,skip=4] # load 256x256 float with 4 byte head<br> $ds9 -array bar.arr[dim=512,bitpix=32,arch=little] # load 512x512 long, intel<br> </tt> <p><b> <a name="asinh"></a></b><b>asinh</b> </p> <p>Select ASINH scale function for the current frame.</p> <tt> Syntax:<br> -asinh <br> &nbsp;<br> Example: <br> $ds9 -asinh</tt><br> <p><b><a name="background"></a>bg<br> background</b></p> <p>Set image background color. </p> <tt> Syntax: <br> -bg &lt;color&gt;<br> &nbsp;<br> Example:<br> $ds9 -background red<br> $ds9 -bg red</tt><br> <p><b> <a name="backup"></a>backup</b></p> <p>Create a backup save set. </p> <tt> Syntax: <br> -backup &lt;filename&gt;<br> &nbsp;<br> Example:<br> $ds9 -backup ds9.bck</tt><br> <p><b> <a name="bin"></a>bin</b></p> <p>Controls binning factor, binning buffer size, and&nbsp; binning function for binning FITS bin tables. </p> <tt> Syntax: <br> -bin [about &lt;x&gt; &lt;y&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [about center]<br> &nbsp;&nbsp;&nbsp;&nbsp; [buffersize &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [cols &lt;x&gt; &lt;y&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [colsz &lt;x&gt; &lt;y&gt; &lt;z&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [factor &lt;value&gt; [&lt;value&gt;]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [depth &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [filter &lt;string&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [function average|sum] <br> &nbsp;&nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -bin about 4096 4096<br> $ds9 -bin about center<br> $ds9 -bin buffersize 512<br> $ds9 -bin cols detx dety<br> $ds9 -bin colsz detx dety time<br> $ds9 -bin factor 4<br> $ds9 -bin factor 4 2<br> $ds9 -bin depth 10<br> $ds9 -bin filter '{pha &gt; 5}'<br> $ds9 -bin filter ''<br> $ds9 -bin function sum<br> $ds9 -bin to fit<br> $ds9 -bin match<br> $ds9 -bin lock yes<br> $ds9 -bin open<br> $ds9 -bin close<br> </tt> <p><b> <a name="blink"></a>blink</b></p> <p>Blink mode parameters. Interval is in seconds.</p> <tt> Syntax: <br> -blink []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;]<br> &nbsp;<br> Example: <br> $ds9 -blink<br> $ds9 -blink yes<br> $ds9 -blink interval 1<br> </tt> <p><b> <a name="blue"></a>blue</b></p> <p>For RGB frames, sets the current color channel to blue.</p> <tt> Syntax: <br> -blue<br> &nbsp;<br> Example: <br> $ds9 -blue foo.fits<br> </tt> <p><b> <a name="catalog"></a>catalog<br> cat</b></p> <p>Support for catalogs.</p> <tt> Syntax: <br> </tt><tt>-catalog []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ned|simbad|denis|skybot]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ascss|cmc|gsc1|gsc2|gsc3|ac|nomad|ppmx|sao|sdss5|sdss6|</tt><tt>sdss7|sdss8|</tt><tt>tycho|ua2|ub1|ucac2]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [2mass|iras]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [csc|xmm|rosat]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [first|nvss]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [chandralog|cfhtlog|esolog|stlog|xmmlog]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [cds &lt;catalogname&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cds &lt;catalogid&gt;]<br> <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [import sb|tsv &lt;filename&gt;]<br> <br> </tt><tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [allcols]<br> </tt><tt>&nbsp;</tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [allrows]<br> &nbsp;</tt><tt>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [cancel]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [clear]<br> </tt><tt>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; [&lt;ref&gt;] [close]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [coordinate &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [crosshair]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [dec &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [edit yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [export sb|tsv &lt;filename&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter &lt;string&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [filter load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [header]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [hide]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [location &lt;code&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [match &lt;ref&gt; &lt;ref&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match error &lt;value&gt; degrees|arcmin|arcsec]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match function 1and2|1not2|2not1]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match return 1and2|1only|2only]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [match unique yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [maxrows &lt;number&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [name &lt;object&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [panto yes|no]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [plot &lt;xcol&gt; &lt;ycol&gt; &lt;xerrcol&gt; &lt;yerrcol&gt;]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [print]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psky &lt;skyframe&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [psystem &lt;coordsys&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [ra &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [retrieve]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp broadcast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [samp send &lt;application&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [save &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [server cds|sao|cadc|adac|iucaa|bejing|cambridge|ukirt]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [show]</tt><br> <tt>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [&lt;ref&gt;] [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]</tt><br> <tt> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sky &lt;skyframe&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [skyformat &lt;skyformat&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [sort &lt;col&gt; incr|decr]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] condition|shape|color|text|font|fontsize|fontweight|fontslant &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol [#] text|size|size2|units|angle &lt;value&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol shape {circle point}|{box point}|{diamond point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {cross point}|{x point}|{arrow point}|{boxcircle point}|<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; circle|ellipse|box|text]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol add| [#] remove]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [symbol save|load &lt;filename&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [system &lt;coordsys&gt;]</tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </tt><tt>[&lt;ref&gt;] [update]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [x &lt;col&gt;]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;ref&gt;] [y &lt;col&gt;]</tt><br> <tt><br> Example:<br> </tt><tt>$ds9 -catalog<br> $ds9 -catalog 2mass<br> $ds9 -catalog cds 2mass<br> $ds9 -catalog cds "I/252"<br> <br> </tt><tt>$ds9 -catalog load foo.xml<br> $ds9 -catalog import tsv foo.tsv<br> <br> </tt><tt>$ds9 -catalog allrows<br> $ds9 -catalog allcols<br> </tt><tt>$ds9 -catalog cancel<br> </tt><tt>$ds9 -catalog clear<br> </tt><tt>$ds9 -catalog close<br> </tt><tt>$ds9 -catalog coordinate 202.48 47.21 fk5<br> </tt><tt>$ds9 -catalog crosshair<br> </tt><tt>$ds9 -catalog dec DEC<br> </tt><tt>$ds9 -catalog edit yes<br> </tt><tt>$ds9 -catalog export tsv bar.tsv<br> </tt><tt>$ds9 -catalog filter </tt><tt>'\$Jmag&gt;15'</tt><tt><br> $ds9 -catalog filter load foo.flt<br> $ds9 -catalog header<br> </tt><tt>$ds9 -catalog hide<br> </tt><tt>$ds9 -catalog location 500</tt><br> <tt>$ds9 -catalog match error 2 arcsec<br> $ds9 -catalog match function 1and2<br> $ds9 -catalog match unique no<br> $ds9 -catalog match return 1only<br> $ds9 -catalog match 2mass csc<br> </tt><tt>$ds9 -catalog maxrows 2000<br> </tt><tt>$ds9 -catalog name m51<br> $ds9 -catalog panto no<br> </tt><tt>$ds9 -catalog plot </tt><tt>'\$Jmag' '\$Hmag' '\$e_Jmag' '\$e_Hmag'</tt><tt><br> </tt><tt>$ds9 -catalog print</tt><br> <tt>$ds9 -catalog psky fk5</tt><br> <tt>$ds9 -catalog psystem wcs</tt><br> <tt>$ds9 -catalog ra RA</tt><br> <tt>$ds9 -catalog retrieve<br> </tt><tt> $ds9 -catalog samp broadcast<br> $ds9 -catalog samp send aladin<br> $ds9 -catalog save foo.xml<br> </tt><tt>$ds9 -catalog server sao<br> </tt><tt>$ds9 -catalog show</tt><br> <tt> $ds9 -catalog size 1 1 degrees</tt><br> <tt>$ds9 -catalog symbol condition '\$Jmag&gt;15'<br> $ds9 -catalog symbol 2 shape "boxcircle point"<br> $ds9 -catalog symbol color red<br> $ds9 -catalog symbol font times<br> </tt><tt>$ds9 -catalog symbol fontsize 14<br> </tt><tt>$ds9 -catalog symbol fontweight bold<br> </tt><tt>$ds9 -catalog symbol fontslant italic<br> </tt><tt>$ds9 -catalog symbol add<br> $ds9 -catalog symbol 2 remove<br> $ds9 -catalog symbol load foo.sym<br> $ds9 -catalog symbol save bar.sym</tt><tt><br> $ds9 -catalog sky fk5<br> $ds9 -catalog skyformat degrees<br> </tt><tt>$ds9 -catalog sort "Jmag" incr<br> </tt><tt>$ds9 -catalog system wcs</tt><tt><br> </tt><tt>$ds9 -catalog update<br> </tt><tt>$ds9 -catalog x RA<br> $ds9 -catalog y DEC</tt><br> <p><b><a name="cd"></a>cd</b></p> <p>Sets the current working directory. </p> <tt> Syntax: <br> cd [&lt;directory&gt;] <br> &nbsp;<br> Example: <br> $ds9 -cd /home/mrbill<br> </tt> <p><b> <a name="cmap"></a>cmap</b></p> <p>Controls the colormap for the current frame. The colormap name is not case sensitive. A valid contrast value is&nbsp; from 0 to 10 and bias value from 0 to 1. </p> <tt> Syntax: <br> -cmap [&lt;colormap&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [file]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [invert yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [value &lt;contrast&gt; &lt;bias&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tag [load|save] &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tag delete]</tt><br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -cmap Heat <br> $ds9 -cmap load foo.sao <br> $ds9 -cmap save bar.sao<br> $ds9 -cmap invert yes <br> $ds9 -cmap value 5 .5<br> $ds9 -cmap tag load foo.tag<br> $ds9 -cmap tag save foo.tag<br> $ds9 -cmap tag delete<br> </tt><tt>$ds9 -cmap match<br> $ds9 -cmap lock yes</tt><br> <tt> $ds9 -cmap open<br> $ds9 -cmap close<br> </tt> <p><b><a name="colorbar"></a>colorbar</b></p> <p>Controls colorbar parameters.</p> <tt> Syntax: <br> -colorbar []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [horizontal|vertical]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [orientation horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [space value|distance]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [ticks]<br> &nbsp;<br> Example: <br> $ds9 -colorbar yes<br> $ds9 -colorbar vertical<br> $ds9 -colorbar orientation vertical<br> $ds9 -colorbar numerics yes<br> $ds9 -colorbar space value<br> $ds9 -colorbar font times<br> $ds9 -colorbar fontsize 14<br> $ds9 -colorbar fontweight bold<br> $ds9 -colorbar fontslant italic<br> $ds9 -colorbar size 20<br> $ds9 -colorbar ticks 11<br> </tt> <p><b> <a name="console"></a>console</b></p> <p>Display tcl console window.</p> <tt> Syntax: <br> -console<br> &nbsp;<br> Example:<br> $ds9 -console<br> </tt> <p><b> <a name="contour"></a>contour<br> </b></p> <p>Controls contours in the current frame. </p> <tt> Syntax: <br> -contour []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [generate]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [convert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [loadlevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [savelevels &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [paste &lt;coordsys&gt; &lt;color&gt; &lt;width&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; [dash yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [smooth &lt;smooth&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [method block|smooth]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [nlevels &lt;number of levels&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale linear|log|pow|squared|sqrt|asinh|sinh|histequ]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [log exp &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [limits &lt;min&gt; &lt;max&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [levels &lt;value value value...&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -contour<br> $ds9 -contour yes<br> $ds9 -contour generate<br> $ds9 -contour clear<br> $ds9 -contour load ds9.con wcs fk5 yellow 2 no<br> $ds9 -contour load ds9.con wcs fk5 red 2 yes<br> $ds9 -contour save ds9.con wcs fk5<br> $ds9 -contour convert<br> $ds9 -contour loadlevels ds9.lev<br> $ds9 -contour savelevels ds9.lev<br> $ds9 -contour copy<br> $ds9 -contour paste wcs red 2 no<br> $ds9 -contour color yellow<br> $ds9 -contour width 2<br> $ds9 -contour dash yes<br> $ds9 -contour smooth 5<br> $ds9 -contour method smooth<br> $ds9 -contour nlevels 10<br> $ds9 -contour scale sqrt<br> $ds9 -contour log exp 1000<br> $ds9 -contour mode zscale<br> $ds9 -contour limits 1 100<br> $ds9 -contour levels "1 10 100 1000"<br> $ds9 -contour open<br> $ds9 -contour close<br> </tt> <p><b><a name="crop"></a>crop</b> </p> <p>Set current image display area. </p> <tt> Syntax: <br> -crop [&lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt; [&lt;coordsys&gt;][&lt;skyframe&gt;][&lt;skyformat&gt;][degrees|arcmin|arcsec]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]</tt><tt> <br> &nbsp;<br> Example: <br> $ds9 foo.fits -crop 40 30 10 20 # set crop in physical coords<br> $ds9 foo.fits -crop +104:51:06.915 +68:33:40.761&nbsp; 28.144405 22.000204 wcs galactic arcsec<br> $ds9 foo.fits -crop match wcs<br> $ds9 foo.fits -crop lock wcs<br> </tt> <p><b> <a name="crosshair"></a>crosshair</b></p> <p>Controls the current position of the crosshair in the current frame. DS9 is placed in crosshair mode when the crosshair is set. </p> <tt> Syntax: <br> -crosshair [&lt;x&gt; &lt;h&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;]]<br> &nbsp;</tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;<br> Example: <br> $ds9 -crosshair 100 100 physical # set crosshair in physical <br> $ds9 -crosshair 345 58.8 wcs fk5 # set crosshair in wcs coords <br> $ds9 -crosshair 23:01:00 +58:52:51 wcs fk5<br> $ds9 -crosshair match<br> $ds9 -crosshair lock wcs<br> </tt> <p><b><a name="cube"></a>cube<br> </b></p> <p>Controls FITS cube. </p> <tt> Syntax: <br> -cube [play|stop|next|prev|first|last]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;slice&gt; [&lt;coordsys&gt;][&lt;axis&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;numeric&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp; [axis &lt;axis&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -cube play<br> $ds9 -cube last<br> $ds9 -cube 3<br> $ds9 -cube 4.5 wcs 3<br> $ds9 -cube interval 2<br> $ds9 -cube axis 3<br> $ds9 -cube match<br> $ds9 -cube lock yes<br> $ds9 -cube open<br> $ds9 -cube close</tt><br> <p><b> <a name="cursor"></a>cursor</b></p> <p>Move mouse pointer or crosshair in image pixels in the current frame. Note, this will move selected Regions also. </p> <tt> Syntax: <br> -cursor [&lt;x&gt; &lt;h&gt;] <br> &nbsp;<br> Example: <br> $ds9 -cursor 10 10</tt><tt><br> </tt> <p><b><a name="dsssao"></a>dsssao<br> dss<br> </b></p> <p>Support for Digital Sky Survey at SAO.</p> <tt> Syntax: <br> -dsssao []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -dsssao <br> $ds9 -dsssao m31 <br> $ds9 -dsssao name m31 <br> $ds9 -dsssao coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -dsssao size 60 60 arcmin<br> $ds9 -dsssao save yes<br> $ds9 -dsssao frame current<br> $ds9 -dsssao update frame<br> $ds9 -dsssao open<br> $ds9 -dsssao close<br> </tt> <p><b><a name="dsseso"></a>dsseso </b></p> <p>Support for Digital Sky Survey at ESO.</p> <tt> Syntax:<br> -dsseso []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [survey DSS1|DSS2-red|DSS2-blue|DSS2-infrared]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -dsseso <br> $ds9 -dsseso m31 <br> $ds9 -dsseso name m31 <br> $ds9 -dsseso coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -dsseso size 60 60 arcmin<br> $ds9 -dsseso save yes<br> $ds9 -dsseso frame current<br> $ds9 -dsseso update frame <br> $ds9 -dsseso survey DSS2-red<br> $ds9 -dsseso open<br> </tt><tt>$ds9 -dsseso close</tt><br> <p><b><a name="dssstsci"></a>dssstsci </b></p> <p>Support for Digital Sky Survey at STSCI.</p> <tt> Syntax:<br> -dssstsci []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss2ukstu_red|poss2ukstu_ir|poss2ukstu_blue] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey poss1_blue|poss1_red]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [survey all|quickv|phase2_gsc2|phase2_gsc1]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -dssstsci <br> $ds9 -dssstsci m31 <br> $ds9 -dssstsci name m31 <br> $ds9 -dssstsci coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -dssstsci size 60 60 arcmin<br> $ds9 -dssstsci save yes<br> $ds9 -dssstsci frame current<br> $ds9 -dssstsci update frame <br> $ds9 -dssstsci survey all<br> $ds9 -dssstsci open<br> $ds9 -dssstsci close<br> </tt> <p><b> <a name="exit"></a>exit<br> quit</b></p> <p>Quits DS9. </p> <tt> Syntax: <br> -exit <br> -quit <br> &nbsp;<br> Example: <br> $ds9 -exit<br> </tt> <p><b> <a name="export"></a>export<br> </b></p> <p>Export loaded image data of current frame in specified image format, at native resolution, using current colormap and contrast/bias settings. NOTE: not scaling, rotation, or translation is applied. If no format specified, the file name extension is used to determine the output format. Optional parameters: jpeg quality (1-100) and tiff compression method.<br> </p> <tt> Syntax: <br> -export [nrrd|gif|tiff|jpeg|png] &lt;filename&gt;</tt><tt><br> </tt><tt>-export &lt;filename&gt;</tt><tt>.jpeg [1-100]<br> </tt><tt>-export &lt;filename&gt;</tt><tt>.tiff [none|jpeg|packbits|deflate]</tt><br> <tt> &nbsp;<br> Example:<br> $ds9 -export foo.tiff<br> $ds9 -export tiff foo.tiff <br> $ds9 -export foo.jpeg 75<br> $ds9 -export png foo.png</tt><br> <p><b><a name="fifo"></a>fifo</b></p> <p>Set the name of the IRAF input and output fifos. The default is /dev/imt1. These fifos are used by IRAF to communicate with DS9. </p> <tt> Syntax: <br> -fifo name <br> &nbsp;<br> Example: <br> $ds9 -fifo /dev/imt1 </tt> <p><b> <a name="fifo_only"></a>fifo_only</b></p> <p>Only use IRAF input and output fifos. Same as -port 0 -unix none. </p> <tt> Syntax: <br> -fifo_only <br> &nbsp;<br> Example: <br> $ds9 -fifo_only<br> </tt><tt></tt> <p><b> <a name="first"></a>first</b></p> <p>Support for VLA First Sky Survey.</p> <tt> Syntax: <br> -first []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -first<br> $ds9 -first m31 <br> $ds9 -first name m31 <br> $ds9 -first coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -first size 60 60 arcmin<br> $ds9 -first save yes<br> $ds9 -first frame current<br> $ds9 -first update frame<br> $ds9 -first open<br> $ds9 -first close<br> </tt> <p><b> <a name="fits"></a>fits</b></p> <p>Load a FITS image into the current frame.<br> </p> <tt> Syntax: <br> -fits </tt><tt><tt>&lt;filename&gt;</tt></tt><tt><br> &nbsp;<br> Example: <br> </tt><tt>$ds9 -fits foo.fits<br> $ds9 -fits bar.fits[bin=detx,dety]<br> $cat foo.fits | ds9 -fits -<br> $cat bar.fits | ds9 -fits -[bin=detx,dety]</tt><tt><br> </tt> <p><b><a name="frame"></a>frame</b></p> <p>Controls frame functions. Frames may be created, deleted, reset, and centered. While return the current frame number. If you goto a frame that does not exists, it will be created. If the frame is hidden, it will be shown. The 'frameno' option is available for backward compatibility. </p> <tt> Syntax: <br> -frame [center [#|all]]<br> &nbsp; &nbsp; &nbsp;&nbsp; [clear [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; [new [rgb]]<br> &nbsp; &nbsp; &nbsp; &nbsp;[delete [#|all]] <br> &nbsp; &nbsp; &nbsp; &nbsp;[reset [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[refresh [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;[hide [#|all]]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[show [#|all]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move first]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move forward]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move last]<br> &nbsp; &nbsp; &nbsp; &nbsp;[first]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[prev]<br> &nbsp; &nbsp; &nbsp; &nbsp;[next]<br> &nbsp; &nbsp; &nbsp; &nbsp;[last]<br> &nbsp; &nbsp; &nbsp; &nbsp;[frameno #]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;[#]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock &lt;coordsys&gt;|none]<br> &nbsp;<br> Example: <br> $ds9 -frame center # center current frame<br> $ds9 -frame center 1 # center 'Frame1' <br> $ds9 -frame center all # center all frames <br> $ds9 -frame clear # clear current frame<br> $ds9 -frame new # create new frame <br> $ds9 -frame new rgb # create new rgb frame<br> $ds9 -frame delete # delete current frame <br> $ds9 -frame reset # reset current frame <br> $ds9 -frame refresh # refresh current frame <br> $ds9 -frame hide # hide current frame <br> $ds9 -frame show 1 # show frame 'Frame1'<br> $ds9 -frame move first # move frame to first in order<br> $ds9 -frame move back # move frame back in order<br> $ds9 -frame move forward # move frame forward in order<br> $ds9 -frame move last # move frame to last in order<br> $ds9 -frame first # goto first frame <br> $ds9 -frame prev # goto prev frame <br> $ds9 -frame next # goto next frame<br> $ds9 -frame last # goto last frame<br> $ds9 -frame frameno 4 # goto frame 'Frame4', create if needed<br> $ds9 -frame 3 # goto frame 'Frame3', create if needed<br> $ds9 -frame lock wcs</tt><br> <p><b> <a name="gif"></a>gif</b></p> <p>Import gif file. </p> <tt> Syntax: <br> -gif &lt;filename&gt;<br> &nbsp;<br> Example: <br> $ds9 -gif foo.gif<br> $cat foo.gif | ds9 -gif -<br> </tt> <p><b> <a name="geometry"></a>geometry</b></p> <p>Define the initial window geometry. This includes all of the ds9 window, not just the image space. see X(1). </p> <tt> Syntax: <br> -geometry value <br> &nbsp;<br> Example: <br> $ds9 -geometry 640x480 </tt> <p><b> <a name="green"></a>green</b></p> <p>For RGB frames, sets the current color channel to green.</p> <tt> Syntax: <br> -green<br> &nbsp;<br> Example: <br> $ds9 -green foo.fits </tt> <p><b> <a name="grid"></a>grid</b></p> <p>Controls coordinate grid. For grid numeric format syntax,&nbsp; click <a href="grid.html#Format">here</a>.</p> <tt> Syntax: <br> -grid []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [type analysis|publication] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sky &lt;skyframe&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat &lt;skyformat&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes type interior|exterior]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [axes origin lll|llu|lul|luu|ull|ulu|uul|uuu]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp; [format1 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format2 &lt;format&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [tickmarks style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [border style 0|1]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics type interior|exterior]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [numerics vertical yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title text &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title def yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title gap &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title fontweight normal|bold]<br> &nbsp; &nbsp;&nbsp;&nbsp; [title fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [title color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text1 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def1 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap1 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels text2 &lt;text&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels def2 yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels gap2 &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels font times|helvetica|courier]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontsize &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontweight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels fontslant roman|italic]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [labels color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [reset]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [load &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -grid <br> $ds9 -grid yes<br> $ds9 -grid type analysis <br> $ds9 -grid system wcs <br> $ds9 -grid sky fk5 <br> $ds9 -grid skyformat degrees<br> $ds9 -grid grid yes<br> $ds9 -grid grid color red<br> $ds9 -grid grid width 2<br> $ds9 -grid grid style 1<br> $ds9 -grid grid gap1 10<br> $ds9 -grid grid gap2 10<br> $ds9 -grid axes yes<br> $ds9 -grid axes color red<br> $ds9 -grid axes width 2<br> $ds9 -grid axes style 1<br> $ds9 -grid axes type exterior<br> $ds9 -grid axes origin lll<br> $ds9 -grid format1 d.2<br> $ds9 -grid format2 d.2<br> $ds9 -grid tickmarks yes<br> $ds9 -grid tickmarks color red<br> $ds9 -grid tickmarks width 2<br> $ds9 -grid tickmarks style 1<br> $ds9 -grid border yes<br> $ds9 -grid border color red<br> $ds9 -grid border width 2<br> $ds9 -grid border style 1<br> $ds9 -grid numerics yes<br> $ds9 -grid numerics font courier<br> $ds9 -grid numerics fontsize 12<br> $ds9 -grid numerics fontweight bold<br> $ds9 -grid numerics fontslant italic<br> $ds9 -grid numerics color red<br> $ds9 -grid numerics gap1 10<br> $ds9 -grid numerics gap2 10<br> $ds9 -grid numerics type exterior<br> $ds9 -grid numerics vertical yes<br> $ds9 -grid title yes<br> $ds9 -grid title text {Hello World}<br> $ds9 -grid title def yes<br> $ds9 -grid title gap 10<br> $ds9 -grid title font courier<br> $ds9 -grid title fontsize 12<br> $ds9 -grid title fontweight bold<br> $ds9 -grid title fontslant italic<br> $ds9 -grid title color red<br> $ds9 -grid labels yes<br> $ds9 -grid labels text1 {Hello World}<br> $ds9 -grid labels def1 yes<br> $ds9 -grid labels gap1 10<br> $ds9 -grid labels text2 {Hello World}<br> $ds9 -grid labels def2 yes<br> $ds9 -grid labels gap2 10<br> $ds9 -grid labels font courier<br> $ds9 -grid labels fontsize 12<br> $ds9 -grid labels fontweight bold<br> $ds9 -grid labels fontslant italic<br> $ds9 -grid labels color red<br> $ds9 -grid reset<br> $ds9 -grid load foo.grd <br> $ds9 -grid save foo.grd <br> $ds9 -grid open<br> $ds9 -grid close<br> </tt> <p><b> <a name="header"></a>header</b></p> <p>Display current fits header dialog. Optional extension number maybe specified.</p> <tt> Syntax: <br> -header [&lt;ext&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [close [&lt;ext&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save [&lt;ext&gt;] &lt;filename&gt;]<br> &nbsp;<br> Example:<br> $ds9 -header <br> $ds9 -header 2<br> $ds9 -header close<br> $ds9 -header save 1 foo.txt<br> </tt> <p><b> <a name="height"></a>height</b></p> <p>Set the height of the image display window. Use the <a href="command.html#geometry">geometry</a> command to set the overall width and height of the ds9 window.</p> <tt> Syntax: <br> -height [&lt;value&gt;]<br> &nbsp;<br> Example: <br> $ds9 -height 512<br> </tt> <p><b> <a name="help"></a>help</b></p> <p>Display help information. To maintain backward compatability, -help will display a brief help message and exit. --help will display all command line options within the built-in help facility.</p> <tt> Syntax: <br> -help # Display brief help message and exit.<br> --help # Display command line options within help facility.<br> -? # Display command line options within help facility.<br> &nbsp;<br> Example: <br> $ds9 -help # Display brief help message and exit.<br> $ds9 --help # Display command line options within help facility<br> $ds9 -? # Display command line options within help facility.<br> </tt> <p><b> <a name="histequ"></a>histequ</b></p> <p>Select histogram equalization scale function for the current frame. </p> <tt> Syntax: <br> -histequ<br> &nbsp;<br> Example: <br> $ds9 -histequ<br> </tt> <p><b> <a name="iconify"></a>iconify</b></p> <p>Toggles iconification. </p> <tt> Syntax: <br> -iconify []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;<br> Example: <br> $ds9 -iconify<br> $ds9 -iconify yes</tt><br> <p><b> <a name="invert"></a>invert</b></p> <p>Invert Colormap. </p> <tt> Syntax: <br> -invert <br> &nbsp;<br> Example: <br> $ds9 -invert<br> </tt> <p><b><a name="iis"></a>iis</b></p> <p>Set IIS Filename. Optional mosaic number maybe supplied.</p> <tt> Syntax: <br> -iis [filename &lt;filename&gt; [#]]<br> &nbsp;<br> Example: <br> $ds9 -iis filename foo.fits<br> $ds9 -iis filename bar.fits 4</tt><br> <p><b> <a name="jpeg"></a>jpeg</b></p> <p>Load JPEG image into current frame.</p> <tt> Syntax:<br> -jpeg &lt;filename&gt;<br> &nbsp;<br> Example: <br> </tt><tt>$ds9 -jpeg foo.jpeg</tt><br> <tt>$cat foo.jpeg | ds9 -jpeg -</tt><br> <p><b> <a name="language"></a>language</b></p> <p>Select current language. </p> <tt> Syntax: <br> -language [locale|da|de|es|en|fr|ja|pt]<br> &nbsp;<br> Example: <br> $ds9 -language fr<br> </tt> <p><b> <a name="linear"></a>linear</b></p> <p>Select linear scale function for the current frame. </p> <tt> Syntax: <br> -linear <br> &nbsp;<br> Example: <br> $ds9 -linear </tt> <p><b> <a name="lock"></a>lock</b></p> <p>Lock all other frames to the current frame. </p> <tt> Syntax: <br> </tt><tt>-lock</tt><tt> </tt><tt>[frame &lt;coordsys&gt;|none]<br> &nbsp;&nbsp; &nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;|none] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp; [crop &lt;coordsys&gt;|none]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp; [slice [yes|no]]</tt><br> <tt> &nbsp;&nbsp;&nbsp; &nbsp; [bin [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [scale [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp; [colorbar [yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [smooth [yes|no]]<br> <br> </tt><tt> </tt><tt>Example: </tt><tt><br> $ds9 -lock frame wcs</tt><tt><br> </tt><tt>$ds9 -lock crosshair wcs</tt><tt><br> </tt><tt>$ds9 -lock crop wcs</tt><br> <tt>$ds9 -lock slice yes</tt><br> <tt> $ds9 -lock bin yes<br> </tt><tt>$ds9 -lock scale yes<br> </tt><tt>$ds9 -lock colorbar yes</tt><tt><br> $ds9 -lock smooth yes<br> </tt> <p><b> <a name="log"></a>log</b></p> <p>Select log scale function for the current frame. <br> </p> <tt> Syntax: <br> -log <br> &nbsp;<br> Example: <br> $ds9 -log </tt> <p><b> <a name="lower"></a>lower</b></p> <p>Lower in the window stacking order. </p> <tt> Syntax: <br> -lower <br> &nbsp;<br> Example: <br> $ds9 -lower<br> </tt> <p><b> <a name="magnifier"></a>magnifier</b></p> <p>Controls the magnifier settings. </p> <tt> Syntax: <br> magnifier [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [zoom &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [cursor yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [region yes|no]<br> &nbsp;<br> Example: <br> $ds9 -magnifier color yellow<br> $ds9 -magnifier zoom 2<br> $ds9 -magnifier cursor no<br> $ds9 -magnifier region no<br> </tt> <p><b> <a name="mask"></a>mask<br> nomask<br> </b></p> <p>Controls mask parameters. </p> <tt> Syntax: <br> -mask [color &lt;color&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mark 1|0]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [transparency &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> -nomask<br> &nbsp;<br> Example: <br> $ds9 -mask color red<br> $ds9 -mask mark 0<br> $ds9 -mask transparency 50<br> $ds9 -mask clear<br> $ds9 -mask open<br> $ds9 -mask close<br> $ds9 -nomask<br> </tt> <p><b> <a name="match"></a>match</b></p> <p>Match all other frames to the current frame. </p> <tt> Syntax: <br> </tt><tt>-match </tt><tt>[frame &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </tt><tt>[crosshair &lt;coordsys&gt;] </tt><tt><br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crop &lt;coordsys&gt;]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [slice]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [bin]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [smooth]</tt><tt><br> &nbsp;<br> Example: <br> </tt><tt>$ds9 -match frame wcs <br> </tt><tt>$ds9 -match crosshair wcs<br> </tt><tt>$ds9 -match crop wcs</tt><br> <tt> $ds9 -match slice</tt><br> <tt> $ds9 -match bin<br> $ds9 -match scale<br> $ds9 -match colorbar<br> $ds9 -match smooth</tt><br> <p><b> <a name="mecube"></a>mecube</b></p> <p>Load FITS multiple extension file as data cube.<br> </p> <tt> Syntax:<br> mecube &lt;filename&gt;<br> &nbsp;<br> Example: <br> $ds9 -mecube foo.fits</tt><tt><tt><br> </tt>$cat foo.fits | ds9 -mecube -</tt><br> <p><b> <a name="minmax"></a>minmax</b></p> <p>This is how DS9 determines&nbsp; the min and max data values from the data. <tt>SCAN</tt> will scan all data. <tt>SAMPLE</tt> will sample the data every n samples. <tt>DATAMIN</tt> and <tt>IRAFMIN</tt> will use the values of the keywords if present. In general, it is recommended to use <tt>SCAN</tt> unless your computer is slow or your data files are very large. Select the increment&nbsp; interval for determining the min and max data values during sampling. The larger the interval, the quicker the process. </p> <tt> Syntax: <br> -minmax [auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode auto|scan|sample|datamin|irafmin] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [interval &lt;value&gt;] <br> &nbsp;<br> Example: <br> $ds9 -minmax scan <br> $ds9 -minmax mode scan<br> $ds9 -minmax interval 10 </tt> <p><b> <a name="mode"></a>mode</b></p> <p>Select the current mode. </p> <tt> Syntax: <br> -mode [none|pointer|crosshair|colorbar|pan|zoom|rotate|catalog|examine] <br> &nbsp;<br> Example: <br> $ds9 -mode crosshair</tt><br> <p><b> <a name="mosaic"></a>mosaic</b></p> <p>Load FITS mosaic segment into current frame.</p> <tt> Syntax:<br> -mosaic [wcs|wcsa...wcsz|iraf] &lt;filename&gt;<br> &nbsp;<br> Example: </tt><tt><br> $ds9 -mosaic foo.fits</tt><br> <tt><tt>$ds9 -mosaic wcs foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>$cat foo.fits | ds9 -mosaic -</tt> <br> <tt><tt>$cat foo.fits | ds9 -mosaic wcs -</tt></tt><tt><br> </tt> <p><b> <a name="mosaicimage"></a>mosaicimage</b></p> <p>Load FITS mosaic image into current frame.</p> <tt> Syntax:<br> -mosaicimage [wcs|wcsa...wcsz|iraf|wfpc2] &lt;filename&gt;<br> &nbsp;<br> Example: </tt><tt><br> $ds9 -mosaicimage foo.fits</tt><br> <tt><tt>$ds9 -mosaicimage wcs foo.fits</tt></tt><tt><tt><tt><br> </tt></tt>$cat foo.fits | ds9 -mosaicimage</tt><br> <tt><tt>$cat foo.fits | ds9 -mosaiimage wcs</tt></tt><tt></tt><tt><br> </tt> <p><b><a name="movie"></a>movie<br> savempeg<br> </b></p> <p>Create mpeg1 movie from snap shots of the DS9 window. A <tt>slice</tt> movie cycles though all slices of a cube. A <tt>frame</tt> movie cycles through all active frames. A <tt>3d</tt> movie cycles through specified viewing angles. The default is <tt>frame</tt>. Optional parameters for <tt>3d</tt>: number of frames, azimuth from/to, elevation from/to, slice from/to, oscillate/repeat times.<br> </p> <tt> Syntax:<br> -movie [slice|frame|3d] &lt;filename&gt;<br> -movie 3d &lt;filename&gt; [number|azfrom|azto|elfrom|elto|slfrom|slto|oscillate|repeat &lt;#&gt;]<br> &nbsp;<br> Example:<br> $ds9 -movie slice ds9.mpg<br> $ds9 -movie 3d ds9.mpg number 10 azfrom -60 azto 60 oscillate 1</tt><br> <p><b> <a name="msg"></a>msg</b></p> <p>Specify a directory of translation tables to be loaded.</p> <tt> Syntax: <br> -msg &lt;directory&gt;<br> &nbsp;<br> Example: <br> $ds9 -msg $HOME/msgs</tt><br> <p><b> <a name="multiframe"></a>multiframe</b></p> <p>Load FITS multiple extension file as multiple images.<br> </p> <tt> Syntax:<br> multiframe &lt;filename&gt;<br> &nbsp;<br> Example: <br> $ds9 -multiframe foo.fits</tt><tt><tt><br> </tt>$cat foo.fits | ds9 -multiframe -</tt><tt><br> </tt> <p><b><a name="nameserver"></a>nameserver</b></p> <p>Support Name Server functions. Coordinates are in fk5. </p> <tt> Syntax: <br> -nameserver [&lt;object&gt;]<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [name &lt;object&gt;]<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [server ned-sao|ned-eso|simbad-sao|simbad-eso] <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [pan]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -nameserver m31<br> $ds9 -nameserver name m31 <br> $ds9 -nameserver server ned-sao <br> $ds9 -nameserver skyformat sexagesimal<br> $ds9 -nameserver pan<br> $ds9 -nameserver crosshair<br> $ds9 -nameserver open<br> $ds9 -nameserver close<br> </tt> <p><b> <a name="nan"></a>nan</b></p> <p>Set image not-a-number color. </p> <tt> Syntax: <br> -nan &lt;color&gt;<br> &nbsp;<br> Example:<br> $ds9 -nan red</tt><br> <p><b> <a name="nrrd"></a>nrrd</b></p> <p>Load an NRRD (Nearly Raw Raster Data) file.<br> </p> <tt> Syntax: <br> -nrrd &lt;filename&gt;<br> &nbsp;<br> Example:<br> </tt><tt><tt>$ds9 -nrrd foo.nrrd</tt></tt><br> <tt>$cat foo.nrrd | xpaset ds9 -nrrd</tt> - <tt><br> </tt> <p><b> <a name="nvss"></a>nvss</b></p> <p>Support for NRAO VLA Sky Survey.</p> <tt> Syntax: <br> -nvss []<br> &nbsp;&nbsp;&nbsp; &nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -nvss<br> $ds9 -nvss m31 <br> $ds9 -nvss name m31 <br> $ds9 -nvss coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -nvss size 60 60 arcmin<br> $ds9 -nvss save yes<br> $ds9 -nvss frame current<br> $ds9 -nvss update frame<br> $ds9 -nvss open<br> $ds9 -nvess close<br> </tt> <p><b><a name="orient"></a>orient</b></p> <p>Controls the orientation of the current frame. </p> <tt> Syntax: <br> -orient [none|x|y|xy] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -orient xy<br> $ds9 -orient open<br> $ds9 -orient close<br> </tt> <p><b> <a name="pagesetup"></a>pagesetup</b></p> <p>Controls Page Setup options.<br> </p> <tt> Syntax: <br> -pagesetup [orient portrait|landscape] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scale &lt;numberic&gt;]</tt><br> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size letter|legal|tabloid|poster|a4]</tt><br> <tt> &nbsp;<br> Example: <br> $ds9 -pagesetup orient portrait <br> $ds9 -pagesetup scale 50<br> $ds9 -pagesetup size poster</tt><tt></tt><br> <p><b> <a name="pan"></a>pan</b></p> <p>Controls the current image cursor location for the current frame. </p> <tt> Syntax: <br> -pan [&lt;x&gt; &lt;h&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [to &lt;x&gt; &lt;h&gt; &lt;coordsys&gt; [&lt;skyframe&gt;][&lt;skyformat&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -pan 200 200 image <br> $ds9 -pan to 400 400 physical <br> $ds9 -pan to 13:29:55 47:11:50 wcs fk5<br> $ds9 -pan open<br> $ds9 -pan close</tt><br> <p><b><a name="pixeltable"></a>pixeltable</b></p> <p>Display/Hide the pixel table. </p> <tt> Syntax: <br> -pixeltable []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|open]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [no|close]<br> &nbsp;<br> Example: <br> $ds9 -pixeltable<br> $ds9 -pixeltable yes<br> $ds9 -pixeltable open<br> $ds9 -pixeltable close<br> </tt> <p><b> <a name="plot"></a>plot</b></p> <p>Display and configure data plots. All plot commands take an optional second command, the plot name. Use xpaget plot to retrieve all plot names. If no plot name is specified, the last plot created is assumed. Plot data is assumed to be a pair of coordinates, with optional error values. The follow are valid data descriptions:</p> <blockquote>xy &nbsp;&nbsp; &nbsp; &nbsp; x and y coordinates<br> xyex&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with x errors<br> xyey&nbsp;&nbsp;&nbsp; &nbsp; x,y coordinates with y errors<br> xyexey&nbsp;&nbsp;&nbsp; x,y coordinates with both x and y errors<br> </blockquote> <p>To create a new plot, use the plot new command. If the second arg is stdin, the title, x axis title, y axis title, and dimension are assumed to be on the first line of the data. </p> <tt> Syntax: <br> # create new empty plot window<br> -plot [bar|scatter]<br> &nbsp;&nbsp; &nbsp;&nbsp; [new [name &lt;plotname&gt;] [line|bar|scatter]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [new [name &lt;plotname&gt;] </tt><tt>[line|bar|scatter] </tt><tt>&lt;title&gt; &lt;xaxis label&gt; &lt;yaxis label&gt; </tt><tt>xy|xyex|xyey|xyexey</tt><tt>]<br> <br> # edit existing plot<br> -plot [&lt;plotname&gt;] [close]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [clear]<br> &nbsp; &nbsp; &nbsp; [&lt;plotname&gt;] [load &lt;filename&gt; xy|xyex|xyey|xyexey]<br> &nbsp; &nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [save &lt;filename&gt;]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [loadconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp; [&lt;plotname&gt;] [saveconfig &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp; [&lt;plotname&gt;] [print]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [print destination printer|file] <br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [print command &lt;command&gt;]<br> &nbsp; &nbsp; &nbsp; [&lt;plotname&gt;] [print filename &lt;filename&gt;] <br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [print color rgb|gray]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup orient portrait|landscape]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [pagesetup size letter|legal|tabloid|poster|a4]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph type line|bar]<br> &nbsp; &nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph grid x|y yes|no]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [graph log x|y yes|no]<br> </tt><tt>&nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [graph flip x|y yes|no]</tt><br> <tt> &nbsp; &nbsp; &nbsp; [&lt;plotname&gt;] [graph range x|y auto yes|no]<br> &nbsp; &nbsp; &nbsp; [&lt;plotname&gt;] [graph range x|y min &lt;value&gt;]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [graph range x|y max &lt;value&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [graph format x|y &lt;value&gt;]</tt><br> <tt> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [graph labels title|xaxis|yaxis &lt;value&gt;]<br> &nbsp; &nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [font numbers|labels|title font times|helvetica|courier]<br> &nbsp; &nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [font numbers|labels|title size &lt;value&gt;]<br> &nbsp; &nbsp; &nbsp; [&lt;plotname&gt;] [font numbers|labels|title weight normal|bold]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [font nubmers|labels|title slant roman|italic]<br> <br> # edit current dataset<br> -plot [&lt;plotname&gt;] [dataset #]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [view discrete|linear|step|quadratic|error yes|no]<br> &nbsp; &nbsp;&nbsp;&nbsp; [&lt;plotname&gt;] [color discrete|linear|step|quadratic|error|bar &lt;color&gt;]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [line discrete circle|diamond|plus|cross]<br> &nbsp;&nbsp;&nbsp; &nbsp; [&lt;plotname&gt;] [line linear|step|quadratic|error width &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp; [&lt;plotname&gt;] [line linear|step|quadratic dash yes|no]<br> &nbsp;&nbsp; &nbsp;&nbsp; [&lt;plotname&gt;] [line error style 1|2]<br> &nbsp;<br> Example: <br> # create new empty plot window<br> $ds9 -plot<br> $ds9 -plot scatter<br> $ds9 -plot new<br> $ds9 -plot new bar<br> $ds9 -plot new name foo<br> $ds9 -plot new name foo scatter<br> <br> # edit existing plot<br> $ds9 -plot close # close last plot<br> $ds9 -plot foo close # close plot foo<br> $ds9 -plot clear # clear all datasets<br> $ds9 -plot load foo.dat xy # load new dataset with dimension xy<br> $ds9 -plot save bar.dat # save current dataset<br> $ds9 -plot loadconfig foo.plt # load plot configuration <br> $ds9 -plot saveconfig bar.plt # save current plot configuration<br> $ds9 -plot print<br> $ds9 -plot print destination file<br> $ds9 -plot print command "lp"<br> $ds9 -plot print filename "foo.ps"<br> $ds9 -plot print color gray<br> $ds9 -plot pagesetup orient portrait<br> $ds9 -plot pagesetup size letter<br> $ds9 -plot graph grid x yes<br> $ds9 -plot graph log x yes<br> </tt><tt>$ds9 -plot graph flip x yes</tt><br> <tt> $ds9 -plot graph range x auto yes<br> $ds9 -plot graph range x min 0<br> $ds9 -plot graph range x max 100<br> $ds9 -plot graph range y auto yes<br> $ds9 -plot graph range y min 0<br> $ds9 -plot graph range y max 100<br> $ds9 </tt><tt>-plot graph format y %e</tt><br> <tt> $ds9 -plot graph labels title {The Title}<br> $ds9 -plot graph labels xaxis {X}<br> $ds9 -plot graph labels yaxis {Y}<br> $ds9 -plot font numbers font times<br> $ds9 -plot font numbers size 12<br> $ds9 -plot font numbers weight bold<br> $ds9 -plot font numbers slant italic<br> $ds9 -plot font labels font times<br> $ds9 -plot font title font times<br> <br> # edit current dataset<br> $ds9 -plot dataset 2 # set current dataset to the second dataset loaded<br> $ds9 -plot view discrete yes<br> $ds9 -plot color discrete red<br> $ds9 -plot line discrete cross<br> $ds9 -plot line step width 2<br> $ds9 -plot line step dash yes<br> $ds9 -plot line error style 2</tt><br> <p><b><b><a name="png"></a></b>png</b></p> <p>Load PNG image into current frame.<br> </p> <tt> Syntax:<br> -png &lt;filename&gt;<br> &nbsp;<br> Example: </tt><br> <tt>$ds9 png foo.png</tt><tt><tt><tt><br> </tt></tt>$cat foo.png | ds9 -png -</tt><tt><br> </tt> <p><b> <a name="port"></a>port</b></p> <p>Set the IRAF port number, used by IRAF to communicate with DS9. The default is 5137, the standard IRAF port used by <i>ximtool</i>. </p> <tt> Syntax: <br> -port number <br> &nbsp;<br> Example: <br> $ds9 -port 5137 </tt> <p><b> <a name="port_only"></a>port_only<br> inet_only</b></p> <p>Only use the IRAF port number. This is the same as -fifo none -unix none. </p> <tt> Syntax: <br> -port_only <br> &nbsp;<br> Example: <br> $ds9 -port_only<br> </tt> <p><b> <a name="pow"></a>pow</b></p> <p>Select power scale function for the current frame. </p> <tt> Syntax: <br> -pow <br> &nbsp;<br> Example: <br> $ds9 -pow </tt> <p><b> <a name="prefs"></a>prefs</b></p> <p>Controls various preference settings. </p> <tt> Syntax: <br> -prefs clear<br> &nbsp; <br> Example: <br> $ds9 -prefs clear</tt> <p><b><a name="preserve"></a>preserve</b> </p> <p>Preserve the follow attributes while loading a new image. </p> <tt> Syntax: <br> preserve [scale yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [pan yes|no]<br> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; [regions yes|no]<br> &nbsp;<br> Example: <br> $ds9 -preserve scale yes<br> $ds9 -preserve pan yes<br> $ds9 -preserve regions yes<br> </tt> <p><b><a name="psprint"></a>psprint</b></p> <p>For MacOSX and Windows, invokes postscript printing. For all others, same as print. Please see <a href="#print">print</a> for further details.</p> <p><b><a name="print"></a>print</b></p> <p>Controls printing. Use print option to set printing options. Use print to actually print. </p> <tt> Syntax: <br> -print [destination printer|file] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;command&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [filename &lt;filename&gt;] <br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color rgb|cmyk|gray] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [level 1|2] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [resolution 53|72|75|150|300|600] <br> &nbsp;<br> Example: <br> $ds9 -print <br> $ds9 -print destination file <br> $ds9 -print command 'gv -' <br> $ds9 -print filename foo.ps <br> $ds9 -print color cmyk <br> $ds9 -print level 2 <br> $ds9 -print resolution 75 </tt> <p><b> <a name="private"></a>private</b></p> <p>use private colormap, valid for pseudocolor 8 mode. </p> <tt> Syntax: <br> -private <br> &nbsp;<br> Example: <br> $ds9 -private </tt> <p><b> <a name="raise"></a>raise</b></p> <p>Raise in the window stacking order. </p> <tt> Syntax: <br> -raise <br> &nbsp;<br> Example: <br> $ds9 -raise<br> </tt> <p><b> <a name="regions"></a>regions</b></p> <p>Controls regions in the current frame. </p> <tt> Syntax: <br> -regions [&lt;filename&gt;]<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [load [all] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [list [close]]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [show yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [showtext yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid auto yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [centroid radius &lt;value&gt;|iteration &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [getinfo]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [move front] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [move back]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select all]<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [select none]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [select invert]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [delete all]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [delete select]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [format ds9|xml|ciao|saotng|saoimage|pros|xy]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [system image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [sky fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [skyformat degrees|sexagesimal]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [strip yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [shape &lt;shape&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [color &lt;color&gt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [width &lt;width&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [fixed|edit|rotate|delete yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [include|exclude|source|background]</tt><br> <tt> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [delim [nl|&lt;char&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [command &lt;marker command&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [composite]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [dissolve]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [template &lt;filename&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [template &lt;filename&gt; at &lt;ra&gt; &lt;dec&gt; &lt;coordsys&gt; &lt;skyframe&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [savetemplate &lt;filename&gt;]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group new]<br> </tt><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; new]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; update]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; select]<br> </tt><tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; color &lt;color&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; copy] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; delete] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; font &lt;font&gt;] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; move &lt;int&gt; &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; movefront] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; moveback] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [group &lt;tag&gt; property &lt;property&gt; yes|no] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [copy]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [cut]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [paste image|physical|wcs|wcsa...wcsz]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [undo]<br> &nbsp;<br> Example: <br> $ds9 -regions foo.reg <br> $ds9 -regions -format ciao bar.reg # load as ciao format<br> $ds9 -regions foo.fits # FITS regions files do not need a format specification<br> $ds9 -regions load foo.reg # load foo.reg into current frame<br> $ds9 -regions load all foo.reg # load foo.reg into all frames<br> $ds9 -regions load '*.reg'# expand *.reg and load into current frame<br> $ds9 -regions load all '*.reg' # expand *.reg and load into all frames<br> $ds9 -regions save foo.reg<br> $ds9 -regions list <br> $ds9 -regions list close<br> $ds9 -regions show yes<br> $ds9 -regions showtext no<br> $ds9 -regions centroid<br> $ds9 -regions centroid auto yes<br> $ds9 -regions centroid radius 10<br> $ds9 -regions centroid iteration 20<br> $ds9 -regions getinfo<br> $ds9 -regions move back<br> $ds9 -regions move front<br> $ds9 -regions select all <br> $ds9 -regions select none<br> $ds9 -regions select invert<br> $ds9 -regions delete all<br> $ds9 -regions delete select<br> $ds9 -regions format ds9 <br> $ds9 -regions system wcs<br> $ds9 -regions sky fk5 <br> $ds9 -regions skyformat degrees <br> $ds9 -regions delim nl <br> $ds9 -regions strip yes<br> $ds9 -regions shape ellipse <br> $ds9 -regions color red <br> $ds9 -regions width 3<br> </tt><tt>$ds9 -regions edit yes<br> $ds9 -regions include<br> </tt><tt>$ds9 -regions command "circle 100 100 20 # color=red"<br> $ds9 -regions composite<br> $ds9 -regions dissolve<br> $ds9 -regions template foo.tpl<br> $ds9 -regions template foo.tpl at 13:29:55.92 +47:12:48.02 fk5<br> $ds9 -regions savetemplate foo.tpl<br> $ds9 -regions group new<br> $ds9 -regions group foo new<br> $ds9 -regions group foo update<br> $ds9 -regions group foo select<br> $ds9 -regions group foo color red<br> $ds9 -regions group foo copy<br> $ds9 -regions group foo delete<br> $ds9 -regions group foo cut<br> $ds9 -regions group foo font {times 14 bold}<br> $ds9 -regions group foo move 100 100<br> $ds9 -regions group foo movefront<br> $ds9 -regions group foo moveback<br> $ds9 -regions group foo property delete no<br> $ds9 -regions copy<br> $ds9 -regions cut<br> $ds9 -regions paste wcs<br> $ds9 -regions undo<br> </tt> <p><b><a name="red"></a>red</b></p> <p>For RGB frames, sets the current color channel to red.</p> <tt> Syntax:<br> -red<br> &nbsp;<br> Example: <br> $ds9 -red foo.fits<br> </tt> <p><b> <a name="restore"></a>restore</b></p> <p>Restore DS9 to a previous state from a backup save set. </p> <tt> Syntax: <br> -restore &lt;filename&gt;<br> &nbsp;<br> Example:<br> $ds9 -restore ds9.bck</tt><br> <p><b> <a name="rgb"></a>rgb</b></p> <p>Create RGB frame and control RGB frame parameters.</p> <tt> Syntax: <br> -rgb []<br> &nbsp;&nbsp;&nbsp; &nbsp;[red|green|blue]<br> &nbsp;&nbsp;&nbsp; &nbsp;[channel [red|green|blue]]<br> &nbsp;&nbsp; &nbsp; [view [red|green|blue] [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[system &lt;coordsys&gt;]<br> &nbsp;&nbsp;&nbsp; &nbsp;[lock wcs|crop|slice|bin|scale|colorbar|smooth [yes|no]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -rgb # create new rgb frame<br> $ds9 -rgb red # set current channel to red<br> $ds9 -rgb channel red # set current channel to red<br> $ds9 -rgb view blue no # turn off blue channel<br> $ds9 -rgb system wcs # set rgb coordinate system<br> </tt><tt>$ds9 -rgb lock wcs yes</tt><br> <tt>$ds9 -rgb lock crop yes</tt><br> <tt>$ds9 -rgb lock slice yes</tt><br> <tt>$ds9 -rgb lock bin yes</tt><br> <tt> $ds9 -rgb lock scale yes<br> $ds9 -rgb lock colorbar yes<br> $ds9 -rgb lock smooth yes<br> $ds9 -rgb open<br> $ds9 -rgb close<br> </tt><br> <p><b> <a name="rgbarray"></a>rgbarray</b></p> <p>Load raw data array cube into rgb frame.<br> </p> <tt> Syntax:<br> -rgbarray &lt;filename&gt;[[xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],[zdim=3],bitpix=&lt;b&gt;,skip=&lt;s&gt;,endian=[little|big]]<br> &nbsp;<br> Example: <br> $ds9 -rgbarray foo.arr[dim=512,zdim=3,bitpix=-32,endian=little]</tt><br> <tt>$cat foo.arr | ds9 -rgbarray -[dim=512,zdim=3,bitpix=-32,endian=little]</tt><br> <p><b> <a name="rgbcube"></a>rgbcube</b></p> <p>Load FITS rgbcube into rgb frame.<br> </p> <tt> Syntax:<br> -rgbcube &lt;filename&gt;<br> &nbsp;<br> Example: <br> $ds9 -rgbcube foo.fits</tt><tt><tt><br> </tt>$cat foo.fits | ds9 -rgbcube -</tt><br> <p><b> <a name="rgbimage"></a>rgbimage</b></p> <p>Load FITS rgbimage into rgb frame.<br> </p> <tt> Syntax:<br> -rgbimage &lt;filename&gt;<br> &nbsp;<br> Example: <br> $ds9 -rgbimage foo.fits</tt><tt><tt><br> </tt>$cat foo.fits | ds9 -rgbimage -</tt> <br> <p><b> <a name="rotate"></a>rotate</b></p> <p>Controls the rotation angle (in degrees) of the current frame. </p> <tt> Syntax: <br> -rotate [&lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -rotate 45 <br> $ds9 -rotate to 30<br> $ds9 -rotate open<br> $ds9 -rotate close<br> </tt> <p><b><a name="samp"></a>samp</b></p> <p>Enable/Disable SAMP protocol. </p> <tt> Syntax: <br> -samp [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [broadcast [image|table]]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [send [image|table] &lt;application&gt;]<br> &nbsp;<br> Example: <br> $ds9 -samp yes<br> $ds9 -samp broadcast image<br> $ds9 -samp send image aladin</tt><br> <p><b> <a name="save"></a>save<br> </b></p> <p>Save loaded image data of current frame as FITS.</p> <tt> Syntax: <br> -save </tt><tt>[fits|rgbimage|rgbcube|mecube|mosaic|mosaicimage] &lt;filename&gt; [image|table|slice]</tt> <br> <tt> &nbsp;<br> Example: <br> $ds9 -save foo.fits</tt><br> <tt>$ds9 -save fits foo.fits image</tt><br> <tt>$ds9 -save fits foo.fits table<br> $ds9 -save fits foo.fits slice</tt><br> <tt>$ds9 -save rgbimage foo.fits<br> </tt><tt>$ds9 -save rgbcube foo.fits</tt><br> <tt>$ds9 -save mecube foo.fits</tt><br> <tt>$ds9 -save mosaic foo.fits</tt><br> <tt>$ds9 -save mosaicimage foo.fits</tt><br> <p><b> <a name="saveimage"></a>saveimage</b></p> <p>Create a snap shot of the current DS9 window and save in specified image format. If no format specified, the file name extension is used to determine the output format. Optional parameters: <tt>jpeg</tt> quality (1-100) and <tt>tiff</tt> compression method. </p> <tt> Syntax: <br> -saveimage </tt><tt>[fits|eps|gif|tiff|jpeg|png] </tt><tt>&lt;filename&gt;<br> -saveimage &lt;filename&gt;.jpeg [1-100]<br> -saveimage &lt;filename&gt;.tiff [none|jpeg|packbits|deflate]<br> &nbsp;<br> Example: <br> $ds9 -saveimage ds9.tiff<br> $ds9 -saveimage jpeg ds9.jpeg 75</tt><tt><br> </tt> <p><b> <a name="scale"></a>scale</b></p> <p>Controls the limits and color scale distribution. </p> <tt> Syntax: <br> -scale [linear|log|pow|sqrt|squared|asinh|sinh|histequ]<br> &nbsp; &nbsp; &nbsp;&nbsp; [log exp &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [datasec yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [limits &lt;minvalue&gt; &lt;maxvalue&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode minmax|&lt;value&gt;|zscale|zmax] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [scope local|global] <br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -scale linear<br> $ds9 -scale log exp 100<br> $ds9 -scale datasec yes <br> $ds9 -scale histequ <br> $ds9 -scale limits 1 100 <br> $ds9 -scale mode zscale <br> $ds9 -scale mode 99.5 <br> $ds9 -scale scope local<br> $ds9 -scale match<br> $ds9 -scale lock yes<br> $ds9 -scale open<br> $ds9 -scale close</tt><tt><br> </tt> <p><b> <a name="shm"></a>shm</b></p> <p>Load a shared memory segment into the current frame. </p> <tt> Syntax: <br> -shm [&lt;key&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [key &lt;id&gt; [&lt;filename&gt;]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [shmid &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [fits [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [mosaicimage [iraf|wcs|wcsa...wcsz|wfpc2] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [mosaicimagenext [wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp; &nbsp;[mosaic [iraf|wcs|wcsa...wcsz] [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [rgbcube [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [rgbimage [key|shmid] &lt;id&gt; [&lt;filename&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [rgbarray [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;,zdim=3],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;&nbsp;&nbsp;&nbsp; [array [key|shmid] &lt;id&gt; [xdim=&lt;x&gt;,ydim=&lt;y&gt;|dim=&lt;dim&gt;],bitpix=&lt;b&gt;,[skip=&lt;s&gt;]]<br> &nbsp;<br> Example: <br> $ds9 -shm 102 <br> $ds9 -shm key 102 <br> $ds9 -shm shmid 102 foo<br> $ds9 -shm fits 100 foo<br> $ds9 -shm mosaicimage iraf key 100 foo <br> $ds9 -shm mosaicimage wcs key 100 foo <br> $ds9 -shm mosaicimage wcsa key 100 foo <br> $ds9 -shm mosaicimage wfpc2 key 100 foo <br> $ds9 -shm mosaicimagenext wcs key 100 foo <br> $ds9 -shm mosaic iraf key 100 foo<br> $ds9 -shm mosaic wcs key 100 foo<br> $ds9 -shm rgbcube key 100 foo<br> $ds9 -shm rgbimage key 100 foo<br> $ds9 -shm rgbarray shmid 102 [dim=32,zdim=3,bitpix=-32]<br> $ds9 -shm array shmid 102 [dim=32,bitpix=-32] </tt> <p><b> <a name="single"></a>single</b></p> <p>Set display mode to single. </p> <tt> Syntax: <br> -single <br> &nbsp;<br> Example: <br> $ds9 -single<br> </tt> <p><b><a name="skyview"></a>skyview </b></p> <p>Support for SkyView image server at HEASARC. </p> <tt> Syntax: <br> -skyview []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; [&lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name &lt;object&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [coord &lt;ra&gt; &lt;dec&gt; degrees|sexagesimal] # in wcs fk5<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [size &lt;width&gt; &lt;height&gt; degrees|arcmin|arcsec]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [save yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [frame new|current]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [update frame|crosshair]<br> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [survey sdssi|sdssr|sdssg|sdssu|sdssg] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -skyview<br> $ds9 -skyview m31 <br> $ds9 -skyview name m31 <br> $ds9 -skyview coord 00:42:44.404 +41:16:08.78 sexagesimal<br> $ds9 -skyview size 60 60 arcmin<br> $ds9 -skyview save yes<br> $ds9 -skyview frame current<br> $ds9 -skyview update frame <br> $ds9 -skyview survey sdssi<br> $ds9 -skyview open<br> $ds9 -skyview close<br> </tt> <p><b><a name="sleep"></a>sleep </b></p> <p>Delays execution for specified number of seconds. Default is 1 second.</p> <tt> Syntax: <br> -sleep [#]<br> &nbsp;<br> Example:<br> $ds9 -sleep <br> $ds9 -sleep 2<br> </tt> <p><b> <a name="slice"></a>slice<br> noslice<br> </b></p> <p>Indicates next files loaded are to treated as slices of a cube. Can be disabled with <tt>noslice</tt> command.<br> </p> <tt> Syntax: <br> -slice &lt;filename&gt;<br> -noslice<br> &nbsp;<br> Example: <br> $ds9 -slice *.fits<br> $ds9 -noslice<br> </tt> <p><b><a name="smooth"></a>smooth</b></p> <p>Smooth current image or set smooth parameters.</p> <tt> Syntax:<br> -smooth []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [function boxcar|tophat|gaussian]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [radius &lt;int&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [match]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [lock [yes|no]]<br> &nbsp;<br> Example:<br> $ds9 -smooth<br> $ds9 -smooth yes<br> $ds9 -smooth function tophat<br> $ds9 -smooth radius 4<br> $ds9 -smooth open<br> $ds9 -smooth close<br> $ds9 -smooth match<br> $ds9 -smooth lock yes<br> </tt> <p><b> <a name="squared"></a>squared</b></p> <p>Select squared scale function for the current frame. </p> <tt> Syntax: <br> -squared <br> &nbsp;<br> Example: <br> $ds9 -squared </tt> <p><b> <a name="sqrt"></a>sqrt</b></p> <p>Select square soot scale function for the current frame. </p> <tt> Syntax: <br> -sqrt <br> &nbsp;<br> Example: <br> $ds9 -sqrt </tt> <p><b> <a name="source"></a>source</b></p> <p>Source TCL code from a file. </p> <tt> Syntax: <br> -source filename <br> &nbsp;<br> Example: <br> $ds9 -source extensions.tcl<br> </tt> <p><b> <a name="tcl"></a>tcl</b></p> <p>Enable tcl commands to be executed via XPA or SAMP. This can be a major security risk and is disabled by default. Please use with caution.</p> <tt> Syntax:<br> -tcl [yes|no] <br> &nbsp;<br> Example: <br> $ds9 -tcl yes<br> </tt> <p><b> <a name="theme"></a>theme</b></p> <p>Select GUI theme. Use <tt>native</tt> for the recommended theme for your platform. Note: not all themes are available on all platforms.<br> </p> <tt> Syntax:<br> -theme [native|clam|alt|default|classic|aqua|vista|win|xp] <br> &nbsp;<br> Example: <br> $ds9 -theme clam</tt><br> <p><b> <a name="threads"></a>threads</b></p> <p>Set number of process threads for functions which are multi-threaded. </p> <tt> Syntax:<br> -threads #<br> &nbsp;<br> Example: <br> $ds9 -threads 8</tt><br> <br> <b><a name="tiff"></a>tiff</b><br> <p>Load TIFF image into current frame.<br> </p> <tt> Syntax:<br> -tiff &lt;filename&gt;<br> &nbsp;<br> Example: <br> </tt><tt>$ds9 -tiff foo.tiff</tt><tt><tt><tt><tt><br> </tt></tt> </tt></tt><tt><tt>$cat foo.fits | ds9 -tiff -</tt></tt><tt><br> </tt> <p><b> <a name="tile"></a>tile</b></p> <p>Controls the tile display mode. </p> <tt> Syntax: <br> -tile []<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [mode grid|column|row] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid mode [automatic|manual]] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid layout &lt;col&gt; &lt;row&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [grid gap &lt;pixels&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [row] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [column] <br> &nbsp;<br> Example: <br> $ds9 -tile <br> $ds9 -tile yes <br> $ds9 -tile mode row <br> $ds9 -tile grid <br> $ds9 -tile grid mode manual <br> $ds9 -tile grid layout 5 5 <br> $ds9 -tile grid gap 10 <br> $ds9 -tile row <br> $ds9 -tile column </tt> <p><b> <a name="title"></a>title</b></p> <p>Changes the display window title to the specified name. </p> <tt> Syntax: <br> -title name <br> &nbsp;<br> Example: <br> $ds9 -title Voyager </tt> <p><b> <a name="unix"></a>unix</b></p> <p>Set the IRAF unix socket name, used by IRAF to communicate with DS9. The default is /tmp/.IMT%d, so that the standard IRAF unix socket is defined. </p> <tt> Syntax: <br> -unix name <br> &nbsp;<br> Example: <br> $ds9 -unix "/tmp/.IMT%d" </tt> <p><b> <a name="unix_only"></a>unix_only</b></p> <p>Only use the IRAF unix socket name. This is the same as -fifo none -port 0. </p> <tt> Syntax: <br> -unix_only <br> &nbsp;<br> Example: <br> $ds9 -unix_only<br> </tt> <p><b> <a name="update"></a>update</b></p> <p>Updates the current frame or region of frame. In the second form, the first argument is the number of the fits HDU (starting with 1) and the remaining args are a bounding box in IMAGE coordinates. By default, the screen is updated the next available idle cycle. However, you may force an immediate update by specifying the NOW option. </p> <tt> Syntax: <br> -update [] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [# x1 y1 x2 y2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [now # x1 y1 x2 y2]<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [on]<br> &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; [off] <br> &nbsp;<br> Example: <br> $ds9 -update <br> $ds9 -update 1 100 100 300 400 <br> $ds9 -update now <br> $ds9 -update now 1 100 100 300 400<br> $ds9 -update off # delay refresh of the screen while loading files<br> $ds9 -update on # be sure to turn it on when you are finished loading</tt><br> <p><b> <a name="url"></a>url</b></p> <p>Load FITS from URL into the current frame</p> <tt> Syntax: <br> -url &lt;url&gt;<br> &nbsp;<br> Example: <br> $ds9 -url http://foo.bar.edu/foo.fits</tt><tt> </tt> <p><b> <a name="version"></a>version</b></p> <p>Returns the current version of DS9 and exits. </p> <tt> Syntax: <br> -version <br> &nbsp;<br> Example: <br> $ds9 -version </tt> <p><b> <a name="view"></a>view</b></p> <p>Controls the GUI and visible RGB frame color channels. </p> <tt> Syntax: <br> -view [layout horizontal|vertical]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [info yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [panner yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [magnifier yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [buttons yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [colorbar yes|no]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [graph horizontal|vertical yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [filename yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [object yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [minmax yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [lowhigh yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [frame yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [image|physical|wcs|wcsa...wcsz yes|no]<br> &nbsp;&nbsp;&nbsp; &nbsp; [red yes|no]<br> &nbsp; &nbsp; &nbsp; [green yes|no]<br> &nbsp; &nbsp; &nbsp; [blue yes|no]<br> &nbsp;<br> Example: <br> $ds9 -view layout vertical<br> $ds9 -view info yes<br> $ds9 -view panner yes<br> $ds9 -view magnifier yes<br> $ds9 -view buttons yes<br> $ds9 -view colorbar yes<br> $ds9 -view graph horizontal yes<br> $ds9 -view filename yes<br> $ds9 -view object yes<br> $ds9 -view minmax yes<br> $ds9 -view lowhigh yes<br> $ds9 -view frame yes <br> $ds9 -view wcsa yes<br> $ds9 -view red yes<br> $ds9 -view green yes<br> $ds9 -view blue yes<br> </tt> <p><b> <a name="visual"></a>visual</b></p> <p>Force DS9 to use the specified color visual. This argument MUST be the first argument listed. Requires the visual be available. </p> <tt> Syntax: <br> -visual [pseudocolor|pseudocolor8|truecolor|truecolor8|truecolor16|truecolor24] &nbsp;<br> Example: <br> $ds9 -visual truecolor24 </tt> <p><b> <a name="vo"></a>vo</b></p> <p>Invoke an connection to a Virtual Observatory site. </p> <tt> Syntax: <br> -vo [method xpa|mime]<br> &nbsp;&nbsp;&nbsp; [server &lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [internal yes|no]<br> &nbsp;&nbsp;&nbsp; [delay #]<br> &nbsp;&nbsp;&nbsp; [&lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [connect &lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [disconnect &lt;url&gt;]<br> &nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example:<br> $ds9 -vo method xpa<br> $ds9 -vo server "http://foo.bar.edu/list.txt"<br> $ds9 -vo internal yes<br> $ds9 -vo delay 15 # keep-alive delay<br> $ds9 -vo chandra-ed<br> $ds9 -vo connect chandra-ed<br> $ds9 -vo disconnect chandra-ed<br> $ds9 -vo open<br> $ds9 -vo close<br> </tt> <p><b> <a name="wcs"></a>wcs</b></p> <p>Controls the World Coordinate System for the current frame. If the wcs system, skyframe, or skyformat is modified, the info panel, compass, grid, and alignment will be modified accordingly. Also, a new WCS specification can be loaded and used by the current image regardless of the WCS that was contained in the image file. Please see <a href="file.html#WCS">WCS</a> for more information. </p> <tt> Syntax: <br> -wcs [[system] wcs|wcsa...wcsz] <br> &nbsp;&nbsp;&nbsp;&nbsp; [[sky] fk4|fk5|icrs|galactic|ecliptic] <br> &nbsp;&nbsp;&nbsp;&nbsp; [[skyformat] degrees|sexagesimal] <br> &nbsp;&nbsp;&nbsp;&nbsp; [align yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [reset [#]] <br> &nbsp;&nbsp;&nbsp;&nbsp; [replace [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [append [#] &lt;filename&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -wcs wcs <br> $ds9 -wcs system wcs<br> </tt><tt>$ds9 -wcs fk5 <br> </tt><tt>$ds9 -wcs sky fk5 <br> </tt><tt>$ds9 -wcs sexagesimal <br> </tt><tt>$ds9 -wcs skyformat sexagesimal <br> $ds9 -wcs align yes <br> $ds9 -wcs reset <br> $ds9 -wcs reset 3<br> $ds9 -wcs replace foo.wcs <br> $ds9 -wcs replace 3 foo.wcs <br> $ds9 -wcs append foo.wcs<br> $ds9 -wcs append 3 foo.wcs<br> $ds9 -wcs open<br> $ds9 -wcs close<br> </tt> <p><b> <a name="web"></a>web</b></p> <p>Display specified URL in the web display. </p> <tt> Syntax:<br> -web [new|&lt;webname&gt;] [&lt;url&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [click back|forward|stop|reload|#]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [clear]<br> &nbsp;&nbsp;&nbsp;&nbsp; [&lt;webname&gt;] [close]<br> &nbsp;<br> Example: <br> $ds9 -web www.cnn.com<br> $ds9 -web new www.cnn.com<br> $ds9 -web hvweb www.apple.com<br> $ds9 -web click back<br> $ds9 -web click 2<br> $ds9 -web clear<br> $ds9 -web close<br> </tt> <p><b> <a name="width"></a>width</b></p> <p>Set the width of the image display window. Use the <a href="command.html#geometry">geometry</a> command to set the overall width and height of the ds9 window.</p> <tt> Syntax: <br> -width [&lt;value&gt;]<br> &nbsp;<br> Example: <br> $ds9 -width 512<br> </tt> <p><b> <a name="xpa"></a>xpa</b></p> <p>Configure XPA at startup.</p> <tt> Syntax:<br> -xpa [yes|no] <br> &nbsp;&nbsp;&nbsp;&nbsp; [inet|local|unix|localhost] <br> &nbsp;&nbsp;&nbsp;&nbsp; [noxpans]<br> &nbsp;<br> Example: <br> $ds9 -xpa no <br> $ds9 -xpa local <br> $ds9 -xpa noxpans<br> </tt> <p><b> <a name="zmax"></a>zmax</b></p> <p>Set Scale Limits based&nbsp; on the <i>IRAF</i> algorithm and maximum data value. </p> <tt> Syntax: <br> -zmax <br> &nbsp;<br> Example: <br> $ds9 -zmax </tt> <p><b> <a name="zscale"></a>zscale</b></p> <p>Set Scale Limits based&nbsp; on the <i>IRAF</i> algorithm. </p> <tt> Syntax: <br> -zscale []<br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [contrast]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sample]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [line]<br> &nbsp;<br> Example: <br> $ds9 -zscale<br> $ds9 -zscale contrast .25<br> $ds9 -zscale sample 600<br> $ds9 -zscale line 120<br> </tt> <p><b> <a name="zoom"></a>zoom</b></p> <p>Controls the current zoom value for the current frame. </p> <tt> Syntax: <br> -zoom [&lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&lt;value&gt; &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt;]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to &lt;value&gt; &lt;value&gt;] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [to fit] <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [open|close]<br> &nbsp;<br> Example: <br> $ds9 -zoom 2<br> $ds9 -zoom 2 4<br> $ds9 -zoom to 4<br> $ds9 -zoom to 2 4 <br> $ds9 -zoom to fit<br> $ds9 -zoom open<br> $ds9 -zoom close<br> <br> </tt> </blockquote> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/file.html��������������������������������������������������������������������������0000644�0001750�0001750�00000062367�12077065510�014252� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>File Formats</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3><img alt="" src="../sun.gif" align="middle" height="98" width="100"> File Formats</h3> <blockquote> <a href="#FITS">FITS</a><br> <a href="#FITSImage">FITS Image</a><br> <a href="#FITSTable">FITS Table</a><br> <a href="#FITSBinaryEventsTable">FITS Binary Events Table</a><br> <a href="#FITSHEALPIXTable">FITS HEALPIX Table</a><br> <a href="#FITSDataCube">FITS Data Cube</a><br> <a href="#FITSMultipleExtensionDataCube">FITS Multiple Extension Data Cube</a><br> <a href="#FITSMultipleExtensionMultipleFrames">FITS Multiple Extension Multiple Frames</a><br> <a href="#FITSMosaic">FITS Mosaic</a><br> <a href="#FITSMosaicDataCube">FITS Mosaic Data Cube</a><br> <a href="#FITSRGB">FITS RGB </a><br> <a href="#SplitFITS">Split FITS</a><br> <a href="#array">Array</a> <br> <a href="file:///Users/joye/saods9/doc/ref/file.html#nrrd">NRRD</a><br> <a href="#gif">GIF</a><br> <a href="#tiff">TIFF</a><br> <a href="#jpeg">JPEG</a><br> <a href="#png">PNG</a><br> <a href="#ExternalFileSupport">External Format Support</a> <br> <a href="#ExternalAnalysisSupport">External Analysis Support</a> <br> <a href="#RegionFiles">Region Files</a> <br> <a href="#ColorLookupTable">Color Lookup Table</a> <br> <a href="#WCS">WCS</a> <br> <a href="#PreferenceFile">Preference File</a> <br> <a href="#StartupFile">Startup File</a> <br> <a href="#TCL">TCL</a><br> <p><b><a name="FITS"></a>FITS</b></p> DS9 supports FITS images and FITS binary tables. The following algorithm is used to locate and to load the FITS image or table if no additional information is provide: <blockquote> <tt> Look for FITS image in primary HDU. <br> If no image is found, examine each extension HDU<br> If image, load <br> If bin table, load if the following is true<br> &nbsp;&nbsp;&nbsp; extension name is EVENTS or STDEVT or RAYEVENT <br> &nbsp;&nbsp;&nbsp; column names X and Y are present<br> If DS9 traverses the entire FITS file without satisfying one of the above, an error is generated.</tt> </blockquote> FITS keyword inheritance is supported. All valid FITS <tt>BITPIX</tt> values are supported, along with <tt>-16,</tt> for <tt>UNSIGNED SHORT</tt>. The following FITS keywords are supported: <blockquote> <tt> OBJECT<br> BSCALE / BZERO<br> BLANK<br> DATASEC<br> LTV / LTM&nbsp; for physical coords<br> DTV / DTM&nbsp; for detector coords<br> ATV / ATM&nbsp; for amplifier coords<br> WCS keywords<br> WCS# keywords </tt> </blockquote> <p><b> <a name="FITSImage"></a>FITS Image</b></p> At load time, the user may provide just a filename or a filename along with FITS extension name/number and image section specification. FITS extension names are case insensitive. When specifying an extention, be sure to quote strings correctly to pass both the shell and DS9 parser. A image section specification is used to specify the x,y limits of an image subsection. By default, numerics are in <tt>IMAGE</tt> coordinates, use a <tt>'p'</tt> to indicate <tt>PHYSICAL</tt> coordinates. A <tt>'*'</tt> indicates use the default for that axis only.<br> <blockquote> <tt> Syntax:<br> filename<br> filename[&lt;name&gt;|#]<br> filename[xmin:xmax,ymin:ymax[p]]<br> filename[*,ymin:ymax[p]]<br> filename[xmin:xmax,*[p]]<br> filename[xdim@xcenter,ydim@ycenter[p]]<br> filename[dim@xcenter@ycenter[p]]<br> </tt><tt>filename[xmin:xmax,ymin:ymax,zmin:zmax]</tt><br> <tt> filename[*,ymin:ymax,zmin:zmax]<br> filename[xmin:xmax,*,zmin:zmax]<br> </tt><tt>filename[xmin:xmax,ymin:ymax,*]</tt><br> <tt> filename[xdim@xcenter,ydim@ycenter,zdim@zcenter]<br> filename[dim@xcenter@ycenter@zcenter]</tt><tt><br> Example:<br> $ds9 foo.fits # default load <br> $ds9 foo.fits[1] # load first extension<br> $ds9 foo.fits[BCKGRD] # load extension named 'BCKGRD'<br> $ds9 foo.fits[10:200,40:100] # image section<br> $ds9 foo.fits[*,40:100] # only section y axis<br> $ds9 foo.fits[256@512@512] # section box at 512,512<br> $ds9 foo.fits[2][100:200,100:200] # second extension, image section<br> </tt><tt>$ds9 foo.fits[10:200,40:100,5:20] # cube section<br> $ds9 foo.fits[*,40:100,5:20] # only section y and z axes<br> $ds9 foo.fits[256@512@512@512] # section cube at 512,512<br> $ds9 foo.fits[2][100:200,100:200,5:20] # second extension, cube section</tt><br> </blockquote> <p><b> <a name="FITSTable"></a>FITS Table</b></p> At load time, the user may provide just a filename or a filename along with FITS extension name or number and file parameters. FITS extension names and parameters are case insensitive.<br> <blockquote> <tt> Syntax: <br> filename <br> filename[ext] <br> filename[params] <br> filename[ext][params] <br> filename[ext,params] <br> where ext = [&lt;extension name&gt; | &lt;extension #&gt;]</tt><br> </blockquote> <p><b> <a name="FITSBinaryEventsTable"></a>FITS Binary Events Table<br> </b></p> DS9 will automatically convert an FITS binary events table into a 2D image for display. The users may specify a number of parameters on how to construct the image and how to filter data. When specifying a filter, be sure to quote strings correctly to pass both the shell and DS9 parser. </blockquote> <blockquote> <blockquote> <tt>Syntax: <br> filename[ext,params]</tt> <br> <tt>where params:<br> [bin=colx,coly] # bin counts <br> [bin colx,coly] # bin counts <br> [bin=colx,coly,colz] # bin on colz <br> [bin colx,coly,colz] # bin on colz <br> [bin=colz] # bin cols 'x', 'y', and colz <br> [key=colx,coly] <br> [binkey=colx,coly]<br> [&lt;filter&gt;]<br> </tt><br> (see <a href="http://hea-www.harvard.edu/saord/funtools/filters.html">Introduction to Filtering</a>)<br> <br> <tt>Example: </tt><br> <tt> $ds9 foo.fits # default load </tt><br> <tt> $ds9 foo.fits[1] # load first extension </tt><br> <tt> $ds9 foo.fits[BCKGRD] # load extension named 'BCKGRD' </tt><br> <tt> $ds9 foo.fits[bin=detx,dety] # bin on detx,dety </tt><br> <tt> $ds9 foo.fits[2][bin=rawx,rawy] # load ext 2, cols rawx,rawy </tt><br> <tt> $ds9 foo.fits[bg_events,bin=rawx,rawy] # load ext bg_events, cols rawx,rawy </tt><br> <tt> $ds9 foo.fits[bin=x,y,pha] # bin on x,y,pi </tt><br> <tt> $ds9 foo.fits[bin=pi] # bin on x,y,pi</tt><br> <tt> $ds9 'foo.fits[ccd_id==3&amp;&amp;energy&gt;4000]' # quoted filter</tt><br> <tt> $ds9 '"foo.fits[ccd_id==3 &amp;&amp; energy&gt;4000]"' # double quoted filter</tt><br> <tt> $ds9 'foo.fits[events][pha&gt;5,pi&lt;2]' # load extension 'events' and filter</tt></blockquote> </blockquote> <blockquote> <blockquote> </blockquote> <p>The shell environment variable <tt>DS9_BINKEY </tt>may be used to specify default bin cols for FITS bin tables. Example:</p> <blockquote> <tt>$ export DS9_BINKEY='[bin=rawx,rawy]'</tt> <br> <tt>$ ds9 foo.fits # load FITS bin table, bin on rawx, rawy<br> </tt></blockquote> <p><b> <a name="FITSHEALPIXTable"></a>FITS HEALPIX Table<br> </b></p> DS9 will automatically convert an FITS HEALPIX binary or ascii table into a 2D image for display. The users may specify a number of parameters on how to construct the image. Any table with keyword PIXTYPE=HEALPIX or NSIDE=x will be processed as an HEALPIX image. The following FITS keywords will be used if present and not overwritten by a command line option: NSIDE, COORDSYS, ORDER.<br> <blockquote> <blockquote> </blockquote> <tt>Syntax: <br> filename[ext,params]</tt> <br> <tt>where params:</tt><br> <tt>[order=ring|nested] # default ring<br> [layout=equatorial|north|south] # default equatorial<br> [col=&lt;column number&gt;] # defaut 1<br> [quad=&lt;quadurant number&gt;] # (1-4) default 1<br> [system=equatorial|galactic|ecliptic|unknown] # default unknown</tt><br> <tt>Example: </tt><tt><br> $ds9 foo.fits # default load </tt><tt><br> $ds9 foo.fits[1] # load first extension </tt><tt><br> $ds9 foo.fits[order=ring,layout=equatorial,col=1,quad=1,system=unknown]<br> </tt><tt>$ds9 foo.fits[1,order=nested] # first extension, nested order</tt><br> </blockquote> <blockquote> </blockquote> <p><b><a name="FITSDataCube"></a>FITS Cube</b></p> A FITS Cube is a FITS image which contains more than 2 axes (NAXES&gt;2). DS9 will automatically detect if a cube is present and will load all additional images. In addition, individual images can be loaded one at a time into a cube. DS9 will display the Cube dialog box which allows the user to select which 2 image to be displayed. <p><b><a name="FITSMultipleExtensionDataCube"></a>FITS Multiple Extension Cube</b></p> A FITS Multiple Extension Data Cube file is a FITS file with one or more extensions, that is to be displayed as a data cube. Each image does not have to be the same size, however, only the coordinate systems from the first extension will be used for contours and grids. <br> <blockquote><tt> Example:</tt><br> <tt> $ds9 -medatacube foo.fits # load multiple extension fits file as data cube</tt></blockquote> <p><b><a name="FITSMultipleExtensionMultipleFrames"></a>FITS Multiple Extension Multiple Frames</b></p> Load a multiple extension FITS file into multiple frames. Please note that files loaded via standard-in or the xpa fits command can not be displayed using this method. <br> <blockquote><tt> Example:</tt><br> <tt> $ds9 -multiframe foo.fits # load multiple extension fits file as multiple frames</tt></blockquote> <p><b><a name="FITSMosaic"></a>FITS Mosaic</b></p> A FITS mosaic image may exist as a series of FITS files, or as one FITS file with many extensions. A FITS mosaic may be loaded all a one time, or by the segment. Once loaded, the multiple FITS images are treated as one FITS image. <br> <br> DS9 supports three forms of mosaics:&nbsp; <center> <table align="center" border="1" cellpadding="2" cellspacing="2" width="50%"> <tbody> <tr> <td valign="top"><tt>IRAF</tt><br> </td> <td valign="top"> <tt>contains the DETSEC and DETSIZE keywords.<br> See <a href="http://iraf.noao.edu/projects/ccdmosaic/imagedef/imagedef.html">NOAO IRAF Mosaic Data Structures</a></tt> <br> </td> </tr> <tr> <td align="left" valign="top"> <tt>WCS</tt><br> </td> <td align="left" valign="top"><tt>each FITS image contains a valid WCS.</tt><br> </td> </tr> <tr> <td align="left" valign="top"> <tt>HST WFPC2</tt><br> </td> <td align="left" valign="top"> <tt>valid HST WFPC2 data cube, consisting of 4 planes, along with a fits ascii table containing wcs information. </tt></td> </tr> </tbody> </table> </center> <tt></tt> <blockquote><tt>Example:</tt><br> <tt> $ds9 -mosaicimageiraf foo.fits # load mosaic iraf from one fits file with multiple exts</tt><br> <tt> $ds9 -mosaiciraf foo.fits bar.fits wow.fits # load mosaic iraf from 3 files</tt><br> <tt> $ds9 -mosaicimagewcs foo.fits # load mosaic wcs from one fits file with multiple exts</tt><br> <tt> $ds9 -mosaicimagenext wcs foo.fits # load mosaic wcs from one fits file with multiple exts</tt><br> <tt> $ds9 -mosaicwcs foo.fits bar.fits wow.fits # load mosaic wcs from 3 files</tt><br> <tt> $ds9 -mosaicimagewfpc2 bar.fits # load wfpc2 mosaic</tt><br> <tt> $ds9 -mosaic foo.fits bar.fits wow.fits # load mosaic (iraf or wcs) from 3 files</tt><br> <tt> </tt></blockquote> <p><b><a name="FITSMosaicDataCube"></a>FITS Mosaic Data Cube</b></p> A FITS Mosaic Data Cube is a FITS mosaic image which contains more than 2 axes (NAXES&gt;2). DS9 will automatically detect if a mosaic data cube is present and will load all additional images. At the same time, DS9 will display the DataCube dialog box which allows the user to select which 2 image to be displayed. <p><b><a name="FITSRGB"></a>FITS RGB</b></p> A FITS RGB image may exist as three of FITS images, one FITS file with three extensions, or as a FITS 3D Data cube, with three slices, each representing the red, green, and blue channel. A FITS RGB image may be loaded all a one time, or by the channel. Once loaded, the multiple FITS images are treated as one FITS image.<br> <blockquote><tt>Example:</tt><br> <tt> $ds9 -rgbimage rgb.fits # load rgb image consisting of one fits file with 3 image exts</tt><br> <tt> $ds9 -rgbcube cube.fits # load rgb image consisting of one fits data cube</tt><br> <tt> $ds9 -rgb -red foo.fits -green bar.fits -blue wow.fits # rgb image from 3 fits images</tt><br> <tt> </tt></blockquote> <p><b><a name="SplitFITS"></a>Split FITS</b></p> A split fits is a valid fits file in which two files contain the header and data segments. <p><b><a name="array"></a>Array</b></p> Raw data arrays are supported. To load an array, the user must provide the dimensions, pixel depth, and optional header size and architecture type. <blockquote> <tt> Syntax: <br> filename[options]<br> options are:<br> xdim=value <br> ydim=value <br> zdim=value # default is a depth of 1<br> dim=value <br> dims=value <br> bitpix=[8|16|-16|32|64|-32|-64] <br> skip=value # must be even, most must be factor of 4 <br> arch|endian=[big|bigendian|little|littleendian]<br> <br> Example:<br> $ds9 -array bar.arr[xdim=512,ydim=512,zdim=1,bitpix=16] # load 512x512 short<br> $ds9 -array bar.arr[dim=256,bitpix=-32,skip=4] # load 256x256 float with 4 byte head<br> $ds9 -array bar.arr[dim=512,bitpix=32,arch=little] # load 512x512 long, intel<br> </tt> <p>or alternate format:</p> <tt>filename[array(&lt;type&gt;&lt;dim&gt;&lt;:skip&gt;&lt;endian&gt;)]<br> type: <blockquote> 'b' 8 -bit unsigned char<br> 's' 16-bit short int<br> 'u' 16-bit unsigned short int<br> 'i' 32-bit int<br> 'l' 64-bit int<br> 'r' 32-bit float<br> 'f' 32-bit float<br> 'd' 64-bit float </blockquote> dim: <blockquote> int&nbsp;&nbsp;&nbsp;&nbsp; # x,y dim<br> int.int # x,y dim<br> int.int.int # x,y,z dim<br> </blockquote> skip: <blockquote> int&nbsp;&nbsp;&nbsp;&nbsp; # number of bytes to skip </blockquote> endian: <blockquote> 'l' little endian<br> 'b' big endian<br> </blockquote> Example:<br> $ds9 -array bar.arr[array(s512)]&nbsp;&nbsp; # load 512x512 short<br> $ds9 -array bar.arr[array(r256:4)] # load 256x256 float with 4 byte head<br> $ds9 -array bar.arr[array(i512l)]&nbsp; # load 512x512 long, intel </tt> <p>The shell environment variable <tt>DS9_ARRAY </tt>may be used to specify default array parameters. </p> <tt> Example:<br> $export DS9_ARRAY='[dim=256,bitpix=-32]'<br> $ds9 -array foo.arr # load 256x256 float<br> </tt></blockquote> <p><b><a name="nrrd"></a>NRRD (Nearly Raw Raster Data)</b><br> </p> Images in NRRD are supported directly. Encodings supported: <tt>raw, gzip</tt><br> <tt>Example:</tt><br> <tt>$ ds9 -nrrd foo.nrrd</tt><br> <p><b><a name="gif"></a>GIF</b><br> </p> Images in GIF are supported directly. For a <tt>Frame</tt>, the average of the luminosity is used. For <tt>Frame RGB</tt>, each channel is loaded directly.<br> <tt>Example:</tt><br> <tt>$ ds9 -gif foo.gif</tt><br> <p><b><a name="tiff"></a>TIFF</b><br> </p> Images in TIFF are supported directly. For a <tt>Frame</tt>, the average of the luminosity is used. For <tt>Frame RGB</tt>, each channel is loaded directly.<br> <tt>Example:</tt><br> <tt>$ ds9 -tiff foo.tiff</tt><br> <p><b><a name="jpeg"></a>JPEG</b><br> </p> Images in JPEG are supported directly. For a <tt>Frame</tt>, the average of the luminosity is used. For <tt>Frame RGB</tt>, each channel is loaded directly.<br> <tt>Example:</tt><br> <tt>$ ds9 -jpeg foo.jpeg</tt><br> <p><b><a name="png"></a>PNG</b><br> </p> Images in PNG are supported directly. For a <tt>Frame</tt>, the average of the luminosity is used. For <tt>Frame RGB</tt>, each channel is loaded directly.<br> <tt>Example:</tt><br> <tt>$ ds9 -png foo.png</tt><br> <p><b> <a name="ExternalFileSupport"></a>External File Support</b></p> DS9 supports external file formats via an ASCII description file. When loading a file into DS9, these descriptions are referenced for instructions for loading the file, based on the file extension. If found, the command is executed and the result, a FITS image or FITS Binary Table, is read into DS9 via stdin. <br> At start-up, DS9 first searches for the ASCII file, named <tt>.ds9.fil</tt>in the local directory, then in the users home directory. <br> The file command first is macro-expanded to fill in user-defined arguments and then is executed externally. <br> The ASCII file that defines the known image files consists of one or more file descriptors, each of which has the following format: <blockquote> <tt> Help description<br> A space-separated list of templates<br> A space-separated list of file types (not currently used)<br> The command line for the loading this file type<br> </tt> </blockquote> Note that blank lines separate the file descriptions and should not be used as part of a description. Also, the '#' character is a comment character. <br> <br> The following macros are supported: <tt>$filename</tt><br> <blockquote><tt> For Example: </tt><br> <tt> # File access descriptions:</tt><br> <tt> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help explanation</tt><br> <tt> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file template</tt><br> <tt> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file type</tt><br> <tt> #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; access command</tt><br> <tt> IRAF IMH files</tt><br> <tt> *.imh</tt><br> <tt> IMH</tt><br> <tt> i2f -s $filename </tt></blockquote> <p><b> <a name="ExternalAnalysisSupport"></a>External Analysis Support</b></p> For more information about external analysis support files, see <a href="analysis.html">Analysis</a>. <p><b> <a name="RegionFiles"></a>Region Files</b></p> DS9 can read and write a number of region file formats. See <a href="region.html">Regions</a> documentation for more information. <blockquote> <tt> <a href="region.html#RegionDescriptions">DS9</a><br> <a href="region.html#FUNTools">FUNTools</a><br> <a href="region.html#Ciao">Ciao</a><br> <a href="region.html#SAOimage">SAOimage</a><br> <a href="region.html#IRAFPROS">IRAF PROS</a><br> <a href="region.html#FITSREGIONBinaryTable">FITS REGION Binary Table</a><br> <a href="region.html#XY">X Y</a> </tt> </blockquote> <p><b> <a name="ColorLookupTable"></a>Color Lookup Table</b></p> DS9 has a number of default colormaps available to the user. DS9 also supports reading and writing color lookup table formats from the following programs: <blockquote> <tt> <a href="http://tdc-www.harvard.edu/software/saoimage/saoimage.color.html#cmap">SAOimage</a><br> <a href="http://hea-www.harvard.edu/RD/saotng/adding_cmaps.html">SAOtng</a><br> XImtool<br> </tt> </blockquote> DS9 uses the file extension to determine the color table format: <center> <table nosave="" border="1" cellpadding="2" cellspacing="2" width="50%"> <tbody> <tr nosave=""> <td nosave=""> <center><tt>Ext</tt></center> </td> <td> <center><tt>Format</tt></center> </td> </tr> <tr> <td><tt>.lut</tt></td> <td><tt>XImtool, SAOtng</tt></td> </tr> <tr> <td><tt>.sao</tt></td> <td><tt>DS9, SAOimage</tt></td> </tr> <tr> <td><tt>any other</tt></td> <td><tt>DS9</tt></td> </tr> </tbody> </table> </center> <p><b> <a name="WCS"></a>WCS</b></p> A new WCS specification can be loaded and used by the current image regardless of the WCS that was contained in the image file. WCS specification can be sent to DS9 as an ASCII file via XPA. The format of the specification is a set of valid FITS keywords that describe a WCS. <blockquote> <tt> Example: <br> &nbsp;&nbsp;&nbsp; CRPIX1&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 257.75<br> &nbsp;&nbsp;&nbsp; CRPIX2&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 258.93<br> &nbsp;&nbsp;&nbsp; CRVAL1&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -201.94541667302 <br> &nbsp;&nbsp;&nbsp; CRVAL2&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -47.45444<br> &nbsp;&nbsp;&nbsp; CDELT1&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -2.1277777E-4 <br> &nbsp;&nbsp;&nbsp; CDELT2&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1277777E-4 <br> &nbsp;&nbsp;&nbsp; CTYPE1&nbsp; = 'RA---TAN' <br> &nbsp;&nbsp;&nbsp; CTYPE2&nbsp; = 'DEC--TAN' <br> </tt> </blockquote> Note that the WCS definitions can contain standard FITS 80 character WCS card images, as shown above, or free-form name/value pairs without the intervening "=" sign: <blockquote> <tt> &nbsp;&nbsp;&nbsp; CRPIX1&nbsp;&nbsp;&nbsp; 257.75 <br> &nbsp;&nbsp;&nbsp; CRPIX2&nbsp;&nbsp;&nbsp; 258.93 <br> &nbsp;&nbsp;&nbsp; CRVAL1&nbsp;&nbsp;&nbsp; -201.94541667302 <br> &nbsp;&nbsp;&nbsp; CRVAL2&nbsp;&nbsp;&nbsp; -47.45444 <br> &nbsp;&nbsp;&nbsp; CDELT1&nbsp;&nbsp;&nbsp; -2.1277777E-4 <br> &nbsp;&nbsp;&nbsp; CDELT2&nbsp;&nbsp;&nbsp; 2.1277777E-4 <br> &nbsp;&nbsp;&nbsp; CTYPE1&nbsp;&nbsp; 'RA---TAN' <br> &nbsp;&nbsp;&nbsp; CTYPE2&nbsp;&nbsp; 'DEC--TAN' </tt> </blockquote> <p><b> <a name="PreferenceFile"></a>Preference File</b></p> A preference file is a valid tcl script generated by DS9 to save the current preference items. See <a href="prefs.html">Preferences</a> for more information. <p><b> <a name="StartupFile"></a>Startup File</b></p> If a startup file <tt>ds9.ini</tt> is available, it is sourced as the last step in initialization. The following directories are searched in order: <tt>./, $HOME, /usr/local/lib, /opt/local/lib</tt>. <p><b> <a name="TCL"></a>TCL</b></p> TCL/TK script file. Users may customize the appearance and enhance the capabilities of DS9 by sourcing their own TCL scripts. </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/ref/iraf.html��������������������������������������������������������������������������0000644�0001750�0001750�00000016213�11426312317�014236� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>IRAF Support</title> </head> <body link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000" bgcolor="#ffffff"> <h3><img alt="" src="../sun.gif" height="98" width="100" align="middle"> IRAF Support</h3> <blockquote> <p>DS9 is a fully functional IRAF image display server. IRAF uses the IIS protocol to communicate with a valid image display server, such as DS9, ximtool, saoimage, and saotng. With DS9, no special scripts are needed. If you have one of the above currently working, DS9 works <i>right</i> <i>out of the box.</i> And DS9 now supports IRAF's new IIS image display protocol that supports up to 16 display frames. </p> <p>All native DS9 functions may be used with images load with IRAF display except for the <tt>Scale</tt> menu items. Values displayed may the the true values, if a linear scale is specified with the <tt>display</tt> command. Otherwise, the value is a scaled value. DS9 supports IRAF in all display visuals including <tt>Truecolor</tt>. Support full postscript printing of images loaded from IRAF is provided. </p> <p><b> Command Line Arguments</b></p> <p>As with <i>ximtool</i>, the follow command line arguments may be used to specify the communication parameters: </p> <blockquote> <tt> <a href="command.html#fifo">fifo</a><br> <a href="command.html#fifo_only">fifo_only</a><br> <a href="command.html#port_only">inet_only</a><br> <a href="command.html#port">port</a><br> <a href="command.html#port_only">port_only</a><br> <a href="command.html#unix">unix</a><br> <a href="command.html#unix_only">unix_only</a> </tt> </blockquote> <p>The default parameters are: </p> <blockquote> <tt> fifo /dev/imt1<br> port 5137<br> unix /tmp/.IMT%d</tt> </blockquote> <p><b> Configuration</b></p> <p>An <i>IRAF</i> image server uses a configuration file to specify the number of available buffers and their sizes. What actually passes from IRAF is not the buffer size, but an index number into this file. </p> <p>So when an image server starts (DS9), it will attempt to locate this file as <tt>$HOME/.imtoolrc</tt> and /<tt>usr/local/lib/imtoolrc</tt>. If not found, it will look for shell environment variables <tt>IMTOOLRC</tt> and <tt>imtoolrc</tt>, that contains the name of the configuration file. </p> <p>If no configuration file is found, DS9 will assume the following default configuration: </p> <blockquote> <tt> 1 2 512 512 # imt1|imt512 <br> 2 2 800 800 # imt2|imt800 <br> 3 2 1024 1024 # imt3|imt1024 <br> 4 1 1600 1600 # imt4|imt1600 <br> 5 1 2048 2048 # imt5|imt2048 <br> 6 1 4096 4096 # imt6|imt4096 <br> 7 1 8192 8192 # imt7|imt8192 <br> 8 1 1024 4096 # imt8|imt1x4 <br> 9 2 1144 880 # imt9|imtfs full screen (1152x900 minus frame) <br> 10 2 1144 764 # imt10|imtfs35 full screen at 35mm film aspect ratio <br> 11 2 128 128 # imt11|imt128 <br> 12 2 256 256 # imt12|imt256 <br> 13 2 128 1056 # imt13|imttall128 tall &amp; narrow for spectro. <br> 14 2 256 1056 # imt14|imttall256 tall &amp; wider for spectro. <br> 15 2 1056 128 # imt15|imtwide128 wide &amp; thin for spectro. <br> 16 2 1056 256 # imt16|imtwide256 wide &amp; fatter for spectro. <br> 17 2 1008 648 # imt17|imtssy Solitaire fmt w/ imtool border <br> 18 2 1024 680 # imt18|imtssn Solitaire fmt w/out imtool border <br> 19 1 4096 1024 # imt19|imt4x1</tt> </blockquote> <p>If on the other hand, IRAF assumes a different buffer size, the image will appear corrupted and DS9 may issue a number of error messages. </p> <p>Another problem is that this file must be in sync with <tt>dev$graphcap</tt>. If your system administrator has made changes to <tt>graphcap</tt>, they must also be implemented in <tt>imtoolrc</tt>. </p> <p>Here is a note from NOAO: </p> <blockquote> <p><tt>The messages means that there is no /usr/local/lib/imtoolrc file on the machine. This is created as a symlink to dev$imtoolrc by the iraf install script but only if the /usr/local/lib dir already exists on the machine. The fix is the create the dir and rerun the install script or else make the link by hand. Users can also just copy dev$imtoolrc to $HOME/.imtoolrc and restart the server to also workaround it. Note that an existing .imtoolrc might define old frame buffer configs which might confuse things, so if the system file exists check for a private copy screwing things up.</tt></p> </blockquote> <p><b> Windows DS9 and IRAF</b></p> <p>To direct image output from IRAF to DS9 running under windows, use the <tt>IMTDEV</tt> environment variable. For example, if the windows machine is named 'foo.bar.edu', define <tt>IMTDEV</tt> to the follow value before entering IRAF. </p> <blockquote> <tt>$ setenv IMTDEV inet:5137:foo.bar.edu<br> $ cl <br> cl&gt; display dev$pix</tt> </blockquote> <p><b> Scale Menu Disabled</b></p> <p>When you display an image from <i>IRAF</i> into DS9, <i>IRAF</i> actually does the color scale distribution. In <tt>Display</tt>, use the <tt>ztrans</tt> and <tt>z1</tt>,<tt>z2</tt><tt>zscale</tt> parameter to auto determine <tt>z1,z2. Here</tt> are the <tt>DISPLAY</tt> parameters in question: parameters to set the upper/lower bounds and distribution. You can also use the </p> <blockquote> <tt> ztrans=[linear|log|none|user]<br> z1=min<br> z2=max<br> zscale=[yes|no]</tt> </blockquote> <p>What actually is sent from <i>IRAF</i> to DS9 is one byte per pixel, values 0-200, which already has applied both the upper and lower clipping bounds and the distribution. So this is why, the <tt>SCALE </tt>menu is disabled in DS9 when it receives a image from <i>IRAF</i>.</p> <p><b>MSCRED/MSCZERO<br> </b></p> <p>DS9 now supports IRAF's new IIS image display protocol. However, there is one minor problem with the <b>mscred</b> task <b>msczero.</b> Before using <b>msczero</b>, issue the following command in the cl:</p> <blockquote> <tt>cl&gt; set disable_wcs_maps=""<br> cl&gt; flpr</tt><br> </blockquote> <p><b>IMEXAMINE</b></p> <p>Due to the unique relationship between DS9 and IRAF, if you use the <b>imexamine</b> task, you can take advantage of a special feature of DS9. Instead of loading the image from IRAF with the <b>display</b> task, load the image directly into DS9. Then, from the <b>cl</b> prompt, invoke <b>imexamine</b> without a filename. IRAF will ask DS9 for the current filename and use it for analysis. This approach provides several advantages over previous methods. First, it will work with compound fits images such as mosaics, data cubes, and rgb images. Second, the image displays includes true image data and WCS information, not the approximated data from IRAF. </p> </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/Makefile�������������������������������������������������������������������������������0000644�0001750�0001750�00000000757�11222765424�013326� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include doc : ref user ref : FORCE @echo "Making Reference Manual psp..." cd ref; html2ps -C hb -n -u -U -W b -x 1 index.html > ref.ps @echo "Making Reference Manual pdf" cd ref; ps2pdf ref.ps ref.pdf user : FORCE @echo "Making User Manual psp..." cd user; html2ps -C hb -n -u -U -W b -x 1 index.html > user.ps @echo "Making User Manual pdf" cd user; ps2pdf user.ps user.pdf clean : FORCE $(RM) core *~ *# distclean : FORCE $(RM) core *~ *# *.ps *.pdf FORCE : �����������������./saods9/doc/acknowledgment.html��������������������������������������������������������������������0000644�0001750�0001750�00000002706�12022177210�015537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Acknowledgment</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="sun.gif" height="98" align="middle" width="100"> SAOImage DS9 Acknowledgment</h3> <blockquote> <p>SAOImage DS9 development has been made possible by funding from the Chandra X-ray Science Center (CXC) (NAS8-03060) and the High Energy Astrophysics Science Archive Center (HEASARC) (NCC5-568). Additional funding was provided by the JWST Mission office at Space Telescope Science Institute (NAS-03127) to improve capabilities for 3-D data visualization.<br> </p> <p>If you have found SAOImage DS9 to be helpful in your research, the following acknowledgment would be appreciated</p> <p><i> </i></p> <blockquote> <p><i>"This research has made use of SAOImage DS9, developed by Smithsonian Astrophysical Observatory" </i></p> </blockquote> <p>or reference the following paper<a href="http://adsabs.harvard.edu/cgi-bin/nph-bib_query?bibcode=2003adass..12..489J">2003adass..12..489J</a></p> </blockquote> </body> </html> ����������������������������������������������������������./saods9/doc/story.html�����������������������������������������������������������������������������0000644�0001750�0001750�00000006025�11556324124�013724� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>Story of SAOImage DS9</title> </head> <body link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000" bgcolor="#ffffff"> <h3> <img alt="" src="sun.gif" height="98" width="100" align="middle"> The Story of SAOImage DS9: How DS9 got its name<br> </h3> <blockquote> <p>In 1990, Mike Van Hilst, at the Smithsonian Astrophysical Observatory, Center for Astrophysics, Harvard University, developed SAOImage. SAOImage was first implemented in X10, then reimplemented in X11. In fact, it was one of the first X11 based applications publicly made available. SAOImage was a brilliant program, implementing techniques in scientific visualization 20 years ago that are still being used by today's applications. Since Mike's departure from SAO, SAOImage has been maintained by Doug Mink.</p> <p>In the mid 1990's, with the administrative support of Steve Murray, Eric Mandel developed SAOtng, or (SAOImage, The Next Generation), named after the Star Trek series. TNG was based on IRAF's XIMTOOL graphics libraries and Tcl. It explored new GUI interfaces and supported a new external analysis interface. In particular, it utilized XPA, (X11 Public Access, also written by Eric) which allowed TNG to be scripted via a shell, or from other application.</p> <p>In 1998, while working with Eric, William Joye began a complete rewrite of TNG, based on the experience developed while supporting TNG. This project was funded by the NASA Applied Information Systems Research Program, under the title "Future Directions for Astronomical Image Display". For lack of a name, the new project was referred to as DS9, the logical extension of the Star Trek series. The name continues to be in use. Current funding is provided by the NASA High Energy Astrophysics Science Archive Center and the Chandra X-ray Science Center.<br> </p> <p>DS9 is a Tcl/Tk application. The GUI is implemented as a very thin layer of Tk. A number of Tk Canvas widgets in C++ were created to support all the functionality needed. Basically, all the real work is done in C++. DS9 inherited TNG's support of regions, XPA, external analysis support, and the general GUI. However, all the visualization techniques come directly from SAOImage.</p> <p>The current version of DS9 is composed of the Tk widgets created along with support from about 20 other open source products (including Tcl/Tk, AST, BLT, HCompress, HTMLWidget, plio, rics, tcllib, tclxml, tkcon, tkimg, tktable, wcssubs, xmlrpc, XPA, zip, zlib, and zvfs). The distributed binaries consist of a self-contained self-extracting archive and application, which provides an independent Tcl/Tk environment without installation.</p> <p>The first versions of SAOImage DS9 were made available in 1999. Since then, the popularity of DS9 has grown far beyond expectations.<br> </p> </blockquote> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/helpdesk.html��������������������������������������������������������������������������0000644�0001750�0001750�00000001374�11425634103�014341� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Help Desk</title> </head> <body link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000" bgcolor="#ffffff"> <h3> <img alt="" src="sun.gif" height="98" width="100" align="middle"> SAOImage DS9 Help Desk</h3> <blockquote> <p>If you encounter any problems or have suggestions with SAOImage DS9, please contact us:<br> saord @ cfa.harvard.edu</p> <p>William Joye<br> Smithsonian Astrophysical Observatory<br> 60 Garden St.<br> Cambridge, MA 02138 USA </p> </blockquote> <br> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057631�012626� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013377� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/button.png��������������������������������������������������������������������0000644�0001750�0001750�00000003065�11332353405�015436� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��j���6���øc"���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚs×øó��ÂIDATxÚíÑ‘£0Dmà ’C C;ß{* „H=⽟ó±Þ¢§53B‚µïŸÏç���Ñô}ÿÀ��€Tî¿ß���’èÞï7.���¤­>¹÷ ��Dß÷Ýø‚šï÷«#Æ„°Ô*ë·è¤]ÍÃ0˜Pûz½L×—‰$±¢°›þ§"Ã0Œy© Æ„°Ô*ë·è¤uÍî…ò‚Ãk±¾L$‰!…<y �� Ó'���Ó'���Ó'��€ ]ê/<ŸÏé?ŸÏxDí`œª©¼ŠR5]š©¹¿bòºªluKˆûl: Èá“ì:ÖØ®ùAQK—Áj�rø¢«O·Fy>Ÿk‹ÎéÚôì ðžk©j¶ uúËÌFEðTùÚùì¹mmL—¦M%MÏ^—Oƒ¥íkQœªd¹+NÑTKËQÒ˜Š~¼¼2¹SP›[K| ²¼¯«7µöëÕpˆ‡ ÷>Ý ÖÎät,==Ϧ鹼9¯¿ð�p)oL§sªWêØî§­ß; Åt×CÞs…z “.ä˜M²´JÅ©Ná§Ê+S}á‚ w­°x…’1"eú@Œ†¶ùèPÅ Ò;~I¿µv%U8Šå|`t¸K†`q'|Öe–i°öS…q߯ªLh1gI•QfD’ZSø R°íïÖT%+ß"Êʽ+Ñë ÝK·ìÎ3ëo¨Å¯ÒÖ¯PI©e·Óv¦Û‡f«÷aÂyc¢É®ÝÞhl¹øÅœÛ6 <“ <íBid¤–i·ÏÚ¼uóG™¶åÝ[ÐïtSå³û^m<[& FÓè¶mXvÆðÕ-|Ó¥!K|krA)¬;cRe§ç3\.`œ÷\ÓaÞ̃ ç=‹Î¶F’ÉñkÐòê\m<ÿ³™¢ ‚ã†3A§ð½t<ÏèZúíB6Ïc4ìl]† ÙkïÁZ«ò¥*o-•—ãR'Ã'ÍûiyñÕ33œáƒmÌ“AD³‚àÈóUw ]¢zJ¤JÝ£“í�¨¼caú�¨†¡»90£Ã�€ê3(˜óœÕ'���Ó'��ÀùümÞà£IJŒ a ¨UÖoÑI‹šû¾ÇaB0¤ðζ;��@êÕ›·���Ét·&v!n·Ûëõº)íÿ|¿_ô aÄÕR ­æXžÝtî1½ŽãqÕeg)z‰{ÄÕ@ ­æX¶lÞ��$Ãô ��Àô ��Àô �� Ÿy+ŠÚçG{õ˜©<²ËoÍl#¥âÚŸÍ|w½‰(6¿Â]' ¦O€¢¸Ê_~«¶ì—!ï¹>ÐŒ ô ¤ýÕ§+•ÍSkfW"šK–¡ûE6¶*YºV®šì¬Xs`|¡Ù£âê AÌì°–r‘£¹ÜæñÎ>{xè…w˜Ý{–»Uš¥%¥ÓU¬²q‘²¨öE1FYñ6O¹÷ ÍŠ?(x•–‘rRyØÕ–Š‘Œï-éšÎjª¼zLˆ_ )lrÆœÝûžQ¹¸íÙÑÙ § ýÙ=g:Ëœ´÷Ó•qGù²Ô–H`pu\R[@ï—<)<wš6¼+ï×ìÒ@¤êÖž‡„ö*Ž-·‡dî)¡Àí4š�]w“Ç.ļ¤4½fZ»9aÈO2ðÀ°»îÌË ä¹x&GÆî&æñæÂṺkúœŠÛ|ÏRºTÉ-oA)d§Î½á€5‘ñˆ°Ô˜µ7;º›Ê½Ol*ÜœŽqÛʦzv×ÉÃt‡ÄŸz$þ§µvrteÒ™8.©‰Ô¿P©mv\ÿi²¤¬O¡x·Sûp-ý“í&&ÏĽ¸²g‰Æ6��å˜ÍÛŒ%sŸƒ��×äøÍÛ³�ÊCÁ¹ú��`ú��€(þ6oû¾o&¤aÐcH"¯éÞ•ãj Vs,‰;·4���’èûþþûý0�� ‰îý~ã��@ÿ�G“Ruîj©����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/vertical.png������������������������������������������������������������������0000644�0001750�0001750�00000624276�11332353405�015751� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��4��˜���ë7õÁ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ1®Î…f�� �IDATxÚì}wœåýÿ3u{ß½½Ý«{…ëwMàŽ”(!¨‰ý&‘(ìðJ~öÄØbÄœ-EAÄØÐ(Šp´ãŽãz¯»{ÛûÌüþxàqØÝ[öŽ"1ó~ñz±73ÏÌ3Ïó̧=Ÿ‚1 óÍ¡†5ëž @Àw§þõŒÉ%Øîº#O¼úÏŠ™ó„ @€�ß9ö~õÉÿ¼«¾êæW_ou #"@€�¾sX‡ú;ë÷��–e~Ÿ0"ð=‰DÂAŽåN{%†aE“5îV4M’ãnEÒ4ARè˲���À±lÐïG'ü®1JD ˹‘H¦Ž½]Äï£L,S…) @€€ ,Ç}1…ÓuÚ‹# ëò8%2%À° Ï#¦š"“hŸì.‰L1ÞVN»K"Sà8pß2'À1,ó-weذ»¿²x †a»ë;ü8AФ§²ß48è‰(³ù  @À…‰pÐ/¦ ƒ^OÓôéu,†Á¬V߃ㄘ&Sô:*™V‘f³yü›H+‘D~‚9îs‚ŠºT¢Ô…¸pOß@Ia~žYu¨£ÐçàºzÅdÐ.1ÊÔ)ü† àÂDZ‰\$%s1I’ ¹Üíõs&•Hé$[Q”¶ÂÇÙJ&s{ýˆ›ÀÿH��0 ÃÑ¥ÓªÔ†Þæ ï L.Ó«½Ož’ ›ø¬ÝiâHÛHD•‘É·~¿AøªË&e·í=vðx°Ððß Ã1 K^À0 Ãð ¶Âq ÇÇÓ >±!,¾æ� HJn.hhúA:İ,Ǹü"¹TpÙ ”§¹k@W0‡ ÆäŠI”åš/Uœ¢UC̠͹ù«C݃£Ç�ŠsL7^9S*¦?ÜQÿU]s(�ÐqQ‰eNežN%÷CGZz¿Ø×dwúH_·j‰?~ç“oZ{G¾«yÅqÜ V¤éxÄò{ERyÔ"šœR¹`F¡Z!évlÙq¤½ÏÊ&±(@€�ç‡9ø/Ù'Ù¯Õ½7^JÄc9/üãk—7p 䵺ÿ¦K‡íî [v£ë—-¨ÌÏHyþï_¹}AÄÓ¢Øy‚KÅ<')uÞ´Þú/¨ˆ—ã�fY&, ôZ‡Ô9³Zœà¥ÒÚ[®®ŽDÂ-]ý,Ëf˜ 4ãc˜NÐR1]l1¥êU€Ešº£ÀæH‚¼fÁ”ËgØ=ýZµâòY%9fí†-»žR.Æ<Œ×9‚ƒˆJ© …#8Ž8E–•ŠiŽã¡drES$†aÇ…#L fYÇ11MÑ$aY–åh’ð‡ÂÁPÃ0š"D‰ãÃp¾`ˆaØS˜4ŽKDIâp¦��˲KQ¤˜¦aÙ@0\–—~óUU½;÷µÌ(/øÅ5sã“a‡_ø$pa0§|#ùë†S5'¹„v¹½QW*²®¦Cڌ“<a6X^FÊ-WU½õé>Žå–Ô”W¤»ÜÞöÆ)–R��Ô´¾eCbN§šõ¾U€Ä mîtGó.Œ úC ìgE4ZLËTØØìÇ1µ\*•Ð_îj¨ÝüE�ÃBÁ�-׉H±Z!+É1[Gæ0'C#;`u‡tjù¥3І¬£Ï½±éPSWšÉ¸jùeÓKór ²CÞà‰ûr ¦2ïæ¥hê–Šét£fw}ǰݽ`zIâÿ§á«-á»xNyyžYB“I´÷Ù>ÜQß9`Ï6믪)Ë5ë:l ³ï}Q÷éÞ&£Vuñ´Iùf1Exá­;Žî;ÖÅqßÎMAVÊÒyf½ª¥gXDŸ°a’$9«,÷’21Ž0v·oÃæF Ë2»ê>ø÷>¹\>ÿ¢²üTŰÇa„ðU àÂ0ëÇÔ†ã†ãØ):·Ç¿ê¾'DâS\ä[ý³“š8aÓƒmN¶zþï_ÿßÕU¹éúkçWzüÁÊ‚ôÁaÛã/þÕbá5È„׬‡Ç{ Vè)µÙ?ÜÎḄaR¡Rqü4Þ£n_ÿˆcJi¾N§íqµ÷ŽïôøCN¤êT©šß±Žº–,œUh1u[Û²Su$IØ>¥ÞÄ$ý6o0±¤é÷罹VNlêÐ*Ä ¦M:ÖÖ»ïÈñª)Eå9)õÇ;A‡'ðÉö}·§¼À²pÖd§Ë58b›39·Ä’ºsÿÑîþ‘Å fr,ësraßìòÊySò¾9ÜÔÔÑ»hîôë.ŸÚÖÕg÷F 6ªŠÎ(ÌIÓ¾³nÔå¹jáì`(�Ð*¥•é±í?FÝ^F9j´;Í�%ùÙ!ŽÈÉ4“ž–¢ ÖµJä øŒ àМ�†a8žôõøIç·¢E’ì¢Éü+E)��à8àµò‡"o~¼ïG +‹-©�€®ÞÁ?Õ¾o÷3'•ÁkN*ux´Y‹Ùs:¡«p\Øç`ü–Ki‚&0&âe‚>Z, Áõþí³ýÅ™Úbfqæü©“¶î8²m_ MSåùæP(ÜÞ3Ð58:kªgZiþ×u­qǰ,†´HJ$p�’$BA?8uãæ?u ›¿üÆdÐi”òÏwî¯oéÉ0dbŠÂ–‰´õZdP¥{ý!’ÀåbR+ÅSÔr·×·ùóÿt¸s²2¦•X�”RQzŠÀáó‡LMNªb¨iI�)Z…V%uºßÙúï GOÊÍLÕ��‚áȨ˛¦W˜:‚¢»FB 8ÚÖÿuÝñÌÕœÊ| cÃ�À„ƒ�¸ÀœðÝs§SMgÉÚq�í{H¥‰· 5-h:PE;õYÁÓ;âLOQ�ºû#e²'#®0ü„ýgÕ;¹çËN9ÀE|nwo#‡áªŒÖÙïöØXÆÅô%%3i±<ÁKáÞ3ì<ØÐ¢’Ñs¦]1§²$Ûð¯íuuZy®Ã@q^VzšI*¦5µI'´9YŽS)dÙé©£!L!—u š$zú‡ÙS7��.§$,F°�X.J"ã0Ã0ŽcµJñ峊òÒtG›Û!KÀ1 DZ,Ëá)Uh±“†'ø;Žõ’$z;{û­öÑ ßK‰¥H™ ‡#NÈd:†;©ØzÛ¶ kåâ)EÙ g—‡þñűîÑÍ_VÒ,Žq f–§´ÝýÃ,l àüó& Ãð¤ÉŽC 6Âù¼)îM° Ë(’X8½`zQF{wŸÏ˜3c²ZgüdoÓ o¤9¡Ûbßšõ0¸Û sbXßÀ1&èVdV*S2½# O÷aœó~«°™¶LËv‰̤W^9»¸Øîö²Ì:Š"íN—ßãÌK«Ðª¤n/Õ M€‰D8�.*ÏûÇ—G5÷[RoX2¯sÈiÐªŠ²½ƒ#Z±ouŽã0œ€ Çœ OògN§’e¦j&²ûà±|K¼Þáö Û]YÆËk¦ »B…Ù©'˜œ7Ð?â,Î6º<¾ÖžaŠ$MzµÓþñŽÙ]~‡Û_˜e¨™V�¢ÜtË„�2‰È Uº}!»Ãš¢Ë0”"\Nc³* Ün·J..Ê˱;k#(êć!@€€ïÚ¬wŠ»ö•³‹âúÝ}¾¿Å óMm1·…ûFø·Þçø){H‹«J&ç›»ûÿü·­”D)WiËrM$IlÞ~4Šœ`l8E*ÇÜs ÛÛ%¬‡IÉW¥Z’’³¹H@’‰÷»l=RCöX£a8šÄ¦eJ%b�¸–Žž·íf�~QI¦×Øúï½{'Òœ¢½nñ¼å…ûdïûÿ>4<œ^Q˜UmŽ0Ls{ׇ_ìéq¨ iñTHŒ§e~»íÖ?âljï¯,ÈX4oF¿Õ ]ï¼þàî#íF­bfEaWÿHßàH~V*ËqPxOC‡„Æ&e¤æ[2CáˆuÔéñùIŠÆqÃp·?ôõÁ¹˜X<F×ШÍáÒ($��dzSu¥¹&šÄÅ"ê`cÛ¾ÃM*­¾<ßlÔ(Hïþàó6·\oÆ ÃÍI€�ß9sÂøº)“ÒH"izwÓÇ’”¬T'šo[IÄ¢»ÿo¹T©â7Ñ«d'XÔ){Nß¶ªÈ3 Ø_zã½ÁQŸ);õ_»›–Te¥¼Úݬ4å@ûRìžV}ÕÍ/¹®ØÎ?tê"ý#>uÎ4ò¤×8 �{k®AD‘øˆ+0Ä¥ˆ”†¸£@à˜ÝVŒc™HĺŒD¥Ë4]ÖÞ»ƒ%$´DF“„V) {G»z‡´y\D‚ápØyC-S‰¥ŠÌTí`g“Íå3˜2"¢³£ ˆ599Ÿ­·o`XªMMÕë<ö«Ã-Rêu5t|n_Ñé4›Í` ¦L Ø€ËãñÜvýUŹé/½óѾ¦~•ÎHca<â‘P8†§?,פХ2 '��(ÆË=Ÿ¢D‰Ø¤Tm0èAÐ ú˜HÄ뺃¬&Ŭ‘KB^{$ô‚ž�CËÔb©‚I„$øÎôyÔJ™N§…¦¨$u±—u÷L‹á¸Çãé´¡QÉ´ZÔJÜÙx N«¾¡‚éó0 s»=ƒÃV '´*¹V«A­ŽÚ;ê gä—R"1�@£X»Ž·´¶Θ�æv»‡mù žç²w7ìç xô¸cÈæTåÌ$E’oYŽHV["”3?;Uërc½ö‘ œ<Õ§ðã€+ÀÂÇ1�ИX&“à$-¶ºCž�N) $%¢Dœ œÁ°×‡)S29Dp‰×ÏFB †S˜X.•à-&Eâ~›Ç¦Ä*£?‚¹|~Bn i±Íå÷x9±:'E6w0¡i…ޤ%¾0ðû�ËHp9âaR!SS¥yi¥¹iÃ#6Z^Qd¶nl#(°CáH„Å0£q©4 Nnå1F(_�ÇqE\ˆ%d:’»ýL(À± #D@"—Ë@Ð?ðã�H0‘L*Æ)š&ER3  à‚�~JÄÒˆË/2æÅ^•oÌà ™éþt¢•30f+‡áï>¡VÊŒ"†£¤BO�S™ó§¤Bm = Ä@\o½ ÇÞãpŠRËi±,ª´TÑበê üÁp$,"’¬¸ã@Ò"9'…„Jo:e¸D„Ú`FJê¸cªII‡?ÅREÜ[Ñ’oy¤\­‹º?‚É%TÉ´ÂËì¬küëûŸºü!R†ãNR¥&Á„R"±J$Ž{<ÞA‰ð  àBäMÎÀ}Kí1rì\ 'ܧqÃq–ã¾m…¶‡'׊ èo[q,†ñ¼õNÝsR¤X@Še¬Ç‹ºÐá�H�øo¡ÄŽúÆf§mˆ‰„p'ER•ÞLÒbœ¤½F€�ÿ  Db§Óƒã¸L*=íÅ¡phhÄ&–*0 uzp—&Ó*4ÁVÃ#v±T'Î �ì{o}’(4$-†Ì�`8IR”H°¹  àI‰d ‡Ókužöb ÃÅ2%,(–)F^[r­$2%q­Ð±o5'€aË2Lø{;3 Ä§hzßç— @€€¸ú“Xœôµ\$o+îÌZ…á8/·8ŽM×IËsS…É @€�ß Ž´ öÚ}ð÷ ͉cÙ ƒòê¹åÂè @€€óööö£Ç\‹ŸÂœ‚Á`$†I€�œ7ôõõíÚµËnRŸ91  ›1 àüÁáp8�¾_"“jg³a­­ µkiÁZ[ÁÀ�óÅÂh  @€€s„DÌ Û±{ë-¬µFJ€�œ7$ÌIÊ0˜Ç\.a˜ @À…œ¸yó˜7ßd¶og~óa¤ @À…¡9AˆÅܲeÂH  @€€ ‰9�hZ)pÞ@N¬Ù¯~õ+ø£ººZ&“}úé§·Þzkqqñ™t¥££ã÷¿ÿ=ÿÈý÷ßo2H=~èС7.Y²dppð›o¾Y»v­N§»ë®»rrrî¼óÎäŸ …î¾ûî¼¼<ô ýë_÷ïß�‰DO=õÔ9î?ÿùÏDÜ~ûíßáôßyç,Ë¢?—/_^UUõôÓOwww?÷Üsg’{ð?ÿùÏßþö7þµZ½nݺóü‚_ýõ{gþ|üñÇ“ÉD �øàƒ¾øâ‹;î¸cÒ¤IgÞ/¿üróæÍð÷C=d0DBûË_þràÀ‡~X¯×ŸÅ×ôÑGíöoKµ]zé¥?øÁ’ièv»xàâââ[o½õìÎ\?þñgÏžýÔSOõöö>÷ÜsÝÝÝO?ýtuuõ~ô#�À+¯¼ÒÐÐÀ_3;wîüûßÿŽnòÛßþV¡PŒ÷Ñ Ã¬^½Úb±¬^½:ùV÷ÝwŸT*}øá‡“¼þ…^hnn~òÉ'ÅãHôß„þþþÇ|æÌ™×]w�àõ×_?räÈc=¦ÑD—w€§Ö­[§V«Ï™æƒÅ'QVVvøðáÚÚÚ¾¾¾3|ç‘‘‘ÚÚÚ‘‘tsþúëêꪭ­=zôèäÉ“/^,—ˆ©­­ýôÓOÇõ”H$ÕjçεµµS§N½âŠ+Îõ¼nß¾½¶¶vÆŒðgΜùÝ®³ÚÚÚ;vÀ΃Á5kÖìß¿Μ9‹/>ì¸YYY‹yزe ŸIœìÙ³çÞ{ïeöáßÿþ÷Ï~ö³$Û8p ¶¶vppðÌ»±sçÎûï¿ðŋïß¿ÿg?ûY0Œ»0Ün÷ÙM›6mÞ¼}M?üp’ß‹H$Z¼xñE]tÖ'¥¥¥¥¶¶¶¥¥�ðÑGÕÖÖ�l6[mmíž={ gzúé§KKK¯¼òÊ×^{míÚµûöí»çž{B¡|‘;vÜtÓMxôÿýßÿÕÖÖþñ|öÙg“oõ·¿ýmÓ¦MÉ_?k֬ŋ“$ ¾§­­­Ýµkü󫯾ª­­õù|±WþûßÿëÔ9dN—\rIzzúúõë?þøcþñ«®ºª¦¦¦¦¦æ˜Ø333/9 ¹\ …jjjøêÅ–-[Ö¯_oµZøÃ�êëëyä‘äï/‹ß~ûíÇ?öØc�€—^zéóÏ?î¹ç¶nÝúä“OB­æ$¶mÛ�¸þúë!ß:xð`MMÍK/½�xì±Çjjjz{{'ðŽÕÕÕð9Ž«©©yå•WþøÇ?ÖÔÔ=ztùòåðÑwÝu�àÍ7ß|ÿý÷zè!xÐf³Á?þ8¼Õƒ>,Y²db®T*agrss;622²aÆõë×ÃgÝwß}~øaMMÍ–-[ÆuÛôôt4ï¾û®ßïï½÷Ž;†Æö£>Š»f^ýõýë_kÖ¬©©©™?þÐÐ<û‡?üa¼¯644tüøñüü|´œ¶oß× êÆgŸ}/^´h<òè£FÝçŠ+®€§àš<ø‹_übÊ”)=ôÐ%—\òæ›oþ¿ÿ÷ÿઆxùå—ù×{<têOú�à‘G©©©éïï¿ä’Kn¼ñÆñv€¢(øú%%%ÝÝÝ�€Ûn» >båÊ•È~PSS³cÇŽ[o½µ¦¦Æív¯_¿þwÞ�¼ñƨK###v»½¦¦æÞ{ïݺukMMÍ|p ߯Ÿ|òÉ5kÖüä'?¹ì²Ë>û쳕+WŽŒŒ;v,77¾ˆB¡øúë¯'pó]»vmß¾ýw¿ûÝáÇ�¯¾újMM;}ûnºé¦… "R‹^T àšyþùç៫W¯®©©ñx<}}}èz8\µµµëׯƒ½½½èÔ»ï¾û½·ÂŽŽ¢÷ݰaÿÔ¼yón¾ùæÝ»w×ÔÔlܸñÜšõX–õûýõõõÓ§O×étˆÊìÞ½»¡¡áðáÃ7ÜpMÓãbÇ1 QUU®¹æš›o¾ìé驯¯¯½öZiiiaa!¤ãÉrc/((ðz½ð+t8‹¥«««¿¿¿³³séÒ¥ÕÕÕÏ>ûìã?~óÍ7ÿãÿhmm`YÖãñÔ××Ï›7㸮®®†††P(4±ÑcÃ0xÃuëÖa®¾új—ËuàÀ®®®þð‡EÆgŸ}öÙgŸýÕ¯~uñÅ_~ùåÿú׿vìØqûí·‹D"·Ûýúë¯×ÖÖNž<¹´´tÉ’%ãe!üç8Çq ÃZ[[ëëëÃáp}}}ss3˲óæÍ»ãŽ;ärùüùóÇû¦«V­ÚºuëW_}¥V«gÏž=uêÔ—^zéøÃm·Ýöæ›o>óÌ3Qk† ˆuëÖ½øâ‹÷ÜsÏÌ™3—-[öÞ{ï}öÙgkÖ¬‹Åã²2]~ùå=ôÐïÿû—_~yÆ ~ø!Çq===K–,™5kÖsÏ=÷ôÓO¯Zµêí·ßþío[__àÀ¨ÙмMÖ+®¸¢¾¾þàÁƒûöí[¹r%MÓ÷ßò}ðx<===ƒÚërrr��$I~òÉ'[¶lyøá‡% _î‰DüñæÍ›}ôQ‰DÒÝÝ )£Ãᘘ ç—eYXœôŽ;îxï½÷>ÿüs±X\]]}Ë-·\qÅk×®½ûî»kkk7oÞ‡á짦¦þóŸÿ|àÖ¬YsÝu×]{íµ³fÍÚ¹s'Z_|ñ/ùK¹\¾`Á‚$;³|ùò¶¶6Žã8Žã¯“ <öØc/¼ð‚ÝnÏÎΆcRVV�ÈÈÈxì±Çžyæ™×_ý•W^yÿý÷ùm“7ö8޲²2¿ßÿé§Ÿ®_¿žã¸úúúåË—¿óÎ;?þñçÏŸÿÌ3Ϭ\¹rÉ’%<ðÀ=÷ܳlÙ²Ï?ÿ6÷ù| ³gφ=oooohhðz½555‹å­·Þª­­½ï¾ûäryGGG}}½Çã™;wnNNΛo¾ù׿þõÞ{ï•ËåIÚTÿ+À'ÔhéjµÚ>øàÿøGÔª®¯¯olldYvùòåðÔŠ+Ρæ—s², …"‘H0œ˜âí·ß®8‰––›ÍFÄüùócgÈ)ŠR*•ãzI’|˾F£‰Dè3v8ð-X–u¹\ápxïÞ½,ËòMp>øà¦M›>üðCHkÆ‹E‹UTT,]ºñË'žxÂjµB®€aX$ …B.— R7‘Hd0‚°ÛíƒA­VÇãñx`.DØ[þîBòhjj‚£ýâ‹/>øàƒóæÍ‹yž|òI™Læv»'À‰W¯^ýÏþóóÏ?/**bYvtt”¦iƒÁ�o áš1 ­·Û-•J †a‡Ã`0(•J¿ß?^Ò,‰~ó›ßtuu]sÍ5×^{m~~¾ÍfƒS ‡ô‰'žèèè˜5kÖÖ­[¿ùæ´t=º‰Ýnç¯jþ© Ãjµ’$i0 …Ïçóûýè”Ífƒ§”J%ÿI’}}}ÿùÏÆû,‡ÃQQQQPPðË_þrõêÕ·Ür \Õ‘HÄáp¯×«P(^}õÕòòS²?ûý~xÊ`0$i³Ùàñ¹sç>õÔSX‰D&“­^½é¬ .¤iz¬m$‘Hô«_ýª««kùòå+V¬ÈÏÏï8Àyìëë³Z­üyܰaÃE]„a˜Ýn¯¬¬lhhX³f ü J4zÑEmذ9~ñ‹_lß¾}×®]*•J"‘tuuÝyç+V¬hhhX¼x1ÿM;;;W¯^}Ýu×544|Ÿ8�`óæÍn|q2[Õjå8. 1 ãóù�ÿú¢¢¢?ÿùÏ …ÂëõF:ËšÓ_|qàÀ¸’2´<L:533sw¾þúëŸxâ‰s:¬™™™o¼ñÆÓO?]WW744ôÄO̘1#j¯½…\.?ëøä“O²³³¡ �pË-·\ýõ�€ãÇ_}õÕ&“)vO"{ì1¹\^QQ11NYTT$O>ùäºuë ÏÖkö÷÷[­Ö¼¼¼$}Î…¡½½=--íw¿ûÜk¼øâ‹wïÞ{eccãW\‘ŸŸW¢ ƒh=¤§§'ïòÉ'Ÿ j\P«ÕGÝ¿ÿ-·Ü288822‚ä‘H4uêÔüüüóü.&“I¯×·µµeee‘$Y__/•Jsssð×¶¶6³Ù¼nݺH$ò—¿üeÞ¼yV«u\]~¿¿¸¸ÎcNNÎðð0_´Gjîk¯½ö§?ý)##£³³3ê¬F£ÉÈÈèëë³Ûíùùùb±X,=z´¾¾þÆo,--ýùÏ~ï½÷"ÎtôèÑ#GŽÜtÓM¥¥¥«V­ºçž{´Zí÷†9-]ºô…^��Üpà ÈDßÕÕ…¾”3wí9Ë»v8ŽoÛ¶ÍápìÚµ+++ë,R™¸¼I^£££ãòÔjµ‡cáÂ…EEE±vü‹/¾øõ×_?vìXGG$F ,Ø·o_kkë¢E‹hšnll¬¬¬<ëKí׿þõààà¡C‡ÚÛÛgÏžd«çŸ~úôéüñ¹à£Fww÷£>ÚÓÓóÚk¯ååå}'}ؾ}ûM7ÝôÈ#ÜyçO>ùäŽ;¢(NSSS{{ûŒ3V®\‡·mÛ¶{÷îE‹EÝG,oÛ¶Ín·ïÙ³Çb±Œ«(Ë2C�� �IDAT:nòäÉííí‹eÏž=v»=Êr0mÚ´{î¹çöÛoŸ<y22QÆmÛ¶ †ææfx°®®ÎápœëÎÜxã|à¾úê«òòr­V[YY¹~ýz�À¤I“222öíÛ7sæL…BññÇ«T*§Óyýõׯ]»vÍš5¿ûÝïvîÜÙØØ8®'Þwß}mmmð›Ý²eKÜÝ»†††uëÖ­ZµêñÇ¿í¶Û¢6ŠæÎû‹_üu7oÞœ••Å0̧Ÿ~ªÑh^z饻îºëÕW_:u*²Áüë_ÿÒjµ/¾øâ]wÝõÊ+¯L:uÙ÷=`4//oÛ¶mp祤¤„ï¯ët:÷íÛ÷1§«¯¾º­­mãÆ]]]|ðÁÃ?\RR2Þ›466¢³¥K—®X±âÝwß}ë­·Ž=u%AË–-Û¿ÿ»ï¾›““3.æTXXxÇwÜ|óÍ+V¬à³¥R¹hÑ¢ööö7nÙ²ð‚‚N÷ /dffnÚ´iË–-Ï?ÿüǼaƳ¨d@üà?hll|ã7"‘Èå—_ÞÒÒât&*r<kÖ¬Ï?ÿ|ëÖ­õõõ?üðêÕ«çÌ™3Þ‡Úl68à˜={öÄôݸºõ¦M›–-[vàÀ(X„Ãá%K–À±=tèPuuuFFÍdeeÍž={¼t',ËÌ™3÷ïß_Ðáp¬X±B¡P\yå•7nܺu+˲ùùù?üáŸþù7z½Þ‹/¾¸¡¡ x“k®¹žjkkûä“Oyä‘¢¢¢äûP\\üÌ3ÏÜÿý>úèܹs_|ñÅ)S¦üèG?úôÓO7nÜXWWWVVVRR‚¾Û+V|ôÑG7nÜ¿yyyIIÉÞ½{Ïî2[°`ÁÞ½{ÿþ÷¿SõÜsÏÝwß}S§NݵkWoo¯ëÔteS¦L®YV«õÇ?þñºq&Æ5×\òìúõëY–5™L>úèš5k,X0{öìÀy´ÙlÉìXL�F£qþüù™Íf³ÙüþûïóÍ%%%åååGŽA†¢Í›7×ÕÕÝ~ûíùùù2™ Éa ÃlÚ´éÀð”B¡H ~?°bÅŠ/¿ürãÆ{÷îmnnþío¥•~ôÑGýýý•••IRN"³pŠ¥°Üí d•éáp8®X‡¿úê)æ»U«��*•ªºº://Ïb±TWW/Z´H,»\.𦝹æ´§’$0 S«ÕYYYþ“¨¨¨X´hQ86?ýéOSRR E+,,¬ªªR(sæÌ …BùùùW]uÕx‡Ã0£ÑX]]––u¾éÓ§ÏŸ?ÆŒÁ`Ðï÷gffÞvÛm0ÌÃ0š¦çÌ™SZZŠãxFFFuuõôVÇ‹‹‹«ªª` †aZ­¶ººj™3fÌÉdN§S¥RÝrË-Á`055uΜ9ÕÕÕ:Ž ˆ3f̘1Ã0NW]]}Ùe—™L&·Ûí÷ûçÏŸÿë_ÿzÜŠ3IVTTÀÑ6›Í?ÿùÏËÊÊp¯¬¬¬ªª’H$sæÌ)**Âq<;;»ºº:yeÇq³Ù¬ÓéÐlÒ4}ÇwÀ±MKK[µjUIIɬY³¢Ö Žã‹¥ªªJ£Ñ1sæÌiÓ¦á8n0ª««ÇeU3ÅÅÅpçÆï÷WVV®]»V©T^tÑE°·Ýv\NE¹ÝîÔÔÔn¸!dddÀ‘_´hI’n·[,/[¶Œ¿©¼«°°v£´´ôÞ{ï½òÊ+Ãá°ßïW«Õ?ùÉOæÎ‹ãxQQQUUÕå—_Oi4šŸüä'555Qkf\@k.6“ÉT]]}ùå—kµZ—ËÅ0Ì¢E‹V®\™––6iÒ$ŸÏ·lÙ²;w Ü{ï½pö/¹äxÊï÷———ßÿý"‘zRã8ž••UUU5^+Žã“&Mªªª’ÉdAÌ™3§¢¢1€””·Û.¹ä’;î¸#%%¥¤¤-¤É“'¯]»–¢¨qCYYœe8)))sæÌ™3gNUU•Z­†+mÁ‚•••ð)K–,)))q»Ý³fÍš3gT‰²²²ºººŒFãÒ¥Ka+H‚ü~JJÊÊ•+§M›FDyyyMMͼyó¢N}?˜†aöBNŒãxIIIUUÕ¥—^ —®V«ýéOZUUE<õ‡?ü!//ï‘GºñÆãš…l6[OO3L‡piÐïu÷bÕWÝ<ÿêëû‡Gg™¶x¦Ïç‹»½IžTW!"uu@€�ß ìÙ³çí·ß^¶lÙœ9s.\XWWgµZ‘î(�᫯¾zðÁùË_._¾\q·KKK�477ïÚµ«Û's“:—}¨«~) œ�ÿãÈÌÌ ‡Ã÷ÜsOFFFkkëË/¿Œã¸0,Qؽ{÷}÷Ý7mÚ´šša4Îæ$@Àÿ:Ìfóc=†ü³ ÏéÆÒ)Š‹‹_{íµÔÔÔØìSã믿ž€QZ`N�))))))Â8$€J¥‚AÁÆ‹ÒÒÒ ´”wpÁA`N à¿”9Åf²n+ à¬2§ÑÑè#ç>Œ\€�üÏ"‘C¶};vì°Ù0^}<bÕ*nòd ÓqEEœàX)@€�Î)sjkkƒµ$��¥¯½¦#— ÖÖ†µµ�lÅÅG…`=pˆMÕv sjjjúæ›oPbæ– @2eZZZ„‘ @€�çDsjim ø'\RW€�8ûÌ)àä”åL,ZJÀ€ã¸Óélhhà—1p&Éd›6mºûî»ùåûÃ0XV• ˆÂ†††ØkfÏž ÓrŸééé>Ÿ/ªê£V«•H$}}}�€ÊÊʦ¦¦@ �Šž~Z”––ÂZ¢èHFF†ÇãuVÏ[Ÿ èõz½^üøqŽãrssN+òJ¥ÒÂÂB«ÕŠöøsšššÚÖÖvNW¹\ž’’ÒÞÞ~†CwN‡÷ìB©Tæççà ѨÖ×9d�@ff¦Ó録ãav×]wULû¦y8š9�H’‹Å@àü×›ù$£A‚ ÔjµH$âïü3@( ƒ‰Ã0¯×›¼ ++Ën·»Ýî²²2XœÇqÇQ T��ªÙzZ455ÅäÏݱcMÓõõõ …B§Óŵ‹‹={öDiiiaY–Ï® ŒF#˲ˆÐÐ4›Ê¹   ££c¥“EQ‹%--­©©éðáÃÉ4ñx<ÃÃÃ��“É …P½]xjhhf¡M†.Å}ßÓ¢¬¬¬¹¹Ùf³ F½K8æIKKóûýQòŽãpØa ¨âââãÇÿWPQ Ã:;;»ººÎ¾ÞC’üõ)‘HÌf32)ŠŠD"ˆè©T*•JÅqIq4'„;w’2C\zé¥ü¬Ï@`\ÕoD¡®®N¥R¡JzÉ}–õõõð‡B¡P©TƒƒƒgH»1 “H$>Ÿ$I‚ Ðüfgg744@þ—$gŠ ƒÁàõz£Ê/�¢J˜[,–ãÇC:‹a|)x$ЦsEˆD"EQ~¿ŸOpù7ä#‰8NŸÏ'‰†á³ùÓb`` îq•JED2¢=zßqáèÑ£%%%>ŸªM4M³,‰D²³³ÛÛÛùoÝ××'‹ ‚à„æÑÈŸ•šd‰gä¬ÈÇ^¯×ívGU†ÇÏüþ)))'‰øý~Žãü~?_ýÍÉÉéëëCr[¬"Ær%¿ôÒKëêêWz'IR©TÂß^¯}{F£þðù|èµáÚ‚_,b{.—+±ùE§ÓÁ‹Ãá0Ud2ªWjºÄ}V$AŸ®\.§i:êþ@àlí±Ñ4­Ñh¢råA�€X,–J¥“&MbÆh4 {{,œN'Žãr¹<J:NR©4‰@z ‹uvvJ¥R‘Häõzá©ææfµZíóùt:]oooìM‚J¥h=Ëåò@ Kâ!W*•'VB@”Z"‘(•Ê‘‘‘¸b\.gYv¬2¸jµZ¥Ruwwó)²F£¡i:ê‚ (ÊëõÒ4­V«½^/_qœ˜�.‹O;2™, …Ãá p&ø©òË™*•ÊP(är¹ZZZÔjuÔ°¨Õj—ËEQ”ËåÂ0L.—Ç¥­gÎ<��0ÛòáX§T*•^¯k,…‹ê4"‘Çñää|ô÷÷C ^ìê…|‹/èÄÒç1Õ£•+WFi¸±«mPµ··C*ŒaØe—]vww# ¢¼¼\*•Â¥†ª‰×××CCüX¨®®†ŽŽ¢z ¹¹¹0+0†a*• ɿǎƒ¿+**$ �Àív£-„¼¼¼ØÚ€gKŸÕétÓ§O!·mÛ›ÍæÌÌ̵k×z<žØBà¾[èõz›Í†Œ ÛÈ"H0„tA¯×Cº …8ދŠ…bppP¡PH¥R‡Ã—3A‘L&CÌ µZÍï!Ÿ„ù|¾ÌÉ`0@…Ãår©Õj‹ÅßÎjµò9ÍXÔ_"‘144ÄWÈH’T(~¿?V®'B¥RI$hŽ‹ÕÀD"Q¬¶Ç‡R© ƒÁ`ö²êÓr8‰D²,ììÃd «ÕÊ׊¢˜$ŒiiikÊd²Äo41œ•E;J@  )б¶Ö:::ø<jÌÉ?=jŠc7‘e>…D;)æ„aXFFârÉb€q‹•±,‹2³ÙŒ⢡P]ÐßßR÷ççç£ zzz`‘ %‹QoÑÂâO¡ˆ„>{…BZ À>ˆD"”žÙf³AÇqX0ò<´XM&Ôí0 k9éR¯Óé '—ACÀw‚ àn­H$’Ëåü=qOI’„Ô–ñ¥iZ¥RAmcÿþý n‡e2™V«u8PìCrX\ý Çñ”””¸Ò$TeÔju8†‚ÝÈȈßïw8 ÃÀSQæ2³Ù Å^¸°£j;a2™ø¶ >B¡Ðàà ˲P¥€eŽõz=¼aìÝøÏB¼~õ€ƒAd~H’ŒE|’!¬Q³Ÿšš:–�Ý××—ššÊqÜyØ[2™LƒƒƒH4VĸãŸ@΀\šìâ Fz½Þívóë h½†M`ð}>ŽãÈwæEdÅNž9!SÛi™“Éd‚£ -lÈBˆHÿ‘#G oÐh4]tQ”¾…ã8*Ú-‰Po>Ëê¡ÜÅœär9Rã¬V+bNèV~ÿ ßz ÃÐÁÔC£Ñ딸\.¤&ÂuÜþ툧žz )”¥¥¥eeeï¼óΊ+ªªªþ‹ÞB,«TªXá=.†††`n$}Ÿ9Í•Édyyy©©©†ù|¾½{÷Æ*@F£Ñétò é Ãð­y§}$Š©ÕjŽã•ippP©TNŸ>¦éôôôP(ÔØØ844d6›¡õ†/Ã¥¦¦ŽŽŽƒAÈz{{cíÏÇAiU©T’$E ¡l‰D0 c&³,‹èŽãQåÕù¤P©THMbË œ¯¸§†I°;Å_°¼^¯ïë냻÷höá)¨õŽu«ÁÁA‚ ø[MÌÆ—¤Íf³Ãá@l’D"Q(gþS|„±–PÚèzzzÜîn C´œ’ì^Á²’ 8O<ñÄ /¼0wîÜ¥K—.]ºtÖ¬Y­­­o½õVË[¨u$—Üib8Nl¢ÑjµZ­6ùÛJ¥R•Jå÷ûe2dpO4''‡™ÛíŽÒ³�Tq’y ˲ˆIøý~Äärss¡¢V«+**t:]KKKKKËÈÈ4Bç…¨nØl6–eÇÚDaYŽU J¥jµ�P^^ž——‰D;•H$r:ð†H)Œš¾š’'ë¶zñ†Ç㠇Ç\þìÃSv»=1Ag†oôƒ­Îpé†Ãad³AÊê¡Çãñù|üŠ]Nci'‰‡×år%î<¨£Áÿ|bW5bZH+àÏ~”#†à’w!ÿýïñ7ßLêKÛ¼œ´Lž9ž~úé_|Ñív?óÌ3[·n½úê«gÏž]RR‚.¸å–[ ·taaá믿~3§fU•J%“Éø¥$· Ʋ¥Ä¢¨¨èرcLÛív«Õêt:=êt:†AÒ¥Á`0™L�€¶¶¶³bæ ªýýý………P-€t‘HîIÄ}_Dø†ÄºšÃဴ^$uvvæää´··‘’’‚¬î|²›€ü%v4F£±££ÃívñºÀb± $pã‚­"‘ˆL&ƒæDÈ�øoŠÆx]–ôz=†ag%T(‰Œå™»ª§NzèС±¼Ï.ÆúFòòòºººÂá0Ã0|ƒ~“$i±X€k·Û“±*ÉœÊËË¿üòKø[§ÓM:þ>vìXì´eee¡Í›­[·"µR«Õ±¾é¡P‰?ˆ!÷öö"›ªª*È`ù†Ý¢¢¢‚‚$ ÀÃÃÃp# ðvzär9º’ 8,ËÖÕÕ!u{Þ¼yÐ ÅIxpÒ¤IYYYQ­ z¯¦¦&øEÅU‡ ‚@WŽŒŒÔÕÕÙíöX§”8HÂÈ�à”J`2ÅÅwë­·îÙ³ç‹/¾Ø°aÃ0 éééˆ9­Zµêƒ>ؾ};� ¦¦† ˆW^yå¿…ßççç÷ôô Êåv»!I=m¼dqq1MÓ‡Bä5ê‘H”••ÕÜÜu¼¥¥í˜?~¼µµ5++Ëd2A)Øï÷Ã8§îînH‰s&ØO~oáÍóúýþ––‰DbµZ¡AF.—K¥R§ÓYZZÚÐÐÀqœR©Ôh4]]]üýÔ±ºA’d^^Þ±cÇ0 (((¸öÚkƒÁ V« …B ,˯áªTªúúúÄ"yâ·ƒ°Z­v» c7Ï�ÝÝ݉­Rˆ8º\®±´j·Û-•JSSS£ÖLTo£†ýLü/c¬É…Ç9Â0Lb•H©TjµÚÄq ±OA þ™ 6®³³31³‰D"|?‹$ƒ4ÆdN$I¢õÄq²£ï-Š #ÊŽ7–eQ+´Ék"ˆU Ñs)Š‚ÂÃ0èå“ãeÜ­ Ãønø,þ•ü§Ó4 ïõ,x ¿WüÑà ~Âáp²–âäìQ\M 8«áhÈá>®åÊårÁ¨pª›þHCÃá°Á`Àq|hh(Ê,‰¦>33áŽu«ÓƬ„B!þ‡£šà^EQQQcc#AF£±¯¯2°ââ⎎†aPˆ AðI°<Š‹‹›››!W€GÒÒÒ CGG‡Óé,))á{BGÑ·Û¼FÁÉø¤£GÂxU—˧‰w �tìØ1¥R©V«C¡P~~~VVMÓGŽaYV$¥§§ŽŽ’$922bµZáPÇÆÆ¢0Lš¦'MšÔÓÓ£T*Q $É¡C‡ _ t*{i‹åÈ‘#qmJ§ÕHÐ'Ì¿˜ß7¸ïýàš‰í9Z3üaOÌÏyyyÝÝݱ;7ÙÙÙ###ÉØ®ÑG<ÿš´´4ÇÃM¢Z%ðÑOFãG×$O-ì9]´5IætñÅç¿o¿ùÍoî½÷ÞiÓ¦!ÿÉ EAØáp$ÞœèêêJÞR‡�Ã0¥R©\.§(*==$I(H¥¦¦æççSÅ0 dl£££|¯ÆÆF‹Å’••E’$ôê´X,eeeгF¥RÉåòXÍ ¡¡!ómY½½½LKK£iz,Î&“ Þßb±Ä}¯mу\.×àà Ïç€òMÓõõõÐã)kµÚââb¬÷Yf³Y£Ñ@–ì÷û½^/ôʉD$I655577“$™™™©R©222RRR¦M›ÖÙÙyvý`333Ñ[ǺøÇö­™q û„ÑÒÒ×§ ££#Š3¡Eˆ€ÆŸŒŒŒ(·¸œ‡T*r§Lra$N7–ëi²š“Ãá@á´È§.Š&ÖdƒÁ “¾3EQH*çᢃü l6-á§;–^¢T*‘7J\Æÿ¡p tH 7ÿY.— Z9ŽC£AQz/³µ"Dã<O¬š8>¶Ç�à¤Rö¦›@¼?ÁœNz0žO¼ûî»jµzÛ¶mh@.@„B!Æ!“Ép‡ó¥R©\.×YI•••Í>N§³¥¥¥££C¡PˆÅâ‘‘‘ÞÞ^>u£(J¡PD…{C¦¥P( • Ç#“Éär¹Éd‚>¢±Î¾8Žk4š »¹óÍ_J¥ÇñXYX«Õ&³@’¤V«U©Tjµš¦é††…B(ü~WW—D"innæ“ÎØguuueeeÁMø¶¶6¹\.“Ɇ††Ôj5ŒÐ4íííðܽðz½É{%ÖÖÖg'Õû@*•Ò4Í8†Q—µ··ÃЂØoA¯× ðµ@‰DÂqŒ¥=“xjZÎ €á̰3±2â˜Ì©½½½²²±™X›f ˆµ³G±·XûµZ­FyN»ºº D‰aò‡iàoäJ®P(øÛòÈtƒ8°Z­F‚üÐÐP¬`%‰ ÁŠã8t>ºR©,..FÒŒŸ IráÂ…H`Aëuòäɱ®ägº? ™SUwóÍÎÒ¿ôÒK÷ïßÿöÛo�^~ùåµkׯÆ_ 6=½^'Ž¿år¹ÛížsŠŠë$"55U©T"•Úè E8æïR£7b¥“p8L’dEE…X,6 6›- mÛ¶m,Þ€a ÅåLro9 c…îF…Å7¶àxfffaa¡×ë´ÙlK¡€_±X¬V«µZ­Ífóz½èx,â-y¤}HLDTjkk3)))CCCçÎŒ;ì:.*Žjkæ¬æ …B°‡0]ET?ÇŠ´µX,‡ŽýbcfE"L’Œ"ŒÎ†¶ LÅœø×+ ·Û­T*ý~ÿ8˜“€ïPBÉÌ<ÿOþÑ~4uêT…Ba؃>˜“““››ûàƒN™2¥¼¼œ¢(H;yä‘n¸á‚?d‚€/Mç‰Ó‘$€Ùlæ›;JKKiš†æ&>áæ+Í$I ·ÛE¡ «˜F£©®®‹Å‰D*•ÂMÇÍf3ô#W*•|¯9†abóÍLL :á)-- ðp8 3³9ŸÏYojj*¼ftt&ȱÛíF£íK$±Xeh%B¯×»\®ØS±B1òƒH$R(ãb6³hÅFÇUt‡N§óx<ãÕÑÍáƒNû8þrêïïORJƒâLô7®W†Û„ÃÃÃpÇ. ÅÆêÁ-Ʊ<5ætáa0hK<i¨<Ÿ¸úê«Ñï»îº þ(//‡?.d†Ä·¹!-:wá ƒÁ †a|7ËÑÑÑcÇŽ‰D¢¨­r~lPVVVoo/Ü€‰ºa$)++Óh4f³9##±%¨‘gff´[§š<s#mÇÕ î3AG†(~Ï›…^¯,ˆB!˜…Èd2 #«ŠÐ„À0Ñj¬$}Iø'ŒHœ »”üûr©*LxÁçj0ÎXz"‘Hbˆ²âÂPåñN’xX–…c’˜½ñ—Sâ˜n‚ Ìf3ßA&A02?ÒFh!®Æq\â÷J<Yc2§¼¼<´õ•tøÛtÒw™ïrÍqì:_Ð ÈFÙÑÑ{ïñxPî“É„6aº<p²öü=uêTx[Çi@aó0R ² qT*•eeeð ßïOÒ`J ã{¢æü•ÝÖÖ¥*𦠑mäŒ<Ùýç»`NßðÕ”¸.¶‰D«ÕòI^NNNWW×Xö1›Í†ãxÔœžVô›ª 77—$ÉÑÑÑ´´´ÞÞÞôôt‚ ànJOOO$ill„âj”%0//¯µµU&“)•ʳ׋-Áßz½ža˜d"[!õéííM144ät:Ãá0J�æp8B¡ú|P„&ŠêE~FFÆÈÈH H œ`Ø_8Ö*±ŒÂ�ÇÓÓÓÇbNÉܾòùq|M~Û;6p‚Ži âU^k²øÉzNÏœ K%¢×Èõ@«ÕB’ÍO|¯Û8§×ëEÄÝŠ/Mdgg£MuÄqG+@¡P <@ÈŽÏW]Ñ ÄÍ2 ó#"•¤‡?o:_èFÍù²�âÄгþ>Ó@¼“\KK^/öé§ØW_aMM`tÐ40›¹éÓÙeË@Œ‘€Ó~HPŒÈÈȈ’×úûûY–…§ÚÚÚb*Y–…ÛÂq)‘L&ƒKÉt£¿¿ÆŒß|óM8†V†a ‡BÞXärÓ¸ª))),Ë&æÐ;¹§§†[Át> ´´´´4·ÛÍ#>›‰büF£±³³S¥R…Ãá´´´¡¡!¿ßϲl”t˜ .Ãðð0|ÇØVg8ûz½*£££“&MjkkcF&“éõú±dùX®Æ0L’«âB­VK$’r†Ùlöù|‰#Ï&`W°Z­±ƒo6›½^/d'É„`'3ÉLŒŒöûý±ËI0ë]x€Þ†}þ9¾q#Æ_%�hoÇÚÛ±üƒ½ývîÆÁÛ¬þ×�}à�„B‹ è‡¡ù;î&¶Ïç+û�<%-$$•••¡Q|ò5%�� �IDAT]»v‘$ …œN§Ýn—Ëåû÷ïÏÉÉ9vìd„��£Ñˆª®ÀJ¸0Á±Ýn‹Åcm¡%³›ÒÑѬ[0Nb¯ ˜Ë•ºê!:G’¢¨ììlè'522RPP––f·Û“IJËÍAkž‚bbffæèèèXì'ùú³jµZ&“566fdd0 ƒ*6Åu’L|ó¸¤9ÉbƒQDq‡}¬Î€S=“ïpooo\Sò1AÑÙ nˆ¤ö¨Ðé  ¥¥E*•šL¦ØýT2u ©;übEAÅ}BP‚@/ŒZ‘$‰Z‰Åbd÷C­`*hô’|e9ÊZÈ·°¡´ªü1â«8° l‚4Y¾Ú÷þEÁW }K8ŽÃ¸ÇÑsWÇjiüèc~g¢ìËc)øHB$†‡�`G<÷\¸ª*tÙeLz:îrQÛ·Ó›7c, �ÀX–xþyÇ…–-ø ˆ—¸ÄÔ´…Ñ”ü�L“É+‚§b+áòÏÆ}:̳@’$Ÿaĺ ØîÂÂÂãÇS¬V+ÌP …ÜnwoooEEE(‚ñL|c� © c%9DqÇÉì^ð_„ÿ^qÃ3A¼É¨ F“&MjooD"­­­ðb–e[ZZÚÛÛlðð·$ €5™LEÁ<LcÝ-''§¿¿?Fˆ‰ùÑÓ ¦x¬$ c!Ébƒ§)–e±RŽùµââ"??¿««+–Í£Œ .FÇáJCË ]\VVÖÒÒâv»U*UjjªÃáH$‹ehhhÂúÌc·²™À8€Â€är9Š ’H$¸ó'2 %6šÁ`rpjÖE~ö-$“ªöA‹\f³™ Ñ@ 3¾î?}útTêã?Fv XžÃ0”˜ï"ÜÇ].××_ZAz†aöíÛ‡(r²ç AŒeðèÊþþþ±lÓð3FK_90PC’ÇÕ]sM?¬˜¥¹É“Í5ýoûö›ùÓŸvˆÅSóÌÿÏ¥¨G€¡3Èl’™™ S3ð-l±÷Q(‰$Vh…Æí±”§ÑÑÑ(s\lIVÕÔØØ¨T*M&ÓÑ£GE"‘X,–Ëå.— ’fh&Jü¬¸‰D©©©ÈñI,Ã\g¨ o271™L§Í6{C‰DyŒ™E„&##C©T677ã8K¼$IzzzGG"0# I’^¯¾>Ãþþ~š¦¡6–Å)–À¡Z½‰$ NØû< &Ï™Î.àš‰½drퟶÉK‹D"£Ñˆ4ãìììãÇ—––ö÷÷x½Þ¾¾¾ÁÁA‘HÔÝÝ}&1ÑAð׌`Ö»°�sÀð.psç‚¡¡Êêêhxå•l_¾sç‰yDz½ÜŠÂ&c6Ik9–NÀ—âÕjuòž±_>rÒëõ)))ÐÑ6–ŠD"¥R ¥{È¢Ôj5†a vû�ß%W«ÕŽŽŽŠD"·Ûm0’,ª ãsãÒqTºóo¨Ñh`¸U$ATzÛívè~;øZ­6Š®iµZè!ÕÔÔ¤R©øi6ÁÉ¢ãJçB°µZ­Õj=“è]¸}†U}'€drJ%~‘\þØÂH[$ ÁRyü)†¬.--mÞ¼y ÃAX–L*•ÂRLpdP,vò€kf|•pœ7·´œ¬2­f-YÂdN��bÏâöÛ…1ç¾´ãiÓk&?>†FöööÂìGP Ñjµ0a9��F©T*D2är9Žã0α(X=Ö¤©T*¡g¶N§s:}}}…FòëyÆ%èqãs¥R©B¡f&ÖðJî"þ*•J1 KOOGI“ùˆÝ3óù|0¤×ívÃà'¾Š|j ýŠ\ âîÏÉåòäç”$IXÞ—0ê•cC°/4ŒU$†1ñ™¬=–S(ÒétJ¥R*•ƒÁ¶¶¶ááa‰DM‹°ø$Çq2™lbåê)ŠŠÍD&ç+ã¯TôÃ0t;~ˆjÅÿ:;;á¼ò}üd2*�ˆ$\±XŒ6ÐNŽã|3ÿè+å§€ÏKPBÍùä UÂ…æt$¹ ƒÇ¡ƒÙÙÙÐ1îŠä_™@â£(Š ˆ$ãüñÒÒS®koÇŸ�úúú‚ˆµìMLº„Nt±æ¬ÄAŽü€J˜æ~À0L2%%¦ÖF+D.—Ãܬ±É‘N§F£Âioo/,ÇÌ'¦)))(µ]TWá†.ÜÞç÷Ã°Ä f,ÕpxxÅ{ŒÅ‚0 Pt8ÝÝÝ^¯W£Ñ$¹¶9ŽCV;hí!â´I+ Ûv¹\ƒ%2H&lÇqDÍb òÆ*¦±ßxÔSøã÷†pö†IMM@0�EQf8¹’q1Vº ÄQŒF£Íf‹D"|v®Õj¡#+EQv»½»»›¿¯†Þ%ê•alõi£Êhš–Éd±NÎd9}BQÛ§Èq�í!'š†ÃaÄ ËfÔ#2y톽Hø‚˲üoùµ#S¬R©D߇††óÕXs»¶†‡‡cÓµ¶¶Bß'‚ Pªž$9æææB›Hv;ɬ‘H$Y›ƒBÁŸ3îÔò©ÿ³€¾Ëg…9åºUÅÕl6ŒŒÄ®±p8œššÚßß]ÃÑ— ¿‘HÄqŠ=dî9¹Ýn¸Ò¢Âá¾ê€V«åû.ÆÎ¾F£A /++«»»›ét:aqñ@ pÚxUø9@ýÀår%Ž‘äû AÀ ß$™ô«2 0 ,j%“ɤRéXOgVqDމ+áò­¾èw0¤(*%%e\iD F¥u£nWâ‡=œ˜q¼áÃq[s™uÐjµJ$•JµcÇŽ@  Ñhb·ˆàJ‹j›¤{ÎXï%d%¿ðÀ²ØÎØ[o¸²U”e6™êP’QIq<77œê9õ¥AÕ‘¶¸4×årÙl6x*ªL*Ô'²³³‘ º»»ív{ZZô?r:üª¦ü¬6Ðé9êY±Ü‘ïò>::ʧ:N£Ñ¸ÝnØ*™[äR˜$õôûýPDÐëõyyy‹%ֵī…*—ËU*•ÏçƒÅd- Ì7i:EQHú�äåå¡ß~¿î'Áª»›}8e‰MRJ¥26Ù1tÓ@²µÙl†ó× =¼ ‚81±éÌcžÄÌžZ”¥7--­§§‡a˜üü|Ng6›M§V’‹ZiHJ²šFÜ‘öœ.8΄ß?¾m�€{ûmfóf¥“E‘‰3Ë3ö¿Œ¨HÛÓª¹‘H&Blc¬+᩸ÕZ� …‚ïÁ yT*…r·Ùl+Y'Žã‹ÅãñŒuA¬ÌF“²#z‘L¼êXÁ¶ ®G¹_ûúúT*U\Ù96_- ÄŒ4ÔápxxxQ,Ëàà`ÔLÅòN©Tš¼š,8qz½ÇñXë™×ë}P8îëëCÇ¥Réùwš’ôÛ‹Å&“ .TFc4Íf3T£Ýn·L&kiiAÖ<X ÷´Ã‹þŒéŽ‹1™ÓÎ;g̘ŒŒÀâÜPø‚Æ ‘H„ªT„Ãa´âQ].Šœ<y2\j4M#–ë÷ûч„2…‹Åbä Ž’Ád·ð D"AÖ$LñS%ñ©Ïµ×^ ×ÕÕÁ´IA T===Èá2®l±X²³³“™K­V»`Á$LA‡p8üÉ'Ÿ Q1==]£Ñ$^ØÞ½øÉºpØà ¶g7gÎ)WœúÍpEEçaAÃŒ°ì´Ür‡ùÁp ´Z­L&ƒÛ~±¡‚|éFMžV?à¢�”””455Å]9†¡€$ô蜜œ‘‘‘£Gò7ná©ööv–e1 ƒEŒ&MšÔÜÜÌÂ…Oollä¿E2ñ$IæççCÒ0–¡;*¨3ù°ÊØhP–eƒÁ ^¯ç8®¯¯O¯×—––B‡ˆÜÜ\DFø ¢(xŠ?’@�æ3ÌÉÉijjBä–»=mü©ßïOœ3ö<++ îrñ£ÇÐÂ@•pá€@«cÔàðýÀÉèæ ç+œ¯ÆÉ-++;zô(Ôò»ººZZZ´ZmeeeNNI’@  šL&†a†‡‡£"4ôz=MÓhÿ)ö[ˆéŽ/u%S›Lᓈœœ*†‡¸I’¤( ú ŠO‚ ô"ÀÉ8Y‡Œ€Ÿº2î/tˆ„�'wÑ`Ðz/þÁØ;@?:ˆÓ~¥ÔIÐ<ðÅ^’$O¿£~ª¾mÚý Sãû¸“ñœâé§Ÿ6Ÿ}öÙOúS¸÷vøða£Ñx÷Ýw_°œI&“©T*ä‚vùd}!qy ”ë cí¦Á›Ëår‹Å‚B)!ƒ‡ŒB¡€§H’„ ¶‚NØ4M[­VhBÝ€ßzJAAÁ`ˆêa”ĉDâ*pQ\%‡¬~hqwRù0:.ö¸Õjíëë3›Íðs€wCœ)V%« –””„B¡¨VP<ŠeÀè•1 +..N1hJJJgg§ËåBY1ÁÉís8w---@�Çñ¢¢"�€Z­NKK3™L(è3Öû9n÷ø3BŸ_;üi‹Q¹\®Ø¤àõõõ0–Ûí†Òp¸Pa!!…Bü¢†Újµò=#JJJ†¡iZ©TB·2þ(E¥TÌz.¸Ù³9‰;éý}ý58v ðÔ#ì¤*�ಳÏb1Üþþ~$lNž<™¦i¯×ÛÐÐÀ¯PðàƒBße˜6{xx¸¯¯/í‚LPëõzùÖ³$ƒœ ‚n0z{{'°}|™<ôŠììì´X,^¯7‰deeµ´´¡Óé 8†‡‡õzýìÙ³!s‚fzz:ôCC暦E"‘Z­¶Xþ?{ß$ÙUžÝ·o眧ãtOžÙYíŠEBb‘À`YYP¦0eÙ˜Ï2¸LQ._Ù€M(p \.É ”‘ D J«vrèžé4s÷÷ãñ¾>:÷öí;³+±óþšéî›Î=ç¼ñyŸ‘ýèGl¹Çãét:*³èÂ%HðrM& Ô•~ýu M766¼^ï… @Üo£ÔétÑhTªŸÐª@EƒÁ \ðíñxPà „î_YØŠ VysÀm˜– ¨^±B;ö›'À¨QÁËÒÒÒ¼+A,K½^ß:[i;P²Ù,¬¨v»Íf¿xñâÜÜœ×륷o±XjµZ?wöìÙ³:]+¥¡<QñÕ>”“Ëå"WšíxHwP­Vi ú–‹‰¢H\´¬Ç@gh6›˜s`‡£™J?v:È.jµZ¶EºÔ cûíÃRà aO…d& *²X,,/M;6y€øƒ Ô·¢_¨ÒËdÇõcÝU·»ûþ÷kÿßÿƒ1,h4âûÞ×ù—Ñ Á‘Òþüçÿ3ŒfsçÃÖ讌y±¾¾þÁ~ðâÅ‹‰Dâá‡þÀ>ðæ7¿ùÞ{ï½ûî»ÿ÷Ÿz[¼ë]ï:uêÔÊÊÊüÇ`{ì±Ç"/”îé¢(Z­Öf³i·ÛÁB´°° ^3aŠJ7Õ }ér¹è Ínbbâ†n@ÄÔ ­V«X,bR­¬¬\{íµår™T¬Ï禶xè{‚«(ªI±–>Ÿm¤?®×ëês6Ò”N§«×ëèD‡¶ÈV«EšÉl6#0Èê9ÔZ­ÖJ¥"û:ùœžž^__çÂæÒrîu³ÙlµZ.— ïBÚ¬¡c³ÙFGGé¡Ìf³ËåB'uÙ-žþ^\\¤kíW9ÉápÈÚè¯Áe7.“Æ×h4úý~®®®^¸pÁd2íîîrÜè>Ÿo{{›­}à†Eg³EN—Ëåd5“’r¥S³m~Hççr¹o~ó›øûèÑ£TÅK#€<(½D’ö*•JX{‚ Ì\r¬ÃßñxœJÉéf ƒ4ÏAD·˜^Ð(”ûA *òûýtˆ«5Ïl°”J¥¤¥ä²R*•dÛ€+¶wë­]»]û÷/¤ÓFX_ßøÆÞ±cB.'\Ú›zÃÃ|DÄ#.S~ô£}õ«_½ë®»î¸ãŽW¾ò•ï~÷»o¹å–¿ù›¿¹å–[n½õÖ÷¿ÿýœáòÁ~ð¯xÅ+^ñ –ÿéù"ƒíìA`ÃÀ8µX,ÇŽÛÝݽxñ"vº~D®ÒÓjú Þ8A³¬a°9ƒ ÷È‘#6›M§Óe³Y¯×ë÷ûYžõ-*•JµZÝÞÞ†‡¤ÕjYÔ¤Â²Ê ¡fYͤæ‘q«²û,îdrrR«Õ ©çê5h@ÀêÈííí¡¡!¿ß¿ººº_/Öd2Y,„¡r¹ë²Øív—Ë•ÉdZ­½YƵà3™LÅb‘Ý‹;tX&“Éår\ ¶Dši ×’eÝ%t6âoý’Ö¢(^ñz½¾R©  R*•Òét»Ý6 áp˜l²ü¹Ü{”?ƒAÁÅ? ë]•Á½—½¬óÀÂ~ üä'Âü¼fgGøå/5z}/éMO÷^ùÊÞoý–fP>à�òío{ccƒCÒÝpà ¯~õ«eAþÏ/ …BÔz™mÌ&? …B4M§Ó{{{ÿÛŠW±Þl6›BŸõ¬<ÈMoÔëõ\.Üz‹ÅÇBÉd2µZnü~ìî¿¶¶ÆrÖô+5dÑ œöêt:ý§ u.„´µÛíF£ûìÐÐP&“‘*¡X,f2™¸^8 Òo׆ˆŒ5”+=peagÏ�„™í$B6›…Ù­Ð%hccC§Óy½^jW‘ÉdHèt:d¡&&&Ö××)ÿÍ;› …BÊE¡Òi tö@˜°fPŸò«ê’Éd8ÞÙÙªT*Òæ÷@þƒÁJ¥¢&ªŒÇaÛ‡Êéy"Fcï5¯é½æ5Ïå5ÀÄÄÄßþíßr+ê…!õz«·Ùlö[<0÷œN'ûøˆ×¡,ˆû}"‘èG2-•¡¡¡b±X«ÕÐMJ¥’ÅbÙÙÙ±Ûí€ø”Ëår¹ŒÔ+íõ©¦OL<¯Õj±XŒmëW«Õöî—LŠÇã°ˆóù<é0ÀK‰D2™ôx<pø’ɤÍf‹Åb•Je_%ܰÝn'ׇ…áC²8þ\è§ÝÝ]®vé}ÒÃÃò4‘HÐ#szwkk Å\±XÌh4¢Sw{Ü/‹reµ‹´„j` Ë(+ðÈë!¤rÕëuÖ5D‡òz½>;;»»»Ûëõö´ìõzýMI9e­Ãá ¬8áçõz=Åâöööh6Ó|D"SSS܇¬E‰D(]A{Ûd 6÷¶ÈŠÞ:_‘m Ž% &de¯×£ø›Óéd od­?–u0ƒlmÉ™3gðDìhlmmÁˆîv»\¡T±XTÓçW%×_ý[Þò–¿þ뿾xñâ+.•Z|ÿûßÿw¦:'ÿþïÿîñx^ýêW_ýÊIŠ9  ¤ÍºÙlV*•J¥BÊ`ttšŒãš›ššZ[[S¦ŒÅb¨¿§­?N;Î@ �žŽf³Y(Μ9“Íf777/^¼¨Õj/³ýG.—‹F£z½¾\.OOO£Åc=&UN L¸ìWù|žˆkÙ{Ã'èÌÔívC¡P2™,•J•JÍÉŠÅâeê'Í3{€‘*’ÖJpü¹¡P¨X,V*Îëe[‚êZ¶e YÒ —hÈ·¶¶L&“Ãá`Ý/öZØd0Uö ¿D"ù|¾Z­l-Då,âñ8Ú”Ð^¿ç`ø_ Ì[«ÕŠW¬y&|ssS§Ó¡ã‰ò©¢Ñ(ÀÝ4ö§œÈqc5 é­V‹p9Þ„ÔËs:´Kÿ@(–ÊH÷ Nj�—fÙi›Í&éÖC§ 5CñYÒ©Ýn—öôƒ¡gd™¨¤þ8K(%ÝïG<ÇßdûHM˜V«% ˜ÿ•Ëm·ÝvæÌ™O|âŸýìgWWWï¿ÿ~ŸÏwß}÷ýÅ_üE"‘xå+_ù¹Ï}ŽýýôôôÇ?þñ~ô£Á`ð–[n¹ªžE«ÕNOO£³µÕjÝÞÞŽÅbn·{aa¡ÙlNNNRur>Ÿg[0ЦCëmtt4›Íbgçjš×××¥TC¡P­V“µчÌ#Z…š€:>}zjjªV« …x<>55µ¾¾îõz766ÆÇÇ©P Ý-vóÍÍÍk¯½öرc§Z­>þøã6› ýú8? €JV  …p8Üét’ãáÛL&ƒ¥Fs¹ÜøÃ©©)ì°ì9²¾¾~Er$Á`õ†9þ\Ô’MNN®¬¬Œ“½È½»\.Çv–’Fk].—Åb¡Øí¿­VëâÅ‹ Õz—ÃÂŽ4Ï¥`Šqjj M ñÉØØØÆÆëÇÐ=¤R)v²U*6|ù.Íz­¿üå/‡††–––Ô`ec°‡a½C‘—Ëõ¡}è}ï{kX¼þõ¯¿é¦› ƒV«}ÿûßo³ÙNž< ËÀd2ýÑýÑïýÞï™L&¶¾ñjn·‹ª¶b±ˆd{{;™L]Ao@@)q- zøpmm Oi%ºlq³Ùy£Ñarr’¥€‚}áB¡P>Ÿ÷ûý?ü0Y6Àë”J¥n·K€q¯×k4¥© ‡Ã1>>¾³³Ã~U*•.\¸0==MåÎPÔáp¸ÝnÚ‘ PIhSômR¶&¨òööv¯×›šš³*=5l¾……üL ݹ*Bj½^<¨½¢3 A¡P(•JNgqq_ùý~Q)Þ#Âììì¹sçb…BAVÍØl6¿ßÏM°r9ýòYuÒl69öêêj¿ªtNS²½Rdjjjee…‹ÚI{â³lA …B¹\æ€êýDMa‹’r¢M‡-Ý&ϩߠ°á/)­¯¦é-ëµÐåd=':Ñ^öƤÑL&Z]‚ P=!kì(/†^¯G›Ë„K´N‡îãW­~2›Íœša‰ñ;Pã{u> Ö!1în·^¯GGöì6›ÍçóQô‰æÊý…„Ó(EZ¤Ër}}Ý`0äóùééiðɺÝî™™™ÕÕUØé¸ º‡l6+ä)‹O>ù¤lä»ßýîoüÆoüò—¿4™L^¯ÏŽ;äü!\K§Ó“³ØÛ›}XÀö¥£±¼¼ <ïèè(*›#‘H³Ù¤ñ—¶0PÉi‹ÈÇ‘#G¢Ñ(|Mð6={6‘H,//FÌ[A€Åɸݶ×ëV¥°±²ÄÙœû«ìÿaÕ³g–Î •énª/ƒd¥ß±F®ô¼_öQ£Ñ„Ãáv»°çÌÌL?$»ò´Q%åtÓM7‘–£‰R*•àÇõëÚò»¿û»4p´Ùþâä:ÒdÄNëp8(oéñx “X°z&“¡ì-˜r¹L&Q4 Z�F£‘t‘ê...RþÉï÷+àá;Ñã²L¸§NR™ˆÅbÀó«é¶y(φ€ WÅH$ÒÏθÑ@ˆgVá7Rü£BÆ%‹Å¹¹¹‰‰‰ùùù|>ÿÈ#ÈnÇV«õ�¤A¥RéÔ©SÛÛÛ‡ŽU@h¶Ûí¹¹94¨×ë~¿¿\.+$Ðo©ÕjIYwQ°·¾¾N)@‹Øð~¥R¡kižÉiK \£ÑÈÕ¤€2jcccjjÊårmmme2™ùùùv»½²²räÈ‘£G¶Ûí|>_©Töööð¼h¥…;˜@óÉ²î² \¼Äx<¾¼¼¼_²ã+%Ñhtkk«ÕjY,6ûh6›)i¢Ò«ët:`OfÏ�˜ª^eŒðaWòCyaŠ^¯§&ŠP‰7›M…Œú((yÏ¢(’i%5Bõz=×~[V’ɤÅbñz½ Ü 'r¹\@�…Ëx.ù>P …B2™´ÛíÅb‘6Dé¾`·ÛÙN]F£yeT7(œ¿X,v»]ôÂà¾ZZZÚÞÞž™™¡¯vwwY eô¨)}pБ*Çø¤V«K7“Élnn&“Io±ûÿæoþ&šåìîî¢Y™ª ¹`¯âv»¹ÙHõSÂjµÂüõz½\·36%jºååeŸÏÇ]ñY] ‡F;­V˽,—˵¯GN§Ó¹\.ŸÏsÙ#‹Å¢fÎka„•Ó¡¼0UCì'è6ÍýÌétªßâM&°ñ©TŠü­V«Ðþƒí“B>:W¦o·ÛÝnw2™„ÂãNh6›u:]"‘˜žžv8 ˆ´•[�éL&´o¿=( ±ÙªEºyöÆèÖ××Ýnw»Ý–â1a s_9Òî�—Ëe(§ÓÉ*~”´`‹§èûà¹\îܹsO=õT 8vìX8‡Ãè;…*€……¤�è(\Ën·Ó«±ÛíÜ`šL&Ò1¢(RåT?Éçóи››› ¡*«ÕŠî ‚ (DÌ®øZ`œ¢A\é:ºî÷äf³™ËV .ìx&y‚ôföÖÛÚÚb{A’¬­­Q)9¥†††`‚@QQô]%]*M·X,Z 4K¬V+PÁ`6ZÏN‡zÂ’ýU­VY"�x¦…BrÈÑh¶R¯×£¹ív›WWWq ƒÁ@qEY·T*Ñ2£‹6 úÐétâ ”™ÇÜ]XXèg~nll(À�e ¤R)Ζö¥–-â—òÏ*¶—ËÕl6I9µZ-n—ái·Û¢OGÉ¢,QV‹æN˜N§c±W)z€¼E6›õx<ŠËb± Ô-“É(Ÿ“]Å©®t{<žgZ^�� �IDATZ­†ŒÀöö6Ò](ÖPvö´ápXº]‚Ë‘þ$ÖãñŒÛl¶•••V«…>F½^ÕóP±Üs¹\õz·'Õ©l%¤Jd5‚Çïv»ì+fÙ“ûI$Ù"·.³ˆŸ«@€½y5̼Ñh”~æt:ívûÀBS%å´³³#«œ¶¶¶¦´Ùl¤œØ>@l;eåè8ýM¿¤ÆM~¿Ÿ³¥ la]T«ÕÒudÄ:¤Ž/èt:äK†B!ªÿ~ú駉 —²S²I`Ù´D£Ñ síµ×bèÚí6)'t¬T*R“¡Õjét:no=”} õNÔh4‰Dâü3{·+¬¢}¥�±ÕZ­Vå¸<Êd¨>Íf³ÆF££�§Åæ2::Ê>w”Á`@‹³OÁ!]ØDŽ& æóyvWârKR?Àét¢’Èl6§R)¤X¨£Z¿ ±…øFCº^dq¬­V«Ùl^¸passS„h4šJ¥²Ù¬BèLÊ)¥¹ÔØÛ:9|öf¯ÆØ«‡ðšU¢~¿¿Z­Ätsq.ij4 ¸­J9Ês&hÌ50np(*år`†jdàRÜÛÛÓét0ƒF»Ý¾œÍ;£ò@äŠ(%•¢/--)”rt‚‰DÙriTð`%Ñ###ˆU´Z­F£Áö(.— êÖív‹¢ˆqµ'J¥Òã?ލ#`° ÜbôWäF•lAg¹}íÈý„Åçty C0” œJÝ,)°ì2…&?º˺Ú¦›Eb¤ÓinBpûP9]uº˜‡r`¡]ær0²räÈYW .;‹êe ´-r­%X#¯P(´¾¾>°é‹òsu:Ô¼aKŠÇãápØëõšL&Is233377'Õ[x³ŸŸ¤2„ÕétÀ)Š1¬ÕjÉd’¶³‰‰‰••·±±xF©T"&\»Ý~þüyéQh¢\qÚ¢9ÚDI/ëq/Kúй"·ËõsUű±1ed·Ûm2™’É$ ÝåÔj¥R!ŸÛd2)0/s’L&¹s‡'{!ÂtKS½ìt:ÜV¥œ^ö²—Ñë´Z­äG£QÂ^‘‰Á’Ð}„B!ÊèT«UÜ“Á` œªÏç£$$µ¬V+…wÑ×b{Là±»Ý.]‹í¼‰Dð¶lÆétR‡´ë®»j¦>77§€«Ðét·Þz+þ^ZZ’nUn·ûĉøûÂ… jeØÙ£òPÁXž~úi»Ý~Í5× üå¾�žø1e.¥ÒívYÕh4Z­Vs¹œ?©R©€'ŸÏ³D3SSSÒ &½íX,V.—97‚vŠ­­-»Ý~æÌ™z½n6›£ÑèÅ‹é è½DÿÕ å † „ˆáW#¡^^^æ Ü3"ˆ —––‹Z__gÛÜìÍ»\.âA[)wr©Å ÕjÝn·Õje½îkén‰D6›ؼGú¾ÔÄW¶,+^¯7 aæôK¦R)vÆÚÚ¶Š‹}›RG!PÉþ«×ëÑ›ƒ{Ë„¿&–ág¼Ž~gçêyˆ|–˜^QÌNÝYzY¶Å‘´ý3}(ôõ³Ÿ.ª¹”Gåxr‰–½œNNÔø7Y -FÂï÷Aå`ÒuÄÑ«©J.»¹FößÍÍÍr¹l2™ÔLcbþf‘àb—þøøñãZ­–-,ÜØØPH˜Åb±•••r¹Ün·kµÚÎÎêª!óóó¬'”ÍfÕ$«è‘÷¥¢&''?ÎvפåÖétŽ9‚¿YŠœ ì) ‚G±Ýn7‰Ñ„\ä#4ø€/555¥¼Ì­Vëë_ÿú'NH«á¹©Å¹r¥ž«««²šI§ÓÆUx®~µ” šÉl6OMM!>¦p~Žá3Ðív?~œ}jÙW<11Á=l?dY]…®Qç2‹¿öx<”6 œåPž§Â6q¹\l‹n·Ënýf³Y¹ŽüâÅ‹œ'Áptt”jj ÃÃÓ““ x‡Ãq€Žï•JE«ÕR(b ¬¬¬°¡§b±¨&W!ÝRo`몉ľN2??¿¸¸˜H$PUnIô-…+•Š”A ïQ¯×[,–d2IʉDü¹šK¥occcc`2 D¦ês–�T‘îQø¥Ïçç@ƒû$‘H †°w‚1±G£Ñ8ÐÚ¦¢Ñhr¹ÜSO=ÅþÈÈûZSr~²€‹Eå”Îf³ÒÂúŠ«©Ñ)xNôS‡ÃA±84Úâp"ð@çy2‘È:#{“Š æN…yô¡(Šäp”J%»¨³†iQÁù¡4:d>t»]ÚzÐOGѵªÕ*aÑ­V+îToÒð(ýXÈårÑsÑp]=u5¿¶€´Uîåìv»ëõz¿ÍÈf³5 ÎýåNˆö²œ>ãÖÇO‰Dæçç÷K½ƒÈ’´ÅŸÃá(—Ë ýVé$Ùl6”ØU«U<…rUx µZÍn·×jµ@ P,>é碡‡ ·vð].—Ç㙟Ÿ'âZÜ’%Ò×GT³pa±r}>Xˆ q¹‚[·Û].—Ïœ9ÓjµTV]»\.Haû2™L ôŒ©TJZÍhµZ- [ Žç:@Ùw£Ñ £‡lŽØÕÕÕ~“0“É`¸˜nôz½ÒŒ”F£ÁÛg?§‰¡Ê6RP­§N"ó”õ™×jµ´Ëïìì`hA`¹_©þ2CO˜ÍfòƒÁ ¥²Hµw»F£ÙÞÞ&¾sšµ¹\NY9Õëu˜HN‡”Ú?“ÿH þôéÓ6Áã‹Ei\¥×ëÑ`G6‘HÀ´,‹4\/�ùâ¿ØëõþðÿðyzÿjZY­Ön·Ko3pµæèY°»»«[‡—¦PË�wîÇãñ,,,ø|>5è5bµZ±$Ñ�…p‡CZ‡Æîª•JEMÌì!¹*|£Ñh2™úÁ#ú­×ë‰ÄÒÒR¹\¾öÚkzè!…à!]‹TE«Õ‚…Q©T°ç€+QE—Ë%5>Ànƒ7‚x>^ñÚÚ›¢(Z,n†Øl¶|>/]ø>Ÿ/—Ëy½^Y¯®T*áí—J%õy&Âíʆét:ÝΩÑhÔ°6+7I1›ÍÀç"O!«œ€½-—Ën·[ZDc³Ù"‘ÈÐÐЩS§!11T*§Ã°Þ¡Èxðž¿÷à¾ÅbQnMËBA¥ù€L&ƒ†.l˜Ån·³]vÀÀÂàé„¡P¨^¯³›®¨Ñév»ÚOh˜*ö´”» ‡ÃÒx‹ܱ(Š”p:ÒVÊéáR©ÔëõP½Z­vqqQŠ› ƒý2¸ì¿,› ©”Æ^¯G[!ú‘C«FG°-7Ù ŸÂ ¡ ±oµˆƪ‰NK£Y²3íŠ F8TÖÄçnÃB33@àĉ‰Dö;1ÔS*§_k)‹wÞyçÝwßÿíßþíÎ;ï\[[[ZZBÀóÌ™3w^d/ßûÞ÷¾÷½ï¥¯¾ýíok4š{î¹çÎ;ï¼â5Ü“x<¢Óé°þA,c×I¥RÙÞÞ&«P¶—ÌÖÖç‚´ÛmÎç�á<ò ÎP©Âk·ÛܵزUN¶—%i6›Í/ 0N‰ü—•\.70IÃ2\´Z-è¿h4JÉŒz½®¼Ë´Z­L&¾»T*µµµÅ¶>¢`”ld)›ÍÒ Fly§T*¡õ^.X蠟• x4ö;‘ÂáðÞÞ^§Ó!`–Jâ‰áááËì(Q«Õ¤«©Ûí7_Ÿu·Û5‡£´�wHÓ‰3Hî.--¡Ç~ó”Âz»»»D"Ç2rV*"  hûôô4ÕÑôE´ 1ºi:»ðhêÔj5ò¸éõPÆH£Ñìíí‘WH?¨×ë S¡1ý€Žn€t·Û Böu²œ¶ìüXZZÂ,4R&\Q'''Ùó8Ž«ªd¼^¯ßÿý¿ýÛ¿ýÎw¾S£Ñ<þøã÷ßÿ;ÞñŽx Ûí¾ãïxç;ß ÿüÏÿüŸÿùŸßùÎwÞwß}<ð€F£ùØÇ>¶µµuÿý÷'‰×¾öµ?üð÷¾÷½|ಽ;ŸcÉårpwVWWÙіŵ( ìn6v$HM*÷Û^k`’ÂÄÄ[¸|™\|Æ#³ü¤¤¿÷ööÀ7¡æ \,èĉR¸•ËåU•ÂyÚí6V“Õjm4\Ì Y±¬4²‚ Œq)½B¡ÀYf³Y„9˜|>¿ß™¦F€³~–Þ~0¬T*$b6›ÍL&£žŽAòX,¶±±‘L&···ÁÔív=ÏiZÕ¾$‡£sIÚ—Ý!àq‡Ð‡:ŽÊ¯iÇGñ"u\:{ ä`!•KR­Vk—¤%'ì„£JqVå°7ÀFÉF£Ñh”­³ó„}UˆàCç%aÏà|¦ì«éïs ç_ÿõ_yä‘~ô£÷Þ{ï×¾öµüã¤eK¥Ò™3gÂáðÍ7߇Ϝ9S*•¾ùÍof2™;Nò±}ìg?ûÙç?ÿy•u¥Ï;Øn·¥EAˆ5Ѷ([L&3[ÖLåάŒÁö2ccc°Z¼^¯ËåCå·zæ-Å—Ün·3ÏJ$‘myŽ?ޝ®»îºË±¥Jô�%´¤c³ÙÞËg-k=pÙ+ª/{cƒ¬oÍ)§b±¨F=°3í¹nÎp·¤Uò¬þ¦qfÉMTj¦™™úà4 t’, SSSdÙËŠÙl9 ëÊ3gntt´Ùlnmm¥R©J¥2<<Ìö¥Öh4_þò—gff¾úÕ¯šL&­V;>>Þn·Y;(•J•ËeT÷^%ÏÅFX#Š"tF¡PãÙl¶ÑÑÑT*Ŧî¹ú´H$KÞ<n0…Bauuõܹs0}ö…á›e#Mœ¶K&“²qÔL&ƒÒ¸[n¹%‹©TNÁ`P6>æóùX-N[•Óéäjè¹;!“úL§Ó+++N§“­†W¿ƒûýþ¡¡¡^¯Çds‘[«Õêóù’ɤtØû ˆì.<;;KQ€/‡ÖV•» Õ:ÙÍZYUÄÈJ&“Qð¥Ø8V»ÝV†²c8::jµZAõ233¼3ûã………Z­f±XÆÇÇû<°ÕÜ:å¨1²Xã…ò`ô•Æ:Iäšø ŽŸ–"ý’}ýäÜ�¨ÈŠ=Š`¿ì‡ì ÈNJ@`^úP§ÓĘ,€!sÞ.Ãm‘c®|VåèÑ£_øÂÞüæ7k4š»îº‹b¹$ozÓ›>õ©O÷Ž}*‹5›ÍR©„Pr©T ê‰'~Urþüy­V;== ®kéΈG`ç’ì[ãràõz C´/¡ßÆX,–Íf)”ÏçØ?ÙÆ"HÅãNÆÇÇ×××'&&ØÈX¿hX·ÛÝØØ8yò¤Ãáø¯ÿú/½^¯&’ܾ¡_ÃS¶) «þ釆†ØN9‹‹‹GŽ9}ú4{”l_%nD÷¶t:ØšR4 Ý …BF›2ØÜ‰„ld’®%ûê‘ܺR½½û‰(ŠÇŽ+•JRÌ€ƒL„«>ëÖn·|‹Å2<<LýœØîGO<ñ„ÃáˆÅb¬‡1¬V«ý KÆëõr \%åDçÚÙÙ¡ÒCLz\’î€å=#ϱÓéeW­V¡ôz=m ív›ÊfÈèæ4~Lqgî‘HeƒS®tH3¥6³éõz"ºD"xØV«õÅ/~ŽŒŒP›œKªÓéÓ.™ÃWa=·Û=::Úh4¸Z «Õ:55µ»»ûè£þÓ?ýÓÒÒÒ¾ð…‰‰‰‡z¾ÔSO=õ±}ì«_ýêý÷ß¿¯Î ϪØl¶~ „ËY¬ñx|qq±\.«é~/íóùÀN¦ ›|Â=p§°ÛíF£†0²PìVNwh±XÐPŽó3*•Êw¿ûÝp8¬ÕjÙ¾phxA“V«ÕF…Ò^õ¬¦ÜrÚndd¤_чÍf£ÅËÑÝi«²ù›¬Pt×jµÆb±¹¹9N3q-ò”\5†6‡¬fÒjµ&“éJµX•îêå`åìÜ+–NÒE¤0aŠÅâÁ £ŠÅb.— E^a=0.C–——××ׯT7Æ_7¹þúëïºë®¿û»¿{ík_‹On¹å–ßùßÿô§?m4?ýéO †ù—™˜˜Àwûí·ßxãfzzúöÛo—eWùUÉÔÔÔŽb[¨Y,¿ßßÏŒ°X,ý¾BXOùB*KiÙ°žì†cËëõJ«±“ÉäO<Q.—¸¦´‡ƒ ÛšL¦x<.5ݨŸeT’’¦ÁœN§V«½páB?'Œ '²t·0 ———A±ÆFóp{:N¶ÊY«Õz½^î+ŸÏǵȃx<XÆE2˜pÁ°.Šb¿|ªÁ``CpÄŸ«€a¡‘‡ìQ‡C¶àɘꇃ ÀšÍf«‘‘‘yñz½Î±^aÉ’{NW¹|ë[ßú“?ùú÷§?ýi§Ó9@¬öP4ÍM7ÝÄþûÉO~?~ü¾ûîã~ìr¹èÃÛo¿ýöÛo¿ªžEßÚ¼É)TÓÀœÁçóQ@Éh46›Í~΄ËåªV« ^× Qò`¿•Üà´Ûí|>¯×ë©9m|ðö”­`›ÍÖívé@A`z³ø\ ^Á§'E:£Èìóù¼ì{B“@öö�p–º Z­Ön·W«Uö«~ûi? \L‹ÅR,[­–tœÏm·Ûì=ã¨V«E(«œú·e²X,µZMš…B©T Aõ}aº- õR`_1Š'¹ q¯øÀB¯¸ßÀŸkK¨SNdª QMöîî.v³ÙŒ"% Ó1H£Ñüò—¿$ƒˆR¦l"Š¥¬¥$$™KhØJQ ëÑù)Í£×ë?ò‘<üðÃ&‘HÆÿøÇ˜tÍf¶ßÛT‰JŸ×ÖÖL`ËÖ©Œ’Ýe2 _À*„5AóÃb±`¸ºÝ.•�9—Ëe±X®Â´Ó Lh‹#]jj¸£pH¿î÷äϱ oìþÕl6eý3•:Kbw:d2Éõ½E`mddDêÆžàÍJ¥b³ÙDQ”ºžÕj•Óèýà´ñx|ss“-Øq¹\­VK6¦¢ð•æR²M¡¥>‡Z#ïPa�»Ý®¬F …B²•‡z½^vRe22žö5úåµZ­,aÊåOizŲ_ùý~Ù[RRN»°Z­T”ùƒü�:ßçó½ä%/!¥G-…¨‹Ï‘#GdýÚÙ,}h2™HRƒ}¶àUìšK G(' (ê&(fÚn·É¼íõzPNl›>½^O x{{[j‚Y,Bü±F+Ù­×^{-‚$Íf“æñÄÄ‚�N‡f›Íf ‡Ãl'›Cy¶E¶” ä1û:O¯×Ã&Øét”Q¡PÈï÷/--õûY$ÙÝÝ•-0SøJ½ØívƒÁÀù²µ‹*Ml›ÍF �ô²ìæ%›ä@ã"\.ºÅÕÕÕjµê÷ûÙ¢†­V‹ÆCCCz½^6. +p n $ì'²(fÐÝʺ#WÊA'ûÞáp(„gß3¬¥Î jd“@4²ç?Àt’­å+—ˈ»î+iâv»»Ý.½J”!«Í›,Vý”åáv(/Ti4WÖh4ÊK…L�:°{.¡p_õ«Õª€Ð’½Ãv»-»ã#ƒ¨ ¨Édo^MÅ;ì e×h4sss@I߀ù,£·¿G£Q“Éd±XB¡rlww—îÐn·ÃZ—î}%Ù¯Äáp@U„Ãa¶i·Åbé¨jµZÊE è+h�9Í:44$‚lOU¨…ÖV 3m¿R.—ÕÙl¶P(4*ûŠóù<7è«~YØç7®Óé|÷»ßü“Ÿüäp;>”_­�$N[ŒÙl~ñ‹_œN§ )Åi¶±JËØsu¢þnÆî8XJMÏED·FãèÑ£gÏž•½CD¥ts»C¥@6›ít:“““ËË˲û5ûUµZ%Ý3::º½½Íö¦¡1ä¾R~¹ØpуŠ>çÚ'RÜt½Ê¸¨F£a6›[­V0Dé/˺‹^MýL–~t·gÚ~E¹Ok"‘ØÝÝ¥“×jµf³)û–÷‹뫜ž~úé£Gâo{Ò{%wLŠRáMoz­L–UŒPDäò³XRž¢(ÒßÔÙAŠ¿  µ±EbµZí¥/}i ØÜÜÄL&=öØcTøN"H ì¨-//#x=-h·Û‰`wuue?ìQ©Tjww7—ËIñ@½^ïÉ'ŸÜyî¡Hçý 7Üð?Ñ�­û ì/Fc"‘PÃûð¿á­û¦ò4€YÍÎêz½þ‹_ü‚öÜ^¯799¹¶¶Öh4pNŽ–•`0hµZ¥I6'JFQY2Y©ŒŽŽîììÀoÀm(ÿ> µÛm®}-5<<,‹yb•%¸ž———‰•ÌÑ}ÑÆEéÍw»]‹Åb2™::É.--qƒ‡F6›e¿bǬƒ´Tý~©TŠÅbkkkøŠ(YI¤ƒI'äÆ_öp,‹±ík1€çÆoDb>ŸÏ·ÛíÇœ-)TÊ 4DØ×¤0Ó ,yîææ&{æ\¨ß$ì«œØ phV©°¯6_ÙòÇgèw-2©(ûWõW”WdùvÙ_Ò‡²Ù®ƒ‘T¤xL…·Eš˜-úàN%»q4ÙÙÙÙÙÙCsE¤Ûí* ;ƾ4¬àÅÅÅááaÙZd„þÙ�%8QÙÝÝ]XX�kÀää¤rO…¬µÁ`àŒPl¬6›ÍívÃÓëõ˜ÞF£‘N:®×ëlH§ÓÃNG—¯f³)ð\#(N766Fc¨¦¡Ñµ×^{æÌ™‰‰ »ÝÞjµàüÑNý¢½Èï÷×jµååeYgnooüH÷>J÷r_‰¢µ‡ÏÍfs§Ó …B€:±êŸ  ¯lxx8—ËIÃPÃû/ûÜ ¬V«EG”È#$Øh4¤Jw¿[<K†§Ñh¦§§çææ¸Jãr–˜Ýn‡‰“L&c±ØÎÎÎÝ2«ÕF¥úBw¸—ýÊEÊd(ZØ(ÕeÃò”µ¢ÔÄÁÐ@VY3) ›ŽÇãKKKÊšIáÍfs"‘Èd2Ò48 à ƒè–6;;ûä“OâC—ËÕív) ÒétØV~@`ccc`íx¹\Þ—vãT»Ý^^^FÇBNïž={öÆo\YYÙoYü@AÕ¿LOO?õÔSËËË4=hb`”L&“×ëÅmô+=÷z½FÊ’…+´¨~¡×ëA£×jµd2ép8ööö2™L$i6›ÒñWŒÅÄp¹\l ,Þœ&†ò+V¾K_§L 5PÀ½i·Û¥µ¾Ê Rä]Ò ƒ0ÿÁJÉœ³ X5çE±LHÎßBÇXRòl :Ý vÖ a (7 š´U ‚@dƒÊL9û¶Å~;  ôî=T0–|>ßív)M ô–}>—'Ð\â–Vó²ü~ÿ~ +\.W¡P:ʇcyyYá]»Ýnš´V«µ×롃Ý|¥R¶Z­;;;x4¶Â+SXEý…^¯WÙmvó‹/‚"`ss“V”G©Tr8+++ jÍ¥ÜÄ È•Ÿ¡ù‚Õj…lµZ‰ZaÉjµ:Ð`m‚ÉÉIRü ÂO ‚€ùY(NŸ>ÉdÖÖÖB¡Ðòòr(’*'t̸?°lœûhµZé´-�Ü›lŒ‡ÛË«ÕJ:>«l{‹¾ÊiddT=œ¼ñoDƒ¢f³IÚ ý¼É|#uB‰"³Ù,íÈÇ’˜ÉÆâàÃÄ£¤å99åD†sµZE£T*I—± ‹” µZír,kP硨‘3gÎ8NÌL®ÓŒÑh$ödÚì,‹lìW° ±HWx?@%í &“‰Ö?þðûýÍfSM&™Øiý~?šÁ(ß<ÛL¥¬¬¬D£QéåõzûUïÙív×××m6»Ÿk4•oÄê` ï×é•yå ´^¯§R)¯×ëõz———c±ÌY5èl‡x_agšŸ»»»8 meeE§Ó9V­²à'…©«˜1›Íê[ I' +;|ù ×M&[²ÐŸ{M:”¾S%õ{Èòz½\vA8ºÛÈÖÖ–ÔÔõù|ù|^aoA ÃL§Ó0\Ô@pÕn,.<Ù~?ûÜ¡Ùlf} ­VÛïöX n¹\N¥Rd•&“I ØO¨” ›ÍÂHUŠg)T©T"ë´u:´ W(R¹¼–zI¥R41—–mq¤¦·½4¨CÞÞ@beåIµ¹¹yE¨@¤qEÙ‡:TN‡òk'Íf“Ì´f³ÉÚûøÊf³‘O¯ÀjJ_™Íf®¡r¿mQ!8‰D”I긊^ðçF"*¥\H&“A„‡eÂ1뉢Hè"·Û-Ë¥àu±Ñt:Ý/ò™N§;Ø[­Öññqô"¢(Ф²_y<²”‹›ÕˆÍfÅ+^qüøñcÇŽmoo·Ûí­­-›ÍÆ’ÉR œ—#è‡$%\¦W|95’l00s$‰Ý—V«%‹ÿíÖcƒT‘HdzzšL$xˆÍf“¦#5×0MØ¢5ºªû2�� �IDAT“É„%ÄVµÙl6$ A ›Å`0%KäÊõzŒªèíõz”©SV¬ÝnÓi÷öö¨‡å¢=í)ccc*Ker¹œäûPž_BQ&­V;::Š&âÙl–æ³Ûíf“ÌGò¹\N„™™–" †B!J­+ã1@¸333ËËËÜ®ìQX˜‰Dwn4‡††Ö××¹-†£»Ý—Ql0b±X&“¡LU.—›˜˜ØØØðûýÒÄF¡P8zôh·Û%­ÉÚÑ &¶F£±Ûí(‘jç†Âï÷·Z­Á.b¶Ûí333×\sÛí. da0õz=«84A.—»RŒ‚°KXg¢Ñh<q~΀Ø/µî³$ÀüHçL_åÄÆ(- íòÈj˜ÂNXåÄD@'±Ê Õ«ø U¶}‘(ŠXxhÀÅ)' CnÆVj‚;Gó̤—V«…vìv»„qc=\õ­—¯T{ü«ANž<ÙívOž<y×]w½`êÈ‘#?þø~š™™!PëÌÏϳî».°ÔWWW»Ý.¶’p8\­V±K‚›‡Ð3ÜWããã\Í—Ív»Ý&“ :ouuIö(ìïý‚„‰DŒÀ\`‡–¥ŒÛ ÁB©ÀÈ^«ÕVWW¹`ccƒšõ ±MQ÷ööÀT‰%Y«Õè+NgG£Q¢]ÀWÕjÕf³9Nö)ôz=¡¦ööö"‘H§Ó)•J@¿Z,–‰‰‰L&ôýU«Õb±ˆN‰µZíÑG¥aDǦ~Ý`6z5266¶¹¹ICf›ÛÛÛÊpÚgO:Ž´†bfffnnNAïšÍf”o\ÁH†ìü<,%ÿ5•F£qÓM7e³ÙŸýìgf³¹V«ÁPh·ÛèºÙ)Š¢Á`hµZPÿ°L&vFN•OÁ1A¸Îs/ì¦À¸“ËåH¯Øl64ÃÖ0e5 NGŠä¼ é&R«Õ(@UU³³³z½þÔ©SôûT*Å‚ù°¶Aêv»lj\×.— ô ½^Q¬cÇŽ©Gjëtº‘‘4ž!Ý©F0ív›Åÿ’µGãÃÖ(±c¼­ étšÝà`ªšL¦Ÿþô§`™Ò0µ»ì°ooosˆN§“J¥¸Ûí6¥î[­Öúú:.‡·_«Õ€ucmYz•NeçÎk4,y©T*—Ë‘H¤^¯£”{FAPÊO:Õf³ùý~5U3°cXoáƒV¨Q§¦¦úq˜ÉÊ‚²GØh4ÖÖÖßÁàp[Ŭ¤œ¬V+9,C àÜšgÒȲ÷A.Qbkž™ï¢ ßöÐëõô·ì©XT{~öoªñ£ Ęlti,UEö¹¤3kŒ3±ÙÁÕëõR@Ùs@ð¼/yûÛß¾´´Ôëõþò/ÿòŽ;îxó›ßüŽw¼#—Ë}å+_ùâ¿øž÷¼U¶£££÷Þ{ïç>÷9Qüñõõõ‡zèío{µZ}ÙË^öÿðívûÿøÁ»S©T~øÃª d?{¶¶“]öårí,A LOO‹¢X©TPui·Û�”NxñâEN°»ÒÑ£G[­Ö… \.ZAãs£ÑØn·'&&êõº×ëíõzˆ›ÆÓ§Oƒ^Mù»”u”j_•¡åããã` g£…‘H¤T* …™™©×ë§§§×ÖÖœN'¹)0nä¯T*:nccwðQ¢Ñèêê**ñDQŒÇã¨(ÁJá¥ä9‘oǶBÐ\"Wõù|F£1•J±Ï‚³9s]½Ýn7{f‡ÃaµZqWccc[[[Ü … …ëía:ÉîÑ\y!€íõzðŒãñx6›}6ZBw:ÒL€Ë..@°=Ñh”f{<ƒÁ ûDeh_åtóÍ7“oKÄ6ÆëõÒâ…B´5Ó#ÑÊatd¿€‚…ôj‡A þåìQ›››8›Ñh¤ÚÖ^#Ÿ”%Ú I&“ßøÆ7hÉ!Ï)ŠâË_þr2dJÆŽ,u['bžN§C¿ …B×^{-þ>uê”T½% )5Ùööö~ËvŸUù¾0;;Ûn·¿ô¥/=ôÐCæ3ŸùÌèèèK_úÒ»ï¾{llìÛßþöéÓ§o¾ùæ¿ÿû¿…Bþð‡¿ô¥/}æ3Ÿ™™™yë[ßzáÂ…|ð-oyËÄÄD2™üÉO~ò£ýèØ±cçmo{Ûÿ÷ÿ -‘H¨IcÓ'&×½f¿[�8S0QEQ{â‰'d×¹Õj=sæ ,¤|>ÏÞêðððÒÒÒÜÜ<'6¸433súôi½^ UR½qàMàAØÛÛã ‹Y.TPNÐÂ7›ÍÍf“2¾çÎëÒ´Ùlõz½R©p\¨Ñht}}½Óé�¶xôèÑ……Ç“Ëåæçç_üâ ‚°¾¾>==]*•¶··ƒÁ`*•ªÕj“““Ð=V«Õf³q›]³Ù\XX@j@ÖÄ4 ™L&Øív6¤íÎÎN6›m6›¹\ÎjµbƒEE% ä•öŽÒh4ÙlV%$Ñh4^sÍ5Édr`Qß³ÁÝ'‚}0i·ÛðMÎÃ%UB•Ãz‡ÒW¦§§?úÑÞ|óÍæÁüú׿¾¯5óÃþPv1ÿjÃzœH;ö»\®b±h³Ùd1³E§ÓY©TšÍf4ŠÅbF£qee¥hÆï÷onnú|>i¸Ÿœ6) ø’F£±½½­rµ{½ÞT*E;)²>€«ët:Ö7›Íz½ÊÉëõ&“Ie4ƒÁ 8/Øû“½Á`(—˨Dh‹KEØíöõõõv»­Óé¬VëòòòôôôÈÈÈÚÚšÑhİëtºx<¾²²222 …¶··ñt   ¬ÕjƒÁl6Cy°Žº•K•Hlkµ½n‚Ei Ÿ;¬ÏçC‘´Ïç3™Lår¼kétZšÒ³ÛíÀÆív—Ëe5š©ŸbEñʦ·U2Å\)¤-;aªÕªÝnßoñÅ¡r:”ÿ‘Ûn» šé?ÿó?ßóž÷üÁüÁ¾xÎ;·»»{çw¢EÍÕ)‡#›Í²j!5¨¨})'´ét:V«µÛíNMMy<ž@ `³ÙŠÅb©T²Z­²Ê �LůÓé¨aq±X„–ÂQøŠ-”í÷˜ÍfSZþ„½XŠêeö(Ù '’+ýv»Ý¢(&“IÙ¤‹Ùl†b›*"]ÉdÒh4=zÔh4ž={vee%‰¸\.PÎ/--agoµZ(¦±,4EÉ3KCáñx¨¤^¯sžÖðð0Ú„“ªæ´™N§Ó~¿e{ÒX¢ú-Xà¡t:Á`¸|å¤Õj=Ͼò•BÚ²FE‹ÅrÅ”S©T" 4H±lF´ÑhPƒÂkÔa•}SÜêýA ÃÙÜ ýM­q-:- :Ûašu:j:N¡BJ/kž™ˆ ‡ÃT:HÞjµ`B²Ž|©T¢�[+Ot)²07‡Ã1<<ü¼`½ûÅâG>ò‘Ó§Oå+_QyÔ»Þõ®cÇŽ}àP`3ú• úèH „§&‰ ÂÆ2áRþfkk vÄ‚P9‡±­[,§ÓÉn”áp8™LJÿÐÐ�.EîQ´ß†Vh4ÒýËáp {·r<“§ÓÙív•‹ÝÙѨÕjà"Êf³`NÚÜÜ ƒ\—±±±ÉÉÉL&ÓívGGGív»Íf3¥R)•JY­Vl8ù|~ooozzUÁÝnu\¬.…B8-7J@ ^¯C‡ù|>2;@wKî ga”J%¨â´½"A6õjÉív7›MÎQî׋è�²_ЮôÎûÍ4v1©€lª ÉW,¬W©TÈB÷bîQ ² y&̈Ô�Û‘/Ò"•@º‡UNNGªœØ6줇z½KäA×¢VI½^O63OjŒ5ý~?’aÅbQ¹¸E6ÿ9Î\çó‚ ÷}ï{ߟþéŸþÙŸý™Ýn×»Þõï|‡Ò„²ò¶·½íÉ'Ÿüð‡?ìv»zè¡Ï~ö³WÛ •J%¬.•L¸¡PõZ&Íi6›©Ï »Øà¦”J¥|>/B>Ÿ/•JDâÌس9ÌÆ½½½z½><< ¤~Ê’-Îæj¸ß DM&‰ÍÍÍP(W‰ì°Â&}©ÔûèÑ£¢(öÃÆ’µ½½‰DìvûÔÔT<§öØétÚjµ²p···1,Ò ãp8‡3™L«ÕâÞãöö66<rW;•UÉPfÊs&‘Hp$ñjDýQ*{SíW"‘ˆÙl^]]u»ÝµZ Î(ËN«^ú¡†Øa„±uùàèðޡh4ͽ÷Þ‹e|Ýu×=ðÀäe¾êU¯úÒ—¾Ôl6m6["‘xõ«_ÏAêqß}÷áß믿þˆÇãñxüž{î¡pÇwÜxã¿Úça||œ-W+‹û¥?/ ´õƒ… é~öl£ÑØÙÙ) Á`å^Óét‹… â{<$?Ð,˜z …n·«Õj‰ÄÒÒ’Óé4 EÆýîDM,èÈ‘#;;;Ní0§u:Ýðð°,–/Úf³ÙívÒÐÀ<õK’;ŽP(„’“`0ˆyåp8677AóÁYlN§SºeÒ¶R©Èî•Ni›N§uTö?,K«Õ’­³§9Ó#<66† CÙoÕ÷è»R'{{{ÐF»»»è+0i¯×“öÙ …Bä¤ÊÚ¯% –*§C9¸;ŸÇã¡ F«`ú}åõzé+⥼J„ M(t²ÃÜßjµ`†sJN«ÕNNNnnnz½Þµµµz½ŽF8쥹C¶¶¶A�×~9;;›Ïç···§¦¦L&Ü‘P—Úív—˵±±‰DÊ岂¼²²k·\.‹¢HQ°š&‰ .(Qkµ»§+ï_‹åäÉ“çÎÛÙÙ¡¤W¯×ûú׿~ìØ1îp«Õ*ÕsèÑOÄb±h4zúôi8‚èÕ4pÄЫþĉ§OŸÆ»p¹\(%§9Ó/ÔI¤¦²20@j³Ù0g”Ç].×ÜÜÜ~FŒ-,, z«ÕŠF£‚ ø|>)öv_I)eq8,àYQNccc·ÝvEðh® ¨Õj ät:NêõzdëmllP/†X,Fá>Z eÀÔ¥_²ð)j†ˆ^´kÐ¥.–z½žŽ¢6-ù|þ±ÇãžKÅ'NàïááaêPŽÞÉÇR©$½–N§{Ñ‹^t¨Ÿca„Û¸vêé_ƒÁÇXN[Ì´ÅÅEdû¹éMk‡û“)Ç355®^¯…Bè…ª‘C#±l­²8Çr¹ŒM‡rZ¦˜ŽªÕjÄhcµZÝn7vI@YçççQ¨0 l¤®ÂñÉk …–––òùüÙ³gQ+‰DN:¥Óé677#‘È÷¿ÿ}Îâp .—Ëáp(#1¶¶¶¬Vë‘#G,Ëücõ«—¼ä%¬´Ûí>ŸÒèÆÔ/@ªR[¸Ýnp…H&êú¦0ýt:¨“Õ èTZ­Öf³ÝvÛmÛÛÛ±XìÉ'Ÿ,‹&“ ®0w9¢!æN¨ÕjÝnw<ߨØH§Bs�(f¼ýb±ÈúRjh—U)'ê÷£yf‘B?H0ñ©Ó€3WÞDØ®”t])Ñ2»PY˜=%À8¾>j¾'µ³Øûg¹£.C¼ú+~MD«ÕNOO#q¨{¯fÁ4 `n|> »ÿ$Ô§ú;$vÚB¡ðØc<yò•¯|¥^¯×ét™LæÑG5 V«Õl6³Ñ6vßÈÖÈ.(QádLOO_¸pî-PʾbaIÔýAý³èõúx<¾½½]­VÙ;Ôét[[[l÷¶B¡Éd|>ßéÓ§{ì±h4j³Ù Ñ!q-*Ýé¶9&Ü~/qyyyll ¤M*%‹?>‰€7kxxxkk‹Ê:`@P¿%öU†—Á}%[™—EÉýN¢ža³Ù<ŒŒãÇ¿üå/ƒNgkkËï÷£)‰ìTw»ÝR8­Ùl‡ÃKKKl|’æ- ‹FîÝ¿àŽãÅqÆ5=R‰Öv%?”žt»]¶¤Åh4’™uù’N§±•X,–xL¹fD«Ñjµhãº?ìShAév»C¡P¹\VÈ[ììì¤Ói@¤N^(B âüùó¬ÖÜÙÙ¡�†ˆâÒµßWœø|>Y–n·ÛMMÄѸÒh4:N”Ò…B!Qóùü#<B1=‡Ãáv»5M0Dq¯òmpà QNÂýÌd2±6(ŽNk}}½T*ÍÍÍ™Íf¸¿{{{\<óÈ‘#“““äÃÉ2YÈ ÛíØ*…øœ._J¥4“Édr8~¿ßï÷cäÝn·N§“v€är¹d2ÉR­Vãô¢ÕjM$èÅãóù€v0™LÑhÔh4ž;wŽ’ÖýâÀðÛhb�û|ωó{¨H¤>¾¬&'È :—pÁ@´*Á‹$ˈ ÐQæ“ê¦ð¨Z­eg£¨e³ÙL7@ig¶U’taKn†eåp¶ÝnÇp±ÎŽêçžg³Y5<¤‡ÒO …B?Æ»ÝNÝŠ•Ã/².‹ÖdÅãñìîî"dg0œN§úR¥……ƒÁ€~ç…BÁáp¤Óiôû¯×ë±Xìé§Ÿ¶Ûíd¨ö—Ë•Ïç;øQažÃärn·»X,z½Þf³i4¹¬K’«,ÉdÒn·s¨^Í3«ã€Û­ÕjçÏŸ÷z½n·»Ýn§ÓiœŸ|P2ºõzýÈȺä±OBBÚrGq¾]º=:ŠåA‚XªõÄO°ë”›”Ô1™L‚ ÐÍ‚àp8Pæ§ §­Âþãt:Ëåòîîn±XÜÝÝ]]]]__/—ËD(ð�;Ks‡f³¹×ëéõzŸÏ‡†gƒA§ÓÁ§ÇÔÅS+´ –eÞhD²&ÜN§C Ãd2QÓîB¡@¯ùm¯b2iôÌü Ðò¤<pO:Ž6QIÏQb¥Ì@*´½f–’„­e§i144b4ÉX`‹ÝÕK0dÉ]h5*§1ƒÁ ÔHÉçó˜Rm×n· …¡rº±ÙlR“èºL&ãr¹”7z� d•“ÅbÑétRåDYÔã!­åp8Z­V­Vóûý™LF!Ö×l6·¶¶Ìf³N§Ëf³<òÈèè(f5äñ¼‚† P úú×ëõb±¨Þ¬åúúºÙl–*§}‘äÒ¶ŸT*Bƒ‚Ž„¬U\Û¯×[,¹mŽRƒžáŠÐ¤ø\ÍÈŽ1†¤œ`Ò.ÄÒÝr¢ð¼šK8kN§Õj›ÍæÞÞS%§m£Ñ˜ŸŸGý·Ùl>sæL2™D'Ih(§‘‘vTûí?ƒ¡ÛíšL&ªôA›òüú݆Óél4 *šÀsíC9 ”Éjõ·®\ǯ³´ÛíH$¢†çôPö+êˆýP“h’‡•ºœD"‘\.+Êjµ Ú8.Ò´ ›››‹eccC§Óaÿb3¸ ,çPe‘¶ô¼€Óª´ÕÀ(M | è á÷ûш= ûŽœNg§Ó¦è{/TËÀ7k±XÐÿ†B!ꙟ²^¯³5iÅb•~ÝMöÎà"}‰Dööö®¿þz´|\^^f“m²Ô'²˜îõõõl6k±Xà¢a)zÒo”«1õz½ÛíÞÝÝEÊP¶øÐét:ÎL&s™,šÍ¦ì: rÒõzÿ7•7¿+!l#öC¹œ)Î}R¯×a¸ L§t[¶oK»ÌÚÚ태ËΞªV«¡;œÃáØÝÝ¥ò8"œ7s0„#‹U´••z½ÇÕù8ÖÝÄ–º³³ƒæ)´ÒÓe³ÙX,&Å÷z=Y±nk8Îf³@•±Ú!Mî½4›Í`0ò‘+ˆíV•zr\´U”n·ÛívI=ð¶¥?€¯“ÉdÜn74%ª`¸_îìì †áááR©$Õyä`)H«Õ⸕¹HûeŽs_åÔ¯úÇßÝÙ‰JöäZ‰[¶×ë±€Hð°ø|–é™rql‡£Ñ+£Õj±ý‡¤Åxf³©TMÄuµZÅ<wl D6³µµ•ZéÆÇÇá΋¢HÑÈd2‰ls¿£¤¡d@2ÌeqqÑd2 á^¦ôz½ý¶Âdϱšr§ªV« ’h6›Ø>PáF Üh4šËåªÕêÁúI³i’jµ ÃáðÂÂÂ:•(põÊTqÃ###¨ø• I©‚†F\ÀMúȇCjj”Ëevýêõú‰‰‰b±(R½^o6›°îõz}$¹ÌTëF 5 Nx�8-§0¼^ïöö6�à…B¡R©HIrfF§ÓI$Ô2ÕR0S»ÝÞÝÝ•Ýyú½,nêJoŒCg?+Ê©ŸÚE1ØhüîînG£%±N¶Ü�½Iè(¨?ÁBé—”¯£q*iÍ7ZÜÓÏèºl£?ÒyZ­–Š;´Z­²¥C~¥6› :I§ÓQZnccïu`Á»>¯*¶§çär9¶ âÀ 7ŸEqbbØ>,©ÛG ÜÝÝÝv»=33Ãqòª°šrºªT*±{"AwñïÄÄü•û2+8 ªhaaå¹ßÞÞVVih„&Šâ@S]£Ñ,//KW —ñ!.Êm ív›öÍP(Ôh4ªü£Gv:¶»ç=\‘˜¶Žf³ù裎ïìì$“É{'@�`Éd’Ø“e_¨Á`ðù|RWl²çÇWÜœáöÌ+E0¿ÿRò^ïÿllè{½o\ª=”C¹ªDMD‚yDžÉI$9qâ—íØßÒ’°_Òç³³³) ©ý6¨l/^¼8P39Ž'NPòR«ÕJYMQ¯NÛ“'ObûfÓËË˲Y¿âŽ2 €*¶Ûm<x£ÑàîÁh4NNN²,V«utt´Õj…Ãai ôÐÁˆ;Jv4 Ò÷ñxÜápàþggg†ËåÞÝÝ%·ãøñãýºœ\¸pA¡¬mî-ÓcJ¹æškú ®ÿÎÎÎÏþó¥¥%D&÷e‘¤ÓixHöN§ƒ™ÃY?˜œFƒs"ñùüü¼Ùl¦~ªftt±+4Å.—Ë4g¸‰Á’+îk™ìC9ŒÀ­½Kò’lv¶\.Šâ—/…Ñþ× Óé€Ì‚´Ûíî%¡Ã5—�³�¨Óš—¤Û튗„½.ý²ÃˆÀkˆ‘°kˆZ­V¼$år¹.ŽÓÖd2™L&£ÑH?�.Döº‡êáê§Ó J,`€ÛY¶¶¶ž|òI™ "N¸%@^ â].Ñrj4š©©©³gÏ®§ˆ–)3rîÙm‹[Æ,á2Ê ŠÅâ“O>I»ÆØØ@£\h<·X,ÓÓÓ?ÿùÏ-ËÄÄ;iûy9ñx\Ë…£Z­ÖÒÒR"‘ÀsE£QYíŽÒYvÀÁ“ 7«_+íím“Éd·Û'&&0h•JE6f0ÆÆÆèßµµµb±811!Š"ªÒ÷ööªÕªÏç#­977Ǭ³¦&˜ èû ¸Í‰­åùó秦¦ T¶“° ^èôô4Êm¸«Œ!qS«ÕØÀøòò2¥¯4ÏLÙ(O 5Îý¾Ãz‰D‚õÚ`˜;ßßÜÔh4÷{½É !ÛD!F£‘nš‹þ" R¯×£k QNœ.8œ%\§á¦4+`~ãBmkkkTm¥CÇaÇu:êNÄ2áʆhŸ×Ù£¹¹¹\.wÝu×Ñþ¸³³³´´466FÙÄ«\PW­œS¡¦(rËd2ýR¸ìÙ<ìõz½õzç¦Çï÷_¸pM °"„…wvv†††XÂÞ ···‰Ë v›ÅbÁZðz½Õj³N«ÕF£Q5 çLE|…}SÅ\.W¯×Ñ©HúV«µV«IwF•ÅÖÍf3•Jy½^ƒÁ@‹š@2šÍæN§â«r¹¬æü8!=2¨³h+ F6Íf“sL- õ…‚p*½©ÔÏ1ŽeXs©¦åvîåª?ùJqô‹ÚaÜNœ8ž †õ)¾“sçÎ]™°Þ’IW§³a0ü àñPžïò¡}赯}-»ùÎÏÏîsŸãRW¹ô õ“¥¥%ÇÓï[¢þƒZbe8z½.“ãQ#‘ÈÅ‹A•âõz9}_P(µ¹¹I©‘F£±¶¶/}"$t‰6,•JÑÖÜétVWWr‘v�qø>Ð~B¯×9rT5lÞÛn·£á¾F \ò].Kÿãt:Y³5²Ùl0ŒD"¢(²Ãˉ› Ï€L‹ö´N§Sên²çBÀÆëõJý9h&NÇ}¶[%BÏé…¶¶¶*•ŠËåÚ/‹’“«_‹‡‹(вs¦_ù&!ù‹Ån· =KÅÆû˜…ÑZíUé´F£ù¢Ï×ËÈ_àrÏ=÷|ùË_ÆŒ|ñ‹_ìóù¾óïÜsÏ=•J…¾º:%Èû=ªŸåî÷û¥gs¹\ƒÚÃ-,ùOØÎÐa( êõz›Íæóù†‡‡IÁ°žR)•J¬u½¾^¯÷k¶$£l¤qvvvll Û7bщD" Æb1TÚl6�ƒ€µD‹•Cg6›‰° ', (4p»ÝN§“@T,..nnn"­²²²T ·¢!¬c7AƒÁÀºŒá .�� �IDATGÔB wÂíã[[[èÏF'&&ú »ôX,A¤ô¡[[[Òî¨+;«UBÙö·û?sÎLã~kauu•¼m½^o0Òéôâ⢚J–ˆR‡z%ív»ÙhüáÆ†V£9oµžu» ‚00$Ún·©(¨P(ÀÐ`¹×ìv;M²zjµEˆ´õø°^¯SQ8ÝC>Ÿ§R}»ÝÓíËh‰ÊÚSd‡®¬¬Hg[6›…‡.B<§‘‘ΓÉDvœÏçÞÕëõè—Ïk˳$ŸøÄ'ü~ÿ§>õ)”>¾ÿýïÿä'?ù½ï}ïÁ\ZZòz½ÿøÿØl6ßúÖ·^åb·ÛAX»/q»Ý‹¥Z­†ÃásçÎ…Ãá\.gµZ5r8€O†B!­V‹¶Fn·Ûn·ûý~ÌRÌj‚aqûbzÓÊý65½^?66f·ÛGGG- h~Ž;FAx§ÓÙn·i‰¢N?I®Á`p¹\œÜÝÝí§ÉA@<Eû|>P¦²+ŽÛÍ‘¡ªK»Ý‚ú¾â¶tž~ºahhhmm­¬e?€àEHy•´ŠÊ(Wõ1�jØvÅEÕËÅñt:,LïÂãñÔëõ˧“ߟrêv»¤Tëõú‹R©©JE£Ñ|%Ñ ¹âW©z£ o©T‚aÕn·i†QÕô0]‹¶—ËEG‘ž«V«¸´ tøÎÎÅj?Ž;gíÙªn§Ó922Bs]úD4EQ¼þúëñw2™”V*;RNd²™ªç—ÌÌÌÜvÛmÿøÇ¿õ­oÝzë­ÜW¯{Ýë>ñ‰O|ë[ߺ:•º’#yùúÒ  ™f³‰<P­V3 6› -·Ñ³¼Ýn×ëõ±±147;~üx"‘¨ÕjçÎkµZ(ÁH§Óñx¼P(°µÈlÇH·ÛÝëõ°5 ìÂ�@y{µZÍår¥R©h4ºººêñxœN'ê @‚Œ ô¾\Yé-º ]QÙ6<ýªHm°ëµ‚@ •JaÛå¶ÒaG)iRõlì'Øm¹û ‡Ã‹eeeåâÅ‹û…¬±¢ÝnÇá‘H$N+ì—ƒùE2¤Ñh¨¯Œ@WOõ<‡œHçŠÚ0dÓ]ýh|=Ûþ +'V Λ··5ÍN粺^Ňò¼–×½îuøêê ë„üÊòFsNp>ŸGcuuuyy¹V«Á kµZããã+++FÃb±ŒŽŽb ‹ÅP(´··—N§»Ý. ¹ ŽübWyWlö$ñÐ7'™LºÝîT*‡[­–Ùln·ÛhÖ¾³³Ól69䓿R¦Š(’ …áááõõu.Ó� Ú~·Ý¤m*•êõzÒ^±$¨ófÝÊ|>/ë 5›M°=)ûšD Ëi¦p8 ¬«š.‹ô˽½=ºy‹Åâñx8ƒõ`ˆi²ØW©þ@D•‚Á UʨĨe­¼YŽG…£°FØ©;99¹¯z“ÿ±2ÕüèÕ››žV«§Ñ|©ˆ=”C¹j•Ó~颧§§Õ#¦9?íjµZ$ñz½ÈîØl¶“'O^sÍ5ÍfaÀ­­­_üâ ãããår¹\.·ÛmÔ4k4šx<.å†`Á:ûlR•Jì!`7Åbh9±±±±´´´¶¶–L&ÑÇy_*<ommIb‹{½^o0”[­VÑVÇn·³¬¡tºE ‰¢8;;Ë*!6´Å~•ÏçY7‹ýнn±X”jzê¨Íî¹ýº\ŽB›/94õzýJÑ^¿r0£ wHɈ~£ÁI©TRö&)“‚":JAsSW}aUžÓ7¾ñ Ðx{šÍWmnj4š'¼ÞŒÛmÓé”Ù)PV,ÉÁD÷eÍ3Ùio¸áª¡äÓÆÆU1¾þõ¯—¶šv¹\”@¢£PWŠ¿ÏŸ?OsˆêŽâñ8ârheOï’ÏÙÙY<‘N§£mâìÙ³°ÁA F£‘2U\¤›6HÞîó"ùtÓM7=øàƒ€éü:è³ÅÅEõ {ìüŸ››£…J¥´Zm:¾á†ü~?Ú£!•N§2­Õj€1šL¦x<>??³—fu,[\\¤ õ#´ÞD¬Ïf³¡'^2™<uêÔK^ò’J¥R,Ïœ9sýõ×ÏÏÏîÿK †ãdzAé±±±T*U©TææædÇJ£ÏRE:‘ç‚7§Ûí ‚J¥Úív¿QQé+²ƒ>533³¸¸Èùj„ú�>÷ìÙ³…BAÙçˆD"µZÝ—9ˆë~ù^q‹Op P{,”ennަ“‚Ï­ròcºJ'$Þ£ §OŸ)7*&8ödUʉ˜(okËÐëi4šïD£9 ´t e÷kú—¢_þV%ë.{N�8è ,—.;§qÛÇ.ÁÇÑØG½Ö@á~)\õUŽÁ`pllì»ßýîk^óš[o½õóŸÿü×¾öµ±±1‡Ã¯ðDccc²¦ñÕ/²Ü˜'¨ÕVvVt:]8&c³×ëMMMÍÏÏ‹¢‹ÅFFF\.—Ûí† ‰DšÍæÚÚZ6›ýÉO~‚]£ÓéÌÎ΢PM£Ñ`²Z­Äo„Rrú*N­­­ÑÉR—J7†¤¬{‚¢eooïE/zÔt;n6›\º¢FÔi0œ ëíÏÉ;*pmL‡Ãn·onnöz½D"‘L&¥ÞpÇG}úé§©üGÑoN: ·KñC ô èõz�áJA¬œpeÒé422²µµEÛ±(ŠZ­Vû‹Å²Ù,%u¬V«×ë½"µyP<4z½^6F§þl³³³(öÙÛÛ£Ih0Ξ=‹qSÃ%ÆŠ$y@Îi´Ryé%ïož~ZùÇŸ¿n}xhèßäÚŠÊÕ/wÝuþ ½é oxÃÞðFóÆ7¾‘~öøã?Ÿme­H›ÍÖl6©‰'Ü}iŸi§ÓY©Tòù<Á0/\¸`±X�Žù|¾H$‹Åz½žÛí^]]M§ÓápØjµ¦R)PNœ;wN«Õba#ɦ°·®­­‘ÕL7 _–Ìvp8µÛm):rxxØårÙívlN%ìµZmuuudd¡EõC744D­Q:ßjµ�f¿Ò\b8ÅÓÙl6Q‹Å¢å ÙÄR¡P 0F¿Æç~¿ßår={–özö(“r¹ÜÏQ`Êãñ4›M§ÓIu¬ÊARPö$41´Zm,ãZ sµþ„³î7°(ßg¯Å¾³Ùܯ ú„nsÏÛëõÈú¡Qp›œóçÏ[,zAèðÖÖÖ®xó¥z½þõŠ¥öº]8ïT,GíI´Z-µrÑëõÔ–Š< Öla›d7“Ïç1¡A 2Ãn·KÅèñk.‘øQ„”jLé®d_9û’`Â`5Ò‡årYeJü¤ø[™ ÷PžéõzÒmËápT*0ß°ˆ‡ÃQ,9åD‘j·ÛÝjµÒé4u”7›Íè®m·Û£Ñ¨Ïç«Õj(\ÞÜܬ×ëF£Ñ`0€ƒÕçóéõzj¢ÃºAä9Éúmn·›*¼^o&“i·Û šå•Á`0d³Ùjµ:??ïp8áÿ³÷¥arUÕÚ§æyž«««Çêîtwf2ÀPDP@‡ Ä+* 80 Á‹€^Aq‚€rå2\(£$d é!=wõ<U×<Ïõýx/ûÙžSU]lµ÷<:uNí³Ï>kíµözß—‡sd¡="-CW´aK º@ÚF£Q¼ÂÁ`6L‘H$“É�o¤Ñh Ãðð0Ë3)•J¢sM›iàdÁdÆíC8öz½åC[îPÐï£Ñh$Gáû‹¾Ë(§Ä­q­„Z­†´.8ËO9®ûäzýX,VªÜQ£Ñ„B!n©P(²ÙìbíI)­ £Ñ˜ËåÈQ2†2™ŒXi²<¢%’m6›\.¦'�žc…õå|>¿(Ó|9çtÚi§y½ÞÃv»ý}Mt®ó°ýýÐÌJ¥øB@ Èd2B¡6Íè½H$Z½z5½F cÍu„$ŸÏãØØ^]r›@šêêêp‘H$B¦ÅÜÜ/Pä,º’a5ÀA>ôx<FÜ€üV%Üåö5,ëXëD(ÒÎ@&“% Øk±X¬P(²+™šš²ÛíHÁÓàM”„E£QN‡·Úl6ŸÏG–À`+@‚¯�¤wh³‹mZV±ôsÉÉ<,Ššôz½f³7B^@âÈ2ï‹�%“IxMÇ£Ó鸧ÐZ¨g–•T«Õ§œrŠÑhœÕjµ¨Ð#ï)ŸÏ—H$J¥’uwX§ …B2J¬G ‘HŒ!¸C¡Õje2Ùüü|6›­íóù€V ‡Ãô/"($½âö­ªªjff¦Â§p8\ÆÝ–‘.b8tìÇÝPÊÈCnŒÅ’H…Bsss˜Qd4À? ƒi4�C¹\.èçŽh! ÊårR7PQZ¯Ódê4™è} Â’›Ïç÷÷‰¾[×®eÊî}-·å¶tÁç`¬Íf+º€u8E58ˆÆ¦BŠÞÞ^@�gƒWï­X,ÆEìv{>Ÿ'çâýgñ#H¥R£ÑH¯¸«ªª¦§§Km‡§ÓɲË,»ÆãñB¡ì‚Õjõz½ôM±V÷Øöçþ} š|>?²ÜªÁ`P«Õ+V¬Ø¸qãìì,+MÇãñX,P$äÂf³¹hír*•:Ž26ƒÁPyE>i^¯×û¡(}îŠu–H$Òëõå—SÜÅb±`•Æzú¥&<·ùý~“É*bù+O744 “•"kK^¸l¤–Û¿jK&“R©™(:ÇË P(�Ó&%£ápØét²^­šššx<^SSS&\†–14â&&&©xê©§V¯^ Uò™™™ééi¿ßEAnƒekr¹\0¤˜„Öd2q©‹nll$ª¦V«5 &“I’Q Ó,F£Q£Ñp5˜÷á«&“iAªiäµ Áê<²úh|>Ÿ¾_B2‹ÅJU®b3ejiñ0¶ ƒÈ!ôCˆ�Û~tIäñ5V‡é‚OÏ›|'…'bÁFC°+Oq—òôe2r`Œ¤ƒ'50%€Ø¬YW¦ßµx<‰Dô•8'Z䊮p#Õ,ÜPô•W^a(Ù@³Ù\[[ûXg'÷†ëëëIÒŒ·ÿ¿ÿ÷ÿÈTÀYB¡Ôco™åfçææˆíhmmExHg´ÊÓ&#FV«Õ---¤W$¯HªWU*Ukk+þÂ8( Âo$•J1\ Ç&ÝV*•jµºh$^^3f¹-Ø"‘ÈÚµk‹föø|>mú‰t©ßïçñx|>?‘HlÞ¼Y.—ƒAƒÁàv»ggg- øÅQ”Àž]ˆ-U±XœÉd¾î¹çP!¦§§»»»É ¯d¥LëpÒge³YˆÑYµÆÆF,?•J%9+ãobhÔäÈÈô—ËÄ ðjZ­V$ÍÏÏWWW³¤¾KYC±XœN§{{{Õj5èÀY…`ŵX,ÓÓÓÉdÒårMNNFlkÙl6ìèЧ€¯߇*j ëëëÇÇǽ^¯L&s¹\Z­vllŒh½ r6ñxÜb±äóy…`…ÊÝ21 ™iE.¨„K~k±t EဵµµSSSe�L-f½z‹B ›L¦l6[I漤s¢™ëèâi”ä3 #äÌlÿÜý>Ÿ$ ¸7@ƒÝhñCDB˜æÆÎ-Ë9%“IzÈàè2n…BíŸB¡Pô)F£Q¼x´`©// $ýªP(Hétò¡B¡àÒôbÊÚ]DK¥RÀo.û˜i\vNY›Í¦×ëÉô Ò¥due·Û][±bE,ÃQ²½Å]©L–+  `èîî7„V«Çã===xè--- …GËß‹V«miiN–e¼^¯Éd²ÙläÐÄÄ–Œô1gä½#5AÜ@¯×³jÓ …¾ƒ³G2™L¥R­­­*•êÝwßåö¹­­ ò‰D"™L ‚cÇŽŽŽ"?yê©§’³�6êà ÿJì”×ë¥ã¹\n±XÆÇÇɾ5kÑ ŠXœ>55ÕÜÜ|ìØ1FS]]m0À€î÷ûé'ˆ *ŸÏW¢„‹ûR(E)€éÀnvv–öDá7‘HØíöD"‹Ìç󛚚Èb·¼×ÄVÙ‡öÍÌÌ”ú9—Ë566¶víÚÎÎÎúúz¤j½µ_aB²Â,ë¢ÓzÖx|•ßÏ0Œ…óº>g³M¥ÞN&_ü`x�ÿUQ/\ŠÆ¢©§©©)V (íjkk±»€ŒY*•‰DV«5“É”â(£a˜XÈ+ £Ñ822299 Xh{{{___&“I¥Räçp´h¢‚FØ„B¡ƒ²îÈÇ|>???O¯Ì ^XÆÀáDünuuu$¡—ÌjµZ£ÑLLLÔÔÔ�¿…ß•Édü`Û]…B¡¿¿_$­X±‚ ‚µE…ÈÜÜJóù<Ƥ£££¥¥(N˜¿B¡�Ì¢Ëåêêê"kVȈŠÇ|>o±XÒé47`¢ôýÄb±ËåŠÇã):Šöp8 Ÿ;mmmlnnîééÁ0VUUjÜW<_æ h-5’œ`l"N‹N“=K¯×Ëd²òÜçek:1 ·­Vk.—›ŸŸÇ\- Œæñx‡ =ÇÃrÁét*ŠŽŽ êðLñCôÏ)•J«Õ:44T¹¯-—Öcɼþß›‹]Xâ!.“.“™‰¿òù$£Bâ\®‰Dt¶Xò<°F4Cß>dÅv4[·o©TŠ›à&Õ€ô ær9òM¤Ô™ Ðøe¢`²°J&“E ”vû'–œD©×˜eµY¨I¬…>FS© Ä% ½Ã„j4‚Ïõx<€.ðù|8'd6€ÏÕëõããã0I]]]Þ.Úº!iF&àÀ4²•a˜+V� …ú]ÇDcÉ‹¼áBaCCh)˜¿'"–Z"‘¬Y³û4 ™ÆËEê¤é·£” æ¶T*­ªª¢Q/…BÁG__Ÿ^¯7›Í°PµµµjµúرcåÚÄÈ’L¦D"I§Óà) …ä¹ÕÛÔÔtìØ±þþþöööC‡I$§Ói³ÙúúúHqÉüCyo``ÀårA€Þ("Ú¯eY ày{"•Jé´'ëѳ2,{ÍçóË“-ØœN'Át“¼hà6«v¦(06ŸÏ¯]»vrrrÍš5Æétö÷÷÷ööÎÍ͹\®æææl6ÛÝÝ­R©4 S½^/vªÈ$dY¿t:M?Ç…“Z­&¹)Ð0ã﷔ʷ8É}Z1:™LžÃ¹Ú)§œ‚çA³’Ûív DzÖßßO�žŸþô§‘‹‹ÅbÚ&—Ë‘@£t*•ЍÓ­ÕîïïÇÐðùü7’™»Ë …öíÛ‡¿W¯^ TÖñEÖt¦ezzz||°ê¢¶uu"íðáÆ«PÌMVsQ“ÈNôöö* Çy@©T W¼ê£££Ÿk·Û± ¥P(úúú P«P(T*U,ommõx<ц††ðvÐ¦Š«jÊš‡2™¬¦¦ÆçóÑIy$Íd2™Ýn¯¯¯·Ùl …"?ûì³<O¥Re³Yîæ„\.Ÿœœ„úN©„L&ƒ­—Àš¸Ýn sA‰áD"1;;k4i;HÔNý~?ÓÉÉIŸÏ7>>.“Él6ÛÀÀ�Òé•ìêcCܵF£qnnŽÇã¥R) zñ[‘HäwÞ)sµZÍçóé8,NOLL˜Íæ Õè¦P(ÇÜÜ ãœNçôô4=V¥0Ý GXY&“iµÚ©¤à¦‹º:¬é+$!Gý¹Ï}Îb±`öZ­ÖT*Õ××GcY v»}rr2›Í–ÕÚÚÚP(d4¹Èëåj½åöï•ú+ŠšÄÒæL©T¢’%•JÁ9aiO^øX,–J¥h»<ªãŒFc<¯«« ¨)O¥R …‚v?P5%8G†Ãž‹ÅJ ic{¦¡¡$–±XÌf³¥R)µZǹ†Æl6§Óé@  ÕjYΉà‘åÓh4©T îA­VÃX°`˜4ˆµTÁT£ˆ³Á¶ŸX,è¤ÅbÉf³ƒå‰õ“ ž¹Ýn\ ÚoF ¤R)¤ÝèýÅ2­èwŠ \µR©,³³‡YÏkhh¨ººšµÑšÝR9Iúé@ œ …"“É ÐëõÑh.‡’Éd‘H„H$ÂÎ+ÐÙ+V¬˜žž–H$MMM�®Åãq.‘›D"‘J¥d¬�o�â³èM ­\¹èr¶ï\6XËm¹±l+bˆR5H^¯W  H‡Ïç766 P¯X±ÂjµÎÎÎbÙ«Ñhæçç% ÌH«š¢ ½Ìßf³‘‚ ¡Pèp8@)@‘wìØ1±X<444==MWÆ“—||<‰Ð =Ðl)ðë…-F%-è›5 Òæ•ËʉD"ƒÁ�À¹ "H8†P(l,„Ðb±˜Çã‹Å´.¨@ (*cH¿Õ]rˆËË|‚5PæóYÑðììì‰ ¸H$.ö¢N'Ã+—ËÓé4, …2™ $&“I(‚Óó3‰ÔÕÕÉårP¢ǃU ž,™¢Ü±Ä¢h—²Ùì±cÇÆÆÆ¸¡UÉȉæí ¦Hµ3¯&•JqÈ€“^’—*NcJçmÁãBç^Y¿ÕÙÙ‰WB,“b6P;3¯3K·5kÖ`tòù<)ï& ýRê´v»k#hê‘¢J¸dDSÎ B>çþÖr[: ¡Àq#Ç«««ôz=â­D"ý˜ééiº4.ŸÏƒ 3M LLL@=9—*.W«Õjµºè>e(êììôx< óa½Ø•è“VUUMLLÌÌÌÈd2¹\Ž%¼Ãá …ápxrr²<‘ }݈Hn(®>>ŸššÒétÄ©3 ƒâ·h4JT:™dB¤.‘Hà~%‰ÕjemÏLNN–rN<h§Å>ål6[Š©¡Œ?Cíû’ší¬b2™L@�œ°Ï°´x@ û˜›› ƒV«uddäÈ‘#ù|žU%Ë û ÌRO&ét¨¼%_/霠WF’!ô‚N2—Ë‘ •¦¶£W=Äå%ËJ¥RäÊGB;'²Sj0ˆo�{ ¾Ytoýúõx%0?XCÆâ1#­(êphhÙ›•pS©Ty–èåöi44²h+U¥R´©T*‰DâõzQ"QSS‹Å.ºè"½^ÏãñPøK¶ÐQ±–N§é©EÖd(½)UÇe´¹{$[Ün7a¾!ÐH|Äken¢Jxûr¹\*•‚?À…€:)•Jxœ#"‘HP;‡šÍfóûýä­$žZ±ä1nävÆÇÇ“Éd]]‹Ø‚ÆçbS~Ër¹œÓ霚šâóù­­­‰„Ïçûý~³ÙFá¹–’óôÞù‰7§Ó999IÛ+£Ñ˜J¥HÀ½¨8©ªªŠ gÊ4ºø“NÏ:ŽòÅ„•ˆä’w¡r¹\¥R›ˆ“““mmmãããÇŽ³X,R©´<•ÆÅe~¿ŸøÈòcyÏi¹ý+7ž•Oâ±òE\USúíU©Tƒ! ¡Ö8qÔ¹‰ÅâH$Bq–;¤í9¤-(PñIcc£Û톽KxÿèKe2¹\Žj=:‰‹ÅE%a:éü‡D"A †††À:Q4·™ÍfaI- ê’à E"ŠåÈØVWWÏÏÏw•L&ñ7¶ÍÍÍÜ%—l—õ°|>_>ŸGÁºN§ÃÀ6[&„k·F{Ñ(„¬­7¦³M´¢q%& [l+ n³qËY¹ê´\"GÄú¡P©/ÇƯB¡ T*!²\ôaÑH[‚÷z½,òëòÝ^Þsú·n§žzê†÷ÛC=Ä0̵×^‹ÿž{î¹øÎ3Ï<C¾ƒœÕyç×ÛÛ‹Oyä‘;_—ýCKAuÁV^Õï'X¢Qw ˜}ûö½÷Þ{¯¼òJGGÇðð°Ùl&5™úã^J*•644D£Qúýœ˜˜ +ñL&377WT‡uó> `©­­å²ZX,–¢[8z½ússs¨,€Ù%’¬‡ƒÖ2ï“#Cf>[,Üo6›E…ÕjÅ]CžNT®Y³Ì~ñxÜív¨µj4‡ÃÁP´,d¹€Ò«ÕJjwH™„·«®®fm¶±Ö(d` a®Y°ÑÉD$×étªTªh4J˜bb±˜Ïç#Š±Ç·Š:n‹B¡P¦J3-“Éh4à‘È•Ó餿OäniAÞD"ß Çšš°F…Bár¹X{"@€5ue2Y{{;Šnèϱ Y\äTSSCrñxœÄõ½$ ëßm"¤î…BáÈûªN.—kýúõ$TÇ„ ‡Ã‡&sDe„ògãÆxÁòù<IFËd2ÂÅp饗’³È;ðÞ{ï!Z¤¡ ù|žEyËjf³¿•ÍfÉÂS¡PEÁv`ÕPɤ¤¸›äôfïRh¯¾új>Ÿ饗¾þõ¯G£Ñï~÷»¿ûÝïž{î¹U«VÕÔÔœwÞy×]wÝUW]µk×®k®¹æK_úÒG?úÑ#G޼ûî»ßúÖ·^ýõ={öÜxãwÞyç믿~þù¢ €/�� �IDATç¯Y³¦Ô¶çi4“ÇãUUUÅãq¿ß&VýåaH߆{,á“ÉdOOìr.—H¿…Š2†ÂE¶µµõööÂ�6D¥R©5kÖôõõ9Î2pÅ\.gµZ1¥= t1hÓ4½§ýn{{û±cÇð‚ÐQÃẶÙldÍ ¡†ÃuÄbqkkk4E¦níÚµJ¥2;v,™L¾ÓÕÕ…Ac¦¾¾~```xxø\ÖÊ'»¹\ª”¡£ü¡+£«R©Xƒ/‘Hjjj€«å"U¹mxx¸­­­³³¶ C EDæ}Õ]†“­­­Õëõ===ét¸4V°‚d&C æVWWÇãqŸÏW¡„.Áç²>W«Õ}a]äs Û¥¡ñxœgCÜ™†`³ž8PPXLOO744ÌÍͱ¼2wê&“É®®.îhg2™R²#%måg?ûÙ“¥pµÜèöæ›o.Î(•ÊÎÎÎk¯½ößøÆµ×^{Í5×d³Y™L¦T*±‡fŒX,†j\"‘ fš7étšÏç+•J>Ÿ¿ô‹>ZZZˆ½0ét!ê€Y¦¤h£í{SSÓàà P(ja¡ð„ßr8¨S·Z­ñxÅu\.WOOO&“±Ùl±X ˯L&“L&gff¸»<O,Ãs`ž䱸s†innîíí-ªwÓÝÝM€¢å 4òf�Kâ²,ô+ùÝÆÆÆ¾¾¾ÓN;mëÖ­¨éšíéé}ohhp»Ý4fkµd2 oQ(ˆ:m6›mii¨««Cö‰ÛILE‘H”ÉdЂÏE*C*‰jkk'&&@1…/ …B ;&� 3KZCC™z½öä~=ÊRO…VaOOhÉÕHM"‘¼‘™GžmAÿT*†Å–T*íïï§}C"‘èïïç2T1ï#¦Yêˆè@"‘ };†«#ËVT¥kåX­Ô-—tNG]¿ø tz>L¾¬2-“É=ztëÖ­ßÿþ÷ÿŸv?´Ô^yÿ<ë!f2™¾¾>¢…JçU E"‘ǪûF¬Â­T*577Öj² V*•===¨åÎ7‹-T"ÜWùýÂé–ÂZ:Îòì B¡P$!)ÒÜÜ<22‚ø ¸.øNˆfÅb±\.×ÓÓƒ ĪU«4M Ìf³ÈwŽŽZ,[[,l¹e³Y3¡C­V8m©ìñx°ˆPÀa–„|¢‡l6;==-‰L&á *3„)!¢!‰hõd4‡ÃmHµZ]”ŽèlüM&ý[‹m|>_,ƒAP¡ƒ A—–L&YÓI¡P@¹˜›Xòù|‰D‚Ïç£ô†LŒ‘‘Pc%—ËQÃr|7UÄ9Y­V>ŸöÙg/;’Ô+,…n<þøã·ÝvÛ·¾õ­å'ÂjDiåË,çDDr‹j¡jµZF€ò@­Vs ·$‰Íf#9p•J•L&¡1 2!½^ßßßßÓÓC´Pu:]QϤÓé‚Á bÔ5p} ÁZÒgÑæE,á;DÌè¼Çã!‡’É$‰êPï‰DæççACCø E$q»Ýˆá é¬/þ^¿~}¡Pxï½÷èCù‚r“É„ò<@�Fi«ÕšN§á/¡ÖA+%Âú;NØV W&“¡=Íqhèt:°ÊrÝÏðð0ŸÏW©TÜCäa-j.lÇ…B±XŒô£Ñh”H$Çgat:T*D"¬¢qžÛíF'™Õ@šs('Ó9µ··3‹AÛ-·ÞvÝu×A•õg?ûÙ† Î8ãŒ7Þxã©§žzûí·årù¥—^Z[[{æ™g8pàg?ûÙÈÈÈ%—\RJ<⟨Aî6Nóx¼h4Š¥7+–%J£E±te¨þM&“ÏçÓëõ¹\N&“N‚õ‹Åâ÷ûéX ù(ü¶¬‘ lŠÊݯÀš –sÂ"šÆZ2ï«îÂéõzø‘H¤P(âñ8íœhÆ„™™£Ñ˜Éd`k$ (<Çãioo‡òx< Ã�¨vzz: MMMñx¼¢ÔÆb±xABU®ÉÉdR£Ñ@q›ßïÇCäóù …‚åàWr¹J1£Ñ(ŸJ|kµÚD"QÆ1Èd2(³†H.®™šš2 \j¢P(T¡sª\î–æ<ÄRuªHê’w„E¥A$Š&„Œùôz}Ñ>/—’ÿ[·Ûo¿Ì*wÁ…BÁÛo¿ý‹_ü"Ã0»wï~ýõ׆ùüç?É%—¨TªÝ»wç¸aÆݻw¶k×®G9tÁ†ä;kÇþ ›ÍÚívVB¯è{Ejìv;K 4úB¡‹Å8«µµZ>ÓÓÓjµÚh4²Bg2™h‡A]&“ …B¤|ÆjµJ$RDÇjSSS�3’BíJ B4úbè6;;‹¢€™™»ÝÞÑÑdÒM䮹'ªTªÅ¢bŽd³Ùùùù¢¥IØë2™LÜÌ­P(„x<þk4éJwxz“É„m$â·XgÑ6É*ïü¢`¹•£——H>) ÌCð‘�L]r¹™ÂÀP¦U"­«T*éŠÐeçôïÞvíÚÅúäüóÏg}ÒÚÚJJfѾöµ¯á¶¶6Ô3 sÉ%—,ûâÆý‰D^Á”[psz¬CØo'jóóóuuu„È.‘Hpì¹¹9Ö{ȵ­¬ÎƒÐ¡TOJ•¢-‹'&HÛ2÷.—Ë«ªªü~?–ÿø2`³B¡0—Ë‘½"rT!ŠD¢©©)ãû <­Ec”îîn.×n·û|>:b�ý¤pk¸t•)øÃn·'“IâŸ7ŸÏ“n y…@ôA‘Éd ) …ƒ~(UUUI yD,3<O­V“C‚+¬V+)x>ñ©¾¨F¶e¾“J¥HÌ„"=@°e2žû‚¹;îü´ÙlÉ$DO–´s+JÈÿ/ÓN=õT.Åár;‰­(þ‘ìñ–Zr1‰htЊ9ò&Æp8œËåæææ…ÇKØÝÝMÔ\M[¦˜©Ãáðûý¥ M(êïïgEo(ÿÃ}•Yb ‚ÚÚÚE•QÐÉ"¨&ú|>¢„ snk ¯àt:ÇÇÇa͆Á†\&“q¹\Üá…p-7ÝG0³´{Fàåt:=‰uT*•R©DúCÁãñ&''S© =ÉÁ@JbD’…#1V:õx<Dý¤TLšŸúúz²éÊÔ\.·Ør' \iv™Æš„'+.(åZàK hAH°îr¹¸Õüt®›ÕO²‰U¦-9çÇívûªU«–ìrû@›Édâñx$¶ {K(g(šk"9 Ã466BØ f1‹BE»Ý>11±(ðïÜÜ\ùµ'·ÌÀV�Òjhh å^UUU¤6r•÷¤©©idd†Rð sss°¹èIöý{ÔÔÔ$—Ë;::¦¦¦ð9DCˆ™ænÝÕ××ûý~ ™ÈÊ ”Ì#‰tggg³Ù,ÇÛ°aÃâñ8”knnÅàkµZF377‡§ÖÖÖÖÓÓSêÉ’¿“ɤN§›ŸŸÂuR©Ôàà ÉdR«ÕÃÃÃN§3`ð=Occ£×ë%s†ksY3Û3Ñìò3¡BÌÆŠ+¸kšÚÚZZê‰.gR©T:Žåž!æóùh¸¦¦¦™™™¢ž Ó‰ûôÉ{$‰€ðù|³³³U–vò¥È!“ÉÄb1ï_®>|Øëõ.5î¿Uãóùííí<åÚ4á?ÌR©lhhà àÜ\.§Óél6ǵÝÊ•+q”ˆ?1 ãv»«ÎE:‹:þ ’»$.±Z­Ùl–,å_ÒÈ80 c0ìv;>ÂÈd²ÆÆFÝ‘àÐÐ –ä·XÚE©T ú¥ùÚÚZ°ªoÙ²å#ù >æææ@*H<=þ€2=Ý ¸+D*v»^.ÒŸÏG»@¾2™ zR†×ÊãñÌÏÏWWW£r’Ïç§ÓiÔR¯[·.ƒn·; ‘Í$®Ø©×ëeí~I$’ææf£ÑX]]MºQfÎвòȌ뙆Çãxú2™ŒÃÄ!Ú ’eM{{;¨²Ùìàà Ïçëîî&Ý*JsÕÐÐ033=è2ÓH^î}-]Cù¯§ KÐvE—N¥–[%­BgÏç»»»¡ª^´ /–5©©©! “ɉD�zgÁ0™b Â¢‚§E´E#øÇ27Eÿh…üÙÈ=B$—ŽTÈuX0Ìò5E¿PWW7;;«V«Q+<ÏáÇ·mÛF~´P( Þ¡©©Éívóx¼ÚÚZ·ÛâoÚ8ttt@J£Ñ-+Œ;‚D¢¿‚’‡h4Êçó‹“a … ÅÈ´¹¹yllÌ`0hµÚ§á(÷q×ÕÕ!©XÆ”¥R)ÔòÅãq£ÑˆbQ\‡;0E=Í‚³½Ô‡ÝÝÝxÄ´N ëû4}¾O¾)”Ep‹qÊ'“ b`xZ¯P(¼õÖ[ÜÏ×­[×ÕÕE«Ðž”–L&<h2™ZZZŠ~a~~¹Žææf½cIxÊ)§à ###“““À âi^†aZZZL&Ó¡C‡wkµZ¬”Ýn7IlÙ²E ƒÁ®®.‡Ã°ÎÎÎP(´uëÖd2IŒ×ë-Jê•ÏçÝnwå†`¹mE)ì¸ àMnb„«N˲&“““‡»¸Z­Öh4 ¥Ói‘Hd³ÙÆÆÆP–³Ê ’Íç žòù|šsã3B*!‘H …‚Ùl.ºEkõ–¿ÙRG³ÙlQåìÝ'w Édy_Zû•Äv¬¤È¸¿BA·Ûm4ù|>«.U„µþ-•JE£zÓé4ÙáC¸ìñxÊÔ�—&‹ñ€ÆÆÆr¹Ü©§žFÍf3rPàþðz½ÜGb‘‹>b‚é†EÆœÁ– ºD¦}Ö‰oÃså˜+od¦ÑKæ'&< è‹Š(ŠÎ™Ð9åóù .¸@¯×ô£e­&.»ì2¹\˜ØÉj‘Hä±Ç[¿~}Qçäõzï¹çž×_}Íš5íííO>ùdMM\.ûí·z衆††ýû÷ÿñüË_þòüóÏŸ~úé ÃLOO_pÁN§óÔSOeæ+_ùʱcÇ®¼òÊ-[¶$‰‘‘‘{ï½W«ÕÞtÓM‘H¤ººú¥—^ºçž{.½ôÒÎÎÎ;vœsÎ9·ß~»ËåúÎw¾óÎ;ïŒýæ7¿yà¶mÛÖ×××ØØ¸uëVn?±ÚØØ¸ì`NJãñx:&¥3KKÐr[ÑC5™Éd$Éé§Ÿ.“ÉFGG;::ðZ¢j’áDÃ`0ÐH{î& €±\ç”Ëåˆuƒ°wǺpr¹d¯Ñh´Ô~ºtr“À±²jdd„+A Ýúl6 ÂVr”Éغu+n§èÎ<ÔѸˆ�<AF.—Ëm6›Ïç ƒxÄĆB“—Ðñù|Z\£(˜‰ô%‚Â@ÍžÉdR(6› ø*£Ñò$®‹âñx8ŠGLcºi põÒÛ`îVT"™x}f‘’ ò8>ç¤R©‰D&“Á B¦ž#–ŽÀ*l¥p{lZ¯®®îá‡Æß¯¾újOO]3<<ü§?ý ïØ±ƒÅ‰K·'žxoµÍfûô§?Í0Ìßþö7ˆ\qÅb±xåÊ•X2³%“É;ï¼óÑGݼyó•W^ùÐCõõõýö·¿u8UUUwß}÷wÞÙÕÕEç‚3™Ìc=VUUuã7^|ñÅøðW¿úÕ%—\rã7ŽmܸñÑGý¾ÐÒÒrñů\¹rýúõ×_=áŸýóŸÿ¼mÛ6’ÆÇã·Ür˶mÛ~øá{ï½·£££TByy#êÄY‚Õ×ׇB!@€>h�’Ⱦh6$²Š‚P($‰V­Zµråʪª*ðÆb±¾¾>”lI¥Òl6 *œ566Fkè]‘“¤V«‰„&ÝJbUS×b±”ÙGŠL$©T*¿ßÊD° Ñ`0THãD»ÏÙÙYè? ¸£Ñ(—ËYΉ$ÍXJi"‘ÞÔh4t:ÒdîoY,–¹¹9–gC’„`$âóùÁ`>†$¥R©D"À Z­ž˜˜@h…0³6› D쥖öàÊkhh°X,.— u Ÿ˜˜Ø·oߪU«&&&hçd0Äb±Çã …äÓ˜nP›£•áÂ�xˆÌ 9´ØÇñíÈår@@f‹ð‚žŸ˜íåKÒÛ>p›øÌ3ÏìÙ³ç#ùþ;11qã7ƒÁO|âO?ýôÁƒïºë.«ÕÊ=ñ׿þõîÝ»¯ºêªT*õàƒf2™ÚÚÚ›nº©¾¾~íÚµ÷Þ{ïôôôW¿úÕ›o¾ù“Ÿü¤Z­¾ñÆphffæ†nÀÎd©Ï•+W®\¹òæ›o&2étúÞ{ïµÛíG=zôèyçwÚi§}éK_¬úéOZ__ñÅoݺÐ/ùKŸÏwà 7kž~úéÈïGĽDØöþIÛää¤P(¬®®†Méééš5ë,ª…Jð¹E_øééi—ËÅãñ\.Wmmmuu5¶ìv{"‘%pZ–“¨Ü| )µ6™Láp˜6 ôUbèžàï¢T°å·¬FF•+’ËãñèøgˆD¢ÆÆÆ¢™«¢ÝÇÍR*•ô#®««ƒ‘D"1™L@ Ä ¬ëhµÚp8 š%VvÉ@måºzõj™LFpÇCô$ÇÆÆ`»Íf³^¯ …f³á4Þ–¶ãSSS"‘H¯×sŸ VeÅ‘tÿKC#“ÉÌÏÏŸþ‰t£ÌôP*•B¡8×B¡P^8nz½^¥RÍÌ̤Ói z‹rI| ÎiddäË_þ2Ã0^x!ëÐìììÞ½{wîܹk×®cÇŽ=ñÄßùÎwŠ:'—Ëu÷Ýwoß¾}ffæž{îùóŸÿ¼yóæ÷Þ{oçΟùÌgšššèÄBggç‘#GÁ5×\ãr¹âñ¸F£¹ð yä‘Õ«W¯]»¶’nK$’G}”Ä@ßûÞ÷î¾ûnä÷¾þõ¯ïÛ·ïá‡Föa˜‡zèž{î¹á†vîÜI®°víÚH$r»G2h-·Rm||\£ÑÀ9YY ÿÈ}iõz}8v8¬<FF£ÑÚÚZ¿ßTÂ�J†555EaÿG,›L¦¼^o™¥ €Šå¯@”pKÍ.Ä4Ñh„§°Å ‚pYÝÈår�«f2VD_‡Hëær9ø!Zƒ�[œŽ³�:†d9ÄŠ½XËù@ @ƒp±ÂˆD":njjªººzrr2 Âoò <,,ÿ‘í„c ¯V«•ËåñxH2#¼ýöÛñxÜl6óùü¹¹¹ÎÎN™LV[[;::êp8‚Á`sssss³T*=pà@y¯OcéV&.S‰öaŸÏ×ÞÞn6›S©Ô¡C‡NÄ9‘n”ɲêKËtÛR©8ºêêêÆÆÆòù¼Ëåâ¦F?çd2™àœœNçÞ½{¹_xá…Ž;VÞˆŸvÚi»vízôÑG‹Zí}ìct˜¹cÇŽU«VýøÇ?Þ¹s§F£yê©§Ž'Š /ºè"ü=33óÔSOMNNžzê©W\qÅK/½ôüóÏ'÷Ë_þòž{îùö·¿}ùå—³2r;wî|ðÁ+_XnPã&ˆªªª‚Á ì7W666–J¥¸Ù-h%‰ÙÙÙX,¦T*A– …r¹\:s&� É0LSSÓÐÐP%IÚ$•×'•H$PÚå»JÈP»<::ÚÚÚÊçóûúújjj*Äç¢d””J¥Z­.ê•%‰J¥¢ÕƒÈ €‹=•JÙíöH$b2™�ÂÅ# E¹Á¥P(įdãr¹ oýýý`t¥™Îéàîµ(käšÇ¥Ói¨ýÖÖÖ:­V[(^|ñEŸÏg6›E"ÑÀÀ�ªùS©”Éd ) ]]] îår¹¢ÑÏñ!jq_"‘*6'¢[Èí†ÑhÌçó\•T*e4¡EB†Z*•ºú2M­VG£QPa…”H$¸¯í✔Jå–-[Ê|áôÓO'Ù0È_rÛ×¾öµ§Ÿ~zïÞ½Ñhô‚ .(ÿ‹6›Íf³566~þóŸÿÛßþö±}ìwÞYl·ãñøé§Ÿ¾~ýz²aÆ0ÌW\ñì³Ï¾ñÆ„Âç±ÇÛ½{÷ 7Üpùå—sÁíuuu>ŸoAÐõrûàpr555d“–äaÊÄRÜR”iáå‡ÐÜÞ½{…B¡Åb1›ÍÇËd2(ïäV�bIH/`kjj|>_™ò9¦X•åw‹&@ …ýë‡#r÷3‚Á V«­««³X,"‘Èáp¤R©òÎÉjµJ¥R² $gém³|m)MØl6‹Wc~~fzŒ 奊Ãá0ÉáNa ÿŸÛÚÚzàÀ¢×‰F£ …N±Ô-k4`f#‘HKK‹F£Éd2###555 R ƒ:.‘HÔ××;v …‰*æ@)ÐóÂmkks»Ý.—«’ê°Jæ ž¾F£‰D"(?Æ£immíë냣*ªçTI+á £ÑhUU”‘1?+A2x½^Œî«”«þ°A¸@&“Éd2£Ñø_ÿõ_çœsNQ½¬O³Ù¬Á`À^+¢H±XœH$Âáð¶mÛV¯^M¾ü»ßý®¾¾þ/ùËã?�3ëjR©T(Æb1Q¥Ö. gbb"'“IÔDMOOg2d~Âáp"‘ƒ¡PH­Vƒùƒ»@ûùÏŽd ŠnñBþ+eí`¬—,oý;ï¼C×¼!_„W”€ þ´¶¶–Åè¥ÓéŸÏ'Ð@ òù|, …BÃÃÃû÷ï÷z½Éd’ÇãAš†âÊÜ'>11QÛ/¸g566’’ÊÝòmjj* ¡4~3›Í9rÄëõJ¥ÒÚÚZˆYnÓÛ�áâ`’ËåõõõÙlV ÔÕÕSŽà‘óù<×Ç@¥[( …B>Ÿ×0—ÞÞÞ¶¶6œUWW°-Ã0ä‚ÌûAº©T ‚ëz½ªð@‰¶··>|˜‹„ÅCoooÇ㄃uˆ˜NŸÏ‡]F¥RyäÈ‘£GNOO8pÀívŽŽ <x2¾ä~žzê©?üáû÷ï'Eq˜f€îOooo"‘ ‘Cô ¿Ìçó'''1gèÑ(å¿÷ïß?88Ç :›^‰Û(:8evX ;2£ Ô522‚HQ(677Ÿ8E£Ñ x-—ËU²Ùyò#§¦¦&º�Ïjµ655‰Åↆ©Tºnݺ={ö|ç;ß9묳…”üñÇ?ûÙÏ^|ñÅv»ý¥—^Ú¹sçºuën¾ùæ_üâ¿øÅ/†yë­·ÂápSS“Íf»üòËÃáðý÷ßÿý÷ ”íÉd²¦¦&“ÉÄ0̽÷Þ›Íf¯¼òJ†aÎ8ã ’÷3¨ÀABüí·ß¾øâ‹Ñ·ÿøÇ;vìØ»woSSÓŽ;ðýsÎ9§©©©©©é¾ûî»ï¾ûpÖk¯½&—Ë›ššŒF#ó>`3h4š}ûö}æ3ŸÁ‹Ö‘ÿ3¶¹¹¹+Vœ{î¹O>ùäì^SSS$éïïG1‘Ðf¦¹¹ú{‚›žžæ®@ @½ò+V¬Èf³„Èb± k„Ý n —À0% ílˆ¥J¥E‰šššÆÆÆX^¿ yð¹Üa¼ùccc¸er¨P(8p�4ç:(W¡Pˆä'Iý„«×ë!Y‰Dpº…CCCƒÁápH$’¶¶¶C‡uwwsĤqÆ ºº:“Éô÷÷ÓÂN›7oöx<0Êô¶«°Èl6#þ€/”šÃá°D"Áî=IÝÝÝ�ü‚³•5,p EEu‰·�¶,™L"ò–J¥ù|^«Õ:NŒ$„ÉYÏ=ŸÏ5^¢C¯P(  “)A8jªÐéÖh4ÊROæŽ˳bØY÷EOú( +YåÝû�p›þÀi³Ùl)<Þ;²ùg·Û±Ö/ÿ[¼Óv|ù#ŸüÜ´' Êú.ØâZ³fÍ?Ö²ôöö …¶¶¶ã»¥Ü8P[[k·Û e èèè8묳JqÌ|Û3û÷ï' ¬kŽ9‚pP¥Ra›mllŒ¼`›6mòûýÄ9±}„¹>|X£Ñ¬Y³æÉ'Ÿ¼òÊ+!ÜGÌ·A Æ®Y6 ²±±Q&“õ÷÷—™¥ ½½½(~`ãÆ©Tªè!l¥Tx× ‹µÛíÃÃË­-v¹\jµš /ŒFc.—«dσî!Öa VÃíTWWsñ+*•jëÖ­ 'wwwÓE"[¶lo ®\ƒÙƺº:¿ßo0@s.“É 1êû!R%-rèw(ìvûÀÀ€J¥ª®®FÁz<—J¥¤:†›ˆ›‹Å¥}hè.X—*$/'S—§=n_º·p-Vc¥Þ#t·è›‚­²[n¹¥fý¹ëûçÆºö/Ãkþ­öÏÎ:묑‘«Õzë­·ÎÎÎþÇü¨·:::xà»Ý~ë­·NOO××׿òÊ+ßýîw?ñ‰Oàt·2ò°}�� �IDATÛ}Ë-·ÌÎÎÖÕÕ½òÊ+ßûÞ÷¾ò•¯,…ûÂt/c›uŠT*ÅKe0òù|Që D-T’Í¡òë§¢Å$qTª<oQ`FÜࢪC•J%Ci¾ºÜŽ §ECíu,CjÊèsss¨ÀÏD¶Z­¶µµ5“ÉH¥R@ÐÛÛ˟ϧV«Y ü‰Eär92H U‰žH$È#V©T³³³$è$‡hÀ/«) €ØÊ¬N!e2Œ›Ïç³X,(z,jDZV³ÛíB¡;†‡‡kkk£Ñ¨R© …B,·Äãñ´Zmù%NK'±O¤9Ž™™™ã@D•‡ÓÒ˜èRwäp8¸d%ËÎéߺ]ýõ‹eûöíUUUÏ=÷œßïàFGGÿô§?©Tª»îºkll %³W_}õ)§œræ™g^ýõÄ9½ùæ›/¼ðÂOúÓ/|á gœqÆõ×_¿DœS&“)ꙬV«H$š˜˜ é¼ „+“ÉJ9'¹\žËåèÅ~0\0²/³ëîv»OÊmBÓ¶òƒR©Ôjµ~¿§°Rš&•J%“If–6^›6mB˜Å0̱cÇæçç‹ni«×ë ÇkggçÀÀ€ßï×ëõè,l"‘P(€„Ýz½ð#ü7‹-ÈÃ]ª”Ù`0ÐŒPpO$ ä¿Fçnu»ÝžN§ivZ”eB4²èOŽŽB²¨è!‘H$•J¹ÅÓ|>¿Ÿi'—„S"‘Èd2dÉÄXÔY ¶RU$IŠ.†–¨sr»Ý‹’Œü§h³³³E¹õþm÷îÝÓÓÓ7ß|óÇ?þñ3Ï<š¶ÄÝvÛmø; =óÌ3Ï<óLQÈγÏ>;00ðOñ¼h.KúC¦´@5Ã0ô 7Î(ó[ ~‡ÖϵZ­åO'Þ4 ˜,¸N‹(õ1ϦC¼E2™ÄÖëõMMM(ìž™™Q©T¸`cc#ÃÁòêtº™™™¹¹¹êêjb0ï‹’ ¡P( úœ¶òÖ¥šZ­6›Í–¯[ã6®40¹fhh¨”yÕétjµä<¯è´¡¯| »ð£…B~#èC€¸Ô}ˆn¨ïÀÆÌÉ’»Ås,UÊDfu%µÇÑ.:›y¿Æ§(MÉuNF£ñµ{ñÁµÚÚZR‰´DÚUW] Á½÷ÞûÚk¯eQúë_ÿzã7nذaÛ¶múÓŸ¸Ó¨¦¦fýúõëׯ¯"þjEùȪM$Y,–ߨ(¿–§[6›€& &‰_xª^­¶¶vll¬cá÷ûY_“H$@k±ªÞis†í¨ùýþ¹¹¹•+Wêõú@ @P”îÔÕÕƒAøýþ|>MVÀ0+¢ó<ÄÄ“^¡¶¥¨ÇEÒ5‰poŽ3x<`^b±¸L­)@¸„±ÂEØÓbm‰ …ùùyÐA1ï 0½&°PÀÞ²üZ­Fhˆ‚Ù™™––‰DF‘yŽD"ô)*•J"‘TŽžfuƒåªS©Ùí&ê´ Æ©ôYÜõ–R©$/ZuuõÌÌ ~àÊ_“¥èœºººÊG‚ÿ¼­££cÆ `ÖY mûöíuuu·Ýv[¡P¸ï¾ûèÜq ¸ì²Ë6lØPWW×ÛÛ{ÅW\tÑE÷ß?÷"k×®½è¢‹®¾új·ÛÍåY:­¡¡att惆ab–…N/èî×%ü +®B¡ÐjµÜ†–¥¼e<½[·‚nÎ`0” |c±X"‘ÐjµpŠsss@Àív#HÓ‚Vf~~žŽxhÇ0??ߨØÈ“påæÕÕÕ¥Ü DrA²G„ïÃl6VrÂÅîQ©Þ¢–Òçó‘‰Á0ŒP(›»\�î«Ôœ‰Çã?Ê’…v !”R©4›Í¨› €t„—L&»X¬üd&º$¬9&É ±›ÄCÛl¶h4 =I²¼XTÏ—¢sr¹\ õ/·“Òn½õÖüãûÛßÂáðÎ;?õ©Oþùcccçž{.Ã0r¹üÊ+¯T(½½½wÜqÇý÷ßÿ£ýh×®]çœsN¿è¢‹z{{wïÞ}ß}÷MMMýïÿþïR¾ÙÉÉÉ+V b8‹c=4˜BÚ–‡î_èìõzY‰)ÖëŠít¡PXtã§h|S>Ó•Ïç¹iIú¨×ë-*®HlÅbA5„þººº¬Vëàààøøx86 ®âkjjHáµÁ`‰DsFÇÆÆär¹Åb;©®®…Bä6S©Ty\g:¶Ùl íïïO$ðå‹<”ƒ—ióóóȉ StÅ ­<†BÚ–š3deÀÂY € Åi§÷öÖ[o±Vmmm¤4ãħ"W=Àm‡ÃÁ­ô¡¤¥w6› [ª@ÚVÈU¡V«!+³ÔÊQNÊ3XRíСC555*]"]Z¿~=‰–D"‘H$R«Õ¯¾ú*¦ø¶†¹ýöÛo¾ùf<šŽŽ¼í¨ˆÛ½{÷-·ÜB¦æRÿT*Ä]£Ñ�„ÿêÕ«A,ƒ, A’¶¶¶šÍæ}ûö£Ãçó± ÑÖÖÖ××Ç2F8ÚÚÚÚÛÛKäãÀ$Vžýt)²ã#Î, r � ž³üSy ‚ˆœi+d¨>—U(@³NNN100 0PÜ­o·nݺÞÞ^§Ó™ÍfÓé4ínì‚ä‘òùüÊ•+ûûûëêêPýE¿k…B¡¯¯Çãéõz¹\ŸÍôlŠànommíîî&ÝÀ)6lxï½÷ÐaØâªª*°¿—ïm&“Y·n„}Ñh”ÇãÅãq•J•“X,V__ÏãñFGGšhmm-ïYÁKË ¸ÉÈÓ ø\¬˜Ÿ8 ’¬S$ Y¾ôööÊd²ªªª¢5¢ BÆ•bR&­¥¥exxoY$áz,+á~x­òućÖx<�ȬÅëø­¢ˆ>´Ôpô*,:N¯×óx¼ÆÆF@ …:ÔÑÑZçööö@ 0== »æv»Ëå"kÌêêêX,æõz‹.!AÁIÒjµ2™lQÚÇ1ùù|¾H$Òjµ555n·›D3`œÙd2år¹ ·+ø|¾D"Éf³d�QßÜÜ ƒÁ J¥* 6›v¥�êMÐ+ÁBD†•{kÉdòèÑ£N§Ä 6›M©T.Ê7ÓÞ`ÕR"Šù|^¡P¨T*”ÌåóyðörkÍIœõäÿ3—B!Ã0v»Ýï÷wttМ(o”B©ÞŠÅâ÷Þ{d̬VkCCr¹ÓÓÓÁ`0‹D¢ÉÉI£ÑØÞÞ>44Y¬‹<¹~Q 466rGƒÖðÕét„ÙÝ&Xu4ä¶”D2ÁCJ8—Çoõõõ GÑáZØ9ÑoZ{{»^¯/ ûöí#M´îîn¿ß¿yóæ MÕèèèøøøÊ•+u:]Ñ/tuuqÓëuuuñxœÞÖV«Õ4p¸³³3 nÙ²Óh~~žZÞ²eK&“9xð ýáªU«Yqt}}}4õx<6l‹Åo¿ý¶V«]µjÃ0ÃÃÃSSS«W¯Öh4o½õ–T*%ÒºX\ÌÏÏoذa‰GÿòM¡P%…B‘H$òù<¢ÃT*uÖYgiµÚ`0èñxòù<$h‡††:::ôz=² ESSSgg'm†XÄq,|. ö”•tX¥RÑbn‹j¨æç}pa4 …¤¤C“ÉdpEè¹X,¿Ê²Ù¬ÝnŸœœ„7™L€d±êGÒéôää$öðU*nœµÞ§Tɺ­P(ÔÖÖÎÏÏ{½Þʳ&"‘H¡P¤R)òò.ù$…é:.•JÑ_ (•JÔÓ3ï—*är9rMhò!@oa²òZSSSe0õÕÕÕÍ–N§GGGãñ¸ËåÂ2bddÄétÆãq‹Å211Aöy<^UUÕbñL¹\nA±c®K[0óIß/Y¾€ßívëtº ™ˆé¡X´sòûý?ùÉOþüç?¯_¿þСCçŸþµ×^«V«wìØ±nݺW_}•|óõ×_ïîî^»vm…Îé±ÇûÉO~òôÓO©'V{íµ×zzzòùüÿøG£Ñˆ¯]xá…Ï=÷ÜïÿûsÏ=S§¿¿ÿ¾ûîÛ¼y3Ã0ï¾ûî7¿ù;¾¾ûï¿ÿ²Ë.cæ­·ÞúÒ—¾´zõêææf†aöîÝûÃþpóæÍ9Ü´i~Ëb±¼ð $µ=>>¾ÿþÝ»w9räé§Ÿ>tèÙlÞ±cÇé§ŸþüóÏ3 ó«_ýêÁ|ñÅ·lÙr饗:Žwß}—ôüî»ï~æ™gÞ{ï=H¶/·T£Wô ïÄ–ìèè¨F£1k¡P˜˜˜ËåÁ`¬ÉëªÕj#‘Ë[°¬¿@ @•3Èñ¡N§Ã¹‹ê°^¯GF 8˜EžJ¥JÁª¸‡`— …ä@- v"xšL&É®ªª* Œd/k‹`f“ÉdWW—T*åóùb±X*•rƒNÒÎ Dà*´X,€ô–³¢«ÕšJ¥fffðC€|–’Ö*• õt~ ¼!Á`—2ØfÓëõxè!N)ê'PnWží…6ÇX�™L&™L†å~{{ûäädOOkšiµÚááaÖÄÐh4"‘4í¬áýpgÈœAŒO_¹|eyÈy9çFô£½òÊ+?øÁ¶oßþüóÏßrË-Ùlöûßÿ>¾àv»_xá…M›6mܸ±¦¦¦P(€ƒë׿þ5¾°yóf@gžxâ $¬Vë%—\ÒÙÙ .çgŸ}võêÕàð`µo|ãx¯þøÇ?644<ôÐCøü¹çžcæ–[niii]»víÃ? çôë_ÿzÅŠgŸ}öM7Ý焆Z2†aN=õÔ믿~ß¾} ÜrÊ)äš Ãüà?ÀSSS·ÞzëºuëÖ®]Kttáÿó?ÿ¹7ß|³èˆ>|øèÑ£K çô/ÜÄb±B¡ ! «- =ztffšC ¢æ†, J1Á°NMM±Dœ¤ÜéwX­Vc¡Ì¥HÔE#Rÿîu Òààpghhè.#àîüG"bì¬V+7; |.ñ7B¡[’E·W¡4ÁJ!‚ÊÛ9¸~ÑÄüD&“A _,›žž®©©inn333è<~r·d ž?Í:$—Ë ÅÄİ"Ay.tÕœÙlöù|ƒvrð(f³y~~ž5t:]Q*w¨¹û|>—Ë…ªýééiÚ3WÃçóÃá0HÿèL<1]3"‹+¾§å¶¢~ú¹ .­ ƒ\¦æ¨œsŠD"?üðyç·}ûv†a.¸à‚={öüâ¿€Û˜œœÜ³gÏððð‹/¾xÇw<þøã/¿üò¥—^zÇw¼ñÆW]uÕþýû_|ñÅþð‡]]]»wï¾òÊ+3™ÌÍ7ßœÉdV¯^ fÜ“(O¾wïÞ#GŽÜu×]Û¶mÛ³gÏüãk¯½v±ñz½ßÿþ÷GGGøÃnÙ²åW¿úU…gýö·¿…sÚ»woQ¾á·Þz«££ã“Ÿüd)«´ Êr+Ó<]í# ­Vkù} ŸÏG¬ü‰3¬³X X¾°ð~«0U¥ÑhJIܞĽX@`±X¦§§á2Ë\™îL6›åV3K¯kŽâ­X,Öjµà\€'Dét*òÉdR£Ñ„B¡d2955UF&Ð]«Õj³ÙšššD"‘×ë•ÉdCCCÀÓÌÏÏËP¤ó,åÖ©©)+U¢øPô™Z­V†ÃáR¾øœÏç#õ‡ÏQ§çóùœNg.—ëîîfÙkœˆÑH$$šDW(ÝíÅŠBq{Ëçó­V+æ0ýô4•àvÛŽß7(гÎ:«ªªêÚk¯%á¡Pxì±ÇÖ¯_ÕUW‰Åâë®»®¯¯ï…^ðù|_üâe2YKK‹Ýnooo_·nÝo¼±}ûö¢aÓ‚íÆoDZÏår]uÕU Ãìß¿Ÿ %²Ùìž={ˆsúïÿþï£G2 333ó“Ÿü8p�ì Ã\ýõ---Édr×®]ããã÷ß?Í•PIëíí}ä‘GÇË/¿¼Ø{íØÓ—Ûñ5“ÉD`>Ÿ'ÈÇ×hVrîŠ/•JáußÌÜÜœF£aÙ5c»œH$ÈšÒ¥¥Š÷Jɤ2”¦-n*½Ç}4Ä•¡P´uuuB¡°Tž°¨ÜL%«or_è3THè· £ œôŠôH[¿ßOð¹³³³ÍÍÍ2™ ª%"‘(‘H˜L&·ÛMŒ;Î%ÿ…&y"´r€Ì,ñz¹ÀEg#h í[¶lAåg8.OЊæô:Ég‡ÃÑÝÝÇ{zzX#l6›GFF …$*ˆM&“Á`°­­­<µ«Ùl6 ¾IÊ— Â%îV«U*]ACÏjÖâŒü]ÉRE%å¡Çïœt:ݦM›Šnõ÷÷ŸþùÜ5ˆ\.?Y Í‹/¾Øjµ~ò“ŸDR‘|þ½ï}O£ÑÄb1” ¡mܸñÓŸþ4Ã0;wîܸq#ŒBCCQX·Ûí˜Ä/¿üòÖ­[뙪««wíÚuèСD"ñ‘|Än·¿ù曕ŸžËå´ZíÒAæþ 4¡P¨×ëOÄ9•I8D"›Íy'—Ë599‰å¿Åb¡# NG^c@Òæ)‰@äÛh4òIχ21ÁçF"‘Ä$pѯÄì¢öw!‰èP‰¶¼&“)›ÍªT*Ö½“æt:ççça Yê´ø»©©Éív;N·Û-—Ë% ¹>ðÈxˆ(�•v8PØ××g·Û€H$J&“CCC¬106 ±¼8.å@Ü4ä N Eã¢èl>ŸªõM›6Y­VÁ粨Çqø›Ó ¤˜XO’rÄ—Nb�QËWùC/C IÆ–ô0‘HïêñRûI‹ ×À‚e/H)ymmí<@–™Ï<óÌIÿ Ô8<ÿüó—\rÉ 7ܰzõêßüæ7·ß~ûÇ?þq¬)¶mÛöå/ ÉššlJÑÍ`0°><ûì³kjjyä‘ÅvF&“µ¶¶Þqǯ¼òÊu×]Wù~ ñåE3ËmQí”SNikk#ËpîvQKKËàà`…¸Ú2›C©TjjjŠlÏàÕ%ÈMÒèjrì@¬X±bzz: °æ’¥4Z䈎Á¸eÚ.ê§ÁüÆŠ„J…n´‰D‰„>šN§×­[‡bè@ P(PÔJl �•¨˜À®ë½£A¸J¥ÄkÖ¬ ƒtt266F#Oggg …®ÖÖÖ6<< üF£A^Î)™ÍæH$"Šc¡)LFžåº kƒ9ÀU4&Ìçóããã‰dddL¯Äî·µµõôô 3 «ªª­0ŸÏ_µjU4%ä~555:®···hL»L—zX´žŸŸ/ê´ÊLì¢"tæ“Æwг<ƒ°üUþò—¿|êSŸºæškn¹å–›nºéwÞyõÕW‘?éêêúêW¿ºjÕ*`fÉY*• ëÖ'Ÿ|ò®»îºçž{@9‡=ÏÙgŸ}á…Þwß}8+‹mß¾ýñÇ?ޏLYÉd"1¡PÈd2¡@.‘Hd2™òšÄ™L†<u…Bqæ™gŽ>|˜°Óp•Jµoß¾mÛ¶]qÅ+V¬xøá‡þóŸ“b?†aN;í´ÿüÏÿìííݹs'«Ník_ûZ)éèt:ÝÒÒ‚zÂåv|…Í"•Ê$u#¢¥RÙÔÔäñx¸Yr˜-5åà²Ù,À§©T ˆE.D7›ÍÛŠ ö÷÷ÓØXœÂZé—’kÃ)� , -‡‡ ázÙ¢€Ê•+Wvww£«XiÑHÕt:ÝÑÑÁçó <6“ÉÐ6+‰H$‡Ã;Ð××ËŽ[fà=zúuÅV~(•Ja4XìD ÃôõõuÖYjµ:™LŽ x;·jÕªcÇŽ/<—ËMLL @À*xÁS.5’4†”[ÂPUUåóù¸¤R©t:Åe0$ìïïommÅÓG7èŸÎår¨¶ÀŸ˜˜€š0KT°®®Ž?…Óý¼B®EVú'³‚?ò:¸\®™™™“¢±777çt:ió{<ΉÇãmذaÏž=ßþö·ÁXóûßÿ~ݺuù|¾¹¹¹µµõsŸûÜõ×_Çw\zé¥O?ý4†éàÁƒ;vìÀ÷oºé¦‹.ºè¢‹.ºì²Ë>ûÙÏ2 sÎ9ç@@öÛßþv*•ºãŽ;öìÙSÆ3ñx¼ææfZZ×f³577ÊD¢ææf»Ý®Óéš››ÁãKŸ¥R©š››é9k``€Ðð@µ(“ÉÅ[†a®¾új»ÝÞÜÜŒâx•Jår¹:;;;;;  ŸËå²X,|>ßh4Úl6¡PHŸE/`ËTðùü“Xòï™Ç£ Áêõz”>’SŠF£ÉjJ¥Ü<@h²ÞyFÌr"‘ÐëõX#ø\<AX.ІҜ=ÄЫT*>Ÿ¿nݺp8L´þè™2éßR�'‘HŠÆR4 ’¥»Ê¼/wKÞ Ü2mQ‚[WWçõzIêF,WUU[­Vî*t¨ ©TŠŒ³H$ª­­dM<¦þþ~NWSS£T*!h’Íf‰óÀν’�s+qH'ŠÅâ\..  {<žñññRH[¼¿tºUï�nONN:N¥RY´€UÍHîˆL³Ù,ã;Àç²F˜y¿ä¡¥¥…4“Ìp)8-ÃÁÌ2ÇU5311Q[[Ëb}Õétb±xvv¶Œs…kG2ø…B¡hÈε'M ÷’K.yùå—NpcÿßP W«Õ …Â+V,û˜™ýù|^,?ùä“W]u•D"Q«Õ0"J¥0¦ò3 @K"`6›éü~%­US…B±}ûv@ —Ë_~ùåJŠ6ŽU Ô××OOOs39<O¡P`éÍ’»eáU­Vk,ãšc£Ñh2™�­¥½¸J¥*ŸœÉd –-sÈårùý~Põ„B!¤I«««{B‰97æcéK¥R‹Å‚5Ëó9ÎP(D2í1-‹ø’T¤Ùl¢Ysƒ»Ž‰ÅbpÞ,šsrˆuJMMÍbã¹\ôø+F`ìåß ¢‡*ÑwÖjµ»wï–;×%\þIé÷ÁƒgffÎ9ç.óÍr[n~? IÂ455af²bh®k‰ÇãØ¬¢ù¶+ltmz™7P.—Cizzš[v¥2™=TÌËår”ËåÆÆÆŠâóùä‚tôCn™´ÙÙÙ¢ÆÅëõNLL°²[Ñh4p¹¯X曵_E? lll„Ôf±ŠÇàóù|VZE­VF�Öd2Åãq®Ã8ÐÏÑh4b4€î"Ÿëõú‘‘£Ñˆq€¯‰D:Ž28ï…SŒF£^¯çú†_9÷®TO.:PèÆ?\F§ÓÑõ¥Þ ¢­}ç`0ÈÚ­?9Îizzú£ýèOúÓRµ˜Ëퟺ½ûî»÷Þ{ï¢*Vÿ•7H$ýýý¨€*C(ÅÊÕˆD¢E%Ze2É*—y½ççççææ@E#m‘?s¢Wx†åi`Ó¡-K_<Ncû]( ©Tj4±1;;[ÔpŒW˜ç‹Å þù7ñ°Ú0Ð\«ZFÁÖãñC~¿ßápTWW³Êùcí B²Ýjµ ø…BQ(Šîó‡B¡¡¡!�r …B\0 Ñ~zll¬ªªÊétj4šºº:»ÝŽrÈg€æÏËd29N$Qår¹ÓéL$ˆ´$ Æ¡òå.MÌf3ýÉÜÜ\"‘¨œM©T­õ?ñ699Yöƒ7H"‘Ðë Œ÷ˬ9#•J¹›;'gŸcÇŽôn͉·e%Ü%ÕÞxã;ï¼³¹¹ùŸ…I(F˜Œ@ @²"ex<žÝn'_ ªäB¡H$¥8uh<¦ÏçãÖ5á }}}‡£··—–'çæóy:WÆ‚îf2z›Äd2A´bvvr× …Âëõ‚uðÌñññòB®¬Ol6Ûüü<GóS"‘°Ùl‡ƒ h£Ñ(–ÒE/޳*¼¸ÝnˆE!³WþËWD~uÏeð^ôØÅØÚív±Xl4ççç[ZZ\.W(zíµ×’É$ž*5âñ8Xp‡Ð"aiS•ØJ`s|>ŸÕOÚÒêÉôZªªªJ$qµ··÷ƒÐ!ÃM‰ÅbNW $κ÷ '^Ñ)º¬„ûáµ%¨„‹UѼ¸üòËÏ<óL†a®¹æÌþÕ«Wó›ß¤¿ÿ­o} õ¯kÖ¬ùÆ7¾ñì³Ï>÷Üsßüæ7Ÿyæ™ñññ 95>ÐV__ßÓÓC¬Få uôûÌR5M§Ó´]æ6¬ÜÏÅ^=+…åõz1nn·;³b¥¬4䨒x4™LB¡0—Ëa{#‹ÅbFãõzçççA$BUºK7ˆ9q“3>ŸÆZŽíx<îv»ÉN§“ð¸“f6›£Ñè‚V±Ü8IÁC#‰J»Ä4Hå!ëèñxˆÃ£ýºV«R ú¹étÚb±ÔÔÔlܸÑétz<ŸÏg±X‰Äðð°Ãá 5wðz½¥©Le:ÈEŸ¨ÙÉ'V«5 ÑqaQ) T²ÔÔÔ`r£Ä�� �IDAT^¨òÉm¸)n9;ÝX"¹¥Ý,çZTZw‰*áþ³dÛŽ=ºqãÆ¥ƒ· Ÿÿüç%Ém·ÝöÄO\{íµ>øà“O>ùûßÿþÙgŸ¾ùæ›éDóÕW_ý‡?üá¹çž¼å–[ø|~,{öÙgûúú°Š\ Î ,ãĬ[,–T*µ  d™<€d¥Ré‚Rž‘H„A‘Æ•.››+¿[CÛ¦x<Ž{) 4KB¡‡ÃÙl݃ u ½ìqp¦¹Ýîl6KÄ…B¡¦¦¦¢æÊr¬' ÑG&“™L¦R4]p¥r¹Üï÷“ÒJ‘HT]]½ T¢N7;; «—ËåÊ×àù¢d …U«Vùý~Ô[f³Y¥R @[)äbDcSSÓèè(Ée‚@†N§ÃØÒøÜh4 2æ¬ÉS”Ñ5—ËMOOã¬|>o4‰Ä‰“r•ZL”'Óétv»}fffAÞÞòKЂ»\.(SüK¶%¥S•Éd:;;Ï>ûìM›6µ´´ƒA³Ùü½ï}/NoÚ´I.—C“›|]]]8„âl·ÛMˆ¾¾¾'žxb‰"òçX,V†(ˆ•Qiii)U«Í‚aÖÔÔpkÃJŽ¢ù½ ¶´;x%T*UMMÍØØØää$k.e³Y®9noo_Ä·Y*KVj$¹vµnooïéé)_ÝgœH$ˆ±æñxôž“Óé„ÜQQ?á÷ûAµNb#¥RY”ð>ÔÐÐ�aªÎÎξ¾>N‡' ÙI¯×»yóf¡Pøæ›ojµZ…BAg†ËäÇÆÆˆH.«Aî`jl›¡­X±bhh¨¡¡†•g FMMM½½½$FL&“'WÄ>U.—­Q,ûŠÊƒ…Ãa MOðùKÐ|K¥Ò%«_w"íàÁƒóóóKϤÕjkkk+\ѳÚï~÷»sÎ9géì¨)•ÊM›6­Zµª¶¶¶³³S¥R­V¨ªªÂ–~kk+Ç«¤¦ˆäBô.+W®,eJˆå%Q) ½Ü/g³Y hƒˆàƒu¨Ô¼êéé‘ËåÍÍÍø9Sʯ'è2ïƒ=E"9Ëf³Ñæµ¼%tãE¢D.—Ó¿X(D"QCCþ;11Q*IÛÐÐ —Ë[ZZ@ˆNwcÛÞÞŽ!R(ƒø·ÛÝÙÙÙÕÕ…Àô¯ý+È[ÇÆÆüÿŸ½/“«*Ó¿µÞÚ÷}¯ê¥zI:I'ˆCp@$Ï£‚8 £"èD”a�QVA|”A”\FP@ÁÄ„%!k§×ôÞ]Ý]U]û¾×ï×/·–t @¾?xBߪ{OÝ{îùη¼ï‰,_¾Üf³íÞ½ÛëõÆãq8—Ë%—Ë»ººz{{»»»e2Ym-n²P(¨Õj‡Ãát:ÑMÀãñöîÝ pk±XdÖZFFF@„qæ™g2Oˆ›S·­€„2,üSX’ÇãaN§¥lÚpÇÆÆúúú˜û!$?ÉlÇÂ$ÔHóétÈCÜãv)¯~èl)‚ÓÃáááá##eÑh¾¿ZÕÝ»wC?pݺuÉd²îv{nn™‡ÁÁAš¦É"xÈŪßB»¨6;]÷.µµµá´R©Ôf³áÝno´-ðù|$.Á…È¥'&&ð¼ø|þŠ+êömcÊÑ4m·ÛÛÚÚ¤R)®.‰ nרÛ>Þjµ2·öË–-+•JÓÓÓ¨ -,,07Îb±˜œ íŽøÉ"‘hß¾}R©´. Š@ ðx<*• ÅV*2N“Æqæmî˜|lxx8‰ •Ëåööv¤¬áÅ­V«L&#ɱt:=55G…ᑩݽ{÷nÛ¶ J�ÉýJ®>55•L&wïÞ=>>Ží‚X,®»?€NŠJ¥ªT*4Mclr¤(Êï÷“N?0Y,_¾œ”a.—K(6gYúÂBæ Óù5 PÄ%XWa W«U‘H½^_ ÛËå`1­µº‡oAÙ¿ÿ–-[Èc…B[¶l©ô‰Ä–-[–¾}/­\.oÙ²d\°¡¡¡-[¶lÙ²eÛ¶mÔGÌ„BáêÕ«Ãáð–-[n¾ùæË.»lpppõêÕ4MoÙ²e×®]Z­¯lõêÕB¡°î¡ãÇ*•ÊÐÐP"‘èëëƒ - | lm¢è¹áµ\b ï!Iåiš¦iZ¯×‹D¢ááa¼ä$B¨Q(†o‘uœÙÌÍ °úûûF#ôýع{>ßãñ¬_¿þcûØŠ+ð›ÍÆápX'÷þAQT2™ ä„©Tj``�T­­­µÃ�ÆÿV*• „ …]]]ùEÖ”¦i¦//‹£££à[#È2™ŒJ …B(‘ç-ðº3Ôììl¥R'àwN‡8F§Ó‰D"™L†ÑbÇ Ñh¼™˜˜xã7öíÛ—Édêögc$•J¥R©Ëåbж°RŽûöí‹F£&“i||¼R©äóyTËd2 ‰D²}ûöd2©×ë1g(ГӻT«–ÉdM uÁ`°9Ô›Hrvvõµ1n"‘h$«r;Ö>‰çèèuwô$Ó9º’õÚµ&“©É8®»îº;î¸ã+_ù ÕæÍ›?ûÙÏj4š}ìcÌõ÷÷Ÿ{Jåì³Ï>Ü; …¸\®Á`8æ9SŠ¢^xá…íÛ·_~ù壣£_øÂ(ŠÚ»wïõ×_¿{÷îÉÉÉþð‡h$}—͹¹9•J%—˱6q¹Ü\.‡—ŸËå¾/’"‘èôÓO�—Ú·¾õ­uëÖ}öÙ¡PhçÎsss\pÁ5×\ÇÁgœñÅ/~1ïܹs~~~Æ _ûÚ×b±˜P(<óÌ3ë.šï™ñù|l<ûûûŸ{î¹b±HÓ´F£YXX“H$år™$ÁišV*•¬ý#)ÞJ$‰D’Éd j·”«‹Åæ=r¹\¥R…B¡ÃöÂC`ÐÉe5[«T*d‡ š. 8d2™ƒêêê‹Å©T ­>Ÿ¯R© Ããñ°ã4›Íù|¾X,Z,D0èžÇ ÁW©T@ÝNbÒ‘ˆ*T.—CËÀIäR©är¹ù|^¥R‘VÀB¡ … ÇW,½^o$![u, ÐPÇÝ „âL3,{À•Ôj5)ÃÀÿ¡Ñ�œ :xatp¤ÓiˆOâžøýþD"Œö4dV  íÝd2yÈ>øx<ÞhYÃ!‹Å …P\Õ:EQh_ìééy7:Åð“`é iºÉ ûÐh4ÙlV$ÉårGÚs0uϸ\®R©ÌårR©ôœsΡÕÖÙP2ŸMǃ¾Ã«\pÁ{öìùÅ/~±iÓ¦@ ðç?ÿ¹§§gíÚµýë_Á Åáp 9 {ã7Þ~ûí 68Οÿüç|>ÿŠ+®{þùçñzÏ–°ÉÉIVI6 žzê©—_~¹Ëår8·Ür˹çžû‘ žìvûÿ÷³þxçw2ÿ÷¼óÎÝ{í¡OúÓ ~?Þ,—ËŒŒH¥R¬³ÌŠ}.—k¢)ÇtcÇÊb±)ÔUPe9Z–Ü-4Cë†q4M3½,ÓGâB¡Ðjµà_€f]±X”ÉdhT ‡Ã …ÏX IÒ¡J¥2ŸÏ7÷¬T3¨€3QÂe*Ž‹D"F´/º++• 9'Öýr¹Ü¼ üªÌ‘ a…Z ®@`qq‘lÒišG"+ÅÍð‚ÑhÂizzš,µà¿—H$¹L& ‡ÃM$ÒëŠä2oyúL×»zõêºÍÖï£ÁýÀy“¤.6%µÏ¨QÂápÌÍÍ!4O$‘HDî>Ò´Þ%—\b6›ï»ï>ÄO=õÔš5kòùüÍ7ß<==MÓô½÷ÞË\¼^{íµï~÷»h>¹ûî»xà™™™›nºé¥—^¢iúÏþóM7Ý´téÉ£·k®¹fÓ¦MÌ¿œ}öÙßýîw].×}÷ÝW­V¯¿þzê„}ˆ ¥¾¥tHr8ÔW–.Y{XFIËr“Ö�2ìÚÿ]XX¨ÍËf‡" €pqhttÔçóE"‘ÑÑÑÝ»woß¾}xxøÀù|]ï333ˆ«Õ*²IXz˜ :f Ïç{½^À`‘ ¨;æ¥ü:tÆ£ðV­VÕjukkkGGGkk+”èÈ'qâ†ív{“çh±XhšÆ!¼ÄªÍd2‚³aŠ}4/ffffff˜>ƒÌô lÆÌM‰D"—ËŬ¾,å.Õ~¦Z­ªT*Ë6ÉÂ!L9$I’ºG0N'&F:fEŠî6›­Ñ!À³¹€cPĶÙl7Üpà 7ÜpÕUW‰D¢ßüæ7M>^~ùåeË–]uÕU^¯÷ùçŸ?Ê^øcbwÝu×<pÿý÷þóŸ?± ˜,“Éøýþ¥ôãRáAHF½{C8¦ÉòÌ,Hä¬V«J¥ ‡Ãv»Ãá¹R,±Å&‹Ãáðùü¡¡¡­[·îرƒD*‹‹‹$tCt•H$b±b4»K¥R£Ñ(“É4ÝnÇù4tvÈd2ä�ÁߺÄ;J¥är9¹…Bdƒjµº½½ÝårƒA£ÑØÖÖFFL19Cma Fîóù dLQ”V«mkk“H$N§“Ëå6B&q8Ò §R©àN¬V«P(ôx<ÌšN˜3ÅbQ,—ËåÑÑQ­V‹> —ËU.—“É$3â„îWm_«ÍfC®.b: !žR©Ä ¡\.ËÍÌ'1>±ëz½¾¶‹ƒ•d>dß2 8aíç –ÏçãóùLщw¤÷ÕúéOJÔlO=õÔ¯ýën·û¥—^zä‘G°OaqCÕµ?ýéOû÷ïg•ß/»ûî»~øáûï¿ÿX©ôž°hŒÕ²*‘H “qL®uH±µl6«Õj»»»±§iúé§ŸÆU*MÓushX¶Ìfs:ÆjŽôP∹ÂBðKÇã™…Ü(¢™HÐÊd2tp …|>Ìì‹ÄjµšÏçÇãqâ>1˜|>???ÈC¡PÈd2—�„ËÊ(8p�‡B¡Ýn Nèõz!Ìáp8Äb±Ýnçóù±X ˆ1�`YCjmmœœ$Žˆä‚øŠü]£ÑÈårô¹\®……î. p{…B!›Í‚Ä<µ˜åjµÇ].Rµˆ"‘¹!ˆ˜3mÿþýhØa%÷;;; …AGÕ:ƒZzíTO$µOL bKÙ‚à[D‚ IN§“,ø‰D(Ýl6[)u„‘ÓòåËy<ÞªU«.½ôRµZív»~øáûî»ïÒK/ýÙÏ~¶Dâ×O|â?ûÙÏ^~ùå={öÔmûyÏìþûïðÁï»ï¾ .¸  ’à„}”­§§§«« Ý+G|«ÕJ²1KáÂ˜Íæ5kÖ¬_¿Þf³àT2™Ä’çv»¥R)@Z¬ [cHãZÆétBž‡µâ Þ¿}>Y%Á#G þX¼ ’Vâ ™)¸&¦T*•Je4Õëõh.X¶lY¥Rä<ÚØÞzë-g2 ‹Ö¯_ÏjS‚à“Ï烞l4ÍåröÔÔT¥R‰D"ccc~¿¿T*¥ÓéJ¥Âl-¶X,ˆfffáÄU ’ Z#€¯»ºº(Š"8'¤° …²eËÈÙ{¾Õ䃦R d]fR^e³YæLkkk+•JƒƒƒuOèt:!/×d!-—˵õBæàáÀjÜr¹¼ ‘óð<¦ÌþØ\.GxîÁ¼ul"'Š¢öîÝk±XV­ZõØcQÙY¤R©J¥R©T¹\ޤÄb±P(L¥RçŸ>¨®ø|>úT*Õ¦M›^~ùå^xá}ìHŽF£H_àÁs¹ÜCrKsãñx â?áŽØ8ÎswÿÜ—q¹ R+BJ `jhdí:»»»‡††˜Ÿ_ ‘1ë[ »†vC.—3'Ÿ|òŽ;ȵ¦¦¦ªÕêðð0q à#')þ¡¡¡eË–íß¿_¡P( ÿ\»víž={ §Äj¼ffÏÀÄÊúiL)r'YÞQ§Ó 4utt`ËÜÒÒzxdÞðI&%üÎ<óL™Lz{{wíÚU(Þxã Š¡ÆÛÙÙ‰Ös ƒéh;;;E"Ñž={*•J¡P€R{±Xôx<øîž={ȇIoTkkëøøx¹\c†GÔAÜ1Bfñ²X,òx<VÆÔ n²Ñ¦i :¡-3'¶víZ.—;33ƒG366ÖäœÃÃÃL kV7±Fd(ÌÎbÀc½qLÍh¦z2˜Q™¾X,²hJ˜‰G©TjµZk#Ú#qN4Mwtt¸ÝntÂlܸ1—ËÝu×]wÝu×K/½tþùçßxã&“é[ßúV.—»óÎ;ýë__{íµ"‘hÕªU¿ùÍon¼ñÆý×¥(ê‰'žx=‡Ãéèè -‚ƒ¡££ã¶ÛnÃÿ:ާŸ~ú=^X±/{WëcªN­b]M[DL-ÔFž©Ñ«US‡ÓÝÝJ¥X9êZIÓjµ* 4ºë[¡PhddD&“¡M|~~~llŒ¦i²W«U ƒü^V©R©ô÷÷‹D¢D"‘H$¬V+ºRE"Ñääd hÔšŒªT*NÇ,2ï- i@ÖÈÉ]:pà�zÖáJÉÈY÷–Çã%“É`0ØÛÛ«ÓéR©T¡PX±bÅÛo¿-‘Här9x€´em°P–Ëe"뼟χŸfþL¨N“v𦇇‡{{{Óé4óëØsGˆ0B$~ÛÖÖV«ÕúÆoàn@;™LÖ]ÐÉ$Ìçó\.wvvöÌ3Ïìëë‹D"DgËåºÝîp8œN§ éCsoÇšNðv‡L7w`�Æ8p öÒäé‘ÜÚׇ\9á‰8µ@ �1s$u{RŽ™î±² îÇ?þñã‡^áƒk•JE"‘@ ×l6“ühÚ¢ÌÓ¨sW$’r¸ª¦V«•ôìa J¥¸JÝþu­V[­VÅbq4åñx™L¦½½=N3¹S].×ÜÜÐY_—Éd™L¥þ………t:­Óé\.WOOZ­þùçѪBº”ÏçcUeFKµª¦6›-—Ë1aIļ^¯Ïçƒò¬×ë­»€‚ªZ­öz½‰Äãñ(•ÊH$òÔSOA|½9k ô�Á/ŽOB?bjjŠÈÝJ¥R‚s‹ÅZ­–„n‡#8ü(…B¡R©€‡U(jµ2† ´iðóz½2™lll,C`0×UŒeNB·nÝ:Š¢&&&æææÀ}޽)‡Ãi¤ œëé‹ÅâR©Ô¨ÝÑf³…Ãa¤4�TŸeÊ1³Äso½õVçêO%\þ‰EíxØï ‚wtüÑ1D ÈkW«Uâ™�;e&µy<ž\.oÔû Äb1ö œ“T*- u)P¥R)«™ŠĭZðH¥R@ r¹\íÎ ƒœNg*•b ÔAQ­g‚ H333:.N‡B!€Ü!üªR©XÛ|…BÉ"œP(¢Y2|¦öZ>ŸÏf³ßWtlÅÐ_P÷¶ ¦U(R©MÓ“““`wE`>Ÿ'L¾ÌÚ —ËÕjµhÇÀ2'‹Qç(‹¸-x”ù|Ýð‹‹‹•J%›Í2{ fffડÖ©”d29>>¾aÆ–––x<>00€;/‹¥R©H$*‹jµzllÌãñ˜ÍæjµJ: dÅÚµ01mÄ%¡PH*•2szZ­V"‘Ò96t¸yìÃ2ìœÈ–N¡Pd³Y¹\ÎzúØ�‘N™ƒüu&$oAÊFµZ- ÏØ¾ƒ´Þ ;憮§÷áˆmppP©TÖv#çÃÊë$ŠB¡ Š dÉ …$/¡Õj™}eµ>£Ö·-¥/�j„àÔiºžü…å e2Yó® ¡P¸°°€‘‘\,•Jett‚,( ™);¨T*•¬lžH$‰Dðñ&hµZ¬³<O«ÕªT*&æ½VÓ–å_Ëår,ƒ"êÔÔ\óþG©×ëÃá0‡Ã‹Å¸Û …ÂétJ¥R¿ßî|…¬­óóóM¸oöÄ/jmm•ÉdÑhT§Ó9N§Ó955Ež8ú áøŒ•Ëå&“)‘H(ŠFLäˆðÀ! Q€‘H$,R;š¦IŠ˜L&’C[â4;CŽ91òù¼H$âp8ÌK£GQ¯×Ã77ái„¡åš>Ÿ;3È `œÞÙ> J¸\#›P£Ñ‰DL&Óìì,Ù«2Ë×v»DÌ]ó=/K jÉúIH²³"œN'ÉÖ¢tddÖlÐFÕÈ?5ª: A§×ë}>v²Küˇ †x<®R©HŸùL6›Xõ€Åb Y €½¸|>_¯×ÃÃOc6›c±h ¢U*•ÅÅEº1†\._deÎ ÞÅùçççÕjµÇãCmixxx~~ž%\¹zõj»ÝŽö6^‹‹‹h9©»qA¯™lde«%Sh´èY­Væé˜Ô§¹\®ÉdjäJ‹Åâââ¢L&ò¨ÆM=¸íMà´Ì‰‹ÅÌfskk+žìÜܾU§Î‰ Õ?L† À ‡ñ¾Ê�¬êsõ¬[Ø`¢:X Æ=²Êh(r¹\,R&T¨VÕ0•J¹ÝnR"ØÏ&W±Ûí~¿ßn·ÏÍÍét:,|‰DbrrR(¢ßÌf³-Eì «!‘»EŽ.™LB?ä{L_[—æÖÒé´ËåBx„9æp8öïßOØXË4x%R©y"©T ù1‰DÒÒÒBROÅb‘ÄÍétÚívãZ`z¥XV}>n¾P(”J¥Åb‘Ëåþýï—Éd˜6õz½ÍfëééÉf³p:‹‹‹¼H}Åårñù|’[Æ£$q§ÇãYŠ|"ëF5)š²N¨×ë™-ÓuÍív3¹†5 “«L "½a6›Ñ¯Ïô¸�θI.¡ö5Ôh4z½=>µzǵsBl¢ßå*y¢¶ô¾–×&­±My½^hí0A£mòR ͺŽÏç¯ZµjppP¥R1÷ѱXŒ•]„Žb8näÂáp¹\FõžéeɲÅáp’É$¤ ë&»ŒF#óP(jmm­V«###8 |’@ X:!@¸è_`õ©ýj4gffð£*• kQFY¨R©¤Ói‡ÃAed_išfFH¹\Î`0Ð4‹Å˜×Bsj*`CoooÇÆ¾•JE$‰‰ g4'''ý~?jЏ±¹\Îçóùý~B,ÂLv§¨T* ÒÆôâà_ÀDjkkg9ét:H0ãéc’m³Ÿ‚×…Ó² jÑäÞ²Ør<cNŒX,ÆzĵøÜ%Z*•Âi÷îÝÛ\|ò¸sN¨õ5ÑW>aï‹}ÿûßÿýïÿ¿ÿû¿h|ÿ€ÚáÊÂÂj•¶)ŠB‡1—Ëõz½µ} ‡tNµé8°9±*Ï]]]@Û0Íï÷{<žÉÉIt“[­Vf‘†©i[·x^­V‰ zí`¥q2™ÌÄÄ„@ `.”¹\®¥¥effæI<èLOOcáv¹\­­­ÌÇ©=&ƒ8ùqBä‡Ôâ:뮑H„,»$8.•JHíÚl6F344411¾|Ò^þY }€åZ,–\.·{÷n@ëÒé´L&ÓÙL‡+“É´Z-«ŒÄŒÑ™yàééifZ’µ[š™™éììÄLcÑEâ„�ÌNOO/Åg°¦+L¯µóçˆÉ‘ …ÂÈÈÈÄÄS¶øƒáœNØ{`©TªX,*•Êx<ÎãñÐÒF^'iѾŒCb±øºë®ûò—¿ŒymP·G™W¡Pà$TmŽc—W —ËenHñrËÌõe2„)µ¨^(!MMMÕ.n·Ûï÷c§Ïáp¦§§Y½CCCs³ÛíÌ´£0ÅR—!›z–ñx<²ºU«U²Ê éòå˘‡È‘o<pà€R©T©TØçóy€‡šo+3™Ìää$S-ptt”y úûû—/_^*•°p£‚Uw«“‘q–Ëe€Ÿ˜ãÁa>J.—K¸‘�´1 \.W,C¯]þøu•JÅçó)Š}ûö%“I8H›Í†Ûe·ÛÓé4pKÝÝÝ}}}{¯V«,|.Æ€§`±X0gX”¸ét¯[6›%3­ní‡tÒ³îÃ÷x4&“©\.7/µ®U*•\.ÇôLxX¬€×|íÊ+¯ôx<[·nmmm=묳üñÞÞÞóÎ;oõêÕ=öX.—õz½W^yå¯~õ+ÇóÀÜzë­£££íííçwÞÇ?þñk®¹& mÚ´ÉãñüùÏþüç?ÒI'Õ3ŽCºÿFÃU£O &‘.%ÿKÒGÌw üßȉ±<“@ p:>Ÿx&tB%(T«Õ¶¶¶X,öâ‹/ær9.—ËlåÂUðh˜Ã ¯4J ø·ÙlN&“Zív{] ³ÙŒÒýþýûiš®-ôx<ØáHÎgvvÖãñ,[¶¬½½Ë:‹Œ)<::ÊZLÕjµ^¯cccF£þ@,Ûl6dYYǺûn‡\¿B¡`•xñD˜'œœœŒÇãTwQµZ%êårÍ{ «««§§ÇÞôO‚�� �IDATãñðx¼ñññl6ÛÕÕuÚi§9ŽÙÙÙŽŽŽÎÎN€½(Šjmm@i4‘ßô¡iÚëõ*•J“ÉDæ u?ΜNÌø‰ÙS÷·³þH4—ËXÏ©Î#x×ÈÓ¯l‹E.—K$2{ë*á~$"§ññqææK"‘x½Þ={öØívRíÝ»7®_¿>ŸÏoß¾™Ky5ôÞUÛ°aÃ'>ñ‰T*uýõ×ÿû¿ÿûüã7~ç;ßY³f;ðFsÇw|éK_b}ë3ŸùŒN§{ã7^|ñÅ‹/¾¸££衇ž~úé–––+®¸âµ×^;Þ~,`˜2™L§Ó!(!iuQ“jµš ÝeI—êt:–FˬVëää$óœ& ‘PÔ5‰¤X,Úl6¼«¯¾ú*>033½ÍZÍ'hŸãÒhá­uBsss6›ˆ.%KIlrÅét–J%@w™™LÖêâ"“É444„øüßSSSÙlÖjµÆb1æò*‹e2 0R©T"‘ ¥GQ_1›ÍhCW(‘H$“ÉLMMiK™B¡0 ¤ã€˜L&#DñxO,C O¡P$‰L&3== ö `fÍfs8&q ˆ?0˜‘‘‘ÞÞÞ½{÷NLLÀ™Íf‚žFI_"‘ I$RvBÎS("IÓ4Je^¯wzz:—Ë¡f‹Å²Ù,“òC©TjµZ2Ó�÷nž@ƒÄp]_U›^ŠÙl¶ñññ£oU×h4ˆ- «ñÁçóI¥RÐY!^ƒÉ9§b‘óúëœÍ›9CCT @¥R”PH™ÍÕžžÊ§?M­^}œ¯Â?þøƒ>xÆgÀÓ Wä /üÚ×¾vÇw¼ùæ›ßüæ7ÛÚÚN=õÔ……… /¼ÐétÂ}ÅW|ˆÓ\ð?ÿó?û÷ïÿøÇ?>>>þä“O²ÞvdziÓ¦%ʈÜ{ï½ÍefÞcœ–Ìx@#·d}²jR¤Ì¥¦i@J¥XyÖµ°¢Þ øM§ÓÅbQ¥R¡+ÊñápX(»Ý®P(HœP6Ë3A1(—Ëét:0Ü4[1{:.þ7¬/ÌC‰D‚ø•JøK0ĺ¬ÕjÃáðôô´L&Ëf³  ‚E~)•J‘hI¡P˜L¦X,¦V«™­%Ø(”J%tÿ×`ÔjµJ¥CÐɼíjµD×µË7¤ZÉ‡É •JåÌÌŒÅbI$r¹<›ÍLN(‰L&“Z­ðù|2™,‘H¤R©H$ròÉ'ÛívHÁÆááarÛu:Ç›ŸŸW(Ó §¥ÓéH;¢ ✀ñ"ÒMöeÞ@ÀThÄ›3h®1«tGðÒ‘F!lAl6[ÝÖD¹\~àÀæÍ®‡vNœÍ›¹÷ÞË9ØVQ5™ª]]œ¾>ÎÔgjŠû§?UÎ8£rÛmT­ÃãǾño¬_¿ÿ•$EQ[·n½é¦›zzzî¼óN÷ØcÙl¶[n¹å /üД?øÁHXÇGGG׬Y³fÍš‡?ffHš¾nÐн¶f¦s"Ꟶ×b%jÇÀçó+• q ñ&× ‡Ã …‚¹ƒÎf³;}¦s‰DÑh4×½ÜRŒhÚÆ`0X» ‘å5ŸÏ3›© µekP&“A G2B¤é ÎÎÎx<®×ëY ˜B¡ÐßßVV¢´$—Ë=H$ªK‡A¶H„°±V«õûýµÍñÁ` àºµ+21ø|>ˆ ™÷V$1es�MÓ---ØUD"‘•+W* ½^}æA,S(DÁ·X,H‹Ãá0®Á`˜žžFdLÞJÖòÍãñX`ÕF Ý#3Nº¬#óO\.—•l´IZŠÆì!2’œÇç}ë[Ä3UÎ?¿üÌ3•‡.ÿñÕƒˆkîk¯qo¼‘z—Ëï†mÛ¶íæ›oîîîþÞ÷¾§Õj …ÂOúÓr¹¼}ûön¸aëÖ­*Tooï-·Ü²|ùr( <ˆç?ˆ–Ïç—BY7|k8f1œf2™º0Û|>_·­œ‰´E0 '„ê¡´˜™™Ù·o ÿ ¤-S=82B¬E’¬µ)²ÿÉd.—‹ÊÕFã5¤iY¾™r¹l·Ûiš¶Z­©T*‹1OŠäÌf³L&›œœ$쟉„ˆ×á/À>ãßr¹¾“Ïçwtt°ö*• ƒÎ î X­Vd±XꮪLFy"’ 3Ø1˜L¦@ ÀÉ5:^øéh4:55…¦8t~¯Zµª««Ëjµ¶´´ Œ$|>ßääd>ŸGìÈüÉ>Ÿojj ¨,—Ëß¶lÙ2·Ûíp8jç ó‡är¹#0°¬®špµZŸŸ?âÈ)ŸÏ“9�*¦&6›ÍÌ’¤\.W©TKvN}}ÜÿøŸã6›+7ÞHa[¡×W®¸âŸgÙº•sÜ/åwÝu×e—]öÕ¯~•ñûúöíÛwÆg GÓô¯~õ«;ï¼ócûX"‘¸ñÆßzë­½[r:7nܲeËe—]vÛm·¡*ðÀÄãñ{î¹§³³“õùÿøÇ±Xì²Ë.{àN?ýô 6o¿ˆ)]zV,kÅoŽ­Aî‰êÅb¬=r6›…ˆ* ݪÕjmÇn·ƒÌ¦nnÕ±XÜÒÒR,‰ þêV¹ÁyšJ¥<<ª ˆ0p[p!’¦“Édè€ooo_¹reOOÅbÁ·ÉDU)‰´·· œÄh4êõz.—›J¥ p¡P‡ÃSSSÃÃÃ~¿Ú€íííx=óù<\õòåËY#îR4Åb ½‰D‹…hÚF£Q¿ßOˆ ˜+~&“!¿…Ü|+“É 'ÙÒÒB¶ˆù|¾L&;õÔSÕj5º'@ÞªÑhXìäM&S.—Ãv! AŸ0‘H ¥R‰a4Jй\.Vkƒ^¯ÇÍYJ ]«„ëv»ëvrÂuL&9SωÇãÕÊÝf2¦¬¥pk–Öãþþ÷Ìæ¾ÊÅS Ö†êÉ'¿#ÆúóŸ«“fÇm‰eåÊ•Ìg|á…r¹Ü»îº«½½}ÅŠ|>ÿ3Ÿù ÍÎÎ>õÔS> %Øw¿ûÝo|ãèUS*•×^{í9眃Cmmm*•êì³Ï~öÙg% ¹×]wÝÅ_ÜÖÖ¶råÊgŸ}–¼!n·ûßøÆ%—\ÒÚÚÊáp^zé¥÷=]ÛDÐ܈ª)yI—÷¡Vº´¹a‡ÈÊÖ5æ2йº« —ËÕëõµG‰Nk �3“B¡¨%1«ýÆV©TL&r¡¤Îa0FGGI!Ô®¡P¨³³Óçó­Zµ 0‡Cn£×ëåp8sss¥R þ8ƒaÖ`0ÌÏÏcAT©T¹ðx<2™L­VC¼þ€_0±PâãÉ€¯Â0¬Vk<'„å,"vü.‡c0Huáf2™ŒÅb>Ÿï¬³Î*‹€šår9«Õj4‡ÕjM$cccSSS»wï¦iU7<‘ÎÎNW,'&&à@AËãñ@cÄRÅbq[íãp»ÝˆPiš6›Íx‰DnžÜŠ&“©„ àv0<¤ÜåQóüuU<âñ¸×ë÷z½Édrff†Õ¿ÓÌ9qÞù;«gžùŽÃï¬LpÛø[GGÇÉït¨&“éúë¯ÿú׿þ¹Ï}îÅ_4 §žzêš5k~ùË_~¸£%–®¨J¥bÝ™³Î:«R©¼úê«Ä9¹Ýn·Û³>ÜäÐûb.—ë°üÍ£¹"ªèŽÚl6¥RI@9]]]‡ Ú%&‰l6³o%“Étww£g¬Ñ·°V:Ž™™ŸÏ×Ú599ÙÒÒ211•% †ÃaF÷CQTww÷ØØ¸½É™¢¨R©´ÿþb±¸eËÖÕ fˉÙlF„dc{{;z"À‚¡ÕjišV*•ýýý+V¬0›Íù|~ff†Ïç£PQ냙'$7Ê`0 Ün·ÏçËf³¤ÓqaYìîîžžž†ˆ;sÇÐßß_.—µZ­ÉdÂ<N&“Ë–-Óétù|ààašžžîïï‡4m__ߨ؇ÃQ*•:P(N•J%VU ÷°®·p¹\±X ΩP(÷Q§Ó13Í'a¹\&> IÑ&s »»{pp¡g#bb‹,½ÜÕHîvrr²³³Š_µG›9§êÉ'söíûÇ¿ívŠEëËÂL£Lè{ljµúW¿úÕ¿øÅSO=uóæÍñx|nn¢;‰ä{Ì«=ÿüó]]]•JåÊ+¯üö·¿ý|s‰Ïºy¼Ã½„ÛíŽF£ñxy fIÃív‡B!‡ÃFÞr¹<77Ç Á§m´.ðùü}_ºº©’ññq"wëñx‚Áààà`µZˆ§.²™}"Zbè$J¸<¸KȪöööf³Ù¹¹9Fƒš »¸nµZ=33c³Ùд](˜¸cœ°R©ÔjÖÁÇ´´´ƒÁþþ~‰Drî¹çvwwƒpŽð­·Þ"[(0Y,NW·Žˆ¶¶¶*ŠÁÁÁ\.—N§IóK©TÃMÈç󃃃‡¥>500ÀãñÐ+.Ή»ªˆt: Ña‘H„ÚÒðð°B¡xóÍ7Á°Çãñzzz|>X” qíîîî}ûö¶ÌápÚÚÚ°Y1¸Áä¢úßS­V§§§ñÇU«VíÙ³‡ÌÕÚ.žFJ͇;Ûñˆ³ÙlÀD"Áììè蘘˜@ ¾J¥R(‡$lliiYXXÈd2D?÷ðœSå+_©ÊdÜgž¡’ÉÊ×¾Æ>Ìâ"«Á÷?f0:;;™é&‰DÒÙÙ‰¶4>Ÿÿä“O^|ñÅ×\sÍÖ­[?÷¹ÏwÞyEÝ{ï½çŸþGÓ9 …ÂZÉÅ–òŠ¥!¨K/†ÝúÀÀ�`1X뙀@À?ß@±‰® žW·ôEøÖó‹E&)¸R©¤iÚï÷Ó4¼Q5e6þ¹Ýî™™ÉÐ4].—G6›]XX@Óàž={0Nð‚ûýþÖÖÖ¹¹¹T*l)¸EôzýÌÌ ÖâJ¥ÂÄ[­ÖB¡€‘€¨=„´f|||ùòå---Æh4z<¡P¸¸¸8<<œÏçW¬XÇs¹Üï~÷;Ü%"ñW÷žP…ÛÕÕ588H®EÓ4ŸÏÏår`G-•JÕjòN¬¤}kk+ö‘H„t‘´¶¶ …ÂgŸ}výúõH¬e³Y¡P8== Qù‰‰ ‘H¤Óé”ãišÞµk4Ÿ ƒ\.÷z½™LF lÛ¶-—ˉÅbò €ÙlÖëõèhçr¹¨5ÖrA±fÚ»'™Q«V\×x<ŠmP…FÄ¥à«HLÖä*M[Éy¼ê¥—–/½´~Ò5‚Ær)ï»]sÍ5×\s ó/+W®$Ýä°'Ÿ|ÿ`ýý„}8L*•òùüD"qÄo5ýÊ|»šøÈÑÑQ©TÊJװ𹃡Z­’f0h¡ ³Ù<00Ð\iT§ÓE">ŸOªô„[‡²Ùl©Tªå~öûýp‡À`0`5D‹¤‰‰„Ùlž››+ Dø\.—k·Û�!éõúP(Är¥$ç„R©j†‘‘‘HT©TÀÁý¾Óéììì¤iz|||jj*“ÉÈd²íÛ·{½^œD.—3A¸ÄŸÏg&7£ü m6›N§[XX'©-‚Ï%'O¥RdIU(b±xqqÎ[¡PH$’±±1t1 Ë~¥T*ÍÏϯ_¿~ff擟ü$|ö믿^,½^ïüü<2Þ�·¥Ói Úl6&œyaa¡µµŒb„R7'—ËI$’B¡P*•ð»X“ð}4ÌRV[M¥RÉçób±ø˜!9Cç,�ÕSN9±±-..nÿ„½3Œ6çôyL2™<€¡\.‡Ž'Sî– mkõIy<T>ëîa¬ž%$FB¡^{[4rNØû;ÎL&£P(òù<ðr¹\Ý^‰D‚Œ dÝÑ"ÁRušššr:ÑhtvvÖáp�#Œ7d& h4 …–õºEx‰D 5fz .A"‘”J%³Ù,‰Àˇ íj±XL À;†Ãa mqÆ …BÖRˆ–ÈÝBî=™Lêt:èÍÆp8LÓr¹<ŸÏ«T*4ËAù7‰hµZN‡® ­V‹Ü¬ÇãAž )5ø*©TÊãñN:餞ž¥R9??½Âþýû].×àà ¸bÓé´ßï£Ïèè(KŽ9™LÊd2’W„sEä*—ˉš0&!¶f)yÄG0Ã!wËšlNXS‘Ëå� ØïŸsZXà¼øâ?=WYÀ «µR©”N§‰€ØGÖ ¯Éô jµšl´ÑïËb}>\+—Ë(8³tH¡*‹=O"‘ k=‡ÃQ«Õóóób±«-+ÚX©TpM©T*lV–Õšžžær¹4MG£ÑÚx<I8B+l†št çóyto#»ˆÞk‹Å255¥Óéu%“I>Ÿ/‰j—!HÊ¢þÏ:- 9È7F"ƒÁ033c2™‚ÁàŽ;PHƒ�]±X\¾|ùØØXµZÍçóR©”Ëå"@4 U$Q©TétŠÆb±,y±XL£Ñ@ü‚<; ìv¤– òÈx<MÓ &ºl4óùüüü¼P(õ;ºÌ^‚8äüü|[[›D"‘Éd\.¢®F£Ï" ¦×ë÷íÛ‡¥ŸèÌBY*‰ 5ƒÃáèõú`0H¨4˜"îØú4_÷ù|þR¶_u!Øàû¨=áa½5‚ ª‘£Ae‘sªV¹wÞÉa8ØÊ׿Nì×:aGàœÌfó ÂckÌ7ªR©X­VF388x40¼Ì¬=c©TJ¥R(a2 uv»=“É  A¾v¬P(€“‚‰Š …µÅ.—‹TÑ'¥(Êl6/..šÍæZY[Š¢l6[ Àê½9!Yò„B¡ÅbI¥RÌk•Ëå¶¶6ttwwø0ô�Éh!EÓt¥RÁzD-ú šl¶ð0/ š‰DмžÍfûúú ùÇGFFÐ2@n”ÝnïììL¥R<ð),..V«U½^ŸÉd|>‡Ãa­§äV£"H–`&ãªÕj…ÏÆ…Âáp8Öét|>Â’©T ÷ ×R*•�QT"‘�Pwÿþý;wœD/‰$ ¼”T*mÁ`jµ$B^P0Öë¶ã‰4;Xr·MNÈ’c>ä x”…±#qNœGånÛöÏA|å+Õ/~ñÄjxÄ&>²mÇИ›>l«ñoN§ÑhÐ|4oKüS©TB^H¡PÈårlð!:Ž×ž€+*q¹\›ÍÆâR".•JLʤKq¢OJQ=œNçìì¬D"Q(…BTž ø€Ö)Ðl“5 ë Íf‹Åbð X›ÚÛÛ9ÎØØ˜V«•Éd…B¡Z­:ŽB¡Àåråry4µX,à3år¹\.I'ÇÉçó™LƒÐÏ¥(Êb± EÓ4�OÈîØ±£T*•Ëe¥R !Újµ:;;«V«A0(‹I"  ]¥R9;;›ËåÌfs.—Ãm™››CŽÔétNNNÊd2‰D‚±6+¨R©¸\.Sƒ÷ŠlüQ{ …BG§ÓÆÙÙY|+™Lú|>8ªr¹‡ÁªÀårwîÜ988sø~B…—L&ñ3!“ˆÌqñ(ÅÊÇçó¹\®D"±î’0lTG ÿfN§æÆd˜`. Y,–H$R!±Ô“ß çÄùýïy?ü\^ù¯ÿª~ò“Çp‰™šš:ÜVà–UÎü ÊÂG,ÞuÂ(Š–H$ÐJ¨}?óù<!¨-¢ÑèQ …ún™� ¸&ÒׂÔPs‚Z|.Sº”醱 MXK掕ŒaÍš5H—™Íæt:­T*hÅbf³zÛn·½�¨²€.—ËA b||@Ñr¹œL&»»»©wÖJ�~  ¾ƒ! :Žt:].—Åbä6 ™ÍfÈ­z½ÞÉÉÉöööþþ~ô@OÁl6£�ƒ"ù½Ñhh-Ð7LNNâFi‹GŒ!ÕÖꘉiK‚9âεZ-‡Ã!Ú¯^¯’ðè&“Él6K$ ˜¢¨™™¨lÌÎΦR©ööö±±1<£t:Í \àx¢Ñ(v'óóóË—/Çß1�&Ò–ìKæææÐ±°°pX 3ÊgJë6ÚÕaw211ár¹jûuc±Xwww>ŸËf³7ŒF£¬!©Õj4ª$“I0¡ðù|§ÓyÈ¢£pNÕ*ç—¿äýìgÿ˜Î9§²q#ÕXçÈ,›Í:ŽžžžBº‰ùÇâ¿GcµÀL©T &Êþ¾x”‰.—ÛÑÑ188X(ð27yŽXÙ©J¸ÔA¹[æxl6zš»O»ÝŽ¥Y©TŠD"&—Ëõ÷÷c`‹‹‹•Jedd+5j*•jaaÁápH$F£ÑhÐ’ŽŸ“H$vìØ…awŽŸãñx,ËÛo¿íóùpÚ`0ˆ¥’}Ae±X*• Y·Û].—‘gãr¹J¥R¡PÌÎΊÅb¹\>88h·ÛëVÝ÷îÝ‹ÕôHäÞiÛÚÚZ©TJ¥ëYLNNB—‹…´eÍ`us¹\kk«\.Á©@÷°°° É6ˆ¦é®®®D"ñꫯ‹ÅÎÎÎ`0ˆ‡ð±¹¹9¸Ì®®.‘Häp8:;;«ÕêÔԢɶ¶¶™™pñ±šYÐëˆsRn¸‰5j*© Êår#€íÔÔTKK uP¶˜bPT0SAèàG[<>S7»H§V*•µ MK–¢*•¸?ø<SÕf+ÿìg•üà˜{&ò¼Q…ûÙŽ;@]Zëv̧PmÞìŸÑ?C4–p’ñVƒÐ=hµÚžžÌëº1æµD"‹§ƒ¢¨¡¡! “È_�ƒU*•œz8Båq8àf8þ÷Ÿ{O>ŸÏç{½^‚. îÞÙÙ‰xÁ–X,v8ƒÁjµ®X±â”SN9í´Ó<ZÀ?ñ‰Oèt:ìÅb±ËåÊçó¥RÉápD"‘7Þx›�´­W«U°¦’ÎòåËËå2´äq+&''].ÿÆãqŸÏg±X‚Á`(joo%koo/VCê ¶™F|K¥RÀ´Z­ …B4¹ J¥ÒÞÞ^§ÓÉåry<^{{»X,Fbvtt”| ¼«ävºÐÙÏårGFFZZZ …‚D"Y±b…ËåªT*€|•J%Ü^ÄÍPúÈd2…B¡«« é½{÷öõõíß¿?=44444¤R©ôz½L&+•J µµ%=ü©TJ¼Ü�ä‰`~2¿ÕH¢°6 �6 ܇Ãñz½B¡0N4“x‚•3ôù|årÙãñH¥ÒÕ«W¯[·®»»»V|’:ˆí‹ÇãµÞk©zNÜoäþíoEUþõ_+›6QMéfOX£…¬úänÿ€ÖŸH§Ö$‰N§;$ˆ}É …*Ù¼³z«˜f2™˜¤æ¿ÉLÖW«U¯aðh œ˜˜�à·¶âb¤ááa’Éd4M3_òÖÖÖ‘‘‘‘‘­V+‹É¡‘‘‘U«V €Ž¨\.;N…BDœ\.w»Ý.—+—ËÅãqІú|¾5kÖlÞ¼™xA4°1épß„J¥ÑC:ÆØ¦¦¦ŒFã®]»˜ƒ‡"XàÅÅÅb±(“ÉùäóùèËÀWÌfs</‹ÄׂÚG ´´´ØíöÞÞÞh4*‘HÒéôîÝ»Ñ.—˃Á I·"ƒ‡Q»}aö¤�…µóƒ¡½½Õ©õë×õ…!THR©”N§C }òÉ'¿þúë‘D76XˆZZZP±›˜˜Ø¼ys±X€—™=‹Åb,Ùûþþ~Ìì?–˜Üc¢u:]“šV]C�ÍãñR©y¡š,bûŒl'F:::¬V+dìwïÞÍ4Áü.Á9•JÜÿ÷ÿ¸›7SU¹ì²Êµ×¾—d[·nÅc0 Ë–-£(jppÔÅbñ©§žÊüüž={½’C³³³LÈÛúõëY±ËÀÀ@ 8å”SÀN‹ÅvïÞMŽööö"÷h4ºgÏVI üýïÇÿ:HëîÞ½³_*•®]»ö„·8®,N×fÉXâIµoD"9bU7š¦Ãá0+»ÉÂÆï÷º ‘§ÅÅEÔÈg A›ËåXþµ–Y�ÀRtº–/,‹{öìAó1—Ë››j ¶¨Þs8¬8~¿ .…BQ©Td2™V«]XXÐh4¤ïyxxX&“Aˆ—°Z­óóó™Lt±LÌìÔÔ”L&ær¹àÓK¥R|>? MNN†B!çt:³Ù,q!htDSfP¥Rùý~³Ù,•Jý~?¨íðy‘H%\òA& 8-uIVètºx<ÎårÓé4´’Åb±ÅbAE ºJè}Èf³CCC�HÅãqFÃçóy<žV«…Obžypp°··w÷îÝ•JE­VƒAfÌ4„täNr¹\¯×;00�Ì$}«þT›ú>V™@æÌÔëõ؉Åb“ÉäõzF£Ûí$ü°ô>圪UîøÏtÞyÍ<ÓÔ÷ùç+—_N;RêçŸþꫯ>ÿüóC¡Ð=÷ܳzõêŸüä'O=õÔyçFE¦szov(d�� �IDATóÍ7ÿó?ÿ³µµU&“½öÚk?üð'?ùÉçž{nÓ¦MëÖ­s¹\p'Ä9 ïÞ½û±Ç{ûí·wìØ4ËÀÀÀE]ÔÑÑÑÛÛ‹l>qN‹‹‹øÃðï×_}zzz×®][·n½å–[>ýéOOMMI$’Ûo¿=ó›ßìêê …Û¶m{衇Î8ãŒ.á}1±XÌáp2™ À°M Bjµšåœ˜˜D§P(j ŸKUSy®ËRƒÞ0°Ì¡•,¨ˆ { ÊQâfP”n²ŸÒjI�¨’UÏçC˵R©ƒA´ÆP¥S™J¥’ɤËåJ§Ó333Z­6ŸÏ#÷%‘H�ÿR«Õñxƒçñxd$Eõ‰‰ ½^Ïçó 19œ š hšfm¨•J¥ÅbÙ±cóPaGÓDoѸ¸¸(—ËçææB¡˜U™;�hàÒhÇG‰a( H$zE¾ˆºÝn| ñÈV«•Ïç§Óéùùù={ö€›Üív'‰ùùù®®®“N: {¸|æækçÎb±¡*Ë#òx<D*ÌÁ °ˆD"€W«Õ“N:) ‚ ´\.«ÕêH$"‰x<^£ò¤X,hìÝ{Ýr¹‰Îe2Y0_¾B¡˜ŸŸÇ|Oî1pNœ?üûÌ3EUuºÊ 74ôLÕ*÷8»vQW]Å:òòË/÷÷÷Suå•W>òÈ#f³ùâ‹/^âO½ãŽ; …ÂC=´}ûöO}êS¿ûÝï2™ÌàààE]ôÃþHx8pà¹çž;í´ÓÀyçwõÕWK¥R‹Åò£ýÈn·oÞ¼yýúõßÿþ÷Iú5‹=úè£^¯W«Õ޳z~ûÛßvttÜvÛmguk<ííí=ôEQ[¶lÙ·oßg?ûY•JµiÓ&›ÍöÐCýö·¿½òÊ+Ï8ã ƒÁð™Ï|æë_ÿ:—Ëu¹\Pˆ?žWðÉÉÉ?þñ§œrʺuëž}öÙñññ¯~õ«ç‘Gñx<6lxóÍ7ß|óM|øÊ+¯”J¥@à‰'žÀ_Î:ë¬#Kˆ¿Fj0‡$}©Íò ‚B¡�çT,ë æ²¾YÝÂ>MӵܕJ…ÙÔ„þoTÈEÌÄ\¹XÚ£,™L2‹mø½}ÛR©½¦¯¯O,ûý~Hî¦ÓéP(T,‡Ãñù|Èi4·Û=88ˆ&@@_A+—Ë¡ØËåL&T‘¢Ñ(3ÝJR-Ç*&“Éï÷Õ‹ÅÐâ¨P(�© …AGfoff¦¶¡7 (œmrrR.—“ìà´\.—<Õ›Édfgg{{{ûúú, hAÌfó²eË€ŽD"CCC(˜ÙívÒÈP­V9N©TgÍ:š¦qÏëÂiÅb±F£a2ÿj4št:Ïç+• ‘q»Ýv»½­­-ÿéOÊd2˜‡�Mã[©TŠ•^ú$<J“H$|>Sw||[¢€»¤nÑøpœ“Ïǽï¾Ün—‹óÌ3j)œ]»¸[·VN:‰zg½ë¥—^ºõÖ[ÿå_þå…^¸ä’K~úÓŸÞÿýGó³_{íµ¾¾>›ÍvÏ=÷‚;î¸aòí·ß¢ 6Ü{ï½óóóZ­öꫯ|ùå—×®]ûë_ÿš¢¨ë¯¿Þ`0D"‘Ûo¿ý /üå/yÊ)§ÌÎÎZ­H$òøã·´´¼òÊ+¯¼òÊ%—\jáZ;00p÷Ýw×­~_tÑE]tÑ]wݵ°°`0˜ò†Ç§ŽŽÞ~ûíßùÎwÖ­[÷ôÓOÿå/¹øâ‹¹\îí·ß~Î9ç˜Íæ›o¾Ùår­]»öÁœ˜˜øÁ~pã7ŽŒŒ\~ù导òÊæÍ›ïºë®ZYÂãÁÈΣ¶uk\<gc™FB" 4ë’ô4’x_b±ê½Ì:%2~ÔA……&cÐjµ`æfý½6oÉáp²Ùl °Z­P?¥tðR©”T*Åzçóùfgg¡¾!‰ººº°¢…B!¹\NÓ4r }}}ˆÀÁC?·P(Ôrt5B‰Æùùy‹ÅÕA„Jh+'Y}èõÑ4­V«!ÙW©TH§œÙlN&“�ià飧Y£Ñ0åç+•J¹\^XX¨T*RA Õj mOµZåóùˆba ¢@±maa!™L’(ó‰Daw.—Óh4d3±°°�fB³Ù „³N9??%E*•Ò4 êtfL,‰är9èU*"fŒbˆnÔWJ¥²Z­²æÀR&áOl2ò;wF£Q¾uŸ~Ýa4üéO9}/wçNjçÎC ªfûüöÛoŸvÚißþö·Ï?ÿü[o½õç?ÿù'õÙÏ~Ù6Š¢®¹æš|>ï½÷ž|òÉ?þ8YW¯^ív»ûÛßöõõ}éK_züñÇñ÷;ï¼sllì‰'ž0?þ8Zj«ÖäóO>ùä·¾õ­‡z¨££ƒù™^xáÅ_üÚ×¾FX)ëÚI'´¸¸øÿ÷û÷ï?÷Üsgç´råÊ+®¸â™gža–Ç®»î:—˵qãÆ¡¡¡]»v]z饗_~¹×ë…LÜÿøG£ÑÈçóo¿ýö4jQ;žM©TÚl¶\.'ÔjõÈÈH“·ôhZxÙRT Y× …ƒnMÏä ÈÁ!ð½.e ¨*µ··g2™x<Ž‚Š\.÷ûý»{š¦A$&ž©©©‰‰ {g³Y²ÜCA|tE‘Bu- \Újµ†B¡F7vffd©HKŠÅb©TZ»Ã@‹ ü"ád(›‰D"½^???‘Èåòp8ÌZ™AÉL¸T*A¥ ƒ7›ÍÕj5 Ð4 ½>—ˉD”J%(êA>´°°àr¹P¢‰DàæÈår[.—K¥’F£A�G…~?Tt:~,+Üz²@ سgO.—Ëf³uùêIuzu'!Üxb³"‰‰ Œ§6>#O¿.Þ£±s …8ýëá9Ìz¹•+W ƒÁpÕUW=òÈ#Gù>wvv'tÝu×½úê«EY,¦§9ýôÓ³Ùì—¿üå×_ý¦›n"‡~ñ‹_üío+‹ …¢‘†T*%‡¶oßþ—¿ü¥¶¢0>>>11±zõjÈW7²3Î8#_uÕU$!vÜšÁ`X±bÅ£>ÊLm½òÊ+==='Ÿ|2SoýúõÈ5½üòËo½õÖøC—ËõÍo~ÓøNåÉ÷×¼^/³oôhäu …àçr¹F£9ú©©)ô"ã>Ið¹u%hÆx<žÇãAO3²Ùlv)—€²þM0§ííí£££DÇ¡Ú&8ܘ�|«\.‡B!‰Db³Ù ë “Ér¹œ^¯ÏçóÅb´op9‹¤;(Ú‹EäÇPëf¦Å�ÃdÆI$t@³�è”b±˜Ñh4333Pß ŸÇã«W¯N¥RXñ¡ý£×ëYJB°@ €”Æ€ @V‰jx©TÊf³MLLÔm{éíííïïǰh"äB›¸òöíÛgµZÕj5ä@ØÑ××'‘HS©|d"‘@'…V«ŸŸ7™LÕj#ÇTôûýD…àX!Èë!@t6BÆÃ…í×ucµƒª!ôkbHçâ–21Î0‡Ã±¸¸X×S6q¢ÿŒŽV›vîäfßsõÝ/<üøÇ?îééyë­·–øù—^z©§§ç±Ç[âç§§§{zzn¸áê„56@pÒI'}ùË_¾úê«ß~ûík¯½–ô+'%4Vv޹œ‹E„sssýýý@`÷îÝ g#‡`~¿ßjµŠD"´‰.ÝÚÚÚêÖ¢\.—L&Ãþû�äÔ 4MmpÏd @Ä •JáY™‡(Šr»ÝL³L&ÃZqð-ê 7` P( ;wî, ¯½öÚŽ;P»Õét©TJ¥RÙl¶¡¡!¹\.“É&''A$ár¹+V¬@§«P(\½z5~(XÈJ máD'&&2™Ìäääää$ÇCψÙlÆž¯££C(jµÚÞÞ^”‹ 6_·–^(4 Ñ. }}} S@ 8ú;v…B&ˆÓéDóúîH‚Ž™:(4\,§§§!Ú‹BT €÷²X,Éd2ÎÍÍ …B´8’ œ¢N§Cêk.—ÛÕÕU.—s¹6î&“ ?¿R©Àç1{ÜW®\)‹™³š”BÞ01ÇÚµkIç×Ò SI|ÌzïÃ\ ñ«L&«ûŠ5á2°iKòL6õNVTƾóï<ûì³çŸþ_ÿúו+Wþýï¿îºë–xN•JÅápÂáp"‘�éÒÖP®V«¸›úÓŸ ÃO~ò“n¸Ájµîر#‰ ½ªT*E"”v‘¥åp8ƒáÊ+¯¬›âÇã (äÊd2”ïÜn÷ºuë(ŠúÃþð½ï}ï¶ÛnÛ°aÙ$‚_+•J¡±gãÆV«MíÆñïo.½ôÒn¸áÛßþö¾ð…`0xÎ9çèõú¿þõ¯Hs‹Åb4~úé^¯7 ¶µµ]~ùå—^z)’«Gæún¤ËXÑsxpBxÖ“““ Àf"_ÍårHãÔåFªk„½¦vëƒ7yùòå$˜Aê#‘ÈÂÂð�Ÿ²òσajjŠ�‰X‘ë+¸ÉdÒëõ€F2¿õÂîºÿþŽŽŽB¡0;;;66†=›ÍnÛ¶-›ÍF”dfff\.TeO;í´“N: ˆTxßjµê÷û3™ )€K$½^,©‹ J”J¥€ÞÅ«ŠüÄ®]»”JåŽ;B¡6 ¸QµEõÙÙYCJn)¹½¹\ \’WL§ÓØ´µµU«UÐ@À[¸\®ÞÞ^Ô–„BaKKK(zþùç÷ïßF#‘ȶmÛvìØÁãñ²Ù,ΉvAŠ¢�Âů[\\D‘ ’L<L'ð±&‹/fß¾}èid"sɃ&ÈëZ|ëR ך››Û¹sgó8¦nD­V»\.lƒjç!QÂ$[§ÓIþwÙ²eàM¥RD}qIi½êºu%bîÈlãÆù|þž{îyì±ÇŒF£L&{â‰'–žÜ{á…Î=÷Ü .¸€¢¨¯~õ«7ß|365wß}7£¯½öo{{»F£¹öÚks¹ÜÆ)Š:óÌ3Ÿzê)Š¢~ô£=øàƒÏ=÷EQ›7o–Ëåñx¼½½ÝtPÑjµvwwc«ëv»Ÿyæ™k¯½}ôÑGQ†immEs B¡èèè€3ÉþsÎ9øüý×}éK_ ¯½öZŠ¢>õ©O‘"ÖñlÈqutt€kÒ5X>÷¹Ï¥ÓéG}zŒ¯¿þºN§{î¹çþã?þãßþíß(Šzøá‡O?ýôJØGä4 ‡Ã™œœÄ%šëïx ŠÌîƒFHø¼ŸøV­ä9?Y÷YÅX¤MÀfÍÜ„6§þ4Ì--3ˆDIœ5~•JŠUüïòåËišv¹\ÉdÊ@Pz<žr¹ü·¿ýmÅŠ'›ÍÊd²+V¤Óéh4ºoß¾5kÖ¤Óið”cåÂæfïÞ½p~,Öö@ �.óV“(œ`¼…³ …åryhhŒLÈ'ëÙ‰Åb8ÂÚGO>IrY"‘ÅLt¶P(œû÷ïGC£ÕjE(‹Å�8|GFFÜnw<·Ùl~¿ôêÌ݆Z­F<11‡’Íf1Xá,AÚ2ÿ)aÇSK:êr¹fgg[ZZ&&&¬Vk£BsrÖ5­VËãñ‚Áàaí21 ›³D2¥ñHÔÌçøŽìÝ¿\ðgløÂ|0*/…?³®­nsÚ{iCCC|>¿»»ûµâœíرÃår¡'3¯ôYgõnã>ô†]öÊ•+Ÿ|òÉ«®ºªn׸\.O§ÓXìXå‡ìèkÅUYIvä+j ðOáÚÖÖÖ#“º§ieföi~~žxÒPÎÞiJ&x&@²Ùl#Üqkkëøø8ƒÁ€¶F‹Å@.Yv‘vC;Y4Ý»wï²eËÀ'‰D ¦—J¥, ØáȽ­V«"‘ˆÉŒÇ2Œmmmõù|:‘ðR©î-8jI&¶œ–ù»ðDX¢õ¬/šÍæD"a4ÉÄ€×çp8~¿Ù²eHKÂ¥&á®ùùy½^‰D‰HâYObÇ$‘Ë;æñxË–-c¶’ãé/,,ˆD"ò°°“^úŠ!•J‘³m¾¡Éd2Us@zíÌÏd2ÀDóx<<ÙÚÏ49!Hñ}>ß­·Þê\ý©7†æ‘Àôþ·¸'Öµö1$ÇÇÇù|>* Ä&&&ÈäG“}]¿•H$‚Á D"!Õ&²n^7ŸÏ³h7§§§™ë8¡B¡@Ÿ7©¢¦#üQ¯×üp8Œê~þ. ÉÝ@Ü<66¥D’H$@`dd$‹¶\*•êõz•JLè¶··CÓ=CãÜétB¹œø3ŒNM’­ˆnCò»µ£Í¸Ÿ……Dccc<O&“1k„ …ˆ%rBÜ ¾Äãq§R© —Ežòää$óéëõz½^^˜‰‰ •J…oÑ4 A[Š¢|>ñ ™Ljgnn.™L¢› r¹a:_4 —ËEÃ&™3F«Õ²°·xú€93CÀ%‚ÛH ž‰91Xˆ¿T×hšæ ¾Ò¨ŠAN(‰¤5, xĵ‡Nž°Š‘rwsNftÝÔD“KÔöv"eÑèó‰D n+ YDXÒ¥èü&LdµmT@þJ"‘ ¡R©�fët:‘41Ýøø¸P(‹‹‹„Îh4ªÕjЛ¢–£ÕjGGGÇŽ;4˓ɤÑh4›Íår%(„?kßââ"ho8DÓ£Ñ(Ü$Ô"Ð^ÁÎùp8¬zaaäê™w^­V¦Š”,MÓ±X ¥4"Ú³X,…B¡\.·´´€*‘N§3ƒHÔºÉd: ÞB&“M˜™™±ÛíãããðÄñMÓÕjuff†¦i ù¤¬VëΈ<¬£ÄÌ‚`â;,ÚI|ÿ- uã³ÙÙYH¨€ª¸îyÀâñpNããã¬îƃAP(°ãÙþq)ær¹H[5ú�Ra$ˆB9 ºz’Gë ƒ!‘HÔõ¦83KŸµä¢>ŸФ¼a0âñx>Ÿçñx&“ ‹&²svÃçó÷íÛ·bÅ ,+Hg«tåÊ• …Âl6ƒ5¼\.û|¾d2‰Ý=tcá…B¡D"áñxLúj¹\Îãñ@Aä÷ûñ»Ðî4??Ïãñ�YÚw~~¢!ÔÁÒ=³­±ËÅ,ÅÁU«Õj‡Ã1==Íãñæçç+• îÚ*•ŠN§ƒî™Éd¦¦¦�±´� %ÄÁ|>_©T"4\»v-zö¨ƒˆc„æÄ?äär¹Áôô´T*%hYª²gaa¿H$Aê°v6ÂÌÒ4m2™ˆSi4gy5àsE"&Æ1ÉR@÷‹ü…ÙÄHŒ ÁN¥Rñx\uü;'£ÑˆÞÊ“µ¶¶2wv'ì}7NW(XÙpV‹Qs#à¹\.‰XÅa±X¼zõjÄ ‹‹‹µØXf Q>Š´Õh4Õj5“ɰ¾EDH¡ ˆÕ€pÌb~…`KIŠôË¥R)´1ÕÖ‡‡‡»»»Q÷R*•r¹|qqQ¡PhµZ`o CWW—Õj•Édp$<šï šWу®ÕjGFFH tA(SQËé¹\m“\.!Ü$Š"‘ˆB¡`)oq)Š!vŒÒ³z”Ëå€2–H$ƒaÏž=b±LtÔAnxˆûùý~°Æh4 ED‚1gÂÇÆÆà´Äb1Ä=&˜œà ÑÑÚ¤†öÂdÑh;R‹™u»ÝP`bNãÚ9sÈL2u,ƒ:j.NÈzXu)(›cÛGçÔ××w”·æx¶“O>¹6¥;00ÐDâá„ÒÒé4¡ib§­­ RÔA¬þ!ߊݭuNHÊ1%-Œ*•J‹…1cÙjkkÇ« .öûdq!H[¨bׯR # '$r·@¸¬=,ÙÚcð /`éçîÛ·MÞ‘HX.—‡ C>ŸR©Ôf³i4‘H4;;‹$•Óé§œV«õûýhćdMÓ§œrŠßïÇúË!À›dT¤À¶zõêt:}àÀB¡Àãñ”J%Ä2Z[[§¦¦ ‚ˆ¯$ ±KìììÌd2q¤ªàD!„¡V«Ä$“I·ÛÝÑÑ100€ßËÊâ2±¥L‡¡Ñhàx …-“üÿì½g˜de™\ùTÎ9vuu3Ý=3€ YWäSPÄUÐ… ð‡ \ˆ„ D\…ÕEPÖu‘U¼\aw1,(Š0H†‰«««º«º»rÎùûq¼ßáTuMÏ€0`??æê©SçÔ ïyŸ÷ ÷}“šF£aŒòô%‰J¥"17V�i»ÁÀÝétB†£V«Ñ£"r3¹\îàà 8Õj¼'ÌÈá®gŒºìzJ¸ÝÝÝ ‡o+’{2:§þþþ­[·~P§ÑVU§r¹l·ÛѶi'lá`…ö(cÁØÁz{{�¿;äî0¹ˆÅbä¢Ñœ¶sçNôs¹\»Ý^,Ñ«M¯ú‚¿®u„àÝ^¯a•ᮆ‡‡gff \ú¦Î VôF£$=ÐM'g’:tär¹B¡�n·x<‹Å8–°4ÎçóG•ÉdJ¥Òï÷c¦«Õj`J•J¥jµÚãñ¤Ói—ËÇu:Ýââ"cú†ßp»Ý²9xð R©t8¤HÆf³Ó霟Ÿ×ét\.3>(Éàû±nP(•Jþ5NCuûhÝÂëàÆl6v]úé¡á"÷ôô¨Õj¯×KQ”ÃáÀr‡1œŠÅ"”;X,–ËåÿÞòò2ά0èæóù„B¡Íf£™Ã Ëø#­í&òp@[ª6†A"™,õÖûZ‡ßÂ&¹\®T*+• ½Èi´•Ö…ã ‡Ãï™s"¸ŠÎ|?ôY¦sWþûÔöïßßÕÕe2™Z#n°In:˜·cÌÅAÓsaaÍfÕáñxþ†¸‹ÅR,ék[6›Éd†±Ñh ïß¿¿V«=ÿüó:ÎãñX,­VÇ9B¯aF@gýP4ÚHùÚív“QJ!×uLÏÌŽÆãñÆÇÇËå2$\:$—Ë»ºº”Je Ðh4§Ñh€<•J-,,Pe6›9Wm6 ;ÍfsïÞ½Õj•ËåÖj5€·’Éd:N&“§Z­òx<°²âäëõºL&C}Z‹‹‹‹H<òx¼©©©áááÙÙY¸„h4 žo\>Ê? ±Åƒóz½|>ÿèÑ£$oÉb±@9áñxN?ýô-[¶äóy:åU0憆èó&IÛ...¢ÍO¿ƒã'Ë ¼õdZãïW8ž…ÔdooïÌÌLëÓo S.‚lÂ^¤âˆ»N§×kãÆ7q’urÉøÄoÉår•JÅè›À&Â/EŽ6:::99Éç󻺺ŠÅ"Ø R©”ÍfÓëõº“þæÎiuuõž{žöx</½ôÒÆaöÈÙ³íã±æ¦HîÛL#lp5‘\…B ü 8¼ÖV4¼‘µ¡ÃáXXX qC¹\æñx ¢†P:ÍèŽÅbap’* ¡PØ›‚f„z½>22âv»±¯V«‰D˜5„B!Y›w†aÒëÐkÇZŠÅb‡ÒAV«ummÍår¥Ói‰DâóùšÍf©TÌÅãñ¨T*‰DÁžC‡éõúl6‹™sÓÂÂêIÕjµ¿¿eeÅn·{<‡Ã‰D Äü~ÿþýû¡"ÏápÐý‰DªÕêøø¸Ç㙚š‚¾É!µ…ŒËår»Ý¸\.M(õzÊ¥B¡E86› mV³Ù D‡?ãÅœ››£«’;¿oß><ßõòÀjµT~ÂÖï¡oǯP(D"ýéÓ‡"ŸÏÇy’5}Ì@U‹Åb‰dÆ0ÆÀh6›‹ À�Ú^‹ÕjF£…B‡Êd2­¡iKÆ' ç…B!ªÕêÉÉI§Ó >u·ÛÇ[ÁÅï’súö·¿}饗žwÞyW]uÕ÷¿ÿýGyäíÍãñw½k×.>ŸŸJ¥èÚÏãããt†ìp8L‚Љ‰ P AjšÅbÙív Ò-™L<x±éÅ_¤(Š¡ºK6aéa4‡‡‡Ýn7]@"‘ìܹs#3æ&÷íánðû °:Yxž˜Ü-CZ—^1Ec:Æ$ñ^PN¢­5éAДËåÙl–>Ë C³¿ÙlF"ˆÎµ Õ ±XŒEú1a˜tOÉf³q@è*B)9›Í&²Ù,ŸÏG“Z¼ø|~<çñxÉdR«Õ:Q`ŸÑ.Áb±@ wÐ=ཆØ.‡Ãár¹PSœŸŸÖh4{÷îÅ<„ œ%KŠ¢ìv;ÔžB¡P­Vƒ /xÊÁå\4©W{ôèQN‡ªøgÙlv¥RA§ ܹËåj £†H.¤Š3™ÌzØçr¹¼¸¸(—ËAèÞ¡Œ$‹‘#Ÿ!ùõrÈz½~mmá!HÙ‰¾êo!}TqÑ#'�� �IDATc`@΃$-;/Ô6Ò\p1hþ …”¨ÐуY^¯—Î%ÝÁþæÎé´ÓN››››˜˜øéOú65??Çw�äÿôÓOßyçW]uÕÜÜܧ>õ©0N¢H‹ïG"‘ï~÷»{÷îݶmÛÞ½{/ºè¢›nºéw¿ûÝm·Ýöñ+šo~󛄱ªV«=ñÄ >øàõ×_ï½÷²X¬çž{.‰ÜtÓM�p0Néw¿ûÝõ×_ñŇÃát:ýï|ÇëõîÙ³[õ«_õôôlœ¦vÓÞ[[Oîöícbj4Ä3Éd²f³ÙöG²Z©T2Z›@ÕÊçó±êj‡è2`yÛh44M¥RAÔß[ˆ¡ êñx�ÍçóÀâôõõÐðLNN …B—Ë…ÞnäåÐ~äȹ\Þ××2o™LV.— &n…B‘Íf1çb“L&#$x�™íJ¥"ùl6ëv»·nÝêp8ø|>j~™L$Dšé>¤†ð[$™–L&“ɤ^¯ÓÓÓ¨úPœo>Ÿw8cccèÛ|å•W¦§§F#‡Ã©Õjäþ3ôŽs¹ ¨'Cê)‘H@[¨/ ˜‰D¹\^YYé<¨d2®Ëd2‘0¸u ±ãD"±ÁŽ Œj™LF?ã‚1mÜ8 Ç¨Æa-b±XÐnCjh©G—? ý8§+®¸âSŸúÔòò²ÉdúêW¿úvõâ‹/>÷Üs<òÈå—_~àÀo|ã—\rɯ~õ«þþþ»ï¾ûÃþ0ùæÃ?,‰.¸à•JMÛk®¹æ?øÁW\ o½õÖ뮻žºúê«Ï>ûì¡¡¡'Ÿ|2\sÍ5>ŸÁZ …–——×˹Ý}÷Ýçá‡~饗.¾øâßüæ7wß}÷%—\Âb±}ôÑßþö·_øÂ6'ý“ÐÐ4ÌÐ_XOî–¬w4Š¢Î:®s DŒR“N§K¥Rb±¸V«ˆZAi4“Éðù|h/AK¹ÀÔjuooo8.‹˜ïèøGðëèt:èÌjµZrt:@ …BR©ò¸p„hnÆ\Œ¶ˆd2)‹¥Ri¹\–ËåEþt: ¼*¦xzùÿ?ïðx€Ð’‚ ¢IÈþr8xSÇår!5 gÄ(¥R‰¼§ô£iE"‘ÀwÂ]‘XD"‘ ¢´‹Çãd& !Ëáp2™ŒÉd¢(jiiI¯×¿eÒäñPÔAº!Xƒ÷! Õëu’Ÿ¡Õp=f)2´èø:tºsAcf½ñI€±X ‚V‘Ü šÑhÄãhDNDô˜‘7ÃYêt: ¯;”ëÞ çôä“Ožy晉äž{î) ßøÆ7ÞÁƒ'“ÉŸýìgN§µ—_~9â§x@­V_}õÕ·ß~;‹Åzæ™g<xÍ5×èõú›o¾9‹Ý|óÍ‹‹‹»ví:ûì³Y,Ö/~ñ‹—_~ùŸþéŸn¿ýöW_}õ‰'ž ?qå•W²X¬û·k{·Þzë7ÞxóÍ7¯­­MLL\xá…dÓøC.—{m‹ný¦ †ÅÆ5@;·N ¿ñ_ö€JFvÑf³!„ cGt'“õf<ŽÅbøõR©T«ÕFGG=ør ¡NrŒË!•p°þ«Tªd2‰nLy™L†dŠôz=Z0»MOOcñët:årùòò2²‹^¯im¥RY«ÕŠÅ¢X,&ú›‹_t8Ъ@þdt„é+4XJ¥R€‡, ¤uéùs­V›Ïçéz"´EJ“œ�dzÙlH£T,_}õU·Ûít:Yob¿H®ÂNðMV! ÄEåF(* 4ãY,–@  ‘ÿ„h}‡ÁFÐÙôL/ý鯗Åï¶¶5܇Öná®·óo1Z¿Œõ AC#hV©T­Îõoέ÷ÒK/ŒŒ|éK_úñLŸôßÓëõ?þø=÷ÜsÖYg…B¡¯}ík('þøÇ?þ—7æŸ}öÙ»îºë‚ .øÚ×¾·H$:묳††† <Íb±¾þõ¯?þøã'�ûÝ·o›Í>묳¶nÝŠÎ"|~ï½÷F"‘‡zè}1S>|øÊ+¯üßÿýßÎ_ûÞ÷¾wå•W/¯þÉi¥R)‹D¢ßê„õ ¹)BëîîÆ(ØÐ7aÞAµ¦µ‹¶¥i O¡„O�‘!‹ÅÝÝÝCCCýèGÇÇÇ‘ûj»Èr{•ËehŠÃ@] åb±X¡PhµZƒÁ`µZår¹Ïç›››CG&“©×ëÕju~~>ŸÏC½é/`u±<Çãðù|Þb±sP*•ù|¾§§çœsÎ9å”S”JåìììÔÔT:¯n`­Vƒì�EQð=H²1<7à\­VS©R…"‘hË–-b±Ø`0`5€Ò”D")‹à×xýõ×_xá…P(¤R©”Je__Ÿ\.sy^Õj7ùè †ÃáR©„ÖD`ž€=¢?b:3®K,ôÈÆ•‹[‹X©tŸäË…B!•J°T4 ‡Ãmá´Ú­þ ¼ÃtÆf³[Kß=œÓ‰ ´ò“ŸÄÈØµk#¸ÆÞ½{7þ~ã7ž~úi<¤|ä#$xË-·üÃ?üÃM7ÝDÙ%ÉîÝ»+•ÊøCäëÛv:lÄöìÙÃf³wïÞ-—Ë¿ýío“BßÞ½{óùüÛÔ¤×,‰<ýôÓ­j1 Û¿ÿ³Ï>{ÿý÷`â§¶ ÜΆ>¨Ö¹ µ]¬‘Ójµd¯õ|__ßzDæD¸–1)“Œ‡Ã3ºF£éêêj4333ô,%:×Kþ0jQíCCC‰D¢R© –J¥€šÔh4:Ó"È÷À AÚ¾Yoâ~\.×òòòÀÀ@¹\D ×ï÷÷÷÷kµZ¿ß†ˆÆbòªV«ápšR(þW*—Ë…v>$<;œ?ùÐh4V«ÕZ­ÖÛÛë÷ûQ‚ú*"ЄW©T}}}õz}mmM«Õ6 4³ ä*ëõºP(´Z­$Ý §åõzq†z½]ò¬õÛÑh´··×ëõ"*5 çÄÀç’Ñ{mœ;ü7úpêîî‹ÅÓÓÓ$&Óétõz}½D·ÙlV«Õ‹‹‹v»}~~4W­M°';+ùÃ?üØc=öØc×]w]ëÖ•••ÑÑѯ}íkm÷=pà�ªJwÜqÇ!VçöÍo~sttÑg,}Ó~ô£Ñ¿6::zÙe—½øâ‹£££o³ýòom:®ƒ„¼V«eDNR©t||||||½½Pc'ÿݺu+œ:ZÆÛN—µZ- “¬³¯¯äom·áÚëâÅÅE”RÀ&.‰d2Ùøøøàà b2Ljá:$p|>_<?tè2u¡Põ06aâæñx˜bpg ú€-è|ÆÇǵZ-‡ÃYXXXZZ¢(ª»»sÅbqvvö·¿ý-¨Œb±T °©Ñh@g+‘Høý~Ð åóù¹¹9ƒÁÀ ²5›ÍŒ\"‘ v\[[‰D~¿nn.Nïܹ³X,Bñ½\. …ÂJ¥Òßß›f0æçç9ÑÏEêyE•JEQT8ƒ-^òˆs¹œN§3›ÍäÜÖnwuuA†±a€%,‹¤¢õ䥥¥§ ×Új.3 •­!> ßèã3‘HÀC÷÷÷C d``€¾{<7º@[Û•ÿæÎI&“}îsŸ{õÕWGFFŽ‹‰ ;«ÕjµZ5H$‰DÙlIv0e³ÙµµµX,†î <æžžžSO=d$\.·\.£ µ^¯oß¾}ûöíÆÆY,Ö'>ñ Ô-7xVwÞy§N§{íµ×p±X,N£*Îb±¾üå/ÿõ¯}ýõ×ß_ô€?úÑ\.×ÈÈÈYg ‡††Ôjõ¡C‡n¼ñÆ;.™¸²²²gÏž'žxâ«_ýêí·ßþøãŸl×BQT?IDüY‚:äÕÕÕt:M¯Êær¹Ã‡>|˜a} iGmó·ëé{q¹\Fœêt:‰n…P(lE8T*èM´n"¹G¿ßÿâ‹/b">xðàìììž={: P$ •¸ëzsÐøø8NcllÌ`0hµZÔ–|>_¥RÙ¶mÛöíÛ!(¾°°ÐÓÓ‘ññq@>½^/|›ÍFÙfdd„ŸG£QLÙp ù|~ïÞ½„¹z çææÄbq£ÑÀ<€€Çã!ˆ]°ƒ³Ùl¨NTl¹\^ZZB²ê%À  ¹\.D±1õ ¹Ýîd2¹¶¶†V—ËEQ‘-N&“+++ôj%+Áh4Úl6ŸÏ—Éd†††ø|þ¶mÛFFFŒF#†"±©©)z¤Î|jj ÀX´Ar8œååe”¬70Þ¾%‰cþ|>YlAuµ+<,ÐJµðà㤣Á ULçl›i|7pNÕjõÖ[o5›Í¤ÇúÄìóŸÿ|¡PøùÏþóŸÿœ¢¨çŸ^&“¡™’¬?ùÉO�?îííU(b±xddä7ÞÀV‹õ‹_üâ•W^¹à‚ ðÉm·Ýö¥/}‰ÅbÙl¶ÜhìÅ ¢/9õzýÀÀ€H$zî¹çÈÑ®¿þú[n¹uxx¸ƒ&ÐÉi×]wÝg?ûÙ§Ÿ~£ªV«•J¥¹¹9n2nÃÃÃ<òÈþç¶n: (™Ö™¼jŒÕO2™¤¯KZ‡ãr¹è¤( <Öl6»»»ûxyëõ:úÐ÷U©T|>ŸÏçÛ¶mÛ¡C‡P‡þ)}¯þþþJ¥ÂÀ]²Þ*¹ ©õL&³oß>Ò£e6›S©”Õj% y,Þé3p  g³Ùàƒ˜žž€ $!Ááp„Ba¡P\]]é-â�àX% ¨¸»ººèy-:¼Œpƒ‚+Ï`0,---GŸÏGrqV«à$,Õ»ºº€´]]] ƒÅbQ¡P€}µT*) «Õ:;; {‡Ããñ\.W0t¹\`‚°Z­pN XD–J%¹\¾}ûöb±¸´´‡¶nÝ:== FöR©„à)™L‚È•.ä pZx¸ømâŒe#ýc·ÛG+‹Îðz½~Ôáp¬¬¬ =}#+¡¿…ÑÏ™@wµZm½^ï\‚ÂŽ ég£Ñ˜Ífõz=c¾5§xà:Ôµ×^ËèÛ²eËË/¿ÌøÚþðüѺ©í‡?øÁÈßããã­_øÓŸþDÿï 7Üpà 7àïçž{Žñå»ï¾ûî»ïþ�dù‚Á .äüóϧ—²O~k §mÖY4‘§5nú'ÔaFcaaA*•’ßjTv0±X, IÏ“K¥R1Vܬvr·f³±;&Ï>ûloo/”¢ªÕjooïôôtooo2™$É¢ÖÊéÚX^^N§ÓèÊÓëõ@@¡P‚h4J—âîÜqñx\&“ƒA¹\^¯×­V+¹]Ñh”¢(½^ïñxäryµZ% pBr8;;Ëår =9˜œNçÜÜœÇãÙ¹sg½^õÕWÉ©b‚v»Ýz½Qs“É$€SCCC««« …Jí+++6›-N›L¦\.‡ÞwŠ¢°lW(z½>‹ÍÍͱX¬}ûöAýÏb±@JJ¥R¥R)³Ù‡c±˜Ýn‡R0‡ÃÉçóR©´V«)•JäoÌf3EQ…BA©T"E™ÉdŽ—�'�9f@àõzщEa¯°X,¡PèoÃÛ tLÒqdÜg½ñE*ÊKtŸµÑû¬æ´iï¡uwwÿ÷ÿ÷}÷ÝwñÅ3”¨‰!Ú8 ÙǵKkUÊm¿¼¶¶«EýS*•2Ôie-µZMRjÐÏ]/3)•J‰t)ar“H$Œ°~qqm¨˜Àô]­V‰–p mEH‰Åãñ¹¹¹¹¹9PD»Ýî`0ÏîA“ÉDîb»F£Âr`ZÕjukÞ^&“!0âñx=== bzÖ¢±ˆZr¹ä*F4m[öGŒÂHÀÂÓˆD"‡c2™ æÞt»ÝžN§±Þ·Z­"‘¾ýýý¥RI©TâZ@`Ñh4l6›R©L§ÓèÔÐh4 À][[ËçóJ¥R§Ói4@@ÜÏÚÚAÏÍÍŽÖápX­Öcj×"ªÑh Õ+‹éÂÊÈ£¯ªòÆm=‘\±XLÊJ¥²m6X.—ý°~a[ç¦¤þú׿~à:”J¥†‡‡y³×^{mjj ¼™'Õ™›L¦ â<Ï`00˜[YípŽÐîdôà~n21 »tgT �C­?ÔAÕíÝ(¢²©u´´e2L^™L†€v%�¥‹Êp¦a˜†"†¢(ƒÁ ‘H@ø >ƒÁ€–9‡CZ­SL("Ș@ @‰R©”H$ ËÃIF£Q¡PHVßä×WVVZ×F£1 ­®®ŠD"(Ûâ¹³Ùì¡¡¡ÞÞÞíÛ· …ÅÅEˆA Û÷P(R…νþþ~°›/--‰Åb1(ŠH$R¯×N§Õj•J¥ÃÃÃÏ?ÿ<Pº�-Q¶oô¶Þ@°0H$’­[·‚6bÿþý$råñxJ¥2‹‘áÕÝZ­‡NkÖ‰›Íæz½àö ˆäÓ m‘¶ïK£ÑÀ˜iË,N"!<ò¡R©d`ž„B¡H$j{†D"ù}àœ>J¸ápøäTÂ|àPÿâ¿xÞyç)Š;î¸Ãår±X¬sÏ= lW]uÕùçŸéÏd2]qÅÏ=÷ÜÄÄv<y¬V«Õjµõp‹(h·¾‡Ç̽lgX;Ãòù<ǃº+I–’3Y/‚þ%FаÓõXœÑýÇl6›M$mŠÔq-+++Euuu¡]Y/ÒªŽ¼D߫ժßïçóùV«Ïb±¸¼¼ –#rC@‹Çè%!ÿ¥ê#ú× \˸(§Ó‰pÐf³år9(á„KŽÓh4�N‚×Ó„ÓéŒÇã>ŸÕ,Š¢p-ƒƒƒ¨”X­VˆiÇ}tt~4+ 8ŒSO=µ¯¯/‘H$“I§Ó™Ïç±ò�À¹\.cÌЗ#t±c>Ÿ¯T*3™LWWýÚ‘ Ãz… �RÁ:Þu>uXõ;®×•žÉdŒF£ÕjÍd2^¯·C¾šñN1оÈw& DàdwNƒá}×PpLëíííÐÖüšÍf»úê«ñ÷\@>'¶nb±Xv»ñ…“Ä�L$h§fäÍ€šÜÈq‚Á`kxõÉdJ§Óë±ÑÐÝd8¤Ù‚§8,b8,çéœxëý h%‹P¢4ʘßѦ{­­­ˆ~:c/z8%•Jqß*•J<—Ëå …Âï÷#¸ÁJuuÕjµ²húR8¥z½n0°DXåº-­u«¥Ói¡Ph0ÇÒÒêRÙl–DårY$I$’t:Íf“ÉäÀÀ@4•Éd ÄæH)8 £Ñ¨T* úY�ÖQ©Tjµznn®¿¿_.—c¢DœT­V³Ù¬\.gÈ·šÅbáp8R©tuu¸ìx<Žþûååe²:Õ,"0¢žŒ*c£Ñðù|­uPHc4 À¢ÉúÆl6CHO_(‚è¸Þ—Ö5Aë ô]]]‹‹‹ë9QÆï2ž/^I@çás�ã0Ò@'sêêêb³Ù¤Éûf'¼ºÙ´ã2¨øýþ¶É+z£ÑX*•Hnª§§‡4M`Ú !€–6³§KëÆb1²öÄÒ[¡P4›M©TJש6#9™J¥Ð(•J¥$I(²Ùlñx¼ƒ"G(Z,4 ÁÓt:=<<Ìf³‘H¥R.—›Ëå0AÈåräӞ¹ǚESÝE¹èØ„–¾€j$Á¿ôŸÏ·ÛítÙ$‡ÃD\6›Õh4‡b³Ùà_À&úKâÜa‡Ãa6›ê%È0¥R‰xN*•ŠD"T•À›^©TàÉ@ž„Êt#Åb1ZÑ2™ŒD"‰ÅbEiµÚ¥¥¥••ÆÓGop<7›Í™L “333Ùl:ÈårÙjµ&“IpSµª'Ëd2\r+ÎÇo›ÔŸŸ_ZZ"s:XM&S¡PXoY°@{cUT.—‡††ÐÍOÿ¾Ëå‰DtnÛ¸ KŠl6 Ål6 Ù\¾\.g¸I®}`Â9°%›/Qb¿Mƒ“÷ЀØj~p݃DÙ³ã¥*xíÊ+¯¼ì²Ë:T×ß} ƒB¡Ðh4NMM=ýôÓårs.ý®‚Ú¹V«¡¹¨X,BûË[Ðx“å$Ñõ¡'ý…ŒÛ‰¥é²7•J¥P(äóyr’M"‘H¡P$ t<“<œD©TÂÕ §Ó !|A£Ñ¨T*…BÑ…9T h4ôa—J%r]¥RéÌ3Ï´X,€ \ ‹ÅÂ’Ÿ´`Õëu:ƒg³ÙP"‘€¾™ÁЇÕjµËåêïï37*O}}}P© 7bÓðð0Øl1ÉV«U¤ÚÀû×ÓÓ «ÉdÚ²eK  göÈßÙlviiÉï÷s8œP(d2™ÐR!—ËÑE‚¶o£ÑxÚi§ ¢ë²^¯ÿþ÷¿…Bh¦p8F£Q¯×«Tªjµ :"¹\>77—ËåèOŸÃá ¡ž&›ÍÂ1X­VÄ7äôpQôaC?óT*…Æwúh!O?"Dzb ltCdwCW&“!ÖGV­V;/­ìv{kV¼¿¿?'‰T*ÅXaçr¹D"144D_sØl620FGGÉ&@T+• ÛÌ»víRš{±l¹˜OGVN:çô÷cï_ç$—ËO*ÏÔêœ N’-� Xò!þ@ŠþnÓcÜV÷s/‹<~ˆ‘ /—ËÈiÔ¥I*ßd2I$­V ”=(äóù«««ôº&#£Ñ¶áááz½~ê©§ž~ú郃ƒr¹<ÌÍÍ…(zÁ} ÓŽùŽÌ2`Ç–ËåúŒV­VM&“ÃáÐh4EƒÁz½^.—C¡2Z…BÁår9Nh½Ûív°êÑ„ÑhÿáÈÈH¡P@ûr<w8Èn¡.m`` —Ëy<žX,~€=M&‡Ã9zô(ý‡cëÖ­}}}ª4ÍÌÌL¿Åb³Ûí ¾…×Ñëõðp˜$'&&ÖÖÖÒétww7@‹¥¯¯Ñ½5Àd2íÔa@é9—Ë•J¥~á–§ö÷÷“ÔcÕÂr¬·"“èTàaê<hÊ 0°äÕëuú+€žP¤õÈ’%ŠÅb‡ÃQ Ÿ˜6yÆÙgŸMwN›Ýz'…½Í0|Ó�½l»‰tÖ3Ö¡£Yß)OÚFÐT*ñxÜjµ¢SŽÌþ §ÏnB¡Ù6T¹ˆŽë­èש©©SO=U,[,‹Å’Íf‡@ p»Ý�ãCµZüó£Åbôx<“““‘J?I’‹Åv»}aaÏ磢ö§?ý©Z­b/ð*!¸²²âóùÐ`Ò–œ *4—+ Š¢c—^z‰Ífwuuy<žT*˜0P½{÷îÅÏãñVWW¡8üÆo 8ƒ`±F£I$‰$ƒ9 \º:r¹Üh4æóyF£V«!ù8==-Ю ü(éaC÷ þf(ã‰ðx<¢_Å¢A°Y,V__Ÿ×ëe³ÙÅbquuüîô¼Ç£+µwèGehÚâ¢Èój°àñxŒbOÛ7…ñ!: vLž>‘nÝ·P(d @¸™L¦···ƒðàûÛ9‹ÅW^y…þɶmÛæçç‹Åâ¹çž{¼G«×ë/¼ð‚J¥Ú¾}ûF¾ÿÆo$“ÉsÏ=—Ñu¿»¼¼L‹›vö6;h€Œ9Þ§�Xâz1ÖËÇ…šl= æ>k·µè Ü(�ª*•J¥R-//óùü¶§W(4M(âóù¹\äâ\.—Ïç´,ZïÀ*´ººJ|¼J¥’ËåB öq²/•JÁ`P¯×—Ëå}ûöét:lâr¹F£ZMƒ`ØX,V*•È&(¨¶–¹\n<G¸*à0Ù¡Q>›Í* Üõµ5è9Ùívp:ÌÍÍŽŽ¢bjjjyyY³ÙT©T¸@‡“ÍfAe‹­H¬V«mDäÇãñЛ€pzzôçÏçóV«Äí8%°è*•JP’K ØHB´)J¥’PÅ3ž~¡P@=²»¬·ÊÝâÂy<6ñù|N·ÞòH(B"™h.o|Õ%èbÇF¿Ewœmñ¹d,u–Ä};§p8|饗:Ž]»v±X¬W_}õcûØÿüÏÿ¤Óé v3êÿ÷ÿ×ÓÓ³Açt×]wíÝ»wuuõmN‹Õjµ»»›(,lÚßÎØl¶Z­nK¸BW§Ý¸A •Ïç‹D"†`³Ù …bƒ¼Ñ¨£O »`íßêØÀ°×:‰‹EÂmCš0k·.„“É$ˆŽ>Œh`vvV  ìÔÓÓsèÐ!dlB¡D"A;&J™LF<TûúÓ Z¼J\¤F­ >Ÿ,D% ÞT«Õ–––$‰H$j½.T\ГÏç tEÒàEaúÓëõH=‚GÏ�� �IDAT=i4 ŽQK$èDÏårÑhT"‘”Ëe·Û­P(ŠÅ¢×ëÇãˆ6HY1 ¢ÓH¬¹¹¹jµZ©Tär¹Ýn_[[«ÕjÝÝÝ'F‡‚P(T«Õ¥R `ǃök, w…ÿ¹[zË"– ¤‡ ²‡è¤hûôÍf3À�«««õz!wk6›C¡@ @Á¯CàžÏçqáÙˆsâñxR©”Þîp8Ün7Úí!isP*•¹\Ž¢¨cv¥~@œl||üC×^{íÃ?ŒüL*•úÉO~200pÑEýå/yýõ×/»ì2»Ý^­Vÿõ_ÿÕf³]~ùåo¼ñ¡û»úê«¥R©Ífƒ0}Ó—¾ô%(.?úè£øäœsÎÙ Û´÷Ä1ð€*•ªP(à=_ôaƒ&•J &wÖ›XKd3Z½ÝƳyH†Øl6ä²Xo2 àoNG´…Úâèá#i+ SŸÏW(±XŒHÂcéŠYµ:µZF1OƒA£Ñ q¹\.EQ �0t‘o°*CF¶R©0®jµZŠ¢°öÇ|‡¦íd2IV�|>Ÿ¢(‚‘"³¤J¥*‹ô´!‚- yÑ¢hq±jµš¢(Я­­‹ÅT*¥V«ÁbŽƒs8ñG0äp8^¯W«ÕJ¥R6›N§ÁgÇÓé4&‹ÅâÊÊ ¸àÐØÛÛKQÔòò2›ÍÆ"qªV«Iõ¨R©´•H&T(Òóùdp®m|dÝQ¶aÑänI}¨R©�á»A[OJ¥R1$1Á·KÿbÙIu‹Å*ÛVòåNÉŒäôT­V¿óï¤Óé»îºë·¿ýí /¼pß}÷a¹W­Vï»ï¾Çüðá÷ß~ûää¤F£yòÉ'o¹å–l6{ß}÷ýâ¿8tèÐ7¾ñ lzâ‰'n¹å–L&sË-·<ùä“frròöÛo?|øð¦89Ín·3 ‚¤Ý Ùl®ÎmkF£‘¼‡b±xëÖ­88#MQ.—[£1‡ÐFŒ ‘(‡^†Ü8B³mËáh`°ôBõ\©TÆãqP%áó`0HgHÊd2@�‘>Éd2Fƒ>@ø¤+àx<Ô.Å´…Žó‹Åbhºãñx‚VVëÅæóùD"Ááp—&‰l6›\.W*•‰D'i³ÙjµšÏ烯Íçó\.×ï÷+•JÄ‚óóó±XluuÕëõNNNÂiB ‘H<š'Á•‡NR3 …èæ 7.âžÈår§Ó‰GúSkµ———10ZI“C¡3m)•)Š!E4]^^†´ÕzÃ) ž°è-½èÀ¸"nIÏ`uîç‚ Ä®þ¾œÓ¾}û®¸âŠ+®¸â•W^ùú׿(ÜG>ò‘ /¼ÐçóíÛ·ï3ŸùÌgœqß}÷­­­Ýpà F£ñŽ;îðz½ûöíóx<=ôÐ'?ùIâÕ½^ï믿¾cÇŽ«®ºêá‡þÄ'>AQÔ'?ùɇz誫®:å”SöíÛ·Y":i®4C>9f‡R[ƒ2y'Ñóf±XÚ&rQé¡»„g0È|Ýv6A¶ ]Äôz}+U]$—î„0)�D_ð‚G§R©¬®®"Qc·Ûy<cx ©TŠâ Ý7ðx<¿ß¿²²b6›é‹blŠÅbô¬~‹~X‡Ã.Dupn™LF«Õö÷÷Ñ¿œËåÁcÖj5´„‘0 á°P±X ‚¹~¿Ÿ¢(ŸÏW­V<ˆKàñxétZ"‘ ‹ Œ…`nÿÅÜÜŠÊ(¿Á8N t¡ŒÖmF(GA ·V«±ÙlFƒI¹u­€ÑмF‡…Ífc­ÃèS,óù<C”‹Ãá€z¦Us¹ƒq¹ÜÖoÑ”ÅbA=™þ ¨%ZSÜk„´^__ß7ÞHþ~ê©§‰ÄÙgŸýÚk¯áËÅòä“Oær¹çŸ^«Õîܹ3™LþùÏþ÷ÿ÷n¸A­V?öØcmCÎ;wâÑÑÑ/~ñ‹¬·²°lÚIhëQ¤@~ô¸Zö}>™ «ÕêÂÂÒmq¯ôwÒ¥'Ð yò¶ÊŒVÝt:ýNÁÊå2½ë·§§Çãñà_rKëõº\.…B<mr(Á냌޾ / ¢zJ“éÚÚ—Ë…Ø]"‘( ‹Î’Þg …¿ÂMh6›óóó­wØår¡Ì^©Td2YµZ•Éd‹ì ÕjÕãñ¸Ýn­V‹N¼f³‡Ëå²Z­Öét|>ŸÍfg³Y©TŠ$Ûo¼Q*• ½ËårѦo³ÙÖÖÖè+ °Ç»7FÛ"s�•H$jµšžøEÞZ­^Ây?¡PH º»»FW@¸|èFƒAžb·Ûc±Ø1yOˆ­'w[(Øl¶ÙlÎårpHx%É‹I6užK?‘“J¥Úö¦­G{üÏÿüÏ;vì¸è¢‹�¸#{ÝÿýCCC8ÿüó;, ¹Îårö³Ÿ]~ùå›àýhKKK¤è‰ª)c¡JO­T«U”ÚÖA“ƒà MÒ'–E!í­ƒáQl6ÛqÎŒF#VÖ <Å2ÐþÅbätGR.—kµÚüü|µZÅ&…Ba2™4 ÖÈÅbqdd„~+èž)€Åœ>uº\.¿ß–#·Ûív»e2Ù…^ˆzO.—£;¹\><<|úé§#©åõz[åÏ{zzD"›Í®ÕjÐ÷ãóùf³ƒååeŠ¢¼^¯P(„Èää$€_À2#q‡õ‡ÏçCÛÂÂÂV «ÀQ«Õ °DŸ‚vîÜ9>>Næ@è°ÈÐëõ8ó¡¡!8]´]€ ¬„êõº×ëeÔûúú&&&Pó+‹@�?ít:Ø!—ÛÛÛ 8ùڻ韬­­á§y<Ô“622B'–$r·­/B¥R‰D"dFe¼\dcH�Ó˜Á`ˆÇãÍf‰ïßÿþ÷‡ã‘Gù—ù—;vÐS·P+@oÏG?úѾ¾>0¾ ¨+•JÅb1AGnÚÉf뱤W«Uºt)æ§§Ìë02›H¥R§ÓÙú6›Mbn"iŠ\PÛndÖ É42sÑ‹ôJø|>«ÕÚVé Í«ÎáD£QT æçç+• ijé#U™C‡”ÓÓÓÓzbè@ËŸ!íÎ …Âíð@@ ŸÏ÷÷÷Óo‹ÅZ\\4›Í»ví‰D.—K¯×÷÷÷ãdúûûÏ;ï<Š¢§0ÇS(kkkÙl=D^V§ÓMLLœrÊ)€+<xs(‡ÃI$GŽAy.—›šš’H$Û¶móz½:n||<•JíÛ·¯P(ðùüýû÷OMMÙl6­V –ôB¡�þ½z½n~È´“ç‹Éd§œrʇ>ô¡ÓO?ý¬³Î:ï¼óõÅøÈ‘#8óÙÙY„˜‰ìS¨VöõõŽŽâÒd2}¤¹ÝîC‡6y^>ŸŒ'ˆÛH´mµZi«d±uëÖ3Î8£µ¥‹0_Ôj5z“·Íf›˜˜H$ Êcz9 'ßv³Þ*Œã7õä˜? ÎI ŒŽŽ’7,4°ˆ“H$£££È°X¬Ÿýìg.—‹¬>ö±ÝÿýÏ<ó̧?ýéB¡°gϹ\>::êr¹vïÞýÀ<óÌ3—\rI>Ÿþùçõzýž={ …Â%—\Âçóo»í¶Ÿþô§¥Rittôm ™lÚ;n¤ánàŸîPn4333­¢;333xs¹\ëjõ¦ò�(+++$ËQ¯× j²­–Z‡´þ‡ÃŒÄ EQ6› 2zød~~¾\.ƒŽ²ƒ[ …†¼ dŽ shà tÔl6{zzHPð,‹Åêêê‚wÎ^(B(ɾÊår$¹¸¸˜ÏçÅbñää¤D"a¨ŒÏÎÎþå/q8@Àd28pàü#ZÌAçQ.—ñD od6›€Æõz½‰D.—£/<—Ëa¦k4t»ÝƒaÛ¶m[¶l±Z­çž{îgœqöÙgïØ±# ÁÃÁàýe³Ù.—+—ËÍÌ̾ PÉd2—Ë…žxz\ÒÝÝ’F£ÁápŒF£J¥’J¥ l6›T%³Ùl$v¶D"Aø¢|>©SºÝîƒâPÕj•1Ò6Þ×ÀçóÃá0¸§¦¦á»@ H$[¶lŠUÛ#0ŸÏƒÌçó“““ë 6a¤‘0Þ.Ø:>1œ: Ý÷wÍÉl6¿ôÒKŒþóŸ“4}ëòù<]¸öÒK/½ôÒKéû’ï_vÙe—]v#!K?Úõ×_¿éÞG¦Óé"‘H+vñêõúÿõ 6^¯W.—Ó5m†lOkvžar¹<›ÍòY¡Pˆ 9½°ð5,¿àó8ŽB¡ðù|€¬Âñnp¬‡¸‚ã‰D³Ã‡Á`ÄÞ,K­V×jµh4J€@«ÕF"±X<44ìñsr¹\¥R‘– ™Lf4r¹\+èR£ÑÌÎÎ …Â`0ˆR t×ÖÖªÕªÛív8ÉdR,g³Yǃ;Ìf³!”%—Ëù|~*•âp8d¯T*Ñ=¿ºº‰DF0T(è …Býýý±X däPI¥R±X ý¡P¨\.‹Eð´ …étºT*AúP(400àñxjµÚâââàà Úôá´”JåÔÔT¡PÐjµ8Ò& QÜŸÖn‡AZ.—¦˜‰ m×3 ÖÃ*•Êjµ‚•c=�,È)ˆ’ËåFcƒ]v|>_«ÕêD×<âr¹ƒ‘¯Æp7ÛTöß }Ñ+¯¼rÓM7mß¾ýmÂ\6í}jU*•Ö· Ñc.];k@Ó-‘„½}«Õ9á;Û·o÷ù|n·[*•¢æ©D9|>h8',f;\>DH‘îåAµZ5'N†Ìª*• 5±X‰Dt:Á`îêê*‹€a>%W¡P(€SnCËå²T*E²½T*E£Qä0á„�hEu©úüØl6A™è.¦x¥R‰†@•JEQÔÔÔ”ÑhÔh4Õj5 *•JµZ}øða‡ÃFŸz½ŽT¡Z­öù|DÒÀ4P$ zMN(‚—&‘HÀ _~ùe�ŠA\6ÈŠŠÅ¢L&#ÄêëÁ½AªD!BØr¹ ”^½^çp8t¤mÛô@¥Réð`|>_Uu:=<‹Åj‹X_/@—H$my•€³n»W‡M/Î)‘H\|ñÅ×\sÍ1Å’7mÓ0õ ¹dk ç¤V«óù|ç8ŒX+Örƒ´µíÏç[,øK©TŠúR Ò–Ìt¨K×ëõ<l|>sŸL&ý ’cmgO‹Å’Ïçëõ:ü «ÙlÕo«Õ ((ê"r¹ß\[[CÓˆõ0ÙVÌçóI¥ŠÃá V@‘œœI¹\F5E¡PÔj5­V›N§·Y,,êäñx<£Ñdq±XÔh4xRÅb±P( MœÏçC—\>~ J¥Òáp€Û;4›M"’N§ …Åb!û΂åÅb Q5;;‹Ù¿T*uww;Š¢‰D(Â1[‡‚`§R©¢Ñ(yú$Å/KÆ'(Éî¡3•ŸÏG?^"‘À9´•cær¹‡#“ɬ‡Ìíp|²ø KÀœ˜ý½ÔK>þñßvÛm¯›¶iÇôLx»½i]c—n)]¡³Y­ÖÖ±^¯'+ªf³‰tH]± rÞ“!ê!‰Ú"`ˆ.0Â=Üé„Öh4b±xmm 5p(Åãñp8ìv»÷ìÙ377çóùèg‚câ€�ç"çƒbФƒ7 tE ·€øAr ä µZÍl67›M›ÍV­VA󃄆t�r¹\Ô]PÁÂ1ƒÁ Ãáðûýz½)‰@£ w '“J¥ Ð(‹9ŽÃá Øa(’ Ã‘e¥RYZZ* `£p:©TÊãñÐÇ ˆÇÆÆp9tt¶B¡@¾±ÙlBŠg"•JÛª¿ÓUë<&t4Íår‘H„tU´… £!žþ¹^¯?fßM£Ñ ^¿-‚¸Õí§ÎiÓþM©Tnœ£‘ý ¬ôù½¿¿Süq¡z!¿´‘o¶í‚H kRä@öíÛ·°°�f­V‹Åb½½½Ð²“Ëåp�¤ßÐ]èå´Mª€Ÿ”Ï%þ IB4U#t¹\ÀÜ€ÓonnN«Õ&“I‡Ã -7Ä¥Ri¿F£!z àÛÆ&ˆD¨T*‰DJÀL&# ûûû‘²-Y2™DØ Á1aµZÑ/.“Éb±b©z½.•JÓé´H$š˜˜8ýôÓûûû3™ ”j±øðù|z½Þl6÷ôô$ ©T*“É©¶·ÙlBÕžäÍpÇär9rªõz=™L¢–S,QB=Œ\;ØÿÀUFº|ÄGˆ&r­V+—ËF$Ñ1ÝÄ€´%JHd%Aùz¦V«[X©T2™ŒZ­¦ã£ÆÊÊ =œB^±õ˜@g·~žÏçÛ’liµZ:ùHgWzÒ¥õ–––:ôû~�Œ`56íomè ÛÈ7øÜ¶L@†’yÊét®­­9Nºf(Ý|>ŸÙlnÛã×ÖÚ¾«` 'çù;²‰dQPßÅ}÷P(ö¼õ2û°V@e½^Åb¨Ï3|”™ û„Z½ÃáXYYéííůPeµZ›Í&9 ‡ÃÑjµHë¡i ›B¡J) ¨€6 bÒé4‡Ã/ý^¯G\‚žL‘HÄçóÁÃÔÕÕ•Éd�e‰DÈVY­V¤UÙlöÜÜÜØØc±ª\\.w~~Þétžyæ™àR*•J`¼•Éd@"H�ixéîîÖëõétšË`N*•J¹HØ ¤m$Y[[[^^ŽD"px ®Íf+‹t‰d!0݈EZ‘¶\.×étBW¥C ·_  ; õVW@goü•Ìd2‡€pßgΩX,:έ[·~PgÌãÊmÚÛ±D"±Á.£¥¥¥z½NQ”Ãá�q5ã%Ç&ÒGÇb±VVVúúúÕcºažê0YÐÍét"å²ÞK1<<LÊ žššB ljÁ|>Ïf³§ÑßßïóùèÁ_Û– ˆQñ$Ü“““Àá2Ê ~¿×®]/¿ü2Çs¹\Ùl6£ì”N§GGGà]^^v»Ý&“‰�žpzóóó¸Wl6Ûb±õ)>Ÿ?::šJ¥–––P¬êéélH"‘ôõõÅãq4𝬬�¬Z©TŽ9‚ÄW$ŒD"ƒ¡««ëÀÃÃÃ|>ßårÆr¹,‰€À=pà€Ãá�7|¡PËå hì>zôè)§œR(6 •J:t(›Íb­`µZ}>ŸÅb1 pEŒŒ�6;33ãp8è¹2€pñ7 uäá¶ÒÙÑ1Ýć‘1344477‡Ž‰cl=\&!é2<¯··wuuÂ+ëÐh4Bø¸íV›ÍµÆ >~#I¿“±!B  ®’½þúëN§ºà›žã]° r4å fXom ê¿§§‡.õ†Wñ ‹Å²Z­¨6“¹�o"‘ˆÞYË0.—»¼¼Üùl[ ë÷D"133Ããñ.¸à‚•••H$Ø™2FGG'''É—]ke«íú-ˆ]]]`>…ƒYï £Ñ(„Ñ.Æ‹599Éb±c¾k6›»=tèëMz‚ÉÉÉîîîÉÉɃ"}ät:½^/¸Ì ÖétºX,"y  …BqÆg”ËåB¡ …ffffffvîÜi±X2™ŒÝn/‹è×÷ûý[¶l ¾ÏçW«ÕR© …@ Ž×l6»ÿ~äîàæ÷íÛGîg2™Ä€Ã,Z3†††Ž=:33ƒ,k­V[^^ÆMÆÁ/´ œ+ݯ€lá)‰Èq{7>àFúñº»»Ãá0ˆ·¶YÂoak[Á\¼/l6»mƒ¨V«u:~¿#$p›J¸ïªmÆL'¡'Þz‡™Ý7@�©í„Ò6N:f¹^¯G)ûx¥x½^¯Ëå —CˆMNNÒµPív{:^ZZâóùÖb±˜äñVWW±;)8AµÕ|gpptás¹\N´ t•è4ÞäÖëuV"‘  E¦6tH...ÒkW\.W(z<žÞÞ^(N‰Åb™LÆápÜn7Än ƒËå’J¥ “ …蘀x‡L&+ z½NH,‡B!ðYd2«Õ ÉÝR©466&ÇFƒ¢(8!@@QT±XÄ Ü²eËÌÌ î-ZÉ1ËcÀd³Y’LëêêŠD"™L†ø‹… ?iŠ£ßö¶Ó79`‡A¸k;Ò6BfÍ hkÀ™%“ÉÖ0•JƒÁjµJQTµZíìMßUçT*•^zé%½^Oø†8ÇÏ9çœ âç;ØÂ‚ÏçÛ¾}»Z­~á…ðØŒF#VX“““$ˆ‹ÅÃÃÃû÷ï§ï~ÆgÐiÊ–——I“ë‡>ô!±XœÏç_}õU’*â•W^Á`R«Õ› OïSk­ AÚ‡áTx<*ÛJ¥²T*mPEp#FF¦ÉdZZZ:®õïââ¢\.Ïçó„nŽŽŽ‚&,] Ä f³Y ÌÏÏÃg WA¯d˜Ífà{ô,À€M+++6› €V|ÿèÑ£.— 94¿anE¡(Âeð[(À¸*•J———].—×ë÷ø{ Ÿ¡Õj> Ý<DBv»˜\´§#§ç÷û …Êòr¹<‹ÕëuµZ ´,éˆB$ EQårÔA赫V«'•Jy½ÞD"! ÌÄf³½^/Äý:[¡P�¦ªÕj�}¹ôô/†“R©”H$R©4ŸÏ£MÉѫ %i‹h6›Dˆ�!à‰ 9“É à¿Q:eÎD"ÁÈTK¥ÒR©”H$úûûWWW;7 ½«Î)^vÙe]t!q¸ï¾û^xá…ÅÅÅ·Ù#0;;{Çw<ÿüó¿ùÍoR©ÔW¾ò•O|â`ùÎw¾sÊ)§<üðÃO>ùäÅ_ ê“ÉôÌ3Ï`ß—_~Ùçó½þúë„[ÅçóÝsÏ=+++CCCüã¿üå/_wÝu<òÈ£>úáxzzÚn·ßyçóóó_ùÊW.¸à‚|>?33ó½ï}ïCúÐæ\ÿ0FZO«Õ¢5@"‘äóùõh :ÈlÚöËÉd2øÂx<~b:,` .V£ÑÔëõP(¤R©¹@6› …ÐÜC»=Rt—8'Fãõz‰%h2Àiµ¶ò4gqi•JÅãñX,6›J¥t:Ø5€‚†B!HâÚl¶R©´¼¼,‰är9´'VVV”J%zÖFcwww @ó^,Ëf³ˆ62™L¡PP*•ÑhsR©4k4š¡¡¡|>^µh4Š^ ôŽŒŒx<0¡&•JRÈår˜L¦7ÞxƒÄ…„ŸŽÜ‡õ±X,ž˜˜˜˜˜ˆF£Ð6„ZNô/{<>ŸO¶R©ˆ1HÚ;Î#GŽà›'07H:ᢠEQ</•JµúR‚J§Ópº–bïªsR(ŸûÜçöïßÿç?ÿùüóÏÿÃþ°´´ôÅ/~±-ØFl~~þw¿û¹ßþö·kµÚƒ>øÚk¯}ìcûõ¯Ïç§§§/»ì²o}ë[êôàƒ²X¬_|ñÀ—_~9Ý;<xð7¿ùͽ÷Þ{ýõ×ïÞ½ûÞ{ï½âŠ+¾õ­oyæ™>øàC=tçwîÞ½ûÑGF£÷ßÿÊÊÊŽ;üñMçtòòI’øÑh”Ãá`’:®Cñx<™L†às;ï…¢ (D[¡‘à2€Ï³ÛíJ¥òõ×_‡ªl[9D mÁÊXn“yS(‚¦+b>Ÿ¼'¤KQ\¡ç‹8ŽN§ ‡Ã˜g•J%h{U“J¥r¹|yyÕ247ƒAF¢q$ql|>Ìxr¹PÖT*y=t¥7›MÜP(d0ˆ¬ªN§#]±X ­ðȲX,«ÕŠöŠz½n0кF±Z­‹ÅèÝ€øú_ÿúW¡Ph0 ‡Ã‰Dèü†¨|½^Ïår`I·X,«««v»]«Õ®®®Æb1…B±>8xøQ4šwÈТÐÒú9t°T*U¥R™…§7DÚ˜at¤-ŠakkkF£ÒdAª¤“ð½ƒ÷=f#yúõnž·\.¿óÎ;O;í´;ï¼óÆo¼ë®»Î?ÿü;î¸ãm:§ÙÙÙT*E„—ZmÏž=ÓÓÓétú[ßúÖ­·ÞJßô /LOOö³ŸÝÄç~À ðRFº¼íçÇ4(÷½�/mƒZ£ÿjµŠ½H©Àd2‘ 6fy@�=7€™PèjÅ̶EÚÂl6—Ëg‚$¨ƒG"“ÉÄårõz=daÙl¶\.';öõõÑoE½^×étEar„xf­Vk·ÛI3Ÿ‹¦8³Ù "íf³IQ”V«­×ë‘HJ¸}}}�ð‚{W£Ñ€l Ӡу³áñxZ­Jýýý� ©ÕêjµÇS©€�Þd³Ù*•Êd2áÌ Ó :î¢Ñ("B¤Ët:ÃáÖétb±¬q`¦ðûý@ äóy´#òx<¡P …íw:dŠÐétdÊåâEz’Ã-ƒø�� �IDATÀK3™Ìâââ_ÿú×çž{nzzÚï÷CZ·õQZ­VF»]*•Â( !î0×„ïˆ †c‚p¹\®Åb)•Jl‘ÅÓï€Ã}·A¸:îÖ[oݱcÇc=vî¹çÞ|óÍmfÇ6íÛ·ïóŸÿ|‡ï|æ3Ÿùå/ùùÏþ‚ .øå/I” ÿûß?ýôÓ×_}™ŸM{ß›ÍîîîF®F¥R‘×üf@MÒ“ïmem†½€ÐÌår­@¨V.,u/*@K¬·ªÓúýþ©©)>ŸßÓÓƒP¯3 §Bö¢B¥L&@%ëMÌ,ÙD&MPò¡KO@‘^g¨|e¡PXZZ‚ƒÁÝÀ²]£Ñp8œr¹œËå4 dzX,ÑhT ˆD"ˆø¡i»D"‹Åµ#¿ fh4ººº ¡Šjµêp8Òé4ÊKXÃáp8N§ÓÑhT£Ñtwwƒ¨×b±ðx<·Û=77§R©8Î$ÉÈÈ<–T*E2¿§§gûöíÃÃÃf³™¢(ô&d2¨ÔCT=~hØ3›ÍB¡N‘>M £Ñ—ËÅ�C;ùAð”J¥£GÎÍÍn¡f³Ç+• åÜ1ýºØ1]¹­HnÛAøNh«:‡.>¦Aþ‘Õ‡ûtë¹Ýî?ÿùÏ,ëÙgŸ½ä’K‚¾ÇeÁ`ð»ßýîí·ßÞVh‡ØÀÀ�´81sýå/ÁßKKK>ŸoëÖ­›aÓÌÈ“žúhEW [244T«Õ&''×{ýPZ(‹ëñé‰Åb'Ý0ÈQ#al"g8??Ïår1=A¾|„Û¦ÕðzÓ4Ð;€ä}ñ©úK¥R­r·$DËçóä½Àl¸X.—S©Tð@ø h‹D"Ä‹t,0òÄ¥͈2éžòããã333V«;" ‰›¬Óéd2 €‰ÅbŠ¢ ȲÙ,x€Äb±^¯‡£R«Õ<ËåÖëu´E€$···÷©§žÂâC©TºÝîžžð€Äb1¡Pˆ²ÖÈÈH8¦( çp8}}}/ÜúPÒ<@& i‚ ŒÖ#hµZW,!wÛ6ÙÛêœZ£™õ„•Ë6’Bìïï_ÞjpÏÓ»99räÿñwíÚ533311qùå—3:[ŽËÊåòÓO?}á… =úè£,ëꫯnÅE>ðÀCCCš°iø„YW’Y3,c~—Ëå§vZoo¯Ùlîþ&#Š¡èCt1;ÓëXÃÃÃô Â0L­V0P±Xl"‘üÙų!Úd³Ù …ÝS¢DþK$h äÈh4Êårz–¯U$8'¢jŠiE¡P¸\.t%@åÏårÅb1L¦.—k×®]2@z„%voo/<ßé§ŸÞzÐ]ãr¹SSSˆ<ÐAP.—ÇØØÇ›™™‰D‘HÄétBaÝn·£_�ÁÜÊÊ È# Coo¯Ýn/ óóóóóó±X¬Ùl6›M•JÕl6-˳Ï>ÛÛÛëv»áž-K6›­"|‰ßï—J¥n·ä­‰Db``� ~d.Òjµ ¹[°9€—¸d¨=®©u`…Btf%“Ép8\«Õü~__#X·Z­É9uV>1k+ÍxMèÏq=¥fCvþ­wÕ9­¬¬œsÎ9gœqÆÃ?l2™}ôѱ±±;wnPP ÕºººB¡ÐôôôôôôUW]Åb±þã?þãÔSOe³ÙȨ…B“Éd( ‡Ã Ëb±XO=õÔí·ß~Ï=÷|úÓŸ&¡«Z­¾è¢‹ „›ÍfÃápµZEîB£ÑT*•p8œËåd2EQ*•ŠËåF"`Ô陊M;©¬««K¥RµºŸ|>F¢T*Õ¡­–#1úfffšÍ&¸mì®ÓÓÓx÷Pn|À‰Ú x<ááF²««‹Ãá D?súi½;‹%‰z{{ãñøÚÚZ ÀüKOý.— y=Ô<èZ· Á&:Œt7®ˆÀt0g2ŸÏ1Ù©©)�›ÈÝX\\, 8ÿb±¸¼¼Œr”ßïïêêÚ¹s'‰D ÃÈÈHOOÕj%l壣£b±Øn·óù|‡ÃÍuh±÷öö¦ÓiÜ¿ß"Ú³Ï>!ŽV«Ý±c‡L&ƒŠD¥R)•J±XìСCGßD¡P@#ÊÁº›Ífý~,“Ëå2™lhhhllŒ¢(ƒÁ°¸¸¨T*µZ-ÛÌÌÌàààôô4‘H…B»%•(U ³ÙÌápÆÆÆÄbq½^?|ø0î :æé¸\.///#¶#àVÙ@÷’œŒÈ‰!ðø6Òb±XXtpW6›Pˆq8ÜŠ þÖ»šÖãóù[¶léêê“@m w¦y?f˜Íæ­[·Êd²gžyf÷îÝ ¼öÚk¿þõ¯#àýþ÷¿EͳÏ>Ëb±”Jå–-[è2ØgË–-ÝÝÝ»wïÎçó<ò¾¹gÏ(á^yå•8ì<pá…^xá…W\qžð‹õÙÏ~öþûïßt'¡A ôeŒå'šÊ^yå•h4Úv‡© Y±X¬Ñh‚Od]wéÇáèt:át>IL»Hš±Þl 0›ÍF£±Z­z½^´3`2U*•@ûâ§µ@ß°z·"4 EQ´f¬·*5Á`�ò”ÅbõôôÌÎÎ24…»ºº–——I$‹ÅôzýÖ­[‰„Ëåòù|½½½ŒÅüü<EQ•JE£ÑH$à™P$w„­ƒ `pp}…BA$íÝ»·»»»P(ôöö6ùùy�Ñ’à÷ûQ3›ŸŸ‡– H$‚!úÑ–]*•ИËåÒét.—CãömÛR©Ôøø8ŸÏ_^^îêêÊårÉdrnnOB¨~Ùl¶d2 Ý÷íÛ·G£Ñ@ € žR©ôù|õzz€8`2™ärùáÇé&’ãµÙl‰Dmå ¯¯/—ËaÙ„¶ìb±xÌ8(. Ù(Š?a½^Ÿ™™yß&:L®” 3ŒÆ÷éF"‘ðx¼T)̹ýC_}îÿsÅZ$)«Å?~z/ǾW6;;Ëãñ†‡‡?ôE]]]f³“Ëå&“É#GŽœyæ™›.ä1©Tú_ÿõ_×^{-ýýcMÛÞq‹Å¢R© ŠMo@ƒ–J%›Í‡m6[kÊ€˜f³ÙÕÕµžƒð¸H$úË|LR•,¹\®Ýn€~ÝÝÝÐÀÕëõ™LˆÚB¡ÍfÂ]ïø …"ŸÏËåò\.‡Å;= J×]‹ÅôM¬7á´hÕY*¦àYÀ Dˆ¶cÇD.—krr2—Ë™L&$$ àŽGž§H$‚½, 0ª&“I£Ñ„Ãá@ €fB‹ÅR,ëõz<¯V«6› F.—ƒ²ÃK/½tñÅ/--±Ùì‘‘±X 𠀫„< !Õ–ËåÔjõÿøG¯­­ÙívœÿÚÚšÕjEÌd³Ùq‡ÃÁÓ—Édf³9" †‰D‚ÇÁårIŠ*Æ­a:ýà¶C"2‰˜Íf´ËÇãqôÄçr9† %›Í¦ãs±ÖI&“ïTsýéOLL€PŠq]ë™ÃáX]]í0æ );Ýu×]Žmÿ°wv-“/Oþu“¾hÓ>à–ËåÖ[謮®¶]ÇÁÓ@ �Djëw åа†QÇB‹W½^¯T*t†1‰D"—Ë#‘È1Ÿ FAÒÝ“­×ë �!ù2N�‘ã8�á"nH¥Rhžær¹èˆJ×étƒÁH$¢T*Óé4ÿ .•JÑÿ ¶†s’H$XžƒÊ2¾„Ѻ9æççív;Ü›ÍÎd2‰ ßn·{Û¶m±Xleeêïb±¸V«år¹Z­&‘Hü~¿F£­ž*• ŸÏ_]]M$[·når¹™L\ã§w¹\¥R HŠÅb<PŠ¢¸\. ˜[§¦¦HJ±X$³­D"ñù|årÙëõ¢á¢÷ °‘J¥J&“„P†Åbù|>(áÂ9áG·9N¨.�eÌzi‹áÔl6u:›Íƒ™LF©T¦R©µµ5"|n«sb¬Bè,®d80§ Á,³hLK$¤ë¼ïz¼±Ds™îœÞËšÓ¦mÚ»i"‘H©TÒ9TØl6�:Ø´Þ^ 3 ³pÛ^‰`0¨ÑhØl6Ç£c’ ÓÑvˆ¼‘ME!_¯T*P?–î °]R˜Ñhdü9 ßïGC͉ÇãáûÍfsllÌåríØ±Ñ (ãpJ¥= .—‹Åòù<&°µP(D£Ñd2™ÉdÐ2î÷û¹\.j ÿ-œ1Äô lár¹z{{³Ù,:ñü~ÿââ¢X,‚Mƒ.—«§§)¾ÅÅÅT*‰DPÉdápÜÐËËËñx;@°¸¸HQÔðð0â†R©Äçó…B¡Z­îïïs:�%7‡Óh4�àe³ÙÖ7 #’™W$q¹\>Ÿß:f€Íb|xi @¸ñCäx¡çD¾ÈÄ‚qŽ -² 7`j‚ÏM¥Rô òK­ã >7þâÐ%—à“Ikg³Ù â™Ö+ñàÜyò÷¬æ´qóx<OM¾_,‰tuumúŒwÍèM �ùTl[4+YÓ7­G½Ìz³Q‚êM$ˆx [Ø5è~…ì¨P(r¹#pL¤žè#§í¹Á0÷õöö¢ë‡ÕÒ¬V«Xðb6!Èüžž»Ýn·Û¡4øòË/ÓC_2EÝÝÝ`ee±X:Ð+‹Å"–——}>_âÿec$»ÊóáÎ9÷tÎ=3=Ó“vfgW$ „õP.°,@UBrQ¶°.\¢(,!–lƲpa2ÉF „ì²+íjgÄžÔ={:眾?žÚãûÝîé•„X‰9lÍv¼}ï¹ç=ïû>!“Q*•jµ¬¹Á`H$  A×%Âÿ‰d3 ‹iµÚÉÉÉ•••p8,“ɇÍfú+8p€ÅbÅãq³Ù¬R©°ÿC8;ÀM …ÂívÆ@ Íf‘œ)Šíím•J…fð/eG¯× …Â`0X.—ãñ¸J¥ÂÉ×h4àuE£Ñ¾Qø9!8ÁÌÿÅç·Z-2¨¦á�öź¤÷þ Jxìf‹á“ÿuŽÝü´K48 †¾‹oé166ʽ°ñæŒz½.‰T*’'¬,Ðp»ö>¯î^}Xðrh¬^êB3¸¨…F£ë]_³Q­VKÕ÷¤’pÉS©TŠÅbÁ¤œìj †Õj¥îÇ©ñ_´¸¸˜ÉdÞÿþ÷ÇãñÞÅ‚Ïçk4êâ‹ÆF6›%‰ÑF30´e2™À['‰jµj2™p#¯¯¯ONNâ„€?„î „æ à9‰N§“Ïç­VëÖÖÖå—_îv»RG‹+“ÉlmmÙl6³Ù¬Óé¢Ñ(ìH‚Á ÓéÄçÃÇ¢éh¼u»]dfh­•ËeèÃâ<ÈåòÕÕU»Ý¾²²sahO@³ƒÇãmooÃt2¨G §ÓICÛ“Ò.üsC¡ÐÖÖ¼Á`Èç󻱿kµZ4Í=‡ÃqAS•¾‡A“¨ß}ä@™ô¢Þ…¼y�r],K¥ÒݼK18={¶ï%{Œ+®¸âuŠbìÝrƒ‘?˜Ðj$uQ€›Ænìg.681Îó`P@ëë �sXê#Èêõ:µâYü­Ñh:N:†¥,aSŸ" ‰„Ïç#9$` ÁÄÉ tÙlV(Úív¨ð…B¡+®¸bß¾}xV­VW*RöH§ÓV«uuu5—ËÁ܈ÅbiµZ‰D"‘HŒFc§Ó1 ëëë‰Dbtt4 Bu âGŽA,I&“v»}cc#»\®ÑÑQ6›½½½N§•Je¥R±Ûí€NÔjµX,Æãñ¸\îÆÆF¡PÐjµÙlÖçóÓÂf³) +•J<ßÞÞ=pà@­V£‚*3™ ,3”J¥R©¬V«¤Õ§T*s¹\¡Pèt:sss°¡¢Òiãñø5×\säÈÉÈR3l ûpi;p‡õz=™«ñx¶-‡Ùy0¤÷01¨›‰Äí(kKKK„1}ÁNlSß&\.w€‹J¥¢b§/Ñàäv»÷œp÷Æ2zó†¾lÖ‰‰‰µµµÞÜ( a«»Klï ºÃQ÷˜ccc+++ÔÂËNÙƒÁp¹\@�…>Ä3Pm¨qK(ºÝît: ãZƒ…Š3Ìd2À¶¡”4==½´´täÈîÜçó!7BKF¥Rñùüx<NUšÀ·àer¹\¯×[,–¥¥%¯×‹ÅÃd2y<ž|>?77†–H$‰D¨d¢üq »Ý®ÓéÔju2™ G™™©V«sssZ­ú°W\qE(‚>a0”J¥SSSNÇd2i4šF£ãB¡�n™^¯‡a‹ÅZ\\DÒìñx�±Ù쉉 Â'àÐår^¯×­V+ǃ©®L&›žžF3 *G€~¸\®õõuÒDA¯^¯OOOSQõ4m6›M󟥎B¡@Áô#ø´úh8š};æÌÅN×@ �¡ÝH$BH]ƒñÐìXÃÃÃØ¾¤Ói³åÒN{N¸{ãM+++¢G‹Å‚e×Ù³g···gff<˜˜@€†ÉÉIØcãC ­F60<%t³Ù\.—³Ù,Ô]û²O®¾úêãÇ÷V~H>‡÷RcÒØØ˜ßïw¹\Ä4–fžð,“É Ú áQ<µ¸¸( M&So¡¢Óé`ÍÇ¢ xjff&h4šÍÍM6›ÍãñP"c³ÙõzÆN›››:N«Õr8œííí¹¹9NX]Æçó={ö•W^™ŸŸŸít: 'I¥R Ôårùç?ÿùv»º%Ìý�Bú¸B¡h6›Z­Öáp´Ûíßÿþ÷0gb0/½ôÒÜÜ–�ÝÎår€ü‰D"  Á^.— C8n6›Ð9‹Åv»Ýápœ;w(j@W^xáÆyP ’-¹\þꫯJ¥RÄB@¸\®^¯‡æ§R©œ››,¥Z­noo»Ýn̸ ÿßBÌáP·­¸F6›­T*‘L—ÃáàjöåtSÞ=žR»­V ³è¢Þ²ËW’#t8¹\êf³‰ÌžFcg0lëø~ÇøL±\ãwªc5þc LD­V»›âì[kD"…B{+`­V‹ÇãT]™½ñ:·5KKKO=õÔ�7ñU8,èG§Ó 7:: …Âáðèè(ZÙCCC`ÂÖjµd2IM‚Ëå2µU@C llGFFжS’ú¡P˜N§iOA LR‡ÃA“Sf½T*Á`Fy½y˜=8øjµ* ‰ú@¯> ²‡b±$¥R‰bTY×××E"‘F£™˜˜àr¹ÅbJKp¡*‹›››€8#äd³Ù­­­ÉÉI·Û ÀÔFGG+•J:®V«(šMNNB=Åb¡G…å[(f2x BÒÅl6Ûl6p­ øÝn·Áô‡s —Ëív»@WV«UhC }d2™çÔ©SÅb1ƒgÝh4 Î*|‰P¨Ïh4Úl¶íímg÷ûý‹®TL&z¿ûÝï \'&&†††àVåõz{W6>ŸÚ/€ûäê‹D"a³Ù###Õj•è†�W9¸ ƒàúúï,@€«ß{Ç1vað ú-™Òb±˜h3™LP Æu×]§0Ž„RÅzµœO„ßÔàT­V_xá…R©D¾åÔ©S‹‹‹6›@T_spZ__õÕW•J%Bž{î¹L&Có`0Ï?ÿ|$±Ùl±XìØ±cÞó‹y™ßïå•W¨O•Ëå_|ÀŒ‡Á`9rduuÕëõ°´œÞ¢Á Îrb±ˆ)D£QEu:],ƒÒèn°O …fäB¡z<étºÛíBQ›ìÅb1¢#y * ­VËétÖëõF£Ñívwú²Z­�¡)ŠÞÊ ›Í‹ÅFƒîS›óp‹ kZ ”ËåÐZÕét°!AJa6›‹Å"ºb¸‘Á½ …BCBÅ™äCjµXó|>¿¼¼Üjµ†††²Ù,4[U*ptP‡”2œF”†@ j4ðj4Ñhtmm j³\.·T*!Hà)pZ—––Äbq6›­×ë‰DPoœçééiÁŽF£ðrEÈ™™‹…V°……¬°*• s&›ÍÊår6›F9ŽJ¥ª×ëï|ç;AT‰D@�þÔ*œÆjµš\.ït:db”J%ò2´0m6\»Àm"èÓÞ`€ä£ïœÁ'ô2„Ãáò”;z¿ bN½U.làÈs:€à‹Å"—ËE¦ÈápŒF#ž¢§7µ¬—J¥þâ/þâí„›Íf“Éä½÷Þ{å•Wþò—¿¤¾ì¿øÅwÞi4O:uüøñO~ò“Ðg0sssD£pkkëË_þr$™œœ|æ™gn¿ýö»îºë;ßùÎ#<rà 7,//›Íf8á~ö³Ÿ=tèÌ >¼§õð2™ {dÆy]‚ñc0&ŸÏ÷%dÀ$w#‡Ã!A­VCGµÙlÒ OÕju&“éåçEpH8 Õj5¨öµX±¸ ±DKÝpx“H$Ô •Éd°IŒF¨$? Nµ8~‚qX\\¯hmmM,‹Åb¿ßàçõzçççAf2™�_Èår¬•ðàH§ÓgÏžEi´Ýn¯®®êõz¯×;;;‹P'‘H¤R)–¶L&Ãår›ÀÉ‘ÉdHGJ¥ص€f2Uñ]2™ À¼F£‘ÉdªÕªH$Z\\t¹\È#µZm¹\>{ö¬R©k6›ããã0³€o!@›P*‚e¢;Òk»ÝîñxT*•Ñh\]]EBS«Õ`Ïé\Çùùy°†™Lf>Ÿït:йèË™Eì‹DÀEY[[“H$<¯W1–Ê´%Ó‰¦l"•J…Ba6›m6›½Ô]2`ÈY©TÈ‘ìDìÙ L‹D>*C™Lxä¸Ng'ÜЛí„ûñü•W^yî¹çÞûÞ÷þò—¿ÜÚÚºýöÛ_§Ùàêê*Õ 7•Jõ=eÿýßÿí÷û‘†B¡'žxâàÁƒÿøÿxÙe—Ñ^¹°°ðøã'Üxàãÿø<pÍ5×|ó›ß„îM7Ý'ܯ}íkpÂ}ôÑG÷‚Ó¥0À´½(ŠF/[…š£ à Ê*që!“ÉV­V‰u)¦ÞÏ¡Õ�!gÉdà;Þ7Q¯“qÞ$·Ûí ‘HD=rЀÔ÷b5Dƒ¤·ÜO~ò?FãõzAÂE‘ÊêÕétr¹\*•.--étºp8 +t˜¢FmÖL&c³ÙÐÉ×ëõðY®×ë&‰ ®�éU&“þOñù|$ öÆ¿Õj¥¡¹¹¹V«'ªííí\.GN»L&«T*¤ šN§[­M&“Y¯×Y,V"‘°X,"‘h{{èv…BUÀd2év»·¶¶Ðþ­ªÕjY,–H$R«Õ|>ŸD"ÁY«ÕBÎg"�ý'“IT_‘´i4šb±HE܃A‡ÃápD"®ñ\&¥·7Cæ é îdâŽÂ/A»ìDÝÇãëãNspÎår`‚cÇc·Ûi˜ ²DÆf³‰t#ßäýéÇ?þñõõõçž{ŽÁ`<ýôÓ[[[Ÿüä'_p¢:áÞqÇŸûÜçz_öØc}øÃÆÒ …üñJ¥òØcýíßþíÛ¹þ'8¬VëNMÚ¶›´]êQ Ãl6 N“u*ò8 ÅKX±­V+‹íT£·X,X8êõ:bL.—£" x<aï“§ÈEz¡P(d2™N§C27àgì/­—‹ÅàjŠŠ\*•"Oì¦R©ò¿ßŸÏçÃá0ÒDØ *•JˆÌF£Q8£ƒl×v¨‰'‰ÍÍÍf³)‘H4M6›…߇Á`�V>—Ë iµZZù|>¢Š2™L¡Pp¹\‰DÂáp¤R)êiÈ °Øq¹\ÈaÀê©^¯£z©Óéêõ:  �˜P(zÔ •J%ü ‘¶6 LhµZápúTç0ж9 ¤®P(<ÏË/¿¼ºº C¡&�ÊtÄÚ±7Æ QÉÔd¦íœÈœ0r¹Ž|Àk^\‹–Ü£0‹ƒ·Z­ív{§®Z}Ùåo6Zottôî»ïþÙÏ~ …ÿþïÿÕØ×<ˆîüã/û×ý×}èCä?öØcøû_þå_îºë®üà»×rß—òÈår;ñÏ8›ÑnÂ3- 4óì6^Pê¤ÖFu— +¾à»FFF*•J¯P‚\¯]!ù±ð†0™LxY«Õ"X.—ûn“;P#!‘€§HÑ $\²\¢Eå' Ng2™ #^.—··· „ †P(´Z­è4 vz<žøý~tSpÞ�Rr¹-%à°pC ŠÁ`àA A‡‚>)HÎêõ:ä‚ x¬###±X, ŽŒŒ@Ëucc£T*Ž“2â]�� �IDATŽ‚ãÌãñ‰›ÍF.—Ë9Îd2i4q*Äb±Ãá@h!'xw©T ‘*´ôÚí¶J¥SZ‹ä ÓÄú[ Óé njRŸÚ‰g=ø© 6_z4™L¨Žîò]µZ8sB ƒ&ª�v6„©l6aJü1ƒ“B¡øìg?Ûn·¿õ­o}þóŸ¿óÎ;‰ñkÑhôÁ¼ï¾ûËýÛ¿ý›@ øó?ÿsÒUR©Tï{ßûð÷ÿüÏÿüô§?¥ë÷Æ[w ˆ@» NÔûd—r™4– ã¼MûàüL«ÕR‰Ÿù|8é¾[cðrvêIÐ*„X•àÑ' �è´Ñh” Mv8>Ÿ¯Õj‚DžBû]¡PPY“4ÉZ±XÌårÉ‚HèP­VK£Ñ F#—˧¦¦¼^/ y±X,‰ †ññq(¢V«UƒÁ044„ª5­V  *ZR©æL¤ÓæÇŽ�ýtΠµê÷ûñc±X©TÂk «¡Ñh E4ÇãµZ í7³Ù¼½½¥\.Ã5*²ÙlソÅðð°Ïç ‡ÃÐjBp"e®|>Ý?\k°­ûÄ€KŒD"õz½ïþWxx˜O&“;ÇzŸ¢Q°/jãÚ]ê½Ïç©Lpò€b6›ÍŠáW¹\Ž Æjµ¾žÈ„ÝÇÓO?ýþ÷¿ßív?üðà ãöÛoïu7ˆF£_ùÊW<èv»‹Åb p»Ýn·ûÁÜ[Ê÷It�!šT»ÛÁÅF£7òð #ÃápP÷ÅbÑï÷ƒD iår¹ïƹÝn¯­­õͨçÍó_=´Z­ååe`+ Öét:ÅbñÔÔlRÛív½^O§ÓR©”*l* µZ-•Èi³Ùà”áv»QùÄ~²¸ï:N¹\Æ}½¼¼¬R©ææææææ:¤Óé¶··³ÙìÈȰ*•jyy™ÉdŽŒŒp8œD"¤†\.oµZ =–„R:1"‘H*• ¡€‰¬«\.w»Ýb±øÊ+¯Èd2‹ÅÒh4,‹N§ …W]uļ+•J4õù|Ð_g0W\qÅÑ£G#‘Èüü<=‹óCƒæ×ëõB¡°´´T(|>>M§Óét:¿ßo0öïß Î-BEß]ŽÅbZYYq8@µA&†ËåâóùФ§½}€ÏSïS™Læ5KµîƸvÀè]“kµÚòò2xwJÈÞÚªäv»={<ÇsÇw0ŒGyVÐÔñå/Ùï÷ãeR©Ôf³ý×ýW­VÛÞÞÞÞÞ®V«*•ŠÃá”Ëe¥RùgögðÏ- •A„‡XÌ.±‰~`!Gº{ãR|>llŒìFIÉ®Ó鬬¬p8œl6‡M& q5¥ —Ë…‘q‚qýõ×s¹\R÷o·Û ôî4€X‹ÇãdçHšÞ¤¹MsãF%väd1B¦×ë¡’N¬ ‘Á‰ÅbÁº°·U ©"¤¤½A¾kuuчb±¸oß¾¡¡!ØÝŽãÈÕj5ÚQ‡v¹\“““f³QÇn·§Óé£Gúýþ'N¸\.™L–Éd677O:Úív,Ëd2F£±^¯Ã”vhhH3¥R Sv­V«P(är9ú[�5@æU(ÎÌÌx½^ÜòˆaR©འСl6J“““8Û:î•W^Éçó&“ ?ù²Ë.C[Ëh4z½^²M~X_Dª`"a{AS—gœ÷Áb2™à?…B!œŠJ¥²´´499Y«Õab-r±hЛÝšðkèá¹Ýî‹}#­ºˆEZ˜d3Gû]…F3;;û:áã´a4ggg±eƒ#r_âééi…BqàÀÿøÿøÊW¾rË-·0ŒŸÿü燣Z­ÎÎÎŽŒŒ|àøú׿þÝï~÷ÙgŸeœwÂ}á…>ñ‰Oàõ‡¾ñÆo¼ñÆ}ìc°‡¿õÖ[¿öµ¯í-ý—þ¨×ëتÑhºÝ.pï™Ífà”.(ŠO-°ˆD"»Ý®R©¨€¥ÞAÛùŠÅb¥R‰fîÞÉÉÉsçν ´E*•j§M/LQ"‘\uÕU …âàÁƒ/¿ü2bØÒÒ\M1“Ëå(ëï…ý,€BjµšpuašŽM*•¢v`Ä' Ü`2™êõ:ÚÝjµb» �ƒèÊf³Ýn7Ð �7:tˆÉd‚é…G`Ëårv‹ÅB¡P(ÂKàˆB¡€b*•R«Õëëë2™L,_~ùå(Сý£Ñh–——÷ïß4 æívN’ØF`b$ ½^/“ÉàÓ!‰ŒF#Ô’D".1ÍÚX¥RdQ,©OAw6‰�ƒ8.— z2Q ÁÄ€¨Ýà9Ã8ßÝÄU†Äíë 9¸ú}ÙN½Ãét®¯¯÷ÚÝ^ìwéõúb±HM%íT«ÕüàôÁ~ðƒüàû™ŸúÔ§>õ©O‘Ýñ‹/¾Ø÷eO=õþx×»Þõ®w½‹V!ïúÈG>ò‘|„–€÷~æ£>º·Ü¿uÚõ|>Ÿh—õ"hw².¥¼r¹¬V«I.Åøÿ[|öèQín …¾è‚¥  ³ðx<F!W‚@3 ^¯ê¤ðím„=lóqT‰¤V« D&<Eê]R©Õ<9üÂÅbq"‘X]]Íf³gΜ!˜Àr¹Ìçó“ɤÇãyÇ;ÞªŽÁ`( J¥–zØ\s¹\T5�j@I‡$n5 $‚0ºe³Ù��å@ °¹¹Y«Õ¦¦¦Ôjõ 7ÜÉd:´Ï].W¥R¸B¡@A•Ïçƒ.† 5kµZŸÏg·Û×ÖÖh”UÙlv (‹èƒQ/‹ÅâñxêdÇ@ö4d¦ …BLØZ¾¬  “W£ÑÄb1œx<Ôi©Á†êhÜ;`Ï1xSÅ8oâÜKW0zÝ“qù¶··{w~B¡°Ûí& Û%®­·7öÆ›6.x[ÂÅü‚K‡ÃH  ¤sÁàD:äïÝ“KX,N¥Rö¼ Ã"sÊd2•J%•J PˆÒé4:(ä]@`ÿþýÐjBk'‘Ht:4x½^4B €à;Ýååeè³�§�ï"ðs…Ba"‘€^öÈ^¯—ÉdBc{{Ûjµ"ÅÃ+;d;Ð%|8½Z­!"¤Y$µÂñ˜Íf|Vm“É„"<øÂ™L2N:.•JI$“ɇ X®"‘(›Íft’@S¥­Ë*•Šà_ àq¦3g΄B!˜}T«U>Ÿ?==].—‰D.—+‹Äј¶.[­V@�GAÄ¡PH< n#§¤rºÁÀc2™*•*Nóx<¥RIe¿"8aÓÐw’ô·É ²za×»”9yòrjpÂõÞ¸}z3þ½à´7öÆ ±Sa:jµÚÚÚ:F¤D¨»X¯w ¤ èDô®,Ø;ÓÚN4.Žt¸‰¡²’wõ &*Qø.xO¤ÓixPÅãq²È²Ùl`Ãàj_«Õ l¾§ÉdJ&“ãããËËËhYåóy‹•ÉdFGGE" ÿ"‘¨X,¢ËÕl6!ØHÔäð{aê ŠRµZERÄŒ0£Ò±�»W*H»z<&“‰Âc©TBe2™P‚\:ð{€öÅãñééiœL§Óá¬j4šjµ‰DÜn7jz*•ªP(`EnµZ¹\„'<…ßÈd2 AÆÙl6ƒÁ À&$!£u_ÈS½‹q¾³Åçóy<^ïþ¦Ñh`F(ÉZ­–æßÑwP›@´Œ!$\ò®¾t\¸¾ÇßgÏwi®›››»YÞZž4{Ëý›6Äb±@ xmØÙ‹<5:@z»‰O4ÿ\Hô}% ¼À8OÂ%ÿ%K*„…PÀÁ²‹XÂf³!Èì‡ÉP³Ijʈ6L’É$‘ºÀÁ9 "g‚М^¯‡s]¡PFö–H$¬V«D"ØÁårE"(7 0y!ù#—Ë!S ¬A«ÕB? Ù L­�¿F¥¯I&“?H§ÓX‹Y,Ööö640Ýn7ÚB,‹ÉdbwoµZ¡~„- ê8WÁ`Çã™L&´T*U>ŸÇ©h6›Hª$I4Íår###hYU*•¶¶¶ãñœ ½àÀÄ`0²Ù¬ßï'E]š2£_›�ä" SSÕû²™�ˆc7[®Ýûç’ ‰X U*ÜV«5 ŠD"hØ÷¾·o$»tp_'Êün·[«Õî™9½icÀM(•JFc2™Ü‰TM/üW©TBîz—Ç€Í8Ä^©¨¯µ.ž2›ÍhGíö,K©T4|kk Š;‘Qç°X§À´Íår´s‹²e†*O:N§Ó½ ( ½€ØlR*•ЀZ¯X,F£Qä ø«««333pcBõI,Ëd2à&:—ËEVX�( ÑÔøCHÁn6›r¹d)X *•J?A$Òh4Àd!0ŒŽŽÂPX©TÆãqøêÑÎf³³Ù,à‚Åb±T*á<Ëd24íâñx±X+ ¸^N§Óçó%“IHQPO”ÓéDAé—H$"Åød´ål†È‹‡‡‡C¡N§Û‰f@Û?½f@9¨]è_Ò’]à<y_2%ð‘bê0Ÿ¼Ôƒ“Ãá@ç“Ú[~Û šNÌÞøƒŽ‹uµZ¬ãu�Úƒ‘‹Åb‹L̾1ƒúDehëx·Û¥í…­Vk:ÆòD [}ɘÔDËÓ�ÃÓùùù……ò,6Â4¡kÔÄz{WÍf3‹‘½s,ÃkÈÒ¦ÓéÌfóÖÖB5¿ÓÓÓào!¼ÉårøµË'‰d2ôèöíÛ‡>Љ' …Ífóûýv»òÞNgmmmttý$D87PÐCäC|B¥‹Édnmm À`0x<žD"Am0—Ë!Vq8œd2yÝu×á½ñx°@§Ó™H$ W=\xÝ’b”J¥ ƒ9‡¬ÑhDŠY©T677U*•R©„j¢T6Èù„vJdðÊB¡FSë£ZÖBã±R‹{±X ùbïèe¿Z­ÖT*… ! CßMRßzïN‰™6É1ÇM& ­W­V{Å,.¹à„˜ôö3sÚ—Ô vwaÚDÖ¥R)‹ÉÆ&¹˜jêM¢�à&§>%¬Vk¯í[/ñ0;QÒaêe‡À?—D,©¥Rinn®^¯‡Ãa•JE6AÂj�èõz£ÑÃrjµ§ïíÖét¨ëcïž7•Je³ÙV«5<<‹Å !… œ‹Å¢Õj5 äbp¹\Hw@¥R™žžf2™Ùl¶Óéàö‡„±ÑXâr¹0p>¢Õj‘ŒªÙlbu0A&“mooÃ?©T* Çc·ÛÏž={ÕUW]vÙeårùܹsÝn×b±€ôx4‹Å‚ôã<i º\®p8lµZK¥“ÉŒF£Ngkk >„p·ß‘œÉZ­699I%º‘ð<‰ÌÒ ¢zW’Éép8’Éd©T¢œïJrizKpSSS4È;u¦á'[½¹‡Ã™™™) ½z¤p×$S×jµ …\.×ËÀíÝNõ„—œÙàŸÎØószÃÍÏI©Tj4øôÐÚ'J¥rhh{74‡Y,ÖÜÜz!Ôp’L&Ñu—H$dé§%UFƒ,÷ÑÁwq8“ÉÄçóiý!‡sàÀ¸ù!í°ÙlXvé÷'›M¢ ±C$#›Í"ùƒ7zò86§Ó‹Å¬V«N§K§Óv»Úh`“ÓÅb±ðz8šW*—ËU,'&&‰„L&ÓëõÐi% $RLNNeÎ8Ú@¿'shh�e¡Pèóù8ÎêêêØØޱ±±t:ÍårËår¥R±Z­?‰5½B¡�9W40ªÕ*þÛétpð(•Ëeüd$4Ùl' dÛ—^z ÖR©4 mll\}õÕ/½ôÒÆÆF$~]ðq^\\DŸÉh4e¦ùùùV« …�:�¨„˜AwÜd2¡cD&¼wû–I7cÎ�1ÃN&“SSS4ðE©T‚n<ït:(G#« UL$äúR÷þ»›Ú(ÒÔÉL¾ŽV{ÀNNN‚[F=}sý?¦ÙàÞØ NofpªÕjX=F#MvO!±Àý) ƒÁ`±Xäóù4 …ËåJ¥RÔ4``+ ÆLµZM$Ôö�¹Ã#‘a1Œ\.g4©] ›Í†åºú�lÿBQ&¹õzDÜz½. áÁº¾¾÷#…B!ºç‡Ûí–J¥Xhà+! /Ž…¦Õjáà!…^¯×].h>Ÿ/•JFä:Z­ÞQN§³\.£Ô†Ð‹& ¨`‹&L w8ù|^,kµZR¨Õjðcx<žH$jµZ‰$x[ ó£)XÇ"=BFK¥’T*…�A½^@.-//OMM•J%…B¡V«5Ùl†T®Íf[^^¶X,Åb4äV«…ó,•JWWWµCkG$ét:4ùFGGa §V«ÑÙ"w÷ððp/? 2E(ÂzÏ’õèjˆyÇãq&“ét:3™ “ÉPRãp8м S÷µ­N½NÍ}'!4¢H–O›ŸøQûý©§#Gެ­­õŠí§?‘àtôèQZ·¦P(ôm/©T*‹…|ž¡P™Ã³ÄN4NÃ|7à%pw°£‹n4QÁ­.—ËQ€BÙ(™f³ÙÞʱs%@‡”þÆÆÆòù|³Ù„Q*•ºÝîw¾óp0*—ËpGûG«Õ¢-;òÉÅbQ¡P…$Æy4BP¨²V«U£Ñïör¹Œ=r$A¨FÆY‡r¹<55çºf³©Óé@ÙiµZ\.×jµ†B¡z½d¶Éd"kk6›…rX.—c±Xív¢®Øª7›Íd2Éd22/ Ùlvii)‚¥d4Á‚g’\. …CCC0¨×ëPÇk’É$ªdb±Ød2É>6xÚÄ(žJ¥\.W"‘Èf³:.ŸÏ“SD’ZdÂt2hÎiµZ0‹©Áƒ¸Ó"‰„N  ù0à6¨b_E›0‰„öäošÙñnn%TÈ'Sû嘘„˜~ÔèKžBÅ›&S4`W÷ž÷¼G¢µÿqœpßœqÏ=÷ƒA¢ó¿7þÔ†L&ÛåÕ§VÉz+ã"‘ˆ€³•J%âí5„ÿH‰ÅbƒÅbDV¡P€æ[:†²N¥Rq8gÏžCCC(Lõeh’­4ò€÷¨‹ i°»mµZ¨õ#à•J¥|>O#öSO‡Ãj�ÿ%Ô}b’[.—2'%GxC@•%¸jµŠÖ[«Õø©T SÁééé“'O‚¾* ÑÐ*‹V«uvvöW¿ú•Óé4™Lù|f¸P³„”x>Ÿ‡?Ò#P— —ËÍår°…éu||œËåÂo°V«¥R)t¤êõú™3gÐ/‰¸X,®®®2™ÌR©¤V«aߎÇÉéÂEG1 ÂÂç\*•â* z©Óé*•J±X”Éd4õq@�ž“Á`H$hLR}qÕˆN)¢‚Z­æóù©Tjkk ¡t{{…VÌê†ÈN�?§ž´ÉC¬T›v*uW.—Sɶ4V¯T* NK;Bš±ßÛ–„›ÍfŸ~úéùùùÇœÁ`ÜtÓMçÎ \.V„+++O<ñ^|Ë-·Øl¶F£ño|wËO<ñ®w½ë²Ë.ûÑ~D`¯Dio\Ê£Õj¡\Ó+ÅOóëD#‹æÚ)tu»ÝÞÐEq‹ÅB Nðw'ŸF%‹@'ƒÍªÑhÊår±X$ŽyÄDªoŦïãÑhÔ`0È%¥Ri{{»\.s8ê± ©ÕjpN±Nñx<½^ŸËåd2 eäÅ„øI+fbD¨€ª—XÇëõºßïGÜ‚œV«F£`þÚívŸÏ—H$L’x<ÞÊÊŠP(D‰/“É 2 ´‚J¥‚ƒ_­Vc³Ù(Æær9HÕ¡Ñ…¨@¨¸HY …W,A<×ëõèÀU*•H$‚š!Ù°Çãq\/4¨ÈÓëõ¨ïáeCCCŒóF”Z­Ð5 ûМ ƒjµ:‘HPƒˆÃàöö•ó`³Ù`;mooÃÆ!X,¬uqÚ«Õ*Âê.´}Ò�oɾ °CìÏhŸ6 .7xÞönA¶ëEºB2_F=3o¿²ÞÃ?œÏço½õÖOúÓX;^|ñÅgŸ}Öd2©Õêx R©˜L¦{ï½7<xð¿øÅ±cÇ®½öÚ/ùË?þñ÷íÛ÷ýïÿG?ú÷ßÿ Åý÷ßÏår{=Ý÷Êz—ZYï7¿ùM½^o6›½U8@@M;¸\.î0NÈ&<›]~) bÔÏ„ø©ÂY­V¥RY­Võz½Åb‘Édµ3™LœF½… ^ …*•ŠzÚCs aªF£! ···£Ñ(*œ(êõúùùy³Ù ù¢N§ƒÞ¾P(l4z½Þétj4(¢6›MFƒï"ÔQ°X ½ 9WôHéy�tjµ$øR©—ËU*•è±Ùl¥€ÃFpJ.—ƒ›ËåÄbq<G:Åáp ã�Ù­d2$ pe[­›Íît:80´ÊR©‡ÃQ*•333›››ù|Þ`0€qµ‹T*…Ÿ&‰°o�fé—ÙlÎçó"‘H©T‹E›Í6>>.—Ëù|>ŸÏ‡Ö‘H$2 µZ-‘H@`‚:=êõ:—ËEãqžÊ†Ü©X½^˜Vþ‚_;N/´Ò›Í&&F¥Ri4F£‘˜Y ìy±KïSˆúü`a¨Ÿ ‰ E¥R¡Îj"…L«·À(•Jo¼ñF¾ÒLÊz¬·ñRÇÀm·Ý655uäÈ‘éééÛn»Åbýïÿþ¯J¥úÌg>óÕ¯~õ¶Ûns:Ï<óL>ŸÿéO*“Én¹å–ÙÙY|Âï~÷»ííí}èC·ÜrK¡P€HùÞ¸ÄG2™D3 ÷)R‚—J¥P8{Ÿz«@ÿf—’ùاC¸šÖß‚ŸS³Ù„¹ê¾}û<xýõ×:tÈjµšL¦l6 ç\.Gm¤ã]ˆLZ­ö‚lt”û°1™LøeÐx3|>ßb± J¶²²‰D:Îðð0H¦(ÅÄãq•Jµoß>ˆ…S ;X  Æðð0djÁ™ö¡ïQAS®^¯¡#¨Õ½ .—{àÀááaÇ# Åb1qåH&“áp¥9$¯hS1Î#5€÷CW¦^¯‹Åb‰DÒn·aNÇ777“É$¨QÅbñå—_‚È[[[Ø�q�-"¤¿ &cÓ€”%J$­Vk±X è·h³u»]x¹öínªT*H’9CØ©XÙ …ROšx!þ4::Š~žÙlS*•F£‘º zm5†Ý`|z7CÄðŒL ò”N§ÃÔ¥=…‚vß9Óh4hÿ‰jëá®øô§?Í h ‘™433C}äcûØ€|yo¼ñf0TËFönFA-Œ€ço6›y<žV«µÛíÍf“ÉdŠÅâd2Ùx°ô[,Tov‚#÷ºšÖjµd2ét:€IÖåv»=Z) £& ¼&‘HŒŽŽnllH$///ÃÖÖu ±3‹±X,X` ~Ó•b±ØjµW…ñññp8\*•Ün·ßïçóù‹‹‹J¥ÒårÁxp|||}}½4£Ñèr¹ dµZ———Àìì, äЗÉdh³q8H\³X,`ŸÏõÕWív»×ë…ò°Ôb±8NÛl6🶶¶¬Vk§ÓÌÁl6onn¢ª&‹¡hŽEßåry½^gf³¹¹¹Éf³OŸ>ЋÇãHCõz=Ø»½+ÚÄÐëõT‰Ng$cõÅjµ FµZíñxa*·Ô­þ@Ãív¯­­‘M-»¢·+•ŠÍf‡ÜD´îOtÍ=yòäí·ßþ¡}è _øÂ=÷Üóä“OÒê¿ùÍoÚív¨Ší-ëoѦíèè(x‚Ô¬" ѶŸ½ý§ÁƒF!t¹\ØG///·ÛmÐãëõºÙlF1* I$`ÙM&vëä]ù|žD…nf�Þhu˜t:Ý+lá÷û<Øh4Ξ=‹ e³Ù@ªÕjhA£ÒÕn·‰Œ®¼òÊcÇŽ¡nÃãñ¢Ñ(ä‹Êå2Ô€ …Ö\*ÇÇDZv£LG¾éÎÌÌŒÇãiµZ¨ËÁØ Ô.ÇC]àÂá°ÏçU«Õóóó(.A¯H©Tnnn6 ›Íãùx<åV,‰äèÑ£?°Ùl…BÁívƒ„¦ˆX,?yò$`r(ë•J¥ÍÍ͉‰‰sçÎ!àäãô �ü›êÈ‘#¨@... …Âññqˆ¯G£Q›Í•&‹åv»AÂ¥M'xi4 ‚bE]Êa¼ÿ~—Ë%‘HD"@íB¡ð‚~c ±¹¹IcgÓ~õ)�8|ÚôôôêêêÈÈH_(ÖŸæR…  0¸’ɤF£i·Û¿þõ¯ï¹ç’`ñx<T�ÆrRæ�� �IDAT¦§§ï¾ûî½Uþ-:666jµa°SËúh½`V jDÓN&îÔwÑÁ©c}};b"ªR©‰Ä+¯¼ò“Ÿü䨱cÙlö÷¿ÿ=Hµd•!ïêv»Àô~2Úïz½Þd2õn™ñ]T1 ,p'Ož<{ö,z3~¿ðñ©©)€’q"‘YpËå2"`ÜÑh”Íf‡Ãa·Û}å•W’ÕŸWWW‰˜),qÁ…¼!Žk4ø¨………r¹|ðàA…Bqà 78p�ïP1ê©§^|ñÅf³Y,×××y<^8‹Å,«R©x<‹¥Ñh€ï—ËåÑh'ðÝï~7¡T*Õ‰'666Nž<yâÄ ›ÍvæÌ™ãÇ#ÛˆD"Ñh”Ëå<xP ÀŒå2œ^x?ŽŒŒ€—ó�…Òn<}ú4Ü“ñ.·Û 8âòò²D"!e:»ÝÞ›(ët:£ÑVVoy¢±jµÚív[­V­V{ã7Bÿ‚:? t…qÞÜ}0Ha§ár¹.XC&n¼8rª#óôôtoÙwVïS‹‹‹ŠïûìÛ08¹Ýî}ûöñùü¹¹9Ì £Ñ877‡ó>33311'ÜsçÎÝzë­üào½õÖø‡xöÙg•Jå3Ï<óõ¯õÐCýå_þå¿øÅOúÓ7Þxãþçî­òoõÁb±„B!X8 C¯×à—˵X,G§ÓÌHöƒ4ÃuƒÁ@ƒ½°Ü( X,þæ7¿!Aé8ÈI Cä騃ÍfÛívôÞAàí}~ŸÏ·Z­8ÂÅÅE‹…f ðf°i÷ù|ð§@ÿ�©ø‘H$‹ †L&³Z­<ottt~~¶<ouuO¡+ÉNräØ t¿p  ^ÉårãZ,NFÏ;wðàÁd2)—ËññxîJb±<YµZýâ‹/¢Žói‘†¯×k6›ù|þììì™3göïß¿°°  …Âöö¶X,ær¹HÝ·ˆÁÄæææÆÆ:XFcmm n­ä”"i[__·X, C¡P‰5Bp¹\¿ßMtœ ¨’“¹&µ±Ý™L†ò2mÇ£Õj¡­nÌ™3gü~¿ßïW*•J¥’¼ŒÊéÄLÇ«ïT$3­wР}~—X,æp8ÑhT§ÓÁÖÞ5QççnSˆ«oþä»>xk4‘•¶Òÿï£ ð'8ž{î9>Ÿíµ×þüç?¿ãŽ;þñÿñ®»îúÃ}¤ŽÏž={Í5×ìÅŒ7dH$’Ç{ì¯þê¯P)a“Vçr¹ƒ!›Í·°(»^UrêËåÄæ€:@‚¡*ìq8œR©d0Ìfs0L&“(ëñi£Ñ²Œ/ð~4ЛÍ> èíjµJZ|>ßn·çóyj?cnnîÌ™3äàÀK&“PAe±X›››hÛ4›M£Ñ …ÐMÁÒ¯R©,‹Ïç+‹0ɵÙl8dfÐz�&‚ÑÏbÎd2!ö9rÝ©D"Ü]­VÓétP …Ùl µ@  ×ëu:ÝÒÒä-"‘L1D"Ñææ¦N§¤bkkkttkºÃá¨T*`éòx<·Û‘Ïç£QG½úPˆ€®D£Ñ°Ûí¡PH¥Rs«xL ‡ÃHþJ•«—ÉdZ­åM¸ÓbS‚ÙH �¨ wX¨×ëX1["’J¥ÔéDfZïS»ÃÃà vjîÝ«‚6áN/ûÒ—¾d›ß1O´‰_Þ“/ú¿ñ½ï}’H$Çït:ýèGÿ öK{Pò7|�JþôÓO® Ó9¨Óé€ÔIcZÀÚE€êÒX)|>Fàä ­{ƒ|Z©Øt"@É úÀà"Œ5b±ˆ6¸JµZ ‹`ߟ ümEãr¹"‘w~¹\Fe‰€ŒaëNý@¢œ„0:âA6›Íd2G([U­V¥R)DÄAM …àÖJ%‡ÃQ­Vãñ8œn�`ЍFMNN½‰6b'pq`—Ñn·aJËáp^}õÕ`0Øl6a¢>6›MnH ƒA ªÁ$Ãß$Tär9�ú‰\Hð»°Ââð`Š8<<Ìårív»Ýn/‹år9—Ë™L&ØË¶Z-¼§‘f2‚ŸŒ¿ò@íËl6;N­V[.—Á¯"O Àd€1Tõð‚z½^­VáØÀçóQ ¼à"C­ÈiÇ»zŸÚÍÈf³ðÙ‚¹‰J¥Ú b§b°œ9£G¾h„öãþûï×h4ÉdÒb±|øÃ¾îºëöÎÉ[t ðBÈêT_íÁc€k;H!(caÝÉ“ö!�)€JÞ‡á(Áçó!R� \ò üsÁ£%ïU“ºÆÑºTWSŒ^9jÒ{#ÑšÃáÈd2µZ=44$•J׈Çãf³9O€ð †b±Øl6ƒÕ›ÏçÉB‹Å¨¯ ~9N¹\®Ñh¬Vk.—K&“0à@F;44258¶z€s< nÞðÙñx<—]vZkT:-+:ÔóPIƒ„9ú4étÚjµj4šùùùZ­¶¼¼\©T4M.—ã ×´\.ƒ¸=˜ˆP(¼öÚku:]6›Eq5™L‚oK. dÎáhŽ´VX4¼C8† 0¹” …DˆÁ3Ó‰ÑÏŽ™<µûº7HÇ"‘H£Ñ %9l@ˆj·ÛÑh¤®‹¸‹÷2ê¾ûÞ{ïÝ;oõÕg@�3Xì<mù|>OLr C:îEñÒð:¡F# ý~ÿ±¼0<¥a͹\.pÌXqÈ'Ü»i2hHbôEP§¢~ÇS*•½q×f³Åb1•J…Ný4›ÍR©zrh¨ðx<�,‹N§3›Íf³YêwÕëu|ì—t:]$©×ëøv8 Õëu©TÊçóµZíÄÄV½ÅÅÅ¥¥%6›ÏçaJ EÑjµ ™¢x<޲˜Çã¶¢\.v» ͈n· &,%°/¤1|>_¡P‰D ]u"«Õ ½^ÝqÆy³J¿ßÕWµZ `g§Ó!s†\bxŸ£òÇív»D"±Z­Å“ËåðŽF£(‘H‰dëð98*|,–ò|>uÝN§ƒ6$ÂXÒÔ‹…iÖ7Þ�_S*•@¹íëC¶›AÌ*Íf³L&S©TGE2wÁ÷^0mê³Ü[ËöÆÛr@T ‰•‰—@ À¤b±¸{&c&“A±¨X,<7•„Û÷–&önÀ`ß ö(M=(j¼þu†¼ F@:Ð:Çb±t:ññq‚PÀÈår€/ëõzµZÍf³ID¤:€€ÓªT*GFF +Ž3dÓzO;¶çårôdDßññq¬×v»†³™Lm½^ô„X,Öëõ�›‹¯0™L0z‡W  £¼V¯×µZ­R©Dûgdd„ÍfG"‘L&ƒ+‹A.—S«Õ.—Ëf³aË"P~´X,8ÔÍÍMÀÊOŸ>íõzU*•^¯‡ß.<æÑþ)•Jè}PçL£ÑÈd2Ф‰D‡£X,ªÕêF£‘N§3™L2™ 2ó8Q¸X0/'9(± $Ê …B!“É a6>>ŽíÑ› «ÑhкzÔÀ�g^b¬X,Æîf`R­VÏœ9sâĉ•••J5>>Þ‹¤P«ÕÈm6[o �þ,ä)‘H422òÈœ¶¶¶ >ÞãꫯޥúÀÞxÁ ŒQòˆËåâñxëëëZ­–Ê”ìÛÚ…®Z.— “êÏF}(®}I¸Ô•‹üH$Pñ§ kR«m¤¶6Ø ··r’Ëå”J% ÆˆL°¿‹F£F¢àÔ·”ËeÜ©Õj""‡@ñS¥R95559‹¥T*=ÏÄÄ”¡¡!HÂåÈf³y½^›ÍÇaw Î~~(BNàõz‘ È.`Cí÷û}>ŽV¡P°X¬H$Òl6!M[­VQC ¿haaA&“9ƒÁP.—£Ñ(ŽÜårûWÀá „_Ýn7dâÈɇM×ÒÒR±X<~ü8ŒÓé4ò âèóùçÔ</—Ë “‰Ñh4P'„¤ÿS©T››››››Ð1‚•ƒbw‰î`ï¥Î´±±1Ø;]Ú…1Ð÷y€õºï~¦e2¥RF±?ár8‡Ã±±±&&!]¤íð ÙOô‹Å¢ÉdºÔƒS­Vy[‚ɤ܀üÞxCâõ¿>Ÿm@Ífi·+•5‰â.“P(d±Xããã449Y;™ÉöÞäo©TªV«iq$Xä)bxzÅWœ8qâ‚%Ä|>OZM¨w^'5©ÛÚÚª­Óéðx<@õœN§B¡àr¹0<…°…Ýn7(Ax›ÈC¸\.•JuêÔ©Z­¾m"‘€ü4vÉïu:Ä©}||<„Ãa™LÆårŸ}öYµZËå|>_>Ÿ×étL&Óãñ …©©©¥¥%¯×‹R-Ð‰Ž‘ÅbÉçó‰duuU¡PLMMÁ–wqqH÷¥¥%”û�rÙ·o€ÔN§“ˆJÄãq¤ƒ³³³èóCq{{kî;ÞñŽcÇŽ•Ëe�¸á"8;õ¢¯`‹ÅÂãñggg‘3©T*E\ ªEr8ÞiA€÷|„A{͹‘æµ åóyšˆ~«Õ"²&ù|Oí¤TD&'Žî'ožø„.Þ¢ãĉ¸Ï/v«²7^ÛP(‰„Tá H©ÙlBÄŠ«Xñid&r×AX¡odb0<yòäÅ*Jp¹\ÐK‘Q-·IÎDÃ\P¥ÍaCÇd2ív{,£.Xø-(Fõf Üú|><ËårM&Óææ&êiápxkk«ÛíŠÅbNÇÆÆ ÅØØ˜^¯—Édëëë¿ýío<©9m6[µZ­T*kØØØ€ZÉÃD"ÑÂÂú(B¡¬^j<?zôèÕW_}öìÙ‰‰‰L&“N§¡‡Äáp––– …N§«Õj,+ :Ð% ^ü / †R©tüøq\µ©©©ÕÕÕ••bÒ:11á÷ûq)™L&œvÑ€É:ܶNž< ®U·ÛµÛí@Ÿ;v ¾ˆ›››ÙlÖf³ ˆØH³Ù|#—Ëå••üö£G2ΛŒ0΋3™Ìááá@ `·Ûý~?ŽOáh!dŽÏ'ݯ¹¹9œC·hsïR«ÕÝnw—ú[˜‡¯íæê»O"þ2H¦©Rñƒ7Ž}?m¯ç´7Þ¶#—Ëõö‡ëõ:#Nçr¹ÀÜå�gô)<²¸¸èt:%Éàž01Å@Fs ‡ÃÕjH6`·z?HV‹D"—ˆŒ{c{ž‚3:6¶Hþ€ÂB&$‘H,‹ÇãÙ·o‚hµZ- •JÅl6_sÍ5Õjºæ‰DÂçó-,, áCSÛÒ9[]]][[“H$‰¤^¯ƒÁX,ÆápÔj5‹Å*‹l6ûèÑ£�Àû˜þááaFƒèˆþÙl†Í<L"‘ÈÜÜü™°^£E‡'&&´Z­ÉdJ¥RétZ /ì<ºÝîäääþýûq�Ä5Æx<¨ºAèc9�Cl6iXòù|—ËÅ`0�Éë5%bœ·‚ãããp"FÞ‡% öâ`$Gˆ>&†×ë…|;mÎФE"ÜÐ{Ù{} ¹àt_Ô ÕwföŽt:î fÚ€[l𾩙SµZ}ñÅõzýþýûñÈÉ“'“Éä{Þóž7V¶®Ýn?óÌ3*•Êf³>}šúÔ¡C‡êõúoû[²­s:´zèË/¿Œ¿gggÑè~öÙgêF#JŽgΜU ‡Ã9tèÐ^$xK ˆ±æóy¡PØjµ–––ð8<O/Xn …�YArkýÖÖ–Ãá( 48UT*•j4tSâñ8鈡R©@d±X£££ØãSJ@è@,--aëEô¡»>�I v †F£Ñ¨ÕjZ[[Ž@*•¦R©¥¥%‰DræÌ�çòù|$In&“ —z>Ëå2ìØ”ƒªüý~?úI´Ùl`5AqõÌ™3‘HYÚ{ßû^”=s¹ >gllìØ±cÏ…3V£ÑH&“333ÅbQ¯×ƒ[–Éd¤Ri­VËf³ÐÍår@ĉÅâ••8b˜L¦………n·k2™ Åúúº@ P(†N+2T¤kl6›ÉdªÕjx‹T«Uج0™ÌÞÍa‚#Ÿ`œçTÛ�ÜP(DUÛ£úõ)•Ê\.W­V{ç a‚—J¥¾]LìzL*•¢µû¡×ë‘XïtsѦfšÓéÜ ©ÐãNý°758¥R©[o½õ¦›núáˆG¾úÕ¯¾ð ÀƼ_ôÃþðî»ï¾òÊ+xàçŸþêW¿ŠÅb^¯÷á‡þÁ~pã7.--étº/}éKd'›Ïç>üë_ÿúºë®;qâÄììì¿øÅßÿþ÷ó7ó‘|$‹Åãñ¯~õ«Ýn÷ _ø‚Á`Ðëõ?ùÉO¾õ­o}øÃÞ[ú/ý¡Ñhø|>¬»Q7“ËåÕjU&“õ¥ÓÒÞEœÝçq€4«YðÈ]GÅøQ—-ÄÈn· r.܉zWªÓ(°Å½Áé¢8•À8@@<HDú«ÕêÒÒ‹Å ‡Ã~¿_.—/,,´Z-‡Ãá÷ûçççK¥`Ä&þ¹årž‡l6[,Çb1x¶‚ÅÌãñØl6Ì)L&“@ €<(ÈAÁùE}, Aj¨ÛíÊår»ÝNÎv¹\ŽD"v»Ífqo¬ûÑhe[»Ý8ûÔÔª…°D²ÙlÁ`°^¯·Z-D‡“Ïç!´Ê0‚+~&R»Ý‹ÅL&sddäÔ©Sp‹7‰DB*•BÞ‚–4óù|ø'“I\nЧxÍ<p{••J%Œ€A³£%LTyh4}ñåÔù¹Ëó0 ®`·Û¡Ÿ»Ëwy½^8@Êåò^ÏÃ7µ¬'—Ëo»í¶µµ5#=õÔS[[[wÜqÇEÉ”]p|ÿûß';ÇÙÙÙÇ>|øï|'<2x<“ɼï¾û>|óÍ7?ùä“ÔJn*•úÎw¾377‡·<úè£^¯÷Ÿþ韘LæáÇï¼óÎ………'Ÿ|òñÇ?}úô]wÝuøðáN§óàƒî­ûo‰Áf³iäStGÂáð�mLöwØHö Ü!r8š‹B¡ E ˆ·VîmèÉÒèVاS‹ÅÀ7ø¥jµú‚ÕÀÞPß“Éd‰Ä`0 >‰Ÿ “B¡Ç†††�€Ä D�‚ â:›Í6™LðÍËf³©TJ­VC½Éh4Bõ‡ÃáP]áÃá0€|¡PhccãÕW_e00þh·Û¸X &‰ 4Øqƒóx<‡Ã0Æáp´Zm"‘@©›ÍV*•¤Çb±®»îº«¯¾Z©T¢ˆÇd2þ¶Z­èç'“IxD!Kc2™8h;MNNÎÍÍY­Ö©©)RÈ^;êÞ‡T.—±/a³ÙÛÛÛØd…©©©ë¯¿Þáp�HI}Wï¢O&�I “Ü×°¢ÍÏ ­VÛW”ºõ˜N´©Kž||>¿ïÝ÷¦fN2™ì‹_üâƒ>xß}÷=õÔSÇŽ{ßûÞwÏ=÷¼±Áé‘GùÅ/~ñÐCQ|ú駃Áàí·ß.‘Hî¹çžÍÍÍÏ~ö³çæ›o>pàÀÞªý'2zë]Ùl–F¨ì»÷ìûx³ÙĺCö^H¾5 ‰¡>[*•*• °éF4ò‚¾nÙŒóRu´ B WV«• @ÇØ%(”P#¥Ri«Õ"ŽÀ ‹Öjµ@ àt:A$’J¥V«umm­R©looóù|X" ïv»‰D¨Ö¨õz½ÛíÆb1hÎBˆÔˆ²Ùl·Ûe2™J¥’è¬ÃS£Óé€[Ê8OÆ»  …œN'ˆÌ‰D¢X,BY ¾6~¿_«ÕÊd2Àä2™ iØ@ó¢ÑhLNNz½ÞB¡  5_$ßET8N6›U©Tr¹|xx–¸'Nœ˜žž>}ú4¹ŽØ²€Ýív!¼$‘H ‰E®# *-‹Ñh¤á¿»Ýn¯!:&‹Å²Ûíív›JeM˜¶¢š’søúÇNÐ ƒÕje2™´ïê=<ê0™Lñx¼ÛíªÕ꾑òÍFëi4š{ï½·Ûí>òÈ#ŸùÌgî¾ûîÁ4Ë_ùÊWî¾ûnÈw’ñè£9rä¾ûî#PzµZ}ÓM71™Ì—_~­Î½…ûí7¤R©H$½f@ÕÛívŸ8qB¡PìÄ`§>®Óé°Íår4nY‘!m€­½^¯ÇG©TªÓéô†œÞA„àÐŽ¢~‘Z­ær¹¨ðPEÞˆÿK>Ÿ·ÙlÑht0  ¡Pvº$Xq€ïÊçóÕjUüpjÌîv»:%Æyl=~¿§çu:úpW_}õÜÜ\>Ÿ÷ù|6›Íï÷C“B­Vc±“H$f³9™LB>‡ ž Ú9V«‰=£££Íf»x"¥ˆ¾]:ž™™Ñh4N§'*‹Y­V@H$„B!%O …r¹¼¹¹i·Û£Ñh<Ÿ™™™œœT*•¡PH&“õŠÁ ·Ýng³YµZ-‘HÒé´Ñh”Éd>ŸÏjµ‚!Ž—J¥J¥RȃGFFpe2J…dž ]J® ÙZÑ�2俹\Ž\â×y7õ~„É$ìÅ‚ïtÓ‘4¶#Àgö);¿ùKÆêêê¯ýkƒñÄOÐÎõë÷ß¿Ûí¾ùæ›i©ñÆÆF,›ŸŸ'AK©T¾÷½ï[__Ð=ÞoéQ­V³Ù,Uá­où €+²I’ËåƒÁ`0PeÐç=^³Ù,Äzû=Xy­V+|Â$ …BÂ)–È^Ÿ@Zè/Æyã»t:]¯×ÇÆÆ¨%£B¡@jAÔú^¹\†à Ì)“QˆõQ—•D" …�ÛCd"vSÐk@Dž7iâj4“ÚÉôô4üÆÆ†T*u»Ý—]vÙÔÔÔÄćÃC Õ§×1 ¡¾R«Õ Ž·²²Ç¡„‰Öèè¨X,. …B(â¢G£Qì!FGGK¥ÈårP×–H$Ø@@t<—Ë¡Gˆ"g.—[[[CÑ !8}úô©S§Áå—_‰F£º=—Ë …±±1RÝÒh4étZœ¥h4úÄO,--­®®ªÕjâQÂçóNg¥R …BÔ%ûòË/ŸŸŸ¿ùæ›ßÿþ÷OOO#í½×]1ÚËÆÇÇ/ÊðÉf³õ"ë «0^¡PŠzG±Xƒ<1™!Ìà´°°ð‰O|âÝï~÷úúúW\ñÑ~t'§©×0"‘Èç?ÿùÙÙÙ¹¹9ƒqêÔ©»ï¾ä5*ñ‚T!¨ƒH8ï·Í@ªÑh´Z­ÑÑQ@°oß¾©©)ÚÍœËå666Μ9Cî™D"Aó­@FÚáp8™LîD]„2ÞcÐB¡°{ß÷v»MÈèÆ›L&‘Häõz1?Ñ–×jµ}S"üäx<m$ZÔëõT£V«åõz‘Ùà)§ÓI6pDT†Ž£…�À«®ºÊf³q¹Üåååb±Ô†ÛíÎçó¤¼ …ìv;þ+‰t:Ýêê*ÖÊJ¥ròäIXi@ðM§Ó¡ %‹ù|¾T*…`üpc±X"‘˜œœJžè¾#µZ-‘H„ždp÷ïßo±X4 Ê­[[[H÷x<rM¥RhP‘R^¹\FÅEW.—;99Éf³qŠàòµ´´tâĉßþö·cccØm�—‘Éd ¹„sÕét°óÎf³çÎã\.þZ­¾úê«ëëë‹‹‹¥R‰˜[...6`0Øjµ$ 6L.—K 8Ž¡¡¡ùùy‘H<™™ƒgä<hnnn^T§*‰Psw™Lvå•W~àH$¼3†‡‡iE,ÚØØØ˜žžf³Ù};;ojp …Bï~÷»¯½öÚoûÛæßÿýß÷ïßÿŽw¼c7%ŽÝŒï|ç;^¯×ãñ�>>??ÿo|ã{ßûÞ?ÿó?÷»ß…mRµZœœ¼á†"‘H>Ÿ‡JƒÁ¸âŠ+¬V+Lq°'œÇãétºn·‰DÒé4Hà¦R©H$Âd2 Óbo\‚ 8áž={–ÀÉ]züøqêm hó•ƒi24{ú$øçÙo‚@$x‡Þújrã÷ûK¥¡7îß¿?NSU«±NèšQßí6Ùl–š‘ïJ&“™LÆçópÃáp¬V+JLz½~nnN.—¯®®’åøØ±cÇ_XX@¤d2™<¯Ùl®®®1DZ+• “Él6›`@s8·ÛÍãñ‚ÁàâââóÏ?¿¼¼¼¼¼Œ¯X__¯T*ÇÒúú믟››Óh4Nçܹsõz°&.—›H$^zé¥N§"ÔÆÆÆéÓ§ … /¼°°°�_(Æyçb‹577§V«Ïž=ëõzý~«Õr:2™lÿþý|>ßív·Ûm6›m±XT*•Çã9uêT·Û˜˜ÀV#‹y<ž•••ßüæ7ápxnn®^¯¯­­á„ƒAêR†$.$NN¸333ð3„­Ífc³Ù£Eø…Pä|[•”\1�� �IDAT[[###O>ùd£Ñ€ûðð0q훘˜`ÊÌf³aL<`ŽõîZhÃb±H$j0c(ç’æ%èõz‘¿r¹Ücqq±P(,,,ô ç¿©='7??O厎æóùݸ\Ô`±XóóóH«µZíüü<ª …ÂçŸþ¶Ûn»í¶Û ÆC=ô|�×X§ÓÙíöŸýìgŸûÜçðìÃ?|ðàÁ§Ÿ~ú¦›nÂ#ý×ýw÷w(¸ûÛßf0û÷ïâ‰'öbÀ¥9¸\®^¯/‹õzÍfcëÚû2·Û½´´Ô[3›Íq£ÒP ˆCZ/<F |>?‹‘ µ´1 ÜÇ/–WL€…ëñƒ ŸÏ—Éd½þ¹´F‹½H?à2™ €ÚL&3 bK[*•`§M{‹\.‡„Édj4V«ê«0Á¯&í}ˆ‘“2¾Õjåóù|>iii||ÜëõNNNBBžpm6v/¼ðùRÿ(ŠÓ§OC ë8“É\^^ž™™YZZòù|G $“I@ØÇÇÇY,ÖòòòéÓ§±Cf)™™¬¶0Ž‚G 3B¡pyyvVgΜq¹\­V«Z­buær¹V«íŒó¨˜ä–ËeÂNCû ù"“Ét8ëëëHÐG©TB6¹¼¼<<< úÒ¦T*e6›×××GGG_~ùe6›ÉdR©t÷›Íf¯v ŸÏo·ÛDÂÑãñ й¬ÇßÛ¯Êd2§OŸ+�¶™ˆXcccT(¹@ �Ä»–¾Îd2…B!Tšh´—œ®Çãáp8“““o{ù¢='Ü7|À ÷Î;ïa…Añ'5›Íb±xss“º× …ívæI4ï84™Q±X,›ÍFOduÿQ$ÉårO²Ù,Í —Ä9&“‹Å÷¨ÔÝÞÛX¡P´Z­‹„¥R#U*U§Ó¡~>dU{¿‘Íf›Íf¬Œ #Ó^Í‹Z­†”hrrÒd2ÙíöÅÅÅÕÕU3©¯‡.ù¯N§+•J.—kyy¹Ó錎ŽÖëuämÈl6[$!ç ÞzÕju||< Ž/,,H$’©©)‹EZbÈö,K&“>uêÒ¹\Ž©õz½Ñh =Óh4¦§§y<^*•*—Ë€v¡qäR©T¯×‡þ?öÞ<:²²N¿u«êÖ¾WjÍR•µÓé$ÍÒl"âÂð³Å™™—DDñøõ ‹Ê´pôÌqÆÁAGá ¢¨œDpX¥ÞH'é,•JR©Jí©ªÔ¾ýþxï¼soÕM%½Ð´õù+©[w©{ßû~ÞÏò<Ïò2ôVÒé´Çã‘Ëå³³³*•Êh4 "Ëd6›¥R)PM" "¹è'„T¼N§Á!‹C\…Óé>—7fx:Èp–„˜ ¦OÁûˆµÞ ²ÐS‡§´Z­©TjÛ¶m³³³ÝÝÝ·Ür‹Ô¾ƒ(á¶õœÚvh ªÅ(›Í®®®ò†J¥*•J†èºÆb1¥R‰®0H¡#'C&,HE Lâñx°´GÌÄ0 `˜xÿyç ƒŸhh$ðLr¹å8'Ì;Ø$"y0,<+qNÂü9Z«é©Íl6ƒµseeE«Õ"B¡ž,½e2YGG‡ÑhL§ÓH*º\®³Ï>m{ $Ÿ¥«¼NHDTa¬Õjáp׆êæz:3IœS2™´Z­ iÐétápœ¨,¢€N§ÑC‡U¯×Ár;::Z­V<D"ŠHêB¡Ðøøøüü<‰{†±X,UËår*•ëf¤’’Ã0(y<´o— ‹%‹q‡ÑT*åt: …‚Á`Éd®Q«Õʲ,:Sȇ¤“‹÷…N@€É�Æ&Aª¸µ>ÒVªèåŽF£Y__W(&‹i4«Õ =0Ng6›××× ö7©æÔ¶¶«×ëÂD eU(`~CãÖêêê¨ÆP>A?‘H‹E‡ÃAçôÍdYýWà�%yiÓÑÉ=˜N§Óét‘H„.M+ ˆ”% ×E>P&!WŽ˜>”²D2ÛØ n¦áw\.4Îy7ÊårI¥R¨ñŽF¦×b±¸¸¸Ÿ‡Ú>gYÜN¼ËƒKÖh4@ uuu©T*ŸÏ×ÕÕ…¦A´Ÿ%“Is¸ìžN§‰Žy¾§@@ªxÅb×@ Í  „NŠ%Ñh´T*ÅÂL&c·ÛAœJ¾L&ù aX«Õ ƒV«íèèËå<tv"‘H¥R„°uaa¡Y'°R©„4ÔÂÂB*•?E¹\F*•÷e´D6¬}Ç̆‰Dôz½Çãi±[oÑÆ‰+•ʆt?èÓaº‘úÊf³ÕjΉ'pܶJ¸³³³›•>ý-n–i±m'ÊèÕ(Çq<’†a�  ÂXËCý“¤  æzŽã‰ -¤Uª»Â³ó¢(–e@$Ά A JÇ:àyƒÛ£×ã<.`˜dGô¿©Õj Õj5xÐÆ`)­Ñhp%*•jmm zí¹\Ž„^˜oÛ¶maaA.—ã"¶@6 òÑhTèm@¿øøáp-@€¸sôß#/Z«Õ ›Ô°FÍf³ÛíÎf³~¿’…B]ŸÏOI´ø "` ¤¨"fgg;::Ð>ŽË#53t̃‡i}}܆ÂÒC¥R)‹4‚¸áâ) Þ <z„‰ A¸` hØŒCÆ Çq‹E£Óéж£×뇇‡‹ÅbÃLµÐ2™ŒÕjQëà½G¨0ÑŸðnhºÖÖÖ"‘ÈÛÞö6ÐSy<Žãz{{£õÓÞ9¹ÝîÍ Î¿%¬£££-æô¦4î„Sɇ`釩™v 8#¹ôšòÃçó•J%ÂÕ É�ÃÏcÀ¡ “>™‹þ^µ ÝÌt‚ÃâDð:d/›Í‹ÅÊår6›Å&Ò1ÝB9âŸH)Åh4:@…ìv;0Fà05¼ôþ&äh‡ }­VƒZ9T”àwqvÜO¼8‡³ÞÂÂŒh ‡Ãv»Ýëõ‚»Z­ŽŒŒøý~Ng4ñL»ºº"‘ˆÇãÁtL°ÀN§:³Pó’H$�öjµZ¥h¯©',\Ш"Ì¿¡€‡ûÙð‘¡©ÝårÑ<¼ÍŒn½!˜núá2oè;‹‚v»ýüóÏ·Ùl©T*•JµâœH®µÅ—K¨y2ðòùüââ¢Óé,•JÓÓÓ2™¬¿¿¿¯¯¯¯¯¯³³3º\8­Ó¡C‡è.—3Ì.¼ð¶î)3xò¦õJ¥¢Ñh05 D"‘T*¹9í 2½½½Ðep8•JåÈ‘#dj€¦-™VÀ1šÉd°T joo/*¼‰ƒ0ã. ’⑘£YCà/tÞÒåruvv ¡H$Bû*œˆè®Ò{!s…x+B¢X…_r„z½ÞÓÓo¸.ÐÙán öêëùùùŽŽŽ@ €èñxÂá°PqZ¨‰Dbpppvv«xáO†’xÐõz}±X4 $ñU,C¡Ê<jµºX,®­­ Cpd� I¥Òx<>55…ÖJŠ¡…app°««k``@¯×¿üòËKKKÂ^|Þ Ôjµ±Xl×®]‡¦HBçµµ5R¢k8‰z2�ÚÂ>,dÕj5‰)›y;¼Nà¤ÐëõÁ`°õUrCÁÀÖmjj çÒétƒ!V”l6{ÑEi4š¾¾¾ññq‡ÃÁ,ûOkç422r¦*á"-ÓžN¶I$Üí†:‰Dò·Û ¾ÎíÛ·;vìõ×_Çt‹ÅUV*•]tÑå—_^«ÕÐS^«Õ0ó‹ÅíÛ·OOO#æH$&§fYV¡P`õÍKtŒÍÌÌ@© +++˜ …xIòsð4†aæææè¤?ÎÕÛÛ‡éT 9 ò²dm«P(@!НÑb 8 ¸Ã™7”aéùúرcˆ;÷ïß%<™ÇAê*<{©TòûýµZ îš{<ÐL½^ÇíÅ÷±Ì…B vïG¿F0$mhrÁwÂáp,óz½ñx<ŸÏK$’‘‘âtáŒ3™Ì…^8<<¼}ûvô’ÍÏÏÏÏÏ£· C˜R›­V«¯¿þúàà` ðz½$&ãÍé&“I­V ‹ä÷ò¼tY2™@°L÷ñ¼v»=“ÉüêW¿Ú,›C³QÔºoƒÜ %].W(‚J„1 ¯ÊiíœÚJ¸m;fìŸÂÄ…B¡ƒ”ŸÏ‡É¢\.8p€ÔxQŠH$ƒ! ‚ë¡»»Ûáp(•ÊW_}­ÌP”ðûý===ÓÓÓÝÝÝÓÓÓBY&²L) ´H$xíwìØ€¦Lú‹‹‹•Je||<Nóøë',ÿÉ¿f³Ùf³ÑX“¡¡!‘‰Çã‡ÝF£qbb‚÷öy½Þµµµd2Éq<ÓÿÎ 2zÁ_|ñű±1µZ ççç‰v"‰Èï"³3” óÐÐÐüüüŽ;H:îOµZœœ”H$cccKKKããã(´@Q¢R©8p�²³Î: Á º¨·mÛ¦P(óF/ÙðððŸÿüçíÛ·£ÿªQdþ}C½^'+ oärùÎ;>\(D¢–d2™L&oˆŒ&‰èÒêt:‹ÅBº[a®!‚¼â_[^^^^^&ª»[PÂ>Ç-—Ë‘ïõzÑ�‚5Çq333r¹œ–vo;Û»m,“-(jù¡.‹ˆpÀ©±X,ö‘­)۟ζ²²b4u:F˲$�ª¿mÇoÇMLLüö·¿EwCCÈt"è ˆgÈ[ ‘\Žãr¹\GG�Œétúرcëëëƒ4¬>Ÿã8ÈåA ºè+[__Ç¥R)šÔék&gÜn7HÛèMDt.—Ë!h …Bˆ9Žk6ÙÁ:;;I¾«W^„w пX[[#m€‹år¹¾¾>R�—Ëåè)ÇÏÇå---!ìîîk8縷r¹Ø2p. Äãq­V /….¸B¡�z\ô”—J%€©q(ænlx …T Áj(•JGGGëõúÌÌL¥RQ©T8pµašttt7y~~þðáÃÁ`$WûúúA¹M <½½½.—k||ü¬³Îr:«««&“I¼nd·Û R3‹F£è³�a«L&C3qäJ¥R¸¾”ËåjQŸÉãñ`\y<žÍ²ólHÄ…È^|öV«Õxj�l “Q©Tº»»³uõr,SÌgS‘À©VÂ}æ™gÇ9çœC‚‰h4zÙe—(%Ü—_~™¼„f³ù /\XX éøw¼ã æJ$úÓŸ¼^ïöíÛ…Ñ4QÂ=묳Ð-úûßÿ·Ûår¸ïàÁƒD ÷òË/o;†ÓÍÀ žˆ§§òÙÙYF‘Ür¹œËå8Ž›œœœœœ•ê±cÇЩ…ÉZ§Ó¬Z­V—J%¤ø˜74mívûââb½^W(¨Ö4ô¦àÕN&“(¨ ÀÃûšÕj]]]­ÕjR©T­Vg2Ðɉ¢éÈi³wÌ`0°, no®rpà`Y¤�è¦[K 6˜H$°‰¬½Òét¥R‘ËåЊF£ÐF£(‰»\®l6‹Å O877‡¶¬©éŽ’ÉÉIè¾²ƒþðdOOOCðÐápär¹l6K‡r¹\­V“¼¢Þx<~øða›Í†d#ÐÙàCB7#ÉG©T*´Œ›L&x\N׬W…˜8,•JÑa´3h¦iëp8ÀÆ$~|tå ŸÏg02™Œð²Íf3H¡¶\zP*•:Nü÷®­­•ËeêfggQƒO§Óïz×»½å͉œVWW/»ì²d2ùáŸ|á _€ˆ!þ;ÎÈéóŸÿüw¾óF³¼¼\,-Ëí·ßþôÓOçr¹ïÿû…BáœsÎyà~÷»ß}å+_Q*•ï~÷»yããÛßþöøC†a~ñ‹_ÌÌÌœuÖYO>ùäç>÷9Fó§?ýé׿þõððp ¸å–[c±Ø·¾õ-HM·#§Ó$rzì±ÇÊå2ÇqÐS§¿€&+²|”FóùüÐÐÐêêj©TVŸä–e2ÙÊÊJ$Ñh4Ø´cÇŽÎÎN¿ß?66L RpR©´R©@¾j°èœV( «Ê*•Êd2¡AW’Ífm6Çqô*›ˆ Èd2èBåóyá2?¹K 4æE²åÇuvvBÛ·££ƒGvŽR?ú¶- ¡�$¢“rv»¸pH•JH[ævg„€ñx\£Ñ†rÔÏ ”A~¸ Ñ»Z[lÒét …B.—á\‰D¢T*…B¡mÛ¶Åãq…B±.•JEàGÈë¢ñÜ ôô£oeÙL&c±X¤R)†J8Fû‰R©XÛ`0€äùçŸ7ÇŽi-¯ë’k'AÃøLd °¤R)†PVf³­:F.—»ÝîíÛ·»ÝnŸÏ·eçT.—×××qÀf9C½^š«b±h6› šqþùç+Í$r:ÕJ¸Ÿüä'§§§Ÿ|òI†a~ûÛßú|¾Ï|æ3'JlpïÞ½~¿ÿšk®ùö·¿}Ï=÷\wÝu‡Þ»wïûÞ÷¾{î¹ç¶Ûn“Ëå iÖv‹Å¾ÿýïïܹóž{î¹ä’Kzè!ŸÏw÷ÝwK$’{î¹çÚk¯=pàÀc=¶wïÞC‡]wÝu÷ÜsO­VÛ³gOÛ1œnFxZ ¡F¦ŽÀZªÕj$î¼^/M[ |.þ^\\D„T*5½½½à̾袋z{{‡‡‡Á f±XdYÖét¢m³D"A”p‘Ç@†Ú �ÿ …@ P¯×Ay üEH^‘5)-­K �²hµZ¡.73Pcʦ»q@ü=00P«ÕõÒh4&“Éb±¨T*¤­*•ŠÏ烢®ÑhD81ü@< ‡ÃD›S"ÉAÀ‘ÕDËÿîîn¼­ …bff¤·�«¢¡ßf³©T*‹Å²l2™Ä&’¿YYY¡ï°Ãáðz½€j †Z­Ç�$2ž/n`"‘XXX˜žžN$‡‚UˆoðD™lçwCÒ–þ„�·7e`]"Å' šy¨=j[˜ÊårÀM///s Œ7“øU¯×üãÿñüôÓO_~ùå¿ÿýïý~ÿ'?ùÉåœ~÷»ß-..ƒÁ›o¾ÙjµÞvÛmôÖ¿ù›¿Á7ß|óK/½ôàƒ¶gð3غÒÙøžZ­‹Å†††H Å`0H$z¢ä8nûöíJ¥²P(8“É p"*1??xìØ1°‚®­­ÑŠPä2°t%—ÇK<vuu±Ô$) twwób/úwÁ�ßQ«Õ¤ý‰Þ*¾‡ry,…+D_5„kјGVâ&“)‘H@Α|ÔT©T2›ÍèÕ&0LZ$—öš<µ{œ+ ö t: ªa~¿?c­ ^4Dd³Y£Ñèr¹´Z­Z­U"<ÉÉI¥R x=ûÓJ¸ñx6æ 6œ(-’˼D£3c•J…p‹çµ°4 ƒD=YäËô½%OäÄvüf2™o …ñ¹âl±|Ec<b²zœÃ0ƒƒƒ7ß|óÃ?ŒRÐÿûÿ‹ b×_ý•W^‰·ô3ŸùLµZE}J¸ Ã|÷»ß%b¸m;³­\.+•J»Ý.„Üóü”â8@üD¡P°Ùl„LÓjH¨6™L&»Ý>44 »P(”N§%I<ÂQàE¸X,™Ôµµ5½^ V|‡n7 ¨É\.‡‚÷ÂÓ^@w‰2›Í`­¥7‰X>ŸÏårpœðÊDA1h‚µµ5¤@¡~DND<épK&“d+Ÿ q^¶Êh4"mHîÏ1Ã3©A&§Ó pÖÙl6ƒÁÐÛÛ‹ŠàÑ£G±µ¯¯/‹uww£ÀC4)Ö××i”(Cás›Ý@l¢žÈ†ÝÞà†÷â}Zì<è®°Ía³ ÃVl~~Þh4Z,–W_}5•J‘æøkBtv"‘�ûF<‡Ãvëð›æœ Ãõ×__­V¿óï|å+_¹æškxÞòxlddddd„¬q^}õU8§÷¼ç=ÿøÇo¸á†øÃÏ>û¬¸þUÛÎ#³í†+¸X,–ÏçÉôT,Ãáp­VëííµÛí€ïäóy‹ÅÑ äîA6 ŠÒ•••cÇŽ¹Ýn}É0ŒV«5›ÍKKK ^!==ƒÁ|>¯P(÷g(4L:–J¥}}} ñéBº P?lÛ¶­¿¿ßjµ’ž!ŒXXX —Ñßß(GØ:(\Ñ#¤ðx<´Z82�™CÓé4)?¬¯¯K$·Òé´B¡�Ú‰>ò†-ΕJ$årÙápÔëu­V;22räÈ‘ÕÕUŽã>ô¡õ÷÷£Õ¢^¯ûýþƒöôôèõúh4ŠS�jÆ;;0³„bœÜ[ä‡éf¤…ÌÿE1 cz¢ÝÇŸ`6j¸—ÈÓ?!–J¥þô§?!údYlô'Üðô0Êiíd2É£ä`ÞâW½^nggç ôL ÃÜrË-ÂeŽÃáØ±cô˜›õY”¶1Ü ÙyÙc›Í%ºB¡�0 Ùd·ÛÍfs¥RY\\„ìÂÈÈÇq^¯×ívK$’J¥277çóù&&&¦¦¦�¨¬Ÿ{î94ƒ1o@|²Ù,¦3¤ËH©@©T ?Y³K$’R©D¸È‰ÑŽ;êõz3:Ìt ôÄ'n·[¥RÍÍÍ=÷Üs"ÿb±È#ÉõûýÐð&ºtþ­áA–——§¦¦Hô“Éd„3,¹†J¥bµZ¡pÁ0 tA! G_qä àmlllÇŽd.‹F£jµZ·¨`uvvâŒ6›ÍívwuuÙl¶÷¼ç=E>Ÿ/—ËÁ`8]…B8h´ûý~ü"rå™L†DágŸ}6©™5 D°Pn9Ñšv€¸çÔìaÑÉ'É@xâAÒá|b x BRE¼uÃEä%™¥ÒáÝÑÑ©•T*ŠÅ"(‡î{á…ƒÁ}ûöuttäóù@ €n”µÃáp ˆÅbPî©Õjjµ:¢NŽ9®m§qW*•ŒF£V«Eë-M+G§¼Î¤¶ÀettÀÃ_|­¤èÙóù| ‡|»F£Å2P"‘�®ˆÞ8�úx \bØK¸„‚6‡x™±þ&Ùàà Á±:^™D©TºÝî¹¹9² â¤Írò>Ÿø{˜­V«(€ƒ`bC4(q]@ƒ2o`Œèc‡Q*•xįr¹üõ×_§Ÿf__Ä/°Ø…°E2™L$pó‹‹‹>Ÿ/ �zìv»‰B <D?6¡‚Î yv …¢§§GДJ¥ÉÉIÒ±¨2U­V#ðgHZ,žÂH3ÿ´)Ø,Þ‚-{ñ/€UDÈQÙ⪱•¯½9ÎÉf³{î¹-8öÍo~³R©Üyç ÃìÞ½û'?ù Ã0÷Þ{ï÷¿ÿý矞a˜§žz ÃW«Õž{î¹]]]tJÐápôôôüò—¿¼ùæ›?õ©O1o(á>öØcøÀðÉç?ÿù/}éK|ßûÞ÷†9÷Üs}ôѶ?8} +ÓÅÅŵµ5’¯ÆÓD‚ÝÞ‹h7ôÜD&k‹Å¢×ëÑ_IJ,ð"H±, õ •J…~<¸ä@bC$ }®†‰ÇÓÐ¥‰ŽVéóù<îÌêê*PŸ"³¸‚è01 à‡u>›Í&$ä&‚§ô‡àtW(DÌÛn·C]‰(à %=Ð Ãôôô@a]*•Òë÷û�²¬‰äì³ÏÎf³ápå ƒC¡R©„W  YˆÃà¡ÐåßÙÙÙ0p)‹´g‚:-F£Ñh4¢rcµZQq¤ƒBæ>”Ai Êm½„Ñ"Þ:ä\¹\Þ,1’P‘¹á#>k+áž:k+ážlƒîµ×^‹:°ªÓ‚õ€ã¸t:ËåÎ9眅…šËÆÆjµZèj£Š‹x% y½^€p•Je:ü…׈ÕP$w F�•¼Y†dK¶ xŠˆ°EØ2ŒV5eDe|e2™Ûí¦–V«ÍçóÕjµ··wii ½!týMF#lltP.—cYÖn·G"4Úy½ÞT*5::‰Dý+‹ÃÃÃÿó?ÿC_<2½©TJD‚V„\\hN§3•JE¤ÓéhJ´·„ÃaµZÝ"•CÃäÇqÍÔ+è;V(À/✤R©Õju¹\étšžnÁ¤RiOOO*•*—Ë ñX^üm·ÝÖsÎÿG”pÛbƒm;­\.óJ)©'«Õ*—ËF#Ò>ù|3x,3 F£Ñ`0€€¼çtQÁjµ•J¥VVVVWWãñ¸J¥Êçó‚˜)b©sÎ9ghhˆÎhµZèÊd²ÍJX–zÉ`0( Œ J£ä_\¤øyTf‘H„öL"WÈqöå]]J¦‰xá0¡È@J¥RÐËd2!°d}}öLH»!;Dz ‡Õj]ZZr¹\‡£···R©,//§R©žžzX™�� �IDATž±Z­v»Ý`0Øl6£ÑˆèVh =“ÉdöH*•Ò"¡PH¡P•JE‡8J¥’ã¸åååR©´ˆz4ÈdÃC§Óñ±ÐH$’ÙÙÙÍ’5KÖ»ÝÎÓ`¤Ó¦PCm™ö¶±¦V«A@2Z�Ò"›§Óé¬V«Ñh,‹ëëëàÏÉ"‹Å²¾¾ÎëÈŠÅbÀ~ªT*� »ê÷û9ŽC¹Çã©V«]]]£££ãããDW:H…rS8MhÆ“‹’”J%:k× [hWW—ïŽh—ÀfyÀ¦*Äß�Ú¼°° ÑhŒF#}R—ˉ‡B¡À²,Þ¥¯P"‘˜L¦d2©Õj‘ëS(çŸ>Z+#‘о …‚צ‘J¥€›ššBAφœ ô5ðž#þå­èÙ_(ÓÜJP‚?H›~GGGC x²Î`&ˆ3þ1œõ¦‚æfôù|Í<­ß0Úã¡¶ÛJ¸§ÎÚJ¸§Øèn=Q¼…t¨$ÈåòùùùR©Dæšš·Ø,—ˈ¨ …™ßIŸ•Ùlžžž~×»Þ.·ÛËåB¡¦ðPT*¡T]Ã%s¡PÐëõ@ÂbÒá8x¥R™J¥V À$~ðfR­$úfØ`R~Þ ƒœÐÊ„=`’5›Í¡P¨X,,E ,‘Núa Ï÷â‹/îëëƒë ‡ÃV«unnNx·áêàõAò¤r¹l6›I?! } q¨8èVy£†Õb±` Äû0í ³|ä¼*•J§Ó•J¥®®®R©477·ív»ú¼Ÿˆ²½eƒû4™LÍÈ–š­#±Ë[À9µ•pÛvüFO‰P©Õj·mÛ ©Íf“Ëå~¿_¸Xæ½Zjµ£˜kòù<èõ¾Ÿ^¯7 ™Íæl6ûÜsÏ‹E’j7›Í )jå'@„U1² dPRjVUÎ ƒã8:Tjæ{N¥õ÷÷ƒz•Üÿl6[.—ÑÈ€+¬Õjƒ7Ï‚ ÷?›Í3ÛÕÕe6›5Íúúz ðûýÇŽëééÙ¶mÛÑ£Gö+§Ói”gàq”J%íÚøÍår(¹\®T*…Úbõ¨Y¡q³:~`®#måxúõz}ËE,ry'ö±æóùVbwÞJ(›ÍZOgç„´µB¡ ‰ÎÎ#í¤m{Slee…㸣ÑèñxкɲlWW×¾}û†††x iÿg'“ f<ïîîöù|CCCBDˆÏçƒÈÓÔÔÔàà /1xìØ1á J¸$Ź[L^¼ø/™L‚×¹ˆ1íçZœƒ†‡‡§§§·°ŠEá¦ú ¡ÐA;\$ý“‚©+• ½žH<Åb~¿¿\.¿òÊ+ YN&“4 Xx[„¾œŒ‚¾¶»»4‹ÁÓEcÞ ¶²²Â»àfNhSO¡éëõ:‚<“ɤT*%I6›Ý²œà‰ŠŸ6ët…è´sNðIgž˜SÛÞ\Ÿ››Ëf³*•Êår'T¯×§Óé……,D– …Ó霛›C;C8öù|µZíì³ÏfYöèÑ£ôTNÞÌZ­ær¹h&‰DÒpž"J¸dÆYS ¥RIû<‚IJX,¼Mô¼Öâ½jØÜŠj¥RÙ,ç ~&=— OÄÉ%32½W©TÒëõáp8“É(Šp8œN§ÁGÇ…(·-$ÁŠ”ÏçI’eÙááa҃μ¡Ôßß?==ÝlîƒJ/†ÙlV©TèBÔh4à»h,}—x÷*•J¥R)|844ä÷û7ëüÞS«ÕN§Søöµ"Úöa‡æ8½ãà™îïï¯×ëKKKЕËå"E±XDP…‚0•Àóëtºþþ~„ 4Ö3ïË/¿ÌPØÒþþþ¥¥%á”Á›È¥zCK&“t×�Çqµ©L]3fC7æõzWWW7Œ½ŽŸf¥««kmm­•rûú믓¨ 3(_Äb1qÏ*¼¼çÈ0L&“™™™áu´ÓpZÒŒH²5Ã# ÷‚Ñ¢–æv»;::´Zm8–J¥Ó¥R)øŸ:::Ép¢/X$pº ØV«ÌAÿëÅÛÓVÛþBlxxX.— …ÃahCd2‰Dâóù^xá‘ÝpµK÷ 9ü >’ȲZ­ …M&Jß³³³Åb±»#ý¹L&#™m,¢Aø&•J»ººúûû “·ÇãÙ°@ rz­ <І7 Øä*yž‰lÚ¬qÇ£!§mii‰öLR©T«Õ6Lò+•Ê®®.lR*•CCC¼>±h4ºººj·ÛÅÛ¯»»»éŽ;¹\ît:¡‹H­¡:_³P�TëÍêxÃI$çùÄO„B¡Z­}z2œÐR833ó–ˆZ±X,Æë²9M#§C‡ÑÝz&“émo{ÛI=ã³Ï>[(ÞûÞ÷¶'ñ3ÕPcF£±XL£Ñ ¡àÈ‘#è¡_i®H¢Èàœ˜˜ q0tD"‘èõz¤þy\v»½!zJ¬XãC Szö‰$;wîÚífffvìØ!^cÐét‹…dN¬Vk(jø“õzýúú:YƒC�°aÀ4[èªÐét¨â´òe4#€”G–Ïç#‘ˆÁ`ˆD"F£‘ð §xòwC˜0=\!Ç) Ú´K³^5Cƒ£T*5KrÊd2z8Ášé ¿øâ‹ƒŸcAÐJŸgC_Îl¾ô&Úiêœ~ðƒüìg?ûèG?  Çã9yÎéÙgŸŸŸß³gO.—;óú×ÛFÖ7@�E¥R911qôèQ½^ŸÉdZÉD Q½0î�È>|¸õ½è¹ŒŽ–——±¯T*\pÁŽ;¤Réää$éGKÄŠÅ"í šñå�ƒ¬ÑhÈVÄ…l¹ä¾)V(ÀÉ`^ °¾¾ŽµÅêêê†mÓ‰D«ÕnØØÖì `¢‚gE©¬¯„8OV-Nˆ• oV&“i˜~Ôétã¥V«7dˆhh …‚W¨;Ùf4Ñ{ÙÑÑÑbÐùpN°/}éKÃÃÃx9ïºë®]»vÉåò—^zéꫯ~òÉ'±|èêêúÄ'>±ÿþJ¥F‘|¿ñÆ¿ûÝï2 ³}ûö|ä# Ã<úè£xårù—¿üeú,ù|ž(I·íL5:ECŒ´M&“‡#‰la @R¨á¦ ç„æt:WWWNO@ »»ÛårÕëuR€f |‘Þt\!O(ŽKŒF#™8X–EüéóÔ¬Vk82º ;‰Dât:释£B¡P¯×ÉêS«ÕÕÛÑÑÖG2ÄãšD| pZÞhÄ¡�÷Y“M Õ[ÏœúÇGˆ-ΜȉgÁ`ðÞ{ï’ÉdGäþ«_ýj.—ûÆ7¾ö_üâøÀ¼^ï]wÝÞþö·ÏÏÏßqÇPß¹ãŽ;Þÿþ÷Þzë­…BÉݽ{÷îÝ»~øá­1ì¶í-a5ÙÕÕµ´´¤Õj•Je<¯V«Pfj±›‹'’+’ñ'€ßÖM¼~`³ÙfggÑÇFWVV0¥Š_99&OZ—yƒ›xaëÖ°´'Ê:::H×;ÁçÒ \q«×ë¼ÛX.—ív;øã{{{ …ú×q@úÑCÀ·áaÕj5ˆ‘Z–¶20ö|8m³•G4m§ü ‘ɈÒëõ2™¬E¶¤Óº!â‹_üâ•W^yÝu×áßcÇŽuÖY<òÈu×]÷ÃþðSŸúÔ?øÁh4úâ‹/2 sðàA§ÓyõÕW †½{÷^}õÕ—]vôx âòîw¿ûꫯfYvïÞ½íÉú ¶f›úûûáW€ŠÍf³…B¡»»zt2zt²…ŠK___3Z pÑ6Ûqff&†Ãá£G¾üòË™L†eÙµµµh4*rñ´´.¯£(×VÔ‡c Œp0Ç®£m}}̶½½½ðêå}S¥R5ì8à=”L&CIС˜J¥H^·c)6ñ`Ú½½½­z½Þf³5ôv„ƒŽÀ°6 §M§Ó'uc±X6Ëô¸5ƒvÚ™9}îsŸëííå8žö¯ÿú¯o»í6ð3þýßÿým·Ý¶)æòn¸Ðñf m;3L<=R­VûúúæççÉ AUúkàÙfÉáÌx£N¡Ptvv¶Nê ›pn¢g"üÍPtp‘2©&“I¡P4 }„/ onh‰DbË“àêê*öU©Tv»½a=†ÞDû~ÒË€¦pÒŒ ‘H¶mÛvìØ±+¤H399™Ïç…š¶ Ãp×ÕÕÕì9 Q¢â‹7fðˆ‰a0* •Èi(­Kó!¸ìåf;&ÄÉËO mjÆ>­S?jN�‹˜Ífø•O|âO<ñÄþýûÓéô;ßùÎvçw^xá…åryk ж½UŒÌn&“I«ÕÒIHÍb$pZa2-™L6|W‘ êììÌår$5Q*•Zj^m+++õz]|²XØRÞ{NølNR]¡Å9Š><@¥Ç㙟Ÿ—J¥»wïƒhâàÝÞB¡Ð0—Õßßïóù¯í­^¯ÏÎÎ6SPÝðæËd2¨yÑ—Q©Tš=dž0©fµľäûALpÖ@L“‹'ßcŒŒlÈ»àöÖ|Ì)H ònË[>­×Ì ˲Z†8‹°ÑhT«ÕHkœwÞy lÛoÉdR8å|+øªæÖœNg3?™v:iÎÌÊd²fY;Þ:a–e‘òbYv``€FóMô Å4Çç"7u ø±4 úËΡDÓ–Øôôt¹\®×ë¹\Î`0 ;^ö¢Ùzýõ׳Ùìüü¼ðw5ì±ÎZüúÑU¿¸¸èt:Ië‡D"®×ëÂßŲìöíÛ[¿?}}};w«Õ*¦f4m‘çÛÛÛ a‹ññq²ïé=ztÃõîá‰�ÀiµòM¸yñ½d2ÙÎ;EUÞJ‘“×ëݵkÁ©iµÚ]»vuwwãßüàõzý‹_ü¢ÓéüÕ¯~uÓM7=ûì³»ví‚pÎŽ;ð°u:öºöÚkK¥Ò}÷Ýwß}÷íܹ³aÍitt”‡OnÛ[Ô$ ‘µÝšKYëˆä áol6[2™?;dÙfgg¡°·ºº iD:Ðëõ á!Ÿ4ìW«ÕHñ‘™‚eÙ“ÌÔëõýèGóùü‘#G„¤‚"íÅbñ©§ž²X,2™¬!£9/ËÇSŒÝprÄÜÝÝÝ ‘\‘V«UÄOtZJ¸jµÚb±ð4*•ª!¡C3jjèR©�o jñÙlV£Ñà·p§R©Nqg d|q1 …Ân·‹óÖÜNg4Å-%{q:yN<xpÓ/ò馄û—cm%ÜnPÂýìg?k³ÙÚ,ðP&“)•ÊfÂ6ÇÉd²f]””7”bþ/>W$= •Jq.Ë“íêêZ]]%³€^¯ß2H“—lVæõz}OOÏ;ßùÎb±øç?ÿ¹!„‹\!–ð´›T*•‹…Çû'<‘F£éèè…BX›Bt¸\.cº/‹ƒ€\Ü%›Í†ÏK¥’0=­^¯×»´´DT»šµ×ólSJ¸[Ø«§§'›Íâ‘ ¨Õêx<Þl $—Ë o|ŠoÊ\.W2™Ü,QzC³X,Õj•\U‹w£­„Û¶3Üêõ:)Q�ÄPÒ¥:'^¹\N“�ñ¬T*‰ä^t:ÙhÐ ’僌oÃ+Ìf³t„‘N§7噚ÉÝ6ìÍÓjµSSS³³³ ›Äˆè*î’P«=ÜžH¥R¡¨ÓépÓÜn7Çqð»¸È#Éår¯× n¯×ÛJ©TÊåòd2I‡SZ­vpp°¿¿΀¾ç`™¢m žiýd2É(f2âfgg>,K¥Ráø4 ¼4©Ñh„Zñ†INÚ€‡;!ï`<§ýåÖîaÛ9µíL¶t:�d¯"Õ €7iñÀ†nO$×DÃ3¼i,K¶Öjµ†Äá¼s‘êq("sk>Ÿ§ÝÏqv÷4“» ƒBÕ`0X©TÀœm·ÛyX]r%¹\s“H+ X·™7p¬Ç‘é5‹åóy‡Ã !!˜Ífe2™ßï‡Ûõõôôœ}öÙ£££jµš¾·<?/Äpy.pttôâ‹/'‹�ñ_‘1Ób$J{A™LFno"‘h=Ýp|.//ó.ÿ¶ò[”Jåqb®­V놋̈́ÛÛΩmmcb±Ø†`¦ K5ÕjµR©X,÷°,KJ¡„JGpX,–T*µ©e©PÆWhv»=“Ɉ7y÷ôôˆlm&w+„²ÒÓ™T*5™L<øÎ¦ $¤¶A\ù±jµº££C*•¾ýíoß±cG4…Rj¹\Æâ P(H$’w¼ããããÛ·oN¥RPSä¨R©ïO6›­V«N§³»»»¯¯ž•HëZ,–q]-–÷x—Q.—銗ÝnW©TÝÝÝ­¸4tð0Íø‡W*•Âáð†Ýqôßš•J%—Ë%ž–ØZ´-™Ñ¶¿Ç¥×ëõ ëÖ¥'šz½¾a‘ »löj›ÕÉ4Á`ÀÔf0@Ì#rœVj`0‡ÃßÜÜœsJûÚ}ûö ˆÌGF£Q&“‰$yAÍ«ÓéÀƶcÇŽ‹.ºÈëõÖjµD"‘ÏçM&8#L&S8–H$ …ÈåH$"•J!JB¹ªÕjÀÂxO$©TjbbÊÂhy'Þ«•vŒVÆ Y¸ðVtÖ+“Éà†·Òi],yîD*•f³Ùf”‰â®eSØ£†É‰ [·¦¹|Ú9'ŸÏGÄiÎH»øâ‹y Ÿ¶½µŒžéZÁ±6Tù<ž³“£-..nxäÖév‰¾ WªÑhFGGÑNF zç„sÁívg2ÞY òG"—Ë=Ïìì,ö6ñ;ÒˆÌ²ìøø¸×ëÕjµÓÓÓápØ`0Äãñ¡¡!ŸÏ©Ù½{÷¾÷½ï}íµ×:D /_º¶¶ÖpÆÏd2üã¥RiGGÇÊÊJ¥R¡Cú³,;888==½¹”ÔföB§F‹€hâKˆzr­V[\\|Z›5§vΩX, œuÖYgÞ¤œIM´íä™B¡ðx<"*­èºnÊNø›uJ$dKvìØ)^½^o6››!IQhH ‰‹ç-¢Y–u:gÿþýtA»R© ¶‚ÕÕUáxN”år9÷õõ¡W¥»»²­ôw"‘¨Î9ç©T òoDJ¥rii©««+ år9ÜêP(4«Ýn_ZZ‡´_Anpuuµ¿¿eeiUüØJ¥¢Óé …:ï¡Ù,ñE‡bpºýýýhýoøÐ% o¯fc†Ù$.•6‚ê†l³»ŽŽNLLœšA{†8',²áã™dû÷ï÷x<.—«íœNÁ§¡g‚æ©F£!½æbïÆr¨ÍcéL—Õjz… wlh-îåv»××××ÖÖ€.‚�|3Ϥ×ëÕjuô^¯7¼M(Þ …õõõ|>O+ÖËeâ™PªNpf³™ã8ž)N“�«á•`²ÎçóÙl¶T*ÍÎÎ~F-‹ÓéÔjµårùСC¹\®X,¦Ó郪TªP(4<<¼ººšH$FFFpC@:Ž(ø Žã<48cµ’q¢³²^¯7›ÍMEÎE °Û¶m›™™Ù0—ÛÑÑ¡Óéx˜åÖÇÌq†JSSSÛ¶mR"zk&ÜnˆhÛ™i<íW2³0 “Íf7ôL %wëõzY–QS]__z–eÅ›š]6é°·@ P(HÇqn·[$¹×¬ !ܤ×ë½^/Šöóóó¡PÈf³‘FmºcÛl67áM§Ó"“>O  ¿ à ³Ù\(2™Œßï_]]=pà€ÏçÛ¿<×ëõhþîïïïïïG|¬V«———Ífs(Êçó,Ëo¡ÕjûûûI+ÔiK¥<Ó–e|}>_8Fw;ÚäÈÀ mSSS­xŽH$ÂóLô˜á8nkWØ¢¡ñò”FB2YC$†R©lØÎ·¹Èéå—_æ%‹=ÏØØØi87e³Ù§Ÿ~ÚívŸsÎ9 7áï‘‘‘¾¾>†ažyædN­VëE]Ä0ÌÑ£GÉÐÙ½{÷¦˜•Ûö¦ÇqF£‘·xG8%Ž´¥g²—\.·X,›JžÔjµf|h"¨ÉjµÊKiµZˆö ¿l2™ÖÖÖ*‹ æÍ"4ívûøøøþð–e}>_©TR©T¼Ö2’åkÖv/.’ËSÂ…hÓÒÒ(Òét0ìééñù| .—K­VÛív¹\^©TX–Çã„"n½jÛ¶mÒ?9NÓÌPâ¨T*@õ‚eªa;ƒR©D*r—p»vízùå—ÉÀ€î”\.ßr‰‘3Xl9ÄS4>L«ÕšÍf!æ‰h:—sšœœ$%¾H$òè£~úÓŸ¾÷Þ{O·‰é'?ùI0ܳgχ?üáýèG¼õ¿ýÛ¿=øàƒïÿû9b±X¾þõ¯OOOßtÓMï{ßûòùü+¯¼òíoÛjµ~ík_“Édýýý?üp(ºæškÚ3þ[ÈDðÿÀ±6tNÇ©ÕjálÞL ·™Y­Öx<Þ,¡ßLA•gÒ‚z½> ãò�µ~.âÉÎ9ç„5]­×ë2™Œ¾“­�*ÅÉ/xNËd2ÁÇ�i[.—‹Å"™­°Éçóoxµååeá´ ¤­PîÖ`0 …l6«ÕjQÇR«Õ¼ÞkÞØÐ9‘1f±Xh”V$ÙB¦ðçÏî&—Ë¿s ÜBMKhÈÄn"ÒÚÔÑ ej:¾õÖ[‡††vïÞýÜsÏ=ÿüóøüK_ú’F£YYYùáˆO>ðìܹó¾ûîûøÇ?þï|‡a˜ááaÇóÄO0 sõÕW#p9áaS³»Y*•öìÙsÑEýë¿þëüÇ|õ«_ýà?øàƒF£Ñ;î¸#‰œ{î¹?ýéOÏ:ë¬çŸþþûïÿèG?úôÓOãßh;§·¢ét:‰DÂ{%h|«ÐšaM …V«m±)VÛ¢Ÿª7BÂckw`S>•eÙB¡0??¢/Ò$z½^«ÕŠšv»ôï MD/˜¾WèË'MkØ +‰ …¾¾¾õõõ\.×ðD$©ƒW¥RY­ÖT*E©KKK˜¬…ž‰\¡Z­6 Ĺ:Îp8ÜpЇl±T*¥L­V2—t+ƒÜm±X”H$‡£•…Ïär¹Édq«›Z¸°,k³Ù6D§!ÄMù3™L&\ ´Èõ¿§ÞÂp¯×ë7ÜpÃK/½´gϹ\þµ¯}- üò—¿¼ñÆ“ÉäM7ÝôÌ3Ï LMMÝzë­“““>øà¿øE`#î¼óÎ'Ÿ|r``àÏþó-·Ür2ôg¯»îºOúÓí©¹m•JE¸†<%0̆):]ãr¹ÐÝÌ“mÙ#¨ÞX,¶©•¸ÕjmÈ峡%‰×_}nnŽþ] q¬Âû&ô÷¸ q &™y¸cì…‡¥×ë¥RéÜÜ\©TŠÅbµZM&“ •»ºº¤R©L&ëëëCz¥RI&“Åb1‰ˆL²¥R ÅžjµJ'Q!Ô,ƒ‘H«0\˜L¦L&ãv»…KºMwk TzÜZ­Ö °Z e6üN&“Ù,‡2°êâßq84?`×'À9ýã?þã /¼pÿý÷_rÉ%sssçwÞUW]e2™~ó›ßär¹§žzª³³óª«®yùå—áÃ÷îÝ{ÕUW]vÙeËËËétúª«®òz½Ï>ûì ¡,l[Ûš%^„1´ˆà©ˆñöJ¥RÕjµ™'kPi0x< R©t³Ê 3d“J¥hiÑ¢Ñ(ïwår¹ ¼ÉdR8õ¯¯¯ã2Z 7ÉÃêêêé\c:†‚j&“Q©Tˆ´jµšpêX[[«ÕjR©T«Õ®¬¬øý~òô½^/ Ñt:Ýn§wŒÅbøÉÅb1’½Džc"‘H$ƒƒƒN§ÓjµbƒV«uaa¡^¯órBDîvll,‘HÐJ¸0‰d2铟 ®Ûã$µZí83‡ü,œL†‘†$ê†>v`årYšoÅ9íÛ·O¡Pœ{î¹í¹¯mg€õööŠÐ¹Š8€Z­ÆsrN§Ì¡™L¦ç´¾¾Î› jµZ³\‚T*jq–'!H­VÛBIè¼=H¿bC³X,",º"‰Dx¨ÒR©„¹xaaH¦Z­†éÌb±Û^*•Ž;–J¥Ôj5Ù …†††8Žëïïo¨�× Ë²ìØØñ4N§“PåÖjµ………ÉÉIB™šËå”J%ˆqWVV4 é½ìîîF¬2b·ÛÍcÐf›BR:ÊT«Õ;vì8I/ˆÛínØ“)ô­´l6Ëãs.€6çœÊåòW\±¾¾¾oß¾·ÜT.—&Úön‹‹‹â‹P™L¡¿ -oJ‹–Nd *Šz½."±ºÙÞb�N›P&“ ·˜~\^^Îçó£££­Ÿ= Ò=èÌH&ž‘cæ\è‚ò^Ulê<AÖ¶áON&“Ä …™™™r¹¼°°Ð·Pxmø¤V«MNNÆb1D´áp˜ŽØr¹\.—+—Ë Ÿõx<Á`gG´G–+++ÙlvddäðáÃ¥R /ßLS�� �IDATÃtvv¾ýío7­ »Äãq^ÈžÏçI«šD"éííOúm*缺ºÚ {…øÐÝ‹¹9çôw÷wûöí{ì±Ç€XZZ*•Jƒ!‘HàïÎÎN©Têp8Ðå™N§-Ë–¥'î¼òJ»Ý¾¾¾îr¹ŠÅâÒÒR2™4™L€dÊåò@  •J¥ÕjÕétz½>‹---U*IÛÞêF$J›Ù¶mÛ&''é91ž·�öÖ.cffFÜGV*•Í2{mß¾]d^€0¹0‹ØÐâ.mêÐŒÞÙÙ ç¡V«&É1- /Û†ƒ`w‡Ãa6›iÝUraôË–e ýeŽãð5©Tj4yo´D"ÊÝöõõaîBã»ßïÇ19ŽãåߌFãÙgŸít:ý~?M˜¤ÑhHa 7š¶´òo X^^¦s\ä' §x|Î㲃²9‚ÛíN$â ,Â!¢àìt:õzýñ¼b-®íø‹§M}{pppmmíÖ[o%Ÿ\qÅ·ß~ûOúÓßýîwƒá÷¿ÿ½ÑhüÍo~sà 7|æ3Ÿaæßÿýßßö¶·ŽŽ"0Ôjµçwj½½½çwÞÖÿ M¡PœwÞy�ë‘)¦P(hµÚ?üáŸúÔ§py{öìÙ½{÷îÝ»ÿéŸþéÆo„¾ûî»±ðùÕ¯~õë_ÿÚn·?úè£íIü­nh®Ý‚ó8zô¨Õjõz½û÷ïçmòz½"$I'öâ· í»¡„k>Ÿçá@‘Á›=þCWW×ÚÚ¹?¹\N¼ ½!Q¬B¡èèèXZZBʈ€™x{)•J4¿LLLèõzƒÁàt:³Ùl$«»»{aaà£GòêUp¼SÏÍÍA;J­V£½«« ›€sÊår‰D©T&“É……á: Q=Ïh€˲f³Y©T U8Žƒÿ£³y…B7Eä †Q©T¥RIøckX‹9 B¡h¥ýAD"Y,¼;Ý”p§¦¦E9ƒé‹ð,ÛJ¸'Ü „{íµ×Ò“—Z­®V«Åb±§§‡Hb‹O?W*•^zé¥ëëë³³³ÈÕ´x=R©¨Òãÿi^¯×ï÷ŸžIiN—ÏçÕét$±‰DE‹>´Bý\ž¡T#üÎ%“Éd2ÙùçŸo2™Ž9‹ól6Çq‡czzšç3L&S*•Òjµ¼‡ÕÓÓ³²²ÒÕÕÅ£1™L½½½‹‹‹ëëë}}}³³³"É›2Žãl6›¸ƒ¡Ý?­ƒ,¾X‡°²Óé$Àíã7›Í–ËåDð¦°Àm%ܶýe™ÕjERbqq±V« ;VN¼$ÇqårY¯×o*GM¸m4ͦz»9Žã• Ñ�vüwc³?¡#t‰„þ™áp8›ÍZ,–VdŠ@Ûa±XÖÞÕj5Š(à#~çÒh4z½^¥R ¹\ÎKFFN—Éd„Z­–eYá3Z\\¬T*´gÒét\pÑhìëë3™Lù|~çÎãããÇ™û‚•J¥H$ÒJÃ0ËËË-²QaåP(Dž×ñ[$ iç“›Ök[ÛNëììDÙ|yyY§ÓÕjµl6k³ÙÀ ÐÊ«"í&“ÉB¡ÐŒVµ™•Ëe€x6[Þ¬$릎|bh6›3™ FµZEý_«ÕJ¥R„Pèp»Ýââ¿è,Ðét$´Å.�áæóy£Ñh6›#‘ˆÑhD¿»ð Á`P"‘ô÷÷#oAž&Xõh_U.—تŒÌaCà6ñL;vìØ¾}»V« ¹\®«««V«•J%Pâ #E‚ oyúP oY­VÜy–eív{(Òh4r¹¼!8‡v!âCËår…B¡£o¡SôtwN333-¶o!‹ÅbÍ0›m;V,ÇÆÆôzý+¯¼²¼¼œH$r¹RFÈoˆ¬.m6›pâ¨×ëKKKèßšmVðª†'ãælª™P$GÔÙÙ™N§£Ñh©Tú‰J¥B29(ù GªÑhÔju3F> mØår9»ÝŽîj(µ#~BÒž: ˲tk8.ü~¿J¥²X,Í4·xj¼ôÅ7sá•JE¯×÷ôôàç,,,Ôj5ƒÁÀñS©T\.W,CUlFàC"×P,»»»…<¼ÝÝÝ@�?O¿!üY§ÓqÇK¥‘Ì( ø±­@ÊDD QÜñ)¶ÓÔ9uuu§²ýi›bjëeœlëîîA™:•JÕ“²D"V«Õ†sw½^_]]=!Óú‰2̹¼~bZ$÷x¬¿¿ó{³/T*2ÿ6ô»Â–b‡Ã±mÛ¶D"!Œ>–——­V+ôœX–-—Ë^¯É4…Ba³ÙÒét6›…‹*•J³³³˜Ž±ý°ü~?wù|tÂù]­V7<l¶ :ñ+++‹‹‹n·»X,r5ô|>/—ËWVV …B±XL¥R¤A \.“0H¯×#ébOOí€_TÅບÝ[¤òHl‡ÈÒÃÇ_÷jQÛ÷/Ô9<xp³º“o!{ÛÛÞvFúÝÓÇ.¼ðÂááaxš`0HO4âµÇy½Þ†ÝÒÈ ¶è7lä•J¥ýýýÇÓæ×ÐSÒ"¹Â9×h4¶È³‡8@ä ͼ8b‡Ã¿‚è s(”ýü~>Ÿ·Ûíår™L‚@ T*!£ÓA}}}Ȧ‚ˆŽh‘V›ƒ°sŠàs‰›ìííüˆã8´í5Cäв÷;vìðù|˜î …HµZ-*=SSS¸ÛÙl¼JØ+›Í ÍÍÍ¡-Â9)‘Hl6›°q#ªŒÍîm__ßÄÄDçܩëÍ5ljD¶ì/OGç4::zF*Ⴒ­„{²ã8pØ@ü|N‹Õ߯K—J¥ãW¸iç/ÔÅ€ŒŒLMMaœˆ»‡†ÓñÃË+6s®‰Äl6+ rµŽ¾¹$a ñ+X–}õÕWU*•ËåJ¥Rr¹œÎìÉúP^¯×ç󎎾þúë¥R©»»›¦º( ؤR©FFF‚Á !è“H$< @æ^<b€p›Ý(´ ²,[¯×§§§É×À¬(—ËY–=räH<¯V«xLØD?2x&áC‘¼ar¹¼X,šÍfµZÍ„õzä° Ã¸Ýîl6KbýB¡ \µoM‚™¨'3” /}(•Jåv»7ó…ãG7ŠpSCòx¦‰²0•z::'Èn¶•pÛ¶5;räH©TÒét³³³ô �}RÌÉd’—ßcY`ÛVÆ' ¢z(m|ð>Q(“““õz]©Tvvv¶2/ðŒeY©TÚpYÝŒˆƒ†:¡/Q¡PlÖE) ô„Ž?¶oß>11‘Éd8“É$^™šš"L&“¯¼ò ïç`ÓÚÚÚx›&&&x·¢Z­âw ý°t:ÓéL&“‹‹‹$¶7Jb4ÖxA£Ñ¨V«Il×llôõõétº#GŽ9r 4a J¸8 ÏoÉår2+mâáááéééÍN)´ó6™LJ¥2 "ЛÉçó-Ž@ìZ³û ¬·šÆÏí¹¬mg˜=óÌ3O=õÔK/½Äæ4Ô'U*•„H´ÏÄ´@ív»"üyŽD­V“_Ì\ø»P(´î™Ôj5i¾¢©äZl‚pår¹.yCLV$‡ÓÐùI¥R^³ººÚJÝþxº‡ …Ãá ?éêêjØ¥ær¹8ŽÃ­V«ù|><xvr¹¼¿¿_©TF"NG.ù]ÉdR¤hÚÎÍÍ<xPiG”p…dY––H‹ Ã0“““ ==0Ä-‘H h^XXØÐ[ÄT*Z7$PO§ÓœóV"§z½¾wï^“ÉtÉ%—´¾×O<!•Jÿê¯þêMœ¶ž~úiByñÅó¶>þøãÈ–tvvB?÷µ×^ÃâE&“½ï}ïc&¼öÚkøþÅ_l±XÚÎà4LŸ:tèСCZ­vCþ£Ñ˜N§yiqq-Ô %p‰Ä†P_™Lf6›S©”B¡@F«E×È3‹Å²ººŠé‰æ#0µZ-nvMJ¥jµ/!b0Ä;z.;vì„‹Uy+w£¡Ùb•JE*…:®™žÏéò&;!Ã0Z­6 –Ëe·Û ¥¨†B©`4{{{3™Ìââbë©Ö5mEÔ“kµ½dÙpÒk Í¶ŒÒ×bÒÍîˆäùÚÚšN§ÛÂÙ¥ÝÛÎönËd ŠZ~¨ËÂ[n4´xàÚk¯Ý·o_oo/Í$nï}ï{Ÿ}öÙÏ~ö³â_‹ÅbPÁÚÚ€±Ç{ì _ø‚B¡˜žž¾ÿþûûúúhV±‡~ø _ø‚ÉdÚ¿ÿ#<244¾üå/¯¬¬¤R©o}ë[n·Ûl6ßu×]¿ýío†ùñ¼ºººk×®Ö!+++€bÄ@Ø-c­Ô¶ã7Žã&&&üq£Ñ˜ËåD0"d¦#h€ã8J©2™¬Y3·N§“J¥˜£%IGGï,&“©P(ˆ{…jµšN§7¼Â -N7<Ñúú:àAôV­V+“É4MµZmvyÍHü MT*ϳ, A#ò ”l6›È’\*•šÍfÜv…BÁ›år¹V«%»›L¦b±(>9à€‰Ï{!wG?,N‡'Í'r͆ÞÜŽŽ0ìµN|P(„9Rþ¼££Cœ¸A&“ÆÉèç¨Óé€óÛÚÃß‚ö|&“I$f³¹¡ »Åbá1q_zé¥FWÿr,SÌgS‘ÀVÒzßúÖ·n»í¶Ë/¿ü`æÙgŸ½ýöÛçææî»ï¾;ï¼ß™žž¾ýöÛ_xá…½{÷Þ~ûítÿÉÔÔÔíoXÃåÌI²ÿú¯ÿŠF£_ÿú×o¹å–………ŸýìgôÖ{ï½·^¯ß}÷Ý×\sÍ¡C‡üñÇüСC×\sÍÝwß]¯×ï½÷ÞùùùŸÿüç—\rÉÝwß=>>~ß}÷µ(TÓ¶SlàýìîA3öaT§Aû‹½ I§Ó »ÑÐOÌKm 3]-2Êœl …B<Îb‹Å222²}ûö Ê ™Žóù¼pð.mCCC»víêîîYøâ¶Vr†aÒ’Ð $ß ‡ÃÄ{q‰¿fO–äµìv;kt¦K"‘Äãqz®G(K$¨ÈOOO“ËåR(ôeá$îfìv{³¤T*½^oC*“­a¨ …‚xƒ¸^¯G’°Y&�놭Ã@ Ðp8m˜uÜtZï›ßüf&“¹ñÆ8ðÿð?ûÙϾûÝï<xðŠ+®¸ÿþûóùü?ÿó?ßrË-R©”ã¸GyÄçó]y啨}aaá_þå_d2Ùßþíß>ðÀ‡úÞ÷¾×æünÛ ´z½‡år9‘5"pEáê’a˜žžžL&S.—7DU«U%çjQ6ûd˜ÃáX[[ï\ ·ÖëuF …Dvéìì\]]ÝrÃ^Ã+�:+šQ1ÕjÍ{ôÝiË4W4®V«À™òÂ5 ÞÓîÕÐJ¥R©T* ‰Än·#(‘H"Ó—!õ ær¹¢Ñh¹\–Éd:Ž$ív{:&©Z­ær9aà^©T¶¶ÞÓ½aÿN³7¨uï(ü°û½×fOóä“O’3­¬¬¼úê«øû’K.ùØÇ>¦P(öîÝÇ_|ñÅþþþ}ìc<’üX,öâ‹/ `ÓsÏ=wZaÛvlÊår4E¦›.b#�¢×CKKK-Ò1‹EÞ|700 žf¤s¶n·»u½>¡Hî¶mÛxòD\UÄèé,<x( 54ˆÉ6œ=φ1Ìh4’…ÿÊÊʾ}ûfffhZ"’ÛÌxÒºJ¥Rxë ’»áÅ8ÎD"±á#–ËåÃÃÃâ e´KÄb1Üvà år9v@"¹Y^´Z­²,ÛÕÕµ¸¸¨×ëÇÆÆÖFäkår¹P(ðb}Œ4FÃÓÏ%FoŽ4áp¢mC±ãVFšð]èììDŒ¾5Ÿº•†ˆZ­vá…òœáè訰%Ãëõ6Œåyä‘^xáxh—ÚÖ6ñLoIDÏ�T’Å;” ²áVqX+áÖ#KÅJ¥‚Žö ס¨Ïóf½ùÂöíÛI?…Íf«Õj Àl6s·a!]¤p­Õj[L+!Z¢ÝÝîa·Û…A€^¯×ëõÍHËâñ¸D"qÌÌÌLÙÔëõ’ ‹¸]À$õõõù|>˜*Ô­6,u H¼áÄ{dV«•T\ÈH[^^. R©t~~¤|>}£Ñ8>>žËåÖo˜ÿ+¬V«yn[xÀV¬Å1Óì]ˆD"ÂÞðéŸ�çôéOúèÑ£¯¼ò r¬øÃ®¿þzq5³†/áûßÿþÛo¿ÜVͲƧÆ�«Þ¬ÀhÛNó´oú ‹t–e¹!Ÿx<žx<ÞŒ6}1"V¡PÐh4ƒƒƒ‡"‰fDÝ+‹©Tª••œtvv–¼f³ÙãñanP˜˜èë뛜œt8jµšÆ— €ó6ËM%“Ɇb¯t>§··×h4NLLÔjµ@’ H³a/>Ã0ýýý¡Pˆöñ §#;ò¸00•óNÉdT*•ÓéÄšuxxxnnŽÌ¶à¬Czjûöíõz]ØO¸´´Dnl>ŸÏd2]]]ËË˸íóóó¸xú¼W¸Nø¼ÎÎN–e———…R¼øšp±NGôñs¹Üòò²pÇz½>88833ƒ›FvaY?Á`0­ÄŽÍ–5ôeø|>Þ×ÈpêííÝJœ, CC_ÈûEÍ—Ç<Gàv½^·Z­N§sëi=¿ëõz£Ñh45M±Xl؈b³Ù2™Ìž={ÐÛF¿E6›­X,®­­Ý|óÍ—^z)ŒròÌn·Ëåò¥¥¥••¥R‰´ÃwÜát:÷íÛçr¹$‰ßï_]]Õh4f³Ùl6k4šÕÕU¿ßÊ'ö‚&f6›u82Y›Öý­dµZ Ø–eñìü~¿Ð3I¥RTã¥R©xˆôÉìì,IßÉåòx‹b±è÷û‰ÄÊÊŠL&Ã1éù=•J9r¤aÕ ¼¤"âÕÕUòñàÁƒJ¥I?žL*=!Öj5"xªT*e2ÙÐÐýŸÏwàÀp¹’f%»ÝÈD3'-•Ji·‡{‹½¼^/šÚ«×ë¥SO(‘l !" #‘Èôôôk¯½Ö°ÓV4®×ëñxœ^Ëãâ9Ž£³O~¿ßjµòh@`ii©»»É:Ò`0HÞŒhì ×µÃÃÃOŠ{ÞÑÑÙ °x”4EzOOÒN^–H$8H$¤Réðð°^¯Ç2Z­VÓh§f&"îìóùD<¹B¤òÀl+üšN§#º‹Hè5\߃PCøÒÇôù|ƒƒƒHoðri››[‡††Òé4É;›L¦ .¸€D Ü}öÙÇŽŽþ÷ÿ÷wÞy饗~ðƒ|衇†9÷Üs ÅØØØ~ô£»îº =å=ôxÖþÚ~ð†an¹å†’»íîî¾à‚ ã>ú‘|Wuýõ×ßtÓMHËÜÿý÷ßÿ®]»~ýë_3 sß}÷íÙ³_ûÅ/~ÑÊ@iÛibPÂ…t©L&S«ÕÍòF£Q"‘€FSÜ9Õj5„ëëëx?ÁkŽ ‘.k_.— ƒô¯Õj•Je3R…BAoÒjµ"ÓJ©TjØÐÁÛ‹ž:t¨‰¥^¯·Z­ðOô]jx ù|? [5N§ÃÅÄb±ÞÞÞõõõJ¥‚µa€Å.hžj]OüVˆX©Tâ g4k&ƒÇãAä·¶¶FÊfn·;N¯­­õôôðI¹\®³³3“É€C‹ã8²ø€E©T‚´.í#IpLÊjµæóys€× ,iˆKZ‘H–J¥r¹¼•&·Û6,/ÊDï–ÒéÜh4*þX;;;›‘Lž%Üd2ùÇ?þÑëõŽþóŸ衇^|ñÅeäÛJ¸mÛ²5TÂ%6>>~ôèQà™–——Å‘¶ÍŒÉ5©TŠæëÃà'ÿ’¿N'xÒÀ|Úðʸ9uoo/ ˜T*/‘¢V«{zz„Ü€ô^LË€JÞ^ÄY¸„Kï¥P(X–ÝðÞ ¸@¥Ri6›yΕ¾-^Þ¦ŒH$om÷žžžfÜqäâU*•Á`à­X–õz½ÑhTØÍžÃr¹\,!\ÛìàõzžÒãñ,..Š÷Ú©Õj½^ßJéhSµ'ÜN…îúúúÏþó[o½õ?ÿó?;¶{÷î6wÛN½)•JZœt årÙB*Cæä^´Z­H”ÞK£ÑÐé,_Ý”Ífgff¦¦¦šÍ×*•Š$ñ@A‡q�ýÐÓ1ïâåË¢ÕjÕjµÑhD†ƒ7‰+ :[(“ÉàS…ÉŸ†×I’ð®¾øäòZŨÕj¿ß1{aØÇk°¢ù>|>ŸT*E²‘ˆänÖ,Ëñh׊Ç+¸¤|>— ÓéÈÅ×jµ•••ÎÎNÞ.,ËÆÎÎNŒfêÉÉd’Äp~¿Cqç\.×bSÃñמp;)%“®®®o|ã=öX±X¼âŠ+>ô¡ñ*]m£muuU\³m­˜ÇãáMR4¨“aÞôÇ[·ºÝîz½n·Ûs¹\Ã÷S¡Pèt:´X,–l6+þÔxËOñµ-©»Ýîp8ŒËÖëõàŠfYÖårÑJ€a·Ûãñx¥RÔ‚F£1ÉdÒf³…B!a~&‘HX­V1¤ªÅb©V« ETaÖàÝpüAÊx¨Ñvtt4¼W¨1H¥R–eU*•J¥‚Å^¼î/ÞÓ$§ã}ŽçØŠ¨-¼Ô¢Ñ"¹,˺ÝnÞEb` áÅ7ôÍÇ­­­Y,BÛ±¸¸h0²Ù¬ðwE"“É$¬Pvvvž(°ÝiÅI}²êù}}}7ÜpÖwŸ™™iQ{æ-dÍ”p£Ñh.—k_h[+&—Ëéê:Ñ´m=k—ËåR©”N§#äÙÂ÷–¤€Ê¿ §o:¬i}Ò'¶€Ff2™d2Ù,÷À«V«Õd2™Íf V*•º\.úm¢•årçÒh4•JEÜ9ŸK&t½^/“ÉhêR!#›€H �á‚[x…Äè‡âñxü~,Jë¶.äÚ FŠg´Hn$1›Íd¤¡èN lJ¥RJ¥’´PBî¶\.¯¬¬T«UÙOiÐív«T*àÏŠÅ"QÂ=ïo8™Îéøc¯¿(%\«ÕÚ×××ö1Ç“Á£o, ìv»Ãá(•JKKKâyL²kkkz½^¥R ›Êå2ñ1<ïEdR1•$“É\.GÏÚ­ûHz/ºäÐŒ~†çNHŠÌ¼µZW¹I§Ógee…v™"Gô¹ÈMÖjµ&“);Žl6Ë»!`R —Á»øŽŽŽr¹Ì»rP0ðâÂfF¦f¡Û¬ÝÛÛËqzCš=ý†Ïqmm­¯¯ommÍív“šÐÐa–J%ƒÁ0<< S©änkµ~#–;X þÿì}gŒ,ÙUwUuuuÎq¦ÃÌôÄ73ïíÛà�Ø ,¶°0Èk˜/Y# 2 ŒmY!„@Æq’e°HxYY^ïú­÷íKÞÄž™Ó9çîªÿ‡óßËõ­ÐÕ=ó¼óÞöùð4¯««úÖ­[çÜ~ç—L&Î(155Õív}>MÓù|¾R©¸Ýn£Ñˆß&^‘xž—ÿP‡DÃ?Ê÷×l6‹û']8ã4;; ì)$öH¡áæDÎK(Šzó›ß\­VS©Ô£>êóù^|ñÅ`0h4ïܹ3T7Q«$p&ÞB{lC ÇKø7^’+‚¸° ÚîáŸêŒa˜ÙÙÙt:óçâ×Êøv»](ÄKZ¹àÂï÷ÏÌ̼ð ’ØUœ?WNÐ ã;Dw«ùa.!&“ÉãñÄãñ@ Ðn·K¥R*•¢(jyyykkKýÓt6ਆ[Îçóý~·a?Äq\ ðûý7oÞœ™™¹uëÖÜÜœ¸Nòƽ^/ÏÍÍA a0ìõz‡caaáòåËõz=ÆfÃl6;ÎÓÓÓ³¸>±Xìøøx¼¨ŽUZ­–xÍ\8ãyÔsoI>‘×ð<íÚ5‹ÅrõêU—Ë5???55uíÚµï}ï{ĺšššjµZľ^!Öwn·Š@;�U«ÂY‹Åår ”¢¨N§#×�4v¾jš8%j.— gÂ…øÕþþ¾Åbê‰p8\­Vý~?Ü],ÛÞÞû»_hxn·[§Ó¥Óéµµ5IcÛÜÜlµZ‘Hµ×Ãñç¢ ”C¿â¢ÕjÝ-(;‚Ñnyyùàà`}}½Ñh€aÈd2pÍv»MQÔCË=}³ÙLp«ƒù7HjDà'Š¢b±X0|üñÇ·¶¶nÞ¼ ~ q_Íf©õz¢(¿ß¿°°Àó¼ÛíÎf³‚ �uŒpzz'É…MB>¨GÚ@ ~¿óæÍQÏ•«W¹kOûC:‘ÐsŠÅb©TÊjµF"«ÕÊqœÏç[__ñÅ©”ˆBEƒN§¹xFDr#ßl6†Á[¢([&Ìo?Åî°¸ †p8¼½½  WÉd¾ã­š(«2 ƒcËår­Vc= ÄAÁºø‡VVVvvvúý~¥R£ELµ$!û�� �IDATô(:999::w1@{ b¡g6ÑÙñ`„B¡r¹Œü-ñ<lmm­­­A¡6üþë0í S„se!} þÖîî.±6ˆ»†”’Ífk6›PÕÏñçB ¨Ùlîìì‚`0ÖÖÖ¦§§£Ñh8n·Û~¿?•J5­­-xúb ¿å““ ]¯Èà Ol×&D«ÕÂú‘ûŽÂÒ•x‘'ºl"žç´½½Í0L.—+‹¹\.—ËB¸_§Ó©é‚ Å­ÁøIål!T3‹ ÐáÐHƒ—T‘@­;==½³³c³ÙÂáp4Å·ç‹E®ìx¨!G%ÎÇl6OOO£à>û»½½‰DÜn7^܌ܣ¼P($¦å–“J¥BX&­VK<‘ããã¡·oßþïÿþï7nhDµør–‰@ ˆWÚîîn8&(HÐY4M †z½¸{{{¸I®×ë© ‡Ã?þx8~衇€“%ëõú¹¹¹+W®¬¯¯G£Ñ~¿[³Ùìr¹Ün·Ïç¿V«ÕOßçó‰ ýív;:E,ðôåâÌ*[áèõz¼°KLÇ<ÒršxNÑd2™^xaqqÚí¼õ­oýþ÷¿/›Þô¦çž{.r‡BäO<ñ„F£yæ™gü~?ô¹qãF<üñÇq¥öÚ MÓ6› v©R†-¡ ÝnWMÇ,<(¤ÀOªy–”H$Äi|½^FÕïF T/ðÞÞÞìììúúz§ÓI¥RÀK‹”@kG%<ÕétN§<HÈTU«Õ™™â3¬Ý; }ð˜a§Ó!6ËC»’+‹ ¨+€©išÖëõåry,Ëêt:¹*`1ïv»NGa§ïv»ÅMö¯JõðLœEQ”Ûí/çàààöíÛ,ËÂj›Äqø{{{‹åÇ~ìÇjµ4–m4åræM–eív{,»yóf¥R•FQ+8·Ûß©dÿÜ|>ïñx8Ž“\! m¸­Vk³ÙT³®Úí6‘d«ÕŠÂ#NŒÓë]òùü§?ýék×®½ç=ïyî¹ç¾ÿýï?û쳿ó;¿S¯×õWõoÿöo{ì1«ÕÚívWVV¾öµ¯íììüʯüʯýÚ¯=ñÄ`œ¾üå/?ýôÓÏ=÷ÜÅ1NÐÜívß¼yAnÍfóØd bq:Õjµßïw»]¹^Úý~_™ä 7KÍfÓd2-‹ðm¥R¹zõêâââññq&“ÁÁX@•d0äT.‡£^¯ƒFît:âØæáááôôôúúz¿ß‡„¿\½^? À8y½Þl6Ûét2™ ´ç±Ùlív7óz½žã¸J¥"6Wc 4p†¤Z­6 hšk¡×ë匄(ò¥`œä’ø6Èh4⚌½Ûí†N»€~ð¤Ž3 -ŽL&ô‚è}577W­VŽŽ wrr‚º^»V«Åãq¿ßo±XŠÅ"Œ’íP %ID›'˜ŠqÜú‰v~K*•zúé§}ôÑŸüÉŸÄãѵZík_ûÚŸþéŸú|¾ÿùŸÿyï{ß \õŸþô§-ˇ>ô¡»wï~ó›ß|î¹ç^~ùå|à gÝh4 ­K±XŒÇãNçàà@2ஆºT,âh$TÄ6RýÕr`Z­v0lllœœœ´Z-¢*[­–]~©¡EÓÓÓ½^ |+•ŠÓé„È…¤1!ˆ$~qÚâ?-7›Í&\2›Íôx<D¹A­V«T*…B!ƒ7Æ0L h6›½^O¹D>Ÿµ2sèd¢ÄŸ~6›…¨c2™äyž´¯Êþþ~&“¹yó&˲>ŸÏd2 †x<~ëÖ­ÝÝÝ;wî ˆ~Qš­—*9|’}=ǨÑi\ä¶nã4µò†7¼amm Wý×ý‘|ämo{›F£ù§ú§ßøß€ šÉdzòÉ'Ÿ}öÙ_|ñÎ;ïyÏ{¨Ì^C^ÎÚ(ÀF›Ð° Ô¥ @²755…'– …B0Äݼ¬Yì)»•¥R k.—“ì&œÍfC¡Ðööö3Ï<óÜsÏíïïã>A«ÕbYV%Ž»X, ©Áƒ~ñÅwvvòù|·Ûõz½Ç)¨r±Ã,½§v» .‹¯Åb‘ÔƒÐCîa9NÜõz=Pˆèék4šP(DÄ'].—7¹Üs$º=õû}bC�+ ͆8 }raB<ýÝÝÝÁ`�œèÛÛÛ›››Ï=÷\¹\ŽÇãÙl6 ¶Z-”]#Çø¡1DŽî¸Fº”ÃáPŸSœ„õ&2šp÷Îw¾ý÷ÑGýéŸþé'Ÿ|þ;77÷‡ø‡_üâY–ýð‡?üÈ#\Ì» ”©V«™™!<W„ÃiÑ[�*ñ`T±XÔjµ•¢ ¸‰C Gpõ$Á0NOOÕ¶�·ÂPì*D±p—‹ã8¯×KT]#KÃ0 ØèK‹Ú÷‰effæääD2Rwxx(g³Ågår9É\Œ ”P‡Ãál6 $~v»½\.ãÓNPë‚oíóùxžÚÕÿ!I×DºK0çææY–…eæóùÀ¨ÀsÂ5'“É™™`§„Ì^ñ?q“Éd³ÙÔôm’9Ã6FIz³Ù<{§‰‰ç4‘ÿ/_øÂþýßÿ]îèÂÂÂ[ßúÖ/}éKûØÇ`‡»ººšN§ŽŽ çŠ¢}ôQ9ÕzzŠG Ãá0G³š&“ÉJ¥* ø³ñ—v0¨é‹,yð÷ÒÒqJ0D~•$fůÐøò© xN£Ñ¬¬¬t»]`d ¾ ]¶- @~!ÿ* #r:±X Ÿ%9=…DŒFãÌÌ LÔ…ív»Ûíf2(ÚžŸŸ§÷ˆ’³v»N§‰}ƒÍfS(æ„ |¥---; …$ƒøš™››ËçóÐ…¥ñ8ŽcYvnnîòåË�k4çòåËV«Õår¥ÓiHVµÛm¹äŸF£ÑëõN§Óëõ¾¶ô­hÁŸVbbœ^ïréÒ¥§Ÿ~úë_ÿz©Tz÷»ß^TŠúä“OþÞïýÞ'>ñ‰åååoûÛÿøÿŸ¿ýíoÿÔ§>¥Óé.ã"Ïó@*·=Ä«õ‰®Ó VSÍ«xôzýââ¢V«õz½~¿ß>«¡ÉÁeww—@žžžž*8=³³³Dô åð ’‡úý>€Qà¿ûûû‹‹‹…BAÒ¾Bøòòòò;ÞñŽb±(WÅ�ßf©T‚¦(J«Õ.--]½z�êäÖjµˆÒƒååeƒAeµ ? ÞE&$ º\®X,A3{ ‰WµZU¨[OxÀÅbñ•W^ó ðýx<‡išðIGGGàÛAò2•JE"¨ÇƒÏñ³$#Ã[[[ù|¾X,ÎÎΎשý\¶†çv©‰v~Ë`0X[[ûÁ~ð»¿û»(Õ|ýúu€ƒh4–eÿàþ`kkëää‘Cv»ÝF£ñÑ~ô—~é—.ÚMIêPÄò‰ÐA)_myyªÚ"‘H6›^5Ã@éeDƒ«‘ê~‚ÏHÃY~¿_²›W$‘ƒ7E£QÉCSSSž"æ­­-Iæož², ÎÐC=$é9étº+W®¼ño„[CHϹ¹9§Ó¹½½×:NŸÏ'öh‰1H2á¢ìŽ2>éTªP(ìííÕjµååeþ‚Îx<NIJxÐ%˜…† '''Åb'“¬ßïëõzèÐ …h4 É6à /‹<Ï߸qãúõëàì¢[S$£‘Cw4žçONN丠î© ÉÞÖã4‘qääääøÀoþæo¾ð ™LfiiIÍž«ÑhüÃ?üÃç?ÿy1-Í…•p8<t[¨Iâà ØÝC˜+•J©)¥( …Ël6›J{†sr"Ô¤¸`Hãñ¸\(ïððPòÂcE"Ç ®Íf3›ÍÆb±……½^/—HápXì4ìîî @¤" h¡PPYÁHØ?Ü )`¢dccƒ¢(AÔ�ÝTz ápú€ýÐétÁ`P¡/èÖÖÖôô4| ÿ|ooÏëõB󪽽½z½^(Ün7zÑÂ�®òÀ$A¸*ýu:4AWyn«ÕBžÔ@w•UÍÄ8½Þenný¬ÑhüÜç>§×ëÿþïÿùF ’ËånݺõÔSO]@·IN Üø\¹ï°,+wTîMÓ’õÊ<Ïü42TW[­VL«æ‡QŠù|¾×ëIj Š�³§`q%‰A SŽÂQж6› zýß½{´ €ŠÐ—K¥’\;p—ËEÓ´Ûí«TåÁãb4qGPŽ\N"‡Qž‹@Xš£ÉqàÎÚÙÙév»â¦´{{{ÈiƒB•r¹Œâ½årö7•JehÓñD"1¶çÀaä ùýþñêÈ¡m˜òw”i'ÕzѬ¯¯ñ‹_é”h4:ê)¯¡¸Ýn–e†©V«Z­Ö`0T*PvȽ€ú7I=´+”<=ŠT–ðF¨$–Tâår™ØÔÕ ÃX­Öb±íï@}4 ¹H”Éd*—Ëêë¦p|.LN£Ñ ×®]ƒ:‹E§Ó•Ëe¢ùúÑÑQ"‘ j‘é;'® 4‚UN†"Š=-„¹æ8eé2!Z­ÖívÃlƒ«‡ÊR$o ßšØív0Ì(êèñxòù¼ä´Ã!ØÐ‹EX„:®ÙlâÎq­VƒÐÊhÆãñééiŠ¢Tºa9á+Íl6 ‚0´j·šÕjâ„c¼tj »Ê.ìÄsšÈƒ/n·ûêÕ«~¿ÿÒ¥K^¯…•ð¸ÖØèEõH[Fszz*WW ±¯¡}ÿˆqâì’;h­V‡U¢Ð$±±ù|¾T*AXO«Õv»]BõÄãqœˆOr$âÓéô=bÁo!mµZ­ † ØrƒW^’3¦¦P#£ñ§Oð†ð<ŸJ¥Ô¯Ò³ qïÝ¥F’‰çt!„ rȨBÓ´8–b6›„Zz?üðÃÍfóæÍ›€!¶r¡ .=»u»Ýív[2ûn冈$w$èI³ÙVÖ¡›YÉ]¹Ãáày‰FÔÌ!×B1á'©¤Åƒ� dªÏf³y<Ô‚zÂÆãqbœ¡P±=á‚jüÐä¨\艈»ró á8@ŒÁ!¹çˆ?}ü,âé«YiâQ©\3KKKwïÞEnß 'ä#6›Mõ²‰qºˆ233ƒÈÊ&2¶�J‘Ð;ý~ßëõÚívƒÁ ÕjS©”RD[,Ï…¸Úd2)`˜”Íç%ŸÏ3 3R‹&†aÂáp¡Pp:ˆ`iìá!ÖùQ£s ‹Åf³)°Óær9duAÔà�ÂÔ!Am÷Hg©‡îìÉжˆ•å¬~*•"TÀïÆ^0g¤+ćqÆö‰ãôÚ $™Ï«æD@?¡Á`àp8r¹\"‘¸víšœycÿ{ç8¶ ‹ÅÞ6à'UÞ¾(óçâ|Χ»pq¿ß‡–*ã–:Úà¯ÓÓSÈN ƒñ²ôÍfúSÀÐíàüîpH²ói½^¿téÏó@F5†Øív“É”Íf‘MQÔâââÐ Ê=8Ö]‡Ãœd¹\NA3¤Óiq”ØårASs…!-//oooK!åÕË›NŒÓ…hÕ|.»•׳Û$ †…òÜÝÝÝýý}1ÓNE:*–V™YZZÚÚÚ]vrrÙAmƒªñCrxx¸¼¼ D¨r´°Z­V§Ó¹\.Žã¨vuuuccCyiÕëuqìá=OOOÅ»~£Ñ ÷öö@¯×C¤^¯G8¦Ð{wÔ©#懠IÝßßÇÿ‹Oqˆœ˜F­V{éÒ%e¾ÁJ¥øª“«?bñƒÃïkaaáèè…¦)ŠÊf³Csr’ej\åZM•w4TæææNOOUFöÜn7Ñ<zbœ^{Ñjµív[¹üt"ÊòòË/Ûl¶+W®Ÿ£è?z¯@‰Ãf6´Z-èKtî›03³³³`lxžF£ù|¾^¯¯¬¬@ݰäžZ¬^ƒÒ›f³Ùápˆ+ßZ­–˜'›Ð¶’\¨`,†Æç„’¤Öm6›pSâB;üâ:ˆÌGº………““9¥FŒJÕ¡» òK„Ÿge2`AÙ2ÉM…œ-\^^xšyhý×ëõ$I¹B¡P©TưÆï÷õœÐ°)Š‚Ž $¹È}G}ßá,ª´Piö†Éçóét:¼üŸOôÚDxÇO·à]ÉN€~T J:ÉCj�•è¿ñx‚„›››³³³¨rŒã8õ ¡Z­&¶LÃ#$ ÃqœÝn—„jY,§Óév»Ç£Ó•ü-Ø wÁf³©>k’Ïç3™ŒÇãY]]¨•Ï‚ Šz)±0¾°¹¹‰¯—ËU(êõz(R í²ÙlC{K#™L–Ëå¡#DW€¤ìÐßx:K¢4’°,ë÷û%ŒÖDyMäÁ‹Å‚ë,1îÑÑ‘Åb (q®Ãá�—?d4•Ûç žç777 À›’ß4™L ªÓb± áC9 ˆ¡ñšF„~-—ËDRà©Só[h7�¨då ¢x||<j”5•J¡6²b‘Ã>›ÍæT*5FÐ"‰(¯hÃó`0ªÕ*ÔPàHÛ¡zhж’ÕN§Sî R¯×“É$Z*Ÿ~½^?KûsBFʉqšÈëEòùüP„ìÑÑQ¿ßƒö“É$Üà‡ôz=¡¦Ë`ìær9I%n2™À:ÊÈqœ¤ÂÁù ›Í&^f0(ŠqɳÄ ‰£f³Yò®F½^¿Ááp…-¼J×Êh4Î+MÓÁ`0¢Ž fÆ`0HN”d‹“É4ÔQVè‹öÇÇÇ€Ñét ž1Ô쉗~–Çã‘´@‰Dˆ€Å~L"‘vºÉ@î”ÜJ;»‹pbœ&ò ‹$Öò¥T*!ºCMÊ9ŽSî¥mµZå(ï´Z­B1X5IuŒæàà@LRŒ »r0dš¦‰³Ä¿¥Ì¨+ 2%Äï÷ãY+Dw+y5â" 쬬<ôÐCèx½^–e 3”Ø›†äÆehQ\P¯×ãÏ1“É Uýý~ª 8-±ùÀÍ?>iøY óœL&Å™0œÓ nc¿JÊ+í¼^XƒÁ îÍ81Ny�¥Õjq'ÈÆe .TN§$PmÝnW®ì`0èt: L¸½^Ïn·KnÕëõºÁ`À‰én¡‹(qb¥RAa±h4*§yžÇÛ#ágAsnü· gÞsºV«ÉÝu³Ù_°X,ÊEÛ�Qb€ènÅJÜh4ŠË^¯×ívÝn7¨øv»Íó<q³ÝnW}ú Ö x~øZ‚¹C;Co:ëÕív«Õ*üy§Ó!&øœóƒñ5?Ì<ÞÈá"çUV®ìbær¹Á` Þ=Lªõ&¢$/½ôÒŸýÙŸÁßôG$Gâw¡D„R©DÓôÐh4Žã'¢ J¬•^¯—+Z ©Ü0 Ò•bk©T 4MG"I“\Ìp¨ÊÈçóâ´ Žo…СÕK¥R!8×åòL°ðx<½^¯\.ÏÎÎ÷z½W^yÅn·[­Vp.áqO¤ÙlƒÁjµŠÛ«Õj4Åà­^¯'^3pAxŽ£Þc¯×“ƒë€¬ÝnC‡uƒÁÐn·+•ŠÊâÆz½î÷ûyž—t¬ñ'> ÆÃ>ÿ(«M<§‰ —ííí~ðƒN§óÏÿüÏ].×?øA)raeuuuyyY ä‡v*¼žEäˆAG0TT^­¯¯CQÌ)]_yž—#ämµZ‹‹‹ cÒ&IŸO<¸ÖcYö,…!êKòúý~»ÝF4¾ÉdJÞ«Õj2™jÁP($éñ4 É.ƒÁ@<‹ôû}9·8—+•ÊááááááöööÁÁúÂñv»wcâ8nnnþžššº|ù²šdÇq³³³?ú7tzzÚjµÎÏÏ+©NŒÓDde~~þ»ßýî_üÅ_LOO›L&ÉÖdP€OÒÆàI]<Aòù|x4F²­¡ße\ ê�È+ ý;p&Ùá8naaªÛ g±ßï[­V1Õ[¿ßÇËÙC¡`„z-å’¤är¹¡%[ÊÕÌ@w mݯ^½‡5M$‘¤Ò€©�K†ŠÚ'“IÉ^Ùl6—ËJ%9`T"1??/W!BQÔ¥K—Кq88±,'xLEy½^ |ZXX€ �0u»]—ËeµZlG˜1ŸÏ'—+‚‡¥:h÷ƒjPÓéô;wävføâét:â" “ɋů{Ýn·8é‹?P`h<88PÞNŒÓD”ö}ßøÆ7®^½ú?ñßøÆ7î—a_¿~ýù矾¹¹9 €Wô ƒZ¸:[XXû-¨³ªÕjH5€¶UÞââ"|Ád2MOO£ÚÙÙµ #´Ûí@@§ÓÑ4 ¬ív;N¯¯¯™ †a®\¹R­V‘®Á‡ßÚÉÉ J$ÀoAzÉëõDGE¡*vq#i¬$Æh~~^a t·ËËËÍfóúõëPO|ttT©TæççÊÓ–ˆCJÄ�Ä£Ñh€vèâ)‹ˆ0~wwWn7633ƒw£(•JxÛõÍÍMAM&S4-‹P*¹³³‰Dt:òe3™Œ\ÏÀL&ƒ 䄇êñxˆ*üYð< FÒ¯ ‡Ã¨Ç´í/Ã0ÓÓÓâN%*%ŸÏ»†ap–¸x<NÐyLŒÓDFëýöoÿö{ßûÞ—_~ùçþçïß1  é€?müûý¾d%B.—ÃKãP±–DW�vZŸÏ‡Ô4øb ¡^¯#=ˆ›؃—J¥T*år¹å^«Õnܸ‘N§qèn¿ßùå—ñ¯ùýþ¡Toè·@æóy¼ä ‘@Aëv»•»æ›L¦7½éM’AÅ¡¡ª 1ñÝ»wåjµM&Óææ¦ÊGŸN§!idHã­ñsÜßßWŽ"@?DhKØc¹v|ÄjDxyy<¸ƒC‡‡ÅöX=ߕлHŽPý6Wî‚ã4‘qÄn·¿ùÍo><<ü·û7ØÈ?ûì³÷Ed©WÐìV«ÕívC›<F—ÉdrÅ8ƒªœÜ¸q9&“Éd2% ôò3 £ÀE‹ 'X›ÍNÞôåôôT®¬Ãb±(¤|NNN†¦ÜÄ ¼¡ÆâT�„rÁ¡pZè¬/þüøøXMPN§(ær¹(Š:±„àŽ˲.—K¹ÁŸëóùÄ9-§Ó9t•JåôôÔd2©ÉÏp%à|Ñü0?²zÙÝÝEÞ¤^¯WØ^ E8êÏ.EÉá&Æi"²‰Dþê¯þjuuõå—_~×»ÞõÔSO …3"û~”Â0 h„L&äÔØ3¤%•‡.—‹ažç‘÷S*•%Òív‰:8 ÿ-NØl6¹¸4‚»wâ,‹Á`P_øFc4á¬t:Ýn·½^/rתÕ*aÀ$Q“…BAìªWŠ?'ÚvØl6`Ô gé´Ä0ŒÙlVîZ„?ý^¯—J¥ 2ðá@ãs‡ìv»äeˆYn¥!!z—äóyØ!t¤G,~ä–½ÊZgág’[„rVsRJ>%Y\\üä'? ßuäÀ988p¹\™Ly*Iíôz½Ç㬌˜®MòÕ c´rÑét>Ÿ¯V«c´r¬1øO=OµZÚUlü~?EQét:Ȩ‹Ç“N§ÓéôÔÔ”\Ñày)2ô·$µ.þ­V«\ì«Ùl>´-�·ñÁÃÓŸ™™[Øétòù<¡ÁψV«EvKòaIº>’ßÔétN§_®>Ÿ¯P(ôû}8T­VÖƒÕj¡V«¡³Qi4‡£Óéˆ]jõµæçΊ‹¡‚=ñœ&ò  °‰+„ð¹ív[ w‘Ïçk6›ðæK†­"‘ˆ¤£†ôTB£Ú„R©¤@×”Ïç%³ÇâÄB¿¶Ûmõ.tšAðûòx<à©D£Q1äÉÙ)|Äš ß"”Ëes c±¸;`N”/ÞívñÝ€d´^¯£ÈX«Õ’ ±¶Z-*ÀÃáðP7]¸ ä/‹%‹kÕn·a pHašW1ݱX ÈYÄ?zBõ›¼1D Áž§‰<hR,•‡:N.0ÒëõˆäÊÜÜ®h\.—ËåªV«ð"àWÒ!Õ`³Ù ’˜P»0B—Ë…¾+TŠ C,µZm<úÊr¹<77'N»Ýîñxjµèzešð±i| ƒ$ÖJ,ápX.;bµZßR¿ß Án6›È€É=G(CgYV\£/¶OÈ6Ÿ…=F»ÝÎf³`/+• X5pZÀtCŲC&“ j»ÆÅ¤æ"b01Ny0ªx5 0bà‡†ÊÉÜÜ\>ŸÇëÍ $¯Õjê§(jiiIyÇ]¯×å´¶Ãá0™L¸U ÃxÃÞ Ž½êÇ�� �IDATV¯ €hš¾|ù²P¹¼¼<Fæää zµÛm¸ß1šM,,,\¾|·îb·µÓé¨Ü’ŸžžÊ¹˜ù|^Ù*°,‹×4‡Ãa5ù›^¯'á$\7Xièé›Ífh�¡R.]º„~±Z­ÂÆb±‘ÀÎív»Z­âX¬ ûªB“'q}’sº2 &4ígq½²V«…t&“A´èË’ NÌívxxH|BýxžW†èRE¹"±X,³³³Ùlô ÑÈ—_~™ã¸P(�(ñ@4qwîÜôûýƒÁ�”Ñ„§ÄÄ#G³äv»Y–šoÛÛÛà d±XÄÿ»¶¶vûöm¹'²ììì,Þ—D!ø©LcKbmm ßž'‰¹¹9…>ȯêt:‡cff&™L‚¯1m£Ñ‰™^ÜeffF²éêôôt£ÑPYÅ 0É@ßEv»-Ùcbœ.„b½}û¶ôa"*…€Ó×ëuPâE…B!Tø¤`E‰§ ~aÔs¡Â–pffF”S«Õp’²ôûý~¿¿»»ët:õz}:‡Ã¹\Rúh¸ù<c‚ARÇ+luu: >Uî CúðöíÛ ¿Õívϱc– Ä„Ý[àBTc.,,ìîîØmñ/‚aY–çyØ…èõz¹Øšx‰ú=ܬŽtï‡ÖÌkþžtÌ0’Vsbœ^{év»ËËËbÐûDÎEœNg©TªÕj&“ j%Ð!½^Ïó<¤m�5©|)h”�Ž…Ñh„6ØUcYÞ7´þ\–e­Vk·ÛÅݳÙ,ÙkGYÐY(H(×{æ,”3§iZ¯×ÃÆŸã8–e¡O.Iv»Ýõz]ÎðFÔÁÄjµ2 £2ÊDQ”Ùlî÷û#ù¸àXîxaHNûP/GA Ù9dì"‘AÊþ#±Óç.‡£ßï#3¯0ãôÚ MÓ÷ˆÈëu%rqQÔëÁårµÛm«ÕŠ^ (ºS.·Ûí¨W´Õj5›Í¯ŠF£‡‡‡žY0?¸q6‡‡z(™LâÍ`®_¿>ê z<ž1LÚHb·Û¡Í9ìpív;X«Õj³ÙNNNðÙQÞŒÛíöB¡€§‘ð¤Eù|¾z½>¶q2›Ír ÅÑ!XrÎß¹L;žJ”ÔÅ6›­^¯ß O÷Œ›†aÆH4*±/Q°ÓãôÚ‹N§c梭ËûK ±¤Übçøø¾S*•À¨ÕjCF£±Z­¢Öv(tƒƒHðJ-<Èsrr²´´„À4Pöí¨=úµËå*—Ërå³Ö•Ïç#ÊpÝét …‚Íf«T*Ùll¼ÛíɺŒ�3/c_p»ÝÅbQeo…òBtH¡ÅãñŒ .v¹\•JeÔ2Çq¨¼…eY£ÑHp)Á^çŒu b'^!øfµZ¡MûØÆÉápÔëõ±aûãt!¤×ë]ÌÏûEvwwm6·jµZ1Ôëõ–J¥^¯‡®FÏâêŒÈ¢½š$LT£Ñ ÔA"‘P¦Ç%t1kQå÷ûÕ«{¼îÀ`0Æ~¿Ïó¼²®L1Ò­D±ß¨©Ž{!âúC»ÝÞï÷qÿF„;==Æo±X(ŠºDG‡£Ûí¢" ɺµ±.X,M&“2 @RÎ2?N§Ó`0ÀCÁgž¹¹9¼_×Ä8MäqœžÙÙÙÁ`pttÔn·Gmh0l6Q­ä.5 âñx2™¿ éJAÔo©¨P(Hbû×qý~r?xfElPK¥Þ‘½ÓéÜ‹=“ÓéTÀ! Uˆâ©ÃÉ#ÐÌ‹ >{½^OM‘=ü´óPi˜Å6�µEG¤·ÄàûýþÔÔÔm¶Z-Èö_iÍàgCÏq(ö Œ^¯w||lµZu:«F“ÉäÒÒ`„³Ùl·ÛEn“ºU™NpNyШcjÒëõÚl6@~är9âM›ššRÙ¥­ÛíŠõ&ônÓ§Ngoo/ŸÏב ð¹NÇl6CÕ8„zl6›$ÓÉdZYY‘<Ôëõêõz«Õj’+•ŠzÊ»ñDìJ"bh_QIn³Ù$.Øï÷Å"^�­Tx0Œ×z ¯ÙlÊ!¦ XÀKò‚ySƒšòûý¨—¬xúê Åëo|ã!.§Òžñ<ŸH$²Ù,Ì|½^G1sqœ  =üðÃ,Ë*àÛ&Æi"šP5??ŸN§ívûÔÔ¤—àP­V#^¶l6 9Ž£(J¹`r0ˆÕ™XF"D+€ˆk½^/®vÖRYôz=˲{{{„f¬×ë’ºò*›+++çÞ'M¥ÈñW«Uà÷ûN§w¨ˆ§]%=GÇ#G�()�ÂrÜ–3Ø<ÏÃåpWÝnWM-x¡Po†œN'½ÕHµZÍårGGG Ã(¸Î>ŸY_|L¸¤w˜J¥PëŸÏçr¹{ì±·¿ýí ïÂÄ8MDVîܹ …>ö±Ý_ÃÖjµ@Ý]©TÒét"‘À\z½7B½^¸yxž'(g¢Ñè¨íŸ§§§ëõz(‚Ý=ê{”Ëåð1¨¬BN§Ó™LfzzzssF�J‰ïÁWWWÁÌT«Õ—^zI¹õ*0á...*@2Ï¥|TÌØ;ÔAQh}›Ëå ¡²c§ÕjWWW‰c±˜Á`O{"‘Pö (ŠZ__ÇõþÐ<tø·Ñh æ°Ê³ßW^‚ ¨1̈2—R©„û(hÍ I#ÆÆóüéé©r N6›E³¡@ C8«X,bÁãñlooËõ!œ§‰()‹z½ÞétŠÅâÞÞÞ¹wË¿G²´´/'}©„f×`ØIÔsša†aâñ¸Ê:%Š¢àÜD" @A iíM¬šËÂY•JùCf³g‡=\°@4®×ë%ßy`½{÷®rPë‘GAVJ‘V#C’ 2555¹ƒ¤¸\.·Û-˲Ê=UA¸sçþ5ÍÞÞ^«ÕO;±6pò_……ו‡:33Ãql€pªÙP(¤@žÕëõh„4MÐUò-)L  ˲ø‹yµZ-À«%W;̱ª‡zŸøª>99ÙÛÛ»}û6EQr|ðã4‘!rzzú¹Ï}îgög?ûÙÏÞkœÍ¹ˆq-ÄF`]òðWõµÙlrh’ÂqíÙÛÛƒêƒåêvqHns¸PkµšBé³F£Ú¡P(4ÒOòýï”»×ëÅûÒŠE$÷ääDe~¨äóyØøûý~e&\¬V«zC`öƒ80îZñ<OQØ‚"7½h9#.^„GGG ¯¬|0Ä´#g±(ï�Ä4¾Á`m8†1 ÀƒŒx%/¨pH@°úðððÙgŸ½~ý:ÇqrP§‰qšÈÙÙÙY^^~â‰'>ñ‰OàHÒûB8Ž.W؇jµZÔÖh4â;Yžç÷ööX–u8j¢7@\ 7›Mq0 påâfbû§°+/—Ë*w©ù|<Ý¡; q¯t± ¸:–Œ=ž/HSYĵ‘ðˆ%$L’‡Ün7~<¬f³™Ëåp]ït:µZ-MÓ’ÏÏóËièšQh¯Ñh*• Q) Öà‹Vµ,Ááp@‡Ibðñx ƒ º 2ZNGnÉc?A“Ʉϼ¦bbœ&2DÞò–·¼ç=﹌ë\N§Óéôz=R h õQƒØiµZ­×ë¥i½9v»¸%½¨¡Pè¹ EQ UqrÕ££#°@z½žØòÇãqÜ8™Íæ³PÁªÙqƒÑU¶LjÄívq?‹År¯Ž ®ÀýÊ0ŒÉdÂÏzAÕëu¼bûøøZIÖ‘ã)™r¹<´¢_3¨^Üjµ*ÆCØM¼› C¼f`’ÅtÌÄ#FVPLýŒ(’‡z‡UYŠÅ"^ݪ֚§‰<h \ø¨f …l·AP®hµZr(WŽãð]^&“Q†¾ó<¯�˜íõzÄÖØçó)gwÎ]†úÁ`¹ïõ0ˆÚ¨§Ôj5hc(V»r å€ ©È`0Hì3ìv{$§y, ÁÔ® þ)¾fÚíöÁ¶ù|^…–L&ñ ÕjUÞŽH¶? ŸþÄ8Mdˆ|ç;ßùÆ7¾q ggW–jµjµZ¡ÆW„l6 Ô2°ßèb.—ƒ7\L®*Gw«^pVSDxŠo«=XíÂ_M}J4»^\¯×û|¾‘´MÓbÎ@œÆ×d2y½ÞZ­†? 1úæ§t»Ý±{äh^¥N&.]n‘s:gkº[tˆ™™e:f$,˦_N‹ß e³YqP±'Ó4½¸¸iÎååe¹@™\A噘-ÁÔl4G*©Wÿ('Æi"#ÈÂÂÂÖÖÖ3Ï<óñ\®®æBÉüü¼\€E«Õ·€(Ý@MƒAØP×ëu¤Y  Hr¡^  »8ÝíÙž‚r£…(hAÍÍꩧ †¡ä{ÇÉeÚûý~6›%W8SŸ¤³Øl6R÷NG\"1FÃlâœÓv q¹\Ä&£ÙlBÞ~nnަiÂ5 (š t·rø\íóùäJlÐJ×S»ÝF††@µZíôôt$i·ÛétZ.ר‚­RºÝîH‰F†aÄL˜è”;4i_4YYZZz饗 ‹û¾÷½/œ=Ïñ#…l-Ô°oìÿíÔ(Šã8ø¡…«Ùlv¹\„~Pǵ´´tŽ\\—.]ÚØØ�ê&ñ0Ô·¶3•Je¨év»DC&|â]­r&œa˜ÅÅÅ@ žgdð. ©&”äf³ÙÁ`�‡A�?·¬`Ð!Bˆ™WèT‹1nT—“Éd”ËËËûûûÀÕÛëõˆv±÷HÐsœžž®ÕjC;N ƒd2‰zÛ‹M<§‰Œ؉ÅbÇétÆb±ûÂ2ÁÛŽçuüˆ¶Æh‹ ÀCÙn··¶¶ÇÕ«W}>€pWVVhšît:F#‘Hx<ž+W®X,ÀóàW£Ñ8NÞYXX@©xü§ÕÈÎÎÇq â³€•¸/é·š¢ö÷÷å&ø‰r´¸¹ ¨½ @îŽ~øáp8ìñx~øa|;¼¶¶v¡Và¡I$»ëõz<χÆ6®80vèlàÓ Ã�¿yee…ˆšÍæ»wïv»Ý矾Ûíª_lcƒ¬išÆ"•J©A ÀÒ­Õjb;¤àTMŒÓD41™LýªÑhÂáðÔÔÔÜÜä·‘Ùp»Ýg~~·hµÚf³yëÖ­B¡� ÜÍÍMéµX,>ŸïøøÂJà?ÁÖøôô’;;; Ä¡r]œ†!^N¼baa‚3r‰bø r‘¢@ `6›ggg%+¬ÂáðÐò0|›ŸN§ñ6†a$£»Çõz= ¹(—˸áÓ^(@w%"HUØNiµÚ¡ œ¬VëÚÚÚ¨YõÃP–Û·o+ŒP¯×ÏÌÌH:¥òáá!ÏóÀ1KÔn·… e&¹³ Äo™(ÒY]]ÅC»Šy¨‰»½^O.ð0 ëMäA“………çŸý7ƒÁT*Õn·µZm(‚*5P¸¨TÚb±Ôj5£ÑèóùŠÅ¢Á`Èf³(LÓ´Ýnïõzrœë:Îëõ¶Ûm X–££#0’>ŠÍf%Q�¼Y«Õä"rÐ=•J)”Â!lp%r¤ÎÈŸÛï÷%Q“¡PèÖ­[Z­6“ÉÔëu\©…Ãaâ·Û-îsˆÇ$qþ\£Ñh6›Õ´•[\\L$.—K™|½R©Ü¸q]øôä(’ñMÑh”Œ‚ªƒÁ�Æ›¢¨H$rzzÚëõÄ}::Ž…„X®\¹²¾¾^*•žyæ™J¥¢²;­Édº{÷®¤Q Õj­F‹Å²,'¸yóæ¹¿°8çòÄ8MäAœŽã8­V‹JºA8<<=â,À`Rµ··yopÀŠF£ËËË�¶ år¹R©ôz=§Ó o2ÇqÀ·_³ÛíÂ`âD<ÚQYvpN)•‚sÚÞ;{ðƒü@2VI|–Æn·3 #®¨&øsL520‹E¯×C‘ü˲:nè\Ùív£Ñµy:Žã¸Z­f6›»Ý®Á`ÀköªÕ*Âr8•JÅf³©4 V«:ƒÃÃÃH$}âÏ2çÇÇÇsss.—kyyùÅ_Ty0HIæÀêõúâââééi«Õ‚Çn³{öõ91NBÒé´šáDä$ŸÏ£^ݤÓé ÎÓjµP¨ ˲¸®9<<d†ã¸J¥Â0 T¸\.³ÙœJ¥._¾ MÍfs¡P`Æl6'“Éh4 Æ©V«ñ<Ho 9{šÚëõ¢¢öQ¥ÛíŽÁH{î~$^hg0X–§¡£%8|Y–µX,KKKmó„«lœÀ ¢Ÿ³V«ÁŽÁëõJväÓh4.—Ëd2U«UƒÁ Ò8e2ŸÏGQÔ`0èõzçÒl%‘Hu:““½^o0ð•æõz …‚Óé$ˆ Äe5f³*;L&“ÓéŒF£©T 2XFã^ok:ŽäŸäœ^{‘ì"<‘‘dzzÁ;‰Ã0�W.•’£A‡ð³fgg¡{ÍúúúúúúÒÒÞò@Ò;ÞŸx<•,\X–… »Ýà­t:­žÎòz½D"Íb±‚°··W,)ŠBU \-‰ëqˆëâ˜n$‚ ¤R©Á`0’ÕWnƒÁQAiápøäääÚµkçµù€€ÇÕëuƒÁÀq²v~¿_$.ž¢sð¨&zí5h?”fm"*efff{{˜ˆ•L¸Ð•ò‘G™™™ñz½ƒa0ܺu šiB”&‰d³Y Éu»ÝE¥×œx§t’m„ü~¹\ÆoD=u©J_pffF®åŒÂ!PýJ{!çÿñ<³o/§íöö¶Éd’¬¦ ƒù|^¡"Çqv»]œU»ˆ€|$™ššÊårr²1B|F5]D´Å§ÕjÕëuX3jøsñ{œÓÉɉÑhÄÚV«Åó<MÓSSSbDÁ½ð®&ÆéBì(Ï«oÕëYŽ. ‹‹‹­V«R©8NŠ¢$ûÄ(BR*•¦§§�MÓÍf“a˜~¿_*•Ap84MÏÌÌ$“ID’[¯×q'˜eÙ@  Þ9€_$>Q0u÷"œŽ ½$!JÐO]½$¾ ‚²SÖƒˆš½Ùlz½^«ÕäšRKª?ô”¡5Ãáá!ú¤X,^»vM2òY.—#‘ÈÁÁrˆ¢×뉓‘ÀN+~L„„>O¸L7^~R*•¢ÑèÞÞÏóF£Ñápàž7ú“Éd·ÛÕ8å’»Z­6 47FÆhww÷ðð°Z­âE4šWëk´Z­äž…)xbœ.®PÕï÷‰ÇX666€¤¶~åröæDLomm­ßïCéª| »Æññq·Û5©TÊd2íïﯮ®nnn‚¯#†î‚²#R‰±XìääW÷^¯W5Û[5{mɨ‘Ò¶ÛÊågè‚333ÐJÁc€C€µ)Rd:nffÙ!h ðÐC©Xúý~ü‚ý~Wßáp¸T*É¡A›Í&´pÕïñx$Kƒ^¯w:C ƒØQÿt¯×#¢mÐÓ†Ñn·åšêž± Áår5T*Ïx@”+�}>ß`0€z¾’Îèøž(Ɖ^»‚hñ&2ž4›Mü}n·Û,ËÎÎΨIš¦Ýí`0À¹Ýà€QHÕ;wî�Ýâæææ¾ð…çŸþÅ_ÜÝÝõz½Ç]¿~½¨=FøV¸ l;ð}pp vDÎØ�”¦éGy„@hî‘dK¡µµ5•äªæèèÙBI°'–ÖëõT*•Édð”^�Ó‚ð¿ï|ç;- Ñ™iyy™�¡ .//3 #·Ûí�#Cœ¶rW§C…>ŸŸŸÇQ_•JY”ùùyè#.¦Ö%D«Õò<O¬4bn)ŠÂÑEð}baðâ*vš¦išæ8Çá`j4–J¥*• ´‹„wA™ÐVóܶc/‰qšÈD†‹V«…Þ3Äç7nÜ@Ù�á"5-z½^±X ~¿@š;;;/¼ðB½^ŸŸŸßÞÞÞÛÛŽ¢ŒÅn·ûý~¿ß´óóó:nuu•�TŠs-#щJ àvå�X°—¬ »}û¶ªè Ã0 ƒÃ-9Ž›%ŒºšÙlƒÄ}³*rN'˲[[[µZ-“Ébk¿µµ…+h†a@ÝÃ!dÊå2´ÃAû}û¶2i,ÝÝÝÅP|Ø»»»âBÔºrb³Ù ˜ÉÒÒ1³³³§§§¸o kÇ#Ë=‘………•••v»ã·Ÿ$MӸт[À!ØC3|g_„‹‹‹c´V~R“°ÞD4±X,½^/‹Çy³ÙDøGÂeAoook4–e§§§S©T§Óæ.— °8à7À×r¹\Pó*tW£Ñ”J%<ìß$‹ƒ¡Ûíâ& ÓÛqžcg?I±ÛíD{S�Á¸ÝnIü‚YjµZÁ`¶ðH …B¹\gŒeYV«ÕJ¶pµX,4M.¦$xpÖÊ \Éë]ÆÝ­ˆÚŠããc³Ù ΜÍfã8®ßï/X3‘H¤Ñhà·Æ0ŒN§ÃM¦ä#Îf³à™ç2cH§ÓhÁ‹/x7Rå'5ñœ&BÊ·¿ýí¯~õ«ÄÊûêW¿z°2jÄív›Íæx<n0À±Z­n·Ûív‹Ù‰¨æU<íUI&“,Ëݽ{×åráÔ¥PæQ䮕Ü_•/Çy<ž¡Í„ÎE8Ž“ìoͲ¬$+:”Ïç‘eBÜáõz]=2Ïårõû}"¸trrBXe¼ç7!¥RIüÔét�n3h.¨–IüM&“r2 ç´eYVÜGÊãñÀ5¡!EQ�ÃÃ_z½, ²Ç0½:g§Õét‡ƒ¢(·Ûÿ¾œ�ÇŠ� vÐÕÓP·};žÃ0’Û§‰òÉO~òCúîæó›ßüЇ>tëÖ­ûbüñxÜh4v»ÝÃÃC0¨NG§ÓAû¤­V«ÕjµÛí¸¾�Ÿàôô4/Tâñ<¿¿¿_.—‘ÂÊd2°%òêr¬¦@\ {üsèè|/8 êR½^ïr¹$‹Bw”šCãÙQ• “*• JSy<ž¡úšj0J¤³¬Âì)_P¯×£áÁšÁŸ¾Çã(q p»Ý^¯·ßï×j5‚=™aÀ #§ NoµZ¨V~È`0hµZ“É+¡åDQì¥ð& ÅénïѾç,ÄfEI®ÀIXo"ÒR«Õ>ó™Ï,--ýò/ÿ2úðïþîï’Éä'?ùÉ‹?~û@‚ê—`­yµu EQø!Ð2š.çë÷û¨"º¿ŒT³?çv»M&S2™ÄŒC‹=OµZ%îÅf³ñ<?4555•J¥à×ëõ:ÔÖ·Ûm<Öjµä>âCç:Vž1•rî<C/(Yhcöù|4M¯®®B‹dù !îD%ž^ðS©ÔôôôÑÑ‘Õjõz½ óZ­‡#—ËÝ붸ŒÝoE,$«U'žÓD¤å÷ÿ÷Ýn÷§>õ©¯|å+ðÉßüÍß †þçþèG?zÁ¿™@@«ÕV*<-Ün·aOšËåêõ:‘1–cV…ÖmÝnWé IEßh4 ƒN§«×ë*Õ.âB…œ<l0#‘ˆòñ8X·Ûm6›@“ µ^`³Õ“>�q-ñ¡dÏìs—|>?PßË CEŽÓv¤ý˜s0B‘H$Úl6d„¦¦¦ÆF4"Äa ¢Ñ(Eèõzõzý’fãQM´ðD$åƒüàOýÔOžž^¿~>yÇ;Þñ ¿ð ÇýçþçE9 &F#èšr¹Üh4€ß`šL&Aúý>Þc™.ÜÆ à'Å“Êa\êõz>Ÿ‡ßÂ=bVàÙl6Èo ‚€ò.­VËn·‘z³ÙLt‘)•JZ­‚œ�ıZ­Ê%R„÷)vìÆƒdýˆ… Ý‹D"CUrœ¶£JµZ™™ýN†«‘‚îʉÍf#È/`l`{Ä®îì …1`R~¿ÿå¥V»ò‹01N‘–G}”ødyyY.s~¡dmm êna+ il4Éd2™LªiBƒz½^O¡²®ÛíJ*‡Ã Ûí6òuÔôŒèõz`3™ ü(, *hš^ZZj6›D¸ieeeuuu0 ðòù¼ú€d¿ßßïm{äÒ¥KÊ_0cøjƒÁ�ß^¤Óé¡úša˜`0¨ü©©)ev®H$ùÅÿýßÿ½sçÎ÷¾÷½\.‡v ÍfS¥;X¯×‡¢Ñ¨Éd …BcÔp‹¥P(Ü#t­ÂjW~&9§‰È¾âXÙ}Ñ vssBa ¦¦¦Úí6”ðݸqnG઱@[®Ñh¼^/MÓÙlkhš_ ÿ°\.I‚N§CÓ4°¼C‡ɨ½ÏçAœÞp¹\Ç%“ÉÃÃCÃ`0€Â'"ÖíȰúU!®HQ”$ä%Cß ñ’7°�� �IDAT)áp¸R©€ 9 ²¼¼¬Ðœ{mmíöíÛÀZ{Æ%!¶LG§Ó¥ÓéX,–H$`X+Ðõ’³$W° ¬Ê<ÏŸœœ‚pûöí7½éMÿõ_ÿ56~Èf³ ”‚’œØããcAîÞ½«Òà÷Ó‹/ò{ô>J††šxN‘•÷½ï}ÇÇÇ&“ …>þñûÛßî÷ûr´Ê'¬‡¨Z†Éd2…B¡ßïoll@|Œ¢(…п˜ð”çyÇÉf³Z­vuu\Š¢pü#’ùùyT¿$ÖP€št8+++ ×$G’Éd$ï…BÔŒÕëõ‹‹‹è;,ËR…:h�òÕ7ˉIîññ1]‰¥Ói´Á F¶¶¶Ô¨ÎF£A0(ÎVœ”àq88´¼Ëå’ëÂŒ%@²ÐçN§<*žçY–áù矖dŠ¢ ðžˆÊá‹E¼8b~~^ @Uaéöú l5lÂ#Éxkbœ&BÊC=ô–·¼å_ÿõ_?ÿùÏÿú¯ÿúSO=‰DÞò–·|ùË_~æ™gVVVþã?þã"ŸçyZ„>of¿Ýn‡Ãa³Ù ÝNåNJ…ë§R©ˆwñ<¼Âe‘ƒì€£³½½],oß¾-®*Oƒ–ñz½bý’Éd”[%Åãq¹*/ŸÏ'©°Ün7Ò›ã!1=Æ0 ²‹F£QÁ[ššš¢iZ9¼¦,@*˜N§¡rÝl6ãé–|>/×õI À÷7x¼×ï÷CŠ¢L&ZNg´mooãÙD½^/¹»2›Í‡Cî"Ùlvh£,“É]¸Î—c¼‡5 ëM„”¿üË¿„?¾þõ¯Ãïÿûßÿþ÷k¤Q\ ×úïîîn8>::R(´78‹Õj­V«âä6P6€±q¹\jšœ½E§ÓÁ[Ɖ[7EÌfs&“!‚c€n ŵÛíÕjU!ô¥×ëF#816›­X,B ‹a£Ñˆ?‘ƒƒÍ«øÍñ,“ÛíÆÓiN§S§Ó©iŒ„H–àkæèèºÐÒ4 ÍÅáЫðñû5‚ èõz<‘©‘j>;ª8¨ç„I>/ïaM<§‰<˜Â²,�QÑsjjJ«Õ&“ÉQ‹Œ%-“dÉ8ŽU‰<[ )Î|8ªõ`Ê“)þ‡Ã±¼¼<77'Ùx·aÊ{˜¨F£ê�Óé4ò&åš„ï¥<†RyÕëõðšÃããcå¦Ý£ t@ïõz* ˜*¥R ág¾JJ"‘¸weèz½žhc‹ÑhDX&Æi"¾”J%Ôt@(.Gy‡Ã¡|“…w©T:Ç’'›ÍFT÷êõúP(Ñù»9‚܈á>ÅbQÒƒÁµµ5¢†Ó`0à¹ÓÓÓ³ÔÑÈ!4%ï% 5ÕNGÝ’¤»½=ï Ë$iY¡ƒ‰Â¥òùüá{G¬LÓôÐmŸÜ’ƒ5C„õ&ò ‰V«F£ñxœC¥R)‡ÃÑï÷Qi\§ÓCož…èvT½L¼®@8ôæ7¿¹Z­noo·Ûm¼Kͨ"—YQi_K¥ÒË/¿LQ ç’Eã‰4›MõÕq.—«×ëÁàµZm$ÁŸÏW«ÕνÏB­V#FXiq=á=*Ÿk·Û£®yD­;Ôð(÷–UH¯Ȭ^¯»&žÓD`¹zõªÜ.˜@Y6›ÍN§£¡)–h4ªþ,—Ë5R‹Xä6á0#š¦#‘H«ÕŠD"¡PhaaÁjµ/4ÛíV.èPcuÔ|Í`0ôûýD"A`¡ºÝîY°PÁ`pT8×ë…x"™T£Ñùùz½Ž×éíííáœXÕjU5ޚѼZ%Hl$U6êFå‚~+++ÇÑ4 ¬˜jœ¿Z­6jà®V«©iœÏóüØ}¤$×ÌÄsºróæÍñ*&‚öƒ=öüí÷ûÂÓ¹¹¹d2)ùŽ¥Ói|—j·Û¡žÂÏE"eåEˆÊLõòò2‚­Ôëu³ÙìñxPP‹çùD"a·Û …ÂÞÞÞîî®ä�ÊåòØÜ<ˆîVÍ—«Õê¹À?CÆøää$—Ë©ßÚÛl6‹ÅrzzJÜ24^ªÕj4MíÚí6¸Î¸IX[[ƒö¾v»=¦ÓéL&#¹f‚Á`«Õ"Ö ¸Z­vh™ßHúqîJANNNz½^·Û …B<ÏŸo Ä3RºŒ-ãt!ë‚æLd<AɆh4 /-^½vxxJÇ3NMMµZ-œ° Ø@¤‚Á Ô%\YÁ\ºtikk íâUîUq@%Ïó§§§è¿@ ßét²Ùìw¿ûÝùùù+W®loo{½Þx<ŽëÙ³$´‰¸‚ ð¦J²´´´¿¿¯¤‚ºTð&÷MxÈ`¬®®&‰õõuhZˆø8´Z-X»££#ÉÄó¼ÕjµX,ÀR²±±AÓ4è÷;wîÀ­ÁšA iP(¾2ÎK;’LOO7›Mbj°6Qr{ Š¢½/,�ؾ„B!‡Ã1j+¦P(T«Õν…îÄ8Ýß‚“„NdlAZ5ÏÌÌÐ4}íÚ5â(Pe#”äééééb±(éѺ €–ÝnW§Óñ<? p="Öétä �þ¹Ýn,ü‘±BÏ´C?—vp’ø?Á0¸ÍSÉŸ‹p`�›•ÌIÀ”êt:hx(éIt»]È=88xòÉ'½^o6›M$ ÃÀY‚ À\)ljµZ£Ñ€‡Å0 ˜ÃÕÕÕW^yš."Œ³^¯Åbð4N§Åb‘+ÂÌd2@‰Ûl´0æ'‘H Ä´x³…¦‚ã8ƒ …BâfT‚ à{2˜y–e²€4MS…›j…§?1N¯/HÝYz0O"é¨kƒN§Ã-®ÕóÆ/¹ÜÆÂd2ñ<ïp8’ɤÓélµZà�¹*"!å8n0D"hÿ:4òFX±©Za„Ð×ëõ‚ ¨‰Fâg‰™p5ÃÈUÅœ¶ÀS.g³q“LôlEBtxš> ýt¢± <È4MCZ«^¯W«Õ`04ÇFÃd2½¦–––И{½q¿ÄCA ¡V«%, ¯×K°³‹Åãñ”J%"šj³ÙA@ÆâÓ.nL'I¬Ì²¬ÏçSXÌf³Y¯×Ë$%ŸþÄ8½Žä¼Ú¼nåúõë6› àññx¼X,·lŠïAµV«u¹\Õ‹§7Ün·^¯gª˜Ìfs»ÝÞÞÞŽD"ÅbqÔ´Óéº èn ÞP¹ÝnŽãÀÌFžçÕ'Š¢œ%ÙV€eY·ÛÏç%TÇ1 ƒ/é^¯7Ô2q×h4Ôd¼´Z-äÞ2™L©Tºuë–x,ËÆv»m±X‹MÓÇápÀ|ò<ßjµ ßàÑÑr’ð-DöÌfs¥R!ê œ5è÷©©)°…°0jµšÏçSîp*éÁèlÀ±I®Üzæ8ŽeYÂ8ñm±('D‡6•¸w2©Ö›Èƒ&7nÜØÚÚ26› èÕÏxA1XÕáp@±Ïó¸ÞÁ™pc±˜ßïcÏçA×ËåuÜn·b ePhš ° …PĦT*©,Í rqH“ˆçV§Ó9Îjµ*N¢ ß)3ŒÊ‡%ÂþþþÞÞÞÆÆÆþþ¾ä¾¡z³Ù,2xZ­V„½½½ãããF£Á²l¯× ³Ëå+b€Óʵò;::÷ÁBìɰ0' ÆLò#®V«%.Hàsq’\ÉønÒ¼^ï¹T¬LŒÓD&r>Òn·áFivŸÏ'§øðClj›~н…nÓà© »•ÉdT:I�§UÃw‡4TâgA:$×ÇhzzzTÍpˆ+ØZÕϲ¬\×Ô¡\½*¿LÓ´Íf»sçÎ;w*•ŠËåÂ;×éõúH$B”Ô˜©Z­NMM•Ëåb±X(¬Vk8ŽD">Ÿ¯\.ãƒG £ßïËbÆï÷+[qd;åVúœ¢¨@ Àq\$0ÀH¶ÉdÂ{ë ‚‡‡ò€\X™„õ&ò`Ê`0(—Ë(êÒjµä²zø¡Á` Nˆ»HÈ5A9H‰ ‚ ×wŽ¢¨P(D„z x(�!Tâg!è.’kÑh4F -âW“Éd6›«Õ*q‘N§#Ç+q¾ýßÀ˜¹\.½^o±XPߣÁ`P¯×Å¡r—Ë•Ëå|>_¯×+‹>ŸÏét ‚àñxvvv å*“SXpH„L&£¾ÉáMZ,½^ŸÏçÑr‚ >ør¹<==ÉdÔ`r >”\.çt:ñe¯N;T,K$Úѳ7ô›xNQ+ùÈGÞõ®w•yÍåîÝ»ð¢BU1L¸hÿ mI¡ºO£Ñôz=q:G¡Ó³XìvûаÎi‹65™gœ *ñ³Z­°èÂ!¹Þ?c¤¸qÀo§Ó©T*ð[„~©pçBu8—.]R9Û<Ï#µX¯×u:]³ÙDŽ K¿°°°»»;;;Ûl6OOOC¡Ð (ãl6›x0žˆV«ŸŸ'î -§Á`Ðï÷ÇãwGdÇøÂhµZSSS…B…"Q\Ø( m;‘±+‹øFŠ€Ó‚9ê°9Ž›µZ­À+¦ÑhfffîE½ñÄ8M„”Û·o¿ð ÷ïø‘îf¦Ýn+@7 …h‡ããcôþÛívâý'’äÁ`W PmŒþ›ÉdÄùj¯×‹…NÛ©©)hp°²²‚¯9N< ƒR/+++÷ˆÞT’$WR4×ÑÑ‘N§U­V÷÷÷ñ¢tHYœNg»ÝÎçó`;Y–•< A ì¢Ýn;ÎÇ{ì­o}ëòòòÂÂMÓkkk_œ™™A‰Fqq¶ØÆ(䇜9AdǸt»]ÂõÄùs[­ÖYp¾ív/ ïv»C›ÊKšÀB¡�êa•L&ÏXknµZÅ´Œä²›”5ßk)§ýšÈÁÁÁÏüÌÏ<òÈ#_øÂ(ŠúØÇ>ö­o}K§ÓÕjµ­­-"Óp¡„¢¨ÕÕÕx<n·Ûp€¡ 7 ÿpñ·ÿ/¼Ï ÇÇÇív»ÓéàüƒÁ�à±øVì¾�Á6`€2r¹\o|ãišþÞ÷¾„@èûÛÛÛc¼•ÛÛÛcxÀkkkwîÜ9‹ëìv»gV£Ñìîî*ŒæÐKbzâ^¯G0 Æb±d2I˜¨2GÆáPHVWWu:Ý+¯¼r÷îݵµ5І±Xlqq±Õjíïïw:ÍÍM(œÃÁLc¬¤GÜàÊÊ n‹y‡zÕ å”<ÏÛívD’ ë8¡Ö|¤Ç„ÿ–z® Pô¡ÓéàÕ·J‘“Z­&v¸%ŒÓsÏ=m?&&äÞÉ»ßýî >ÿõ[¿õÕ¯~õñÇê©§ÀÓO?ý/ÿò/O<ñÄòòòc=¦-ô£žç†)Ž­_¾|ùúõëâSb±ØÞÞžN§k·ÛHDZ,+¹Qƒ/ììì࿈þ…B;;;DtEÌ„‹ÅÐðà(ÀqÖ××Fc¥RÙÞÞÆ+¯ÔX&1äs¼]æ¨0[±àAKžçÅ�R\�„.¥ náøøX¼IÛQ¨ÿv dç¶··9Ž+•JßùÎwb±ØÚÚšÅbñù|Nçää$“É„Ãa»ÝþÒK/A-8 ¦‰Ù@8kŽãPƒBpà¶ä”'DYðÄtߘÝÜÜ›à D¹8S<áçØ¨In–9Õy÷îݳÛó‹V«u»ÝjzægY­VÀ£{_á¡b4åÚ]-·Ûí¾GÁ–s”o}ë[·nÝÂ?¹sçŽÁ`èv»ßí#Á0ëõºÍfë÷ûÄüß½{×f³y<|Çív»+•Šš'Å0 ˲°Òð2Š¢ ƒø ƒÁàæÍ›Ä‡‘HÄb±d2›Íf³ÙÜn÷¨•‹Åív#j"“ÉÄ0ŒB¾GÚ*ˆJè®LXyS¨XÔHY|>_.—S£ÙF£Éd§Êd2íííñ<FáCß„r¹œH$hš®T*‹¥×ë ƒh4šÍf …B8>>>&¼4@ÚV*•©©©x<>FW{à™=;ƒ ¸xžPÛrÊVëýâ/þ"ɾb³Ù†B¼’¢¨+W®Hîv•S,cY¶P(àwáp8ÎÒS¥øý~È‹}éK_Òëõïz×»îǵòï|gooïïxŸßGbµZ¡@`wwwnnÚ@å1zL‡ÔÔ}5 õ¶A§ÓY,ñ6¸PÅÆÉétŠa@ÛÛÛÛÛÛ Ã\½z5‘HŒQóFTs8ŽãÄuøË…¶ 0‰t»Ý““eûD Rð VDySßï÷UZ&É >òŠ'EŠ,‹ÓéL§Ó<Ï×j5Ng³ÙºÝîõë×!*«ÕjwvvnܸªÕj<‡"{¨¬!y c[è0{.«:•J]âGmœÆŸÏ§oÊ”=žçÁ2 –eÑ6Ðëõ¢ü§X¼^¯äû�¤œè]…Îüg/¬$DΨÛl6ƒÁpÿæó>üá?ñÄŸÿüçﻑ£ �LäîØl¶B¡�ö Y)š¦Fc·Û%¶ÐzÞ e ˆÝ@l-$Áÿ8"G¬©%/ᯌÁ`Ì 4›MümÊÔ>i vZò(G¡=q)”¸×¢ÓéPrÎãñ0 “N§Y–5›Í°`Y8æÁSlµZ333ét:‘HØl6h©°··Ç0Ì­[·Ã0ТÕju:I…ær¹*•ŠÜ®- xÖ£rÀã¿Òn·å|÷stÌf3é¸ÝîR©Na¥ýhd´ú¯×+éØívœe$¿$›Íöz=5…˜ìQYÅËvOr×”|å¢ÑèyUIý¹ +o{ÛÛ{챯|å+O=õÔŸüÉŸÜwa=I©ÕjxÈ =šf³y||,©MˆU7öÓ[,Ç#Ùƒ`¤å=v̸¦œN'¢dE¯d¥R988G·”gNT¹íSàªüµZ-¨ ˜™X,†¿k…B8A ]=4¸‚bôk×®%‰£££ƒƒƒV«U.—Á– Ó%g}( ÂEMlý~¿øt\Ý!º[¿ßë€Ó޽‘ƒîž>1Zñà!{='I$c·ÛÅ·HÙl–ã8‡Ã¡¾H±ÙlÎÌÌ(»öív4+w|’KÖE"‘““t CÓ p¿çåëT«Õv»}8’ÏQþøÿ¸\.œþK_úR4½råÊg>ó(azÃÞðs?÷s÷‘‚&{’Æp�çšàív»F7!’©ÐH$R(FuÇ[­¼DC_„soÃØï÷á‚à!©|5 À0 TmàFÝ´11 *hjj ˜Ë=O¯×#€\‘H$‘H�n‰að2뺾¾n2™t:ÝÜÜÏóF§œ\(*+9xX<Ï7›MBqiDˆi¤yžGOà´på¡ \1¦[LwkµZY–Ej3â”"жÀaÊ+@A¨𦧦¦ÔtRß8I&<ÅÏF²¯°V«ýñÿñD"qxx …†A/a±X”ŒœÎÍÍ)¤µZíÊÊJ³Ù”{™F£Óéăù|žØ ø|¾v»ø{fggñ”x½^;è7??¿¿¿†Ín·ëõzõÑÎ×Vüqä#;tåÊ•+W®Ü§’ÜöQ<ÏEi°, ¡‚ôE©T’|KA?Ž:H´Ìäjæçç÷ööî…çÝëõ@ñá·£¢Ûl6%¡W‹Åb±¨É™ÍÎÎBõÝÐ.N§“¦i‹ÅR,¡¡*þÈšÍf0D7"9‡( €k'˜öíímŠ¢ƒA*• ¸ˆÅb‡‡‡r*4†\FmðÿØ{ó0¹®ê^tŸ:UçÔ<w]ÕÕó$ÉÖ`°easùÀ6äaɃäBÌLòÞ ˆxäï†ä™B^¸<B&<ÇØŽ¿k0Æ–A¶$«e©Õ’Z=WÏUÝ5uÍé÷Ç¢7[û uªºÕjûõúKêSgÚgï5íõ[¿ZMÒ%J§ÓPŠ¿L&ÓÓÓƒ !9…H®œu§œuJQ›L&Øu#ͧ˜WÍl!±ÏêE„Ü—ë­Õj’I€b± ••*³!iÈ(Gò“LMM-..¶··ßtÓM’·£ì¸e éä ‚ `Û)¬eC–‘x®lŵܓf…ã¸ÞÞ^¼ÎAÝ P'¥R)•JI&«ÅIAk`¤-˲·Ür "°–ápX}?JÀÙ’›N0u¡sŒúkîÛ·Oý;;;qfOR†‡‡É1!u(>„;®‚(€p!”Qó`étšçùB¡°±±1??/>+‹7¡Ýn7ÆÒâµµ“ßï‡æ{¹\.‰9r$“Éär¹r¹Œ}eXÅät¢tn45›Í‘H¤)M z†ÂçÊ%“I®œ&›–ÞÞ^<« …Âââ"ù±šŠ~ÚÛÛ$¾•à¸á].• Ueœ(<`ËÏwöìYøêP× 5uƒaÿþýrѺ‚«•âåryqqqttt``€Bb ‚а!UµZ%':<ž×ëÛ¡r¹<77§~`*€6„'{6cǤ\.‹ ¢¦¦¦$[NMM‹E¹IòÐÐVXÁ`Ðb±€¾¨ÕjgÏžE¥R)ˆÆÇÇåv¿I²T½^ßÛÛët:ÉIK"m©C¥RI«Õ²,›Íf± ÕÕÕEn÷JJSuÆÐCAüw��¡MÖZ£Ñ(^ úF­»‰‰ ¹e¨¼ÀIýÀÏX,”â³*• :ŽãúûûÁõ$“r”kb4qŽ}llììÙ³Z­V£Ñx<žC‡:tÈjµÖjµz½^©Tfff°ŒD"„^*•²Ù¬2#†ä‹‹õêÖëîÈ9355…/¨F’B­…ÅÅE2ZºN�ÍD"AŪT­Ïçk­yŽ9àößãñ@ñn¡Ph ôóÌž W®\!£±†ÛË�«–<´ºº*F˜s744ÔÔ8�ÖrÏTÜÀø‰J" JºMHy*ÙÁhqq‘,ÇD®pè*yP(„ã’b±811‘H$ÈIK.êBhppÚ꟞ž†¸ŸœíZ­–äehjÇT¡’2Epµ|>/^ �¶ÅÏ€—Jø°dð ´Z­@ ^¯I ÕUàT Ö°ö§¦¦p¦ @»ÃÃáP(‹ŒŒŒŒŒ@ªeYžçûûûm6¸ö³³³0ø}U¦[yžÇÞ‰F£) Û ×!çŒxØab�ë®òu¨µ@£V«íîînáÙ4òv»¸^L«òº`-M&“x« í Iû µ˜T">•J‰‡Ȳ°ãi·ÛÓé4‰ØzM¨½té’îO sƒâ`2|1™LƒAý>P©T'¦7%¡’Y‹Â5ùª@×RŠÀår‘;Ž‹‹‹ÛŽ}†:19ð)á²Té_ËAwAehµZH ²÷ Þù T[£Ð¥Îr¹\¹\Žº¨9r·?†ÙlÖét*±ó€~mkk‹Çã Ã;pAÜPª©. A$‰Ï%M^à@[\©T`ýÚl¶l6+nDD;|båíFŸÏ·¼¼\©T¬V«Ùlîë뛟Ÿ›y5‚ŸPÍÁW€b<£ÑX­Vc±˜ÉdjabT«U²7ŠÁ`¨V«j¸Tšú‚ªŒ¶ÆV«•ʃaŒw¥RÃÒé´ø“ÉDævA‡ÛíÆvÛãñlllàs¡yp©T²Ùl°ù QÒÕ¥²:‹%“ÉÆ 3ýÜp©Õj±X¬ÙÌÀžP j÷W(HËd³ÙœN'Iú€ç3$²�«Óé RÇŸË0ŒÃá[ä„ À&˜ºÙlVy£�Xrv&Åãq½^_(*• ¹'Oín6–ã8žçÕ+# QKêqFc³Ù …BWW—V«ššÂ <âF£±)pL[[["‘˜ŸŸ.>rطؒÇ`00 £€Ï• nt:Ïó˜F™a‹Å"¹<ÉÇßɃýS©” ¶µµF‡Ã¸éT*ÕTÁ`�@’Jã¨/Èp&‰îîn­VK}âÖÄl6“Íà¤X,6ë[4W­§PÝÌ|>ŸxCwv!E²@ N“ŽØÕ«W† årymm ç=q!J…nµZ3™Œz®nƒÁàp82™ ®•€F&<ÏÆmq*•J8‡Ã{6æú Ïó 8XL7™Jåù¥z½N¹ð ¹…V:„‹•5´Äõ$Y£¬ÑhÜn·¤ª‚IH¦Ôä~I ��äòfÊgÉÙc èäyÞétÎÎÎ...‚†goÀöÈÙc 0s»¾¾n±XŒFãvµ3¤*Šqn¶¤?¡ÓéHí î ïEÚc ìONBPå³³³^¯W³Ùì÷ûkµšÂwt»Ý©TŠt¬u:]*•¢ŠÈ$µL'’ mö¶P¯DMpÜT[†Ö56›Z`‚ šU¾�Ã0Á`paa‚¸ãkJ¦tÁn‘yùîîîx<.އš-À…M, ó«Óé¼^ïõ¶Ô³S(ï'SÜäÌ„‰ÔŠˆœ'‡àPr?†UÊ0ŒÜNÌÍ7ß ei¥RI§Ó‘ºF|Š2Úò[[î4*ô———m6›Ñhôz½ Ãc[.—©õ®° £W«Õpd&÷K‹Å¢Ñh$‹˜Ad |wIÅ"ùc“ÉÄó<ÕwJ«ÕºÝn*C(çÄ“U¯×Óé4˜=åÈC<€’Z´–äéêßýzHË7jÂ8…B¡t:Ç…ª\k­jëõºœš)ß�� �IDAT¨^¯+ìRZ “ÉH~æf£×b±HݺC¦R©ëdœ†iªœfO(™™™á8®««k‡•5iá‡¤× Oá¿‘H$JÚ•H$ …ÚÛÛWVV’É$¥åq–’Tªñ#Ýn7´•SièììœUÐ) Ãlll\¼xQ«Õær¹µµ5…Ù+wÇ@ @UÓ!ù^b•JEÎfHÂ}�”׾ؤaH²ä$¯ËåRÐQ‹E¯×SŸ²Z­ÆãqžçÂ(Ó­¦à^¼K‚6{ûЧ |âÖ¦S³Òrÿò&ŒÓúú:ùy(jÈD"±õšJ¥ŒF£ËåRŸ—¬×ëTjÏ�FÓÝݽńµØa¼~{Tê÷6÷D."ÁýýýçÎSþ½Õj5r:Åår1 ƒ—+5Hà6å*J?l§àL%ÉÁéìv;ЪšÍæh4*—M™¨P(DR¦*d‰¥vVÒ‰š¤ô÷÷OLL�‹ëüÇ‚ ·.€ÂîN2™T¯ó$¬V«ÉdG*’}�Äé&�º5Tñ ‡Êå2Õ ‰�[<�·$/ˆ!ÃÊ¢ÓÍó¼ßï'cA´:±X b*±¹Ã2<<\,%;á6aœ”×ÀÖ3˜d¼‡“ÉdSO (‹wÜqlj'R©TË@È=y¥‹šjãl6‹çsOOÏ©þ(…%i'Ö××%u7¥ƒ°¦ uÙ7„Òhkkk—.]êìì\___^^V(mÇ\YY‘äžtÕA( N§“çy¬ÇÉî5âÁA †@ Ö³³³‚ �©DÃTªByk£»»{ii ŸK~GÊÛkx}ÉïBöÌ%Ç–z�£ÑµÚ�Ü®V«[Á8ª¬/¸§¤/yò7Ö-Vè{Ò´¶§§G@ÞPL&ä^H@"þÌx˜úúúÀ{U£‰à‚öÙgßüæ7ëtºÉÉÉÛn»Mù\ǃäjd[ÀÈ{r½E9lPÙ²@¸Ô’¦øsI-\­VÃápC.`ÒÕh40s&''Å.W{{{&“ ƒ Ã,--8qâìÙ³j²Ž$ò”4 ’Îr2™$#EgyÿþýP‚÷Ãáð¡C‡L&˲À1aµZÉn­ä¾)¼/�íñ*6ÝÝÝx(”…Bzâ³ =+©4HÕ?88Hb¼$õŒÉdŒ­ÛíÆ¦ah¥‘N§%µ¼z¹|ù2<! wÕKê qu:*q“0�Ü&Ss؃{5FÉг©öÛ.¥RIÎÅi® ¢µ’|ÊbÃŒ÷x<årï.’Ô:î…^<Ïá„F¼\aæÁëõ:Ä× Ðéý…^h*ÚžZT5Û¾ð*@‰DR©Vj‘HD}óì% ÞºF£éïïNnÐbÐa…bèÒƒþþ~ªÏ‚zþ!œ'TH—Ÿkaccc‹Üq ÔÐÅÊ Úð)Ñh¦ýàààÜÜÏóv»à›‡1Ôétf³Ù`0¬¬¬„B¡••PÖù|~jj êÅÊ·8Ž«ÕjÝÝÝÓÓÓø-€ÉbuuUù-ÄÍ”ž$懫×ëPoL]_îVNÈF·ÛM¥gñð& 1­—¤ôöö^½z€ÛMMBñÔ¥–ôhÇ#/IýŒÉ¯ÇjUкÛÏç¤ÑhŒF£ôFŸ^ŽûmFâÚˆ¤½»[>‡Ç§§§‹›=Ä ‹×ëºÆ4¾€Ð-z£ußÍ7¿pò$Bó u „žCè¦ûïO½üò5·Cº¤ )³R}`¡Ü|gHkv^>÷¹Ïuvv~îsŸ{ðÁúÓŸF"‘ÑÑÑÏ~ö³ï{ßû^‰”?>11æææ¬V+Ã0x»ÞétB_ê±±± rÁàå­Óé ie Ìf³r7Llç�?®`>ä`³€ˆhø¦6›M„-äîuùòåÁÁÁb±(§1ÖÒív›Íf R"*ŸÏ‹nÐ…òc€¿!‘žH¦ª‚<KN¨mEH2ÐEò<D–0UjµIvL*.1›üİ Ùp´q‹�¹aǶ_.£#‡Wvt {ÛèͨDŽ`o—(°$k|½ÖZkh4»Ý.mœ¼^ôâŸþ”ö5šDmfábÅBDÃÊ,BYâ°LÐ}ïÎÿÈôBè ÝÈó4:SAè^8v!D¶‡:|ýõ_£ü@ —l’¯ <ÏC…äGGGa¾êt:½^/ùýífy÷»ßíp8^zé¥ú§úÌg>óñðð_þ˹÷Þ{Å6»_�¸ …'àÉ’N«Ãá¸í¶Û�° ¡ W¸\®T*e±XªÕ*åèa@%'“ÉÔJ¥âr¹H•j2™ªÕªÝn/—Ë ÆÉívS¥FXœN§ãDéqÀÌÂ܆Ø6ø|>Xãz½žeYR*ÜK‚±–ZôûýäU×’ˆC�$ÁRROµ£Óé¬V«zPÃ0r°}8½ …„EÄO(y/1fšúFy&“ÉårÅãñjµªò‹^ ®œR#ó@x§zŒëJ‰®;j¢­ÖnV­V•¶§¦Ðÿ±xp=ŽôIÜ~ww7lÉRL¸!ôÆ!¸Ò}ݎСG¤oú7ƒ_J£Ñ¸\.qu£^¯Wµ#1I333årV8˲rñ„¡Ý,ûØÇ8ðíoûo|ã‹/¾øõ¯}zzúÿð_¡•&ƒ9\.—Ñh´Z­ÝÝÝsssྸ\®|> 0•lj‘0{± ƒ°°©,º ÷3Ä0A, À؆ž½TÒ OQj«Fî^�&£ @’ü±ÝnO&“xs«T*‰Ë+`ù”J%±M¶S,pH ùh(r$Œ´•» ÜËd21 ƒç@½^Ç£iµÕp…P&vmm vkŸX„¥¥%ÊjÁ{ÃìÏ-Ï´ÖÒz²qŽÜ-î 6kù:„÷WÉíhAzzz�¨ÿèõzu:úB_@¨ ¡›z\Õ€ —BM‚¶¥HrA€Ÿ4 â-Ü\.‡K¹b±NÑ‹E¹™¡ph÷ 4 ­W(™¯XÁ‹¸Ýn¨aÓëõííí‡>zô¨Ùl&éš¡™äuH­šJ¥¢Ñ(¨cj% |Aèý(¾ÔD(ä$$Ïjø±Â¥.Ž a.—SIÒ#æV˜ ð[—Ë-9‚H¹C$+àOš Q6ÇÛ^îZæ¹N¥Rêƒ?½^ïv»›z°fWÄ‹‚¡ÙæÚ3õ(HR:;;óù<^º8🛛 ƒÇAc=à_ùmJ÷{ý1B„z:!á„B!ê‘H„a²ÊØ?A‰ øIÅ,P¤´ 1{EÈÜÜ܉'>üḣ£ãñÇß®Ö27V ¸n·ûöÛo% .½^O5yÛºûXj |%ÕGËÔ— ¸_\ËB%Eä*¹A2™Œ\M`±X„b‡X,¦Õj%{wÉ­¬\.‡U«Õb±èr¹€ìœTâbêwª'ˆÛí†L bÅ%Ù‰ÚC"ÏR¹½Ô¬øý~°â µZM2ø«V«*k+>V±X …B»§[Í6'r>9Nh™ÕPâñ¸Ñh'[¡_=B(ŸÏÏÏÏ­2Œc­VC%„@è#—¸f­V[__Ç]îñêõ:ÇqðHÝ@% Bˆã8(¬t¹\.—+›Íš2N>Ÿê­F:::šòòö¤Å9­Ñôõõ)ÿ¦P(d2¯× é,F³¸¸877ÝÓé´ÙlnáS!ÉP‡êëë“„ˆÊmˆbÝJÆ7~¿kd5ä,v»Ýb±4¬PïêêR©žÇðð0ø‹¤X,2¸‘30ØLj4Ê´P XÊt¥Ói�éõz«ÕšÍf)OB Âíîî¦êª 4Ã…ÎËâoÑšº-Ž)¥Lxž'k»“É$¹}U©T¶è ( îF¡×ëINËP(DÚÈ‘m®Ö#.N‹sV«54<L²ã€S)‰Ì� çS§N¤®­­­½½}nnî·>‚€ÐBȾj7·Ó¸9�Çi4ÒãvœXðÝñ!r—hppp||œLˆéÞ•Åétvtt¬®®¦R)*¹¿'×#Ù0iÐH€a^¾|ú¢¾õ­o5W¯^…¿Ãd¼zõ*x÷Mõ¡ »X†††š­D—séðœ¤HœÛÛÛâZej€ƒ ¸€Ûjµ*ô³Èd2ù|^\³žËåš :+• U›GŠävº‰ŸA ÂÓj///ãU,ÖøjpfÛb'(eBÁi·«#¢JÁqp©T"7Ï$áÞ[”þþþééi…P^6r:pà€ò¥)7„eÙ¡¡!м ð, ô¯¤[”Édpu#>T¯×_zé%ìF±, �& ¼ÄŸ‡aè9†zó›ßÌqÊ t: T’Φ8Ë ÁÓ¡C‡�×ÙÙ‰•˶²²‚3õ$?)VmÊŸŠeYP>J&“çÏŸ_^^~Õ;‹Åò¦7½éßøÆ?ÿó?ž9sæ—¿üeS°å"TY+ßèÆ»ºº®\¹òè£.-----AY«ÕŽÃWÃûŽÁ` `¶c«�‡†‡‡5äc`&ybCÙ·o…]­V«‘HÄf³Alò^u)Ö× ­ |>ä90ϬÁ`ðx< íćËåOi�Æúý~·Û‚rº’|xFÝ&BZ­VŽÅU ¦G®äðŠùsÉU¬ÕjyžVùEz{{Õ—Œ)ãŽáùñ(ÉÁi[ º«R¨Ç„{oQ®^½ªü¦²CváÂ…Ót:•¥ ‡Ã«««ð± Þï™››£òuxЇêõ:x¯Á`0ƒA¼ „'A,ÃÎÎOúÓîîr‡Ð½¨^¯W««µš¬Jë‘.ÏÈÈ[333â*Lr{°…}ÂH$˜˜[n¹åmo{›¸Íùî—©©©'Ÿ|R£Ñ¼ï}˜¸|ùòäää¡C‡Ôxß7VZk611Q(ÒéôÔÔT½^(÷ÐÐä¸J¥椘pq*Â8466Ö°´ÉdjXà�³!tñâE|A\2:==ÝÖÖ&ε°¹½²²B5'- âÖ2dngmmM\IÆ%kkk¡PH¬Äu:P٠ÿ CCCð9­Ê0LÃÌ­Ãá÷>äê…Dk½^gYVeËè.¨rla@á===TbS§› ÉÀ§pGñ £MÎeàÙÚUi›†STížpÔ’†”JqÌÌÌø|>­V n•Wq»Ý {–ð<åKKKóóó`0l6[8CÅó<.еX,'O21õÞ÷¢|@âš©TŠZ?@¶•1%CA³—ËåZ­vòäÉG}t/Õ¶“"ªY–Á`‚:F£Ñ .44u’Ò”.–ô²³ÙlÃn#N§S\»o2™ü{rr²\.SªÍ`0\§mm°¦,ËJ" Äš}vv–J¯qçõzÍf³Ç㕲,éA.,,\¸pÎ’ÄT6P†[!„Ö×שïÂ0 ~B‹ÅBÚ¥K—Êåò… –––¶}s¥!¯éøø8é:Ø·ÃSW¬¸ŒFc{{{GG¨V(ä³Ùl’x&“ 2UF£Q}¼¾“ÂqµLÔ'£Ñ(¹À 6ÝcccÐKÊn·‹ç4˲8‚ϲÙlXkT«ÕL&c0 €¤t:ív»ÛÚÚÜn7¾WWWW½Îþüçèž{š�¬me ÃÎï îÉVXæ.Ú2é*VbÇ…çù–Áa«««b½–N§©­xª*Ád2ÉAëÌfsC×JA  R%ã 5n.ÚÄêBða³ÙTk, Çq‡£µ—õz}rr »ÉdRౕO(9Ó$5¾—Õj¥Î*‹°¡…/(V\‹%—Ë]½zw£XZZZ__—,ÛK§Ó—/_N$â{íÑëõTy¤ÚoœH$$?ßc¦££ƒDƒµ?þ¼ËåÂ&ŸÅqtS}Ýë^i½t:Íf±mŸ››Óëõ€³ÉçóµZ ¿@¥‚þæoÐç?/#+¸ÔÖq ’J¥šb¡Ó®P´'×[b±˜dW‚mÏr@Îív“WÎf³¥RI¹WºÃáØ R;z<2áµ?@H=¡X³75?¡¸N}q±±±AŽzc ???/WìñxÚ-eRàl6ÛÙÈápÈ=3Çqbå#§1 w±õØÙllçêêj¡Pðz½$à;.@ÙÜÔøxYlS›2ÉÐ\qÛãKʬnµ”<›ÍRF«½½# È€1ã³ ÑV<‡=±r¹\*•`Z¤R)\bÐÇF“É$$Ó½^/tã__GO>‰Þÿþk©V«If3}>ßõsôz½BÝü¸í 1Örcc&¡òÄ !Ø Ó š R²Gyl}z‚`0(„¦øI’É$e§ à„Ô§»öÆ!k§|:8 ¤’c’ä\äb±¨P§.÷`^¯$¬g¶2Ôrßk}}]ý^T>ŸO¥R@¹$™=ÆI]É÷jkkK§Óêù8ä2~¨[ñuš± e›=Çz½>::ŠÇ+•JÍÿ-nŽ(œ/•J¸TF„S§NáC¯ýë×××GGG;::8Ž›žžÆùe؈Òjµ Òitò$ú³?C¿ùÍïž×é »Ý^,‘ÑDk ƒÁ000Ю)QæiXY;11¡¼o±' ÃÙýd7E)E@®pà'ÍårµZ RÇâÂ!ŸÏ—Éd²Ù¬ä:t:äY•JÿŒr�Å\¨]]]T›¢¦bq1u)(8èÜït:A€ ÂM¡ÁŠð› ž��…»G"üð.—«Z­’û%˜ß™L¦†¬×ë$’×ëõf³Y@«BR9«II ⛚l*»iP†èҨ?rçñx ù„¡ÊT­ Ö*”eRæ´×+’CŠÿÝ´÷ðn³qÂìŸä‡”´í0!><:: ÅN§Ójµ^ºt ÞÖÛÇ?þño|ãÒŸ3€.üú•ýùô­oI|Œd2)Êå lÄ—Ìq‹žL(Sëªäµ”›4dÎsOZåÄ¥ …ë¡ÙÙYÉ•ý[)Í…Ir©³€&ÕçóAÉy Å„ ±‚š7 dó!òá©fY¶³³srrÒd2™L&ê`•‹ø½^/Æc%“ɆӘ|ø q}6 5Â=)ÈÅåñx*• î³,9b £l4uûD2nÃ'ÞÉ™ÉdT–b“½”­¦e¥Ìi+é"Ø|qqÑï÷çr¹L&C’äÞXiÝ8FŸÏG:€bT„²Ó433”Æ81277‡§K.—cæ?øö>4Í5 [2ûÐB×j8p Z­f³Ù#GŽ<þøãèZÕP«Õ$+@#‡††p‚béííÅ=ÖÔd @§ì˜’Ÿ´··wrrR¬ðÔÕh4PˆCIű¶¶&ÖA•J6„pƒÊ>7ðûÎÎÎX,–ËåX–íëë»|ù²XŸâÔl6K)w`•sÉrV5àÙR©400påÊ—ËÅqœÜæØcü¨äâJ$ êïzÀN‘_¿X,¾öµ¯]^^&wq� ^æûöíª§­ˆú8CL­«^” ­˜"¦1 8Æt_&L;mœòù<¥ÍÇÇÇaΙL&¯×;==J¥’ÃáX\\,‹Ãûö]DÈ1A�‚QüÙr¹@L¨åŽ;îxâ‰'Ä1{oŸõWB!¤ÿ&ª>ˆB7ß|óÄĦó© V£FÙ#èïï—ãÆƒsñÃ+Ž÷°Xxž×ëõ{›R[L«Š•šÃá0›Íb‡ jppž§!¹Ÿ 8±,™bb_ªM @Ñ‘<³»œÀ‚>Å9–Z­&Çë³oß>˜ºÔãiµZ¬”açLܹµÙСZ­Ž»\.¯×;55…ß!´ÿþÑÑQjÀ(*aå[°,»½¸@üŽÐºlrrR¯×SCQ.————ÅWªÍË6Yá‰'† 0[á’ßiãät:qr��ÛÔ$Öh4z½¾Z­âiW¯× C¡P( `À)Ã%›à€X­V³Ù‹Åúúú–——É„ƒøÔjµ'žxè5±ãy¾R© Ü|àüsç- KŠM• 9Š£ÉÉIªs¶N§«  &S6›…'”|e9ËD>˜Ëå2™L É5šÕDÅbqr¸¯b9{ö¬Íf»ùæ›É?&“IÉ™â' ÝØØ˜BÿåjµZ=ÏÜÜœÉd‚ž&‚ h4šžžÈeA©·äÎVš$ ) ™À¬’·–{ jê™l­Vëíí½rå œe³Ùxžo™›<a½^O¥Rv»ý­o}ëøøø•+W@µŽŽ% ÏóØNwuuÍÎΪ1XÏ„ÃaÌŸ»½R.—ÇÇÇ}>___Xzò½666$ñø[´.FÍë›L¦|>OÝ. ®¯¯oK4C^f&þ‹N§«×ë»Í>ÉVë=zm¢í,‹¸ &ÏóÀ0n<Ï+”®¥ÓéÅÅE»Ýn·Û•ë>»ºº •çr¹Èî¼]]]<Ïo¤6LÿÃôúy=z¡úO¿MÑ›7*DEçç!EÛÞÞÞ,×b±àzMLy">ÔP®4rOT~G˜Æ¹\Žt/¦§§/\¸°•ÎR€íÛ·oß¾}û:::`Úív¼ËÇ,Ú$gÁÿÍf³TÀ3Mý*F£Ùl&P2™”´LZ­–Dá˜Ífñª4 @€¬Ÿ†æFÀšJVÉ”’Œ '&&äT³Ùl&—þ@333×Ã2ak‘ÉdFFF Ôn–2£ÙµUPCéêê|4ÝŠe’ë9�†jªVóÆGN?þñaâZ,É9](Ä í‰‰ FCúMrj:—Ëý†¬±“’cÇŽŽŽ¦R)“ÉT.—ÿÌ[­V››Ðý¯º3¿…‘ç7†aVÑ*Uƒ'ÆfOMMµ··7Åép80k¾` H¥Rä!5ÓÜ´=;±BòþØívN×ÂvzC)‹SSS`ÞpòÙëõªg1Àùg Œã8Žçy�EÀœw8�À€f+â ¬ÕjM&¼ì˃Aˆá”oÍqœÙlÆÆ�ö]¨ Hu#›ÍŽiµZê1®±ÛíÀJƒÍ'hÌR©Ô°;"À­šE¢Mþ\¬ÓZF=Úív5k¿a{rl{ÿ:†aìv»¤º íN¹8§R©Ôl€a ¡ÖÓÓC¤)èn?6ZdˆöôÓOŸ?¾R©¬¯¯Ãú1›Í‡c}}o·2‹‹ï@H¯×Ëum0›Í¤g§�Âe TG¾h4*ž4&“I«ÕJ¢T†ž¬­­]×v÷{B­= k9??¯À3+ÎÔ‰é|ÄÓ O*­V[©TÈmцýuÄ‚‰ àáµZ-&å‹F£Pü¶ººJ¾4WC€€#‘Ò§dM#Lò|>OîFÄãqqÇÅþûÖÑ{ â n'¨RÏ@j§)OBY§™L&eÄ4žNÔÚ—›3ê§ÍžBÁ½Å"öÌf3v×ëõ]¾•°ý}�kµU)[­Vñ$6 ®ööL&CFÄx QÓÏÑb±ˆ ñöàM7ÝtþüùBˆÐòî Œê%˲^¯7Lò¨ïv³íÞÐu•ï}ï{—.]úüç?¯²eÀÏþó_üâðï¿üË¿Ü=ÉI(†[£yÅò&ƒaã\,Ë «ÕΕJÿ‘Ë=žÍVUh^øc[[EX«Õ,K½^—t“m6›Ü!Rü~<‡m†a2™Œø1 ØL<»ÊårC?’ºšä$WYæN]­³³s~~^妅Ýn¯ÕjೋŸAe¸‰õLË6ÒápHÒ#Y,Fƒÿ …TÆ‚[´Ö-4ÝhªV¢^¯C‚ÑjµBmÞ.WM­tˆh–îvvvÖëõ‚¥ o�…©6ŽãúúúŠÅb&“†JHq@¶R©T«U³ÙœËå"‘]__¿õÖÎ/™Í…-.’c—š‚ÔYõz<ßL&£°Càp8ÔwçÛ:CåËàààí·ß®²•ί~õ«ãÇW*•Ûo¿ýé§Ÿþà?¸›'ú§ìö±pø¿¹\o0µ s²XÌ BP«}«ÉôÏÏÉööbï¤c&OÉd€=Øl60Ï‘H„Ü?P“§êíí=|øðàà`www(r»Ý¤ ””D"OR­VÅÕ¤˜N§É ò66«ÐQ;PP<–e±û¨ÇC†šgP–|>”ƒ-¸/’9öT*EޤÂ�Ã0˜¶TaÎ\?Á__är9ƒÁ`2™r¹X¦-vÊØ.áy> ♦Ê8‰y1ÔøVƒáöÛo§ û=0T‹Eê+V«Uì8�C%Bhrr=ÇqF£Ñëõâf³ÙÞøÆÛî¼=ZøÀgu#‘8ªzN[ÌPyø˜oˆ$“É»7åûßÿ>Bè'?ùÉ?þã?ær¹{î¹çãÿø©S§î¾ûî‡z~ÿ‰O|~ü‰O|!4777>>~ÓM7ýÞïýžÍf{úé§wm~à_=ž¿r: BèÿL&»çæÞ¶¼|ÓüüÙMÕ?ÈqO>QùÈ�� �IDATB©··W¼M Éä_ …B,Ã3À¹,îH&ô2™ÌÚÚZ$9|ø0PuPjñСC;¸2 rxxX’?·¯¯O«Õvwwƒê‡ÇÀø\œ„LJÀSToœ”±¢-HkVX°%ó~äÕ¶µêõú¶á*KgggË}ñÇ©Èd2Ù”'± qr:5NëU«UɺeÕ\,GFF Óüü|8N¥R™Lfzzùý&“ÉÓÙ933(»Ý¾´´T*•î¸ãŽgŸ}‡·°¢H0\§Pý~?´ü±Ùª~¿t>¡­­ÍjµB_ *0LIÔ¤¤`†Jz5íÀ|Ý.¹óÎ;M&Ó¿ÿû¿?þøã_øÂ ÃÄÄÄéÓ§ËåòéÓ§Ï;W*•î¹çžãÇ †'NüèG?zê©§BoyË[4M êò†Èu:ß¹¹‹ðX6ûß6ý⤠|0)ãÓÆ²áp<p­;9773Äl6»Ýn¹þÙ$ªÖ˲Èf³j2À+++û÷ïooo×jµmmm…Ba~~Þår‘Y<–V«íííïr)/U94Þììl­Vƒ\¶ÁX_ctãVJ{Âáp:ޮ┭›:¤ím·Ý622ÒÑÑ! Ãß?•ä&nVàcY,èo°ÃÊaÇ qJµ*EN�’mœ0Ñh�Ò;·€ó€Ždóóó`TàR¹\–7 œ¦§§ …Âððð‰'Èu^«Õ þ}û uôðððñãÇ!íïïw»Ýããã§OŸø—9N£ZMë÷·G"t»I³Ù‡«ÕªF£a5šÎÎNžç÷ïßÏó<f*®^É’‘IÁå“ÜŒÅbdšB¹ÛÛn3gÎ<ñÄ@£@µãD |ë[ß‚&rÙl¶X,šÍæ{ï½7‰Œ}ík_{EX¦C<ÿ "8þ¯×fY'*•Ÿú娨‰Ì[˜ M15Ôjµ—_~8&`:)TW*•r¹¢Ñèüü|¥Ra†Ú„ ;VÀ“`žÙjµŠñ¹Ê¼«äYrÉFhÂÆ²,Ž«Âá0îB §Øl¶¢U¦1‡ ‡ÃàÂS– å±2¡Ùä_ª­­M’PTœ¯V¨CÚ ½ôÒK¥R {ÀƒÜ W£Ñ «Tžø£Hj ²m£‚X,Hí3 >ÖÆÆ†rQbÃ9sDà¬UH§Júbbñx<år@×À ÊÇ4 …M-«þÄèWŽã>ð<õÔS‚ ôõõ-,,ø|¾z½¾¼¼ìp8ªÕjWWpddñøñâ×¾Ö‘Ëßð†g¾û]:÷röìY·Ûír¹ ÁàÒÒR±X„{‘N\×"¯×ÛÖÖ´§’“#‰,,,tuuáQ¢~†ßKżKŒÓ}÷Ý×ÕÕ%™» Lï·¿ým„ÐÛßþöžžžGyd÷[&­VûN'^«/‹Ó"'ô±\îÞÍ*¦«RßÔåÕ«WK¥ ˆJO–œ¡Pó `#Aú Ãà†oñxüÌ™3âÏÁó|±X´Ùlz½~yy¹½½³cà{¹ÝnA666䨵J=þ–?°ÁŪ-Nçr9N'žÕð^P@T>Ÿ‘\) [-KµZ­T*ø¾X‡V«Å $”^å®,R9 ¾ÜPàhÿ�Ò'°‘l0ÀŸ(‚šÖ°ËÇA™\¼xQ¯×·ÖÀ #ˆ}>_.—£l¿²yƒ9ÓìÔÖ¡»ÊO¥Q8Me-ìÊÊ |*¿ßîU>Ÿg?(Fj»Ý.'Ôëõ~¿ÿ™gžééé àæóùd2 ø¢Ñ¨Óé½ú…/éééÿÀhË„emm-Gçç ¾¡#ƒ«H———/\¸`2™ä0zSSS¥RIn”HŒI]º«äío{__ßo~ó›Ï|æ3’Óò‚\¸pá™gžyä‘Gn¿ýö+W®|úÓŸÞýÆ)bµÞEx¸ÏK-ûçrÏ ¡_æóÿ»ÔúáÊ•+ÀŠbµZ½^/I’© ßɈ¼P(Pzš…“®ÌÔÔÔÌÌÌ3Ï<“ËåÄEÉŠÅa!@ÊQœVŠÅbkkkn·[®4ynnÎjµ*?¿ÝnoHca6›%I} ƒÓéôz½äþ6¹²HÁ… ™LfqqquuU²€h}}ÜêT£:)x Ã0 t-H(¢Ôšœ2‘ŒÎe¢æ ÅŒ±”,--5•/å8ö;›}}\þsd;C¹™™…šÊŠÇãä²,‹'ºÑhL$KKK‚ ÜvÛmx à³™Íf(ä­V«Ï=÷¸üf³¹á0©Q(,ËZ­Vžçñ¬ŠF£jr›âµMê1ué.‘w¾óÉdò‡?üáúúúNŸ>M+¤R©ýèG§OŸÞ¿OOÏÉ“'?øÁ~÷»ß½÷Þ{NçwÞÙÓÓ³ÿþÓ§Oÿð‡?L$ï|ç;wÛ ÞR.³D2íœÔæD¡^Ëò²}zú++«òµOù|Âèb±èv»¶ ¨Kc±.%gÆétæóyrK â§ÓY,gffÌf³ÑhÄêˆ0â´ôz=ø|‹‹‹  â~Bä½Àfˆ3 @A‹MDx”:v8P»5xÑId#„$+2(!×#¶Ujt.åþÖëõ¦ˆijŒ«W¯Š/h·Û¡ˆÓM•:ކŸ˜âêu‰ò;âÇ &0á’gñ<ß<kmmM²=ض¥=¶÷rsss@ÇÞl…( ÝM$вóĉ¸\güc±ôzD(SrsHÁ¡PˆjS©¤–––ŒFã9R9Ž›ŸŸ§‚V¿ßoµZwðíïÿþï¿öµ¯MMM<xðK_úÒsÏ=ÞøÆ7‚.…BôGôðÿûÝï>vìØ±cÇ´Z-øìŸýìgï¿ÿ~„З¾ô¥'NLMMÝwß}Ÿüä'w›qºõZsZ>³ª¾yÑúúºå¨�rÔh4¡PH"àì4¨´Z­x É…AmmmÇ ‚�ß…‚·SæG«ÕÊa­€y}mm rJ’Ý#·žD¯×ëõz*Œ:ÞúY M ô¿°X,‚ @Ì'Æf™Ú‚Öš”ži8þ[¯ªå8®…áÇA[áJ¥²¼¼¬ÏKÉ¿½*L²¤ÍívG"‘‘‘<O`»,Òí†1ä8®T*‘±—šv9N§ @;š“¿m¡N±Z­â°Ýãñèõú•••J¥R,<xîܹ ‡Ã1<<œËå<øì³Ïîß¿llÌïoChI[[[6›•tƒ@Êd’›¬'—Ëáäi>Ÿo¹k=v“%ÔŸ Eï “Étüøqüß;úAoo/ù0H¤ÜyçwÞyç®Më ][ƒ»R«!„œÍ¬Ö{ÆAž×#´T«(þïtú‚ÌÚSÃq½^o±X°¯æóùÖ×׫Õêââ"uH,™L¸Ps¹œB³V« ™ÍæóçÏW«U…}ïz½^<iŸ8Žs8«««¸Váu`…®®®ÉÚñZ­ÆÖ Ëå2›Ípe–e½^/DcõzŸ+vÅÀR…RÖ××Ýn7ÄjÛ8yZÃ`‘k¿YR>9ZÌ$ÂÂÂ9\øãR*«>Hß)xêr7Ú^ÝåñxÒé´òàȦõ�å@«ø`Ûv½^/N2 ÓÑѱÅNMù|>—Ë厎 Ð5 ‡Úg2™ÉÉIŸÏ—L&{zzȦŠù|^nwN LÙy‰ÅbMõôÛ“­KøÚ0"-ï2™^…þ§óˆ^ob–aBZíÿf±ü:üœÌ¾ òWã8. Iƒµµ5Š"y%IJ±XTž·‰DÂjµ†Ãá£GBÛe9) ¸ï©õ°–ÉdHeÐHÉ÷ÊårT»Øp8LEl.—«§§sgT«ÕÉÉIÈÉy ƒºTµZ•«À‡Ä´°7P(6%Í61�‹"i‰ÄÊÊŠJ³át:ûúúZÛ%ÚvVF ÆÞ\ä$‰´M$$/5N8ƒÁL&Ü—êÛŸˆ `¨ÄÍñx¼P(@Uk2™¬Õj Ã@\533ãv»c±B~±w ‹ÅRÕé:::¦§§Y– ƒdJ}ffFÁ†÷ööNMMµ[ãyÞï÷Ëcv³üìg?ÛJ£°]"®kAµ_éîþÌwdæ³G^¾.ÚLVî. h9¹£E2µ¨aO–‹àÝnw½^/vÑ=N§ƒæ&rkPlp!É''ápÖcooïÜÜ\  ½o°µ”k<88844466622200�°wè¾°°ÐÑÑA6“u8ÐJU£ÑÀbÄä¹TCRð¡]…‹WÆ>«Ôä'V™q8 ·!/w=¸[5nºFáMÈÿúý~—ËU(AØ·oV»x¸ar|ô£%g œÕø!4š×¾öµTCÆžž°ÃÃÃP¿W©TÜnwWW×k^óšÁÁA«ÕšL&UÔ®¬® …¹¹9ÈSŸÞKî\ ÔÈ )W�bèî+Nn¹å5@].üµ;‘„ó¥ÒÛ——}33¡ÙÙÿ¼ººx­»}Üélor»Qgvexx˜œiÉdLæÁƒÛÚÚ09¡ÅbÙ–ÓZ­¶¯¯¿W(”©àÉÍÏÏ“jNLDdµZ#‘Èðððk^óš;ï¼ÓívG£Q—Ë…‰â�ÚAší……Žã‚Á xEâjÞp8¬¾¾Àn····IÔÖÖ]žA@§)¸˜)³Ù‰D<¾ x4$3lÊ¢ÓéT6†€‡/ ÊÍËå²ÝnojìÆŠÚuH—.]ÊËÙÙY ¹¬V«===‹‹‹/¼ð‚œÁ0 0á‚�”¾ çÏŸïííÅü7!`Å5 ÇŽËd2~¿¿V«y½^žç¯\¹X–žg0, rìªÕ* Øû¤~ŒÊå2˲cccèÄÄ„ z½> I6PÉ4ª¸Ø5BºíxñÅñø“ÛÂcåòÛÖ×=\,f2™[X8S*½ÐÞnÝÔûÃüg‹åËD I&Û‚X,·ÛÃôƒ^¹r+}§Ói0À}Áœ§pG8D”ëëë—.]³vuu±, \F£z¿nKvë5¯y ¹–ñÆ,|tm{–e<8:: ÅÐPÍ$ ¶­Vë¹s熆†^ûÚ×NNNz½Þr¹<55…¯Àóü¾}ûΞ= (ÆÅÅE¸Eƒ)g¢ ˜<“ SÁ.‰Iòx<†TôårY¡ˆ.›Íª´7}}}Ñh´X,ž‚cít:Y–Ué×ÂëiäŠÇ–JÀêõzñ½¬V«Ãá kO$×¶Ó7mœÈ{ ‚�Ôf³ÙívXx�kùå—)÷¤\.ƒÁ¨×ëdƒöövhGÿ-‹¤e¾€b±ø'ò'/^ììì\]]mkk›™™aYvii‰a˜ÑÑѾ¾>„®àq—ó­¶²iVq¬†©u1m¨@þ3Àjµ ¼;=<<|áÂ…b±¨¾I¹¤ë}éÒ%9î=Q)8Ž'±Y…zÝH§/%Éb19>Ž6Ùƒ¢Õê·ÒéO»Mo4™HãÔÝÝMöxl!}Af0Î;&ªÚH_*‰ÌÏÏ×jµîîîññq|¨£££P(PêP“ÓÓÓ 4wvvVQÞ¬œ<yRrùK²E‡B!ðÛ`Êjµ...áY*•aÿþý^¯×ï÷ßrË-ÐF§Ó?¬ ¥RéìÙ³ .ŒF#în.Öwä_(­%Ñp8,îÛDþW\ͤÓéB¡BºJÕŒ­Q©TRNù$ õ £›jL.þ£\¨-f¢"ùsqcöööx<¾Å ²-'9ÏÇÇ)÷{G"‹!OÙ_\½½ü²R1¨^¯ïìì´ÙlÑhôÔ©S‚ <õÔSÇŽ ƒÝÝÝ.\XXXèîîN$W®\9vìw'‚óHÙö¶¶6ÆãY"\'»ÝŽÛú¡Í:ò|> ÅÐtÐz³‘Yá!”2¤RÖZn"sª&2ëïï§Z4îɶȺ ‰l˜$÷gù<iœú®Í¥>“J1›ÍPø y4Àž éŒ[,–h4 ÁuG(¢. Oø‰‰‰r¹¼EËd0�MÑ쉰¥ å³³³Ðïÿܹs¹\Îl6ÏÏÏwtt@!�ÇqÇ¥R)HŠÀ&“Ñh,•J,ˤ©!… Ã0r«µáZSs–^¯¡\.[,تQ°LZ­V²èÞKÂM§Óá†#Û[n@jB–eõz½dl§pHRHÚd2qÇÕ”õo³qb@ *½B¹Z[‹Å¢×ë¿ýíäÒ’½Àê×]¿9†®¯®›Íæv»_óšrooüÔ©î+WVAp8<ÏC¬³²²röìY‡ÃQ¯×}>B+¤·ººJÍì|>Ïó&ûýþ_|O¦¥ž%4PÉÍÚééiô<BP¸ôŸ:ˆÐŸÿ.÷¸õo@RìÉV\%ñç«Õ±‡”—2×êS3 ÈbQN. Ù$“Ýn‡¶ªTš(4%5”ÅbI§Ó’o釥¥%9 êr¹äšo‰˜¦ÉgòÊ  Gñ+ƒ+wãî¾ûn—Ë]—J¥R,cY^Êår¥Ói·Û Æ)ªñÁÉÖJ×CŒF#t;´Ûíz½^²¦ÜétB (  ?6 ú±q²Z­Ôðò<ÅÏräM tŽ€X‡œ3ðrÆIîPÃ{RMMüz]"'fFŸÏ§’!W§ÓÝ|óÍfóéOšéK÷—è›?¯p¯×»²²20€>ô!Ën;[_w?ñD9—«---A)y©Tºxñâìì,4ƒÍrÖj5±™N§a®ŒF#½»ãCèN„j•ú¿d^ã¿#ô„~ŠPB¿Tz_—ËU*•šb¼j÷¾eeeUêïcå2ÙËլѤD6#sí_òMfÏÅËDDBA#F#0Ç+à“¨â.ÀóCN2‘H@’°…%,qÍ!d¿q9¸Â‡÷ÂG¡r,•JÁ~°!Äb1Àlåóy«ÕZ.—A€'„®¯.—Ëëõ^¾|ù†—Þaoc~~žÌ@5¬nxe–eÍf³d úÉeN•g³Ùm¤Æ&¡Êäó”Ëe9>D¢Õß‹œ;jœ`s’ôøÈªÓZ­Æóüðð0˲╤?ߥRùOÿt± Í Èƒ/ß¾óÊ€£¯½¶¶†º»Ñ=÷üv…<ÿ|íþû—G<Ž*X,gÆËG®Âe76PµZGh6ïGÿ|�¡o¢š½¶\YÎç¤Ü®£O ›×Э!t…¹âr¹µ ßP¡ B„B/!ô¯×þà¯ú8BGèçý\i@[ã—¬T*»œ2y—ËÔÔnp …p$ñB±øA¢¾+¤Õ¦Dî‹áZå­ÕœNgÃŒ?Ài¡ €úç¤ö3Z˜-$‚U¹šßïW®i¦B:»Ý‹ÅÈ@LCEí½aµ�Ú!•Je³Y­V[«Õ&&& R"§ÙÙÙz½ …ŒF#Ž ÃáðÁƒµZ-tÁ¯T*£££>Ÿo~~#moÈÔZZZpˆ±+°²² … Ëšª óæó·ŒéV–†œaÊZ æ p1cGÙl6ët:q¢­Ük{"'R¨4E<×jµ±XL¹iP±XL&“³³³ÅbùùçQ†Ó£[/Ž>j·Û5 ^ÿ‚Pä‘8B(ŸG÷ÜóÛsõ«äùóˆaÖ"‘Ît:ÝÝÝsæÌé@ P,ƒÁàÔÔT©Tç;ÿÉÇ~<?Ò¹Õ,[Ê%e,°Íiщ«¡:ª¯!Ñ’¾¡ B5„žI�#t�¡Ó 70N×µÙÔž¨r#ðçù|¹^ç6géaž'ªvüy©…§Óé@Qâ¿�(õ³¶¶¶b±ÐÕÕÕ°Ošx‘k4šp8¬�ŒS�ý@îˆã80Z’O¨°À3™LÃðJpZÐr0™Lvtt`Þ ¯×›Íf!Íu_¹\nqqþk¦^¯hgg§Ëå‚Â×gŸ}V„¶¶6¨Ø.U¨Óéü~?ŽS}>_&“i˜HÄQõËZ­&éÇ(|}<?aËcë\À*Ú3JîçᘠæLoo/Ã0Ð ¡ÙR “É$J*Ä÷n·[\ѦÖ8‰‹’T„7‡ÏÂ'þä'(n4¢÷¿B:]Ž´j‚€!„ž}ö·ÿ8~ÝwúÞ÷ßôþÏ—+•J8œ¨V###(Ÿ¯–JÑl¶$ÂÉ“'WVÊFã<TÜ¢òïcffæwHÛ[÷ÖŒ>Ùn·OOOÓÃýW}¡I„j‘7â·!ô}„îo}rD"—˵üžH ,?Œé~$›}ï&*þm&Ó¿nÒ(FzŽ]Û»ú_Óéü¦öD"Ð_\|,Y “Édðìj ¾E²Jžç˜ËåäÚè…Ãáµµ5JÏ’KU½À)˜$·V«ªõx<°[ŽGÃd29s†lŠáv»çææªÕªN§®Óéôù|&“iuuP½ A¸ bµZM&×RßQ¡ñA{{;`œ$S¡pCáëã³ …ÂNv«Ž=åßÀk ÕjµÒ9°XšÍIø»’ët:Éê2q½$n&"BèŽ;î YÒ ôâ‹èÅÑýºç4?FFFr¹\¹\N&“§R©´µµõõõ•Èââ"d2™ ù™çææ:DÚዉ€pÑ&nî·Çþ¡GzQÞ2!„~…Ðz¡gú¼ÄqÌô…EŒÏÅ>ãžì€‹EXc_I&³›Ä› †Ã<¦Ô(‹ÐýÄüü·‹ÄDZ\\„y…÷ö=ÇãQX™8øhmã¤^¯«¯Êíì줪ëëëËËËñx\ÁZ^^†wÑjµÒΘü!„Á` Û›áV4øá×××WVVÈÑ€¶,ÐêÉï÷»ÝnHñ‘ÛífY*æ¡þâðáÃÇÁÚl6ªA”2fëbqP"•·”Ó¤+++[)Vóõ«Õ*¥ýÕ¼WËR.—U–]ÀfXk•-„¹r0öS¥R‘¬Ó;À„›L¢óçÑâ©…ÅCoûÎwP"‘€yCzš×®1¢JåwÛúúú™3gN'`Ë)ÖH­V {t0çN:E~‰b©„Ë%8ŽËf³¿«€\CˆLØä¤×ªI‹–*"”BH'ªS%•—/_†¤ ¶[¯{ÝëÔì°ŒŽŽz<žO}êS-œûýïßãñ<ôÐC»Ð8Al„Ð’ |dmM¨×áã>äõsœ ÕjUÏ0ÿÐÖ6¼Y;~I«¥øœÄ$¤±X¬åÈSв,;44$yˆ¯×‹ ¡d¯ñÙÙYÀ½âX¨Ÿ«ÕªBB¿TµZ—œðpH!`Ä!˜Òg¦%�æ“§œ>}úêÕ«étzaa!‹AoÐàÐ.6‹ŽŽ^¼xqff&&Î…³È«©áñƒOÜòüQC Mz-™,h'ɱ•­VK¾—JvÚ›nºé†Øî�yn‹8'Œ"T£#B¯=B¡ŽvôðÃèþÛü~˲ ´k0 ‘{µZ• uáRÏ?ÿ<,‘^ÈÀ8ÎK—.ÏHéžãª,[«ÕX–=räÈÉ“'å"\HQÕS½¿ß{]F¡ÇzLéMÅÿÅ÷Ï<óÌøøxST;£Ä+• $db±X8†Öx8(4ˆF£ð"Z­¶¿¿cccaazAmll\WÚ±Äh4BâÈãñœ(•î[Yù§¶6VÒj_Ï–JÙzýf޳³, Âw66>¿¾^¸žmãƒÁ 4ó. N¢ÜíÕÕUŽã  Pñ‚ºÄøÇz½ÞÑÑ1??KFŒšTóõ-‹Íf§èéÄó$µ®ÉdŸU©TJAc°,ÛÑÑd7à˜V*h³ººêóùAéèèà8Žìô¡ðlâÀnJ‘jZ§Ó¹(ŽÕ�­,©Läž°»»{bb¿šËå‚Á 37d}ÙívŽãTÖlï¨q‚ }eeE!zåyþ·[AR‰ÊÔAÉp8œL&qºÖår%“IXƒ&· Çd2MLLQ—2îÁår¥x>ŸÏ×j5 ý.ŽÇÅ/E.9 Mx5%Á¿ûÝï>ôÐCï}ï{?ö±]¸pá]ïz×±cÇÖÖÖÚÚÚ¾úÕ¯–Ëå?ýÓ?Õh4‹eddäá‡Öh4O>ù$BèÉ'Ÿ¼ë®»>¼«ÞGX?O#tÓüüX,o1÷qÜÍ<Ï ”„“Åâ‰BáÿÝØ˜¾þ¥ü ¤ºººfgg)¯ë/«ÕJ‡ÃuØ’øG$…´“œŸr@Q$êa!'mmm˜í‰:Ëd2)äÇpPÕÛÛ;::j6›Òd0ÀÔh4<ÏG£Q£Ñ ‡,Ë¥K—ÚÛÛâX%ýæ@ �€“)I×ëõ‡C²C ¥L�òûýâr 1øÉ4P8kÇD}‹6NP áp8”˲*£«ÙÙY«ÕJµðñz½ét–±Ùl¶Ùlн…BÌ¥åe¤:ƒ €_¹%a0Ä<r‹Åét^?°ôõ–¹¹¹÷¿ÿýwÝu×W¿úÕ»ï¾ûCúÝnôÑGö³Ÿ½ç=ïyä‘G"‘Hÿ§?ýép8ìp8>ó™ÏüêW¿úð‡?üÉO~òÃþï‰:�� �IDATðn³L’Â9ßI&ÿŸ&c q@†6«¶0 ³©³@+±,k±XÄ{‡ƒ4N’ûê˜BZŒë”›ŸÇaÍØš(´»¶X,ÕjUÙ8Õj5(dM¥R ÃÔj5¼¾0»n­VƒŽG 4&''µZ­ÍfkÊ8Ý-peíŒqROÿèìJ¥s€Ô3v»]§Ó‰©1 Ø»P´Z­ÉdjŠ$~ÛŒ“ËåÊd2° YƒÂ›Ê00 #æ½&Sñx|[j.tC¹’ Ó‰B0jæQ E£Ñøý~£ÑØÖÖV*• g'³ Û"G½÷Þ{ùË_’N߃>ˆ{¾ç=ïáyþG?úÑ+âu$é˜C¡TKƒ¦nÍõ#·xž‡Í|r:9Î\.GÙñƃ˜Ý{ ’QK2™k(1®É”‰¨Ïç[]]U‚R€¶¬¬¬´µµ% ûT«Õ°yƒV–X™T«Uˆÿl6›ÓéÔjµkkk@Ë ¬Œ-|#Ðév»vž®Gç·dii‰ä´µX,&“ Cz%þêk>a³£Z­Öëu9sn³Ù®«vb†ì¤îr¹666Z®HlnGkëÝgÍf³dóùjµ*·Ï¬ÕjqOÏm‘†•Žù|V¸Ïç3\[g,é©£ÏÅ‹kµÚujлóÂ0ŒÍf;räÈßþíßÞu×]=öØ¿øÅ ²ºr7‹ø+/,,@^¯×õz=ISIŠÉd’;D¥³�• Þ ¬|›Í&Éw,NU*•x<n6›îDMr-;åÒËGyw³)^憳º©iÐcñJ§Ó333™L¦^¯ÃQ²HÏáp¨Ü×Ôjµ‘Hdhh¨¿¿Ÿ¤ºWží TÛ¨‚È·Îf³ØCŠÅbMõ\—TD¦\?®,0«[›c[5Nb÷Ín·KÒ¥˜ÍfÉŠ[’¢‹25$ìoÁž¼ÛíVOè"÷ î1bwU w-ð+&“IàyÛØØxu_Æûï¿ÿÈ‘#Ï=÷Üììì¯ýëh4úŽw¼CÌÔŽzðÁw¡"Ã0ápXafñJ¥BnŸà³:;;áh±XlkkS3Ó�–Ž*pr§Ói5®"ÇqíííjÈßòù|,k;Û«r0ù¦òI®¤™„±Õëõ’ü¹¤@™²cÊî$W_±XT郃_åñxÌfsî€h“¸Va¥S­}|>ŸzN‹ÅmpAÈÄÆkK&�á,¿ßÈ™†7*—ËétºC)¸V@Ų3+Qü‰m6›†¿ÆÆI¯×#›~KI.—“ßb±(™y,•JâU!]ƒÁ &ŪT*W®\I$.—‹çyjèF#¸W>ŸÏn·oe(5Moo/¹ WVVv%·{äá‡N&“ozÓ›>øÁ ‚pë­·>ðÀ·ÞzëÇ>ö±7½éM?üðÕ«W?~ï½÷¾ï}ïû»¿û;²èy7…···Skår™šH˜ÄAã€ÎÎN¹ø£³³sß¾}@K ©ž.ÕjHÓfœ²Ù,îà¹oß> N§|–úöE[”îînP ˜"‡•÷ÅÊ„LQ 0===Ta½×ëu}åËåòØØØÂ™3gÔØàX,&‚ÂN ÂM¥Rêë¡€ÿWNϸÝn²Ì@ˆ–––ZflK"‘PÖi}}}Ê}¶"PÝ£òÇJ{N˜g…”ÉÉI?É¡º�l¡þ‰‡‡‡‰ÄáÇüãjµæçç{zzFGGÁ3Å(tÊ Bí___ßÚÚšÛí^XXP¯#HŠÂááa(}q8F£Q}²›$looÏår8:ÔëõíííРswRâŽŽŽ–óøñãŸúÔ§�Þ?=4ñDýà?�'Ôï÷Ÿ:uÊ`0¸\®/ùË™L0•»äÄ8Ö••5˜ò,·Û](ä¦ñ‚F£i¹ñ¥ðeÙ¾¾¾……q} 4©kêŽTE€ÏçÃM [ÕÓÓ³-DbÑhJò½062ŸPšØÝݽ¼¼L޹Jˆ(†ÒK†#ð +++d8õß],˜_‘Ô9êGF¬ AÀ_–J#áÂgm{.8<<LÑWb·â¿CÛþþ~IN/J|>lvˆ3gêU«¼ÈÅó “M5Œ¬Á©T©M.]ºÄ0ÌÏ~ö3´ÙÔ’*^¯…øj<ÏG"°(Ï?ÿ<¾ZÃgcY¾}<Ç«ýâÅ‹pn2™ä8Îëõ‚+=<<Œµrß{jj ð(×$ÚÍ»P:gÛö@Å)x2ÇG­Vë­×UĬ¦¤‹RcJzx™‘Ó©¡ôõõÍÍÍ)øÝµZmrr²R©Hîi+œ¨fÅQã Œ´mJ”•vÕÓé4PZCÅ^F£Ñï÷«$ ©T*Txk’’v‚ÅC4<<Lá#Q#²cñï·.x@¨ïµ-y’d\îíÄ– Ÿ%÷ SSSµZMåhl þ©iˆ/ùJ,ËJ²ÜC “Ïçkê²z½žìN?11Q(~ñ‹_ˆ ®}*•JxuÕ7EùFƒã¸ŽŽøïðð0ֳ乘‰R¯×cËdhâÇ€ÕO‘u¢MÚ“”ßÃë„b—p:réoN§&ËÂq\8Vùã«W¯*g„X–íîîÖëõ0‘�„Ký@r:ñ</~ 5å<Û5Ô*w2€î€Šuòù<¶LâWF›ý_ðÉô;–p8¬¼Ð(2n,ÀvßÚmûþF£‘LB0 £ò^^¯Wް,+¹£/~)8K¯×Ëåô"‘ˆV«Ýú„Á‹Ûoœ¨#YkÄó<Çq’¤ôÊÁuCœ^¯÷ù|[É ƒÁR©„W¹sç$wò- |`ǃkuxžÇê 6Àðï³Ù¬};à …a{r½ó¹Aªl¸²¶¶&·!¿¾ÙlnØ~¦T*5ì>®^jµÚÌÌ dVÆŒÚ{—›NT¡H ÀºÈèĶêη••…µd½�ÜKü€ì&±˜#þ¯dŠX,ÖeßÕ«W[ÛÔÑh4ØŸ&gÚVD«ÕRÛ·f³Y£Ñ0 £²bpii ïŸÕj5É>sbU gy½^9ËýÖ_Ðf³QÀ×Å8e³Ùt:íñx¨ÙV(Ä– øÑÕ_Ün·‹‡Éh4&‰­`ë&''Y–mø$8rŠF£årj.òù<f[ZZ©j¹ BÓ Ø‚Rù=öd{E¯×cM733£Rá¯oµZ1DT.™¶½žÃ0&“)ò<o0VWWñ2Ü+—ËI2H¸‡T:§”9Žs»Ýb›\¨Ûòä¸E‹N§“4xÀK~¬âÉgXYY”&9ì©Tªa‘­ÕjÝaFiA°›+~¯–3~ÑhT¯×cï;Ub=ãr¹†Ñjµ@Ú«RÏØív²ËÜÜÜöÆ‹emmMeÿkmË÷à8Îb±”J%*Á¥l*Ð}ŠÅï÷CG}Jk¨¹¹“$¹þ%³‘ øÜ……¼%é@)g4ò-..îÎr‰WPúN€¥P‚e6›†Q®_„ôˆÁ…O&“F£1•Jëæö'˜œâ“›·X©-//F­V›Éd ÿ9‹Å¢xù(Ф¶ ÀfK1’!¦äV„Ò¶ÙÝÆQ™=#õÌvµEÀß »æØ!&õ †Ó”€&årY¥y.—Ë×{¯A¸½mÆÉb±¸Ýîµµ5rÁ�PN%Óp0;­n·;—ˉk.G¥RØùüü¼ØÌ`Rñ|>Ã0ʉQÀ¯œgݰͳrÅ*¬U—Ëe2™Ä›“ð"{ûR[‘ÎÎNŒ& ‡Ã h’¬¦ ó$àCG«Õêv»Ø`s~¿»4#Tš5{“«âpŠ7ÔtLPߺÅ`0˜L&•¸@¬¶ë›*°Ýo»(°ÓÊ‚^ ×Ôétn·»µ‰!Ù‰Ô3¸ôcyyž°)àZµZ•tµ)&Ü-Îdðõ[nCªÊ86Úär¹Ûn»­^¯¿øâ‹êÙ‰666Ž9òæ×½î_2›ÍF£1‹L-C-$A²Ù¬žYâ3—Ëy<ž†öIni‰×a(Z]]Ý ÿhƒ&VˆµZ‚;ìÉVä›ßü¦B<¤ÑhL&“z°iÕxžÏårƒÁl6c°mËÜ^/UÍb„: õÊB§ÓaR¥W·(  Ê±ÝÆ™v¾¾Ê8¤)ee1›ÍÅbQ½©xa"ÕœqZ]]…�nsàÀGy„ Œ2™Œ×ëíîî·Z­f³û>™LæâÅ‹ž#GÀö@¬055%Y¶æ*‰¬¬¬HÚ˜ÞÞ^ NÛMâäm¬A‚_Ûr©|>/M˵ÕÚ“¦'n¿ýöݺړ=ÙõòÂÄ‹Í'ìjuww/--ýÛ¿ý•Ê[]]…ý:¨5Be³Y*,Çã“SS&“ÉCu“²G¶¸¸¨`fggårºÞÞÞùùyõ9ÐÛn»-‹™8¼^¯J.m–eûûû)æI«R©üÿ³Åv p1 ï ÅžìÉ«CdÃ0G¥¨�7'†Lcp8B¨\.»\®ÁÁÁ_ÿú×dJ¤Z­ž}é¥z.733CáÅDа¾›nºÉd2>}ºZ­B?\Ë«`&''•#*ê10Ñ~~Ø{Ã(n­VKEi^¯—eYÜ V«AÍ+TÇ*”< ¹=i-lÂÑg<ß‹D÷dO^qByjÔ¥˜”1Öà,˲,+vù×××ýë_¿0euvvÎÌÌT7/ât:Y–ÅÁ\jQ¨„¸$eäùóç<ÿ¦*20Ń˜«·a®ottT£Ñpgq'ØÈŒŒŒP½¥Ãáðââ"ùÀ«««ýýýµZ o6ÂMw€˜kO° PѳxŸO²¢åŸ©?Wüwõ·ØU/²½çnûû¾ŠÇêU3â¿|ä#áƒ776N6›M\t˜çÿ“éµz}·Ng×hª-×ë/åóe³Oåó”ço±X¼^ïòòr:Æ6[/ò¿ÀþÉó¼Óé¤Â‹`0(Iq{îÜ9¾À65õNçñxš*^G›88+ollÀ 0 CQ”¢MÖ80Ò˜Ö3™L¾:º’¿ „!„ü/u¨Ù£÷‹Â!ê/[¹‘úÇR~ŒfRù^-†øh /%>´•±?†ø^Ûø·2»ä1¶qÂk4šýñ©ÆÆ‰B{…´ÚoºÝoØñ¥á¹BaÇE´ÚˆÙü.³ù¥bñ½««‹Ä>P2™„¶†n·;N+¤é€ýSºKZ&h?C9ÅZ­Öl6‹`ÙšUgäY‰DGE‰DÂf³ÉÕàČӶÔõ½RdbbâÅ_¼õÖ[%ÛÉìÉžìÉž´,²"ÈNB]Zí‰`[¦ó¥Òhôí++7ÏÏ_ÙÌéÑëÿ‡ßo`–eIþÈ‘mc”ï¥ E¤þX,Õ“E6%ëëë8a833£À _©Tv�¸Kä7¿ùÍŸýÙŸ‰Ó¿{²'{²'[UÕzßhksoZ…z½~,–„ÐF½þw©ÔßìÕÇq²Z¿™ÍRutb0t…I¥R@5Fñ)øø1°©èïïF£»„ ]£Ñttt …miÄ{£äÔ©SðÀ„B¡/~ñ‹ð—»îºëî»ïF}ýë_# …xà½õ³'{²'7Ì8™æN¢gÔSù|%F›¥N^»¿ò“éïÓé†ûÿ¥R ’Œ¹\Îï÷ã Äb±Øíö†™±D"Q­V%küv^êõz*•"«Þý~*•Ú%¶S¼üòËþçÞÓÓó®w½ëÁüèG?úÐC}èCšœœüÊW¾òÌ3Ï?~\§Ó;wîþá¾ò•¯ „>ÿùÏ×j5õ¤–7VÎúý]ª»ŒÿK¡ð…Wηۓ=yµŠl¶m``�þQC¨@T9?–Ë‘!ÂÒµP¤ùÞ_”q‚ªññq6¹Ýîööö†ñx¼R©¨LʉÍfSÙå·¡qJ&“d_2™,—ËTNfî‰Åb£££½½½oyË[¾ýíoÿÕ_ý•Ùlþå/iûÿÚ;óà(ª}ŸîÙ×$“É$C’ÉJD+ˆ P†�¾@4¾ªÉ|È.‹*\ ”×èÅ)@$<—§à±B 1PXOBЄÅÈB&ÛdÖÌÚÓïcúvz–ÌÂ2çóGjætŸ3Ó'=ç×çœßïû‹Šš5kÖ˜1c®_¿ÞÒÒrá½^?mÚ´iÓ¦éõú .DÄÕ)pÜË�è ãä[š9*´•$WöôìV(�tÄf³™öëeDÉò0 � ‰²³³»»» ‚°Ùl ß<”ƒƒH$âp8ŒÜ»†åææ ‚¶¶6*Àâ¿D˜GŒF£?ª€t$Ill¬Ç0®Õj½råJ$†.edd<d·øÄ�Õ"ÎÝcUf’q‚Ii!ÿc2´Xžàr¯ØíÆÁA¸’Á“ƒ‚��˜Íæúúzè ÈÔqàp@|¼ÇO4 ÖëÁ`/A€†®®Ñ£GËFŽtÊd­mmÁ\¥ËÜjü·T*IFœ“‡y(ŽwttÀK¶Ùl~*D„P2.RÖëüaB ¹.WÓ ü„E À81BVuñóÀøNßéɼ`òã€K·{¤-��Øí€Å?þßñù|§ÃáJÆØ@§r¡@Ðïio@ X-–Aß~çNðí·v ŸÏ'Âápddd\¿~ÝcKW%"",“D"IJJêììlhhxë­·:;;«««GŽi±XÚÛÛãããe2Yjjª@ €š€š[‡û̉Ç�œ²XÎÚlÚŒü¯¿†ðŸBa2‹�¨°Z]� Ó„@„¯qò“"šàD/A|Dó²ó°š×Ñ”�� ©©Z­Ö`0DEE‘ eXf¦ÇøÜ„´´Û·o“.�@(òx<nEJ111”ˆ@ £®\.ïïï×jµT&ø! Hµ>Œ†ï‰wîÜùÙgŸmß¾](:tH.—WUU-Y²dûöí�€íÛ·‘$ùé§Ÿ�æÏŸÿþûïŸ:ujÆŒTžû0DŒaq¹Çúûç÷ôx bØÛb1� Ÿ$¿@ÔD$§—%Ž_´Ùív+IÎ Wdxkr8þÖÙy‡6 8ŽSá±0#½5jó&::Ú·q‚‰Ÿçx´L�€›7oÊår’${{{ccce2eœd2™Á`ÈÊÊ¢tó„B¡ÍfóhœÚü[Bt¿®Hº9ÐK¢££Úó�€²²2úÛéÓ§OŸ>=œ¯+ŽÅºát~èóîšÅãñ1 �°ÏbÑ"o"⌓Ç÷Ž®…XHò}“iOw7c€g±Xtw5I<‡ô»£ç…ôG¥\#IR"‘À½".—K’$Ý£Á·³†?pýsPD<n:ãïÜñTp@��¸C{ûûÑnyÆÉ€“$Ù�è&“Ë5ŒÍæa˜�ÃÞ‹sq|›V«¦y:1|áBÉki³ÙJ§HÉ AW@jl‚Nðw7Zö~æëDÜu&r8Or¹�€-&“í6!aC�8z—kÆ;ÿÞÑ‘vëVúíÛµ¶&ݺõ¾>�� Ã^‰Î%&>K ×õŸqãÆÝ»+ìïïg(ïq¹ÜäädÆiiiiîaIJ¥2;;ÍV0�Þ‹�Õ6[5ʧ…@D¨q�\°Ù~²XäYYð­•$ßïëûa`èçãøWññIl¶P(T©Tþ7ëm÷èát:Ýw‰:;;Ýsjôõõµ··»Û-¥R5°Ù†ˆ\æ ã¸\½Ëµé&YG îã­×4 ]ùo£‘òÙãøÊ¨¨·´Úþþþäädb©tt:—ËMKK£üâFŒÑÕÕ¥Õj1 ËÉɹ|ù2�@¡P`ºÌ«Ëår×ò˜?jU4773üÈ»ººÈ»ºs^__ßØØˆnÇ q8O=õT@U”8¾M"�üÝdêr¹0´Û„@DŠqâp8ó\ÀB…B1uêÔóçÏÿ>8ÏÅt`Iöôô°X,*|uHH’¤{l_»v*‡– вQ¬]»öðáÃ&''Žét»åãCsrrèjIƒ:ÂK­œœœææfF?P-Œ5êêÕ«!*AX­Öœœœ‘#G¢Û1².�»¢£¥8^ïpT"÷q"‚Œ†a”‘Áá`�\ìïð믿¶´´06dRÂr•J%›ÍfˆýxLw‹aØã?ÞÐÐàgš¾?þX $IÍ6衾éééMMM\.×}zä#$6==ýÆîfÆjµòù|Çív{TTû¯¹¹Y¡P„èaA¥óB„8!ööÜã^¸X$z†Ç�ì5™œá-‹·„iÞJUü©èíE@_ÃÛ‹@?ÔG#]”ŸýÊ÷ îßÄ÷òä!ûç®\TÐÿ¯{ý¿âöÖÉÆ óË8‘$ -S›ýB‘Ëç�Þìéùt@Ñ®¿¿ß£ 85漂 I¥R‡Ã!“Ézzz0 £L†aiii]]]þk¹&$$Ðm�Z8-4J¥’ÊTëjµÚcyssszz:›ÍÖh4¹¹¹'Ož´4¤TN˜0¡¢¢"”Q•Çãq8œHâ  A"‘�ðì³Ï:|êãÉŽw›š�IÚ1Ì6aB>z2’$Iö@¹xñbjjªL& ¥‘îîî;wîŒ;ÖŸ“OŸ>——çíIúÔ©S£úé§üü|úÂFCCƒB¡ˆбÓëõjµúÉ'Ÿ|饗€4chã$—Ëá(¿K.ÏÎ|=:zŸÁ@ÒFU.—+¼[ÓæeI ðèèè–––ööö„„„¸¸¸Û·oSâ­f³yHËDτ˅Gív»Ýn—J¥&“) Ëäª)†e‚‡îÊÙíö€|å .]º¨äû{µ®\é¼q� ˜4éèW_¡ÞCD"sçÎ]±bÅ”)SBiääÉ“_~ù¥?'§¦¦~ÿý÷/ÿ‰‰‰Çw/ONN>vìݤ-[¶læÌ™EEE”•}÷Ýw;�øâدîó&)))ðEí«$²Ù3hÎâ06vô`Oë_¼äÂ!I’Ê€n2™l6Û°aÄB!\©ªª²k™p1 KHH€f)::Z«ÕÂȪ¶¶64 Axƒøãguõ_7ðã£AD(ÅÅÅ9E{$##ã…^ðóäÕ«W»ç"§X»v­Çò5kÖ0öƒgÍš•5àò �P*•sçÎu¯èuæD’êþþ¥4·éÍ2ÙOííp5Íb±X,–Ù4ÙIî˜ 1rÚb–””ÔÚÚ*•JE"‘Z­–ÉdY÷ Ð…$Ib(õXâ¯Iêž=ÿzº>u"B™={vèdddøŸ%gݺu>޾ñÆËׯ_Ï(yþùçéo•JeII‰{E¯3'JÃt{__#mÅé ow\oÀþ‡X<W"¡Žþ]«½<ÌHe„¤§§ÃE<›ÍÍŒV«µ†à(Eé[­VcPq*ôuOÄ£€«½8uê_wKÖ"8Co\®ëèøÚh¤ö?ÿ&‘\IN>šðII X¨w¹–÷ô|BSØ„Æ)11Q"‘��::: r«Íf3ó˜=8áS(èõzMFýQæÄ‰ùùùpÙ—AUUU~~¾ÇÕäˆÃ9xõó¤‰@ ¿‚p .×òîîöõ½(Oáó³¸\9‹5C(´‘ä-‡£Ñn?Õß_i6<­Ññù|¨ä1ÊÕèñ¹ÝÝÝ”3fŒZ­NIIñæh7$}d2™J¥ºtéRRR’B¡P«Õ&ÌDòòòžxâ ²===õõõò:�€8{vq’JÑ€@DØÌ ð1cÆÐKn:ÿÔéŠ4š--ªÎÎ'¹\ùÍ›cZ[_êìü/£Ñàe÷ÈétúÞXb³Ù†AÇÝ7Üìv;ŸKÕÌyHßjc±X†Qúåb±8---ÐÑjµüñGjj*†a/^ Î2Á‹btऱ±Q&“-Y²dëÖ­2™¬¢¢"///+++;;{Ò¤I:îÛo¿5jÔáÇKJJd2YCCÈ#&OžLÍ, ÃâÅ‹ããã].×éÓ§•JåÈ‘#U*ÕîÝ»m6ÛÔ©SaþÜúúz™Lš×¬Y[ “~p ÄíýE Irˆ‚V«Õh4te³Ù¬Ñh4 •ëÇétÂ’!¥t:ïZÝÝÝÆÇÃ(U‹>6º×2 ð´ ¼'Fj *•J­VûvØ…ÐýÅ=’––Æf³ÓÓÓ�‰$ M ›ÍFו6l˜H$JOO‡Îd2¹{œûƒT*µÙl­­­<χwŠT*‡Ã ŸAF¥TVV:tè±ÇÛ¿?�àܹsgΜ¹råÊk¯½F…­ÀK—.­­­½|ùòÒ¥Ka ååå‹/ÎÉÉ™2eJWWWqqq^^ÞÕ«W—/_¾eË–ÚÚÚÌÌL‹Üa#ðfMMMõç>¹Oý@K; "ÐØ‡gnÞ¼¹bÅŠÂÂÂââbøãÒjµ»ví*,,,,,üî»ïl6A555°¤¬¬lPòñÁ´µµÍž=û·ß~ƒ6¦ººÖúàƒ “ÁŸþYRRRXX¸hÑ"’§N§óĉ°Ö‡~HÕš7o^aa᫯¾ Åí4Mii)<­¶¶öîÏœÜóp‹Åb8X_»vËåÂ'eÆ¡@¹~ýºÃá€6F¯×{Ì@Áf³­/“��IDATE´”»Þhmm5™LjµzH[í»AN×ÑÑ�ˆåõpÝÜÜl?•ëÄÄÄmÛ¶ÕÖÖÖÖÖ–••]¼xÑÛ}säȆ÷çúõëŸ~úi———Ëd²_|‘*ùâ‹/ªªªÊÊʆ‡S–ð¯× †ÂoáMeeå;ï¼SWWWUUU\\ �8qâD___]]]]]Ýž={ÚÚÚŒFㆠ`ITTÔÁƒ=6ÕÔÔ´gÏJ Î`0¼ýöÛ°–H$:tè�à•W^Ù¿]]Ý{ï½·råJ÷Fúúú¶lÙkñx¼ÊÊJ�À‚ >ÿü󺺺­[·®Zµ �pàÀÌÌLxÚÂ… ƒ‹íñ¥áþà/‹ív;ú ‚ Oëè‡Ü‰ïîî:üˆÍf‹Åbzæ ˜ß>ìÃXà€œ, qb¤Òp' \M|>ŸÍf‡óU~~þœ9s��?ÿüóš5kÆÿ¨É&ñJKm[·’íí˜\Îݼ}ˆ0çÍ7ߤ¬Tˆ¾ã•••J¥rÒ¤I¡4Âçó§NZ^^gQ999÷îÚ½'¥Ré.G/¡ïîP‡”J%œs0Ã0‹•œœL’$C B©TvuuÅÆÆz›Z­V†Ó9—ËÅ0 '±X,‘H$‰Åb飭Ûðx<‘H¤Õjýi0ÔQÇ“Ëåðuø;P8p ¥¥¥ººšÍf»çb÷HMMÍäÉ“}Ÿ³|ùò;vœ<yrãÆ�€³gÏøEq`çç³óóчˆ,vïÞm4·mÛt ¿ÿþ;Ü>sæL(ß„ÅbÅÄÄ@i: ÃüYÐ ¯Î0¾•ÇãÁM ˜˜É@< K¶ÛítÔ„„„´´4os#J* Ñkq¹\¨„æ§~9e ©Ï2›Í½½½‡ƒ1oc,<ú‡ÃQ*•Aô#I’ƒA«Õz먨¨ðIµxñb•JUZZºcÇŽõë×_¹reH%‘H¾þúëÖÖÖ­[·J¥ÒuëÖ]¾|yݺu555sæÌP«V­2555›6mŠ?wîÜÌ™3ÃÊ8!ÇG}är¹6lØt W¯^=|øpAAA ieÜ1›ÍG------åp8pûê~Ïœzzz222nݺ×¾¬V+5ìêiÁLÑÑÑ,«···¨¨È`0=zÔLJÁX(3™LA@S°Z­Põ•áya±XŒF£B¡ð±CÈÀår 9ï‘Éd$Iö ÞZg]wl6ÛÊLII©¨¨ òÿæççïÛ·O§Óñx¼qãÆåææ�V¬X1jÔ¨±cǾüòË111†UTT( …BQQQ1zôè®®® &äççóx¼Õ«WÃüÅ3fÌ=z4lV6xÚ´iá㯈@D";vìJ¥%%%ìœwÚÛÛ¿ùæ˜Ã¡®®N£Ñ9rÄ›D^­sø˜ tttPKôôz½žÃá¨Tª¦¦&³Ù wÎÛÚÚ…B!Ôuòãé–@(fddôööÒ †aYYYt—¼!Û¡OþzzzÚV!bȽ«à"ˆ­4iT*9s&½dâĉÔkú!ºZUm=·}TT£AF•JºðñˆSWW·lÙ²WÏÆOM6mÚ4oÞ¼èèè!wÜÃ×8Ÿa³N§ŠïÁ9¨[__ßZ,–öÁýÁb±¸g$IÒÙoo)Z*ô™L&‚¸:‚ââb.— �ÈÌÌüå—_Š‹‹ÛÛÛ�û÷ïOIIÁq¼¼¼–ÌŸ?³›§T*…ë�€˜˜˜ììl˜¦gïÞ½°ÖÂ… W¯^ �øá‡ :::233=.ƒÅÆÆîÚµ ÖZ´hÑ‚ ��ÇŽ+((Ðh4YYYGŽ�¼þúë›7o†§?~<8Ç+¯Æ©¾¾i{ß NŸ>:@øÃÁƒÛ`ãÆÐ‹Š÷˜4iå¤à»Aèü �Àq|Ê”)ŒZr¹œÚFòØŽãÏ<ó £V\\Ü… èµ$É'Ÿ|²sçN`Šj¿ŒÓùóç-^’_ Bª` uáw÷Âàl@píøY+h³äÕ8ÅÅÅá8þÜsÏ¡ÛâÞÁXðÕét‡x݃Âh4†3$Æ ¦ì ÿí²‡è¯ØÚÚŠº"h¸\®©¸"«qb³Ùá#ƒöˆÌÖazßáÇG‰ïBGrDÄCfœpœeÅ…çþì½Þw uÊ}Ãd2étæÎÿE}~×¸Þ ¾ùñ‹…]ˆÈ£©£ÇYƒŒ†ã[|£—¸Ñ{uÐý…Õrõù]DÔ­îB½€@D"8΢ä˜Ù��ÂaïëjCý‚@ ˆá°�°?oÜZ´nÛ]VE "8¾Úµíÿ»FÆo0Ú%=����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/index.html��������������������������������������������������������������������0000644�0001750�0001750�00000027236�11555611701�015423� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Introduction to the ds9 Interface - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Introduction to the ds9 Interface</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> This thread provides an overview of the key components of the ds9 graphical user interface (GUI). </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li> <strong><a href="index.html#gui">The ds9 Interface</a></strong><ol type="1"> <li><a href="index.html#gui.menu">Menu bar</a></li> <li><a href="index.html#gui.info">Information panel</a></li> <li><a href="index.html#gui.pan">Panner</a></li> <li><a href="index.html#gui.mag">Magnifier</a></li> <li><a href="index.html#gui.buttons">Buttons</a></li> <li><a href="index.html#gui.frame">Display frame</a></li> <li><a href="index.html#gui.color">Colorbar</a></li> </ol> </li> <li><strong><a href="index.html#preferences">Setting and Saving View Preferences</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#components">Figure 1: The ds9 GUI</a></li> <li><a href="#vertical">Figure 2: The ds9 GUI, vertical layout</a></li> <li><a href="#menu">Figure 3: Menu bar</a></li> <li><a href="#menutear">Figure 4: Tearing off a Menu</a></li> <li><a href="#info">Figure 5: Information panel</a></li> <li><a href="#panner">Figure 6: Panner</a></li> <li><a href="#mag">Figure 7: Magnifier</a></li> <li><a href="#button">Figure 8: Buttons</a></li> <li><a href="#frame">Figure 9: Tiled frame display</a></li> <li><a href="#color">Figure 10: Colorbar</a></li> <li><a href="#prefs">Figure 11: Preferences dialog box</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="gui">The ds9 Interface</a></h2> <p> This thread uses Chandra data from an observation of the Trapezium Cluster (ObsID 1522). The default ds9 GUI is shown in <a href="#components">Figure 1</a>. The main components are numbered: </p> <ol type="1"> <li>Menu bar</li> <li>Information panel</li> <li>Panner</li> <li>Magnifier</li> <li>Buttons</li> <li>Display frame</li> <li>Colorbar</li> </ol> <div class="figure"> <div class="caption"><h3><a name="components">Figure 1: The ds9 GUI</a></h3></div> <div><img alt="[The default ds9 display includes the information panel, panner, magnifier, and colorbar.]" src="components.png"></div> </div> <p> The default setup is a "horizontal layout", with the information panel, panner, magnifier, and buttons displayed horizontally across the window. This may be changed to "vertical layout" in the View menu (<a href="#vertical">Figure 2</a>). </p> <div class="figure"> <div class="caption"><h3><a name="vertical">Figure 2: The ds9 GUI, vertical layout</a></h3></div> <div><img alt="[In the vertical layout, the information panel, panner, magnifier, and buttons are displayed vertically at the left of the data frame.]" src="vertical.png"></div> </div> <p> Note that the colorbar remained horizontal at the bottom of the display frame. This may be changed with the "vertical colorbar" option in the "View" menu. </p> <div class="subsectionlist"> <div class="subsection"> <h3><a name="gui.menu">1. Menu bar</a></h3> <p> The menu bar provides access to all of ds9's capabilities. For a complete description of each menu, refer to the <a href="../../ref/gui.html">Menu bar section of the Reference Manual</a>. </p> <div class="figure"> <div class="caption"><h3><a name="menu">Figure 3: Menu bar</a></h3></div> <div><img alt="[The menu bar of the ds9 GUI.]" src="menu.png"></div> </div> <p> All ds9 menus can be "torn off" to be a separate window from the main GUI. To tear off a menu, select the dashed line, which is the first item of each menu (shown in <a href="#menutear">Figure 4</a>). The menu will become its own window. </p> <div class="figure"> <div class="caption"><h3><a name="menutear">Figure 4: Tearing off a Menu</a></h3></div> <div><img alt='[The dashed line at the top of the "View" menu is highlighted.]' src="menutear.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.info">2. Information panel</a></h3> <p> The information panel displays information about the data file and the values at the cursor position. In <a href="#info">Figure 5</a>, the object name has been loaded from the header of the data file. The image value and position (in WCS, physical, and image coordinates) are updated in real time as the cursor is moved. </p> <p> The fields of the information panel can be customized from the "View" menu. Any of the default entries can be removed, and additional fields can be added (e.g. detector coordinates, min/max data values). </p> <div class="figure"> <div class="caption"><h3><a name="info">Figure 5: Information panel</a></h3></div> <div><img alt="[The information panel of the ds9 GUI.]" src="info.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.pan">3. Panner</a></h3> <p> The panner allows the user to view areas of the frame which are outside of the current field of view. Although the display frame is filled by the data, the panner indicates that more of the image is available. Clicking and dragging the viewing bounding box in the panner - shown in blue in <a href="#panner">Figure 6</a> - will display a different portion of the image. </p> <p> The panner also contains axes to indicate the directions of North and East and the directions of the physical (x,y) data axes. </p> <div class="figure"> <div class="caption"><h3><a name="panner">Figure 6: Panner</a></h3></div> <div><img alt="[The panner of the ds9 GUI.]" src="panner.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.mag">4. Magnifier</a></h3> <p> The magnifier displays a magnified view of the current cursor location. The magnifier cursor - the small square in the center of <a href="#mag">Figure 7</a> - outlines the size and orientation of one pixel, taking into account the current frame zoom and orientation. </p> <div class="figure"> <div class="caption"><h3><a name="mag">Figure 7: Magnifier</a></h3></div> <div><img alt="[The magnifier of the ds9 GUI.]" src="mag.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.buttons">5. Buttons</a></h3> <p> The button bar duplicates many of the options available from the menu bar. The buttons provide quick access to change the most frequently-used ds9 actions (e.g. changing the scale and color bar, blinking and tiling frames). </p> <p> When a category is chosen from the top row, the options within that category are displayed in the bottom row of buttons. In <a href="#button">Figure 8</a>, the color category is chosen and the bottom row shows the ten most-used colormap options (additional colormaps are available from the "Color" menu). </p> <div class="figure"> <div class="caption"><h3><a name="button">Figure 8: Buttons</a></h3></div> <div><img alt="[The buttons of the ds9 GUI.]" src="button.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.frame">6. Display frame</a></h3> <p> The display frame is the area of ds9 where the FITS image is shown. In <a href="#components">Figure 1</a>, a single frame is shown. </p> <p> Multiple frames can be opened in ds9 at the same time. In <a href="#frame">Figure 9</a>, nine frames have been opened and set to "tile" display from the "frame" button. The current frame is indicated by a blue outline around it (second row, center frame). How the frames are tiled is set in the "Frame → Frame Parameters → Tile" menu; the default is to tile the frames in a grid. </p> <div class="figure"> <div class="caption"><h3><a name="frame">Figure 9: Tiled frame display</a></h3></div> <div><img alt="[Nine frames in the ds9 GUI.]" src="frame.png"></div> </div> <p> If the display is set back to "single", then the current frame fills the display area. The other frames can be accessed via the "previous" and "next" options in the buttons bar (or from the "Frame" menu). </p> <p> The "blink" option may also be used with multiple frames. When blink is turned on, ds9 cycles through all the available frames. The blink interval is set in the "Frame → Frame Parameters → Blink Interval" menu. </p> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="gui.color">7. Colorbar</a></h3> <p> The colorbar displays the colormap, bias, and contrast settings. The colormap correlates the colors used in the image with the pixel values in the data. </p> <p> To change the colormap, use the "Color" menu or button. The contrast and bias can be adjusted by right-clicking and dragging on the ds9 display. The "Color → Colormap Parameters" dialog box can also be used to change contrast and bias. </p> <div class="figure"> <div class="caption"><h3><a name="color">Figure 10: Colorbar</a></h3></div> <div><img alt="[The colorbar of the ds9 GUI.]" src="color.png"></div> </div> </div> </div> <hr> </div> <div class="section"> <h2><a name="preferences">Setting and Saving View Preferences</a></h2> <p> All of the view options described in this thread can be set and saved as a preference. Open the "Preferences" dialog box from the "Edit" menu and select the "View" tab, shown in <a href="#prefs">Figure 11</a>. </p> <div class="figure"> <div class="caption"><h3><a name="prefs">Figure 11: Preferences dialog box</a></h3></div> <div><img alt="[The view tab is selected in the preferences dialog.]" src="prefs.png"></div> </div> <p> The "Default" menus are used to set the defaults of the "View" menu and buttons. For instance, uncheck the "Panner" item under "Menu" and the panner won't be displayed when ds9 is launched. (Note that some options require ds9 to be restarted before they take effect.) </p> <p> After setting the desired preferences, select "Save". User preferences are stored in <tt>.ds9.prf</tt>. At startup, ds9 looks for the preferences file in the following directory order: <tt>./</tt>, <tt>$HOME</tt>, <tt>/usr/local/lib</tt>, <tt>/opt/local/lib</tt>. </p> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">06 Jul 2009</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/frame.png���������������������������������������������������������������������0000644�0001750�0001750�00000143051�11332353405�015215� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��s��ß���… ÓÌ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ)pø®�� �IDATxÚì½w”Ç}&Z}çNÀÌ`2A`Ä0€"Å 8”)Á"MCñøÙO¶)ÃAk­}´k<b ™Þ·’Ö2%ì‚ÞóñʲÖÞ!mËI²×(kGƒ²4$Á�� 2aúýÑwúVWêªêêü}çNßîêªê¾ýõ÷«_ð|ß'„Üp˯�����àá/~ŠÒ hõö;ß‹���€$¸á–_}ø‹Ÿò®¿ùŽÛï|ï+ûcF���� ^|î©Ý>Ô þ˜=y3����Éf���Š…#‡Ì3°¤v÷ ,\”ï±f=5{’Þºç±oŸ?è ž9sæ™Ã]‹V].lôøÁ—{?ùÜÁÓ«¯yn��� 9fOŸ=vøÊ+®Ð?äÑÇ#„t÷ôæu¬˜Y‰çÑ[—^zÃÉ=?Øpû;;::vL|vס}½C˘#OÏžXÝ{ìŃdùš˜Ã���À’Y¹òÊ+¹òÊ+}ì±î}y+fV/JÝ=LJ.ýÛOýÃ›ßøúË/[óÌ—¿~¶o°ÙÕCïÓØÿ³³ýÇzW-êÄ­����8çyž¹Zó(d¬ŒYÌ}ÃË_zöÕ‡zxéÒ%—^pîžx`ùÚ·Ò:þÐîŸ\±bàÁ§œwÅÕ¸¼ëæëÇn|Í—|ü¾ßÅl���Ø2kÊáóÿr8VK³XzáÚ'òõÇw5ÁŽÙ}»~´ì’k !Göí¾h˜|÷§»V]÷ ±ýX¹dð×ßñúKW-ëlvÌ9ñü+þzÇw>>^ò±¿²d¨Ÿ²ùÏþõ¥}3á×^¶êß¼vÕ9‹:—÷þú÷§¿üàã¾O!ÿߦw ôþÅg¾ùíï*ÐÝ@<BÈñÃïypÉ9Â}V¯XtÇ/¼îÒó—Îùþ#O½tÿç§B†÷;·^zþ²%CýgÏÎ=ýâ«ÿŇžyi?~Š��T‰Z ÇUšâ‘9ö#¿ÿNÙîôçÿ¦sld7áF…f•-”ž³vôù‡vôYBÈÜÜ¡ƒ½½ÃËg_xl÷¾•WÝì5:bGºéΛ—÷¿¼ïà /ïì¿úÒóü3gç„‘ÕËZ%„\½zp÷žWš=„›ßpù·¾ž²k÷ž'g¯¸dÕïxÃÊÅýãŸ{8ÔÍ÷¾xâØ¡ýCÅ¡Ö�>!¾èe¥¿·û~óÖ¾]_øÖ÷=âßrãõˆzÿø;‰™Æ®ÎæÅç.yüÙ—;::n¼æ’'ŸÛóØO_}ùE—_¸â?Ýùö÷mù»³^ó²ÕËŸÝsàä©ÓøU�Prbµ´Ê‹î“?~`Í5oŒ=ö#¿ÿλÿÇŽàó=¿w›ìX™f¿ t4»—_õóû~¸³³ƒ4Þþ]ßo,]vúì‰ÞÕ7t-èíúâÁ¾¥Ãý³§NÿƦú^£ÙÙ=Ð×}ìØ±ÞEç6›Ý„7_} !ä©g_¼ä‚s×½éµÿôå.^Ù¿ û]?!äþùÒ}ÿò¥fWÏ_{ùß÷kë^¿ös_x߉vWý¹¹¿ùÐBÈøÎÆn¼ª§«óß¾ù“g^ÚÿÛ·½qñ`߃>û?ÿí;ss>!ä?¾ë¦KÎ_¶°·ûÔ™³»^Ø÷·_xøÅ½3„KW-ûí±7.îÿÉS/>zâ­×¯ùÊCÓ÷îABȲá…wÜrýå,ïlv<ùü¾¿ýüC/ìa8²zÙo½qÉPëpÚ>ð«·Üð¦×\¸°·çÄìé÷ÍüÙ?}}ͪå} ºžß³ï¿âïô¾öÊKW­\zñ’ž]ûÏxD|+¬YµìÆk.yý•«_ÜwèÿìŸ;úú?øÉÏ~ë_ëìêY}þ9ŸøÐï/ì[°°9{ðLãö›®¹ä¼%=öÜÔžþÙs/â�� „ÌêÒ¢ûËÿîø?ý—!”þûÇŸøÓ?jø9l9VƬÒaô,ê»à†ÙÝŸ=ëwôô6Ník¬8où*¡=>{òÔéž®Îßõ[Oî9ôäî½ÓϾÜÛ3ÜÑÑAˆ×Ùì¸áÊÕ„jâCðË— _rîâWNø—­^ÑÕÙô}ÿÓ_øfÿðÒþ¡¥O¼|bϾ™s–]uñÊÏ?¼‹§¡Ûß²öé÷^{ù…wÜ|ÝÑã³O<÷òð£W_üÀ÷ùéîCÄó– ÷óáŸì;0sÍe^{å¥ïûåÑMÛ?30°pãoí_Ðý“égŽ>rÓ WBŽzuæÕ—Î9wõÝ¿yË¢Þo~ïÑý¾óçßô‡w®ûÃÿ÷3³gÛç^ÐÝùÿ×[ût?òij'½éº¶SÙU—¬¼õMW<÷Ò¾Ï|þ›}½Ý×\qɱ{f—B-<oåò%+/\ØG¹äüå<ûXßÂazP‹úF¯¾hôš‹—/ZøêÌщ¯?üù¯~çЫ‡º\òÌ‹¯ö/ZÞ?¸x`Ñ !äÌÙ³/½¼¯£é}Ÿ}àµ.ºéuWÝxÍ%{þöOž™úñÓ¯Îů�€jÖ†ÕQžðØË®•‘±úØÿüŸýð{‘ÂÐ*Ý ™¹ãæ|2ëw]´´¿«««ó¬î°OŸõÿâÓßúõ[¯»á5#7¼†B^Ùhû?|cÏ«‡‰ç]3r^_O×Ìá£?~|×î-×]ö¶7\=þÙ‡ööBNΞ:v|vùÒ fGgÇ̱“ç,%ƒ}'áOô±¿úôwô³ÿµeÓy+–|þë~ò?·é=ïºåÆkÏ_6ðÀ#Ïö.ù“¿úâó»éï_øÕ‡vß=¯\¶ˆœÜõu—õ/è~õà¡»þôãÍ®žþ¾¾k¯¼8Â׬9oÑ@ï³/¼²ý¯þ©kAÿªsϹîÊ‹¯Z5øðSÍÎà¤W_z^ß‚îý3‡7~øttvdÓo¾öò‹‚¯º;; !GŽ{qïWfŽêóß=qüTã¹'w¿|éª÷ý·ÿD d傞îÓ³ÇÉÂápJý®_wÚ³§¿ó£é­ßxð‡L{Žž¾… —®œ››kvt -è{ß»ÞFùëþ¡ÃÇ–­|åÀÑO?óÜßî;;ü¶×¿fÝ®¹ýç®þæŸø_;Æ�€RQkƒ4<‹£<¯!>VÖZ¸]~ìþËÏ}øß½#B«×ß(8¯Y©‡÷<uæÀÓ§,è:~êÔ©ÙÙYrêÕ#¯ž»péù:ƒýÑS{¾ö_>qÎ`÷•—®ú?~á-+—/¾õ† ÿrâ¡fׂ7]u!!ä»?xÌkt|ÿ‰ßrÝe?÷º«?ù™¯91Kééîêë[àu4Äó†öB96wö,áL»v¿4¸äœ“g|BȓϾ°`áЙF'!¤³³yjöDGÓû_|ݵ#¿Ô· ;<¤«ÃëëiB^سx‹ÎYýÊ¡¶9wÑ`/!ä‚ó–ÿËÇ?n\±dèÈ÷ŸX²"0Þ.ì%„<ÿÒ^Òh,^yÁžÇ_;¿çOv½ðýÇž¹öò Ö®¹€²÷Àá-÷}îåƒ'þtü‹W¬è]¹lxÏÞýoºîÊ7_·væðnnŽøó—`x ×ó¼öìýÙ“O¿¸ïÐвó»{û|ßkt4:::‰ç­\ºø®_½iÉ`ÿ_úKÿ¸ók -k4›Äkô.>Ý{òèÙΗ;´÷àeõöu’¯ì^´b5~ª��”J³º\g•µFYt¥ÇþÉ{n ?ú/?òÿ|òóÂóJ4«„ÒO9xd×ÇÏ6/ºîí'ï?ðÓ/7ÈYBÈÌô7»¾³»w¡z¨Í޵óröà±£ßzô¥ÅKö«ïxs_ÏÁ½/®¾ôò«/=—rëM¯»õ¦×û÷õö¼v͹?{æ¥S§Ïtu6éíoþòŸot7^sÉÊ‹B¾÷“鎿ÏÙ³g›ÝÝÁ¤œ9{¶³»§1ï]åûso~Í…7^sñK{|äãŸ:vüĽw¿·ÑhxžwàÐQBȹ+–võô¯±jÅ’°Áƒ‡OBv¿ôÊŸÝÿ¿ÃfŽœ=sÚ÷çMBÈác' !K 5;»=ÒX¾¸×{úÌÜÇþák§½²rÉàÿùŽŸ{óuW¾n䜉ï>ÝÑÑý½'_9óèsý½]¿wçí„<ú”×ÑI¼ö%øóÏL­XpzÝë×¾ç]ïø÷¿ÖñÓ§^|à±Ý?š~iöÌBÈšó—þ‡_yKwWsË_þã—¿õ½þ¡¥}ƒKš=Ý׬9÷k/¸êâsææüòäo»ïÁ<ÒÕÓ{öì™fg'~®��”‡Y­¬Á ±5XÖZÄ,:ö¿þÎ-¡Z –fÿä=·þ—ÿùEþ¼fxîÌécO—xÞÊknîìîí\Ú{vÍ'žþvwwWggçÑ]t_õvõø»:›ÿáWn<vòõ/ìñ}réyK!?~|—?wö†‘ó›ã'Nþð±VäÌç.?wÅ’Ÿóµû»¯üÓW¾ÿë·¾~Ã/ßrãë_9K—œ·„ò¥o}ïñ]»¯¼Pìîã5(? ÈKDÐɳgÏvuvÝôöVŸ4½ûȱ“K Þû‡¿uâ ¹üÂåá!?˜~þÀ¡£«V.ÿÅ·¾ñÅýG‡ú®^³ê“ŸùÚÑg_!~«ÁGžyù؉ÙsW,y߯ýâ)¯ûµkÎ _{ñÊwÞøšÇŸ~áÄÉS糜rèðÑÃ_¹çÿÞ0säø±³×_¾ªoA÷·þéÏví^¼òÂFôŠ>½ïØÏ>ýÍ¿øç¯¼ñª‹nyËõï½ýÍÓÏîùèß~½»«ó?ýÚÛšý3‡o½öo}cG³ù¯ßøéÓ{fÞ÷+oY{ÑŠ§žßû‰üâ—¾þÝ£ÇOt-èXrî‚þB|‹Û�� 'fx}è·o–íù¿úRô(qLª†fž70௾lù¯¿s ^³ N|â…-YصwàµóÑ™‹Î_³ïøU Owvvú¾ÿüs?¼ðZÅ:=÷Ùï<zÉ9«ÎYÞÝÕ¹æðW¿óØøZÏÀâ7½æBBÈÄWøä?~>HºxÕšÕÝ´áuW_Öü›Ï~å{O=ÿü c7]wÉê•Ý/íýÜ×ü—/|kAÿ`g÷"ñ¤¥7Ó{|çÇOœ7|ÕýÇ ·ö[?>9{º§»“rböÔ¶OMþæú.^uÎ÷yòËßþÑ-£¯=;7G9yêÌŸŽñ—FG®¿êÒ·ôô<rìñ]Ï?õÔS^ç@G³3˜®³g¶ýýäoÜzÃÍ£×=ºëùoÿhúÆk/ Î8säDÃ#oÕ½=]GŽŸüü7¿÷¿¿4ÕÕ?¼÷àá.;¿oAÏþ™#ŸšøÚ}ŸùBOï@g÷‚FG“¾} w÷œ:}êøCOîûÖO?³¨·¹fõòWžûÙ#W7;„ÅC‹‡‚ÿõ‹S§Nûî#ÏýùýÿúÄS»:»zzú–.9¿Ñèð^gW[¾��”‚Z53æ>úà×®|ÃÛh©ËhM鉔dž´œåýåýÖÛÅçeê³>óÂ^æ‹ã¯<µºçÐwY¹öçè“ùssg^xèºËV={öÐáÃÓ‡úú–] ùÜÜÙWž›>{úô™3³þœßèèXÐ?Ô¿hiWgÏ+»§O<Þ7¸xá¢e¾ïBfO›yåyxË/ºÂ#äè¡Wg>=;ë¿ÙìZ00Ü7°¨£ÙÕÕÝóÜcÏÍZºráâsžÿÙ÷ !KÏ_Ó70ôÂ?>szvhÙy‹Wìñéc‡ô,Z´bÕÙ3§÷ïyöÔÉãFGïÀð±™ý¾?·ä¼‹/^öÒ Ïœ8|àÌ™Óûãß»ú² ?þwŸûöO­XÕììšÙû‰cGNŸ<>77×ÑÑlv÷ .Y¹ oa` &„øþÜþ=Ï8rðÌ™ÓÝ=½žç<~48ã™S'_ÝóìÙÓ§ü¹¹F££»·`ÉÊ®îû^Ü5{â¨v®£ÙÑÓ7´pxiGgWW÷ñôùþìÉã§OÏúgΜ>=Û7°¸³«ë¹Ç¿Çì5¼bÕÂáå3¯ìîìîéìé#ž×ÙÙÕìì’¾‚���‡^}ùÊ+#e`ùîWd;¯}ãÏ·XöÑÇ—¬HãØp7áÆàØðÛƒ{_h×geˆúÔ‘ý«{=±ûÀò+n"ˆÎõ::æ–®=~jæ²K.<räˆÿÌî§ê–§kh4šCËΛ›;ãÏó:‚G}³³»ÙÕ3°äœF££ÑÑlvvwv÷Bºº{Ž®ž^BüžÞŽfçlï€ç5€$ººz:ºº !ƒËÎëêYày âyCËÎëéF1¸ìÜfG§×ÑAY¸hÅ‚áfg7!^Oï¡%ç¤ØÓ7ϯßz½G®{öù—/Y½âêË.8züÄW¿óƒfg/!ž×è\znׂC¾G^‡çy>ñ;‚ÆÛ6„Ž¡¥çvõö7;:½FÃ÷ý…gÏt4; !] ú‡—žÛh4½ùÎw4;›]]ƒ‹Ï™›;ÛÑÑ éìêjv-P¼Ru÷öw“þ¹3gΜžíhvzÍ¡åçõôð$¼pÑ ¯áutvA¤�PfÉʪÀ«Þôv£„^HÎe6ª3ED¾8úêîéã{V]ßììæÛíéxdÿñ^}ääÉ“§OŸ:rúxÏÂëä]&½ ż;°h9³¥³»ghéÊðÏ®žÞ.®:OK¥-;7ü¼hE;¸vpqûÝ¡ÙÙEÒ?¼„oç¥W¿õš ^Åê³§~ä©OüÝ¿Í9¶ä¼s¼FÃó¼ŽfgÿÐõ%éìîìî~µ !¤OTÌ/ó^H‹$ÁÄÌx��JJ­6õÓäÝ,Že¶Öàçö¨íEÜ»{úØá™¹³gF³{ÁÀ¢eÝ zú‡(��9N<~âè!Æ0«Æ£>¾ °«§7¯cÃ-û÷<Û¶{5f‘Åçôô 6šÍÀ¿«ÑÑìYÐßhÀ™�� åN}ôqýCôGåu,ƒøL•Ç‚…C án��( ¹ööw÷ö—ëX³šõøáƒ¸¢����`ŠÞaN³rüðÁû?ønÌ����˜âݼ?$W¬&���@"lß¾þ³Éï133ƒi����Œ3[ Y���À%À¬�����f����0+����€Y�����³����˜����À¬�����°hš0<<,Ü~ðàÁૃ%æÏÅ4ž‘>u’nðÇÒ}p8´äcÏ;wîd¶¬_¿>Ü|NcŠ0L¯Lûãüg¢£¦tj‡7mÚ=dN¡xnç3á¥w5X»3˜ÛÂBxqSý™4íËòòèœ+íþäu;üg2èÎ;wîܹ~ýzWœªx‘*ÚOtxx¸ d2D¾]J29¹á…óéöÒ‡7sf«žœZͪÉð©J=™² ï~ëû5h!<V¡‰é¡i¾»5?XúŒôvæs—&Ô¬üçR#v\:³‘¶jT϶“kÁÜfÖ§ÞíLKÇþÐR•_²ùL‰êèG–ptŠë¨b:)0®æôZÜoToMþ*:'Ù{YÚ¿º4†fúª+ìI@'4µÐ;dÜÿ@È‘õ8¹Og\êÙHò4žÑh¶³ù™˜ž:[B=9Â3ª{˜dÆOõCCvé>ÍÕ£³»Ir¼ñÊH«ê©°»ßš ïŒ Þwdï²ßd.æ/Þ4ääµZ8ÏÅyǤùR¨J‡‹¶>Ä?a3~½+¸ÙÐT™þ̪ðךüÒ;ŸüX²—«™WIÙ ÔJ°:sϬ:'sE{_{¡•5¥¡YŒÝâq^ÿùuÖúüJÃûD½î;ÕES Én²üÊh#ÍKïêgh1oê7€ Þ þʨ°¸B³È?ѾÝah²U“Š]š¢ýøéþÄŠ-kTÕçoÈ)”ÕAèNáðÒÝÒ!ÉYÜBáX„ ªxpõ~P%ÆuˆFO¢”ÞUÓSšÏzhÌJ^)^Ó»4U¥Õô&6Éµà—–‹|YùîSµ—e>Õ“,3¹Õ9Çô7hwõ›)Ýš<ë8aз·OõËra‡æª'L¯2ëì:k¯PÂ!dv]ø©Vt@}öYØ”¢ñŒocõäÈùþÐtî±lz¥ó3ç'P={ÅyˆÇz¡˜ ;¥ä]ó·ßùÞç÷:~øàý|7!dffï/��À8Q¢ Äìåx[ŽB~0³¨w`xß »v?ú²�Ïc«ÎñÎ �(À¬��ä€Úz¨Bî×ML��9’+€9¬ÞÜB³���€K€Y����Ì ����`V�����³�����f����0+����T‚xÖ Q�����4ëöíÛ1)����à†YA«����¬5xÆ ˜����ÐÇÐÐл?x¿X³����àX³_0 ì€ �À¬…ÃüÁ`€òbff“��`V<›�ÀÆÇÇñ^�vÀ:+����@³�Ÿ–Å$äzÍW¡˜×Å€Y‡‡‡…Û<|…¢öF 'žÛpc7*æ\xEb/“ðŒú‡u¬Ä¹€YWÂU(æu  k >ÈjM« cÑ,+ÜÈ_£“ªQŸ1öp žð€ !Ëá£8„¼ßq‚É·=òmv{x®Ö>ïgÏ.ì ³3H»ÙoG>´þäXöðo‹;o:WôИaÎÌÌ(r+5ìèþSÀsG6o4Eé3–…j¤/Dø™ÿ Ó ú(úB3Ÿeç� ‡WŸ-6Gù›côF‰7J!þµ}¬ý9h!üìæmiïž(ØÇÛÂvÕŸ"þfB>:Lîžß41ßìhëÏ ÍðX¾‘`ºóþfâÎ÷jsd¼aoù›¥O¡3·nÖY 'C!€ŽŠ f,°±3…{ÆR¸ìBȾÕáïðúððsØ8�ªÊÇ-î™hd‹ðæÿdÈŒaÇ¥è#ÌM2Ì~¦;éOÍï¿™ewñ›Á–/ehîg^‚ê]Í =êV°òÊUa fŒð±WAÍŽÂoÝ.¦â½ � … µojŒ±– ¥Õ^È:íSQÆkÓ¤ŒÅ# :ÑÁü!!sÓ–E '™µZeÚ‰í¼1³ê¬ðzMiµPºt�õ”¡úMÅš‹e{Òæ\a—h>ÿ ì·4e¶lņCfT¯bgÆjͰæ|ºŒºÁ£9–½ì¸6Uæ­�`†«XÕèO25ŸÞM¼AB¶Dåìün2+li“oÛ¼,1ØZ¿a„ É„ÚÔ?‘™f5zRC¹ÊH`Ìzjª,žýuÄ ��ù¡XÀO÷o{"˨ yƒ‚žx£”sÓfVPÒkœ‘“Ž ˜H ¶êáóÛ‹²²:üê†YiO $“¦¿Qݲé…pâÚö7��ä õÓ_Á»:¶VÞ™6”¡µ–æÎˆ-w³\ÿÍ;û‡"šaùÅÑЊ+4ù†M1=áÙZ6¦o*ñÖ`þ)I /Ån@ì|Ê|š47*vž%v£º)YÏq�@©y—ñéÕo÷ïmû OotþÿÍ}9jª%dÛvãAq?™FXIéÚÐz{ 3j~„Çê�yƒgÀB��TOàŠ¥í”4ô³¥ðûðD[¤ò,.\7år±¦œ¢ørT5FÆUJ}vµÓ˜µ²4Æ r‹�P ¨He¢mfØŽ6±2ŽH¡Ï‘"vEm©¦e#l=*mJÈ—*ê3,ë�ùËŠbòØ�*@¨š&PÚî~ne\š TæñF ™ dŒøcâÌDä‘Ä´Ø„;%¦ÕXž‚Dcd­fM¨J�@‰ ÄBÇ›¶>‡ä:Q¥í0V*ëakyU¯'B¤ÖÆ ïBFç£zôoÀ¬©%)��ÈLhæBÀ‘`ЩHt #>EÆ­ýGÅý—…¨Šžl•e¬(—}«.0kºPC�€âCX{(#­ª Ê–<c¢w¦¢N¹T¢%ÿ!÷°$ë ÔÂÝ-Wa1‹&}«ÈÓCŸääï.`VV�BX{(’Ðj¬tSwtÞ)7º6éOòÓÖy‰(¦…ï^‹P2Œì¯°Ç ÷áQ §%Oãu­yƒYñl�ÆÇÇñ^XFµ*‹q%…Y·£yr ¼–ZßkŸcm?&"_+m7(Ñ©ŠeNÓ·‚;!O“1¶?FÊQ7���ÕQ«nSð 7 ³¶HtŒJ½4ªÛ>³I?1¡TF[e˜ŠdaÜ¢ò7Öé ˜���0f\>ý/™Ï ÌĹªé­þpL@·‚ݬW¦qíËZv©Y…é„Ù ìRÔ!},«ƒÑŸêk¡³�€JÂI~ýF˜„…‚oÇâ™)ràDŒ¦Œ”™›Š.âN ÖSe%á4‡™Dýk1«°· ±e\ë ¦†9Õ•ÓyÛ^ ý�PWÚÑØR )™c#lšþÑ8—¥èŸ´1™¯L%€H`÷g¸Q_v ó&*”wRfe2ÕÉX!ÜÂŽRüÀí; ^w€ºÃ‹R©Oˆ9›ô(¾ [‹ŠÆbšz'Ù†EKÇó0I ‰¤Œ¹,·°Zv‡‡D{K»M£9t°ÎV Š0![w¥4I¢9u™Á†¥ß���rªu ÍIt)·€Šèü…BJ$˨<É)êÛÈä²EœLh7V/|ùο�� �IDATÄêó«fµ¦Ãº )ú}"3Å:+�°²µ6‚•&§äb7¶DL˜5""7ýáXÚ:Ü ¬»rzV»ì2%cùªS-Ò±­š“™ºo0ë²~ZÒ­Xg€ú¾KlqÙ‚ÐYIöão&žw°ži‹¨h¹Bމ¿«Ò1I«Ê^d´«\SgÖƒê|‹ÓoXò€<eku«)¸bkš&i‡#&‡¹ ;C[WµÝ±Q1µ«§Èî½$ö•%žYÅ×ÞÔCúñ95—V ]��ìx”Äyôè4eAƬKpÔå§Ýà„ · IÊÛoe¡®Š W™4LK kiVuEëІÉoç’5n¯*µÐOR\VQ‡�*®À·8Ûͺt ãgD·ÃT­ºõ*ôeÛßxŠÓ²¢Šëü›„"´†ˆœžZ%Ù§Ív�ݼÁÂçr¬O¯ú¨ºÉ5Í«ÿ4šU°)�pȺÈYçEå„Yï…Yy…„MGÎèçò%ty×èÎþñ5ò;ÒN¯øò/ÂôÅv@vC��êA6>ñýÈŸµ¥U»õWo‹®†côhè'¬ð­/ßN‰·„µÖÕ—µô0¿1v¢bݤSdV��r–å[ vp›D"LA³W¬´m™a7 ²81ëµ²´J¡WùJ«iÙJHL–cY­&#À�€âRŽWe©jÇ‹jÎ3ææ»ÛtãÊ%*FÑò¾WÂ5Ô6Æé)§–p%î ê³f€ññqL��eµš ´Lmð–½w0Zu|JkÙ2R5J·êÚæmõ9!à`Y-t~Œ²³X¯UƒYSÊG@Ñd«ça&г,§RP~œ(·Âzæêµ[~OÙ‚•f®’9ßšŽÛ—¦k˜5]lß¾“ À† 0 �Ý€M›bùlj>¥þ–ø6ãݬ¦ÚéCZe6êHÒ–˜´Éî³ÅxÈ`VÖ"bff“�dKDÄ#XmMDÒÃGÙ�ײ츙õoï0‘›¡?0#aÛy%¬1VгŽ9vQÌ òÈãããxí�€Té0¨VaãíÏc pÀµ„ˆm¿4A2Q§‘ÿå¶âÀ™¶<ëØ™Õ¹Ÿø?™e ž�€z0µ¶ê‘Z,µšæä3J;,Žoe½‚Å §XÝl‘¥ù&_l±Ý¨´”:ű:¾–oG?U$˜�€:¡~F`žÜPàÒÑ«âl‚cmfÏ;yàãvxíÛú0¥õÑþvLwZ„iݬ³Êòï ƒV‘&¢° ëàõ–®óånjS¥•ËH’X;³Ì´Û>vÞ#W˜çAšqJD½„-Eìæ‹R>"ÈA«ja牨Ü,=^}@³Ö…VQ¨�"TŠÀ%*#WÅQŒÃQ$§à”X€ -M~‘lJ¢|ÂD’Xó½ÞQo·dVE ¹a ü£œ>„ùŒZè���ÅçNžT˜EJ"_mg ¤PÛd<aÌX|Éq¹ò)i雄Z_SÍ'Ò¬2Ê �€B ¦À'{òJ%:Ö^@%’Äôú+‘¯} KÖðš.–®ÓçØ,Œv°dVä��¨¹œ=P‘ƒ‰V·´„¥YSá—Ä»õšl…íˆu°ù$Ä3«¬\¨]¦`��ò¤Šº*V'•ãŒd’90â’pNFô±ÂNYt Ó¸°ÍØI`üž˜iiV†Ó®©Ø…ä�ÀŒ]ý ùÕiƒÅ‡il«î•‘Å¡R>J  &#q‹»j¿$Eá…®Ò¼õ‹…³†,hJ‡2y å �€!3x ÿùï÷¢Ù"<ÿJ¥Gíx‚ÎÒÀŸHê ;*îž,,µMoSܹƤƒ CN…Z–­öº…mY¨•ù8Z£šçfšUȵAòIᚉéC¢*3f¨µÜ¥í|v{2.=ª3 ±ƒ•åüã£Y„Y˜Îø‡ÚJQ¦;ù´a¼©0®”æ?B"Åãx,KmHS,OíŒêe}²jV"2üÒF]ÞÆË|Å‚‡{ö䊙jªu™·7ÿÿGíe\éÞ-øÄ± -¤¨6AŽŠ ;rÔ`„AuÈXø'E¸ª> ÊrÒ«¹|¦FÍ™"��¨>¹¶‹Qcp5«þð“ë`†‡-ÓœD‹QEXª‚×Ûé…%;ó«Èâôý’1 йFõ«"}1˜�€:B(ªjB«©šøI¦¹Šç-ÖI’—HV@yÉ(Ì_¨ù® H:Á,óÅïÒÊ��P:Z•=úëI´/Š¥ åÊ—²ar¥WÖOJå,dP™”ú3«Ë:C >kêÇ$�@1©ÅèqYIé©¿v¨˜%…Œké<Âj>E F#Ê$©" Ï”:N^Ârèôý¼ü`ÖÔúÞ�;(ž¤©–/ÔÛƒ>SIô'O{! ö?DÈ=‚²áêÙföWSšp»¬ÊºæQŠ;Dÿ>³¦‹íÛ·cذaÌ ¸@i³ˆl£©b+é‹…Ý4 ¹‡IŸÙg¬]Эµÿ M7ô¯ š‰ÜËIX‡?0‰=Ì Áš'fffppÜÊS'õGk M–Peêž 5.!bùëöÉrPĘ”·D†£Ù73™³âÙT@Œ„Õp ~,$šÌ’©É+|åí2² ];8%¨.œ^ù…Ç —NÝY±JªfâÀ—Êh%ÕÛB¾_µ|ƒŠ�¥…ÐQ—êdÒ¸—‚Vjnu;ÂHô¼©òŽ:{ÐOޝvù;ÌÛ~é…Õ„�³¡U”þ´Ða¦ÙC‘gqM,ÃN‚‹xN’…ІuÈÕé‚uúÉ«Èè+pe=vaUöâ­ÁüsêàÁƒLZúOf¤ÓÓœaz¢bçÏÒ¬nPq”º)Ó£rOMœå©e·}òiTß )«¤<¡Éˆm a˜=øžH Õöv%s™Ð”ðÅ”x�Í„c$1m*ü{[Nè–§¡5·Êÿyªm%&Êec{ͪH<+|˜"K­æ£Y!°b'\ø*£¨/Ä¥nÊè¨|-±áÛ^Æ´ªsE¬'_x'¤}®œ™Ò°>[g%u‰P—‰#|Éç \!ÉÑù˜hϳ0»!Õ‰ãÙ‘é•ÑÑùå^>ë¢Å•pÀ¬šz«ªÕTè5<‡¢ÿ¦¢y^¦¾P–„W„©ÌË×q’iG‹þÐwšìµDÅXT™—hÓ¤a™ýPV 4žlª^D]½`)ôEŠÍÍ+ôÔåÓÉÔ'‰+i.¬Ç쩨«X‰7²”4>_P™å.~˜<­àcAu¹ ²4Þ,…w‚iMÀJV¤¥­ 3ž8<Ñ2OLYI5êBˆGü8ŠõæwðƒC*Ȳüná +3½²¬:Fùñ†_uìôŒc‚nû›[)Žõår#ÉÏ[a¶ª˜/IX…)‰?~cõ‡°o꣘®Ñl“ø³yéQ¬nêhYM¡©ø5ÅþĘlY¬Á„Ä[ƒ…ß2fdõ?âïͤEŠóÿ¼ªþÿ£õ«‚b½rÓªêõBF·f9bîŠÍüJ¢È¡¨õú5¿<ïFÒ;³ ×üàŠY4Ñ–„È38ª¤ˬhÒjîo%ýyª­ÁþfÉ·ï¨þGæÿùïo¶üGs§'çNŸR®…Ì϶íÊ{·hb¦Ädëñ¤ÎËÈïš(⛉Æaõô¨®¶&É×Y™_/ ˜®åI8€~ÖnMÂyN‰VñkR?¾#ûQgÚ‹æJŠˆßêˆQ{KÃf)W…©G'E½6ÆH«:iº:ʼn¦‰·ý§ìDvÃÉ£§òÏqZ¯ÐÞ%Åa\ž�tl¶²oíŽ*È5ʘh„šÐƒÉá%«öÓ\!pM‰S(J¤ÏVMB íÀéÈVžÌÒk<–̘uVÆS)Œfá¥$-^‰< ~XN˜+JÜÿ»Ù®òÑȜ)é ¸·k’k%%˜Ñ‘¦W£ÓÉæÐn’…GÙ«€W™‰HÉÑØ d¸,'¿,—Lú(׎º‰M—£YãE]¥øu[ÕfX·8*ÈÖĤ¸ò7 ÂRムD‘¬|BÊvuÕAÕ#àþÑ6…3Y™Ô2šFSó™»Qç¾ìäšÒ�“i×Ùžš—Òú(R›š÷|–“o}ÉŠEú‘6‰3Ð:d‘¸vÍe®¡¬4òržƒI¶,ymë.E‘:tÑ<ˆÂ8TJš ‚Oü«3üqÞM¼Áh|ó–HˆSç' Í ��£P>@¨Ïâ'f2íaJ#¢ù’f &~”IîOä†wAhì¨øB Õ§cl?[GÝ3Oü[¨8[$a<c`V��@½æŒR|;pñ©½²²EœQ!þ©Ž„NFŒÙ™ˆ,·¡+“0YDh©¦n—[Ì �@õ¡O“ú‘�ÑxáN±ù"èÝÂ3bqZYÊ ²FŒÏ"ÿaÅ/óUì½ú¬©c||“€ VW%”¶˜X5ï¶ëX+}DÁŸo‡Ïå¼ú¬0Í–š/i†¦ßPù<g”±|4.PE¦,Šœ&o.‘Æ–ѹ¸BO()qñ<´ÖXĵÊÛ¢%¬Á¬©cûöí˜6lØ€ „ T© ¸%TiÕš©vÉ9Þ0kdtm—{c”(ç~¬{„>ƲTá!ßf…**fffpp€*‰õ˜J5£¥¨Ö”±£`LµL¼,݈΄ðÕX‰í‚YñlÊãããa5\ ‚_ ÌH¥J¦ã|"XÎÇÌЙøhUJÔd•‘«´¬ºFæKõS¾Á��T öiƒ`:Ná´Øk"&O«fQªJRä½t®8¿¤š]F~��� ,j>¯ÃéõTa¡Öv@ê””žCVºÉ6š’"½§Ð©J‡æã­ÁÂ$¨É³Z´Pœ”§|OÒîS›ÓÉFÅUÕlªÈþ©ODoIJ¤R­Ò)hzÆã—¶Çòù#ÖÚ‰¿2ep„#RwOXé‰Ú]Yxrµ©ÏꤤFMª{º}XÓóŸp£æU¶nªÎWJ±(KøEü纀\rû¶…N¥ƒ>ßb½‚™|¼‚¬ýáKÔ˜ãi^xk4’?JdÅYù¯d; ‹„(*‡ä¾*mªú í·*&Êå…gáO¡(‹^ÖØë[½ dN^Aÿ•J¿fÃÍÂõζ~½‡ø‡æ»D—=—Ô†’Ÿ‘ϰb¹Ærsºùé²q¦’ËÕ[|îÏî,ÍŒ©Ö+ì{L}ô®úRâ„lÊúr²¥k«3ÔU˜^uOì5ÕµÂü §«aô³g~ùÌ#@H2Mø_rÍLL$1!eel¦šw5žÝ¿ú V!G*æ¿’dSÃwvÂÇ"ú’1ðÊV@y~e62NÈ4qò¶eY^‹ø÷'ÌÊü¶­)Aÿ¡Pü7tÆØXpš©áÂvf¯>Öv`p$Dj¹†ïê]¤Õ“«ZiúéÆy=*‹“ kùìÿüÿ¼Ä!»+fF¸ëL³š ™¢Õ|šèÜ"Ðj5‘°1ºšCæeK¸"µÎËžú›çóò_¥’ž„h•“S”©á÷çËÆ© á G‘)³ªŸ ±4Y–'ˆÐ*ž^ÏN‹ìp<¯›è[B¸¨°÷Å'¬§Ë£¶Dç [cœ!Ô–Ew*æ¥7ùÆæQ¢w£{Î`WŸµ™ÆS†_@¢Ÿ¼–å¿¥72;ÔóÁ­ž"‹ÛÒ¸”¸@@Yôh;TfР«þ!WŸËú+T«æÌ!ñYØ|¿q`bjÛ‡OÍ—ºÛœ(ü¦©ó,PoŒÝAö°HxŠ|Ÿ:³”êÝnLØT‘™¬gL>ÕU½@@1å¯~²!kRÄ+™O ¡RºcTfü{X*¥ÉRŸ ™Ð –&žh—ºšŽiw'u­÷Ö`د���ŠC“vò×UÕq¾m¯¥»‰·Eœ©Ÿá`†ò ‰¸6“0I^A7+L䤆cfEH;��@q “Ö Õ³ó´×fÓ{ÄY‚‰$ p,å3ë¬ú¹‚ ‰OiToǽo0h�� Päj-jÓcå–ñv”ãÅ)V) YSG+[Ën…+“f˨Ϛ:ÆÇÇ1 ¸@�PFÞÔƒ3!N–ÙÓQÕþj7%™¨¥÷×tq"’„þš3�fM%- �%‚‘sll*”…¤¥Y¢\“&™z;²Ž©yÚôÌš¶oߎIP`Æ ¸@¸@€CÚË8üÆŽÈeRX&LÖtSôS“›Mf…Ê333¸@¸@€sVKO¹jr¤þ’0·~ú$™ W'râÅ1¬Áx6ãããa5\ ‚_ À‚ÕÒ¶ Çö'½Cèñšž¤ÃlP±‘B Ü���UbYM"ÑTN´µÅþ²ýF”¬jXU¦*;˜�� jHBŠŠ” ;£s ÖdòyŽ¢ÌªætI ìS³o Fò9É`–d' ,%$«/$,yfÑTñ+evN`ì¬VìééT t˜eÉZ4«÷ØfçsòEâüÍ„Œµ¤¤Â©Xß+XŒ ƒÙ€f-‘ó9#…eìÔµídUZõ›ªRí¼4ˆÜncgÈÓ“ÝBÝ)­£RmªH‘(3&+¸V±³¾ ½aúø KNòÅɇ)ðÄÀÔª,~ms˜ÇVÚz(af«ZŠpn€Ù.³£„ä'ÌÈÈdV8E«4¦È]´ŽºÌ¶ûvb¦Y‡‡‡é×a£—h†kËþfö¼,¼UÞ÷˜2ŠWõFÙmƒ• t¢6¤Ÿ„R8–)ÙÔRR±òªÃDZg…pu£~"ðu[+ Œr|ê—­åŸéuxvg_©TŸ,é×2f}´ d,OSbÄ„g·Ë÷$Ìͤ“MÂI7ì5«[aTv Ås!u^) E«ú‡@TꊳÇFV_"òF¦ó>ýœþSZ 8 fel¼úÄPÆJ‰ Ú0ƒV@AT9–™3}Ð4>3«¶ô¡×’`¢FÅ®ùT‘ÓQxxî3Â\È5ù¼q þ–ƒ ˜1Дåö‰¦² fYºA!¡êÅ w¶ñ1ãaºdV~õˆÿÀõä³þ©¿1¥¦ÀšjoyÅ*¼åq�U§“HŸo´0‘ˆ˜íÞ릚>À±©©ØÜ£ÆÃŒ÷`.V}þ¼Ký›—‘SNj·1aS%ºR™Evjý›§p®êx—žruË©ŠBxþæø÷Y¥9·#ÒœÕÔ­Á°h��„nô«[3¯¢5F)ò&_ȲPÒœ›U—™"’¼ÎÃ<��=tˆD–¹7ƒô‡áWF4Š…ïÂ4'3#f%%÷��¨¶rµH[Ÿ-~¿ŒE7\^•Qolé7a~ÍþÈ&*vVQŸ5uŒcp� 2Llݲ~¡òÛÂåU}VK{¤:K­`ÖÔòѸ@�’ Lƒu*{;'³¤…h4fÉ¢Aqm�FÀ¬ébûöí˜6lØ€ „ 8'*kZòýr!¿’ å ³ÒÿkžEȦǨùªs­Æ£/:-ƒY¡‡Š‹™™\ \ KÒUó„ç}€^ÑL)vEó@¾«lgYÈP­z[Z¥^Û{NDvS8pi ÌŠgS>/«áü°óÍ4 d}f#¯G…Z6ÔÄšÍê�•Ï��*»Âg²¦Š64†õéXX±äewz•YÕÙÁ¬���uäT-ßA“ËV‡ÜlíOD¸sBa*3ƒ[LB¼5X–Å40§N~^a6¨RGÙÒ#’ D˜¢–?Êùl'—EJTˆ^=Õ±×H½¨'\-pZó\Üì¶)R¬²�!Š §Ù sÌöàð¼£(û¯(¶’0µ¤ú¨"LNî…o‹páøô7@J Ò¢žZŽaÊϵµéTü!âr£iz0…?fæýÖ· ·3ŸuÞµÓLí) 3¨BAÆÅ—zLÏù[N½b�Ò}nLSjAXK.â¸$ÞÆêdêÁÄ?õø§!½Ñî][VWË9­jvO=¨’*§´gÛî¾âÿ¤‹ò´jª �š•hd®·Ë<œ­Æ|˜‘‚?%ÎãÛÍ\ÿ6Ì*|æ¦jYewødDm�"*ÞžÒl;²úÛ�ˆå¤ØuG^Ñw©ÍƆìFbiZºs4bfÇý*phÚSYg>άµjÌD­°‡Nn Ü`�`$U“ëÅìÇ¢ø–&WB"­llÒ„`,C[Lšƒ¨Æì–D˜fðL„`•-Iè{ɉ€F%� &)™r¡y£—�uežPn*ª½¶·µYV K¢!°úï …ˆgÍì±^Z­›P‹lY& È—kSÉï¿9©êÆž XvŠÒšq££%¬N‚Ó™qÝ0p!¡ÝItžÌž<ÛÅîàêA,<Qzgwˆ$düfK1^Ùð…NLE‘ÝÍ_¨6€,!+tXŠ«0CÈÁ÷gÑæ !ÉçÃUo›?!õýoco ç÷‘ ŒÃdü€c6ªÿ,Ô¯4½›­€¯êš÷d^ÃDQÛ"3.;‘(+°dž#¬W�³D-ØÀ† PW�³U&WL��`ÖÚk!¸@��€Y—ÀZ.��`VÀ °‚ �@ Êç����¦f¤����€3fݾ};&���� ±Hʬ6lÀô����€>†††ÞýÁû¥ÌJ c\K h.lÇ*ÐÛ"÷?èI¹Bt‚år]}ü¾0„’öFSs¿Œ1>>ªçByo¶cèm‘ûO÷¤,v¡¡¡pÒÊrõñûÂJÝÃð ����—�³����˜����À¬����P$ÍnÖð ö"Å+BöŠî^Ž]-rmÑòÖeÛ¹s'!dýúõ±ZÝÒ¤äÕ|QŠ8¥éJob›u»Þé-@™œ ”àÔiÖPÙ ˤ*­hÓ¾9„çâ{ňװÿÙ•B:Ó=— ë´iOvMùI£»Dog>gð:5üÌÈænT\hÙÕÒìDF×´ ?|ýî ˜é= ?(Ån±‹ ^‹uMW$Ëǯ°ÎçÐ~5<·¬aùéNoés o_ýþg|í3˜%»kJÓ­°«Ь ¼ ™ pçÎ4§}ëp&Ã!ëÜ¢FSšËHÿšç‡oÚ½l~}ê”ú©¥î|ž!W$½ž˜öÁáÖƒ)Gî^Z££dï_‚§ŠÂB-F³4—Ñ´Î<€øÛ@öm~æÉ{•ÍÐtÎbÚl®ˆÑ£IýrYÀǾÎ5³ù¡fùP(#ŠÜs¡~­Ï¥)ï[õCSç… ö‚–ñŠçòįÃOÃè֪Ɠ¶Y›µÈO±À°£¾¥Jñü•-¥TŒ`jþžÚ!þ:wœnðÓ°¸µ*3ÛYƒCjÉå\ey¿¦{ά±UÃe7›Û ÕT‹·Ò]¡š^¾|ø¥þiv,ú¦pPEP«:·ŠÃ9odp2˜Sá¹è; öÉà^ž¥8v£IÖW®Ù0ï_ý0£ð„·h®¾~ÕwBq~øÂgÎ-žZÅ\ö>×éƒC ÓLÞWæ³pc^2Ÿï•ðg–}÷tf)—™TŸÔîÛÌ:R)Í©ê¹Üê9N£]·ÕC(HŸ‹ÐaÍóºúÝá)‘û-aÚUWýDvC��€¢ Ô6m�Ì ��P8”hyP ‰)���(¹¥žshV�����³���@Q!¶§‹…êL):VÞ¹ÿCCC˜=ô¹b¿¯R ¡D“ì]ó·ßùÞç÷:~øàµC6lØ€× ����0zá~÷ïïÞ÷®Ý>k0����¸DSȽiœiff†¤lIËà®:YÛ‘ñ£Œ†ÓêÝrfÅ.RÌÄ0«p¿„íÌÎÏìn;YaÃûÐÐPx {-jrËa˜»XH‘Ö`����p 0+����€Y����Ì ����u@}ó[$¼fjPЕ)+P“œE¸‘¯¾YÉa&¹7p5Kñ.æ*p-*öÛI~E‘¿F?c×õÀébצ޸šÅ¿šey¤”÷ZTéº8¼"5eÖðçNýªÂìÏ¿þ;ÿU(ô1ÓI~#ÝI¦Ÿ²J¿²Ÿ#qÒþ)æ8LþúVx˜Õ¾šåE.Gª¿ìâÅ]gMµp8§ŒEWö‹eöÝa˜÷)º“²ž÷}o™>Œ˜û/¥‚‘Åfª(à0+y5K:Š”ìaÕ¸YÄá³L¥±NäÞ‡ô~W±´§mŽ+΂Bª=©°çAO”Í@20eg0‡Ïºf’¤$×èÆ«ººi!¯«}ê܇™Í*W®f¿©jü`+@«Ù $³âÝWÍްJ>·®Þ00Ìì{âöyQaf£pOJ„•ý·SÆû ¾ÁήYâ¼^,2þAa˜©FÝàj–îPwúÌ’vÄZ¯Hq™5 íWM;Lši'¥gb`úç;)ܘÒD¥wŠ" 3K†Ë}˜Ù¬æ”újf6Š´CZ+óãÊ` §¢Öš•ž¸ØIT윟Yo”uUÑOõˆÒû±j˜é·8ÃÌ~y5³a–n¹,¯¦w9ªñ0tÕø���€K€Y����Ì ����`V�����³êo½ë�� �IDAT����`±oðøøxz§LµñÌN‘CCCu¸ÃJq-0ÌZ ³2 ),¼ëo¾ãö;ßûüÞCǼvèÀ† ðº����FJéݼ¿w`xß »v?úP³žB ����Rˬ۷oǤ����€!I™uãÆ˜þVâmÂ48šLß?{žWÓIØH¼möI²?n6ÀÙ<ï Þm¸ÙüwðþðOøÇCF«þV3zjýã^Y…èGßiMi2Üߟd›êÌyþÝ=ÆÜ{·a¦YÔ—Y“S‘ wÅÖ“Si¦ô7 ÈOŸJ…ÄnôÖA¼mÎÓ¤=f7%˜Õ /ÚžÅQ0,×J¡ÊŒ´Þ6{e)k�,D­Ã=”.˜µ.D›MB¤ÖñvÚù ´ô&áBMV†Y¤h$UçÒÙJÌ* ¿4Ô¤Âû Œ[C¢Í¸AÙ*ßT·ë\¬µcÖXKÏB+l9ìȵ‚7ÛF›-ú*“Y£eö®à 7@y™ÌZŒKžòÒ¦>AÒâ8øäZ1Ned¢p•ßG­2™h 3³^~Ëœâ0¾Ÿw¸Ü ÌZGÍš°}æ¦Ù40á©:/pÚŽEª]|õ[kvd©&E;§b-4«³L™›ñ–‚l­!ÓZ–¦Fž&õ ¹:–d Ö7Þm Lb¿ƒÖšYS¥ wãyWÖ­V !þ4+dJÝ~¥Ê”?DS’Ò{Êê¶V’ÔHk&!éÈÙÇpjÀ¬vjUó(Ån ® hµE®Ä÷»Á©Õ#Q†É„K°jÚó'͸P-| mÚön#þ‚$’µ`Ö¢q¼·‰»ºéPÏ› Å+Pâë«Áš:ÆØ¶‰xò17Cê¾ß§£‰JÝ„·Yêׄ78—̼\O»1˜ÕüÝ-¡Ä|b¶M«›î¿ òT“®t²ðkžÝ[G¥3Ü& OÏ;&<;^¨¶‚̘Ñeg¬g4˜Õ˜J¡7myl~ã]Ý«­å”§¦)“¬ƒÒ~OúɇƒÖÈÙwâJVDžJ&&Éìf­¨š”ÝÄN5¥ï·´ÕÛ‰ù/îõ§‰·‰øÓ0WV¿êä5Ô7ØÊÚiŸ'#[¨Öð؇ëÉ»®èSÈšÈì_Af- Y5]Pæ³¹òù"¼âo%Þ! ×ÒëW· ÷Õ.öŸZ¬üÎLð�hj_µù °§§w¹ˆ'Z¬Ioo1èXën–ªDº *sMáüR«¢'B'd� j§}í콕·WYâÕžEe wÞ7ÛŽdh‘nÀ¯tWáÙT¾[q£Á·Âº­ ž–…Ã*¾z91Ízë@®e"<ßOáÑt[ÖÇV^ïVY¢]„r¤(aH«·)IM‹TBYÓ¬³¥àN>Ó½QÄ*N¡° Œ#ËÈ*ì:\ØB>ÙDôc0šª@T7¦<·ê~›ž'”¿•rY"m#°ïw·CqFðH)Ƀo›®âdvPKÉØýBzfÜ‘²”ÅÑú#l '¦2´+U7¦Ü^›t¿MIãúÓ„ŒÍ‹Ô€>'æYüÞYßï²Fð|ßv$ À¦±$GˆÔcˆh$,”yEÉ2ø =~uT t[q¥a¨&Ž BÞ`0«½M²³kFŠm55Öþßófùöéœ@>wˆI\0ØTÁ£F…Z…üªCÃ2Jö7¯TUÃg¸8T—%\m­ŸiŸÁ¬™R#OHúhÄXvôêNB!ÏÒÛCåÚò]kEæöaþ¼P®E©š© e†bÍÊ6êXU† ùÏBÏaÖb¼xËÄ'j_ Ý;í6Ç,èûë­©NsgÅ¢oÍcrJϬ§Ù+<çµ–WLj7³Žx#íZ7U:A¼‘ÝÒ–aEQ 3©J W@Õô,kÜ4V‡.„ÎE—©ç¶Ýx¯Ê?YfÜJólôvQͦáÎn¥g}„,âY¼ŠkLj72/Cï&ók®AFˆVôê´4Á!5N]Ÿˆ …[dZšÞôS3-ðR¸¥P'¥¬Þ2±"7õyR¿'w¤»¿‚zÝJÏúÙ 2+µ"°OkiMfÚìÌFЊüŠ:ô·òÄlÀ²-;ðšrWw P[>Ã÷΂GóI²e™èd*œó»Å€S†´ÊP¸Ð¢K{Ë"s˜<ˆÐ¬¹§i ™â2E”ðÉ8#øèü'Ñ£B³3߈X¼®ùå@¡¶Ò0ŽK÷N‡)#Âcœ dz­Ó¦:žJÌ­°<Ëþ’:3ïÔ•ÝЬéÞl·ÙÐOÁé³Ô³º¾Å79ØMPç‰O„ÚJÛÜÕÒ¼š³eü Þ-‚®U¹þNJI+>믆qØHJ†Æa&P‡ˆ<›ÔrÈ—qK!þàÁT쟭El_ó¨–ÙïSúþ™ ä®noS«¸Mdÿi3"‡Ý8Ý{ccR>cô"Êb‘\‰aßXCq¸hÚÚ¸“]Bæ‰6òZ°^ú–�€À²”¹`ÖDdªí›ºµ¿ biî ÿ Ü—¹ µe¾¦Mæ0ô¶.ôBªfãšq/Œæ3ª‚λ ÅjY…´ 8’7#3 ;¨šÎ2®èÔþ$õr°3žéz‰"}„Ñ+%s¯¿ùŽÿÍ7~÷Þw~à¾mÛð»q}ÏùÝ#†úÕ÷»Cmêom3«eÊ\¨J5!m”B¡&ÙßmÔ ï²«î•8ph2¢>ýR“u“C$ÏÅ· öfK›•sL\ãG½çîûÝ{wüÒÆm×ß|G ÖYSªïæö,Bj kàúÔ’¡OÌrAX!.ˆa ¥¥ªÂ—*øñpFÿäÖ‹m1|cÁ»Nºª`ÐØ`o]K†2†zzY»‚º¬”:o©žRv¡® ùØßQ2F/³:Ï@$´µ&ɯDDeÌ[›W¥ÓóÁ6÷N‡$ÚúpW7ïxú ËälèáÌfù\°lÂò/ O·qÒ¦©Ð6«fP-=_½.Ô£­=×Íû=Qfd¸2¥Í[n‘X˜M"›q•ËV\&ßàÌvô”$ÝR¥#óY Öt“0AÄX4)ã½³ÂS‡l­6+€l4®þžšÁ< •¶Dä:éþ$š"äEž½uV†ñD–wo[û¬cqý°»�¡´-˜µ@¼hDá6æV*¡’7B<o6È †Ùÿ‚ćáYdTÍ{6¡�Žƒ[%±÷¯úu1WE;m?^"vq¤›X×–¤ †ȸ {²xØ2“ 1ìâ Y0‚áyÔ®–\ÚŠ¶ˆ€Sß²èN·Fr6MSÿomS¸‚Ëi—("2™qKêT’ªýÓŽàŠð(vãé–‘ÂÉ_;p³ª EÛÂΔZ¹–σ)mòK•‡ÚžJ„‰VžýHΦ‘vÑ›Vá­‘¥S~µ5â%Z‡æs9ÉyN?i°)÷0ÕË5é–W¢üÒ©:Ú5l'è@Ø už&ØK$yi-èP&§@YŽâʘ…ëe F¦¦±Hƒ#ŒOÓX$Ʀݥ±ÈŸŒ3ý§¢«¼`Ç£L—àŸYæÂõZ§k5>É(K—(K‡$[õ”VxÝ+Ø“)œ-í{¯¥‚#3›ªâD ©Ñ¨ ˜5ÛÛk“ÍW$YAvŸ‰ˆš•a߀néÀ›Vô¨ÖÈ6lM«âДm¬¤3»×i)×Ö"è:ª3뤑aÉOþYa|µ,ÊhWj#Iÿ×A­ù³{itmYÖY¨¥žŽT/—uX\¬¼;‘–K²ª*Zy–¾¬2‰a Ó.ñ¿LýsÓA c"ç*§`­m¦·Ú®°LV¬•ãè:knÌš¤w šo1â|Æ%Þ#É÷GøeŽK<Ç*ìb2nî»äùo]qŒ];mT G±âÛ¦ÌÉ}*Ž*©¸PÌj곃TG¥»Ù áÁ”ÁB`lJ#k6Ut>X œ’¼Bî “Æ÷Þi¦ñÀƒ‰ˆ}y¥Hœ«¨–ZÅwÅ:3ª“•(ONœ²üæ˜Å×v™ÕâFx“2íèXzÕÚq8~_ìñ<@ëÂÖ·Ëùõ³¡sÅK†¬¥{Ï(Ð:kªb‹w 5=‹)Q…^K„´Ê²2™%"Y–ƤçÒY6Ó%föÖR²×IRhoy)C6¦ véõùýC÷Ý6ÖK]«dµáè¯BNmE¾®g³DÑÒ=ï˜Bè ã_ôȈ†Ms%&Y%MØÛ`£¬¥ x-³ò²,­œªïO{õ®nu—˜jíÍêwÇæë—eƒÇrϤxŸPÏÅ&Tð%s¬5å´O±¾M{d'!¤5jº.ºÐöë­›¾ë[†4Ùv]^—( °£¥ät´ ÃyÉUoÍ ²—Y“‹] ŠÕVÑôŽcï%­4ù1ñ¦²*u­v¼Y¾o‚âêé¼TI¶¶ÙB”ŒžŽ~1N–¤Ám:•æbJ ï$dgk Þ6*c¾H OÄÒDâ‹ü>ñlì”2¨b–XXÁ[F$êÄ ªà×pcfI”ê’9˜R¢¢Ð§×÷Gø|IÌÊ+ÿA'³Rƒm2v*ñý7™ És?%ÎPWi•%NÒï!íQìO¯ ¢œpÿØ4L…%Ñâ–,,=¸êdM\±ŠâÁ¤Ÿõ>m$´£2ä׊“ Óo"„<KH;qDXä¼…±¶ØUôMXcN(¸Mrª­q=d—-M‚U˜T:ÇÊH‹ký™õ*Ú(UjÆm·³~~‡´ìÀt›LRb&░Ѳ?‡ /G>³«—å` ÍÙÕˆg-\oƒxÄßJ|ÿ&¢Œ[­@=óRÈëˆOÍ=Õñ<úQ¡|Í8Z8*^Ô…ÊY%º1r":˜GHü¦šµD¢Ó(øÇ‚ÏÒóø-¹–5o°['uÎe_ùÓ„¬!„{§½M„Üûu"÷œâ×_…—’t¸VÌ­Ã[ê%ÃØLÂ̽D#õRछxg¤Ka)~çÈçI±Ìå]‹iãÈ!’‚6 a*›O,µæËšúbÑ(øG§Y¦{éÉÖâºM•wÕ O˜6¢ckõýšÌ Ön¦š”Œ3¡ÉÜɵ¸K_ÙLFvâU‘ÏÈZ.k¦ƒPì*fZ¡22:6œ·\‚µÎš5Ë M]Jûì¹Ù2iV5 8Q±¦#M9¿¤«!ä‰iBæ3Elm/¬ ³@x#ÆÐï¹0Ô5’@qkülWëYÖZìœ4(;C¸�•Ⱥé$K–<«‰‹Ÿïä¶%ãN1Õµv¸Š ÔY æ‘wƒ¯ ÀûCž ±JN½ƒC÷]¡ïq¹…«¬Y þ¤vb_|5ŸÑ°åÊ4ŸÂ¯¨Jä©öúfa:ÎñÒd)#4ƒ[LYN ˜°'Šþð:X¶ÔJ$•Ìc݉õ="»aÁ5hI{èd\êF2›ºü5kÆé|eì•DòªŽ ä‰Y2AÈ]#ÞH$…!}¸º–jlßÔ—bë³ò‡TR°Ê–™eHu:†ÏüÉH#!ýð¡«|(-ïlÌ0¯ƒ½uí0SÆ,éNAçÃ…ØV¼ÍN-6Õ/¢ç佉0 ƒjf¼b'õY(†¯®~“›~-ø:köq#֭щøCFÿ›6Â%X£HÖ´«»WIF°<J§­ŸTéE™6]¼dxMê(ªß°ÿ&ݧݷ.ÝSÆ›- ce§¢v¥‘:ˆþ¬kÝTuõNá‹1üN³Ä&óþ•RõÖ´f;—KS¬ò#Js±¾7“"…fJÞÒËŸ]`%Þ“ ¿Í£{£´ºW¼'ÓYÿ51wUZó¨›*Ñd–På`ÖlˆM“ÁkA‹©tK¼^äó.ÉèÓ¡KQÑò4¥ñ°cÒáZ<ñe½±+²Š OS¯ZY#âˆÕI ‰nT½´6ú·‡üÀ¬Ùðe8F´T—L„`Vv0Óé†)³"®vÞÖ²ÓRîŠuº¡±SŠMûagMiÔ9×Ì®À¤n°ë¼¿±%L‰$Ç#ss 9͸òkÖ©4]¥ôÿ(n8繂jÇœz•‘“ÃhKESa°J¾•^Z «Aèê³âþ©ù'Z[øèoS{ž/*V±KSÕÚ8F¾6ê¡c‘PÒ‘ª‰íL$uÃúvꆀü,î²5ÏùèšeT €õ…qD¾ß×>ä#­,о%gAEÍ» DÙ³Û•³Œç}ÄöáÞꆰ֩"[¡Ù7mæ+JîˆBiVÓœ·Qcó™÷ÛåÞ„ùbýŒLß3Ä;LÓ¿´_.‚Nu+#Œžï³ðkæ$qk“ Ÿ¦ØÞ ›åûI ±Q•[?ë«¿±d7[ŽJHGzÊ8RHÿ%²Í–Ñ÷ªÐ™"4+~«Èú@ûnªñ‰Y>…a˜%?(o®ð]¢U,pßttQ ;¡£zËåeFG°(êÃðéì…A2š6ØPä1MÉÒå+ò'Èbuh!ëO J‘QôÓȯš/¹ÊÓE·(vÝW¨„’/C†ÿÔgdøÒßA|mxý!¬t4 Ÿ«A¨hù-i$õ5­Äîö’eʵihÖäOê´c^·¯Pœ¼]W¶¤ªŸó!½¼Çi_ '2ÂÉalr%Þ誰aä qö ‰S•ºª«lŸˆZõû²©–Z@RLx³© šÊ˜Ró!.ÜÓ÷×2 J}EÅooá·à’vg¯G竌s<{¥<˜rçéù9펰ætÔ$»•åWÆh,#ÔØàœ˜@Ø­–s’êt•Ô]S³Zœl»,ù‘ØxR+àG3Ù&]o«H­sæ+¾_q.7›‚k´Ì>¾¿Ö÷#$ò¨BêóºßgO`vžÌ¹ßl¥dV·å_Üv†OìJRß¿‰¦I·Š¹Œù~]=ìO’:„F?óƒLÅêDò}”ú•‰Fmî÷‚µ „êjÍ;kIr£è¼å6 K>c4+OÌô”â\ëêµ wJ+]ÄN5kJê–!TÆÆËlaŒÃ±¤˜’8÷÷‡Öà‚ÞB\6D&ñ1Ì<,t>¢sD÷ie‡˜Ì‡Òô߇Jp³ù6OÿØ²é¯ j„J)åJHž~Iˆm5bÖ¤Lšè4žãi´©éýD{µþœwòFZlx…ulÚ-OPQ7cº=aÜšJG¨i<£cW@íøXÓMWÖŸ°JkXa†®~Ór&Z' zÓõíú¬í}æƒg{oXÒµE¥{ ÙIÈO[G1¾WÖ ü¾¶©þ,Ö :þx,1ë·0´JÅzù³<BÆZG*r&Øây-ÁÊ'Ú•öÁ5“)‚vê,U¥HI³Ö§$™0ÿƒ0Í!?-Š$ixåRÑÖ¡ŒP%œÌHÅVZÕ±Hë4ÒæHÅ$L’ø~á—]“Mˆ«™´ž%'q¶ô`ٲ펨ÒöŸRG$¶…p©UæÓëëÉh%^£ QJögêÆ©iEÝX‡¾8|”§±§–Ìà¶Œo„±vÙ™P¹Òvà@àò]²Ž¡©š¯x“KE[—oÍ¢¸Z)¦D®Â„²¸ávYÝzg¶ÖM0¢Ÿ è<ÒøNâyÇZQ:ëÛ;ðjÕèuA_Mª'\bd¤Vs—¶Šø(S®oÙoý÷’1Ze>Bîym=˜¯ÄÔ2ÖÞŽ¨‰tÏ‹—°üW¼ðÕ SÑ¡@ϻД,‹’á¡àš5m1äpgëMÆ5‰.qC42ï§ZE•Ï›(ÓÍI®‘ES)¹kº]Àsr¸Eà,S±Ô§iod…•¶IC€æ¢z33XÄÉ„‹£moÞ¹®çÚ÷QÜ*W£v÷5”ΣT[£ã£€v¨dzv—xGÖjjÖÒ{09L£h5›Ý‘²qA‚Ã85IÌÝz…$m–Ó>pº;R`g%™+²~…Á!“1ï ¬ËÒ^{"/øô:éªõkœfêÝ6­îh VB">GmršU%l€”Òd¤Î/ÜùôÆîl°ƒíë±bà…"`kfMd Î ßB¼ ÁÊ8é̤yï,™˜7ꎵþ¤Ò&¿ ÁcK”‡‡Y…yë®0OS,1‡~Uy]hƒ+e˜ØÖԉɚ˜¬LD´ ÌçQR¯°2¾Nªµäõ„¬'ä#­žÖ`>L6ÉôêûpeCÏEpw M»-Vko$d'ïz!y·Ï{„Pv×ЮKÛré/“h)Ò«yC±i†#Yb©p˜B2½]Øy2ónSëœÓH¡Wš5ûåY<¡Ô÷7‰—Kõô«“Q˜™Çó+cf ÓvXµðˆÑQœú¢S(UÉI4>G•öIÄ¿wÞêKY€“³c‘enŽLBãêübêZÆ:J;µãdüÕK$VVÞ ¬¦„ˆ€Þ!=?Ö‹©ÙX}‹Ó#Íjì9¤¼w—0(z¥¾ßÝú·U‹ð4éи:¬ö‚q–É?ì’<|cµ—[gZ…Å8BÀ{U½ÞljY¸ÐÆŠëê%ÀêfîqëÝ!þ“iÞÍ‚½x{r,˪݌ÝRQA\y6iÀnrk°QЧúq¬ùŒVØ<MíºŒMUÓ«bÇ@ÿÝ;KîexN6aŸùÎ3νšS¤žÅíÆž¶{°ÅƒUh*”9îÆ~ËT9­”ÎxüÒ †FZÚ ‰µ$Ï czC=Újg#!W²“øÛ¹õ5Ë d̵ŠB:×=ÃoûÁ:U{ó ÇÚHÇæ¿c…cЂw[ë‰VvãmªâÎP½7lS:í^Œ>v˜í¡Þ5”*êxkz;vNNÛƒ)‰lމã:Ï;1´Ê¶–Îi¤æP¿sn3Ñ”É ;9V?£s QÃ;"1ß  ‹Â–Èù(/%(xÚ_æ?Фí¥RÊ;I¨)Y6ua¦ÑqVe³j³%cšÃýìÖ7¸,É•2è°ŒMÚ«] ¤ õãœû«=cÕéì-šô¤7²”)cëHÕÉv±Õâ3b¡øÞÒ­ÔÖ¶ÄÆÙZcËà0.ÁL Ô¨Egè\e”g±ÔÅbóaÖ|ùÏš]d8š–*Tf»u)›T­¦—ó¤ÿš;VÛÅ-+ê$6RHO‹„ûºÌ*òHjmôû„>Ãaõ7B…¨J ²—i2ÑáÔ¬L57!%0tfÃçãI„&Âý±Ë±Ù¬ǼÁ(÷Ù0kÉ °lMzH+˜5ZÍ&¨.§ ó\’F%ïL.;{Q;©:DQ>]!suÄ®Z‡) …‡>M„r.ñë|N76ì ÓHmTÑâ¥"¿ ãâËdzZ“‡"Í¡[N))JTM³ŠJcË  W(iZÕñò ›*lÓHÖÜß~, tú5aô¢q"¾¸“1ÊÕ([½`Ë^©¢U)oάêFñ_K—ƒ‰ÄeDR´HʘKW“1Ïâš<§ïl¬#‘e'ÕIVUìýEgVµ5/–ç4¡³/ir°&M*Lµ:a<Ös¥o .ˆf®Pj8߬æ*l„¤çë¡¶ÖG'#”ù*ªY ›pÒÍœT† ³¿Ùx%":•¥bä¯">U ‚wˆu³©”L‰ä¯òLRvH˜”±Üšµ(N1¹h¯­m•)ô Ö¤+õzgö¹‹Ï¬ÉŸõ Iªïž#UÓ‚ʬ‚ꪓ‚råŠì†$³ú0®ËÉåÈÍÆš5®žÌ|~àµ<a­l7¢áÜ«Oúa¬š“†¾t»Z Íš³fƵZÆÞi N› YÄUTËþ\kp,)Zrù–+²²À"ʂċTº}™×RûóÞ¬åfÙxÞl<ó‰Ãiô2+1æ_ý¼öš ÄóXÛŠÓëÖY 6Úé[¦5«®µíOò›’Fݸ7aû|B‰vßgt¢´3%ܹ˜ÜìÀ@â³4 ôfâ3²â•«lk6ò–5U|¥¨™»ÑÉ(Ò]ýÍ’YsôÎàÔ÷`ÃõQëwa±—±1È‘\Î2BÓt-–ˆ<‡…íÐù•IƒýÄ÷ß 8Ë^KÂËÏ .vÓJ¥)wíQÄ­ò‡¤÷ W«Xks´ši-sÌUFù˨Y‹ÃC—;eþLîå„’efdÍLÅ¥`VaLª}Qš¤Ø˜WÖ/‰'ÚI±SÑÖ`G³Z\FmÅë‰(;„ù,„Eâ#nËKÝÊ26—åf«¦58KöeBWé0ÊEȲbæžÖ"HW~ %#á+:µKcKÓÈ´¬Ì•7’AÉ¿„whRŸÚ!¦š÷±&ÌÊèÎØ˜ßÿ#5KÅJFW&Ü4¼‡tlÔúk¨‘¢@)¬W„Y“{dù¸OÞOžÆtØÔ"¦E¦€I®~[ù>ìbùOÑ0"CMÂ@yÃ2˯°†©Iªè�Åy„ÐølQw&ѬÖä—Ï´+%µÌù«ìÞL.+Ÿ3°.B˜vá)4}nÛN´¡[ã³F°C3¦ü°¼9³? õÔ•++–êòÅÕQaJÖÐÛÙýw¶¿Š%lþ¼ÞºÈÁFƘìlW]pÆ´0�=UD*~ßÖ~ÐEih†`Ê•Gî¥4‹~‡5y„R2†æ‹ÆÐ[±]R—a7êR¡ÜµuùmlçZ‚Ú‘±ZÀ‚aÕ6¾ œ7"í CÃa³ÌÎ|›‚ruÓâ1:)PR~r¡Z3’4dÓöþë#-xëæÿm‹ïƒº«ùVµóÉk/UY·Û"D+ã¡ÈS³ ªËωéÿ63¢[£ƒ�� �IDAT25çʺ¤hGøÒ æïÛr¾gê¬vR˜g€Ÿü­„Œ±ù˜„É‹ZYg„…tËÐd(jCŠ ø[ÝT¶¢¼TiŠÑõ‚hÒå 5¤go]Kª¶ ©Æ±‘¦HÍžPeóê’ù4æ©ÆÞðºÓßÑ*¤Jï,fåbfh8ܮϱDn¤5ˆJA{Š· ᛊ0»“phŵ!gàÁ”±*Ê Bhõ: óª1agô}zM¬@<«>ÉñëGg ³øò™ú-²U85-«WIyšeð´,¡z IœÆ/y@‹æ!I:f”Rª¼7[!|ƒƒ„õjb°®šžRz?EÑò„))¬sJèÏ@A¬¾¹gŠÐác!5¶=˜&Y¿$&éRÚ…5×Ü^ã¸\Š4÷NFÕ‡8$'»­úfjÍöuÒ_“˜³cV'®Â [N©�*SFX놘’êð¢â,:£È Û~‰˜U ;9?áп—ý¼1QERöM•;ëCÌ©ÞlŠdô ÊÑ÷N/‘«Ö\¥KLrHqøµñ¬y%”7¥áù"¬#L¦ý³¨“Bè§Œ3ît±ÔjŽÌšÜ²¤Iʆ“r«fZ¶„û%z3¥I‡Ü“=;Ÿ.ͼÅdÖ"z0É¢bÒ ðˆãî&Ýî<ošñ'bˆM¤Œû.ÿ­láW¥q³µ+\¼–lÝ(Õ—Þ²V;±ù ÜÿÛìGjÍv‹–Îpôç¶wÚŽøêª$ÎéÆ»Í²^ìºwÚm¼›™ ËІ\„[¯ ü›rwýGöš5‡&ç|,¨Øª—ù(í¾éˆã:Ȉ¤UØ&]æE*š°K#¿ÅkÆšUßgG]bÝ•ðM®SÓÛ¹Ò9‰f-–58ábdö²¾Áz.Á.SçOô³†Ì*ô &¢(UfõT…8‰çmay(_æ.;³ª¢9õª¼YœËIn„„>ÃUbÇ3kAj™%ä`!ƒ*\„ÔUqøvÄ©žÀâ[}³_ú²ÈÑ_:6J2Fç•äë|³é+Z ‰Yjörè‚”cÍ€‚2«­ÆÒ†…4L`ÚæÈñ6‰ŽÍÊÂ\¥‡]râÉŒÃR%<EXQehµ̪“–ÈT2ºå•lì½NZV”7€fuÌ"éUìƒNÄK„­·&*uN{)®�_!£n*¦Õ 2?uKTC \¨ÜÕ+ÉÊI*f-Gvà RñÉBHcXpºÕ½ö–ù ±ÎA8,ïTLg+4":»!Ÿ ¹æà…š…_+ÝH)ÜbµrTIÂskî÷›ô©å©$—"e®"£a’| IQ'i¢¦£2Ê‘Ù?ªÄɛРYu(¤ ÅÏ· Ô!ã9,üìd®&~ª¹fM[elûÍ qÞà 7[‚¤V¬ÔN(»íLf%wòÕ¬Õ©|nÇÇ\Iúy*ÜfÆÃ®øôœ)qr¡½°g@¢ŠÓ&•×Mýµi÷ªhÏRZƒ­ÉC] Ž˜KnºÓ쉄à$10Âr$¶|,Š`/uÕ‡°°ø¬Áö“©¬w¦°ÖÊ Ï%,°ª(A“¿zÞ#§N\eÏ+ô P2feÈÃZ¥Y gJ³ùÓ‘-²ê1ºå²R©|dýÔ$Ѻ¥^ª­ü5ÍÄ”}²âÚò«¦­äªS`UFQê¤E ó ŠüØÆÑª+ñ!SŠz4÷®êçõ•4aäL‘3B(l&U²gò ³AÕ–2‹y³Ù{ÓË)˜åyëž©¸ÖàôŒ™ÎùF˜‰W¡§eF]×NK«ËfŒ¦y„«¡V3¬¦UV¸"‹ (di5f¤z3£%·¢ÐºµhS µ¸•mSü+v ̼L=™V )ÅŽaîþØÖZFŒÙÑ5…"E›û3MSQ¸hZÀ¾buˆPs7ZÒ ž±fk$8¬>³Æ§‘(ŸbšøÓ„LPK§ó+¯Þ!cííÂB4êöK”­°Ô¨ØGŸx W%šÿ·ÃRŸ™’¢"ÌÔ‚ ¬×jÚ¢‹™Å°Ö̪ö¡Õçc•ʉ$dð·¶þ s5ðŽKú]‚�ÍîVÑ(0çD·™6bD~¦C‰M°:#lÿ¿és˜C.”÷Çæ¼t90k¡)–XY€š’^×ô§U”9ШZ*(¶˜¤[À³C†„ÏûC†¢’ðS¬õ8–qcccÔþ\Xg-Ë*vÐ!3>¡ºÜMȦêSÀö[d¨ƒXrc±~uHëFJà—ëÜ:Ú²»ú–¢6yÄÝB©Ejɘ5K²±N‚Ø~=*3DÇ6ãlÒ¤DŸ ê’y é°].ußt:¤õ¤MWFÎŽtßãPYÚ5„¢ê3z•¨´dÌj#)qU5;§\/š S†’™Ãa.¸òËòŒ Bp°CùȨF;·&Þì¬NA\aN-³&áàTC<épB"8Dç£Xg­@ZຠÙ*6á]¦¹•y‰%Wº bY&©š 4Ìj‘°ÞÂ}ɈÈŽ “ZÇüЫ°±™(€ Ù\¨R¸PjÕ‚™\•²QçV;îVÞÌ[5fÕt,2U´É ž_eR# s;/P%ù˜ ‚>«ÍǺV–PÂùšnUkž—›Ys¡êØ£„ù+t™Tƒ]5›Â,è3–z 3$KKâ¬ùUlÍs0k™ïHGÅYÅãi uS`mµ/a Z\5ˆEÐZÑ¤Ž’c¨T‘ËþÖ:;„¿Ã $jUË›WœY]ñMB‹+³,J‹T>àUg,Âzs@U)Ù¨4 ôk]î™Û"3V¡j6¥ 3Ùâ+/+õK¢²~Â~ §B³ãæ+ß(²5éx«³Fh3P‚ACå …fµ©2EÑõI.VÅ:§ºâW)³fM™jbS;L)lÅüYbƒ\r'½Ñy¾X†+¯YöŒ°lœ:¤ÿä)Y]ØÎ:…“ñ‚Y‹¢#­[ÐL¬¦a}Räxøö!^‹û(ÔfŽ)U•Ô²±<ǨCE¡&°‡–ª2ƒ³é­—C³–ä1§Çg:¥R5[ÐÍÅ?C½ê0Vˆ× S;Väé5¥^‡ÅãüI\ä’iYEDkLó«u~Y Ë€Y«CÀ:ºVwÿ‘hˆÎ´®Ò…Z-¬0Õ$6f7až^aNlûNŠÇµN½¹¬B6yZ|M&Ö<ïß_kJÆ`֪ܔ ‹c5ÕÁÞH$?¢"Þjµ\tk·›uBÿäÚ¶åòrªÞÒѾ ÞåM¾žG<ï;é f-=‰ Ôá´AkÖ)øéT K2HìÒ_èÛÚÞFš¼%[=µK‡DGÓ*T¯æò0˜µœw¡^á0ñ¯Nkü*©¦G1Xp¨8:“«Åþ²õZßì›aX³®ªbyÌZY–uØ [÷fk[k.b=0òjúúµÃ¥âlc¢±cT©F§Xg¤„§`>ú«¶¥wDÊšBv‡…0MN½Çu“ªv x…R2ŒØIR¶æÅãêȬv¢P'¨†Y1 \“˜ MêE\Ö: SkžKB ×jkY'ªQ?“blE0kuŸh&iè?õivMbbGZ;ð‚\›ýðuª¶–e¸M?³ÏAá!Å›CÌZkÙ*ÌÞ`”M)vzŸTk³�Dj=5«Nˆª¬êœ:ŸƒÌ%¸Îò´ÖÌjZ:&=žã“1A¶‚É2 BˆÔúhV¥¨NdhªMA®5eVSÞrÅs‚l…# ÑzÜrÛ"4iÊ” BÀ¡œ•q^låuÙW}± f\*W¶ºÜ´AØ+P%–ÍÆ­7ü¶_€¶Ü*8ðTªY–< fÍHéÆRr XQÕ¼^8§$¦õž%äoH^ ´÷ª«ÖØåúÀ¬YëÔXbpjÝkmzÛ X0 k¥UùÓ‰Á¬‰h/¶"zØHfÛ/…C°¼0M›ö°ÎJ£Ér†¢&=@OÔ]ût©×âfp³e: ˜hV�����³����˜�����g`×Y½°Þai9E]ôÚÍ µÔƒ{ Hùf«õ“ÍŸ$Þ:Ü9<Ù YmÈÒ”V Âl��È­ú“î ˆE­™UXv&6¢F“tÁ¦úO€jÿó7{þæÈŸÌgŠÝÎ¥s–ÊϤÉ? ¯d)cPè`0kÜ='*;æHJÒ�´oŒ-ÄÛBüÍ„Áÿ„o´µ›ð¨p·ÈSo3û9�h‚dhRGw‚AÁ¬)2®P˜"÷/ÿDcqŒø› ‹Rà˜hOn ¿CØHð!`U%NÙÆp©5¤Éà+ÚPŒåX0kQHWŸzù¯€:pª¿¹M~Éy£ÄÛÒ’§ÁÆàÏàƒ?áÂPãÊ•&c!e²çÚÒf\ âO¤uâ4ƒÊögHךÈ0kêêVA½0×守r!c§eH7øð.C®²Æ*–7)õ¯¦2T“2™fA´`ÖLnî­nöÊ®Yú20 ‡DZniÆm™©Â}€:0hø§µ§’'9 Ì ŽL*aÁ©õÔ¬<ÿ…ÿÈ„Xà6a›*+tjî®u‚dþt¥MÓл`ÖZÐ$³ÑyÌŒïw y—­…º­xe´ív¥ÒpV‡_eâ•qeª'X¥¨/½u1A®v åZSfU¬zUÞd9’’ОçÍ ÛAØk=Åkè[Dh?£Q6GÖ¿X+Ü¡Uè׊ѪÃ,èPÆ…´6 rêȬ † j©ÊèÍí gšÈVšSešÒ”ÕþM<­B¼VáEmÁv2©�•y ù58x·¦ÌJ$çÎ"J•ޱQ“oõø2vKHuB§ß02‡ùV³YÒÕñ4*&ji d‚VJOa0OxFõ‚YkD±Âê¥PúOzéTaOV°8h¸”÷Ï–ø-¡™×Ÿb]™˜(U¹*̹Œ Yh–u ¨6¹ÒTÊgŠQ#Í|niX-¸Á¬%¼ÉÌÓ5¿ex‘þ3–cíÌ<mÃ\\ !Û^[e²C(5¥f³ø*4ü*27k«AŸ2á(#T…̥妵‡Tmy´^̪™®× ú¼kÊ‚þt ‚VKÄ:B–ñã¥ó ‰“v!nŸwÊ 'Bº• VâR>ÙÖÅP—‘·°C¾jÁ¬šÊRß+ØŽö"Ì=-óÍœ‡˜¾B_±)˜bS:‡ñ‡r­¦­–K§ÚÉYfKl;ú\+Ìú~­2³êG¶ÈH×!ç…á=Nހܫ©•Ž^ed¢ÂŠ+‹m•-Ê*ò)`SMÂãå,³Å!ÿ)œ‡úæ`’ù¥Äú'‚­Œ`eŸr3íå$äNÙ¢¬â Àî½(2ËêD¶èÄ¡†q«ù› JkÁ¬ÖfÛ„–%ÿAÅ–—bišŒ$2T†ÄhúËVjA¨¹ÓDuibE¡l†…ÕåtZVû›R>˜µ¨7_âµOÍ}øCÒ&¼°}¨Ø 0±zÁ•I&¬Ã|LÒ%Ùž:^Wpe*‹fMBWjoá$V\}Ku}ȵ‚Ö`³µ‚CƤgíClDÂoªù|”˜yur*©w0­:g-s\¨TŸe9vÄœœ -V‹Á¬¥W±LŒC3޾ôÙcûàmЉá­–…cw¼|ùÔ ávõYx¿'Ó.µsVÀö[¢çØ:ûõͳ±Œ›œ ëéÓT»L:ì¨æ6WF`>ã„Ò2}Þ™$ãmí<!gM‘„eý‡Gc4¥úÛvöÿ-*gzÎE¤%Ô,¶jW“Õ ú~_m¯fu˜U˜m_¶g¢"6. »ªˆ¬MèÉ ¤Í²DÃ`KH{ÁßܦLšÛ„žJ<Ç»MÉú)¬¥ûp."U˜×÷û„N¹š¥Î6mÏ#Ï;f-½�Õ1¥Òõm\ ßM1çUwF˜Ö?üSÓ¼ hIÔ½¨%FG[ŽÁ÷à1Áþ:<g”ÈP¿5ˆ×bÝWÞ1ÍT…<òê¯z2™‡õ©a9ebÖXj‘Q ~òB^#«BåšF]†5Jâäÿæ§ÎÞ0Æn§M¾ARˆ°î ]]MØšž½šµt„q´¯9ÜKr›°©'°ŒkÕ¼(ÛSó\®ŠÈ‚Y M½t…sýv’TlÕq_ÒboŠÀ—ºKª22›š[Æ^tK<m‰Ta¯ Só¥U>MS356_„Ñê¬,g“)¿ªOZ7ÕºM)Z²PŸIÎèªý´Æ€û×5íìö §2Ñ2ŠÕSõ:¨ºzkHÛ G§6>é8Ó[n]„_~e”‘Ÿ· ó"X͸I´²)÷ƒYs¦L;óoÚPßà¬I¥k�Y’1# yöâS=0eæ4IÝÔ`KçúÙ]’6á\ø•בD™ª£ýIâû}|kv<êj€`Ö"Ý|rƒ­ºVyª‚Ï"O…š&-¨0¾j›S9%¤»¥ 'äZ»óÆ®GU¬ yZÐ[T£FŽG’·®å²+¬Š#£=·DX‡5ײ2«µËŒO'"ׄÙÒà¿pDàWWBÓùmkê=mBõ72IÄÏ[,gË"P-‰…-ƒbs'KžÛtÑT®  ×wÓ`Agc0k†w¡ ÚóBðYÂÏŠ%dÍTêêL8hp«V…†ß6áMPv‚ÝŸöV7.3;ËŽR¯óÚ‰AºyŒN’B».¿p}—$È¿¯?„J–Ð)qÔM¹ˆIê%á‚®`·iUoRr6nY O}i(üÊŸ"þ!cÄßÜråõ¶ob²©I*dPº3I²IȆ s¿²; Ã‘úT'2U'•.w#L+ÁØ+Na´nÙ‰¶‚ë¬öÑi“u@°qBÕÛˆzžNJ´¡,ëàÓ¨æFô–6ÃÕÍàCZá·jæV87%É€(EÀ êÈPlJŠ66soB*âƒjdù(»q¹ûíÞ<À¬éÜ‚ÓÚ{Š(‡6ÿ*rk¶œð ÀÑÕ ÒíÓ‘\ ×äêÍåÃbT`’ÕL·Ä윰ÃB1*ìãÌ/îB¿Úg,¯˜šaT[ý&ÉÚª~î~»fK*^Ë_ŸU›…n>tœ+ŸyØT=+ˆÐÎ,³Ë‚\ÃÙ@ža mjÍúÎ÷‡™Œü 3i•S=$M4¡><tM²¸²ÌˆÉ±f£Œ¾ÖõMe¡±2V’zò®F2T¶î[\óþ›oüî½;îüÀ}Û¶m+ñí«íˆT”û#ú\[õéS $øWÍ*“}Ùw/–€ Ïù›Ùuâ"\Òè½æ“jAH±v¼kš—ieO¶;?pßïÞ»ã—6n»þæ; ¡YÝøýn+ÑØSÝIW[‚Ò›ëNÍåÛ¾L\³º"'ÙW¼ V&JSGêèT£ñ†`ÍÞ–HŒ,œðtÌÅĪú  ýx‹³Ô93«[£¥&µ0>½šéù®Z3™‘ŸºÐÙØîep¢ó,ŠÉðA±šd$*ô]r’ï",ËS(¡_î÷¶Ôþ%!9–PßÖv#6/1PtfuKšñ¦:esx÷Mß`ã‡Ú´îûAût.4ž®2¢iÚ#ýóê—‡“½%„éušbÄ7ˆV“;³ÌYOŸKáÇäOÏ;ÖNÒ´ÎY Lz ]pî/‡“eʤé”­h:)‰ª[ZgDEØê¤Á1¾ ã\€—•Bÿ[ÓŠ:±#âËBTõ"3/#'ö¡¯_fÕÚYIÁÖÒ,ói„Ui(æm–ªZ8¥ú®È`Ö´¤m¬Û°æŠ&S±•g)çIóuÊðÉŒ}©ücÉÉ”Œö×ÏÈÛxõ—Q‰¡]ZMá±zZ±0ìDÜWä[§¢M" ÉÕ‰k±¢Yá„ìèvu9¶ ˜ÕXí™Ê,ç²L(aisNWFeÞeÝ�‰±lJËêÇÑéyÕù( Bz4v0Õ¬²®j/-ÈV}JPic¥¤"Ɣؘ²¬$j»ö¼cÞ:âûoHU­VÉ7ªˆÌšô×`å¿Í—·ô³@ %“ý¸ZòT7B“®N táÙ5Õ¤ðÔ U»¢Ô"\MÅ™µ"¤³’8?aáYÔ$¼þÕªÒäÓfu¦_õùÛ ĤxNŠR«Ó¬‘½›b¡SM¹Ó.Coë¨1i;üR¥kÛ[ÆŒ»$Ì_ÈœH&:i±kd¬x’0eSÞ‰V¥úË· ¨ðuj1·ÿò¶¾TWJË$S„EÀŒ5¡Z÷!˜QSBu»sº™"²×ʲ„ûD;ƒ&±Y¬ 'EAæ;÷LF)}¿Ï¢M‹­³I$¯Hc´ú[:©ÊdŠÈYê6ÓSÄJ[¡k’Cq™ ó‹ÓŤØ2k^ô YMs£ÛZ7„ÿP©%iÅs09!`EñóˆZF¸º%<Ó PeaÖ¬ÁŠ5BWËX3/³ƒ"™pdî¦u;©(Ež0¿„þÔñ.WXjO]†‹‚t"@>‚Ehk-z#Hí4¥Åê€Ô ÈÚ—X3MqIdn¹i2ríÖÅË?'\úç•Ý„fmíÒKåˆ|ÖY³\óÓa~Uìø3á`˜vV¦‡ ‰K­¹«^oKü]¤SŽNíÛ^kY^T'2Td•RaŒâæ©ÞcJD“2±˜âCx]ÌW²uÜ䉟4Ûq^t½úÌjG*ÖTdÄ(LŒPþjŠÑäÅV“  5UŽŒ¾'Q{£fMö«)–iZ «ÔµkÁ*“gKŽÑÄ£âϵ6HT P;nJé%G4%6ý Ã)Q æTÁã)f.yªýc-¢:E[“„ɪŨº“i¼s0åÓuæÔh#Â\.LH;ó¬î à'MêJ˜£1¹�­ª58y}7‹t ¤[w^@X½@[:ãm™U¶&ª ~e”](1³�ë0Âb,뤓Úãš …õÛk˜†©ÆFŠøS«¯fmš†cE$s"'Tg$@J»WÜ"2é¸aôÖn~Ÿ1.4–ÞH·¯/k‘¤Âít%)äî …ªÏjQ9<Afä lÑÏ„²Îª§3¹Ä…ñ N5[–kÏTdO}Waý>k.²Írठ©úóë Éi@¡eË®ú'UGõ(–uùîiÕîµ)³¨›¼¢SܞѺ‡ÖD]3ÿœTƒY+ÀncU‹Ê‘EdÖlä©þ¹ü§̪¿³õ͆E2är1kŠÖàЪð¯1µLšæ öÊǨsô+,Ò골ý¤bË üÿí?¨%I–Þ#‹†‚-X± îFÖxz èÁª(‹Œ*X9¯ÆÕ+X9c´-¦`à!´B,^3v ÆX ÄÚSבQ…MÑ”@‚.ë-ÈÈ™©14Fe줌Ìqâĉ™‘™ß¡)Þ»73òÏ»}ù8ñâ÷d«„‡"‰M=g™pÂä’·�Šì¸^鵨Fâ ¯êû!·dŠUbyè¾ËŸáìJ=rÖW %Üx“ÑT6˜UmYæ¦g·â|dÞ¥J΋ÍjÖ¿ÇI". Cùžq ú®tµ4kÐ0Ì5äZšmÓì2ûG|)S#*sÝÓX߃)ê›}abõwcºµËc;ù쬔w¯î†É¢Ù\„*¡frR7ªŸÝö¡[=¼À’Ó´£'£ŽIöê.7&zwYÓÛ:Y×åA0i¼Q\­ÞPodm-]¹îôglý”»O%“¥Ë;ЬQR)­GiÁΦ¥ (ÌÍŠªàšo•¼ YkͳVºK^QSʸ¿†¿±ä$Í)X‰³qÂ_a÷þ­­úHkël?.$e÷͘ÖvOCÒ“NÍ]2¬uDÂEDm>ñÈ¿Êåþ B'8­å7$ç|>Ð’?ëkÔÿZ?¡ž£•/ ^ïšQ;\j°Èi$œ@措Â|-ÇÔûò¸­hÖü¯æäê®`ù>îpdù’OSÊG–¼µ{墳=8òûDá0ñé#-u ´¬¼æ…òþXµ³Ázª²MTðdZ¸®²ç°À5>ÏZƒ‘QËO *ÖßÄ›]-ü}à ¥Ò¶Q3Á•‹­6IÖ H•Ã&³ÝIÍÐ&§­,qkwlE²–Ïw/l ´¶áB5 äEù€e— %ßíÌ;¼¢]æ‡}° f/«ÊS³ûésäšïÏ^ÿý”wÕ lÌ ä-“·EÙGÖ5e䫔퟼‰œp½oóà2y“ó4A­†ÝLoÿJuÝ¥ÆÍ£ä4r¯zÇÖŒšUiIaR´¸BNtɾQS¤mšf¬õd—¯Y×\lS¹ÂÖt.LØ7áô–,5Z°>¹°f%WÈ”"D u@üj¢Y£V'íLf§7ñ”Sð´«dƒë-I³†(î‰/GcÐ#ùE ã3ïóæ²ÁÞž0-‡ù…W^¯‘ÉÄšoñ}Ôyâ"ùÛ¥þ4ÅȺ¢[°‚‰;C–yLçso±ñemë€ØJyà-®çie=kŒ£tmTÁ”œ+9íí¼…K3G ›yç—$k>Évï”V”dq=A/#pÓ¬«À ÓJÂ'?š^±²Ö’Ö¬j-Ó)a ¦eHìFÁޮɒn8Ÿ)Dñ2éö­—Ú$«\·LJIyR¥óîèýïë<¯|Ÿx-åøºSDÔfÅåom°Í’À†N½ØG<J¾QM´£Ùºfe´Z ˜³q¬žË'S²2^u©œ|UÖ.FÖªéÊÕMuŠxüï{/\sRåË —;Ÿt²2ÚŽ_¯²|‰l¾Ÿ"¿ÙX \FÒ=Zþ’ .2nެËxúŽ’Ìò„Óök±µ°eG¨ôWk­‹\ããK²¬AOÄÆ ¾Üsš°�� �IDAT.räå³ÁÅÛ¯9‡ü³2Eê2^Çi7gIŽÖ"«¶\¦åç]Ò¬­D;ÞWQŸUõî2Ɇäói3,ÑUõøa²ÿý¢G¯÷4P?MV „—• Nqcpkq_Ií 9=*X;Ëçl…MåŠt±UyåÍK|‡4åÈ_ -—xfŽ“Ÿm–t®ï䑵R‡™Òÿý“JfIóWõ¤ºBRÕ?B¦f~—\¶‘ †J_ûWt•ÓZ UÕwÌXˆ¬iÌIKZKcù3É_/»€ ¡\¦e’ë‰Úb {ìu“óÌTiÌìiñyMÆq-Y\¬BI'‘qeÑ0ã[?p6‡‘¾æ+¤zF¬£YI<¬e‰@z._šsäw™bà*"8›¬»\'\Q*· \× 1áZê,G‘uÝ™9äÌrRù™¸G=7˜+VU‰%@ +Ú-‘5§ɧ£ ’ágQ*\g[ߊŸ“ŽZD´PÓò}U0m”Ü®?0©#sJ£9O‰ïünæî¥hV~¥f¬•|ATdÖ�“s½R¸¾òÜ 1ã…Ó±[m-ÍJ’#¡H=Õ•V9̨OáR™„ÅB¥f“w?õÈZ¼ké2Ce2TŽSPGïi“£z&kòwºWAN»ÆQ21mš–<m²½¹9ÉÕö ±\çóÅ óºqwÍICÉ#Ë2«žö¤Y7óü}j×tA˜o¹ŽIh¡>^Ð+¸ Y“õ¢¤Ñ›P>úËt ÷AZO—òLµN;vúy-­ÙNçóÂd‰³{©´ ~éËgjåo·2^ÂtwÕ)Rµ¸f]X×;’ÁÁÕ´nÕU¹RË‘þ(;߸ùΓ°ïi ïŸÔžX]Ñ¢¹!²–ªýY~6‘)r[ôÈÖRÒ*»„˜üusÏ+k õÝ÷ÿœ?VÂ$+ÙØUÈBÉ,ïz«¤ª÷ºIØÆ§Pù×sÎS´H—ÕÍý+Õ÷_­[¬”ùW[æ|ª÷º‰âÐ)V¡}¥Å i¸Zùô]õ¿²Á¥0ì³ åL™¸º¿ã’d­aÏ[¤æÖrdéø(A#ZdªªäÑ’½2¶¤YsÀf¨Tb)kRªÌ i;6>±FÖÍ­´É<áüëµYû½tùòÑfß'ŽßšfeDaæ÷;I//}/N®:yë©’»"Ûþûmçc÷VÌT*‘Iל~/EÄ¥ f¹P[q†5çé!êÒj,ê=¸f­7™ÊLdæ¬@ Žiu³žÀ²ÆYd-îOàØ*_Ë@_"‹y]^ª?ϦçMÒ¬Q)ßàr”Ì´dƒÒmù´°Dß×ðî_…¬ËëÚ%§T%ˆ:âßg‰Ô"2´Îm, YìÉûžQÀ’½h.†V2ÝË ÚEµ a«·©o¤‹\ñE®‹Q° Ó,‘3ÏsùLòºšuún+q¼”–lìE÷ʶ€fmÎåçU¹ì¢7ø ‘©†ÕÖ¶.·žU¸Y¬6‚A<õtäZËyó%¯`J6é2# [ô\”T!Y´³„ðï[¾ Kw‘«'Iãÿ{ÂÀ̧¶-Üú,‚W÷ƒ<:YóYU¯H5¶9ZB¾´öÚÙ(ÍʧÜNTÒ¬K¶x[‹±íh¢Ælç27MV¾þ¨oäFù.J-IjLÙ~e5·©Q ²ÖUTË+§Ò3[eו–½¢VàVÎç¯!i™¼M`½ÊüèFkƒsudjQ’DkJà-)¡š×?1_4šŸ?É<ù½ªÛV4ë–÷™ºsØ—*6N^.¼B²zíÚà-¢7í„£&2-`o¿¡ÐÊd•T§(¨P­5ÌŽã$«¹´¦B¯|-×?n…žäk8E<Xlî}wUXã–Â*c¯Ø½(Ì`߀üÜ{bn?»É/¦·ÈS’_Qû F÷MÊøò½ê¹ FÜ}3þuz{ýƒ…çàb›X ¾•èžÅ}MëíÉï÷î™êûGî6¢‘»Ê—Ëí ƒwÝ÷„»îƒ%p‡¡Ì»îõúƒ+…‡-UÈ1íÎ,ö·[4VÓ¬wË@öK¶ª/^š”6™Ô»mZFÀƒ)±•j©bûØD¹>í@³–’Ge eK"Ž2·ÿjHöZ–ý«t°aš 4ú¿íZÙ` HÅ‹W‹4¤[±?OÚ4mÚZuC"; r«"5Ó·µ:YKͼ¤l´¾ &eä„é8FƸà]ÚSITL«]|*}Ë÷JLèÌÚ>V[#k¦_|#B-Ü«õg ¡ pl!ñª÷§ÅU7 Èß„âä‹`}´uέìMQižUøåž6±Wª gùiEkT¿<“ar³Ø«ØÍdjù¿ÎŸåíþMÞÿ’ƥ߇1çSÉSr'\íWž'æâÖ:й9š~Ýœ¬Ý‚"™5ÃÖ”Ž!ClR´{6n9M>³Ç×G™ÞzýA½þÐ=S}ÿUYte.á:â:ó©žXˆ¬Ã—{²xâÙ@¾[pWÂRzך.UºÕ¦~]QäÕ¡±ûJÀd¿;ˆ¼Ó¸V®ú(&A™Ó«q¥[—G$É‚_ývÑëæ[Ãúg ±ú-çÊ)bÒ5PšÁFÓßZP7ÑØ.N;÷*`Ù–æ^&Ì—Õ~Âe9‹­Ô,µwÕAM%­‘ nP3U:%Ií.Zæ•àyMl#lŠÔ„¨nûš¨©Våi0g [dÉM~±UëÍvÚô`J›V\k±æb [ËŽÓ„!ózó¬»l‡žv”àÔlÚàËv³iˆ¬¥,ø&;g%H†½¾¼_µ—·ˆ©U°5rbë̳R/ìÈwù·ÜîëÝ BøæÓZ³ÅEÚ²¯1 ‡î8Ö²×#gƒ»oVûÞ¯šuç5ƒPÔó¬Ã4­d/óîùê¡ö—õ•þ}Ÿ<c¶$ò´é g_ЫN•“gvµ©™"&dNUȶe˜×Ôôê-hÖ|™•ï¬Ôòò_>¹ï1Vݬ|Õ¿(¿eò^±öL±#·¡_›È»€Ióf’è*NŸ$õmŸOÇd _‰´¢f]¬¼ä1 {ã»Ö&Ê’%Br”6þùkœ¬õL”ø]–䜛-ë]¬ŒfefE6„©­Èùy\r’µ%ºu²>hä´È„° Q]¦knæøñéåþ®˜k±;~©¼nÚ­ƒ¢�8ëoúÍr;š»,™J5×ϸi^óW¾öØWútÐOÎ3o].SL¼e¤gS$s{%Ï|!%|­L¯µåàƒèƒ½Y¯KÖ¯ˆØ ¨Ûu³ÁõڣƸ°ýÂ’ Sá±A¼À°ÑµÄß·,s×ÏWÊ£&™k„##¶­Y£Ö‰Î2ÀýÃR¤a<„gžÐð•7Ê\»ØrPüpŠØ æ¹ÅË$ùÜ$Wa­µ RPºÜ"µcò°ÖS_-O×ý`n`-§™i\A5Ð+‰ÕÈš°Àf†À¿û˜,Ë‚¤‰ynòÙÒÁÖëd*[~Âü¯î[HWUr ;åJ¸Å;úì |9aþ@&Pœ –Ñ!‘§õÌź™O’$/Õg:×”²Í(x;ˆÁ/BÉ81VÌûÚΤÕéÔ¿½¯~ˆœÇ”us&wär€Z œŠÄ°›ém¾¹}¾íÔ'#‡œMä§éì·Ìž6–¤öå„‹ÀrÇÄmÑ)¢,Êb¦R·;á˜Ø9àöå)ÈÚÑè;w %K›qä÷Õýïµ®»Åч3ç´ùœ±-²>hñCš•7 æí&„ËuTF·sr×w>úWf3É9è³Ý½?âòR2ðãúãó·:-<ÙJüÙ¬`˜1š@(Á´¥N®êíÍ”/¿îÅb¤o{sµ{¦ÔënV¹¥.ŽüáÙß|òií}Dsde*n|ù}›‘¥=&Þäé\áRÃEXè…Kià©1HSø1Ê0™s±ä.Àj¦2³<˜ÔÜΉ_ßb9. ¨5ÝëžIÐki1nZѶEVI!«¤³ipÅj°}MwåÝÀ]bËŸ*}Âω3 6í E,óán�ˆ–R®L]’¯Ð—÷D$¡;‰Ô§úWªïŸ ã» d'œ÷O4­éaŸU¹!>šnZѶEVI-+OÄ‘ÍÏUw!ƒ 󡔯½âr¹/CèMºvD•¾_,·WËw�Õ¿¹biD-Í$¢íŹ'p?ÒT{ o†¼rö²8‡|P‘öOi u?ùáÖ*˜|xc&_ƒMe§—ì'Ó~ïšè+BSMÞ/Ù_¶í§‡FkƒIšœ‹ŒÈ&qºvÉ•Ëz‰Nl±Âýfkº‚I2ÉJúJÆÌŸz æ«MÙí}¸Ï½r‰HfCmýÜÿS¾)p½iN™ç€ Aå69w9hYߊR³²É˜©ýâ"I?PIàçãfOŸõqYôî–Ö ®º ÊÓR®¿’&0 Èܯ6;ÿ ÍZû`õÑ Y«2˜4‚PörÕÁLø‰[Öäkà =ºsÍÊËÖqæò*:iìSŸr½[ÛÄ+lYÆ­)ÖÈ ±'F–‹ÂÑ|FÁˆ‚ÊUyJœ¦Í ã$‹‹ú‡®ûпR]÷ƒzúHcuœp¥j€sf77Ýú­^<Øèy»\‰]~ZŠF>)Iž!ÑçJô@`µýAx7±¡„ê°˜Q«Š,qzúÈüÕuú»Ö<}2¬I–·¾k}ÖÒ+Y=¯HNUy–뀲M“•·fHÙß—©ý‘lfM�û¯¿Ì9 òÚ7a ÐnEkVpìabµðýdfU©fpÖ:Wi¯Ð9áþÕ8uj²Ó]ÿã!ûL‰£tíŽ- ö@Ö4YBÌ ÉD/0½çøÇZˆjf‘9²Á;КÉIh2³Õ‡3§µª)øÈb%7«;Äim:êÔ§Ôë†úþ‘5;kÂ’l+람Dv´gY²l˜é$™¤#_E?¤'÷w³fy‰aD³*¶†¦Z—'Ÿ$²»k>œu†‡¢_WóñÊï"g§õ©ærØ©øõÈZk¾VÒ²&¸™ëΘLЭgÝYsÐ’ãA!ªH;ýLÐuUü2b¦Z.€ ª´*çÌ“ô@»"b'Ø<}ÄA׳Éìþf‚pöÓ']÷AW3ù¸ä«uÌî`ï{.öÁ±>Á @%>û*o4Í0±º*-e¥Ë»øæ«[þº`¯¿ò·Ó³iVÕ‚fy‘93êò©¥4AÇ amÀ4¯ Έ¦¤NöAÜ÷\ìæÉ*lÇæ*B¾<Š©J€eúzÖ{|á4§J‹°Ùœ B´6ðÜ.舵àª($嶬qÚ˜Oó¦ºÜip–pfXkœs;〬%e¨ù«¯ä‡YêŽÉ˜ã{Ë”î£.¹½Yx%q?F´&a%ÂÑ7?š‰7á)!ëÛ>_Õ¼éÛDÐ PÍ^7ÓOi«¦qåë|3[à6ò¿Òî2Ã;Ï» M–ÅCWo|5\^$ìöU%}ü%vQˆªªÎ¥Qƒ“”Öyúê• O7DYk>ÕE‘½¢t¬ ~bN¬òãV¯éÝ_fxWd ¶ŽI›°4Qç«76Wʶ¹þÕÝѤ/ª‚[€Væõ$2iÿëΛ¨›ù*³<ç+S§J%§ÅÍP©Ô÷Ô묖p GóÁæ[»cUz ²’p’̼JDíĹûDf»©i!†ÁÔý|cþ‚xE%“;'±Üÿ–¥ªùƒî7æx% «V ¹”e1ÈWK¡6xÛ¬eÔá5è¯ì8w%å4y2rñØ “…¯žp]KPvÿ�ÏFeë¥Wù#³œºýZ*vfdxѲ5ºÓÔà.ȺåZD§J:›³°±˜ô Dj럱)èΛætfEíÒ¶dëPĤë•Hõ9Õ÷O¬E«B#ˆ¹ ²¶÷¬7‡Ó¼5Ó°|á®&eÁÃPA Fy4æ×[!”¶9­^ÝŲæ+±EI˜jÝ(b•ǘ©ïù᧺îíë¤dFüTh‚¬Œw®Y§_¯ìùe3“ÿ‘`+3êÛ]ÞÊu7Ò6èÒL>rÿÏg¯¨NmOÇUª]÷A=ýj° &[©ó¨+ÕK®ì ë&å¬Wƒ^ÑoI:Ìék.ȩױ]ú"tP‹gfÉá×Û÷í3Ö/ˆº(=zpñzDwC Àܤ13“67.Qå+™›y€[Äš•�ˆ¾µŒBßi5Ž.kêŸ(¥ºîß.q&Ï"Øypñº7²’X²läÝr„G±j¦‚Ýa}ãó•̈ÝÈÐ":µÔQ�àÍ|®žMÂ#n_X‘aHüˆ¬$–´�•¬"eÍe&[_Jéˆz%DûψFU„á¶ÏˆH”¬K—AZlËš`…TÔˆ~†ê„ jGÈÐÝ‹×Ñ"ømse ².øÕF§HM__ßÂܯ°â ±oièÓˆi ÌWéƒXWªŽñúƒ¯j)S°Ê÷ò50G<8âGó.BSš…Á–E°õzšnb58ر`•+ÑR‚ÕÇKwü¨*'uŸÈ4/ìñãDAÑgO$0"úkÉ^DÍ4o—r6}Äõ¬ihô!6¹Òj‘)XÁcÄBßœ¯¤ï’=�@ÖýËVÒB(4…È4w/ÞÒõ j"šUÏã'uÏ‚U²½¤¸‰‡®µ®Æí|ŽPª?ìÝ7ËSêXùQ†pišõpó¬¼Á¡b{×ðVþAúš …`E µ±Z©¥9"ŸØŒ~ÿ{ýϹ_õ+îë¾£‡0>l¸ˆÅ>l=þC@³"²"²â Q0ìyÖ®ëpS¢¢¿VÝ›Ùîv3?ø°¹ñõéçê=î>l.ÿNÚéÒÝR²¯¤{æ1?lЬBÓXE$pTÿ;DVÍû«ÉX¾Ï#o(âÛXedåÄhÛ€Hä¥$Ž24ÕC‘cBÝ"‚pµT¦’§ƒš kE1ê“¡iħ.ð’Å¥ EDáÜÛÈô5¨F^dmº‹í…Ørý\½GæQ—£Ží®¤ê3«ð’Yë|š!C2åÊ‹N!wgDꄌ%%”.ÈZQ¼úø î"‰(Lö"'Œà!Gdzï¥ÌÉ C¼—¬•8ç[lÃ/Ât%^-"ÆJOÍfwGf(ÜcÊS›¸Wö.排Þ_n"óü”=*Y‹Ostô ë¾nÒs®Ç¬ùØÓlv5+£b!p Rå0Ó’Ô]cCÖ ëÞ\n‘îÅ(…ƒ'vØø· VŒ&Ó4=¦`-È<í#C ÄôMu?¦Bà™¹_‹¸nÃM÷’#B³îMi\ûôNøøíS•òz4'Ik.Â1Ç!F6ø(âõ*%Ë(Ë¡ßå,Q|5òUƒ6J.ƒ¬ûúÀµ­»[|üö£JûÇ´$uñ¦ß%É')wrBþ Q»+ÀýVMÀNFNW—z¨«�¡[Ô§ _ù[¨WÚ¿nx;ÿ‹_@ûÙã÷fýQ°àHO©ÆJaÄÎ?`©ƒ äxþ¹Ó«Jœ¶$ïA{8²„£‰Í·¢œúÁàÆ@M ¿ß¾ýT׬?ò MWéºæ°FD©Ì œå=ú35(ïE ²îîÑïMÀ2Sʱ pPå´Ñ¨Y$««“ò $OøÛí ¨Ê¿¶U.m­Âc«¸)º ëÎùº€ )£YKéHß4­|«îB[D˼ n–# }ìÔÚ Ø· –Yð ²ìS{½SÓK[F ø�4• *cLö8“ý`êfd€,g[*ãjCζúð9[ðzwh{t² 5¥¹YlMoZ 0&\Û¹³RP­úê„‹ˆ`¥>k'Ä&ôë°û@¹ÄDI)ÎüT±®~µH/oõ ²"ÚB>¢YÐF ÄC‰´éXR¹B¿nW¿v/Twe— ù&M5 I‹VïÂçàëóJ¶ƒ=f Üâù@°¶™:/_¦á_M‹Ø®~õÎÔ©’ůü»æú_!h]dƒÛÂêp>¬íõsõ¾ÿY:J}\4Ç—Ì/~Õ‹k݉aðu+°Ì¡¬Æa%Ô‘¥ÈÂŲ ëÑ%l)IŽÃ˜ûÏŠ§ e×xݯD4Õ±ãËO‰wê×.Q†þˆôzQQ Uywþ‚ÍÏåŽKnRúP±C²æàGhþP\% -Û‚Z¾®¨YLf¹|ìÿרDÉú#¦Ê=J‘V<ˆ%¹;Ì’º•·ÖbÖ%Å4ï%lƾ3 ï¬mâGÂ{HÒfÊx/DÉ>×Y‰Ñ>¼uÿtT¢dýS å¥ÈE!–ç«›Ú vWÂcáni•[¿ }w–Þ6YyU)Úñ]ÐùV¯ˆ#È¡ ˜fø|ª }Ý•AÅ`oW9çøéÛÃöjÝ$Y5íäýS“YÐò×Ý@LÝxU‚ °èó¸€LÔ~ÅB1ê#èp2ª+ÊÐz£ :’ç7™›ËZ¯ð»»èÒD3ȺÆQÀ! c  +xwƒ„ A¬¥\ÍÔ«YX›L#«=N‚¬´–´òŠÓ×çNr2в«X¾\h ÏD‰¬ìrÎWö+œóvüý}X4ƒ¬ÛSºEvY x³íV¡<r(­zÈ5~úìg¢6�i ÏÑÓˆJ*–T„|¹¹/㳟�<Éö#Ëç}Ôw™1Þ-YÓ¢oXíC³æoì[Òšìè;(irñ\eZÃæ¯ªm Ù‰ˆ÷P…-ÐIuë{Q‚Ï`M²i¾8ÛæåžeëfȺVR´àqÑ}jÕgõͼ+’Sk 6á„…ín»ÈRµ‰¯>¿owåu`¦E}5M¼¹27lñR©ç¡„‚d]BƒnîèÖ icjÌ‹©U׺ÈmA#1a §HIàuoÓ›§FI^wд¹¯¾«üÈÒ_ŸâôÍ­º5M±Mè|ŠÖäåDý+{3ó茛ñvY ¦F‰î§>Ÿ"•Ï9–µ0i^Æ¿×]{Zi ’½k*Ñ»ˆ‰I¦òÖ'%}Â×tçwëŒ$}ß‚ aWF»îQúBø<öv§`÷OV½ZÔ¡U°<hÑ»7€k±ð‰ErYKTµQÔ6–PN  °ÁV¾®óÈþBZk&Kƒ¥FÞà«ÞäêPÒ N>¹Ëôá‘?m€¬­ˆNÞ Ð}¥,¥ÈÑŠHasdTTT¨¾D®|ê4=|úw8PÎü«Š¬pJmðuK° !du#÷Ñ—_TTÕüµ˜,w…²%£÷Wdƒka¯àhÁÌ0¢,lÆÛî,�•¨À„f5ÑIç‡ñ/þ–;ó‚.¿QŸòF˜Ž]º#ržÏ^w¨¤ï{ríµf¦{!m«ÎÈnu±­2 h=¦2„H[�Ê è³Å'ĤïÐ žˆî±>Wïɡr-óý“´~tTxWþ.7ýÃ`!’;Ÿê&¥u¦šA¬U”¾—Ô–ýCù…o‹²%k½2˜ïÜJ(a‰[Ö$i}#Ÿefa‹¨FŸ±”ïêÀׂ( jµXœtÝÇ(u<ЉXùòZ¤®û¨<åW>¨o¥¦©9²ÊÉ´°A’pÌNÆëÊV3íé Y¾ÌÇêç£fœ+ÿkTÙ°d­-™Äv3À ²aÁÃZš"!¨o‰ Íž«i(wRÖWI¤üÞú± r|¦ÁD"úÞ{™¤nÖ?·¯\›#k™nJâ-?‘Çï 4Ýžl’,a'oMÃ/]•èiæWIÙ0¹ÖÖ’×ÖD”…„le ä<Ǥµ�†¬ŠÕÖr1í–AñÂî:WßeZ?·¯\7œ în›ã½ü”˜t4 »¼r ¶)P$wT0yÃÐÚä¢P} Ï](F‘Û'¯?{ü^E¦šI» PVŽÕÿ¤¡å ¸žhV*|oK,Òm?xþQŠ3ªEȺ±¨G;¡#q‘$9ÔšQ…µî³Mº™X&Ahež…“¯Ca‘p…klcóA¾óÂ= ·*Ö JÀU>³ßq„—)§aæM/b—”ò¬¹p–÷‡"ïFÔ„nËâõpdMÏ@»Ð’ªá7…<`Xs„¤XŒB‚™F61és@”àÇçKÌ\¹‰C¾»ù( -Djœ°»‹AÎKØõ.1&–ùÑtJ/ ú&ä`sꟃwÙàö>åo²öõÁ•‡.g#‚Õü5Öwž·Yp…oŽëo‚‘¯d½)ßÀ|æp¯‹¯†H@Î=*†CÂ5'î2t•©§†¬‘Ð Z-ZS­V-•k_L>|¸6mž¬õzÑÈÁ¬ë›,'Ew¯LSÃ4®#„àaXHN=ºòÃLmlëÖªZPž+vóÛ臓̞îjJ±Æf5ƒ. ¼…¡Ä5f*¨Èù·¬Ò¾X±X¾ö> kILfvŒ)#go¦øA*9)"\DΚ …x¼iÆè †IP&1;§›À-Éó-ý¥9Æ�/El¨UkÒ˜‰g§ÜÂIkîØ«f¤gæý4›¿6¥bÛ"kUBÔsÙ%K‚k¬…óþrÅ·Õ>{üÞGĨ2"&ƒ«e£”(ƒç¡BX²PU’ q%ú•Ÿ&ŒZÒêS«±û*Y¯kî/g!Y{»®—,ÂòuïY—¶Ë »ØÃÅ’x[MÉS¦¹‰@K‰ºæÀ¾T³ï@.SÉs k— —p•-鉈χ é¼ÏÚW"=]oBjl`Τjùëêiã%î½èazª¸—*ïêñ§þýŸÿû×ßþú/ÿêo~ùË_ès}”ËlêJ-¸†R�� �IDAT{#ÖåëŠGŒ:"gëKöFie^¬7(X[ø°ÉÕa©í»H37#œÃ*~@‰>–ß 2¼$_û¾ÿË¿ú›¯¿ýõ¿ü7¿üÓ?ÿ‹†4k�J{|šrgÄ Ný0xk…Øê!~“<"ãM(g°už’N±îq£Ê¬\ï'ÖJXu‹›ä0ó®–v›ÂN›ÝÓ+^ôš×„Z'²«¹ˆÖÝžÙ—ùu8yW©¯˜nˆ¬ÔÅöS“凊b|%< ‡µ6“{.î>Ç|••T ‹’\üøX妚ø¹ÕÈEž-˜#’Ýa…­0ù:CÂsQÅ;eÈC‚¬ ²- ØùW_ï‹ÓÑßꞣàä—ܸwÀ;Ú•sÄçKkV;ZËç3i]ª5%‚ûë «ÃCrXŸ’ ÝeÎsá]‚a‚äõ"¹PIþ@ÁƒF5êžpB_ØÕ>ÿkdƒ‹Xú©PæsI¿/_N\ÊdݹÕv³ÁE$£ªV©[—«7.Øù<Áq¢»~’ÃÓµ|¹>þ«†ÜüHùëƒÒ\ïƒ<ã½¢Åú”1V ½Ù}B_,,7, ¾žÀ‰ê•”AYËWܽ_'®¼ÙÙ‹iæªÇd’ÞÌ‹Öå4äqœ ¦›…4¦.£•î’’t]ˆ®UTÔ£eKrrJ– žF=ýZ#°›[l»ÉÒvž!Y<k p¿àÉ4®Y—WÃM»ê4‡£ãLíi6š9}k2²?Ï|*¦”ï°ûÙFé [¸J'¨¨J•ä«h¢† . ʹ™ ädEë»®ÝÌ„i4[¾$‘­±Ü-èõù Æúé+ÿ2\ÉÈV ÑÑÉl3pEŸçQ—¬ |ƒ—:ÄZ§jIIMeË}bxÝü·¿ž˜: ´¿QÚ½w·ö2iÝÚjœµ4™Uïjb ­H8ŒÅ–Ü­—ÈûÀ7jíÿ1¾¯Š*ÁÊxÃî/ªÛOH?W}åkžÃB§s™JcãÑhV>÷ýCå)¼šmzP`VÁ®(® n¹ðGN—z–úv¯¿zÔ£'{ýz™,ת :Ó¨¯·*É,ÉšQ!&£Ž’¥CרuïÞò¶zÚ—±¦w¹/|D¹®¥ggïˆÁÉn²ù×BÜ®ùÜAp—*’â?lf6xWó¬i¤lDºYIàYÊ÷:À`ò*øWÖºêjƒsvdÈÇ.yº1m]MÚeW%µójêÃV÷+û>,ׂôM>óœ $ûú€-á}„ÍEÿÐí‚P•¬»šg•»"˜›­e¤`¢´?_r¶·Æ[:?|3þ ×ÌèéRk:Öܽ.÷ªƒ<ÞzÆ89Ùh¦…5Û¬Ž7n¶ÓWEL¶ÊqDVßJÑžÿB÷-ŸÈŽZé´Ñl0oÎWÀƒ5®Å´4,1ø‹ðAk$ßeJ’ØôÕ—ö[&õ­°Ü0ÆÍîg·nyÞ¡úäë¶4ëþJoú³êß]øúNõ§Y¾—üÁgÁD´"Í›OÐ%Ôø,Ù <ªê8*Qì;PPˆ—š9.~Ç6ZìêT&+‘€A’9[W*ª7ö‰$61Ëä–Ý|¯>±Y…°µñ"šui²Ö°0L¡¶>jw­tnÿ;ÕŸTÿS‡Ù ׳ Ü-ÉŸùܸ${\ã¶Ôû²+»:E‚O&O›Ó`µYã…í=¶n–¬ Â7Á5—„–üÈt”Sq¾ 79Ê;÷ýUß?œißû’”­› Îììù&÷Kß:ºù+™>M»Þ±R÷¬Ô­ên”ºUêv„¨RJýT©/•úQ)¥Ôª¿¾˜9 ÅÀ76§já7SºÛÊ{› itš7Ö1ØÍ'gþÉV™Á´ª’Mvã|öx*‘5û™›ä³ò´ŠrHÈv„j2(XI„ ³ÍÖfÉÎþGä}žó‘[ñëZ7} ÇÿµSSÊVÖ7Ó–5-}mjV3Ç«ÿåzµþÝ}×}TÏ•z>2ÕL³—V0ÍTÚ©Åë¯UÿNõתÿêgèW¿{©¡gÿ:V…úWF¡2÷'JÔD³®r>™.†ùç“–7Ö¤,[f•“Ä^X³iÒ»Z‡ŠÎªÁ2`FWø=p袤;{—Q‰öWîDìøÃ=]UÖGb«µÁòºÖ•=†N¦ž.d}71Õ½ ëÅéÝs(w}Ù ¸EÂêâeîgñ/;÷[Xò¥œ-èX”¼œf­‡†âÈQw¾àõù°­è7”“¡Í‚è]¸)[„Ì”í¼»ð“ ¹ã öýC’â¨j‘µ7«ÕgÊ#y5/ónUèŽ`¥ÔwJ}­Ô——Å?RJ)u£ÔY©ïf¨SJ©ó”¿•þÞØzÌÍ”RêÇË_ON¦pͲ©’ÓÒ¼ ‘%] Ö¬ºÙ]~pÆÆ¡*;µîd|’cK|ÝÄuðÎ3uÔ«D) ˆ4`¹Û°¤¹ü2ÉC“½q¦C<·7¶ŠuÍÞìÊc4â¹ NwÇᇮû8ß?Ô¦QÝÕåxØñeV":6Ê“5ªÑ›e<Tû›½^‡¸ñBn.¨»Qê'£#’ú©R?^~~9¡n0EbèNêm†ÙYåL?óHÒT85n®öi «Éy×`óߌ¦{P߯>‰Fn`v²‹j¿šù,2þ¡ßüã/oT ˜ˆýƒÖV ]Ü1xžòÞs>§~Í6~ý妿«n´Ý ìçþ§‡—Jýã‡ýRß~${ͺº¹ïªo?*¥ÔϯôAõ›¥{µ6• nÊ´A¸ÁˆÛ3±ZÆÊÛ®¿'ØÖƾó±›Á]‹*{}%ÄKþuV)×,þMÍÓ®¬¹?3Tq‰v¶•yÖv¨Ï/˜Éqˆ5ågæ;…/VÚy2yè’ë,ߥ´ÓÎÿ°-— άÝ] ¥Œ¼ÖÂqÚeŒƒ*½™øÚÿNu_\’ºç¹=;ƒŸÆª`½1>f0ÏQ_Ý,9ÞŸf‹„ƒ™QJKþNê°þ±·sxZ˜ƒ»ÅÉ™÷09 [¯UŽÚB-q]¦õµu›%o#›»/ß–Ü÷Öè’ÿb”¡V#šº¼ÆLòvÍ“™RÍ/çŽK÷ÄiïCá?âæjƒ×l$nu’Q3•IÊÁ ´È¿íBüŽ{ h╱þ·¥ŠN%ãd¢‚IçSGhœÄˆ9“ªŒŒaßš•×|̲×Z%<w¶?é$G¹4vdª1ùºÀÃMsšµFÔVNLZU7ÑíÄÇu¨çqÒÔR´Z€³¡Ó»ngk_{W—jÆ“ŽKÝ´þ¶¼ Û_¢š£™ÍÌn6Á¯læKÜ7޹ŠÔ×UMEÖX•í^®÷Š}Èö`çO)¿4i—ýÕÓ ‰xÅÉ4`ÎѪH?«ƒ›RcM©•g%®%vg{=7ºÖ|û±ïªŸO+mÔÏ6õ7]”¬kJ%ñ¡™6®¤òën.¾¾·5çus¼cÒ¼£êL Ÿh¿Íx–·óç{Ø5ù«2‚àä¯ls²s nÐ"8Vê¥q…1s®×,Zv}0øóñ<×X±³Qg‰äºÜØ-ƒŽŠ” ]ÞBÕî1we7Œ³’Ì6ã͉ØçvQñˆíK˹®û¨¾½×ÇÕÂ9ˆ’Ñl¹ÖPmg€ÓA¥.n…×3ÃB¥f[š#(e÷€s“·rÂ9¾dΤT‚.á 7¡ä'aulÙm9$N>äfsM5æ[>Õž¥öA3Íž|¯/ÁçžáKÞ¥I\©_Íz¥¶¤Ê:EìÏ"_®öhë|ÍÈwÑÃú̒ȹXÒ…*XTÜÂç/øe—�3 ™µ=„r †6WZxü¨ê0Þ"1ÿº6=ÏÛç<a˰DéòZé“Ç= r»ØøN¤¤7IÖÝÕvÉ?œ3—ͨs¡ï(î<_Ó6hœ¬ ÂH®äb¿¾3¿ßMçá…‰%OÝ+-UZòòRÁ”Leº÷q#s†½BŠ›«f*ßäõB 'ËW0-\“‰ywtÅøÚŸ¦  uU‹¦ºÉ;ý9¯{²ü÷}Öüü·gÓ…K If=‘U=$/&" ‚ZÖß4aðI y*¹Lò4‚¥^™îJ`Û´WÂÉKa“Ùɯ-‘LëêIM¾/¬{D]dä Êi>X/K}n\ηõöÝÕeöt˜©½ ¥y&k4«ü]‡ eÉZ_òÖ÷ 4†¬T£´Šop²÷¯wK–êѬµ¥g‘™]yutУ*¡am   ?l%[‰Ý-±K¡ó%élÊ7¤s}5Õì»Ì±ˆf•’5Á²§YÙšv »=ê‰#¢ÕšF™þû'*ñ{ ùïŸÙ™–®w‡K%è2 yU°½yÁeµjÁyÖ²°†Èü°-óe-צÅ1Â}ÜQ|­ÚÍ”/ƒÏ²S›&ëFUfÙÝ]iRÖv1¼¬¢Ñ*Ö­%öËÂvT›¼hs Yz¼k[˜ú*[ß$ÄU8³] ÃïJhœýY—–ÃÎÍu‘kSH—ÂÁ뵫y)j*ð;Ü$q¶â‘ùUž`=oí>[0sž©—ÊŒ.ƒ užŽÕÝ*uVýIu7—ŦßÍ| M³ëÅÑmÿ²±^«j+c*íÌ[LWj-ÞÏö‰è+Îð%<éIY·ýŽÛ\]y&%6÷Œ_ÿpÕîŠUÅšW—/Ÿ Ö>‹¾+"ý&™4ÀV!ø3’©¾ÖrÑüL*é2a¦M3Bëzêt§¿Mü‹e4ñ@³WÍšÀo&×j&cI‰i.iõ9ÒeÆ'nÅ*?Ú¿°uIµZDFäÌ¿¡µP}.æ~6ÃZµ«»—ðnOk¯• iPª¦AW²bG>ÿ<“œ¶«ßö£dƒKÞ²Ólz•™òœ˜7Ï›µ\&Æ]·¹™Õ¾ì|ˆq‡¨Ú”F>rlÉ•ül3‰•àJ|«’µªÖ\,ÉÌ—%JÆ{B­¶üر².êés]qLŸ„½Ù‰jëvž~pçVÓ.Äõ£Xýþ·ðe'û_é«_^%»@­lr©TÁr-þLª¸ì‡my$¤ÍþªÔy.“zÚ½e*ךgõ™ÜZÿÒ—ÌF]…½¨ôöÒ‡üDûÚk_»GÛþ”ºñ¬‹õ'uÉ…›?'º‰•T伩d}jpËœ¯{ß”ª{zK’:¤i~ì‰1ËRù1ɾ{Œï±dn˜¹›ˆå×GŽÓ¢Vsv÷¥ÎS8Næáä®ÅjÉpÙQŒ¬ÁosÞ0!óû½T}YÎ3ËÐÞLÕIºÁ*Ñ«Õ8óîv"®Y‚ä>awÆ-kš½{¿­4ÊÅF¬pôaÀ­¯É™Ðþè!‹:æƒU¬$l4+?y¦YîëVWY5Ìߢx{öuÉz_ܺäg—¦‰âe�ß.YkÈØ2ײ—ÐÝå»·“¾ì¯Uw3âv<¥[cnõ4ë g|šu‹SÊþ•æèúÅšÁM eNÔêR•ïòf½ûÙco_ Ã+.|z”iOn]±þAH)߉™"8HD«Ü—o&Ï܇aœ ¹kƒ—–_"ÜEÞž}[´åÉZOî, ¤Æ¥ÛÙÝëÍBÚÔîGcˆ/ iKiMS[ÊUEbº4ù&Þ¦ß_ŽzR•_Cb¥ˆ5'È¡,bé_»·ö[¾Œ(¹fÆ¥)šåEIÖUµµy’üÓ@ð¶—ùþ(î_m—V[&AÂùX¨“?^øÖÉk£Ü’cßÑÛ$în׳¦q$ßi,;²;ªž&¤Í„éyú·»™¶tÕ¡åÚ?¨^³ÇjÐà7è¬<mpÔ|(É…žÁ©ÊߨOM__ `$’œ˜çàN�“J1vU«+=cD4í’dÔê[¹Ž?ˆ\˜Lƒñ‚¥-‚ett_gš·o"P‘¬­ëŒ6qètçyÆNKkNS¤·c™Òx†çœ^¥x;IXÓ•‚Ÿ^½uÓ³ÂR¢¿¸ú´‘/ñ›ð¥/×mA®ø\|ãä J;Z03¸i×¾'3ýµTiΘrnY‡+rP¾+{ìÆ®D:Y ~Ûe·•dîRgÕÝŽDìO,M‘ê.õ×Jý¨Ôs‡¸·áÞЩW³|É”Åesî[ÁÞéM…$‰šSY#Tc™Þ>Ϧ¸¯ãÇG4˦ܧ áU0…¾ÅÝ<¥JËŽ\K:+U}HV¢Ûšê~ v9(…æ‘5 €Í<ð„Õ__@{£”RÝÞúg·LÉ<×ȰÆmÙxµd–ù¬ô6ûíÛÀron>6MGòTˆLY3EULeVìU9€¨1¢>yÕ^0³E­yh²æH.f_MÓ©ÎèvÔ‘V•И4þã^¦6õÎ@e€'ñòÝ«MûBPñ¹zßÿÌKë«?9 ÅÝ(¦J(%W{ ³­yeåYÀªœuJ–Q¥U»AZY„ÈGk\Ìí¸¬º²&|õ3† iÇ’$“Í|ï #uzvP¨cÆø<å„ÝS}8»qMȉ)è¹±c%šþïݯD„Ó·<ƒ‡° M0›_ v&B‹©IVþÙe¡ϯìÝhÝâæ¯ù~~¾" 4B¯"‹»8‘ÕR kÊWÎz’8~§Ô =/“¬Ã<«º™zÚŒ‰ßóä»4âöLÕ4©IøJNLÃ;ç¹áÈÁÏüùÜõ¬U›z{_¹oW’e±uÎdÂÖW‡Ìøò`ŽZÆãË!'¬îÝ.Vƒþ±¢MXOEèÌÌíÂSªÁ-Û×Á[Êó½Ás¥ðÿQÝÍEª±œRJÇ%ªÓ.·³´­6ް»®žlñ~;+‘¹â‚÷g»AZð›Õ:’¯{~K¦ò(GÆù\ùPæÈt·¯ Ørƒ’P™)QÞ2ÿ;Ó¬&V‹Ëç˜,é|¥¼ §´¿Îµ›'«0‘›ãL õãÔA˜N)Üï&3¦q"vÞî¦{£úw¶3°Î!û¼ÉŸ»Úv*ê†('›}(ÊúL!äšRX}»Wð¸>g(êÈ#úZÒF‰c%0ÄœŒ9›»×’¥d VEKAØw/âì„ç°ûÉ×ÉÊú3û�&ì!3ú^€ª•k÷Å|ÓÃCX:}1í>s~˜g†­cßÅ-…å7PÃþPS°¦á­0rÏÂX%K8’Ù$ÒȾâfüôªËQÉU»£é[íç`*¹ÿ\¶½QËznl è‘^jnxõG“½‘5P¸+ÀI–Fà½SýÉ0,$‹Nã‚×±`øÆ9ùólݪu9ºÊ)ùÁ"§Ýqd«kx[©�˜Ü²xG‰ËRÐ Ùš¯Õ±’F7ÌSŸÌ­ñ‘{±ÄhëÖïD]cþsC”á0È* eõ.c…Ñ×Vµÿ¾:_:ÞÜ+\Oª?O­o”‘}eúÕO‰¿3°å…ÄêÀ•ü½pÁˆVÒœUÃÏw d¡PízÑ‘9«*4ST1+j°hµÛ‡ E!t·ž.^‡¬Kxë‹Û¿ŒéÙ›Y÷˜‰”§™Ü;¶Þ8»û5ÓÉ'·%‹b±ßøBQK1­Xyüðüsm’‚— ü‰h¦RW'-^ò-få¦Áˆ"4Zæp® þ ~O“¯;ñ`b:¯I;¤y‡e6æVe:žü»_Ûü³­ü¯gç[ÄëÓÄÉO‹+ ›™v¥´rÔBUw3w±Û߆Ÿ\häkBG^ã>Z±®«G«r×ׂF¿¸:ÛvS3¼™yÖR"˜;ÄyÊOýÏOÓV‹‹S¹“#"™<-“4ö‰QÞäë²™â•!V¶}"¡¥s´LëÖ éIì¹Ë´è!>xoñ™ Ó¢l¹ÓDáž’À+“5vž5G„ñ˜xžƒêæ²ãwc½í;xæÊωÆ^]„\ž–¥/?ãè¦X]\kkÓ.)CŸdŦŽÝ“t$»Ì"-,çYqxl]çÅVoâz·1ÏškµÏ EΘž/jõk–7³%m©OÞ’I!µ[_ž&ô¨‘,Ót{ ºïæˆ<wýŒ5/ëSÌ ëqÍ1-Š|ÇŒ#ëWU¢â·ªÎãÍ˦©}Ë{6¡¼› k#ﯧÖo{ºšI·“›Þ=ÏPÇñ+5³*4 Ê—>¹ª7¨¹K \Òì‰!£&™C-¾êÎÖqõ©?ø†%í«ÌBåàòD2Ú†6G š8–º-ûHo¬YÒ½[¿eJÇàîvòÙŸÙôŸh`“ó 3åzCèQRÂÆÞÒ³ QÞN©Ùq;Æ è šý2à´4.Yå2[¿¢E°•¿^×?—lÙWiiî3>ä×ê ÖRœ•’¥äy9Ö†|ö7FÖ(¢$g†É¢Üþ¬úw—IÓó(U ~²œeXÈ1Í”ë-­G]+¹ ^é®Qb”±Éµ²¦&QúÇÊ×3¼{›â/á*NfIË6Òp8¶‘€Ï° ju»¨^Ås_8VÝ”þ(¼)¹§PÝNJ½œŒ“úß–¿S;9·¬wŽÌÁÝ0ê‚, f„¬o3DÉ||åÕªkM,¬ìµô±›øN»Æ®¢qÅ¥¤úIQÆŠ¦Í1·B´Ã]¡çþ1˜o›¬KKd« ÍíÅï÷¤ÔÓ[Ú/Â¥ò¨_u®ºµœ¯Å°‹@죆܉ Á¥¶ó­™QÆjT•TQůu—Öød®rù猪¥Ü¯ –(e1Õg"Q ½ý=ÈÚÔgÑS%”b–{6`y3N¬Ž¯›îKçܼÉV“¦&Ay‹XÊ’† i&ðxËû : ¾ô2”, vq·¦EÝ}uù’y½ýÏ”˜<˜V‹ð`*.Û´ÏD¢ÔEuW kKL%áÁØ'e'—¥:¯{3οN›9þYòT(“猭ü3¢†~µ~öåN}Ž€±bŽÑ²’×]àùö%Ë—º_‰hÒÅÂy…l]]ÔJg%#?¼m²–dãê»KóóEþ8³ãW§IÔvNïUS>2.ü.>™â8Ù(-[}ZÖ÷îÐ1H Ö"'/wÉ÷9527+mVµ ìõ¦¿{ßTkÎIÊG8ô“ûRu7ª×ÅÀg¥¾ôlyÕ­NíN5GN8Xmäz9å<XèS}‹ˆÔ(™øÛ·Ÿ2½h\ò *ì)K.<•\šË`²n«ˆGT­ûVf¶6!;mR>Â’=\AÖZJ—œãœV¬žT?hÖ§VåL”jñªüIéipS•ž9@ζ<¥ÈS²º ‘£V…ðø\½ÿìñûÏ¿÷-MI†:/”§?ýÛðàLV™\2KZã0þˆå£&åOûÜ'öÝM’UN ÚPpКÚ×ðùø«Þ`Ô‚—6æ³éX¿B5á:îrCoF4ƒ» ‹hîÑííäÄ«¨…­AŽÆÎ§Ê7_cµZfØr¸RhÖ½br­³òå“w°°u“dõ½}â.ÖýI)Ãxüvä¢Ð=Äà&á“Å Ž >;Ã`Ë9¸HH¹ÂÕM¢ò е§HÜ®å¡Ü|r8öˆÄßà©ç¸´âE¬qðp'>½Û FK_\êY©ï”RJ}y™mDíÍLÝÎìoç…N’³zãÕµ(2R¾W™”"©cšôêiNc$>ƒ¸ÊïÉÃîûÜšä’qXE»3ø¬)ð µÝ¨&ÏFo¸¯Çêßþ4©Ó^† ?¯D… ÌM… (n·¤ST‘-©2­Z$kq*³4V˜s&¹ë¾ Ï )ÚÜæ:¸ïžº¿‹¬9BÖze$¨éêpk8íÍMŽòÔ}‹™‚El:„<3ûÃð´³lý­|2éÌ3²ê•"6ªsäfp_©GÄ‘$ï–Èè´*Ü÷Ë 5µ¿²'8õDi÷f¬íç³­ &}-Zž‚ó¬ˆ%±JfY©*A¯¡Ïô_Åt—’™FlãòÎþwù˜6øÎí–Èš£ù¦j£Ó¥gÜO¦ W=ë9A÷z­9á:Ž6·ì÷UNù| ¿Ã ¤‘@^‹©¦ âGb[ßÿ‚²ieÃdyp´Pþ…ª®m2bÓZ–\á*_~Úß{­ƒ[â kI¸&È>lÝ­R/§ asa¨¦¯58YIÄW3ùfRÓ®L]1´·c"HNŽË€»§”ÑÕUØýÔ7ìÒךvw”X#שAF89\¥[ï’‘‡ ktgĺ̤ÝXMÊËDó’e´ët(lÑŠXX­_Qó´°[m+Ì ûí$,Bì[§›Ðs8³^ {¸;+j,‹%“¶§„¿ÏŒ¯OœœµS2ùz¦€}rk©Uß+cqïÏ&Qki\%v+ê˜øJcÒe0X Ö" R¶{‘[¯tE{$ßàóØ3nlÅ:o³ªÔ̿О@½«ˆ%Y>LšB~ˆÄ+ §¡WLÌAÓü ®õ:IÚ?¶×ó@ò‚š óãß^%ìQÈ:v­¹Uê¬Ô휑·ˆžÇrJ¯7½½”5yfRÝŒ®Š¯æM—íˆ×„Â"×) ä¼ä•/¼1}†%q0íº?ŽJúáÔ¦;ò^%ìQȪW¬ª¥~2Ú*e›+i‹%­VÝÔ±OžÊûØøª|¡V7ÇÚ ÀMv`°ª¥äÝrxZ»ãð&È­3U£«…$Æ…dÝG9h}=Úº¢sšjuÞõÏ´àŠW¾[»Bc¸ \ÆÝG²¬“ñiñ’ļö~BmðæÔg ‹#M²dö8"ÕŠOvyUt~õ×Jýt¦SÇwOörÕ ùÍÃ&á8­[ KòUH’„0Óf\[2Çä×ጟ±·)J±æ×Ú‹5wïïìøåc¡Y· ÚÕýC¥n 1zÏf±DFG›2¿Îõþ��nIDAT>$—¢þ1Ñ·\QH$Aƒ«iðw„Æ­ fu§p½êûk¥¾_éÞ‰_å,}m›æ0 o„Ü’$8ÞN?}Ë}fý2}eG¤e„„¦äÄžY•…‡²×YÙør*ñí¾0jšætô-}q˃Í©rùë¾¾î&˜YÕ Nu;¼šâ•ornýì‹Ĉ=¥Å7ÀÉ¡Üq²öת?OÞúcÜÒäëÞ¨þ]h´¹·ƒÏ?mU+b‹(%­ùÍ_Íž6¦^´Ê‹È]|¾ÿÊXBcÂÒÒÄÈ÷A­Jf=¡GAÖbL‘ï²hU©´$»/ L«lbαѮŠaVàðòQãVâ»ä£¾{°vOju™£@¤‚¬ÛNFÉÒù¢M¯m¿$ß‚÷u_guFæB°î_R<¶‰ËÈM’…7DW“Yeóukd¤‚!v kö§j¨]¬—nlªYÿö§ÉGÂÜÒ’¿QKtä2±ÝøúÔ-MbJyQkò’wr wTž¼tæ»ÕUÛÐ, „]:�جWBcT„$‚ ãHâêÒ_—Ä’.o’±úg0jµ¸®u݇ ëHD'<t‘³'b¯ý#È(|%vÄùJ Sßö¼‘/YýøP=–¢µÊl)e‚{"Ⱥ£×íE¼Þ\„ì›™ “ Qwr”™.å­€ÃàG›²L…‘«bƒ|5료8¦Zͧ2â dÕ 3 õô§›ûu)«ØéR! ¡PîR¹u=™¡Ô|.v¬±®ŠˆÆó¶8 ²àiîz&@MÇ™;„רq$€Á×£ VþÝ઒²®®²Ê¿}û)£zÒW3JИ¼^a…íÈß÷ý±;ÿ¡lÜGŽœðîQn~Ûøqå?E=>cø°é ÿ9ý³d{4+@  +@  +@ @ @ ˆ †]Üun @ ò°ŠÏ?ñlÖ)Õ)õ@©y?äAå“ÙëuéÔõ‡êêù‚,ùCþ.[¿Ï[ûôå »¿ë"þïìvzaÖ;»÷dƒ¨ +@  +@  +@  +@ @ @ @ ÈŠ@ ÈŠ@ ÈŠ@ ÈŠ@ dE dE dE ²"²"²"�Y(Ÿx^ï•ê•únÐ>âø[î)z¥þ^©¿ÇØÓŸ±ñ¿bßsdµÞF DãÑu];_ÝÅO&yÀ¨%ËD6@ ˆ’²"Ķ£©\cñ“I0jGÉÆòAV@  Y�Y�Y@€¬@¬Ÿà "9ÜUž]× ?,\´L7çd’Y‘E2h—´° ›s29"Œ@ ˆ”èû¾¥´í¬£…fE ÄÞ”tAʺ<v@hV@�«œ.'óÞ +@ €Õ…dE °J ²"ÑD ‚ @ Åœ•\k=«>tÎÉû Y‘…Òà+«œFþÉûJD6@ ˆ’²"²"²"²"ˆ‹©6øþøOþçÿSÿúßÿ'Ü@ ¢âþøO²Zo H׬ïÿïÿƽ@ "?º¾ïÿÙ¿øW¸@äÇÿø¯ÿåÿ¢ŽM×põã����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/mag.png�����������������������������������������������������������������������0000644�0001750�0001750�00000005066�11332353405�014672� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���†���ˆ���­¶���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ�æ ´�� ÃIDATxÚí¹nM…{ŒYð°/F`„H@2Ã#‘8"!e^€ !!1‰¹G##� $–a_löK÷ÿÜ®c÷H¿ÄtûÜ„«V¹º¦‹:§îVU{÷î]fé'ð'ð”X‘ÁÙÚí¶¿EMI–e­VËŸ£¿¦$˲Z­Öl6“í:NèÇŽ }zz:Ù¾Ñh„>11‘lSä]JÆÆÆB¿ÿþÿò^5†^ÇyêÔ©Ð=zz½^ýÓ§O¡ïÞ½;˲³g϶ÛíV«e.éïURðúß§Vÿ—±Ï"«Aõÿõë×Ї‡‡C¿zõj²=ǬÞËöÔ‹üv®Ú7oÞ$¿u®æ?~xÇåM°ÅSR.i6›ÄeµKQ»/â,Û³OÕO‘ѦM›’\¢„Ø]dœ;vìýîÝ»É>?žÜ5q<Û¶mKê_¾| ýû÷[·Î«ÄÀeñ”TÊ.á¾¾WEá5Ÿ8p`QN¢•Ûív“VzKûàÁƒÉ½?ù€ý?{ö¬'žcÚ%”/^$¹‡¿ñÞ½{^%.‹§¤:\Òét”ŸªWBñŠÅ=E<»lOÛ‚ØM¿û!Œ'ûäw ÒÞbÿÔÉy+÷»¼J \OI¹¹$G ÄM%½rŒò}­Zµ*‰ÅÄß“'O†NÛÐw¤¢äú¦h¯p<´ohÇ«èãø)ïß¿O>ç{½J \OIé¹$+–q¢Ú¨ögΜ }Ù²e¡?|ø0tÆ V¬XúöíÛCg¶û/Âäb:9cß¾}¡oÙ²%ôW¯^-Ú?…¶}†äѽ{÷&ùÌ«ÄÀeñ”TK(EüNó »?-_¾<¹÷'ÇìÙ³'ô$m)r }J³Ù…ódzÿþÐ׬Yóß7LöON"pÌ9›£'y•¸,ž’JqI‘x¸òe£_¾|™Äå©©©äßŽŽŽ†þáÇdò‡Ê»åÞŸã§}søðáä8‡††BòäI’Ÿ”_K}+•#—³ó¼J \OI¹¹D1QÉÌÌL£=:ã?þLb7íâ8±›6Ç·oß’XO×Ó§O“íoß¾äÚj*¾Âqò9mò\.?Í«ÄÀeñ””Þ.QµE*zÑçCÜ$'ßW®\™Ä_òý`ê¹ÊÁel†vý`lOÕºÌ3&çÑ÷¥âóªÖÒ«ÄÀeñ””žK&&&T½7yEÅÞU|[ù(ÄbâïúõëC_»vmèŒÁ(Þbüœ|À~h1ÎO[Šc NÅr”=W$§Ù«ÄÀeñ”TÁ.Qv†ÊßåþZÕŠ3§vλ}Îw­^½:ôß¿‡Îzò 6„^«Õ’ý|üø1iÓÇ $ß«ò}ùÝT.²W‰Ëâ)©—äÎP!¶*]á&±›¾ âòóçÏCßµkW茫ëi»Wè#ýùó'9òuU㢞+¡C~U>@ú¾¼J \OI鹤Ñh'z­$†RˆûÜó9}V###ÉçÄtÆEÈä->§Aì¦/‹¾/ò"Ç©N1¥/Kñ+Û0þÄL¯—ÅSRz.©×ëÄ;ú»Tî–Š‘gY“¡boß¾ }ëÖ­¡³Îƒvy‚XO¾áß’ É7ó¸Ø?Ÿ“ •Âw©ZE—ò*éûURF9}úôü‡çÏŸ÷”üK! es}ò¥Ÿ’n·[ä<vŠòá°–ðׯ_¡³Vƒ~-þíÆCg\„¸H–e—/_žUNœ8=·#aœƒmh£ø\ÕçSçß2oXñÊlLþܹsæo‚-K‡K¯*8%NG©NßNΔ!…NŸ’:k]õC›€¾,â8í‰ù|>ëÅâsòqŸvÛç¸*„õ(äÂ;wîäÞ>ßvQµŸ¹ÚøÒ¯’+W®¢Î2—X<%KÞ›Íf¯ü‘‹‡¨Ú Öp3§O‰±w· Oð½ÔÉI쇜GŸÏŠ'Çpü*™ß„:9ŒþÀ\¬Å«ÄÀeñ””›K†ªëVX™»0iClÞ¼9tÞeþùóç$¦³=9†:¹{Þ=E¬g{öCNb{>§Ÿï♌ 1f£âI|WίèUbà²xJÊÍ%ÓÓÓôãs¿ÌCu 1”\òúõëÐé;¢ŸŠ~-:Eøœûz¶á»èw"W±¾]å“i‹(¿m& óÙÈ»ä3Æ™r÷hy•¸,ž’rsÉðð°Š+Q8{ãÆÐY«È½<kMˆ³ôqQˆïlCü§j ‰ïü[޼È1ó÷’ÏÛ§ÏíÕù¹|0¯—ÅSRn.év»ê¾)âs…Õ]|®j¼‰¿Än'g{Æ6ø·ô•QÔ_´Wh—{Ôxh÷° Ï‚d¬þæÍ›¤íÐ}¯¢Ëâ)©—äø€¢jMÔT< ‹ØM @\fLžX¯xBå°Ú(ÔɃª…$ǨœcuN—ªëôy\.‹§¤R\²€‹8H¬ääŒÉÉÉÐ:”|7û¤ÿêñãÇ¡3–N\&¨zCö©â%ä?egW¨_¿~=ô"wô*žËq¡W‰Ëâ))7—ä’S¸Î$‰ƒê~U_Bßs¥ˆË, em<ãÞì_å«;QøœÜÃߢúg~°ÊG Ÿ¹^ì'w¾™W‰Ëâ))7—dúlyu?9cêü.Å=¤.â2y…öub7yEÕHrÌÌ ¦½B.Qu*´Ãø[È‹üíün—.]J~g¯—ÅSR5.a­ñŽØM»A¬|>Ìß%óœb7sˆ“`,]÷ÎØ ¹„ö q_ÝÙ®ÎÞWç9ª»LÔÝb¹ºw¯—ÅSRn.Q‡q-`sÐv!70†O›ƒ± îñ‰¿ä�Ö¦(¼¦¡îÈâ9`ªV_ÙO¹;tC[¢°^„<ÊÜhòm¯—ÅSR»DÅÛÕ™óÊ÷5ç°ž¶ßK9@7LîQy_Ä÷;w&í!r$s®ør5†‹Ú%´uÔÝ”^%.‹§¤ô\²ÀAèããã¡Ó'£îo?räHr¯rp‰¿ÄYæqñŒ,â;yˆ¼E?}e¬ù¸víZèÌ7»pᢟEÝAÉßË6Š?\_bà²xJªf—(Œ#¨8÷Ýôqñn+Æ<h7¨:GÞ±¨jÅ™+5::š´i8frýNŒÙäî§Jòí$ÚdêÎ+ÇK \OÉ’à’z½®béê¹’[·n%mÚjO!¯0Šø«Î £í˜D‘Zr›Ê=£¨ø|þÈõ9gJ.^¼ØÏÿ}âÒ•%´JÚí¶q£¿¦¤Õjù‹üs©ñà^K?È_ìx¿FSc����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/thread.xml��������������������������������������������������������������������0000644�0001750�0001750�00000023030�11224464026�015402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="us-ascii" ?> <!DOCTYPE thread> <thread> <info> <name>gui</name> <version>June 2009</version> <title> <long>Introduction to the ds9 Interface</long> </title> <history> <entry day="6" month="July" year="9" who="liz"> Original version </entry> </history> </info> <text> <overview> <synopsis> <p> This thread provides an overview of the key components of the ds9 graphical user interface (GUI). </p> </synopsis> </overview> <sectionlist> <section id="gui"> <title>The ds9 Interface</title> <p> This thread uses Chandra data from an observation of the Trapezium Cluster (ObsID 1522). The default ds9 GUI is shown in <figlink id="components"/>. The main components are numbered: </p> <list type="1"> <li>Menu bar</li> <li>Information panel</li> <li>Panner</li> <li>Magnifier</li> <li>Buttons</li> <li>Display frame</li> <li>Colorbar</li> </list> <figure id="components"> <title>The ds9 GUI</title> <description>The default ds9 display includes the information panel, panner, magnifier, and colorbar.</description> <bitmap format="png">components.png</bitmap> </figure> <p> The default setup is a "horizontal layout", with the information panel, panner, magnifier, and buttons displayed horizontally across the window. This may be changed to "vertical layout" in the View menu (<figlink id="vertical"/>). </p> <figure id="vertical"> <title>The ds9 GUI, vertical layout</title> <description>In the vertical layout, the information panel, panner, magnifier, and buttons are displayed vertically at the left of the data frame.</description> <bitmap format="png">vertical.png</bitmap> </figure> <p> Note that the colorbar remained horizontal at the bottom of the display frame. This may be changed with the "vertical colorbar" option in the "View" menu. </p> <subsectionlist type="1"> <subsection id="gui.menu"> <title>Menu bar</title> <p> The menu bar provides access to all of ds9's capabilities. For a complete description of each menu, refer to the <a href="../../ref/gui.html">Menu bar section of the Reference Manual</a>. </p> <figure id="menu"> <title>Menu bar</title> <description>The menu bar of the ds9 GUI.</description> <bitmap format="png">menu.png</bitmap> </figure> <p> All ds9 menus can be "torn off" to be a separate window from the main GUI. To tear off a menu, select the dashed line, which is the first item of each menu (shown in <figlink id="menutear"/>). The menu will become its own window. </p> <figure id="menutear"> <title>Tearing off a Menu</title> <description>The dashed line at the top of the "View" menu is highlighted.</description> <bitmap format="png">menutear.png</bitmap> </figure> </subsection> <subsection id="gui.info"> <title>Information panel</title> <p> The information panel displays information about the data file and the values at the cursor position. In <figlink id="info"/>, the object name has been loaded from the header of the data file. The image value and position (in WCS, physical, and image coordinates) are updated in real time as the cursor is moved. </p> <p> The fields of the information panel can be customized from the "View" menu. Any of the default entries can be removed, and additional fields can be added (e.g. detector coordinates, min/max data values). </p> <figure id="info"> <title>Information panel</title> <description>The information panel of the ds9 GUI.</description> <bitmap format="png">info.png</bitmap> </figure> </subsection> <subsection id="gui.pan"> <title>Panner</title> <p> The panner allows the user to view areas of the frame which are outside of the current field of view. Although the display frame is filled by the data, the panner indicates that more of the image is available. Clicking and dragging the viewing bounding box in the panner - shown in blue in <figlink id="panner"/> - will display a different portion of the image. </p> <p> The panner also contains axes to indicate the directions of North and East and the directions of the physical (x,y) data axes. </p> <figure id="panner"> <title>Panner</title> <description>The panner of the ds9 GUI.</description> <bitmap format="png">panner.png</bitmap> </figure> </subsection> <subsection id="gui.mag"> <title>Magnifier</title> <p> The magnifier displays a magnified view of the current cursor location. The magnifier cursor - the small square in the center of <figlink id="mag"/> - outlines the size and orientation of one pixel, taking into account the current frame zoom and orientation. </p> <figure id="mag"> <title>Magnifier</title> <description>The magnifier of the ds9 GUI.</description> <bitmap format="png">mag.png</bitmap> </figure> </subsection> <subsection id="gui.buttons"> <title>Buttons</title> <p> The button bar duplicates many of the options available from the menu bar. The buttons provide quick access to change the most frequently-used ds9 actions (e.g. changing the scale and color bar, blinking and tiling frames). </p> <p> When a category is chosen from the top row, the options within that category are displayed in the bottom row of buttons. In <figlink id="button"/>, the color category is chosen and the bottom row shows the ten most-used colormap options (additional colormaps are available from the "Color" menu). </p> <figure id="button"> <title>Buttons</title> <description>The buttons of the ds9 GUI.</description> <bitmap format="png">button.png</bitmap> </figure> </subsection> <subsection id="gui.frame"> <title>Display frame</title> <p> The display frame is the area of ds9 where the FITS image is shown. In <figlink id="components"/>, a single frame is shown. </p> <p> Multiple frames can be opened in ds9 at the same time. In <figlink id="frame"/>, nine frames have been opened and set to "tile" display from the "frame" button. The current frame is indicated by a blue outline around it (second row, center frame). How the frames are tiled is set in the "Frame &#8594; Frame Parameters &#8594; Tile" menu; the default is to tile the frames in a grid. </p> <figure id="frame"> <title>Tiled frame display</title> <description>Nine frames in the ds9 GUI.</description> <bitmap format="png">frame.png</bitmap> </figure> <p> If the display is set back to "single", then the current frame fills the display area. The other frames can be accessed via the "previous" and "next" options in the buttons bar (or from the "Frame" menu). </p> <p> The "blink" option may also be used with multiple frames. When blink is turned on, ds9 cycles through all the available frames. The blink interval is set in the "Frame &#8594; Frame Parameters &#8594; Blink Interval" menu. </p> </subsection> <subsection id="gui.color"> <title>Colorbar</title> <p> The colorbar displays the colormap, bias, and contrast settings. The colormap correlates the colors used in the image with the pixel values in the data. </p> <p> To change the colormap, use the "Color" menu or button. The contrast and bias can be adjusted by right-clicking and dragging on the ds9 display. The "Color &#8594; Colormap Parameters" dialog box can also be used to change contrast and bias. </p> <figure id="color"> <title>Colorbar</title> <description>The colorbar of the ds9 GUI.</description> <bitmap format="png">color.png</bitmap> </figure> </subsection> </subsectionlist> </section> <section id="preferences"> <title>Setting and Saving View Preferences</title> <p> All of the view options described in this thread can be set and saved as a preference. Open the "Preferences" dialog box from the "Edit" menu and select the "View" tab, shown in <figlink id="prefs"/>. </p> <figure id="prefs"> <title>Preferences dialog box</title> <description>The view tab is selected in the preferences dialog.</description> <bitmap format="png">prefs.png</bitmap> </figure> <p> The "Default" menus are used to set the defaults of the "View" menu and buttons. For instance, uncheck the "Panner" item under "Menu" and the panner won't be displayed when ds9 is launched. (Note that some options require ds9 to be restarted before they take effect.) </p> <p> After setting the desired preferences, select "Save". User preferences are stored in <tt>.ds9.prf</tt>. At startup, ds9 looks for the preferences file in the following directory order: <tt>./</tt>, <tt>$HOME</tt>, <tt>/usr/local/lib</tt>, <tt>/opt/local/lib</tt>. </p> </section> </sectionlist> </text> </thread> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/menutear.png������������������������������������������������������������������0000644�0001750�0001750�00000567126�11332353405�015760� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��4��—���aG���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ9¹<�� �IDATxÚìw@GÛÀgËõW€£÷r"¨(b‰]cAc/1±F}£F£ ’¦)¾æKˆÑ¨ILì¾Q,±#ˆ‚HÑ‘ÞËõº»ß«›ó@clÙßÊíÎìÎÌîÎ3Ï3Ï<mÛ¶ÍÃÃ#-=Édûùû!ZXXˆãxPP§§çùóçM&“··7‡Ã¹téRmm­««k@@�›ÅÊËϯ­­•J¥Ýär¥J•——‡¢¨P(¬¯¯··· $"??ŸÀq?77·“'Or8yPÏÏÏÏ7~~~ _Ïɾ¾¾žžž�çåå•––ŠD¢=z…ÂÚÚÚôôt¡PàààX[Sc±XÜÜ݃‚‚òóó+**œe˜«­«“J¥AAA ……·‚ƒƒ]]]���Î;WSSãêêÚM.Çp<??¿©©ÉÉÉ)$8¸º¦&?/ÏÎÞ>,,ÌÓÓ‚`�ÀåË—‹ŠŠ¨2ÔÕÕ¥¥¥ ??? à ˜Lf`` J©¼UT¬àóx=ÂÃý|}©”Ê̬̚šGÇÐÐÊŠ EAX,–Ëå�€ììl­FC�Àf³{öì)“É´Zmöµk&³Ç0­NÇb±|}}ƒx<� ºº:%%EQÿªªª¦ÆFg—�ÿ;ee•••.ÎÎÝ‚ƒ++* Ba÷îÝù|¾B¡())¹¯x|^HHè•+ ÓÛÛÛÓÓ“ËåóùüîÝ»³X¬¼¼¼úúz ÃÈ,R‰¤ °Ðú1Õ×7äåå©ÕjêÊ(Šzx¸‡†v‰D�€ªªª”äd³ÅÂb±‚‚‚‚‚‚8™òôéÓ õÎÎÎ!!¡"‘èÆyyy"‘(((ÈËË«´´´²²R¥RiµZAÂ#"üýýFã•+WZ[[!Òét€ ÜÜÜ‚äA‰†áòòò¤¤$��—ˑ˻ùûû³Ùlò^¿ýö›Z­–Éd†ÕÖÖòù<@ØÜ܌㘷·AäS€a8//Ïh4øûû§¦¦¶¶¶ÚÛÛ;::º¹¹Ý¼y³ª²R&“…„†þqþ<“Å 4………±8´{÷šššââb‹ÅBÞW „††z{{3 �€N§;~ü8ãb‰„Åd�  9{ö,†a~~~<ïÚµkB¡Ð×××ÕÕµ²²2''ÇqªyÙlv€¿¿J¥ª¨¬”J¥þ~~••U••‰$H.×ëõyyyA„……¹ºº¦§§×ÔÔðù|ggg‘HD5 Í3ŽPÀCÚ¶m›«›ûñ³©UJŒnš§Ë¼É#ûõ A-¬àN­…ïÕ;Œnš§ËÞ“`8†š1,ùš¢ïÐñM­*ºQhhhhhž.·ÿÛ}õôô×Êq3èut£ÐÐÐм¨`‹Ù¨Çñ‡Ïà@�BYl“Õµ\„29 &�€YÌf£¡“¹LÊdRGÈ©V4 �€TÃŒ=uNÓP!@M<ÇhÁ5%Ù\ŽÀqLÛŒëš-,{®½#ýÔihhhže7êµl&"¸ç—Ô8†5µ4²yB† : —ÅàqîPƒY°æ–_ ȨÓðØ,‡õÐ\‹¥¥µ‘ÃÀJ�€’n`AXûÁ ŽEU=(z°J£KÏ+Õé™(˺>aÒsMõ­z-àH­3ÒÐÐÐÐ<ƒ˜M6qtp ÝG*É njU!(ƒËf8H¥É…ã8€¡¥AQ‡å •¢(ÚA H©Ö±¸ü»w��… è®Gþ��€-qcnþ@?O)çFU Áô‚a„’M@yf@8ß…Ë·³ÎHCCCCó À`0˜VÖ³Ž#—Ëmli�0; A.‡ÓÒª"‚ÅdvFž�åp8­* %JÈÿÐ{‚"÷ÜûØöÎ7ª:Íu>ŸÇ'Ôª–®Ô��B[[âÆGJZ€ÈÍ‚áV‚ @���àÑöNV‡ï§$ u†!›+<yœ¥v“‡F°YŒÃç³J«›:¨2hS_š§,œ ²îaž‚ ‚`†©\0 =@g"þº ÃdFë\í‰�*|ï^V’ -­-äŸ6…†”ïp«äªª%ÜD¨ ›#tзV;2uÕF§À¾ÔSÈã îé? Â_Ècë æúVu¡”f•ž,èȾÝ& ‰`1ÑïŽ\¸œWŠá ANáàž=å|.K«7]+(?•–߬Ôy9KÖ¼6²´ºñ—Ó—«”÷Äê“A`.›…‹^Õ„™M(“uÿƒ2‰ÝȨnaþ® )­jÚwöjuƒ’þ$hhhžéA0€àN§¿'`¬rÅÎÍe·£Emùñ÷f‘D�‚ 2#��€UjôÛþ©Ñ�cÚðžžN8©6XîÞ ¶œ¨u·sm#i&[àÜT˜•�fÆÍ®¡¶\­sèßÎCP°¯Ë˜þ¡5õMY¹ŠxÈŒê& g"ClÇ÷v•Â0„ãx¨§$#·@L±=êðž!>ÎEwª²êš<œ÷ tñ¶H& f2è4Êf‰/²6«u| ‚@‹Jý€c±àJÁh�È$B‹ ÃÃUZ½JcÀpœÉ@ìù,&ª3˜ b H“R«ÕQ¶p\AZ½©Y¥5[îs/a3Nb C|.†!€�öBž=Ÿƒ 0†áQo2”÷óý#ýzC³rò¨þsFG~ùë9FÛ<ihhž ÙÔeÍ ÷ë[Aܺ]n“ÒÍÙ±òöMŽÔF»©ïלª”žÎâׯö=p.ËlÁÆô ôtª¨®»]ãà|¯\ð_2��”´º‘êXÛò±xb{¨úN0ë´-5(®· Lž[Êdw¨d |‹Á@³oŸOÏÑ1³3Œl¡B©½·‹´øN•ÈŽß]îÃ;ý§‡=%áî¹·¿ûõDeƒÊÃUöî¼ an"ãw•%‚ˆØ}pdpZn‰«ƒ½½€wUQFàD�W Ž9íÚ­J FÌÑÛŽÇd 0“Á¼UÑpúR~M“º—Üsü€P&¾SÝä 2Pø×Ó—ón×y9è#w°ç8¦6`§ÓnäWÝÓ5ÃÃýÆö5Õ*‘€«T*�<6k °gN‡ °¬îRn‰ÄŽg0š’Ó³ËëÕ#ôtq°wsJêt” ÍS5ëÁP§5'21i×£rY0|ÝgÛyÂûü·W/šje¼÷/ü×TÑž“³Gõöu“¾2¸‡R£õu)*­øz×A3Â0LN*µcÖ#Í€ÐýsNVÆ=˜-ë¸öº&-Ê@¹  A";iÇ5Ä ¢¦IUY×2024ÀÏ»®Y]ZÕxõæ½c3Îb‘{:9Mæ(Ò7¬G çŸ7k]ìaªªm¬mÖ %2µ…YÛ¬qw–x9‹ *›m®Ï�–3©Wgâ™qýVÆõ‚þ½ºÉ=Ä7K*´((«»}»†‘~ò¾a·n—ë †á‘A;îGÏ1Œ‰#¢U­^ÓÊeB#úù¹INÕê3ƾ4¼·yU]«#[ÇA$Bà–ÿ¹èè ôtT*�@&µëîïªT©O¥\`D£Ó7Ô75¶¨‚½†÷ï©6ö¾Åb–ØñåMžði™"ihhhþ60 Á֜ȩ&&e%4”éê+¿Ï¼ÄáÝMSšÖ]¡F&0cøáäœñBä^N�€›E¥»ö'ªMÀÅ;´À‘÷¢ÄÊ]‡ˆ»šÚ5Óá˜Ù¤nÀŒÀàrÙ0 pÈØjÒ«ÙIÇ+­iÙ÷{†§#ÏYjâëê"5§T$äx8*Uš;•uuJCd˜|Pd÷ä¬bJDL”Á‚À0YH‹Éhsñ³3³oU¾üR$äËÙ€»x ¸,Ül�€Ý¬Ôz¹:ñ¸Ëb ”p²ç¸¬ú¦–ã\vu÷è&·ã±8Øó%v<N;�£�@b!G*`4ªô �ÈÍIÄa3o•O¾,ï!÷'  ÒèkZD¼ðn~J­AQRi°€K¹%³Q&ðŒ¦º†f‰½�³Xp‹�¨( Í“N�êJ_tצGŠ4«\m…Ùy“Š|ofëþ{�P3&f³…o/EÅܿޒ÷ºÿ²è=¸vl‘›ÔMêêB„c'vu55”¨Õ-8Ž+ï\gÈ Œ¯®‚�“Ö4«oÝásCûÆ Šp¹”-õw÷ss�86nh„0¸l¦»ÌÑžSÝЊ„³£ØMæÐj‚Åg‰†@IY5`p¿ã›R­aq…pÌ¢5˜øv"R\ã˜ÅËU4á¥03_¹® —Äaœ A™,6ߎr‹$@�€a¸à :ÃiYj­®¶¾Ñb&,6A��€P&›Å@÷œé›Õº#ÉÙ<H&±‹ìèë.Sê/—×)ëZØ�öö«cMfKEM€ 7}š§� YÏ=<ù]IÓÎLU»ù˦SÓNw“1P$f@ˆÜË© ¸¬E©Šê*´—û3¿Y¥£.xß] ÈFs²½f4êj0‚=B9vKWžÍÀ ¨¹EW[(ôèþ zÂ0äå4¤§_M£R§7ú»;0P´²¶ÆL~nR. ­oÖrØ,�@«Rí$µï˜šS–W\%÷õ˜7‘Yתwu¹Hír nß(* ²±ŠÁwWh�‚`º—BbÇsñ‹îTÝ®¬suv"=Ö«ê[ZTZ?wÇ…SF²¸|w™¸±©�PÓ¤ªkR9Ú;#ÚªÓ‰…<©˜C µ0‚‘šlE}«Î`ôv—}©—›«›‹ƒÝ iîëîçÞÔÔ¤1`�‚9LÂŒAîOgµVçí,vq”^ξYRQ˱w$ô§ACCóT5'ÈÚt6é¥P^{~w'Ҥ̰òk°©j3­›9'†­æœ¦ ÷w“––W¿÷,H$u òtœ<8ì׳ÙZƒ Póa÷÷“(xМA˜ŠøLÈ ’óÅ2F„2¤f‹aeS×ÁëA ¡ÒõC7/G—k²˜S¯ä?—&I»û:×44ÿz<)¯¨A7ÙŠ¹¢zÈKÎ>x.+:Ä­g7O™Vo8ûçÕC§.`eqÚ™³� ¶+‰ îÔåUx8ÐKk°X0� Òê]È™:,|@¯nŠ’ÊÒŠ>‡E„Vo<–š«Ójz…ø÷c²”mf~‘F«E|F jÕ÷Íœ:$lÂÐ>•u- -JJ:º;ÙG‡y³™ ­Þ”–«(¾Õ«G@w©ß‚YΧ]ûåØÄ@™lF:? ICCCó™õ +¯lO™ÈŽ×Ž_[CY!8# ¸§ÿXûr#(²åý%L6×:‹½€sWºëwÝs@¿›ËK&ªmhÚ’°W#.ÎÒé âë"©*γs ´rî»_^¿veÕ–½‘ƒÇÖ5Y/Ê!ŒMe¢¡L…ˆ½Â(sŽYðú!"@àõJC-.e ¤2Wš´­ºÖF3c˜à ˜ÉˆX(ÜRWa²`¡„ÁdÃ0„�¼µ¾ÒŒÃ/€›Ì:•Ù ·`œ€`—/”0Ù\”0×U”)•yèZëZš›ìe^"‘¨®¬ÐŒöŽ®(”Õ¶wtc¢°ª±Êd4 (“Á`hTJ¦@$söÐkZtÊ&‘»æé&“yÇ᳕-&žPdÖ*M:•Ù¨Ã0œ€`„Åã‹™,6ÙR ´ÍÕF­Ê‚cL&Ûb6Yp ”º²Y UcµÅlÀ10ƒ#Š0ƒF§nÂÌfŒ�“dz“0X”Á¤? š§‹É çsPGÇ»¡PÙLôÖµ?ÛŽïõzƒ_~(ƒ©×ë+*kP&KÀe98ÜíçY äVö¥¶×é ýaÕjuU5uʰp%1y–‰@…Ù— Ç#°;iˆÉ@*oå65Ôõ~ ‚ FSS×ÈáÛÝÕmšëËo\Aß\¶‚ëÑÓf“IÝ,…•U͸È;²ò„†Q& Ôb-~î,N‹©VÕbä2ؼ¶e%�€™<¦= ‚RÑAL@l{F”É`² Æ,fŽØEÀdÃа8�fÁ ¾+u™L6Œ2Ì&‚+uCQ¡€m'u—À0bÂ�Û^ÆCP„Á$À»@0# €2™|G¦‚`˜À1{¾‚‘Á½¼Å ->îŽR‘ðÌÅ«¥•ul¡!L¾ˆ€_ ß“ù(ƒÝsÇ �Ä8 .A€˜ÈŠÀ(ƒ/aA@ÈÌ0Œ2 Ÿ3`!W<3L¥% Í3 9Ý?çd4cž¡QkZ”Då2Yp¯‡ä¢Œ{å2ãÀ',Ú:™Ù‚;ù„8ùü•ë>D®sš0~ìÙë5àþ9.³Q[­l×Pµ ŽÄdsokŒu7ªMF£Ñ‚\=“Ão·”(“eFáÞñû<ýPS ú+®yÛ;�,6ƒuWe²þREùöémLÎ_š&×Î6ŒzU£FfÇvs67·$¥e¥\Î!`Êd“.Œ}Ím}÷ûJng번  &‡G444ÏžpB,nÁ°Îc%Âh2ÁÈÇ-Ž¢H§r™Í0‚@0bÆ0 Çäá¹p7š,0‚ÚÆÖc0PÐfÎIàè €÷ƒ®ÅH,@Ày~Œ¢¬ñrV®VÙLŒ L6Ç·c0ÙE³¥¡¡¡yqa0Xzƒ¶±±™ËíÄ–8ÞÐØÂæ ÖéµMMÍœÎl™aMÍ­l®�‚ ­N 7µ°ÙÚ2£¹UÅæòmáæää`ÿopwæÛKÙ<!twA2„ h»Z Í ¨9!‹ÃÓ ZÃÃc~B�bó„Š�X\žÎhÐè;‘ ‚Ø<!‚¹øZƒA­3t.—�iI}gŲ›�Ó?˜Åü?ki„ãnÂèW–††æßŒ 0Ò)sŽ[p“¥Ë¹0 Ž=z.e"(zwΩªºæ®Ff±ôðq p¡Ÿ Í“çRî¢Õ]Í)~Óç,×��ÇÜ„ýºûÐ DCCCCó„Q(êæZ‚¸;¹…®]õöWû.X§Ðét‹å¨*ƒÁàpžŽÓ†Z­&èÍihhh:GYYYZZšF äžprssµIDŽã/@m)ñð$å†a>|x'·(¦¡¡¡¡1 z½€¿–â /ü�_¯×Æ'v»3gÎÔ××Ój Í߀îFihhhhž1áDñihhhhž=͉–M44444ÏœæDK'šgM8±é@¥44444Ï(Ú•=bcc³³³m.X° ¸¸8%%eÇŽ®®®§4§OŸþú믩Ÿ‚$&&R?üñÇlذaçÎÕÕÕ¿ýöÛ7V¯^=a„E‹uþ.×®][·nÝ´iÓ^{í5òÈk¯½ÖÐÐ��ˆŒŒüè£þÑŸ8q¢µ÷àâÅ‹Çÿ´RRÒçŸn}䨱cUUUo¾ùæˆ#–/_þw.þæ›oÞ¹sÇúÈüùó'Mšô„ë8}út•êîšó˜˜˜7Þx£3¹4ÍÔ©SÃÃÃãããÿ~0 7nù÷øñã/^l“ ??ÿÝwß8qâÂ… cÝùå—_~ù…úéààðã?v2ï{ï½—““säȑǻX°±±qΜ9QQQqqq?ýôÓþýûׯ_ß³gÏéÓ§s8œÝ»w“/áöíÛÉôÛ·owww¯ªª²n™µk×8ðîþöÛo:uª«ÞÁƒù|~gÒoß¾ýرcŸþy·nÝ^H™QWW7wîÜþýû¿ÿþû�€Ï?ÿ<))‰|L6)7oÞ|áÂ…~øÁÙÙùQ„S—Rß¼y3==ýÂ… €:(‹OŸ>žžn0þ~µÓÓÓãââ&NœØölyyyzzºR©Œ5›Í��µZžžÞ£G.ÝE©T¦§§GEýµ+IVV–^¯?þ<—Ëý§mFF†³³óáÇɟ‰ä)¾g ééé«W¯ž1c�`ìØ±#FŒ8sæÌ7ß|cýˆØØX“ÉDþ}öìÙµk׎5ê WpÚ´i©©©iii�€óçÏoذÅb½þúë'ééé,ë±cøðáµµµ'Ožüã?Ö¯_Ïb±æÎk@¥R¥§§GDD<ÞêWTT¤§§oÛ¶­ÿþ†EEE½öÚk”OÿùÏ Ããj “É”žž.‹©âµ¶¶�®^½JöþçÏŸçwfÍšõúë¯/^¼øå—_NJJ5j”““ÓŽ;��_~ùåÂ… ÷íÛ×ÕæZ±bÅŒFãÈ‘#Ïœ9Ó¥NÃ:‡sòäÉ#FŒx´îø¹Àh4¦§§S›§§§ëõú¶)oݺõwä£lîéééííííí››½oß>êTUU•›››\.÷óóûàƒm‘T*õ¾Žã©©©žžžqqqÔÕfÏž=xðàŠŠŠÙ³g�~úé§]»vuþúƒ Úºuë¶mÛÈaÚØ±c«««“’’¢££W­Ze2™6nÜèëë+—ËÝÝÝ‹‹‹kjj\\\æÍ›GŽ\\\’““�ÁÁÁ}úôy„ 2™Lª‚Ÿ}ö™‹‹Ë… zõê’‘‘ááá!—Ë}||¶oßn6›G]TT$—ËfÍšµ{÷n¹\îå啘˜ˆaXss3Õà«W¯~´‹ÅdaP-///))‰ŽŽÞ¸qãÿû_—#GŽLš4ÉÕÕU©Tvé²®®®ÞÞÞžžž¥¥¥ëׯÿÏþ3oÞ¼E‹ùûûËårµZm±XöîÝëíí-—Ë===“’’pïѣǵk×är¹¯¯ïG}G>‹‚‚‚®VM©T!‰\]]a6 :î•W^ ”ËåQQQÆl6õÕW>>>r¹ÜÃÃ#77—òb5™L[¶l¡Þ‡›7ovµ Æ ËÏÏ¿víš··÷ܹs ¦L™²dɲ|}}Õj5•X¯×/\¸<¨V«ÿüóO—>ø`Íš5...W¯^íjœœœÈçk±Xª««Ífó·ß~KU633Çñüü|ww÷eË–mÛ¶ÍÅÅåèѣ˖-‹ŽŽÖjµ×¯_§ÞÉmÛ¶™Íæ &¸¸¸N™2E§Óu¡ÇávU‚„BáÕ«WgÍš5qâĸ¸8ooïÄÄÄ+W®ðx<¥RÉ`0D"‘L&srr2™L]b£×ë+++ûí·êêê²²2FsöìY—O?ýtÍš58Žß¼yÓÝÝ|.[¶l¡FWz½ÞÅÅ…4òÉ'...éééjµÚÏÏ|Ÿ/^l0¶nÝ——§R©¼¼¼ÈSK—.ýûc÷gœÚÚZª/еî‹|}} pîÜ9??¿?ü°“ÝÔ£§[·n”——c¦×ë­ß’>}ú¸ºº*Šøøø¯¿þšìý¡’………555111 Û¿?%º ƒ»»ûÞ½{�sæÌ!%Gç?ƒa±XÈÑÑh$‚Åbéõz“É´ÿþ-[¶ÄÅÅ) __ß>}ú âèèØÔÔTWWg±Xôz=Žã¥¥¥:îÑ̘F£‘¬`CCƒÙlÖëõ&L��‚åË—Ož<Y¡P,Y²díÚµçÏŸ7‘‘‘ …âÀ§NÊËËS(ãÇŸ3gŽB¡èÓ§X,V(_~ùåÎ;¿ýöÛG(O}}=Y³Ùìçç‡ã8ÙdÙ>üðÃõë×ÛÛÛ?‚$&"%%eöìÙ¯¿þúǼeË–C‡íÚµK¡P †¡C‡¦§§/[¶Œ¬ËСC'MšT^^^WW·téR…B±~ýúÿþ÷¿žžž …"(((**ªóX’ßÿ½GÆ 3fŒÏåË—/^¼råÊäääÄÄÄk×®�Þ}÷ÝäääƒÆÇÇ+ŠÐÐÐAƒQ]ÉÑ£G7nܸfÍ…B!—Ë£££I­½K�Àf³IK5‡ÃùòË/÷ïß¿cÇ…BaØ Aƒ¨Ä7n<|øðž={ …V«6lù8¾þúëcÇŽyzz>‚*SYYI~M ÃÓÓóÌ™3±±±d ÷êÕkøðáõõõ  ™0aÂ7ß|£×ë1 3™Lz½^«Õ<¸G …bùòå~øá‰'ŒF£^¯óÍ7ûí·óçϯ^½ºó…‘ÉdÇŽS«ÕuuuÔÁÒÒR†/^¼ˆã¸ÉdBQ”ÜÉdr8.—{éÒ¥ÖÖVrø8yò䜜œÈÈÈ®êñçÏŸg±X§®®nüøñd÷µk×®þýû÷íÛwÔ¨QõõõóçÏ5j”B¡X³fÍÆ=JÉNggçÖÖÖêêêæææºº:‘HÄf³l0N:µoß¾œœœ~øê" ��8uêÔÏ?ÿœ••ÕyƒêsZ­&; jÌÚ§O™L¦P(6mÚôí·ßîܹÓzdPTT”˜˜¸aÆmÛ¶u²)ÐG(Ö'Ÿ|‚¢h·Ü+o�� �IDATnÝzöìÙö¬N§KIIQ(\í£G¦§§“RdÛ¶m”²LvÁ¥ee2™·÷_»)Z›ø(œ’’¢Ñh��ŽŽŽ»ví:tè–-[D¢»{ì¾úê«:Žzw»* Þ{ï=��5±ÿ~F“™™™’’RZZÚÉ« †”””7n<rk$&&’S‰---mÅÛæÍ›Ùzn4'MšÔ·oß 6<­¯è÷߯¯¯Ÿ>}zTTÔØ±c­ç8ù¦�äryIIIJJ ie²¡¨¨(%%…š»zòxxxÄÇÇ;öòîÙ³'111--ÍÑÑqçÎ'Nœ��ܾ};%%¥¥¥Å:åСC—/_NÎ%<”ãÇwþ-µ!55ÕækêX/wwwOOO¿xñâŠ+~ýõ×wÞygéÒ¥ööö]½oVV–Í-Z4nܸŸþ�€¢hrròåË—SRRŠŠŠ¬“±ÙìÇGDDÄÅÅEDDüúë¯;vìïÓ§Oyyùøñã¿þúë]»vÉåròÓ�ôíÛ·ªªjâĉ[·nݽ{wPPЋ$œòòòÈšZwõz½þA¿··÷¶mÛ(£SÂ)¹¹Ë¦’½{÷ÚÙÙ‘R¤íY•JuàÀ�ÀôéÓ¡Úo¾ùæœ9s(;á?ѲC† ™={vff&ŸÏojjJLL´ÙN833³¥¥¥wïÞ] uww÷ÿýïäßkÖ¬�lÚ´ÉÁÁÁh4~÷Ýw»ví4hPç…N§£üѤÈüùóÉ)ú°°°ùóç?~üqÕôرc|>ذaOë:}ú´Z­ž:uêŽ;Þ~ûí'NôêÕ«m²²²²O>ù¤´´400t±!;;[£Ñ„‡‡‡‡‡Ã0üä+2qâÄG“L�€uëÖ1âÝwß=|øð¹sç¨Îð      &“ù$ë"‹ PTT5}úôÂÂÂÖÖÖ˜˜˜¥·X,‡vtt2dȦM›Ö­[÷Å_ 2¤_¿~¼ã7Š‹‹ •••••sýúõ‹/¶Uôøá‡­[·6ÌF8�ø|þСCËËË!êÑ£‡§§'�€T4,X0qâÄ>}úlÞ¼™J¿}ûvF³hÑ¢‰'öë×ïÓO?íÞ½û #œúõë·gÏ�ÀâÅ‹Éþ‡T§¨¾(((ˆ´L<2ðÖòó·Ð2™,!!á?ÿùO@@À# mDNNΕ+WtöâÅ‹]ˆŒŒ,((X²dIŸ>}ÚNþÏœ93!!aÀ€¤Õ~üøñ999‚¬X±âÚµk×±Š|´ñññ!!! ”sWg>õ„„„•+WóÌÏ?ÿüóªU«Þ}÷ÝwÞyçi•!>>~Ù²e¤Õ»íó"§š:tõêÕ£GNš4)!!Áßß¿íu¦Nš0hР€€€®î={öl‹õÃ?ØW_}õóFŸO?ý´¥¥å³Ï>#ÆÄÄ$$$ >< €··nݺpáÂ?]//¯7Þx#55EÑ„„„¤¤¤ªªªM›6�\\\ÆŒ“™™ �8räÈW_}¥V«—,YBZM† öcS§N]¼xqÉ’% ›6m*++KHH°I†aغuë¼½½¦NjsÖÁÁaåÊ•™™™ä,lïÞ½I­t÷îÝÿýï'M𔑑A :�»víÚ»wïW_}5qâÄ´´4kÇãGGÇ„„„åË—Pj1ISSÓ‘#Gºt5ôñ.66ö³Ï>[³fMQQAÇ„‹9r„Ô`Ž}ë­·Nž<yòäɶq¾½¼¼fÍšõçŸÚÛÛ¿òÊ+]ºKÿþý{÷î““3þ|¡PH—###‡~ôèQ…BqôèÑ%K–��\]]§N:{öì‘#G®]»vòäÉuuu+W®|¼­Ççó—/_~äÈ‘5kÖˆD¢¾}ûþøã•••7x\\Üš5kJKKÉéG3ë‘ö™–––ÇèIŸ@ÎB“Ú!�@"‘„‡‡ÿý÷¤eiÕªU¾¾¾Ó§O¿páš5krrr–,YòxåëòåËW®\IàöíÛÑÑÑ/½ôR÷îݳ²²¾øâ —˜˜øå—_Êåò1cÆœ<y²¼¼|äÈ‘………”õ/""bÔ¨QÇŽ+))9v옗]gxã7X,V\\Ü­[·ÈÇ£×ëwîÜyúôi ÃÞ}÷]*ñ˜1cþüóÏíÛ·?~‚ B®‡„„ÄÄÄüþûïuuu§Nš2e “É\³f ¹TÃF‹b±X«V­úõ×_É4nܸ°°°®wswwÿä“O>þøãuëÖ………<yrúôé,kõêÕ{÷î%ŸczzúÌ™3­Íò †×®]»{÷î5kÖØÙÙ <øÀÖ*”··÷Ì™3ýõWkËp\\\YY™Á`ˆˆˆ=zôo¿ýFúàƒJKK C¯^½FŒñbK¦ØØXrv¶¸¸Øb±ØŒ!`®¬¬LII<xp'U^H¾‰ë1FŸ¡ãkZÆEÄ ê®Õj4回žÞÐÐ0zôhRNTUUeee+•ÊÊÊÊ¡C‡²X,j ŸŸ_W­Leee999‚Æ×ÒÒrñâEÒ—Œ4ܸqC«ÕŽ3�P]]™™Ù­[7???›«1™L.—ÛATò¼¼¼ÒÒÒˆD"£ÑxæÌ''§>}ú’iFŽINA×ÖÖ^¹r%((( àòåËõõõ£Fjk9sæLMMÍÌ™3d*9yò$—Ë¥¤ˆuH£hJJ � Àd2Që„ÆßÚÚšššêååÕ½{÷ëׯ———¿ôÒK€‘y{{‡††v©Á+++mTï±cÇj4š””.—[PP)“ÉÎ;GD—>°¶“4ݺuS©T¤¸EQôå—_¶)CÿþýÅbñÉ“'y<ÞK/½TQQ‘êíí}ñâÅ–––qãÆuUqùý÷ß)Ÿ+ŸêM&C† �”””C¢èèèëׯkµZr°UTTD™Ñ‡þë~‚°yLÙÙÙ��AÆŒÓÔÔtéÒ%__ßàààk×®‘MÄ`0FÝØØ˜––ö_�€|“ûôéãääD–A$ 0 ´´4//L3xð`@ ÓéΟ?ïêêzåÊ•÷ßÿûï¿wuumll|ùå— CRR%Ø|||.]ºÔÔÔ4vìX­V›œœìîîÞ¥‚uü5ݾ};??Ÿ²Àóù|­VûÇPÙ{öìÙ%_$Ò‡‹|“�ƒáìÙ³ä)² uuu£FÂ0Œ´|R™ŒêôŽ=zèС 6øúúRjéæææ‘ŸŸûömòM>qâ¹ý‡‡GWW¼<³¯Š‹‹ i!'_×!C†p8œ“'O’iÈ79++«ªªjèСþþþžžžÇOOO'=QÛ^¶¨¨èÒ¥Kåzž‘¨šëÊò2º&œž/*œþ *œhhž5L&ÓØ±cCBB¾üòË„„R8M™2…n™¶ÃÙ¹sçŽ5ê):ø<¸¸¸xzzRÎGíÒV8¡+ƒÆ8v–n>š- ãã?ž8qâùóçÕjõÊ•+I³5“'OŽˆˆXµjÝO�tkÉqgÀ¦‚†æ_ A}ûö%ÍŒ��AžŠGâ3Ž››[~~> Ã6ž½4¥¬¬¬«Öx��ʀ膦¡¡åÔÖሆn¢Ç¥š?ŠæäŠÂÆ¢þDA¨¯·>‚¡¨™ÍÆŒFâ N¡I ¨¹úóOEé—òŸB,†BBèf ¡yAE&]-¼�5!vî$î_I`ÀôÄ‹q×iéÀœ~¹þ¹1ìK/A÷¢VÓÐм˜Â on/„pºÛmÍœ î­üE„Á`XÌfK²ýn—”h4š˜6LÿètÄž=t3ÐмøÂé«<g¸·:Ádr¹\…Ba³«Ð?J…³³N§ë6s&J»’ÿ45a´p¢¡ù7§ŠVëÅ­^IIÉåË—»º× ÍSNŠ“ÍÂ匌Œêêêç®&aUU.�$''kï…LõööîÑ£†à #‹Áu’æA\¼x‘ šÀT«‡P_W—yâÝ,44/ m÷»B¿òÖ·?%Y÷7nÜÀžà$Íã‚ ÑÒÚªº·DC*•òx<G?øçš´´´üü|2B [«�˜L¦ÆÆFºehh^dÍ)ÄÛ€»Â)==ÝCˆ=§qwÈ•qlË|/ô@èyÇb±ddd\½z•Üt�ÀÆq��Œ àŽ††æY‚ †Ä=ád}Ž� wïÞínðìƒ_½Jäæ¾üòË”C„µpÂqœÚx›æ¹Àl6_¿~Ü]"::šÜ>45a›7»¸¸L›6n"š 6›½ÿüõK7«ÛN/0:Îz;yšgŸêêêË—/“755‘uà–�z½¾ù^¬'nnnô¤&Í‹ Å€æ9@©T’Š/ªTÊ�0™Lõ÷Gù 'ú­ ¡… ÍS&((ˆÜ\ŽhlÔ ‰¢££ÿMQTT ×ëé·‚†NÏ7·nÝ*//7›ÍäЛËåÚìú•››«Ñh¨ŸNNNÔ6b$iiiÖ?ýüü©ŸjµšÚ·$<<Üzº¾ººÚz0Š¢‘‘‘Öé ›šš¨Ÿ"‘Èf3®ÌÌLj»<�€»»»»»;õÓh4feeY§ïÖ­›ý½0�€ÆÆÆ[·nY'èÓ§udåÒÒÒššêgW›ˆ ›ZlšH¥RQ{ǵÛDUUUeee4‘Édºëij4�poëxú/!//ïîô Í‹-œt:Ý‹]C©Tj—Á`°Ùlªkc³Ù¾¾¾Ö]?Çc2™Ô.—k#*Äb1 ä·=Ab±Ø&½½½Édºk†BQggg뎆a‡C|™L¦§§§uWÎf³Y,µA"‡Ã °vî·³³CQ”šB³³³³)€T*ÅqœÜ‚AGGG› ÿ|>Ÿ*�ƒÁpss³f]m"×AÁ0,‘HÚD\.צ‰è“†æ_-œJï”upúÆo¾ù¦ÍA‹µ{÷î™3g2äÃ?|Æk(‹Åb±N§£úwë~Öd2 …B›,Ö®F£Q*•Ú$ û}RiÀqÜ&Åb¡<1 CQÔ&u,KÛÅXÖ;Frwk¬e•Ùl¶¹>ATp‡a¸ã°Ùl6›ý ³‰p‡ ¨ã&b0”bÊ”)æÚÚ#�¤§§§mÙ²zõêÏ?ÿ<11qÇŽí>ý¹sçÞ¾}[&“ÅÅŽõÖ[Ö§~úé§%K–ˆD¢_~ù…<òÍ7ß<xpÛ¶m›7o®ªª¢RΚ5kÑ¢Eqqq©©©trr*..ž?þ˜1cœœœvíÚesÓèèè7þðÃ?ýôyA¤¤$êkZ´hѬY³èÞ‡†¦#áÔn/@¡Óérss_}õÕ¸¸8ª+ ˆ<îççî÷Ò~f·áÂq¼Ý•ÅTú º¹ãAtœà¡ø›%|hþ~ ÿé&"Ë0eÊ”¤¤¤ü À¤Iáá!‹QYYimr¤®Ã0éÌVTTTTTtôèÑâââÜÜÜ9sæ¬[·Žµ( ‰DBÊo‚ ªªªòóóu:]AAASSSff&¥=�ÊËËsss£££ CnnnXXØÒ¥KÉ$¯¼òJ~~>i>e2™ûöíûàƒbccÉÍÎûöí;xðà³gÏ.\¸pÙ²eÿrošÎ�ûùù>4‡Ãq¸ÇĉÃÃéSæwÞ  “Éd%%%t›Ò<vV®\™ššŠã8¹¼éBjê|ðÝwß>|�0cÆŒÆÆÆk×®¹¸¸„……ùùù}øá‡Ööj‰DB‰êMF$??¿¤¤düøñ¤Ú”°cÇŽ¨¨(��ATJk½–Á`ÔÖÖR?© ’¦còo;;;AÁ0Ìd2ÙÛÛ»ºº2 ƒÑV¥¡¡i_sðùMT__ON¹·]Ÿûã?îÙ³gÇŽ“'OîÕ«×!C¬g¶ŸZ[[i§ç ëp½[·n]°`Afffrr20€<¸dÉ’[·níÙ³çàÁƒb±Øßß?00ð—_~¹qãÆ¶mÛRSSGesͺº:Êy$88¸cmJ)“É\]]ɿϞ=;|øðC‡u\ø©S§êtº½{÷~ñÅŸ}öÙW_}Õ³gOú™ÒÐtA8u&Ñõë×·nÝ �X³fM» ²³³Ùl¶V«}6+Y[[›””ÔÜÜL?ï‚ÆŽÛÚÚúÆo,_¾<!!¡Ý@'Ô› �ؼy³D"<x0eÙîÖ­›‹‹ ù·Ñh¤RŽ7nêÔ©ÔE˜ššúÐ"½þú믿þú矾zõj­V{àÀ¡C‡ÒOІæq §#FlÞ¼¹ƒ …Âd2;Öf^ýYÀb±TWW;::Z{ÄÑ</455544tF8ýüóÏï¼óΫ¯¾:jÔ¨?þ¸­—ÄÈ‘#?ýôSë#[¶l™6mÚÎ;322fΜٷo_ò8—ËýùçŸÛ½W||üCC|)ŠK—. 0`ÕªU‚|öÙg+V¬ÈÍÍ¥( ÍãNeæÌ™“'OþöÛoŸAåÉl6ûøøøøøÐûy$77·3ÂiëÖ­ÆÅÅeãÆ(Šž>}zìØ±rá³F,÷ë×oõêÕ}ûö¥$SÇðx¼… îØ±£ƒ4—/_^½zõ¶mÛW¬Xñí·ßÒ’†æ‰ §¡C‡&''ïÙ³'99911qãÆt›Ò<1f̘‘™™¹yóæ#F0™Ì7fee566Ž7®]I“œœL9”ÇÅÅÉd2‘H4mÚ´Ÿþ¹W¯^ÖÓBz½žJ9bĈ˜˜ê‡Ã™3gNÇ©ÿþ£Gþå—_Èð€:îóÏ?§Ÿ ÍcNGޱäµuëV½^/“ÉŽ9âää´iÓ¦òòr�À¤I“ D·)Í?Á§Ÿ~ªR©`Æèáµd � 22ò›o¾illìß¿?AAAAdb///ëìAAAGޱ>"È?‚ƒƒ9âááAúæ›o¬ÝgȈ «V­zíµ×��^^^GŽ¡&¨��›7oV«ÕÔOÿ 6P‘A&Ož<xðà®q ¹#ÍãÂÝÝzÒÒÒžÙ õ‰DÑ5ádgg7dÈë#}úô!ÿ Žûùù‘ žž°Å‹¡{;e!ÈýYÆóŒŸÁàª×óöïwg0��8†�$R©Ã½Ž£{÷îTb›wµã7™ÂÞÞÞæéMnChh(õ7ŸÏ·ÉÒ»wo›ôOÒ˜¬T*ýýýéh°øÞž¥�€úúú‘#GZš¡y¼´bÿŠ­‡¢€ÉÕÕ” "�€ ÈF2Ù¬÷¤VkÚ`±X0 c2™äL& ÃOàí4ºY APíd–Ç‚ÙlÆqœlŠ'ÿT™â8ÜÚJPwg2ÚÙ÷–Á`@4|øðsçÎ=õ7ôúõë+W®d±X(úø¿;@0cÆŒììì'Ð<t´7zôèÓ§Owõ²={öäp8•••¥¥¥]ºÝcùùUUU‘ê²»»ûæÍ› d­=‹Åb‹EK‘ÇN}}ý… &L˜ÐV7}q„¼iØ´é¾~Éär¹z½žŠS×ÜÜ|üøqýg"8‰ŠŠòóókØbÕŠ{öìIII «®®3fÌÞ½{[[[©õ7îîî8ŽWUUq¹\6›M¹ª»¸¸ÔÖÖR„B¡H$jll$[†awwwƒÁPWWggg‡ã¸Z­–Éd,ëúõëƒîß¿ÿž={$Iss3e)òôôÌÎÎ2dÈܹs¿üòKkÉáêèØ»wï³gÏRëêêÈÈx(ŠºººjµÚÆÆF‘HD®�­ªªÂqœ*™ÅÁÁËåR§ôz}}}=Y¼ $''Ÿ9sÆ&ë“!77÷ÚµkQQQÔJ£»X¢í€ÄÄÄ{É5Oýõóó»~ýúß,OÑ4T*•uáÎcËñ¡xyy544tlæÚ»w/ùªÃ0LEºb2™TüåvËpæÌ™¶Çårù­[·¨Z“ŸêCCŠtëvÇÍ¡yŒà8þ Öþm™ÑÔÔtòäIÈ‚ o5‰¯Vk|EÍ=ÓÓÓ!òõõíLॺºº?þ8##ÃÁÁ!//ïÇ èѣǀ‚ƒƒ¿ûî;2YFFÆ{ï½§ÕjÕjõÍ›7—.]º`Á‚·ß~»¡¡A (ŠÄÄÄæææ‰'N›6ÍÉÉiïÞ½qqq3fÌ —‘åççÿüóÏS¦LY³fMQQ‘H$ÊÎÎ>}út'—’’’… bÆb±ªªª:TPP0þüõë×/]º�ÓÐÐPPPðÓO?}þùç¾¾¾eeeóçÏã7^~ùeFSRR’––6yòäU«VÙÙÙ‘ýéÚµkÿøã§µÁ]aaá³¹¸ûÉÃb±yhL) 6›m±XlvÚ$JªSðòò*,,ìäɉ4÷Ði'ª««©Á\YYÙƒöü|P …õO2Bq2˜Ãá (ªÕj;ßD4Ϩ-L§QýêY[[{á‚ ›Ä™Õ��~I C­=diiiA¶Í•’’RZZÚÒÒBþ<qâľ}ûþïÿþoÖ¬Yýû÷Ÿ5k¹‰øÅ‹«««'L˜••UQQ�8räˆF£ùæ›oT*UHHÈŽ;.\¸pòäÉ~ýú¹¸¸¼ñÆäj›ìììøøø;wî¬X±bèС¿üò‹¿¿ïÞ½—/_~üøqƒñÝwß…‡‡ËåòY³fýú믩irr²§§g||¼H$rqqY½zõ|’ŸŸ_YYyçÎF3räÈŠŠŠµk×N›6í»ï¾{ï½÷âããÜ‹¼`ÍÒ¥K/_¾|òäɽ{÷>Å­W½½½e2ý¹’TWWK¥ÒN>;;;Fc#x< Ô®_XXÃ0ŸÏW©:Û888°X¬Ž¶«Õjk'‘Žc›=H:ÚÛÛS[Mv,–¨ô|>ÿÎ;´pzî…“Á {á+É`0´ZmPPÐ_ÎÙgVÿ¥¿5�¦ 2 Ö{@PäååÕÖÖ>t„èããóᇎ7nñâÅ Ô¬Ÿ~ú)..nÚ´i6>QŒ3fذaí.ö?~¼½½}FFFFF†N§³ÞQ¢c,X “ÉŽ?N…6ïÓ§ÏôéÓ×­[7lذ={öÔÕÕ}õÕWÖQ·Ÿ}š››é¾Æš¶aà;P÷Ûlmmµ9Ã0—Ëm+œ|||ÔjuCCƒP(d±XÔš³;w¹µN‰¤µµµ³›L&3›Í’1¤)Þºx<O¥RYÙl& ×0 ‹ÅâÆÆFê¬õÎd]ÅÑÑ‘ŽÉû '±ô_1 ‡aØù–Jqõ¨õñnAÝd;Ø·yoÙ²eäœÓƒ‚„††Ž7ÎúˆÉdúú믽½½§OŸþh¾páB\\\HHH```—&„ÿ÷¿ÿ}ôÑGãÆ³Þ¢©_¿~ýúõ;räHYYÙ²e˘÷ŸüýýÉpi ƒ‚‚û^‹‹Å: -…»»;iXƒ ÈÚ �ЮóúCõ9ÒÉÞÞ^(’KP:¾BÛQAÖilJe#êììì:³ˆ»“…§y¢ÂéßPIr–Çãù½>Bà›_¾ûá‹–¿ù )™:?!ÜV®\yîÜ9jª«\ºtiݺuùùùï½÷ÞèÑ£»t³gÏ–——Ïž=›4îQ²9""âÿþïÿ��¯½öZÇ®}UUUÛ¶mk{|Íš5G±úGŸàã}@Ï/7oÞ|’áNòòòHõH©T’®@2™¬µµÕÉÉ©¼¼¼í°ÉZ‰ir ŠÇãéõzWWW£ÑhÅd2=ÔÁZ½ÃqœÔuD"‹Å²‘¯8ŽwéµiWˤyZÀÿ’zZ,­V 3Pïú½=�à6º¯ü­I™¸ó’iôèÑS§Nݶm[LLÌ;wvïÞý ”‰‰‰jµzëÖ­111»wïž7oÞ€Þÿý˜˜ƒñõ×_·›ËÎÎnëÖ­YYY§OŸŽ5jT|||LLÌ_|ÑÜܼjÕªFÓ1÷èÞ½{XXزeË^}õÕï¾ûîÆdl‚¹sç8Êâææ¶~ýú”””˜˜˜ÄÄÄwß}W.—ïØ±C¯×øá‡Ö+Fß{ï=ÿyóæM˜0þ`žø|¾³³óß¿ŽµáN"‘ˆÅb•Je6››››ÁÛŠI¨ÕjZ[[—¥N§kk“$½U»Ô Ãfù6Í3­9<xð‹/¾ ÿÞ¿¿··weeå¤I“†¾aÃ*ÙäÉ“›››“’’:yïwß}÷Â… ‰‰‰O&$«ÅbQ«ÕÀgÚPÙ p¦=Ÿ%èõúvGjk×®]²d ÀÑÑ1##ƒÏ绸¸ÄÇÇSŸ«¯¯/ŽãT¬>úhåÊ•^^^üñ5G"‰¶oßNN#âëë«Óé222Äb1�àÓO?•Éd cúôéQQQvvvdô ÒøîããsñâEòjÖÆ:òóËÈȰ>"“ÉÆ§Óé`öôô '‹çãããèè˜àîî�àr¹´YˆR�� �IDATóæÍ1b™ËÙÙY DFF^¸pÉdJ¥Ò—_~™,^ppðáÇ CgBÕÑ<#…BggçGž€ñððhnn¶‘¤æDúVX{:tÒ]ˆÂz6‚    ß<D"‡Ã¡Üÿ¬iw|i2™îܹó ÿÀõgÖŠæÉ 'Ç?þÎ;ï,_¾|áÂ…óçÏ4hЕ+WÌfó­[·BBBÌf³Éd"×&$$=2†a”MœZr¨ÓéÈ¡Š¢,Ëd2•——ߺuK­V?±xᆩÕj>Ÿ/ðv�t 3999999Q€ê—¥R©õ\4‚ Ö]¶L&#ÊÚ†Ìpvv¶Áq¹\*£u‹E·Ž¤þ Á�APÛSÖ;Ú‘gÍfs||üï¿ÿ>oÞ<jÂɺ mǶ֧¬Cû<HÿFë].i:¦¶¶–4RyxxP9"##ËËËkkkÉ}mŒom$ A6.NNN¤Û*� gÏžùùùÔg%•J FMM¯¯oMMN§ m×?ˆ ra //¯¦¦&k)h½Ê°3à8ÞÕ]Ü‚  ÈχY/++kîܹ3gÎ|çw„Bá¡C‡\]]© H&!!!$$äûï¿×ëõ£GŽŒŒ4™L‡’Ëåƒ þᇠCYY™¯¯ï Aƒz÷î½hÑ¢æææ/¿üòÏ?ÿ�Lš4éI†Â0Œ\ñØç™že<xâĉ;w¶˜çÙG¯×?öu—/68Ž“-V^^þ ýÊ•+µµµ,«mì%WWWëýIêêêÚ:³ét:멚¬¬,£ÑÈf³Éx ¤"RRRBîMü ÏUpÿÒZE+**lô3‚ ä´‰ ›Í¶^­Èáp��O&° ÍSNsíÚ5.—;{öìØØØk×®‘ïܹ³dÉ’—_~933sÆŒk×®ÍÉÉ?~<—ËÍÌÌÜ»w/¹víÚµ/½ô�àÔ©SOØIÆb±¨TªÕøhÖ¬Y™™™#GŽ|NËDÙNiýk‡á¶"ÇÍÍÒ{(ÊÊÊ:Äçó�jµº­ÓmDûsQØÙÙµH"‘ð;±I7…@ ðññ±³³³~g‘J¥d¬^šçŽ¿å­7pàÀ ÄÅŵ=UVVvøðᢢ"›ã'Nœ Û¦K¼ÿþûäüM—†‘* ¸·*ˆšéáóùF£±ãµ±àààð vóæÍå’J¥Ö¹d2YCCCÛ‘bWçZ[[moegg“s íÎQѼàšS´´´äääÈåò¥K—>¯!š3§OŸ¦Ý|‹e½¦Íb±X»$‘ù⥥¥(Š’^3‡ÚF„¤°°ô0‚ è±Ï=FZ2½°ÂÉÝÝ}ÆŒ—/_NMM�ìÞ½»¾¾ž �ÈËË{Pìá=z¬_¿¾oß¾6óIEEEëÖ­;þ¼õÁ§µz†æyaß¾}6Ž^4¡±±±m0Ц¦¦Ç¸˜W,w>Ž j(""‚´à=ÈHC §vÉd±±±!!!±±± ,Ø´iÓŠ+Þ|óMò¬H$ºqãÆ™3g-ZD9w9;;¯Zµ*==}Á‚}ôŽã<oóæÍƒaÁ‚+V¬ÈÉÉ!u©·ÞzËÛÛ{õêÕ!!!ô“ ¡ù'pttl;ÏÔ%˜LæƒÄ†Åb¡VVtrv‡Íf“=€Éd‹Åz½¾oß¾¤S_·nÝ:Î+‰lVSм¨<|ÎÉÕÕuݺuä+óæÍëÑ£ƒÁpvv>yò¤T*åóùýúõ  ¬ÁÒ¥K©Uœ‰dÔ¨Q‡&µ(GGGÒÓ:**jÏž=¦_¿~ô“ é€ØØØv#óÒ<•JÕ¥…>íJ 2ö±D"½ZXXèààÀápê½m6›I}N§ÓÕ××[,–€€�‚ªÉuuGZ>Ÿ/ iãÞ‹)œ@›5:䨇’(ÖËtHìììÚÊ›v˜­·1¥¡y´·Þ£ñ÷ w8Ž“.6.éÁÁÁ7nÜ ÿvrròöö.++£\ø|¾——W~~¾ÍÕ8Nÿþý©½Éâ?><<üòåË!Il–Ì[—¡]t:½né9å±9D¼öÚkMMM”Cù3 A{÷îÍÊÊzК £Ñ¨T*©ñ&ŽãJ¥’ryê�½^¯T*q'B©Tv~”§ÕjÛ.F!¯öÏ­ï±X,J¥ò±‡¥yj3 ?rÆLë”ӄ;PEEE”®¾¾þêÕ«Ö{ljµZ[Ÿ½ßðz½>)) 0�X ÀÛ½ÿmÝÙmîÞî)Œã¸Åb¡ZfàÀl6›ü»m([šçOsê ?þøã³_[‚ *++ÿøã�@^^ùM¶]£·uëÖM›6íÛ·oÔ¨Q�€ÚÚZj'ÜŽ¯¿bÅŠddd¸»»92""âÛo¿íLÁ&NœxõêÕúúzëÂÄÆÆîÞ½;))銌––óöÛoôÑGÏøƒÓétSÿKèÀFçë뛕•Em•Ò%ݨ­ŠCÉ-ÿ‚‚‚vOQâ‡!¤ÝžÏçk4‚ `¾o'šQ�Tà 0 ã�à­¿®ö A˜ŸŸ_qq1ƒÁh;Šò÷÷ï`I/…H$b2™dLØšš ÃØl¶Á`B¡°ÝØê4/”pz.¨¨¨HJJb±Xb±X£Ñäää@l#Ÿ¼¼¼œóóóû÷ïÏçó/_¾,‚ƒƒ«««©•[½zõâp8/^ …nnnäWJº;_½zÕËËkóæÍäÌmEEÅíÛ·É\‘‘‘G§ÓQãD??¿Î;)555QHhh¨X,NKKƒa¸oß¾�€ªªªâââ   ''§«W¯’ªž]=*++KJJär¹££ã•+WL&SDDDNNY¼ªªªgÜQª¤¤„ŽxFÂçóQm7 dQQÑ#H¦‡Žç´õWïÞ½³³³ÉEKööö†‘SSݺu+..V*•R©†aòÁq¹\£Ñˆý‰þ�äà @ç¶Þ%7Btuu¥Öc±Ùl ÃÌfs»"“¼—Ë¥¢KXÇ®%¿_//¯¢¢"•JÕùÍiháôR^^ž’’Âd2CCCCBB***233É=ÈCBB¬íÓ¦M»|ùr||üðáÃCCCçÏŸ1gΜ 6äççwëÖ-55uÁ‚ .œ0a‚¯¯ï!CvìØFšæN:5jÔ¨ &DGGóÍ7ëׯ/)) LJJZ¶lÙÿ³wÞáQ”Ûwvg{v³%ÙÝô°éACïEB‰Ò[€ Š ˆ¤EŠÊE¸HQ@¥^þDšôHƒôº©Û{ùýñêÜq[@I`>ÏfÊîììÌœ÷œ÷œï™;wîîÝ»wïÞ=`À€‚‚‚ÈÈÈ5kÖ´åø›››·lÙrîܹ„„„›7o¾ôÒKK–,IMMe0÷îÝ�œ={vùòå»ví‹Å ,HJJ2 ………Ÿ|òIVVÖš5köîÝ;~üø 444\¿~ýüùó�€‚‚‚tpãÔ£GØ'Âb±ØÊ<‡TTTˆÅâ'¥«Âãñär¹+ 1‰Äãñe^ù|¾§§'ÇƒÆ ßöâÆ¼qãÇ+//g2™Z­–Ëå677[¦X@�¯�0 €'a:;¾R˜Ífëõz__ßššG#Íápär9}ºúRŽâ�„qzj”––^¿~D"uíÚÊýýým6´O‹¥{÷îîïöììì£G®^½zéÒ¥ãÇÿý÷§N õ‚,^¼ö´-//OOOÇâÚ7oÞ<qâÄ|°páÂTTT@ñ¤Õ«WϘ1cÛ¶mëׯ饗Úòôz=F{÷ÝwGµhÑ¢;vLš4iîܹ»víúúë¯~ûí·Þ½{GFF¾ûµµ[·nmnnîÞ½ûþóLC,/^¼øüùóÆ 4hPÿù tu:Ý¥K—ZM8~æy‚Mëét:‰D‚ÏqƒA¥RñÓŸV«ÕiK@:®Ñh‹Ï¼¼¼ §ÛÝR(ñûÃñ%ð�C8éÜÒh4»c€‡G&“===¡ „ÿK¥R¨ P(\.·©©‰ÍfÛl6¾«¨¨°{sOOO½^O̰Æ©cA¥RY,VRR’Ñh´ÛFÄh4"Â`0ðnJJ ÖŠ‚Ëå¾ñÆðõÏ?ÿÜØØˆ—O†=ý† �pß0wÖ¬YðÅüùó·mÛ¶bÅŠ;wî´ý[øøøL˜0áСC—.]¢‚iii7nÜ·oƒÁøá‡Ö­[ÿlÿšØOù|Þ±ùùùÑÑÑOð!‹—Úl6GoƒJ¥J$»Ç}MMS¥|˜QTTd4<<<x<žÕjýÃ÷²°€€9É0ì²ÒÍf³L&£Óéøc€‡‡ ˆ]ú Jc‡ }&«Õ ³üüüª««ñïÓ”ˆ'>aœ:‹%$$„L&F»¤;©T ‡fv™uýúõ LOOçr¹,+%%åìٳО%%%Á´xXÖ.‹¡ej#Z­vÁ‚2™lÙ²eÍÍÍ7nÜhãŽeeeiiiL&355µ  �ÜÉdò–-[222vìØ1dÈäääçámo‡Óg‰`mMìð÷÷ÏÊÊjWU“¯¯oCCfé¡o! ÊûŸiÀËËK¯×Ã?ñæÚ,Ë€Á` ( ß¿G÷îÝ3#´Cpê?!„?»…f³Y§Ó………µ´´444H$¹\ ª°Bà––Ìü8Æôˆé¥NÇs‘I µ/­V+•JÅ+¬Ðh4Ì29Î$¿÷Þ{ÕÕÕgΜÁ'éEDDŒ;öÆ;wît3z6mšãÂ¥K—>\­Vÿúë¯^^^cÇŽŒŒlû·Ëåׯ_ ;v,¦‚Š ÈСC›››oÞ¼Ù¥KW-ŒeË–9ÎoïÚµ kfHÐyijjrSxàØúË×××h4BcF¥Rƒƒƒár•J…¿¶ñ2J¥«±…ép|,‘Hðİm°â§ÒÒR³Ù ꘠_åT7¶It\n4kkk¡iiiqtu:vØÛ)•J) Š¢Øy èÐÆéîÝ»ñññ7n|ì¼0ûäÞ2�ÂÂÂX,‰D‚™Üƒ ZµjÕ§Ÿ~ÿù矿óÎ;Ž’þ/¼ð¸qãÖ­[—Œ92--mË–-ñññ_~ùåºuëÁÉ“'¯]»¯V«§L™²dɘÑà”©S§ÆÇÇÇÇÇgdd|òÉ'ÇŽ‹‹‹ëÓ§Ïĉ[ZZ$É¡C‡ð»ìÞ½[*•öéÓ'999!!aÓ¦M3gΜ9sæÊ•+ €5QìÙ³gFFÆþýû-KBBq3@æÌ™=æÎœ9£¶¶¶¥¥û– ¼õÖ[ømÞzë­§räX?O§Øl6»\™Læëë û™L&ÌÝ1 ®²þ Þ3£Óé!!!UUUxcƒUMÁf¤ðussóµkÖ«�¸��“&™^}ÕIlV­V7448½…U*´sz½þ‰×ÿUVVZ,³ÙL$—wްìW‹ ‘°Ñ¼¨T*›ÍÖjµ°h�EÑææfA<== ƒF£a2™Xj@Gˆ) ‡C¥R¡T³Ífse™ çÎÃîvƒ±dÉ칃¢(‰D’Édø:>@ðÝwßY­VEá* …²jÕ*L*î5`À�Á‡sÅØmf—Ñþá‡â‡pZxòäÉ�� …2kÖ,è Z­Vƒ‘œœœ™™ ·ôöö¾zõ*<rx �€­[·~øá‡(Šb­ÙétúüùóçÎK&“Gú™aÓ¦Mhnn6ðì™L&™LÖÐБ‘½aEãââN:uäÈ‘¥K—²X¬-[¶À‘û÷ï<¸ƒÌºc]hñ·3ø³ø>ˆïÞ½ ’¢¢¢ìJúöí{çν^­¼Î­V+™LÆæo Cyy9—Ë…ÝÓáIˆ-))‰ŠŠ*,,äóùd2CLLL—.êêLžž@.Àu_úË}j7½„ Hdd¤{%÷H$³ÙìÔæÙø£÷B§ ëwíÚu̘1ƒž={v]]݆ ¤R)œ;‰‹‹ƒíNŸ>-•J8С¾­ÍfS©TðÒ·Ùl:Îý…ˆ¢(¾ã�,*„ÀÔ>*•jW£N¡PàZl™L¶Û ®¥R©Ð*`kí>¿ŠJ¥¢(Š�49T*Õf³ýöÛo©©©xxðÝH$Š¢˜„oHX&ÈòåË zôè-¹råʲeËÆß³gÏ¢¢"³ÙL"‘rrrΞ=k4e2ŸÏçr¹ð· R©ýû÷ݽ{wGø:XZǸ–ìm ‹ÅÂ,v)^ºt ªÞa{AŸÛ×ׯÄb1Fó÷÷ojj2<n™““ÜÐÐE¥RáEH"‘¬V0bøé'ûCòððp“+kµZÇ2�jkkÝ[&‚Îç992cÆ “Étùòåßÿ}Ô¨Q;vì ‰D·o߯„ š››óóó:Ú†ù< Ãh4>_V«uçΩ©©ÄÕüÄáóùƒ®©©IOOÏÉÉY¼xñìÙ³étºZ­þì³Ï:´~ýúqãÆÁ/_¾ì´åyGC¡P(¸\0b¶$21ñÆŸùŸ<oo‰T'“�|ºt¹_^��r�ä�€øx,¯|xjêÁƒË��áávÍÛ Q4zôèììlàã#0Àl6ËårUPZªï?¸€+ï6¢D ‡ ŒÂ¸“ýX.Ku5hƒZ„ÝГB¡´*SKÐiŒ“#3gμtéRzzú¨Q£à’ÜÜÜíÛ·¿õÖ[m¬àù‡Á柞Èdòñãljëøo"..;½©©©«V­JNNöòòúôÓO:´zõje…Ì›7ÇãuŽæd£GƒÙ³ÁŸ37��fÈ�`³Xt³Yo0”�p~¤u:0q"| ;ò<=)(ÚÐÐ � �`Õ¹å�˜Ñ¯OÜYXºn÷ÙsÕÑ€¦ÖÑø@)“i2™H$>±EQ‘·w• ­ àãd2šÚ®s@¥RÛ¢¡NðÔŒ“¢…ðv œSQQqìØ±^x¡oß¾ØÂ>úúLxËÔù8ydf�¼½½ñÓ<OO«Ñ\(CòºººŠŠ ›ÍÆd2Ùl6[$2àÁªHD¥R‡GEýä¼� à­95›Á½0¢ñÎõë�dœÂ¯Gh4”ͶÁN–¡Ñ˜�W_‹Åuuu`È0c†Ý*A„Ba}}½« ÑhÚÛ€ƒàŸA'0ß0mÚ4©TºiÓ¦ôôôÔÔÔÏ>û,!!s¤:)eeePç cûöí"‘ÈÎ2}òÉ'J¥ËÒì CQ Å®ÁX,vœq”Ëån4ø-‹^¯‡!8*•êíím±Xrrr<x��Éd•••Øîö½¹ j>¸ FþË �6›ªR©ì“ —ÓƒquœþþþíÊèóõõ%&_;ÖåêÁå·ºÑÏ?ÿŒǼùæ›+V¬˜>}zssó‹/¾S˜  ‹;¶mÛ¶êêêÕ«WOš4©ãß Ü3þüo¿ý¶°°ðöíÛï¾û.lªùðáÃéÓ§ÃmfÏž=xðàÿþ÷¿Z­vÊ”)ùëX­V»€¶F£%€(ŠŠÅâÊÊJe„`›©TŠ×µ�466bJz‹¥©©ÉQyKa…ò+Øòýë×Hù�€êêj¥Ri³ÙL&S»r8W™ …¢]ÕNXªAG1NîWGEEýòË/ø%ÑÑÑÑÑÑ0»”Ïçck[·nU©T # à—_~M3 :Û¶mS©T4 �  ¡”"\Á`0~üñG|9ÌúÙ¹sgÇY­V;¡Ì®X,hr õÒjµÐ7‚Ru,‹ÇãUUUI$­V‹ ßÁÚ#ÇÂrÿì„<Ê+"À™û�€Z�N—ý!L^[[k4±¹LÊÏÏÏO.—»Ÿ†‡çÌ2Á–PˆÏ „„D'3N,˱<Ó©z–rJ§Ó‰ŠN‚΋Œ‚@ °i9ªèB»õÔ<%%%//ÚH.—Ëårí4[©TjLLŒ\./Å-ŒŒŒ,,,¤P(þþþ………Ð&a‰sz½>**êþýûƒA$uëÖ-//ϱ1¦MMML&S"‘`^—T*­­­e²˜l)û¥/^úÆûð�€E�lñññ¹¹¹˜màñx,«ªª k]ëªoS[v!¢$Á3©S§4 Š¢ …ÂQMÜh4feeaÝÅ ‹ÅjµºšÔÉÏχ…±?üðƒ£à7ž7ÞxcäÈ‘(ŠÉår¬˜–1eÝÊ2zs~É:€~†RwS�W¯^Å{----P£Ál6CãµnÛu*bbb°Â©úúz¨žN£Ñ‰%.•gÁs" è€Àv ÏçwoU×ÕU>7H¤.]ºÀŒˆ‡‡–õ�áp8t: £q¹\8K{¥cá»~øááÇ&“©¢¢Âßß6±E¤¬¬ ¦' ÆŠû]�`†…Óéô[·n9J.Á"qìÓ-‹«"\‰D§Óu�ШT—î´±o=òóósÚYE@§¿ ¹\þÜ>È:ñuI¡¸iY¤R©\µæ‚O¶~Üf³á-�@*•VVVÂö�Ôjµø ¤ˆˆˆ›7oÚl6:Îáp0)Šúúzh„`5!ìÛK¡PÔjµZ­†™ß1�¬ Åõ/Èf³I$’£`¹“È‚ˆÅâ2�x<S"±s í¸rå qgÆ©¡R©Z %èh0™LGÉ� …ÀãñFŽù<ŸŸö'>Ÿ/—ËÛž–ÍãñÈd²Åb¡P(žžžf³™J¥b®Éõëסa¨««Óh4,ËjµêtºÀÀÀÂÂB£Ñ¨×ë¨Tª\.÷ññA6‰DB£™Çk¤ÑhT§É�§wnN‡v[b±XÊÊÊ€TZ'“×– ;<âÎ"ŒS¢K—.PE‰ Uœ>IQuS…C ‘H%õì4…ýˆˆˆüü|»q€D"©®®†ê®Ž{A‰HøÚÓÓÓb±èt:Ìs�0 >ŸO"‘ø|>üÉd2ÙØ±½V®ü¶¢3†|ø°ËCòññÑëõd2¹¥¥‹d"[â:6fs Š¢\.·±±‘(`ê”ÆiÛ';�@Ÿáoh2™žÛÆtÏ!NêÜ 2 ÐÕ××óù|Øo ¦)¢(* kkk¹\.�€F£)•J˜Å‡Íß`n^‘A§Ó544X­Ö’’Nçëëb2�º^½tN‡Ãa±X&“ KˆÀ€‰Íf·Ñ´Ùlа¹Içñxf³Ù•GðA<<ØÄY xfÀ*dÛâc±X,ø/++ƒ;???NÆMMM6› ë„k0ôz½F£1›Í]ºtÁÛ!FƒfÐKóóó›5k–J¥Òh4^^^0¢  ÿÕW¯þi<«! FPPƒÁhhhP*•‚H¥R*•ŠÅ?Ôj5ŸÏÇw uœu¿N§Ã¯$I*•—PG1N“'Ž'ÎÁ³A»Ê­š››±ÖSðé/“É1ãÁ„’õz=ìÓf6›kkk½±)S¦P©T³ÙÑØØxéÒ%___ooo³Ùìååe6›…BA` bæLPU"¾0q¢½Cc4KJJôz½———¿¿¿N§ƒŸe6›ñ¶°©©Éi8ÄÇÇ'66ÖÝ ©öؽ^}Y›Íæ´ÉÁÓ1NŽí\1jjjÂÃÃ-Z„-™={vxx¸£¼dÉ’ððp§i‚ ;©!÷ †.]º`pa 8¾Sbtt4~¶F$y{{c‡Ý»ùûûWUUA9h`îß¿_WW×ÔÔTWWW^^T^þ0=ý)âîÝòÉ“/|ñ…}Òb±h4¸WMMMss³Õj…Kø3 ÑÍû³¤I&“Ý¿? ÀUÕmyy¹Ùlvs–ˆéÌdœÜ¯¶Z­uuu° ¼¥¥Ž•l6[ÍŸÀUJ¥N„ÖÖÖÂŽV«­©©õÛpc7 ÁO{["‘ÉdlzO^^ÞÈd2»[˳‹Åz½þêÕ«ÁÁÁ&L€oÅårƒ‚‚,‹ŸŸ—Ë…3Oûö}k³ÙL&³BaÒë)®;$Éf³I¥ÒV[iÓéôИ+a±X`™—«lF³Ù üWÁ\âêÆÉÇÇçÈ‘#ç΃ý¿W­ZuõêÕÿþ÷¿÷ïßïÞ½ûÌ™3“““—.]Š÷îG �8sæLttô_|QZZ:nܸI“&M:uäÈ‘ÅÅÅÄI' è8@…ˆ¶LáØA&“ƒ‚‚à뺺:¥RpæÌ¬ØˆL&C‰Â‡²Ùì°°02™l2™`M•——l­ë///‡STTäªç=ƒÁ€’²z½¾¨¨ˆÃá@MÞG&00°  €¸:çä”}ûöM›6í—_~Y³f%( —�� �IDATÍñãÇ;æfãõë×çåå>|øäÉ“¥¥¥+V¬ N:A‡‚D"¹±®°X,EEEð5‹Å’H$õõõZ­6??6怹b±˜Ïç³Ùì²²2oooA<<8ОUWW³X,§iîPXÏ&^pp0~­\.ÌrÆâââVÕ7þI(5n'�½½½Œý9räH·sç΃îÛ·/;;»óõ×_Ã1Áߟχ¡-üB‡c0`ú�™Lær¹ŽÊ B¡°¬¬ìq>šÁ`(•J˜GÇápL&CQÔb±À΄¡¡¡&“ J?ò�ÈÅv´Z­Nãl‹åÉjat&ã´÷?�à»qugΜùñÇgddäää|ðÁ"‘hãÆ{öìY°`AÛ{(•J.—»zõj¬ÅÆS!;;ÛM…“ÉìÚÒ†ÓRSA0 Tü6\.×ÌbÁ[ø‘kTQõôôlhhÀò×Édreeeyy9Š¢d2¹¡¡¡¹¹™L&çääÀ¾vŸå&ñ]§ÓY,±X\__ ŸÏÇÏx544¸qt$I]]£jAg2N/¼Ðã۫víòÑG͘1>»?ûì3>Ÿ¿téÒ“'Ož:uÊq—:t¿dÞ¼y`ùòåÚ~‚äää¸jŽI¥R‡ ‚ýùÕW_]¾|yùòåþþþN·ß°aCuuµ@ xï½÷žìAæççïܹsäÈ‘£FÚ½{wNNNFF¬lï¼ó>õ(%%ï·‹?ü°¢¢âßÿþ7þ1GÐÑhhhÀ_Þ*,��üüüjkkñšf³n<dÈ‹/b{q¹\‰Ô–6}ÅÅÅx§G,·´´X,–ÀÀÀºº:E›ššx<^HHHdddNNŠ¢·nݪªjýb4M­VF›Íf³Ùì\(W=!p/Wn÷Âêdİ¡î·èÑ£� W¯^P‹sïÞ½uuuãÇ¿qãFjjê¡C‡.]º7Þ³gOuuõÎ;á.àÏ,ó×_}êÔ©—/_îÕ«×S¶Æj£ø—RÇ£G%ãëï®_¿~øðaWÒ“|ðÁÎ;‡ 2|øð'~„ÕÕÕ‡¾{÷.�àÅ_LIIi5aÉ)ß|óÍÿýßÿ¥¤¤¤¤¤P(”•+W^¾|ùÑéÇ<|ø01í\èõz,á[¡PH¥R«ÕеbÒh4°sL`sº� $$ÄÕû755ùûûã͘J¥‚ÞŒZ­Ž‹‹óõõˆˆ ôññ …jµ¶ÞËÿ΃ŹNß\£Ñ466FOOO‰d±XÚÕÖ¶©©‰L&;Ó@kM§Óýüüˆ‹¤C{NmÙhüøñ½{÷öõõ…<øÜ¹spÅ`00}ÿàààŸ~ú‰ÅbyzzNœ8Q, ‚£GÂ!<Nê؈Ùʨv"UâççgN¾cÆŒ!“É™™™óæÍKIIY²dɆ vïÞ­V«·lÙréÒ¥œœœ×_n¼víÚáÇO›6M&“íß¿6íž<y²Ífûú믡C–ššj0zôèññÇ�¶mÛvâÄ ¸ûo¿ýV^^¾téR�À¢¢¢®]»vùòåÓ§O«TªqãÆÁÍæÎ;kÖ¬¥K—^»víôéÓãÆ‹ŽŽÞ½{·ãÁ3 è-Ý¿ÿàÁƒuuuo¼ñœ) <|øðO?ýôþûï¿õÖ[÷îÝ;þü±cÇ`ƒ¸ÔÔTll‘’’BÜ'¼«Í´ >Á-˵k×ðñ1‰„ù%ÕÕÕØ*___XF‚EäìT`pÖ¬YùùùýúõËËËÅÅÅ4­±±±©©©ªª*22€?’âär¹«–¤WSSóh£"«Õ +jù|>Š¢Xº„¯¯¯R©„úLÄEÒéŸÏçóÿ7/… ¾÷— ¶ÊÓÓ¾xºóLIaaaccãš5kÞ|óÍÅ‹ÓéôE‹]»víâÅ‹¨ªªJNNîÝ»÷Ž;6oÞ<wîܯ¿þº¸¸¸¨¨¨ÿþÆjµfdd¬ZµêÛo¿<yrß¾}¯\¹RYY9zôhEÃÂÂ>þøãM›6 6¬_¿~III×®]KOOÿ׿þ5iÒ¤#F|óÍ7yyyf³¹W¯^~~~§OŸ>räȪU«˜LæÃ‡óòòú÷ïÿÕW_ 4ˆB¡|úé§®žP‹…L&/_¾\¯×Ÿ9sF $$$̘1#999//oéÒ¥[·n½zõj¯^½®_¿>xðàøøøýû÷úé§o¾ù¦›2m‚Nô‡Á"{‰¤¥¥Å®¦‹ ( ‘€Å¢£RÍL&`7‹c³Ù0B"‘¼¼¼<xPPP`µZ¿üòË>}ú—––*Šððð[·na„M&“Ó@±···¿¿YY¦aA"‘X,–——LÜnhhP«Õ®šäÆÄÄäåÁ}åJ9À}ŒCX­VBr³£‡õˆSÐ*"‘èĉl6F<°äWgµZ•J%•Jåóùt:]­VcƒÐ˜˜™L¶k×.½^§sQ•Ëå<ËåšL&µZ=oÞ¼ììì^½zÁˆ‡\.‡½s Óƒæµ´´P(>ŸÏb±ðj`.\€í ð}0*++÷íÛ·uëÖ’’’¬¬,¡P¨Ñh, öTZ¹rå+¯¼B¡P |§B¡€Š5F£Q£ÑéRˆVû‘«Õj,ÿ»¢¢ÂQíÅjµ"B£ÑÎCªª¨åå´ÀÁƒ�qœæQ(??¿ÐP¾¿¿¥wïp6«K—.‡ËåŠÅb“Étùòehö(”¿ ˆ¥R)6ŠÅ›½ªª*ÌLzxxôîÝ[­Vc)…eê2µY �pÕ9077×Vú‡µ¦Z­kÿwØwîÜ!®“gÇs"h/L&óÛo¿mu³šššU«Våççóx¼ææfh–ž þþþYYYØŸ%%%sæÌ­5P€÷ö¼yó��={öäñxÄÚY¶kˆÁú37¯UAhh¨§gþœ9‚’Š«ÒTø†žž`Èo‹>zô=o½åWRÒ —ËY,KÝ¿ÿîÝ»Z­¶¸¸Øb±ÄÆÆ…91N/E»€[||¼ýØë �Š�(À À _ã.�ñ�<À€‡­Ü­&“©½â„qz–ùúë¯ÿûßÿ<xp̘1qqqvzewïÞÅæóž7n¼wïÞ­[·¼¼¼ÝlÙ£GãÇtê¨ìóÞ2Ñh4A°‹J$•——‹D"&“éF€N§[­V›Í† H—.Et:ˆŽ àÂû-çÏUT”ÆÇƒ5kþ˜…:|˜çáQ9ož¤¬L€F ¸Êáq¹úõ>>>MMMƒ€,~¸ê ÀxÀ“ðd™¼¹•L‡ß‘ß�>3#€õ�D `�qõ�Ü´ßm2�[�¸€€ÿ¸{¡P(—Ë ãD§g ±cÇ–––îÞ½;;;{РA°6¾tëÖ-&&æÜ¹sµµµcÆŒ9tèÐñãÇcccû÷•e³Ù°ÈÆôéÓûí·Ý»w_¿~½GgΜiïÑ<ø÷ßÿꫯø|þ¤I“nß¾}þüyÇgÓ„ îÞ½»{÷î_ýU«Õ†††vœn6›±¨ÔóLDDD«iýT*•L&cÆ©´´”B¡OOÏ·{yzzæææ66*zô�°'mQ¸qƒA¡Pð>>¥�ßÈÓÓ³&1�PÖ½»·Z­öñá? ãZ,.—ÔØH2@Ïž/œÎÊ:Táå7‘ËåNÃÑvXµ”»šΟ°¾�´�¥ƒ¿hà�>�üÒÊû?|ø¸¢ãôô¡ 8Q‹&8.'!$`ýßdorrr`` D"Y²d | DDD¤§§ÃTøéÓ§÷éÓ‡Á`0ŒÌÌÌo¾ùF§Ó 0`øðá!!! .ÄîáØØØôôô¤¤$�À¬Y³†Š¢¨——WzzzTTÔ€ÞÿýììlN÷Î;ïx{{ †ðððŒŒŒsçÎ 4(66¶´´ÔÃÃcãÆ{÷îÕétqqq¯½öZbbâÔ©S{õêÅb±¨Tjzzº£ Y¾|9œþßPròd …RUU�ÈÌÌ„µhééé/¾ø"�`Μ9#FŒðððÈÌÌüòË/u:]RRÒ Aƒ¢¢¢æÍ›WWW׊œL&Snnn·n݈[·Uè™ÍæÜÜ\)ÃJ$™L†M&)•Jl"*#“_xá…ßÿÁ�vÀ’%�� ®]�€±cÑ>ú0™á …B¥"…‡sª«E Ã`0 (¹¾èõ OôÆ ’HDF„ÔL£¯¯¯L&ƒÒp‰T*mhh`±XøÃûƒ)�Ô`À�ÀÇ� 3¦pî/Û°˜ÀJ�¦�ðÄåÐ Sc}õóómQ8lX—.]ÚâdÀ$l8õo•Å‹Ã×XV7�ÀÇÇ[™9s&ö:<<<<<¾ž0á£(°] 0`À�øëN “ãââ°·²ûì †Ý*–àŽgüøñ®ÞpâĉX”ÃnÕäÉ“;ÎÈd2»uëöܦZݽ{·k×®öõÖŸêõz»\m@`4P�0÷B¡Àù¡ÈÈÈêêjÌ€••M›��àüyt:`µªa8º¼¼<88X&“±X,(|�€Åv•••v‡a0°<u@€ ˆÙlÆÁ`p8œ?LW�¿à^Kï�Ö�p€x�^à¤ýz‹Åd2ñó[AAADߟdœÔÚçè&4h···«HQdÚY°Z­ÏmaYY¾£]8-*‡E©x`2'�`ÿ~ ÕZ¸Ÿ V®ÔÃYWR­7n€ä&TcNXqq±^¯OHHhjj2›Í¡¡¡®¢²øJ[F£T*M&¦rb2™þç ^j÷Mà5��� �tubœŒF£CÖÔÔDÜ\È8‘ç(²›r¿:Áó‰c Ï)°<höl€iiµ�ÊI”••åææ¶1wÀl6CAŠììl“Éd±X즡P˜—— o&ñ2Èdò‹/¾xåÊ•vݼQ ¢òA>��œ�ÀYvªc†^ÏÁ?RXäRX¯ºº:((hþüù�€M›6A—<..®ÿþ��‹Å²k×®ÐÐÐÈÈÈ.]ºØl¶ÜÜÜ.]ºDFFFFF†„„œ:uÊÖ*Á?‰DŠ…=ÜlƒM,UT€‚‚?þUT€ÆÆFÔëõЯŠe0Ý»wÇg~âu]I$™L&‘H:.  {÷îvÊ–eee·nÝrÉ ‚Å‹åúõëíý¾¾û3EBH$B²ó§—Fr<Q(0ÛÇ`0( 8rQ*•*•J¯×ïÙ³gÓ¦MëÖ­+((2dÈôéÓëëëûöíPPPP0a„9sæÜ¼y“8ÑO›ÍöàÁ7Zy��.—ë*ÝJá—äææZ­Ö¬¬,ü<Vbb"V<.‘Hºwï.‰ø|>,�·óT,‹²žòòrÌ•iÕg"“Évå½xC(‰ì„l��T*•ÅbF‡…BE]–”Óh4§}‹IHHÈÊÊZµjÕÂ… g̘�سg�@«ÕvëÖM¡Püþûï¾¾¾ÁÁÁ½zõâp8ĉ& x*Ðét³Ù îF£±°°ÐÍÆr¹¼íúª‚øùù•”ü%/ýLÝ��PSSƒ%8<¦ÏÇb±Ü'{°ÙT>¿¾¾žÃáèt:;+hW/H"‘<<<$‰¯¯ïõëס$þÎs²Ù\ÆÜ¼½½·lÙR]] ²!çÎCdïÞ½Nwa2™‡ y÷ÝwW®\)öìÙIœh‚§‡ÃyÌ>Ÿ(ŠJ$Çå‹ÅÎ2áí–£(Ñã'G¿ÇÞ¬*°ÛSxxx«J+d2Y$)•Êüü|Ø‘h…Ú�­¤¨Ý¾}ûÈ‘#ØŸëÖ­Ãw rD"‘üç?ÿÙ¼y³\.Ÿ;wî|Pë¶Ù.ÁßG}}½jNwÚ¨‚J¥:•ª‚ýsG®nfqÈdr—.] Z4›Í~Ì.nV«µ˜8Nss³ÒŠ#°”»¶¶¶®®®²²ÒñtÏÉqò÷÷Ÿ2eʵk×h4Úûï¿éÒ¥úúúwÞyÇÕöz½~íÚµû÷ïïÚµë|””ôÕW_Øÿ]»v}²o¨×ëïß¿ßêf|>3B‹IÙl¶£ E¥R½¼¼��žžž©y ˆÝ$Yuuu«Æ‰ S@qoœÄbñˆ#Ž=:nܸ7Þx#%%¥¹¹yöìÙ�€°°°W_}õçŸîׯ߰aÃ>üðÃÂÂÂÌÌÌ;vôë×oöìÙÝ»w¿zõjÇù¶—/_v“:Èb±ˆk‚ SãXÌô§®36z…88CF£±íÕcõõõÁÁÁMMMqqq—/_æñx ÃÃÃC&“‰Åâòòrhœètzss³]¬ÅjµÂLq©TªR©Ôj5ì+ØÆ …ƒæJÁïëááAÚ^¨D£Ñø|><HXûè> DÐጓûKdÙ²eV«uùòåÛ·oÏÍÍݼy3—Ëݵk׊+’““�eee+V¬è8sNeee®Ú´Óéô1cÆ`îØ±ãÇÄþ Ûºu+q¹t|r¹üï˜íohh0 °¨V«Õj4š   …RQQ,ør%Š¢~~~°ùEII lØ®ÃS«ÕØ]\__%ôz=‡NçóùÐV…††»y¸a5X��¥RIdCtDãZ3Nƒ¾uëœüôÓOu:6ß( W¯^ ¡��(оüòˉ‰‰Øî"‘¨Cu«C•Ñÿ•9.rzƒ‡ƒ¥®–””\¹råË/¿Œˆˆ¨¯¯OIIAä£>"®‚NG}ØÍ¯íú=jµšN§³Ùl™Lݲòòr³Ù|õêU÷Vë®ÛöÌ@æïï_\\ �ˆ‰‰ill„lj¥ð™L&™L†}îÇÝ»- 4“UUUŽ” #€X[3N, kæãã#•Jñu|žžžÒ?¢&T*UŠ££õQ%Ym¨ÒàøËq2Eìçç'•J Ceeåž={¤Riddd``à­[· ƒŸŸßèÑ£OŸ>-•J·mÛf2™&MšókÃÃÃSRRt:Ñh\½z5,Uhhh(,,ôóó[¸pá–-[üüü¾ÿþ{âB$øg`±XNµ%i4šŸŸŸ£×…/ªuD¯×c �ÁŸ‚@vÉ‚b)6›­-<___¬ûvll¬Á`(-ýC.àÎ;N§±…B!Ü%<<Üf³ÁLJÃÁj„¥R)>5C©Tâ›Ð�H$RLL q‘tãd"úœº¦¢¢¢°°°´´”N§———ïÛ·oÍš5‰‰‰C‡miiÑh4·oß¾~ýú²eËÖ¯_òäI½^¯ÑhfÏžýý÷ßÿöÛo‹-Ú³gÏÎ;7mÚTPP  á |äÈ‘;wúúúÚi‡ü}h4šŠŠ Gq<ƒÁðàÁÇYL¶Øø]¨Tª£…———Z­Æbhm¤ºº›<ËÉÉ!‘HØ1»jÈ[WWU\<x`4‡ -–éWRR‚9‘‚ (jç]Aâ"é PŒ&Â8¹ä“O>žß´iÓ>ú裚ššâââ‹/âEÀâââ6lØðÙgŸáwüî»ïìºy\¼x@‰D«W¯†%ÌíÂ`0<·õ £x‹ ƒÁ@„%Ôµ!¥Íf»jƒë”   šš»jY¬†ûÒh4nq(ŠŠÅbÇ„ò?êsíråÊ6›íªtf :Š£t ã%n×lݺ5þÏÎ7ÕÕÕ¹¹¹‘‘‘P÷~åÊ•‡öíÛ , 8°L†N§{në$ Š¢­¶Ì R©G«Õâ'œáñxUUUªº:à¬Ô —Ëåóù:ŽÃá`£1‹e6›?ÉdÚl6¥RÉf³µZ­£gÆiÞöA®’• IvZêD"‘ø|¾Sûãååe4]'½^OX¦oœ9Ķ‘}ôèÑÕ«W/]ºtüøñím >wîÜ—_~ùàÁƒDÆc¢Õj+**Z• x†ÉËË“J¥î•L¹\nPPô/µZm—.]ètz~~>l5Ùh4›Í:thmm­V«e2™---¾¾¾ …ÂÑ¢P(6›­®®N,;=0æ*ï€F£ÆGK¶Z­>aaø…B¡°¥¥Å•zAç1Nm#::zìØ±çÎkjjêÝ»w^^^fff[vìÛ·oŸ>}Ž=zóæÍ£G®ZµŠ8™Ôº&ÎC[L8æ6%&&æççÿe‹Q£€··›w¨À3,ÌèçW““cS(lL&Ë›…B½^ÜåŸ/\ ÙÜ~P(ÍÍà‘Ûètàðaì/¢1Û3bœž7lj!â'n^àä‘÷×6í©©©ýû÷Ç÷ JOO‡2ƒ½zõêÚµ«B¡4hÂ:T,'$$øùùÍž=›Á`ˆD¢ýû÷ûùùÅÇÇoذfÁ¾ð £GÖjµû÷ï ®¿GùŒ¸¸¸ç6ý÷Î;Ý»wouæI£ÑÀ¬9‘HD"‘nܸñ—(ÖO?úúV?«ðÊs—.Šª*oooèr5þ=_ÊÕÛúùùÕ××·>Í&“‹�111MMMŽó‘|>ßb±´%)EQâ.ëžÓóÔæ„J¥&¿œ¥SÜÓµkWG˜ààààà`øÚû¯£N˜7�À®lE±Nê111øU|£w‚Gæ´±ßݳÇÇãââ\­íÖ­Û;wðK`§û$ºâbP\Œ_Àd2ê¹Ô³Ùf­¶™N-–jµÊÕŽððp*•ZPP`6› †——6k(“ÉœŽ6š™L³^ïÆ£ ðàögee¥%c³Ù§±±ÑÕ¡z{{›L&lRÍb±ýp;Èså9%''Óh4¥ ñG‚ÎŽcr^¯7›Í•••nÒ àføæ�€¦V«­V«V«åñxx;L¢”——{xxÀx¬]²eMM«ü§¹vokg‰±9]8ÔjµÐ÷‚£™ððp»4úææf±XŒÕTÁ/K\HÃ8¹õœnݺ%‹aéÙ³gÝ\â½zõ m×Ç9R,ÿc1b‹eu qAt^Èd²«h'–qળ@°= � ¤¤Ä`0Éäèèh�€\.Ç[x³0 Ç[>66Öñ©b0®]»ÍfÃßk&“ •Jmµ¬Êñmét:v áááXHƒF£‘Éd;m¤ÂÂBh¥°™K³Ùì>Qà)'w«m6›Á`˜<yrAAÁ«¯¾úÚk¯ýôÓO‹Åh4æÿ ô‚+**ÔjµN§ƒI2 …Û�ŽD, ¶v^©¬¬T(ƒ6@S©TØ0´°°°¨¨H§Óåçç·7;Ž€ày#88رºÖFƒI-8ÒÒÒ’••%“Éèt:ŒZ,–¼¼<ø(À"CBB`ÿu¨­‡'''Û’B¡`‡„$ƒát^Çh4âctmD¯×cÇ R©0'Ìh4ÂH»Ý ¾ ÓéØ1”——··F˜àé{NxÖ¬Y“˜˜8mÚ4…BqüøñQ£F­]»vÖ¬Yï¿ÿ¾L&Û·oT>Þ¾}{KKËÖ­[§NºvíÚ”””èõú³gÏ>|íÚµsçÎ]½zuuuõ‘#G |ÈæÍ›U*Õ®]»&Nœ¸víÚ &ìÚµK¥R%''¿ôÒKìÝ»÷–-[ˆ_‹€À ÅÅÅ<g× ÏÇÇÇ}¦û÷ï·%àÁf³{AiµÚ¶+øµ‹ššÌÌäää¸iû«Óéþ¦c x Æ ?ÀY¸paTTÔ‰'RSS<xéÒ¥õë×K$&“ùÉ'Ÿääälß¾}ܸq'NœHJJZ½zu}}ý¼yóOœ8±eË*•ZRR²|ùò�ÀÞ½{KKK7lØ0tèÐ'N 2$33jv566nÙ²eêÔ©x1Y‚ÇÇÃÃJ¥�H$’]›ÁÒÒRLs5X,�€Ãáxyyá³ù±UŽÈåòÆÆF�€X,î8Ýfñòòâ¶V†Lðtyô:§ªªª-[¶\¿~ÝÕ7oÞܲe‹ãà%)))))©í÷ϪU«`)‚GÃÛÛ»±±ÑnVEQèiÙl¶V7 ø3ÙZ©TÂy& í,™# C¡P¶±§íß ‰D¢ÓéxÏO (•Êç6´ƒ§²¢¼GÜ“Bár¹Ã† 6lX·nÝ7 Ñh\.wΜ9��§íŸÛ‡Ã!,A[H$ Å©DÓ .—k6›ÛX1†)!555Ùl6ìSx<žŸŸßµk×Üï!Ù6‰ÅbÑh4ÇnŠíÅb±ØiY­V›Íæ&HðO;¸Uïl㦻wïÎÍÍݸq# F‹Åâ¹sçúúú^¸p¡WÐWSS³aÃ�@\\Üܹsu:Ý… ð7ÀÅ‹g̘ñË/¿`K ÅÚµk‰ƒ€àq¦Pþ ñõõÅÊòšššìÜ&¡Pˆï^¢A—¬¬�� �IDAThXX˜D"áñxX^µ+š››1·‰Ãá8fX„‡‡ÇÇÇûúúÚ-·kQÑ^L&S{‹¯Y,L>tƒH$2f³/èLðô=§M×nŒŽu¿ÑéÓ§oß¾]^^þÎ;ï̘1ƒF£<xpáÂ…C† ©¯¯饗`èFŒ±téÒ>øàܹs¼|ùriié»ï¾Ëáp¾úê«iÓ¦ 2Êÿ@AÕ;vŒ3fΜ9éééW¯^ݾ}{NNNEEEFFœŽz²üðÃnòÅ9Nß¾}‰k‚ “’››‹/AmjjÂjoCBB`'@l­R©T(°k­V«µX,555f³Ùb±´}Úd2UVV:ÊEÊd²èèh|Lƒ„§]ä!°ÌËý6X§à††E¦Ú<ãTf2¹QщÇ78 …pVó¥—^Ây.— ûJÄÄÄܸqƒL&‹D¢ÈÈHLrÛËË‹J¥öïßÿæÍ›p‰‡‡‡Ã�DFF^ºtÉf³I$’èèè””¸@  Óé.\ =Q‹ÆÆFW c̘1ØÚ÷Þ{ïØ±cß|óMTT\ò믿.Z´èÍ7ß|íµ×íÓSSSoß¾}ëÖ-:~õêÕyóæa«>ŒÉŸ<J¥?öÂ;vW>|Ê—””À‰«ÕªV«y<‹Åj»8¬Õju*d¬P(àÍ §>|Ó"þ1bbbòòòl6›Åbq_Ã$‘HŒF#¦  –‰k©C'÷«©Tª£o� P(N—c5äL&Ó.A§»ˆÅbø‚N§Ûm ‘Hžø¦Êõ¾ß: +¾±×Fؼ®\.¯®®®¯¯ˆˆ@Äl6Ëd²êêj¸B¡€÷6‚ P[O§Ó©Õj½^o2™ASSŠ¢ C©T²X,&“¹mÛ6£ÑH¥R¯^½šœœ<zôèíÛ·Ûl6NßkE§Ó=<<T*•^¯çñx0;öyÖá&xL\MõÛ9"---îC[!!!J¥²¾¾ÞÕä Êd²úúz,õ 666''ÇqûÈÈÈ¢¢"ø†d2A»Ær7àve¼¡¡¡r¹¼¡¡Z¦¶œ;!>›ÍF¤EtçñKÛlŽÿœºh)))Ð`Ü»woÁ‚?äb«ªª&Nœ˜œœüòË/÷íÛ·¤¤D¡Plܸ±_¿~‡~å•WÂÂÂêëëÃÂÂRRRŽ9Ò¿ÿÌÌL¹\>cÆŒÈÈȦ¦¦Å‹[­Ö‹/~õÕW™™™‘‘‘ÙÙÙ÷ïß?~üðáÃ_ýu™L–žžvêÔ©_|±OŸ>ÄÅJðÄÆ¤¸ÚX»å0¹ 'ØÝÅÅÅp‚¹Õž‚ÐétðWp§– �PPP@¥RaKh???¼¬%ƒÁ P(={öÄ–x{{ø‹#EEEð†uo™Ü—ptωàÂ… cÆŒÁgÌ÷Ýwžžž{÷î‹Å"‘háÂ…¯¿þúöíÛß}÷]»Ê¾ŠŠ •Jµ`Á‚µk×vïÞ.d³ÙLJJ>|ø«¯¾º|ùr¸|âĉ.\8wîÜĉ±p⫯¾Ú¿Ì¿$€«¶‡žž1§.†‡‡‚ Ž § ƒÁ``ùM‰¤¼¼Ü郾U)*•* Ûþ3ùúúZ­Ö’’’ææf›ÍF§ÓaXR,WVVâý›Ço‚ìããSüWÝ[‚Žhœ:Ne\$999--­OŸ>[·n8pàùóç�óçÏ ùí·ßÃo¼ñƹsç.^¼ÿŒŠŠZ´hÑŽ;ÚþÌ=tè]ßQ£F}úé§DÁ ƒÁðÜÊYùùùµ¥®{\ÅîT*¾bÉÐÑ@à%ˆ ×ÌAœ#q„°LÃ8¡ÂyrÉÒ¥Koݺµsç΀€€ýë_Ð8ýðÃkÖ¬éß¿ÿŸ²Z­555žžžË—/ïÝ»÷©S§��K–,!,­V[\\ spžOîÞ½NzªÍnBBBJJJþ&ÉfG¥; …Âãñ°IYˆX,–ÉdvÇ  Fmm-¡åÚé“–èî–ôôô+Vཟ³gÏ–––:t(44ô£>Âo|øðaG̶Ãd2W¬XQPP°gϵC³Q‚ ®Är\áëë[WWçæyM¡P¼½½kjjÚî¼þ“Ç/ûÅpš¹`6›M&“¿¿¿]S¡PˆÕtã´uëÖSóˆ኉'¾ÿþûÉÉÉgÏž…KæÏŸŸ››»|ùr.—»}ûöuëÖ]½z555õÈ‘#©©©àÑbâÿþ÷¿§L™2eÊ”††‡rîÜ9âü;B§Ó£¢¢žÛN¸·nÝJLLlïÌ“J¥²ó0„B¡ÉdÂ|ØZÂÇǧö©²²’L&ûûûc“¬þþþ*•J.—�¤R)ìNÀårQ}ü<r‹ÅâŠtÚP¡P( .—k÷}µZ-‘†×ÉŒ“§§çsõ…Y~ÞýLv\NB`ý߸2---555,, AcÇŽ�úôésþüy‰D"‰>ÿüs¥R‰ HDDDll¬§§'‹Åª®® üé§Ÿàôüùó0ô4qâÄ>}úÅÅÅ©ÕjtþüyX‡¿hÑ¢)S¦„††²X¬~øÞQÀßß?--mæÌ™aaaÄejÇóÜ ·ººÚ©Z˜{”J%t͇š]QQaWeµZ›šš(í ò[­V™L†ýÙÐЀyfØøL£ÑÀBàY³f;w®ºº:""âþýûð"'“Éõ­u‹ +))iWŒN*•:Jb>v�Ý8%%%íÿöŠ{‡ú/q .y´w»ö}œr F›8m ÌXu¿¿?Öî&Îq¹\,Ã_CÞµkן~úiñâÅiii°–D"!‚mìíí  aã�:Ž­õõõŪ»ìêpýüüüüüˆk” í¸*$Âü‡BÉ£ÑØÒÒí\ëííÍãñìRr\ƒÿ,¼/‹Y,wüøqX® =*�@KK vkãëœì(++se™¢££  ž°fTN)))ÁbÄfs×þõæÍ›|>ßßß?:::::Z"‘\ºt)(((!!á>¬°°0::ºí2zááá±±±OðÛNœ8Ñ`0È]Ъ²²+†¾jÕªmÛ¶EGGݺuËUÁߊË�0 wîÜ6ÀÇÇG­V+•J|ÁSmm­eBQ¶šEß&�ÙÆS«Õ¡¡¡øZZhT )..¶Z­°±ºn\ä¼¼<§¥¸yyy¡¡¡qqqÞÞÞãÇ·[±hÑ"âRéž“ÖÐzoòiÓ¦mÚ´ �’’2fÌè’«ÕêÂÂB‘Häëë[^^ÞÜÜM£Ñôz}~~>ŸÏ ªªªÂÜönݺùûûùå—0É­²²˽5@ …UI¥ÒΕ¢6cÆ L®‰€à©�kfÝûd2EQ½^Í-•––ºòN¤Réýû÷‹ŠŠ„B¡@ ¨¨¨À<$l"Ö(Š’H$8CæL …F£±¥¥%00°¬¬ ¯”ö˜`ouüøqGûíÞ„tãtúrÁ#ì¦Õj?~ðàAŸ>ø 33óøñã·nÝ‚ÑÞÁƒOš4éwÞY½zµL&“H$çÏŸÿüóÏýýý<mÚ´Å‹¯\¹²¥¥E$ýúë¯_|ñEbbâŽ;¾ùæ+˜<yòo¼Aü<mG*•^½zÕ}®Š¢|>Ÿõà>¿³(F£‘Åb•——Cû´wïÞV‰ÉdR(|æ—ËU((Š¢(ŠMY…GŽ å­§–åççþùçŸþyMMÍË/¿L¥Ru:F£yóÍ7¿ÿþû³gÏB ƒãÇkµÚ'Nøøøôë×ïÌ™3?þøcllìÖ­[.\øûï¿coxúôé_~ùåí·ß>|øð믿~åÊ•JÕÜܼvíÚÇ8ðÃ?$š(´‹ææf7¢û¼ÏäuÄ/ñòò‚ËQÍÊÊ’Ëåx}£VQ(v9u0â e'‰ŸŒÀqª¯h½¹–^¯ojjjjj?~üæÍ› †@ X¸p!¶ÁôéÓ¥R鯕JåæÍ›CBB¦Nš””´jÕª›7o®_¿žD"¥§§;}óuëÖ¥§§ûùùÍŸ?¿°°0333;;›øaÚ ìyÑöíù|>”¿Ã€¹<ØŸb±ÎH‘H$˜ÈWWW‡%P<Pó[«Õ:Mo÷¼%?·Pf°ÿøî7êÞ½û²eËÜoóÖ[o®Y³F$½ùæ›�€ž={öìÙó…^xûí·KKKåryjjª›KvùòåF£qòäÉÏsñ?Á?†Éd²ó´t:ÔÈ7 jµNaËíSx<žÅbyL“†a6›‰D»çÅsÚÿÅ'òFC‡åp8'Nœàr¹C† �œ>}z„ (ŠîÞ½ÛÛÛûĉNwœ?þ¼y󚛛ϟ?:}úô¿£Í Ás‰D’J¥ø%*•Êé‹Å‚Ô`}”1/…„<,‡"$$¿êP©TŽâ)žžž¡¡¡��‘HA ŸãôßëèÑ£øË¢OŸ><ïµ×^{ûí·årùéÓ§±U©©©)))«V­êÛ·ïÉ“'ÓÒÒÂÂÂ6mÚôí·ßöíÛ7222))iΜ9D×d‚vá>·ûË€µX,˜2¯^¯ÇL`uu5‚ nB#L&300°½§V««««ýüüètúÇYZ‰D"EDDWQ¡•‚ðnݺÛ¦³²²`õܨQ£Š‹‹±æ(ÁÁÁJ$��„Bá¶mÛ°A“@ °X,ÅÅÅ4ÍfÿûßÿƯ�Ìš5ë•W^·©S§Âú7ÅtÀ±cÇÜ”šóùüaÆaw>âÅܪ_X ;8m–C@ðwã&í-&&æÞ½{m©?mUM<,,¬¢¢",,,''‡Ãáðx¼ŠŠ »›Â©¾Œ âsÊa!°¯¯/,ÂÕétÐ Ål6s¹\‰TYYi³ÙÍÛƒ…ÀÅÅÅDå{ç0N ÅQ{êî��h4Öq£¾¾~ذavÓ•, ¯ÑI&“±w³[� R©ØZ;sø¤ÐëõV“™¬uRÖÇïâ÷Ê+¯`u¸K—.=pà€H$¢R©‹…ÏçŸ:uJ(:îxãÆ#FÌŸ?Æ �€W^yåâÅ‹D.Á?OBBµk×ìna«ÕjµZsrr¨TªT*ÅZ1a«ìÞ¤Õ”¿ÂÂBðgÁ¯R©t:ŸÇs®´Y±×Ъaï�«;ò ìIít-ÌØ‚CäúúzFÓÞSWPP@\?É8µ?üÐÛÛûÛo¿íà_U|ÿë¤OÚ˜[K­À~Àõõ×_ÇÇÇ×ÔÔDGG/^¼xëÖ­ÁÁÁB¡077W¯×ÇÆÆÂkº®®®¶¶V§ÓÁÛ,;;»_¿~*• $J¥R>ŸïÞ=³Ù™››+  Rqq1 `R(”GM# À°³L��ooo¬K“Éd‚Ér‘H¤P(\éß³Ùl­VÛª¡rF‰DxŠÉdêt:èÖP(2™Ü®øƒÁàñx­úU°ÿS[Ÿ¸a‚gÙ8=ó'ëÌ™3K—.ݱcÇ´iÓæÏŸ_TT”›› =îÝ»—••UUUožýû÷'$$ìÚµëСC yyyÇOKK›5k–L&Û´iÓ‘#GÈdòæÍ›ÍfsZZNçóù.\8xð`ÿþý‰ëÒ=:Î.ŽôüàæÎáp±3'øª&2™, 1QT(²Çår•J¥c( ¶ 5�A;…VOOO¥RéáááØ{ ‹RØýFB¡Kv÷ðððôôlii1›ÍxëH¡PètºS{©ÑhÁrìÕ‹ HCCÃ?Ü„à5NÏ$'Ož¼~ýºB¡ðòò6l˜cŒÂËËkÍš5#FŒ6lبQ£��ßÿýÅ‹?ù䓺ºº 6Œ?~ïÞ½kÖ¬ùôÓOáf³¹¾¾þwÞIII9vì˜F£¹uëÖ‚ V®\™™™yçÎÂ8µŠÉdzn“e‚ƒƒ©TªÓ‹ •x<^SS“ÉD>è´x¹n.—Ë`0h4šcC ðçô‚ \.—B¡`ÆÉÓÓS«Õ²Ùl•JÅf³]'Gðm0 mÓëõxSÄ`0Äbq»š¢Q(‡ÓÜÜÜîg…b0,Ëãw& ŒÓS¡k4NG&“i4ÚiÓÀ`0ÒÒÒ~ûí7øçˆ#ÄbñçŸn0ÄbñâÅ‹‰ÓîFsÿþýç9åäöíÛQQQŽjýµµµ"‘H&“Á4"‰„mƒO,b0t:½¥¥¥_¿~t:ý‡~p»³Z­˜â%¾'Œ@ßëÐjµ‚˜L&»ù*ƒÁ Õjy<^»­6.àr¹‹ÅÎ!#zÆ©3mÚ48ç´mÛ¶3gÎ 8ð‰ÄÀ3þ|Fc0V¯^Mœy7Éd,%‡À½^o±X ¤2>—VTT`ݰ`ƒAè3¡(êííÝcƒ7T*ö´ úA >÷ïc— 1íy˜ÍæVÅ&Ë ãôl²~ýzÇ{ïСCX‰†Á`ÀË;¹á?ÿùÏÙ³g7nÜxøðáäääü‘0Nî¡Óéaaa,XÐÙ¹qãÆ‹/¾èjß}t ®5 ƒÁËËK¯×À¡ÅbMlÛ…Åbillt<˜¶H¹úáá=Á3æé鉢(Ö€0NϳfÍ¢Óéf³9**jÓ¦M,+777##cýúõ‰ÆÐãââ222>úè£7Þxcܸq;vì3fÌ+¯¼²gÏž;wî¬X±"))©¾¾þý÷ßÇ â=zô÷ß?iÒ$ƒÁáp¾øâ â´· ò?Ÿß½®®ÎÕwß·oŸ«Ô;GP… nžù3I¡PH$RÛcòjµÚqJÏf³=r¿7‚¿Å8Y­V»Q N‚­i:é&“‰J¥Úu6kX V ü¿aTˆÿK´#‘€+°ÈÌÌÄ+ÕR(XÖ¾aÆôôt6›=|øp(`0óæÍ›:u*œ[æp8/^´Z­\.7$$däÈ‘ðX,Š¢.\€{õéÓ§¬¬ŒN§Óéô/¿üŽ=!ª£:šÄ®ÇkÒb±`NFC_|Š¢(,Ü6 Xc=¬.ðï ¸¸¸Õ®çmyz8úˆG%NÎß«‡^+ÆéöíÛÆ ãp8XyìñãÇñMÊŸ Z­V&“}öÙg{öìùúë¯1±†GàáÇ)))cǎݶm~¹P(œ4i’«Ç>*Í`0œ*tAs�Àw@Q_zŒ­¢P(v ÊNW1™LG#JðÔ1™L'NœX¶l™——WSSÓÚµkg̘YN÷ÙgŸmß¾ÇãÉd²={öŒ1âöíÛcÆŒñññQ©T&LX¹r¥F£;v¬^¯·Ùl<ïØ±cÞÞÞOüPét:™L†@ žøX%‹Å"“ÉsçÎ%NËßç“81Nm ÅNž<vÂ�dgg_¿~=>>þÎ;€ÍfcÕ ÝºuCQ4'''886{ R©T0�ýâ‹/’H$¹\ŽUb‡‡‡ãg¶sssß}÷]|‘à#˜••åØxfäÈ‘OJ™à™§¤¤äõ×_Ÿ<yò®]»–/_¾lÙ²øøøÄÄD¸öòåËëׯ_¶lÙªU«¦N:}úô‚‚‚áÇwëÖí×_Ý¿ZZZddä™3g ‹ŠŠt:]\\ܲeË<øÄFŒ‰kûobèСz½Þiú>Áßeß¾}íÚáõ×_/--}ï½÷V®\Ù³gOh‡BCC/^¼˜––6yòä©S§¾ýöÛ×®]+,,Œåóùµµµ?þøãÎ; °}ûö“'O&$$dgg¿ôÒKiii<¾sÏž=¿ÿþû7b†€€€€àù¹rår«åääìܹsçΰ¸Áh4nܸqÁ‚=zô™™™ûöí _µj•Á`¨­­ýî»ïöíÛ7~üø£G&&&îÛ·O(¦¥¥UUUmÛ¶­OŸ>ûöí8pàŽ;Ú¥5B@@@@ð¼xN õ A­l„©1b%ëׯŸ9s&�à÷ßÿñÇþùç¶wU¿sçκuënܸAœ}çÆ‰Öý︸¸ÿgﻚ¼ºÿŸìE a$ìVT@p H­³ŽV´j«¢ÖZkíkëªZëªZ\•ÖQ´ÕZ‹ÖYGq·nÅŠ"AV€�IÙã÷Ç}ßû{¾OBˆm>%ϼϽçžsϹg€â¶ÿ½‡H’éÞ½{K—. <x0¬”Ñ&œœœ„B¡P(DäEÊŽYFAAAffæ¼yóìcl‡vØñÚÏb1;|sEEÅ£Gºuë–””äââbå]¾¾¾IIIb±xÿþýb±øe|UUUÕG}dWÎìx;v¬}Ñc‡/]sz‘›ß~ûíùóçoÛ¶í×_]±bEEE ë1‹   ÔÔÔåË—gffÖ××ýõצñ…BñøñãnݺÙØŽÃßßûöíK–,‰‰‰©¯¯ÿî»ï€ºóæM@°aÆåË—ïØ±ãĉ555û÷ïçr¹cÇŽ‰‰‘J¥üñèѣǎûöÛoF¡Phwö±Ã+ëÕ§/Ó·g¯ÄQ¢ú&Ò0.1*((žÖëõJ¥“C¾o4a@­V ¢i4 6$4 œ¢R©D"Þî§0 Òh4†F£½H®Á`P(t:ÝÙÙY©TÂ8JËQâÊÝÚñª�j‘$$$€ÔPJ¥òï¿ÿ?~|çVOh fɵ¥¥‡ÃÑétHü‚€àF£6ŒL&ƒ`X Ì‹lRFFÆÈ‘#í™âìxó@¥R]zxóiµ¬±¶üq&Ñ`°TÒ˜@ €Ì˜pQ‰³4ZsÊôÀ)ý"Àãñ¦Ï9tè…:›ÞÞÞñññèƒÏŸ?܇J¥zyyan1ÅÅÅ4­ÍºÎb±¸©©ÉÓÓóÅy“] ³ä Wfh ‡ëÓëíÖvØÑ•J%û_¥*ê ±™<ùžýz > >+77wêÔ© 4{ccã¾}ûÂÂÂзhµÚØØØ^½z;wÎòK¿ÿþûíÛ·ÿõ×_}ûöµÓœvØaGÛÂiÈ!*ÿE žIr ï|‰éñß.E—iðàÁ_|áïï¿{÷nƒÁ°xñâ+W®P(”¬¬,pÁÛo¿VƒŠŠŠ>|~2„N§Ÿ8qÂÅÅÅßß?33³ à¿…á3224͘1c)++»wï8>hÐ ‡sôèQ‹% oܸa'P³P(¥¥¥ÿÎo·ç)°ãß"œ/^<鳕öŽÀàÀ999W®\a³Ù‚¤¥¥•––~óÍ7 111'Ož|øðáâÅ‹ÁÅÅÅÅß|óL&‹ŽŽ>qâÄãÇçÏŸ?kÖ,__ßž={=z\vìØ16›½{÷n¹\·zõêŠŠŠ¾}ûfddܽ{wÅŠsæÌáp8o½õÖ.\hN­A¯×wÍž“ "((¨µJ¸vØñF '{X‰¼¼¼3gÎ,[¶lÁ‚¹¹¹;v쀱_¹¹¹gÏž]¹råçŸþðáÃ~øaΜ9@7b³ÙëÖ­ËÈȸqã‘HüüóÏwíÚµ}ûöøøø˜˜˜?þ¸W¯^eee{öìÞÉ"‘èîÝ»ëÖ­ëÙ³§½ÏÍ(¾$RXXFû7÷iIu;ì° ';Ú@°iÓ¦ž={VUUݸqcôèÑ@CÄÓÓ³[·n?ýôÓO?ýtÿþ}x‹——×Ö­[í[S­Ò+‘èçç×¹Åèì°ÃŽ×@8Q(ËÞt¯ðxü«m�—ËmmŸýŸÿü'***99¹®®®ººg³ÙvÉd öÆ¥vØa ÇÆ §Û·o?xðàÍøÔ€€€vìÞåË——––Nš4 ”2dˆB¡xÁö̘1ãÂ… à·T*-..~çwz÷î keÙÑ®\¹róæM{?ØaÇ›ÂF<‚0Í §=z ƒp»À˜ÞY•vÍÆKáðx‹aæj‚rÖC€ïÜØ±c `4ÁüqðàÁõë×ÿüóÏZ­öêÕ«ÎÎÎNNNL&säÈ‘)))7nܵk—V«½yó&‹Å§àÂßÉÉi÷îÝ3fÌpqq¹zõ*‘Hܵk×òåË<¸iÓ&™L6xð`{%\³ˆmo2‘Î¥%Û§ö—×BÛ4¢’H$<o˽gÚ™6ÕZ$?2™|äŸÇ⼚ÿ²ä:qã¤ÏV¢3Dôèу@ tñ¦«^¯—Ëåx<žJ¥’ÉäNy;‡Ããñè ðññyçwZk:ÎÉ[�È1|øð€€�ëïR©T‡Ã¡ Û …N§Ãápl6Û6Ó=Èår£Ñ¨Õj:dk݈ÇãûõëÇápl¶÷ÐÐét---x<žF£‘H$[ðgŒ‡Ã±X,[è@ÐEt:ýÿdˆ0{iKKKk™^>|˜˜˜9K§ÈaLp¾··÷°aÃÌ–ÂÉ. lJ¥²]놬¬,&“ l�€ÉÚÚ]¿~= €ÏçFÛ\;w®OŸ>t:u¾ä�� �IDATÝÁÁDæÙètºF£Ñét6Û{hTUU•••õë×P²å$j]ƒ¿þú+>>ÞÁÁÁ`0ØBVVV–——þAÔv†x]0pà@¹\nçõvØa‡6|ÎãÇö^°Ã;ì°Ã¶„Ì c‡vØa‡¶"œÞzë­ŽÝYPP0…üüüE‹}üñǯü“fÍšµxñâ¼¼¼;wÚØŽ-þùçŸ)S¦\¹rÅFÚ³bÅŠ©S§Ú~¿O™2å·ß~³“ÀÑ£G§L™ò¸-ÛǼhÑ¢N|/±c~¢ÕÕÕÓ¦Msww_¶l8âááñ÷ß××׿ò®<{ö,Ç[¾|ù!Cì„eÇ¿ååå§OŸîðê³ÓqíڵǯÃ&‚»»û¼yó\]]í$õÓ§O·¹°8wîœõõЭҜ\]Ûý8•J•˜˜˜ŸŸ÷îÝþùçêÕ«ÉÉÉ0ñ6‚ ™™™Âÿ†v.ú÷ïž¿`ÁpdÉ’%B¡°¬¬ üÍËËKKK³ÖƒÉ“' …ÂN÷¨,//¢pöìYAFŒþΚ5 \¶~ýzxN§+((˜3gÎñãÇÁ‘+W®¼ÿþûB¡ãnÔY8}ú4|;H~/‘Hà‘~ø\6qâDpd„ ˜'$%%S“'O~-ܽ{7lH$B$??9räúâ'OžÀS'Nœ@ä½÷Þ‹ŽŽ®ªª …_~ùe'6ìÆB¡pûöíkÖ¬ …¹¹¹‰‰‰àÕ ›%‚ ß|óP(,((ˆ‹‹2dHIIIrròï¿ÿŽ È²eËÀÅ111‚<xð@(nܸqóæÍB¡x¬³?xð`A._¾, wïÞ ”¡P(•J+++a×íÝ»ÜòÎ;ï€#3fÌx©s ø}áÂØ’ÌÌLxÍýû÷…BáæÍ›7nÜ( _$¥ÞÅ¥Ý *•zêÔ)A† òå—_J$’ÊÊJ¨1¢OŸ>ÙÙÙÇŸ4iÒÝ»w;· PRR’½k×®_~ùeùòå«V­JKKWA¾jµZÝØØhçéoæÍ›÷å—_‚Jçûdooïììì;wîLš4©©©É`0Œ5êöíÛ·nÝ:tèÐÑ£GçλmÛ¶M›6­Y³&;;AˆˆýsõêÕììì·Þzkܸq .ÌÎÎÎÊÊœ¥qýúõiÓ¦ :ôÖ­[ñññï¿ÿ~UUUxx8‹ÅÊÎÎþúë¯üñǃÎ;÷ÁƒçÎ;þüÅ‹ÑBhÒ¤I—/_¾pá™3gΞ=;mÚ´Îmá¡C‡–,Y2wîÜììl@ ‰ú÷ïš=iÒ¤Ù³gÃEjMMM||¼P(ÌÎÎ?~üÌ™3ÿþûïÚÚÚÒÒÒ¨¨(•JÕ¹žÖJ¥²²²rÅŠ{öì«ê¬¬¬ììì½{÷‚Üÿ6løñÇ7mÚ´xñâ'OžÔÔÔh4šÊÊJ‰D²víÚ;w~ÿý÷ÙÙÙõõõ±±±jµº²²rÛ¶mŽŽŽ±±±C‡íôÒ-jµºªªJ"‘€–777777WWW·´´¨Tª=zxxxdggÏŸ?ÿ»ï¾;}úôرcoÞ¼yòäÉãÇ_¿~½s kh|ôÑGk×®•H$ÑÑÑwïÞ4iÒðáó³³ûôé3bĈ¢¢"ØþÊÊÊ­[·r8œ˜˜˜!C†<{ö¬ƒÂ©ƒÖ@"ù_”+æ”ÑhÔëõ2™,//¯±±Q¯×wz”‰^¯7 yyyåååF£Ñ`0 £ÑH 222`¡RS4555¶©Tj¶‰ÔÔÔ¨¨(AZ‹Që0p8‘H<{öì/¿ü²yóæ#F�Š%‰ ›Á`ÀãñD"‡ÃíÍh4‚ËÀpy Ñrt:=<<üÌ™3›6mš5kVVV–‡‡à%‰ãÇ/((˜8qâ?þxöìÙÆÆÆ¢¢"0)ÐóÅh4ƒ/êÜ‚þ!D"ñèÑ£yyyA¯×ƒâñxpš?€î§`ª‚¸¸¸¢¢¢ÔÔÔN§.—›ššZTTê…æåå•••a÷Ï?ÿtvvÆ|à*`d!íM›6mÆŒx<þe0·7nÔÔÔ$%%Á#K–,¹qãÆ_ýÅf³a¯NŸ>=??ÿwÞñööŽˆˆˆ‹‹S©TçÏŸOIIyIsp÷îÝ¡¡¡ @×566æååÉd2Ó~HNNž>}:œ,”2/éKrrrÖ¬Yƒ ÈàÁƒ;ýù:>_ X¹~9sæLkE BCCažÖ¼¼¼ÊÊÊ^½z±X,µZ}íÚ5WW×îÝ»[~>XyõíÛׂ€´�FsõêU.—izV&“effzzzAC*•¢ÕÓèèhÌ4³~bèt:L­ú7MMM?~ÿý÷M­a¶€èèèk×®<yrÅŠ©©©kÖ¬1k½yôèÑÌ™3ù|~kÏÙ²e ™L<xp›düJ@"‘>ü’>uêÔÑ£Gÿu„††ÚÂ6ù‹`Û¶mÀè=pàÀððð]»vuY¸»wïžìÇ{5ÂiàÀ»víºwï^~~~Ç¥eÉäÇ×ÕÕ?>44 §“'OZ6 ÉdÓãL&³_¿~0X:--mß¾}W®\éÞ½{CCÃøñãGŒqàÀË­ÊÎξwï^·nÝ:6T2™lüøñƒ6;KKJJÆŸœœ¼eËôñ–––mÛ¶;v,..A›7o6láÂ…°<‡õøôÓOåryIIÉ¿G2Éd²ï¿ÿþôéÓ+V¬°ÍŠD¢‹/†‡‡¯X±bÍš5_ýõ¨Q£àÙâââÛ·oÇÆÆnܸ±¸¸øäÉ“!$$ÄìÊ—N§?~ÜËËëåµöìÙ³b±øí·ß¶åA?|øpCCCFFFppðåË—áÊU¥R¡Ë[¿àp¸÷Þ{ïÁƒ¥¥¥~ø¡N§+))yë­·0Kü¼¼¼û÷ï÷ïß¿¨¨¨¶¶ö§Ÿ~š;wîÉ“'SSS»l¯}øðáëׯ¿yófii)¦hÀÓ§OŸ>}js‰ÃáL˜0!777%%åÒ¥K|>?!!¡s_‘œœ¼zõê”””ÊÊÊ{÷î­Y³&..îÒ¥Küñ‡‡‡‡eE›Á`€<"8::Z£^¿~ýöíÛà÷gŸ}¦Ñh~úé'@àéé ¨ÜÓÓ“H$nÛ¶ nÂÅÆÆÆÇÇŸ>}://A*•:oÞ¼òòò?þø£wïÞZ­öÁƒ|ðŸÏ¾ï¥¥¥çÎ:tè… `é÷ÖLɃaýúõ'NœX³fͻヒ ÈéÓ§Ÿ<y¢ÕjSSSi4Ú°aÃÒÓÓcbbp8Ô®æÏŸ/“É~þùçððp.—{õêÕÑ£G p¶¾¾~ïÞ½B¡pذao¼pª¯¯OMM /,,LII5jÔĉŸ>}ºuëV‰Dâãã3|øp.—uòäÉüü|™L7Ò»À\“žžž@£Ñ&OžÌf³çÌ™“žžž’’’““ÓØØ>f̘¬¬¬;w2™Ì)S¦Üºu æô|ï½÷>|¸}ûv½^ìØ1°ÚíDDDD 0àâÅ‹¿þúë¨Q£ÆŽ;uêÔ›7o¦¤¤Ü¼yóí·ß „«À?ü0333%%åöíÛÆ óóóë²ÎüðÃ‹ŠŠRRRD"Ñõë×׬YÓ¿ÿóçÏ;vÌÇÇ“enàÀ.\8|øðÝ»wõz=ôŽy©Àãñ«V­Šˆˆ¸wïÞo¿ý¶fÍšÌÌÌãÇóx<N7kÖ¬³gϦ¤¤Ü»wO§ÓEEEÕ×ׯ\¹²¼¼ÜÝÝÝÛÛ{äÈ‘]ÐHÑ£G?xð %%åôéÓáááÇG_ÐÜÜ|úôéüüü‰'vØrFX¸hñ±³W<ýr…ŠŽ(ÃüyîîîÀªhé6ÁÛÛ;..Î××—ÉdFFFÆÆÆúøø 8°wïÞÑÑÑL&“Á`…ÂäädkòI+•J‘HäïïO$Û4‹GGG»»»S(7nܸAƒùùùÒh´)S¦øúú&$$tïÞÝÛÛ;((H§ÓÁ§åääP(³ëJ*•j4aN¿óçÏ?|ø¸Ë777ïØ±#88ØÍÍmùòåD"188xÇŽ¥¥¥ÑÑÑ“'O~øðaffæ¡C‡nܸqãÆÉ“'755Q©T‘H´eË—æææ•+Wúøøxzz~ûí·:ŽÁ`Ì;÷éÓ§,ëÌ™3wïÞMHH(..þûï¿ÝÝÝGŽ™ŸŸÿÍ7ß8;;ûùùmܸQ&“ ‚_ý522í"¯Ó鯲nÝ:pD  0€N§O˜0áÚµk………{÷î}òäÉ?ÿüC§ÓSSS«««CCC§NúèÑ#vëÖ­þù'66öСCMMMjµº¥¥eïÞ½žžž¯0E=@mmmMMŸŸŸ££#—Ë·ÆjQSSC¡P8…B±œ§‘H$z{{GEE1 ƒçééI&“]\\Þ}÷ÝáÇ{yy :Î`0âããgÏžM"‘|}}ãââ¼½½™LfÏž=cbbètº››[bb"óðüùsggg&“I¡P,‡s8::vïÞÝÁÁÁ`DGGôÑG§OŸ>l6›Á`øûûOš4)***,,ÌÛÛ›B¡p¹ÜéÓ§³X¬€€€!C†ôíÛwàÀà”““Ó˜1c¬L”W\\ìååE"‘ M-Éh¸¹¹…‡‡ƒìÛ·ï'Ÿ|âààÃb± Fhhè”)S‚ƒƒ ЫW/x*,,lêÔ©ÎÎÎìÑ£‡õ6@°]ÔfïQ(”   þýûóx<A"##=<<Èd²››Û{ï½÷öÛoûøø©ÿ믿’H¤yóæùûû0 ÿþAAA4Á` <xÆŒ$) `À€l6;66¶gÏž Årk›››%‰··7‰DBo¿Yஞžžñññ~~~=zôˆe±Xx<¾wïÞ`܃‚‚&OžÑ­[7///2™ÌårÇŽ;bÄk:°¨¨È××—L&“Éä6™‚6€=—„„„>}úôèÑÐdddäÌ™3]]]Á)‡ôôôwß}wÈ!^^^3gδƿ\&“I¥Rÿ'¥¢Šúfµ²EZWe>+¹J¥zU‰_©TªÁ`èÄįè¬ä¿ýö‹ÅB[Ÿ1š4ëÍŸ?ß¾}}ûöe³Ù*•êŸþ1bDBB‚ ~üñÇÉ“'…úÞ½{À‚?tèÐ)S¦ìرãÆ™™™ÁÁÁ"‘hÚ´iaóæÍؾ}û_ýÕ·o_>Ÿïãã³~ýú±cÇŽ5jõêÕ+V¬8uêTNNF f½ââ⢢¢èèhWWWÀÒÓÓ „1ëiµZWWט˜˜ .œ?þ×_ÇSRRú÷ï/•JCBB Áª{÷î|>¿gÏžõõõ/^ìÕ«Wÿþý7mÚ´oß¾]»v;wnÖ¬YMMMéééjµzܸq ,€ql¯ +yBB‚Yclk€‰_™L¦'~e±X2™ÌuJ˜øõÌ™3cÇŽµ©¶Áį/Þ{GŽ9qâÄ¢E‹@µ –““Ó¹­…‰_i4šN§³©Ä¯›øõæÍ›#GŽœ;wn»t˜ø•ØÑ:¦NºpáÂO>ùÄòeqqq7n6l˜‡‡<\?·oßnVQhçæçç¿ÿþûƒ jhh°¦µQQQ .ÔëõgÏžùm=<<öïß?lذaÆ•——ðÁƒ ª¬¬D«ç˜e>‰Dêß¿¿}èíø— ÿþ8næÌ™ƒ ’Ëå´÷‰€hï Ý»w‡5Ô-^<==ÑG Űaƒƒ}}};öê;wnÚ´iãÆƒ žmÂÅÅÅÅÅí~B&“]nß¾}k×®]¹råÈ‘#‡ÚÔÔd\;ì@„ÇãíØ±C©T‚¿îîîö>yÄÄÄäååuŠóž]8µÏ˜ààà •JE"°§µvehh¨““Óž={D"ƒÁ`2™T*µ±±Q$áp8.—kö.<ÏårÕjõ/¿ü‚Žöpuu­««3«?‘H¤ÜÜÜN˜08•R(³%€Ñ2¬±±Q,#rêÔ)>ŸßÒÒâèèhù.;ìxSÁf³;àÚj‡YÉäÎðæ…“D"éâÚÌè�Ø–––N‰‡e2™˜bƒ�¡Í{½¼¼"##_)‰DŠŒŒôóó›8q¢R©<pàÀÑ£G Æ… ”J%8îòññ‰ŒŒ¤R©B¡P¡PLš4 AñãÇ/^¼X£Ñ€½¢èèèS§N=xð 22lÒúúúFFF’ÉdggçsçÎ}ôÑG ºmëÖ­{öìÙ³gÏŸþ™””´nݺÈÈHS?`>ŸêÔ©¹sç‚×-Y²„D"Q©ÔnݺÁ¢ïÓ¦MS©Tééééééû÷ïŸ5kHû4jÔ¨   +W®ìÛ·/222<<\¡P Âb±`ólÍÍÍ@šZ ¥R ‹·‚Hp[›ÃèùÕ®Oë2 ·F¬™2] ûo4m³÷Ð@ïŠ577ÛBI9P¬Óél¡Íî{™qˆ …7nÜèút \.·{÷îd2ùéÓ§ååå/þ@oo´CÄï¿ÿÞZ鿪L{aaa¯^½&L˜°k×.[n'pˆàr¹í @ åóù4íÂ… ›¬¨éììL¡P222l³óûôéC¡Pîß¿?hÐ [kpÚ"“É ¢ƒÏ燆†R(”ìììšš[hpÐÐjµW¯^µ‘.ŠŒŒl£L»J¥‚‰º&00FE¼ ‚‰9Ò§OŸÖ”Bôé²@(¶Ë[­B 0À–?M­V¿¤t±…^½z|•6Fc㽇ë°°0BÉ�òoÙlšN%%%¶éÛÚ\]]=<<H$Æø`j‹ˆŽŽ†;Ÿÿrp8œ¯¾ú*<<üµh-™L¦R©/þ½^¯ÕjMI¥ë¡Õjõz=…B¡²¯T*‡k3ÊÇÖ„™Á`èZêØ¹vÍǶ-œž={Æår_F®¤—�šJ"‘0Ñ»¦Iií@ §——Àøe,ñÚ ]l MMM òeä?µåååd2™Ãá€È×QeÏÊÊ #‘H$©‹÷§;Œüü|777ƒA¡Pl‘ ²QÛ¹všššêëë1Q7æ"¼½½_FB¼—‰D$©iµZLÖj»Ú›­VûâûF uuu _‰)©t%ª««9XË¿ŽÂ©  �Ć£óªØ8ž={2S¼mnhh¨©©±ríáTUU…NvÝÂ;ì°Ã›ƒ]8Ùa‡vØas°áÚaGÛH$r¹ÜÕÕ•L&ÃüO ÃÉÉé•·M&“Éd2‡c¥·½R©„Ý\.·‹½ôz}MM FVÍvA¡P466²ÙlÄfã0 ÕÕÕT*µµ¸ûW…ºº:FƒÉkP[[«ÕjÍž²kNvØasøý÷ß“““‹‹‹srrbbb’““ß}÷Ý9sæTUU½ò¶9s&99”o---?ýôSbbbrrrBB¾}ûºØ5 ¶¶V(~þùç¸7##C(îß¿ÿ5ZÓ…ÂÙ³gÛZÃÖ®]›œœlÖÉh„ 6R޲Ó4§[·n544 <øâÅ‹\.×ËË+;;;""¢±±±ºº:11ñŸþ}áííݽ{÷Ç—•• 0ÀÑÑQ­V_¸pÁÍÍ-66ö¥~íóçÏ-l>“ÉdÛɉ`7nÜ�)ÙlöÀ»øí :Ç‹‹‹spp¸xñâÅ‹Ç/ —.]ÚŹ|ù2Häáêê *P0™LÿëׯK$0álÊÉÉ!í8näÈ‘yyy«V­š9sæÆ?ýôÓ¯¾ú*..ÎrEŒ—„²²²Ç÷èÑ$=9þ<pRàóùÑÑÑ‚dgg%•H$6¬¡¡!++ A§OŸVWW[¨ùû’>+íïïb0�ÓCÄÁÁT­+..eÛy…ñC¹¹¹¥¥¥ýúõ{øð¡V«íÛ·ï•+WÀ)¡Pèëë;~üø¦¦&FHÅÝÝýÑ£GݺuƒÑ„*•êâÅ‹îîî111‚<zôèùóç‚àñø#F466Þ¼yÓÏÏ/"" (6–‘‘ÁápúöíkCÂéï¿ÿ^¸paÏž=KKKW®\9pàÀI“&Íž={Ô¨Qeee999K–,ùá‡&MšTYY)‹×­[wèСŸþùòåËQQQ‰dÊ”)C‡}Ù)¯^½ÚšG&‘HŒ‰‰Â)++ëÁƒC† ®2---ééé>>>mÖ÷¼råJQQQRRƒÁØ·odz²ö×É“'ëêêf̘aêþþçŸÂJÒÖ´Á,?~|çÎAƒ¼Ž’éÒ¥K©©©ýúõ#ÿý÷–-[ÐE­º�¿ýö[ZZÚ… &Nœ¸sçÎÝ»wççç ‚®W?uêÔüùóÇŒ#•JŸ<y’’’r÷îÝo¿ýöÀ[¶lÉÊÊZ·n¨@’’B£Ñ–.]êäääíížž¾qãÆW^  J¦£Gfdd®X±"33sþüùï¿ÿ~mmmYYÙ† ÂW_}Åãñø|þÁƒ7oÞܳgÏ‚‚AJKKëëë»X8íÝ»wÍš5&L())ÑétkÖ¬‹Å€éÑh´³gÏnÙ²%88xåÊ•MMM§NJNNž>}ú«RôwîÜùÉ'ŸüñÇ*•jöìÙ‡6lØÃ‡=<<¾ùæ›U«VÝ¿?//oÊ”)!!!ï½÷Þ¹sç|}}Ay£Ñ¸wïÞ»wï}÷Ýw eéÒ¥\.×ÓÓ3==}Ó¦M~~~S¦L™={öúõëúé§?þø#33ÓÃÃcÊ”)ýúõ;sæŒ ™õ<XZZºhÑ"L©’S§Nýõ×»ví¢P()))3f̸wïÞùóç‡ &~þùgP'›ÇãM˜0¡ †F£E™C¿~ý £¹xñâ¢E‹`™a©TºhÑ"kŒ ‡Z´hQ]]‚ ÍÍÍÖL¶oß¾hÑ"SÁùÇ,Y²¤¦¦¦¹¹¹°°péÒ¥KusíÚµE‹Yiù±Aìß¿ÿùóçË–-[±bEuuõ/¿üòªZ‚êÀà’H¤®UP(Ÿ~úiJJÊüùó >Œ¹�‡Ã}þùçyyyÇŽ»xñâÝ»wi4Ú_|±|ùr[Èê Óé"##9RPP°uëVµZ’’2gΜœœœS§N©Õê#F¬[·.%%ǧ¤¤øûûOœ8A‘#Gv½ÝiíÚµ'%%eݺuqqqZ­2½Õ«W×ÕÕ¥¥¥eeeeddŒ5*%%Å××wÆ ¯68içΓ'OþòË/ ÆÊ•+SRR†úçŸ>yò£vïÞ}ðàÁÇŽƒLH$~öÙg¹¹¹'Nœ8þü½{÷f̘‘’’B¡PÖ¯_ïåå5nܸÌÌÌ[·nÁç|ÿý÷ÎÎÎS§Nµ9³À¬Y³¾ýö[ø7))iùòåÞÞÞ¿þúkmmíœ9s`^©ÄÄĽ{÷¦§§/[¶,--M(ZY ó2¢šG—i1bÄ7víÚæååµlÙ2Ÿ?þøÚµk‡×,[¶ÌÍÍmÞ¼y {öìA$33AÕ«Woß¾½¸¸¨A—.]:~ü8¸kÕªU...555°×øñã[ËõwðàÁo¿ývÚ´iŸþ9FkllŒŠŠrqq9sæLFFƧŸ~zòäÉšššU«V-_¾Ü2zôè!C†¤¦¦æçç¯_¿þ«¯¾ š?>š€ ·nÝúzöÃ>åÕ{öì¡P(_|ñÅÅ‹<xëÖ­Ö†ï%áý÷ßÿúë¯?ûì3‰DÒÚ|üø1¤dŸ;vÌŸ?ŸÃáüøã÷ïß·…¡ LLL¼sçZ\Í™3&!0`@iié† ±©€Y@`M¥c[À_|1þ|‡êêêµk×^¾|Ê4üüü L¦p}óÑG¡`ÀçóGŽ9mÚ´{÷îÁƒiii...IIIÕþ—;Õ£¢¢`v2™œ””4oÞ¼ãǃÐâÅ‹ƒ‚‚>úè#6›½iÓ&ÛÔˆˆˆÀÀÀ«W¯655Æ?ÿüü^¸p!‡KJJÊÏÏONN–J¥üá‡>ÿüóƒ‰D`±2d‡;xðà¥K—®_¿þÕW_Q(”¤¤¤GM™2¥±±qÚ´iOŸ>MJJ"‹-BOQ4îÝ»WUU5dÈà…åìì<qâĘ˜˜œœœƒΙ3gçοÿþû|••l‰K—.½råÊ?ÿüsðàÁää䤦¦Âʹ[·når¹W®\™6mÚë¨?1âÃ?<~üø+¯Ïû ±téÒ={öŒ3ƯP(œ8qâöíÛ ÒÓÓgÍše³ß…Çã“’’>ùä“ãÇOŸ>ý·ß~Û°aƒ@ HJJ"‘HˆíÇàÁƒäryrrr^^^RRRDDÄkÔþNN£Fjí‰D›fË–-»té˜9L&óÖ­[d2ù¦šµõõõ………~~~ ÎÎÎ÷îÝ6L©TêêêzëÖ­o¾ùÞÇ9�� �IDAT2éÕ«Ì…U[[[\\˜žž¾eË‹õý÷ßïß¿?!!Áßß¿¨¨˜-£ïÿ°qãFp$''gÇŽ7oÞܼyó¡C‡‚‚‚JKKE"äb½{÷–H$¹¹¹àÈ„ Þ}÷]:ŽVÆ_#ôíÛ·{÷îË–-{üµ:YYY*•*>>ìT[žƒ{öìéÛ·¯\.?v옓““-;OHHàr¹Ë–-û믿JJJD"QdddBB‘ˆ5ð¬X±âáǯ¤—.]êÛ·ozzúëB0Z­öîÝ»NNN€áXs‹Á`=z´åkþóŸÿìØ±#66öÖ­[_}õ•^¯ÿã?:±åcÖûþûïkkk‡~úôé^½z!B ¨T*¤ªëׯwëÖ-44T§Ó½ýöÛ~ø!8þçŸÆÆÆÚ`’¡o¿ý¶¢¢B£Ñ¨Õjww÷?ÿüóÚµk‚¤¦¦þüóÏr¹F‡DGGï߿ߚT„ÐÆ`0 4ˆD"YŸìù¯¿þzüøñèÑ£{÷î b&öîÝ;|øpPZZš˜˜H&“DPPPcc#F7[àÊö±sçÎùóç4‡Ãñùü•+WvqˆD"•JÅápׯ_ …€’'OžüÅ_tqKŽ9’н{÷ÀÀÀýû÷Ï;ÇS©T¸Úºuëˆ#†úí·ßâñøœœœ)S¦H$F“••Å`0ÒÒÒ.\xæÌ…BqàÀààà®l?‡£R©@½ŠÇã322z÷îª×ëûöíûñÇ#RSS3cÆ "‘xéÒ¥øøø©S§îÞ½ûùóç›7oþî»ïºX ¸sçNttthh¨V«MJJzï½÷F ˜‡ ûý÷ßÉdrEEEJJʶmÛärùõë×AÂâ®ço°cqtt¼pá»ï¾:uêÔéÓ§ÿç?ÿQ©T€ƒÁæ[™L¦Ñh7n9räˆ#V¯^Ã᪫«gÏžM$õzýõë×a±X2™ŒÅb…††Ö××S(”Îõ·êá¤P(RSS=<< uxܸqãÆƒ°X¬²²2Óår¹Á`°Áz:îáá1räHF ƒþæÍ›·`Á‚ÚÚZ¥R ªg‰DSÉã4щD*•ÊÑѱÿþñññ'NœØºuëêÕ«[k‡Ã¡Óé555ݺusrrÂ2  Õj£££cbb.\¸––¶xñbxAEEÅë’½·M0ŒóçÏ¿ÚÅ ÜL>µ¯ L&½oôÎ;ïÀß@«(,,„SSSÑU•IJJêÄö‚ÇãÁçÅ‹CŠ5Ýùé§ŸàoOöÅ_tý‚�AwwwLL…B9uêæ² €2ž¯¤zÓêÕ«!cÁáp111ðìæÍ›M›÷å—_~ùå—ÀŽ ©hûöí¦o™9sæÌ™3Áo°v·E³Þ/¿üwêÔ©{÷îÑh4+ –Œ3ÆÓÓÓ6«lÛ¶-44ǶèìììççWQQqçÎÉ“'O:ÕTï d³Ù=Z¸p!8Âår}||ÊËËïܹ“”””œœ |c¤Ré;wôz½»»{aa¡Y7ªeË–Íš5kÖ¬YçλsçγgÏLwbñx|TT”\.¿sçŽJ¥òðð(..…"/^œÍb±lÄ{Ø;ì°£«5'°üù믿INNF;ìYÀ… ÂÃÃ7oÞÜÅÂÉúýÕ„„¨¨öéÓgÓ¦MHKKóöö^½zµ££ãرcÑu,X`4Ïž=»ÿþ/¾øB ÄÇÇoذáðáÃiiiAAA6làp8éééË—/OKK>|øòåË/_¾bêŠöÍ7ßàp¸cÇŽ!âëë»k×®œœ&“9vìX°¿E >¼pá´´´ÄÄÄ•+Wfdd€%Þ¾}û/^üÉ'Ÿ,Y²äüùócÇŽÑŽƒ~½êuÙa%âãã}||^ßQv؆™2íåååQQQ¯]É :®ÑhЉåÉd2NG—i?xð`LLLkÎoL™ö±cÇ^¹r¥¬¬ _k€2í «„‹FYYY]]]ll¬)©t1<xàèèÀd2årùëX2ãØ±ccÆŒû¶>e—/_îÞ½;—Ëe±X¶¿>+//¯©©éÝ»÷+'×.@eeeyyybbbeÚß`DEE…‡‡·6a/Ón‡vØa#0/œh4ÚëâÖ…ÇãaðlNN âCÄÓÓ3** }±@ x]ªv¾þóŸÿLš4é5uÌ3‹§OŸ‚q/‚––˜ ûñãÇ0)T×£±±ÑÑÑü¾uë&¯Êk•J~455ݾ}ûµh3ÌÅ®Ñh^Æ~碥¥æ¼òä‰5'¯/ …i¦y¢Yõ‚J¥¾.Õ-ùdÕj5ÇC—0xŒZC\\ÜöE|>ßÕÕõÅŸÜAx�¯àí …ÂßßÿÅ+Ðw=‚‚‚ðx¼Á`Àáp¯‹ÇMPPà jµúµh3$W77·7ž›™.¦±Â‰J¥úúú¾¦Ÿ÷ÆxNÛa*œ:7„ÂvHå ð¥|]ö§Ñx]Rý«8Æ—+œ.]ºÒ7˜X+uìÅ/r/ú!F£ÑÊÍ¡aÆÙ9û�ëóãp8gJiÖ˜mRW»(¹]ûʧL ½Õ±N°þ.+½c-!F£±í'ÀwW¯×wbm}?¼<Éäç :‚°Í §Ã‡cR½nfñÐÐв²²Žåa ‡yt: oo簾& >u î*Mž<Ù.œÞ ìÛ·/''Çö² b‚ Éd²OQQøK"‘ÌÎy>Ÿ¯P( …V«5¥d2Y§Ó‘H¤ððð‡‰D³¦o<>ñìÙ3‡9Õ)ÚÐ.nååå%•JmÇ9-,, ÄÛצZHHHQQQ›é½1O ËË˳†Õº»»k4L.³Ã*`­&8x<n¿Aê2  ÁݺuS«Õ ÒG»xt¿~ýJ¥º|ù2:~Íß:�²ÇlŸ»»»kµZ¸-÷’Ö% o@k|ýõס±Ão>­þïõf/rpp€ƒÁàñx ‰µB¡°~bP(tÞŽŽI&<ViŸ?Ž‘L$ ]gÚÓÓó•'®¶ãeƒD"a `7•B¡P©TÓôJ&A\]]ÍV4¯®®–H$€Úñx<ÚîêêJ¡P¼½½år9™LqffÉÞÍÍ þ}òä Ö¦ÓéÀfN¡PÐÁv"72È]]]-WU7ÝU®¨¨x’ÉÁÁ¡c7ÂL,ËÑÑ‘F£™¦ÎC#??ßšÂhëâÓ§O¡d"‘H, ð"ƒ±‰D¢Ö$z˜ CAAf˜x<ž¿¿?†áp8xYNNN{%P_ššš***0‰7q8Uì0Y,–ÙS"‘è%I& Mðx<—Ëuqqió7{ÔÙÙö¸L&“J¥`––——·&·Ùl6@@ÓN7ë0F¥R­w$Ããñhô8ã =OJJJ^Çíe;Ú†¡ oP©T¢—™­A&“YP_¤R)à†D"¾…Á`ÔÕÕ)•Ê¢¢"±X¬R©Ì&1" ¶ÁÁÁ½>Óét2™ŒJ¥º¸¸ e @°ìA¥R¿«¬¬ÄdPÄ�º#¶6›Úë'Zþ‘H$‡ó‚ѾMMMb±˜ÉdvJê9©TÚÜÜL¥R™L&zà�µÀ刳³3LBh Wµ<L  £Ÿ‰D"£Ñø"™ÔµZíÇAég4«4ÅÅÅÖ<Á`˜­‰#‹M%1™L6]jXI*­½È”&‰D"‰Dª®®~Qáôüùs½^ý£¤R)¨m$ ½ mjj2[r†H$Z&G6› ?X§Ó™.„]\\ðx<x—\.G»Ûño€L&ÃP…–Öcà‚Í¡Èd2š—UUUiµZ777FÓ©‘Éd¸À7«u¹»»£× ý"•J%‰H$’L&C�´Z-&oP’Xi677[¹ªEg°¤ÓéE $]Å0ËŠ ‡Ã|/…BÁãñååå²?QWWƇý C&‰D*&@ Óé@v‚Öœ^ÖG³644 ‡Éh4B ‹ÅÝ;‡B¡@n^Šî±¸†J¥Ò§OŸ¢¯õ]D&“!ááñxËú Hö /•Jår¹x<Þ”TZësËôD¸ÑhDÏ&4‘[è¢N³€ÕÖÖêt:Ó×›B.—C¡Åãñ¬\È0™L´3¥Ñhl—¶ãÍšQRáp8€q`x¨Ñhª‚ AAAˆ¹}`Ì‘¦¦&(ÿZ#r£Ñ¨ÕjÑñX è Z …âââÒÜÜlÖÎÆ`0Ð2Òë÷ðð° µxzz¶ö½^+ª´ù�>Ÿ™hb±˜Oðx|×ÔJG‹Å‚†)L?Èd2é_­VWUUáñxWW×ÎÚä7ûœêêjp}V,;99¡¹v'¶P4P©T>Ÿ–…,K¯×+ ww÷6%°7@u ¶Ó”TÌB"‘X_Z¡½ÝK´¼¨±lZa³Ùð¬·W²X,‰®W(¦mkSUb»Â'KJJJJJììûõƒÁ@g™âñx………˜g ­‰DWQQHE¯×ƒ52fŸ ¹¹ÙÍÍ-00Ç744àp8ŒæëëK 0ôÏãñšššÜÝÝ[S ƳgÏ,|”^¯·ð ˜= r³¤®P(4YÓ"d– €�m:¸ººšM±¸Ik¯ðóó³ÜfŸÖÃA·½nÊÕj5ìF<ïìì\RR‚Y ´«mnnnÍÍÍà3õz}CC“ɤP(¦ÖF£ÑhœœœŒF£D"Q*•pA­VwJì¿Ñh¬¯¯'‘HŠT*Ch‚„î<J¥ø *B3ÞÖt5ÐZ´a“N§›ö‚‘ìðÉf»¨ãé‹4Y)b †í°þ f5ÁÁÁèdï^^^fw­ì°e‰DÕ‰D¸RXX˜J¥ª««c±X˜½^¯¬C*¦ó‡ÉdFFF:99) <6{zz666ŠÅbSÕ´A,F*•êêꊑ mNTNgêh¢×ë‹ŠŠ¬gaMMMf}öüýý+**€!ˆÉd:88˜Ökpppàñxh÷Ë@O%S^ÙZ©øÎ;nZ5};Z\étºÂÂBpÄÅÅE§Óžm3í" ë� H;xJ¥RYذ„ �œ@ øúú¶¹8F7.ý¹\®Ù T­V«ÕjÁž‘˜~€]„á®hÆk½.88X¡P´VòC¥R¡—S¥¥¥ƒ�Z[д tøN½^oO¹¯¯o}}}KK ô‹}©ÉZ€³;ú…B±çi~žHJ¥8)”––R( ¾˜òJ4oòöö–H$|>³‡Ìçóœœètº@  P(¹¹¹è=çÚÚÚÖ"K�µËåòððð§OŸbŒÁÁÁíÕ ¾õäÉ“öÞe6𢲲ò‹––³ë9…BÑ®zTKꊹ«îì|>_¥RÕúi`—š\>@ièÑ£òàÓL»MT|>Ÿ@ @ñ�OYf_¹e0¬ñÐijjÂèâjµÚ²UM"‘´—­µ‹ñêtº’’½^ßÚ]:[```]]Á` P(›V §ÀÀ@‘Hd=Qzzz* 8öð777£Ñm ˜ €¯!ô ¬®®¶l— P(>>>è•NPPiVÇ‚àì°M¨T*•J…Ãáx<ÞóçÏa„)¤:À 1£_[[Ëáp´Z­B¡P*•½ÊÓjµ!""¢  �˜! �Ï! €͆³gÏà\e³Ùl6ÛT&“Éd2«ªªÂÃÃëêê¸\nNN7]³w̘f‹è }öì™J¥2 @êóù|µZ-‘H ƒ…ÓŽµþ,Zj¶÷[Lì`,,ëd^^^ÍÍÍP“P*• <Îl2¦‹€H€_„i@Çìr:±Ò¢ ÛæâââååU^^lqèÞ6ÛíL&“Ãá˜-ëj68ÝìðƒF£Q­V[–t&ÐKÅÅÅè·[ðñ¶ 3ï...æóùÖì¤AÊ’ øÉÀúFµµµuuu&ÌJ¨Ö0™Ìnݺ¡ÛЦÅ\­VcæsQQL8®MG;^_H$Àúù|>Ø Áápt:º~¨M®®®uuu?~òäÉ;w²³³‹ŠŠÐŽI¾¾¾EEE «ƒÁðððàr¹0F"88Íæ€·’——WXXœ2R©J&è¸E&“ EEE…——ŸÏïß¿}}½N§ÃP2í´ÆW úY‘H$ËŽEyyyþþþè#ÕÕÕ >>> 8 mPEÏ} i~Г½MÝ^�Ó[ †§§§ÙGáñx2™L&“E"0Õ"ÿsM\ÞÊ·ãp8X´¾Í6ƒaê0 ·6¾T*’k}}}VVÜ%j3åRss³YÉ̹À÷ ð@@EÐïÎßßü ÑhÖ„Ua\¯1|¾°°°ÃûmøÖŒ¼(âááa4-½øzëi4šNô'‘H­ÅHÚñšÂÁÁÍ Èd2ˆ·•Éd|>¿  €@ øùùùùù™ºz_ ¸$'ÍÍÍ™™™'Nœ‰Dt:ÝÇÇ2‹’’µZ bEU*•X,®««ƒÄ‰É;Àf³™LfYY°˜6ÛÕÕÌ^FSQQþ:88¸ºº:;;‡††š åááÇãA|.&Ò:ˆS©TDÂápÚŒ4­ƒÖ¼*• ̓X,Ú-Öì] Ø9:aÚ€ï•ËåÏŸ?§P(¦ëN°CÃápœœœ|}}]]]A˜Ž———³³sk®ÿ˜/©†,xL‡Éì):ŽV ÓƒJ^kÊ WLdNkca½aóÀi4‡Ãa³Ù...D"±¨¨0…BD•JµüÃårÑí$‰À%ýÅÇýE]Éi4l&�–N§› ™LFÇ^”••ŽP©TÖg­·o¼x…;l,‹Ëå‚H[È—!;&5N—››ûüùsÓˆB­V ¦¨S]]—————§ÓéÊÊÊBUUƒÁ`³Ùb¹\®““‰D2͹€†X,ûØŽŽŽf×ÑpcáÒh42™ ¢� ‡ÃÁ$N­ªªR(`6Á©îââÛæìì ì ---Àú$‰^¤N&Ú?¢±±±MÏ[L Xû8޹èN''' Z:²Íp ZZZe2™B¡`0¡¡¡^^^l6»¢¢ÂÛÛÛÏÏ 0L˜Pe&“Éår­·¡‡Éì*ŠË境p1LÏ´Ï1ǹ’Éävå{%Vf.n{ð¯\.¯©©‹Å:άÁ‰N§[0DUWW£÷zI$—ËÅ´Ü4”Ý@äf4™äF”H$šêÅ wzõÑØØhvÉéââÒÐÐÐÞí"WW×úúz{ÙÀ7 d2¹ºº '*•ŠÇãͺA·´´X¼€Ó�!‡#“ɉD.—»¸¸€èFC¥R“®•ÛÈ`[$Iû"L&<ù_ø¤D"!“Éb±¸¢¢B"‘èõz ˜òe.—+‘Ht:F£N‰8ŽÃá€À©ö.¼@¾A‘Hf•J¥P(Ö8ÊšMNNNõõõvk2kr·l„G›ªZód2™~~~ÎÎΠך——×Ý»wU*U~~>H þT*$’�¿©TªD"!‘Hµµµ¦Ö'‹¥Óéh4ôÙ³ÒléÌ2=+‡É2%›#f‡$p‚kŽÖ\-ZÛÏk3Þ� ¥RiêhÒ ¶H$Òëõ`v¾p²°^³Æ9ÇÍÍ d‹!“ÉŽŽŽh'œŽy1Ø}ÞHˆÅbȦ”“ ‡ÃQ*•`æWW×Ö<_ÑäŠæ¶:R]}}}PP(fÆf³ y<˜íÎÎÎ*•ªMƒö¾›nnnMMMx"�(‹-±MÉÌ¦Ž­ºLwþr ‡óðð0u[0;›^på§×ëkkk1ͲK.—+—Ë­‰!a2™ÎÎÎýúõóðð0 `Lóóó1‰¦À‹@5,Áì—‚q*•*//¯5×///´Õ§Íd:ÖS» Õj[“:íu Ã|‘5ðð𨩩ií-ƒ31Åb1Ô_µZ­Y¹Øª*Ù>µ¾¾¾` H§ÓÛÜòñôôM`Ib00^vP›À7ÛÕ¦7ÁÁÁ`yE¡P¸\.`Ö*• .á1®ää“R©ôôô„‹5v¤\\\är9@R©4::šÁ`�¢:¼¼¼,çL3 --- o‚\.‚0µúúzÌoÍÇ666š.Õe2™YNíììl9;NSS\ƒoihhÀx‘™õÎ5;›$É˨DŠÃáüüü Ù¬@×áñx___8L’H$À¦ˆD"—Ëe³Ù\.d…`2™fu@�GP­V*R*•f/nnn‹ÅZ­V*•‚Þô0½ö¦Hðöö6kp “•€”ŒÉSŒ&ˆª*‡··wkcÝÝÝétº\.o/ãmhh°ìêÙªp2]Ý´ h�.ª–/¦P(D"Q&“Á0Ÿh‡4 ‡Ã „¸|KK‹V«  ‰½)ÕæÄðóó#‰AAA@­qww—ÉdÀ}èô………b±ø8) Fƒ™NNNN¦¹Î´Z-š477Ã[´Z­^¯Çp·‡\.o/T©Tèµ …pÚö²]k¼Z[ÝC¶¥¥E.—Ëår°ò�™4 èXwww6›-‹¡t @>Ù'Ož�q‹ñR«®®6eˆ€ŠÌ¶J*•VUUÎÚÀãñÀ úùùI¥R©TÚ®Š‘ å5ú €bu:]g¥7%±XÜZT«D"Q«ÕR©tpª´æ-þþþ–—z­šõ:1 Þ¢×ëÙl¶³³³iú;vóùóçd2¹oß¾õõõ<ˆC4EPPzÿÙÇ·°0qtt|ë­·ìbÀ6A¥RûôéÓÜÜl0Äb1zŸä)FþÛ„ Dzó2¸¶¶V©T#xyy¹^¯¯¯¯©Øš››‹ÄápÀ_ÞŽ1ëa ×Ož<Áé<ÏÝÝ>¾Èì‚Ð`k²SbÐ=öCçŽQMMM¼|MFTFNçïïœÄb1´€©Õꘘ˜TUU¹ºº^»vÍÝÝB¡Ý¿?$$“õ ³~"‘(  ººÍѤ‚¶I‚AAÔ3ˆæD?ÖÏϯ®®Î”…zyy"fåºD"é@qØ<Sãš,ÛûXÌ] Ú~K @þ¤­Xé6“ð_+ill45ãÒéôððp …Á`0ètºV«ÅãñRÉd2 JÌZLJ……¡»Ï××$ŸµLýzŽ 6³laó]G éiÁ‚û÷ïg³Ùh|âĉ$iëÖ­‡4h]`tüýý/]º¤V«õz=‘HÉ{x<È'yøÒb2™LƒÁ ‘H"""?~ h¦©© RNN@�œ0»ÒÒÒÿÎ "1++‹Édº»»c¼ª"""rssÁ"C“¹¹¹$) ??ŸÏçûûû«Õj0 „B!hƒé¾ ÍÍÍm-‹@§Óy<Ü—&ƒö0rXŸ_€J¥zyyY“ñȬþ‡É¡¡¡Ðƒô òw¼@t'4R!¨èÎÜÜÜ€€€âââÊÊÊ   ÆÆÆ–––ÜÜ\¥R jך®G 9ú¡´´4$$„J¥fgg·ÙEðZ­6<<œH$>zô}AYY™YWeeek¶¯ŠŠŠß@á‚A7í-¤:§Ã…a1÷Í´­MŸ¢©0°2êÛ=kCÄãAð⯩©ÉÌÌT«Õ¡¡¡ ¼€H$âp8t£AvKOOOÌÚÄ`0`–`HAQQ‘õˆ,U{œ4# GÝÿ€ÑK$­V{ôèÑîÝ»#ÿsAqvvÞ»w/Ì«˜ŸŸHœÍf{yyÕÖÖÖ××ûùùUWWkµÚ°°0`€Ëy???ƒQPP�Â<5 `¬á*• NB>Ÿq2þ×¢´´T.—‡††ÃÞƒ[¬T*U­VCzƒ [???¥R ûÓÉɉÅb={öŒJ¥ [PP:®Ä!ªTª€€€ÒÒÒÀÀÀœœ2™¬ÑhÈd2X5c¨ŽD"u=hƒV«ÍÏχæ#°] ˆ…„.ƒ2£ÑH&“ ƒ5ú'‘HÐÇŒB¡hµZƒÁ@£Ñ@„ h9X°×ÖÖBÉÔÚô´°4¶>ŸYuÊÂYбyyy4 ~5ð•»tÀè L$ñx<ø(¶¬P(@óŒFã³gÏÀt ðàAii)@€K´‰Ž;è2™\^^nš\Ž;ú8lX‘˜Z2[ë[p’+z;e§¼¹¹ †††–––ö>$Æ} O×h4&·ì^77·––05h4šZ­F®1á�� �IDATSòÿ§p¸R€ýÞ)ñS­Ç333êJ$A’ A ÀŽ®ƒƒƒ©Ã»B¡°Æw–N§‰Ä‚‚‚—á°———7`À€-[¶À#wîÜ:tèªU«æÏŸÿñÇìܹsÀ€iii)))C† ¹uëVSSÓÖ­[?øàƒU«V7î—_~Q(#GŽ<uêÔªU«fÏžýÕW_¥¥¥­ZµjäÈ‘GU«Õ3f̪U«¦M›¶aÆÎM ùº#//O«Õb%Hâ`6ì$ì[2™¬©©‰B¡ðx<:ÎårkjjÐÛ¼ŽŽŽÞÞÞT*µ  @§ÓS©TG¥RÍÍŒÂÍfÏ7wwwL¤R)ô20u/äŠ9ªèZYŠ“D"ñù|x±‹‹ ØßËb± éæôrtt­Åd…�¢ÎlqÛÖ¶Á[&V=LfÇÈËË Ä�¡w†Äb1 |WWWt/ÑétÀ(ÌöXx{{{{{?|ø‡Ãyzz¢³{  sÄÕÕÕÛÛÛ´åÇ”ÂæA1Ðf·€˜qð wuu ²¾òª˜ÓóçÏMíŠ ŠÀò£Ð*l‡wPãÌ@]h¹êêjhÛ…�ÍÖ©Âß¾}ý_$uV}³ #F“H$Ïž={úô)Ì6Ãâ$I‡‹c:88¼HõI³ÈÈÈ8pàÀñãÇMO-X°@©T9rdíÚµ·oßÞ·o8~ëÖ­µk×âñøyóæ544444¬\¹òÈ‘#ýúõ[±bEmmmKKË–-[Ž92wîÜ'Nðx¼#GŽÏ™3§©©iáÂ…QQQGŽ™0aÂîÝ»ïß¿o—Imš2Ð OM4'‰äâââéé<¼{öìÂáp©TªƒƒC]]]~~>tL÷÷÷Ñt:½¶¶m¬€±±J¥Øâ`89zÓ:Ñ ofÉ0Á¥!ÔEP‘¶­à€ÑްFø^µZmj]qvv‹?SáD  ƒCW€ ŠÈd²•RŠÍf›NžžžÞÞÞ¦ò T%vvv†6U4Ã1gè‹Á6(wkú–ÚÚÚüüüüü| WWW;99YS—¨¢¢Âl=øššš6ù¡5Õi) B€T@¶-5üâ³À´ð&ÒÖ¬pj­Îø  N‹Å°ÚHkƃââbµZ]QQË=ÿÿæÍ™3çÅ[ãììlM.;òØß½{÷Î;@•pÑ3Ò7,Ê`0,Çêƒ*ÚÀÆÝY½,‰ž?ÞÚµ^¯ß¸qczz:úàgŸ}K¯Ι3§¨¨hãÆÀÚc¥ kãÆ7nܰ +ÇH­Vûúú¢馤‚ÇãÕjµX,÷Ýw'L˜àëëëââb4A­6¨UÀå-4•À DÀãñp8Hgg!]&“¡×Ë’MÉ.Å€‹xäe Å,³ .á1©Þ E}}=‹ÅBOøÒÒÒúúz‡¼dÑkv­V Ý—Ðpvge…ªªªÖ ¦~\õõõ …Â| &‘Øšx®­­…ûð %Ô}ÑF¶6÷º^œ1_„¦"È=JKKÁˆ ¸ŽåëC‹pP „D"™> ãsÑZôk{üJ�ã¥P(@UmhhhWJ{ÓÙDܱc‡éu v×ÊçB]›Â‰@ X0U1™L€qÉÍ€qdîîîèÁ�‹A¨'¾ NŠÆôéÓÁžSVV–ÙÏáp8góæÍaaaçÎÃ\PRR²téRAÞyç뉀D"q8œÑ£G=:<<Ü.~Zƒ£££^¯ú»»;Ì#€9Fƒ²²2µZM$=== †@ `³ÙåååÀƒÜÔI£ÑÔÕÕùùùÉårH±€u:e®G§ÓÁ²Äá”——{zzšõÅÒjµ‰„ÇãÕÔÔ�nRœÕÔÔÀ«f-Õ˜ÐE³[;¦î�F£Q¯×ƒz²­y£ý2€ÄzÁry\.·¹¹ä‹2àiV¹Áps`b•J¥˜ãà‹à� >Ÿ_WW†©¥¥…Ë嚨 ÞéþŠíâ‡fo4{Ü”éa�˜•Je2™ ö`kƒËápT*PÍDw¸Ù  èáh0ž±‚ࣣ£M¯»Ö?W*•ZãϪ×ë-ËRFƒ™°‚™LÊYKK æã13§ËöiðxüôéÓû÷ïùòe³õD"Ñ•+W"""¦OŸn}P³——×ôéÓœœ._¾üJÖ}6>Ÿ/0 +µZ ©­˜* hŠ5ÑAç»B¡�ž æÎ; +Ð0Ð"ª®®N"‘¸¹¹¡ÍY Õ–#‘H!!!Z­–L&E­Vƒj=NNN€’]\\ n ÈÎ @É@éDÞªžT*U ¸¹¹@`SY”HÌ)Ö®²ëV^ ¾¨²²R$uÀ[ò_PaÖtBí°¹¹Ø3!ûÒétf¬õz}ö/ºuë4`__ßÐÐP³‹N©TjÙ- Àlïa2€`d³LÏT ˆß‚ç·R©ìÜŠz< mèXZP¢㕎ïÕ«æ:___FÓéy@ÒhËÂI­V›RN÷ööqyÈÿj„cv/÷¥b÷îÝt:=11ñÃ?lii1ëYÞ½{÷eË–>|811±_¿~ݺuûðÃ-¬@ÙlvZZZfffbbâ²eË‚ƒƒ­Ÿÿo6ªªª0㎮ì)‘HBBBà)77·ˆˆàu몪ª¦¦¦GÝ¿?33“Åbåççƒ:ܦ3 $ÞnW-"p=F)¥9ìÁx ©TŠq7 @ÿÕªZZZt:]pp° úcÍ.òªªª$‰——„hÑ®V«Ùl6ÆZ¨ÑhÚ•EͲF8A†Ø±òÙÈÿÒ˜òÓàS´p¢R©fÓgèt:kŒNžžžhÞÜFø|>нÐcäèèˆÞö­™%kjj ²èììlÖ�ù_0²Y¦²h³­N§kSâ‚prË×X¦.SLCP–¬cƒ«R©0!e‚àêÄ“>[Ù+q”¨¾‰ƒ4\;¹ïþýûVKÛ4XAÅ”kÓˆ6Öa¢"À.+fð˜Læ¼yóÖ®]‹fa¿ýöÛ9~Äh3‹MW'h#SH¡PÀìÂÀŒC§Óñx¼\.{lµµµ0“¦“““L&kii§D"ðÆ掎Ž,ˆD¢‹‹ 8Öì XÂf³;Å“çµFNNNVVÖÞ½{M} ,Pp †µÌá)wwwP+™Åb•••BÔ¹¹¹ °fs‘ÅbuëÖ­›À@ J‘H$NÝÐA¡?SË««+‡– „aü¿ýüüœœœ˜Læ;w U»»»·¦ÏäËz½´=©A…ˆ—š‹²µ¢‹»ä°–à*nnnÏž=ÅÅÅžžž–£[ ØÀ4 "ÕX,V÷îÝY,…BQ©T2™ìþýûp½rôAF„&HËÔ‚¾«]€ÍëXïÁð; ¢¢¢Ìnd´‹ÃC„‡‡çååý?öÞ<8²«<ïîÛû¾/êV«¥níÛÌØ3v0Œ16 `ì� EÊàr pp@X;N?–8@ Tâx «!ÄE±0”±ñÆhÆ#if´K­ÞÔê}ßû÷Çóù|‡{oßnid³é-—kÔëísÏy÷÷yz¹È;ï¼sèÄkŸ8É¥v¶æŸf–WVëR½gh´Pª¨Eå­¥³Á`p||™ûÞ4f³Ùl6³ú…Z­9·¹\ŽuZÈn‹Åäq¹\X#âAQ´`~¿xµZÍëõ¾ñol4äÆƒÁ·Þ|3£VrÿÇŸÙ[Ò\SôºN!­V bSÔ`YOÁ£ç‚N§“Édjµÿ¦ŸBZ�O‰(²T¼å0fÚÙÙ‰F£gÏžå&Ç].×ÄÄD©TªT*8Æëõ`Ó-Øß9½B¡‡aÀ~ëó[­V*•r¹\,jzzš5úî÷û‘*”Éd˜|Äÿi½ƒ· §¶Ýnk4šf³Y«Õ0NŽlYrͤ3­¯¯×€ê”J¥ÔjµXƒÁ@ã Êd²‘‘¢o‡zÍd2@�ЏG@†a&&&‰ô`/ê’|,Pm.åî—J%Ód#ò'Ƚ‰Äèèè¹sçêõ:bAèœN‘D¹\¦ŸÕh4ýýý¨|¢BÇFM&Ó«^õªË.»Ìï÷ëõz†a@ˆ%âpy‹z¡Þ£Éd¼dï<м vww—÷¶ ÄĬ͚.RÁ›rl·Ûè©a½`jjо}W_}µÉ=¼½›¯–‹ÙxXrï½÷r?¥Kú¹\ÎmבJ¥êü©TŠ·É 7ž dpg¬V+†×j5^ü‰D255ÅM§‹ÅéééN+{à 7ä:ËžzKåw"t(FIoòŸÅbmŸ yõx<¨Sj4•J¥Óéìv{8N¥R###ëëë§OŸ^\\žë‹t:ÏçËår¡Pˆ†ˆ‹Å\gsmm Y~\†T*ÅÆv:$ë"‹q b±8‹mnnC¸ à+ۘǢ7››{úé§£Ñ(Ñõz½Ñh9™L† œÑht¹\¸‰D2??Ï{šð£•–ˆWzéëÃïåæHX­+++Pý\j`ü(Ö'Èåò`0èõz‰‘�V=/è"®ˆ±¬dékW(XUÒ¤±V«­T*<ò8U*#ôg¾Ðne:ÞS¶™^=‡ÃaµZ±t ÃÐm®½‹§©—7Êår.¿â‚€qíµm<‰¬EÖÞ~[>ŸO§Ó(2sG²EÏ7‰â‹x¨´Z-Ð/¸çÆÆÆüüü3Ï<s¨ÄÿX…ì7Lê„ÃaDç¼ú›››•JØ6›-›Í—ð6D±úÇôz=RC‡£¯¯ìC›ÍÆâ©£÷$¹ ð±âèæóy½^ž]¿ßŸÍfIÇ6ºòÈѵX,]©4Hïüùó;;;Çãñx2™t¹\6›Íd2!jÔjµ©T ƒP,î;–8––"9à.‘€òê%—¥R©¸¥ ¤»år9\FCÖO±R ¸<©TJ> ­äÕj•C)sÃntö£aO�±Ûl6[­V†a.^¼(‘Ht:]±X\]]]^^>þ¼\._[[k·ÛN§³P($“IèÉ®%pLƒíuÀfFx¢¦S¶˜çH$"“ÉàoaÒ¼—›Eü³}êT«Uœ”K2N@kæ¶KõmIÛl6+|ÕjuWãt¨¦ÿ4…8nr¹¼G�ìv»½´´$\ùÀ.†OM&“Ùl^[[cü $ó U*qhÑjª;\¯×CË#áÃò1···I¹\.Ãh‘kØä¹\N,#?ŒüŽ4þÚÚšT*Å…%‰l6 …P "WÎ2ᬂXÏÍf³Ífë Á×û|.-…Bk0êõz0$ôäDˆž'¹§_ a†!Æ)çóù¥¥%²°Åb‘·OéÇ®ÔèïǽËåv»ýÌ™3ÿû¿ÿûÄOüæ7¿A¹Õjmll`C–Ëåííít:-| îàA'z”q?hV«U:Ò ‡Ã,"ya¡Gw¹D‚/œìaàkww³]b±M)pº¾‘`ô8ÇGæŠy khüPþ4!x/¯‹Å]Ý=( €ÊH¥R�t¶Z­l6Ëjo@'”&Þ…^º e0PËh¼Ùl6 .H¿ÓédE-ä:Y»Ý®T*G8®T*ÙlÖjµú|¾‘‘‚S,0kÒËDÈΞ1¬&¢»JŠÅ"´Êîîn'š–‹L§=¹¢Ñh¸æ³Z­ X&:°‹F£P8F# ! ‹ …H‹“ÝnÇ\6Yg»ý½"ЋÅb«ÕÊÝE$<"°(, |Ôž8é/‘ñÅ0Npm,ï©SïjµZ¼»Áëõ ¼WøÙC9®&âx½™þþ~bÐJŽMBéÔn·‚Ã=«ØÉÅb‘aµZÍ=º@ %nÙÆ†öpY3ƒÁb±H$r ¼§‰¨KÀ^0 ä:›Ívüøñ±±1´ qסÙl’j¶Ùlfùà„é@ô|0iU%¯¡Û‹ •JeßܯD<Ïþ,œD"êÈpyUG«ÕÚk/ï[Ð;c4- àèÛT(B¡i�¸ƒ—"o»ÝŽÅbÀ ‰D¼a´ÄãñÞׄ{Ó÷!r¹\ÀGT«Õ¬´­H$’üÇìá 2™ ZìöÄjEx  ·&&ÜÏs‰Ý>‡ò§&µZ5ˆÖÐîÖìôØØ=|в6Î$¦n-K'²r¹œH$X³kZ­v``@©Tær9»ÝŽª;ïå š§®R©Ð@�333NS:¬×ë@ù³Ûí“““ÇŸ}å+_9;;k0ðÓx§|L&j3ø�zFóôÔ|¢‚ñ®¡¡¡N¾¹ßïïƒþ¢}ÜnÜ\߈$Qè“ÚÓÇò"ŠžÇo-•J,þx´ÓÊwtttÈ@¸~,Kñ˜Þüûžqæ­V ñN$y6›•ªÕjršh`bzP‡×èrï‘äŤ%"€+v»ø‡ÆéPv©T*»ÝîñxˆÅâ@ ÀÚs¹<ÍíímúÌÇãñz½Î0ÌÈÈH»ÝÖëõ`¡f½]§Óy<žJ¥B[&™LÐP®R©Ìf3úÔI¿F½^‡íïï×jµ±XÌ`0ŒŽŽô¡¡!…B!€W‰ŠT»Ý###W^yåèè¨Çã%n4¬ª°L&›žž&œŠÄ "S„È€î›Çñ^�AW‚©caNﵿ9ŸÏïc°S®PǵZ­“q2›ÍÓÓÓÂ>ƒvPréØjµJ×C¡Ð>Œ4¹= \áyíN266ÖõòÊå²pXŒdË®“Ó”L&Ééà…Â5(•J·ÛÍEµ°ì´�W¼ÏçÛG255%‹[­,p"‘¸ôT�-n·»—Í×î&‡ÊýT0?€Ã¢îh4ŠÃÐn·IG2Ù*äXÊd2·ÛMŽX,®T*¨Ù ŸX§Ó ›L&ÖI. ÜqF£±µµ•Íf×ÖÖ¢Ñh&“©T* (U*•* ßX,ËåòÙ³g¹Eæ`08<<¼¸¸V0–YšššjµZ.\Ðëõn·;‘HäóyÌuˆÅâh4Z*•T*U"‘ƒÈó\{íµW\qÅ7Þh±X�âN'ˆˆ^@À{šÌf3Í A[‚l6KO«ð&”ÄbññãÇ?Îö.‡ƒÄvkkkâ-(’ï¹xñbDŽr¹üرclÌçó¡Ù’hXlø%´>%Oõ÷÷›L¦b±¸²²" RÄb1¯m  0F£‘›gb½ô›ëëëûˆ;WWW»j<Œâ '*XÙK²¸<¿ß/àcáXýD¤ÿ8ûTt …«Ž¼M,Š6îR‚K0ŠÑ­®%®K‹_ûÚ×:%OÑp|íµ×²2³øj¹\Ž”(xi–—Z­†VÞÞBÞtv4¥S=‡ré2??/“Ɇ††@è…½DÎ}~šÛÛÛˆ{.¢Ûív8ËËËÀ ƒ"ØÞÞÎçó^¯÷Â… $ù@7r2©Tê÷û———޲3Xh—–– …°Ïé£Hö6¡iǬ"Ž Á> 2<<¼¼¼Ì0ÌìììÜÜ\¥R‘H$?ü0Ã0Éd²^¯'“É'Ÿ|Òï÷{<P½éõz“ÉtõÕW'‰®õÞÓ$0Î"¬{ÒßßX¶n6¡#àF£AY²°° —ËQ5$õ|šCN òžŸŸ¯×ë ißÜÜ @à¹çž£×M`̈trkN4 Ã‘#GÊå2w‚LÑe2–AiòÖÖ–Íf£Û²{¤¦”H$ô+÷÷®^ž"§©T*Ñ £ä-dHq—ÿ+îºë uHJX[³—–_Dv(³n'×}¸¤+l´‰÷¿ïÀë_ÿz–UÝë^÷–·¼å¦›nºá†àÞ~á _˜ššzâ‰'ÈËVVVn¹å–¯ýë½g0¦¦¦n½õÖC‹ré;¢VÈ„)w²’•%§c)Z)ÏÍÍ €Gø|>Ìiîìì„B¡åååN¥ 2NŽ žF£wïp8ù!°¤+ét:£.+pd¶··÷ÌÍÍÙíöcÇŽ]~ùå'OžÌf³÷Ýwß÷¾÷½H$âõzÏ;p ©T V‘T*‹Å¸<{jµšøãR©d½ÔK¸‡½S!èOC ¾ˆ÷ö$ƒƒƒž¤W’wêŸk? pvwwaWWWçææ„Ün·“¨3gÎt¥Ñ!IÄ X\\, Ü¡®¤Pjµš†îE†±Z­pÿt:·…ušXé1µZô/= FvëÇŠ¸4í—nœ\.¦ X~D×ä&¯KU¯×¹,dˆy{ŒÓÙ÷»Pëûçôÿüaš¦}~~þ=ïyÓéüÊW¾Òjµn¹å–w¾óÿþïÿN^ðØc …×¾öµ}}}ï}ï{qHΞ= —J*•¾úÕ¯Æ"\Ã/yÉKÌfóÏ~ö3$6Ïž={äÈ‘C³?Q(‰ .¬Â¤B¡ÈårH. LVÔ�($KwoeeÕ&•J… žÙlÎf³ÍfMzd“³¶.ز‘X“Ë値Êd2R© ‚×ïÆ5�h‘eé˳Z­þ0 œJ¥R©”N§Ëf³6›muumëV«s<ƒÂá0�l6kB#œ?®«J¥‚e*—Ë]'ÿÑ=±¹¹‰{!ÜV(.^¼¸¾¾NÈ0>L<†P(´À Y\\D~+ Ñh"‘ˆ@F¯×çóùN ç@D ž¤Ñhjµ.ð²¹\N£ÑH$r#”žÃáÀe³v2½þÜ’°•ÉdR©´Ó5£»uO?ý¢ß†GžÜÚÚ2™L,óyÀÆ©ÕjƒA‹Å‚ØM =ã§ý…Ó}÷ßÿ™3g~ùË_¢ÙéŸÿùŸ¯½öÚ|][?þñ Ń>ø™Ï|ÆçóÝ|óÍ·ÝvÛÞð†|ä#N§³¯¯ï¡‡úìg?ûÒ—¾ôŸøÄüüüW\ñ裞:uêÃþ0¨‡ÓéôÅ‹SïB Ñ× Ãd³Ùjµj±XÒé4I.á)ÌrºÝîl6»µµ¥Ñh:å« …ßï—Ëå©T M$S„¾¢Ð ð¡YÆI$±®è_†aªÕ*¶+àþ …‚F£áa˜SáÅo•Ëå2™ g{{Ûjµ¦Ói¥R …àÝ£¬M],wwwM&ãÅñ4 år™¦i€Yí”Û àî:Íf3Rý2™ŒXë%UÈҕĺËd2F³ï£&W«Uò½J¥Y>Ö[´Zm³Ù,—Ë@À²ðf†a¸OY­Öd2Ù)Uh³ÙvwwÑÛ"ÜG§R© h¨ˆq¢×Áb±hµZîʘL¦|>O ª\.—Ë唽kÑJ¥²§îŒ®"•JÕj5kç7›ÍN™^ ï‚î ¡õz=‹u*÷íI¸ì2f³9&õÅT”¥Ré½ï}¯B¡øÄ'>Aüá877÷Îw¾óî»ï–H$Ÿþô§××׿ño\}õÕwß}÷Ç>ö1‹ÅÒjµî¼óNäþê¯þêÐäô(‹…•é¤=UÉÈ!†{ðˆ5•JåÑ£Gm6[4U«Õ¼á& ÍÎÎNMMÑ©*•Jåt:¥R)z¯766 Ýjµ«ýO"‘ 1 C¼¿V«%‹Ñ …úûûFc<‹Å&“‰›‡%|§°ƒÎ�¾kcc#›Í¢sÁb±h4‡Ã_ͽ<òFÚ9Åê…Ãa'…BÁJªãD“K¥Rz¶”L&±.‘ôÎhøÔ}ïü"–M%Ĭ¼*›¼…p²tš¸â½6áñ,<‹-*|å‰D`ç"‘ˆw^›aÞ,ë“ …B××jµ"ÖcZK@ŒFcï4óÂ<„…BŠñìƒ^Èœd2×r°†ä/½ãžK}„ò&Ëñ#ê‹©+ßøÆ7vjgøüç?ÿ®w½‹ëE^ýõïÿûy‡N¥«ÔëuÞ±A´Ã‘§Z­qÇloo‰>×q–ÉdN§S&“ù|>Ä"ô½CÙ-9Êþ6›M£Ñìîî ØA¼øÒt^,ÉäßþdggZ‡¿¨Ñh�jèfepydN9NÓG¬Õj±útX':‡Ãa²>¼ R·ÛÍB@š±ÇŸÖ‰SŠWáðæšXGÞ¼†“aVÓ+xíëëC$ðÎyïE§ÏÇõ8§FÈÞâñ8½ ƒßï×jµ‰Db¯Ó¾H×W¯×¹Ž£@^Mà^pM†ôK_â¹Á]¿ÎívÓÑúž˜Êzn阛sàåôüÊË^ö²ééé¿ø‹¿P«Õ/²Éü#–\.‡mz5/‚d ˆF£ccc×`{{;‰ˆ„fLöz½±X¬ÑhŒŽŽ‚)›Í®¯¯—J%Ú-‹Hè ]øª^¯—\C¡P€v€&"jˆN_¤R)úà‘§†††¶¶¶x÷‰ßïg†—a™$IT*ND,“Ëå…B¡Õj �W¶Z­t:-“ÉÐyÄ:_˜šÈŠX'Úb±– –�� �IDAT´ÛmácΧÝá,o|`4÷‘eªÕjÍÐèuþƒÁN§ëõúÁN¿ð.]ï/®T*È?c'ã7ªÕjUÂ\öîîîê‹Åv»ír¹’Ó^ïE �ø¬ÑhduXHþüÏ÷sM8/!:oß™j<Xùû¿ÿû«®ºêmo{[2™ÜÝÝ}Ç;ÞqòäÉ|àxö}ï{_'�Ä£G¾â¯øÔ§>EwOˆD¢»îºëª«®¢+á?úѾÄu ¥ƒ`¸µÙlv"›AVdrròĉW^yåñãLJ††d2¯2ÝÙÙi4r¹üé§Ÿž››ûõ¯=??‰DÜn÷ÌÌ tPìd2Y:&þõèè(} ½ð^wR`Рƒ0›Í6::j0Âá°pÖ¥R©lll˜Íæ™™µZM r¤Ùb±ð6h! å½$œ¦t:ÍkQ„炉©>@6 #ñèr4ôˆÎP«Õ:aˆD"§Ói2™Ö×׫Õj»Ý~á*èûË*e³Y§ÓY,ÉöCQÇf³ñæuŠÅbïżññqÖ#ƒƒƒ¼½Ž©÷‡Õ4>>NL)Ð7~Ë8}ðƒ<©UÖ?:Ù§^�Xé.Uîî]0Y900@ÏwºB•JE£Â°.H"—qÿc½Êår=ôÐCƒáª«®zéK_j±X¾þõ¯;NôÿË¿üË{ÞóžF£ñØc‘·|èCzÓ›Þôö·¿}|||uuõË_þòW\ñùÏþ«_ýêøøø<ðOÿôO}}}z½þ‘GyöÙgúÓŸÞrË-‡V§GA½§ÝnÓڥͱ±1¹\¾¼¼|âÄ £Ñ8>>>11D?±1ÇŽcíV«uñâÅsçÎa–PÖµZM*•’éÎR©´¹¹i4 ‰oHºÕj%¹&±ñîÿNuaaœj±XœJ¥’É$fq*•J§iÖ©©©™™™V«D‰óçÏó*t:½»»;::ŠJÍsÆžžÆšL&LG‘;;;û5Åó¦U¦¦¦bêõzjß•fü.Öƒ[[[P2$_Já l•Nª‰uyôŸãã㬄d<GÇ ¯¹ø(Þup:¼½×V«U˜˜[¿'‚N T~H,mll$“I^‡Œ¾éäÔj5oxe…ÝÒ IânvZ¢®²²²B|¾D"Áêš‘~ík¢›þÛ[‰D"•JebbbqqQ8ÖÆ°¡Àk|>_</‹Fƒ;cƒÙ‹‘çû: …×ë%‹·d»>ŸïÂ… 'NœàÞf×ÌÈ w}¨S²’þK«Õ>ú裬—|øÃþð‡?,‰n¼ñF®EüÏÿüOÖƒ7ß|óÍ7ßÌzðøñã{â ;ÑofN&“ëëëÓÓÓ2™ìñÇ'sB …‚p�V*ÞvµF£¡P(}É.U*•Hß±š FGG1! ~X†ašÍf§™œ&¿ßOæÐ¡ÓIíü.�~‡ÃaaЉ‰‰•••Z­†ƒƒªØàà`&“aåP-Cs¹H$šŸŸïtÖÇÇÇÏŸ?ŸÍfYñÞ zràþMNN6›Í'Ÿ|r|||aaDôÙÜÜÜo@»ÝfêÓ7vn£÷G ¤ÓA2Ùh4ÐÌ©×ëIxÊÕN w`` ‘H çP©Tz<úÆq×·D‡]$¼2###ñxœÜ\Fc³ÙÐ'I~éää$ˆûz,%Ë+•J¼û«ÕÉ'+•ʱ±±³gÏîû,³†pÉj³œ'ß ð¨v»-l™ ¾»Âlll'÷JÅH›kZ§8 :ët:^+(‰Ün÷ 7ÜÐè û(U«ÕóçÏ›Íf.®è¡¼²¼¼\*•ÐnðÔSO|qqñÌ™3«««½´~ÕëuÚ_]É›E"»ÝŽö\¢hj2™„‘AÖÖÖ$ zÙIêŸ4 z½^òuù|¾¦ÁR©ŒN¯T*¼>¢ÙlF¦A­VÃiëäùŠB§Ó±N4” ‚Ë™™™'NØíöóçÏW*²h‚'wäm0Ÿ«P(H$Šo___禕è| }›:%TVWWœèñx²Ùlíj† mnn’nøJ¥ÂRñ—¾D–––h·£X,rÁz¸v½ëÁ¾<nƒ¥J¥ÂiªT*—b™D¿=„+´.å;XsXF£HÏ{]¦¹…¡Phff¦P(`Ûñ¾æšk®9X.ö|>ÿØc½ï}ï»í¶ÛMÅïDL&I8”ËåÕÕU­V[*•.^¼ˆñ ºJ©TÂH ðï‘Ü‚Á` ;¾PAéëëC³�XøÖ××É&ï¥ìj±X fU*U©T"šŽÖh€VµZíTÇB#†ÉdB <â¬:œL&ÓjµétšL¹Z­V–L§¹1,‘F£1›Í…BA"‘¸\®?û³?S«Õ««« y"jAHkb'Á”X×üR©T©TÈãaÄb±ÍfÛÙÙ1 Üøƒäâ´Z-Ëå2¯©6™L€™o4“¶Ø9Ä«¶Z­àñúìpƒÁÀÂ~c ´"ƒ=NP Ù®F£Q,wê4‘àïé½áýRÄl6wbÊÊd2f³™ Gö‰Õj}àÞõ®w‰ß•D"rn1ÂFóù<Ã0áp,´´˜™™!{¸^¤Å?‹±*= …B*•bÊG­V—J¥½*©`0¸²²²±±Á0 ðxü|>¿»»«Óé‰*Èå„Ïôüå,Ï4 vEî!zƒƒ ®V«X¥z½^*•ŠÅb«Õ9.€“]‡#¹E:ŽÛ… ž¤D"l! .677Ëår,Óh4´ži·ÛDµ¥R©L&£T*; ¡Z%ê%z#nmm½pl{jµZ8ŒP«Õ{â<ÙÜÜdaS¥Óé^ºär9k`F€OôÓ/HäÄ’N談#™Lõ©0»\.ºiÒb±Äãñ}0FÊ¢hµZ³ÙœJ¥H(ìv»ãñx¥RASÜ^î©ÉdñxÜ`06'îä&ëLbz_,ïìì\ʤZµZíi‰Åb„ }}};;;Ò’¤fIgœNçîî. ÿÏz  ;? †¡³Fb±UÙl%X©Têr¹­V+Y·^ 6o›e× Ö °^OÀã‰tZa³Ù\.—Ëå²ßïïš>ÁD^¯?Xz$a¶§u;(‘Ë僻hܶخ”ö~ŽÀ¯#ÛX¥RqÝ”‹œÜn7\'¹\Ž&’ŽG#&÷-.—‹åÍéõzV¿T*Ó%bçXǯV«èóùâR<ºPki4¥R ;¡¿¿_*•¢¥;‰$ ‚»Kû¼©TêìÙ³ PÀã˜Æ§ d'Óùîî.Š=J¥²÷†4p�’M®T*iÞ#^!¨€år¹Õj‘¼bˆ@ €O“J¥###¬#cµZ†ÙÙÙA#÷ÃQœøvEB0ŒF£‰Äd2]—a€\Ÿ(5Tm÷zOóù|×4ëDóbÄñ Ù*´~À'ô¢g÷÷‹ö!¥Réwؤ.“ÉhX—ËÕuZ@Xjµë4¥ÓiÜAðY^nŽŽÆi¯°o™L÷¾Ñh SY*•pÌð··;›ÍÒ‰u­V ú5ðYö‰¸B¬¾'òøCùà >`ŒTôü"T­Ëå"ø˜:Îh4Ò*dƒøw¹\ÞÙÙ1™LrâÍÿLÇ6›­Z­À@ ‘¯åFûûûñEõzž¸Ýnçm£0›ÍDS#­Ñhàí!ß…MÞl6¡aiV¡ÍÍMèÓF£Áëòïîî Oº€eŠ^s¿ßŸÉdL&“Ïç÷x<;;;Á`^"ð€”ËeÇCü_¥R9>>Îm’î8ãqÐB¶ ±jP=F�år™k8Õj5MjÅJ´ö‚a±éëë#™L¹\Þ{n™°/U©Th àl6{°&9“ÉLNNNLLøý~¢^`NöjœöÚ§€L4ööwµZ¥!·1(úôn ëd‡¥R)Ú†c(Òëõccc‡ŠûOAúúúÀÒÄÝÄ àî°Ûí\`ô" E:QÕ¹\.nä´¹¹‰™'§Ó)‹kµor Ü€‹æ°\.»\.«ÕzêÔ©ñññf³ }—N§ …‚ßï§3Pñpìhжr¹ŒF»J¥B&mÛí6^I‘’X•J588ÈÂÍçójµš«Ý@Ä»ìÀ’X^^V©T…B! Ñ8RJ¥rvvÖd2¥Ói0(²êív›,î ϵD{Þ­Bî‘° ^#T©T:¥ Ëår/Í–û§^¯ gùL&±‘ÑhtssS8“Dö$K'÷²J¯×Ë[7êëë3.—Ëãñ€Ã¬Ñhâóùºö(H:åyÉ÷á:22"’#d±X°|¬\?/ô™\.¦Üææ&�KaçÉENNNvÅX<”?DY[[#ýudº–èœ@¯°vw€ãA¬Ö2Ý D�ÖȪÇã1›Í^¯UbL “!\²“1ÛJ¥666úûû/¿üò™™™W¼âCCCÃÃÃÄ�`ÊuccEÄiÅQç¸þh4Z«Õ:•ñ¹'´R©lmm¥R)hR†a®¿þúW½êUX"e~qFív;mÒæææ–––’ÉäsÏ=÷³ŸýŒÅ¹W­V/\¸€5F£=Ÿ___'Q#WtÒ<ôŸÜÁOǃ^|‰DBߦNšŠž• ²lÏáÒK$’ÉÉIäA º¨c ?Ø)|ŽééiðÆ G*ÄmªV«år™^¢Þeii Å]éôB¡+Ý…6¢õõõŸüä'µZuÙ¤ñO�œß8 “þ“ÉÔËøCÉ ´î$“I42 tE Ek’ÏçÑŒër¹P©^\\WÊ Ê€€Ê —¥ÁVžžžžžž†c+“Éèó¬R©è³¼N•JÅ…€ÐîÔÎÎt|Ñüü<z€ó½²²’ÍfWVVž}öÙv»-‘Häry"‘ ;¨µÛm«ÕêõzC¡P¡P0›Í‡ƒÛß î8rÐÚí6‰ä|>‰ö4ÛíŽD"tþ�WŽƒf·Ûé²B¡ÀGÊA¡P¼êU¯"H¾<¼^,“SÇIâK¡P4›M©TjµZÏ;—N§777iôF3==MR&^¯'÷F#‹õÈRûEHÊY‡]¡PêôP(„|Ýèè(f1y׎<èΩ®ãŒjµº¿¿ŸUãfíÛäôÈó�ÅËëå+ –Eî Ëc]ùÂÂÂ>ÊHÍfS¥RÆ®‘n«Õ’Éd´[€€) ¦R)€½rç¢ÈíÎ êÔ­{ Õjj)ììp¿Šµ)ñi,·èR´ý="B>üðö¦D"½âŠ+ˆŸ‹ÅfggIÄšJ¥.\¸àõzƒ}äÈá°´\.ÏÍÍY­ÖÑÑQòàéÓ§ù–CÙ«4 z£÷÷÷§ÓiRZ�̾E"‘ÓéŒÇã^¯—Þx …‚ # °Ò×*•ŠTΕJ¥Ïç‹F£ ò³X,¤Ñ]?¤5yccchh¨P(,..àJ,ƒÁL&“L&—––Ðæ@fÆq 2™¬R©p¯A$­®®¢¾Õjµ¸-�Z­¶¯¯oyyY­VëõzÖæ'¨×ëÑY§T* …©ºƒùB¯××jµL&ãñx‰™hĺK€±«P("‘H©TâΣ …Ó§Ow:Ñ,ðrÐT*¯#X«Õ¸¨9$à¥Æ«p.E«¬ŸÊºMÝ.â•ÁÁAî:x<žÍÍMZ}Y,dz»šF¯×‡¹%4½^ßl6;ýØR©Ô£Šv¹\ù|žTIé#y)"ˆm­Vk¡PàÝa´h4šF£Q­VM&S&“i·ÛÅb‘ûƒm6[¹\à|c‰ÑhÌårÆ ÈåíõËårÞö ­V{õÕW“üÅ/~ñÁüå/I°Åž|òÉ·¾õ­ýèG­VëO<q×]w §H$òº×½î/ÿò/ï½÷^òà­·ÞšJ¥¸Þ‡Ò»ª×ëIUŸT¹ië‚!\¤¸i­V N?FíNÑC¸ÍfFÅf³¹Ýîååe’1¯T*±XL¯×¿44ƒî†a˜J¥òØc¡õ‹àˆc±ÝnG"‘NÅ]£ááaXhÞÖ5Rù€‚‹Åkkkƒƒƒd»*•J“ÉD*x–è8‹ÅbµZ777ëõ:æmív{¹\FEŸk±Xl0öJ (‘HÌfóž´¿X,6ôÒ¼b™Äb1¦Äz'J¯Ób‰èÛd6›£Ñh'ÍÖn·y-4÷–¸¬k@ðJö*Øü0…Gt:âx»ÝÎjÙŸlmm ¬Ã' ¾õòV«µX,V«U•J%°S766d2™R©ìÑ8áÛív:›AüÐûøÁæäÉ“¼¶T}ë[ßV«Õ;;;?üቷ>;;«R©þë¿þK.—¿ò•¯üÎw¾3;;û²—½Œ7ÛùÄO\uÕU"‘è»ßý.ÙôÛÛÛ?ü0þýš×¼Æï÷ÿ÷ÿw£ÑxûÛß¾µµõýïÿøñã‡ïi§·ö†ÕjEAô| (ü_‡Ã‘N§YÖ+™LZ­Ö�VÁ>©T*™L–Ëåè6‡Z­‡ÁŸ]­V­V«B¡ í�¥R §Ý`0T«Uš}µX,ÎÎζZ­H$ …2™L­VÑáET(�7ük“[,¾©x<n·Û;u©Õj:ó†O^XX >Y¡P@Æ’è/ÚA†gI¼´V«µºº*—Ëm6&pyï…V«…Wʽ†aèVi eìõ¾c˜šåLØíöÝÝ]¹\îv»d ©ÝnƒA«ÕÚ»qŠc§Ñ1Öv%gßápô>6ÔË5ÐÐ<H!Ò³äµZ¯•Je­Vk4Â(Ž{µOï‰ .©´ëX4lÊH$"l9ëõz>ŸçÍ s% d‡_œa¦ÿøÿÀ¹ ‡ÃßøÆ7ðà÷¾÷½;ï¼3‹}ò“Ÿ¼óÎ;ï½÷ÞÅÅÅ;î¸ãW¿ú÷Î;÷ãÿÿ¾ï¾û 5âñøwÜñÝï~W,ÿà?¸ãŽ;¶··?ó™Ï|êSŸ‚=»óÎ;þóŸš"ZÀHË ´Ûí¬ä;:ß:}‚†H$"¬%e2™Ãá@¸#•JÉ–ã¼éÐ\¥R-,,ÌÏÏg³Y0áâ-d7NommaÒ¶âWFƒ�›Í¦P(Âá°Àþï„)L?žÏçYú—öN™p$²Ê/è|(}ØòöõzýR=k« NÆ}Y§›‰DÀ#¸K„;x)êK¡P°ÐÍY×Ð5×µ»»ËjO�ek¯M»�>F:¦;ó¾á-„F«Õê…*‰Œ r^îF°÷ëã ›xw:=2îI>ð¤Óéüã4ÑÉ“'_ýêWŸ;wŽ÷Z$ýä'?yä‘G¾üå/“ŽR©¼ñÆÿõ_ÿõ]ïz×ÌÌÌüãX,öéOºT*½ãï¸çž{^ö²—½þõ¯?4H´tJÓW*V.¾T*¥R)è¬N TápÓQäÃéóìóù€³€†¥l6[*•är9lI| ×ëâÐEY ?¬®®nll ´BQHüòù|¹\v»Ýn·TîDQ©T*šÔÀb±UüRò\W5a·Ûéü³R©ä%hh·Û‡Õ)n> {uªÓÔ„i£Ñàæ`1Ÿ‹¢x§éN’Ië„Ï‹¢ëðþ:ÇÀa[B«lÜAá· /üÇ^sëÄõ1›Í­†‹…FÞ° ¬p ·fß–¸‹qÚ9#÷vrKpõzýR Wûúú´Z­ßïçvf³Y¬¯D"éDS½W¹çž{ž|òÉr¹‡ï¸ãÞÊË_þrO¸úê«Ož<¹²²òÌ3Ï|ðƒ„^Ðëõ~¿ÿ®»îºþúë¿ÿýï“äÞ}÷Ý÷ï|§Z­~ö³Ÿí}ÎàOD¸«Ä72 ¬ø£T*Y,aȲD"Ñ騠lƒ©uF.j«ÕŠóLˆr¹ÌÚÌ^¯—¥ŽˆÌ›rXZZ"fÕ`0èõz(Aà“’C¾»»«V«ARÕh4Ž92::ŠA`r 9zô¨èytƒ‰‰ ›Í–Ëå`ØðT½^çͽƒ x¯Z2™L¢;ãw»7¦;‰.ê¤OK¥R/ºž·âEß&ÀŽ^ð|>¿ï)Wô‚’üS)(^!ipôñx\�ª£P(ЫDz n·Þsˆ5#â¾ Á;§ÉÉÉKß1O¤¥R) qÛHP³ÅÚí#©Í+³³³R©ô5¯yV«Ýß´¯Ífóù|ŸûÜçyä‘©©)L®¯¯ßtÓMf³ù _ø]�ƒý;þü7¿ùÍCkÔ»„B¡f³)“Épz!ÈÅuÚÉ~¿œ~N#žÊf³ÉdÒçó²u€ëõ:+ °¾¾žJ¥­V+R bçÕG¥R)—ËÁ Ñjµ‹%‰àÈ�*‰ èÌçó6›íÔ©SÛÛÛ˜ö‹ÅbõzÝh4Z­ÖX,V­V†™šš’Ëåz½>›Í* ¦Æ©f³Ù©'¨«Øív:¡„"S©TêûÒµJ§¸J¥R Pö@€‘‘ÒÕm0x×A£Ñ°æ”ÇÆÆx§'éÛD ™0•J¥ÃÃÃØ6‡ƒÆ×b±ôR=ýv]‡Å±ÈÞ`´ye-‘Ùlf±³âW˜;ì‰ Ä8a»ÝfõžK$’v»¶··YކÇãA"EàkhRµe|||ee¥Ñh`¤Ëb±0 ƒtp×ÄàÂËÏÍÍ]~ùå?øÁö]ºí¶Û¶··9rå•W/5—Ë) ‹Åb2™d2Y¡P8~üx&“ ‡Ã¿øÅ/þú¯ÿZ©T~ËRü'/GŽyî¹çs#f3ª333ô!!ís.\àn?¹\ÞK*(Añx¼¿¿ŸŒúBOqJ´A⎘½ÍÍMò2¢àðl»Ý&­X,nllw1 ƒA%™L611^�·Û}õÕW †ÙÙÙ{aœŽD"A¦F[nµZðÞè+$‹Óµ&ÑÑ“•HÜnw£Ñ 2–þ–ÑÑQ.­×ëu86› »ýÙ€„#›¡¡¡Nh«««äj;­C©TbÍ)///ó!†aÆÆÆ.\¸@ЉD¢`0H†xHë©OOOÏÏÏ“ KÄkoúúúªÕ*Rš´Zë~A[âjGFF¶¶¶:)ÃN:yee…w‰`¸þœÛíN&“’·¬SF_Þžòf„vLµZÍápT*ÞG�Mv H/^¼¸§ä#=İïÞ¼Nw¥ëkÇèè¨B¡P©T@ÛÔét`¼®T*x*�/�O±°þärùèè¨Ëå’J¥}}}V«U"‘ Y,–áááï~÷»ï~÷»O:õþ÷¿_$}ä#ah6›ý~¿0…ÝŸ¬Ôj5À§’Й´ØÎÍÍÑäd³µÛíÑÑQ–³U«ÕÀNKÎ'N÷Ìã@nmmŒŒT*•B¡099)‹s¹Üöö¶X,æÂšÐÇÿSÆàà ŒF£J¥2N“ƒÆ:>Ÿ/ ùýþóçÏÏÍÍ™L¦±±±ÁÁA—Ë¥×ëwvv®¾úêz½¾µµ•Édär9©á“¯Öh4z½ž·9ùx1K=z£^¯ËåòF£!—ËiO4‹%“IÚÖV§>/þB0dF&“E"‘z½®P(œˆ, 0Q {EÏãËtú(ÖS\ý¦’ááaL&±Ö»D"‘Õj%•3b™È•sa; =NpÒ9d¥R‰. Éq(¸‹@_<ýìàà ì£essƒ}¼ëÉbˆ¦/¯«ˆã‰ÔMÿ矮¸öÆØnÚ"J>öðƒO=õ±X,œâ˜~‡‹Å†•ˆ:c Fú{ܸyi6›,£-‹a_ßò–·|ík_+—Ëä¿þõ¯ŽŽ^wÝuÜäß!<ð¡ð :MxàsçÎuñ³¤R î9{ •¢Å®Ýn $�FFFr¹\<';Ùh4Êd2’ÔÒétöÏÈÈz²é“U¯×yý_µZb²X,F!ºV«©ÕêñññË.»Ìh4þæ7¿I$»»»ÛÛÛƒ¡\.‹EµZ]­V{ÉOèt:Fär–«ŽBÝÖÖÀ¤‡‡‡a¿±DÍfÓápd2™=^hN#±Ô¾o“ðÔh4tC¿Àí�òl§iß^¶J«ÕC×Ì“O>IHy—šu ½ß¦?°“ð~‘Õjm6›$ÊäU×û¯×»³³ÃÒÛJ¥’‘N@î¼óΡ¯}â|$—ÚÙšºKk¹\¶LˆœÈf‹Å¬�g¸G¼;•jµZaºeâ¸ÙívÂxM'îƒd_ž<y²ÖAAÍÿ ¥ÑhlllÈårÒa0zÉÝ©Õê¾¾¾d2)œš–J¥ƒƒƒ4M&“)‹™T @ËåÖ××éæUjšaò”F£±Z­øŒ@Ùl6½^ŸL&ƒÁà™3gž~úéB¡ǃÁ Ïç;zôh__ŸR©Äدèy6N«ÕjµZAdÇ:Mù|>‹Åãñl6‹%"g–Œd²�d2ˆ†Q«Õ=‚ñ_Dƒ·â6u:Ñû£ËÂk(žÜ¥RIóæ­¬¬ìÏ2‘up»Ý—]vÙÐÐP³Ù—k§×ŽˆÎ‚Û$‘Höúcyµk'¥§×ëq›è·$ ºg[š«®{o€ƒ…á?BEM ¦ÿÎ\�� �IDATÝ{¿ƒÜ²Ö,¶Z-n|Úûð6ŒœÙlîų¨×ë¼Óõ¸…BÁ5Q'Nœ8šáCù}NG ð¡îÑ JT§\.ïåvW«Õt: ÂMúƒ‡£þÜî,™LFÈ<«ÕjÀÜ©T*¹\žÍf3™ γÓéÌd2}}}èé’Éd»l+S­VCx½Þ@ €¾^©TJ2{€‡:®×ëÂå^…B¡Õj].W*•7y"‘Ðëõõz½\..%Ðô¡< òóõz=. S8%lòYv¯Ås§Ó‹ÅJ¥wž”Ü‚Ag6›A¬ƒw±^o³Ùè¤%-v»=‘HH$F³³³£V«“Éd.—[[[£‹X¼Ž;æéÔ(±Äýýý{Â×@z™6?¸MX:x�Üqr2`ƒœËåÌf3 UZ­·™E©TÒÁ™F£‘H$¼á¸¡éÔ-=b´ã^0 c0XöiÿdƒJ¥’5 vP’J¥z™¯êz#_8fåCù}VmÀívc2Éáp q‹°A û|>âE:N™LÖßß/“ÉL&S2™ä-ö’o1™L@äd¹ÉÙl–7+Z)òçúúz£Ñ@þß‚™'X z½NTI&“!¡l¼+++ív»R©D"NúÂáp­V ƒétZ,§R)½^ïóùx³ñx¼Z­nooc²’tjàY ìÈd2´“a¨¨ÝnÓ¸D$öåŽÓºÝnG¾—3^(às‹ä}—ÀO uAü#?õÔS¿úկбÅz±ÙlÖh4(6‡Ãáz½N €Åb!1\³Ùä­'uEç½`zÚ—õCHl@niŸi6›\#‹ÅhoFàææóù`0Ø#úFÚ¹c¡\.ã þ–qúÛ¿ýÛ}ï¤K7!/„€ü¦V«]J«å¡ü :  É …‚V«%Éœ••°$§ÓinÀ„IR“@p¡P`Æív;NÒ˜„ÉJ:³ÏçwwwÑûÃ0 §‰5›-âë2‡-D/ýøîîn? /l6€0ðårùÈÈÈÈȺ1/188‹/%7AT«Õ´Z­Á`@ϺÀP~W&“#aZñ•J%N'—ËÂáp£ÑÄÐ\IµZÍÛ'}éR,ÌF×Xš–)NÃfðÀ¡é±Óù|¾f³‰ÛT,c±X,ã•©T*õzîÕ¦Ÿ"Æ SbÜ·÷îñ³n‰f:EŸØÉp€J^¯—N†—J¥‹Rôþç5ðôÕt’ãåN Jöm`Æ¥WÒ^ ‡º÷Á‹Cù’P(Ôn·ëõ:QådÂGygg‡ë—@£•ËåP®ÕjËËËtv¹;´¢Ñ*2•JaW"‘°z)Óé4m` †X'‹àøÑ$ ½]s¹Zû–=B­€%€dÛ0>Ç Ãäääää$mVÉp¥Ùlî4‘CëŽNy9b×óù|>ŸO$ô5˜Íæ+¯¼r|||墮²?8Ñ‘‘4Râ¦Øl6͉D‚“”]§5â6X²Þ’J¥†‚¹ ^,»Ž~v¥›Ü&D`t¥M«ÕvâðåZâýõk/v}[a ðË%ŸüÄ'^ŸW&“½8¬µ¼�”‡ò‡.###¤C£ƒ7 zlWtRÊù|žîòr»Ý¨$ÑÕSÇsôèÑh4zôèÑñññ‹/êõzÞ’CáHñ‡Ñh¤?ÁwŽíj2™@& …È/ÝÜÜ„I ã0Öö@íêê*Ã0,f9´ù€`zzzZxV«Õ P€#t»ÝPåä”Jåàà \.ÿ½:t`€%[%•Jáî€a’¾ÔT*Åk•Ýn7šÐàЋE…B!À1¯Óézá½£#išL§ÓÍÝ«=‹Ñ»ºT*ñ•JÅâТ‘öãöþb‚™ ”sv«î*&“Éãñ`„˜›x¥ õùóçëõzW§Àjµ²Æ¼1-Dþ$ Î‡ò§&+++£££¸ûƒÁëõb^gdd$‹çÚjµ^uÕUn·ÃùÀ‰hµZ½7h­®®âØÔj5N744Ä0L4U©To~ó›GFF0![, ‰ßï'Ȱ†kÉi‹Å¨„£—¬Õj¡hÄ0L:F¢^¯§› r‘º 9ä¢ç!+çççÏœ9Ã=MZ­V"‘€]‚|àÀÀÀ±cÇHÁ¼P(lmmÑßE_3þ‰DX®.¾šŒ¹ŒŽŽ’ú?ýF"\bVÖ¡æe_åU—¬Nç±cÇÀ±”f³ÉhÃ…¡’Ö’äš LW\À)¥Ç›dcõ‚MMM («z½ŽQ6Ö"ˆÅâ®Üµv»}dd·ixx˜—ÉžÞEØiëæ ÖdØòò2bÞÛGüá$ÞHÇJc/ ªét: …B!nCN*•¢›ôX…Vˆ’5ŸE3á"k/ ˜v(¬Òn·çççq³Ùl0´ÙlF£±V« (Ât:ýì³Ï6›Í‰‰ pŽŒŒSChy@¶ §P(x<‡Ãa2™À°±±qìØ1¯×‹ÁR‘H´¶¶F† ë–J¥˜ÓDŸ<n‰DÖ xôz½Ä(2™ Üø=~ƒ“}>Ú‘‡††ÐhG,føIã9M«««N§sqqñÂ… h6™LV«ukkknnŽN?¶Ûm³ÙŒÂŒB¡À"Èår´Ûmò8ÑngÏž…÷‰¬1 Z­É%ÚŠÐó§¯×K—IÒé4 ~L"‘°¼{:)JþŒÅbsss]û߆‡‡e2tëîîn4ß1Q2~¿³Yív›îø=G¦k”J%m~X{ ĵ¼–ƒ„d„ÜårA³)•Jî±$§R)ø7ðºzqÙ ƒÝnçn0 ¥½GóBuêÎ( †±c{9h]Ö¥-¾ØJ§Ó9Î}OpÍl×”w/Â1T¤yC®_$Lê¦çC3ðû,n·›4 ïìì€ô‹îáV«Õõj< …z§s8ñxû„a•JEJî&“Éb±looÏÎÎær¹P(d³Ùd2Ú ˆF.—Ë›››F£Þ`0lll�ŸB¡P˜Íæp8l³Ù¼^¯Á`ðù|�,^[[ÓëõJ¥’|N§+  .Äh€ÖÖÖü~.—ÃEµZU*••JÅívG£Ñb±È0ŒÓé ‡ÃR©”r–±z¼¥xâ z½^£Ñ¨V«Qó¯V«´&{>Ad6›U*•ÜϬT* Ã;v, ¡o÷¹cOÐn$“Ùjµx“.]9zx÷‚Vn'•J‘šåöö¶Õj…o-ŒÒi·Û;µEMír¹z™8&ÞáÂ~<ùw__¹~ZÞNÞêŽ\.t…\.gE~¥R‰>Y†€â ˆR©4]-è]ÔÑ8=þøã¼6¶“a4›Í„Ž·G1 •J F³ï&:Ô].W½^GÉZ§ÓÑŽ’^¯'„¼¼H…?ÿùÏ;-®T*=zô(1NO?ýôêêêk^óšNSo{’Ó§O_¼xñ•¯|¥Ýn¯Õjÿó?ÿãt:Ÿ|òÉË/¿œ›z^[[{ê©§Nœ8!ãþÓÖ¹ÕjµÅb‘Öz¨Ð°ük› lAôg2™R©”B¡Éd …"‘H”J% ‹cƒ‘®°óe³ÙéééH$‚#Ýl6N'Á8F¯D:&Û’d†p vòîî®ÑhÜÙÙAfIô|ÿÝ*‹¤Œ � …BQ.—iRT\y¥R!+Óh4677a¤÷Ôî$“ÉT*U.—“ËåhFçvƒÁ�ºXôì1 £×ë;¡Ñ vL§Ó {rGDÒ)Æh4ö— T*†!‹Å²£ù|ž60`! ¿}(ÜO&Úœ«‹H:qOX&“i}}{…²¾¾"ZìRl’®_˜ÿJ¥ …Ìfs×àcU]!á–^†_%ÿ_C`ži@t½\.—H$Âì)¬XìcÄž½@? P>y? w |SiÏípÿ»âÄ Ì*‰zè¡Ûo¿ý ÐÍ¿÷½ïÝ~ûíPårùöÛoÿâ¿X(677yú_ÿú×·ß~;¯ßp(ô«V«]Ow’w´“Î0ŒT*M&“0E�î¬Õj´ÚÝÞÞn6›7Þxc @î –P(T«Õ@ï-¼ÃI.^«Õ†ÃáH$¢T*•J%+§ Q$@Ÿ‡ÃAÒD2™Ìb±äóy$Õ- ùp<Åúö®Ð×À>G©dÁ,Ì­V;888>>n±X°€¬%âê© .,..’´gðÛRpvQt øª\q:$Ó…›Ë ËX^¯À.r¹\Âí6N§½´{ÑãïÕëõXjà·íÆ{kk ° …B¡Æ/¢«0])¦ˆâ}ÑDúÖ·¾õGϬ ¿³ä¨³ xyË­VË`0´Ûm¢|6ÔÕ`‚.½‡ý¬¼Á¾¨ó�Si˜Îð0]^~Ùå-‘P8¸°°ðàƒâß·Þzëèèè]wÝ¥P(þáþáܹs_ùÊW®¿þúk®¹æË_þòÊÊÊÇ?þq\3¤V«¥Ói¸‡_øÂ¶¶¶þñÿñcûØØØÙ<ðÀâââ?þã?Òd_â"—ËM&FsXîžB¡@8ò[wœSÔ%%RÇÿC, gÀ-‹N§C1 Fˆ05c¤Ó©­V‹õí Šw8ÛÛÛø.½^`æx<^¯×Y'Âl6 !xù|¾¿¿ŸÎ7 #c2™ÈƨV«°vpår¹Ýn'dBn·[àÌö÷÷ƒm`ggÇ`0�ô-ˆd‰p®£Ñ(`ýö§§ö)ÇRG¼6‰V8¸xœÕEýÀÚ*¸Mõzþ½DãuŠù†‡‡µZ-|bz€žr•Ëåf³™öúúúâñ8ŠéõúZ­V,q={{Ŧg k—êt:†ah‡@*•Úívr%V«œXb±˜»D½\Þ>}ÉÍ7ßÜõE¨âÒ¶'‘H¨`�–p¨&`r”J¥Ûí6 Z­Vxß{<ž}„ì[ÖÖÖÞûÞ÷nmm]sÍ5«««ï~÷»···¿öµ¯}ë[ßBÒü¾ûî2éøÃû—£»ººzß}÷?þž{îùÜç>7==}ë­·Þwß}<ò^pÿý÷×ëõG}ômo{Û¡M¢v#ì„Ûí&~�MSK¤P(tê,"*•Š7¬V«áüêt:؉………sç΃Á\.ü:ÌZÑìm¬³Ãr¶ªÕ*Wív;Xß #œä åóùR©´±±.Úl6ÐÎNNN ŒŒŒH¥Òl6»»»›N§Ñ ^¯×ƒÁ`*•Æll>ŸÇãR©”´¿³òZ¢çùÎËå²Ñh ‡Ã ¡¢¯\¡PÔjµP(´oLñ@dµþ³–”d¸³Ò¼»ˆ¾M´3m4‘ÒO§Óø)¬VëÈÈÈÐÐÏçS«ÕD’!žÝÝ]îž, «qj2™¼DÄ�p Ì ÁŽŒŒtš×fÝSŒ¨c,K¹\Æ"€1™ÞE.—‹¨êtyûøQ=ÁY,›ÍæñxèN98þäOÌ:Ðï· mÒpãM&7+X«Õ’Éd©TŠÇãn·ûÈ‘#¼‘‡Çã©V«/>Bk6›=}úôÀÀÀõ×_ïñxžyæ™\.÷ío;‹½ç=ï!/ûÔ§>uæÌ™û￟•üÝßýÝu×]÷çþç¬ÇçææÒéô+^ñŠÛn»~üºë®{ó›ßl4÷M%õG&h%o6›86PÜÉd’¸¼ƒáétšö[NçÔÔÔÔÔ”B¡ eöL&Ûžì¬B.—Óëõ‘HäG?úÑÙ³gDt™ßïg%v¦¦¦L&S>Ÿo6›.—‹T x6ð,Ð�FìF8É‘©T*@¬€4›ÍÙlvgg§P(;vljjÊív3 Zz›Íí¯R©úúúB¡ÐÒÒ’N§Óét˜ m6›¼æ¸Ìà>}úôööv¿B¡ OƬIÇÿ 'ýýý䈘Êh4 Zò€ãúúúèôk«à6‰Åâþþþ©©)¯×[,Ѩ©Õj‡‡‡†¡IO çÎxP X¶áرcØ®,ÕŒ{166¥‡T?¹r±XÌ;ÿ$,½`ô•J¥H$Â;T­Vé2ÕØØPµ°ù|ž®ì¦R)zaIúç/Ç8]wíµOk4š¡¡¡L&{Kgf›Í¦J¥"-ÿ¡Pˆe3oó[6›eaNOO·Z-…BqÙe—½ä%/i4.\àýÁ,FZ|>Ÿ�]ã !ÓÓÓt§»H$ÂÈäää$ï|ÀG?úѯ|å+_úÒ—>þ ]‡6‰Èúú:ÏÁ„i¥R¡éM‰&"E—éééF£Af’ÂÜ9¨Fƒ7Øm6›Ø‡v»=ooo+Šb±800�IÞ ™4Ïf³ËËËp‡ÇÇÇõz½Ñhd)Â#“Íf;aÿ#RÉår»»»@`ddäå/ù5×\sÝuס0‹‘þÄs7ÞxãÄÄ„ÛíÌårdZezzn/H0Ÿ›ÏçC¡ÜpÔÒh•Šü¯óJ3µ³nÓ !Ñh”è"Ì çr9–Vi·Û¥R‰ÌJÇãñ®–ujjjssÓf³]yå•Ç7™L@•ÝÜÜûn“Ýn‡{],üñ‡~+ž[\\X‡`0xäÈ.jC»Ý¦¤ê*,ÅK´ ìq/žýúú:ÆpÇYGƒDT©T†††ºV1”Jå±cÇö4§,ýéOú–÷|¬ÓÓÅbqssS"‘¬¬¬1CÚfgû›YiMÒ®Ã5-ËËË'OžÄ4C³Ù´X,±XìÌ™3¬*%M Ét=J¥ÒN1ø !‹úÑn·£õ¡’�¬± –ôˆãû'+ÎÍȳÙlív;™LLÞ�ûf³É fÏœ.--a;5•J1 333súôiÜP¹\N&gq ˆ?  ^"‘¸páfÉ766èý9<<ŒJ\.÷ù|døÈI Ð%¥,|¸ÛíîïïO&“‹‹‹KKKÁ`ÜíHµÛmÌ?MLLäóùçž{mî™L¨pÌ1•LêËËË‹‹‹Â«Ý©›K¯×ët:ºç˜~#˜µéZH×¶=¼Åét–ËeTYoAÿz»Ýžœœ]噼…@&ö¢L&Ó±cÇÊx~ÅgÒõl@o\¸pûùÂñD©Tb5‘’Èill¬ë¨Sïõ$ú£œNg§è™å‰(ºW"ããã›››¨<ˆ™a˜v»ÝËÐQ¥Ráý½ô}gùôqç:°F£» &àœN§€bí*¼ctä.>þøã[[[!ŒD"çÎãöÏD"‘®(CCC=’‘ô"ËËËÏ=÷ÜsÏ=‡}>_2™|î¹çÒéôÐи}ôѹ¹¹ýèGKKKÙlöá‡~ðÁ÷:;=00 V«/\¸ðÎw¾óÐõêUQcƒ@ �<oLVŠž>í\Ä+ …ãMÍfsuu•Bìëë3™L333dƒ% VíÚëõ^¼x1›ÍF"‘ÝÝ]âm ]¼xqtt”Ž0VVVÀZ È"âD÷õõ%‰z½î÷ûa·4 8Ëå Å7¿ùM�ë% 0,ãvJ¥ÖŠŠU¥R‘¼ºR©¼xñ"Q¬:ŽvºU*t ð ½dH#_tJŸÎžF ¬€ ×àp8Âá0é[a½Ån·Ûl6†a[­–\.çΊúýþý¥}>ßöööúúúÓO?MóSÈùóç.Ãæ¼Oñ–v”Je/w0‹í©ì‡d&ùóÂ… ããã$o,‰Ün7à/]ër·JG %±X „˜b±(“É”JeWÖAaañõ²dSétZ.—£r+ÌC#`Nº(5µÒñ²YÞ,¢â‰‰‰S§N}ç;ß!{ýÞ{ïý·û·O~ò“"‘èþûïÇvT©T§N:räˆH$9uêï\Ôèèè©S§Ð^/•JO:5==Ý××wêÔ)¯×û7ó7ívûþûïÿö·¿¤Çã9uêR¦W^yåáh0ëÀ�”H*•Ò±æÊÊŠßï'h§äA@Ö!o·Û‹%“É8Ît:ÍR ƒ …âÉ'Ÿd½‹øÈd“[,0&Ðs•ŽÓé$ðz$Ǹ½½A«X,¦P("‘Pe«Õê¼ZŒjÍÏÏ ½^ܲZ­Æ|¬Ýúúz<ÿ€ná°“ËP«Õ‡È{$åNWæN'\F TÐe9Ì–Ä&½^º‹H$ºüòËñ‹_à)b`Ðþ×l6…õ�÷¸ª#öõõ) ÜåjµÊ%êú-†Åò[æôz}>Ÿ_[[ÓjµiCÙØN¾Èôƒ.—‹qƒØl¶®X £ì‘vA@aÅ qb±˜J¥*—Ë333 Ã<ñÄhÌéåcÕju½^gЩTjgggh ãÔn·/\¸ Õj=Z¯×1…þ©«ÕšH$°ÃÀÁƒ D“É”N§õz½pÊžôÚÌÉãô<ÓoWþß?o½õÖ[o½•õüC=ÄÝäÁ›nºé¦›nâýà›o¾™tEj4ò–“'OŠD¢_þò—@àCúYák®¹æšk®Á¿?ñ¢ óþ¡ˆD"A‹wz©Ñh,--i4 5›M肱±±'žx¢—˜Iô|ïúúúå—_‹ÅXSh[[[ …¢¯¯XÄXÜN¹\î…ý™hU™L¦V«ÉÙÆtçÌÌL,C_ƒèù ¿\.ÏårdŽV[[[^¯‰‡z½žËå4Ùl–Éd8M°å …B.—çóy@idŸ666p6¹“•ëëëx ×€é|Ôêê*·Ö¢Õj{áìQèçƒM†×ëõóçÏ÷þzƒÁP($ æµÜ�7„V¾ …‚ì ǽàj*­V‹A7b¢xçs»¶hc‰hï§w) ,‹ ÒEð|*•Êr¹¬Õj-‹ÃáÀ(^6˜ñ],t×ä#ÚX÷×nÑ£ ?“ÏçÑM¬#ß'´°ÌÎÎ9r¤“•ý]‘¦Óé»ï¾{ii øIozÓ›Wìv;¡äÅWv¹\Àï)‹z½žèÇ DT 4pØé?Ãá0ËÍÄÄëòò²ßïw8¸Q”–N€I@çËd2f³¹X,Ã@^¯Ãk�3:.ÞçóÃ$ë ®E& Üí‰$‰8NN‡À3ÂÄ…G3ºˆjìÆÒÑ ·^¯k4št:-púXŒõtˆÉ}1Ë™ ëp ªã`ãr‹Åš’t8»»»ÐZ­V©T‹Û@¸þPƒ&¯Ó齤ˆÓKM%@ÞJÇÎÎŽÓ餱-ö÷{yß‚Ó$à+°¶ëæÂ9(‹ÃÃÃ�"a†×˱ÙlÜ^üñ/¤\3«V«éN˜KÌæíoùPÆêt]&ËÍ˾EËäää ÿí[Þð†7( hŠ»ï¾ûÆo<4E¼.-´�j~Üî,Ú£mƒL&ÃÈ]£Ñ°X,b±oôx<‘H„öH,KµZ%E¼{Òëõ¢ËöÿÛÍf«Õr8„v¶D­Vózô¤žQ3:ø@—ËØV™LfµZ‘cdéxo6› Ýç‡C­V¯¯¯«ÕjŸÏ°€µµ5‰D‚ú®³SÙlÖl6×ëu2á$—ËÝn7"9ðÒg-ÚŠï5GÄ»{­V+—Ëi˜éý]ÔëõÀƒgm$@6§oºT:}2¡Ýuîß¡ŸbÍÛp&º–Ón·¹ ƒý-Qר¥Çqd2¹¶¶–ÉdÐBÂ}kŸ ˆN§ckI¸)TÔ`{IJ”pƒAüÚÞ?Áív+ ¬N׊ëöµ¯½å–[n¹å–CË$_6›Môs¢6É*Ÿ²Œúw|>Ú£ãñx6›-•J(À±jæôŒÑèèèÑ£GY»´^¯g³Y�V‚ŠcóÅb‘lW¥Ri·Û¹í<2™l`` Z­B¬XlWµZ s¡P�_\³Ù«E«Õ2™L$» ëõ:ÿ�mŽÆ‡õõu ‰¸/  •J…š¶Éd‚šÃOQ³5ƒƒƒX[¢£wwws¹\:FÕ™hºÈ/êzдZm'ü²{’Z­v ìÛ˜¹ÔjµF£‘Ë Y©T¬V+}yÙår¹×ë-•JŸÙl&–Ë;NïÕ^Ô¶kqǨÉmb-ÑÐÐoc×Ýá^¡p^nttÔn·§R©………µµµd2™L&¹!]¿ˆÞ,;ÍŽœ0åP­V/1Çe4•JeW;ßÉ8u•±±1ºæ‰ âRºCù=`´¤Óé|>Ï:u¬-åìxðˆƒÁh4Š½Þ™£G$úT‡B!äýF#<åryii‰.˜ËÝ +•ŠÃá I{o6Û•5#‹Åáp˜IèG@Fð€R©4 áp8“ÉÌÍÍ} �µ@ Z­ǨP(ú–^¯HHd2™X,†ÎìL&¢,d«jµM”U*•*•ŠÅb)•J8°Ü!¼§®\.ì¼¼Z­F~o …B�h�°//¦xµZ ‡ÃÜ$U'¼4nä$,@`kkkjŠ{ “““Ñh”Ü&ÖÏ¡Ÿâ®ÆÒÒÒ>&ÒärùÑ£G§§§Ëåòêêj½^'#}—¢{¹ž‡„û LA“‹6¬NÍ®\Xp éÇ&�� �IDAT_P®ôõõõ©©)’ÐC–œœ¢C%þÇ*äæ²Ò333¤‘Éf³¹\®ÍÍMZ°“Ëå2Ì ò{´)ž)ë‹9d¦¯¯4yƒIO­VƒÖ–Ww¬¯¯Ã& âb‹ÅâÉÉI…BA6-‘J¥rìØ1TŸ>:Ü�”J¥"‘¹ìjµzîܹgŸ}–8¹ù|زñxD×^{íÑ£G T+,ßÂÂØß®¡odd0²étÚl6ëtºr¹ŒÕÓétýýýµZ-ýËm> ‡Ã´~ámÙ· ðÞc’ŸWÖÖÖè@¤Ùlò6¹µZ-ÞËÆ c×l˜Óéà}‰D›››FC@M±VY[‚u ËËË9^§Ó±¸ŒËåòôô´J¥fÍJ¯­­íoVZ,kµZIÓ)ô‰k;'‘H´ººJG&“a5„tÓét^¯·—hN&“ñF~¿Ÿ·©``�9™Z­./‘HÇY>)À¡÷G6|(¿·rìØ1™L611Xq MCçb@R­VcXMtËËËF›ûcLx׉'Äbñ™3gÀ�‹¤ ÔŠL&[ZZR*•‡ãìÙ³H� !¯ Ó鮺ê*°´žº±±1L’|8ªG"‘h||œa˜ååe§Ó‰MË0 p¬�;77GF :^E³Ùìt:Qí@±]*•^qÅ7ÜpÃÑ£Gc±±Osssóóó`e­V«È%:Žþþþ—¾ô¥fttóRhå�â'4ïÊÊŠD" ‡ÃhC±¬L&»êª«®¼òJ›ÍôX’Ss ‘HÈA#²à½ÜVü¢ÿ§’$—ËÅE8C íRúýêõ:.�y `é{ä íBß&Èöö6«ˆ¥×ëŒÐßßo4Ye‰Dâñxè5 w¦Ç¥T*1™ÀªÈ,,, †ÑÑQ‹ÅBëIÚ·£)ȱ-Åbq§æ‹v»½¹¹ùÕ¯~u~~!&¶Áé” ÄŒTï"í>§ #G{ò€Ð˜�VáW"Âýév~ÁÀ_èe,‹n·»G¼úCù„&n·;—ËA±&‰|>‡ ã)jµšœÏ­­­±±1Œû`@}bÏ<ó N¨l6[,ƒZdfii)•JŒŒìîîîìì ë ­VËn·ÖëõõõõT*uñâű±±éééßüæ7ô5“I{¢q¬VkµZ5ÑhT*•w^&“ªœ˜7´5çr9’9ìïï°ÐÂÂBµZF£W\qìS.—S*•cccÛÛÛ—]vø5Po[ZZ:}úôèè(¦ôA^%‘H²Ùl£ÑÐjµ}}}ÑèÿÏÞ{GIZ•ùãUoåœs讪®ê®Ó3=aÅAXÃÂÈêê\ ¸¢²°¨«`°ÊÙE¢YÝå° îÁ,, q‡ =Ó==«ºRW®®œë÷Ççpᄎ& èwîá¡+½ï}ï}žç>Ïçù|"F£\µZ mÿEA}Q¥RµK P¥ÑhA0$µŽÆç\.G6, c‹V«u}}½\.CD]ŸS çkÔj5zØ`0d³YzF.“É ÐòNÈA÷ˆ||oô9e¶+üâ Nz¥ûx‚år™;Ëåòââb{=…Ïç_qÅÉdR­V—J¥ŽÐsú¯Ûív¿ß>×ååeø*º%'|+ô_Ëh硟;Ïô\ÕÙ9ét:"é$ Åb1ý4­T*7Å€ÂlšÙkï)ëøÔju8‰DÝNÜd(ŠÉÉÉr¹<77÷GÀ^Ì¢H&“É …Åb’µ€hµZ.—K¯ACknnÎd2>@_“l6[£Ñ€ž•Äe2ÙÒÒR³ÙD|$a³ÙjµZ§Óe³Ùh4ºwï^¨…ÂZ­­Šr¹ {ÇðL¬×ú4éÁ2Zb±‰¬Vk"‘@Êás$‘Éd kÃúÇ}Åãñr¹Lˆ× Ó ‰,ËÐÐP6›=|ø0Ž,;vì0™L€Ú®­­ÍÌÌ$ ¨«Õj±ôz½@ H&“µZÍb±,,,ˆD¢|>/•JÙl6)•áDÅjž ³ÏÄz ã' & :Ób„úˆÃáètºµµµnEhœÆ€j©T*Ý0Sr¹œ0÷3:êø€§mŸÏ. w½>—Íf{çÇ„B¡L&cà±\y<^?²{Œƒ&Ô¿N1šÚ-³D"9|ø0ŠUýÈ雌H$©TÇ{^½^ŸÍfé(AƨT*tŽ«³wNôJ{VGÍGÆ`L™V«í†]!TÊÝéÖ&¶ ›[ …n·Ûd2e³ÙvF„®=–ÄÖ.ø€7ìXYY±Ùlù|þ€´A Ήx&©TŠ&\FžH$"‘HÚƒ!@À`§UD.—³Ûív»½^¯G"½^¯T*³Ù, é|>ßét&‰R©$“É 1Õ1Ë](´Z-ÁG`%#ÅAVÔ!p pN ã+‹|>¿\.ƒ˜åœ`0èr¹´Z­@ X[[3Ç·Ûí\.7“É„B!À(\.×ñãÇm6ü_0Ä/F©Tº±±ÞH$"‹I’­ã¶…‚à/ŸÏƒÀÒã×vÑ †ÒǦÇ8'rJëèWŠÅ"žäí‰9R«Õ™L¦·ßâñx‰$“É Q”€Sd2&žµƒ‚OïJXÇXäf;NKo“ÈårqZ蓚@"‘œ_ñvHŒÃðv»6ŸÏ755ÕÃ9Å8›ªÌ¥}5M>Ÿï‘}F†Ïç †|>G”ÇÈ ö~E Y,FsìØ±ŽÓô‡?ü¡ÛÅóx¼½{÷’ÿýõ¯M@\,Ël6¿ÿýïýÌîüãP(t×]wu£¨úÊW¾Âb±Ün÷õ×_~úàÁƒÏ<ó̵×^ëõzÿíßþ­Z­~êSŸz£¹%“É´°°P.—�ÇC‘�lCÌ0›Íáp˜œ™(ŠR*•õ!¶€>·‹ôäíÇk Žx<žÙlZÏn·«ÕêF£‘H$Òé42oƒ!™LB6)›Íêõúndn¡P–Z¥øz}}¬ç°}xx6¡ÓkZDGãôéÓ‡£\.G"”jŠÅ¢X,®×ë‰D™‹5<<Œs XW†††Z­–V«Õét©TêðáÃ8Ðg xh4ªV«‰ý…Ö"ØWa[Ñ—JaÏ—„t7+ßÛÐ1c„”VE lŠ &K…ñ˜:fb‚Á`Çò`ÖÄ}âFÿéF£ÑÎd0è‹–8T@%I°Þñ� XfûEžã³@œGrž\.·[nÂ'Š¢ôz=ýìØÑÂ3?uvÛŽ’eÝÞÜl6é˜TÆÀ Cž%>µiº>I§ÓHňD"…BÑí�Ë-Ö´/Úÿ{Ëåo¡#©žzê©{ï½—Ãá v“U<_ã?ÿó?ï½÷ÞnŽó³ŸýìC=488Ø^%>÷ñ‡?üáÞ{ïÅéÁjµöÿdÿ˜ƒ]jµ˜ ÐLŠI#TÅÙlvccj³8CW«Uz¼‚/¤(ŠÜ/ÈðA¯×ëõz‡‡‡wìØ±k×®ááaHFH0ÌÍÍe³Y£ÑH®¤ãhµZ¡P(‹a7 ‡hÃét‚ıeùz²5ˆÀ6€[±XlaaáСC@ ‚gÈï÷///ûý~W¯×ÕjõÐÐÐää¤@ €ºúÍfóøø¸ÛíV©TV«5K¥R@@Ü HÛ€ÓXŽÅb¥R)ðÏ’M¤âß8Ãn·c–Êå2ñ18 o[3–ʦ?D8p_B·x8çiµZ:w¶@ `86| §=òR?ÆÕdˆ5c2™d2YGæO±XLT7;E°öL&ŸÏï¾§[ònëŸñ)Æüœ·“S"‘è_9© cÔëuúi±ŸÎ§F£Áøò|>ÿÜsϹ\®@ Є‘ª6dKVÞ°ÇÓ.Ó~ÕUWMNN¢tqàÀ+¯¼R*•>þøãŸûÜç~ò“Ÿ ù9<<ü•¯|å׿þuµZ][[{þùçY,Ö÷¿ÿý›o¾™ÅbíÝ»÷¶Ûnc±Xßþö·Áð&‘H~øánsuË-·lÛ¶m÷îÝßûÞ÷n¾ùæ·¾õ­wÞy'Þâĉ÷¾÷½O>ùä÷¿ÿ}¼ÿÞ{ïµÙlû·ëñxÞþö·ß{ï½,ëÖ[o}þùçOœ8!î»ï¾[o½•Åb½ímo»ñÆY,Ö¾ð--Ëý÷ßÿüóÏÿô§?e±X÷ÝwßÈÈÈ“O>Y*•8püøñ/ùËø•;î¸c×®]·ÜrK£ÑøÌg>sÇw\qÅduDØA‡Ã  …‚Ùl®Õj ða³ÙCCCKKKÕj©|Üu<p£Ìf³É«01‘H>£R©´Z-©TŠŽßïG™‡ÃáЩ¸añ;ør¹YŠ„ìI'°»Úív‰DB¯·ÓW5ŸÏ‹¾5ÇÒÒr}Èsf20 ¢YÊf³þÕår) «Õ 1§ååeÈfV«Uœ&‰•••p8̰ݩTÊáp4õõuòÞ‰[X]]%¼ÅbA‡ò¡<ÙnûpÊÂï¹|9bD@6ÒétÇlG&“q¹\DÚ SÔl6Fc$Áÿ¶g4aÖQ} ]ƒ¸Ïne† m7• ®Õ¡¡! ÉAºÝí³äi* ô¡+•Êb±800N§ûÄ­´Z-†¿ïÇ/p }H[jµZ€vÈ/õér^×A„„éÏ`}}}}}ý¼ol6ûôÓO;vŒÃáÄãñ¥¥¥h4úøã‹Åo¼‘¢(‹Åòï|çŽ;î¸çž{ÞûÞ÷^{íµ<ðÀñãÇ?ûÙÏBëþûïÿêW¿:99ùÖ·¾õ}ï{\Bû)óé§Ÿ>tèP6›u8·ÝvÛ÷¿ÿý[n¹åg?û‹Åºå–[^|ñÅÛn»íšk®¹é¦›n¿ýöüæ7¿yúé§<øË_þç÷Ó§Oß}÷Ý×]wÝÕW_ý‘|äË_þòÓO?ý¥/}‰ÏçÏÏÏÿð‡?üá¨R©@EqÏ=÷\qÅKKK×_½Íf{饗�ؽ馛ÆÇÇïºë®ûî»ïƒüà£>úâ‹/‚íûÊ+¯üÚ×¾Æãñþ$âñét”š2™ b¯ñx|pp¤ïkµZ8f³ÙV«U­V/,,t\«N§(X²ó‰ìH4Eõ›$y’É$Ô•ŠÅ¢P(ÜØØ˜½ì²Ë áR¯×»q…1èË¢úý~Ø&ü¡¨Ñjµ2™¬\.—J%l¼^ïüü<Ùÿ„´) ŽW*•ååe€]á›GFFfggS©T¡PÀOT*‹Åâr¹FFF@Kè](J&“‹‹‹ÃÃÃ&“ ˆÕÕUØ/€Gp Ífsff†ÑF;6¼Cé£Çãóz½í*Aý @`µZÛK†Ý¾°ãC/ ¡PèÜÉgI@ãr¹ÚEëÍfs¡PØØØ K‡¨Õj;ø|>hpéI<p^“‹çr¹‹¥ŸZÝðððââbÓU»T<²Í„÷¯ŸÞP,V«{¨k¾®›j´ÝR{ê<•Jõ@:öÐM±Ùl½ûÑÎô {ùùyìíó¥}Ýu×y½^BžÉdnºé¦ååågžyæøñãÛ·o '¼B4•H$èµ\ZZ„¨v4ÝØØ°Z­n·lݾ}ûç?ÿy½^‰Dr¹œÓéD¹Âétær9”åÇÆÆd2iû(•J“““ËËËþð‡C¡V«c³Ù~¿llÌjµ‚\äöÛo?räÈe—]†–OŸÏ§T*Úl6ÒXV.—ý~¿R©S«Õ@�Î^¥R}ï{ß³Ùlétúuí°î18ÎØØØŽ; Ñ`·Û…BáÊÊŠP(¬×ëh^Q*•jµz}}}nnŽnR±*,‹Z­öûýŒ<C­VÃf³Ûí|>ÿäÉ“B¡ðÕW_M§Ó333/¼ðÂ3Ï<óÒK/=õÔS§ÇK§Ó¤-O ìØ±cÇŽf³ybbB*•z½^·cÇ»Ý u:26H-V*ÀpR©ÔÚÚäšpI°8°}l6õ­áááF£177‰D&''õz}½^7 ‰duuudd„Ëå"YÇf³WWW;‡†ˆF>Ÿ7™LÐ!Ìf³Ï>ûl(˜6›N[4oݺµX,V*6›M$VËå2\£ø±)³ ]•Í4íïQ©Tt4ÞS­V;b½Èvû6ÆÀ•3úœÎtT«UÌ•Ïç#« ° çÆ<yò$9½e2÷KKK333ônò ŒÙîfS“èv»ƒÁ`·içóù»víêq$êØŒÜδ@.¯Ñh¸Ýn:×),ÑûœÎÝs;•ôFtV'ºnz“Ùl.‹“'}Öâø|~­Vãr¹xf6›-“Éà£7eÓ~)2˘£ááá³ ÐãñÇGZÝ!ïÿû?ó™Ï  ñ¶·½Èl÷9n¾ùf@�þ‚Þ³q¦¢Ž;vìøÉO~¢IÀuÛ™ï{ßûÂáðÙ)ƒQõ'—çñx«««6›-‰8Çãñ¼^ï‘#GÐEQ²"v»=“ɘÍf(Ì*•J¥R¹ººŠb Ÿ±’)Š¢( Îiuuù–§Ÿ~Z¥R­®®6›Í@ `µZK¥ÒöíÛ_~ùe»ÝÞhµZM¢K.¹D«ÕÆb1‘H´ººšËå(Šš››c³Ù¥RéôéÓäò G‹D+}-¡VD"SµZ M¹|>f)è,=zT£Ñ€Á6ðùü™™.—Ûh4¤R©Õjåp8 7ªT*ðCø-õœNg$],ïܹsaaìš*• ân·›õ;C·.C@$ðÞz¬ É«öB]_›ÅbŒŒ,,,tc'_¨R©„B!©É㱇Ò~˜CŸý¡ŸehOQäfÁ²Hÿ6ú¿ÉÛúÿEú*Å­#¢· -$ÐÒwF£Ózû:¦²è}NÝüNŠýœ_;8§M{ÀG áv‘HÔÓ¹X‡Ã±¶¶(‹F¹dE©TbÌ ¢ÝêiÍfó¼x¦ã£ýèâââòòr>Ÿ‡÷êgüèG?Ú³gÏ«¯¾Êý£»îºëÕW_}õÕWu:ZÖéãÔ©Sçø_×2ç®]»r¹\"‘¸øâ‹y<^8¶Z­"‘hppp~~U}µZ ø˜*Fƒ ø^¡k.“ÉŒFãââ¢Z­Æa«X,Z­ÖL&ƒZB¹\~õÕWÁV'‘HªÕêØØØìì,�íEàƒ¾ãïÀ)׌xY,cßJ¥RÐ] † ’—¦wš£ü�V=’º çËå²ÃᘟŸçr¹ÕjU$éõúx<nµZS©4|Iº8{`ÖÖÖèš­Ž2Ø¡C‡°»%Éôô4Êò¸lÒOBï´Å›¯ Š¢ÔjõÊÊJŸIuF2F"‘t¢ïe°hUzzvµxˆÁÁÁp8Œ3%çÂz p(“ÉÂá0ŽÝý{)Ô«Õ*¨Ià 7í­4™Lñx¼Ï)" °h×{]ŸÏ':ôÝž¹*B`ßctKH¢‡½È Ó9I$×;q¬P(à®E"æºZ­ÊåòB¡Àð‡À³njò ¶·8´Z­Ž-ÇZ­–ôÿIÆÅ_|øðáßüæ7E]zé¥áp˜´pvccc‹å¥—^ŠÇãûØÇn¸á†~ø Û‡Ñhœœœ<}úôO<Fßô¦7õÓUGOþþ÷¿úé§5Íå—_¾¾¾~ôèÑ¡¡!§Óyøðáçž{r¹üâ‹/^[[{â‰'VWWwíÚ¥T*ÿäÎixx|*.—kbb‚Ífçr9­V Ah#ˆáp88›†B¡z½®R©P‘‚Çqí2n·gâJ¥"“É`ªpHb³Ùh¨j4b±x}}9Ôòù|ÇŽœZ­öòË/¯­­) ‡säÈüÝ`0¤R)ôT %Àغ|>_©T"Ì,—Ëw>vÐ (cÈåòd2ÉápÞt8@.—#X‰Dårymm-‹ÍÎÎîÚµkmm Î -ý|>_­VƒœËåBBÂår9NµZH$Š— :5:°X­V“{9ÞOƒÁÐ1§‘H´$ýÈJ¥`œI¥R N§see¥ý´7<<<33ãr¹ÀóÄzM0°Ý9‰Åbô“) z§-кS*•¹\N§Óù|¾~Ôüz7rµ[cŠ¢Î yFÍÈ2™¬^¯‰ÖûYT«Õ@ @Wþíhüû Jzåðÿá·ýò™ƒVçp¾X³Jéðʦh´Êã*I×·J¥*—ËŒ‰ÉdÄŸuA­V£‘y<^©TÒjµëxV«—·eË–k¯½¶^¯“Y;qâ„/˜WM¸ÿé/™h±þÿüa©T2o~ó›QÕ¬×ëÍfsÏž=HUïÙ³‡Íf¯¬¬T«Õ;î¸# ¡-ß¾}�h¡Rb·K.¹äÚk¯E‚( ^tÑE_úÒ—לËåÜn÷å—_^*•vïÞ½mÛ¶r¹¬R©öíÛ‡Ùžœœ¼ôÒKM&“×ë][[ ƒ6›íK_ú’F£ÙØØ¸è¢‹vî܉ËÖjµozӛЪ955uÉ%—T«U@°wïÞë®»&,•JÝsÏ=áp˜ÏçÿÍßüÙlöûý·Þz«D"ûÛß¾sçÎ`0 5ÍwÞéñx²Ùì–-[.»ì2$`÷îÝÛNÿzŒh4‰DŽ?ŽC^¯×ëõf³Ùl6Ûl6>ŸŸv´ ý‰DjµšV«•ËåhZ¬×ëÐîÌçó2™ ½J‘H„Ïçƒ Û¬X,F£QNGQ´¨‘½i6›°Ý|>?N xGº¼…¶!²  ƒðz½À¹ ØtœiØl¶N§Ã) ÄK`Bi4z½žnï°›€¢(Êëõ–Ëåd2™N§9H’É$Hav‘uôûýÁ`°ÕjY­V$îÊå²T*U(¤G¨-Fc³Ù¶oß¾k×.0 ¯®®êõzK„ö[’dÙ ýgzì‰ ùT?-¥ÕjXyÆoñù|©TšÉdªÕj¹\Æãèö…à‹2™L LÂIšðq0¼~T«Õ ƒÁÀçóK¥½ÓH£Ñd³Ù³PMÄA³ÙlâÁ‘¥ÂÈß ¶khh¨w‡£E l:f¬½v¯i2™ˆ×l7þàëhù{œöíÛ§²¸ñ\¥T؈…ØK+¾ö_.zËÛ×ãi +ùü?~å•WÎ4ÙÒì5R¼zÈåòv¬]ç”ËåèÝsqÔjµŒˆžX,Ö{ßûÞŸþô§ôIä‘G.»ì²nì„ô^³ ã 2Nœ8qôèÑßýîwÙlÖ`0 §Ó922’ˆ'N ¡§^¯‡ÃáH$Ç ïéõzÀsL&CÔ¦Ñh„Ba4Õjµëëë@«Õ‚ƒ‘26ˆ«èÇèþíܹS(BfM©Tnll`·c«”J% Úâ›™™‘ËåR©’ PÖ ¯d•J w4mZ­vccC$ÕÉãñÌÏσo0‹Y­Öjµ ˆ0R‹àV‡ì7z¼R©”^¯‡%•‹Åb4uY,–—_~'ÑÑÑééiòÓ ª¡×?Äb1™¢3=×'2>Ð ŒvW±XÜ'c¬ŠÁ`(—Ër¹|Û¶m|>? …B!¿ßßíœÁf³ÑNpvªðíM¸Ä² …ÂL&C–ÊyÜ;Z­¶a<‘H„ðˆ~y ùí¶üH>¼Ûw¯·[x‰D¢R©ÒétGÏ÷ÏÿüÏÎ]W¿t*œMEý'+ow;§“ï2&‘~¾¿ÑhÄãqøa²"‰D£Ñ豃Ä?1Æž={G7ÜäÙÈ_„p’äÈe¡2$„B¡J¥zá…šÍ&ÁbÛg³Y@€Z=¨¸I�žÍf‘ñ[__Áy2™¤o¨I¥Òb±¨R© Ü@£ÑX^^ã‰Ùln›\$—Ë5¤ð€€Úf³•Ëe«Õ*“É|>”/²Ù¬B¡�,R‹d#Û£«Ñn·½†À ²Ûí¶Ûí+++N§Dp™LF.—ƒê©\.+ŠT*œ—ËM¥Rh䢷Êåòúúz,[__‡×gl%¸º¨ñb®0E€¤®¯¯÷S¿a˜§³8"�zW.—‰Žð¦õÜr£Ñ€2žËåðU¥Rõ 8€q ¿.šÜÛ šÍæ@ Ð~|e#¶‘,•öV³Ž¦Rñ ¬ÅÔm~‘dñC™“¼d43™ ±ÉFíôŸˆD"t(|ûÌG£Q…B€OûºÍ ÄØúɲº5á:N¿ßÏápÆÇÇc±X*_%E÷Èkw|©ã°Ùl ¹$Ö„83úAU,·“%·Z­n1ÔÀÀÀ¹æaô<×€°E<çóùù|ù%Pª<xP$Å V«añ€7‰Dƒ!’hÖ²ÅbÑ`0”J%œ�л²²¢P(¤R)z’°AU^©Tl˜ Èd22™L"‘×hF>ŸO$ÇŽ#;sccuú6²ßï÷‹EŠ¢GG€R2™°M<: àî²Z­0vKKKÀwlllhµÚ@ Ðjµ�w …årY©T.//×ëu’Ÿ©T*«««±XÌh4[ÁØMdŠR©\5�� �IDAT=˜CyF&“U*ä{Œ…›6ÑGðþþL `Gf¨:`Ä•Jå¦ègbpú,±x<ÚD¸Fq‘,×Þ¤·`Ì¢£ÒÜ„ƒñréÉRúqÐápz½Þ1Wév»±YI·""ÙMt¯v5FÍÉ?< ‹Eǃ– ÐkÒˉ¤û %ý¤ÂŠÅâ¦Á”\.'Õ,$ŽÑ‘àr¹âñ8Ùˆì zí«¨½ætaüÙ ÔœÀÆX³X,Îf³±Xlii ͤ¡PH$ ‚h4Êçó…BáÚÚZµZu:F£1™LC×\*•ŠÅbâHß>„ŽJ¥ÑmCàW¡PÀn¤/<¹\À#ä²Ùl±X¬\.ëõz”(ªÕª×ë=~ü¸ÏçC==¶+‹¸<¬m™LÆr( …^¯…4ú ' ¿¬V+rž“““*• Ãf³‡u:Z­Fnddd||ŒÚh&þU"‘˜Íæd2 !Ý\.G7”*•Š>EŒ 7R, …‚×ë3r¹yK”ú<8¥ÎÚDœã O°Õj …L&ƒèõõõßÿþ÷>ŸÏívwkàCƒ „•ìÇ‹ ¤y:ÅÚ ]Cg›ÍƘpÐYU«Uºl¯îÓï—þ}%w<oôxôÇÔ ßOî¥/Ž".whh½ ŒšÕÍ3Ÿ>}“‚ ŒÅb¡k„D"} ±—Ëe.—Û[l*—Ë‘ƒ'9*uÃÔ“‡tá$ôÿÂ@¬×l6¥Ré¯ýë£G?~<Nc¤ÓéùùylZŠ¢�4@…r¹|pp°Ùl‹ìv»§¦¦8`y<žP( luÌcÏÏFTGív;òˆ¨VVVð‘X,µPŠ¢æçç‹Å"I3€:(ahR@·Ñhø|>"$OQÔèè¨Ùlž™™‰F£¤Ït||¼«õzÃáh4šK/½ù›Í622âv»u:]½^Ïf³¸åùùy23ñx<“ÉD"‘ÇÓ^±X ƒ¸¶özu&“C9àaVˆÈ^ýµjÖÐÐÐðð0òBñxGœÒº5ÀvÜÈn·ð¼ó8&&&¸\®Ãá@Øá÷ûŸyæ‡ÓjµèìÝô®ÞÑÑQ´ I$œMY¯‘äyÛ±w^ðnwNä%“ÉDdŒP(Ô1KމޱZ­gÁ~@NN=xºû9ú`ê—ɈŽÕäÚÛ¨¹=Š=Œ jÿ;6XŸÕ£z½NZÀèÃø BuLÏ™"AÌz­Ñ¯£KÇT¾Þa×…ñ'èN—H$¯¼òÊ[Þò–Ó§Oca$ µZMQÔÂÂB³ÙäóùÍfS«Õ¢í‰Åb;vlll¬^¯;ÎL&Cꔤ– rè¡¡¡@ @´ê±X,³jÙl6‰�aµ¶¶Æçó=Ïòò2}C6›M”…¶lÙ‚ÆaHÒ¡¡Ñh€Íf›™™K^0.ƒð„5 z9 ŠL&³¸¸822rêÔ)4½R8:: M‡H$R(’É$Rm©T*™Lær¹ÉÉÉB¡ÇÿÊår´0ÝjµD«N§›ŸŸ/•J؆Þ‘Ìp:«««Õj•!²700€¬)¬<Âa²£13 ¡?2¼^o{ßH{ÉýÜ7;ÚKq ˆ:F؆Ãá`Áà6¡­LO$:Î@ pòäItÚu{eoþuúc ¼Ü™–Ò13 Â?»Ð_©TŠD"F ZˆŒwÒ-<äžûrNôÕÀår;:LÔåȆ—J¥…B¡÷\àÛ¤R)éÃ"xy¨Z‘ç„…ˆ‡¢"M× %6‚ð›ÑøÆ_Lràì‘‘‘p8,—ËÁ÷ŠÓC½^ß²eËÌÌ ’øóóóz½e«ÕZ(VC$²"‹•ÏçUÇK@x?~4¯Ø<d£Öëõ¥¥%�áÀ`/:d …ñL,K§Óñx¼ÙÙY³Ù\­V% &“©£87ǃ•!Ýîv»ýÔ©S@"‘¬­­¡1°‰DjÁp8\,¡ˆÁf³ÁÆ”J¥e26šH$‚iƒDÍ ŽtEÙl64â%ô·ÒÍÇ£( õ*¤@}ôÑ3µ‰;ÑqL·ÎŒÍÞ;~')Üv¢´ô€Þ1^¢ÏY*«««Xà]|£íèÈœƒA sÓNÛŽƒÁñÑcØíö¥¥%,•d2‰Dœ¶m›;'�þpC+_û{èCFÓƒ¸]Üt N§ƒ/Éårôò•F£¡/…T*¥Ñh`VÈò‚Nc¥â y<àŒÆ_ÀP*•Z­¶T*Õj5•J•L&S©”H$‚FûÒÒ’@ ðz½©Tj|| àæD"Aò-B¡Ïçg³YHÓbñЗ+ä6b±*+\.ˆè××× –¨Édr¹\è«­T*–p8£¢ååezŽ¥\.Ëd2‘H„þP‡ÃŒO¹\ûÉþa Tv‰yE '©TÊçó766ŠÅ¢ÑhDi­Z­‚”Öï÷F0 D6šºêõ:Ý”à)²"1Ó‰Í!į£è…dIRõ&Ô9£¡R©âñ¸J¥Bæ¶O·D܉F£s‚8!ÝLs¹\¥RÙDP­VC¹˜ñÓ@'â*•J7n§³ ß9ÇΖnʳ„G£ÇgkµñL¤ù¼ïëÞK¥+Ç¡wËçó}²|öè çµptù1ž:”=y¿d2I° ¡ìH%‡9EÏü³þ—1Êå²@ 8}úôÒÒR8^YY …BÅbQ¯×+ ³Ù ìp8 Y5 ‘Häñx†††4L&#bã£ç¸ÑY[¬¢jµº¸¸F‰Ær‘ŽÇã0îåru¬ÕÕU‡Ó±x@'KD^ެd,W?@Hb,DWµZ-›Í¦Ói\n2:N"‘ †jµZ«Õ¤Ri"‘ˆÇãáptÃ0¬«««•JÙBG<%¤{)Š¢È<Q ÒtE›'ÈL&CgýGóo6›­T*gJÙÏ�‡“\.ïMÙqh4šH$£T*Å@²U*F2 Ú $Ž!@j‰D‚çK˜‘1λúZ­&O¿£ùbØÉ³B¡¡gØ{ðù|raý ‘HÔ†~úOnw,Kÿd„Bv»Á]¬¶ŸqäÈ‘îS,wëϽ0þä#‰ þ/L&ÑJGuØhðã©Õj°™ÍfèûY,–R©$•JIôg0x<žÍfƒÄIG ŸÕj…,å‰=b½Æ\ CV©Túa`4c(•ÊZ­ÖÞíAÇݲÙlƧT*¹~¸ÕR©„pJµ>ŸO,7›Í`0‡Åb±Z­3SGT‹‹Å "W¯×qZ¢_znz4�U*0Ùî%ºEƒð‡Ãtð¬My©TêÝ„Ô-­wÖï‹År¹SAØ«ûïêø\ŽhT8Ç;ê6ÎTR€¾Â­VkûB;Wo& ‡ÝtœÓ¹§PU*U«ÕÚtë¶3×öP¬T*n·Ûáp€î úrhP`|IÇsè©S§ºá[ø|þ•W^‰ÿâ¿øùÏ~ë­·NNN~úÓŸ¦(ê[ßúÖ±cǾûÝï¾óï¼æškX,ÖÝwßÅêr¹þéŸþ‰Åb=þøã¿ýíoÉ·=ðÀ<ÊùétKŸ¢(™L†æÐb±ˆÚ‰R©´Z­H7•J%°áI^h#Íçó`sQ©T2™ 7€<Àð1\ô�;ÚS X.’J¥­V +Öáp€‰:Ö‡žöo@Y‹l* ze´Ob¥U«U¢% ¡‚‹oµZõzÝívã „¿c kµÚZ­(¹ÇãY]]e„äH–Ò¯‡\3ÝŠ•J%¡P¨T*é;—‡,+Ãbmk` {`ŽÑVߣ4R*•Î4o;Øïýf‘­%Ñó¦ÜÖ|>_§ÓïÕ±¿eӱ饞‘eFG¿ÀÐg`"è×î¶›ÎÆ9»îrŸmÀ¤²¥×ë7eEá¦ÅbQ©T×Ô>_%î˜±åæ«º—:y\úƒ2øÈ©S§{ì±ë®»nrròW¿ú‡ÃùÖ·¾‡{ì±ááák®¹æ _øÂøÃ‡z¨T*}ò“Ÿd±X£££wß}÷õ×_ùå—³X¬÷¼ç=õzýÁ¼àWÎï�Í+YZF£² …B§ÓÑõZ­–R©„ä’Á`�n DpÉdÒd2™L¦ãÇÓ7 ÚÕjµX,>}ú4æaŒ¡¡¡………L&Ð)©ZÁºöL:ç&øõI†½}ÅV«U“Y,h*âÛHÔEßPèü#~/E£Q½ˆ%-‹ Ôjµn·ÚÐc¬qmm>¢c„ÔW<i§‰DŒp× ‰ø|>¹)·Û ¡Þ> 6¥Ø­CÇËë=Äb±Íf‹F£</Ûl6’¶¥Ÿrjµcˆb Ô¦©FÝ®[­Èd2åóù\.GŸÕ?þè8=·ÔÛý‚Åb!ݾV»pùŸ2­×#Ö€± ãaªÕ*Ð9<<ŒÆÆgAe†ú៥¿allìÔ©SÝЙT½)\ïPµ6Mí2íÇ¿øÅüà?úÑöïßßjµ&''¥RéÿüÏÿƒAÇsÉ%—ÀFê ã|ÑÑѹ¹¹B¡�´^­VÓh4kkkhÜ‘J¥;wîÌçó�ÒDP?B=üå<Ú6›`ùR©â}–¶nÝšËå�%·X,:nqqÅ!>…BAW,ƒc�ŒÉdâñx$ØjµZëëëè®Ç_ìv{:†š !—Ãáðûý�ÐÓ=Ùàà â§§§[­‡Ã±Ûí@ÜgÔl6AcCl% L l6ÿHzÖÕjudd„ÏçŸ8qB"‘èt:$m’Éd>ŸÇÍJ¥Ò¡¡!/1ŽGDŠü‘ÐQ0Îf³½^/›Nf Mz¤UÚd3¡Ì¢ ø2‚crµÐCéxyôfÆè­|)‹Å:¿è‰3d:Þo{ªÙl6C†¦ãb±X7ÏDVQGãïv»Û5?ûuNç,§B¡Ðf³‘MˆmÀX¬¤“ƒþtÉUâ#=„‡_~ùeVw*¼¹¹¹þõ ;ŽO}êSÁ` "’$,•J7Þxã'>ñ‰O~ò“`…AíÁår±X¬|à±XìsŸûÜwÜñÄOüá8/%Á Ãét.//Ÿ>}šÇã]rÉ%áp8“Éx<¿ßŸJ¥víÚº(ÎÍÀ§Óéóù …R©<yò¤L&3™L‡£V«q¦¦¦Òé4T¨ÑÚjµ&&&QÐ2™LFcvv¶^¯ONNž:ujjj pÐÁÁA€&ÐßÚc…çr9úÑ4ágbbbzzzvv\AXØèäݺuk£Ñ8yò¤Z­ ƒ}š™™áp8'‰€â0ÁµZ <› Éårb††Ñhär¹@Àãñ„ÃáB¡ÀápŠÅ"Ò/(´àbpd) Á`P$¡“—ÍfÓo–üÛét?ÂŒÿ¯èhX=°í†ÜðgÔá„P£=\¦_@½^H§ÓÙl–î{¶%&³Çf³µZ-[¦§§Í0nÇf³åóùŽXj£Ñ˜Ëå2™Ì¹”£¤R©N§c€¼×@QÔàà T@â˜ö‹ö'Åf³[­Vo‘ª¥&²Šè³šH$l68*{躢õØl¶Çã9‹¹c4[¼À(åµ»+Æ9Q&“áºÙlv»4Qí¶"ÏÑòx<.—û÷ÿ÷D¥izzúCú—Ëí†ZáñxŸÿüçÿú¯ÿúÊ+¯Ü¶mÛ!Aü3+à¡g³Y™L&‹Ñf´wï^>ŸdðË/¿l6›·mÛ6>>>66¶mÛ¶«Õ*•JårùÖ­[Íf3ÒzËËËn·›Ïç =z”lu›Í†åzòäÉB¡€Æ#ÐÕX,Ðo×ëõ£G:tèäÉ“à R*•.—‹¾6€}Ç¿H$ÂI޾J[­ÖÐЈkGGGy<\,‡Ã€T|½^©TêèÑ£étÚçó>|8à•••JU(@ Þl6N'~¢Õj üÚÁG¥ƒ}B¡P8‡ƒ¢(ǃ/¡_1h Â1Ñf³Aü»ý1­¬¬Ð=\)œ¢‡÷Œvîðð0®“õZ£ä9.§ááaúÿúý~ä`è ÑhèÀK¬=°¶£‘Àl6oß¾]£ÑìØ±ƒa‘»uùP&žËÅçóùöö#rG˜sP#¶76¬¯¯Çãq즎>00@/IÊår³ÙÜÛ\·»7²6ÐO7þJ¥R¯×#·¼©¡î:M­Vë¼èÉú|>¹\Nïó�ûY‡C— Àh  ÙIDÁíÞ ËtôªH$B{ïyÁ´¸ÝnFsôèÑ©©©mÛ¶;vL£Ñ u{(zþùç£Ñè<pàÀZ­vàÀ Nå| ½^¥^¯ÏÎÎB{"™Lr¹\ô9q¹\Š¢vïÞMQÚõ'''·lÙ‚<h¹gff …‚Ñh:I3$Ö„B¡V« …èª!^k2‹% ¨É!r‡Þ‡Ãñûý`؃î* ȳ“èÄb±LLLðù|·ÛÍãñÐ)Áb±$Éââ¢D"Ù±c‡Ó霚š …jµZ§Ó!§þǃ}¡V«é *‚Ùl–äˆÀÈÉb±J¥R,ƒmÕjµø8£íééééééZ­677ÇápZ»‰äBàz±mý~ÿôôô¦™ ð*á–––HR¨V«‘àU(*ŠMÍÜÜÇC~U¡Pœ{N‚‘<¤ß,ÝÔj5ÆåáÉãñ …ÂŽ;®¸âŠ«¯¾ºÝ@±^éXÑx=„°ÉI¥R0¬÷@¢a7AíˆØd\Ú!ˆ ÝØØØTÛ·=s¦Óéèg5zL–N§#‘H(ê'=Ký,‹Ïç 7, $Àlo›­Õjí­dHzp8ºB«\.Zñ¼8§~ô£;wîüÔ§>õíoû›ßüæí·ß¾{÷îøÃ,k×®]F£ñw¿û]¥R) ÿõ_ÿõòË/ÿâ¿xÇ;ÞñûßÿžÅb=ðÀoðÂ8ëAøRÕju¹\ž››ƒtÄÆÇÇájµ!ÚA „Fr»Ý®O4EÍÍÍÕëuŸÏ§ÕjÇž={Ð/‡•J%EQ(V1Láôô4›ÍÖëõ ÷F',›Í†ãáñxðÉ"—Ëå¢E“@ Ðétx †”²N§shhÈn·G£Q°Ó"Á \ˆ˜1 D nbpÙEF¥R‰D r„šÑðX©TˆƒAûÇ#7‹ÝÄ0:@?¶ÛV¼Ôkr8œt:Ýc/ˆÅb‡Ã±i³<›ÍO¹[ñC,wk‡‹Åð¬˜"4?‘!“ÉÚ‚V«uÏž=[·n¥Ï0æ Ýf³yhhœ¼Z­Ôôè¶ý; Eÿíg½SÚSʇ~y89‘)Å´À£€}û\ÎvÅb‘޹÷ûý‰äìlò©Ï‰žãê†Ù ­Ž:.™Lö8úÕj5ú,à'ÎHùìÆ 7Ü@QÔ=÷܃íýè£Þ}÷Ý[·nݾ}û“O> XG³Ù¼ñÆ/8•ó5‡Ã©×ë°>ˆÎòù¼N§S(ápX­V œ„2™ H} æW(b±X¥R)‹Pu+‹f³¹Ñh`u±‰D†&™L …B‚šclu0» ·J†ØÏð@P¹EI»°„Þ€ VWWN'üÉ(€lI•ùùyÆ1oãñx8ÕÑÿŽã‘X,†kÁ•t¤w¡ã\.ø¶É±› l_¯×ÁĨ¼Ý7ô#GW©Tࢺ=VÔÉ6åm6›ý �žd½¦ I¯Áðx<ü/¦ˆø0œob±pÿ¨üg2>Ÿ?22b³ÙR©H,ŽÅb³³³ƒ!‘Hðx<4t2,GÚ½ø™VñAÀÑgc@ è(ºHQ#¤0›ÍX<O&“Õ‚o…BFâ2çeóBíèœÐ†}èTŸ÷Ü;ËÙ± )”H$‚”Bçç§ULüãßuˆÎ(6«Ùb8¡}ûöAûk_û(¨1Þ÷¾÷ @$¿úÕ¯¾óïd±X_þò— EÛÝwßý|à‚S9_#‘H`ó Au+$ úý~•Jµ{÷n2PÀÉHzQzS«Õ2` …B`;Å®n6›+++&“) †B¡ÀãñØl¶\.G"Ž`ž>}(†x<ŽZ½Ëåòù|À byî.— ½QpÜiµZèÊG" IåG™H$I7½^ÏHÞ&høÔ+q-~¿I…L&Ó-¼S©TÐù¥ûËŽ{ ë¬×”Òè<I$¬ìöqzÙÃd2Åb1›ÍÆz ãÎê Ç•Ëe6›m6›»õÀ’îN2{í¦ƒÑFM¾ŠTSšÍ¦Éd¢(jçÎxúRÈåÒ¿¬í±Xìé§Ÿ¶Z­ P(ø|>_Ç(ù,Ìý¦õ—Ë ±;º½™<ÁŽÖ•þ˜Èr=;åUЋu¨Óér¹\ŸÇ&´rÿç$>s^ö5T©TºAû˜·þ{{{ë.wÛ`ží†ìäñxû¯ºj`` Ÿ ¸êª«È¿‘Уw½ë]Œ¿ìÞ½öñÂxý�x…B"– ïI§Ó±XlÏž=XfH-‹,B;N>Ÿ‡BÒÊÊJ"‘ ÜzDµÙh4‚éN¯×CG Å[“ŠÅ¢Ýn_^^ƒ:n```ccÃï÷C·ÙlªÕêÅÅÅx<N?IØív�êà#+•ŠV«åóù  ³ƒÍfƒ‹…8o:F·S0?¶:D ÉémccC£Ñ0Ì" aŒz0 £¦”G7U•�ÙtèPîö͇ƒÍf¯¬¬0ö/ˆ7a(º•¬D"’¬ÿÛÊÚ£i²½»sÓ.(.—k6›×ÖÖˆ•H§Óžzê)HùñùüJ¥Bˆ‚ÀÐ#âAè�¶Oúi ϱÙlZ­ÖsŽoJ¯—Ífm6ÛÊÊ �ÏdbM&S&“é–B$6µZ-N#ÃLŸ7âÌ ‡Ãé³í•axaüûlx­ÕjŒUÁåž iR·éë±RéÛ£ÑhôOeHz:¬{±X éòwœ»5|íß¿_£ÑtÛ±dÚßø¬$f aûöíHŽY­V¤ã€J§Ó`çp8r¹¼P((•J™Là· <´¸¸ˆ¢¤Ù±Cè«Èd2Åãq™L–L&½^/ˆ>Aµçp8*• Jb³³³"‘ÈétùöƒàJAÙ§ÑhJ¥’\.ªACCC·«Õ*N åryllL£Ñ…ÂB¡°´´”N§:ê8NǪ2ÌŠL&CýÌl63(•‰«@ö šOÝ&œ¢(§ÓÉ8ZõÅbƒe\-ÃsÀÅ’-Y­VI ˆü±7ÑLŸÝh€Õéth!H$„o@Weon0B‘œM6›5 Q‹Su"‘J¥ …¢ö£öl}ŠÚˆŽtÛ™L¦Ÿv°”ËåŽðK¬<Mè¡ôÎÁâY@Ab}}×ÜgN[òÿ¬½Žïé¡Aý™þ¥½Y•º §ÓÙ£XÚ>ã&“‰QɤgÉ1PŸìqÈ«wsßø¡7hñŒF£×ë.ŸÏoll<xð©§ž:qâ„ßïG*,“ÉÄãqe‡HùŠÅb¯×Ëf³ÕBCÄz£££n·›®Ç­Vk6›ÅQ:Ö`í³Ûídñ –Ë奥%ræ‡ÃÓÓÓX` óT,s¹œÏçƒÇ…zoµZܶm´TÞ½{·ÕjEæP,Så÷û!‡‘Ïçh1äŸQiƒ«0À²4¹V«Âl6÷–üi6›p™z½žÅF“Édv»qÀê_³&‹ÑM _•Ç …ŠLP¡…´ã\ˆ)!ÃIŽŽ’D+á`mg»ÆÁ ‡K0]‘æ¦F¯Ÿ)¢×€‚î(TDOYõv ½Õ¤È¡X?LvÓ9ŽÎ?ÝL.— f²è\Ù´©¸GN†þ¿«««=²|^¯—á ×××766²;§V«éõzì4‹Ö™ Fü//›‡ðmjjÊëõæóùjµJQЇB/ääääE]åòcÇŽ­®®¦R)C;vlbb¢R©<÷ÜsG-‹óóó­V êœ …‚.t6777;;»¼¼LêùÃÃÃV«Õãñ,--‘íŠNÞ^x!ŒŒðx¼S§NÉd2›ÍF!�„Z%‘,°yE7¡X,Fƒ—Ë+++ õ9vìX*•*—Ë ³P©T§NªT*°’ð‚0|dа=e2™ÙlF3òÚÚ~kiiidd„Ãá$“ÉX,600H$Êå2´\{„Ã0îôSÅÜÜî1—ËÑSd°Ùlàû{˼"kÊb±d0:úfjjjjjŠQ· ,333ä)`Š¡ÏÊÊÊÔÔÔÆÆ‰$0±ÍfÝýÍf3Çãq†y<žÞ&›ÈÂ'×ñXi·Û§¦¦:ú-LÖ!Ý$‚U’&¤ÇCpr¹¼c9 îñx|ÓƒÔœé÷…§CÏÉ‚!¹ ò*Ý•Ðó« /óvý?Þqçã¿ù½Õ9œ/–Ŭ’þAë"�� �IDATx0DbÄãñ “É„óxŸçDz‡¢(´¢»Ðår1õ€¯ ó|Ó´âe réA´äÑÌLÿ–-[®½öÚ G¢?ëF#‘È ªÕj$ABF.—¯¯¯Ãèóùü-[¶p8œB¡€Àìì,Ðn*•ŠËå<xÐëõât-Wh/ÕëuÄÎ¥R Y>²ä¶oßn·Ûív»R©Ìçó�e±Ùìx<žN§Ñ](“ÉA>ŸÑh´Ñhðx<—ˇ5 =“622BÒs¹\©TÂÕf³Y¡Pˆ P*•N§S&“¡ÆŽõ|øðaèü†ÃáT*ÅçóQÁªT*¹\žÏçÑ­$="bä‚L&ÓîÝ»Ùl6tA­„LËÆÆ *$®‡ÁÅÝaÛRåv»ûWQ¢W€!´›žÚ5“ú¥R)‰�EÒçG0Eí>Œq’p8ToµZÐ(Á§l6›Íf[XXèMZ! ­V+Imuc1ý%` a»ËåÚØØ˜˜˜ çŠzÛdÄp=nö\†B¡€Ì˜Õjehe1Î`dsP.—#rçB¡x×|>‚¾}ûö©,î@<W)6b!n·üìÚÚ0”«yPy©T*ªìÈÆ!—Ë[­–H$J¥Rèioç:‡¦×ë¥ËQwJ¥ÜN§ÚÒä%•JU.—Ï”XðÂøs§OŸ¦ÛúR©T©T Šçè'U«Õ'NœP*• …B*•6 >Ÿ‹Åæææ†‡‡ …B8‰D¥RÉn·\˜C©T‚ s©T*—Ë ÿÇÌÞ½{kµ‡Ã‰D"áp{šîz½H$£Ñ(‘HVWWöær9ÂúHFGÊ8ƒÁ�±Z‹Å2;; `B.—k4•GO.Ð ±XÌëõB<žÏç‡Ãá|>/ óù<XŸÏ7>>^(„B!ý×—––*•ŠT*]\\„ î(æH$¥RF5M&“ï;CŸW,cŠHðKg}¥?£'Nü© ¼àr¹‰gÍöW;Z6™LFhÚÑÕi±XœËåªÕ*VÑÚÚÚÚÚšL&ƒz}·y(—Ëg§'+‹Åb1Áô¯®®öàÒíxGÀ£Öëu©TÚg±_"‘ôI©N”f;ž›é'¸¢r¹¼²²¢P(ø|>â*ƒÁ€¶q‡ÓÞ›Õ5­Gä‡éM§u@…HÖno N…B=’È€ºö.ÅãqLG{n,»à™þß<¯^¯C·„Ð ° ™Lð9¤Ë––– Åììì‰'°\Åb1OÕjµ^¯÷V«…["%ååe¥R¹¶¶6==}äÈ‘jµ yu|' ¿™L¦P(d2™¹¹9‘Hd4¡ŽÊ¸Z•JÅÈü€bu}}]$”ˆ¢¨H$¢P(ðÒÊÊJ¹\F†E—�ݦ¹¹9¥RIö ié:êôþÜ@ €Ð)NÄbq{;- |"‘ˆwÈGH§­L&Cr‰Íf«Õj>ŸÿºJNoÚVæªö9'}ÊxèŒWéSDoÂEG­\.F ÊA­V«T*É„c¸\.üP»ôvû•K¥Òþé!r¹žÂÓjµà Æ1!½¥ÏOïk ÷| µëÆÆI!àòˆ7éðdûü Ɖ¶•OÒ'™H$4 ÃC÷rvPK6›-“É(ŠJ¥Rà¨>w ª ã<ŒFc<Ç*–[YY …ÑhT«Õ®¯¯óù|È^”J%±X¼¼¼¬ÑhØl6cãñ8 !X„gcc‘5öüÀÀ@µZE@§ÓMOOCtIf­V [CQôg!_Íf5ÍÀÀÀÌÌL£Ñ`ÔW�¾`x,rá·ìvû«¯¾JL$nÎ X†Z­X,#iœ@ €VSd&`&c7!AG~Q¯× „B!ø(¦R)“É”L&錨p·ðÍÄbâ G”œ”Je¥R9ïp³õ€l0H ‰áÃ?ŠÅb»A§O‘\.—Ë夀_¯×ï'Dì@�-ºt£F¡ÊÉdù:ø�ðn þ&iºó>pG›põz=ýpÓûø²Þi[>Ÿî©BŠ¢Hó@_'§Ž‡¸~àêE¥›Åbe³Yr–ª’LJï:c“¢¥J¥¢Ç&õz¬×hY,–Õj=G^Å ã ;@Mm0`¬‰^ ‡ÃXc�‘'“INV.— xrn:N$¡H)•J­­­Á9aÕá Áç†è ¿\.çóyÐC€æœ4¥‚¡N£Ñ¨T*‡Ãò6›æSd``MˆDÇ3™Lä^’ɤÑhäóù¡Pòê@èÉår“ÉdµZq G¯×“=÷IR©T¢)ƒÁ@Q¦(2Ì9SÎðL¡P¸5¼DøýÀ6›J¥¤*ϳèêñÔóé¶^Lx·)Bæ†$ý7H$’ö.þz½Þž}ŠD"xptÚ\òêvø»R©„榷¼é•““±‡hi0 ísÅpEétš\CŸ?Ô-ëØñ¸vvûº³79¿+ M “õº¤ïè¼^ô\Ý‘Ñl6IœR.—± éŠÈårX^(ÐÙ.Œ¿€46ƒP(t8è @¹ˆÃáÉp8Ül6ÁNÚJ„´U*•Z­F3l"‘Èd2étšð‘U„Ô1ì˜]°\AþKQ”T*ÐÆãñÈåòÕÕUü.šíkµZ¹\V©T‹BϤù*‰d£‰DbyyÙn·7›M‡ÃA"6¨ÈCr öD"‘Ïç…„ü.R”y›|>?88H¢CòU‰Äï÷/..:Nëñù|‰Db±X6í\‰Åb(·�°Nö n‡´XªÕjŠ¢ÎE â|b±c×g•%ŸÏÓF³ÙP¥‡Q©T°L G äÛñÁáp°À:=r¼&Üw.—«÷•‹D"ò,Èb=¤Óéökè!ÊÞㇸ\.éhgÄg;ŠèÃd2‰6#yìVÖ9ÿÎ)nZCBA»=ßÝžO «‘vü}8Öl:k›Žï|ç;û÷ï§se¾ôÒKû÷ïÿÿøö7?ÿüóû÷ïôÑGY,Ö?þã?îß¿û÷ïÿêW¿Úñ ¾ÿþo~󛽯áþûïß¿?P$û÷ïÿØÇ>Æb±~ùË_îß¿ÿ7¿ù ÞsàÀýû÷ïß¿ÿž{îÁ_¾ùÍoîmüÅðûAæi«¹¹9¤’°µ’ɤÝngPG‡Ãáx<~³ÑÑQ»Ýn³ÙZaaÉ¡G¡PŒÓ3rXеZ­P(Èd2ØpC°Ùl¤‘ëõºR©?:ŽMX®µZ <IÓÓÓ8«Áä¡ Õl6‰„D"q»Ý N§ÓiƒÁàóùjµšV«µÙlÀ r8œ±±±r¹¬×ëÑ M™L622R.—766`Ëp¶Ëf³�1ŠD¢Õ€ìÈf³©T 9H5b>‰DïD¬^¥RI§Ó(0£2W*•<i«Ïçóç…/ü¬‡R©Dh &y‚2™Ìb±ôÿ=x‚Õj•^#p»Ýt¬s>Ÿ‡Ã¥R‰ÎáÔã`{ØÃ|ÂCNн»V¡½�7LwN�‹Ñ¤õnm&©Îl6ÛQ»´Z­ãããô:iÌH§ÓÕjµmFc’íz§çee "²cubéX<�AIƒº\.H”öŸ©ôz½ŒŽ«`01´ÁÁÁŽø¨3Êá9r„þH2™Ì‘#Gþê¯þªýÍétúÈ‘#o{ÛÛX,Ö‘#GÀœøðÃw J¥Ò‘#GÐa³é5 2=räìñxüÈ‘#X7×]wÝ‹/¾xôèÑééé~ðƒ|>_$Ýÿý÷ßÿÅ_\.—wïÞ}ã7>üðÃoX¯ÃårQêï¿#FLC±X!)ë54Ô®]» A s ÓéHºéĉpð¨iÓ¿vuuuddÇ/qº¹Fàe @S�²&‰•••ŽX&ºÝ¯×ë©TÊëõ˜� œñññãÇ‹E±X ò‹Åb4Ëåòää$�{™Lfjj &¸P(ÌÎξýío÷ù|N§S©T6›Í@ 088ˆ N$ŸÏƒ3T&“+ƒµ„ „ÈžÍfåAo¸,š7jµzуL¡¢ðuj1¤(jdd¤ãŽž˜˜8yò$ hGÜD¡P8÷2˜Ïç£?JÉã™â/ …U‡Ã‹Å0ÛýØCºv°ÓéÄu…B¡þGæÃjµ …ôo}æÀÈÃíöCð¦±XÌív/,,¸ÝîS§NAuZ¯×ã°ºº ™c¢Á$È®éQ-ê%6È`‚ __û›»!jœN'ÄBQºØè›Wí6àr›ÍfûbE¯{£Ñ8/JT,ëòË/‡c?zôè 7Ü€?þÃ?üƒV«=uêTµZÕjµW_}5yÿwÞùÊ+¯°X¬}ûöùýþÉÉÉ»îºëÐjµ?üð»ßýnƒÁ@ç«-‹·Ýv›Óéôz½ƒQDMûU9ùîw¿ûÙgŸ=yò¤Åb¹êª«ÀwÞ‰Š P­&“I¥R‘rèŸdP% •Je7Á`‰Åb—Ë…ÍÌápÜn7ºk÷ìÙà2ékkk'Nœ˜™™•CµZEÝ€–Ëåééiâfˆ›œœ¤›f¿ßŸÉd€ (èœG/!øa].¬9–+Ǿ}û&&&FFF ´k×.³Ù¼°°°wï^Ðó„B¡ÁÁA§Óòùü¶mÛp"´Ûíjµ:™LF"‘^x¡X,¢—ëÀûöí3 Ð0[YY)‹ÇŽ›ššjµZÉdÒçóƒAz¯>Η`šàp8R©Ôf³‰D"zž¢(ü"æÃá…BR˜"ÌHR¡ˆE· ¨¥íܹS«Õº\®³Ó‘e³ÙÝvôÌÌŒB¡À{:q³&“‰.2ÄãñFFFAÒèèh7 Z­Vãóùãããh+Æ)Êáp(•ÊññqŠ¢@ BzzWèé&§drñDà´ÝèÑïˆ~ª“J¥&ݬÁ`ž©÷ž"—¡Õj<#íS144$“É—g±XäryµZ=uêTÁ° Âá0I_—úôiry>Ÿõõ�ölŸ&ŒvÇN$®Ûß¼²²Â@ô)ŠöŽñ>yíèÌÍ=>r¾XòÐ^«Õ–––è"¡DQ›È.`|ãß�÷ësÏ=G^…¿ü—ù—»îºËb±ìÝ»—¼ÿÁ|øá‡¿óïÌÍÍ †K/½”þë÷ÜsÏå—_Jr¾…BŸøÄ'Þõ®wá›1çxêE}úÓŸþøÇ?þío{Ë–-ÇÿÅ/~Ñ1ùF˜"àº),x½^ì´r¹œÉdp02ÑhtnnîôéÓ‡Ìd2zJ$Û!_(“ÉØlv*•âr¹B¡S×q©ÌÎÎÂiõXWR©tddD.—{<»Ýît:Ñî®×ë Ü 8Z—Ëåñx^zé%€ƒK¥Çãóù‡FâP…íÛ·F@°k×®«®ºÊétær9½^ãááa¡P¸e˵Z-“É„B¡Óéíž^¯Ÿ˜˜@ØcåËd2ðDàu:]8Îår C"oS«Õ¥R)•J …¹¹9ôW†Ãa·Ó;œHM…„PD:1ÄE]är¹Ð7½¼¼ÜjµÎB×çÔ©Sd»u¬èàÛíö†K‚îl’ðV«uee…h²`@a™”‚B¡JŒ‹úÂàùm6›íšÄCwÌÊáp Ýq¢7´›Ñk‹‹‹¤qB"‘08/à;ÿõ¸ŒD"ÁÀ˵ «.--F†‘…Bp3x@­VK,Ó¯A(â¡£…™qy"‘¨Gé¼Õœôz}o€<A¿¤Óé? óÝ»w¿ç=ï‰ÇãwÜqÇÖ­[Ï嫾ð…/Ѓqú˜žž~òÉ'»ýo¾ùfRÃ{饗î»ï¾Þ?ô™Ï|æ¹çžû»¿û»w¼ãï|ç;>üÆŸçjµ 0B&“I$¼Û�aAk4šx<. C¡È7­V+b¸ Dš…Bª$Õ–N§N§Åb1›Íô劌((±Ë/1¢+‹•ËåæççA`!‘HÖÖÖ€ùfp¤jµZŸÏ”91«««/¿ü2‰9Ö×ׇ‡‡Ùlv±XÌf³¨(@>Àápðx<ç×××zV*•—^z)Ú¤–——S©T¥RòWÞnȤR)‡ÃA®Éb±(•J±X îóéééŸýìg'Nœ ±y"‘€';Z x½^›Í¦P("‘£ä.•JÉÁK«Õó%°!ø‹Á``¨ÞÅt7P¯×_yå•“'O¦R)4e3`å<O©Tv4͌Ĵ9¬V+`)�XTéÌf3ä+e2™ÓéT«ÕÛ =”ŽY:-ü=ü‰D¨ÓÓý¹†>Çúúz(Â×2Zb=Úl6y<^ÇËë1Λ8Âöã©X,fT|é× ×ëÉAu–þY³ÙÜñ‡6wNp' AßiÓÞäFä´„X±á¹\nïU+‰ÚÕ6_ïñõ¯]©T>öØc.—ëöÛo~åèÑ£¿úÕ¯®¾úê믿žñÒ›ßüfFóßÿýß7ÜpÃîÝ»Ÿ}öYdzeË–_õïÿþï‘Hä¾ûî»é¦›Ö××ï¾ûnÖŸÉðù|¿ýíoŸx≎=çØÀ› ²„|>=-œÉdÊå²P(  µlà [¨R©ÛZ5Íf3�ètk¨Ñh@™õš‚-ú1Q�ˆÇãØ´ÃÃÃŒØhíP%‘H¢Ñ(b‘W^yE à{ ú®ÑhÌf3´wwìØ±sçN§Ó‰Îˆgƒ´I©T (•J `Æçó‰]&Þ‘l8§'NH$’`0h2™o)º;‰Çí¸£AY{úôiî ;ºZ­wHï¸/‹‡:tèÉ+ú|¾z½ÞþC$ àp8›¢“Õj5ƒýxH43œ“Z­fpÐÅpœ$umm «B är9xbݬ¬¬¨Õê·¼å-_|ñ–-[1ÊPëX«cÔ‡¤R)Ý”qÃ8¯®®ž´D¡P +îv»Û'‡ÅbU*•Ž{ªçaÿC*•òºK[ÐýÇcØpœ§Ï¦æ„ÇLr¬d˜L&¤Â=O;ø»Û æƒÃá´goH‹_·´Õßb~ä#¹÷Þ{IÁ‰>xànŸªÕj=ôý/?ÿùÏ»ñ|¼ÿýï¿ÿþû½^/#Èb±XúЇìvûç?ÿùûï¿ÿ]ïz×C=tÉ%—\yå•,ëÀz½þ»ßý.‹Å ‡ÃßøÆ7þ÷ÿ÷—¿üå'>ñ Lõ¿øÅ?·‹ÅŽ?~èÐ!½^¿uëÖ;wv|Òâèàr¹Èªk4¬ôýX •*«ÕŠÈ1™L.,,¬¬¬X,–±±±‹.ºsžÏç3™ 8Âëõ:›Í¶X,XÛð:|>Ÿ,¿µµ5¨1jhhhˆð$‰©©©ññqüœJ¥BÌÎf³µZ­ßï…B@ŠD"¡Ph4€J¥R*•Á`°ÙlJ$—Ë555µ{÷n¯×k·ÛQÒ€ÚºX,¶Ûíããã;wî§-t¤šÍ¦F£áp8&“I @:O¥RI$’õõõjµj2™ÀBëóùè0-ƒÁÀf³{ÐÔj5’óQ*•0åCCCðÖ¥R b"ôÒ2£€Á°VŒ¿ \ÇêÒNËù|¾½ñ5¿L&³²²Â°õhzËf³tƒƒ^lºaÑjµøiÒÌa:8(³(•Êx<NGñðúÓŠF£t ýJèÇÁ3Ò×kkk^¯wjjªÝýƒ¥c·‡½%»iÓÍ»)âëK¥ÿûâö(`E¢ßIj4Æl6;55%‰NŸ>M?“RE€» †;Iì ÂB ¿= éHE! årù¹Ç{Œ[o½õÁ¼ñÆõ«_á/ïyÏ{Ž9ò­o}ëâ‹/nÿG?úÑùùù{Ñà¦P(|ðÁD"A÷û÷ïöÙgüã?ûì³=öØ×¿þõþ/ìúë¯ …ÿøÇÓét<ozÓ›®¹æš_|ñ{ßûÞO<¶‚[o½õÏÅ9y<žmÛ¶uÌÑÛl¶ãÇ×ëu»Ýh]ÁÒl6£pBÊ!$õ„~À¾áÉØlv"‘€•¡ÓEçr9x Ò2…Ÿ€´.cùU«U W@£È,Ž‹¥\.‹Åb¥RI/IšL¦T*U¯×!€‹-�‘CÐßéõzðØ‚´ùòÌfs  ”]£££z½> ®¯¯—J¥õõu€úl6›^¯—Ëå<û—\@½^·ÙlPP¤[ƒÁL&{�í`ÚðmF‰•JÙWð6À4ñgݾ Oþ:;æ{¹ãÚWíæ”"í‚OFƒü^BWÝ[ÈårŠ¢è^¼V«ù|>…B¤" 9år¹»ÞF‘ËŠÅbkÚ§*@rØçwr8œ;v( èÐ/--áqØl¶`0ˆžëŽ¥8Æ_@uª¤óˆ¥ê±ð˜::ã¾ ä ?æÝb±,--MNN*•JµZM h¤'K¥¨ZWWWÉ N£Ñ4L&Jú,H$µZ- jàõz{�+fìéç‹Áèƒüà•W^ép8(ŠÂ içÎ<òˆÛív¹\ÿú¯ÿšH$Þüæ7 ;ôÈ#€íÿÊ+¯üÁ~P*•öìÙ311a2™^xድoß>«ÕºwïÞ+®¸¢T*=òÈ#‹eâÿcïMƒ»Ê3`íëÕ¾¯-µ¤^¦·ÏbÆÛcCƒ!„¤¾@91P IˆIˆ¿¤L*„Äìà¶p�³8í™±gz¦{¦÷M»ºµï»¾OùÔɽ’ZÝKŸò±Ôºº:÷œ÷=ïò<ÏÔÔ#<‚rôwÞ‰ˆ5>ô¡ÁÔå+_¡}Þ=÷ÜÃ0 Ì¢Åb9räÇûÈG>Bžôý÷ßË-·üŠ{¦p8\,o¿ývƒÁÐ ²g³ÙžyæHv"MQ«ÕÈ*B¦®Ýn§Ói†a=£YäÁ,ê l6 ñX"ð‹·Z-·Û ,ú$ Þb-<˜-BžþïÙÙÙB¡�†VØÇ‡×××É ‚¶ [B=C$éõz¹\žÍfÑâ:V2™Dì‰t­V “€¦…BVu( „•Ði…+J&“X<Ü)òù|P¦§Ý†ËåJ$õz]$étºR©$•J‰ =‰´0Õj•vx}ä|X%+ ½zÛÈ=ìuQ onn‚§•|ÜápÐdô Nˆ$èÀ L‡8n·{ii©T*à],£§×ë!fO»“ÉD»®þê¬Ä}e2™ôz}(²X,‘H$‘Hd2™Z­FÊqcd¹ÒÃçóq‰J¥Aì ¨~ËØM;;;v»„}ÖC¯Œ(Ç¥ ]Å4Áû899 \4¢ûááa°­ÐÎ †ƒ›Ñ&ž|òºÃáðz½&“ ËÜh€€tåßÎùK¯•Åœ˜˜ Êl·Þz+-9;v ÿ ¯Ðø'Ò‡áœx<Þ‰'H––üýøø8-jÇ$>Óh4\”Õm·ÝÆzejjª¿<ϯÔhµZR©4ôï3¾råŠÙl.‹¥RÉï÷¯®®Â”#|!ËI.—›Ífú633såʲ0ÐJ„@mnnîСCÄiU«UƒÁ`4£Ñh«Õ"‡J¼e·ÛK¥~r(ÁÇb±‰‰ œÆHêÆãñ�ð„Ï‚Ú5:NN‡ÆÔÔP)õz],'“É . û`ee@Ýx<®Óé º°°‰D‚Á`4ÅŽK¥R‰ÄçóµÛíçŸ^"‘x½^‡ÃADwü~¿L&[[[óù|[[[*•Êd2‘K,#ê!d$Y­VC'Ì:ÐÄJ¥r~~]Ä A˜urr’î®v8„̬\.Óf1“ÉôÙ¶¸s5 ú åóyê°$hAØP•JÅ:³ÓΉ•IŠÇã8aÄi¸óÑÑQRÕçÚÙF£Á2̓@eáùÀ²(•J¹±;Ü<èKpc?úцÑét+++ägöá¾ëJg7¸J$}€@Ι¼‚-ƒ ïúpéÝÄŠgþ—sZ^YfÝW¯^¢mbbÝäÜ ,“É B€ç„T2Ò£££„9]^^F‹$B.rAxx±X { E,ǃôËÌÌÌ… :4;;Ûç)’¢ß¯¬ ÞGíoÉ€ºÒ®ùúR©´¶¶ÖjµD"¢«l6 £ïóù4ÍÜÜÂÁ Y~¿ssóúë¯?sæ Ã0f³yss“ˆÒȵZ­P(ÐôŒTÛÈÈиZ"‘èZ¹m4àUš››+—ˉ„…È ‡Ã­Vkjj Jw :zô(JЖU(` ¯Õjh+—Éd&“) ¥R©x<>55… ìAKKK�Ë………«W¯B$zyy™p7‹ExnÜ6ˆÏGGG@JIÖ$ÀØŒH ©£ÝnW«Uœ`ʃÁ ôdY³‰D0¥ˆ‡x/vgÄãqòÇè®»&iÇè5È= ®:1<<œH$H(Fwº³b&œuàS3™ŒÃáXYYéã)é¬ íäèøƒk*1{ûÛ™L©k¤E‚BXQ¸’0¤Kz###\Tè5I29ŽZ­Ff[*• vz�� �IDATáA€ÀDš’$ÛAûßô»¿wnnˆ ^>÷™knþ—&—Ëån·lN^¯3Õét¸%¯T*E�Õ]CÅv» A9ª6› ™_L}±XL¥R]7k„Ûøß_±Á'N¼ï}ïëŒ>d¬ÍÍM�iK¥’ÏçÛÙÙÁzÈd2 ß‹Å@€,Z‘H”Ïç@³ÙDG�8î²ÙìöööÎÎ\.é?ú¬DZ’Qø!®trr’µÂS©”Åb±ÙlÛÛÛtÜF`¹È+f³Ù@ Éd¤R©Z­Få -ãH V«U£Ñ˜J¥P6(‹O>ùäèè(2BårY£Ñ °ßn·kµ u:j!;;;•J%ŠÅb®ïìì�8U.—!HšJ¥†‡‡S©”ÑhdÆ`0t::‡ó,ök7=F´`Œ¥R)Ö–ôûý`[__'ÌùKÔ{öª¾Ö+và 7°Z92™ í!ÐKÒë`}ájµ ³Þ'Û™vL2ŽüIJ>åt:…Ba‡Dê[ˆ¤‘¡)‹´u¥ï~düD.r‰‚to×Ûx錬”l»ÝÎår¸l>ŸÇ$­Êú]ÜÛ`‹ ŽŽŽòx?ìuÞ‡F'Á!“€Ù$”'¬s x »ž‰ú¼•Ëåž~úièhµÚÍÍM|…P(Ý2Øcûmh*¼ƒñ›4@™ˆ £Õj±ºƒäryµZ‹Å4fbhhH¥R5›MèøÑçDP¯Ò(¤mé\øÐ0Då¦T*åóùùùy¥R —CoËÅÅE–h‹Ífƒg<Gg0t»Ý‘HäÂ… N§‚¹ñx<j4äÁ:N4u»ÝçÏŸ‡$RI‹%‘H JŸJ¥‚Á °5ÑhtssÓb±¥¥¥b±wØòs†††d2Ùüü<:9ыߕÍÜÉd’»›t:ô1«]Úëic„>ïF£Ç4 @^"‘ôß섳jðÁZ õz½Ñhøýþ`0H?PDóÄϵÛmX9D û1NûÓ?j×δ„àÊÅbñÊ•+ÈØíö]yx%‰ÛíîŸádÝ9YÉÜ ­>6]¯ƒ'¥$‰Ýn熹h+í«¸®û k_<¹3tkccc•J¥½.+“ÉÐ_ÛKðjiiéìÙ³sssçÏŸGS,CìY­Vw…:Éd²]Avã×zƒA¬l ¢Ñ(]£BŸiÄb1Þ*•J+++@¿²zôñV2°5\±T#áÌ€0ÞÕh4‡ÃårÑׄ ‹Bû€B¡…BÛÛÛ@w’œO½^Gý²ÛÛÛÉdrjj*“É ¤€ø,äׯÇÇÁ-D‹Åñ\P6Äb±l6ÛjµÔju4Íd2(Ö¶Ûí`0ȪѮ®®ÒFS©T¢ž;ÕÉd¼´t‹3‹Å¢P(ìÃ3 e5š Gâñx„6iÀ'®ÑhèG ˜×žÖ W ?BBóL&³°°�Ï%\Ç0 ýmÂIO0 •J%4â³¾‚fbµµ5â9H†S¡Plmmõ÷LàQ¬Õj´uU©T¬Yeµõ£e¬«¥…Oy7R„âb¯iä>/>Ÿ_«Õº&`ív{¯Æô> Ü~ÝzFƒîÞQ«Õ4I{ŸQ.—Ûí6Ã0à* °8]B"º—Ÿ€€(YU«U4­²êŠ@›§Óiø¹}'vÆ¯ÑØÚÚ[[[£Ï¿0ÄÈ]²»\.'“Éjµô÷èžR:<‚¶S±Xd¥> ù€oåñx&“©^¯óùü••Öñ?•J©T*ƒÁ …Ðí](XçD£ÑØh4 ¨T*K¥’Óé, ###À”Èåò`0X­VAWƒóV6›ÝØØ€/„L§Ób±X§Ó™L¦x<­(ƒ ˜Ä0 4Ójµ Ãø|>°jñ^Ô †‰:j{{~›*öºÛÁÏK‹´Ái †J¥‚¯S(h¾…A„ÞM*•BûÖž4EY2%øjȨ³ö»L&‰DtY^­VwÍ}­­­Áq➆¡cq8§B¡ÀMâÛ …=,[ŒA¡P¨T*V·W×ѶÕkà±hH†a «³J'­V+ëtº^éM`{”J%ÍQ‹ F£Þ&ÞôcÚ_NKÔ+ðDmJÆØ¥&“ íyƒ\—@w‘ìæ½È­‚×É4A!—õqv£CEZª’>Ëà+°€ÑétVÛƯãhµZ‰Dበo¡öP.—Ëå2ÄS4 tÇív;±e´h²Ýno6›Ñh”+4ކ‡Ã‘Íf™?ùÉOœN'‚…BC`±X¬V+|º§H(O¸ Ëf³n·;ŸÏ—J¥©TÚn·WVV‰²…à%jµZÍf,û z@ÜÃ0L¹\†+Õjµhy�ýôèò ùŸt:Ýôô´ßï‡TnµZÅDašL&ܽ¡x/ªƒbÏ"ƒBÚ« C±XÄɵaò)ºJMc‰ ·HÑÑhd®¹”J¥8bM”É‘‚¾ž.t´M†H$¢ûÖè)b³±º®½^a<1yNg{{{bbŠ-½V2æa¯ùî‹]›îºšJî<pÑh„bH¯y · EMò˜¸ÉLú1íotç\�~•+t4NNN0±™þ•Ëå Ã`Äb1þ“ȪOÖëuP/sõ 1§£££HXƒ¸¯Cî–ÕüŠ&«z½.^ŠÂãÁø•åËårV«•&r&e:”‘J¥¹\g)£ÑH– ŒEy¦ÝnCH‰FÑÇb±Z­& ü¶¶¶.]ºd³Ù‡Éd¢3 øâóù¸ºXRPÎ×ëu¨Le³Y³ÙŒhÉl6»\.·Ûm·Û}>ä F£ÃáˆÅbh……B!•JU*½^ŸL&Aôi³ÙT*•X,ŽD"J¥Y>ÜÉ:êtºááaÐí a•¼½Ûí®×ëäÐÝD$Ò€’ l4‘H„ëcXšj�B‘ùGî±k=I£ÑÜtÓM£££}’x¹\ŽðqoFóÓë@Ãm`#"O8(pk$,Jë-ZçVÚc}ó>º‹µ¢ƒ{W 1@Ÿ[Êçóàá¶Î‚k˜¶ØÄÈ÷ñ¾ôcº–Ήȟ‹D"—Ë5>>îñxl6›X,Îf³ð[,öYTØà‡­¾CfD*•º\.£Ñ8==|7ä´aqºÖÊ l·ÛPu#?›Áá§Ói@úLùoÒp8�¨Ân¢Q 6Åï÷£8AL¤N§‹ÅhÉs¹\'Ož¤«r¹œÔ;²Ùl°P´‘‚1‚ä———C¡P2™”H$ËËË ‚ ‰D¥R)NãÄb±Ãᘞž>vìX @k1IÛÛÛJ¥Òét"å…,ÇãB¼‚rÈúú:Ñ´‡^±X\^^FÌÇ0 ˜ò!ì‹£+±p-ðO�Áðùü\.§V«õzýØØaCÅ"“É-ò:ì&lvÄ@RÖôü÷~¿gg'ŸÏ£ÛeyÇÆÆ|>ò]=Z­f•.|>ßöö6œ_/$/yËét"¢¥%Ly<žÕje³ëõ:>ÉvòzW£ª{üo¥R©V«æúçôz¹R.8=hËF‹ 2úLpb±x}}[šŠ¤µJ¥ÒÐÐP>ŸßÜܤs×q­Æ. ØÓÓÓhŠ•J¥L[XXàRÌÆb1>Ÿ?22²¼¼ ‡°fd|||ii ýš4iV Y©‹r5@ à-r -ö±±±®Å4"‰ÍßûÞ÷útOj4šS§Nx‚_Á‘L&±‘æõù|ét™„H$‚…AÌ –‡ÅbÑëõÐÀ ‡ÃgΜ!ΉœlÏçCÙ€{ÊS(^¯÷Ê•+/Â’Îçó.\ÀÙ ½Ú'Nœ‹ÅÐ¥%¸ \.TI»³F£J¥R‹‹‹v»}ɳ³³×]wÝÖÖÖêêªÛí¶Ùlkkkf³f±X,b;ì%ZêÝnw¹\&Äš€'£’„¦)”²@N‘N§õz=‚¤L&ã÷û;ŽT*­T*ˆíX•q„ÍZ’Ëå˜" ŠÅbÔ'V/F� \M&Úâ»ÝI_pOu,¸UÖ=póoDN0•JÑoU«Õf³9==M48ÔjµP($aÜv2™Ü·ÿîó‹h¼ªÑhäóù}¨êÜnw*•ê/+Å tzQ±æ<NCKºÑhX­V¨$ó^D‘?³Ùl•Jå¥Ä »8'àB¢Ñ(ªÁxN¨nq;*• DÏ茟à#äÉ¡¸M?H2Ý4Ë©€‘l¯¿=Q]Ó’r¹üŽ;î þïøÀW¾ò•ï|ç;„'â`üŽZ­Ön·§¦¦æçç«Õ*é#NezzúòåËè}‚l«J¥²Z­HØv:H$a¡N§311±¾¾ŽÞ\¢:Ããñ&''—––¼^/ŠÏFÃår¡s7€óòòÈö W—m·Û¨Š¡U€ßÉÉÉÍÍM³ÙŒh©\.#ã ðß /¼ ×ëq*Gï ±º¶¶~¦ÏçÃaqcc'H[üo­VÛÙÙ1›Í`ùK§ÓóóóÈRBùåܹs­V Ò‹'Nœ¸téÒÈÈa|àf“�Š‚<¾ ]ï•J…ÔçAÊ@>ÂÍm`³÷Ìáà*³X,dk³®ÓI?©ÁGn·zóÜËö‰?È[àĉ˜ù¹¹9r.ÿ«-⥠ø‹ºFéߢbÜœN'¢=­V;??OÿðÁ½i§Ó!…¥o~{{û%Öþû9'‰DN¼§Ÿ~Úår•Ëe‹ú$. ©q*¬…å+rnèCóTNNNâjONÿåþÈŠt:ݽ÷ÞË}4äi!åëc±XPdF àðbµZÅbq³Ù$‡Fƒ„L,Cûr,c• ‘[8 ŒØëðz½kkk„e±Ñh ¹†•“ÍfqXs»Ýsss ÃØíö«W¯Êårdz±±a±XÀw‡qAœy‘#d©­V‹†ò„B¡x<X·¶¶FV2ð¿ËËËFcrr2 ‚"9„B!±XŒ„Ûòò2:ˆ{¬Vk«Õ:yòäÙ³g;N:F-Í`0ˆD"܆T*ít:›››É‡Ã;;;/¼ðÂÄÄD(ît:(ÀšCy `s¨T*õz!&hmS©«ÝK,¿ýío¯×ëgnnUwÂÅÞjµÀù‚ìp8J¥ÉÕÓgmz³³ì@¯ÍÎÚøÏ>û,+såóùÂá0ëä•Å«W¯"~ESÆ®¶•î&èz{¬ÒùQívûÊ•+8‚਄×ÀÊÊŠßïm™ œ<öí¥výQ¼¦ &K*Þåríìì`Š˜Æá€Žv¬yÀª v²O" |.äoèOu½Ô@5'tâbƒA¿ß¦ÕD"AÞê5¸\&“Ñ]. …bp• rµl6ËòL¿4m§Ûo¿ýÉ'Ÿ|à^ÿú׿ë]ïúä'?ùÀÜ|óÍßúÖ·Æ÷¿ÿýn¸á¸ûî»?øÁbçßu×]ôGôÝï~wzzú/þâ/âñø{Þóžûî»ï8~ü8tÜÆžW÷Z­V£ ?$ Éj‘J¥2™ ˜¡X,öØcår¹•••P($•J£Ñh¹\ÞØØ MžH$‚Šj0W¯^…¼©\.‹Åx+ŒŽŽÇãr¹°’ÑÎêr¹¦§§Åbñ‚ÑhL§ÓJ¥òç?ÿ9¤§@Ñl6—––.^¼ˆB‹Å’N§“Éä‰'ŒF£N§Cåc{{ΕJåìÙ³'Nœ+—ËW®\Éf³ØM›››‡%? ¾ø333ËËË—.]ZYYY__±X,•Jà|xxxddduu•TºtéR»ÝÎfccC«ÕüÓÐÐP§ÓY\\$£… T×'¥P(ø|>Ë@¹ªÿ#WWW«Õ*Wèܹs¤ª-‘HHw˾÷"lìå™h%zÈ‘hqqñìÙ³tœDäÉÁÎN^és ís{|>D9ýgÉh4Ò7\­VéŽíb±m·ÛÝjµzm ݧEÿ.†a<Ï€ÛÖf³aå@ª˜û§Ï ž|òIÖKz½ž4l`Wd2|Žuø²Aä°È&¯‹E$U¡¶ok5¸‡{‰£Óé¼ë]ïzâ‰'~øáï~÷»‰ä‰'ž8vìØÛßþöL&óo|ãmo{ÛO<ñŽw¼ã³Ÿýìüã÷¾÷½Á`ðK_úÒc=†+|ãßøæ7¿ùþ÷¿ÿ‰'ž°Ûí¿û»¿{àlö:¸¨F°PB‹eðx<•J¥Õj5 öÀ¯ìv»M&­Óé´Ùlô™I«Õº\.—Ë511aµZñ@<Z­Öb±@Œ`}}]§ÓµZ­µµ5¬d•Je³Ù€äœ€8f³Y¥R966†KY,tF(ŠF£(z³Ù¼õÖ[;ùDµZËå´Z-üú¼@ ðx<‹Æâ…^¨Õj p!?=è‰äå/ùÔÔ´}¡è*‘H3™ 0RÄÒ¡wcii YJTY’É$ä€è2 Dƹ‡H$¢ÕjaVX rF£‘Õr-—ËqÛýýSŸÝ³C¡ªkžp¯ò¯PÏÂ"Á<°BH$²½½ÍÕ]CÍn§Îçó‹‹‹}TA|Óë-pÒsÝÇw­è˜ÍfÐ óùü^Õ,©TÚç>I­—\ÅOÑGl8eL]×* òÞ=WÆä⬔—Ûí–Ëåáp*b±¸kó77lJ&“]³¨�ÍíÛZõL!@ð‹¶˜"‘èŸÿùŸÍfó£>ŠŒý¼?üáÓ¯üä'?yôÑG÷Ä'v0hÇE™ ‡ѼÙl&–(™LÆãq°nmmAÁÍÐ�Â=˜Íf$O°TD"ÔÐ- 6b`ßÞÞƒx±X¤é%‘µCƒ¨B¡ƒ Ãx½Þl6 À»ÝÂ:Ôæóy©Tº´´”ÏçÛí¶L&3ðF£qxxýD2™L¥Rá€*hèu:­­-¨)* \ –L&?£ÑˆühÝ ¤a˜@ À0ÌâââÆÆÆ¹sçè4&™pvÐfŠPD‡Pñ’ì@¸ør¹Ü`0d2D¢ûØÑF£‘UÑQ©T2™L¯×÷ç›Ðëõ½`¿äö¸‹{eÒJ¥ˆøv]±¡PUOnù€¨vÅ-õy "¹ÜŸÉ5¤˜"ÄO[[[V«µ¹.•J¨›+Íz8¿>‰•ÛŸ!íJV"ú³?û³ÿçôÿ×5´´ÙlXÇ…B ª°ÂX²`—çp8hÿLþìv{,£$Ýé' =dÝëj{¿ÙÜV«õ¡}èG?úÑ[ßúÖ]{:ÁÝûÇüǽx›FŸÑµ} MH®WìÇ'''×ÖÖ�tM¥Råryll kX ”J%x öé8 Ú€Z­ìt:¥Ri"‘Ðjµ¥R û]‘HBï 0V©Tõz]¥R©T*ÇÇÇkµšÑhlµZZ­6—Ë­­­U«UdP±@Û7 À¸‚Õjø½ÝnCýº$\hµZz½Þd2Åb1ð/?÷ÜsôÆÁÎ…î†L&£;ƒVVVp$W(Pè }Iø]ÜY%;š–.$N²ÑÂÎbUØëFÆ„èõzò¼ ÂÍU^oÌ,}p8à6ìó©®Z©}\3„‡¾¶%ç®?„þèE ÂA>ø½!ŽÈ²VÓà6dƒÙ÷Ãòº&“ ™Pº%£T*!SÏãñÐ !%ò)ì§éØFèE÷ÂÆIÇ}}ߌD¬ÛûÅ9§Ï}îsv»ýôéÓ¬ôz½þðÃÓ¯¼úÕ¯>}út6›íÓ°t0ö4Àˆ @ÉÖÖ÷pC–¾×ëE:Å|ø³`0HV2ø¼QÆàÒ¡*•Jº<`±X€»,—ËÑh´T*¡ÑN(®¯¯ƒã R©€{á‘Åbw:'Ož|Ík^óªW½êÆo<yòäÌÌŒD"Cc¡Ûí/@µkkkÍfS*•2 ƒ /›Íêt:†ajµZ˜‡­­-D'$ûky\ì# ·d2™Ùl]ÅÊÊ ±³8h£Ë‘•æê:«]÷&±„ »\.ïÛ-aÀàÐ@W ;»²Öýbd½º^Ðãñ´Z­®MØ€K÷±¡x¬tœ@ èZPá¥V«•N§É‘J¥ÜÂÒà’'àÎ §Œö®]/Ec¥{##‹D"á¦%‘%&'ŸÏׇ‰‘~j¤ËÿM,ëÿ‹Å"™»Á• …X O*•úýþB¡ ÕjѯÕjY¹`ä(¸—dBÿ‡H$ú·û·ÅÅÅûî»/‘HÜwß}ÿøÇï¿ÿ~§Óùàƒ¾úկƟÝ{ï½÷ÜsÏG>ò‘ûî»ïÓŸþ4yý`ìo +‰ü¯B¡ðûýè#EˬN§'ûN§“L&ÉÿšÍf4Ýe2™‘‘t¥‡Ïç‰DÃÃÃjµÚëõ‚ž•8*«Õ*‰Ð¡NV²V«¯ˆK ­Ž˜¢PPCäv»­V«B¡�S�"‘}‰dzzÚd2E"d™“¬×뉤T*Ùív@s%F?E>Ÿo6›@àðáØ"™Læv»É‡{†!€†P,ïÅ <¬3Í�Dú×y<žF£¡ àÜcÍîÇãTÖ>†Z­æzHïúY«Ôg¤R)‘Häõz¹oét:4ŒtµË¸Öñx<¿ßß‹¶Žår™UàÀÁE«Õ+ïõzi ˜N§ëU—b>ÎRæpô§2À*âFôc*‹ƒã½êõ:÷ÃNVV*•k¢'›ËåŒFãÈÈê·>Ÿ›*‹iµÚH$Ò²‡†‹^4!×* „Þø}ï{ßÛÞö6Çó½ï}¯œ:uêÙgŸ…1úØÇ>¿ûî»ozzË}ºn·û¦›nB¯3>èr¹þáþxzÏŒ}z½NRÊN§sllìòåË8/ƒ(oxŽtß ÂÀ߃A@zÎ"#—Íf#‘Èèè(xèwŠÅbg{{ûâÅ‹×]wÝÑ£GS©T,Có÷ÆÆF4=zôh§Ó¹|ùr �ŸZº!Ëýì³Ï¢‡Ðåri4šD" …œN§Ýno·Û¼²Ù¬F£!ÁÓË_þò^x!¬­­FÐiCÛìÆol6›óóó.—‹–òó,¦¨Õj‘S#ïED-7ÃsêÔ)£Ñ‡ý~2™T(ÐìH§Ó´½(‹år™L9(ØíöõõuÐ:Îê­ÝÓ�õÆ/4àž˜˜èZŸ…BÕj•a˜®}t¨9ñ8 Ðõî/õR*•Ð̉W@šEßjÿ+à1‹ÅA&\¯×»\®H$2HV ¤½ô+›››Ä!œr×)Â×Ñz`Ü�ý´ýNÿƒ$wÅRy½^Ç€´ØÚÚšœœÌf³r¹üðáÃÈH|þóŸ«J©T–˜ê#N§÷—¥qy}†R©|ãߨ5SÁõ²Z­èÉ!l" Ã�å�ƒ¥’}ë[ßúÔSO={vgg#8­÷bŒ?ƒŸ*€íÑhtrrÖäþçÐ�H)B²%ð)’7FKw§ÓvœH$ºté0 ¢Á`h6›Åbà•P(²p·Ûm6›“É$ŠRP)l·ÛȵÛm¿ßþüù;î¸#—Ë¡³ÀjµÖëõb±(æææŽ9’J¥„Ba0Ìd2>ŸO¡P@ bkkkhhH"‘@A$¡•\«Õ9rD(;v `&4ûµÛíóçÏCTÈœcŸ+‰ßKæa||¼«ÌëáÇ;f2™4�VÅçói'±¤­V‹v„ÀD§Óé¡¡!:Ÿ&^ŠD�¾è´Š�fIy±r•¥R)•J¹\.–Å'fŠ <ÈÚц‹@¹¡Õ´kº6¤ä1a­rÿža`{x<Ž}¼ãää$p8–¡ïfðíF¿²¸¸ÈzÅl6;ÎÍÍM:ÇFn^*\s …P#¤Ã]œSÿCŠR©4›ÍÜ¢2g¤E"Q³Ù¬V«wÝu—Ñhôx<Éd–Z*•ºÝn`ñèßyâÄ  Xbðª :z%ޝ{Ýëèúí/b|þóŸýë_çwâëþå_þåÀ¯\“á÷ûQZXX(« „’H$SSSÕj^äÜØØ@ö€´»^¯F‰Dǽ^¯H$·Z­f³YÄÓ…B®íH£ONN&‰b±ˆªÃÅ‹±˜ÕjµËåûïE!æ‘‘„\ñxŭÇK¥ÒjµzéÒ¥™™F³¾¾þÄOÜ|óÍÈ1^wÝuÐeW«Õ¨u:ááád2™Éd ¢Ñh s'•JŸ~úé#GŽ\¸pavvB*•¦R)¬©TJNßWmµZ´x< „‡ G0¼|ùò¹sçpÀ‚<]*•"ggˆ Д¯<³GPÏdŒ_½z•»‘% !˜¸†¶h׎$Ø«þ@`âZR©²äá‘{ú‚ „#›a½^áA´Xh*új½¹>@8ÜOÑ*ív»¿ð }؃8'Ôb®\¹Bž;ïãp1¶··É$O–Ü^Ÿ/BÚ,›Í>|xvv¶Óé�þÁvNý V¥R©«xt¢ ˜ÇcÇŽù|>S ¾¡�� �IDAT§Ói±X´Z-ð('Nœ˜ŸŸïêÄ¥óÑ5‰Ém°ßóÿ‰ýæ7¿yàK®ùˆD"N§À4•‘…çt:+• | ª#B¡pggG¡PàïÇÆÆ:ÎÒÒR¡PÐh4 pƒu–Éd^¯Ë†EÓét:¶Z­ ås»ÝkkkƒÁívÇb±­­-‘H„"Ç»ùæ›C¡ü“Éd^__¿xñâáÇ›ÍæáDZuÑtŽ&`Òkç÷ûA&"‰Ö××›Íæúú:’~нít: (K”ËeµZ /‚@R õz½_‚èm{{[­V‹EØ †a”J%H(ÖÖÖΞ=KSˆuí€&«m‚m<BW‘\<&4š_Û…!‘H¬Vë®bQF£±X,Ò! %I¥R1 µZ ®·ÝnÓž‰Çãý¶²²BÑìЫè„Ü€…|àÄ‘/ËüöW‚ïu2™làÐТR©dfWU›Í,níÚH ÄËæóy.ÌfÐ~k˜:¹™ËåˆP«Õƒ&�\ã`ñARkB©TnmmI¥R…BAƒpA½éý nußmèãWpèõúµµ5r:«T*¤a}}ýêÕ«ä,’N§wvv†1›Íb±kÚƒ*•*‘HÀ:“LŒËápŠ‚¬oÇã/¼ðÒ}p óóóèý3 F£Ñ ì:•Jåõz|˜Íf˜N�ž çæv»e2™B¡Ðh4 ¨…F†ßï·Ûí¬ÃF>@«Õ.--ÕëuƒÁ‰DÐkg³Ùr¹p'ÀB ¥�âÁW45Éfçóy˜À'Ÿþyºð.“ÉÈ.#H[înÒétP¶U«ÕPOØõ Âãö±*ûµZmWÏ$—Ë3™Ì€}ƒb±§øD"ѧ) ›Íõ Œ|$«žÍçóI@�µV,µkýœë\g¼W]`ÜÀ€µÀååeØäB¡0ˆ^ÔÖÖ$cÐñ?ø-qu;wqN4C=#½`ÀäñcÂomllÌÏÏG"‘P(téÒ¥sçÎýìg?²L,£‹t±s™<È=ÐÑO*•byW¢Rz0~³„õhÓÍ=úoÔj5M •JQAç4”^!‚Žž+˜lÒùªT*ᱪժÝnG²¨kc±Éd*—ˇ•H$ WÕh4ÃÃÃÕj’êh…�#ƒÇ㙜œœžžN&“.— Ù¿|>Íl·Û‡††t:üP&“A™J£Ñ=zT©T¢¯L ”ËeÐ&°yr¹’ ¨T!ñ‹Åt:Zɉ¹Á¿YSd6›¨Ô”N§ÓétZ­V"‘pÑ'î†_ÙØØÀ}:ƪF ôô·*{ô™c×/¢ç[yÄ"[­V½^O@»åryee…ÕkЇ£Ï”œ@h2ÈÏ …¤SéšÛCàÓûÜyWÿ„´×fÝÞ^Ç ‘S6›¥mH$bíÛD"±µµ7:Ô ÔŸzê):ÐC¶1N“[­V¯Õ°kĉêoÃ@¿k‹² zè¿býëƒ:b}H‰Ð 4ø3£Ñ˜Ëå,ËÐÐÐÐÐYäv»]£Ñ€eˆZÒ|ÇÁ3$“ÉFGG r%›Í‚&‘Hètºz½ŽŒG¥Ro‚P(DMª‘HäâÅ‹W¯^î à\Ç E™Ïç·¶¶°k*•ŠX,ÆM"¾!8eX8Î\.g0`ñéÙ€€úÐÐ ´�ë ÁxbŸrwx}îìº+ /Ô/g…Bò,�æfƒXÇü®}½F*•‚@I4e‰<áÇ¢Òɪ8˜L&b¯é¾ÓwdVÏ ÙíöA¨|¸_IJÉdíõ:ƒO,Ã0,ÏÚÅ9¥Óé>ÍéÀåÑ}AÜn±H$òÄOœ;w. Ñ-ãH�šL¦>ä­äú·•×ëõ}´ðŒ_»Vx#©Tj·ÛY*D<Ïãñ@ Œd{ÄbñØØX*•‹Åèu–Ëåtj%‹Šn‘H$‹ÑŒ¾°°P©T, ÉA÷Èn·Ãâäóù‘‘Ü€®ÙlU"/€ÂÜårÕëuµZ=??xh}}½V«Áiñùüb±˜H$677Ãáp$Y[[ ‡Ã-¬T*ù|^"‘(•J›Íf0Ž=*‰|>èþúWÜmµZít:^¯0Ð¥ƒg¶Øãñ°¶L$Éår‡4#W™H$Ð:Dä}ÉÙÂtV›ûân[›ÍÆmw‚øµZ$Åb‘FÞÐÜzz½žU8ÀÑmÐ0Žjš Öß 3¢kÒápp ‡ˆœGÿA¨Fè{æV§*•JŸ PW°W×ÇGVÑž™¢AzЀäÛs䄜8²áØÛ,°k@5Ý÷PëÚÞÞ&§Thz …^Ãf³±RØÀÏØèßÚ‘Ëå�`Â"Îf³\êVf©X,‚­ÉȰµZ-:€¬±±1ƒÁ`4qM¿ß6î••Zˆ]$]½zµV«­¯¯ g=dO¸h4°˜›ÍfT¿kµšB¡Éd÷“ËåÉdR*•ÎÎÎÂ8¢õ<‰ ×W(Z­R|ÛÛÛ ‡‰Dh ãóù±XL­VC†ªZ­J$’d2iµZu:]6›%`#Ø}°‘Z­ÖC‡e³Ùd2)—Ëis>ŸG3m«Õ¢'�)`Âè×1«v»]"‘…Bh9ø¡),‹‰M䊾”a4éHgü»+v <ôx@Z™r¹L[|‚rNb�>Òþ ©Î|>OVr¯AO=ðE …Á˜»^Áb±€¾6“ÉÓ¹2§ÑQ«Õ/%A7HHµZeùÑ]œ“R©ôx<ù|>›ÍîììT*ä4¶··ûË “h.›Íâ8366†hT¥Réõz0»týT2™dÝe¹\Þ[„T*íŠü?¿¦q ‘–)—˃œWFFFÄb1í«l6›^¯·Z­•Jx&4—¢ ìv»Z"'™Lz<r¸ÞØØ¨×ëHâ‹ÅãÇ{<žT*e2™Z­ÖØØX>Ÿ_]]F£B¡°ÙlBôèÈ‘#«««¨ªB‰§ÝnkµZ@Ðjµ”J%kµZµZG§Ó® \Gà\Édõz]¡P´ÛmƒÁðßÿýß/¼ðdÔ—––R©´hN'üj4+™äêõz<___Gf¾V«% £ÑˆŒ¥Ïç“Éd¤_‰ËƒÜÙMè¹�«i»Ý^__/•JðON§xèÐ!:­œr¹\ÆÑi×0wG€†‰„ÐC‡ñ¨f0ZG›¶*´u¦)}éUÔ5aÓ5Æ*‹è3™L¹\޶o…Bh�=éŒëäÝŠªÕ*’,¤9ËFVjоÖRÙuììì Âη×ÁZ*¬!ÚõŒ� 2ò ÚêÝn76[ÿ#�‘ƒãñxD½”›ˆ›šš":r¼nšŒ{ÅåÕjµ—½ìe¬×¿úÕ¯ö¹ŽÙl¾ãŽ;È  oƒt—‚]f¯Ï�{ ËAÂÛ}Ñoê@Q„Ïç“¥‚myÓÕÕÕv»M/64‘"’ÀÂ[[[ÓjµÃÃÃèÌ®T* ó©V«étý h“C»ÁÅ‹¿H§ÓÁ`ÐåréõzTŽ9"‘HjµÚ¥K—, 8Â/_¾Ìçóï½÷ÞD"åg±Xjµš@ X\\ .—ëÉ'Ÿôx<×]wÒeÍf¢½Ð£@$cF£T*;w®Óé8Î\.‡28Éã… »ÝîóùÀZËÂ˃') Ò&ò€8ê`°ÙlbV¡Rˆ3%£ÉÞD[³ÅbiµZÐóæñx7ÜpÃ3Ï<CTº£Ñ(^_\\¤oƒ•# š€¦y<žßïG_âàe rýV«E€>t„u½ª]­R©´X,ëëë½Øù¸ækeeB¸ (ÛÉ à¹ô²<Äa�ÉW.—{qbb'ËÒŠÅb"6Øh4677Y3Ðõvµá½lr×y ÍxW/Àý“ WäAëÖÛív»ÝžŸŸgQœuÁ`0NK$¤5xݶóóóל«»ëŒ7fµÎK¹ÿ™ŒÆ×½îuä/zè!Ý~ûí§NºãŽ;¾ð…/¸ÝîO|âû¸™O}êS·ß~ûåË—ùã'Ÿ|Òívÿã?þãO"0øz½NV?VQ0„bÇEûd;´_Qj‹Åà%¹páB¡Pðù|ÈòÍÍÍi4›Í†HÅáp˜ÍfÔd2¾Ð×F£ñÌ3Ϭ®®¢—!looŸ?¾\.K$’[o½ç÷p8|èÐ!pñùü믿^£ÑlnnÚl¶ãÇ£˜T¯×;Ã0èɾþúëo¼ñF·ÛMŽÿ^¯÷¶ÛnÝÚÚR(×]w݉'fff@¼%‘Hb±Ø™3gD"ÑÄÄJA2™L  ÝwáÂVêF.—»ÝnÌ×ëšš’J¥sss‰Äd2Æ)‰‹‰ Ç ' ‚,æñxÏ<ó m"�án½®ÈzµZMšVWWÇÅF ©IÒŒ|ýEò t¥R ùÀþœ�äæææh¡?œ¢èjµÚ>y&ò-«««ûŽNÆÆÆXbƒ4+ý"]î‰D###{=÷ꔡ¿###ØAZé]"'‡Ã A Öõð¢T*‘‹ÀЏWš.‹øÒáptUmACmW´ï5âBÍñ%îë÷<ÿçm{!~éK_𙙉F£þçNbÇD"qÝu×Éåò3gΨÕê™™—ÂáðÔÔ”V«}æ™gpX0™Lccc÷ÜsÏÑ£GQr;sæ ‰ÙlÅ)D,s£½ƒÑË4ðù|ú€ ¡[¿ß®6744¶´£G–J%(JH¥R‡ÃÇ«Õ*òòØ®N§3‹…Ãah2©TªF£AŠê&“)NÛl¶H$âóùVVVÜn·Ïç«×ë‰DbddD&“)•ÊjµšÏç ¸ò x@í¦›n¿—Ýn×ëõF½`š@Ë$t¡@ßétž{î9„\sssN§S­Vollèõú••F3:: ¶iB¬Ž5xwl6[<çýZ­–N§Õj5ú�1˜Ï®ts] t«-IöʺR*•ö'aŽ4¦ÃáÈd2{2å2™¬Ùlöé¿`¦T*ío�¬Édª×ë©TŠea‘äA/@ &k4}Ú.¼ú¨ÃË>ÓI  ST«ÕB{“$i677-Ëà\ˆëºTh‘xz,,,…B§Ó¹WA†îÎi}}Ïç †^IIƒÁ°½½­Ñh°²¥R)‰:+‹$‘ôB½^o4½ôÄXH¿ÊmW_ûÚ×|ðÁ?üÃ?¼çž{®¿þúüà<ï‹_üâÇ?þñï|ç;årùÁ¼ë®»¨ýð‡?üõ¯ý“Ÿüäã?žÍfAX¾½½]¯×yä‘f³ùž÷¼G«Õ †þð‡Ÿþô§šã¹ƒÐ] ”Ôj5z“pŽK§ÓƒasssnnàS‰D²¹¹Y«Õ|>ŸÝnÏf³ãããÍfóìÙ³dšL&´ämnnú|>ЂA?pff& ?.‰B¡@ ‡Ã¨Œ8Â’Ñhl6›‹‹‹¸ÉÇk4šv»]«ÕÂá0еV«5•JÙíö|>Ðgmm £¹\6\«Éd²T*ÕëuN—J¥är¹ÇãASÁãñÐ"ˆ~¯×ëp8Ο?ŸËåR©Ê‹%•JajµZðª¡]&“¡lF,$ÙÈ„«T*P f³Y–­ ‡ÃààÀñK"‘€ acð€Xå µZMÓ€¢‡~OÝb±X£ÑT*•ÁñõÀ¢aÆT*UR7<<¼°°Ð+¥×ëñ‹€¨V«`¯&éV2ú$µZm¡PÀ-u �wc%Áð,ºÞXBÐÏÂz‹àôz}±XÔjµ¬©_p=ù±]ã<♩“sIŸ¶�ˆGï9™ß'Øì*~Œ·¶¶¶pìB-O±Ê!ŒH‡ŠÝuå±j&“©+C+‘Šï5®¡‚ûW¿úÕO|âŸûÜç,ËÝwßÍãñ¶··ï½÷Þ‰‰‰~ðƒ•Jå-oyK,ûþ÷¿?;;û /¼ò•¯t:?üp­V»é¦›>ö±½ìe/£ë_ýÕ_‰D¢G}ô#ùÈñãljD,»é¦›þéŸþéÑG­T*û·{àŠ¸ƒð T(Íf³P(˜Íæñññ‰‰ ‘HD–«X,‹ÅDjù¦›n}g·Ëår,Šb1F£Q£ÑÌÌÌÈårD3ÀðšÍæcÇŽy½^»Ý";µZ Â$HjµZ…BÑjµŽ=Š–¼B¡€ãÄÄÄ©S§ìv{ @«*x+ªÕ*ØŒlœ]XX€5Ü0 “æñxmrÓ+• „õÀœ‚Ž—Ë…&°´~¿PJ—Ë…²<Òì¬ÍÚDPyïzT’Édäõr¹LÖ0ár¹œ‹ß”J¥d;£¡±+ORŸ! ÑT¹§R%ÉAu•x`Åd\‡1ļ• ðo°uìzJÁßçóyzöX# q=“V«íU«®×ë$ËÚ'ºª×ëä b0”J¥ÑhÄ5¹†—þ±,ÃË2#hîÿ©®óð’"'ÖP©T�½ãv»=³ž"x«ªÕ*Òú¼Þ:X¸]},ë€Ö+¶Ý5潆̒˜}ƒÁð¡}H&“}ï{ß»í¶ÛŽ9BÞ=}úô¾ð…¯}ík/{ÙËž~úéý×>}út"‘øë¿þë7¿ùÍ333wÞyçÏþsÖ•}>ßßüÍߨÿSŸúT¯ŠåÁ`ÁpFÀ°{bbûø!œ“È™ —ËMLLðx¼­­-„f±XÀµzéÒ%ŸÏçp8Z­ÈxÀ ³´´”L&³Ù¬^¯—Éd(äx<žb±øÜsÏ)•Ê'N@ð é;µZ ™Z¡P˜L&QæóùnÏ?ÿ¼X,V*•‘H$[­VÔ!‰„P(ÄŽ(•Jår¹^¯W«U>Ÿ¦v"9ÚétŒFc¡P0™LV*•ÊúúºF£H ¼Z<žžn4©T Gf’ =|ø°D"å Íf“Ëå¡PÈb±„Ãa$á3�œâÒa ÇÁétÒt�ä¬Ý5¬a¹¢}lRÔö?˜rm÷à(W.‘Hd4¹Ñý£ ¦'\£x‘ÛðÌ5A Øgœ_/gIâ e2Ã0¬ðˆõ8:/Ž>Ï‚õ­V .Ö_²òj}ÂY@`µZK¥=ׯ9A:š4Ü>}­V‹àaª«f³Ù5× Pý =ÅÈ~`íÚ2ŸL&‡††v¥ÛdÜÿý¨'ñx¼ÇœûF£ñýïÿ¿øÅ7¼á 7ÜpÇ{Ó›ÞÓ‡zhWxö¿ÿû¿ÿÝßýÝ[ßúVŸÏ÷裸Ÿ]ϨI¥RƒÁJ¥Ð¥Mˆ“% œ*ƒT{ÖS©TjµºR©�‡‡ó# ì‰DB"‘ÌÌÌLMM!°àóù@´@ÙvaaÁn·+ ‘HtèÐ!PáU«ÕL&#‰Àcd³Ùòù¼F£*Ã0@Àn·'“I†aÀï"•J 6'•JU*|K³Ù¿`¼—/_&¼J¥rggÇh4šL&¡PxéÒ%·Û­V«U*‰,Á–„ür€ñBõ#Cbcaaú¼`›…ºëüü<9SÒD"‘˜ÍfÚ‘ª;ê/O׳8~¡zdÑΩë/â²/BýH¥Rù|¾­­-–'.•J$¡ÈAò™0•(Aáã^¯—”?@ šÆV«µë•a?ÉyegQ¯×Y�Azà0ÐBŸ€[iOZ}p«Õ*Y«««Ü~$AÈ ÕÑþë²×ì¬CŸÏï%þ¸ë=\áP(n¹å–H$rùò剉 ¤_|ðÁ7¼á oyË[yä‘p8ÌbÎǸxñâ«^õªÏþó—/_ŽF£§Nºï¾ûú‡çV •JÕëõ¹\®Óé€^G&“i4šh4ªR©&&&ô¨Õj=öØ~𜟠4³³³“J¥ E½^_[[§2Áâ´Ûm…BQ©T&&& a6R«ÕFc||9çl6‡aƒär¹t: ¹jµŠæl€a  Ÿ‰Åù\.‡¼n©T* à†ˆÇã™LæìÙ³¹\Ža˜\.‡è¡B¡°°°�¨S0Dc­N§C·ÊT:.Ÿ9sôwb±´åè_Åbù|Þl6çóy‘HtçwŽŒŒLNNrk̈ɉSü›k(‹jµ÷022&‹þ\ì/}IH¥RšÃ‚N{ v4›ÍõÏ*;.‘ mÉw©Tªb±˜Ïç•J%™"®ÑËd2ŠÃÊd2\§X,â#´Ï+—ËÜ,åþ¬ë®£\.÷é^AÝ·?Hˆõ½Þžh¯7JÏ‘ì¤õêû'v{œ†‡‡ ‘L×C«’‰6bú•¡¡!(Ðìïö=>üáø½ï}/yåá‡>yòäÉ“'!juúôé~ô£xë¿þë¿®¿þú#GŽT*•ãÇ¿öµ¯ít:kkkð •Jüñ»ï¾ûï|çê³Ê‰)ÔÌàN(—ËåÕÕU ÊЮËåÐÔ¼­ËåBO]¸pazzV°þ„ÃaÄ4 5™››S«ÕívÛãñðù|(nèõz´är9•JþP`w@³ä¨eÂáp0ÜÜÜ<sæÌm·Ý¦P(P€ãáóùçÏŸ¿ûî»K¥ÒÕ«W§§§Á"a±XæççWVVŽ=  ±ZµZm4ÑFˆÝ' A$ÔÜ•+W�ö¸xñ"úÔ‘C^]]Åñîòåˤa½ìP”H$Ð:‚žɆµÛíÍÍMtgÈåòíím’Û¡ ª"‘Èãñ€•£Wè–——ñhz=h»Ý÷-‡Ãa2™VWWqõz½+3gŸ{˜œœ$GÆt:¥B~/b ’?ŒF£jµºZ­F£Ñ>Ò½‚?—Ë•Ëå�V;tèЕ+W =Lÿ kÂ÷´q°PY6óšŒjµº´´Äò¸ ¢Øs wð·“é7¿óÿ½þö{â;/õ³ï|a@u%^oýY>ŸTI¯,$Bú¢·»ëͰ®ð{¿÷{=öêÆxå±Ç3™L÷¿öu]Ây©²Öä ‚ §¨×ë� Ôëu4ã(úÿñ/^üû¿ÿ{’'d�ÇÁ¹âj¬·Èwñ82q{J¯ÿ¦ŽË—/_¸p!&¦%e¯×›ÏçagIÿ²^ñxÜï÷ëtºùùù‘‘‘Ë—/#ÿ°¾¾Þn·}>_, W®\ƒãããèCk6›x¾år9N·Z-p7Äãñéééf³©ÓéD"Q¡P@ILkjµà*‘H”Éd²€a(›ÍBH°^¯e‰uU.—Ú‚Áà±cÇÐmh0�Âef|| tœ+++ˆx …ÃáXZZ²X,v»}mm ¦\¡PLLL¬¬¬H$‹Åø|þèèèêêêØØtQqÁ±±±‰‰ Ø‘ÙÙÙL&=‘p8 ê üpz³;ŽR©„f3üÇ3 R©%w(Tq÷2&Ö¶ëfçóùGŽ)•J8¤vµ-€î"ã:8’‰kmpÁÍ£kŸu5|‹@ aMuøðáz½NH úÛ1t÷ @.K߯ ÀXü(·ÛM2É#ãþ^–…¤ïaÀ144!Ý}¸†> \Ö“ýË¿üËá¯>s5šO'¶æÎ¾$ó×ét`@YaR©„¸5’Øê¬R N|䦜)PÅàShèìSÖã“Étÿý÷w} ÒSôùŽÕšBwþ^ÄF£ñíoû¡‡:}ú4íKXˆ3ÚÓpÁhôwõ¸ C66¡P844„’ÌÈÈœ²‰I­@ �z…B±µµe·ÛËår8ž˜˜h6›Ç/•J‹‹‹Hs]¹rE$Ýzë­ÑhôÒ¥K×_½\.F£�JíXó à ɦ×ë™!k`o«Õ²Z­ þA°N§‹Åp*ív{qqq{{{bb¸Ë[o½U¡Px½Þl6ëp8�r‰D“““ˆÛíöÐÐÐÊÊ èŽ9Oø  Ý1Eçüùójµ:‹Áa@¥ñ%b˜ÂÕÕUÄp‡‘*.— "Rä´„ý•H$G†B!¿ß~Eº¿Éãñ€«›õàèNâ®[µÓé@ï¼Ïßh4¹\‹ÅödX!Ü@·!(•J«Õº²²‚öEÄ=´Åõ-K6›- pí½,ììì,J¥Þ§aÝårmooCr¢ìxÕJXÿ^žI.—#ð …‹4´m–ºzÜÒ™4rƒÏ!]ÂgÞ^®ü;,//÷w· Ãp%ý^êÙYQVôM ½È f···­V«B¡àæ¸e2YW~ ƒÁÏçK¥ŸÏw8{í¿óÎ;§“dd2™¯~õ«ï|ç;ßýîwxŽ_ÚËå*•*“É€6/²Ât,º.’N§ÑAW.—ÇÇǪÕêÉ“'“ÉäøøøúúºÍfƒE³Ù …BÍfB­V Ý[Ã0‡:Ö8Ë“ni¥RÙn·3¡‰N£ÑÀ`Aêbrrç\•JU(Ôju"‘XXX˜˜˜@[rh …âüùóVEy½n�� �IDAT«5ËåòD"!—ËÑ›ËåPxK$ý‹Åp ÑhÔ`0Ž"b óù¼ßï¿pá‚J¥R*•­VK$¾(°ô˃Á I …B†aÐ %rì;"=L‚ …2™¬k‚üû`CàJÂ÷ÿ"òÜY¯À3!Ù•ËåÄb±\.'& ¿ÙBô¿t­8 ÝJô”ívûÜÜ”‹i VV´AÜI³ÙÄ= ¡Âí7á~‘ÓéÄGðøXmµZmmm $“Äy`±.Ø #4`HÄá‚“¡—ûa-­®£P(pïS´¿ûÓétxä»öÎõÊìõê§„…vNX:è$Ée”jþÏ­¤ÙlþÖ·¾uà-~ÑB‚ä<ŽÓÓé¤{…u:mHæάÝnF#À ¡õ®\.!�jÔB¡pìØ±Ë—/rà‡@ -‹m6ÒwàeAäIHu:±XŒØy¼r¹,@ °­Ãá�¹,#hÈ¡UX(Ð×�Œ¶:'“ÉF£±°° ‰”J%¬¼F£aA?!TŸJ¥„B!t܉ùsR±X4›ÍHlôÙÅF£Q.—Ûl¶sçÎñzKØ( –r„H$R«Õ]}Þb9'ô^îcm…BF³§23‰W2™ŒR©dÑ{‹Åb‡ÃQ.—777†)   F€•JE°á½šÙÈšDË@×›Ä[}b†aŠÅb³Ù\]]Õëõ0â½@läj:ŽKhËMGI¥Ò>§vøB\“á’áv»777ñôa®O�öûŒœ®9^ŸcŸÏ—H$Èq˜éßÎnf¨b“ ã:bqrÄæDð­V«‘Ù°Z­P©àñx¹\.—ËaÇ ‚Ç»Ýn0ºæóù•••L&Óét†††4M Èf³*• ºM`L€ ïŶu¬IF#“ÉÄ/”+Z­Z3H#S£Ñ@CG6›ÅVGÔ…:ßïíT£.]º„#ÂÄX,†ä0‘ªÁ¾Àñ™N‰¬®®J$à½ÀµÓl6oíìì8>Ÿ+Iüz¯íìr¹ìv»X,†´n&“Ñh4hM´X,ÛÛÛp3©T éJÖA¾—‚h­VãžM÷mRh„é~, §²[­V777q?tIŸÜ!>BÜä€766 …Z­Îf³‹}7$)ÊÕÆ$ƒ¶ãf³Â"¤8’L&Y÷P*•úȳ|Ì ðî¼Þ$å¸s¤" ÷ÙC‹ÌÆžÔÁœ‚Ut œS§Ó¡—^¯G?>7AÜétÈÔƒòk‹ï—Ö~0~5Ñ®¥Os¼ÿÝ¿¿…ª2z®¬V+©%“ šÜ@Øc·Û¯»î:F …žþyÄUèMçóùápÍuN}Þãããå“H$z½Nræ8M3 ƒˆJ$°òQ¨ÀcŸ£ÍoccC*•NNN¢ƒ@.—£ÿ,±.— Å¡ááa¡P¸µµÅ0L³Ù´Z­`Q""ß�K? ¤Ë^×$‰‰‰‰ VrŒkÜ!vƒ†7‡Ã …ÐÅÿŠºˆ@ �ËÂîo\ ƒÁP­V÷EuÕ¥c)6±Œˈóù|TŒ†††\.×èè(žŽørKf³¹® «îÅ¥ÐÅ÷GKØkT*DØý§à¿®…7Ú}Öjµ=Ý»Ý&¯d\ƒX¤ïKC¥—[&:Ùðg###ÜÊØÁø-6›­T*Ñ$r0£è"ÙÙÙAŸ[>Ÿ/‹hFjžÈ¼‚dõpÇ¿¢R©P„R©ŒÇã"‘zÍhÒk·Ûø"󀆌G Ã0 jl0½^´/^W*•�6!äÒjµv»]§Ó©Õjh–J¥jµ‡AžD~ ŸÏw»Ýñx|kk«V«¥R)øÈ¡¡!>Ÿ¨ ½d2i00HÙѳçóùP~o6›kkkÄ3¡îKö J&“‰ø¡h4‹Å–——QßB¾§Ìj6›eA8‰`ñ/?ñk4!XüR®Cäêû˜)Ö@·=T½^ï+^ñŠn¸ÁápF<,–Û#ËX&“±ôËiY$ñ˜FFF~AÉ*ð ƒU‹-±æðí½’Nõv»l[wC¼i=Öt÷rZôÿöBÓÉÓr¹F_ʹ ¬­­½Âüƒñ+8tqttÕi²HÒé4Î@¨ ‘è¼T*‘ã*„Õñ"À’2™,™L¶Z­'Ÿ|°’3L¥RÃÃàf˜™™zI©TÞœ/¿ "•J¥ív-|J¥’4Ñ„T«ÕŠÅ¢T*E.±Z­ªT*§Ó Ü‹/V*•›o¾©Hä WWWK¥Òððp&“!í×t‡ÍJ¥})@ ÕjÓé4¦ˆüX2âñ8ðI¬·€‹${ù1µDM§ÓÉårJ¥À^ÖAžv`Vayiûý Ç‹ÅÔ/¯V«{EÿÐÃï÷onn¢ È}‹€Ë&†y�Pº^¯#F—H$W¯^:…&¬!>�rµZM¯×‹D"r}>Ÿ?11hž…R©Ìç󽜮×ë})6³Ñht­8¶Z­—’¯2N§O‘,W:˜aõÍ ÿü½ïûæ÷ÿÇ9<Z,W¼J§’…B»þT©T:<<<ˆø.“““]1YFƒ¼…>½½º³Ù ªy<{’ýœžž~Ýë^×l68ë~}8žþydº+•ŠÏçö±ÙlàÇ«V«£££¨Á<Ùl6©TJȈ±ÛN'Úd2Ùöööæææúúz(’ÉdgÏžµX,ív»ÕjY,–µµ5—Ë…BK¹\‹Å‘HÉt´oñx<“É`ÈŽ XáŠ�“£V«¡-äаZ­Ö¹sçìv»ÓéÔétN§“aøNÎY­V‡Áv Ä7Þx#¸!Ìf3­ —Áª{Æ™™™ññq¯×«T*C¡H$òûý0v»TµZ f¢Ó逨††UÌÌÌà …vݘÃÃÃàS‡ucI¾Ž¹\.VÅbhh¨¶^©TÚ5’Éd‡8Åã@ À2ÀM�Àú{œ*ÆÇÇ7€‰•j ‡³V«1 “J¥¾ýíoG",£ÑH ýää$`¥d&‹U*—ËEæ•Qb¸@µÕkò1EB¡ÜÞ^k4½ß_J Åg² ¹Æd}¬O:uJç„v µJ)·a§õ‚Á 7}Œ-Íz´È…P(¥O´ØÒá*Ž òV¯@ ˜œœ$O~õ?:UûŽk›É=¿ˆAÓ<¢1i}}½\._¹r\øÇŽ;~ü¸@ 馩©)@€6tF †‰‰‰éééV«e³Ùž{î9§ÓùÔSO=÷Üs«€þÅÔÔT>ŸD"Hñ5 "ƒë4 ÈJ¡ï�]Ojµœ~xµì†aT*•Ùl¶Z­Ífóúë¯w:°AµZ-›ÍÎÎ΢ë©R©\¸pA*•:t¨P(ƒA›Í6<<¬T*o¼ñÆÙÙYàŸvvvÜn7‹?åÔ©SšËårÙlÖår9N½^4={&“éäÉ“·ÝviGFFX›]$abá>ÉQý ŸF2W$Z%VÞf³׸¼¼<;;ÛËà`§óù|ÚnwLWµZí߸Kÿ¢±±1´}Òò]'OžìšŒ*–@¿c±]tG•V~~~þg?ûY"‘°ÙlwÜqxåác¬V+²ÄB¡³ JˆÑÑQ›ÍV­VÍf3²¬ ñ¥íxŸc¦¨Õj‘ÛƒA~‰ícb±xlllßg© ÷±ð}Æ@i=¤h·Œ Y‡¼/tõH*•Ò§¤>팽Þ1s×6y�û,Ç®òŽ_ÿú×{¯×ë½ùæ›éWWW«Õ*ñ‚{=;,//kµZÀÝn7Ê ˜ÁߘL&«ÕzàrÉŒÃ@ ‹/†Ãa”ÜétÀÒÒR4•ËåÍfS£ÑÀ?A@]¡P”ËåL&õ?´¡Ëîõzårù 7Ü€G[�TAÓI–1’]Ћ«V«V«µ\.C6·Ñh@À t«€âÁˆÅbT�FJV±XlssôÒ6›íêÕ«ccc°kW¯^Å!ýòåË^¯×b±,..úýþååe¯×Ç!Ÿˆ u£t:íõz‰„ÇãI$Ï=÷ÜøøøÙ³g‘¢˜I(bÆb±œ;w®ÕjŒŒ\¼x‘ÇãVŒ¸ˆæææǰ¤×t”ÞÈ.Ê{‘í7Ã%ï!ñ‡\.7ƒô˜ÑÞ¥«´V«‹Å8¿"qP¡Ê…_‘ËåÏ>û,÷ã¤ï¼ë·Èåò™™™t:Fu:](Êçó?þñIXV©T€öM¥RF ºN§søðá`0èt:ÑJZ¯×Ñ¢­P(Ün÷®Ø Ø7rGøN¦×b±”J¥®½\»þI:E0=>iðøì圸©Ãz½¾µµ¥T*qPâ.¦=±#‰ßõ'ío‚D"HYºžº >)•ÊW¾ò•tׯììì<°±±ñŸÿùŸ·ÜrË^ï!ßrË-÷ßÿ=÷Üóå/ùÝï~÷ 7ÜpæÌ™ßùßy9Ç{ík_ûæ7¿ùÀ÷ ’Â&i:²9Ífs±XD-Ó`0,,,Èd2NW(X(Tw …ä*l6P56›íÒ¥Kjµ {p0f³¹\.[­V”¯l6[¹\†Êm.—Q¥R1H Éçó (ªÝn#®‚¯"5ðz½^*•Òét2™„h!`¼ÐGgèææf6›}î¹çÔjõÊÊ HL&“H$Bg±X.]ºtäÈ� …‚Ífk6›år¹Z­:«‹ÅbÐO(•Êååe‘H„]&•J- hж¶¶X<¤b±¸T*ažÑÖ<::zñâEVN†a˜r¹Üç8ïp8`jQE»JáÌZË>VˆD" …àn¯Õjt(IWÐë¨ÑhT*Ü­F£i4¹\‚°]¯¨Svµ°@€a*°�à¼1E`/, :©QŸÏ—Ífãñ¸P(t»ÝD&´Ûí‹‹‹"‘]ã}U°GÇ ¡¬¼õQ"‘€¶‘ŽQà‰DÜÓÆ®wÎ@0Eƒ:'èlòù|µZÝËÍ�¸oŠUH´ÁckµZ8'`_"m+ŸÏW©T½–8Ã0¯xÅ+º¯Xëò‘G¿ñÆßñŽw\¹r% E£Q©TŠÍ÷ÝwÿèG?ªÕj&“é®»îZ\\<þü7Þ¸¶¶Çßô¦7‘ëø|¾×¼æ5v»ý‡?üáŸüÉŸ´Ûíßÿýß?~üøüãññq÷ÔSOán¥RéßøÆH$òÓŸþtjj ùW¿úÕƒá·Ü9ÑäÂ$–B¦Žx/(À’‚N§“J¥p8¢Hq¿ñññB¡€  ´û`˼^¯Ûíe8*Oív[.—kµZl?4Dà�[©TE …ÀóH|U¡P@W.Å0 ø“o)ŠC‡AXÝív×j5§Ó™Íf!ßh4´ZmµZ…š‹w� Fpc«««F£1›ÍBD¼\. …x<îóù ÅÙ³gy<ÞÎÎÔ7x/v óù|G4n¤R)8 —Ë…&cXg:•1_rÖf!L NS*•‚š,‚¬˜ƒµÙ¡§E xTìq€ yI7wÀ!1 ƒ ÂÃ=àÖ=Ós/õtøLÝó…›0 V«Á¦R©†ÃáH&“"‘hggÇl6·Ûíõõu2ÙlV(šL&ÒbÊõ   ae’zéŒ÷h¥_I§ÓƒTýA®ßÕ9íÉ/ ˜ºçDPT,8•ÑhÌårXd¨ÓôZ(J¥²» ò¬B·RÕuX,–®²•Üûß÷xâ‰'VWW?ó™ÏLMMy<ž/ùËz½þ£ýèwÜÑét¾þõ¯ƒÝ9—Ë=þøãÀ>ôÐC¯yÍk:ô™Ï|&¿Ÿþô§øÀ>ûÙÏøÒn·‰ÄÒÒÒŸþ韞>}:Nÿå_þÿì}g”£gy¶zï½K#i4;³Sv¶8îØÁ@B8$Ž1‰Oˆ æp’ð!Ü0>êpL'È à¸`° ÄÆem/kïÎîìô‘fF£6*£Þû÷㊟ïý^•Ñ;ö9þá•4Ò«WÏs×ë¾®»?n6›¿óï”J%³Ùü±}ìÊ+¯,•J333ãããSç¢íæN‚t€Q¢²$‘H ™Ä`0€½†ÚFS©”B¡�×çÖÖ–Ýn÷ù|°ªB¡0NK¥R•J¯ƒŠ?¤J`‹�±/�Ȩ<áHž—ËeÂ¥‰ÙÙYŒ¿èt:³Ù\©Tb±±>ÈäÀËh¢D"!ß8:”7äry2™D²‚é@1@¬– ”©Ä6„ã¢D …„@ú˜J¥¨ÒÝðåÈùb±˜T*¥‘{Þk€ú{:8Ô“Kí ¸PÁë´ 2™ � RÕÐétñx¼ko¦ÓzÐÌ7ZnToÍãñ†††677É-" ÇX,†z¬ßï×h4ÓFîn41`0Ølv(ˆ›Í6½€Ž»ríºt:]2™ìš&‚Ó‡ü‚½ Kóv;2ï) ‚Ík6›½¨›º7Í@ïÕ�Z›kê!1år9Uפ5O¼. ©@xL}’°½ˆÄo^Eœ´µ&û¬§žzŠDù|þ?øƒÁ˜™™áp8wÞy§ÓéüÞ÷¾÷ÿðþð‡C¡Ð£>JÒÁ[n¹E­VÿË¿üKç{¾ï}ïCvÿ¡}ˆêWVVn¹å–;ï¼³Z­~ÿûßÇã/¾ø¢Óé¼ÿþûÉøc^:Ýo›ÍÆãñP˜U*•PHê´DCCC¥R ¤F£‘ì®ÍÍM(É ²ý0Þ„jJ¥Ik(Êçó‹ ˜´]°yŠÏçó„b<¡¹\.›ÍâPmÉD"›x*•Z__'dêÁ`0‘H´Ûíp8 —––@(Bü[«ÕJ¥RÉd²Z­”´ä}�{»ÝŽD"dn½ÙlªT*‘H‹Å¨&�sÊ]o5`´“Žbf§ž7NÁ½„¨?ÓŽE!ÐÒ{£Ñ œT*µ[Œš6ŠFëL j,K­VSwQ§ÑëzñJ¥rhhˆÐ4c&Œj—pÙl¶ÉdÊçóëëë|>ßf³Ùl6½^ÿ–·¼edd@$Ö6›ÍápLNN*•Êf³‡{uÇ1ñF}0TÆk —AnTJ~A‘H´cd¬Õj;ÚåryŸqUÚϱ‹ž“ÅbI$]·Å€$àhû»Ow c"].Çóz½Z­áôrzõÀ^§u×]wÑtÃú¯«¯¾š˜Â]­ûî»Toä‘믿þÞ{ïí:øG¸ŠÅ¢Ùllš„ÀHA †Ýn'Ò·&GAÌív‡ÃaF”Ëåt:- óù<JL2™lmm ¶åY¥R©V«1¯ÊårÇÆÆÂá0á0XcÏçóR©H<>ŸëA“‰¨bBÓ¼Aår™Ïç ‚\.Z@°¼¼ìt:QµÇ0PÝñxÜh4¶Z-½^Ïáp677Ýn7ä ‰OÊårøâ€B C‚CBün6›777xFÞn·Cf‰Ú¡éùRǪðnÈ···iU ÀL  Ìår …”î5"ãr¹€¢ªV«Hžö,ÓøCù|¾V« …B´o OËÀVðý!ç‰Dà­Ém4´:Þddôð¡Pa„L&s¹\ccc ™LÉF××ב{½^»Ý¾«Ùh=ò';Ne2»Ý>H荒`ËèËa¡R©Úíö Üœ®®€ÝñññR©´~ÕNmÀþÎ ‹Lw»\.D%ëëë�D`؞ܩáááõõõ×ozéÁüÅ/~ñÅ/~ÐÒ[o½õýïÿ½÷Þûúß¿û»¿ûÔ§>% áŒÝn÷EÏDuN_Z^^& è²À c3Äãq2·ˆ ÖZ­†-¤ŸT*Õjµ|>K@€ÃáhµÚõõux>Ÿ?;;k4Y,–Åba³Ù[[[´‡Ã) 8Z¦Ùl‚Ñ5›Í¢“„p|>X ô®žþyƒÁ0>>®Ñh&&&Äbñ©S§ bäV,»\®@ àv»µZíÙ³g‡†† ˆE0Ÿ¨Ÿ¬¯¯—ËeÌ?aÒw)‹Á²èõzpÎÆãqj¬ÚÕ-‰ÅbµZ d>À4H«½3 §Ó ….�h‰DL&uʰsÑFYQ]ÜÛ~°Z­Pîå1ÁZ¯×inÒívS=v˵ƒ90”¼hí‰D‚¹4ê-2 gΜ‰DHnФôx<G%<ÄsWWW›Í&\ÊÈ´l!“ÉôÑ% hWû·… ÷pdzÉ`0<ÏÚÚ±É}*{Ä-‘Ÿ©g;ªkÑRT+++uϱ±1@Q§öO°iƒ±¹¹yòäɧŸ~š0† j`â÷û{y¦Ã‡ҵ꿢Ñ(h¦§§§§§1ÂICÐv]Ÿþô§—j¤.Ç3==}óÍ7ßyç]Q¯ØÅçóQsñd2™Éd\.XÀÑÎi4€äáØÀy á)h5Ç`0&&&˜L¦V«… n8Îf³f³ò¥RÉf³)•ʹ¹9ƒÁ`2™Ð�::Œ×D¬¡}ŽrY2™L§Óù|¾^¯cª†Ãá‚k®¹fbb‚ñš`O±X<zô($<^xá…`0X«Õ %fffl6[$ñx<ï3Xymá È‹Å`• Üh4ÐÛÚÚB—žd™¤hC5 ˜? ƒÁH$¹\. H^¦×ë‚…MÁ<)ı�ÜÐétGåñxøš´…š*õˆÃÝé•8C  Ó>wÂ%]ŸBéiðøßlXu?‘H4<<Lí&‘‘‘Ó§OcH–ÏçƒA€ôÈû°ÙlÚív c7‘‘ª9*•JcccÓÓÓ|>ãh¸:ïÃÄÄc~ǵ±±Ñi“i#q´½Gý-ÍœÈõ–F[T—t:M }dì�ctûqàþŸV ì”f2™ð^�k »ÝÞg€·ÿH$ƒÁ@ Êl6›L#á^+•JƒÁ�ø†Á` Ͱ¯~õ«ßýîws¹Üòòr2™ÄS`rûiµZX4>Ÿo0$Ég?ûÙJ¥róÍ7#á}ôÑG_xáh¶^tHd±Ùl°½Q+ÚèáS3{±XŒS \%ÄΩg Ö¡Ñh°Ù쥥%8ŸÏgµZ‡‡‡Íf3~» .\~ùåçΛžž®T*6›ÍãñÔëõßþö·ÇŽC‰Æãñ0�U*¡P˜ÉdÄbq>Ÿ3:‹ÅZYYQ©TÏ>ûìØØÈÀkŽ:ŒßïG)c.étÚï÷{<‘H„aU¤‰D‚v GJPÆH͹\îÂÂÂÄÄÄéÓ§IûòE™Lfzzš*è‡"D(Âù"X<811±²²‚Ï%"^æóù>¼²²¢ÑhD"Ñúú:iÓvî^(áö “©¤ÿÏ6õÕEæ”H$LT*2ŠDk¨…Bjï4 b ½3U™…ºˆ1ìÚ,i4°<z½žÅbáFÍÏÏOLL,//#Ö·X,z½¾Ñhøý~@=#‘H8ÆäòØØØÊÊŠÇãYXX¨ÕjT€¾1¼«««˜§Æ +õ.Áöâÿû–FFF666FFFæææh÷áСC{à¡Þ4œÖþ.ÀétÆb±þ ¾]Ë´Cî ß%ZÅ–Ïç›L¦AòŒ×i1™L¡PÈd2o»í¶/ùËT™öÿøÿzç;ßÙ+uÛ³á<pçw>ðÀó7sÑ—à‚Lû3Ï<súôi´»ñQ÷mO"ƒ;v­0 ¦[^^Çð©ÝnçñxH:T«Õ@.þꫯº\.Ç333sèÐ!¤_jµÚb±@H3‰p8\øÿ-K,k·ÛÐ$ID&“jûÚÚx}œN'ŸÏ?yòäe—]¶¶¶g“N§N§B¡(‹Å5;è<­>44´¾¾ÎápªÕ*Ttëõúää$úa¡PÈëõ"½s:&“é¹çžêjw¨öÁé‡W«Õ±±±B¡Ðy¢GGG£Ñ(8ÔñW˜2&ZãTa¡=¬ËY;ÚN¬3¶ â×ÎÌ@,[,–^Ò‚½Ú9l6ûðáÃ|>½% Æ©Õjxý‰‰‰¥¥%•Juøðᥥ%Nwøða ¥R)`ÕR©¤“Ûíö™3gv¬¤!×ÙÚÚB—ÅUÌ´A ²OÛï ˆ# Ú¥»ýÛ{ï½w_2íz½>@¬Z«Õv‚[ªÕêëí™Ð”î…}ÙÆÆF§B‡ÃáxÛÛÞÖë·¿Hû¦]@@¥RMMM¡†yU.—‹¨ÓéÂáp«ÕãƒÙl …áp¸â'Ù¢ðL(…Ûl¶‰‰‰|>áÂP¸2™L½^Ïãñ€Ð*Ê è.•J˜€ú¥B¡ËåÈx<zEù|ž¿òx<›Í6??/‰Òé4f˜æççF#ü¨ÛíÆ(Õùóç- RàÀ+ŠÚõÙ³g½^¯X,–J¥(ûÔëõ‰‰‰¡¡!§ÓéõzäÛÞÞ¶Z­$šîê™d2ÕK$&“‰†9˜[IÒ€ìŸø›ÕÕU«Õ‰D4 ˆk7/—ËÙlV­Vóùü>¯;®½ý-rSHŠ�ÀM} l„Ø3ÖÓ`0tõL _É©�� �IDATÃh4öê¾7›Íååe½^ ›ä"‹‹‹&“©R©$“Illl¬¬¬ŒŒŒÌÎÎ^z饸‰Aã …åÛóÙl–ü(ØÉ@šž½+rTö@@%9d±X(t­<õz ÉI«ÕÚ'áoÏžSרò9è÷Àˆ#„g’Ëå„.ˆÃá�0 ˜\.ß•µ‚]9§^()ôòŽW\qE±÷ÚUµ³×õ|Àív_t$¯ÓJ$>ŸO$É-›Í’ØÅk¨ž£1C0`jµšZÅ…’ù§Éd‚é‡GAó3=J¥R£Ñ8NL ÍÏσ‰ ¼G‰D"lll`ÆV œ={ö’K.a±Xàƒ@­/›Í¢#Õh4ÔjµH$ŠF£©T £¾>ŸÅgDë‰DךQ€­1Ìãñ„Ba<GSõj‡Ãår£Ñ(X«Ñ—(qqq:ÛÛÛÁ`pqqqaaŸ;O˜�ÊNbø�tÆ(ŸÏ§ö•¹’ÉdÇŽ{^±X„t„÷ã™ö°Äb±H$<|-:‹Åáp]ƒH$ÒyCú€¿hOI$Rög0µZ­—X”‘')ŠB¡ðꫯ …BÄ4…B!û|¾™™Œ‹¹\.båiÕQFC í)ryØ*ƒw›¨9%•ò §©—¹îÓt(•Jý¤_]2'ê¤-¹šN\ uØ EFjfGÆiiOõJÀ{õ‡@ÓIKÎ;÷‰²ßxÓyÕUWÑxù.®\jµ:•JÍÎΊD¢L&c2™PS*•Àjãð›) 2`ˆAN2QHÛÉ ìÄ”k³ÙL§Ó…BA«ÕÚív@•Òé4q(ÙùýþãÇ:t­œg$Xà»C �úL˜¬h·Ûsss±XL­V7›Í¡¡¡v»8ã5‰L&“H$x<°Ùl¾páüÊà4mll´Ûmg02™ †Êåòúúº^¯Ÿ››óz½¸ •JU«ÕD"à©óÈ, (/š é<ìäxÒ"z—Ë…1§ÓiµZŸ{î9ŸÏG¦;î#ØûL)QAU4†Ù®†‚1©F år9 McÐét©TŠÈŽ *¸¶¶|` ‡Ãf³ØtE*—Ë1HÀ Lcö ëeïª J5•döH¯×z­®Õç)’Ìðx¼^IûrNdæ;~aêïA‰D‚ß¾ Ê`¸éýߺVávtÎB¡°Ovuqý~­z½‹ÅP?Éf³$â#„͵ZíðáÙLÕ3®ÅbL&“œyé€ßï2™ ƒú è\<o4‹ekk 0˜!Ì”J¥ñx\«Õ¶Ûm°Úg2µZa ¡PX¯×Y,–H$ZZZr¹\‰D ‰ááað­Aɸm” qÖ�|—H$CCCø4Õ¹\.‹Å*  PJ$ßwuuY#bG0#`.5?~4w°Dd™ÉdZ­VBAîÕjEªÑU‹¡Z­êõzÇ=ûD"Áf³ûKâR•vµ¸\®V«ío©…&›Í ‰Ãd+õÚjµn”R©Déµ³X‡ºngµZ\R¹T@½^öz½RFæDúÿ6›M"‘ £Òjµñx`½^Oœ:ÈéÅb16£‡§öv”¨†—ö¥ðMû0Á¸lçàËz™L¦Ñh ““T]IqoÇV±>/(‹Z­öСCИéõ2ijý?K¥RuVëõúž[©×›m±5Ø}d3(%U«U‡Ãa³ÙR©ý¢Ñ¨V«…b±X¤ÊGä·­V+áu2™lbbB$OÁh4& ¯×Ëd2§¦¦t:Ýèè¨D"8C3™ŒD"ÁˆÏ+¯¼+Ãb±âñ8†0Ÿ»ººšÏ硤ît:Áº¹¹‰j[$‰Çãñx<™LF£Ql‚£ayy™!álÐN#ŽãÃÛaúiÉM.—;5"N¿ß àTµ$òÑÔÓ”ÍfaD"2<Z®°²²ÂårAz B²D"áp8H P(H1 ŸÂáphâ°ƒ,6›Ý«,ÙÕb,ÚápkÞkž©×S¸ED!Œä&“©SÄ)—Ë©ÕjÜa™L’:Ôf©b"¸±X¬T*¡ÃtèÐ!Œd³YZ˜.‰V—nu>^.—-KJßA‰±ö¹èbƒ›+çE¢ßK‹:Íú8•þÎS¯×W*•íím`La\öð@’D“7öx<‰Dbttô¢Øàïû‚Ø`:ÆÔ'‡Ãn6T«Õ:ŽÕÕUL¡BØ 09ô{ ºäp8 3 sŒ@&“•àà) ` òx<V«U ,,,´Ûm”æ0‹Å¦§§år¹J¥âñxõz]¥RétºùùyµZÝh4666P»[]]Õh4<Ïh4ž;wÎjµ¢Éd2ív;¸ˆ®ºêªÍÍMØ ›ÍHE£Ñp:ápø ΛÍ&t±ÕˆY¡4Y·ÛH$„B! nä6ÃQår9pÒ` ‹œb AÜ�°ÓÒΨ¡šÍf2™<wîÜK/½„rP¥R!>SÒÔOA–ÙÕ8Ÿ©k0Žß«ÏVœ HÄ =y#@žÂ-êo—É}0§‹Hî^µZÅÀ�þÙUõý< /Cƒ¸ÓmàÁÄjuU‡R©T2™¬X,"ÔÃDùކwdd¤Õj ÂI1::JEšL&°PÒ^¶ƒØ ©iBr”vCN'8Ž=J#›Íäñx<m¬®®ær¹>�¿®-+"6Z‡Ìb±ìyøüâz®P(&…F£±´´„æ3 ´Á`ðÔ©S°hµZM @­çøñãZ­¶\.OLL Ùú“?ù2­éõz'''ÑJ‘J¥V«µP(€&Žjyyyqqd¯FC§ÓI¥ÒÑÑQ³Ù|ÅW üõä“Oþ÷ÿw&“ÙØØxñÅs¹:=бe2™Ušt:íñx X*ôz=ÏÆÆÆÎ;¦5ƒ‰DpôÊå2é]aÒÖ`0èõúr¹<55uâÄ ÚÁ`Ðh4ž8qB©Tº\.ú!²¤õç766à‰Ùl¶N§C÷WxìØ±w¼ã|>ddÃd8MP&²¶¦°ÆçŸ~iiissÎ×ON‰¨å/bÓM&•º­^¯“¢ŸÙl¦–C:Çi;fŸN'A'd·Ûír¹·hǘtñx¼k“Ü=2Û ‘H¦¦¦4Éd¢¥V«µ½½ |4íZ­áÎ~ÎN×èÎj*·ÕjummmOÌçóKKK²OQÁ#ˆ8÷H_Ä`0FFF|>_§šv£ò´Z(šÍ&uJ·«Sa±XÚÃdV‹v;¸\.Îè~;ñDlæáy<^­V{饗.çþV³Ù$g‡¦ÛÛÛ,kllŒ(a³X¬ãǃÁ§žzŠl•v»ÍfOŸ> ¢ø€W^y…¶Ûmt(QTáñxívû’K.a0“““jµºX, …R©ôÊ+¯8Ž`0h6›I¤<66& ³Ùì /¼pÙe—‰D"”•‡Ã9uêðµ"‘èèÑ£è3ȧÉ`0¨Õjh®¬¬�pÑjµ�F@”Š><oÐÏ—J¥J¥`0.¨UõUj¼L=;ÍfÓápŒŽŽªT*”A;ëp8H˜èv»×ÖÖ 4ON.z0äÍáõÛí¶Íf+‹‰DÂãñlllŒÓLD×EzH伓ëÜ-ž×F€B¡ðÈ‘#ét#«ý­íææ¦Ëå"¢O<Yi’Û‘ËîóW…BavvV­V³Ùl»ÝžN§©¥WŒ%0 ‡Ójµ<ÏçÃh-”Ž©&qoºésss\.·Ùlö¹T+Úç&P¿oî`lêû rœ÷Øsb0ËËËd%]…eɬû Ÿ'“ÉÐ>-‹6› ezj+ $’&“ •V.—Ûuò W÷ Ak­Vë cÝÞÞNô^»H¼¸ÞàeµZ‘è€;!§ÛíljÏçóz½^¯Õ0É¡ÆX¤rb6› Ñ>ðûýèý`#º\.×år]zé¥ÓÓÓÃÃÃçìÙ³n·ÎŒ5jµ: Ã]( ×ûâ‹/ ŒbÜç²Ë.s8(@6‘£H$b±Xf³ykk«Ñh¬­­­­­Õëu¨:aŽÕn·£\a³ÙÆÆÆd2Ùüü<¤=R©ÔÖÖ–F£ …€r •zë„B!°gh-‰Db±X.»ì²±±1“É …œNg³Ù$ž Ì–•Jehhˆœ\„ÿèýà�²X,‰DR­V`IWVV;Î/L‡X,î…Ž …‡†©ÙóöÀå!Q¸ôÒKßýîwëtºååe±XÜU\”¶ÖÖÖú÷ÈY,–Ãá@ÀA´X,ªW@l,—ËU«U܈쑢N§‹Å0¼»Úm²Ûí´­¬AÚuv»]$ rvL1Q—J¥ÔFãž×ß úlétšÅbí­'Ô™ö2™L¥RÉáp¶·· C:Öëõ„…W*•6 ’ÝSŸ¢µ¬ü~¿D"¡%×Èíx<^W¦÷§žzª—Óf³Ùãããhf2Œ .k …]õ ±R©ÔK/½4444¸š{>Ÿî¹ç¬Vë‘#G.zA–D"Y\\DÀÄårU*dtôz½J¥:~üx¥R9{öl³Ù4™Lr¹ÜçóÑPI¤ á÷û‡F£9sæ ‡Ã4Œ{»Ýöz½N§“Ëåêt:ø—H$ ÈK29tSø|¾P(<wî™�"ÅbíÎçóHkÀžJ¥0ÏFèZXXÓÓÓ+++à(AE£î ‰X,Ô‹âñ8æ‘IªªuÇ6¼••ƒÁÀçó© 8•J%‹×××%I¡PÐh4: C´ˆ,Ëüü<äe* è}ø5 ¬Óé@  Ðk`^o4$ ‰DP(×ëõîüqU*Dcu:­¼/•J‰ŽðŽ…)’i4©TÊçóA0Ø™„·Ž“¶Càn+• ‡ÃÁÕB[¹Ñh¬®®Bm’ÀñƒÁàà57ü^###áp¸P( ÛT,qy‘HÔ@WâÇR©T‰D^“JÂDü1:[;Vð·û)t^CוÍfÁÙ§¬Jf¥û¹Õ^€âK2™ ‹ÅÂ-;ç„€ @jÊBÏôÊfÒé4�<]ï8`£“““4@Ä… ˜•†Ô—âo—hÿM¼ãª+®¼’4$¿ò•¯Üwß}ØR_ùÊWJ.ëÂ… 7ÜpŸÏïãÀhkccã]ïzWµZ}×»ÞuÑñô_�Dd2¿ß_«Õ › ‹)—Ë­V«Õj…ŒT*Å®‹Åè<±X¬r¹¬V««ÕªR©l·Ûd½$Gs¹BÔRX,XA͇qïv» …0ç˜Ëå0{pT*åñx2™ Ää\.—ˆÞJ¥R‡ÃOf4µZm.—+—Ë‘H›œÃá …âóùr¹ú{¸Zì±±1tU1³™J¥fff ÖNþ–š5›Í©©©ååeŒ“`]ÀˆAW%¡\.wþüùùùùf³Y©TÄb1¡ZÆyë:¶g�oZ­VÓé´L&CSêKˆ¦Mž«ÁtNƨT*Ì#¾aòù|,¶cap?À=6›M­V‹±e@��-HÕjµØ?D®uZøòF£! kµp+»mé¸m”gY,È•J%u‚ zª®o¼OŸÏ”ªp<9î®®Ã[ÅårI<×u!QîóqÀ¯Ò b ú"2ó…,жÉð1ØÓd:rÇsõ4¤æà ÔkÚ‰Ãáô¢œà”ëêÓ]ÊÙ—ûòƒ^;þøÇ?>99)‘Hî¼óÎZ­öÞ÷¾÷ÙgŸ}ñÅñì'?ùÉZ­ÂÓ§O¿üòË—_~ù~ô#Ì¥«Tª|ä# ãÔ©SO?ý4þä#ùˆH$zààÕ~ûÛßþéŸþéC=^‘HôÉO~ÒçóýçþçUW]U*•Ξ=ûÁ~°ÅûǶ¶··kµšÉdÂtQ©TBøïv»Õj5æ“’Éd2™ …©TŠÇã)Š‘‘‘……„–°Sd@j{{› Àt€Â�HÊ·¶¶ à‹Å^yå@Ácd2™¼^/`oÀw^ÉdZ­–H$$I*•ÂÁn·Û&“‰Ëå‚gÉdj4 É–ßïw:ÙlE9ôÉŒF#ª Бj6›‘H�{L,K$’X,–Éd4 >N”V~!¤ ˜ü…»m·ÛÉd’„wd¬žz¢ûg“É”H$ôz=Þ÷ÿ`÷=«†‚u—Ú "ÃÅPwdPæ hÍ9p‘BQ  NLcØuökÇECŠ#Qãñx…B¡Óï˜ Ò‡£]6Í„hù|œš<íê> Ús2´S±XDðEE…’%—ËI{@ÏŒlf?ÉZ­Ö‡îÎ9L&óCúP4}üñÇ_xá…{ï½7»ÝîŸþô§·ß~;—ËEc„~>øà¿øE‰DbµZ¿úÕ¯~ýë_?sæÌÝwß É¸ÇüŸøD³ÙÄ•K¥RµZý³Ÿýì _ø‹År»Ý÷ßÿ—¾ô¥ûï¿ÿÞ{ï½ï¾ûî¿ÿ~šˆÙçÂðiµZ-‹¡P`h$.6›íèÑ£W^y¥Õje2™ÑhZÝh_ƒ4E°r¹œL&S© qz].—ÑhD¼…þô!‡_xá…S§N­®®r8œ­­-µZ½±±y$@ÛÙl6ŸÏ-úI.—Ëáp€õ•”_‚Á Æ{Iï]§ÓAòw‰D¢^¯k4T«U‹‰D %ßn·!C….œ "n¹\ŽÓd0P0¤ù  ´ ’;“ÉlnnÎÏÏ/,,@ŠzœÅb1úXý݃Á`àr¹P¦Å‚½&™ö0á´ç„›†SÈd2p½;Ž Õj5Z ?7;˜‰}GωÇãõ‰ E"Q'!€ÝnÇÏ”Ëåðq GF;d·Ôg±ÕØ*¿`ç-z=Vç”ËåzyÉ©¦íòkÑŽ„^¯ “Ûí&Ðs¨H”Ëåúß÷>ø…f³¹òŒÎåõz.½ôÒ›nºI¡P<öØcb±ømo{JÉccc§NŠÅbñqã7æóù§Ÿ~Úï÷Cyᦛnú×ý×|àB¡´èCCCSSSgÏž ƒoûÛoºé¦z½N0fóóóo}ë[yä‘‹°CÔjÌf³N§ÛÞÞ.—Ë …"›ÍªT*˜oh(C] :›¨×¿®P(•Éd¥R µ81ÀÈ DÞ �#Äb±………3gÎloo‹D"àQÁÙ£×ëá$†††ðÿÃÃÃ¥BvÂd2u:]¡PÉdétZ$wÈNÁúú:Ä@‘ÍfÅb1|êÈȈÛíÎét …ùùy0ìÕëõ\.744T©TÒét©T’Ëå(:¦Aî›V«~!“É$“I¥RIêêÐoM3ÈËaw0}ˆagâØ¨ ÙlF0êóùÀÄ#hX†Î³‰¡±Á1G:®Î÷~V:æp8‡Ê8»ªÈF£4{ˆ¸>Þ®9Ïç6¸Ÿ˜•Ƴ˜T£ý M¶Š,—Ë…íº+yRb«%ÉàúÝo$j¬KY¯¿ÆFWïŠÚÎöf¤ F(" &ä}ÞÐb±är9ZJ‹p’š îYÞbŸë‹_üâ·¿ýí>:Ê7ÝtSW ÏôôôàŸò|àÓŸþ4hü‘/(Ú±Ù쉉‰jµê÷ûÁÁáp‰Äææ&‡ÃY[[«Õjl6;N¯­­™Íæl6 ."ĉD•D”H#ˆ°ÛÖÖr—`08<<|áÂ…¡¡!ŒµŠD"hq---©Õj9rÁ¸ßï7›Í‘H$ŸÏ …B6›½°°`6›ÁûG¢o¼ôv€ÉdB.Ek²Z­Öx<â>x hüX­V°Ó¶Z-°(¡z Îr‡3<<<??ït:©=œ5“Éô]WÇ‘&Ü©TŠ #Ìüü<'y=†a(\.×êê*ÈÚû×£àS;/Àjµf2™Î³œN§w•F€lzÊQtz_bæ¬kq‚fpX,ÖÐÐAåÐL%—ËíÝbô¨E¼ÕËV«Õβa/"]PòÓ~¦Á†¸|ñ>+ûuN¼êEîNç³$ø¢nʱ7‘H¤ÝnÓ.ã È"{-„çÄß|⟸ñÆ;É2òâ»ßý®ËåªV«<ï·¿ý-5€B§­óOºž‹ž©³ ±¸¸ˆ!žH$röìÙ±±±L&RœÿøÇ¥R)‘HŒA‚:sss­V ~‚ÉdšÍfhIx½ÞZ­¶´´Ôn·‘ý !±ðù|ãããh_c¬Ûh4^~ùåÏ<óL½^xßïÇxÝn'ºÏçß+ÚB.—‹HÖòùüB¡J¥X,Ìh»Ýž˜˜8þ¼T*þÍh4Z­Öjµ:;; ª@¤D:ÅáááÍÍÍÕÕUœ¸t:3¡f³)•J¥R©ÓéœD"˜0åñx¸ªÎ`< AeØjµâ Ñ ær¹“““çÏŸÇÍÇCÖl6×××ɨ"ž¥ ª&d¯"R8î´6TùÐW&“éò‚Û 2Üç#R©f„á&[­ÄÔ»¶v¸ h-ñ}ëõ:FBq÷l6›F£Y^^.—Ëãããsssw¬Ø”+ÇÆÆR©T¥˜^u¦m2&´úx&ˆ%,Oçät:#‘ȀĂZ­vÀîYˆõúÄ88u###ÔYåþa‡Ãé<ÜÿBÿùĉï|ç;ÿýßÿýg?û™B¡@Ñù½ï}o«Õ:sæŒ@ � ëK_úþ™Ïç£Ñè[Þò–w¿ûÝïyÏ{T*DN?øÁÆãñW_}•Çã¡üÍo~ó™gž‰D[[[~¿ŸÅb]Ä>ôé9ñù|°` ±R©$‰`0ùÑááá¹¹9˜T©Tº²²R*•˜L&ÑhV©TR©´V«e³Ù|>¿¸¸xíµ×¾üòËv»}cc#SwQµZ]ZZr»Ýù|Ì­ D�û*”[aé¬Vk.—;}ú4ƒÁ8zôh»Ý& N§•íf³¹´´ä÷û=šËåÖÖÖ,K*•‚Þ 8FN祗^Úh4Î;Çd2GFF¯¼òÊL&“Ëå|>_,s8˜Iòù|SSSçÎc³Ùh}9r`¼z½5BÆkœív{~~~||œ:ò…/‹Ñ QÁVªT*‡Ãáv»A,ïE{»Ý¦Fô ÊÃl6çóyRÝ‚üüŽñ®çzWö„ñw'#Ìx“ÿ„zaÈTŽ;¶²²ÇßË.ÏÏÏ¢‹dšÔ“¨oGxW òA*Xƒ >ïmuÒõÒ&mûs/ìmu’ÏÍÍá#%ÉŽé”ù$ònW¤$:H^U•JÕIÖÔJÎm3í<¹È¨¦ýgûË+Û”¨Ðëõ–ËåÓ§O?ñÄSSS?úÑ ÆáÇU*Õc=öÄOˆD¢_þò—P[Ÿžž~üñÇßþö·ó›ßL&“?üð¯ýë'N|ï{ßs»Ý‹åç?ÿùO<Áf³zè!¥R©T*¯¸âŠ_üâÇà*•Ê#<òÄO:tè§?ýi:öz½W^yåÔÔÔE·(y>ŸßÜ܉Åb"‘Èáp€‘„Á`¸Ýn‡3;; 5X™L”]¥RÁˆ·ÙlFy¥[[[$ð²Z­(vi4š\.§ÓéÈ.’H$h‹"wQ©Tz½ž@ À1ø›ä èu‰Åb³Ùl6›£Ñh6›ÅQ2™¬Õj …"–Ëe³ÙŒTÏç AqôÛÁ`°Z­š<!Ü!šFÍfskk Ѝù|‰L&s»Ýn·Ûáp�÷L .rP`¤e±X4Ä”H«Õ".‚ª'Nœ)—ËçÏŸ'ǰX,ÒàmFMš5òb@`0hΉjR Lu %a ¤=.@/‹ c=yJ¯×÷ò\Y�Nšz¨£’G¨®”ö5ºâr¹åréé |t»ZL&S,È´Ï€‹ð•à{ %¦ö�?›¼M:4Š»º:ò úÔß@( ‚+�l6{ìŠ#W~æª^ù-ùßÛn»í¶Ûnë|ÉÍ7ß|óÍ7Ó¼òÊ+ áË_þ2íÙn¸á†nèì?‘?¹ûO?~œ<uq‘=R DR^Àè"x¶¶¶ø|þÙ³g©¥›Í–L&Y,–R©„ÆDgŸXÔgÇÇÇ×××ÁòD"Ñn·}>„_m6‚eŒUe³Y©TêóùL&S>Ÿ·Ûí�js8ÇS,WWW  ¹�#í… Pä …B�Ø×k®¹Æëõ>÷Üsè~¡™ë#•JáƒÓé4´äu:¦‹:"µ .Èd2‡ÃAc S«ÕÀGöëÑÑÑÍÍÍr¹ŒyÕJ¥Âår1¤’Ëå€\./õØÊd2.—›J¥H.¢Õj ƒÏç#æ¾R©t*«QM TÁg¸O«Ú5DV*•étzssS&“éõúx<NuEår¹ðF *•Š\.lÖR@t Ü¡ÂPdá�� �IDATÅŒ± þ þ ßZP$ç ÎTím)Š|>¯Ñhv ØÏꄼ='¬v»}°jëäÝ1u:'PƒPï¯N§Ã“Â=*Žf«+2“. ø%—\Ò«ü}Q¦ýM» uDšOÔùŒt: ‘BüN B¡�â¸'N¼ú꫉¤T*AE‰ðë‹EÐC £)“ÉÄb1’›L&ãv»+•ʵ×^k2™Àææ¦Á`�“5hãŸÏçr¹ét:ˆD¢`0Øl6Åb±ÅbÉf³ëëë‹% åóyÇp°�¨©E"Ñ… ‰Ä‘#Gl6‡ÃI§ÓZ­6™Lf³Y@�Ä|>V° looûý~‡“ÉdD"Ñe—]¦P(ªÕ*—ËD"±X ˜ÀíímL(óù|Ü%‘H¶t7Ãá0¾f³Éçós¹Ü©S§4 &~˜Lf"‘J¥Pz„z!ŸÏ'm`! …B§Ó™L&ëõz¯¢=Õ¤ÀU`ü™z¢‘¬ nø¨¿ -´Ç-ÚƒÅÔfÈôz=è90‚F´».<¥ÕjÉ´�¸²Ù,Ò÷Ί%œÖ~œ\æ(£¿©çù“ɹ6FoN-ÒáĸœT*…@À Ÿ(:ùŽ9²ŸMpqýo-ðÁŒƒÈf³©ú7f³ÏJ¥RƒÁÏçårùÊÊ äò677E"‘R©„‚©›ƒBž ³áxjuuudddbbÄt2™ E ¹h€ã0|ªÑhb±˜ËåZ[[#ÓƒA"‘,//·Z­‘‘$LG£Ñp8ЭR÷y.—K&“Ðç]]]õx<Ñh”¤J°q‘HdjjŠ'K&“«««Ä-‹ÉdÒáp…Âd2Éd2Á£¬x<Ž™\ò)¸ñx\*•noo·Z­ñññD"At€�uCs”Ëå*•J‘H4>>nµZ[­Öc=Æçó£Ñ耠ªÎ¹]ê4xQ‹úOƒÁ “É EŸðšÇãÉåò>ƒ´L&S¡PNÛz½ŽùÜA®‡ú¶µZ-‹õ‘Nß?êøþƒrNT—€š@禋Åb±‡Íh4¦R)Z±Žú+2™L—ËU.—©?ŒÙlbŸxq|õf!¨/—ËCCCb±X¥R¡Üijßï'{ !y»ÝÎårzz­jÛDΤ×ëñnÈ-íb"’¼‰ÍfÚÚ»ù|¸¸`0Þ‡t: hÅbz´6¨—FS©”V«]€~o6›ƒA«Õ™L&1vFáf*• p ‰DB&“ŠË³ÛíÁ`*Pä4—}ff¦R©¼òÊ+&“©\.czÔÔ9Ùb±¨V«‰ #ô¥p7pͨ[ ãòš»äØâJZ­[[[Ð …D ‘z¢».µZ™­þAªÃáè…@CxA+ÐY,µZ­Ñh^yå•^MEð£ÖJ«åÀI7 Á×b8&£cƒïÞÝòýñ¬>?îÎI(ªÕê^øúÁWö<êOˆ¸ fPã%µšÎªc<§5©}Ëz½þ¿5uqø’Ëåhr òÀL”F¡œÃ›L¦\.Ççó§§§ÏŸ?o6›ý~?úCR©Ôn·ÏÍÍ•ËeìL¹\Ní\ºÝn…BÊ"µZíõzA¾T*%¸\.XŽ�·C '™L‚ ÄnpŸÐ››“H$áp˜ÍfÃØ•Ëe´mÆÆÆJ¥R8ŽÇã:nkk èÄÕÕU.—ëv»¡ÊŠÓáp8�õÆ›ƒûÜ`0„B¡f³©Óé Í!p@ñq´Â•/í1 kµ“ÉL&“˜s»Ý8ƒ}W©TxµZ ¿H$*•J…B÷“ËåÎÏÏ#mêJ(Óëv•]Qí@gAouuutt#_döÈáp`ê�ÿ¤v.ñ³v¾9üŒÕððp86 áp¸œÄ%oðÜ‹Ëå‚ÀÊïãÑîóãÒ"¬V+ |P0¥ÑïïjA˜€ö`½^§9'.—ëñxÌÍööv2™„BnŸ7‡²'m3µZ­Ã‡_´æ`+‹aÏ¥ Fc0¦¦¦†‡‡ëõzg)‘H”J¥ÅÅÅ¥¥¥Ã‡Ûl¶w¼ãR©4›Íùùy² %‰Z­¦‰D²²²âñxb±&pWVV¶··M&‡Ã¿�ƃJ¥æ?ŒŒD£Q‘H”ÏçÁÔÔÔÔÔT³ÙÍçó U«ÕÃÃÃ('ær¹±±1>Ÿ¿µµU¯×ù|¾R©Äø-‹ÅVäl6ªÐÆu¢€Y­VA`:??¿½½}îÜ9Bß•N§ …L&óx<W‰DSSSf³™C�g4‘zâKî�Ìxƒ ñ)¡P(Ÿ9sfvvöÌ™3gÏžF£€M]T1R\$Lûüú}¢Ìv»ÝÙ&Èår˜ñ¢–U[ŠD"¢BÀ Ëf³ãF*•b•º^0æl6»«þ–L&ëd‚Øí …BoÏÄb±z±cïíÇåt~Ïb±ˆX‹U,ûÓ¤ƒÿƒZŠv»œù¤ÏÔat‘Ôë0™áóù¨¥d­VËf³©ù2ppqý~-"(`h¿=È7Ñ_1^¯×jµú|>»Ý¾ph,..Rw&šTK=77‡–0Ö©T xkØ÷v» Õ%j躵µU*• ÆFäøx<žX,æñx«««õzýìÙ³0¦&“ ëL&)‘H499Çgffìv{8®T*~¿_ €H¢X,ƒ’+‡§d¼†å…dàOŸ> žYHo …ññq�‘æçç5ÍÑ£G777©qk«ÕBÚ„K¥ÒßýîwD^$s×ŽÌ ìï^¯²ÈKp¢¡ I2;åÙü~?aÎZ]]…¤á€±ë+‘,â&ŠZñŠ p»Ý¸çããã à”˜“ɼæškÊåòôô4JÁ"‘”7n·["‘PÑö4'‡OW(r¹¼+`I6íõ½¾TŸ²áAyÜùÁIh•R¯×‹ÓÔjµ,K±XÜÝ«3¸™@ 8tèö79´oÂãñphQ… OQ'güžäÇ€6¡úaTêû¼¹†ޏÞ<ktt”<Z­V«Õb¸ÝårQù¢ l zèä¢ ¸s«Õ‚°5áFÓHÌ-4 ð‘«ÕjPí1 pMLLŒŽŽRIC�‚`0‹‹‹.—Ëëõ™}þüùßýîwF£éè C0ÜÞÞÂ[áÖl6¡…w³X,/¿üòÚÚÆrµZ­ËåB,/”J%zþ›››étzccãСCL&l`"ÇlµZ.\X\\“^,›™™éZQÑh4F£‘Íf{½Þ™™ôº¼^o*•ªÕj4“ÉT©T¸±´ÃÎãñ  I}°óx’?¬Õj^¯W¯×Î7::ÚçY@àp8¨>'Üò¸Ïçƒ×êê*¼@¹»¾¾DnÕj…‘V«µZ­‘Hdff¦#*•ª”Žz<Ïãñp¹ÜC‡ H9q°Ëd2MLLôÏbû/ T1Ë …öIÄ×¥ç„*­ÇãŽd­V2’æp6I™ÍfP"fÁÄ8´Oz9 0ÀR]jn„$šä¿,«BµýDú_\oØaP(\YY±Ùlñxã´¤Ç@2 è°0™LNÎÏσé•Ãá„B¡õõuZ–ìdƒÁP,™^^^æóù6›- V¶Ùlóóó6› l{˜¥%oU«Õ0Œ»ït:u:Ýúúz"‘�ù74ÌP…ÛÚÚB«€Çã)•Ê••" „Ó~ £Ñ‰Dàúú:x`+• i¨`" 6›m6›!ÛAu ¡(—ËÁ`Ãáôã †D"AqÔM8ÑФ†çÏŸï|§Óéàõqy}Xž% î¼T*‰D"|>„`qq‘`â;€‹4ûKUäñxÔ­‚+AuN,£“711FßúÖ·E.ÚÝc±X€Ú‹‚eƒëÃÃI«Bùý~Ð …BFCЕoÌ …Bû‡ …ƒšŽí ˆX]]5FÙ™ŒSÕPú`år9m¾šl‚Z­¦R©¶¶¶h¡žBU—ÅbÉd²L&³cñOyq1^Dh4¿ß£N�ˆÆanx<žF£ä —ËPöB_(B¡¦e+• ©Ë‘ K ön˜Tl{˜*hp�€k�¬l6Q0Ù¨"‘¨ÑhÔj5§ÓÉd2e2ŸÏGÍp F‰DêõºX,N$‹oNv2И¯Òh4kkk¸!4®EA´ºsþ¯Ýn‰'‘H”J%øÝ»ÞíX,&•J‘̵Z-j¬ÙYP"H9Ì“f uT}œD'&&, ð‡¹\ne8¤nƒ[C¸’Üä†C¤»T*a„R©tbbâСCPQ*•‹‹‹ÛÛÛB¡0›Íbq8ü!õñ³ö)NBzTTÌ!bˆ^ö72§ÚdZvÑh4ú„ÀØ[5‹ÕçW‹Å:nzz Ø”wû½;ˆd»êóx<0@ã2¨i¦B¡05ÆÎ_½«LûÅõ{º0 ŠãŠÖõ ²X,½^7ã÷û³Ùl*•‚ˆg2™´Ùl™L†Çã%“IàÀ1ƒr¯DÍ`0@pK(’Ä‹f àlðz8Q‹H<âå Ãápx½^0‡ LÕëuµZíp8ìv;¢rˆ’wp8ÇjµºÝnØGˆub”0‡„ÿg³ÙV«˜dÔᅫ‚AòÔiþúß"(QZ“j1»¾$ë}~ß@ �¼¥^¯'«Û}ˆv\Åb‘86­VËd2}>ßÖÖ–P(İ?¤¹¦§§;6>>§X,¶Ûín·›L/Õj5Zp …ºJÐò­=XTüÄ}Š~PéüA;±iƒ/²:›)ý­1ø/,sB}¬^¯CR”*v»”…¾/"ÍΚ£P(‰DÐ|³X, ¾@¡P¨ÕjdKz½> Q }ýw­^¯'hcòJ*£âÅõ{Tǧþ½ÊPäYL^£4A„YÁå(—ËçææNºÿ{F"°“äjÿêy8†w©T*F£qkkK*• á¿áñxÐ4’ËåÉdR¥Rñù|“ÉÕ Dß䃠Á!Nœ8É(h!Æb1 åÀÒYjíŒL"”$UàbïüF$9ëu‹ð8¤"�Áß?~º^¯ÏÍÍ…Ãá^´/¾ˆgÒétÄÈB~¶2µ …B©T¢)‰¸\n<ÇÏÝ+ Äl�ã5ªš®Ã^MÞÃewÕðÝñ¤ì æ€Õ ð½ã°×~†M»8§J¥1i»ÝÎårK¥êã…BapXw§šä€:Îd2e³Yò‹ÅbðÆ+Š\.‡ñCÚÛf³Ù><Ǥ}Õh4ÈQQ©T{vÝ×ÿÖBQŽì £Ñ¸ººj³Ù˜Læúú:ÍÚl6”€šÍfg„žH$œNçÒÒ 1µX“! år9 Чº\4u@LLl(¬9 b�C$—ñ¨' ©›V«Å8'æŠ2™Ìðð0Úºäú!?=44 ….»ì2‡ÃÁ)‡‰D@gÜÕ8bJ,£Æj×>G½^ÐiUA犳™Éd0½»ÿ_¼Ýn§ÓéD"±#‘y¯¥T*!¼‡¿…;øËd2áׄ´q:ía½^_ZZší,¢©7°Z­R«A½~¦W×9åÓÁ®¬­7NÓže`÷¼d2­ÜÕÅ9‘ñÜsÏMLL€—Ö6DI]¥Rõj õº€$iµZ‹Å‡õz}¥R z½>‰H$‡ÃQ,&ßÕ×ëúÊd²>Ü!×›vQ±Ú„»W]ƒ«`§>år¹677c±ò'è8À¦D£Q»Ý¾ºº ®¥ ƒÁ@ÅYÁU€Ð©ä)§Ó ˆªT*Qï‚™p¹\KKKCCC^¯—ËåÇb±h4 zr¯×Ûl6£Ñ(m*(“É /…â$ÇÛØØØÞÞöù|¸3ø¾xñÖÖñ£'Nœ¨Õjf³Y.—Ÿ9sÓT½ærpd<•ô*„( ¤ ;'6}J7£ÑX(vL†€V !,îÕ~z0Ät€§5™L dºñx|}}ÔØýÂã$(¡e$´Ëh6›ý] â˜^{{À9å‹r´ÜçgJ&“ÿ+€çÿ©pôwNÔB?$¼  ÓkôŠ˜¤RiWô¤P(I¥RÐ †‹†DiµZ}ûÛßQ5h”A “ŠÙÛqŽŽ®¬¬Pήqý~­r¹ Õ¾^Fv||üüùóÔP ­&*«±tv»4ÕÁ`ptttii ^ét»¨V«mmm©T*›Í‡‰húÚív±Xd±Xh2ùý~§Ó‰Y(’ßcÓÖëu¼ˆˆÄbq¡PXZZª×ë&“Éår­¯¯Ãru5ÜÍfÓëõ^uÕU³³³+++€5“D§Z­¦R©'N„Ãaª_XX‹Åãããv»=ŸÏŸ9sfG†Í ’ä·`0—\rÉ™3g “Ç- Uωþ@p hïˆUI&“»-C "çêñx666ú ×j5´K¥Hå•Jåòò27J¥ݨÛleee?3€K{={ 3LØÉ;¾ ?Óë:Ï«R©u2-Çí$gè ù€c Rî³X,j¯ê½¼=ŸÏ'DœX$…\È͘L&›ÍnµZÇŽƒÀ Ê»±XL.—3™L¨ºu.̯ÌÏÏC¬Í3]\0kccH(šL&jVM <J¥Ò`0 1ÌH•uP(kkk¡PQQ»Ý&0T«ÕÊf³1Ÿ´²²røðaô¨ õ×l6Ng,#ä§L&33™L›Í–ÍfF#p­L&“Åb8®T*Íf3æaŸ{î9@Ou:]£Ñ(•JjµúðáÕJès’ê•J%BœšL&ùË_b®Ëd2…ÃáB¡055…sFŸxâ  qŽÆÇÇù|¾T*]\\|饗¸\.þIõdLrp ØÙ‚g¢>Ò.K›`±\.áèà1699 à=ï"ŸÏ‡{ÕËYr¹\2l4···ñqGŽA‘óä hp:ï95üúû\yÿ;ˆç~ä v5ùÄNl'‹mUlzZ¹Ùb±€:s÷…<Agñš“CÃÍív£ñ‹y·L&# [­V$ùÕ¯~…âÞÿxQ‡:8 n=„ZÔ¬™Ïç“<©Slðâú½[<þ<H¯£Ñ(Øí¨¿8â$@pìØ1ŸÏ‡ýÀãñø=1gS*•R©),K¡P Q°Àõær9²» ÆûAüJN¯P(´Ùl¨ì…Ãa›Í$a£Ñ‹Å“““ …P8zôh2™„þ:É$€ š™™!µ8½*•Š4&“©ÑhçƒA ëD"Ñöö6æ4ÁäÒjµìv;0c‘H$@D£Ùlø@�E ±XÜUšoW ÷LâSŸ"2Œ»Zä†ãDçóy’ €áéÆo,‹`ÜçeŽŽöz“f³™L&år¹Z­t³Ù,€ �% …B¤ŒT¿Ëf³9NW¤R©d2Ù>€˜L¦ÇãÙÞÞîóA}n,ã5í¡]á!{å\.·—]ÝÕåQMlõõ¯}À¿ ƒäæ²X¬N´â–×ë%ÿ …BO>ùäÉ“'—––p¢„ŠD"©T:Òl6‹‚‹Æýcá‰<ž ¶f0:ŽÇãI¥RXò¸Õj-—ˆÍfSéËP¸(‹"‘YÙÉ‘H¤³ÞIÁ"•JËår4…x^Ól6ÑX. AZéÌ™3:îå—_ÖétÁ`P*•r8œéééË.»ìÚk¯f³ùŠ+®@ÂËNE AÕ|ب¿Éd2áA‰D‚sá÷ûI… ޹^¯SqªV«•ÃáÆl6Û(´¶ø¦ýÁD@ëÑñÏþú+++×\sV«u»Ý€,îó wÔÇ-PÙãñðùü£GJ¥RÐ&‰®¾ d]ß0•J (·Ñß³}Kê4ÅàK¡PŒŽŽÊåò}^ ŸÏ×jµ˜¦è|€ ýÿîìcÇOÌ,oR3§|>O«<"�¤&}$¢_ÀPîá" q{*•*™L®¯¯©.“É–¿F£±câ™N§ðùü+®¸âïxÇÅÌé s ƒóóóµZÍfëtº\.I:�™@ŽL&©&iM0¬×ëÙlV.—csbÂ?›ÍB»Íf ’©@Ò ›¼ØÿÔ6ÃøøøÖÖV­V#›×€|msdˆ.#‘ˆR©,—Ëù|¾Õj™Ífx«ÕÊår'''=çp8ÕjÕh4:N¸OdEÍfsmm”2™L«ÕÂ郬Fg©„´î©uŽT*Õjµv³ …B­V‹ñaÈb‘([$q8­³pàœÜà9d³Ùñx`Ë>¤3ûYjµšúCËår•J…<µÕjñùüþ�jµJ´Á¨»H*•¬dù Ý®R©–ú}Vðt/¹\.ÕæãȤÓé½]]¦½s™ÇãÑ:¨`?¤U'Ãá°P(T*•¹\Žè¯ï9.ær¹2™,™L¢ªV«s¹¾0 .‘H:GIÀÂèÐ0¼¨çô‡´¢Ñ(΀V«ÅŽ%@m¬NI˜x<Ž‚†Á``³ÙĤÊd2”øU@ßdcP �\}SjfOü厌ËÃèt:p§®®®& ŸÏwäÈ»Ý>::*‘H`pQrÄÔ-PHL&òN4¢P`ØívÈÏ“IO%oÔgNS ô±³úUŒÿŸ³�Oõ*!s}8 šÍæË/¿ ÕÖÖ–Ýn‡nï@ @ßQFåÐ#Ü•,8Ç#—G¨ÉÒjµTøLŸ%‹Y,ÖÁŽ|õg(ÝÕêÜBÓ<¨÷çÜrË-¿>ó9êC+¹;ƒ2Ì$ÍDÃAè €®k}}ËåÒ vä<hµZçôªì³~zqý~-“ɉD/߃#œìê΂;ubì4H"‚†t!^C­‰)Šf³I5|>ßh4æóy2·Øl6Á¨×ë‰ò๰X, ¹OsR"‘ s6Ô(×€£ ƒrùšø^`ˆ(•J}Tþƒ\×4¥×Aë‰Þ3•õ€ :’™½N­{¨mÑš%}nã  sbðf öÍ¿ÀRPïÆÚÕ«ióz•J%‹År¹L  =3ø;tK­ÎáK’pŒJÛÕyUù^ÿ°—ÑhÄdI"§ÓÙõñx<NµÔN{¯ÒÔI¥®~OµZ¥=…¹j­Ãl6ƒú _½®B¡€—¡êX©Tàç677Åb1ÂOrÙÇ!šîŒ 1 ÆxMßS´WV*•d2ÙëÕj5jRâv»iÄÞ½ÎàŽ€õƒZ¨göÍÐÐÐÞú^�D¼®×ŸL&ív{¯íJÛŠ¯Ÿe#rV¸¨£àœîºë®ÎG].WWÆ$´£:/ ‹ iÃÃèªí?iµZˆ× ÄIÃDˆD"2‡¸«¸æ‰'žè¤²½¸Þ´‹¬ôªGѪmhí0^Ã8áA¨w÷ÿ,tkØl¶ÛíÆ#„…Úét’2šD"9|ø0­Àápìv{*•¢Ú”ÍÍÍ………P(´²²"“ÉŒF#¸m–––Ο?Ñíím�K¥¬“Áu\C猤V«¥¶ÇA Ó—Ïç» Úi¡>ELÿðð0͵÷ ¨:¥ýîÃë·a^¼ñU£Ñ Âê‹Å°]¥R©Édú_9Sñxœú»¾x<ͳ:ôtÈÄñŽ÷ô§O ÁºýöÛ;Åèâ®®8 Ã}Ô‰*dz7m¿ßO%XK&“4‡‡ÔöW4N¶NÓóÌ3Ï$‰³gÏö¡[þüç??99‰)«X,699ù‰O|bÇ ¾ë®»&''wUž¦™àÉÉÉøÃ]Ÿ]XX˜œœü?ÿçÿt>5;;;ùÚzüñÇ;_ðÃþprròÉ'ŸÜñŽ;öž÷¼çÍæœ*•ŠÛíî¿‹h1f,#`_Ò‘Êd2]'-0D‹ �ÝI¤™J¥HïªT*ù|>�ÄIv‚¿"ÆZ­V»\®Z­6>>ŽQ!‡œôüüüË/¿¼´´騵µ5±XŒ#S©Th§zšˆ^;L¼ÍfK¥R½v­V#e&“9>>.‹N§V«åp8ä4mllðù|â©nµSoº×J$ƒ×Z … >Ïív_uÕU;=ï¸` ÷RMÿ#<)ö‹Å=”  †N§ëÅÉ;ø-Ú›¥ª×ë4¤B8¦…S;Þt‘‰Îd×Å¡ò c±Ù쮺×;^19 C¥RAÊ:C`±ÿŸÔKÎ$*¿Õj•JÑ9<Ñu¸£D.—{ì±ÇÚ&»Ö¬7Z/¾ø"ŒN'Ô"NƒA|è¿¡Ž ¦A¼F¥R ŒÅbñãÿøÇ>ö1F“J¥È b±8ŸÏ“ÉLzær9¡PØn·+•Š\.çp8ÛÛÛÁ` ¨Ô“¤V«kµZ0ì„BÍÍÍýÙŸýÙõ×_ÿo|ãŸÿùŸ?õ©OiµÚÑÑQÜL‡ƒ1`0cN§"Ò;Á�� �IDATqÓ�BÖ8àÑF# …Bry€ãg³YžT(•J¥X,Bë«^¯+•Ê^X•\«««Ô=‰OìZ‘Ç~k47-—˵Z *ФĦÑÅB¡`0L&S  š<ìO„eä¨ -ïÙl–0þ1™LC9r…¾`0˜H$àchê©©)¨.ìç÷û;¿,ü\çQ%˜:ê]j·Û‹‹‹@÷aN™üáÈÈÈÜÜœ×르2ÔHNn£ÑÀœrgÆår].W4•Ëå4V:Úr8ñx\ H …œNçÑ£G_~ùå®`ŠÑÑQ¯×ÛB bö½žU©TB¡pWÚ=4 F®f»†;¾¹ÇãÙÜÜìƒph•¶¨%l°Î>ÓŽ¹ š”ý/ KHb³Ù¶¶¶öCVÈ`0R©1£;ꦣ®×ëý~?—Ëm·Û¸­Ô!Ü]Ý»®g³ÙŸÿüçízSâKi~Ê«ÒÇŒ'Ožì基~©ÏþóO?ý´R©ôù|?ü°Åb™ššºöÚk'''¿ñoàe§OŸþØÇ>†àhccã£ýèG>ò‘~ô£ëëëb±8<óÌ3¡Pèúë¯ßûÞ§P(~øÃ~ík_ûë¿þë[o½•Á`ÌÌÌ|ûÛß¾õÖ[ï¸ãŽ™™™L¶¼¼ ?Ú5&¸úê«Oœ8ñï|‡Á`ÜqÇwÜq‡ßï¿öÚk…Ba³Ù …?úÑÈë766þò/ÿR*•Öëu™Löƒüàá‡þÜç>÷…/|ág?ûÙÜÜ"÷G}ôóŸÿüu×]÷ÙÏ~¶P(üíßþ-¸€ÛíöOúÓgŸ}ööÛo¿ãŽ;Nž<yêÔ©ÕÕÕÎçÀígU(\.·+p Ó¡PˆÊ"±ãü8íýq+à“É$ˆøL&Óòò2Þ‡ÍfCéÝn#žƒ ­Ýn' åõzzfsssB¡Dl6{rráW&“™)‹4VÀJ¥âõzù|¾ÃáˆF£:.•JÁ]QÍYWÏ?Tü¨3Ël6—GKñeiíV½°x„Òä+ô�¬×ë0`ì“7 ߟŸ§Aù÷¼ (ÜËö"£!6 ×ÐÇ"íCO®€þ®´R€hV\]]}½iE-K©TÚÐb±€™Édòùü®î¦‹EÞØØØ§gÚí2›Íår{Ñb±  )‘Hp”/‘HüêW¿j7þÇ31 ©7¥8e—'Ožì•Þž>}úé§Ÿ†c0>úèƒ>xçwž<yÒår]ýõxüÙgŸ}ä‘G®»î:RFÿÕ¯~õë_ÿúýï¿Á`þÖ·¾õÌ3Ï|ë[ß:yòd½^ÿû¿ÿ{¼ìÅ_¼üò˯¹æšüÇŒF£>ú(ƒÁ¸ôÒK?ýéO?ÿüó…BáûßÿþÉ“'5Í_ýÕ_ þeo¿ýv¿ßÿÔSOýä'?™ýÜç>Gžºí¶Û‚Áào~ó›ÿøÇgÏž%EÂ{ï½—Ïç_wÝu,+‹y½Þ;ï¼óÁ|ôÑGò“Ÿ˜Íæ'žxâ±Ç[YYùÌg>ƒ?ùÚ×¾V.—¯»îº7^O† ¤;vò—J¥A(J;8OQãºpá˜Á¤R)ä·Áµ£Õjqêõ:ñˆ±X,•Jmll`FÇd2¡Ÿäp8œN§ËåR©Tù|^,_¸p¡³Â Æ6ÔúªÕj4U*•6›Ïçw¶v„B!i†5 x&i+ªcèJ¦Ü«W´ã.ÚZ¤È#‹Ùl¶L&ÃÈ*©tÝ!ÉdrÀŠ­âºŸÚÜÁ{cä>P縯~¾~Û»s»’ß‚ÏçŽ53™Lø«$%€#þ¿\.ï ž·¹¹‰B‹ÅêÕ}<ÈjÌžÅ)È8ñÔԛ͉D, eû¼0‡“J¥œN§Ì—†gúŸ3¹’T\ˆ ›l©Tª«2ØóÏ?ÿóŸÿü7¿ùMÿ÷·Ûí÷ÝwßC=tõÕW“·¶¶¾óï|æ3Ÿ¹ùæ›{ýáõ×_ÿçþç]ŸzÏ{ÞóOÿôOËËË?þñ÷6¾úêï~÷»=ôZúwß}7yêŽ;î¸õÖ[Ÿzꩇ~˜ú'—^zé·¾õ­‡zhÿ¥ü7çÓcµZ¥b  XKŠÅb4Q"‘ ÅsB¡OlllÈår¿ß¯×ëN§Óél4Ñhtii)OLLôj3™L¡PHưb±Øòòr¹\V(Ôƒ]A¢ÏIÞM  8÷:b´$‹ÂM …BdW…Bª^è~ìÃA­ÝšP2R‰DTç„r÷ëºÁ5 0xåpmm(oíÈéQÍAœñîƒHœ¨Õê>»¨ÙlöÊ 8xûöJ@ gÜÀ˜¡îªR©Ô?¥…ÚíŸ8q‚Åb-.e½§þ¿VÞ!ëÐø[®êU]§¦ï¸ãŽ©©©H$òÈ#ôùÄ#GŽÜpà ´ÚÅ÷¾÷=·Û}Ë-·ìíVœ:uêž{îàæÀpqë­·ö¶>öØcwß}÷»ßýnڻ馛>ü; ‹Õ¿Ô¿2ƒdbÀ×3™LH•SòÀ;P33i±VÔB14 P”[\\ÜÜÜ I»âŠ+zœV«…¤„tÕjµ˜['³ðcIÔ SZÛõú(…w]Èei—Gê„:.™LjµÚýùìsí6‡î¼T¸9bÿN£d0b±ØA{‰ ¸ÊåòŽ1n×ܹm0üuò ¬^ytW}Lêàû¢–SöùKäóùÕÕÕõõut›l6[³Ù¤Z¢f³¹ãG€6†š*Öëõr¹Ün·ýã_Ž|èÝÿïk¾ã’ÿžé`+™÷ÜsÏÃ?Ü w·ã:}úô=÷Ü333sã7Þu×]469š¹¹çž{677|ðAƒñä“O~ò“ŸÜm3r¾û·#ÿü¯ÿú¯H$rÛm·}üã3$4{vÕ»iÄød±XìïÏÒétç±Çõ–ÚíöÍÍÍõõõÍÍÍååå••`ö<½Nœ—ËY;¤I¨G çA¯G;¶zg*,¨mE£ÑÈáp‡Ëå:tèЀGÐì‚|vŸH³7r †Î²ŠJ¥"§BÃ.C¬÷@‚6Záq ;Ùd2¹µÆ½Óøÿ_öÞ;H²«ºï÷úõëœs˜Ð“ÃÎÌî*€´J$¡ð3¥B*($,°eƒ/FZa ²Á a@ÑBÂYc@Zv6ÍîNØÉf:ç~œ¯n]î ýºgvQ˜SµšN÷Ý{îÉç|ÄåIgzR-¯q­VÛ®1†a¼^ïêê*¨÷T*¥T*yAº¤ BF£Q¹\Näc«Õj>Ÿ×ét¸’’Ó³ß~ÊóösÇn»NãµC5—”u¾ýío¿æšk|ðÁ_üâkkkßøÆ7„Þùƒü ^¯?þøã?þøÕW_}à 7LOO8pÀb±0 óå/™w{ Ã=÷Üsß}÷ýüç?ÿÔ§>õ½ï}ï«_ýêc=v÷Ýwßzë­û÷ïçeÊ~ô£ ÃÜ{ï½Ï>ûìÜÜÜ;ÞñŽþçþÌg>óá¸R©ŒŒŒÜvÛm¿ÿýïáýû÷ïÿà?ø¡}¨X,ŽßrË-Ï=÷ñÐæùàƒ^sÍ5oûÛwïÞ=;;{Ûm·™Íæ/}éK÷ßÿ¸­P£Ñàí‘ìïïi �Ú¤¯¯oyy¹ÝËÖl6‘Å‹ÅÀÕjµù|~+3¶q—*Bq¾ªT*D™ =²ñ†%`à®z†Ëåòù|�Ó8QÅc °Ùlx� ²_0ã5Ô5“ÃÇ4›M^ž/€·Û ã\·x§šÍævM9ÊårPæ#Ò@ðC[„Šœñ¸‚Ýnçî�õ7ûé™påMo{×F4i•Åû“‡^zé%)žšÏçÃë‹ü~(Bœm2™|>_8–ÒnMQ”J¥ò:Á¸@±(^)£Ñh¬V«Pðá†n€„ ZÃ0:®–+æV7”v“ÚaÍÄ•5kkk±XlddD£ÑT«ÕãÇ›L¦¾¾¾P(„‚“““F0¥ Ýzee%‘HŒÍÍÍ!Þu:^¯wyy΃a˜ÉÉÉl6»°°�5ÊðÒ®]»X–-‹§N²Ùl€Â�’ ÊšáÛìv;·ï8ŸÏ£žâÞÞ^‹Å‚�ôt:ÝÐÐP$ ~¿ßl6Ÿ<yvO¯×*k0ìëë+ûÈ‘#0SîôéÓ°<™L677—Ïç¡Õ^vwwo‹Ñ'NÇŽ›žžþþ÷¿ìØ1q ôìL(þCN§³R©À¡C#0Ñ÷­V«ËåòÐÐH9«R©Áÿ8<<LÖƒ1[©T¤»†øò:#Nçp8Þüæ7=z¥C`|xx8‹E–eÏriÕY;w—ËU*•ðö¨ZÒ1f³™eY¼„Çb±¼å-o1 @`~~¾³jD###-‹¢Ïñ²+Aà†â9�^)•Jû÷ïï;ÿªßŸ e›«Çÿ@]tÉe*ï¤rÒjµN§“(r…ˆÓ™[¯×iš†v øK½^^^^žû[ðµp3¹ËWNH?!Sº\.ïŒæ{5“¸r ?Þ°[OOO2™”âjsMZñîœÜn·Ûí^\\ä®A.—wwwÇãñL&µã8¨ ~WEê¸><< ý~?²WKײÇ¿ÑPϫ̠zVJa4MÓ*•ªZ­â þD¯‚Ý@¬Õ[B²zïðˆ4EQçòË/O¥RÐl°•‘¬Û¾ç„%Ú™¬–Hjµ¬aB9ÑþðͼØ»w/˜ä‰D7ÕÇÆÆà`ˆ €2`¥4 4Ö¯·â±êt:´ Ž» )oJ@gG3½†�&ˆò¡„L7èàWæçç¥O¼‡ÃÓÓÓétzdd„ÈL@¬áرc¼š 7!Íf37mÀåð¹¹¹\.Gh&™L™Z´£ÑØÝÝͤ[S›¦é ÐLèÛ�ž7ÊŠ''úúú´ZmgRrbbâlòEQÀHDéŠDª×ë===Ñh$Ì­æÊ"†aöîÝ;00�Ó‡‰—<ÏôôôOúÓÿû¿ÿÛâ°ð­h&^VAíhܘ™ÈWI,© ¨X,òdÒ]]ݼ@>l*•Âãf'OžÜzñ˜B¡à-ÝfF«Õr§•ÀX–d=(Rô1šs‡^ÔßßêÔ))sHÏ1 wU¥RÍÏÏKè#x¼þ‘L&QP8ÊVq¹ÐrO?ü#NUsÉb± I}~¿_.—«Õêl6Ë%Êd2($ ²³ÍäªÛ3J�ó(“Él6›Ä^pÑ.//C°N¯× Q­ÕjÓÓÓ¼’·Z­<xpiiIzmˆÄF%!é*ômm±Êää¤Ð2hšÞÞa²´P�]ºC§ÓéÚíc0 ¼E÷‹ejjJ(“a0P3/Áİ!þz¥ÙÙY¡6Ò³F¸ ÓjµÐðaµZ%Ö˪Õj¢‚ÎãñÀ—°,k6›á*'¤z§Édê[ÒëõPA¾õÄC,C5ÙBk� (é/‘*Ó?;‹EЩ›››(ñ&®¥�è’ðVËå²Ãáè¸>6›Í¶lZÒjµ ôÜn74€‹¿_¯×KÙy¡ÖWƒÁ bâ:tçIÂÞb0©œ~ó›ßlñ+t:]»0ƒìáå˜X,†¿èÚÔj5õƒ¦áíЊ,KgÃý(Š’2Cš¸ºPkDzl³Ù„hL0ä:âù‚FD“Öââ"ÈD½^ßÕÕW 8¹Ñhà¹åH$"T‘¥Óépí°RÇd2ñ^(ƒÁ�_ˆ¯¡~œeåtênZ*'Š¢ C8æ¾§e™¨AU=a©Ï �ÄðC„rBÇ„S"‘Rç"´lñ± Íf“[‚ å6) ¡–!veŽ9,³ ñþ’Ëå’ÒÑAK(ÉÍÜ¥£oKÝí½Îˆ‹Ô,ð´Š ÃÕ$®+ª¬E!nš¦Q/ ÍfËd2È0‚™£ßÍfuÚ®®®¦Ói‹Å’Ïç ë _—¸]ç-ûñ­£(Êétâ™wK…Ò{Š'^­T*øÂY­Öšº¤©¶…Ä£[jµZ­VocQ(˲ ¯‰Ã"žzx¬ÑhÜv�x›ÍF;N܈œ´´ ½Äk!ÑùÈ-B_ÇußÜn·Hø¢««K¢›Íf[Ʀ¡Xä‘vh‡K!ñ:FÜFCÜeµZ÷îÝ+d÷AÑ)×ÀbÆl6 bŠ?䯥ƒM� ï‹…Šª_à¥jµ*1/‹Aª þ_«ÕÂ&$ ‰RO­V[,––ûƒq;ËÛo±Iym (Û®/l4Ùl6•;Ÿ·^¯q¦­áC yáÄmj6›"ŽJ¥Rá+!—ËN'o=}ñÅ t\¿OlVDñ›Ãá�ƒ´¿¿¿]Û©Ø éõz»Ýîíšl¸C¯?‚ D.@Z€P¶Ûí~¿ßb±twwŽ“‚_cÀ€.—Ëét»år¹ãŽH‡Ã¨²}}}ÈÔƒ-¯Ín4¥G½ ÅÈÈwŽ*j#­V«Ä¯LNNBdI(Eа%’ ®l±&í ‘Ëåi™›.“NµZ-N›L¦Îâ–¹\Îl6o¯ÐCà8PYÍ[DÈFï˶©«]>”WÜíQN™L†PNh<b(j·h®÷ÐÐÈ=™¢Ñh.¼ðÂÞÞÞjˆ78Æ«®ºê’K.áÎV)—Ëñx¼\.Ê ˜|ccãW¿úU8¦i:‰H1ðAŽ eOy*¥W¢ÕjµV«…ÃadÂSåñx¸ |>/½b¾V«!d2!óÔpWWdŒ Á�e´èmýýýHoeX@ÇÔÝÝÝrŒ©L&S©TxmgOOoE €·‰:b“É´½¾¹\Nú¼G®¾Üºç¤×ë'&& h°··¶¼·b±ˆ&à\ÝÄårÙd2IÌnªTª‰‰ î�¹\.Ta!¨œÀÑÙ"hÅúú:ØÅb±Ý¯e XD"! S©T p»Ý°U©T€/%xòÉ'E&@îM%Uðn†¶â0Ü6â%‘okkm¯ã¾.•JuñÅõôôpSñgo\(+•J�˜À»ß¸¼GQtä/¡ÿÄÿNQÔÀÀ� 9Õj5î�À”ñ›@"‘ ( ÷ÕjµZ¥RÙÜÜ$ 5ƒÁàõz¥5›Í|>¯V«¹2‚ P(1IœÍfÓéô\pÁ˜ÍæÕÕÕ³ÜfK�õƒA)±\.ã#�ÈY¼§Êãñèõz˜Q$1¢#“É$ÖOLLh4šðÏx+jµÚLzø«G¤Ê \.o½±'—ËÍÎ΂ɂ¶¶PЈ5�>*ü;J´ÊåòÜÜ7²W«Õ„&J*§={ö°, ¸j<6.7ÅÑÓy/’B¡€¹/BçåRÅb1‡Ãá……صR©´¸¸Èu¤šÍf(zæ™gŠÅâôôôÑ£GyöŸþéŸl6Û3Ï<ƒ.ªÍfA¾@ôÑ~Ôf³ÍÏϋũ©©}èCöŠ+®�l:âïñxü’K.Ùµk×®]».¹än"¡Z­Úl¶+®¸¢åOüÃ?üƒÍf{á…^:^d``à÷¿ÿ= FòÏ\z½^‹Å200@žmnnâÎ h;îüÝž={º»»½^/�aìÙ³úK†‡‡‘I899 q’½{÷ò6ŒŒŒ@K;~eúúúÞô¦7™L&"bÃÕ”x‘t":¹„@e¯`ë5›Íh4úâ‹/¾øâ‹Édo„Ç špñ¿Øl6ŸÏ‡K8 ÈØI_s¹\ÆË”%šYÄž£Oá=U¡P¨­`c£Ñ‡ÃBXb:uª§§gii‰a˜ Þz.›Í†\±S§NL …„Ò‡âíÃ~¿_¨Zª]ï s§‡Ëå€Z®¥"´é&¸R©„AÞ¼ê™Bß•Ïç+• L ›–•r†ó¾ŠTNKsovvvddd}}M$šÓµ¹>ŸæZ"Æõ766ž}öY–eFc¡P8|ø0MÓ¼ÖŠÝn?}út¡PÐh4ÇŽÓjµýýýÑhÕóŒ©Tªééi|Âá‰'ü~ÿÃ?Œ`xù¶k×.¥RY,aŽÄO„æû®®®ÞrË-Æÿƒ“ï{ß{ÿý÷ßvÛmh £££xµH$ABgllL©T>| ð–——Ñuš™™©V«{öì£æÊááaN7==­R©|>ŒþÛFœ·í"¨jS*•D@tÆÒÒ’Ãá0›››HÙ+ 4 ÚJÄÓÚ0H­T*AOT÷ÍÌÌ@yÛÑ£G†1r¹|mm `Žóùüüü¼N§“Ëå>Ÿ€Æ{zz„l»ÕÕÕZ­vâÄ îM~ç;ßIQÔÓO?b>v»MH $J¹h²WFТÿôz½Þ´­ÞXn‘q,ƒã@Î0Lwww4Õét-‘`ü`[³äÿÄô¦i¸n"ïÁw‹Ä0 MÓø†×jµ¹¹9‡Ã¡Õj‰>ÚóŽópv»˜ï‡Óòò²Z­¦išØ=F3<<œL&Ýn÷K/½„Äu8öx<0>¸³õ /ªT*-//«T*éi*ùퟹ㿞~Î×7œ+”4²âêܤ¸ª°÷–s)|>·&‚7Ä)qzf,ëêê’˜„Ìd2P¿ ¨V«½½½ï~÷»kµ¨ëP(ô«_ýŠa˜ñññK.¹D§ÓhV(6› ·A¦¦¦–––¾öµ¯½ë]ïr8çŸþÄÄÄ=÷Üsï½÷>ðÀ ÷ß¿Z­ݳgÏoûÛX,vë­·<x0 e2™t:}ùå—ŸwÞy§NºôÒK8ðÐCÍÍÍÝwß}F£qllì‘GùÛ¿ýÛ@ ðØc---íÞ½û©§ž …B·ß~;.Åîºë®Ÿþô§?üáûúú4Í7Þ866†Öð/ÿò/ƽï¾û¼^ïÛßþö{î¹ç;ßùÎüüü׿þu­V;<<¼wïÞßýîw›››·Ýv¨C¿ßÿì³ÏÞu×]{öìÑét_ýêWï¿ÿþÅÅÅo~ó›ðàçwÞÿüÏÿ …|ä#‡Oü³84GŽÁmUµZm0xkáôz}¿J¥Â-•z½ÞV*8ý§ÑhT(p©L&Œ‹¬×ëããã›››r¹\«Õ–J%¯×›L&•J¥Ïçºð c)Bi÷Zz½^n¦V©TÆññq@/D" ïr¹èc£Ñ(%Ó ×ë%œ·ŒeÙJ¥?AQ”Ñhl4 “"¡ˆÚE(Á=d2)±fÄåráó¿Û%–e].1ú À)Þ–š7NÇ•l,Ë:Î\.GÔŒp%›^¯ñF#agär9qAïv» …¡œFGG''''&&X–%¬¢l6ËkʨÕj¹\Þò‰>Nœ¾Çh4ŠÔÎ\zé¥fïàz4[.æÓ‘ -¢–Q,˲RÚl———¥Ø8étZº± Ôð%d� ù¹«««¿ùÍo a°{÷n™LÖÓÓsÎ9çèõúC‡ÍÌÌ´Ô©‡z衇®»îºG}trròïþîï`—~ö³ŸÝ|óÍ_úÒ—öíÛ'“ɾüå/£¼ë‹/¾øÄO\ýõ>ú( ÛV*•Ó§Oß~ûí>úè{ÞóžGyäàÁƒF ^{íµ>úèÔÔÔç?ÿytÃ<øÈ#¼ç=ïyôÑGwíÚõÙÏ~.ÉìììÓO?}óÍ7CœýÈ‘#wÝuW£Ñ¸ãŽ;R©T­V»ë®»}ôÑóÏ?ÿ®»î‚sY__â‰'n¾ùæsÎ9çÕã0Y,§Ó Qû|>ÏWQ©T:nii©Ñhˆt Fñ(F"‘@ö©ßï§iÚn·ŸþùW\qÅÅ_,—ËY–•Ëåp€@–J¥œN§Íf;÷Üs}>ßòò²^¯W(Döà ˆ_‡Ã§N*•J …" ù|>µZ·^JAO‡‹&± œ¸ex"¢(½^ÈÔ4qu:Óél·Oe‰¶ÒV_.—777Åá€ãñxÇõ\ûI6‹Å†&�%sk¬¹’M£ÑˆdOt:]»i{¡*š¦«ÕªôoS©Tâý<f³™a˜™™®VÃRµZ­-PoF$îŒþ¿³š['ÇÓä¢P•= %;çœsªÕ*ÞÚÛÛ ™g˜š…[OW]uÂ@Òëõ7Ýtüû¹çžƒ„nÝyçñ!“Éž|òI‘åÝrËÿk)ûÌg>óÀÜ}÷Ý/¿üò™ÞÃîîî»îºëꫯ޿ÿñãÇo¹åT·:00pã7þä'?™žž>uêúˆÃáøâ¿H`ûþÙ �Ðùf4Ô7Ä@ñ—Ëe›ÍÇårE"Âf‚±u„\`Y6•JY­Vä píP„ÑÕÕµwï^—Ëáî@ Ðl6åry__ßúúº\.ƒ333çØ±cLJ29–e Á +áê'š¦Ÿ{î9š¦Óé4á Æ“ü¼ °Uˆ”{Ýh4àç$FcàÂÊår„x -–[,­ÚJ¸-¸ìŠ´»ÄîO¡<–Åb) Ò¡ÙÅ)¾üòË^¯WúðÜÃãÊd«ÕªR©xý`"ÄÝ Ç#EÈQx¾�� �IDAT,}Û'2h4NÇ ³­Ñh´Z-þ‹ÛÕ_Öh4FGGiš.—ËÄó ©T*Š¢güïxÇ÷¾÷½/ùËf³Y¯×ßpà ?ÿùÏQúúún¿ýv °¿ ™¤ß–O~ò“‹‹‹·ÝvÛYçóù®¾újÞ—æææ>ûÙÏjµÚk®¹ÏcÛíöW›fâ²¢^¯ŸššJ$‡F‚Qjµ• ð²7ÄW¯×a  À´ˆ;ɵZ=22n  $°, ia¥RY(PìÌÌL6›ÅùªR©à¹.Ç‹Å�ñ™˜M‹Å4M8;zô¨È¶pƒ-r¹Üív‹ƒ×µUJÚ5›M´ó¼c_ÄÉh4R%”MyMbWé ÑBÄmŒíŒÀw‡Ãápxcc#Nwww·[PýP•J%›ÍJF^.—‰‹#ÑÏ?ÿüÙ<³J¥V÷%¥RIÌ4Üâ¡âî$”Š*•J<:³Â@3q£ŸûÜçæææžxâ‰|ýqrròúë¯_ZZú¯ÿú/‘€Ã‡?üaî÷ïßíµ×f³ÙŸÿüç.—ëú믟ššYö_ÿõ_ŸwÞywÜqG"‘H$×^{í½÷޻ŭøÂ¾€úÏ777_xá…±±±ë¯¿ž^áUNEi4"àP©Tð\T2™ä^lHü—Ê>3™LµZåMP%‰J¥R­Vu:]"‘8}úô¡C‡�Éf³ öõõáõQ§OŸ^\\ŒD"µZ pkð°¨ôsøDðd2Y¯×[†µK¥þ¼“““ÐY¡ÓéxÛGÔjµÏç+‹-“¾ÃÃÃítÆÍÁ­ô«–J%½^/qXøk‹ HÛÖG„RA9Õj5 ³”J¥ÎΈ+“;[ž×ëU«Õâž&Ð9¹Þ 4oÕjµh4Êke2™3‡ÿ]¯×!þò,è'–eE4ÜsîC&é’K.ùô§?ýï|gß¾}<ðÀ?øAn~ÿþýçž{îõ×_ÿ±} y`·Þzë¿þë¿îÛ·ï{ßûÞG>ò‹Åòøã<xpß¾}ù|þºë®ûüç?Ï ×‚tøîw¿›Íf¯¼òÊ+¯¼2 }ë[ߺýöÛa /¾øâÃ?Œr—]vÙ'?ùÉoûÛûöí;xðàã?Î[HzÓM7}ìc£iú?þã?Î9çœ/|á =öؾ}ûÞö¶·MLL\{íµ¯~˜8µZí÷û«Õj:>}út:D¡íjµŠœc¿ßÏ+^c±7H…›uÙl–kÐõôôh4šZ­V*•Ž;¶¸¸xäÈ‘#G޼üòËõzÝï÷ŒŒLLLLNNBã§Á`H$€2 %‘ Q4¸¿¿_¡Pà�Û™L…Ú�s½]ŸfƒºÝn.ZàØØ¬Ab8dmm¸v»ýìÌ`-—˯(÷¾¾>ÄEZ­v‹f\4ÝÞCm90;Ö0::Úw Ý&!òx<"ý¹R/Q+k›ïø'!$\ˆ¡5\öJûÞ·¸ÅNOxÓ¶ˆ‹„KÓ4À ]!Í„„E½^7›ÍèÎ {Ó`0Èåòd2É0 îð‡k4Óé4¼T*•¸4°Ÿ ƒT*�A?Ä]„k ïx_¢i:•J¡å …r¹ ý†ÍføùZ­¶\.ƒoßö*QE®J¥šššúãÿ9è,F¥DZ­Öår¡Œ ¼Ë½½½ñx\èfH¸Rƒ Ã4›MÈ Œ …d2©P(ÔjµÝnïíííîîÞØØxì±Ç`U^o4°Œ‰‰‰cÇŽ¡Ës#¡:K©TöööÒ9üèàà ¯”û%—ËÍf3$ÞªÕ*hDBº3BO$“ÉvíÚuòäÉŽÃM[—ÛNcccóóóÜðÎEBH¯"Cs÷÷÷ãz×h4FÞ³l‘^¯·Z­ÐÏÛ:Á©]`@îmr8E ¥ÊhšFÝrâ˘œœÌd2\$\fË„óÆŽqͤP(jµÑúàñxà¢Â ýN)&›Ðcàë‚Wqtdn´!“É@6¸ÙlŠk&ñDà‘(:⪤¨ÐK*•а8@vàî鶬A|y~–°,‹êÖ$"ý‰eÙk®¹Ƽ„Ã0P»oÈçóx­ŠPñ«nÞì U|èêê2™L'Nœ(•J‡"öymm –GFFà‚ ‘T¯×D·ÑhÔét@�­M©T‚I;55¥P(ˆàâ ®¬¬ˆó-Œ©Õj‰D] ¨}ŸŸŸï8F„ Y^__"i4—ËÕV!®qÛÝ:&‘ ,èßZ­Öf³ÿ(Šz½*_Hèv3Î-D·“®Õj‡Ðè‘� tg¨]ÈZîmv…}€ÝÓ ¢/ ÀcäWoƒCCm ¹", ¢Øe½^ߢf!‹Å‚D?EQoÔëõm…F>Ÿ‡¢Æð§×õöö ˆJÁLÀ=j9¾DdMÓ"ÆF£A-ÒÇŽž¡i2,Ë*Š?üáÁ`0›Í AÁ6›Mè)9[`²èõzš¦{{{¡ÄüðáÃÁ`¿MÈ”AÆZ­‡Ã VÐx\…B¡T*qÓl6€Ð|9´E¸½Ò©T*‰C …BKͤT*¥Àt�‹,47avv¶¥¼ÎårȲq:jµ¤=]­V ;F A®ˆfbFziþ‚|Dkp8ˆ£ oÛ~gkh«H˜œÛ)ÐÍ'$ Zb¾Aµ"JV5›Í……0=Ú”‚üÓŽfzÍÑüüüâââ©S§p¦… qÆãÁa2™ Jƒjx…*á5™LH\* øô]êõúµµµ•••P(bW¥R:€¦ià•JeµZûúúººº†™››«T*"’ðè@ƒšL&—ËÊ­Wp0 sâĉ¥¥¥B¡ ×롘»¯¯occƒ‹¥MQªQ‚¢ÙNÇ`0 %Ê n7B%¥p@<eÎKBYðÝ#¤"° ñ¶@ Ïç!+Å>”¯mY!4¡o×óJñt¹ºP¥RÁ‚Á 2È*• oX¢³5ÐgM²P%Äô($B …âÕwÚ¡3M'Nœ <†P($n05›M^ѯÕj)ŠªV«ËpÂá0”Q¸\.½^Æ ¥Ói˜³´´„ä>8.¼.(ðÀB"¤ÉdÂY& Á·Á�I›”Ëe¡Þ—r¹ … š©»»Ûl6C;ÆL&øL6öd2I¬eٖç#‘ê9ëL½á‹Å¶·½Ò`0À¶tÚpWIg¤œÀå%‚1R ²ÁÉ–²T!K‰x(jÒ[ÄòÐór_’H¼+ÏårÒVVV:(¥9{Ê©ÑhÝ[^¯˜@d0-"˜‹¼#w24Ä;˜¸•d>aG£ CH[ /ßn·ƒ” xiuuueeÅ`0À§(J­VÛl6½^`àqÊçóBU¿P?†4 ±�xˆ–‡M&S €Ÿ€ZX€Çã)l±XL&hn‘G!¯×Kè{§Óy†‚KPšØÙ© · 1 !nik+pJ§Ó­C?½•·¡•Ûl6¥R óæ¥P*•š9¬"åK”Je»þ©œ�éìH™­LÍÚ¡"x‰aŸÏ'ý#¥R©e›„F£á‚#„Ãa!›‘[¹dµZ‰¨c>Ÿ‡«ŽFšÖjµH$Õ’Ðe%=æ\¯× …‚Ùl÷˜ …P( …PݼÏçµk¨T*Hæ–J%•J¿Pàþh__ßððp¹\–ÞÃíëG… 4kë˜Ä ‡oh©¶ŽŒO'îÒÙl6Nçóù¶ÂÛjµ"wGÊ(t‘åÀ˜wõz79êv»Û4ØcâïéééÜvSB4×A‹P4gNšÀŠ_ý]5;ôš D"Ñh4Úš)L&‰ŰZ­ÜN¥RAW]¼}Òï÷·,€X\\"ã¬Z­f³Y˜µãõz Ñh4V'ŒJ¥‹Åb±\[Þië]]]0zŸh1„‘ â‰DµZF£ù|>ŸÏ#9’H$Úuz¸kH¥RH1ô÷÷‹“Á`ˆ–ž“HÊP Ùív‰pyu ˲ Ë%ZÞf³™w(2e¶E§‚—\”Éd�0aÂBH¸ g!=à‡z½Þnè‹æª}F344$—ËÏ\K¬L&ÛØØ œ\@ÙÙ‘³;$B à ԗ6–`á8ŒŒàõétškrâ£*Á¹!Þàt:¡–' ÕëuhtÅiii —r¹ I·Û=55555Q5(«Ai·Û£Ñ(!r¹á¸4 <á* ¾Ÿ‰,n–e)Š"n Å œ0®^!fW÷ôôðFr¼^/·âÉjµƒ*VWWÅ)ŸÏê¦é‘‘¡Cߢ˜J¥R[Œ¶Éår4"9N’²tôÂl6+â•–J¥í²à¹?T¯×q.òù|øøÊvI$Œ·¥K‹…`ÒÖ …BÙl6ŸÏCáðð0^388¸¾¾^*•”JeOOH7FK‚{>22²¸¸»ŸL& “Š F‚¿$Mèõzn™©¸Q�µ[; àÕLµZè‘b\£& Ö-NR-yƒws4…/~æÖì€C}ëE †Ý»wk4šééi„mX.————aº9xQøe†fÌZ­†we6›Mš¦�¤# ­­­¡åéõz·Û½°°àñx*•J<Ÿ™™á ‰ÁC\Sú|¾\.Ç;úˆ˜à©Ñh<Éš×€3bYÖï÷ÏÍÍKm4PšËÖ 1 388(ÒÙ Ûºè¯×ëGŽá"Hö +¨ ‡Ã° "Boëë$6–ؽP(ÄÕ"Ä­ç“­è…d2‰Dz»…•ô�Ã3 °AÙ+ °ˆE`ÊŽivvß)b FGG¹8l@ccc¨§ Â)[d³YnQãO<!d@ãÔe—]†„N&“ñù|J¥�¶aúÀö²K*•ŠÇã.—këÕMojײC\d4µZ-2¡UVb§ÇãÉçó€Áˆ¿ä˲µZ­Ñh !EÐñãÇY–3===ñx¼ù Át:Ýää¤ì•)$¸…«Õj- €Çã¹®b±ˆ†•ÀôÈ .¸ •J5›Íb±È²ìÔÔT €!³[Üü@ �†Ü¯"Dj¡P€åIùÑÁÁÁÅÅÅJ¥²°° P(¸ £s¾V«‰÷\ ½^¿-ñ!ñåét:³Ù ¢ŸûN4Ѫ··7÷õõBïríŒ�}¸¥-ÂûV«U.—' 4ÝXä¾lE/4›M=@â'ñسFBšI&“ÍÌÌ Îƒ RÏ©ÖPmä¸ÿëëëÇ‹ÿã?þã¹çžûƒü�jÃÎ=÷ÜOúÓÛþ€¿üå/?ñ‰OˆÞ¡­V«E Ã©T 4‚™¡iº««K.—·l© ƒ©T Åj¾‘R©49‹Å…vBvF¥R9räÈÉ“'gff ²Öjµ"t:ýüóÏ?ÿüó/¿ü2h&„ß“ËåÖÖÖ"‘h&Ð2­Vû¦7½éª«®êîîÖjµV«U­VŸþù]t‘Pn/ÌS(-{qœN'¼G$…ïlñCÍÍÍq©R©DNR–'ÒéôÍ\à†òÚÚšÉdo˜YZZ*‹\¡‡ŠÔˆ o ³„ˆeY‰5\Êd2©T ­¡³Q«EuP®ÉH|_ËIMƒ³Z­V¤ÖE¥RÑ4-$§¶†—+r÷3<q¡ÿïKב&ÞßüÍß\qÅè?>|î¹çöööþò—¿Ìår—_~ùÁƒ` áù矿²²‰D†¹æšk û‡?ü>~Ùe—Ùl¶§žzJ£ÑìÞ½û·¿ý-EQüà἟~úi¨Ÿq¹\]t‘L&;|ø0 a]wÝu;šF"ä`6›-—ËV«µT*æªÁ`€ˆFãôéÓ�ÐY,µZm­V2 õzýúúº^¯‡HZww÷ìì¬V«­×ëëëë0ܨP(X,¼Ê`0 äÖÃ,×ååeÈÙl6äZ¬…Bû’ÙlÆ«ì rxxxpppmm­^¯Çb1@AL¥RÕjÕf³%“I½^òÒ:®\.ŒŒ=zV¨T*Íf3‘‹BZr3H ÛívnöÈh4f³YŠ¢Ð>ÀAë1,Läì …‚ÈõW©TJ¥r» ¶‹`¼@Ëbä!Áµô„ »(ŸÏ£bÃáø¤„%kµ0­\.—®»Ê^ÁEkîá· ø¡­”pÊI 9Þ›fµZS©$±T*•ˆrbæU•õyï{ßûÃþ=÷ÜsŸþô§¿ñoôööÞyç üÄ'>ñ—ù—étú…^xæ™gº»»+•ÊC=”ËåÞò–·8pàôéÓûöí{æ™g^zé¥ýû÷ô£ÕëõW]uÕC=_ûðÿøâ‹·ß~ûõ×_ŸH$¦§§ï¹ç½^ÿùÏÞápøýþïÿûÙlö¯þê¯vTg‰#)+ ÀM/—˼seˆ’Üz½Î²l?€–âÊI©TªÕêZ­Öl6U*U¥RÑh4™LÆd2AÒ¡P£lðÆÆ†ÅbI$€º­R©paÇ+•ŠB¡(‹Á`ÐãñpCd äxû:Íf3äÛ¹*¡\.¯¯¯' h_-•JU+•J0C6@ÿ2RN€ŸÉdìv;ô`år9×Çqý$—Ë•Je6›vx‰·7Q­VÃx0´!°Q‡# n±u¤h¨³£œ4ôJQµZ-ELÃ| ÜÐ!6\:ž8ÞF£Á0Œ¸r"ØüTÞP®{GÄÁ]†ÛÔh4„&<‰-[üe¥R)RæÈ Š¿¡Z­Š{`¹\.NC8dzþ,ø.·ÜrË¿ýÛ¿‰¿gmmmffæÀ_|ñ~ô£K/½ôÀ4Mýë__YYùÏÿüÏ}ûö8p`bbâ»ßý.s$yþùçï¾ûîË/¿¾äÁL¥R_üâ8pã7RõÜsÏ<x°Ùl~ä#¹ûî»ÿ\@¢¯E‚.WÞû]®ðoÇñ1•Jc‰D>Ÿw:¼Eá ·‚Á Áç‹…ˆ âo@ °øò}yÔ9k0$Ž¥‘ËåÜ)D.—kmmmqqqqqù7ñx|uuuuuFÁ&“It£A-//·ÔP°.~ÍN§^¯ßØØà- àîß—X–•.Ùĉ;^�× Üx򮮠%](¤h)‚7—˵ԠpLÛÒˆ–L&·zÒÂsª×ëÒhòÁåÝv1Ëå2:¼F£fÄ%šÍæYÆŒÿÊW¾¸·Ó3Ï<‡qDvÇóõ¯ý¢‹.ªT*Ï>û,þf›ÍXP.—«¯¯ïßøÆÇ?þq³Ùüïÿþï;ZøAºÁH˜„f³9™L"5‚fÅbñÔ©SRKñ0»,e¥RÙh4G$1›Í}}}�ŒZ©Tà%‡Ãáõz×ÖÖЗèt:µZMôð"c\"XqT(£@Éd2p†l6›\.á…ŠÅ"CDs q£‘µ„GcàÒy½Þh4Jhüöùý~Ü–/‹ÛRôÌ»E\5 �ö-mk«ÕÊ«9¯dkx»rQP“‚”7ÄZ¥³+ÂíŒ|>ßææf‡’Ïç†q»ÝP›-å#GÁT‰i¬”îGC Rgû¨R©¸~¸ÍÛh4àv•J¥h4zF±¥yéÊ+¯|ÿûß¿•o˜˜˜¸é¦›nºé&™Lf”Á`€¬’ŽŽŽŽŽŽßxã¿þõ¯+•Ê#<²£œ¶b<â­ 2™ Ä7˲geeE!<Ô&‰(Hèy+Cµ׺‚ðþñŸ ¿Ê—¶0‘â §N"Ä\WWׯÆêÖëõ:¤[www$gºÑ,Ë d2¤¨’ɤPy}ooo("ä×jÔétƒAÈ«±MñßXZZbŽ i\)~X­Vò„ö¶¿¿ee¥ƒ˜$ £ý‘.¾€][¾ÍëõBþGh¼‹Çãâl,îôPµu¿Íçó% <ˆ£ëm5¬×år¹Ž•S¥Ri9\\böo{‰¦é§Ÿ~šøã­·Þ*ÔxÁ%Çsá…þìg?»í¶ÛZÚóóóçœsξóïœsÎ9›››?þñívûÁƒwŒL&×ét»víj7†Ó××Ç+ú«Õ*HÏJ¥R©TŠÅâúúº8›AÍkww7ˆûR©„�!‘àÉívãµs¨ —»Ã›O¡:+ .--áÍétîÞ½ o‘†ÈçóH{Òj) —––677aÀŸ#„©Ãá€PX(ªV«¸ét:ñɞЌðMÚ5#pb}}½Ñh cB2NŠØåm+néšsƒQ@`ëfq[r¹^¯·ô Áåå¾ aDqOPú-k6›[G"ÞÜÜ$¯jµ*}^q,Á ?”×_é‰k4g'$MÑ´BÏ7<’áÅzPÁÕ½½½F£Q£Ñ|àˆF£wÞyç·¾õ­ùùùååe(Ô"K•J…>vë\ðàƒ~îsŸûÑ~T©T¾ÿýïû|>ƒÁ€ª*!#­P(þû¿ÿû­o}ëääd£Ñ8ÿüóï¸ãŠ¢NŸ>ýáX.—W«ÕrsÄEù|U‡*‚Á$x¸R©@7(Ñ !O ‹E°â‰B˜¼âDØaårYhTöüü<À›®¬¬@‰÷bB•y³Ù6 ÓÓÓPˆˆžTü‰lË�Ò4Ü/$rÉpÍñ5àD�‹ )ÍfSè)$î9Afdd$CE™x´ kf³Y¯×Ëår˜§ðÒK/Á¨º-2vgðßÈŠ;ÊÐÛEäRKL>Nçr¹ð6;ñåá^àJK’Õ‘XâúÛ¾ˆÃ´onnnllˆëmŠ¢`„TZûoÛì¶^mÂ…iì±Çº»»ßõ®w Y+¯ÂZ 780íÉårU*".”‰‹Ñ’“år9MÓÕjuÚâ¯:ÎZ­†bèccc¼Š“ЯðµµZ „0-ú!ÄÉýýý¨ëEüÊ( ˜°ðæ7¿¹X,=zTŠÝ-îkâKÓ4Ã0âJÖИY[[k×ÅA§300Ъ’• ÃpªgÁ5ħ¦¦>¼´´Ôh4¤úëŒ�¸%Pï•!¦æu[ …‚;.A¯×‹•Ñ4ª’L&Óvµô}y^¯W¨EQ&“uuu]uÕU5Ú‘þš Ô�+îšðŽåj¦®®®©©)£Ñ(ÔÝ íýÔ‚ÍxGáææ&žÝÅ…”J¥âE 3 F£Ñãñ@›*“ pNÆ X£Ñ(RÈgµZ5ÍÄÄD¡P8tèLódYJáQñ!MÓRz!U*•ÇãÁ7D¥Ráh„‹…Ûòkèà@ …‚øÕ‘õz}aa¡ã+ñx<NsI£ÑÁŸBïQ04™L°Eo4Í$“Éòù¼+»Ý¾•¦i†÷ò´”Ô•J…»8³ÙœÏç…Üóz½Žb\›–Ëe\w*•JÜ[¼v饗¶Û¶C¯*‚ÖN£ÑØ™¡Í5˜z{{-KµZ][[C\d±X’É$p2Š´  .š¦Íf3ÎHÜÖEpµZkçÖä,e2¼¦€àdñ'ˆ†B¡J¥b0ÀßÜt¹\G°r“ÉÄ{är¹^¯‡$¼Ãá@ô(Š2™LÉdm¸Á`°Z­¹\ŽíR#jÙcµZEB ÃÆŽ$¼Ç$ÒPó{^xá½^¯ÑhðÒbq}Áë…Ð4½•˜ÙlN¥R`y¼ª@ï¸á;‘}๞Ü?…ÃáΰØ×ÖÖÎt5˲„c”Ëå:Vu;ôš#µZ].—yKl¥ã,˜ÍfðêõúK/½433³¶¶†KqsFBàáEÁÁËDÈétJ¿¢Óé<ø˜%|‡ŸÉd�ÝÊZ­&T$ õñðCPJn³Ùü~?ôoJhss¿é¼:‹Å"Wm±X`ÖŽ\.ç69‘€/ò7n(·,Ôëõ„w…@î%Wà°,‹#ä¶t÷…U†é�ãç•Jår¹X–í�rSè˜ÄŸŠ_´Zm»C‰är¹t˜+úµ%›âñ8˜·]]]"±»!þz%‘Tªô› ÓáßÍf3—ËášÉårE"n§­HÌ "á]]]B¼GQÞØh6›Ñ­®×ë‘H¤åLa(lY¦ ‰-©5°ÙlHÛÀì•Òv˜"X¯×›Í&× Vh¼½½½jµZè·ðš®Ñ™Qëõz%êÞMàÀ-½ÿ4¯­­µLœÃèÅ|>/äÓ¤Óév;Ae:&5×ëõjµ*ä¼* ‰¦›Ä:8x±«Ro>Ÿ—>JƒþÊW¾òg δøêîîe$Û Ü½^Éï÷C6E«Õr/›PÁŽï’i4D„w¢]¹\Ft¹\NŒ¿L&“n·»X,ºÝî¡¡!€<'.3Ζåri;P„¼QJ|åù|~cc£T* ¶eh§Ói¡@·é ~H­VëõúD"! ÑjµýýýH1d2™P(”Éd¢Ñ¨PA2™„—ðÉFˆb±X£ÑP(Ò-KŸÏ'½¾— óˆÃâÇd³ÙPžà"»ÝŽ2aâxçD9~¾�� �IDAT;‘Ì똀P©p$©Õj16›Í%Åu¿Ä08:&!¢(ª»»´i¡PÀtÛ.xi|÷Y£\.g4Åk"€_E6±ƒ—vè5M‘H"`årÙ¡ÝÝÝ`þ Yd¼fPoo¯R©®×ëDT:“†‡‡ Y€†Ú5 nûN,‹Çã§N ‡Ã¼ˆ/¯P(àÐ…h V«ïŠÅbÜþ'˜D,ßR(¸$ÍårÕju``€°³Ù,J¿Ñ4 §F£ñxЛ�¿§\.'‰D"át:[®µÕóÊqé>D"‘êúïëëC±#Iç1ü˜²Ù¬Åb—¨èËd2¨R=¨n)ýÛ¢T*ŵ<�ËXd [¡f³)…æ²½ÏçÝÉeWÞ(%©œZ~L„Ìf3K ãT©T‚Á xZŒ×€Ý¡72åóy°Î4 ‚-‡Ãm©öx<‹% V*•µµ5„]ëp8p(tîTSÔøÉëè�»B"]J7wV:Èü†g2n±� ´†å †îînb \j›ÍFD )Š‚LþG˜®T*Ì6ÞíÞh4 ô ~ …l6»k×.ˆÑ!?rcc£³tµ_§Óáð¡"¦ëëëÈ#;€ûF#îñ€­P,aIù|žØ"ôârL­V÷÷÷s¹h[ˆ—‹PuÔ××ǾîîîFN¤Är¯×[.—»ºº”J%ïŒ`âúÔëub!ý|@’‡EÓ\ÅCQþÇS§NI‹Ô¿www£¯,ËŠ«Ob ;ôº'ÐL(4„pc š§€³ëáÇA´0 ‡ÃétÃT=x[4Åý¡J¥¢Óé@¹\."‡/š¬ÑhpaÔáX¥?’2ð÷L&Ã݇jµúûûãñ8aÔW*•ƒ®®®Ââ{zz |U¹\†žJ‡Ãáv»ñ;o�¬9†aàÙ)Š:qâD¡P8xð Ò P|111?£Ñˆt§ ´ô·@&Jy‡C 7 Þ´P¡Ph)1Ãáp$Ab m‘DÚµkEQÅb8÷÷÷kµZ8\½^ß1«œ!Z^^æµÖ××Q€at›pš˜˜Àÿ\ÍÏÏ£új^trøB FäÌè‡~XÊ¢w(x"‘‡Ãȃqt¤0nÊ!Ç_.—‹wØÆm¨Ý¡W3Ä*—ÙªÕ*Vv8(šï, P)Ðl6QδDvW.—{<ž……†aâñ8Ç<'ü/*• $r¡PX\\dî…R©ìÌxÚµk—”ò^ºb±„ª�ôz=\™ÕÕU8p=áÍ‘HU²á»Á²¬Õjݽ{·Åbéíí5 ¼Yq™LvüøqT… …ZVg>}ZН ¸ïÛÈH-3ÜGk+–333ƒ¶ýqqq1ŸÏB«(j�ä­­?b<‚à;ÞôwŠ¢r¹7Å‹æ³àÁ¿ÐÉ ^¸È0 ¸òÜÝ–zm666x#é�u,%–"RW#Ô]HQTˬT*ÕîdI)4;;û¿Im7==ý¿ÿû¿gbøÅ™ôz½P%®»M¸J¥¥sÖ××!<h0„úRëõ:àªiµZ“ɤV«Ñ7 ¥R‰°»]..\t:s‡}aø*)ÐÁô}Nú ¦Ùr.Z:&*úxo|ô9A2,ÂàÁÅÅE›Í†n4˲*• ß"D‹Ez‰¿8µ2ôç%8\ñb´EÁ`°Z­&=“Ïçk)H)Šj‰¨¢Ñhˆjd<Áè nÏC»™€¡2jµšÐœRú׿þõV~ ¡âï1™L+++ Y–åžïnÂFpýh“ÉDÈ)µZÇI)вÛí-«Åé¸îºë¾ûÝïþøÇ?þñüÜsÏIüàwÞyÝu×mK‹èhš–b3öôô´œ>@´ôëõzÜTp?t=à%³Ù,—ËÅ/|:ŽF£Z­}/»®¬¬€E=¡©T*‹éõúÍÍM”†aÆjµJg�£qÚÚL£ÑÊ©T*mnnêt:­V âÒl6Cï0z3¼· n™B¡€­Èçó¥RÉ`0@øæ çr9�Z­¹¸¸Øl6†±Ûí6›M£ÑÀÁ VQ(@}Ÿ5R(-q:ôPÙlV(„‹srK±†Ï•'‚¢ápX­Vo±Vø¬=ñãÐétJ¥Òd2·;K¬YcÄKMX–Õét[œÎ²,2²hšæšWR&aàL@8a\›ÅX¶HwÜqÇÔÔ ><õÔSðïë®»®··÷›ßü&˲W]uÕO<±wïÞ·¾õ­¿øÅ/ þþíoû3ŸùÌŽî‘¢œ E¿V«U«U¡\±09ááÖ™Á`ˆÅb‡ƒ[öÉ0 P`<Âó¶Ûí\´ÜfgWœÃ ^šU*•Ä'˜ðÚãN§³P(À}¬k!)†ûC…B¢(‚€×NQ^­�·:`šÍf(B+‡ÂT¼¸¸h2™¼^o:ÆŠhš†ò<µZ"„~¿?ŸÏ£æóyüG{zzÚºìD¬²X,‚@<Ëí"N§3‹Ùl6iY,[.â"´ �KF„,ZÄEÍfS ž,w‹  UáÖ¦JôujµZhJ‘¶bÄ`0ï±cQ̼ï}ïûé _qâ:ëÓét,Ër¡ÌJ¥R[µU\âVñU’Íf“ÛH±EZ__ÿÜç>W(Þýîw?ùä“üã¿öµ¯Ýwß}0ö&“É<õÔSEiµZ¸Þg´÷5MÌ+$T‚…û»�•†×Èâ:Æh4§ñZ²âÆÖÈÈH©T:tèïJººº #ôñJ¥‚dú!èîDli6› È <V.—óù¼ÏçeS«Õ`A"‘Ò‡ âÃl6g2˜jÓl6AªBUžÑhŒD"ÖÍçóûöík4ÞP«Õƒ¢(¢Ú»T*"”ÅbÑjµP¯ÕÕÕ… Ãzzzr¹Üææf(Â- TÙåt:E�¢¤J¥ÒëõñšL¦­”SCù a9Ùív¼æ~+$4¾½%»ò®7UýÔF/A”¾<<5 MÙ"Ú(•J9ŽL&Óñ¡ :àPFÂżêíí•â¶4NË·uww·•K –w¦éïÿþïßÿþ÷üãF£¿úÕ¯FGG?ô¡ =óÌ3À1*•êÊ+¯|ë[ßzâĉcÇŽ]zé¥P ù¾÷½oGåH§jµ R ¢C¼±5Ü©V«`DC¼¾§§‡a(Òét`ç‚…ǹ×ÞívCj~~^©T 1X&“þž¶FÅÎ¥R ÷~ ùT¯× ©ÕjxR¤0¸!ÂmJ¥R¼]2N§±Ôëõ|>_,s¹\&“Az=* "4¤ÑhÆÇǯ¾úêk®¹ÆívW*n9x©TªV«&Ãü~¿ßï·Ûí>Ÿú|¡�—Ïçëõz0dFJ ¯Æíêêòz½dMˆœíp‘ñâNS$¨¯¯9 F£ï`#(—Ëu6Ežw ù|WýýýµZ-™L?‹E)Ú“ÉdR*•- uìÐfzAhĵ[ºS\VáfҢѨHÕ?EQCCC¼Õzøò¬V+EQg"Yzà 7@C¾PßœZ­¾ð ò“Ÿì(˜-ZŽÓ{饗‰MÓ—_~¹¸2ƒ¸œ£\ñªÑhl6DEP#$$q¹\Åbqss3›Í Å"À¥¨V«¨éÇãñ€÷Æpæ'®: Ë›Íæ“'OÂÝA¾‹N§3™LâUÔ©T ¿Gõz=—ËY,†aˆ D±X$žšQ¬Vk£Ñ8|ø02Ãý~(B;Y(@§vuu¹Ýîîîî®®.ƒÁÇ­Vk*•ŠÇãèÖs¥rëõz„ é D¥ƒVª-ˆ­GÄæŽÅbÈá€(kKy¸k�툳àº;z½Þ`052è˜òù|Çq9¡å¹Ýî|>ŸÉdöîÝ‹Ú9Ìf3Q;C·û½'OžlKúý~°…¡ôÐ`0à£_ŠÅ":?nWD³ÙD‹v»/Ç—G´.n#ŽŽžsÎ9Dýþ!úýï?;;»±±qÁp_fY?‹J¥âv»!˜Ž€;;ŽW<‹EŸÏçõz5 ‚Q'L%ðWü~¿¸8k4HˆG""@Çåd¡ÑJèÛâñøáÇŸ{î9îðÀB¡ $š{+S©˲„Á^¯×‰(´úÆb±@ €×MJ¥"—Ëßö¶·]tÑEƒš½Âá0MÓ.—kß¾}—^zéÞ½{}>_,ƒ “H«ç$rËhš S-:c°þþ~ñ²‰7 Q$ܸîînŸÏ …ˆÐYµZ%ìu!– (ª] g!‚ÒÊ–=³ù|ž›KCÉEîÊqòz½D׊F£peNœ8‰:ƒÁ`2™ƒNµ)ÖÛåŒååeØÔ6HdDC¤Óinºý\4¥išdo]<C%XÅb"ïÜŠADf³™a˜õõõ+¯¼rGßH¤™™™‡~xyyùÊ+¯üÀ>À[S;77W©TfggGGGišV*•r¹< Šƒ) £¯ÙlF£ÑJ¥Òl6Q¤¤ÎHhËT䶓㜠kh6›DÂá² \.£ËÐÐR©„µ‘ªÕj^pw\ç­V‹g@µZ-h¹\î÷û Ñ#GŽ=zï½÷...ö÷÷£Ú*˜ðT¯×_xá•Juùå—¿å-o±ÛíÕj2¬z½Þd2Ùl¶þþ~ЂpLsssçwžB¡Ëån·WÕj•7râÄ !¡Üh4è"Ar¹ÍøhI‹‹‹Ha@¯4MÓx-Ñ©#"ô!}¸°°P.—¡D ÂÚÚZ €w©(!211!$ñ›ÍæÌÌ ïKâc\‰„7#‹óIÇÁ·`0(±\m~e ܪP( 'šãôï¼óÌ –e[¦”Ž?NQ””æP(ÔÁøÞÎÈçóMMM¡UMNN>öØc'NœxÏ{Þsúôé'Ÿ|rxxx|||tt,å©©)~óÐC]y啟úÔ§ž~úé­#…`ü¨Åb¹ì²Ëìv»¸b�ÑÖÕÕõÎw¾slllhhH¤¸Öçó!x@¨ …†(˜†Ú¸ÔC캸¸¸]à/°†”†Q( …Âív‹”C_½xbµX,¶X P(‚Á ŠJýêê*˲v»=•J!ß±T*:uŠeY4Ãiaa€í5 Àà†Ãáßýîw:.ƒÁ'Nœ>}zuu´>H^µZMQT¥R™™™q¹\áp,bxIDD eª×ëaýA¯4´pmñˆûûû!&äöïY­VTA.Q rHĹhY&¼‡Ô³ôŸ[PèU•JÕ²Ah‹†áÏÓþÒK/¡èÄ¡«G±XlY$Ã0LOOÏææf.—S©T`Erw‡¢¨¶jc¸0í;ôj#¹\‹Åb±šZF¦]«ÕNNNÀv4…83xçZ­–—Ù@~¹ßï_[[ÓjµH@;ŽR©”ÉdúúúVVV¸úI¯×–ñwN3Ó¤\—ËEÓt(BŸ:sÛk³Ùjµò …ÇãI$†·*šeY­V[,á¢ùýþõõõ®®®T*åñx QÆd2AÇ(LšH§Ó 0Â<öôô„B¡jµ*—Ë¡; }yoo/x<´pë)ŠÒëõ”GŸ5R*•v»]âà%½^ŸËå:›) Øâ…ÊY„$HÿÒÒ’Äßr¹\Íf3‹ñ²kWW׿ææVJN€H˜v¡ÂyŠ¢„ê¡EÊNŠD"RÊ7 ÊÔj5ï˜ @¼Ý‘æ¯3ª×ëf³YH3 9Où|>›Í.,,œ<y2™LB:„¦i¡vZ¨øçœ›Í&ž‰D" æ„`{zzxC+hZX,¸]‰jpõz=X£r¹œÛØ e>mm&ñC2™ ¥‚Ð>¬®®f³Y¤™ˆ�µB¡0›Í6› îÚòòr­V[^^.•JÑh4‘H@óÊÂÂÂêêêôôôÉ“'=º¶¶vèСR©¤T*WWW!/—ˉ&MÔ§Ü™Ãì•24a+LbÀÊjµ²,Ë] MÓZ­V¢f’½2²DöJg’”@#¹L&«T*-[hðXh£–¸° ‘y’ëëë5“J¥Òétz½žÈÕñïÞo~ó¡Ð§Þ’e(Êå2d}“Éd6›µÙlį@ÓüÛétî {}ÃR¥RYZZ ƒëëëpÓªÕªB¡¨Õj¼P„E M_l6›BµÐaÊ5¶xÅ+jÃâ½2“@—ÄO&“…Ãa¸Òx8žðöÚÚ<ÇFÈb¡;‹ì¿¥¥%|¤¬²­2™,N¯¬¬,--­¯¯ÏÌÌœ8qbssN˜P©Tð½µÙlà½âj•þòjí~ÛöJ0Š¢ð´ÓV~+ o}›ôCßvÚØØ@-Jù”ÝnÇ’|xú ÿ;y¥§ñrIgäõzyÏ�ey {ˆ¢ £Ñ¸Óôú†¢\.‡®1pK(éž©V«*• ”ÓéÄg )§f³‰ôÉd³.‰t…ÛÜÜ Rð±Ìf3á–ñÎ÷Ãe"§Ó)? –g0À!˜ ^³7‹ÁÂ`)<r"‘@4·Û (P‹J¥RÅb•àÖëõt: z+‹†y<î´Ü?m£“½Rli±X¸¥Fƒ7|Úr*•JËü:`ME£Ñ³?ÉÝ„w%Ãý³B¡N§‹OìõzK¥·âšÞ½{÷Ÿ‘K2™ oü$•Jù|>†ax#øÐ*þ³T*íd•ÞhT,‘(ìêêÚ³gP²§ÙlÆãñZ­7—ËáHzÃÃü’>ÅË`r¹œ;ùE E tÐÊý~?$\ñ›éñx YÍ5¹r¹œtIå2™,D£Ñ–€­ÅbT¾E a¸-¯\.›L¦¡¡!½^š–²Ù¬È5\]]-‹étž÷uÆF£­ñ-“jµºe—w±XÜzšG<'´†jµ Ðr ÉdRÜžÙ:º­9í~¿‹Cm ä4{“÷ñeCnvG^¿ÑÈáp@EWW×Þ½{…‚`EMLLôôô€x…©¦2™lÏž=4M¼Mµ»»›[DG('^sX¢SU­Vñö—z½ªÕ*èH·Û]¯×áç¸~[-÷årž4—Ë%“IÞ˜'þPH9á4;;Ë0ŒÙl†Ýs»ÝµZM«Õž>}zmmMhž4¯8®Õjétº^¯ A©žiêééi »G:A–Ä7 p;a½^/.ĤŒ`?ÓÊIŠ÷f4‡‡‡·2—ž‚S”0dÉn·Ëåòõõuü:ƒÁÐ�ËåjÙ(.ÒITÄ‹Ú>|¸³ÂÍz5W®ÏéÓ§¥û /ìííÕjµB¥±“““CCC«««Ä\Î'NÀÀYüÁ`°e9>ü”Ë®ÆívKð Ÿ*‹¨5‰ –[œm©&…B‘N§Óét¡P`YÖï÷ ¤óù|ð€p­`´A2™ìíí]YYåÁŒ¢]»vÁÍ,P~ÃÃÃËËË"B<§­Gè€ðPðÉçó …Î&b¯¬¬p—“�[ ðSÏZ a¯´¬ŽŽF£–8 `xðÁ–oBZ„XD$7‚är9ïèØ–ï@,Ëòr9± øþÑÑÑp8œJ¥&&&àÎ …_üâ/¿ür'ûÂ0Ä4F�W%~Zh…|$B;îçqù–Ýî†oñ¡„…B!ñçð °A°ªÕj©TJ$ÙlöðáÃ0¿¼jtÿ?Þ××Ç@kÎèèè©S§ ÚŠ^ÄLqêïï‡Ã K ¦Ý-‚Ñœ‡ƒ¢(q �éD˜Þp/D ;¡V˜÷ïÉd°?¡P·ù ¡]¯×Å¡AeŠ Ù.™ÍfFƒ\Àññq†aŽ=Ú®¡£P(úûûÅ—õŸÜ³0›Í¨�opppmmM<§�:Ü‚Ç/#äË×ÖÖ S›+?!€400 ¥aâ ^š¦†áÎ+€¼´ `}Õëuh†ë¬ü½}ÿáGßþ¾þßõ¡{þó3÷|ûÍo~sËŽ*‰€4,Ëâ€ëBÝ>£qUÞÀ¦Çã!B…ƒ�â¤(JB^.—K)×h4z½~ddzE!ŸÁ²,^ç#qÏyK¨=KÃÃÃB•?RÀ0 D}QËžÈ Ò4ÝV¹L mpddD«Õ¾ãïP(ƒƒƒ*•Êb±à¨êEíÝ»Wä,x·H.—Ÿ¡(Þœ.…ɆA¥njµ]O¹\.f'¸Hœ'ÑKhy0 wÛ‡††pV±Ûín·[bêKí@ªl˧¶—¶e DXÈjµâœ,`¬þN·k×.nªJ¥âMr#Œçt:!îóùÚ ë)•J¢„øaÿþýßÿé‹7ù¿ÞsÇ¿½éªÐW_}5wGÄË¡0—aüTPÓ¾Ùl¶eêO¤Ãÿ,øþ‹…÷aC¡‘¦Ëd2ñx¿TÍfSÜNT*•B8Š„Ý}ÁT*—ËŲìÊÊ ì'¾½CÑçóyé�"sssB”ï‹÷”¨T*¸f³6Jä¡]†a‹Å"QðnÂììl>Ÿ_ZZ‚ %Máãf³9==Ͳ¬Ð0Þ-ª×ëËËË[ÀKƒI|´E,Ëj�õj4$k ÆŽ6\œÁôz=ñ\v\“Á·Fø”Óé1¯âÇ4??³ Ìޕ؉È{qxÇ÷b[tH؎׀·‚ñâŠÇã É ‡Ã„àÍår333\G°T*ñ"lÁÜ)\ë ½�cäär94esgK¶$£Ñˆ³ à4ò1¼‘YqG¢„rBш‰„”y¬mÕ2 Ó-Ú­HȆB!‘¸ªÕjÅŠÛ,—ËEæ "§ƒ[«Õj8ûr¹l±XÞö¶·]z饨 ,ãí“B‘¢Î +^AÜ"YZZ¢(JÜDÊåræÝØØh9nùF£ÑjµJ¦Â;+V¾¸¸ 9Q±Xä} 5Àr³V•JEbÈîÁ¬eÄE�J„=p.R(wÁø0ŒZ[[CÁÆ|>/!Çã\d&b“‹E`×h4 ËCM¸\å„s2D!e·Û¹kápÂu&lÙvÁ‘©ÞÁ¸Râ²ÃT§Ž×�_øjðüpéŠqèÄ—@/@NPhf‚à‹`•r¹Ì[­Óy++àẺ³LI[À€Ä¸ÌvY³ŠD°ƒÐ'ÿÞŒ/©­õãË�älµZ ±l6+$kˆˆbg¿..2Zš½õz]Hôo…‹–——¯­`¬Ùl¶X,F£í�t;µ»�Ä p<‚ÙlÖétBl *Sœ÷àù|žH°wÐa*Ä'y'‡Ã¯<—Ëá˃>J§;}ëËÛªÙIoq‘Ñht+Hƒ§R©lW~q[ÒH¸Îà]^­VC67ÞG¸\¯£Ý+¶¥9 :NJÜC¨Ó–«Kxý�¥R‰î@2™”ÞÒ$4m·\.‹¸tõz>U­V!).¯Á¤5"ñIÙ+í“›››8ÄK&“©V«F#ŸÏ///¿üòËB&BO-±´d»? DRÚVÄY „D?7m '[«ÕÌfs±X”hiµZB\öôôÔj5¨Yƒ8Õj5˜| Ž 1Â2C Ã0^¯·X,rí›Z­–Ífûûû·Et¹\J¥çÔ„+N0 —ûw(Ó¬°“"õ,€ÑÅËBíÎ'ÛR·ÖY9;´Ä7‹=x ?)³ÙÜÁ¦vI¯×‹ø‹ÐÞ®ºµZ­H ár�*/ˆžq$xm6›¤¶DÛ¦i.[”Ëe(1‚q™BO§Ó8÷F–e¹Ç,\ Wþív»3™ oÈÈãñ¤R)¼ú¶3»}J$[ÖÕÕ‰Dpöjù[Ùl–«)aãÒÒ€[sÅ.ã¶—SY–u¹\hÜ+'~?¹‘ñT*500 ÞQ T*u:\.G¬BÓtoo¯8БìO¿p¹ b±Z­rw¦Åb1â˜*• !…· ßF£!Ä6"/ÁÆÆãq¡#0J¥R\žƒá|R*•¶2å q#Á*°ÃÐ/RK ]MÜ¿·Üsî1 R©T6›MºcÚ’ÃÅ…÷%ü¤ŠÅâv=²ÅbÑh4¼Ï¥R©T*àSpoqgkÀç ã'‹ä0¯{ ±]ñaQQ6›åÕ=€–L&…2<ÑhÌårð�*•Êï÷çóùT*åõz c¾ ýçàà ˜õz¬NÑn·[¥RVN±X¬¥x•ËåCCC[ç€H$R­Vñ5”Ëeñ_çTÎd2Ùl6ŸÏ&da9{ &y£*µ|>ßÓÓeZ"[øß܈BÆV«a.’.ã¬Òl6¥DáÄÇðºM¨ ŽIˆÁd°A‰Äå=\×Þï÷ƒñØh4D<3˜Ž–×ßß{ù|¾¥LtBÊóÚLF£‘èüÇ/;ïÚˆðÎââ"Ñ—#Z>à“¿\zI*Úœ¶j Ä[˜y<BÖ;ðŒ¹/•J%‡Ã199‰²ÚP¾<�� �IDATz¦³9ÙlV蹒ɤÕj½ì²ËÎ?ÿ|nÌ `Ž;0åѧ¸·IÉ^b´ƒÒLÍfY µZMä»x­WtÂW\.—×ÖÖàÛ666Ð5V(Ü ¿´´„¾6“ÉÀXÜjµ àIËËËD”¿R©´ì°«×ë-MuD"¸™åröG:H.tp·ŽX3Ž [422)GîÇÑ_:˜üf/®VVVà(ÃáðÞ½{ÑÝòåHš$“IÞ^™z½^©TpVi6›HtÂæøý~Þ‚‹®®.“É«õ.°k¹\æƒèqÆÆÆ:K`´5ú`&''ÛÂS^YYZ})~y™MäUt›Ð_víÚuúôiNç÷ûyY…°J¥ÒøøxK·Œw0TB"ÇBo@Ë­Ëçó8'KaîC‰¯aë@ï±XLćÃ'OžÄkµUù…¶¨Z­Šøß‡Ð·+WÝq%¡l&?{ 3 ³õ¾ßF£›WÐi({%)JtDsÅñA·Û !DƒÁÐl6E¦Bƒ§äâqqÿˆãfòn˲ÜeÃ|bîzzzvïÞÍ ¸{½^<Y…#ÈÕëõf³9;;;44¤P(¸ ˲xÃÃ0ƒ9è8ðŸãkzz˜úý~!%?G´'-oEQ°!v»Ýn·///ƒoA|p}}=•JĪH”R"OºÝnˆ¼Ÿ<yRÜšâ¢Ã‡K¿°«Ç‰™pŸ’Ëå é) qœïf³i±X<\C–e?³¡0O ÍÏÏ‹G@âpó.µZM£ÑðjA^MV*•Ä'¼@u~”â¬Ò.ÁÚâ1!añB|‚ÏHÍår-GC1 ƒtŒ”!8ñx|vvöå—_ž››ÛÆ6ÿv©««‹(Û‚Íäß©ÙÙYéšI©Tr›œ …Hæê¬p‚·aˆHš…B!†a4M½^×jµ"A–e‰èF£Ù½½½ d†‘hÏÎÎú|>.z´×ë&V*•¸ÎXYY9|ø0ר "©& ™™Þ-‚cªT*óóóèN§“Ð%¨7¶3ZZZâUÒ*•ª««Kä›»»»y 4t*• ¦‘£F@rí¢Ð*ô[\q¬Ñh„:Ø …,L§Ó‰$f¹\$"ˆ¹ü52°r÷On M px%¸8'Ãoµœ{£¬!¶#tL¼wPöJßzOO‡PWo±XÜØØp8ÜFàB¡ =€!Dh¤Sg^2lŽÈ1‰±{v»½³Úq¼‘Õjiíà/°¶¶ …–——%vz ¿ #kkkc¤´Äâ¶I2 [c0Ün7aV¨Õj‘&�.:$ï¸ýÌÁ`0 ‹Å"bY”ËeheÅòÿoïKc$»®ó^-¯^íûÖµuwUïÝÓCÒä MŠ Ù–! Š'm@$h;°^�;‘!ÈH~Žü#€!G¶€Ø¤�)€(VhhËv(H¢-.3ä,==SÓÝÓÝÕU]]U]û^/?>ÏÍõ}K½ªîYd¼ócÐS¯ê½ûÎ=÷œsÏ=ß9*+ N§Æd\Ç#ÛÝÝÝív»H}©Õj*ÈÊD‡‡‡È¸5 Ø“Ùl6¥³+AÔF‡CÉaôx<…BA%äÎ;²[¿ß‡“tÁ ‚@3ŠžAžç™E.5ðÁ`P Ûëõz!c‘HD (†j´9N¥ü+ŸÏǬÞ`0xùòå^xäË¡­ó²GE%I–õØdù@OÓ`0Ђ¼) `šÒ4¹Ýn‚ÀåyžŒÜçóY,–Û·ocÉ0ÓDS½^Ïår Øh4Òßw8Ó)>¿ß>Hû9DE}šÈ\H%™Ñ`GGG/'Š×ï÷Ke…BA%ÅM#‘~F…ãt:P©”s0N‹Eª¡Ìf3F\,···¥GÍc«êÊzC@  Bw0{#—Ëe³Ù···ïܹÃó<ã1AëÉÈïïï{½^©ëÍÀ'»Ý®ÆÎô‡ X•¦NéPV‚GS!7ŸÍ¥rFŠá¹Ýn¥ý¢Õj …B²ê£P(0N±Õje¬ ì\ÄëP(¤$÷­V‹>‡ßßß'»yÔ• uÁÝ»wM&Š}ïÞ=¥|‡|>½E6›UÒk‘H„Ñ5v»]Ö¿q»Ý¥R‰1ÒP <σA´ƒC²"ã ¨�¤ddµZ÷÷÷IL†¬A«Õ:pI€ê[lqÐshXz±3Ó$wÌÔCÈo !G)÷­!*Z¦Én·KQgÜ ò<Å{xx¨±© ÙW„m®ì—e—§l<pºÔ¡‡aœjµšTe£s³ö'iÙz †jµÚl6ѽ”‘ZéI­,�Öš8rœ‰Dd·ÿ î¬ÝnK“¶M&“Tìr¹ÜÞÞú§ÙívPBÅÒ<«Ñhtxx¨ÆŒM; …~¿/ŠâØí3 QË&k¹DÍl% Îx-Ì7ñŽ‚ (!W&Mš¢§I:*š¥~¿¢ÌÙ=(ý_<ÀLS4E‹OˆÊééé‡~xpp€Ê˜¢(`ϤƒJ;}Y›!¦v» °T*MQÂ\EºÀééi0L¥R³³³‰Db¢<c³Ù¬„χtÙ”“““³ç<h’­UÏLS§ÓÑ‚÷…BX2ÐE6›M{D—ËårƒÒjâyƆLk>Ÿ £ÑH¥Ýó¤¬xpT§ÓÉøë¯Ù¹’Ò}ÛšÍf½^?==õù|‰D¢X,Ò¨ÆZ­æt:‰ÛÕï÷ ö"‘H,,,�êqïÞ=´Æ¡sœÐ^º€Ëå2ðÒöq„è¼2æsÔ¢&}NµP:N¥Rê@`ª Ÿ2 goÝV­Veg�Ør¹¬t¼ tÉ´ìt:ŒƒU1”ªË7›MiðV:Ù}!aš°ú~S»Ì¿‰iêt:¢(QAþØÍ›7wvvúý¾’t¥R))g”€>Õj•)JvF:==UÊìBîk§ÓiµZ­V«ÙlN”bÏçé;Óg- NY‰"‘ÈÃ&Aá8N%wJišh„©ÒQP(J&“0NXqÈbh„XM^¯—Aý#ÿ°Ýn3»œÑh¤„#Bîv»Õë9…Ãa(ÞçIHû×Çn5JÒX’2% ›Í&ën 58K'Ôëuº=ÑË‘Hdeeå©§žZ__'åý»Ý.Îýâñ8²*Ée0qRii  Ãp8¾J{qP($ë},,,(y²LõîP(D7ÛTÆív«�%jµZDe+ˆ×jµÁ`@DÜårÉúËý~¿V«ùý~i„~¿OÛ`­”Æ0år¹é*>í2iVWW-Qš&H‘’¸*IW¹\–F¿ëõº’¯ãr¹G¥‡'Œ¥q?Éd’˜4銆$Ó«‰ŒTÑ•–¨ˆ+w¿y.½A'¶ªX,ŽÍ�"ҥćx<®¥£–Õ$w¯×«eE+Mý²4¡½V6›…<cÙöz½I¥«©Ýn3ë.r<´¥ÑRû¿Ó騧HIž®…•:A\¥c0ýö¿ÿßü?—H/7Z;×Þ»uåàà`ii 0fôÇ”ž— ‚0??/(P®Ët:¥¬ü~¿ …NNNÏ»T²�Úí¶Ëåzúé§WWWQÒÛh4îììÀ{õù|Hÿ?99aj± ƒn·;33c4ëõº(Šý—h4šÉdZ­V$ ‡ÃS”Æ*—Ë»I-í8 ò义4 étZýxo0t:a™µµ5ì?p¨CvBÌP,Ã#Û»ápèt:3™ ƒ£t»ÝóóóGGGRàSä"Á,¹áp877˜ÔDŽØØW&/«´×·ÙlÑhôää¤^¯co„Í÷‚’ÛíöD"Áè_%隟Ÿ¯T*ÚѬP|ø>¶ì²¾ÿüü<"Š4Wñ+¬Ôôûý¢(ÂD¢3’ëœN'¤K,©„¯W¤ç¢Ûí*q½‰VQšÁX,6 jµÚt(`éÈ“É$Ñ�(äÑëõ¦Òa¯®®ÒBÒëõšÍ¦lÅ“)ˆéÌIÆf·Óé,,,<óÌ3±X ít:q]\\¤»Kû<M±š¦Þª¦Óiˆë‹/¾è‹/îëÝv³z|È'±]Þßß'5å( èÂ… ¹\®Z­z½Þ`0Hv‘ëëëÅb‹Íï÷ûý~õÔ¬1Ò ÓÒ` ­­V+~Úíö_ÿõ_C‰` ü- T´Ã¦J]ëc„õÖjµŠÅ"š(Çãq=‡ÃdIûÉd¤*L ¨Däw0˜Íæååe<¨Ýn#Û¢Ûí2|h4ôƒ”´›Ñh¼|ù2BÕ£Ñ'KKKFs*{ÔT.—q7„tÈ1»ÝžJ¥Pè¡Ýn/,,ÐæDÅf³Y,Ûí6=§½^¯R© ‡C"ßëëëäAÌ„Ò&-Â:‰¦ï =Ž'WVVTªÅpçp8.^¼(-HÇUÂw˜)¬a²8ñÇéé©’ŠQ¿*Ýo ‡C%QQY24¯˜yÄ�h™¡… ¿»^¯§R)²@e©v»Mæ¾ ó”Á`€é@Ÿ3Ú£²‘ú‹x½ÞP(Ä Ðôd,ëšÍf³Ù”~Måè”™V©É§íåyuË­T*4˜æ¥çBssspß±š0¹P¿O<ñ„Ïçk4‹åý÷ßGTƒøšðHd/½j°ØÏe¨xvuõz=N‡Ã••ìסHǧþáÿf³Yuù¨V«`SR¯X,‚AЭRËd0,‹tîeXË ÔóÏf³;;;ËËËänÈ'†·+óhžç•*Éx ¤Šx‚äEQœ™™OM&S·Û•®4©º¡Ç€óóÑhÈvôƒªÕªìØ0�Vb”(ŠÅbqnn®h,3›Ít³WF^¥lE‘ð#ï÷ûV|­\.Kí:.¥Óév»M׃ ¿Q¾ •»ðe¸äF£‘çùz½Þh4àóª÷V7 O?ý4'WFËÁ’(ŠØÅÒ–Jƒçy>N—ËetRÖrs©¨ GK]EÒ‚‰D\.íIˆ¢h4q\¯4 Hr¹\ änâ}’=üóù|ô¢Æ²µX,‚ ÐR¤eå2ªCafV®JË1fš4’Ê€i=0õmQ™þAì<šÍ&vÒäYf³9‹ÍÌÌ�{çõzONNšÍ¦tŽÖ××kµŽ'd ºe"L‹–†OìB¥RùÈG>‹ÅžþùD"aµZƒÁ'?ùI“+BŒ“Ú™“Ò±Þìì¬Ñhœ"æ+[Óšã8%|"³å—Mar8£ÑèÛßþöw¾ó+W®t»]únÇÇÇÄP¥R)ƱŠÅbJ� ÔÍu8R_ i»n·›l_‡ÆzÒÉd’dÈ"Á»»»�ÁhÙ“ÃÖT¼<½ÎårŒ¨Õëu¦Ï=ãÈ2'|PI‘•“l6+Íæ˜ÍGªÔ“<i̬Ïç#R´¿¿Ïø²0jÔ0œZ ÙÀ)ƒp:ý~{{[¥®¶ŠD"étZQôùbËtB@:F)I‚WYÑÌ'RXq¥Ra¶ž˜Žz½Nׄu8Sä€% •_iLù©T*çžñ‡Ï˜”a4ƒÁàyõ]#‚!—îøþþ~½^G©L¦�M[[[‹‹‹SgTmÅ@{êhªÉó<zò!MñÒ¥K ËËËO?ýôåË—P+üª´À¶··Õ›ì©¸K´»\.í›Í& ®F¡00Zý :š›»»»D_3¹àõz=�¥ÐTUŸ™™Aƒ;ÇÓétduÏó4Ùãñììì ‘Ûí>==%Y4ÈéË—ËE2ïÝ»§’ËÈžÉdšG€~<χB!§Ó‰“p¿ß¯‚ëÔ¾ð\.•,æLl6$¿"NC>ŸWÒ³¨WÂ8°×®]ÛÞÞž¨­¥F™¤‡AøP¯×™&“R»«âXܸqƒvŒ¤Xéíím€½ðߣ£#l(i¾qã<3„ß¡%•V´¬Ë:=ôÈ!ÉäZܪ˜¬2³ÙÌÌE6›‡J >¤ÃSrȦΒP¢ÃÃCø (u?š•çy•˜Ór2<z/…æÃÃÃR©„"X²=ó|>ß`0øðÃ5²WJ²é<c— JØx½Þ½½=tÝìv»ð)ekTÙ“ªà®ûý¾lUv¨.²Ñ^°Z­Òùƒa쳤•¢Ñ¨’ø2¥bAÀ¤2j—ËU¯×[­Ö­[·´%­¹ûxòP(D*»Ð+­ áZª¸c*{i®¶,ùý~DºPæ@û4íîîb¿~3$Ö$åMJÙB¡£§YÀ«EÄP±X$M‚ Ü»wa,4¯Éd ƒ8ô’ ,œc6qŒèpœzaº™™²½†K;Vzéí Ô˜1}TŽŽ”œ•\.0Öîî.ÏóZš<åóyÙ$I‹Å°óÌÌ °z„«‚ ˜ÍfuQq8¨) œ;ÝÆ<À)¾Â"ÔívÏh™°¢WS£Ñ`„œ¬h@£ªÕê;ï¼S, …Âîî®,cÏÝk\2·oßF‚l6{ëÖ­­­­wÞyç?øA>Ÿg2ì&Þ€Çb1„Pe³“'"³àa²f4Ñ‚‚Þ'ÄE¢¿ ð©ÔñgÌ©[­V¹\öz½ÌÞ®ÓéОE¡P @¶«¤ùÙl6¥ a»ÝfæI ÆÈ,H›H§ÉívK·ŒL³Èd2I£ÓANJGGG333ôð4F]ºÝîh_)…§”âñxœ°ýôôtlq³\.Gd[ft»]xÄgìðŽŽŽÎ土éÓï÷Éî¿\.=ïGË ¯Ãá0ÏóZ0ãŠb±X.—SZMgÜ|O‚R_ѵZ áÍl6‹ βÖQ–ÛH×<wÊ® ƒÁðÁܺukww÷Ö­[ï¿ÿ>ã[LlœpK=ÇÉK&“*ØXQ±*Tàr¨Ø-;<·ÛH"ÜÜÜœ–‘÷û}(~¯×æIËi¿Ýn‡uGôŒá°Æ6�ó2jÔn·“DGžçeÅ‚~Ù~¿¯Q„ê§“” G<ÏKãÚÅbª™iš®’&3À×NNNF£þ˜ènF£qaa†E£Q©µSa‘tu( ;›ÍŽƒ¬ÔXº[c’=îFŸrKk«‡dÉ –J¥££#Q-ˤᎎ>hÇ9<ŠÇã$ÝЂs¼¹×jµGyXMZV4¡½½½ÃÃɲ9ÔçB½F°’YB{C饓““ÝÝÝ+W®´Z­n·+Olœ&‹¤Ï*årYEÝ ´�QËu:¥Kív Ù Ù§¤R)ìâyžÇÂît:ív;‹Áœ †µµ5b>Ábí‘h܇[Œ®ÑˆË+•JÌÈI5O"úc3AÛí¶¬ŸáõzÑÅœ,Y02yP¡PPáöz=äôc©c)Šâí}™10IÀŒ·«R³™vqhãBâT0Ÿ*,bÎÛT Šc'ÂívÏÍÍѦ±\.g2™±<Áð’ÉäÚÚšJ…tãX«Õ´—'®&m“‰‰ZzÖjµóÊÞ~„ePñ½^ï|õžôˆÔ`0 ÏªìnXËŠÖBóóó²¢X½ŠÂQ2]™LFö¬•uq|||ýúu>1—äA¸ßÐëõJÁLV«uvvöì„3È,žT*5??G³Ù´Z­ÑhU5¥qÀS”t½z½@ZÌštðÒH ½è,]Z—/_VQÐ�šT*5Ö7çy^ ü”þ„ÆAùªÜÖétJSÉé›—ËåF£¡ÅóE±Û툂{ív{ee,\Å\ÐÜ;Ǧ;d?J�°ôƒÔÃ}4‹hHÜh4Rº£×? *• Ý&µÛíª€1§§§x›Í–L&Ç'BVÊ®¦F£!k¶ –N#-//«#Õ!ü2äœ0avv–ì{ˆÒC™íéì ŠðS‘ .«XÔWôD0-(ã@ ljié÷ûR=©~Cš{*†t±8§¯}ý¿‡gWUŒŽ=EQ$€/zaK}üÁ`P­V}>ßX®ì~ˆÆ… † .Ð1®z½îv»aÞÑž«V«¡ü×Ôó´¼¼\¯×&ʹÚAºLÊ}2h]ÇM&½ŒFô²ÑhÔëu“ÉÄ܇öDPF}šiîÑwÃçÌq R3Ün·Ô8á·X‡ÚcF£0Cä q `L¦ÿäD$})ò²ø²GÐi¢(®®®¢°ÐØ’Þ,ŽÕ°ÓUæ•�ÆO†ŠK(Ü Ä1š XD,'* ðÜsÏáø }´'d+ñgÒüëGn‡ ÃÆÆQ8èͦʦK©ÁÓ®‹È*ÃŒÓE y†¬­­1¨^%YÒFVá6 i‡ÇC 2�§˜qéZcÂÑhôâÅ‹´q2þüÏÿüØh¢Ÿ¹\ŽÙ€¹Ò¦¿h®ñx¡3´%öûýtœD¦Ããh4ºuëL­lã8³Ù¬”E.¡o¦Ê¬[­VÙ®ÉV«UºÁ<ê'Áà]¸pÁáplllD£Ñƒƒ¥­äþþ>ÐÝKKK8I\3úBv„túP$!Qµ òâ'F£Qún‚  ç³Ï>K§9˜ÍæõõõIW5Ïó$�E¦ãÜáååe²êü~?ÉPÊd2€x3½y󦊇¸¼¼Ì|Bºñj!ŸÏ·±±q–í……¥ þââ"äAåäÉét*U‰žˆùßûÞ÷ˆ‘NHÃâGӉʹç›u@þ‹ll•1K{y«è"uÙë´Ý¸qCE’F#9ô …BÁìÐ…¨‹­­-lÎ�NÖ«Ìe!Ûˆ'2˜KŽãŒ¿ù›¿©>ôjµ 3£Ô½é¬3)a?k±X"‘H©TÂÉ`ƒtñJµ(Ë´ºñx<J0[¯×K¢ºêÉNè÷*ÍNL&“Ø(1ŸØh4®^½ª1‘ôæÍ›Øcq÷ÇNgìÖ›fQ¯×#®Ž;==Íår ·Óéd³Y›ÍÇñún·nx»ÝžhÙ»\®~¿?¶«´ôWê F kÛßß'/U*•*• <†ííí«W¯šL¦Iç§h‚N»\._½z•Ö_ˆ0k¿Û­[·”\έ­­Ñh„iRbÑp8”…°¨¨°):±ò<O%ÊöµáìY^Úhv»Ýl6/,,Lø%Ü{$¹ÔôzW•I‡7€råþiå±;E4œ››“ d•žºt)¹JÃáP¶s&£®Ù*‰”Ô”îœ@ê ÇÒíÛ·ý~§Ó¡—™Çã1›ÍR}çr¹˜ ‚ ;Ç€"—J%¥³¸““¢¬Õë;ܾ}»ÝnKµÀ;w\.×îî.½ÓÇÍA ÕÏç3R9ðz½F£q8¢;™Õju8ZúfÒ,¢1q@5r 0Ã"º×b(2›ÍÃápooO#𛣒P5Cû¼Ó<·Ùlh’F# x ô¯í— u¤Ñ¹ßïW‰™ `ŒtƒÅèPÊÊÉáµÇ¦EÉ>k¬úÐrbÞ·×ëÁ«Å4¹ÝnéYºÝnŸ¢’‚Ýn·Z­XìƒAû¢òÁL·å†1(¦6`^¯W}ÕçêëåÖb±Hõ�ÆÐh4nÞ¼)µg²JOÝ@f³Yu…#;ô¸’¹¤ô$í¢æv»'’K»ÝÎŒCúsT°–e1³Î†l®]»Ý&é•h,­2¤±mžyž'+‡4ù†±Z­v»cˆD"È€FXÏf³™¬d4z‘…ò ‚`4gff èkµÚ¤¥é±È·(3¡Bš:Îõë׿óï`o—ÍfaY{½žvØàòò20Šj0Ís èÁ² ”Žaww—f]¹\~ :Ñ»VéêÞÞžJø86éäJʼny3MÀk«“°ÈåriÜÉu”pÙøÀ'À°¥¥åáŠMá¡Ò+ú1J;²‘ÌX,†µápXË™N0L$±X ÇÀƒU<¤sAoº.½˜tÙ±ùý~(õ]o§ÓÑÞQŒ™/Y«&{01éÎ[£áWR8²*]äm6›?cVÊýЈ›è|S:(‘HhÏœ"ùX:BTBRx½ÞápÈìZèƒkòG.—|rrr²×D³ó\.‡üøH$Û‰]#þ–¬Ãáðé驯¬6éD MN)Á½ÝnïííM ª8ûM§Ó×®]#òù|ý~_zrƒ†fÅbQºÿ†Ñ’>ópšJÑTÑVG È ³TËHyÎLÓDxAíç*?Wº„ã*¦Ii»I›@³|‹GfF;R©Ô`0Иz€žÈÈ&ÀäÒÍa¥&D„D"Ñh4¦@mz<TIf Ó%cµZÏRæqj…ŒVJ:Ùn·£kÆÙÇI†d|GÙ1 ‡ÃÝÝ]ÙÍ–ñµ×^›b4¬^¯+õQ¥å¨äËÒ, ]6ÇCâ6S�¾”ˆÑïHߤ¿@ΜG$aZÎÌÏϺèñxü~?S,œ.=pzzŠÖÈtü‡“€Ñ ‡C£Ñ˜L&Ûí¶Ûíƒn·›Ø³|>ϘÌv»H$»ö¾*®# ¨J.U d'×ëõ h 0¦Iã:akk‹±CLr6Ë’…¸ÊzXgoï;5`'Ëa•”¤T*e6›'Ò³Œ‚BÄTÚ 2Á¨iìÚµ? \@˜UN)ƒA¹\&’¬ä-I{»È’,‹fgg5.7ÎL �� �IDATöf³™Ïç‹Å¢ÛíVÏ_%Ü«T*ÇÇÇ¥R)—ËåóyfÛ×ëõü~?¶žƒa~~Þår=÷ÜsÏ=÷Üææ¦ì.Ú•¶³½^O¶DHš>v¾$Ûbì~ºÓé¨ôÙ “ÆéóoÌ…Åb!'RLå=pkûv(µ"M%_^^–ݦlnn–Ëåt:-Û1Þ|¸\.´«!°€>§AbüD#,ßãñ lª…e&“)“É ÷ ý9y`Œ"¹Å£ÑÊ<ŽçùÕÕU«Õ ÃÇ™îyn·­¸i`¶ø&"ä’ÕjÇã$BÒëõ 4}çÙÙYꀶLN'3«½0È4rØÏX,¶··G{'ý~Ÿn5´¸¸Hš~–ËeÒC–æçç[­ÖÂÂB>Ÿ?<Ç9’zJg¿ß‡V÷ûý´¸¢JÅÉɉ´M5î©ã …BDÑIðZˆ™÷±þ8=³²Ð’.ë¿Ó#w»ÝcW4š‘“¾‹*3‚?Tö»¸JøÐï÷-ËÚÚšÓé, ²ÝX°re_“¨$*xV2™¤ý )©k¡‚~¿pŽÊ0` Á`½„¡¬°¨•Á9ßxã ¥#‹Å"EzoooãäY}OÂÌôRY__—ušh)¤W#ÝŸ'O>ù¤ôÈ´^¯k)Z³¸¸ˆž1tYtBsssØÝK7UÜýŠýHÈÞÙÙ¡7 îܹÓét°¤32é}ÛéééÜÜœÓé\[[»páø�Ie Œ´&,©Å0<—ËMZ™°P(”ËeÜßjµ’äNz @k¹’ ‘ OOáC$ôz=•ä$ˆÔï÷wvvTÆàt:766ξžWWWÏˇ…“®%¶&-Ù‰ãI4�TY²›­™™:RM¶ÊO°¢½^/Ä•¤ƒƵµ5¥_u ®âÏHtó@é)²ìt·Z-uý®@§Å¥wïÞ½ÃÃÃãããX,F"N¤÷³-0™L4žd¬K···§äS.//ËÎ`&“aÎ B¡sš" s¢HY¶ÒãùÙÙY—Ë%]M'''˜‚½½=c¢Á´zÕÇ'åÿ¹_ûÜûë_ü½ÿñïïŸ}öYúªÒy£ °[ápxlº!9œš;^¯7•JÑHR£Ñ8‘†R:®º\.:?“É<õÔS—.]^5“ÉÐ71™Lèo0B¡ÐÜÜ\2™D:ÃÚÚšÅbùØÇ>¶´´D^Ü`0,//k9èÆŒF#úÁóüÊÊ þŽÅbá|>]‹æáDÚYIñ †'žx‚ü­þ‚sss.—ëòåËg1 „Esssê] VWWU†}^«—Ü "¡‘5V¹Ø6™Lò,ƒÁ€W#¢B¿~B‹+=AÒwײ@---чÞ@@)‰Ÿc%å@{t0SIuÌÏÏ+åa§Óé³hjš¥h¦§…KÌç&“iee…Χ²HVT4Þ_ºÐ˜/$ &ðèv»I¨Üd2 ÿÒ G‹ð3ÀÚTÊ‚&š|cccss“|þùÏþµ¿øþ/}ñ›?û¾|ùã¯pßýþß«§)V©t½-,,ÐI$ÎÎRqÏÝM1›Íp‹èü:«Õ*ëQ ‚°²²b6›ív»ßïßÜÜL¥RÉdR6F½œ\“¥Fs/‰H§V¶u‚,µ‚F£1(!ÉdY¤ä\ 힣FRï*¢Â¢Ç”„‰jJû¦¥ˆÏçPzvv–h^«ÕгÒp8,åƒÛí¦=”kS_¹´hIÓb§Ó~¿_Öy%–L&UàMét£z@`©$G£Q-™÷Rp™&•ýètjê\hvvvssS{ÛÏ)tr(ÚÜÜTʉÅb²>%cœL•ÓjÏäš®¶ž¬NI&“Ìés¼^o­V›™™éõzƒÁÀívËF Ãììl­Vs:çR°Ûí$¨FºHà)—Ëh²çr¹pì”L&wvvF£0qdo‹ÅÐïüÒ¥Kf³ùÚµkpFP_މ6„B!ŸÏ×l6gffZ­–Ãá ï‚wǃ˜¯Éd"¥á×B“›Á`€Ý›Õj ƒ8‘ÂÈ].—,gR©”z$Ç+%’‚Eý~ŸnáLâQ‹…çyzcÎÄaìv;©Ë2Y­Öd2©Ýn6›cÏxƪ—ËÅœÓ8Ήê6©S,“ͤˆD"ˆ¼ËÝH$R­VérŽ×jµJ~2 ˆ¨Hù€âlôTŸžçgffÈag$Á ÒÚ¤&«ÕʼÏóËËËÇÇÇív’La²Çãi4êÅgIY#‹Å"­ ô7³6ÏH´$+U”Z‘ÍÍÍf³i2™0 2M“viÁÑí¶Ï‘ªÕj¡P˜ny †T*5¶tj«Õ* „{ŒI«]ƒØ3§¯|å+Ì7€‰S9ûA"@ŒT= Ž`Q)¹'¢(Þ¹sÇb±LŠà&Jãñ8í›L&- )Ëf³Ùà‡ÂBìïïã0çI�'šÍæ`0Èó|$× $]>Ÿ¯×ë‚ ìííõz½@ @¸‡2‡‡‡àÃp8¤a¤N§Ób±�Ÿk4½^ïéé)9Âq»Ý&“‰p†#ß½{Wýtº×ëÉ¿Ñ,¢ñ‰´onµZÕ½'Œü,sÔn·Ç6èd@¸Ó­4©h±Ä OÚ?×l6Ó^áþþ¾Ýn—îB” í¸tóæM¨lY¤­ßï—ëJѾڹ×ï÷i˜Q.—à ÁØ¥g±X¤6”‚dÔ.­Uêõ:“a¯¾ –WŒmºµS°H‰†ÃáÕ«Wgff¤±Í‰vöÈU&3X¯×µç²k‡0;N-{P%Œ0š¿H?W§ãV“®&ù€štn+–&¯g6›':<°Z­f³™A˜2à;¯×KËD«ÕÒ‚ÎÓBx#AßËå2í¸‘ºv»Ýápà„9öz=xñ°@V«�@(ønµZ-›Íât f4Ýn·Çã)•JF#‹ñ<¿··§Qq‹E«ÕŠ…€OZ­V¨*¯×[©TtŸ»_Kú²g¡J¥B¼oZ IÑ@ 8>>‹A1 G‘*ŸÏ7Qæ4ÊY1:”Vy�ær9â½J¹ªeU3?9K<J;)}OÂÅÊ…Wµèv»¥06›Íëõj\¹ðpé%ÃÝ/&B–Œ>9I�ÆçóÁEóx<*ÉñSpéÞ½{¢(JñÚ€Ÿ]]hWn½^owwWºŸ˜è¥, pÑh…F' kùÏóZ<Tª´Z­©TJËÞÀb±¨t"…šRZMD\ǧb±ˆ:çJ¥¸EQ$;z½®’VO�´á›oz–ÂÕc}HÂqiZ9:íííµZ-´¿D-vì÷«Õ*ÂeÑhÔd2¥Óéd2IZÍÏÏ[,R:6Þçó­­­¹Ýîáplj„öÛd21Å©h^ ‚‡±“£Yd6›Ñ¶R©ø|>4Âàyþ|Ë<ÓëŸ<†§ñn‰DåšÆzyJ ÓDgd™ÍfõÚz¢("š¤]ð:Τ¥:ˆ¨’bk&µOÌ'GGG0Z°îdØtrx Ø©ô5G£QµZ%[7•"–¸¤EÙl•ZjÌî!Næ©|;c/s¥U£…”ª†V«Uíe™:Ž4 =ÑK‘‰{­V«ö­“ÇzœZ‚áèÐ&Š"}jÇ• ›ì‡ìj‚þ”] FuÏ¿Nßït:̈™P¸,Åásãð‰‹…¬7œ!ÑoÔjµö÷÷ÅbØ¥á†n·{}}Ýçóa h®Eó! F£Q³Ù¼··‡.,‹% Åf³ÙšÍ¦ßïÇbÇÓÕëõ,K³ÙT±å£Ñˆ¹J:ôp÷k#‚{4‹P|Öét†Ãa0X¢b±Èó¼–â¹ÚIÒ|V¡R©“§áp¨½q VÝX �0gR1“1ÐÜSÏæy>N_¼xQ QX¯×µœ1<LÂäÊ•0¼ÙlâÒ ªßïã8JvÙJ× ŠLBø™&{8EEQဴ=P*•νXŽ,axÚ¡Üív{0È5ö=R"z 8kWù2éÝ…íA§Ó™4¤|îdµZ»Ý.1±êÝÝTØ ]ív»4œS¯×A¸› F"žçe—.ö²æD#.OekÉ`¾âñ86òê­©ÑÈÃï÷£aƒ‰FGî>à÷.Ìáp˜L&X¬^¯Ç �ES�e]__¿~ýºßï÷z½P—¹\˜§@ àñxÚí¶ÇãAÒ`RûûûêëYÅ*‡ÃF£áv»3™L¿ßG% `ŠQî¬×ëy<t™ëv»ËËËØGz -..2=Z´{g½^IRu†h¼ÕXÀ?d†üüwvvïˆZMJ·²Ûíét:8Žr¹Œ/[,–T*5u §M๬Û'½¤JUw"I`“Ák úÁ´Z­ÄšÍæt: Ÿ¬^¯—ËåG©ÖØÀ _{ŽÄ³tÅ$c*"BápØb±VddTtSîlHÛ©}£Z­Öl6¡xéUO‹ÊÜÜœRQ š í++{>Ÿï“Ÿü¤ÅûÿÍ•Œ“Á`xöÙg‰¡ÂÎ@VôÛíöÔ«byy¹V«©=à!ÒÏJ¥Rc;z‰¢ˆ´ t¼U¹?ÉËZYY9>>v¹\™L%ÒQ—Ùúív{iiéøø†yÊd2³³³Á`ÐápØív4î[]]]]]E—^äøb;U(Žq@µ²²B6 ‹‹‹h¼i4µZ­étºÝncm ]¯×ÃÆ¼Ùlöû}Ò.s4ùýþÙÙYtjÇIÑn· uưÔï÷kï ‰võù|•4ÕUØÂÂñ�Z\\£¤gÇ­¯¯+54#“Kß| ×L8–îΑxÍó|µZ5™LGGGФØo=V=XçææÒé´R¥Jý~¿Ýn«p#‘H0m3‰•¢•�?¸xº‹ y½Þ‰Ò†dyy…KÈëLôî²»•~Ê‹‹‹ŒýP¹-£ˆxž_ZZ‚Õ®L·n©2|8Æ k Zˆ±DT˜5¨ÄfåJ Ø¥K—¼±…ñƉû§E6UJC*]Ò …é ^Q®[º×>6ø9 ½hq9ñ,â1ÂÍÍÍR©Ä´'___Gâ#š¾ãœ©^¯‹¢øôÓOó<ÿþûï#Ñ‹Ón·§R©X,æt:N§(Š&“)ÎÎÎúý~¸“6›-ŸÏ¿÷Þ{H|"ó£?ú£W®\¡CÀ‘H$ŸÏ·Ûm³ÙŒíw¿`Z±XÄÝðîÁ`0#¾‡’Ã-A°u#ª–f¬Á`€Z¡UËåòù|ûûû4‹¤a£ÑˆÕ>`6†’e …Bn·»Ñh”Ëe¥iB0‹HÏÈÑa$J6nŒíRQ®_¿^­VIÑ,Aæææ‡TÝ@2bŒš‡cÑèK9€ºæ¥+4âøšyGé:â8.“ÉhÜ(¨¼”(Šè%A\iÈ]6|"U.—ëÓŸþô¥K—°fÜÖÒY˜¤È3ät:‰ `¦ e÷Î70 ‰’$Ðam•7’¯'žx‚46¤¹G™¬&Fj¤¥¥¥F£ÁüŠ^ì´Âû  *N§³Ùlª4k1 Í9 Nßð…^ø'mÚ5†õ´J¦#”d³ÙIR,üÁ‰îf³Ù0ý~¿~~¾×ëÑœšúœE£Q£ÑÝQ*•ÖÖÖîÝ»GÐÝnw8öz½GGGåra=ìxl6Bd©T Y©TÊëõÂÙFáp=†Ñ5Ò`0à´ùí·ßît:ÄB[,˜¨R©D4T¢ÜýÂàžt‹ u||Üétü~?öpÜý_Ï?ÿ<*±Z­Vø\¢(îýWZ`ffÆ`0ȪW%e¤7×"{¯×;é¯&¢ápX*•šÍ&ªtéR\’žCdç‚^ÏL!`YÆ^sff¥q¸û¹UêKuql6¦ Éx£Ñhii©\.[­Vzl•J…N2Ä—M&“–M!âçFc0àü2•J5›Í³„³�~H¥RN§S{s»ÝŒ—ì$­DýllyB´pvvV) ñØ&KÍ­×ë•=¤Y^^&H§XM4ÉzÈ©ƒÄÂoëµÀ󖆑›Í&DgggÉ™,Ic$¨8ÊLƒs:gãd0pÜR«ÕHðÍår ²ùPZ‡R$ øj·ÛÐËÌÄK£RˆÂ‘ÿ6 ¢; –:ª6@à*• ÎÌpؘáp‰D\.×ööv"‘¨T*@�•¿Q×Åfffl6[:F>L‘ÙlFšâÊÊŠÇãAg3³Ùl4[­V*•"|ðù|¨RLöy‹% ¡z1ƒr‡=~¿¿ÙlÖj5—Ëåv»EQü±û±@ ‡±©B}v»½¶¶†Ì@ØE¥9%LÜDfê;„é£%AÐk‘$€R­ª¾ž¥’œH$‰Ä¥K—L&ÓÖÖ‡Õ³×à6Ý»wè5d‘ ‰ìµ?ôAÇRµZ%á„F£ôYø ;'ÂÑÑQ.—ƒ™$ÆÍ£M&#“ý~_j™ ]N§syy9NÏÍÍáð&Nwz:É6¿˜ˆ²Ó¤$E¥R øåó]eS/v´ë+ *ò€ã-A/ 'W2NcÊ^É&òªä³Cû399.—K6Ñãñ íÍéÔà0”�_ô”4YS¥îA¹ ‚@2DÃáðÇ>ö±Ÿø‰Ÿ@"òéééÉÉI³Ù¼yó&’€wvvÜn7*8ÆZ­ÿ½j›ŸŸÏd2¡PÛ—ÑhäóùZ­p¬¹\áD“Étçγٌ¼€pN'At»Ýƒƒzx´G õää Øãñ\¼xìzæ™g677*÷z½ƒÞØíö3cF£{ÔÄ„‚|˜„ã7x ¨‹±µµ¥=» |€ÂHòÁÁÁûï¿RIùèèh,øŸáêññ1ñÈ$£i2³-ËÁÁ$Yû‰‹ (Ûb±LÚ4çy§ÓùÁ¼ýöÛ§§§ %šl6›tøP¯×wvvàGò<ŸÉdˆK§2<ôoûa‘CQ?üðCÙ‘+­2ºââ¹­BOOOK¥’Ûí†öÀöƒù¾’†—uµW¤3Ž•0Ùɦ3=ÁçŽF#ézÆ)ŽlÀÎE‘Fÿ m³TFɃd $°êÍê‰û@¶/étÚívãH€�ÏóNÿjµZ(Z__÷x<€7âø= ÍÌÌ$‰T*§ÁºJ¥Òét`Š‚Á`>Ÿïõzˆ¡ÑŒ¥ë|á-ÂÝGõollÌÍÍE"‘L&³°°0Ñöm4…B!»Ý °Åb9 ”6‘ƒÁ «×H¥ Ù<òù|4^Ûb±(ACT.‘66p²²§åÌüév»RIEñÚµkH–rU .ÍpÕëõJ¶lÏ)‚]f³e‹UN&ueè,ä|>‡+·Ùlžœœ0­Ý”ˆð¡ÛíV«ÕR©T«Õ�N'ÏÂðdY4iãs$?^å=¹ô RòȪaRè®”Âá°´.=©«½Ü­xÏdœ†Ã¡ìîrgg‡–~õt8* W�¾˜=¯tÑ’]~„G(¦e ‘HÄjµ¶Z-¦%3&£P( ‡Ã¥¥%àP ð#§Óé÷ûQŒÜáp „ @™ ƒn·{||œÍf1r ÎHk¯×«äñ©\¢uN ¬Vëp8æcF;êD"€*"'8ˆ¢ }$+Òz*xœÒf_e ²w@ʆzÌ„~#ˆ·z¦GÁÉ‹Å"uл4ª> Òívcs IEq{{ûÝwß•vЮªd¹×l6™8˜ì›ÆãqFAû|>z‡'Š¢Ùl&0êp8Lkùn·KtЬò’m™¡aºâ Fãêիׯ_GiòšݩĢ)rÿÎ…T¼-|h4ZŒw>ŸÇ*+äãÒ‰ƒŸÍ) }ÏþÐivNDŽý~ÿÌÌ Ü^Rp°Óé�Ž:i0“GÐcE“ì0dã¤L¤Ód2-//“jÍ‘HÄ`0\¿~ýðði‚‡½Çq.\À¡T£Ñxî¹ç€JC •1»Ýn«ÕB;àz½Ž3L@b“ɤ×ëEéÏn·»´´suzz ™Ãçä¡KKKsssd½ G"‘p8\¯×³Ùl6›½wïžËå:>>ÞÚÚZ[[+—Ë*R6”÷û}æ@"N3›†H$¢Ô›`,¬4ƒ„Tzô!^K�=“ÉpøTV@‰#ŠW·ÛMÛi¤›_¸pA5IÓìì,íÜ0#Ïd2(@%=PEñøø˜ˆ+†§ô²ÈÓQ‰ìá.r;™(1-`Ãá°X,’H£Jrp³Ù<‹2òx<Ãá<(޹ar1棣£z½.{bÁÇééù’JXYÇçU×Õh4"_ììfxl`øµt5d-b ê38©áœæËëõ»S.—!â‹evv–=õz½ùùyò…±‹ÅH†Øòòòáá!yYOÁívr @u(ŒìñÝÓO?ÍfQ$±V«õûý@ P©TpÌÓívM&´[«Õj·Û¢(¢,6=H/AaP¯× hNz CµZ…yÈçó‚ ±¢ßïÛív4Óët:‹%3™ôsss»»»Xù²)ÑÙð¡ÓéAß}÷ÝV«•Ífwww}>_±XD´º“Öï`>Ñ~Ô©r\±¶¶fµZeS°°=r:Œ3Aª’kÔƒJ½áÉæææ0x#Ô, ï…ÔGÂðn·‹†46› Û ›ÍF#L3™ c� (Bi ¨îƒvƺò·¬¸Ò}TM&Óââ"íâ)º………r¹ìóù<ÏX'…Ñ0†¢*$R"mTêõz‘T©Ô<—^Ñê#¡;‚g¢.`ê“û8“Éd򯯡Ûí²>=ïDT¦~Ý2qºhà(Z¾ À;£ H)3˜Éd€{±Z­èÆ0A¶^§ÓÌÛï÷Çb±£££jµ |8¢¹a8Fª;0´gâÓè6$ãÂS€¥EQœE‘†:!%A£¿033ƒžâ¸Þº#—Ëá±ð€ˆÆ*ây>•J‹Eds!Gn0 @ÜÉÉ ,S>ŸÏçó¨Î€þë¬çr¹h4 é¯xYf‘£ÖªÍfÃΆ  à\.ŽOêõz±XÌårÁ`Ðívïîî …P($B¡P ¦)C÷]¸p¡V«mnn ‚@/ÙPêY,“Ñh¼xñ"Z'+¹c½^ézŒçNÔÊš9ƒáîÝq74av4àè$YƒA‹Å‚LQò}únLdCEúr OvÒUbwÌÝèé —°ïTŸ£……º˜×ë …Bô’1«««Ùl–~Öââ"]¼Gvš¸û¿O&+šÐÌÌÌ rNfÊáp,\-vFË ½^¯F¤ùù’(Ѝž<V’ÕѾÃqœV¿±±¡8Øét”Àm²ï%«ê•fJi›KŽ`¥ãd¸sw÷W>÷_.ôSùb%À•Þú_¯¿ýöÛä­ßïÆt:}ùòeƒÁP.—ßzë-õÄ_ +&²áصF”úÖXÁñPHª´ö ¦s¸9Žƒc‹üÀT*U­V«Õ*Ïóp*·¶¶p¶vxxø‘|ÄårY,–^¯çõz].@Ôår1‡b±xåÊTÞƒA…Ï‹ÜñZ­v÷îÝÁ`�›7vØv»=#GKÅùùùããã¹¹9QB¡é1AnÈó¼ö…äuz OÊd2GGGL|2‹¡4âØŸC\‘/K£Î/\¸@’¦®jƒ,÷ *•˜Hyj§ Nzc …8Ž[]]ÝÛÛ›ŸŸ¿~ýºôçO=õÔ{ï½§‘4WÍf3]’£"4ÊÿC&”6gj4«(7¸ŒJgŠ©JpNðD7< ÍÌÌ@û)E8´¿ð ´õÂyÊ7ÔûùÏ>}éãß½‘«• {þ½QÅÛJ§Ó¨“ýÔSOÅb1¿ß-˜z.]tU#¡á:0´eRÉìb.É$È2?4›Í(êL¨ ,kT(`ƒ3™ ,“ÙlN$¨æprr‚¬V‹ÅÒétŽŽŽð_›ÍÖh4¼^o$yæ™gоöG~äG\.—Ýn_XX0·o߯~šÔï÷;NiðÝjµ’$”±‡Ã©T*‰Ü¹s'߸qckk+•JÑMrÁ•°,%“I&‰'MÓšŽ�3’'¥¦¸”Ífa�cÀ%äîkŒ:&“Ér¹L[&ŽãË„iR:ï!c`väþÚl6²dNOO'-~*-—©žñHóã¸H$ÂÈ•Óé\ZZB š“ÍÎÎÞ¼y“y;›Íd1!X\ØÓ“Õd2™A@W'2ƒLÑUf À¥’ÿ&‰×åÛâ‡Åb– | ýW¥AYCb4Iþ#ä hóŸJ¥¦®éÇó<½d4æÇ½÷Þ{Ä29NYi{7—˵¹¹Çé1 ‡Ã±–Ifî~í×ã/ÿæûÒ°=£ÑèÒÒR8æyy¤†J\bÒ2š0H¨I®Òr‘\ÄyÀ§§§Ìfí£ˆob2™b±Pv»¤ ’«HºCR?B¨'''ˆN@.‹Å¢Çã ƒý~¿R©”Ëå@ €›õÑ›Ù�� ÏIDAT ‘T•Å,ŽF£›7o:N Ž–——oݺ533ƒ (ÄápˆŠÅv»/…ÕóI£Ó& ¸8ºD” h\„òÀ&oæ_v'ÐîÉÉ Ã=ôíU:À; ¡.=M�¥J0œlZÀpä0Ñ“ú}Úŕ †±ýa9Žk6›["‘æ#h'é)7jûªl•h>BM(kb6›‚ „B¡ÙÙÙëׯF¦4ú°üL8O­V ‡µd5¡Ü0Š ìd’œÉ¡¶$m¼q@þ{F”ëXÓŽ–»Sß!’ª¦¨f©]Èá­’ *‚(à2dÅ­IY€IÉëõÂc–Õ¢XìcÏ_æççA/•JF#¼2“¥Þ�BÍ*0È ?.Aïᬋ ë™Õã N§óôô4›Íâä P(ܾ}›h7«ÕÊóüƒ æª pÉ%žç½^ïh4"“|èe8MäÒp8ÜÝÝ4]šHƒB«¥RI„z½n6›qsøMÝn·P( ,Óh4*•Š ÇÇÇXóX½èœ‹ýe¹\ÞÞÞF&ôÁÁ9ÉCMLºv-æfooH òÚ‘*=N[§Ó9é£Ëv»MÐ]n·›”?‘.TÙ:ß6›­Óé8NžçéÃŽãÆöâDF cðTÆ@ä›K2MµZ Å/˜“KTczƒÁy5¥gs¹\Ú•Ô¹GfÔ›M+ñÁív×ëõP(FWVVj~÷Ýw!]LßEŽã˜žô}±š¸ûènݺ…ã:Æ‚0aË‘9ióò³)±35‘•‹ð¯�"a8ZÛ;Õ„"Ñâ}­Vk¯×£§€Ñ¢XìcÝM%´(ü`œw£DŸÏo]FG£± étz{{[6ÏM2Ng<¿zõªÔß2ªK9šIïíí}øá‡×®]#5ˆ 1bÑhT#zÑív«$(3ÈJi,˜çyÄPJngg‡™iìá#à»áßÈžÔE-•J­V í6€ I&“‚ ÌÏÏG",<ôÅ@ù"ìZ ^.—¸´Z­wïÞEúC¹\F6y&“A)�JèבöŒ©×먢Öëõ¤˜PBHÇït:‘I(; ^¯—øòR-oµZív»öi±Jw4'Àr¥1Ð ~4¡ØR4%c¨.Eô ‡C&8ÅÆqÒšÈi<ËCa{àbú|>”‹´X,‡‡‡˜ í½"¥D$©I¥Ïç#À nòÆÙ$²ËåRï´„Úýý}¥íòt}­Ô{iå@sˆ=f±µÖ*"¨f³I¼C Á‰ö ”Êršjggµ§eÞE}”ÝnywîÜÉf³wîÜ¡÷qív›¶ êÖ˜ŽAËæIÓWUá‘V@ J÷•¢(ÂC!õÞñ+dÓ"é¨ÝnKŸý~ÿðð›’ããcTh½wïò5òù¼ÉdjµZ‡‡‡Èá&Ý|pýúu`owvvè1t»]�§�Y- 6› º�-¯ŠÅ"ÍH¿Á`8==Å煈ʥ‰¶]²§±\- ‡‡‡F£‘àÀÔ4©ù#9iÇU*¿ßÏœÿ¡À+3M‚ x½^r|ŠzÚ„4™õ‡"瘖z'zÙéÌj­V‹F£È›§³ç'b],£TÄú¤Æ‰^€$€¯ÔZ]ážcÏLÆ¿QBy3âŠYÞoì\(eÛ«*¹0zRªÇÞ§Õji×ÉS<en˜Qì‘Ì,=†ÝÝ]•1äóùápx÷îÝR©är¹ÌzÊ¿þë¿þ»¿û»Œ7Š2w²Gy‹h';Y,ô^Á`0ÐABÀëõ:¹„ø;$Õãñ˜ÍfÒ˜Eí¤õ(¢Ì$Éó¼RQNAPCV¶ãÍMbÒ¢œN§öº\.Ùôh§ÓÉôcK1Aˆ­u¹\êåÿùѹϠ:™ÍfÇc³ÙP&ÿ•W^™Âœ?äizp,’•ɱ—¡Xp¿ß¬ôäDfþ,«`øâââ·¯*§ äÎ餓N:é¤ÓC%Ê8Ÿþy!:餓N:=Vdf²¡J¥ÒÃIyÒI'tÒI'BLO6¬÷ÙÏ~"R?¦žîêØ£o•/<ˆñ<¸wy ¯>ü>¸‡>ükÉÚøç!*?t‹ô‘ ø‡Ht•fÐòÛW_}•Ÿ¹ðÿÓOþäOvÇÝ ½˜OTþÕxéìw“ŽPû¥ó}Ðo:cÏ‹ çÅŠó½Ûƒ˜Áóåù¤w›šç\VÏ}EŸ/+ÜÝÎWºOýðø‹ßWÿ÷ßd|æ™gôí¤N:餓N¿ð…/è\ÐI'tÒéñ2Nÿù÷~Oç‚N:餓N—qúWŸþ´ÎtÒI'/㤳@'tÒI'Ý8餓N:餓nœtÒI'tÒ“N:餓N:éÆI'tÒI'Ý8餓N:餓nœtÒI'tÒ“N:餓N:=jãôÊ+¯è\ÐI'tÒéñ2Nÿé?þG :餓N:=^ÆéßüÛ«sA'tÒI§ÇË85›M :餓N:=VdÖò%QU>—mÅ)´¥’ýDéÒùÞíÑþñÐÞåŒÒþ“‡?ÅèEÎ-ç+Æ_2'âÌŤ<ÊçŸÍ‹< 5ÈqÜüü¼šqº|ùr&“ѶN:it×”\7þÐ÷¿ÿýùùùh4ú𽿿ŸÏçÏÞ ¶×ëýÕ_ýÕ'>ñ‰‰~ÕjµÞzë­Ÿú©ŸRÿÚûï¿ïõz£ÂÐo¼ñ‰O|Âd2I/}ë[ßúÔ§>e4þcÒøOÿôOsB\Ñ8ýÒ/ý񮮠.”:餓N¯¼òÊg>ó™ÿñøþó?ÿóoûÛø‡xÆû”Ëå_|ñk_ûÚD¿:88ø™Ÿù™±¿úìg?»¾¾þ™Ï|Få;‹‹‹ò'b·Û¥—æææ¾úÕ¯ò<O>yý/ß&›Lf~nõGéåF«cçÚ—RápXJtÒI'»Ý¾²²âñxþ£yžÇãê›-d0|>ßÅ‹'ú•Ñh c7*V«uaa! ©|Çív?ùä“d{Ä\zê©§èXß•íƒýb½ÛnV ¼`{ñ_ÿ»ËýT¾X p¥Ï|òy}礓N:é¤Óç×ÿòíïÞÈÕÊ…½ÿ^¯¡“N:é¤ÓcGºqÒI'tÒéñ3NW®\ѹ “N:é¤ÓcEfAt.褓N:=ZÚÛÛ‹D"V«•ã¸v»Íf9Ž‹D"$Ý`kkk08޳gIh§r¹<ÉDQ¼~ý:Çq'™LâÃÝÝÝF£a4×ÖÖðÉÉÉI>Ÿç8n~~ÞápLiœt™ÐI'tz´tãÆW_}õÿøŸ|òÉN§óo|ãë_ÿ:Çq/¼ðÂ/þâ/Æb±ï}ï{_üâÛív"‘øßøÍÍÍ=¤jµúÿðñ‰D>÷¹Ïáÿù›¿ùâ¿ÈqÜòòò¯þê¯.//_»víþàööö,ËïüÎï<ÿüóù|þOÿôOÿîïþŽã¸—^z饗^’Í#Kú™“N:é¤Ó£¤+W®|ík_Ëårøo±Xü£?ú£7ß|óÍ7ßìt:o¾ù&Çq¿üË¿üÚk¯½ù替ð ¿ð…/|á!ŒªT*}ýë_ÿÁ~@øòË/c`/¾øâ—¿üeŽã~ÿ÷ÿ¥—^zóÍ7ÿìÏþìÕW_å8îoÿöoËå2¾öÕ¯~•¼—nœtÒI'~˜è[ßúÖüüü¤P¤Métúõ×_WØ>PÒ“N:é¤Ó#£ï~÷»ƒá¹çžÓY¡'tÒI§Ç‚Þyç7Þxãgög×××un0¤'D褓N:=Êçó¯¿þú[o½ÅqÜÖÖÖ+¯¼‚<t㤓N:éôÈè£ý(É8xõÕWë·~Ëãñè=öt㤓N:éô(Éf³¥R)üF‰„ÉdJ&“_úÒ—âñ8Çq¿ýÛ¿ýòË/swåÊ•ÍÍÍÓÓÓgžyæ›ßüæÃa·Û%ÿ½}û6öñü+_ù Çq¯½öÚÏýÜϽüòËv»ýæÍ›ǽôÒK•J_ûÆ7¾1u&û»¿ò¹ÿ¢~ÕI'tÒéÑ’^øU'tÒI§Çšt㤓N:é¤Óãgœ€òÕI'tÒI§ÇÈ8}éK_Ò¹ “N:é¤ÓcEæ/ÿ×ÿúgß¾ÂqœÉÌ×úÎÿù½ì_}XÔù¢“N:é¤ÓC¦£JËh2ý£qúÿò_Â8ŒÆ‘ÅyP¹jUç‘N:餓N™ F£Áð™ÿˆsêuÛ¥£=5:餓N:=Z†Çý?!]\1~Øú����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/panner.png��������������������������������������������������������������������0000644�0001750�0001750�00000005006�11332353405�015403� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���}������b²"���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ&àG?�� “IDATxÚí]?o;w¢¦å#PÒ™’nûÐ¥ ÅWDŠEB÷PR!Q$HP!$"(/â#\‰ø�| ¤ò+¬·qÖÿfÆ3¶÷ŽÕ ¹]ïx<ž??Ç;Æõ÷ªõÌ÷½½=ò³Zëa´ÖÍ{1¡áââÂÓ†ï ÙÑ|$,ßo5éÉz½.yEö‰üW·‰„¼Çâ"´%�'•‹Zf=C#«>ë;Ñ3âú}wwwì*ÜNB¸‘A —±z¬d¼+ñ½‚|íïïÏhÒ´÷gx‡dww—ÎaêéQ Ý ›L6³Zë(ßK¢•~ÌM³waWÓ4Ñ´j¬ÍÉ`û||Ðÿ2/·•M¿•àL™2¾Kƒ¶öÀ'`22ah¾‹zµ,ÏVs(ýȬ µ=ša–ñêgR¾ßê#$óË>øìÙ³yˆ=Ù’¾ããcrËöûáá!*‚­<3Úè àUò –¸OŽÈ.ô»úö<aá‹;®"-þœ|çuÊð—º}£r×|—a‘ö ‘éibP¤ú¦ÒN§z&(An˜"a5H³õøž f?ñ«UÓѱ1l¸nÅ2Zíñ™,üâò=*òG[âGGGsõ#±Ãóùl;y·ÄÐI*z®%Ü6ú=ÆA8ÑáÉaÄ=¿„ñ,•÷ÂÐ\Ôg>u;šÒ6É«(•ôŒO{îƒu`ØûßUŠdj}µ\{T˜7Æ(—ð%5§øÎ²J‡ÅI‚(¨´Ö…|o¸ŒE”÷’!‰)Óôß}‹jùî²{C佚p•Ov^¿~ oÜžßëà‘-øn'yÓ1Êý2þ—ù# ÊÖ›vvýðaú†Øçß««±…L## öK„$ÛH°©ý'O2ô\ù¢¼—¨aNOOÝgƒ®ÑÇ3$¥JE3.ª‘F mrAÇÿÔô &÷¤ù>šâ‹‹ :YžžÿT™~Ï,q`l9éN`n 4å!EVÞ›ÚÕ²˜gŠ˜�ß9}í\7i¹¶«ü3=&Ђö'kj´Ö÷ïß/§ìµúg¥”R;׬÷ÈñþÑÖu‘ZcFR>JyóæM |Ÿ~7eÊÓM¼Sϰ'›#ÐW£”RÏŸ?—IàËå²ý!ÅÕ Y5[u2†s¼oÜoŒDè[Õ®WJK85rDPçµõgB«<†Q«ñœ˜-=88ðQI©ì@7ðHDA±Äs®]Aëz|| ÇQ,…8 _&s”_Ï$|ÊXTEÛü8ÖÚ€ðIë™àð”ò=Ø(ª“Y[j¯oß¾ÛwqC`Ì‘0ÑduŠíï ¾ã&p¼>|ø˜%ã¿#~~žf1ëÈÑÀŒ‰M z†[y$ÛOû«Í5«æÏtP£ÎŽÓjµ z÷±?Î0õ:É誋aç„kr'¾¦ûˆ¥Ed_¦´,½#'Ð!õjɸ‰g_¶nUÂçsQÃ1,X¯×V›k­?}ú4Æ«¨Ü)‰â%ÆÃ�£‰Ø‚€ô.È$i‡a¦òNÔ3Bæ1ùÞ$ü-ˆåu Í ê<â°(âÒ5%|N ÃprrâšV#´Ø„—w~ü=8‘Bá ¯ÅbñôéS÷)ƒL .¡XzDÑ3#0]ÂGà»ÎÎÎlö¬ÖÚ&}h­—Ëåè_Ú5ÄiÑ¥þLì5ißæëׯxU)õåË¥ÔáááÝ»wÿþýøñãGýøñCÝ\°’šuOá Å,^Žïo%¤¼s˼ܻwïÏŸ?<¸sçŽRêóçÏ„©6¡Ö¶ìN¢_ëõ:±7 \¸˜/_&„·l]r_†áÅ‹Ëår¢£ì >yÆ-icb´›eû7ìjú:::B­|ú nxcM,qŒ‚ždãÄ:€Ù¿éS…Þw µ~ûö-Įޒ˜Õ3 »¢ŸèŒoG¢îÊî›™Œ½¬Œb‡sÄ)_½z¥xë¼ È»ß!ˆÕéé)ªmû GbÓ&÷ÛlËh#,^5ù~ƒ\˜c›wl¶Ñ>ÃE{¢X±0g¡]M,øÔÐ31ýN†Çt¨9ŽÍý™B࢜Ýtï0~3­›åã-¨g°þÊÍ/©‰\G¼˜å’Ï5ý'ò˜1‰ðUsÿ*» ô[ÿ³`™!áÂÔÞÿQ[Øüwx^Û¨ƒ+‘µå\¹·ålpºÉèq`8Lê^ïß¿'ó´~©Ÿ€,|MTƒII=ƒ­Í!1*åY› LëáÉɉßcù¸Z­ÇþR×mãl­7&F7Ä”Éjoe¢u==î äM·ûRw ‹x1×íL(¾:¼cZÔvÑìÖ¬ƒPIÏ4)f.¯–eQPoiþGË)R¾KËhÿ›=уâN\‰Ž¤c”lû ω£,€=kHäE‹Î˜Gº²ÿ>©ã¸··7ݶ &h±X\^^²ìák0ÉÚî³±ùˆS‚¶á#s•žÏ‡’¾NÀ^‰:Ù„Ñ7øžÀÛ€M,rm2ÚA¼T‘ˆ¯‡MØD g}o3&öw\¾yÓ5™PÍV“Ü쳨J¤Yê«RÁ~T£³ü0uY=î 6æÆ^ÎoÚ¶‹s¿<pÃQ²Õí¼ì24½ÇÈTIÄNì[úÚŒéi©]å•»ñÉ9Úv” \óÝL²APPKCÓ„SÌ–ÛÞhÀèë«ÙóÄ*¨Ë±Û<çªÔœ¶=pŸ¥L]³sYf  o‹´?²Žü‹™Cvƒtç¿Ãe-ݬ×OSJß¿÷[ûõëNRÍü“{çNsÖ[êüâgÆ«%ߥZ “�uæ@ÑÅ…l4ƲNPäÏ0®TLžŠ-2l/|ppÐCçm==ò¨È%ÏRê\Viƒ`U¶t-¾Ã1~=C¸Ÿ{‘×ò¹°Š³³³à¯/_¾¬¯¢fŸóùù9»˜wn (ø{a—´ÖdÔ~íjå.±Ÿ=¯!©„û¥Ú¶ü*å{+ãÖíük)ï¢ìÞ ÃÅzÈ)sá­ iÆnaVþã&Ô‹« /ÙÒZ½ŸO.ªä?”µË„Ñs& £ºÍÉxŒ}/ÝïÑ2™—¡.¨sÕÚ?cßãQsPyâU „¸ÔñxŒVon4&hå$–¾ú×QrÏçZºj»@ d“è‹×Óó_0©“Y¨¬„¶8m>£µîGØçå\Z¾ßVJýüù“öâwïÞ©¿òº¼¼TJý4Æ`¿JŒ×·����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/prefs.png���������������������������������������������������������������������0000644�0001750�0001750�00000027537�11332353405�015254� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��)��Á���#¼;���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ7G­ S�� �IDATxÚíÝ{ÕaçñsóÐ<ûJ=AH6oA lüŠ›G<©]±Ù-SÅÖ%»ÈºH‘­Ä[v ^c{]©Ô.c»²Þ<]6)b²ÁåG"{mÖ ‚ kÀzLkFÍh4s÷ íV÷éÓ§ßûý”ËŒîôãôéîóëÓÝsO¥Ýn !®¹ñ�@Âv<|¿¢Þ ž›n½�$íšoÙñðý•«oøØM·ÞþúÑij�´Wöï=°k{½óù¹SÔ� d�ÏÌñcó'ܯê]ží¼’ì9=?gÿôµÝÿtîhettôÌ™3/M÷.ßp‰t¡³S‡¦_Ø?µpÞâP�€tÌÏÍΟœÞ|é¥ú³ìÚ½[Ñ×?Õ¼ò않ýÓ± ®™{íéæM[jµÚw¿÷ûŽ0V9æ\˜?uÞÀÉW¦Äê ¯qÌ�H0{fg6oÞh–Í›7ïÚ½»oÙ`Vóʳ§rvxôôõÏüõýß|ß{Þ}Éžôƒ/ŽÖ{ûíÓTþlq¨çäÀ†åC£ �šJ¥R ~Å_±I^¯ì©:~1ØXýêÏlß¾cllå×?=ùøêË~Uˆ7ç?~à_.]3òÄÞcç\úŽ*zÅèÐ'?úÁ·Ÿ3V«V¿úÍmßõs>�]œ=ÕPP}ëÌ«ÕïéÛtÙ ÿòãéé}Õju´6xß3«Î§bæð·5Äc?Ý·áª_ó-ÇWÿæÆÈ›wúæN/ì}ùðß<¼ãÀ¡cŠ~Ó¯¼ã «Ÿ{aÿ£ÛŸyòéççŲþÁŽ?�]>ÂÕškv@ó~ù“[¼&ÿôŸ|GgÞ³&“~¨è÷x=°Y{Ùû_ÞþÝ~1/„XZ:>502ÐX=:p÷Ãë.¿¡R­inòÞý¯3§/ظþ²·¯ûÏÿþúßýã¿YgÍ[«U—¼fk !zäñ>ñ\ÿÐhß²>!*B™zê@‘£'ä½/ä¾Ù Ï>~áïñ÷ËŸÜò™ÿñÝÎÏÿõ?þk¯y½ú=ò­ÕûV_~ÝáßSÕjåè¾§ªc«O œwMï²!ýmþßÛþñwìZ=¶â¾?ú½‘¡±ÅC'+÷ý—ÛªÕÊ_mÛþ‘÷n¢ý{®nŒ|ìÆ«/Ù¸º§^{áåÃýÐöƒo˜wýÖ¯]°a•â>qó|âæßÿʃíÅö-ãïºdãûdBˆÖÝ·ê,Кòþ‡Ÿ¼î]-xjÏËú­ŸœY\B¬4†~óú«6¿mM_ïóÄ×ü/¾rdUcؽœJ¥ò›×_õÞ_Ú4<Ðj~á•Ãæ×þöÇÇOÌqb�H8{â¼oöï>ñi÷Ä÷g_¶[bÒyÿðëßûÒïü«NäX?[ tÌë•=ž›10²|pã5ó¶ÏÎ/¶kýÕÓ‡«kÎY½A{sßüï±âŠw\ÞùyvvnîTµó«^wå“»_œ;ujæÐK_ùOŸZ>2ðè“»Ž›ÚrÝ{?uë‡?õ•ŸØ½ßê[>úÔs“û_yýÐþɯ~îw—:&›_¬h.Кòú«ÏÿÉÓÏøÝ—½{óÆ;wíØ{´¿¯ço»qÅèàÁCGŸÞ5yîÚ1qêX­}æ3·Ýè^Î…›Ö}ä½—îõðƒ=:8ÐwÅ¥çŸ<öZ»6\­÷pn�H¸ßS 5WE:ïÅï|¿W\©çýìÿü‡/ÞþëBGðØì]»¥ÙcKm1ßî}ÛØPoooÏbàÍþôï|Ìúy÷Þý{^|yùÚþÉ_}{Û·÷,üðµW,øùÁ×'¾ñ·½Ë†6¬_{Õæ·_¾aôûÿ¼ëòMccËGøÏ;Ù±ûº÷]µ|tÐ=ÙŽ½Sš ´¦œh}kûO_¨´Û7]÷îs×4yjò=x׊ÑAsúÄíŸýï ‹íÞþÁöâ™ë?x­t9íZU1sâä+o{Ýœ½ÿ¡ÇæOÍ6Võ÷Ö{+¼t Áð©Šj%Ä\•JU>¯×ҬϽçýìŸmûâ'ÆÏ ž«? Y¯4{ 3ýÚÞ3Ç^\X¶j¤wöôéÓóóóâô‘™#ë‡ÇÎÕßä½û_=rÌœ›?½{ïþ¿ÿÑã=½ý=}Ë:¿zf÷¾ák— ëÏY/„ØxÎêo}ýóÖŒkV3Oí­Õ{;ÿ\68º~ÝZ¯ÉôØùùç®X³TëBôÖë§çg—,B¼tðÐü™±s.¨T+íÅ¥5c+¤Ëù»=ó¾_ÚøÎK6^váF!ÄǦÿè¾m‡¦N ÙÍM�ˆµßçó¯¥Ùî›yÎû…Ä~§î®?Hº^~GèÍÍLÍì{|v±þ¶«®?5}ôØOP‹BsÏ£}Ã[ú†5oºuž÷Të=•JµwxÅÀp£R}3O/,ô===3§Î!¼úú×þ×·­™™3‹g¬‰…ÇOžöšLŸë}}ÕÚ›•Ðn·MÏ !6®_=44R©V{úûkÕêñSò5ÎÍ-ü·oþháøëVŽ~tüƒï»jó».Zû½Ç^¬Öªœ�òxÏ­*¿çæµ´³î¹Éæ½ç·o´z<GD_øøGîþ‹‡Ýë pÏméÌÂÉ•ʺ+nèéèX¼ð§^ü§¾¾Þžžžûï»üzýí]Þ78"Ú¢R«Ök½µžº}óªµú3/¼zìø‰ ëVÿú¯¾ç•£'#ƒï¸pß?øÈ‰Ÿ¿n_ÎÓ“¯øN`g?:{zÏ#S3+ßùø ¯]7¶ü‡O½°sR¾œ·õöþÛ_ó³—^95wúœµ«…ǧOLO½¾bÍÆJ•~€ä²ç¬†ëóÿá¯)?÷ïŸ=—üot4ú=’y­õvnµ}îßï|rÏoßè^¯WöHV|êà3+‡{ß¹rdåÚÎ'ËϽððì± Ã ===ívûåýÏŽnz§~}õöÔju¯-œ_XüRëáßxÿEW_~Á/÷÷OÍœ|~ßË{÷î­ôŒØ‹7¿°à5™þ½J8wzñKùпùåK®¼ôü­]ùúÑã/îÝ3uüÌ—Zÿç7Þ±c9kÏÙX«Šë¯Ý<Ðß;3;÷УO~ûû?éj,-©×z9=�$>š7öw=ñÈæk?dï.¹çíôW<W¤œ× žÎZ>÷—?øüo]/_¯cÁñ{^:ø†ã³¯ï=¯ÿø³fÖ]öAûÊÚKKgn¿êâ ‹‹‹Ç§§÷\µQ½ñûwïXZZ4ÆÖ ¯X[?û°—ž{BˆöعŽ•JµÝ^2ß8xêäÌÂÜìÒÒR­V¯÷õ®\·lpøµwž?5ºrÝèʵÕZÍk²ýÏ?¥¹@û”G^}éÄÔáeÃÆò5çõôöO>8wbzaîäÒR»^ï1VŸ30Ô˜>öš{9•Jûè¡‹ §ÛKKÕj­o`hdåºÞ¾eõ²@RŽ9´yóY_ñüÜcÿ×kâËÞsÝ›9´ëùÑ•k’˜×šLúag^ë·SoüÅø=Ž(;=sô¼““Ž­¾ôWDõ¬¾R¥V[»lö´yñù›fffÚ/xñäñ¾!CQM£«Îéí_V©TÝ™i¬^ß?0bÅx¥R[ß»ìx»"ª•Z¥Ri‹v­ÖS©ÕFÆÖU«õj­&*¢RõœLö)‡«úFê½}¢R©T«ÆÊu§– ‰öR¥ÖSéLQ“/§ÖÓÓ[_­Ö+µjçÉV­ÞSïí‚{n�’ëö8{—¿÷z¹¤ï Ä>¯ãCõß–žõ‹Gì™êßpu½§Ï½ÜþÁ‘çŽÎ<òÜÜÜÜÂÂé™…Ùþá«…n¬Zïõ«å®¿ªÕ{†Œ•î)G–¯Ö™Lö)†F…íQkõž¡ÑîY¤Ëé9»`�Ÿ{nîÈÊl^ì9«s³òíW«5°|Ýi±®*DŸ«8� EÃÆîÝ?sÜþRÛµëùa£R©f5¯V¿�[ápvíz^–eC£¹²šWž=ü-$�)~†ú†Š5¯g¿gvzŠ= �HÂÀHÃÕïbvzê³·\Kí��’ðÅû·â‡o�¤Mò-Û¶m£^��q÷Ï!D³Ù¤²��ц199éø{n�€´ÕC$X¶%®T*SSS”²Q6ÊÖUeëêì1 Ã4ÍlKÜn·¥»‡²Q6ÊFÙÊZ¶ò pÏ-;Fašf»Ýn4”²Q6ÊÖ eëêìÉÉŽ±vϽ÷ÞkíÊFÙ(e+kÙʪ㲆ÕU”þl¯M{§Òú<öž¦½±LhK+]W¢ˆk-)ÒëXÊO EU¬=Í‚y­Ñ÷„M³<ªbljU½¢\íÙ.Êžp «WbåGO÷E›5@:WB)W ºH©U²bE´úªñî÷å‰×q ÿaÄ“Ç*Rç‡F£aÿÄþOÇuc2Ň)´ÒB&TzST‹fM&TKŠBzý3Û^eN¹YwÔ hˆžôÿ³Ý³ô{ú)ܨ±_@é\(©ûg±Ÿ¨ŠðÖé8¦SoáÖ{‡bïXi긕”Ú•²ôwQöBÒšÇRÉéìMõ}KölzÙã8Õ3¹#a-Ê^éýYÙóJ?Œ·;ïÕ™Hºw¯Yo!Ö{¥ùîM¯¹{uéÜ2B”³ ?•¬s:°ÇÓÎGƒ•íÓ{ߣVúLÕëP“Þ\NçZ&ý‡Ï‰nHB•¦¹7#ÎRÖ¶>èõ"Ç~O Ó>…ºzò½ýÉ)šÂ³ß(õ–íÏI¸È]öx½™æó¯"¹ß’p/{nêBê|žá…³ïO´Àнé5㇬?áý(ý®ï ‹\~•3{¤o=ªßDŸš¨KâþAs‹’8†| ©®ÞÔêÍ·B¼j)ƫߓÔß݉îPßZÍÕs‚œFqÌèÿ*«ZÒ<A øk®M�€ìÉ^!‚‡t@ö��@ö��rŒ±ãº´lòd^*»;ï¼óÎ;ï”–“}JÙ([ÉÆµ+êØq÷Þ{/e ]6éðé9Ñ)g»ÝfŸR6ʖòÅ?²'Wc+U*Ê®lív;·Á#„˜œœ´ÊÉ>¥l”-‡e‹%~ªVœ“æ©3¶e wèä9x¬ø¹çž{§û”²ugÙÊ:®] [šè?§ùmoyø>+õ·aº¿9…Ò^tÑE{öìq|"„p|˜«ŠÊ¡@#ÈuyÕú¢“l‡Ìy2,^²Ù“«¦‚ÊgQ}K•‡bg<Eɯ;†ðȰÞrøÕv¹L2Ÿm]кÊO}V“«ýQ¼Ü.¥J¸gËÏié®:‘âhT{öìéttìÝ ë“‹.ºÈþ³×éì>é!dÿ§z(¹L¹D‡ ÔÊ«ÖSTc: «zÈÇôëPQu^˜Î ëu;  3Öb®û=êcZg/Çi^òxuíS¾©¥îG{}ÏîZ·ãÜ÷åÒ¿3£8„4¬n%er¼yu/܃)¨«1‰6ÝkÏ*†|ÌêœUWc eSוWë¡.^:uX½¼Ju?#“û�ŠúÍðrXgijü°÷l:ý!+„’$Å7KjVTú£SK¯«ø†¤ %Ýqù#Ñ/ VF¥Óz¤|Öã­ý‡„:cT—ì().+TÜq’‡?¡¡®ÝËy~.ë[6Å�NÕÕC5Þƒ&è•HÎ/UrU¼<וÕûQ¤{™àIaO¥¶7‹Õvå°´Qû=޾Ž{H.õ\ÒÁ0Ô#€¥sáá°lŽç=ê I­ñêôäá}ëp‡Pú{9«1õ1a&óÝ…qÿSÚø¤P0ߊʪuê*Ûý[öˆ #‰éL ÒmI=*ZÞõª¬ iëgwêt>I:Ô£ÒiŽh—r£ ý$ý?êcL¿J3mO¿ɪêR8Q¿i W¼tŽÃº��”T~zÛd�t‹Ü>Ûcü��Ù�(»ÊÕ7|ì¦[oùã³ÓSŸ½åZ!Ķmۚͦ}¢\0†ˆòÿ=ÖBˆxà®»îbg…Ì×fç‹÷?>0Ò8|pß]ÛýŸ÷äyœ1”ÕÍ7ßÌQ”Î0?U‚�£Îê?Ь<�€Øãçž{îQÄï��ÒFö��È�@Ùþ^ƒmÛ¶Qk��»ñññd³GáøëŸ¢ÈÏ_)™¦™ó¦¶É�J Ä‹iÜsKÛÄÄ›  ËuÝw‰f{Þjµº­‹ ³É�º ý��Ù� {�� {��d��AÄùž›ãkãtÆj 1–xg–ÎôöŸ#Û±X–œPÅúÌQøpÛ’«�@¿ÇÇÔÔ”=tZ78ýŠÕ¬[�è–~£¡l4FÃÝV:>ñÆ«‹ã^Bľ…££ ív8 ãUÂt: Ò5:ª%P=ëtƒÎ�iô{|û7ŽÊñ¡þu½c i^Ñšç¡{dÿA¿ž¥›ãøP=;§€Œû=¡[Ì 9: y+³»Ã‘Â.p|¨^/=�¹ËÍÇ?†ŸýÅÅm·ÌãÙ~33“„&x�&{ô_Íʰ¡§aÕ©Þw�QRÏ{¼;w®ÙóÙgr< ‘®EgEé7Ê^kŒÞ{#`�#{¬Úý”[ñ”}ëgÇй’ë—è>Â4ÞâˆI÷ŸÛÿ©¿9Ö¢¤kÌç{�Š"Î{n¾í²úCû?Ýï°y½Õ½¡W¯Wº ¯ß&ôêNŪ«%Äæè,™[‘�òÒï�€ì�=��²��²�@ö��Ÿz·mp«Õ¢„�@¿'=”�è÷¤Ç4Íf³I  Ùc�H5{¸/�°O<{ºí¾Pžûy¦irÐsqÀ ó#|rr2Ð,¼c]`t@Áƒ‚ªS½`äUl!ý��Ù� {�� {��d��AÄùž[£ÑBLMMuIÝž½IW`gùvAו‡]¬.ƒ}ÕÓd~ Ú‹áþYº ^³�ô{wSo‘¦Q9®J¹uöMè÷¸Öv\¯9.ÜÜŸº0TÌî?®í ôa ë÷LŠ­¾÷ýAz$øî}Ë|Ç¡ëÙ«�¹êYÅn4Yê@~û=ŠëPÇ9#m¡ô—)=ý«`uÙ|?̪äQJ¨Þwö&2Ð…><õ„ÔÇg ß_I£Å±¥ïð~Oüg—ûsõ™£¾¦ Ñ<¥|Ï$ó+S÷²oaO|+?\kúðHçèwwØWä•1�Ù¾¥Ëd™¹"Í^rMj£Ñðº¬.VóMÉs~¨ig×£—4—™ÏFDg+R+yˆ*µç¢$œû t­²;P ¹{ÏMÚöéç–×”3<[â‰Eæ%w—Añø$Ñ vÅ”Ž"åd§Êtφƒì‘´SŽ«9ß{;Öoí×nêíËô2¹«B¯íg?MQ|èõžRB%·J«.ŒoÔ•ï5±t½šœ|§t¯E½é!Éõ™¬:)ô† ;Õc?zµ_:³{M©~zŸèI¨¿Æˆ5“hU©´íÖ,¿æþ ·£­7ýš×,pÐm÷=}€.ê÷¤v3Šû åØw�Èžìo „»iÀ=‡âî;�](Gã–Fl³hòŠ»ï�Ðï�€ì�=��DQ§ 4µZ-*B�ýžôLLLP àè÷¤êÎ;ïÌy MÓd7qqœ€~¸¦Ç @¿§¤Œ<Eàâ8ý��È��Ù� {�� {��¥ç{nÒ¯ÐOè{õÝÆZE¼¥ÒYšU`ý•ÚK½*-ijX¿ Q-^óú.*Ðôî!b“>Bí_Eñb?$€2dOúŠrâ媙°7Ð:ãUgX-A‹§3½£ùζÊzÀdýdv\h»/è¤×¹¡/î-?DÓ¦ßÏs—Á¾:E9¥‹«À1Ö¡º¼®Öuö‚fx„k‹E•¨^¨N’îéT@ž¥÷¼Ç:mܧŠôüInùî¦'Êê+r—Á±:E9}¯vÓ ž@ûHz³K}Q¢�Ö¯¼V'-Œ{úˆ[í[' ubìuâµ¥* lýë„Ñ?B7©šQm²ƒ¶w™_“*.uZÃ@7Íbßð¼]ÑG/£Ûç•1�Ù -öºnÍÏ™Ÿtãn‚tšKéÓŽèe‹²SÜó=„Âu}ÊqøÑÝA·÷{§A7\Çé¼Ù•Ï{#AËÖièÓ|\ŸçÚ }¡æu7²—b€T5¡3Jø½¿¤Óp¤Ð¸D_…×4·±X}&¯}Ý)UôÇu±4©¾wíêK`î~! tiö¨O{ß‹;kÊ@ŽþòC¯Âw :ep¿Ýëþ!‰;Ú&i ¥e ?iEáÖëÞGê½è¸Ê$õ}7È¡zì'ƒãgõë³^¿õ}³KѬë,?–óSsÕ«v/ÄkÛc,pнà»_Ô[­³|õƒ'Aß= täÄÛ¸ªÍjè÷��@ö��È��Ù��Ù� {��ˆ¢NhjµZT8„�ú=陘˜ À!ÐïIišÍf“z�‡eö†AÅ�RÍî��ìÆÇÇÏî��,†aLNNš…w ��i#{��d�€ì�€ì�[œ[ê¯7Ðð½qõë»õŽ˜#–‡Œ ñì‰" ´;;É�EÍ{¢Óš[ ½ãWÒž‡ïìŽÉ¬ÌpϨßGqwà¼ÊìU:@� •Æó«åuç#i¬ÉìÍ´zvGÓ/Í÷ŒQâS¿<Š€~OR]ÒvY³£ ž t?ë·®<tw� ñìqܪ ±4ÙáºÒ8twÅ��áäñë¸ZvÇͱx‹ûb€ìÉ8xâzÙ:b_'«Ô�²'*«Y×Ï•Æ[‚ÎnMl@ói¿}zÅÛÕŠÅz½ç�°‹óy£ÁU?¥÷šXóq½bá^¿ÒÉé¢tÖnŸÐk�ú=��=�€R¨S±à–�Ðï�=��=��²�@ö��@ö��ÈžòhµZ­V«de†aì\�9Ûß÷ø¶ÝÍfSñ[Å€Žib´ÕjmºïY!DK´Ô…T¬4o_ãf†išöBl�ä={„\jËέŠÐÑêy}•gÍ¢<òëÇO e‹<BÓ4õã�Š—=á¸/·£ÏY_mÿm,éöà‰?Ž¢º¿ÐZ:ªb»Bo ;i¢Ä¢Ø|i7€Ð ð¼Ç=ð4“¢Ï/â'ò³Çð Žáæzmrèà±ÇOè@•›ÁŠ�”${6öϽ }Åí<qÅæx ê!Ãnºs.~"n#� {¤ nìmœaŠà±â'ö—ÄÜ™* Úp›Üjµ|滋¦Y¾×ù�=Å`šæ–[ÕÓ¨_Žˆ’¬Ž[X!ú7RÍfÓ7WZ­oR�@Ù²Gg4kEO"‰øI"x½Ÿ¸¨ã'öàáy€b÷{¬øñz»Úkú(=¯øÑ¯§Sê gÅmßäè­¹Wüè}£ÔÅæy€Ðò2vœ£!³7sÒi¬Ÿ£ÇÏw®¼-hð¨ßðýY‚ÐñcOÍàÑ›ƒÔ£ìñ}ˆ’CöøIôV[šìñ“Э6â@.²§Ùl´á¶n¾•éÿ­›o±¿\ÐùËëö ! ã~Oq•ò+g’{¥¼ßc � {��d��ñ ó¼‡É��igÏÄÄ�°Œ'ž=|'�ÀbÆääd YxÞ�HÙ� {��d��d� Øbû>7÷×úÂcûÄ!¾)Y=‹c\œˆ_GÆ9@^²'Fñ6뎨О�P€ì±¾ZßÝw±w;¿uôH:³«çõúP³âXˆ}u¾åt¬‹�„“øó«vg‰{ ¯ÆÝ>¯b¡‹ç[NÍ�©ö{B÷–‚NºŸáÕ[ò] ãF@~³GzÛÊÝîGo¾Ãu5¤ÝßB� Ðï‰7f¼–ûý®„ �p‹ùyúÎXçe„p}y5û:ét³��)e¢õW¿fMæ~ã˜×þ¡N´Ø§W¼]­X¬×{n�€pâ¿çæn u>ñê3ù>ç×ÉÇ4ö S/Öý&^ˆµ�Òî÷��@ö��2V§ ¸¥�ô{��d��d�€ì�€ì�=��²§µZ­V«U²2 Ã0 v.€Šíï{|Ûîf³©ø­bhÇ4±Újµ6Ý÷¬¢%ZêB*Vš·/|3 Ã4Mû!6 �òž=BˆN .µeçVE èhõ¼¾ô3‰fÑ žNùõã'…²E!„išúñ�ÅËžpÜ—ÛöCÒÅr‘nžˆñã(ªû«¯¥£ê)¶+ôº“&Jü(ŠÍ×{­�Ï{ÜC$H3)zðü"~"?ûq Ä`Ø÷C¯M<öø ¨Òb3¬€’dOÃÆþ¹Õü9„¾âö ž¸âGsdÅdêß ž(ñq �Ù#mpcoã ÃP?±¿$æÎTiІÛäV«å{WÍ4Íò½Î€ì)Ó4·ìܪžFýrD”duÜ ѿ‘j6›¾¹Òj…|“�Ê–=:ã^+zIÄOÁ£èýÄE?±Ï{�»ßcÅ×ÛÕ^ÓGé1xÅ~ðx=Ro 8{Ðnû&GoͽâG?xì¥.6Ï{�„–—±ã ™½™“Ncý=~¾såmAƒGýŽ€ïÏú„Ž{ÒhþÛ¤€eïC”²ÇO¢·ÚÒdŸ„nµ?�r‘=Íf³  ·uó­LüoÝ|‹ýå‚Î_öX· !�÷{_ëê��àIDATŠ«”_9“Ü+mä €ˆøk��Ù� {��ˆW˜ç=ŒH�H;{&&&¨8�€e||<ñìá;Á��Ã0&''ÍÂó�@ÚÈ��Ù� {�� {��Åç÷¹9†Ÿ±¾õKýÍÇÑ¿9–1§�î÷8Æ„ñ ­³Þ¸a�£ßãHkìK{ÏÆž î@’þÖš=Dɽ@waè$@áû=¾IàÕ;‘þÖ<1®�P¶~Wg(bG*PGÝ!‹^$�@²'Ñ·ý]ç^ŸoŒ<�‰,ï¹eÅÊ?îÂ@©²'öŽE\9ÁC �(aöXOSÜÁc5÷Ö=1é{höÙ­}c¬ñ÷¼Üa€\‰óyWãnÿÜëgÅ|3CýhG³0�€÷{êE�Èž”pß �ʧžÿ"’7�@¿��²�@ö��@ö��È��Ù�@²§ÕjµZ­Ò× a†ap$€¾¤þ¾§ÕjmºïY!DK´šÍ¦Î,Ò¿õý“RÅ8¤) Òc†išöô·Q8Wͺ€®î÷XÁ#„Øtß³©õ~ì£3¤0^ƒ=oLÓŒÞûÉ|t �(jö؃'DüØ{�îAµí_V-\#ñX¿Ja„wG'züØËïøÁ1oµhþÌ×å(Cö¸ƒ'®ÞtÜ«—àè.x}ž\ðhÆO ¯ÜvŒ4am²;žƒGÄ F�Ê“=^Á4~}—¼Q?ÚÑéý¸ûs‚JsP éZìóædY�dO¤Y<Vüø¶Ë9_§Õjù¾S`šfÎ_ð³÷xèô�(pö˜¦¹eçVõ4[vnÕy,Ïžf³é›+­–êÕ>ûH¬Ö ´LRÖýB �,{|ãG?xì#^ëK­UÇ:xb¡³¥ê„c<$�åÉEüèoc*}ËÀz,Ÿmü$<Ò- 7¶#òÈVü[Ú‰Ÿï\y[Ðà‘>éÑyühâxãÇž4úÁãUNß W-ÒiÈ�åé÷¸{?Ñ{<¹eïý¤p« �è÷èÆOYƒÇ?�dŸ=¥O{üp@ Œ¡�� {��d��ñ 󼇡Ò��igÏÄÄ�°Œ'ž=¼Ù�°†199hž÷��ÒFö��È��Ù��Ù�(¶8¿ÏÍ=¦_Ô�H£ß3õÁ`Ì�€¤û=:ý!{&9Ær–~¨?;� {û=Òà‘ö„¬áŸªggÿ�ýy7Å‹ô·:1ôx�€ì‘çAôŠt �=ªØˆøê1�eR¤¿ïi4<ã�²G·ËÒ‰½ûìt€� â¼çæ öÏÝÓXŸxM¦˜�@¿��²�@ö��@ö��È�@ÙÕ© M†aP 2M“J ß�陘˜ è÷�\}#=­V‹J ß� {�� {��d��d� ˜b{ÏÍ÷’f³©ø­ÎHÛá†QЙË=À]ô¯ÊÖ;<·ÂíS¯ÊtT¬´~ãk(ê­Õ›ÚvY5ŸÜ¤ØŠÐ°)d®M÷=ëõ«-;·*^*u´PÖH?é…±¬Es‹ò/ô> Q?îpòª·ÒToÊÛ•N-éïG=y9߬«3Gcä¾ôúÄÑ„Y“IG®“Nã5È·b-¾[äuIk_£cKÕ«óí4¨?ÌÛeö¢W¯þvi™îCÔwß³#Ê&K×¥yV†Û¿È³<ïqsjµîƒÒq¤:ÎdéŒ^ þZxÒSË~.ù®Nº(ý3ì8ª[÷µú-HY«7èzíî¾ns/Üw±:gPÄýe½:ûdO¤æL³òmÝb¹ JùªÊ±:ÅVHÏöMyìW šm½íH­ù(bõêäú—1n‚t?Js.·Õˆòßs ÝЇk›ÊqAäÞ ÷Ŧׇ…ØãV •I™‹[½±Ü÷‹k2Íý¨_ôfè÷ä¨3åÎL¡ƒGºÞ"Kº´îh6Íîkdª7'èÔSìGÅ«¤:Õâ”ÙãßN9N�ý&Æ‹µXš÷E\¬fÉ¥÷1rØã‰X?e­ÞØ·+öDtßG«„êjLh½ ßøÞE é¥Ï!¥¯$8î D¹£âõ¸5ôÒ¼nõ8J^”{n¾¥U¸¬Õ«¹]:ë•Òúk÷:;­Z:™WoÒ=qÐõ¢Xê¹jŒÔêÁf”þz-¾[¤¿4ßy}K®YÈtv¨~Á‚6”å«^í ºùŠ"þètÖ¬ðè§<ÉÔuÙ³eçV*´dاˆ·Ësö4›M†Ã*ö)’ú%Œ[šsœ¥T/ŽRâ{¬�d�€ì� ^<ï2à;6@¿@œ&&&¨ÐïÓ4ÕcødœaT� ÕìáŽ�Àn||<ñìáŽ�ÀbÆääd Yx×��6²�@ö��È��È�@±Åù·¥ÒÁ9â±Ã±ÇT|7;�tiö$Êž.Œ@�d³ƒâÕ;±ÿÓ1ÍÔÔ”â÷dÖŠÜÓØ—/]� [é=ï±Z{*¸Åa^·×¼nî¹çbˆx�(öØsÅžŠn‡ûWñöQÔk�¤)þ{nöNŒ£C“BÿCº R�Jž=^àõ`&öäc§@Î%rÏ­�b Þ4j4<ã€îÊE uRÁúÙñC\˧�yç=7{s/}Íw‚(ËÉ¿°��(X¿GŠ›c�@ö¤e�Ð…²ÿNò�è÷��@ö��È��È��Ù��Ù� {��Ý+¶¿ïiµZê šÍ¦â·^Ä…#ýKÕDÿ|5ÆÍçž�=lºïY¯_mÙ¹Õ4Mͨ°ßhŒ’nÓcÙü„¶�J›=qõQì!$lÐ9F¢³dŸFѬ Ù�BŽÕ¥ÜùpÛ«¨îJÖ†t+ÔU�é+Àó«1µšNw~؇cPèµÅ Tê*âp@¿GÕ° ¿Á¤è\à»ûIVÃ[ްÑ/0=�dO«*m1“l;ÿߨí¾;§Y`‚@~ékÇ ¥D[ö¢Ü¡*\ ÙËó•г[ý†¬z<ŽÍw ¦§Ø.=@öÄÓþªß0v¿…l5Í^â’Þ­Êðž›{ÕÖ'Šbäm+�@_^ž÷8ZI{Kê5™;~“ —2l©[*- ­ �”9{¶ìÜÚÍUÙå›�dO³ÙTüé~éuùæ@fýžLpC � ‡ï±�=��²��²�@ö��@ö��º4{ Ã0 £kk¶”›ßjµ|G§ž»üÈtÔ“;ý:kiý £4ßBbó355hðtÆo‰V³Ù 4oB{6‡õבŸÿãÈ]¿Ç~Ö™¦©s èøþærO Íù5Õ !Ħûž ÔûIhsrXÏqùEEÈQö¸/÷tNBé¨<öÓ²(áTÊÍ·OÐøq|w\®ž}[ÿô‹ä;•= w:�)e×}†ÐíBq{<á6?‡wÝÁ®÷“‡zNnŒ‰.?ò,³G}ƒ;ÄIX¬Ñh¢o¾c3ó°ù^Á£?î!ˆ¢oT”z–ÞËʶH¾2Ç(! βÇÙHù>Y5M3蕲bôš\‰¾ùÒ%ÛÍ7 C<Vüx5¬^cßEÙ¨f IÈž÷åt�ÒËžf³é{vµZ!ß¹Üqó½®d³Ý|Ó4}%Ú²s«¢åu\¹[Ó‡Þ¨f ©Ð§^öøž„¡[„¢¼íSÊÍWÇ:x¦l¬O¢oTë9ö"•àt�ÒËÅI×é—s7¿a“ŸòŠuð䳞“{dï‘Ï£=1œ„ú§Ÿã}SÇ%s!ÎÀp›?å’«ÍwÇOÐà‰}£BfÒÞX¶E’®7¹råÌÇIØ%=žÒo¾=~2ìñ伞»üÈôÕ“> »óô+åæ[ñ“‡àÉm=wù‘dœ=œ{¥Üüü¤Nžë™Ô|1†�€ì�=��Ä+Ìó¾�vöLLLPq��ËøøxâÙÃk<��‹a“““fáy� mõ‚–›gNù‘Ã?úá˜dWvÉ®,î.£ßƒHxøÇ®»¬‹ú=\¦åAVcfsL²+Ù•Eßeô{��d�€ì�€ì�=��Qï’íìŒ{ß155ÕùgŒ£Û—o­%Äì „Ü=Çdr«à Jm?RÛô{äg`ç°pçD\¦Þh-ŽâcEÜìJú=ªK?÷ñ!½üth-GÿZÒ=‹×b;?¸Ëæµjýâin]:—áP“Ž:ö`ûµÒèuÖÓïéÆËOÅ5iˆ‹{º¸+ EõªÕÓønHÐMFæ=¡Ð»I³jÛëìÖÙݹïê=^ÇSˆßJŸ*I/m"è!ʦÙQãÖ_ºˆ»)Ç×~é´ ³ŒGqd¼7ãÕ¾‡ˆ%LJ: $&ÄrôW!=ùq˜þ:¬h¸kÍnÛwdg³žPÿW§Ykš1é8rðD<êØkî5û­ų¯+¼nÛwåÞã~¤ïub+~•Ä!ë»®¸¦QLi}H'ŸÇdÄÝŠ"†Y—ì»jWêîæUq¯Öº3WïGç¾V\ÓhnúC¤yLêuìÁ|îGÍ6Äý@¨;÷]½«é?}Ò„¾æþPg2¹ÔŸÚ:n×ää˜ôÝq!v+û4“ý軿ØS‚w¬�d�€ì�€ì�=��=�€|+ö;Ö­V‹]ŽI°+é÷¤gbb‚ýŽI°+é÷¤Ç4Íf³ÉþÇ$Ø•ô{��H¦ßc�H/{ÆÇÇ'''©8�@hÜs�=�€nΞ/|á T� Õì¹ãŽ;xàê�È<p÷Ýw+Æ%òy×àŽ;îøÚ×¾F=�ô©ƒGè¼çvÇw0ö;�@ŸïH¬õX–�€>Þs�¤MÞïá› ��©fß\��H÷Ü��Ùõ{F_¼ÿqj�„‘†${¿�� Ù~Ïáƒû¨ �@:*ívûšo¡"��éØñðýÿÿXr‰«ÐR����IEND®B`‚�����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/info.png����������������������������������������������������������������������0000644�0001750�0001750�00000006137�11332353405�015061� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��^���¤���P7ц���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚÅ_Û¯�� ìIDATxÚíÛ•£:Eé^NÀNJ‡0zB¸^—¥‘J¥Òû὿º±ÁP%ŽJ_¯×ë�ø—oB��!BÐ?þØš_¿~! ]øýû7A€}ùû÷/ÒÐ=¸�{Õ¼nÇÆ\� � (žÏ§øÕ×ëõþˆë ±„ôÎÈ‚û_e;^߉«+ Ås7îmÛ Y~E‰FYð•“â^"~_‰­rê%Úü¬ŒÎ5pþ!çðœ¼ÿ~>ŸJ{ÒåÃ[Ý[è®âí¡}#ú–{ÈDìWê»4wÝÜí(jå}ÓeQMÞ«'@{iHF¶S‡pX9ìEõÞø^¢œWb—"¦LÜB¿ÜemYŒØµÞç†qËž`…±-kÒïMy9àŒø®i÷wb:éÖÃ7>zÐÄOïVÖÔžÿc×úPM*“{ï€rYÍ)“دľï-ߤ³bë–Eî~k‡XœêÍ;L½È¬¹W‹ºE‡]†¢`@áöÆvq©×ôdüs‹‹Võu¨s¤!÷˜¡28c_  ýF³­šS“ˆÙã/&Êù¯oª ÜEhWuxÔG’scão—€uÆÆ±SNßöû_ÿ®êæ±þn²Ó”õAV(ëÊFÖZÊ7s·SÿâY¡eû×Gq[qCOù wwî˜94KHíaW¾Yy‚¸eûÂܽ}‹•ÛÉœláÅËÞN™kðB4à¤ûâ¬nÈû.tž¡8ulxöz­—¥ Ý€ ¦‹Ûe¼íîöš;Ùoši€¡l7€]|‡ûíÒмž€`ôHøüüüؼ!)�ð†\€À�Ò � ök¸T_ª«ô>ͳm&“þšÞB=2ºÅ`rûW`a˜ô}ÌJqÒ I܈âïx¥ZMÚ.*á…*iÈrõ#ôJL’ÖC¢ÏÊ•2t?ÕÝz?ÛÄ�R1>4†Ñ^¨’†ÐzLt½lî†W©åá‡ËJ“Sº¸4ÕÊÒTHßGÏ5ˆ6›WŽ!"É2 ©7eÜ%Âã¡|®ÁR-[ñl0†E…q “Û 3é)ó¿ËŠ t—†¬®rG ú{JÆ®+ ƒ"Ë-Ë€º(’Ùº!¾vpkéJËó†öÊÃj¨ŽaDcig ¯Ôµ4=ÙÉ…¤¡yÕ–4q %IüŽ};WÊŽÑò£°ú€ÂâbxÙÜ c›/|@«i ñ6uA® å¿£áü tœkÐ_‚–5î9H^sÈ ,QBÚ5Ú–¯/$ÜnÛŠ½Xh®��6 (.˜�i�¼!i�Œž�i�¼!unëA ºÅ„4P2 eº; 2&i8°õ¯‰g=H‚O÷5�€�Ò��i—'Ø‘.ˆyFZ )÷z·}Òÿr){KæŽÕ…J¿ÆéìÛ9é­)FŠž#æ5õ¹äGÁÑÆ,!7a€J‹• ¶7ÝÑ.sí;+IxcÀDÍ>öj“ÏÿY|T> i—F€âsFïc7jiŠWÃ×»0×�§añ¶?~Ü´\¼Wí¢ µÒp—Fï2‰Ñ è`)%&(¼K<¡Sq~R¾\Ñ}Õ¡ÀDs.eÔ—\xE¬a¡ûv»*Rêk¬eÒteÛTæ`ËQ: @TòÎ;è5×�Àøi€–`%D‚ÀGˆÀ¥ÝÑHæzCU=Ò¢`¾†4ÐúÁ/©ÐÍàâ%� �P6 ÈrÑᔥoÅßÈ$¨ —.xN!ØsA³ªÁ}Êí’üùÄþG÷‰¤Ë ¡†qUCAÿC—pNÕ@GtÆtÃ;_žG�@•4x†•¦}´ËñC wHø±ž‹Ð«jP¬¢³åÀ9s ¢ÓNM@Y;k|AØ¡¥4X*Uñ}V¡-ã‡î\)€ÆŠ\7>£¥ôVt0´j��¤��€�üÚƒ× €a àóóóCæzCRÐÙ„4P2 eº; 2&i8°õ¯É:Þ$È’ ¤v…W·w…‹—°«.`Ò•‡"Æ7÷cÚÞ¾bbpc_wÅŸ˜cX¶Ö7ûL®â}gYãÉ¿Û)eÉà×OØúì< ".>«ƒ"ØYø¬šÚµ²6K¨¸–}SaÌ/6LY2bek‰º_ŸGM¤®sM¥ÝqlïcŒmßsÐ+[K)¶í›Mû¬0«ù•¥,©#•>tÛx@Q‘c4â>̑Ǖü-ñ ö0¶Ùuz×`pÁ’|e@—[˜VÏGÍa‡Ç<+IF°cªÖX Å®ûþ‚q­Üä* Ùô^Áó+?Á¡_)Ár×*“€‰ùV>¬p˜>ƒ‚¹ýX#;ï2ÁÓa|w½B½P8× ¼¨6mC];ŸM ÆÊàï® WÙ} ŸP;ÜoºëÕñÇ{w\Y=XYw·£‹ä¬¼‡1öi}ÊzhwáÝníàîâ1 á0»É¡‰áJưl-û¿à]'Ÿ›z÷×»þtMðË"Ö0Î5·6<Œ•Ñ òȪ²íÚ/k%÷Á²PŸh4þ–åÞ‡5+ÿY)ËŠXåZY)ë; �€ãA��i�€â¹¨+!„4€�>B$è�¾¸[‰îh$xCî’ ªz¤¡à ¹K‚†[ÿ²%Þ%ˆ+� €4�€@Ú29OY|ûFÏóÅ 9˜Ä%AW5`× €4\Š@\ÿzQz.â¡FÙŠeO%÷ Œ=ÒR ™s ¢©÷ИøâÅÎôÆG³ƒkp‚Y«ÇΣ +çY‡ìQ5xE~åw¶Óq +Ð…9Uƒ%èG&fîY�Öª”O„=§·$ö䊋ëÂ…³6|rÕŽÙbc¹ÐcÚh¤—\�’å´´x×e½Ò«·¿]¿ùÄkñéè; ��¤��i�€8ø5´+!„4€�>B$è�ð†¤; Þ»$ˆªi(xCî’ ¤áÀÖ¿lI…7äF â � � ö†¼ùlas„‰ÖƒÞŸnRÂ|é cY®ÜÔ ,’ eOÜ�ЧØj JxC6|ÄðÞä6;¯Í%´ˬæ›"Aî߯P¿t¹™˜ GF*zSÊÜÞo‡Dìäûçôdg=Ìv0+$H<9õ}XÙ4ì» IqÒ•lÓÞieoÈØ^aW·ògq¾õÖ&Z˜ˆå€2ØÓŸò¾=ÖÚH±,)Ån÷sta°vg%hGá~dUª]“´‹×Sn³èÝìÎè£+¶Ð…«†\ˆÕÆsÞRb,RŽòÄ^Û.,5ˆK&hß\|÷‹Úe{)Þ“Þƒ½!Ãle*Û¾»D{‹òĘ Ü!Æ: z4 S8+«=ŠŸº ½/€1nWêrzÁ¦x¹CÛ¡èeödŸž «7d®û£n¦XösOˆs1Å?m¼TÙÖÂs/9¿·zË·äbÍ5PнœG­40ãp$µs ˆ�Ò�&°"AHà#D‚�oHº£¡à ¹K‚¨葆‚7ä. BlýË–TxCn” à�@�i��«7ä°j{•x§æî3¯zˆ65},Îû.7ÝmçÖ™ö†ôT½þew!O†hSÓDzgÏwTóÜ:YæýáêVè“> ¦«]ïC-0§´ÔHönõ-lrúòë škÓ¦Ó]¸T7%ºÝZvO?(h>èó<ìĉÁÇüzPÕ v›*1Ï€m]JˆË9ó§IƒîPœ2 ] lè\ƒqÐ^ÓP2|²"x½NÍéM¢'Ì5´mcÔýCtáÓüò’»‘çè²ûYR5”ù8Nt´XWža‚x¶é£ûŠªØ›Y×<¢ä¾-˜8“7d®ÑcìS£af۔ؗ·=®í,+צýÛ‚º¦/\-qÜ( Œ›�i€Yùµ£çÁCÙ°Ÿ:�Ò°%X ‘ ¤ð"A€7$�0 �ÿ¤©b"hÅ����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/components.png����������������������������������������������������������������0000644�0001750�0001750�00000634021�11332353405�016312� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��4��˜���ë7õÁ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚµ5/ �� �IDATxÚìw\GûÀgËõÊq´”ÞQÀˆ vLŒkÔX^[ìšXc7jòÆäÕèÏh0Ê ±kL4Ö(6lÄB•*½õúÝÞí  Dßd¿þ8v§íìì<ó<óÌ ò4çÙ´%Ã_ÍÊùïGGôÀq _´iwÿ·'05ÂÀÀÀÀð—³÷è%A¢Â»ãÝû®¬®gj„á/G`«ØøåNþ8 I½NËÔÃß‹Ùl2H‹ååA€³Ø8‹ÝúXœÅjs,ˆÙl†?p’$ :uC¯®a›5|.�PgdqE2ëÔL ¦SjÍ,¡­‚yå o8$i1è4,p9ì—‹1’¬¯©ç Å(‚t¸ì׋/£(N Ñ_…�Àl1Ó¤«ÅÔPÑÁÓO,]OÎÔhqWð»´ÏP©®.2 ÛÓ#20000¼™F ör9‡Ë}¹$³XP´ºN¥ÂY†ØÛÉ9Nkb±[Ëb± hu½J͈~M¿ 'A¨ ‘ÔD:—TTËmeþnv÷2 IÃ+ºŒiª¹ö"['zD†7Vwâ°Ù\¯%A ‹Åµõ $ 96·òŒKE’$—ÛÒX†‰E¢ºzMš tá„þ–‚²ÄöÙ¹í/2©ÄŽo.­|&Vxúږ¡ J'r Âpö?çÅèáß5ÀíçûO“Rò˜fÎÀÀð¿‚ ‚¶\€áQE¤5± ­Ì …áÑ߉&kÍ �€a¸ÀÁ++ûž¼ºŠ$IÔ„jj„B[gƒºÖQ”” ݺâìfõ5 E|Û; t’KL„¹¢FuîVjva¥Ùb�¸:ØÌÕGÈç\KÎ:w+Ug0Át hß7ÄÇ^&Ò‰ô¼²+2Ë• �€Uï 8‡ÎÞÉÈ/ÿ _­L,tuâ^ÓÀJÝÅ1,ÐK1°g;©�>oæ³rÂla> †7D:4=äåá ‚ükîè>Aúзgï”VÕC9AÑ_£��øàÝ>Š~yø*~PÏ€`_×?&•)~ÕŽPšD~N°q(ŽÛút+ùå'œP i1ó-ªŠêR¾K6Oš—ŠR±pÎèHYÏJ F“‹£œÌ„`l6ŽuðP8ÛKI’ôVHeB¬Xo@1|Hïc¢BjêUy…e"!¿o¨‡³ìàw +ëE®€ËÒÔU‘fƒÌFf"Ì�� C&‚0[ ã†Þh2 ��‡sX8Š¢�&¢3-E›Åfa i¶XØ,Lo$ô‚ ,ã²qEÌRg0Äï¦ÐPá±Y,#,E� H‹ÅB’8Žñ8, C�f ©Õ=\äsFõ)WÖܸÿ¤“¯ûô·zí<ús^I-É| o„lBZ§¡(B^ò8„ÉØ¨[ ø¥¹éf¾=Îbÿª5!ŒN…q´/×oßé[&ÂÕÍ/¼³§Z£-|š‚J¿ÆBèb¨³Þo ΖûöªÉHDÌ:½ªÚB<!y\ÜÖ“#²EPìO%òD|΃”¬]ÿ=c ��ˆÉdÀyRŸÃãrºøµ«­WÕ5hÜ\mEUj©ˆ?¸g•F·ó੤ÇÙöv“ßîÛ·[ ·B\¦|¾�‹$;{»,2,=¯Ìl±¸9Ù>Ê.É-®ÐÝOÀã\¹ŸyîVš‘°ôïê×£ƒŸËb±ð’ÊúÓ‰³‹*ím†…¸;”TÖé ¦NÞÎgŸN|,³÷éâêïÊçàZqù^æÍÇy”ºƒ ˆ‡³í[ܲg¥Õ’R’Ð.¾í†ôê rL&³Ú`Ús쪛“EÀ/©ÙO]™øvÔÛý»{9Š ÊjÍ$Ê| ÿsf=ô7ëÜïbÍ^ù)Îþò´pÚ(+ƒÞïŒ»ßø`t'¹ø½!ÝòKªÃ;{VU×í<p´TYßÎÆ•±±E M '��W$cÛ¸ê*žšÆc!\À•8¼tª©A£/,¯õqwY<ýÝ⪆¼beVAy½F¢¨½Lìé"’‘û(#wì°¾Þí2 k\ím8,¼¦¾áAZžØÖÑ”Vku£«ƒ ˜s(Ï_%Ÿ€õ0=OÌgõîä® ’~IïÓ­c'Ç_Rs ••ÆðóGÊš:ÏöN#ú÷ÔëuÅe]Ú‡ø¹<HÉÊ~VÒ¿WAtêZ“^ìÛa`¿'™yOžæ÷éønTpö³’ÒÔF\Vxg¯�wÇ÷SŠÊ•1ýzÀˆÜ og'ñ^J¹²ÎÞVZSYVíhKX,Þn΃"{øy¹á8æh+52¶°z4ÃkN‚¶Ü¬ç›PE‹…� ÃÜü;Óòá4Ô–~Ó·Pz^ßüpgâ P7'Y{GYi…òÀ‘òJ”.ž8›Mœ(¥Ð5§¦Å©I[oÖV[0.Ǹ,TOè, Hv¸ ZãwîºÛÚÛˆºx+"»ø\¾—qáN¦ž Cü\-fK^QYznIIU} {â/Ù(�, @PO€a,Á,$À1”0êù;áôKZvÂ×§Œ °·½~ïñù›œì\ì¤\œ$LÆ‚òZžE,hõ‚"b>[Ì!lÅZþüõû²Ke¶¶ö¶R@>‡ÕÞI†¡ˆ^o@To 8l–BRPVËæ ��6¡¨A­9uñfa•ÚÃÍ5Ø·=�ÀDXjUZav”ËÌ$RRUKHfAù•{îŽÒÈP?.5M��³É€±„(Ê84200¼ NµX6Á9'€4š÷±šB_…‚ü6GõûXf’|V^ãæ$�”U*5FÒÉÍ›M¹¢H“Z͋օ#Œº†Â3a’´ëhn(W©+-–Si‹'b ¥hö!1 ­ª×&œÏóXݽ†õ ñk'¿pSÃb Cü\¸»8òù‘€ë(»ÈÅeu*að¸ÞnÎJ="àslE<6«´²Úh"%®Ñè,(›ÄX$ ªjê8|!‰â‚�@JœþÝ|:º;fçiuzÊr„´ I"(ÆI0‡2hBù.—‰Mf¢²ºº²ºº¼ªZ¯S³øAဠÌ�Åøb™…üÕ’©Õî¤æÕÕÕÉ„œ@/×a]H€<Ȫ<s#E²àèÞÉÛ^.-­Pš3Š­ª0000¼&~UœZÚ=×´šˆÕè_äyxôwÓT(=XÿPŸ°NîeÊâòª®AþB‰í…»™ÊzM3Z]s²Ý“‹®<‹P+…®¥Î^ÚuÕ×á†Z}E6›Œà¬æžJ*â‹îRRY[¯Ò:ÛI¸v]ƒJ­ªpµ·itz™T,“ŠÒl¶˜»ø»g^úåAzAXg¯IoõË.©±‘Šƒ¼Õ5Òs h$¥I (Š"(�Àb!Q .oI©ÛÞA†òþ“,©T ë4úòªº`ßvýzyVª=1�è ¦¢ŠÚP_VŸW\…¢¨ÂÞ¦NkÂp ICê5†š§Â¦gÿŠ·½Ã¯¦NËÞF¢7¹Å ¶6RvNR>Φˆà*•JÀeúy4¨µ3óÌ�ƒo—ù.þjÍéwó:ýC½MmqãI~­JGÿ{'o¨$¡MjNÏåú\Ný,º«wX'weMÝ7‡Ð-"¹_;; C¸™V§Öÿ¥u•”·k3¡¶kRêí½lœ½1[hëL¶¦HÄÅHÔÔP]Àwôi®Ì€�²‹BÀã£(,­8{õ®ZgìÑÑÍh2]¼ñàêÝ'Ʋ·•ŒØ;Èßãä•û?ÞJmh¨ ðpwu´X,ÏŠËÎ]»›UXÁÚ6er„ú#ežü5@e­:#¿´GG·á!9ÅUеAo0=È(pq° òs—ÛÔTU×8Ú -$i4ŸIø¬îÃ&ÂR¯Ò¨5q6Å0AµSRJ¾€Ý¿GçâªÚÚ•ˆ'�`ª°“tóoÇba\6+#·èÖƒTã¸;*ä>8ŠV(kŽŸ»–W\ÅËQ G˜9'†7À¬G7µz8ÙˆšX{þÊu—à,6øÍOáwº¥³Æ Ä6ô( ¹øWõëŒò› ±“§“F«ûò›#ÏÊj~ïea(âí"o¨,4sd΂–ÀF"�€¬ÿöja™’ž™QU%5–WÖ‰=ºãœ_Àl2€ÚüvR à²kUÚ"“WêМúÈgYôõ•i1› Þ¨Òl¡M{g…¦¦¤JYcB9\¾Ç1Ï¢o(,.;ºñ98‹4�Âh2u“ÆhÁ¹"_äæìPYQU«²±SØJùÙ&ps÷ TÊ¢’b¶ÈÎY᤭-¯ª®Ã6r[jRtjµÖ`g'o¨­©VémÚ‰¸,³¾^£VOx+*¢kÇ= ?&>Ê“Ê8¨%´Àl4™LF“¹N£Ø8r"Å�� XiPi´có8¬*e ÉÛ;8`„Ö¤SÁ§«Ó˜$v ;‘Q]m2ôƒJGà<1W fsùÌ& 9F½NÀÅìá¿öRAAz2I6^‹YZ¡lס+›ÃÓëõ…%,ïw±lÏÒ4ò��””+Ý:vcq¸z½¾ ¨„Åæ yl{{»ç±„¹Oî”W7´÷ëÌæò�·¾<?;+Ë-°;‹ÍÕéô…Å¥”ÌS×+‹2’O³§ô²_…Acêjêê…í;ã\>ucs i{3»ÞÅÅÖÞh$Ÿ••é…,žÐº,�4è,:‹$Í�°Ž€ÏEq§FcRi&´c³8lÅq•‰ÐiÜ ˆå5è-&ƒAøåqQ›ƒ³¹e5ê:=Ê‘:^R£%¹2.‡[«ÖkÕG숱9Õ*½ÁˆãB›Ã×™ƒ!ÊåWª-f„/I½Û9vëè^]]+p»ùhtú{20L��jDp#a4Í�a¡,„o#ÁÙjÚÐLëô(@D(‚iõ$"°e³¹=a2X E9€#qQŒÅ©Ó™uZ„”ÍçqœÍa±ȳá9¡¿[±TU¯eÛ{ÐX̸;xa8›¾ËÝU¡ªN˱÷²Žåñ[,ÄÚ•¼ªNÃwòõT ØóÉ ­Á·ó²¥ÅjvÓoÂɨ­/©®cÛúñ6Fý,® HCT§–­ÁdÒcl¾¨ÉŠÀX,¡Tn}]"wúŽÅÆX¶ŽÔ¿<¡Äzó�€ÌÁ•ö߯ÒU,ûMocs~ÓOù›FÑM$ÎÁ±°ÎÞ$I>ÎÌ;têbZoãäˆ`(†á<¡ô»M±ØÛ¾‰ëœ&"‰döÌ7ÀÀÀðfšõH�,$Iù)¼`—�€ÙbA0AQ­‹…¢ŠX^–Æb7ŽÕ„·Þï×9 l]¶®ÍåÍÚ˜ ��îÿÈ[)QªöžH¬S–F‚ 8›+±wa±9Îf,n ÿp6G­Ó Õ5b‘è¥-sqI9O(BPL­UcÕ5¢Ä2›ÍÅ¥<AQµF¡-UZVÁˆ[·ÎéoW –a¿9Í£Îbs™Ù ††syBµF[ß n‰¢ÅŠáaƒ\¾H¥ÑÖµ0–à·X -Œ… Ü籬4'��‚¤ÅL˜þÆï†Ååý^\›˜öÊÀÀðÏÒŸ8pZ˜ Œ$‹Ã­Œ…b8JÛÔDÊ…ìnþÌËc````øKÈ*Ræ”5üÎ!‚´vîÛ}:1µÃÀÀÀÀðçSRR’››KÑNiN¿b4M¦ßÛ»Hèt ¼”–"¥¥Hi)¨®¶|ô ™Úd````øã(•Ê7nTVj�°mZ8Y,J8!/"Ož€¢"¤²èõÀ`@ `0�“‰øàÀá0ÊÀÀÀÀðÇQ©TJ¥€ßyàÍ…F¯\AnÜ�,–ÆK‚Iæ=†×H³Âɼm¨©A~ù9v }ð€©)†¿^8�€LFöí 0‰áOäe›¿aàñ˜jb````x“„#œð6ÄY½zu‹�èÔ©“ŸŸßÑ£GÇߣG?RŽšššuëÖѯ̙3ÇÏÏþÎÏÏß±cGŸ>}Ølö¥K—æÎëëë»|ùr>ŸÿñÇ·*£>úH(®Y³þûý÷ß_¹rþÞ¾};—û÷³=yòäµkרœœV¬Xñ¾û?þ¸®®ŽúwРAC† Ù·o_JJÊÆ%I›SNIIÙ·oßïA(úÅ_üÉøèÑ£ØØXêß•+W:::¶$âµk×Nž<9iÒ¤ÐÐÐ?^Œ:tþž?¾——W“ cÁ‚žžž¯ðñwìØ‘ŸŸOýÛ½{÷ &´0îÂ… œœ>úè£WûFRSS¿þúëÁƒ<xïÞ½iii›6m"IrÍš53fÌ��|÷ÝwIIIô6Ó¨9}ôÑGÎÎÎmÈ}ÅŠ§Q?ób>ùä¥Rùïÿ»…áãââîß¿¿jÕ*‡¿¥ÀP«Õ+W®ô÷÷Ÿ={6�àØ±c7nÜX²dIûöí…<zôèÍ›7›¼õ5§èè蘘˜˜˜˜ÐÐЬ¬¬¸¸¸ììì?þÌqqqYYY1ϱ³³£îVVV·îçç#—Ë�GŽ9uêTk3:|øðéÓ§©“““ãââ<<<bbbp­ïõþýûqqqÞÞÞðûôéó×¶³'Nœ9s†Ïç¯Y³æÒ¥K]»v‰‰ùƒBÚÑÑ1†Æ7âââþä§{úôé‚ ”J%,ãG¦M›¦ÑhZ7###...//ï#--mñâÅuuu111¹¹¹³gÏ.//·–^qqq•••¯¶Ο?7xðà˜˜˜víÚmÙ²å»ï¾kaÜaƽŽöY\\÷äÉ�ÀÕ«Wãâât:V«‹‹»zõ*ìÑ6oÞìììóý÷ßÏž=;''gþüùð=¦¦¦NŸ>½¾¾¾µY/]ºô›o¾ùúë¯W¯^ÝòXgΜIHHhyø.]ºÄÄÄÿ¾{ †¸¸8j@÷îݸ¸8¥RiÞª®®ns^mN}úôéܹóÆ;F¿>uêÔˆˆˆˆˆˆY³fµ­4Ñϱµµ…ɘ1c¨�?ÿüóÆóóó'Ož¬R©JKK?øàƒÖª/%%%óçχ_ÂáÇ׬Y“ššºqãF£ÑXTTñœ#GŽ��,X¡Óé #""6nÜ�øê«¯"""?~܆gìÚµ+|@…B±eË–øøøˆˆˆk×®Í;f=eÊع|ýõ×_~ù%¼X^^Þ¿ÿˆˆˆ¥K—¤¾øâ ª´A´¡0& //¯¸¸øèÑ£7nT©T}úô™>}zRRRDDÄZ•¬õ/_¾\QQqòäɪª*ª´l²Íœ:uêСC[·n…«««áVu(ººº'Ož´k׎jN·oß6™L¥¥¥T1¨~gÒ¤Iðʼyó¥óÞ{ïÁ[°Í´ŠÂÂÂI“&9::nÛ¶-::zÏž=Ÿþ¹ÍÀaš›6mjeÀ€ðÖæÍ›�;wˆHII;vìСCÛðŠû÷ï\ZZš““-0‹áÇÃ0ç΋ˆˆ8uêÔªU«"""*++7oÞüõ×_�Ξ=KUWFF� 22rÚ´i°aÐÓ?Î÷ß¿fÍš &Ì™3'::úܹs ,hhhxôè‘‹‹ |r¹üÎ;F£±µ‰'%%<yòàÁƒ÷ï߇ý@DDÄùóç—,YÑÐÐ�;êa/\¸@Å…mfíÚµðßÍ›7GDD<{öÌ`0PáwíÚ�8}úôÆ•J¥^¯§n}õÕWÿ+\ß¾}áónÛ¶~}Ô¨Qo¿ývvvvDDÄöíÛ_¯Yn$‘’’âêêJ"f̘ñÃ?ܸqÃh4FEEaÖ†WB’¤ùùÞJ(ŠÆÄÄ$''_¸paĈðbyyyJJŠZ­Þ±cGbb¢X,¶þ¼_Œ¿¿¿Á`ÈÍÍ�(•ʪª*WW×k×®¥¤¤¨TªÈÈH//¯ÿþ÷¿±±±K—.ùùù)))&“É`0¤¤¤øùù‘$YRR’––ÖÂa¸uí™ÍfAôz}JJJvv6‹ÅÒjµS§NÕjµ?ýô“P(ìÕ«×Ô©S£££×¯_¿zõê'NŒ3&,,ìúõëyyy#GŽd±XíÛ·ß¾}û§Ÿ~:`À€ÈÈȰ°°;wî´¹ÂI’„çQ>{ö >oJJJFF†Åby÷Ýw׬YÃçó飄&¾zõêC‡>|¸wïÞ~~~ÎÎÎÇOHHXµj•@ ¸páB£6¼víÚM›68qbøðá½{÷¾qãÆ£GÞ{ï=6›Ý*nppðÎ;W¬Xqúôé-[¶|óÍ7Ap8œÐÐP77·ï¾ûîСC+V¬ …§OŸ¾páÂíÛ·kkk‡ ‚a˜¯¯/LdòäÉ?ýôÓ½{÷ª««‡ŠaØŽ;Z5ÌÌËË qrr�´k׊ŸÌÌÌää䤤¤™3g²ÙlºM"++ëÁƒ·oßž5k›Í®©©III>|¸F£iÉé8͵7‹Å‚ Š¢6lØ¿\\\çÎ;vì8|øðeË–Íš5kâĉ÷ïß?pà€^¯‡oßl6_¿~}öìÙï½÷ÞÂ… çÌ™3tèÐÛ·o§¤¤¤§§[,–1cÆ|üñÇ<oܸq-,L¿~ý6lØ ÑhHÚB~‹Å¸gÏž“'OVVV:;;Ã'õ÷÷�±gÏž¥K—ž={vÆ ÿ÷ÿG¹¶œiÓ¦eee¨Õê‡Λ7/000%%eÖ¬Y»wï¾qãFÏž=/\¸ðöÛowïÞý‹/¾øì³Ïf̘qøðaÝh4¦¥¥yxxÀb¦¥¥Æ^½zqñâÅ .¬ZµŠÇ㥤¤ †^½zY,– .œ?~õêÕ<oêÔ©'QDõ”ÆRRR’”””˜˜8oÞ<ºé%##£¼¼|É’%óæÍ›?>—Ëmá8¯-šSÿþý­/Ö××azNôn�ÀåË—ƒž“””TSSC’d§N¬5k™L† †aR©´UY B7‹Åb>ŸOu¦0G£Ñh6›ÕjµÁ`8s挧§gÇŽ©(»víÚ³gϾ}ûzõêÕ†gœ<yrPPPXX%ƒ-Z¤T*óòòRSSíííM&Ap6H«ÕbfggÇb±ª««år¹L&3 Z­V§Óa4I’lR³~)ÕÕÕ°¶×­[7k֬ѣGÓïÄÆÆŠD"F£ÓéZ›øÖ­[wïÞ}ðàÁ>}ú (Z]]㸕 l3¶¶¶¶¶¶T›Ñh4,ËÎÎðšš;;;©Tj0Ôju«rg±X'N,**š9sæ¼yó<==333I’¬®®†é/Y²¤  `øðá±±±)))\.6`8ˆ¦Ô/³Ù ßH£[m¦ººAø\z½ž>ÄiîŽã¿üò Qµ–€€€Ñ£G7nÕªU°UÃfc±XjjjŒF£J¥âóù[¶liôi •J%ìììØlvmm­ÅbbãÀð=êõú–†Íf‹D¢mÛ¶Q“p$IvìØÇñææ8q;vlqqñܹs-Zäé陚šÚ5š ˆ²²²ŠŠ ú{üä“O† ‚ãxuuµ‹‹KzzúöíÛaͨT*J?sss;{öì÷ß¿råÊõë×=zôäÉ“>>>l6Û`0L˜0¡ÿþ©©©Ó¦M£?©^¯Ÿ8qbTTTjjêßL2ݼyöм›.ì9 ‚hÔª�r¹üÌ™3‰ÄúÖ+Öœ®^½Zj04yëƒ>`±X!!!m›ÚŽŽ¦ >¯ wîܹ÷ß?99¹¸¸xéÒ¥C‡Ý»w/ 33sòäÉð«¶±±y刋‹ƒÎ#™™™�€áÇ/Z´�——7iÒ$(q[žÚþ󟸸8…BÑ6ÿ¹\?õC‡-X°ÀÛÛûU=fUUUYYYûöíÿˆcÅA­V?}úÔÞÞ~Ñ¢EF£q÷îÝo½õ4L5";;{ôèÑR©ÔLۙάY³0 qwwÿKž%..ÎÅÅ¥mq>|XRR2f̘êêêÒÒRxqýúõB¡0((ÈÃãÏ>(G.—;99ÊåòŒŒ ‹E¹>Y£Ñh233íììæÍ›g4wîÜ9räȬ¬,úœô‹)((hhhX°`�À××·¶¶¶¨¨ÈZÍ=räȺuë<<<JJJÝ …•••,ËÍÍ êvIII¥¥¥#FŒèرãÈ‘#¡%rçÎ’’’wÞy§cÇŽ£FÚ´iÓßÉE",,ìøñãàùL¼ØÐÐ@õœ …âÌ6µ]8½€ãÇ …«W¯¾Â7¡Õj¡÷N“ÔÖÖæçç·<A>ŸÏçó£¢¢ÜÝÝáN:ýøãyyy™™™ð›‰ŒŒ<räHrrò!Cììì233ýýý¡¡æ²aÆ´´´G‰Åâ–wëÖ­‹‰‰ùùçŸáö ¡¢¢bûöíwïÞݱcG÷îÝÿ’2¤¥¥ 4hæÌ™;Æ�� �IDAT[·nýè£îܹCw•�<{ö,===((hÙ²e‰‰‰555M6¤ï¿ÿðÄÄÄÖ¾t¡PØ£G’’’ŒŒ ÿ‡–••iµÚ?¹*ÜÝÝ·nÝ:räHªÙ¹sg×®]¡ ™ÒÒÒÒ***^wa† –ššºm۶ÇïÚµËÏÏO.—ïÞ½š=½½½SRR*++ííí/_¾Œ¢¨T*ŠŠš:uê¿ÿýï%K–ܽ{÷Ò¥K­Êqûöí<¸uëV@@��àÞ½{¼qãF£`ååå ,xë­·¾ýöÛõë×7r.íØ±ãš5kÞÿ}�ÀÿýßÿÁvrñâE6›}èСٳgŸ8q¢S§ßN‚·<8gΜãÇwêÔÉz:óo†ÍåË—«ªªîß¿ïåå•’’Bü7oÞlm‚¯lÓ€d2YBBÂîÝ».\H/YËyöìYìsà¸ÇñC‡%''[7nœJ¥ŠOKKkU.ŽŽŽÐ•|ðàÁôIf‹5jÔ¨òòòØØØuëÖ}ùå—ð[ýì³ÏH’üüóÏããã;wîœ0qâÄž={¾ÚWÛ¯_?‡£G?~|Ĉ%%%ׯ_Aø   ÿ+W®ÄÆÆNŸ>=11± ™êt:XÛ7oÞìÒ¥Ë °­â—_~‰uwwÏÏχé8p`ìØ±J¥266ööíÛÁÁÁ¾¾¾T›9|ø°]TTÔ+¬O‡~ýú¥§§Ã”––¾óÎ;|>ôèÑðñÅåååƒ ’J¥ÿýï/\¸0tèÐüüü»wïÂD,•JãââvíÚµdÉ’Ö¶4''§;w²Ùì•+WÆÆÆ.^¼8>>~È!‹%66ö§Ÿ~òôôìÚµ+~ôèÑðÖùóç½¼¼è·^={ötssûñÇcccg̘qïÞ=ggçðððÇŸ>}ºªªŠØÕÕ5,, zä>\ ¼¾Þ­ÿþ7n¼qãÆ§Ÿ~;mÚ´[·nÉåò¨¨¨ÌÌLø‹ŠŠÞ~ûmÞkضF$ 6 ¶X6›íååuþüyúZ ww÷F f~þùç3fܺu«cÇŽ:t ¤n]¹reÆŒ·oßîСCÇŽé·þ–Œ;Ö`0ÄÆÆnß¾}ýúõ<]Fãùóç/]ºäëëÛrEë;bJƒFo'æô t'ÂÚé )(@iŽ+��Ë{ï>ŸÇã…‡‡ûûû;;;‡……Áϸ¡¡$ɘ˜˜I“&µöñø|¾î9~~~C† a³Ù8ŽÏ™3G*•†‡‡{zzzxx„……I¥Ò>}ú˜L&GGÇ–¯Þøí¡ÄÆÆ&,, jPíÔ©SDDDdd¤ÑhÔétÓ¦M ùµš0¬W¯^ÁÁÁ(Š:88„……)ŠVPÔËË+,,L,SßCXX4¦Éd2•J… ´DÙØØ„‡‡‡……999aÖ¹sçÞ½{£( c 0ÀÍÍ NÞtíÚuåÊ•‚´ª<0MXÛ¶¶¶“'OîÕ«Š¢:tèÝ»7Ç BQT¡P„……µp‘¬^;;;…BA½MƒÁ°|ùrX·r¹|Ê”)=zônÔfqvvîÝ»·ƒƒ´¤õìÙAøö[eƒ’J¥]ºt¡ °lÙ2X¥°öööS§NíÚµkhh¨X,nhh³fÍ2 ööö°æ o!2|øðñãÇ·ö¥Ëd²   XooïE‹=EQµZÍãñÞ}÷ÝaÆ¡(êééÙ»wï¡C‡"BÝ:t¨u›iíû…mA[[Û°°°:99©T*Nׯ_¿ ÈåòŽ;êtºæææfggÏ™3~QQQ°ð¾¾¾‹/–Ëå8ŽÃ† HkÕ<ÜÜÜz÷î-“É0 ëÑ£µžÌËËËÕÕU­Vëtº=z,_¾\"‘ëõzX ÿ¥K—¶ÊÞŽ¢¨¯¯oïÞ½¡d¥šSxxxïÞ½íííQ íׯ_÷îÝ ƒN§‹ŒŒìÞ½»Z­îÒ¥Kxx8‰:::ªÕj’$ÇŽ Š‘‘‘&“I§ÓI$’‰'öíÛEQ???Ør¨[&LèÛ·ïßC!ÂápÂÃኢ¨··7lº‹E«Õ ‚±cÇ4ˆºuèÐ!‹µwïÞœœœ±cÇ8Ð:Ù†††¼¼<5ÁҾɠ¯¯*ûV4²þàÕâŠ:ñ¢qýôz½õô&’˜ˆ-^L¿B\¼Zé-ÃÀÀðf’‘‘±gÏž 6lâĉgÏžMMMmÛ*׿7>üðÇ ç®ZH‡‚xúôé Â_¾|¹LÏ«¶š†ÚÂô{§¿ÙÎl_ÄÀðÆÞÞ^(~üñÇï¾ûîýû÷·lÙbË =­ÈÌÌ\¸p¡½½ý[o½ÅÔÆŸÎTÃ?[[ÛeË–Qk•<==_ë&^ÿ£´k×n×®]ÐÕ©VqâÄ ²MçÓ2‰៎ÍëX5ñw‚Ïçÿí^mv³z™Y$õ¾8mÚ)‡áiN ¨ªF#Ðh+÷Y$)‰ ,àóT PfâŠáONj5úŸÿ ee ¦±ÚDݾ¸º‰„ìÒÅ2y2x¾ýÃëN( H‘�ð¢™,™ ´rm C[…“Phiý ¯^8þñcZN“[•ÿ&œž={vûömú^R ¥æT\\rùr^kÌa`````xÂÉh4:88 6Œ©†?6›}å—¼ ž5N��Ç™mKZˆÑh4™LL=0üù`Æ|§ Ká„ã¬&4'†Vñøñã’’¦`øó±µµ}ç<10¼i0©ôìÙÓÓÓ³m20´‹ÅRQQ¡P(˜¹aF81¼½^O0Û 2üYÆÄÄDjûpF8100¼¹¤¥¥ ¦^!ÎÎÎð÷“'O˜1èk…Ïç7¹sy³Â‰$ÉyóæY__¾|ùîÝ»1 Û¸q#S­-áéÓ§;wŽnK—.}ÿý÷�€Å‹<x°ºº�àïï?wî\`ÿþý=Ú°aƒL&�ddd|õÕWTô%K–¸»»/X°Àl6�zöì Ï­ß·oßãÇ�"‘è“O>�$%%ÅÇÇ3&<<�°fͳټeË–´´´={öÀÔfΜ ˜7o4ZöîÝŽÖ÷îÝ›’’�H$›7oþƒÕ’pûöíåË—»¸¸ÔÖÖ®Y³^‰‰±>ÈùñãÇûöí£þ]¹r¥½½ýÂ… =<<ÿþ˜fм¼¼Ï?ÿ�ðÖ[o•——ß½{—ºåééùÍ7ß¼õÖ[ÑÑÑðâ‡~(&Nœ¸cÇz:kÖ¬±±±Y¼x±——×Â… �§NºråÊ‚ >\QQÑ(ß)S¦„††nذ¡²²^éÚµëäÉ“Ož<ùóÏ?�Ö®] ù~UdddtïÞeö_~¥Ý%½zØ:y}°X¬VkNñññžžžÛ¶m£_”H$'NœÀqœN-ÄÎÎnĈíÛ·oònbbâÊ•+#""† òù矟<y266¶¬¬lÓ¦M$I:;;ÇÇǧ¤¤TVV~øá‡P8•••ÅÇÇ¿óÎ;ãÇ�Èd²Ù³gÿôÓOß|óÍÇ·lÙ‚¢¨F£ùôÓO/^ìíí=qâD“ÉôÙgŸåääÄÇÇ'''ÿç?ÿéÚµëÉ“' ‚˜1cÆ|`kk;{ö쯿þzÞ¼yß|óͶmÛ._¾¼oß¾äääÍ›7cV[[ûÙgŸ-[¶ÌÓÓs„ A4j­åÎ;ñññ3gÎT(“&Mª¨¨øä“OΟ?¿jÕ*‹Õ¯_?*dVVÖüùó ÅôéÓá±Xl±Xâãã»uëÖœpªªªŠ2dˆ··÷É“'>¼cÇWWW؆ âãã½½½)átôèQ™L6`À€øøøaÆM™2^ …AÄÇÇK¥R’$-ZôðáC(㣢¢´ZmiiéüùóàèrqqY»víþýû÷îÝËãñRSS·nÝŠ HÏž=cccoݺµxñâW+œ��®®®oˆ¹O$¹»»?yò¤U±¸\®——†a%%%J¥òO.³»»{aa!ÛyxxÌœ9ÓÎÎN¯×û‚8::®Zµª  €  &I’ÚÚ€Åbq8œF)›ÍfN×ÂbäååF(ÛµkGÕ Žã0©‡‹nnn>>>ðwii)Tì¸\®½½=¼¨V«aRô …B‘H›L&8ô¤;r8˜‚ l6›’Ó€Ê I’šnW«Õ”ë2¥Á[,XŸ�€úúzØl6S!µZ-A£Gþå—_¢££U*U«Ízb±¸ÿþð÷¶mÛ~øá‡Pwoܸ±bÅ øû³Ï>ëÑ£Ç?PöDGGÃö7pà@8ü_»ví•+Wà‡úÓO?åçç¯]»v„ ^^^ü1>Ã[<˜;wnII‰F£6lXNNŽN§ëÛ·o^^^MMMzzú˜1c|||V¯^M Ãsss/^<dÈ-[¶P–‡E‹-X°�ªÆ›7oÎÍÍ6mZÏž==<<x<žÉdºwïUàÌÌ̪ª*ê_•JõèÑ£I“&õïßÿìÙ³/^lhh¸yó&›Íîß¿?A%%%yyy“&M ƒ  z‚Dˆ#àïéÓ§O™2eÙ²eIIIgΜ‘Éd3fÌ1b„D"ùñÇ�ï¿ÿþ¥K—¶nÝÊãñ<<<ž={¶ÿþ²²2*ÁŠŠŠqãÆååå<¸¸¸øÜ¹s„j}jjêêÕ«7mÚ´wïÞ¸¸8åܹsb±˜êµÝÜÜàï=zPÖooïùóçïÙ³ÇÏÏoàÀP~9röŒ®®®T³‡� ®®.55•þ°={ö„o�ààà@EINNÖjµ}ûöl6»¼¼<''gÒ¤IÔûzåÆóçÏÿ ­Ýßß?##ã0 ãñx­uÙ@Q”Çã!b0è‹4^šÝ+Ëå Ø=ºQ�½^óæÍ´ç‡uêÔI¡PÀ>º¾¾žêÙy<^£ˆA´¼*=z%¢X, d”A\¾|^ ¤Ä@nn.”C€iµµµ0)z ¥R)”©PŠÀçÅqœRTb¡žE,K$J3…!IÒb±À‹uuu°0$IR’Øl6S¶P¥R •Ùl¦D¾J¥2z½¾¨¨¨¹ y‰p"I¶ ÃJKKÓÒÒ¨ìŸ<y2a„˜˜˜ 6¬X±b̘1çÏŸ÷÷÷ÿGI¦AƒåååÝ»w/))iúôél6› ˆ½{÷~ûí·]»v 6lزeËÒÒÒ***6mÚôõ×_ÇÆÆvëÖ-888&&æäÉ“ .\¶lÙôéÓ{÷îݤÖeggGuµ°U•––VWWGFFšÍæ/¿ürРAp•šš:mÚ´1cÆ,^¼˜Ïç;99.—ËÏœ9C¥°~ýú'N¸¸¸´êI …B¡5jTZZš½½ýñãÇ›l-Ý»wwqq9uêTBBªU«ø|~IIIzz:l”*•*==½W¯^³gϾwïÞ±cǾøâ ‰DbccC’äùóçׯ_¿téÒQ£FÑk`Û¶m£G2dÈèÑ£—.] §X8àçççëëûÑG:thýúõüñÈ‘#ß~ûí°°°&GîAÀÆŒ¢¨D"qrrª¨¨€ûuåää$éíí …“Åb¡ºH8T�tëÖ-::zË–-/­«øøø¨¨¨WW×3gÎ<}ú”{þÉ bíPJ¿ÈãñœsrrZ˜ Ü{³Éd©^ vÇNNN&“‰Rƒ¡M¸I«Ž§§gfffsÙQ´oß¾¶¶¶¡¡áÏ Ûa«j‰ê1›Ã`0”””„„„À‹ŠŠ¨ÒRy988@½�––Ó”J¥]ºt¡†8°QY,J¢ EŽãTƒ©««ƒÒAÊœPRRòÝwßQòjlZ­6++‹’X5550)hÇOñìÙ3J‹‚v`.—KÉNÇa‚À°r¨ß8ŽSªeF¦û…QÚ’N§£j•c&“‰JJ¥RQ²Â)===88�@ÍÐ?u•JõV³ÙÜÐÐðœ6<þ|II‰N§3 ƒ¶?ƒÁ ‘Hlmm¡ 11‘úíìì¦NzêÔ©¤¤$gggØJà˜…Ò£_L@@�¥E}øá‡ãÇ¿xñb×®]SRRú÷ï?räHjö¨ººzĈÕÕÕiii†Q)…B¡PXUUEµ¤–e’ͨQ£®^½j ¶¶V¡Pèt:Øõz}BBBŸ>}`ß4pàÀ!C†lß¾~p,†¢¨Ùl¾páÂôéÓçλjÕªFcjøñðx<úÈ+Îb±D"Žã¶¶¶›6m’ÉdGŽ£ZkF ?­àààƒÒ­PúÒçÃΞ= Ÿ9sj<8ŽK$½^ߤ ¢‘éûþýû&44T¡P :t×®]Iû HOOoÔ¸»»WTT@kN§ËÉÉÍ£%í ǽ½½srr^¼®þ�š“L°ÏjR2Á·Oÿ—2¬5‡¯¯/—Ë}ôèÑ+¯I³ÙLMX,¨¬4 @Õ³Éd‚‚@ž*Dý Füûb‡�†aô§’¥wT×OÝ%I’zƒTH’¤çK ìrÚu‘’(‹…úMõð‚P]ŠÙl¦¶6ëY§Oà §:@3�`Á‚Ö®^½ Í¡¡¡üÞ©ƒ)))ƒö÷÷i‡�øè£>úè£E‹1‚ÅbýôÓO;vlmŽ:.--ÍÖÖÖÝݺøäÉ“Ž1‚’LsçÎ%"11‘.™ _~ùeÿþý+**(#õ+äÙ³gï¿ÿ>lpr% àéÓ§?^^^ÖíõÂ… ÿú׿þõ¯5’L-düøñãÇÿôÓO—-[ÖÐÐpêÔ©ÈÈHë`§N¢;Mœ81'''??ÿÁƒ:îúõëô[t ‰î <8??çÎ/.ÏÓ§OU*U—.].^¼8zôè³gÏzxxlذáÏoŸiVÇXù kë=›ÍnäÜa˜X,†C`¡Ph4©7??_¡PX‹ @ÐäöÒ”¤áóùpôÖœ … ½ßwwwúô)= ´*ÃNÃ0‹E×{šr-áÅ…gøóù£®äÆ û÷¿ÿýøñ㢢¢W>Íûæ3eÊ Ã.]ºtýúukg¼sçÎñù|jä’–––ŸŸ¿fÍE<8cÆŒ¤¤¤Ö星Ÿ=~üxºÃÞĉÁÞ½{©+;wî¼uëÖåË—›{)áááééé-Ï÷É“'………ááá” 9|||.]ºTPP’’Ò¡C�Àž={~þùçñãǯ_¿¾Qø .L˜0!$$dݺuô뉉‰jµzèС/ή¬¬,99�0vìX’$wíÚ5vìØr«ã›››AÙ´iÓ¶mÛ"##›sj„‡‡‡§§'5Ç’%KnݺU\\ìêêúé§Ÿ>ü oƵµµMvÖAAAz½ÞÑѱ¶¶ú‘Âa{“JŒƒƒƒµä£`³Ù …¢¾¾Þ`049Ãçóq§rb¾Q™L¦T*¡xc±X2™¬´´´¹ìp§/µÚÛÛççç7'V% ÕB^ê)‘H –OWÍéyAÏ&ë·�ë„ÍfS“CtýƒÒ·àƒSc*YÊmkk -‚PcG•‡zNG=µ\.·V0èZ”F£Ù¡(JÕ¥œÑ53‹ÅBiEô‹Tié_½p²³³‹ŽŽÎÈÈØ¿ÿ±cÇd2Ypp0}väŸÀ»ï¾»k×®ýû÷kµÚÈÈÈ'OžtíÚÕÃÃã‡~HKK[¿~ý‚ ¨Ífrssׯ_?hÐ .—KŸYÄÄĤ§§8p@©T:;;÷éÓÇ:G›Áƒgeeíß¿?---** j?z½~ÿþý0LçÎáï¿ÿZ·e2Ù;ï¼COgݺuÇŽ#ÂÖÖvàÀ™™™û÷ïÏÈÈ0`€\.?~ü¾}ûöïߟžžîç眽aÆ#F¸¸¸ðùü·ß~»9%æÆû÷ïOJJ*((زe œ¤… Òc…‡‡_»víÔ©Sp¸ZUUE•?""ÂÇÇgÕªUYYY” ³†;6))éðáÃ¥¥¥<ðõõ ÖKÙ$a�3fÌÕ«W9²uëVúg™ššJfÔ¨QtsÊ Aƒnß¾ýbåiذa©©©ß~û-‡ÃÉÉÉñòòêÖ­Ûÿ\ÛÖëõ°k£&¥ìì쪫«mllè"ä:Y£ᤈ‹‹‹Ñh‰D555t-Ššº%%%ô¡d’J¥ÖÒÇq×BáD’ds’ 777jˆ’ÍAùà4EQÊ׎N“ôÒýî¬SÀ0Œ*¡¿¿?ÌÚh4þðÃðb`` ¯¯/ü]YY eCuuõƒàÅèèhº=†’(”P¤ä}VL$Q^ÔÛ$‚iÔÜ‚ tÓèK·'ÅúŽ˜Ò Ñãf·“ˆšÐ£^IDDD§N¨‡÷óóëÝ»·T*íÙ³g¿~ýºtéb4 ƒ§§ç|@ùŠüí)--•H$b±¸W¯^ptæââ2nÜ8ƒÁªÕj CŸ>}.\ˆ¢¨\.0`€³³3¼Õ·o_h&EQT¡P„……999uëÖM$©T*‹5bÄÊkÇñ:ôîÝ›ÃáˆD¢hqwwŸ3gއ‡ŽãÁÁÁ†ç899¹»»ûøø@7$ƒÁÀf³ƒ‚‚0 svv ƒ}4‹ÅêÑ£G¿~ýBBBà{ôðð˜;w®››[DDI’z½^,;vÀ€NNN>£õ$l|}úô!Â`0ØÙÙM™2¥{÷îðVŸ>}D"Ñœ9sècF³xñb8H§Êïîînooãxhhh=Pµ±± wwwÇq6B¡PA„··÷|àåågþ‚ƒƒW¬XãxIIÉÿûßÐÐШ¨(ÇýýýY,LŸËåRU Ãüýý{õê…Š¢2™ÌÍÍ*LçÎy<‡Ã ‡±PõòòêÝ»7T"‰DáááT*‹ÕjµÁ`£G†úß™3g222fΜ 'ÌÚ0í‘››ØhÂ#==Ý××÷³Ï>£`ùƒsÀf³™næ’ËåA­VÛ †aööö0VCCƒF£‘J¥:î•LTóù|ëy 8GhþÍ/…ÃáøùùEDD¸¸¸PKKKóññ9~ü85F©¨¨°6ã‹D"©Tj-‡¨X&“éźByy9Ì”Ãá´Á EÏ Çq¨™ÍfÊKÂÁÁšXÕh4P`Àµ𢧧§uˤœ šË‹ÃáPúP“®äô™*JcƒÞz ÈË˃rðܒšìâ“A__U2ö­hdýÁ«Åucõ`tex)÷ïßo×®³³3³tüåîÝ»ƒ š9sæÖ­[ß"M›6íäÉ“ÉÉÉmˆn4/\¸0nܸF*ÂñãLJN÷S T*•\ZNûöí­­v‰D£Ñ´¹ÁCËX“öCØÁÙØØ¼Ø+“ÉL&SK&w©4Åb±F£i¡òD ×6lØÐ£Gj*ëèÑ£C‡;v,ô]‚&nk[¢“““õZFÇ©XZ­ÖÚ¢åšÓËghhyQ+–iN¡¡¡4'¥Rùb͉ËåZïpÝœæDé¾”GTp)͉’s¥¥¥jµú³Ï>»téÒÔ©SU*›Í¾p/ûìlMCmaú½Óßlg¶/bh#<hÔï#rìØ±7ªçÎëÞ½;µôê/äÛo¿½uëÖŸ“Waa!Ãzzzæåå5éqãÆ&o5)BD"œ+jd¿2™L”©-((nJqttT«ÕjµÚËË ®ásqq)..¶NºþÒ¯¸»»ѳÓjµ”¥¨% úz¾–`2™šôS‡Š5& J…¢(tf�ÔÕÕY»cˆD"8íÚ555”áÚÕÕª ‡3/ÝÀ377ÚÇè"M¥RÁº¢›Î,‹uR2™ŒòPwpp ûàQ5%QèÎxTm˜L&ú¼õƒZ’Œ¢(lfôêåp8ÐÿåEâ–édÚ†¯¯¯µwÛC``àÍ›7á'÷&”gРApö±µ+ÌÚ�5€---mÎ[÷ñãÇ$I ‚öíÛ7rqvvV©T"VUUYOÐgËÁóõÈôžöqPzÆæ¤E#"� ¬¬¬‘쥫‘^+(ŠR=;õÈ‚Èårø[­VÃ5sb½T‚R±ÜÜÜ ŽB·¤½4•Jk†î”k2™àËj$¨’S/—nB„ë ¥ ÈK½áa!éûJ (J÷}€ÙQ aiqg„ÓëâêÕ«m¶œü]iÒw™)Ò+)I’Ô€º…4Ú;‡¾x¶¾¾ÇñöíÛSsÙÙÙÖ"­ÑÌ LªÑò~µZ 7ñT*•………”aÃzZEÑ&•!//ßñ~�� �IDAT¯ˆUk …££cNN˜s¹Ü:$''ÛÛÛ£(ÚB×M†7 F8µNפ7Ãk¥å3(Çh4R]¼­­-‡Ã¡&KØl¶Ñhlr9ÁK'–x<žB¡ÈÍ͵-Z­ö—_~i2ŸÏwtt¤{ôõë×ïæÍ›Ö*QËw¬ Dú$^¯ONN–J¥l6»I+bÛFM^¤Ä?]“àñxP™àp8ô*¢;p¿¸ª­Uúø�ªÔ{¤vÉ£’¥v²X,Ô€†ÅbÑu>¨µ b}é.ý:]¢îbF]§~ (J¥Ðä³´däÁ§6òèÑ#ëE ¯[[[jZûÅÀ™ªGkäüíææÖ¤†Ô‘Ynn®õšÙ—ŠÕF¾æÔfq†±Ùì–ï‘Úêêê¬ílmÃb±4éh±X¨ý_èDEEÁE5:Ž’š|>z„šÍæÛ·o¿ ;‚ ¬§¾è¿* Ê5ššgª¯¯·. ‡Ã™<y2üÝÐÐ@Í&Rë/Íf3u‘Ú™Ajeý»¸¸PB‘’=t9DÝ¥–lÂA -]~›L&úZ(F8½J˜“pþdZ{î‹í‡ÖÖ¼ÖB_3 ]ç[å° ‰t:››[NNÜâí10ÂéÕÀœ„ËðgÒ†“píìì”JåBñx< Ú‡ô5³!!!wîÜi‰êÃçóQ…³SB¡°}ûöp©²Ñh´³³{±X,†‹Ï˜ÆÀ'†ÿaþø „ÔÂI¹\ÞÐÐМO©T:88P›^¿8Ahª¨¨°³³»víÚØ±cÓÒÒªªª^ºw;Ý‚ÔàÞÛ/ØÅ¼…AwýhrÚÏÆÆ†r{£\û¡6Í¡–î"B­×®­­¥äqYY™õrWGGG¸çI’T,¡PH­=zöì4—Ñe¶››\ŒaUZúNáÔŽ´ô…±ÔÊYE©ôQ¥P‡KÁ —áEjMI’Tóhhh ]¬×9ñG·/*((€{H�&L˜Ð«W/�ÀŠ+P¥Ÿ…ûöí+V´ÐM611ñèÑ£ï½÷ÞÿúPëÖ­³ëM:õúõëôIÝnݺQ–_�ÀÚµkµZí§Ÿ~ ÿ½xñ"< "¶oßž‘‘Ñh+ë 6lذ¡‘®6cƌ˗/çççÿç?ÿ)//ß²eKÏž='Nœ�øúë¯?~¼iÓ&Ç—/_Þ¡Cú Û·o/((صk—õ×o�\]]—/_~ëÖ­„„„qãÆQçÖ×ׯ\¹200pÖ¬Y�€„„„[·n-_¾ÜÕÕµ®®Ž¾y+l3[·nµ>µe„ =¢›ž‚‚‚þõ¯ýðÃô£‰d2s¬e›±>¨·µP]œ$ ú#™LF¹ª:::Z,º_ƒL&c±XÖ¹ÛÚÚÚÚÚREøíܹsN½Ô\IŸCÂqÜÁÁ¾›‘5ô ³ÿf³ùÅ�$ µ¶šîwNuâð+À0Œ:âòÙ³gTÒäË’Ë唜hrívee¥µ°tuu…“Rt— ºp¢W#å1A_@_¥D¹9PrˆÇãQ{FÓáR/ˆ$IªTôÝÇ)á÷Ö{±Nÿ¢UMMÍôéÓ³³³GŽi2™–,YýpNž<yúôizÈ‘#GZïÞÑYYY /މ낎9²G ÅÅÅ#GŽ9r¤««ë¥K—† 6räHooï­[·RGá­^½zß¾}ß~û-<8�žžž P(`ôøøøE‹•——'$$èõú‘Ï#FŒ þ…R¡¨¨èâÅ‹ ‹¥®®.!!áÎ;0Ùëׯ'$$PçV\»v^ò .$$$X7Ž­[·~õÕW}ûöíׯßîÝ»·lÙ’“““@—µ:.!!š}½wï^BBBMM I’'N¼wï,!ÕfàY‘‘‘0x×ÍÍíÚµk QQQð Ü äñãÇ ðp¦ýû÷SZ2¼““ÓKƒÕ××S.Ü9Š¥R©ÊËËé» jµÚÆ[9$��€F£ùµ/^�À¯;[üüü6œ~ 7µzqê€"jŒÈ¼î¿ƒY$ÉÁƒcväÈWW×ÀÀÀ%K–¼ÿþûÔ�Ó§O1bÄÒ¥KO:õã?~ûí·0À;ï¼³dÉ�À’%K`éèèxâĉÄÄÄÏ?ÿ�°yófOOOjûµÿE` G‚ŽŽŽôÃÅ�‘‘‘Ðd_^^N­OLNN>tèH$¢„¤cÇŽ0ºÙl¾{÷.Üʺ}ûöô4©“ Î;wùòåÅ‹GFF¾ôHRRÒ'Ÿ|;úåË—7yÀè§Ÿ~º{÷î;vÀÖýýý…Ba“ç65Ç­[·ºtéË|÷îÝcÇŽ)•Ê�� Û’\.oTKaaaÖ;‰uîܹ_¿~&“ º3êK>c÷ññi›ƒ^¯on N‘H$‘H¬½±Íf³R©¤Ô¦‘3[ fÿ€Ã@?V¯×ëTàŸ;±ÃqU“hî$\A ²õÒ§stt4 Ð!n$Ëå(Š6·­0Ã-œ`ŸÛ¥K¸¬Maa!lv«V­š?þ‚ ¸\nYY<í´gÏžjµúæÍ›/^\´h—Ë-**Š‹‹;}ú´——WPPÐØ±c:4kÖ¬uëÖ-X°€Úüão ÜÍ J5ž7oÞƒ¼¼¼¤Rivvö¤I“:DF)‹-µw¯Ùl¦_„+¯^½:kÖ,xºõ¶WÍ¡V«‹‹‹¡·°°°É¹ë²²2•Jw’4/Õ‚ ÈíÛ·£¢¢|}}Gõá‡Θ1ã¥GlPÛp¡(Jiýð"´Œ¿th³ÙÜf;„ÙlnÎúßÜÆt|>ßÅÅ…:¦ÖÓÓ³¬¬L«Õr8œ®]»Â]šœœœŒF#T‰!³Ià�€�{�Š�hÁ&yÙÙÙÀÑÑ‘ÛÁO€$ɬ¬,kw$x—¾Ö˜.~’““Ùl6<# Û6ÜÝÝ©#-(¤R)uŒ}yYsj(üagg…ÃGXÛ"‘ˆÚ>ÜÅÅ~A‹¥IaIIM; øAjä'—Ë©RQ;…Ó®  tô d±XT'#‹áÇ(‘H<==Å2›Í………Ö—D"oŠ~L;üÆ_<'ÚÆÏÞÁÁáäÉ“çÎ3 ôn®®®úö蟣V«M&“D"±··§ŒÔЉ^(¶ðÿQÂÃà ‚(++3fÌš5k „ nzh6›é¦åË—Ãóè|||¡¾òí·ßRÔŸ~úI¡PdddŒ9rüøñ­=¼ŽÇã?~Û¶mp“|¸ó•?²¿¿IIɵkצM›¶{÷îµk×Μ9óÅoyÀ€ðëêׯߎ;àÅùóçóx¼ââb—sçÎ1âçÅ$ÙÇQx„Á šP(”J¥TCʼnDþþþz½Þ¢$‡Á`xòäIpppQQŠ¢uuupˆ:¤¦¦‚¹�œàG�H�¾iÂLGŸª¡.j4ú®H¥¥¥8Ž7¹¬¯¯onn®5—IŸs‚‰C‡õ?2E_K¿Ørg ªë§ŒDß%ˆJŸ~*n“ÅbÁÀô 6JºÐýèк¥¯ÌmôÆ ODÑáRy5ÚôˆJÖúâ«N/ ¦¦fÆŒÐÂëääô‚SRþöܽ{·ªªj̘1J¥²¨¨ˆ$ÉšÿgïÊ¢¬Ö÷™}˜aöM5QQp_ËÔ®VJ¤•e^35Í¥®”˜Kfiefv-¯åšÝЛšK–fjn¡¢ û³Ï|3¿?Þ|Ç™aÀµÌyþqüæ|ë|œ÷¼ÛóÔ×ÇÄÄ�%]\\\SS.xW­Zå(WøÂ /¤¥¥Ñ¯TVVzm;úöí;jÔ¨S§N555­Y³æý÷ßo©“ÿNpúôi‰DÒ¿ÿ>úhÞ¼y‹/îØ±#„õZÂO?ýäÖûôÓO 4~üø‹/æääÜI³m™dCBBp=.†¡ÍCSS“c©‡Ã¢;£ v\B|}}››››››/]ºD!ZBª‘Râäb$‰L&ƒÂw 3‚—Ãår9¸`¨ÆŽûÝwßA<¾ …‹¨W¼hý\7þa½¡C‡^¹råôéÓ yyyׯ_ïÙ³'ø˜ƒá—_~qº—Ï***Μ9½Ð6›íÿûóààS§NuìØño,Q²bÅŠ1cÆlܸÑh4;vlÿþýP£˜››Û»wï÷Þ{]øV±k×®ùóç¿òÊ+̳ƒ\.ïÕ«WIIInn®Ùl®¬¬LJJ …ø7²nÝ:>ŸzNŽèܹ³J¥:vìXLL ‹Å:pà€SÖT¡P˜œœ\UUuñâE@€/†Íf6lX×®]9òè£^¼xK=o[·nõõõ5kÖÁƒÝ«w‹…Žyxxèt:»’9Ç>'‹ÅRTTã4 RYYÙÐÐ�9‰Dõ]¼\BöòÍYV»v%0c^^^‹£^àå…B±XLèÀ2Ñ_ÖÕÕAîÊÓÓÓ.‰EëçÞhñY¹\B· y†öof³©NѺs88‡ÃÁX7—ËEÏI¥RÁѰR†qŠ”Édp£ÑˆT*„öNèêm”± 2½^vœ“éõ Ã0È+A3”Ãaéø0í!ß«ÉdÂI§Ó¡÷vËÆ‰Åb}þùç³fÍš={ö¤I“:d³ÙÖ¬Yš%F£ñСCMMM;v/öJIIÙ´iÓ† ²³³Ïž=»dÉ’~ýú;vl×®]~~~K—.]°`ARRR§NºvíúóÏ?_¹r%,,ìaÓÏm;2337lØ�Ÿ'L˜0sæL¥Réáá±&•<wîÜqãÆ½ùæ›z½þܹs‡öòòÂZÕ~ýú=ñÄ^^^-¥ú&OžÌb±–.]j6›Y,Öúõëßxã pÕùåŒÿ¼ôÒK‹/0`À¼yód2ÙÏ?ÿ¼}ûö°°0›Í–’’rôèQ¸¼óçÏ'''·*AùÕW_A1kXX˜kË–�‚–·Zóf×ô ³¿——Wcc#Î2 m�s ~Ek{Ó€0�|}}Qi"** sT@"‘8µNv{B¥R©Õj½^ïååÕÐÐ�sHrB@ý&.©TjgœZ-oR©´k×®xýØÙƒìD:Î1?×ÔÔ„ì…íÚµƒF%6›ÊO´(_·nÝঌF#þ”þî,‹Ó‚±X 9!µZÅ#III`iãd4iÛ€Œ|˜R‚¤˜Lºg ‚F×l6£ÅB7—aüL@!+N‡åòƒÁE²³uÏI.—/_¾|ëÖ­Z­611qÈ!ÑÑÑ„×^{Íf5jÛ¶m£F4h¶é,Z´¾ÂÂÂF uY\.·¨¨H¯×¿õÖ[S¦L!„$&&.Y²äôéÓO<ñDK«øÞÞÞiiiðpp–2d¬hÂÃÃÓÒÒyä†a|}}QnØÇÇ'---&&ÆËË+--Í.r=\ŽÙl¶7ÞxÃŽæ‹a˜çŸê* !‘‘‘2däZ%IZZHG'''û8eÊ”ÊÊJǰï¤I“°Cåí·ßNIIÉÊʲ»Bˆ¿¿?ž(111** þV¬XñùçŸÃHú×)-- ó¨`n¡ÜÆÃ qÀ€‰†q8œ´´´¶:»á:· ½ôÀµ­D"ár¹à¯Ø‡žåñ+“É„³L@@@ss³X,®­­µ›k LL$Q.bþã˜NS Ã86<±X,LêÐÚœÍm6Ûm½”—— ”Àpã/Ö?}öìÙv§N ¿b³ÙŽJ½õéÓ§OŸ>‡¨T*íîúÉ'Ÿ¤#{ø-Ö‚Ã:·ƒÒÐÐPÇ' Êîvh×®~ sÜK,ãF,ÜwÁ‚3qâDú¿qqqqqqmy1`ét»Ó¯Z}1œ¾Nn8Âjµº®Š¶Z­võ⃢p„R–#7cÂî+¨Ý‚%0Ö§Ñý¹´a«¨¸¼iÉÌ$kÖBȘ1¿ÿN(aB'¡'tµú½¨ÿ¯ËQÔÿ®qj ¶mÛvøðáýë_Ž¿n¸áÆŸ‚ÀÀÀúúz¬¤¥Y¢èEI$¹\n§LÖ§OŸVu{ ›Íöôô4™Ldâr¹ÁÁÁÍÍÍþþþ¨„KéÜ9jÒ¤+JåÆ)1‘ÔÖ:1NŽäß"‘ÈËËëN”/üýý›ššœÒŠÛ…[RÂ…Ê™GFF¢ƒ…ô UUUŽ""‘)ä}}}i}[4ŠøeÚ=<<P?777Öl6E‹ ‡……A%·ÑhÄw‰D‚7‚7NÈyzzÂg‹Å‚®\¹o…P(ìܹ3.k0@ÅØ°ÈŠÓÈjµâÏDSÂ#·›ÍF²sºäï^§ÁƒÇÇÇߪšn¸qP[[ë´µ600P£Ñ@f"§M¸YYY"‘H¥RAn ´q›ššè®Xh©¯¯¶Z­:Ža˜ºº:¥R©Õj;wî\]]ÖQ.—åä]»HZ¹¥&ˆÛP[w4<­Ò¸µ ³ÙŒ‘À€�< Ý™G³É8š1,£€µî…‰·ÚÚZ´8‰ët:8/—ËÅT1ÝÀ#‘HÀ8a&ŒPzN„Ê ñx<Tªåóù¤Å{Q«Õp.;I\ ÿšÍf =Bèì‚¡µÛõz=Þ—Sú"0i÷\ ×ÇÇDZøa€[ ×ûŒV©QíâTލ¨¨°mÚD† !0ã°X6Ël³‘›ë¦ša±XÅ‹al6[¬p­Ö+Áu4›MX,+Ãq8V«ª¾Y¬&‡Ølµl¶õFM‹Í¾À«ÑËŸ©{ÿµÞÂÜéïé<ò¡Ä0ØÅ-°Ølàzk¥ÆŽÃ!+W’>hé{§‘:˜Ý’7ó°Þà ·.‡ÃÁ• ÷ w¨ÒbµZ‰DBÆŽ%§NÁ9::º®®CR|>вl„HärhµQYYI¤aÓÌÓS«ÕšÍf@`³Ùd2ÍîJé[_‰ì!{™øù—ÿ×$=[È÷öoØ (Dî RtŸ“üóŸ¤5’=G�}Q‰qY,–D"q”Ô#Tu†P(ÄÐIóù|@Ó.àH·^¡� P(Ä‘PÙHnîÆåñx8�K;(v\ãŽw„¯´y …p.h³»AúP4Fçè� xÄ<"]žg2™î”•Ü–páÂ…‡\Í×׋kÝxIÔW•””@,ˆnÂ…q™LV__V ¦Ñ±cÇ>|¸¤¤¤]»v@MmWô|éÒ¥€�B! RIü½ˆŸ³P‹‡‡‡Ãáñx7µîâåååããƒÿÅ‹‰D-‰Ö·*­{K¡B±X<räHŒ‰i4,[GrnúÏáêÕ«05‹Åb€í>V«6�Wxƒ ÂY-1]Ž„5ßR©;¥ªªªà°f³ŸÍî´; ㇴ…ˆ»Ëb±0{$‰0ÆÈãñà µZ--ª‹…õø¶TWWC­ ¡¨’hú"XÍ´Dêè6Nw„^½z=´J¸ ÃÔÔÔ¨T*×If7þR´ºLú‰'JÚµ„   öíÛŸ;w®¸¸X øûû777ùå—ðmvv¶O¯^½ ûG"‘Ð+hBéKvÏ#] yœÏ?'¸ôöôô„Ö:6›Cˆªª*GÒ9Ž5äFׇÃi»î»B¡ÀÙÖ wXïÇC«„«ÓéŽ?>nÜ8÷;ð�Çãñx<Ú8‰D"°LHáéé©Õj===kjj¸\®L&³›²³³³‘ˆÏç744ص»j4š‹/âJè´Z²cÇc~#äã#ºxƒ‚‚***är¹N§F‰6†Úl6[Kk# és4r. •JÝÆÉmœÜpÃ?Ž­Hì‚)  €ÏøA.—C!–ŸŸÝië”z•PY šîA£á|uć,¨$„ì'dÿvB²ÿÌ0Œ£„®J¥ª©©q–h©ïØ–á3Pb·êâ;ŠaÒ`±XB¡V�@önÔ¤+è\ŸÏ§ël6J,c‘ ÍÞ‹i-™L†DD4“&À£¥(F#ëëë1˜�§àp8µ£kçð †Á`,bÈÍò¸ô{…G°Z­xÌÑz•\.×jµÞ&+ù‚ Ølö²eËà¿ßÿý¾}ûþùÏÆÆÆÒÃŽ;¶}ûögžyDrݸ×(++£5ˆ_z饸øx÷cyÈÁçóûöí{üøqø¯···^¯·›‘e2™¯¯omm­š²"%%%H³ ù ð]Ìf³^¯÷õõÕh46›M¥RÅÇÇ=zÔu¬L¯×_»v ús1ÛV^^îçcëcó;ïwñúENH<!™ÄÛÛ›Ž+*•JࣃD—ËU©TN›œ ¶Üê“‘ËåƒáãÏ,‹N±X,4NhZèBj¬ƒàñxhœ°å‹ÅbaÆH$a°4ÁÔ’|°V¥ët:¼£¦¦&ð†iM[;>466bš\,ƒÍ‹ÅØ…•âp¿°Q«Õâ}Éd2LJ¡]–<»û²Ùl4C ÚoÌ¥A-»ëRò WFF-w›••µmÛ6GO¹  `Û¶m4§½÷jµzÛ¶mUUUãÇ?~<ŠÁ¸ñ0õœ<<<|||´Z­cý40¶Ñ¦ÅjµB,Ëh4:­,0™LÍÍÍ:N¯×755effº&Px饗:vì(•J …X,Fil09… mÏÙ¬'¬ä!_RæÄeáfB°çAi@PPÐ-š3¥¦¦Ûì¾rã/ŽÓž={jjj^xáBÈwß}÷Å_,X° 11qòäɉ‰‰‰‰‰À’‡˜3gNbbbCCCUUUbbâ‚ !6lH¼–Ä.ݸ%Ë”ššÚ³gϵk×0`À€g‡™ŽÆ ŽZ­¶±±Q¯×;ÖA™L&µZM[›Í¦Ñhd2™ŸŸŸíZB, ³ÀÀ@.—[YYé:ÎVPP�,š°@Æ÷åË—­V«¦\Sw¸.?/Ÿ2P50\N¸ˆ‹Íg]]Ý-UÖÙqëá‡Îçóï„iÂûŒÃzQQQ‹úÃkkkýýýçÎ{èС£GšÍæääd‡ƒ\m%%%—/_¶X,‹åòåË_ýõ[o½µxñâñãÇ9²GHKìÆmÏAeeeÕÕÕdfÁ‚“'Ov·uã¡ÂmTèh4»¨×¸qã¾ýö[T«#„TVVÒ7}úô9rä!Äßߟ¦Nøå—_°ZÚf³¨Õjˆ¬°Ùl†až11~„¬9~¼%;ÚØØˆî]Wm‰DâççwŽ:iCC1<èÔÐ9rIµoy Ïf‹D"´µ´B zœ Ã`,.00þ* ÖwxyyüQPÿÿ?“ÑhÄ~~~4£Ãz!!!vc±X˜Òjµ˜ðk×®jj [ŒÍf³á†††"Ãæ´L&Ì‹Åb¸/ZõêbðjÁÒ üÑÃÃÃa‰L—¨èõz</þ|t´°-ÂŒ® "hoÚÓÓS*•®_¿þ­·Þ2™Lõõõ‹Å1ÅjF0 °Z­ŽÜnÜ*”J%v|ðÁsæÌñññ5j”ûɸá"ÌåZî–nÞìÚµK Àœâçç' !+ÂF£ñÈ‘#  u<ÚNãââ@Á²ººšËå‚8,X…Baï޽ϟ?èmq¹.äìJÛÿªºq@Ü¢Õj!˜™“MZØ‹ÜHüÜ9£«SÃæ¨ŠD¨nb6›M7Æb©Þ6Ã’c±Å•NóÐõ(D úôvFÿ¸´Í£_¼�Lß }1ôÍÒ?\ }.§Ÿ[M2µ5¬Çb±<¨Õjûí·ÂÂÂiÓ¦=ñÄyyy£Fzþùç!j×lÞ¼yêÔ© …"!!Á=SÜùºø·ß~¹O7Üpœ¾éŠ2œ8P¥Å)ø|¾£ Zxx8¬Ó+++‹ŠŠJJJì—2™ ¯P@{`*•ÊÛÛ[$õéÓG(ÆË—/Ïœ»t)éÒEåJÂÍÓÓÓ1½¯T*ž®¡.— ët___ô9Üø;„õ!B¡Ðßßøðáaaao¿ý6!$--íêÕ«yyy‹ysíÖv¢¥¯½öZJJÊO?ýÔRá©mGSSÓðáÃøí·ßºŸ†ŽfF&“Ùµ†q]¯$•J}}}!äe0<<<𛛝\¹¶l6[¯×Ëd2½^:~À€íºÍÍÍ¢9Sôz½ÅbQ(ÇŽyޏ¸8//!dÔ¨êÿý8]bI¥R†aBBB®]»…‚ød§Û¨i‹"¹.”¥R)͑چihh HlåÖsJDDG´ðà:>ÓÑ-6›6`y‡ß­)Ã0x³èxÑeë(J‹5„pU¸oµZq/¡PèèÄ཰Ùl¼$¶€G~)<¬V«E' Ý) �›€Â†x®††£Ñxûbƒ …â­·Þ8pà€FM1bÄùóç¿úê+¡P8vìØ¼¼<kǯ0‚ "¹Þöѳ�� �IDAT?ÿü³F£ùðÇþøã»g;P(?~ü… >ûì³Ó§O÷íÛ×-Sâ='¶Dçã”Á­¯¯¯¯¯÷ðð€Þ[±X¬Õj- /ðx<.—«×ëE"‘Éd’J¥MMM*•ŠËåbñúúú‚ i×®H$ÊÊÊ‚œSuuµX,6ŠCCÿhtõðð v6F,‡‡‡×ÕÕA¯X,æp8ÐÌçó¡Û¦¬¬ÌÛÛ›î˜i Xºíú õ[á\N‡™ÍfZÏ^ `Æéš»®®&zºÅ ?°Ùlü³åp8h¨á¦d2 lFðYi[¢V«ñá›L&8‡Ã¡¯ mxåѯu”«ÀRo:i0p¹ÃårQ[]] 6†Íf+nÒ9'HëÀ»„•÷/^¬®®vkm¥ 7 à­·ÞBmÉ“'óx¼šš@°lÙ²íÛ·BºtéÒ­[·N:ñùüºººåË—·k×.22²wïÞ w«×ë_zé%”(tã¶!‹—-[öõ×_ëõú^½z 0À®í̇<O¡P´]ˆ�°¤Å ‹Å²#ÚÇùŽ\ZZÊf³ ƒcݨQ£Îœ9Ãçó"ÏËËK*•ŠD"¡PNXÇŽ>íÛW÷éÞ½}Ÿ>ÂÇó33o:‹Åª««ƒêÐû!7òôÔÜRÞÂÇÇG$•––¶d·«ªª¼¼¼°ÁNØþ–2"nü™a=BˆŸŸß¬Y³è-)))ø¹¥¯p;‘»Ÿò]„···Ýcwà BˆÍfkK° QUUÔ °ò¥³JØŸ‹[T*„b¬V«£e ’J¥B¡ÄdóòòJJJ f¬¡¡ÁÃÃ#44´¬ÌüŸÿôàñŠjj4ßßP[k_Sr·2™ bYjµÏEÇ*[ª,‡exhh(oì`0\<%†ajkk݃Œqrà 7X,–[-ˆU«Õ×®]s¬½Æþ\DSSSKuêAAAƒaß¾}O>ùä… NŸ> ^¾Åbill šó’}s3ÿÅ¥åå…ÿû_‹W2“ÉÕjó‰L&“¨T•F#WBaN.Y,Vdd$»£Áçó###ÑßÊ%|ìè‰b¥†T*ïa,Q‘Ëåø6tìQ.—Ãè©Éd‚�Ý¿¥V«ñ×9sæ d’ E—.]ðv0ÿ„çâñxXc‚>¢@ À÷úúzx€® 1˜\DÒ#úø999àU ‚!C†àÓÀ§§P(àtt 3<<ÜËË‹q'7Üpã@»nK~˜]ÂÆ.›%—Ëår9L—555f³9::zß¾}1118Àd2566VTTtèÐÁf³åää•–r¼¼H»ví ×åôìááá•••®ùîðª õõªÈH“R GkIgÝ5bbb\б³Ùl©TŠƒ–P¢ ÁÿVårK�¤R)f\èÖ´sÞ³€Ät6› ó[´”IUUü4V«•½ÅSã1éLÊXÐõåôÕâgèÝÆ%  ïW£ÑÀ“ …h“è§!°° I¤R)]ï6Nw­®Ífk)uìÆƒõ; ¹\®P(®·Ü'Ô’ƒÖËl6wèС°°z3Ùl6ô†a³Ù&“éÚµkf³¶[,VBHaa¡Õj¥õ÷h@-†‹R®.]º\¸pÆ0&SuuµíÎ8Åóòòî\ÊÝ» ·qºMèõúäää‡ù ´½0ìn®O}xÿb¹\Gb³8>ì¥%7:CíBs, Úäoð¡]‰‰‰)..Öëõ‰$..ŽÃáœ:uªªªª{÷îíÛ·onnž0aÂÒ¥K»uë–&Ñë ÁtèÐì–ÝÁ†éÖ­Û¥K—Zú¹í*Í@$þNžªkË­iëØ—J» Ž-´„jAµëz¦;v³Z­V¸¶–c¥R)øFb±Ø©ã‚îÊîRé.]ŒÚáF.—‹uíØ{ÛÒpz_8QÐþi™TÞmœî.\°“û|ØàããsŸ•p³³³‹‹‹ò†J//¯îÝ»;NÖ!!!Ž)“ÐÐÐ+W®À”ꨋÅ6 ‚ýüünÕm¹†ÍfFTx :uê!D¡Pðx¼’’’ææf†a–-[æïïñâÅ   BšhÅ…+c6›¥R©F£ f:1æše\"‘Ü]L†aÔj5jÚŠÅbÔ™¥m¿£HI …¨‹F‚Ífãû,‘H`�Ã0ŽuØ4}m0F… ¸òÀ>':<K ?* ° 4;„jÉͤGþþþt]; ¦o–®Äu}_ûöíƒè±¾º .æº<Òmœn³®Åb©©©ñ÷÷¿ÿJ¸ íÛ·8»Õj­¬¬ tlß±X,v– zfóóóAÈ@­Vëõzœ›¼¼¼*Øl6›Dï{µJЩuèÄÄ©M¡Päååc§Óé°u·S§N?ýôS@@@AAV+i•áA&“ùøøûøøh4h§¥“ «Òé-ìyzzº¨Ýa½¿?f%Ü_ýõ®(áîÚµ«¶¶V*•>óÌ3îÇî&“騱c&LhË`¡Pí™`œ8ŽÉdB%Ü’’…B£ÑtîÜ™6NÐi ,S}Xhcª©©¡å%ICC›Íöòò‰D6›­±±Ñ××7 <<üÌ™3àñTUia!®P(4SvhWÂÖ¶´ÓÒ‘¥ÂÂBè÷´³C, .„B!võºá6Nn¸a-[¶TUU±X¬eË– ;7îØ dµZA]£ÑÈår™LÖ|#ðb2™áÓ^)ÀRcƒÁPZZjÇãWZZ*zõê¥×ë#""€ÓH­V{xxÔÕÕ]¿~]¥RùøøRƒ¦¢¥‹ÇVâÛîŠÅJ0OOO³ÙŒ.¾Ó⺶.GƒJKê §´ªô‰pQ…e{<÷BYš1ˆ.£ëúð¼Ð\ºNIfiÒ£²²2Leá3 €Zs†aœæ,ÂÃáܺÙ`cpp°R©„+ÁÅ ŸÏǼÀÀ@L“%–••Éí'›Í6mÚ4zKjjjfffVVÖÊ•+åryQQÑŠ+úõë7a„¯¾úê×_…aJ¥õsZ¼ÿþûТáïïÿÖ[oB<øßÿþ|üñÇøãBvîÜ „µk×r¹ÜË—/øá‡8`Þ¼yô)öïß¿{÷î©S§BâG£ÑÌ;¾9r¤#SÔ¥K—Ö®]KµpáBXÇÅÅMŸ>}ïÞ½ÿ£ÚO<<<Þ}÷Ý{ú”vïÞ½hÑ¢ØØØ€€�x¿ï.Ο?¿aÃø<sæÌ˜˜³Ù<cÆ ðÄO :”žÐ-Zd÷ÕÛo¿ LðQQQsæÌ±;…Ñhœ9sfûöí_{í5زqãFð„Báš5kèÁø ::zÖ¬Yô‹±dÉ’{!Ðe6›aÖ€þÖæ³žc;­Éd© ÷B‡•Î.Ь6„   ¡PXZZêááa0Š‹‹#"" (×ÔÔ¤ÕjƒƒƒKKKé|aKuä¾¾¾r¹¼¤¤„–“�Âx]ƒƒƒËËËY,–S‘\‹rýúu8>ª»üüüÊËËí.¾-�½;C(r >Ÿï´&›~UP1§iz/´C4áÊXØl6tõÓ–P èt½—ËE“†‡¢3dùùùŽ a( –Ž·ŒƒæÓßßî–A°Q&“áüæççFÏxUUUÈ{t;žÓŽ;Úµk·jÕ*øoDDÄG}tðàÁôôt³Ùü /ðx<øs=sæÌŽ;V¯^î¨Îû°aÕªUk×®]±b…\.ñÅ­VëâÅ‹/_¾¼cÇŽ×_½OŸ>v¯ïÿûßôôô”””ÄÄÄ©S§Nš4iË–-•••;vìøÇ?þ‘ššJA…fBÈï¿ÿ¾xñââââÂÂÂG}ŒSJJJqqñš5k>œ––ÆãñFŒãÕjõ¤I“êëë³²²BBBÀ8½þúë_}õÕ¶mÛŠŠŠ@÷ý±Çÿ™çŸžÇãÝkã´hÑ¢>úhÕªUO=õÔ]?xnn¾>eÊ”?üðå—_þúë¯}||vìØ³|ùrx¥é¹#55µ¹¹yÙ²e{öìY¸p¡@ øñÇ7nÜøù矫Õê… Bhû4}úôâââãÇ÷éӌӗ_~¹råÊW_}566ö™gž1›ÍŸ|ò ŽïÝ»7(±jµÚ”””äää®]».\¸°ÿþ?þøo¼‘ššº{÷î{÷T[[‹ŽQ}}½cê§¿zM[¶M›Z´%0gWð'²‘@ �©¡'Nœ:uÊÏϯ¨¨È.’ý¹vËg©TJç½$‰¿¿qq1º ’Ëb±œfl6[=·ž|DÈ«„¢}JKÊ9ðÇW-µÙ>èhnn>räí9±X¬¤¤¤ºz¨•°žL&ëׯŸÝF«Õ:räH@°yóæÀÀÀ 6ìÙ³çƒ>˜0aÂj™¦OŸ~þüy‘H´iÓ¦§žzjÈ!ééé·}´œœµZݳgO¥R©Óé.\¸°ÿþO>ùdöìÙ3fÌ@rÆÂ‰'Ž1búôé»ví ”ÉdB¡ðäɓ׮]›9sæÈ‘#—/_N/¥“’’BCC?ûì³+Vüç?ÿY¿~=~uòäÉöíÛ÷ë×/>>>%%E¥RÑí+V¬8yò$®îÁ«0ýúõóòòª««ËÏÏ ËÔÔÔtâĉ{ýØãââòòò°{÷î»{pµZÝ·oß~ýúmß¾ý§Ÿ~ÒjµÏ?ÿ|``àöíÛCBBpäŒ3Ξ={àÀ5kÖˆÅ✜œ/¾ø¢ªªêÅ_œ8qbûö틊ŠÔjuNNx½[·n]»víܹsˆ‡ºzõjuuu|||Ÿ>}l6í'B:vìúõëºvíZø­§L™Ò¯_¿mÛ¶ét:zuyK ….:IÉÍì -©DEE‰Åâ=r¦OïØÔÔTXXx3ÿœ“Q­V/Zt)6–L˜íG;v¬¨¨¸~ýúÉ“'+**êêê¤RiHH!9v~Œq*--Å•P(ìÕ«WYY]S®ù†¼Hlõ¶–QÍ–fÒãÆ" ±’VïúA‡Åb Þ¸q#èzÐ;·Z1NV«ü_ä£%„ôìÙS"‘üüóϰÐnll4Ë–-[¹r¥ÙlÎÎÎ~°LÔ¬Y³222öîÝ;iÒ$­VëëëÛvµª6”+7mÚ´mÛ6“ÉôÃ?DEE™L¦¢¢¢ÚÚZ/////¯Y³f8p ¦¦&33S£ÑÔÔÔ?~<99Ùl6ðÁ=ö›Í...†Lott´cüz*aÅJó‚p8œèèh»~{hÛFEm:°síÚ5.— kü{Šçž{nÕªU‘‘‘qqqcÇŽýî»ïîõKKK›››‡ Æ0ÌÓO?––Æår«ªª€b.::Újµ~÷ÝwË–-[´hј1c äÒ£GµZýÈ#¼ÿþû°r/**2ááávõŠóçÏ/**zöÙgù|>‹ÅÚ·oŸS QPP|òäI= ___쥿 Fº"œnU‰DW¯^åp8V—lÞ,«¨¨(%%ÅdÊúþûl›ÍÆ0Ä1/ ‘ˆ#" fÏ& \¶Z­R©õ…âòó/FG‡çæ^®¨¸vé’Üh4æçç[,–=b³²²¬VVqq›OÌ\BD¤sçι×sl#¹¹kËDLäFXÁÈ2žË9çããsÓ˜i„œ&DIÈï„<FÏBÈÍ—XBÈB¾$ä$!jB¶ºzn]ºt)((p]wÊf³iÉ+Œ¤Ña=¡PˆI8ºK ÿ¾0¥D¨d”ê?؈§3™LPÃBWŠ …BäÿÆ4•D"Ñh4›7o&„¼ð À.o÷'Eá(ñEóJà}‰D¢Aƒá{…!ÐÀÀ@ ëáÅœ8qDI„Bá“O>‰>:†ø€ ‚Ṵ̈âz)Æm56Ò»woBÈ´iÓ^zé%ŒÿšL¦¦¦&0NóæÍ›7o|Õ¾}ûîÝ»_ºté2N:nûöíñññ'NœèׯßÙ³gïú)Ƈµm#FŒHHH�Nš`òñññÉÉÉ×®]ïæÏŸ?iÒ¤$$$¸îG)((èÝ»·F£3fLZZºhN±oß¾áÇ÷íÛ×®ÏqòäÉ.\ÈÉɹ ÍZ­V$yyy9sfÒ¤Iw~ÀÊÊJ\K9pùòeø‘‘ñÜsÏyyyÍœ9sçθüܳgÏ«¯¾:kÖ,ÚË<sæÌµk׺wï>gΜ7¦¥¥¥¥¥9=þ»ï¾»wïÞï¿ÿ¾OŸ>AAA#GŽ¢9‰‰‰\.÷رc¸åÃ?üòË/+++wîÜÙ·oßÛ{òvâ¤aaaÕÕÕ0=éõú‚‚¥R9lذÂÂÂS-$,,, `Û¶më×[ÿý+öÉ'äã¹VëÿÛµÐPÝwßB "“ý1I-^œµha³s¹\‹Åb±r`©d6³Äâk ár9b±x£V›Îç Ÿ·]2]²2­È^؈­‘46‡ð]!Bú’EˆÇv²ææ•ß %$ž%„¸ìÛW¯UØÑ¢;ýœö¥¶tÇCaï­ÝñFÿ x.¡¤Àr8vûâa±Ç¨¥µ š †að¯ Û„!¬ŠÀ¼q¹\ºO™>²ã“CÝQŸSÇŽ1Q8tèÐĉÇŽ»yóæ:””””••EGG»)m\Äú BCCqåÒª½¼xñ¢OdddÛÏuüøñ-[¶¼òÊ+ÑÑÑ/¼ð‚ëñ?üð!äâŋޑÛü1È„«Tª—_~ÙqÀ™3g¸\®ÓÞa«ÕºgÏžY³fMŸ>KKîæÎ;mÚ4¨U)//w$€¸ 86úÔ××oÛ¶Ín޳[_ÂŽuu¤];"‰D"Q}}½¿¿F£Á˜XN¿zòdoY|<™=›ìÞÍöõõ…$¿R©¼pápÖuíÚõèÑ£¾¾Êž={?~<:,Ìf³]½zÈb± „î´õòòjhh‹ÅNbw] YFˆ”B¦òÏgˆBAÈÒ›ÆÄ2š#„L#ä¡)Ï’ÉdQQQðáop;ìÛØ‡ÅbíÚµËßßÚ´i.\øê«¯FŒa^°püøqFsèС޽{?~¼´´ôî:?þøãˆ#ìÒ*ÍÍÍçÎËÏÏÏÈÈ õ:¯_¿>bÄ"ÑØ³gãZÁŽ=š‘‘átçô«ÌÌÌÊÊÊþýû;ª}ß#üôÓOƒÌäcéÒ¥û÷ïß¿ÿ—_~étÀ“O>ùüóÏÛmüõ×_3224Í /¼ …øbdddØõâ\ºt)##£Öu*ææXbFF¤âùå­V;|øðûü†ÓŒÔt´ÊËËËn# )Ág¨ijj‚ð”âû¦M$)‰$%‘?&O?M¸\Ž··wqqqAAAMMMhhhcc£L&ƒ¿¦êêêÿýï ¿ÿþ{ff&š:‡ãïï¯R©0–%“É:tèÀãñ0v- ÿßfO äiB’iI!NLH<!') „KH˜“!7‹åzmm³Ùø7�…Ô�ë €gàÝ�8�ü–Ãá8Àº»XœA§ÓiµZ½^_]]““yñâE|?ñø „ �&0� Ðá\æ  ñ “ÉÄÜ�-ƒ{íšššD7�•ñf³Y¯××Ý ×Š‘·Ùç¤P(Ö®]ûúë¯ÏŸ?¿ÿþ@H|õêUƒÁÐê‚ý¯†Aƒ¥§§áǬY³ž|òɉ'ÆÄÄܶŽß!CN:µuëV±X¬P(FÕ¾}û^½zAµ}eeåĉ9NQQÑsÏ=÷ôÓO?ýôÓ|ðA\\\\\\SSÓ³Ï>«T*{ì±¼¼¼õë×gee : ^|ñÅvíÚÑxDjjê¾}ûÖ¯_öìYÐ~$„,Y²äܹsµµµŽµ­ÙÙÙË–-+//¯¬¬ çióæÍ¿ÿþû‘#G0¢}O1räÈwÞyÇ`0|üñÇ´I¸+P©TC‡ÍÊÊZ¿~}~~þc=¦P(ž}öÙ¯¿þžj\\\||<!ä½÷Þ;zô(Dü***°ÌdРA¹¹¹K—.-**Òh4þþþ °sçÎ?þxÏž=IIIŽ!»ìÞ½;++‹Åb=ýôÓ„“'O¾ôÒKK—.m׮݊+ªªªV¯^apx1@åoâĉ®En\.W(Úy! Ã�ÅêM»X¬ÕjÅbëÌ™„JB*y<’Ÿ/´Ùl&“)>>¾´´Ôq¹óÆð¯Wu žžžÕÕÕ}úô)**jhhP*•N-ºÅb}[lo‰DgÏž5™LèÿUÒm:óZ»[B&Ò›BH2!ý ÙäÄZÿÿ !„86íÒ–Éf³¡;R]] O’N1 Cç„E"èL•S:l9¢ãoXN§¯hÊ¾ÆÆF†a ƒÙl†®¸›Í±;´Á:K.Qžƒ6'1 ã4 §V«a/§ôE&“éðáÃð9&&Ë*++!àÜØØh§âºÏ‰3`ìä&­Ëè£üevË"‘HÔ¯_?zŽñññ½{÷æñxr¹¼[·nV«599¹OŸ>ÐOзo_:Xÿ@ 66V¥RÆÙ³gÃoƒuØNQ^^îáá!—ËZþ¸¸8???£ÑÈb±FŽ9yòdÿ˜˜‹ÅÂ0L||üœ9sÄb1‹ÅR*•IIIƒ Šˆˆ€Ø«W¯×_]&“=òÈ#Eh×®ÝË/¿ ºÎ"‘(99„‰¹\ndddbb"t%''ý¾ŸŸ_jj*d Á#<Ò³gOXùûû÷íÛ~å=z@KŠX,~â‰'ÆŒ±;vìÝ»·ã*›†Ùl¾~ýzÇŽ¶÷·ñññÞÞÞF£qذa˜ÑtŠŠ ©TêááѪD7!ÄÓÓ3>>š?:tè0}úôÀÀÀ¤¤$hXñòòš8q"˜d>Ÿß­[·Þ½{Ëåòøøx\FDD :ÔËË r'£G†|/ÇëСCbb¢\.g±X‰¤_¿~ð§ëÊþýû¿úê«ðKõíÛ×ßß_ tïÞ½W¯^0¹¨Tª˜˜8¾-ÝÃ0W¯^‹‹³KæäätèÐ[>œ–Øü穧ȉÄ¡C Ñh¬V+Ãp¹„Ë%ee¤±Qn±XL&“Á`h£j”Á`hll4›Í<lŒX,¦É‚CCC•Jess3d×é*s­V‹ù3¨æ¨®®nQ¨©G"ª›˜Ëáú}´'´„b!ä!úÀ&“Éî€àÉ©TªáÇá¼™óÓO?aç¬V«…Ÿ€Åb¡í¡KƸ\®SX×™*³Ùì˜s¶hš%<!|Î6›ËåPðõõõõõsˆW¨×ëÑä8-½HÓçÔNÓâx³Pdd¿<ðñA¯W£ÑÀ-�i== š1ºvíj2™8ÎÕ²ú+¥õf£A]Söôè!¬Åÿù©´ªQ`ªÙ-�f47ZÅ™3gBBBZú¢£GŽ7î>së?^¥R…„„<´ôE˜0a‚´k×®ÇÜÏÏÏžb±X*•þáš|û-yï=rêTÛOíááAWm ¥R ¥­555­š«°°0B”DÒó‹Åª­­uºÔ€N[h™òððhIý–BþùO¢P¥Kép¥\.¿=½.]º¬Y³¦W¯^x³;wî;vlZZζN='@€ÎzN„*ÌkÕsÒjµŽžÖèW‘H„‹ðœ—HŽ_]]ú¦N=' †eÝe·í9<y²¼¼ÜndKžSnn®ÝºêøñãÏ?ÿ|ss3ŸÏ?púÊÞSW´M Å9§36®tÓ¹áÆCaØ8ޝ¯/NON¡Ðóà4žc燩Õjàÿ¥#c={öüí·ßàsTT(ÚÙQð!\Ù›¶på®G:ÂjµÒ–) @­VßÉBŠÅbAþ«T*=<<0†Þ~¦ù¶q/šÊ1”G(vÓ¡ÍÑ؉OÓ¡°!M)¤V«-–H$Â# Ù¹V«ÅÐî#<éWÄ(¦Ã£££Ácc±X¸B“òx<ˆ“Ãgt’ÐT‹Åb4ð`>ï¨”Ü 7ÜøÀb±TWW»VÐi5AM¹\®R©´cBí BHII ¤j,Ë­rA,¨íƒU**á:¢¶¶Öq¦îܹ3Ç;wî\OAåh=Zp#]´“D?s|¼´Å‘¸í9Ñ*PNCˆB¡Œ]›àô‡¦`Øæl0hIxGÒ#º9Éd29iºB¬¯¡ ¢ú[˜Ì6  Eé6N÷­.!äOl8vìXi ù’¿=\盓—kÊ�§D˜(­„kgQ`þº ƒä‰D¥R]½zÕÅTÂíׯßÉ“'írrvÿ•H$:t¨¯¯÷ðð åóù¥¥¥-ÉÕ»ñ'Âmœn:î!W½ÿbNðØœð¡Å-¹Ž\.×Êá8úGr´^¡¡¡‰„v‰ ÆUÔ--\¼½½ - Çc¦YK¯|E3¬�� �IDAT™kËDn(áòù|­VÛªÖ—V«…f¸[m¡í<ÜHvIwÎ:ÕÅo±×ÕÎrz.ì´¥>§ê´4;;ícцŽþ‡ÃÁÈ€NC À�¨Vw¼�ú¹a¶Ê ]ÿXnãt›ÈÊÊú»’H¶>>>b¾oÈÎÎnIGî!R©tTÂÅp“P(t-Säã㣕HG( †a#cމq‡dGâ'‘Ht:Ì5‹…Ïç+Šæææ€€€ŠŠ Ú/Aý\h¼½þ7‡ÃçóñÐþþþ—.]ºÃ Ò–,‡ÃÁ<–\.Çr�ºº’N)aU4‘¸íÎZ,Ìa2†î4¢µ3p–G"y“É„WH?ü|åÊ•ÌÌLøÜµkW¸0…BEÚs£Ðýüü€r³%téÒ÷rZãt9•——×ÐÐ`çÔºÓÝAÏž=ÝJ¸÷ßyêÑ£ÇC«„Ë0LeeePPPKΓD"ñóó³3N …‚ ¬¨¨ άWÛ‹,Kqq±L&ãr¹<¯ººZ&“y{{k4šºº:™L”»„__ߪª*»ˆ™X,æp8F£±sçι¹¹(„ÑFÈårNg±XØl¶··7›ÍÖ"‹ íbóÐÐo¯\.§+×ÝøëÀmœnn%\÷c¿Ÿ�m@J¸ Ž=ÔÞÝ+a³Ù"‘µêêj‘HTVVÛÔÔ{Ž•°Zÿ ƒ·zyB¡²Yû‚¤/ŸÏ—x{×ÖÖBë’ë¢DrC Œ“H$Òëõnãä6Nn¸áÆ}E‹G µ¹Š&“©ººZ*•Bî,ˆ«‚0cK “%¿ÿþ;¡¤\�)þ!ÞÞÞÐk±X°©±±‘PN|«Ì¹:ŽÃáÈåò¦¦&Ô3t}Ù P…Άõœê ŠD"ÁA~Îñ°Ÿ—½…Ê{øŒ{¡D!0tà^Xo„C0€Ne9F|||âââÐQ†` X, ÄØ\ŒG‡Ÿ. [Çn£Z­Æ_`` Ó§tûÆÉf³ÙQg¢î{ï½GÈ·sçÎåñx òÖ*6mÚtòäÉ·Þz+ à>ÿ1ççç¿ÿþûC† AÏ --M­VÓº´w§NúòË/Ÿzê©®\¹r¿ÈD€¯>ù䓪ª*Ôšš0aBÿþýéaÙÙÙ}ô|ž6m䄦M›oOŸ>}ž}öYBȧŸ~ Ñg¹\þÞ{ïýæÐÂÂÂ+Vôïß=ƒ%K–TTT¬[·î^œîܹs6lxâ‰'† Fyûí·ëêê>þøcøöÇDªòÅ‹CóÇ•+WV­Z5xðàñãÇ;}gàó”)SzôèAyõÕWa!Ÿ�œ^ÿþ÷¿‚R$Ù‰äÞ( «Õªv+“Édmg t:+Á,ï[ ®¨¨€y­´þþþõõõF£‘ËåªTªêêjœ—›ššœN‘|>Æ„……ažÌQ?—NðØÙ0×R#3'4"‘ •ÓZ¡PÓ1-—މ(šRÈl6;’AØQ•c)9Ÿa¤·H$Èo„ç¢>:¥R‰óö?ü�Ž£‡‡6? €Ëå>òÈ#èeâÕÒæ“¾Ç' Ñh°3„(oÇAwñÝÎ;ÏŸ?Ÿ’’’’’Âb±æÌ™³zõê;wÞ^‘è?þñàÈi NŸ>½sçÎ6¥Ü]ÔÔÔìܹ3‡„}ûöÝ#©¡ .Ìš5kçÎW®\Y¹rå'Ÿ|2xðàÇüóÏ?§Ó»ï¾ûÉ'ŸÀ™4iÒ•+WRRRø|þ믿‚@€¢¢¢iÓ¦Õ××§¤¤h4šW^y%??ÿ…^øá‡RRR¢££—/_¾eË–õë׿ÿþû )))_}õÕìÙ³ÿ Æ©¾¾~çÎtßÉvíÚu/Îuùòå3fìܹ377wõêÕ£GþüóÏ¿ýö[øöøñãóçÏ‹Å)))¹¹¹©©©õõõ£G~ñÅí^ @yyùK/½TYY™’’b2™^}õÕK—.M›6í»ï¾KIIéܹóÊ•+7mÚôÅ_¬\¹¤ wíÚ5}úô?%ë´fxeìþ®…B!-Éèt/šŽÈ)‚ƒƒo#h¾äF;­ÉdÂ4[ii©S£ææf˜…ëêêD"Q¯^½!z½¯»zôW8ÉÞõø§w‚VXÉe2Yrrrrrrhhh~~>ØU«ÕÚ³gÏçž{Žòí·ßöìÙsÏž=0~Ĉ ~ôèÑž7�èâÅ‹—-[FùùçŸñ«S§NÁò·8RqßgtíÚuÉ’%[·nݺu+¸%%%ßÿý]?ѵk×>úè#à%„äää455%$$$&&jµÚ¬¬,ØþþûïAÁŒX,^·nÝæÍ›“““ÃÃà èÕ.ìåçç—œœìïïŸÝÜÜüÛo¿ñx¼ää䨨ØÊÊÊëׯ_¹r¥®®®k×® dxeµ÷:uz÷Ýw¿ýö[ Ÿ5kVAAÁ½xìeeeË–-KMMEïó½÷Þ£—Ì]ºtÙºuë¢E‹’““===Ïž=ËápÞ{ï½iÓ¦9= ^¯¿pá‚Orrr```nn®Z­>sæ ‹Å"Äêêêk×®]½zµ¦¦¦K—.ÉÉÉ6›í^Ȇµ £ÑèããƒìôâÚqÅi2™\Çèì€t54ªªªœêÁ·jDÁžY­VFãááäzTvonn6PCOè!ø ËBX­Ö?¥;Â[ëáë ³ÙÌçó¡ðqÀ€}úôyñÅ“’’ kjj@rª  ÀÓÓ333sâĉcÆŒIOOûí·Ÿ}öÙï¿ÿ¾  @,ÿþûï)))ãÇOOOã7RSSA‚Öjµþøãû÷ïõÕWÍmC,O:•a˜ùóç/\¸a˜C‡a¬önhµZ-­§î³Ù\SS Ï„Ãá´oßža˜-[¶¬^½zÙ²e÷_|áÖé:®²²R§Ó³X¬[’³j#@—…µT*•J¥¢{þe2™L&[µjÕÆëëë÷îÝ+—Ë=<<n5êõ'âBvZs^^^ ¢¢ÂÖ†4ŸÏŒŒÌÍÍ¥³l6Ûi ¶óù|ÇàÍ´´#|Õ©S'\Š9ESS“ÓdT':êÒs¹ÜöíÛ766¶$ZßÒ]­â©~ šÊc}4¥r=@å^•£.Í%Áçó±”QÈA‹zÐz0÷Âñ1 R^^ŽZY¸Wss3:‹H£J·1ùùùa\7 l0hjj‚@®/^¼ˆe)ÈÓ¯T*Q5­%úÄ;õœrss“’’’’’vïÞ½~ýzÐî=zô¨L&ÕÅgŸ}vÖ¬YsçÎ=räÈСC@ÏM¥R<xðƒ>˜={ö… :t耡^NÇçóårùÚµk¯\¹Ò¾}û'NìØ±£¶¶|óé‡ïx<ÞäɓnjÓÔÔ´zõꘘ˜». ›½dÉ’íÛ·»ÓÜÜüÑGuíÚõÑG¥ÿÚ·oß¾pá L›6Í59Õƒ…áǯ]»vÆ —/_>v옣ÚÐâÊ•+¯¿þzFFF«#çÎ{ùòå^½z=ú裷:‘ýéïÖ­›§§'X)™L&‰êêêÊËËi†7�™æÐÐÐððpœUãââpþ¥*‹333cbbœ­¥íðU~~~«+9§³›V«u4?Àd2?¾%Ëäâ€m1ù.dpÐ[ÀÌ8îNotà¨Àëx"\… Ln„”•ÝH`1Gà^Ð�À¸Ê¡5«ì`´"€Ö©ºíɓݪ«~îÆŽÛRXÙ××÷òåËZ­Òh±±±çÎ[³fÍž={ºwï¾qãF×±é“'O&&&Θ1ãßÿþ÷_áo»¶¶öwÞ9~üxbbâܹs322îz¥éرcgÏž}âÄ èä-,,t$Çüþûïóó󃃃Oœ8óã©S§víÚõ¯ýköìÙJÒâ^cüøñP;°víZÐô¼»xì±Ç,XpâÄ ˜¯_¿~«¤¢F°žÍ.**òôô„šé1cÆØ™È¢K¥Rtí>æçç1bìØ±ƒA¡P@"½¥´vaa¡N§“J¥4‘„ÝR¬%â¥ììl×=ž·Š»{47þºa½¶ 55õÌ™3ÀIÓúúúŸþ9"""==}ñâÅiiiNõñÎ;wýúõÁƒ§¦¦úùùíÝ»wÏž=“&MúÓ-¨Ï­X±bذa+W®…*Ç­;Á Aƒ6nÜHJà“'O:'І€aP µ~ýúýû÷8ЮŠá‡~`„ Üp¡C‡Âó„ë3gÎ S2 ´´ôôéÓqqq­ZÇC‡éõzÐuüKV<µµµ …B§Ó•••Ùe•O>Y¡Rù———{z{ëÊÊ$J%Ã0¦%HFBv …Á2Y9%¨xžÒò3ñ ×´LÞáâÛ|BÈÐíÀÃääB‚‚‚jjjý0©Tj4ÛÂÁår[8§%šhÇ C´� º vuwŽì>6›Í‘”ˆašÓ‹yAÚí …ð_š[ÈjµBŽfB »h¡] Vá6› Ót(ËÓÓ(ðÆ}||`#Í~„¿ŽÇÇ „knˆ»fœ!ýû÷?zô(R¯kµÚo¾ù¦±±qÔ¨QÞÞÞqqqŸ-¯¬¬¬uëÖ}ûí·‰‰‰“&MÚ´iÓºuëôz}RRÒ©S§þÄø~^^Þ† ¦OŸEÆóæÍÛ¹sçœ9sî®qB¹ÕíÛ·Ÿ={vâĉr¹<==ý믿 …J¥rÔ¨Q}úôA¹aÆ>}úƒ>Ø¿II X><""bÞ¼y:îøñã=öXnnîºuë²³³‡îëëûì³Ï®]»vݺuùùù111 Z­ö§Ÿ~ÚµkשS§D"Ñݽ¯¿8°X<##ãôéÓãÆsÔ0khhøâ‹/d2YRRRiié„ h—‚Æ›o¾Y^^ž™™9zôè‚‚‚uëÖ]¸paÈ!'N\½zõºuë £¢¢z÷îm³Ù<˜‘‘‘™™Éf³]ôÒÞv,Z©TÚuíˆÅ⦦¦‹/Ú¹ä%qq¤{÷BBˆ¯o9!žqq\¯þæÆU!y„ž=íÝ2G©P8þ…ÂÑZ ®hM&øV,³9ÍIÊ×ϯº FŽàp8ž E]m-ùõWòÝw„¥RÙØØH'Äb1AFÜñ žžž YŽÇÄ&»ÈŸÏG# –äæÜ -™}N´A¢- R¢ë¿Á`ÐÍOhçh@šËs?hàpS´qâóùhzñ°´ ¥F£bN‹Åâ´`gĈp¿t}ytt4vbá¡ Êgg‰u:îí§ôôtߛ߶”””¾}ûJ¥R«ÕšžžÛŸxâ‰íÛ·?úè£à¼¿óÎ;ûöícfôèÑ?þ¸J¥š?>Ç£¿3fÌèÑ£U*Õ›o¾ Ô^111ƒ>vì!d̘1¾-¼ë÷aaaééé]©¥ÜÌ™3ï]O|||zzz¯^½ºtéÂãñ µ˜žžž’’B›2eÊc=&“É ÉÉŽáñµ×^3›Í*•êwÞÙ³gÃ0#GŽ9rdppð¼yóÄb1Ã0‘‘‘£F‚¬!—˽víÃ0o¿ýö”)SþRöcРAíÚµ»§géÔ©Szzzbb"ü÷•W^Á5]\\Ü;ï¼óË/¿0 3yòägžy&¬ÐÐÐôôtšNpÆŒZ­ÖÛÛ{éÒ¥ÿýï†:tè°aÃÂÃÃ_{í5±Xl6›CBB–,Y 6›}åʆaþõ¯M:õîÞ‘Ó\HYY™“5ò—_Úï«P°ø|B‰ÀÀ@TñP¯×ÿQ†Îf³¼¼È­„CY!!í‚‚ªOœ�‹ÁâpȧÍòó#·eœ‡ÃR(e#Ñs¹\ooïÊÊJ¸qŒIØÝ ((ËÓFãß2Ìû€âî(ánÞ¼yÅŠ;vì¸ëUmM¸•pÝJ¸÷w¢„ ø£ ·…öA¨2/--5 J¥²¾¾õs¥R©Éd² ÅÈår.—KsÅr8œ€€€’’ǃûùù¹æbH$b±øVm½WxxxEE…Á`QQQŽŒìJgšOqqq×®]Ã7Ù©î“O>ùïÿ*,@°SÂE/Ê©çD£UÏ b,‘·ÙlÈÉU ¸—£ç”——&™Ífc¾Ùl¦…=§úúú¶{Nx³@uhç9Ñ@aÃ?A wË–-Ë—/Ÿ:u*:Rn¸áÆý‡Ã‰ˆˆpQŸ†óˆ‹R=è‚yéïÀ¡¤Í!—Ë ¹víšÁ`°óɬVkK}¬h™ —Ëu4BF£ñ6*èh^s ”Eó�.=-“\.‹ÅV¹zõj«¬6›Í`0à寠m@!xD`œÌf3>:‰D‚{¡‘€9;ãÄb±ÐbÏf³9ZGøiàÂ, zÿÀDË´Ó¾µÁ`€#�l,//‡È ‡Ã–;в¿X¡.“ɰS‡ƒñ •J%Ê ÁwÏ•p‡Þ£GÀÀ@$Œrà 7î'èyÁ\7i ·PBB™3g §íè¤2 çrÌiC÷1kjj²cÏk©.ßé¹Z…Ùl¦%!à&“éÒ¥K.*lµZ-2e´JrwM_žcƒc9Þ—Ý^vëǽhÒ#º47ÒÆ 3‹ÅB;FPôO“ûÑæE¶¬V+Þ‹^¯‡‹Ïç;íâ ¯ŠnðÂcÒ%!hœèF.Z*÷~(ázyyÝõ~”n%Ü?¿üò‹ÓÀÑÀ–jÉl6Û­vbc¬\.W(4'ÞùóçN XZFŸË‘ù Q^^Û¹\.«¿waO|.”m¡qçጠ?Xp³’ß&t:]UeûâÏRÂíÝ»÷m'Gÿ¸%%\r£ÒÌÑtEGG_¾|dåìœlj;00°¹¹Y­VÇÄÄ…B¤@är¹AAA NóX8pà¡C‡ÁÝÒn¿ˆÅ⨨¨ÚÚZ úAß®ëÞdÇÎYÇN} š "xЋîE/;PèÖn9âx´?çâÈÍ!Dt1…B!¬~h :¿…,´Nez¤Á` _9<¾Zô`·qºËp+ẕpÿxyyuëÖÍqb’H$N— wT:¯®®n;åÎãÙÙÙíÛ·Çí!!!&“©U‚æƒòx¼ÈÈÈ–ºtÛ@@óúÜɢʎ½7((èúõë‰ÄÅÐÒétÌŠžú1ÀLNð-&;¼½½ÑñÅX"ÝED›ÇŽ%Ú0Еñø#r8GÇšÅbaû³H$¢ ßÁ&566b…z—.] ÕD;âÍÍ͸vÁÝéB,ˆ`Ö«W¯bÕxÿþýá!˜Íf»¢·Lû=(áÞgÔƒ†aª««þ,%܇ó±[­Ö–”p¹\n§NNŸ>[üüüÔj5Dö-“‡‡Gddd]]R¥I¥R­VËãñ°<¬%`—«P(”J¥8µá•( 6›M3¹ÁÄt'–‰"•Jé S[  Y,–‹!D.—Y­Ö€€€?EÁ ·qºûx˜•pOœ8áV½Ïp¡„Kwhd2™V«°XQ|~{±Xf±ˆX,6!z›­Þj5{z?>((²w<ŠÅ…B!]¾ÕÊÜÁåÛÔÓ½½½kkk¯_¿ÞÆrƒ¶À‘B¥U@xʵqB%ÜË—/óù|…Bq‡×)¬ªRrÌfXOp=<êÿz"nãä†nÜX,;ÚžkÝ‚žžÝ…‰ÌbáÂ"„!¤Îj-1™’åòß„B(,Ñh4F©TjµÚ¶V8Í~™L¦ÂÂB°XJ¥ÒÇǧ¢¢¢-\5w ,+ �ê [eìõòòR«ÕmñÆè :º£ˆ® c±Xl½^õóϾdzoÜ2·[·ê!Z­=~´—´X ðY›+ñ¼t¦Êl6ãÏd±X08F€s±X,:'„é%%1™L¢4›ÍBÄ×f³!n¤…ÁPsÒb±äååá^Hrh±X`°V«ÅšÒÈÈH‚¼ãd³Ù¦NöÆo<Tçùùù«V­2dòú,Z´H­V£Âì=Åo¼¡×ëW¯^““C‹¥ÎŸ??22òŸÿü'¼=‰‰‰“'O¦wlnnž3g|9r$è:._¾24ÁÁÁ‹-"„ìÝ»w÷îÝ0ìÝwß½óuâÝBaaáòåËû÷ï?qâDØ’žž^QQñé§ŸÞ»“~ûí·€Ï|>íÚµv_½öÚk[·n¥eüä“OâFãŒ3à3¾3«V­Sáçç·dÉBÈÁƒQ8ñwÞ¹×Ô'<BžJŸ“ɺ …"KÏ0‡ôú½Z­”Íž •v C¸Ü¡0^«m‰~¦&J×>STTTQQQ«S¹Á`€*V©TŠÌo\.×ßßßi™%­]{'À&\×® £ÑHWœ›L&zƒ8“Úl6Ü ?X­Vb³)33™™lÊã`ZtÑ©qBöwP&²;/mœÕÆË0 R’;5Nhºhã„ mf³Ù©$<Ú!¡PˆýUØNKq|Pf³óÁÁÁÁhœà°˛۷o¬ù.~W†ë›o¾9|øðö­©©ùæ›o.\¸€[öïßß‘…;Çüùó¿üòK0UUUß|óÍfKMMMMMõññ™2eʾ}ûRSScccW¬XñÕW_ÑûN˜0áÌ™3©©©þþþiiiûöí[¶lÙ§Ÿ~ òŸ}öÙâÅ‹:ôæ›oz{{§¦¦fff>ýôÓäM}}ý7ß|Có“<xÕiï²²²¾ùæ›Î;§¦¦Òá²={ö¼ýöÛß|óMuuõèÑ£á'èÖ­›Ý‹AIIIùõ×_SSSCCC/^œ‘‘±jÕªµk×4hܸq7n|óÍ7=º`Á¹\žššš“““’’r¯‹ÖˆÅÓ=<z‰D"‹!ä´Á𯺺Íš›¿jn®°X!<«—P8×Ó3ðÆŒ¦Ñh\»8UUU Ãp¹Ü6¶Ûk4šÚÚZÌ–;²38Æë:tè`'¿+‘HhÞ§ôw„ÚÚZºƒ¸Wxçqi©÷©Sü›ãœnÜ6Ø­Ž8vìØŠ+6lØ——7|øð„„\¹öÙg 7�æôÒ¥K +W®\¿~}BB(á:ÆÌŸ?ÿ¯üDºuëJ¸[¶l!„¼üòËÅÅÅ{÷î½×ç]¸parr2Ð8^½zuÆŒ>úèŠ+@OK.—Ÿ9s†Ãá$%%ÅÆÆVUUÙ-6OŸ>-‘H’’’Ú·o_RRRQQ‘““ÓÜܜгgO­V› J¸íÚµKJJ’ÉdtþüOG§NV®\¹k×®/¾ø‚2sæÌ‚‚‚{úØ·oß¾yóæÅ‹?ÿüóIIIȱ{èСsçÎ 0�þÛ½{÷¤¤¤°°°O>ùdèСv|ð§OŸ‰DIIIÑÑÑeeeeee „ûÈ#ôîÝ[¯×geeUWWFDD$%%yxxœ={öž® „,Ö‘(–χx“ÞjýT­.´XBŒ6Û¯C †¤‰åó‡Ý(Á B‘\.—‹lX8c®ëp™Š¦Ífk©|Æ`0téÒ%<<œ^Ñ:vìHÇÓ!•••-YÐæææV¥mø|þ½b!„pôz¯ß~“]½Êz(«uîZÏ9iµÚ>ø`îܹ?þøãäÉ“øë¯¿šL¦ÄÄÄ)S¦ <øÝwßMKKûÇ?þ1|øð®]»ž8qbذaIII>>>iiiF§Ó 6,33óêÕ«çÏŸ7nŸÏ‡pG›`µ†de±~ý••›Ëªª":ár‰¯¯-6Ö–œlëÚ•ˆDä.éŠD¢©S§Z­Ö ,\¸$zcccïéÏ`2™jjjüüü°\ª±±ñ×_íÛ·¯ÉdZµjÕèÑ£>c4Aêïô" …Âàà`½^_UU¥Õj‹‹‹Ùlö=%ÄÒjµ&“é£>úôÓOõzý©S§T*Ã0,Ë.à©V«+**’““½½½ÿâORÆf{q8¼×-–ƒTUB‰ÅÒHÍž26»‡@ð!„ê™…PLKÒmiø­¯¯o»ÄœÙl¾t霺¸¸8$$ÄÃà çòòò¬V+N»Ãô•Édr¬]lÐÕ‹¹š•üV«2;[yæŒN©45ñ¨Îf³ÑÕsŒšr8ÔoÄZD†aÐcFÇf³a Ž¢–‡Õju̪ €®†ÏÎΆ')ðU¿xñbyy9!„Çã!Ïý;þ{×ÅÕµïÌöÊËR¥³ˆˆ€QQ{£¢h,ÁMQßhì&ƈ‰‰š¼ýŒb F½cGPAªÒ{Y`ûî|Ü8︻T)k²Ï?†i{çÎ{î=÷œçðDyÜ/^´à �<}úþ1p<11Eѵk×¾ÕÌ ÷or82™,‹!$ŒjˆˆHJJ ®¨¨€|…þL&GEEáÔËMMM¸°¶¶§soc‚\ºDZ¸¼|9éøq4;P(ÀÒP(HVzò$iåJÒ§Ÿ"OŸ‚΋à¢P(‘‘‘&Lhhhøæ›oz÷îÝéJ¸DÔÕÕÅÄÄ̘1J5BçFQQQ^^^FFÆ`S8\�� �IDAT”)SæÍ›—””4lØ0‹•‘‘qàÀ?þøc×®]ÿ°TÂÝ¿¿MVVÖÍ›7»”ydþüùEEE/^¼ÈÈȰ°°èß¿¿B¡¸páBrròW_}E<&\8pïÞ½ú_5*U²LV¤T*0LŽa'‰~+ †)}AL ëüÄéQ'¢…Þ¼]³C"›N~~>Ò Tˆ<8tjòÒh´æœ~­>WÇaÜŠ ›ädJSSq` øMy°v™@|‡Æ Ú;µ3v‰'àÚµP@| p} JióÜëó%Þ­¹— A¬ùæDLÚ7sjeee6lHJJ277oy²¯R©>úè#�À{ï½×Ö±TŠœ8þø#¢P��0&5J={6°²BRSѯ¾B €BÜ¿H$`ùrÌÓ èÛ7¶ÊÊÊmÛ¶%&&¾÷Þ{Ÿ}ö�`òäÉÍÉ€¾=þûßÿ* :~çÎ'}çÎ8Né"„ÞbêÔ©YYY_ýõž={ºúÙKJJòòò„B!.6XTT´eË–m۶ݹs6æçÏŸëdÀÔg¨�øE$ªP*G²XJ ûµ±‘˜ŸKys@ªÂ0±Z C®Û8d¤P(nnn8ID7�ކ‰Ta‚ØÚÚjÏílllh4ZAAF$!“É$2·v.(2™Ez:?/¯ÊÍ­F(¤¦<rÝäÖkýõ×o¿ýöÝwßÍž={РAéééø¡ÜÜ\"A:™L>{ölMMÍõëלœÚrsäÁô¿ÿ…– ðöƦM66��ÌËK=y2éõìMKS_¾ŒÙÙ·?«¬¬Ü¹sç­[·¶mÛ6bĈ;vÀ(8bŒVçÂÕÕ5--í—_~¯WhwïÞ}ùòå3fࢂÍáþýûÅÅÅááᆦÜ^üù矫W¯Þ·oßôéÓá‹Õ»woø"RSS�çÏŸŸ0aBbb"›Í Á¯}øðaaaáˆ#ôóÑš0ìDSÓ‰¦&è8²65Å“1‰Ä$ à1ì©LÆ`0¸\nUUU["5ärùãÇ©T*•JÅm�ŸÏ¯­­…áPá� Sh£hhhÐ Ç0L§×177A;;; ãÄãñªªªÞ²$oæ½.†J.7ÍÏï•’"c±Júôi˜@:[¸{ µoò�á;ñ ‡†f.‘X?™È„_…û5´zá•JÅ·MLLðÐJ<ðÈ3„;‰!àG'™çÒá1ÁÛ§¾}ûúúú^¿~]$…††¾|ùò÷ߟ2eJzzú©S§p²Šˆˆˆ­[·îÝ»·°°ðòåË6lh ó ò×_Êá¨}|0‚9æïOl8ÈÓ§HAöÖÆ);;*á®çÓO?=~üøªU«ºÎ8…‡‡ãÖ¥_¿~"‘hÏž=Ÿ}öYffæÞ½{Ÿ={6räH ‹Ù³g÷Ýw{÷îÍÉÉéÝ»·¿¿?�àûï¿?sæÌ³gÏæÎ{æÌ™½{÷&''ûúúöíÛ—Á`$%%:tj¯3¦OŸ>¼yó¦D"©¨¨˜3gN—º+õžžžýû÷¿råJUUUMMÍܹsÁàÑõë×ggg¯ZµÊÒÒrÕªU�Ρ!8ÿðáùsç;v ¾¦~ýúõë×ÏÌÌìþýûGe³Ù<oüøñB¡000011ð’’’Y³fc‚»|"¥RA‰jHÐì\]-À©©x"“‹E tµ=Œ.–à6�§Š€K,Ð8A Z�ÀðáÃ/_¾ S}áú„‘‘‘ýšN‚Š7õy[…@ ÐL‡K)‚˜™™µ÷†xo‹—–èQĪ«{=|H‰ <=Kml¤ZÂx@ñ[#²ƒã¦·D{€ç7IÁ‰â¸L;ž$•J¡ÓŒ¸@Hd%§ÓéÐ&Ñh4ü*'''kkkXTâJ‘ì—ÁŸÅÒÒR»ºŠ‹‹Û%zÛnã#z÷î3pà@�À¬Y³‚ƒƒ¡nLLŒƒƒÃ€bcc!Áþ’%KlllH$Rlll||¼‡‡‡L&ƒ¢UK—.…™Ø666±±±méWW|baÜÝÑ·¦áÛ-.m!mööö111DÛ¹bÅŠNLtoŸ|ò‰\.777=}ú4†a£G·µµ]µj“ÉT«ÕÎÎθ¦íŒ3 Àãñ6lØ`kk‹a˜··÷‚ 8pà@ …Ç111pãÁƒ0‰mîܹzhœ† ÆãñºZ �¸—/_¾`ÁâѰ°0333è^»v-þCL™2ÅÓÓ“Ïçùå—�Ã0Ù³gÃ? …½‚111³fÍ�ÄÆÆÞ¹sðùóçÏš5«9Ý÷·r.Q(ÆÆÆ=¯=™ìL¡”©TÅJ¥1‹ÕŸÏ.“Ù!´L›šöÖ×g+�€úúzkkkA4H`u ~ ·r¹߉ܦÄ^nè¨Õ>_Í]emm]Þ1iÝX, ³Éʲzù²Ñظ¨woi3œñt²qBdéÒ¥pß;v,~¾öƒp{þüù555Ÿþ¹··wHHÈíÛ·ñóçÏŸßÞÂaC‡bYYˆX ³°ÀZ^©jj‘>bmm?ì_º‘‘‘p£W¯^Å��DGGkϺ´ß<‡ŸŸŸž/¢øûûûçÄ]lŸp¥ö-\¸Pãèˆ#pŸžvµOœ8Qc·····w—>‹Z­Öž÷,32 b0êÕê• `˜ ¼Ü�:‚¤P(¿UT\klÌ" Åb±ö5—Ë¥P(ÔA4 ŽÚ8 ¹té’ƒƒC^^âEd±“H$4ÍÄÄD[€¦3ÓÜx1??ßÙÙŠé ‚””âQ333//¯Ë—/wJ³kkÝ=ÂP´ÔÞ¾ÒÆæßë…èfãÔa°X,ÿ-[¶œ?þÕ«WË—/×&Qn«q3Fmi‰Ü»0 B\[(Ú)Ñð.B¥RiOzzS©nT*€ÚÔjšJÅ ‘Ô�ôR*=ÈägTª¼W/\?W# ˜N§ ‚ÒÒR™LfiiÙØØˆ/ü°X,GGG~¿eTUUiìéÕ«Wee¥T*…Bí%]m.|¹¦¦Æ›AïÖý †•””Ôµ?I†Œã -"‘Á0Ÿ‡Ùõõµ¦¦YB¡A诗y4 Ð-F WÃg„DVr|?‘|ÈÚ@\”Â=Ãd2î—H$¸(FÃIˆ­ÿ]bIð[Ý•xÕCá+**à…:ó 5>>·Æ÷8Þ¯ ðš!³eÿvç'6sæL|õX p¹ÜÞ‹ËÅ Â||�†KÃö iioœlb^“Ã`À¿kŒI&»ººâÌf8bkjÐé¹ ÅK¥RŠaöff㌱J¥€DšÂf‡0'ÅâÍ"Õ¥\ —ËËÊÊ`/I§Ó===<x�{öªªª3gδÊDTÂÕ¦¹+//‡Ýnaa¡J¥êDÏ9Þk§ýÖÖÖ¶œ”Óœq".óÀu §’‡¼<…òÊѱÆÄ„¢ä[DœzNÛ8õuJ(9‡ð ¢|¡V«‰• ͆a­Flã·Â#&ˆüLÄ0 Hrßr;Ôx�€©©)ôŠ«T*Üæ555)Š.WÂÕNï´5 è´m*zþ<±‚177ÌÚº;{„³n’ò”puB;�ð@&K’ËU»ºüÒÒ»"áñ¢¸\Šö"“ç¡¨ÊØ8¶¦F�Š¢úß°ßDQ´   °°°_¿~©©©p,ß–‰1«�Àd2---sss--- >—ÒÂö‚!“½—žNW(êy¼ µÁgóN¸õºj5rë‚ç ff† ÞdåêR455ý››N(á655u碔¢¡¡A;L@©T¦i8à‡€š˜W‹aR ;#‡³XN( �0BÑ1Læ ‰ä¦DbeeånáhÚÈÈÈÄÄäåË—666 …¢´´7µç3}#nM,Cv†éh4î²ëNhä“0Ì'7×L$RhoªÕl‘ˆJ¥Ò¤R��éM6�’LF¯®�•Ê&CE&ƒ79du†’ë ¿&Žˆáìp?ÑA‡ŸL¤‹%æÉR(ØŠH$’öm5îß÷1‰-pò\â4ˆB¡à.>¢F"Þi@œœØ †¼<ôàÁ¿ÃãóÕS¦`!!ݹ攖–†;ëÿàóùݯ„›žžŽ;Öÿ011éð".Ä …¢‰Ð÷Y’Éi´› ä¹a±X‰EQh™��0½c`2™Ìßo++«ÚÚÚºngV…,Ýxí(‘ô).¦)��çÌL‡7c¦oz;yÙÙž¯åÇ«³¶&Ns5¢Æq‹¢íÁ#…+•JÜY‡_E"‘¬¬¬ð <FÏÃÕÕÕ¸KÓÙÙ/îW”J¥pK\©âp8¸JOO‡ÞW>ŸÓÙ¤¤¤À¸*•:tèP¸ÓÖÖ'ðÅ/¯©©ô8Zv9¾kÆ Z¦Ÿ~Brs† svVƒº7ŽÓ „kPÂívº´´´W¯^:…”Þ7HNd2E_(¯”J � …‚§%Õ©TÄ. –„·ƒƒCvv¶\.ïðØ‹˜ŸkddTSS£R©Pår¹b±˜˜ºÛ^àŠ D°ÙlEE"—Ë¥R©555]Ý<••Ì׈ÑÚÂI¡`¾î‚IÝ>ç3¸õº¯SÙÙè‘#èÝ»@.<ž:(9óõºî] ƒnüú¿Y 711Q§.�€L&s¹Üšš{2ù}'œÉH‰ɲª*1†±X,SSSh0Ñp¦tn 41?÷à!Â`0áñxÍ'¨¶×^Ó#Ó¨T*ô#u Þ/6O#¸”XZ>EºTªÁ˜g0Ž/^° Ð`jZêâÇbC"Ô?Ó8)ȳgȯ¿¢II@¥ÂÔ¡¡XPè(Í¢üó@ ”ÁXÈåB:×Ilö/ T*‡ƒç*ñP”8”“`XaD_VVÖ²ÎÆÆ¦¢¢‚ÇãUTTi‰�$‰v ŸJ¥*--ŵ!,--+**,--qæì ººšÇãñx¼òòò¶Ë j?T +ajµº©©‰ý:¸†ÍN27ÇM#n™ q2­¬$§Zsóä!C�J®R7™´GZ*• ¹&®ÊàgWˆ»øê‰D‚KM‚àgÒh4œI9-- Þ & Àø’��Ï:§ÑhÚßMMM85‰‰‰¹¹9,*‘¯î?l¯£¥%%\ÜÃÈÈÈààà®û®rss·nÝ:tèPcC¹yð�ýå$=ÔãÆa!!ÀÑè"c]·nF;›2eJXXػҿ|øá‡`Æ Ú‡/^ ›Z```TT�àûᅦé&l6ò”'&&:tž¿fÍ(“Óm¨««ûôÓO½¼¼´SS[øò-Zäàà ošËxðàôSió‘ïܹ†nC:�À¥K—âããáÑØØXssó²²2(@ �˜6mÚðáûp˜I&óx¼†ÚZ3ÉøõwAF¹΃šæ`jjZ]]íD¡° «³•*Õ3éœvB’ö¼OøÅWÛ>ë%ÆæI$(b€ß¹ÃsJ˜ekk[\\Ü%.([^]]mcc£³‰J$<%†(/«3HA£#U½6HDE|ƒÈN­ 1äšüBŒ)'*¾Ãý$ OH"†9àWAw+ܾyó&îwÕ¶=07-ø xa$ Î �׺d2ÙÙ³g»iætòäI—o¾ùþÛu,ÑJ¥râĉ"‘èÙ³g&&&šÆI©DîßGãâ¼<¬Oud$6`�`³›pš0aÞÊoß¾½}ûvwÂ8}öÙgwïÞuuuÕ6NóçÏ¿zõê‘#GRRR¶mÛF"‘Äbñ7ß|³zõjWWשS§*•ʹsç~òÉ'ýû÷Ÿ5kÖæÍ›£¢¢âããͺkr‰aØ´iÓ=ztíÚ5Eµù,š»êäÉ“>>>zeœ~ùå—íÛ·¯X±ÂÓÓóý÷ßW(?ýôÑ2ÅÅÅmÛ¶ÍÔÔ422R¥R9ò‹/¾:tè„ Ö¬Y3sæÌ'NÌœ9S¡PlÞ¼ù?þøüóÏi4.“ÓžEee¥Ã2ŠW …ÃëáêP&shSÓE‘ˆB¡Èd2€PÃìµõ’cX²Lv»=Èò�Ì›3'ÆÆÆd2¹²²²Õ¡ h›pmË7Ä‹Q]]ݱ§šÎ`>3 sÑJx›Ízýû÷ûùùeee………=ª @@eñ™3gVUUÁ=Ÿ~úi||<܆J¸J¥?ûöíoø"H¤]»v­X±Bgמ<Awì@^¾ÄúôQGGcƒG‡eR(@y9hjêïí Ìb±>üþûïGFF®[·þ4>ù»té^#^PP�÷|ûí·ß~û-Ü~›h¥vá£>ÚµkWsYÓIII$)((ÈÝݽ¼¼üÕ«W/_¾¬®®öôô R©T)))uuu999666AAA&&&¸ÌW·!??ÿÑ£Gk×®}ñâœ@Û >èmæ£>òóó#ö x›ñóó{{âÈ·|ÊÊʾ}û!¢¡‘]__ß¿\ª*//ÏÁÁ!((ˆËå>~üX.—'''óx¼   {{û¼¼¼V'%o•JÕÐЀpU"ù¿††š×ãeSi£±q8“iÌåZ›šF°Ù“ÙlŠ�Ô�<‘ɶ×ÖÖjuè8!YÇ ‰4Ö~ÜÝÝñm ‹ö*uißP' n\ïiii …§;s°¯Tj(á¢J%¹ó”àÿU ·êr³?*•ZYYùâÅ‹!C†H$E'Mš·sçÎE‹q¹ÜÂÂBŸçÏŸ§¤¤Lš4 Aëׯ¯ZµjÒ¤I×®]‹ˆˆP©T÷ïß?þü’%K ƲeËðÙ¢³³³îÁË«W¤µk‘êjÌÚZ=s&æç§;^\­FîÞEüQ=k6|8 PÒÓÓÇþÍ7ßìܹó‡~8zôh`` »»{ppðÎ;çÌ™3{öìuëÖ-[¶lܸq·oß~þüùÌ™3¯_¿~úôé?þøË/¿¼~ýú´iÓ²³³ñ°ý®N üŽ6&2™ìì윓“óÅ_ØÚÚÂ63zôè+W®ôïßìØ±K—.]ºté²eËîÝ»wüøqbœñ… –-[¶|ùòåË—Ïž={ðàÁ©©©Þ}ü3?c2¹OŸ>ééé‚4°«¾>G¥úØÈÈ…B¡�àJ£ý×ܼQ­F�àðùdQ`˜Aâ¥ÒãFF%%:GB��.—ëíí]YY‰KáÀoßÙÙ¹¤¤„Çã5Ö¯íXËÈÈ FU*UpppZZÑä2™\¢«<Íyê ?BfKÐ`dd¤T*[åº%‘H?M*•â#HCa\_ïš•ÅhläH$¦oÒªYæå 9t¨–ÃyØ»w©©)x¢íÖ#ªTàcJÜqJô5Í_¯~Éd2¼ %Zh,Ã^^^ð'D"Ñ£GàN???è S«Õ8«¡L&Ã}Œx= …B¸““ï@&“qÞÎ’’mZ^‡»ßrrrZM hÅ8eff2�€kÚòùü7n˜˜˜H¥Ò¢¢¢²²²ÆÆF|% .2™LÈÕÁf³Éd2$uojj¢P(eeeuuu¸ q+¨¯'ÅÄ UU0dsr:Ù‹ÕjäÕ+äÈPR,,�…"‘HÞ{ï½€€�芑ËåJ¥’N§Ã%Mè_–J¥Ã*£ãüTl6›N§Cj ¥Úm”äï:àjÄ‹/JKK‰Lû§N‚Œé°æe2•JݺuëË—/‰œðPcccYY™L&‹ÅmÿË¡T*322¨T*›Í¦Ñh¥¥¥MMÇWVz©ÕC™L/6ÛH©d"ˆ€W$ÒK©ô‘X,öñÉ‹ï?xЂu‰D7oÞ$îwuuMOO‡–¦]lxDûQ\\L¡PîÞ½«arT*•J…¦«·år¹§åx …¢!à �hÕå¨ÓÿŒoày¯�¹\PSÉ��tzƒ`¯§SÆõõT™ OcÒ¾x“”Hûw5Î$šg|£íß NJ„¢(±¶áÝ4Õ´oK SÄc:ˆ;›ã%ÂOh˼ãÔ§OŸk×®áN'�À‘#GLLLd2ÙÿýßÿmÞ¼ÙÍÍ­íI‘µµµü1� ((H磦É9yC6• IL$5ó!µQ(€Zyx`FF�€‡B60C·Õmxòä‰\.www‡¯ØÙÙ¹   ]À_ý•šš ˜Ý©{ô®ƒJ¥š››ã.h¸^} €k ¨®&“ÉpfaaÑÔÔÔÐа=<¼âõ§Ýv%\¢š(•J¥ÓéR©”è:†qä­Žçø|~CCƒFÔxuuµ™™‡Ãi{šm[cÍÌÌD"Q‡“«Ú‚r3³ßCCñ ¤R©xæì¿3í¡;ÜzÍ¡ººzåÊ•£F:zôèæÍ›wìØÑ–«Á™3gŠ‹‹ïÝ»×·oßVÎ.+C/]¯'XˆR Z{͘½=àp.^¼¸`Á‚yóæmÚ´éŸÑéCoªž—sÅŠuuugΜÿþòË/Ÿ|òI ç'%%é Þ={öÊ•+ËÊÊpß…ž °°ðÁƒú9è‘Éd-,ŽB&‰DRVVÝ27oÞÌÎΆG  —h×/Â(äÊÊJ¢q‚Aƒ­§æâ¶;0šiL&³ººº½¦=w‘ËåÚŒ>DÖbx·1kspÊ‹×ÌͰÙ‰T*•¶­mhhÐVYDQÔñµÒJ¥Â-%‡ÃÁ% qµ@&“‰¿âë£FFFD²%ü¶L&wÖÁ`¶~•¶U&“Éøm¡ƒŠ¤+Üúm›Íž:ujZZZ\\Š¢}úô9sæLË kÞ¼yû÷ï‹‹KOOþüùÆ{÷îÝÂùHJ RSÚ娱·Îúõë¥R©¥¥e\\þÖ]]]ž={¦V«gÏžmeeöäÉ“¸¸¸¬¬¬‰'ö “iË8vìØO?ýtñâÅÈÈÈÝ»wÇÅŽxñÂÍÍ- @*•^»víäÉ“< R©3f̰µµ MJJŠ‹‹{ùòåÔ©SÙzÆÔîàà0xðà( üGGÇû÷ïÇÅÅ>|ØÇÇ'<<œHãß ¼xñ"±Í��=z´`Á‚7>üîÝ»Går¹<oÒ¤I...AAAD¹[‹5kÖ¬;wîÄÅÅݹs'((¨ëâ]étzÛc÷�|>ßÑÑñï8åñxJ¥²íÓ&ß F0`�ÞGSt.wõ5´ýoD¯—D"Á³ †öU:½jùxü7Ñàc)âb —Ë…¿E¬\hC©TâLHFFFxn²§§'49ÏQijjÂÝz-&q¬ ›Ín¹wjÉ8ÅÆÆâùY�€ &…BXh.— ån�Æ 8p`zzº««+|`(wëáá�˜4i’›››……Å_|ëÎÝÝ=""B;¦ÖÖÖ666öÃR±´'_c±0++@§ôÑG±aaa>>>pœøå—_Âü­˜˜˜K—.�¦M›6a¨j ‡žžž±±±PÕôƒ>ï éÒæðÕW_3ÕÇŒ‰ªV®\Éb±T*•‹‹Ë¸qã ‰D‚437nœ7o|.è‰9sæ”)S´Ûk!::š%’á¶••‚ 0õÇÍÍ-&&ææÍ›C‡}òäÉ«W¯PÅÅÆÆÂEŽ9sæDDDtCJs CQT£ÍxxxÄÆÆz{{ãr·±±±3g΄5©ÃæÏŸ?sæL‡sôèQ�@ppð{ソˆ.òé7®½W9¶¬Þù¯„Îà2™lÝ5Š ¥ãŠBZhÝÕŽq¾½öN//¯·¼­-äóçÏ[šŸl8t½¨¼Ž&¯Õß* @Z R\ ²³AÛ#¡i4Ìݽ{#=zdkkkmmý¯¥/ºyóæ”)S:À­—’’²wïÞ &Œ3fÚ´i—/_ÎÎÎnc&Vrr²………­­í¿–¾èâÅ‹3fÌИœ<y222R'±±1—Ëŧ&'NœˆŠŠú—³<wÈd²½½}CC•J½ø0çÜýœ&QmAúăÛõwÁ³¶Ý«Ïd@7ÀÎÎÎÜÜ|íÚµûöíKOOÿî»ïÚHhf@s ‘ÉdÖ†¥SÇøö!C ÕÛÕƒ]ÝvËP5t'LLL>ÿüsè�ØØØPz‚´÷Ÿ333•îº+«×q×3“*Ct%ÜŽË徟ý߬„Û‰ë`0Nÿ@Ðét2™Œóñü;¡èvRXíï‡oWÀ0Š7À`œ h0ìªUÖ:}úô1T»ü댊¢Ý0m€`€›"-:˜ÿý_WWG$g4À� 0À€nCii¥nã¤T*µ³Ž 0À� 0 'gN&&&ýúõ멸^±XŒ¢hs©a&‘HÈd²~z8õ¤–Ú¥R)—Ë©Tj·êE‰ÅbÈ‘ªÏ%¬©©IMMÕòR©T\xâøpr ‹TL�� �IDAT}�Գן „2Á%’ð*G‡q¯Å}»? ëúõëÁÁÁ(Š¢(Úƒ³7¥Ry÷îÝÀÀ@EyK²ÈNÇ7I$‰D’´Gº´ûQQQQ^^îææF&“‰„˜Ýƒk×® 4¨Ç›S«%DDÏK(‹ E×±.u ƒL&C=ÿ��¥¥¥µµµB¡JèCFÚýû÷ÝÝÝ™L&™LÖ= ‘H”=`À€fgN¸ëþXU<[¨gæ äl‘ý^6ýçáojjÂUº¿&õ¿¢ô¹™i”Á`àrvz‡ƒ8é`}cc#.êÑ#½«Î±#$ÝÖ“D"‘è‰F`€è ÆÉ� 0À�½CG«1 »}û6þ¯½½½T*-++óññéA�@VVVyy¹¯¯ï“'O(ŠŸŸ_eeeFF†££c뻢¢¢—/_º¹¹™u 9zËHOO‡“åààඈ"÷îß¿¢(Ñ㜭Íé|û Г¨[·nq8ooo=¯·ªªªôôt‡^½zZ� °°0//¯OŸ>|>¿…Ó>|¨V«ýýý{xæôçŸFDDyÔÔÔ¸¸¸ñãÇ÷8«ü®]»Æ_XXxâĉӧO�ÇêÔ©î)ÀóçÏ9ÒvÝú®Crrò’%K¾ûî»#GŽè¹ \dd$Î qïÞ½#GŽÔÖÖº†cÛ¶mãǯ¨¨Ð“òŒ?¾eed=Á«W¯Ž9Ò²Îп ñññãÇ¿wï^˧͛7/22²‡gNÇŽûì³Ï(ʰaÃ|}}Ï;G$T«Õ{÷î…Ûƒîôʺ|ùrff&�€D"EGG�rrr.\¸ˆŸãææÆ`0JJJ.\¸��¸sçNXX˜««k'ãÂ… 999³gÏæñxµµµGŽquu533óðð€ú~‡† ¡666'N|üøñÝ»wGŽéâârèÐ!™L¶pá„„báß=úÏþóäÉ“… þç?ÿùþûïMMMÿüóO???©TŠÇ/]º´ªªêÞ½{NNNP¢pôèÑ=ª¨¨`2™óçχ�LŸ>øº;eeeñññ°ÍX[[{xxÐéôýû÷S(”‘#GÆÇÇ{zz†„„tîÞ¹s'99ùï/LþðÃKJJ~ÿýw¸gĈ°ÍüøãPCÁÅÅeäÈ‘‰‰‰fffÏŸ?/..¦P(¿þú+�ÀÛÛ;((¨Ókæüùó/^¼��Ðh4¨y˜™™yùòextÊ”)–––R©tÿþýpFs"òõõí Ͷ³gÏB5©¶´™´´´ëׯÃ툈>Ÿ'üüüÎ;7pà@í¨­ãÙ³g7oÞ6lXvvvAAÁ¼yó~þùgxoN ………ð¥¥e¿~ý<<< ç�p¹Ü9sæàýLuuuVVÖÌ™3MLL:·&÷íÛÇb±fÏž••uéÒ¥   ooïßÿ½¤¤dñâÅGŽg÷ë×O»ŸéR+UVV¶dÉE_½zõçŸÂý£FrrrÂçÇŽëÓ§—˽ÿþèÑ£ßFÐ’4dâ\Q“”¬’¸Xr0 k9Ø133óâÅ‹(ŠŽ9²¾¾~Ù²e½zõ‰DÏž=‹ŠŠ:xð`\\\pppffæ±cÇu**jO8ÜÝÝQ%“É-²_¼xqݺu\.×ÔÔtË–-jµÚÚÚzõêÕéééJ¥òúõëÕÕÕ|ðÁ¢E‹ž>}:sæÌ[·n¥¥¥¹¸¸ 2ÄÔÔ´åb¨Õêììl777‰„¢hËq,[¶lùþûï### gΜ Âׯ_pûöí7úûû×ÖÖîÝ»öeëׯ ìÝ»wTTÔ•+WV¬X‘’’²xñb@Ð+žžžËF¡Pä-j0–••]¿~½¨¨hÀ€ƒ š0aÂýû÷³²²~úé'Øè©Tª@ عs§D"±²²Z¾|9™Lf2™gΜ¹ÿ>Ç#“É1114Ëå®]»öÕ«WNNNGMKK2dH«Ù9"‘H$õêÕ‹B¡¨ÕjRÖ8öìÙÓØØˆaXAAl3§Núî»ï¦OŸ¾téÒ+W®¨ÕjüPç6§âââòòrE÷ìÙsùòå¹sç~ñʼn‰‰žžž—.]ºuë–¯¯ï¡C‡¶mÛ6hР‚‚‚ŸþÙÆÆææÍ›'Nœàr¹ eóæÍ2™ŒÃᤥ¥8qÂÙÙÙÖÖ¶í%$‘H-—ðܹsëÖ­ãóùÆÆÆ›6m"‘H|>Íš5¹¹¹...ÇòäÉ Aƒbccýõ×€€€§OŸž:uJ(&%%eee}øá‡Û¶m;zô¨¿¿ÿ“'Oþøã¡PØ7,¡H$ª¯¯où‰NŸ>½~ýzKKK##£ÚÌ®]»,,,üýý׬YSXXˆ<xðøñã>|˜™™¹ÿþ^½zAê@£Ñär9‚ T*µåáÏ?ÿ\³fM^^ÞÉ“'OŸ>]]]}èС   ŒŒŒß~ûÍÑÑ1))髯¾²³³»qãÆŽ;***ììì>úè#‡¢¢¢õë×ÛÛÛ3ŒÍ›7³X,±X¼bÅŠœœ&“yôèÑÌÌÌaƵšÆWWW'‹­­­)ŠJ¥jù[˜0aBFFÆ‚ ®_¿þÉ'Ÿ…B??¿O?ýôðáË/þÏþsîÜ9Ÿ;wî\¸pÁÃÃãôéÓýŒ»»{«/7''ÇÎÎŽF£µZÐqëÖ-‰DÂår¿ýöÛÆÆFWW×Õ«W'%%¹»»Ÿ;wîîÝ»<zô¨J¥5jTdddjj*•J½|ùò½{÷Ø*•¾D")++sqqÉ-®É)ªQȤõ•Åㇷۭ7uêT&“Éb±&Ož¬}ôСCl6;:::<<<--íñãÇk½a';vìØèèh2™|ôèÑÒÒÒK—.yzzŽ3FÃüXZZŽ1�  ;·$‹/ …«W¯®««ûÏþãææ¶`ÁühBBB}}ýÂ… #""ŠŠŠ®^½>|øð~ø!'çï,³’’’¯¿þ:00pÊ”)[6ØF'OžÌf³áˆ¦  ààÁƒ~øá'Ÿ|²fÍšèèh‹uèÐ!èÊ(//ŽŽvww?þü Aƒ¢££Åbq||ü«W¯nܸáççmooòäɨ߶ *•¢³ÍÀCaaaiiiø,§³�ŸT"‘|óÍ7"‘(!!ÁÙÙ9::ÚÛÛûÊ•+EEEÇŽS«ÕÑÑÑ&Lxñâb¿r劯¯ott4‚ çÎ‹ŽŽ>|øÓ§OŸ>}Ú¹%LLLÌÍÍÍÌÌœ:uj\\œ»»;lNÞÞÞÑÑÑ;wî3f •J Œ‹‹‹ŽŽ:thrr21söСC&&&ðÐãÇ;=©öæÍ›ùùùS¦L‰ŽŽÞ³g››[ m&??ÿæÍ›ð]||<̳©¨¨(--=xð`Äæ[ŵkצNzðàÁßÿÃáDGG‡……¥¦¦&''_»v­°°0""B{ºvõêÕ¢¢¢ˆˆˆ… ŠD¢?þøî·¶¶ž6mšÍo¿ýÖé©ß|óMiiéŽ;ð=?þøcvvö–-[9vì˜MttôÆçÍ›gll û™ÌÌÌO>ùdÆ ]4mrrrŠŒŒäp8‡ª®®>{ölïÞ½aqá ï1ŸÏ7nìLÞÆ±ÜùÙûUUU£G®®®îº æÚµky<^cc#QDµoß¾¶¶¶­úF; ~~~|>ÿÒ¥KR©ôòå˃ òõõ½{÷.ñœ‰'âÍW(:99íÛ·¯‘H”˜˜Ñ–ÁÎ[ÂÑÑñÇtss�ìÝ»÷ƒ>€oª*´ÿ÷ÿwûöí®£^d0ƒ>wîœö!&“9xðà3gÎt]å$&&îØ±còäÉz(µpá±cÇ~öÙgÐvüøñ7nàG7†±k×.}A~~þèÑ£»aý º•.^¼ØÞ ]\\~øá˜|Óéøøã—-[Æãñ>ýôÓòòr½Sxxxïû™.ªÀðððE‹ݾ}÷<|ø°ªªjĈDv �ÀöíÛE"Ñ´iÓ ¼¼¼&MšÔE8p †óòåË£GÖg`ooº{Í©UïÙ³nwºO_)Ÿ%…B)..ãÀaaaaaaöööûöíÓ9‚±R§gû8‹-Ó¶oß¾~ýúÁƒ5ª±ð›ÛúˆØ‰øòË/>|¸mÛ¶¡Yj'Nœ {òäÉÔ©S—,Y¢}Zhh¨Z­>qâÄÙ³gׯ_¯qÔÊÊ ÿ$[޹ê)°Ùì.²L��ggg|fjjJìÖ¬YóN·Þ¾}û� ·#%%…D"ÅÄÄtÏO¬[·ŸMvÅO ÞÈPåóùOž< ýí·ß:÷þt:B¡ñùü1cÆÌŸ?ŸD"1 ¹\¾yóf|…B¡Óé2™ìã?¾ÿ~çÆÒÒÒÄĤ°°ÐÄÄÄÒÒRà(jjjZ__?xðà;w�6nÜ8vìØ &üöÛo÷îÝ2dHppðîÝ»»³5‹Åb©TÊårù|>—ËÅ0¬e7™Lf0L&“Ïç¯[·näÈ‘]1'.++›2eŠX,¦R©ÝÉj¸iÓ¦}ûöíÝ»×ÜÜ\$¡(Êb± …H$’Éd&úEE"QSSlNÝù¾¶lÙbgg—••uåÊ*•ZWW߈L&‰DóæÍ …EEEµµµd2.MÑh4©TŠ/eq8xèÖ­[Æ ëô9(¬¥¦¦&¸Ê8yòdb •J%‹ÅÂ3Z8Ô àp8°wJNN =qâ,|ccã Aƒt>Wcc#Þ0ºÇHߺuëÎ;W¯^-...))9}úôï¿ÿîàà€ ›ÍV*•"‘h×®]NNNçÏŸŸ5kV¯^½ÁÙ³g NœÑ¥@Q”ÉdÒh4>Ÿÿý÷ß1"++‹xÂÉ“'wìØ!—Ë™LæÛÐ vd´èè臙l6[(šššÊår¡PH§Ó=z8|øp�@ttôâÅ‹;·^>ÿüs©TºaÃ8¼té�à×_]³fÍÒ¥K.\xþüy*•êìì CæÆŒ³k×®]»vmذ¡scð!nܸ1zôhÜebb" 9N||üäÉ“¡}ܸqÛ¶mƒ–ÒÆÆÆÎÎŽÍf³X,[[[;;».ê‹ÍÍÍáE;;;¸ùòåR©tÇŽ;vì8{öìøñãW¬X! !EöU¡¡¡ßÿý–-[þúë/�ÀŸþÙéÑzNNN½{÷Þ°aüyóV­ZµlÙ²ØØX¡Pß# ¾àp8B¡°Ó'âFFFŽŽŽ[·nݺu+N¿yóæÙ³g-ZðÏ?ÿxõêÕÐÐP¸gáÂ…_~ùåwß}' ™L&•ÕNX·Q¯×‰Õ«W744|ñÅp˜ ƒô8°aÆ«W¯ÂŽÀÆÆæñãÇÇ>|øèÑ£·mÛöý÷ßÃ7H¡P?~<bÄXþO?ýtæÌ™nàårùÊ•+�0Ö‘Øf®\¹ەݰaÃöîÝ»uëVøÉ\½zU Ûgç‚Çã …B|AþÑ£GAAA°*`w�P(K—.={ö,\–Æ[ÚŠ+ œ§†„„œ<yòêÕ«x#´±±ty[`A¸\®³³³@ `2™fffNNNÆÆÆ‚p8œÛ·oOŸ>–Ó¦Mááááááx?3}úô]»vuzâ}œÇËd277·“'O®X±–äàÁƒžžžŽŽŽøxhÊ”)¦¦¦'Ož<v옗—WÇkcáëEåu4yõ¨þVC† Q«Õxüòò%hË0A0{{ðî‚'NL›6L&Óh´®Xoo# Å™3g&MšD¥RõSòäÉ““&M¢P( £{†HFaaaQQQ@@�“ÉT(ÝL%¬'Í©-%¤R©úÀ¼Ù\ ‹ŠŠ^½zÕjø\7rë!Âb±ÞæV0mßÇLJL&[XX 8&Ÿt"òòòªªªüüü˜L¦\.×.»¿þúkРA‡Íf¿ej 55uРA³gÏþî»ïÚ~UuuuJJʨQ£.>Ì9w?§IT[þ0áàöægN†üðú:Y¡`l¶zõj,, è1 `€îÝ»·uëÖÅ‹›™™±X¬¡C‡êDÐ’[iãꂵ5 –É� x·0wî\EssskkkW­ZµbÅ C¼ ÌÌÌ–/_Þ¿ÿ.7N m3>L(Ä <T`À;ˆN'Ýù7ÃÂÂt½qz½°‘É ¹@[ ss]2n€`À¿š&'---77��0,¼¾ž@¹¥eÊÀªæ‚ÊÈdL©—.½M!ðŒ²²²ÄÄÄžª bÒO^^^JJŠ^½*<@£²²’˜‰©‡Éd¸B]RRRIIIwþºž4§€¯Š—””t[ÚxǾ …ƒéõ(úwL]]Ý¥·ëyºR©ç‹zðà>Pñâ”ÊçÏŸïñò( ûÚ’q’Édvvv§ì($™ ¡ÑLý—.í†%%¥RÉd2»‚:³½í^¡P˜ššölIš+žJ¥¢ÑhzX6 P(hP…BáÛ?v*•ªÇ›S«%äp8úYB˜~daaaff¦‡ñ„†a†¢¨þ��˜."‘HúôéÓé<j“É„ã=©@)ðd ó€ Ì,A¤R�ŒFVV´®O<ÄG»­’Šj|B°ìôT¾¶gƒÂwܹ„$‰È¥ØýhcµÀ"éu[‹×ÏŠÂç%%ÔÃ…BÑI#Ò³• fµ·Ú{°´÷[À?¢®ƒ>7¿7ŒSjjjVV4ÌššQ�HxVZZxîP(€X $ R `2“ ОÔÒåp8¡¡¡ …Éd¶L÷ÛE€Y$‰Íf÷HÄb1d‘çr¹=R�‚ÆÆFE!í±ž¨I555ÁOÝÈȨeÞý|›y{Ë I¨T*ƒÁxW¦¢(Êápô¿Ì …B"‘ ‰*ô\’­Sz 8ÍhÖ8�¼½½ÿžxfd€½{éFF¾Ã‡û˜™!iiHFò⨫ faÜÝ1¡sq<^đìi‘H'^=’3{êÔ©qãÆ‘H$X¿Ý_€ëׯ÷íÛ×ÌÌ Ã°Îͧë0ªªªž>} �J¥­ròw.]º4`À�cccµZݳÕãmæ-!‘H._¾ Y d2™T*}'Š}úôé‘#G2Œw¢Ú_¾|YSSãëë  úºÛuÀ“p[1NÿëúáûS*Az:éÑ#$9Z!òêxø;{;V=n°¶6ä9`€ÐY ·0 � ÕÕèï¿##õˆ€ÍR)’›‹<”J€aHE”Jõûï½d;6À� 0àŸeœH$ Eƒ…„`C†`§¼<äøq@‰‹77lèPÐÙ4ˆ`€ü;Ñl8Ö·¯úÃÕ³g«çÌÁ¼½ÈdÀfcêE‹0‚BR^Ž<z^ÇÎÐ455EEEA)žÂÊ•+5øZ>•——×SEºvíZTTÔíÛ·õêeEGGC^ðD½Fff¦>”móæÍQQQm§Ö=räþÝòäÉ“¨¨¨Ó§OwàÚ?þø#**êÙ³gïÊ7^^^¥SéMoÛ̦M›¢¢¢ôd‰«ùX;lútlÊð¦ö9��ØØ`C†ì†¤§#UU“Óv(Š„„¨ùÝS¸pá‚F Þ“'OêêêzªHyyy zõ²¢¢¢"""RSS—-[† È¢E‹êëëçÏŸ_TTÔãe?~ü¢E‹Ú¨ÝpüøñM›6õíÛwÑ¢EwïÞ}ÿý÷»¹´eee ³ë åååïÐ�4!!áÑ£GúV°ÚÌ­[·ô$š±Å@p è”pEÌ×—¸£1+K^Sáëë[VVæíí½råÊ'Nx{{Ÿ>}zéÒ¥ÞÞÞÞÞÞ0ãÚµkÞÞÞ„×N›6mÀ€Ýÿä/^ô~¤¤¤žzgÏžõöö>vìXO 33ÓÛÛ{ãÆÄaaaP¬¥§�Û LeOMMÅß”¶žd7à“O>Y¿~}CCCNNŽ¥¥¥¿¿?ŸÏOOOïþ�ÑÜÜ\¼*`›Ù¹sç‡~X]]ííí}æÌooo\äsôèÑðd¨KT\\\VV& ýýýi4ÚãÇ{êýÆÄÄx{{gdd��***ð‡úé§Ÿà 3fÌ€{fÏž �ˆß¿?�`Ù²eÒvÝ€¢¢"¼„ÿýïáÎÉ“'Ã=óçχ{¾ýö[ü´ ܱc‡··÷“'OÆŽÒÞ6�¨««ÃÛ �`ëÖ­ø”Jevv¶··÷W_}�زe‹··wZZ�À××7""¢¤5±A Ó†‡½&ä€`cØ ^-/Ç0L¥Råçç:tèøñã eÉ’%0öÔÅÅÅÎÎn̘1K—.-/////—Ëå …¢°°°¶Û]‚IIIË–-{ÿý÷¿øâ‹%K–Œ=úîÝ»NNNÝ\Œ»wï:;;¿ÿþû}ô‡Ã3fL7 ªªjõêÕ111sçÎe0pçÔ©Sá�",,ìâÅ‹Ýÿu­]»öàÁƒ)))žžž÷îÝ>|xhhèÁƒ·lÙòÁœ8qbðàÁÝYž‚‚±Xìëëûõ×_¯[·îÔ©Suuu‡rppèÎbˆD¢Ñ£G÷ïßÿçŸÞ³gl3¥¥¥ùùùð£+--e³Ù3fÌX¾|9‡ÃÙ·oß½{÷ž={VSS3qâÄ5kÖè‰F{\\ܶmÛœ‡ òôéÓ~ýú¹ºº^¸páðáÃk×®…j°<¸uë–\.÷óó‹ŠŠ:pà@FFÆ®]»¾þúk—î,­T*õõõõòò:}úôáÇ7mÚdbbräÈ‘ëׯgddÔÖÖ¾÷Þ{ ÅÇÇgÓ¦Mß~ûíäÉ“ƒƒƒ½¼¼ 2d÷£¦¦&???,,ŒÁ` Ò®6ï0nܸŸþyذaT*ÕÁÁá믿þñÇGåççׯ_¿øøøÊÊÊÒÒR©TZ]]ŸŸ¥ :W‰´ù™SC’¤¦êÖÔàŒ@ÑŸöïwssÃw0Œ+VäååM˜0A­V—””`&—ËG޹aÆ;vœ<y222233óÁƒÝüþ|}}“’’"""òó󛚚äryÌdwìØA¡P Ed†òùü?þøƒJ¥ªT*ÜÑokk‹a˜L&둯kÓ¦M¡¡¡‚Èd2X ±XœŸŸ___¯P(zÊç””´råÊ9sædddŒ;vΜ9ݼ8ÇårŸ>}ºnݺüüüºº:í6¸}ûv¼9YXX¸ººS©Ô7nlÞ¼YOÜJK—.}ÿý÷I$|¿0.??¿ººZ©T*•Ê}ûö]»v­±±±¸¸ÊŸ’H$ÈpC¥RÑnOü—Éd(ŠÒéô… æääŒ7N.—cF§Ói4,!,9…B¡Óé(Šöxú—……Å;wòòòÚÕfpçžÎçBD*•º¹¹:tèĉÄ%óÀÀ@µ»xæ$¡‡!¿ý†`˜zÔ(õòå@ƒåB£ÛârÁ›d?!!!«V­Âÿݽ{7‹Å quu�X[[ÛÚÚfffÖÖÖúúújçw5êëë÷ìÙsüøq'''è[0@Ÿ‘––CBBB:] ý]R©<qâÄúõë=== [=úÁ&L˜àííýÃ?èí£áï×ÒÒ255uîܹï"ƒ†žàÇ´¶¶no›Ñ+èƒ wî ññˆT d2$%ÑŠA*+߸߯æfJJ Þ¹o¿ýöÔ©S3fÌ€+£Fš2eÊž={RRRvïÞÍѹ²Õ•xþüù×_=nܸ„„„žªýòòòîŸ5j¸,´w—.]Ò7‰ú€€€„„„7Θ1Ã’)ú¯Bccãòå˽¼¼àJŒÊÊʈÍéÊ•+Ç?|øðÈ‘#SRRÚ¥œÝÍpvvNHHعsçŒ3œœœbcc_¾|ùË/¿à+ÓD\¼x±§æ%ÙÙÙÇÏÏÏÿÇ´hue×ÂÂbÀ€éééFFFÓ§OONN‹Å4¤ËgNHQx=ÅCÊË‘Ç1_ßÿ¹ò0 !ÄÛ¨¸QSs7'G§høð቉‰GŽ133ûöÛo×­[‡O/\¸žžÞ#ïÌÚÚ:<<šF{{{›Ã‡ùå—m${í,455]½z5%%%$$¤›=éø`üÑ£G¥¥¥}ûöõ÷÷?sæ � ??ß¾}L&sÆŒ=þuq¹ÜéÓ§?{öl÷îÝW¯^¥Óé¾oãôH›ÉÌÌœ<yr7Ïáh4ÚìÙ³ïܹ³{÷n™LÖ¯_¿sçÎåH`sJNN<x°³³ó½{÷6nÜX\\ìàà`gg7bÄ//¯sçν|ùR$}øá‡=þ~ùàƒþúë¯Ý»w'z?Wv�� �IDAT%%UWW»¸¸Œ?>%%eÿþýL&3""âÉ“'×®] pww?}ú´¹¹ywri“Éä¹sç^»vm÷îÝ÷ïßolltss›4iRjjê¾}ûÄb±µµõ¨Q£lll|||.^¼XZZZSS³`Á}0N­¶HMMMNNn¡Í¸»»GFF.]º444ôË/¿6lXmmí¶mÛ:·ð¤!犚¤d•ÄÅ’IˆMMMZܼ‰Àá‰R  à䬬þ¾H&Cãâ×Â$j;»â€€Aóç_¼t©²²ò‹/¾!!!ÎÎÎ�€Þ½{ÛÚÚBúðQ£FÍ;^åè蘜œìçç7jÔ(|)¾½ÍšF£Éd2‰„¢h»bóy<ž——…B!“ÉcÆŒñòò�ôïߟÔÎ<⌌ WWW2™L¡PÚE"‡ ˆ©©éĉƒƒƒ™3gNß¾};P ùùù€ÅbÁªh×µFFF¡¡¡3f̨®®ž>}úàÁƒ™L¦§§ç’%KJJJBCCñ0¤vA,———;::BÂÊv­¥Ñh4—ÀÀ@>ŸÏápß{ï=???F&“]\\æÍ›×1+ž››kmmÍ`0:VQ!!!AAAx›ñððX¼x1®YÕ=m†B¡À(;2™0xð`‰äçç7lذ¾}ûîÙ³§ÿþË–-CQtîܹîîîýû÷†Mœ8qìØ±vvvÎÎÎ(Š’Éä   åË—w€ôZ©T¾|ùÒÕÕ•D"!Ò®ïŽB¡ØÙÙYYY±X,__ß <˜N§“Éd[[ÛY³fùøøxxxÀù±±±ñ|@£Ñ,,,BBBœœœàÓµ·ØYYYÎÎΰ‹kWµ£(Khooéåååååeaaa‡Ã?~ü¤I“lll„B!\ \¾|9…B177 é€dLmm­D"±²²¢P(*•ª]îMƒááááïïÏf³[h3 033<x°P(¤Óé½{÷°µµõ÷÷_²dI~~~Ëm†J¥:;;¿÷Þ{€ÃáøûûûùùuŒC]"‘”••¹¸¸ä×äÕ(dÒúÊâˆñÑ ‡®•×ÑäÕ£ú[1 &“) TŠþú+òÓO¬MŒEEa..@"ANœ ýôP(��eJåoTª×† Á£F 4(==½ªm O¿ÿþûÆwíÚ5tèй ñ+ì/zø•F£1Œž%~år¹·Ç¿Òét¸¦ª¥Â‰_q²àžBW´™ÚÚZGGÇ!C†œ:uª«Ë¿ÂØ„wŽø•Éd¾CįL&F%üƒýÕ8ñëŇ9çîç4‰j Ò&ÜÞL@®ž>a±Ð£G‘²2 “¡wî`yy˜@�ššW¯€BP³·çLšTvçÎ/_~)س'77÷èÑ£m)Í™3gÖ¯_?}út`€`€o¢ù<'.›4I€<x€>x�rsAq1’ŸH$`jªööÆ0š™Ùªðð^s ôêÕ«-¿:xðà³gÏòù|}S€6À€wFFF)))s`À»fœ��t:ppÀììTS¦�èßÃsrQôï?�x4Çkׯr8œîÐ3À€*Pµ··7Ôƒÿdã„ ˆfPÀ»À5.“Éz„_íW*•=R�œ½ðäÄ#‚(å'‹õÄ¿W”Z­îÙŠêñ6óöß¾-•Jß•GÀ«]¥Ré™Åb1¾ÝØØø®,ì½}Ѭqâp8\.÷rÀuB ÃJJJz„®ØÈÈA Ãjkk>|Ø#•�ÃߥRiO@fffÐ ¼|ùRO’B`Ô †aMMM=[QúÐf:åýbVXXø®ä°³ÙlEáî¨v8V«Õm2{w[”æL Öãkl˜K`€ÐÍ “ÉçîfèŽÖ«­­}þü¹¡Ž 0À� è~””¼1AüŸqºwï^—²o¹»»Ëd²/^��8Š¢õõõïJ­9;;Ã’· .— �h!ÆÌÌL$õ¡jgÁÆÆ¦¨¨¦ŒTëän?¨TªX,.++뺒#beeU\\ !‚ Ä—E&“ù|¾vàó¶|g‹E¥R[å×·°° ÑhYûPUUU'f´tâ MLL¤R©@ àr¹†UUUÕÕÕuìí³Ùl‰„ûm©ÛÎm· oIEEÇsrr²ë7D·q*++»uëV«÷²µµ-..î�…¶Z­f0eeeÙÙÙàVßÜ´ ‰T*…‹u•••°G£ÑhÚ.`&“Éårëëë1 ƒŸÏ/**êÓ§OMM þI°Ùl©TªÏ)uVVV555-/À×ÖÖR©TÈU¬T*Û;Î055Õ¸ŠL&óx<¹\N´ŽŽŽ/_¾„Û<EÑšššvý~•µµuee¥B¡022‚ëáÚN§;99iûàó¶j\Éd2q»¹á …B©©©Ñ6N\.·©©I¥RQ©T@Ðj7jffÆãñŠŠŠšûޏ\nccc§p§²X,…BÁápÜÜÜyöì™X,¦R©MMMmwÚXYYÐh4E!ýAuuujjªÎºÕÙϘ››766êüQü±Ítà=þ3`iiYWW§ç,DÿþýŸ={Æ`0"""ZX€üÿGü¾¨©<Wû³d0VVVÄND¡P´]šˆšššòòr…Babb;ccc(¢ ˆP(|Ë1¸¹¹9…Béİ•J… 4à†a:å-ÔjµB¡€†G¡Pxzzr¹\KKKA ð{{m:îêêJ¥R› qyKˤT*µ»N"`%Ãú!ÖR puu555Å_1dŽ ^¥V«Åb1œS:::B%…BLà?×Þ!‘\.W©T666"‘¾#xjO¦P(ÎÎÎ*•Šh ËÊÊ(Š­­­Î(/*•Ú«W¯êêjâwáââRWW§]2™ ï2X,–¹¹9ü-(ÝâêêZUU…evvvMMMÚJ¥’H$R©´¹—)trttÔ¶[–––(ŠêœÖóù|åX]]]VVÖÐÐ�|Û_üpà„Õ¿”æÌ¹Î~¶X�h€MLLñvHl3:Ûm'EQggg8`255e±X­ŽN:|>ŸÁ`´`{T*õÐãû1>Ÿïìììâ1€H_¤ÉJÞ«W/.AC*•–––O‹Å{æÆÆÆÚÚÚªªª²²²úúúšššŠŠ ø.1 k.¦ A>}ú´åþÕÕÕÛ_Ëd2íÏC¡PèüzU*ÞôÍÌÌLMMQMMM}öì‰D²³³kûïB’=‡£ó*è­xMlØôêÕ §&#úA…‚ªªªv�®†œŠ.äçç㯘Ïçk×­‘‘‘¥¥¥X,nhhèÝ»7±7i®Óáñx6oJ_!—ËáU/^¼ppp€i,KgV†aJ¥R#Z•Åb!¢P( 3Pg7*‰ìíí.¶öêÕ+ÛÅÅ…F£Ám‰DR^^.ÌÌÌÊËËáúººâ}\UUÕ‹/töª2™¬¡¡¡Õ—E&“{÷î­±³¨¨H{ú^YYÙ\Üee¥¹¹9“ÉljjêXn�†a·D"Ñ.¼¥¥¥©©©v?Ãçó-,,à௰°¿°±±º4p‡^¼–F«°³³k5S­V¿zõ n×ÕÕµkZÆf³›KMc³Ù-÷µµµ-GÃkÔmsIOØ566Êd2 +ó76º¾`ûKcL›6 ƒn+"Š¢:ÒªtÙ'8%o•~2Q/láæÆÆÆÚm—F£ …BA,--á¼G£$Ú7$‘Hýû÷'²‘"‚¢(Q ¿F ›«ü* ‹æ.ˆ÷AD±Gí0äáÅŸÂ××:Xˆ…$þ‡‡4¶¶¶øÎÞ½{ØlâãÛà;™L&QSØÙÙ™ÉdjT#ü!gggh `µP(‰„ßÐÓÓ“(ô¥Q¥Í»P(E!É/¼„XÐùûû …B2™Œ¢(,Uo޼¬ ü*6£Ý¢`©´<î‘o÷9l{Ú;¹\î[vO-ÔC[ZuÛEç­à~ùþÚmA2™Lz‹Ͷ÷$]Q¥«OoÎ/;KµY£ŸéÕ«WÛŒŒŒ`#Ôù–,Xpêú“ù[â#Vÿ8þƒŠªT{€ÓÆZ kˆá¶ó )еµ5›Ívrr"vv:Ç\p°ÐªX–µµµ‰‰ |=‚è4?ÄÑÑ­W d2Yvv6ÌDADƒü˜ÅbY[[kÏ™’““srrˆV«ÕÄ3^«666=µÎá~UYY‰Djnjbii‰R*•ÄŒ*• ?'øš$ è€K#ÎÎΙ™™0íƒÉd±<†ax9 Fjj*� ¾¾¾  �¿mff¦B¡ …Ä!-l}ûö…Wb±877?áÅ‹jµšØñ*,,„õ, Ùl¶………µµ5T':¬H$’¹¹¹N•qb±µ;M¢ystt„ê«ð*2™lmmZ(Š:99‰Åb6›Ý¯_?SSSkkk‹¥óæD=VÈŽ½•JuwwÇ¿6£q7çææÝ4 ¶ â9EEEp<®ñ¹‘Éd2™¬- Ëãñ´¥²1 ‰D¯^½ÒX´wêÓÂ@¸³’#ñ· ¿GýÍùu±‹¤Óé £OŸ>oSâ°ÆÉÉ©Óõt`#ÔùFÚåÂ{c§Á”‰D¢T›aoÜÂŽXB~¦°°°íÍõõõp¢ÙÂ7ûÆ÷«s͉Íf·ìP†Ë›N´622‚Ár¹¼ºººÕ ‰Ä`0Zõq×××›™™Á)-•J555Å'ÝÚå§ÓéÄÚÙÙá‹0¢¡¡AÃ"—Ëëëë!ÿ<ìÚ»€…ÆÿŸ¸7‘%ËÎÃ2#—È-rß—Ê­–¬å½Þæ¡{¦‡Ó˜Àá@sì±�E‰Áì‚Ò�É¢úe¶É‚� ‚e hs Ð.³ôôôt÷ë·W½Ú2«rß÷ÌHÿøôŽoßX2*«u4úUdDܸ÷ÜsÏ=ç|绩OVÕ‘(Šâp8ä\%è˜Åb‰Çãð;çr9ò6ØíöT*e±XdY‡ûûûõz½P(8NØ\0ùeYÎçó:©u†jr¹\N§Óåry}}­åbÊd2$`[©TÊf³³Ù¬Ýn[­Öáp¸Z­@Ðívkµš,Ë‚ Îf³U«U¨{Y–·ÇãAV :IC2‹Íf‹F£“É„ýÌÑhtqqQ­ÕjÝnw6›I’ÄNf?#d‚QM$—Çãår™âÒ¶N§s¹\Rç'“IµZF.—ëààÀëõ6 ÕOƒ|²ç~Q}>ß|>gt“ÉDÇí ï6.K­ÍâÐúž’»ÝŽÕÚëõT]»ƒÁ€Ül6çr¹jµZ­VïÊÏð^(šÍfV«•äÄ·©»ï÷ûEQTAÒŒøØ-K&“i·ÛÊÙ§K:·K’¤-{M2£Ü¿üå/çößbcNV­!Sõ³ûçmÿk³’$M§Sšu›Íæõz•Ãg±X$Ib-™ù³ÙLkgÂ%IbÈûª¶I €"ƒ‘(Šb¯×SÍ»óz½ãñX¹šÍf¿ß›Ü!—ËÅRX­ÖH$²\.m6Ût:…g£ÕjƒÁn· ô)õx<NùKÑh4‘H#+a>Ÿ³AÖ¤‡Ü'»\®Åb¡¿>;Žê.Ž€R©&Ò1&“ b“ˆ«Ùl¶\.÷ðáCR4™Læüü|4)gZ›ŒŒ~¿/‚ËåRîî¢(Â0’$ ™&“)‰x<žápˆ]ˆ]“Δ&“‰èÚÌf³Çãa%BSlˆéU¢¦ÏçSMŠI¥R²,?{öLËÜáä“ËâÞ¥Õ†ÇãÙ€ÑJõì(ŠâëÈÊAc-}‡Ã!I—¤ Uí§ÕjõâÅ ›Íæt:ïe>Ÿ÷û}ò¯°âq›AÐ1!iFfj¹\j%(ê\b-f}™ù+ñØl6epušöËËË ’Åï°qþŠÉdr}}ív»¹€GÖô œ#}£ƒ3ű;N§Ó©V«J{Çãñ$“É-ß],Ãü–~QlðœTù­V«õûýápˆ1Ìår‡g&àP-‹———;;;_ÿú׿ò•¯ÌçsäRú|>›Í†$1­I±X,Tn¤Õj­U¢(AY0t»Ý’$ùýþëëëçÏŸÏçóN§sÿþý·Þzëþýû~¿ç'»ÝŽó{Pƒ^Æ^ÂN &DQdyܻݮª0 °êÈÿ¹Z­®®®²Ù¬Ïçcݹçççì†Ùg£lLŽmÜü6Á`P.—Y«Ù°§Ýn?~üxcœ& }- –0ØÈQƹL߸AëõzÊlH5<¢Ê&‚ªÎb±¨:‡×6<°Ûí²³¿Z­X§·N»iY8¯×‹E4½¥¢0Òpxú«ÑíªïFÜ2×ÜœTÏR×Åb7u×6›Mî év»ƒÁ çñX,Øc :1¡Ñ”q#v骮"Y–ÕóI"åñxT{âóù¼^/ù£ >ð¦Æ&¸×ë Dû/..Êå2Α­VËï÷/‹³³³ÓÓÓ|>OúÝb±øý~ •-—K¥uR¯×¡=oêÏ$ߊiÁ`Ðáp� :5·Ûí÷û±âù²,ӳ݀~ç.ɲ‹ÅZ­w¶ :† IZ&“™ÍfÏž=«×ëZ_!äC tuuÅ&†h5ˆD£Ñ`md‡Ãq#J}àB:æ"Ï X½ƒ‹Ì»aÎdY~ëF¯Ó‰W*U94›Íétz:j™ü\ ‘=ÃjµƒÁ!à]$eb\AÙl¶ÝÝݯ~õ«ï¾ûn ¸˜šÅõWFa|(ý)!«ÐãñlóF·?‡Íçóf³©úFN§ÓHN3¼I:KHé<ÌårÍV«u~~þìÙ3å+Ó\¯×oäQ ƒ7¥#A‹F£‚ àØaµZ‹Åâr¹ÜÚÚr»Ý{{{ÛÛÛƒÁ ‘H8Î~¿ÿÙgŸ={öÌãñ˜ÍæëëklrÐwÀâ(Gi3PÚ|>o·Û(U^­V‡Ãáp8´ÙlÀ ]__W*•«««V«…ëFóN§&î.€Œ/ÕÛ±»ÝnB^³Vs.—s:ù|^’¤H$B+û ý’»ÄmÙKì þúúZ)-,2šÛ7}òx<f;¿²vÓ¦4o 6Di_ŒÅbFLuý´uœ¹áÕ¤µ¿Z­tîZ.—¬èDÄ#F«T ”ËÉkÒëõH™(Ø:Z7•JÅãñf³Ùjµn¼=+ŠŽ2iµZ¯»R»(Š8 ƒh0>!"™LB“š^%“D"‘n·;™LÆã±Ámœƒîn ÛÞÞFÍÓ+üg›ìììùf jÒÅâ­V+åæaw \§jPA ù4h¨n†Û],ÂGM&“`0¸··—J¥€Åb ƒ?ùÉOb±X³Ù|ùò%B/²,³M¤HQϋŢjjÃf•,Ë»»»ÕjÕívÿä'?A͈³³³§OŸ†ÃáÁ`P(”»`©TB`ŒŒ>À0‹…*î‡KñÒšÍÉd‚Ôè_Ó |Ûh4êv»ØíT›/v"89|®* ’&f2$_Ìf39E1NsžÞ×ǶZ­ù|~ƒp)ûQJ8íM—*÷dvFØ»b±X.—Ç�8s⤳¸R©J` Ɉõ`ÏçsM¹uGên<oÛ“e¹Õj!ñŠ;æn\�a­2ÙL;iP&ØY«ÕªÎ[Þyç„ËoN˜E6›h4ɲ¼\.µf1‘Hˆ¢˜L&É ¡¡ü½Ýn/‹Æn�¿U7­Ñh„Z,M‹V‘�¦åÍÈår)AÀ¦Ôn¦ÿDMç£Tm‚l6 ­±\.³Ù,¤Ùf³½óÎ;Éd²T*Åãñ@ �ô’(ŠÝn÷£>ªÕjðã¥R)³Ù‡[­– ;;;Óé4 ҚĆg³ÙvvvšÍf8FêÃÑÑÑÚã{W"‘(—Ë×××ív»ÙlV«ÕO?ýÔçóµZ­~¿ßëõ”Ðï÷YÏç0›‹ÅZ~-ó¹\¶Ûm øt:¥ GGGåryµZ¹ÝnŸÏG¿Qú Ün7Y ÜP ‡ÃñxŒz¬Î‚Ý Ós$×ÀJXkÝëH çAh½^o,c7¼ÃÃÃZ­¦µ0od<¡Ãw¢QdµZåóùn·Ë®b0½a*`–Ù}‘³år MȪ…ÝÝ]NÚ‹� LÉv»}}}Í!‘ *¢t:-‚r_WU&’$±¹¦dìîî®ucÆãq‡Ã¡ Âcðõ·êõ›<àûûûÝn_bY­RVëßp¹þ{¿ÿ~-øûÀß’¤œNŸÅÒX.­’4_.+• K|§eWÒA%ì¥QY7pøe*•²Ûí•JsoPÔX¶.AXõ„6ÎE£Ú½×Ú …‚jx÷ööhi±ÂÊS±X|þü9õßuïÞ½~¿ÿu.—ÛÚÚŠÅb�3âHát:EQ„-çÂ6²,w»]ÎM´³³ƒlxÌãx<&wº„(rµZ)Ý¡ápøàà`0ôûýÕj•Íf«ÕªÅb)‹§§§‚ 8N¤•S ¸RŠØo÷ù|¡PˆdݰZ­²,Vœ°a<zô=z#›Í¢$Âá0{¸a5jj–$IGGG£ÑˆÛ+·ÀÕjÕjµ¸% <‹ñt8ð=ƒA,¨'ªSÏ>Š® Ì3¾w%üNm!Ó}¹\{pËBóër¹¶¶¶TOcì÷²£„)¦"u¶Ùl.—ËF£TÕh4êr¹XïËN0ì×¹Ýîd2‰ær9È M1d’†ßPߨK7Ú¢8cËb±ìïï7 Œ7‚ @Ýá*îÒqÆR5ËL&#B6›í÷ûˆ¡‰¬_²‡¥ » f?ŸÏ¯ÙœHeY6›L!‹å¿p»ÿy$ò‹^oÁf›šLg‹ÅÜdJÛí%›í›.×_s:/»ÝGÝîÌ€˜"üŽ}%‹Y­Vn{ŸL&ÊY´Ûí¹\Ú°ßïß²š!¨ 6›/§Ó¹X,DQ\.—ápØår­õ¢ì©²Ã«ÕоÔ`k·ÛÜΈ;*D°E0öàŠ<@  ‘•×ï÷ïÝ»×ëõG*•*•J{{{Ñht8>þü÷ÿ÷Q5à¢( …n·+B©Tâ”CËÛëõp5$‰v» /3«ŽG£‘ÕjÍårØùÊå²,Ë;;;/_¾„+.i:µ ­Qg$!3HBãz½Þöö6*ÔqñÎZ­Ðq$9<<áòò’Blíô!ìD˲¬”²—†¾§+‘HX,-?ÕÖÖ9m‹E«ÕâÌêF6›ÅCT­`Œv»½ÖÐÖ?ãº\®B¡ e>{½^U‹¬¶›ž«ŒTþÝn·³BH®6³ÙŒ"„œ d<CT<Ͻ{÷†Ã!—v„5n<LBÑ{BãY,–V«Å-UBÀYÏ­ªNÛXqy<:ËBf�Id½Ä8ÍÀŸ¶X,°3¡ç:ë^¯7™L°»Óv¨%ð:—Œ7R&˜}åÉI/΄¿ëõþÓPh×f›¯VÿïxüKÕê7¯®þz¥òïg³¥Éd6™öíö_ Î岨·aµZ)}ž#ß0›ÍŒÐU`9ià¹K‡Cɽ˜N§)[¯^¯‰ý¦R)åá ‰`'�Gkm+ÿèóùXÛÙkår²Hê÷û:Å2 ×èÇðÔ™^7#}‡cÍ7¾ñN§ƒè+ ÏÎÎàG À‹éüóçÏiÙ·Z-àr.//•+³Õj}öÙgãñ3‚Bl’d(¢ôY’»Ýîóùìv»ÛíVÖ’ñûý°?{öl>Ÿ?yò“ÎÕþáí·ßþÖ·¾upp Ëòþþ>*¹™^*¡ý¹”<AR©ÉŒÃáನ$×U*.ælµZ}>¾ôììÌH…oÔºÌf³Üw¡ó$N§S5ÏÛétÏKVÍ`u™jšâ)yú}`O{———àÕj¥dàEÜ”ìô««+dií³™º@p[;÷@Ä1¶$ù:YW”úôéÓår)‚|‹Rœ¬V«e0 ²»(Š™'Ož°[N½^Çž}||Ìî n·Ûx,Ç …B´:”}f/e›Ö¦¤kV%7›LK’þ~0è“Éôd>ÿ[­¿œNe“i°Z}2Ãé [,&“É/3“é£é´ûÅmÙétÚív@gàîDaã×äs»ÝápX+ý ºHRi.—KƒìÈ WÅóã\Ün·Ífs4Uµ›PÓ^¹;ÂÙå÷û'“ "ðô.å£_§´_F£­R˜±€ÊN§S¬¤ÆR޽/ ‡ÃFgSL–Ãáðx<ì 2 ùý~ê<¶ kììúA i²óù£+d†µúIf<O8¶ÛíÀcr_Mͱ´‚Á bc\º3ꇾýöÛ‡‡‡¨}~vv†7›Í±X¬Ñh4 N)ƒRNW§Ó‰£•o±X\.×il§P(ŒÇã9æó¹²FŒ¹�� �IDAT‡@ž‘x�+¦<9ƒA«Õjðu‹Åb“_yW ¸iJ”–ÆÀ&aÄ`‡´Tçóù(c“äÁãñØívZ&€ÓÚ÷z½‹E!¸¤?YÃáuX­ÖP(´¢ P»‘ˆ¢þ­[$I²Z­7ʶ˜N§ÆùM,K2™Ä¯%„d4x½^úL ²6+ ¬<9Y¹o&siÛfûU¿ßa6›L¦åjõ½ñø“ٌ䫲Xü_Ãá?|…^ò ‚Èœœìv»ÇãAŠþi¼’¼ÛíaíŒF£QÖÅäñxü~³ÙÔÛ”ñVm¨Â°ñíçççÑh”ëNV«5“ÉŒF#2ÆA$‰Û�$Iòù|8ìë€7óùüG}äõzŸ?Ž£ØãÇQÙDµZ­ÓéÔëu„ú9 FÜ܉¢È¡"§‘H»»ÒÈr¹\ËåU‡Ãá@ÁJ¤ H½;;;S L·Ûív»Á`ÐH,Ðáp�†¬ü;ÊÝb耯¢èüü¢«…à±X,V«•sÇ›ÍföE@€Ý)95ü®l6[.—%Iº¸¸€Å°Ùzf=ûìašõw ‚‡!i$oZ“õ:A°7»Ý®ºm6›Ž¯¡Gú 8&6›MUqâì¶Ì;¡Æ‘¶J ®UÉžmÊè¶@ÇƒÌ åP¨šø¨Íx'„UËåR¿b7YH€?ƒÝÏF»1´\àf( âDù‹’”xåkÊòç³Y‡5~W«?Ïf³ÕêÑlöÿ ‡Õå2™LØçqØP„šÔjlIoƒ�Oî7²,++é;®~«q¾H¬,¢>î‚À2 ã›�.—Ëh4úÖ[o¥Óé{÷îÝ¿zÀ#¤œ²•u¸…ŠyD'&u:üñ~ðƒ““¤$|ÿûßÿüóϱ„ºÝ®I•{h‘ã.Y–9È$€Ûår™Ms¢ùe±xtc¿ßo·Û:{O«ÕB °–pÚp^¸ÕjU©TTa˜f³ùôôôòòòìì 9ëì>¢ÓéÄÉ= Áp8l2Í#’£Ø·+û6þžN§wwwK¥Òx<n6›Th¼±{ÄbáÀjx£~™’4Õæt: „uŠ.j5¥½…’"ú4˜\ Ãx<¾¸¸@±D#/µZ­´$Æ–>Ú8ÈÄæþ¬ådÐ$ÕÉR} TÐÚÙçBG˜,ØÔ™‘[¹õ>þøcà¼&Ó?…B¯<û/æó7ž2–ûÊdêÈòdzٿþípøÂçëÊ2j€bŒÖÂá0LwvvÈÄ0˜Ë¯L²¤»r¹\¯×cœˆßLo—V£YK$kïEŠ‹Ò–ÉçóÈaM$JA‡ä±YÚÔ�á³Îd2©TªP(Äb1Y–>|ˆ¢>ÄG7™LT%R„Åb`Íx<^­V°Â*• v)³Ùüøñc˜9^¯wgg?^;òGGG(·£4÷A Œ&Ó«t/<–¶= vMÒY”ù w 80³ÜØÒ'cK€·Óçó‹E�!t$ QÀù|~rròôéÓZ­oîB4Ùóù\ÄÞXÁ`ŸIC±5ú %²‚O#æâðð0ŸÏ{½Þjµ KŸøB¡0UeFé<0›Í³Ù ùÓ:: ÓÊö"t»x<NŽŠd2ÉU’Õ2{q~ý+CY`jTW¢ßïw¹\¨øF;v8Ñhô¦U︺y:-Nke“®?hh nö¹µ šÎÙÁZÇÉ•›J<Ðår…B!TJœL&PA¤<×zHU¯ji'ƒn=>ægËWŽÿF’¯ãæóïÍ/¾fn2].Ïæóòb1\,�7ÑÙ'9º[3{·U¹Õn_ÆÍ+²õ "k7¼Ñï÷£4*i. âYß7sÜ%V,<¢5H‹‚"øüóÏ·¶¶ÎÏÏU3zЧ[[[¨¬Â@�ùTV«õÅ‹ø  ûÊ@ŽÖ@!¨¦õEt) êä§q7*9—M&ÓÞÞÞÕÕ²T8vZ$ûAó¢Hñp8D"÷¬¤Á“yuuuyyY¯×œK$¸ ûÁ½£Ñ(›äÊìš^ñ.—ËX,¦ªkØ<2Îf³(Àh6››Í¦2R5{Õ‹ð¹ltQ3™ Þ…?ês¿Òþ¤úà«ØÝÏ„jÝ(ëM™p7vž£¬>lDËÍ/b´ét:·Ûm€üvww‹ÅÚ˜ÄI–eãŽz̬ªf@Ò ¡Ïç œOB˧ÙGþ{×mðÔª˜nÊùÀ< Z…›}ø´ÌVBRAót¯ßœð»_p»¿ærÙ^mN?NÿïÑhøÅ™p¹\TŒ‹x»ÝnÕ:í,ŽE„Ý­”ßÉÓ�Ô’¿T*ÅæÁã„% Z[£Î% i¿ßG‘S$¸7›Mì(ZK š3U0懣T*¡lÙl®T*©TŠ�ÛX–ª;“Ïçã`˜J‚`Ô¸B¯ööö(°ì §J±XÔnƒR©äv»{½{Ê$(!ÌFÕ]“$m9 Pý¨Å‡HÌ|>ÿò—¿Œô³@ °¿¿`ž¾i‚wÁƒ­j!²‰Çã‚ 4 ˜ ÝnW’$”ê`W2Þˆ‚‡Ã\.‡OfG‰¾ë6Ï ¡ ó ¬JqRæõè�·W«kmp%Hó¢XW,K&“ñxÜëõ>~ü… R©T,Cðèè¨Óépu�¶··kµÚMãÇZœ+óœZÐ×Q4ûªwéY o£ßÓÍ �Tk³ë]õïJ5Žv»]eÕnŠ3™ R Ñotsú%¯÷žÝnyµ9ýd:ýýá0`±|Çãù`ðŸ„Bÿ ø¯Ž­ñx"Ëõår®bUC’•ét:-Š"ŒG¤íMñL©TJ§ Ä‹VðÈòÇhù|ñ±�T„‹§E£QȨ$IüljDÊå2õŠÅÍ!%Õ·ö÷÷É`D˜*ŸÏ?|ø¨WWWËå5ȹ‘7}çÑäTɽ{÷b±+j@H˜L¦û÷ïg2™÷ßÿƒ>øò—¿Ün·ONN@)«\f‹ô<6› ¾iåodYŽD"=b“àQë<6]}¥Ùl6Qà€›G<äúúúÞ½{–z½>a}ƒÂG_Màj,ã†Éd:<<lµZøð`0 +• ÞE¯³³³ëëkÎÆdQ“_!¸X*•zÓ�Õ[o½(ü–Éd8z-L·H„Ù¿MÁbU³j¢#u‰SÕjík_ûêW¿zxx˜H$Âá°Ûí~ñâE¿ß¿ºº¢’õzê�D"”)ô*›ËåàìÑbÆ¡â°Àœf08e»»»�¤ÓÁåFmµZ‘¦ºo±*H+Dç¾ÈHVV~TëPpSÜï÷S©•Cß mN¢(þ'g³Q†Í£ù¼·ZýÓPèo{½E»Ý%v³9h±Ü·Ûÿ3·;nµžšL]Y–W+“˜ˆEQ¤£%· 6CÚÞŸKjø²x<‹õ6–)�•F~©áB{‡ÃZ­öèÑ£Ùlæ÷ûûý~:ÆÞÏáæÓŒÚ©äÊØÛÛ ƒOŸ>Æ$Ãá°P(ôûýû÷ïsº&›ÍN§ÓÅb¡…~­ÕjZvn¯×K¥R?ó3?ƒ:rØØÂáp2™TRJ¦R©­­­^¯wÿþ}.ÉÂÄàQ?‚˜!ív; P$6ª˜ne«ÕjÜw!/kµZ9N·ÛÝh4¢Ñh6›•$‰øàÈ:[çáÈÄC0¦^¯›Íæíímdöû} fØ¥®ºæ©Ê†²çª¿w8ú½º¾¾fW¯×‹F£¬÷U’$%œ–0ÝÊn¼÷ ÝÅŒ ÿp ;(‰81¹\N’$ÇóàÁƒýý}¯× ä©åv»é«Q}ØôEè.ÛpÆ’$)ãH­DžºÝî|>£jåZóÕl6¯®®nš>@O“eYëDk\Ñ6ÉmrÈ·TÝ,1Ykk$ªª;N¯áF"‘ÃÁæ~~I-HY­?œNÿÃxüp6›ShD~Q’~}k+ër™ÖRP("—˱ \¥½¦&IÒÚ¬VT^]]}úé§ú©>Fx‡íñãÇ“ÉD‹qy2™\\\|Ïï÷f³Ùl6“Éäo¼a6›ÏÎÎàÑ~ùò%J’s9==Åo±X”ù„¬­:cú‹Çã9<<|öìYµZÍfý~ÿéÓ§‹ÅâúúúÓO?EðŒ}Âååå§Ÿ~:?üðCVÖŒF£„Lôx<;;;8öKíÉ“'Ø¡JŒ'e¥R)Ô‰E1ã‰DÐ]¤±x<¢Ð~üø±’K…€‡l B”eùéÓ§ì¥H$²1KºVî|£[¸Lý~¿¯Åúq£f@µÙívŇB!§ÓI˜n”ó�pÂô W¿:fd4ƒA”ØG®y»Ý¦r',ÒVYDÜd2œœhÙ4ŸþyµZýÑ~D[æÏ”$)™L¢œ¿ñ/E¸ñgËÄf³L®[Ûž<yÂ푱XL«˜�²»_¼xÆ8WJÏ+åÉ©×ëý’Ë•`$^„ãùüêtþy§ó¯ƒO§A‹e×nÇ fsb>ÿ|4z>Ÿ/V«N§ ©òe¡Ph<;ÎH$‚T(·Û}£Ú¦Z�¿kç’])q¬ç.Asß…L§×Q‚Ïn·»\®›B€™‡çàà T*ìïïƒdöää¤ÓéL&NG"‘ÓÓSš,—˶§år‰ Ê Ù¹ÑhHOÌh4êõzEQ´Ùl———Ož<)—ËWWWô ñx|8‚ãX«ÿ˜M p 0POÀùW*¯×K‰R * ^¯—²†p—êB‹Å"™LN§S›Í€j‘Á”…B¢(~þùç@.SL‹KÖ‡Ãä'pŽø:À?YI‡n·[+=8ë ÕÀ¼Ñ.²Ù»ô bÝÀÁÀY±G.‰é¸'O§SpnF#¿ßc+‰L&°’~ÿûß¿¾¾žL&6›EÚrÄ`„W„é lÀü†B!³Ù<™Lb±ØÙÙ™ÅbᶨZ©Ô v€îpö±´ªh­ýÆÝV Õ_r“åt:·¶¶ƒcú¯@2‘ÎÉIÝæZ|qøÎ‹ÿ½×ûÝáOúñtú[­’ÍVzUó Â7]®?¯—K“H-‘H¤ÓiÐŒnoo§ÓéýèG¨õ«õÒ–Õ N‡¹ÓédKª6@#/..À ¢ê2F©’`Î÷ªú]:è<fPdO Žc¡‘:ÞÅ©†ëëk¤åÀÌ,—Ë;;;àpê÷û£Ñˆ8–™–V«•ÐÝ\eåT. ¦wyy)ËrµZE òu4òììÌn·ë™T¢(Â&è÷ûÈ1½Bùá{¡ŒL ò?Š¢hµZ«Õ*LZ´ð! ¬ø;ö`:qb½! Á.QQÝn7½ˆÝ¹1Y° ƒA2™„ÿ Ñh°³¯$_ÆŽ‹²l·§N§Ó<WyÈf³y½^òÕ°úzm£9©ê «#ºk=íøvö¦‰v D2>|Øëõp¬Ñ?CÓÌB¤i‚t¤”ºzqq‘H$dYæ¶H;RzØt¦øNf_UÏè/dGmÖTŒV]ÿ—ú3þç]Ý{¾Z±£Ù쇓 ;ØËåïqSy[%AÀ®Ê€¾¿¿‡ß{ï½8N°V#Ž­Õ9Y–U‘bÜÄ£·ÅbÑ9_S¸; t:vwdŸÌ]ºñy¢GiÅ6õ %Tgÿ¢d5Uz ØúÅÅÅÙÙ™,ËN§¥ã…ÅÍõz½‹‹ ¨ãJ¥Âº9dY–Uä•J%™L^\\°^xY– =›ÍÖ:è»Ý.)VLÖp8¼¼¼ä¦X+ÐeŒ3;ò(zMt`·âÜ;¦WH[A‚Á 7A:1êét ‹˜bø«Õ %ô#Û$–1ÝFñÎd2\5i¤Ý#lä^n*•ì´ãñ˜Ó¹¸e2™ pp³Ù|üøñ£GþìÏþì/þâ/Ün7JŸ¨nHä¬&IÁ&ÛU/1K¬¬JäOÕ¨’ÖßÉì³3…üo¥º[Û�½é]ìæ„d"3´qRõÿsB¥¿ÿ8¾Ë¥ÌÈw[–ë_œƒéjõÓ/ŽfÂjÕ¯ýúøñcœ c±˜ÓélµZ¨?Ù*wK£ÑPýÈv»ÍúF€àQ¦8s*oí‚äXM7h@€ª+RÙ½Ùl¦ü ­€³NÓg5±ìt:ΚúÓŸþôÇ?þññññþáŽF#³ÙÌ–kÔbVÝÚÚ²Z­¬§ö]Zµ$”A¬v»íõz)<ãñx”…AYÎe¶™Íæ­­-$åÇc$÷ã²€Žâd8pì’šC¸„)XEÜéa{{;ŸÏÓ‹êõ:Ð4P³ÙŒËAE²Ýn‡è‚Øãóüùs˜hv»]§à&Ǻ›Ïç $8VSôÐårÁwêñxHâйqU@½AÓ/ŽIk·ÛììSz'Ÿ¡PˆJ½°$&tª³Ùl‡C’¤v»`¤ßïçLÕj¶ÙlÖçó)óPÒé´ÒYÂê™z½~Svs¢Õv::1Ý «gTS<Œ4}J0ƒÁ$D¿¢Ñ( !;•¬2) Zkÿ ››­{Æ}™B'.W+n»²™Læuç¸ñx<:ŠÐ`åZ­VŽ>™5aÖ‡ÏçK$ZÍ^_Ëçóœì‚ñáöOjP(Êd2.—K(Pú“ûc¯×k6›ÿæßü›‡þøÇ?¦¢Îª.øH$‚•Œz—ìëÆãq(’$©X,ÂÛ©åç‡Èqb÷Œããc¨Éd¢ÜªÁÁCîPÒæ«Õ öïl6Fµ¨ÍfK§Óª™Hèáx<¦wù|¾R©d6›///}>ß—¾ô¥B¡ÀÖt¹¾¾®Õj`°Du×N§“L&EQTõ@7&¢´3€œÇ÷*Mø½½=UqbI¤ÖZ*l…lôÄzØ¥H2©lîÑÑ´ÆÖÖWô&£R³ÙìäVõ»tþîóùÖep8BûsÃ×´Éd‚*Ÿ†(•JõSà*àÖ£ªèÖëuÕüøf³©Tñ¬ž!ù\Â!IƒÌØíöÝÝ]бß^](‡—--ÁIµªŒ³ã–›ìãH$ÂðÙ©dWqµZåf_}sbA6ŸO§sf‘8Á¥HLââRYÖß©‘ýò»¿û»ˆ–ãï(/OáM®>›‘Öï÷7¨ }ûvyyÉZ…Á`0‰Ìçó\.w£Øhd[­ÖB¡€ñiµZNÁ•µ¾ €ÅãqVív:�Tg³Y&“ñù|{{{˜n§ÓY,ñ.¨rÀu¡ãp nh«Õz~~¾¿¿¯ÓÅbq~~Žôwv=“ÎE|;‘H°ë„M¬h6›¬úÐÉÁ[,§§§:#C±ôl6Ûëõ¬Vë·¿ýí|ó›ßt¹\ãñuù¶··l£wÙívfÜÈõ<÷(ø_Š2æìv»±9©V( |Ë`0HÙ­èvÕ¼2n;a+Cß¿2€Ñ¸¼¼äL™ÑhôüùsØWWWÜ Áˆ!M‡Ùñ£RœtšV©Ûíþò—¿¬üû“'O‹Åáá¡rˆJ¥gkRúûÅÅ…ªS‡<Œ Ò^A0âÀ¤´rå×jj#9¢N‡N®(† V—Ï>ûì–®­aÏçóJÔn·Y©°Z­úky³¶X,’€©§?JÑhnnÞàæ²õh-—ÿµ$I¯6¤Êbñ—“I›™'‹Ét Šßa¾ÿ'³Ùwƒ®ö\¢0ëññq§ÓA]Ö} G°vppÐn·m6ð"JvZB?àiÄPI¤T*¥<p¨¢šÔ²[U9CÙÎH’ f0âBT/àñ£ PÊŽ)Gåý‘u6Á…Š• Õƒ[ƒb$T¯ CD!“f³Y*•�GÅ%AP.HøLè]`_ÝÞÞ&Ÿ›¢–JUü5nßÚÚâ*Ú©0ï±X,“ÉÐ"‡ÌȲ .T bòÑhôë_ÿúƒpt€õÝétÊåòîî.Í~ @ÆŠÐà¢(‹EY–Ãá0à´œo™=ÂÂ$<<<¬×ëxK<w¹\´D1¹™r¹ŒN†Q$?N«–€‚>¥Ùçbò˜–=™ê;ÎÑhl©jX”ª•*MÖM£G4SápX’$§ÓÉUõÅKU-K(7}À ®íímb{ÁÖÒï÷UkØë ß²íììp4íª8VÄ«Øo<<<TÍå[›r}pp��ŸÅb‰F£n·»R©(UÇLXÝí¿z¦T*Õëu§Ó‰BF »\°joo¯xø%=.ì¸æd²g³½ù*gcºZ}<ž0Ã-šÍ?ërýµWÎ¥Éôôû6™Lµ;¤­VYº[ö¸ „Sj(r»Ýì&l·Û³Ù,Y%N‡e€JNh·µ:¯Ü™DQ¤¢2:ïºóFpÅH$"Š"g³³€J¥»? VR,ˆ•m_úÒ—>ÿüsöÚl6”†DÑÒ·Þz+ŸÏ¿xñ‚¸PS©"ˆÜsˆÖ¤ Í.‹œ'Áf³±0{³Ùìr¹”éOܶZ­ ˜geÖ:ˆkîííÅb±x<^,m6ÛÉÉÉññ1øæeYf­%ú½½½^¯‡=¼>«©Ýn8“.¸»»»\.N'åÒ†™Aü4åóùÁ`P,YØUß0Þz‘e8oÏh4ÚÚÚRžØÉ2.„F~\,Ÿ?~||<“ÉäfË$ ‹Eð¼pJâÖˆM²ˆþ`0H5;8wb ¸iý7p�b#G"¨ªH£:ÏKùNÑŒ ¬ÎhC;!š[©Tts‰DBµÂõÆ ìk”~rSÀ/‰S(úÆ7¾Ë–47§ããcˆ¯ÉdºX,~Þív ‚Édr ÂùbññtJª.h±ü·>_áUÂå“Ùìév_jO‰$Iú TV„k@�$‰n·;”,p¨“¨õXà`dYf§v¹\Þžõ$‹ÕëõµŠ¨4ã)¯×;ŸÏÁ†…ÄkNˆÁ4Úëõ†Ã¡Ò›4›Í´´'!+Q'¦¨VŽs©xŸÏW­Vñ®d2 ûàüüœbѤÁ• …ª6p–‡ÃáÀ~ƒ½V#hÖŠ óßf³åóy.AÃÄP!¾Š°%©Qƒ¶ÇÓï÷].—Ífóù|‚ 4›ÍO?ýôÉ“'Íf³Õj¥R)¶R'Ûùµl/œO‘ªp8Œ’ÏlµCˆ. s°ï"Æ,”7m4ú2ƒŒ^d2‰‚Óø™$IìӺݮ(Š\u¸`0È•5Òi¢(j±hª*kŒ�Ñ7hØì•Ò#Ö0â2EU‹FªVQRõF²N‹H$rÿþ}‹Å2Òé4¨mX¿7½Ëëõjí…BÁívCqw±Íï÷Ãú„`(@;åÚµÏzhÖîL:=W6Ĺ!]7º‘'¯×‹Åô*D°,ΟÍfÿ¢Û…+Ïe6ÿu—ëg].·Ùl2™|‚ðŸ»Ýï¿Êƒº˜Ïÿ×n÷Ñ|®sŠƒR ®ÉÀ·N ·ÛÍòL£„²Ëçó¥RII4~ûV©T SP_€Mâ6'6Ûëõ*¾©Æ%¿ßo6›ñ4�”ë ÎC—Ë¥õ]Ü%Œ΋>ŸEz&“Éöö6—¶ÙËËKÚƒ‹H ò'BÁ-ੵ˜¿áœÄ¦øâÅ ®‡J,(Øëõz·ÛÅÓ˜Pª6‡ÃÁ~o  é@ŽÉd:??ŸÍf•Jåw~çwþüÏÿüôôÔçóAÙ©Os8([n\$ªÕjµZ•$éêê 1'Ì>²9(ÂJá(¥2Â'שÌûD"Ñh4‘H°Ë‡îbbOž<é÷ûLA”ÂÉ®Gš,ãj‘¬Õì¯cÝ)O{$Ÿ>Ÿä³‹% ü‡ß9ͪ LZ­‹t'¦Wüù|þððÐf³qŽ¥j=öÙ³gÀ-`iR«ÕÒ?…€wãÑÓJŽ(‹ÆkX°Å!U?4kÅIµF‰• ùý~‡Ãê·z=›Ùü7=ž¼Ív_ÿ;¿ÿMQl,—)«õ¿ôxœfótµú|:ýWýþïŒFƒW¸Åb ƒœ™}·qxi4åÖ�7Ä5 ªÝnC ÀÉf³ >ß «’�•F¶}x9T¯B!²Ë‰3.°f·Û§Ó)ô>¾Z߸өFJ—"‘u Å’ŽŽ ¦!XÜ«×ë°úµ^Š=†lø¸˜×RZ®Õ@Œ×VŒ Š yDAKÈ\Ó O±süà?H$‡|óÀ&+݆­V ;(;_ª×¤�n›^%&aÁIñ-:]¡ü.6i›Í†# ™©V«0Y|>ù²º‚Ì¯× 39•Jõ‰é‹˜YBI___óO—Œ0´šÚâ tÔúmöžµà\³ÙÌj°ƒ�aùÑh¤¿ã*©uÙ)Æ ‚�<øJ"‘Ƚ{÷:N£Ñ`ņËAU…$+ÛcK2£•Djü¼¢ecéÌ•¦5)àÞªŸLR­zêÒ§cæÕ{ŒíÈò¿èv½Ùü­n÷£é4eµþ]¯÷×_’¤‘,ÿñhô?w:ÿ°Õú׃ASÁ £*I€ƒÀ…¢´æà+Ð@<Ùl–YÇ“Édvvv°¤qÜF=›ËËË "Ÿ\@„§ZG¨ù|nŸ«DÛ`­Ñh¨ŠiSþ½×ë±{'‹Axˆ^.—dY×jµ>úˆ\ÛªŽV¡ér¹t2µƒÆ:S¥�� �IDATÁÙÙ·‰Š¢Hyɪ$Ó¬kTÇnÕoËå0·Û Dw¹\²XKZWÍfóéÓ§P^ý~ÿôô9¯ÊÚ¾¨¤LQMô€”ºÝnRC3øÙ à´¦å&3V-cÔóåÖãåååññqµZes;•r‹¢RûÇ à´¸Å8j’BN>7›býp˜n¸Ùa0ÁØn·Y̬j´ƒS:£dµZÓéô;ï¼S*•À@™–ÊÙ}í6¥§PU‹LÕ:¨¬¯R9#\>ËZÕŠdqÄbuöõWª¼/l²üá¥(þ«F# N³Y0›ç«ÕÄb±G£?¨ÕzjkUÕ./¸òP¼Yy#çEÑJ&aÈ�yöì™Åb!-³\.ÏÎÎTØ`•Á­ è³`sžžÞÔäÌd2t‹§+ äPz“ɹáñxprÅ·“"C÷FÙ«à•ÑùR!Ђmu±Xx<ÚwÈ#Hkgòûý‚ ÐlÖj5l¢TÇŒL×z½.úà÷û£Ñèõõ5b?õzÝb±pRÁíPü š.NãE(üzqqÁ ¸MÝÈår¨~ <?h6›¹\yð“ÉuáTƒÞìCdY†Byôèuãââb>Ÿ=|øÐåry½^œ6F£Q*•º¸¸Èd2'''ª‹Å’N§ul|pù Âˆ‘92¸F ÜQÃãñ¸ÝnÖl'ï‹Çãq¹\¬ý§ºR©T£Ñ888øì³ÏHfà(Ö'%X3‚ÿÇìÏçs,F¸|ŸÕl6Ÿ?Ž£Î¨³ìõz[­ÖºÂxc{h¤!J ß„ à‡ÕjuSëA’$6©Í`©e,å»Öæ ªó9}A×ȲÙåêÚí»Ýçóù³ùüÅ|^1™ìñøÅ Ï•à¹>Néí‘eÊk0¨R^â öRnµ�ØÏ*;»ÝžJ¥nÃ=ƒ–Ïçñص±>¿ß¿½½Í‘œÁ‘äjY ƒÊ UJœ¶»»»>ŸOë‹‹E¡P@ðy4…Ãa¢ób“Ô¹b‹FÌ´›2†í&(J‘°€Ô0ÖÐÔ+‰ãè8…>³ìÉx:OL¸ôwåb ,;T| šf¢-§áeeÉåra3‹Åbo¼ñ@W¸Y‹œõ&Âöö6¼èQÛM&Äù:N °Z­löKZüƒ>‘4}؇A@÷æó9ÐZõz=8În·‹Zú•SØnÞ à#Ñ2(3•&ËM̉ òB'“I±X$¥ÜR·ƒÁ`<'jàÙlÖn·iÛƒ½«L-ñz½(ʧÏ#>ŸÏÁ§HÜÖÖÖh4êv»———ßûÞ÷‰Äùù9úFܤ äÕßË‘âÁ¸©#Žxotü%Æm’Hš‘ü– W?ûL¿kߥ,üjúù§¿òϾû÷þÑo}ç;ßѱ幠+çí]ÛJ¥’‘Ø ø™ÕjUF>”Ý0îÖiàƒÑñJ#²²7úE1›Í*ƒô]ú1$Aµ"X@†*ÿ¾»» Ç®×ë%̬ê�þ§mg³\,(VýdLÊ]u jýèèH޽=Ì”Íf{ï½÷Ø¢˜Äh4 çóÎÎ2A¸ÒÈÑ'݃ƒ›Í¦>=Éår_úÒ—à¥ùÊW¾‚zð:ï …BJ׊êØ¹ÝîR©d$,dŸkÜm€Îœb@6piL% É•$é½÷Þ+‹n·{ßçó½ùæ›ô@ ðÖ[o‘7ûàà@gº±Z7è¶Ö] ¨¤¦Óit Ò7‘×Ý~åW~åßýéOÿö?ù?ÿæ?øß¾ò7þN­Ñ2´9™L¦d2 )Üßß7>¬Édñ�U9Ó™Þ> êñxòù¼‘)×ÿ6Œµ? ƒ™L†ÛœÇÎÎŽA!0›Í ”Ùl†bµÙlápøí·ß&DµhÁ5AOSU…Zë¶X,Rî“ÕjUu›^!×jý½s³©WT4UVˆázˆ[ØÿÂGôî»ïªæ‚Ò]V«¥”‹_E\bßÅvO)¤gµ¾’×ëEi+hwß}÷ÁƒßúÖ·~þçþÝwßËQ<W}ýðd­Á%Ô2g+‘8Ýrš Ê›‘•‹±åÄ Sé ãMUfh‚AÈçó h!=S(Ø¡xoúö±Ùl–$ ‚±öí7ê^<WÖE»ÛYÆ<*7§õn=ò&# ¤Êa¡s¹P”0Ìt:M. ÕÍÆå éì¿ö +Fÿ‹”ø\dèqwyÕnOát:¹ââDðªä™ÝÚÚb+H±mkkKé~aQ“ý~ÿßøF6›Çãü1½ì’$e2b§ÎçóTÞJµþ,°8Ê1!T/rô+•вJžÓé´Z­Édr0¨²³Óúª÷n°RfP —›,Ô¦ìv»„WÅüšÍf�€0¤@�žX-§ÖÎÎŽ’™ +dÜ!Q˜ �’ç#ŠôðB¡L&!l 2QT¸\ÕëõétбF£pƒ£¦€Æ‚ ”Ëe¯×k·ÛQ÷OÕ;”ÏçYžY`º%I"×¢ÕjÍçóWWWì E‘ŒÔº¤ïæÚ¬ŠËåœ{$N6›pudkUÈ ƒ¥Ri6›•ËeÖI€ Wq×_¤C#®¤H&eb\ÝÝt;DZ  B ÜV2³â¤þGùæb±¸ž¦ý55ˆ ÜåXŸ½^OǃÉ26½¾ê°›bÇ@g©z�*ãñ8t>™P“’$¡"=´±­£u»]­Ø�œéœ¢ð·Ãáwß}·T* ˜ÌWWWºt:=‘mL î³Sh„,.< %g¹\®V«u:¯× ¨¯ÖúÇèI’4ŸÏAp»Ýà¾BÏ9ü£ÁÖét°¼‰Ò©ƒœË{>ŸCç†Ãáx<>ˆŒy€" K¡PHYøGÎjÁ]È6FY¿t:Ýëõ, "ä4Å€–oooªÑÙn·h”$ ­Š‘¡P(\^^úý~ÌþÛo¿ýöÛoG"§Óér¹4‡‰%_'IÒjµ ‡ÃÕjÂbºá!Ä’Ô™bP “踷À.¹©ŠÜlgBQWÌ#ǼÅvô›‹ÅâöäŠX¹TŽM]“$I’$ *ïíí)ËÞW’ÆÏ4‹ÅÂétn2˜u¹\O­ b—�¡³Y|®ª8I’´X,`ÐÔj5=švBƒªîlÉw•`nÐ6›í¦Eæ×ºÈðCÖTþ½V«ºíââB9ÖX&“©\.C)w»ÝT*…‚ÐÛÛÛÃáÐjµ¢6W®QŸ Êpîu(ËÅÞ~ûíû÷ïïîîîîîÆãñX,–ÍfN'øçó9€u»Ý=·C§/”÷Gz€ k_4(Xã�Â¥Ñ0èéæ0Ý,ŠŸÐï÷Éüç<<Ãáðôô”tÊl6Cê*www'“‰rôx<Jç6ÎIý~ÿøø»×ÉÉÉh4ªT*’$Q'ƒÁ`0œÍfÇÇÇÓé”C‰‚ÖDÅ~¿¯\tV«ÌŃÁ�iØ×Ãáp:fy†ºÝ.ȳ-K.—K$ûûûÅbÑáp”ËeRå„é6™LÕjçE¥ÇU’$JL_,¬èz<'”âU¦T*‰Dtܤ7R&&]”+;Ë.— I•I$¡aôûýìºë÷û°¼^/ ¾t©×ëÑ%»ÝþðáÃÍHë)©’”‰NƒžÑè7,“µ'Hý„²f³Ée²èl°AêÄ€Ñc6›µ¤Âj$ðœùÆ›kz³�É;i!½ú•c551ĵZ›ÓZvHe”Õápø|¾b±xpp ŠâùùùÉɉÖç+ñ¹’$9ÔšãÌP^"#q2™´Ûmªsj·Û±ÿe2™óóså¹{ÆZœ‰)ý©%F¢ú\¨„ή×ëжø§ñ4K€×ëEýo¬ ªaÁ9q¸ 8”°’VS¨:WµZ-œ’á¦cmծ鬒–(& ŠÆn·‡CQ±ŽÇcÂÉ"I'Úr¹ì÷ûAË}i,£¼5¤5?~üx4Á¡W­VÏÎΪÕj 899Á©4Nõ«_µÙlËåòÃ?\ˤ®Šš´Z­Zn }B�Ì~2™¼ÿþb±¸¼¼¤<ï[*­ xn©®­³À0Ü’'›Í†c7‡ϲêy…V±N‚¾ÙlN&“ÓéTi½QÏ•ÊD„H$Òét8º[2n¶Ù]72#dYÖÏj!$¸jyˆ/lNpø¨þh306F#’‘Éd®®®"‘§’ ®cí+8%ËÕ66­Cüɲ¼V]R‘4VždYÞÛÛËf³ÓéT ËGå7,oå6�g…²¬²Óé ƒívp™'‰³³3$ã,0†—-´bF’ƒYc8æ>p<³¾”d2 ÀrèÖzç{†y ‡Ã(ÿÓn·ø+Ð ÇCoá¾—ÛPÙ©gP(íp8€ÀÅ6qqa±Xòù¼„ Éd« ˆD"¨1n11’éW«•ª Q—p—–Æ8>O‹Å‹Å<Ïh4l,ƒT Wx¹\"¬ëp8¢ÑègŸ}fdËW-°q-J|W"‘@æ–…ÀYe‚ÌI%Kù|žãm1¢L OÚí6Ä©^¯‡B!¥¦£ÓtŒ9 Ø1ª=a!€œ2Á„nFLÌê™Ý…Rg7ºÄ®zö`Ý l¹\‚YMwײÙìåå%-3hI#7"ü®„és¿Þ¦)ö¹†ÓÀÈšÔAÚ"ºS¯×q¾A09“É€Ú¤Aöê]­ã6ÙP¯ÓéôììL„T*Õív°}ùò%†”“¤ ° Ìív{<ýj(À¨éü@k²Ø1ä@¸¬(ƒx<¢Ñh2™´Ûí?üáu6'³Ù|pp@QRÖ~Ò‘{]UU.PdV«•ø  †NÅRÑ6›Í”RÁIGéÂ6hÀ7¨óÉ’$5›ÍápˆÔP‡ÃQ­VK¥ÒüÁ¸Ýî“““L&k†`U@ÞÀÁËéY„FÝ}ùòåZ³ÀˆÌ|Îf³«««gÏžaL8®´\ß^Ô2šeYîv»§ÑþdD™P�zòJÐ~Cô%F*q*ˆt½rjÖ ¾žÑò–Çãq­Â7À•껵ƖáóÄŸûù¼Ã„ˆù|^(H˃ïËÈpë+@ªG"ý¿»jP"e*û]™L¦Ýn¿|ùòÙ³g  „a+Š"²³TŸéñx`j±ÜÛÛÏ ÷:xöæ‡:È{&“ ŠŒqÓÄo�Ó[ëâãF!wêát:5‚!%< ÷÷ÑhGV"‘H§Ó£ÑèåË—ZÛáöö6h5”²½½ò_à,ïõzH堨ƨ‘ã‡Ï‡h$>Áz>ÇÞÞ&+Sµu¥”BlvvvjµZ±XœN§±X¬×ëÅãñår©Å4ŠD¾áp¨ÜYÙ?Ât#÷ 5PjµZ­VF­V«Ùl"•uå2½¼¼|úôéåå%1¼ÐჅ{ã-UƒS¹\.[Ð_½^¯R©´Z-­ŠG6ÞtpÀYO&’ê\.×ívuÔ­¬×§X”+ˆbqp¡[ÐC}ýã÷ûý~¿rÏV…Òë<Ðô î­µ¥m€ÍE1‰`”xjÇóõ¯=œÞy]Ùzóù¹Ià|Ms È÷ë8Q ‚°¿¿t£V4O±XŒcœ‚Ÿýùóç§§§N§ìS”(‰D°—§Ói,˜^ÂØáúÐï÷Yâ«L& =:àp8ØÝŽ=`‘COKvõw&TJå$¶óR³Ü‡½^o0dõ ”Aým6 sY–Ýn76xî¨],G£—ôˆKo¾ù&вn·ûââBGÛ–J¥\.—N§³Ù,çúØÙÙAb–S§ÓÁ(¡~ Ë•€ÚÜ9²T*Z€}b0hqó cPU3â^‡ì†ëëëf³Ùétð]o¼ñF¥R™N§~¿?™L‚‰˜%„çgwzìÑÑQµZe‹VÀ±©º¸ i‰DÜétf2ŒÕx<^»Q†ó *—cãŠ| dëÒ÷*×9{ðÉ8R»ÝnNœXcQÉ\ªÊAÊ)“@  …ô½X£ÑˆÈáp"Dçi”NOO•›ëîî.›©ˆú÷u#GÝ¢ºTïÖÜ'ú¥òt:ï¿ÿ¾ÞæÔjµ”:H5BÀ½#›ÍBÑ Òèfåì8c\,ì!”—l Ãív åF(ÂÁÁ«hÈ£¢¼ÄÎÇ-Y“áoa©K‘e ®×ë]__˲|ppÐh4Øt– ·ßïèQŠ£¤¦ûý>ˆ#ûÞ½{¤£•®9¬üÝÝ]Tâ~Ïç÷öö:·’ƒCÙ™L&ZÑuŸÏ‡}ZE¥8ÅU•jµZÙívQ?ùä“ããcY–Á'I‰œG{6›Q 3@êÔjµétšÏç‘YÐï÷•ü¤ÐõÉd0d$ײ±Y°¬–ËeðÓt°hµZ±s AˆÚ®T*=~ü¯ …B¥R ¬êív“ËiÈ{ ³tK&“AF;Îîîn¹\îv»Êx*™&(Ü¿òàIHâñ8ËËgµZYø$íúúOfýœÜhpR‡³£A+[‹.Ý q­’]3‰`·S54Qü‰Ê\™Œ§ë°Š•N~()%k]”áp˜ÎvÊÞ·ÌöÚf³¹–rWé„t£2fª“ýær¹m©êd*‹Û÷hnN?üá¸&÷öö†Ã!;(ˆÃßá6 «ë½²¬Y¡Pxúô©ªd°rƒøÐþJ,›‘À },@KªD .³Ž³ú]×±JvvvNNNÈ‚ƒ²æêÓw¡`9‹‡Ùl^›Š‘Rª ·Ûm³Ù8‰ß`ЧÓi·Û%à¶Ác+à{ Ö&—qÌ›´ÙZ‘80;HÇÇÇý~û ñ“PÀÀ`0˜N§‰Ä‡~øðáCöÃA´X©TرÙl,¸|2™Ôëu–òƒ PÇëõ>yò„»„bWªb ‚ÓéT²xpgYªáë÷ûƒÁà£GÜn÷ÁÁÕjU5@[ŽC°²Žß`0@F¯Ùl†ÍÎj¢(®ÍmQÂi•Æ-Äb± ¦Z»ù9X÷¬j»wï^³Ù´Z­`Íx}qÕE§ÕÂáp>ŸGÏIH,‹=1Ö¶Ø»r]BfDQT…[(OHÊ$ÕŠZ'…ƒwnëÖk47‹ÝÞÛ¦J jä rUŸÏgi‹òtÊŸmmmÁ …®I§ÓkãìY‡3¸Ty-KÂч"ð`Âõûýñxœ šœŒÆãqÒ’€ ‚ o©QUPÕ“>[˜uã†a7þð4K’ï‡Î¶Z­N§s>Ÿ\¢ìy4Eí–÷ßooïèèÈçó=~ü¸Ûí*5ÂZ£Ñ(“É„Ãa�œOOO?ú裭­-dÁQº Ê0ƒ‡÷F£QT³¦µ°6©ºU8ŽB¡ÀÚIÀŠår™ËåôçæÁ™[©Tà\BÞ^±r#ï÷û~¿Å—•—¦Ói*•Ru¿loo#Š£¯îpáÓbD¹Bƒî>ã|¬ƒÁ@ggRÍápà@s{îì» mT«Uäè’ ×ëõ⟪Ժ’$¡jöfc¨#NàƒÝ@iH’”J¥`zúýþo}ë[œ[oCô‡ë\Û‚ÁàÆH) 4óçâ]DÿŠbû‘¶ªp°““š•^¯÷äÉ“;ߘÝnw4åp-è|µZ}òä‰ê^¨¼´7g2 Â%$ãlNk¤Y­ÖX,¦Ê€‡\^L=Hr¹„¶V«•™‚Á …óù|,ÐÄÊ¢(šÍægÏž={öìÑ£Gßÿþ÷çóùÅÅE±X$1óx<N§3 ‘SF"‘qí@He pÇûûûÓéôÉ“'ªóˆüi¯× ü£ÇãÑZY�n£b »t‰á¢F") `°°7³—¸õH�Ø»¢»U}½…è˜õ‰k¹»nÔ”õ÷€³~ùòåíÝ_xš*a´ËåÒçêÕf¥R!sU”X6sÎó¡ôq‚¡3†ªu�”âtSヒ §Ó©2,'p¿†N‰F£·¯Dëv»©‚ÀÆœrXÆår™ƒ|Æb1Õ5‡Aƒ7‚yÅà‹”$wÕ\.—>6¾Ñh�MÉY%´ F"‘»ª Üh4Œ¸‰AedäÕ¬Ì ‡ÃF£Aâdä|©\9x ê£(SoÍfs6›EvµÏç³Ùl Cu dðÓ¦\WƒÁàäädµZy½^T.‹‹‹ ¼Ëçó ƒçÏŸ›˜B™l*UIØ”=ŒÅb¢(ªÒÐÍçs6¥> " ©¨2½áGLÖÉÉÉ èQ”†Ëd2žÒ©„2â*ÙÛív6âT:™Lü~¡PÈårÚœCî«ÖK5h€*{H9î‡:” {:MýÊvÏãñ°õM”ûZ­¦£sÃá0Í‚Ýnç¦X©´XÖÖüŽÅbìö/Š"í˜bú.”Vêt:kqÖ‘H× åÒ»€î¿ET.—i5F#¥øÂxQŠšj„ƒëµå÷Ùc âöÊ 6nv(íXì.H†Ïr¹¼ººÂµV#Jòy%Kèö×±9é§Ãù|>¶Ø ͽÇã!Adow:wËS %:x)ÐÙáp&ž–h*efmÆ#1á.—Kåö ©ÎAp>Ÿ›ÍfÇãóùjµÚÅÅÅåååÅÅ*}PU£ÑÐ:7/—KDŒH¨è.Y–‘duqqA_ÁŠt­V‹Çã‚ °w©Ž ;w‰Dê�$uì/ñ?ªôĤÁÃáðÅÅÅl6cmÛD"¡ŠÃO$ F.†ªÌÌçóz½Ž·s¥÷©(†×ëEX.•JÝ¿ÎCÜÂÑÝn¼|8N[-M&VSsÜÙkm º‹Na×y”Î?¹µÐétT]jý~_?‘ËlÔáb¾QçÑ=Ìþî…8ÝF±'V8sÆFõµíZðh4Ò·ÐoStœíá|>º3›ÍªÒ*wAБĕÏçÍfóZ§¹×ëÝ €¼Ýn×Ù†§Ó©Ïç£ #aekG²¥†ŒG¼ŒŸq•8Y–ÙC'pµ>_)3\9NU ÑYWÍfSÇDbK*•ªÕjÇÇÇÈ„¼¸¸øøã?üðÃ?üP•΃kN§“=f³™%XÁ±•Â?øq `UI¿ß×±áV«U¯×Ëår±XŒ2Ç8Ô¹ËåZ{<].—ÀzÏf3VGã¨ü=BGÈ>ב™étŠÍ›[(û éÍf³?÷s?÷³?û³ét/YЍRÿ¿©¦Su¯ù|¾T*EG‡Ã …ÈQÏ9uÉ+Çõé&t­v¢Filk·Û,g&'¨,]ìíý\t墸鰯­[¦üäd2I‰`·¬?§š'¼~sºÑQ€µFS©Ôå\µÀ˜]‹ÅëõÖëõµZ{µZav @7‹›Fp:á«p8¬JM­»&“ ëCè÷ûÛÛÛ�áŽÇãD"qtttttDðù|>#‘È;ï¼£ê2ŠD"ª׺4™LÖ¦BÑd©¦GnÖ‚Á ~]Dý^-‹«««V«EóX­VËår«Õº¼¼T®Ø£££ÝÝ]ÖOö¬·?ƒÈÙR©§4V*•J¥®Ïç ‡ÃØ„¸ .”C¥CñÑõx<ÑhÒ’Éd\.×T*…3r8±T‘æ°V¶ãñ8„Íjµf³Yhs$†lmme³ÙÙlf·Û<xÀÎQ4]ë1B]hzEÍÓl6I3 ËKžl±Xè½ív{2™look…FjµÌ‚Åb¡oX‡B!Ö»ÛZ 7m;;;›Õ½M«×ëÛÛÛì_tbN7m”ˆ[,ŽŽt~y7 \#@¼Û7PΨ®±ápèñxTk l n ît‡ˆ}°5+Ça-Ê•‡­Vkgg'—Ë!«ª^¯ù¿··ÇIN§S§Ó >²Á<D½A®^¯ÅmÙK@j!c´jƒá5›Í_ûÚ×{c¹*6n³–~6›õûý=Êd2/_¾E‘T–J¥t:m±X(Õ>‹ET\Uý´v»ÚToTÞ¼‘å‹–Ë%Ê©f]âCV«Õáá!Á P¼\©‘QHÒÂq{½Þx<~uuF1ÖøPMÀS]G6“Éd"’‡tù?üp4´·Ûíb—]+½^“1UUáRY¬Ëårkk‹ncßÂcáªÒ–’¤‹E}I›ÍflªýÐZ 8q­…Ê×­Z•‡(iIBuè/{{{ZUQƒ{†SRfÜÁæ$yB ³ÐФ)O3ðn³#Žœ"ÐIœT`0xqqaÜÙ¥ ë[­V¨²ŠÄ|�—Ï籜ð(Õw¶EZquooïäää~ᎎŽü~¿ß¯ÕjÝn7›ÍŽÇc€”eô&“ÉóçÏI=!u 5F‰ã‹Þ ì64øÊùºQÛßßït:§§§œRe—A/Bþ 7€`’]­Vûûû(QˆK¨,P.—+•J¡PøøãQ^…;­¢ñ~ô#ROÀ–ÒªS !ª@Åãq˜*´Y«qˆ(„sô� `ë”Ëevg"œ f2C“bµZŽŽÎÏÏ»Ý.H•eC£Ñ¨ÏçÓ‰p šˆÔdA$Iúä“O iÍfóþè�ùÚÚÚB!.^`nô•¸òÕXoUåM/Ê�� �IDATž;ª²*RiT±£Í.:eùÁƒŸ~úéZ“BKqÝyc±qZÖðëÛ™\.W±X¤XëXæäÜ Øs9¨‹…Š (Õ ™ì`/Ëçóë7'§ÓiiÌnþ4‘PÄP J–l”ü9´Øçó%“IÎm²½½­¬ÐjRT0RâsתÚ`0 …8å%Â^êt:‚ ‹EìðÃp=¤ºßï§’-˜H¿ßTÁÕÕÕÓ§OA /A#ý~?`‰¬âʹš^qÚ²#›Í–J¥¸ê7šb²N«%ÜÜ%Œ\.—J¥0Ñ,á)P“Fƒr‹s¹Üùù9…PY…ÅîõzýììÌf³ÕëuUÂV»Ý¾µµÅ !>¯¯¯Ãáp0DEѵìÉ&“éàà�ž@¼(£tˆÖ�:ª¿@óHïB-%(ëH$éÍd2¨ ˆDw0(c¨&볇 e!â …Òé´Ãá(‹<ˆD"———?üá¹AƒOR‰Uç¢÷,Mêën$3eÁiL‹Ay^QîLV«UB¤é– ±7²HŒÃ‡Ýn×ßþá¥íD•qû6mkk <>ȘÕ"¢œÏçívÛÐÉ u0w‘XMM¯PxœÑšH$¸º^ãñ˜Ý™Ìfs*•âJÔ@Y³ÀlQm6Ûb±Àý~ÿ¦ ÈÜÜn÷ùù9²rÙ*d·Ü™ð@‡Ã ˆðœ O;®²ºI¥REñââ'Žk’îªV«k?•ÓXÄt Ç4;àå#Ø©‘)ÖÂ_ƒ×ò–V F§Ó©V«˜}8ÇrÆ 2M° Ò+—dF=ÌfóÖÖÖt:ÇãJX%yḆS,ˆ]€Vbºív;€±`›•e *{™Îommõz=âêEs»Ý@Pʲ,Iõ‡BD%Ùª‰˜Aòè²¢ëp8, ·7@q‰Ó¡àªW €ÓéÄøommår9«ÕÚh4¾÷½ï±Éô’$¡Ä8ª“`D£Ñ|>â¡Ô”þ4nG‡Óªê;Õ(¯‘g’žáþîv»½^¯êAÇãñ/äs£‹Å¨ì/ø¥t¢×$„=†Ãa}…ÆtX¦fƒ#Ïò s[#L±7ß|3‰‚€4w2”§1=&\j/^¼¸Q}u·Û­ û¢†Ê›Ø¨U!r«ÕJ¹3ÁŽfKÁ£2 = ±jÁÜTQ¸õïP’€€ãÀq\C!H}‰ùË¿üË>ú~°ÛCÓYÄ4 †r‡HãÉ,`±S½„2w5’ !EÏ „«ê¶&Éq»Ý¬Žv;V˜!i�9q’·ƒ×ëåàÞ'''ý~±Xôû}À'€é&.é,9¿ßàK<ÿý÷K¥Ò|°³³CXK$׃AÿH2ÃÒøšL¦jµ*Âp‡X&ÁF!fä‘;% Çf³Qžclpk<¿|ù²V«}òÉ''''ìÆW§Ó ^¯—Z¨ªÕn·ý~?;’“ÉÄàÁ…„MUÌð],Ø vâÆV�¹5µ¨.z½žœà–­R©@€Ãáðl6Ó¯LÆfŸ=yòD_Õè¼*ÕµrxUA~¨1-IÊ%sêÝårÑ]:¨A©hb,‹¼áÆñ&Ng¬93«X±g®wµZ‰ƒ(o5‹‘n]‹™Õqèu»]¬i�8è6V‚Fª>™i°S+q‘ì¯V+‚ß³wé¼]k"*/»Ý¾Ù’྅^D \¯×›J¥R©”jŽŸ**U³Ù `¬’á W«{dD´…‹õââÂår•J%Tº|óÍ7Ãá0â=¬·½\.³_ÁÊ kÖø|>€sµ†�•ZBøÆo|ðÁH¾êt:ʃ ‹d‡}6›f¾×ë}öÙg?þñ¹ÍÉb±ôû}<°\.“ìY,p£»ñ=•Û9” \¶‡‰D‚Ô@  j›²ÚiµZ­-;‰£�ç}ÒA1ßí!IǼ3RÇ�)7½KÙàýVÖ¬QuËsçE‡Ã|8^__òÉ'JuÇÞ¥ÓCA'þfpsêv»lÿtðÃËåö…AB Uè.kS˜˜ (›¬<y<žx<žÏçÁ¸êp8�@I§Ó¹\ÙpI«{¨Év{¼e¡Rö(é  …DQÄ9ÄO  ó lªÜ% �ו8kU®[ÖfR Sß´…ÃáÁ` t4a€ó´\ÏÙòØ`_Íf³ªf Üæ$ po’›ÍvzzÇ/..à$Á¥z½Ž‰ïô„H$Ðò�§Ói«Õâ¼1ðR*AcÈX!“ë*¤=q¼ÓìWÓ%8ÖDQ<<<|ðà2™%™LBk§R)Nk`k¤K²,w:/^àÜÀÎ,GØF—Æãq»Ýn·ÛgggÆï:¯ì%lÕ&“i:’ÉrUUƒÓNFº¡”^œµ‘£›A÷ òPP"€kJ4z04R~åúúš›bãã€ÔM#{*{Ç�²èl}€³ÎU>æÚ‹l6‹¤U>·µAî–t:Dz+ó6a·t:MA,ƒ±ýH$²X,¢Ñh£Ñ€÷èè°¤D"ô¥Íf«T*ÛÛÛÈAP~Õ7B1!UÇ ƒêS¸ri÷Á`Ðáp´1eYÖa�C"; mèwP$°„“Vûx<ÆÁÚO þÓØÂ¬ÓGÏáEÆíåT*5›Ír¹çºÄ!F©ªÀ„ÀŒÙl. ì™,’œrøK±XÄ»à(g… \2™#‘˜’Éd8F‚>ý2“ #í¹ŒX,vzzºµµü\½^¿ºº¢ÓI>Ÿ ¨&¬JÚ…Ž¡æ¸ív;¢Ê˜b@vH–ØÂæóù'Ožø|¾««+¨×h4ŠKHP†kŽŽSÉd2™LpÊjµ"çBµZ1‡æÄRµ(Šž¨îËåRk!«^b_® [šD6›-N7›Í»­aÆIZ>Ÿïõzªû(¾HµDµò˜}#ŸÌM15 ¨´ ÆW±ÙlN$”Ȫ3úÍh*9?t¸&Ѽ^/J¼`sƤ*oA4[YN_g+&êRÕ½`Ð3–H$œNg£Ñ N'N‡B¡|>Ç···³Ùl.—CPý{ßûÞh4²X,Gi2ØívªÛ¯Ã“‹*×:>% Œ}Úîî.vÐÍV-–îVÉ„›N§¡õˆ… œ¹¤å‘®ÉN%¢²ZßxæMiâ0J° ^º[ö(wDŸß{#¼ˆ§•ý.<ù>ÛÛÛÊ*'lªú‰D8v8lŒ }¦yd÷rv…B!¼|ùÒápüä'?)—Ë@ª¢¤z.— årY‹èH§Æ#NÆ06•ŒÆ.—+@ A¢Z­V­Vk6›v»B…|"ªûô Q"‘h·Û€INA;˜&¬<H’¤dj6"Ÿ7er:Ø/µTßï¿«’á‹l­_*•t–*’?Y@±É�í¯ªÊUþ‘fww_äup:ìµäiŠ·¶¶hÝÝIØ(·Î 6'#s¹\àBÕáB *QxZ ¦X,ªÖ7Êf³ÐA¿Y’$A0Èá¹¾¾Ço¾ù&XP�ꄺ\®/^ŒÇcAJ¥Ì1v]Qí¶àdž õ„-J”J¥étšH$X6Ò^¯§j¥šL¦££#XÒ½{÷úý~.—3›Íðù v%�„‹…GBi³ÙvwwY¯`ÛJ÷Wã‹kH9‰ŽX+•í|>çHrçóy©TÛȽ{÷”Ø~¬Òû÷ïöÙg„K%Øœ’­U'¶··€$Itž¦¼Dåì§R©X,6^¼xQ¯×¡Âá0ŠëÏçó`0øüùs¨%Ò…ɵ&!´h4ªª@Y|. ü3àf–„“óà F#Œm‡HVâ]ÄÔ¬Å(7/»T×¢ÑU?Ùf³…B!Öö7›ÍGGGµZÍív»Ýî ¨žTmãheŠñìííiM«1ØÑáÏÝ qzUY€›âápHó»Ê¿Î\åædúù§¿òϾû÷þÑo}ç;ßá”ÝmN²ÊÈ äéu•e³A8<<D|EÕ‡Fù—ù7ó7¿ûÝïþÞïýÞoÿöoÿê¯þê{ï½'IÊÛ 2 Ô§ª_‘2…´b˜ªÕ>°'ÁE+‚ÃáXr¤D{÷î™Íf§ÓÉUÑïz²Wý1|óÍ7¿ýíoÿò/ÿò|°qø8Vö/ÛÛÛZõW€€Éæ^þ̽ɒ\Éuó<Ïó”™‘3¦À"YÅA&“™d½mm´é¦VúÞÓÔÿÐ ý@›õNÚÈŒšH‘4© @U ddƘ1sôân;Ýß{ñ2Å–/h,DÆ îׯ»ß{Ï9ܰCïXòdúÙgŸqiµZ˜®Â€(ð¬“éÆãñ`0øøñãŸüä'ÏŸ?Ç€°æ„Îs¿’H$PøG„å^¯—¥ì£Ž9NnRh4ØÁ×ëõ¤â!.IIû¬[ÒÙØæ÷û×ò8«YãÌF/.÷RÊ£„–ÉdÖ’ét:IÇEÄÞêG)ŸÏ£¸fã·°ïžCG–††B!…¼7¼ ΄µÏh4 ·¶¶ÔKçüâ¿øþååÿöþßÿëÿñýàùßo-Y†ˆûìíî“<07�88H¯Ëå"FN|J(ÂçZ­V›Í†ƒ$Dhìvûr¹´X,ív»X,¢^6¼y󆞜L&¹5{·S>aíììp‡M<÷6Äßò“Ÿètºz½®€ëçôd2¡ZN†XM,emœÐëõ>xðàððÐårýó?ÿ³ä© r÷c«ÕºX, „PqvúšJ¥v;8›‹bC[ÈyHž©kµš˜l¸¹¹8¡‚}ÊáEÀ üx"‘(‹…B!{½ÞjµÊ½3™ KSEÄ^¯ÇÞ¶­Vk2™„îç.wvvP8@c›Éd`ù\Ž®hDOe6›‹Å"”àµZ-ö×X,†™²Ùl‹Åo hòÒ;;;ÍfÒº³Ù, šÍf±H"¹wõ’@�a† HU>aýbjS.R**nKÞ¨$×öööZB2'üçänE£E¶¥Óépä#wmÈzbÕ8et6g3œ3A­|;J@‚ßIYUX^û>hJ9Ü}pf³@KöY¡ªh4z{{+†’ÉäÞÞÔr¹V8¼Û7ß|suuÕjµ¾úê+®t„Piš?ä•„ar­ÙlŠcÈ>d'''šÅþ’ëäZ¬5ˆ|ÊÍív+wÕh4¢ à»o¾ù& ’ö+!4£Ñ(å'@YÍÎB"‘�qœ˜®CÜÙõét ñ��%w‘^¯*µFÊê~¿Ïêšã¨[­V%yÁS ŠaM×år¡J"‹EeEcH$FpâGÝn7 ‹þ®ßïcl­Vk$ÁæÇ!Áûý¾Á`ÈçóN§s±XƒÁX,†Á4µZ û=Åð¶.—+N÷û}سÅbI$ OÕ|LÑo°�Y·�T¯Ïç[«tNÃîp8¾ ½4¬wU{J°± Ai+ÚŒÜò‘\à°˜.ki¬}r>•ÔÄëÑh<ä!CecM—£`¡ôXûˆKËõPÁqÝu+QÂu:bHJRòÒl6o@F¾¶qpZW¯×ß¾}«pJ‚Úøï>|¨×ë©z½~vv|ëÛ·oÿõ_ÿµ\./—K°Â`1òÍuƒ^–•Ö½«´’×ë%^jŠ•×j5…£+ 䨬é#…nFÄb±HÞ²Ãìv»ïß¿ÿÿø^¯G¸]¡Y,É  nê///iIÃ0`3@MB½V«% ³ÙŒ*ô_2&ãt:¹¨î¾ÜýÃb±”J%ÐMˆü;c¹` ‰ä*7�é:N§Ó‘ƒ³ðíÛ·ãñØd2AÓ1X`ÑhD¼Îf³5 ±z¹\™¹Ÿÿüç?ûÙÏúý~¥R!t6RªgggÓé´ÙlsÚív‹Å"[ÜA·7•:È’¡ìX,ÆMV£Ñ`ó=’Fèõzñ?Þ >¨æVP¹²â6‹£‘¶dœÍ(àv%ß3û¤˜¡ìÝp¹\’tÖ±PúV«µ¶È›üÌ]/ÄlLæ$·©qÔâÍÜG(ÙÀ]M ‹ÃN+“< ­åQ_Žz,])è&T¯×? Ž€)(|ûö-B˜ÂZ­†R „A =©ç³ÙLRøNýR÷x<“É„P„mÛ FÌŽÎ+•ŠB7�©#9s.fX©T o£ù¨ŒÅžtè#®M&ºk±XªÕêb±0™LÁ`¢mxßT* M³Ùìõz‹—£ GÆívëõz1)4z½~8²â؆Ã!”^¹Àm5ttGÕjÕjµ³Òn·%‡…Øíè¨D^†ür­V ƒ•Jô-ZSà>·Ùl îøÃÏ>ûŒê³E ±dÑêñxX¢<n;Ùlù4›M�TÉ-q”òZ@ÑZ4Íf‘Hä“ÇTà¬i¿Wø3VàU®"«œ´.˜ ƒ×ëe/âdº¬Ø1‹gG Ýðûý’—3‘ {í& ªxÍâ©Å}ñNÆŽÈ>ÑC¶Ž†í¡B ’«Ë—´¥Û6›™àîn„©„$Œx_Aì[ù”«¼$‹›èrƒd•ˆ™­×ëÈ9Á«ÚívàWp]­V———Õj5ŽF#”¸ÀË$ …×T†˜±‚§¸ìSiœ$}ÃÚ9æÄ+›Í&¼¤r7ð:ÄÉF3,ÜÕ\Ãbg™¢&“Én··ÛmØ P“pÓ$xzWh$®& B!s"à ƒÁ@r)Šxj¸ ÎÔ•§¸R©`¦0Œp4¤i»6ð˜Íf=ÏücS€QÓO`ÑA‡÷òòJ1u"¹È§Â¢t \ñ#;–Äç. dI°ª¤ÖjµËËË/^|õÕWý~ÿ;q®Õj ÞAÚ»–~H¦aöööPÔª<›’3"ŽR³Ù”ÜœäôsåëÃÙ\:²ÐM/9Kk·ÛȶH~‹0Ý 6£tK¡œS·ôîåË—âYTÅâËÒé4 ÄV4Ê9ñD"!gä¾›ÉdÒé´Hu•L&Y’Ye0,€fóù±þV«u{{kµZáªHÀ ÅL&³AÅ*]’4  dá;;;‹EÍI6‹)(ü²Ú3 >ñFr:qxY|®rc“̨ÁÍårívànäÅŠD"w’|&p†¤}ËaÅÊ”V“IƒÜOV˜Äd2©Óé¶AA ¦¶Ùl`µ¨~¿ßétðÝÕj8‘äomm•J¥Åb‰@ ÐëõF(n©Tj6›~¿>N \Lf/çh DìG$î“J¥°¾À6‚W*4W‰µŒÇã³Ù¬×ëá¤ëú´ Ià êœ3Ñ|ĉo–úr:Çãñ|ÿûßßßßÇhɨë1°ö9ït§Æ=P²‚EÎcР3N«ôi nA2›áFFÙfTåœÖÞ|Ù•Ï:$u¸Ó®Êò|>¯×ë.—K%EÐÍÍ Mr{5¦Oñ¨dú¹DL T<¢%¥R‰å:à Õãñ¨¼îäóy¤@¹ne³Ù?ýÓ?½ººª×ë’•î`WÒ|GhµZ*—Óx<^{kŽÅb÷×ÖÄ!š;\ãJ:ŸÏu:ÝÚó)'] Möð¡’Æ—vhMà[&“I²ú\lv»Ýh4*ßärlý~kk ÷­Éd"7ìØ·pMgC”ìŽ>ÊçótÞF¥R©T*¡”îw¿ûÝû÷ï …Âd29??w8ûûûÝnsyeƒA¨ÙÚl¶ÝÝ]îB‰$ðü{{{di8Ñ#“Ê-|ð¤5›ÍL&sW„ Øá<Û\.×fwšápX*•X?gB‹—å‡m·Ûw­Kdm¬Ûí‚)Ñf³ åp…ÛíOôNf³™¨9 ÊÑ΢ø“‹sŠÂʨ1f­Zô¹\NežÂëõù|>IýLØŒÊWCÎXéæt%\²¼ûÄôP´ššß’Ü„Q€¹3†î…ãñ8Nã É^ØÓM¯×Cߣ*—Ëjz( :Îf³Fc{{„Í‹ÅâúúZ’®ð=ô0™Lʱ ˆ¼ö\J*ñ¢Ñ(‰ÔÑ�ºÝn¹ªk†É�æKfM(�a ü¬×ë¥ì‹$·ÛØ)F˜Hj¾ñrÓ4™Lž={&>÷ððÐd2½zõJ<{a´b;¸7 O–Édp¶…Š•Óé„;Öét¸uqŠJÐïÀ‚J®X,Öj5‡Ã±··‹Åôzýéé) /ñˆ·ÛmDŠ T+÷î´]­VF#‰˜L& JAøDØp¬â½½½T*õòåKZw@Àív# 'w"V¯¢ÂÚŒšFêÉ(î‹4܆¬¥Á`ÔlSðøÈápD£ÑF£aµZ§ÓiµZýꫯŠfQ•6M…p¡PH¥Ô§¤ƒ…¦3¬WóårI˜nú!rwôQ6›E8"ܸq;ßï'”צÓi»ÝfÃ6x~Œíb±ÐëõþçJíªá®}¨æd£Ú³Ù 8-Û¨‚EDbK~K²e³Y9J\ŒFãŸýÙŸýøÇ?ÞÝÝåú f’É$ýä@¡°ú™Rý¡ôCýÙƒ!{×Ùßß—ËÁà#ÉO¿øâ‹¿ú«¿úë¿þë¿ù›¿ùþ÷¿‹j&÷÷÷i4¨ô†�•laÄj±—üå_þ¥xôËd2Ož<Á¥Êl6ïîîN›J¥X*hAŒöèÑ£gÏž=~üX#ù„ÉqXKnö倢œ †h>b-QsO™mL%a?óùüçŸîñx$ç7—ËAÄäñãÇk!Ø Ü@ €]P§Ó=}úôéÓ§â()çÞïÓîãgÄŽ~®­áïÍê¿’ÉdœN'ëgX±¶¶ùÉ“'÷.tù]ýç]›rþÕh4²FÈ Ð?þíßþ-ÂÝpsú۲٬®À…ªÕ„-‹%Ž;µÝÝÝçÏŸ#ÃQk‹qÎËò½|ww÷N4É3¬¸$�Ä‘ ¨â#ÔëÿÅ_üÅ/ùË¿ÿû¿ÿÅ/~ñ£ýˆM®(MÞaºD"®Õj9A¯ Z$9>>¦CÅ­T§Ó¡X ²f¦+¿ß¯@Æ»W�~.J¼»»K¯l0âñøñññññ1ý#Ê+¸ÂGbÍîÖÖ–d1ý-SÈ`0PÉb±8Nì‘ÿsœ�†‚â„f³ö¹¿¿o2™¶¶¶è/é#…µ¯Óévwwÿ8=¿ç'sâÞ e®jž�›Ùà§÷ööÔïj¬9Q»CħjXv»ýÓfAå ºN• 5¤Ñ€µU+±XŒW½k6›årÙãñˆÜ ÊÊ•Êyû ø&u'UÜ'w $£×ëø.—Ëf³± zS—Ë…šì\.‚—Ëåuh j>*wø|¾f³‰AÔ…�•x x”MKÿˆ ÆÍÍ ÑN§n·›9ºÝn§Ó™L&Áó6u: ê@éóù¨j\.€6ìv;©? °sssƒ€>ª×넵NÄ%ô‚œt)’(ñxÜï÷G"(t°é±ÛíO¦0P’"¹l a2™`ö‹•nïîîbw¿¾¾¾\ä»kÀ-´ÛmÂæ‡B¡Åb1›ÍPpÈfé#î!v»$°(˜‚*X+A«òŠCˆ~¶m\èO1L˜S8fYám6›Çã vôz=× Ô•lÀÀp§žsÄhw+ˆP\¯×+ Âåän‘p–ÃZÊ} MR·6è$+ôz=ñØC%«j ¯A§é«««ïÖ®ÕjÕKÐÒö»8Ÿ’>©ÕjÅ„*1@šÀ<­VkµZú:g¯@�–ÐétšÍf¡P( ý~ÿÝ»wçççÿò/ÿò»ßýîË/¿ìv»>Ÿ*JïÞ½ƒmøý~+ÚÀà>Øàj0 ‡Ãn9á½Ô ¡&Ûív«Õr¹\8Eú|¾ƒƒ«ÕúôéSƒÁÐjµ`Õšµ„´U–cŽÅb6› ô"Óé”ÝÏìv;^а–½^OeNââââÝ»wÝn—5'²™N§c6›÷öö¸8ßïçРkGÉårqël¶Dû«\&Ž�²òOH^Õ4—Ë … ƒ(«]©Tä´ÕAÁ.ù‘Åb! oÍG9f›Í&yo¨ÊC“oZ­v­P'+…*‡´-—Ë,Äp8”„T²Ätú\ër Ãç¢¬ÛØ·F9.©×ë£ÑˆdR•¨ð«Õª~DHîVŒ8¤n0à0ÈÍA:r×ÀôW–‹‹‹»‚påð€Ÿ¤™¤¬E‚*çh4j6›¡¼°X,à©×Ú4™Óù|­Ìÿ÷'�i«Õ‚�+¬"‰L&“z½Îž !EA£ÑÈ8Ìfs,ÿ0›ÍThÍf³f³IÒpƒ!‘HàDœN§¿øâ ÜÀ@ÔD‹Ÿ}#¿ßÏe"¡¦C¯†[#=‡Ãqss#wóðù|Ø#u: Gáž<ùqÑœÈf,‹Ïç+‹ 5Ò|;Fc½^OÔA6ŸfŸ» ‡ÃËËK:’³ßu¹\ RhÜÛq[¦¨g-'¬ÌÍ ™fr2¨ûÀ¡¨)ù[µZ­Óéà8Eg¸Z­&—Ô \ÌC986 ž‘ú�� �IDAT›ÍªÕ*9ŸÏG'5LÐ^¯f¦>Û'©î-ò�”Ëeb*Û_7ÈÛ}²Í‰S6”lдe™+¹îÚI¤-PY,–`0¨>¶&ʤj†v‡À3Ù&“I±XDð$ Ý3ó©Â€Ê··d2ù©2Òjí4ÍñññóçÏÿäOþä‹/¾€�zÈ©îrX®p�›Óõõõéé)Ý*¸Cæåööv¹\bBI¢¥R‰•5Z,Õj%Ž777ÀQ©,�ƒÍ°0ÆV«Ü÷€kq»Ý6›@¸„éf¿‚2™L"‘ úIŸÏ4˜Á`Èf³Ÿ}öÙ矞H$P×$iin·Ûår±3‘\t’ýwªâšk38D‹E¶i>ÖŒU*±'ƒÁ@óÈ¡˜¹ù£Æ\ó‡ðÒÅbáóùØ0A°97Íþ§>‘+@åÖr«Õb›ü àØ®è·€è’[ ƒÁ€:k±ùÊÚÙÐGæ~ÄÐkcb777˜”››C«9 ‹Ã�²É¥'¹³ÊñT 5©Pƒ¸3‚÷I<CïOX‚°¯ëŒ×ëÕjµìGj¨Q f³¹^¯+ó'“ÉZ­ö]ýT¶P(äõz¯®®TÒ:H6³Ù ‰FH (¯Õj}þùç`.@ 7ŽÏ˜kP#šÏÎ>IdÁ0ð[Z­vggG¯×KF±hL&v6›Íl6ËQÞk™žƒÍC%Þbkk«^¯ƒO¬ÛíƒAb‚€ïâââúú:™L¾}ûÖëõ¢ºZ¯×³Ðux.T±w:JbáèMzK 肼ÝÉÒ k‰˜DÿR©T¥R™Íf7776›îX±X å¼dù@A„B!"_.—8ÔÓUOa=BS§ÓÑßpì¢ìw9DÒNÜ,K:!úû÷ïåÖ‘èæ"‘‹’!;áNÈSÞÉÔQ4ϽäIâ‰LŠ%(<mí¢ DMǨ?*]%ë¸z½ÞÖÖ¢Áä¸$£÷r=t:6›{Y.»I–¶öh«æ•9ænÙ;"WÎÉ£ +w«~S!‚²jäÚmdzÚÎΉIk>ŠÉ‚°°ç){éið­ø9Dq²fwäݸÅb19t8»Éd¢þeC¡Çg ÷§|á¾¥×ë£Ñ(0@tBˆê5Pll»÷öö¨ú`>Ÿ#=N÷ööp®ŸL&~¿¼p™L†±CwöäLœc=�{/;eZ­vwwÎ!¸Ñhq÷ápˆ{ÊdXÓ¦8‰@š¼�F"~,î5 è‹y Édr4A' ~…B!ø|¾P(ÄÆ iF¼^¯Ñh¾ZÒõzôÂÉ[a”ÖÊ1‹- BAuwwüè¹\Ž;ÇãñL&ƒfYR�=iµZ•J¥ÛíÞ©Š‡d¸•ÿL%òUOfgŸ=а%�\}çg¸Pä3‰ˆ§aEcÉÙOI–ò8b'9.å¯är9P_ÒáIHËMŠ_§ò•%ãë%3¸›,pûØT±HvwwY«x¢B%Í4ý¥Â·ÔoQô�͸à€™¿N‚§’‡Ü�DHÅ+ðjµêt:Ü+p�CQÕt³†ònÚÈÉÙÉm¢r“Ëå²Ùl³Ùdß…“U¾¿Ë} \‹ ¯V«Fã›o¾a}wb‡‹=œ°ÐyüûáááÎÎÎññq·ÛÅ=LÙõüà?XË>™LÄã-I¿Ã±®V+¬LüÛy”ä=}út_«Õ6 §Ó‰$M>Ÿïv»[[[Ø\¹±e{F |ztttzz: êõz³Ùl6›ì©“É$€šˆîOäsqÃy#‘Èáá!ËØkµZ9‘-ÉØC*•ŠD"§§§_|ñ…Õj=;;c§okk äl¿ûÝEÁ‚«†.ŽÐ\Vs<U,oooC [Î<8Ä™.;Ü*£#"ñ ›E;88(—Ë,Ò~f¹\¨)i!8-2¸bÕøz` Pޏöï¹­H<öÉ…C¿ÓS¸Z™vöµéº‡ÂY€ÛF£ÜB;™ÏÖh4ûûûòÂ/n·;+\¥AÏŒ1’|z(÷+­V‹U²ñz½(¡¦ŒÔáá!«4ÈõÝíYx655Šm¹\CÍGÌŠè2¸úrNßO¨‰J¯× Pw»Ý®T*â.+™Ûíæè¢¡f¶Z­ðsÜ·À]öêÕ«ËËËßüæ7¸UÀ6è®àv»¾§ëÍ#* ¶¶¶æóùíí­^¯O$ét:N{<žv»í÷ûჸ®¦Ói\,ªÕ*ue2pjÐ{<ž`0Øï÷ÙÎãïQ«cÛÝÝ•<9RzìéÓ§‘HÄjµZ,–ápøòåË/^à ={u¹QÒëõãñ8·Z-øÜ|>? ~ÿÓ«F£9<<$• ŸÏ‡L�é³ ²ùùóç‘H$‘H�zŒöí·ßîïïƒØq•d2 Z p"¼{÷ÃÎÍ>í[r¹\»»»ívûÅ‹&“‰ÝÒÀB{~~¾YÌ_⥚Öjµ$;@†ÃZM³àµppÐn·F#ÝZ€õÆüÊ-·ŸÿüçÇÇÇÿõ_ÿ…ÇÒØ¢‡�8Žx<ÎÞÝ[­ÖjµBþuµZ¹\.¬üÐ'øãããr¹¬|ø â5ÑCúý~îTMçcØ "½pw<`=9 ”r÷ÔT!ÜysÒétÈgr‹ì!HTq¥Ká¶ p#ÚncÑhôúúšÅ‚p÷ Tj¨¤é•ü!ˆWb(YUSÚŸ8=4¼ûjµÂTéõz0CËé¬m éÔ|¬NäȲ,‹ÂÁÇf³­V+ÉýŒ¾‹Å*•ЏGbåÜ xnØ¡Ëår`ÍŠÅbbÄŽf<w»ÝP(d2™J¥R¥Ragm4 1¤£×ëÃá0¼<‰äÎf3Döìv{µZ­V«ÜeÚ‹Å‚›¡k½FJÕ®Ùn·“Í@V%aDät:%¹¦P­0N½^¯ÉdFWWW§§§××× ˜�¨N[”eO§SP³ [†çã" ñõf³év»¡'‹¡«×ëôÊØZh×Dì.‰¼xñÂf³={öÌãñL§Ó—/_^^^¢j#C&íétJ"8¿ãÞÃ¥XqHhL&“ׯ_#ŠË~ÒRåInÚÍe2'¤ÀÅ.ö¼Å¡÷¸µ»‹áÍ�\ùr¹¼‰Ö>{¤ ƒPÛZ,ÈétâÖÈ-Ò$ÕP¶ç›  ×ïñxr¹vAî#îTm³ÙP¬a6›‡Ëå*—Ëäîë%Ã@ŇrØVe}ÜÝpNn·Ûd2¡0—+Éÿþ=È‹5£ð’«P(Äþ‹ÃáÐëõ'''v»½×ëÅb±l6+IKŠ9“¼&›L&¡Óé$ëdÞ¿/ú ‚˜`=sg ìOЫeË‚•àT»)ÙC±¬@ ,9‘). ¨Æ‰Ä’»¼¼”»ù©‘*€L(:===99¹½½È¤Öj5v³ÔétÊà-«Õº\.É^OOO± ƒÙl~ÿþýþçbcà€\AÑÉÉÉt:- ¢¥QF#öH*ÇçÂÖÖV·Û¥Ù‡$W×õõ5ÜM¹\ ‡£R©¼~ýz0\__¿~ýß"«6›Í°–P(”H$p4 E&“a+`‹Åû÷ﱡ‡C9,T™£¼Ûçó ‡ÃP(”J¥vww‰`=vÇS.—Ãáp*•aÿïÿûL&ƒn�Ó#Y f4Q:åõz …ÂË—/g³·|¼^/ªsål†=yh¾ã(k¢ F…BÁl6£2 ®-Ñöûý™LæñãLJ‡‡³Ùl8â[ ª2Ǿ¢Ñh^¼xqzzZ¯×/..XsBSàuc²ÉdO™(v¿Ïàpx5Z ívûõë×j²YÑhT§Óùýþ`0(ÚÌ|>'áJ,Åb±¶²¸X¾7Uœ@ô59ÜùòS°nmF—Ë%VI-—K®Åçóy<›Íöüùóíím³Ù\*•úý>P6’sIó\.¼b¯n‡C§Ó‰ç¬+‡ÃAB;ÜæÇõd6› |k6›y½^|ŠûE‡�Þ!®‡8RAËÑl6£Úèè æt:qîfßÒŸôÀ@  |¡Ämo­5¸ÝnÜŠØ;p‘4Å,¶v[rOr‡©ét*Y>g4ƒÁ Ó鄨#—*“ûdgÙ`Qý~uçV«+Öv» zSå�,M1 ó»\.M&‚‡˜}:c@B¡Ø(p£B¸ÒçóA€‘Õé�ÖӇɥßb?Âå éÕgÏž%‰Ç{½^ˆ£W«Õ7oÞT«UÜ :N$ùÙÏ~æñxp…ÂÖÕï÷ƒÁ ÞZÒe¬V+\.QxI¾ŒýKö#î`¡<âÛÝ@VFò˜Ïªóq ÁØ< CtAÔ=0zHÞŒ¹]ôÿŸ}öY2™t¹\NžC1ŸÏa38:c4jµ˜vÅÊ1ˆk>ò´b™ˆV­ÓéîSÌåp8 ƒäjå¬Z!ºƒ³'JÏý½Ïç[[…³¸V«U¨åoNJ;^¹\N$Åbq¹\B$—Ý?K¥’B"šøhÉA©V«©T 7\‹Å"§•© û‚L[˜+&$ I…»¢²(œ£$|€"P˜Àú8ÙF'Â5K–YÏN‘_0¯¨ÙŠÄÖh4 ÛÃz"ŽýÓ$´¯æóy¥RQ–ä@õzýíí­ÛíFPe2™\^^Ò‰GÁfÄJ 0ýà‹F£ñêê ô0v»}0°îrµZ­-£ ‹ˆæcÍîõõ5j»³Ù,„á5E¦ÍfÓëõÝn—ÅÏf³R© qÈ` ÇÙÛ†Ûí^­VpI±X bN`üB½þ2 ¢^´P( ”7µZíööö‡@ú·µµ…}«P(Ôëõb±ˆ¤ Ö£Óét»ÝÍf“E·Z-ô JÍwòŒz½ž¾.YdÁª`›L&Tu*<¸.[‚ÙJ†ýW‡qÞW¿ �üÚßß÷x<£ÑHNéXèîÒÕ- nÀ/.g‡÷TýæìjeÆ•Ûb±%ªq‰,•J`ú@Y‚÷@åug±XD¬•tX/ƒXñ 岜µM¹Ò®\ô½^ïÝ»wâ©òÞkß_î¨ÕívG£Q4Íf³¬£ï÷û×Ñ·�Ý].—kqs¸”Hr·ŒF£n·«Pû®ðTM5 ”|ÉK®%‰QF±¼ rkk‹S]§\EÜt:F QD¶–Ý~€…C™Ïç Ö³Oö#`c³Ù¬ÕjE{>Ÿ×j5Ÿ»¶„k±XPØÝét8sBhŽìÃtãÒÐï÷[­(1&8&·Z-¶ Ø#Ä‹úý>[¬<›Ípã‹×ëÅŽ8 …ÂÉÉ "/^¼8;;›L&:ÿ …0˜&“ PÖZ­û$÷gëzXÏ® V —UPå>êõzV«•�•F£‘eãålIž ú�õdT))No’…µ›%½�‰»¼¼|ûöí›7oÔxliŸ0ÇÆaºÙ& oW)ÇŒ´ßï«Ä]±ßbSGøOa—˵½½ˆ×ý_\´ é°€5Éd2 N§S,­x­¸*ØhƒÁÉÉ â \lײ¸‚ÐLe!ƒÏçãB…*¿?"žÝn·‚¸N(ÒétwÅóJjP" 4ŸÏ!Bzו#N–ÛíÎd2[[[{{{¸à²§*ˆ‹Ñ Óa�3™ «®„:`hÚÊéÁ BŒÕ~.ûF šŠAFŽ»ñ˵l6‹-v2™Øíöx<N´¡t†@²=ŠÒ·4Œ)ü%4+ª‘Ã`ç7]N"YÃà+ãñ8†PjöûýoÞ¼) ¨ËL#‰0×|>‡|F§Ó©V«gggÐ&F´Š �F“Ëå:k«bp†™UƆÿP(„Z ƒÁL&‰'‚d‹Q /'ÇÌ])ØQ]g¬;Y›ùÇ~¿ßh4䏸Ćª­V …63¯×k³ÙÔ;9aeq9ÀQ¯½¡`í®>\üV4…>j¿ß÷ûýív{kkk{{ûúúš+JTÎíIŠä©ªÖ›L&£Ñh{{{8 …ï®üXËÁ`Ðh4..."¸½½%8­nmXfgg‡½l¡²Vý5Ÿƒ1* ˆI>Òápˆú]‡#T*…½‡ä¿î*Ä|±`F‹Å‚ê2 ª×çóI¦ N§×ë­V«>Ÿ®ÿ믿f þq¹\nooDnˆœ]2™¤òS—ËE±;å&.EЗH–JƒH(10u®•†_žÍfؘQ×@ 1ä¹F£‘Ñhôù|¬ö¶ä‚'—²+${ˆF£z½žÞw2™Øl6§Ó 0,z…Ë\�í¸¬€+}2™üö·¿½ºº ¨ªêv»¨ÔçfŸÛ}%}¾ÅîLè9Ê‹ñ@ŒÞw¹\¶ÛmÑ]¨̪l(£Ñ˜ÍfÕL®ú†‚=õgD¼·#‘ø9`2ËÀ¥Ö¼^¯¸ QR“åõŸÏçœOÓ¨s±Áqm°3Ñ=› “�\›Ûí>>>öz½óùüêêJå¹_n4îVJ~ssó]ÓóÖo þ4»Ý*98­šC‡e“K™*LŒ€4™LºÝnÚçºÝ.h"Q¦Ün·³Ù,{ŽF*UÙ8؈ŠÁ`ØÛÛSņt©x'c£©$­«‘BõºÝn¯×ËÆÙ‡ôû}ŸÏ‹Å^½zµZ­%{Îõ·Ã–‰ñE8ô ›£lÜt¢YƒAIã•i²Æã1”ß©S>°™=ë û(vñ|>Oá;5ql2 ùAÚÄ„s½Â·†Ã!âi½^,5èÆîîn:…BÕj¨^§Ó¹»»‰D@¶ …œN燖Ë%îív?¡‘Âçœ*•Šœš0kNÜûJ.XÎøYÍåû‚ ÿú Ýtî¹ ¬D"áñx()ÎÅ1(`a¿Å9úpÑTãr»Ýz½ž¶.ѧ©i’ÔrCò•ÅyÄtƒ9 v»Ý¯¿þ:‹.kkkK<ÀÉå_ÄÍéÿü»¿û;`K?¹¶žBÛÞÞÞŒ!Ÿu¨ÜÕ02©’mggGäÖTù¾<ðù|ÏŸ?¨â®ôù|Ož<áÊè©ÿ¨ØÞÞæJ-%)­Vëöö¶Ü­ÉF£l1îÐcµÙlOŸ>ýâ‹/~úÓŸ²êÀF£QNŸ”ÂßœH.·)Ã*O´^¯O§ÓOž<Y+5‚ªÑ?>þÆæt:I.]ôCf³Y,Àq8Ož<A7Ù x­XsÚÚÚ»'©„Ke>¬º«ùÈ™„º^î#Š: lO«Õ>yòäÑ£G>Ÿï‡?üá“'Ož?NIjïîîâ® Kgm`}Ø€}R¹¶^êOîIb±˜8ÄÚf·Ûs¹œN§K&“"ß¹N§K§Ó¢‰~ÚWÞ¬êA²ì£|>¥5÷®­Pè¹ÁT*åñx`3÷ù9·ÛýË_þRVlpÞ)¾yó…C÷¹-Ý G&‡÷VhŒ¥¸S øð჆AM*ÿÛ½H$"r=ˆ­Ùl~ï{ßC½)ðÕ·ÛÛ[6m³Ùè4l3èp¸0‹j²Ûírx@z&§å~ WUœX ÉHd¬@¹"qvv–Íf///ŽŽ‰D³Ù¤êÁ|>ÿí·ßr/#ˆ[$»Áæ 6#öù|6›­\.W*.Þ‹¥Â2P<xð� {PNÍ‹ÅíííF£dÂíí-½²†)Út¹\‡‡‡‰goŸý~¿×ë¡ÃÈÂŒF#0Ë(`'Èï÷[­Vî®àp8pSŒD"ˆÈ±ÄÁeœ(7·X,”ÎpmµZI²V«¥Óér¹ ³Á`ÀF¾X,ž<yâv»)Íå¡Z­f2™Ó“Éd±Xz½Þd2ÑëõÖÒ…x)»Ý²KCýú}ª¢Å¡•7»¡{¸•¢Ä_ŒÕ»\.½^/ÖªÙívD!¶p8¼Ö™X­ÖÕj•ËåîD G®¢©Ô+L¬”ƒÓîììà–,™ÖÚ,Њ3ßóçÏÝn7R0£Ñ`s•ôTr“»µµ%Ök\¾ùúë¯YJ.NÇ1&8޵’ F£Q²üS5 I…B ùMV&•3ÒBʼn‰nîƒÁ@M¨‰YÇsuuÅ¢í\.ý¢z5Ìd2I†”›¤4$éZІåv»¹X®îß%•ñx‘³Ù 7‡š+‡Ã*¯F£ ¸Íf# FÓh4HM˜T—� Ø, @J£rµXtÎ`w¦`0h0à1#�îжÁj¡Â=u»ÝX,F¾\z ¼®(“CàE§Ó¡„u±X É(ðúÉd’¶OXR8ðÖx<FIÌöaöAK 9f6âäñx d±XoµZ<�=¿ÑhÜÚÚÂ}ÖNJ`¸Möz=`º±ÛÁtA"€5þ:yÀ-Í�]À`¹©—�mÖÌfs(’¬‘Q¤AQ†hNœ—”LÅ©QW (×VØA±öœ¸¨NËĸµŒ$ÁØ9­Þf³ n$\yYïĺ ;5£ÑøìÙ³ÇCêÌãñÐHÞ“žjMÎéêê %m4L\îÚçóQŽÂ W¥†žÜÉÂl6‹»:‚ì Ðu¹\  •ÜÚì:‹›S‰Ï/ûç›o¾á¶PÏ}>KI)‡Ý8‹‹ ¬ò™rÿNÁèù|ŽÃòh4‚„Ýp8ôz½t3h4œðO8‡˜äíÅŸ“TrÐ]HÆápr nqböM&“8Y�q\µZ­êt:,]G#k6›±¨&“ (£Pé‡W¦t5&“ Ô|ápØétB–_d½‰ÇãÇ···äŽQA‡páv¹\\‘!lê!øw¿ßOC t6ÒÎÈ?ÑØZ,˜t¹\ÆŠÀÎÙ‘ÛÛÛÁ``µZ?ÿüóããc‹Å.Ýåri±XÚí6ŠìÛíö£GpEÀØ"s^.—!rm6›‹E8ŽÇãv»}8²ŠPbjðSÕ&àÕ8'Ô×}޼Äßj4N§Â&ÇUYX4õJŸiöñª8.+Ì#¾%&)9Ÿ¦26CXuƒÁ éBÏ.ÕÙlvtt„?£·`'‹z¨æAz‚¤õû÷ïtÁc¨��÷V>¬¬ኒÒV  GeäÑív#Í+¾¼dÞˆMÀÐæ7›ÍDÁ´p8l0J¥Œ­VKQŸËµårÉIëú|¾ápÈþ#ÍØ 37€?I¨Z}[,•Je2™K{“¦vuuʼn³iò&Às`Uv:Á•Ëeä?ˆÄA2Oàr¹Úí¶ÇãÁÕ­ÑhƒÁjµJ¡ô°h\’@^àñx÷›L&år9 ‚€Žâ*Á`Ðï÷Ãe˜Íf¸[9ryy9-‹Á`@ŒQ£Ñ”J%­Vk·Ûñ»ð\’ Ýn£p'‰Ôëutw#Éù%ƒ§±ÕétÁ`z¬‘H\‹äd§Ói¹\¶Ùl D ±;ƒÁ€•;Æá±x£ù|ŽK3æôK`¨CÂ_2›Ì,»ŠF#¸�€[krÑh” EH 5m*W“¹áÞ°"¹uçv»Ù½{šXG@Œ«’ °hÖA!eƒ—‚;d…þ½\.?þÐ|Rv­¡PÛ',MÒEœ½zõ fÌÖý*x'Ôò(SÓJDS$ÏæðGàZU`‚;¡Äb1qÏ_Rò&F«€,a¥r ü7¤d¥;¼ñYl±XD"‘r¹Ìš5·ø9#S)2Ë.�ürTÓh�Õ4ǃ£ÐÚâTMEoŠk’| ¼±Xt8±XL9@*\óù<¢vd8Ö\\\`ÒáR—Ë¥ÃáX­V©Têìì UjãñÇ,p¡zOÆ´X,À»ó¬V«Eaw¯×óx<~¿‘U€Þ!â,Y×Cl¬a øL§ÓIî,‹±Ä¯t&`kè¢üËå2 f2™\.W¯×ÏÏÏ3™ŒÅb1™Lù|^§ÓµZ­N§óë_ÿ$žZ­÷$ÈmX,–ÓÓS³ <ñðçâ/M&ÓÙÙÊ«ÄÕçt:].¦,#Lkvé)!-›Í08¿»‡èK+ƒÏçs8N§Ójµ^^^²‡räZ|>Âr„Ÿ¢ëç\3®¿ƒÁ@bCádï÷ûQ>JÃX¯×Eæh­Vëóùz½Þ`0àö-jì¯Ótàÿ8Nœ®ØuM‹Ýêb±ØÍÍ‚ÓX,wÝG4’ \<ÁG$‰µa=:É©µ˜Y6 lµZ•anØ™ö÷÷ƒÁ n9™L;ß‘‰O&À䔸¨®Çãï»Óx™Â |ÿûß§Ü/*—Df• Øly1”RƒÁ ‚8€¢H(@Læó9Ü.ÑÖ¡²6‘H`½!í„‹‰ªúµÕjµÛíz½ŽïRÆf³A[„¨¢Ñ(beÁ`¢*.— d}>ŸO¯×çóyµÅb1«ÕZ.—Óé4, í6x“¹S4ít:ð‡ƒ %\.—™L†,èl0ijGr&“yðàÇã1™L§J&“`ʨ×ëÝn·X,„Ôh4V«€½@ƒÇcœÙ ê€P9»ü A,¡Ýn‡ƒf»´Z­ÀQÝ^5FÈzFH²É| 0“É$“Ép2(lÛ¶ �� �IDATàW½ÝÊQƒAÏx<†F , ™B LwƒUl2™ ¤R– 9Ÿ `çŠ9â1x¡÷ïßW*Ä{Õ(·ïŠ]&T¤œGW 5¼ ëqN ;“æ#êP=ºû™Ü^•H$Ö:k*aRØÌÜnw>ŸO&“±X I¿b±x{{ËÍ:OïÃÃÄI^*#àDàá]‘¶ìLN§“Mƒ±NÁétBí”eŒeëAŸ‘\*¡P(—Ë)ãa�ý¹\.¨%¬¦ bÏf³Û`Î)áÕ‹Ò€t:’9ÈÂâoÓÀÿGl6[4ÃøGDP:XÙC„Ïç«×ëä}ðàA4 ¡PÈëõ^^^¢4Ûáééér¹„ˆµäZ˜L&‡cggžWóÒ§ ÊÝe_þ.L§Ómooã�`l&“I&“6›íÿñ}>_«ÕÚÛÛK&“°´/¿üÒåržž"s p(‰Ãáðz½™Lf6›!2 ÙØ­Á`•p1¶N'—Ëa[‚Zˆ Ù3¨Y¬&r®ì¦ ¯ ée?%±cêüÚ¤½Ûíöù|�ÕQi+K–F"Ÿ³Ù zžw]ÅÀt‹þZdG g qg’Ûl�Zß옋óy­ÝÝ]ÉÐÜt:Íd2j’>÷Úœ”¿ŸÉdD§¯p•q¹\€ñJú&¸ÂÕjõðáÃ`0ˆø*¹¹TÙÙl†ý)ÿæ7¿Á+vr­ñÚÈú2VN.^ÁÎô§Å ÊÝ0Ün·xËDçáPr¹q"¨éÞx<nµZÊ{ ÆuÄփȘ¨ÖŠUSðj³6ƒ Ðb±<|ø»x’Z­ö¼ýýýr¹Œ}‚-Ä¢h²XܱÕj}ðà=P4³Ùlæp8?~üàÁƒX,‚–x<ŽO‘l3 _}õd;Pß%9tø JøèÊÆr¹ (7À@³ì@„Ò¥ŠD"ù|þòòe߃áíÛ·ÛÛÛ˜D\•ÎÏÏc±Øîîî|>Ïd2z½~8‹ÅP(‹Åt:ÝóçωBs€`û8&.™L¢ˆÌ \À™Â9–lcj;5Ž’Ê1þŒÃS“*Øþþ¾²ó¢ÞAÔ&²$0öàà€-(ÅQ€ÍÌI>΄ƒÍrˆ~9~B»Ý~xx(n÷$æ@!{½ÞÁÁ$>WY„—[û€‘qG–ûnN­Vk{{[¥à:¤t$¥Wi ñQ­V£®ã[kÎNÿjµr8"DX’ìà> .Búl’`³†jx…QRÓH˜þE2þ¹bÐÜ/r¸}£Ñxxxˆ·Æ’@™ìüãB¡@J£’ƒìr¹Í#®t£Ñˆb0Ç …`îˆ)±Çp Ëår¿ÛíæóùW¯^aßBe&œ5(2 ƒÅbq8à¸ÛÙÙÁY݆ÜKa€à8ë2>|ˆ35HW! ìp8vww?~|ppàt:ûý~©TBB¬wƒÁ€È#”'är¹>ÿüs³Ù\.—Ùùb×0Ì ›1þ2µ@ÚÝÜÜL&³Ùüûßÿ¾P( HÏét"€ùí·ß~ñÅ_~ùåÇ···m6[³Ù|óæÍÖÖB”GGGÛÛÛ&“éúúºÛí6›M Ùi›AàÚçó‹Åd2©ÕjC%éêAŸ‚:ö³±2í¬‘£fíæ´v%"‡Š¿yøð¡×ësNõz]¸ g³Y¶|Àét¢¦2 ðÝÝÝÅ}¡ÝN§£&0›Íä..PÜFò‰,&Ëív‹¤Ô8•Ïç±ÓÃu ‚I”–kÜ~&jj6VÂeg”ûùÿ«q»‚Õj-•Jggg_ýõÅŧ)®²$oíà’&‹š¼gs»Ýr •êÛÎÎN«Õ' PPIXt6›åÎûlCóåÆÞâ“Éäd21  GÐL.´B"¹Øiòù<)kHJ¢ ‡¡PÈåra=ÀÒØS j|Ëå²ÑhüüóÏËår&“Aer0­VkÝ3 ÀÌŠ&m±Xp¤Ã,JÁ[ªÕjÁ^o³Ù¬Vk"‘@1÷·ß~ ¥æ~¿jˆ¼ÈI®p˜DŒ®×ë�Û½ÿ>‰Æn·k³ÙHt•,Íãñ ˜ÓéDˆ&NCZ7 ¦R©ËËËd2 ŒnÆÃáðôôt<Çb±x<þ£ýèèè( Úl¶ù|þÍ7ß@µ‹Ž)§§§•J�çñẋ‘2gmZx/¨ ²Ûª2ó>"¹¢ ­òåŽö€`ßsÁ&“IƒÁ�"àR©ÄýQ<zôˆ à‚šÍf.—CÎ’$Û–Éd¼E°z0°qå,ÔÚph«Õñ¹XÚ Y[ ‰Ë= ‘ƒA>Ÿn÷lwÞœpÙ@WÂh4béþqö*£Ñ¸X,ˆ P«ÕPÔív³Y• õµf³¾…ï@Àf³4r³®ðÝÇè=§ÙQÈl³jÒçómmm±+‡ÃINK=„ð+lÀh4‚™ÂjµV«U%Ö:ÂWF"Tlj~0Ý Ë„’da΀4 …Bðéív;™Löûýf³ è.H³Ù¬Éd{èv»Ýá>Â-YHnck·Ûíà x±X,‹n·;NÇcŸÏ×ív©°Øb± ¾ £‡Å J*—ËJœ ™ä,ÒÔ‰Db:B$PóQàµV«ÑP€ÇÏjµv»Ýd2i6›G£Q¥RA‚ 0Äiq¡£ÄÞÞÞÎÎN:FIa­VFµZ­R©@Ï´Z­ÐM ØÌjµòz½ÐõÁîp8Å<N§SÎ-(û}šbe›ÂL9‰¬Ä*(öP«Þ©AG#à¬Á߇‘ôb‡ÉY,ÇC!evi�H¾Ö™€¼Cîà MTqAQZ ‘Iñ‹œ[ jûf³i³Ù®¯¯Õ|ëž›“3Î5ŒÇc…@³Ù ”¢øtÄïZ"©ð@åFÓƒÈÏb± P©B  *’Ä 8D8ñÑh¤ÓéTs{½^9ñM§ÓÉBsÀ…s~~~WJ$Î,PwÀÑ® …X,¶³³Ã‚T@4^«Õ�_%­^N‡õïr¹ ˆeÁqzØb�@ìßpx `¡¢ÉÂÒ‰ÄÕÕÕh4òx< 0`ëÁÇžL-ËÖÖÖh4:;;CÆ›7oÀ* w¨#ࢠ/Â+�/ @k·Û•+kÖëõN§›"0:®T*M&£ÑøòåËZ­F ÃÉÉ á–0ø6›mgg—ÌB xõê•Ãá0›Í±X¬P( *-ƒS»½½ÿÙ� /ƒíÁð\.W±X|÷î"P•‡Ìn¥RÁþ‡««+T!6 (}¼xñâääd2™˜L¦Ùlð-”,=Šìê6Ýn·N§{ûö-& 0ØóIóùœX*ð"bq#¦x>ŸÓ¿Ãœ84˜ø@œrT@ —Ú¬aÊØ³80¶˜¸óósÑ;qXI…ƺ~egR(äâX ¨”¹«?‘Ûõu:Óé”<L³ß·’ š[œk¿‡)÷%ÉLʆY×> 8(Jp  »SDŽ"Âjì€CÛ±šÜÜÀ©Ù™Àaƒc]©T톥Gít32Y±{’ §„ÉdBÛm>Ÿ¾H#ï÷û!£G±g…R©‰<v°Ò¥ÄãÑ(h¢ÑèÍÍ ©šâ·HS޾´|¯×Ãìk&Ô‰…Bçõë×Éd’Öçb±€ÃŋБ,j’=/“~.²?bãB ⻺ºúÑ~T.—ÁË'Þh4"‘¡³Á‡[­X$@t‚ˆY¡Pèv»p³ÙŒ^JR:ã¬I#1‰mÏb±Øl6`˜ü~8FqP½àšÂspw¼¸¸¨V«WWW¿ýíoÙƒZ2™|ùò%¤SF€[×b±øðáT+1Yr‚§^¯ìï&“I¤¤SˆÔIbí¹£¤JÔ9.‹´Š#‘H¥REréÀÍ©'oÖ"‘éªÀüÖ¡r箼$Rs&’ –)‡½ÝÌŸ(¼pª»ráAõ:ݹíZ!ó†8L*•‚Úæ=ãQä4ˆ´kö5õê.wÒKŸC=Á²”<>(|„n#¯ ‹ÓŒƒªä°[­V‡ÃqWùg±AÏ;“IÑ¢½Él]ʲÅ)d1…zØOq4;™ õ¯<·¶¶àA)„¥©8eÇR©à¢¨ÌƵ&‘H˜ÍæV«…Ø Ìâñ¸N§Ã- ± dÝpwDRG^¯"‘È`0¸ºº2 ¡Pèææ V«µX,Îçó““G˜Íf²@v é÷û´)•Jz½~>Ÿ_^^Ò<b·£z3.¦Ö"Œ»ØLµZ¿ßÍÍ †Ñï÷»ÝîÛÛÛD"q}}­Õjs¹V>V%@N8þÿ´{tˆ¾¾¾¦‰&“X­VH†hµZDMÈ> iKÇvPKZyƒP‡FìÏîvà|á<C¯× ƒáp¸X,"—@·˜¦J$õz—]˜D4EˆUeÏÉÁ¤‘–SI`½vqIú™û;5Gjh†áÔ"'jÃ9I•7?.2‡\#åœ ãb,  $©˜ TBà8.àõz×^žâüQ,WI±œû`•äZ6›¥h2ì½T*Å¡£À"×BÞ(\iÏEa´\”¸OÒŽ”p¡+¯|¬#” j´Ä ®ÉdbëÎ-K8xSaYz<”õF£\.'yÐÃIÅ£ÑT@~F£ÑóósT(8ŸÏ—H$"‘h¼^ïd2yùò%BH¼P”ÓéÌçóH…Ãaä„=r¹\‹ËµµZ ·»Ý©$(‚w:X­Öt: (…È’‡çÔj5¨M‚›œÖ¶(Â#‹mu4É…§r¹\¿ßõ¸ÙlÎd2(éF®§:”Q Ìu*•r¹\çççØ5q!Ãd¥Ói`Ñ@‡­.•JE£ÑgÏž=zôúµZ ÷Nê0 ÁB >ß'P¦¶V*ÂIuàPð ü�÷„\.‡P Å—¢FqPQ½Xþ···[[[H ‰¿%çîÔoNÊ~fmK¥R£ÑHýf@¿…²L…™Z.—Ñh”=²¨÷²Ô£ksN:6·öæÔh4Ñn·q~”äT¾½½½?äÎÎŽÑhÜÝÝeO`‰•™ð÷8nlÐçç<&"<ܸÃñ)?´qÍf3)åÐG,BáxrO56:B·4“ɨü­íím.œúnžN§¬xŒÜÈîS…ÃNP>ª!ì: ív»€ÚÄãñp8œËåðƒ<~üØårY­Ö|>ŸÍf#‘ˆ×ë…‡êõz¨ ƒ———(cgNT¹\ŽnaKŽÅb ði4HK�»Z­*• ŠM...l6[<·Ùl¹\îøø˜Mæ‘Í  rooV#£Éçó$Ëäñx"‘ÐÍÐÀ·«DûœÏçïß¿‡Qáf‰+K$]újµBm:Ýlnnnnnnp¹ÄðâBssƒâŠ|ôz½b±èt:ãñø£Gôz=Ôx‘ð ÛáãÇ)Ä„C@<Uë]ON¤zµ\.Õ„×0J`Êàî¡Ph4¡FQá«ÕêÝ»wˆEÇb±H$r||œÍf%ƒ‡­V OÃìÃBÑPÝ 6h6›s¹œÇãA<™L’VÖüŒBs:ê“ìou»]¡BH–Užï^¯üŠ’÷N¹”nNýÊé×_­þZj·ÛQÀ*‚7ív{<G¨'N³ô”¤jª¦sÀú±°*`Hå„e×’(¿M* ”o⨪”<Ú çt=88Ðét0â~¿¯p©:::úT·xê9Nr2š6›-N³)S1ûŠ)ÞÚÚ"ø=¼<ü—u»Ýà9·F£9>>þöÛo©±X eŠ³ÙŒèM&ÔüÄb±~¿ï÷ûÛíöÓ§O§Ó)HH÷ööŽaT×××ÈlƒAÄÓV«U"‘@ :®ŒÀÆg2DPu:ÝÞÞÞùù9jðpæM§ÓWWWÕjÄÕn·Ûf³A ܉@ÈCï,µZ­V«Qàˆ³ZäËåÒëõ>~ü;k©TBu;ð[ãñ8”Ëe +ã âyÖðH„TóQ 2+ qÚß߯Õjñxüââ"‹„Ãa‹År}}½X,¬V+X”0懇‡(1ØÛÛkµZPÂ…N.6ÑápøÿðÅbdðlž+…•Õ4ö[F£ñ®R@Z­öøøx8&“Iÿ"h¬æÌRà~¿¿½½ýìÙ³|>ŸH$,‹&f¿Õj‰Pk• „‹-P}*/^w œªé©—±[ìp8ÜÙÙ‘›£Ñæe9 &-q.·5jJÉ ^j6›u:­åðWø‘+ê·(·IéMìïïÃyaŽÉDDÐßr¹ÜÞÞV çb£Žð&ô¾lè/) Î~êóùË&.TÉÐêx<®T*4÷wB«iÀ¯B¾tíšÙh‘k„"àårùƒü@¬(AL 0L AâPe¬ ľÛ~¿˜Ãþþþ»wïˆ�ìl6»¸¸@Òèððcà 8t÷ûý>Ìf³b±ø«_ýªV«áœ‰DPÕ&YùP,N”©‘H¤Õj¥R©›››~¿¯×뱘Ia õ™ûûûNgoo…ÝÅb±T*ƒAPêÁÒf³ +Y;$*Òxòä =ª¹p?³Ùlf³™–ˆ'ÈB'gÕÃØYñ:nkkkooo{{;›Íîîî.—K“ÉôöíÛ'Ož M]¿V«Fè¡€ :”€8ÿòòÒáp�ÛÄ®V 0ûd3«Õ ÍÕjutt öµÑ$ëJ[òœ/N6’prɆy„Kñz½Ïž=;::ÚÛÛ …Bívûßþíß”·tŽ˜êÚíÄétnoo×ëu±: “Kû®@7Ã]>|>âäÈ­j>"mÙ#æöö6ŽÎÜGì·`¬w‚3!å3q[ÂÉ ”ÿrrE°IÑkM&:­n²9áH;=zäp8Ø.²´ê!u±XL Û)AÉ F@j­ÀgÐ>Çú;ÉÓ–ÊÌät:Åö#ŠWÒGz‚E ò7rUø¥„KRˆ,G£QX®0‰"œ“¥ÆG œ¹—¬uL&“ñxy8BAGB(áZ­VV •`§Êbx7bÆCQ8Р=PãÍ›7ËåÒårA'âææ¦\.7›Ív» ‘ûV«@«Ûí~ýú52Õ½^*GËåêõ4Œ$¦×ét�^f{NµétºP(g9>Êçó777çççdiv»= [3ƒCׯÛÛÛ/¿üòåË—dif³9 ‹Eš}ð‹;NRÂu»ÝÓécKKö@M "T«Õ‰D@RŽåóâÅ‹`0¨ÓéàÅ®®®ŒFãüãþð‡ÉdÒãñx½^¶¸ZYÕjõòòÒn·Ÿœœpæd±XR©T¯×=—Ãá Ùlöôôôùóç¤J2-t^+j47Ö¨T߈=�ŒòµZ-‰ ¢EárñÍGà¶ÍfdB kƒN§ËçórÙ ³Ù,$éf8áoÍGÖŽ’/bÜ—ûŒ— ©w¹h†îjÕ]®©×A&ÃX¿9õû}¯×;N¯®®`‚§á7¤uZV1VÒSÓT± •‰DB~xc°7«ð»V qKN\'âï¬Z+ =?4=P«ÕÏ!·E²}-ÚNÉå”pYZ9¶„AM’ñ ñß%ñtÝn—­…øŽ„ápx:Æb1@;)ô ¥µ3ÒétÈœÀÙ7ïß¿GM h]¦Óép8|ûöm¥Ri6›­V«ÑhètºÁ`�©òóósú<zôÈjµjµZ GÛí6x<Ü“0¹\.•JaK£ fW.nĆ B¸v˜ÍfdÚ‰ ¢J'''ÜJFå1f¦Òh4Ìf3 àr¹¹ßï'ZH’IF~¿Ÿ4D¼^/r`ù|y;D^¾|ù½ï}¯R©t:Äá¡'ûîÝ»N§ÃŒz<B³‰Ä£@ —ËAÑŠvBÙ£¼¹º‡îïï'“Iìè0 µÛmIl¾¤F¥æÞ NÉæv»aEt£óÕ«W———r,>�nÇãñ~¿?qì .×I¡ävÜÅbAÉI?S•‡d€Ífã4—ï” PÈŒ¨—–çtŽ’ì0K” "¨•J%Ö_F€U«Õ*]N9Hšìœ¤XM$¤q¸vyyù]æq =eSF]@B¸O€µÿ®ùXñI÷6ÖÁg…D½h(5îõz\’I§Ó!k Ö8ɉ§"fÈRˆS«Õî‰ê]{åbS¸°xˆÓw|1¨—„hNý~ÿ믿F…+�}Hó …ׯ_“rüp8<;;£-6‰`cÀ’v:‡#›Í"¤ïñxÐy«ÕŠ#ž¤>©dÑ×ë5™LÛÀ@éõzL1+kùáÃd¤¸cçÑï÷ƒÐµõzÝjµ"ÚÆ*A_ÔëõÞ½{w{{p '»²‚º„ˆÀ¯ƒ:ˆb±Øï÷M&È¥R jggg,Úm³ÙŒXB,“3§@ Àºî<v l¬3mˆß‚Á“¸åŒð® ‡ET»‡ùòË/±‚XÄÎ>âÌår"X¸Ê`u:ËåÂ}}ã^áø"÷i¹\¾kaÌiã2 G­¦ÁÒÄ‘§ú®Á0Ìf³ø-ƒšÔ¥8:X$r¬b’uÝétr;0áæØ¸êh4‚YCxTò·>RNŠª$z ¨ «ôª×ë©RQ9)º\.K¥ ×ét§ÀÚE†˜óB¡ ð-€Þ}ÚZ}ÂÉdÂAÜ ëdïµôÜ«Ê> ¸HÌ/n!Óé,G`F€Â4¼dß\.W&“t“V« ¶„r¹\¶¿Õjù|>ÔLÓíšå¸‘H^dƒa'®¯¯ãñ¸ä‘Õçè ]›‚Á ¼[2™´Z­8ʇ;•-ÒQ�{BÙ|Œ­V+§R©V«U,¡?Ûh4Âáðx<~Ë`0@Êïôô°wœjS©x4 ´o,ÃÏA±D¥.A°E·�o½^ÿÕ¯~%ÇC*éL81Y#ÏÆR„„ÍÇz½^³ÙDQ\ƒ4û@¿¹\.ÎÏ =s}} ’eKïJß°¶Á»†B!•9n/Ô0šË›Å¥Ä5.)6Õ]ª_¿¥SörµÂT´’k-©TŠEbB^ˆ"éìÎdµZYY)½^/Y€Èu# I ’nÜ [#ô41ü8¡BLa#ÄÊ_,^¯—½m˜L&Žmœ‚Ûí~ðàA*•¢û>}Dç}2ÄO[çrwx.³Ù‰DÔoùDIñz½8.ÑGœ)Ýë9„oÕjµÉd’Ëåàµùd‘/..êõz©T Ø‹Å2NS©êë …j¦1 sS\,¡i„¬V+îC‘HįìYr0Øívœš¡(à{(’Lm–J%”ç±6_©T†Ãa»ÝÆ·PIb1ãèv»)EæÚ©‹Å¼|±X¬R©¼~ýºV« …W¯^½xñâìììòò²ÛíF"‘H$Òn·Ýnw¡P¸¸¸899¹¼¼,‹ñxüúúÚh4â&„&<5¥aX-iÌB4åvNj4µŸžžþ÷ÿ÷«W¯ÔûÜÅb!y¾ä CsÑ\E?C9BEå.%ÜG"2ŒvèÌx<¾ëùøÐÖ ï­ýúf_äŠh”CˆÔCÉoI¿‚ƒëD.oJbîeTêh°ÇLRLàRg€U²¿Åi‘¡ €(~Yw€¢gÉÊf³ÄQ§´¨Ýnw8ÞßßÏår°Q0ôh> `K¢QÃÊ¡êÄRÔ×ÞÞÞÚívdÝEü#ò(ùÖétê7'PÉ1 µÊý0ƒâó%‡—ŠGQÎçõz‘)!áZú-Íša-ñLÔÔ9Nœy»Ýîùù9ª½¡R«Õ ЬÑhâñxµZ•jê´Z-Ò„;;;(QC)‘(¬ ?=ƒŒW“t:]¯×Fc<À­`f"jI­<l'lµ=°P€¬’U#‡.%í!xŠé€"-.s0xÔ‰`ö;ÎÑÑ2—N€Eì‹>Ÿ$ý@�ý$mCœ¡HS @e¯×Óëõ ·E±e±-Aê‰Ö¾ÁÓ»ÞuŽQˆ;QçG%̢ͧQ­ä iDÚ¹»-”§~·fgã&øÅb°måa§yôûý‹eãÛªBãÊÍU±’_‰u¥Òñ©Ü™¸)œÍfX�4R(@âzÅ•ŸÍfqʓ놜V¦¨Ñ©~¦A‚ñæp8œN§Á”c0€EV™C p'ö½$…†ét ÷M7kJB ªP®CšñGý«¸¼éßá›`ˆð†’  Ej4s¹¸û$]‰Ýn'VzšÑhÌf³‹ÅBœýÁ`®¯¯O³Ûí½^Ïét¾{÷îðð”¯çççÍf3™L"Op~~”O«ÕÊår‘Hܲ À{q}ËçóÕj·E|¨O#Úù|Þn·@µZ­T*¤ *U*4eM—ý-V—¬š¶œ%Ífs"‘¨Õj ™?ØÙÙ™Llô`�� �IDAT&»»»:ÕžðbNçææDŸ•Jåää;""Š$ …HƒZ,vÖ!4 ¦ŸJ¥Âw²D åŸ\c3…ðæn4ÁåîJÑ;‰|KPZ!wLú¹Ø¹Eyß  ]Ê-—Ëáð$ÚŒØÃû45jæœ×¨ÏZqbÜ*›ªÍ ÆAíË€= @AUrà¼^o0ŒÅb?ýéOÍfs¡PPèáÞÞžxÑÞÙÙAYÑ: ¤-•Æöz=»ÝŽÌ¢L…Ba¹\Öj5ŸÏ¦Zê¿^¯ßßß¿+¨Ö`0ìîî ƒÁÀŠr«k±X Êï£æÉl”†;(áßU*AyJ¥ôz=[7ˆGÃ+§× …De|k2™p³¯ÕjwvvNOO1×`ˆðù|z½þÇ¥R ¨{{{>Ÿ¯T*-—Ë“É<)jš‘Êöz½@Æ˜Íæããc¨ÁR”�aiàõ+…ðP·æt:Á~ÄQø‹ÇUQºT΂¦±#Â9„¨^¯£ˆ)OÈo÷z½½½=€mA6ÿþýûñxÜét�xðàè!{\…ìP4%yˆ"búP0 | ŽMÎJQéŽ2ƒm&¨†mæ®úßræ¤ÐغÝnˆ±éõ~wô»ú‚íkdän7Cñ$z§m•…HJR¬6 ‡Ç<²Ø¸Í7'•Ðb…¦’‚³¬f¨ÜÀA>`fF‰D1‡@�7\½ƒ^¯Ïf³777’!f@êÕCÚ®V+»Ý˜Q¡Pø§ú§r¹Œ€Éíí-é»Ð«Ù™ˆÎf³ÄŽŠo ‡C»ÝÎ*HŠ$ùèèH2‡y||ÌJs"S"yO_‹gÜÛÛ# ƒv»m³Ùôz=»9±…¶Ü¤à[’ƒl2™ ¸z½%ÿ5ˆÞu:"Äááa±X<::BÝŠ×ëµX,Ãáékì.&“éææ5€"}öÙg¯^½"é/ÜPŠDB PAI"d˜4. ðþbŽÇãívüãñ˜ÝX\¹F Î’H$le2¼r8éÆa=ˆ>ƒl7æ››£ÑøàÁƒßÿþ÷V«5£.±ÑhìïœD"0º¢Nu4]‡Ê J¥B+€®(wH6CH[öš…Ød 8c¢¡g ÁSeyRNÀ[ô¤···TmÌÆZ—  «V«TríÐ9ÕMÚk9ÁuÉFˆ~ÊbJ.ú-…U¬üFŸäJ ³Ï<kº’ê‹ó!{{{’ظ 7§O’‹“Û™P\ËMžœf(÷ÝN§ƒétú›ßüÌ4ì΄L>Njì�¢TÁEE¯š]4hçççÅbq±X°’—›µ@ �J´étÊÂÜ4‚:­Ë‹N§a³øÑÍÍÅb¬J£ÑàÄ­Q¡¡)6ÎÑÀ‰Si0àd¹gµzÍf3S8'6›M"hç&(‹Wg4Ë®Ón·G"‘Åbqvv9v§Ó‰‚T�Sü~§Ó` æ# w£Ñ¸¹¹yüø1èjHX =ìõzù|&HÓâS»Ýmr—Ë&.4Ø04 pck·ÛÁºF'ñ@ Àþ;òØÎG£‘Ùl†d0Q5‚îŒÝnÇè5 `–QŽˆpÔâF#\}hêµZ-bƒgggƒÁ�»`–k4v»]§ÓÍçs€pc±Øl6ÃË’Í`#´Z­�q³’„ûä0Ý þNq–t&djžìõz!Ji4ÇãñÖÖç0Äõ ¹p’p8`š—skÅ2ϼá®\MŸ¶% ä¿Õ,0,³¦Ë5”tI¦ÜÀ�ÆHöŠ-ÿclNkqs‹…•²'—ÇY•œ: ®õz4¥Ø …æóy­VãLp-ÒM%L¶(çUTÁ_®M–ŽF#:¤+ÃÜlZNKwmqý(¿ïfHôÐf³qҥؙ�¨4M0 ƒ’1É~¿q||\«Õ�ÜA ¸´ H­ ~Ñh4ôz½ÑhÄ]3§Bû_¿ßO¥Rß|ó êY ¡çv»<%Õ”Ày”Ñh’P\S@¸àt:A=,w¥jºô ‘‡$+8!ñ7ëõz<‡n·¼Ôv»˜ñGdºÄbF µ+›±ðx<N‡®Ôý~ßb±4jµêóù@«±Á`�‚8™Lv:²Ç“Ëå(''NIN£´}¿¡Rq› Ce¾å!vÉ P¯×#²¹`HñùD?qŠ•ô×v»]„€´"«/³Ù½GÍZ²‹ xäÔ¸»ñxŒíDΊì™[<I8NŸÏy9.O©vsÂ÷7Èø±ØûâÆžBÁFm6[§Ó‘{á~¿_©T€b?…÷6› 'AÍGáè‰í²’xšÂu›Vþ§:õõˆ<Ç£\z«×ëñ4³Ùl·Û¹1§©”œG¹oÑzFø‚=oêõzœK0zƒÁ Ùl‚Ì –†Ù‡5{<žù|‡!­Ôl6Áò™Ïç …xúÝn4Íçó~¿ ‡Ã‘H$›ÍÆãq£ÚÈîvvvÃÀÍ En¸…`xQUÔt:ÝÛÛ{ÿþ=pÑht2™�rF!í39sd˜£œaÿ�;S<w»Ý *‡”T�~ ™LBŠÞëõº\.°ÿ;Üjµú|¾Õje±XŸD!îsÇjµÒ*‹D"‹…ÕA…Bès.—+•Jívd’ôÜB@â yè@ Gh®}îß)'g3rn�çårI†qφ²[ø:–²AóQô’LÂÊb~øð!r°.¿ßÏŽä &}ϲ 7þœ[À@éRö¥@6²aÑÝAÇ™•iæ ãNm8rSf6›93™LàuTëäöçÍ ,nN§Óa«zá�\ápDÑìðÝUK‚•»Å{ÉþîÚÍ‹Åbr—'p@l–öx<b¾êNÀoBKöp{{Ûï÷›L¦r¹,‰€Er5á´šÆâ· ñJâ~pIøÖ|>¯T*Pœ}ûCd,0®Ñhx<×ÞÞÞf³YÄ pÕÐétáp8ŸÏ§ÓiŸÏ7ŸÏ/..P´ M¼D"Q.—///¡(BBVlÛb±@iµXh© J‰Ý.[;t8s¢Î Ô bkçü/˜&0 §§§‘!;x{{{yy º¾¢Ñ(’ lÿÐ]dSøˆ‰€è¯P(X­ÖT*EWçëëëP(t¹2Ún· :ì+X ‡™…D2ø~¨“wBaÓ{Qï ÂMN󇊑ì߈§:€í×ÉçóÁ`ðÝ»w~¿ÿ׿þ5”ûÝz½ ï¹?±r¬¢[ÀA\«ÕÖëuq”`�È­ªqûʆ!ç¸XÂr¤i‹ÂìËIÎKôG!|φŽ#¶9ÉK௮®¸¡Oët€£¡”�ÈH¢…°@ưI7 TË=9™L–ËeT**‹‹g¹@z§K'LJý±Û¡ËfõI©Q„zk»Ý‡Ã»»»&“ aI”™y½ÞÅbA÷<ê<ë©©…Åâ boö#.kiììþáïh(z½ÞÙÙjÄ=O¡PˆÇãÈ( BóQ®µ^¯wuufX@ʰM6›M¶~ggÇb±œœœ öe±ÁfªÕ*xópq:ívûææû¼ƒ(]Šúoˆêj>ªâ¢².B®Âb±¸\.½^ÿæÍòQöÈãñd2™>ˆ‡Pè‰Ð5õ¢ô£ëÁ·¦Ó)ç‚“Éä7ß|Cs„‹i¡B\‘Mt!‡:u5Æìr¹\.æšå_` •…BAÁU¡zÐãñàíD¸Ò]Ûb±àÖ¾¤.´4çó9¤uÙ8!‚QŸþy,K&“ìá†^ÔŽŠ«ãÓ snå¸Ê�)Œa*•")d”µZ­f³‹ÅHÁNr+7NÄ{ß»>P§ù.Ûp84™LÄEÖ/¾’dF23’Ù#K‹Ü�‹%Ô|”QGѽš®"YÚjµî…Sˆ #™ÌQÈ5Ì!™"â.àD!'ÔÄÆð&“ jŸ Ãt:ω¢2;gIΈB~‹ €4%ç…^jÆôe85ûýþ^¯‡ÅÓl6½^/j FC°š¿xÓétŠp–^¯¿¾¾>99AßÍÍ (�ìvûÞÞ^2™Ìår:®ÕjÍf³\.çõz±£°G Ù|>ŸÑht¹\©T Kzgg¯ Š 8wÔ¤ÓéR©T©T@»*t”ál}H${{{v»½Ùl‚ïÎét>|øP¯×“sDíج)UIzTF:FzP ø n6ÏÏÏñjV«uggG#È͉iQ@ ÄC$ Q¤çv»H,Q±–É ¥ÉksN‘HDÔë£íAEüôì6/Dâøøxkk‹»)‡ÿ/soòÛZ–­ù±ïûž)’¢úæÆm"#2#òUÞC<©*jdçÈþ<,À€ú {àI ʀ퉂²*²Ò/2ãfÄí¥«¾¡ØH$E‰’H‰”?ß…çQº‘>ƒÀ ‘çpŸÝ¬½öZëû¾^µZ=;;ƒÆ0‘HÜÞÞ...j¨5¬"’‰±ø©.Ô^ô‘@ÕöS¥+<ýCÉÆçlÿš™vvv¦RÛ<øŒûç¨ÖÓLk‰8›TÚ¨ahR5æ{¬ú} uˆ+_0„³{ ÏËœV3n·»X,šç¥ q’¨£à='9ȧíõz“´V…Ó �Åãñäóyý¦"¨µáp‹Å¬V+Zy.—ëÕ«WƒÁ “É(Su?ô÷á\ŸÙgµZççç\òÉårÛêêêéééþþ~, ‡Ã¤‹P!ét:[[[Õjõàà€êÁápˆ~R0|òäI:¦äZêýý}„©ðyã¬oa*•‚ò¹ÙlÂ^½,¸cªXÿ2 ¼‡7,ŽnФRþGä ŸÏCe„ß�…«Œ…L'¨cUKFx8ƒA¼@ª$ §“šŠÅb0'É7ûý¾Ãဥßﳄ …WúÈ…ê ãÎ ¤ÊîÍ$‹"N¶»»;=XU>’ae=JJxvvöüüü—¿üå‹/¢Ñèòòò“'O¨ô[__ï÷û.—«T*µÛmœ˜U[­Ööö6‚~ù�Kéט ó ŒÞ·Ö› °%š …z½þ—È*k?U=¡ 2¿þJÉÅR‡B!)ß44è+ÆÍéR©dÈB„çêêJ…&Œƒš\¢j*øGÙ5²Iz%\ ÈQ=çš0©NÜííí$eø^œè5³mmM¢”Ô¬Ã6 ’Éäþþ>ú°ÐDêW\MWz¡dñcάV«*`89IšØ/IÕ^\\ Y‰D^½zEÁ¨~Ž/ý~¿Ùl"¨quu…�tG£Ñèõë×­VËjµ¾{÷®ÝnsÂ�›ˆ]ÊÇóùüåååêêêôôôôôôáááÅÅR‡ÍfÓßï÷Ûív2™L¥Rûûû¹\NN!b}ªIƒÁÚÚZ·Û…Ú#üøñü#»#´#½^Ïëõžœœ\^^ªˆ]™NÔ;©å‚¢¼ Hëîî®ÝnóŠ817„Ýp"—™Öëõh¡fô Aœ\Uò´µµµ‹‹‹µµ5ŠÙVMœ¶¥¥%*DDq{\T ™L’Æà·ô`UUÓVýQ±3Ýnwyyykkë‹/¾õÈßþö·D¤7€`½|ù²ßïÛíö“““·oßjì¯áŽûˆC‰Æé¯_üâKÕ«'†Ú, ’U¨Cb“>œ0;¨"m§§§I¯L’d ‡ÃýלžW7'ë¿ù_}X︧Wÿ÷¿ÿ÷ÿþA­‰D"Bzö^¹\NÌ“oŸ &ÝG¢[˜c0U@@_Î ãñøäeŸßBõQ“¨P?ⱕJåÇò—J¥r|||oÉ ¹ÍÛÛ[»Ý®)Z…!wkk+›ÍòÍÞ–L&YÕ6›íææfuuõõë×NŒL&³¹¹ ¿ÎÊÊÊ»wï‰ôwÓÓÓ³³³~¿Ÿ*v¤)%Äç÷ûÿøÇ?V*•^¯‡&£Ï¹ Íå·oß²3©™Ç3;; U£B¡ðäÉ“_ÿú×···333ÜåóùjµÝB‡„B¡|>ÿîÝ;ù-‹ÅòôéÓ·oߢ2N/9ŽýýýJ¥²··×ï÷ñg·¶¶œN'(ÈÛÛÛ¹¹9ž3)g°ÙlÝnW¯†B!t7dPÌgà³gÏ®¯¯5º‚ôÿôë“O§µµ5ø1«‰„Aÿ“\ 1¸cª:Iì‰Ñ\[[»wRZ¥Aíhº·T*Á¤µ¾¾îp8ŠÅâæææ£Õ•, ‹6¼VVVÞ¿¯ÙKÊår³Ù¼—U zÝÐŒS[­VïmÆ£çŒ\¿úÕ¯þê¿úoÿ¯ÿçc¯ÛÞ÷Ýÿù¿ü[íÉI/¼¨ÉªÈ)AM>Â&šÈ¿êÁùŸÝ§NKu†ËåB𔈖ËåªÕj(®êwÇ ÑvúÞ+w{ïU*•&Œø=èÒ£.Ä«‚^ÖÐ„Ž‚=½ä%šå`fûý¾×ë…,\¾�–¯ªZ­šàÕ�0Ê>Ÿïìì,CC777‡h2I¦v»Mí5¬¤$A«¼~ýz4×å#FbØ:p¨eÎÌÍÍ5›Íh4 –³ßïW«UŽé/^¼øî»ï,Ÿˆæ‰D¡P�Ò`³Ùfgg!ci]”µZ:Äp¡d$4$‚Ë¡PèÛo¿ýùÏþå—_~øRŒ‹‹ 8MØÕ`Þáp˜ÉdPO†‹o0¨êÉTÝÝÝŸŸ›×þ€š:??G¶QôãE›=R:j4O®i;33£fLõ˜îŸêšžž¾¾¾^]]=>>Õ«*n[,–F£Ü-*Æ‹¡*á’ÈäS=œVý-à6> òôÞK »úLÍ0ÔÏD«—™�ìÚápZr‘»ÕðƒÜ;g:F÷‡õH/kú‚Êtp'“›\HŒ#0ÖKCÝ *;®·ÐX,¦‡îº\®T*ëŒæWÀÆ3·<µÙlôðèIVƒÔ=¨Vâ^¹[õBÎNó"ã’ȼš´ðqXZHJ¥’ºöÀp8D9)‘HH-ŸÚ·üœÏçK&“ƒÁ�_yVHWÑ䆾^QU™Â0îFmä£P(twwÇv˜L&Ãá°Ûí†_ ­lA½^o·ÛT‹ÐÙÛÛ£b¾Óé š‹Å(r•l–äí …B(b³‘ùÿüùóÝÝÝD"Ñn·qíóù<H—“““@ �(®U)¹l4x3ªŽQ&“¤ÒX2"Ðp®"�xrrR(–——ƒÁ`µZmµZ°HRK§ÓÇÇÇàÏdEˆD2¥‰œä …ÜT*Åû¦R)t"­;.a€•Éf³KWU°UýÜq¦ÊÄã&’ŒL*(´ÇE`èjø[`ŠIƒÉ>ª:Ž|>ãâv»ÕY#Kq¦jg˜]÷&³eÇŸŸW9ôT[Ä1„ ö qlœ%<ÐétBw©_€ÐÈÜ:¹Ýî eÎüô›Jâ¥Å”ÏÃÌý¸ Ôºzä2¡ÖƒV«U]0ø@ŽÕÙÀ™”±×ˆqÈ®f#çEŸš{Db‡ùÄGÑhT]ü¾ä“\™LFx''‰¬« üÉO·ÔÅ ‡Ãt:ˆ&dÓs»ÝÖt1gP] ÈøâÜÅb±ÍÍÍçÏŸ#W177Gõ*&â >Éô@Ƀ=<<L&“P?^2ìíí‘X ©T*‘Hd2™x<SÜÖÖÁC«Õº··çóù /o4ÝnðÏçƒQ>‹É"¿½½íõzv»>jfff|>ßíí-ÒÌLÝT*…ü¼œ³9!©œËå ê̤˦`åýú5N7)‡››0­VKîgggív+9’É$h*ÖÄgw:™L‰ñh4z{{K‚ ^‡Ã¡¡îÕ˜$0³ð¨ŠY—ч:òz½ñx|4ƒAóùiù¤„ ¡ÎCU_ÅbD"Ç£Ék.õHÇLÓ@§07 U0‚Ñ„‹ô"@ljÍ55£ÏÐë·ÁYÛi‰ä¢Ò°^¯'pÚq&Wh‡ ¡»²Nš=W¬ßïc«Çõ¹ð�0Ä›‹ÅpÑ0,÷ƒpùh,Ö÷ ¹"šÐ„Å-:à.6¾L§ÓÑléú°€ÛíF�ÞUU-¾ÕjÅãñq * ;™ÉU(ôI~þ’Édô”H¾kwwmŽIHcï-L888Ѐp O1Q4 `Y/Bj³ÙF¿ß'’Ëœ‘O/..�ÜIº¨P(ÌÍÍÃ=;;CIHï'ªÿ‹)å¼h¼²PY T¦§§Ù€¥­V«½^ÏívcNNN‚Á`¿ßßÝÝå”˃ú[µZÓŒÀæ`Ÿšš:::ª×ëoÞ¼A–c´Ävˆº ‡CÎRLé~¿¯"õ°ÓÃÃC‚ò°¸c¹9ŽF£‘ËåØP/..þæoþ†à³pßAß%ο›‘€™X½^¯X,–ËeèXVRâLŽA…@ÉÄ�ImyfVf àÙIÔT‡Ã!“ðq;còX¢áL“¸¢¦ È1“€T{÷åÞt»¦Ç¥Óô«9f|I1æóyÕЙ¯}uÃ0„î~Î%ø\Âà㾪ón·ÛUaåD"AxÙ„Á¦?èÁs,KNw@)Çð TªEý*·´xâˆLÂz@¥Á7½ÔÓçŸl²Ùìþþþ8·å@=İt‹Ýn'È« Ú¨UCÃáP½kU 2ã>â¼¥axDòNίÙl–"ÝöÏþY¥R‘ü‡¤ƽ@H}½X,ÎÏÏ»Ýn˜â:ÎÑÑÑööö`0xòä ‹çíÛ·HÄÆb1²’‰Dã·^*•š™™±("¹#E"»ÝÎÙ…úrÈJ�-ŒF£ÝÝ]ªï‘-..:޳³3QO·TpÇÑ¡š±P(@2Ûl6m6Ûîî.Y:Ùƒëõ:ûn©T¢È;•JE"¨Ö1 õzhA¿qííí½|ù/L†’¦¦¦ô u·ÛÍ„q¹\‘HDcôõ²ÅŒ¾Þ)<::šœæ'¼PÜ#ƒ¾‰f³1ÉÁÌÌÌÄãñX,Æ]N§“lB.—£LÛÉÉÉÑÑ‘à‡H´JG6¨š5Èã‡ÃḽPƒÜ’»T˜ètë÷BM÷^"\k¨«'W­VH[€úRµZ B†q[€6¬§?ƒkdR¥ÓA>ÚP·Û‡€˜„&¯¯¯¡e¼÷P"ñn C€'û“ÈPª¨4}VPÿGøŒ½oÙíöR©4®¼Âét’QÿX©TÒé´F©OcòdÇwµÆT‡˜â`ó<g$ &õ "\;ºZXX ø–L&¯®® » ‡ÃŠ1¸æõÁÚjµÎÏÏ™V«Îh4šM$ ˆÈla‘a¥T!‘H úŠBR¥R ‡ÃµZðÕÝÝ]b›¹\ŽÊìÁ`‰D@ÑŽF#þ855Õjµð%ÕÙâr¹ÐÏÕT K ÓÌññq§Ó!/= òùüþþ>5‡DG¯¯¯§§§Ù~677ÉNÏakDú)zÆétZ$’¥Oäð$Ó@3áqADè¥s^?Ni4£š ¾ð§½ÆIZ«=½°²4RÒBz‘Oj2¯®® …‚†E\›ŽåívC™®ba)m•U/ žG[ fšìŒ”É6 ·ª]•OÕ‰1n-ÿTÚ²M¨‡9ùiù"®Á`ðœkUƒo%÷3®£Uèk>Ÿ¿»»¬®6”9ýhAÉ~¿?;;Ûl6a¡žÜ®Û)Ú ”´ÛíOž<|’õFÝ*¬ßfôÐ]r~† Uý ‰ôÃ$¿f¦‹E5Q ggg%\Q?Ž|4Ž«âúú<¦ÍÁÁÁË—/)1gÙ‹E¶&ñxœ<¨ÉX,V­V©Â µZ-—Ë---µÛíh4º±±bíÜ…/Ź$w»]ŠðKJ¥Ò‡noo³§êŒ¨=´+"6H¶ Tæh4ZYY!ž ÆSz€-ðèèH?Žù|þäädff†ˆ“iZ–Pb¯×Ûjµòù|¯×ãtˆí”ØH ?OJ™vŠ´¼¼ÌQÉíT*E©ñ³gÏÔ .sFVºÊ“&3‡Ye®Ÿ?Ée²FÆY'ÕÓ±†òÓÜH˜T4 kÑÏ£-ç}ÕöœY­ÖR©[ƒ‰æH-Öé¡´2†–1 Ü¥¥%•.Ž“Ñ„#øh¹[ýµ¸¸H ³9Ê2^?ûÙÏðˆÕ[z½^¿ß Úq:„†<³ËËˬÿ@ ¢�b;çDrQÂýó… ÄûðûýñxœÙ¶ººº³³ …&ÜœØ]Td$cª÷Gt6›UIxsšµª‘¡T-.áCÏvÂìÎû¢Fž¶:ýd˜žž®T*æžʹ¿ýíoÿÃøœ÷ÑÒ^^^v:Äî�nkŽéøì½^#K.—«×ëàpIÔÓ¥½^ŠîÓÓÓÅÅE@¬Dç Ì´²²‚V¡ËåÚÚÚÐôÉɉ,r¯×{vv†ò .°ÕjEtª×ëÁ£zyyùí·ß€&ð §R©áp8??ŸËåvwwqÎô T�� �IDATD&faa¡Ýn×j5Ì=\œB„jág?ûɹ„3å7ß|“Ïç}>_³Ù ”<ØüîînqqQ X¤@Þééi¨ ¨_¸¸¸h4ƒÁ@rKš»Ôð/¿ÎGÇÙl¶………F£FE©yr6Ï]÷Fì5Öiii‰ò3Ë<3Y,Q¢|>ït:5;æ‡XV«kÎ$TŸcQ�¿8 SSSV«õÞ¤žÄ$–D¨´ÛíÏž=s»ÝûûûšÍO§UÁ"è/ŸÏšç34ª˜qÃÍÉòoþ×_ÿêßþÿÝÿð?ÿ«õ¯>2­­­=®‰«««Ÿó»{Z>‘x>ú9n·ª1¢@°ªË¤Ñ_”y'o¡JÒü“_¡P¨\.KVý-rÔŸ?”ÏŸ?w‹(J&0‚8úæ›o1ÏÌÌD"‘ÅÅů¿þÚ¤.—ëùóçÏŸ?/ ¹\îùóç_}õÕ‹/PH"Ó£qŸ>}ªv»T|ñÅòe›Íær¹¦§§áÊÓ´\bµ|ª&/—Ë ‹ñœþÅ¿ø†ár§Óùõ×_kša·Ûççç¿üòK·ÛýâÅ nŒÅbÅb±X,>þ<Z­VŸÏ÷í·ßrËÔÔT6›•\[[óz½+++T6çr9ž)Ô_}õU±Xä·¨OY]]e„B!2nºtÂy˜ÉdÐÐ’â M›ˆèŸoVO²¸ —¡,ºÏ¹4scjjêùóçÁ`pyyùÞ‡8M®R©”H$&´Ÿ¡PhvvöÏÝŸè¥Éèk™šo2ä/bg …iQÍÄPE}ß_ýêWÿû¯ø¯ÿÇÿí¿üïÿ§oþ‹ÿ¦qÒú\ú" œöÞ­X§¥H÷A{¸Ë‹Å�9B÷ÉÉÃðÐÀúwž “!GU1ÖÐ1DÀ^DT®®®–––4Š¢÷î—p± ¨ÔP öçFfŽ{õà8¿ß¯öƒP9nD²Ù,n2ã¨ÞõÅ_¨žøÅÅgÁ`ÀoqìH¥Rà €Ïd2ÑèïºÝ. \§Ó¹³³Cæ =5øsrrr~~2ÒØR©„Ž$rÂÝ�…O£ÑXXX ¹b8”•J…–·Ûíf³ ýòò2 ?«„‹E´äÕÑ'2yrr‚4-æóós`mëë눩/--¡T(‚Á ýlµZ].ÚpæÂ ïóùvvvŠÅ"‘v¯×»¹¹™H$B¡P<·ÙlâJ½ÀÖ´ÛíÝÝݳ³3ä¬ôô6úÃ4ý ¤innîââB¥·Ûí|>ÿçëYÆ‹äªX`xðô;¤í㮹¹9SÁ$¤­Þ¦©Öiؾ*¤á6Ü ôqš…¬·½Tl¾*Æ­·œ™L&ŸÏ>¥@�™jî1A*ÊjjjÊãñ` T#£?9ÙÆíφžrUšá·¯RIe˜êWÿHvÿÊg–ºÆ_>==¥7ùÈjµ¦ÓiÍ]2§ùhòkyyyÂã‘ÉEå´‰‡.Ù]£‡U²p¾¦¯À±Z­ÔMµÛm©ßòi•j.C¡ÐÒÒ’ú[Á`Px…Èܰ!“É@gÇ]ÒÃúÌ4»ÝžÉd„¡•*!F£ìS?XúËï÷CÌ*fëîînaa–ƒA»Ý¾¸¸855555…Já›7oÞ¼y£‰Òœíîîòœóóó>°Ù;ˆˆä›?~L¥Rì Œ#3mgg‡Z M¸Ãåríì쀘á¬IÿôŸþÓý¯ÿu,#AÕ"èe´Ûíííí©©©B¡€’²Çã:}aaazzºV«åóùÕÕÕùùùµµµP(´±±‘N§Å@ÀéI:VV®V«˜¶ÕÕÕüÿñ_þå_ÎÏÏë×¾Á£&l±Xö÷÷³Ù¬Óéüðá¸fõ.u¦©½FÁ=nÕІ…pv»8¶Ïçv­ÿÎéé)ý p‡ž+ݤ…>|�&¬Yƒh–Z>érÉGœ2Í_Jýß½½=Ù ôõÏšAìõzjñj0´Ùlš»ôü2ÄæG@ÄÉT‹áñxX_КЌóós ðêÄP[(÷û%ãšbxH§ê_Py™psB‡Qذq’#šô *²¢¹øèîî èt:5mÐèËMxPû|4dÆãÕ@  _$Fcœ™~ýÜ;ÛNOO%žÀJ/ÏäQ[[[[[[×××lu"åÀGãæÌÖÖ–æ™ét:ŸÏ§Óé‹‹‹íímÉè’òa¡âF€r“±€ÛjµRQ}wwG´×ëå·šÍæææ&…yjDQ¢ÛâïsJV§–T3g¶¶¶ƒZÈ .LŒ Á±Å¬‹•'þ†è{2™$,¹¶¶Ž^¯±Åââ"ª¹¹¹ùùy^‡ˆ™ÃáØÙÙaá€|ü'ÿäŸ,..ƒÁD"‘N§···©ZÆ 0gö÷÷eÃ�z¨ú”Ýn7NkBš‘H1=ÎßÜøˆ8¹×ëM§Óår9NÛívÃró ï2Óôé¨Z­V*•J¥Ò8± iŒjß±Bš¨†‰€ 3 æ{ΚÌêT*Å]WWWjÀàààÀ¼üUí ‘Y‘™f¾9éW1E=Œí‹‘ËåLb­Ò ½‘ÔŸ7à|¹KÙœXøûûû···[[[,PŒš$>ŠjgL†c7'*ˆô'á¬þ…Š[ÃÉÑívõGÚG‡€YøëA8jš5Ô É¸Xs"Ôoív¹¶ÛÛ[C°ÅñññÎÎν¿Y€>üuttÏÓ$oZ­VwvvdÞûý~u}‡Ã\.çr¹ÔÝËäÕd ØívÍÁTæŒÆ¸“ÿ___WXxc¬ƒ´´¹üµpÍf“š…Z­‹Å`m %£N<Bˆ†C¬öíÎÎνs†¤N¿ß_\\„¹•~èt:rD;<<äç...>~üØh4NOOAÝÝݽÿþòò[h0£_ýõÂÂB$ÕÂårQÞY(Êår4-‹¡P=S( ïÝ<Ünw>Ÿ…B2Äv»&½{÷N%2¶ÛíÌO¥©P(x½^ ” '§uJG"JXëõ:Àmt‘ÉeŽr…f %{“ýI÷î÷ûš5pZÍĈÅbұࣉñÃïh4¢yn·Ûðl7n¦ PoFÊèAFÄ!‰MQ–‰&ÀÃßAô›4ãââBsîÔo‡¢@¨^NG`Ô€Ž‰„¸>z@7èòoNºî: ÷i1’¡üÿÛE‚D©3ÁçŠë‘ÉdÌ÷‚Ìår û ¿ϼËå"ë.£(ë„‚>ˆAº[Ï‹h~©šjû)Ï¥©š™­Gü £|hzzš “ù®v{{ ŒÊ2Ë'ê<¦»ß™q:µZ @¥lذUQg€:Õ½Ýn—È8 պǜœœ”J¥|>_(4]”ÍfìÑc d©Ž*ƒ2¹ÃÃÃüñòò²Ùl’‚Rƒ‡ð•µZ-¶Ÿ«««üñßý»ÇÙÐY(r¹\°ÃáÔ‹Å©©©D"\étÚçó%‰••§ÓyrrR­V!ª¨Õj ìîúõU,\ÎÖ333„þ†ÃáßýÝßÑ~bÑ„•ùé÷ûQ!l¾fs’]AÕt»Ý?nnnJº¢Åq°ý /ôÒ4žÄÑÑD®333c§á^õz,‘¸VìL¬úééi0°±X¬\.W*•ååå¹¹9‘·èôB”ÅQ½™çÚÈ]Ÿ®X,¦1 dè7¤_`Îhþ˜H$T·àææF=B¨¥ó6›MS=„šš™ hXQ*•...(B½7¡w/ûPýš8•°¦1ý…Bá3‘L“oNø)HùEQé„$OLY5âD­„°…²È½^¯ZT­Bà¬4ìdæöPCÁð`ô5ÈA€‡'“ɨ~ï v²Hu”///¹Kæ .ý"_ZZZXXðz½n·»Óé$“I&=ú€T¸E#a~uuU©TNOOI.ªƒrwwK,ŒGPgI’67d2©™iù|>‘HÈ’ÃHQÅÛétH¿dŸŸŸ‡ê[mŒºQ?|óæ ÄÇív§ÆkøFŸ>}úäÉÌÓ`0ØÚÚz÷î¡¶b±˜L&Óét8†ªÓé í2 Ôn±|b³´@ì½ßïSBZº =8T>§L5¹ÏaUÊZ 3=²R*ÜÛÐŽËÚ7ûk®L&Ã/ªŒF£Ôð‘&ðp{{ £ ü.!G!´Û ”[ÆZæ6a4ÍÏÏñŹ\. îïïÎ¥7`ÆgL4kDZÈáX“4=ù*æWîîîæçç…ñH“È0<{™[ÝÉÝ¥ájF_3X“âœ@ñÚª†@e~~ž's¾}}Y¢zéì yï>GÑÌÌ `—{¿ù Ébªð«¿TáÚB¡�ù©€7ô*“ÖªÃ?î·~š ýKé­ fÆ«)Ôs@¯ü~ÿÉɉ4¬"µ ê]Ýn·R©Pø ³Ùl0|úôéêê*åa¿ùÍo„‚åüüüææ¦X,›}RËŸª'3@‚G£ÑÙÙYÌ—Õj}úôi$‰ÅbˆµcÙ›Íæùù9d¬ ”äÁf¦Š³ÁÈŽÏ;???55tw0 ±›Ëå`09ÑH$ … „=:: «««›››œ¶Ñ0¼¹¹Éçó©TêéÓ§Ïž=‹Çã¬z½ÛO*•Êf³ Ož<ATþääÍ*¿ß áƒO§Óœf`„5ƒ’ |èÑ0‘»m6›&žµº@Ú:ŽçÏŸommñìõ‚Nõz½†rÌ–1¤\²ö á´ú(½áö3 €0k>‚÷–ã ªª®,’|�±ooo…BÕæ½–——K¥R0lµZoÞ¼‘Mer¹m Øßð•dLĺþóþÏÀi6x±3ãzÞ0j=áÖ5‰‚" áÞܤÕz 3&o"›Í‹E¢®$lüÖ4¼L…ÍIßõø\@ R©X­VÁ¸s@¸ÖÖÖÌ¡Áþþþ#NÏž=óù|üA>ŸWëswõû}bÖÀ¶õFAö›?‚äq 4 ƒééél6«Fð¬V«Çã9??ÇàÊïîî^½z¥w ¯®®666dÛ‡ •Jeqqqvv6™L®®®...þðãш ÐÁÁó�„@5›Màúj ©xÿþ=‡¡¯¾ú 6ÒX,677‡È,Íã¼Åéóüüüýû÷|´¿¿Ï¦¶ùððu»½½-“IÙ—/_þö·¿Íd2n·ûãÇ’0s:­Vëúúziié·¿ýíÔÔÔþþþññño~óäáAøbå9å°µpô/™LÎÍÍÍÌÌär¹l6K ¦àããc`¹\ŽÙÞÞfØÉ]«äUTcÎ.ùc"‘(ÓîîîâââÍÍÍ÷ßÏäÌf³ÏŸ?Цc\¢ÈçóU*ͯÈyKè×7Ìà\/wdµZ‰ ìÏ OS Ïøh{{›Çú|¾©©)9Ik2è¿ûÝï~÷»ßýÍßüÍßþíßrÞ%ÄׄËgeeER/*G‘zƒÁ{ÑQ L¦* % ¼:¾°ºº o½~DÔžWÝwbtÃáð¡Uc& áV蜓Ïçƒõ6Ì£££J¥òêÕ«r¹|{{kµZOOO‰ŒßÝÝ©ž²È'³æeîúý~¸È·KQ ],WWW!ÂdùSz]Mž45Âwz. È@Ýá�Lk漇£V« MõòòRï¦Åb1! _}ï°MˆE(—ˆ˜ye‡e¼h$ .“0F›<èŒ ƒp¹\ÒWê7¿üòË““4ÖÖÖG¯×cΨ�ƒY*•¢¶•,Z\‡‡‡ðÁÏït:———I¶"a@ä0 x~¨Ñh8˜ÎÎΚÍ&=ÀFurrâõzÑñ‹F£ìg#hÔÅðÛ,Ëâââ?þøâÅ `IµZ ÀÁC#8ÑBË'lG¯×[^^öx<Ír¹¡!¨˜ŽŽŽvww›Í¦ÃḼ¼¬ÕjÄôz½^"‘¸ººÚÞÞÞÙÙét:N‡]§Z­öûýd2 üëââbqq‘p9 Âéù|^Ö9Bǃz¤˜ú�¯×K9"æ¬Ñh¸\.9»¸¸8>>æi`ïØŒUœ¬΂ªŽ-· hœµ#$ R\ïC!Ï·«™°,Ztz§n·{ffþÜv»ír¹ÓÞf³IžOoLÄΨ™›IÅ:-dÎèoÉçódçææNOOÝn7$ïß¿—âÆF£¡yAuÔÔY¡ÑÉM“Þ,„B¡t:ÍŠ@ñRó(µç- ÔÉ,¬×?Ý[__‚Žj¤fKX[[Ã$¡ë#8¹ËòI$9“‹‹ aÊeø‰¶‡Ãá_þò—ápxee%ÔëuâàSSSúNÁ´x„ ¯ì[ê,ÔãsÇÉPr‚Ô¸K¢Iú¡Âµ¢OªÿH¯*rïÅ!ƒ •þÞ|>¯QZ3™|ƒB[‰£gøL‹®(—¯ ©!jü `€D¿þõ¯«Õ*ÓÃzyy933ƒ;†ä/’ËåšÍ¦˜ŒD"1== }[.—!Ш Gl'@+&êþǽšZ­†Ôüü¼*CÊv{{Ûï÷³§b¼l6ÛÚÚZ$ùøñ#Åx×××êKÏÏÏ?~üxpp�)ûéé)¡¼@ �Pl}}½×ëÕjµN§óñãÇx<‰DÜn÷«W¯œN' c—ËÅiËËK€0Þ¢Õëv»777™ºªÜ­˜ X” •㣥¥%š¡ÏaœžžgÏžqzfÐËå².F"‘t:}yy p[ugõ—ìŽÀ´'™öD?ANV¥æ·Ÿ fÖ˜ÏLà$ ÆFŠÅm6 N)zÒ¸¹ÕÎV/8Ã4 3õ$'Xàáp¸»»‹¢¦ì~çÀOR˜ær¹r¹œœDù-Ž1.—‹=ÂëõjÌ ^;ûþÍÉvÙØÞÞ™CQ,©å¸¹¹ …Bïß¿‡`_Êê5°DƒùtzzÚ(K@ùùyp^œ+K¥Ò›7o&ÙÃ=Ãá0±¶WÎ'+J¸ê 0œ²,W“f¡2Œ4ªÂµªB%ú¤N­Y­ÖX,æp8X6¤O,‹a¸Y¨ィË�+*öH†R$’Åq1yT$‘݈ä~ÖÍÍ ¨õF£ÝnïììlmmÁíÖív17.—Ëét">{ww‡¨.¢æ$–eÆ;Žd2I28×p8¬×뼘•ÓÓSÒ™Lê9¬ŒßïÏårª.ï…ü &à·Ûí2îjõÜw^¯wjjŠeÒjµJ¥Õ=€ºÐó¬×ëä¥D0ðêêêèèˆhö´û<O«Õj6›0ûíìì¼}û6™LÄs8@¯ö÷÷9½I•t|ìµü= ^]]©{ ÕŒ‹:X÷$Â!X?ÿAqåWè@©j³|ýÂÝ™0v{{k¸3qžÓØ8 âèl¹ººBêšÍÖùqmÅm§Ó©>C;3¡q‡Ãã:—Ò˜ qš¶l„z·òѤù‰D®®®dtìv»^"9—ËÁ.¨& GÄ,çtvv&½··§é/FЇÂM¸@îÒXdâ'üÛ¡I {cc£V«QË‚ÓÇÇÇ£Ñh¨ÚŒq.•„z5¥¥áp˜ ÔGàsõŽ¿Iå~0dÿPÏ%R[­V'g­õz½*Ê=—ËÍÏχÃa=Úƒ¼ˆ~VM"£ÅLª×ëjìNÊ{»]óú†$h®¾¨Éx<¾³³Cb_¦“  9‡mllP•ãñx䨧‡Ã!Jí‹¥V«Ñ~¨Ð[­Öáá¡ø×‡‡‡4Cüß ¬6'<*­¡ ×´x¼žq ›ÍÚívöžn·K–þŽN§szzŠÿ›‘×ë%úW¯×[­ÖË—/¹ à~ooïôô´Ûí¶Z-þqssÃ8’òé÷û‡‡‡*ØÅï÷Ãõ� äôô”4 k! i’:d&èFÍ`ÕëuQ}|®>cI}õêÕÆÆ†!*ñââ'àó‹om6›9«1ANÇ<«ŸÉdZ­V,3_ø2?¸ ó…¹1¼‰„t;¼ï¬ h4z/—ë^Ç âØ ›ñèK…Ó²UK-†|>wܵèjí™åò¿‚WGqÀäFÕµW±;š�ÝÖÖÖ÷ßÿ»ßýîÇß}÷Ýææ&`Œã`nêG3Ý ƒÁ`³Ù”ZíÃÃCy`$Q Óg^gggzçE€±„§U‡Ô˜2ÉÔŠ §ÓIèÆp~cž4þÔƒ^™²`ýßýh4ªZíqÐ]Ã<ùÑÑÅQjå''†©©)^‡ÌP À÷W;n›@ 0ea x{{»¿¿ßï÷U@¾|¤I"æóyuz3gÄÓ§†U­3±Ê^¯§.ì¸ ɹD"!ìMGGG×\?88ØÜÜ ÇÃÃCp¸N§3•J]\\°¯ÜÜÜT«Õ?üᇇ‡××ל€I¤{èv»ÛÛÛtpZÞÂn· Ö’óhµZÕ{-21ôƒŠwCʆjµª_ûÃ|vGoŽ»nnnêJêMÓI8mU‡Uãç±çÉÄ`dõ/¥Yà†>ÕîµÛm¢a“,I§Ó O•¹ ¨NN=ªWÍ©ÖÉ04!¢ßðíÔaÜè›ïÇc7'Í¡»ÛíN¨k9î´NXÀãñŒ£¶ëõzïÞ½ÛÞÞF3‘¡º¾¾Œmx’E¡Òäç,c0Âò@Рú6‡ÃaF â„&øÖ³³3󪦚çççªK¸··÷‡?üÁ„´JzéRÁZ>4exNÒôðCÀæ´X‡P(D¤N,!‘@ À‚N yèW *€Ä!�¹éõz4õ2²Âóù<[¯ÇãI$”,ËûŽF#²_Ä7âñ8Üßß'¨úÔjF'•Jq$J¥R©T SˆRÆh4*•J‘H„è ð3QLOfŽ\Ôh4"é…< ê½j11»êA™ ¡¡ãÏÄ0”»E€Ø$™/ºDkqžñ ¨ƒ:s/¦[oy)º3Œ}©&rÒƒƒT>ÒLi½1999¡¨ÒЛ„%êõºZÔ.ÂÊ<Ðä¥ZÓȃéK?á W:�vË%qdµ'_È+@6ÜÆY›Z­f¶Õ«ÖSÍ(Z¨’ûÞÞÞU×hMŽF£l6K�zÜ;S.A ºgjY°úMáÛXSk|õ?§—ֽ׿š¯ÍìTQG/£i*Ã1¯Ô¿bK†cDmU.—ãT÷héR „P]ðšÍ z_s@¥ÆÉÐÌ˧’Hõ•ÙÂAGÊÒÂ( hc0ÌÌÌ4 x{{KìKæLlxhºÝ.G"ù¡P(äóùD™Œ¥õÍ7߸\®jµÊÌ”Î'O‰B1ç(ÌÕ¹oß¼$Mrww7;;ët:#‘ŃÁ�F]ˆYG£>zÁñxüÝ»w©TêÍ›7lv»}{{›š¨l6»¿¿ YêRÐ!Y±r¹ …ä¸Óï÷Iš¢Ìäõz%ê(Ñ…ápX,å,È35b’‘H¤T*!5+ç�9ÖÓùèx‰ºî„—¾ÄKl®F¸V¢Cê[Æ�Õ- Ì€TA¸ªk¥ÉþOã4Xuõá©T t6H¯{«ò(%Ÿ°4 ƒ†b²$õykuíÆýúý¾:úòd …&2M38û îp’½ã~.@*(B£VÄ fV°¥˜þ.Êx*jRíG’ÀÝÕ6è§/Ï ªLªù™Úðšžž¦Mý­áp( �8½›É8‚þr¹œ¾Æß¥Ã]0›Íêe!Ucy,..šºÝîd2‰w†ÝyhmºE!#q:•JÅ$š?‘jÐ$éçL¹\ÖWmÀ[jƒºøÅrч«««Ðè5›ÍD"áv»%'¯NéP(T¯×ãñ¸n2}>ßÜÜÜÍÍM,kµZ?ûÙÏb±ØÕÕU§ÓAÁ+2g€ý9έ­-ÚŸJ¥˜äTå k6›Ýn7‘H¤R)XÃi’Ãáøðá¤MOŸ>=>>î÷û(Šmnnv»]»»»CPø@y´Pft»Ý|>”°Æq^\\|ñâųgÏ‚Á ×ëµÙl¢ÊŠ<ÇÞÞ^  ½T.—‰¬ÞÞÞÂÙl€[d óÉQÏò§ú³———ò¿"™-ø\8sõQ„x<>77G…‚:"ªw/ ŸÃ(ØJªÕŪǽQc:­ Ñ8� ¤÷úúàݸÍÉf³ÍÏÏ?”)Ôð”6‰„7V0ŒD"ãüEFf/zÀp[; áÖ2l]ñ ÙŽû7'’«ü5Eß~û-Ïö¥jPÌ•`˜j~¿Ÿ©5uY|&4tÑ<ç‹/¾@²ÓétŠ®åÔÔidu¢ÜÜÜ hy}}­"]î @K’–‘¹Ðp·gËå²kÞweeÆnÑÐdÅN&©æ#ôŸ4_ÀLóG}ÊdÂÛÅÊTßòä`CQÿÔüâÒÒÒÙÙÙÊÊ è jwóQP猔2ªjôV«Ø\»Ý. wwwBòÆÃUý\¸ææææÖ××ïîî8lI>R†º)„JƒÁW_}Ášå%TFív»T*Y­Ößüæ7çççwÎÎÎp 8|,//ûý~ð@D¿¥oÛí¶ÈX ‡Ãóóóz½~ssóìÙ³r¹‹Åò£š€è"®C­V‡Ô^Ÿœœ4 ²¤h# º%I�� �IDAT”N§¡&* ’%R…•óùü×_]©Tnoo766666ÔYÔéth¿ËåjµZKït:V«µR©ñ>==•¡TKï0åú‰§Q§•qäùÉd²V«éa‚h õÕW¼û8/S])Tx3Ú Í%‹Næ¡*Æm¸®S©¡uêòz»§®…L&Ãɉc·Én1ÎÔ˜,»Ý¾´´$iU ÷ÞÍ ÷KÔè SSSS™LæääD³-e2¤ò˜+++ÍfçÃÃCõjãÕšäŸlsREüž?¾´´DTêêê þS>]]]UËÓÓÓÄŽF£qv޶ðkVWW»ÝîÏþs‡Ã¡ìt:”ó‚¶³ÛíÅbä/j=ïß¿—àÕÕÕ•âz§\"H1NŽ¿*,ɺãÄaX GîÞã¹þ¡w aL±XLƒ4œ^sss*S™æiãZÈ"Y[[S#Ý4çp8æççÍKÀ-Ÿps§§§¢à®B)å·Y8F)v8årgÂårqVP+éççç;¼všWf°€Ö1—(Keˆ=ÏÚÚ•xââÚCv÷ñœðdt8ð|›ÍV(�ù©¯`–ríD"ñúõk‚uœö÷÷[­Öôô49ž©©©ƒƒƒW¯^ÑÂéééR©‹ ¸ýápH£º°°`µZ_¾|yqqDáÇäDèõz›Í&4H(›\]]Ùl¶F£ ù• D@ø_4y…««+Êó(3ùꫯ`Ø´Z­`Booo///Ñ>:::>>–Íê)ŽP´™uÍp,,,p`å·x~ô^Ô¹Ó霛›;88à¦×ÁzòäI¡PˆÇã¯^½R%‹äÊf³êy ˆžÐ8€ ºL„«ÁnÎÎÎjœ]H¡,ŸØ å£h4šJ¥„= Y«Õ¤°Nˆ1šûÇæ¸ãq/";å-&±2=6Ö¤‹ÈÜÜÜ|üøQ`Rh4µZ­ùùyHR¨’“Çª× mšÍIýv»Ý^]]Bú¤P(°D5=xvvÖï÷gffĉ@7›Ë]Õj•…ÍÌÐè®2AÁZRž$QD}=Ûôô´ÄýÆœgff ΠA¸¼”^«×2vªšoC½N™+ $ ƒà“0Æ’~Ð첚w™¨ «’—&—7çp8ŠÅ¢òõ×_‹ÅÝÝÝ@ 033ÇãñøÑÑ^üììl¯×S•…BüÀ¸ÎÎ΢4!˜ÍfÁ±Oe9f¯× ˜innniiiuu•c˜Ò?Ì ”–ðf4*Ô‹E«Õ ã88q»ÝNÑ¿ÕjµPXÇ –YÚétjµÚÞÞžÓé|ùò%i*Z˜ÏçËåò‡jµÚÊÊÊÙÙ™ÍfCèäõë×···ñx<•Jmll,//³ã¢&œËå€ÙV«U¯×›Ífãñx³Ù”!°Ûí¥R‰=¡@ Ïçá˜øãÿH ÷ùùù`0ˆF£Ýn·X,~øðBGñäTŽ�ýL£þBF?™L’3³ü©æ²áåõzM(¨G£Ñp8t8­VëààÀ0LQ=BMcb.@}5ùBwˆó …‚ŠÒ#¦ªjš<ðs–ª&þ)!ýq  ³ÙlGšäñxø_uç ò4ay—X KûiøÑO¼9Â#ˆ�õHãúrm•-Ql®á]-«TØMè)J ÇafÇA\U7A¸Jq‹Ø&= Ræ±>8KÀÇ]Ôõê_6|¾\´˜!ð€ápXŸc3i¡á¥ÁZŽ»4¸¹Ñh¤ß™B¡Ð‹/ƒü (žiKÆëêêÊívÓBs,p8&÷€–Úó<YsW*• ççç™Lܦ3›Í’ª È©®æ×ï÷Ñ—²|â›!É/S %—ËÕívAÅÑi­V šÂív;N*ƒãñøþþ~(ê÷ûm$“I 7¬V+$.U`¿ß_]]=<< Íf“,#ÇM ÇÁÁÁéééÒÒR(B3¾V«…ÃaÂDЍégÉñ¨Ñhôþý{$=3™Ìññ1œ{§§§N§óÛo¿%ÌÅf¯YVL'v××׌ãp8dô{½žxî³Ûí~¿_¿²$’6nóˆF£‡‡‡"4<nrF"¿ß?.<>îbb ‡C¶™‡²$;Ž•••ôþÑÔÔÔÖÖ–”–-Vi0ÿa®ËËKݳ æ¹åPËd°<7aúœfLòÑä›ÓØRò`0ˆwöÃ?¼}ûö^'å^ô™åO!W'''&ªxåƒ^Çå„4° C@¥t«êâ¡€T«hhƒAÂwáv»ÝI(÷^6›MÊŽ[­–ømò^ãFy’¯i ØRd¡Bˆ�q”P… 7Tae} Çñ@8¶Ùld.U¿,K¢àMÂz‡‡‡” 8Îï¿ÿþÍ›7¿ÿýï÷ööD®Yk¿ßÏ&'“°T*ñ@<$ÁZrÝŧxO€Û°Òõz= c±X2™ŒF£h[нÝnA6BŸÏ‘ÿ%6�7ÚÔÔ”à™noo©@¿ßëׯ9C³[ÏÎÎ2!)ÿF©U£ìæ}›››jöWõWˆóºÝnAgÛl6Êͽ^¯�*!‹2N²9éÿÎ 21sÛÛÛ`“Í''¥24“pÜÅÄà½Ìes '<˜ªN§C�Im!ïKîC=7˜ZÞ{‰¦­ùÊUMæ½|>Ÿ`B£.h§jµº±±1¡ÿªû[îƒÍjFJ'†wÉ*kî4¾ª4iH›Ív~~~||lÈ> ^z‘\P“jºlr\¯3«IÒ<T7ºÕjiNB×××¢_UÝU¹Ký£&¼9aM# ðG\ÃáPÈår�;®®®´ š+ªc§ŸFpõÊW«Õï¾ûîÍ›7Õj•ïs¤( ¤¾@¤ ¸Œã¸Yù©†H, Oã‡T6ºé”òomm‘Úón2™Ô<Bä|>ŸÍf¯¯¯ÙÁÀòÑÔÔR°,'~Dg>ŸGÜn§Ó ‡ÃÝn÷Õ«WÔz`¤†ìììD"‘z½¾¸¸xpp@%÷ÚÚZ¥R ƒ0‹#°»»{yy¹¸¸X,¥›W&¯„ä™@ÈB¨AÄF4mgffÈ6y<²­j€áâââüüœ„b·ÛÕˆS)†²Z­¦R)—Ë5ª˜Ë僆P˜zEóýÌðpdh>Úßßq‹Ž@µï†Ð(Ãédù$éb¸ê¹ƒÁæææÛ·oÕÁÁÁlÍ¡nËü(6n÷É]½!Rá´šRE¢†¯¯¯³ÙìÌÌ uãjkÍ‘¶°.—3×g9Ç‘˜WKÙ4#§LÈBÓ#ê‘_¯…ª¿ü~?”…êJ û ©ÓO¯Ï?N~‚ãÆÁi'¿&t¬4ø\˜› IÒ(Tª››°µçççú4�/5T«Õb„øh?é «ÕªAªSèE^Ä|ë•Fãêê ô‰fÕ‘¯¦¢—dõÝݬQ”låóy p?7—Ë©1Í’É$t…äY!¾ƒj¡ÿé‚C½R© „[«Õ„¥ò­@ ‰D� ’1ÝØØ(‹¸Ûår×{zzo¯×ëõzòj+++‹‹‹•JêØ³³³Z­„¼—N©D"ñõ×_—J%öT‡Ãquuussspp@8TÆ‹âÛóóówïÞý§ÿôŸðiZ­Ö`0@<·Ñh #®‘H†oT‚óªªnA•©—ÖáÇáiî7¢¾ßðƇ"%®¯¯„«‡ ^__omm]__žçTŠ96­ããc“·6e½nºþ–ILÐ`0Èd2¹\N/’«š“ŽÒ€ý}½11¼l± ú/Jëþ‰×¢æœ~øá!öz½årx;Ê`0@ u’Á×}UóÓbóW¢.ãA!éÏ µ•Ëe“xºáÕív'‰SS 2 6n½T,ONNÔ£![¸5ë–êÒ{{É\Ÿ`¬ä`ô» Õ›Œµ?tW”ÅØ W]?ú•<55E-r`ùþ-8kX_kµZ¡P¸¸¸H¥RN'‰œŸŸ§R)‡ÃA®Ù§D"ÁfɆD½>YNŠ’IžžŽD" ‹8#f³YØ]‡Ã!õ GGG}„Ãa¤c[­ä¶°?X­ÖjµŠÚ¯Ãá@= Òä„Ôn·G½^Ïår''' B JõP©TÝŠ`08ß½{×jµnnn …Âþþ¾tµ”Ì™™™™ÝÝ]0Èͪ3DU<RÍ4‘[u¸ÉBɧêœÉd2(éŒ#SŸ—ø¬T*EÓB¡0 ¤úÃð"Ë2NFUÂU/&ù8cMÌ“á»Ã.QÍ[K%—É+›|¤7§ÅbQßí_]]¡d …ÆTDj`°¿¾æJ¸æóÐ[Ÿ´ bnnNð1NõÁ–¢…*qC2Õ õäïx‹èÇhö| aÆüü¼>;W(¤U¬Ù?“>'‰D£ÑÉ ¨á®P(Ä9ZÝÕl±ñ˜yuv"I§ÞöEý¦×ëzrÎÃ4Þ«Ojˆ¶C÷¬Õjõz=äbOOOçææó&†ÆF°Õi´ÕÇAýÀöz=·Û å•aûƒÁàåå%�>ʈG£Q4å”�5Ãññ1ÝH ºƒ>{öŒ jO(ö:B¸ÃápnnŽçX‹Å( X__Ÿ››ƒo"N£c;77W*•@øíìì@Š …"‘R¹ƒÁàÝ»wwww\Ùíöjµ‹Å³Ù,é´H$Ò‹£Óé hKÔbYœŽMn·›'pöŠF«Õ*‚¿ LMM!À#“ÓÐR£ŸË8ªG1™K2gÀÖ|N½�žéĬ`!bËå2+Ñ\;ÛP¸Öjµ>yòÄçóÛÒ¸kBÅ[ýÏf³Ìóûù—!3KR4´2™ÌÎÎνÍVïº7…¯1&Ÿó Ä32™L¥R»9y‡g‡‡‡XdY¢lŒ¼˜Àß4Ç|�z°~ÉHÃ, ëõ:È ‡ôAFÃ’- ‘ŽûihÈäLþ„Á`ÀKéÓã~Ñjµ²9ÜÝÝåóyûzÜÇE½—â‡4îž ?äS=$¯¾1ãл’V%cd6DÛ ª¼ºÝîôôt2™ÜÛÛCèA¾LGÉ“C¡ÐÜÜÜÞÞž TPVE»ÝÆ:KÏÊ[¶@²/œAQ]:::bi! ¨rM©=Ì?R©ãèv»½Âã€Si³ÙJ¥Òh4‚}™ÃÍááa½^ŸÝÜÜÄ_™žž®T*óóó…B¦óL&à ª@ ès�ï[[[Ðá­­­R©´¾¾ŽTãÞÞ^:i‹égÇÊj­T*qNÐap”¡ÖY¶óP(ÄiR¥up8 â¸hð•z¶f.i,Æä—f¦ ñ‡Ì ži¸ñ¨ÀmÃ/�÷´µÞæPf8Ûý~6›EvK5&gjE½è[ug ƒ«Õj‚s2±uš«ÝÎYbg]½K3úúorÒÒsmË]Ùlv~~žÀÃ$[ìùùù³gÏÆnNÍ×ÿ÷/óoò}W’s»Ýß|ó ª_Èàúý~*Ñ�T*„S¸’ݵŒ—p}Ä%Ѥɟ©¬ÑÐ@h\‰r¹|zzJ€·Ðà^ç6júI#`UP>ãD³Æ½¾ù@ \1›Íz<ž•ÂS}ÆâíÛ·lØ2îX\\ĨYJ¥R³³³œÕÎWOŠ- ƒOŸ>ÃGŽLMMIŒ»ÛíR¹$8ë7oÞp8^\\´Ùlbõ](<ÖV«uggg4!%5;;kµZÝn7Õqd}2™L2™¤Š’moaaa~~þõë×ʼn„ÃáˆF£n·™V«µ··÷»ßýé Ñ„Ë5JN‹åǹ\noooqqq}}}zzúääDŠûAgßÜÜx<hЍ)%çDŒ‘:~\‰°™¡÷áõzEäþîîÎårÉ-É`çS•Uh —?ú|>“Ixï¥AÚšÏÞG|§ÙlF"‘l6«ÉTY­Ö¹¹¹wïÞÅb±t:­Ïc!’‹÷©†ôçææ>|øðP“bù¤CÈ´á™ËËËïß¿—¯© ˆñd %‚á·ÙlÔhL¨Ð­Ù™àS–{aÄ7¹ Æ}…q‹#ü0î$—à-Ÿd(½^ïÅÅÅÔÔK´T*!Ò…0ÏÆÆ†!Ëe]žÓÆù´OÀX!d|Üs Xº¹¹æ†ˆ{ÁqŸyi& pÑÑhD˜E/[<‰£:NÔf³î÷á -JÝ�_3¿à£Êd26›íúú$¦™ÜÏÇUmbUiT"~Çív“ ö³³3PVšì«!ÎÚf³Õëu·ÛM<¹U¡è¢"E–J¥z½žÏç[XXØÛÛët:”HœžžV«Õb±ØjµŽ/..°h———Ôõ­¯¯sŠ‚ôëééi«Õ¢… Ü+• D 䉕ñ‡#‹ÁÈw~~Ž:¢Ãá899©T*ÉdÒãñ SG°ŽIX­VÙ·8MB€d2Ä©Tê_þË9;;KmºßïÇK˜ÕLuR¤‚´ÅçðûýPÎÌÌ@›i1ÒÎ~Ð¥AÚþ´—ßï¿»»#Ìe¸oaˆØïƒQ`i¨b™�¶/>œl?*ñ•æ#½M³|R…¿¾¾ŠTÛ‡Ëå²*¡ù  ½f5šåt:}>Ÿ8%b4@øšƒp9ÁkbcÛœ&Ahg¡KKK­VkfffaaáæææÛo¿å ÷w÷ñãGáE†YàÄg qæÓÆÁi=©#Ã(óäW«Õšð 4!ô,‰¨ñhÑÏä8ùy+ßÝÝy<ð5@<ó2‡@ �5œˆWªcJ¶cyy¹R©8NôÈ OZpÊ‘tÕ4^€ôòʇÃèƒùCsyjjŠú79)’؇•@†àv4-—Ë.—ëÝ»wÇÇÇãäDõ¤-¯Œ�A£Ñ�ǃR 7“.¢šÙétÖj5‡Ãq~~¾µµ“f¿ß÷x<¡Pˆb‡P(´··W­VÑ•ßÞÞ¶Ûíl*l9@àïÿþïÑÅ ÿ ÃS"‘Èd2¤oñöpõ8±ÍÌ̸\®W¯^e³Ùããc»Ý¾¾¾Îa ñYÎ^&.š~ˆ¹¾ýöÛ•••@ � ÕSä™ ¾ m‘ÑÂÏ ’çã ®ÿ`W¡P8==5·3„š5§7Ã÷ªT*~¿ŸiŒê&lìÌ#\m¨O8‰šP„ÃaI¾ÄãñËËËqñ|>/ãFbÂIoùõ";Á`0›Íj¦ ƒôí¸ß‚©O°ùwww”­®®N µŒGh&“I»ÝNˆ\ƒ›K&“6›íÙ³gý×].—ñ)ä5Dö…øœ §ŠÉªÍàhIU¡„ûÐ ô‰þï”ÔàÚº‹téäÏi40³q—`„ {C“L …Bà:÷öö,ж3;`ëñù| d€gjž&W‘¶òÿN§3 1‰D"l�|PtooO[À{$Ãn·Çb1*Ž`Vm4¨(OÊçó÷d½áóù`®¤= H�<5 jv )âE3Úí6 Tè]\\¸\.2CÄ…r¹\4™™‰D"çììŒÐV"‘�¼uqq }6›- ß!†øøñ#;.šñÅb1‘H”ËåÕÕÕ|>Ôo4%ñIáCÜét�„눵»Ýn¡ô¼¼ ~\†Xõ&ù÷îîîÑÑÑo~ó›ßÿþ÷oÞ¼ét:@é5 ŸBÇÑDÓ¶Z­b¡�T3ŽýfB.µæ@`5yÖjµgm1‚îF£Ñv»½¹¹)ÇhäÍoéaûúkwwWâ¥ÌXC°¿�h5î;;;â,úýþH$2aÀƒ.u»Ý&Xà³³³ _ESJ&†ùÑKÓÓÓ‚64\fH—qM¬†ÞŒÖjµR©”L&Ýnw&“!vçõzÇ=÷÷÷'œ‚Á`Ð0AÇš7l¡zôyÐt‡mÓü™&$`*þ7ä<`8½¸¸8<<D–y&Á\µ@ßãñø|¾IZÎ]¹\®Z­v²¾‘úµ f¤x×ápÜÜܼ~ýº\.‹Å½½="{š§Iã5%¿<~U™KÄü4¦É©xj„¤y*£ Õeªì7Ïq8áp˜ƒ’í@ Ñh$‰d2)ÂÕØîZ­–J¥ÐFRûœÊårlTîH$B‰|¿ßgŸ³|¢²†³xww7ŸÏsøÛØØ@í"‰ìîîRòG]ƒ×ëõz½‰D¢P(,,,ÝÝÝ~¿ßh4jµÚþþ>+v?•JÝÝÝ}üø1‘HP‡†«Ôl6K¥’àÕD@ÞÈf³ÂM.û“Úç@£Ô¬5C³ðõŽì‚ÄÁ¢Ñ¨€F†Ã¡~˜¯”ϼ áá†1ê HxÛí¶z‹º é-Ú%LQ¿ßÖ׸LîwŠM3l¶Ïçs¹\†è.ó˜°v»]&À„}‹›¹~ {?ÿ¶C=pûÿ{ò$Z×C,[•­T*>Ÿ¯Ñhloo#6 ,ìj(Ó¨Ô€p …½÷¡eå÷vá¸Ø°|öîîΰûÆU=P”)QZ©L€rÕ`ŸYüX´ÕÕUçEEÀ™ÄR åke"æóyËŸò¤I«à)ØÚÚ‰ é[üÃÆ«‰Š^¯'\ætËõõu"‘�ä(ÉtBAµÙlª~ëÝÝ]·Û•9}zzJ|Æózww†ÌÞÞ% ¢Ê8€àw!\k!©V«(¾K±—ËU.—Q·òx<Ì¢ŽN§sssT¯Ëåòù|ìC±X,“Éà¦øýþt:H$¢Ñh:fÄáØ |U´”È{“¡`½g¿T*Á°n³ÙŽt:Ó-01 ü/õ#ÛÛÛ*ôBÄŽebXtlè9ƒA(¢;Iý”~IŽV~Ð%po“+•JQR?Ée©g÷5—Ëåñx_L|UÏL(˜î³³3MÖ¸•ycôH[ä•ÑÀiÍGŠ<(U “d=ÐãºÌ¯‡pëõº! ÒÄ�Y>•›{¤< æJ'ÿãü>|`uÉ6£‚pÇÁ0UÉK½®Åbѧm?ó¢³Ù샪9 ›Oá`P>Ì'UâS¦^¼Òëõ~ñÅSSSäBÆQ"©8u£°'ã¨ö°æ#Ëx ‘¼ ú `¨jÞQˆx Ô°™l¼ñ÷\.§µèYú0‘H/�Upà™ ½ºº‡Dõf(šŸŸ·Ùl¸º�·m6Âv»ÏçN§Æ4@J |‚jòN§“Éd.//Óé4a:Îg{{{ÑhÙø\.… ?üðDvÉdrvv–àÆíííÙÙÙÑÑQ£Ñ¸¼¼¤B oår)z½Î” KÕ:úRÄKᤠµZþD U#wK៪ì—Ëå.//)·Ó{„¥R‰ ®  ;Ö”V“›d¹M¬™äÒkÚj~HÝAÑL0,„Pªù9#…A»¼¼4TÜ6yšl„ílóN“œýÔÔ”z§ˆI$î­}0}sã©ÈA&È=įä4÷¨u½\KKKzçE*îc±X£ÑØÝÝ}óæÍwß}7Ä»FÈÜ©<??W'(Òa8³æ£uopó¡W·Û½¹¹yÐΤoF.—‹D"•JÇÿææ‡:™Lê³V.žå\obúÇùƒgggçççÅb‘¸j)øHëãfó¸îeô‡Ã¡I‘k(R9‡æææÇÑÑÑ`0¨V«šé¤þP¿ßçűWéϬ³³³*÷:Ч§§’ùH¥Rõzýòò×(](pµr6º»»+—Ë;;;‰DâÉ“'ÙlVbñvéçççÔ…çr9„ÒaˆAà5[­Ön· ¯¯¯)š@çÛb±<yòÈ-EƒN§óòòrccãÇÜØØh·ÛÈÜy½^ÊF8NF£~ø^ÚH$’J¥ž<y§"©G(ØñC¡¦¹R™ÕÔþÉlF£óóó³¼H®¡›’‰Ì¢1‹1 ù¨4FÃòI‡å§Z¼2úû–5½kuyy ‡²\\\œüç¶··ñúý>êáêµ°°�jBÓ9333rXd° ?.ÈA¡™ŒàÉɉz"‡ê-‹‹‹+++íI ÙªY€Sø¡ÏiµZ¼ ~è -†œÔON¯_¿ÖŸÐÛÈ`Sïor'n°¹¹‰~ÌÞÞžô Ëå¢n5™Lšœ4>è«y0ZõÜœÛíV ”5?4u<W[¨~!N/,,få[ì'VOÄsåuˆËküD4ôbƒLÜ«««ßÿþ÷㨘T´éêꪆm9W½Û"˜Y«ÕúÍ7ߪº©Ý‡™ß²Ì:ŽÝnöì˜D .-!¨IÕáବ)<ÿqmm 9W # Òår­¬¬x½^>çT­VÕ]™®œÎ±>kkkáp¸V«¡'977÷ñãGUÉŠ�êÈfCi" d<°^¯Ë‚IÈï÷£W}||¼¼¼üý÷ßãAC»°³³³³³óìÙ³t:}qq1’ÏçÛÜܤ”Ëét†Ãa ˜¯Õj½^ïììŒUͽ͇B¡Ÿÿüçù—ILïøøøôô´V«5  èV“3ƒ:( ®¯¯ßÜÜx½^än5”%õzýúúzzzúèè‘E‡|·Û ªþç< eS5£P .×ÚÚÚú!¶F�� �IDATúºL<âÏdr1œØ²ÆÁ“Yþ'd}©By“Ä')à&Åï2ñ¬Ÿ.‹Bb YªÝnw~~^_ý«A+Z<ÑÏåSL¹êçIÏËíT«© ZÍ :âz»j"ám 5×éÖø4 •Õ/'-%§>’œó~¿¿°° ©Ç×ÏzÊëõ²#·ÊéŠØë¸)‰PÇiyyyBqi6Ä<ÔDéIKív»fTæææT÷ N*õ *Ì­×ë³ã.//ŸŸŸ;Î/^@ˆ {’4Fþ¢]¯×;;;KFDŸç[]]µ|B㫽Á‘žCIAˆ´ÕTíh4a6n¤Þ¾}KÛ¨i6œ@P=ª ¨~¿ÿÍ›7b¶PpWƒÈH)É…¡jiiéââ‚H#”É)Yv&HZÝn7Ñ­jµ*<ä2EN×f³1Äj ].eFÃn·ã.Põ‹7@ƨX,~ùå—WWW ûûû———n·{ee…Èß„> ylN~€´>~üFgggC¡Ðöö¶Ïç#uDÍq"‘øðá(þÂÏmmm±šþöoÿ–-ŸM‡ÐŸÕj=99ét:D¢œNç»wïÞ¿0ëèè( ¢óKíÃååå/ùKÐNý~Ÿ úô»»»½^ïéÓ§~¿ÿõë×ggg.2%è„««+l¥ªj*rõDäïæ! …–——é^Ááj ô–O ¹’Ì ‡Ãâ˜~~@Oý9ðþ¬J6+fÎækÅ2èé¯ô@QÙS5G¾ƒœH$l6�8=œ–_}¦^1Öì?(à¦ôÜa‹Ð490y)½âöä!"x­·3iÔ“Í"ô›Óìì,hAü8SN‡Pµyƒ¢Ñh À1ÁS=Ò– Lë÷­íL‹¥\.£¼âõzS©ýG«Õª{Ì– nnÜ@6›M y!é¡ÌO ´ªOjxN÷x<†é\h¤kµšfß’’`0”jŽD"°jTM¥æ^DeÒˆy&‚ùý~â6¿…ʰ|S�•@ÔŒÁõõ5Àm›Í°ÅÈݺÝî/^ÜÜÜ$“I¼ûn·+pïr¹Üívý’!Vçm·ÛÙ*4=8[———èm7›M6ÒœPrx<<$ô|)š˜ŸŸ‡x—#‰#awzzZ(666(Çïõzëëë³³³@»81‘¦Än·/..¢àçõzaÛÄí`gr:Ýn·^¯ÿáÀ½»ººÂ¨Áû€®<âñxìv»~=^__£¦x||,Ÿ2aòù<^Ëììl»Ýf]är9ÇâXä_AÚòRðt»]¸Þív;”²ìàs‰¯¨ œß·¯ßïkkB°ªáEM’Ï绺º¢'5qÃëòòÒ0.-šËäîM™€\v»Ý¤3;N:Þßß¿NËÇÁýˆ%Dÿ¸†¡ÅPånI.Šº 8ÜNG™l„Ÿ3Žõä‡p5 Ê&ä8Í#¤âe£1c1RPM§ÓŸëÒCØkPCRÚdìMQñ‹_übyy9“Éàæ«±£q¿‰D˜Êjþ‰Ð„ ö9K©®¡.V -m ª×ëõ’AÕƒãX^¯W>¢ „°4ëSí¥`0(w…Ãa(ìTÛA­¶fƒ$èGËÜs8€ØVG£ÑÂÂB4ýæ›o €À«h$C<55‡,±€øT[!†t}}=77‡}>ßÖÖ–Çãi6›Ø šqzzŠ&Åòòòíí- Áëõnoo_]]­­­ñC‹„­±ÕjQÈÞh4ÎÎÎgffÎÎΠ– “äõz[­V$i6›§§§ÏŸ?§,›R·`0HÒ‘ÊÉ"  ”-eë�_°>>ŸO04¥R)‰œœœèë˜ OÙÎ)Ï<âñ8$Ô”S€þ¤-†•4“Áãñd³YÜVF„P¿~2gªãA‹Nƒ'£Z'CÃõ K6cô!ï=ºá+¨<ÑnÇãõzÇ= 8*z‡†ÆD“+!}~oãõ"㾄 VŸLG, IÝ¿9¿2é#¦»IÒHì]¯×#ò0 âñ¸aÔòüüóϤpÁ9‘HU«Uó±ÜΔL&ƒ[ËÁÁÁÞÞÞ$*Ò€]ƒA$¡ìǤoÕLHÁÃØe˜(scJ˜ÍêÌè÷ûê¦Å±Ÿ]^^z<y)µ—Ô»âñ¸†³áÔH$ … Ò«z‘Äë‡Ãáéé)1ñ~¿?33³²²òäÉ’§§§Héh¶UY °çy<Š†Ù›“É$ç€x<NøûèèèäädzzÚn·_\\ð@ö¤t:Í"‹ÁQ(œNg«ÕŠF£¹\îÍ›7~¿¿Ùl’ÃO&“V«éôL&CÒápìîîB,´¿¿ïp8‰ÞÜÜÌÏÏ{‡¤‘ð™fggWWWÀ!ÂÄ[t»]Ž#‰DŠ#Lr$hV…Ãa€À°Zàû·Z-õp,–×n·c–––(¸8??§ø‚þ”ýl8ª¾6YÀd2I�üs8Š˜̨=‡ÚLêŸÉbhÒ¥&‘!jèÉVÈÎY‰jg@‚ßûLÉ<εÛmÕhàÓhÚR6- –äô[†Lf‡Ãðá°à¿æOÖoNýñóqEèò‘Ëåâü$P†ÑFæ ’éÏ„Î÷£å£€ÓšÜcÍp8Äœévtt”Éd€v •8™¨Óê?"�¥ÙÅj“ݺ“xppËåšÍæÅŸ>±§‰‘#|D30ˆ²™Œ5œ3¨lµZoÞ¼Éf³zq3™„j’�ˆ®à"Õy‹ÅJ¥¹¯×»¿¿www||̦…QÈårDÀªÕj8¾ººKÏÐLMMÕëuÚF¿µÛmŸÏ·¼¼\¯×aBâ¸CL6›%Ç@åÂÆÆF8&áõz].YN'PÄb±³³3ǃ gggÉd’ò"’RÇÇÇÔé‹Åh4Já%§x¤‘ÔVé͹¨p8\¯×)ƒ„×`BT†fµR¯?¹¸Œ4ãq[ óms¹I5'çÃ~ïs‚Á ¥˜Bi¶ýÊêv»Lu*ìMlt6›…‡l—¡é÷ûz³ Z!4Vˆ`«FÕju~IÌõ¸¿Ó«3òZKŠ|¡‰cÂGàuPÓÃÏçIüª…ìpãävÌ?úü‹è|»Ý6ÜhÑ'ÕäèT™T¦ï.777ëëë/_¾\__רq`.†ë“EÊCôªHª-Ö°˜ wkù„ö}DäóÞã ÿÍfSS}.3[¿Ô‹Å¢ÃáЀkµÚáá!ç�JŒ˜3ÉdR8K@g  ²Ùl¾zõêûï¿ÿãÿøŸÿó–’BàÞ•J! þÉdx`»ÝÞÝÝM§ÓU«Õd2ùå—_ær¹\.·ººº¶¶f³Ù %3Ú‘íím„8T¥Óéµµ5DÐm6ÛÁÁ/…e ‡ÃÙl¶Z­¾}ûÁ$6¡—/_Öjµb±˜Ïç­Vk¯×‹D"¯_¿‡Ãð¡‘÷Mu~~þûßÿ»^¯ïîîîîî@#šJÍ^½^O¥RårŽápÈbáTDqA±Xœššƒl·ÛNçùùy§Ó™šš¢{ív»À Aöz½ÈRKùƒf(G}i/£i¸ÀYû J6›ÕO õÍq“†W(ªT*XÒ -† ö¿w™èëæUŸI4m¥å  õÏ4žç¿Þ~nœÙ¡bÖdS©È¿5uCMÑ–‰ç*`j1A\Pß{×Ã6BÜ *ÃøH”FU©D»I/OˆÐÔÀ0É–ë‡ÊP&UãþM}3|>‰túWý-}¤C¿±As®Þ5pé[5^§yŸ«:GhUèWëÄð® /Cø°d°…Æpc”‘WsllišÍ¬\.g2™““žÆœÑhh"ˆÇ>  ’]­Õj©hbçZ­V¿ßŸŸŸªrtt¤™„$“2™Ì/~ñ fÅÙÙÙ?þ(µÔ„8‰­¹ÝnˆÀÃá°¤ÙŽÅb±r¹ ÿ‚ËåªÕj0Q;Éd2N§hs4lf0„mnn.ŸÏƒg€0+ª! ž¨Õjïß¿]Kò œ'd|“É$é4§Ó™J¥NOOëõz¯×#íÑn·Ëå2utèú|>Lõßétú‹/¾…B0ùJ釩ëq0Lµ,[V–ÈW’ÔÔLxõ–H$âv»'Aéjž@,úAÂlâ:ß»L42Í\ÓÓÓRóFW¨ænBÕP(‡‘8Qu¯AÀ΀7l<\VæúgØjy5¶Æt:ͬžf, ‰òù¼ÞŠªNƽôä)MÆýÁ’^¯—õfù$]ªéÙx< …˜1ÌÎqM´Z­ãtW5¯†âªô…ÉñBœ}•ëÏÂï÷kNÓ/<_ÕîË &“I¿ß/ñw›Í¹[“ 5f>ÌÁö“Édx5^ꫯ¾r:FUÓ~¿Oݼ:§Uå‡Ã¡Öщà)Ý®ŠäêûPæ4J(†Í“áTM21¢Ñ¨Š(Êçó² í …ÚàÆ„këææfzzúÿe~Éò3mÞ{ï  ©"«ºªº{z¥Qh¥ØXÝí_º±Š64Ò(F3Ýå‹$a ï’ ù]<Q'Îd&’ «gw/¾¼˜è)@âä1?óEŒÌ×%“Iá`‚ìeL&~]|8ŽB¡@óéßþíßìv{§Ó±X,= …BÓé‹&è«Hnoo^¯·¿¿o±X˜±ívûh4ªT*@àoþæo^¼xáõzc±˜ÕjD"Ø Ñ‚e³Ù¶··³Ùìp8¬T*€~ùå—Ùl†U xdúúý>òétŠx}£Ñˆük¿ßO§ÓÝnw{{Ûáp`ì{vv†nþ‡@ _¼x±½½=™L¬V+u§H$Òh4ÂáðÓ§O-˧OŸ:ÎóçÏÁóôå9ÃðÎÛCÚ+àb9ˆ‰:/'xXDEL4P¹ŽÛwÖ X\«E ÎZ‡‚-EîÓ¸\®X,kMÝ`c'µ Æ}†Hs¹¼¼”Ï-0·ŠÝ_±³ÊDô�ø^|+ÞÂÄ€Û o rÍÌp—µ÷ÆÆÆp8 ‡Ã:0ï{NÌ î Pƒ¢{†È?‘òÆÆ†>ßjÞ«Š9$óé0¯É-HçÍ`4rf³™ÍfËf³år™ýBfÛÊÅêF¦¿™L¦~øAøzÈf¸‚'œ§Õ'ZÚšxMÙÓö^?Yäd‹}h4jµZItšÍæo~ó›V«%€æòO¦m+T™I »¢ÁQPó&ÑÇŠ‘½_xNòb�G£' õ™'+Ï ŽOZ;â¡(POdÆV«µÑh¬®®ò‹b±Ø»wïøÌÉd²±±qzzzqqa³Ùž={‹Å¨<ãÂl±Xb±˜ßïÿôéÓl6Ãà€nÐ/¿ü’Ïç_¼x±¶¶f³Ùnnn^´F£ñêêêÍ›7¹\ŽOÞØØH§Óˆ±ŽÇc B_&x‡§OŸ‚° j¾¼¼ŒD"~¿¿Ñh˜Íf·Û-ðœÂ÷o‡–ûÿñ‡‡‡•Je:®­­íîînnnZ,ªü|”Úg³™ÝnßÜܤÉa2™†Ãá›7o–——QÊÈd2ãñØn·üø±\.óÞõõõh4 A;PµÕ5SÌ ñô­Vk0áN±XxqÁÙןÒÐò×ô\Öù®E¾Bá› ˜EÄO2ËE\jF*�`Œ90çàÑ—J%¼EÁe°‰Ž²Ì™Åb°*åÛ¸ººÔ`3^>³5ÓêÌ­aÍOÎd2«««w‚9Ûðo=œ  v”x¨PÇã±,§¡×h¾jµZõߥæ‰Htÿ‡T€�ƒXM&“@!Áªq`+ON¦@ 1ˆ Ï_Bc—òîñx|>ŸÌA¿ýÈ8ó¥›››;;;@€ê6Úþ¹\®ßï ”¼ú&¼?¨‹2AØð•c0ÖÖÖ„7cÛëõHŽy ¾Q @Ô›QWr`¥�H„¡:«ÕʹEH…ø)E6¨å‰yˆ›››0x¼^/¨῾µµå÷ûwww18ÿçþg`{;;;Õj•‚•Óéôx<•JA»ÝFGÜf³ ‡Ã££#€Ü­æêã¤8â’É$§ý9ìy;ͧ££#²4~€xNîN§ãr¹¨ÎF£V«uuuõ/ÿò/X±À¢C¾V«=}úôÝ»wãñ8Nóuà#6773™ Þ‰ƒÁ ›Íîìììì윟ŸSHI§Ó˜|…€¶µ»»û·û·/^¼�ßO‘› ¼ûéé)Go©Tbb(zÝn·P(d2™ápˆ£]4ÕtK•.μp[AÏT¼$ó|eV¯¢á¤0A—üö\.-RøÁS°åûÌ<4:t=ÙÍ鑸{AªQÿ(Å„'s’¥ÝämpqjÞ é°ì¿½¦W!Ë t�Ô›§ÎýjN¸:Ƶ:Λš×òò²f@­ßÏ—Ÿ±×ëU[ërZÐXbSËf³²`õN§Sq¬f³Y*]"Øy@–Í ámùÁP…\? *LPžú«W¯Úív,[ZZÒ„È “\ßóã�hÄãñáp˜Ïçå-¿"dFåZœóµÛm‡Ã‘ËåðÒ”æƒ\Ìïä|E„!¾+ŸÏ‹ƒÛFZN"Q¹¸IüÑù÷f³ÉïÄmHBN§ȸÍfc#ÆÇ€Ãï÷óÆã1„VJg�µ§Ói¹\>>>î÷û¨ùò%‘H0¼x Ð¢÷‹ÅðJ˜N§èˆ£¬ˆl »r¹üþýûV«Eg ­q`®“c±Ø§OŸpŸ‚5l2™tÀ ÐívCWÌd2ø¹@K¢–8NéKw:\©šÍæÊÊ `@ p||̉üüü¼Ýn»\®Ÿ~ú .ðÙÙŠétZž«¢¾Z—ÿjδ³³³z½^(0BTœLbŠé¤PmÀ'Svê#Z× Õ±³b¨Y½"ФÝ(6®~¿6®JŠÍDQóŸ‡ß»¹¹Á[ëææ¦V«ÝË?A”˜QF£‰€E¶ »Ý¾ îÑårÍ+ê,rÉ›‰úR¦´¢ïÕü5'ãÚp8ìóù4ã&ƒ–?éâ>³:õbM0+tkñ]ê2‘œuôÁ‹ìk©0®Õ¿è~˽MÙ¼R0mü4ø˜Š’½[€¤šoÄ$—ß.¯FŸÏ7NONNf³Y»ÝÆ‹ju*Å^^^*æt&“ÙÛÛ³Ùl.—K} ´öŒàZ*˜ÅlÁhòË£AJaøÊÎ&qoDˆ;\ZZzöìöá2 V¯ÉdZ^^…B˜ßÜÞÞ’E±ó"d‰ûõõõÁÁÁp8t»Ý'''Ô!Ñ©s¹\dÛ@ÏÑÜCÖh4Q£öx<V«R-<Y*EÈuÃöûý ßÈèõz½^´½Ûíf¬V«ËåzóæÇã9??Ç- ý ç¡P¨^¯×j56Sôi²Ùìååå»wïØyáß�:hµZF£ÛíÊN-žæÊÊ 9è—/_Ž9³As «!?/¢.ø¹Ð*…ç²<Ó䇥˜3Ì@õtsFX·t©»ív›"í‚+HÁGqClAjZ’ØLhá@֜ǂ‚F ÐÍàfÆ`b­‘lQE\Ówv  á‚-lµç­âûnAŠG¼ÈLCüä;ݽâ„{gò¤i­h·ÛAëâ ª«À}Áõ|¬x¾–w¾y˜?_ØP$_KÒm—˵x‰œNµâ€I‰P¿æËþ¤:1¾ˆ†Ôs¹*lÙ”“f†¼º`ݳ Î[]x™ËŸ†.ªbƒ‘/ ËKÃWËãP(ÿôââB®W* ³å)DEŒa¯×7/¾¨\.£²±¿¿O»˜^ ]ŸB¡@°‰ज़›ê®{{{(Ýíïï#»P*•Ð"*•Jü"n,£Þ}{{+ä@ßD£QRŽ.¿ß çV»ÝnµZ———­V ]˜³“Éduu•ŠÜ#€‡‡‡(•Ëå|>Å*N;æ§0<åCªÕê`0À¨‰£\.#È"²Ûí¡Pèóçϯ_¿þ÷ÿ÷wïÞœœ´Z-1gH×4!m···<J1ä™6t§ít:ýò勾Úñâö ù]&“)ró¨ Â=Ð|c½^¿¼¼Ô¡UÝÞÞ~ùò¥Ñh`†‚`ŠÎÍ8NÖˆÂû•Tÿ‡Ç2ŒÁ¬Vk­VA°ðê•ݼ{¸/ëH~Ä÷u4^ÄÝû!N¸wö5¿U°RÍF˜°ì5'ß<»[ŧ-HtÕ4É•Ò<CIEI·R©,ÈÑ3èºîF…Êý¼Æ¬þƒ”ëÈ‹¼K}ó‚º+¬KõS~n8OhCM?”ÇöääÄjµ&‰½½=~(2¥ÖM狉ÄçÏŸç•ÚI°„ã-.U¯^½J§ÓúL&Óùùùêêj0ŒF£iggg‘H¤Õj…B!Š4.”׆Ã!Dc–8‡¨LÒý&Ë‚u¤,‹eyyÙl6›Íf6Áåå奥¥½½=Úòf³päªÕj,Cqøðð¹D®FOOO9t=±ª˜fØBò­T*>Ÿ•‹™ÙlÆJs “[ x$æÝSMïMÑX%#ÔŒut^Ò¿4—*ÙªŽÌ„ú%ºkÌêZ­F¡UÞ`·Z­h4:›Í4»ÅÑhT”³‡ßï¯T*ÙlVè9¾((ä‚îsuu%Vƒ®|¨`ÚŠ°¢˜ÉF‹±ÕdõÞ×H]¨Ke:ROót�‰ÝpÕe+îïòòR?•±ŠÞŒæÔÔd�äóy!v)Þ5¯¯x¯‹jÛâ•CWç1måÂ43~7Bç%ʼn¹@y‘w©o^‘o0Þ6(»ÓNÓÌЉÄÙðl6x†¦2¢&”2àÕ*>~®üÒp2kRMê”ÊP(äñxjµH¸‹Åb$A›.›ÍbkÔï÷=ÏÖÖôææ&—Ë‘p°ì1 üB¸êõzÝn·Ãá@@Ÿ ”É8- ( „…úýþÛ·o9±ŽÏÎÎ@HS¤­µ»» î ÁåL&ƒf#'''ý~ßl6Ô=ÁÝ¢­n³ÙÂá°Ýn‡ý*O˜Åggg¤A ›æe*Åb±P(®¥ŽjŒÂÓV‡f+S…D…C“ð»`á^T ÙÂm_+ q)GÊc ’§“Â5Ts –©]šE&Ã|dÁl6›0:Ün÷<¶‚R¹H3ƧÎyŸTÓiƒÁ ˜B6›MMÁ~øAxßžÓ}Óï5ÏÔ£É?þ%¾”ΰþÌ•úgÀíí-û‘Nþñ�V¼¸R©o_]]ìjªŸŸ+p‘H„ŽŽf Ðkàƒ<×ex½btòÔåååÑh$(Öc‚_^^®T*4«ÐøaË •ù¹âëõºø:ªg`^¦Ó)ޱd€<‰ÞúÙ'''n·ûùóçëëë©TÊãñ´ÛíwïÞƒA§Ó)¤êÈfÜn7h.0Šèq!z7"­8J+ØyPSC÷þý{Ê€�íøcN8Îi‹Å²¿¿O.e0h)žž&‰p8,¶ú©P)‰K=‹Œ4ðîÙl–ÍfkµšÕjE©r•˜Òš$q‹ÅòäÉ|§†Ã!èDœp±„@šÝãñð»Àõ ¤ÿÒ‚þ³šÛñ·ì j“\Æ"°|‰-HŒ¼èO“ ƒA–X&“abú,Þ¢y®ËÛB±XаP(DF¢¸d²ÛE"WÚ±(£Ïû¤(®®®òù¼:UW´ôOä¸z½Þ¯�ˆ§(^õŽìt:eçòòò<ìÍ"Qÿ½zqŠËï÷Ï#«& ò[¾0’¸3�[ó¼ò”‚°¦ó¨ØÄÕcÎâ???GÀ›íR“̈Ì|Ò<yò$‹‰O¦å#æ“Óéôz½ò´±­sxËìlâ;Q‚Eh±XŠÅ"HK!u{{»¹¹‰ ÛßïÆíiŽ-þx²:5[ _„œ«ÇãK …ºåææf½^/•Jkkk+++[[[ÀŽi\}ùòe4ïŒÇãV«u0¼zõªÙlF£Q ³¨?œŸŸ»\.—ËEŒìŠ‘Ý„x«XºŒ¤Ýnÿþ}0|õêU<G`HÅ—/_xK­V[[[k6›ø¸7›Mð½^O�,‰©•••ÓÓS3âv»ûý¾`Fô–hlT«Uù™j’Ä¿ÿþûJ¥‚U¾p8 Õ=??w:@�lÂïENˆo7°ÏÈ%òjU¬AùÇ þ^WWW…B!›Í~ÿý÷ø¡¸\®Akt@æù¼ R< ¦±â/™ä¿¢C£á«é¶-š›gÇд¢—Ÿþ}5øÉL§ø‡ˆåÖ´ž,MÚÑ™øwájª¸d‡J«ÕúäÉaxú°˜f‹K_ w2™èxvÊR|˼¦˜I=j·Û÷Z´Â?×áp,//‹¡¸¾¾.•JÃḠTá<ÈÍÅÅ…¬hB…ŠJ‘<áäû+ÿËÖÖV£Ñ¿³F2 ÌÎVDÜ¥RIÑ8 7|‹|ç?þø#çD(âøD/\x­Z­Öb±(ø¹¼ ”ÆÊ�ßoooóù<½0*^__ Öäææf¹\~þü¹Ùl¦Ò‹Å(6Âc¥±t~~¾²²âr¹èGsq�� �IDAToÿñüé§ŸP¢xQìâây1¤†<YMo x˜�ÓšÍfµA±d�ÆY__'ê<99év»~¿ßét~þü  'ôÅÅFvàø1  bù¹üõ_ÿ5ΟÕjU¬âžìp8 nÇãñR©t~~žÏç÷ööˆ‡ÐŸåYË©6Ñ€ZH[ÜÆâ=Tý½à_ vöƒ‹|—ÛíF†CÑeÁ_QsŸAPßçó•J¥R©ôÝwßÅãñóósd;ˆÆÄË Ô^¯—^|šèJUS‰) …B¡Óéhiß8Èì3j~ªÙl^[[“W1;Æ‚Ã{çÓ,7>é¤ç„{~vøùóçE †2/rÞæ+ÿ»ð-UïÅ‚ƒ}}}]«Õî{2É”:˜¶êL6‰ø|>z”‚xh˜§ŠƒÍív£³È½),/ !åô\vÈ–= …лBfX¼*ÿc¯×ûíokµZAæX|ª»¦Hû§ã¨ÆhˆU:o<uÄÿoá+666pµÀ'ê.Q˳gÏNOO¹´xŽhá×07 ,^£´´´D—´×ë­®®~úô‰Ü¢V«5›ÍýýýÏŸ?³¡Ãuõz½oÞ¼A”èâ⛆@ �tI°Ý~¿Ÿæ–Ûí¦ȇ @ÎCÄ(‹ô››—Ë…7ÊîîîŸþô§›››R©”J¥ xM§Ó>x<žããcDî)'â>…Ne%d–òù|¯×€ñô- ÕÅjµZ­V¥,1dÈ©)±{ŽF#ÐEd`4Iï45ÎÛ‚h½„B!Eún³Ùæ^†»ø²ýô¼‹¥JËvÁåÆ*¾—ïBÅ@ñ÷=úðáƒØg²Ù¬b4ØC@0ÉdÒh4þ×ÿú_B…KœOìœ4 766.//eË4fò“'O\.W¥R¡ÞŽt^nuuÁyO¾Wkcžåîv²:—âé«ïMÓ›XÏ ×rÑ.—Ë‹0§†§25RóÒ§Ô= â'\#­V«(.©í“.ôä¼ I0àÀU_]]¡Õ(¾‹KÙ& á ¶Î�'½³¬\,Ýnw­V;;;ãWÄb1Ã_°qùoMË]ÍËb±`Q¡óL…n&“Y€}ƒÑhä]èº]Š{€#ö…çϟ㺭ŸCír¹K‹N;=dZµµZmuuõàà R©€Â:99v1éýœžžF"*××ׇãíÛ·à#0«µÛíᾚPðX`X­Vt=ˆ ÉÞúý¾Éd h±XºÝîÁÁÁ?ü€¹{8¦.zuu…Ë"t¢áp …VWWg³ÙÚÚZ£ÑˆÇã¤Ô€îºÝ®\¦£ºÈÑ’J¥ž>}úüùób± ï¢u÷øñcˆ½$vÈ.(fµÝn___Ïd2¨ ݉L­ØÎÏÏY>( ßÞÞRìRlý ¶âÒ9™ÄmÈœÙ;/Þ%dËßÃAý–jµj±XÄ>Ã+6ŒµÆã±ÍfëõzÿóþOÈŽ`+:›ä³gϺÝn.—Cá×årµÛíétšJ¥Ø nnnêõº|`hŸÅEF¥ï¸ý°<ò^B êbüD1&6è“pÛåüãoÐôB¥L)f0Luñ\ñ½–³&¥îΗ<¦„Á` qfÙëç1Ðieá%õ%„¡¨îõz Vo*•ü\ªÉ îÔÑK€Võ¯v»}yyùùógA‡g*Z÷²“M7d,uŸOþ"äº_2˜ÿûÿïn·;ÄïRÌiz3L­@ P¯×q(@(Ïï÷///;ðoôÒØŽ›Íf0¬T*8T¡žg4Ù§NNNÄàŒF#ÑØãK iá“°4hSÇ�Á)E§‡PFÔÙ΃ “³Ù,u|v±ããã?‚H6›Íûûû‰Dx� 0îÉd²Ñhx½Þ~¿<Rž~¿¿X,2¶TRý~ŸUÉÔõù|±X,™LÒIŠD"àéÑ;à”…¤Ì¹.D»åF£A"SæøÏF£Q)$‚ŠWÉ&e&8rVwN?ÁêGÀ—ûßF£QvÝ%áVoÇÅbQ é†Ó=›Íį&μK¸êØl¶f³i6› 2¢ÑhµZ%[F A½7 æµ;$•YúFØ:ùdr:BkãanU€ûÏÛ‚ù³{"€Ã*Ò)YÌŠò…ü3XÆ÷õS_@`žƒ»¾kd8+.í›x0¼ºº ƒÐ‡—¬šJWÐ0ÇkR}ÑÞ y.ÛPÒ]ÿ?sŒÑ}ÑD…À@\Pü?ÿ\«Õª–”;ŽêâªøcÙ?•ŠóóóB¡ÐjµÀï$§Qþ^HÖŠmB¬FXñ¡Phßëõ ‹¬v»¼W„Àg³Ê=V«5"Ñööí[„ÆÙ(³Ùl·Ûu»ÝÓéV,§ 2U|5»*Íj„g@ 0[èË‚+»¼¼<<<¼ººÚÝÝ…UÚï÷?}ú”H$z½ÞÁÁù"ä$ÿ‘¯…àât:JèââyunpÀB¯×{ttÄ]ýáðz½^¯·×ëÉ“Ðd2½|ù’—P•v̱XÌív##‚ÚX ŠY‘mX,THä~³¾q6j¹£ÑØý"[óâõ@áÂ…ʇˆ«�I___G£Q™'GÏ:ÕÂX,Æ¢@x[Ƚ½=J©¬…ÑhDÆÖ‰¿yôèq )òh4ª×ë û<ñeùt#Fýb1{<ž ÌyÀC¡à×:™¿Ô‡Ó<'2zÅ?b“*&Ÿb¾Îf³EˆWbÏšÇún4ÃðÈlÐñxLLðZR òÌ.üÕ»µT iZÈ7©êXŸáã ù«uÞ5¯žyzzª¸“H$2ø’N§CâyÃe·Û™>ŸO èÛû^__ÓyÖ¸ÐjŽU<¬~·Û ò^*€Åø‹)MÂÑh´»» -WP¼í ôšÍ&j°———«««àP8„H•è 3¨»| %!çLƒ0h¥R©Õj› ùÍÍM(êõzåry6›íìì„B!¸Ïù|ž—®®®Ðºív»Ng<38ÂåèèígQÓéôíÛ·Ùl¸¼Ñh¬o4?~üÉW>�>ˆÆ âŠÝYA;ÓœŠ"æs8ñx\ŸÀN¿Ys3YðÂ…‹‰¡˜-där·Iþõ¨/ß»´´ôùóg zì3Õju<C÷6›ÍPˆ8þéWaåÇœ„g&P‘|`¥RAÂcÁ-ΠÒC`b,¸5)~¸¼²t.j�š•ªûJHè ¯Q}Z $‘Ïçõ­Ÿš•j®åÃ.� ê*6á€bIk»ÝîV«¥YLPÛPB bÒ‹³S‡„Kì‰Dº<ct¬!õÁëóp·:èPêÔ/‘˜*J P©Óé³­Z­dé‹<5èR»b±˜<¹¹ét*@ÈBÔwÈMŠ_‡îåå%6+b: ƒjµ …ŠÅ"êAápÄ1ЧOŸööö�#ñ“Éd 8==…-ûòåK¦(ý•Á`À~Gþ„}Oó`2™äÁCZZZêõz`ÁÛí62h…B1ÍÉdâóù–——ÇãñÆÆÆÖÖV¡P@7ü=hˆ¥¥¥h4 »Hž<ìtCF€Óéd¶—Ëåf³™L&A²û£q}}ÍçP<4 £ˆ?êõú`0¨Õjj„"³ÁòJü_Y°œE§i«-û ‹mAÞ×ÙÁÆ>¿W_B.a8Š€VƒXv»]áédrâ]ôqåùÉ¡~yy)vŒX,Ön·Ñ‡t:¸Mú|¾Á` WzÀ¦Ï‹ËG,ëõzrf#sóïu©p+•Ê"eÕyˆöRu†Wy8 ë E{ ¬ÔeÄ¥¥¥•••;[ý², SpÙDªaú²óšXÃáP1šD»Ó³Ù,é‚Õj•-¥f)Þ¥ŽJ(lú|¾yu!ÍXC}µZ-ªÔšä—è3Pô·å°—óRQXYY!ÈR¼”Ïç5\F»¾šÄȆAKö7“ɈÄŸ:às@`ccCXùVÓé´<°‹“¤«Õ²\¬¦àH­V£Ë"v €¹ìÍf‹ð¨ë¢h·½½m6›G£Ì'Ê\Ã* Ç#ˆ® ÑÆî÷ûív»ÓéŒF£Á`�¬N`Cð‡¢ê¼8fT…B¡Ñh ð‡™–Bkgoo§v1ø©T ¦p¿ß/ P;„Xp>Ÿ§ªöéÓ'‘MŽF#.äõ(úmÈ/ MX ì‡Cži<·Û€Ûí–Sm»Ý.\áén*´}ÙLðQl r/@ßNqÑ¢ä .i$ q|rX ‘YÅa¦ÙŽRLBõDoO>ŸHyI¬K¥ ßãñÄãqÇS*•B¡•½£££x<þã?¢cÔétÌfs8ž'è§¶™~À…X­æK äÕ:o×¼ E‹g^ÛE=´[_Šž“ð'U?¶;5oXBìz:$\ÙíJø®ª‚B¡À¶Z­ÈȾÒQuncq> ü\d¤±þÄ.Œ*“X] ÁM{MÚ¡ápXáܪ¸19)ÙÜÜœ'¨%^õ\.—ËåŠÅâîî®LÓ¸±±±··Ç³SÜž0¤Q¼ÄrRKZmllL§Ó••îÁívÏë-)Îlyä¹s'•"qø›ÜÞÞ"Ïl–¯I@O?c¸ÀT™7€¥R)™L’B!`*Àœ£Ñhii©T*žž.--ñ9ƒÁ  ’úüôÓOÔ—––°Ž ƒ777@Àb±€w¿½½¥Çn2™h'0…c€uK—Á1b óósê'v»ýßþíß1d2>~üˆPÛÑÑQ¹\îv»Pš 7 ƒT*…÷p ¬~)¤R)P!«««ÇÇÇ`—åÂuKù$¯êÑCÆMaˆwuu WÞ®¯¯Qvn6›¬žh)ý^,³ÚbTþ—”ô Ô=Ã"{o§ ‡Ã¹\n2™ˆïZ¤Usyy‹Å²Ù¬ˆƒKŒÇc9`BS1“ÉÕjµx<¾²²B+áÉ“'ËËË6›“,ËåÚÜÜ GGG½^Os-h¦,ëëë;`+µHˆ?ÏZW.ÞÌf3b;ýµ/̸-|‘@g'\ÑétàZŠ’¨<( 2Íf“ãýN®á+·KØÝ.--e³Ù­­­Édâñxxü ½€oô×û@v»n·w{{«ð&a~Ì£Ó£A<d3ÒɈH8éõziƒ«Ój>üÇp8lµZ¹\îàà@^cÌŒét*×Õ±Œ"ýeF[ýL+¦ÓiJˆðÓ³U aƒÊÏQ̘¶¹\Ž]RÔŽÆãq4ÝØØh4§§§àÊòù<€È®X,BP¥¬ÄýL&¼Ddír¹€`¥R)xF©žííí^¯—N§)’€ð ïp8‚ÁàÁÁ¨t•J¥~¿¿ººŠ9: ëF£‘žÓû÷ï±c§Wäóùnnnh‰¢ln6G*r #&“ îV“ÉüÅíííëׯ±fGÃõèÄÖÖÖp8ÜÞÞæüøYøÎÉÀ–`0Hr³¶¶öåË\BŒFc F…Báâ‾‚PIX±=Q»-Šì¼ › Ž+„ØkµZ*•¢˜Ã¼g®j³ÙVWWÅ’»<¬; c„MˆÉ$ôûý�1D¾ËKâ'“I«ÕZü�z"ƒÁ@°Á _Õ‰HKKKß}÷ÝnGÉ<T2™|úôéúOÿ)N»\.NºŒ€òß¾}[*•d)ä;{Û"1]Ä WÞÖô¯µµµjµªI´W䬈ô«ËKšo ‡Ã`MÕ¿ëŽÃé?þã?„ªØždh‡á+óN8áòïÄ¡âQþœ ·Èx±s…ÃaŒ ºÝ.ª¥¥¥ QQÇ´U߆>Ö¥X,â)'þ^6œUTÒ¸õçÀ€£‘®öPѼC1"=Uw€onnì$@N§ÓKKK“ÉwmƒÄ"dáÙl¶E9¤,ì&GOŸ>­×ëŠçH[¥V«ÉfÇê oEqO&Òcˆ> :ÎÒÒR½^çƒÁà?üÃ?¼xñÂd2]^^"Ó€= ÏçCO †¬œ^ßÞÞ¢œ+ÈœØï`¹u:­­-„é0h4øÌv:ÍÍÍñx\(ƒßïçHÈÛl6=zt~~¾»»KC4™L¶Z-³ÙüæÍ›ÛÛÛl6‹»ŽS‹Åãñt»]dƇÎÀò0!ö~øðáßÿýß].×õõu:FQéíÛ·œ@™LÆçóåóùB¡ðË/¿üÍßü }«Õº»»Khr}}½½½H$¢Ñ(Å«ÓÓS\6ö÷÷é]]]aPär¹NNNÈJÁP(¶3yÂpt›&“ Z$¥RéãÇò\õGѲêt: »ÝîÚÚ84B uг±±! LôÙl÷Â=¯¯¯‹¢ŸÚãULBáB©9?ag/ø½,2W·Û8¡<€ÔúDܰ±±AÿïOú“Ñh©Ëó?üðäɲð~¿ßï÷?~üh6›[­ÖÞÞKÀ|>ÏB`É«Çö¾;­[¡ $ÃagÎÜùÂ~~8Ê*¸Ò¨?ø’˜"BZJSD¸Ã S€2Õ /�½ób ÆüMü£\½Q0m¡âó ™ÓéTpfð†Ìh4noo÷û}Å©ðøñãV«¥J»Ý.-òãý 4EÈßÌS]‘jµì·«ßàû>½ EëX–R© lõ2üG±Å£qP«Õ¸rS8³0ÈÐ õûý(W ά"7çe¦Ü•,@¬×Òï÷çóùÉd²¼¼Œ6Ýþð‡ÝÝ])\Måç(o4P°†Läa9Žv»°]X,æñx+Ç“ÉdÞ¼y¸œD!—ËÁ2Á{‚/­ÕjôÉÞ¾}{}} iŸ<žOˆ$R-ÒG“ÉV©˜¥µZÍf³ù|¾ÕÕU``dÎÏÏÃáp»Ý>>>¦’Ìb>==µÛí{{{¤eHÙò¼hGÕëu˜›<à6ÌÓ ÃËãúú;`ÊG$mŠu%Ëçó%‰““Øl6F£p4&H‚RÖl6ív;ž¹bð›Íæòò2B¡ ¨¸ºÝnµõ‰Ü] #v Q'P“pÅ$DuWž·òü6²aqii !¾ZÝròptt$äZ­Öòò2AÖ<µZ nÕéápX­VÛí¶Õjm6›0̰”eh á ”‚W¨Ñ¹ÀË@`U˜ä**" ^²~œ ÏÃ;À÷Rì„ NÑhT“`$**Š–¸ÌJ{0©óa`M¶-qÉdF¡"ÏÃl6C‘s‡Ã¡æ4àÞ­XÒ^¯×jµÊ?“‹¢ÌšJ¥õ_jA‚§¢8oä8N¸VkfEr7(šf�X(8fD®cøsž ªtãñXøb¸@^ņ…Ãá˜Ç…’i˜Š²5ÌSŠdE´vÌfs¥R¡ϯ3™LÉdÏ=1°,§›hÆ•üsЬCš(ŸÏSõâXåæ©Z”`§ 4™Lž?N8ppàr¹Øµ¯¯¯+•Ê“'OÜnwµZív»^¯÷üü<™L�"l+œUP>¯®®ªÕêÍÍÍÇé-Ñ.å èv»ØÔâ…P,Å´óóóÁ`@"~~~^­Vùí²3ÊIbv‘}RÅÂÀ·R©Š™¹\Ž9‹Å™n: >ŸOÆ(ÉAX<¯D£[^°….//Ãá0?¿ÝnƒET+dªëÀÙšçÏ"êW:$\§Óéñx檅ç²é*fš¸t6kêÀd¨[]\\x½Þz½0MŠD"Á)e4ûý~µZ=88¨×ëûûûØp÷z½\.ÇŠP?N‡�´×ëÙl6º¶³ÙLXëòD¹³ŠÇ'“I2™TC¨âñ¸ÜtÀErÉ);ÏS”V®bg[èp’4ÅtõJ™©ÀáÜÙ<ÿ/J[ŠŸÝjµ …HŒÀ:ü\è´rW‰øú1kzCȨ6ò(þ#8›Í¦( T¼9H”HfÉßu/ê®Éd’%9å‰D¼^¯ÅbAz€­Ùl’0á šÍ¦ü ÷ |w»Ý%€>:88`?ít:{{{FƒßFonnþëý¯¹\A&4ÛÜùù9¸s*!ÃáˆZ“ TrWU*˜ùrEËd2¡išËÝh4J|&ù­i�èoß¾}úôé`0@c :çp8¬Õjf³o:ŠZ`ß­V+¢|˜- ¿ººâ@GFñ·=<<¼¾¾Îçó@4Óé´Ì…\__o6›0ÌÈ`ÐRšÍf;;;dd2¸½XËc¨FE"+¦Ï#xÖc»Ý.’Š OîÈ_6›M"ñp8 Ì¡Ûí"’+6¦¨9‡B¡y} }b¬8;){(J ®œ!B¯>ê šÍ˱L&S*•â·øœÍf”ø†Ãa"‘8??ǬäË—/È<¾{÷®Ùl¢$ j†b�=°;šÝn'ò¸¸¸ çÛ­V+ÚšÁ¢‘«ÜÊ/=xC¶X,Hf�„ž×1t¿ž“¾*9ŽœlÖ¬õûKŸLÄéóZ,¡PûÑy™/ý=$ׄæ" ü;°pÅãñE1(ƒhbdeµ|€ŽÂÜO¸\®Õ7P„D…àW</2Bv•••D"ñWõWëë딪Úív$AT~ ‘H„wa.ÈMÄì,‹‡‡‡ñxœ}‰¹…€)ÎõõõÁÁÁh4BruX ù|~{{¹Ò««+r%:âL 4âÒéôééé¼Q"ß"‡ç1·ÛmB—Ë•L&áÞbÙ¡×ë™L&¶˜¶@0Ü¥WBÉdB 4\9¼^/-1 ª„;‡ƒJÈl6ûòå hïn·KÒä+2Ò'''@¸£ûá‡ÀRŸžž ²l6KqïððPý°ŒFc8–›(ªÑÏw:T¿™„Ì–‰`/!¹KΑN§I²q ž5/xÝÙŠ×É ä‰!¿”_ý’᫚œ&û”h^PZ„lX€cze4ÁÀ¡ b³ÙNNN`a¿~ý: åPæV~'RœÔŠõÛãñFs2-(îJ¥ÄwQ ÏËh4Æb1ͤó’á«õÃHW÷Vˆ e…ºñxLYÙçóÉ õ|>/|-/Í»2™Ìâl;²1V®w5›Í; HË\]]á› ®~RZYð–“þ`YƒNA¯×ë÷8iÞÖãö¯×Ó§O———××× …B2™ì÷û𔬋‹ `†9Ά9®¦§§§BöB0m£Ñ(4Ì£££~¿ÿË/¿ìïïïììÀH×h4`Ôw»]Ú0¼E@ö…3[ªÍfD5¡²T*‰™æóùàMó¶ÛíGGG”1‘¿/>‘-Åb¢Ñ5 þô§?µZ-@ðˆª á)çt:ÁªÀÆ7V«Õޝ®®Ìf³€cPç™N§Á`ðððä Lbp¸ %DR&j*•"Œøüùs·ÛýôéÓëׯé´Z­ƒƒƒýýýƒƒƒy$qÅC¤îÄóe{½^&ƒ‚Â! ï=z‰D®®®ŽŽŽH£©>};ç^ÓIüµO· nS_:�bk:…k¾¤àækj™‹—H†z½Çx ìïïÊúô‰„˜– K©×¾PEÐÜd¼âvuóBgŸÑyIÍêý–ëÏ2§f³©¨#æ8WЏCaò(¼…‡ÍåKR1À*9€‚n¥i¦^?h"È‹¤X,‡Ã|>zzJè—H$À¯ ¯×û0¡xPÝS£òù|t×E®&ÇtŠIó€ƒP! Šu©PÖ¡ÏÉa2™jµZ§ÓÁ;\ôEÅ»¨&ñdçN-sRº÷¢^'-‘HÐΤÚs3‘HpJ$Ä1™LHsw¬¬¬t:L•�Î¥Ói2.H§ÓÉ +^ÃWF t}¢NÒ)›Í†CÄp8¬T*àtqQúðáÃåå%Îît‰È°éZƒAòZ$s@3ÒÖÂiDâp8|ñâ 6‡Ã1N)¨V*€…üÇãAØBT&ÁY0,Á`²0€TÞŒFã«W¯øùÓéÇB\†e>@:ݧžN,F�ŒI(sSœNçãljÄãÇ‹Åb,ã×¥R©J¥òî´®ð_]]ÍsÆaʈb}ÿÏh4ÊQ¡ælE£Q挼Õ�…Ù•ìiër¹èíÕj5(®°˜áÌ ÃWÝÈx<MX‰mA¬8ñD4T‹Nò΀fÇT\æí3wnAj[ígNv8½~ýZ±¿ßÉJS¸Fâ>Éd@²Íë]Éþ¹:óXÓyAA)м677ûý~6›,H$,K*•‚(¡Á`pcccss“ì ÚÁ‚çS.—›Íf˜‰ñ,ÖEdÙCÁQ¬«Eüsóù<§õâß%¬KéùÇãñr¹|ssspp0™Lp}•i³òÆtyy¹±±1> Š Qu´¥xЉDb<7 ¡u„R8« ã` u!å‚‹Ê@q‡×××Á`£<Ð, ¦®Ìø,QcR}â8üá‡�gÓ‰Éf³“ɤP(”J¥Z­Fï- íììÔj5¼9>|ø°µµÕívËå2jxܤÃáàdòûýèÌ"AMØ[,_½zåóùÞ¿™ÂÍÍÍÉÉ å~Ø6›mmmBÍl6K¥R£Ñ*Ïš~~&“i·Û¢ÙÖnÔÛK©�� �IDAT·©Ý1˜BŽW>Ÿ¿¹¹¡wuuµ¾¾Î¶(s-®˜zR¢|ôèÑ£GŠÅ"ïp8æÍXáƒü€52Ïq[s[€|"¯bìÁ÷©~IlJ¬J5(ƒ!U,v‚™„ûÝwßµZ- 0F#Àþ`kk+•Jíîî¢ÓØjµÖÖÖ&“I>Ÿ?88",‚b[± ¦À‚—&gÖ i,Èý…‡]Þ ï8œÞ½{wssS,öˆápX‡ñ«aô;–À+K¥ÒÕÕU*•Ò¡+ßù ìv»Â,¢ ,NÃW‚$ÅâPÅ···¥RiccÆÒÙÙÙÞÞžp¾³&œZlvâÔü2Ì84W—p†…ŒlHŽ2?wmm8k}}]^x Y&¯×«ÃW3©é‹‚c´Z­oß¾=88àoÄ-fŠß]ñÉÅbñââbccÃjµjî52D£QŽ\ŸFããÇIúý>+ ¦R)Îù~„;å“'O*•ŠÇãùî»ï®®®¨°ÑnyòäI£ÑÀÕœ wŽ£•Ì¥[°ººúøñãׯ_—J%’¤£££z½¾±±»°éÓÓS³Ù Ò/—Ë…B¡H$òÏÿüÏFcuuõ¦ápHj±X:ΫW¯ž KkµÚÑÑ~t”"1é¼(£ÑÈN1)BRº¾¾~öìå ÃW*Ép8Ìf³Ãápii Ã'y ï] 4Ãè„ÑÒäMÑàA‰Ê²^NKx¹e‹óF³Ù¼»»Ûét^¾|‰•˜ŸÂðTl ˆ¾kÎOûT§Óét:õ!Ôâí[[[Ÿ?v:‚ë"{Ä(.ñ’Zs€i/ÿ#Î[š·ÁÌL¥R iJ¥Ò§OŸ`|O&Ù€˜T¯×ív;晥R ™u!™LRàýµòKµbCÇýÃ=Z¤q VŒ•‡Bq2)ÆvÞƒ^ÑívÛí¶|0°_ð°qÔ<…¯¥~'3¸\®OŸ>…ÃáV«…qν "õQúüù³üÒãÇÅ„›Ç ¦ÃY,ó›ßllläóy8%µZÍd2íîîjZ÷BÄ3™LTrøõŸájª=¢£hæ©Çpuuu4ËRðs9„666¨äÈ?MNPúýþ<>27/ß3«Õ‡ONNöööØáZâÀX?“ɰð4Ÿõ+Üðd‡@1tü(§Ó‡Ë岸óõõõT*õöí[ñsÒé´Õj=>>®Õj777V«uuuÓäD"±²²Âó…«ÿèÑ£Ñhôùóç~¿ŸH$`³Ù,ˆ,þpXØÔ¾¤‚÷k·ÛGGGWWWHÒ]]]mmmmnnc3øòåËP(„.ªÑh|ôèXÿv»ÇS©Ôd29<<ŒD"€ñÿøñã?þHêS­V———½^ïÙÙÙöö6°…X,¶ºº*„~øá‡ñxLå¹X,ÒŠÃãêåþþ¾Ãá�HÛƒí·@°ÈÝn——ÄYb6›ÑzÇ$[¢Æ®™ÌÄü\qœ´¬&IIãñx»Ýn6›ÿôOÿÄɤpPUžÜ'«X.¨¬¯â¥étz'¹'›Ír`×ëujóÖˆb'å»d~®N“øL&£ÙŒ,LHʆ¯VݲxŠˆy;Õ¢ Å}‚yûFë8Å>£9Á` ’n·‹ãy×ëÝØØ`nÜyß}÷°ÆãqèÞ÷>œ�³Ù¬S(˜¶ù|>ŠÂŽÌÐÔ÷µ#Ý é0†óÞ¢I§%§â§®/% Ù.HóET.ú=p<ÿñÿñììÌb± S 8üñšDýž:²ÉULPÜ¡4ÓAAŒÕ$’ð©‰ÃáÈd2Ãá°^¯Ëü\yaË»�xõ øý~îh{{›vÎÉÉ ‰J¤TŠ Å`0‡Ã¨éTb¡ˆªkûûûl ýÄcmµZŠÀVá4ŠD$¶7àè(Ø6 a¶%`ii) Åãq¸>‘HäääÄï÷2m.//Óé4%¦B¡€’Løᆌo$Áõ* y<·ÛMCûÕ«W•J%‹íììôz=§Ó‰‘.P“É”N§÷»ßû|>júà¿¡.³³³ÍÍMŠ“ÀÖß¿ORlLJcss󿿯ívÿðÃà/xˆÅb1‰t»ÝåååF£ÁÄà’“�q`$ ÈÿÜí‹/‰D$á@•#˜¹:ð‹‹‹J¥îƒ”ªøõõµLÝÕ¹«W| XtŠ—¹8Å ú4™L úFM#7Í}ÜápÔjµ›jn·a-v…úôjÁÃSlw¸ü,èµ6ïZ„à,‡ÎštZͧ_¯×¬¥Ql³UÍ÷îà “ÐF£¡80ŵÛíÊG‚p55ü¹V´æwÌétRÖל:ˆÆó0hõiO GûÆJ¥Bü¥#lnn¢PyssóÝwßM&rÄZ­V¯×ÙGÎÎÎÔP=;G6Šc‰‰µ´´¤0¯ê“òKø‘zÑ<-xswNôH$Òl6uþŒÚ¦ð™žg’Kè'ÿ vvâ]?ird2ÒÂù›—ô •"Uïòx< ›y"¨…Ê·¡ø@™Ó=dÁĈF£~¿kkËëõšÍæÛÛÛp8ìp8>|ø€7}DSªÕ*Õ<T”„� §¸˜3øÆb±R©d·ÛŸ?îóùìvûx<nµZlÇ"{¾¼¼t:„Ýn—£ ƒr#âð®ü~ÿÎÎÎÍÍÍçÏŸ`ÐÑ™L&‰D F£Ñ(•J°¯˜3™LèÁÓ§O{½^³Ù¸'Ö…°_çqHå’ÿóçÏúé'Ø]µZö¾¬ó’J¥Êå2ddÃW’8íòÊ‹( Ì*tÂ9NXæj澎Aö¼ºÜg˜õ‘Hduu•@dÞ>#°)KŒ­LÝ•iÑó.@ƒP W)n:Ü ¤X^Å‹|—æÕétü~?ÒoD©èТsL¨öˆïa='eÝÒ¿Ø5,‹>¼ßï/Øä\ZZZ]]…Ù‹Å¢Ñ("ÓÂÛ d*Ö×) Ôc„Š:EAÜ?Ñ´($ò/ß}÷Ýæææûoÿmuu5‘HL§Ó½½½ý×-—Ë”wDŽ%»Ôh&aÜ9²â»?Y|¿ v Á8“^¶@œ#|7Êù¨ÓêÜÌÇM&,ìÝf9ó®X,¦þ™¡Pèøø˜N¾CĹîüX³Ù,Þåp8òù¼ $ d'gäjRq8¦® W~ ™ÁR©äõzN'x6N‚½½½p8 u4É,6YʤzB·0ã‡äñx<Ï“'O^¼xñý÷ß'“IÔ"é$ûñx<F£ñàààâââôô”b¹\ÞÝÝÅøøð𱉕•!Aíñx(©!¡ë êÕÇOOO‘Åâ÷RnµÛí6›­P($ *o‹Åf³q€A¥€EÂm! Øt§Ó¹¹¹‰ÇãÙlöÙ³gÉdÒëõÞÞÞ3‰\-‰˜L&1‹ìv;ý6¾ˆt:œŽ™ŸôóE¨!–ªš] ƒß–——ïÜgî †XûÅbññãÇÿù?ÿg§Ó hžs¦|•ËeýtˆGyXÐqǯV«E´Á‰ÇãbÇp8&“éèèú3nOòsT/R¯×«pOÕ¹sÅ>ó°‹à^kÿ/½/ãV·|Õ¿noo«Õ*Ž£Ñˆ.®ÜcÞ£û©ó½ü;BpŠ@š)ÿ;,K:N§Óù|>“Ɉ;9>>þòå‹ì *Ì+ù.õÍT*b(âbÍ./Él1°,W*HŠ»+Y§E¬ ’!_I2ôÑ+¸”ºÝnáR#ûŸŸŸøƒÁ\.ÇR§‘£ó±¤¤üw³Ù<>>V\TS#‘ˆÍfK§ÓŠ›O-•JÑ"ç™ø]@Z)àär¹G¡yJ)Cs¡'4›Íêõ:'q6›…º‹9z¯v»=‘H ”‚Á ™ gÉÕÕU½^Çç‡Æã1G=g*]ÛT«U^ªT*�¾ Ű¼2…BÁçóÅãñF£Ac¦Ñh°÷ ‡CÔ›Íæþþþîî.`~éÙÙŠ… Ã‘$PÌfæªÌêh4Š X ”‡dÛb1z¢ðèèˆÀ_6,f²qà¾r XgS£Ú¡¹ÞwÅcÂ`0ìîî–Ëå“É”ÍfïPląȵ¨\ÔLÄKù|žò ÊÅâ&£Ñ¨Ž?Žæù4™B⇋O;;;#û§ŸG‡Æçó‰ó©R©(VЂ› \±Ï<ì’µ˜õ‹„h¹ÝY½ûœÓyíøøVó¯…;µ&ÝZÁ››— ß)ò%Ö†hõó` …ÂÉÉI4E DÞh4žœœ¨E%ø¿@lc±X«ÕJ$:…é;Q.B‹ôTN{@(ª×ëGÊ[¼f‡«Õj kâ'©ƒf‰L‘(‹Û+M)~yy 9Ìpº˜ÏçI’Xu­V‹dB*òà'‰v»ÉdšÍ&@Ú`ThqSu»ÝŠƒÁ RLl.n·»Ñh ø{yyÉ7 «§““¶ `rH9t:öè^¯‡úÅÅöH+ƒAØ×××ÑháÎT*…¢h‡‡‡ §­Vëx<®Õjè·º\®³³3fãåå%Ëáì쌲0H1¶‡#™L–ËåjµÊ¯¾¾¾>::²X,XÄÄÛÙÙa�)˜L&ŸÏ'&N¸ôw›#…€î»wïÔÀF›6›z2È3ö@õÎ%֔έruæí†wii‰j§%Èãè€ðE€Õ?ª”Ø|&“ V5ܘdù©T*ÔÖèÃŽ2|õ©Q@¨ô«aw²*S©” ç­û¦Jšï²Z­¡PH­ .ïuúƒ£ö%×®¦Þ)_±+‰¨ù¹ð‰Y2™ ~kúßGÑ °ÓÀ(ÉdR-©'_2u×ãñd³Yè–À±ÎÎÎ�žÑB8??§‘`0VWW;Ô]X÷peàÖÈøô£îU¦Õ¤¹ðØ=§Ói*•êv»ì#ŠÖ±üvÁÑAiMñÉâ3AO-¸Âô=†B1Ÿ0_]]eÙ$ ¬ð4±7š¹@QB9d…Ë2B@@HžH§Ó'''6›­X,†B¡Éd‡“Éd:^]]Íf³«««>Ÿo:"AÜ8Ù5g6©Ùl.Iq3áp˜ì9væ,¿ÑhÔh4NNN^¿~MUs:–Ëe4Oiƒ r®P)Ûí6ŽM€è<º2£ÑèÑ£G$g‘H„gMÜéé)jIP1c9ËS©T0|ûö-g6ül6k4á§Ói`#l€Ôå‘7^¯×h4"Ž…ÎÍÿøGŒ?äù D_¤Ù¦t jË7âÊ4cð‡½‘ž®,^N²KÞÌb×ä« —'$j²!èMïùEpò»®¯¯Ýn7i´üÔæ1m¼d>µš·»²²rgçX‡í«/Eq'XópºÑjµøAÂÕtÂu¹\‡øHá…ª3dä}2gí¾8“ÉŠ¨æœæ%Ôà¡•€HY]]%ßÝÝýïÿý¿ŸášÃ¯{òä "˜‚DÆ„fjʆLŽSŸà²Ä2–‘ß24CĤÂñ–CQ½ÈeëRñDèͲ}¨ï©›/o†” "§ä%a' FN‘ {½^µ°ÀyìlƒDf¼ººâa]\\Äb±³³3l°Ñ«Õjf×ÖÖ¶¶¶ü~½^ÿýïlÔzäNÐDò …˜ápxuuu8BËÛØØÀ½^¯cLþþý{“Éô»ßý. R5µÙlä1ø£÷z½õõuŽ+Ô•¨Ñ5›ÍjµÚëõB¡P¹\&¢'ëâ¼´Z­Ñht6›v»Mþ4ñ´EÔyii©ÙlŽ …B{{{ÀÖ¡²‘¯ JÓ&“‰xV1¼f³ymmÍf³ÑïD´Ó霞ž‡ClvŃvËår`hçm1”¿.//Ñä6HQÍ9cø6î}/uçŸ5‚ù…~KMqd2)\r ÃÚÚ&¨¼4/•Áq[f’`ÿHZáŽ}ð7²_5ò¼¥³ê ÅÆÆV¿î­.t8ýüóÏó¶3MNŒþTÖ„ ¥ìjjµZ‹Å"µZÍ“i^!Uf Õ¬3²â%9S3™ ÈcÃWõX¤|///9hkÃÙTlj'\AU_ŠJÚõõµ&tP“Êʶe±Xž>}êv»>³šODáò)Fo8&“IrYýˆAt‘qâ±2†Ü¼¢$\ƒ%Ç#$e···£Ñèùù9f6Šï¥Ó«yT³øõ‚Õ¦ÖÁ±=›Í677QØËf³õz½T*³Ù h2BõF£N§óáÊ·øøˆ`_àÈò Xí…EzЧOŸz½^$áœH¥R···X:á‹ÅÀ"†B¡ÓÓÓñxœN§Ëå27†¨Ät:õz½Ýnw8 …~¿ÏAH§Çãñœ±•¬­­}ÿý÷8,ìïï///G"‘J¥rxx¸¾¾Ž„Å¥n·{{{Ûï÷77798WWW—––ÄÁ°±±=Ž-5#tijc]°SG"˜.¢eøÊÍ ‡ÃÐÂøL|Ÿ©JqÔ¡-CÿÕ~kk«V«©¹ù z¦×ßk³^¼;‹bz&“AX}žœ«ú‘å¥).Š–,Ùl¦P3Rl’ yu¢ÆB¡€Â²ÓéTäL‡W1†šu9v'›Í¶¼¼¼øÙ/6IM3nÑûÍòo:œÞ¿ßO¤Ëª¼ w8ÙÕ”’·Î§ùý~5ÇÈjµ*Æ}Á„šj ãÞëõ2™ÌÕÕU±X|ùò%µª.Â2Ê'Á£LV=;;ÓÿF™Ÿ«Î ðÉÕñ¯¡%gÞæææ›7oø½‹Ûû>zôh<¯¬¬aÖ’H$p.Wô„Å ˜Íæ­­-p8>Ÿ�˜¢r+³ÖÖÖÔ[Ñ«`¬ªÕªúž777Q«›èj®²b$/..@^‘KÁ3EýŒãdggÓÂËËË7oÞT*¿ßÿîÝ;aìÛëõ˜„ìæ€ån* ±X,›Íòì#˜Û¦ÓiŒ¶··Ýn÷îîîññ1D‚õõu—ËÅÁ¹»» gq³Ù<;;Ëf³oÞ¼AW·R©�Û ƒáp8“ɼzõ b,R¸ÝÞÞƒÇÿòË/årùââbuuõììlggÇ`0üøã/_¾¸èõz« ^ÅÉ—Ëåöööh¦ò«1µ¹¹¹ÙÜÜ,—Ëêз0¯×[(PYÌårÙl¶Ýnÿý÷Á`°Óé–©º‡²¤¬-Ïmyêò.õ”(•Jjf$â÷Â=' MbŸü™rá™&ìQ4ëH2ò.ÚŠïÞ½“·&ñs›Ñ9Ô?œè§ÓéŒÇc\<„!5?D}ZÌë±â Ò=½o!êΓIìó6"!¿ð<œööö„«éÝÝ*“Én·C\ðëeãZÍ‹#MJŠXìaÕ€ËËKúÈÉ´Ûít:ýåˤþÃá°Ú~‚ïòz½B® ¯ãAÁÏUÇbN§SöšÔ¼ìv;Mõ««+f!Ö¥ø?-Rk6›x‡süSz:;;S‹ VbñßÜÜ r~~.…Ûí¾ººb|�FC¬éõz²é”Ú\U¶HÖ„E,x¡v(ïz“ɤ^¯38ÕÞÞÞ·Ûí?ýéO¿üò ²#l¯`<â9BŠDÌ›–ú›Ãáèõz<Çétj6›“É$ëáp8²Ñ£îj·Û/..Êå2P¤+�PFê‡ÕjÕëõ®­­•Ëe!)2NçÛ·oyŠF£§\.g2¿ßo6›=z‰ûcèt777ét…Cô…ƒ#Ïã�ë…ÕˆËå²Ûí.—k0´Ûm,ÕñV¯;èqØ2]]]3Ddhyy™½Rijce¤+ø3§Ó©˜ øAèg¨)þ1ëˆAk^ÌR?(•Jêþ™Î»†Ã!ô d8æmApE€QÜéc  â“É$é Yþ¶;¼oðùÕsšX,¦oáô7žOêÃɬH5°¼\ä³ &Ü««a4éiëÿ™ÇãY\ÌÅIõ#¡> 0à²ÙlƒÁ`ooOõv»}Þv‰l ÿ õ °777|¬ü.E¡ïN‡@j;òÈ ¤X¶ZQ”Âè–‰í›(Ûáp`Ȥ8zm6Òã:ÈF‰D¦Ó)yÎ3y²ÙlÈ>)¦> JÊR.—Q!¢ŒFf0`²)È4ôrØ{½3ÇëõîïïÃyéŠyápxww×ð…… H«ÕÚÛÛ ¼Ä¦IL Ëå²ÇãùüùóÞÞÃ"O¶H$rxxøóÏ?ëí2¼$†Ã!膳³3ø`ƉD½^Ïçó¢ÿñìÙ3nøødíëëkrý“““ÃÃCƒÁ°¼¼|tt‰DÎÏÏ àxú~¿ÿ‡~ D6,‹ˆ²)§—ËelˆÅm#|þåËöò¿ßŸJ¥~ó›ß°�šX¹ãÂ$¬¹@ŠéAêù°–'܆Å/»Ý¾´´¤þ.y¦)$y™„`)üñÇ_~ùE§‰‰DèjßyŸ RÅt•¯ÓÓSac/ö¨û&@ún|ßr©y0íÄö²÷ñ—QȰ½ ‡Î5NœF‚i;›Íd.Ѽ«Õj-b§„Cå<~ì3ÃWL0\K4úCs÷”é´§§§òÁ &9þ*×Ùٙ⠡Ìâñxl6›à)«Ã%Í—¬V«`}¾zʱ<N0|„ú8 Îf3Àý~÷ë%GO¤êóR>¨Ô\àÅ9zÇÇÇh•‚®„!XÃä:£ÑˆæÍd2YZZúòåËþþ>r ð¨D?o6›±Ë‹f/Gr‚âÎáZÑFÀ[­–Éd‚óË(ñÇâ‡`NjŢÑhüøñãp8DmöââbooØËÑÑ%/QQöät:ÿê¯þÊh4ÒΩÕjèè‹ï€ÞétjµZ$Éd2½¡õüøã÷w÷øñcî¼âT¥R(‹²…\bThÅ6äp8@BªÏ µŽi:üY¹º€Rƒ"0•-”æQépÍcÚ‚Žñx<ñx¥â¥y(øõªM«ÅÓ¿½½•)äòKêÄ&#™LþZÌÑycûàÒÀ¿Èá¤h}ÿZ—è.ÊnZŠ?˜Ç/9N5‡œdS3‚7§sWãñX¤ÏÑhTãîüù¿Êà `,Ä 4ãÁ•••x<®SQ”¡}&“)ŸÏõÄZB}Ï£ÑHì†�ú k’ǤŸ&ŠïŠÇã°AÕA–àç*Š#¹>GO4ðD¯×ëÃá ÏPöl&Z­E¼Z­†BÁéé©xú···~¿?›ÍbÀ!×møÕb÷¡«×ë-‹>Ÿ/“ÉüÝßýÝù/ÿÅãñär90xôrÄIfÝf³Q\ZZBB ªM6›Å›•<>†û5²×ë½|ùòãÇÓé4þõ_ÿu6›¥`èñx˜�ÉdÒl6‹GLwšrkµZµÛí?~ñâE©TBAUð.8³†¯„JèÞ�J•qçƒÁ Ñh¶œáÏY“ü(ùãÑ(é‹<¼ŠN†bÀÿ“ð[.ð–Š­3‹M&“N§£©ŸÍKw®ñ¥¥%ˆÛ†¯�EýåÏKòf»„Ú@³ÙT¤M2Ùÿa§Ý"Ú ¿âu' ë/x8 Û›_åj·Û¤D³p©&u ›TÖ°ÝnÇmSñ®yMBá¹xR,~¯Â×’SÄh4‚d“MryéÁOWǯÃ8‘H„Ãál6+R|>1ºæËy‹ÅÔG ¬I(uâÐ‚ÅŒß µ×ëé'¬‰D‚p‰çâ+ Ê«K~”2V‚Ÿ ?fK4ØlTçeì¯0¨æ÷ÒU®V«|W6›¥ÅÈ„ááÌ ¤”9_Q¹yðòò2ÃÂ-•J!_„ûN¥RÉår� ÏÃ0 ‚P£NOOQO$ä.pÂìv{2™ùyqqAÐí÷ûIøööö °òc±:–ܹÈrðÕ%9::šN§F(µ×ë½ÿ¾ßﯬ¬`iŠv¿ß¯V«ÕjÕï÷3£L&/Ñ¡¹2™LþÇÿø;;;‡‡‡f³™ïE`#v4å²¶¶¶±±ñ÷ÿ÷+++¨ž«¯ëëk9ˆF¡¦Ò+¦Ó—Ëå'¨<á9ù Ã`0ˆ§¯ñxLÊÕn· …ǧhƒ ƒyåJ^’70Vv» JÆ_ážú°l¨sFÿüº›„û¢j‚}9¯AªxÞ‚4ÇK,æ;â‚ £é„«é5¥fÀÉw¥Iíï©¶ ½×áÄBÀŒ?sÁ€ ,vjvÅ„†'2~>EA©c_¸—i©p)ä9Rá ²ßñÊÊʼb/?pšâþ1÷“cmxÖ´š³Ù,ìZñÓàY ¿NR§\.—ÉdP«V«4ü ©íã-8fY,Ì8 à@Û„§‰DR©¡}·Û…ƒÜëõ�ÄC¥E‚Q$1ò`0�¢=N···±ÒËËËî¯$*TÞ™pfÉT¦Ói·Û=::ÂÞP«P˜ v»λðšyöì™Ýn‡ÕjÓUô5Æã1:~âló–›çD‡Óx<®T*`Á[ã3„@›X,Öëõ°HÎf³›››ÛÛÛ‘Häw¿û"Å‹o¬ŠåC¹õ^Vu ¢h©T¢ä Œû4[¼òtÒ\,‘Hd6›1Ÿ¡m,x§l«o�� �IDATÉL[f‚ö™¶†o *ÿ¿v-äçôë^2_Õjµ uB-›W†ÃaüLu y …B6›mµZbð.qzÁçP{2jZë¾²\ÕÿžËå…¸É|>/'UìÔ2V¾Ö××5ÉLêÙ ði0ÈÓšjDw9«S `b~¸¾m± Ô¥Ói½¹&JÁö¥Å"ÈÞOŸ>ít:´XÔïe”æÝ!ÌùIɤc¬ñxÌÂ~âñãLJãììLpºi„ÀK¥R¢—Ë#¾¸¸À­±ˆøoe@�rq«Õj·Û?ÿü³Ãá(—Ë·¿|úôi0ôù|µZMÎÏDù¡×ë¡îAÏétžœœÔjµáp¸¶¶f2™HŒ®¯¯IË>þ …þð‡?à¸Á ÊF '�–™L†4tmm 9Œ?Æb±ñxŒ©1<¼WWWØbqã„‹h,E×ÛÛÛíííJ¥‚H˜{¼ Mø¥³Ù T0$CEëE,Ów|X^^Vûb(ÄúÔ]ª RíÖÖyžÎnÆÎÀ„) êm $‹LÂÅ6ìN¢æºûÿ¯yÛÂB‡ÓÇåwâ(ú}&‡ V“ˆ£áF£‘ËåtB•Á` ¨Þ õ5QTÜ »§zsd‘\\\<yòDAi‚Ã+&7OO^„ý~mmM}>ÝIXs:¸îbC©ØúI22™ ى⽡PH°&Å¢ÿ-¯äõõõÑh$þ¢%˸Ûí®­­-rˆªo>“Ɉ}¡X,z<…Ï Í˜Éd²±±ÂBÿ5Í8høŸÇcr/,Ý�´Z-¸b¨ E×ÖÖÚív>Ÿw8èIÇãõõuìÔb±nê?¥RIк=t®““³ÙüáóÙ|yyùñãG,ƒ©ÑѰ¬V«lÙ‘Hd}}}:¢`2N‘8"w±Z­§§§ ni”¶ÛíP(„Ÿ>XOž<ùùçŸ …Âéé)ê´étl7yd©TÚßßç``(.//···_¾|éõzöÝÜÜ„B¡V«…¹»ðz7H¦Â$ÚðÕ yrÊÂøFÚívŒá™3Øa@/‹^˜L&zãõz}ggçòòò矆 ®éÛ"7lȹçñp‹n^`§&üýxóæ T?±•)Ü×Ä„á64°¥¥¥ËËKœšG£b¯Šª¦º‘¼x*s/eçy—Z"àÿÖ¥ÿ(çuÍÅ[ô'û¬wrr"§ºápX‡›"Ü`寋>ŸOM§5hñÑPá]„¥ôE‘…Ÿ£âsø—\.§®Sá“Ín¢yÚáªG?€Ë‚„«þƒ ®(¦‹-U³4A ¢U¡PøòåK0,•JTuäY �éüü\ó8ǘœÜNÀîg³™‚ºÛjµÖÖÖvvvðSЄiïO§SÎ'ý£TܹØÑäƒsŠyüÜV«¥¹þwÏjµf2ˆÖn·G‹Ö+ß¾¼¼|~~¾¾¾ÇcU|¬Íf#µªÕjf³¹X,>yò$Nã¥ttt$CcWVV„ww¯ƒ”L&].×ïÿ{«Õ Á9‰åSŽ7ž58TaNNN?~œËåX¤�g³Ùoû[<\.W>Ÿ¯×ë­VËb±,//Ó ‚þ$þ'''P˜›Í¦xù|u2™¬T*ÈôíïïÛl6àš•J¥T*õz½R©4€  Î6Å‚‡ãñX8áZ­V‡Ãá÷û™6F£Qc…®FY´¾–––Þ¿_©Tnnn>ï÷ûŠ9#[§‹±³æ~b¸‹q¯©œR¯×©ŽŠTH-Ëdܽ SIJ¥{W*•è?E£ÑZ­vvv&hÝ ‘Â\8áþYãDe?-®@  P6zÀu§DÀÿ•4hAõ�ùô§ÖÑûׯ_3ôx2ê׎].W.—Sl Ož<aåËÊFú—pÂŽ7-&ZÌCóRK¦²„ØzPÇ™õ,//ïìì0¸štÚ;ÄòEìŒà¦ü.¨$I¬pD*ce³Ù‰Ç-ýXbvÌßd—RÁŠÅaÈl6C£!W@}9‡ÃNâwQ¼s‘°Ã2¼pYÕ¢Tljƒ`_Íû™º –R}Æ!/qlp²v»]ÜŒêõz¿ßWø®²ã'‰Ñh´¼¼ìt:¿ÿþ{ 55…‘nÊôL9€ñF£Ñt:=<<ä92¤D'bKl‹ÅÊ`2™ ã@Z€jQ§Ó¡l{qqÁ?ºÝ¥³³³n·›ÉdVWWŽóùüÎÎVIf³Ùd2íïïçr¹J¥2ÅØb®JÎãñôûýL&S­VáÒ²;¾"›F£Q±Xäïïï‡B!æzÇDÑR©d±Xvvv(fÐ*S·ˆl6›Óéä´Ÿ&Ö¾<gÔØ[ù·ÛŠñ‚:�w®GM’¸(´È+Q³ÙœÍfÏÏÏA?‘Ö ‡Ãßþö·Ýn7B°Á8›ú*꼬~®&Ù_܆¼èØuõ—Ï_î²Ûí‡C_pàÎcR<”yfÜï9U*“ÉdµZqn¾¹¹1›Í.—K½ã#¨e2™HóÅ ÀÞûa¿ �O1 ‰¶?U/n¤ì»ªöå›ïõz(ñ¨GßëõÊî,šà MûvÅý£Ãwá(ÇÑX5Å}ÒJiö¦P¡§ÓéÙÙ™Ýn_^^^ZZÇÉd’ž<:%²¹8È+jPbÛèqssãp8²Ù,Ø Å ‡Ó£8™x¾˜äb‚.+ʃӮ`ÇÝuÌuFIv§‘ˆ1¨‚bâñx—Ë%ž£<gÄñttĈÅb>Ÿ †¤dggÇjµÊS”ÝúÑt:…“Ùd2A!â4Ç¢‹7’[ ‹d„;N,ƒÇ[° £1›Í2†œOÈàõ‡¢.í1|]Lòx<Åb±R©`{ˆ=j¢6bµZãñøp8$sâ“Eù‹ †cx0̃ãF"‡Ãq~~ŽL”ÅbAÒp4ù|>5 Q>5ÂE=giNÏf³\.ÇT¿ʵÀL01«5cSz l8©TŠR^¯×k·Ûü:”×c±X£Ñ Lê÷û«ÕªN×Ãh4&“IŽ1}N‹Ø‚@oQ7úvãÚû^@�…þoéY­Vb yfÜ?œ~þùç‹‹ ¿ßvvƃÄB=WÂá0Ýo¼ÅÉ!/{§Ó‰è<À .^rYì2ãñXLwüit 5X…jRijS”ÈЄ6¢~§JºBuÞmL§S„º···_¼xñèÑ#¬çæ­7DKåtÇ99óƒÅ‰˜)(GNáb[999á‰ÐXZZÅ:Rlõ=Pk’Çmv|^²ÛíŠ0r�ÜëÊív[­Vxøb”Ün7™œxŽÁ` …_FUœ <A!0Nâ%ÊbWWWp«ÑUÌ™p8̸Á+"V¨Õjn·ûúúº^¯×jµ—/_*ºë^¯—6U"‘è÷û|Èd2ñûýÀ7Ða÷G‹D8Xž3ˆÄ‚ÜÜÜ<~üØëõV«U ¼^/žÙ@1F,‘ëˆ�£)’0ÈX6›­ÑhÓƒÃ~:ÒƒäHŽˆŠÈOØøÎÛ€F£‘×ë…çÀ»8«¨Y)ÞÅLc&¨×‚˜3ápXÇ}Í`0D£ÑËËKñ{T:ÌkGŸŸã–2ï´S7(‚KÅ{Ïd2U*•p8̾÷ìÙ³‹‹‹ßþö·Ñhª�^ùs‘o#‰Ð˜ççgC½^'*µZ­rÀúæ‚ûõØëëëW)ï/­ˆx<¾ººŠJÊïÿ{õßƢέÌëõ±5;xIäþ‰D‚PåN:­æÖ¯£T¨¸=a°v/$q@�6—˱qÁOS[^Ê¥£ÑH3ß rSûŸŠÿÆÑª×ëÁEåñxœU;lŠç˱º8<اßÕn·5yŠ?3™LØ)^„ÇyŸ þ—ÐG¬vÅÃ’]³Ù,]§ÓI¦ÑhìîîÞÞÞ&“Iì.Ê2t¼êõ:®µT~ØËxÄòy špF£ mÖ‚˜ºÉd²V«¥Óiì'Ä?"¸€JŽÑhDjKæ£ÇX=yòu ¸·êéA FŽ,V]=#µíõzPtñ"ÑœµZMLiÙÙHó$“«¾‚’¥xéζ?êb›››…B5[¯×ÁmßP v-ÑyšN§ò94 4Ÿ?.02çõë×< šóV>dú±¬ÛísCÞâ3MÝO±X,.P=,©RÄÐ\>ŸïææFçŽeDXhþ+8ÝÍÍMÇãr¹VVVÔZ�w^f³Y“£ øUÁЯ¬!\n·{eeE-¡¾0a3Ìçü2 «Õª&^Cž@lõ¿N±zñùFǯR©ÐGÕ”%†Õ«Ž  ‚Â|âs¹”d£ÑåÐëõ†B¡T*õÓO?ýýßÿýúúº¨BF¡*("SÄ¢¹BCKö]•ñ3ü Dfjh†?÷›wxÿä½IocI–&J^^Îó,Ф$’’(Q’ÊŒ!322 U¨Eæ¢zQ@V¡·Ý±z]? —4Ð@íjÛè·¨m5ÐýõPÀU™Y‘‘žžár ®™”8ÏâL¾Å‡°¶0»×x9¸gÔ{¶xèòÞk×ìØ±sŽï| öÙh4¢º3é­œ6ŸÏÓH[ýí‹Kðá°§Òèl$Iƒî[8j³UZ«Õ Ôéé)4æËáp(V|²ÊãñàŒ**†ÎI%  ×ëEq#Z* nàÀÝÜÜ öussŠ —˵½½N§ÁŸ‹:Ite¯×ëõz=z´³³óýïLŠ"MgIÀ0Z]]u»ÝÀ̒€u‚©D(XM¤Íf³bÝÜE*.òK•7­ÄnÔ�«¢µD!ˆB쇈îh4ÊårÅb±×ëU*¯×‹"ÂOž<yúôi&“Y[[EÜÚÚ vn0Ö�b#p2f‚3úS°‘ÐÕ׈T(–æÑØéLuÄóñÿï„Ùè`bg2™H$‚óóT*5�Öh4Æb±‹‹ äûÒÖD*•:;;C©Jd3Q‚ÍÍM«ÕŠdÐz½NO9²oÕ ðŸÂÒ$鉳¢¯q¸ýúõkòþˆHQÄ7½]__¯V«Ïž=1¿ ª­+T …Bù|>ŒÇcÄîQu5Ífs2™ÜÝÝÝØØxxx@0ª¾v»Ý@ @; ÇÇÇX„dp¹\H¬b"±È#777>Ÿïòò’ˆ—–è„Ï绽½Çã¨8‡£:µYív»Àn·Û„f)•J]\\3åÈò®Õjäȼ*ˆÜâKA}‚ô¹ëëk‹Å21,<†¬7¤kâù�©ð3…ªá8=  m¿ß_.—×××ïîîpšõúõk”iµZ‘HLN(ún2™ …HÉöÄÑl6Ç···±ív{©T‚�øý~EªÕjH ‡Ã ‚¿¸!é<þ‘J¥Ó„È\Ñ<ÇâÈ &ŒÍÑÀ.ÿë_ÿ›·vm³H#o¡Á—¨âX¯×q`¡×ë­V+ŽñÀüÛï÷QsRqkAê)Sn謚] ñ»X¤ù]\czÚT™y—øÆE^ªc*D<{ö ŽíÎÎ@ìõzýÙ³gX{ŸH0z<á)ŽOÜn7á!ûÖÓ§O777#‘–ì;†ß¯×ë©™`ÀWBÎíEïɃ‘ßl63 \Þf¡ç›Í&ØKAD$IR«ÕZ__ì¼\.ó¶¹¹¹»»{~~ø'¢R Áƒ7P¯×!pg777¡ÔªÕêçŸÎØÂF£qccä¿ „ØÛÛC¤ l¿Š<ÓÁ`Ö(Øäðù$,H£ÑˆO�›W»ÝFíŸ×¯_ÃýÇ4†_Æ`dŽ÷Þ}÷]zõâÔ‡(€½ºÝîÎΔ }¯ÝnGYOØûŒý>qþ0Šã‘DP|ÊOÐ2ƒKøvžeÈÔ™ÅhàhŠP<Çãñf³¹»» ¦Á««+¼GÄ›››áp¸P($ Ìæææ&°Ãø4̵ÕjEFÏ;ï¼P-l¸­´À3;ÎêPI|¾Ú‚åÀkO¤ CK ¿ ¢  †ç3·ãñ88ëq YV¡Pèþþ’ÓÐb±�ÿ‹_üâË/¿D†êåó�|X¢4²“©0Schµ5žúð¯Ó:{îÏÝ\.×O~ò“ÐzZ5!âÅ‹‹ëëk½^o±XÊå²,Ë|º¤-#üÅ$ Q»íím¤±Fëììì¼zõªÛí~ï{ßC6çíí-aúÒ(Ü4,sÜÊçOóÑê½½=Eˆ.³~è.1 3†òÌLÀñCJ\15PQ½^Ïf³°Ç!Ö4K R“ARjdQ_\\”Ëe×0„¯®®†ÛíŽF£pUA Eë‘1Áƒæà\„•Ãáp½^'Ð]z(Pz�,yįõ�G˜åóy&­€£!' ÚaEàT ¯%³ #7‹!dƒÂAFHI%8kB%Œ ÈÖëõKb6›Á~„cÐïâ{­V+XM{ (Y‹3'TGð}ww7Ÿœœ Y–ÇÙÙÙÃÃă©¾áp8’ɤÏçCƳgÏ …ÂóçÏñ³P(´½½M2ø¡M|>ßááa2™D^¬�ª8yà¶¢Š´Z­[„%0D`†¤‰˜Ï„vvv˜‚/Šáp8D¹V«5+.¬û©;“J”èb”Ô ËåÝ0RÿQ”ÓT«Õ°™1¦’Ž#­æiµùø0¯hëa¦IípK I.68ãC;žj¼o·½½½¹ÿÎôòE²,g³Ùããc5êRµI¯×g2Ô&§ãñxooÏï÷ßßß‹E ÝßßW*I’šÍæŸýÙŸýøÇ?F̰¾p8¬Vmˆ€7 æW÷MÙf~.ùt ½^ïõz#‘ÒåIdœH›C#Ù©TŠ©ÈÇ£e±— |�ªïèÔ!ºÈN¦ÿ‹ÅÈQùd2ÙÙÙ9::B2ôÉÉ èˆnnn¾øâ‹ËËK˜´Ýnwss§&WWW¨•€Zœ<[,,­L&ä`ÑýÇØ"ÆBÎð˜_ú|>§Ó &_”T,ΚÙõ™Aà#æ±X Åô\§Ñh ‡Ã×N§CД»»»Dt±Y‚O¯×#2›Í‚ ž®ÅbA °>[ÚétR©ô»$IDæ‘q�W€gÏÏÏÉ„V«Õr¹|ssc6›kµÒĉÉçógggè^(}­ÎÿF6iƒÁ`6›¿þúëz½þË_þÒb± O«Õ¾òûßÿ1[l¢÷÷÷ Ï€ár||,>ØP ZòãgN÷ dõÑ£GˆÉ“žommñœ¶pâI�Y ³ðQ(¾�tSµL+üˆ ßÔ*Ñ£Ñh4G•@ ær9lTÈÅ’ÜÝ݉BSqûÄ0Gׂ«EËÉ Ó7ŠçEº<‚7¼Ë~xx¨©¶Þúú:­¸F#M›-n¨'FÇ µÄa£Åb …BÈ}²Ûí£Ñhmm ÅŠ<O8°ÿöööææFmÅbÈv¥-ðhÙ½½^/òzÕ2Ôy®¢)Çp¯)ÊœN£ÑH‡}“É$³å¿IÒ¾ÄØ7 X‚f±XVVV ß­Vk«Õ:::B¥$Y¼÷Þ{ÕjÕét¢Øh<GQdB%ÐK�'aò+vž¤k‚ã~AóçBf€)æŸø°Ú@‰¯Øëv»kµC“: îïïh¨"‘ šr¹Ì 4·¶¶Z­–Ùl†SЙâL&s{{ ÀÑhD£Ûí"äH» ú«×ë½^/™L …@ �dž‡£»üàÁ`kêöö¶X,†ÃáÁ`°ººzvv§‡I½ÝÛÛ#µ±”îîîîîîsqss#IR2™„PU«Õ““’ßó9Ä >ÿüóz½~rr‚Òæj’¦]Òªd4ñìsŠœ¶ÀO?÷–eR9" Z<<x¬Y–wvvö÷÷é³€9UüX:»Ý.@TÅbñææ&ŸÏ H‹ÅâÅÅ <jÜ™~|A·c|®ØR|Ë èluä¯j-üÊ ÇAy§T…˜­"Û lN.¸‡‡‡B¡Íf³Ù,¬’v»ýÙgŸÑY˜�ŠÒRN<3Ú"�ÚT �ÇŽúÕúøjµ Ì|³âóù¼^/¹)^ƒ¯ºoèÚ s C4…—€tARHžƒ¢AÃáP–åN§‹ÅÖÖÖ°¶#‘8úPÃëõr4 À¾ƒƒ„mA/‹` ̇‹Å"ò*A5„¯`Ô"W¤Ò‡"p;6 $n0ˆi½^/®�*†èj‡´`$“I8‘p€ÏçCedL „ÒÓ§OK¥R2™dÔJ>ŸD"È…¡@+ƽ@I!·ÛÝn·Ëå2êÝaÛŽÅb¡Pèúú`ûÁ``±X�šA’7ŠÎaÀm6ÛõõµÍf#²Ïç³&ºrccÃét¢Ô^4D‰à ­V+b‰Ñh´T*‹Å|>ÒG²,ãf³ÙŒÉZ ÀH[z*ù¥ªQc,¢1dYŽÅb›››|ðÁ`0@µõEú µe§Ó‰D•Á`àñxàÃ]]]!¦ ?€€v)ÚÓxà‚:Ø^õzûOmôÎM¢x(5[ž¥¸s[æCó›“&Š*<¦Oq—ìr¹|zzJ¶Ð^¯÷ùçŸÿö·¿ýÍo~CޏÀÊÊ Œ-,IîôÕÕ´÷Óï÷˲Œ»Æ[<CÍ bSzÕ}S…ØtD!ŽF£››«ÕŠú¶±X Ut*”—‘HœC™LgQOŸ>ý“?ù“>ø�I’$ÞssÐÏh4"$o(Ì£û†»݃DV9+”á¼Þ™HM¯"~¾...àxñš“É„ðÉ*®»Ý~vvV,¦Q¼ĵ4ó¯^¯___Gm †&µ\.C¹#ÝV‘Ó–™8z'¶Z­Èü†Ç†¼€b±Hè˜òTív;xÐ@‘;¶á½½½'Ož<yòÄl6?~ü8NÇãq$¦Ã\£wAÐbx///À$“e±Xp‰î¼Édr8t5 y1<ç2/ð(¦7•\õëžç>^¤!1‚‡ijãù²ù§Æ~ªÕªÇã‰D"©TJ–åt:í÷ûa –J%EdY>j\<gP¶¹YhAëdÁÍ µŽ9Á—H’+3‡ÕgÓßãv»3“?ÎòûýsÔ«@€Àâ Ð§YäèLK$”žþ¥!㙈IB4QiüÛF#ˆyhW,›Íç¨BYhT/$é!dFP™~Ò‹QÚÇï÷ollìïïÃ~Au£Ñ0 HtÖqÐi /qÈ´!HLÝ7 îdšpH�Á@?ƒd$Ý£¡»‘Í@»Ìà+è±¥ÑÙà`¥Et2™är9r—Çã!Uä Ò›|,¤rèõúH$BR«ƒÁ ²!˜Ó‡Ãú]ò.Œìb!’ñ|>†2ƒj@‘H$„ |xx899q¹\H#J¥RH7À ]–HÎx<é-ð¹^¯—Ð|0¦$ËJrü¦6põ*."PÉorŠ¿[§Óyùò%9�Äbé¥}˜Ù§G`2™œŸŸOU)Ä ‡Ã$µ jõ÷ÞÄ1•ØÇ¸¾¾ž\ňS¡Pà­�à.//—E1%1:‘qKAù|^–ed~¿g>W–)À›½^¯P(¸Ýn‚´-‹À‹¨yÄÀTñŸ›éƒn@�l˜H…�I@‚4"Uq›¤Á=ŠÒ eþPæÕ«W××פ 4`1.—kww%À­ P=RŸ‘ÐÆ/¾øgz‚a×ÒC @!Ë2òëp‚~„$——cf îÎÎÎáá¡ÀÐŽÇãˆÔcm»Ýn€4™¾ñØœJ¥€Û‡ƒH5>™ &©ˆÇZ­V0¨:d«Ò+¢ÕjiQ4™æóyÔ»3™L©TÊãñ …““§Ó¹¹¹ùôéÓ?ü0™LF£Q`Þ“É$hŸ@ä‡[­­†p¦h6›áöÑcËÀŸQšOmûØÎ½^9¤ò:}Ií¤Jmö—µ9}ùå—?ÿùÏó›ß\^^âê ½ºÄÝÉårçççX†Ú7)Á/.R"@K�†‡Ó.Øhlþ‚ 1vfÝ- ö­3§¯¾úJms‚IE€î¨XL¯ð96'h‚¤R< „§8%R‹5káü¦ô0¼= âñ8!j#„Ö‚ÅO·­­-8.Õ&\zRQoÁ7 ÃèKëëëÀa {eee0ììì N’ÓéD@e7¯¯¯ïïïkµÚóçÏQüŸ¶v1ìH±CÔO$ŒZ$V ‘Z0Ìf3j!*¢ÿ0P[[[–ç£Ñh€BÍ ¦ >ŸGhÓŠ�|¡åyFŒ�yc,B a É%2Ãpóâ‡×××ÉGM&ÔI!̳¡Phmm- îîî‚}£×ë dL¸\®óósÈÍ‘ ¨5N �–‚Ø!$ßåñxÀž§»ÇápX ƒ Qñ’`sR„-7¸GÎ âÒßB¸¡é)žC•3L¸Œ¼içž&ɺ# Y$s0çgÂ=3t˜áÐY ¦RL^©öpzòÈ|`Þ¨–{=Sú ÃUªØC¡ê¹ ƒ©I¨j¯S×ë)³�� �IDATK8$t¹\@¤ké'r%ภ,/ªd‚y\Íf‰ËívÒ.— |„ EØ0plC6N¾ÛðPùh;c*]= à·úý~ @'äyó2“H$jµš,Ë�ðC/+*&†™1­è‘ë`Ÿ¡þZ 3üü’½´Ùl‡‡‡²,;N`¨N ‡Ã0#�Ø@ C¡P( ÛÛÛ¨ÀDžŒ4H$ôoll Fm¡0l>$(2‡0°ç )©¸D€ÛSäÞèÎ4뻀f™/Ã{V}2_LìààÀçóMuÅÏ\4ðÑ,÷™¤ü›ڜPð7öyæ=ò÷••BxŠB¼Äœœ›êa ¢n¬V+O“Êýe„;˜»hòJI’2™ jîÁE%ˆT†+6‹ÑÈm5pM?Š€ê Èü¹Ь†JÆpÿ믿&?FŽ/VÔG}tttÔn·¬KlZ@J"…GIìJ¥‚Ã^PÕѰvþ[h./¨q%XØDŸ¨Šßï';"á)Üq°'Ä£&„8Ö"—ôzýþþ>f9 ‰ƒ@‘ó—ž>|;d†x0: iK6N¤tÓ]Bj%àÉxæx<¾¹¹¹¿¿Ç'“IdBb¬J¥ÒÕÕÕíí-€}HQã{ˆÍh-ÁH§Óô„À)LE†pàb$Ò$uOÞjÄ펎)fø¦iK‡‘.ü¼ÌA®Ê¯VÝ\$­ŠÛžX›idÂ-—Ëè¡Ïçóûýs$Ç/N¡[­V÷ööÄŒ}Š ƒÞY“É$á;…Ç#(‹]&‘HÐ2ÃoNú¿þ»ºÍ×ÌýráwÿÏßÿýß/åhÑl6ßEá™ù¬ØÌäV#¢² ³äÎìÖÖÖ«W¯Ô~àt:}>2m຺º"¦®Á``( ðÀl6ëõzÁ>×ívQ&•%Òøs½^ï÷ûÚÚÚ‚†zþüùÓ§Oó›ß Ð7"‘È`0ÀQ ­JønÌ=ûˆbÑs :L°™ìS•dôMícjª“‘4ÒCpiDSŽŽø{÷ööã »»»ggg›››ù|>¾xñòY.—ô£}úé§}ôÊ)ÝÞÞÆb±HÒO°‚°/¢â¸¢¹FÛí¶ÆÔj†%I((IõB£Ñèp8Ìf3öÚ¹-_à=§î78 Z:Ál6ooo{½ÞO>ùdñE ^y€Ûæî<2k åa=ÒFØ@bpO&±^E–ÿw„$WKûøãòïÿÿû×§íFõúåoþ¯ÿóo¾å9i¤¡4^3Fˆ–© Á¤ OgéEʳ/âÌŠ=tÔ§Í:zYºÝn8v !µÛí½^j~›ÅbLj8"šÝçóÑà3“ÉôÁà (.BŒ‹Å*•J2™4 𥶷· #·{<ŸÏ‡:``äœiPD�ÔŸ47˜‚\ðTœÍÌ�EQŒ˜Ù®Ôzˆ¤yàcÈ]‰DBPš‘4`˜Z­Ä)‘Hø|>ðpò{*­ h¬e·ÛÅ\ ›¦ÙlZ,T”@b´ËåÊçóµZ O¨vHâûûû ÈÄPñŒMuNãårÇ 7š­V«‘ñGŒEíÂáð¬åéPê¯Ó‚÷Äì#‡MÌ †R(Ý´ø"E4;“ɨÁH´tž!®eš×ëµX,‹$ª!Ž<&†ß™i⢈h„ŒûÍ©>zögjŠHð)a½ÛÛ[š9p¾†<øªSkCê ÀC€7p\J5IÅwÍgJ¨qhNµßÁ#x vé¾)º „ ßï‘.v\ðn¬¬¬@ƒ€(³V«1+¡×ë½~ýÚb±àQ²,»Ýîóós“É„&b°n·;“ɼûî»ñxü믿][·Û)8ÍŸ«q[2 °ÊQç?e0ÝSsXÖ××q4%ˆ ‘ªn|@› ½ŸöB£»FƒpA‘\*•€h¦y'“‰Ëåê÷û„ïÎår‘¤!ô\¨Ø™ìv»^¯GÕ;§Ói4³Ùì«W¯[H›/0ÏÏÏ‘gÖétÚl¶©º|êøD…Œ<.1LN ¦{VÛÎívCftßà=F£˜�`Íf2S­Vç@õª=P‚)†Ú«XËòs_Í´X,jÅk´C\kµÚ²†N­á@gŽ =ŸÏGfŸŒí.Þ¦Û!"6‡ãÑ£GV«˜Á¥¿ næ»°˜96'µTiþ¨Rsyy)IÒÎÎΣGöööÞyçÔIÓét———�Æ*ÂÜp‰  »X,3Kb@ˆB¡t:‡£Ñh"‘H¥RDq@\…£èEZEðšçr¹^¯wqq‰D�V—ZôcjÚ1¡zRk×××jöÚññ1 Õ%æ–™ñx|zzZ(رÛí[ •ÉW«U²1£9ÀÔ�«–J%»Ý¾»»»²²²¶¶†âƒáôô”јý~¬1’$¡ÐC§Óé¸,Ë<³2wðïF£= t­ýÉ%f©Ú´€p …  :Ù÷z½ŠÐT-ŒGºe£z/..€ö›é.šBŒ„Þ\꼎"#- bŠ Ü[£áH\œee¥Ó‚¡Vˆhj£g_ Z¥¥ôØï÷Ï· X²,¯®®F"‘d2©£°–so'LC%ì¹SqMÒb€]–_Ì@MœT3„¢×étÉdåÚ Â1Ø`C`Žè3R„¶x¹é÷û‹uáºÝî/~ñ ð—“%§ø:â€cG›xа3º š?>aÌØeáøæn؇?Y¯×õ•ËåVVVxJ¤p8 < À 4R©T2™t8wwwgggŸ~úéÃÃÃÎÎŽ@k á/Íf³(mÀœ„£î-Ðb±Ìªy§Î﬿ïv»´l/xnÿ&P½stI휉¨~-ùRúÜívµ#®iµÞŒF;€t¦^¯O=à_YY¡ËÇhW­:¦BÄÜmn.iƒˆz�û Ö’fµZ­â3@¬1JÙãñ sz¦BeðA�œù :”9ÒˆF£ŒÝ*ÞB1PDÕÀŒ‡üoÇS«Õ…P(ü<)Ym2™HYZÙÇc$½óÎ;_}õýE"8 tVÏÆÆÆåå%ˆ?øž¼~ýŸ) ªq+òûý¨~6‡€­®®–J%ía+&Aóõ‰{Nß5@£ÕjµšÍ¦Ûí~ýúu«Õ’e¹Ùlnll¨ †b˜ˆ¯«Ûívý~¿×ë½½½¥…®º\.þGmyîÔä;³—‡ollÜÝÝù|¾¥o6³îv³Ökàý´Z@ÕÞ%Å2YV·çH«côóÔøž¾mAÁX¤Ò¹ÄGóµ_ÚÚÚ¢ÿwŽh5¯ ^¼xñâÅ à´WWWív;8‹ÜhñCF¿ßO¥Rô^²f4ƒ*^ÆZç |EKt ›°îÒÝóx<Œ½ ’±X uhVVVÀ¦úî»ïZ,pK’$&äM$WWWƒ9Åb±X,Úíöt:͸³0»Á|~~žH$˜Oæw~ØÅçÆŒåN‹#3Š*LÜZ­ÖÜW­¥aFò=§ï!‘›wsssww‡´ÒW¯^-ª¯×먑J¥ƒÎX,FÏ>J "¹Fð´x<·@�)Ú¢Óé¶··-K&“yôèÑ“'OèK‚†Ñz½îõzƒÁ îßHc” 1=‰W=P™ÿÞ©YÚâ4 $8?wk·Ûý~cc¬Äˆ`)6‹Å‚\pënî ;çDJàL Î,‹“ <:0úšÍf¹\ÆÆÀà:µ9"=šé°2 áéT†J5ºA3Tîííñ¦¶I-ŸøÞljÄööv<¯Õj¯^½B½0B ÜÔKÆs ìr¹Ün·ÇãQä2€V¥õµßïW<ƒå‡]ü]ÌàÓâ´¸Ì(¦ƒƒ½pªá²xZ-AgÏzc·Û¨{ ò¹‰D¡PXÊ"ªÕj@àì쌖XN‹¥Ñn·§òÌ2wÑ.#¹«Ýn †õõuI’J¥R("–V«u§qÂrFuqžÞwªaMíììÐþ:WÃí –‰$I=J$=‹Ê‚¥Ö1)KIÌCÞN ;ßëx=Chµ§W%§ f¨÷Ð&öêê*B®ø½Éd§NX ‡öDû ûö&ÞE¯Hå+æcì3«+Òä=:ª¬ßC-§\÷÷÷DI)"œ´WX‡~¿?£èg¿ß·Z­ýF£ñ/ÿò/$Æ(V»¨Ùár¹Ö××ußpÆ#þ•±¹¹Éô°ÓéÆÝÝ]ìU…BA’$ÅùbF‰ ù;n4 »»»äêêêª×ë%jH-ÐG8¸¾¾îr¹¦{ý’;€Í}T)¸±Ýn3­UüñÞÞޱI dÆh4:==u:LM<>LÍÔ×·ÛíÛÛÛÌK»Ýîï~÷;&nCo'ºo* “+N3Å*•.¤„×=<<|òÉ'¿ûÝïvxuuÖh4nll\]]AœÔ,Œ7ǵºô†½üää„ Ûívz¼^¯à´5 ÑÒx<¾¸¸ˆÇãHkDBæ"Üßß_VVäS\)ƒ¯É„&Ë2”‰8ÒÀ±5ÅsÂî‚þíííÑ BBÊ<óloo#éàîî!ïH$22-Vâ…BÐÝÂô›#ËDÑrFóçšÍ橬ÕLŸ‡¹Ùl6a»¼¼h¿×ë×jµ©µ777I�D¢à韋Œa$"S<éÛH¬à9£dIy¿ßïóùÚíöÆÆ†^¯òäI&“!Eµ›Íæêêêd2 ÀÓ§OÉî‚b»Ùl–ïCO >Ytƒ™úÒLmêì3/J§Ó‘H„°ÓÒ—ŠÅ"úàp8666pàÄ<ªßï“ b~ÉvÈ]Ìåráp˜qà˜ï3$/™áp¥Ê岚åËsÚʲÌ? ’szzJl€Z/_ûº�èø»\Dޝ]‚"Q}8Çüw¡d>ªO1F@³ÙŒD"0F[­Ö"õX9‘BF(ãÈ¢>Ȭ3Z™hLpI+zNº¿þ»úøoþ×ú/ÿýg?ûYrˆ¨¢¬­Ç癵éõzÁYÅ‚Íd2)Úo³F:-ukk pZÔÜ{C/M§ÓËšÊ`0ˆTÃ>úè¯þê¯þöoÿö/ÿò/gzÂöööÔß ™åa¾kšËd2‰ --‹-˜3ÒĘÐâzò @Ý7¼«ô f_û<ªM®à„ãM4¾ã{ç«q¾¾¾îóùPJ-Úd2e2EÊd2ìììhÏ CÍáp¬®®jü±8„³ Jùøãÿç?}õþëÿøËÿüß~øïþc¡T‘ý øÝÃáDAh¹\N ì×(ŠùÊ’$ùý~þÒd29==U»‹4_Íá²Ì`RÜc曋ÅBßxzzÚï÷Ÿ={¶µµ…ýi>ñµÛí‚}·ÑhÌZ±ÙljÝ(‹ƒÁ •J™ÍfÐC ÚÒšGNÇÄLè•@"'¤Ôț۰gm.— 5Ÿìv»Æ¼,ÁeæööÎ=€pDèíÊëõŠƒ?²,“}Ôõs|”ÇãA±Á[ˆ²Âj³O.©Í£–È6­gÞB³X,Ð'ÀMk\à´ ºººr:�ý¨íÜý~ÿåË—Š©Òý~ÿÅ‹ÙlV»ÒИx¢QcqjµZ<B­E"ABÍÒó\6'�*5ê¬Yqj 2£Ñ˜N§Õ’@ *¾D‡±©ÑvËFÜsfÕɲ,þ"p¡âß É—–#AMbàŒôöö„@}5Ióó €ß™¶^ÁÓB¡P¯×;>>~ñâÅgŸ}FŽ"‡à.Ô>!O`®ú|>—ËE& $¤årùM”Ñî!Ñ–#Átkß/éO†Ìx½^ˆ“×ëD"Øí°'1he_…2ó€î.øD0F£ÑõõµÁ` }PƒÓªi†™0so¹Aœt:[¯×‹ ¾ a4½?nF€Ô™ºö§ÆÁ­6 ØSõ-¯ Õ&HñïàAV»ëèèH ‡3U¿œssúƒ´ápxuuÅœn¯×!4›MFm ÌLY–Õ28—ÄÇZ­|.AÚ*2ô%„‹€µÆ¸ýÉ•JeVð6ªüÍñíårùúúúêêêäääÿñŸ?Þh4šÍæÕÕ•ÀÕžŠ´½»»›za6›ç¶×œN笱/2ÂÓâCü/ :›n€îªÉ Î'p»ÝnÓ–“v@%h‹5ÊŒâß Ê‚‡{¿åf0è¨?T“eÙãñ´ÛmÆ}!<Èó5P]ÓB(Id#RÄoŒž!A-CMœ¦¦fvbAJˆ,Ëj¡oƒÁ@Hk5mNHú…8Yi>Ôj¦F£l6ËœìÑ \Å#GñnÇ÷­X,"@Ío biët:¤ M*iL¶.F øsq’ …ŒF#ý ‡C&+Æ`0¨9—ÄdÄE{HçAÖ}S\ñitÊM’KÔ4–à`†?Ñ%D×ó‰“F !¯ð“"aZGñçê(Ô¹$IH$mee…T·›Úˆ8ÝßßßÞÞ‡C|FæQ`ßÞÞÒŠ†dukY¿0¢§AѬ©V«Š …B|lœ¡IM$²,ÇãñYçH°T—Ûø</æª^¯GÉÊe½Ñjµ‚5†U>{ˆ¦Õ¦uZ 0ËÍÈGõι3SÖ0˜ÒÔÆVm±Hj¾$³VƒÁ à4L{®H-Å¿ …Bx—ßï_Vù"F£©¡U—fòÖ™Úødà:ñGæô—À~K u½^™ïñx¬–KV©TxpSquªl©p/ñíôôSL›Mõ&lp-âD¨´Z­ðVÔ¬±r¹ÌÛ˜8«H¥Rz½žù.xT$kV™Q<Z€`h|T§ÓѨÐ!Kȃn‚Ë¥Ì4 ’¯‚V*•F£ÑL¤DàÇ�-ÅC”%Òƒb±X*•hÕ<™L4>Ë¥FäÁþG-ÚÉ_̯ ®Äææ¦Ú+«þ““ÆR®V«-�"&¶�//Ï}&œL···Ý*IÒê= ÜC0G“5JçÎνk,¤h±Xž<y»;×××üQ |<«ùΙLF-Pf4÷÷÷™z‘Ú‹‹ ´¿Íf‡Vâñ8BŠBðzo™g‹n¨RȈS£Ñ€!âp8,Ë{ï½g6›4´�¿Í …N§ƒŠAÌŒ(òkl»»»GGG‹…üÃãTœÇ í=>ŸïÉ“'|¸ápýü;í4ïïïëtºp8¬V;®Z­jƒNs‰š}‰-•J=yòD(Âðrë=b؃Áà|qén· ¸Õ»D–êÞÞžî0fËÙ ætkƒoŠšP´9ñÒáp(°Ýf–Þ90ßÙlvÖ?ØÚÚóWîïïg³Ù?þã?~üø1 äՌզ¶i+b„ gh,#©)™L†NF¢A¸â¦×ëéR˜å*°m§U¼$ 4 Ïž=S ;H’Dð¹S×*ü `œq€Á”càÏÙl–ßxæC7ÏÝ$Izÿý÷ÿâ/þâG?úɼ½½EqZœ¶ôW¿úÕ?üÃ?Ày§Ù€ÀkáÖÃ?x8­â(Æ^¯×ívé³åëë뇇‡ýý}f�%Iº¹¹Ñ~²X­V_¼xAHoEküàà@¯×?<<Ã2Cµ{¬hzöÅjaY ;Ùµ«=H$wÑ’$éòòòÅ‹⯠K2 E"˜Y,vB@¬x꿨-5P<ÚL³¯Ö\.×áá!Œûd2‰Ýz¦Õj]]]F#ºÃá’Ñh4î¬F£ñðð·ütªfª \³Ù¼»ÛíB}O&ùÔxo<7™L777t)I¡P£Ýµd2yqq1™Lêõ:©sšN§™  Á$2X¿`0ÈWGu8à“m4ÄV* óo‡Ã!]|h}}\æ�šÍfdkÅK€Ô1¤Aj %¶H¾×ëñN7ÉD‡Â"_A3¤@í|ÀX^Êùñ—e9‘HƒÁN§óúõkÆT"¿·X,¨ÄJüd2ÙÚÚ:::¢¥”DZJ’ ].W·Û5™LãñÿE¡÷Ñh$Ë2ÍÕép8‰D¥R‘e¹Ñh0b¦×ëM&“×ëEnþ˜Ïç‘ÑG/=ô‘@Ý793ÉpÖŒ_¨Óél6["‘(•JÍfÓãñd2™`0X*•Ô*·òò¬†žµ¡B‰ƒŠS‹ ¢Ã˸Ëd2aRˆª™éزÝn»\.¶/Ø™vvvF£Q0¬×ë ØŸ]"3;;; Á<8ÕÞ%Xí*·×ëÝÝÝu:I’ÀûL?y2™à6ÿ^픓ɤR©(.rÔ7½|‘N§K$V«‘(Ö,([€¿hÿ}¯×ƒ±‹Å`MX,ÞðÇgggv»ýìì¬Ùl’|õêÓgŸÏ‡#1ò@²½ñ§ °Ý[º{yy %%Iž W›˜Q‚RŒ£ÑHcÃLq8žÚò.—ËEŸ‘Ð}h6›Ì®öòåË™Æ ÉŠ|–H—ËU«Õ¾úê«Z­öððÀ¬I³ÙL² ÖÖÖŒF#:|õê£X‰ÌÐÛ¿ÉdÊår>Ÿ/™LZ­Ö�Hñ@·ÛMxŒÇûï¿rr‡V“ɉDƒ³O€Ç » c31OÈf³sœÇÜÞÞŠmR˜%ÔÈ]Ÿ~úéoû[yÄf `R“~5›Í3­ z½>wº6Óúý> â•ÎmÎårZŽ… \.W.—³X,jwÑ2sttÄlº¹\NmŠ-‹ G@CÅKÀY3â„$ÅæóùYë¸+*q¡m­a=€pÅ›êÔ§@¥ZT›¿$IZž#1 œ‚¡jX¶ËËK°>3«‚_,HÞ¦ž£ÙíöÅ7ìÑhôúõk²ïŠ1RN§S–åÓÓS)$ �*Õ®"M–ŽL­“wU«UÚ¢#ŸV«uÁ€¸b:L.—#cÒ*• ,ú\.çp8˜Å‘é!dFà™A–ˆÌ€r…¡Õjm4777(>äv»_¾|™ÍfNg¹\îv»@ ¿ûî»^¯—[Æ¥Fm*&dª×ëWVV~úÓŸ¾ÿþûô½@`¦ l™©?“e™Ù‘YÏCpÀ7„{ww+“6\.ا>P\@}j|ªâZVÍ«ÕÊ Þ€<‹F£ :Ôºøw¹\ž/QÈápŒÈÛÛ[gþîõz=z”ÉdéÅ…ÜŠEÅçú`I¹1„;µø¼ ºP %5"‘‘¬ñ”Þ%m \^^ ‹Á²˜›öØý3ˆšÍf½^¯𮊟c³ÙVS‚š Rñ®p8Üëõ´CÄÉ»Ä?€êŸ—ºÝnñbP£»EMÑáò—N]Áú×nK’Äô t·Pv^¯×ãñx<žt:}xxxoµZ‘±†» ?øàƒþð‡Ñh4Nw:äå_¤¨ ïïï;N,‹ÇãÛÛÛD½^^^¢�£F•­Ef»AÍÌf3Ðo­1#xwwG»†ív»P(T*-°M@”ÌgkT\Îü*6 ¨àÌïd¼)&ƹ3¦I©TŸå[­VÞšLþøÇ?æý˜b±¨ø@‡Ã¡ÅÊt:ÌëÜn7-Zj/šAŨÕj¡PH»+­qó‡L:ÙÔÀ÷¿¹æõzùpq›ºPµÕÀVz;ߨ&±X —¬V«ÇãY<)Ÿh¤ ÂÕP ¿ßqqµjÒëõ«««(OËFvn€©‡ÃáöööÞÞžÏçÇ|g Ü€$I{{{ÿüÏÿ ãÃëõöûý©k7778ÖªV«ívÛétZ­Öf³9kÙiÇ{ý~Ÿùí+T£AmµZ‘Ö¸,1ÓØ¦²",Þ@¯âÕÕÕûû{ìñ ˜Z§Ó©·—Û盥vÎ-- 6 Ä–Û" C¿ß—$©Óéhôœ–ÞÂá°¸l;Óƒ“¨&Ðãñ˜Ž\u»Ý••š*µæË„A‚À¤Ä2ÿ]Sc˜ËÍî•e@&›±¨›d¨­‡Lt:Í'¹ƒB¡€8I«ÕÂ^ƒx#ÒÑh¸éõõuÅ U’¤t:Ýl6‡Á`øÑ~ôôéÓp8l0ž?n±XŒtpVU*•h4Z©T~þóŸßÝÝ ‡C£Ò¹mÈãRÜr&“Éùù9*ë µ‡dÃ2S¼²²ÂðYhi‘HDã]ÀkGõBœìv»×ëÅ¿‘ÓD£éßfãÕÂÛiDư;jé”-ÿ÷•••¥€/É€@ _½z¥PEÏþÆÆÓ“`0(Ër«Õâ;ÏPëb(hÇãäFM ÈÅZJ;£Ô²ùKÚÉú–ÒªÕ*ÃXÃ{¸&“i}}}*y¥�iK&ø^ ý 5"3ý~¿ÕjÑÀmAÉê©…ç‘ñHÃÀ{ï½÷øñc&º»ººÚét`3~I+‚«Õ*Ê@”Ëe›ÍÆWa™L&8>Y]]…f×ëõP|~¿¿\.#¤S«Õ0û···/_¾<;;££Ç´`H’„u΋RO¡ôz}§Óa0Ýtà—þ‹�5IZ­V[.x“×JÄh4“ëh·ãí³,· o† {ŽV¯×—¢ Ýnw(ªT*×××_ùR,�� �IDAT~ùåååål<ëi³Ù,‹Z ›u!6Oß^m½Édr¯6"Œ8.‚dTk©TJ-èIoà)Þ_„ÑÑjµ´oÛŠ'=¹\N vwwdcZ&“Yî§6¤ ë¾ Ü­g2µ«�ªt|ŒþîîŽ&;æ3;p›™ýëëëñx Z>RG6 À�îîî>ÿüó/¾øy›››{{{±XŒÎ_øä“OÆéé©ÇãÁ Ü&8kZœ677ì÷û`D›üét:dyÛíöƒƒ@#£Ñ¨b"à´ô]jí½÷Þ›[�†Ãá"á–b±ˆPÿß³ÞÈkoZ&KKkµZF£1 L÷LÙ.ä!Ì_H0c¦‹ÅÜn7ø»g ë‘vppÀ,Ôq”HpRì2ôëXJÀl6§R):¦ 3Q×ùž9p$®f 11nÅiFü7¢˜a·Ûe€ŠÍår‰Ç%Ibøì™¦X}'•JiÕÐwv]‹‰¤×ëG£^½»»«Æ¯S/QÈwýú׿¶ÙlñxÎÀFø=j=ð' ØføžÐÑ6º3˜)I’2™L½^÷ù|ˆ¶¡¼æ'Ÿ|’Íf766R©ÔÚÚšÉdr¹\ N§Ó/_¾Ä×ÙÙ™^¯§ åž<yâv»I¥GÈ ©ó$IÒp8äL[B©TB¾F>Ÿïv»cdµZA¢øðð ±ÌÁýý=#6´Ì,k‘ªE§ÉP¼Í@œâe2²$J[¤.>CU³Du§£ ÊŠÆèd2Aâjíïï«áÕ[2™d4†ø</‰X­Vµ“ âÉÈCPù°žhsâMÈD"Ao•È¥s{¦.'µ™ÀßÝn·ßï_J›ÑhÄè&¼‚°¸ê¾€ÓnȺ …l6ÛÔÃ*m×h4 ¹xNUŰ V¸‹fÂÕ8àjE<ŨIæ.fö™ís*j’Ài‹“¾d2™vwwÛív±X¬×ë¯_¿6™LN‡„éâñ8!ægŸl6ÛÛÛji÷<n2™ìt:Î ‡Ã››£Ñèr¹ŽÛív¥R9<<4›ÍápØn·_]]}ñÅ8k)‹ãñ•:ý~ ¨ÕjyO„0 ¹ÝnTg@¼W­‡SÛ¨¡Ùl6Aå‰D H[—eY» ÎO ™}Y–³oÖm€f4žIK¼¹FÓ13néÌ`0`B,ºoÀÔŠ‹ÌOz7J$ív›üØëõz½^^Ÿ(²ÓNmN§ E± "˜î™Îk ŸÏçñxÔ2Åø\z~=zär¹™pµzBÀÍŸŸÓ–—Íf£EÑhtÁ¼Ìz½®˜Ie0h7ßf³ÁF˜#6MoÀ4n)­P(hÉ’âÑv´ ¥f¨},ø gšGµ«@@Kþ.öl6©8ÎÏãÔT+E8­Z3;;;étóIcpÇZ�•ãñøèèH°ëŸ‘ÿµZ­WWWÝnW’$‚´-‹_}õUµZ}ýúu¯×ûì³Ït:Ýñññëׯ6áK¢ÄÁ`,˲lµZ±m$“I‹ÅÇ'“‰Z‘*ÜžÚºÝ.ÊÛÍ(˜¬9¢vsó ê8àöÜM@A;_Ôkêoìv;9D„ o™“,ªQÐÌÐ_1rkµZç(Úl6¯¯¯5ª Å[¥R¹»»³X,$ºN³'koÏŸ?W'­›“"n®ÙlÒæÆùùùrÆF#½‹�Þ¨×ëg¥:ä£F(ºBxÊwI°s¨í[ÚW»ÝnDóïîî´¸­ƒÁçó¡ÄÜ b&be³Ùl±X …n¤½~ýzªm!¦H¶Ûí}ír¹ˆ{wwwG »ä.¯×;ñ‹_T*•|>uu¥4#HÛl6 sÒï÷…Dj£ÑxùòåÃÃÃÙÙcµÐ=ôx<D<„§V«u4ÜMŒEÄc™Ý‘èPb÷h„îòç1ØàSµ'JMÝœæØäÔnѲÝ6 ’Ÿ F£‘ZÚ[·ÛXBjj‰Ž´ƒÙlž©Úï›P_DfœN'‘O5°ÿÜ}к9iÄÍ Ìd5ÙF£b±F± :m?›Íâ E\gè»Üá)ÓÎ`˜Š—PT÷ )ƒ€#mŽ£&EÛùææjw¦¬NÀ}æ3lOOO¿þúëñxL/†©ÇæŠÐHÀiuÓ~óù<Ùlè™L&Ü2\¯×{vv62 ³y@%A2úýþH$‚êGN'ŸÏ‹1Ý&“).T"ÂS“ÉT«ÕÎÎÎjµÚx<F6 ŒEõAÓÝj„î*@ >_SÃY3B8+JmÑ1¯fÓŠÙ¹PAz½^ ¶ÔåriIñÐëõS&˲ötßÅkÙ(‚p‰Ì‹EGQûÏÛò–²õ4ž+,ò›?TãÉ+µ4BxÊ ý;ß]âÆGB¡Ðr“àgz`µZeÜJ-˜nž"™nHþÖ"~˜,P—ŽF#Ü•ËåÆã1ñ:Ž`ß%³‡eY¾¹¹!³ïr¹hmÈ {µZ%±ûëëkr—€ð´^¯7›Í`0¸¶¶FêÝäI’$\¢ýEBw‡»Ýn¯×cÊh¡Ö½¿¿_"¶¯P(,I‚Âq ×ê”Ø“‡Ã!S€j‘¦¦hÁàQ½´ŸÍ!Ù¿ív»F–-m&Šäl6«1ý‡Ùœ˜#ñ@ @‚ªXá‚{Õ·¿#m2™,^¸^ÍÚš#n Rš¡�ì Ú óZ[€êÕxž>-l' pÕápÌʈCû ³ºŒ­V‹¡.EªÙl’,äÒ$¹ívã™Ífs¹\¡P —ƒJî–vš •i+++[[[p¡L&½©t»Ý««+Q–v4!‰f4mllÀ×±ÙlpœN§ÉdŠÇãÌë´{Û`Ugœéííí7T»Äb±¨1|k]þ—Œ5Cï=ÀÌÑUšâ`¾¦ÅŠÜ[í¦ueeÅb±h‡¬´Z-µWû|>gö½^OP™ZUœH¶ž±WsÌ[Pè£Ñ¨ßï¿…lQœ¾ªmøý~›Í¶8‡Ø*¢1 ÅŽZ‹ÇãbuZ:gZW䣼^¯Óé|xx`èç™Í‰ÑÚEVíkkk Â\0JÃáÐçóF1™LüzE£QL-·j<  —zmm1«Iå¢,ðh½~¿?“4¢?kkkHþ¤§"Os8n·;ŸÏcéaÐÐÜèñxÀ³< Æd2±X,™LÆf³iDYª‰*¯ã«N§ßàM0…Y{¦Vր̬¯¯«affjð³±ßh‘m^ùKø_¦ ΙÆñÔ®  Øjµ¦êQ¶^³Ù$Ví›3và6Åãñ·S©Ýn ¼®z½®±.ˆ� ަ.]VãùxaBF‹ÔÎmv4©•N...fÒª+++b§ðþþž”Çžª/€ÓŽ@F¥RI¯×÷}gg‡?kÝ­NºK{¥Š,j¼Ú"q€Nh;`0€¶˜—4žîÖçóÁcèt:F‡‘4ÃÝ?~œN§è‚Î:Š”¬µZ Ù}„=¹ßïçóù™Ž énMÌ¿0U0˜‘s4Om H^Ö‚]]] NçææF££ …‰y•JeY9-3¨?Æ)Fàg*áH—(Sûg³Y€ö樔ö¿='˰v}}ÃL„òü#í¼/b`%Ð_ÓeQ¶Ð=#Á‰®åŠPVZ?Öëõ¹ÇdjyJµÖl6»Ýî÷¿ÿ}Ç |îR,�ñB0úU»Ñ ÞÌF£_ÝduuØ&Å©ÔÞ§Ó‹Åh"ÑJ¥Â#y&¨ÒøçïííÁÕ¨Õj>ŸAh’ˆ€–ð, ÃÁÁA,óz½¸ ŒT»ÝÞÝÝm6›ù|žyP“ŒS‹žcð‡ÃáÓ§OQZÉl6£îyoµZ …B(ó/i~�¯¦=�I’ö÷÷!2;;;4º€PÑ}¸•š¡[Z­3¿v»}mmMÑ<¬;øÖf³¹àá–Õj=88€ÂDÌ|2™h?~Ãi¥Z?g’ê©/bö9Fªc˜;ŒqâÇ\ãP¸ÝîŸþô§ÁµmeÏ Œ8×××2fS …B$ ‡¹4Ÿ² ‡Ãäìn<úé§ôoŒF£ZºŽÑhT¬Ï,•¥GØüâúA:@0Ôh-†Id:v¹\‹…Iº¹¹óz˜Í楔5¢c&˜ºêø!Íår3> �0™Lä{Ž û ž>‹Åeæï_ý5Ö¬~ŽÇc»ÝÇA²·»»ûçþç«««_}õ¡^ÌçóÈÈ7™LV«•é `Ñtç1z~¿ßï÷¯­­!ëÙ³g_~ùå—_~y{{»¾¾‹Å Ãîî®Ùl–$é÷¿ÿý|ËØ%©TJ ƒõêÕ+zõù|¡PÊdª•Ñu:«««¼`´ÛmµŠ×³‰Ð¥ª5Y–t]Pûw:gÏž ¤šBE‡ËS<+©Ä‚+Ž=E!î<ó(Y–ç¨×G‚X|êµjB«b]Ýßß½À’˜¯ÝÝÝ ²ƒÁ Zb0L$Pëj@¼¥ôðM7 , ¥RÉf³M ¡H’ÄdR¹\®~¿Fg=oo´^¯ŸÈÌ„AhÁXÐÙ]<í•i4j2‰ÌÀv»}uue2™´s£–¢¹€TT‚XÙív'‰µµ5«ÕÚëõ˜1_YYÙÛÛ3›Í<¬Âï÷ÛíöH$ÂèÈ !VÖ}Ãä¹½½N§ãñx$éõz@àý÷ß_ÒüôôT£ö,—ËÚ©7à`5B¡°˜°N§{xxPJbá,1{M,„>ŸO¸¶X,ÂÆó«ĵ‹t@’¤¹W–Óéôz½¤óâèp8<>>^âÐM飯[&Δ¼ÌåräªÁ` Åùµ4¯×»”ƒJíq^lÀf³™ cdYFm—ËU¯×q©Ýnƒk\ìF£óós&*íóùÎÎÎfåû¹¸¸ 8S\{Yõ¥x‡Øív/1©ÃDEÂ.ö1"€ÃL&Ž|:991Ä °ÛíH‹òz½FDÆ$}C10¸·Á`¸¾¾Öëõ€ý‘PÕõõ5 °¯Cÿ-¤;Ïï‘Ñhôðð¤ƒÇb±ûûû?üÐívK’ôÅ_ð)õ’$Aê𿇣ßï‹Ã\˜}Y–m6›Z޾Éd2™L*PÏ cEÍ%¼éPÄj’l³Ù–Èà³tÖµÖh4F ×¥„|òX`·Û]¯×;3€D§«xYöx<ó­¬n·Ûï÷N'Šx!™eý)˜}Ѷ:õ¨f¶ø$‰™& í®¥ ƒ™Nª¦Æ—Ûˆó'Ër0 ›››}ôÑÁÁ$I’$år9Y–a•R×t:] P4 yÆZÚh4œV{¤s·n·;S%Jσ_žÓ–™”Z­V­VM&V ŸÀí‹E¢�LH«Õ:™LnnnPÇÆÒ hÍf³ÙlŸŸ#oMÍÔUì¹ ì£×ëÝn÷ÎÎN,“e¥[°¡Â²X,HP¤ã±²,Ó©&“) ò>Í„‹ÙWc5Å â¤"®‡µ 1Řn‚}þN5†V[­•J%˜t<§­šê�  ÌÈ:ÊJäVKÀ­×둊mwwÀ/!ÉÔÈŒn^îr&Ûï÷+<öx<€†è4�iß‚Có(éF#þP‘emmmww×f³U«UØJÝ>µÁ!F¿#kÕ`0„B!~›!$¹‹4Zœ¦Ž•b²,OBª×ë“Éäd2áîà*D%r’ár¹ z0p¹×ëEvÃêê*ŸÚpyy E¬¥¢²À@)&¬®®*Ža4Íår777www.— )|è’ÃáÈçóý~¿T*ñ "‰”J¥P(„×U*¯×‰Dr¹œ¢DE"‘B¡€dtÅâ{évص‹£_aLè¾{mV­5·–cP#U ýÒY_mµZÍf³– ýÊÊJ©Th¡ùf_ä91U MÕ”†ï‰ëàiË�*×ÖÖp"7Àø­5ÿÈàp8|xxH&“ßûÞ÷‰D<ßßߟÉòù|j†R¹\Ö’c·ÛµT“ŒD"‹œÊªA’{°v1Ó‚-‹j§`Ī#)È' ><<äóyFÒ�VE!êb±—Á` ×ëaÂ7›M°ãÐ=Ä%wñ“…€ÏÓét’€—Cl!äï¨A~uuuqqqttDÀU———¹\ÙÛN‡®QY(Æíí-(C|’ñà p©hŠ}øDmÏZûM·9€ÛbÅ¥Xæ]æ\Ð`a,¥‡41­‚:[cØP§Dã«ì?çæ¤=šçr¹ëÐ�¹9Sl‡A�F£n·»¬ýI@ɪÖ677¡Ôìv»â&4‰!³²²B,âJ¥‚St‹Å45’²Ô†KÐCºÂô|æ'Û§ü 5ÖÄÇŠÐ1¡'3†$wVq¢} »ÝNx<ûý>éd6›}öì¢O‰D‚+!ù›9¤ÄÉòŠÅ¢Ïç£#cív; ÚíöZ­–N§üS,cަiGê¼` È¥v»M»Õj•GýêW¿:::"Í<Éà4-N§8'E!$Éâ‹…9º_Vù"-’–L&µÄ÷\.—ZýFÏГ»D;pbgkÇo©é™™Ú܌ۥRÉ`0¤R©Á` ñ4Z‘#MÑ&˜©Ò›ˆÏIûaÎÍæöX÷öö ¡˜´$j—ñL*Ú2Ó`! ¨+z@>ß ÕÉ@†¢ß~O½^G¡ëóóó““¢aX ønll´Z­£@Ìñ. 0öÛÛÛS¹¬¦ö]étºV«5›Íŵ䓼5 XZÁÎWßaвÀÇ�)’\ÚŠÄ¥V«Å_B ;=)äÌ%¦e2™Z­öèÑ#ì²ÌTf2™—/_¢ çh4ŠÅbåFXq0}>_:F™8L´`™ìííq‘þ_‚aeeÅl6ÏŠ›!’Fk·Û É&Š -’¬¸Zk8ÊŠÚiŽ(Q ¨m¨qá¨é~ûáË)eòðð0_¥%H/Í;5_‹Åbz½ž¶&3¢Sª!Úœ´:_’4. ÆíŠ!®ºi8Щ&!åGœTù|>¿ßOÃh4Bÿ'“‰Çã[„`� Â׵ÛmY–kµÚÕÕÕd29>>îõzäð’D‹¦îÛ(B†©#f¸ò˜4¾Ìd‘)[]]%É6ÕjU£È2(Hª¬ýï"¯ ‡Ãn·åa•'~&ÈŸ˜ nŠ™Œy¯×›šÌ9#‘ˆ$Ixàp8d„¬µK{{{´À./„>Ÿü=‰äóy€¢è¦Óéõõu ®È«›Í&Q âÅ…Y9=öü˜Ÿe„Kâô%’Šf³Ù€™UÃY‹'‹Ñ$è|¿ß§…V£ ”†^¯+“› x =€¸E’$ƒÁ0O)fG BçPw´Z «•(“¹·–ýý}qÁ*í�gÅC_µùÍI÷×÷OÿÍÿúOÿå¿ÿìg?“eyŽœú•••©0Ìt:ýÌ´¡=n"¦’$ñîp&“™5øøñcAÙÿ©t:<èáÎÚ4BêPKtÖOfšßïWÌs»ÝëëësC PK¨£ëë¾ÉS`ƒcõx<‹GNè¹ÐWÔhðAé¢Gâ™}úôé£GfY–Óéô[^nŒ`,rÀ©¸Tµ4·Ûýøñãh4šH$f*_„Zïûûû~øá‡~ èâc²¾¾>o*=ûK/; h6›m¾×¹\.`ÚÛÇü?ÿé«ÿð_ÿÇ_þçÿöÃ÷ ¥Ê·´§×ëšn¨S‚aNÍaÏf³ØÉßÖ’H¹@;�`¤xéúúÚáp{- XJðüÛÙÙÙóçÏyó‡ mÅ”$‰&G±Ùl.— Þ˜@¥2cË£zN§Mwzz: fýdÞÞT¤¨×ëFƒéÀÔF£Q°ÔK¥’7A©T¢ÜÀÊÊ ­ÈjµZ6›Ë ¢ÿ’$©A•=#ñt-•2ð@r¬B>™ž,I’�%²Ù,êG §Ó‰RIÀ§k__j¨If‹Ù“éïšC0±ÌfóŒ±ÂçÏŸ£F>H ³‹Å¢ËåÚÝݽ½½ýÕ¯~5—rFuuuµH ½Ñh¤V¹ãM4µ*޼BfTn£Ñ˜ ¸ò-yšZñŒØ>Ì_‡X|½^/dìŸK# Oèå!Pm„ÕTM8ÈÄÃÃÃÔÄG1ƒªØv�áÆÐh4*nÀÍÊK—Ë …°c1 \: „»hóùäZ­öv(œ§ÆëJ¥-3F£q?•JM]êS%MG:„ 2¸\®ƒƒƒD"¡†!ƒƒÅp.[­V’“ýúõkbr "ðŠpÇc0ÈA½Ûí†z¥sd�}£SÞ½^¯ ¤©O¥Rù|ë ’Fï—€:M¤/Ò§Ù“}>Ÿ¢ÿêóù4nNLÛµ’$ Ì©N§S(æö9Ï««Õª6PV«µ^¯_^^Úl6T?:;;Óýÿ¬u»]ERAÞÄY°ÞÇ·äIL JÃ4›ÍâxàÍÍ <§n·«½® ³óUXhèF¹\œ¦€ÕTçõzÕ‘G¥Ûj¾š"÷÷÷Ýn—(8®H·~¿ ©Ã{vv&>F]Z£ÝÝݽåºâÉËŒÝnƒ‚´Ûí‡iuKé¤Ùlöx<ñxœXN:Š$—xü ˜ H¦©H[^2™‚¢WJ°–˜}Æ<º½½‡Ýn—Å0™L` &¯&lºoØ“‰;x{{‹ƒ ’>Èw)n777óe“Š1ÝSËÍÍD «q!×ëuµœIY–ëõúçŸ~4Š"DW-À¸`q)è4Xà·Ùh’\zÅ͹9!mi¾Îâ¬HS_5Y;¨6 |§âcÕÎèÔþNó“ÎÔ@BšËåHª³YF£Qò—V«¥xȨ3ŸÏ'6“#‘Y–V«u&Éfü¿ß¿¾¾>«Ž ef8ýþ÷¿Šb.Êå2¿ã‚–^£·Mâ¢Åbñ‹/¾xõêÕõõ5Ã(xªÑЦ½bvl.—›zbl±X¬V«4åÊÊÊúúº ²�P½ôK¥ã)2 èŠr ‘Ѿ±±üóÙl–y,HÑtJÔɼÀ(JšàÆÑh$¶e¦ž)øý~ÆV°Ùl0ûÅIб²–ÊÅZ4ɬÏ!Nÿúú:Â*“ɹù"œ¼vÿÆ`0@àÇÅ gúØ·Ä„»_b‡ÕÔ®à�•ЏZ­¦–ÍÌ_¢Q“ó}E³Øè¨…À“ðù|á˜ÊÔG*G£Q¯×ÓÎkÉDn·›É/êv»°µC¡©Ì+˲âi^¯_[[»»»«é‡‡5ËI`™*>‡^iFƒh[¬p^ƒ `ÂãñøòòÒjµnmm© #3„g¤Z­2ÁXµøÕT«q8ÞÝÝ1Àf Ö’–4¤íF#TZêõz<j™}—Ë•H$¶¶¶4r‹Åbá£ús0ýèõú™J0kA^:Ø¿R©ÜÝÝMͩܛð Oµu46 `Q¡¶ïmÓÞ¡ÆÜF;©í.XAàÆ¤×ÈÔ²LŠâôÚœ¬V« aƒ8ª‚åÚh4ÔöÁ%1OëÆÆc2€’€W‚s”=µÛí™L‘úf³É�¹ˆÒB³Z­B›8Hy<»Ý.ðÞÚív¿ßßÛÛSshü~¿Á`�Ö²ß™~`&“I&“jŽ#ã%€€@§Ó=}ú”¾DgšÐ˜DFܧž„¹\®L&¿¾¾Î„z*•Šâ\.CF~#Ú¦µ–Ëe§ekuuuŒ´™L†ßàÈg©T²³Ï ;‘zöëõ:êÆÌ${‚ýž@’Ï Ær¹¬Æ ‰DhÁ¸»»»¹¹ÉçóAÒ ýS¼êt:5r®ëtº­­-í§§üÚ�‘÷ÒèÙp[Ç!ÁéK’$‰I"h¸·¢ž™¯u:r¹ H“îÐ6¹@ À(.ºDÀT¿pjlvssP¯×£åVcå‹ÙJþ6'I’‚Á ØB™/£}‘†<cš„”h[¦ó3¥ #ÅU2§æ1VâwƒÁ©{|"‘ðù|ûûûÄ¢ñûýdýã“KÅb±hÔá„CÇµà£æ�¤R)úQƒŒ!I 7™LbÕàóù˜òBä.A*¹â%2P¼` ´9zh±X´ˆ®â°omm‘¿£X*0ÄŒ"Æ@ÌÔLFƒÑþŠ©ätÎ=ÉýÅbdÓ%‚á÷ûé½_KÄšAûâÈ-Ý ü`j3[[[0ƒ˜×ÑKu¦Í†Á3,ØIïÞ´òÔþ½Df¦ †ÕjM&“SRÉge:t}}]cÞx<.•Jj(à]½¸ÜQ&¢¦hàL&“££#ÚÜ`Œ‹Å²¹¹9èz4œœ Î¿À$A²2жét:XÇ Äã%|áZ`zWWW•JååË—@Ôº\.§ÓI"øÉdÒh4öz=§Ó‰”.57”±ß%I èsôˆ¿ŸŸŸ+bŸ™”0Øã‰D"‰0¼ïˆ‡CI’ˆçÔï÷ ó4âÖ WäêÁÁîª×ëÃáh®L&C„­^¯çr9r þNÓ¹2S ”(zˆì -&þ¯_¿&Ç…Bq2€–mµZÈÇE*.Ñõûý@æ'“I†ê 8“0 Ãá™~¿–á´�� �IDAT!¦’˜ÀÍf‡£Ùl–DŸºÝ.Ê™K’‹ÅHÄ} âµ(bò{E§­1zg„éU\.—Ëú!Fܱh4Z(àXƒ‚‹ø‹DÚ=Áw9:üHKtÝ" îýŠ¹á·¼Ì ÅãqÊêõzŠ=gtu$é÷û@Àn·cFßÛétªÕêúúúÌž“"ºfÅÒ·e”� ÿ›N§ÅûÓRpÄêç¿qÁÝQc÷VWWannnNuhQx5ë^–eºTý]F£ñ?øÁ~𵵪[‹Åˆi¢Øùƒƒþ!ñxœ6h4*ãñ¸bò}$!iÓü°¯­­‘»´L êÇCõïìì0b ŒÕÕÕÅ)ì„Z‡B!Á±(éüîî.¿ylll¨%Áƒ¨Wœ>g4‰¤…Ãa-Y6qNŠ‘ŒïrSü®T*e6›-‹^¯÷ù| êø;ßÅÃü3™ŒØ±Z­ŠÇ„Dœæñœl6/ëƒÁàüü\ lB€~å[½^'N•Ýn?;;Xz½~)8ºË`-}>Ÿ¢¡½ ¬3ZâŸN§;;;ë÷û<Ò– 4«¾ËãñÐχ4‰I¯‚1žÏç?ýôS5pœÕj¥gßáp”eÙív›ÍæÛÛ[bV“dºµÛm”tÂFûææ†> æ•ô»H»¹¹Q<󣉕ùa/‹ðÃ4ÊŒËåj·ÛÕjÕn·Ÿœœ0Bèóùh9¡é˜s¹ÁÌÎÁ2L–«ÚiŸÆE$8c'³tt—š^Å———Ñh”±$� ‡ÃûûûF£QPÎ`0ICý½©k_#Ö[#~ü»Ó¿ Î1NõœN'Á'̤$Å>EÓA–åù•uZ§ÓáÑ–ˆÐnìt:<ÀY $§oNŠg˜ºo¨KµH•À"v»Ýj³âv»ÅŽËd2Y .›Íât”ÆZbu1‹\ 3«ÖÑ DGÐÁú$–AÚ¢¼04 jéóùp—Édr8¥RIpÚjµèð‘8·Õjaö~ÐH³ÙŒŽÑë€Ý·!ŸçççÃá•ý“¤@d—T~4 %?ìâJd�g50u¥R@¸Ä'Ã]ù|ž>å6 ŒÞÒÖ1· ZŽUF£ÑLIMºoÒm6Ÿl2™ º÷÷÷ôî®–+ˆž›L¦@ �ë |Q€ÒP0†ÇãáÃ+++3­±j["KòÒ›Ùlâ ÀétböËår¿ß¿ºº"(ûh4:ÕÐgj¨™5Šö4˜hüøÜM Ó4^Lœ?è©…ºÔétÒÄüá¤ÙlVss¹sæÁg óš ÑóYƒ¹~¿xob˨ŸuÙL8Ô#ÐÎ'k4‘ £×ë¿úê+5ÿ†LÑÀé Gæ.`-qW»Ý>;;i·â˜0ŠØh4‚=ˆh^ŸÏGÿ†T¸m4ùó¦1‚ÁcaÅÓ—€HŠ:—,iEë`0 î>T�¶Á`Ò›L&›Í¦E2Ážus"ó–, °ÂÓ=Ç¥p8L€Û‡Z£T*F#‡ÒÏ:x[{²ÍfCÉ z½~îì-a½%–.\zÃ@‰{HPç4A6&E€f!u�´,Õf³©H.EèÊ÷Ï0ÅSá´N§Ón·3 \§Ó5 í|í¢¥²” íëñ~_¡P˜¯®»Ú3Amà'ú³ÛíŠFJ·ÛUË—ÕžF‰_ Ô“žê@×@/¨ÍH6›%$¤ŒtòøG0#]cÁµ»Ô€Û Œ`:‰ªI'Šü3î8Ò f’X,6™LàØ©ýøáá¡Z­Öj5:¥X–eE¯Žì=¸k>ɬV«| %qC‘\"º‚õ8iKI“É„äX6´H~}}ì(ø#˜™Èd]__ûb¼1ˆ²lôz=îbÂÑ•J…¦²,ó™“Úĉ‡Ó¾…‹ÅÔƒÝëëk1b©T*!½‚ˆBÇ^¯„b)b¦X 3LnšÑh ‡Ã‡Ã`0Ì ƒÁi÷—ôg*Ä|øb­›Óà8Ý·±–Íf“ιZ³Ýn3z§¡TÇME¤V*ðµÛmœ²ôz½@  ”ðz½Äj� \“t4ƒYB†¹±±Ç ãGÞyçÝÝ]’Ù¬qæ4b¸-X(E§Ó­­­Ím|ñÇ¡•J…1Mdþœ‡E£Q³ÙL?ÁçƒÁb±ÈœuÓ0U‹åûßÿ>ÃH«c±†‚aHžH»—o�ÆÔ$ðg$^¤qöΜ¶ÑhŒF#ð?u»]Ü{r¹\ÞÙÙI$HÓ²ÙlŠ<Ȉçr¹`0ˆÙ7›Íápx4aØ•e]Òêõ:6ãD"1çÐŒ´Šôù|S²š±¿H±iœ˜2i¨Ñht‘²IÚµ“À©âõ d†ù=(fƒA¯× ƒ³žƒ2ôÓê©pÚV«åp8xº©ÙüQžÏimm ãŬíÕÕU-f,ÊÔ>…B!£Ñ8Gñ70úÌô̓Á@cz%ª“u»ÝN§3˜dM»Ý‡‘À†eÉéÊÊÊd2i6›´Õàr¹l6[½^î2N¯®®îìì`£* ˆ¥Ð€X,ÆOÿõ¶¶†s8‚51‰èõzñ<noo+ƆÃáÜœ‡Zîeµdb\£Ñ¨ßï'‰»»;›Í¶²²"Ë2 ÉëëëÝnëy<ó¯Ã+•ŠÏç …BÌãÉ¡Ph8òî ( ‘€.˲v¤s4© -3Ø{ü~<‡q ³AÝ@,Ÿ¿µµEûs[°º‘[0 ½$Ÿ&Ëò“'Ovvvö÷÷Ãá0€´<ç!r‚±Söû}Y–÷öö‚Á *ƒ »½R©ôz½N§c±XVWW™EE†N§ƒ}zŽ] Éß8&˜Uù…<ëùÅd2a¦¢"ð è„$µoÚµÿ]|˜´½½BVd´  C2™¬V«ŠkîîivMdƒ šäÇ= öz½©ú‘æDK¥R<Ч×ëñì™Ì]N‡·)hÖ]“É”L&µ1‰êg¹y¤SâFf³Ùl6ßßߣü Ò^FÚz½B‹N§³Ùlnll¤ÓéD"a·ÛeYn·ÛFƒ>ïEQú¥ð^ƒãUG±Nyo<×ëõjj%™Lб\ºYˆ•Å=öD 8P—v»Ý^¯G,DþEkkkd¯Å'!)&¿Ák£Ñ@=E¾c2€D§Ò¤:Žp8Lïô|µ¿ß¿³³ãñxÎÏÏñuä7ŠäмiO<†%‘Hð–S§Ó@tP:ÞÝÝõz½…Báøø˜(a¾ 2ƒš#™LûÙÎÎŽ×ëÅ9ÿÝÝÞ5Aô®8õb.TñQ©TªÕ*¶ŠY­¢år7ë„´Å›››µZHè}I$IÚÙÙÔÐþ]‚¡ØÚÚ⹘ù¡p:+++üöƒu7 ´øjö••‹ÅòðððôéÓÕÕUÄ*].×O~ò“ÐzzÊæ¤Fk[«ÕfŠ˜ƒA—Ë…ÂtŸÄ:Æã1 ‚3—HL�ân6›aí¢Wt÷F£ÑTêRÅ-}8®®®Öj5I’‰„F‡�µj<åápØjµ*Ýõz½ÙlBVP·bzyy „c»ÝN§ÓD«íL(†D ¤&“IÆïf, Á`@XhÉÈÓD·jCÄüE‘×2 ÞR«Õ:Ž,Ë?¦ ™€ƒjN§Þ`˜L&£ÑÈn·Çãqœ|±Çûûûù|ŸƒQ´F£xÀîî.ü0Äqƒß€ðÔáp¬®®Š-<Ïl"‘ÀæG´˜ØðÇFãòòòüüwÑSC§V~+/I¤óŠ_]¯×“É$³oÑG8œGúe·Û}þüùññ1¹Z«ÕÆã±ßïÿ£?ú#PfH’Ôï÷‹Åb&“Éd2|ðA2™4™L¥RéË/¿„ëvppÐl6×ÖÖêõ:9Ö¢ßîr¹�3 F£1N“Î üÚÚZ¹\†O@ÿF;«²N§ÛÝÝÅG)Þ¨¨‚ÔŒf³ÙÜjµ2™ ÓçT*e2™CO ™—$I±v&%“É,…צV«iäÅ£2Ü(û#®8k%!f* °òÿ›ûï,™¦]pHUB¦™ûX,FìY^,è¨ÓéD"ÅE>ß™¹u:]$Áža±Xæ«ùÏŒ;]ãRñ©T *u8‚ôìw¿ûÌIœL&ºtwµZD8777Õ�{{{´q'nF£Q¯×óbŠ)®×ëz½þððð‡?üa©T …B¤‡Ñhtcc£^¯Ë²<ëðnmmÕëu„p‘‚C~`T±¨Ôž‰ßÐ_W©T’ÉäÕÕ.¿ßOó£C€ÑÇ×¶X,ãñ™lôèñ²AN ÃææfµZ5‚ÙA¿X/ ˆí´!)üááâÉõzý—¿ü¥Óé4 įÚÙÙ8¬ÙlîííÅb1§Ó {.¬­­%“IdlbŽ …B¿ß'ùMkkkصµ5Ú¥V<«@œ *MÇì+~ Ò5Vî/•Jd Ün·ßïïv»´u¢ñD¼Z­B­ÁÃc²@N¯¨‘°‚piwwWí]‚3Q‚B"Ÿšòæ‰-nüz$2oµZÇãq±X<<<dÂzoªð+ÁZ �•ŠXK^é‹“¼çn¹\¢Faåɲ<÷ñ)ÍJ—#£/¥R©Ï>û쫯¾ú×ý×r¹‹Å´¨jl&“‰œiƒÓVmHµˆ/à{HÖRL…Àw=~üø‡?ü!âìtN×íííóçÏ;ÎÔj1¼Ìœœœ0ë ¤GOŸ>ýÓ?ýÓ@ ðøñcA·IµBw{|| €0þ\$¿ôz½eñ1"ùÓb±lllù>W0£Ñèøø˜Á>ó ûЏv»v†L&t£Ñ‰DNOO¡Îsuuåp8ˆä9¬œ`ŸŸúé§©TêìììîîîåË—§§§×××år™(}Œa¥R¹¿¿ßØØp:¤ •ðôððÀ$Sh4µC2·2›Íz½ÞEÈÑ1űXL‘;›È!†”nÏÇ1-«JR<ŸZ1€ÖN3áϬV« KžgÜVô™et:ÝÆÆ†Ú%åÍIR7«ŠÔ8ñ^¯ëP$—9.eïd¦‡°šjAÚª7iM` ¶(›ÍF.}þùçÃáðþþÿeïÍb$K®+Aß÷}ß=<öˆÌÊÌJ’"R Ô5 Øú@´è¯îúêÆ|Ð@C€ 4 ýè[ÓÝ€ ?5FÝó1À 5�¥µp˪̪Ê-öÕ=Ü=Â÷}›3i2šÙ³÷Ü="«8òûQ¨Œçï={f×®]»vÏ=ÅW¯^ÝÞÞ6 !‘¤N.<á)Í NäøøXKR‰Õju»Ýåry4 ?ÄÅbÜb‰D‚Î_ ĵZ°{Zt&ëõz»Ý¾»»Ûív‰Î0<ÈÃá˜-úš»L"á&VRBa®#F@%½!8<<ìt:¯^½"ã â+Ç*tf…: g=‹ÑBŒÈÉÉ F¿Óé ¦C¥R9??·Z­pA 3‹¥Ýn¿zõê“O> ÀK=xð Z­~úé§ŸþùþþþÁÁIç!h¿^¯wzzJïx¡ÂSR “É´­v©Tšï¨Ÿ⃃ w61& p[i¼$nºdÇãÓÓSÕ\\‡ÃA3k/Aër¹B¡Rš®œdœœ?)9¯^½RºdR2p£ï@ Ðl6µ5 … ¿Bâ¬RuµK)ùV«UøÝnW•8ør¹ÌœT1†““³ÙŒÆ3¡ ©£Û …PýžDù¨{½^”¤¬V«¡P°Ñh�Gú_Òƒ! Jö dËår àÏ·noo}>_±XüË¿üËx<þìÙ3¦£Æãq8¦ýëEt¦V«¥R©O?ý´ßï¿}ûùñ ˆ‡>íṯXÌ`0±Æb¦4úf³9‘Hí ÏeÚ OtpvB*].0 ’»´è3?Ž„ÐÂk;2ôèÁr8È÷!HÛN§ãõz‘5¾··*p8||| [­ÖÉÉ ²ÌƒqøÚØómqÈDZÌâYå÷ûOF ËçóµÛm‹Å¨’H%ü™¼"Á€X­V°ç¨Þ …p¶¤¸M?p¦@T¹\j[WÔÎl޲ýH4£^i? ÞA;ïê€GUàwôûýJ¥Â³šŽF#2À‹ïÄIì{>>Áe¡Á¸rÃáP_æ!uáp˜™ u)�•ôÊ„®À 0`çét‰D0uåH[úFºìžöÑÇëŠÅâ³gÏ ( »ªjCGáèM.¸¹¹yûöm³Ù¤+WM§SNKˆ’G‰³F%gGìt…ߣ „ÏN§4¦ë(=úÂÎA9œ™4S©“%Ð]ú¯×;ÏÎΰÝÇZ|.ÁY …³³³³³³ããã—/_–J%¬y€XЧtß.çWn#AcÖ§Ý­›R"œæ31¹¬±‘‹]5 M¬LCUˆ Rí+áWÌ»“¿Ï$€—ó'©ÀB˜[¿ß§0y%#n·[)RÌ |M!8N˜ÇÌX•"u½^Ïjµ’8ŒÃá`4 ÕjÑC8 @24 z ÄA% Zªq ²H«ÕJ;GV«•+>ÁZꀢôY´R3è“U &Ûí¶°¦�Ž I¢R.•í�"0LšZF²Q£7ˆ™L†ÇYkÜEt8¦+€~eî*—Ë<fCNÈË8[N»²²¢Týšè =à“Q¡ ƒßï÷x<ëëëXà¡i{{{¨Ã§‹¹KIíQè]÷E Û_üNÇï÷ó9oJ:£Êá; T³<Âá°ÛíÖ’Bu}ˆè‚*w6c‚äQ�ó tìî1[OÕ,*ñ‘ƒA³Ù .WfEåkÀ/hÙ$x&ÐðÐQ‚§ÓÉkÉ5Gî¿ÄÉsÒ€ÓZj˜Q‚Ÿ�Ø…~c­È»r¹\»Ý…=Æ3!àtï*|É¥/*ç€ ãcé„éñx¼²²‚ôtábO~ìr¹=z„'á,E/ÑDro0\]]’C2ŽÀÃ2›K:ôg±XR©”Äšý9ÚiµZS©Ôt:eL ’J„ÂôíLh¼xðÑhÄ#Ž™¡Ç.¼Ûí *;ƒÓˆ€“666Êå2’}èÄQ9r®^¯#gÏf³ÍÂý2 ?UU]ù8ì//†4+ÄuV±ÙlJql2[UÑÍZZHzƒájÝ9­¬¬,r¤)´/JVþææ¦Ùlv:þÃâñ8í#›L& —y»Ý¦+o × fŠ C·^ã÷û•rK´;¡…þd¾B‡0bãóù.//777§Ói¥RÉçów8"ÄERú–Éd"¬èãõz•’‹¼^¯p³ëp8ˆGÙëõÎÏÏûý¾°jdooO÷···§”_‡=zäp8Ðí˜l^¯¨—ÃÃCb(áš?“6»µZY‡†Ã¡ÆäÚ‘Ä!A«Õº¼¼D½vN·³³ƒ“ÔhWR™ÞÕl6Q|Hî3M§S怳Ûíz<Ô¡ÁÊtuuF?ýôÓ7oÞ(Ѭ'œ«µÛí»J†œU¶¶¶î‰J>MÙÞÞæœÍféÓŠn·«zR5_%§™¬ªVûýþÝÝÝ‹¢I´Zeçäp8Òé4ŽXè>µZ­=ÒRˆw R©”ü¬O Œ/¡M6¢:RÇdÂ)|ŽËåB} æ ] ¶FÀqý~ßétnllôz=í»„@ °½½=…q¤X,†(–ü!<lÀX�,Æã1o©J>ŸÇ. øG-Çoˆ°á“ j²ÕjñͨSÉï BÇ™€Uãñ¸ÅbQRÙL&Ç­Z­Úíöïÿû(\rrrÂßâ÷û=zFÉÑÕ½+‚Ã’étÊ#jµDùéƒb ÕhªÆã1¢|@ÚFTÒic:– ÐÙ›››d1~¿_i×ÒjµÁ•ÍfQ‘3±×ë¹Ýn`ªªÕ*zN!Ôõ�¡ Ü›!W£0³Ûd2Ñ(%UAI6è®R®2°Ï™Le8Tßοëöö–Œ,¹Z¯×é½ýd2 ý²œ«j`§Ó)•J3UfÈÌ;§N§&lfNöûý_üârK*Ì4k·Û<Q/4­ƒÜ4L&Â)™L&5æ^£X,‹F£Lžº0iÐl6cå&'ÿív[{¶ýííí³gÏ”æm¥RAìQB ¿•¹Jzcmm —˜ÎQzàáá!•ápeUJº µÓé4?f³yuu(„Ä-ÂêýxÔÕÕ•äTàôôËÞúúúd2Áž`¿R©@a€xÅ«Õ*r¦ùÒõP›P(„ X8¶%¨wÕ`0ДÐ30¼Ó4ôI.—»C×þèè¨ÝnöÙg(ОÉdnnn$¾ðt:=;;«Õj¯_¿f åÕÕV8ÙÇ$!e4™L&Ì…O?ýTu % fÈ%‰Ðy%»»»3Q2’Á…Ã-ÿ1oÈ …NNNšÍæÚÚš*¾Çáp0!Úâ{½^Ìf3oLL&S±X¬V«Ùlv¦"³<S³Á`b•æHw$æÝb±`š/:’½…Þ9FÉ ›Óé”lk覇B!‡Ã1S ‚Qù鳂b+Æ8 ª~+¶ÌU8“¯Å‹Å˜ÓFÈ ³\|>q€TEÉår‘WâÍ,o¿ãZ|pǃکBGÁd2Ák¦×*f—†à¶5ƒÁÀëõJJ›€@KûÖùt£\.c¾~ýÚl6O&·ÛÝëõ’Éd£Ñ ‘§ÅbMeú¡Óé´Ûíh4Z©T˜½EKU1DSgÒm¢‡Ø Ƶç &¨uéò²ôˆ ÞÏh4Â¥ð-äîÂí“É„év,ùÉd’Œ~£ÑÀ!±ÆªwP'æ¬×étªÎÜV«EÂsl‡ª&BÃè 9}ÀhJÚ /^Õëõ0úBcâ÷û­Vk·Û¥á%Z$ëõzz¶:„˜8òîø2šF+!Ì;ª«´Z-°£Í4 Œ’w©ìœ$£Ð„Á¹£~sju¨æ¿KHr¯®®æ#옩„YéBHš¼¼¼”—îÐRôÁívøá‡‰DÂãñÄb1Tåb0³J€_-B°–ªR«Õ$uSxS€F%=¸œÕjUbµËår­Vóz½¡PH‹ç%„aöûýW¯^5›Íb±ˆÂ‹åè舞É×××…BaVM»½½íõzig‚µ¤‘¶<’‘ zÉ%†Z×årɃ‡ÒÓ0L~ Ä%ÜE@¸� Ð£Ï*ÏÏÏm6›Fš‡–™5Ê÷·žî¹k»Ðà¡1a²µ Oá $5¹é÷ûÂ,*éÃ$¢„ƒ˜'p dè¬';ôÌ–øÿ.1sRž"R(° Ó*·h�rÔbq´o ívûâtD:Š·ÕjI¬§ËåbÈUyS%AM#�E;’„i”nÆx<6 >üö·¿½··‡Wü#Ù 7 Ìç³Ù,Ÿ` ¯T ´Ò uì§\PóQõ—ƒtlÐ1Žf³ùææFÉ](•JÂK¨£ŠÈÊQmϺK_ŠÇãtÌýÙÙ½ÝÁ8òsZ‹Å"¼øÉdB›%Å cŒü¦‡v“aƒ˜K¸ JˆC&ÌNß%y—’¦ñ\¨uÐg½K¨us¬(‹…¶¡@}L§Ó¹Ëª)Õø—[bâÆãñÅÅíú%„b#Û€‡Zk±3Ì*Ø;ÅÅI»Ð{ %.TULGãg‚›éõz¥,>ÉCh&\ŸÏGÿRHC©%©ô^œ»D£Qèh¿ß¿¼¼-%`ìàï,‹’yeí)I¥\.ŸÍštFÁÐH÷€Wã Ì}€tp¥«Œ†‰?Ò G²kLo!“–t¥Æ3'%Ìè£^§$}×ív ·5‹hì]NçN6¡ß¾…7ìL¿ß¿[ÄÕâÝÂ$•ªG£ÑPò›ïdôç\œhº[‰(!mùµD ˜FÎ<% `J¾¶’-Üôœª±Ã!¸®%?Ãæ€|–J%ðô ƒËËË?þøððP Ó#4ßÚKß•ÄãqfûˆêΪ7¦Ói‰‡%á‰7˜®êõ:˜46žÁt‚M˜šUaÂJÒl6É–Îï÷ÓÎ5rg°KÀ%!p»Ýn;ŽõõõEÈWWWÚ'!§-oh”‚wsmm- Ê¡4žŒÞéª~c0T Ôjµ¹Ï°³;ÓªO¾Hû]�n /!¹‘6€ÓÞ÷äEž¤ÒÕ@ `0f)beN—ËåH"jD":øD¶ªÐ]­‹“Ýnf¶�hív»ùª3ŒŠÓÆl6 ¡étªd¡h»Rü‡¿„z6sø¸«ßï+Ù}¯×Ëø§ªGâ o£Ñ˜Ëå®®®~ö³ŸýÕ_ý•ÒÊã57ù¬dµ f¢Ûíj Mð":ŽÝn—×0Õ½ Ðoll¿Ð™Wjp¬¥RIx9T‹…Ñ´jµJ¯ñÝnw&_GÒ'ôH)94ò²F£X,*r*•R-“_*•Æã1ýEµZm‘dò]~¿ŸÙX{<P J¾¼·üª Z/îý¸\Gn¸×™NÈÔ"JtMˆL&Ú 4ù ë¼€ÍDx õúb±˜p·0_·ÓHšÅ öSé»´ûÿm�� �IDAT¿KŒsÚÜÜ¥ž×’¨š„×Òëõ†ÃájµJ®‚®Ýn£²�cè‰ÇÍf3”{8`4…B 7!¥–**D®á“WVVèd3¹ ªÌÁQ ŽQ&Çf³e2-•ç“N§“ËåÀIJ/$í€îV ¸À3o¢ì© D×CIsÚjaãÕ©e »oÞÒ½Ê$”O&“9ê¾øý~>““öØègFBxÊ\âo$ÅPè»È:*á]Uê(%šÔd2ÉøÈG˜²EúÉZ”œí©zº+++r­æé§µXd·Û=SPW£Å`”j¦çóQX þÒx<N§Ó¹\Ždå¹\.%ú:¹ôû}%sÝï÷s¹ÜW¿úÕ@ €DG‰êjz°„(l‰Ò«ãœ€2{ûö-!]–X^Âü-t™œ·—/_¢bÈTÈß<xÀ¤ ¢ÁÓéôõë×(— ìg·Ûít:4|GÒ Z5z(@@©dz¶X,ƒA›q½^O€ Œ3Á®ÍÍMBöz½£££`0Sb4¸à{°eÚKßÓ¯~óæ Ùf³‰3É‹‹‹p8üäÉ’¦zàIÖ•ˆj`y™LtºøºÅbÙÚÚvÝÞÞžÓéÔŽhÁ» i_ÌhÄäŸ "Ãw»Æ©ûæÍ·ÛýôéSíeåp”' ò 1³¶ðòò²Ùl±ÛíÑhôüü<‹ KM"É…™õÛÛÛ*2H›´“#?xð@I1h¹¹¹¡]¢¨>Y£ÅÐét;;;F£qñÐE¡PÄrNOOŸ?N&ˆ–yÇt,%síóùHá¨ûC&©Gê¸Ñ7›ÍJêÄîœ0î ôËìÐ8†âÓçóÑ,áN§3‘HŒÇã`0X«Õâñ8¶Âߣ*»ÆVÑ •c>¡PÈãñÆV«E«‚Ñh4™Lø«ÕJ¾Èårmnnêõz&bn³Ù˜bLÇn·‹"ó¡Pˆáª§Õje2r ¹ ‚¼½½- h¼ÝnWâ'¾‹¦�—¹¢‹pËööv±XÄ^ù?´2àäYânÓÝ®*ÛÛÛ :QݕΡBÕ NÇ`0ÏK„G­I¦EÂá02â$¿Á‰x`F#,»ö` ©×'wY иÑA¬R37 rK#¡­FA´JHä:«�µ*)íO;X3é§–OÆñ6Š&3†ë}J4õûýô¦|ªïœ...´O?”†dÀƒAÂjaµZ™6Ox ³Ho§Úív¥R @*ÕN%;h†cM¡984—¡Æh¥Ra&˜Ëå"ç(kkk䥭Vëùóç|²¶Gªó³R©œžž2†d£:îää„\2›Í|ÞÝ"g­ÝnWȆ*à’?ÀK…¦„Ÿ¬¬¬ çéý!Lq:Äy¤ï™ÌLB�ÈË«W¯Ð!BÕUR ùN…ïa§Ó IÔj5¥B_´Î0úÏ_ ßÅoU=Ë““� ƒ¤P¤Ñhä± `s'64¹*³›éõz Öe6777Ú)Ž”„LU‡Ãq·5?™qDãM&“Àƒ|°B¡Ð|È9°'ók¼Iâp8x”ËÅÅÅÕÕÕéééL!P¥!žOŠÅ¢ö!*û;%®IL<‹Å‚JŒå’€ãºÝ®:&!åQ“FãäääòòYö’ÈÀ0ÂSÞú“e|mmMcè|2™ð ¨×ë¥R ÐÈZ­†}?©TY#ç–~¿}}MP“°¼ÊK9ÚCŽ3l6›¤î'€±ruû3…t{S^1°Ñw ~S"IªÆWƒ0II1ìv;ÍöÄ _UÂ|>ÿõ¯ý«_ý*™ÞN§“SƒZ:Ã?VÈ„«×ëé™%b¥òë ü+¹G(án§Qö@€áò�|"•J8kz°05ÃÕ«]Èp(iÚy‚Áàp8”' ñˆ~^1®®®f:«#†Ëçó¡è}•GÚ2vPY‰£¦Q$Àí{ª†…Þ%4²Ýn2;ÐùÀqF£1‰x½^8Î ™psõzýððððð°Ûíf³YÚ#C ü`ž\«Õ&“ ß¿<ªW£Cg6›áØ  ¶B­~ÞkFåEf³y>QSU­‹Á3ƒh4•H­PVDh”AÿÈ\ ‡Ã̈ðn~¿ß'¦Äçóy<%ÛT(H ŸÁt£æ ¹ \ÇCœ$œS*O`eZ­Öáá¡0n_¯AøÀH$Â{‚à:r:Ø\NË ˜g-kF§Ó)íjóùãr%´Ùlý~>eÏØèjµÊ˜HÓÍø‘ §­¼˜¤|q}Æñêêj0hé^—ËÅLX1=‡n¿¼¼Ô¸„;øÅbÑH£Ñ¨tÞ©q/È�·¿D‹“פFŽ�2 ´l {½"¼~¿Ÿß±2q<Þ¦Ñét ¡I4¬¦üžšÇâñU‹0„Œj4gggív;“ɀˇKâñÖRKŶùð†½^ÀšjµªŠ™ó¦Ò‹@%§tÕb±0«8Å?•Fø9Žšù\#¦Çôzý"Ô«Óé´ÑhÐ6w:*Åå&“‰ÙlÆ<'ü¹gggü19Iœ–V N7»S‚ò:CHTg „<™L‹Ål6›Ífóù|$™i ±ÙlJ®Ãi«Ä¸ý¥¡YˆF£´Yh·ÛZrkaLh°¿$zÑh4H^h¡PÀ`áZ¸’Á}!cz}}|9aûusÏ2î;!¦û}¤m�5)`âí8Õëõ C:Fè<“ÉÀ7 £Ñˆ¶†¤ŒÛíF¾_»Ý.‹¨££@¸àGà‹'öz=p}‚±BÒxá(Öj5ä/h†Ãa`-iL€P4ò®20·9DßҔÝK0$þ×ÍÍ ÝQN=£Ôõz= ÉwJ9u<f–Ài±8iç8.ðÚ]¦Æ"ºHÝ»Á?þ¸R©(Õg²X,+++|ú¨’:•ËeUÕY×x¥Kà\n6›Íf³ÑhÌ™‡ o:ÆÀf³­¯¯k)G¢Snß“ ÙÝçó©Ö7b2щÎHŒI,K$&“‰€ý…D—rǽ^{c"w»Ýn·Ëà$œ†Jð¹´aȸïP„˜nÙâ´¹¹y'/&ìŸtÈ8 ‹ˆÓpEÚ1&ƒÔ«·Ûí›››|ðÁãÇM&S©T¯×ëóùºÝ.IP¡9ð®Z­&9Á"Ü6DB¡yTˆÐŽFBÎ!oŽÉy …Bô<14 Få/å‰6´›]üÄ25›ÍV«E"cù|^Xi™]B]º½½%VÏn·ó›†ù2¯&“ÉÛ·oÑØ`0H¦ëÚÚR]N§pCFЯ ÅC‰d ¡Q~)’¨9pòù|’C5FgèžG.ù§Éd‚:ù|>zˆkµNŽonnÊå2³Ø»$ë}ä^©T0ƒ†Ãa±XÔ¸ðKjv(išªèõz ΋Édr»Ýį’oH× ”·oßÞ•@&çLŸ�¼ éP)‘H0ÆD‹ ç—4Þ„Ì‘>ª*P'!¦›M%‡@ÿ*AÏ”°–[[[8àQmÐ`0�´ÿñd2q:£Ñ¨ÓéÐþƒšlµZ“ÉäéÓ§Ož<‰Çã‡C¯×—J¥jµŠLÜ'Ož�ÀÁø8@¿Úíöx<Ž­\‘«ÕúðáC,-étºÛíÎêõ´Z­B¡Ðét˜×õû}šnÀh4@¬j4‰9CÒ”¼¼g ‰9€SCLy&Q�Ón··¶¶"‘£{{{NGÈA÷<öŒ> ‹Å’Ïçg­B¦êéö!aDìõzétz2™ÜÞÞ"½e<w:P(ät:•òàÓ#"„`C‰ÄLe§IJ0¤¨ÄHW(à±ÏÙlv8‚pW‡Ã!r£Ñ( ˜&BÍ‘\2›ÍëëëÌ`‘±@b½Rº×ëD"dD”F0ŸÏW*•¹K*ðÓ!ŸÏw»]´j4Õëu¤ŠÌ½Ò{½^»ÝÖÈ*¢eÿD·ï!o·Û]__ÿÚ×¾–L&¡ ‡Ù<mllÐý  HŸ­]vww‘ÂÆ§’ÿãâdבkHV~¾Åkkk½^¯P(@ É7ƒ,äêêj2™ (§@b£Â;8ÚU‡g›››.—k<ÿâ¿ 'Óéôúú.ß­�ä †`0¨êÇmll`*¢dªÜZ,|Ð3»˜u—Y™Dôa4`H;N6›½½½e΄&“ ­ñ`ÂUj¶Éd"U£Ñèv»c±9Ûäyui²cúsÈá\>Ÿ•{¥RA]+ÚÍGz}©TÂ1,y8ŽÙHWÀIçX™#Àµµ5˜Œñx|{{Ë0Š‚d]¯×ƒÌM²Û0 V«•ñ ív»ÕjU}t{£Ñ@÷Òì´NGI9 C-·bhv4•¬vŒÞò}ÅÌ 螤•ß…ˆE¥RÙÛÛÃYÖ›n·KGðÊ%F“1ĉDÂn·“Æc-WýÔýcºq0hÙTñlªö!ý@²^.N@Lïü˜™{ç±\.70”ÙÉd‚ÌÒ‡ú|¾f³i±X~þóŸ£\Ù÷ÀË‘£ív;LÐ]m&“ ÈQÓd2­­­­¯¯ƒ}c:~å+_Éï=/NåãOò“ŸÈß:oXiéå§^¯ÓKšpe²Ûí¼Ó”ËåˆÛ2_Œù?`ð XxàÄëÉ*ôv=¦±ä ^¯›?DÒùÓrN‹áÁ:D÷†ËåŠÇã¨8R­VIs8JÔB Äõææ&Ã ÆÆùêêŠ^ÖÖ֚ͦD;ÁžSt©­7N…ÇQè‡ÃÇÉL`æd¯×Ó’üM£;uƒp X*•¦Óéææ&@…’çD£QE2‹“öƒ¥Z­¦Å² 7Ûí–ˆ Ñ�á'™ÌèçóyÁbv0€¢Ë›Q*•4·‡"o!èl‡Ã‡}Ö½2 -£„ªÏL&“LU³ÅÅjµÎšDG;´ƒÄgR9Œ¼Ëd2­¬¬Äb1h‘×ë½¼¼ê–ÈmmmµÛm%eS=öæñòÙÚÚBæ~½^úôi6›ýÊW¾’N§JýÎw¾J®«Ó´»\.áAE$±X,Áª¼öð<::RÝ¡+¡zõz}(úéOúÃþðã?.•Jggg$X< @0¯*a@…¯³ÙlápXÝ5™L$ëŸ8˜ü^/Ýo¸ lñ$3[’ ¥Óé, ò >w4ñg0ûûûtä„ÜÌheeÅl6‡Ãa%às™3ÂLß™Ô&‰  _’W6›ÛžN§ ˜gNõ˜Àö‹Ö|óæÐvÓÐH(ŽgÂáð",…étZŒÕqùZÀ`0Á½L&F·›L&!ZE#pûòò’^Ë :ûúúšâÝ¡e –]cÆ3Og¼¸0)yóí˜s¾Åž‡N§ã5 A…*d¢[­V¥¬¢7oÞär9-äJk„v²G�í±^Úl6»Ýîóù?~¼¾¾¾±±ñÁ|ó›ßä£h¥ˆ¼p›|~~Þëõæëëýý}ÚWR-´L+¨°Äút:ÅòS©T䥎#䕈‘[Ün7­‚Ãá°Ùl ¡» ¯t¹\ív»Ñh€^]É¿ ¡‘6›­×ë «ÕŠ»HohDMb¯CT•2›uïÊë(Úb-b³ÙȈøýþP(¬¥ÙlF’\íãˆ5XÈi+Ô´~¿O£_-»½½5™LJßE1‰`<þgWwk¹èw©²š*)†Ðdœžž IHÉNëêê zHÖ'Æ¿¹¾¾~õêŒu0¤9mé÷û<˜Z©…ŒY 9m§•X‚éæuf_ ì?4Bš$dÇsËÙÙQB ®}!ÁöŠt;¯i­V !ôóósÄú€¹*ád2ùüóÏçN’pgKüfmp¹\———Åb±^¯w»]€úùÅI<Éå(Z¡ºàüFcÊ©ÑhÔŽ ‡LÿƒÁz½.Ù샟”Ö lž„IíÑh”¦CX?7™LN§“~¦Åb! ¹XðìÞ˜r�-¢ü’$F´¨¸Õj%ë¥Åbáw n·»™¿Ó~±Õj%XKÉ s3l6IÀ3ÑÚc#¤%F£Èp8Lš„¥îööÖãñŒF#%øÎïÖrÑïÂA´$øì÷û 3›*ö–Áç‚‹’·ztDEbÁOOO#‘@QJ£Ïߢ¤] ÷E¾8M„ŠK’f�Óm·Û Ÿ6+$Yè€êîMl6[»Ýžcñ“+†ÆB£Ñðz½Ä,ð½‹Å€RGI_€µ}>*í ÷ñ‹lî‰C’hÖx<ŽF£ˆ ÛíöH$’Ó²sJ0ÄfB¸œéįÕj-¦£åE<h÷úúšX(ÄîðÿL¦¬¡¸9æ™H[¿¼¼=@ÚFpsº_†a' î+¹Õ ÖÒëõÒ¾°ÑhD8ˆÎDàCðL ]8”€F’’Ñ×¾I’,w»Ýù¨@Z­–Ñht¹\àOÒ–¼H~60ç2#‰DB‹#%T:N¯×+T %oŒ6µ<I.v„XûÁÞ"Ÿ¤¾Æ‚Çò×××È0BŸ·Z-r|¨ §¦{2™4 úШöÿ2H2™Dš˜<Ék‘ƒpi;&?Ú¡¯èîÁÁÁ³gÏÎÎ΄Q!p;‰,è"hÛN§ÓÏ>ûìõë×gggÇÇÇ?ÿùÏùÔ ‹S¯×ƒU:þ ™Û"‚²ß u)33G£‘„?Oÿ“`ª C6›-¢´ZÎQ‘ã¤Á{X½^—sÊk¤Åbá‡íøøX‹ùðx<n·›Þ  †P(DŽu"âZw-ÙÃår9ú[Èèó’J¥˜ˆG¿ß'ÎG"‘ØØØ`öìÂS‰ WŒ°k°Ñ4W£ø|¾ Òr½^ŸÍf…‹¢–‘�*›Í¦–j›©TŠì)• »¼(ñ÷0;”$h·ÛdôiêR-þ;‰"‹Exoyé.âqNwBn{’ÉdH=ù®¤3ôè#o°}¡ÅPÚ5žÍZ:D©Z¯Ÿ&Hi½8??ÿÅ/~:X3,Nív¦áþHðÈdF™%k˜Íf‘H£´—ŸN§JŽ.F#t™®)ä]¨u_«Õhf2™ÜÝÝÅòɪŠ×ëÕëõ£Ñˆß¢iL ëv»Ì†o40ïËRÊÍÍM”%¥G_i ¿¹¹év»JÐHÂÁa6›ÉÙì|Ì›HO¢ûJ)‚$ÇZ’§ ²¤1:FqÞ[¯×…#%$ÿ”�*%ÄÊôÌÅbd ÇgJ¶´§<™Lvvv$e‹…ÉŸJÑc¥·0ÓÄív#Y™i'¯zÆdA©T*¤ëîŠ=™Ž÷2^J˜L&ṬÐbÌ!¹\Nè÷Kxˆt¢ d"«««Âu &HÝ­Õj/^¼@Áå?øÓ}ô‡ÿíßþ‡ÿôƒü@ûç÷ÿûÞÞÞ=i ²;0]q~³··gµZgePZF ±³xù;³Ù,,[™ÏçUÝ+¢n·;“ÉhQ&IyüùdssSâY,–Y#ì8ƒx½^>`ˆÍâ½:¹$ιø‹è¥)p‡uÆxuB ²ÆÛi^ƒh4z·¾Pè9ÂŒò¬þõýû“µµ5–p¹\ØsÇãñ™’ÅHÒ&µ¡ï»@»êúý~ÆÈïîî oÄÜ_°U}ôÑ_üè“õÿë¿øwòßùץʭÊâ„ù …ƒ ­…BÕÔB^)¼‘±(CGÿ Ò±4`‘N‰D"ªÂ%"d¡%¹H*C=1áí¸x)sªÁô†–KÁ< gúÖh4>|ø'}òvŠÜÅÿÏCðJ>‡ffÞ(§»åc ÃîîîL£?_%…ç/ÉIc• ´Ñ›ár¹>|HvoÚ“ƒïvp¿ ëÕj¥mq6›•¤çñÌÔ3õ<3ôªwíîîÊ>ɵ +ù¬ÄËá?gχÑÏçùÅÉ _`1½kµˆ<EÆEE…%Â~½%õñÌf3}€d±XŽŽŽèSddÒÔ J(…&@^)¿T*•®¯¯%Á x1üÉ Ø «ºŽâˆF£=r¹\kkk›››½^Ρ§—¦Ó)Š¡Y­V¢Uv»L [Hèt:bb‚Á M¾·¾¾n6›™bh©T*<yòäÃ?d6s˜§x<N¶,¤©w‹‡ÄÞžâÛívûÎÎðXÌ„oµZ€¹… ³v¦ ÷ÎÎÎ܆Àb±(mš­V+.ÑŒ…¼Äb1¡õœ 7Újµ^¼xÿ???ç#0àû¸×Ua>U¹óXB¿ßóæ ùçÉɉ$ˆÇ´™Ø"-ßb0˜¬ê]Ÿþ¹ädÑh4’ÊuFx¯Ãá CüæÍr6ã íí”Ð>ÉÃìtß/u”äžápÃJøIùo|a¸H&“ƒÁ�G&@¿’Kr‡K‰Ð¥#eú’Íf“Ì=mðùZ ¡ÄY4 F^]]a†¿~ýZ£±Ý-)ÑíñxÆã±êù9r"È?IôŸ9e}õêÕp8dÐ '''Ýn7‰`#Ø£n·ËЩZX›Í6{2î’'1<ÈP_úÔäíÛ·Hìt:/^¼¸¼¼ôù|3Y«Z­6í‹îÒ–üóðððÅ‹´És.ó¦Pií$ÉårY)CÌjµÞÜÜÌD´#DLkÙZÑþŠp9ä±Ïs!´ŸËå2 ò⳪q­/Š@nÐþþ¾íÇhšªŒÇc²¬JtFh?m6›Ð%¢³å"SÓl×ÚGß t*•øIY†²P( öEï-€Ñ+ Œuæ¹&uïp¼Á` × /1ü¤Œ€¼òððq[�9–çÁ`@–‚÷¢s™PZ‚gÂ¥!uØ)~¿¯ÊTÆœ"’>¤ÁqJ`jX2?­V+œb±ˆ@™Fc‡ñ^g$ÂÀ0ƒÁ ÞÌ*yÎeÆ+*—Ë÷M‰F#m•ÖTÆäF~ÚóWÂi«“²î2ïšu¥!èl틱×ë%êL·pƹÝî9"œÐÌ”×x£ßï×ëõdÃ7Ç8†ÃaL: tWÈ\ªQä8k(†$f¨ªislÓùbÒµÛíW¯^ñécBt¶\�¦VÊÂUº‹Å” Ø&á—hÌÊb-åC莰X,L"“’‰áÁ›ÓéTÉ‚0 Ýn·X,³¥%û…�c1½I½¾~¿ŸJ¥°ÎÙíöL&szzÚh4Z–(7¶˜õzT⻼^/<ƒÁ`–Oºëóùz½ž„i´P( F`îÁßµ{^¯7“É`QÔ®3:º‹FÒ†€OÂl·Û̪y\¨&“Éçó)9žª€J~" 6Â/ü{‰÷# G ß …x®2¡¡¯¡P¨^¯Ûív¾ñ8?ÆÁd£Ñ�¦[Xhx>:ƒ¥)’%‚ý10Uyª`F(ç1™L®®® Š¥b+e´Z­V “ŽªÀó$ƒ…:³ÃáP²qŸºKK‹¢ÄÝÎ IÒ“° ðÆã±Œ%p«a"5‹µ4j’þ}("4KªÒétæÈ:å[(¯%%  «AßÜÜÐŶ Ùxéޕ«×ëÍf³R©Y¼ øÜétÊ”éDµíæÕh'P“J‹Óùù¹K¦ª“ǧÓ)AºQêÞT*¥téêêj<«Ö¿X¸½ˆ>k¡Ö*8-éyf°jµqÑ&“‰¤6•pèùd¨‡ð,e HŸ�Ó­¤Nñx\5²g±XèHtf¦à*¦ÉÆÆF.—ÓÈjFý~ÿø`!$þŸTât:×ÖÖ‚Á`±Xœí€24±XLHF‡ï5[U§|èÕëõ”¼pئòçÜ–ÝSÂYóq)Ùâ¤*$ ŠÆZ2;*¦xe&“1 õzî#PÈU/€pïd´z½ã02ÿ ‡ÃdûººJXM!+++v»½R©�¡9 ˜M¹ ƒb±È<BB\ZYYÀ~uu•’4b±H¯Ó£Ñ±,Ý;ŠÉgò£ÎSœN'›jÁh4ÒÇò©uF#–Ûããc¡ÄZ‰D4æ7ßáèÏa©•pÖ¬( ‘s°š •¸ÀA¸ ?`ÆQ‹är¹ét KZ�Q'Q %ø ¨2ØZ%öDUêõz±X,—Ë¡PHRQ‚6&×××ÕjµT* Þêv»ÑhVwƒÁo|ã_ÿú×<x Œ‚Jô q%êglI¥SUÚ@^PŽ€8 C”³&I ‡CzÓ [Gô“àO&¥…“%ÄB"ä[]]ƒ Z¢™L¥}èæò³»W¢Óø l„‡÷g766´£Ò²Ùl·Ûå$A‚llôÈßµ±±AGr¹zc:Âô3KõÚÚ˜ßÈÀü‹š½^A½år9ÒžL&½^¼gt3t:Ëå ‡Ã3i!Ü…Ñhäp8˜�­ý½ª=?™LÀ^a±X®®®èO ‡5ìñ—F£qss#Ù%ƒþÑh4Úl¶z½~äfs{9wš£H&“Ðm:N°3QBÒÃÃáP^reeeÅ`0u¥ÇQ£ÑN0¡ª4%¦Dm„o¤[N댒´ÛmPÊ¿? Ì(!g‡N§sccÃår¯«³�� �IDATŸŸ Sy%Ö ³U©+ $Ùl„¨w¨œ›››sƒs‰¦))m!766´0<Çc¿ßo³ÙºÝîêêêíí-Ö?¹yçÉ Â0K¯×ã‘qçççÍfóüü\]A!aÚEÊçóÂýf¯×£ÙÉ–…Ñ'‹Åòøñc¾RÑt:Õrð�0“N§»¼¼äçF("N+Ÿ fN·»»{ssäÈ_\\ììì`3Áon&“ÉÙÙ¶ÑhôñãÇ`Ùѽ«:Ã8’àó庣᜵Î12,Æã1œÄÕÕUx… 6¤¦¥îj·Û´atæöö–¨Šja§~¿_(àK¬Éææ¦F†yNRøj&1 [[[O®¯¯™_6›M¸zL·Çc¹†J“ýœ–S0ŒÇãÉdŽ0Ç#©é WVV4*Æ|B+­3:e°¿\—˜ø‡ênƒÔ¯ƒV#Ü]©Tr¹™ÔDgë4S�9UZã• ëëëÌ1d4¥¤wžU¯ä:œœœ0f<•Jy½Þ &by{{‹íøÅÅj¬™Á‹RáJ²M<x€QÍæ"lŠ0p°õõuí©Jrd.ÆÝÝ]4è+_ù ¢j»»»ôQ¼Á`H§Ó0‘&“éÃ?´ÛíÛÛÛ€ G"‘ÇÿÚ¯ýŒ “ɤj?0¹O«««Ð?“É´½½=S>xð€Æ´àLéUd_"‘ óDþ@g‡B!-µ…T»Èl6Ë+ ¨‚pïjöâQ@@#³ô >ÆcÐóŸÔõ'Hpú‹˜IÅÖ¿“™zƒ¿ÓŸH:VJТԙ0ž"fƒŠòOØÞÞVÒ^É%-ãHcŸyæ¥oaþNŒ i ñÉèáÞŸÏ óƒd2É8p‡ÔDÃäã¢ÝÎ+! †T*¥”‰NŒÉÖÖÖ“'OÈßg®1“Øl6¦•±XŒ>%&Z}÷ŸâVWWá›5Ïd2¥Ói>ØŠ\�œm:Žííí½½=ŸÏ'´ƒz½ž,*Ì÷¢+h3ù^£Ñ(4ßý#}»±±¡ô3~£Ñ¨R‰Ïh4z·\jh€ª‰™u‘~ÿB´]£’KÌ]™LCOr$ç´¶¶Æ³Çãq²`˜L&Uo€Ñ™1@D«“ɤðx†àÇQGNuˆy°ÿ}ˆÅb¡±±©TJËù«Á``&&Œ ¶Ô‹ôá=aŸ3™ÌÇçîO-ºžx‰Å^š­BĬ‚ 8ý—b±HÇ(Éð»Ýnh­¾.Ô;7|¤z Ä;::ê÷û>Ÿh¤Çã!ÜÆn·›k§Ó ò½ÕÕÕ>øàøøøåË—ápøææ†?>TÐét:N¿ßBäJö’”<ÂLJ‡‡N§“ &‡ÑhÌçóh0zJO- •ápøüü\is ¤´Y¡ Oss}}M±mñL‹ÅTWbžwVá;ðNO/NJœ¶t Fx&\RÑœþd�·u:ÝÁÁ¬¾ºº"9Bd¹Î$ l#TGÁf³ñfÎãñ`IÐÙŒÎ�8¡Óéö÷÷%ÑBò½B°?žy‡pZR�r~~®¥bºÅbÙØØðz½Œ1™L& åaìÌâák¡œžž¾xñbn>{‰êÒ1=”sU²OÈ Œo®.å¥Nª:>>VåtA:xµZEû@.ü1¸PgE)« Ñ?ÇÃ<ÜëõžŸŸçóyÇCC òù<¶ù>Ÿ¯Ñh 9¸ÝnW*à-ºÝn(r½â>@Aqâ]*•œNg8Æú4ŽŽÀjŠß®îFæ´5›Í/^¼@À,ÚÑÂPyqq!9&999FdnЄ§:eà3±ï‹×g;99QEÔÎDÖ dXy̬„‚V‹ÐpÚÉdrzz*ì ¦~<-oÞ¼!•#�Üf¶8|jŸŽâ™Õ( cVÒ™ƒƒƒétª”ïót:]¿ßg²u˜¶U*V¥Úxì¯×ë ±ò=¸h¤Öíõz¯^½¢ƒÛ¤…39Ö>Ÿ/ ‘ʼnØnÆwÑú)ŸÅJ#"T]²((-:e®Öʼn`‡Ãa¢»6›ž`ä(eÖÒ¹z½> 1ÀšB¡@¯áv»ù€Y½IaTH†n·Ûe,àÙÙY0l·Û‘HÄçóù|>Üu}}=™LPíP$ó ëÀ·ÃÃÃV«•ÍfI_Y­ÖX,$‡Ëå `Ó« à#Ǧ¤X,öz=Ô¨…«X*•ªÕ*i?¶u»Ý‹ÏXRDƒ¡EGކÙl.£ÑHN£LìþLÕ ø]õ¬þr(b"Hõz6‘±XŒá\æëõi‰©2{‰Gñ„ôÒóŽLUbtÈèÓ³˜öÀìv»M„$×1êDç¸W«U>=ªÓé¥.‹X9‘H(9Ýsô¡H†Èl»ïÄb˜ÍfÇ ½^OèNÍT`Âb±œŸŸO§S¤¶ÏäjhnϤ҈+¤Ói-ËžÅbá+ƒ3–D „k4•@&fºb'Kƒ:d"¡¼$(k¡8Æx@§ªsw›dIÏ4<9™L"æÐétxT<²ÚÊår£Ñ�SÎt:jr4a•r»Ý CMÕ~¿yy™ÍfƒÁ Íþ%ØÙÙÉd2ÓéÔívg³Y%Œ½Ž£¡dº„L™¿ã.àÞãñ8 u ž2Bžê(H2ÝŒh4ªÑ¾@1´´P‚ëÇ xNƒ|×.ç´å•sþ\N‹¥zúp>a8V*ƒÁ@P“¤Ù¤¯Hß §¦¡c¶X,J¬QJ,Ãx¬Fx<ÏårF£‘``…=?kö©| g! U÷ööÖçóiô¿yc»1Ã.á] Àø3•-ÕÜ·–b«êóùȪ#á\¾¾¾V A¸©TJRÉA<WonnÈ JH[¹ŒF#~b«†›z½žê»b±˜ÜéÎf³°Av»ô,aÂ=<<DÌðZ®¬¬à>D ZÂiKîÂ4Îf³(_T­Va޳Ù,’ÂG£‘ÕjL&ÄÇlµZN§óææ¦Ñh t ©¹§¤ßô¼b�¿@àöök$])wPÙn·©¹¤ wn‰F£ø4 âp8dš¡™dµZqž§š~-äxÅq­ŸDKåù©N§óÉ“'’Ô€/!M8 8üÌêv»ä@¸à&ý„KÌí :{<+Y+¢i 3$:ŠpIK⮈‚´ÛíétZ,©Ã©]Ð<¾€DÍÆã±0¡I ˰|›B°ÀÂ`,3ýáU�Ùï÷ï¶¼ÞbµZ‡Ã! „È{C2}з„Ž™ ØÎÂåc¯¡PHùôx<Á`Px‰Î!ØgóRÇ€Z% 9¥%zuuµR©�Éœ¸’½ Ðg€¸âÃá0NW*Ài‘@6:Óé´×ëu:—˵½½]«Õ°‹J$H.—+‘HƒÁV«µ²²R.—ý~½^_[[ëõzdÓ©ÔlÉØƒˆvggÇëõƒp8ŒÂ†À«Ô–Ïç­Vk¹\ÆÕf³ è.Áèùý~Ç£…H^hª†Ãa.—ƒ>ÍÔxæ90ZL³ðv2úf³FÝ;ü£Ò£’ÉäÖÖV6›Eš ±’ÑhÔl6Ï]Ùá¾ETBMÎWs„Þk|šÿO§ÓôDƒÅ¨Õj`A­V«ïR-œûJó?æíU<—3—ky8Ú@CYyËh46 Ú¦X™~õ"HÛ¹÷ ­V ¦Ì`0Ð-¤ë�0£/ì"WN¦žÛíþîw¿ÍnÑ \ñâôá‡RÞÑh¤äKjuhÙïË«…Vxò.—Ëåt:•h³é_6 ¸“’.›L&ø@Ôž à&ûö-|„`0˜J¥Æ£GŠÅ"Bð£Ñ¨ßï{½Þ|>‹Å\.—ßï'Êt:ýÆ7¾aµZÇãq ˆF£ ~¸¼¼´p2™är9˜WøòÛÛÛÃáÐï÷Ó ¼ÉdÚÜÜÇÙl–N1ºF£^¯ƒöî3A¶ðÁz½þèèh2™ Î1âÍf_:é’{{{ÚƒN(¦W©T¶··åw9ŽT*%,„èp8à=aóÄ\õù|ápXâMœQnƒ\][[ët:ü ‡Ãát:Ýh4úý¾^¯'Çiý~¿×ëÝS$y>ùàƒp<ùþ_ ¿MÒ›››PcÞë§wx°p˜Heʶ²²bµZç({šN§WWWëõ:F_>÷…FCÕ1²½½-¯õ@·a<3ì*( ÔíÄ:Ñ›ŒE–ÉùŽBðù| éE}¥¾•Èh4ÚÚÚÊï>U_œh_”Ê4(BD×]&Q/yô“®ÓŒXg³ÙÔèõ£ñhú´~¿ÿàÁ2Ib±˜×ë-‹ý~ww÷Í›7‡´Éd2N´Z-Ä‘3j0?~ .R_F:ƒétZ¯×‡C›Í6ö³Ÿ]\\”J%üq2™¬¯¯·Z-bµQÏÉçóa㼺ºŠ5ûÜn· G‰œ%|ýë_¿¼¼\__‡ß@Npl^(H} æÀl6¯¯¯c+Iþ¾µµuxx8ù¡!wmnn+Ùl6{½Þd2‘ìßÑ·ð—•Ô§2dé·ó…µÌ&¤ÎO€D"ÊoNçïÿþïN'Q�„ÑiSˆ½¯Rûq0@÷-­Nr›ëõz#‘ˆjÑ ’#ŽQÝ/We¥Ušïù¹O¶ðL8O8ª„0NÈÂt:M¥Rßÿþ÷>|HªJj‰š Z7÷Âï÷#Bˆ63ŸÌW§¼ë¬4;˜³Õ¾ý¥h•Ѹ³³CåéóWúu¤“Þ˜ueÚÜÜlµZÌ]ô!®ÉdÚÚÚÒ2.|…õétê÷ûáU ë¯Ë•“?KžN§?fÊ©‡õf»ÝŽn+++WWWÄ;^[[›µ`šÕj…1µX,ÛÛÛV«•1x—ü˜!âä¦V«­®®¶Z-:Ëf³E£Ñp8Ün·ñ÷h4Úétr¹Žø&“I,[]]M$×××™L&‰` @—r¹–‡ñx¬×ë»Ýî§Ÿ~zqqa2™ƒA(Êf³µZ {dzvÙl6”$'†Õ`0ð*ˆ=5ü}ø2±XŒÜåp8ž>}úôéÓB¡°¾¾Þh4ôzýx<Æ/Þµ¾¾Î£‚o2™r¹œ°^Öd2™ÕŸÃ>æóy¡3~‡Òl6»Ýn±X¼¼¼Çt#q‰ AÔj5“Éd³ÙxßËëõ2Û\ù' ¤ƒp8Lp?ªª‹}äÚÚ\Tr‹ÍfK¥RÍf§˜Âf ÍÌl6kL/r»Ý¨Ž?™LªÕj*•ŠÇã‹äqÀúD£Ñx<îr¹.//5† €Ëå.NÃáÎ.pTw¼¿ŠJô^¤óÝN› ÚÖ{½^áäÚÚÚ¦S§¡â—\Hè‹7&ä\CueBö)ò„™A$EfÖ“¸¼.á8y _[ï.'ÀÀÇxØl6\¹—áñxxõÇã¨)‡d>S3›Í2VÕívÓ…4ƒ,f8/q»Ýð^;^C¯×ÛíöF£ ‘z‡À#@Egggv»}<#3 :Žx<¾µµ…¼DÔ;ñx<.—+“Élll”J¥ ìü†Ã¡×ë%cl4ae°Í">>®èÞh6›ý~—°Û;>>¶X,^¯w:>xð —Ë…Ãá`0pEd‚ÀòÞÜÜOæW -•%B†x¾Ûooo¿ 5^Ýn7SêǨ¥êÞÎn·ëõzòEf³9ŸÏolllooW*¬ŽBÕå‚N§»¸¸ Ñ…L&* jµŠÜnaà´HçS-KºÞÞÞ.ž;×ívñ¥———ÅbÑápÐ= ±ÙlLÒ&_—õƒA0\_____GxÖh4Æb±UW£‰_$ê˘ ²KP:=º½½]__zB#9‡£6ÓC iˆ-I"rZÊþb:X­ÖÑh$l†¦Â¯!Š% Jr+½^/CBÂ9L2îü~?ý.r \ɧòp0šƒƒ—³³3h‚!p¹\_ýêW¿÷½ïíìì˜ÍæÉdrtt4ÏÎÎö÷÷{½ÞÕÕ|‡n·ëõzbŽD"éte{âñx:ÞØØH&“^¯—ÐkbÀVWW‘˜>Ýn÷õõu£Ñ�þ \³ÙL'@ŸžžâŠo<.Çãããcl+óù|$1™L<xôèÑÞÞ^,C¾¾Ûí¦‡¦jqóͳӺÝî9(Y¿„²ººJpÖ°¯_¿Ö˜¤Š»ÀÔL+¼^¯w¹\ŸþùÁÁJR=—€pÉ4f2ãÉü¯×ë„–™8°©V«4¦[UÈ…Âcµìt:ÝO~ò“gÏžõz=F¥¡3Zøs‰ê–Ëeg·Z-—˵¾¾Nú6&–ü éçx<þì³Ï„Ý.aý¾ÃB‘0òäP ºË¯ Úyy­V}ITMè&Çb1að¹Œ}{{+ô4!/¢ùÔ邉´$YÿBúd�c/..T+ŽÐü¹¡Py›››Dƒ1ŒÂ¯,‹.— ,gv»Ýív»\®P( …"‘H2™L¥R+++Çf³„8NËåòÚÚšÉdB†ð‹…Œ}·Ûå½$%vyF‰Ëå2ÊûG"‘l6»¶¶¶²²Òëõ¼^o·Û­T*V«Õb±Äb1l=,©ÀÀKÉH a˜Œb¾;œBz½žy „W[•räóafqzãææ†h FV«Õýý}aXÛápý^1ZáçƒÜBö鬟àp8$Å ø¡×¢-Õj•ìl Ò¸ ‘ûãÄ+'qøv»ÝjµÊår«Õ¢³Ò‰ÅºÎs4þ®ôS @&¹ÄÏ/U³@{Vè®PÂá0¿ÒÓxd~És§i¡ÑÙ -NB†ÊËËK:˜0.-Fƒœš Ž\žÒ/â7é?ʱ–´K°—¢uZ¯× 0—' ›ÍfµZ@¤»Ýn[,ŸÏ—L&ãñ8v¾~¿ƒÚl6q"U­VÏÎΰ`£žX(ÂÏ ƒ`^r‰îÑhD*çãä¶×ë ¿ß‚ZœšªSf¤âñøLõ›«Õ*ã‰ÃCWj¯ÂПi›H$äf…y Ø«ŠùÅàŽF£F£ôÎ?´ô ¶4 3‹a#hd³Ùüì³Ï>ùä>ÏAf-äŠÂÞCÍyÏ Õ‰TN§SÇCšÁp7 ²âʉ¤é­˜0r…mý|®ªÕê³gÏÞ¾}Ûëõè“cb1„£ Ìâµ ’\²ÙlrúM˜ Õ·bå¹­1Ó0B *œûüºp·M‹qQá˜øÝ<>,¿3½•ÎÉÉd2ª® �Fc…T"åL&“H·Ó½Ã·Ÿ"”O{£øœD"a6›-ËÑÑÑÓ§Owvv …v¸ÈÙV®Ñh ±Ë’Á`«««v»=ŸÏÆjµê÷ûC¡ÐÍÍ |F '½É‹D"ØÅ3—”\]À#ÊåòÙÙÙÛ·oÏÏÏiõê•Édr¹\•J¬É: PIOiZ•é!&.ç¬äªD„Àm¡ÓD2DxaZȯx Ëå -T FgVWWih$Q ²a¶4‰äóyá ‹ÅÂ<†+"9¨Ñh\^^ò€ª^¯GsQær9¥ è…TâZ¦£xub�•H %ëœÄ&ΚNÉlp€D^”ÉdäȈ> &¤Ò¶0Wó‹à.$—TQÌ3qƒAÈÓ=‡(%d2{5ÚÝ M§Ìh¬é˜UaBD>ŸGî€ÍfÛÚÚ²X,…B4šƒF£H$”™–W8­N§Ëf³ÈQF†´p LÓÝjAM c€ÁÞÜÜär9$U# ¾Á``·Û‹J ÇF£R{Ñhôàà�Å6PI}0àè Ø$!Ç”ƒÁ�åøŽaq`†ºÝîúúúíí-ýáp¸×ë—ðhJäãy<žápø×ý×:îåË—¨ïr¹')æ (.Z/•‰3I"‘Èd2FCÉj¤R)>Þ•H$¦Ó©F;È·œZgï„§iFoàiXªÅF I_ƒA&à=±-ƾ™`Ÿ <ŽÁtÓÓ‡4†N4I.íõ“á —R©ÀѪ¾‚|ô±ï'¦Ÿ_ñx¹<JS/ŸÏË Ý;Ü ¬WM¬‡x· âïMHš±ðð’ææ)’g•§j8¶ÛíK!œVÒáß t ÃÕjUk¶^«ÕÖÒf³!Ù·X,¦ÓéétŠ’Ããñ˜`-‘í¦=ò((ô¥V`‰”ì .¡jo¹\&¨IƒÁ°³³£1ˆ ëõz³Ù$ø\Ô 777WWW777èn§Ó‰D°Be B¡€¹ÕÕUdô{‹%³Óé ëææuÓ5þ󟃼d8žŸŸ“©Ël«Õ"•�Â…ÛFaïp×ÎÎN³ÙÌf³¨þ‡-v$F?þñ£Ñ(2ýJ¥ýü½½½f³™ÉdªÕj,ÃÁa6›¥=Pô§S@&j—•••D"qyy)÷Äù÷b\4ªÓrR¼ƒ6ÄDg677IY9zyÀU¤™ÜÜÜt:¸ù^¯÷ôô”¶È_ºm]È@zñiäª*Ä•ép¼ˆþr•\BÚ±ü™ ú5•J ú‹à,’èð.ñMK,[__Ç'éU¯×Kò§WWWIe)t-ðMµ(Ø‚J¨ ö¿?™L&õz] RBË8jé¥@ @CÀß­å±3¡Ñ•à´J#%ü;îÂøO&~qÒÿÁŸþèâºfÜ”^üðÏÿüÏuïR¢1cƒÁà·¿ýmT3ûä“O˜‚Ó<üÊd2Í´³<…S©Ô›7o$?æ_GꣷWã½8X¢Úîîîëׯ…BÇÇÇè‡|>rrÒï÷M&ˆ®G£Ñ“'OŒFãp8´Z­HCèõz(Œò ÏŸ?ït:&“)ŸÏ¿}ûç€ã­¯¯{½ÞçÏŸ£Z0›´–üÏæææùùy¯×3™LÀÍôûýX,vvv¶²²‚ÜBBu:ƒ¡ÂüWG¡;…͘u(…}®ûe é{¦¹\ŽÑÆ~úé§ZÔ�1Þ|>¾Å|>ŸÓé$§é,ì ƒÁ°½½Íc0„¿Ïår8ÏŸ)¶ÈY™_ôÉìa±Xôx<'''LGÙív~J2ß%bÀòh <} }õNÔLU çÐÀD"@‹Òw1â÷ûN§–züDÿJHR·æû^íß‹ÅâñøÑÑ‘ü\ûÛ#f¾ëÁƒJS’ÈG}ô?üÿæÿø‡ýv£zöò§ÿý?ÿ¡AiÙÞÞF‚ì×¾öµ\.cÆñ_¾¾¾>ÓÇlnn’N§éi€˜¿b3—°ª%‰@ ÏF›N§@WèÞåž2§ÄŸþùx<¶ÛíN‡ìH¶··a¶œNçãÇÝn÷ëׯ±a±1ÕjÕh4Úl¶Ñh’ÜÇ?|øçUÙlÖl6'‰P(´¿¿? =z„]Z:v8 ¤[ öOÒÃoÞ¼I§Ó&“éÉ“'àz˜L&Ïž=s:$™!G œb±)IÎKéÿÒcçr¹øŠ÷ æàj¯1¯”©,gŒ Dg¹êt:•L¦=ÑhÔëõbi'?¨V«Ów¢{G©ä Ñà�š‡üñøøx¦• -¤ € yÚ!ÃiKS»3´½½ŽE¸Þëõ^\\0ynȦ¡«C?ɇ~"Äcä´ŒV§étšËåè‡#2·Å˜umžµÝ/³B»Ýn¥,;èŒÐw¡³éè9Λ ÒÕ™Lfî(ýÉÓéT# X,>{öŒ†ö ç¾êÓìvû£GR©£Nª+“Ö3§Z­v}}ír¹öööVVV€•«Õj8k•Ljg­)P.—1Ì8Ĺ'ãN‡Á$ø½ÁG1•J•J%æðÐívO&“z½šÍ& ¡ 8©¾ººÚÙÙÁ s¹\rA’z½n4ºÁB‰DþæoþNP­V….иV«h†ÉdbµZa"{½ZëñxF£Î6h[†š˜½^—êõºÉd"1ÆÁ`€�7sCõ?¾?q*†h'?ßâñø‚ž/ˆGþâõz•�•°*s) OtäÒjµ´T}¥Q“V«Ûù-§˜Íf¾@ÀLÂŒ#0¶�ƒÏÅ´"£o³ÙŒFc«Õª™L&ý~ÿ›7oxTo6›-•Jdô‘WF³ä æ‰õÉï÷‡ÃáÉd‚èãt:Ëå2=Ü Òö^«z½^›Í¶HLÕ5ÉI°ö|`fäÀ]Ñh„¸$ÄçêÞ1²’ >«�5A>™™& H\IVWW?÷3™ Jw¢„ oO°Ño4P'§Ó©”ˇKP<´–ë™$9?ÿüóo|ã&“©R©Ð&ÀqJ™Ä‹‹„ž„¾ ™ô$ŸÏ‡X?ÈdéKØ#¯¬¬¦Qf<®¯¯›Í¦Ï绹¹A1ñQ‘Ó`0T*À8Ày{{›H$ƒA¡P@J÷p8<::BÒ`¯×ûøãuï*v æ *›Íf³Ù|~~NOW¿ß?Pÿ‰.®¥{Ç3ËØkš…q…Ñ!a=rŒ#JÙ2eÍF£êá]<«ÕÊLWUŰX,v» ¨“Ïç;880›Íô™<DVe.½7 ¸ÒWAdÊÜáÛûýþùù¹ä’ÑÇ¡P(ŸÏ§R©v»]­Vüã+ÆßÅt/ÏvzÕXËåòÅÅÅð1ìc��rIDAT“'OxO€ôñxl0‚Áàd”i—Å 0ïºw|ðÚɃü~?òxÉ’O’°qéž”ç J㈕@uO¦t¼R«Õ@³�b||ÌÁ^¯w}}MJÍe³Ù³³3áŠV<»Ý¾ººúìÙ3áH)¦’ŸžžŽF£ãããýý}˜WÁÀý~¿ö¼[ ‰–Ýn—` \.¸h±SŽF£‡‡‡LÞ=ðbà-Æ%”òt8àBUÚ™–J%“Ét}}üoœ0ùýþd2‰Jš »ÝŽí9*³5›Íããc³ÙŒxk½^?88èv»oß¾àææ&N)Ûí6 gXêææ†‰<œŸŸc'a³Ù„xd¥¨±†Kšp½>7‰ß%‰Pë~$Hðª8VœÌ!´²²b±X`èAò«}ò^U¤íß;‡á´r ‡Ãó…§ÈY(ŒFc³Ù¬×ë‰Db{{;‹M&lÄå \Õ8TšYÀ˜Ê7<‡ï¯–âoUgØ ”^ Ê^‹Â ½º‡yM«T*ª¨/Xá%«ÕŠÑ¤á´f³ô=LGéDl™´»ƒz§§§JC†sºººòù|ŸþùÉÉÉþþ>½�2ä•Ì¡+?Éëå§»r¶ÜÉ;‘}’8!MØŠJ‘øËññ1˜pù ÙÕÕU(zûö-�•···ÝnW¯×“ˆóósܳX,ø ½^ŸÉd>ûì³çÏŸ#òS(@Aºë u@“$“IœUŽÇcPÒ-I§ÓØþŸŸŸ3—C%YÈ<A¨Si!éU°â]ô%BŸu3ÏǵZÍ3H @#C¡Åb!OÓÈŠ­ôE÷¼[¡[îr¹´žÊç—Fi·Ûz½Þãñt»]ƒÁ@“§Ì”sÁ %Ah2n"óÌñxŒé3k³­V+plw.ödþR¿ßÇWí«9êL‚€M'Å8ky,]Hz¾– d"Yø«8n ¾o¯×#hàÒ”žv}}=ÀÁæAý̉;�`”Üúý¾¤# É :G)tK¸Ž˜ÍP"‘�ìp8$ï’0n @Æi8¶Ûm”G‚–I¥R¨�KNü~¿Á`�”äøøt#Á`Ð`0Øív¤k£hØþþ> ·Fãìì Õ £Ñ(bëÉd²T*¡ÔX*• ƒàÃW(y1˜Ãª¸1½^˜‰¼77¯\¦ÉÈ Ø=äï%ïâISœ8NDÌs2™Ð§;¡P(™L:Žr¹ «Õ*VkP9á÷Ê•p{a2™äá»l6ËpÄÍÑršµOâŒËyHiøPœNg0·i¯×«Õj?ýéO#‘Â)Ây'™Îòƒ:Ô^A�cñZ¥³*ÆLOV"—\Rå0d��»sDÒ·ZèÕ›&,LNÏ}a0Mþ"áU ´Á`X__Íé]ñøñãÌÖ#MgN˜6ˆ.5 —¢áp¨tÄÅ“ÑÇcíW6›- ý~Ÿ©¬\­V Ø¢^¯cþ |ŸL&»Ýîh4B6+‡ñâÅ tñË—/Qmžì]šÍ¦Éd¨(‹u»]„ãð4,u¥R Ôs.\•••Z­–L&ÁÆD»:mPüN§ê^¤­g³YÕŠ¢¼óÂx^´½Ëd2L%_毛››oÞ¼©T*dSu{{ —‚þ! GöqŽ`%Á¥`0(?¡Q’`0h±X”N,b±ì;ÊÌ/25€f"3«««ûûû>ŸÏf³AÙàœÊ½uy3|¯Édât:÷÷÷kµZ«ÕÒ²KBäÍ~¿Tõùv{ðD‰þϧZDâÔ¿\”ÓéDA€b±H>ðóTufñÚóôtÆ.ÂápHfœÏç Â#a5Nƒê䟩øÄƒTJ®A·Ûô#Y@Zäòòr0<xð€Yá19wvv`4»Ýn¡PˆD"‘H…0$á`Pie³YÄ R,‹a±!mÖëõ¡PèåË—¥Ri4w(cÜᓃA«Õ›¦ËËK³ÙÌlÆg’««+t˜Š?~Lj­®®bÇÆVzûÌoݨó¿ñà"RD¥s~ £(;é¢ æÈ½š¨U¸¹¹)ùLŸÏ'Œx(é bü&“¡²U¥V«‹E%¹R©`6¾zõêÎÉI0_[[k4$H u2ÛÛÛJ›c%oS’(áñññÕÕU³ÙD8wŽ’^Èr"fN-h-i£ùEUÃ{ŸÒív÷÷÷y·Ûf³ÝIz=)t ‰Þí!G™_Jk˜ÒÒÕn·ùÅÒ@‡€N0ðM&S§Ó¡uqss“·wÄ›Öëõ¤Þ»Ò>ǧX!2™ } «<FNp/¼··‡…„#e³Y’¨ír¹PŽ @(Úš`)º¹¹A•Rša8ú|¾'OžX,–R©tzzÇÉ1{³Ù<==F£àìÚØØp»Ýƒáèè(›Íú|>Ç3 pv²»»K¢ HëÉÉ ¼$œaDC¡�¤gœ_ûIudp>þœxÐÇÇǼþ‹EÄÐ$¦§ÓéüèG?’Ð*“hžp+ wòFŸÏGª¥Ñw½}ûV¾ZwÓéÔår ×-`ÈðÿJ)C’ Ÿd"•¤ Ã|l4F£¹\n¦…ŸGFãððÎ A3_¿~­ºçcÐ3¤çƒÁ`*•§a¶B<ÏLEé¯W]ZS)qCⶇCzôI÷2“ý°¶¶6+‡<Ð2w&È|ƒK†9Ùüëõztüƒ(!ݤâ3ogfjÌÎÎŽÒ%yã•ÌB½^nŒT#ØÈ `ÿúú£þð¿ýÛÿðŸ~ðƒÃðón¹ÄËÎÎŽÒºE»Hkkk^¯—¬®V«•ô,¬@彊Ïç[YYYYY!ÛIÂ¦ïÚÙÙÁU³ÙüðáÃßùßÉf³À$F°f0&ƒé®L&3_˜…·Û-L÷ Á€‰Dâ}NÈ{%PªûÅàU…Q{œŠ“‰�¡ßr·T:v»žtápøáÇ‹sq‰D"Àª¯­­ÝGâœÉdZ__>÷nŸ ï)-â}Êêêê¬ ¥ét: ºÝî»Õ4¹7èÚuFuf å£>ú‹}ò¯þãýÿîO¾ñ;ÿºT¹,¹'''ØßðÜÞ'''ÝnWhÚ^¾|©ºO‡õz„b"‘ù «ÕŠJwð cqzÄüÌåri¤oA>Þíí- ©½zõªßï W~Æ- ä®×¯_' Ä2™L¿ß_YY!Õ¯ÁM‡£Ñ(ÑKÇc4³Ù,‰Úív¤T.Â=ƒ’E†Ùl&sûòòòž`¤N§Ób±Ì]`ÂáphôNˆÎ0+Ö|Fåk°*WÅùù9¶¹d"Ôj5:#eeEn2 ÃLìjñxœ†˜”Ëå/^Ü!0¨T*áhóàà@KÌ §3vö÷÷<½[¥º¹¹Y9^.MÚ¥KrÕ=::B¸[»bœ9Îõõu^ÓœN'Þuç¾&oùµë Œ0}€D7o&³ ÞÊOz§´¢ç¿ß‡7×ívQЬ\.“ ©×ëq°/~÷Ã[Þ¾»\.aÉ,Â] ®ÅFÛl6óz€‚xÎáááÑÑQ¡P888@q³³³p8Œ>ÒŸÏ7In$JÍZ­Ö@ €Æ›L¦98o€µ^Roκ_áu ‰€½Þd2ŽÆ/k›ðïÌ8áÕà[ßú¿ ¦k\U«U%¶lrtt$ë“A…*Õ"šÇÛÍ÷�&ãÿ†B!~Ò GŸ† P£X­ÖE¡ªa¹»#ù¢P($™ŒÌ%—Ë¥e°$SU¸>={öŒW —Ë…šÉ ß•:Ùl¶H$" QÔj5ÓB7Ïf³Ñ·ÈkΉ'pÚ*Á¾f‘iÁçÊ·º°S�o2«,_(øc‚ŒF£t|– Ü•6§ƒ&®µÛíÙl–„YmŒ«GGGGGG/_¾•ûd2ÙÞ•JøGT)<;;£™°Æ££#4~VD*XË÷°ë"mm6Ûƒ†*‹ív{îýêQ GDËÎr:îïï¿}û–?b}(]&T€ !VÖ¡×uäÜÓŸp‡Þ!½IbZÕå‘sóñkñxf æ[,üÎÀÈK~ ±if³Y)ý‡7A¥RIKöQŒ¹Åëõ’”×™ 2}ŠÉ;ëÚG5‰ÎH0ÂtóÀžC<ù|”¤ÝI&Áêõz%ˆ™dœ¦ÓéL$¤üJcÇ€ פä®R©”Íf1œ( ’N§½^/öC(?€Êr¹ŒˆJ¶D"˜Z³Ù¼³³³µµ¥äkÐæ‰ æ˜ÃÖ~—ÑhTeÝFŸ»F‹ÅâÞÞ^2™\__F£<£±Éd’dòhí¬¦ãñøùóç¼æ,bT©K…†�“V#«)ÐÙÌÔ+•J±XL#Œ}>Ñét···LüP ÓM�øMCµ=(†ÕjÕŸ+!V–6Š`óçFgäÉN{ß2äÜëõz<šUr‘g¹Oœ{í‹I@SÿèªüÖoýÖïýÞïÝk‡z½Þû®¬åv»‘½}‡wƒÁÛÛ["F}*”õz½ô%£ÑHûMIã“tš ®´8†Ì5†G€ÿ׸r»Ý³nqPÊ–±‰Ýnœëív›çcÕ½‹³ßëq×½jšÉd²Z­3%à¢âªöDA¸Ã¼@56-Z=ŸÎÌ'MCùÄv» Åp»Ýw^Aø‹»Ý.!Vu:¼/ƒ Òüâ°è{’l6{\SXœ²Ùìoþæoê–²”¥,e)KyïrüWÏÉ]öÈR–²”¥,åË&ÿ¸sêv»÷𬹔¥,e)KYŠPøÃø\œþìÏþìûßÿ¾ð6-ø¯;ùÍûyˆF8ÛûyÑ—§ß~åºîË3Fÿ4»åW«ÿÿiΑ_!Óñ»¿û»{ßüçâÅIø ü]~†ü…ü“ÿ‹ð¿’K_àëÑ⯛éi3õÒ]5ûËÐø¹å>ºb¾ÿ2O„_éA¹[Í|Ïóî=ñ{3†s´í¿ÿõ zZž9-e)KYÊR¾t²\œ–²”¥,e)ËÅi)KYÊR–²”åâ´”¥,e)KY.NKYÊR–²”¥,*²J‹_·Zÿ x¨,@I>àn·ÿ¤Ó,;u)KYÊR–rO‹“^§ûgGb–:ÁÓew.e)KYÊRîBda½oÎR^·?>‡Óå µ”¥,e)K¹·“Ï`øÀjÅ~h¬´äèõ†wëÛÇÃáùx<‘Æý–²”¥,e)KYhqúŠÕjÑë_ ‡Ÿôû­é”^u�çÕét^ƒákKÆdL§ÿg¯w+e]ÊR–²”¥,eÑÅiÃb9ÿ—jõGÝnO¡pÅc‹eÓçËètŸ ‡?î÷;˘ÞR–²”¥,å^§ÿ§Û=ØíŽjöYõú]³yÃlnN&ÿ{·{8/—¦¥,e)KYÊý.N/ƒƒ¤”lÄ`øžÝn×ëÿ¯~ÿÿî÷ÛËmÓR–²”¥,åŽdN®Y¯ÿšÕúM«õd4ú‹n÷èKIK¼”¥,e)Kù§µ8õúÿÉíÖët?ìõ~Øë-—¦¥,e)KYʼ8YôúÿÙëÝ6›:ü¯­VkÐ[ÊR–²”¥Ü©h*�1¥–£N÷ÏŽép\ŽFÿ¥Ù$= Q•äò«ü?µÿ@ã+ø«: l]wÒÔ»ú÷Ö’;”ûý»bA%ù2ô¹ö¦.ø!÷­~s÷ùŠFuÕÞçJ?»«yÿz>·9Õëõ¡PHqqJ§ÓßûÞ÷TW)çþþïz“©™ÍNÎï,·MK™]àîL—ʳ”/±üä'?ÙÙÙq»ÝïÿÕ———Fc{{{Áç ‡Ã¿û»¿ûõ_ÿõ™î ÿðÿð­o}Kþ³ƒƒ³ÙœÉd$¿ùÛ¿ýÛ'OžØívþÒüã§OŸÚÞÕ!úîw¿›|ð-ñâôÛ¿ýÛôG$oÍäì¬ÿû¿?þ»¿Ó»\Oþý¿ÿß~ã7–¼”¥,åÿ—òï|çÿøÿßöî&¤4Œø3“l"³&"Xô U{1¢Ðªk!ô0âx¼ÅCü¢‘ţ Jé"x‹"¹z‹DDP¶ƒõ#jm\ZIš¶×Mš”_ùØÃ¨uÕÕDM"åÿ;%oæe†y23ï¼oNNNôwm0VVVn<!ßÈår)•J£ÑV¯½½½ÒÒÒ{õôôÈd²æææk¶)**Òëõééé—*((Ðëõiiig-coÞ…}[ïäß®×{üêU`e…ü~&%Eðì_�øQ544¤¤¤Äd× …âòm®[ˆ‹‹S«ÕáöŠ¥—R©Œ»iþU•J%•J¯ü©±±ñú«Ræ7ýŸ_ÅG×ü’QVVvͦ¾™™#­6°½M #¬ªŠ{ù‡/��Ü‹±7ï&Þnþãq}üsáõp_¨£õ»»¾ÉÉ€ÝÎe ¤��"$äâ´´ä_Z¢ãã“n#w��Ëât»ý‹‹ÁÏŸO¾3 óèr��Ò€ˆÀ‡þ÷ïéÜŠLr2r�p/œN§T* …Dtttät:‰(111!!ßÀápƒA‘H$—Ë£Õþþ¾Ïç;?lagg‡ˆÄb±L&ã[\.×áá!¥¦¦žõr»ÝD”””Ίµ·ºrr8‚§O›NŠÓiÊ��à.¬Vkyyùöö6ŒŽŽrÇqÜàà Ëå"¢õõõššŽãÚÚÚ¬VktÊÒòòr__ŸV«=k´X,UUUÇi4›ÍFDv»½££ƒvuu•ˆ<N§ã[ ƒ×ëpqúö-èvÿ§I$Â!�pGg%Çf³ét:³Ùl6›ÇÔÔÕÖÖNOO›Íf•JÕÙÙ…¨GWW×ØØØùÆÊÊJ“Éd6›ëëë»»»‰H«ÕrÇGËÏá`2™ÖÖÖø–ññq‹ÅÙâDB! ¿ß�d¤RbYU��w4<<\XX¨x`ãŸ322ŒF£F£‰a !Õ6;[ðü9I$IJLR’°¶öšuž�� sss‰D7s®¼& e#Á“'¢/››tpÀH$‚§O‘8�€»X\\œœœ¬««ËÍÍE6nYœH,ääb1Ç�ÀikkË`0ðã,KSSÓÄÄÒfq�€{UQQ‘ÍV«Õ---" 4Cq�ˆ-¹\~öÒÿä‰eÙÌÌLFÃÏÕÝÞÞ^]]MD³³³yyyûûû###± x~~>++Ëçó Qooossskk+-,,QII‰ÕjåãïïïÏÏÏ¿õî˜ø��"! žeÆ/uv¹åBcLâ¼ÃÿEn¨&~Å•�@Œ]8_>­?ÒW†¡hñº��<8(N��€â��p!1,{,ˆŸÛüúÑû�€è³ÿåaÏÍ“'$"†a‚?ÅÛ<~›ç ��Ñǰ,Ë ¾§@ àÚý„¼��@Ìù}'ë­ g^ŽO_��ˆ­ß»M–ýü/Æåžq,~����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/gui/color.png���������������������������������������������������������������������0000644�0001750�0001750�00000000663�11332353405�015242� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��g���.���â)Ë���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ "çö¨��@IDATxÚíÛÛŽ‚@@AÚøÿ¿Ü>h” Âp13@ÕÆuYmÇÄ#D"3;� ÀÍ�€j��PI|¶"úýŸÓ¿–ìó§»]ñÐÇÞ¬µ&í¬íù^«½‚í<Š'¸Ë>ÎÐ@)Õ�Õ�Õ�Õ�Õ�Õ�Õ�T�T�T�T�T�T�PM�PM�PM�PM�PM���®(2Ó*�´ø­¼Eï>É–;,ÿßÂ=§wüÕZ�p¬ �{s¬ �ª �ª �ª �ª �gq·�ô ®PŒˆçÆìuç\4êêùU€‘ð|—é½=zcÅ!—Žºe~ghè*&p…̬5§j€jpÆMÕ@2Á·�x…SDU€yƒ«2$óçg KÀà Óõšª �[ù6�¨&�¨&�Ôò�5͇CÉ'=����IEND®B`‚�����������������������������������������������������������������������������./saods9/doc/user/gui/menu.png����������������������������������������������������������������������0000644�0001750�0001750�00000001704�11332353405�015065� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��h������iuë���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ'Ž[è��QIDATxÚíœ[rÃ0EÓŒ7àý/ÒÞû‘GŒ$$眯NÛDpAä´Çq¼���@Ç ���ô,¯×kßw„���`â�� p��P8��(œ���N��� '���P8��(œ���óXnc]×ä÷·mûühÛ6+kⵂ7?W¼.ÝbFüÚ« †®µû>—œy¶9L¶é:V•Úc¾Mô‰Úiiäíma°„pn$õl ½•³u/ ­[’Á5Ü&‹ò÷Fª¯Y«·=³²Íy–_q]×mÛl NöIÞvàÇq?VM7©E' ŸÔÓ6ôg2 Öo–L/§²>wÔrsá™ÜÕéøy‡óµÂD›³¬f_ÁëØÙëŠ×ï_ MR:ÛAáÖ/½g>Ym“X W/m2¥8¹llá­ž*ÙõÈJz'ÄQ¤4ÇU)ïm¾½m3/’ùÑœëªzoª®•6ªIK®“_ðõxûƒÄözMã—¬FËa—\±Hí1Û¤té)!‹“\Q¶°E1ád\èkÙ»º$™˜xßX5e)4ù¶”~@·’ër[nÊÝT|ocÒ'uöÓ!Þö­&¦z{6 ƒ»7çwz¥ÓLéF¶JªÜGZBo.þm-ÏÝ$bNŸ7Í;­â©y/«ª68´É+ÐN®Uø^±Û„ÆÉ£¾)y";~+µ·~¿=ˆ¹öü1“2ôVÛ°B7¹À(ÿÎ;Baâ¯cqµÝö&\Ë=±xXh¼íí«=·£’&FO=¶âkWwÉ2†¾(¥ÏV‘B§/É)x«òÿ¤‚ZÍ»ÇAÓ©Óì×Ë+·úÕµà)ÚW´rýBóÔªÙOØ–XÄu=‡56ÏçÌý-zÊ"ç.Ì~ùOSJ÷ &ú‹UæÅEŤ@že)øÀ¤ÜêöèU§7ÑA§©ÜÞ]C3fúOº0,.±Ô‚rŒ mN¾•ðæƒÓX'¹‘çn4MޱJ³Íceõüb~î)4ƒÐßqû¾Ó}��W _$ êMLKþå� :•~ù!ÌÏw˜…�Fð³ŸídX\Õ��0q��P8��(œ���N��� '���P8�� ø8ÇÙÛ8�����IEND®B`‚������������������������������������������������������������./saods9/doc/user/catalogs/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014411� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/addlabelsds9.png���������������������������������������������������������0000644�0001750�0001750�00000627115�11332127303�017473� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ"Ú0ød�� �IDATxÚìw˜UºÿOåÐ9NwON0C‚¬aÇËUWEtw®UÁQLq”•Õ5"`¸¨wEEWEQÐAÂ03L==©s®~¶¸:¸¬wýÝþ<óÌS]ýÖ9ß:ç­óVsº¤ªj0ôz½>úhOOøAÚ{#.‡dÉ’%K–_*PƒáX±Û2Dû@ àt:‡h m6 Ã?l–——wÿý÷:4 ®ZµªµµõÑGÍÏχ �ðþÿþ‘¿ßtÝo³µ˜%K–,¿$Y~{Ó»ÿ}÷¥Çýpó®ý饗æÏŸÏ0ÌPŒ_{íµ¹sçJ’¤íÑvÞÖþ÷öö>ñÄùùù7ß|3êõzÛÚÚyä‚"‘ô-0 Ÿ¼-JÒ‰å>¬ÈÕÕ)/Ç’f…h"m1êtÞãâ8Zä±·t ��F—çÕµö��F”zš»dY)ôØ¢ &‘bíŠÂÁ8Mân‡¹ÝlŸÙ(Éw„b +¸ì&YQ‚‘¤AGÚÌú®Þ CÅž£í½ƒíË ]Ýý!^rs,,'Dâi³‘ÖÓdÏ@Çâ<gsgÿ`ûÊOk÷€$)n[<ÉÄS¬Í¬Ç1´?£H,×imëö¶Už×ÐÖ£ª 8ψ$Ò Ÿc3ª*DzštXô½!†F”xÚN–ãˆp¼èqšyA ÇR&mÔ“¾þ†"¥ùΦã…U»Û}Q’óÝÖDŠ‹'›YOàh_ FX¾ËÚê=NØÈ²Ü£}ª¢çÚƒÑTŠáœV#8¡£ §ÕØÙ„ 0²,¯þø.+Èé DXNt;Ì‚(…c)“ž2èîþ0ŠÂ宯޾ÁöËÝ=A”ó\ÖÃŌդ£H¼×%p´ÀmoõžPõ¹M}Š¢åÚñT2Í9¬†BqšÂ]vsÇ?¨úÒ|g0Æp‚Ëa’$%Mõ”ÅH{ûÂ/rm?NXÖ'³>ù3ød?�`Y6nÌ¿·…‡ HQAB¡ÐØd¶E‘eY3þ{‹ÅòÌ3Ï,\¸Ðëõ"¡P衇Â0ìGS‡ èÝ/[`bÒ©_ЛN¹-d:•ìé 1U‡«m=’À”äèë[º‰øØbûáÆŽx,6²ÐÚÔî ‡#ù:ŽöõûÍŒªbGw/…\ ÙØÚLÆÇ|k?¶Ô~¤©3‰» }þÀ€?h7`²Àz}ýlz´¹Ã—N%GXj;‰ø¸{mcG,–kêòõ‚!—™`ÓI_ï�…)jíê9¦Ìm¨oîJ$âcKìµGÛc±ØˆBKK‡/ŠäÙéh4ÚÛ0‘IíÞ>UâòlôÑ6o2[l¯=ÚÅÆ”Øë›»"‘hQŽ~ÀìÚô¨*r]¾~TF¼©½;•LŽ.²Ö6uÄãññ%öÃG;bÑX¹ÇèíB9f‚eRÝ=$ª˜H¨¥Ó'°érQ6N³Å* ,­]=¡P8×FÅcñž>¿�$"·wõ*"[à ¶z‰ø˜[mcG<]lkhéŠD¢…N] îXiÈBgw¢Š9&¼©½;™LŒ)ÒìããJ‡¶Ç¢±RÑ×ç÷BNγioO?Èiíèa™Ôð<SݱsnìˆEcùæö®Þ`(ì±’ÉDÜ×ç×ã€F•¶®^Y`‹œº†¯Võš°QEÖÆ¶îp8RàÐ…Bá¾€…F`EèðöÁŠà6“mÞd21¦Ø^ÛØÅÇ•iEK܆Þ~¿ßr1‘gºzpH¶ÑHK‡I§*óÌGšŽU½&lxž©£»/ g}2ë“?Oz}ý"Ïþç™e,Ëþh#Ãð‘#G&L˜N§µ*��‚�C� †áŒ}CCØ1cX–ÕŽUUí{(s,à kßNš4éþûïG}>_~~~$ÔÒ³H—UŸÉ¾?’N±bEMK� �`¤p‹‡ (É Ñ´�à±ÒŠ ‚qNd†L4n¤qEU£)>ÅJ(¹­t8Á§yñ4>»b7’¡ljrf§EO˜iœåp‚eÅn¢�µúÂN³Îã4hî3ÒøèR×—uÝ41¢p_CPÕ¥îÖÞH4É•äÚ^îìzlF³Q¤}ÀD#JröÖwëHlʨ¢Ïk»p]ž[×H±bY3’ä|xÓL’DCWÀ¢'Ëò_õé)|rEþg‡»(7<ÿ@K?/HËrzéHªÈe0Òä 9Lº<§å›æ^…)s}q¤›&°‰•_íQuD‰»½/I°Å¹vNT:ú¢n«Áf6në7ÑÄÈo…MY´»Ö‹"ÐèrOCW0™Jó±´Ðíç;Ì4MÖwÌ:bX¡s_ƒOOâSFçï:ÔIâè¸ay[8AV˜ÓeúéB—F¦îÝH¸¬û›2¼4N¬(øúh¯¬(•%®ÎX(Æ{l‚¬¶÷F\½Ój<ÔÚo¤ñQ%®½õÝ:›<²ðË#>£Ê<ÞP<-”æ;¬èˆå9Lz=Ußá7éˆáÇ„aS¿6vXÞáÖ–—Ê (ÓJæXP kômºÈc«iì1Pø„2×îZ/…£*ò÷7öJ²RQìòúÁSì±I*ÔÖαè]vÓÁ–>MØžúnšÀ&(ÜSïƒ!0²ÌÓì‹ÄR|iž=ÅI]±\»Éh ëÚý&QQìÜWïÓ“Ø™£ò?;ÜE È˜a¹µmþ4'–8Cq®7˜,ȱà8~Ô´È’<û×G5aîÏk»(?<ÿ›æ~A’‡»|Ád š.r[³>™õÉŸÇ'4É$��àGŸo2|fûP{ðþW÷žÐêÞqÙÄ˧Ã}ÁÔk>[ì¸kö6#õY­ï‘7¾ºúÜʪFÓ$¦èø|>Äãñ\ýõÇí®ë}ðµ}íýñ…v³ž„a¸£?þ؆¯×ÒPâ¶¹Ìmþ¢™4XIûÏI“KôN‚…eÞbôzýÒ+ÇM(µÕµvÇy8ßi¼bjQ¹ ªÈ!ó]Vo ISä—Œèðúú¢<„*€OË_‘Ë8÷œÂúVoœGTUl ‰«§—”Ùá‘æXŠ ¦ä/‡œË¢sXôÛ‚U˜c:Ø$p¬Ømjí‹q¢Rê1‡ü@Œ-v™djïOxlz³>Ò²©‚ÓþÖ€ŽÄ‹]棾ˆªB%s” %ø2™•®@2ÏnÐQDƒ7â0ÑyNSM‹ß¤#‹rLGºÂ‚”¸MÝÁTœË<–+ö„ÒN†aM=Q—E—cÕh Xôd¡Ë|¨=H`X±ÛÔÞŸ`¹Ìc§øþ([ä2ª�jë‹{¬z«‘>ÜqLØ7­šÄ‹]æ&_DVA©Ç<eƒ ®Ìcæ%µÓŸÌ³ :¢¾+â0ÑùNSM³ßH….S}WF·ÉLE¡ÌcIq’/”*pkôEs,:—Íp 5`Ö“….smGÃÐb—¹c ‘æåR9šú"l±ËAHk_ÜmÕÛLôáŽÕ@䘶(+r›š{b¢¢–z̈s¥n“(«É\»Þ¨#ëºÂv]à4íoñh¢Ðe®÷†!)q›zÃéHJ(˵¤y¹;˜ÊwèI?ÚÍ1ëÜvÃ7­³Ž,t™j;B†»Í]þDŠ“K=æXZì0E.##-½1·Ug7ëµ5a‡Ú‚$»M­½1ARK=æ`œõǸ·IT ŽD®MoÒSG:Ãv#]cü¦Å¯§‰"—ù¨7¢BP‰ÛÜfÂI¾<לdo •çÐS$q´;â4Ó‡qKÀ¤# sLG:C‚”¸Í]d‚•ÊrÍñ´Øf s ‚6÷Ʋ>™õÉŸÁ'síÆðâ3Ë´±œ}Щ­­8q¢6–³ä¥/XA:!äÔ4õÏ>§’"0‚êëëÇŒ£¥üè[ûûÃé¾p*câiáÉw¾QUÐК>:?ǪWU†áuëÖ¡™ÑžM_´�Žt†žÚ|à9SIùë¦ýMÝa�ÀÆÝMçŽ+„ �HQaš$J\Ææ¦†ÏuDRBJ!Ç /@ÄðŒDû!ûÄ2ÌG_zk«ÙU|ÇUçm‘;bœ"KrÒöðb³Ýi¦ñ¾(‹£°‰Æ¶ì+°Óg”Ù �vDë¼±ùÆñ%Ö`œ7PèžÆ`Ž…WdޥŽÍÁ@ŒÓÔŽ.4-2ó¢"qi(¬7Ñã´øB 'Ê%9ºÿúÖÕ—^XiWzÓ ft[I×{cšÈ1ÓM= E…Kr Þ KIcŠÌþ˜à±Ã<FNR»©<»Ž"°zo̬'íF²¡;Ž"h¡SßáO'y\±©7Âã|ež)Áʽa¦Ð©ÇQ´Þs˜(‹¨óÆ(ϵéZûS ¯Ž-2ùÂl8!Œ*0‡SR„)q�€}q—…6Ðx]WLO. ÝÔ›Tx¸ÛÐd£)qL¡ÉŸýQv˜ÇÈKÀHæÙt4‰Õycfi7’G»0‚:õtü;a\ež)É)=¡t¡CO`h7æ0PQïQžg×µ÷§Ò¼2®ØÜâ ad)š’ú"LIŽ‚‘£Ýq—…2ÒD½7¦§p·E×Ò›e0<×à ±Ñ¤8ºÐLˆQ¶Üm¨«?‘k£u$^ï™t„ÓL5ö$ )Ê1t˜xZ[dêñW‘kLóª/”.pèH«÷ÆmÒf ë½1ÃòìúöT’UÆ—˜}!.”àG曢ŒÔfŠsôŒ4tÇsÌ”QGÔyc:wÛt-½)^£ Ý!62HX™Û +P[Âc¥u$^çiÂi¦{*ç¼&vL˜ˆqÃs¬ vSùvI`uÞ˜UOÚŒdCwð‡¾c `åñÅ&_„Åùù¦#÷…™"§C‘oÌi¢Ì:¢¾+F“¸Ç¦kíO±"sL˜0ªÀ¤U}©Ë �¨©'á¶ÒYŸÌúäÏà“uÞX¦‘ÊèÉqãÿÐ÷w/Áßg|õ9Û|QRv×õì®;6ùùÂ3Šs†Á‰£™îûÝ”›ŸÙ)ËJ]ghñ Ÿ)ŠÚN�t$vÿœ³2È� §¤#]á³ÇVŽYñUkhÇáÀ¤2gSGwoŸbeQã>Ž™ö¶¶øYLv^A)%!°(��ÇÐÊ+ }¡PÕ˜ò}G:Æ”44D£ ðÙî¦yÉ™SÂÞ‹ÆWz;Z•xlìä1þžäŒI%ï~ôåð|ÛYEº÷k^Å<fê¢ ¹­Í’ÀAö’aÅž3‡;^Ûð^2Ÿ ‡©²SG:£W9.6à,v˜(¬¥ŸA`¸4‡®ó1‚¤N.5ÖùFǽ!>šËrti^é‰ðNIáhë�Cbh¾jèeD L)5ÔúVÏ(6µø¹# wë£i¹/ÊçZ)†[瘈Æ>VVÀ¸Býáî4/*“JL ½Lš—Gæâb .ÚiYÞcÖÖÜÏÀ\îÒñ¥I\b¬ëaA[`쎑¤XêÔ1‚ê sIhë�ƒchªïeDIÍ›XljósqFæÖǹ7Ê{,ŠÀ­ŒžÄ]f¢±e0å;aæ†^&ÍÉ#r „ä 6ZQ¡.?cÒVÑ<À�.wëë|i^T'—˜êz†—Ç{"B8)–8uœºÃ¬ÝHê ¬u€ÁP´ÐA7ôWŠLíA.ž–†¹ô Vé‰òn3…¡Hk?C˜ÛB6ö²¢ ¦”j»VT&—šŽö2)N®Ì5“Ò@LÈ·Ñ*€Ûü¬IGØ Ds?£ªðpþˆ/Í‹ÊäS}/“æåÑù†Þ¨JˆÅš—@wˆµH…µ0(Œ;éúã…/2vùXZ,wé’œÒá]f’ÀÖ†"Ð\+u´ïÛªïfXQžTbjêç’¬TáчSr”ϳR·°Fw‰¦~FQ ±}­ï¸ª•oè‹Á¸Pä ExC¬Õ@d}2ë“?OŠ2€¿mä¿—bO&"À0lÖÝxö öOl¬ùÞø4¥Âý_×L}ðÕ=™È4}tÞÂ+&™õä`ãcó©a.p_\8ÃmÕ�z‚I-Þä9Œÿ³ôÒ\»A2,äÓ£±¥k>Ø]sx|YjâË\Tß@˜Õñ£+aÆN v«9ÇS`5›ŠF£’(};Iì?XûU}g,þh×—ñxŠ #]èÜK~uδ3 „jT"fùü‹/["¨ªÈv=fÑã3ÏU”ç‚Ø0쬣p‹ßññ§ ��èê 5w‡®õswe€#´‡\{Y…GE8– ¤”#½†Â#s©¯:@còéoºNÃ\dgH§åÁJjgX´é1³mèã æ"÷w1+¤÷u0‚ *ÝTã�ŸàÔ"cåcÆInà))v»Y†Æê¾lKK 4"—ªía”:IBêK APk@0P¨Ç‚×öp Ê£öu¤�ΧxNå9¤7"„Rr¾àeµ#$Xõ˜U‡Ö÷q8† w“5] € qôWŒ ƒ 7ÕìçcœZä œâˆN#Fpã�OâH‰“8ÐÍB04¡è;aGzØ´�Jœd0%õÅ$G¨% èI4Ï‚îaQOïkOË*4*>ØÍ²"(Ï!}!˜’ól¸¨¨í!Á¢Ãì´®ÃQ¤ÂCÖt2*€ÆÐ5 /án²5ÀÇX¥ÐN$y¥+": ˜žBûyGJsˆ^M½§=-*`„‡ªëåR(q¡”Ô“ÜC ?¯#|~ØÇ"<¶€Þ{LuÈÇ2"(Ë!{cR )çYqYíAÁ¬ÃœF´®—ÃP¸2—üºóXÕïïd8 w‘íA!ÊÈv"-¨]aÑaÀŒz´Ÿ'0¤,‡üÆË@4¾ÞÛÎ ¨ôP }\’W‹D„‘}QÑeÆq nöó4Ú‰C>áq…º=íiI…FæRµš0'Ù“R®WÔL4ê2áYŸÌúäÏã“ u™F‚ V»#Ý‘£Þ°öWße%3)`°1‚À¥Kæ¯,×Z–k¥ ‚¡Áö™mAT? ɲ*+ê Eß=å@Tì6/ýí™O¾³ßëO��Ês­÷ünªÛ¦Ï„A� À& ûõ(»a’ÛL!=Þ3« E zEat¡uÏѾY“r®:×DLÍmµ­=ºB7� ��@QTÔàTU€P&#Pqš)_O_ š<{bE(δöF~sѹ,áTUÐÚÌóëëRœè 1Œp�$ÄŽä%Uç Öb�$’À{"\*(Îwɉ޾¨]H X̦ÝûëD̆ØB\rÀ'œg›¢ @¥68˜RiµØ‚ˆ*èŠÈnl #}¢†ÝFd¿O p8Ï‚Ô÷‰�‚ò-po\ްj™ fEÐSr0‰ÁG$‡vѯ½‚‘€óÌÈ¡Cá| Ü‘“(·ÁqNéM(&A æ ”£‡ízô€O0“p®ù˜°| Ü9*³B¡´âO©ÅDVAgDv`Ôö‰V ö˜oº ‡óÍHÀ¨@P‘îKÈaF-µÁ¬º£r®¦q¤a@²Ó°ÛˆÖx癑Ã=ŠÂùØ‘<(·ÃI^í‰+ù&E ¦€äÔÁú&Ì„ìp ηÀm!‘•@© 3Ê@J-² *€ÚC²Ë�›iäpïwÂHÎ3ÃGDY… mð@B 1j©áeàÊ#L“H}¿h×J¸[ÐiÂzE†ó-pwLŽq Ü'ÐWòL0†BÉ©ƒt·`"á<rÐ'à(œoÛCRZe68Ê(ýI¥ÐŒ�j É.=lÕ!‡zE kUObpžn ˆ¢ •Ú`J ¦Õ+"* +"{ °žDêú¿­úo…é!*°À=19Êrœ/¦äaƒý’CçКŒ°o«¾#"§4a¬Ò—T Í0A-A)GÛtèÁ!#,ë“YŸüWûdæ)GQÁ+;êßÝÓzBGÙüK'\W5vði2 þÉ�� >ù)çËúÞÇÞúzp²ûŽö>ýNÍâÙgÚͺŒ1:ø‚Æ–:ï¾ú̇þçKCïùÝÔ…öºù�ÇYµ¦% Oµ‰éHgoØZ4úhÇû‡ë›tîáÃ[YKë�̦xÑ*õñqG<¢:TÈôòކúº¿`hm9ôúOöúÃöõvÔ¢¼¼Ç�§¢þ†–Îæ®º!hƒcyÖKçµzº…n$ò‰p_˜U‰BÀ¡´¼©fÀ.D5õ» h Æ!ú¾¸wמý=)ĘËöø›úCñî˜Jäê È¡­aURá2‹âK€8t¨ ¦Õ2 àd¨'¡z ‰AMAÅDBV ´„T‚óMŠ7¦&h´SíK0†YAR€ú“j¾`ÜTld"Ac@!1ØcT;¢jZ„Æ8U_DYPiö§Ô"�ÜR:HƒÆ€¢Ã¡=h«¢ —[”nM˜] °p0­–Z€ @¾¸êÖC5# Ùt %¤Î7)Ýq5ÁC£j 3ê0+H P_RÍûV˜•‚Ìh *8{ŒJWTM‰Ð§Ú“TØ@”ƒý)µÐ n©N2 ) Ðš°ˆ*ÈЇêK€°«A¦Õ3ÈUÝzˆÆ ¦ b û·Â MJwhÂÒPˆQË­€‘ Þ„šg€j * ²P )¤bœkTºbjJ8NXŒƒRj 0ÜT4d AcP¡pØ¥W;¢*'C#ª/ b,4®†X8V‹Í@V¡Î°êÒA45•LÕ+*\hVº ÁA#ªŸBiµÌX êM¨¹ˆÀ Æ b&!+šC*ŠÀyÆïª¾7" nqHªF€"pSP±ÓI†Án½ÚUY åP{¾­ú0Rj±(�n «9:H‡ƒ¦A²>™õɵO2¬ÿ¶‘—$åäx�x㓆ë/w|P91æ à{,!èÝ=­¢¬��.œX<©Â³ò­}’¬|zÈ;ç‚Ñ‹þ{Ær2)Ž.v¬ºãB=6ÃÉÝ|²ŠÈh ©2ïRep OŠ:E2Ã¥ù<N «²þ £ºâX»àT%3ä€Iœf¼¦OPœÓZR”bŸ#t]RV]æÃýªd? V©¾˜¤*FˆC ‚’‚Üœ_çK’ôá—ßxI’F½ŠS•-À�!¸NV oTéä­Š¬ ™àhW„@ØHê‡e®P�3R�'“ÔQEŒwò‚“À›àK`1.2ŠiêK!vJ"µ#ŠˆâÑKM\RÀ'ß&xŒ±óQ")Be&!Æ#iÄEK0:bˆ“´ÒÅ$Œ²óu!BÁx'ß! ·ˆ4dà<ƒ()PO1²WÚ¢ß!Dù8a=I,ÊÁ…F‘¡¾b#%UÛ£«yz©)‚‹ƒ„¶ó]q"!@¥&!Î#ýiÄEK(:b)NZj‰â’&Øùú!È`œ“oŽŒ†Yă8× **ä‹"F\6“J[�”šù£ác'¢ «´ }),ÂÂF‘“ Þb%eUÚ£«F©1|œ°Qv¡+Ž%¸Ä$$x¤?äЫQ”D-5kÂrø†ÁË`œƒo‰i”›Å0‹øÓ°G/tF.[I¥5Š©*iã c%PiúSX˜… Œ¢ C=IÄBÊz\éˆb¤~+,s"#mBw‹óp±QH pqPþmÕ»õRóñU?ÖÁ·E‰”ÊÌb„EüiØ­—��QDËvRi‰bŠFÙøúðqU_aüi,ÄÀùQ”!_1²WÚ£ "£pôxaYŸÌúä¿È'Ç:Øöô±¹$ß÷û©ÝXsBÈYñ‡_nä3s îœuÆ-Oï8¶�m6Á53Æiâä¨sïï¦ÞüÔ‡ãË] gM2ëI“žxpÝçs/Sžg;î‘èŒ3ÎØ½{w*•Ê”í+þkÈý3¼, Ýþ¥ëEi •758þÉÔ(D)7±ÍqZUA‘ qXL@ótœ `_ w‚”›b”“Jüá°ŽFäaf®>¢C ¥ØÈõ3DJD ô'#ý æ¦x®¶ÅI#&ùÚ°N‡ÊÃÍìÁžD”R#ו$y*4pI ²X.ÍcèL\ÌÕ‹õZÊåfîPHG!J™‰mÓ² Š \„Ç¢<šGs�‚»S¸ƒì¤Üx¼°r3×¥a –|+,_Ç *Ü—Æ]”`À•Ö“„ éqD)5rÝ)’“ B=—’Ð�‹yhž@AG‚0ãb¾^¬$ŒD”2Û§$*ÒsQ‹ph®Žƒ!È›"ì„è ¥Æ(e@¥R8¬£y˜™;¥!�Š ¬Ÿ#’’¯ãDîMã9”`•–ã… 3sµa)%F®'M°\ ç`0ÍS¨Úž ͘T`ŽDh=*3s5aF®#IŠ T¨çbæÐ<ÃÀ›$l„˜CKG£”•Ê̼VÂå&¶²öuG�� �IDAT)F�Š \€Ã⚯ãdîIãNR°rsŒ2bR‰V¨<ÌÄÕEt(¤”¹Þ4‘–à=¯U½‡æiTmK&L*4 GÂô Uß™$*2pq ±h®ŽGaЕ$¬¸èÖ‰ Ñãª>ë“YŸü|²#“‰öÿç7ò™^xá–[n‰ÇãC‰¯¾úêœ9s´Õ?j¢è”)S`ðýNß¿­ÍXûþÈÒsŒOWþdpý“Iáˆê¦Ùö$Å+H.Í„y,ÈnŠ•U¨+EÙ Þ€É 1½“\8b ÅMsMqZ‡fX""à¹ÃÊpC:IŽ@”æ¸ÎŒ‹9(l¤QÅMqõQ= ÅúÒDRÂòh&)¢ý,™Cq0¬¶%i+.ØH±6bÐc²‹âŽDô8¢º)¶#I± ’K1 p„›de�u&Õ+¬6b ÕMs-qZVá\šõ³xDÀ=Ã+°/M9IžDä¦ï„(TqQ\}Tà —b{ÒD\Äòh&)¡},™Cr¬¶&h .8HápÄ CeÅÕEô <Û•¤Í¥˜¨€ú9ÂE±*€:R´L¸XÕ0ÉEóµQ=¨šk‰Ó’ çÒL€ÃÃü1aÝiÊAð4*7Æu&\Ì¡øÃ‘cÂŽÆtyh¶!b"žK3i éeÈ’Ã`µ%¡³à¢ƒâe„Euš0oŠLKh.ÅÄÔÏnŠ�t$i!˜q±.ª7`RÍ×F4al[’T8—f‚â ň äMS‚×aòјބIš0UÜ×§UòÐl?KDE<—fY îaÈ’Ãaµ9ñ] Ө즸ºo«¾;M¦$4fâ":À.Š…€Úž¤­„`%Å#Ñã«>ë“YŸüY|2)aƒGOþQ#ÿ½“Ð~”ŒôG¦ßÍXâ:�À¿¬?IEúY]L$J¨hH 8ª€Œ Ò•Ö;q†€åÖ”Á€ ŒkO ä’ÉV—”ð:ä© OS±”Œù‹H¡Úš2š0Þˆ ­)#+."åeôi+¦b<È:É^–Î%“�€ö”ÁŠq:TlM)D²cL£T¤€Œ÷stL$J©hDÔ„%éJëÇ„õ¨¨ SÈ%=¬.!á¥t4ÈSž*¢bŒŒu3:‘F!¥-e4¡¼åÛRF VÝDÊÇèÓ2VBÅü<ÈR:“ˆ^–öIí)ƒãô¨Ø’4RˆìÄ™.FÏ«Hëçéè·Âú9:ŸLH*Ü™ÖÛq–‚¥Ö”Q‡Š6ŒíHÎ#½¬.!á%t,$hÂâš°"ÃJkÒhDÊ·¥Œ¤º‰”Õ¥$¬„Šx*$%t4.=¬ÎC¤`Hm;&LhMIDvi/£ge¬ˆŠ ðtD$´îãè<2!«pGZoÃY ‘ZSF"Ù0¶3mU8ŸLô²º¸ˆ—Ò±@ùyªŠs êeôNœÁa¥-e0 ‚ãÚS¹DêXÕSǪ¾„Š%%ÜÇêÜD ÔÖ”ÁŒñThI XÎ!Ò^FÏ|[õ(¥cQ‘ìcé<2©¨pGÚ`ÃX‘Z“FúXÕD) YŸÌúäÏä“TôGãÍ?ú]Îí¡!�€ /^¬( �@’$ ÃNè•ʈ��ô†’*BþBߨJ!"+c��–xQU‡eY…dF!‚TQA HÅ!™WÐãíENA€pX’UXVa’!�D!;É>³AÀ’¨"Š a°¬ª¤Â¤ "((T–8ûaa¤ *(©$s' ãT=Nرª0HVT$# �•<IK‚Ѝ'žÈP„X§* †ô˜°¡—°*(T>Y˜Ä+ÈO†Ã’¤ÂÊ?[õa?^õYŸÌúäéñIXe%Ç¢SUõä&ýä=±XÌl6ká{íŒÇãF£1“ò÷‹¢ˆã¸ªª²,?ù䓨Óé¼õÖ[†axçÎ^xaöußY²dÉ’å´ðÑG]z饩TjÇŽ’$¡™/t:ÝW\‘- ,Y²dÉrº¸âŠ+rssû]8ö#M…ã¸leÉ’%K–ÓÂÁƒ;;;¿?䨪*B¶Œ²dÉ’%ËiÁëõì³%’%K–,Y~²!'K–,Y²dCN–,Y²dɆœ,Y²dÉ’%r²dÉ’%Ë¿/èPŒzzzÞ~ûívΙ3gýúõS¦L9묳~ZÞŸþù2ûÛßz<mûÍ7ß”eyܸq}ôÑœ9s��ëׯ¿ð G5””»»»7mÚtñÅ6 �PSSóå—_�Š‹‹/¿üòÓ^ˆ;wî<räHæãܹsÇÏV…ÉdÒï÷g>Úív³ÙÜÞÞ®×ësrr~B‚'Ww¦$ÿ¥Ô××ôÑGÚö˜1c.¸à‚=dÛ¶m·ÝvÛ?“ï_|±ÿ~�@EEÅÌ™3OøöÙgŸ>|xUUÕ?‚û÷ïÿâ‹/2/½ôÒ²²²=jÍš5ùùù_|ñi)ä;v477/X°àСC»víºþúë†yûí·gΜYQQ¡]8��Š¢æÏŸ�xÿý÷[[½îþ7¿ùMiié)e÷ÜsÏ•——_tÑEC1~ýõ×ùÝï~7Ä’¼ñÆM&S¶?ítvv¾ûî»Zu···¿÷Þ{—_~yqqñ`›–––>øàÊ+¯,((8ýO9^¯·ºº:—B’¤êêêO?ýô'ŸØÇ\]]]PP %H’ß½Jgݺu/¾ø¢Ñh,//'¢¿¿¿ººúàÁƒCL¹«««ººúèÑ£ÚÇ/¿ü²ººÚjµfBÚéeÛ¶mÕÕÕ™’!âçôd2ÙÔÔ¤ªª^¯çyþÈ‘#©TJ§Ó .ÏS‚¢¨Ì¹ˆ¢8¸$ÿux½ÞÛo¿Ýçó•——£(z×]w}þùç?zÔæÍ›ÿò—¿ü3ùÖÔÔ,Z´HE£Ñx÷Ýwoß¾ýƒ+Vlٲ崜ãÞ½{«««ÍfsyyySSÓüùóÃáðURRâv»OW9oÙ²eÅŠ�€¯¿þººº: iWwCC˲·ÞzëÁƒËËËŸþùÇ|Ë–-÷ÜsÕj-//ohhøãÿ‹Å†ž×Š+–/_¾dÉ’ÌÄóâ‹/®[·n(–‹¥¼¼üä·se9-´µµUWW·´´h¡¥ººº­­í›£GVWWwuuýKžr4&L˜pÉ%—hñàé§Ÿ^¿~}¦É»âŠ+$IbYö¾ûî»øâ‹3‹. …™3gÒ4­móÍ7óçÏ_¸p¡$IÚLJzèÍ7ß¼õÖ[�O<ñÄ´iÓ†rc8eÊ”?ýéOwÝuפI“¼^ï³Ï>ûÔSOýío«¨¨=zô¢E‹%Iš5kÖí·ß~á…Ž?þ©§žºõÖ[½^ïöíÛŸzê©W^yeïÞ½z½~è'¢�`öìÙ0 Ϙ1ãÙgŸ]»víí·ßn2™R©Ô‹/¾(ËòöíÛAøâ‹/ Ï>ûì×_]–å>ø�ðŋ744Ȳ|Ùe—-X°�Çñ¡çnµZm6›$I‚ 466æää ôôôL˜0áÈ‘#EEE'¿^édl6›v.===K—.½ýöÛ§NzÑEñ<ϲì=÷ÜsÉ%—ìØ±ãᇦi†áwß}÷oû[QQÑK/½ ¯ºêªÎÎÎC‡3æ/ù EQCÑÏ0L{{û¬Y³¦NZ\\üÜsÏùýþp8<cÆ ­ôÖ¬Y3vìØuëÖ½öÚkAäåå­]»V;VÅ^xáÍ7ßÄ0¬¤¤dÕªUúaz{{ÿûß_{íµwÞy'‚ UUU†Í;·§§‡çùë®»nÞ¼yše:ž7o^ àyþ¦›nš;w®v9Ȳ¼cÇŽC‡ ½¦Î?ÿüÂÂÂÖÖÖ72 óÕW_ .IE.\‰D®¹æšeË–­]»ö‘G™2eJEEÅÿøG¯×+Âܹsÿð‡?LŸ>}úôén·û7ÞøðÃNçPr×ëõ‚œ|“AĬY³EyþùçM&Ógœ¢è¦M›Âáðĉ ½^ïîÝ»‡þ»½t:ýùçŸïÝ»÷“O>©««;ï¼ó¦NzÞyçÙíö 6|üñÇ:®ººz÷îÝ�€³Ï>ûÁÔ|ë­·V¬XñÎ;ï”——¯_¿~åÊ•ÿûß;;;ï½÷^N'¶mÛvïÞýôÓO7n÷îÝË–-£iZUÕ-[¶ÆlÀøÑÔÔtÍ5× †D"±yóæÌþiÓ¦Mž<¹  àõ×_ߺuëÞBl¨««Û¹sçÁƒ“ɤÏç“eYÛ¯] »víºâŠ+®»îº@ pJgòé§ŸîܹsçαXìâ‹/ž<y2Ïó�€T*åóùDQÔ—»îºk(ñ�@„Éd ‡Ã’$qÇív{ ƒ«V­Ú°aÆ xàêêêÏ?ÿ<//ïèÑ£Á`°¿¿ßï÷×ÖÖ:ŽS œZ÷ÚÎ;{{{ý~ÿG}¤uÈ<õÔSÿùŸÿ¹k×®‰'^|ñÅ<Ï?ùä“ãÆÛ²eË–-[|>ß®]»‰Ä 7ܰfÍš7ß|sýúõË–-{ôÑG?ùä“SÊ=‹d2©×ë1 cYVEQY–ííí-..®««K$§ÔÍ5sæÌ«¯¾ºººzéÒ¥---»víºêª«æÍ›W__Í5×\vÙe»víêëë»õÖ[‰Ä5×\óÒK/Ý{ï½=ôÐ¥—^ú?ÿó?¯¿þú‹/¾8Äì*++_}õÕÝ»wOœ8q``àý÷߿ꪫ.¿ür›Í¶k×®n¸áÉ'Ÿlooß¹sçc=¶uëÖ>øàÏþ³vì¾}û|ðÁ%K–¼ûî»ï¾ûî_ÿú×!f*IR86™LA (šŸŸ¿jÕª>ø`ëÖ­ .\ºtiæÁú¡‡úè£vîÜyë­·.Z´¨¾¾Þçó­^½z÷îÝÇ?¥šÚ³gÏÎ;ÛÚÚÆŒ“J¥N(ÉgžyfÓ¦M<òÈÓO?íóù8Žëíí ‡ÃÚ3Ç–-[/^|ß}÷ÕÔÔôôôlß¾}ĈN§sèÝÅ+W®,//ÿæ›o´²,8p`Þ¼y_|q Ð.�€Ûív8óçÏ_²dÉ<pùå—WTTìÝ»wˆ �ðç?ÿ¹¦¦&//Ïjµ>òÈ#ìééÙ¶mÛØ±cm6Ûå—_¾gÏž–––W_}õ¹çž[½zu¦/×l6˲¼gÏžX,vàÀ£Ñ(IÒ•W^YQQñæ›oNœ8ñ™gžÑš p8ü»ßýnÔ¨Q6l¨¬¬|þùç³á4R[[»sçÎÚÚÚL?peeå®]»ŠŠŠ~ó›ß ¾oÛ±cGyy¹Çã¹ì²ËNOÇšF{{{MMMccã÷Þ¢>þøã{öìù 'öÍ7ßÔÔÔÔÔÔ¤R)mÏ7ÞX^^þO–×äÉ“3mÁ™gžyB‚kÖ¬y÷ÝwµíÇ{¬¦¦&óqß¾}ï½÷žvëtª]4555Á`P»büñ7¾õÖ[F£ññÇohhJ"/¼ðÂ;ï¼óӺעÑh:¦iE{x9räOHðé§ŸŽÇãÿõ_ÿõ³¹øù矿qãÆeË–Íž=û¶Ûn<<öÇ?þñ7Þ¨¨¨Xºté×_ýôÓOŸ|øûï¿¿jÕªŸóš;vìêÕ«ßzë­S:êðáÃ6lxóÍ7—,Yb·Ûµ·Ç<ãÿ��»Ý¾dÉ’Mêì³Ï>yðéGEñжyž_¶lÙßu×]o¼ñFqqñìÙ³ï¿ÿþÁ"‡èEÛ¶mË|<÷Üs3ã:çŸþÍ7ß¼yóæ¿ýíoƒ¹è¢‹Î=÷Ü¥K—677¿òÊ+wÜqGqqñ’%K’Éä½÷Þ[VV–ñI’$—,Y ï»ï¾Ñ£Gß{ï½Ù8qiii©©©Ñº×4Z[[üñ“;ÓÎ:ë¬LÏéìX»ì²ËfÍš�xæ™gNø A‘#GŽ9ò–[n1›Í§tbwß}÷©6îCaêÔ©•••wÞy'Ã0Ó§O?áVtذaS¦L¹ì²ËÆÇóüiÉñ¾ûîËlçææjÎ÷Þ{ï矾lÙ2­áG6lØÔ©S/½ôÒ &œRîùùù6›­§§çðáÃ,Ëþ“ç²mÛ¶}ûöUWWÿlþíõzï»ï¾yóæÍ›7a˜|ððáÃ'_ ,8çœs&Mštr yyy'N\¿~ý©qÿd&L˜0nܸS=ê¶ÛnÓét0 ?õÔSÚ¹Ãá9rä /¼àt:?þøãµìêêê?üáÁ`pýúõ«W¯®¬¬ÔfèœÌ{ï½÷öÛo?ûì³þóŸ!Ú¸qãÃ?<”Þæ}ûömÛ¶í¨¬¬7nœ Ë—/Eq°Í®]»îºë®›nºé„qi�À-·Ü²gÏžåË—_tÑEÓ§OÇ0ì¾ûîÓæ‰TWWkC•Zà}÷Ý×ÞÞ>þü÷ß?N%Ng"³gÏþÿøíÛ·gnÇFãÈ‘#«««iš>¥Q½Ÿø”ó0›ÍALœ8±¡¡á‘GI§Ó§tx ðûý~¿_E«ÕÊqÜc=v³Š¢ƒ!™LþázÊO>ùd[[†awÞygf§N§#b̘1<Ï?ôÐCn·û™gžyú駯¿þúuëÖ-Z´hÑ¢ES¦L9-ÕÖØØ¨×ë'NœX\\Œ H4ýG–š°Ñ£GK’ôÐCµ··Ÿê­+Ïó’$¡(zª]‚'°ÿþùóçÏ›7ï‚ .Ъ† †ý~*•2™L(ŠšÍæt:­Í”;-³††ùòË/ü~ee%EQEY­VQý~ÿâÅ‹Ï?ÿ|­£µ¸¸x„ ‹…aí-´8Žëõú’’’aÆÝÿýÚìÄ¡——·zõêµk×~øá‡œ8qâöíÛq‰DÂ`0d¨F#†a~¿?™L †ž#O»Ý>|øðƒò<o6›=Ïĉÿò—¿¼û455ð|©×ëqƒñx\ÛþɹŸuÖYÑh”a˜™3gÖÖÖZ­ÖÊÊJ�ÀÆ›››«««ý~ÿŒ3î¾ûîO>ùÄçó)ŠâñxÌfó]«¯¯¯³³óÌ3Ïœ9sæÌ™3‹ŠŠöíÛ7x �@( ƒ•••cƌѮnm�0f̘üüü}ûöåæær7}úô×^{í©§žr»Ý™ûîD"qÖYgmذáÙgŸµZ­™™uYþX­V³Ù<qâÄ 6¼ð ƒ¿úôÓO×­['‚Õj==O9V«µªª*3.T\\\UUe4«ªªÊËË|ðÁÛn»máÂ…�€çž{Îf³ ñ´¹§K—.Õ>._¾|ÇŽK–,?~ü 7Ü Šb^^ž–QIIɺuë^~ùåÇ{lèed±XÎ;ï<—Ëe0´^ˆ‚‚‚Ûn»a˜G}�pÏ=÷h¡¥¢¢bÚ´i……….—kòäÉcÇŽ=¥Yg#FŒ<‰vÚ´i™¦jóæÍsçÎ]¸pám·Ý†aØë¯¿®•$Š¢UUUÚÌã³Ï>ÛårÝrË-étZ;Á%K–L›6mˆ¹‘““ãóù|>�`üøñf³ÙétF†µyÒEåää ±¡ÔëõS§NÝ¿¿6u�pçwâ8®UñÛo¿=jԨ͛7¯\¹ráÂ…çž{îš5k6nÜXUU…ã¸Ó鬪ª²ÛíEUUU|û¨¬¬|å•W^|ñŽ{÷�~øáÙ³gÏš5ë÷¿ÿ½–﫯¾šŸŸÿ /¼öÚk_~ùåÖ­[—/_®õÏœyæ™Ï?ÿüo¼±}ûöÙ³gßxãCÌT›’«ªê«¯¾ �¸îºë,X°|ùrÍ'_xá… &̘1cÔ¨QóçÏaÑ¢E�€uëÖ5ªªªjĈ§tÑjŽ6Ÿ¢¤¤¤ªª*///S’•••š[²,ûÖ[o=üðÃsçÎ�üú׿5jÔwÞÉqÜý÷ß�X»ví¤I“.¸à‚Ñ£G�¦L™Â0Ì)ÜfÂpUUUEE�`úôé™!÷ââbmiáÂ…………ÚTÀŒO�6mÚ4ı·Û]UU•i€***´ Dû‘Ùgž)ŠâìÙ³ãñøK/½”¹ºµÉ«™¼***4‘$I¾ôÒKË—/_¶lÙgœ±nݺ-[¶TUUåää¬Y³fÅŠGŽ9ûì³Oh³ü3·DUUUZ]g®è­[·fÚù—_~¹¾¾>SÅ¿þõ¯1 ³Z­¯½öÚ&qÆ{öìaFk—“Éd¶Ä³dùßâ‹/¾Ø»wïwÜñé§ŸÎ;÷wÞùõ¯ý°^|ñÅÍ›7øá‡Y—ø7§°°pÆŒ/¿üò?2غu«,Ë—^zéŽ;î¼óN4[dY²üûàv»wìØñõ×_Çb±«¯¾z̘1ÿ aÍš5?þø›o¾™õ‡ÿÿȆœ,Yþ(++Û¼y³6¥E¯×kãäÿט3gάY³†>!;Ëÿ"û÷ï?¥aˆlÈÉ’åß‹SóùÿF£1û£Î_ §zg}­g–,Y²dù™È†œ,Y²dÉ’ 9Y²dÉ’%r²dÉ’%K–ŸÀqÓÒéôÐÈ’%K–,Y~˜t:=x!•ïBŽªªÛ¶mÈ–Q–,Y²d9]|ÈyçwR©Ô)­“%K–,Y²ü0ƒÃÊw!G„+¯¼2[:Y²dÉ’å4¢½¶õÄ“%COOöŽä,Y~qL˜0a(k¿fÉò¿B6ä|~¿_{s¶(²üâÈÆ›,ÙóËÃétšL&UU³E‘å—Â7ß|£­%K6äüòPU5r²ü‚Eñåy¾¯¯/[2?ÌjO}}}§kíàÿkØl¶^—÷CNww÷K/½tÂÎ[o½uíÚµ¿úÕ¯.¼ðÂliþ#V¯^¢èÍ7ß �$I[I �°`Á‡Ã±gÏm’’’n¸!sÔîÝ»?þøã»îºËï÷gVƒ¯¨¨˜3gÎßþö7m%Ä3fœ}öÙ™C^yå•x<žYó4 >ûì³3gÎlhhðz½³åË—:tèïÿ»öqÒ¤I—^zéêÕ«ûûû�W\qÅøñã3Õãøƒ>�ظqã‘#G��Zu³,»bÅ -…»îºËd2}öÙgŸ|òIF$� ?ñÄ'ˆÔ¨««{ûí·µíqãÆÍš5ëå—_æ8îöÛoÏ:Ì¿ŽT*ÕÒÒRVV–-ŠŸvÓ©õR8pàT—ãË’)á>åô÷÷¯ZµjÑ¢EçwÞwÖ(ºjÕ*A²!ç{Ù¾}ûêÕ«:TYY©…œ ÔÖÖ®\¹òÉ'Ÿ¼þúëW®\yÇw\yå•gœqÆ-·ÜAÐõ×_�8tèЂ ¼^ï-·ÜâõzW­ZõàƒNž<Ùjµ®_¿~Ù²eÏ>ûlccã‚ ^yå•ñãÇ�^}õÕ‡~Øf³eBÎõ×_¿wïÞÜÜÜiÓ¦iË)®]»vëÖ­=ôPCCêU«žzꩲ²2—ËõÜsÏ=ñÄëׯߺuë-·ÜòÆoÜxãEEE7ÝtÓí·ßÎ0Ì”)Sî¿ÿþGy$ .^¼xÍš5/¿ürww÷Ã?¼bÅŠ›nºéî»ï^¸páu×]WVVö§?ý Aæææ={öìß¿ßb±œrúúúnºé¦éÓ§_vÙeàÛWÏnÚ´)™LfCο»Ý¾wïÞ?ü$IUUEQ”$ AUUQ¼8´¢(0 C¤µ³ÚWZ“¡­? ð,Ë��A4cI’2m A0 kû3f–E HKSQmÙ\m§$IAh ²,k鈢¨‰Ôò‚ H–e£Ñ(Š¢ ²,#¢IÒ¾<yòÁƒ%I’$ †aíÔ4µ†i;5KQ ‚ÐÒÏÄ‚´µ½Y–=÷ÜsÏ9眲²²Á£bF£Q»Ð´£†Ž¢('4»Z!ŸÐ.Ÿ°J÷à^EQ´o!Òr‡ èVøýÞ3ëgVûæ8N3CDÓ“©úR;a‚ '¬G®(Š–ì`a«W¯öûýN§ó„ÄéX6lØôéÓ�/¾øbuuõ| í¸ì²Ë(ŠŠF£ ,¸öÚkÿÉÕàÿ=»)þû¿ÿ{íÚµf³Y’¤M›6Á0|íµ×²,›J¥®¾úê;î¸ã³Ï>[¼x±Óéôù|»víºà‚ ~õ«_]tÑE™Džxâ ‚xž'I²¿¿?wvv>|ÆŒuuuš—Çb±•+Wþö·¿]¹re8¾öÚk¯½öÚ™3gQ\\\VVö›ßü† ˆþþþT*¥Õß|‹ÅFŽ™ùéîìÙ³xà™3g�´u½Þ~ûí>úhË–-MMMwß}÷Ÿþô§©S§Ò4ŸŸóÍ7Ï›7AÝ»w' AŽ92mÚ´éÓ§QWW7jÔ(Žãìv»$IétšçùÇ—––NŸ>}óæÍ²,ïÝ»·»»»²²rüøñ‘H¤»»ûž{îéîîÖö>ë®»®¹¹9•JÍ;÷ª«®ºè¢‹ÊËËëëëeY^¹rå¼yóæÌ™#Šb"‘˜3gÎm·Ý–Y~£³³ó /œ;wnww÷®]»Þ{ï½;î¸�àõz'Nœ¸qãÆlD ííí_ýµÖøf®ÿÌ-¼Ö.C¤ªª$I8ŽkmAZã•1Ól´Ö\’$í’×vʲ¬-ˆîñx:”i†´¶²ŠpC�� �IDATIkôEQË]Û£ªª·Ñ’ÕäÁ0¬… ­!ÓÒÑZFEeYÖ‚‡ô{÷îÕGQTE-_Y–µ,4‘ƒÛÖÌ=4Çq™³€aXUU—Ë5zôhAÿ€1•J}ñÅÚ!?0Aãä›z­x£ÅÔ5ËDŽï 9™2Ä£55��A´ –e53E5=ßrN–±œcÆ,†‰D"'Ëû‘w¬ÕÔÔlܸñ³Ï>E1•JeÎäÞ{ï »víºöÚk/^üÿå; º»»—.]:iÒ¤·ß~{ܸq[·nýôÓOóóówîܹhÑ¢+VÔ××_sÍ5\pÁ®]»òóó¯½öZ Ãôzýàú i:N/]º4oÞ¼YÛùÕW_mÚ´éÀš|þùçgžy¦¶ãø%—\²ì“O>9sæÌ={öà8®×ëׯ_ÿÌ3Ï<ûìÿcïÊãc<»ö=û’}“U2"‘=„ HÅk)RŠjKBk_ƒò•RJk©E‹PMš–"‰¶’V¥„Kl±d#û$™}ûþ8Íyïwf±D#óG~ÉÌ3Ï–gÎuŸs®s­aaa‰äÞ½{~~~¸àº|ù²§§'Ýo%‹Ïœ9èææfii9bĈ¢¢¢M›6 >üÂ… <O(ÆÇÇÿôÓO{÷îíÔ©Sddä­[·:ôùîÝ»ûùùíÞ½ûàÁƒ=zôðññuÆ¡C‡Ž=Ê`0œœœ233= GäóùB¡Ðèܹs'!dúôé;wÔœ5kV`` §§ç’%K>ýôÓóçÏ/]º4>>>??Ÿ~–Þ~ûm‘Hqá‰D˜‘‘ñÉ'Ÿ˜™™Å6“5á5M}}= jµ\6¬[Á1~Àfà²ÁEr8øà ˆ94@ €g�bX§3™Looosss…B_ ð‰ðôÂg!Öa2™<ÃD.—‹‘“J¥‚³‚£,)•JÀ-bðдíÔ©‹Å ƒwá4à’q±o¸¨oÌX,ç­…–ÝG( …Â'š„¦÷�¨ ŒÍfëÿ“pô­€éÆì1÷¨®®®¼¼Ü(¢Êd²åË—_¸p¡ g$Ö®]›ššºxñâÎ;O™2"’•+Wæçç7s'jµzñâÅ=JHHpvv.((€»ZTT´zõê 6TWW×ÕÕÍ›7oóæÍ„ ‹/¾ø>ëçç·}ûö>}úìß¿ÿÓO?ݼy3ÄO ]»v4hÐçŸNÉÍÍ=qâÄܹsÁ¡€ïÛ·oÆ PÅ}ÚØØ$%%uëÖ-!!!))iûöí½{÷†(øÇ,//‡ï䯿þzîܹìììâââ‘#G¾ñÆö•——óÍ7999üñ–-[Î;gt!óD6bĈ:Ì™3':::66ÖÃÃCoƒÈÈÈÞ½{'''ß{÷î?~ü¢E‹LXÒLO Î Ó €=˜Ñâñx …]'` J«ÕâŠöÏd2oß¾}çÎú³ë°X,ðìl6ŽçÑ ��¼'çF§ìèLb ŽF£7)8ÜórÇÿâ‹/ ‘¢ú*L,óµÇ@Î+¯¼2nÜ8BÈöíÛ ±wذaÆ #„888´½[cee5cÆŒÿüç?“&M:qâ„Z­¶°°X»ví×_ÍãñÒÓÓ›³“Y³fݸq#))I$á‹8pàêÕ«Ïž={ÿþý>|¸¸¸ê1\.w„ o¾ù&lüõ×_¯Zµj÷îÝQQQðÊW_}uêÔ©-[¶\»vM¡PÄÆÆ*•Êßÿ]&“BvíÚ¥WJ)((˜5kÖ¬Y³ íF‰ß´iÓñãǃ‚‚à''§3fBöïßߨµ´oß~ÆŒgΜùá‡>þøãÐÐÐÐÐЇ®_¿þYîsDDDDD„••Õ¬Y³ÒÒÒ¾ûî;ooïÆ6>räHzz:&xMÖÌu¬ÁÁá‚¿Æå?-Á$dœ�!À¹C„ù4€pîèôfl�0t:ÝÕ«W¡X‚A]1ÂÍáLt:P(„ò àì5¸4Ñ •J%üÎf³û÷ïöìY‰D¢Óé’““!ÌÂlœ$ÜÀ!•JÅårMÓ¢ö”à \\\x<žMJJÊœ9sÄbqÛ»5EEE¡¡¡_}õÕ¶mÛ¸\®D"‘J¥jµÚÆÆÆÅÅÅÆÆæþýû555ùùùr¹œ´¼¼<øöæççß¼yS(¶k×®¤¤äÖ­[B¡ÐÁÁa×®]ÇŽKNNž0a!dýúõ………999H¹ººVWW ‚üüüüü|PûNNNNNN rvvþã?Μ9“œœ¼uëVBÈ”)S|}}‡ 2nÜ8à&¨Õê»wïææææççóù|GGÇ‚‚©TÊáp`Ÿõõõaaa³gÏÎÏÏW«Õîîî666–––wïÞ}ðà­­­¥¥¥H$’H$°±‡‡GVVVppðÞ½{oß¾mnnnoooxíGuqq9}ú´ÑÛëáá¡T*÷íÛéééÙ¹sçE‹I¥RFsùòe—o¾ùF$Éd²]»vÇïüùóS§N:uªF£yðàéÛÛÜu%›­R©°t Áb±Àƒc”ƒÑƒJ¥‚XG©TÂö’€Á²Öä•J%À8}̧A…J8*• Þ…Í09&—ËñO,à~�?�ðˆ�i€|Èk€( &|ñôéÓ2™ .ááÇÀ;�@’Édr¹R‹xQ„5–>‚³‚âŠR©”ý¯ÉårMƒá‹phãp8Üÿ5ú<—Ë…l—ËÕÛ@2˜ŸnpDƒ¡l0<!²Âmär¹t˜‹ÂÝj4åÿ&ë›ÐTÎÅÅ%&&F¥RݼyRö` …¢¶¶¶ÿþnnn„ÚÚZ‹5pàÀššš>}úÌœ9³¼¼<##C*•®ZµªcÇŽmé+ZZZjggçààrêÔ©ìì숈ˆ•+WöêÕK§ÓýòË/"‘hРA YYYYYYNNNÈ)/))ñööîÓ§üÎçóa›œœœÉ“'ûùù:uêâÅ‹#FŒ˜3gf„ëëë9Nttô«¯¾ú×_eeeuîÜùÓO?­©©áñx—/_†øøø8;;ÃGÊÊÊÜÝÝêtºÊÊÊþýû{zz„……·ÍÎÎ.$$äÏ?ÿÌÊÊzõÕW¡°daa‘Õ`aaa#FŒ8}útVV–§§gBBBPP¥¥åÉ“' §OŸ>tèÐáÇŸ?>++ËÜÜ|ÇŽÞÞÞyyyÑÑÑÈ/++‹ˆˆ�V®D"‘H$¯¼òŠ••UEEEDD„§§gaaahhh—.]†ž——çææöÙgŸ)Š_~ù¥¶¶vÙ²eݺuS(}ûö={vvv¶—˽~ýú¬Y³jjjª««³²²=zÔ«W/œè-’œœœèŠ‚L&«©©¹yófnn®R©d³ÙP~7Ø lll¤R©!T@¬�<1ÒPGè¢3Q×D¸mø;$¯Àma®ã ä¹aM\?¼Á¶¡ËÝ�!€4l ¯D¢ž­¥¥%€›Íær¹|>*êÈ,ð÷÷§ïäÍ›7›H�]N×sî/êe>iÄÅÍšCl3d"5ü lð<†žôè⻆™[ÃÓˆ‹ÅPùS*•wîÜIKKc„††fffJ¥Ò£G>Üô½%„\¸p¡S§NðhšîÆ?hñññl6{æÌ™3gÎLNN6MÖhÚΞ=Û¥Kº„[YYyï޽Ç'%%¡¿�ÃZº•••……EQQ8ttsB@)XR@À„9HvaÕ‡ƒ\jzN;,Ä€BqưP„Žir�l¸”ƪlƒ@Â&î x²²²’H$@æóùîîî·o߆ÂÞ¢£££££é;yôèÑ   º]„<®U‰a|>_9 Vh ¢ðƒF‰a†aDsjþÿAð¿`ã0 áÈïÀ(M2ÔË…êÅU†Oãýû÷#"" Èzž8qbÞ¼y&õ“µ^ëß¿ÿ°aÃ~þùç‚‚‚„„Ó yÊì9“I'µ04W$IMM =H/†2 2›!Ÿ£Õjaíazj€À½•5Ò”Á«œ�àC6F$t4�îs;L&S ( xyÒ¸‡_0¢˜üÏþsëÖ­[·n©T* ¼hµZ.—+—Ë á1åheeÕ¢ÿ$=Ó`Ü¢$$UÓÒœõ4ÍÆFÈi,ñØÜ4¯é Ù˜ÕÔÔ4Ÿ1i²–0ww÷ììl|â«««M÷¤ kL”…Á`Èår$@#� ³ »dÐÂÆÈ6ÆJ;øwD, w O¥èéÐÂÊ<Z Àþ1œÂÏ‚a N@&“áš ipòP7êdä`ÿLJËëŰI§ÓÁMD„kÑ“¡¯GÊx‹¢ü|Ò«C,¤ù&F/Á9Ïj-ýð™ÌdÏÑ„B¡@ 0ÚÈçó0…´1\Wa!±PýäX8°ÉÖPD¾¶aBY˜l4lÀO$ Ö�V‰�uÕ�K8æß0Ãw1H‚ó„1ÔË„” ¢ M… ->F*•šž¥–3ä·K—.™››·=I“µm»xñb—.]ô²4êqã¤]ºhu:…NG Òð“Ѱäg2°ˆÕh4Œ†…íßUå†ô=“ÁÐêt º†Á`0 ˆ#L¦V£!µk8ºœ!Z/°¦Ò€<oÆ`0Ê C 7&“`†Éd5™´:‹Éü{!H•pŠë0D§ÓêtpZ­"]âÁžé⫎VËd±”îîÄXÜ–@çM¨’ÉE�z ÃVsd šn-Âp Y‚†m³t¢Ïh@ƒ¥;<ÜÃcÃ5“Km4¥ãèèhº&{éÌÐݰ²²8iiÐöH°ü«Ó1˜LȆ›P«Õ ªD2=Z„l6[«Ñ0Y,)4 «ÁóBláââ"‘Hjkk1),—‹U<%LmiµZEÝ&:‹ÍPÔ¢R©Ì-,¤R)6·‚<ÄU¨jñ ƒÁ�¤kp!˜QÄK£™œW^!!!Í¿ÕX<§óðx]Í©|Eš8®—“lrš® ÑÓÄù4 9´°ž^âî±Ëtä7[[[£9 “™¬Õë _gÞ¿¯ùë/.—kaa¡R© »Lø „V% XÔ ˆExBNT*‹Åa2A~†Á`8HÜA‚‹¥ÕVçæêt:­L& „ Š�Â4‹Åáp$‰H$b³Ù÷ïßGÐh4:­:X±G•©Ñ8¶o_TT¤ÓéZ-C«åðxp\Õ¸óß0¨P"ž B Øb5ÔN0=¨c29,„)LOÏfBŽÉL‰5“™ìßkM¬`ÝZ[[‹ü. /A¥»X êN¨Jt§­2 aCø;¬± ¤Õjù|>–åaÙÒ¢\.PG¡Pðx<@Ø3–m�lhf6‡Ã¨yíh\.W*•"õ� r°••Umm-6‡*•J¸.¨Bм€Œ»–^heWc†ŠNF9FÖ/¾xõúŠK¹z ä$%%ŠZÿþýGŒ!—Ë—-[:7„ß~û-%%eÅŠÖÖÖM者²ríڵÆ Cá–Öo9998º†òÚk¯]¾|ùîÝ»„Ñ£GƒÆ6ØgŸ}F™?>üyÿþýøøøñãLJ„„,^¼^är¹  sàÀëׯãø“™¬¥ æÐ`ýöˆ+@?ƒ0ˆv|@n¦Å:I œ8ÊÌ�<Ð"i°z`=M‚zníËPÝÙÕÕõÒ¥KŽŽŽ·oßFy˱h„?eáÛÜ<D>¤í!ÌæÇZÂhÝeÃD Û_Œ{ðVPoÆ"MÂnôQlâ½äää+Vôë×/888...==]©T&&&"o•4iÒ¤Æ$„i«¯¯OLLÌËË{‰¾¨‰‰‰ÁÁÁ“&Mš4iÒÉ“'aÊ@»ví¦OŸ~ýúuÄ›7þüóÏð§F£;vlbbâ­[·4Mbbbmmí¤I“Æùò娨¨•+W&%%™ü É^ä"fa@Ó V±X,X)bþ ¦Ñ ì i(c×”[ÐiBuPôžiâ@jµZ:KÊú»F£ÑHwJA“†4͇Ôg­V+•Ja©çäääææ& ö£T*% ƒÁ …C† ¡K---ÍÍÍ¡¨ƒàW !ðÓpDÂc#E“=ŸÕOcodeeÅÆÆ~üñÇ#GŽ|çwfÏž=fÌB.++›?¾··÷;w’’’¢¢¢JJJvíÚåççéïï÷î݇2$""¢k×®qqquuuï½÷!ä‹/¾¸xñâËu¼½½CBBBBBV­ZUTTÓhðé<pà€µµu§Npû¢ jTTT``à¬Y³ †OçÎÓÓÓ_¢8ÏdmÀ V/‘HîܹS^^®ÕjËÊÊàõššÒP©Æ´4ffftaR^ÐÁ‘ JA¥D*•‚&J8 …6ƒÈI§Ó172ë6×±¸,Bˆ"^ÁÛÅÚ36åà$Pè^‡€€€×^{ÍÎÎÎÍÍÍÍÍÃḻ»ƒî‘B¡HKKäƒs–H$ ñƒü¹\\ ÅtÀ ~‡9M$'é<’Þ/´5qÒjiz3nôvõì½¢†'†mOôž 7£_iú]ú.5q¶Ìæ?µøû•+WÞ~ûm333LÕÔÔ,]ºô­·ÞÊÈÈÐétË—/OLL<{öì?þ¸ÿ~µZ]RRCS¦M›Öµkח뛚šºoß>ÐDÙºukrròŽ;üýý«ªªÊËËimºÌÌL�6räÈÐÐÐýû÷ÇÆÆªq›Ìd/,Ê.�$” ’ ;rÔj5¶­€;Æp“r�H¬†2;fÛHÃ5Z‹Z"‘@O(¸x¨Á0 >ŸÏKåÕªW{©™ULF9PuÒÀíM­VÏ Æx{{wèÐ!""ŽëààPZZzæÌ,54*•JÀ†ÓFÝk=mSzŒ)†tÑ|±“ã<Ã_š£n SµÌÍÍa¾ ÿàe`g.ÂÃS?�¨¼‰/òx< ¥U×@·ó~eÒ—‰{ÀëÅí±ÀÖŧÉFEEuéÒÅðõ´´´‡ÖÖÖÒ/Aãþýû/o×ñññعs'¨vnÚ´iذa¨/™™™™••µ`Á !ˆÊï½÷ÞæÍ›.\hò€&{ñƒM‘(€†Ê›8ÿéÑ€7�N@(À¥+óQB ™lÈQ§n|ºž 5“Éämá©2Tº}:ÎC÷!—°þ ]p†8Ãáðù|;;»N:ùøøtïÞÝÙÙùõ×_·±±TJAAX,†ZP€ê¨dJxw4”â…ÃgMÝx-jì¦#Œ§èµ@c‘cHHÈ”)S&Ožliiùý÷ßÓ8Iã³ÞŸ­ß^}õU�˜„„„ 6œ8q" �ÞJJJú믿!7oÞ$„ÀÈ™£GBó'Ÿ|²k×®   mÛ¶™5“ýƒk&€zH3.ÿ !666„ºº:™L%ðàÚÂižØ{¡÷Ðoaï˹Π•y&“ j4:޳ž£ê¯l�‚Ò0`ll7˜d*•Jaæ½V«õ÷÷/--½råJaa¡\.ôèªì@¤g¢R©ÌÍÍaZ\£T*Å~…Bh„ú¤¨Ëð7—Ú4/眞={îÞ½;..ŽÇãÕÔÔlß¾ý‡~ðôô$„<xP$i4¥Åf³½¼¼ cûæ›oFGG{yyYYYåææ^¹råË/¿Ü·oŸ«««§§gqqñŒ36mÚdfföÒݬ’’‰DRWW,>__ß{÷îÁ[ 2›‘‘fgg8pÉ’%'Ož¼|ùò… *++ýüüLœÉþ©(P´ôQ¨p¢²²ykØb‰õ”«Áw±é2-�N¤¡º‰S>�P[jEOu+a«jRñwåðC(¼P2N£Ñ”””0™ÌŠŠŠ=z¬Zµ *.|>F{ÀNà@�0 †äâüHõ�ô’mM•J%àrär9ÄXÍd :� Б¾Ì£ÃÍ —òÏñŸ‹ÊÓOj2™LOIÚhÔa¨<T:ðóDÂtME9£GV(™™™„ 6DFFÊåò˜˜˜ÈÈȪªªQ£F­^½Æ'[[[õÕW{öìùöÛoÇ¿bÅ øï¦¦¦B2*44”²wïÞ,Z´èeÁOOϘ˜gggø3,,L¥RýðÃðçœ9sðB^{í5úƒíÚµ‹‰‰ñöö;vìÒ¥K¿ýö[¬åDFF:99™\¡É^X”ƒƒP2�‹78Î�‚!üÅj˜¸—Ëå8XK;„š©�íþf*Whg؉`@‹C£äJ¥ª¨¨°µµ‹Å999b±èg>DARŒ½€M³æ5¾î„z˜CÃŒ_3‡Œ™¬¥k„ñãÇ?ÿäóù7n4º¥ŸŸŸÞ[111zÛtîÜÙhwt«5 ªáŸ#GŽ9r¤Ñ-çÎKÿéîîŽwÃðŽMœ8Ñôä™ìEF9à—1Ó…J-¸êÇ>2 èޝЂ½ŠIžtâ˜òÒKʱKÙ̃L> *B²ž3}þ2™¬¢¢ÂÞÞþúõëHÀ«¯¯GTà 8C¨]A& ëÞ1D0Âý è5Ù3ʲ³³×­[g’#3™ÉZ­a¿$úYŒch6Pœ1|¡GJc¯>dÀX,—ËŶx u£ÁÅc£2Ð�«,P¼þº¦o_s­V'?vŒ—Ÿÿ_mZµ ÚQ‰ !¥¥¥%%%ð.€  J·¡Ô \N+À4#i IãŸ:î±-†H.@è2”÷Çì"1¦@OV¥˜;"ªQ84ä†áiÐíSH¦ÐSE#ƆÝÞ°„sÄõ6{l˜øLúrµv>‘UTT<ã0"“™ìEšL&kÌKB® p¾Ž2ÃùžX€. é±ÐØêOO@§ f« B£R©x<ž‹‹ŽÁ þþê+W8..:.W­R1  ÃœCŠù=xúŠè1ØË çÆd2y<žT*¥Géðx<CýcLèáà&“)“ÉšþÖÓäšx·éhI¯­§9qjc»5< äPÐHö¤Œ-Cd"ƪPºzK-9mÛJKKM‰]“½Dfcc# õZ°»|´R©äñxXeAÕKÚ}`zJ(‚r3¦Å°Ç�œZîéoµP ÝÔºçÌá'$("gq´þÿ="™˜*ÄQ‘†: ÀR· 5D!Å@¡!‰nÇCÀëXÚÁs†»dz–Zib­ [vvöËÈ©{"³°°x¹Jk&kŽR˜°$ƒ5S$F‡ ô@hŒf€* ñ NÞÄ ’­éš?¡Æ`¢Ñhaètºýû™c?«WuWëtHŽÁÆØ˜Íp(ÎŒD"¡»5P Õ<IC+6Á¹é-`Kà`XöŒ9ÌÆ£3„Ò§ž j¸,Æû€ûoz‚N3¯ùî‡nž%ÿ;1Èå<¥uêÔ©m“Êà ùÔ K“½D†õDH…é( ðJ(Ãd2œœŠ‹‹e2ŸÏ—J¥€IPÁ¤ he‚Ñb9° ö¸ A9$$¤{wÝwß]:—Í}û³z&�h¸P}¡_@¥ t`ÏxD¼@z®(ÎÔA¥ÇêàïÈ‘Ñk½û'½ÏOôY<Ö³@ŽÑ#ÂmÇž$ºïµ9XhtÿXR¢‡¯<³McÜ,--Û6}%55uüøñuuu¦ÿu›7H£AŽK¡P€[çr¹è"Aå«Í€.=b±X`òäÉ»v킊½za”€3ØŽC‹ c½råÊ… r6›{V®ö'äKB¾çñÀõƒ:'ªæ ò§r¹�Òàƒp�!�Z0°�¡Gþ É Ñ ü)¤×h ŸÉL‰5“™ÌdO“{A¾2xmlaAÒnåŒÄbñ®]»p¾�iàwA' ¹¹¹T*…ÎML²¡Ͷb±X§OsJK‰&Fs…-„«ÕL& KDÈ À¥:ì%ø|¾X,& Ìoàààøä w� ”1Õ› Š„é&RL4•Ë0›„s†ª9x+PÆÍh¾ _4œ j4jℱ.eTgs˜†á¯ÃĆ/ôÿô)åìÆžÑ™3gFEE7ŽróæÍM›6ÅÆÆvïÞ·‘H$ ,2dˆ^¤ÉŒÚÞ½{³²²!ŒŽŽ–ÉdóæÍƒ·Ö®]kooŸššzøðaBH``àìÙ³ !‹/†o×ìÙ³M÷ÐdÏ’[,AGC™†ý>Ý‹/,2!œÀ‹L&³ªª R؆‰¡†DØ@sø0K§Ó©_Sçà]dêÈD¥ G€Ñ8kšæ ¡°œÿ»’°˜�� �IDATÉÀFxƒÚ6ºÒ¡›íA˜lB:It ´ ÆC ä R'ºlL£ÑÊ¡€Lô˜Ä*Ëô Äršà×áöF3~ML°¦ÕT@säóD0fcxþóÏ?Ÿ?\XXøÓO?•””Èd2‰D"‘H€’ðàÁ¼¼<…B’b*•J"‘À}‡Íàu“%''oܸñõ×_ŠŠZ¼xñ/¿ü2a„»wï.Z´¨²²2:::;;{éÒ¥={öœ2eÊ'Ÿ|òÅ_,Z´èèÑ£‹-²³³‹‰‰©®®6ÝF“=¡À3�Èû#‡ÞÂP�?BOóÄÕ=2ÐÀ;CTAG�0Ya(–CO?c2™æ#Í98¬ ,ÞVãA€^À ”ÏAaid.`€U‹Åãñär9’Âq‡8¼ÙXà­kØ­.j²–zKþ>|xÏž=ÉÉÉR©4::zÚ´i¾¾¾={ö7n\xxø¦M›° (66„¥?ûì377·ÂÂÂøøøÞ½{7®{÷îùùù¦»<f̘k×®ÙÚÚVWW …B>Ÿ_XX(¼½½-,,<xzùòåÞ½{WTTp¹\33³’’Bˆ··÷Çœ••‹&3ÙS†666ÖÖÖ°„ÉØj mtúàAÊ Þb³Ù0þ�Ó/àÊA ùo„"#Ðq�ì0O£Ñh ´*µŠèóªÏ‚-ÄdÐÁ!MÏœ(‚S èÂÍ0aˆ4â@tEg›sW §àè%Êh#Ææëà»È†x¾€¡5±™á97öâc§ã4rŒÚåË—ÇŽ{ìØ±wÞygýúõ=2ºYUUÕG}4qâÄcÇŽ©Tªµkך¾ó`§OŸ>wîœH$rvv;vlQQѶmÛnß¾ää䤧§;88xyyAêrÛ¶mÛ¶m{yç>˜¬5X@@€¥¥%!D(š™™A±C̡ۅ·0b±X"‘Ho¦" §ÁA¨Þ†õôJNNNÈxf±X™Ì -Qº¼Dwæ#˜áëHsÀFN”¬ÆX¦¢P-w¸…:z,íæÄŽ 1Çn0µ�F…ó¿ !Ú ' çå<GÔ¡ÇØ -#ánO_¦ž=QhØ(}ÀËËë7Þ€ß;uê4vìØàààåË—ÇÆÆÞ¸qã±û=räÈÍ›7õfçüËmΜ9™™™Ã† ËÍÍ?~ÇŽ !ôÓ9~üøtêÔ)==¾]ÎÎÎGŽIKKûæ›oÀk˜ÌdOjþþþ–––ÕÕÕEEEÈ"Ã@'›á O P?­®®cºY3þðæÐ`‡„> ÿ;óM§Óõ$„Ãb]o`6ãq1×û„½é‘¹‘Ì¡bÊÀ6tÛ 2 ±~`ÌÒÒ.K;¦gæE'Ö!vvvÝ»wÿè£"""<<<�o¾ýöÛ÷ßßèeœßÖ·oß÷ßÿĉ«W¯6Ýe¥RY[[K?Ê …bÈ!cÆŒqssƒ»W[[«×ÕÅçóÇŒãçç—™™Iß[“™ì‰,55õáÇ(4@´aP±PêÕ´¦'D …¢¨¨ØØl6—ËÅÑ¢ÈøB4" ’n| ñ F$@nÍËKõÁr€\&“ ÙfÔ{6¯åéé ñtaöØÒpKKK˜…ƒÅ!.—ËçóHPfói,ËÖÖV(Ö××C¬£WÐz¬N¤nl›ÆÞ5ÌJ=GŠöSÄIÏ=§÷d‰µ)S¦„‡‡?|øðàÁƒ„[[[&“Y\\liiéààpñâE Û™LfRRÒ?þHár¹µµµÅÅÅãÆÃYmÿf;qâD=¾ûî»Ë—/»¹¹988ÌŸ?È!§N*//ïÚµk^^^¿~ý6mÚtæÌ[[[˜wêÔ©û÷ïbzÚd&{R‹Å …ÕÏ g‹ã ’À· &ÐkÙðÀø†ž‹ •ìªAÎäèE†Ò™€FÓÁA·fÄ×WÊfR©HXê§U¥oݺh‰2�N8"2ÓÌÌÌP¨ ` !­á¬`èœZ­®©©V¼uÆš+éî%FÛÙÃ/r¹Ü°H£P(är90è;8ó”Ïçóx<uƒáí¼¤ HäpÂM”Uè–¦qƒ ýÏU*•pª …÷€ù4;±ì¤7ˆú™k`ƒ jß¾=ü¾páB‡“žžÞ§OŸ5kÖ\»vmîܹ½{÷~å•W`zà–-[222Ú·oƒsÒÓÓ§M›¶`ÁÓw~øðá*•*77—²qãÆ¾}ûöìÙsݺuééé¡¡¡sçε±±ÙºuëÉ“'/^¼¸zõê &@”“žžîää´páB+++Óm4ÙSä—ôFv¢˜&ø)̤a‚ ¶Gð°··¯©©A·Žô3Œr óË0¸ÒP1‚‡òÆË^°XL”bCâ5 ]C‰ˆNA°…:ÅÅÅôààôx½´¾‹\5$ˆ›˜–³Ç@ÎèÑ£é?çÌ™ct3Ä•~ýúB|||>üðCÓÍÕ»“ôÍäñxz·("""""‚~eáÂ…¦ûf²g·.]ºØÚÚVUU!�àRšP<%\ÿ’‰3\3™L…B (Ò@# ­3l(÷‰ø+wB5p ªÞ³‡Íb‘·ßV;Ç£֠Ü5¶¦Â>+kd }�‡m̘1cûöípÚXBˆÅÎ$6Å.Ó3óAŽÉLf²—Ý®]»VSS£'hi1:±á F<ÎÎÎ …¢ººˆab±xÕ¤A:dž1a-d€Ów vÁQoÇ[FE)„BîåËî„ÜÅ#¢ �F°Cì—$ ]ŠÈpÃ  ÜÜ\šºàwðàAÈé!ØÐíô€OØmаdxén͆øì)5§1w×tDe¨×‰ÈúÏJò@¯.¡Æ@˜ çùXiiiæ®è}LÖ† ÄÄè‰8zÃ4!’�9N:*++CáWÀ ˜Ão°®€ü1ˆ`�`Hýƒ§.-e²ÙlGG§¼¼* 1ÃAaNæýÀ£)•J@@Wà» ;d±XW¯^Å0Pþ¬ªªÂ™l ®®b2 !àˆ ûóæÏ·®ÞLÁ½wéíÿÙì>!Íœd‚œf™X,nÃór|||Lÿ≧Õg½² 8xÎe2­Ìår­­­aP!  W ÂzÕ¢§¨†1 D$‹`z 6.,| ‘ð°¶D áÌ,äÐZ¨L9,k#Gý ²$€ã€E, 2Pó=©é™1%Ö^´={fß¶a;}úô ˜—séÒ¥ƒZ««k§NZç¹A`��aÕqÀ$Ò  3lêëëÁ›C(Àb±¬­­ëëëIñ ³aØD q~aÈ tÀ¤Ó)Qþ»> 1&ƒ „žëLŸ6ŠBÔ‚‹2 ð'ÍÃú 2¶áÜp‡FùWxª†j›·ƒ….q{º|ÕtˆCþw>4=SÀðTi݇ÆN ×ðÄès0:ß³šÀr¶› ržÉ‚ƒƒÛö¼ ù2‡=0`@Û.É‚nµL'ƒ$´¸ƒ×€n@Ï–†iј‰2>ŸoaaQ__avû#ÐS¢‘†Ãø|>›M„B¡B¡�”ý4333™Lliì�E‰é;ä¹! ìáDŒ®Hi ÿMpiz#Ýšn Ñ›=ªw{I#‚͆ÌÄØ¼êæ<<ÀX²2 98¦è±»5ÜÌðü ¯¨Wfk¦™F®7¡PHŒI!µ;qâÄ {* ÛðÔjµ'Ož¤U$Z›aÑ571 †s3i6A�œZ­–ÉdàÐU*Õ˜1cÐÏb£%Ö`°A#ðPІâîîîàà`nnakkëêêjee]™þþþ“'O¶±±ÁèeXŽÂôZpp0Ýî Kè qÊ5@D{|>¶‡£p¹\Z«Íä�M‰5“µ.+((€Îß÷Þ{ÏÜÜÜtCZ³a'&— ÝØrZ5Ø—Cÿ$ÿ&Mt:]bb"–FW4H$***‚LŠÀqÍÍÍ|}}ÃÂÂ:wή¯¯yôȹ¸¸¸¬¬ àäÁƒ{÷î…Q¸¦†¦¤{åææB~N»Á§àp�'ØxD7Kbh°ç&ôð:]ÙXFËh$ÑXþŽZû$?j”J÷DÝšFƒ-97oÞ\µjþ9tèКššK—.}ùå—„­[·^½zu×®]GŽmBÈèÑ£aáÓ¶­°°péÒ¥ï¼óÎÀ !¿ÿþ;ÜOOÏ>úˆÞr×®]§N"„ <xÒ¤I …bÊ”)ðÖ¦M›èÄ]^^Þúõë !VVVŸþ9¼8kÖ,OOOÃ^Úwß}òéË–-³³³£ÛwÂÃçOŸ¾zõjÐÁÓ|¾V[[»sçÎþýûoÚ´éÆpùÏÅöîÝ{òäɤ¤$øsÙ²e iúî»ïöíÛ7£ï¤P(Ô{& wKßÉÊÊJl/Ûµk—gΜٶmÛ‹¼“/2Е>6¸@|Åy¤/cp€ND†i7˜Ë UŸ!Æb±° ˜cÐ'. üüüBBB¼¼¼llê Q»ºŽøóÏ?Ï; l6›]QQJ‘PXšÒÌPÕX.—c!GbC!Š40#ðÒð´uàÜè‚ ¤¦‰PóÅCX{"È1dx7K 7{Æ(°QÈ©®®NIIY¿~ýðáÃay²`Á‚_ýU©TîØ±cçÎß|óR©¼|ùrffæáÇ۵kgaaÑæñfΜ9çÏŸÏÏÏŒŒ$„ܾ}{É’%S¦L>|x—.]ØlöÊ•+¡ç.--mõêÕß|óM}}ý»ï¾kmmýÃ?¨Tª-[¶ÄÅÅ 6,;;[*•Ö×׳ÙìQ£F3fîܹƒ š>}z¯^½¯^½:`À�½˜6mZVVVjjêæÍ›GŽ™½aÃø <ØÕÕuÛ¶m‡:zôhJJÊÔ©Sþùçàààç{T*UYYY¿~ýžÙúöíÛS§N-**ª¨¨€WV¬X‘˜˜xáÂ…o¾ùæí·ßþå—_D"Quuµ¥¥eEEů¿þúî»ïNŸ>Á`\¼xqáÂ…÷îÝ£¿ l6ûçŸÖ»“#FŒpqq‰Ÿ6mÚ¨Q£~ýõW\^¿~ýÔ©S_|ñEçÎÁúõë·oßž••ÕrwòŸQ>Ÿë}¼K8j“`€CPç4‚µ¿J¥š3Gûæ› ¥’Acÿ~ÞW_ñ ú‚C 1ø¨¨xhg§•ÉØ C ØØØ888ôèÑ£W¯^...–––íÚµkHÜ)íìì `ccsñâE‘HT^^~îܹšš�B©TŠ¢p@<Óh4 CËÕêêuPBÌ€KãóùußÕ™5c2™õŸ×s—r¹µ\ø,^>&èpL>Ø/‹ô�‚²†U Ñ™¡­1ænúmkkkxPàÙMHHØ¿bbbHHÈéÓ§?ûì³ØØØG=|ø°•CΩS§Nœ8qûö휜œ?þøãév²uëÖ={öàŸ^^^YYYï¾û«+!äµ×^;v,L¨spp°··‡ß÷ïßðàA¥R)‹AFúË/¿ôññyðàAee¥¹¹¹‹‹ ƒÁ¨¬¬|ë­·222ììì O@$i4š¼¼¼òòò:p¹\ø-Y²ÄÅÅåÓO?5kV^^ž½½}QQ‘‹‹KKðîììì&Nœ8wîÜóçÏ[[[?—}zyyeddÀúÌÍÍÏççåå•––Âï/^ôññ9räȘ1c¼¼¼ÂÃÃóòò¬¬¬ºvíš‘‘Ñ¿z‡‘‘‘Ó¦M3¼“ååå|>ßÅÅ…Çã•——ãë÷îÝ[¸pá¨Q£˜LæÝ»wmllÄb±R©tvv¶¶¶†ß_ÞĪîÒŠ/ØÚ`Á@  …ØIÈÄb±Ì͵«Wóúõ3ëßßlÏ& iÄ¡Ô àëKTNœ¨ÌȨ0@Çd2ÍÌÌÚµk×£G‘Häææ# 0‘UUU¥R©ºté"‰|}}­¬¬°2{†Xs€Ähã´š!E?åñü7_ ¡ Ѩ:¨õ †æïÏÒb?aô;!„à(O£&åšSÞÓ›à G 3üHóCUT?[³fÍ?ü°oß¾_ýõÍ7ß4Ü¿–2ÃÁ<ô û1<CÃ;Àãñ@ °°°°¶¶¶¶¶¶°°àr¹´Þk‘Ðcj9Ç¿wï^ûöíAõK*•®Y³fîܹaaa„:,Y²„’™™™’’²eË–ðððÖù­ûé§Ÿ–-[Ñ¡C‡¼¼¼àà`Ðæy.vâĉyóæ­ZµêwÞ!„Lž<ºêŒ&å.\hgg·eËBHÏž=—,YòDúi^^^&''çÑ£GÞÞÞ°®IOO/,,|÷Ýwq³5kÖüõ×_Û¶móöö~î7S*•^¼xÑËËëÿþïÿ¢££áxîæîîÎçósrr =<<ø|¾««ë’%Kccc+++srr~þùçU+Ÿ>}ºƒƒCógkk ’““³ÿþ 6¼òÊ+ÇŽÛ¸qãõë×Û@9kûòBz1¶¿@L p8èÑA'Ë`0t:2v¬68X®ÕjÏœáýõ<58î3ê¹\MD„",LM¹våí-õ÷W±Ùr{{Ž‹ËEW×Gvvça¤ÓéÌÍ™—™—)dåì|ƒaegU×£®²²R¥R=tzX]U 5=§Œ³J5]5ê…j†ŒAâ !„|O÷¸_1SAáíàéjôÓYxpÚN¡¦YÚFQ‡P|-ê0á×Û}%éöt•”-@©º¥K—æååMš4‰>¼F ßôàWÌ"œNÔFÔAÒ© eììì`ÅY]] '¦V«qtçSBŽ»»{çÎmmm1o¾`Á‚¤¤¤Áƒ‡……uèÐaéÒ¥°rLHHøóÏ?[-äüøã«W¯îß¿ÿÞ½{###ßzë­çµçôôô¸¸¸Ù³gÞ�äBvïÞ­·¥B¡ˆuppX¿~=Lù {¢¶•ï¿ÿžÇã-]ºT.—ÇÇǯ_¿žÇ㥧§?xð�O`åÊ•iii j‰›)‘H.\¸pðàÁAƒÍš5ë©!§°°pñâÅð{RR’^:55µ¼¼|éÒ¥»w‹[¶l™¿¿?<o ³ é¸ýû÷…œ3f<ÑÉØØØÀÎ ! ÇŽÛ¹sçîÝ»«««¡röòÄ+ôØMôŒ›‚¤xœŠŠ ˜0 e Œ˜LfA./4`@—‹ª¯¯3›Í¾~Ëdj:wfRG©­eݺeÉç󭬬,,: þ<ž ›m­Ñ0 Ñ•—W”——›ûMêX#vRJªªª|,}JjK|ù¾—o\æ^ášÕ™É¤2¢"DGˆŽ°™ì¿= “ÁcðTjÃA!B.ƒÁ‘rС«T*‡¥³×1«˜Ä’àŒú†àª[Rpä6&MÖBöÈ <xð·f³gÏžÍb±&Ožüí·ßJ$’˜˜˜„„DÝÊ­W¯^ ÃÍÍ­‰ú‰ìúõë“'O^°`ÁÔ©Sé*‚ÑG¥ÓévìØÈúúúºººæô¬h4š²²2£©K™L&‘Hìììà+÷ñÇïØ±ãòåËÎÎÎ-}K»víú,wÒÙÙ¢=zñÕtþº²²ÒÚÚ:::ÚÖÖöÀMl\VVÆf³qµÔ„ÕÕÕÕ××Ëåò!C†,Y²V wwwïÑ£GUUÕKý%ÇŒÊBC%�0CÖßeLx«!S¤¾z•Ÿ–ÆÊÈ(JÕjõ‚ Åb±V«MKcètŒÌL¾……ÀÝlÛVíàÀýå;WWWµÚ[­öË;ùøøÔ××çææJ$Ö¶¶ž;† TTß-¼ëääÔNÝî–øVeeåÕ´«š3DÇP0Xjæ¾8LæÙHW¢¹£ú U §Š£V«Y\j¾1 ‹Ž y@4Îe‹°€:ê ( ¸‹zðÂÓ&¢œÖc555 jµZ ¬[·îéŒ&þllc$ â\pZâY!Çи\î¼yó˜Læ¸qã/^leeuæÌ™ÊÊJ‡–Èá<Gû믿"##u:]QQ‘X,¾}ûv·nÝžqŸ0ZíÁƒ¿ýö!¤}ûö£Gæñxqqqnnn§OŸ–J¥"‘ÈÕÕµ²²’Åb>}À{àÀ{öìùðÃOŸ>ݽ{÷;w¦jµÚÐÐPÕ––}ðÁÝ»w¿qãFjjjAAA=ØlvJJʾ}ûŽ;Y‹ºº:•Juþüyà‰öêÕëy•[h+//¿uëVmmí³ÌŽc³ÙŽŽŽ½haa‘ššzõêÕàà` ‹œœœÁƒïܹÓÇÇçìÙ³©©©¥¥¥½{÷6úñW^yÅÏÏé”h½{÷.))IMM­¨¨èÓ§!dÓ¦MñññYYYÎÎÎ.\prrÁÁÁ‡þð÷lÙ’››Ð·ñEfÕè ;tD²Ùl,ð`±³ÿèÄ‘:Ü¥‹’ÉäK¥Uwïr««Ù›6mÂ6RB‡Ã‘JJ%[,fê ¬­-x<žL&+//W(:t¨¨¨ÈËËc2™ŽŽŽÕÕÕ|>¿}ûö<¯¨¨èÒ¥K¹¹¹ÙÙÙ 4Ù?Ä$h4Î%#›¡ÖªYL‹ó·6¦Ë´Z­d›Ä¬ŸƒÁ’²3Ù¶jÛšš¼"`Üaö Øq$ÊœQhp°õ ƒÁX¹råÊ•+q­­„O仞h{™L†TÈžI¥Ò²²2X J¥Rb¬/ÕÐX...111*•êæÍ›´îƒÁ°¶¶Ç„8“ÉôóóëÙ³'!x<žµµõ¸qãJJJjkk_ýõèèèÖü­û¿ÿû?­VqðàÁk×®™™™ùùùݸ´´ÔÎή±õ;ƒÁ°°°wvvf0–––æææeeeeeefff;vd2™!!!£FêСCaa¡V«}çwúõëÇb±<<<`Ëêêêž={2™Lww÷ÈÈÈ–———••õîÝ{þüùÿoX¬ž={âI …Âððð7ÞxC£Ñ”””8::.]ºâ6GGÇ>}ú@MˆÉdzyyUVVÂüýýÆF7oÞ zº’8ƒÁ€ÄÚ÷ß?fÌpÜÙ;w|||š™¼f0:u‚vëÖÍÆÆæîÝ»sçÎõööÆgrܸqb±¸¬¬L$}ðÁ€µôó öèÑÃßß_ïNFEEUWW—••uêÔéƒ>�ãééùꫯöîÝnÚ«¯¾:mÚ´Î;;88ܽ{W(Κ5 ³yF¯ÑÏϯ*òÉd²ššš7n\¾|™ž2 V«…B!¸ZöG•e¸'ôÀƒÁd²œ5ööjWWVE£¤„ ¤}7j? …B+++›víÚÁ÷jÔ0 2 EEEõõõUUUÕÕÕ'Ož<qâÄÍ›7ËËËhÉ�Ô§Ñç!ª½!9˜¡e°óØl6[«Ö2®2TRFH˜R# Rrø´@ØÇd2;wîìëëëää„釛7o:::~õÕWzÏj¨CëUnÖy›¦#-ü¯ …B(Ý=Šán›Ãj£)ò†;�µ…P#Â:uêT±XìááX®T*ïܹ“––Æ ÍÌÌ”J¥G¥ùBmÏþüóOssóK—.ÕÖÖÒ}zváÂ…N:YZZ¶á¬î±cÇÆ_WW÷t¯¨¨ÈÉÉ!„ôíÛ·éÜÚ‰'FŒцiƒ”èQ£d2Yk;·ÊÊÊ{÷î9r$11("“É„œÍ+(Ü©ç€pT3¤.5ÒÀ`Ÿ,ËÕÕÕÑÑQ(º¸¸¨Õj333''§àà`kk뜜©Tjmm „øÚÚÚ¢¢¢’’(Aƒª´Žj4 ³À{âL�Kpˆô¬kˆxàBP3 uÀà¹\Ž:üÁ5B·éøñ㣣£»t邊G ÒëXhrŒÒôî§QˆjäО½ Ù £ôŒÕšpn0!B/¶C¹ P êàb¡Þ©Õj!Ü!„deeÝ¿?""B¡PXXXÔÕÕÍê_¤>€Ð^ŠÊS+7{{û—º5ò_e´$%d«Ð} > Öu „Ž® Êé0|4Î� …€µlÊ€/Ëf³år¹¹¹9¤O?D"®†˜èPGÁ“‘H$ò²°°€±Ù¤Aë®úLuHÃ<$LƒÓ„kÅ8 öÃo Act2t¾Ø+ŠZ;8×Îh0xƒl«K¸\®^ÕèqvFe=õö@ÓF3â /OF©TÂI"º` i˜~|µœ>µJDë·Ùe¢V«AD ­F9­ü ñ1F24°Ñ_ƒú 6„¢>&i¨ _¹rÅð]œ¸ƒ‚7Hrãp8� �–ä|>ÿÖ­[õåñxr¹ÜÖÖV <zô¨¤¤¤ªªª¤¤¤¦¦*‘²hµZœ8@÷ĆÉ:tÐO5jö�÷„¢éø�¢P"@—Š3Lù|~Ó$éçò¨4±«æBûÖZ�� �IDATq¶\©‰£7!EjT±Ô9Oã”Ûð¼œâO7ö·áÄ!¤õ«àÉ�u zXž\0ø_T“ÉdB¡ze06‚è¡¶¶–ÅbA£|›{´Z-tˆ_�@Rvfff@---µ´´|ðà,Mêë뱊€±­´†“°q ¡X˜|ÃkÄanZ­2Àô–î�âÒ£zLÞ¯åÌ9FÌÛÛ[ ´Úñ'ÏË0.nQëÖ­ƒÁ€2~Û^ ´òÜŽÚ„™Ó´*3]âÚþØ,I¨r4¢2Ö�œÌÌÌ�$ °\__/“ÉÄb1“ÉŽŽŽÅÅÅ v ‰„B¡L&óôôÄ¡8555XÂéT*Ôß„«€ø âø›i ´€q} a€Rl™(æF¨}-ý¿ÀƒÒ ‚æ$T0[ˆ²Ù¤ 4$_4Ÿ†ëi£ù7ÃÍŒêÈá»L7AŽ+((xðàÁK!Xô,fccÓÃø9Znnn+¬«?w‰DMPÚþq¼÷ e @.— ExèV¡‰ÔX¥§icôŒ5ÁVPp:ðY{†ª2öÁX[[+•Ê¢¢">Ÿocc¹,•Jeiiéææ|6ÌïA4ƒs}d2‡°‡†&àªåàŽáŠpvð ʬá(½~{:GÔrf(»ÙÌPÕ0etBMíkÎÞ½š)AmX+ªÇb¶ rŒ˜F£‰ŒŒlÛ#ÚJJJÜÜÜžš±Ö|S©TÑÑÑÍéô|IM§Ó=zô¨]»v­Y1iºËÈ÷$ ¡É1pÊXÿÀ°bbì•Áš<b�ènÁGjkk¡M`L,—””p¹\+++ Ø* ;;; ;¬¬¬t:ƒƒb�Ä(¨‡†¬H8=äAàdkÜ’âêêZXXH‹[“î�=‚5p¬­ÉškÿLÞ© “¤ÿüóÏñãÇ¿˜ciµÚ6èètºÌÌÌQ£FµÚ3¿Œ•6›%ŒNпC§$â 8w,r�8Ñ6À�3=-,, :©¨¨€Ê lS\\¬V«íììlmm E}}}uu5[¨€)/È aßUJ¥ÎMí0¿‡£?1‹HK«ÜÒ£Þp&2ª ybôc¬—¶¢›oH#}0† æÇô" ø…Çãa2³9ìjÜ•Ññ£Mç÷ôÒªFQã+zÍRF&ºÕÉ9&3Ù¿Ô°î ²d0}k˜ˆÇlútñèÁé©-€7 J3Í4 êêêpþ´Z­®«««­­577·³³«©©áñxB¡è°1„´GƃÒq dÌx<„2ÀOÓ�z$dØ §P(¬¬¬d2€"’¤rPl ®¢15!Œé™§¥Èh¼AµM=ä k!4)Y� ?HCBr‘TÝtrÏ¿iMkœomˆ|ô 9¾-‰ºwïÙ«W¯¸¸¸)S¦<)Í©¬¬,22'n5a«V­‰D/¬Û³gÏØØXL1‰D¢íÛ·?ßCÔÖÖDFF¢(í[·|}}###233/^¼Ù¯_?‘HcoÀ¾úê+x«gÏž"‘(##ãüùóþþþ‘‘‘~~~W¯^ýý÷ßaƒððp‘Hô‡¤=©=zôH$mݺþ<qâ„H$‚ÁtÏÑÊËË£¢¢"##»uë¶k×.…BñÓO?uîÜ922²K—.¥¥¥555o¿ývDDDXXØòåË% }†={ö„-¿ýöÛÒÒÒÈóôôœ9sfUUUAAA@@�ŽnkcFp¥Ž#�º-ý Ž8ÃÙ9� Øj˜Dg«jkk«««Åb±L&“J¥ …>%•Jåry]]]eeeQQQUUUiiiUUUUU•D"ª4(I#Öò¢GAÔÒS� <1”’S(:JJ¤óÃL±ËÑD_ŽÉZ<±¦ÑhÄbñ'Ÿ|2nܸÌÌÌaÆB,--ËËËÿüóÏž={:88;vÌÇÇ' @¡P?~Ü×××ßß?%%xz÷îmii9{öl(«;v ˆˆˆ‡ÂÂÂóçÏB,,,(—ËÅbñ Kd…††^»v-??ß××÷äÉ“fff"‘èù";;;))©  �ÓÐo¾ù¦——×±cÇbcc'L˜pÿþýŒŒ BHrròòåËa‚Ø[o½õÖ[oÉåò?þøäÉ“vvv‰‰‰3gΜ9sæ˜1c&NœxéÒ%³{÷î­[·º»»ÿSÇó÷÷ÏÉÉyøð¡¥¥åŸþéææftÒϳØÑ£G;uê´sçÎ;w.]º´gÏžS¦L™9sæš5kBCCß{ィ¨¨ŸþùÒ¥Kõõõ›7o¾qãF×®]á³óçϯ­­ÍÊÊZ·nÝŒ3nÞ¼ ·=33sÊ”)ééé Zýb(|ÿHêÜ1ºp 3ÀŒ………££c]]X,–J¥ð:Ž Åu:öQÒÄe€ˆ6àȤÕÕÕYXXàpx·¶¶º¹\nQQ‘………L&ƒvèý¬¯¯W(‹ Û Šð Ô„0Û-¨»( �Zƒê ´œa˜X3Ú5i4©EW’Û†ínN0a4tЋrhÃaFC ££Í¹ÆÆ‚f½¨«ùd«'+êÊåò;w~ÿý÷‹-***Љ‰ùñÇaEsäÈ‘¤¤¤… 8p`ñâÅ………111Çÿꫯ/^\\\œ˜˜¸xñâ’’’¸¸¸C‡Ïž=;99ù ?ýôÓ€€€yóæ­X±bݺu6løÏþó|µgÏ777|å½÷Þ»wïÞŠ+òòòÞ{ï=|ý£> =z´Þ@)väÈ‘ÁÁÁŸ}öYddäŠ+nß¾­÷Ù=z¼úê«ÿ”;³¶¶ž={öáÇóòòªªª¶oß>zôèçÎÝš2eÊÎ;<x’’2fÌ{{ûƶ سgâM¶yóf@0}úôèèè={ö´Ä,»Ve€7Pº�ºNV¶µµ4iÒàÁƒÁc_$$|бªP£½h9!ªV«+++!«¦T*e2p۠󦶶ÖÇǧ°°ðÞ½{7oÞ,((¸ÿ~QQQYY™L&HèØ±#Ðpÿ(m€µ­VËçóQeç’Ñy3ø E4á K9øA£7Pý¿7P Gœ5ñ)ܾ™T zëÎgûG§¥x<H”"–h Ìð2!¥©gF3lp ¼º'b–3ûµ>|øûï¿ÿÚk¯õíÛ—Íf¿öÚk½{÷NKKÓjµ«V­:tèЙ3g,X:a„ãÇWUU‰Åâ-[¶L›6 žrBÈ‘#G¸\îìÙ³bbb,--gÍšµqãÆÙ³g×ÕÕá0àffff«W¯îСCBBB||üСC_ÀAÏž=kcc3hÐ ''§³gÏ‹Ÿ|ò‰T*]µj•áöóçÏïÑ£Ço¼:::4ÈÎÎ?ûÿ÷VVVqqqÿ¬/ëÙ³ço¼±jÕª)S¦ôêÕëõ×_o‰£¨TªI“&ÙØØ|üñÇÎÎÎëÖ­;|øððáÃKJJp›ØØØáÇ7=Ô�ìÀ999Ÿ}öÙ¿!•ÁãñPÐç(•J�•êêêk×®ÙÛÛ———ƒß¤§À6˜¼B—‡ÂõtC%V8À‰Ëd²úúz�e(–\ºt©¦¦kååå=ªªªª©©AM˜¬Œã±QÇ/clíÔ“–ÁÑŸ¸ü 5ÚuB»7\B©‰±Ö²iަߞ9sæ·ß~›’’²sçN 0b9‡ÃáôèÑC*•^¹r%''' ÀÃÃcïÞ½çÎ;xð`xxø½{÷ ñ\$…‡‡óx¼«W¯6,22ò±SäZÂÔjõ±cÇ~ÿýw//¯eË–•––¾€ƒ^ºtÉÊÊ Ä¹/]º/æçç«ÕêÀÀ@£ÛÛÙÙaÒÌÎÎ.<<ÜÆÆ?›——ÇåriýïÄlmmããã¡ÑïÇlß¾}KTŒ бcÇ/¾ø¢]»v,kêÔ©gÏžýöÛoi.{||üôéÓ-Z”––ÖôïÝ»W]]ý/QÛ“ÉdzB)˜†‚žB¡X³fÍ… ]ø|>`“É2dP¨ !�ÀÀ ú41IþÇã©T*¨£@& †E*•J¹\.•Jkjj<x ‘Hª««=z?KJJ ­­¬¬Äª fö4ÍŒ3è™Ó(;á 2¼a3:ÿ¦�~�ÄRÖŸÖü±Ð4>5ñ©ÆžŸâ@Mc!­Cc¸óBÓ§Ø-ó±ë#ssssss£jÁaaa3fÌX¼x±R©„Y[.\ÈËË;pà€»»ûìÙ³ ç]æåå:tèÎ;K—.ÍÈÈhB µåì»ï¾ûä“O6lØpþüùÐÐЉ'þ#ÆoܸQXXH+Ô?~êdffBp.ÀÑ£Gÿúë/½;YVVöÊ+¯´’¤ ø úo®^½úÆ{÷î…çP­VÿøãwîÜ177§—5fff|>–® …âСCW¯^5Ü[qqq~~~DDFámÛh4¦b RÁê=°Í‚U«Õüñ‡P(„aw˜iA@‚Xs>À@IM€ ð§\.W(r¹jưîÄHÒk|>Òe6Á?zûöí°åypL‡>xbH�þ7±à-�-¡Pˆ$‹Æn#ËÀà!j„K3ܵ0»¥R©är¹\.ä†mšH|ÁiÙn¯¥ ^ö^PyÀ=ð O ·§³Žô‹Ç‹Åâóù|>Ã_Ú»ÏJ’îׯ_rrryy9ü)‹ãââF- ß~ûm333xýwÞ‰‹‹[¾|ù™3gBBBú÷ï?nܸ”””’’’©S§¦¦¦¾`àY»vmHHp"–/_”ššÚØøœçe3fÌøôÓO—/_ž›› c’ÓÒÒ.\¸°gÏÜféÒ¥~~~áááÀ ›9s&¼~çÎ?üpðàÁ·nÝš5k!$999??ÿĉÿ’x\­V/_¾ƒïsçÎ}þùç½{÷®¯¯‰‰áx7n‹Åýû÷÷÷÷¯­­6mÚâÅ‹ß|óÍœœœåË—Ÿ;wîí·ß677?yòdJJJrr2>ŸmÛh1Z«G‚’†&sh¯ÁŠ�¨¨a×0:,¤J\*00h€ß餶ò`HÉ1:h€ à13F-Ð[Î#Î …B©Tм�=ÑLÁ造èˆMé¯|{¸g^^^øÊ’%K¦M›F‰ŽŽîÑ£$4ºuëæé鉾`èСíÚµS©TÆ óõõ …)))îîî®®®NNNjµzذaþþþVVVkÖ¬¹uë!$((«ß¾~^vàÀsssøÝÁÁN²%ôùçŸãBlÒ¤I Û6lذ½; ¶oß>hÛ^±bŒ �›>}: 6lX÷îÝ !“'O~õÕW[Ó\µjUË1¾æÏŸÿæ›oâŸ666|ðD0#GŽìÑ£!dÏž=quuuwwW©T)))nnníÛ·§ŸI@лwï””½Æ¡C‡lllÚê÷_àÍÁwZ`ÊÂÂB*•ba[I‡™lØÉO÷è`X™4X§Ã@àp¹\¥R‰N_.—c?&-rhDlhÊÄjph8yœˆƒÍª MÃÑãvþ›Þi ã!úÂ¥aŸ©É^4äXXXôêÕ‹~çL»ºººººB$É'Ÿ|’››»qãFÜLoŽ2î%š½½=òŽôôŒ>I×r'йsgú)×;ÞI4œíëë«—áÔû¬‡‡‡‡‡Gëy’Z4Fôòò¢W?PTл!z2¬7Ð{&mmm ÿã€[m5±ÉOðòÇ@X�‰JpÇÍ`Òå2NWmffV[[‹=Ð JG8 A«Õ* D5ôì´´(ˆÙÀØ42HC‚!8P¡†øC¯¹Nû41X¤›4‰@OEÔ„“D„ké,ts2º,ÒBp†›á2¹v˜…äÙϸHEZR?^ŒØÏ3%Öîß¿_^^¾ÿþ&&Ø›Ìd&ûg \‰B¡ 'BT@¢ .ø P¯Ayš[ P†!ÔuƙУ�žaP‚Hª×¿( ºÀ@&�Á ö/“Éh¨Ð t€A«ÆÆ¤Jƒ¯Ç<j½ %Ó†/,×ÒL{aÝŠMË€¶ Èñ÷÷ß±cG[ý¢fgg·áy9t~K›\.?wîœÉõÿSF¼¤q‚np¡{-!¼ Ò)HcìÊà°�GÝ6(qÃrŠùjƒš6*ŠBáÏçß�‰µààX8r Ï ¡…fNã*è�"ØÙÙUVVbG6¥"¹#0ȧÁL$éÖ 9mÛ^ÀðŒÊ^äT1÷"'½xkåÌ7Ô¶A i+ìÕG¡Ie0ÀÊ r±� hz1æî0¸pÂ8%«c†ƒ®±DDJ/0š4ôØ#â 6„IÈÅaC¨¹sR“Ë嘩ƒ_èA¢¨€�Ìb±@ѧ‰ü$J™á5Ò¢�ôÍ×ÛÞèšà¿¹󰯆i1£šiz%èb’N¬aÚ·§óixDLTÒj¡Ï%3AŽqKOOoó ZkkëSEûé§ŸÚðð0ww÷V;/†Oc æcŸ¶¶¶è.Q’�Ý ûƒc…QZ^yÕXÝa³ÙfffÀ%º°shÆÄá$a†ZjÈ)€FN¥R) c ù7D/¸4@”E)6Lýa^6‰)Ôü|—Q£pÒœŒ-`ƒ³À›Ø›^;ŽÞ6zÒ6ÐÉÆÆ€¤éÛb‚œgµ¨¨¨¶] *,,‰D/`^!$::º '+t:]II‰‹‹K«Ѐí)|>_.—óù|,ÔÔÔàz3WÈF£Ç3ë¥éð-LUßÇž@£io° ý"FЈ91Œ„ôÂL²á˜júÄàã�BP‘ÂbŽBÀ¤ µŠ\ÐD,b2Sb­e ¾–mõêΜ9óÜ•L3`.µaÈÉÊÊjÍór07E¯—1§>ecB蜓ɴ··W©TUUU˜DÂAœàÐU*•@ �ŸŽx€ëkðò4•ÿad1` 9¡8„…œñ#—Ë‘›€™@Lbˆ€3Si6º°ôtf4Ê¡)s‰ÿÓ¡ŒÞ0V:#×´;¢¹!4»]ï 1ycccƒW!":;¡æ,½"Ãy9tþÍ9&3Ù¿~]Éfët:333@PUUº/8‡Ö(à f ¸^¾¾¾ç †J�ÇCíNˆ`‡ÖÖÖUUU¸öác`„žËûÈ&P«Õæ�Fƒ*Ÿpb `M‹UÃ>i¡h8UÔÅ©¦ô¤5D¾gœ ÚLÈ1J¦K2zȵ"£Œ2Ü?è¡ôú@™¬¬¬ ç E/BˆB¡Àíñ_cxEF¥zš9n—••eooèС6ù% ÄÖÂââb{{ûç®ðXYY™——×£GÔ¨ÎÍ͉D‘‘‘^^^¿üò ÎËéÛ·¯½½ýÚµkñ³8/'44ÔÞÞþ·ß~ûã?:vìÙ¡C‡óçÏ㼜>}úØÛÛþùçÿÔ|øð¡½½=6f?~ÜÞÞ¦<G+**‚™7ÁÁÁ›7o–Éd_ýµŸŸ_ddd§NîÞ½[^^Þ½{÷yóæÕÖÖâgïß¿cŠvïÞ]RR‚órœœœbbb>|˜——'‰ Ó¹í@…\.¯¨¨Éd  ‚u{H(9ÒÉÉ EqHƒX™P(„F"‘Àì�!(Ý[ZZ:::BÇp`‡8F,ãŒNˆ<½†Sp–ãBŽΓvww‡^],2!&¼Ñc.Q@ Á 4ß�Ñ;Ã[ðó‰ì&{Ή5X¤¤¤tëÖí—_~!„ :4%%…Ò·o_’’’“'OBø|>ègddTVV†……eddDEEY[[ÃtBÈØ±c µý#6xðବ¬ÜÜÜàààãÇ»ºº>÷Úïµk×:T^^âT„©S§¼œ©S§â¼œ¯¿þzݺutÓ(ÌË‘Éd+W®<w‹KRRÒ²eËbbbÆŒ3uêTœ—“°wïÞ––êiÂAß¾}srrŠ‹‹­­­322‚ƒƒŸïQþøã>}úlÞ¼yçÎï¿ÿ~TTÔìÙ³q^μyó¢¢¢Nž<yéÒ%™LöùçŸß»w)yï¿ÿ¾F£ÉÈÈX·n]\\ÜÈ‘#á¶ÿöÛo³fÍ ?wîÜo¿ý&•JÛj»jà«J;\”¢IMME´ÀÅ,ò†Á¡^¿~¼6¸rGGG??¿S§NABG«ÑJ8guwpÿt÷ zâ€NŒ? ßUXX„H~‡±rоƒ¢Ña"k9€s÷ öUXŽj¯ŒPc›1Hq4nvhÒ¶¦‡iÒ=F„¢ØÑ†N§vt‰U:L¬YZZÂ#Zå@¸£Ñh°0‰W¯ž䀭]»6**ÊÓÓóÀ§OŸ KOOÿé§Ÿâãããââ4ÍСCW®\YSSãáá7iÒ¤ï¿ÿþ·ß~;xð`ZZÚùóç'Ož¼k×®[·n­^½º•| W¯^½bÅŠyóæuéÒ%--mÛ¶mQQQÏ÷.\ÀWæÏŸ¿jÕª äääÌŸ?_߸q£¯¯/¾Ñ&‹¿üòË÷ßßßßíÚµyyy ,¸qã=­`ãÆŒŒŒü§î¤••ÕÔ©S'L˜ðÎ;ïøùùíÙ³çƒ>ГNxv›8qâĉïÞ½{øðá &´k×®±-}}}qDiÓ¶cÇþÿ³÷ÜqU•ï¿çž»ÙKQYNÐLqf8Ò2ÅÈ ‰ æJ“¡‚EMIËp$ñ3WjiZæÌ9r‘ 8AA6—»ï=÷÷ÇÏ÷í‚æ`e÷ùÞ{Æó®g±888˜òÁìß¿ÿU•+±¿'fþÓÕ—é_éfeXåŒ.”I÷ÓëõwïÞÍÈÈ�ß º†T :Qà:]Ê ë¼óÀÈ70£™™™;öäÉ“÷îÝCÎAÇïbx7r,RÕNÛ`0XXX@¡L‚7c£©?a?¥Æš¹G]JÃí²c’uÏý­ê}áèìTŒ¯Îrª—¼ª±ª&øÁ¾PF:�ôǃ?°"3æ&Ò•úžô¡7¬!ètº”””àààV­Z=z488¸{÷î§NÒh4kÖ¬ fY6!!áêÕ«999~~~ €B<èêêÜ¢E‹4žC(•J£¢¢^ýõ-[¶lذ¡ÖùMðÛo¿5mÚ4 ÀÍÍ ”EBÈâÅ‹¡nPõû§L™âååÿuvvhÖ¬>;kÖ,kkë 4ìd’sçÎýè£úöí;vìØºøŠF£ù補œœ–.]êèè»gÏž·ß~ûáÇ4g‚Îxÿø¶M›6%%%ÅÇÇÿLÐì=4P8�³m0R�,`˜@ƒ®¬^“’’ið,ð$ô ÐE9Qç€$°ã¡2/Aï]lµ%Bô;HIIÉËË›<zÚñ°>4í ÕJ¡Pà é¦;@yi× Xt@õ1Öê^jr/_¾ é?~ŒA«V­ð¿gÏž0`@III‡ϰµZí?üàéé9eÊ”{÷îÕÃG322ÌÍÍ»tébcc“‘‘³³³õz½Q1¼ßÊÊ ‹~Z[[wéÒÅÒÒŸÍÌÌõxöEgÍš5­Zµ*//?pà@]—çääxyyõìÙsãÆ¶¶¶</(((==ý÷ß§û®îرcÁ‚³fÍ:tèÐÓ_˜——'“ɼÕP½J¥Âàfp€ÈF6¨ˆƒ½ph§:ô# ýêPS�rt@�‚MØ@Nc—T*uww·°°�VË|>_,‰·´´DŸÏ·¶¶Æ^�𞤤$¹\n �\ [f`1øu5ÀðG¾«Õj•J%m£K·=‰ß0Õàe–ƒÖÕŒ˜¯ jü„áÉð¸á±ìP(4«Ë*À¼¨§£ñ­€^<bM&“Íž=;,, Ô¼®P(ÀÁƒö¥íÛ·?~œöè68lݺ5>>~õêÕƒ Z·n]}&äܸq#;;{èСxê8æÛáìÚµ«iÓ¦´-99ùÑ£GÕÍq¯$¬X±âáÇëÖ­CÍ{ÇŽ¯½öšQ­Xú°©Tª]»vÑ2„û÷ï_¿~}РAǹX§€ôˆT5_AÂ:üqÌÀo ®"Äh‚V)¨³‰nyŒaƃ±Ñ ôlÙrÆ ëׯ߹s'ª5ÈÆAÛ¶m1ÖÙÞÞ¾²²wè¨eº„ôÄX;­V‹%JÑìD,ÃX7¶5AÓ ÐçùYŽQíµê±ÂÏ®tbè9¾½A ~ïÄÈlUãÑ”-Èó¡ tDè` ¢TÖg+îƒÙ­²²>Іµ'MZ-k9R©têÔ© !!!ãÇOKKã8®cÇŽ«V­Â&Ïž�� �IDATu ¿~ýzHHHhhh£J”ûúë¯;vì8hÐ BHXXØõë×Oœ8Q× ¿sçNHHÈ•+WÂÃà !'Ož¼zõjXXÞ³dÉ’ 6€å‡2a¸^^^’žžÏ:t(33“~öÕNRYYYð·L&ûôÓOßyçOOÏ%K–ÄÇÇ¿ûî»:u’Éd¡¡¡G8q"!$$$䨱c“'O¶°°¸qãÆ‰'&Ož }"^y�Kí´@G‹> Ö¨ÁÐ5iP*Çx\º‹zï‘C¬ZµêÏ?ÿDÂdDÜ“’’ÐCc0îÝ»‡â?vx£¨~á@PÍB­˜(°°þ!wÁÊ=ØK›.¥ƒuNM毺ƒ'j9;v<s挳³³§§',çÂ… Áéíïï?`À�77·¹sç‚IªmÛ¶ï¼óŽƒƒÃèÑ£U*Õýû÷7nÜH?~<”T?~|£*²wï^t£5mÚôÌ™3tÓšZ„-[¶à9r$øÕÇ&˜I:¾k÷îÝÐêcùòå4“®>““'O>|xãé—³bÅŠºë)9yòdü¯½½}DDÄÈ‘# !Ÿ|ò LÈÖ­[ËËË !Mš4æLgΜiÚ´iÓ¦M÷îÝ rYË–-Åbqß¾}Ïœ9Ó²eKú¿ýöØ^=€X™Ÿ®TF§§�í …ÖÖÖ0“èþ¡Ý׸ŒqeØG~Âh–eårùÑ£G!4�zÒö+ †Æn˜)‚Â;©r´`J  ˆaÏM¹A°¡R)!¶³‹ÐZH×{•²¿Ÿ×ÂV?c"Ë133Cö­Â&f  1ªS§NÛ·oŠŠÚ°aÃÝ»w›7oAxõo­z £ŠëIº‰ Ç3úÎduÄŒ<4Õ‘lÖ¬Y­Ç"¿ QðÚgggggg#ÉÝhBŒºñù|¼Á(ˆÜÊʪúŠ7Ú i/666-Z´ÈÊÊB/=êXtícàÁ_)•JÐ�h »±a)6Ìto p GGǬ¬,Ô±0Ÿyª/Øyëî�æ˜Jª’HUmŒ�{ ¼ÙÌÌ ,x€<€1 »ø@ 7½^¯P(Äbq”+h€ÚD«\¨ÑâÐ&öôÄIŒÃÉÄgtœT ƒ91ºßÂÂÌtಢ§õ<gmm³˜€thpæ8.''þV(è�ƒ¯#ÏÕd¨6«èt:ÈàY½z5t±4 LаPTTÔ¡C`9(࣫‰&6#@'<ê à¨ÇBÑH‘ sss>Ÿ_VV¦V«±—fÉèõúœœºô�tðĈ5ШPù@ZŒÍuè²Ê0î T­€ìb S¨K¾TqÐKäÃ^á2WÚ°öb�Y¯$&&šúåÔ ¨Tª .¼ª3Ùø)ŸÏÿý÷ßQÇj7˜LC»jè�0 z‹ÅBŠë —––b‰3´}Áý˜›‰²LE^‚¾LñÁ¢dôTcKSx90º 6*T½h4¡ °­Ý3Ôÿ–óÊ�Çq]»v}…kÊöèÑ£ÞF'ŒZA¿bðìïj3ƒæ¾} ²  ›AÅ…®Cƒ© ˜ ªG4)G¾‚Ž"x¾(‹7@5z•€‚sÈÎÎ.??ÃP•Á°0^ѽ±Á†fÔ2ûœBd2ZºÑ�U¤ï©>‡<¼¿O T££Úèð¶gÙÕ“IéŸàm eVß{(D¤Aóoò÷TSLÍÊÊ‚+ؼ;^WoüC› ¡4yB8ËyY8sæÌ+AkeeÕ«W¯zøÐ¡C‡^yÉÑÅÅ¥Ë=‹¢ƒÔ,ZÐŒÅÇ€ÞßnšŽÑ_È„€= ÚÁøWàNx­F£úˆV,Ôx€Ö‹D¢3fDGGc)h–eÅb10À =:úH¢ßB©Tb“7 D@`�VµA ߌIKOá OÔpŸWÿãé`Ô$íI¿>å§êõ@«·Éðt¸Õöh–Sc5—d0&–ó¬0`À€¦M›¾ÂVÝììì6mÚÔO¿œÆ\Ø¿V ''ÇÅÅ¥ÑöË!T> ² ,’ú z:ñJ5c 1­�ayf¬!Fûº±FÆ¡“Cómé7¨D‹/ÆÒ;€•H$‚¢5t· ðtɪ$Ze¡S|è#ð±Ã¨±»6Ý1@“a­àÕî—“””TcɃº3켪3i0._¾Œñœ“ßÐ)8Ø êHméRh"Ãf,‘‰ÁÇ´‡ï/ D‹!A‡l@PYY‰é5`pãóù …)xIyy9þŒ‡î;€vF€!c¿5|ÖÖÖV&“’À>1N~JÁ ”@‹ò<£&@5ÚÇž]ÅWÕ¥õK\)ÌLÀ²žÐ¿Žü=Õ•!L«€´¤Ôrª+Xˆm¥¤+ï½ ËA#,NDõÂs/ XÖ‚eY£ÌÞg£Dº@²¶Î<dG­Î�ǃ“ µ¤@ ƒ3 «�â^=  Âã36árƒ[ qÍpõÙƒ>+¸Uh;¤C½’�¤LFè·W«ÕB¡sø¡0 =Ã3p °(© ñB÷˜¼ 17 êvÞ„r8 O0 Ó³gÏääd¬ó†ÍÁà+tÅ3d~˜pŠqF±Ôx?ÞFwwæñx•••È@w?ã8 lÓ!|Õ #í[ûÐlÓ`_˜å ã+O±šóÑaÖFÕ6CšàiÅØhÌ[ª‘å<¥_ú~èý£˜Î{ŠܬY³¾}ûúúúúúúnÙ²¥vAQQÑäÉ“ßyçooï>ú(??ÿyß Õj}«`ذaÍš5‹ŽŽnl§ã¸ÄÄÄùóç7kÖ,33“þ©¼¼<""¢_¿~C‡2dȃn߾ݵkW__ßž={®]»V.—¯]»¶gÏž¾¾¾]»v½}ûv]c{çÎ=z 8ðþýûÏrÿ¸qã<==v†ÏŸ?ïáááëëÛ±cÇÇÓÛcýúõ=zôðõõõôôÌÈÈxðàÁûï¿ÿþûï¿õÖ[³fÍ*//?|øpÇŽ}}}=<<Ο?ÿ ³`* ùžPæ+ :�á@'],�É.]H±ø?ÝKÔ�aÂÆ,˦¤¤`ÓÐ3èr; ñ U×@†ÀÊžÀ2±N„ ;A+"öÒÆÔÈAá_Ї€Ö㜘 a k³fÍòóó#„\»víÛo¿9räÏ?ÿÜ¥K—ŠŠŠ»wïBºvíúÆoüòË/=zô€÷B|||\\\îÝ»wôèQBˆ¥¥%]c877·iÓ¦ ,Ðjµo¼ñƾ}û¦L™ò\¨ ‚#GŽÀßÛ¶m{øð¡——׉'€²wéÒ¥W¯^*• ™e@@@IIIAAAQQQvv¶›››½½}rr²……¶k« –sàÀÔÔÔê?]»vmóæÍ[¶lyë­·ZµjµuëÖÛ·okµÚ#Gެ\¹rñâÅýû÷_¼xñܹsç̙Ӯ]»¥K—nß¾½NwÃW_}Õ»wo¥RùÝwß}þùç;wî477wrrJLL;v¬¥¥å•+WþüóOXb:-)))99™ÒªU«Áƒ×çž9sfçÎ÷ïßüÙgŸaѹ²²²… Ι3gîܹíÛ·_¼xñ믿ž””tûöí?ÿü3 àƒ>øì³ÏÞzë­-[¶ 6læÌ™0„W@c‰Dèw¡;Ó`O¬WFgÆÀPýuÚçAeÀBÀ™ÑÒÀB@› …ðNJ<D€®ƒœÏÈUƒÊ JÐØ©šV¹ n)F A”²:¸x*ÈÛàAºlèóšÂÀZ…eƒá)ItMO:›²% T•ªwEõë…¿ˆî±êºW-°„sçÎ-X°àÔ©S r¹|Ê”)? ]¿~}LLÌ Aƒ<==ãââ®\¹òî»ï8pàÈ‘#ëÖ­›1c†ƒƒÃ!C¢¢¢är96^ìܹsçÎW­Z•œœüÆo`ýʀ͛7ÇÄÄlذA§Ó…‡‡òÉ'%%%¡¡¡ß|óÍ®]».\¸0sæÌøøø7nøúúFGG;–ÏçÏš5+00°eË– .¬¬¬|^†÷ìÛqùòåñññ_ˆ>yòdbbâîÝ» ÃÃÇ ¶jÕ*™L6nÜ8¨7sæÌÞ½{/X°`÷îÝsæÌAÞòÎ;ï4oÞ<<<œã¸!C†˜¤¹ÆÚÀ@uïÞ:–å€F€ÖÂ0Ž# ÃòxœÁ@ª4ÚÔD[¥(�¥dax<‚žxUBM+�ŸÐ0Ì_ G  ä–òxLUÐÃã髜IØ¿‡VPþ—¬¤íïýÁþzÄ``y<=Ç‘ªŸ4 ó†S­è$„ € a¬ÌqœÊɉ<OÖšP(ÄRÙ@Ð9Ž+,,| ËAK;Øjk¹š2ùZ^Þ«Jûº^ õXNLLL|||çÎÛ¶mKIII }jµÚÙÙùÂ… kÖ¬ÉÍÍU«ÕwîÜY¾|ù¾}ûÎ;÷Ýwßݽ{wåÊ•¥¥¥çÏŸˆˆðññ‰ŒŒ¼xñ¢Q¯_??¿×_ý“O>¹|ù2|âya×®]‹/Þ´iÓ€Ö¯_Ÿ““3dÈÜÜÜØØØ$$$´nÝzôèÑ<qℯ¯oZZZË–-»téÁ0ÌèÑ£,Xpþüù:b9ÿ"¸}ûöýû÷•J¥J¥ÊÈÈ€B®®®“&MÊÌÌLHHðóó»qãÆœ9sš5k¶{÷n|0///---22ÒÃÃcîܹ·nÝ2±œÆeÊ8vŒÙ³‡åó±î<:H0@ ìTè¾…_u:eB„TЍR©DƒRäOzމD:­ö¯ªhÇUʆ«Ê<õB£ÑˆD"!À·4Z-Ü Óëy £Ó뙪Ơ˜IÃòù !iƲ,_ ШՄ| a‘P½úLS\Ø$WÕ¨ ¬jÈ„x<žpÐ Ò»·iÛ4Œamîܹ`X[¿~=!äèÑ£­[·ÎÍÍ ÚôŒ\áܹs:t¨ÞžÄÉÉI¡PTTT”••½�ö)))ŽŽŽÿÆ'u÷îÝk×®Ýüùó !-[¶ÌÈÈP*•‰ÄÞÞÞèæ£³¾øâ ›Þ½{Ó lLЀ-,´ÌÍÅà"ºË'Çq¼*—;ôÏù_×NŽcŠD )ku:–eY>/Á€†mrà |>8Ë0|pŸpüCï{mÐéˆ@` DRUú/j�z=Çc8®E‹¥¥¥ù¨«x/†áXVÀ0%œ2 ¸…þj•­×³`‹«2¯aí†ËŽã±¬Š“6 ìÜ“Ojîiä=2º³ºÃߨxÑm´¿ºñ”rmÏh(£ 4áóŒP} 4žÿ¨÷¼H|×Ï?ÿ|îܹ«W¯Þ½{wĈÿx```XXØÆib”™™yüøñ—ÉØÐëõŸþù¥K—þïÿþϨæc#‡ãÇß¿¿Q±É[·nmذ!>>% h6Zc õž={ª_ŒŽŽ~óÍ7¿ÿþûÖ­[7ìX._¾œ˜˜øÞ{ @ïÞ½¡]ŒT…á‚+rªv']ÞÆˆ¸`.Öa£]÷x+âÐEt°Û4&WbJ&ê4i£é2úcþâ¦UÊZ1€ êèrøü(¶ÊÆQרcÉÞÞ>((ÈÈž† §ØªUF(ÅM‚z6Š-&Tl4]ÖÓˆ|Wš#OhµP;Vgi5Æ‚Wç=Oa{5ä鈽 Ëñöö>tèPdd¤«««¯¯o\\\IIIwÚÚÚN›6mïÞ½iii/^ܼy3þ$‹ÿøã„„‘HÔ«W¯>/:î»ï¾kÓ¦Í7ß|WZ¶lÙ³gÏùóç+•JooïîÝ»/X°`Á‚'NLIIið†Í»wïNHHHJJ9rd||üÞ½{_{íµáÇWTT\¾|yâĉ·nÝš>}º««ëôéÓ÷ïßûöm>Ÿ?mÚ´†Eûµ×^ƒå¦{ÊB<==‡ºfÍš­[·æç翌[î`Á‚'NLNN†%>sæÌÒ¥K½½½gΜyðàAˆs™>}ºµµõ‘#GŠ‹‹}}}_{íµ ÄÆÆNœ81==½Æ^௴k×î?ÒŒ®¶ //Ï(ÓÌ̬~Ju¼2põêUKKËê×™îÝ»Ÿ?^¡P<x&%*•*77·I“&à++++..vqq‚‚‚ÊÊJ©T*‹ßH¥ÒfÍšåçç«ÕjWW×’’’ÒÒR777•JÐÀÈ S\\ ö4 ‹&Mš<ï Ö °¶¶Öét•••ð·^¯ÏÎΆ_]]]5Í£GE"Ñýû÷mmmmll²³³Åb1Ý/çòåËíÚµ³´´¬­0’òòò¢¢"gggˆß/((P(-[¶„YÅÙ#„Ü¿‰ŽŽŽfffr¹fÏççI8tèИ1c°ú@ËM‘H$Í›7/((P*•NNNyyyJ¥ÒÒÒ²C‡sæÌ ¦—N¦Qç¡cÇŽ}ðÁu— Êqö‡ýYZZZRR‚ËMÏÞ£G C666Z­k³·lÙòÅšÞ †cÇŽùúú6Âê%%%999=zô sìLð,`aa”„rôèÑ‘#GÖO©ŽW  ÀF£±°°ÉdÇŽ y¢–#‹i ‰µµ56Z „@ç+øê�¡DýÆÖÖhГ,-vvvvvv/<†aj|3"Ê}ŸÏÇÿâFiꬬ¬¬¬¬ªch4«¤ZÓ—§Ì^íÂ?.7!$%%eüøñcÆŒiß¾½­­­««kõå®àñxFSdcc{’^n�£C ÁÍ€u °.ØjÚÏÈoÀ®SYYišÃç…óay¦y1Á3B—.]Ö¬Y#—Ë“““—,Yâïïoš˜ÀϦkO„sçνpÕŠ—÷ìЯ_¿~ýú=ïSJ¥ò?þ0í(˜À&–S@”NŸ>}^íþ€õ3:è Ü¿ÿW{ØN L`b9/¬òÊ÷£}1Eçyáí·ß~…ËHèõúÆÜ¹À&hŒ,‡a˜W¸˜® L`˜ ±ƒÁpâÄ ÓŒ˜À&0 jÌÍÍ1Ïéo†µ.]º4H 9oØ0Dºgb£‚F‹˜`qÆÿìzÊÌp×8£Q =R#œºF¾¦ù„V¯CÓ°ÈXXX`Ý„¿±KKK33³ZovýtÐét¥¥¥fffæææ¤á<(PÙÐÜܼžgàé “Éôz½H$²°°¨År³µÅÅʼnD(J$’zž@µZ]YY)‹---ÕÚ”––òùü‚‚‚ .Ԙݰ`ooߥK©TjTq¹Á¡  ÀÜܼ"fr¹Š“ZZZ6†ZVV-럘Whêjff†‰´ÆáZ­¶ž¡åååׯ_ïÛ·/©/‡vpíÚ5GGG'''½^/žÒåõ€˜ƒƒƒ‹‹‹N§kTˆÁ¹sçúôéÕˆŸ±ÞkmÁ£Gòòòºuëöô>% /^ìÒ¥ !ÄÍÍ­[·nMÅ133ƒs‡m"èõú?þø å)•ÊF(I ¤¥¥‰D¢6mÚ4Ò‘””äáááààPÿļ:$''·nÝšÎ+7¥‚šÀ&0 ê L,Ç&0 LPOðây9gÏžE­­W¯^‰‰‰­Zµª±Ö}ý@iiiRRR§Nîܹ#‹»wï~íÚµ’’’ÔÇwrrêСCƒ/ê¥K—ÊÊÊš7oÞ±cÇÆ¹íd2™R©tpp@çãÇÁc:“/°Ü:ÎËË«1 “œœ¬R©úôéÓ˜gì_dýÀ½{÷233ûöí+‘Hj¼¡°°0%%¥k×®ÕûfÕ«–³ÿþI“&]©‚ÂÂB??¿Û¨Ô¤¥¥ùùù?þæÍ›™™™„Õ«WO˜0¡Þ¸råʃ|ýþûï&L¸téÒýû÷íFÏÉɹtéí.++3eS¾,\¸pöìÙ™¥K—†„„4òËÌ̼yó¦içB8àçç÷øñã§°g??¿”””†Ôr<Y\\l0Ú·oÿÓO?}øá‡øë´iÓ Ž}DD„çúë½ Ü¹s'**Š"¶mÛFY¿~}RRÒ'Ÿ|7¤§§ÛÛÛ<x011±²²2&&fîܹµ‹Ã™3gâãã—.]Ú¦M›S§NmذaÙ²eàç'„DFF¹Ÿ2eŠ——W``à!CgÍšeii¹páÂuëÖ]½zuÓ¦Mµ>9gÏž øðaYY™¹¹ù˜1c–.]ºhÑ¢·Þz‹eYÈ»8pà„ æÏŸ 3¹lÙ2h:mÚ´¾}ûÞºukÉ’%„©TZH"(•Ê´´4WW×&MšTTT…ÂìììÂÂÂ:¤¥¥¹¹¹Á|Ö.OŸ>þnҤɚ5k~üñǃB¼¼¼f̘A ‚Š ÑÑÑR©ôðáÃ"‘èøñã®®®ƒÞ°a!dçÎu4-+V¬¸zõ*!ÄÏÏïÃ?|üøñÌ™3á§M›6I¥Ò;v>|˜Ò§OŸO?ýܲeËñãÇ ! 0êø^‹¶ìÛoeeõÓO?íÛ·Lˆ'!ÄÉèèh…Báãョv›>}º³³sÛ¶m÷ìÙƒûÙI¸îï•UTTTÿHB®^½ºbÅŠY³fµjÕjÚ´i£F>|øäÉ“ÝÝÝÃÂÂbbb®_¿Nñ÷÷:th~~~hh(<¸uëÖºkzTYY9f̘?üÐÏϯ¼¼|Ê”)p=..ï$[´h±oß¾ï¾ûŒëIËyûí·===ÍÌ̦L™’••uôèQŒPš6mÚ©S§bcc[µj5|øpè¹R‹ ×ëlgg›‘‘1vìØmÛ¶-[¶lܸq([={öÒ¥K4’µ¾B%%%üñÇÝ»wµZmjjêÅ‹•JåÑ£GoÞ¼õý÷ßÇÆÆöèÑcܸqIIIÉÉÉJ¥“Ëåþù'ДZ‡îÝ»¿õÖ[„°°°ÜÜÜ£G<8%%åÿþïÿâââ¦N:qâÄ… þüóÏgÏž3gNll¬D"yÿý÷ccc»víššúþûï7kÖ,666%%%88¸îXέ[·ìíí¯\¹R^^^PPPQQ!“É 222lmm¯\¹RJ¬­­ccc—.]ZTTtóæÍ£GΙ3ÇÏÏ/$$dùòå[¶l LMMmÒ¤É{ï½W\\¼dɵZûý÷ß>|866öáÇ#Gެ‹9Y·n]llìÔ©SGŒ±|ùòäädBHll,˲“&M:yòäêÕ«ƒ‚‚f̘±lÙ2º!¿þúë‚ ‚ƒƒ'OžýÓO?ÕzC‡Õh4±±±b±xâĉ ááá#GŽ ÿâ‹/6nÜ·>|822Òßß‘LLLܲeË”)S®]»Va]gΜ‰?þµk×¼½½I…BñÁ ’S§N=zôhVVÖ¥K—Ξ=[#’Û·o?uê”ÝàÁƒë"L®¢¢âüùó …âèÑ£wîÜ)))9}útvvöêÕ«W¯^ýá‡.]ºôÊ•+ï½÷žF£ùüóÏ !u$C�„……Á"&$$|ðÁ …"66V£ÑÐÔN:µvíÚ²²2™L6lذz5¬™™™‰Åb†aèN9hQ«Õ)))ùùù¥¥¥usYRRæE¥RY\\¬P(”Je‹-V¯^ýŒH¾<øúúúûûôÑG7oÞ\¸pá¢E‹^{í5ÜR&%%åÁƒååå<ï‡~ؾ}ûPZ9|øðîÝ»ëbëH$©TJÁFDîîî©©©—/_Þ¶m›\.OOOW(ЦL&“9::J$’’’GGG ‹òòrNWRRòøñc˜á'õ{­èÚµ+t¤7Ú'p]«ÕÖE6Ë²ŽŽŽ;wîdfß¾}*•J.—ÛÚÚÚÛÛ«T*…BQRR÷H¥R¾R©äóùŽŽŽZ­V«Õ:::òùüZ§�š5kööÛoO:ÕÌÌlçÎÝ»w/..†‚;vìØ±cÇÛo¿½cÇŽãÒÒÒ”J%,% ©P(222ÒÓÓéëµ®#ŠD"GGÇ-[¶ìÙ³G­VËår˜I¸žUDF"‘„„„¤¥¥ÕØéùåÁÒÒréÒ¥iii,Ë–••¥¤¤TTT””” ’ ž"Ôˆd«V­¢££áPÔ’ýúõ›>}ú§Ÿ~ZXXW¦L™" ×®]+“É4M“&Müüü.]ºÔµk×®]»–””ÄÆÆÒ-•k6lØ`cc#—ËÕjuIIIEEEJJ öiDèÛ·ïäÉ“E"ÑËlþÚ/ë ‚¿‡‡Ç¼yóÌÌÌêhß§¦¦´hÑ¢¢¢¢Al ƒþí·ß¶lÙâéé Y4¤¦¦6oÞ|Þ¼yMš4iØf‚K–,áñxW¯^ ­Žç“ ¨¨(55uüøñF\_ ÈÈȸpáBddä êFŽ9räȘ˜ÿ¾}û®Y³Æè†´´´www-ŒàîÝ»jUlÛ�� �IDAT-Z´˜7oÞ³¯u½³³óäÉ“ëîýžžž¨zÊd²ÔÔÔ÷Þ{ºÜþKaãÆ·nÝ õ÷÷ÿüóÏi#jÌž··w]ðÚ’677Ÿ={¶««kRRRUøèÒ¥ËìÙ³ nݺWÔjuttt7_»v­.ÌîlÞ¼ù¶mÛ:uêdä²bföìÙ:uJJJR(îîîAAAß|óͬY³F½mÛ¶™3gµ§¬k¸~ýúÕ«WŸÑ@7{öì‡fddÔV âÂ-**š<yrË–-ëHÖ~Iؽ{÷èÑ£Ç?kÖ¬³gÏbmfΜyëÖ­¤¤¤>ú¨ÆÐ˜?þxÔ¨QIII(D×ÄÄÄ S§B›6mfÏž­ÓéÀ5ÙH¤ŠîÝ»¯X±b÷îÝÇ¥¤¤ÄÄÄÐ7\¼xqôèÑ©©©AAAÇ_»vm‡ЂZЪU«Ù³g †k×®Ñ×/]ºô믿¾äË_P˱µµmÞ¼9!ÄÂÂÂÉÉI 899YZZÆÇÇøá‡ P(QQQµ.b°,»ÿþðððÈåòãÇ‹D¢Û·o‡……EDD„††J$’¦M›‚ÛyÍš5£FÚ²e˲eËêbaöìÙ3a°´Bœœœ¬­­CCCsrr  R©¦M›Ö¼ys>Ÿß­[·'NtëÖ­¤¤D¡PôìÙ³FµVÀÚÚÚÉɉa©Têää$ !£GNOOŸ1c†»»ûªU«¾ýö[•JåììL±±±iÑ¢È NNN{öì™7oÞùóç5Ío¿ýVHB-Zܸq£cÇŽÖÖÖ‰D 0 Áš|>_"‘ÔE‘(­V[\\|ùòå‘#G6kÖlË–-³fÍš7oÇ ?~üرc½½½aƒíÝ»×ÌÌÌÉÉ Ä=Xbò÷fçµ >>>Ç÷óóÓjµ‹-êÓ§Ï‚‚‚ P^^¾ÿþ&Mš„††FDD¸¹¹­_¿~íÚµjµÚÍÍmøðá B¼¼¼ œG­ÃþýûÇŒ3`À€ŠŠŠÝ»w;99EDD,\¸eÙ±cÇ~òÉ'7nÜÐétï¿ÿ> Éãñ‚ƒƒÇwáÂ…'…áÖ 8::bï“\¾|ùÑ£G !OGQÝt›7o¾ûî»·oß‹Åà–••åëë«ÑhÆŒãîî:a„}ûö)•ÊC‡Õ2@ÀY–‹ÅNNN‰dß¾}£G†ÙÛ¹sg^^ž““4ðôô|øðá½{÷ `äÅ€éÞ½ûùóç ÅÁƒ?üðC¡PØPoÌÍͰàÍ•+W àD"iTESRRR àMcCÌNœ8ѧO –eªà……EÚ1k„3gÎtéÒE.—’ 7,x#•JU*U£*xsìØ±÷Þ{O*•ªÕê—ñäççç'''¿ñÆ …ÂÓÓ3::šŽ¬{yÀ‚7X:¨aáÂ… Pð¦v‰y»víÞxãíÛ·?×S‰‰‰­[·nÕª•L&;vìXHHˆ©E› L`‚Wd2Y||ü¾}ûlllÚ·oßHrfÿ³`b9&0 ^ehÛ¶íš5k Unܸq¶$G#‡M›6ÑÕ9M,Ç&0 j†Ö­[·nÝÚ4/µåäWWB>|XŸ#¡rrrÊš\^^îèèH‘ËåÙÙÙg¥ËËË!B¡P4*ÄŒ�­Æ¥¥¥õùé²²2øC¯×7Â)BÇ 7:@#77j.4 é@nnn={Ÿ JJJ �U¥R5†í‡îÌú'æOA¦f–íFêßëææFÑh42™¬¡X޽½½¥¥¥Á`P(ÊmgggeeÕ«¾ˆ|>Z†Ô3ž¹IQ«ÕpŠœE"Çãóù°µ«F£!„hµÚÊÊÊFEÙ=<<�1™LÖ˜YŽ•••Á`P*•aû5oÞ\*•617GGG£äž¿E¬Ñå L`˜À&xy€PÒ"ÖŠŠŠNŸ>]wÅãjÑàéé ™@ Û¡V¯×ƒaÐÜܼñwh¯Qç•H$|þ×¥§ÕjA‚nð½Tƒ²²²j<qÏu •••ƒ!55533óÛÏ<ïÍ7ß´··777ÿ×mQ•JeTÀذæääÔ«W¯F> ‘Hd04 Çq _RR’žžîååÅ0Lc¶zUƒÁðÛo¿ùøø0 £P(s£ß:…ììl™Löúë¯ †× >nß¾m0ÜÝÝ9Ž{eõt�#^¯ïÞ½;ä8¿2 ‘H Þ N§«£Òyu—C×0u5 L`Ô—Òfš˜À&0Acg9z½þÎ;ÅÅÅ=¢‹6ZÈÎÎÎËË3-ù« ùùùÿŠ}ø¼pïÞ½üüüzøÇqp¢ñJiié;wt:]õ›óòòsÈþËÃÇC“ß„GÕÅ¿8Ë©¨¨èÑ£G\\ܾ}û¾ùæ›Æ?ƒC‡mü-rMðÂ0wîÜwÞyçÕ×;ï¼Sëmmk„ÊÊÊ=z¬[·¯\¼xqÅŠ5ö yµ\·oß¾uëÖÿò 2dH­¿¶B;¬¬¬ìíí322¶mÛ°ÿþ-Z|üñÇ„˜˜pïµmÛ655úØÙÙ………9räܹsÓ¦M‹‹‹óññ©·ÚG;v쀮„½+W®|÷Ýw³³³‹ŠŠfÍšU×üôÓO·oßö÷÷ß¼yó˜1c:v옙™ ûÛÜÜ|îܹ§N:qâDdddnnîöíÛÉþýû/[¶ ¼ˆãÇ·¶¶þú믇 ’žž^YYY?<õË/¿„ìË€€�ôôt(ö7mÚ´3gÎ888œ>}zþüùYYY;wîD$áÙE‹¥¥¥íÙ³gÒ¤I›7oîÔ©“P(LLL$„tïÞÝ×׿ò믿^¹reÒ¤Iñññ#FŒ8wîd˜Ž5ÊÓÓóÞ½{ЃR,GEEýñÇ7nÜP*•[·n ª‡IÈÍÍ…6½<oéÒ¥„_~ùåÊ•+®®®;v”J¥§OŸ677Ÿ8q",7 yìØ1BHÛ¶mƒ‚‚~üñÇû÷ï>÷ÀÀ@ww÷´´´~ø¡~Æb;wîÌÊÊš?¾T*mÒ¤ ˲pº !–––¿ÿþûíÛ·ËÊÊ~üñGÿ­[·fffBܯ_¿ââbzOöïßÿ)Ë7lØ0˜I „#FtíÚµFzäÈmÛ¶i4ŸÔÔÔû÷ïwíÚuĈ666:.99ù×_ÄzöìIwÃüå—_zõê5êôéÓ………}úô2dˆJ¥‚-A™5kVQQÑÖ­[ÇŽëââóöÛo׃lôàÁƒøøxøÛÕÕuÒ¤I{öìfÄ5"iccsúôé„„Bˆ»»;Ýåä÷ß?yò$!äµ×^ó÷÷o0-‡^¶-[¶äääÄÅÅ»¸¸,Z´hç΋-Ú±c‡OqqqPPPffæÄ‰•J¥O\\ÜÊ•+ÏŸ?çïïG·µ¨ëã´hÑ":œ9sfRRÒ„ ®^½záÂ…Å‹ïØ±£pHHHX³fÍ×_­T*'Nœ˜™™T\\ìãã³cÇŽE‹%%%ÅÅÅÉåò{÷îÅÅÅåääÈd²¸¸¸+W®DEEíÚµËÇÇçñãÇãÆËËË‹‹‹›1cÆÒ¥Kë¢-PuX¶lÙÆ}||***‚ƒƒ333ƒƒƒ+**’’’üýý9’˜˜§V«ïܹ—››tóæMŸ³gÏ~úé§qqqüñ7ß|3oÞ¼9sæ´iÓ¦}ûösçÎ¥{%œ>}zýúõcÇŽ‹‹›<yò×_íãã£Óé&Mš”™™øèÑ#ŸŸþyÞ¼y­[·nÖ¬™@ èÙ³gýl$ÿììlŸ#GŽ„……:thÞ¼yíÚµûüóϧOŸž‘‘±sçN¨ñž°qãÆk×®}öÙgVVVýúõ[¼xñ÷ßäÈ‘ØØØàà`88[·nõññ)--…Y?~¼\.‡f‘õÉo~þùg…B±k×®¨¨¨+W®ÄÅÅ=|ø088¸´´ÔÇÇgëÖ­K–,i×®]“&M$I·nݾÿþûÅ‹÷ë×ÏÊÊê³Ï>»ví,÷É“'aO>}¹÷ìÙ³hÑ"Ÿ»wïøøø †É“'×Õîüùóýû÷—J¥Ó§O·¶¶îرã¼yó:ôË/¿ìÞ½;-- hT»ví"""@b�8yòä¸qãpO¶nÝÚÕÕuÖ¬YgΜ™6mÚùóç}||®_¿üàÁƒ¸¸¸¬¬,¥RwéÒ¥zšµµµÏo¿ý¶wïÞýû÷ÏŸ?¿S§NOBòÊ•+3gδ±±éÝ»wtt4RÂ?ÿü3$$¤iÓ¦={öŒŠŠzùçµ>Ù¿ÿ’’’ܺuK¯×ÛÙÙI$’´´4[[ÛL˜0ÁÎÎN­Vß¾}iÒ¤I^^ÞĉëçD=x𠤤¤{÷î<(++»~ýº­­íìÙ³ë³g—T*ýúë¯]]]322äryZZZ‹-¼¼¼x<t=4h­Õ2dÈ!3fÌHKKã8fõæÍ›Ü,—Ëúé§3gÎÔæ2™ÌÒÒò«¯¾š<yòÌÍÍÓÓÓ<ø$WÙŽ;–.]jggÇçóQ¶¨¨¨ÈÊÊš;wn~~¾•••••UAAAõJ9­[·†šÿ*•ÊËË«eË–™™™r¹ú®zyy ‚›7o¶hÑÂÞÞžÏçwèС~VP­V_»v-11qóæÍ111ùùù?îÑ£ÇöíÛkt)½þúë‡~ÿý÷mmmËÊÊrrr!ÇõèÑ#//ÏÅÅE§ÓÙÙÙI¥Ò[·nÉåòŒŒ —¯¾úªžûZ6,((ˆeÙ´´4¸ÂqÇq§NÊÈÈøùçŸ#""œ­­­E"‘»»{NNNYYYÏž=Ûµkwÿþ}èEboo?wî\ìÎŽË}õêÕ#GŽôêÕ‹^î»wïzyy5mÚôúõë^^^­ZµºsçN½E§¦¦öèÑ£M›6÷îÝsuuíܹóãÇœg+V¬èܹsõý™ššŠ{ÒÝÝýµ×^ËËË+**úæ›oÖ®]kgg'‰®_¿þÖ[o­\¹2$$¤k×®õ`G!„XXXxyyíÙ³G$íß¿_¥RÙÚÚ.\¸°oß¾¿ýö[Ÿ>}®_¿neeåååõË/¿ìܹ³sç·~ï½÷lmmKKKÑURRòðáC ›’’’ÜÜ܆7¬Ñ  éŒH™LKñóóÓëõ_}õÕ¥K—<<<èRNßÿ}önzF,ËÖÛç†yJÊ- CùP«Õ,ËB…®òòrœU¸2sæÌz˦úâ‹/d2ÙÇÜ·oßiÓ¦¡¬ ‰ž” »sçÎo¿ýöÍ7ßÌÍÍÅb´6l°²²‚r;wî´³³óóó3ª½Èãñ¶lÙB©Ï¥yFHLLüã?BCC—-[F‹~Ð̪:FEEÐíÝlmm¡Õ4˲r¹—÷FýçeW?666‰‰‰‡Žˆˆ¨¬¬Ü¾}û³TxtuXî{÷î………ñùüF¸ O'­éS ?óçÏïß¿?Ö,ËöîÝÛÙÙùîÝ»#FŒ¨·:{™™™›7o‰D~~~~~~QQQ^^^\µjM´ !ùùù ,(**‚ŠŽF°oß¾fÍšùùùµoß¾qi9F`kkïëëkmm]\\üÝwßùúúÆÇÇ7cÇŽCÅ«@¥R+âI�¶Ô¤¤¤/¾øââÅ‹|>? �~²··6lX­Ô^رcÇš5kÖ­[÷î»ïÆÅÅ•——Ãõ­[·Òi¹%%%?þø#üÓ£Gøøø¶mÛÖøNhÚ‚óË3ÚúQw N GGÇ+VÀE½^ÿí·ßÒ·={ºùfddüú믟|ò }Úi°²²¯•µµ52ïÍ›77xö_eeedd¤P(üꫯ =À›7ož:uªÆ§>œ••etñâÅ‹§OŸŽˆˆ˜?>yu!&&ÆÝÝ=>>:òeff†††vìØqæÌ™3fÌ�I=˜sœœœ üàùóç###§N:iÒ¤'N$%%á?þøã’%KÒÒÒöïß?eÊ”•+WVÛôéÓ¿øâ kkëçå¾õÊr–.]ªÑh¼½½ÃÂÂ\\\\\\æÏŸ¿iÓ&ooï/¾øâôéÓ{÷î­ÿÝ0vìØ^½zùûûGGGôèÑcíÚµ.\¸~ýzÝu®Q433Û´iÓüùóÛ¶m»lÙ²]»vy{{k4ðéy{{BÒÓÓ'OžœššÊ²ì Aƒ!;àííÞ²eËú¯LüÆoìܹsÒ¤I·nÝŠŽŽnÛ¶mttôöíÛù|>0Œ   nݺEFF¢[eݺu§OŸööö(,,üòË/ñmï¾û.D~ôÑG÷ïßoÙ²e oÑ¢…··w||üìÙ³Û¶mûå—_îÝ»×ÛÛ»¬¬ì‹/¾ „Ì›7ÏÌÌlÍš5õc[ëØ±cdddLLŒL&[½zõСCß}÷Ý™3göë×G}ãÆS§NAKcOOÏ &,_¾|üøñ°Ü.\À·EGG⇆†:999;;GEEmݺU$Ú°2¾““ShhèêÕ«¥R)  §{ãÆ111ݺu5jÔòåË'L˜àéé Ë}ûömì ]}¹W­Z²nÝ:ˆ;xÅ`íÚµW¯^õööîÛ·¯™™Y``à¥K—˜“““œœ\8œ;wîòåËþþþááá­[·¾sçΘ1cΞ=;bĈþýû#’QQQݺuëÖ­[PPÐ’%K¦L™²téÒ~ø¢<zõê5vìØ¨¨¨áǧ¦¦º»»¿¬‡.ëÙ«W¯»wï>»‰F­Vóù|ƒÁÀqŸÏ×jµÐ¾^£Ñ€î¬Ñh (hÙÇA½¡Põk_Ìt€ož«wµF£aF hµZ(<Hfddðù|77·Ñ£Gß½{‚:ž°àÍsµ@ž8qbBB½{÷`Æè™aI °Á` ¯ã¬Ò³ý\sˆo^ ÑoË*<<< U- l´%à~NG?KÑétðu–eéêX:Žã85®Ú³Ìس Þ<okØ4€pJJ °F???0‡B` z½^§Ó1 3SùgU§ÓAêgÇ Þ<ï �a>Ÿ3Éãñt:P(4 5" ˆ¨ôôt¡Pèêê:lذ‹/â>ÇåæñxðrRÕÓ—fÉÈDÿ�o®]»fkkûìo�‘H„³ F„3�ã¥Zu„a–`¤à;0Úð/vZ±àH$zv•÷'=ÃF 0ÛOÚŸp½ú }Fûsm6¢6âÕ ÐFÇk@#5"cD’Ö¯_ýúõI“&=zôt‹úz6è¿ÿa£YmÀ™|òˆð?n  S5îc£‹F“ðô«¨î«> £X–EZóÈã�ësPÕ— ®Ñõø¤ý›••üøñã!C†­½Ü4å¥/Ö›§‘©Nš‡'-Yu„éYzÒ†¯·ÓZãþ4ڢϸ?kwEL]AÉòåËwíÚ¥P(Æþ’:ÿÚj±×¨`áÂ…`8þ/ƒ››Û—_~ Füÿ&¬\¹rÏž= …bÒ¤I ’Wd‚Æ &–C _¯>¿øöÛo¿’3 ù¿ÿqhÚ´i=o§ÆVVVÿñ0Ás°×øã†ó¨N§+))i@L0^‹Ò°˜</Ð7ÊËËÑìû_ôêõú× > …6ø©7À¶@ÿ ö¼äþÐh4ÿºÕ¬ÞÚüo,G,;::6þmp–!Pº¦a¥ZBˆV«mpLžÀ˪ÓéîÞ½Û°m‡ º\.ÿ×­àS�,œ2™ìUÔS Y³f„[[ÛZ µoœ µ¤¤ä_·š|>ß(®úk‡5j”Iï3 L`Ô.ã©!bã¸I”1 L`¼Â`iiÙ»wï¿Ø^åñxcÆŒùoÎÈÁƒ†+°Á`àñxÐùU ¨ÕjH)@£ªÁ`ÐëõƒÂ ¸—¬¬¬|||zõêµuëÖ¤¤$4+ƒ^ îx\aÄ7@£N§Ójµ‰„ã8x ¢æ!]@«ÕŠÅb­V«Ñh �Ò# Q�çóù�þ«Õja8p>é°Ïq¼ž…„ @ 2®à@®³,kaa¡ÑhÊÊÊ Ï�‚Çá¿S¡ýð9l„“ ³Ãõz=& ±, ÏjµZ‘HÓòx<½^ˆ±,+‹Õj5üm¨œm³†|àUJ¥üu:ŒpLp!€DšBª|‡Ãqœ@ €45H=!”^(¹ººJ¥Ò¼¼<•J%“É`’a‡°, ·áà…¸÷ø|>L®¯@ Ðëõ€0\áÀÐ`c`BþŠ‹S ) …þÀm [„`h),1 >ï„mF‹Å ²²æWvü—ÇãÁÆÆ_!¯† »v8äÿ‘ª‚oð]Lð8&€6¼þ†Ÿ`—*•J>Ÿ»†�kµZ¡PÃ;q-�1ÈF‡Ç¾Hª<ÍðŽÏýàoÜ`:rƒàŒÀÛ0fƒeY­V '¾Ž }pÿ`bL—D"Q©Tˆ*`•’’Ò¦M›ú!°z½óÃLkÿc!°½`9òrî/<±LÀ~‚ó´F¯×WVVþþûïׯ_øð!¦È!†­�{†ÉÃÑ‚WÁ°éá\á邜,¤A€†¾ €œÁO‰„Çãi4šœÁþƒS™k42¸×á=xé]ðE8]¥¥¥ð-äxæi9ò azá´�ÃŒly'¾G çàýHGhÖ…„ 1Á$e8«H‰!R©ÔÒÒ2??¿²²HÌ L)¼ &Æ‹ôΪÁ`P«ÕÈÂ1¥ÉÌ-dÐäã¸üü|@ —ËQÀ,Bà%8íL¨p˜:zÎÕj5n]¤¡0Xؤʩ ‡¼É–e‘IÃ…B!n9Ø~0c¸X€9. ò¨Õ·áÀ…B!29\”Þ­ÂÍHÓñˆÁºÐd]«Õ¢(E"ŸÏ—Ëåðx I3ðE@�‡Þ £@�CÀ%3:8"¸¢Õjá6Ø € b<|6® C€|Z h4@®ã–†;A˜Ã]GªWI£ D ·%žôçÊ´­M#›‰ßÀRñx¼©jõv±XYµÉb ±Áð+ËþβpÈy<Þg*UË*ê¶J(|À0oêõ~ O«!êtºÂÂÂà‡›éõçùüŸ¨ÍŠÄ žP(T*•x¢4À¦‡ B'¤¨R�=M œa|9œ ðux„¦D„C«Vê®]Åû÷þD†¦(ÙÑS‡2)fÈÙA® <~EË (Ž!›¯ðx<R ^H¹ª¢‚…‡eY333‡¢¢"˜I”gQÅA*ŒÇ¨MµIUþ9ŽFŠr LêF´†â*V䑏ܸÌ]§Kd °è€2fZŸF²ŽÛ�µO¸E¤PÈŠPúÑétÈfŒÄ`oð6øè&êFz½J* CÂgQéRˆÛña(À] w"ƒÁ}‚û î¡)dØôºÐJ'lBd{(ù!‡ƒ†R>H“šyCÅ-„Ã0R©”Æù-èÂÐÒÍùèµFfI‹e¨ÖÀêÓm0¿Ž‰ßBúêt§åòÖ·×ÌLÍ0 Ã|¥Pü$Êtºáz}1!éb1œŠƒ,kβ„™jµ=Ç õú¡ÍF–…ß)ã…Âp…"™| Fã#¢ìf@ a»�ùƒý50•éMSš.€Ô‰Š3œx w§D"Á7�‚÷£è 2ʪ ÃD"åüùìµkê… H¼ð ™€OÓÖØ÷øÔ‡Ðâ61ä4@)Ð<ˆŠ!D$Á €ÀÑÇ'eY¬Í\ñD6‰2&Í{Ðóüøñ㊊ …BDdyÚv ø c†¢ ç6—`ÆÐÄ„ •pQ(‚ì è!ƒDîŽÄ`À¶‘‹�3�î EŽŽågh !N>phnd¤ñ’@gÕj5ì1l$Xbä ¨©à2AÁ=¸ž ˜RÆOƒE7?ЏvpÒPZE†½Do?0|!#D=°‚=F£ŠFHšÁã‡HUQàЂ ŠRàC—ö?Ð,‰ç…?šaÀ"âxѸBo Bˆ™™È”5rÔÌhó ZSh®fb9 gùü±ff{år­N§cƒÁ0S p\7‘ˆ¯Ñ ý—eÙl–åñxcµÚ?…ÂË<Ã0QææÎz½­^¯'„Çã¹’  †ƒBá#€PV)Z•A ®Çðx@9&T’èm‡ Tv‚ƒ„Ÿ :˲°)…B¡‘Ȥ:yT”Å„ Z­V¡ÓéÌNŸ‚A©�� �IDATˆ%ÎhéPE›m!Á;iÒ5Úbƒ6Ô™�U”áð¢Á´Ì !@ Ti7¨8h¥D{B¡Éd0(­C*äÄ0ù¨ç!›A6‰< ü%(á"MG¿m$„E—Éd@ E"šÝÀk¨×ëÍÍÍÕjµT*eF¡PàÜ  KKËG)•JÚÃ$‘HhŠä´_½F†P`Z(åÀ< ×�îLdW´xަQÜÆè¨ƒÙ@=ŒVQôÓí ÎA½QbCO¤P(„õÅ·Á¶D!FŠŸ`ûçS©T0À½ÀÒ lØêÊÀQ_Ä!£„Û œ¬È‰A Á>DIPR©T0óh8E)©ª–†Ö0ƒÁ�uiánFyø  PP†‹Å&ÃZûrhlJ3ÆO§+`˜†»ÖJ¯wn:8H** ¥»Nç¥×áóA.i0H4š2ow›R±i{7ò0Ü+hL€MI»"`ÿ¡"² b¨ÖÐ’ˆ½h¬@/ü‹’¶o¯>Ülþ|ø‰÷å—êÙ³Õb±ðÈؾH‚ÑÙ€\‡V\�mÚmKû™á¨€ìtÖȀ÷¡¶„TÿÀQ£A'~ú«Ñþ�–qzPhÔB/:do´€*V9D¾Ó‚Eoø.P4ÑŠD>Š~&!D¥RQ£¥r77777·óçÏËårœz,h†¢}x˜¹Œè&r}ÚºˆÊ LxÔAqwÁã°ôèKGs°dôÑ’¯ P ÞuÚ¤†[Gp¤xRè€áhîÃ:•H”a¥R)ÆbМFTôAª@Í ¤N§Ú ²î+4s¡µº�È(¨ê¡EÅSÔŠàº\.ÇâžhƒEýŒ«´j� ¤5x´«7ŒÃÄo@Ó|ŽãŠYv–Dbe0¸UG YMt:µúwÊð.‘„U‘­ÔéfK¥Å|~7ÅdtÒÀ–Å€.8ü ¬ÐÇ 5bØå ¾ÁC»‘dú¿ð mGþ¤Óé4NNj__ñ®]$/”!g¶nÞÕUõÁB¡d7šLÐFBÔZð z¡p ´LM[Ÿa¶ñ6šßÓx½߀Šò`tÑÖ!ôx“ªZÎè ù1Tt𢆤5E´Œ1T#€…Ðõ†ás톔Æé5…p� …´ð¡R©<xpóæM¨yUa,°¯h^ˆø#n0íÀ`øH¸iÙ ¶ í€ý/‹‘“¡ÆƒÌ”Ú†‰o@÷8N,Ú*q{VHCá@’Ž@k©Œ¼t2``~t è7püA»g`®`8¸-á%pÄìííÝÜÜh]&t° ÔÞ0ú”–2n˜ašÇÃÐЋñ„ôî2Úö -!Á¸€€’T7¨šXN}ƒ^¯çª˜ Çqk”JKÓ8Ž«ò³„ÈUª¢¢"•JåNHd•KªÀ€Ïç(i%)±X ÄDÜÜ4K�ʈÒÍP„ …b±Ž.°¥R‰jåðU¸·è½þ?ÓPi)¿¬LÛ®ÃãI$à1ŒD¢íÜ™Ÿ˜ˆÁÖtl%>Nk!´`ˆ†cT 0ÞCÐÆ€¶/¼EE´<@è;‡!|4ùº@‹{èRB³Z­ÍGhãW@-�r &>t¹ÑùítÈÉÎÐ/ úB¢&‰€rÁÚ‰Ý$à²B_XX˜‘‘¡P(Äb1N= (éªM�í<C& ó‰+käË¡C‡iÎMG�#³¡Ã h·"° H>7rL”5ĸ|¤’¨Kцš[Ðaô¨jÓ>²:0]‚˜BÊgt9ŒA…§ìììºtéâàà� ‡9L¸J¥R(À®@çÀéBHÇšâЕÒ<‡ƒ“l”¨€¶ ‘H$‘HÐN@GT"D ÆAmí@;‡É°ÖÀö5ŒÂÒêtÝ8NÎqZB*FÊ0M8îËêtºuju33‚y±ä¸78ŽQ©Ry<ƒÁÅ0.Z­ˆã„—#ò«l)ÕÍ_¨àã‹Åا=ó@ ÎŒ´Œƒ{[Å`– 83U*†ºâþþ+’U&ÆÅ)Ãõ„È8ŽÓ¹¹ÉçÎ5Ÿ8‘Ïçëôz /¦u ä^ˆJÓ¨‘ å5Z‚ÆS´�£èHTžŒ(^;>Í„à±Æ4£:É%ž^Úç„f"\Apó 5™0É´‹‚æú(ÿw|9]%Ì(Øpê0\£ÔàW §g=4´SƒH$‚ƒ³ÿÒ©$‰D©TÒkM[ó� °/¡ÉU(ä÷ô¨auà~,î‡>BÆb¾Q´$k �Áhoð¾ðù|¥R š&†Ñ!sÈ#y<žB¡ðððèß¿ÿ¾}ûŠ‹‹á‰D‚ñ{eee8^#§­7Ó~M<¹‡œ†‰?!>´Xc>ÎKšÒá6¸Ð¨â£æ' é÷&–Ó`À0Ì¡PDzD¯ç8.\(ü\­²ŸeÓD¢f ó&!Ù #öW ò ÃÜæ¸½,;J£aYvºTÊqÜ—|~¸N×W«Mޱ,Så@FnP`püPzBa3tH îr æoŠœã8¥R‰æä[hªB6ìWŽã,Ö¬©œ1CÁç srTï¿o±`C9NdC´ãá=¤~ñ˜ƒû=1~ÎÎA¢†"!R¸h=ê[h¬£í- èpºtš‘QÐí§¡¥KáÄÒmâè¬[zèŽm´¯gR©Tœ£ÕÅyÔc0¡ ‚©F1„ðZg‘C`´=mëÃ,"$©´aJ­VƒwÍÈ ˆQÎhƒmN:Ç&êÑ-kÓ³CÀ Z#¤Ã@ÐÖ‡»šC½CÁaއ‚ÄÇ%æ“ ±‚„:Èt:* –‘‘‘››[ZZŠ×!3 ­¸ß0 Žæôè„ÃÍ o¦ã­át)šhpƒõEÎûö†Q  #h× íŠƒÉÄÄ/ËixØÀçóªd½^?¿Ê¦ÁRÀ0»E"Z- ×K¥¤J® …)Ãe0qTí¹/y<Â㉄BC•„d·jÖ´™Ž«P(¤»I"Aâ‹’ RúU´“–ªpß9*µZ­àë¯5“&);uÿø#[Td¨ˆhMç‘ÑŽYx 130 ‘¤å2Lº„ñmt7CZöG+›� 4 ÏÆô[¤é‹BSyzrP´DÊ…Œ)&˜¼ðÑ^.x3jNKÁŒ:´¡Ä€:\e°¸…Ð’>ZÉhN)\ц8ŒûB7;n?üØ÷‘·!'À©£-rô¸0R‹aâà òõmÜøWÈV×®Ÿ~Ja§M3¨T¨éÞ|S`0lgÍ":ÊÏOÛ§1öoç;§qrÒDF ɲeö*•……ÅãÇe2H6tÜ ©JƒÅ¸PDÈ ”Z ?Å‚› f¦¢¢B&“ÑQé(âI¤sÅPQFÿ+]¤�”*ZEÉ ëà2aÔŠ\د“>_ø*ºÔ½Ütš a¤ïšXNCx´¨ÂHé¸Ú3L»ÄIUË<:ó dš\â’ñR-m)†3Ðl `A†_¡ î3ˆÈ¤Íµð-�b€/Ô}1 ŒÁ Ú¾XYñ õU‚'ÝGœÎQ§#ˆ�U©TŠ!X´ÎAG:2èŒ/DÏ*.˜ B'¸Áê@l.žQ©Tè¯Æ(/ à´Р300ă‚PÀÄ¥”H$nn-HàEé (Âc* ÆÝ! >:’®S€ÖQ:evÚ€ ê¸Ät‹wšÓƒÂ!À¾Š¢�È <0§• üÇ3ø¨n2 £X¹RçåÅ¿sG¼iÇ3¸¸à`ç]»T*ÕÃuë,§Mƒ7óÛ·W!]¿^£Õ–ÆÅ™O˜ ïÙ“=vLt÷.Cˆ!7—‰*?ÿ\¼laT_}Õ÷§ŸÜÝÝ÷ïßãÆ :‹‹6aË0*ú€QvXÄ–8L:݇N‘1J_ERŽ¢pÌUBá�CãèÐ5Z{†Í) Áo ÍztÚ5®&-§ÂŽE% &Ñ<ÈçóA3)‚M,§!ƒ¤i±‚&â°¢˜L€2/Š3híÜéŠè3‡} ª�P^,,†3ȼýó±aÓÐÿJt-£êmøf V1r˃lˆv0>ŸoÐhtqUv BeíaÚƒâámHƒ0}y-\¡M ´Î§Î¶A/4:0t:B¡À81´«€çe[:e PXY±ƒöš¶!Z,ÃËÕj5æ'Á À´Ð†rº¤m“„ G?Š2È?0¶ŠŽ£ùºI0î‘Ö‡hüaûaÅ9 vhÈB¡ ‰&ëÃ)…á³, TXÚÁ@;Àà%fœ««bÑ"¸¢ ‰……H¯×ÙÛ›M›“&‹u:㈠«Óé*+ÿúœTª‘JE¥¥lEÇ0\Ó¦¼´4N§mÒ$55577÷ñãǰí°ªðT¬/gTßÙ�Š>h=ðXÚ � lU$ÑJ¤ûh$ÀLg<&è^¥!ì=,‹‡!È? »Ï£H$BÓŸQ¨|Ø'î" P¸ÿiûèñ( DÒ°-…L,‡ÐXä‘®ò„Ñ™t‰C:l)ŽQeC:ã½ÞŠd·ÆšK¸ÛPð¡}!´„ú rG:šˆÜDs9¦¢H…2#h!°§iã;tÂQ bF0tDcØúçÑ£ƒ³…yT*¤©#­G³âƒþº šÅà»t@*£h΢ó-ŒŠéѦsÔeþÒÙò¸CèÂE´‡ÖHÐ\F—öB½ =h„¤m÷„*¯‚¤“@€žZ5§C�Ú®HG7ÑL‹öüÑEq0  %–&¢ej½þ"y­Z=~ï=½¹¹V*åÿðÃ_î«òrîñc¥Ã0‚³gù|¾à?´={ê;uRËå‚_奧³çΩ§NÕëtœ­mvvvNNÆ7bå4]åú ØÊ(ª#¸ÿéA‡i JJ‡þ“Æ"§UXX,z&Ñ2A»Wñsè ¤sBÁI‰A­X«—f¥hÉD†Ë £C '2?PŒÊ<V�2±œ†4¯ÑUùp£BÖ©TX-BxXÆU«ÕëõE¢"‘‘ÔI‡ÓîDôR`!&:i.åG;·Â èh4LxFå-~À«g2Ò"Z·ÜÐq¨´=‡´Å%£snÐüB—1úœ²"ЭŠÒ(åi×4¡ê ÐYAFÑAXx†®+EWbEÒ@‹˜¼I‡V£éœ6ŽCÜmÕ¡Õ/T}0sˆP5TÐbƒÑtí¿¡­¾¨%£K™®o†Šƒ<’Î¥%tôåÐæbºt&ýÐÅ€ªR¹«TÄ``fD’NH7½>D©$„(•»**æmÜø}EÅŸÛ·¯Ú°’ãâ2¿U+‹Ï>›­Pl8{Ö燶þò‹`Ï@ &½z1·n Ö¬1 Ä PÓã×Aš¡cý’XÅb1‹cÀ²šeš™™©ÕjàI8{´ì!´àHbǽ¡ÑhвÑÞtx¡QÍMZÀ¥9  ¨¾Ð~_:³ØÈëI½iå ýL˜ê@çÀ‚Þ`dÖÄiÈßSçÐD×ÔêÎq«E¢ IƒÁG£y_§Ë!$N 8À²=)‰7.ªðÍEþžS ò;mT!Tq-Ü©´«Ÿ.I[è2¨_£O4k<]XØŠ.LGÙ¢ëŽ:ÖÜÙI$]E‘® !Ë(ÙgÉ7ºß UíZ45§ULw§c¥è²Ö4‡  XV {e–`*ÒV Ð0 dêõzDBÌ͵B¡ÊÖˆÅ|++¾•13c$’¿>aii03#UþÚffzʈz-2�l<ÿÀcPÙÂÈdZF²˜âî@,kqV´mTè“v ¿4HÌ-Ã;ÍÌÌú²ìpƒÁ…eµB¡ƒÁ ×ëo³ì×bñ:KË~:]nq±>=ÝB­¶ä8 ƒa¥@Ãã Ðjy<ÞLµú*Ë>"D¨Óù„‡ó^ýdEE¨Rù—ÿL¡îÞ-Ý»—WQÄM¬0LLõ§S»ÀGF&“áÑ�i Œ¢0p…P=ÑMH»éÌ£²¼¨ÄÃé€i·²²Bÿí)¤áh×]Œ“½ åB{ U´ -®´pŒÂ.ÚºaÆh œb£X>“–Ó0ÒF– šî3 £6Ü•Ê(Ž 07Oçóu:ÝTµú Bñ™§Ñ !…f*´2Kï<-iÅH J”h:Ç,ýê& |ÆÐƺ ¦+’¿WÃEMŸîö/4 PÑÎCÎmäÙЀ„NË mÊ4k§+Uýì ¨ñжA4C#±ÆX/”×èXp£ªÒè·@†Šn0°¿ÀtT ÷"‘Héá¡iß^ß§xêTp<('NTÌq7w®àƿҿÝÝ«V¢<>ßöƒ4-[VÎËÙÙñ.^”nØÀ/)aFÓ´©rÓ&á”)lÎÿ³÷Þav–U×øýÔóœ2gJ&=CBß—"D@ˆB"RDA©Q”"ð¡(E)Ò›T!€ˆ¡CèDB jH2iÓË©OýþØsVÖÜÃïßo¼®ßÌåÅ'“9O¹ï}ï½öÚk­ÕØz„¬È²7<â2F†™Á ]É-R©”Ðèâ¸É 0®S¹y�Y–v–×Õ_ÿúÔlöÖyó^6Œ×]7I’¢i®tǶ“JeÇÖÖÅÇÿ‘çÙŸî%Ia»íšÛÛRIõô\wÐAQîõÑG)˪‹ñ.»ìߨ8º±qÂÚµí®ÛóÍö}÷Y–e®\‰ˆ/'îk)¦q‡Ÿ™‡=¾‰&-«}uÏó*• î÷”tÞïÈÕpÐWåj^>EzZ¼‹qJaƒ# šo ýñì”»´4š~#²žÿ-GŽF†áž°Rª)I¶6Œ_xÞJÏÓÔT*•îêïãøøÚÐ ‹z¡]ÉÕ1Ÿ¬=ŽpÉRQŒ 3Ų !¿ÏE=h5xf“óbE*ñ,;†¡i„0bÆî>¬JÇLP©«¤¶ÓæœYì‹9¦Hö™¨ÊS~ø>kmqó�_ðÿt‰÷TT Cl1Vصë®VM!-ÚvÛ`»írÓ§A Î;ÏYºtà —.ÍydÇþ‰'&¹œïûþ.»d.ºHµµ•ñ‹ðÀÍ9sÌÉ“£ý(7N»„ÇþTAQr1SVVŽ€HˆSŒUÃqŽÿ¢imMœ÷_‹;êÐEfhÎ÷ýO?ý´+ŽW[ÖÇž§”ªëî>äÙg_U*ŽãÆõë›gÏ~ôüó«ÕjÓ¬Y†m_³õÖ»÷öVÖ¬IÍ™S:ê(Ã0þqæ™ÙöæÛn ùËh×]xë-óÙgñ¼ÜÿX9ãŒÈ0Ò—]&°6ÊVÎ-dBS:pâ‘ÃC*lL‘@5D0 ÏJ˜á+ˆÁªµlÏ#§²”þ2àU§üðÞëYcà~Ü š|XŸ6¢oD˜9‡8>oFürþ+NÌc²Ê¤,Ž1Jí¨Ôùüÿì¹çÁ¼téÒW_}õî(êìë{´Öëãò¿¹¹YÿR©$³¾\îd³Ù¦¦&¥T±Xô}_šYX5$"æø*&”¤Hl-–äV³¶ €ð`»ŠV1`}h¿cË>€€~�œ܈f\Æn. Õh®ÊG#Ô2AYÑä ãÒ `¤Ž]×ðHÁ\�fX­Ví;î0¦N­žsðTgÎ :({Æ¡šò)Õ3ÏÌtP¤”5{¶iYÁöÛ›MMÖ¼y¢ì`ærögŸÙ¶­¨ç©Ñ±Ê ×bŸrdòÁˆãæ–PÁ·Ô‰ìDKx¨“³ly}rCHMŠ­Ï-ëUÓ ƒ`toïI>øz>Ÿ$ISÿôóÏ9sÊåòŠÆÆës¹ÿýâ‹Å¶ýCÓÌ|ö™óÑG¿.ÎÏ寄á^qüÙí·A`…a$-™Í›£ßþV*×x°-ŽF€Ør%[o½õÎ;ïüᇮX±I¬1pߦԗù|^ '&w z€,Üs6�òÜð¤3Î?`,ëæ½Ìc³|°±þ/'зæ3F›Íéå Û©ƒ †2Mž<ùøãŸ>}úQGµÃ;¸®k(eZ–@Þ¨²Ùì„ ZZZr¹œ¤i<ÔÒØØ¸ÝvÛí¾ûî“'O®««ƒµ4¯d¥â,¸ÁƒØ„BIrj_LBA£T€¨h²˜ ã’¸Ï$\fèñ�ïâ! ':¦Ê¼ ˆÞH”‡€¶ÓH]7Õ`qî¡x&Ãèr1™LF¬´‚&–Lo°>ñ‘éÓcÇq®¾ºðÀ|r‡aX¹â ÷²Ë°œü|ÞŸ5Ë»ë.cíÚxôhÿG?rn¼‘‰,�Ìcí`rå~ƒã8¹\®±±‘•îÀ!DÇXÖ°?üÄXÀBCóä;8bùåâì‰ãØ«µÙ¡âU__?~üxÃ4íºº­·ÞzôèÑ;ºîÌžž—ÇŽ}câDÛu[ZZ~oŸçr¯¦RÑ2j}¨d2û?“Ɉ¦ºPÌÿÎd2X<è_"‡Ý§ 2#òJþ'oær"-‡üÓ4t.Žc1aâ?ï ðʘãŠ?3ù Z|,v€}'Ø/¼>å"ÔÀ.ˆ1Z_|©#ÀÚð3еcq\Ùó%¥:âØÝ¼ù‹/¾=zôÊ•+;::vÃŵ†zÊåò† ²Ù¬4*¹¿'‚4½½½Õjµ³³Sv;²KGÂ7黨šž+Eck\¡Oóc2èÎM,ÙKŒøå‘«ÁSúÌéÌNbÚI#Ý&¡tCÖ+P í]É?aåÀbr2ŠÐ,·ÌÖ5<µ3jÔ(éšÀ‡1kŒwK¥æÏÏ>ôPÇÕ–žÚ³m[ëtw<½v Î=7}晦e)Ë*Ìkÿæ7ÑÎ;ÇÍÍñž{ÚkÖ Åæz‚ ZDsO–L.˜Ñ 4œÊ˜€à…hÌ « ëAˆ`jÉõ�ƒÂl�þ Ïó½½ï;N6›õ<¯Þ¶'”ËGf³QmN§¯Ÿ:õˆbÑËfÛ CÁn†R_d³¶m3ÍÓéÐ÷§$É hg†5Øô©+˜¡—ŽÖŽRjÉ’%«W¯–³Š©Þ°?÷</ŸÏïºë®]]]K–,Ñüë@äAZƒ)y¼š'!sÒP;rÍŠzT ,IÀÕF*•’áh$¶mË—mÎÔ†  …B6›…™“FÑTÞº�NëyÒ¸WÐÿ;@ó4É:Ó\d—nÚô§§Ÿ^´hQ{{ûŽ­­éë;)“9¹Ra)*y—…Bé¹<okkc‘yÖº—@ acÈ¥ð¶xŠ»ëÌãb8 nÍÀ¬“e[Ôh:Œ ðofEü_5FÒ1"ƒ'—Näwè$±V‹ ³?Û»I ‰« �OC4Ùa‡FÕÙÙ)±FCù o̳)ZvÂÄúŒa=ŒÖV££cÀhàW¿r¯¿Ë~â ã{ß‹’$;¶²çžÞO€jÈ-7AZX¿™“v(‡¦½æð¿eÇ?ù·°°ƒØ–‹¯ý¼"ÏfØg…4¬‡r¹Íétccc}}}âûwwï¶q£¡Ôsù|Ç£»ºÂ†† ¶ýlcãa†aüiÒ$¿TZ˜J}½X<&Ÿ\÷ÅjÕã >µ¬xÈà”0¸J¥Øhš+ü|¥RAm„Œ„ä^º»»»»»Y[‚¹¬6Ë‚ÜÄbÌäiÑÔ`å'æX#KÀ!6 Û¢3{že4ïyV r�­™rã—–¼|(¼‹—Œôrþ[Hk¬°Â¢H%ÉÛ–&É×®ÓÚEÑdžq™çùƒÇ9³à,ž‚¹ñ¨Ùv!ü)šÛg2`}ÈŸ@øDŠ�žAã[ãùJ5DYòhØZìÀÁOE2P8·$–áb$‚~l€ïÈ aŸ…‹”oÊÈ ÏÛK(‘ÚˆÝÑÅáÄiš´ñU«Vµ¶¶Šk*ÓÙ%vËcÇD÷ rÑš5ÑÒ¥…{ïUJ9¿ÿ}’$Ái§e.ŒÿóŸàÿ×^»6Ù¸q`W©ê5ׄŢJ’Ôw:ý«Ä©ÂV[¥î¼'%[\ã¬åh"媘Çp; Ð+Š| âóØòVj@pÔ„ ˜×®”º©¾¾¡¡¡±¾>ŸÏwuu]7z´\žišÛd2þ¡‡:}}™%KÖ67ßÙÔ„ç_ž÷r]ÝØ±c¥¼¨kkëêêZD&1€ wÚi§=÷ÜsÕªUï¼óN¡P`Þ7œàHàB>·\./_¾®¯ÜBפ4ãb…ly ¿±Â&£[È@Á 0÷ÙðI›ÚÆw‰À’/95e© Õ²Äa‚7Rå óyƒ0ÊÁ'A“R—ËÊ0ÆÇ±§”RjÃè3 7IÞ¨uËy²óÀó~§&Æ,Õ(Êúf©sAºe7²2Tm0å“cÐõaˆÞ½uuu"#p‰ Ͱûåá,Š"ÑXcq­~‡ �7?±bgŽ…¡¦Á½ŒÎp�� �IDAT°'„‡Y™‡ؽM8²+W®Á£TÜÎ^†a²lYêòËX^ýýöÝw«§Ÿ6 ÃY·ÎvÝÔ‚Õöv+IœÇ7’$¬A ù+¯4óy?’8Vííò¹¶mg~󛸣#¬E è²Ø0RÃ'ÖíuPî®R©È0[va%ËÃgrD@ô®y^gH<H“@;·,Ëjhhhjj¶˜Š"J˃#‚¦Ê"¬AÏa‡–•zî¹®®.Ïór¹Ü˜1cªÕj¡P�â'·æyÞ·¿ýí<ðý÷ß_±b�΄P%cU0Û…™Š‚=roOV¯´FXMޱ2÷O£Œ“^Û`ñãâCˆ•¤ùû˜›Ñdu†Úà⠙ą)wÂðÛTÍwd.ç¿¢—ƒ­.ÞM@lÛÞ%“ ÃPö0ëd°tV4祫£vç&r1®'äy+F 0Ô ŒE$΀Ú3‰(êÕ`ñ‚R©†÷±8£ä¡&‰rm&GÀª‡Õ6‡êP1Ý^ Ø–Y@`¾øܺc.5ع<‹ZÂM2¶]1M3ö}£½]ÁžµRIÖ®M’ÄŸok‹+Ó¶ã®.~#Áúõ©Ž;Žàٚʙڼ٨± (2òAø` ;ò\? 5ÔÁ VT*ãV4.Ð5†¬rs%áGÿõõõ£G)UIÑ$}ö<Ïó¼L&“J¥FÍfã8îèèè8è `ÌU©tvXóóÏÇq\,=Ï7nÜÆÅ܇DµZý÷¿ÿ](>ýôÓöövgCõ~°äÊQر…¤\¼Ò8·c-¨ý#qDmÕšsr Å7ßÖ.›í(UJI&™Z/yµpEË”шCæ¡h’W˜¨|~9Ãvä ¢±,´|É~`•lQ0/™´:ÔD­DxPQÚb¡u0_y²ÁU?O{1VÃjlª6Š'ÿJRN…°mÀ€â D…*Ͱ ëÚ¢‡(Rss�Tø\PY…E"…¼&Ðyê ¾þ#{˜sI5Ä¿’ùÓˆàòœ¥ÇÀ"’xÚàƒ0ÊÁ㮢)€I+[ŒshÇ-C‹àSq ¯ ²\°Ðñp0НEséoãj mÛÎçóMMMRe‚åD®®®n«­¶š4iR©T7n\¡PèíííøÞ÷ŒLf›'ž¨V«Ž>ºï¸ãì§Ÿ–ëñ<¯¡¡U¾ÐºÂ0\²dɲeËúúúЗâ#‡ó}4ÿ5/NßÑfZñÞ‘ia Y æd¹›%ICªy¥ÐÁÕ ›3!bº?²>òq›°i`ÿY +Ì‚CáÅžÖx³ ù|¾§§g¸ü FHÒ[v5XCù|~ܸqù|^6•¼u�è,ô GNP}0ÝÉ“%L2ѡ̥‘°B*Â"¤ ‡¦6ŒS±cûXCeû§@p´@×ÕwþDM×™ÙnlaÀ4$ã8䨄†+*5X†„Éëò^9׃ã22S”¼%‹Ôn7î“ü� �sq ÿVå…Ø« Ú0ÐϯŒ-0 õŽÓP­-–"ƳåÈÍ3n60®ËÐ8áȳ«Šü€¬ÆT*•ËåÀ?dIVù«†††I“&577·´´È$ÀêiÓJ†1þÉ'å~þñR¹Üvì±a‹År¹,þÊ’R èêêÚ´i“Zã½}eî;ö ¤2¦° N�fyrS‘h&9Û[0›»bHVä5±`³–=°³8ëí²ê•¬4ð ä'qƒ8Û€³Éïd,„=´�eA644´´´äóùúÀ0Ÿ7ª8‘—E&Ú‚ì4Ž×Éq­,PÏkY§6PÂR˜ ³0÷_v‚¬­¡²¡lO€ÓÙ"ƒHÓŒMưuÚÆw¸í¯‚©Áºý,1—·¬Tß\­žXcµ~Ý0n,•ŒrùòlömÛ–f{Ç‹K¥Bmìïy3•:¯R©FÇÿL¥®7Í1J=Q*JÝäºÏg2Ñ`}h®N¯ÐF…pTÀ:…Ï!–—Ö0C8š0Ê£K,êT œ1”Gh°1š–/ûݱØëk¡Q§ ž*ÒBfX@L¨eåHÀËe•L~t~ˆ8$�ä2™ ¸ÒêCÖÿƒ•+¿ÓÕe§Ó™ ¼ßÿÞPjf¥òÏCu•:ù¶ÛªaÇq:Š~÷µ¯Å/¿Ü}üñÅëùe¹Úºº:QÛ”tUš@¬BÁ€½–Å㕱M»ViÀ)3èJòL4ûs+’uGÍÇéÛt¢oÄ£šÈŠ0Ó9 A°ÑdÙ@Œ®íl ?TßD‘ÿŸ(ž6oÞÜßß_*•†k4gäÈQüî!3ŒÕ†¡œ:xýh‡@B#ϰ.JÀq©XùÜñƉƒý~‰~Ezþ°êᣈ<Ù9 §á¬½Ïú �²dº„-&q{ ÃéÕêqQ4©æŸfÆ«ÕCêëƒ XP(áyf:-¤ß0¦år]ô0Ìøþí®û°ç¿žU­”Í*¥î*——ÅñÒZSADJ�§ð© XŒ‡^a÷"ú(xÝ@í1…è z!;S Ï7÷[Zâ °7o†Üp<1¶ eOI,\Ñåbætøåj¥9eXÒ±™“ˆÁÝ E¹æÒ\NÕDÀä$Ê5HÃLÈ„étšåh… ƒ–º»×_pÁèææôG™/¾h´·g»»güã¾òÊù3g®{ë­eÅâqvûG™$ɨ×_O,«R©¤Óiá°ÈK‘ëÏœ(,À öÓ‚úÖÛS‰ø<ÿ€cŠM€³äQ� �Ï^ u¤§Ë9(Û½³.ÃÈÌ5šÇüO.F…Ö$ˆÍ«šñ«ÆGEÒŒÜÜi9r†³‘‡N‡ªá�àÎzõœP°È1%\sSTÑT0«°0jh®‰Èjž \°3”¬ù©(RZãá6Ô*ù"°F€Ý²ÜÅ£ž÷˜i¾ÜׇnÁ¯Óé]“äPß_è8‘a$Q$iõ˜rù¢j5I’G c“a(¥©VÇ$ÉFÓ|Ôu•R¿u]3I¾« £-Š’Ú9Ìq„iî|úb¢)¼\¶7sÜÁ\DQJ:¼V”ªbüøê 'JY<tvrÏ0ŒL&%c´ÍP³ ssåg0(Ÿ+ü1‰P2ülÈljõ¤çyB×ðî.`:ܶ:%b2Œ"gžìŽúúú1cÆ4­_?qÒ¤1—\¢öØ#8åûù瓽ö2—/ÿÞÚµÏï¼ódßßûÉ'˦Ùvøám•Jãý÷S)1¨•þP]]]{{»–-ñ|þWÎ }ÕÆ!‘b Ç-ªp6ë oO‰Ù1°à©5XUsÐшÈ„0)Åe³®ùú5Ñ6.—qˆbÏrލ±·Õ`[ ‘#gØ€5d%’°I p[_Ïó²ÙlWW—ffÅÚbaÜV’,MB˜zå@eÍ[”WÂPaÖSâVä¡ ÊIãt˜Y˜ÈþXŸë˜#ÔЕñl'²åbzl{…ë~»ZÍx^¥sgyžJÃ4W.Ÿ›Í¾âºm¦išfs’œ¦RqoEGFÑ}ét‡Rªö�Ù.Š"ñ#` Œ#L>ÚUM$µ`CCƒçy]]]R™q"‰ç V˪üö·©»îJ,«rÉ%Ù .�ÖzX €pΡo/Hš@Šj•–öØ5…!ù[ô½ã8. Åb‘'Ž!CÀy+ÔáQàšaÙ'—l6[*• ÏJ¥²ÙlCCÃvÛm7zÅŠæ[n o¼Ñèës®½Ö?ãŒèÔSíöö­oºéÂ+®8õ¶Û&×Õ9ÕêÆ¦¦1<¢j A.—“÷"Õ’ì>Q©àv£ÖÎÄIÀ-RMÏŸ÷ €"5wE!ü<qJÁqŠ ÊrtÉu2Ø 5yú<@Våy>î?¡†ÆÔø Xô ÜQ$GŽ ü†QOzäÈQZUÁ‚<1' ”ÈÂCÞ•§ð˜þ¿`¾Š”b $‹Ä’ÕX.C#!ŠÎM !ìA‰è/ÿý^ù>cаiš6eþHÄA.ÆÓ ˜jÊ®N’d¬m¯SªÕ¶Q*)L&IeÙ¶=Ë÷-Ë견WM3N¥v/—¯V×ÇU«¿N§{ ê,2]Mª%MAÌB´Å�6¶"ŽÛl6ûÍo~3›Í.\¸ô\ø0–ÇqfܸÞk¯Í^|±ÓÝû—¿ôßz«wá…f±ˆS_8æ¢ TMôÉx±Lk”1—¡Ô;^¥ìþÀÕ¹xƒz΀’\Èi©TJ>N†å¥3füøñ ;är¹l6ÛØØ¸õÖ[oµÕV£-r¼¸÷ÞÖ /˜Ÿl¿½†Î˜1é8vúú~ÞÒòôĉ“ÿñSÖ¬Ùpä‘¢`YV¡PQÈ–´L¬Ç¹ô1ÚH<�€êu$Ò )øàÈ.x¬ü*–kzK»¬a›°›*pN�›˜F‚†ˆÐ…²á9>äàfÄÆ<¨¥øÕk~¾x2€ë™óí.YÕ2kÁ¶RÃiGŽœ-Éx,ò^1(ÇH‘" fd¢%«I—«Á]n”­Åì�ï0òC·Ÿ!Ùl’|!â0oŠÇkÒÝÌoù…HÀÍ"øjD�ÍHø5F/—>¬bÆýýß®«ÛBÙ¨M =S©LËå (ú£0Œ ãáš:C•J‡66A`ÿ ’Ï,„,Q@¢ WsÂȸ~ä®]»ÖuÝR©„쒥ɶDí––ž3ÏÌ\}µÑÞî¤Ó®ë–Z[nfÍJß{¯½y3ÓŸ´°®9Ó0#_‘™…Ô™L†_+’ôùÙO ‰DL™ N~'†i0Rаå8N:C~ƒHjÊßæóy‘ï”B¿®®N0±ÆÆFÇqb™,šVJon>{öì­ïºë¥«¯®Ÿ0!Š¢¾¾¾7Š©šôN+•J¥R‘Ó¢|¨$J9‹3†÷ˆÆgC"bЬ@X~•‡Ð£eŠ,�Íë“ n‰/Õ¬eb†ml´ÒJ~XÄÖx˜»¿©XÜšáí|’_Åôw°~FŽœaûbx] ÙŒlhü`$§üî±Úx†ƒ|BpºÁŵf¡%4tž! ­ý+h°hGc¾ŒHµX6m-ùIƉfs€èhòM,‘`Ƴ–õëJÅ0Œ×l;L’Ý“$Eï'É¿gV¹lÆó†‘$É"¥¾†‹†R¯xži–R q’X–u·ãtÔàA`žÌj…°ú�â%¡P`Ç#+—-[&66Š|ìUMî)BÐÔ¤ …¸P°kðc†V©”J•\Î[¿žù)RÖ�á²p.*fL5JJ>nܸqãÆ-_¾¼»»LbÛ¶¥�¥E£Ãɹ‚"›çKIâk'7xž¤P‰tU“@–SÍuݦ¦¦É“'O™2e¿¶¶‰'žhÿãISS|ðÁîÛoWöÙÇ^¾<ÈåÌ >ü׿ò/¾66¾þúëŸårÕjµX, Û¶‹Åb:. 7nìéé‘Ç‹Éåæææ(ŠÚÛÛŠ`95ö¨ÅÖãTÊRò.ä¦0ÐÍÊ (ay¹ ö>+›@R©È9'ÿé‘v‘¼¹¸´VZ§°AgüO&ÍãÈ—3›=îFŽœÿ ª4V!Æ•Q[pYÍíþç~ %Ø\L²äFùQøK$•ùír¹Üß߬@¢�‚;Ú6ªÆà’|VF(Q‘ODQuîâ€úÉzl ¿:`¸)Mƒ j+ìÌø;ÏÃ0ã©Ô4¥â8~ײ"Ãè2 +Ž Ó¼Íu÷¢8Žß²mÓ4?6ÍĶÇAŸi¾ç8V’\VW—öý8I,Ã(F‘ª!ÐB†NG˜ É4‰æÆ¦½n±Š hÁCβɽO?•ª\z©û‹_ôôôضmg2Å‹/NÝv[üÉ'!ÕÚ+¯¹*öCB0EÑŒá!žaî;&O‘m@æ‡] ØxLn‰ì�aøL¾'Í,ñ•‘(&…x___ooï¶›7çÏ9§þœsÔ¸qÑ~d?ÿ|fÑ"sóæM‡V?fÌÞûÛÊ8^ÙÔÔÛÛÛ^.Cñj‘Z‡h©<:iG¡’`qXô¨0êeÍE—Ùr›<àEQ>Ÿ¯¯¯ß¸q#3µÒCW\ûòQ§«s ¦2²UæÝ°94ÔØÔÌ=€ð¨¢ðdd¯1›Ÿç1Ø7r„±ößBzg…’lrŒf<GÐ^&+šâfaP.xùs±½Az†|‹ëº»í¶Û÷¿ÿý>øàå—_îîîæ%¨ñÓdÛH {7!7”u©Mþ ^Ï8›| Lsá5�e¶k:Oª)K~`YV­éê›æsahÔ„ÚR©8ŽÃè ÃÕ:qÙ¶ýi’|$)ÛVqlYÖÛ–U­eŽQ%$èÀEè¡x}@M¦5¨ð_Ø™0üÈ@–üA¨ ÙlÖ4ÍÊâÅ©«®*ß{o梋BÓ,Ýpƒwá…ª³“ Ž ÷¡ÀâL%˜u˜jmmÝ´iS?/„fÆ<ñÒ‘ c–¨)¤ €$ÃOLN;ð’ΘQš[¢$†Z6lØÐÕÙÙþÅÑäßz˽æU©˜¾¯”»r¥éû>à€’ë¹t)GCvBK©˜Äñžž QaÐ’I˜rrפ†„×Çòj„|ŒiPQ‡C~=Pð88{€˜^ü6!ÎÄƒØ Ù³„xÑÕgÞ¬æÚ®IX°è:kÚ"7NàPÊßÈ‘3œ_X ÜKÔ‹<SÆÜ <ƒßšu<k$¡æe)\¹¤þþþeË–­_¿^V<²c@jHx¸CB-'ŠÀ2£G^»vmww7# <ßc4Öü@ÇC²<èÊú+À¯?D3 +žÝ-‹™R…ƒPšÃ€›4œ¸$0Ú¥FVÎç bL©"aë€öÏ@ÀZ¿>sÝuÕóÏ-˹ä’pófœÇã “„­Ÿ„i'>ðP‘H(Ç'æ<Àž’À‡4<YÒÕjµR©xž'zhÒ&ÁÜ"4R¥îÑ„VAÖ÷}?›Í²¤…¼¯þþþB¡°Ì²&Ýw_yî\;—3öÛ/Žãöööþþþj¥FÑ÷>þX¢fWSV,zŠlа#) ¨ É¢ Ælâ%Ä×ÉÜeáõI{_ÖOOO¿|¨¬(é‚ÈC–$΃ÛH#Ø;\Ñð?Ïím䪑¤QÏáícV ‘|æN S$°¡x@ÉrSC•æGŽœaûâ\�ˆ¦êz88Ê.Õz´¦¢"hiò`& —ÞAüç?ÿÙ°aC©T’( ‘ENL›J8c9„*ÉžÒéô¸óÎ;Ï›7oÑ¢EŒç0–ˆåÎZE¾ñÌ @?\49„ÑñD ÒРã©„ ê<EËX†lؼá�1x[Õiî)‹-rê�¡6>Þ‰cÔÏDîÅ^½ZÍ›”JÉš5øt‰€›…ä"Ó€_!/ÁH#úÞaŸ$„*¨láç‡* Á!AM¾ƒ_ÂÞ-(òwUJ Â’˜ÈªÊiíyÞK'.ùÆ7¦N:eÊ”¯ýë•JeÞ¼yŸþyWWWÝÝÝH°Ìš$9¨Æ–e•J%ñ£cM<U³Âᄸ‰ç£½:&ăˆGÊ­>E"Üô °±Â!“Vð·x#`Ä1´«M\)R*BæÁL9ÔU ~jÓZìiÂU2d2´f*Óh±pï#Gΰkš¢>/¼r-µ5Sëj"ceNKua™‚c?ì1§ÒoÌÀQ$©O™¡¢ò}¿µµÕ4Í®®.|¬= ‚J4M IßéP/¶oá.+w8[çˆÌÒa¨`8IW$-ÅŪ _âÉH<Ê„Ö.è­ÜûUdÜÀH=ÒCh€rð>f~ø¡†m‹VRÔ7 D1“£ ¸mšÖ5Ëæk4fL@ÖO‘DoxÝÊÅ à?pKb¥TfÊ‘p«M<I-3èëë[±bE¥R™0aBÿþóŸõë׳~ *t ¹£‰eŒù!Ít€Mç8‡@nǶ-çМ? ˆÙ~!Å¢;ËzÚäÙR®æ±Ò r3I3•“ÛaQ+<a@pø[. áÇCÊŒ‚¬Èîs#GÎ0·s°YE+IA¯„£‚/Ζª…ÏöD9ÁíCBžÄ 2í%¿AT@¢iÄÂÒ`²AP©TÞ{ï½÷ß_TÁæCCÎýµÝ½tÑ¥”I¥R2–„ކ섺ºº–––ŽŽŽžžV×–›‚ #hÙ)Ó-ÁN¸^¦'IF:®ÛiU²ÃYŽëA‘Ī6à°<oQX|Ò @» ¦y†Î´š¦™N§™ ¢L,Î¥ N_ XàLjî«`'buqEôT˜­'e¨3Èâ6¹0)´˜Åj1H>ðTq$  Êd2¶mK3Iž˜+…BA^Šã8­­­ÝÝÝ7nÒ36º5B=Qµl6›J¥„€æÒHËȉ…j†ñ+æ³ “@«\Qæb†ªù Á‡çO(’ð ¶kâªLE.+«ˆX!ýœä®1™ÄŒA;Øa`C¾ÏȤ&×4rä ?U/›ƒ:±è£’À…3è5v5–Fùd.Ë ¸Ha'£È�ÎÀ™ j,î¾Hø›[#®1ýA†×‚ TDëÊ�¾×´@4J` yÅbQö†63/C!²úwˆ¢G …LÓ0Œ#‚@RÐ…¶Ýgš-…Â]Žó0©TáiHaIv5X›’¥®°µHôÅ<xN'ÙŸFîNR ëeD 6½fTÔ”,ò‚øvÁOO2ÄGŽ’X¨HnÐB5ÌORj×!âéi“%\[ð€ˆ|I¸Ç»“†ÚìXüd®39NäÉ4.êùhñN–ÉÃ0 …‚C2 Í"À¬5X – >0× F¨Äe nEg,†Oñº1dBKÈOv󄵈i4#0Ô$I‘î2]ÙSõõõp£�n†–Xm 6€æ02 :ü_̈g;jÓ4!Ñ(ﯩ©©®®nÓ¦MB¢Å:vjJÉ,•`ûȤ­± ÓWÐC”áT‘ÇN¡7£­fôåb�øBý¤/ìC¦rj­ÏóäPÁjÆ ®V«2ÙËÑ£ÿ$Ž¢(Œã7,ëÛÞ+I>¶í8Iâ8NF»m‡ƒX“QP¦t#ú° +l`VA…:LŽB¿”´QžàÃ0”PX(øüãÑNžä`Œì^YB¬hÇÒ|j°è­ð²@­äÙ28áÙXnÝã-3³Q*•J6›ÕÖâxµZíïïÏår|äÈvZGÖ\§¤YÙlÖ¶m±Õò,Ì9­aÝØðËš„ø¿<»ÆÞ"¨òyö-«¯œìFŠ€åÇQÚ‰® –3‘G”`¼Áµ|Ž“EŒÊ‚÷)Tµ´vz gf?rÞpÒÁÌK¸°wS©T*•J˜í’­ˆäV¸Ü„D#â‚Z0OQƒSáýŒv£+C#/;{j1D–c¹\ÆMA9{Šž‘ġ̀tORZdjòMIçëêêdŽrÙí‚•ÉçEíJ]ç87çrM§_°í•Šl¬ÀòY,ßË(™ÆðAÝ€‚õöÙ̆C 8ÒFùWJà[ ïE¹…ººº©S§Nš4IÙ•G>Ëzr”…SD,E,üÝt:-É\9Ï*3á®>À8{ÐbDÌå0­‘ú¤(dí5¬Æb±X*•ðúªÕjµZ…™¨â—J%©`„P.—åû’hCvH^¤ÿ½½½Åb9Š@¯ Hðõ}¿¯¯¥•ðÒË×^ öpÏ÷ÍžÝÿÄÑž{ÜŽãØoj’ï;ï<à{ö“ŸçÌ©Ü|3*ŒÊìÙ…'Ÿ ?\‘,R¶ŠG«jJHØÝRfŠ9/fÆóùŽ˜¾pÄvÀ‚a‹EöýÞÎÞKØkÀ5-•‘#g8 © :kbBªÙ´iRo®ÇuÁ)…if÷3[I‘î:Ç Q¸RdºÌ‹F¢-T˜ÐÚ况®jFè| –bæ.#Î ø2)Hî‹÷€\ uHp”Ø OI͇ UIÿ –'É–µãÔ©‡vØN;íôoǹÔó®®Té¥5²ã«Ñrø„“¢oCŽŠ ¸÷Î\ YéNDÀäQƒ¶àû~¥RY³fͦM›˜àÇ…&óCyDœ" u)FL‡ÃÆàñO0ȈX3X–è±3ì ¡<Ž€œÈËÄ%ÿ:�9Ž …‚8ªÉewwwCZß4MÁèä;ó’³Sú=ÜUû†g؉¥åÏœÙóÒKþá‡ãòJ<=óÌôg?þ±jlÄ3¯Üw_ҧŸ^¹ôR#Ÿ÷§OóùÔi§y?Üt“eYå[nIŸwž{ê©ñ´iþ®»ÊQ½¼ª-xNép¶¡dÄîáˆËq¼)YPî�RƒúµïûÒÁe¢ ~°~¸!¤}Ôîìv?Œ§Î°6¨¬ID°Þ3úÀ@Ï$;C é~|´Ì0fʲ33ß�� �IDAT s£ù#@ÜBÒ*½VÛP¬ †ÙcR¯ìs°°P§kù5…€€2‹õqÑ´Wä¸ÎDR¦áI.ÌÍs²| ¥TbYõ£F}ôÑÓ¦M{ÿý÷ï¸ãŽâÚµY¢´j‡´`1ˆƒiÓ…ƒ† n,,©¬ÿ èƒk>5XÌ$£vâì‹I#íàÁ”Ÿ6ˆŠN›.Œª)R ’ó1érqyÊö_lB‚7ŽR Ŧ,Aš„%Ò%}éîî–­b€±T*­^½º··W®Z {ɯ€¨¿¿_ŽU� ªKa$ÏËRM¸K<òˆûÈ#ý¯¼‚JKÕÕ©T¼×^îŸÿut`Ö^¶,úÖ·Â04×­3â8Þ´IM™b|ûÛI]¹lY’$©³ÏŽr¹pÚ´¤XtÊe»^IzÇi–fÍÇÒ -°('ÓDÁÇÏ d%$”ZoXZ­x8ZšÖ"ö 7™ø1q|„$=üŒ5´ÝøøJ¡o–—ô¯Å)E fÜÍfÍ �q b`ví¥Á^C«Ò5ðÞ`0š)[¼â™IÅ`+SáQ4Òý —šN§Yà–±uÍæÎÜÕj=yqã0îíí]½zõúõ둌›¦ÙÜÜlÛöºuë°‘¯±){W³V&Ã÷H«Á<â‡|xÓÃ@&d m€Q Íã"IÞ…ã×øWétZIÜ#?žÒÒ Î*8·e@^{<ÑÌzûÜg'S–%ÖZÜ(J‚ ,(+ļ‹Åbgg§‡À÷Ä`ÕÕÕ…aØÞÞ.¤mîÙÀ—“Á(L:ãUʧsÍÇqRWW>唤XL¦NMÝxcT( ¬ŠÍ›«--†a==–aØå²oš~K‹åºÆªUiY&ï°CQ±èP“g¹@øåòhäq„hæì2€„�Á„Of¸h"ÐP8䈄eÏ]^HrÀÃóp„±6üG$R´ÉMþ#@yåÄ•„6AÂy‡Œ³ÏË(2Ú’‹Ü�Ӹ夑P…©®åµ¡ÍsšgÍ´Ñ9á8qtPdà†Í&q„…´šVñÄ+˜ß(é^¶¬‰Q4º£ãÙgŸ}çw6oÞÜÙÙyuÞîºÂŽÅœ)Â.xÔª6[.—¥3Œç‰©LÖWd‹Éç™D1‰§Ú”¦̧µ"ö¡`±yA|ÓÒESÀšÆPíáï0c!lŒQìrõ†F„o芨ÑHQÓT*•ÞÞÞ|>× ¸pÊT™TfxƒÈ²€•"¾§§§··&¨!4Ç3ªˆõà.#Ø">[­s禾ø¢8{¶Êfbq ±qøá™t§ÿ©§×M¦NU…‚wë­ñ”)ÅsÏõÜ0 §»Û¼ñÆòu×™--ÕÖV¢".� vJ½ÅnrÈ$xnø¤]ñ¢ý™ç©HLŠfœÕ`{lEc§€XXššÏl¶ü9r†íKB¹mÛ^M€}mÛ�]VÔ¶|–àMË&D³š{ LtÆòâî«5ËzESE O_â"y¢Y0Ž ˜ÅajƒxG8Nx;ijcIèú ÁO6?¢†,€&7âû¾2Œ6Û®šæ½•Ê©ëÖ7lðÂðÞjÕI’wL3Šã 6�?a”Ÿ§ÊAEç c@Ú¸ 0"N½±ÅNç({&± â¸ÀëÚðÛîÉoXãd‹‘…!€‰†º€6 Ú#$ÌLÙ:R)…Q!”éXc�–;íTÃÔìžg¿ø9ø¾¿yófß÷ëêê`±#ϧR©À%ä+©TJ€Ç1ÿžKpÙ>.ÃâÁ<œ,<üs´ˆŒjÕþì3×óʦi™¦YÚUÈÕ”ò}? “$LÓ¬<õ”5c†ª 0àNQ—ƒâ·r�³žç =è·üAJ=¤t¸N©ùÔeGj!ω�ç%(¦¡B‹Ý¡qýñ¸$±9r†¿ÄáÆ©†§3Š¢)Þsüb¾2ÓÞ2™ s°´ÑKE“ÌŠfQ+ÀMGÕÄÖ €À/8Nœ‡:`J«†âP4°Æ–µœÇÚÃAólQ¤´Øü,¾Àš†Ž)¥¶Š¢—l{Y*õA¿ì°«<oµaàûº®Ìâ\d5n¤ÌìÇzÏhá2(¤h”ß/;øj8ÛPoo”kL‹`^@yˆ¬˜"q\Î]Ì[€¼ÎS· ¾k ˆI’7@Vž’$€@qœ D`¹eür”>²Œ¥ãd \snYW«Õ®®®B¡Ï祵#‹6—Ë¥R)PªPù¥R)þ) ===‚µBA‡ÉÜpÁAÁŠ]Àµ87Q õà¼÷žÌ1‘e%+VäÇš:µ; ÍeËì÷ß?^)e/_n†a¸fMüµ¯•:*Éf½?¶,Ëü÷¿“cŽQQd—JI{;2 Õ‚õI'‰­Í¹ ÛP­³ÈÍZ–Fe4‹ì1j¢jº8Œa`®ƒ¡Wü—ýˆÆ!Б#gЗT!Œƒk#ÙS5!?fÓââi/t¶¿²ç! šä¹˜VaÁ1f*ÃJ–ë>Û4  „l,2Ž2 š+2–Vƒ=xÄZîònÌÆY%1­äVØ„<õmYV[-°í a˜(u™ã Üf’L6Œ5©ÔGŽcÕfV˜Å 5T“  K L‰M6¡OÃê8,ß)A–]ï$V`”´å?IEfXB,XÇ19!Þ⥰¤ Î<Më‡.šÉ[:d4­‚{”Ò Š¥ò~†å 梄…®-ƒP4?/&¹ÙlVD8y’’KÒp!ž …¾¾>Éc˜^%¯•ùi¬<‹¸,寢TíöÛñdrþsé'?‰âؽýö¨«Ë7N`»ÔÕWû'Ÿ¬ #sÛmf›~e³Ñž{&î]wùa˜úÂsÎQ¶íÌk­^SÄÇa #T~ȧťœ²L*aª4æ±8OÒ¹¸Fdc ·CY�å$<l™ÆÚð økÕ˜Çlb†:ƒÕþUM: s j°b1ë(YØï S„Æ*ß×J"EþÖÚé…®ø¨~p…@Û ‘bÖ¼œ� ‚°à¬Ð…Þ�r1°t†Ú³C`CC-ËêRêoé4ôð9¡ÃСò yL5qI3̆D²N4ðq8q §ÈC…UàQvðä œÞâ8ѤºÔàiAœ(LФ²%RÈ N}gã‰"Lõâeq`b-T\­örQXðtªRJ„� އ|ð^º»»å’Äê©X,‹Eˆˆ¬† ¬p£,±µÂ‹çü *ò£J?ùd\#ƒE½½©[nàm+•þôS7”eE}}ò}öƒ0TJ¹o¿m½÷ãÛö-·È‰ÔðU¶À¾Fo[žMÇq¢À LÍÈP¸Ã·SÛ,ØÊœVkóUò¡uuu‡zh6›}î¹ç:::¾RFräÈŽé$vå¼h£ÌÚh±Ö`g³)v<C 0—Ëeôd BÄ;n;!‚à NMÍ0K}hß—6/z<Hº‡0Ëa ^× jB„RØ}¿ ?…M2t’!ý‹†ŠKÎʱ?9-š¼Ë¤Í%�¼B‘cêGòþƒútDˆi8kk*²F dTºÕVV{ûUãvˆ ÃoksúûåžÀ¶ÛÆ–¥zzÌîn¥T’ÏGÍ͆Rjùò <iRœJ©ž«£"á"kH#«èš ÄQdÅÚBŸòÁ±Dÿ\&F‹ÅbGGž6Ü1ðk>ë–BeœÇ ˜†ê³4�ä%'·, },hzjíI>Õø=»®ˆ,׬û^ó È8rmÖÕ„µØ}G^†ç£vä($à*r,ˆfá÷ø¾¿~ýúl6Ë\íáý9r1ëQ¨šm;RxÄzÌ3ï];Ö‹Õ„Ç…Ì¨Š»/¬|ŽÃ Í(eXÏMÓæœ cßÀUäPáž“Ü,æIyÆi` Öÿ—ýÃ|þ€TÄ9Ÿäì2‹ÐhŽ),—«HŸ2û8çp°i8äPX@<RTfâ °‰‚ORð4Ee€ÎÏDn¼é …ñÌ 5¸Ô…¤ ü}ö Ï??sÌ1~[›eYþ~ûÅ'd¸®±l™÷è£ñ† ê®ûïΜ©,+XºÔ¾ï¾Ø÷ý“OŽvÙE)e=ö˜ýê«Á{TgÌ0ÔÚµ©‡rÖ¬J>”ׄ uZME©:Ò~þš k¾ ñc³<G…á@¬4Ê/T Dvè"£’‹×Š!¤}Rd¨Šë—es ,0_¤Ç©Ê ÁeÐܹYËH)ò-¹xL ½}<pÀÂ-V>NÎ\‰ÈjÀ·MþE‹Y–U.—A•dLuäÈÎBGDàAN =Êlf VÕ‰‘kczÁ X6¦"P.°Ì À#Pd†Èu h»\] CÃ¥‚ˆ"gl `èPŽA¨â9$N€b¸ßƒ-‡Ò±O2_ç, Ýþav¦a·4Û`ò†šlh³ I³šæAwÄJviDXÑ:jŠÄ“�Xi¥*Ÿ7ì‰izž9~¼¥gÃÃ0¸ðºŸýÌèꊾùM öò4*³fåO<Q‹þ7¿;Ž=qb8ujÝYg%IÒÿÊ+êÕW£\.õ§?Ùå“Oö÷ÛÏ^³†kî/‚mˆó›…“E‚–y+Š, û°ŸX î³V&(ø¤šä‚‰;=}•ER%P,ö¨EQk,{æe— öÖTäåÊú:LÓÇ®gÄ•‹oÏì4Ϩ8jzž£:‘Ú{¼ÞðR ÚŽÏ…íºh œŽ£ñ+ŠÿßEڑÆ{ƒ<ƒ•ÄÇ�»khí85à‡kg”Jà @GB3c*Òa¥ì"îØ#Fh³ë(ðEµë\[Îd¡sÌ&¼…ÄJ•àN²á5tÉ&*-RYeÚ´çypÔ�÷g2ùP œÅ€)XÌ"«T*(:Y ä:ÖÅA‰j¬k¶?î¶–´4pêðH#»£bdRî‘ùøh{íÚÔm·_~Éù9aBÿ¼yá¸qÑêÕ[ž³a„'öÏ›75%­­Q­tCvì½ùfª§GM™’l»­û ŸŠ9xøÏ!èÓ¤Ì4ï4{°H´ir�AiA†‡\MŽ,04¯Ã„Hó¹ÀÅhÒ!˜Lç/ì>,ô¥œ•e†{H,WN8Íð‰quÖèÃ`,nóQý:š#…#Eì¡j~ŒöãØ½‰û2„…`í¿Xc£= UìÌp‹%ƒTéëä&Â>AÆ;ätàÈ"ù•œNù@}©M a¸â)q|dµEуŽãºnC’œW,~+Šþcš—d³ýÙ¬ì™ú(:·«ë•Ê*Û¾<›mK’“äúÞÞD©{<o®çeâø”bqz¹Üogg³jû£B¬èäÌ-±Ô  Ô8  ÜgÆcì#»Å(Ž.èv#—GÒ-ŸŽ6>ž­œ‹€%Ê�[Ó´Iä—@'†õßxñÈÄ>ÏNa‘à<çÕ0M˶Aµè¿üòºþ°tÑEjãÆèÍ7�}¥*—]–9î¸Ê¥—&­­æ‡&óæõ¿òŠ@–5AKKù¢‹r¿úU\.ǵ¸Æ“!æÈÍ  ©7r& á¢JI ðͰáTÄ£`ÜHǔƷĉ%3ÀM"–Æ v`ÕñTŠüB™f‹¢(ÚgŸêè^}uÒÓÃ~ê@h¥'IQ¥ÓiEÂNàòqÇ ŸÊ²hYkÏB4³å^0º Ùóâ0ÐÆ:³�*°ý™a/ÌRcÐdGªœÿ×_Œ8ñø$–³J˜ÇÉI½ ‚ÁîPv”¤À•dùHMÏ•ý$í’ÿ¿Vä΂ä‘õăþ±üÕù¾ÿ½0´k´[½”NÚØxg&3«vÍI’[,~â8‡55=œNŸ]*%Ir]GÇ¡‡64êûãÃpBµú¥i~§©éŒºº¿ÖŒ7†Z:² «fa¶�;á9æÐ9S°¿àß̵(€Øvš‰a€ÎP5‘G  I2`©ÂFךî€FBÉÅ}fÍÆ”Ë&¬ ¾¢BÆSª¦iY–iÞgÄ…‚œ%xȉRÞé§Ç…‚aY©tÚ2ŒôsÏå>¸þàƒUÆq\Þm·þ3ϬûùÏãrò'ZËZ;H_ì� uÐðXR¸.H}¬y#1N(j,Â&OÒqœL&“ÉdxªúC¼­˜ÑŽR’‘1qÊš\€œm’“EävXê±ÇüÓO››e/Ct 2K€1 “! ŒK@×uE%åiH&ÔÜÜ\__/· ò›/hÂB¨QpñlÕróë°ÍåFv‹´FÖ3SKcŒí†Gªœac¬¡¦ÖpyÄ À8˜ìÅin$w5Mf!ûÃÔ‹¢O¶qZ;s„BB*ùKvÂÆäNùþ9¹ÜO|_…¡lûW Ã4 3 ôýg\W*ŒaU iJY–õ@.÷‡B!Qj‰m÷Úv«i.UÊ4ÍŸ”˦Óhcס\@Ô@^ÌÝTŠ,ÅÍ!›{Áå€ ²¹/÷rÔÁ'æ'Ÿ ¨ÝœrJ¼Ë.ö²eÞƒ2›68õÔxêTsÉçÁƒ Hššü‹/6M3u÷ÝÑêÕ ~TÏ9ǹùf4‡)ß »�ÝvQƒÃ1º’4a4ѼÂ)\>íy±äJJ9Žã[–" GEØ©išVKKiï½'ž0M3QªZ­ú'žè>ø ìƒ-¤›»‰,b—0N‰8ÃÀ ªn¡V`34и‘6áDÇ»9˜Wü²ƒ"/}˜ïÀLÎ(Š‚ï|Gí²‹ûÇ?ÚIby^ùœsÌ?þÑ ÉTEŠÌlp²â,‘eìyžØÿh]:•JÅó<‘µÅß ± �10ㆰ4ž=ÚH\`#Ê]I¾H)•4]ó‘*gxær¶°-Ï<3Úc¼ãòu×,¨Ìš…L!•J…¿úUé…äÁá‡Û¶m¿}qÁ‚â‚ñ¶Û°3/¼°þüÒ 7ÈI&p°¤-’ðj´`Áa5À׋©lŒly÷ ¯$1k¶óþZ(ÌvÝw=$–yéôžaølw÷5ýý²ˆ÷©VŸñ¼ºî„8ÎÖbÓï …Ïr¹—³YM© ÝWÖ e€Ý@ä™�_FÔþJ ­×ŠH¥Ó¥^(ÜtS´Í6ÁhƌIJ¬9sb̜߯‰ùðÊÌ™A¥bÏkº® J©àúëݧŸ¶çέ\xaäyòdünO:i(o[ß•ôY 0Ë%dHÔàh‹P.m0®Äë9r"PV*•Â0Lýö·¥ûîë}§Çüè£xâDÿw¿³mÛ›5«<{vqÁcÓ&sÉ’¤§'5ª¸`AÿüùésÏUJÅIRùÛßúž¾üâ‹ñá‡3½ .mÒ ­ V#\) IΘtŽm a¬Ip”5ŸÍfE›•XÑ`Gy¡éëh-%`ª8Y¸9ßq'ï¾{ö¡‡2¦éy^jÑ"çñÇËù‹´—á'ÃV›|`£Ž ðT*I¡€n ¨ž¶¯ N;�ò`ƒÖq.u}}½ö^Ø@R<×P]õÆ'¬>MÏ‘*gÐycÛ¶1qbßÃ'&¸§žšišþUWO?»ä’êA•>Ú™3g@TãöÛS÷Þ[5ŒÊŒÊu]×í¹í¶Ìôé†açÍËvXtì±öŠîí·ûî[ýì‹/f›N Àƒ2�M\t´L TÔUReChKb«fL ‰²8ŽÓ˜$U«÷æóŸ)åÔÀ.Ó4Ûlûªúz×¶wïëûvµjšæŽAð~]]E?«Tì0lH¥N-_7Œ·,KÕö¼füŽ¢y´ü˜\ÞPeýÌ— ª:cjð £RÊ,—³Gåÿò—8ùªãÇ_|atvš Úë×oáòmµ•ñÎ;ª³3þ׿œ£(Š·ßÞz÷]Ó4ƒK/U¶mFù÷¿wŸ{.üŸÿA’ËͶ€Ðˆò@¿Bò}éÍ ¥3…L>1=cFþñ²eΉ'FQ¤ÂÐ1MU.{7ßFòÉ' 'ž(£@aÄqlßq‡û÷¿J%•Jbšé_ÿÚtœïË(J¨í/·ƒˆÐ&CdÌ„3Zèà!õÆ+FÕÆlëëë;ì°ñãÇ¿ôÒKŸþ9{¥³/€&irH¶!l~ž‰Æà$>Ò™0‹ò}?jn.sLúškŒÞÞÆ¦¦$Iz{{ÝåË£'Ÿ ®¸"uÍ5¸YÃ02™Œ ärhÛhvãòg©É˜}–#ÏK°Dú*•BpR (¯=Z ;á" §&Û¡Ø’ãMòU©Tøí9ì ëÖ¥¿õ­Ê•WŠòŠÌšAàu”¹n3¾iÛ’Ûš¦©âØÚeµÓNæ­·*ÏSŽcT«ö’$±ŸzÊ4Íêᇭ/FÖi;±få(fû0 hÃ; à£g«Éš Ôql$‰œ.ÓÃpe*µ¤†qI M§ÓSâ¸딊-KÉâ®=e{ì†é0|-“q¾i–ïÀmx0g Bv’$áw¿ë,X0мmjŠ?<Šc{þ|»«k‹;}ssåC’8¶ž{Îèé‘O¬z¨û ‰B&ãw\¼ë®æªU[(�rˆQ*?n}úé˜åCü\ÎèëS>jþ¹õæ›þŒ†aÄcÇÆq¬&O6Â0imEÅ~ÀìP€ @ ö$……ž‚pŒv;oþ$IÌ p\Æ£~¥JÔ0MC©¨&Ï—Ë’‰ „›$IÊ外‰Û¶íW«Ê÷M×Udñ�ã>aÁóÁÜŒÄSH¼H0•!†‹[AÁ<,k)IíÂó•x8¬Ð/Øä ¿2­Ã$ ˜ гÄmmÞßÿvZüè£A¡ ?mZ²ï¾™«¯N¨Ü„œ¶*Œ>¥v³×âÖ=X08#åš!ÈÄ|>–ä'{{{Y ‰å0¸¡ZÈ‹ 1€ªÞìºÍï}äÈf` Ë4ãZònFpöÙΛo&[meØvüÚkÈPÂ0¬wœ3{¶�µæOT®»Î0ŒdâÄ-\Þ\.r]U­"©ÑðYžúDåðP2(‹òÒ¢'ƒÚÜo`VžÇÇT*;išï8μtú—åòsÛn;¾ZÝkõêt1ŽŸ÷¼T*u.w]¹œ(õ‰eu*åûþ´ ¨+-Ó\jY÷¥R8,YKßá‹gF©eYþ‘Gûíùüór¿ÕsÏ5×­K’¤|î¹î%—ˆ~pb¥sα7lHâ8¸à‚ÜÕW—öÚ+úþ÷Ã#ŽpvÚIQñì³Í¾¾Øqª3g¦Þ~[µµ)¥ÌLÆ»ä’pß}££¶—,‘H˜¦ò¼Ô¯zh|øáÆ_¤þüçhÆŒ8ŽÓ4ÇŽ-Ÿp‚5w®³jU¥†˜³H"?sœ¦PÒDRŒG?ƒ)é 5€ÇpfxYC£AS€e>=”÷X÷OÜÄ™'¦ï#fiºMìˆÊ# Bð˜ó°y¬¤P(¼øâ‹ŽãôõõA`(wSåSƒí6ªÕª¬ssði¡I²òlƒ¹x±™J•Ï8#¹öZU*ùßû^¸í¶™ë¯×$�°˜ÁÄa "ø³”"g, „ ” Ô‚¨iXž•o ƒ]vX É – ²&ÄBs¬Šd†ò/FŽœa8o¶ :äÁ¥ Ã[¸Ð½ÿþâÑG»îšzë-EFÁþûg/½Ôtœ(ŠR÷ߟì¼sÇÁ ›âÎî½wyútë©§X ´…Ñ[Éà@s3’ÙYØü²ªxþÀ¿j:¸žçý˲–ÔôÖ:lÛ¶íW<¯··w‘i¶Ö×7FQg,5MǶŸJ§—+¥”Z®Tw}`—Ö×Ë/ï«ÁJ’¢“‰drô£Ð!·?þX­_í½7�œ`ÿýÓDZ³ÛnýW¦ï·_îˆ#|ß7wÜÑ4M{Õ*õØcá·¾µÅ•`útï ƒT&S¹òÊ(›Mdàô¥—âÞÞ8Ž“Zš90–8~R*!#Vå²}Ï=aÓ§GuuÁi§EF¼Ãþo›úÓŸXæK Å’‹Ä„ ° ÈIHv‰Ü#‡h�è£QŒI:" )$§È¸q’ál1§[¢)’EÆÍÈž–~ñЫ«°Ø„" %I¨ïr& œ ±%Žã®®.ÔˆÑX´ìÂ{âÁ– *ÝÌØÔ¶³ ÏBu‹?ø êìì»î:û¡‡ŒwtïºË¬ÄñÛ‘¢?·R©-æÔ©!‡üM>„Ô`¡B@‚¬O(åˆöé)Å7%!CzÁ8n;1àÁW2¢$ý_DZÐH³fðG‘µlYEI-rÉ@V†Ñ6Û+Wn ;Öþàƒ$IT±Çqpúéf¹l<ú(ë ð&« gÍct¡1·Ïãc€ XRâ‰2§©j‹›MS†P¿6)µÉ¶aÖ™øþÇQdwvš¦Ù- ²R‘�ë¦ù‘ç ˜!A_ü[DA</ øFÊ”Ç2@HQ–j“[€2 kÖX«W+røVétôóŸû3fØ×\“^¹r@„ßq"ÏëûéO«Ççýñá_8ææÍ~¥])÷¼ó³Q{'�� �IDAT ¯½¦ÆŽM]q…Z¿Þ¶í¨½=¬«³vÝ55JmÚ”$‰¹ãŽá矇ëÖY£FE»ìb46&›6APþûßSù‹ešvWWüÅõS¦H øòËÖ5×Ĥ6Yå'å•É>!qI8(ݪU¼nÖ˜”ˆ÷(5<%ÀžèÉÉÈu]Ìv0Ø… yô…¨„Ø-·‚ó q¬bLDb%Dq°˜QÓÈp ®L}ž6…´—XÊŒ�ÄV± FJÎn°(&iã«\É…ah._î^yepæ™é«®J¢HÕ”Èù~YšÇTT„])œ÷ ¯‰ý¨UŠšj'l6#@Þ)»^vñ p‚ 8e²V;H eŽ‹$D�àÃiG„oÜjê^ì~ôQ¸Ûn•™3Í–{Ù2Çq¢éÓ¥SºãŽÔg€Büìg•™3ý“N²Þ}×0 kåÊ`ôèêí¹§»x1¦©ABÃ&wkh;"a<gÔâÜç*y%v5ˆ1ÄwÛ�ÁßÏKñÀ%¸b-¬'þ·ñ¨Qf±X7mZxñŘ3Oâ83Fµµe:¨ò»ß1×пñÆÜAeÎ=78õÔhܸ8ŽTétpÖYæ¨QÎ=÷†{¬iš©ûîSñÙgGŽcýýï–e¥.¸À?óÌÊg¤®½Ö*•ÂJÅ/•TºÏ?oÖÐ0”¥RIb‚ ž0ÒxšÙÁ’Ò²l4Ki Ö’Ê@ÐiúÈOËå²"žàðÃåw²TXøLÁ‚«ÈTÚ`7…c& `nJ{žÇ¶œYcÞó+ àicËòÛ4-WçþñPê&ƒxLÄGIJf oIŽ 2³µÕ½ì²¸V—3ÀÀZ½x¿1§DT~áí³ù\´«å®­4¨°fÐÙ’ù0EÒ8UÆyÃkž;©È„ðvlÛ–!Vvx‚ö(FAGªœaÖ¸éÍŸ¯Ö­Pvš3ÇÿîwI“¬?4^{-1ŒÄ²dl%uóÍ*Š’Zä]}øýï'I’ºîº(Ь×_7|?ž2ÅÛ°Á|æ™(Ðêµ9pìaxª9Iƒ;Äæ(j°G2z ܺgj¦4uy8‡"äa„ë‚ñX L<\ÊMF´Áãd·›As|µt;Žc£µÕ|è¡„Txã86,ËøòK÷‰'”i*jT€dÛ¶0¬_´/Njqл÷Þërѵ×&Âa½õV)^¨>==Vê†H-?¯‹µ€)  ¶|eð·,<Šî)–â601¾A,nD'IâŸsNEÕO´~˜'g5ñ:v BÙe:‘¡³¶&çAoamM’�åÛX04'¬q!^óˆ8oœia’:Š"ÁÄøgâr‡5¼…·‰³–%þÀÍc;�ôØY<B~LN,.€XúÌ¢¾ÁLqvÐ�ÑQ 6êEw–qiÁ0!da4Öç•ÚKCÌ´3 ]”;lq;rä 'IRKI’ï½ç8Nˆñþgž±iÌÓþç?…rj?óLǪf:utXwÝ5ÐD•‚ã7Œ… ÝtºBºjPÍ@ž�ÔÎ&¤¬=Ì20Œ hòÒhu‚|…ˆ pö.%-•ÿjH4´>!¤ 0¬ÉÍžZŠä ®ª;‚ 0j #E–a˜5-HU‹¶œJ¬Åy溮AÚø°àr~30ÿö=À  i9/\·ch–he#þJ‚) :2¾Ã�kšD¾‰#¡ò³ŸÅë×;Ï?ÌœYùþ÷9sP\²<+Ó™4ékßXZ³JÞ |r 6Œ¾Ã‡Ô¶íL&#Ï_V”#xæT~³ gÐÒÅ:‘‚[×gN l‡¤½!w Ù.¤´òˆÝoÙ‡MÙ ’üAoŠíšä70‘û†78нÔ† § ö¸x. pþeFSØF’S™‘#g˜9VmRi;úÀL<h®k¸2´Š<BðßAƒcü ëAá aitM`¿›^ë¨ä7Hh@öÝ Çq®ïêúFV £9I&D‘Rªh«l;I’‰q¼Û˜1ЦÁyó(ÒÊÕZMÐ.T5ëä_ضmË–Iœµ,+÷óŸ_]†wÆI’DGm)å.Xž}v÷ /(¥Ò?ý©\pÇæòå²çƒ Èydáµ×’$I]q…µvmT{8<þ;`Ö†a˜N§(¡ Æ` 6 ÄJ*rââáÈzhjjÚ~ûí{zzÖ¬YS,åá—J%øV`lž½´¹å‹ƒ?#NÙ¶­R©òltv¦æÎM’Ľçÿ—¿TÇïÏ™ãÔÔt@Ü`® 2Má‘¡?¦EÉ�‡æ¬ƒi|SÀ:°Ã5EÚn()ˆƒ+aÇðÒRd±ŠÆ“Xhãkù×"±ÂAÒI§Ó ˱"†ìAˆ3±F¶0Ú)/äÁg5ذQ»qp¾5¡î¨ñKÁŽÀ^Áʰ†KBßNÊ&Èo°9r¶9lw‰Ê€�œê‘³ì´¬HI„:TðfÃ’‚à¤j íZû—Aø(âà ~ÉØçâ S__Ê?ëJý¢¾þëA0Î0&)ÇqA©•–õšiÞÕ߯C•èÉè¼ù©¢ bv÷Qs?ÿyRSuV¯ö¾ûÝ8Ó4Ÿ}Vv¾ùÙg™|1 FuÖYÒŽ ðÚÙY7mÚ�._Ëy¥D>Îh(gØç"� hžáײ°#ª×uëëë¿óïLŸ>}õêÕO>ùägŸ}†¬ŸßÒì~$·#€ˆìUòVÛ¶ 'œ`…¡ýØcbóS.—S·ÜâŸwž:öXã™g˜ŒÀ9µ"7Í^o“oP1šZ«%¸` Z õ6T(SœEbo ÞájÌ÷}ÑaãSžlã6¸¦0¦É°ÐjùÍ`rsTr2Æù¿PåÑy?ì`Âf ¬[#Û cÎL:WCô sú‹lFôÛ䙣^ļ‘Ì91²:rä ?¼ðšÓdÊÈs5oè%xžìÁµ-Î NŸ’ ¥Æb·`£ÊâcP^ vëá^‚teÅP¸žà’%IbV«¶Rç”Ëç55}’͆a8.I.ïìì¯É¼õf ¶žÌµCJËnTýýýlj‚ò nlÀýR©”ŒèK\ÃyÆš¬à�=yd¦ì …´Žu'“$Éd2ì;1´4UÙ…ÅÜ;Aà³m{Ô¨Qûì³Ïn»íÖÔÔôþûï/]º™&s®$-`X°ª´y-³¯ æ•Rét$1>Ÿ¸Ãó.VÞÂ-qÆu%A ïB‚ëB‚ŠÂC²¼)�ÀWE¤"9d˜?ñL Êœë8³!ÚÆmWÌác ’!Mnºàãx%sGŠ9oìÇí7~˜Lcã(ÖÐÓŽR–Y˜œ§¤9Œ “ŠƒS3ÙâÖZ*•’°#U5ØX1’qÔÆÚp6XÖMÞåäÉ“Óé4v¦4B£8Y‘õ›V±Ÿ×I²eãagºµ™s‰/²C ¸¬Ñê™Å/®V«³4¾¬0©ÚÚÚÚÛÛ-ËÊårr`Œñ¯}}'55}9~üÖ[o=nܸ®TêÒ††o†áDšpÜlj9þ d7AxE<…&áùùó³b¾v/#`Æž_àWÄü½-qljþò£¹Y‘  ¤ e‘$D IùÔ¹iuOOÏâÅ‹?ùä“E‹­^½Zôÿ9C—À*㙨œ ÓŒÓ]YrPC‰ãØ~ä‘P©ð„Š¥Roo¯aÁ¯~¥¾üÒyúi­ÛÄÃÌ.ÁrÕrj|.‹©«!c§ÊÊkfhÚÔšxhh'ʼnHB ¨¸X«/TVB}}½´4~A  æžP¦A¡ 830.Á´ñ.XóPÕÖ,…„Ǻ�8€7p¯H‘|œ¦Fo×¾ñãe’Þ�ÑÉó0H${°X,bá±uÚB_Y_ŽT9ì1ů¤Q¥R‰Ýslj&Mª^y¥yýõ©e˘h„=‰þ9Ú3@‡Øˆ Ÿ"1sD:ùBT ñTÇjæ"ç\ëÀN1J¢”Ú.ŠŠ'þàØc÷Ûo¿U«VÝsÏ=7nÌÇqj0%‰‘±¡ÃFüMè£àÓå¼a (OÁ‹Eîñâh‘vì*‚†¥w¦ØÂ€Ë4ͤ¾>8ûlïŸÿìýÃì+¯tÖ¬áÊY6Ó®84³Zj)I™ñ»çÌ™óÆo”J¥Í›7#ó…×+m3�Èm4]Êå2€¶˜7‡¡ûðÃåŸý¬tôÑæ3Ïø3g68O=…‘Å <p¸Q±¡Æ54³P}¢ –‘™³r$R²Yäw‚OÏ#Yœ Èš”Zy¨Ë2~€XÙÂ:«ZSëOÃ4�KS©T¹\–ô"]SCç©jÆ®å(’ç�ýœ{±Q3àÑîeY^Y0Ì!Ä_±Ð*`AÊK”.û ÃH]gœš=Ð9cvåH•3œ$é éZ Dc»¶··‹E8K†ÛmW=é¤Ôå—û?úQáßÀ:r%mÝhvÅl¢í7&>!#Ó½PkÏeƒ JÆœ)°”hÝëojjjhhÈçóZu£=gæ‘�$ƒ'3@äq¤Òˆ¤RÆ!7í‡ýÁ€¡#+Ǽ€ô½ðˆøâU6ëŸzª³x±ùî»é /LN;-Ú}wÌ4�¸G*hSËϰú/§ÿŒðÄqÜÛÛ»aÆÎÎNÔ7 ÷±ê‰¬»Ì²ÊÚDÈ€,˜ïo«¾õÖ ©É?í4£TrçÎåüÔ5¨d2hƒ$šÍ–P i@#³cyÅ£G7nœdhé¡„’4‚s/ˆîhpÛ¬¡bÖàkÑO§Óuuu’ÔfDΤ”"¥cG.ÖAŸ‘uõm¯1—SÏ,«!· [^èÓÙo”!æIÃ-©ç\_òY(ëP†`©E‘jÐÄÂÞ”“ º;ˆNÃå\0Råè£9BÔÁ@»H²Ì––Ê '¤fÏ6[[¿þµò“Ÿ(ÇqÞ}WúuÌbDæ‚�-J¤B�7à‡ˆþ6Ç/ÞÌÌ'ÖD£¹Í€lQ‹ã8ÿšJðå—¯½öÚúõëW­ZÕÖÖv@¥òE*µ+³Ë ã˜Hån0†NX—¸ÎUS_fuùÙå}÷5}ßzï=°-°bIn¹#æÚ¶]¹è"ë•W¬7Þ°'èíuï¿¿:c††ñ§Ÿ" –.4\M·PÅj¿Õ$ðLΠȹãðlë˜a¬Sun2)rýBÃLî4sçáGØÏ=§¨ÒÅ+Ð:O€VðXX>™c:7HÀQ>&I’Íf÷ÜsÏb±X©TÚÛÛ2‚7êZðÔ9v3hÉî;ÚeŠ#7G©ÁÓT˜Yá¼ 4w"°ãÃKÈDSþ`àü„å¥Ëžâ×Äöì$Â8“z°B˜›®g1¨Ž[¸6`XvJåf3êÚ‘#g˜Ïœ(@€Â¸ qÓéþk®I_rI¶«+ÓÜÜÖÖ–yøáêùçW»ºŒ%Kdµ§ÏC0’bðøïp6+ó<€2žGSƒ% P™i¾pÈéx·³¬�þðJ>ÿdG‡zó͇—-+‹;‹êìüó¨Q…Ú|ƒÁ.Ž,&Ï‘82ÚŠ|NY;O;›Í¶´´$»ïþÉ.»D®ktu+V MÐXv´(IK%¼–þÏÿqçÏ7ß|³.Ÿß~ûí[[[Û[[­‡.]v™{á…q?Ã0æº9qüKN€Z7«•Al–Êlc政bÅ0Úåàz ©®Yóæ5¹6\< !É3ðÝÅßbÚ—ÏT¹µt:ÍG,DYäî6mÚÔÓÓ#Ç*•]#ë.ãÜObI:Íù‡iX>�ë­T*qÖÅÎñÀ1U†“Ic™ƒVÀsþ,sÉʇLMd�ò'i8Ég ˆ¹Õ îï²Ñ5˜Ù8cÀ¾ãÂsà4Jí8lëðø-OY±(ÿÀÈ‘3ü½Œmco`< MW˲ú®½Ö½á£µ5¬ÉOÙ½½Æý÷/»,}òÉÈ#°^Y�s*X‚(ÿ=ÏK¥RÅbâ‰L”"‡\-”Jˆ\¬¡‹Î–/Ôüæ øZµúÃ|þؾ¾oܨ”úÌuÏnnVJ¹jr.ò¸» Œç oŒ€Ž)Bè-‚†êGȨQ£ö?çœwØá\°bÅŠÞ›n2o¸Á]±˜!Íq4g<$Iû7¿©Üw_¶£Ãëê7n\gggÒØX9å÷aèäó…BÅ>Œ.}evÂTf4·äÓS©xeŒe±ªÙ«È[@— B5l›„Ž3ø¹u@É-<ÿÈëGÒsþyl|>_*•d‡K1TZårù³Ï>Ã, ä\Á„´®j_@¢û­™•må¾àUÃ\^fPÒcŠœf˜4VøÁ8•y2I~L~9sâÙ‘YšÛH¸ <% 4T<€äÍ áG§›Úd³¨¥PÖÌC5šÉ·¬2rä 'c Œ0­YÞ½wî¹åßÿ>®¯_} K2¥zÌ1îï~';[”¡€ò, YF$Ô<ýÇÄ_Ï’ç‡x¤}Œ ñœº ]÷Að¿Qdšæ}™Œüó£úû-Ëz½–ðr-Âî¶ØçuuucÇŽíêêêììd†7Š!8dˆHx‘C³D~m÷{<’$GÜu×û}}I’¤ùËÊå—Góç«·ßÆŒ«ÏÉ¥:Žƒ¸°%”Ïšå_xa×üù¯¾újɲÊ?ý©õæ›îâÅ&Ov]wÍš5<胡ôcåûØäl–…áyE6t`±ãmjð?R© €È+¶åL‚;.ªçŽ”Yn<îš`&—³.ÈèÉ‹@ÓQ~!ðO TìËð€¤8îLæåš$I.—®{Ksþ'Ñ5�+ª¢E/ÍÔb±U”b¹&n¬Ê-3Av™¼M&Æ:vŇú˜9¨ìFÓWN8@m²[x¸‡Áj­!'ÝGˆ‰°^5.U³@a¬ ó[²è-"Î 7„§ŸEQôúëö6ÛT~ðã¬õëãÁs�¬b‰¾³SÀÖú½òM´‹é`,IÌr OdM„NTèP {ÜqwArX»Eö†P*0IÎ3F`%É>oll,‹¨Z˜£9yàLB&ÈåÚ@\8ðÀ®vhºþú…01 ÷æ›ý“OVQ¤.ÔüxX’:yÚN¡`ÜsOÿ‰'z…Bå?°^xÁzãJ·µµÉæÄèxÇåsÏÍÜy§Y­Ê»+ß|³²mwölëµ×w›¦YºõÖ$IÜGµÞ|Ó0ŒðÀ«Ç¯Â0{Þy` Ûl“ì±Gê©§x‚É/M´A¦x bà Ç,QÌ=&}pŸ€•op›x)솓ŒwmfµVdEêa³K¬sv<d†j�J€<Ö¦¹/ËdwÀ! Ì{œ4år™oÕɘÇ-&߃SƒµBŠ6‡Ä§_*2zŠÜ°˜E­Ý¬†Ç2†‚•Å @ZÄÙ+ˆãO®ŽÎÿŸkT½ª$Q•ŠªT%›aÆQ”sœT’¨Z*äY–g{ ;+ÕÝ»÷^ãàƒã=ö(]u•}ûíæŠIZ GÑà;„Bîµ0~Åž"šï23ÐÒÒ'\XP¢1œ"ƒ–r’ñ*‡Ìód@™ƒ^&=e‡c¡ËU …¥K—vttà›�¾ðlÑ’Ý(b·ÙTnÜ4MõñÇQcc!Ÿ/•J…Ba LoµUœN«Ï?ÇÓãF„6æ>aÎ\­[çÝõ¬³ÔO8o¾)ÝÝþþþîînÙÌÕj5<øàòÂ…Á¬YF ¬«Ü}·yûíî-·„Ó¦ES§"î¹'õ·¿yû[<}z²ýöÑÎ;‡’½ãï¾ûJwÜ1@xõÙ{Ó0;«*í?Ó9§Î©J*#ƒ!€$(´Ê¨À H2¼í„­‚­8144à ¨h@@QP[@! 2ˆD†’ÌSMg~žçÿaÕùå®]~í®¾®Õ/L*ç<ÃÞ{­u¯{Ý÷”æÝw燦L?í ÚóÑ5ƒÆ6$+š*kÍ \£…53ÿÚP½¾VÍx8¹XÉ–ˆ è¥šr EÙ 1 †s9sŽuZa4 WV#jïLÔibU½^7I!»YÛ)¶¼8Çqww7ºDö^oÉnœNx”^¡íû‡hžê~Q鞤­v¼Õl6›6B‡ª¡Â-8¡Ðë—&˜1E>Á2?„Ì©çÉxÈùïùY·Î=ñ„;ì°]2¾;ñDwâ‰îÎ;$ïÇ×ë¿éë»¯ÑøX†y¾[~¹ÙüíààµÚlç‚ 88ÏßjÝ·qã¿}ùË¥sÎ)Ÿ{n´i“6BùQØš: aG[jÞ>TÔØcªh† \†> ëè³ÑNô¤gmÏ6²»äŒT'À€J³`` iµ/5mC ìÈ`GéÜ;#&�Ùè6B¦0«Õî+®¨æ3ýûî»sçÎ,ËÒ·¾µuöÙ®¹¦Ð™‘‚fÔON@(ÅÊÃô¡Í›‹ŸýlqáBŽlµþŒ¢(™?â 'D/¼�̕Μ¯_ßîî.Üzk²lý€tß}£µkƒI“Jßþv¾lYZ(d…B¶paºhQº÷Þv ý÷ÜSºàã·@ž7:@‚@pÈžÓ‚*ïoñÒnÉ%MP ªk†"HªùÙÚ.†ñ)Mä)Ùí)™ „=y¥{©1‡Ý2¾ÈîQpcOg È�Û&4Yól+m¡‘²¿À¾ §3¸jb7W ¹+I‡C÷@iTùê⣽Öm©T²EËl c õzæã«öê @C̆ZªZ­ yP¡íkpìz½^­VU‹vXûïüY²ÄÝwŸ«VwýÉóÏ»ÇwιÓNs§Ÿî:*ëWT«Ç”JQÝ[«ý¡«ëøv{kžŸÚÓ³–ýÛÐп”Jok4Î*—Ó0¼¶Z=äsŸ{NFˆGs”µœwbƒa™‘m'Õ+S‘[=tA¼P;tOÍÎ<Ne *‚lmOv,,Ro<M7˜¶guTçàz^°Ýhi£žŒªO5\ ~ýŠ+¢‰Ó0ÌŽ;®|ñÅm‘pV±ÅÑ3}P`úz_Þ”ŒjÛ´Z­¸Óçh~ân·ÝÛ·GwÜmÙ2Ü Éóƹ离ílÛÞ~{¸ysº}{íSŸÊ:ECû„¢‡}1„p8çd'„ت µCRÚ�‘±< gå%ë ¢JùéÕzÝ;#”.Y¢ÚóÈÊöºGw¹Uù ÓXo¿xv¥ YóÐô!“3Ù!®BH¸‘’ &ðA¶d ™ªŸ©Ð›Ô‰¬§Ú˜t“’Å)žha²ühñR£(ͯ9Ñ»râÏ +ÝðF…òHàŒ^HÒƒòÂ8°ößùsÒIܤI»þäâ‹sî7¿q'žè&LPå¢Ñn*ówk¡0¹Õºmhh½s¯v’>•¶%Å€®Ãœ&²ž°�TÍ…¼Iä•|Å*'&Q—PI(%š î¤üÝNÌ6S—¸Î(;,KÊ(ÌUj̰ vµÎÊ€±¨á·A`ߥ¸Þj•¿ûÝ쨣‚·¾µpóÍv¢'O×áS'ƒ½œw¦TcXGA½PæXsñ+¯”.»Ìí¶[°ï¾#z°‹—.»,Ÿ93Ûchݺâ¯~÷÷‡†œsíNÈ>8¼þzs¶,ž‚Rh¼yæoúx9ÐᒨЎúèpâÐpR uäÔtAí/‰1¤/œežÛ1æÞh½Î´*›$–E w‘_³RÕ³MÓ´À“Iæqéÿz)HZÊåò„  ôØCú]\³öZl÷Z)< Œ*ÈÉ`WZ®c¢t‘ì4>Ñhl'"ŠQ^Ó,À 줣˜JaW9ÿs“8nÞ<·l™ûÂ\©Ä¹ÿÅ®®G]ì—¦aÅÎ…ív­f3ïhà÷9w}~¼Õš;GäX_0*¨|M„_ÛjµÊå2jÁ(©Ð8õ:@Þà½ÂwTîžW;ÜÆØÿd‘œn:“DÒ-§ÊÙÐoÀF8^­`Ò¦¨ •Úçxò¯`sí:ý7oN~ðƒÐ970Ð̲$Ï…ÜS± m½ª:B^^ÊωƒòÁ)ê¾ ?lã–Nh¸Î¹èÁŸà\yãFwÏ=Õ4 Î>;Ûwßæ?ÿs~æ™AOO>qbáO*<òò^ÎN$Ž*•¨“ޤYtw»$ÉÕk5+•ìVÃ8Œì[*¹$‰Ó4o4ìÔK;³ÝΤPþˆ¾V’ñÑȾZÿyò?€H<UÊGÏSNgõjá\™ ýmV…)—!ãÀ Ç*lherlaT*3xö6T•µÅo*Š Ó,ôvlUeˆÙE–J¥©S§FQ´~ýz†x0wâ§#ÆöQ&ÉCÛf4•IÇÈÈeU7‹ìD/Øó@9ÿ#?óæ¹GqW]¥ÕL†‰¢ã*•8ŽïÈÒ´Ñh¤Æ¾MSó;$Ë…áò(Šné¯pª"D¨µ6yï¼c‹²¯TâÐ$• õëÐ äÄÖ<Þ½l´ÖFsÌê” ¹¹BÍûXâ•JE(,täàg“$ c­Q-�� �IDATƒÚA<x&6‘`Ÿo=juÎÞEgع3øcTªúZÚË%+çÃëõ&ý¶KèÙÙ^w¸#^´(=òȬÙ̇†Ò;ób1Þ{ïpåÊè…‚㎠‚ ªVãf38è Ò…&>XÛ¾=\¸0úÞ÷’ï|'ŽãüÿüŸìÝïz¨Õé^À×P*A6cF¸Ï>ƒ×\SyÛÛ†ãî;ß9pÑEAÄwÝUøå/ókð…ÂW^1ø¬tæ™aooãóŸovX°eKqΜä•Wò7¿¹1gN+Âûïo¿=ô*H{æ–ôxa&I³M#O²4\É Ìiz½hÅÓ ö:±mö(‘:@¦’Ì6èC#ʸjVi•æ:zá&s`x£)’kªT*U«UÄ=b”QÛ”Ƽý-5J€­®Í3U=ì°ÃJ¥Ò¼yól„À’¯]§LàG¢HÇÖˆeÑÂGÐ4ÔS¦w2=j[CÓÇñ*çöçK_rÏ<ウiúvûžrÙ98×6ý>4<‚ ÃkO/—­ ÛNÓ\hÍÞ 1ÂìÍêq”Al ãu,uSªv2ôÎ`»yŽp̺:ux|M%pÛ'Ðx¤ÃP‚ÓF Ÿ¶t0…ûò´Ü cÔ[ú(Fç_°ª¼Ù#ý5'òõ÷šV¼ÊxRTY–%¿ùMœe-çò</]rIý«_uq\º÷ÞxÕªl=Òƒv+WÏ?¿öoAÐõÛß«V…a8ô³Ÿ ¾ë]®Ý.^|qšeöãuë’'ŸÔDU[ÊÔsÙþû·ÞùμX¤Z­ùË•ãã¸öÑ&år«¯ox­__>å²Úæ;Þá6l¨œvZzÐA­‹/Ž>ó™¡ë®›xÚii³Ù¸é¦ðÀK‹Áæàf5›FÆkhé >s¯‡§ÓÁ*´¡~eÔ.”à:õ ³yØZ·“qšf)cBç™M"ESºÙõzÝifÙhQ©Ê Ê>U*Q)qÕie"¸Ùl>ñÄaÚt3@Ú0ÓnÔ8(?Y}fH²N1€¥1’ê‡ÎP­VcðcXûÿÙ±Ã}øÃÃÿ}ÛmoIÓSšÍûâØeÙ÷²,û}5Âðiç>ÚjÝ^­VÃðŽb1MÓoÄñw —¦/EÑËywW÷òÖ=ïzh<vnÚŠW/EHÏä_VK5FSÑ•À¦È†˜ ²?Ô)^íÞ—J%�z@míÊpp_œÃH·¢[3«r¨¨¬ÆbŒCµà´Ñ¢9E5•ã™(ä­Æ\ZbÒšÒBО¿ d¨(orûíygÃçy^þêW)Š[·¶÷;ûöòÿû\L«Õ }´ô§?qT ;Ö¬^®]›vÐ Ð$ïÃrÅóæz¨ù¶·qÊ8çÚoyKý _ˆ¯¿>Ú%¼´ÛnõþÐA÷7/¾˜¦i,ec†åÿøÁ[nÉ /v+W*å݉}†.!úÌ6hÏ(õÃu¤”K‰NŒÆ!ºwöîjµÅ_AA©8›Êv(ÓRÑ! fO?M¿Ýk›![­VÑæÁkÉ>^ΫÛ8è¹B{8ôÿø+6Bäpûöí Q轩À î,{ûÆz½®©¤¶‚”7„ëœ+—Ë¥RippÐÂ-¾1T’þÿSÈùõ¯wý÷ܹ<¡Ry9Šž.Bç~[*=Ÿçyž¯s®•ç¯:÷ƒJ¥ÜhÄåòº8ŽZ­Gò|]äYÖW(ôeYÖIî,…ñÁ¼ WIYž­‹IIBa!¹c{(®­°€n~ý·J¼QpOgܺºº¦L™²}ûv¼èÁôâú=ù)þvW‚š'ÒOháy“êjo‰ ð›"Óé?¸×Þ®ò”#@ެ.P¤7ãFªdÂýc‚Ê> õ0/çW³Ù4-o<„²éÓ[gŸÌ™ÓüÊWŠ—\ö÷Û?)Ÿzjæ\žçƒsæô|æ3íN˰ʹÊÙg—®¾:Ȳƹçf»ïž½ü2ý lÎ=÷O%qáÀDÒ H—N•ª¬�Ú üµ[ÖÌZò¶Ÿö´‡kˆv»_i6o¢U6¥”¦wÖë{fÙ¯“äÖ(B·Ë¹ŸT«S³ì…ÂqÜÎóJšžÓj-*—ööÖëõöÐÐuƒƒoi·Ÿ,®,2±!ØE|ï ÙdK*"‡|œƒW¥\[ Ì�¬m«þOè8h¸R× ÏWÔŒêwM­ ¤¢®Fe[iöF&Nœh4z¯š9ÿý?3gîúï׿^ÿf Ï·Ú> ÃdI­VEÛ£hk©”¶ZqgÐrešº04X¨Vxë³¥lûœ³T*yj›š9’a‘‰@à,¦Þ×øaÕ·Êš/�à ‡#©–ê¡Ù?™8q"¤„³t2�?Ðr¹¬‰ÒèQjÕ³!Ljù¯· ñƒ V«yú"0>uóHTêÑ‹v\ Ã@FÃN î1)ç‡cµZ5fNÒ<I°;2 Ddc|]§‡õʤnÞ\¾ä’,ËòÞÞ¶sY£1œ^ôöž> Ã)SÚFÆkµŠ&-fϘÑzé¥$²$IººTª‡JÅZÐä<„V¥05<k ¦�2Ø4Z(1í™kRZ&£0}™<%3›U¯_[«ç?ì°¨/h6/ëéyµÕº¨Õ:#MÿÐÀý~µzq¥²*M¿Ôn¿³Ñx:Š~\«í“e_.Í€ùµÚOâøü$y_ž®Ù¼ILwjóÃÖƒâÆ:´ëM­!‚§¦òN¤Ä•þŽþ¬ñ&4ùS»w… ­'OåJ =ÓÖ¥*bT«Õv»Í )b¯ãæcü£FR:ÈBC{xD£3Jb«/XÀSí]k©¡ ¡`ÊBö´Ê©*li¢ ïÉ—¹‘ë,YmÆMxP»J­8çêõúŠ+ì0Õ&]b ¡½Ì]kÍá5`½VëÈ£±M“üNAEOƒYµ«ôãaþ]a5ìQÊŸ|J7¢ë¦SÊÜEZq4ɘΠc†:!„Q›Ö4ê•;¼�$WÃpèÆËÇ7L¹´"Òzçœñ!ƒ ´{‚°£EæÄÊ ‡eú©é€iµóRµ5G� s#¥Ä½Öô-‚-…j6›ð_”?f©Éâ 8½R¹½^gÊäÚ$IZ­MÓR,ï »QÝÇï©×-è®pngÙÝýÅzÝkY–ý¬«+MÓ)y¾³ùx§BåäUn½£m/ЧQÎŽÒ[«vËìK$ߢfrßBx=ú²H+ù eƳØ<ûj]T¶\Í$Ô³Ý�9c1 $ƒ/è3*ÁTkm͸‰ª³BBm,IÊv¤ï½ñ 3.C‘áÑ*\€2®¥fjD¯¶"¶y,ER7bî‘b_‹•‡"vÚù«šÖ•ÂçÅE 6-;±�c‘êÀ9ÝE 9 5Z«V©Šõº‘zvN)·‡�ù‡Vµ"¦¦±² ½gýý¶“v8VtöB‘Ø,Ëâo}«þãAÌëÒÃÏ÷Ø£ðÇ?&·ÞZ½óÎ Š¿û]Z­æþsö‰OTï¸Ãõ÷ï¼3ÏóÒœ9µ;ïtA,ZTX»¶=’¤î9[æ½^¹¶®#3ñE§^à¼KÙŸ¹ 3‚âÅQ ªIÝA½^×CÜIFµ6Ï÷KÓ®<Ï:ï}Jžo‰¢Fí×l–FÊ·ƒ;ç¾\¯ÿ:IžY޳Æ4£¢% Á ÛÌP‘iB…Úc«–šBioßË®†—ÁÈ`Æ‚„à àÁë¶¡YoãJÒcÿÃYÌ$¿ Np± ‚¾¢78Ʋpâ™áÍü«¸=›¬S³içÁωK•yžÛo"¤NŸÉSCq#GM Ü‘{zìLæo(Jt·xÆ<7µûEãYCœ:Z8T–x2‚Di=|Ä1¡É 'X—r¾£U ¾G#J«RB¬F…ôÐCëÇßuóÍa«… ÏM§Rœè¨¢X6ÄËÒ?¸+Þ}wñÙgà 6mÊ[­Â²eÙ+¯AÝ}wño Ã0_·®Ùj¹W_¿õ­pòärekÖäι‡.®\†¡Û²%RS>V‹æÌ¤Ì4'òbúBµð²I€—¤ o,×Û,]šát Ñ‹#Ø+ߘÉz­Öl6+ÎÕÃð×Î]˜¦3òÜ\!Ò4=²Ý¾|âÄÕYvIžï‘ç ;é!`WÜn_[­þ°\^”çNö…½‹®®.ë®ë¤³×À#>Ù{jæ-CFõâ^YIþK áþò-ÈÀ«ñkLÛ¼2&ÓíCt‹y±<äŒÑO½>õùçßah²uÚlæ\3MWÅñêK’ǽöÚkòäÉ/¿üòöíÛU¿Äœæ4!}6•$óŠ6)€`[¥RihhÈÉH)L-ªÀsí°oQbdÌíÂÌÇÅN;ŽupL×ç…µ0"ÏU2¨V¹ëzµ†@0ÛH1 ‰¦"ŠRÚÓÛDÐÁ‰ì£êsëYiS7R=“è.Ôh4h°“õ8L';ôÐæ?X˜;·ñ/ÿ’ÜqGÜqµWFSʉ)Ž•¡:eåDsÓ9ç^{-ïœDI–ÅkÖØ#JÓ4ïë Ã0ã®8Î^}ÕÞŠµ²³þþpp°-çH¸jÕpV!M~uyP}q k‹Èß=å72#]ðLÖU]P$5椦ºU·\ƒ­VOÇQ´çž{.\½ºÕjÝ\«]]*½lïQf®Ã,sæ¶Þ!¿)Û^R«ý:ÏuªZôÞ=ÃcµAQA%j� oÊ”)FÃ$h1ÍB$Šë{·_°BPÓ8´ˆtþTÇ$ø+k Û‡ðo½í¯€›)Â6rÆègóæ)W\q\…aø™ÁÁRž;ç~ÇkÂð YöDž;I<_€r¹<mÚ´µk×j.¯å¹ŠÍ¨µ g7¹‰v5tL„‘7XS_‰µ[¬Çh§�`Õ\#Ö«²¹ )ò'60HÂ4ñijÈA"¬ŽX‰€KÐù·D[ç08¡ôP¶V–=7%4Óçw2Që)â'>’Jh3·«ÂÐç´JóŠÅ,ËÚ'ž˜}tåÒK³,Ë’¤uÞyÑ72Û¯l tñà;OéN¥µ¡BoÀž½ëx±èÁhÉQeïšoç[ìuóÊX†ö­¤^^¨Gzôlâ yó ” ƒ,�GJ–Q‰ {òÖ6ß¶m›ýÛ …³Z­f»]tnYt9wZü6IîMÓ÷Õëí,+Äñªç; üsÁa~ Ëo4‚ øs?Ý™Yfi)¦­Õ¼‡¾zî·Ú£ õEH%þìóáøÐ!cX‚œÌÞb©£{½ìMkÅE/a¨Ž>º2ÇCÎØü, ÃÅaxV–]:yrÓ¹j­vl«UÉóß$Éîæ<Í V®\¹nÝ:›9Ðð`•>Y¡24 =ðzĘ}‡µX¡ªeÊA y¡gz†Ñ¤ú…x*ÅÚZWèI·¥œZãkiþn 7Î2%èôµÎL8= ÛH’Üéh·2vø4}ÂÝ•á¦tmö¶‚¥|#š„ Ã0=þøüCÊ·Þ:cÆŒ4M×ßí˜cê—_^¸òJ=žÌ8‹Þ˜úNŽÖµTE¤ÅBÛ@iÙ¤iGP[Œœò<gÕl¥š¡Õ ŒI“Ü"“i2©R‡Éb5GÐj†e ç#^2àWv “*iqy[¡°ªZµ;úm©t|£Ñ¯DÑ’(*…ášF#K’_ÄñÉiZ ‚—“dY¶[­(Š~S(ôE‘1Ü$³ƒ Ã<˶gYÐañÙÅ»‘:îú£ƒýº;´¹b™éà€ŽI9¢º¿ëŒ”ÊÐуQá êøÔÁœ&Œ™¤ˆªFi¢£Êªã!gÌ~ y~`žÏëí}nÖ¬R¥²lÙ²g~08¸Ä¹|ä"ã0L,<0·¨ H-8=)ßÑD�=,lzC[šúϽµ«Ç+'øèÁf~“Ô‰(/ÑÔNü0 'MšT,wìØ™X¥R©··wÛ¶m&„>44dÜbN@>™!je¬y7¢Pƒ©Ä¥Ñ>˜=m@pâ%7âFΪ3¼š¯¨1æäûìUæ0v½£Ù³ÓSOM®½v‚sguÖ† î»ï¾Ö£æS¦4.¸ xóÍä¿´…ìŸwuuÙÓ$C=t¼ÉŽ0ƒ@y,Dà~}­Ô‹Ü8~Età1··Ìº…®Æ‰fÏăs€,`„.Õõ‚É¢<.¬}¥Ð×:ÉÐ! ¢yž?Ç®3í†áü$11 ‚Zš>](„yžeÙCÚÝužÕÒ0 ;5Áâ xÉ<dmiɶB=PçCàGMžÔ׎‡cT¥uZ™'¬zÒx&Yo˜º½(ƒtþÉøý€fêøsÐRÝN½VåXµÆãsîÓÔ•Ë+?ü_Î;ïsŸûÜI'T0á ¥ÒM.E$|SU× G^Ì)š{ô0øQNdê)í" ,nµZææ4šN_ˆ}B±XTÖŠ}ò0ÜߑтIÛ lÛLœ8qÚ´i‡vØ‘G‰Y ‹µV«Vÿõ`áf³IÖ¦Q⵬bjM“i‡ô—q“ƒ–Cð0\Û GðPµV«U«Õht3‘Ã[æÌ~›+VD=Ô>ûìZ’<òÈ#/¼ðB½^Ïßö¶öGL¸í65â ‚€c e(¿oœF%|ÛEZ,÷=Œ÷Ú+Øw_›a]‘èðÆY hÍ)[ׇ|àQ*#¤¤r‚©&ýj¦»tÆ™—«2Ï\¼½JUæ-n©õœŽEó¨á”þ]M².¥xÐØ`8_Ÿ$sT0 ôßjYÌ@¹‚Å $PaULÚu¼ ËŠ?Ib{Y‡®®®žžÞ»:¦+†¡Ôf¨Ç•¤ÿWüì¶Ûn§žzêI'dR¯¼òJZ¯»ÁAÝ:ò¢s”z Ò˜%‘k³=Ô‘uÅýÕKc¸ŸÜÑÛð€8åiù¯¥:•–ç…Le¦ aöõõµZ­eË–ÙØ3‰›}£9V+X6§ù5Vz-êO æ)3ZhÑN˜¥çdž±’w•¥ƒ®`ƒÌ!)'õï*ö+Îf_Ÿ=ô+v~ìc/~ó›I’4N<1=ôÐäÒK³Ž¤¥ÿžy ¡ÈuTy˜£²[°Ã”…DF’Z­–›<¹ùÏÿœåyòÓŸfkײl8FÕþ@¥MèÍx§’)Œ¯Jk^±H²¯aUÍÖH·xUâSñ=’À¯1Š õ_k8Ü?•²o‘O)0Ê/åIªL€•ºl1SêV ÏÊ‚q"˦ö†ºøYê¨s{ÚYá¥Ó†á‡°‡3mÚ´<°Ñh,^¼ØþÐ*N%%*»’‡i…Ž*×W9cI’†»mÛ¶ÁÁÁaÚkÖ ¶°ÙÆ)‹xrØ) Öà8c’”Ëå=öØcÒ¤I¶d‘{QÐŒÁcˆ¿š®*8C˜á_yÕ;‡ÃN‡@U?ÍŽ•Z­688¸víÚµk×2 4 .h’NßK¨h;QU©`…’àˆÕ4@ª45Ó²jÛìù–ªP›šÒ«SÑÓnðÆz†tî¿?zòÉ¡+¯¬w\{ÿý“o›cW¥õµoäUxÞiný0�1Ð6»³?©}å+у&øCóâ‹ÍtÃXi.Å j¤H&e¢�f#˜rˆÓQÎ5ïÓ ½Ù˜=‡v†xÅÞˆ±÷(¨ùôµ¹èõÆ4”ò] ~l´i­Ö:cUY–Ýjý¬V»«Z-tâ·E ãZ­Ÿ ÝU­²‰¾Q«ý¸¿ÿ£ɲ7äù]µÚÏjµ×I§f‰´úh?{ÞQjcA×Pm¿é¶&I’$É^{íuÌ1ÇÌš5Ë$½¤A­³Hƒ°Mñ4vÇ«œ±ùy¤XÚ²åØ_]µê|ðÁ‡Ö­»upð’R©+MÛ#M6-8©º”â¿æÚ'Ðþv†S§N}÷»ßýÜsÏ=óÌ3L_ë6ÖóÔ¡Í�£0HÄ©ªÈ•ý-„ »¨d:«SK.k‡"ÛŽ0‡~©Tb ZË&Žf},Ð †€Ž4RŒÂÃŽˆñžós»ž[—òñTØ p•a7u]Jbvýp†ñÔSιÆ;ß™\w]d.5®ªbýÚC˜¡¦4ÈÅúg:âG«€¹ô §§uÍ5•›oN,¸êªú­·–/º(°#’ªÂb](oøŸ7‘0¯üÊGú”jF@õ©3:N´ÒÎÏ.·=Ñv˲̜`ˆdª-<XãâÆ#Búʲ졡b–¹ ˜˜ç…<‚`ȹj½äù¢$¹ #ÄžFšõÍjõmiº¤ÆÎhµNnµ.)Â0üIÿÿ-ìIîïÜÿiµ.)¢(úu­öO•ÊWëõ‡ŠÅWÂðÌVë¬fóþ$ùÚÐÐù…B$·T«g‹\žJgzãvS†§‘Ø»6êk€‹W‚C–e[¶l™?þ¦M›vîÜioÇö£G`Q›.©§85rÆæ§æÜ+axèM7 ®_¿íÑG÷Ú´éÜZíUç6§éŒ ˆÄ@W­ãuøŠ˨V«Ùh‹²vŽlÙ²åüãÀÀ�ÒLžÔ¦3eÐã=£‰*×P¯×w`‡‚ŽÂR›5V0¸“rau„tÈÂŒõFg”´ a‚¢dÈÆhÊXÔÞÓ¼Œ/¥®‡¦ñÄ(ò8¼ÜHÁO<­P(¼îu¯Ûc=-Zdú‰úkn¤l¾±ªò<<yâ µÄVåJFŠ`»—•{>Ä~%:§Ó§·>õ©Â÷¾7iÇŽ°}ûö 6´¿ô¥¡K/­üàáêÕ\†kŒX£Ê,îÄ%˜ª$‚~¨¡Š6úz •…GToɉ:#Ø-+áÞ‰¨½Peu3‚bžÿß®®·…á;šÍ}³,wî¹(z.I^Êók:DJ 8Ý/—T*3›ÍË;åæê0üJ©ô†4Ý/^íTÆívûÕ0üz”e3Òôe¾ ‚íέNÓzšƒ {- s“Ć÷¨Í0xÑô¤Å?4¼ªˆ³%Ïó×^{mÆ 겨‚­=h„*>«tÁñ¹œ±üÙ¯ÕÚ+IOœø±üàä,sÎÝǯ†áYíöß:X².^46©÷U g´]®¯­^½Z'�´ñãM„ ‹Éd ç G”dZ(ök®£Ý¤c4”´ª\gæÎ˜DÃsÞ¢…ÚØq¬á¨v1‚lŠ<¨º'&ûœ¢î)<RN¥z½®;MÅè¼µ¿®Ô}¨²»ªŒI8QF*K¥W‘h¤s¤ÒÝá|œ0aÂÀÀ€ئ'ív±Ñ˜<yòìÙ³_zé¥ 6¸ZÍõõµ§NV­2geR(•©Ô¹³&x뉲€Srúôé•JeÓ¦M°!”œFÛctKR‡Þ‘wS—µð¡bFJõUŽ(pî-YvA£qAW×Êb±ÝnU¯kpð¼žÝ8:¹µK6·Ããf¶ÛÿP¯/íôŠ,|Æq<£Ý~s«õRfYö@ŸÚjâÜ[ÓôqÜÎóùaøÅV+Ã)K{“*ÂŒšaCPhÍ´\OOÏÐÐU®ì&Ï5 66“ {hâHÒ3†Êžã!ǹiÓú¿ô¥go¸ÁíØñçîîLø¦/Æñ’‘Ì] BLy[d¥R z¾§£6$€*°Âl½j;]‡ö-x°É¶×SOž’xIõ€¸²¶.@ÏéÇ*ÂîC*pIõ³+ýc;ý‰Äªvãu­iÆ F£}&%(ƒ7’$‰ ÷Ñ€ÕÒÍs’W’®snóæÍ›6mR=’tðIÆ}ÀÙ·Dtº¢9ŒŠ’Úo«sC]ø-‰NÃ0L–/oÞ}÷Ðç>·ã†–-[¶iÓ¦<ÏÛ_ûZá‡? ž>!\uMæ[ ;é‹ÓƒÒ.x#¶àÑŠîêê:âˆ#ÞøÆ7Þ}÷ݯ¾úê.Ÿ©çÔÅB&¦Ëž|*ºü©{›‚Zg³n+yþî4½ \ÞØÛ»×”)[¶lùS£ñÉbñߪU7ÒÆÍ‰Z g´W¨ÍK’yIòèàफ़‹¢hn¡p>V«ÝE÷‡a_TÒt+¾ãø¶bñ›;e¯ÌOTyÿHöéô’½¬ÞÞÞ &ØH†2'GûeØ#ííím·Û¦dJzáèY”õ,ˆÆCÎÿìOW׆Ãÿƒ¥`Aà‚ ïœŒÃUçp¡\ %HóSO+ÕQVÃiÆ4—Ñy4j[UX¯,Cvã9·c? ©W§s˜¬ä|ÔQ;õ> ‡ïD˜¹T*aîDòEæHG”óQykóÖ“>{öê¹êVÂÞàÄ BB~%@zæ›vÖ˜.d\žgP~Uô*0ƒ;@Ž:–ïé6RÃÑç Ûµ£ŸO££F8´ûªÕj:,lYX³¦ñõ¯¯¿á†ú—¿œÆqõ–[’+¯Œ7lÈ;Ù:!þ:ü¨Pµ ±ÁDœbÎ~hhHÉ/°–,Y²iӦ͛7Û{þ¹X&'Ã: Âx¼òbtXÇÕ¢RA¼<Ï ÎíçÜÀë^÷¡3Î8ôÐC}ôÑûï¿ÿùíÛm4žïDS~™È7 `v–Jžç¯Ï²O7—–JÅbÑuº°yžÏn6?^­~¹X¤R™eOÇq#fdYžeVÉþ!¢ ¸XÔÍ©Ñ@~1 ¥rPOÛXâ’$‰»ž.ªš@À³œ¯§§Ç9gŠYôJ»ººl]¾ñ*gŒ´å,°M¥ ¸Lê^¬¬MÏúà`EÓ‰׉5�� �IDATa.÷Tè $ü¾ëȪë1ç:PŠÿhÆMŽC·#¿Í8@MAǾˆEoÍ€f³IwÚ“/äi(›Ñ âŸ×æ¶kS$Ž6€Nó謼RºY4ܨ« w㥱¤“UàN4?Ð8¡ÌUVRÖÑ:Ó9-ûeNyÊ2¥$Øt”ÁG%j»Žüh¶eKté¥[.¸ ¨Õân_{-è¼\šT Z.’ã8ËîÑ8Wèéóâì¹­\¹rÕªUD»#“ùb’»ØcQ†´Z¯Ú<ŠM*®pœÎÄPßë~´oÜ}÷Ýßüæ7Ïž={ݺu•Je``@µ-ÔWÍ#¡&¶Ò4¢Óó<jµ‹Qíßh¬ôPHëõ“(ŠžŠã4MßßjÕ¢hkž÷8·*IJqüõvû¾( [(e-î1tØeí*Í<ç\¹\&ï±çƬ(Ø2Å¢ùö£Gcª½‘Í›7{ Mn÷÷TÇC·Òj…•´µ�ãSåŸÝHK%íØ;«÷Ž9U/Vr“×Uõeø?žÒš×U›åGb1@;_³?Ô–µ6WÔ.šxìÍèÐaB,Àö†VTôl4§ÓvÕ cNLªÛ‡xͱLJ Ø@:ɨ(9v¦#ù•yf D­ØÈ0ì|·zÅJ^­Þ´… 8§J¾êƒR79^ ì¯,ËÜk¯úÓpâÄ`ùòLNkM)¨ewÁ$t5':iXi °§ì²%e<ÓÙÒÊ^m5ìQÁÏ>¡P(tww×jµjµêÄ––¦)ÙG¶¢ìñ¹É¢Ò4­9÷ç,Ûûå—|ðÁåË—ÿõ¯ݶmÛ{êõ»“dVškcÁ§,ámYöÛNµÎ¹_”JgdY±P¸¢Tj7»µÛ[£hM¡pwŸÒn‡Yöå®® Ë~P*ýs½~p–=Ÿ$%IäÜ5…ÂGšÍ ˾Z,ªÅåŽç1ª5 •å´iÓ†††ô¡9‘åv2L[N÷¦md“3WYk Þ^9cÿC!¬Ö&^º¤„«4Mkµi»Â>NTë•é¨Âû¼xmQ¸á™f¥3dЗj¿á:þÍ4º5É2"?N£pü¦¢ç€õ€3|'”©;³¸5Ž`ø<UŠî”O`k`hH}øÜ0eÕ�ɸJ’PsxÞ½ ëÛ½£HÍùÎ]{j:žg‰'UI!K8ôÄ^¡äY¨¯[ý¼ÕãY‹Ý]§ÆÒ¥aæ£Xå}Ùã5Ö¢Ç!÷kìôüo´óOŒä^¬ò&‹UZM[¤nöº»»:è µk×®X±Â3omˆ©9õ“^'Hµ XÇ7nÜøosçþ´R8}pðµÚ‡zz.®V)u¶¨y[šþ>Ž]ò]T(,-¨ æÚ–o6ÿ–e‹ººò<¯^uUé²Ë²,ûI©”Ξ]ûú׃0ì¾ôÒUË–ýG±8|>¼ñÕË/Ïó¼û¢‹Òõëó<o\tQóØc£… ‹sæäy^¿õÖ|êÔá€úñ­ë Æ@íH”2‚5æ¼2Ž3åiÓXå…R9™WÖëxȃ¥‡±Ö½yY[»¨2(ù] 9y)«5Û²nÑŽAZX@ЙôJÀ—t—’Ñ(±Í+¨)í-éC8ÀúF¤c0\I®9"yPÈ3aã¥f:õi‡óCÈÓш2tÅÊv.àò€7Ba£{ÎÞS²3•мØãñ˜ÕA<ŽcSiD5 ò›…L„ÚX?d—4®TÛŠ‰%B¬eëÊÎR‡M9ò"(µš]˜Û¨Mõi´;ÒdžmWs'ÈŽ¹AúÞ$%Pº‰`›4±©9Ùl6W¬Xaý!Ÿ²‚šXB)›´Êß%jéÜê8þD^¼yó‘Y朻;ŠÞ[*uuHwЬÉKÊå²]³ª! óãF*BYQ»ðÂÖé§£+Ñv®yíµ•O:MÓk®)|ìcÃGy¥R½üòîóÏÏó¼úot{nëÓŸŽ6nŒÏ;/=òÈ¡ .(\}û ƒâÓO¬OV­Bú¨ÕjS§NíëëÃÁö•âÐp¤¶ËÖ [6ªÆ ¢ øÇ¸EÛØkZ‹(µW«NI;—•HãUK|”'ì¡}07¦”ÍÉä|ѹ0°/ÃÇ,w¶ñ:NsK‘Ö'K2m«z½®¾)Ú’áx¢½dßnókaš€˜m¡\«?ªÑ©Sè Ú%"÷äб;‚ÿ›êÐþÖNövö^µç܇Pg—¡<rÀج=:ãb‘¢î2*ÖÂkEãRSÈ+�ÉÂQÔžú‰ßçE(g=%¡}sô(§ŸâôÛp¢YÀ§qÁ”t:1æ:úu¤Ï6eŢŗ̠c àF‰ì[‰… 3zµRm½=E_«VmG<†Î¹½ƒàß[-×j=Óù(kÕà !00JE.6<‡â 7o¸¡ú§? § aX¯TÚÅb~È!Ý_œu@‹V–eår«T 9¤tþùQE7æ3gº£vß=X³&—$ÁÑGgÎÅÏ=ç¤^±°AŒTM ¢»m:SS${ózÃ8rj©‰Å¸yÁÿ¢Zº­'u¬Mu� ÅÊô´UM-èžÚæÌÒ†¿2h™¨¡µܱý¬0§±¯Óþ:>¢Š¿?ígx3ÿª`af´ï:b*vúÛN°”'¢sž$—*ù[Ðí!0^ª„oz61Œ AØS«@j²•� Ã¯’Àö :A¥P§ q³ HÍk:B¢êÉ­jGMsž•6ÉtéÚëÆk@Çnô×À!•áÍÐ(UÅÙT¢‚8dÊJ°Öºa­ºXÀVm+=Ýþ¡ñìQ®×ë¤&öF.(µI>Ìg©¯¬äÖ˜Qû·ªšaéÔ06ЙxËs3f´?üá¼Ùtœ\}õ.Õ½÷N?ô¡ ÝÎfÏί½6Û¼9?è lÿý]%/¿œçyrçîo ‚ =ì°èÆá!¶ùÆu¢ËS $ÙRÆjÛ¨Ÿç›®�Œ—X‡œ±Öxy:0¬š†Ä$”#¥‘S[yÔCÖ.gõÎ7ÐôS<M§îÉ.í?Îi6ŸŠã•†ðUÕêì,›Ç·vŽÔ$I>Óhœ`®…Î}+ŽçGÑûÆÐsîüRi]8ç.j6nµ^ Ã9QDo_»T_K&<“ϯ»6¢ Šê@4e€T”^Áƒr#­Þ”ÑGÙªµ#w30ëb 6XöW–Ëc‘†Îùe¥gO>Z)é<ŽÕ†ñ†Xí‘ÚË5dŸ»ãެJf­êaª¬ m±œ,±°ë±WƒO¥ª};±gU<ÆTr‚©¢¨Àbê¸ãª6摾Œæ¾ktAÖPžÝ‹ZU‹EËÉl‹ÅÉ“'×jµ¾¾>6NÏnÕþÊñ˲,N70ÜsOqÅŠ¾yó,ä„a˜å¹ëïþë¿â+y¤ôÍo¶:*Z¾¼ô‡? sLûØc‹óç»Ûn³Ócðg?›0y²«×ɇL_Jç‹ÉÏ@wyA”¤äµJ¢Q•kË甼g…¯ŠqŒ‡œ1‹:da¶ßl“kr¡þ.vjØµçœ kÙÄ\ãžÅzÆ©å¢ËX¢NÂ6:Û+MR«ÍȲu6íÆoãø¥,{Ÿsiµ~^,ÚŠ|C»}}½EAôeYÔn_“eŸêéqy~ÇÀÀiåò'›Í­q|^¡pxš^R­^[*¡jYårÙâÞ0àWöÜÜHw�G2~­ö“]Ç[W‡lÔ4Ú>±¿µ‚ÃFAëmÌË"´S!ÙÓ¦¼SƒTÖ�[ZùÊÅ0!M'§ Ÿ¡ïWË • ÀñÜSÐÚÒÆ²£9ë'ÛÚUž±‡ ³2½ÒÇ«_uÙ«l =1ã>XžD³AÙüÖ]`Qƒ €­Xåk(¨K±‚u!ÁcU(¹Q½ŽôÊѲëêêŠã¸»»ûõ¯ýêÕ«wìØáÑ>™Õ_«õ¥juйBìÑIMÓŸNqîŸÂpA__°dIÚ‰åÃï+IÂ;ã+vÉZw*Z‡îõ½÷–Þ÷¾4MUŠgBc±ÑXÂXº\.³¢”ª¾éˆY‹E¯ŠEÖeŠñ^ÎÿŠ*‡X¯§<3 –L©/˜G Xúð:ê¨Äb=µ!Œ‚ò1¢1O‡‡Qc[Ój½£»ûêZ#æ¦B! Ã3Úí‰yþ‚ôœó<?"Šv ÃW²lG’ëÚ†At;çœ[ûgÙ±Îí†kFiЦi:}úô &¬^½ºZ­¢Äåõ®4Þ2«Å$-"Û�H¡`ï)�qô{°5qZ…X€_¬D£-Äs&¥UÑ_˜~*3ªƒ2úú@BÔU…O¥B­¼@赈©ØˆSö‡×§×%rÖóH-;çªÕ*kÛƒé ¨Ôáv˜{N5Q_º&öxžç&§Jm¢?«:,WmŽ*¬¤³>j ©žul=ç\ÿÂ… ëõºj™ƒÚÖî ÃïÁò8Þ?ŠÞ•ei–åY¶Ñ¹Ï‹ŸNÓ0Mƒ… Ûg•Að·¿¥iš½þõa»í6m —.mžqFš¦á3ÏA½ür¶Ï>í³ÎrÓ¦…/½”eY¸dIíÔSsç‚Õ«ÓÁÁ sæ0÷^ƒy*‹@ê²£AšÇEÂaQ_»;¼;ûeã¿U•3n^° ÷Œª<-tä㸃K]àƒi~ªÃíjkÁÒÄSþÇ¥šþ*™úÉuLuÖr¿</97 •?$I˜e{7›§¦é›egr°ît®Øn¿>M»[­íïUteõêÕxà›Þô¦ &À”³[³B9OÖÞ‰â!ÌøNÚrPZ¶ ª †Wú$ 0J8&3Ð$š ù­6t:D;˜‡*ë‚N¶Çë=‚H•Ì…ÁƒÐúƒLÅu Ìø}ÅÈâ«•†àD;ÜÓŒP(I­pÃ㤳X®|å¶0Y¬]ÛêZdÏÙ¾Î^‡ñÊÜȹEÌ X£ú\A±ÕjYÐÕ¶ í¥ÑµÕ* ÿ¶ï¾ì¹ç'zzfÝr˹iêò<Èóä꫃ٳóýö+]uUÇÙ„ Yw·k4ÊßúV0{v¸ÿþÅ9sÚív|ß}Á«¯¶÷Ù'غ5ùÕ¯œs¥¯=Ÿ5+Üÿâ÷¿öõ)©ÒV4ùyhÄx¯`å5—2ñ<‡«äà¯rÆl(‡½Jv¬.{¾[$­¬U×7 ®º…Òq2LJòÎALQÅ‚£ˆ¦2SAç\ þKyž«Túpµú¦fó¯?œ—$óÃ0 ÃsjµƒÒt‰�#v‘‡;·2 [*ÓhœÔn?R,Úö¶-mÖ«V­j6›Ó§Oïéé¤ÞR¤KeïiÓî¢ €Ž¬ê:L ûGqEU6T¸LŸ°6àÂ1ÓÎèŒ]N'P§²ô×É4ê• F£NÝù¼›R–VQ³9=+q—ÄúØ7 {ŠÕ蜀 ç0³©ñÃc²0þ¢mjkk9,¥' ZüÔµÄ-s]GŨ@<­Ã0ÌVF IõŸöҾϤ鷻»¿ùÍ9ñÄM›6=úè£ëõ«WÃð3Íæ÷ …dËwýõÃϹP. ‚ çáÚµÅoîµX¾xß}± [»¥Z-ÜpÃpN3RÆâF~Ú›5ö„:[Cñç@°Ç¥Ãì ¨Š s ‡œ1ÖÙœ={v³Ù\³f x‘‘ £W–‘&S�Íê¶©'&9;§!§’º2ÿݳÌkz+ï3IGã=Ó/ WV«ÿ/v!ýUCC?Šã—èu@|µª ¬ì ìÃCSÉg „¯½öÚ¦M›”‘EÖIÓ[‹ô1I*aR0†bg·µ¦mGûÌ$Ôjõ¨0—m9Íí®¡¡S‚èØ ¨•†‘ºÑ‰QuE³O.•Jhµq¢ü+ÏpSEø¹`딨ü(I€}©:Š«2ÕJýb~–È­j¤FWšhgµ#Ç· xùjžFIAç@¥€ìj¡BhwðCËü¹I#@̘€Ò}doÖÚÝÝ݃ƒƒ;wî„dÈ‚cU/{'I’¨ÝÞ?Ë6÷ö~ðC:þøãò<ÿÝï~Wß¹sz]çùµ³BzêQ½Õ«P›ˆZ‹X5I¨P%³ÕAuÈ#–¦‚Ñ5çS~ö¤ÇCÎXörœs3fÌøÈG>R­VþóŸ¯[·ŽéÆD@ÛÑá`K“'ª4€Q˜ è1-mdí‹ÚB¡=`›ŸÅÍ(¥ÒWÐlæÀj·Û®PÈó|i¼5MgµZSœ{Þ¹ Žk6Ã¥axTž”e½aøD–¥Q´8ŠÞÓnÇQ´ ŠÒ4]EopîŒz}Zž/6òJ õ èvPÎ3cÈ Ú_˜=Ó |b 'J&F» …iö¼‚Ñ0Ú­ÞŒ’0K?.é¼7#Ïl#I4¹¿rXybúßj¯âFúS0Á£Ø‹ÇÿÖ{Ô;UA¤ÏÔuͼMYÙ­1ßc·Ì“שRŠ-«%óðŽuRrífé+Óºê`j».hWWWWW×ÀÀ€ue”›`P#kVÒEQ444¤r@ð†+o£™´ÛÛ·oߺuk__ßÖ­[±+ÍÒÔupTfªÔ€¾”Ee†'ÍÉ›U ކÕåÍûR.‰¢ÊÌŠª±ˆRx9c¬µÛíþþþ'Ÿ|²V«mÛ¶M'ÃÉ©u4DaÀ•EòÌr ÞzZ&*‡ã:æoÌÓ©C05²ç’I*ꜛEó<t.MÓŸ&ÉœÛ' Žc—çSZ­fÜY(œ¦3[X,>Ñn»<¿¡Tz»8÷b1rî0Œò|V«õZßßÝwJÏd^5¼âIƒÝQÐ!ro’}³mT‡£ꚲ̌¼™S‡XAmÏPÀ‰’êñð™ Ök K¯þÁÊ0Z™¾ŽŠhA†+Ç›&¡â½ó¥ÚSP‰Žª¤ ÖçõÒ5ãV¿ÊïÛ÷ÂS<Ð&Ñ PK=¢š‰53#•Ëå7½éM‡~ø’%Küqªs V;»F]]]h=8™¶¶ÀÖh4 8¥ÈsÎÝÇÇîØñ_÷ܳlÙ²þþþçŸ~j½¾[–=ÇQ‡"jE b»²««‹å¡­5Ò…p$èÍÉüH ü*@Äs#ßtVLßõ'Á>rƸÐÉó|Û¶m?ü°-D%ä #2ZŒL“ãI§‚IÔg‰¦ºÎv”€~hCa{ƒ…ΖvÎ=Çi–QŸý<І[ç‚ ¸+ ‹…B†w‹½½½a&[¶´ÛíõApc›”–bß›çA¡P,§MžÜßß?44d„µÀÜù"]Óö�M´†dÎ…#jŽ`R?{JF]«ÞÖ±HãÙwªõ‹—òÛó´ÚEX¹«´´“¬=gŽ` Lª+´BÏÚ‚×§AéYKb°Jà•¨V«1l4‡|]Kž(-í[–éÈ0‡ ±¡+>Gc2nã(ŠjµZÄUåæŸ°ìÔ¼ÎÖ­Šn¨º/* ÔÛÛûö·¿ýä“Ož1cÆÂ… ·lÙ¢'8¤; ÞæÅPï�b¤t”éß‘‘XÛõOIòfs·E‹.}í5ë\>R­>†/A©TJ²Œ7£ð¼Õ½Q•æ£ß›§aÝuŒ™ `ö˜NÝ ~^9¥mH’†1ËïǃÒá³,°„–#X$Ù΄Kæ!ÚðP|i yRZ¯þµ}b®áï$õ•JeòäÉdA"¢K„@™V J‡³V'B±XÜk¯½¦Nj9`ÜÓ“ÏžÝwÛmé~û ßËî»×î¾{Çܹ«?þñAçœs•JeÒ¤IÙî»ïüÅ/úæÍ«^x¡«TìÓJ3fì¸ë®|êÔ,ËÜÔ©;o¸¡ÿá‡wΙ“Ošɳ¶-‹·úÆ6¹r`èªJ˜V°Ê‚ÙVÔÕǃcÔ©6 È0óp¼‡6¢T\’3—Ýy½ööCÛ›,Ø®'I’)S¦üñÇ{l¥RQö¶}…!0µíoKÝe%/>#ÑäUh{I‹'µ‡°oפJ÷‚Ù¨DÕ©óÔõíˆG‚S7šZ€Ö¶Z­;w>ûì³óçÏŸ?þàà ¯„IF¼ À6ÁÕº8ž»v†Óòüâry~,Y¿~ÙÆkûû/,•î,•&:gROÞ”U»Ýã¸þ®w \rI=I w«Æ•ýš9hŸfDÇ<K:•ø§šåÊ ·%æF$éõøúc(=0^å8x^¤fPι®®.ê\U×ýÌ’åoko9 ˆ­ çÐÒ÷°5Ó¤%pÔQG½éMozê©§-ZäFZ ¸Á,¡çÒȈ*@;çÖ­[gåB³Ù öÙ§ñïÿžvXêœá,Í«®ê¹üò|ùòÖ?þczÀ¥^Øwß}[­Öó—_^ú¢õëë—^Ú8úèòÃg{ìQ=çœÖA%…B+ ‡Ž:ªrûí“–.í?ùäÁ}¨û»ßÕñúœ¡–ŠrVêð µqîxö´­M­º ÖÜR'`åòUtÒ®JÝÇUø~"iȨx™»iü³Az¥fÙÿ6mÚÁÜßßÿÌ3Ïp¬Ð)1 Ȫ«Â9â-0(½^MqÔ [I5„vΕJ%ëê£îC½È^°[°MiÜðhhóÜtìÆÛq¡Â“t2™«€ž0ÖjµçŸþ¥—^êëë3ÌÖ;OuAˆgwÛ½ØÈ°É ²xìK_NÓãÓôóívs“$w.m·?ßhaØÊó¸Ø.Õ6©s®þ®w-XÐøøÇ wÞ×j¶Î=eE–4@…‘›§±?±÷nÇŽkº–ˆè¼Î(ƒ4‘Õ?W–ÊxÈ›‡£&%­¯Î…„CƒšŠ‡OSaZ[:h“0—Îщˆ'͆1³É“'¿îu¯›:uª ¦yÀ ¶[U`MéRöEõzÝ(:ùçòå]çž[ûþ÷ ½ Hç̉{,Z° ãÍ›7âÇI˰šoxC9M‹K–Ôëõ Ë*÷Þ›çy6y²û‡èzàj�îž9G¶i¨ìyÖ©ø‡ë(F“+óЉgš6äUª™M˨Îð2‰¢‚ÿúž]…Òà÷ÚZÞÜÊ1$IÒÓÓ³cÇŽ{î¹§V« áÑÉw¡‰ ÙɉÞwo'ox)5Ýií èì*Ø—Е…¯©•'™¡rÞê^Ó^Gw– ïCt¶/j4®3dJL%]=3¤^òÊ$$¨·ïÓÅâÓÒ‡#Àï—§a:û೩S‹×^EQ+ ëŸÿ|åÚki@ê Ÿ'´ 3‹r#­â\`d–“G[`t]ioÞ„²¾Êñ3–}y䃸ÀQCiWó{¯¦@Œs‰gZ nã+:ñ¸Tbå‚ ^yå•Í›7€N£‡©¶°¶_ûv£1K§ás‹‚à’Ri¸ ï õo~³rÍ5­#Ìò'žØºuk–e¥9sj×]—÷ôd{í}ñ‹é¤I­“On¹¥9gNÜh;Gɶ+®˜ðÝïÆ/¿vª@}DŒCr§vâ{†xjbÆ^üQ´¢íXÄx#v¢Ñ½÷š9˜À?a¥ëq£L<×±<à@‡A„D *J4ú!ÚÙïW*•Ù³g÷õõ­Zµ ­UåD¨wÑ'›Í¿„áó˜}]­öÆ<ŸÇ×wlííußÇ· ív{¿Fã;iꜻ`âÄ•izZ­v^ç™ßS(ü P°à½ŠÓ_™,äI$4V¤ªù‚…FmÉ`íãÙy¨ùœ†JÚ$iÃÕPep9ÝHÅŽ`U…áôWƒ�¥¨WwêéGìâæuVÖÛÿð‡'N,‹C=Öß×7øõ¯þýߕ٭TSº>€V38Ai2Ú Og~Õ“6-8Áhä<äŒe¡c@9G¿E [djbÁá„¢Sî‚°$̙믑ĩÀ¡Nçolݯ_¿~Û¶mFú„§ÏÆ�W±?´ž3fûävûÌRiß øX»}L»íœ›†¿(6FÑ«ÕáßÑnAåÒKÃÅ‹Ý[ßÚêí-w.5\º´|Î9Yž7.º(Ïó¾»îê¹ôÒz¶K¥tæÌ襗ÒÉ“·_vÙ䫯6ovR +ÑÒæ¿õ±0h¢j¡Ì=`m ä kM £ðÓ¦ ö÷÷+^ ®*È^±û¬€Q6š¤D +m„&åV¨#€b}FcéÒ¥ÖÃãc½¢°P(ÌÈó÷õí™e+•’R©Ùl~¾ÑøE¿Eÿ”çç´Zwñ†¯k6ÿ3 _L’³ÓôõúÝ…ÂwÓô}ÝÝι›Î-÷Ìó»ÂðžR)‚v'èêì Ìf*x† Kk ÄǵœUÇL;í!›½îºÖåÌ» 45ÑôÄX`öU W=Å5{ \TP±"Dð” ·K ûCÜG”nº©'tROOÏý÷ßßÿä“Áž{¦Ÿýl|ë­Zš+›‘hdÂ*×ñð¶·`š¤êk[[‹6ÅoÕ¨¨Ã4øJ^¡?N³¨É$¹ôB ¢éÏè–I“ZÏꌅbÍôÀM²…æ6z0ÀâvVB+RU ­ÓL#Tš¦é î“çwÔë(—ß¹ûîoïí½/ŠîYÍ:�� �IDAT¬Õv« c…’eYÐh€5qí£‚ i6#C®,úô§¾ð…tŸ}êúPžçýçœSùýï‹;wÚB7×B›ëTª®rÐU#‹¡ÚÎvûü!:¸ mÛÆn6›Õju´G¸w|ëœs‹ô†¢èaê:J3Êï`€¾½ šZ®©WžŠG°ü êÔìÅX‚öWgÙ;zzþKºƒß.ž‰¢ÓÚí)Y¶ZôI Î5ƒ EYÄ&$“çÓSëõ‹‹E»ý·æùéíöQiÚ”;U7`GxbµPá´%�RSšñX|4½7e“Œ´ëx5*"@+EiÄ*iè©Û!d̰ÔlÛïx8}õØåžxqøÈ#Í~4ëéY²dÉ‚ vîÜ™Ÿy¦›1#ºå # ÷MG2QUFÄÖ°-¶b±8uêT`a¶ýšBvÈốïÆ %%õ8 ãUÎØüàÔd|J8¬*"IQ `V:©wf©Ã•F(,fýLÚ�*e¨¢jy  " Ë»õ²9 ß“¦—Mœ¸zï½ß8mÚÚµkÿ¼~ýEaø>¶_–9TýúÓÆÇ>æ’$èï/¼ôR»Ph|à¥ýÈuw×¾øEÇnÇŽdÉ’Ò½÷Ú÷þò—]W_më{ð£mœp‚s®ôÐCÉcáÄ€î:šÌÖhr È®¾J<ÕÈþÂ¡Ž¡((1Z÷#ŒsW*Þ5%©ò˜xõšädµ^e£Ã@uºèjdI|"¯7‘à°C>¶·?%Â,«‰ ƒ„8Žƒv;k·›Íæ^yþá<ßEµZ_-ŸŒã,ËzÓtÏ</eÙ½"ŸáÞhÏP¾³þ)&T¼•ÔAJ¼qQehë…¯ã5ÑàÄ'BOL-wõ÷¤ÖÁH¶Qûñ@ž¸ý_x•Û¢Œ•ç¹›;7p®ÿ¼óV^}£Ñ¨½ÿýnâÄâ7æA@;–=év>RRìt|îûûû!ê„“Îc(æÆ£vqZmú’}Ža‰3rv ´5b#ˆyíXêAF‡¿ª?¹Î¸5=þ€ÝÃa×éêw#§ŽuvOå1ì7U‡Ê9÷Ž<ÿÑ^{½ÿ½ï=ôÐC}ôÑ_ÿú×Úºõªz}0Šâ8®ÜpC¸~}ÛX¼óç§Û··“$\¿>[¿>H’èÉ'³,‹x ߸1M’èµ×‚õëƒÎÖíþÚ×â4M»ö³Öî»ÇqAòÚk¹è\¶3`Ú@ ïÕ¨¡ŽZ}`¡¦S2À‰Æÿ¡¾á¸!Ô¾7L2›"Ä‹ÁÔÂR ‚%‡¶­6r¢ºX̨êsP*³]üã4MÃ$q_Èóüö0ü§jõ<¦Ã7]–užÞŽ øE±¸¶PxhçίÁ¢$y! ƒ 8&MOi·ïïеsSEmNm „˜&(¥$7“Œ›ÐK ¼P²;ïHIwü­N©Õž•&<g´·hRyØ›0×uŠË̪ަJƒæÃv¦ØŠ{,­Vû¾ñà‰'\OOñ'? ÄÌÜ››Ö cIã+ØjµúûûuЊ™y¢&qQ—´ý�Qð·zÖ‡œ1£hð ”áD0-'úžÎ´úêjöŒ¨ux^/À¥8©îYâ 래w:©u’ ~�Ñ~øá'žxâŒ3Â0\´hQµZ †OÒ+¸Ú8ޓŋ-bYÂ-^Ü4Ôë¹çB[²b#Vxùå<ÏÛiÚ^º4\¾<,•¢(Š’$ï:JçÓ‹'åT¡nëEéÛ!Vqxfˆ$Ú¼)M–øŒiéé=I„àÔ‹H5‰9L 6d!ÖD±O°Y#zØV·÷«é<žÂ¶öH¶¨è ¬ú<Ë0¼¸rpðÞbñéNóœ®R†Aç»"ç’$ ÃUa˜5›¶ü>ÙhlËó_ ®S.«K“U]cÕsÓÎ6Ä ; íQ˜i·NƒÚòæ¡!C€“‚,{Å<m:ÍZTYJ]>-AdªßzŸ}zµ©úÈqˆ{Š*þÆ·("MÓð©§‚f38æ˜Òw¾Ón6Ñ ,+®T*…BaóæÍ<ñ:ä4{×:Û§Kbãë©Ð”ý-$‹1,tÆCŽs#¥º(EÕq€×É–Ó4Ç8±IoÔPTÓIi z\â ¦\U5™ÆB†SeWlëÒæ¥–·Í`u€QeþÜnw¿øâ‚ ¶oßþÔSO­Y³æÐzý©(:0Mmâ9/;<UcÍè©'XÇ:äHe£ËðÎf*÷q?/ Øña3šâ)û“,{DûJNt, )ã( ƒkÝm"ÒÓ–çmr6qhMàÄȉš¶©ÁjA°C*‘ix‰ÊÈê¢Bá-íö>iºG<EAœÜj=˜$O‡á‘YöÆ<ïÍó'œk´Z‹¢6Y–ý%в,[îÜ!iú‘V«'Ëž‹c OU€iHtBµ³¢½+�@ÊG- 5ÇWij¶’*²«´òãUéê#}5{h:¥«ï›¢ãÕ+ÈÂ<Ø)+\QD%A(D1lûÜsî¹çl!)ýâ¨Q´E%ÇreL§õW5[»6s˶°ÊÀµÅ8ÓÐd`ÏŽ ÞŒ=°¦„w³eâZÁP]Vú+üi¸çBÚc§žŠOS…é€éÓí$å4mÎVRtkÙiü·]ÞOÃðŽ… ¿ýãÿqúôÕ«WÏÚ°áÚþþO ÿÑÁë5î*ÇÆL<=MÛ­áé©_£#`m*µÓ¹Z¯7æuð:´ôM�€ Úª«·ÎNiId7e¼#µúV”2® ù(8£´7€r=<†’¶ßY�|¬bŒöÒmŽ˜ÃÈÔ9÷û(Ú”$&£ww’œ–¦»Ásqü§(rÎuå¹sîç…™ÆÔ,ûk?ÇA|³X<£Ùl·Û×–ËAÌ ‚, ÈóÕyþ@DŸib°5O’’¥à,xoŒZ…¥eu5IáàZ¦â` |ô–ÜHÙVµ=ÄX¶JçÁ |[æ@Âí(§<å‹T’GÌ,lÀÞ<ÏM>J–”Ö¬ãJÜ8� È'Ó6ª›§JEÊ€=';¬ý¯¨r @[Bª¢oNµëÑV¶ {Ѐ%ʼnƒ2âcªŠ¡G¤Uâ4•&ÀçIé’BÃöO^‰ãO§éû-ú„sívûqç>Ç«ãØ5V °¾u¾ÏþÞ6”Ð|ËÊR± VË[‚ÔÌ”;Òý9:ä0XùCí¨h'ƒ–ìCåÑRî0m§Z×:Ô©û“¹Ëf•²Ç® ?”êÑ'Rz y;ÍíX·ó—÷«Õ ×Ñù§Â^P,â1so±È?̲ìž$±Éªß—J–+tÅqÇ[›Íï'Ij8[DQôh>ǃƒƒq£áåLz“gL ”Z*•ôÄÔg¢’z:=C#S§£hhYâ¥N¨l3] ,g¦áFúV)7-ºÃþÒ”…ÃÁz;åU`ÞüÈí´(W�C…«=ºçƒ9¡¬æIÚôRµhBÞ(£üi7‹=2®$=ö?êN¯'êæë)G KÖë8Õs«·›ÚµéD›-`Pެ‡lB {ÕÉœ_­\8€u[|A¬Œ¢û††ŒA˜eï‚ãòܵZ‹GúøB‰1(�ù&ûºÆÌ™¥µkíFLEØ4ÊÔåÌ®V›Ä0˜ßÖ‡–fŸ_,9Í-¢s6sŽS»€Ý«‰�³Ÿdûí·ß!‡²lÙ²E‹Á 2©ï +šF ¥@Zh;ìX oàr@ðxŒjÅL{1èRêEkËÒ"¥š©–d庫««P(LŸ>ýàƒ^°`Á¦M›xÂÿ”‹aß G™QÂg “î& §dd^‹éOðöyAN<“ì´IžamT> W´Çíüªµ®›Q'„<år„IVx•O4]Pµ;É8 ±mlQŠà­Ó<:“Ç"Ô}­&rTrv›H[‘¯(ÈLDdÝÌ�Ù<Aëñ3f…õC8øÎ„ ¿LY•ñc.ð”Hô‹l7Z}�JCJE¥š]n+,Èè©�,÷¤e«ö¼ ô£†††ººº\GÒuôÙìÚ˜N妆k NHO>¹=o^ðè£|T­VC›NõþRRúКë1îÀ<Š$˜¤n”eµëè~R7/Û§U*•Y³fmܸQ¹³ºoÝH[OÒC²iõuèW1ÝÏÈÐÔÕt›sÍÊ9Ë*•Š×‡�„¤ÎÆmVG ÉöÕÖY4ó'ž$Õ0¥žÂex–m‘"X”Q …ÌôHÖ*QK¥z>•Þ< ÜÎPb†NÝjY�™ÐkžSŽ0ìÄAQÇœè>8ñ4³•i>¿œæ:¬#ž–³úD z¥V„ʶP§¶x’�•DYm­ANÓÚNåþƵ1þÑDU9ì°;8<N&�P ž²"-ñÑ"IA!O{ŸÝ¥Ä3Äß´O�¹…n'ÛÞ>½Á'èp™»és*ŽÇêÐÞùÎìàƒ ×]×<ûìV|°V«yÐ<É»Ý2鼎%)ÜÄ •BŒÔ<6j)ÁvâÑbÛ)Cðӂܶm›§žÂ p¡›@U¡Ã<R WJdÕã"=æ.i)¯ï8%à¹Î°ªÂnž¹rm5ݹs§Y[ªŽåìÞ@"¯ÞeFOÔg¢ö3Nœ1y𿵎dÙ3P¢À²ŽaªK jÁ™n¿i ÑÞŠ×H?ОцŠö/ù5ãÄÔ肇OäÐA=€>%”sU`¢<£RXõŒâB/Î…(;cX5±SiÏåŒýôzÒ)ŸÕüi‹ÊÅ“CédÀ=l%ÁFJ™ò…2'º¼ð°9aj5 ÷Ðìd:ÕDb”Oi§*dbå…aØ:ôÐöG”n½5êïüãög?› …O>IŸYZP˜ÔóTéI´ÙuØÅ6Þ”:. 3ÜÈB§kùoµ§š©Õj+V¬Ð¾Ý „.¥íyE'•Ø&ë„ë4zP§Ú[X²¬¦È6µãACП(Fa%‘ˆh¡B>ðHÔNûÁDPŽT€\OùÑÝ$=¶/xûÞrROUe¸À²ÑøGøÑ¨`Ø€7ü¨£Kà½*:§2B€ÀÎÜOF]¬ûb©èNgPs¨NËLýjµÝ¨)T†Ž•B ªÁ}y²†«Ì J{XQåFªKŒ‡œ1`¬©ÀóßüðH; cT*årYM>´—h�…ú¸° ÀîU÷S…âi�¨q:ƒ')ïÕÎ*U«¼aþ9¼¬s•ä£ßਣÚï÷e—’$éî®W«Ñµ×ÖæÌɳ,üë_‰yÌ3Zè²³À -{ꦪršI¤ójš«ƒ±Z7x¤2ÄAÌÐG}HS'æ]°ãøýуPs'TÀXÝ¡ª6”Ô=0 8Ù ½Qé~Â}rÍìŸ?80`EîŒ,›’çιía¸. ]ž7;©RQc×ñØf¨EÕSÜÈAw“ç`z¨²Oh� }Mj½AüS €W¯3[œª'à. –)Îè‘jØêFˆ°;À á³Ñwd!)•ÚNYø£1:Å'W?ä"Å42‚JjÚm›Â¸&œÉW-y2óvz‹ÅB¡P©TÊåòàààx•3ÆsOSoc%›1VF˹¥Šº‘^Ës<4Ïu;œˆ{zµB¯UI8šay›JK”JD:f+^ûCÚc ¡bÇSí¤“â¹s£0,—Ë“'O6OøÂüù­w½+ûË_t~E\vƒÐ´`»)ÿ LŒ‹WÅLf¿`”!jE>9VÌñLù²ô*Èå-¦!‡œjH#¤fÿÊzËÞ"¡(„ƒ§SžY}Ç"¢óïSÆYâBDW­\Ò4 òüýåò)­Ö>Îí].7›Í iº6 ¿¨V=Qd/<SßÓ]Sµ.På’ØYf»R–-iÆ3•þk¯†z¼‹2Èó‰Ð£“û³ÕPDÈ'0ðW ]YY¨«úúœˆ ™Ê~”Õ5C¹…Å”E*Kæ¤æI`hH5ìƒ%@O- µZM-ãˆÁ<aͬ—yÄGì½÷Þ .TBàxȃÃRÀ}REòUR{õT»®£ÙîùR(IIÝd%ŠŒóª²åFŽÜÃàRê‘Ú·ŒöÔ±šéïZ›¨ ÿè¿Õj%×]Wûä']]ÅùówìØÑh4šïzWkÖ¬òu×Åql¢yžãý®ózÄžf³Y*•Œrƒ³µ}—ñ”T3WÃѯ”}wÚ<°Cþj’$'NÜc=V­ZeÃÊóšI£ÍWÈÙá›ð>öX×j%Ï<3<Áúá·<2~õÕ®o›Ëv'4tÊ)i–Îu?ñDáÞ{ƒ hï¿6kVôàƒš: ]xáÔï}WLdµzÑΠ¡¡!¸Ò.rçfäùGÒôÊ=÷L9dãÆ•Õ«¯Ù±ãorúÛç aˆ¨ÚöµgƲ7³ì>5ºhô% àjªÓòFgàÈö@»€HPµÙîFª©´.mEn6 ·ÑÔÛ‰I^\sÈÆl+ÎH‹¯à˜zÂjÎqµ`ìž;;) ÷hÁ^}B¹e *+*˲ÞÞÞSN9eÖ¬Y£PÆCÎÌå(èÉRÖ±2õÔ‹±šiB e©ù/)¼eÙœø¬Z¯/âa²^_„-m;Y%ÐUñ×Î X.j›EëY¸­a«UþÏÿl|úÓýýõÇÏÞþöô-oI¾õ­t` ï}†JBocâĉ‡rȤI“ž}öÙÍ›7«o­ úéK¹)zæÄÚÄsá}áÒÍt'‡¯ÊäÐSÑr“ R°=ÀÆOäS¦¯».ýË_ò<oœuVÐÝ]¸ãŽpÿýkŸýlé»ßµ¥Ò:ðÀdýúÒ¼yq…[¶¤iºãG?jÏž=qîÜÞ§Ÿ6·‚(Žw~éKÕ“Ož~ûíšRØC+•JÚÇV0PƒÍð;uî²vûÊÙ³÷{Ç;N9å”õë×ÿò—¿<ñâ+¶ms¢Ë@†Nf­Mr¯¥¯´4òeÁªH¤ž74Š(ÂX´T 6–€;çIõ4î*š§P’žõ»Wa0áÄB åÍÿ̾««‹6- 0õ%¥¡N5€qÁ˜Ð)³CT¼ŽÐ¢ù+mZ;Ôìœ3ŠHf,¯‚TjMªº;w>úè£Ï=÷ÜÒ¥KÇJóf<ä8Må´«¯Ý`'îgdÜ‘L·¥Ñ” vÇV½Ýœ 9Â֟ͩש@³§3M'†C[µv†ZâcX0ˆ– ¨¢]òÔ…F#øæ7«W^™OšÔ<âˆÒ¿èœK¥9¬ƒô:Q¡­”0 ßð†7L›6í•W^Ù°aƒ>=“²íjè³¶µUvÚö³Îð« TõjµºvíZo�“¯i&cL¤áðã-…;W,»N<±þñgD‚éÓ Íf†áË/Ç÷ߟvÞx+σ(*”JÁÀ@¥¯/êíö¯ÿÚ8î¸ú‘GvuuÅq\«Õ¶þóS^|±uÔQæò ®3ô' *Ðê0stHi‡õú¬$™yÌ1ùÈG8à€¾¾¾­[·þ¦¯oß;ªÎ•Ëe“ǧlR¯hX*L)y]¡6#¤¨Z+Ó†~èA©E&ú4tO+•ÊÁœçùÓO?­D/Â9œ-*{/$Xj§¤ì$g6¬lÛ•:ÖC£¼S{æ†SÙ'ØEJƒ»Sî5ÂEžôŽ'©âÖj=Ǩ“Ý*†ˆ¶œ!%éX‚}ûàààܹsq›9cu4–x@JcãA*•S¥mµÙ®Os"ªô/ c‰Ûr›¤€›2˜´¯­iòVLéí Ñ¢J¹ÿºÏ™ûQËd»æÒå—7ÿõ_'\qE*ü]æxT/}4!"‚jµzß}÷EQ´}ûváí WGdÄü=â,OŒžn£§@x,*�aOUÝYøp‹p:dªt>AV’BaX¯%šGÝ:ðÀȹÒÄO?m÷^Z¾¼ñîw·>úѸ^wsçNX¶¬\.N˜ •J¥Z­æ{íU(•Ê›7aX.—9ˆ-{°Þž½Üf³Y©TŠÅbµZÒ¹±4M·nݺeË–™3gnÛ¶mË–-æL¡Šœ,EødÄ äªÞŒEÕ^ J^ãDÛÓÞiµZ6,S¼···««Ë< Y¨*@g)½ÕѽyzL[ÊeȘ U¨rŽviÙ¤Ô>¨Ï§YlÞpL<›’¡=®yy°*¯óÉ*ZèÑAõ 8‘ìò ‚ñ36ñFu´¬[;}úôF£±mÛ6]4¤f^ŸP³¯:QdLÇ3Y‘ºøhÃ2ZÈž ©'<;¤P(twwW«U²¤ J¥‘ƈê©¥¬nÅy»'I,ÜpCÖé{é¥êq¬[T§óšÍæÆ•!ŠÍ‰öoXQyL<8N”Št{3IéÉÀ‹V[×A·Ž®¡I’X¨FÌ4‚ú%—ôÜ|s;ŠÂ<’¤ïškò(®ZÕsóÍÙÔÏ8£û…¶œ~¾ûîaAðú;î¨ÏžÝxï{6ì±`A^©T …‰'®<AY³&.]Ú»fMÐ9ˆQ5Uy£*Y3læÌ™³gÏ~úé§·nݪؠõrîŠãƒŸ}öw½½6lX²dÉc=vòÆÿ†ïíàQÚ—¶0fç¸%+ðxÝ:~¤S±ú:àÔé¡#ˆ^Õn[«Õ^}õU;ãxêÔ©'œpÂŒ3xàåË—sDª˜î,oR’Í¨Š™0ÜTÁ9dú"Úsõ¼—ì)Á‚|¡Mµá±üÉc“zb¦ðVœh�Z»ÎãÅÑW£a¬E?ú³ž¨¼þß1Œ7ã!g°Æd€½àR©´ß~ûmÛ¶mçÎJÉw¢5 ô¤F £E–œ8±386š½†b±îyïw¼S�:2Ñ…ÍŒî/¨šŽ R’ƒrhª¨GÅßÐ_¡Wš]:ñдQ u²*ÇŽ{fõ!•©ƒ€ª]éŸÇñ#lz+I©k¼hª[*< êN5Î<sà Óý÷ï¹ùf{›ý·ÜÒ}óÍ­÷¼§~ÖY“vÛ-뀄­“NšuÕU;O?½4889ŠúÊå•'œÆñ[6o&Mjõö®=ÿüYK—>öT÷ÛoÛ‘GÖfÎ\sÁ³o»ÍðE– D² 0Íãªèx9%õ“Qô‹µk¯ž7ïW+V¬ß°áí7~epð}åòû: $=žƒI†SqlÑSTgBØ\Jñ·º¿vêHjzV…4ux³O6@xÖ¬Y§vÚ„ Ö¬Y³fÍÔ”í»ºº¬X1Ø–ÙgJmŠoª:¸ Þž²»³VŨ8÷mAÚBRfüßÍÉhüÐ'»s"O‘¤4òW:7ÔâJõVÂ$¬6-›(:½!'¬ãmÿ»xp†††žûÿØ{Ó8¹Êj{ø9cÍ]=wÒ!„$„0‰ ˆQeTÔËE¸ˆÈ( ¢"WQ&QD!Lˆ!B™ç±;=V×\uÆÿ‡ÝµX9¹ï×7~èþà/6ÕU§Îyžgï½öÚk½÷f/ À=C9Íe´Å1!ñ€™N\³clXtãY·§IdÝ`®~é¨?xÃT«U4l0‚ "&O5Ê%‰­‹`\{a>âÁ1²åÄwV„¤Çå‘\˜|¼�\OàEü‰PŽs ¶`BU—�Aµ‡ªÌ>8€ñ xn.óùç³ÿ{þå—åÉAàMžœìí-Æã™¿þ5lkó'LHôõ555õ™¦J$Œx<iÖ‘G6í·ßño¾¹y¿ý&MšT7Î?þ K–”4í„_ÿúåì^»öåÏ|æØ¿ý­ÞֆŠ5¦iR³–J%Yi®ënÙ²E†IÁ\ú0)qÝs3™oïÚuç¶mJ©çmûœT*NE`¢ƒ<"·1ÂRAF65Àtg&ß÷+• ôýP �;e²·å˜Þ¹iÓ¦gŸ}Ö¶í·Þz«\.³º® *³¦Wíø_è·2K“ÍȹßÎÄH'CL]AÕÈ#Ϙ¾`%¤BŽÈ‡)T>IÐ[R %\„m@^Ø…‡Õ˜_ÎÞ4¥ YUB«ån*"Fë1L‡¥Ì³oŒÂqB*Ë]Î x³1FdøT.LJEð‘ž÷á~ŸH$$å…ÎÓmìkË:ð¼R±7ØýoK.`ÐàQ»+ÿG´§X’ ¦2ª&'íp ©^Dø¾P¥ ¬r¹Ìô?ž’cÅ-ä ,(‡z‚‰»]¿¦)¥R›7ÇL³fšõ /4R©Ê 'hÓ¦™ï½7þ‰'’ÉäÄ%K‚³Ïn‹Å¶LŸnÍš5}ddÞÆ÷Ξ=}út;“™–ÉuÔQ5]¿?;¥Tší8©z}ö‘Göôô‹EÁre™á@”®†ëºÂ/O&“ò”%9¨×ëõzýo¶ýMó§Ï4×Ðt9Óq4MûkƒH&‘�È·»"$=ØL0‚ÇEš/ŸÏÃIšE£ɽDD•�v¡’cV:ºúÃÃÃóçÏ—Ã#ænCá– @(Ïñà;‚í&·0&Û'B] ÈR:�BËtsðw˜ó)¢Pl©QK’OáÉVt‰ØêFð�¤q(Yðαˆúù\bm,äìÍ£hö›‘";Û#K�� �IDAT$D°W3 Š&°rBÎÎ4ÓG7ñƒ»£ kò” ¨Ã²]AÜŒ´.� Á‚jÐðSàsŸá;Lùðà*rÉ=gÜ€ KÀŽ[nÇŃÀa22ëyÞ`ÛöŠ+"Ôp6ªL/úŽãT«ÕD"±ß~ûe³Ù\.—ËåjµZ¡P€Øž0pCäþșȳMX òÈFg#”Ò4-½lY,дäÖ­™Gé¹ùæIO>yÑ‚ÏÌœÙÜÜ|ÀË/ï[­~nåÊëî¸ãèBá#MMØÔÔ4nܸý5-nšégž¹îüóO¥>¦ë‰… ûÅ/ú»»—sL¿išÍ7¶ÖëfÌpgppbE’Ò@±P®=Í"* ០Tcuñô1Ï»¨=D7¸‹‰Æµ°Qä÷hbs§!—Ë\Ù!Ä<p…Ú v(¸”8÷qñ,dŽ`)tÄ6žaä€ÕK¡'͘"i�.Ö#¦×R¦#…˜Ñ±„«"5Üj¦hâmmm™LfëÖ­Åb‘L‘îšÚ]æƒSЦÇBÎ^îå°r6·yЦCÞô�%²‘ħôÐX<­'&¡& VgŠx$+šMã†*N (\ñh·¹#Š+G¿‡§4"’, .§ÈµžeØc±˜L–‹E¡–¢e‚£4«ÆßÖÖ¶nÝ:¹™òxÖŠ5R©`2_¾W2™ìîîîèèˆÅb;vìxûí·#ÔAÕÐã1Xøòñ­f> yx H²¯…aûâÅñlvжo^¿~¿zýÍÎÎÖÖÖ\pç§?ÝZ©´ '=ôuÛmétÚ4ÍT*Õôæ›ÙnøÞ÷¾w’a|ÔóO>™¼÷^­Ri‹Ç­tzÕܹgýïÿ&‡†,ß/¯\yÿYg• ùtT{rµ©T ЊïûÕjÕ¶íbÃVD;¹á$’Îʹ‰…„,AnŽœãˆ@X-¬Oˆ¦JvØë¡Ú€3:Ê\Ô^œŠ¡Î`›µÈÄ(¹(Wd¨Š¹`E²:ØØx)£A_'2Ä'’›ˆ,76£Ø@Gq(îåÝPΚ5köìÙO<ñD¹\æ³ •KŠ9¾#^ …Ó±³×~>œ¤Û}P‹³ožÇÆ‘]©Tã@Ñì&Âð·\ç¢c‰eâu™äeƒ�UA– ²dû'ûÛCØÞØáÜZú!ù@·‘oH ¯F±µZMNg9¤äÚÀý“ÿ ¾V«½ú꫱Xlddpe„i)FÁGΕëº;vìp]7•Jõöö Ý‹=•ã|AÐâá_u9¥QóÓ––!UçvìðŽ:ʋǛ”²c1ÕÔÔrøáØöŠTê­Ï~vå%—h¦Ùµm››ÉHz+—Û¾ô¥ê•Wn<ûìê%—¼ý³ŸÅS©ý}4ýÑÚ/¾8~Ù2mÖ¬fÓ\ùo¨5k{l¥¿ÍùT*…æŠ<ñ8Q˜d2 0÷X¯¸Ÿñx¼µµÕó¼ŽÇH³�£˜�TÅj›:v]W@]–_‚@˜rÃqR9œRë½b% Œ@¯M¶^5Mr2rÜãeXâòÉóC\沇)‹ç2´…ñ§G@ÅwÇmŒ@Xo{NžJP_¼xñÚµkûúúdËÔj5pÍñþJ)hcgÚ'?¯±³×ª´yõ F±P@]ÿ‘à�ˆÌ'ót7t"¤{ì"äÚˆ",,ã3LÑa¾¦"¹FÀ`1— äv堆 >ôDÇy˶ó Ôå|×Íèúß_²;Ø}^¥’2Œ…šömA°o­v‚ëºþ›F=gFkâû¯7ŠèûŠr˦±{‡mœAµZMRÅZ­¶iÓ&vÄb!j|™Æ*Ÿ[*•"þ"’ƒËq/'‘¤êétzÂotuue2Ó4»~÷» —]XÖQï¾ûÆÜ¹_zñEû¨£:wî¼xõêßÝzk"¿âÒK÷Ù±c»iš¦yB½žòý`Ÿ}”e}þÞ{çßv[‹Y|á›ov,[f®^L˜ÐÑÑwÝÉ«V¹;wN C¯µµV«ÕëõL&ƒ²±\Úò(Î˜Ž¢A�€VÐu“uÒÚÚzàöôôär94K0�ÏB´hÔ±î*sÓñæÅƒ™)KA†�´+6´foä$˜Eܬ±r0ÝÑ¡À&ìVö”º$bV ¯7”ælN]j¬%®„8=U¤AÅS¢ÐãË"ø®D®mxx8ŸÏCF=™L²+x1 j²Ÿ-cm{¿—ƒõ„m†Àް¨<ä)& )AD' Õ+”¹CÔ-Ž+lñiý¡dÆÉ‘$ˆˆ[àúQ \ùÀã p£Á¦âVËÊéº>Ýu¯ò¼£}žeå• ‚àÒZ­jšy]ÿ”ëz‰ÄÊF1÷­Je Ëž7/ kš6¬içÔj+4ÍPêjǹ1“«º³T*êúk¦‰ "M,ð˜ñPÚÛÛ-ËÚ±cî—8¬aƒ*02WÏlÅD"áºn­V=:"C) ùŒÇãmmm“_}ußY³¤¯iÚ'–.mkkSÙ¬™NöÙO—JÉñããñø5»vu¾ûnjÊ¿½]Ž€³'sûíÊó4¥.zä‘óÞ~»ø‹_$Ÿ{NÏç½Ù³ÃtZiZ†•k®I/^¬)uô’%ú¼yº®—J%×u+•J<ïêêÊçóøv’ÈKÌN jw×,`æ}†Q©T6mÚ$êmÂh’» ˜‘å�Ðè²,+W*D#¹ ¬C>úÙ*"猊D€#H^Fz jcôUt4"8´õX½« ‘5ˆ1RÍq”‰Åøú\èc‚ÌÍ2%<Í~ÞèÌqà”H¿§à&$õ0«ñÔQ CU îBuã1>¶ŠüíXÈÙ ? d³jèÄ ­“Ç™N§åtYUm$ï€Ö üÉï¹× ´!ŠGaàä!F�¼�ðæÜFÒu=N‡aX,åC¡Þ4�C <ïayÉMØ¢iwFW„A`˜¦Rêo±X¿®Çâñ«J¥®0\ÙXÊÇÔë_ÅJ¶}CµÚ›Lóc±þ0´5íÏÕjhÛ†aüo±ø´mŸÜØÕò)Õj5â©òà¿Â¦š‰\>ŠF–~è¿°» 6yœ0wH>Z„âMÓÌd2ÍÍÍ'N7n\GG‡ø1û¾?~üøÎÎÎjµZËçe’1NÇ‚`Âi§ÕæÍºä’ËÎ>ûÎÆ´ŠõúëúÀ€ýøãZ±hoß.%•wôÑÕO´Ói{Õªz½n|úÓ®[6´/ZÔÝÖV5Œ|>ŸËåâonnnkk Yx²GFF¤ÂΞÔ@l–!øÀœZ­¶mÛ6íŠ4íAêCÍâå0'ä‘OæOâ¼£„så¡C ‡YžÇpÄ–w�òÅ‚‘—¡DÀ02ï·€‡³a ¼ \|€râË&ÂÌ5ÏkG¤<±ÀS¢Š¥å#Å·€·ì¯ƒÖÿ(²žb(E1©ï¡×À­¬½HZ 9»¼�Gæ¹wÙ~±F"©´,ÜQ‘'4—ØxT>iZ¤ ‰°†òÂ>¼I cRr;B‘.x.hY‚ÂCÅPfÃȳ2õ XëûErÌí·mÝóÎ(¶Æ¿âq·VkW*¡ÔJ]?Ü÷=Ï›†³|¿†K”º$Nsœ§R݆q R³‚`a†/ø‘JÅ4ŒMºÞ§ë𦠂}'Tê-Ërg``�ý u&Sðăã8È7åO¤“„‡(ϨT*1 ]äò˜ý– #“É´··?¾µµ5›ÍŠšC{{{,kjjJ&“š¦©zÝ4Íl6›J¥,Ç1b±-çžûk×½þÖ[¯þýï°~ý~–5ôì³ÍßúÖÀ#´~ýëñwß•çe¬Z¥ÅãÚªUuÇ ‚ óóŸ¯^u•ÜçI“&ÅgëÖ­rñ"*!1I·|‘jµÊþİbÖ¾€0ÈAIíy^"‘Èd\Xµâ†ËªˆÜIÜv^ü¼€QK ôEL³ÉQ §5µ»¸À.¹WÈ‹”°0AÀªîb²wÄ# œˆÄ¼* cäpÔ @Ìd¿ã’ ±ˆ\ ôS±Ëä—ì޹+)ÉdRDD*žÅ=]×…ßž&[4õrö>IZž½(°’9­È>‘ã[ÖÔä\‘z…KZ–ïeQ$û@ƒ1Â@e\ɹ`/ç‘|V¥RÁ0#SðqläÃìU$‰ ³ L¿êyŽ®?bZ­v‘ãáûuýÚXìz×]«äº¦euêzW,öp2ù‡0œ?<|_,vç-0͹n¨ë¾ï¡Z=B)C×óºþp<®”úrµÚJ©ñ¾ÿ´eÉè’ìU ¤¬ŒÅbµZï$¾—Ú]38Âbe¦BÈ­“;&ì�˲’Édsss*•’jF6°mÛÒíÀ|"ÒO¹B¥T_>ÿ·çŸ¿ô¹ç&Ÿp•ÕêŸ{{ÓÙ¬9yòe‡ÒôÀÖÖ­Îgl3ŒWŽ;.¶`ú÷¿':ÎÑGaY–;oÞöM›†”:üàƒëÍÍOÇb¥ÖÖÂþû»,\¹Xù,�÷"ÑV­Vœê%G_7T+G§€ÀWaÎÆG9ò¾�ÊYÏÈä#Ûw2W8ŽYU“ù`ˆ Ü¶áZŽs;TÌL×äéipÊG}:,Kv7×|< ¹h p¬ŠÆ|°ˆÑ.“¤jwÿPfŸc­JÉ…{+ñžµÏ9ö�Ò”‚ ‹hÞÿ—�ÊXÈùÿû¤�yXQ§Ó‘Br÷/2¿4µQdè›±è 2¹ž7 #ù &º�àáS E<º§#2Ó‘è¾ÀÙó0B~èº~¹ãì ç-KRjØ4‹JiJéº~s<>1 Uµz¿¦õZÖuõú|a7)A: ;‚ †Óçh]VêG©”n·ŒŒ7M¥Ô8ß¿¶­Íçz{ÿÜÜÌõ.²QqC8|"ãÀЄIœÅø@l“j&‘H´µµ¥Óé–––t:£Jºâô#—”Êf‹W]%ïüã¶¶õ=4£³sjww`YŽRõ£~Ѳ>ë8·_~ù•/¼P¾â ï”S6Åb¯êSŸ›;×÷ýÐuÝzÝÞË/¿dãÆãl{F"‘K§ç§ÓšfÕ¶{s9)¤Ú–ùÖB‡Íd2-V*4#åû¼Bòþ9—A ¹qÀEöÐÙ×€AÕð.Фùð@ŒG¢ÍꬲŠu ËÅÂ?zfx²%¶ÐL1�µ„e§Ñ:‚ÏòN–!�úÇ4 žïaî2ä Ø••ý® AÃ=} ä¾:‡ßÏœUL•îÙ* 9{[S4ŒMÈýj¤0ØrüAì…kõGj)žÎÁ<¹,P”&HÇ�Ã*X@~"nK|4(r† ;V-�#ÔÁß,›@úL"¨iY¾ïÂó®O$2²£b±¿ù¾¥i“5íÎzýÞL¦¿V[wù~àºL3ẺaÔtýåTj¹ç%”úk¡°Ð¶W$ÃA 9Î}ÿ]_¡”®Ô:¥žÛµ+Pꪎ“†@QJ2Î�£0ô¨1† ÃJ–9‘;Év&Lí³,+NK %CEmmmñx\k„1|Už¾Ì%“Éà„ì0Ôu}i2yÖÇ?¾J×KÝÝ–Rº^Wê¾bñštúΦ¦êi§‰4Q½^Ÿ†Ç•JºRqÏóƒ Ão··ŸÚÜ\ÒuU,†a8.æy^=zÃpsGG.—ƒ‡i6›²u©T*K‰&…8òîˆñ¶„Lf@š“§ŒQR3sLÖXKK‹¨ „ÛËÂB{Š"ã,¨°'… õ(›xÊ~UƒÏò¶`å 3ô6ØS¥t͹>ÆtWÉ p˵!v²³ØÊ“ͶÙ=kOÁßz½‹Å"g s,YêÙ$38âñxwww¥RÙ²e ’6Vf 9{“$ÍLPΧ@J†&Ëb‚(Ù®Oʉ` ÃÆætÓ�˜½�ÀE ÜX'Ç"GG`Ðhù²?¸›â°Â™¼¡“6¯¢Ii¥ÔËŠ77§5mxxx…¦ý¼áæyƒR=±Ø÷*•§Móñøc##)ßÐ0®O$¦†áKµÚ㾯iÚi©TÍóò†ñÏbq^6;Ïuóš¦ëú™JuzÞ=¶í»îa¾?- çµ·›Jýe`à³ííÈ4Q©ð©ÄÔv\-Ì&`ÑR– R<t Ã0›Í U8ñx<•JɳÈf³étÔyAÞd>†›vוË?L§‡u}²ç]­úA°5 iš¾çíò¼®Æ™/—ßK¥¾ÖÖ– ‚Ëûúö+ÖØv³çµ;NNzÈÕj.™¼ ¹Y)u‘ãìÛÈ$ªÕª¦ãñx{{;\$4ær¹d2)scÂ7v%@3”‘ÁaäCx‹V`ànâr•RÅbâI£ötæÊž@4oÐttÌ|käã9`¡e”P8I1[*J`tZ %Ïã­çz¨Z¶lt/$“Þa‡†,_®òyy º®‡é´7{¶¦iÆ{ïÕª>q¢6eŠ/npP­_¯t=<öXÏqô5kÂþ~Ð_™8Îê5qeŽ(³ûìYŒù.:aBnš—[-_9“Ézè¡k׮ݶm’E®GÇBÎÞìåDR0æž1ŠÅÓ9¢p£H@N:Ü<ëÃ-Gv¶‡B-ÿ‰"“l>˜åÅ~ ‚ ·¦xœ ƒGù�¾ÁcÏ\'=<aÂܹsûúúÞxã›n›£{ o‰Å¦®ëç¤RûV«Íšf۶Æ×’ÉÑû ßK©Max·m[šö¥Z­M©ßd2¦sJ)Ñ5it­XF´à W°‹²àzeÆ@Ž’òE8$aO§ÓuB­‴|¤7+Ù(÷_‰ÅÞ5Í wd2Æñp"1ÓqvØö·‡‡»ƒàÛ­­ Ê¥Núm±˜H$úMóÚ¶¶ó]÷_axÅÆï´´Tc±¾¾>ÝqþP©HŠð¹}öy¤TRJ IÈd}9R[ZZ†‡‡%<‹<(ûi¢j” (“hY—ˆix ’»`†,2¸Û˜HöÍ|3pšy;(²õDÿ‰-õxKò´?'ˆÀÊ"¢æ°ÒPJ9sæ‡æ}ùË™cŽ‘é^xaØÑá*ey¤~Çø+ç⋃l6 Ãàˆ#´»ï®Ÿ|rpòÉÚÊ•¡RîâÅÆÚµµ³ÏV3f¨0 >þñøƒª\npðb}FŽ&vgP{èÞ0zz<:88øÚk¯‰%.÷Ãöb‰3r¢íœˆÉ4`ëˆy ›ÔòNÆÑ.}d­àÍy.)9zÝ@¸¿aÔþ¹®ë™LFþÍŸÅÄnØpÏ%¿ß °qÍÇG†mÛûï¿¿œbòq ¡º®ë{žÖ ¬Ô¦¹Æ¶-¥ôF#Aš3«Õ§m;´¬Àu]×½¨ZýäwØ7Ý$—´yÊ”__{í`,–¹áÕ× EoÊ”‘«® ðí–[‚-[‚ ¨ó›µÃ7׬Iÿüç?îg?«vîÔ–-ÓÅEr—‚Å}%1Dü ’H$‰Dkk+ð´X,&¿”Ô^^ ½pÙö𦽋m°¬ËÊå–•‚ª¦×õ»ÓéãŸ{î˜?üá²{ï]mY/½þú?îûþ¶Y³6NŸ¾}ÿýÿýÑ®ŠÇoÞo¿t­vi'“eÃXÞÕõ-[–75µzÞ¿²Ùí¶}ÝÔ©'f235ML¬qÐ ˜V­Vc±X2™” cEE‚`\øÂ/C‘@»•Gæ#cÎRß°Ì Xûè4È™ Ú1äX>k, €Š,×0§Å‹à6KÜBI–9¶¾Ý‡Šˆù¼ÖÓã5ö”aÕÓOOΫ”ò?>nYª¡ÿäžzj擟 ‚ ´`Aüž{TšÏ<c>úè({Í0Œ;­Ç ðúàƒ~K‹•σ–Í*‘C`ÏÞÀhrÚDÀsî£vÁë$t]W¨žÐÎ�Ãh/V9úX¤áćÙMˆ"2,ª;b ŽoÌ0c®[‚’߈›,Ó‰ð3â@SÜŒþ1·­fÛR‚rÈ!§|îs>XkiQ öð(h†n*å$“†mîÿX,ÌfÃtzÊH¥ÜtÚK§ýL&žLu §Áƒ èééyüñÇçÏŸ/ÉœÚû¾ïéz½±«_Ç-ßqxø'¥ÒÙ¶¦iwW*†ãA0Õ󖆆¶m;ßýî/î>GF^™îû;ï¸cúO~òú•W¶]sÍÅ­­£…],–¿öÚ¦Ÿþ4ûÓŸßv›RªzöÙa¹ÜrçÚÚµåo}+ CÓ²Üc-ß~{0~<¥”#wÀãeb¢O‹B0•J%“I‰ÇÒ×]µD"‘J¥äÉd^¢²ó—)õº®ŸU©d5MÓ´e–õx,öX,vF¥~ø·o¿}n:}øüùƒK—¾¦”söÙŸû\OOÏÒzýÄ\î`×ým_ß­YóÉU«>hj:¤¯ï þgÖ¬ñø‰Ä‘Õê×ýÎÀÀŒÁAÊ’ÂQÆt0Õ+WË6êŠ “X§@�(Õ¡@‰½ˆ*ñ¤’*¡*DF@•¬Õj‚6#bj ëìÉ[|ÎxJþ!L¨ÒòX™æÎd<^ÿl¹Ë’J)ýý÷µ§žÒ¢Ýžç)]÷N?½òúëîȈK0ãŽ;Н½Vþ׿’w݆¡îºµ+¯,/XP½ï>϶=ÏÓ_yE™¦ûÕ¯Z¯¼nÞ :ÜyÖ#Glk“$FÊkd½È8Õî.Y|O0«‹µÍ*rCP�IÞÖÞÞÞÑÑ1&ë¹—ð<à^…г“GÒ8Å“œ‚ű1R ç8Ï‚€?(srä1Î>úyS§zãÇ×oº)9gNkkë§>õ)íŒ3žuÝj>o>ñ„þØcz#Oô¿ô¥à‚ ”Rñ'ŸÔ<ìîv.»Ì›5KïëKÞ}·Z»¶ü ÆÐ¼yúŠ+ÂmÛ"Ì÷/—Ë›7oÆe3—Æ4Í4íEMÓeð% o1Í[-K¾ã|7‘p]×TêÆDBZ1J©ô¯]ýå/{æÏ?>“Ý3mmÏzÞŸ:ȺòJ+ÌÆÞÓGFü‰}ßWýýJ)•ÍꃃúæÍvwwµ¹9 C­¥¥~Åé?ü!l@8¹¸§Å!\/ž¥ÐÁCO&“®Â0liiiii‘„Q^,{œÇ)•J=oj"ñTkë®Û†ÿ]©,´¬Õj;–,9ò¥—¾sûí›FF®½ë®É›7?z?úèYK–<|é¥÷qÄ¢ÖÖ_ô÷« Ø×u+Åâ¤B¡dY»‰ƒ«ÕyCC7ì¿ÿ£–u__Ñu›Ëåºï›¦ÙÔÔ$¬Y[Éd’Ôm‹&#p“¬væÇ³eYBÉ‹DÏ…%ø¸y‰W²û7Õ0FoÄh�¤^#ú„\"';@-nø©†‘ónXÜĉjß}“sçV^}5<é¤�•Ä~>î8]× ¯¼’üÛß’?ž|üqß÷½£Žª]}ìê«•a¸_þ²nšñÇ 4- ‰E U€1].\®™é’4H}cšfµZð¾Üécûv¨^ÐÑÞÞ~Úi§ù¾ÿÜsÏÍåìå^N¤€N¦¬oÿà5;»$ñh!ã³jƒv�­Œ¶¡Ïv#£sŠw'M æÌQ¦©iZ¥Ry÷Ýwß8÷Üé]´~ýúÊùç뺮5ÎMÿŠ+Rǧ”*-XùãÝ“OW¯Ž]}uðÑ:_l]u•rÝæ3ÎUC0 E–Ž(ðñlTþ‚<' "Výb÷¶ˆhæ‡÷‡>ººÜóÎ ãñà#±~ùËÑΖï›[¶8sç*¥Œµk•Rñ>pçÌ©}÷»ÎĉA__Îç?o=óL0nœÎ0 w"U%´øH›Í¶íD"!AEމT*%Ó ‰Ds|Ò«—w+ åryhhÈ4Í“ÃðåDâÁTêŠz}vþÛ¶×YÖ]•Jâßÿ~zõêîý÷î¯M½ñÆW^|1;cF°aÃWÞxÃ9øà>ó™ÅéôÛ–57™l­Õ>ÑÓãÚöÒ––é•ÊGÊåŸ ¾›N¿kÛASÓ--û:Žjå Á·Wî|­V+‹âox CÍÅ{!nbJ•DÄTFM, ôáÄ™H+Û:ëì˜Çr5‘ eæ‘îIªÚÂ÷íÙ\ŠÛûhËÛ¶]Ùº5ö‹_HKD×uÏqFu»iæAÓ4gölÍuµ+>DäÎ;OӴ؃Ö,âaÕñ¼*JžðãÎ.KÞ1¢ÎRiP{’} úOÄàCž{½^ïïï¯V«’FŒ…œ½ÌŽD äÈ}$öCÞ4ŸßÙûYˆ‘‰Ì*/м~™ˆÂþènyí5óå—ݹsŇqÉ’%•ryCwwé‡?Œßt“Ù 0«Gk@(¡çÙ¶í[–+QÖ² >ý›ßh‹©ÝÍÐïáI@ž*Åñqo½ÞÒÐbÐCòçÿÖ´ß$‘(œk¦i*šÀÐêõØK/Y|0<~pÏ=£Å¥aÔ?ùÉÎ/~Q)Õ÷÷¿k¿þu|ÉÍuƒ 4Ó4m»vÙeFìOª^y¥Õ˜ê•R¶ºT™R€ˆ%LÖpÄ&“ÉLŸ>=“Ɉ¬Y&“‘èbÛ¶ÀVкÔBnN*~lL�� �IDAT•’Ï]wãÜæûo™æŸ …À÷­ÿÛXµjÚäÉ_)—~ôÑï~ìcûÿéOæ=÷˜7~ñ‚ æårš¦ý4•Ú™Nïãy[ZZ®[ºÔó¼ÿ:þøóËå“ÃðÓù|­V{6‘XÕÞ>exNAMÎ>‘µgµcžù�œ+åQ$¹án¢œõp˜E·CN8=å81±˜y©#À³ÚŠP«áÀik£‡MÚŽD–£åþRØGpc“7 ¥âG×*|h¸’S+ùGíCÌz=¾rå‡bG­5Œ²˜»Á°h/ 6‚fÍúÊi³ÂºÜ%Dw9g)âz†‡‡_zé%ß÷K¥Ò˜àÍ^Ö"­uà‡Âƒ¨«a€Žác¬éX,ªñžîI8p¹‹€Ý…¹ËH£›{†Øí8ÓK¥’7qbùÄ“?úQåöÛí¯|Åj0Ü×__Z°@…apÀA¸hG5 óÄé§{ºnézýûß×{{õÍ›9…’)Óù¡ÃÈøòaApa<žð¼»îáaÁæù¬e5)u¾ãü†(CÈ:Ùsˆ62b¾ÿ¾¶»`]DW)况r¥öÞ{ÚÈHýØcý3jgž©.¹$èì¬×ë± Ò¥´÷¡žÇÂÃØ´Ò$|2™L§Ó3fÌ8á„R©Ô{ï½çºnss³t$«`æO­VCŽÙÜÜ G¯“ÃPwÝe¦yP£Q'—=§VU7Íê©§ú÷ÜÓôïüWkë%¾ßшM¾/(™ Äãñß47Ìó¦Õjõz}¤T–ˆÕ"g«eYÅbq`` P( AúƒK€Ñ0‰ê ›Ò·‡Ô&`Iž%Àp.«Ë°Ÿßg€i<P ®`�Dž¡™¡�Bs>RH1¹”-5±UÝó!½X‘PÇqâ×\S|õU¥Tê–[BÏsO9EK$Ì¿þ5~à å ”R­·Þê[–zê©úÕW^}U_·.qõÕ¾ï+Ç©¿ù¦H¤Ï;Omß.·4™Lbb¼î ¸KHìX ÷Sr#6÷d6FÐ<SdðŠô×÷ý¡¡!ðÚÇBÎÞg¬L€8·F ÃÌš°fâØƒLûTÐMÅÄôä¡MË#Öðº†ChDé C}ëÖø¨ëzØÜ¬4ÍkŒ)‹gO9ÅqœÜüù†a¸¤A;ªY²Ï>Ö’%º®{ÉdhYX²œý1Õ›Œ”kšæ)5Ãón ‚ÿ™1ã§&lݺu^oï_ …Ó’É0 ÷wœI¤ïCZ çi¾oÔëÏZ_³Æùä' ]7׬1 Ã7.Ô´°¯Ïذ¡|ôÑ–e™«WÛ¶]7¯ÞÕe¬_ïO˜ ¯_Ÿxì1¹ÿ…oÛÚ°Á.•TC¶¤ &ã”2¡477ë&[[Sõz*•ª×ë½ÍÍ•ööVËú„R2 %w¥¦m³í&ß?\Ð’ X˜N›¦9Ó󺕚†ŸªT.N§ß1Í©¾¯”:dùòåÇ·) 4­Ó÷뺾jüø¹Ju8Î;‰D2tMëÔ´–Db\,íèØåûû 8Ž“uݵ¦ÙŸNT*‰þþ‘‘‘D"!ˆ«®ëÅbQrXB¦Ã¥©7ûÇDzHŒPñ#Æ ÝPŒÁR)žXU T7öºýð�jh²w0%6©b P^ ! 6¾D6&^…BArVç/.ù¹Ï @R-Z”>þxÜØ?ÿ 1VóøãÃ0ôT/•×_ÏÝ©ÌÉ'ã0-+hôíÅÒYš$72)ÅÕb*³Ú Z/ï,· S½x²`‚`²G’fx3¢$Šø……œ½9 ЧŠÿX]r¹ É ~H]‚4DÎE.„0vÄ4Œ×3VŽ–lÄ×€/•3ÎÕîJõª;ÝóÎÓŸxÂó¼Pþ¼Á~Vê¤z×]Í'ž8 þú¾µ;sOµ(‚Ù´Ô0Œ&¥ÖõŸpÀô3ÏüÂÌ™‹-zñŃ͛Ïr]]×/òý¥¶+5Óó>ãºJ©AMû½m+¥Îqœ{ ™Zâ'?©_t‘¦i‰oô<ÏíèPJÙ»v¥ö³Ê9çx†‘½å×uãÏ?oœvšsÌ1Ú† ©§ž 0£ðöÛA„ý±'YKv£P@Lbé§>µ`úôµåò¶nÕu½¯«kÑøñšiÚ–åèú§]W¶îrÃx1P©dYÇV«O¦Rýñ¸ïšæ×§ÉqêõzLþOsó©¥’RêÚ›o¾S©•×^;ÇóŽp綬Y3W©Kz{ïö¼²®bdä€j5 ÃÓ+•§m{8þÌüù}3g~1{¶µuY&Ó^,0<ì¥R‚ oMDEËår¡PíWqB–ÀƒÉ‚èâ8fEî¦%kÞ }®V«ìBÓ›¡0^E¨5#ÖË<ŸÈ¦ÜsÂU!‡&¯Rº’~;ëHE\yØ”õ/ØBË”`°¢§ÉCKÌ©S䬨ȿ�ì$æ­±ƒ'³Ò¹×¥vwå`ä#¨æ9h®by@¾ xäc!go†Î5@*4 X2Èšá#I*™ÏÌ@çøC^=2X€ž-AŒt¡íá4Þ0‚äý÷—yDS*ö䓚ç9Çc$“Ö‚µ ùÝï‚ ˆÿþ÷Aد½V¿ðBç‰'Ì‘‘Ä(¥7ÝTüÔRú¢EöÀ€ÛP:ˆP‡Q¨!óŠæ¦0üX"ñ—ã?餓&L˜ÍfûúúþQ­þdãÆù†jÚï ãk®»IÓÎO§5]O»î<×ý½m§ëæý÷‡ ¨!68hÝvÛ(‰÷ßWJ¹¾ooßž¼å– ”eIÂûÇ?¼¿ýM¢é‡rÅ‹A 5„y¦0Ƀ¬LÞJ$Fo¶o¯µ¶‰\.×ÒÒ²&™ÌÖë§oÝê§Ó•qã´F•öŽ®OTêÜz½Ïu{ Ã0ŒÇ’É7ëõ ¾‹õ–˪Pø§eMlioßÙÓ“™3'62ri*eq†Ü^gîÜs–/wN?ýÁÎÎÏööÚ¥’¦iÛv§ÙuÏ,Ö¯__rÝ|w·eYç:NeÓÜ1~|¹\–dVP5×u‹Åb>Ÿ—0#ñFôZ¤ëƒ œ;R‘ çe+LE¦d8×°Âчã 1„õÓ�l*òÐð¨HP‡ dèÃqDÍ ÄD;º€ê©ÌÌJU$â.ݨ_C.{|ôi:kÇE@3\¤ † rð_€òˆD8>%ø‘�Œp‚n+@AYÙi{,äìå–r6Í•P,¶!�ætE†Ô�@Y–•H$í\ÆýCŒvc‚I‰œE¶«ü×ôYgéýoýùÏÉwÞqêu¿·×w]óÝwMË2 #ýì³õýËó<cpP7 }ûvíž{‚DÂð}Õ×§4ÍxõÕØš5J©`p°–Ï#ʲ¸&ÆåV�Ç€¨®ë* ß—iŒjµ:88ØÛÛ[©TTÊYÕfY]axMSS-™4 £Z(Ä•š¦”ÕØ$`±AR6ù‡ä¶’ãK5 ô�X¿\´Ô¤”a‹_~y™4N„�‹ÅƯY“êî&N”‘,¿½½†7LjÄãwæóncšG×´\\›±Ø¥’dÚ€•ü ¨úþ*]Oõô˜éôÀÀÀQ«V…±˜ùðÃæš5£Åè† N¥ò¿Ø}øáw´·_¶|yºèÊCommµ,kܸq(š¡çƶʒ žn’¬U![2 RNOˆsfƒôŸ%nê"-“žüdNHÍrk}˜8º@¸Œ©e­Á/#hæy!1ED¸ÂkXÐósB%@n'¡—-Õ‘ ÊëY9Mþñ:ì A5±¹ÛÊsxÈÛ0o‹È$ IH™¨†ÇÔ9fð;GÈ8¹G…öN§±¹œ½O’†I8w#™šÌz˜u€ŸèY1�…üâ`Ö2 PÎ>Y'£’¬ûûƒ†Ç†Úöíšã„ÒÛ¯ÕüJŵ,Íó¼‘YÂÒ‘TÃÃF£­¢” ƒ@Û±CÓ´°!¸‹" ™pÙÁ}É“Q#MÛP­îø×¿þàûãÆ[¸páŠ+,ßn$}”JÝMMéÖÖc:*“É,\¸ð¡íÛo+•ñ}]×ë @s‚<‡Äb£ÕjU¬€ä@ˆb@ƒ§C¸‡!T ¸‡«Ýˆ¤ó;;¯_¾ÜÎf2iÒ­ƒƒ23áéúuÙìí•Ê¡®{S*uk±¨Â°X,îŠÇ{››Çb~k«ÕÛ;kýú'gÎÜ>~üàŒ¹Ï~\:­n¸áí#TJtæ™Ï™³Ï<÷¥—&qį&OþìúõãFF„ÝÑÑ1qâD±†ã…Š .I†…B¡T*åóùááaiäT*4EXZ‘iÜt�^ÁgkÄK†6åX¼Ž%«#¨,SCå2FGµHü_5ÔÏ$d²%Š-LàC#n{¬Ã«vWY†jxwL³–?—’MSÎyTG£QÒ–Ç»áƒ"–´áo-!pO­xq±Ïod^8 \`E´ºáââGc!gïÿ@ÝYN’zDÈ!x¥Ð–Ðî‰í<æZ­Ó0È~�£“@¢}V†£|Æ»°“… ŠA3ô™÷ÂÊ=@̰“qÚ²˜ "ÝLÙ·¬ nw†ƒšöªR?ܺõFß;‘صk×ÇÊå{êõób±ï4²Èx<~Øa‡sÎ9mmm¾ïçr9½ZU®ë5z¼‘Ž ú[À` âºn<+L6~DN÷rðùú˜”Õv][a½^¯×OܸñýLfgW—æûŽãÄb±AÛ~);Ùó† ãQ]·•²ÐÛ½½ïìÜlš¯ Œwr¹üüG>2’N?ñùÏÏ[±¢eÝ:7þõí·¿ô%MÓ?úhw©ô¹öö¡©SÛ4íK==¯Lž|äºuÓ\Wˆ étZ–Š"¡9¤Òé´{ 0årYþËår±X,•JàÈ=a{r<w|_ÖÂáúR‘ÜÏ”ðUè6B;¨tÈÇY)Š])2$Ú±´¾dip²Á;€i Ò Šäþ¬Æ‘@|¬ª@ÅÌ€Þ¨DÈÁkah¼ÿ>Ã\qƒSö²\?ÌôøÄ`„ƒíScB1H¶!ƒ.<“Î7�°}tÈxÂ/‘HDꡱ³ª<fäGŠl pÂ*š|“=9X™ˆ*gOÌÍG´‚P}ˈ"rCÌ]"¡+3 |‘˜Á=¡ˆñsÁñ-$°‰¢ äO«>”²Ã%†qOœµ}û>šæºî;šöÃdÒÓõÐu‚éÇÉår¾ï‡²uÛJÃ8q\ò` \†¤œ|~ñ¸"ô䯛B™Í†á3zÃÃPà)9Lm×Ï×c±Þ¶¶R©”H$véúËñøÝ¥ÒyŽó«x|kƒ’´¸·w£ivU*Ç®_?É04¥Z‚@Ÿ2¥ÜÕµþÜs»»»µ¶¶7Æ{t`àW™Ìï.¾xéðpý‡?Œ{^s¡ph¹+ž8è Yýý¶Rù|~```ܸqíííÐoÆtQKK‹œDžçÉêÐÐÐÈÈH¥R)—Ëâ*À GnžÁD;D^ iVD† Џ)Âò‘LÉݳ¯#õ(8i¬ñÅ#ø &:Y‚R¬Ê«Z£ª]‘šw"%Ø€ö±Â‚J,:C<gjÍœY=ýt¥ëZ¡ 6mÚSf­¬áýl.µ# uÖ:aÀ AOAHíîôŠøDHÙ„ã[KŒ…œ½ùƒÉíÈ“€•V!L>˜ËÈÖ„ Ý8ØØˆÈÝ ml,`Π^FBÇf‚ð”t 3z6 Õ³† :“ÌžDz µyœ0õ‘ýP­V¥ù]­išQ¯?U«)¥ZÃ0†J©)šVñ}SÓ뺮ÔéôÃùü•Ë–ý|xX×õõ«WŸ•ÏoÔõ冡4Mot†¹”ù°Û©iµO|BÍ™“¾ï>¿T’‹éèè¨×ëù|ÈË+—hÚw¸Û¨/ÏTµªÊeyúGmÝ:¿µõ•ƒrLsV>_©T¾ÓÒò¥N©×Wéú MM-¾ïà ã87,[vÅܹé”U©ô¤Ó<õTw,ÁKù¼Þм²-+}†q²ã<ýž×iš–eõd³÷µ¶Ž«TNð¼˪–JAtuu!”ÊÚƒ‚½4o4M+ ===ù|~dd„e–à£ê  D&ÃΣÿ,x/šƹÚ]) _äLg¶X$»ŠÀbh²!/NmÉíJê0�‰ˆ -ão²¤ãñxDdšm–²ã7 ÚÚj×^›¼ê*MÓJwÞi]y¥žËa¿@§\Öö¬|¼¿$pùЙfŸ:. A[dzÃWƒJˆp’ñ5HÔáa)¬¢1`í?¢ÊA §)æÉÀZ˜ã 0%àÚ‘)ˆDá„SàdK}6�\KyæY÷SÖu¯Ói5i’½zu„1'MEšÿÒÇ1Í1ÈÜLã˲æ$0ä³FnãK¥~ßÏiÚ…;v¼¹k—eYÓ]÷Äzý!Ûv©ÖÄáÑ!ö9süã7/.Ÿw^âÑGZ­¥¥åÐCݾ}»ŒR³"«[å2DpH0R!zY€q(´â'¾ývGGGµ­Í0Œ&ÓüüÒ¥óÞz«·«kᡇzžwO.·©µõ}Ó<¿ZýIµú™¦¦´ï”Ë™Bák‹Ý÷ñüÁ“+W>uãß~úéJ¥rá“OþùœsD²Õó~P¯_ÛÖ¦”ê5Í;šš¾Q­–Mó¡TjÚÈÈm϶MÓ³¬æææl6ÛÞÞŽ§Y©TK¥R©TÊår’»ÈøçÈÈH±XÎçóÒßbn!¸Rzã‡Ï\@[È“dÎC ®<·a€\A ‚+HÈ$ö£Þ’¯Ã´·ˆ±&ûІñ€ðÉá„?&Ô f$Ã[ÖÑ® SàpG !¥á‡­¬C©_rIÇå—'‰Z­¦}ó›…;ïLþö·á�‰e¾—YÈŸ˜.Õ°`ÂÈ2Y›�¹/ø²+™‰Î‚:<´„+Gϲx.’ci¬íåƒÀÀ= úÂÛ&·é ¯'�œ¯°©u…½&Ç99ÙÚ]~`·Î;,Õˆy(ª4nZŒž)—_®4ͱ,íÝwQÍÀj¢XX÷ÒíDŠÊj&áü@J¾~à£Í-¥ÎuÝu¶} ï«\VJ hÚïlû£aØÝجl‚N¯øèÔtóÍaÖ £òo$ï¾;ŸÏ¿÷Þ{ÕjRT€ X6‚S¼Hû]èjÒõ•À#¹$»ïIzË•LÆó¼R©T(ê©Ôq†1·V MS¼IV­Z•Ëå†Z[gmÚ4«¿›® !ÔB¥â螥Óéiºþ`¹¬iÚ¼öö‹ …?'“š¦íûÄã‡ùþß÷Ý÷;Ž“u]±"IGYåryddDÄJ¥Òðð°0¡«Õj¹\ÎårÅbqddDž‘±£Î E³îÀ3t :øœ¼¥vቨ‡á¯X6ò9†‰Xô ˆ"–(øi,}-™"V2?æ’@Æ ®Ì:ÄÎQÌà°Ãœ“OŽßt“eYmmm•J¥²s§}ó͵ /ŒézbíZ©{¨=¬ ¥A` L ¦;ƒÍ!y‰V†Á ?§ÅlðÊšw"Op,äìÍ„³G„œˆ»— × ')Á@6€djR9É&d1ÃŒíbDŽ;FìY‚ …ËÆt]†’išµ[n±žÞÚ±£òµ¯Ù…‚Ö°¤EWRN˜øÂ 5"Ö)Õg©(}°y€.c‘`,7áñx|²R¾ï¿mš7€Ç0 mËzÇ0¼0Ô…`Äé«z Æþû§|P7Œ /¾8NéºëÔM7 ‚m!ßFŸL¬bw›‘ƒ‹b4FÁ …:q#–2888hYõqã …B,•òâñ¾¾¾\.×ÓÓ³£Rq§MíäçyµZ-ï8â[«ÕväóÏtt|»¯Ï4Í µµßqüx<gš'zÞI®«”ʘæMÍÍ?-QgàÀêéééëë. ù|>ŸÏK˜)âR©T,e²Ýó¼T*Å.Ôx:Š<’‘Ö ÂfeežŸåÚ*.šÑ„Gƒ“‘½a×D&á¸ÓÆ��ã½,ÇÉS;€ Àcd§ÁH'µ# ¡ø^àYCCZ:íÆbN±˜Ïçe󆩔–H˜##Ìàgù�4l"ÃøtÁ ˜¡Žd¡EÎT'ò¾¥3ò_“Éäÿ Ð1GÓc$éÿ®ËwÊI*Šâ`L1é–ͤ#˜�#€t`TÅ5 'ƒhíIBe©‡Âíl7ôµÐ«eÁ55Õ¾û]ý¹çâï¼£iZúç?/Ýu—võÕZ?ŽZª�µÄJÞ-òÅå#Dd8 HÅ{Y›ü$‰Mž·Öu݆1U]×}¥tÒ»åÓDÍž­Ž;.ù«_Å]·sŸ}jµZ.—s_ÝÌfë—^j=ð�²Z¹˜~FäÑ]ј ‚ ›ÍÊwt]7•JÉ¡P¯×KA$:å”y/½¯V=ÏÛR­Þºï¾Žaœ°ß~)ßÿݶmñ®®¿ì³÷öÛ‹çÍó-kõ5×´÷öÎyä‘ûÏ9§bÛº®Oöý¦¦¦r<ÞW.¿ày öÛO)uùºuln¾véÒDSSËĉ¦m×jµY==øþMãÆ]‹ ´"…K>Ÿßµk×®]»z{{‡††ªÕjµZ•ÿšz½.Eª�ú²Ì$*˳Å®µP$c?ëeðH#ž~D[š§p$+gIiNù#'#ô°#“×<E &øvµZE] è›2•yäEÄr$¨³ Ó4”RÁÖ­Öí·×î¹'õÕîÐaÚ„ îÿwêûß×*¿üPÌI­ÌóI{V<œÒA|q^lÍ…'"N wùR Ä nÞ¦"¡6*4n÷¢KÛXÈQÌDü°NÞJ‘h?‘±0R0ø¦È?4Bªáw`íöÈBgÅu]X€pφ''Ð¥UÌfÝ /4Þ~ÛZ¼8ÛÚªëúððpì«_uî½7þÀá²eÌÝËŒ×ɶÄ×a:4 ¸ #c†²¬åø;øàƒ3™ŒàN{BšÜõÅÆ“„. Cíƒô®®Òg„=&Éš¦9ÇëMŸž¹ýö€p˜B"/­¶Gó&™LJ6 $@9¶`næ8Ž\­ïû[ößÙ1ÇìèìlÚ¾ýTÇÑ;;o3çwK—655=œNO]¿>?<ܺuë]Ï<sý¹çþ÷O oÛo¿¯þö·Ÿ\²dõ#¼ü…/dgÍÚwß}ãÙ90ðÁ%—l>ÿü¡)S –õ£—^šô4íÜY¸ï¾êi§¹ï¿¿ñé§Û¾ýȉk]L›&_P š\.7<<¼k×®¡¡!aýɳ+‹Õjy £L̤ äc˜Us¹Ï˜OÄÑ�g::|… †Àz D&Ž''þÁ#CÈóÛ¶+• !T�}e„@x1@œJåÞD¡�Å$±1í0šÍ‹©¯½ö«_Õ~ó? Ýo|#yñÅ¡R.M.c¤«=N:#>Üì8€1É™À8Pä›Î‰n&8JÐ9ŒL¡±lB»ä—œVŽ…œ½ðƒi¤äg ô‡„›ä¨R¡^AbÅo…ìƒ÷Þ&Іa´µµÙ¶½cÇy+–4Ç8*ÜaðÂ3M?3GFDz ¶êíõººìÖ¦�Ï+ ¦¢ùÉAsÎ,]…"ÄŒUîØ±CNpHj‚"î+fe Z: õÌŸ_Wªüoä~ñ Ã0ª§œì·_ú¶ÛÂFw9 x4ÀÐF2í‰7’&§ÓiiêÊ–®T*røš¦9~õê k×þñŠ+ìX¬Z­ær9ÏóòéôS“&M]±bI[ÛÄ… gÜt“RêÎåËõÔSaÜþîïìüËé§Ç+•SçÏÿÙ©§ÎŒÅt]ÿÁw¶¾òJiüxkíÚîU«&”JãßygÛܹ¯Ožü•oŒ¯\™Y´hÑ´i½?úÑþ·Þªÿå/…Ë.“oQ*•zzzzzz†††Êåòððp¹\–[$,viGÃ2€5ëõºg"ð»$VÉÍ©Õj£"• ‘:n  ™YìXZìsƒ|Ÿë^ÿò¹A£êjnn>äC¶mÛ¶nÝ: EøCàQ rK{“Wf‹1©ÜOÄfÔ‰[n©wžR*qË-,0Z­VŬ5ÃÝ{¦¶ÜëŠÐö0oÎ&x€M/iV çsBÈùHÑ›6fDýŸRèpïŽ;œÌ½á¼/2ÜË% Zë’�š¦™Íf%¹®¬J�ÚbAÀúWt¡P €£ó 2Ëtv—ïûa__ìÑGýSOõ¦NuGŠwçÎ;Õ?ÿ©¿ð:@B{î/³÷XëòKô]yy ”C»Wîí¶mÛúûû%•–/‚N¸8ãXÓi`âå—Í… s×]—?î8§³3õÐC‘r“¥'åë µ÷- 0R8Êç2•(www' ÒòÑ2R.¿”ûS*•Ä÷ìÞ šW¬øg6û‰üã‘GŽsLᨣ|]¹¹ùØeËî¸ãŽUsçN[·ÎÏdÌRiÿ‡ªÕiW\‘Y¶L)UéêZwæ™M[·ÛÛÓ»ví÷úë©iÓtÏ[ýÎ;ÏNŸþñtzßÿþïøßÿ>44´eË–žžž;wnçÄÒX�� �IDATܸqíÚµk׮ݴiSooïàà D>Ñâ“|0< 608Gf L‘0—<Ðpa¼Äm3$92€,÷•%tdãy n·` ­"ªØ²þEƒYöú¦<��ˆ ƒGèÈÊÖc7s¾ñ¹(°ÁãéïØa<òˆùðÃAO7áM‡þ¥Ú݈Û´Üx’ ûK‘s |Ayj@¼™þ‘o`«Iý”=‹Ë±³w~ÓñL¦ðPåÌb764yš]¶Y2™ö‘ðÁ áÎp¶(}±:µ®ë######ò)rh=gAIÛ±˜FiW½½‰»îªÿûjŸ}´L¦zÝuæŸþ[º”ÇÜ©•J%ɼä}äx’·Åûã#ðç̪�± ³Ö‘þ–¼²`ajÊœ˜ hzÉ)É3Ö¿ÿm¿ð‚àÖxù<+JɇJÙç8ŽœÂ‚A¡wXú=MMMMMM’BBÇE^Y©Täep4H$©TJ×õ˜m'‰ &Äâñ³ß{o—m/:à�õ¥/ßÝ}Ý/YìîÖ}ÿE‹Vxà†3´ƒšÐßÔ‚›gÍJ‹oÏœùÞUWå¦MSJµ¬]{ôw¿Ûúþû›fÎ\öÕ¯Z…©7Þ˜îtœ)•Ê>ü£¶råë]”Ëå6lذ|ùò·Þzkùòå+V¬Ø²eËÐÐP.—«V«8}DDYQÎ2YlB…P¤ƒ0 #bet֣điÂóñ‡eÀ=$asaćeh… KDS>bdddéÒ¥Û·o‡¡¾¾ ókP¢q‡×Ë›D<âr€æ àÆý˜Ñ Š;ÕŽÜm…`D„IU“g¼þÐr+dc¹²›§|Mæ7! ÀÅH"%ï È=Hn,"êû±^ÎÊh·²căä-`P<BÎ2"¶T’VˆP&ø õ ?sæ/Êï‘a1Æ ±,†ƒ%ðšfªŒçyf±hík¥{îÑ·l1ßxÃ|÷Ý€d@BÅGë"µr|�À€*†-X  ,ßt2eÛ°êØz<CqÀ;ò</öÖ[ñÅ‹åÖ@˜Râ`@è ɽ<!‘H`Ks”N§Ëå2¦+€«H Mâ¦i¦eeS©ÎÎNË4—OšÔ‹P,Ž›1ã … ;^~ù÷G}é¿þó¼íùüMßüf“ëþáškvxÞßÿþ¦9s¥úƒ`r*¥vMšôüWœtÿýÝK—¶¿õVïA-<óÌ/ÜtS²¿¿ÙóŒrÙ5Œm##]ùüÊ•+s¹ÜÎ;óù|¹\´R¯×yJ92Ro©ñ”¥à„(%!$|œé0˜TJ‰÷Õõ ϫݭ±`ë'ïÖÔÔ”ÍfÊå2è^\I¯B ”a¢€51#“=`I}æ$Îq‹8“0o†7ƒcX„’Ì!|b&@bÄ(Á5c"Љ6jw½œ$£²° Ò üW6ÐÃï1(yø hª)ROG«lï:c!g·>¶¤É(KYV=â8€]Ä¥+\î%Èÿ.^ÇìiÈŶ(ÛŠp»>âÿŸ1yC¹~¾릛ô~Ô|í5¿bË•ƒÃÊfŒ¿«=Ô×÷´æåW2‰—5×õr,J¤”íÍÍUuà³A›ìs&î™QBMD¶±üȵIVa^AŽyÀr” Øv†}}}µzý¡É“?7<<-Ÿªëétzn¥Rjjª%/ŸpB¥R9ñƒŒ\zkÎ¥Ô™3^³†Ô¡¡¡ZµZß´©ØÔ4óí·ßš:Õ÷}U.Ëý×j³—/—Ëeßßàybñ É8ÜY hƒÜ…›ÌÔ&0µ‚ H&“h}s’ùÐÌãŠìæ}pÆ‹‡#ž¹˜Dý:Ž‘šÓ8,u8^#<D¨¡)^îè@C/2,1æa (,x ŽŸ";Þ­ˆÁ,ä‘¥{1¤É±§V«% E6¸‘ýˆ›#ï á x~CÚÉ>)”GÆÆÇ€µ½rP7HÖ€£ <~MáUµgÁŽ,Ù~xO©Ê#4QvÓÛžçǹÃr¼˜(ÕøCØÀ€õÒKzƒìh½0!B.•8¶‡˜‹ÆÔ´´O¤¦aSÀŒØÉ{æƒøA¿ ýô]÷$›î):�³ é.°c,“4¦“ð/@°ÄW–Ôjµx<~þ»ïf’IÙùÞ¦M)ß?²X<«XìhÌ$­Ÿ=»’J¸zõ—Ÿ~úžo~3Ó×7mݺÃ7lè™>ý ;¿uÛmFÖ (—Ë®ç-:è ÍMMJ©c^~ùñ3zÓéû?ò‘ ­­qÇ9dãÆ5®»¹PÈår¢jƒ6;-Á�Ã7˜dNY‘P4xÐDDÂÎS¢‘î7Úx=‚Ç-Èr —Aë9ŸÏ÷õõ‰þ:[HŠ€†9rFÞ°rx&LEEÔ9²Ç(_|Ä…ËЄ–3ìçõÝ-Òq9&akˆð9R*@ïÁsèªbÓq¤g¿4VåÎCÀ®H�ü¥&æÁX/ç?‚>�î–t5¸v‘¾4†l@2áI4FQÁP*ÂŒü�hüÍ8Sò± ‘¡°WŠˆ9Ê' =Iˆ4ª1­©vŸ×“Å-ŸëÙ'rÜ�dÀæ””JÊ)žªÁL+°„T$\ÎCœMºßŠÜ†TCü4•Juvv …Sœ¡�Þg$DPÒ¨ ‰“‘íÂP“†‘N§S©”\ðÔááÀ÷=ÏK&“‡Ôj×oذ(™t††*•Šÿa¿ýÆMŸîN›¶lÒ¤£–-ûø+¯\|ß}SV®ì=úè]ï=ä)ÿø‡ïûO^zióÈÈe=Ô98/•–NžüÏCÑËå×®vÝá\îö)S57ÿ×”)Äbƒd†2Qš hÆ€ƒÄÔŽçE2_ùA“@‘[»¦Bé?"ˆ€¹+œ³X$Л�ÐÄ/Ö«– %QÖ2 Û²a$ÁD,É0l b�(DÀè‹8ºàKíi×+';¶3;Œ°›€RªR©ˆõ�û 3€ÉÒ¥jwP™¸‚ »"‹H¹�{¶Š@® 9: ¹G°kcÀÚ‡ˆV6›­T*Åb‘ °@ãõŠržå+¸ƒ§v7É@õ€‰˜G)‘bõcä-Ò™—óZ€;Öjd:;/p‹… 5�ƒ"o>nܸT*µyófÁsDà ŸüÀˆ˜çµ.U#¤Ú#úÄbŒ–L&…'†‹+wí©’"îj«ÂÔPMÙòé2‰¶†qyèoÇãq¡·Åb1Ê!!°,kv¥RÒ´ãñ³‡‡—|ô£ñ£ŽÚ·V»ö·¿=ñâÜá‡å­·Î]·îë/½tìºu'=õ”U* Ìž=0{¶†¥‰så•###…Bá+o¾™(—ßèì|ओ*•Ê„]».X³& Ãÿ™:uØ÷US“"È‘ñ1.&¸Lä4Ÿ n(âž'Î’”`ÍãÈFˆ’'îyžLÉ`¢ðLwd}J9ζfŠ ¥ÙÆ8Ö’„UPyd ôv/ 2K˜BŽ®?ۯᯀï¡õÂD2F¥x,Fz�°ŠÌªY}‡´xföCê@òÙŠìAð`ñ†rsxô‚MÇBÎÞDÕ<Ï‘5Ç´w–æ=Õ/Ë I%pj¶]B�è€'ã¸ã Ü�îLHÌ Ž8沎:�7®„@I`ï^F½±Üåõ©TjòäÉÝÝÝÛ¶mÃŒt„P�7 -ÖcæN¦Ú]›‡ì´––ÏóªÕ*"¥�)2¸Ã<ŽÈ˜ˆÎ¬·ÍbºŒ¿Éo@`…A¯ÔT*…´Qb¼ÐÕ€…JeP.—³Ù¬iš3wî챬ßMzX­6Õ¶_µ¬¯®__ªT†fÎùøÇ'L˜pÎŽ/L™bŸwÞÄ¡¡x,æºîê“NR®›(d„þOÇ'»dzž·¹µõ¦ÖVyvi¥„",ßKì¥Ñ˜‘±ðY"Ís¸±q2Â'Ž@‘Š´‹äœ•¯/qA‚ýŸ#esOüÁC"Üž6Ì¢FÇý|5“mÛ¶ÐÄ¡7¥ AYÿÈ~Ÿ¡Ë1Rcn‹@XøèH»ˆåSñ!•ÄŒÿˆc74à#³«Ò½§‰?—ù¨àã¡Øåö*T¨éÇk{ór–’°c4õn9† ‡AL€FZâà†rý.ôJ&ÎG¸^B*k¤³—S’0år³=q1†y888—¬ÕjëÖ­Û¶m›yh¤£öBF1q�q“w£j([³ç£¼XÎwá%777ã)`çðõóÁÊÅx,/FGAp¤Éªa*†ßð^“hQõÈ!"µB¡P)«Z­vP__¬X<¦»ÛíêÊdÊšfFWWWwww6›íÓu#•:¨­-›J‰baÕjµR©$‰L&#¤8Ã0ä>£G- •+“Á"Õ röoÌ«Hs/âlÄ„ÀÈâœ=–äªV«<±‹×9OaÌLE^ùò†Ìõ@_u�kÆð�J^ €i¬Ï ¯IV€Eé�ÜBíî]‚=ÂA;—G_cÀóïÏPöš¤20¢FS‡õ„&7ëú�MEJ²þÁ•ñXÈÙk!; ß`ae£K) Œ=bi¢W!ÆÀÈ1FŠi¯È<x“8$B-Œ•`ydøHtG"NSÜaLmqpìܹ“ÝH…¢ÍƒÍ|¾ð("ކ=åè#æZHrÃ0=Êl6Ç …³xXÀô«X¬\žyÄó•X„˜Äb±b±ÈE¤¼C"‘ì^Æ„ þ#6íííB”˜aš¦¥r¹óvì¸eêÔK4mVSS6›ÝlÛÏØöÿìÚ•H§ý†¦ŽÌý é%Z5xîòàǓǔL&aw/cn¨0äëû¾PžÐØ"Iƒçy¢ÃÏ8w5ä}DÙ1ž¸Ôߊ$ÃQRG0dî«ÉdlPÞ\Ê&¹ç{røÑJ”/%ÿ@–ƒæŠ<ALÞÍ•€ª.4"ºŸi]ü茺@“ËÒ>‘I�.ÖQ¾£°ß„0s€0-;HXŒÚ©†Œ:ÀvÙAP Öþ# L±qßÇäÈC±ñý”ä‚‘žñFÿŸOChN£þ@&Y6¨T*H $æAº_>Š'�ÄÐóƝ!à•ø[| Wlr%g£²¾‘ëA‹ßˆ9@ê0 K¥’a---’Mcx‚%ïذ##>ˆèø¿ˆß Š‚þ ÚÀrÇÒé4¶. <D’î8Ž ¹ril ¥R)+ ?=8øô”))ßmû™Xì®ÁAÏ4ƒ H/X  …´ï×'‚ŽJ%ŸÏËhQ¹\Þ¯ÇÅyZni<äMY)åJâñx©áP‡‡.¯*kqb¥IÉ‚ƒ Ok˜i„œt³2ûÊ TåÏòÉÃù‘)[8}°‘3:Ix ˜˜FÉ®v·2c<  ÓËu¢-uˆ} ¦ŸÔ¸jwÇ.€`Ÿ(@ǸÀt‘¹–Ëâì ì2~(!y¨ØŒPÉÂF*‰" ¸"+Œk{Ÿ±Æ¹ll ] Yô’€ÀgP5ücÀ•†¤5Ð+‚a69Ôp±»˜z€#€›ŸŠ4ßаÅ�ãžúµ<د9ÀJY¾,›fD@v@Š!_DF:p“+•JKKK6›x ^>¸Œã3½wüfîš‚šÁ²˜Î“~€T0•JÚBðº†o±è4;Ž#s-3|ß/ a.ž<9—J¿sç?ÆOÛö÷ŠEòûéOÃ0,œ}ö¸gž‰­Y#¿ÜrÜqÅööãŸ~úµcŽéùØÇ@|àNƒÜ¢x<.ó’¸Ï þ2¯ËàŸï%b, fÞÜçãÖ#Þˆ« Ëç°â'?Y�8°>b©4Ä pÒ(@RÖ¶mßaã(–q“bâLøÖèˆðìxŒÜª‰ å*/Ëök,¤ÈQrpó Kˆ…©ü".ÀŠqx#ÜbòTV2† ñ°’åh�°“’¸0 9{‡> «D`+ž’aåW�¦‘Þ£$Ü'—F:ž+÷Z™šÂ/`y]¤!H¸"ÒÑœ¯ñ¹ÃBL8|9áÅ•°É»¡°~W$LN’>‹m(që ƒÿ“o@Ï###mmmžG¬â9dp¿mô±[qh¡ŒËeÄãñL&#˜ià ˆ±²$—Tl–e¥R)©$¤Ï!ÕÀÛ&”3™ó KÓN/I¥ÊšÖªTö…¿ÿ½ÑÛÚvêå—Íþ~¬®ÖÓ;wJDimm•²F†íAxÅÀ «9ÀÀÔA†+ytŒ‹f^Š‘@Åø‹nàqËÙ-‚x9ˆ+8—yÌ2.ÜXBu‚c— ©®®®<°··÷ƒ>u QN¸ÏÅR$¼QN“Èalc!+bª{ÅÊ5ïȱû8åâD ä –`“_EêlÉDƒHœ–HR[©Ñ™5ÃcÝç€%.&ºÆ€µ½Œª±‰ž<?Aãpóób È—J%ÀÓLÑak,–Ù@iÌD,2ä¡’¼HHC«Fí.´ƒ¥€eY"-Ìp ìç:chhᒘƃ[$÷ļ5V‘àÀF¨³€†N˜¼³eY"šÉ¼�IЦå¥jÜspI«¼¿ØçDô©$}–[$wRÊ!F»®+³{’7`ÄRxØRß 1Ê TêqãJ_íë³u݊ŦÄb?©Õ.ojº¦P8`çN÷œsÌ]»ôÍ›íõëƒövwâÄþoÌiZ÷OÚþæ›Îtttˆu4W¤#] S¤›ôÞÑoǨ øx˜gba¦0A¯‘v;âò /ƳÆ=çeæV±4”ô~xæ¼$[ˆ øt¹ÿ“&Mš;wîâÅ‹W¯^}Ù˜=³ÞŒÚ]Àó[ðˆcè¸43åñ–G$‹`ƒV ÷~ðzÛ¶!2$Ìo€Éœ2`ˆÜž,iƒ®#óØ5ÐäFr [BN¬ÇBÎÞ©rðˆà9¬p‡_–>à,$ãòb†"À1Û`i¢æåó4®‘r�ŽxT]8jÑèÆJ匆Að)¼4ñæ,ØÅV¡(ç—±m‰"ά™¡H® "ËB N…ÁOÔ—<a «o@"rÆÉ~–D0 <RˆÈY,î8ÅbQ*@£rÂ655ák ´"³Ÿ ’IG„覹vҤϛJI9eY–†§ÖjϤR×Fhۡ肟sNéºëŒjµóüó³fÙɤÜíT*ÕÜÜ\*•p¦³s6°/âBìW`qBsÔg> yúÕâ„<AÉxÐÞCï=?íç3³)àúóÞÁF›³KLÉ[ÕëõåË—oß¾Ó ìhÉpîž´4v‰e»V‡ã æ P¢Efe"D5Ö P¤C£vWÌDõÉà„ì,‘”Eé ÛiÖÌekŠE…¡W¹‡œoÁ É€;nJ…œ½Vå�,âøÁ³LXD#‡]29< @}ÀÂJ<‚Ç+‰ƒ: Ÿ¤û­G � s»Yämßsg‹Y@ó¡JÍf›ššúûû¥)™�¶nC2Å‚=Ü9cò7„Âùá¾+¬ÜÙåÜhÙ`¢æÉe4«•ÉCBy<Ïçóðµ”lZ�4c–›,‡©¨ƒ äìÍ›ÿ¹Ï>¦ëÑàzü9Ï™æå…B†ö“OêCCXf*¹ûîä“OÆÖ­“¯³íÖÖÖD"Q­VÅ�Û÷ý|>/G†Tc :Ž#|69tä¾U*ŒLB6›+˜ €ÈÁ¹Tè·BéU‘v™Ú}Î1bÄ ‚³:±GЬ�“ßœë¥T¡P( Ü.ÂjÄ n!¶C^˜ðk�ã)@ê°$0ãjü؃KpX2‰¸-¨ êW å²"bÏö$¯ÂÉ–&èòÜËùáÅcUÎÞÿ&1÷ô�ŽTƒ†?æºÙU"ëëqyŽqež<ˆŒ¤aßÊ>à†2EzÝì†Ú+cNH>BvšR¨¬9µWˆUCôp£‘<²|D² ‡aðÝ�X'…t)ð†<ÍǧլüD*3!Rƒ$ÐШuãU³ë•JE>ZÄ€ÞH|â'fÕB†$¥éº'¸î3ÐZ*Ï'“ƒApA¹,÷3ýÊ+œÙü?öÞ4NϲÌö½Ÿwžª’@e2(ƒSJ£¶ Ð-*´ÃÑ-*ÊÆm ÂÞ*6ޏuc{œÚÙ¶¥w£í<€CƒŠ‚‚Ì C!„¤Æw~Ÿç9VÞ?«îrïO»wù;§ê¿P©¼õ ÷}_×µ®µÖ•eÙ`Ï=«…BiãF}¿V¯ONN¶Z­n·Ûjµ4l[¿EŽ aì,É…éXÔ5+² j cKÓh Æb!0/ޤÇm™È‘Ý@uQó@Qpqåê0¬6…hf�Aœ•>f ޏV/=T6š DôUÞ{×*"F"ÆâóÖ.d"’¼¸ŒZE;½¤z{ÚæÔàÒD{[��bˆçt$ìx¶’¸xÖœŽk-ÀùÃïr'ÓJ¥":8ÈùrÈYJ]g:y®ÒF·ACuPC楜TÉ…Û} ÀÅɽ5ñ˜BlïÃÞ‡èâÒ+®V«Ífs4ÍÏÏÃUÃIÌ}9]pã„Tuª#à˜Š›CÙáKÕjµÓé’Ú±c‡¦¶Dî‡~¼2p®•KvÔkAuˉϩGàÄsEÑZª—.êÖÔ{G££',éªU«‹I ŽŽ"‡.{ffFoªÙlª¸Ñs“ÇšÐv»­øÝn·ÚT«ÕV«U Nïv?vÔQ/6‹gÏÎ …N·›t:+ÇˬþÉOæ{î9wúééB/†ÂØoBLýÒN§333£ [µj•.R‘²Õj)j@C«ÕšŸŸW€cí…B)[—ŒÁ4ÿÊ 8”©×ÑÿÒ!€Íïl4�ç`CÖùCd}ÍÚða¦Zö¤n…BAo\¨&ñÆY‡Ô¢þ¿ ·YT-ºGF$ø(݈4C¾ýµ;lW,²SÂGÁ�"yO„B߇WÁž€¯¡C0vRd¾E¶G;Í‘:5ÿ¼S»r–²¾ÑZ_,?Æ‚ÅýðɰèûEØ…�¸aX–ì^„…öhŒú IgÊà“}è5Ÿ¨dpªu·’\I—Û#ìmív|_ï(ˆ"A› ê¨/J ð7oäºYˆ÷~ÂXýÇßò3>YQD7®ø­°Q<&F lÔgt€¤üW$9…[išêd'ÍÔ *öèô‡­V+„páw^}ÐAoݲeX*åã3½{ôÑÕ»î ÍfÿyÏ«^qEwv6œ¬Ü~{¡ÒIÕÿ¸`.¥: UwêõµÛmˆZív[\•R©´råJˆK¥’l tc8 \£'IÁ ’Lu.ê$x°,w#æü•=ß÷<,Œ}ÓQ®DBo&1‚,˜=Gdnë.sÐm`Âîsf¯1w©ÀMÃGC¹I6kwNŽuP;̵õ¯ð1ÁŸ F¦òn¹ Â+šµ¡Û§¦aRªÿ[¼ Áº}’oä!´r–æ Ñ"aÀs4½$ïC†…Fœ®‰shØ'UÓöìÆÝý\|Juâ\Wá8ݨ„´ ÿ<lS­V•òø˜wŸ¢Cœ°¤ôµÆŽŠtk\‚à:ÓÅÍ!'I» ‡Ó£A>œ€|” ïam9˜@÷UŸÃYF,Ô×h³ÙÔGA•–ï€Òm%­ô6JöMi;»sç_w:V*…BabbBqzûË_¾öŠ+J£QÞjå¥Òê}èq²^c  ½Mi UúÈ÷FÇZ‚ü•!\¬Or—Xm~Tù|eŠ ÷(ÒÓ†qÞ —äX(G¡ü‹È!×j¢ÝÁÜ xtð!~ÁQkµÄ5FN73¤�iTOˆÛÉ”)¨›l¯,ýv¼ä]äb³`*QŠQUámûY¤¬Ëí®]çƒå³ô¤5?.}²HX(æ"À(Ù÷¦kˆ.®Ë-9š¯iÈû|-Ùî{ß[ÿÄ'£fY6øàócŽÙ…_xaõ–[È篹&o4*ŸúTáê«98zÿxã‚ Ò~?I’¹},;ôÐÊX¾ür6’ ŒXŽ‘ù âj*3F°8t†Eh²û2D6ï®?uÍ&O^öšÀ˜sÐ*›fÚ‚Ó~8k’$iµZ:¸•²'õ{å:#Þ3n¤t€tj·Z-1• ö¢«Œ(—Ëú-›7oöž–^ýììl©Tš˜Ë²­ÿå¿ìv×]_~y!kµþÜçÊåòÊË.›?õÔÎÙg§{í¥Á‘NÇ_P©Tšœœt‡´¹¹9´»Æ)xiGÓÃ8_8…) a¹ÜX«bª~‘J.ŸÖáGQDÔm6±Ÿ [ׯ‹ˆûŠôTm ç�ëÌ5Ëî•sÒ7£ókÁìp�  ! p k‚Ÿó6µ†wê"o-*ìÔߢ­ë”Ö<j²\¤ót9àâÝ¡ÃPw«[9Ko”ì ‚!{…Lš½u‡›#é\P}às™¼ ÑA ãkpôуË.Ë:¨þ©O Ø)]rI8,î¶Ûè­o­ÔjÒ«&hœh9�� �IDATIÒýØÇ*¯}m±Û]ziºeKí7¿I''ûo{Û蕯Ì.¸ „0xÛÛJŸúTeÆÁ«_Ý=ýôú—¿ 3ÌÊ›œáÉñ ƒG,jØ“^!‘ý9ƒ("A)¨PÀ!A÷<O0aM(7Õ•]8„�—ꅔݽ›¾`…9a3==ý×`0˜˜˜@Û¯x£Ÿ›C«E?¬[ž››Û“¯¾ºX.’¤³nþjõ%—háuŸúÔÒ¾û …¤×“zc8¶Ûm€&)OÕ?WSŠP­®kp¾€CIp–¼éÔvØe—]Ž8þy“Lµ—D\Ê/˜jƒ£ I˜Ógæ‡1tpøN͹HãÍy<8Ž2³æùîvêø9ÿV»ë ã L t³gÿÂYŸ/€Àˆ@ ˜y³¢Ý†a‰üÏuHQ Ddzr–˜> ü„Ùµ/®©D0̨•µî# ”ñ¯Ô à”×9®Ä]¢‡7ÜÐxÞóº_ÿ:Ä’,Ëj¥RïÙÏN:âo~3ƒQÕ¿û»B¡>8›+oÝB½àáÑG ·ÝV,³$©|üãI’ô[­|·Ýª7ßÌfàð“q)�‰ Ï…iV³Óœzëh¤[öògI)†G’K& ¥sLDpnnžçy»ÝžœœtÎ:e <@WþúùËOjžñ†#CO£Ýn“y¨›µT*m|îs7>÷¹+V¬hµZ *"X‹vX¯×óq«É«iŒ –èo±4ÕÛ™žžVý¡ì¡ÙlÊ‘šœWÇ=KDF[ïõáõz2žÈ/b(йtF/•(plï4p¤FFGœìÑ$’6²îã #ìÁÝ\›ò’Ë'ú85€Âhü6‡;�Eç†R¨Ú¥æ=KÊ8újªx<¨ø´†ÿº{´HtÜÊ-reŸÞlF‰”¨ÿó_ËSAG¢½®÷b\‹žÃšñzm>‰„3—l=˜;-+8"GÞ(Â%»í–uTáG?â¤Øu"ï±Çèõ¯¯~ç;…{ïÍ×®M9¤ø‹_ú¥i:8ÿüð«_%¿øE$ôè`«“oó)ÐEêøÐü7ö�G"ŽJìÂ<P §Òé™ÀòÉÇ®í`»â˜âÚ Ÿ¬¥-G£•Oä &¤Þç”@"­€_¼L‹‰d.�êv»SSS=¸©^¯7===77'^¯þJL3ù ¦`IŽÅµ¼ôKµäð«×܇f³éƒJ)zÊå²Ô©þF@Ãô´™¤©.”ÎYW1óyÒo—?þoP®ìŠç ¥‡‡¡ÜGƒ¥å{ÁS~˜)ìGÇ Ù ŒþŒ†3ѽójÏmOµ„bQRøNô¤\x=h]‘–¹ôÛ7£/]—ì%bùXz×3ñ!)ÞÅqœ“\ÂÉËUÎHÚ‡éúü Ü;Ȇ�mœc꙯²T|D´ÃI·uÖSÂë¼s58ËåqÍi£‘=ñ‰…[nÉÆ´ý]ÈÌe—Õ/½4¹ÿþ4„ö>P~Ï{ < Ó¼(.æ'?Y¿âŠâwfã»p»{·*ñÄ ^L¥†äΫö^0šSbhQ»@Eá¶=ž”Eì g¨“Æ‚ó8æ©íÚívu‡…Ã`$•øÙ¸ìW6b»ÊèÏ:Ylt‘²Á^,ò×1¤×7Eö#´0ìÕoV –ÞE­V#ã©×ërWR-´ ÌS‹Š~·É“áó9Áá.âëUdzzZ&±™µJ?‰ð@Ý …í@Yd,¢!Ó‰‹²Î¼wN Ì7ð(°;ˆÅnOåò¬`~‰Ð¬•*Êb¢ás4x¶a‘¥ˆ¸ ®É+¿œéçL¹¨±1hÔ:ÂUË Ú#_Dg@ôz=UÃ�ãÚ1Œåó'Qëxá’÷cÖ‚Øqd¬Œ¬d‹=‡‰õ¥ÒaAóScÜÆBœÁÁ|0r@éýÛ¿5Î8£0;«Œ%Ûk¯þ¿˜$I¶n]ÿ3Ÿ©ŸqF÷²Ëê_ýj~Ç£…PUdçC¶»Ø±ÍÝm™ÐÌ5ßóÑäì`ž=a¡9•ÛGB5üé{¹^¤^¯ 5Òte Ñh(Æ{êÇ̺ÉÉI%¡ƒÁ ßïË?çLØãÄä°Ö•ˆ×‡‘ŒÎÜB¡ s¿ÕjÈc2-þÔa²0÷Í“ÞBצO!ˆr [rÅŠ=Þ^¯§5£>–Š**p«Ü|L?©Ožššç8§×ójè+p=¬m·÷êQ»Þ[zAz2îØ¹L¹¬Ò11^Nªö±n÷Aˆn›æÓ NN¥ñp…Ve4”üþX ™|=/öjsÔ‹xOõ¦Uáîp,³sA¹£Šú|—-h[ú/‡\]©àB„`.{¸ehaq`qv+GF“Åurdd­ñ?ÏóÄ\üò<o¿÷½Ï~P[»ÙL<²~à ½bqxÚi¡Û- ù·¿Ýü«¿Ò‡Ì~ï{µ³Ï!dyÞÿ«¿*<éIY–•o¼±²~=°‰Ï§r[DÑJ©è»ê Hʬ'ö ¨k^>zýá g†î‹ÅÝvÛ­ÓéÈÄn´&ÙpÒ‹Åf³©¡™Â7@W¨?<u¨T*ªBŠO’ˆjø!ÁIº¶êÞEPÂëÇ«´†*B=Š•+Wª¬QCBŽO«ÕjªŸÐýÀšÕ™«&¤Îën·+k£Ñ(‹³³³bFèA—æ“ïкx”ÎTÄŨ=LwIº Qh–Ô‹nI �€55ƒ ÉâÄ@?ßÉ»Jt<ö0ʲ>M&šX„ 'ªi〬;²k 6VÕ§¶Ã“tW' pñÝy6˜2Ú'FF…žƒòH½sÌO­G.½Ž%¢Íâj©áÇ[9KÉ ða6X( ÝH-šì½JD‹´ß}<'¬wÈÝqíNõsŸ+u:éx–TñÃöY¼»öð'?9Úc]œŸÉöÑÒ4$Iõšk²'?9O’<„Ü¢‹²¥€óç€ã²‹ÕIÙ¸)d­ÞŸ ¸âqK…G_݇óùÚ!;vì�!‰NLÈåE]n7«‡K*{¯×“Û‚J48ë÷û‹vÛm7o½ÒÊ–%Ó³,Ëä5 ²¥bE³ÝdÍ055577'BA½^G ¬F‹—:.ðƒŠ <Šk%àƒB¢ ÛŸœœÔ²ÔmêQÌÌÌ„ñ(3~ûÚ‰3 O¬€yè³Y•HÜ‘Ï}ù\_IÝL¦€ªK"I瘮2Ë5aî½äj÷ETÊÂfÔjÄé€qH8ƒ™Dš'ÎEí¯¶aÍÁ„¦*õ ºJ²(b•»Þq¼0´Âñp}Ž3ñHšqÃb{‰{2½r–,Þà�¨�àÐë(ƒ®5aÀ‰K|]Î aÑçT*•Ã?<MÓ»ï¾[Jø<ÏË×]—$I¡\Ö•¿óôÖ©©âO~’•J¥ü —A•J¥?î^–¾÷½¤TÊò<¹á†ê7Rf«lØœ>.ªè<Í ñÀLzN…Dû×é¼Î8 ¦þl!û“Ìнà88àF ×Ò©á-]Ù¿ƒóºÝn¯_¿~jjJoa÷Ýw§W‡h?˜¼T�ѕ޶ÛíF£!s6g±•’$‘‘Þ¸H_Š%€<ê·;×@M HºêHû\;7ì" VØk4ÊýqtöæìdØVXçyKÀéÌõ³ks^5Ô,•wL|pÖCÔÞ‡§«1ØzbB•½‘ãëÄÏ}!•” ŒÝ¤W5VAYq¨ƒX <,œ–æ¬LJéq:ò%!À“-˜°w •Àÿ$‰™ ;ÉQ‚¢ò…"?ÁäPb•S Üÿw9ä,YÈq£òn°ú]Wˆ[„(Òmjy¨ÀÞÄD9Ïó8à¯xÅŽ;¶oß®s D :ƒ[±Áîe ŽÒm TBN_A\ :Œ Û}Äg4ŠÌ!G5ØÌø<lxàeÒéÕQª¦ç;€˜!«+ý“ùùy·*Á_ÌQ™C#BR¤ ÷Ýw_¯×[»víŠ+ô~¥ì‘Û Þ0ö:·_Ÿ)“AyR›ê „ ‹lµZ{î¹ç¶mÛvìØ1âÙêÕ«Á]ZÔ1šŸŸß¥µêvÝïÉ‘>\.Ÿú߉‰‰ééiÞ.ˆõÀs6 Z^ûÎEz@$bžTAM†Ì~$ k ù )x¬›G`~µÉʽ‡Ïõp|Ã&p·ú.Ê`¡A‘®vÕªUSSSr â'µø]^a„ÃJÀ PŸ,©¤·|дéiè¡I™ÐíN´æUa�@‡ãÚ¨Ÿ£àö Ãú4Êwz˽œ¥ÿÒKâ`…gB®lþ.«{:å4LV8Ê•€ÌÌÌ|ë[ßj·ÛÓÓÓ<” ”EU ˆ&n‘–¸“KJ¥¬†‡K‚Èòè*ù|’&ª§`@çtg÷WwƳxF ·zŸÉ÷·F„Ê�‚ÃÇAl‚hPãÚµkCÍf“|‚MèÊA?ΉT©TT‘È„ [_*­‰‰ ½£v»½eË|‹»ÝîÌÌŒ¾ lPÎkʲޚÚ3È,�ß}ÈG-6 ‚ f˜¹ W DâîÝ5ŸÓêÏÇ»Í{3h.ºšKÓHA8ôÑ«1•gq‡½ÍJÀ×xÒÔÚ.•J*„vâ%S@Ø{ï½=ôÐ[n¹EÚØD«0vU�œ¤+³ø°&W[<Ï ¾ ŒpÈ ƒ²Ê3o§ñ¨Ç38r.>å©*®ó™–½øf—CÎ|±¶Ø`né sn Yz«Ó§D ›F±xV·{ùØ.å‰Ãá[ƒd4zÏÖ­¿žf%éÏî÷¿V,>–eyž¿a~þ°4½µXüB£ý×£ÑíYv÷Bm%£±XÙјHïp¨q ‘ÒõÄ)ð',´r:¦SÀVþp¼íI¸‚,õT#v™·FIQ} R|¡ ŠÍªWtbÇK°$*+a—ͶÓPäa‚7‚ŠÑNGŸ 9ÓÓÓÂß°Ï ­Vkbb‚S@ 8¾aÔ=r—ÀRÌe¶�bâ€/¡Ü÷GKOAWzè IY€Â<kar¹Ï0Ô£UÇT} œ®ÂíøX÷¨#€Ï÷¶?ÌeèçÝŠM/WÿdëÖ­I’ìܹSÚËG·‹ 6Љ>.¯ÃÓPà5ìD]åÆ-Ã"‹¦ÅG ±owˆà!xÞéŠQ?s�'ƒ ÒÑù€Ý%“£,’q4Œ*c©X…ÀœñAŸnÛ爖>V¸ÞñŽÞÛí“Çüúzšž?|¦Z½ªXüX¯‡ºXŸøº^ïN³P(—ËgeÙt¡ðéJ¥“¦gŒujÇn·÷̲ÔB&©Ã?ðÐÊóŒÕm3ל_n ëpö¶ÇWt:ÉÇ#‘#Ïó4ËF!ôÏ??;üð]WX(ô>ýéöÏÞ9÷ÜÌ^M¡\nÿã?Îüä'sozS"ááQGíøá·~ç;á€ò<¥éŽ .ØxõÕ›/º(OÜzwÚ™ÊÝ8™6²Þo0«ž'Ì1(ºr÷rtY ×ëµÛm!6 0d'dý>úè¶mÛºÝîüü|§ÓñAq«Óéôz=Ad4õ¬Ä}Ðg*fÀgS¤a>\•( Wæ pâŽd ,f”¡,QÝêõ:a4jú…yk®Ö"A?äÝøháoRléÚ\LæBÐCÐ&¥§¢ë æ;55u×]wÍÌÌD³Õ=5ôMM™EˆÕí0Õ‰¨J‚Þ•�4 ™´­ãE Cø5N™aA²býJÜÐ!Bàï)ýÂ<ÐkÜ0v#\vø“èèÈ>˜lÎ0X™‹Ô"@œ# 0ï V;¹ÙLÆáa&MϪVo+{Åb:Þú'Fû†ðëry4 …/ÕëߨV+¥R¹P˜ëv‡ÃáþYöÚ~ÿ«Åbú¤'¥_ùJrÈ!«yÆÙ7¾ýxf ,ôî[.Ò*ÑLfο ŠìXhgK+õ+­[×ýцo~s9>þñúg>Ó:î¸ò† éÉ'´:ÿðÕ|dÍÉ'F£ìU¯*­X1÷ž÷¬}Ñ‹ö{Ù˶ŸsNžç³§œÒ¼þúC^óš‰ë®Ûþ¶·)®·Z-Å•tT]Úðª*¸Mô7yž×ëuŽ6}ˆ Çn·«ƒ Sc+ƒÁì쬈pŠ(ƒÁ`~~¾ÝnëÉëÌÚ¹sç½÷ÞûÐCmܸqvvv8ÎÎÎ>üðÃ>øàæÍ›5H€§þIoüÕét„$ªÃëZ8›§PðÔÅK-ØP y›j P´*´€yDdåT·zƒ‚Ä3ŸÑâë*Œ‡Ý©�uôuñÑAÑw¾VW"’ºÏ‹ ýͤ÷r  ‚Ö0ð·:7:¸õÉDnÅ Â0 «Ó££ã‚ðOKÔNïH¿ÅcªD7Å›ò9ÑA„‘B® $ËÀÚŸDÈq2tõ¢*§ŠÖó3€¼]–µKœlÔ€Ñhôô,{ÉhôŽZ|íÕ£ÑÚ,»¹\>||v§izB§óÙn÷$yk£Q(^Òë”ç+Cøñ 'Ôßõ®Þë__úæ7O½ùæ„0w2£±~_Ô+ðž½Ç¿À›´a¡t<òfwz^µZ…Š7(?Y§Zå‡jtRç²Ë &èÉÒttÖY•õëK¿øEqܨ^ýè„fŸóœ¼Ù 7ß<Bž÷;¬ì±+ßûÞB¡°ê»ßM’dØlö;lòŽ;Ò4• &º(}Ç…´€'´ñôuXHf!®ZX¨G^£3WÃÜžè,ã·;§H=ž¹¹¹=÷Ü¡‰(zzb[1RZí ‘€úXՌóÁæ8¸9�,RÞƒê õòW¡Ú‰Åþ뢜x¦cš•Ãaç^æzqîw¼íäMP)·  6wÇœ{~ѬAº|xêöœÌ‹!D3®³öçOg…ðé1Æ!2 þÈ^âb¹›v–è0N†v0siͤ—«œ @|h¶žÀˆ3æcÉå<.¯ú}h+XÛµU,^Ùë}¼×»µPØ™$¥Réä4ýd§óîNç÷…Â÷ÇÉÚh4za¿Pšž_.ßX©¼ Iþ.Mß4^uì±Ý¿üË·â+·n}î—¾ô¼¾ðMûï_³Ê |:·I‡ûY…ñhjèpQߣG,/÷°qçvÈhûè:=»õXFž$Iÿ¢‹ ½^ÿ¨£²ç<çqÇÆr9ët*ƒA¹XÌ%58øàîÉ'§³³³û· ¢½ùÍÍõë'~ö3²éhÌ%Ö^d£Ê”u2*{Õ7 QZ«Õ uèçUɉè¬ú_E J"Á_ʦÛí¶œúýþìììÎ;%Þôé *kÔþñ™r:ÓÛív»ÝÖE´¦,Ð%ÑWä!€’É+ v… C².áâ@G¿…ú’®ƒ»¬b å=?o}ût8X‘|UËäÙéÝ„7Më“A·RÓPøØǬ|Vž»Å¸­Y‚‡·˜sm�·C¢Æ£ ¯£ÇrìÚp«ãU†EÎ[þ„†À-¸óéâÂh¹Êù?ÝËù «’ WRmJrv¬kø#9‹#HLPv5x9ÏŸœç¿´™»7‹÷—ËÇFïéõB¯wP–}&Ë^ÂÓóü÷ÕêOBèFOÊó? &J¥³ï¸c¯bqÍp¸Ïî»?²cGÿË_~ó%—ô/¼0™žf¯zŠ �Æú2ç’”ãýÌV͉šÝsÒ`òl¡=…œ6Mðæ!Ćßå;bƒàÊW_~íkáì³G˜üû¿ïR}tãÊ+Ëë×÷ßøÆì€’ Š<ÒüÂ’­[ç~ðƒn·[oµ;ÿüúµ×¶î¸#G2§‡AWÕ[ÍÉž›*”Ê„Ý.o›N§#T:@íN‘˜EÔ†¿®|wdÍDpj²Cö¸ó ãÄ”AŽ„ØÊ9YF2Ç(shT}ê E:ðsÅ¢ÏìàòÜÈ f¼zòâDE–¬?m]” Õ“´€½ÇèÝx±;w”ÃT‚,Êk ø–"|Â7ñú5¥—>“†ê£ß«o¹ Z ݦ‹Í™þ€å’îd—ñ!"a;}ƒÕEÉHš‹s]0÷ ”Žù/‡œ%ƒÔpÈGÆ%ŒH»—=ÁßøhE.„°$•<êëõûk†YV ¡ž$O áéýþïÊåJž?’$Û …&'³,ûZ»}~£QÌóÍY¶gžßÛn¯Ìó÷7¯j6ÛŸúÔ¾ùȇn½õºC)­^=55Õ}ôÑ~èCïxßû’·¼ú¯YD�ÁÔþt)”};%Ɖ­ŠR,t2nÌUÓY|Žƒ°còtN|Ø»œê …|üë’ûî«V«ƒB!És1¾vmci>ò<ÊÑé$[·bû6ó7S»í¶•øCa\Ù0ÜýXé3á ¬J®ùìì,1`nnNBýF£!¹ÌÜÜœÊ\SØ:ÎæççaÓŠ&T©TÔ ÂQMëjûöíîªÌçàf³ÉÔ2ž°ê!g‘)5vcšEùµ‹Ñ R�qòº—3'uÄBÔƒ‰@œ=b!¯U?#09,š§6 ·à†N•d7)Z{Â#ŸJ÷ ʬâcy#EžÉÃÑÃ~¤*‹î_¥Ó ÙlJ\Œ!,[×ìoг>ØÔ"­½b±ØjµÜƒBëÖ ÖTiTB#ágãéÐ^[Dý'Qå¨(Vñb\ïÌñ ?Ü-Í'LSßð…bñ[ÖÚùe’<c8œOÓJ¹|S±øÄápg¹L/ôÇ£Q·P(äùWjµÿ<|½R9p\§ïùÎwþ§3ÏÜ^(ܱqãf©¾=öÚ㎫žw^ÏÜ5ø†}Ë ‚ùg8lü[·vfQô ùÊ?²ýd«Õ’1¿%?´-Õ ûùχñ£g=+¬XQù÷OŠÅôå//\sMåç?üàÙÏÎ&&7ßœ ¥›nšÃ²,+]{­öêìsžöÚ«T*Õn»­që­ðâ{ôTàJ‰2Múq Ÿ¹išŠé¤OófÎ4¸ž”J%Gh›æçç'''õ(T)ÉžžVà‘ó›ŠQÆE‹ Y¶¡¸·á§"&žÚTne´˜$â¶’Ñ)ìSËx8*?7BŸÿGi¾÷Ä¡f¤ä½qø]»¦FYáE¡£dŸ£VAÝêŒ;/gù\Î诰°CýCÉ¥—¨š•à¤N˜ÜóèåD˜vÏå$̸K©Àg¾Oç,,ôï cGj*i嬴¦ÅëO•6ªV¦›r¾-KA—8ä8“Äw‹#Q¨vù_šxZU¨ÐƒéI6Yö©ñ ónž¿½\>o8ÜR«]S*¥£Ñµ…¿x4}©ZÕIú×izs¥òåò)Ãá!YV(.xøáoå+—¿á •k®)¯_Ÿ=ó™ƒ?ÿó·~ìc¿ÛcÄ ¢»ðêLÄÉJ-™H}F¸Z<t$,œÒ­0†ˆÏŸ›#$ªu¼ÊM Æ]å׿6mÚÕÿ×Í^ð‚|·ÝÊ¿ÿ}éw¿…Pìt’$)}ãé _V®¬þö·É-·$IR¿òÊô„ yÞø—IÓ´ô£ÕŸò”¬P Y»íZ"d"z½1%90v¥: Ü[•�çÂiß*A¥¥âLnV®\‰©Œ·U8Ùu4è"ÒCaMa‘+•ŠE‚|¡ãV%,ôm"cÀ ŸrÊÉÓúŸëí7`+~�ûWrç@#µyüÜZXèlÆýBE‹:ð~GÔUb±Ü ÛE`:îén²gµAx80¾|þã§§§½z¦Ç£Á^Á‡\DAÝ{c.ô^# ú¼àAÙ‘ºêoÊ_ pï­.‡œ%¦«AßtËgàTRZæ?ªˆ¨ê{ý&:.û@ðÏ|°çÏ4 …N–=9Ë’<¿¿T* £ºÝÃmÛ¶òÓŸî¼÷½ÃOº÷ò—W?øÁÂöí¡Õjgv2Ë#/NÅA†/úãTÑj5ŒFéx'—&&Ò,““Ìãñ©^OC(ê‰u»I–…b1•)}·›gYžç=öXµ^/Õëæ¦ü=ÏóâÍ7ŠÅ0 Š?øÁ®.IÒѨü“Ÿèê«×^Æc’$)íØQû×ÝÕn !Üv[ýî»UÉ‹Å4fgéÆuˆãð¿X ±x¬™Úo:Í]3èÙ=Á€.‹ž^¯×“ú’ûÕËm6›˜n¹ç©.•ÉuêBé°`¨Æèknn®Óéè3»Ý.¤AP5òë`® 7w!DAñéÝ*É0L|G'µ®K~-(ÏåLÄìÂN D/kð:òTyê¾¢>­#Ò0¸³"ã¢]~ÇûÅt:œÜ|r.r"ÌmE é¥TÕ[‰´cvãGÁ¿¢ê).ý0P\Ì2}`ék‰öqtÂÑ6ÿ[F™yÚE•)Î"[Ùm•ÊÎ…2ø[ÇÕqš¦ívÿïJå#ÕꥃÁ›Úí_–J_.’ä‘þizº03“Ÿ~ú)Ÿû\ë¼óÒ4½£XL-ûãÔ�„ÁØ}Ú]‡ÿx¿zuzÄw¼£ôÖ·Ö7o‡£uëÚ—\’¯ZUùå/KW\‘oß¾k¬Ù;ß9zÖ³ò<ÏŸð„ê¹çö³Ñé§^ñŠBõýï/^ý®ÎöK_:|Ñ‹šgIŸ;b1º˜Æ/8~„WDúƒ`Óˆ•ð*GZ如4IÕ¥¿QkÁ³?¥œèØÇ�M LcH/¨îšL�� �IDATWôhšÖ÷)%W¬X¡n·â…Ù¢ªñV}~/ÄuˆK7êvjؘÂûZaTš:mú_= õ³ð9¼=10CÖ6e =-ú76<Ý!ðcˆO!Âù”kl <3ƒý¡ïûŒ"w`Áu–?Þz|8*˜(Ä/Z~8 :‚` ò‘ÑŠóDP³?œåü âó©a¢³Í “`ašGEµ ¬-å;þODaòAtùèÍ2hÏy_¾@)¨µhþGµšçyaÜ?(‹ç6›Ä‰·V«ššsi«µË2„,Ëþ¯ZY8ï<-w6üu;i~úôŽ”clÂb±8Z¹rpòÉé^{•Æw×½øâÊ;ßYÚ´)œxbØ{ïlÛ6ÝlýÒKó<ì»ïèÕ¯<V«I¿ß|á ³,ëüüçÏ~¡PèŸrJúüç‡Eƒyh’9Ù ŠéøØ–nÀå¦î`ôýÉ+YõcÈBâ Fƒ—Ù'ža”‡Þ…™Œ2SÁ!ôF%¬>йdÔRP%™ýÃéé®HŠ7>'NšŸwðà2¸°“ÇÜÝÝ%Ð8]eéÍ?ž<98@• ¥$‡ÃÝ>®“Td¯×ua40Û£¹ñ3¼ „“aé¥3›»SóÉÐ=¤9;ÎC£l¹vŸ¸v>â$ÂùÝ㾃WÛ�‰\ÀâQîÁ<¶}÷b ûrÈYšB_µ`FñœY"¹ø†hÀâLbàš%åñ$‡´2OÓ·9<žÁébþŸzýö1‡L³³·ˆÜׄ™TÞh=ð‰O»ÂêÆÿú_Ûk×.Ð(LNv?ûÙÊ÷¿_ºöZÇiš†#ŽÈÓ4¹ûîB¡PüÚ×BýsÏ­^~ù®+<ë¬Ê»ÞÕ;çAO‘‹´N| ¨æ]ødïŠ#5õ6R„"Pçtpõø¸Þu³ÙtEºk)x;òmÓe»u&h†j,ºBQ¨9FI´{ùŒdjeçfŠÖDä:d=-yJ^ÅÒ�÷!l> -2÷$êà'­µMÓNO†:Ì 2UN„㦟nkáÏ®ŽäýFÏÍ2K‚tÄjcŸú Ò®ÇÚ  •(àcƒ®quNd¸ Ò¨ˆB,‡¡îb#¬Ó½ïå>ôÐh|:3-,7å ÅÝÌ;,²{X9K@ð —3Bo]Ë‘Y”;nUë^ AŠð ÿp¬Oöæ’äs¥Òª4ýZ¯§‹ùÏ­ÖãÑëƒÕƒÁh¼«õ»„y¦é™,6ñ¤‘4ÄmÖ8ú]ÛìÃk²uûÝË/oœsNïÔS‡ÏyNñºëôσAºzõð%/©½ó¹Bo’ ßøÆòƒÖ~ðƒP«õÎ>»tÕUùÜ\‹Ó¿uŸ1¾BsssÌé”Ëi¯§sS-z"P'ÁùáKÁý î¸nëËÄLâäG";|¼ƒ¢ËSÓ…®oe‰Îq@!Øù ™ív»Z­*t©¦CZ.(<i‡h"¿™üQ0æ±³Ãq®Y9%Ž—50½®'ì4E\J£}çÙõMÏouÈÁG«¹ ‰ÑZÞ¬súÕnÑ…éÃ3„IÝPEÖh*?¿W°F´o§«!¶à=!€.è`—¦zÒíeÞ»¢f¤\BºÚrȉ!/@g-S¼ß]»‹z‹·™}ikybH„ãž–È\v¦é…ý~5„§pÀŠ+¦¦¦®zä‘,ËþP,–ŠE9¼.|Ò(ÇÚg¿@‘ 様ç]¼«9œ$•3ÏÌ6nLN9¥°b0K!M’dÅŠÒÌÌ0„P­N?½ðØcåo}+‹¼ =ðÀÒM7%GÖ®Mžð„â#°ñá^Àý}ðÉ..ìºuý .h\yer×]ò€•ÎŒj¡Oì%õBh2KÌïª/¸êÝC^1LŸž››ïÉ@h‰øW ) ;¢?H߇R˜sŠÈQ©TùÔ¶Éó¼Ýnçy>33£Ï䇡òë3§Ç6DÍŒR[ï‚_KHS[tïÑ”o'è2€˜p†¦.Ômºà… G¶+RÝ‘V-:‡»#²¥ëjݻ֧Ȱ߽ÏÁx@Ÿ3¢ ¨þgÛ FíÔÁŒ�¸6 ä%:=ôùOÔâ>ѕ֋˜)hY9@…²²¥f. Q�º(R.‡œ¥©r€Î#Gtz dL:bàS’shrù°*\’‡ò,;j4º©\þš5Ï|æ3×­[·aÆ ~ýë×=úè1izO£‘·ÛnaBÞ _ÈýÓ\$áÞ\›sv9ƒ8vµXƺ]{l"—35eÍé©§–¿ó]éê^{õO8¡öÚ×Ö›Í$I†÷ß?zÆ3ú'žXZ³&ìµW8è ìá‡#/6§ bd=^h>íiÿ¸ué¥Ý3ÎHV­ªÞpC$äö#J#˜øÇ8äÈièlW˜k,tŽÓò”Ó§ü‚>Ñ¢CøE&«T¢ç áúµ 9p$hú4Í‹SwGãs°ÌqpÌK@sOÛƒMÅ fÈï·ãNtœqÎzb½áŽLÎÖ�öqc4<–ÂÂQ³´TAó|Ö'ûS\g4«Ù�lô§Û\b<Šæ!‚ÚHd@¾;έ |84؉~5ìg¶'€íCpB>`\qH:e]'i‡øJ¼üqE”ñå³” tGN„r�»ÓçD]¯w,¢ª«|A]qžðñÏ®H(‹IšþÅhô/k×>ãøãÏ8ãŒ}öÙ§ÿ¾÷=2;ÛŽMÓæÜÜ)£QP“9˶‡ðŽj5Ø|RH¦€8Jî ;ã–u¾xjIvOgÈ;"ÅO|bpÁ¡Ù,Ü{oùæ›ó‰‰öYg>ò‘<ϳ׽®tÜqCí„$ÉŽ<²ûùÏÊådûöòùç×n½5˲äC²‹/.ÝpCaÜùX¬OÔÓ呜–ËåÞ~ûå/{ÙÄW¾RÚ¾=\uU÷u¯ËûýÆï~G4%iU–ÇTMï P´³'…县 @ȽClìȆÛ<ûÔ/0«V«¥®œ Z­J»S—°J«µ*Z­r¦aKÊi¥3ÄLˆ\|"Ð1^tìîSép±sëiœ¸Ã?d o1ÒžA7MOÎu¸°6ø¾ n]@­VƒŽ¬…A¯6‡çyÁFP"xéLÍäý$^1q‚¢Ð©>×B$š#Ɖ0 R,FX"q‘ÐMgðanÐù´Æ\s «ÓÁ;C0�ÕØrÈYb`ÍK{½`ÊgOÙœ”B©‹¥·(ÝL 8UoÝ¥ÔLÕZíCy⟸bÅŠúcÝòÊWÞwíµÇÞ{ïÓÓô°~Y(\V¯WW¯þðCÉXIW¨¾1¤R§T¹—3½q­þ}÷ÝWã[\¬î ÔúEe=V­VËårvË-½| Úje;v¤Û¶e…Bö…/$y^,›¯}-‘#Ùºµ~òÉi–ËåRž‡$QO%Ù¸±vñÅ®P!™¦»;!*˲lrrø®w­}ÿûžœlüÙŸÝqDžϾóŽw”:ú† nBŒ¢…ÄÙÛ>ð é•çËúƒ`.ú´N²€]ÊùÈ”°¸);¨¢[›šš‚ú¬—¥¹¾J¥Òìì,Â-)qA:Ã+ÓÕNMM¸f¹õ@'aZy”`F£ÉÉIÍÆÖ)¹|{r&Š¥X4¯š~8ô-ŸÝç-•ÚÍfóˆ#އ÷Þ{ïÌÌŒ®‡¹æ<&÷x•Ïl\~—W¥•£Пt£° 'l®:ÍÇé'ºS%sTœÎLqó´è”À1ˆJWχR”Þ«%—µ:²‚ÐÛ‰!¤ST™Ë!gɾä˜Ñy<“—�UÜr\ÛXøÆb+—`ÓY�µµJHÙ诌²lS¡Pܶí×?ûÙ!‡²nݺƒºÝßÞvÛûzh[³yû›Þô•;‹¿úÕ—7n¼ï5¯™¸òÊý÷ÛïÞ{ïÕá¼ Ý|H𔟠 $[·æi:o€ÚÖ­Ù#Œ”¦eYuçΠÄÿÁ ÒÉhTÞ´© ]( G# k‡òCcH»û„Ÿê}NAÒs_ܺêªÚÜÜÇû„'<aÓ¦MÙÌLíšk¦ÞüæÚ¹çrÙvþ‚€¶Âxd5)$Z%¯‡tô8©p‰ã‰,Ñâbé>5I®ÖÏŸøÄ}öÙgýúõ›6mŸ­X,Š%A\¡)-:é*ph`XŸÁA œæÕG¤6Œ¼®#j«ÕjµZŽ \’B’0ÅùK &èâQÇîaÃ7å8'מC£Ñ8ꨣÎ:ë¬~¿å•WÞzë­Ôë€`ÊÛ|CT ÈUŠc ÕIë¸ÝUSOIüÏw©Œ-‰q*¢fkný�§_oÄñyÈÓž˜‚ûQãì½PÎ+ç4±ŠæÇÜr¹ÊYúB‡Æ`4SÙ'Ä@bña—4~œý…‹-z’ïd~ÑÕåò³{½½~ÿû/|á tÐ7m:fzúÑܺçžO}êSÿó~sÕªoÜ}÷˶m+ç¹æ;÷”¼Þ3)Êyò}þ‰l%]ò&—ŽÈeŽÓÙ1Ð<Ÿ1Jþå >¿Y2,<Ê\B´º\.§ç×}÷»wÜtÓÏ~ö³V«5??Ÿydÿ/ÿrâÒK‘i—åÚ”æCF÷)Ôÿ3-n4Ì6¦Cξu— Â«ä©j-ɦó°Ã;ì°ÃvîÜyß}÷áÄ£“w5á,É âö'º˜v»­ë„Y€>¼¯™™Úã=ôЕ+WÞÿý›7ocù*P!v)Á&‡â>®5¦ŸÑá(¡—Œœ¶ƒyþ”8ø]²zi3<öØcyçKOì8d}Æ´~×  †©Œí¦ÜOZ9*AD�£•BdòQ@l~…Q(¬¨âèÅ:b™[SrÁ“Ä‹�Ã݃"c-FQü|Òp8l4˺œ%þbö”6’sÞ£©3Nw4ŸæÌâô}.ˆgâ…B! …•õú³ìm×__¿ùæ½§§)—o?çœÃï¹grÕª§<å)Ãáðw{í5üô§“¹9Mq×ò cO*ÏÙ©ÁÁ|³é’”éP“mptsÐè±ç’µ±U8ñir ´Íp1 Û±x� Gœà<Ï !4®ºªûú×?Ôë•o¸atðÁÃão~þóÅ;† ©¥d¬^d ýÓ÷©�ˆ%¼ûaáðc"Y‰sm=ãæ½kuMOO_ýõ6lظq#ºQ´Y©®ÛÃõÒ Å¬UN^¯‡ÍÝxh¨hÅ®KêÀ<óÌ3׬Yó£ýèꫯÖlžÇÅÅc?ލ„o|ùX$NR *"ùpã}š¦þÁhôz½[o½uff¦×ëmÚ´ î"BnçþId-Þð¤Ò½ó~ù4’EdF�YѦvÇ:*¸Ä›—‹Èr)\AïAºÛž`;÷'âæ!g†ú¤5Cqïü~R[F¨,á×rÈ là•+WV*•mÛ¶¹8‚ï'“ñ1ö­(a@§p§ÓQêJ£ÅIbZš²Äxé`püpX aŸ4Mæç[y^¸üòÉ4Í_øB7nœžž^==öØc°w<at7xº8\€Žu£:¹(ÓÇÂÀ]J9^a�X9šhlö(ÛÌCòâQ»tªw6[·V?ûÙþ¤íöàì³[_œÏÌ$• ƒ,]%�ŠsGI"ìžc=2‹¤ÙCÚŽBÂ8¯tf‘تãÍɲlÆ ›7oÖéæ„gP4Ó@Ò£ ç}1\ ’S”»„ä|n…ÄI¬F5™p”qÞšçÔ.†§e‚€0$×ÊW¢¾”£vÙhÂdÚ}Ï=÷àÇãc•iÀзðúàA ƒõ¤Ç €4tÁ˜±•¸_Þ €0¬7øºú|°p²Ž—ã°<´}þù@Pav(±`ƒÃpc/I€“Ô—CÎR~U«Õ£>ZCìµÖ¿µ”™µꪲ×ÁÚËîX£‘²ºßï__.Y­ºÆ—ggkåòmÇÿ”×½îÀÜrçßþö·úéOo››;v¬KE¬ lTä%-h!Ñè*ÂØ)ÝRíaw}‹CÞ>î½MÑI’ŒŠÅôIO*Üz« Í‚Yn� o�þâ¼pZøèÐúý~a~~âïÿ~öýïŸx󛑺Œt1[ÉÉ‚àññT(Rˆu¿wxÏ~:£B§gë^Ua,–T1¡OÆmˆ"CøX·ÛUÿ&MÓúØä´Óéð Õ Ô‘±.k01²Z_®$FŠfÌe«P(lÞ¼ùŠ+®¨V«ëׯ—·ïTPOžÓŠ7ëØÄ+Ørïס9xw®¬T`v3 nª(cÈx4Ûv §6Ón R:(A!xPVf ‡}›&ç.¨�­Þ8aï@W°ƒ3@;…hŒ †#Nîºlû¬R¼©˜ÀË'Çöf$ÃÀ¼ºZ9Kü5ï¼óN¬«¼9é\R7¼qÐ AOä«p¤Ìzñ@‘`Ã7R’gÙ¥Åâ—þå_þ­ßßpÜq¿ýíowüò—Ýw߇‹Å§ BºÈæÈŽ îªËJåì@.Çeàn¥l46 *xažeYï oHÖ¬)6Å_ýŠÑXɇw}�Hcøcön÷«g^¿à‚`b#˜¸þë܈ŽB«ÕÒoo4ÓÓÓÈ0ÃØÒ?'Œ=HP•Fê`&ÇPØÁŸfa8ß #8nG'¬ M℘‡6WJ)較³€ªW§ÜbÀd§Á,XZ­VµZššúÝï~ç\R{–¦sœP”tV(è–ypr{ªOý", •ÆÎ®isý˜¤K\[¦Ó¹^¯»X˜ Æ]n#CXÚHûZìçù͸o-ÄaÁl{PbøöT˜WžÍ<�²íWB ö² Y«Os¦¨ ã–CÎÒ|i¡lÙ²¥X, 7ÇÑOIÇRèÎs²¸ÒÁ øœ‰¯SÌ 't> .H’gÿøÇϺñÆC¦¦Öw»W”Ëw–Ja<™ªßïK8¦=ì•S½^WÀƒ)«UèÍ}³^¯¯Zµ*If_R§ë:…½¸ÕGïÜsK6”¾õ­þ™g–‡Ã즛èèp³ÎÌÝ©óçøà�Ëoáž:†Àìž6˜d Ïk¥‰­pë�­ Õ+ú3Ñ»wÜQ¿ßdzŠßï`0ÐëЇ;ŸWuž è–5ìÀqÎ8ÇñG£Ñüü¼˜`›žKùÈ(&Ú©.d‚*Ý`XwQr,KÅç—ëqé9û OÎ\}Beɼj­Õ’Y¢èäb(h<’9ÌÃ3²ñD“ŠÖ}{=Ò8½HÇh&¡D•³x¨i¨¤ÉãÜNrÀ4@FYSRsãP¥ÉZXá^-‡œ%ÖåxßÛç¼*ëá¤`º›@éL±…¢ºÿþû‡Ã-[¶ ,ÇûÏó)–Ât_íõÒ$YÙëM>öØžy~@G&IBj²ÌŒI”@Ò9ûêõºN4ÜdUh azàêÕ«×­[×l6xà|p~~ñ< àãLrypöÙáž{Ê?øA:”?ñ‰îûÞWܾ½¸q#}…0žmÌÖuÅ5´Z¸‚À_dëøþÒõõðÀýztqÏo 9åÚív›ìUҼVRZ ]+{S ð üŸ¸~&6 v€þV:bï-æ$yN9Q Ä(ØLOƽF¤cïÄ==†ø NA/™3ˆœeʵ•”è:5‚` /¸`¨‘E˜. 'lêuw¡u^%Rp-ºqXêÁ`F Í[V $èB®s»'Ù§p ÐBèIº‚2ª.ŽÁ€nbí£n¼(²äÐ=kÞó`Eyé ã� %š±r–€>@Ç‘ÁQK›Ý÷³‹HÀµ"‹²á­øb±7Ñl˜7Újµ*BØŸÅb±`L03F½ MF:VzÎÀPÍfó ƒ:ðÀ•qoÞ¼ÙID‘‰u^.§gœQ˜šª|ï{ÍfsP,¦Ýnñïþ®{ùå•/})üîw~ #:c2µN»½aTêÃGÍ3àQÐ Hú@Ÿæ äBºíi£à,Îw ·_Lvr‚o4»^Ÿ,kè|4!ø½Þ·çxÂ×NzFR c û΢VG'?áŽ[¼ýhH¾šÍ¦š”^‰<Xá>bœÔÁ9ýN}ä ÓOÒÿî¾ûîÏ|æ3gggo¼ñFy)¿‘Á ^¨'PW¼ÿO ¯ÇÂöô΢Z\XSÃEÃðÅ£µÇu/ £ìÇëéh|0Y‘6oädl¾»£ˆ8ÓSEaF¿Î§ðÄ\ÁM ½„ÖË!ÇD©Âë¾5n@Æí¸cå`Ü.Ì®µ~ýz¨Âæº6ž»liÔJXhâ°£ž‡ÌTnrÌ>*7BxíÚµ{챇æ•AÑMö”W«£5k*wßí²Ê,Ë’ Òƒ®Üzk¤W ë5{Æ­A"£{WºÑ*pcSJ:Ÿ>éŠw?¸‘Âxà Kl7¿r-H0Ù/±ó†Ý4ÁIAîû‚Ó>4-<@}&©~©ŽKF-@…w3Ø,™>O ëÝ"šX¡=œ¼N 6AYÁ•žaUWR¯×÷Ýwß;v@‰,ÃB 2,v·€n4Ä(N"ã(}м«ê註´EBiV,g%7<×PÂ|28#"Yˆ~MÒrÇ ÇÊØ;<ü¨=$àj6§÷Gá‹“­*-ÃÌb9ä,e/‡cÂ'—°Ê}XDà~Z©ÞŠ\lïG<ã4„oxÞÁ|Ó �µZMŒ#š`ÇB]8ñ#_zÚªô½u³<òˆ Ûgff´ÜµE©? ûýä3ŸþÍßdíöÜM7íµ\tQùöÛËßÿ¾ûº}‹ƒãÁ,OT_ÅÝ/’‹w“J¨z¯ì^Îw×{’×Ó]à–£èBš‰ŠH ¨ó…hùz¦ì$˜ ›KÊ÷øp?è'þ7]å;‘À ËèÈ1–tž3kvvÖ«@’nž ¥q ·.x°"ÃÂÉ!„Ç{ì»ßýn§Óqª.âGZqÜ…Ycš[t+2¯t¦¥ Áͼ˜# DœL2¨ÉT0 gN¡Œð¡G<R6áb=O[PPñ*œÇ ÁÏG3¨BrfcôœïNõÄ42LZ9Kö*BÁ'²¸z‘#ÏÙ,ÑHÂàƒ¡LtiýVÀB°ÙÃ.»!N¨¦Ö/…ƒ(‡¥ XáíŠÈ¹$˲;vÜqÇSSSõfs{©4söÙƒ;î¨~ÿûÅb±¹víÜ…öŽ<2üþ÷å / Ýn’$ÕééòW¾Ò¹è¢á¿Xúá“wßÝ~ã»o{!ßm·ÆsŸ›>ãýK.Ñ^)üúוsÏzãôZ!¶:´åþÜÔg¤‘šÇ{WaáÜ*Ú'¾¥õXT>ºåÇœ[\ƒõ-.\@êºb�¹ˆ«îY*zST'öxYRº·˜1J Šòâ&º'p¢7+¡ÿáo-£¼ ‡ë(øtË–-~ #á ç’©Ì…*&N¿ ø} -²‚L}Ür°Ùò³ðrÊK §Þà„D&¡}ÊŸuG2­×ëžÞÜaoñü4~Ç{¿$È#¸ìxÿ˜S¢Z­j ³84\m½8å»Ke@°rì!ΤBzÓh\ÀÁ[§–Ç™v©ï‚±ÄE/nQº„¦ lp¢E‚ šö^l`DÓÔõó"—'&¾üò쀪÷ܓȻúÌ3×mÛ6÷ŠWlÙsÏÑ©§†þç]ãa^ûÚÒw¿› …ÙÙ01Qþþ÷ëßüæp8 O~òèœsòá°pÝuŸþ4MÓü•¯ ûí§cÑÄ"`@«NÐyŸté|eNÇ<u\:ÈÎÉî­~D >V+âtQµèÈC¬.3‹”‚>s°á§îu!˜¡^Ò¢¢ßîè«¢‚ž98-tV‹/'¾íê!�‘!›e©D;W!ŸuÆŽÂñŽ¡•.Ñ€~z,µôVÝæ#º0¿ oÉÐÞóip¼éÕ. gꨶ£Äñ‚Þ€Æ *“Wù0P§¶BÛcpF„ŠÂX,Á4B¾I°Ðvhîå³ÄUŽ¢›D ‹¦¨‡ °Fß™ÜѨ¾¨^‘DÃEïNX FÓ|µ}ƒkâG ^ç¾8ÞSÑþi·ÛI§Ó:í´Þ[Þ’E£Á`Çììüë^—nÚTüêW³q‚YH’,˪ï~w÷¿ÿ÷â½÷RW N;­øío'cÂ[©Tê¼ím“'œŽlÄ.‹fÈ>u³¹ã¼ð¶<M&&àyñîø‰SƒôëvyŽIN¬f>/ôÒr‘Õ´Çò]†­ã6’sÇ1ãñ&ìdxnÞ–p̨ÊÛæÎj£Oî×醳ڼ†�ìõÄى˾tëx-îš0ºã#8£ëÙ¢1ây“¬¸ÚÑÁUwÛ$<xMµÀé=Bþ¡‰T«Ñ˜yŸ[æ | 7,Äó÷d°A¬4v0r)ïŸ)ÿðŽ¯¨¶“:¨°d]Œå`ãÇ.³äŒÁT~è·}|º#E¬$6¹¼tkXÿ„lGý|ñS rGp¯×sG÷ó#ÃÕjn‰=o4…ñ™¥O{øôÓ=šÍ쵯%ŰD“�� �IDAT¬}ó›Ù‰'v>÷¹ìàƒ‚ÇSË·ß®ã£X,ÞóžÆûßï&7˜\y_„("¬IBÒv�lZŽŽoòVïZûÈH78þ eÀÙºÞªu2ãŠÉŽq@ñ[ÀµÙbÜ&~Hü[×ýAg,›Át¥0,åòø·Œ´qFO†9=¬FݵçæzV da¡¸X8!KÎ[kȇyŒL>ôÆ•jë¦ÒòV Ée,B¼?yøHÖû¬d<>‹“°á3CÕFíýˆ¬áV¡´ÙœF¡ŽâÆÇ ð{½2Ö÷açâ•ãJBç =P8Úftѵ[v’^â/ !©ëÉXO ð…EŠ çÕS!%¹::AÆàn¹þÀ+GƱ/£"¦ßÍ~÷â€âÚ}wT0”Á9>³,J}fã‹_,]sÍèØc³ç>—Ø\¾ûîÒ%—T&&FÏþhß}w͸Ük¯¦Å;“qçst䑵ø‡ÄˆËžS;ÐŒÅ!” À®UtÏPnGGDgt¨”¨S)ô#÷9áKÑUÁÈ"×™‚ìF5¥“z½¬t0])§z3Áä„I’Ôëu– Ä6¯D£Ž`±X”0+7NæYŸ©è#fÍš5ý~_„N4õ?¨9@ y>‚Åk;ø].?ŠÔ—>|ŒîŸà.:½˜p™AÝã¦2L!¡(ñÁ€.ubKÄdóö*Ö ·¸’Æ]ÝXi$pº¤Ö¨8iAØñ¤W#,×±8÷‰K¢®ÕjÌ8y[Öå,};á4ðãë¿€RƳfï¯èc¹ X„Ÿòä#î5Ëê×%"y'™äŒ·å}BYÞ0vœ,ûøÞž.‚l’¤;wZÃU*•üCŠSSé–-£;Â~ûF£B³™î³OáÞ{ÉÔÒ'?¹ôÀa8„ÞÊpµpÒø¾’\ר×j5·3q:œÞ…ž€«”<£$×vîr¯×k4 —Þjâ`r&®ûù uÏoÚ;ˆŠzAx»ÝvQ<§›»u j>!•×£¿/úToÌÓt»ñùùy‘ýÃU÷ 5‚ìÌøÕ;ðÔXP“WXö‚Ìêɸ u>}Ê-0@ž=Sdª«qÛæ×Æ†læ¹£ƒ·~›‡B·àE.Ô*IµD†ŠCÕ¹ÇOûhê:qYõ¥`è>U�zNcAØGê£5Ì’[9KŒ­¹Ù¾OÉ%‰fŸà#ëÜ$H)@‡Bãί¬ w'ƒìë@<4üˆçÅÆÔãÀAdëÁæÆïº†j5ƹá†áI' /º¨$¥ë®KÓtpæ™õ/~1[³¦ÿÒ—&Åbž¦•_üb8öÞ{øìg×_óšÓèÓN«}ç;I·›ŒqyJ4o`º@É]¸à`Æì°ÈÝËg^…±Ùp–Ó 9RVÄ“¤,c÷2;§ßïC$S*-(O,ÀRH¨ÙóŒü¥» `DÇ«[Ÿ9÷=ÒmwÐñJ#µ`Cç¼Pö‹$ƒv» )÷Vp;‰–„Å€s ¨¸®;>D«À�hùpþº$Åe­•ÑÙÆnåŽ Ïto¢xhd¦Îb/AÒV^JÔžñq„:¯›I±É -p+6¯R�Mo4všÁr•³Ä%̸ Ÿ±µ`¡`Væ«Óq�\7h6øh?ÊW ú¸Ïòœ9­-W­VF·Û•Õ¦O¡æLì'>*xÝÕãäw…B¡þ½ï ççsæ7Þ˜w:é{TÛíäæ›Ó$)ÝqG–e…n¨ÌÏç»ïžlß^¾í¶Q¡Pܹ³ôÁú&©}ík¥™™B¥B:Ï,' {—؇Ò{uB â¾8úXÂÎ@嬡/(¸¯âÕ!X\Œ;­¥iÚh4ÊåòÜÜç²³¨Ývžþ;ÓD¶=®™õU!æ¤'Ý.�‚’äúDB¯{æSvÀºD ¨'s” º¸®~…gè fJpgpÍzÿÃE?îâ,h1¢áã'»õóbŰjÕªf³¹sçι¹9P¸(|z•é (m6‡7¼ëîãÎHVl6;œÜ-€ÝŽW‰±nMCÈ # Î¡xr ×Ñh$W x±—–>°r§ñ°h Ï Cþ£öÏNeë`‹k0YÁpf‹|j}FºçÚb ÛÿýŸþô§ßrË-ëׯç â8Õ8ØøŸøÆÃô+¤i Ôî½73aléöÛËI’"ýÍovmË[nÙu® k·«wÞ™˜UAz×]I©” 4ZüNÝ»“híÖ¨´Ä</ã”)‹+W®ìõz¢ça²€‡J¶"z)’nEºn¹±‘GB˜œœÜ{ï½ï»ï¾v» 4ª`#çHê~9ÂC!‚&-¹'1ø’c€âHÞ;+Z`ŽJaìÈçГÌÓ0‘[›{«ÏÁ.õTåsÊËÒÙÇ‘çþÿ¤eÞÉ 9ãQ/Hc»N®pÈ!‡ì»ï¾×^{­^¡HØlX]­›‚{Òqöf.Ç’œö•wãÖ¬Y“çùÜ܃D Z¸8ä1â|ð·Ï¥ºèÛ¯ùú“®-;IÿID€g4‚˜›4ìs @HÝó<˜"š|G' {ƒĹ@¾ã!ÊYpåryrrRCì7lذmÛ6Pcà ¡çœ³ž=¹ºÂã¨ë–}ù²oÝzÎ ÄQ Äm•Œ“ò0©ý¯4÷œ]eûÏS,V*•r¹¼Ï>û ‡Ãûî»aŠ`ow{ êZwý×ÒàÈÒ0S/×QЩ©©ÙÙYº>}9’ÙGD»`ÖX²FM}@*íI ¿…€Áa§Ï÷ Ö@‚ˆ%!§8¦Ä°"§\{Æ|ˆšÃ¶åÔIDeZJ,á¬ç…²2EUw΂RýwÒóÖH8S~é‡ï¾ûî 6LMMáz�;Ù©}nÖé´? ð°!Åt6?ïÆç]gff|º'¬>f~±‚ÇåGÞð‹¤{úL%[Ýn×gVávãúrÈYâ/oΓí:Ã’—Ì‹jƲÈéô¸I;È€[ü:õÀ‰’üWòuëÖ ‡Ã»ï¾{óæÍ’§Õbx7­–œæ2æÈêÍ›+ží ùÏ{/Ä© ®µÖ–v‹î°Ðz’Y×pÜ´Û?j8=®‡zÂybf_r¬) Ýn—ͬZGy4®2ŠK§s({CN¤^Ý>óäåIÂK!â§¡n_‡;g™+[} xÜõwÕËŽ¤Ç=}GD‰fÁèôÔò¡ì^¥Aó^£üIHé½C¿}^ ïšcïh¨„kÑ´H\ÌHŒñ÷Ŷڹs§o[¢K°é!n%Q9|Fx”»èFÍÔˆîÌ2sÚU;¡Î¯¥I&ÂBÓZš~ëéŽï,ç¹,‡œ¥äúìK'b:äŽü“ˆñé,[åeÊ—uø’4±}‰s""ƒôÑGÇE7ºf!rPFse¢¬9š'ÌïÒÕ .ðæ2B(åÃ9‹ÉÙ±åçˆd,¼ïs7—ïæ ÓÅÕl‰f2:â’—B{t-ç5�mÑãT•~…ÓÜÍÈÉ9mÉÜÕ–p…/ d::îí€ão§Z­ÎÍ͹_ßb§�·wóûr£°ˆ&f¹;R#óROÖ�L•õLÂ7P[4.c‘¿E®è$ïµpvã<æµ#oĉ3Þ+õ”‚`jXaQ|,T4»H ¨PýB\V7ŸÅ%ÃønžÆ¾&B÷AˆN䋺JKèé¹rôrÀ[èBƒ®xAÍÞv7FB{յ啣 ì~¬ ð=Ÿ¶¾ñÈ#€ÈyyáT`-Y‘[Ü=7Ä„…Æ9a¡?!Ä73± X£°ß~•‡æ�uk}¯K(¨“Bäh¤±^¨kcCú¯èëÖ–`Ù>|:jÒ|ó÷âØ:Š&M‹òxËaìÏæp¼ˆ~F#¥£sl›;vG¥†Ä 9y]éÉŸ{½žJ(<Œ= (T{‡†‘ N`s<Ög‘§E²DòjJOØ=õ66mmHÞ0÷l7Waó±Î8�¿Ò”ŠÅnDò¦Äô©Õì5÷Cãu¸ø¥ÎâˆNâE$ æ‹ªU%zÌ Ç:â[Ò{r>õ1ظ<O–Ðíf9äç9Ér1¶ãðµN-œPLòé„ÛæGÎ#NXçÃYkË©EÄÉðµ_||†(;/!‚;zÙNéy¶» 5˲Ñ1Ç´_õªÊ7¾Q¾ñFHtsssº~ÅN77ß y'—GóQ­VOy›Ç[Ù^~9ŠMçŒ!óÞ Ç*Øý~—ðAY°ôXžxúàEÊ£ˆë]u-9òpv¬©Ý¹‹€9”V”†tÛËú„‡"Fîm´y<ýrÄ•…ªl€Q›,Î(&1ÃÁqÓ¯kyÃá/]§Zè yïN’æ¾"+6‡ðá%H°›ˆ4^9ÅÃó$öÖ‹h\ÂÂ)¨‘á÷óé):žÁSE†á³Gy>ÞOu'-râ`#!¸T^ sù¼kµr–²‹ãÎK4ú`¸#øqé¼Ò,ËDèv»>2þ¢ï„Åz. oWŒ³”@\)›eëÉõ¾šÁåýh[,Pwª L¹hÄ$rø¼çeGYùÀ†¯}¡^Ïo¼  >•ÓŸ‚ÙrG—sƒðàØðõ Þ Êø»hªJ°ÉFœw>UÁu”Žr²ޤšÑð.×l¤%(¦áÄIáý6ÜÜëq>®¥Ö‰(SFàJâýœS~ A€Œ¨wú¦°¦È: r°³6œa‹Á½Ã}‚[Eb)\ƒM"×(vÒÛçwq×<Àa§ÞE€˜WH|‡·Ãªö‚GW­Á¼¥½â'Þxl#UÂX!å¸ZÈçôD²‡È¦Ú纲þ—6Þ„eµ_ÓˆLhTRPOxeM‡Õ‘¤’…zÈ1tgûzuŸé¨‡•/eg‚áÚââmŸ²N÷%¹3å‚ÁÓT%(V¹·Çã™øÑGŽ9¦þÅ/6fg+ÿøƒcŽ™?üð©©)8ßNú`ñålgg1Ì˜Ž‚’qŸ!Íyę˦§+òΊØçÞÄv4ƒwd'dÃU |y×Á³�dC£žêºñÔpæMpy•J×WcYi~ºa¢-õ‘Ø^µ0dÝgðð9âžýÑ"†ÃQqÝËhê-wµa6špZ ±Š^ú/”Ngsè@9K %î3”¨¶Óg’ é3ùEîËNðÊÀ6{ž±¸jTŽÒjµ 86ü 1ä#Äñ²Œ”"ò6…2 íP.—W¯^ÍÀ@0= 5§€ÅEs¼–«œ¥ù"òóJ¼÷Æ>Þ—öfŒçML„¦…hÜ»5à “O&‘wíúÿBê-nŸð†»š¸å@W4E-èúŒÅžZ»Ò´£îŸvÚÞ—]¶v÷݇+WnÞ¼yðñw.½´Üëî¸ÃYvðPÝ$ 9‘‹;ÂA$Ú£‚ñЗvÒ°Ô!˜Åî“ 8ó²äO †:²ó0?áÅ«©ê3,úÿ(JæÊP**Šo`ðM¹:’ó‹(•Ñê'ié’ xãÄûî)ÁýÑÂóâàñ£dü ³¡tŽ  µ÷{DØ —;C—Š_Ž× ôö¹ÿ-{®„u+èª 6ÏvúÙè™¸Ï 0ÒÖø?amè0֭â9XüyrtÔëu‘ ' ‹ì—ôá®â�X®r–¬Ê! UÎâmÅ A"g-Ÿ�Ï0ànE㣣)*•JFCMW÷«p4Ã1 {ê¤ÅK'rLá|ñíêqO‡)¡$Mǽ—¦iﯨýÛ¿íÖlqÄûí·_¹\κÝò7¿9|Õ«<Sé£/t°2ßQÔôW•qó>Qð Á‡½^O"¢-1^?¦tÞ-о©V©q]}éÓ‚Mö~5ŽdLAóQú9ÞGÈÓÉH·½€A€÷Õu*úý>u¶žh~uv:Äîv a÷ê•éW£ÝáŽÜUS^ øÔéJüõ·I¦$ÒÿªŒ¦PÐ?¬V««W¯Ö¦ãXþ,¦-° ½²×»PÉ‹ºV×µý¡EN3ú"FRŒ²±üa·B¢‰œ^yø˜sû´ž°p®÷޽=ÿ »ýá‡ÖP»ÈË€8Šë9 ${y¹ÊYzPŒ§KÇÌJäá¸t(#rarî#0¤€àôñÞpÒ0D `~8¿1JYÛÞgfDdPÏÜʾòª^ÿÀ眳uõê;ï¼S¦é‰'žò”Æ?X£ÿô¥½w ,¢`ø©¤mì¦ÈN"ò<ÚnJy•zJ“““ŠFn>T2 P¿»ë¾v<ˆôÙ¹—‰·¸]ëç~eà~üj."Iä‹q)£Ú×»âäìŠÁ€‚•̺^$ý< ˆŒ‡½‹Ãнj±ð€EÎÔWØÍ„t¡R©xàÇ{ì#<ò«_ýjff†UÌSÜfÜEiNž¤t3xw»ðžŸ¢ þ ^Ò‘š@ω¦ïø¨ro­‰“B²å0i4Ñ„|R•·'²þ¨}yÈLDËÞ]”<Ò/áü‚å³�:ð~#°22=|)x#e2KÁµ{X?E‡ì/oqc¼õÝ]§’ûø¢ï c±7)¶½óÝAÒÙ@„=HDØN–ey»Ýøò—w¼þõÝmÛ’_ý*}Ö³†ögå«® NŸ&úç@OÔ…‹ØÙ:O,R’ú”IIÓ©�ô”µy,ñsÔBù²Ï;Á�­¥_¶¿Gºý®RŠPYäèF¢ŠÁ !“Pe‡GwrsŸ ‡«žÓƉ ãApü<ary %8ašê *Q– rE®îÌ3÷-I·ËtÆ9å²÷·õ¥¬HO£ÑhuÔQ/~ñ‹ï¹çž»îº«Óé¸ñ cð^ŸËÇöô„/zƒ€Zî £…J»KïQËÃíÝΜ—âF$ø3±–¨ÅõêÅbw#NïDFì_‘ÀÎ…ôü˜^ètçõy`[®r–Xóä£úôu|x?¸™|„†'8�+Ïé>•$˜“9xËäää>ûì377·}ûvŠp×XHÎê™Ì£aj‰­Àq·)K‡Y°¡Š»îýÑGËÿí¿Í^zi¹ZMO<±ñž÷¤Ýn¶!l²2 –.w/ß|®(°¡Î ܾ›OÏÏÏsÎ]‚MõÆ•Y—2ã0>=ï [u &¸Ó- ÑU‘­»á›ƒN:ÂE‘ÑG|ýd«ÕZ»víƒ>ˆ§Í ž˜ÿs˜"ÜSU£þ‰ŽWð=…0%ZÖÌf–Õl­VS– ô\«ÂN1Uz&…"5Æ�«ûÛ߃͛7ïܹ“ýÅn’7½DH¸‡D®T´²hüT*íV˜ëîšÃü\z*¬L¦µRÕ[ÉÁKvÀ7=Ïi°œ@‡póp¥ŸWÄòȇŽ#º˜Ü‚cìJ8»–=Ö–ò šŠoHÒæF¾ŠQ›c.Š_ 3wió‰è4\âS,8âˆSO=uÓ¦M×\sÍŽ;˜@åc¦ÈëáÔ9*¢íäã©] Œob ©ÇèÌ}çOG¾ëiš†4-¿ýí£w¿»vÁé¸HÒ1™Ôa ¢ÓÍç–zÕœAÃp4Æ4ê¼D„ Ô:5T D3÷*îGçÚ#²oì3›Õ«1õ|Ɖ“6†ÜmùÝe5ò#q"€¢‚ÎzÜØ”<úè£*bÔ !ÌÎκŠ_ê$]RæN§Ã+“,FÏJ7®Ù¦néyŒåí¥O¤ƒqÑx�ýQ ™Žàûï¿ÿá‡n·ÛBÐP›¥¦ñMÍÇô_ŠbÄÉå·‘·wQ0‡Ÿ´x°7,sÊe¸¯Áܧ|ð¿ÑPƒÈ5Ào0T‘»†E¶ŠªžÝÙh™$½Ä!Ö™£œ ¶a¡cùbÃ׈`æS¢ñÒÇÁž²¿ééi ò‚¬¥ÏU¹4Ï¥-ZÐôœ#PbÐ á'ò-Eïâp3˜žèÕ÷¿?,ô•rž1m*® E‚}ôÿõš/ß⾇‹GW¡ëf·Ër ./Q_]Þ§g¤ùu‹‡HpI„&?ýþà¼g¾xøç {i¥{ìv»˜æ¹ï/üæX·Ûmý“ÉÉÉãŽ;îiO{š¸Ð 99¸êciþ�A•ÝoÐ}'£Ñ˾ÎõÛƒA·ÛõðN©ˆ:üa8ÎÏÏÃ/§°sN—ϦsE”÷8Ý»ˆ·ãŸEÔÃ#õä^ÂØWf±“&Š=×].îµxŽ: %–“;5¸>‰ÛtrÓ¾}›‡Þ¾+7–{9Krœs̳/3»k�¾ÅŽþ{@ò„ˆ>|fý²D´â7lذyófÉø=‰öt¯8þBßÇî…æ¿¢’p¢ªoNî#8º;1³ùIwDÍL—&8rÈö Ý‘•Aá8ÝhªCbO:¹ ÂÅ+îŠMˆ¥¾Ä&D °¸7uݶǻǾii„¸ß+ª,×Ü“7ɕܽÆ1ÿÛÈ=“bvvvzzZù¬J.Ÿä¿aŒ¾óãý ƒÍ—äÀ æˆì£1 ~8ÃÓý$t,|Ϲ c« }¦“q–F“^ÝM˜ôzwf"â’yˆäæÃ®.‘†qã´|ÿÔ‘Š€r¦±ZùH)ôg‰öqZ_ ÕŽÔ6ŒÆ!7åãÑ]Ôëõhðr/çO"ðªreV¤Âaʽv…2ˆÈª ~˜Xœ ½°pVÛÎ;ƒÙˆ96M  ÍùYL>ãËÉCÀ†ø«L ×zÀ}Ÿ2µ.I–;½GÙúzqÈ_¼é ”á™]0Éž·©ˆü:Ð�zz×r‚ÿ0ßS¿ˆ§áY"Ëâ©¥â7® «Õj>×™sÍD×g�¯G,8Zå€! ‡OègHABsss7Ýt“š:T“ v»ø¯ó1äþlè#=w·:gäGæ=>ΠH\¶«ЖòKဥiÚëõϺ Dä¢aLÑÂÚA+6½NLL”J¥-[¶8ÍV‚W*ÀYú1¥¡›ŽŸ=‚jÂ=5h}¾"ç’Ë·‘׸rà :”Þxue±ÇÒrÈYÉ»:,tªàH%­‹´œÁØXv`ÙÞÜSö¤?sBayµy†‹·´“‘èˆÒ‚¶àp%âã (Vè]E:‰Ï#ÁˆÌu£`zä†b¾‚×c£ªîX„7®’î@u¯ßE¡éÚšˆ‡=è]fº„‹ "ŒT˜-„`þuò:rò7¡öIdçÖ~§Î¯¥Qá./T¢8Xëç½ÿA¿ò…Ë]]ÇŠ  ¥³+ºàËè4Þ›¹jú@- ÄC\9»ƒšÀ}ÄA“¸ßÈ GSs�ZaÂ>(Œ>Ä)ë0„033;ràļ¨Déµ 'U>lÐç#T æK™ˆNƒ>“¢R­VS±zÔÁ>ma¹—óòõûó\Â߆pÛŸ™ áÓGÑýð‡Óuëv‘s^øÂîe—ußñpÛá?8øèGGÏy Œ7"cZf79T‘€ñË"3B¯@Íîçf„t»½Êâé8@¬~Qz¥ÑEjÇÒÏ$’¡”tú¸G_Ԝמ`2Hªóbù'ܬ7fý›¨"8ŽÝ՛ΰk†¢ÞÏb` üMÈ€;Bš ï;cŠÜ‹•nrw�69Í*÷ýõƒÀÛû()”Þí½.ºóüø ͨ]‘êFþÜ}ŽÊ'(ûíp((óo<}qA´]wÎ´Çø`ªR÷3ô9=îþç÷%<Å£¿êv»³³³ý~ß©~ ´N¡±Qs³³Øn0ƒÌDí@7Îí Ïã¬%¾Ÿ÷½üAEÒo-W*6õÿ|‡± :Èad…°rþ·}}%„cC¸Ü¾sN§…pZÿÂcöý·†ð?\üÆ7†çWX¹2?þøôÐC“ú§Âþпøâ<Ï{ýhõG?*}ã£OL?ÜiQtA}j€ÏÄU v„¤†å\¦­è£jPTqFk©¹A/Ð|ÔãÅØ‘êÓ‡Eï´ßïCÄâ}”}4Ú�³™°ÐÖ×Û¤µZ̓«7}&2b‡MTÐø<ù]¢ÔzMèc{8 9úçîØíTfp :ºÑÞvýSX8ÛѱøˆpQ,kµ,A7:ã|÷&JÔ“wÀÍkrNé¦tZ©È`ðe$ºt€Ý»O_v8`."«…笪ˆ”Ùû”®It£IüÙô``:|ÍÏøSr#WôùÂ/7.ss^­ÍèãØh™~þúú‘2š8»Ã©Á¼Y£ðã~}‹'2 ¨ðŒP-IÆ Ês±j4敞™?O%”¬ Ÿ –Túÿe`íÕ!ü§þܾswG„ð@a•}¿Be4Êææ’J%ËóÂOZþéOCš†OÌëõB¡U«Ã™™d0È …0]R¯(‰�ˆà¿ˆKtšp*ùê²¼N6Ì¿– E~äÖI Tß@ç°û@*`RÂ`ó ÂXì,†×™ÐEä¨>MÀ§†s)õ!I»z‰qÈ>ÄÌp’õ(<SEqŒrš0‚Å%/ÂÍ`¥�J�� �IDATêõºØ€”P´Ç�EAç9#Ïfíp,œ‡´ V0q Ñšg ¯Ý[€h09_fòTéù»n ø…ÿå½k=Pycœf•ãÃ>UfSøÜyÁ±\—O–J¥n·«×Š(R/H-±ˆ¤îfBÑäÀZ­–é¨D= …µˆÕ™ÄüŸÈàÜn„ùˆø´QPd2: Eï_zvµ˜ÐHªujYÞ4„€ "ORýAX"vJÎ>]9ÿûË·BÊ»!|:„;C84„sBhŒ¿ÿâ¾zðÁé[ßZúÃ’~?äy’磓N Ï~ví’K²</]sMú†7äIRxðÁâÖ­ñ…xþE#Aˆ Qžý-ÁKàñf/‡²v&Ž„Î¯õäízÄÎt €³-#DÛ½RH»�¦½žãüò]½Ø2ÒI8È Ž#µdRC”*¬¹U fúf³Ùĩާ†£¹säÁÓ[Nôr. þ›xÆ„ñp0V˜rbÂG÷<,µ KBÓÊÀGLBý9?Ø­WýMùlo„,dåÞô¦€Àˆ†.O^kÏU54ü´äÑÁÒÑ MK0o­V[¹re©Tj·ÛÎUsn€÷&õõó �<ÞŽóE[°1% v8"ç>¿3/ø|&–óÑ Þ*c=‡…Sµ¢™ßÑ ï°p*‚3Å>g4‰=øæÅôbkÝe`í?ðëÉ!|.„aÚ¾ùÉþö–[êoyËðùÏÏBzÊ)ÉSŸÚüØÇvy‚w^ý¢‹ªçœ“¯^t›LF¹jdKå†ðî ïP£Ñ@|G5Mó† A“Æ{BÑ,o{ªé?ˆ|Ò¦púGS]"ÃnŒè¹º$¿MþUd2ãæÀúîúóø`gÁÑj¦Ìq¿Ç{¬ZµÊ »èQ´e�ªC§Kj)F›¿އñùÙ1À›Nr ñ·£>é£V…è'&&öÛo¿f³Éüo¿6Üø_ !2n: ‡ QN` fLîÖ,ºŸ ºX©TV­ZÕl6_Ž­'ývŸ@®à–K,{J[‚d.ÉûX.(†’§Ÿ”ƒ5llÕµ$:nÊ阭ODu¿86‚dÿ®vòIµ-$³õ£ÀáGJal]F øéÎk«pÝâš’úrÈùýª‡ð¢ÿùß>nnvüñÃu늟ýlÞïÓ/Ù•Ês²­J¥²Ç{tÐA­V fFtÐæšLîó”~ÿìÁ�Ó‹,ËÞÓí®ISy„Àþ:c0¸®ÝþçngÃou:?™›{éüü`0Ø7Ï<;û³n÷'ss_ìõè0÷:šn«µ«¥ÉÕ’Ÿ²|a?;rÅÎ÷® g1bòÅ“zq“Œ†˜y¸ÒͲ™Ý {æ5kÖ¬X±B¸<' „¶V¯×›ŸŸ§ùD ¨V«<ãÆtN® æ%AØså`¶ó>@Ö•¤:ΪM×$˜z1b«•Mâ ð¢×Ä ý÷ßÿ¤“NÚc=tkÍfsåÊ• ™žå¸þôŒó_8 Þ~ZGr†ÖöÆK‹ËÁª|Æ3žñš×¼æÐC…Ì °ì9>OujjªÓé@\$§dô*P!T w‡¾H¼‰<UykºíAáNHñr\v´ýYö^?Õj57)¢ðXîÝ)llh¶‘ÆasçÕž>EEµ©ÏÙrZûóQX”FÚÁåóøup¿á÷!¬¡ÂL†p_÷‡ðòÉÉìiOK¶oÅbúô§ÞýîÙsLºß~yž'÷Ý7xÒ“F^8:å”Þ‡?\xÚÓÊår²ß~/|aöºëV~þóÏ8é¤R©TxÙËF¿þu÷¿§œBéãY¹|Jô²¿Úí~j~¾55ÕétBGF×Íξ¾ß/›»~½^?5Iö)Ojµ.jµþi8,—Ëÿ£Ó9{bâÄfó°,{^š>œ$ÙjÔl¾©^OmE:#&-ÍÊø jœ®ÿšµZìIß÷2ÅÑ>t®”¶WlÎ; ¬)Âj7sI?ÝɤHåF£Ñ¶mÛ4)N¨”²ì$IšÍ&Ó»]%£ƒ•­è{xÊeL8v‡…^ zD´—uê˜ÃULçšúØÄ RN&‰95ÐlóæÍ×^{í¶mÛô{ûýþÜÜH©÷Ò¬rø_" þ•È]T¤ÿŒøT—Q*•šÍ&W‹(Ç™by­Vsß9•D —A~y¯×øI“ Ö‰^–hë0°Qûjƒ$ˆtÖhw0Aà¾"p€Ûñ_¼É)¤p˜Õ¯ˆâ4ƒÛ#[hwâˆf¾9á[_>Г]O±XÄÂUOCÞ2‚/ˆ3KÈøÿ‹.ç%öçÏ„p~!„·…°{·†ðP„ðW!|ý€þ_öÞ,ήªÚžkíî4Ué DÚ ½"x#¢HF¥oD@zDš‹\®@QD#éû΋¢€ iƒ!@ Bé;R©:U§ÝÍúfí‘‘ßÓåòpsøUŠS§Ù{­5çsÌ1Zßû^iâÄ´\nžp‚×]ÖÚÖá‡Ûþ3¸ë®ò9ç4o¹%Ýu×®sÎñ¦N­=÷œ¿÷Þñ„“&ÙiÓfŸzêGÕª×é4/¸ {¯½Ò4­OÚõøãÕã;t«Tö5fÏüšfí•Êý­Óg±øœ1i–éº~.‰ãÌ˜ŽµË­Íœ³¾/Æüf`àм± »¿€ ¥+•‡äѽg 7x˜ýÉC¯Ý–å�%¡Ýn”$OF‘¾øPçnµ<Ï{:Š–“ïð,ûfû" Ñ/ÅñVIò±µOE‘1&°öÛ==¾ïÿ͘¹9™‚ÇÝukétÏúègîííEQÂøÉºº,,Ä'@Û¡ Æêv|¹´½ åPv@ÁÁG$Ð?°Š¡‹ô¹¯¯¯V«uò²þ@@ÀÐ})4˜Ó($§5†® °!øh˜K®£Qh}ë§}íµ×fÍšU¯×•ÅÄeýúq+0�¿GÜÅ[t’`¾‰äR­ péf—ÜV–Pž ÜŒŠ…òð#¨ÿÜ—e±N6¦*hæ©AaÝ88pÉ„~Œ à5Y!¥ÀUA`+âÝ×»‚~RKéçn‘›éŸŸùœˆˆ"ò‡·Þ*Ÿ{®çyɦ›úo¾L™’î³OtñÅÒl"¿üerÑEÕW_=Ïh!bñ}¿Õé$"åN'xøáÆÄ‰Y–…?\àÁ8âY¡kÍâÈŸÁÌ,Û9Ë&6Õ<cÒ86A`Iíí8ž†™ïyÅ kä(ÖvTØH 60v2_βñ‘xþ‘õ…|}�…£ÙÜ7ËvKÓÇó@uA§ó‘ç¥YvV£qEµçµÂEI2/ 1çµZ‡áWœÛ-M{¬+òí8þS×l.ÉÒôØ,») —ç“79Oºî8±o<|ãydRiì—¥õh`,ÑÈu¦¥å7.õp^³lA’„‡i4pQÈ£õõ»»»A �«B;gÀT•üÂSMøxhì±¾IJÀ+®U£ÑP× nΫɣB�ô êø¿LÚFm¡"8yg±®¾²=&ø`®HVnm¢nк™ë ñ°_4¬"/dP®pï †°…oÊL¾ÔŒ[ê×A~%&G²é.ä,%k{Z¯Ö>=z[~pxž—ì¹g<nœwûíÍI“°Ô¼ *o¾¹ê©§zŸyÆi}Jò*Š«Ä&Ø[o-Ý}wúå/,7óØk\xËÈut&Ì$I²Èóî‚;‚॒®¹};GK¥»K¥²µ›ä|ü]âx†ï;ê÷òDE-Ã\Pà ”Œ¿!ó|„ĸœ~rv%QÒv–e¯Y{w©ÔÎ;Lι{ÃðîrùÞJe×4MÛmT�»§éax›ïïÇY–mçÜJciž7!Ž1_ïtî û£hL– 'ý=‰ôc ßŽ2²fíÜèù…³ <õ)ØŠZ„[ `£ýËyY[wœ(n€±hø¬L7àø„¶°Rú•Ñì‰ãX…ºtÀÊ÷ýÍ7ß|üøñè1èÒ‚ß³ÉY�ƒ¹…Ò“D_ª§õ èéÌð¨öˆ _Èé£ëP˜kÁ:/øf„hyʤ ¦£'¯â~°ü8 ~Aš¦Išfkëö–Ëåîîn«';n˜RÜÆØ|àš»¤L¤Ö¹+ìôc ¦Aüíh²;+ÆòÐR8ŽÉbÅ2-ˆ_cÂBBà &°Äúóé<ÞóÏ—'N Þz+7&Ê^‡·Þ:ò€†ï¿¿ä=UC^g"b6ß¼<k–1#ÛtS!íqY{0~ f²ö¬r”)ñž÷v͂بsœ7Ï‘‘ž—Y[Ë2ÍÝ8)Æx ²Ôþ�ˆ×fýM¨à¨$>¸aÈpY¼h}Gœ­Ë}ºsY~@T*•¹A0,Mÿ_³yqww›,{ç‹lßlîÔn—ó<o…HUä‹"Ûäçõ¹•Ê”þþ§ûú¦3T¼4`c±Xµ6WÐŒÑ#¸àÍ£¢^<‚2àò®®.mkŒÎ$oœz¬¬ÃtX”‰J†`0VÛÇÁµ績8ÊNWW{ÇW?ûlša×]×~ñÅÖ /ô½÷^²Ë.K—.ýðÃÛívg«­ÚGYÿÕ¯±¾r¹¹ýöÍt;ì0H Úl³úÔ¦LÉ®ºÊ9’eôºÁƒYß]©·hõ#åó!òàÍ ñ¥ÔÂ.¥lí Sm»{Taüêû~¶ÑFÙ.»4þþwhV¥{ì¡GN8Áå I’¬Úuמ§žê{æ™úÁ;cÒaÃÚW^Ù÷ì³õûï÷¶ÚJD:ãÆÕž~zà¹çâ³ÏŽFŒ`ÓBäUàŽ‚k  žÏâÒZ…&f ibÚ¤3qæ„äU/»Î\sý‡â‹I:ëµO¹Ê#àä›áÃë;ì½ü²î„áÇ7‡µÙfK_½–¦žïk"6bÄåäÄ#`Hk£|TµÄäîŸe¯†á˜$98MWù¾MÓg¬Í²ì)ÏûV»Ýi6ë"+J¥îRiÿzýckßÃ,IÀA_c ŒP#ËF gm¥sÿž¦͸ÑIr@š¦­ÖƸ(íj“,ۯݑû=¯ß9cÌÞ­ÖæÆ, ‚)¾Çñ‘ïıˆ<•÷«µ‡ï Ýßÿt¾•tõ_Z©\Ðnc6qÎ=U©|«Ñ8²^éÜ2c’$¹®ÑØ{È4Mßh¼E³s9KœÚzÀax‚u½ïÖã¬\.³í[¡à@ßBíÅØ>˜FÁTMÖV.`p9ìà-†TÏ×ÿê`/ú.8‰Œ1É–[¶Ž=65J[,ÖÚè¼óŒ1f›mZ‡nW®l4'Ú_ÿzúùÏ›U«ëÝáÃ;ÇŸŽçò £ýŸÿYºì2ÿƒÒ½ör[n)o¾‰ ì…Y¶Àî€ó°à4Ê‹‚+GaN‹[@wÙ Õ*¯L6ÅáA}UÀ\cõ…/´÷ßßU*kF…®¾zè¾û¦išœq†DQ—þõÿüÏî½÷6Æ´Ï:Ë‹¢Î~ûÙ¥K«{î™n»mý‚ ÂÓNkÝpCuß}M–%Gšõô°P¡{Ä@VŠâ \tøyÒ¨@bä0økO±PV=� OȤN? ´*Öõ).´šÖ‡œOá‘å • ¯¯óúëÍßþÖ9üö·¾ïw=TfÎ4==Ù®»Ö8"MÓÒo~³Å[ìêû/|rcï½ÝâÅöÁE¤üÈ#µ_ýªÙß=ø ßl,,JÝZ³œëËñ4]|wT*½ÖÊëM’4Mgøþ粬aíû~`í-žwt’D¾ÿ˜µ³ÒÔo·§‰„Ô:âÓ“õª cžˆsh~8çŽït¾”$[8÷„çYkÃ4=£ÙœmŒµö¢8¾2ŠtGu;wj«õ¾µNä¢8þIÇ㜫Y»]’¸$yÚ÷/lµÞ‘³;r~jµÚÆAð’çE9AN?äbkÏ/—=ÏÛ9oi<èûxÞÎÎ1*´›åyžÍÛû`uk/—¹ÎBÚqÚ™ç#ÂY˜+,¨¶hÀ>Xæ]]]q7 PuQß�cÁVlÓ1u¶/Læ²h7 ˜ Xk½3*3fÔÇ7y<Ó¯ÓÙyçtáB;gΚÆÛµ×ÚwNO<q°èüè£Òyç5o¸!þ,¿ým8uj0u*º8€Ñ˜…¡Q¬+–Ù[]éºô¨Åa]Á¼3Ö­¾ë´2g P›VEø`ÞäÉå§žJž{ʹ"ï¸cû¤“*7ßìj\™ êÇSùÝïl–eÿügrì±íI“¤Ñðï¹gðÛmºië Køƒ¿dI–+þñø‡RH ªÆ¸H‰,ꌼ¶ÀòX’î8iº@c](ôhAZa32>Ũ³>äÈF"Wõ«—{l×Ãwz{ƒÛo7[n)"öw|ß÷¦OO{z²ïÖ[Ó7Ž‚ š={ùÈ‘sï¹Ç -X K–È¢E©µÁm·u¶ÜÒOSî\G+ ÒÔȉ4Y+Eü\—:˲©žgQìåcÄ9ÏóÞpîu‘0 %Oçʧ1¬sY–}hLbŒGz±|”3ÃÅÆ­a² ëxªï¿—å3á. o5æ#k=cžÎ])1íÛK¥yƘ,{¦^7QôF½˜¦ß?(Ëvèt&{Þq|yW—µöÑ ß¨Y–}¹Óùqµê‰$ívâœñ¬5ÖÞT¯ŸQ*¹,KE<Ï; ÕrÎ=].ûIâ‰qqlDœH’¦&KD“L/£²Å”¬ ‰ëfÖ¬“ìñ_Z‰è35\i€)—ËcÇŽ]¹rå¢E‹„´d@Ðà-tqØÁ£|h¡ƒ¡�W HB²Z<ù(zÝò€çßÙa‡ð꫹CíqVZJ“Ä÷<ißxc×~ìµWºçžÑßþÆÅHiûÖz¾_oµ¤|ßäÝ;k­þdIÉ\2œ› Õ9 ¢ZDêý‚õ-ÔÜ•á¦$mA,‡o%ÐHf»I.÷îyž=ºuâ‰áÍ77~ðƒÒ…zƒ•Ê&›48"¼å–ú~T=ûl·õÖR«>êÆŒ‰÷Ü3|õUiýìgÁÏ~Ö>öØ ·×¼ý6Ø…1Olp$ÐÆ¤ª^Œñ¼Ð6D 0ÐÀ g[ž½Å‚aáWÉà~!Â9Bþúói>^¹ý…lµŽ8Bî»ÏÖjæ­·òË㛥Km–9k¥··\«¥iÚvnÙ²e+W®ÔÙ uQ¯§Ó§®0ºå…îqÁÞQÏ>¬l?,š‚j¡ˆT*äÂ…A!aÇÙ #c¬/P¸ ŒY™e6Ÿ­Ë²lžçǧÅñÕ•J©T?~üÆo<mÚ´ù==£;KÚíï”ËιžçŒy¸¿±µ×”Ëι=owÏ‹“dˆs³èyºÑз;¨»{¯$)¥é_<ïš(zª^ç¾EI’üÅ÷/h·Ïíí}×Ús*OäÀîî§k51æQôž1†D9dÀ’úVÁžmR•KÍ`‘žû•J¥Õj¡ñ¾�ÿÐl6ßyçðÙp+¡¾Sð[c….Hèfã€æ;¾¦þÎ2 œz$úâàYE®Zµ==’÷·Ïc\žÔýfû,ûR«µ­sçŠtŸ~zyæÌS>úè›Íf»V»¨»{v¾0*qüýVëëiÚïÜ”Js<olo$'§é‘å²s®êûGµZÇu:.Ë.)•^ 0¸0[ÊÔ°éŒ1ªyÌ“"ív<æ&h•€Á^l ½zUA¸$³y³]±¢ëüó³,ël¸¡°ZÝÂ…öœsü0lo´‘3Æ n:ÿí·Ó45‡ªïwœIÓ¤TŠƒ ËK“ûœo™~T˜‚C,PæïIîç„­7Ô@0ªŒäÓ©Úœ[7lpEø/õœÐ-¤/ëCÎÿÞãq‘é"?9þöÛ;§žšuTôÀÌ;D²¨dYî(BZ˜ íÑàInœðÑù#Ló ‰´ƒ-ž+—ÏŸÝVÈ!üR[>Jáeyð‘”“ïû.•I’gûúö ÃU«V¥iZ¯×7îtŽétn ÕΙøv¥rPÙj]†ç‡áe†ˆŒvî›å2pŃ»»ë{Zâ,{Ϲýºº¯p–‰È¯K¥kµ«¬-}‘ýº»ÿ0ßÀÞÚèF[Ò4íëë/K[2¬È¬týåæ›o>a„•+WNŸ>}ÕªUÕH ÎYwN½ÂôÊk©Ä–0ªeÉR]L§Ìºü4ÍšÍ&@$TŠ�O²<èÆ_ýjôÒKè4¬Y½äã‡iC=oßÿP½PãøKY6ôðÿºjÕè?ýéîþþƒ+½2»v:e‘½ËåIrK§sDµºç}¡Óqù ÐHçöã2$I’©õú¾¥RAG0‘º«Æf³É¢|ðš½GX°`Ù:…Ñ„TC æ´c^®Ýi­•µOdåém@ÃÒ³VP•\ýfEæQM5€u ð¤6d¨ä™ ž'å±°9P'ñ<î;H 0#^_å| GE>ù‘ÈÔ (•JróÍ­£ŽO9Å»ùfd¬`VXdLÀV‡ì&p€‚kb`ô2룔Œé#½âQDxd¥r~u8)ã6;àõBNd­5ÄÔ,9wZ«õ»JEß:ŽãE‹-Y²¤ÇgÄñ}Ö¾mŒÂ;v:s²lvöY{çc>›¦bŒŸŸ†¨9”ð¦Gbƒ(°-ùHå) ÆŠÀp3¦ ˆÌBE-ШT*xà0wîÜåË—«Iæ # ,g‡{]phe!!/gÆZ‘ÞÚÈLaR–÷á!”€%êy^ãÈ#£½örš[Œ“í¹gôÀI’8£Á¾eÔ¨9cÆ|iáÂð®»:§Ö™?ßüq?M­ç¹¼òdÍä³#6M­µw„áÖ^×nkªÔãÜ?¬ým¿snR®—ÊjF°ÆÐ«„öŒ&4èÙðñ‡XÅ2<¬÷ÊÏÇ錞Ó`pÊÁ%kmtóÍ×_Ÿe™yúiÛhd»îÚ><œ2¥|÷Ýí›nJ¬•GuívöÒKÉñÇ×'M2†×]ιà¿h]½sÎ~øa6w®OmJ!wd®)›þñ΂<.WMûÀ¿`‡'ÜñR©Ä ‡X]È`�Ãræ Ñ6¼Ø­Ö>ñG,�¦Ñ>l(ò¢È["犔D†ñ™±cçÏŸßõ—¿48"9æwÿý:Á`òl·\­kýýh³&#¢«O²¦OÌ`É&´Ñ¡õñEœˆÍW›g­èqé\FNÏ<AÍ `împ YH°¾×X�°Œ£ÈžIr³sF$Ñ-MÛív5˶uîÃJ%h·­1綉ã†È\߬M³ÌsS½~Fø¾¯ i!Ó*ýØÊCSý0,¯«õ»DÝŸMîö3ôQ‚Qxžª¬©±­V«­^½zñâŵZ{<€k§ \ tÝ™sˆiGŽá”ø yGð— Vc(ždmë ½•³ÎJ$Wáw¿ X?ìëKž^ÃUãwJ×\ƒÁ÷ýÒOÚi· ñ^~9XºÔo·½¹s½R)±9“"˲W|Gc¦Öë¾sË<O|J‘µše[§éõahŒ¹¨Ý~(iÌüü—x²6* z€ûˆ®;knê‰Ül6ÙÍV× 2 –G³ÖVN: à›ÿðÃòúë¡çÙùó¥Ý¶sçbªwß]~í5ÏóÚï¾k’$\¸Ð»í6³á†¦ÝÎÞ{ωxO>é/Z”9ç/_nkµ8×Û^3«—§ú¦(¸1Ÿðÿ3ƒÅ‚躼¡ý¡ÿÕ×Y—ˇX…UÇK±‡9lì¤�&Âz’ô'òxOäC‘߈LÎcÏ="·‰ˆÈ•"{‹¼/òˆÈ"S·Úê͉1Á 7dcÆD÷ÜÓ¾õÖtìØöÛo—~ýk³dIºë®rØaQ½n¯½¶V«iB‡~�Z…8  #Â4P$hèàˆÁÀ‡.¬óÛíou:«îÜÖi*"‘×=OD¶Í²ÏwuõæUÜ‚ñúÚÒ`.œ¹lå –§SK«Õò¬•‹ºç]ií£}}b̉ÝÝžµG´Z ŒyÓÚj§óh­fŒé1æ˜jõšRéªVë¢fó%k†&Mÿ«TzªÙ”NçâJ¥FÝ{"zî ÔK MDŒÍƒ¸Å†•úݱÚÃÏ,ûÆ3p›fºj’$“'Ož6mÚªU«–/_ŽáæOkç€irhÀèçWö”ÎÉ+ćd·˜V'à™ÀÙa~ƒ<š«@]u9slÎ20Æó狵zâZMj5§(Vû+Wš Ph1Ë2³xñ€H d„÷ß·Îi5‘%‰ä:F£aíÄRib©´AšÞÔnë·óÛmƒ$&ò^¦iºyÞˆBÝG˜ÒBçf©kðY8oS<$Fz«Õª&z4£Ü¤ð½÷^fL©Tʲ,cûÎ;:2“:jè2ÆÏ²äÍ71‘ïku™-]ê­X1tèÐ(ì°Îž=¸Ìòtz ,ÁÇîSBZ(8ôž*ªê3 >!ûvdÈ Ž`@Q'IWWW»ÝVª`@ÎwQñ+år}ÈùŸü]äUúçj‘GD^‘kEö9Eä÷"׈\ýòË•cÍ>¸yé¥Õ ZW\Q~™Š{(�� �IDATøáðÅÛ‡Ö8øàhÒ¤ÖqÇõügŸ G² ½dç¥ÆƒoÀvxBÕ4ƒ*Ìú¿¢hC‘‘Îm¬ç]–-0æž÷_NaŽi>Õ××'d‚$G<zVH Û`P‰Ù˜ ¢Hò¤ûI²µª{À8÷`N+ø:é„ê9uiÞR$}I–í—G¸<³ã¡Š$I†&ÉQzTAƒæÀ_ðýwòÊ�²f… ÓsàJ&ÄÍM5€iÁê :î°jÕª¾¾>uoC—§@c<„1f$BlSëH Z8|Q£@ƒ’•°y”Š©t|.³€ëáNYËY’æ3<Ï“üìƒVºsn“,ãÜ?òWPÎëÑ™,“æuyû-L}k6qAøøÃeQm"¢³Ûm·Ý„ æÏŸÿ·¿ý Òd¸°\9±×‘¬-~#dÌŠRµR©l´ÑF ,P)wÖÖ„#+z0g‡åv„´n tÈA,zy8W�÷ Î[<W[PÿÔ% ‹|0ç\¹\æ\³»»[Kùõ!çøñ=‘CDŽ^§óG‘ßæÿ<Mä&q.>ä÷™ÏˆžÅy?<IS¥™šðŽ;êårëÌ3Ë/69½dzMÎ<f.Œ§À#À ¨‰’Ê ‚¥½A//˜Ïît®5ê/cÆ´Z­åËÔ×WÍUXŒYÖVÆåè…EÌù>÷ЖÀj…^À¹¤àV–Ö ˜µdW7�,åDˆº©F&É¡izo©”9wC»mãXD~Q©Ì·v÷4­;÷vÆhø—ÌN?ìaÜ3dzÀ媕©Å„éÐ-c†\˘T­·Rk,@¬ŒÎ!(S*((ãë`Î-¬¡‰(Ë4®ê„wÀaΞték¿Ç¿o6‘‰a˜eÙIÍæ£ah‚`¯FãÄ$éˆLÊ5åx¤×ÚW¬½±^ϲlR¹Œ~'.;k—XÚår™jPƒ¢ÑÈÍ ]±ú‚Qmºé¦»îºkÓ¦MSa7ÖÂa{ì5Ñ‘,3pO!Ù‰­Ñn·—/_®QŸ¡oÐä >Zµ ¯åø‚î¨(øHl‹ÿ@ŒÁ²8.œ¢„¤;N­Vc��}5Öt×à]«Õi_r>ÁÇË"»‰\,r’Èó_ž,ï±Ç¹;ïlšMõ™¶¨œ“0lMšTºá†ôsŸóFŒðŸx¢uóÍ¥3ÎHÚmðÄ ò"dSÁ\O–ð¢²`‘¥vuu…izíÀÀi#F”vÛíìo~³ÝnßsÏ=?ç³ݲ,‰ã$¯B†ÚðÁ -N™}€r‡sp.¬™:$“èHºyö‚-À˜ð<)ÐaÃH ^–yíö˜$98Iö:Ôú¾sî?Æ;÷|X�ÊTh®h‚¯v ²b!o ÑÀÈ™Y�Ìé`E!FèÁ¨°›‚cº{£(Rð*Êav5Fj®»i±y+Û !º ÆÖ:Œ¡Z]‡z/à)¹”œ~*¤oóQ¥â“eÙâ$¹-ŠFe™ñýYij²ì¯AÐë\O’Ü^*m˜eÍ8žcŒæKÓô¼¼_Ýöý©cÇn±Ï>===Ï?ÿ|ÒÓÃÍ6Kjß8µYå|4Ð2½Îì‰7Þx£§§gÉ’%«W¯Æ7‚¾”š(Ñ@ˆÙȯøœ|ñõÚªâ8ˇ³½¬Þ ÌiõBZɾˆèiáÞiù‹/;ºâRp.²¦ ÁÑLW—Á K"Š˜$ V®¤Âûéÿ·4Övù±Èv" yäMdó^¨n·Ý L­ðb¦u≥[o-}ø¡ªÚx –®ºªuÅ¥±c1Áó1€ ­ìJ¥‚)­o4AcëI]‚¹÷Z²ñÆpÀn»í¶ûî»7..—}k«"™sj#¤Ï"/ŒyjpÖÐ]Wwp(!Š OFºÊãåH'õ°Öe­Ö^èØëæQ‹fR*—5fd–u;wzWת7Î¶ÙæãQ£NêîNœ—eBz\Œ=êù…OŽÈ¤5 ·Ê‘3¢ ™NÅ]„Ô¾Ñ béxü¾À¼À™…R©0&¥g“ÆÜfdûT¦uh°Qþ!f‡™OÁ´¡u×/Þa}:íú'-cVç¥Ïóf[;'Ùe¾Ÿù¾snY’¼kÌä1h‚`yB«è&›ØvÈ¶ÙÆø>++š„dœg'uI0ïNkÍ Xò‰D\^¸pá´iÓæÍ›§íÂ*UL—h¹\Æ&4÷<Ïó»ºÌ¶Û¢+S¨!§�òá*ˆz`1è_AΕ¡ Éåò Šæ=CûÂWLÿ‰L¢  Z°VÑ9$—ºÒ4R6›MpgÖW9ŸÎ£_äqHÛªÑ 9Ñú³gÛžž4MrízÝöôÈ–[ú+WÂJ„eÌuo Õ4¤V«éJÂ)Œqîî€ø/"µZmúôé•J¥V«Í›7OÛÑLÒá‡K¼Šö÷÷ãŵBOÄ!ö-æŒ^Èæ�»Ñ9·q§óMˆ ç^gÀš‚4ýÇ$`ìÝ™˜jJ³lÿ4}¾RY±á†ýû¿ï¼óÎóæÍ{â‰'nxï½çúû†YNÄÐAY‰SŸÚÆl†�‰Ž :ù�‘1(¦(pÆc­¶!lz³xŸMmLâb”3(ÜN@=Ä$¥øðÃ“í·† _|‘;O ª`zFÿVÑГÇ2C›º à0{öì»îº«V« àúp{F{ø*ûÆ\/îˆ@“Xä<P¥\>ýëÒppâC%¯é1íO”‘#Ýcyo¼Á&›lÒÓÓÓÛÛ‹E‹CŸC#Ÿøli„M?*{Z¬ŽÁ(sÙU}8&7ó3…cþ*0|X˜º†Á£õ!ç“} ÙOäX9_DD'²µH÷¾Ð¼å1&š8Ñ9>òHû˜cÚÇ#K—Ú?ü¡yÎ9åË/O’Äf™s®õ£ù=$ÿügœsE�Óc2óÊ’àtA\Ñ�ôº&~ëûǯ\yíSOÍœ9³Ñh,X°`§v;¶v–çYc$O±dÑ<@žÈ!D) ~‘ÂØ#@a H"2¶Óùj–ýÑ÷»²lbnMx~Ö¬=,MçX»0ÿ+H“a«ð\J JQm¹å–‡vØøñã.\¸hÑ¢K–H?*6\p�ÀAÿ¦0Ý݈_!äð…Ä¿aΆãšŒÜqÁ½V‘¸æØü¡q–±ærOFð™dŒ‘,tòõé—að]N<QJ¥òõ×wN<Ñ¥©÷ jŠŠs=Á8ÉÀûj`†w*|kâ8®Õj³fÍâz¥¶þIµZU$ ÝÁ‚C3‰a¨Á_Ÿ5îtTÎëeoèÚïâ…çœkþð‡öý÷£É“[Ç'F×’%Ço·ÛŒl P1ƒŒÑlNù‹æ ª«—£WÍHP³:ÖF…éTÛÈâ`Òv¥RÁ2XrþçCsV´ˆ”D¾/ò '""_)‹TDöœ3ç–k®±Æ¸>Ȳ,{ýu»l™©TL½î-_.ÿøGó†*—^šfYýw¿ó~þs;o^JÃ_˜âD!¬«iB0‚-9ó ü[‘­½ªÝö–,ùy­æœÝhÜÜéÜîyKœc²4ElÀ©k«Ñh`­s‡ ΂N%Bvû˜9³Œùb’l“¦;—Ëú±Çs{›,й„b�ÐÈÊkãz½ÝlÖz{—/_>jÔ¨åË—¯\¹Ò‹ãöÚöÀµ Aí_a{ÁÉù=ÎÊÎ%ž§I·q.Œc'ÒÏÓ\5IßÚ!ž×I’¦1™ˆs.rÎ1QÔ$ûÔ@Ää~HÜ¥(hÈs)©w\!x!ÓO¸+k@Ö%¤¼ŠTAÍJžµ6,•Ú‡"Qäß}·´Ûá­·6/¸À-[æÍ 2¦*SK«C8™âØÕ8¤ ë³5l¶„þ?â–VÛBâ+ÙÚ2EàUã r…; rJaâ…!°*x1X’<‚=¯uæ™2kV÷”)iÛI“Z?û™Ùe³gÏÖm‹ n››)`  wsQ]!ÒA 4n{Ùyc-+vs»ÚÈXÌ[Ö±„!©B(¸YÈ�î¥À�×W9ŸÈÃÙ„þYOÿÜ+``À¼ÿ~¢Ù½¦'K—¶@‹çÎ /¿¼uþùÒlVo¼1þðC—+Ìë % /bÈ‹U.ÔV ç#R3ìì¥Á|͹íE.êêš$óV­‘•ÆœEƘÃó,ŒY¼Ot'£ó 6V-mvÔ &B0O†á&Íæ€È‰QÔ6,‚z½~J’\R¯oš¦¯u:QÄ{â²àã`O8I‚-;}æÌ¹åæ›7ÙtÓ… VfÍú¯Õ«/­V3Ê q´á„…º¢¦œ€ì°Ù¸ç¬×vó,ûŒÈ•ýýû¥_ßVë´z=Ͳ‡Âðår–—}‡dÙÉýý.Ëî Ãû­Ý0ËÎn4vɲåÆ\Es}ßSŠãK:¹axg§¸\£¾&4N„%ÍyµRa.�:çø¾íçJqWß•ŠÙI’4:(5ªü»ßA aØîí .¹¤sýõÍÛn+åIA�Pÿ©ñf3c¶HÓ,MM–yGE+ˆ$˦‡aœ‡.Ù™…EÊ5V­Ù„]0¢ÒðGJÄf¬ðÊdÌBz„|É=ÍP‹XkÛÆdßûž]º´ôÔSc6Ý4Žã¥K—ºSN¸õÖöµ×Ú÷ÞC~íp—`˜TY�(€P§b+uww7®¿¿ÿÃ?„`6ÓH˜8²ÁHóy+é_?’$I¹\Öˈˆˆ ‚¶;U¯Ö>ýÆLðˆ¢H \¹ìfÎDíMrÞ·¬Å)$©TèÁ <‡²bbºž¦‡áÞI²W£áœûï{ÖfÎ}#ËŒ1/z^‹l9÷ä™m¡ÒÉÄÁ9Aš\Î�¬Œ'°7 ðß#ãø¸JÅl´Ñ{ï=tèÐY³f½ýöÛS’ä¾G£Ïç hɽÖAØÚ¹Ì¹)Ö~¹ÑØãµ×J3gŽmµ*ÍæCA ÎyâcÛctŸ“töb(àZ¸ I’ŒM’¯´ZÍùŸßßÀÈ‘ívû‘¾¾'Ëå¾ÜÚnL½þ­aÃ’$ùk­ö—!C¾Þé,ö¼+»»wLÓsêõú¾1æ´8ÞÁ¹¹¤œ/kÞf1Ú Œ°q!æ LIǤSð1ÀRV†­í¶³/¾($ô¦©}å÷å/›wßEƵE#G?Òaqü¥$ùÀó¶Ì²ƒD¤iÌ­a("Åña¸œ EôÒ 3¯n] €€êŒÚ¿Âi^`¾ §ž1ÐH;€¼1tÜét²aÃÒ‘#ÃéÓµ‡½dæL·ÓNvÎ`qÀ«Y3IHx »£Ð°ãÂ… ›Í&DNÁˇ+zQˆ1¬USèÙ�IæöŒnj,ƒ‚†h¥š0.W8Ö‡œOáÁû¤ !ˆ,;zûmç\BÝEn_óà1Ò Íø Ý~ÕÉaVIÒž5fj¹Ìh Cìãɰ5oHÂð@8XLBúÜå.E7ròbøðá{ï½÷V[m5cÆŒ%K–ؾ¾Â¨C1‰ïs+D⯦iÉ9kÌ·j5S«‰È³ÖÖD¶Ì²{*¬Cä* ÿ\£”Cˆ`Á¢Ùö|>ëy_ÎM]A1²Ö*>–%‰îäß—Jé„ ß±öS¦¤ž÷jÅG]ßgŸ÷æÏ¿óÒKõ+’$ß=ðÀÖ '´D¬1þsÏy÷Ýÿô§M7Õ˜S¾ì2É’8޳³Î2<’®XÁJ<8ƒa„ §žÐô8zpï•fJ×_ß9ñÄÄû ÚdJN:É9Üxcb­žûAE–ÃùǃAðå4]]._9n\½^oôôìÙl>êyã¬M³,ÍSf&v#Šð [ècys­†v 'PÃQܰg²7žØç€Çj¶(Ų,3==þí·''ŸÜétÌ™£Ÿªý£ùo½Nžœå�8€&³A&h6wj™Ð¬(Voo/Ïcq’5wöžÇÞ2YxøCø^«qãÚ{îÝu×`$þÚ×âï~×dYéä“ט[ߺðÂA ãý÷£_üÂZ{žHEä`‘cDDN¡fÄïׇœOúÁ˹³ºPô¤ÖÝ««¿^¯#¡ÆPO¢i¨@Þ™ 0 Ø*é¿Æ'ÝHÌ�sIÿ1 y1²?öYA²†ª2š ì‚ÿÃúž$ Ÿ³F§YÄϲZoïìÙ³»ºº–-[֬ץÓik²ïû-mÿ :ŒsîCß?¬ZÕ}xl êɳ{$z¸5!,(²‘6"»fÁíXGäD_Í÷ýÕú“¿ÑF“oº)}é¥$ËÞûæ7Ó!CÊ?ýik³ÍÞ¸øâê¯ýÛzý¨(ÚíÕWå£>.•Z;ïœl·](’î¹gt ƒ!pÉ’à _h^{­Ûb‹òäÉöã™Ä5¦W¨£äz'ÀÐZÀÄæj1êû¾?0ÝzkûüóíÀ€L›Ö9üpß÷½{ïµk·÷¶ÜrKçÜ‚ p„ :«:×%²«çMú·ÛìK_Z¹hÑÌ7ÞHfÏÞ6ŽõÒ'4yƒ&"!YøŽ¯¹¬íXȳÒ,uƒVPý_ÊâÓV¹¾”ca¦M`˜ìy´ÐEÄûøãôæ››W^™^~¹ééiÿà¥Y³‚)SÒ¼‡ÄŽy:êTÀÅgr çgHŒ€£j-«=?t¯¤+¥‚³�T­@‰ÖõŒ–Uû¦›Z_ü¢ÿÚkæî»³,ó>÷¹ÎùÅ/Rcš¿ÿ½ÖYƒ î¢E•«¯NÓ41¢óÿá§iûòËÏÝd“ÍEþ ò¤È‘Å"wä͈õUÎ'ÿ5ÊŽkæÏ×…J‰60ºÅ)X+.±.s‘ù9 µ1©‰…õi˜ÿÇ©ZXÈô“ñ:³/;;!ËC ä$T‡T`‚¦¶kŒ™EߊãléÒûï¿ÿ/ùKooïWV­:&M¯+•„”ÜôTìÞ e€èž‰È¼ۙª|@ "¥tYÀ;/$Îú"PÛÅh*Â^á‚ÞÆ œ/*qoò‰Ÿ4MÿÆ7Fzè¯FŽ´×ÚÝmÓÔ ¾C_ß÷¯¼2ùGnkÌ„¾¾¬¿ê!µnèÚwßÁb³ÍÄóþû^–¹éÓ»÷Ú«qÛm<CÃ2ûHÐW‡Å2—†8¸1„(dÁ–¦ƒÝ‘$‰~ò“Ö¯ŒkFŒˆn¾™G€uevww;çªÕj£ÑÀ9[©T¼zýwµÚûïÈgì²Ë.½½½=ôÐÃýý§,Y²½nŒ±9:ªKG!@6î¯0g0!™Ê63¤ñ:x u�¦ @ºkVrÒÞOj‹ˆYµ*<õÔöM7ÉŒáÂ…æ±Ç²œü¢Q¿Z­~æ3ŸéíííééábÙ—žhƒ!b±à ]±š¶ÊÚR:üÙt“ê…Í{¹R©h|ÂÂŽN?Ýì¼sçÔSõ7m±1²ñÆ•3Ï”¼Áœöõ™ZÍŠ4o¿½¼ÇN¤|ÕU›zèüqã2‘ŠNn‰ÌχׇœOöQùã†ÆÇëÝ{¯·`6'«3hâjÚiäcì�æGbK°©-p ¹œ©ñô>û ô³)!j L–aÔù>F1‰‚ t]ÝkMŸy„ÐóXìÇc/Ögv¥é£ž76ßÊÖåV%@m‡S•ƒ(³?qññ`Çx¦të‡ÄGÅi¬‰¡‰‚L’Vk­£aˆsêõ}†žcDÚ_ûZ:zôâ,{ª«ËŸ2åßœÛ$MÇ+ÏêðÃÇ|©”ýöK³Ìí¶[pË-nÕ*}?žËŒN%Y[3 ÷´`=Éâ]˜f-€3|†ç×þþ÷«7ÝdóŠVHÿxîܹl ¸¦¥Ÿe"²Í¶Ûî¼óÎ#FŒ(—Ë;í´ÓK/½T^½Zêõ µÛ�üAô‚Åt¡ fÆ8¡Æ*ÔèÈøƦ`¬ïd[ãqÁ8'˲r¹,¹¦£a¥Ë.ËöÙ§ôøãI^«†1ܬ™ÓÌt¸‚¢Ð¦“1bý=œHûXJ¬]Ƙí0 ³<ÉJÓÔX›}îsñw¾ã‚ÀŽ=ü°~H•š÷ßß{òÉ5:#"ψ”DF‹”DöyFDDÞ9w}ÈùD?ÙøÝwÍ#´Î<sèϯ^Íî5Ü) =86LàñÞ<É,& F€5˜ÒÆC…zÜ0U”;ÀLTå)H$Ñp»Âa]5mØ’N_Ÿ¥½ô ÅñXcBçh6õ÷OzÞ¸,Û6˦—Ë¢HKY8ýqZ 0§VZ@À±!›­q” èÅq¬dV�댑[ººn^½ZDž,•"»‹ ‹ã)åòFizbÿj‘oö÷ŸÖÝÝrîø%KúÅ/æo¶ÙEgŸÝõâ‹OZk­ýn³ÙL’O:©k¯½2eŽÝx£fõo´m”­ZÅì,}wý<¸)ˆÍhÚL—y²=gPÔX•þmåöÛ-ñ©p; t]èÜ›7oÞG}äû¾zÖ-[¶¬Ùlê]S•r–Ž-ôêà; ,š§ y°Ä“ =ôó êÊ+ÔñŒ<sô…†'Æ÷ñÇæÁ³\(º*ƒ,X°�²ÍÀ9y¾™OÐT- 9xÀ*]䬸5ˆplLÀáoФÜàÅ(=ð@öÑGgž‰~˜“ãäÛßö¯¹4‡²1?¹Fd¦È6"?Ï¿àׇœOîѹPäL‘»næÌð—¿ìÿõ¯+?ü¡@çC-M„u%Aq�íq!סÉd®Ô¬¯¯Ù\X@HÒÙR·�æ²÷hþ e¬a‚Ñ€!ˆ^\yp©@0Ò<g`Ç÷ý—’äˆjUŸp Áèæï C“cÍ|ú\à„t'™ÛªCï…Ô—èTáeÙLA·€yâri©¿?uôh?f†á›•Š1f¹1I¿áœo­ˆ¶ñÆ=]]ryFWW+IÒ,›<{öëív? fYöï'Õªi4Ð:®ßõ˜cp…Cbá ³#¸¡ìÊÜ%ά0êï Jk|myL¥³†[½¶zµ«„ÖÎE•ÊáS§ÞY.?~Á‚o̘1aÅŠ¤Ý~ÞÚ”^uH�Ë÷BOyN/� ©2kþ$ Y'C,Qˆç ·€�;¤±½!K.¡I‰ëÍü¬SJÚ1¸’B�Ç l:|Sœ $ú‡œW±Ø6BŽ>ÇqÓõˆ€P‹ieyWÉó¼ÌûÑGvþ|KkLϱ4\§#y€l^}uºÙfxN¯È¹"w­g¬}¢•"¿9Qd‘¥åòÈ‘#ë}}É%—Ô/¹¤|ãfþ|´1ÕsMpäËå2àÁ¸ÀŠºÃðœÂFÂvU;cÂ[Ä|αë8³ÌÍ’É,+‹¥ŒqöTWaDM´Ñ$‘–1êŒzž7ùÆXÏsJÃ¥�ƒô¹` ÅÌ7S?S|N(T"t1‚³Š×à&`êœQ=þØty̺‹|蜗Ûdš w:‹Ëå´Têq®E~»+Vï¸cm¿ý² 6°³g§išýÛ¿E3f´‚`àW¿ê¾ì²ƒ8‹Å{íeŒ1==¦^¢TRlä)‹âQ¨áP¯ ÿ�EB‡ùu}²Lz\˜rËÚ£¸zˆº¬µžï/1fA³¹÷_ÿú÷3d``ÇZíøfó!Ïû¼s~žO¨˜ Õ"åÇ€*'^øÉš§pbœÁ°aìµ}}}<‹Êp7ŠH$OŒ™±ré %MýÀ˜waÃYäpXQ(¤Ÿça�}ÁN§S*•tùA¥‚™¶Ð+Æš¸XÀà‚BW½Bಚ¬Z•õö6¿úU±Ö¾öšs.Ùf·p¡ÇñÉ'{/¼`?øÀ‰´Ûítñâ—:y¾‹ŒñDJ"O‹ˆÈçׇœOè±JĈl ""#FŒ;vìÌ™3]³iW­’M7 –,a—Y¬0Öve´µ`9å¹ ìp&0¦OØqß &6ôTçÍÀµ�� „p<qv¦ßhذaŸýìg/^¼lÙ2°†xÈŸX-†ã þ/Û ²\¦îy®o Ôj6øßëä‰,¡ê-†!‰Óóú K•¦©÷î»~»=è|óüó.ŠÒÝw7Ë–•oºI¬M>ÿyûæ›ÖÚhÊ”dÉ\ÕòÅÇ?þq–eáøK—ÆYæy^øÄéÊ•&ÿÀi˜ò Of0ÄsÔdFH~q}P"£'&.<îŽÄKÈ÷¼;YÖŽkµ®ÿ}©‹ü2ÆdÙ8}52ýÃ-`S5VÈf¶1óÝÙæ÷`Höˆ”AôôôðiÎCf¸°( 8a.ª²6ZAÜSÖÑ`ÅÕÖ†4RžHc4›ç‚¹^gû!ÙÏI'_íA¨våÊðÙgån.Œ{,9ð@+Rºä’ ŠÒm·Í>þ8Šc7cFZ¯£ÌŠ&NüçñÇ0nÜ"{ˆˆÈ…"wŠˆÈµëCÎ'ôØFä‘߈\%R«Õ.\Çqë²Ë‚ûï—éÓ³¼‹ƒT‘¸t©iy6>ìÈò Nã@¥y&&Š¢‚ßeA°‹G10%.äs޾ ²~€ç-Ÿ �� �IDATB’YØ?úh4B§æ˜ÖZbÃ*gQŒDä¿ Z&à1£”œ â ëð‘Äy: #ðŽø8+´ÖÑ(S�ª¸_læ-k«§”ËåÊGÅ+Wvòÿ=ý´›<Ù9—‰XkËwÜáT®í±Ç$×9βÌñ¯º çÝà%úÓŸÒü”ÔwÇóY®%8ë Ìjó‰UMQñheŒ«Š_Ü&a} B³^v“Ó û¨1sÂPœ›ãûÏV*Yî •¦éOK¥ÕĆгRYûqk£’<ÃWCrÌR©¤á‚œCp÷¥§§‘’±&<™g«±_°NШg pÜÍB5 ¦%¶ŒbàLTç-V�*AÛÑÊ–ðx‹VhÉø/Í:ñ 1®  ƒ$‘U«äÉ'³¼Åå¿þºyíµ(ŠRÍtÿüç4M%мiÓ$M‘žÎÏu¿ôñY‘Ÿ®Öþ}"ËD®Î#y&ò„È"+Dþ!òÃz½§Ýnýö·á 7¤[oÝúÕ¯Œ1ÑÑG‡Ë—îÕwLŽ<2úÑ‚ ÈvÙ¥ÿÚkE$ºøbï•W0í…S˜•Ì™0 †><%9ñÇ*G¨’nÓ“‚}0 ”!lr ò,žˆýÀ–ÕšòsÏ@ߥ§§§¯¯/˲®®.U;Ghá ÈÎWÀIÂÜÇÁ V<±-°]Yk£HêÙSÅîîîz½Žm‰aFÀâ�XXøKr|ß÷Uˆ°Ã0ôᜦ•JCººÌÇwŒIâØ9ײ¶E“ÂȯÂá#‰ U6ƒP�“‹Wt`eÍ3ª@h¡x…²$Ø0 Ç ¨P�y  VFäÖ{4×óæûþàL•µF‘4kb¹DHAYÚš&vNׄ¿�»- DC¯EKí €©üxF:(Œ3£<eÖh><]‹ˆÛ®\å­M’¤R©ðÁ$?ô#¸†F—7‚f³  Øä¸ï+Eð§ ÒgØ5 Æœ±ÀbE…K7TÿØë5Ö>ñÇõ"SE¢üŸËDnyMDD޹nÔ¨æ~PºóNÇío»k¯½|ßï¿ê*{ÑE"’~ñ‹Ë.ó–/×uÓùÎw*{ìáyÞÀ³Ï–÷ÛÏfpΚ‘…©a‡”8X»ÌD( Þœôl‰…Ô> ðôQ¸MÍG�æœ&qã¼V’’º®‘ÍA=„ê>$ž¬ ô}5ëÔkÞšæ¼…ì•GÑRèAä+ôrÈÑ¿åÐËæÐú'[yÞCË–½†Öó¾<s¦çœˆ¼E½Æl”$÷V*wV«Ø½È 4?ÕëÀ„æniëE ðIX‹‚ùŠ×S— C=|ò‚fn|µZEeƒŽ5†q1AQs¥ ”ÄÝÄÈ kWC¸…½>yÖ5C^L«Á(%dmr€“Æ~Þ¸³X™¸ÂœW!’ñHœ®%4üYKp]‚œVùjõ¤Ma�Œ=±W<gÙ¬"K3^c—\€!Jè­«~R0sbzQa ä:æÖ£ýÉr‹¨æ×‡œO– }ªÈ÷ÖþåßD^¹EäÙáÃ}þyÿ­·âM6‘ÎW¿Úœ0¡ò“Ÿ¤zî¸"ºøâäì³õt._|±Xï³?eŠ:2wÜQ€9hõè[ÜÉäõÄrŸNt¡óÇøwX%dÌ ¡¤à¹ÔuåpÖå¶ŒŒ@…’[s0‘cLLéOH!ø­ícnTeТ>Ãqƒ"¬�dqS ½÷5·/ËþQ*ý÷!_L’ûí7lذY³f½7wî¢8n9å2Ã,‰È½¸žÈÖYE‚gqp ‘Op3è&õÀ5‡Ü2nP†£Fj6›«V­Â}Q0â 0 ÓKWð Ä@±äÒÔ Úc’Ÿ Ý~^àúóÜ þ‹ê{3+nt4(c{fYÛúAOaeô ÂåeO#Þw( ÀZÆJfK$„ýAkthXeŠ;d™ .³PjpÃK»Ä9Œ.á^ðUeÓX~7 #…>Å£øÿ–+(?¦‰LùœÈDÌ»ïš_D`'LÝv+½÷^ëŠ+<ÏKŽ?^î¿ßËY:ƒgßî»»v o¸Á¬íª¤Ëg?³,k6›q+¦iíV«Ån€ìžÄúИQ/L>óè^ö*FFÏ·B¨70î¤!Zô`²á¡~Mû(ŠÔŽÍQ¸ÝŠÏÆÍ­u$œÎøüüQù{1„Â}côÒi-¢ÒÌljp蹬¹§ïûût:»}å+É¥—&—_¾äôÓûwÝõxÎÏQ5íáéY€‰ \ý²zr)÷}f&>àÞ ù•©seÇ•JeìØ±£G†F$NX(§¢(Ò¸¢BÛoh>—J¥R©¤Ÿi ÒvBëßù¦f1b£ëJ›üšÝ‡¹s( • Hã÷HËXê}eV<ZÓ9[Û æ³XZ¸;�«QHaDZ*ëͽü‚(ËoŠÛ 7]ÚãÍU€ì°‰�J¼®¹ÂcsVrÏS»­²¶ªR°yì€33'ׇœOþ10 K—Ê׿¾£Èù"‹Ì}ç=.¸à…FcŸv;KïÍ7ýI“²G|ÝuÏÅñ S¦¼Ï=å¡CË"µZSîØn»!ûï_ºõÖ zzž«×§ÔjÇ'I9gg¹\˜E=ÏÁÙ1ÆÎylžŒwXÉ;c AT*%£†Ð·CÓ½ž•lÅKj7Z/X7òvTȰ‰äƺȰ0[ʃ2øF<ì‰ì¥¯™‰„C%8i0Pá[ÍMiÉEnð±Õ�T©TÚ»VÛaß}Ë?þñ¸­·Þh£öÛo¿ÍŽ=ö/}é'µZ`ôˆ‡ž˜2¤yûíÙˆšüb¶#ZX„a¨XÁá[A0tèЯ|å+§Ÿ~ú¾ðvSUÔQ[î`^´ÛmµGÒUÔÕÕµùæ›#fdYÖßßß×××jµçjHï/ú`1´Z-–îÆ«¡3›gÎT @1Œû.  éá`…üþºcHnðÙípš³O®†ðf³‰é.0_ÔíT¤±­ö¸ˆg¹L½¶jL½g-_à ­71 |kvÂÖ—Õ¤ßä#Àª| U20ÞQK}GÞŒ…nÒ)ß÷MvN<1þÎw:9Ùz½õÿâãñÇå¾ûdΜ²H·ˆˆ\rÛm/üêWÇwÜ£ÍæKqÜjµl£!ž·÷½÷–.½t˳Îúá%—4.¸à°åË{Û«»{Ó믿î+_9«R9¯ÝÞ§RIûM»=ËóÞð}˜h5 Éõ3¸ÉíB8 sbŽý‰ ‘‹6)@7éžžØfÍfSt->¸m«ïŽWD#ÝZê.¥»T ¸êàrÈ]%nJbÒs™Ï/Oº1P‹0»©R©HÃÊ8¸p¼Õ1Ï2MÐû|}l°Á¶•J4oÞÖÛlcÇ×w>|øž{î¹ñªUC_xaÑ#7:tåÊ•úçê-Ÿn²Ië»ß>qbïW˜oôæÌXÏ‚ÄðdÓ£ TræªÅq<oÞ¼gžyfΜ9¨äp²#jBÂ�*ŸI’Ì;¸Va(ŠåÙ? 73Å`ì…Ì/RèÞ#´7›M²�BÊÚ:L ·jö£¿ËéĨ±\á_Ç 3;§w8—Ñ’a$™[#€Ù‹“¡9tVø“cÊJÿÝîÞñ”BAærDýÊúRLSb/ €„Úˆ*•J¾ï§ÎuŽ>ZœËFvßùŽ÷Øcë[rþWG%GÕýÅ/~Aä'""2ì׿>àϾ4Ž_ ‚N­fÞ}·uñÅ">ø`ðÊ+§=÷Ü#¾o.¹DÎ==Œxûí‡~a–mzõÕ'µÛ+ŒY”óSAre‰O |x> @ã—ëJyb{I3kž8)È~ðÄøÇ<ìf­«ß.4âÎsÍfð†*ÐÀ×Ý>bĈÕátÆ£|èÊà]42áÉ8³@7Àò¸’töÁH<î˜c­$Ÿf³éµZC‡ÕÿÛjµV­Z%"íV«ž#Šƒ`̘ÆGt=öØåËÛ¿øEë¸ãÌSO™7Þàax Ïè–3Q G!·å•²ñÁ,Y² ƒÙ½(¸92s©1Y š/“²˜hÎú³<b©/ X?`qEΤVTC^B¥RIÓTĘƒ³’qWd˜šBGGOa°õ0'Ä£`øä€¬ÙÙêLe=7Ž»zÖ#…*ðÊæ5›ÑK¸4½°L“)Ìð±”5ÊЂ&!Ô]ÁudS£êìÎÉ'»f3¸÷^é|ÿûõ#Žðï¹g=°ö¿ñ*ò_ùÏÝ"§‹|Qä‹"gˆô3Ã÷GeY¥^/Ýu—÷úëÑ[o·Þº{šöˆÌö}»dI4i’n’èâ‹ÍªUöõ×ý3:ž÷VU­­Ðì1™°µÚæZ­snҸ͇á1ƒÍü7Ž(®™˜˜1e†2xøNa!e=Ç×f6VkFÛ€©z8x`³T*m±ÅÕj¢#\êåDX_§æó‰ÉL<ÆIø›ê©§€»¾ Í­üÑÛÛ«-÷… Î1bæßþV{ùeí´õõõM›6mƒ{î¹sذ¾¾¾Õ«W7Z­Öh4’$Y}á…ÕÉ“wŒãÝvÛmH­fî¼³qØañ˜1�ÊôM9Ï`–¹B+<ö‹Û¡€X½^g'G–‘e1î´s U «‘Q,ž/F4b¥�î±rá"£¸äñR¬€‚‚ïË:¤Ê/¨ÌÌjÑŒ œOÔ=¨Ï¸‡¡G0kð°-¦[XÖO‘g”PëÇY˜Í*¦ƒ"çcSN€Oò¼ïDîñ�Ü.¤ž¼ÎYo›íB0¡kÉó¼ög$==]øCEQ…·ßžYÛ9þøÂ Åú*çyD"ÿFÿ-r þ´bÅ kŸ¢Ó;›¦vùròdm9Žv®mLˆ×lÚ7ßÔEN›fšÍ`òäQ"óWcöϲ!9é‹õe1ž H—§ÀÀÕa)&°±lDØ3z¢)”Ç•2ØÏ˜>Q®3r=öaĈ%¼O˜ô š,Îzì.  (ÿÑÃTà¨Ùl|ðA­VÃ*Øb­íj4¶MÓœ»´T‘À¹#Úí“:Läk—çÇG(r|³yl»Ýùnwwo I’ëûû7ʲ?{Þ¥Rfí¾Î¶ÛbÌ9•Ê;ùÉ„)­f¬ªë£¦?I–ˆÌ›?»“O^zÏ=^¥òꫯnuÛmí¥Kß*—K9ž£^›4©4q¢¿xñV¸Í6ÛLŸ>½wá®{ïíûùÏKßûžnûV«¥Ý$þ`¦ÁÕ›ì¡æ¦1~FoŒÇ{y c.žç)�ˆß@퉦qqCAWÃr‚£k\ÊÓ¹‰Ï¯ß%[¡§iÚßßÏ7Ä]W¬†ÇîËLTcDˆ•gyÒYµÊóIŒe¥YÈÛ˜ˆŒÉ\ÍJÝÆ'gOøâèWÖü†‹9ìÀ¦{ à§–€¸t:yÃ)šFÀHÐêÉ|ë[žHôÔS#FŒ3fÌÀÀÀܹsÝ#$§ÖþÚ×>-`íÿ.cmÍãÀ›Z£ÂéÜhç†!x‡,�l­½`À'ÍÀ¾"R.—!.Âd!4‘|68R6†N©bÀÊ aÅàC±Æ%?psfr#xÂ4$žÍ°IŠ„W ª¹ñšþS_¡Ñh¬X±é01çeÙ%i:$Gf6N’ÈÚ}‡ýÆ!÷ �6Ù©ÝÞ*M÷êê:¤Z=½ÝβìçÁתÕÌÚo¤é0‘Ó:½‡ Ùoذ£:�;Ú¿UBQAÆn–e4›ïxÞõ#GnvÀ[î±ÇÑ]ôroïÝC†ìÐéH®¤×yØ~Ð<óÌúg?;uêÔ;ï¼sÅŠÙæ›÷÷»ÕË.CQ˜DÁDó†ƒ:ßJ¹2}`f6Цœ^%„”ø€ÃÚZ«1 tj^«˜d P!Na” ¡²)¾q9%¤Á¡‡5hu8y…d)„| >±bB›ëB~Ôë\GFQÄÓ»/À@N�(\vs)‰«Í¯ ö?ÊD¨êÖÆÑ$’‡ótõBÕ´ u4x”ýái–ŇÒßß¿lÙ²Õ«WÛ ÈŽ:J–/÷¦LY?—óé=Ž>z›ûÓyÕóšÆl/Ò•¦÷¼²lçn0ÆÅ±sîmß?$I.i61OD‘1æŽ0üFÃZ»Ü˜¥k›½kV¥Ý ÃÜ“ £gÚ ÛðÌ ¸’È+…\U R›ƒ]Ž*zìdöBâ ¾š¢Øð�£Ù1ãV÷áOÊåÓôäfSw×"kï¶ö v{‡vûŽ|"d0¯l·M’ñYvU©dE±ö¨8öÒ4qnv®,°{’ìÕn_“ ½ ?Ìî�à_ ô¤éߢh‹¯Ù|h«­Â0\¶lY«^ÿ¬µ+D^Ì“ë7í¾æšÖ '¬xæ™>=Ùxãø˜c¢‡2 "€RB5 똘qJ’¤\.kS*•”@…¬‚ð‘ં¹B{d-†lía2Ô7l2‹» -pÍQï‚ ,äk¹îÐ+ryàÆmYø ¨ãyT¥ÐI<ŬK�Ôp°‹D•Ñlgá!$ž1bŠ J:Œ4¡‘µ¹ú.”Vˆmè!á˲.‰ CÁR¡B©S3:^lƒù7Æßû^íÈ#ÓûïOÓ´qÊ)YOOéᇳO Uû?r®»nÍÏgž¹º¿ÿÕÇŸnmÇÚÕÖ6ÂÐdÙRk'’²Ù;ž—†á¦iÚïÜ+ÎùÎ=P*í—¦âÜ,k—fY– ƒ+‚œŠ] t‘¡¢b¥gf:»(È=A>€°h@gÂ`å|¨£3fÊ“ÞNNA×€mÁXÛMcÒ.Ç+ÜKžÃ�l$ÉçZAð5š^‘âxç½eíOÿW­n-ò¾çÕ¬ý‚s8×ëyŸKÓ¯´Û¯„á­ÖyÕ*Óç”ÇÎÔ1ŽR©Tóý뺻5¿ÞhäÈJ¥²0Iêõº~È,ËßÇ®s.üøc¹ÿþú)§D«W·Î;¯<i’y÷ÝÔ9VÌ8f×¶5c9H¶]Àyš8ËÆ°R*†‚a¯ÉTõÂ?Ñ`—µ‡Ò9±Ÿl@w 5"Ô\ðLžC⸂~8Ftk`QÆfemí‚ˆÌ È°8]½P@O!Ÿ×üõ…l;@[�c°\.£SÈ\öÎ`­h´Qùšp©:hW*éu` lÀ$ÀÓØæÜ"®«ØngÐAãî»ãc8öX×Õe. þû¿ƒRéSœý¿r¾üå5?—JËwÞy²éq¼°R Êe³zµT*³E¼œCl­}Ϲي d™žÑSrýv·v=¡0·mQÖç¢ :šû€ Ë÷Aß‹fäKÐ^ààG0ƒµ÷ƒI…jµÊS~ áZô*>¨ 3£@J^Ó9‹"˜[3ý”CŽæ|Òn»¨ œêÜ;ƼëÜE9æœc^ªTî©T\ŸÓn[kwrî‰RéCÏÛ±ÕÚ Žg{Þ»¾?©Z­¥é%w9 .(ô¨ ÜŽõ9½½½F5ð n¤Çq, V¯½¶ÿÚk£óÎóêõlíÎGÁ¯»Œªñ9Å:4…¶º€@‘à³OîŸ\9µZ­R©ÄU;†!iRñBJ„ SX¾²k€Î ±–9Ng‘ì×µÊe¼81s†A4%ús«\±þ×[ÖétTæGÅiTìNa@!©”õ<‚ª!ô™Xy©˜*èÀ€öÆ„œ® íý‚0dÖ äW·¶®Àz½.¹®(ÄëÀ/ÔL¨8™³Îx ‹ØZ‘ð¡‡âcŽñ—. Ÿ|2ñ¼)º>äüïv´û Ú9ñĸ»;ºóNÛÛ‹”­0€&+§±šL!“Ò´EœÔü:ðÌà ƒ·ŸØÆ€’pAÐÝÝEÑêÕ«Á�ƼºfRhÚÃnŽ;ÀÙÛxê›|˜±ÊHÆs³©*»d v›üPÞ1IŽo·/¨V=×j‘3q\ϲÄóãÐxÇq¢©}–¥IÒβþüÊãÑž‡¢0ºQPF’Ë“š°£šs.®ÕJ'#¼)4Ûybƒ{q<ñò�[ ÑŽyÀAù_j�ý tq¯‘•`¸žà°Ö5”r Ä̢ˊø I½AÑÇn¡A层]&“°¡¡Õ›#ÿ1¶¢@&|މ[Ú~ÒPç a:¦•¶Z-}ÙR©šR A((pØøN0L¦QÄ8AذN9¢º¼€(Y®�or:…¦ÖŽ ÏóÒ$)Ý{¯s.!þÞzÆÚ§ù�S¥yæ™ÞìÙÒ××:õToâD—·ì ©cÖ(epL°3&OÕ ÕÁ¬Vݨ˜| ë-âøVÀrEl°Á!C PˆˆØ Ì‹cù!O„%·6ÿ„žÜIæ³Ó¦<‡ÏÃCz–Á,Ÿ3˲Å"+|ÿ²fÓ‰ÜU.‹ÈA­Öß­]äy·Û×j™swˆü1ŽO= Þõý–µÿ‚ËšMÏóþ;g‹qú‰«Šæä~õ+ë0,rF‹ã‚ _@¼> $¼>C ¶nÏS ìÜÊYž»âÄšœØrŽ¢ë¤�O1›NÓ b›"\!g ®#Áã‚|�ºñ ZôöA1�Nç 3×ù‚”ò<\"LAõƒ@uOúÖ¯¯Õ?.>“ÑÁEÿŸÇx9ïÔ±›Âà6d¢ð4Ü;¾˜lWÏãPØG@Jñ}ÈÅÖÆj×õa&­9ŸrÔi]~¹÷·¿ùÏ?/"I­ÖÕUѹ炖ŠZ BÏCÑ À 3“DÈb�ôÝÚ+ÖU¨J—œ0r7› ¼ÝŸXëÓÉ•"em¼EÁºâÖˆ1x|e4<¹ø+ Zœ¾qÃúGž÷»0Ô“k©1wûþÖIb¬}Þ÷]’¼“¦ýÆ´­½×÷·ÉŒyÞÚÀóž4æcçÊž·È÷?´6‚ÛEÆ7È+žìž›·’ëZâ (Þ1ce íAŠ §3D=ŽÃ0àÙÃv»­7‘9Ñógh‹p wˆÜ…# Å«àOA‚ Z˜+¬¬vÃä&¸RPp`ßX.ÍYOW¸P+s«_ ¥kÁ ù²ÅGV½øz§xt´ ¤¤Ó>Yž™ùèŒu¯Û:-”k`jK "{ì…hÁ§B#ϼ$WèÐÀ#à¤ò\$!­á[Yp¿æ)lTBjrëµOõQ­v.¼ÐM™R}ùåñ•Š1¦ÿ7’ßý.ùñÃ+®pÎI’xž×cÌ@)qŒOµ!S‰* ÂÜ“D=€mua|Ð_ªk[Ÿ!Ud éïïït:===ªú§§*Ó~´…ÃA‹}yHˆÛN… ŒÔ°§ ¿y^0Å`@qWY_³fÌ@ºœ·Âó–ù~’$¾µI’¼§4„8^^*-W0'MUÞæŸ¥ïðUƼ\© ¦Øù!¸îÔ-Ïñüv;�Cý<8ô!ú†á.»ì2~üøW^yåwÞaù‹Tb‡ëD> –Nz¡ Ô¦€ç˜8޻ݮZ;ÉZkmUäìVkÿNg©µç–ËçOîûçµZû$É|‘sð7>#rïêÕÆ˜»¢èÎ, Œ9!INˆãĘïvu-ÎÍ  æ‰" ‘ ³&²¶|$ž pO€F/”/:xWW—rÆ  XÃú�»V£õÂâ ’¡×|Þìz€Úˆå 9X”m8¸HBP/•J¸ã0¼ÑÓ¦ @ÛI¯g¡Æ•\¹J÷ ”¸U A½Ø›HJQðLä"ºMÀ?ä–áúó©=Òm¶I^|1œ5k“,{ä㧇a’$LŸLŸ."/xÞ*k7ëtþ7PëKSÐŒ{0È�ä„#ú„˜ÑÁK±Ã›Ç yt&´j†¨†1e9ãfÀWÈ\‡ 2ÆIpJ2•©Ø�±ÁØÑ'¢[ΰ@uPP˜¨ç,˜ir<{#†¨Ù@ÏX–Œ›„¢d„x%Z-«Õêˆ#¶Øb‹÷ßpLhK¯ËÓCT+x’ )K2eã?šÍñYö×0tƈÈöq<ØŸU«[gÙ•Íæiå²^Õƒãx…çí[­nÇÿ¯Ù<7îØ«»»T*ýªV{͘Hd{‘=»ºÊÖþy`àß«U Çh W`9мÂD “$Ñîb’1òq¶äÁuЂ’I4 ]8r…©{xê Ùçn Ã\ÛA0Â�Ó�²e×Qägº¹Öõq`ÅwÄ'>ðj¨õíÀJ`E¦o0&Ì<]–Ðר#³XÿåÖ‡œOóáMŸ½òJ|úéñ5×¼æû•JšÍŸüð‡åÛnët:ÝYÖçyOúþ"‡0)¥ î„sqÕ‚é2 œƒì.ª �H5xq†¶XôBåüÀlV3oN¬~´ Ù&„µ¶øgžøáÑ6î·;çÊår̆@ˆåóˆ{˜|îÀâG04c¶ò¼|ÿµQ£êõzooï—Z­ŒiŠü4èõ²|-Ž÷NÓ~c®Îý`.l6ËiúB¹<ÕZçÜöizd’Xk'VÏoÊJžÐKª/¢èôéÓ¯V�� �IDATßÿý•+Wr7þNé-(ѸÑ(‡`ñhM¯j§ÓùAµzho–×I¯…¡sîäv{L?âû"R.—“$1ͦ®ÜÊ5}£,sD|ÂÕ.¼)¯ ýލØ@o$d¸Ž,ªb?i´dxƒ ï§‹ƒGÄ* B˜Bý­pÁÌ”µ­Ð öQHõ@¶ÔfèìèJòe‘:æ‰1n†íŒ\àÆUA±—ÇØÄ2}zQäìîîŽãx``�Ó{œ)ò3¡ÌýirµÖÇ›A.Ы¯ú>Úùå/“$Ù¥¿ÁW<Ön?¶í¶·ŽñXñÿµ÷åqRUgÚçÞ[[Ww²« ‚`®!EÔ(ˆ5êD“IÐ$šÄ$Fã$1¢ó&Q4Œ hp4AƒJÔŒF”AT@È.›È*[³6ÐTwuWÝZî=ß/õøô)'™ùÚHÎùÃ_ÓvWßåœw}Þç)Ét9;¼#gxDÙ€£0;w8¨æ°m(\`nƒ Z” D Ðr4 |-È}YÓSµÖ(ë3-`Ñh´¦¦¦]»vød´1Œ®)y1'Ï3†rÌ…*?üp&óTSÓOû÷¿îºëúôésj±8¤Tšá8ï&£‚�ÄqŸ/•¾sâñ5Žsg±‰D~åû+”zÓóÎÊå>="‘k …9ñø ¥îjhÀÉJ �aØ”§ÓéM›68p�Ožé°¸;‚[à *V:ë,˜æü/~‘ž4ɿ㞧) Ù;ïl™2Å¿í¶Càû®]3/¿œ™<yé駯«ª:U©Ò 74NšÔòðêlЙÆâÎÔN1Q¨TH*ð+±rVæ�…ÿÀ«gUf†¿2À â¹á™µ'L™U™Æ È Ž$š˜jZ•…ް÷PClÇŠÚœÃMˆ>%6«½Sp´8nò¦@`ƒ¸ŠKâ JÂ7QÀhß¾ý Aƒúôé“L&Yº¥FäCòù<ƒNm–ÓÆØ0 ÝU«¢·ÝöO¥ÒÈ›o^–ÉŒ8ûìš/}饗^š5kÖMŽózsó´ÏŒ­Ï!w€G¼Ã~£0@Å ð„݇ä”An÷À£Ÿå$`ÜŒ5špx€ïR­u;*spØPÀ"Ë­544€ ‹Ë 2™a„Ûn¦0 “Éd†í•ꢔcZ(8ŽóX4zf<þ³xüÔDâ ×]‰¼wкW"Ñ+íÔ©ÓŽ;"‘HRkå8;]·Öu»8N4=]©q‘H½RƒK¥aؤu§ x×uk=oduµÀ $Kƒ–fŒønÁ²È@A‰ž £ð‹Å¢n×Ο6Mwë–¸í6ÙB¹›nòV¯Žÿç,~ï{ÕÏ?ÈFÜv[lñb÷¡‡¢Ù¬¼ì–'žèzå•žÖ žy&÷ío4(Ìd’ßùNØ·on̘ê#¢Ñ¨CQ°"–9Unº”ŠEU1 É(cQPâ:-…�´|GÈó!&î5ÜIA‰«¾Ø-¼`ÒBÔ1õõ<a÷aÊZö‹Œž0ž¹ØkÄI€/‹EâRž!ÖÇÂ6@B Ž~40`úè´IE1f³ÙU«Vù¾ÏÒxVaZƒg„­Ëiã,GÞ_¼XŒ*ÕéùçÏþÁ¦RŽãôïßåÊ•aT57»åÒC°À-†N”EÐf`¬B y\6&�ŒAè*ç Sß(CÉçHÃ&¦e¨ôu¼`lqæø’²ƒj=¸ŽâÞ q{ÍÕæ'fúzLÆqáÎuÝo´´|+¶:N§0"Ù•Ró#‘–™3ûΜ¹»¦¦è8ÅRé;…Âç²Ùi½{KE«X,nTêl­Gd2ÇùS2©µžçyA.úi=¯TÊ…á±AðƒææÞAðšçM+ƒ…r¹œÌÆ"Œ€ÙŸÍ8 ––Á«‡VD™zÈÖ45µ:4wó͈3Jž)ƒÁƒõþý‘?ü¡P¶YNU•S(¸™Œö}'ñ<Ï]µê¢¾}õý7oÖ¥RdúôH"á%¥“Ov׬ Ê •ϳ6°'•R{  BY˜ymfd¦A&-{@`50g¾ïc’0dè`sÕ‘™,„ñŒb <ÃU/8'ùÌ48bì?€éç‚êr2»&æ€ÙC*sY`—eÛ†RQ< 8ïÊֽܦ€/—È€Ézâ/Ï!—ËÕÕÕ!¨å“…BUÌ“¬Öå´E;GÊVŽ£”Êf³«W¯^ºt©ÖzÕªU™L¦VÐMÔúæ0ç ™8sn2m3¶l,CÏ+ÚàYâ–;t (e�p™©¡¸#ÿ €fnGÁå0®_•É@<E;$°°\ò– æ6&æaÿd@H‘=@Ê õSÑh'­rÝ7e’ÎuO/WG"Ý¥ž‰„a8.ë¨Ô“›6½P[+×yz†¥ÒuÉd÷0ÛÒ2¯¦fl,ö}ß?J©Úò«Ihýz$²,Ÿ“NOëÒˆ <4¤)F看N¬âÕ¡CÇqZZZX$8^‡çy‘7®¾Z-X úö £QoÖ¬C:@3f.¸À9ÿüÒ²ezâDÇqœƒWvêÔ7~àÞ{U.÷R,æºîr¹Çs¹5ÿõ_Wh=*Ÿ\wJ,¦µ~¬ªê×¾¯µÞéy{\Wi½ßuïÉåB­ÇÇãLV Fÿó<-û\âÖ,Ç“­‚hlLL)» 6”5Ó¸ßÉÈo\-\ü“3QËŒâ˜`YŠ„Ü)äÏAÉEi ‡j°¸7l {U¦òø»F»…%¸dðÍãà`ª'Þér„²Ä‡ú<ërÚ¦°¦”ÊÁ\Ï‹ù¾^¶lÜþý®ëîÚµ«©©it.7&Áˆ­]ÃåîåáŒD‹˜ð (ÎЃAN`´U!§Êz9@pÍÙwP™¯Ó 3 +phL\-@> rx¸½hvºÆUñ1À8 Fý؃/¾^,þ¬¦æ=ÑÜ,~ìy=Ë~ëô ˆÇåEŠíµO$qK%].&ü騣|ß?*›•“½ÁqÞ‰D"ž§Ë´òHY¹™%òäaÈm"!pÊ„Ópùr¨ÝKÿ£ªªJ)å–Í“RÊ]º4öøã¥ .Î:Ë{ë­CæóçG½Îõë·ôÊ+K/¿|ùË›ï»o’ãt5ªð‹_¼ë8á 7¼=gNdâĵžW¬ª:Fë¦0\ãLŠFë´vg“ëîwÝ@ëgc±J¥@ëÅñ¸ÛzÖXê®2ýŠ '@À#:Aüa°3ˆñå 2¦UxCÊ×àIƒˆ�fPódÆ�µåˆäæ¹-„zÜ”¤ÈðCÌ\À¥*®?£¹‚cåV¿œžÇ¥CCKdŒÐáSÏ~…'‘ŠÆ£�MŸíå.µ5'<¯ÉóFíÝ{s.—wÝŽ¾ÿù|­gºn×h4R1‡i ì î‹òAbD²1…ÀÈTdÍHM¤Ô†&66:*{’`‚G8µŒ9gP\;ÄìèØ…FG 4Æp‡Ü·`APÀÏ1®¢±Sh¦‰E–XXœºÌEž9ÎØ\î’ÚÚÇwù™gÖ××/[¶lUCï G©_G£­{A¯|¾S<¾Óu]×=!Ý«µhq÷)•ŽÒz—ë*¥îÍå^ÇëÃP;Žïºn<ž ‚Ïhí†áÎ22q=£ÕQcs‰bºôÐBÇðÖŒÂ;‚(åš‘õëÃ\-ëC�ÅN¼­[½uëöu”>á„„ã(Çñ<o«R«Ï8£]mmᢋBÇYµ~½ Çq6)µ.âñ¸S6ñ‹Ë”ŽRZëJí¦r™ä PAY˜#ehÀxah‘-Ƭ~eˆõ–‚Ø’Á¤Àó:ÜK,÷!‡”‚‡á¸¡ˆf'p=òúÀ²Ï7Jðf6wx ½QÙE O†2ƒ�»XV·c mUxÅp:ª<vÍ<�p£[ ërÚÞßÈW=ÂðÏ{$}%®ÒZ)õ@4ú†ç• ‰J•×‘Û ˆ@Œ&Þ7†0XSËÐ8ÁaÜ«çu<ø*¨kˆÅG¥¢†øŽUã˜øÉ °åŽŒÊ˜¢)N®UJ¨ž°d'ÎV‹a)x„ÏÅbQ+WÊWªW¯^ƒÞ¶mÛúõë2™µÅâi¥’ã8K<¯“Rÿ¯Tj ÃM&•Ö—47¿TU5?i·är JÝRU¥Ãðödrt:]«õ_âñÅ‘ˆçºb±áÍÍ®ãÜP[Ë³âæ¡(NF*Jç  U©Š[b*FÊõAiHkW¶Áš5A¯^úª«œîÝ#kÖ(¥J^{óÍ`ð`÷¸ã ûö…;G7lp'²paaØ0¥”³zuÏ;ÑhéôÓï}M+ݾÝ[¼˜}<£%Ùúã9ƒLkŰÅÐ åI,Õš­RîZÒ P sG2c€ °Ó0ކ‘áÚØ9•º´’‰)ÆfåÄBÊźü:¸‹+”ß7 ÝhöF Å?HâÆ1o‡¦ Ã8åÿbê–5àUë P€k*gæ*«m•Þ°²0Y–ð¦—춃ŽóR$ÒYk×uG%“Ø µÞäysËÅÉ„±–bŽl,n9²N3jqƦ籆9ÂÄK7qæ@–ÃX{Àfp€UkõC ž¡Ò†æÉDø!@°w٪ʽ€› Šæ'·,5þ\ 3ƒA°iÓ¦I“&566¦Óé=Ž3)?Mš^®ûºRÓ£QD‘ãâqA¸MD^NjŢ[¾©[ÊÇÏu­õÇY‹E"‰å±HË×€Ò" 7Ï”$ â2('Мk%">gN°oß¡ óúëù‹/Ö½z¹[¶D^{M+¥:tp]76yré+_ zôpׯwgÌЮ[uÿý¹«®RJU=òˆö}µt©×¡ƒîÒÅs]ÕÐ�ƒ"ý1—H‚_†2²uÃàhXÄ…ù¾ì‹_A¼ÏÉo6´*Å…Èš1ÇÃ×iì^ƒ­€+ÒìºÐPÄÿ‚¯eTK%|Ÿk 8³œFðø3’$.*°¶ �l¬sÞÌ|Šl²²#ep<J¶ÍôJá y_¢ËÇŒ®NÛ‰åX—ó¿‘CÕ‹=–H´G"àvÇ+;´"9Ý‘Ñ?ì焘N²u©ñ^guNAèŒï9õ€iFr�p Ü’q%¸6Æ•¡ò.ý* TÊ×ÜÁ’ÈTê°ÅÐ>^et´j@R‰ØÛõ0v°JòçŒÇG ÿR_ŸN§vqjt(•æ”Èñ!ù|^$&16vn•!Læž9N¬Ü)$‡40Þ´¦¦/š‡QEÁ{„uq™ÖÚ[¶ÌS*‘LâJyýõC�9‘e{ùåCeØ©S#ÔÏWMMÑßþöPMF)wÆ؆ [ÇžDÜÍ:Ö ;–È]^öêlâq‘óœ FM?´ʨúJ‚ˆCØq’l UrÒàH…'àR^ec ØQãàˆ¡Y#´@ … ¸²‡ÿË•«0 ³Ù,¾o°t*ÔœÍsÅ›ƒdEÿ¡&êwìOœPÙl8Ë8Å:+Y—Óö Ôžçår9¦˜åiDÙFÒ;æDiub6¦GŘAúÍî…ÀßðtN«žS¹¤‹SÇ#oHŒ fxL\£ÔÎ*,PÏþ( 7€JK<¥üj8çr¶Á…%mgô9¤7£Ê-zc<‚iFñ>Ð,)¶¹îgÃ𱦦±ÕÕÅbÑ+•-_ŠF÷ OA¹.$=pÐÆ „]9Db„ùò¹[ Zðîò“҂іĆ:‹‘Y*¢BP2™lnn|‹Ã®£2¨ÞTþVw¥Ú•JJë¨ À–J¨ÿD£ÑõT]‘DD*¥—'c*¨²µÑüàbA æ/›ÍrÙ›ÇBe ’Bž6¶%2£ €{¥L¹ÊêKü0A›‹w-xEœ@å±ì&råðŒ„lxI&02Ð'‘ˆ)+G…8ün‚O‡<[q6¹8{&æ]±ó;à^¬Ëic„4s6Ëñ%(h_B4É hä#„p™§ð ô„x;צpDÁ&‹âØ�Á>€¨E90Ê€ú â •bü ¢<ø ¤írï8ä¬À¥"MìBÀ 9—þåù¼/,'Ãù+ÅRé J½‰ô‚¹*¥òJ O$”ã_n&ó€abþŒ^òXÚbB“a Š»Y‡‘…ËкãT,e<—ËÁíñ=,…¸^ñåò ÐÄæžl¤d2ÉŽ‡õ¤V(ôÕz¿ãôji9+¤8<Íu•R—ø~¯šãWJõ€LÀZØ3`saŠLpD¢Þ TŠdG‘@�K 0"°”úÊ9cX®2XÁÈ&i¤âÄ¢ÔÒ{Gœ{ œEo IÀFð ®Ã4A¸ÍÀVCGŠÛZ}˜TnÁè 3ù7Ô§P<@]Q^ ˜·1‘[—Ó– i¤8lõ8óeö‹JePG‹Ê“Qq‚:=GLØ ø©Ä ,cÐQ×ô˜ ¶wǵ˜Ï󪫫ѣbÊw®«€ä˜{9Ü\Å]ã<p÷Hn󞆾  É¨þA° ‰„amÖ»îm‰D<Çãr¹R©ôR,Öçs9&"ìû_.•«'Hp§u†÷$YbÀÈœ<P¢ø¥p8 FgÏuÔÚÚÚ3Ï<³ªªjÁ‚õõõìŸ8òàx–)èñ‚Ö  ÿẮS,މÅ./÷%“sjkµÖ¹túèBá¥H¤±oŒOòËd‘;4¼y)$sr3%¦,ñ ÀC)hŠb<!€@Ø„ï Äé€!wÍ*s8¹â …‚xAPKp Ü�+3… ŽªLºÁ=WÖát«²@(’ÄÈ0jL¿ OŒÒ4 òi„,Ü æèoÖél/§-**¨€CkVE„¡  ðRY+½e‡g ˆ!8’ Ü^2™,‹¨~(â À1dcPÈà!Õàd!Bì†B¢Ëq’ƒÊ$7ì̸{‰½ÎÍLVU,�÷ñL+ŽÜ:×]G äˆç%"?-IK¿<£ ø1­õ¥Ò׉|¡Tº;›UJpœoWW;®{O6›tœ,A†xHrôFMƒÇPJ¤ÚMU¦êª­­0`@$YµjvבŒ˜c³ˆyE\’§[xžŸ9Ë9S¹( o>öØêÓNsgÕÂ…?ܵë¥ãΣ6`Ƭ|È �@”XQ8n…G\¡!„CJ&¨¸ÑÆÃtär4�‘Ïçó Û‘‡‰º"Rjø6ž¼1Pò™¸eyY÷47?X[{°œ)NÉf«•z,›R~r³¯f³‘0üÏhôõhTk}i©4Ü÷ǹ0™TJý,—»¸P—1&½\ªB)Ó0¨•S¹˜{û(˜3a¨äšìŒÉT/åÀ³Ð5KyÁ:áwåÉWrœ[—óIÃP@ƒQƘ®˜'´:¸Oˆ,¢Ãe1Ž÷9öAÅ ¶UnzcZ»Pø¦`ä<K– T´ļL*Šô•(CÙ‡™Ï\gMM Í bLVóq‚ƒdcÍtÜ£%#‹äIBË’óN×us¹œþµZ?ÚÜü†çun×ÎsÝöÅâkÙìĪªÆòÏs-wʉ¬<gŒŒ LÄã«r¿€9 …t:ýâ‹/º®»{÷n1|lh è#¾Àêu>Çq"=zäî¼31~¼Z¶ v¯þ­u±8­¥åKŸÿüW¯¹æÒK/ Ãp„ ON™òouuŸËçáÌ=e�2fU–°”ý†ÁdñߌGà¶ÜpUUU¡Pê<à5ÐA1ædñ0í"çFðsxP"ˆX2°c<…i`Ž•RƒJ¥{š›O ñ55Âðﯪ*çyw { …¿–·Ð+--É‚ãŒòý¥²axQ¡ð•ššh4:³¡á‚drl,öH,–Ãk ¥¬êû>* Ÿ‘ #0Nx_ƒ u<>‰ˆÛ„ Q‘ ©„Yp-˜}–‚@˜k¡TªP[—Óª ¯ˆlÆ!ÌÇœó<<Ïø`®ÔÊl$Öà1z†¨¤Ã. ¥à*?h¸€�fÔ``´ìQ9®¬)€bˆ!ňAñšçÒÅ`�‚[»r§é!·4˜#Gž¹1Ðǽ_Œj…€¯x¾ÁJMD~FG»î×ý~uõe¥Ò1å@Û ðæ–8N½ŠxíhyÈ̯*Π¾¾^n\B˜Nl0üB+“‘âZk¯woÿškb?œûæ7£É¤÷׿b&à”Cµ{¥j:t8þøãÛ·oïyÞñÇ_U]-ïLÀTòp`’ø¯0|Kèvd¯â™pŒÏAU̳Øx ~@¨„œ˜[2bIñ¨‰„x>ôùóÜç…yxV Á–ã8s]wp299—+‹AzžwKUU­ÖW ¾Rû=O•<o¸î?—JŽç5{Þ>­óZïWêÊb1ªÔ¬x<‹•‚ §*Õ# ŽÇªRríQ•g¨qBÂÜš²1PuD·Fâ ESÆ,†«‚P€ùàà ±;ÕšVÊÂÚ¸—cð·sCµ@d#$ô0d»``ýG&¨`T(kØðÒØh1d:t¨­­M§ÓF…>Ñ8¨˜KX£�4K1¢ËÊÝ!1lU ~*ÆY¨2µ 2£ÐlsE Ç ú²7uúQ¡pJ»v5UU½{÷vgãÆ+óù˰¹Ê‡Ráç\q×ÌpŠTΆ‘ß,‰„81,ǘœ3¡ëºn¤K—Â~ûË_ܵk“=”¿îº’ãÄæÌ1|? ´Û·oŸ?¾”ÑfÍšµ{÷îbëF#\5s¢¨ìŸJmi|Р>–ä`­&U&8sÌpùg·nÝ´ÖõõõH ¥ŠËWΦåG@;.¸¡UÃãn.Áœ|^€@%b÷Ékש½XôXèR©PF:¸J]áû“c1ù9¬û€¸ 1œák¹óÊòöªõà02Q€2PÕ”ˆ“ÉÖ˜Âq\G¹Ï˜¥³.§m\ê�l(yŽÛˆG‹EXWN‹Ì‹p•ÕÎ%T.g6ÄŠØ8Ò‘ìX’q£Ì#Ç:uêÞ½{.—Ä3(Ñ$Гp Å+IGøN™ Tí1>& €øZEúƒFðŽú'²$6«ïðH< 'pLSˆ¤Sµæ¥gÂSù_]»v½è¢‹ªªªžzê©;vÀžªÖª—ü®aˆQÉT4»‡ T™PT½С²d2ß ™Ê%Yù§?fLõD·nõ íûz„ì7†™LbõjØÜCÇùI4ú«;îzýõµk׿óùuëÖ—NoPj}¹ÓÀm6 Á ¥HN0H˜L&•RMMM¹\͉ßÜðe£R¤H1ãq8xI¹„ü”'ð Å?¦Gæ…±3‚×—ò�Æk*™’yˆUöáA­ŸˆÅî-;çóëËÓ]_Sê²h´èy£s¹ÎAà;N7¥~—J¥ù…ÂÉ„R*âºgÁ/ E$`Þ À¡ÌЄD{<Ä ø@.—cVì@îN1èfƒWä:ÆkßD[6έ¿Aqá³dòÐ86 õÈ Ö‡@,X®Vù×¥V&Tçh¤#¡æS­%°vïÞ½|ùòt:-›[¢N˜¹B¡À꿨žÉ÷å6ÁôÇp$˜Á5�Z&W‹‚2ˆ›¤ÜÁ|ì,¥cÌÜ—pP;•!ŸÏX^ñô²@`,×ÀÏó¼m®{|ì߿ƌ“'ON§Ó"Çu›Êa¦˜'L Ëà.†f@' ­y¿°Ôr%<À(Ãða2P‰RªüiL˜³/ i-ŒxòI÷ý÷ãñxÏž=“Éd¸¿3n\îúëKå9åª%޳ÞóŽÏçoÞ²ÅY±Â]¹ò¼ÆÆ+ê”jQª¹¹YÚòØ«²Í0x(›Î&LÞHŸ>}Î>ûìd2)—-»HðßHq¢Ñ¨€k0ßÃa*±ò¬äïŠ~¥ã8B$Ñüiá˜ÃV¤”X9žØùp;ü|„¾3a¾ï·´´¼ØØØ-‘]$í >Ú‡>™Ž:Zë>a¸©5Y†j- ÊJTÒ_dª9L醬îS‘h¡jÍ*Ë F>®j H@„i³œ6Nt¤¿"->£±aŒÝ°ÚzÎÀ bÿF5L÷{˜•‹»8<ÁÌø¹\ÜK>Ÿ—IC­5òq.¤�Ìȱï¸)4P8†Z(7~x ×Ï„r(¤ ýΓ’(m1ù4'LÜ1ÂÅ#„3¨ ‘H<”Ïÿ2“ycíZ­u•Ö¿Èåêg¤M­§ÜqJ£%Í|H=â°è=þ ãÂ9+†?�ÌŃb ¨©2¨D)U}ûí¹_ýJ'ÁìÙbvÃN¿ùÍĘ1n6[*×ÈÿI©?D"gåó¯ìÚ¥”Úéº÷Çã°3•7‘\À¹»K^ÐæÍ›wìØ!q7Ö˜XµS‘Ž3 9™œ/ålŠŸ*‚r4Ôó˜ F�–‰ÃÆCÇžÙ}fzÞWs¹Bd=o¯ëvPêߟ¾êyß,=°‹�� �IDAT"Z7¹î>Ç)„á~Çùn¡†á´hTÒÓß66ž_S£ËO Ćæþ‹…w8—ÍùÉ#Ð'‚|<faàÅ<sT2Y÷ú¿#E´.§ ²P060-‘ Œû¾øË@¾Šñb‡Ä™çþ(úãP"çQgN_T…BóR‹}A‡dÆ<µÀGÝà¶‚]}®q‰K3zÑ\ªÆ$6úà!†¿XrTϘµk¢ Êq¥æpç¡x¼_±øeßw§ä8k#‘w\÷ å“É:ŒÿàÂ!Gp€PWày\ c$®8i㨜ìƒ5Aýžo*6ztîûßz^ðÖ[ºcÇâ÷¿8ÑÛ¸±DÚ€r§Sb±~A ‚wâñå âCÏu“H(2aܪáWÉT+,#à.®¡ñ,¶êr E@ÏÄ*êD7…‡óeÃË(±ªÐCãËL6B+öL¬ÄkþX,–ó<ÏuÃ0|$ýnÄ=or$²ÉqŽ*ù‡‰k|_ÁÄht³Ö¡ÖÿåyƒÂÐó¼ 7 ƒ Mtð‚F.κ…K4`î°*’Ù @{†Ý$ˆðöÑE€¿‡!új[¯c]Îe ¦˜8Šq´,“\ÉaÈ}ò4f´4ð"Ì8°ÆžA‘ûÏrIàÀѼŠSC 3ØÌáÁ?€äF:�Ìð(ç Œ©ãR5SãÀ‚­€/X­§Á&"P®DWœó¿‘¹\£ãÔj}¢¸+¥Þõ¼ï*ubÙ3ÉÅ9×< ^53©—jÍÉ!zfе¤vÇêÝ`ÏħÉ8䪛š’ücþ'? ²Ù–ýHÝqG¸e‹ŠÅ€Ô€yZ.ÇÁ€Ýrè—û@¾ÀUs‹ÄÞp{P3ô/ðÍxNÕZޱ~›e½5)*€‚éÆåyI!‚}˜`í¡÷l´<åLD pË‘Ü õ×äy³ƒ@2‚§Ë­P¹«M‘ÈV齕ÉD¦x^´µ®¨¸g žÐ¢c¨𣍔`ÛË?™¼óÌJ'èGOžŠeÌ‚„M›ÀsÆÁáùërÚx!ð €[8œ®‚FL¨Ã$@c"Kù]ÈÊrþ+øzÌ„[Ér‡PoãÑhÖªgSƒ æLZÖ@šÊ•Û߆A¯)‰y¥@eý¡òé¨1V²r‡Ê®˜hÚïÔ`”ÚòÇÄb£Ë ø œ@±ÀÁC–é�`â5T¡ô#v$¡\Ög’|IæÐ`ˆÈÂ\LYTÜ·/ñÿ‘½ÿþÚ[nÉïÛ§Ë.WØ5¶$Í “ÇŒƒÁ°c³Ù,&6 eyJÂ’‡5|Å�¦>ƒV ƒ±,ý‡rŸü-iÃ� Œ²R¤ÜÞgšZÙ‡ÙlPiÞç\xÄ8‹4?€0äÑy’Éd2Ëg27Œì„}(9 A‚‘Ï5Ø:€jã: óïq«˜iëð5Ï%ÏÆµ2*ž‰[’Àï¡q‹2£¢>,kØ@8Éœ”0)6+HA/3b ±g¥š€˜ä5“ĸ˜¦1WÄÙ¥Hà�b£ÒH@íH6%Ø>XÞ CËØµˆÖ1£DfÄÖÇÿ …l‘¬˜L~ °ƒ–ì8GÓlô¹›ÿÄ4hüÖ¸(2OÝœ ¬†(žà9 dа(ö†´ˆäJ0Ó "�‡ÌÌè1¢DlCL3ÁÚœ¿b¨–yi™ ¸J\³Ü…ä–)F*²ïdÉA¸y‰Ê æ„Þ´™'T‘ŠÚÂAŠ»åú^œ�ê .4TC;JŽS]È× Ícì2 ªHJà­QèãcÈ9Cðâ‘\ ÇAµ&ÔᢢÄXhY¡¢ÈàOtËQ±ç–MÎ*Y Z±.§-S>ŒÄ'Á¨Ê¦q!#n#‘ˆïû¨qd8Kˆ8‰‹m!Æì ­@Je6¤™@õÁG™‡ìΰãÒ‹Ÿ´ ài8©BÊÅ• U¡<f(A ágL*Œˆ“ætá|…‡xd?ªµö!ð…0P,©îx…‰F€.‹èÞhŒ1 ÞH-\³Aô‹œR¼Ì=7ö /0vù r\`ôQ~á€�Å,xz†Ž8pЫ^@Z)À$#v˜ÁGÊ&D&ìGŒÚ7F1m&žV£6T-äL)…ŸB¡`xMÜ—§ÄKÁ¸s£³´ì\¹BÞ±cÇ“N:iïÞ½;vìÀ5s*É ESáª5¥!Wðùòº† ZO4£0‹=†0NµP”ZÒºœ6«ª!z…Œ"â#İ`hGþnÌñc†•Ì+XØÐÌÕÍ'<¬ÍÌs|¬H(AÔÑÀG>Ž"¯*Ò£WŒ Px#9'ÜÀeƒ¬×÷}$1pº¬W ˆ®Ó!‚ª)tÐT0^–ì%Â0¾bȾ–ñ:ùap£ô3 z=`ùŠAòÇH&$XnˆÅâñx:Fj«ÊÏÌïP¨Äeà]+Òkáz¦¢¡KôÏQÏä™'“¡BË”¨ƒÉÓÀÝq¸ v]ô®aïÄ `(ï—¡Œ<Øû=¢/X<x€ï€S@<ø-È)F¦‹¦: Ûë9Ž[N´ãD<O9ŽòM’qŸg8é½zõºüòË—,YràÀ9¼ìBp¦8á±\t\žÉäÉHÀ$|æe0¸9ã炪mûÂ×Á¹t†.…pÊ.�;1Ã4Ï�ó°Ž{©€ Q<ïB†ÁŸÁ¾ó4Ð)Ù³¸Ä8\ç‘òŽ\L<ollä‚‚&?†öX®ÆD£Ñd2)ujPªˆíÃïJõ\~†uQJ$L+À—ø»xªfÒ4+“È¢^(÷tà˜2x-5±‚ò3Ÿ2xA V!2ê!•²ªÂ1tèÐ^½z-^¼øí·ßnjjbä0˜¯)# Œh1Ÿw¼d‹JKÆh @]UV.ñ >ÿ¢<m»wª¸Û'·€¶ †F—(5Zj ôBdžXž�÷òLx!(>A6IÁÆúÆÆ­ž§µþlÖh­”ÚîºõŽS¥õRÏûת*Nn¸â-tòä7oÞüÌ3ÏÔ××777 b $Fœ*!cÁ£÷¡ æˆfȆQá`z-³¢*�^Wžò±.§ –p�‹X–m寡:ÎãÜ»¡í¡ZÓ?ólk²Œ B<ní b zÍÑúÜæÆ½È×@¾¢hÃ-ˆ4¹IÃ#@`³"bh†rWÜhü² bRTØ�ÃE¶„ F âo`FNÀò˜Ü§” rå°ÐKŤ:¸yôŠŸ<'Œ`–{ìÖ­Û—¾ô¥Þ½{G£Ñ÷ß.Yž­¨Ëà6 ¿Åâflj¹] š$C,ÒÃó¼LGËO½°™I_Súm0jŠè*¸ˆj4cäí°¤&„à ž$Ù5bN0ù»�àÌ.Ò\£š …½ªª*ysˆ¥©ë<ï_ª«Ïõý”J*¥g¯ãTj^ÜX¶FNjֺ͂±±±¥¥…{œŸqÿ ÏIb2žm`±mVG"†‹±ýŒù*ÖA1ß,².§m–pâf³YDÜ ðä?÷0Ù{c‡ & ‚@d­cB‡çuXÃ\„yà p ñ¨˜a#ò¸ 8Bs‹l� t_¸ÁnIŽÀQð"R"rß÷‘àT°­dàÔƒ¸ÉŒã x˜j-ë€Z¶¸½ÏgQž6r¹8CfÐá©Ì20INAÅÍÂbr%Åb±¡¡aÕªUXµjU6›­”íB1JvdÒðshË1>žUaP³20\nbh8;N0i¢Jò–0ž®Xœ2rÏAº)¼ÃùåÄàFÄRšp /ÈÀm]NéfÉ]òÍÏ‹g‡á¿WU5D"A|¾X|"—[+Òãà„Æñ'`Üñ4ð89ðHcΞ‹ L´ŠØ”EðÇ ½ÇM´‘à„x°Çsµ.ç“^ù|>NsŸ`-¤AœÃF]…›uŒ{áqQä+ð^Æ´>p¸(c$Âèäjl´"¾‰60¡ÏRy=nuqŠp«w‹Ë‘r¨Þ„_D‚P4‡p丒uwù-VôRÄ–Æú¬ž >’Ã:Ô7$·ƒ ²X Š}WUU%`qäÈ x ¼UAyI ŒI”={ö¼òÊ+žçíÝ»7“ɰ² C3PkâÇËÀ Ü &{{qÞõD±qØÌ˜³Ž š²á¥I öKnDÀVJ2·Š¡c«Ëû’¤Ÿ9¼v;¹[Î$c•°CÀ€Eþ†á axfÞQ[ë'“b±¦¦¦E¥Ò?WWOÌfß.ç¾Ršc¡,fjÇa1D¡b" JÈû1]$‡…‘ëü¬³ƒ°•5<ïÅpSÀ7 `³œ¶\ÅbQhÞ±8èV4TÌT(q<Îú¾üMEú»²EPç™dÙâ\ñ@ ¹ŽM±ËÁ°ÅAbÆA>S‡â )¯”›U¨þs®Zµr˜Æ°C-±U¦—˨Ä\ ùE5rDĘ gãæ3û?Öñd–h¸|�^AùÅ|‘Ø*¨1•â_„ö,_´qãÆD"a€aëlôxñàm2÷j*§Ê1Ê[uEýE·O¾‰D$…¤;ÿ¢@*¡ƒÅ1{ZŸÙ´Ø$éù�F†¹s@ˆ!hÌ<É–�arwyVàü7š%H¸Y0®T2 íÚ}å’Kª««§Nºk×®aØ+ –‡™Xû|KÀr0$ÿ¬©©Aë´OŸ>AÔÕÕIŽ ‡Ä°{º–‡Ãá ?eÃpÀÚ5Kj! B~Œ<ÉP4°.§ zòˆûpÎa ¸HÊM{þ¤Àœãs1Ú õ…¬…œFôH¹ˆH9 ?+9eŠÃD8€£âäªH4È(ܳæ©hœˆåcØœÍ7w•¹¯Ë-k¦¤c7V eì/*þ¬X c ã³J¨u  Š™üºà}yŽU€ËÅb±¥¥=y8îÒ¡�ÂlbXŒG>%øl ”°Ì³4®°I8hPÄ®„!Vc¼5@™>‰Çãàï2ÚòxA'¹ §ÈæïnÌ`ÅEø‰0ÜþDê°]YÙïiFU¸»‰Jc±Ì€þ(ÇÂÓ*oü ¨\9ß·o_ccc.—߀äG@Ÿƒ.)傉ÄÑG ´ŽN¹Œ–>þŽƒàÑQ)•‚è…˜×ü:ƺ³rò[,òd]N/DÜÃg:t„3R¦gà4NVX¬a/—ȸ¦†-&äO0+>Ó¸ '!'ÓîÿÃ]\.:WÎKsnTóp¤¬“§kcA˜~Æ%Ëa“>Y¨›%p*ðÇL;$5ÌÙñ«D3Œ«—ü yD¾Ÿ?òW®ŽòH)MâÍ:øEžg5É2°@û!Fpi jv®ØE!Ã&¦…PÏDµÛ›­^·ÊÁÄÁ•.øiÞá†Ð-³ðR‹Ü§¤P³E}»8�p»dEÒ&BvÅ)ü¢€§áøµÖ{gã¤æÏŸï8NKK‹ëºÿ^,ÞžPnÉp‹±ž•æ.O@6U.—[¼x1 ø|¸x>~‹ñ–ر õäà•;x/c <clùIO¤X7cn² 4oYC^ŠKŒÙGm|Šà²–Œœ@Pdr"ÂÍmÆÚ…2ù(üQc*ž©d¹Øz Ü›E_Iîˆw-“ÍÀ?‰Ùò}Ʀâ!dþz\¨ÝqèÇ&˜o¢”ß  ícâäs·>†%ŒZ–ÄÂÒ|’!>ŸRdõ nDƒ—ˆaèU0‚™'íåbä6ÙDr'™¡ä˜Ž” m�FEB[Ѱ‚–.ûÓx›ÕÕÕÒʶXG�ÿÀÆžÒëŒGž'ò±ÇÛµkWEº8°°‚哇ŒR0O ¦Ã˜½AŽD„¹Ø!59ÎÇy0›ýL:]llŒ–J# …)•fà ×ú-¢xA–GB‘CèÞE"?p;  à/ÜÈàrh,ñ…qÃï GU"<äšÜi³YN›!ÖP•†-@3Õ[ø�¼-ø> àí¨ á–>ÛA ‘‰CÉÍÐS³Ð3I3s#ªÖÔ,•ò£²e‰„x H[¢ÄNÈ€¸àFpU|†Ñ Â$<~+‘H>Oïƒ[ n�mv agšHžƒa§ÈSa$ÄÆŒÂnŽF?RVW„ áÆ¯ëºÉd2ær9TÒä®QTÑZ×ÖÖ‚ñˆç·ØÁ`œÅI5ˆY¡n|HåÄvK¾ïcC"pæm‰*+ëL),K 0<LB)[Aᆱ9RY* û÷ïÏårÅ8[B÷NH˜ÄRƒ±Éÿ 4Bƒyã¥0îI¥öF£7ºî£¹ÜÉa¨”z4ýf<Þ¯Pp(/AZ#Ïœ¹?ÀžŽ—Ó4ù!=%#œˆP»cXZ’È}‘£yƒ \LÈ2;¸ª@x–iá‡E¢Ó*û+SI2Ç·g�©b´.êû¬¢HÒƒ'N Åüž˜&aT+v’Ô`CíÈ-V}F¦H^£¯HÛa‘™ q:\ºè|aœr/'~*µ ÁšÅsæòÐfš0òBŸ8l~bœÕ1‡#ælä¨Ka‡#�¶Ñ�XËÏ ?á’Ô¦1 !_wîÜYJðÌÛȶVØN`¬�…Ï$qǵ\Tê¤ÃÏs¹ù&rG¶È §@·`8cE´ùÌ/Îh<…œ ™.Jy ˜ïØÐЀ¸¥NðÁ0š™1Hw0Ü ã‹!3.kP=䂀̽‰üS¡ •z+y«\üùg¥´ÖsH« %Sî~±²7`ŸâÖš"õaÔV†µÞ¾9ãž%6³¼G¶?èþ"¨ÅÀY7/¬³QåLÀÀ@U¤Z«ÝXgxD�#ÜRa‹Å¢DÁñ;Ö¡àFû÷ïŸN§·mÛŠb˜�œ1˜pÈ6Åp N‹œR èp—ˆ[P×@qQ¡è¬€@ÚȆ¶·1Πs´ÊðX ¬9< ¨Ê iø&�+¢ŸB¤É´WLЫˆü”éåùäÃÙƒ •Gí”R---ÙlVax\žÔaøsÉ :Äù C›0žÅÓ— Õæq±h4Ú¾}{É´à¸%‰'?gpVªÖb¼%*S^ÕZ†å€‚CóŸ?™rô_P[h™0Û—ž8â‘C%pFÀÿ!ÂãÆZë‘UU©$cöŒìþå. jM¬‰‡€³™³p\?ƒ’!ÍZ$¢­lL5°X¦8Öå(#³áz·Lùrù>K^Ìœöš™5 Œ!Už FÐW)ºƒýÊ ¤rD‹ž…O`MØüñd"þDuuµ\°Üì‚AÄ„ø]¨Û¤4Äa#ߪÿˆšQ5¥lwÌ^° cº"V]ôŸÑ “g…b4ƒ©�”HxÃú€U曡ƨõ‹¡—xBdŒ±=à€A²€Ä ¦¶¥¥¹Ó‚I“‘ô°­ð1L«ÊÉ*õ€–ÈmÂ’"FVJuèСG;wîljjN]1ÍF_ƒ«Ì¨m¸l à,d{pÀÁôÞ†¾ Ïo2y9\¦ G|fp×`\Œ²P˜€>@mÀ»ðþ4Þ 6P¤Ê<9Ç�zV’e~$v|À=¢Œ À:;^ â1Êã•%8@fä².§-—=Y)“,ÅPäõ<�ñ߉¼rHJ mDçPøŒÙ-ñÈ¢• ¶nÝŠ¡KE´üpN¬õ‚s.iM:æÀk†ò(…Ù T!X Jµ¦»G¤ÝkÖAa¶”Å$ |àQ…@£E'&-…h?Xéô"xäþ6C«Eñˆ1 ò!ÉdRØ(e/%OF~‘[¾<\m7�¨QSƒŸñ\rQYœQ¤B¼×TK¥R:Îf³â?Xh€ýSÔðT 1z?r³¬„Æà4ƾ3]²‡óù<70” Îã@¤R¿%#Ù@¦±è_¥ö¦¬à9€’Ç•çóyÙª5u/û$Ö2„;g7ˆ<¸ã®ta9î”]Þ>×TŒãÉ•Oxqi⊠Eᙈ=J–£´.§ÍærŒø‹ûÛ"€ÔÆ”;Ï?¢$mdÍhƒ¿h°½â¼¡ýÀd̺Ϻ>L•ž1TŸx¦`í¶!ˆCX‡ ¤1pÃ3φ>G¥¤¦1G‚òûJT!8ç¹{„›7 ¡.' 0RЍXš…u©TÊd2ÆD’<øoqÃLWÊÕ-Ž©åu0›XÀvíÚuìØ±¡¡Ëh˜QÇ´?—t¸Á†À™gª¸«Á½Lé²Lð\IBáðͼùy's(ƒï )[W.Ry›¬ÜÁ–yFR \'Êp‰NdW 2àÎøÆÔ ¶f�A1Ù äêx<‚ÊÃ|x8| ¬PÅb ¬Ùø˜¹lA‡¢NÎÀ"æ8`h%ëwX—ÓfØX 0Ôb†M]Æq¥•ùkÑ ‚ÙEgþ†{6‚]Aeƒ—à¨FBv$ÆÅ5Âaàx&¨†H•œ1lyñ9Á1¢„(Ì(#Èñfu>*†Éß­$#Aå‡Ý�ü·D‚¨¥p(‡ê@Ø‹(š ”çF�à_©eKåí%æÆœ³Ý0O;l ý`ðB^«ïû555FÌLjQM ÇŒ± Õš¨iÍÕ¢Zåáw9lGûšq"�ûrÀ†7°ûܧA›“UÆ önÈ1šã³J€2<dÿ¤ÿ±êϼ?áû¹¦Ê\d(žÃú3•]#“Ú1rA.µºº:™L¶´´�ncj¼J.1XŸìù±*,Ô¸¡‹¶"~2{Z—óÁ`ó2^ Áè¸2v€Éçå£�v‹çJ뢠½ÎLM#0Øúò2vŽøšÄØ€2”ÎÈ€é/=D…1 ƒ°‹oÝQî~c^Uü=àmÄ|põRȾ¸2iðù†Mz0œ2ì ³‡œ‘pÌ(¡0†”ﹿ¾Gþ—Ü,l"F©�åð}ûöí@-2C«$:h±1µáqÉqý•(¶àˆp±·áNðdòù<"-†À0ÔÁ‹)JJ)Ãâæj;Ø'<͓ŰÝx¤ Ñ¡´$ìÙx&izÉá&+N+‚-¨O¡³‚§bˆ£p‘âK |â‰'4húôé[¶lÁe ŒœGå8âÙ\ö$·ý ®$Î"³ÈÏäDàâ¹8a]NƒÖ¸\Ã$ù•¯ÇPKã >¦1q!v—¿pä¹£®Š-³(¢ý`p†rÖÅqd¶8ÌȳÍ\dž4\ ¼™¿Ä"åt ¬<–,,HÞ Ï&6Z[ðß,ß`@–áà…£S5ˆÙáSqJ Ê�iÏòh-ß&º÷hT€þ’E]+ƒ�éˆY<y[ ÜÀ¦ÈÓ0ø“&3Ê‹½¸")°¬Ê§q©‡V¸ŒÊ2+ׇ©˜3‰ÐÏH;� åJ Þ‘ôä"¹&,Ócx³Ð‰u ÃTk²;D07C`Œ±Ü,¦gàYìÙ��°žAíuuu¯¾úêÁƒÔÃ4Y Üž96 ¬Î «’3¸lun`4¿8ërÚlxâ‰Ã‡W­e͸ at¸²Œ²o>¤8Ìynô<Tëá5Îʹ%S)p€d° cµÙŒr×—›±•°1æ³b;‹¸› HXu†u— ¥NC’€Ï-žë%øTƒÜÚ¨ïñ9¿)tøÑ±G؉a©Ì«Í§šy£53ž¥бàP�j›ø×3áà™,,G¬GÉuöú,Nc` @IÀ¤dÆ6`׈gÓÅ2ë§Øø-f¿OYqŽÖ˜b®<zÆL.÷x©WH)‰Ç“ @ß/)qGÖIFqG[øY)Õ5²ºÊ9 þš&†|-OòšQI4Ì:âF=Ó @t§C‡Öå´Ùêׯß]wÝeŸƒ]vÙe×Ǻ,Çš]vÙe—]Ÿx–£µž1c†}"vÙe—]v}„kèСâr‚ ¸øâ‹ùç 1˜ÿÉÿúhì0¹Œ¿ñcŸä£8.ã#y;GÆùÛ×p8\Æ'ö:>î c­J›çðóÏ?ÿüq9úÆôõßø¯ª ûhñãþ|{aÿ—Ï?l/Lµh8</Ìîa{aGö…µ¢)²IŸ]vÙe—]ŸÌ².Ç.»ì²Ë.ërì²Ë.»ì².Ç.»ì²Ë.»¬Ë±Ë.»ì²Ëº»ì²Ë.»¬Ë±À.»ì²Ë.ërì²Ë.»ì².Ç.»ì²Ë.»¬Ë±Ë.»ì²Ëº»ì²Ë.»¬Ë±Ë.»ì²Ë.ërì²Ë.»ì².Ç.»ì²Ë.»þ×ëÃÅ ?±nÖHWÿ`ʪíÄK”UùDv‚úÖ2ù8ÞÈǪâcßH›¼‘ÿ‹e9|·…�� ®IDATr䇸Ïó¦OŸÞ&~ïÍ7ßÌd2_ýêW 7~ÓM7=òÈ#Gƽ¬X±bÙ²e?üᘠëHz;öàÎkâĉG}ô AƒìÛaáï^tÑEmr3Ùl6N·Õ_ÿÈ×g?ûÙ#æ^jjj´ÖGÌíaoÇœÃymÙ²¥gÏžöí(¥‚ øÀѤR©ùóçg³ÙW^yåšk®QvÙe—]vÙõÑ­ 2™ÌôéÓö³ŸYø€]vÙe—]ŸÐ².Ç.»ì²Ë.ërì²Ë.»ì:²VäûK---+V¬8çœs”R™LfÚ´iJ©¡C‡víÚU)õÎ;ïlذ¡}ûö—\r‰üü /¼ µN¥R}úô9¬Yccãk¯½¦”ºð ;uꤔZºté¦M›:vì(í5­õ /¼ ”:óÌ3{õ꥔ڰaÃ;)D¾ño†›àµ×^kll<餓  ”ª¯¯Ÿ5k–Rê²Ë.«­­UJÍŸ?¿®®®{÷îC† QJù¾?yòd¥Ô AƒŽ=öØÃçFf̘gåE®^½zÍš5ÉdòòË/—ŸùóŸÿ\(N?ýô~ýú)¥¶mÛ¶`Á¥Ô7¾ñH$Ò¶÷²cÇŽ¦¦¦þýûË?W®\¹víÚÚÚÚË.»L¾óÒK/•J¥œtÒIJ©-[¶,Z´H)uÕUW @hÆŒ }úôI¥R‡ÛÛ‘µtéÒÞ½{wìØQ)µxñâÍ›7wêÔé /TJAðâ‹/*¥Î:ë¬N8A)µnݺ+VD£Ñ¯ýëm~/7nŒD"rº•R .ܺuk×®]‡ª”*‹“&MRJsÎ9={öTJ½÷Þ{«V­J$€N™2%—Ëzê©'Ÿ|r›ßN¡Pxûí·åt+¥víÚõ׿þU)uÅWTUU)¥Þzë­Ý»w÷èÑãÜsÏc>uêT¥ÔùçŸß­[7¥ÔòåËׯ_ß®]»K/½ôoÿ-/Ùñ˜žç|{åæ}ÍõÛ¾ðù3>¾»ºõÖ[ßxãaÆ)¥î½÷Þ|>ŸÉdfÏž=hР+VL›6Í÷ý]»víܹó”SNyä‘G2™ÌâÅ‹ûöíÛ®]»ÃÇ®5ªX,f2™7ß|óüóÏ_¼xñôéÓ}ßß¹sçÞ½{û÷ï?vìØ¦¦¦L&³`Á‚þýûïß¿ÿ™gž) étzåÊ•<¬üÍ /¼°nݺ–––5kÖÔÔÔtîÜù¾ûî+•J™LfΜ9C† ™={öܹss¹ÜÖ­[›››ûöí;zôèl6›ÉdæÎ›J¥âñx›ßÅìÙ³ûÛߎ3føðáòã"7mÚ4iÒ¤|>¿oß¾M›6qÆãÇß½{wssó;ï¼Ó£G0 Ç'ováÂ…_üâÛðvîºë®§žz*“ÉÄvåÊ•“'OÎçó{öìÙ¶mÛi§6nܸ}ûöe2™¥K—öêÕË÷ýßÿþ÷rñ‹-:ûì³'Mš´fÍš–––µk×&‰=z´áíL™2å‰'žøýïÿãÿß\´hÑõ×_?hРcŽ9fÁ‚3gÎô}¿®®nÿþýýúõûÍo~“ÉdärÊ){÷îýãÿX(Þ}÷Ý6t¢aÞzë­O>ùdûöíÏ8ã ¥ÔܹsgÏžËå¶oßžN§?ó™Ï<øàƒÍÍÍ™LfÞ¼ygœqF]]ÝŸþô§|>àÀuëÖ 0`„ Û·oonn^¾|y·nݺtéÒ†oçÙgŸ}ê©§¦L™òï|G)ÕÜÜüÐC‰˜;wîàÁƒ§OŸ¾hÑ¢l6ûþûï‹ÅÞ½{ßwß}¾ï‹‰8çœsV¯^=uêTß÷÷ìÙSWWwê©§"ÝRœ¼t÷›3^[¾h®ê~Rêç¯æ‡On=îYý±­#F<ù䓯 “¦R)ùâ¼óÎknn~öÙgÇŽ«µ^½zõµ×^«µ>óÌ3‹Å¢Öú†nX²d‰>œ.~Ù²eaŽ?þ±ÇÓZ/Y²ä†nà¸öÚkW¯^=oÞ¼áÇk­›››Ï;ï<}˜-¹H­õرcŸ}öY¾H¹‘ûï¿âĉZëéÓ§ß~ûí|ƒ—_~ùÎ;‡»Ø¶mÛìÙ³O>ùäÊ×$9eÊ”‘#GÊO~ík_ä÷´Ö·ÝvÛo¼±aÆo}ë[Æï¶Õš?þÝwß=jÔ(ùg}}ý¶mÛ´Ö¸H98ZëáÇϛ7ƒóØc?¾mogãÆ³gÏ0`�çç?ÿùå—_n\äÂ… ò“Ÿð+¸æškÞ{ï½9sæÜrË-Zët:}Á´á½„a8{öìáÇO˜0A¾#Gk}ðàÁM›6ñÅ6lóæÍ88{÷î½ôÒKùàüêW¿š6mZÛ¾5kÖL™2墋.’â"q#¸È?ÿùϲ'qƒ\pA:~î¹çÆŒ£µ~ï½÷®¹æšÊ?±#]>¹ñÊûg¶ëzœ«”ò"±X²ãz“Ý·oߎ;>÷¹ÏµÈ|>?~üøîÞ½û¸;ï¼óŽ;î8pà®]»PÕüÔ­ãŽ;nÈ!R8Ö¿øÅSN9ÿìÒ¥ËqÇWWWwçw>õÔSŸºÛéÓ§Ï!C\÷ƒÎñ¦M›’ÉäÑGý©»Çq† Ò·o_þæ®]»®¸âŠ›nºI ÑŸ®Õ¿)—ÉêØ±ã°aÃ8pàÀ|ð£yh®K¶ëpô‰ÑDõǨ««{ôÑGo¿ýö:æ ¾¾^rš{Gœ>¥käÈ‘£FZ²dÉ1Ç#=*»õ|ùò1cÆ<ù䓉DâÓ~/Ó§OŸ7oÞ=÷Üsļ)S¦Œ7îºë®{à>í÷ÒÐÐðâ‹/.Y²dÉ’%·ÜrËGþù{téÒ¥o¾ùfSSSSSÓŠ+fÍš%¶OïêÙ³çõ×_o ]ŸØZ±bÅÔ©SGŒqd¤qwÞyçYguóÍ7/X° ©©é¹çžû´ßÑ7ÞxÌ1ÇlܸÑîÕ¶w9ƒîܹ³Rj÷îÝ[¶lt]vÙõ?_7nL$‚}:Öã?ÞÔÔ¤”Ú²e˧=�µë½ºŸ”ºu†¾u†óøsk“ª®®îæ›o–¯7lØJ¥R©ÔÛo¿­µ.•J÷Ýw_*•6lX>Ÿ×Zû¾ÿ…/|!•J=ÿüóAVýv̤R©¥K—j­‹ÅâÝwßJ¥®¾úêB¡ µnii‘˜4iRA<ýôÓ©TêÜsÏõ}ÿpƒäóùaÆ¥R)ªi­ß~ûm¹þ 6È Ž1"•JÝxãrƒ»ví’˜9sf†‡Ï½\yå•øÚ¸ÈR©ôÈ#¤R©K/½{lèС©Tê‰'ž‚ ÿüå/ò+ló{™9sæã?._¿þúë§Ÿ~º\›4¢}ß?÷ÜsS©ÔÓO?-{lÒ¤Iò---ZëB¡põÕW§R©»ï¾[8‡ÕÛ‘5räÈwß}WöØ]wÝ•J¥¾ûÝïÊkjj’Û™<yr†AL˜0!•JwÞy‡Ã!zî¹ç^~ùeùºX,Þ~ûí©Tê‡?ü¡\üþýûåâ§M›&ÿøã§R© /¼Pö^>Ÿ¿øâ‹S©Ôï~÷;9tm»Òéô~ô#à#fÍš%×_WW'{é§?ýi*•úùÏ.{éý÷ß—˜;w®®Ñ£G§R©¯ýërƒÆÚÙ¤o¡¯fs§ãú9ÝOJ}çÑ%J©n[ž¿åúoYl—]vÙe×G¸veÔØ…ªqÏ–I¿¸Ì²Øe—]vÙõ -ërì²Ë.»ì².Ç.»ì²Ë®#k}€XËÕôzgsÃ)=jìC±Ë.»ì²ë#Yïîh> ;~ˆËiê|æË‹Võîx¼}FvÙe—]v}$ëåEuùNG©²5Íå8N¶ªÇ˜×¶ýÝHfëjZ6ÛGi—]vÙõ»t³Ž¿ùoÿX®ª‡Wö7J)gÑ¢Å7üzÂ…7ýŸó·? ÃAÇ/ýŒgŸ¸]vÙe×?ìš¾Ùûëv÷ïº ¥¥T¶qß̇o|öÁÛ"ݺuí׳㞠KÛu;>Ù¾‹ü￱Š~Kº~oK.ö‰Ûe—]výîb±J©øßuâoöoy÷Ô>ÇtëÖÍÆé_>0îÝÍ»‡ühôßýå TènëWsÐ>q»ì²Ë®ص£ê´Í¹£J…ÜßýÉ9ão=¥÷Ñ÷Üvcÿþý­µRjÛ¶m{öì½ìÊïýOþ’ä½ gŸ¸]vÙe×?/9þ}6ýiŸîÞ½Ûñǯ”úÿä¦kZ¿ö¾����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/jmagrange.png������������������������������������������������������������0000644�0001750�0001750�00000553726�11332127304�017102� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ! tÁ�� �IDATxÚìw˜UºÿOåÐ9LOwON0C¢¬aÇËUWEtw®EÁQLq”•Õ5"`¸¨wEEWEQÐAÂ09OO÷„ιrøýQØ\\Ö»þnžyæ©®~ëœoóÖy«Î9]RU5 z<žG}Ôçó¤³/â̱‚,Y²dÉòK@j0+qY†hǃÁ Ífƒaø‡Íòóóï¿ÿþ¢¢¢œœ4 ®Zµª½½ýÑG-((€ �ðþÿþ‘¿ß|ýo³µ˜%K–,¿$Y~{Ó»ÿ}÷eÇýpó®ý饗æÍ›Ç0ÌPŒ_{íµ9sæH’¤íÑv»­ýïëë{â‰' n¹åÔãñttt<òÈ#E"è[`>y[”¤/4ÿË}X±³§?$R~®%Í ÑDÚbÔé(Üçâ8Zì¶·õ �FWä×·û��#ÊÜ­=ƒ²¬¹mÑ“H±v‹EáÁ`œ&qW޹Ó8Ö>³QZà ÅVpÚM²¢#IƒŽ´™õ=}!†*KÜM}ÇÚW9{B¼ ååZXNˆÄÓf#­§Iß`Ç’|Gk÷À±öU¥îöÞAIR ]¶x’‰§X›Ycè@0F‘XžÃÚÑë?Ö~TE~c‡OUAI~N ’H3|®Í¨ª Ièi2Ç¢ïî A04¢ÔÝØq‚°\ï`„ãE·ÃÌ R8–2h£žôD0)+p´/¬²ÄÕé ˆ’\à²&R\<ÉØÌzGû1’À œÖvÏqÂF–ç5uõ«ŠZ’gFS)†sXüᄎ&Vc·/A`dy~Ãñ%\^˜Ûˆ°œèÊ1 ¢Ž¥LzÊd {Â( W:›»úµ^âêöQÎwZS K0V“Ž"ñ>”ÀÑB—½ÝsBÕçµt÷+ŠZœgÇRÉ4—c5 0<ŠÓî´›»þAÕ—8‚1†œ9&IRBѤQOYŒ´§?Œ ððbgSçq²>™õÉŸÁ'}þ�€eÙp8|lcþ½-<AŠ¢‚ …~À&³­(Š,ËšñØ[,–gžyfáÂ… …B=ô†a?š:Aï~ÙÓNý‚þØtÊe!Ó©¤¯oÆT®vtû$)ÍÕ7´õ$ñ±%öÃÍ]ñXld‘µ¥ÓG rèH8Ú?à7S0ªŠ]½}@ò,ds{o2ó­ýØ2û‘–îh$Zâ4ôûƒþ Ý€Éëñ`@²éÑÖ.o:•Yh©kîN$âãJíuÍ]±hlXž©Ç;†œf‚M'½}ƒ¦p¨½Ç'rL¹ËÐÐÚ“HÄÇ–Úëš:c±Øˆ"K[—7ŠäÛéh4Ú×0‘Iž~UâòmtS‡'™ˆ-±×5uÅc±1¥ö†ÖžH$Zœ«ôƒ6=ªŠ\w�UÅ#ÞÒÙ›J&G[ëZºâñøøRû᦮X4Vá6zúP®™`™T¯oD µu{6]á6jÂÆiö±XU¡¥½Ç …ólT<÷õû  ¹³§OÙº©Ý“HÄÇ”Úêš»â±Øè[c[O$-rèÁðÀ`ÀJ£@º{ûUÌ5á-½ÉdbL±fW–s¸©3•¹Þ~¿?r˜pžM{|"[h¤½ËÇ2©áù¦ú£%–s¸¹+U˜;{ú‚¡°ÛJ&qo¿_U:zúd-vèÛ<ZÕkÂF[›;zÃáHaŽ. ÷,4+B—§V—™lîð$“‰1%öºæÎx,>®\Ë(Zê2ô øýþPŽy¦Ç7ˆC²FÚº¼L:U•o>Òr´ê5aÃóM]½ýÁ`8ë“YŸüy|Òãyö?Ï,gYöGy†92a„t:­íT� € �A0 gìÇŒò¬v¬ªjßC™c!F`XûvÒ¤I÷ß?êõz "‘€ ¶¾˜Õ@:­úLö‘tŠ+ mZ��À��#…[ô8AIVˆ¦�·•VTŒs‚$#0d¢q#+ªMñ)VBÈe¥Ã >Í‹§ñÙ…Ä»‘ %8N”3;-zÂLã¬(‡œ(+v­�¨Ýv˜un‡ù@k¿‘ÆG—9¿¬ï¥ ìŒEû}@UG”¹Úû"Ñ$Wšggx¹{ ê¶ÍFý‘ÎAMŒ(ÍÝÛЫ#±)£Š?¯ëÁdtE^}W ÅŠå…ŽH’óâ…3I=‹ž,/ÈùªÉ«§ðÉ•Ÿî¡ptÜð‚m¼ /Îí §#©b§ÀH‹7”cÒå;,ß´ö(|L¹ó‹#½4M¬*üªÉ§(êˆRWg,’`Kò율tõG]VƒÍl8Ü1`¢‰‘ß ›<²xwE ÑîÆž`2-”äÄÒB¯?^c¦i²¡;`ÖÊû½zŸ2º`סnGÇ Ë?Ø6È Ò°¢Ü(3N9­0‚´ô†ìFºÐiÝß’æ¡ tbeá×M}²¢T•:»c¡Sâ¶ ²ÚÙqZô«ñPû€‘ÆG•:÷6ôêlòÈ¢/xŒ*w7{Bñ´PV“`EÏ`,?Ǥ×S ]~“Ž~T6õ[ac‡åndy©¢Èˆ2ý¡dQ®ŰfOÐf ‹Ý¶ÚfŸÂ'”;w×y(PY°¿¹O’•ʧǟƘ·MR¡_8×¢wÚMÛú5a{zi›4¢hOƒ†ÀÈrw«7Kñeùö'õ Æòì&£®ïô›tDe‰c_ƒWObgŽ*øìp"c†åÕuøÓœXQèʾ`²0ׂãx“'h5¥ùö¯›4a®Ïëz(?¼à›ÖA’‡—8½Ád š.vY³>™õÉŸÇ'4É$��àGŸo2|fûPgðþW÷žÐêÞqùÄ+¦ ýÁÔk>[’s׬3lFê³:ï#o|uÍyU7V¦ILÑñz½ˆÛí¾á†8ŽÛ]ß÷àkû:â#Šìf= Ãp×@ü± _¯ÿ¤±Ôe)vš!ÚüE+i°’8öŸ“ '—ê ˼7Äèõú¥W›Pf«oïópÃxåÔâ T™K8­ž@’¦È;/ÑåñöGy%T�Ÿ–¿b§qιE íž8¨0ªØ@×L+-·Ã# ͱLÉ)^%8§E—cÑìZ TQ®é`gÀ±—©½?ƉJ™ÛJðƒ1¶Äi’U¨s á¶éÍúHwÈf¤ sMûÛ:/qš›¼U…JÝæ(Jðån3+*=d¾Ý £ˆFO$ÇDç;Lµm~“Ž,Î5é #Rê2õSqF,w[¬è ¥  ÃZ|Q§E—kÕèXôd‘Ó|¨3H`X‰ËÔ9`¹Üm§ø([ì4ª�êè»­z«‘>ÜuTØ7íšÄKœæoDVA™Û<eƒ ®Ümæ%µÛŸÌ· :¢¡'’c¢ ¦ÚV¿‘&Šœ¦†ž0Œ ¥.“7˜Š2B¹Û’â$o(Uè08ÖìæZtN›á@{À¬'‹œæº®†¡%Ns×`"ÍËens4%ôGا‚öþ¸Ëª·™èÃ]!«*Ì5ìPVì2µúb¢¢–¹Íˆse.“(«]ƒÉ<»Þ¨#ë{Âv]è0íoóh¢Èinð„!)u™úÂéHJ(ϳ¤y¹7˜*ÈÑ“ÞÔÍ5ë\vÃ7í³Ž,ršêºB†”¸Ì=þDŠ“ËÜæXZì‹0ÅN##m}1—Ug7ëu5a‡:‚$•¸Lí}1ARËÜæ`œõǸR—IT ®ÁDžMoÒSGºÃv#]˜kü¦Í¯§‰b§¹ÉQ!¨Ôeî 3á$_‘gN ²'ÊÏÑS$ÑÔq˜iwŽq[À¤#‹rMGºC‚”ºÌ=d‚•ÊóÌñ´ØfŠr ‚¶öŲ>™õÉŸÁ'óìÆAð’3˵±œ}Щ««›8q¢6–³ä¥/XA:!äÔ¶ Ì:·Š"0‚ÆŒ£¥üè[ûÂéþp*câiáÉw¾QUÐØš6º תWU†áuëÖ¡™ÑžM_´�Žt‡žÚ|àÙSIùë¦ý-½a�ÀÆÝ-ç+‚ �HQaš$JÆÖ–ÆÏuERBJ!Ç /DÄðŒD ûÄò˜¾ôÖV³³äŽ«Ïmj“»bœ"KrÒÎð³Ýa¦ñþ(‹£°‰Æ¶ì/´Óg”Û �vEë=±Æñ¥Ö`œ7Pèžæ`®…WlޥŽ­Á@ŒÓÔŽ.2-6ó¢"qi(¬7Ñí°xC 'Ê¥¹ºÿúÖ5—]TeW›<i3º¬¤Æ<1Mäšé_BQáÒ\ƒ'ÈÄRÒ˜b³?&øcì0·‘“ÔÞ@*ß®£¬Á3ëI»‘lì£ZäÐwùÓ FWbê‹ðÁ8_•oJ°r_˜)rèqmðÄrL”Å@Ô{bçÙtí)†WÇ›¼a6œFšÃ)i ”: �ÀÍÞ¸ÓBh¼¾'¦§§…néKH*<Üeè ²Ñ”8¦ÈäOˆþ(;Ìmä%à $óm:šÄê=1³Ž´ɦÞŒ E}w ÿNW•oJrŠ/”.ÊÑZï‰å(‹hðÄ(Ï·ë:Ri^Wbî qá„0²ÐMIý¦4WÁHSoÜi¡Œ4Ñà‰é)Üeѵõ%D Ï3xBl4)Ž.2â`”­pDêHäÙh‰7xb&á0S;!ʆž�OKc‹M1>ã*óŒi^õ†Ò…9:Ç<q›´ÈOŒÀ°|»¾s0•d•ñ¥foˆ %ø‘¦(#õ‡™’\=#½ñ\3eÔõž˜ŽÄ]6][_Š—Àè"coˆ#¬Üe¨c á¶Ò:¯÷Ä4á0Ó;„ Á%¹O€‰&bÜð<#+¨½ÁT]GX½'fÕ“6#ÙØÇ0¬0Gß5˜N°òø“7‡âüˆSŒ‘ûÃL±C¡H£'æ0QfÑУIÜmÓµ¤XŒ9*LUhÒª¾ÌiP�ÔâK¸¬tÖ'³>ù3ød½'–iä‡2zrÜø?ôýÝKð÷_sîðoD””Ýõ¾ÝõG'?_tFI^ŽáØÄÑÌ÷ýnÊ-Ïì”e¥¾;´ø…ÏEí§��:»öÙ™d€„SÒ‘žð9c«Æ¬üª=´ãp`R¹£¥«·¯ß?±ª¸yŸ?×L{ÚÛü,&;¯ ”’X�€chU¡•F…þP¨zLž#]c K£ÑølwKiyé™S¾‹ÇWyºÚ•xlìä1~_rú¤Òw?úrxíìbÝûu ¯bn3uñ„¼öÖfIà {é°÷™Ãs^Ûð^2ŏІ©²CG:£W9.6è(É1QXÛ�ƒÀpY.]ïeI\f¬÷2Œ +2zB|4%–çêÒ¼â‹ðIáhû CbhjìcD L)3ÔyVÏ(1µù¹# wé£i¹?ÊçY)†Û皈æ~VVÀ¸"ýáÞ4/*“JM}Lš—Gæãb .ÙiYžcÖÖ:ÀÀ\áÔñ¦I\j¬÷1Œ -4öF„HR,sèAõ†¹Ihû ƒch¡jècDIÍ›XbêðsqFæÒǹ/Ê»-ŠÀ탌žÄf¢¹Ÿe0å;aæÆ>&ÍÉ#ò „ä …6ZQ¡?cÒVÑ:È�®péë½i^T'—šêû†—Ç}!œK:N½aÖn$õÖ>È`(Z”C7úŽ+á ŦΠOKÜú«ø¢¼ËLa(Ò>ÀÐæ²Í}¬(ƒ)e†º^†•Ée¦¦>&ÅÉUy†`RŒ 6Zp‡Ÿ5é›h`TîÖñ¦yQ™\jjècÒ¼<ºÀÐB ±$‡æ%ÐbmÒ@aíƒ #%ºáxaã‹ÝA>–+œº$§ø"¼ÓLÒ>ÈPšg¥šú¿­ú^†åI¥¦–.ÉJ•n}8%Dù|+Apû k¤ñ#Ñ2À( 4Ö­¯óWõ£ q1ŠshQžk5YŸÌúäÏã“¢ àoùï儨“‰0 ›uÄc7s‚ýk¿7>M©tý×µS|uO&2M¿ðÊIf=y¬ñÑùÔ0 :Œ/.œî²ê��¾`R‹7ù9ÆÿYzYžÝ  È�–òiSléšvןO–™ør'Õ?æDuüè*˜ñ‡“‚ÝjÎuZÍ&…¢Ñ¨$JßNûÖ}ÕЋ„?Úõe<ž°âÂH':çÒ_{ÖB5*3|þÅ—mTUd»³èñg*ÎwBl˜ vÉ�ÖQ¸EïøøÓÆ���ôô…Z{C×Íü9¿»*À‘:à ®»¼Ò­ „"ËRÊ‘>Cá‘yÔW]Œ  1ô7= 'aN²;$„Ór¡`%µ;,Úô˜Y‡6ös† s’û{‚ÆÑûºAU.ªyOpjqcåÞ¨˜kÆInä))É!ö² /Ò}Ù‘–hDUçc”9HBˆKn AP{@0P¨Û‚×ù8 …GåSûºÒ €FÐ< 'Š\ÒB)¹ÀFð²Ú¬z̪Cú9C†»ÈÚ@иBú«.FA¥‹jõó1N-Î!œâ‰ˆ#Fpó OâH©ƒ8ÐËB04¡ø;aG|lZ�¥2˜’úc’Û‚#Ôô$šoÁûXGÐû:Ó² ʧö²¬*rIoD¦ä|.*jgH°è0»­ïçp©t“µÝŒ  ±…tm7ÃK`¸‹lð1V)²I^鉈¦§æžÄ‘²\â€GFïéL‹ á¦êû¸”�JD(%õÅ$—ǨÍÏë¤À†ö²-¤÷Fò²ŒÊsɾ˜HÊùV\VAgP0ë0‡­ïã0®Ê#¿î>Zõû»NÃdgPˆ2r¡H jOXÌ1`F mà )Ï%¿ñ0/¢÷v2‚ªÜTc?—äÕ’"ÂÈÞ¨è4ã8·úyš@ŠìÄ!/‹Àð¸"ݞδ¤B#ó¨:M˜ƒˆIƒ )ÏŠ«�ê &ušð¬Of}òçñÉ EºL#A+Èͽ‘æÞH“'¬ý5ô„DYÉL 8ÖAà2·%óWžg-ϳÒÁбö™mATŽ}’eUVÔо{Ê ¨Äe^úÛ3Ÿ|g¿ÇŸ��TäYïùÝT—MŸ ƒ�@2€MöëQvÃ$—™Bº}žB3« E zEat‘uOSÿÌI¹WŸg¢ ¦ÖŽ®ºvŸ®È�¤��P58T ” ÆAfÊëëD“çL¬ Å™ö¾Èo.>%ª Ú}Á|o°¹¡>ʼnÞÃH�ð`BìL^Z}.b-@" ÜáRÑ@ISNôõGíBbÐb6íÞ_/b6 À ä™^Àà| Ü*³ÁÁ”H«%DTAODv`…ém4ì2"û½…Ãù¤¡_T`ûâr„UËm0+‚Þ˜’g„I n”rt°Óˆ~팜oFù … ,pODN  ÂÇ9¥/¡š`ZƒR®¶ëÑ^ÁLÂyæ£Â ,p[@ä¨Ü …ÒŠ?¥–XYÝÙe€M4R×/Z)ØmB¾é(.0#ƒ¢AŸ?!‡µÌ³èÊyF˜Æ‘ÆAÉNÃ.#Zë œoFû… ,°'"'xPa‡“¼ê‹+&E –€äÐÁ9ôM˜ 9èp .°À!‘•@™ 3Ê`J-¶ *€:C²Ó�›iäpßwÂHÎ7ÃMƒ¢¬BE6x0¡„µÌŠð2ðDe·¦I¤a@´k%Ü+è4a}"ø7&Ç8Pa‡“ðÅ•|Œ¡Ps@rè`‡Ýß+˜H8ß„ô 8 XàΔA¹ Ž2Ê@R)2#�‚ÚC²S[uÈ¡>ÑBÁZÕ“œo[¢¨Be6ØŸR‚iµÔŠˆ è‰Èn¬'‘úo«þ[aGúE† -°/&G9PaƒÓ"ðÆ”|#L`p³_ÊÑÁ¹´6#ìÛªïŠÈ)M«ô'•"3 AP[PÊÕÃ6zÐ'd„e}2ë“ÿjŸÌ<å(*xeGû{ÚOè(›wÙ„ë«ÇûcšLƒ2��‚O~Êù²¡ï±·¾>6Ù}M}O¿S»xÖ™v³.cŒ{ AcËw_sæCÿó%‰¡÷ünêˆ"û Ý| €ã¬ZÛЧ:Ät¤»/l-ÝÔõþá†køðvÖßÖ>³)^´Jý|Üß5¨9*dzyGcC}›_0 ¶w‚\zý§M}þð†}}]µ‡(ï6À©¨¿±­»µgn ÚàX¾5ÅÒùížÁ^¡× ‰|"ÜfU¢Hp(-oª´ ‘DmÃ.Œqň¾?îÙµg¿/…óXŸ¿e ï©DA‘ž€rt =¬J*\nQ¼ ç ‘9j€‚iµÜ8ò%T·"1¨%¨˜HÈJ¶ CpIñÄÔ¤�v¨ý)fÀ0+H Ð@R-0 [‚Š‚L$h($»jWTM‹Ð‡êM‚( ªì ÂÁþ”Zl�‚ÛBªCéqÐPt8”«aUTá ‹Ò« ³«¦Õ2 ÈW]zˆÂ æ€b$!›´…T�Á&¥7®&xhTŽ:†ÂŒ:Ì RÔŸTó¿f¥ 3šƒ ŽÁn£ÒUS"4Æ¡ú’ ‚Jˆr°?¥™�í!ÕAC´ZQ‘£z ÆA#ìj…ƒiµÔ DòFU—¢1¨%¨Èþ­°"“Òš°Á4bÔ +`$¨/¡æ …Z‚Š…‚,h ©ç•ž˜šŽãàÁ”Zh ·Õ2 9¨P8ìÔ«]Q•“¡‘9ª7 b,4®†X8VKÌ@V¡î°êÔA45•LÕ+*\dVz ÁA#sT?…Òj¹°Ô—Pó AÍAÅLBV ´†TóßU}_ D0Üâ<˜T �Eà– b§!“& ƒ]zµ+ª²4*Gõ}[õa¤Ô3P�ÜVsu-ÇËúdÖ'ÿÕ>ÉH°þÛF^’”“ã �àOo¸xÜñAåĘsL �ßc Aïîie�pÑÄ’I•î•oí“dåÓCžÙŽÎ±è¿g,'“âè’œUw\„ °Ûf8¹›OVYm!Uæªl9Ó¢N‘ÌpYÓGª¬?ƨž8Ö)8TÉ åÀ$N3 ^Û/(޳ÚR”b? Fèú¤¬:͇TÉ~6¬Rý1IUŒ‡@…¥…y¹¿*)$éÃ/¿ñ’$z‡*[€Bp¬"@ž¨ÒÍ[Y 2ÁÑ®¥€°‘84�Ë\  �f¤�N&¨#¢Š ïà›#'6Á›Àb<\lÓ"ÔŸBì”D"jW%Å­—Z"¸¤€ ¾1Lð2c绢DR„ÊMBŒGÓˆ“–`tÅ&çÐJ{“0ÊÎׇAã|K„`$0Ü"ÒHó ¢¤@¾$b"d3®tD1¥&¾1BˆòqÂ|I,ÊÁEF‘¡þb#%U;£«ùz©%‚‹Çmç{âDB€ÊLBœGÒˆ“–PtÅS´ÔÅ%L°ó !BÁ8ß! ³ˆ! 0pžATTÈEŒ¸l&•Ž�(3óMá£'¢ «² ý),ÂÂ…F‘“ ¾b%eU:£«…F©9|œ°Qv¡'Ž%¸Ô$$xd äÒ«]Q”D'-µjÂrùÆÁË`\ß%Ò"¨0‹añ§a·^*èŽ"\¶’J{SU0ÒÆ7#Œ•@•UHaa.4Š‚ ù’ˆ…”õ¸ÒÅH-úVXæDFÚ„Þçá£à4’CIø·UïÒK­ÇWýؾ#J¤DPn#,âOÃ.½�èŠ"z\¶“J[S0ÊÆ7„«úJ‹àOc!.0ˆ¢ y“ˆ™¸ÒÅ`…¦ã…e}2ë“ÿ"Ÿ›Ãv¦Î ø¾ßOýëÆÚBΊ?üúØF>3×àΙgÜúôŽ£;�Ðf\;}Œ‘&NŽ:÷þnê-O}8¾Â¹pæ$³ž4é‰×}>ç¢1ù¶ã‰Î8ãŒÝ»w§R©¡LÙ¾ò¿6ÜÑ?ÃËÒ_ ±>”¶PùãQCÎ?™…(&¶5N«*(6p!‹ h¾ŽSìMá9¤`#å–eÀ¤2#8¬£y˜™kˆèH)1r ‘‘B=ÇÉÈ�ƒ¹(^‡«qÒˆI%F¾.¬Ó¡òp3{0¤'¥ÌÈõ$I^†Š \RDƒ,–G󺓄óôbC„Ö£r…™;ÒQˆRnbÛã´¬‚bá±(æÓ€àÞžC vRn>^X…™kŒÒ0PK¿V ãîOãNJ0àJûIÂ…ô8¢”¹ÞÉIP‘žKIh€ÅÜ4O  +A˜q±@/Ö#ŒD”rÛ§$*ÖsQ‹phžŽƒ!È“"섘CKÍQÊ€Je&þpXG!ò03×¥!�J ¬Ÿ#’R ãDîKã¹”`•¶ã… 3sua)¥FΗ&X .ÔsŒŒ2˜›æ)TíLfL*4G"´•‡™¹ƒš0#ו$E*Òs1 sh¾Ž‡aàI6BÌ¥¥¦(e@¥r3¯•p…‰m¬‰P�� �IDAT‰Ñ�€à°¸€è8Y…}iÜA RnQFL*ÕJ•‡™¸úˆ…”R#×—&Ò\¨çµªwÓ<ª Ò„IEFáH˜>¡ê»“¤ CÅ..b!ÍÓñ( z’„]:±1z\Õg}2ë“?ƒOv%p2ÑùââÿüáF>³ñ /Üzë­ñx|(áÕW_={¶6£úGíQ2e ¾ÿÑéû·µk?ÃYv®qâïéªÿ€ Î2)Q]4Û™¤xÉ£™0yÂE±² õ¤(;Á0¹1¦7b’“âG $¢¸h®%N+�rÓì KD<bXö1¤ƒäDië̸˜Kñ‡ÂFU\×Õ£0pS¬7M$%,Ÿf’":À’¹ÃjG’¶â‚ë"=&;)îHD#ª‹b»’« yá±�G¸HVP÷QaR÷Âê"Q]4×§eΣY?‹GÜM1¼{Ó”ƒäIDnùN˜B'Å5Dõ0 ò(Ö—&â"–O3I ígÉ\’C`µ=A[p!‡G :TvR\}DÁÀM±=IŠQÐ<Љ ¨Ÿ#œ«¨+EÛÁ„‹ Q½“œ4_Ոꦹ¶8-©pÍ8<ÌÖ›¦ržFåæ¸Î„‹¹8rTXSLA›fû"&ây4“–>†Ì%9 VÛ: .æPü¡Œ°¨NæI‘i Í£˜¸€ú9ÂE±�€®$m#3.ÖGõLÊ¥ùºˆ&ŒíHÒ‚ çÑLÃB<á¦Q<i*‡àu˜ÜÓ›0IF¢Š‹âZâ´ Anš`‰¨ˆçÑ,+Á>†Ì%9V[ß•0Ê.Š«ÿ¶ê{ÓdJBói&.¢ƒ,á¤X¨IÚJVR<=¾ê³>™õÉŸÅ'“vìèÉ?jä¿wÚr‚ñþÈô»kCœB  �ø—õ'©È�«‹‰D) ä G’qAAzÒzΰܞ2PÁ‚q)<2écuI /¥£Až òd Kɘ—Ñ9‰ ©í)£ ã¨Ðž2â°â$RFŸ–±*6ÈÓa,¥£Q‘ìcé<2 �èL¬§CÅö¤‘B$;Æô0zAE Éø�GÇD¢ŒŠFDMXBP‘ž´>ç¨0£5a*�ydÂÇê^FGƒ<à©b*ÆÈX/£siR:RFÊQ¾#eÄ`ÕE¤¼Œ>-c¥TÌÏÓa,££1‰èci7‘„ Й2X0NŠmI#…Èœéaô¼ŠS±žŽ~+l€£ È„¤ÂÝi½g)XjOu¨hÃØ®´AQá|2ÑÇê^JÇB‚&,® Ë%Ò8¬´'FT0¡|Gʈ@ª‹HyY]JÂJ©h€§BYJGãácun"CjÇQaB{ÊH"²ƒH{=+cÅTl§#"¡•p?Gç“ Y…»ÒzÎRˆÔž2êɆ±Ýiƒ¬Âd¢ÕÅE¼ŒŽ…ÊÏSETœSP£wà +)ƒÌ×™2ÀÈ#RG«ž:Zõ¥T,)á^Vç"R¤¶§ fŒ7 B[ÊHÀr.‘ö0zæÛªD‹Šd?Kç“IE…»ÒÆÒˆÔž4ÒG«Þ ªH!™ÈúdÖ'&Ÿ¤¢?oþÑïr†h ��TXX¸xñbEQ��’$avB¯TF� /”TòúFU Y�°Ä«ˆªB8,Ë*$«0 )¤Š A*ɼ‚o/r �„Ã’¬Â² £  ª ©ØIö™ –DQTƒeU…$F AA! °Ä)Ø C TAA H% ™;I¯ êqÂŽžÈP…A² €¤"a�¨äIÂXTD=ñD†"ìÄ>Ua0¤ G… ½„UAA  ðÉÂ$^A~‚0–$VþÙªÏûñªÏúdÖ'OO¢(+¹ªª'7é'ï‰Åbf³Y‹ßkìÇx<n43)¯±(Š8Ž«ª*Ëò“O>‰:ŽÛn»a†wîÜyÑEe_÷%K–,YN }ôÑe—]–J¥vìØ!IšùB§Ó]yå•ÙÊ’%K–,§‹+¯¼²±±1//ï¸ß倣?ÒT8ŽË–Q–,Y²d9-<x°»»ûûCŽªª‚ dË(K–,Y²œ<ϱƒ=p¶D²dÉ’%ËÏC6ädÉ’%K–lÈÉ’%K–,Ù“%K–,Y²dCN–,Y²dù÷Š‘Ïç{ûí·OØ9{öìõë×O™2åì³ÏþiyþùçÈ|üíoëv»µí7ß|S–åqãÆ}ôÑG³gÏ�¬_¿þ¢‹.5jÔPRîííÝ´iÓ%—\2lØ0�@mmí—_~ �())¹âŠ+N{!îܹóÈ‘#™sæÌÉÉÉùÙª0™LúýþÌG»Ýn6›;;;õz}nnîOHðäêΔ俔†††>úHÛ3fÌ…^ø£‡lÛ¶­»»{þüùÿL¾_|ñÅþýû�•••3fÌ8áÛgŸ}vøðáÕÕÕÿü îß¿ÿ‹/¾È|¼ì²ËÊËËô¨5kÖ\rÉ%§¥wìØÑÚÚº`Á‚C‡íÚµë†n`æí·ßž1cFee¥vá��(Šš7o�àý÷ßoo?úºûßüæ7eee§”ÝsÏ=WQQqñÅÅøõ×_Gäw¿ûÝKò¦›n2™LÙFü´ÓÝÝýî»ïjÕÝÙÙùÞ{ï]qÅ%%%ÇÚ´µµ}ðÁW]uUaaáéÊñx<555áp¸â$Iª©©ùôÓOò‰}üñÇ555………Z‚$ùÝ«tÖ­[÷â‹/ÆŠŠ ‚ jjj<8Ä”{zzjjjššš´_~ùeMMÕjÍ„´Ó˶mÛjjj2%CÄÏéÉd²¥¥EUU½^Ïóü‘#GR©”N§;¶<O Š¢2ç"Šâ±%ù¯ÃãñÜ~ûí^¯·¢¢EÑ»îºëóÏ?ÿÑ£6oÞü—¿üåŸÉ·¶¶vÑ¢E¢(Æ»ï¾{ûöí'¬X±bË–-§å÷îÝ[SSc6›+**ZZZæÍ›‡ô¨ÒÒR—ËuºÊyË–-+V¬��|ýõ×555¡PH»ºY–½í¶Û<XQQñüóÏ?þøã[¶l¹çž{¬VkEEEccãÿøÇX,6ô¼V¬X±|ùò%K–dî$~˜_|qݺuC±´X,'¿+Ëi¡£££¦¦¦­­M -555'Ø455ÕÔÔôôôüKžr4&L˜p饗jñàé§Ÿ^¿~}¦É»òÊ+%IbYö¾ûî»ä’K2‹. …3fÐ4­móÍ7óæÍ[¸p¡$IÚLJzèÍ7ß¼í¶Û��O<ñÄYg5”Ã)S¦üéOºë®»&Mšäñxž}öÙ§žzêoû[eeåèÑ£-ZÔÜÜ,IÒÌ™3o¿ýö‹.ºhüøñO=õÔm·Ýæñx¶oßþÔSO½òÊ+{÷îÕëõC?­p��³fÍ‚axúôéÏ>ûìÚµko¿ýv“É”J¥^|ñEY–·oß.Â_|QTTtÎ9ç¼þúë²,ðÁ†-^¼¸±±Q–åË/¿|Á‚8Ž=w«Õj³Ù$Iêî¹977wppÐçóM˜0áÈ‘#ÅÅÅ………'¿^édl6›v.>ŸoéÒ¥·ß~ûÔ©S/¾øbžçY–½çž{.½ôÒ;v<üðÃ4MÃ0üî»ïþío+..~饗‚ÁàÕW_ÝÝÝ}èС1cÆüå/¡(j(ú†éììœ9sæÔ©SKJJž{î9¿ß‡§OŸ®•Þš5kÆŽ»nݺ×^{ ˆüüüµk×jÇŠ¢øÂ /¼ù曆•––®Zµ*ãQ?L__ßïÿûë®»îÎ;ïD¤ººð9sæø|>žç¯¿þú¹sçj–étzîܹ@€çù›o¾yΜ9Úå ËòŽ;:4ôšºà‚ ŠŠŠÚÛÛ7nÜÈ0ÌW_}ulI¢(ºpáÂH$ríµ×.[¶líÚµ<òÈ”)S*++ÿøÇ?z<AæÌ™ó‡?üaÚ´iÓ¦Ms¹\o¼ñƇ~èp8†’»^¯Gää› ‚ fΜ©(ÊóÏ?o2™Î8ã E7mÚ‡'NœXTTäñxvïÞ=ôßí¥ÓéÏ?ÿ|ïÞ½Ÿ|òI}}ýùçŸ?uêÔóÏ?ßn·oذáã?Öét555»wï�œsÎ9>ø và[o½µbÅŠwÞy§¢¢býúõ+W®üûßÿÞÝÝ}ï½÷êt:A¶mÛ¶{÷î§Ÿ~zܸq»wï^¶lMÓªªnÙ²Åh4fÆ¿ˆ–––k¯½Ö`0$‰Í›7göŸuÖY“'O.,,|ýõ×·nÝú£·G§êëëwîÜyðàÁd2éõzeYÖökW®]»®¼òÊ믿>œÒ™|úé§;wîܹsg,»ä’K&OžÌó|ww7� •Jy½^QµÆå®»îJ¼�a2™Âá°$IÇÅãq»Ý‚ÁàªU«6lذaÆx ¦¦æóÏ?ÏÏÏojjêîîƒ~¿¿®®.''ç”§Ö½¶sçξ¾>¿ßÿÑGi2O=õÔþçîÚµkâĉ—\r ÏóO>ùä¸qã¶lÙ²e˯׻k×®D"qã7®Y³æÍ7ß\¿~ý²eË}ôÑO>ùä”rÅb@ ™Lêõz ÃX–EQE–eûúúJJJêëë‰Ä)us͘1ãšk®©©©Yºti[[Û®]»®¾úê¹sç644\{íµ—_~ù®]»úûûo»í¶D"qíµ×¾ôÒK÷Þ{ïC=tÙe—ýÏÿüÏ믿þâ‹/1»ªªªW_}u÷îÝ'N|ÿý÷¯¾úê+®¸Âf³íÚµëÆo|òÉ';;;wîÜùØcmݺõƒ>øóŸÿ¬»oß¾|pÉ’%ï¾ûî»ï¾û׿þuˆ™J’‡M&A(ЬZµêƒ>غuëÂ… —.]šy°~衇>úè£;wÞvÛm‹-jhhðz½«W¯Þ½{÷ðáÃO©¦öìÙ³sçÎŽŽŽ1cƤR©Jò™gžÙ´iÓ#<òôÓO{½^ŽãúúúÂá°ö̱eË–Å‹ßwß}µµµ>Ÿoûöí#FŒp8Cï.^¹reEEÅ7ß|£}”eùÀsçνä’K€vá��\.WNNμyó–,YòÀ\qÅ•••{÷îb`�üùÏ®­­ÍÏÏ·Z­<òÈÁƒ}>ß¶mÛÆŽk³Ù®¸âŠ={ö´µµ½úê«Ï=÷ÜêÕ«3}¹f³Y–å={öÄb±FI’®ºêªÊÊÊ7ß|sâĉÏ<óŒÖ…Ãáßýîw£FÚ°aCUUÕóÏ?Ÿ §‘ººº;wÖÕÕeú«ªªvíÚU\\ü›ßüæØû¶;vTTT¸ÝîË/¿üôt¬itvvÖÖÖ677ï-êã?¾gÏžŸpbß|óMmmmmmm*•ÒöÜtÓMÿdyMž<9Óœyæ™'$¸fÍšwß}WÛ~ì±Çjkk3÷íÛ÷Þ{ïi·N§ÚES[[ µ+öñÇ߸qã[o½e4üñÆÆÆ¡$ò /¼óÎ;?­{-¦Óiš¦Qô¸‡×‘#Gþ„Ÿ~úéx<þ_ÿõ_?›‹_pÁ7n\¶lÙ¬Y³æÏŸìðØÿøÇ7Þx£²²réÒ¥_ýõÓO?}òáï¿ÿþªU«~ÎkrìØ±«W¯~ë­·Né¨Ã‡oذáÍ7ß\²d‰Ýn×:ÜüñŒÿ�ìvû’%K~4©sÎ9çäÁ§EÅx@Ûæy~Ù²e?`|×]w½ñÆ%%%³fͺÿþû9D/Ú¶m[æãyç—×¹à‚ n¹å–Í›7ÿío;ö‹/¾ø¼óÎ[ºtikkë+¯¼rÇw”””,Y²$™LÞ{ï½åååŸ$IrÉ’%Á`ð¾ûî=zô½÷Þ›§‘¶¶¶ÚÚZ­{M£½½ýñÇ?¹3íì³ÏÎôñœÎ޵Ë/¿|æÌ™�€gžy愯9räÈ‘#o½õV³Ù|J'v÷ÝwŸjã>¦NZUUuçw2 3mÚ´nE‡ 6eÊ”Ë/¿|ܸq<ÏŸ–ï»ï¾Ìv^^ž6à|ï½÷~þùçË–-Ó:~”aÆM:õ²Ë.›0aÂ)å^PP`³Ù|>ßáÇY–ý'ÏeÛ¶mûöí«©©ùÙüÛãñÜwß}sçÎ;w.Ã0>øàáÇO¾,Xpî¹çNš4éäòóó'Nœ¸~ýúSâþÉL˜0aܸq§zÔüùóu: ÃO=õ”vcž““3räÈ^xÁáp|üñÇÿjÙ555øÃ‚ÁàúõëW¯^]UU¥ÍÐ9™÷Þ{ïí·ß~öÙgÿüç?C´qãÆ‡~x(½ÍûöíÛ¶mÛ<PUU5nÜ8A–/_.Šâ±6»víºë®»n¾ùæÆ¥�·Þzëž={–/_~ñÅO›6 ðûî»O›'RSS£ Ujý÷Ýw_ggç¼yóÞÿýt:=”8eˆÌš5ë?þã?¶oßž¹7#Gެ©©¡iú”Fõ~âSÎ?Âl61qâÄÆÆÆGy$NŸÒá@Àï÷ûý~Q­V+Çq=öØ ÏR(Š †d2ù‡?üaè)?ù䓆Ýyç™:Ž ˆ1cÆð<ÿÐCuuu¹\®gžyæé§Ÿ¾á†Ö­[·hÑ¢E‹M™2å´T[ss³^¯Ÿ8qbII ‚ ÑhôYjÂF-IÒC=ÔÙÙyª·®<ÏK’„¢è©v žÀþýûçÍ›7wîÜ /¼P«‚ `öûý©TÊd2¡(j6›Óé´6Sî´ÌbæË/¿lllôûýUUUEQeµZEQôûý‹/¾à‚ ´ŽÖ’’’ &X,†a´·Ðâ8®×ëKKK‡ vÿý÷k³‡B~~þêÕ«×®]ûá‡<xpâĉ۷oÇq<$ ƒÁ 6†ùýþd2i0NxŽ<UìvûðáÃ<Èó¼Ùlv»Ý'NüË_þòî»ïjnÐÒÒrÂó¥^¯Çq< Æãqmû'ç~öÙgG£Q†af̘QWWgµZ«ªª��7nlmm­©©ñûýÓ§O¿ûî»?ùä¯×«(ŠÛí6›ÍCt­þþþîîî3Ï<sÆŒ3fÌ(..Þ·oß±K°��B¡P0¬ªª3fŒvuk#¸�€1cÆìÛ·¯¸¸8//ã¸iÓ¦½öÚkO=õ”ËåÊÜw'‰³Ï>{Æ Ï>û¬ÕjÍ̬Ëò¯ÀjµšÍæ‰'nذá…^8ö«O?ýtݺu‚ X­ÖÓó”cµZ«««3ãB%%%ÕÕÕF£±ººº¢¢âÁœ?þÂ… �Ï=÷œÍfâ9hsO—.]ª}\¾|ùŽ;–,Y2~üøo¼QÅüü|-£ÒÒÒuëÖ½üòË=öØÐËÈb±œþùN§Ó`0h½………óçÏgæÑG�ÜsÏ=Zh©¬¬<ë¬³ŠŠŠœNçäɓǎ{J³ÎFŒqì$Ú³Î:+ÓTmÞ¼yΜ9 .œ?>†a¯¿þºV’(ŠVWWk3Ï9ç§Óyë­·¦Óií—,YrÖYg 1w‚ rss½^¯×ë�Œ?Þl6;£Ñð6Oš¢¨ÜÜÜ!6”z½~êÔ©û÷ïצ�î¼óNǵ*~ûí·Gµyóæ•+W.\¸ð¼óÎ[³fÍÆ«««qw8ÕÕÕv»¢¨êêê“o`ÿUUU¯¼òÊ‹/¾¸wï^�ÀÃ?<kÖ¬™3gþþ÷¿×ò}õÕW ^xá…×^{íË/¿Üºuëòå˵þ™3Ï<óùçŸã7¶oß>kÖ¬›nºiˆ™jSrUU}õÕW�×_ý‚ –/_®ùä /¼0a„éÓ§5jÞ¼y‚ ,Z´�°nݺQ£FUWW1â”.ZíÂÑæS”––VWWçççgJ²ªªJsK–eßzë­‡~xΜ9�€_ÿú×£FºóÎ;9Ž»ÿþû�k×®4iÒ…^8zôh�À”)S†9…ÛL®®®®¬¬�L›6-3ä^RR¢ #-\¸°¨¨H› ˜ñI�À¦M›†8–ãr¹ª««3 Pee¥vh?r8óÌ3EQœ5kV<饗2W·6y5“Wee¥&’$É—^ziùòåË–-;ãŒ3Ö­[·eË–êêêÜÜÜ5kÖ¬X±âÈ‘#çœsÎ í`–æ–¨ººZ«ë̽uëÖL;ÿòË/744dªø×¿þ5†aV«õµ×^ûÑÄ¡3Î8cÏž= Ãhír2™Ì–x–,ÿ[|ñÅ{÷î½ãŽ;>ýôÓ9sæ¼óÎ;¿þõ¯ÿ–Ë/¾¸yóæ?ü0ëÿæMŸ>ýå—_þG[·n•eù²Ë.Û±cÇwÞ‰f‹,K–\.׎;¾þúëX,vÍ5׌3æÿ`!¬Y³æñÇóÍ7³þðÿÙ“%Ë¿ååå›7oÖ¦´èõzmœüÿ³gÏž9sæÐ'dgù_dÿþý§4 ‘ 9Y²ü{qªs>ÿÿÃh4fÔùKáTï ²¯õÌ’%K–,?Ù“%K–,Y²!'K–,Y²dCN–,Y²dÉò8nú@:úY²dÉ’%Ë“N§]H廣ªê¶mÛ³e”%K–,YNßrÞyçT*uJ+ÄdÉ’%K–,?̱aå»#ÂUW]•-,Y²dÉrÑ^ÛzbÈÉ’ÁçóiïHÎ’åÇ„ †²ök–,ÿ+dCÎ÷à÷ûµ—1g‹"Ë/Žl¼É’ 9¿<‡ÉdRU5[Y~)|óÍ7Úê�Y²dCÎ/UU³!'Ë/QOðXžçûûû³%óÓȬöÔßߺÖþ¿†Íf;áuyÿ0äôöö¾ôÒK'ì¼í¶ÛÖ®]û«_ýꢋ.Ê–æ?bõêÕ(ŠÞrË-��I’´•Ä�� ,ÈÉÉÙ³g¶ Hiié7Þ˜9j÷îÝüñ]wÝå÷û3«ÁWVVΞ=ûoû›¶âôéÓÏ9çœÌ!¯¼òJ<Ϭy Ÿ}öÙ3f466z<žŒÙòåË:ô÷¿ÿ]û8iÒ¤Ë.»lõêÕ�€+¯¼rüøñ™êÆqüÁ�lܸñÈ‘#��­ºY–]±b…–Â]wÝe2™>ûì³O>ù$#�ÇŸxâ‰DjÔ×׿ýöÛÚö¸qãfΜùòË/swûí·gæ_G*•jkk+//ÏÅO»éÔz)8pªËñeÉ”áPŸrV­ZµhÑ¢óÏ?ÿ;k]µj‚ Ùó½lß¾}õêÕ‡ªªªÒB΂ êêêV®\ùä“OÞpà +W®¼ãŽ;®ºêª3Î8ãÖ[o… è†n��:thÁ‚çÖ[oõx<«V­zðÁ'OžlµZׯ_¿lÙ²gŸ}¶¹¹yÁ‚¯¼òÊøñã�¯¾úêÃ?l³Ù2!ç†nØ»wo^^ÞYg¥-§¸víÚ­[·>ôÐC«V­zê©§ÊËËNçsÏ=÷ÄO¬_¿~ëÖ­·Þzëo¼qÓM7ß|óÍ·ß~;Ã0S¦L¹ÿþûyä‘`0¸xñâ5kÖ¼üò˽½½?üðŠ+n¾ùæ»ï¾{áÂ…×_}yyùŸþô'AZ[[÷ìÙ³ÿ~‹ÅrBÈéïï¿ùæ›§M›vùå—ƒo_=»iÓ¦d2™ 9ÿjìvûÞ½{?üðC’$UUEQ’$ATUEQôØÅ¡Ea‚ ­Õ¾Òš mýi†eY� ¢K’”iS ‚aXÛŸ903°¤( AZšŠ¢hËæj;%I"BëTeYKGEM¤–A²,FQAeAM’öíäÉ“<(I’$I0 k§¦©Å0LÛ©YŠ¢H„–~&®@¤­íͲìyçwî¹ç–——;*f0æÏŸ¯µ'Œ–Á0œ)-ÍLéðÄ©­´1ƒ (cljÚ†,ËZ±»EQÍ AÖ WU5³È÷90ãÚMó †Ø´víZ¿ßïp8Nx@ü‘޵aÆM›6 �ðâ‹/ÖÔÔ|ðÁÚþÁÁÁË/¿œ¢¨h4º`Á‚ë®»îŸ\ þß³›â¿ÿû¿×®]k6›%IÚ´i Ã×]w˲©Têšk®¹ãŽ;>ûì³Å‹;¯×»k×® /¼ðW¿úÕÅ_œIä‰'ž€ ˆçy’$âñxww÷ðáçOŸ^__¯yy,[¹råoûÛ•+W†Ãáë®»îºë®›1cA%%%ååå¿ùÍo‚H¥RZý}ðÁ±XläÈ‘™ŸîΚ5ë˜1c�@[×ëí·ßþ裶lÙÒÒÒr÷ÝwÿéOš:u*MÓ·ÜrËܹsÙ½{w"‘áÈ‘#guÖ´iÓ‚¨¯¯5jÇqv»]’¤t:ÍóüáÇËÊʦM›¶yófY–÷îÝÛÛÛ[UU5~üøH$ÒÛÛ{Ï=÷ôööj {ŸÀõ×_ßÚÚšJ¥æÌ™sõÕW_|ñÅ ²,¯\¹rîܹ³gÏE1‘HÌž={þüù™å7º»»/ºè¢9sæôööîÚµë½÷Þ»ãŽ;��gâĉ7nÌF”¡ÐÙÙùõ×_koæúÏÜÂkí2AZÄ㸢(Š¢¡µb3ÍFkÍ%IÒ.ym§,ËÚ‚èn·ûСCZ ¨5ô™Fb¤§�� �IDATAQµÜµ=ªªjq A-YMžÖˆ£(ªµwZ:‚@„¢¨,ËZðÐb˜¶sïÞ½Zâ(ŠŠ¢¨å«µÚZÕ¢—v.™öEQŽã2gðªªN§sôèÑ‚ ûÆT*õÅ_ü£“‰™fðäÃq\&ädBÔÉÍf¦e—$)¡3ñ;“õÉm}Æ EÑ“CN¦äOž]’I AL,ÌÜ7d<9:früÞÔ†‰D"'{ã¼c­¶¶vãÆŸ}ö™(Š©T*“ܽ÷ÞvíÚuÝu×-^¼øÿËwôöö.]ºtÒ¤Io¿ýö¸qã¶nÝúé§ŸìܹsÑ¢E+V¬hhh¸öÚk/¼ðÂ]»v\wÝu†éõúc뛦ét:½téÒp8¼yófmçW_}µiÓ¦h!çóÏ??óÌ3µmÇ/½ôR–eŸ|òÉ3fìÙ³Çq½^¿~ýúÿÇÞ•ÇEYví{ö…}aD@A1TT0À×¥r)%·²RÔ7w³PÓ7K³ÅÜB³´ET>´,ÊÔ*%\E6Ù‡aöõûã4§»™qÁ”æüÁfžy6ž9×}ιÎu’’’6mÚ)“ÉnݺգG|.\¸àççG÷[555:uªgÏžÞÞÞööö£G.//_¿~ý¨Q£Î;Çãñ„BaRRÒO?ý´}ûöÀÀÀØØØk×®}ÿý÷@ŸïÛ·o=¾þúë½{÷öëׯ{÷î°Îøþûï<È`0<<<BBB²³³<GäóùB¡°¥õ!dÖ¬Y½zõÔœ;wnÏž=ýüü–,YòÉ'Ÿœ9sféÒ¥IIIEEEô³ôꫯŠD¢èèèsçÎÉd²ž={fee­Y³ÆÆÆÆ"¶Y­•ä†N§“J¥4x€Sƒµ6øA.— ø›ËÄápà ƒ æÐét�žˆu`Ìd2lmmU*|5ÀUÁÓ Ÿ…X‡Édòx<t߈\.—ö€pVpt€%µZ ¸A švÓ, œ>¼ §— .ã0sc0n‚¹çÕh4~iŒf¾øÒ …BˆðZYé¶dr8œYßsÌÌ<|y'Mk´–¶¹Ë©777×ÖÖZ¼G …bùòåçÎëÀ‰>ø ##cñâŽzõš6mD$ï¾ûnQQQw¢Õj/^\]]½yóæÎ;—””À]-//_µjÕÚµk›››.\¸aÈ߿üòKøl=¶lÙ2hР;w~òÉ'6l€øióæÍ}úô6lØçŸN)((8zôè‚ À¡€UTTìØ±cíÚµPÅ}:99¥¦¦>õÔS›7oNMMݲeËÀ¡þôã?ÖÖÖ³òóÏ?çææž={¶¢¢b̘1'N„/CmmíîÝ»óòò>üðÃO?ý477×âBæžlôèÑ]»v?~||üôéÓ}}}M6ˆ8p`ZZü¹}ûöI“&½õÖ[V,i£'çÿepÇtF‹Çã©T*ôhtd€ (€(½^+bØ?“ɼ~ýú7èÏB¬Ãb±À³³Ùl8œ` 8h��xNÎNÙÑ™4Ä @Nn Rp¸=æåFõå—_ªT*#u:D-ôUXYæíjwœ!C†L˜0²eËs´9räÈ‘# !nnnïÖ888Ìž=û¹çž›2eÊÑ£GµZ­Ý|ðÿ÷</33³-;™;wîÕ«WSSSE"¾8tèСC‡®ZµêôéÓ¥¥¥·oßÞ·o_EEÔc¸\îäÉ“_~ùeØøÿþïÿV®\ùõ×_ÇÅÅÁ+»víúý÷ß?ýôÓË—/«TªéÓ§«Õê_ýU¡PB¶mÛfRJ)))™;wîܹs!íFIJJZ¿~ýáÇCCCáÙ³gBvîÜÙÒµtéÒeöìÙ§Núá‡>üðȈˆˆˆˆ;wî|üñÇrŸ££££££æÎ{äÈ‘o¿ý6  ¥÷ïߟ™™‰ ^«µqÝKcp¸à¯qù‹\ÈÆ`’ 2N€àÜ! Â|@8wtú�36XЏtéK0È +F¸!œ‰Á` …°d<€c —!b¡Z­†ßÙlvLLÌéÓ§e2™Á`HKKƒ0 ³Op’p�‡4 —˵BN»Ú}†Tžžž<ÏÉÉ)==}þüùMMMïÖ”——GDDìÚµë³Ï>ãr¹2™L.—kµZ'''OOO''§ÒÒR___±X\TT¤T*iPA+,,„ooQQQqq±P(tww¯¬¬¼víšP(tssÛ¶mÛ¡C‡ÒÒÒ&OžLùøãËÊÊòòò òòò*++kllEEEEEE ö–––––Ú¹sçß~ûíÔ©Siii›6m"„L›6-((è™gž™0ap´ZíÍ›7 ŠŠŠø|~§NJJJär9‡Ã}J¥ÒÈÈÈyóæiµZ'''{{û›7oÞ¾}ÛÙÙÙÞÞ^$Éd2ØØ××7''',,lûöíׯ_·µµuuu5¿öƒzzzž<yÒâíõõõU«Õ;vìˆõóóëÕ«×[o½%—Ëu:Ý… <==wïÞ-‰ ŶmÛ€ãwæÌ™3f̘1C§Óݾ}Ûúím뺒͆´ ¦¼Àá‚Ç(£F±ŽZ­†í!%�ƒe¬É«Õj€pú˜Oƒ ”p4 ¼ ›arL©TâŸp¶ô~�?�ðˆ�i€|X( &|ñäÉ“ ….áÎ;À;�@R(P\ÁȆÂîéöB gbt¢L­VCêâ*‹%nx fx|>&s Ø ¯‰Ñ+ õßM§Óáþq{4á|ð-Lâ9›Í<#‡éÇV’‡,OOÏ„„FS\\ ){0•J%‘Hbbb¼½½ !‰„Åb :T,4hΜ9µµµYYYr¹|åʕݺuëH_Ѫª*77·ðððßÿýìÙ³ÑÑÑï¾ûî€ ñcÇD"Ѱaò²²6oÞœ“““““ãááœòÊÊÊ€€€AƒÁï|>¶ÉËË›:uj=~ÿý÷óçÏ=zþüù, þCR©”ÃáÄÇÇ>ü?þÈÉÉéÕ«×'Ÿ|"‹y<Þ… `'Ý»wïܹ3|¤¦¦ÆÇÇgèСð§Á`¨¯¯‰‰ñóó+))‰ŒŒn›‹‹Kxxø‰'rrr†…%;;»£EFFŽ=úäÉ“999~~~›7o µ··?~üxYYÙ¬Y³ž}öÙQ£F9s&''ÇÖÖö‹/¾ðõõÍÊÊ*,,ŒGFxMMMtt4°re2™L&2dˆƒƒC]]]tt´ŸŸ_YYYDDDïÞ½GUXXèíí½qãF•JuìØ1‰D²lÙ²§žzJ¥RÕÕÕ <xÞ¼ygÏžíÞ½;—˽råÊܹsÅbqcccNNNuuõ€¬pb²Hòðð ý …B,¨Õj6› åwH—6'''¹\n+�OŒ«ñ]t& òZ€(ÄÈmÃß!yˆ…¾ ã ä¹aM\?¼Á¶Áò8ìNñ#3ôÎ&y3{{{�'6›Íårù|¾Z­&ƺ:ƒÁ ¦ïdqq±»»{rr²åe»‘@3ÐA±8„X‚ۊׇÄ*MÀÿWK¥&b‰°`‚‹xtók‰S`‘SGoÓ cmæÌ™MMM¾¾¾PùS«Õ7nÜ8rä#""";;[.—<xpÔ¨QÖï-!äܹsðhZïÆ?hIIIl6{Μ9sæÌIKK³NÖhÝNŸ>Ý»wošgU__ëÖ­}ûö¥¦¦bI kévvvåååàÐÑûp8M�¥ÀBÀ„9XncÕ‡ƒ\j:bÀ ¿� Pœ1,¡‡Eš�MÛÅ òÍ ·†¾ Bpi,ËÁÁA&“)•JƒÁÀçó}||®_¿„½ÅÇÇÇÇÇÓwòàÁƒ={ö4ï6CoŽe-\Ýã…c.ÞXÜ/þ œ¡k<9å­”åÍM‚ìÁíÍËWOÌÜpUaÑΜ9SZZ­R©@ÖóèÑ£ .´ªXíñµ˜˜˜‘#G8p ¤¤dóæÍÖrŸÙs&“Njah¯Èd2±XŒAÒ‹¡L‚ÌfH¤èõzXûCž`°ÁdÝ4epO˜‚ .ù~L¢ð³àÝà@�=.x9p-ðAø#*€Éçž{îÚµk×®]Óh4@xÑëõ\.W©T–••Á5bÊÑÁÁ¡¯M·"=,3 Pˆ¥÷O#2,°ÜÕÒÝ�„ÈÑz0„çG¼×²V[NÌ 9-šX,nË¿Çjíg>>>gÏžÅEwcc£õž´b-‰²0 ¥R‰h�dva— d¨!°1²±Òþ ÃÈSAézz�´°2OûA- P`ÿNágÁÐà ( \ª#! Nê¦@½ƒŒìÿðáÃp9p½6 ¸i�ˆp-ÝÆvúÇÑ·ˆö9&]8÷*Á…øm1uÖúùàî_ïz +ä´h%%%miÙµšÕ …ÀÜGèt:>Ÿ¨€ù(¤¡ÃBb½nÅ „5H¶†""ðͰ ’BÀd£a~")�µ°J¨ƒ¨XÂáp0ÿ†A¾‹Aœ'lŒ®Ö¡{†n-¢©ÄØâ£Óéär¹õYj?³BŽeËÏÏ·µµíx’ VëØvþüùÞ½{›¬4µ&È{÷Ö *ƒ0Äø“a\ò3 X ët:†q¡úgŠßHef2zƒA/ &ƒqƒÉÔët²vÆ£+ a¢‡ðk*Fäùs3ƒa,•3 -$ܘL‚&“e,2é “ùçB*á,–0Ä`Ð pz½b(ƒñ`ÏtñÕ@ˆA¯g²Xjb©Da¢\ÐJL`ÒíOƒ%¼‹„ øh �ü ÉI Ò “4šIVE!x>æá‹y œ&“¨‹NxÒe9»kfÈêR[LétêÔÉz¬öÄ™¹Odåäp޶G‚T(ƒÁdB6 ÜœV«ePEx$’™Ð D`³ÙzŽIsmb OOO™L&‘H0),—‹U<%LméõzEÝ&‹ÍP4¢Ñhlíìär96·‚<ÄU¨jñ ƒÁ�¤kp!˜QÄK£™œ!CHxø½fÆL 篽 ÐS£<íÙÍ!ÇÒh 7‹e“=¾rW5 ÏÌßËHôÉZ¼±Bν™³³³Å…Õ¬öØëÍ_g––êþøƒËåÚÙÙi4èGÁ¾¾‘PÀ2R€E €X„'táD£a°X&äg †€ÃÄ$¸Xz}cAÁ`Ð+B¡ Ah\† :i‹ÃáÈd2‘HÄf³KKKt:A¯‡VìQeêtºt)//7 ½ž¡×sx<8.‹jÜù+ 2ê@Ä“A[,£Ü¦ L&‡Å×Ìôó»Wȱš5±f5«ý묕,x% ò»` •ìbª;1rœèN\Òb‘ƒ!ü nÉçó±,õår¹€:*•ŠÇãŠÀž±l`C3³9Ž@ @ÍhGãr¹r¹©Hƒm$ 6‡ªÕj¸.¨Bм€Œ»–n£‰È¦¹Hhë†qM¦ I}-…/÷=¸‹n¢j%ße1UˆÛ߫ۃ&ÖRSSAE-&&fôèÑJ¥rÙ²eqqq sCùå—_ÒÓÓW¬XáèèØú®êëë?øàƒ‘#G¢pËãoyyy8º†òüóÏ_¸páæÍ›„±cÇ‚Æ6ØÆ !o¼ñüYZZš””4iÒ¤ðððÅ‹Ë\.´aRRR®\¹‚ãg¬fµö6t˜Cƒ>öÛ#®�ý  É€ÜL‹u# œ8ÊÌ�<Ð"i°z`ÝDA =7ö}¨îìå啟Ÿß©S§ëׯ£¼ „eÈØF4Ÿ€²ðín"ÒöfgÑ}£¬5ݲjâ [1à&˜ì_Á£yý¸û·èýMÄ„ZB&såi󾜶p©Ú¢ÝЂ¥¥¥­X±âé§Ÿ KLLÌÌÌT«ÕÉÉÉÈ[%„„††N™2¥% aÚ¤RirrraaáôE-))INN ›2eÊ”)SŽ?SÜÝÝgÍšuåÊÄ›uëÖ8p�W1ãÇONN¾víšN§KNN–H$S¦L™4iÒ… âââÞ}÷ÝÔÔT«´Ú#‹~ Ì€¦¬b±X°RÄü¨³ ì 1öŸc×”[p 0ž@ï™fÁ!a�¤ÕjåsåŒÐ?ht:|«4iˆ‘l†Ô8¤>ëõz¹\K=ooo@�µµZ-“É †P(|æ™ghÅR{{{[[[(ê 8ÁUCH€#î)Zíá¬~ZÉ OŸ>ýÃ?3fÌk¯½6oÞ¼qãÆrMMÍo¼pãÆÔÔÔ¸¸¸ÊÊÊmÛ¶õèÑ#66688øæÍ›wîÜyæ™g¢££ûô铘˜ØÜÜüúë¯B¾üòËóçÏ?Y÷( <<<<<|åÊ•ååå0ŸÎ””GGÇÀÀ@Ü~èС¨‚׳gϹsç2ŒîÝ»÷êÕ+33ó Šó¬Ö ê½2™ìƵµµz½¾¦¦^‹ÅĨdƒi%hlll°^)/èàÅ/€(ö³X,¹\šlpP(á¨T*Ø "'ƒÁÀ\ÇlÞÐÌâ²!ª$o‰[Ø”ƒ“@¡zeÜÜÜBBBžþyoooooo‡ãããºG*•êÈ‘#€|pÎ2™ 4~_ T*+Á ˜˜u„ßAX¬•ä¤9–Ó(…¯`œGgÆ7‹»27úƒô™ÐBàwM¾áöØíÄhÙèóÑÍâµt†÷å´”ï»xñ⫯¾jccƒ)#±X¼téÒW^y%++Ë`0,_¾<99ùôéÓ?þøãÎ;µZmee% M™9sfŸ>}ž¬olFFÆŽ;`@!dÓ¦Miii_|ñEpppCCCmm-­M— ã�ÀÆŒ±sçÎéÓ§›«q[Íj,Ê.�$” ’ ;r´Z-¶­€;Æp³.�H,c™³mÄ8EÖ¢–ÉdÐ .j0 ƒÏçó2xÒaR­¿–ÙÀdÔ2�ЯAúhoZ­xn0i&  k×®ÑÑÑp\77·ªªªS§Na©  Q­V£»„ÓFÝkmSzŒ)†tUÅðΠ'„VS Pàm„Wè>VúÒ˜ffòA‹†U+úÄP=7k½’‡ÛóŒ†C’Ì eët:ÊhxþˆCp?ÿäÙÿýŠZ±û¡ÄÅÅõîÝÛüõ#GŽÜ¹sG"‘Ð/†††B£´´ôÉ̓㣖”””’’²uëVPí\¿~ýÈ‘#Q_2;;;''gÑ¢EB•_ýõ 6¼ùæ›VhµG9؉h¨¼‰óo xà„\ÃB1%ÔɆeðnàˆÁ§›¨P3™LÞ§<M–ưÃÀ¹ÃáÞáÖ_Ðgˆ8ŸÏwqq ìÞ½{ß¾};wîüâ‹/:99A*¥¤¤¤©© J8@ª;´ƒF%SbäÝ™TìJp�šÕrè^$z-ÐR>mÚ´©S§ÚÛÛ÷Ýw¸1ýY\b<A÷høðá�0›7o^»víÑ£GCBBà­ÔÔÔ?þøƒR\\L‘3„æ5kÖlÛ¶-44ô³Ï>³>jVû×L� ôf\þBœœœ!ÍÍÍ …J2àÁ!µ…Ó<‘ e÷ÐoaïË_\gc±Éd‚Á`à|ÌÑÄhë�„ 4 ˜Û�Û &™Êår˜y¯×냃ƒ«ªª.^¼XVV¦T*«««Qeb ì}±µµÝ~¸F¹\£T* ê“¢.ß\j뼜rú÷ïÿõ×_'&&òx<±X¼eË–~øÁÏϲwï^‘H¤Óép”›Íö÷÷‡ŒíË/¿ïïïïààPPPpñâů¾újÇŽ^^^~~~³gÏ^¿~½Íw³*++e2Yss3°ø‚‚‚nݺoÅÆÆB²²²àϳgÏ:tÉ’%Ç¿pá¹sçêëë{ôèa}à¬öOE9€"0G�…j�'êëë‘·†-–Xÿ@¹|›.!¯àDŒÕMÔ �@mi¨ý9Õ­’­hIÝŸ•À ¡ ðBÉ8NWYYÉd2ëêêúõë·råJ¨¸ðù|í;!Õ †äâüåÄÑpà¯\ŽR©„«õ¢n@ÏP0_Cƒ¾@ë†zntÇe[0O¯×Ó#€Ñ ·Ô Jê‡bjx†ÀÝ #JzÄ8øçþ£œ±cǪTªììlBÈÚµkccc•JeBBBlllCCà /¼°jÕ*Ÿìèè¸k×®o¾ùfÏž=“&MZ±büw322 AÙ¾}{JJÊ[o½õ¤àŸŸ_BBBçÎáÏÈÈHFóÃ?ÀŸóçÏÇ yþùç麻»'$$Œ?~éÒ¥{öìñõõÅZNll¬‡‡‡ÕZí‘E9�98h�%è=æÇ°{gÏДh”Pà R©ÄÁÒXÚ!ÔL(�>ñO¦rNpZ€ý˜´84Jh4šºº:gg禦¦¼¼¼¦¦& ŸÝ¹sIÑï›fÍj|5Üõ0‡†?(ÃX˜,±F™4iÒ¤I“ðO>Ÿ¿nÝ:‹[öèÑÃä­„„“mzõêe±;ú±5 ªáŸcÆŒ3fŒÅ-,X@ÿéããƒwÃü޽ôÒKÖ'Ïj2Ê¿Œ™.”`ÁU?®ß‘Y@xp|5€ö¦à:<5(èÄ1åe’”cW±™{™|ÀòÉrxÎôù+Šºº:WW×+W® O*•"ªaœ!Ô® “†UnˆP‹ ã!öÓJ¨Õä´ngÏžMNNþ裬rdV³ÚckØ/‰~ãšM�g _è‘ÒØ«0]Œm1ðêFƒ‹ÇFd V-Z¤zñEÝàÁ¶z½>1Qy诨è/mÄB¹�9t:@ „TUU•””TVV»�*3(Ý„R7pi8­�ÓŒÄH’Æ? C+-†˜‘£ó‡4ŽÒ2ø®y¾Ëâžñ¸æÂeû@Í_4?ŠE5zî.LöfQH·¡§†›Hõ¥ ö@ñdµvÞ“ÕÕÕÝët«Yí4LÓ›~ÉŠ�¨8€óÍp”Î÷Ä xp¡PH…ÆVzš�:} €�É0[FÃãñ<=  Ö^¼Èñô4p¹Z†îàRÌïÁ»ÐWD!À^N87&“Éãñär9=J‡ÇãaE…#F5̰)Š6~ëi¿ŒÓ}¶ÁjÐ}ýž¶7i·VD¦[ºº¶s.¬tÀ­ªªÊšØµÚdNNNB¡Ð|ý‹Ýà£Õj5ÇÃ* ª^¢ßDÅ‹% A¹=#ö¸�À` €S«Ñý©Êb¡‡‚"óüùüÍ›U±s9ú࿎ˆC¦f€J�QDTÄX§XBê6¡†è Ä¢(4$Ñí8pxK;xÎp—¬ÏÒcšXëÀvöìÙ'‘SwOfgg÷d•Ö¬Ö3çJaIk0¦ IŒèÐÍ�U✼‰$[Ó5B9À(D§ÓÂ0 ;w2Ço”júj $Ç`c °ÅÙ ‚‘Édt· ä š'16±bcœ›Éò� ¶†e-E È.kKÔÂçó[I‹áfô솖—ÖE9éôi+‘ÝÁjÁXÌÑ™k¾ÑÿV¸潟ô…[!çÞ,00°c“Êà Ù*§ÕžtÃú?¢¤Â ”†?øk”‡a2™ …‚ÏçËårÀ$¨‹£~he‚Ñb9° V  Þ·¯áÛoósÏr_Ý(eR°! …ª/´Ž ¨Ô€§Ø3/ž+Š3uAé±:ø;rä@ôº%ÿ~¯Úšè©[Ñ ‹@­+I·åˆ-¶ „àf˜µxbæ=XxXû±X=ºk#­r,›½½}Ǧ¯dddLš4©¹¹Ùú¿îði4Èq©T*pë\.Ý(¨¼ X' Kuu5‹ÅS§NݶmTìMÐ £Z õ»ó†êâÅ‹çÎ)Ùlîi¥6˜¯ùŽÇ×ꜨšƒÈˆ"”J% �¤Áá�BÀ¿ÃÀ„ùƒ$o@&D/ð¿^£)|V³&Ö¬f5«Ý³a[>xXì³A ]¢H€mÀ×755mÛ¶ ç #¿ úþlmmår9tnb’ åÅèiÊ,ëäINUÑ%è.ò)!Z-“ÉÂòp ;D‰>ŸßÔÔ„éàààøä w� ”15™ Є鶿ñè;JÌ™Ç(mäÐ3Ld1äÂŒœ9Õ µJIÛÊûxçÛÒ™på1 zÏ£ÕjçÌ™7aÂBHqqñúõë§OŸÞ·o_ÜF&“-Z´è™gž1é‚´šEÛ¾}{NN!dèСñññï¼ó¨ùBlll6lØ‘‘±oß>xå¹çž=S¡P‘�� �IDATz´X,^²dɨQ£p:‘Õ¬vß¹5À,–ÐC¦!‚A¿O÷âÀ‹�K€L'ð"“Élhh€”�¶aÒÝéX0�‡¾oË`0hŸ×æ¥ðÎ3 ä%µ O€Ñdfè2„JÀrþì $P�›Ö—ijE€!F šöEÌ ¶Q˜‘€Fnb&"p×ÔœÅcÑc§q²œyÍü@æ <À¶?$´px[ ‡&"‹„Çãµr–OH§Ó8pÀÎÎnܸql6»¬¬ì§Ÿ~zöÙgq²h"íÝ»×ÛÛû™gžÑétB¡†m�gÔ#h¾ù¿ÙÒÒÒÖ­[·iÓ¦úúúÅ‹ÛÛÛ'$$€þëòåË‹‹‹u:Ý… öïߟ––æîîîìì¼|ùòß~ûíÒ¥Kݺu³BŽÕÄPàª8P´€2¬îqF�­m1ºlØ#!øs\t› �®š1ŒÀ´“É´c«Õë˜:ö/lŒ-`è‘”(%€êpÈ\ÀÀ Ý44 Éd2b”ºÁ˜ŒF,ä€n)H±a!ÊúÀ´ïÓØRòwß¾}ß|óMZZš\.Ÿ9sfPPPÿþý'L˜µ~ýz�BÈôéÓAXzãÆÞÞÞeeeIIIœ0aBß¾}‹ŠŠ¬wyܸq—/_vvvnll …|>_$üüóÏ¿þúkzzúo¿ý¶fÍЙÖh4...|ð*ëXÍjbv8999::‚æ,LÀVX¡£Óÿ Rfð›Í†ñ„jŠ„šŽ� Cºò [B$-Aú½F«!¼ÍD©B5¸@°…rmÈ ƒC šž9 P§„Žxƒ"{šB#DWtÖññ1T'B»¿!¡xOî:hÇâ<“`5&°— ~áíÞ Ç¢]¸paüøñ‡zíµ×>þøãêêj‹›544¼ÿþû/½ôÒ¡C‡4Í|`ý΃<y277W$h[yyùü1bÄ{{{Ÿ¹sçJ$’üqêÔ©‚³šÕŠ…„„ØÛÛB„B¡ Û1ôÁòº]x f‰D"“™fˆ0œÐþÑdX™‡‡æúY,V/&3Ô¨%J——0âAê1ŽÀx€+lÅynHEƒ¸‡–»þ+ÃÃfã $òaâññ1F£ø»árÿ>Œm4¸QÈ›7œÐƒóxð].—+—Ë…ÍØl6üÂårŒÖâ ´ô†¿¿ÿĉá÷ÀÀÀñãLJ……-_¾|úôéW¯^½ë…íß¿¿¸¸ØdvÎ¿ÜæÏŸŸ=räÈ‚‚‚€€€’’’cÇŽ%''Ãèý÷ß'„ÔÖÖffföïßßzǬöP,88ØÞÞ¾±±±¼¼Ydˆàd3ô‰A� ¢477cìB7ë`³ ¼…Ù-Ø!¡„Èßg¾ †þ„pX¬+Ff3û„½™¹‘Ì¡bÊÀ6tÛ 2°ÂQ!ÄÞÞ.K;ÖgæQ'Ö!...}ûö}ÿý÷£££}}}oöìÙóöÛo[œ£ŒóûÀüöÛo=ztÕªUÖ»¬V«% ý( ™LËBÈéÓ§#""pöÕ¬ö-##ãÎ;(4@ŒÚ0¨Ø(4bZÓ¢ •JU^^ ll6ZL¤ G¨� >x# ·æï¯yç¥@@.“É„l3ê=›×òóóƒx êO˜ýCÍ|@˜…ƒé .—ËçóH Õƒ*Ú …‚Åb9;; …B©T ±"“Å|Ô]ïs+ý7­¼íq•šѕÝu*vk‰µiÓ¦EEEݹsgïÞ½„ggg&“YQQaooïæævþüy Û™Lfjjê?þaWHHˆD"©¨¨˜0aÎjû7ÛÑ£Gûõë÷í·ß^¸pÁÛÛÛÍÍ­¹¹yòäɳfÍzî¹ç!0ó#77÷Ô©SÎÎξ¾¾Ö›fµ‡eMMM*• ÕÏ!0%‹ØïhD‹:ƒðÀø†ž: •ìªAÎäèE†Ò™€FÓÍͰzµ,(H Êfr¹ò<Àx¦ùʃáÚµk€(£é ÈL³±±A¡6€1„X´†³‚¡sZ­V,ÃÀxê:£Ì5Ñ^ÕĽ‚av‘Çãñù|>Ÿi(4˜§R©èŽlLRáhb;Íãñ„Fã d~θœÌMOŒFÐÂÚ |¤¥;€{Ðh4°[¸u´©Õêz£Ýsb lذa]ºtßß|óM‡“™™9hРիW_¾|yÁ‚2dLüôÓO³²²ºtéƒs233gΜ¹hÑ"ëw~Ô¨Q¦  €²nݺÁƒ«Tª À°QBHxxø¦M›Ž?~þüùU«VMž<™bcc³`Ák†Íjnà1MFv¢˜&„˜IÃlàáêê*‹Ñ­#A£èüÇ2 î‡+F¨•2qâŸN–Åb¢¯QèJDtê ‚-Œ¨hÔ©¨¨ ç i–ü}˜úY|¹jH·>0ígwœ±cÇÒΟ?ßâfˆ+O?ý4!¤{÷îï½÷žõæšÜIúfòx<“[M¿bggg½V{pëÝ»·³³sCCƒ‰ ÝV‚ä.¬£ "'C*• PÄH#Ff3Ê}"~àLBµ˜<û¬ö›oØ,yõUMn.Ë„‚oðqT»cñx<˜h€€‡Ln(Œ£dŽ^¯Ÿ={ö–-[à´±,„‹I lŠ]>Ög惫YÍjOº]¾|Y,Ó zlš¡§¥aÄÓ¹sg•JÕØØݦ¦&àU£t4È<c* Â&ZÈ�§ï@ì‚£ÞF²‹S …Ü |¹‰GDAŒ`‡8„†‡7#à '„††ÐÔ5�¿½{÷BNÁsPäa·)ÂÒ=Ý^ºÛÔ¼÷^¡P Ì›¼E÷ê#% Žâlm·n)éžP È·¾=^¡æå˜Ÿƒy N«ÕÖÕÕáºÁ 9÷fUUU˜»B³­Ö± ÄÄè‰8&Ã4!’�9N:ª©©Á2`Lƒá7ÍÇ}¢"5 `�lÝ9à@«ª˜l6»S' 1ÃAaNæýÀÍ©Õj@€6(«;d±X—.]Â0PþlhhÀ†P@ÐÜÜŒE ÈÚÁ®0컿‚¼ù4ú-쮵¨ƒi²“q¨äÉ­¿eRØÇ[º"š¡ÐÊÉ›à5ʹOkjjêÀórºwïnýÿK <5¨>›”mˆ±™Öãú�ÅËÑÑ¢�½!|¡W-&Šj£@D‚±¦×`ã²²Û2kK´ÐÎìÁBöâ ŽfÊ¡‹DŽúMdI�Ç‹X´Ô YKáˆÕ¬‰µv·Ó§OÃìÛl'Ož|óròóó;üãååøxž��F˜ JH�1èCà ©T ÞB‹åèè(•J‰‘x†Ù0l¢„¸?‚0ä:`2Ô¨u]Ÿˆ…“AP‚ð†ƒ×PW Qe¾°#és4ÿ ë7ÈØ†sö´N‡ A 1ŒZ™²ÓzL€iÀ–¶§9äï3{è&á-Îf²‡–¼ç¨þ`žvÃx×|{ú4îz+¬cÙÂÂÂ:ö¼ ù2‡ÕÕÕÿùÏ:vI|ôcËtB1H²ÁðMp €Â èÙÒ°1-:�Ò QÆçóíìì¤R)†MØíx@O‰FV;àóùl6 …*• PJ¥R1 …Bliì�…£cÍA.o°Y‡Ž®ˆ‘´†ÿ&¸4“‘n­7”àÍÁÙVòimLÇYfò; 9tœ×Rr~Û±žÌÝÒ1„¥·¿ÁÛÖ‘«– ÔH ׎=úÈÆž …Â|'õzýñãÇï: ñ4,ÚC·#"ékt Ûï!u›ƒÓjµ …ºF£7nâ6Zb %d0ò€ ŸÏçñx>>>nnn¶¶vÎÎÎ^^^Е<uêT'''ŒN0Q†å(tsaaat{,k°°D¨‚t§ÔA´Ççóa{8 —Ë¥µÚ¬КX³Úãe%%%Ðùûúë¯ÛÚÚZoÈãl؉ Äe“E+æµ¥Uƒ}9ôOò×0ib0’““±4‚¸¢ÓéD"Qyy9ÊTCyŽkkkëææÙ«×Y©T\]ݹ¢¢¢¦¦àäöíÛÛ·o‡Qº*6šr°¨  �ò{tÚ >‡8ÁÆ#Zª€@+€=·…A@§[I´«"5=‡þ/›œ¹ÅQÜtpp ‡×A´G+Ž[Ì+ÒïZ¼üû§¯\¹ÿ|öÙgÅbq~~þW_}EÙ´iÓ¥K—¶mÛ¶ÿ~Ð& „Œ;>ÛÊÊÊ–.]úÚk¯ :”ò믿Â=ñóó4´mÛ¶ýþûï„#FL™2…råʕիWÏ;wÀ€ô–………ü1<Ÿþ9!dÆ çÎ#„ÄÇÇ¿ð ôÆÿýï!Ÿ¾lÙ²|=!!!""ÂÖÖöÈ‘#øâÊ•+ýýýîH$[·n‰‰Y¿~ýÕ«WáòŠmß¾ýøñã©©©ðç²eËJKKá’l¾ý–-[à™<tèО={ #ºdÉz¼“„ÄÄÄ.]º`{Ù¶mÛh¼<uêÔgŸ}Fñòòúä“O!«V­EAüw?¡n–ùàb ¾â<Ò—18ÀœE¡Çp©Õj@2T}†‹ÅR*•4s úÄ…BaHHˆ››[=ÂÃÃýýýœ¤„h½¼FŸ8q"77Øl6»®®%‰±°„5!¤™aó¼R©ÄBŽÄ†B12#ðÒð´uàÜè2¤[Ï!TÿƒcqÿÀì !Är o ¿;::Bœ'•Jé -eüp±‚û·h÷9éééüñ¨Q£`y²hÑ¢ŸþY­VñÅ[·nݽ{·Z­¾páBvvö¾}ûÜÝÝíìì:<ÞÌŸ?ÿÌ™3EEE±±±„ëׯ/Y²dÚ´i£FêÝ»7›Í~÷Ýw¡çîÈ‘#«V­Ú½{·T*ýïÿëè蘖–véÒ¥ëׯcO¨\.—J¥ç¿ÿýïˆ#¦OŸ>lذY³f………­]»6##ãúõë~ø¡§§'jÌœ93'''##cÆ cÆŒÉÏÏ·µµ•J¥K–,Ù·o‡ÃY³fÍ!C´ZíîÝ»?ÿüs˜òpM£ÑÔÔÔ<ýôÓ‘‘‘‹l}ýúõ3f”——#¯ÅŠÉÉÉçÎÛ½{÷«¯¾zìØ1‘HÔØØhooÏçó5MJJÊúõëu:ÝéÓ§çÌ™óÞ{ïEFFÆÆÆòùü ÔÕÕvHvvvEEÄdÎÎÎC† ñôôLJJš9sæ /¼ðóÏ?ÃáJKK_zé¥éÓ§¿öÚk£GþðÙLæ–-[rrr233—/_îííÝ£G'ñ¡7 7Ná¨uL‚AÐÖþfþ|ýË/«Ôj!Œ;y»vñ ú‚C 1ø¨«»ãâ¢W(Ø*C 899¹¹¹õë×oÀ€žžžöööîîîÆÄÚÅÅå?ÿù““ÓùóçE"Qmmmnn®X, ”Ëå( Ä3NÇà1ô\½Aj€²b\ŸÏoþ¶Ùf¼ “É”~.å.år%\ø,^>&èpL>ØOŠô�°qYSSÓ½d{LkŽŽŽžžžô³»yóæÔÔÔäääðððÌÌÌ7¾ùæ›ÕÕÕz½žÞò1´ßÿ]¡PtëÖ­¹¹Y"‘€P½ڦM›._¾ŒB5þþþ0h�n^^^„矞ÇãM˜0A.—»¹¹ñù|™L&—ËwìØJÒ¸·¯¾úê½÷ÞËÏÏÿã?!ùùùƒÁ××·¹¹Y©TzxxôîÝ;>>ž>úúzƒáééikk[__ß–?þxòäÉ0TÔÁÁÁÁÁáòåËkÖ¬Y»vm{pÒ\\\^zé¥ ¼øâ‹111eŸþþþYYY‹-JNN†W¼½½ù|~aaaUUü~þüù#Flݺu„ ¹¹¹%%%qqq° ’H$NNN*• ôËccc{ôè‘™™ùÅ_úûûóùünݺUWW677Ó¢Õj<==Ïž=Kyûí·ÕjuçΧM›6mÚ´':±¤2,ÛИdkXFJePÉGÅh½^ok«]µŠ—‘Á1¾®…Èãñx]»ª|}ÕúÅ‹ÿûŸcFS ¸»»÷íÛ7<<\$¹»»ƒ—T*•ŽžÉdÖÕ50Œ½^_WWçâârõêU¹\1†/jû3™Bôcõä4Ñ©uœ,ºÚ¿øe ]¸N'Ñ1¤ †Ž=žt ñIk ñx¼Væ´Î.3É>µÒ Cw>Ñï¶”£BO¼^½zuß¾}½½½7oÞüí·ßšôÙ<HQÊâù›_H+QÑ}BÎáÇoݺեKPý’Ëå«W¯^°`Add$!¤k×®ÄÈÎÎNOOÿôÓO£¢¢ÏoÝO?ý´lÙ²èèè®]»†……ÝäX´£G.\¸påÊ•¯½ö!dêÔ©ÐUw×öïßÉ’%ÕY¸páäÉ“—.] Y-[¶ØÚÚFEE!ÂY´+W®ØÚڢخ]»BCCûôéÓ7S.—Ÿ?Þßßÿÿû_||¼I"ëa™ŸÏÏËË+++óõõåóù^^^K–,éÙ³§F£9yòd\\ÜîÝ» !¾¾¾111û÷ïÏÏÏÇÏš5ËÍÍÍÓÓsÉ’%·nÝúå—_jjj6nÜØ½{÷«W¯æåå577™433S*•º¸¸LŸ>^Y·n›Í:th;ÝÌG†:ès!å…ôbl ˜@ àp8Уƒ•ƒa0ñãõaaJ½^êï?8c„Ù³¥\®.:Z©%„\¾Ì kØl¥«+ÇÓó¼—Wµ‹Ëh<0 ¶¶Ì ÌüïUŠZvƒÁppqhî×\__¯ÑhîxÜilh„Œ‰t&`'“ÉÔõÑißÔ2 ’D!ä;"(àfü|Õ!„÷Ï 6Ð?„â8à´œBM³´ÍóiðÆüí‘‹l®>@#^-dR;áñx&û§©bÇ@sÅŠ§Nzå•W`¹@“5°Vd~h>4-¯G(öv[2Šì»~í{õêåìì  …ÂE‹¥¦¦Ž1"22²k×®K—.%„ÔÖÖnÞ¼ùĉ-äüøã«V­Š‰‰Ù¾}{ll,ü“Šeff&&&Λ7ð ‡òõ×_ßõ³‘‘‘�Þ ,5j  .))Y¸pá—_~nqwîÜIII™9s¦ýúŽ;Æ×N^R&“;wnï޽Æ ›;wî}CNYYÙâÅ‹á÷ÔÔT“ïIFFFmmíÒ¥K¿þúëÄÄÄeË–Ãó¶dÉ’qãÆõë×!gÆ W¯^…ØìÙ³á�쌌ŒÉ“'—””ìܹ³ÿþK—.=sæÌŽ;.\HÔÓÓ³W¯^sçÎÅI½zõÊÎΞ7oÞÎ;zUìÑÄ%ôØMtà%!éQE]]“É„ñÌøðª%%†ÂBNXXèþÓûüùŸ¤R)ð˜Ùlö•+\&S׫“fBˆDºvÍžÏç;88ØÙu‚y<O6ÛQ§cb¨­­«­­µí1¥›¸ÉC-khhènß½RRĺpõ÷"צÙF!W !B „ÍdÿY›a2x žF«aø0!DGÈyÂ`08rºoFÃâ° ®f“Øœ‘cîÄ1±†Œ¡±Ú?•X 1bÄ_[³ÙóæÍc±XS§NݳgL&KHHؼy3 ¢~ÌmÀ€nnn ÃÛÛû¹Ю\¹2uêÔE‹͘1_ÄjÄ]M*•677s¹ÜçŸ~üøñ‹/¦O,66ÖÑÑqݺuÐ^SSc^-S©TGŽ9uê$+~þùç´´´˜˜6›íèèØÞ·´OŸ>r';wîüé§Ÿšd$Z1Fwtt¼|ùrnn.`d2Ù¼yó–-[£P(pãšš6›ýí·ßnÚ´ H-Yss3VB‚‚‚FŒ¡P( a²áСC.!‹ŸÐ/9fœPòT8€:rhýMPÆ„·Œm7ÚK—øGް²²J‚*­V YЦ¦&½^äÃ``dgóíì>>ä³ÏÝܸǎ¹xyyiµZ­¯Rؽ{w©TZPP “9:;ûuë9TÕx³ì¦‡‡‡»ÖýZÓµúúúKG.éNé 2CÅ`iYÈ\à09˜g#}ˆî†NØC¨Qi8 ­VËâ²PóÁ`< DHÈm¢óÕq.pX„Ô ¨ <(ÖØ±u¬Ö!Ç\0ÆbTd¾“A2‹r8b±xíÚµF |ôÑG»dZÉa\‚,ƒÖÏмa¨] Çܸ\îÂ… ™Læ„ /^ìààpêÔ©úúz77·€€€Çù‹÷ÇÄÆÆ †òòò¦¦¦ëׯ?õÔS¸O­V+‘Hnß¾ýË/¿BºtéÒ³gϱcÇòx¼ÄÄDooï“'OÊår‘Heûæ›oÞ{ャ¬¬ÆÆÆ;wîdffBÜÜÜüýýÝÝÝ333KJJÜÜܪªªBCCßyç¾}û^½z5##£¤¤¤_¿~ݺuÃÁE^^^C‡7n܈#|}}Ûuxmmíµk×$ =—ïž>6»S§N-½Û³gO;;»ŒŒŒK—.………ÙÙÙåååA-çàÁƒ°ÍôéÓþùç×_ý…^>|xÏž=]]]AËgÈ!=zô˜8q¢Á`øå—_ðN8°²²2##£®® õë×'%%åääôîÝûÊ•+ ,,ÌÖÖÖÉÉéèÑ£!!!�ÂÛ5«FgK #j6&©ä}¡GêpïÞj&“/—7ܼÉmld¯_¿ÛH!ã$—3ÔjvSûÙgÝ££ÇS(µµµ*•ªk×®uuu………L&³S§N|>¿K—.<¯¼¼<??¿  àìÙ³ 4Ù?Ä$èt:N>‡q–¡ÕkYL‹ó§6¦Ëôz½ì3™ÍÓ6 Cþ½œÍvÖ:‹Åb¼"`Ü¡_v$ 2׺?EO T‹–*æ´šûvÓÐ{KŒª ÄH’^µjÕªU«è¶DT0Oô!Ÿ¨¼¼ãBz6RK§»¢‡…ß޲<==4Mqq1­»Å`0£¢¢ÜÜÜð’zôèÔ©þýûóx<GGÇ &TVVJ$’_|ѤÐý¸}ëþ÷¿ÿéõúèèè½{÷^¾|ÙÆÆ¦%RUU•‹‹KKëwƒaggÕ¹sgƒaoookk[SSSSScccÓ­[7&“þ /tíÚµ¬¬L¯×¿öÚkP:b0NNNƒ ‚»Êd2}|| äàààîî;a2™ãÆóöö.--e³Ù3gÎìÛ·/d5£¢¢&Nœ¨Óé*++;uê´téRüïÀ3`À€ÀÀ@&“Ù«W¯–rq`ÅÅÅ¡¡¡m)8Y¼Xûî»ïÆ×z©éÆÝ»w¿+u÷;|ê©§œœœnÞ¼igg·`Á‚€€€–žÉQ£F………UUU‰ÅâqãÆ?ÞêׯŸùŒ‹‹kll¬©© |çwÀÅøùù >|àÀð/>|øÌ™3{õêåæævóæM¡P8wî\šn~=zôx ù …X,¾zõê… è)Z­V(‚«EaTY†{B¼a0L&«sg««ÖË‹UWǨ¬dÃißÚÏB¡ÐÁÁÁÉÉÉÝݾGPÀ€‘hi(//—J¥ Ç?zôhqqqmm- -€ú4&ã|Ú�þk =ƒ]Èf³Ùz­žq‰¡‘kh& `l § çß«W¯   ,œ»»»#±?b"æF·Ë˜?ð4Å�± 7£‰ÚæµÂ:¤Cy<{C—+�ž˜Å’ ‘Ö­Á¶’lÀKÃí-â îaÆŒMMM¾¾¾€åjµúÆGŽaDDDdggËåòƒº£Ú‰'lmmÃÃÃóóó%‰Å>°sçÎÚÛÛwà¬î¡C‡&MšÔÜÜ|¯««ËËË#„ <¸õÜÚÑ£GGý ÁÐ㟶:zôè /¼@§õ«¯¯¿uëÖþýû“““Ñ"B0™Lè¡AGÍ+(܉Ûã*]<À�p©Q^öÉb±¼¼¼:uê$ ===µZ­‡‡GXX˜££c^^ž\.wttB¼D")//¯¬¬lllÔëõ ê­£:Ã,œh‰BŸ8Þu kv¸ÔLƒå9äÖ ÿŒ±pÐm:iÒ¤øøøÞ½{£¢ÄÁƒCBBLÆY™G94}À|1‡ÞŸÁ‰Ú<¸^a¦&¼‹Ü<‹‚&úÄ,BnØv¯Q>£ÜCnnniiitt´J¥²³³knnšÕ¿H}�Ÿ˜'¢òô˜›««ëÝù¯2d:!­P7ŒuÈÞàZÊé0|4Î� …€µlÊ`è2›ÍV*•¶¶¶>×&‰pp5Ä”MMM@U€Ÿp22™ R^vvv06›µ>áZ ÏQ‡Æ\z�� �IDATç D4¸i¸ðƒ€RØ+ ÑÑ#ê´$µ‰^žFbLdÑ’-Un�éÍpÞí©éÄf,‘ Ž-®æH€R@µ. wP ::ÃóÁ !ýH˜ŒBÀÓëõ­°Ìï³–óï±²²²6¦ƒžD»¿”Ú}W¼@D £F9ùâcŒdh`£¿õlE}Lb¤ö^¼xÑü]œ¸ƒ‚7Hrãp8� �úüù|þµkטL¦¿¿?´¿8;; ‚êêêÊÊʆ††ÊÊJ±XÜÜÜ >,N€Ÿèæ�ùè  žjÔìîEŠŽ Ñ( ¯Ç¦|>ßbÑ…n¦iå?~ß”†4“Y5ûxZ™gCï¡õ³miŽÅË1Ï×Ñçp×;`…œÖœrž—ú(rN¬BÂÂÂ\Dx�ŸN÷‡–€§ þ‡=+ HøàØP”Ÿ‘H$, }à³ØÜ£×ëïܹcgg|�!HËØØØ�q´ªªÊÞÞþöíÛ°4‘J¥˜¤ÂXŠVZÃÈ�§àŠõ€É7¼Fæ¦×ë!Lo á .=ªÇêýÚϬcÁÁc;þäaޤmW{ê©§ Fppp‡_ <æ¹5µ ó’iUfºµý±Y’ü}À% 2Ö�œlll�$ * •J h±‚N:UTT@Ç¢H$ …... …ÂÏχâˆÅb,áÀá@Dza|Kxø›i@³ã6úA® ¥Ø2éœ*2Ü“µ^u7Ìž Ó/ÚÙÙÁ–J¥GH´åé¢ÛK1±f~9æ¢80ÛS£ä9ÐwݱBŽ+))¹}ûv{ óýãæää4pàÀö>JAAÁcXWè&‰Z¡´ýãxîÊàŸ\.á¡[ÅD ‡ŸÞŸž±¯@0åðžðY{V«ÕR©û`Õjuyy9ŸÏwrr‚\–F£±··÷öö>æ÷ šÁ¹> …J4C—®7`/'¤ÎàŠpvðT*ʬá(íäû#þÞ7ä˜ËØØØàm$h£Œ!æ»0PkQFç]Û>`­-++äܳétºØØØŽ=¢­²²ÒÛÛû¾km7Fÿ€òcž³ª®®vwwl‘“f »Œ|0p1B¡j0§Œõ k &Æ^¬É#@�‘H$ ¥©©²²’Ëå:88‹¥R©\\\0ìppp0 nnnˆ£àÈdEÂé!‚¦fa°åååUVVF‹[#w€Á€š 8VáÖê­‰µ&ïÔIÒ'Nœ˜4iÒ£9–^¯ïÀŽÁ`ÈÎÎ60ñXŽEÁ¾,É`t‚þú<WÀ¹c‘À‰Î°ðx<Pµ³³ƒè¤®®*7°MEE…V«uqqqvvV©TR©´±±‚-ÔÀ”Jm`P¥V«áÜLÐó{8ú³ˆ´´À-=ê g" £>kñ¿LëUßu¡ Ýfk¾î³Ü¶¶¶ð.rÈn…Ðúž&¿Ð}3m¯`.•F_#ÍíÆ_à4,Îã±F9V³Ú¿Ý°Ããñ0ÃÓ—±†ùwÌV!Ù ]<zplx„B ŒÔDC66š››qþ´V«w[[[±XÌãñ„B!Ð `c;hÚ”Žc c�N€^ÀR+--… äâT*•ƒƒƒB¡�PD’4BŠ­ÁU´´Ð4ÑnÅÓ’3æx,fìñ’!IH¨Ê œaKÝ$ÛirÂæ×‚ HCïIØæØ†Û#äXij»Æˆ-"ÒÙ³gE"Qß¾}ccc ˜˜8mÚ´{¥9ÕÔÔÄÆÆâÄ­VlåÊ•"‘è‘Õ`û÷ïRÁ•••"‘hË–-í´>pà€H$úé§Ÿ®]»’­P(>üðÃ~ýú=ýôÓñññ ø©]»vÅÆÆÆÆÆöïß_$eee9s&88ù/]ºô믿ÂQQQ"‘è!I»W«®®‰D›6m‚?=*‰Z×4»«­­‹‹‹}ê©§¶mÛ†KÈšššAƒMž<Y,¿úê«ÑÑÑ‘‘‘Ë—/§§UWW÷ïß?66¶wïÞ{ö쩪ªŠ5šŸŸßœ9sJJJBBBpt[3š8€+}pè;è¶ô8â gç�$`#`­’H$MMM …B.—«T*ø”\.W*•ÍÍÍõõõååå UUU 2™ ¨Ò $ì/Á$ºlèû¸ ü#0ðÄPJN¥R ()#燙b—Nvh½—Åjí˜XÓétMMMkÖ¬™0aNy±··¯­­=qâDÿþýÝÜÜ:Ô½{÷•Juøðá   àààôôtè8p ½½ý¼yó ¬zèÐ!x ¢££ÝÜÜÊÊÊΜ9C±³³:t¨R©ljjzd‰¬ˆˆˆË—/?~ÜÆÆF$µÇ~þùçíÛ·C³ÛË/¿ìïïèСéÓ§Ož<9%%eíÚµÉÉÉC‡?þ¯¿þŠ£Û^yå•W^yE©T~øá‡ÇwqqINNž3gΜ9sÆ÷ÒK/åççàš¯¿þzÓ¦M&2ÒÒx<^ppp^^Þ;wìííOœ8áíííââòprðàÁÀÀÀ­[·nݺuéÒ¥±±±×®]Ûµk×íÛ·]]]wîÜyàÀüüü7nŒ7nÀ€8—è7ÞH$999}ôÑìÙ³‹‹‹³²²!ÙÙÙÓ¦MëÙ³gff&¨V? ß?’úw „.à 0cggשS§æææ¦¦&¹\¯ãØP\·b%M\øh^LZss³Îhð®D"Q«Õ0‹³¼¼ÜÎÎN¡Pp¹\¨ÊÈd2©TªR©èQ=ÄXZG‰x jBX3‡TŒ]T*�À òP[‹ ÃÄZ; :Ãðˆ¼1÷xô»&:7ƒ›‡²"Á{hNuûA§òLôÈïíp÷´µR©Üºuëwß}÷Ö[o•——'$$À°E‰D’°ÿþÔÔÔ7ß|³¢¢"%%eñâÅeee ‡Þµk×âÅ‹+**’““/^\YY™˜˜øý÷ßWTTÌ›7/--í ?ùä“… ®X±â£>Z»vísÏ=×úè£Þ~ûmøýõ×_¿uëÖŠ+ _ýuÜÆÆÆæ›o¾A¼A‹Å›7o3fLXXØÆcccW¬Xqýúuú³ï¿ÿ~¿~ý†þO¹3GGÇyóæíÛ·¯°°°¡¡aË–-cÇŽ}èÜ­iÓ¦}öÙg+V¬HOO7nh¬;v¬wïÞ­ƒ¶n6l³fÍŠÿæ›o`”K6À(]�] –óÇÙÙyÊ”)#FŒ�GŒ}‘PéÁ=¡ õà±ÖÁŽÕjµõõõUS«Õ …¸mÐy#‘Hºwï^VVvëÖ­âââ’’’ÒÒÒòòòšš…BЭ[7 9àþQÚ�3Hz½žÏç£ÊÎϦófð'ŠhÂb�B~°=î?�m3lø.ö ‘¿+;´ôÁy0ø|>ŸÏ§%‘àÐtŦþ”J%r¸2älذaÔ¨Qo¿ýöóÏ??xð`6›ýüóÏ8ðÈ‘#z½~åÊ•ßÿý©S§-Z1yòäÇ744455}úé§3g΄§œ²ÿ~.—;o޼͛7'$$ØÛÛÏ;wݺuóæÍknnÆaÀÌlllV­ZÕµk×Í›7'%%=ûì³íq”¤¤$zËéÓ§œœ† æááqúôixqÍš5£Fz÷ÝwÍ?þÆoôë×oâĉðg§N† æâ₟ýßÿþçàà˜˜øÏú²þýûOœ8qåʕӦM0`À‹/¾ØNÙ¡aÆÊd²‹/Ö××·"”׺¥¤¤äååmܸñßÊ€©_àyqNZ­Pill¼|ù²««kmm-dÛèé° &¯à #£ðíapâ …B*•â8�à(C±$??_,Cb­¶¶¶ººº¡¡A,£&‚D"¡Çc£Ž'^Æ.ØÚ‰Ëpİpj4@»7\B©•±Ö¾iÞÖßž3gΞ={ÒÓÓ·nÝ F,çp8œ~ýúÉåò‹/æåå…„„øúúnß¾=77wïÞ½QQQ·nÝ2E"QTTÇ»téÒÈ‘#cccïªÉÓ¦Õj:ô믿úûû/[¶¬ªªê¡bçÎ&((¨¼¼* ¹¹¹ „Œó+,XðÅ_lÙ²&Ò–ŸŸïââ‚I3—¨¨('''ülaa!—Ë¥õ¿ÿsvvNJJ‚F¿üÑd>éC„œ¨¨(??¿ââ⺺ºÄÄÄqãÆAÆR¡PÔ××ßÓÞnÝºÕØØø/QÛS(&Š)˜†‚žJ¥Z½zõ¹sç]ø|>`“É|æ™g€BM�6�NЧ‰I*ðï<O£Ñ@2iZ­V©TªÕj¥R)—ËÅbñíÛ·e2Ycccuu5ü¬¬¬„´þ¡È]&FÆÝìÙ³ápX[B¨0ÑÖĪ8æ‹ú¥R©pøæ_ó­ ¡‡´%]‰h‡†¯˜äÓL`ŒVî1¯h`6 ‹°{EG†™Ñ9ºVNÛ`ÉL®Âü­û©åàúÈÖÖ¶¥w###gÏž½xñb777˜µuîÜ¹ÆÆÆ”””Ù³gÏ›7’æ´…††.]ºtõêÕsæÌ±8H¦½íÛo¿]³fÍÚµkGŽ9kÖ¬—^ziË–--Í2¸?óññÉÎÎ^¿~=LlƒøÏübù|¾N§I˜Ã‡,eggãDK(f¸¸¸Ð›………555C† yL’6àƒ°‰úáÚ™3gÊÊÊ0÷Èb±ºté’””D®­ùÂE¥R8pÀ¢êAEEEQQQtt4FáÛyLûp²PGJR è½V«ýí·ß„B¡Muu5M¬o^ ɵ ØŒé ãx7ŠÖ` «Á`€".ž¡Á`�Œ …8«'ªmÙ²•¡M&xBc)ÆsjÃvºù®î\ŸÏ¢AK_¤à€¦äïÌEá+æ•!z$š¹5„wà@lllˆQhÎ?Ì•¤ñÄhpºfrb( m^’¡Y$­4¢âLU$¶>Š»MsW{úé§ÓÒÒjkkáϦ¦¦ÄÄıcÇ …ÂW_}n!äµ×^KLL\¾|ù©S§ÂÃÃcbb&L˜žž^YY9cÆŒŒŒŒvrU-Ù|æåË—‡††fdd<\ÈN!$'''++kÚ´iJ¥ò“O>Y¾|yAAÁìÙ³aFË·ß~{âĉ€€€aÆB–.]Ú£G¨¨(`ÐÍ™3övãÆ÷Þ{oĈ×®]›;w.!$--­¨¨èèÑ£ÿ§ÙÜÜüÎ;ïœ;w®  àÅ_ôööþòË/á­ˆˆ//¯÷Þ{oþüùëÖ­kjjЉ‰ –H$3gÎ\¼xñË/¿œ——·|ùòÜÜÜW_}ÕÖÖöøñãéééiiiø|vl£uÆh­~ JŒìXh¯AàŸ*jØ5 –¦Sœ200h€ß餶ò`HÁ""ð›*h-5zlI¬€^O(Êår„Í4LÁ™¬Ç!¤ƒí­Œµö}[z¸gô°÷%K–Ìœ9“߯_?hÎê©§üüü–/_Û<ûì³îîîfäÈ‘AAAB¡0==ÝÇÇÇËËËÃÃC«ÕŽ9288ØÁÁaõêÕ×®]#„„††bõû®ù°,%%£77778Év:ÞIÐm9rdxx8ŸÏ_¿~=&$$Àz|ÇŽж½bÅ ©TŠ;™5k Ç9r$Ll›:uêðáç¹råÊöc|ÅÅÅíÞ½[.—9ÒßßFDƒ}õÕWÀšûæ›o ãåååãã£ÑhÒÓÓ½½½»téB?“`àÀééé&+Œï¿ÿžÞm3d|7ß h (;;;¹\Ž ª“#‡™l:Ð=:ÄXå†L,a p¸\.Ìt§¯T*±“¹4¢ 64å Òwph8yœˆƒÍª MŒ#dèq;ôBžP3 pÄö™ZíQCŽÝ€èWpδ——$ˆd2Ùš5k Ö­[‡›EDDП€£Dsuuuuu5Ùæ‘}’<¯]O€¾“&Â;‰†³±ƒ‚‚L2œ&Ÿõõõõõõ}|ž¤‡#š[¯^½,¾ŽÃOMdX9Þ1“gÒÙÙÙü?Þ¯_¿œXƒxyˆc ,�!pÇÍ�¥ éjF ¯ÚÆÆF"‘`g´‚Ò‘ŽBÐëõ*• Q =;-- b606 ³g°Cp Bm2-Ûk0Ãâi&ÃÊ03{ÃSEÔ„“D„³X 4,N6{pÍi¹†E�“È£CR{+ ‹æ#×ܰtG›L&3 i^`<ü×Ú1±VZZZ[[»sçÎû&ªZÍjVko× R©0‹�nÜ :\(ç€z ÊûÓÜbx ÊÐ d€ºÎ8bÀ3 J°³IÕXæu�–Ѱ/(ÅÀ(ò &ð èaÕØâŠTi�]ÉKœMG˺X̵´4QÆj-ÊicÊè‹/¾è¨·æìÙ³x^ŽIA²]M©TæææZ¿lÿ”Ñ#/iœ \è^Kœ I6¤± v# …ºm 0eèìTÜPQ 'x&8ÿHt¨Ç‘kxV-4skàÀaƒ’‹‹K}}=vaS*’ë0C†ä¬ö8BNǶ‡Øâû¸Ù£œ*ÆãñåD¸Go9ó µmÐÃB{õ‘r¡ †X¹ÁÑ2€4½swÜ�8aœD/ Œá k@A,céæORb=3r à@9 b5wRjJ¥3uð =HyY4« y\æÉIHÑS;± dÎsÃP ™Ù§vÒÓé× ! P6ùû j,8ápÿ à è i7ZÑ€ÖÅšœ¿^¯‡CCÈ /bö5ÖðT‘z‡’rîÙ233;<ƒÖÑÑñÑTÑ~úé§<¼�ÌÇÇç±—ç1ó1áOggg ñƒCIôDÈ--¢´¼&äÍPž"ðYP×÷;'ˆÃ0HÂ8 }"r  ÑS­V …B`ÆCþ Ñ . eFQŠ SHM&ŸÖL²ˆ:Sjûcè¾¥yÏÕ©ñ|èXÓ|W­ä÷`$è͵,4}Ý–¶ë êû´¸¸¸Ž] *++‰D`^!$>>¾'+ Cee¥§§çc; ÛSø|¾R©äóùX‹Åè¤ÐÇ!Ïl’¦Ã·0UzB¦½a» -]Œ¬9FÃçó¡°„ä1Œ0ÜÁ$Ž©¦O > ),&á(Lú¡P¡Èô¼2«YkÔàkÙQ¯îÔ©Sí¤djqy®rrrrçy9˜›¢×˘SŸ‹ýç!tΊÉdºººj4š††Zß÷ щ@ �ŸŽx€Kcðò4öƒ˜„,Ì€¡"'‡°ðƒ3~”J%rhaJ¬'#;v…˜J ä °Ñ…¥7‹3ZÚŒN”a†M*•Âïû»ƒ»…:V[B“š<3mÌâZ!ÇjVûw¯+ÙlƒÁ`cc# º€#ph2,±@aŠ+àå¥R)ÎA0@—ÊãñP»b Ø¡££#Lå€Í w‡ìd“¾ø‰l­V i.Ð�]ø,œ(XÓbÕ°OZ(NõFqª)=¶‘ï!N¥!§¥üp3˜¦P(°)•Þí=íŠþà=Å|ô[²3ì999®®®ßÿ}‡üöìÙóå—_†ß+**\]]ÛIáÑ`0ìÙ³îdAAH$Šõ÷÷?vì˜T*]¾|yŸ>}üÌ3ÏTWWã§p^NDD„««ë/¿üòÛo¿uëÖ-66¶k×®gΜÁy9ƒ ruuýüóÏÿ©;yçÎWWWlÌ:|ø°«««¹ÐÑZyy9̼ Û°a®ûÊÊÊz÷î=vìØÚÚÚøøø¨¨¨¾}û.\¸P"‘àgKKK{öì cоþúëÊÊJœ—ãáá‘pçÎÂÂB‘HÎÏ�*”Je]]B¡€¹ŸX·‡„Ò˜1c<<<P¾“ÅK„B!D02™ $a�„ toooß©S'èøî�ì§Ñ455áŒNˆ<½†SPí†Îq!GçIûøø@¯.™ Þ0`ÂÝ"ÝÁ Tj�1*‚·à§E.€Õ¢1[Rõz}zzzuuuJJJJJJ}}=üRZZJ©¬¬„?™²²²~øá‡òòò”””ŠŠ ™L–b´Ç*µ2bĈÒÒÒ‚‚ð’^^^íTû=pàÀàNΘ1£gÏžYYY1113fÌ8þü矾bÅŠŒŒŒ€€�˜öÊ+¯dee¥§§ÇÅÅõìÙÓÓÓóرcË–-ËÊÊêÓ§ÏŒ3bbb²²²²²²&NœØ¥K—önÃlÅÁàÁƒóòòàß••Ö¹sç‡{”ß~ûmРAYYY³gÏ~ÿý÷áñ»|ùòöíÛu:ÝîÝ»?žššºfÍš;wÒ3âÞ~ûmN—••õòË/'&&r8¸uË—/wttŒŠŠÊÍÍýꫯäryGMâ#Ý‹Åb^'ø}ìµÔétõõõð:¼›Èͽ{÷ü€‚ ƒÁèÔ©Sß¾}y<‹2ÝÔ K‰‘z�Ûû4± ^'ÆÉl6»¬¬¬®®Ž†BŒ•ƒöØ!dÕ8èþcÇ%NݘyCœÃ¼SKµäUªn®•i"ე¼–‚§V>hÑZ_ÝÒãZÊ¡1ÍÌâAÛòA4BiƒÞ=æ¾ë|ðA\\œŸŸ_JJÊÉ“'###333ú駤¤¤ÄÄDN÷ì³Ï¾ûî»b±øÿٻëÿÿ¾ Ǩ(n¬¬pæµÔ´02£!‰A¢¦æWSpœ)ejI|Ë­eiÑÛRs&*D' в»ãöïW<¯45Vv¯?xwŸñ¯÷k??¿qãÆ…‡‡÷Ýw»wï^·nÝöíÛ###ÿ÷¿ÿ¥¥¥Íš5«šÂY³fM›6môèÑÛ·oÿüóÏ»wï^/Z°`Á‡~¸}ûv!DTTÔÌ™3£££“’’¢¢¢p‹‹ ºjr(((øê«¯&MšôøãÏ™3çÌ™3ÑÑÑ©©©¼[Á'Ÿ|Ò³gO*æV%àááñî»ï†…… 0à±Ç[ºtiLLŒ]é„¿ýû÷ ŽŽNII «]»6É7­Zµ¢Þ9_|ñ…““Sdd¤â•W^Ù¸qã£*W¢¿'2ÿyõeþ+oV†*g dHÐu¾téRjj*Qpº— Ñz8Qè{^Ê uÞˆy òÌh...ýû÷ÿõ×_¯\¹‚(�{(Oxȱ%777*”€4 z2÷mðˆ ¨}w³OŠ’jl‚•6(ÝT²ˆI‹»ÄÙUYå7R ÝT¸’w7›Xé2£(ë`Ç]ì.ãÞ&;öÉí/uÄ¿V!ÍfsRRRddd“&M¶oßÙ®]»={öÆ &,\¸022R&“íÚµëäÉ“ééé¡¡¡Ô°R±yóf??¿ÈÈÈúõëoÚ´©úBµZóä“O._¾üË/¿¬ ~3oÞ¼ &àß­[·Ö©S'<<¼Q£F[·nóëÞ½ûøñãKß>lذÀÀÀˆˆú·AƒáááuëÖŽcÇŽõôôœ:ujÕ.& rÒ¤Io½õV—.]ú÷ï_o‘ÉdáááíÚµ;xð`aaá©S§²³³zã–.]š˜˜˜ðo0eP³Kxh¨p�²m)@Ä 4pí zMRRé7t/ñ$žÂkÞ  ½DE‰3Ÿï/6J‘Ít1õ;HJJÊÌÌ$›ÝN ìxd'%%:KŒA§Óá¼éŽD"qvv¶su ðVe†µ¿„ãÇSGúÛ·oãK…BѤIü»ÿþnÝºåææ–YF¾ªÀd2}ýõ×»ví 6lØ•+WÊýK–,±Z­>>>T½4==ýÔ©S®®®­[·®Q£Fjj*]6mÚ´ï¿ÿþ«¯¾úàƒìžššêááAåS…žžž­[·vwwǽiii …¢ÒÏî¡è,\¸°I“&›6mª àr‰DÒºuk__ßk׮忿Ž5ªOŸ>×®]3 EEEÚñ(33S£ÑTy«¡JƒââbدÈAB"?¼T½p¸SÝ`0€C@Î¥j4°•A§&l$§’±K­Vûûû»¹¹+¢Àe*ÉE$ÞÝÝ$¹\îééIL…t³Ùœ˜˜HÕ½x,�q)´Ì@1úºÆ¾k2™ôz=ŠíCã¹G\Y™¦°{w¬á¿Þn“Üîaøzˆð»¡r¸‡ñ°²YŽF£7n\ÿþý÷ìÙC†N÷Ë/¿àß.]ºìÙ³gÒ¤I¥-W!¬X±"!!aÁ‚{öìyá… @~r„–-[fee­\¹rÛ¶mÄz î¶ß¢$|eýúõ»wïBТηß~kç“?vìØÍ›W¾›m�� �IDAT7©ÿÂ#X½z57´nÝzåÊ•+W®,,,¼yóæñãÇKÙ+V$%%•~¹ñ^xádV?ÚÀ;åðØ4Œá Ê`Ý"J +´":To ¦‰åÀ’Ô¸qã%K–¼üòËx/q8z¸B¡hÞ¼9vhTêÃã©ìܸ‡È4$ëPÀ4näqáh±lWW"]ƺ{¹"ärÅŸ¡Ì-ü ÇØ}z M%@+V&”6Ž !T*•Z­V«Õçñ·P’“¬À»ò<ØëþŽmê½÷ÞÛµkWNNÎÀ—.]Ú¦M›V­ZÍŸ?ŸÊï !ÆŒ?zôè]»vMœ8±úÂO?ý´uëÖÔ¢&::úÉ'ŸÜ½{wùÖ€éܹsçÎ…¿ÿþûÖ­[û÷ïÿöÛo“éĉcÆŒiÞ¼yïÞ½W¬X±cÇŽ–-[ó˜5kÖc=Ö£G¥K— ! DO+((ˆíÖ­Ûùóçi%þùç´´´èèèÑ”H$óæÍ;~üxJJÊÛo¿Ý ADîß¿¿~ýúsæÌ9rä¬Y³4MÏž=Ÿzê)F5~üøÁƒÿ÷¿ÿ=zôÉ“'‡êææöûï¿ïÞ½û‡~�¢>Ú€œ‚%üÃk R6ÃkþsrÏ#ŒIóàu ‘Œ)„ÈÊÊš?þ©S§àcà­m6[bb"¢¥m6ì °z!F3ú‰Y‹LJø(ÊcsX,]@!ÔŽæ we9­ZµÚ·o_ƒ h;§M›FNï°°°nݺ5jÔhÒ¤I„"Í›7þùçkÕªÕ·oßâââk×®-Y²D1pà@*©2pàÀjUäÇtvv¦ÏuêÔÙ·oìWåXIò«8Ðßß_¥RÍŸ?Ÿ,Bnnn7B¬[·ŽÊ€Ï;—g³—^É¡C‡¾öÚkÕ§_ÎG}Tq=Å;uêôÃ?Ðói%ñÓ×_M¶Ü+VY»vmjδoß¾:uêÔ©SçÇ$ƒOãÆœœºté²oß>ZpÀÖ­[Éþóè5@e~^©Œ3b0J¥ÒÓÓ“Vîßxà2 áG>?¢ d2™V«Ý¾};… 'ìW†F·"5ô>~ÒEx½„kÃ�fFñÓTþ�·Óe舃9¼¶Biÿƒj“Žòð,ÇÅÅ…¤~ô­B³ZµjQ˜R©„fðÔSO­^½:&&æË/¿¼téR½zõÜÝÝ Ee–¼àQÅ=H¬¤(UL+Yz`všÒƒ¬[·n¹Ç"ÿ°£àåvíp�ðÇØu’ËåX1» rÒ;^m+¤ý}¨Q£Fýúõ/_¾ “”(©³‰¢ËÈŒ!~%>¤×ë©ä §ÑÜÚF~”bC¦ ySˆ[øøø\¾|ÁTȧ¯%!ÑÄÝ Ï?2CEI²‘(i'­ˆz4Г]\\È‚GƒG€�)4ˆ¦n‹E§Ó999Ý»Æï÷\šÙðjÜ¥íW÷˜Àë–$ã©Kô%JA–Ù¨F{üZÚ(‡2v!ìôÖÈÒásWh¿<«„‡‡›Íæ;w !,X@],à�T-dgg?þøãÄr àÃܺƒfpÂCo G= E‹w ]LÊÕÕU.—ççç ô2  y}ÒÓÓyéêà‰ˆ5Ò¨ |€œ¡¹/Z »ú/@µ"’¦äk·€ŠƒÚ64M†àPVªFËy8 ,‡GŽ9âè—S.P\\|èСGu%«?…’Ëå¿üò dT»A2 29x©Åäää„2${"Ö™nÏËËC‰3ؾèzâ:<7li.à%CŠÛ"6EÐÉÙð2Ø<U¨tÑhü Ç3FŒáÃr°Z­mÚ´y„kʶoß¾Òf§P(ìZA?bpŠ÷Õ™Ió@ YÒ Àf ¸ð:4t;™ÚP)€.㤽Ž"º—ÞèääD¼B¨áU"^HÎ!ooï[·n!Fª 8�—¢) Í®eúœR4-®äAÕÄ#ù5± ÐKʪøÀHG¼G>¬ƒåTìÛ·ï‘ õððèØ±c%¼èçŸ~ä%dž VaÙ¡ûQt}B-â HÐ!ƀ—t1Ñt$¯ð°7Q9#œ4tKþ´~Q*•F£‘(¬XÐxˆÖ«Tª‘#GΘ1i¨B1„œƒwss£Ô$\;z½Ë4Š€ )ÀvëfCÒRåhÃÕDLáÃÀÎ:´œÊ†nݺթSç¶ê^½zµY³f•Ó/§:ö/HOOoذaµí—#JJ5ó gÒoë6M„ž'~R©f´ãä Ê3£M�®AQ5´\CÞ(ÌkÜÒEn$R‰fΜ‰Ò;4*•JEEkx·JPE6üåqıgƒ"l´ ”J³FwmÝq@Ë©x´ûå$&&6kÖ¬2 ;êJÚl¶ãÇ#ž³zòžn‚h`Ð3xãK”*€‰ Ì(‘‰àcî¡Á5(¯)JâÊPe@¡P!E† nr¹\§ÓñîÎ6›­  �ŸÁxxßhlèŒ@SF¿5Üëåå¥ÑhhHbåœéá Þ”®Ø_fr>ï{Ú¥Ÿÿ1ϗ¬qKé{ïV‹“u?=Žyλ=êÞÓ¼ŸÕ“߃Lðd]B”ò= XzªSûO°K©ˆA–×™7™L*•ÊQ°R©”p‚jI‰’j€ØÞ„¼B„ÇûlÂMä*·@ ìV¸ôêQŸ  Ët1¥C=’@®u2Áoo0”J%r!©0 Šž¡Á (^ƒ�•1q/¬ FЗ¤Ž ó&•Ã!}B"‘tèÐáØ±c¨óF)ú¢$›W<óCã8ÄØÅRãz\d Q!œ‰&K¶yß±œÒt¶ôsÀ9ýS¦D r_f7{0€Ò‹ºOCŸHéç—Ù¯ºÌ‡ü6ÞC ®[·n—.]BBBBBB–/_^¾Ç ;;{èСÏ?ÿ|PPÐ[o½uëÖ­}‚Éd )>}úÔ­[wÆŒÕí´[­Ö#GŽL™2¥nݺTl PPP0a„gŸ}¶wïÞ½zõº~ýú… Ú´iÒ¡C‡E‹iµÚE‹uèÐ!$$¤M›6.\¨èÑ^¼x±}ûö=zô î� ï¼óN@@@Õ®ðÁƒ[¶lÒªU«-[¶pôX¼xqûöíCBBRSS¯_¿þòË/¿üòËÏ=÷ÜØ±c ¶lÙÒªU«–-[<xðf9ÄT(’d^¥RIÚÔêA�ºOL¥hDIPÈ%¯3B8¼+(Štý¥ŸHJJBÓÒ3(Þ ¬p¢$üŒ”3r{#–Iú)d<ÊVDôÒæÍx;QÒ‡ˆÈbMP5†µ±cdž†† !N:õÅ_¼ñÆßÿ}ëÖ­ /]º$„hÓ¦Í3Ï<óÃ?´oßž<]#„nذá•+W¨t¿»»;¯1œ‘‘Q§N©S§šL¦gžyfÆ Æ { ¡+ *_&„XµjÕ7wïÞM”½uëÖ;v,..³ ÏÍÍÍÊÊÊÎξzõj£FjÖ¬yìØ1777´k«–³iÓ¦äääÒ?:ujÙ²eË—/î¹ç(yþÂ… &“iÛ¶móæÍ›9sf×®]gΜ9iÒ¤ñãÇ·hÑböìÙ¼ÎXEÀ'Ÿ|Ò©S'½^OeF×®]ëêêêëë{äÈ‘þýû»»»Ÿ8qâ÷ß§-æAh‰‰‰ÇŽB4iÒäÅ_¬L 5jÔÓO?½qãÆÈÈÈ÷ßEçòóó§M›6~üøI“&=öØc3gÎ|òÉ'/\¸ðûᅦ‡‡¿òÊ+ï¿ÿþsÏ=·|ùò>}úŒ5Цðèi *• ~ÐbL“a7Œ+©ú'tîóGP±ræ#ZšXi“J¥’žc6›I‰§(Té§‹í\5Pn V£¬W¹¨n)"Ð(Ê�¬Ž.&Þ#JQÁÛèF^6ôA-«÷£[‹ÏÓ}ZðxO„ûW&H"9Ô΂‡Þw»±üYàÀS§NݳgÏ®]»Z¶l©Õj‡ vûöí¨¨¨Å‹ÇÆÆ¾ð ñññ'NœèÙ³ç¦M›¶mÛöÙgŸ9²V­Z½zõЉ‰Ñjµh¼øôÓO?ýôÓóçÏ?vìØ3Ï<ƒú•Ë–-‹ýòË/Ífó˜1cÞ}÷ÝÜÜܨ¨¨Ï?ÿüÛo¿=tèШQ£Μ92cÆŒþýûËåò±cÇFDD4nÜxÚ´iEEEÊðîw}åò¹sç&$$T!ú×_=räȺuëîܹ3f̘>}úÌŸ?_£Ñ¼óÎ;¿þúëÉ“'G5zôèN:M:uݺuh¸pêÔ©Ñ£G?ÿüóõêÕ3fŒÕjíÕ«—Cš«>`Šˆ0têd–ɬDòHk‘HlV«HdR©Õf% wÆõ1•( d¹—!‘J<+ôœ’[,‹I¡ >a”HþP€¤Ra³)·T*•”X™$R©¥Ä™„þ=\Aùÿd¢³Ì˜ƒä!«Í&“J-V«@¼DòÇm6 › wSã¥Á‰D°þfž¾âA²ÖÊd ÷°˜åÜ'Û(ÍÒî§ßó±¤÷–vJÝ›å<çû –›ðôÓO7oÞ\‘””ôûï¿“Å¿Aƒ‡Z¸paFF†Á`¸xñâܹs7lØpàÀ¯¾úêÒ¥KóæÍËËË;xðà„ ‚ƒƒ'Nœxøða»^¿¡¡¡O>ùä»ï¾{üøqzŃ·ß~;sæÌ¥K—vëÖmñâÅééé½zõÊÈȈ‹‹»~ýú®]»š6mÚ·oßÍ›7ïÞ½;$$$%%¥qãÆ­[·ž0a‚D"éÛ·ïÔ©S<XA,ç.\¸víš^¯/..NMMMOOBøùù 2$--m×®]¡¡¡gΜ?~|ݺu×­[‡333SRR&NœØ²eËI“&;wÎÁrª—)cÇÉúõ2¹UMx#NPyŠc­ù#Ÿ_&“¡d)¢z½1ÈÛàO«U¥R™M¦?ª¢Y­Ö’87!‘(„–dž’za4U*•Mâ[F“‰.0[,R‰Äl±‚ŸÆb±Èär‰i&“Éä …Ñ`Bà!B"Q)•d\µP;TÆuˆMZKµ‘U LH*•*_xAtêä@›ª1¬Mš4‰ k‹/Blß¾½iÓ¦cÆŒ!ÚtŸ\áÀ?þxéö$¾¾¾:®°°0??ÿ!F_XX˜””äããóïi|RAPXXxåÊ•-ZL™2EѸqãÔÔT½^ïììLõä9”õá‡Ö¨Q£S§N¾¾¾Žõ¬V »sÇ=#)¼Ë§Õj•–¸Ü©Îÿwí´Z%B(U*±Mf³L&“Éå”x‰²ö@OËåÄÁd‰œÜ'V«œŒHBÀe±Xlf³P(lB8—T€þÀV"ÑË,©T*±ZëׯŸ——WXXø‡ ^Â{Œ¤xI$V™L!‘ü‘p*‘[èbÒ‹Œlq%æ5ÔΑ!•É„Õ*•É”,NÚf³Éîâž´“èí ÜCG¹‡)¬ô<äÁ®ôªxðTžÒeÂË´Ñ•nNÊUI»Ÿî=˜¿Ô{&¾ëûï¿?pàÀÉ“'/]ºôúë¯ÿåõÑÑÑK–,áÄ(--mçÎ'cÃb±|ðÁGýßÿþ× Aƒ عsçµkת›<wîÜ—_~™� ƒš–H½~ýúÒ_Θ1ã?ÿùÏÊ•+›6mZµs9~üø‘#G^zé%³!èÔ©õ/àÕÉDIè#Tä¬v'/oòÇÉ œóh`é$ÞhWD}x[;ƒS4Nìà%…ƒ‡^�6ÞûG”Š0ÆKÑ*³~úé§K¯a­Zµ†ÊG³Ò½ k¼C³9.“dßÃAƒ’ïÇ¢…¡ôœ(+”ŽÇFßc"°°ñ‰ßcüw3ý= Ë úùçŸ'Nœèç矛›[æ•^^^ÇÿñÇSRR>¼lÙ2üäääôÛo¿íÚµK¥RuìØ±G: ³ÙüÕW_5kÖìóÏ?§o7nÜ¡C‡)S¦èõú   víÚM:uêÔ©ƒNJJªò†Í€uëÖíÚµ+11ñ7ÞHHHøñÇŸxâ‰×^{­°°ðøñãƒ>wî܈#üüüFŒ±qãÆ .ÈåòáÇWí°Ÿxâ ÚîÞ½{óïz÷î½páÂ+Vܺuëï¸å¦N:a„Áƒ;vŒ¶xß¾}³gÏ 5jÔæÍ›)ÎeĈžžžÛ¶m‹ŽŽÎÉÉ yâ‰'¦N7xðàóçÏôÑG*ËiѢſ¤]yAff¦](¦««k'‡µíAàäÉ“îîîe¨AÔL^§ÓmÞ¼™“’ââ⌌ŒÚµkS‘üüüœœœ† ·ÌÊÊ***R«ÕNNNÄoÔjuݺuoݺe0üüürssóòò5jT\\LÐ …ÂÎ “““Cö4777ÞWôþuÆË—/óo<==ÍfsQQ}ööö¶X,W¯^¥_ýüüŒFãÍ›7}||T*Õµk×¼¼¼jÔ¨qõêU'''Þ/çøñã-Z´pww/¯TЂ‚‚ììì P¾KVV–N§kܸ1­*VOqíÚ5’&|||\\\´Z-­ž\.·+Îÿ7áçŸîׯª”¹ÝBggçzõêeeeéõz__ßÌÌL½^ïîîþøã?>22’o·ÂÅÅÅ®óÐŽ;^y啊KµZ­èëEø™———››‹íæ«wóæMNGÂP5L&¹¬H^y¸›Í¶cÇŽjX} 777==½}ûöv 1ð—àææF”D±}ûö7Þx£rJu<J@îŒF£›››F£Ù±cÇèÑ£ïªå899q ‰§§§§§'þ¥ÎWô uˆPB¿ñòò"t7K‹·····÷CÏG"‘”ùd Œ”;~\.Ç¿ø`×™¦"ÀÃÃwÃíVU”júrÕ+_øËíB$%% 8°_¿~=ö˜———ŸŸ_éí®|J¥vKT£F ÂI¾Ýv† E•›+h_ȱ᠀à7d×)**r¬áƒB™-|¤ŽuqÀ}BëÖ­.\¨Õj;6kÖ¬°°0Çš8Àx pÔX»+8p L.ýè q÷Ï>ûì³Ï>û wéõúß~ûÍQp€,§  (Î;?Úý+gvÔ¸k×®6Â8Nà`9 ¬òÈ÷£}8EçA¡{÷îpi‹ÅR;8ÀÕ‘åH$’G¸˜®à�8 ±›Í¶{÷nÇŠ8Àp€Ê\]]‘çô'ÃZëÖ­«$EΫ6 ‘÷L¬VPmf(Îø¯E¡{¬ŒÕj­žÑ(Ô©.]5ßÓê|BíJETù`ÜÜÜP×àO,ÇÝÝÝÅÅå!šý0›Íyyy...®®®¢ê<(………TÙÐÕÕµ’WàÞ Ñh,‹J¥rss»GU×*‡œœggg¥Réìì\É h0ŠŠŠœœœÜÝÝ«ÕÞäååÉåò¬¬¬C‡•™]µP³fÍÖ­[«Õj»ŠËUYYY®®®Õp`v Õj©8©»»{u8¡ùùùÔò±ò‰yi ¦®...H¤µ0™L•ì-((8}út—.]De9´Ë„S§NùøøøúúZ,탔.¯„ÕªU«aÆf³¹Z Ì8йsgªF|Ÿõ^Ë nÞ¼™™™Ù¶m[›ÍV —èðáí[·B4jÔ¨mÛ¶ÕMÅqqq¡s§Óé´ULÅÅbùí·ß¨Pž^¯¯†’ %%E¥R5kÖ¬šŽÄÄÄ–-[ÖªU«ò‰yi8vìXÓ¦My^¹#Ôp€PIà`9p€à€J‚‡ÏËÙ¿?´¶Ž;9r¤I“&eÖº¯ÈËËKLL|ê©§.^¼èääÔ®]»S§NåæævëÖ­r°sçN__ßǼÊ7õèÑ£ùùùõêÕkÕªUõD;F£×ëkÕªçíÛ·Éã8“±Ýf³900°: æØ±cÅÅÅ;w®Î+ödåÀ•+WÒÒÒºtéâìì\æwîÜIJJjÓ¦Mé¾Y•ªålܸqÈ!'JàÎ;¡¡¡e¶Q©4HII =xðàÙ³gÓÒÒ„ ,4hP¥ àĉׯ_¯rúå—_ tôèÑk×®U[DOOO?zô(÷ ççç;²)¦M›6nܸj2˜Ù³g=ºš¯XZZÚÙ³g˜#„Ø´iShhèíÛ·ïÁžCCC“’’ªRËÙ¼yóĉsrrl6Ûc=öÝwß½úê«øuøðáTÇ~„ wé¯÷wàâÅ‹111B…B±jÕ*!ÄâÅ‹ß}÷]ºàüùó5kÖܼyó‘#GŠŠŠbcc'MšT¾cØ·o_BBÂìÙ³›5k¶gÏž/¿ürΜ9äçBLœ8‘Èý°aÃ#""zõê1vìXww÷iÓ¦}öÙg'Ož\ºti¹/ÎþýûÇŒsãÆüü|WW×~ýúÍž={úôéÏ=÷œL&£¼«=z 4hÊ”)‘‘‘´’sæÌ¡f Ã‡ïҥ˹sçfÍš%„P«Õ1H€^¯OIIñóó«]»vaa¡R©¼zõê;wüñ”””FÑz–/äääŒ1‚>×®]{áÂ…ß|óÍæÍ›…#GŽB 0€*&̘1C­VoÙ²E¥RíܹÓÏÏïÅ_üòË/…k×®­ eùè£Nž<)„ }õÕWoß¾=jÔ(úiéÒ¥jµzÍš5[¶lBtîÜù¿ÿý/n\¾|ùÎ;…ݺu³ëø^޶ômJHHðððøî»ï6lØ@¦ŒSa7È3fètºàà`œò؈#4hмyóõëןíI߇……]¾|9;;»ò)„8yòäG}4vìØ&Mš >üÍ7ß|íµ×†êïï{úôi!DXXXïÞ½oݺE7®X±¢âšõë×ïÕW_ -((6l}khõë×ß°aÃW_}EÆ•¤åtïÞ= ÀÅÅeذa—/_Þ¾};"”†¾gÏž¸¸¸&Mš¼öÚkÔs¥Áb±¼øâ‹ÞÞÞqqq©©©ýû÷_µjÕœ9sÞyçÈVû÷ï?zô(d¹ïPnnîo¿ývéÒ%“É”œœ|øða½^¿}ûö³gÏÆÄĬ\¹2..®}ûöï¼óNjjjbbâ±cÇôz= L«ÕþþûïDSÊÚµk÷ÜsÏ !¢££322¶oßþâ‹/&%%ýïÿ‹ï½÷<mÚ´ï¿ÿ~ÿþýãÇ‹‹svv~ùå—ãââÚ´ižœœüòË/×­[7...)))22²âXιsçjÖ¬yâĉ‚‚‚¬¬¬ÂÂBF“•••ššêååuâĉŠèPâéé7{öìììì³gÏnß¾}üøñ¡¡¡£Gž;wîòåË#""’““ãââj×®ýÒK/åääÌš5Ë`0ÄÅÅ­\¹rË–-qqq7nÜxã7*bM>û쳸¸¸÷Þ{ïõ×_Ÿ;wî±cÇ‚ƒƒ…qqq2™lÈ!¿þúë‚  0räÈ9sæÔ%„øé§Ÿ¦N9tèÐ3f|÷Ýw1¼Þ½{Ƹ¸8''§ÁƒïÚµk̘1o¼ñƘ1c>üðÃ%K–Ðe[¶l™8qbXXyäÈ‘åË—6ìÔ©SÖµoß¾¸¸¸)S¦œ:u*((ˆ©Óé^yå ò½÷ÞÛ¾}ûåË—=ºÿþ2¹zõê={öx{{¿øâ‹&WXXxðàÁÔÔTN·}ûö‹/æææîÝ»÷êÕ« ,X°`ÁŒ3^}õÕÙ³gŸ8q⥗^2|ð¢‚d‚èèhÚÄ]»v½òÊ+:...Îh4òj{öìY´hQ~~¾F£éÓ§O¥Ö\\\œœœ$ ï”óˆÁ`HJJºuëV^^^EÄ\æææ’yQ¯×çääèt:½^_¿~ý Üç ÿ>„„„„……½õÖ[gÏž6mÚôéÓŸxâ  ”ÑhLJJº~ýzAAT*ýúë¯W¯^½iÓ&H+[¶lY·n]E Ž³³³Z­B ‘¿¿rròñãÇW­Z¥ÕjÏŸ?¯Óé¨M™F£ñññqvvÎÍÍõññqss+((0›Í¹¹¹·oߦ¾[¿×r6mÚPGz;<¡ïM&SEdcÈd2Ÿµk×J$’ 6kµZ//¯š5këtºÜÜ\ºF­VÓôõz½\.÷ññ1™L&“ÉÇÇG.——»8EP·nÝîÝ»¿÷Þ{...k×®m×®]NNµ\³fÍš5kºwï¾fͫ՚’’¢×ëi+i:.55õüùóüûr×U*•ÏòåËׯ_o0´Zm5jÕªE+I—ñUÅ`œG’’Rf§ç¿îîî³gÏNII‘ÉdùùùIII………¹¹¹$©§€2Ù¤I“3fС¨ˆA>ûì³#FŒøïÿ{çÎúfذaJ¥rÑ¢EÆh4Ö®];44ôèÑ£mÚ´iÓ¦Mnnn\\\DDo©\îðå—_Ö¨QC«Õ †Ü@x…�� �IDATÜܤ¤$ôitéÒeèС*•êï ù—õ$Á¿eË–“'Ovqq© ¼ONN¯_¿~aaa•Ø@_|ñÅ­[·._¾< €².8$''׫Woòäɵk×®Úf‚³fÍ’J¥'OžŒŠŠ*=λAvvvrròÀí¹>ššzèС‰'>´q âà7Þxã7bccúté²páB» RRRFíïïO²…\ºt©~ýú“'O¾ÿ½®4hРÁСC+îùP=5MrròK/½D]nÿ¡°dÉ’sçÎEEE………}ðÁ܈Z¡@«T¼üƒ¤]]]Çççç—˜˜XA>Z·n=nܸ¬¬¬sçÎÑ7ƒaÆŒe^|êÔ©Š0»÷èÑ£^½z«V­zê©§ì\V‰dܸqO=õTbb¢N§ó÷÷0`ÀçŸ>vìØ¾}û®ZµjÔ¨Qví)+NŸ>}òäɈˆˆˆˆˆû4Ð7îÆ©©©7ª*qáfgg:´qãÆ$kÿMX·n]ß¾}8vìØýû÷£Ç6I£F:wî\bbâ[o½UfhÌÛo¿ýæ›o&&&Bˆ® ˆ…S§B³fÍÆg6›É5B0qâÄj"U´k×î£>Z·nÕjMJJŠå>|¸oß¾ÉÉÉ عsç¢E‹üqXP+š4i2nÜ8›ÍvêÔ)þýÑ£Gúé§¿ùð‡Ôr¼¼¼êÕ«'„pssóõõU(¾¾¾îîî ¯¾új·nÝt:]LLL¹‹2™lãÆcÆŒéÖ­›V«Ý¹s§J¥ºpáBttô„ ¢¢¢œëÔ©Cnç… ¾ùæ›Ë—/Ÿ3gNElÌúõë D–V!„¯¯¯§§gTTTzzz·nÝŠ‹‹‡^¯^=¹\Þ¶mÛÝ»w·mÛ677W§ÓuèСLµ\ÀÓÓÓ××W"‘¨Õj___¥R)„èÛ·ïùóçGŽéïï?þü/¾ø¢¸¸¸AƒBˆ5jÔ¯_Ÿd___77·õë×Ož<ùàÁƒF£qëÖ­1Hj¢S¿~ý3gδjÕÊÓÓÓÙÙY¡PH$ Ö”ËåÎÎÎQ$Êd2åää?~ü7Þ¨[·îòåËÇŽ;yòd©T1pàÀþýû‚ýøã...¾¾¾$îÑ‹?7;/_Þ¹sghh¨Édš>}zçÎ7mÚ4`À€nݺlܸ±víÚQQQ&LhÔ¨ÑâÅ‹-Zd05jôÚk¯‘D,„ ¤rå7nìׯ_·nÝ ×­[çëë;a„iÓ¦Éd²þýû¿ûî»gΜ1›Í/¿ü2 R*•FFF¾óÎ;‡º[n¹€¢xï6ȹsçnß¾]Q«V­{’QÅô–-[ž={¶gÏž.\prr¢�÷èèèË—/‡„„Æ~ýúùûûGEE 4hÆ z½þ矮ˆÁ—ÉdNNN¾¾¾ÎÎÎ6lèÛ·/­ÞÚµk333}}}©É@@@À7®\¹B#’víÚ<xP§ÓmÞ¼ùÕW_U*•UUðÆÕÕµ Þœ8q‚ Þ8;;W«¢)IIIT𦺠ÌvïÞݹsg777™LVUoÜÜܪ֌Y&ìÛ·¯uëÖZ­–Y­Æ†‚7jµº¸¸¸Z¼Ù±cÇK/½¤V« ÃßñäߺuëØ±cÏ<óŒN§ ˜1c¬ûû€‚7(TµpèÐ!*xS¾Ä¼E‹Ï<óÌêÕ«è®#GŽ4mÚ´I“&fÇŽ£Gv´hs€ð(ƒF£IHHذaC5{ì±j’3û¯Ëq€ð(CóæÍ.\H©rï¼óNµ-ÉQÍaéÒ¥¼:§ƒå8Àp@ÙдiÓ¦M›:Öáï@yy奕Ð7nTæLxAzzzUY“ |||„Z­öêÕ«Õg§ (B§ÓU«Ù¬ÆyyyYYY•ùêüü|ú`±XªáÁ'•J EµÐÈÈÈ š Õ8ÈÈȨdïàAnn. Wôƒ;³ò‰ù=S6Ë¡v#•ï€mÔ¨‘Âh4j4šªb95kÖtww·Ùl:®Z¹ ½½½=<<ªáÀJo¢\.§–!•<NÊÜB †j¸D 4P©TR©T.—WÃÖ®F£Qa2™ŠŠŠªeoÙ²% L£ÑTg–ãáááíím³Ùôz}u@¿zõê©Õêª"ævàããc—Üó§ˆ5^ÞÀp€à€¿JZFÄZvvöÞ½{+®x\9Z(¨j;ÔZ,2 ºººVÿíeê¼ÎÎÎrù¿×¥g2™H‚®r\ªˆIyxxTŸ¸ç …¢¢"›Í–œœœ––öˆá³T*ýÏþS³fMWW׊۰7¬ùúúvìØ±šOC¥RÙl6£ÑhµZ«6>77÷üùó‰¤:[½JƒÍfÛºukpp°D"ÑétÕ¹Ño…ÂÕ«W5Í“O>i³ÙþY;x¸pá‚Ífó÷÷·Z­Ì¤î d¤±X,íÚµ£çGœ©Þ Ùl® Òy”—Ãk8º‚:Àp€*Kis,à�8 º³‹ÅrñâÅœœœ›7oòâƒÕ®^½š™™éØòGnݺõÀÃ…+W®Üºu«^dµZéD㛼¼¼‹/šÍæÒgffVçý¿7nܨM~«nÞ¼Y[üð,§°°°}ûöñññ6løüóÏ«ÿ öîÝ»ú·ÈuÀCäI“žþùGo^Ï?ÿ|¹·µ-ŠŠŠÚ·oÿÙgŸá›Ã‡ôÑGeö=zô£àºzõê+Vü›Ô˜1czõêUî-‡Ðš5k¦¦¦®Zµ*<<|ãÆõë×ûí·…±±±äÞ0`@óæÍ“““©€··wttô¶mÛ80|øðøøøàààJ«}´fÍêzУG*Ð;oÞ¼ž={^½z5;;{ìØ±=€ï¾ûîÂ… aaaË–-ëׯ_«V­ÒÒÒ¿]]]'Mš´gϞݻwOœ81##cõêÕ>>>4È®]»Î™3‡¼ˆôôôüôÓO{õêuþüù¢¢¢Êá©ü1e_†‡‡·lÙòüùóTìoøðáûöí«U«ÖÞ½{§L™rùòåµk×btïôéÓSRRÖ¯_?dÈeË–=õÔSJ¥òÈ‘#BˆvíÚ…„„à-?ýôÓ‰'† ’ðúë¯8p€2Lß|óÍ€€€+W®PJ''§˜˜˜ß~ûíÌ™3z½~ÅŠ ¨„EÈÈÈ 6½R©töìÙBˆ~øáĉ~~~­ZµR«Õ{÷îuuu<x0m7 rÇŽBˆæÍ›0à›o¾¹víÚk¯½†ƒCÄ=""Âßß?%%å믿®œ¹ØÁÚµk/_¾<eʵZ]»vm™LF§[áîî>a„_~ùåÂ… ùùùß|óMXXØŠ+ÒÒÒ„/¾øâ³Ï>›““Ãq²k×®÷Øîøøø>}úÐJ)B¼þúëmÚ´©„™nÛ¶­eË–«V­2ÁÁÁÉÉÉ×®]kÓ¦Í믿^£F ³Ù|ìØ±Ÿ~ú‰Ö¡CÞ ó‡~èØ±# øÍ7ßÜ»wï;w:wîÜ«W¯ââbB !ÄØ±c³³³W¬XÑ¿ÿ† ÆÆÆvïÞ½d£ëׯ'$$Ðg??¿!C†¬_¿žš—9È5jìÝ»w×®]BÞåä—_~ùõ×_…O<ñDXXX•i9|Û–/_žžžÙ°aÃéÓ§¯]»vúôékÖ¬ ÎÉÉ0`@ZZÚàÁƒõz}ppp||ü¼yó<ÏÛZTôqš>}:Ž5*11qРA'Ož<tèÐÌ™3׬YS cصk×Â… ?ýôS½^?xðà´´´äää¯Y³fúô鉉‰ñññZ­öÊ•+ñññééé&>>þĉ111ß~ûmppðíÛ·ßyçÌÌÌøøø‘#GΞ=»"Ú•†9sæ,Y²$88¸°°0222---22²°°0111,,lÛ¶mGމ7 /^ŒÏÈÈ0`ÀÙ³gƒƒƒ÷ïßÿßÿþ7555>>þí·ßþüóÏ'Ož<~üøfÍš=öØc“&Mâ½öîÝ»xñâþýûÇÇÇ:ôÓO? 6›ÍC† IKK‹ˆˆ¸yófppð÷ß?yòä¦M›Ö­[W¡PtèСr),,ìêÕ«ÁÁÁÛ¶m‹ŽŽþùçŸ'OžÜ¢E‹>ø`Ĉ©©©k×®¥ï»víZ²dÉ©S§Þÿ}gŸ}væÌ™+W®Ü¶m[\\\dd$œ+VçååѪ8P«ÕR³ÈÊä7ßÿ½N§ûöÛocbbNœ8ãÆÈÈȼ¼¼ààà+VÌš5«E‹µk×vvvnÛ¶íÊ•+gΜùì³Ïzxx¼ÿþû§N¢íþõ×_ 'ï½ÝëׯŸ>}zppð¥K—ÂÃÃm6ÛСC+ÇjwðàÁˆˆˆ®]»ªÕê#Fxzz¶jÕjòäÉ?ÿüó?ü°nݺ””¢Q-Z´˜0aI ¿þúë;<lÚ´©ŸŸßرc÷íÛ7|øðƒŸ>}:22òúõëñññ—/_ÖëõñññG­„©yzzoݺõÇܸqã”)Sžzê©» òĉ£FªQ£F§Nf̘Jøûï¿=ºN::tˆ‰‰ùû ÎË9|`âĉ]»vÍÍͽ~ýú¹sç,‹···³³sJJŠ——צM› äíím0.\¸@·Ô®];33sðàÁ•s¢®_¿ž››Û®]»–-[^¿~=??ÿôéÓ^^^ãÆ«Ìž]jµúÓO?õóóKMMÕjµ)))õë× ”J¥Ôõä…^àZm¯^½zõê5räÈ””«ÕJ«zöìY nÖjµß}÷ݾ}û*aäÆÝÝý“O>:tè¦M›\]]ÏŸ?ß AƒÍ›7ßÍU¶fÍšÙ³g{{{ËårÈ………—/_ž4iÒ­[·<<<<<<²²²JWÊiÚ´)Õü/.. lܸqZZšV«¥¾« …âìÙ³õëׯY³¦\.üñÇ+g éS§Ž9²lÙ²ØØØ[·nݾ}»}ûö«W¯.Ó¥ôä“OnÙ²åå—_öòòÊÏÏOOOBX­ÖöíÛgff6lØÐl6{{{«ÕêsçÎiµÚÔÔÔ† ~òÉ'•ÜײOŸ> Éd)))ôÕjµZ­{öìIMMýþûï'L˜Ð AOOO•JåïžžŸŸß¡C‡-Z\»vz‘Ô¬YsÒ¤IèÎŽí>yòä¶mÛ:vìÈ·ûÒ¥KuêÔ9}út```“&M.^¼XiÑÀÉÉÉíÛ·oÖ¬Ù•+Wüüüž~úéÛ·oÛ9Ï>ú裧Ÿ~º4~&'''ýýýŸxâ‰ÌÌÌìììÏ?ÿ|Ñ¢EÞÞÞ*•êôéÓÏ=÷ܼyóFݦM›ˆˆˆJ°£!ÜÜÜׯ_¯R©6nÜX\\ìåå5mÚ´.]ºlݺµsçΧOŸöðð üá‡Ö®]ûôÓOoٲ套^òòòÊË˃+77÷Ænnn5jÔÈÍÍÍÈȨzÃ¥RÉ3"5M\\œ"44Ôb±|òÉ'GmÙ²%/å´råÊ íÝtŸ P(d2Y¥½N"‘Ü#å–Ë| ™LFº °ªôͨQ£*-›êÃ?Ôh4o¿ýv—.]†YA¥RÝ-víÚµ_|ñÅþ󟌌 £ýòË/=<<¨ƒÜÚµk½½½CCCíj/J¥ÒåË— !*skîŽ9òÛo¿EEEÍ™3‡‹~Ô̪4ܹs'&&&++‹·wóòò¢VÓ2™L«Õb[•Ÿ—]ú Ô¨QãÈ‘#[¶l™0aBQQÑêÕ«ï§Â£B¡àÕ}h»¯\¹-—Ë«á†Þî¶§÷0üL™2¥k×®$XËd²N:5hÐàÒ¥K¯¿þz¥ÕÙKKKKMM]¶l™J¥ ‰‰ ìÑ£Çüùó9ÑBܺukêÔ©ÙÙÙTÑÑ6lØP·nÝÐÐÐÇ{¬zi9vàåå•âé陓“óÕW_…„„$$$Tc;vì€âU P\\L®ˆ»ÙR?üðÃÇËåòððpú©fÍš }úô)—Zâ kÖ¬Y¸págŸ}Ö³gÏøøø‚‚ú~ÅŠ<-777÷›o¾¡Ï±±±íÛ·OHHhÞ¼y™Ï¤¦$8ÿýcÆ­'N$§…ÏG}D_Z,–/¾ø‚_¶ÿ~êæ›ššúÓO?½ûî»ü´sðð𠯕§§'˜÷²e˪<û¯¨¨hâĉJ¥ò“O>±Ùl|‚gϞݳgO™wmÙ²åòåËv_>|xïÞ½&L˜2eŠxt!66Ößß?!!:ò¥¥¥EEEµjÕjÔ¨Q#GŽ$I%˜s¢££}}}©üàÁƒ'NœøÞ{ï 2d÷î݉‰‰¸ò›o¾™5kVJJÊÆ‡ 6oÞ¼ÒO1bć~èééù Ü·RYÎìÙ³FcPPPtttÆ 6l8eÊ”¥K—}øá‡{÷îýñÇ+ú÷ïß±cǰ°°3f„‡‡·oß~Ñ¢E‡:}útÅu.StqqYºté”)Sš7o>gΜo¿ý6((Èh4’O/((Hqþüù¡C‡&''Ëd²^xAA±AAAcÆŒiܸqåW&~æ™gÖ®];dÈsçÎ͘1£yóæ3fÌX½zµ\.'†1`À€¶mÛNœ8n•Ï>ûlïÞ½AAAáááwîÜùøãñ´ž={R$á[o½uíڵƗùÒ1cÆÔ¯_?(((!!aܸqÍ›7ÿøãüñÇ   üüü?üP1yòd—… VŽm­U«V'NŒÕh4 ,èÝ»wÏž=Gõì³ÏbÖgΜٳgµ44hÐܹsHÛ}èÐ!<mÆŒ´éQQQ¾¾¾ 4ˆ‰‰Y±b…J¥"!´je|__ߨ¨¨ ¨Õj*î%K–ÄÆÆ¶mÛöÍ7ßœ;wî Aƒh»/\¸€ÎÐ¥·{þüù£Gþì³Ï(îàƒE‹<y2((¨K—....G}ñÅ#""ÒÓÓ;V cÈÊÊ:pàÀñãÇÃÂÂÆŒÓ´iÓ‹/öë×oÿþý¯¿þz×®]1Ș˜˜¶mÛ¶mÛvÀ€³fÍ6lØìÙ³¿þúkŠòèØ±cÿþýcbb^{íµäädÿ¿kàáe=;vìxéÒ¥û7Ñ ¹\n³Ù¬V«\.7™LÔ¾Þh4’îl4©(iÙV«•êí(•Jª_ûp¦¼y ÞÕF£Q"‘( “ÉD…§h©©©r¹¼Q£F}ûö½téuÜ' à͵@<xð®]»®\¹B+ÆWF"‘€ÄðÛl6þ=V•¯ö­! Þ<D£ß2·U¡P´lÙ’ZÕÒ€íP‚®7›Íü^!„Ùl¦·Ëd2^Ël6[­VÌ»v?+vÿsAÁ›mbMÈ@NJJ"ÖJæP!MÄb±˜Íf‰DB+Szðe®ªÙl¦*Ô÷?6¼yÐIÑ€år9­¤T*5›ÍJ¥Òf³•9`˜Ý:þ¼R©ôóóëÓ§Ï;w> <ÇvK¥Rz¸(éé€í¦U²3Ñÿ%PÁ›S§NyyyÝÁŒJ¥Âjã@ÑŒ°4_~ÐJ˜V‰fJ¾;„¸ÓŠ‚7*•êþU^à'_a»ƒ­öÝð“¾/}BïÓþ\ž¨í¸Ei´€&•J«ÐHÁØ‘¤Å‹Ÿ>}zÈ!7oÞ$Ý¢r€¯ÿü—¶[Õ*\É» þK” :U&Û}i·÷^±J€ÒÞ¸Ò³°»@&“Öüåà1ÁÊœTém¢—éz¼~ÆÅÅ]¾|922òöíÛ½zõ²Û)¾Ýœòò/+ÍÓƒÁ”&MÃݶ¬ô€ù*Ý á+í´–‰Ÿv(zŸøY¾;âè *æÎûí·ßêtºÂ_R¡V^-öªL›6 ÇÿfhÔ¨ÑÇLFü'Ì›7oýúõ:nÈ!U’Wä€ê –#(_¯2ߨ½{÷Gr%)ÿ÷_uêÔ©dtªnàááñ/_<�Ë‘J¥Õ?~Q"‘yÔl6çææVáH¯%„¨Ú‘<(ðÆ0ûþÛ�¾@‹ÅòÏÚÁ{€N§£ Ð*? •h ô `JîèƒÑhüÇíféÖæb9NNN>>>Õ¿E%!Daa!•®©Z©Va2™ª|$ äe5›Í—.]ªÚ¶CU Ô]«Õþãvð@NFó(MêP·n]!„——W¹„ÚWO†š››ûÛM¹\nWýÿk?ÿüó›o¾éÐûà�8ÀåËxʈX³Z­U’(ã�8Àx„ÁÝݽS§N°|+•Jûõë÷ï\‘Í›7‡‡‡K$²Ûl6©TJ_ …Á` ”Um6›Åb±Ùl>h³ÙȽäááܱcÇ+V$&&¬Lz1¹OèQôD"¡ñŠb4›Í&“ÉÙÙÙjµÒ]5Oé&“ÉÉÉÉd2FJ ôJ Ûår¹B¡ M&M‡¾¡Qº�ì[­VzÝK 4$ʸ¢4lú^&“¹¹¹Æüü|Ê3ÀOt;ýK9%ÚO¯C#tZLZ=0ýk±X$$“Éè^“ɤR©hYèF©Tj±Xh`2™ÌÉÉÉ`0Ðg[ `µIÎ’H$4z”^¯§AÒøÍf3Í‚ÆF#Á !hTiJ©ôFLÇjµ* JS£ÔÁ| ô(’ŸŸŸZ­ÎÌÌ,..Öh4´È„!2™Œ.ÃèÀ=¹\NK„ýU(‹…LßÐthj„HÈÀ¯ØtZRJ¹ÐétôhI¨N7R04Í”¶˜¦I/¢gš !œœœ EQQ­9vœ0þ•J¥„Øø•òZhÊ„„á”ÿ'J ¾Ñ{‘ DÀtLhØô|úL?–êõz¹\NXDS ÛM&“R©¤éÐ•Ø e#ñpè¢ÄÓL?aF8;dô£Ï@0³ÙL¹AtFèiÈÅ¡ÕÉd&“‰N ½ ‰>À$ÆÑr9;;c¨4ª¤¤¤fÍšUµX,ÈsD¬ý? !ô¢í$ÊkµZÉý…+)Â':ÿDk,KQQÑ/¿ürúôé7n ET˜Pp…ÂäéhÑ£èJBz:W8]”“Dð”�‘3úÉÙÙY*•FNÎÿèÔQæ pžƒCÈ;tÑétåååÑ»À!pæ¹Cy…´¼tZˆÆá�ƒÍ€wⱘ)Uœ£çƒŽpÖB†‘ I™Î*(‘B­V»»»ßºu«¨¨ˆH­ -)=ŠŸæ úKgÕf³ °p¤4‚<Ñêq!ƒ“?«ÕzëÖ-…B¡Õj! ‹x – ÷ ¥ãkn0€º ¡4YBQâT§/ÙÂÉd`Òô¯R©ÊúÑŠa³häØðªÕF—aâJ¥L»é l•.MÇ£}ádÝd2A£/U*•\.×jµôº ¤™ø¢B¡ CAO¦Y€Ð°ev‡3¢oL&]F˜@£¢ÁCl⃧7Ra ÑèÕ …Âh4Ò°é{ 4]I°N”$®“† KD h‰“þ@™¶åidsðÚ*æ@2ˆZ$é2J̆�ˆ­%2qçÎ;wîpi…žâEO©Têõzœ(BzB<–Žh†Gôˆ4->:Ãx8¢ôvº…S"íX­ÅÇ"‘HÔkÕ²c2Lœ ×\¥àK™òtfÀ•‰ÇЯ¸,]�q l†Þ"•Ji" 2D¼@¹@U¡`á0Ó‰ ÒDèàÉd2—ZµjeggÓJBž…Š*ŒãMÔŠSmQ’޹ÐL!—Ð"@7≫ ¬à‘Øn<¹ë¼D&]@›Nãcæú4È:ÐÀÉ!"€BAú1›Í`3vâ ±7z}&º‰£a±X¨¤î…ÒI'h‰ñH�«éJ0à ð®áŠ6ß®t‚íAò§ƒ©7–&´GÄPB¨$‰Z­æ#Ÿ#£)M ¼ œóñ½³äbÔÚ}þÒ*óë8ø m Д¡ür*Ï 7ÝpDgŒð˜0<‰H!¡ ‘?ª!X¦7§2œ.Ô Å™NÝìtvvƈ�Ñó!z“ %“ÉlÂfìc4¼oP¢VlWH$}˜Þ<ÝìùЧL*5§‰SrF¼§DAp` r1(̃P,„*•Š&EŽ{, L&Cmâ:à¾`“19ï!‚ÖùöíÛ………:»C²<·ÒxÀ˜i‚Cé<Ãp ã­LL Ð0TÒ—J¥’dO$¸;ˆŒ`ĶÁEˆ÷¥—‚££ü ·bñaÀáÜÈî,Ð ‰Î Â1š!m18(4lÜ£ øRÐ’B'>M ?ÎöŽ.� å*2áG?2|B¤QŽñ¡ÂÉ<^$JŠâ@€ƒ! ©‚ÆÃKûИ%q. üq†A›ˆù¸ÂCáââB2e™œš7ÏÀšÂišƒåT%àò J‡�� �IDAT$CH¤œœJ#¨T*urr"3¡2{0 èvÁUVr-@Ãñ rLP’8ÚA`¡ÊNtPñ‰”0™LFH©T*íDòˆÈårK{‹9ÐìÙÓ@rDâìá\°¡ÀóUOrT zWÕÉ„£Îõn‚ê@Ÿ¹Å6¬ Ò"ÝB^4ú–Vz •»ÙHÅ•ö:N§ÑhˆzBZ§"T°ÑâCÏ››O" $\Ðtø¸‘6]£Ñ5T©T0»‘×Ðb±¸ºº µZ-‘Ht:ÖV¡P¸¹¹¹»»ß¼yS¯×s“³³3·¡A$ç~x#ì ¡„½@`ZxMÀ�€™8\<‡ih G @?(‹p…’é‰;Hˆsp£7$6x"•J%í/žFh !ƒfŠá'B?â|ÅÅÅ´ĽÈÒKlƒØtebÐ1e¨A@'r²‚“@C3"<„¤BC*..¦•‡áRQR- Ö0›ÍFu¹ðGCž#~B2œ“““ðVÅZddh¯DÇAýµ6›ÍÕÕÕÅÅåúõë”Î'¼(i7BtŸĸy7€+0&RrWáyÈVÄ ÖpɈÄ^+@ƒè©ÄÒÑ"?,ÇÀþÎlBž$7µ7IJè 7píÂé‰À8üÜÏLkH²ÑY;�¦COƒ¶*ƒ˜5 Xþø«a Ë8=‡ûo ÄÀ°ÃÙW ¢¡Ê!ø"- (Doz/Q’4aÅ""K/…ÓBQãBO£F5jtðàA­V‹•ásŠû*p©àvt\Ÿ[¡ÜÐ"‰‡ ì¢Ûiëa!€¹ŒX2üC\ò–�´Â(ò®s“ ¶G0SœŽ —€¹u*A”iÕj5b1¸EËEŸ¤ hN`f³™h7É À+˜¹`G-m' ª,"O¡Ñ÷Z­Å=aƒ…~f-X5ˆr vuË©Ru¯Ä·Œã jä áÅb±Ã�' !!7œ+@VÈ0¼ÀðŠ˜Ž˜ž¹†#h ¸ §6_"µïÀŸ,6‹ñ£Û nB&HŸûƒYeb§(~©Ø-Ñ tœö�w¹“ü”órre»À!ä:¿ÁÈ¹ç –=>;Ð1ß5Y?@Ùéu8¥ðØÁ8ƒBÎp°ƒ¼ÚGZmˆêpó�O ñp¿œCévD ™bµZ‹‹‹¯_¿®Õj©æ/âŽá±Rt¤±‘Èe¢ž0[q' MÈF·899o‰¿’Ü�Š M‚]‰Ø3,2V+OóE4~…•ól"Çø—r§ ¢ 8“~CRt¸{çËeHY³fMµZ}íÚ5HWp™àxr‹:´7l w=’ðAW’tÁBhd‡´sÈñ°#nå*ˆbv8 t°œª8B±m„©œD‚»Aÿ€¨Îc¨ˆU(Šââbèã„RÐôá €r@§—ûÆéÜBý¢xG©TJš8a•^¯§çpõqœ<bA&“I„D"ý˾³³3„Ùbæqt šà[üðËe(;ýŒ+@°ÛprÛW8ìDEE¼!|v 8Òp,áàŒ™ÆìììÌ]¬à=°Ñ‘ô@R3ˆÚ¢g+p�Z äM.ÔÃL«Êã¾ÍHãAø2 ‰ ‰`ÉœB"è2œçì†ëRÅ>qÏ|lœ6lÁKÄ]> ÄyºKMÄ왆 È“x \.' s! ˧$Áñ Æ+®U@-Éd¤RS Äôe°3uà^•JåêêêããsíÚµììlü œvŸØßX±¸>Áe)î}ÁH05;6ŒãL<’BüÁ‡ì’`À랊*=ŒÊ‹Õr0›ÒhÇ{èÚ…BA�u�¹…œ%ÐèA/xÐ"¤ÉÈKŽ•JÅÉtÂRW*ܶ<`Ôh4Â%KFö\ÒÆ”J%}OþPÒ¥†z"îZ­Ö`0˜Íf!ÖúVy†œŽ M„Kô\Ñd qùQqÀóK@Cy«.hsúRšâÊîèÂMêääÄþ<úêœãÀ•$îsâ»L¿F­VK;ÂE`2é À䕞ogÿqçÑGàa<è�¯F€�üFÅÅÅÀ7PLsÁÅv;×1­Qd»•‡8 q¶SNîijä…u b q”Òñë´;ð`‹‰ %ˆ¸›L&üKKå°f Ö#�JÔprrâaÁ8\´t™Ã^èt:__ß=zx{{C}wqq!².“Éòóó³²²èâ‘ÜÖ Ù…û‰y«]X3­3­$Ò3ø”Á! ƒV«Å¡æ"/ÝA[Fx‚½GÃx‡–SÙ}¸­ƒÇ¹#¤Ú4LhvYi0ÅÂÿáå0°³5ìQ<$&]HÓ°q¥‡¸¾„§ ¢ŸÅbQÊ”²/dú÷ôž1žHzµÙl6'›!ÂàÞÛ]"•p ˆ%â)r8öd‚'&oi3t½] 'ˆÏ΃ì 2A“…q±ÐЏa,Bâ]N»í‚ޏŸ8€w¢#¼MϺåëÀ;¶q_7\Ðz½ž0¬¦ç¹!”›æ±Y<p^z$¸€C ÚžóodqsÔDƒÁ@Þ5Üm)‚¤nCƒ†}G¼8P`ø¢5!õšÇYð0Ć�«yÀò4¡Ø‘Ç‚+ÇØbhÿ´ tÐè¯]:* ,555###//ßSfN:ðÍÎ2‰P~àØ̤À^nwåÜÉ0ò>ŽñPXnQÀë@p¸+ªXå·v°œ»ª8Àª¼“Á` á±ÐX9ÎZСâ GdÉq3W¥RÉ»I‚‚€ø" ‡?Š\ì–K®JÌ·Í ”³”Š,…Åb)Ž(6µ1¹~æj§X`ä<Ø£ä¢<5çI` C0‰ÐâàÜ’JnÇ+Ã+FB¥B¡  àÙP›@Ó‹áTž/‡@¹Àx¸CÂNŸ€Ý %wËá/ÉÚd £6”0„b— µìÂ@xÂ&"ýË…Ä’Biàêâ¾àfúá]¤ð·`é v€œ¨ršĥiã�JJLŽól 'LI^^^nnn·oßÖh4$Ùð¸Q’ £ð""& µOÇŠg±�Ùhe 5 ×Q â$ò\18™è{ ª?‰Y8éœP�Û„¨?ˆ\è×ÉÏ×±Ë|»yšO@ô¶ƒåTð ‚<nÞîö+â19H6æä[nÇD©´yP ÄÝrD'w YéWª<#û8÷ÀÓ]\�D€¯J£’¬”Xj[´ó´¶z6!„óg§ÅN²T™MØxqž£Î#ˆh¨jµ!X\çàDJ¥²¸¸˜d茂AqA‚Op£Ý¡Ø\*<CÆtºQ^DÁ¹½Ž†Á30`~& [éììLáæäŽ¢^HÇ($žû<‚ÇÒC¸ÏŸ‡`}äåR¸ÌjŽÈðXðñ NO ù¹ç™'rÂj—}ÂÀ<¶…ñ¡nrdæºJ¥"‡êñ ¦Ù¦pqñŽ^¤T*»téâïï¿qãÆ3gÎp÷7ðÚ˰+ú€(;q Ã2¦ÉÓ}ì¬Ç<}•‡·ÐFà€#W ÂB㸙kÏ4e¥R©Óé€<n…§]c7¹œŠ¸ âCˆ,@éòA°ÀL‰ØYí,§Ê\8+8§E2d^ˆ3´G”¯x‡6á1©pC»Gä’Á` ý™§„4ü/²VQGË®zž _.TäáSð®0y®Ük ì`R©Ô*ù£2p¬ÆÜƒFñô4Ð ¤O‚×­S×9pÚy¶ þQˆÁl6ët:âU°;Ùl6Š…lËSVa€âŽ7DÊÙVn¬#‚!šÜ�´5ÈO¢ e-†ôÍ53ú@ N£â{À?à ,žó'¸Iè-àU]+ËDšЕ�—‹a.&4#G ¬4„]DI…åI$p€òb² ¢’KØ,²s‚�k'ã(8¢«“““322nß¾MhO„U° LÄSŒcWß¶ñ‚PJ`†åf�Úhb«ä[‚î#‚™Î8&áǶzèj˜)]LÙ°K«T*˜þpèà&ÎÍíD €ÿÜþAz<$!’Hª¶¥ƒå ‰"¼Êò`x‰C„MsÏ®²!ÏøWC””†Ù-³æEæ+nã Õ©wä•Zxô¶`uì¬^!ò"܈. z =V¥R‘ÿ¡®tØàÑÁj#’ŠÂùè`ƒ=s;�YЏ�ËÃgé'2à€æB…9Ë.|À.œÚN³¡˜r pPÈ`Ü‹Ã5˜Ëxi/èUð|ÀÉ5ÁÊ«ðXXð3¨Î|M¸jäáaiàñ¼gZÜóÇ‹âÀO B‰ÒD\¦FÜœÄoPï–j\�_:lMvŽU“ÉtõêÕôôtäð"ä¦K»\ˆ}¤ŒBþóÁÃ4 ’ò²RĤ1Aq®ÂÒfñ•„e‚»Wñ:øyN(9)ÃZ½œ•Â’ †m¥ÙÓƒùñpüÒ¼(•¨î`9Uc^ãUù€èÜ+P<®ØÖÜfµZekdŠ X™ì¤Nx€¸µnÁ 1ñšÍ ¹<Ë;·í @tŒF#ž¡¼ÃâÇóRy&#Á`ݹáYÜžcëÉ3X ><Ô‚—1&úHœÂiàV…4 £<wM V_€‡òRóµ+ùÅc¦A¸‰äM\ÆC¹qœâ>¸U‡«_P}hy™îÊ"[lxrŒ]´´d¸”y}3(jÐ*àûá9@ؾ fòC¡%)Ÿ¼¸‘cooo™LFQ[‚•¼¤­D½;~ÃóÒ°¼ˆÌÄé ¹èõzÚJàåa`ZäQpÈœEÀXg™...ƒxVËþ4lîfGâ?DtœaÙ&Ë-_dîßå*oiNê ÷ûò¨W;¯'7zså ~&QRWžûÛHA¯22ëà4œ|Ó®s%ý¢”›^6iöhägåªOTŠ–®ͯ«ÚÊki�q¡Â#šËÎêMò;7ªV\ ˜Ês’yéLnaàeþ _çBš5N [ñbÀðšBå"eœ½‘dH^E‘W ¤[`Èâóåg äîwÁ*ã®ũ9W}îÎc¥xYkÎ!¸ÁU‹Ðƒ�Ǖل‰fGs'G±.6½‹/!ÝaTœ»ðzHäù'e ‘#`Z<xW²•ÑíJ*p5Ú®Ð'w ‘¿4H® Ð•.../¼ðÂÛo¿íëë‹`9DpÑKOh Cý 6ɵ^Š[Ã`b¥i"ÕŸ§vÑóé]Gƒ¤12ŠÒRÐ7‚ô„›»y »²¼œMÒØ …‡‡üsÜSÈá¸ëŽc¥¨T* ÇD¸P°¢m°¸ráÂ.lÝ´bÜH˜lËçÐrª&BÚÎRa—&¢o¨·¼dqîâü‡,l’éÙ,™v¯VÞMn—ÁÓŸ¹xÎE¢\ÜÖD4h ÉÚ.ß.…ˆlkv­wxA'TÈ®† MŸwû@ÆUô¡óP¦ss§$pW ji”]î!ª’=·  bX/žÁ/!¿*Ü`d'…•È=-))aÜ¥ŒD(øoÁ0ˆÎÒóiC¹Ÿçœã˜%‘iêD�ÿ¹Íyµ1(šô.P7ñç …B¥RQ°Ï—´{#g‡vxE[ %˜¯ªÁ`8sæLzzznn.V�áÂä%e5T AÏ$ÚM” ïõ«ЧñÞ9à+Ø8gyˆ¬&Š7±+MX¿º““å<OàLAç粆úª\›§·899aÅx)Î` "5߸éçNÙÑ.;1š;üe=«QR?TÜ',„¼$‘ïü£ÍŒ——Õ…4 ²_eænfÉî?õâ’÷a‚C”Îþƒy_É{|Aw ‘Æ•zX¢ÅŸs6¹\,X•x^v I3äá3Þ݇wvà‘ ¤W!­•›àx±/c aŸªò2øž×ÚâÎÐø€ïfºÄ¾À PT^[b¬§§ÂðÀt^G€Çzð U>BìÅqÀ¿…zP¹x¤,=ŒH SÜj«Ø9þò"¼TZéx-nOæÓÄ*Æ3g΀ð!ÙvhWp‘ ФlN7ÁJ©;’4q ÔV.[H¥Rggg2ÊQž¤ÂÓ¡H &ÂÍž0!"H„ç?𪵼=qeRý‰ VÙžøs# Xx¥m^[K‘‘æ'ðé«p¸¢&“(ÕéŠóG¿œjÁuÉ«Lþa ékqíæêäæÔ¦M›çŸþüùó{öì¹}û¶õ{«ñ=£ó¯ÎvêÍš5Ið×ét*ÊÕ///!%±£\( ¯ {7ñ¬0 LI .$yCO~ÂK•8®T«f}Ô~Ç‘Cø�ná\Àkä@ö¬qïæ‚vŽ 8WéÕ µ<@Y°ÌAnß@Ñ žÊm><q„G‹ ÝÄÅ®¸2R y':XÛ°ØDî,ÄÉÇzÚ…cáùðµ`v`Òðß "Ž;·(ôñ–0uB:±xR'—²iûPå¡wð"ÜÝÓÓÓÛÛ[­V"ŒÂjµæååAk!‚‹�XVµZ-i®víhÁaĦ‘4jÔè‰'ž8qâDZZ„*ž²Æã€`ÎâÓ$ýÒÝÝLO<¸ƒ½…3‰GðÛuð£Œ+z O¸á™Îà”<Àmé\á)Ãü,ó´YÎØxý_.dð’9 v¹–Se\ Ü ‚i~~~o¾ùf```‹-222òóó-r‹ ²`€¹¸¸Ô«WO*•fff’…ËÂîîî¾¾¾ 4ÈÏÏ¿~ý:¥7C®!{œ:< ’2=ã¹ÊýùüÈq3ê$Š’®38Ø<1Û®rQpÄÚñni¼MŽ] `Œ„£Û9x81å0yíjˆ®vý7íºñ0?~Ây½Tê”%„ ÐüuHþG)g Ò@Ȱ†Õàuq  rµLü¹þ)MÇ’ñ´vp_»R­0Úz¤R© EAAlMxÖ!©ž|ý8Ë×·£º/Ï€AÈ ½ÐÓˆ¼ªÕjê¸êååÕ¨Q£ìì쬬,ÕæêêªÓé é¼ðøI^Ò?HäUâñ ¹*•J­VyxÁ1Ž–îA‘ß‚Ðú‘’Ï%טa‘†àÅ#˜y NGöX„_ÛUÙ=͂Ք·+…T;ÊðÜ .š Éu+ êqk¼ƒåTq¼vÀ69É9‰¾±þÎ;çΫU«ÖÅ‹³³³m6›­…ÍvΆÏ(m’™™éââBŽJîߣ‚4ÙÙÙƒ!''‡l÷.Ñ« }s!þPpoMÏ5ÁÒÖ¸? ÏC2h$èq‹é8rñç,}!Óï$ÆíNð6QH7/;£'©v¾+º…W^YŒ@É¡pGÑ”yëžµãííM^´pæ±¹¨1JJî£èëÃ[³@.áêIvæð!bs}‚7h¡Ê`„N(Ë#zNe<"�ÄV)ØÜ€]À’$©%JJäñ8˜wh0pÒ899999©Õj•JåââùÃÃÃC&“>}º¨¨ˆÜNTrÍÝÝÝÃã   //519Ž!çÿØ{×8ÉÎê¼÷­{UWwÏh.ÒiØH2™‹AÈ6æÄÆ_rœÄרàÄŽ“8'&¶“ø›_.NlŽã8ö!Æ—8àØ‰q Ä9 Fè6ÒˆfFÓ=Ý]U]·½÷ù°ºÿóï·ô;Ó|èþ ß¨/U»ö~ßw­õ¬g=ßÌh¾ní¤”î½÷ÞG}4b•©ÞÈv»ÝÕÕÕ¼àkkk÷Þ{oæ_‘ÇB´q@ÇÌ< ÍI£vtÍJ ŒK¸ÚˆQY«Î7›Íxâ±ÍMm˜ÍfƒÁ ßïc攑G\¾{pÐ<ØpÿÊÚ«!gŸv€ö4Iû­íÉ›'—üò»ßýî»ï¾ûâÅ‹O>ùdQãŸ÷^Ù+Ò)ªx–O=õÔ`0 óÍÊó .XÐîÎqÇ@ÊFçÜð”÷ªy\†³�4ÈšÉÐѵEM¦ÃhèÀ¯Lqc],5#éŒÈ°ñâ’b{£©N5f=fôiœÛ’ð}´™3ª±k>Sxoºé¦£G^ºt iN£|t² 25F%)¹õc²6 T.Ôì-í¶D|ë7£‚“Ê)22‡o~jîrü-Cþ؈qñü~’g3K(SHc=„ÊÑÊÊÊ¡C‡¢È(/žBŒ7Æ/GcŸÓ¹×ë<y²ßïŸ?~{{;+m¹cÁàF°Ñ2W‚øýñx¼XùÇgY_____çãÃÉNj˜ôi¯¼§îBSÃÊOæXw¦�ÂÝìyË(dÞóV ¤]GSn~ˆvâ@hئÔ½œ¯Òš=r®PZŸHõ/Ô·~kkòO'—ﻼ½½=ùÞIùš²õó­¬=@fá,ÞÁn<f¶]Isû&#Q;/J£G>î44ÏW¦µfäѬŸýf&ßDØà,ãb°÷àD‹“Ýv2�Ê”|¿(ŠÀ@<o½Å÷K²ÄÐ4„LÚ.ñGyäÌ™3ášj:{œÝqÛ™èN²N óMhEõ.‚Pü!cR¸Œ/ž?è ˜–ä}NíÈÛ9¡ŠõÒrñ”Iô{�€åJøGZ-ΩLÊ e|ÞC‡:thuuumm-ª±¸ž€×j#?þw¯ÊªV¯½ä—_ÒëõžñŒg\¸pamm-ë«E<xÞóž÷â¿ø‘G¹óÎ;ƒy_i¯þ!‘Òì2>EØ6?øàƒ™'Y—á5Äæ¤€oS…G·ÌaÞsiîÄÒ‘šX¶Õ#w¦r˜"Ut‰Hƒâ+¢&p_’u—A¼ƒ*gŸã Ǩw"Asجÿn=½7mÿ£íÉM“²*Ûïl7®™N¥¢¶£cáÉJ懃;ÐívMX2y1íÚ0΀NX¦6ÄÁm ðÄʦßg(ò9$_x÷®¬¬„Œà’ Í™4} ìCcÍâ"YýŽ €i d¬Ì!r€R09s (Œš†aO„‡­Çì¡6sÚ58yøá‡ÝÛ§mîvé!;œ‹Ó<BTèÝÙ2ÿñÅŠÛR ŒÐ[Ã8Ö#5ŽY·ê`|ºñx±ÄÁ.{Ò`g Iy’�œBËâV£Ñ8|øð‘#G‚-A1Di=8²£‹Ñ¯Ý÷·ï›t&7ü›Š¢(‹ò³ÿú³Gî>rÓºéêtõd2  ~x½Ã7|í·Þz×]w=ôÐCY«ŒLáKøØ¬=>ßáñ'4H’T/íÆ´ˆ'›tg/>Ö6L"ß.!+IûûÌÍd²:‹6¸\¡I@.L­ƒÅ«¥Ý‘Ûƒ¹œ¯ˆ^[=&×@v¾¹6ï ;î³~gK×÷ÌǸak Ó*Öëtjf*Z¬È8Vðadé°æŒ~ qjo õi¯xÁh4‚çê>–3Jý˜$êÚ&›Ç#"$pÔRe:T¦;GådGµ8Yp0_(@Ÿ&‘zЖ‘F¤ÌàãA0aÌÐ?ø¤!ãXÒ?þ—'%²x²ŒÂ`åM3ã}ý@jÔÁÒÂã’Ù£´ ÓíÐ+F8eœ+i† ÿ‡:~üxH©FŠé³[;‡>~üx¿ßÿüßøü5ᆭÿ?û‘ L§Ó¯úk_5ø«ƒÇ¾á±þô†'Nœ;w.Ì“ÉäÏþìσÁ¾ð…‹/Rœ-êý°âÊ)ìì@)—Wšs;k1 öOâHm‘äïÔãœN¡ÜxóøvvÙN²P"\M/½Z\Ñz¨9øèdI“¼ÁDͨ.!gB'še¡ã+öƒUØ¢¦Ïº'ï:ÝbïÙ b&´e¡u˜¯žìá-\õ{ÚËXÕØÒîü) Ã1§P“â¹á‘y{ÐA1B•±¢ ËX×–Pdææ�M*¾¥@¦Â'E<&4°“<u¨/Á ý¸…°À2å7¢Wô,"ÉÝΆr@VÁCS€Å<%¨®Âín›Zð7pP; r\pèÚqsÅÏNóèosµ…A8räHT™‘EÅmÛ²²²rà 7\ýõ£Ñèĉ§—Ow¶;ËËínÛA/u6^¾±¹´¹4_:|ø0U~·æóù½÷ÞûÀlnnÒ—rÈq¾OóŸ…dj†g\2)&ÏðÃü$kaNÖݬø’†ª½Ò t¸:1±LÈt²‡|>&6 ±<*gÃ8ÔšffWUuøðáÕÕÕË—/ï—ÁAÈÙÃÄ ¿ººº²²­fó=cæxöž×³¾‹•½‹\žO9ÕB™ÜCH€x††7'c•ææ‘è¹µhë*£7ã·®³Ã­m<hZ° ˆSvt» ¦gr‡»èmêÀl7䮥¥%à#z6v°·_CF¯p…êØ@º€ Š˜î`¤žmBêÍ[™ÖV¬+^WÙŠÆÓ÷¾ý(Í7á=„@Ö�� �IDATE2åÖ´Wñziiiyy9ü/¨ÈãÂ:N7×_}Œ¦=ó™Ï|ðšËKeë‰VYí<”(tš÷4·¿uûòòåÚùZ§Óéõzëëë6Ó‹ù‘L TãÅtÜÆY›³Ø”ô$)R4;l¢L‘$øM'Ʋhpl,jø°í³J”_Žqâ\’¯WuÄûL/"¦²àË>|øºë®óÈùAÈÙŸxgŸùX: Øå0ÉAË……å É÷“¬Æ¬áŸ$k–½?El*vB ê‹²¡¶'`-úè!œdL³ì´2÷ßíýÌ[>3K{uû-1ç’ˆãÉA—ÙuK4ÒâGï3úuf/í)Š€Gœç‚#1„hj™å¥3ÌGóxSŸ&ñBANEé¹w4¨ï¡‹ýX_‹F]Ú+xê d@LÔ²Q¸ðp­’é[‡ô "âH�ÄGXZZ‚[Q¬¿Óéœ<yòÚ¿píé¿tú»nø®ÚÆÖ÷nm×·ÓvzüU?÷§Ÿ»R[™ŸŸ³õF£¾£Ô°²²j›P0Ò®ÐQ …Œ9÷b‘ð¤²þ?ë6N]Ó•ôL4)¦C‚k>§ª¶é¤oäQM,†"ˆšÑOÅñkbÙ FÑ’zæ8,NzZf‚âéüùó[[[£Ñh¿FsBNò³Gf˜Õ<ŸÏ#êðøi‡ ?‘‘gl£ëQ w ÂÊwÇ›sÙƒý~…D’ž?V=EVð´sÏøŸ"3Y`WƒÑ4ÊØDœî“¡ÆÈñ‹¢4J¸½™9¦ý1³�´‘Ó|ÊpjE£<nÒCF£œZ#ÀÚV;ïu¨*n)ʲ¬§zóÍ›çáŽÙ6Ôµ,H®t¹Ì¼@3®6šC( @¶™SˆÁÝ‹¦EæÒ.—vEÀñ‡‰y¬Ÿn·Ûëõ,GÛív———ƒ0}ýõ×w¾¾ó‘Û>òªæ«ÞY{ç[Ó[o?^ÅꃫÇÞuìO~êOª‡ªcï<Öôz½ÞöÑíÖ¸ÕÚnÇã^¯–x(qý‘æQ,ÀLjZ°¡?ÖpÜplOãÄwÙJØF± 8+n Š' u¢§ë…j»w{àF6×hÄüO£±k`ý˜M»Æ¯•¤™ÜÌÀ想Ÿ÷Š}j§½j`�ŸàÖ«wBa‘c%žksSÔ$Z«°µ÷iî!ÓÌsÁ³¢†’3?•$¥5Ød0s¨ÌŠz®Ê‚o6>`@TÎÓ×q‰â¾üUVÏ€Gœ&sç1ÍÝÈD)|o¶·9î0—B%:J:+¥jUU³œ•×”E³hÔe½,_RŸ)šŸ¸Â°XZZBɘ¶±UXÌÍßa1Iv,N¨n·k¾ X%òqa=ÙívƒÎS64êÇdŽ):Wa”ˆy±;:tõÕWß|óÍ¿|Ë/¿göž#å‘ÜùÇß=þîWV¯œL&o~î›Ë¯)¿îŸ}Ýý·Ü?¸mPG}sssóÕ›íSíæ£ÍíÙvô‡VVV.^¼˜eKžÏÚ9!+˜ÙA"È4á–*Üf™H«ï’Ù1XHxê%íUDÍt2♸¨Ë ³®}ý™h›Ëe‚({Ö9bÆÞN{mBξkd%‘ؤéCßn·Ûï÷×ÖÖ23+÷�`üÈ;ÊáÁýF#˦Zz­DÆÐ¨ã_ëÙêTÊé°Y˜dÖ'ÍðhOY;^O`;eÐãî,5ÃÇkú#°¥½Jˆv‡‹²‰l`Ü�ÉthO»FsÔ‚‡îv»kkkQ™9 ‰Ä ÖÉ'i£ù™fúDªÕjVcö—gó—Ìg³YãS ê!°€ˆsôíÉd hVie·ÝÊÙDYúÞeYƒápè‰cdœ7X¡Ž[Á5cÙ—~¿?ÐçÑÇ?ç9ϹÿkïÿþN‡ï¬ßy¨<ô5å×Ôêµ~¿ÿÆÙßòMoyìºÇžýGÏ~ð¬MýÜ›ÎuÏv{Ø œx.Q-Åî • —¶°<|’Bú·œZ&XàÎ#´'Ým5 c;*‰l¢.®Ó`[Õ < pj©¯p¶€G|(V`ØC òàN’ Ú`û¨'}rRVUXðÑsq¢A…,<ò®žÂó9‹ß ˜o’¢gAd‘,ÙŒå²h‰(º› !ö äô?•ß7MËbÚ¸Èü‰‡\ÌÓ L5q©P`…jÀÞ8�®8hpc8ÜwXßt5Ž­ U/¤8m¹$¶"á¶ßï¿üå/ï÷ûŸüä'¡çÒ~0–XtŠÚ_¨u~§S»¿Öè5f³Y=Õ›ïmοžž“šw7‹iÁyÁ\G!G�¬’x±¦5ƘË"õΫÔî®ÎÃÛê¹¥¸nä´àD Câïꫯ¾öÚk!§-//÷ûý«®ºêYÏzÖ 7Üp÷õw¿"½¢VÔÎÔÎôê½£ÕÑh̼¨ñ¢­“[o.ßü–_|Ëúòúö7oÿèïÿèìÒlþÕóF£1 Âß%�ØHËÂzÜ¥?L´‘<�@õ@Izü‚XWñR–gzKqv¬±Mì¦ Î °É4"Ak Ê>Ãsr¸Ù˜‡ZÊ>óóåÎ�×£÷Cý‡!oÌZØVjOÚƒs%ÇÏ•A9#EIfdҊȤ˳.·G ck™@ñŽ‘Ý~C±Ù"ùâÄÉõd:éÄêç´%B ‘À‡åð͈4f‹%)&ð\2ºôq9ïµn8úœñA<5™ä¢,)‹‚ ùl!ä8â4±pµFãˆx’.<þøãív{4q–&ãSL¿wÚø|£þÅzY•1Ò{goô¶Qýžzíþš“_ë™3ùIfQs0ßÑ|éóÛOŒ@'fP¼ˆ‹×d˜†‘RŽ­V«Õëõ `Ä+,--u»Ýøéêêj³Ù<tèPú+++‰]uÕU­V«–vãYªRµCÐÚ91Sõòôò?|øÿåÉyË·<ãð3Š•bóÈæ¹sçÂT-z'W]uÕx<Çíå£ d=D9KŒñq¡`´–&"$4ËZyȬ0ø“¦±pK ¼4³Œ,Ê66Yi¿bkfp÷7N*‹[nÉâS¼”éï°~Bξ}^ÏŽl#f$Sµ qhBg6œù!²#8›J±ó4s�tGãÈþŠd y4óín0’jq»­ïɸ‘h›;�VÐÈä›8õ(¿L9Ëìd-Û$gÇÊ ”0æÉ£±°ý�€x $ …ŒÏ=ŸÏxàP¯Iò±‡,NŠPe*wÀO»*Ìçó¢,ŠyQßuÝ×ç~z¬„e÷9ÞŽ©ÆHÉOœ8qâĉ|p}} Ûl6£€Ò’Ñá"®Pd{¾$I?‹Xnðp<E¡éiW).¢Z8H=ó™Ï¼ù替úE_}dzîxizéó«ç?”úrãË7”74´>ró—oþäÇ>yçÖ_|¼º½j>ÙœL&Ãáp04›ÍápØëõƒÁ¹sç._¾Œ“[|®cÇŽEqñâEC–S³—[Ï©ÊRñ,°×cIXªÙ¬b`(O.ÛR÷e¥¹ • Òï‘f¦éÞ) ¨@ë°@˜Ñ‡¦³ÿ“ ·‡¡}Zwü äì?UšUH£›ÚÂeµÛ?þ¸â„Íe’%´ñe+ØÇI#ÛÛÛ[[[`q p¸Ó¶I»cá‘φG *Ðü=ƒx0å|LÖÛ ©†FŒ•ip¡¶bgÆLÿßô6OáÀ Åb33�—a‡šC¨>1šÏçnxJ<{n±† ´àņóΉШ×R-ÀåË—Q_žÏç©Jób^Ÿ_i$xŽÕ+$®Ê~H¦͘nS}ž<%Û@æÇ.PÙà®-XsrÊÇɾÍLøÊÄ)…øæææÆÆÆË›/Çuïø{Í¿÷¼âyïl¼ót:ý¬ú³jµÚÒ®þüÕ§<õÐsš?9Ÿ<2Y­£ h¼:¤Ö-[í(* ‹ÃÚØ¢ I¡‡½Ìžˆéç¢(Bâúܹs´véœvmÜ\û:Ô¥½ÆêNªhO&xØõw1aQEqgb¯e¦Θ)¤k_)ô '9+ŒdÓg´ñœ@{M&Nšâ¶0¨ ^¿/ÛÒ3ò-ívû…/|áÞð†Ï}îsùÈGÂÛ*p ªÄTDD#+’²¹ÖÎ&ÿ¯7Îï‚i.^(‹Ø®Ñ­xÓg™‡ .Z0Ÿˆ˜ù†Ñ‡0!Íe¢çã²2޽md#¨É²ÿ·6Ì•Yñ *ôûýö··þï­âsEõ…Ê;yöƒ³Æ§õGvÎ8 ÷Q`9S¦ÄYÇüЙ3gž|òÉ­­-/Žfcž<tdfY@MmýBC>@D;xÉgfTSs§Ý‰éˆO<ñÄç?ÿùŸ\ùÉ×ßúú—¶^ú£µýûKÿµ7¦”^ù¥W.=¾ôŽ7½ãè}G¿ê_5-§Ù`?7„ʃr6¥tùòe†¨‚´mÉÊh'ñà¢a]"b@#ìʼn#‡%Š¥QmdΊW‹µÊ¸ÝÇ!Ù[B^ºúæÍf®í‘Ä‚ ëÖ´%7 8z‘òwröó‹¥à^bFXôL™¹+<m›Ì:žÁš8‰¨y-…—´µµõÀœ={¬ ³ êLÓž„:"JÀ2ÇüñÇ×××$x¾+9k~PçyHÖƒ®Ö_¿2~H3ŒŸ²e<NæN0\�nÊtlÝ“;žNÔ(`åŽ+|:N‘2¦Gªh¢ R´ŠAQûbmò'í«Úå§Ê¢(R=Í_;¯«µïn×Ëú¼Üd†)Žž¬ŸDÄuÀ£"‰(†ð™d¶¿i¾i1½4»Ýnè¡E›„¹E4R£îÉ„V!ëO§Ó~¿o †x^[[[‘u:_lÿâù›Îÿô‰ŸnΚϸøŒ­­­ÏL>óé—}ú?ñ‚v­=žŽÑ£#ðÛ(ãA Ñ:Ï€á’ÙÙ1Øä%äë4w9x}ÑÞõùòå­­­xÓXQщ›ŒE, ïeŠHç=–·ß‘2àJê9ž>HrZ|v'Æ 6”$¸HËM-*Í„œ}ûr.�âÁTGÇØ¥Ù@OÖTLò‡&¤1äa&‰KïÙlvêÔ©'žxb4Å)€!ÚÉàf–3±ªGtƒo½õÖç?ÿùï}ï{ï¾ûnã9ÆYîîÐ&ùÆ›@?<<?‚Ñ„x"¨4tžZàø�U÷­±†ll^ÂqÀ™ e«º,cà³�™ZlÑ©Bm™L¡öÚméßµª7UÕ««é­Ó²(S-5ÊFó4ëwì«�?âT5ÍO#/a¤‘¾·¥\L”'ZxÃFaÎgÌCRN7¼×Hk8âÁ]SJ°A YÕˆÖÝnwssóñÇï÷û7oßüöúÛÇãñ{ßûÞûï¿mmm6›­o¯ÏÓžFÔñv£Ñ(¬‰—vm„N–ÊB½:â!rKÝêKÒ4â ‡Àf…C“Vø)OFœ¡ÝlâŠ�C“v€Hã@ü²fÜ{š¸JF&#k¦šFËFೄœ}Ö2E}/y–ZBÍ̺šd¬æt!kAJ z®Ø{&Ì©2Â[Ú;/éiï *ªétzæÌ™z½¾¶¶Æ¥½Ú£ W”hp²Ù ‹ŸtÑ‹Åö-ëàlÝ'²¥Ã¨`œ¤“³gtx¹÷“4© ÊDkz«{¿IÆ FêIÑ�õáUUUç÷:épJ/IEQ4j¥;–f³YQ.3IÇPÌôie1Óº¶l~F0cÏ$½o¼nãbƒøO¦Ãæ˜Ø¯U‘Ñ"¹¹¹ùÐCÇãg<ã[[[§N:{ö¬õ;€ªèº£É2f~(3°éœs£¸Þ‰Þ)¦_fÃ�@ÜdW¼ béÎZÏ©MÏ–ºšg¥!rALÊŒDã×âãXÔŠ; ÇO1\ ág½jã„í>wrö¹c9NKñÇOc0z%Ž^¾ÄKÕâóÆ~ˆÄ_Hrûˆ#çsŽP! ¤idQH˜laÔøÙÏ~ö®»î U`Ø\ahèÜ?Û-î ÐER¦ÓéÄX½Ø +++'Ož|ê©§._¾luíøPX–AËvè]3«7ëUYOå¤ ª­Ãˆå\E’UmàXÍ[”Ë‘†#�ízÛØÔ„¯øf¯×›ÏçÕ¥ªq{£VÖjµZÑ*'-L,´h&(œÉÌ}v"«Ëý•@f詘­eA4Ãbñ›<˜Ù™eµ’î*!2hii©ÙlF3)îX+ƒÁ J«Õ:sæÌúúú¹sç‚ôÌ¡[ÔƒUë÷ûN'x0ÇH –‰ˆE5cüÊ|29 0@‚¬r¥ÌeH#íú Aß'9¢H²–(‹Ü΄¦ƒ’ËÆ*ÊüË)²í矚É$3í ±c`#¾od2“k:9ûO•æaû0¢K%fÐgìj–£|1—çò)v2E8ƒ3j,w_¢ þ`skÎ5Óbxm6›*’ue€ï3-Œ’�¬w`8ÆÞÈfæc(„ƒÃ":ÓçNç'çÅ_/R-•UÙú`«vªV~ªLòð݈Ä’ìi¯6¥‡LÙZq|1Þé¤ýiâÓEªa fƒ$i¯éµQ¨%”,¸æðŽ€]øéEÆÀùèSÒ£N¤üñ1cè2Ê·ë8¹{Ùd‰k ˆÄW÷<»hÑfg {#Ä\çl6‹p‚ejä×~vá“=µZm0Dñ·˜ÅÑòf ¤½µ6ø`®FhœËÜÊ9n›mç<nXþâ, 1Ov{Â:ć2BÆX4IJÒÝ!Ó=æß$¯”Gà@®Ñí;Ýÿ/3âmG]¯×‘hŒçwäÈ‘•••'Ÿ|2H´¬ãˆC�JPÝûdRIckÖ¡1}Å€§ŒSE¢7“­fúÀq1�¾x @úbšÊ™µvºÝnV3+x2™Äd OnÒŠÇUÍ^0K¯KÕ´ZþË弜Ïç³ï›U/«ªÕªõ§-›¶YÓÚÐbFz¶à<GT(S׬‚ E០„üe¤q÷€ŸÏçqÇ?vz’Ã)ìÞXBÆ–æK{Ew´âaA­ôl™N<ëÖ=OÙÌZNU:=Æãq¿ßÏÖçød2ÙÚÚZ^^vȉíµN¬Ÿ¸ÎH³úý~³Ù  Ïy`æt†u³2àך„ü¯gט�u•ïÙZVO;ÙMŠÀòËÜ1²1)o+Qaxƒgùœ“EFeá=Á#EU+kçØÐë ä|ED¬ÿOJ¾S–åh4âTòë,ÓçDóx™¾yŠœb/B,@C0†ÀAÌA“ált’04 ©ààÅ5HÇÙ}|'‚k�5LŠ0öh;Äiiii0Xgî)Yçì…³Ú¥Zû7ÛEÚ1 ­ý~mþçÕ«Úû÷ðý®¸oœ³¨ 8ûj§AÂIaÏïìl‚IAU„Út’Årìü¸Ï+++7Þxãæææ©S§’TbÉ3¬MndÃG$Ñ"k DÆø¤_ž/—äGϨ¼›.´»x|†ÔXTQZmÏXPŒmöz½àAÐnìõzÑ€¬×ë£Ñ(*˜` Q‰6.±qññ^ÃáÓ€^iAÅ­‹·ËÄ�ÍF#S%Üæ†¸Ù¹gÐJ.SIêÔÜ7þ‹#5·(b€Pþ†¹*í=r©ÈÌÈLßw~�k40L^“Ä(“q‡‰±O›í˜tl8¡âÙtÎÄ$‚Tóä“O’z»7ê‚à Ó<f÷›­ä•M¦à[„Ÿ;±—Pa¢µëƒ Â~Ú5ê óA-eæ®gŽ$“‚Ò®o˜ëBªð«ð#˜ÏçxJZÖ:ITq~ã¼|iYÿÝzQÏ}îs_ûÚ×>ïyÏk6›í/¶Ó½iòW&­Ãå‚“ÐŒ–ãR5ŠžCŽIî½›‹£•îB,n5´…ét:OŸ>ýä“OšàçBÆü"ˆ¼þi]Š£vŒs\Ö3ç7ü¾À÷œ‰‹å-šÚÅ_ÅÍŠÿ�ENRøÁ`0=^__GZ¿^¯FßaÌ+ðƒè÷8~À¾ñ¬˜ùž—ŠHæ[—Í]ŒyméãÚ@°ƒM„`/ûuËDb§9»‘ËqžK”,DJ‚%ê×hÙ¹p:ÌÌÎBÙE–l·û¬1yPåìÃ(SZpÈŒ¢AÏ";£ŽFºŸïÜ™alÊŠ¹Ñ~ ˆ[PQ£×JåŸöL·<_(¸&°¯@Æ€¡ëãÒ´Or\7‘Ô4¼Ñh” åBÊÚ9AÊYÕ¬³Æá£‡_ÿú×ßvÛmwÝu×ÛÞö¶³gÏÖŠZm©FWƒ1@Ò:LÏ�£<]˜á04TøT àÖÿú0S<íóæbÔ.œ}™4Êyq6ˆJ§-::FÕ &Ň¥ŸYB”­(O“lñ½�J±BxâÐö-dÊÒK¤Gú²¾¾:ö3­ª*�ÆÑhôè£nllĺ¡Ý+^6�¢­­­«t ªG8‰ûÀÀrŒ÷fŠ5?»2ö<læ3 Uš Ì#–¸ZÄ+xþ”ùnNK@[°(§i¢ðñ¨BìýŠ‚†{ÃÑjµ—®Ó }ö ŠI&~&ޤ÷Ÿ±fØ„0ð´Bß–—úÏΩ$3w³­9Árgp|*J–ì5ZÍH× Ðl0Ú”-¯x3©x/£I¼¸k|»Å¥öz= Ü[ÏlÞcWGÚ j·_\­mll<úè£gÏžÝIÆk©^¯;v¬Ùl~ùË_f’¯eª9‹:¤|OZ ó8“ÞáDv (ÌŒ[#3†æyA’túê„C$®ù«^¯½1>#ÁÏóCYä¬"íU«³úkÏÍÖÛw{ÜN¦–%ÎZÜ%³Ùìú믅f ¼ápxéÒ¥‡à›Íšm+++óùüâÅ‹AÚvÏ_Nº5$I~”ñîe<Bkã%s…qÎÊr¬¨ˆpiW,*Þ" ~¸@n‘’ ˜Ûe€„€ÃÄ‘ÀÀx&¡O$–½»>^Hàã¼ÊZM!gB‰R6¹é/™È«*‰¬=ã¼#Æ¿íóaùƒ$£­¸ä24Ì©×òÙPHæ9íY³ltŽމ@¤¢¼LŽfÐ*O¼ÒŽÚéW=Þ¨}¡6yídíýkïyÏ{î¼óÎóçÏ_ºt©ñÜÆôYÓö¿kw»]æL9v tp«ÓîTìööv êÜO¬<­Ÿd‹éx§Xœ§ÙT¦ìh¤ ` ‹5ÄBð-KG’¦€3E”,„ø;fL±1æTuõÛ*ŽotEj2Rjšñx¼±±±ººŠk.œÑԉʌ'H–�lñ—/_ÞØØ c€¡9ϨrÖÃ]öHàA� N†Ò®Æ�²ó3ò BQ4ó3ŠJ¸�@ìŒzËnrdî§‚ íʃæô7Ï3ILñ§¤ç´×;iìˆÅÒÔŽÙ¶ü89ûöGy³Ù E&ŽûÌÝ–' ‘ÚŸcxRÚøåÅ^‚‰Î,/w/¬Öë5úü�kx»«¸¼¬ñkj2fqL-øPƒwD8ñvÊÔÆ8’`¦Á/ö-§FÚ+€d:Ö¦µÚ—kå³ÊÙ ³›ÏçÕõUùÌ2m§òËåý'ÀOŒò{ªÜ†o…Ãhð’<(GÔ^”öy¬$ÅnŠÄk¼ž ßÙv/^ °ã䋉…€I†º@›f4lj™iÄ êÈhãCQ±¼X<�XwYTãfræÒ]÷}˜N§çÏŸŸN§+++XìÄýÇXÃÑX"_ét:±�B8Îü{—à±}.cñ0 ?·|´xR‚fÿ“¸d&U~Ôå¼q+˜ív»AÏýŽD©GJÇuFÍgP׎Ô!ÈçB€Çy Å4*´ìŽŒëÏíŠÄâ äì‰ãÆi†§EÉï}~™¯ÌëÔëõ¥¥%s9°²ÑˤIæ¤ÙCjÜtÒ®Ø ¾x¼àœ8/:`F«ÆNqìLoB–uÄãìæÐ|†-JJËæ·ø‚5 «Õj÷vfß7›þ´ü“²Qk¤”ÊW—奲õµªz³ÄE«q“2ÛÏzÏ´p %òùùÚÁ7ÃÙ½½)×L‹°¬'P'‚Sâ¸Ë¼äuOÝB|Ï ˆI‘7  ‹í7R›ÜsÖ›3 ;VPúÄ2Ž:ÌÉ\s·¬'“ÉÚÚÚ`0X]]ÖN,ÚåååN§3I½ã-:Nÿ ƒË—/ÖŠ‚ŽÉ܈…S°² \‹{!Œª.аõõu[ :ËŒÿíÀ„WÉ+cFÉ„sªCë(ZlÐ!€5"¥iÐÙ3jBéf ƒ¹C¯ü×ÜWC£û8zrö|Eb<ÉFF,í ùÚple^:ÛOÛóˆ-ò\迃þÄ #§3bk|Ÿïà–hî¬Ó[³¿@–Ó^XÇgGÞÍóFĪ8CM §n 1úUUÕøîïu§?1-E£Ñèþ‹níB-µ÷È·˜Å5MT“ èƒ)Ùd«Õq,߇¬]ïâ¬`Œ´”òÂw2ÉÌ‚%dæºc!Hoy(–T1“5ù² KÚNjìi>c”n(–Æó5Ø�� �IDAT ë vQb¡k‹A$ÍχIn¿ß'OQrEÄ“Á`°¹¹'¾éUñXÍO³ò,ç2’ î2R‰Ú?Ê~F"{ „&+!‡¢9NÄ.=o+sJ).#ÊšTbh汜'eƒ\®mÌr»È�4Ž ˆT LðØ2Œµýÿ‚ÜBáiœº„“+ÉРï¶@€Õé©£±TòÑßÏJ¢$ë,zÑu€_@õã9Œø5$RâÚ0w€I àVè¢7À&gÃ/Ú³3†’¡Ž&A5úoìI¨Eô»c le°‹]ŠDY' |‚S6 ƒ‡ŠUà89Â’Æ<!t8½%œdR]iï´ Å”L*;NŠÍÍMîR Lãñ2Ìiîj’–ÍZäëÐB6´c„ÀÉñ Nøð\Ö××q?|øðp8‡ˆ„¬F¸ÑMA€%vVxyÎ?i5ÉŠÈŠúTüyhðÀT´‚´ñmV øªí�Ø×ô&ÙòØ\%Mø2»“%óäÓÅeÓT‹[ÄÔ¶¡ÌeչǪˆ^+++¯yÍkúýþûÞ÷¾§žzêie$BÎ~L'IØÕy%h†Qæl´8k°{rÓŽgžý̘···-èi  H{Ñq$jfllÃD–úȾm^z<$Ý‹Ìl€Ñðº6¨åA9ïU:Øq:¸—KH“ŒN2Ò¿4$(.•³?–.&ï²¹ú>öGóÙÂYÔÇdʈe8˜µ5“ì‡9CmTŠÄ$˜(P\˜§ýÓ^C0³ìòI£(¸ÈRgd5c¹×èú5ŸñáXrŽEñæ©§žânãŽAfàÇ|ë–¢2î±Ó¨œ¥…� —\|äXHô±ÐôÌÚ“Žj~Ž`×àŠÜð¸æ´×÷ÚƒDqâÚÖÍ„µì¾ãyX[~°–¸‡®’c!šÅëL§Ó³gÏöû}sµ÷÷ë äìaÖS¤]ÛvRxÎzĉ]•Óµ³^l&<d *w_¬|Nð3¡™RÆzn™6CøÆ¾Éþ"¨¸ç–yRϸFkXÿ?öùþ@ª'ΈˆO;ƒ fšÌ1År¹IúÄÈìçl¹Ë�Ä“¢š‰À&w2ð´$2 3㙜þä­¤Æ)’,b9eÌ ‹75m)î�Â3t•aÄfJó—躙ý‰3šú S‘!U'ðýϬùÄ?Æf=GÅð…2 ¶';:‡dTqñY1DÚçáWºiW-ü Ú´Í¢çÔ‡2% B¸ ™‚»›µFJÉ·ââ™.ZüøÜp`áŒo1†+ 9 |Û"ðß}÷ÝFc{{ª¤1Õƒ³Ÿ…N6ˆàAÎ =[d6¨M»ƒÄdÄÙ˜^FpËf*"IGÇCq0a@� É Ñu ´]WW�t4œ)5L㡼`KøL¯³ýA—³O2¶¥‰µ^Ðe±)uô„Aêøe®ÇìJ0OtbrHêºøázÐ=S�ò¯ûgY9E�^,Uoì‰ ½…|ºývºCú“çÎøºHY»Î5û‹° ‰ß&‡­y+I–†À>ö³€%qßZ™46(ø¢štAC¢c§g¸ò±H U‚bÙ£Ö,�[z€ßcÝlXú\'ž‘[ïz#®.¾ Ïvš7*NMï9ŠÅ‰ë)x½ñP˜`å}±]Í¡€Ó OëP|rö!äo‰Ü6*�s–�â=Å‹»×ëÙq=Ó'&95øàcš÷òzâä…!Š`—õµ¨¨ü¦ì KyºŽ1!'þ9#½lòøÈ4´aWglæé¹ÈFV-^¥alB˜¥¥¥µ¡£›é›³ µ…,‘ü ðÁ®0ö¡ÁêÑ£õp5ILyàŸ†zFÑîõzüâY ï¸!¢�¬¹9¢@RϦU. od&­v·4Ó/êQ«¤Ø ÝϦt¼æ¶²<„ÿÂN!W³ç æà™ÜpH1.e¼˜Ý+¥[èäf$…BÄl> ©Óð YêÎBª½_&=­×}ßÜ6RIn>ÜýLÔ�n«Kx?º|·5ÑAÈÙg`ÍF{Q¥fÃÌÙÌù縻ʬ?`"ö wätpdìGoÖ"Ô7±­ÃÁõ7g ’ pʯn·›‰ÖØe Æ•Mc'xÛZbò.:üYsý.ÆH™c«  ÷™¹-À>a®L1÷'º ÔI6âÝiã[@…G-l-Ó&‰A'Ƶ…OLì{vŠE° ç+3Fe(ãÐG±q*Ä*[†sa x&CæÄ‡ šó'(OG)c¾ë§"‚¹‘ΔOÆ·dþ4âpCÄÝ1ân°ê<•/Øn·gWÍjýÚèWFi9UUÕýÕnº'µo¹õiD„¥èhöz½$a'¸|>ÄÉ0L‰EKn„H¹O ŠˆîñY]ˆàm^mQºAe‚n ‘š,.ØRŒ1d2!çõ—Ó+W²ŒÀÁw²¤>ü¯2GC·±ÐgM¸ñ‹�_à³±>,VïV°=Ä\…-j@Y׌½Óî8¡·=í%÷öéXò‚ôH¸<S`¹r:·´âcz¤½3ÕléH{­mjM\ϱº5tfŽC<‘0š356>µC¬;�YóÆ¢^þʺ5\-xK„ÛXœÎh%�ðgeËÕ‡¯ ë`SÓé4*o7{ܲŽ|FYæcûjgKî?Áyq¿'Ò¸…„Òxd*»~ͬ7 w3mKªŒqšÑ(§&×L&ß7™^7í~w·5mUU5þÉqu[Uþ~Ù¸³¾-•.d„$­)×ñ!€Š6{-Sø>vìØt:][[Ö‚Æ›ÇàÜ¡1(giQ{.XGÑ¡%J|ûÈ™úo&B”ÀÚþ3Ö¨©3\€ˆV“½<9º‘îj˜ÚOöÇÔKÒŒ§mÜÌ”s>èÎ3mdKvbc¹3íÕŒ" ¤{ ¦çµK4"]Ùs¨£iÌ.âXád$/v·†ë±·k{¼<Ð�ÂÅИ¡½=ÅbYbl¨öp½è^7ºvQÃá8ÉÒÑ<¨L-}B Ó£!YM†dö³¿âä3ózÀ2•T×nLÙs7;c– ¨rÜ ¢V°P°G�9ث…šÌX±8úøÁ™É9}Á´Ü.—|y>Ÿ×ÚµV«UûÕÚüÙóñÏŽ;Ÿë zç¡lÇf×…ñBv:€GƒTãñ¸Û톬-?ÜÂîD M7vÀÊxöàc^ÀpDÝ•ä0ñEFNéš„œý™Ë±¤‡™Þi¤‡z@&Üì_æ´…%‰«›éXHãdªãIû,>BÓX)çí¨½ÈoŽ‘þ£ËÆYÄÐèçCŠÃb‘jœIÊÓûI{5ói#sR€Ä©MlâËz­&þšûƒÈ5,)3Θ,¡ñ`<ÝÌ]¸­YfÄ5gVT0.P˜ð üXX%Þ%†%íJÌ–5©š`à™A²> ³3"lØr4ƒYQ4‹Ò|<Ï›tnl:ˆ(R£—‹j8šOlYL"ºg•h¡¨¬”AÓ.óç-˲:^Í¿qÞýån”&ˆJÌ7?Ó,þJQ{WÍžn|¶ÌX òx€µ*¼OC;#Óù6BàâÌD»˜¨ÝÚÚ¢šöš7¢—òä ‘DZF¥nùsWZ!g?ã ‡‘5ƒ™°«Rl¤PUÂjÞ‰³¡¡Øc–ð�<+�M\@˜,±N;+ä)ŽÌ˜À玙šô 2 Ä^¯éq‹.B„4Zô>I3….޲N¢Hګ챟{é´L]‘dÔ¦±QAœIR±#o5óÍc}™úgüä²e½–Я¤'ß4e‘ lFƒSìÀå¥pu™DƒÎÐAÚ¬í‡HÈ 7Ð)ŸÉ#¦!øSÛec¶‡zík_{íµ×~øÃ¾ÿþûí•n_€èhrD¶mHGV¯qfŸ¶Ní¢8R¤3)uÒ‘#GªªÚØØh4íy»Ü*«k+#ÛKKKøåØû.³GMfö,GÏKX¢&=J!ã>pdl*˜­ü¬HŠ»dpú%¾Œ7Å×x<öÓ?9û¬Àƒ©�X aH/Ú ‹¹¬ßëŒÌü"F¬­e¶IÛ y†w àÓ³ÍdÍ2Ÿ,³(çã íõz±E½²Ý8Í /¾e–ïà6¦]cLsk$¶þ|X}œ†ÁYˆÓ0Nü¤!vßÿøÈ0=ÚÉGêe®-Ÿ=ílH°ø † †q b,võZô=Išrx“ö*[›O3Ó ¥o—éûY">oœ§0â0åM%bÖBqÉÔ*XS€Ež¯äæX¡ÃµZÀS »ø•eBTÛYW€²FŒ0–Çξ+ ŸæÈù°UãÐÇÇg# ¸u †gd÷Oî'»ÆÏ(Œ<¬„ä:ÕE$µÈ‹E¶ª·]·ýÜBÎ>3À:8b8e8œÙ%*Û.¶(}¥]±5’hã³™z «+¢`’œE½ô˲ ¼ŽÃÔý³ò˜Ëc²¤Ýn_{íµUU]¸p!ê6"™Í}ñóp²Ih± .Aˆ‹w+IÄ´ âëÏB‹¿ *QVâpFd „Á«ì¤ðÓ ù8j8Ëtf÷œhŠ’&I±Ç0Ѹb´ þ@ƒá^Šs£3XÏgÐ*·î_d?HéûœY™n“a[|™33›¬(OÈ’„ ƒ}èC­VkssNX–»)™é€“žÉd.íh‘I²^a`^®Õ>W›¾zÚ½£»¹¹y¥?zM½x^ÑyOÇ÷ÁžuîÃaÚÆ)ßY åb;ÀFˆÅFMãbÔœ…a—ëñ8ý5×À|"}à7æ×,n™ƒ³?ñÆ»‹ó£$0›[œ‘4<–]äƒÆÓXg–Å÷“3k³Ž^B’à&‘ÉX„1,³¢–â ˆ;ôÏ2ç#± V´É Q¿Ó´"²­Ã"4¢˜ÍÇ1ÖŽˆºyzð §“w›Êeî€o¦ž‰î ‹Àç‰ñ Û±dñ82lÊ$‹b›“«Ò<Çq ­ùH3!VÐ��#%IçdqµÍ»0fàÞ2_™[¦ÃMÆmd/K¿<ô³M›H²PŠ„:ð®N§ÃoBŒ×\[[³z&^¦¨O¯Ñ/ŸD–ùKeÎî±àg³YwÜ­=V›¾pš>˜öLFNÅ3‹ÆŸ7æåœ§9ïÛh4¢¥j<#-8ú›Bi¯P!°õ £ÉÞÝ]^ìÕaùÁe*J<|%JÒ_A¤5ÓI1ø³i`̇b e‚#0=Í7~Qµ1™Õœ]J Rã€#8§°¿õòõhd[!ž¼Ò´+ˆ‚»ß‘³Øæ ty `–ˆ+hã3•o·R� AÚÍXCžœϱ?£©Þ,½cfè¡vS%åœN§£ÑÈy%"7pb†ÃR7”ˆˆP¼Ækò·AÆj‰?¤öu*ŸÅgȹìIÇ(î¨ÝnCý0Ø2œ‘¾ÜÎŒ…ÃÀBJ‰³Q3‹<†K¸ÚŠ`ªð}A~@ù2Ò°Û3aAMJn7XJ@Ð$6iÜNÑó¾Öô‡¦ÃÛÿ°†©¨Ó¿3­úUÿ‡ú™®Õ©©ÞPa CŠ®}P“ìǬRÌT; Ø6# ïŒ]»8'H‹É2­•g© Ì¹Hâ$�?9ûù½Õ|0*tšç¶Oå§ÓC—4ܺ˖ ͤY2qh‰L¡„­kvTcC=¬àl–‚­žv%¥‘ s÷›q<³¡ÈÄÝ„pø$-ó7«ôm5žÎ¥½Jõ´FÝYVÒÉZ¦&² YãÄî ¤i×'hšO£Ñ(:^$×™Rà«Áw ÄÌÎe+ñ@CV5bv&³Ÿä4±½½Í5Ï_;¯®©æõyúLj|©‘qëÌ]ô¸» &^é÷ ‘öbfʶ&õ1ÙÃ5£1’«ñ‡Øáðʈ¼Þ™ú”תõxv´>ßÞéývoøÏ‡ÕRU«Õ–þõRúbšsÚÙ„bMs·¬œajºknøgµˆÅñ#bdÄ­Lƒ~žG—Œ°y 6í•däÛò.žlÀÙëAÈÙ`-Ã÷9Mì1eÔ‹µ˜)/™6C±âž6É‹sà„«»fåty!ë$àÖ½5§#ˆz8_¸ªÁua›2y¸ÊMÔF´q±xA¦%Å/XTÆØ£ÿfì™ÈÓ#WðUÙïÄ>î-v㙤¿“öÎçZÐ,€ÄøDøÊ$ÍÛfdnòtZÊ#÷qiƒK¯±ªªÊ—”ã¿6n>Þ¬U™Êò»ÊéÑiÿgúi¾Gä‰Ö gmz¤Éª²½ÅL&I@ya CsAMŽYi¸‘ý8Ób§„.FÖ154ärÇÞ¼Á-ñ·ô³K�t³jf±ÝL£!~-P@VÓ1¡áÁ´w¢†… žØ…V`NšÇ±­¶•éóFí•!fÒ`'ëlq{rö“$p )z*Èæ{`Åá!IÀq±g3P)h©®ÐÝÛ0ÔnRO)[Ƙ@&/M«ÓãúH#>í)}ú7‹ð4°B$¹hÀX“ÛžZIò…öα1 FŽiö ü“)’ü­„´Z­heå,~3¦M“CиâÝmØ… ÙÿOoÉBœ@%¡ Ô ?;g�k™>߬×ëåuåüûç˰\ÜW¤­”Rš?c^;VÛþõíÞßìA肘9¢fª<3[‘šåa5UKQîáÁ1úŽi³Ù\ZZ¢9‰ùôþøžÑÒcDÁMé™öJ±Ù];Ú Àà¹b* íu¿µ)ŽÍØ ‘ü!‡Ã“²]S¼‚‰Ô@60H3ÔF�cc³Ûå¹Àø&tQzVÚÒãI²ë!gß9!ÅáIúÀLÀhîsX_ÏÐ*yD¨ªøøA±&~'Î&Á[ªË7YÒÇfÀkê¨*Úòô·„ŸÏçEUÔ¿¶>~ÕxûÛ¶«ªjœj,¿m¹x¤hl4ÌíÎ*›$­Ü¬Õ;!a@öm|3Àz|<-Úg}Œp¢$ligrÛ8¯y‚I ”SF"›îõz”Œsf#´žâSPpsb=9räÆo¼|ùòéÓ§‡Ãa\êh4·‚áV{i»åËÿ9§šÍfqSQ»\küF5¯ªZUUUç|§z²tåɲ}®m↹RdVÆs›ѢângÎ:ô8ù&„¾Ié‰ ¦ÄáJñ¬ƒ㥕d±Ê3MÑ“ÑÙ.vC+³ ¢-I'„V0�ƈ=ˆ½“ýëÀ0؀Π­@“ö6fÎw&ô`°=íUŠ2 KK@@°db”MÈîïa{r®„è<K*S�¡9(A* —x$-VjLìg‚Öf†cF’ÎÙdüSÀ¡ÈÁ ¿döy¸Â:tÊ¿õF‹¢˜}Ǭ¼­ìý÷ÞU¯¿j6›Íž5ü­A:•:¿Û© k %dú–É’ö f|QvwüÁÓãìXâ‡+Û8Fs;X³ä§&txTÅÆ¶ÍfŸÇt:½1�Ïá{VÔÒœq:t蛿ù›_÷º×=úè£ïz×»î»ï>²~?;ÒF_ãã@™cíÌâ2?7X¾myžvüËÃÜ/¥Ôúg­ñÏŒ[·E²ìœ:ÉÍ!³WðÇÌàM¿Ž5üY?ðh2de±SqeѲV3xÇÕØt:]ZZòβætD2Úà”Y¦z² æÁõGýÞ¤YËL@›°ÎQåÉy ‚dsKiÁ6BcÎ&§=’`§¿$ °£ßÆéD½È¼QÌ9Y=9û¯^;0›¼ÛG˜Gâ´^“ĬٞY)[ÔË‹  ÉB åÓ^·€Ñ• gÀàzÂ%‹0ú‰Ññ¿|¼ÕjÕšµz½Þýr·ùÓÍõ__o]×j>Ú¤Cn [OsíHiíFµµµeSÊ/ÜØÀý:JBhôòûÙÞŽÞ�Å":lå± ´é¥¥%ûŽ AKƒSÕ†(î3eŠ>(=zô¥/}é _øÂ#GŽÜu×]_úÒ—l²@íia=`Õh?$y-ÛWf6›UiçŒîõzÄêõzª%°J:ü˜wYy ¼…µj™H`¢ÙlÏ)ÒE (ÉzS�à+H™$‡Œù“gb( ˆë)ÑTok;Á\0¤é¦ oç•쎔9o—2s ^B´Úé!Y(5°larOIû¡“JàÌ”·ÜZët:qìDUm[æÝŽzrö3ذ¬³ê> ”'Nœ;wn{{»V«•U9ŸÏçÿç|ò“”Rëý­ÞÿÓ«ŠÊP´Ü]Ó°.ÉDÌžrQB€ 4 ZwV,žOƒ÷rŸ6˜T.\ˆÌÌè.Œþáhù—–kµÚ‘#GŽ92 ÖÖÖŠ¢XùÅ•­ŸÛ:öcÇœg.È4™<ÑFX…çõ¬—ãZÄRÁæ ªé´‘ ZÒŠ“]º³RTEõ7«é÷OçõyóSÍöϵkUÉ'4ß8Œœƒóz½žB/•ù|~ùòå{î¹çرc§NzôÑG···3Ñ<ì°趺D<À“8š'“ ReYVe5›Ïšæp8´ÀL£Ñ˜Wss+<}lÔ×,Arj³'�uɯ3o1÷)3kÆîê5FhÒ5 þ}ø!¹HÂÐ2H1‰ì]ó9ýYâ'³õKˆüf6›Å¦ ¸2.¤â‘,…"ëÀÌÔiwwv?€¨€¹ÎúþÙ²l©ÓéšëßÜܤÙfo²Ò§­/BÎþ�kæ#Ú›$œõØÀã׌ç?=oýj«ûên­V+¾µØ¸}£÷k½Æmܧ-A{t7g|IbæäDlç,îd¸HgàܵN¼iü7w’»“eûƒí'N|çw~ç+^ñŠGyä·~ë·Î;—ΤâdaJ’‘±Åa#}Þ="œ=T⼈n8ºÇ˹í® 0Td±��+œz˲,_YŽ~aÔý½îê7®E1yÙdøáaë7[íwµÓ<YŽÁ´+ïmƒ~ÔR‘2óìÖ××ÿøÿøŽ;îFçÏŸ'ȳ•Ž‘;تp¹Æt™ài­V[þÑåñ¿7¤é¦zJiôë£þ­}Ô̘¬÷O»JÆTlQiÙèÓ³÷dKÐÙ‰(Q";+pFŠXîG0byœÚ‹.˼ÀÚQÄlVu¦ÖƒZ Ã4€¥qF‡›_$&ssˆÜTáf¸°ï̃È>x\ù ÆB~”i5Á—cAÆCŒ.”}У3ÿ5Ÿ):gfW„œý$IsR“ YÊìâÅ‹¬õÙÏÌ–o[.Ë2ÕRY–Å-zïîmr{é— B…2 #iFr½ýL³¦‡io“ ¼¾mMŒgëÜ ê×fF,C�GŽ9|øðêêê•Öeª2¾µUj˜v„*cÖMœ& OXïÄ Å• Šî¼E½6ý‘Ù·ÖµÒFJ}0ÐáF¼pNÃÁ[ýW÷›ÍfQ)¥Ö§[­[[ãw;ê46Ù-ít:‘»„Ê”ôŒíXücc#¶=ˆ™á¾¬½—ùHº"޳h­V«oÔk§k“ž´ßßNO¤”Rñ²¢x^Ñü“f6Ìa³ 47í'm~`6ñjo4>{”ÇŸÏç.\ˆ5f¦cÅnœ¿ Ð̆HlÒ³G<¢DÈ–â¯øl¥Lñ T\d ‹Ç?‚ÚÂÿŒËÀØ�`/©G©0Ä!Ð-¨´×ås÷œü¾Ž…Ðã¡ æ`ã#„“É$uáò@§ayr¾"Fs‚¨Ã@–ÝX©ãŸ÷~µçžjœ³ý·ö§?3m½µe#™ ;ÌÄ"Íž¤Z‡”âe» f#,>&è{“‘È_Q°~g{ë»·.þ«‹ÿøÇÏž=ûÈ#\¸p¡V«¾o´ú«°Ë0FUÁ6œÒ‡UlwHøx :iW}ÙÓmEQ”ß_–¯(ÛÖžÏæ©žfÿdV]¨º¿ÒÍÎJÏÐÛ™ÿؼ÷[=åÄ_u£»ýcÛKÿ|ÉbÑ…ÆÕª/N5iÊõkð�­­`±»8Œ²~rÔ‚™¨‰{øŽ£åù²óŽNñÊbòw&åJYKµÆãú“õö¯¶-%™užl’DŠäyÌ sCNùXUU¿ßñ‹_<ÇãñÅ‹=ò7*›(ˆ`ã³Û]4Û|d¼È'77™Þ0‡4»_›Ø‰ù¨ÓDSÿšë–‰‡n]6Yª£™MµñsVˆ¹éÙx–AQã“&ú›F„(µRÝl^tü;9ûoÈ}8€€Âœ‰¹XþÎå²^öz½¥¥¥ .ìP*ßS›ÿƒyùKeðsȰÌVÄIzq‡Û¬,¤ÀØç$ž‹ÃüNŸMÍr:ïv®‡xÐødcú ÓátxÏŸßóÀ ‡ÃÙ|–šiòu“«þÍUpù3ºQvRXLÞ'8'µ•ž]@d²ðW$ß0ïŸè?û£Ï^>µüðÇÃòƲx^±ýw¶;¿ÚY̬˹gD—”ÒìÖYç§:U½ZYY¹ñÆÏœ9sñâÅ”Rù‘rüOÆå?- wPB-nNÂä8ˆ[6›"šmlN9ªS`´Çàz°Ós~¬Ö|¼Y¿¡^õ«F½Qbë%�� �IDAT;Wk¬7fÅ,Õ¯ˆ³‘Öðb•òSÒvÇÔøh¡°`àËFœO>ùäåË—#¬Òó°õ-Q—q«?X’.s>ô0 ekd]q“G£‘³.;<Ra™r–ù.­Àsþ–¹´ò¡©‰f?M§Ó¨<B¬ø.€MïA&{`fc`ßù¸NSH'ØëxüÖSVYÛÕ&!gŸ{9t)Ù´%Á(béÏf³zU'1ÏH‡P¤2‹È ézÂc>Ÿw»ÝN§3O4QÒ~�ñ‡´±|f\æŠÍcf×ú¶C—þäÒè®Qïö^­^›?s>øÁÁU¿rUíáZY=ÀLL†“åÑÛ_ì[.!*Hăc‹BH£z¨ªªêWÕÉêøàø÷¾à{ÜzäíoûC=T=V ÃòÅeíx­y¾ÉœG¦ä³Ã f£Ñèv»'Nœ¸té’auuu0PÜd•ÐÓf'¦2ÓÜŠwït:èÒ3ÿ+D6ÁÊYO—‹¾m“èxíq)~¬Q–e½QO)¥z2¤f]>»\¼ŸÍüûlÕÕÕÑhp“K1*­íííûî»Yä\aB{]™ µýLk¶²-Ò8ˆ®’Ny™áøžÆ’œf¬"jÍV%*{2)~ «xc€dQfifl£à‚zJš15h¨Üšµxv,Â-Ÿ6EÍêy2u+ëûYê0Ö¾"k ºŒ˜Ö¼#ìøîæôÛ§­ÿÜŠÓ“mö³ök»È4Žý³¹p¹S3ò2ËŒzlÒ‘[Ü™í ¼#´ 3ñºFc>™¯¾v5½: ß0L)5kû¶cN§¨H«eÙâÈÊÊÊ5×\³¶¶: o«þЗ‚D¦ :¿ƒ’ß\Õo®Oß2½ûew÷z½ÐœŸÍfí/µ§ON·_½Þ±ƒÛØM .5LéAÛæóyëC­É7M–þãÒÆÆÆÇ>ö±˜e)˲þ†úÑO½îºëNŸ>í| C%Fí£ò ƒ¶"gW‹§™Ák¾¥Q€È' Û:“°JCõ¾á¤Ì¡ZÕ˜™*’±¼q¼ŽAÓ1^4 „е ¼ƒ*+¨œû€É^®UU-//WÂÞÒÎÿâ4§&³æÝ#úFív{8¢ cA)Ë5YŽ‚œùi±Ìk§”7Å€ª"9&PDq‰‚‰Ý艾á€ÚªËºz@Î)c. 1ëUs©™âcmŸ¿<nÉ£"·r¿·ó­nµþóÎ΄ö3ù»“Õo\-Òži; ^úf§0µ@bkŠs, wÈ X#+sPòÄL #íU £#Úþl»sçn3¿V!!Œ².àqbŸ_uÕUÃáª%3U³“1‰LÐåZQUY¥”677?õ©Ou»]L kµZü(I~*w@…áŠSòï´¶ïØNÿqçä⪆?4\ùû+ç6Î@QtPî1ˆEaǬ½ µ®£ï'øH~q4ÉMLñ ÄÆ ÇV,uc/ãCs<Yù†ÉC±{‘̃;F›Í³ +BªÇf—&¿8xSî€WÛ`QoÄ*Å÷æ=‘&2‰l_˜ÃÍS?ˆÊ)³m¶Ûˆç|©ÜdzIÒ·vWË>l†Ç£`µXb6ŠÀÜ+7P×2£^H/J¦þ¯ƒ”â Ÿ©ì”°Ì©ªªõó­Ñ'FÓïž–írVŸ_7Þ¾c»÷¯zžüJ{ÅQ2øŽrÁ½ãWöYô]öP^´ôƒô‰ ‹4©�e°‹eÒ¿y2xÜ¢×Ĥgìpz\Õ`0øÒ—¾ôÔSOñM€/î- ¡Ø½^/ɵ×¼Qo”E9-¦ƒÁ`4 ƒcºV•©¬WŒÍãh³.QÜÎOu6?²Y¼©([å$Mf·Í¶ïØn¿³½ufk}}=63æo1ÁËkÆÅö3!¸‚1L¹Àî&E†{\¸¥0Úbh<;Ck\X3óïÆ€ ô~¬Îx8¹¸ÑRBÑËšr¨®Å 1 †s3N^ÏTh…e0™LÆã1ÖÙòf‰fÕ|ðÍBR(>,ºGÑŠï,//£K/˜õ–âƒÓƳ£UYcã,JÁ›`ß±%Kä£EªÖP˜œúÕy퀲Ù­,î3Öàæz°€=c”!7UÎ~ÒÌca°o. JÿÓýòËñ'ï›Ôjµæû›K·.¥”ÊZ™é÷™&à± ê\OšÓBŠºè*MF%9™K”€3®Ê퉂¿€QÄÈIÄ¢ªÀm>Z `@°šù°1óL¥eÆAffÃê[ç:wÀë?¯·¿Ô®~°*¯‡W_W4ŸÓì¼½3mLA'ÂËÝ~¬à?(²tÿg·ûMÝí¿¾=zϨªªÖo-ß¶¿<-¦ÖD1m$NÌO�'f‚›¤Ãl6àÆÄ;GŒQÛ¯¥lý;ºŸÄ0²&+ ç8ñ¾ˆèлrÑãbt\ `e&C8t¤]õU*ûœ¸ÉVŠøV¡†È!­ ð0‚9m4([ ùZŠb=ùeÐý)à -Æ[³(˜â²N,z›1“ `;Ða…JÀëŒÇcª(›(R‰ç2¢œ$ø‹¢v\p„«�ó]"„œýlç¼þ˜®Š³EÐíÛ®ÿësªHEZÐàs_çi þ±Ú¬Wf)N7­3BA¦b‹Fz¦fg §¨F£íÉŽ…Eš§YÔÀíY‚zŽ¡Wà…¸q¹tÛ£Oõù²xUQý­ªó›;I_ñW‹òeãŽnr[\ìœùF퀄ÿ¡ÕýýîÎç* ·g]éÒØGû9â1ö2°%•¥S †c|¯’Ι´0™>V­ŽckœÐ€Îë ”Y8›—œ4¨h)?ߺ¬{Çm„ò€À%KÔm°Œ¬{±Ëmå'd ²ý’Ù•²æ¦ù‰SpD¤±ÐÒ2i¯$h ‡qGBfõ3 mxÎ&ƒ+YB‚N2Îfõ¸Õ棋æ×’„’ü¹a¥3{DñJeô¨˜‰¦pêBÎ~V9hÏdÉð>ÁÊLä÷à›i”¦ë yeÐ,^Äûß’Y¬2ûÞ/úó@+™Þ(Ñ…ÄÞu·Çë,N¯Š×†¤‘W1ËÎSl7oMªa4!Ф­~g=•©|N9zÛ¨JUªRý3õꞪù‰f£Õp¶NæÛž'E6‡ >è’2^¨v¤ô#£Àe^pNV D™¶ ° ž‰ÔEþNÀ'¬•ܨŒ‰s¶ž´u‚o5µ”­¯­‹Á²¥§Í앞ö þs "¦¡À|‡Lwǧ-Û„ì>ØkÎÕl îrðiƒ·[&Ne¨½"üÄi;Nc%Õ̸^îlñ(ÙûÞ¹¬½˜Wõ=·¤E�n°òœD”JR‰54I¿ŠàGÑœ5œ¨qã×à:úಬÔAÈÙϨ“$ùn¡_,Í2Æq Ÿd}Á¨ ùš„_;›Í–––�:PR¡qšu€2k/®tÈfôãòb,€NŒÏ¸´ëëÅùHòîèâHýLd¢`rSÔB¥ 9 ™Âd#€µînÕþ¬VÞSV©ª×ëõÇêÓ­i½S#rO÷ÜzE¿$N™lœ>óÄCy™_ žCbÿ³Õ˲ì÷û.ÄÁ1ÍgÇI(ËÙiN�U‘1päEu‰àËÓé$7vãλò6}ãi‘}[ÿeò?vŠ»JYœyÊ6訛s 0úÛ¬Š2—!“ûOv÷‡Z*~´µµ ßï‡Ás¶xÜPaT6àuVD¥Y˜í>Ãw–à öDZcÇÆO<Á†â”/fó]B’Ç¢‚F\`¦Aˆå}0@|Á™ÊAÈÙŸxÃZ 0„Þ>ppÚ+¨@Á¢O(ò$®µIè²óŽ-ʾ"êÄïL&_gÜg€§³ˆh‚kíÈFQ@Û…â™ÉÏdê#ý~1cM»“†¶¡#í mJn¦Û‘o¢º(NšRª?xŧjUt•’Tª((™@$QÅe2;UÆåq–Qáцá eä"ÉA¼(Š^¯wÓM7]ºté‰'žÀ‡u5rOʲŒJvh€AhL{}öLoÍ0"à8l¡™Ê>8oYfÍmئ‘'EwÁäæ4³^´ñ4j_"«77Pò6Ò Ã8þ7ꘖI®ñã^ñþ<U·ÛFˆ%fÄ<(£8¶™ƼÎNÿo¯Qlu—ù°Fãk¿ök»Ýî‡?üá! Ofk3}È-ˆ"!Nj’ÓÐL™>izMÞŽpröƒ·'~d,&:F«2í kyAÉw‘lr ŽûWÆ[G!Exc¹ØÎ<Tw2üY@Ã2G8fÝãLáLg@ÕgwÐb±B¿Î¤B³ùÄØ?LáseZî„1ê-ߊÅü VU6{DË-£lصÚÜë¸l3ªNâX§§ @Dd�Ï(öc=ƤQ¬Ïë,º4F€1 ™Ùê ¦À¨ eùÍ€ÏÆ,,ñ�ÄÏ{e~KÒd -úøÅ3hËL mدŒÚ…ÜSŸ´Ü±ÖuY#i&ßúª<8ê6R4'qd#)mÑ¿E„6“êpÕk‹q× ŠžÁ¤Jûô§?]¯×ƒ£o‘làMwû Æ!Ÿˆ²âR6$4·–dÔºò¡ØÕg!gߪð먒LhŒ 1|ÿ‹Q®åü˜Ys×ÝŒ¦+ máÂÐÜŽvKܽ%Ñù4Îø îø¦¤tzݽïv»(Lc/èÖGPŠ3D«VÓ€3*ª¸·Œq¸«aÉæO¡$eªS¾'ž6°1W¦]h0ó+DÀlïæ¶£'Wv‹<=ÍÙÍf—/_öQe@44‰Æ;ëÄù…²Å–X6tªâà¶ãrFÿuÛ̧0Ù•{×´ô02õƒôt‹ÅU³Üx`{{›b‚·pAéId;ȱÜÛà)Ð"Êj8«Ñ°ÀðŸFhó̰/€Å]4pÐs…qsÜdžvíÛµµ5ƒÀDzotáβwÇN%Ý 2o7¥´´´ÔívƒA„[:—JÒû?—cUA ¤ GN§Ón·›ÍÙdLr)L6–U¸&eÅ/g8 AÂòkI¾XlãÚ†¼ùý·&ÞÜóŒ[¯×;zôèÚÚ^ôà >¤¸þL~ŠïÀnÊ8âì%·4ñã2oн%7<Ø„™§ÿèœgs¸™‘ ]:3My @‘ÙLÚ«’ ÷Ïݬ-´Êù ‰ÇDö  ÓnE$)_$IÜ3DÁÒú™B%Æ 6²³’&/HÒ`¤ËdË  ­ÀŸØnÙ™u¦¯�5Aˆ(óuëÅ[fq¸’•ÙívWVVb‚ÇÞwÙ½rBÉ£ÌDäs%jÊu``}l[›õÁãw¸²kFæ+d2CVã6ì:ÍfóСCA£Ïªùƒ³ÿUŽÇ’8޵݈(oéÄrÇòãÏíVÀ¨GZаr‰ÍNƒ>ÀYL½ïø—gÁV« ’Xú|:R-ë¡ÅŸ:t(æò˜°  Ü)[”)KKKN”G©­gC˜tùï ñƒ ¨ ¸¹£nf6LJAvG;.†Ú4L¬±{)ž[8±ÛG£Q´sp’æN‚ÝqâS Zñuó£HŠM-±Ó ­¦È3lcAŽšÛÀV\'•Jü&c¡Bk)L‡ç´×*"> 2Ø4Z(1ãž;%©—2*�Ó7íNž’™a¥“¤:4„g;ÄØÌF«±¤Š\4›ßš5â#Ä<2-Dð2®Ù˜Î?b;oÂÉŸíÞ ãþ€‡­Pª¢È<L’Œß > 3¤ˆ½0Öö¿Êa{{…†6“¬›HgÜdzm&Kîr¬™3“?rþr^V†ÏäËÒ^‹u–¬›±@Ôn©•”Òx<~ä‘Gb?»ÉD—ØC!´—ùÔ®9²lÖªI»òhlÅPç$¿3¨˜i0[»Ú 7ói…=8¦3ÊŸ >Ó躱*âa.!­¦j"PlïøDœ¶üÈù»7ÒU7ÌLK# y Dû-àdeVf˜cf*>T s‡­Ö“%gÐ=,%žµvÀ \G 5NῸˆATJ S€`F0x ÎIÑ<ŸÏ·¶¶èñ›`kМ“±Æb/Ч1gÇC„ÕøÈìc³ä[ÔLi×·^AѬ½çÌÀË8³¯ö¢Šå:ÃËØ¼ÖÅðAÈÙgqˆ(ñ®µq!¬³âŒ5@9PiD'Ÿ1ã2¬ˆ ¦o¸�|ßÎlÎzœ$ÚcÊ™TtÜ“wÙΠ"œœï†]¢³)ÿY\´7dk¼;ã‹”D›óËç£O[Gkk•zŠ%íÕëŒsÊÜ�™k8øÝjšÙ[fÅ3‹”RëwZõ×ý:qÀem'w8V\Uó}ó=’9ß@oãẅ³Ñ™é”™qdNÐë͵…’磾ü9•Aœ¤ñàÂEé±GS¼8jA5©{bßJ?tF³à—dX¾(eææŠï­W8kÌõ(YX0Ã"Ó„ D ž[ ÕÌ#§;~vY0cAB„aÍ�x𸡜˜!å…ºo'íA°¡' fíÒõju™v»Ýëõ¨ý½£2ë$ό̋ ‚‘@ûq�ÜûyÚ<%²øÀÐØA&f·Ç{e#èþCäÑq=¦ÆrØQ¹“ïqgUî“Áí!8¹µ�§Ž9lµ0W& Ò6G! ˆn·Ë¹6¶’Œ;#_ðØ@d1»Ç!^UUj¤ù_™>1jÞÑ\ú§K_è̾a6úبZ®`Ÿ»¢R£ŽáÁµôå>M’×C–X ßÔíB$ü°ê¬®„@Ž»¦ZYzÃÞ_?³(ñÂÎÜv¤XWž?ªšS•· 6Ä.‹…>ÑÑ<´À!Jõ”tÒ¸tF1ÇT"~ÚëõL•ÆÔ™A zÏÒã‰<Œ”÷,Ð1Ç•S\ƒõ@™úâ](ïèþÆc‚bc•?ÚŠN'ö‹ åÞìûˆ­T9ÉT¨â•E½]ŸÍgÍÏ7››M+Ž0çØh4Nž<yäÈ‘‡zhmm-¦fwÅÊåÇP…ŠQ €àXÝnw8&”rL{Gq$Y'ŠA6!çEø¸„ÿ[ó çE´9Ô8eL3"*w3C¨ÉC ‚ÅqÏI ¥E>ŒRÆÝÛ$ &É>ZŸÛ • ˜¦½ê™ôQˆñ“É„;Y?áp>Ÿ·þ·ÖüUóÐg«Õj©L½Ÿï•õrü¡qÿ›ú(4¥’Lq"U÷”U’æ&7~­FÌÙâðŠDÝ Ny Ÿªæ)ØåÁúâÖ‹8+]1ø¡xÞ+SÄð̼$]L¤æ =ª[®!€Ö8Çoºé¦Z­vï½÷òS³6œ¨Å1 / ’0¨ÿ´4È‘±ÚœÓÄC±¨]üÕÑ£G'“IHÐb„H´ösÄ\ŽzÚþÙã\7Ž DiùÛlûpKòkØ/lí äìò»^1O/Ki5Õõ¢(ª[ªùSóÖï´ÜÕ�XZZ:~üø—¿üeçò.ÏY­Q‘4ò˜à®†ÇDyóÀšE| 'Ñn‰cœ€]I"€\C¬W³¹˜±wàd¬„„..‰û`^¯;v|ÀJ\‚Î�\žÃà„ò¡nÜ7šéó'MÔR”¤]‚‡Í“ævm! }ιaÜɸáãÛÆµÔàì<‚To|¼Q|cÑøH#ÓaL{¥Û|‘™Ò¥ÝP¡7wŒƒ>íz±øà�´ä¨ŠgÍ»ó.ñ¸yd–)ÁÝŠçf¤GW´Ô”dfWÔJ’€2YÆqç'“ÉSO=e‡\£¬Á_ˆüÉu�(¢ “ Ø8ƒ¥eLÛ²7úš¹ßºGµµµEHc‰?”IYÀÄl„_¡tF’DÕ˜õzÙ›36nBD¯ŒahG¯Ìƒ³?_å_*Ó«Rû‘vÿ#ýÚ¬6§/Ï.Ò§öÿÛÆ�0ýÔ©SgΜ‰™‡‡!$+¤çÁöñ.ƒ×Ç mRªœlº“ä…*Þ%¿Á÷̃d‘–">ã.þ¾–óñ q–¹`·ôµg&œ™…Il$Iî<ÚmƯæ;ìèn†›O‹\YUױǰ0ý¼÷Ê^X>_ýõEQ<ñij٬}{{üÝãÎ;>g§°X‘ý†í)±!]æh˜–M*�S€₉SÞ*gfsÎŒãh’£)nµ4:‹ôÕ!xªš~ç#^206Q24i"¾yþüyž©öxLì&‹Væ%BX¿ÊîJÔÙÞV‹·ÔtmX£q÷"³ ]Ð1I#G´û»g¤¸±ô„ü´<ʇ²Ê- (x8‹™D'“M:9ûoR¹yt³9núС“'O.--=ðÀƒ»Å…bôS£Z³V›ïq½ Á|&4�—=ûæÎ¹û(‹D�1½á–¦ÿ<[»>^9Á›ùM6d’(/Ñ”–ÉUW]ÕétÖ××1«ÕjÝn÷ðá×.]FeY‡ÃàsòÊ Q›±–}C i¯—£ -¸ÛÐЉ—|ïÕl€Ñe%>˜(&x‡Ý›%ñ¦+++oxÃÎ;÷¾÷½o6›¥Ú•J™_I¯×‹;–‘ZŽž˜GBm°æŒÜã(1†>4*èxÀL£’£Ïp.B�‚Ðe]/˜,æqa `ô•BßuR C¢VsÈ,™-Ä@O(»W´imC—Ag"•ÍÂÕ˜#„½¨Ý=ŽmqEZqh Ö†õC]ð€çŸ0’pTv†Ä¨uÚÁ£“Êš´ÄÑAÈÙ‡¯3éÌ›>ô¦c¿}ì/zÁ÷|Ï÷¬®®¾ç=ïùð‡?¼qj£ýÑvñ£Eûß¶MÛG;“Cг¯2V>ho¬O·‘rÆÁ›Ä£…®\àc»Kè"Eµ˜£Þ‘>pœÇŽëv»/zÑ‹–––n¿ývˆ ñjÛÛÛõIðäFÑò%@ƒö¡�¡�È›bàèEy6Û™µ 1IÛḛÞjG^ÀLËoƒXÒñòØVã‹â¹EýþúöööÇ>ö±°«ÕkóçÌ;§:’mŸ/ÓE®~ˆ£ÈyˆÆi-âøëǵf­*«ÚçjÕæ×¥´WOÈ”hRÇ{´dâßqð¹ .dyš™pQf^WËÀœfê­Ìk#s¨¢zޏåuëRÒ0Fz.�T âwØÃÿö&@o†-o:cÿ~j\ ‚،׸Uw#‰3ÄѼ¦¹Hh6›1vCôõ€‘Ÿ©íotröó«Ùl^ýõßò-ßòš×¼&¤~øá‡zhØ"³Ùà,㹚fC\aèŒðCµKàñȺq{iÐO^t¨$»ô*gå-*d^ÈTfÙ6ÛØØ˜Íf<ð@Œ=“¸Å;˜À³xÆLHHÍwó9SfŒ¸åNX¤çW­½"Ä&ïr6YÁŒÍçÇ(ßâ0ûd>/"ýäVwßÖÝþÛÛío‡Ã/|á ;]ÜFšýðlõµ«Eµ“É‹Q7ЊpÀ­ˆÃ”e€¤Ëù«æ£—ÊvY¥*¥T½¸*/•Ýß%fó4­)àb°VOË& ;™»ïF'ÌE�‰ (ÁÃl+Ï<e#ÏY5ƒ¥ó•†8”a¸ÅŸG{϶±ÁòBÔ.ÞGHú{LÒ[X˜“$ËöŽ¢ É]LOÎÙ&œ æ¡Ó†á‡ˆ›süøñç>÷¹“Éä¾ûî‹oFTÒ´1bwiWLÄÊu!gŸ°µ²D_`{{ûÒ¥KƒÁ`2™ÌgsËds‡"º×¥]ž@f2>RàNAú<|øðÖÖVßP0 DØ¥xÊÝlÖº¬mã<—í\•^«Õ®:N@@ѽ´²5dî *D³š*žø¢! -V 7+Ég¢w°c± 2¨WKãÇ,¾lœ‚VYCdÁ†(±–€¡ë;V¯×ËGËúCõéNÛÿ¤]®f³ÙäG&Å«‹Þ/ô¬Eh$öãŒÉ¨Ûæ¶#Fu¢ÑhÌo™Ïo™×þ¼ÖýH7ÍRJiþ²yõìjò·&­ßhùˆ‰· W®pÄ0šéfžó›lZã5n3¸»î ~܇àLjd-fl“FŒ©ð\Œ’÷Øš†Žù ¥6„ÆÉ&Cž³ÎŠÍcEY¤•‡KtÏ€\àD„6Xئ–dŠJÄlû¥º b£‹zòäɯÿú¯?}úôÃ?ln¬³Á·.(Iïç×uéº_»í×Þú¦·¶ÛíÇ{ìøÀí·ß~öìÙò†röêÙÒ?Zr§$òz¡­ÀøŽ†›´4;öº×½îž{îùÜç>gs\q€Š@Ã’ÀèìŠø7»Ýèû ÂÈq|F�P$éœÇ¢q—˜ ή[ÙÝn—}岉žªo G!ç çƒnÝ{\ŽÑô´W̸ÀSoöÆvÁ½Í{te#C¦ YÂ1·£]¹ÖøÍFó]ÍÙ?›M¾z’ªÔ|{³û3Ýæ¹fQÐð UY Ú±}UŒÀ=âG« ÑhL‹éìúY}³Þù@§Ñh4Ú¢(ªÿ^Íž˜o.ÚKíùpn%¡¨;éBeÃÿ<ˆ T6æP>‚ÑÙŒÀÀ`–gð”iaÜâË'ê§H­DÆa’§²ÉŸ¾vh/¢vUmòæIùueª¥ö·Ó¥ÚùZY”`¹Hgš=¹+£Ì�3Üšr’Jõã€ÁåY:3‡ˆß C êÎxÖà( I–�� �IDATí fØn€»wñâÅ~ô£çÏŸ¿|ùr<Øæ×9ºð¬ Œì„œÿÕ_Ô8¶yl¼4¾ûš»Oß~ú¿üçÿræÌ™É‹&Í››Õ—ªÙÚŒY w§A‡Œ¡Ó H*0zòΑ‹/¾ÿýïßÚÚBš)“Út0s‡÷ŒU®a<ï ëë°ç#äÐØd“‚™ ëzС3Ígó&Õ€;¢ 2dchÞ,êl9/ãM釧½ã·HWa¸ÂëgcCăv»}Ýu×]{íµ÷Þ{¯Í"Í4£èÌ:ÅEëGZf´g³$ œSÑ‹Ê Ø'‚Ø¥°~vcúºi÷ot˪<tèÐõ×_¿¶¶vîܹâ‘"Ý‘æ?<oþz“ˈsñ‘˜Ä‚2Ë÷“\ò€¡J"è‡úªh‹÷0©"ü38b½¥'vFˆlÂ}’(eŸ»“’I9™}ÿ¬úÖªýËíÖ϶jµÚô»¦Ã_Öß^ï~°Ëä k5i9sw!PD§ÇùM2õqË{“O@yÈ\áqi²¦'3ËüaL¼17ÆÙRUÕÙ³gÏ;g—E &¸fãÉûÈ[;9)¥Ô¼«yñ¿]üí—ÿö5'®Yÿõñx\oÕ§¦·6í†cóeiW™Êd ä@á^·ñÚéÓ§=àÆO6‚,f ѽ€(É@²(ökFá +á4LŠ áñC‡y:F´°ýA„§uˆƒ ør¦n—‰ Á>g‡Ø=…[Ê©4½Ó,F—8ØþŽîº÷¡+cšž1ñ¨ù²&“MÀˆ¬ÍÉ_«««[[[ ؆BHÜÞ#GŽÜxã÷ßÿ¹s窪*Ê"©^ֻݮa¥hWÐú¦ñÀ¹é„ Ó²v�Ÿ7ÓÕW_Ýï÷ÏŸ?Â�mÅ–¤å9�Üì’` Oá0ebý@¤Új­|}¹ü]ËUU5[Íù|žþ uÿSwtǨþá+žCžÜÊèj çšÊÅúaž,;¸ÍtìbŸº7IuËÔª­À ÙLË­¬¬ ‡Ã¨\ÍÍ»’1‹Í$†a'Ž$=ê_QçÍæ'š¯ÝHÍÔ*ZÍÏ5Ë ej]i±¹»° Á”EÖív¡ç» E’º!@óUB…`JJ04Q›ÙT™<%ñ’| qeë%ƒDÓµÈMV Yà’ê'jA®-W˜LÆß|P«!8™u ·Ÿfܨ8þ ÷Ñ€ujq†òˆ.\8þ¼ôHÒÁ'÷1 Ο%º2¨yòtÈ92Wr¨‰ÖEžÍfñ‰®¬œ´s�•e¹¾¾þÀœ?~爩7R•H€@)íu ÈÆCwcÒÃI–ކ"…Vt¯×»å–[žÿüçÿÑýÑc=fŸê9»˜Ç Ú\*“O¥ °ËŸÝÛ ¸ÎfÝŽvÜùçZ­¶ººzôèÑ‹/^ºt©ªªæ¿hŽÿÁ¸ýKWÔ’ÔñOsçÕÌu‚`8Š™ÉÿÎÚ–ÙØ (.ËÆ¼ÿ-–.åa>|xuu5F28ˆ¸#áqK>Œ’)éE6¢Q6³ :9û@ØñﺽYOõZuEoŠ Ôå-A¤V|ZYGÙ†ÓŒ;8—ñ<5G¬*¬×–!»ÉœÛa*CTõt vÎG£ ö>H»BsIÂÌÝns''†ºÎÍ[˘?°ž|çÙ?lu»•°78ñAH(¿i¯~”¡í�ܸ]`÷@@h}ôÄuÆ÷ÜrôX~Æ8g9Ñç Û£ŸWs×Ý÷j{{ÛÃÂõ3õ·:å•ßlloo‡ýhQåW•óWÌ»?Ó5TŠšÉü7ÈZØ H1¿?íçÄøÎ¿øÅóçÏ_¸p!ž#ðÎÀzàTÌù{„ñxób<¬“jQ e:å-eûgÛ'Nœøöoÿö—¼ä%ÿøÇÿôOÿtmm­ú³jöC³vjûùìýšö†„Lž •ŠIt3Ë=Z#dÞã´¦ROC‰t*ŠÝLÕæ#ð"ç[YYI)…b½Ò^¯èNøªœ}þrÊY›Ê “L.2k3£Ã§½žZ䀼ˆË&»Ä³3 $4ýâ§²û˜K»PÆœq“ãÐíð„ƒfì« ¥Å±è£rU¼»}6¹&p3 @üËš¢ÀÜ8fÖ–µ3ßɳrðJéfÑ KRWƒ<æ>0—îDóÊ\˜ˆ¦½²1ñËœò”eö& °y”µoµÓ$5kL^>Iÿ{ÚúàV½¨×jµù-óâYEãF5¨¬–MDr‘ ½ÀYñã†s…™n1.îÛ©S§}ôQ¢H|¢ù2e+–YÜ3¤3ëÕ^¯@“Iž†ã`K§][·ÐA´Nœ8ñ¢½èÆo<sæL¿ßßÚÚªšÕ¼vE–ÆÎ‡ó¶¡B:66ÏŽ/pÚ$w¯´Ç\Ücè@™åf^Jiii‰¼'î³¢`Ë‹áÛŒž$]Ýx".\È6šÜééTBÎ>‡ÒjÃJn-Àø ~°t”™fŠ(}v̱2$Q¶œù?™ÒZÖµÍè<°Rœ×VåâwËÚÍÛE³:Ll¹Ø®¨èÙ8§s»‹ê‡ÍωI•û¯9öáèÀD[£äÌë0É‹pixn&¤Áhxpâ¸zs Á8§%_½ÆÀ ì&ÇC)Š¢qg£ÑjÌo™—/Ü¥D–µt>5íŠiÔÄ™©“ÐÕ’tÒ°Ò@aÏì²%$ÈÜÙreo[¸AðƒÈ¾¼¼¼½½=’l aif‘’}+*n/‘›,ª(Šúï×ß18uû©Ûo¿ýÁ¼ë®».]ºT–åüÿ˜7þ°¬ ÏÝÄ´;7ÝúÿØ{Ó0ËϲÜ÷]ÿ5O5tUwºéN‡L À(MHB69½¢rdr8l pÔ½åRÜg« ȵ/6E¶¨ˆ„ $bČĉt:=¤z¨aÕZµæñ|¸«~}×[øuª>p5êµþÃû¾ÏóÜÏýÜw6[­VÅ£ûåfÛ´3Ý•„ÆMª‚͇F£^ÓPYîÞ½»ÕjùC &Ël:˜ ó½©, v‚¥3Ýv("vmûñA_¢…KE*°)÷¹?G"#HGr,õ·Ú+ÞÛtƒ2hŽK·ßþÍ4º=ÉÒü3pnñˬœá£8¡4oÁNàÖ|r(l–>£øàNà�¶††Ô‡ÏMØP2FšÁ`¢j5òîuX_÷Ž"õ™ó}ã®#5ȳ$’ªt¸ß©"Ä3(yªýu»Ÿ·{<{±›¹-“¹-3~ùx’™$©$}Wz¼4Îä2ÎûÒãkщãû=vFþ7ÞÒ𑎰¡˜à§e¥ƒ·.HÝô*•ÊE]tìØ±C‡EæÍ[ 1=‡£>6ÀÜé3“Ágk»vë­·ÞqÇtÇýúå«ÊI:ñ±í& fUW”’zM«««úÜ(jïæCÁ¼ÚpcDVöåYŸo„§ã†Š"XcaÎ5sÔȪ€§Mc•J=l~ÜY¯;!g~œÆZæ9d‘¢‰Ê '¿»† '/eµg[êˆv Ò‚ÎäW¾ä»”ŒÆ‰mQAÍNPÒ‡p€úF¤c0\éCpDò 7fÂ&JÍÜ{[‡óCÈÓшÒþAYç.Øx#¶µç=%?S˜%ô)ÔÊcvqI‰ð¨ü¦‰PëÇuÜ>ËŸ•‡XeëÎÎr‡MPhnt|Ë8R!Æ©õ×!bµ©? Ä•#Û‚¨æ&Nsƒô½IJ\ÿß\‚MàR#Š9Ùï÷:¤þƒÏ áþB"BCÙäU>et®• õoÖ»î¦ïJ§†“7O?5¨þRu4á<¢š@˾T*¡ÃD-ŽÌOØl‹Å(Í$! V†gQ L60†R.(Br[ŸŸŸ¯×ë>sªoôB܇LÙVšØsw]0@Ÿ€vñÝÝ 9Û¬y-âÔ^¯\ÅHý½ˆ ä 1ߨ Þ§scšÁÙœì@*-Ÿ û>¦ÜYãuîX¬šÆåc9YTR¸oŠ·d8žh/éÛ5¿–$‰ d{Œr­ÿ¸F'ç8÷ËÌ|?H;´y±vþ·[·¡ƒ€>46Gí9÷]C&«ß¯[…¢¨v…¾ˆ3ò§ÑçóZ]€Ë›Ì[§7T°:jOýÄï»<Q?%¡}sô8§Ÿâ#l¶ÛàÌõOã‚)é|b,lØ[>kÊŠE«ßÏår:£QÙ ³Áà€÷DÍÇÂhbi½år¹Ñ·Fé[Ò½›zýŸê‡ 7Š/+R²S©{ÑÅ.Fè²`` 9tAº@òD1Á9“cËŽX¸S0{*-x×2wz‘~”!+iÞ°)œi0WX¦ ´r¶¿ÖnI{S€Â±2?m]S º§w§9³¼áï Z&nhíwl?æ4ö}ÚßÇG\HÆ%,égD3ÿ® 0³Õwn¨Ním<F@‚‰yD’\®ä¯ ÚC0`¼Ô ßÁ”HœFƒ  ìéU gÙƒK�ÐáwI`ý‚OP9ÔéC>ˆÎ±åZúâù\عçÂ9GÃiÙÑy¡×«ÝDÌL’_?Œ¼iïl÷žqÕQ$*ˆCšPv‚µ×%8†yÕÅVµíôtýCñìQÂîv»,ÆCÈ8†L8Y'FúÊNîp½]‚(âR„=¥Sä.Ñœ¬C‹Q«•åAØÓ@®ú£QwP×sòäÉH‰ÊÇH¤Õ­xâœëY”0Qb½r¶Xs\¯~\cØyP[5e9Í#g/tÖ…³6Z»œ}>%@“†¦Ÿãi>uOvéN…4„½wU+† f޹iqd2°ÂÈš]‘Ðaú‘rTD-e¼Ž(èb£a³ÚUØ0ªˆMþ Âf«7gôQ¶zíÈ]À ä7Ñ q?r5®t=:òÀÐ]/\'£7x·*E Us 7׆‰†XõHõr…ìswÜ®Ò@²ü[gmx‹ˆå¤ÄB×£WƒO¥«}³g¥t¦éèÜcäV{rãL*Ö§“¾DsgxÅ×PžîÅ­ªòù¼r2í |>¿k×®N§S¯×Ùt(Fk׸ý/‘Þ!))Œjð4lòÆ¡knê“ûý>¾Sº_éKù|1ùè./ˆ’”¼ÖI4¤¨:yOõ–‹q서m‹:>E ?Ê“ ÷wÑ©¡ªŸ‚†À½áìÒú‘Ë–[+r;U¼Øõ}¬=:Ѽs㦟n'ì+2¢KEmO@oЍÞ*‹¥RIñ�oð+=·°ÙÇg#À‘įõ~rØðÖõ!7Ž„Oô_É(™"òGh§BÂëÁYÑÑ`K;ŸÂ¹Ê[=dœ‚~†¿_/ƒ\&�'rOAkËËÁŒæÔOÖÚužq„ ³2£Ò'ª_}Ù»l ž˜¸Z4œÍï'¬ƒr^iÁo¦ÖtP—2ë&BBĪpr£ eú•£eW,3™L¥R9ï¼óŽ9R«Õ"Ú'³úë5ÊÓRé‹Óßn¤B*„Püùâ¤1 Ë„ÒíY)Xù^�F¯\aºz7׃‹ÆÆÒ¥R‰Ëóî‘û¦#f‘Ïç£*Y”)vz9?U+°ÞOyfðn!º€ip´QtÓBôQG'û©ík5bҎѨLq³HX— D2D}ŽòeþÁ´p¢±J2q'ÞŒF£={öLMM9r¤Ýn£Äõ®<Þ2»Å$-¢õ9Ü q¤# Žþ¶&N» ð‹J4ÚB<gRZÊPŽ{§xDƒ2þú@BÔu…žH¥Â­¢@µˆÉŽˆsöGÔ§×%rÖóHCív›µÁt*ˆ}¸æ^„BMô—î O8òܤât©Môg½\�jöæ¨ÃJ‘Ðl÷¬s™F£ñÀt»]Þ/5·na]Jõ¢þð-ÃL'3}õ´^bý“õì‘lþÏòãCgŒï°ƒÚj@¥{wr9±“!- &æ¾Ñkð-©Ä"„±ÌþÑ]òõ½»Ã»ƒeGr¼r¶íÇ»Þr ›¥�9å·ŽmBä‚§¯ç§>ÜîŠ^ލàß§½ ,Žý†[E’û_ú~ã°ˆVX¤$è8^0é'¶Š[lÇã#GŽ<ýéO—iÇáÇ×ÖÖ<ó!!çªq‚€¸ìŠÏ¯¸Æ0çSœ¼âP0ùÎÈÒÈ(s«"‰0ýÈŽšË ¦m ³⸶76¦QaáÒŸXFR%{÷N¯Ûcé=h¾ÄõÜ"z$KÂçpQy§¾,]®ÔÙ\hÏ1Ç–}/¸*¯4Œò\²ÌgVp,Ô·(Lz×AY »SDõ²’pÌ•™hªo¢ ¼iœýL¶úPuî¬9¡p¹7äÂ/…ÁKéCgú¬‘“c¹NrHÓÀ{yæþ‚(R™ÑvOR÷†÷lÆ'ºHÂfZo§mÃ8ÊN°!£älÕA†tŠ7”¾n‚y¾ºQ&ádžÊOq¿ðÃh ÇMׂKÃýŒy÷â@ßèÕ´·!{lˆæûtÞ›ÛíöáÇ;B¨V«‘%x‘‹ÑÓÖ-xA@Øît:Nô=‰ðÃå—SÅÐAÅi{páPñf»î”ý¬§­oA\ÒIó>Ûá£üD\,P W]Œæ6¼Æ|‚4Þ¡ññU¿$î…YHdooTÜõZÜçM¸¼Pôj°;ò™6³n·+V$/(ºÚ ü²‰PHò“QÃp4lè`yèå5IM€NûTVKÅûüª±zWõÂÑPx²pÑEÝxã¯zÕ«8Ïç³_ÏŽž1šœ7aœKÏÙåhyøÑïÅz4•ì¸WÆä:ÙlV¿;G,†Oso$W¾ áºCØf` ‘Í /¼°ßï=z¼HÝ÷+tï¿`f´üŸ˜ã™ð@BäºOÉEMo/Â(¶ôB PÅGQŠtÕu|uJêÓ$åDQåIg.ù¬„ñ©§ž:uê”3²t´ñ<¨•rË"ŸÒ1¬jËëÈ ‡Ï.uñÇÈ%ˆòÑ[hz2ÐÐÝ›ÄÔŽl@÷‚ÔOŒF®nJÆq‹t+"W¿*Ø((ù£øàkƒ·FÈw®¹«.Aý¢¶@—ÈÕHE÷úÆíat=‘v‹Ÿ¡Ä†saay…"Cr» ú4± …±!˜ B�P¾ôfÕn¬T*Ífsuu’! >ŽÖ¼öÎ:m}ÿ0ÝKÏ&³¯ý믺ê*Uð7ß|s¥?œ¦¦R.-êËØó€ˆÝ«Ð›ˆ´oa.xD„Xäc¶ÔÉ*0pó´a'¢‹ó ¼äÝ 9ÛÙË !8pàÆol·ÛŸýìg?Îô�c"d‚èp°¥ƒ™«;Ú¦á/m~7¦¥ì}Qà8_Ù'lo!ÈÐWÐlF‡j«_od ‘|hƒ/×½'„Ðv p+ ÀóÔ50ršïr­3¥¨‘¸@¤€à]bg^ðiPì¢a´Û5¼%a|~ÞV“ÇhF žò”¶%£—<1ÿ³Û«„Íþ€TÎJŠøß~~§.ˆ€ô™»®`j-A ÐÍ*ÔEÌ]'û¹X­c_~¬#äÝ,eÞBwLoѺ/‹ÅbQr^@Sð1²&QÁt:Ýjµ\îÏÃ�-™uŒ+¬C+++KKKõz}iiIº£Ñ(ŒC:¤6tJž÷¥•Y‘4'oÖ,8"|Ö—7ï˹$n CÕEœÂƒìNÈÙ~`m86þç–µO†“SûhˆKEѵvY¤È,êm¤eáÑ®`íÞÌ^#G.™NtvIù`VrÎ:seRrs𙑥•”}KÓ5ñ>º|rH“€(è¸(˜Ó¢ñLgÚ©kÎ2磙S‡˜ãÞat"%¿æz<ŽÝÓ3eª7òvÖ� ÞÛN[rHSeÀ ÃA^õ¡ðÞÝe¸ÆÞœèèJš@XQ/Ý3ngð»ü¾¾îœãºS.ˆÖØ"x©GT‹"±gfD¸R©ôœç<çŠ+®xøá‡¿óïàÄÙÞôz½F£‘J¥ŠÅ"ZÁ¦­Øz½žZ§y©{RƒWêÓõ/~ñ‹>úh£Ñ¸ÿþû{½^ÿyýp,d³jG¸º4×b±Èòps&Ò…¨¿ÈÉCŒ(Õ;ˆ i^7ÓOòY1w.qퟳr¶¹Ð™L&ËËËßüæ7µƒŽÈVý12MŽ'o¶“  ¸Ï;Íuu”€~xC¡½ÁBgKs1Ôg‘¢¥R{]ÒÌÌŒ–;%šª1í"‘²k4­VK„¨n›ù"_Óz€|;Á'TàËyç?ˆ^¯Ç·ê0·¦õ¥<‘ô”_ÏS)ªÓù¼E§V– ;õÜçWthÂÓ»®% Å(*MˆÁ.#*Q§Ó¡WGéÉáE¿Ð×R$J y 8ò‘aAbCW|Ž#ÆdÜ ÆétºÓ騘 wØ‘çæªBœ@ái 9ÌÌ̼èE/ºîºë8ðÀ,..ú éNÁ[^ ºwçMP¦ ¾##é÷ûáÁÞÆ{ÇÝóØñãÇeÊž$ÉøÒqæt¦´Vd¼‘3Œ‰Ü¸û…n/Û›L&ù·äÃSÁGý]šþDühž†ä/lÂ.aö˜ÎÝ ~Q9å c’†³Í?Ä’µµ54ä)Y4Ž)¸ú÷¦Ÿ7<ß@Ë„qz¯²éñèhpJ>ĤL&S.—óù|³Ùä¸w –jAõmpG‘¤Ï>ûì^¯×l65Ë2 E§·BX^^VK¦\.§R)±l£D~zz:›Í®®®jÒS#xäS¥RÉ-è!ž¡½¦™CÍ©S¨$P3¹r¾Gãù Ä?d˜á>x‡d üÓ½|$"špt¶’na³Ï‚ÛFd³ÙÙÙÙ+¯¼²ÝnK¤Úý§¨OnUÒ‰¼nö– H«w+’‡ ƒßQe1¦Br&§÷#ÝwÃ!b°#ž°Ç DÎIºåÕÕÕ{ï½7›ÍÞÿýÍfÓAGèF–ÌÚò ¡ÜAÈu-«ÿší|¤ÓýÏÝÁû׵ɇŸfÿ!›þ`ºÕo¹†B’$“™Ió½Íñóƹré$¤“ΟvÂjȼ/“©ex#n*ÏDZ4´DK)ŸÏ#lÃõk¿Ãè²ÙY ztTuþØ=çÛ 9ÛYâ8°ÜÄéS,Ý Ðs×Ïð–¾J{r@·³ Â9:J8m]1MZ/xÁ žóœçÜyç>ø`Øl,pÃépîÒÈHIJ;~ü¸Ê…È}ìÎûR™LæÜsÏ >ú¨³q”#ÏÍÍMOOkðžJhññúª¨HEéÖD¿„yÒùHb@W·ØN˜‡a³!ž3سQh^é(tá;øˆ¤¹p½gîn Ä›Å/n+²l»wï¾ä’KÆ]wÝÅ N§D@ ÅH賊ôhåyõà -§<E�ùŠAuõa©Q/²t žÍè/áñÜ|ì&Úq¡¢yl2×½`ìt:÷ßÿC=T¯×…Ù:µ2ÚDÌð:‹Z¥CA„:Ï™†å(]ú¥ÒèÀ¨÷Û½0 ÃѰzU•aðdíîÎÏurÿ–K½÷̱P|}qò²Iï¦^ò[I¤¬È’¨ð™9ÍÓèoôÞuì8°æk ƒD^ g” Odý沈r¶§Äq s—´bàŽì� jý¥š Ójéé0—ÎÑ :’ˆfÃHÁl×®]û÷Ÿ÷¢ôv« ¬9]J_$+Z2ÀXÜî$8™LNŸ> »”LçÑââ¢À7ŸóWs~«²½s¦ù{ðC7TކŸ\üb7 a§9óLó†¼K5G1Og:÷èrXþ‘]…ÓàÚZ>ÄíP1W«ÕZ­ö…/|¡Óé´Z-(Ñ|š˜‚éÝqwð!e¨â„v NE¨(ŸÑÑ÷Œ˜¾|©Kf¸œDô—¾×¶jà ²Lk•pâæ¼½^O% .Œ˜Jºà¦…Þ\DÏÐÍœ\3Þ-jÆãqúxºò¶Šü(E>åëDóýýÑô(ûY/d‡Ãar(I®LÂea|ÿØmjéKAAôËÖð�'˜*ž°!Ÿã†=mÑu§½EÊþ*wBÎv6rüå‘¢ Ä u|¦ÝÍoô^¥@ŒsIdZ Áy±öâÄÊ»ï¾ûñÇ?}ú´�tê?L½íä€5}æuÒMƒæuÍBæK™üÇòŽÂûÁªi|Æ#–––üœâ~Çãq«Õj4Âå\ìÒ«ÿ'ø#DÓ‘‘!ž\ìUÛ­†h Ë“ôéHhtï#…f&š½°Ò}PÆ™xaÃò€:tª(Ñxª®êX.—/¼ðÂz½~øðaºkΉpï"[NÆ…äâ’õÙ‘¼´Bạܜ:Ûé0ìÆ_§›/(4zKE¥ÈÎÕÈç|NÈI›$m¸º n4à«çvUN7pŠ{åq§‘~Äz�ØÓOͤR¤&a2==Ïç[­V«Õ?9·Æ“ó&™ïe˜‹ òæÓ`å~h“28á ä†ç¢îÉëÓ©ÊhÁ ¶"ÿ;!g; Í]rô+Zh‘¹‰‡#ŠzqÂ’¤j‰¸‰$q.°F¨óù­û………ååe‘>áé³1ÀUô—ê9sagF¯­ßj>Z¨þLµ×ë ^9hÞÖ,¾¿˜¿=ÏÒGÔsÄpŽ&h²Ð9òbŸ!…tÃJŸt7�� �IDATN:þ Š2‰ByD/õ'_¨5¥7²{÷îf³Ùh4 &=«Œ¬Wú:) Â(ÛÊr "\^œ6 “s+ÜÀ±¾^¯÷È#ˆ4ÁÇFE!Zב0 Ýø@¼aB&¼8="]- ïC½#‚ÙLOÀpai0DZ§A¼YwÌÔ9¨‡LlŽºë^—3ï‚~3}&鉱Àô] ×=Å={ \TP±"Dð” çºJ“°>/|Í5×T«Õ¯~õ«*Â’$™„‰çÎf¤àÓ£�Q@MRwÈÕÖö¢Íñ[7ª�êPJ_)*ôwBζýдt{H®ä&Qã'l~Þª°Íl{«â° !¹*Öœ"øoQî`ÚV“®¡ÿ›ýÒKJÅb1—Ë%ã$ýùtú‹éµ[ײ/Ëú®ö¡6>ÜG2ÁĹ$žƒ'\NáK§Óbþ°Ï}º³Â=v·”öo„ÒX[[ÓX«wþF¼Üd‡ ›e œÂ^Í8œåãG.âàQÓ˵șìË\Ýå…P¡cTŇ¿q¢‚S`Ý{F“’ür.—“Vq¤~M¼G6n ÉŽˆz'žÙ ÀVLü†œ ø”>É8½ØÎ(ñª î»—G‘Üb£¬lrô*M0@Ö•r8Z#g„à–“ac8:g4Y˜<üðÃI’¬®®&I2>k<ÊŒ2Ç2ôØtfòɇù  ‘°‹Åùùù……(ÔÀøÎÚ÷Bœ¹@7Íò¢-“É(;ÜÆ“v'ä¬ÿ°ŧ„Œä"’ôå(°ÓI£3+Z¤u¾¥ÕÏä´u)C—uËç®�ÝàWè΃!„îÿÝÍ~4›Ïç8°{÷îcÇŽ-,,ŒÇãÌÿÈtßÖÍÿiÞ'}òCG|è°áÈॠɗ{#ê7qb@šÌÖø1ʶqߊž°Y6ÔÉT“ÉdmmMü:CqPb«îGö—Œ¸zPq‚©O§rô3Í{EDÄj£Ä#u#K° òzQÏ¡»+Í͸ ¼ëÍzÔôzÔƒJDx£=ÃiÈú§˜pñV*<(‰ÆE=KðÖ‹Ç-V§-O‡ (w|Ú,zà0Eƒ  9íY‘¸þ¯ J•#Þìœ<: ‹axå°ÿ×ý'žxB¾“ÉdôŒÑ¤<IÝ•Êä2ކA:'ãQ!VÌ»ît:FƒäÌ'œ|Ã17uاõ¦¯ïÖ³Í?n•æÜ6¡ æ!¼cé˜, ü‘<šÎ)(j~ü»9†Ã®óÕ6Oûìž÷êÑÑ:ƒ×ýÔpúåÓÎ>ðÚ×¾öÇ~ìÇn»í¶ÏþóKKKÅ/[ß*² z@¾±ºÙ<΋õÎd¹ÈÜ~ÀVïðœ¨ÕÏ«qE2·úÀBͧd€aN»Þ”Ot{ß.˜Þ¢“­‹Å"^ Q©äKl[U<†8µš<ÝŸäiœ\¢ ÒM‘)/XWÍh º‡:OÒ\¤+"Å ®Í 5»^íArƒ0ɸ õ¥ö…«Nüqj¢›ø¡ˆÌï@ôÐä,ÏìÑ&÷˜‡½Éd’OqɬÚáhz[Õµ¤ _*ô½ß~C;¹a}G´>ÙJúIñ÷ŠãÔ™ym_çn³Q{ð FíàX£ëIú#¥ÞÿÕϺ³mô°Yaˆö’D´mð?'@XÍÆåÃó~R”âpt´ÁQrT¥}èÇ•`Üo‘:I‚ŠvSSSW\qÅË_þò$Iòàƒ¶ÛíazØ -ç5ø8…ÛÉ(ôF§³÷uÄ…ã`RKÖsÿ­È )§ u LjPÏÑ8 #;87Âñd9˜ÏØVìÈ+Q=÷"ÚZLøXYw™LFØ ˆÚêz¿žÎ‹è¼ªÕŒu …¬zê0ç¼yþN§šƒ š¬Þ`Ø<O™HhWÕå"ßÔCÞÙ†¸¡ÓPB¦ÝŽàiyóÐ!ÀI‡ ËÞ1†H›Î³W–r—OÝ#Qê}bôÕ¦Þwä\üo9ÞgÞ“ÉV²o5Â$„roÌNÆÝq:{¦=&\+N—Ëå\.wúôiì\¼ÎGÖø¯lr–"(ãÀÂ.4¥ÿJ*¹ÓËù‘˜Ëñ°AòEaxrTØ, LDRºjaÃL…ÌÈi ~\Bùw®ª›L#ŒOŽé²+ÈØpf9†«: ßï§¾’ZyÑÊ#<r÷Ýw¯¬¬ÜyçG‡­ÿØJýÃúÄ;r^ÌÜø4€gôÔÁ»0ã&Á¬9•̲œ_G%²G#ŠkPÉS<g’es‚xMà]R²i’bšÛÀYº$,„½-Gë›”¾4ùl0 `BjÞ¦«AA‡&}¾È}Ò=U)LI]ýŽÀ¯¶ž¤.æä†§.Àƒ4$:¡.çZ´�€›,�Æ?$Ç|CGÊ7¯ó"~¼+}xÍF-Ð]2ï"ƒ—\ìMÝ/* ƒSÎ: Â!Šñh<YTÿcõ 2røA%)[ë#óŠb- &J|W³ÕµÉ-[aßHÅ8Ó4ù`ÏîÞl?°æ„wY‚ŠÌà #`*±i]Ò_áwHÃ#zÐz.>í*Ñ(¸+ÍOýÃDV³Nßiüy<þ{¡ýíö¡ÿt賟ýìÌÌÌ‘#GNŸ>=»ïê_\ ɦÞ»‘•zQ'Àá/q‡\ýÚÑO0£¹Ú¨7u-Púƶwˆ�¢­»zûì”—Dº)ñŽÜêÛQȸ>NïàŒÓÞ�ý<ŠJÞêg¸ë‰‹j ˆóÓ™`Ãè T«È‚7BsÈçÿ}æq«Äd0QNfìyDQšåmBYƨ]XšQÖ`r“Œ¤¸¦^‹ƒ¹‹’Ç$±È)šâ6»ù%j2  Ì„ë(§<å‹\’Ç»b,lÀÞÉdÂ@ˆÓš}\‰�ùdÚÆuó\©È[çdw€µ‰*´Ò�s®]~°³eØ“€,)÷w—Itqð‡#7Ž`âí”ÿn ©&‡W`øz²Ÿûpnñï;íT¾UY]]¿fÜ{¿ø‡E„Yß>߇ð2é\¿Îzeå ©è‚ÝòÖ… =3åŽ|n 9 ÖpîP;z#:XÁ-åÓv®uíC¾?Ý#ÀÐ)g¥P¸ÀOÔ×i®c]ç/ï×#µ°1TK…‰¡ð$�Y3y0£ÅÀ:t›»(g‚MžÁÚB)µP(ø‰éÏÄ%õ|z†F¦OGÑÐRãKŸ(pÙfçv"Þê cœÅa³ÿ7a•rSѺ §,^5âêóò#‡zêé‹3$·ÞµFž{fXêJ „ß⬡%¤]ì;ïf±Gv”¤·ÿÇm]àÄÝ|#!µuX·‹S=g1}O¸¢‰6Z>ÁàØÁ²ÝMÀÉl>ïÉžq–˜ë›áï’Ò—K½wöš¿ÞÆ…¯f^=3è ��]ÖI–â͙ijGƒê ›Íæj¹ðTŠp¯×s‘@€ÈÝ’�£ Z]qhiú|‰_ù¸ €(ç8µ ؽ›0ûI&qþùç_zé¥>úèƒ>/€Èä¾/0¬h¹P·\¯�¼Fvì„7p9 ø¨ìÀЈÊC7] >Ѓº*(΄· ‡C±á÷ìÙsÉ%—Ü}÷ݧNâ {üs.†¾÷6Fa4„Ï&ÝM<NÉȼÓŸàíó‚‚y&éEÚ$ÏPÆCÛ•OÂíq¿@µêj°}B(R.g@˜d…W)x ¤!ŸÏS éÉq Ñ‹¦Í¶½ë„™<¡ïkÖ¹+Çë6‘¶"_q™ˆèN%d?Î;ß 9Û_èHP ZúZLþË.‰è˜,[Åuà£( õOTh©‘FyDt_gé*,Èè©�”{’ãÆ–J¥ÆÃqá å•[­V¡X‡q˜¿ ?tÀFÙ§g{WõFŽ&³“Q N RÇRů3ýL§ÓA›Î÷þrRƒûôøì4 &Ù´X4«]ŸßÇp¡n _Ö§•Ëå .¸àäÉ“Îõ} ?Ðók'qd‘ººA0y¡°!YÄ_”n»¬·èõºËårÔ‡�„¤ÎVBµíî–´šÔY”ùO’j˜RÏá2¼€eM#ê$uCÈ, YØìÑéU`¯×CËÃs8÷©tí�ð:çÎ3|êÖËÈ„Qóœr„¹à`Š>ÆL÷Ái™Z™²™w+U%a«pŽ 3@õ¦#…¡³-œÀém'žddPâ%¯S×¼¶s¹¿`m›<Qu;ìΣˆSàÉ�TäO tãòºÞvj˺pÆ!–;ø>äºl{}{ƒOàÖ"b·Ëý‚±úÓSéî/vÃáûd.õd*•Jõ/í‡+ÂÊÛVŠÿ­èÐ<É»n™tÞ¹m7q‚@e†^Ådh¤ÃF-å3ØÁ<Z´-'Oäòò2BÅ®pã@„\è&PU¸`¶†ó(ˆ»îRì¨=i)¯ï8'à…aU‡ÝÈ‘9ýýâYÞ«««²¶t#åì.m篷cÔƒ<ˆÈë.¶µŠ¯žÖwØìÑéÀ²Ó&Ý%…W9ãL×oêA!úÂ[`ŒéÚ3ÞPñþ%¿±f8ˆ êìÒæñi-÷Yçv€þxÈQÿÆ=gý½»ž×Fð}çp¢D$@N¥µ3—³ý?èý¤s>«‡y ÒqÒF0U°•\/)eÊ8D¥È\‚éòÂÃæL¦j@ï  9ØtªPœO©S2±s„R¹TÿÙýâûŠéL:•NM&“ÒC¥É÷'o62‰d`$ŽÛ›ZuJº»hcàMéã¢0SÁý,|º–?»8ÕL§Ó9tè÷¥èîxh$t9m/*:©äÀ6Y'\§èy@no¡dÙM‘5µACº0 ,'‡þÁL¼ð\É3t#`}Ž`"¨G.@î§üV‰n’í wRðå䞪ÎpeãñÏGˆxz¢áG]ïDç]€ÀÎÜOÆ]¬ûb©øNgPs¸NËÌýj½Ýè)T†ŽB ªÁ}¹*¼8—äQTõÝ 9ÛÃXsgOmvsÒÈ•J©T‚«|P°íîå.,^>“˜Ó�pãt*†HR>ª]ªÖyÃüsx ˆ<:ÉÇ¿í¿kÏ\;3ÉMt2v»]ÝKé ¥Õ?_­þlÕõ"é(è,´aÏÝT½CŽ¥#é¼›æú`¬× ©,"q3üQ@òÔ!˜yì8~ë Ŝ℠û ;TCw¢Ã†’º'»Ð—î',Ñ'÷\Aÿ¼ßï'•dtáhø3Ãî‹»“É$sG¦ðùBx8Lš›ô°'Åuò´³áñ|Ê*B•=xDBhøkrYâŸc�¼zŸÙrÇt \Ç!ʼné¦Da³»œ>}G’sP©íœ…¿£s|±q÷CÑ )¦È~(¹i·6…¸’ ÛOT-E2ó:=òù|.—+—Ë¥R©ÙlîT9ÛÜȇª:1¤ ¦Õ ɇ±2Z¦È 8U4löZöQ;Gó†cG0qϨöâoÜ<-º¶HÊÞRÏÍ}r4iÅ{È{ 4TÖ§T†¹\®T*íÚµKžðI’$©$¤Îœ,N"�GáÊi²°Ýœÿ&æâc®áæ„4ý‚(C$ÔŽ|r¬”ËešC´Í &P›’BÂõp)æu8AÔ[Ž u8x>Õ™Õ§7~èüGä”qJ\ˆè>Ë€‹cÿýñEãÂç ³8Ûív;WtºÿW7<Òÿ#í ÏWü]™˜£–¢0˜´+”íHYZÒŒg:ý7l Ó_AÃßY‘˜·Éz¦&ò ü'†®TÖ�êº8“¿>Vþ“fì`„âä ]ÄO¹‡ÅœE*KæäæI`hHÅìÃY‡žšËå:N»Ý&äƒyž©—ùüç?ÿœsÎyàœ¸r¶!ä°°ƒu‘|×ôõ^=ÕnØÐl|)œ¤éûóɈ8.s B6ÜÃàrê‘Û·lõÔAox«µ‰ÛÀ8–؃ªJ¿ß¯Õj Ïý~?Œƒ£@x¿û¼±§ßï Qnp¶Öw‰§äši¼Ž~§$ø»óæú«Ùlvzzzß¾}‡Ö0„sç¢fÒVórv7ðhá!ÜYï\6"ZRRa#zñšTWñЉ¬ªuµZ-¸Ó.Bƒ× ¦®žš½øÒ‹Ož<yüžãé;Òo6²[ŸñÒ ap®vãýEï™±ì¥7ŠÝ§G¾„½š‘Ì—D¾éxÜD‚‚èÍö°YµˆrŠ<Ò…AaFͽ˜äÕÝÑÇZçŽs�Òâ«8F‰jt¾ˆ«cÜÙIY¸G{´‚™Ø:KÐYQãñxffæúë¯¿à‚ ¶  ì„œm˜ËqГ¥ìce®/²5c5Ó„@ËÒó_RxeÙO¬Ú¨/a²Q_„-³Ï0Pⱘs6K¤~™°•ßSî~¨›{oNÞnÜu÷w»…÷¶p‘ q‘ÚºÓÓÓ—^zéììì½÷Þ«ATòDZôÓ—ssô,˜Jnä&Âû‡N'˜Õ AÝerè©x¹Ié9gˆð蔦 »)L•Ϥa&§a¹  ħñ 2™L¡Pð>¶ƒltGÝwgß1»wÿÞ—¾ô¥×_ýÂÂÂ_ÿõ_?ôÐCã·ÛÚν-çõç¾·úœî{„ßqò^+Á§r•qv ÅŸÓ‘ÑM(—Ë!ù¬Ó¹ñ_óðì¼2høÍ)Ó”r•e Ü`n°½^¯X,Ò¦¦¾¤4ô©0.>%#;DÇë-ž¿²rt2¸³g‘L,Ó¨‚„Qí‰&UÝêêêm·Ývß}÷=òÈ#Û¥y³r‚§rÞÕ÷np0÷3ކˆHæÛR4eÁîX`¹·[°!GØÃ^à³9ý:hŽt¦éÄ0c¨U«3T‰°`-&p!E]•Ž3ŽãÔ£©ÔTjøÜax<äZ¹~¿?Þ7NíK¥&©ô‘t:“>coˆ‡²Ko¥$IòÌg>s÷îÝ?þø‰'üéù˜*,èD¹ÝA#gåÒãÑ!Òn·; `ã=ÍdŒ‰4~¼2P¸súÃV<ý½¯(Ý]±XT®­èR(Än’˜¼@¨î:CÂi£ ¥!Ü}Vw÷Êî½èE7Þx㳞õ¬z½.ôô‰Óíg¶K¥’êTÊ&÷І¥Â„“×j!ÅÕ:X™ú¡ äVèÓÐ=-—Ë—\rÉd2ùîw¿ëD/Â9œ•Þ –Û)¹;É™Æ-¢]éc=Ô1Î;Õ3N¥OÐEJƒ»sî5ÂE‘ôN$éâÖn=Ǩ“Ý:†ˆ·œ!%ùX‚¾½ÙlÞrË-¸MmŽ:K¢N ¥±N §rº´³V›vxZ0ÙP§¯DYK\Ën’nÎh`þQ;ß[Óä­˜ÒëƒxQåÜßçÌýœ‘Ž^å?œï½µ—:š·Ç!„ÑÜh8?Ì¿#OQåbõ?”‘J¥ÚíöW¾ò•t:½²²‚ ¼zwDFÌ?"ÎòÄèI0à¶u „Çâzª<|ïù+Âù©Óøï:@ ŠÜ—ù³j"%—J%]›<l6ÁævñÆV ¯¿×Ëí÷ûår9ŸÏ·Ûmð(ŸFKKK‹‹‹\^^^\\\[[ëöºãÉØ9YŠð;ȈÈu½EŸõ^ JQãDëiï  KÁŸ™™)‹ò$d¡º�R(z«[{?óü˜V¤2æB®\à£]^69µê³Çi[4œ�ÅædèˆkàCcQìÊë|²‹FtPÁ$»"¨`'älO¼q-A"{öìéõzËË˾hHÍ¢>¡g+QuâȘg²"}ñцuk&jž•»'<;$—ËU*•v»M–¤³H#dŒ[ˆXÝŽó:v?ùþ¤øÎâृÑÙ£$IÒ_MgîˤR©$€{øqÌõé¼~¿òäIgˆbsâý[Ž9wqöI)÷ow"j:ÿ…:O~ÝÖ%lŒ ËìÄ­Ït¦+T#fêÍŸ„¸pú· ¨•J%—ËU«Uõ±…§'IM¥Ò¨šº<Œ¨Jj†<xð /üîw¿»´´äØàx<®|¤ròM'SŸHÝ|óÍ'Nœxøá‡¿ýío///7½™ýƒ¬K™*©—p+“ÒÙÑÝÈÚÀ_œ:ŸàñŽDƒ¨j×ít:O>ù¤ÆN3™ÌüüüÕW_}àÀ¯}ík=öG¤‹ÙøÎŠ&%ÙŒ®˜ ÃÍ`C /â=×È{IO –ä o¢¸ ò§ˆM‰™Â[ ¦¨v]Ä‹£¯æ†~¤YèÏF¢òþ·1Þ서MÀ“zÁ…BáüóÏ_^^^]]uJ~0­I '7Ù*²̉Ý#öŠÅ¾ç£ß‰NèÈD63º¿ j>‚JIÊá©¢W<a4ùV’„õ;OÆÑ4„+Ï.ƈ£î<¤CYÇ=³úÊÜAÀÕ®|ˆ/âø6H½ÎäÔ5^4Õ-žõ`šzÑ/ôz=r}"°|lµZ­¹X,æóù™™RJhºÝîÚښ̸:%©~Á‘%Hº�i®ˆ«âãåëd¿¯e¿ÚXþàòwþù;O<ñÄÂÂÂÒÊÒp<\;ÈýN.SÊpÚÒÇ&\ §âØ¢§è΄°¹œâ¯º¿vêHjŸzv…4wx zع\î‚ .xå+_955uôèÑ£G¢¦¬7"”’éfŸ)µŒ¨êà&D{Ê­†\ŒŠs_ ’7îE[s2?ôÉÀÄG ©'uUÄltª·&aµyÙDÑ Ó`ݱhûÑâÀhµZ÷Ýw³hxÏP§¹ö -Ç„Žg:yÍÎØ°ÚÈ®ÛÁi­æ ñKÎò ÓéthØ0‚ øãSº$Ùº£ðÚ‹øÈƒÇc[ØâRÌ.bõG$=zÝœkº~®'x‘#Ê10—°U],¡Ú£*‚¹à˜ássñ»vµÐ3÷“¸Y>ŸßµkW©T*—Ë•J¥P(‹Å©©©jµª§Ýl6ûýþÊÊJ·Ûm·Ûõz½×ë±TÓ¤R)Õ¬ÍfS+m0<ùä“*’`.‘ U~©²ú÷«í›ÛÝB·óÚÎð†aém¥l1ëz¯ÂëÜ90b©ÑÓ¦Æq�~ ÐÎL£Ñ¨Ýn£ïG)�vêd oË9½ó‰'žøâ¿˜Ëåþå_þ¥Õj¹ºWK†ç‚Ê®iæU;ÿ‹~«³4™‹rt1ú"Gº<rê U£<3}áJHBNäc ÕOzKaC‰€«BØòÂV›/ª¿œí4‘R…V•hµÞM%1ZÏ0KÙgß…ó„TË]ç…˜õÞb¡1dT €zÞGý¾X,*õ…îÓmîkë:ð¾RÙîþ‡`ÉFOجüiO¹$¦UÓIçF;žB† /"îUJY`µZ-§ÿù”œ+n‘7¸ õ„+üú©x˜I„×étŠÅb©TªV«333ÕjµT*MOOÏÍÍÍÍÍ …ÙÙÙJ¥’ÍfÅѪÕj­Vk8ÖëõS§N-,,¬­­ ËÕ2ã@TWc0ˆ_^*•ô–•(V ƒÊ‰Jöúlï†^ãUÑh”º#U¹¦’$Éxr†ŸíÆnÞîŠHzØL8‚¤ÀB¨×ë8I{yLî%U좒sV:]ý•••[n¹E‡5#çnÁ¡ˆD¸µ�„ú÷ÛMÓíQWù ¥sQ�Z§›ÃßqÎg§ÓqÞ©3V€+}ªÖácb- øä”°–‚©ºyøñ¹é­çNÈÙ†löÛ‘""ìU`F¡h‚•9»Ó`8¦§Aüðî(dMŸ’:¬í q3j]� aÁ€4~ ~î;|Ç”®’Knqf „O`¸‹‡ÀÍ B˜Œf`‡Ãá3žñŒ\.÷àƒ...FÔp7ª¦—„~¿ß×qÎ9çLOO×jµZ­Öívbk¼)0¸!z>:}¶‰Å WæjxB`U 4SMC°Ù·oßÔÔ”0{ö쑳~t„U«U=‡µµµ³Î:kzzúôéÓ™L¦^¯‹kÐï÷—––h“”ÅŠ„ÓétñæbúËéõ³)“¸îŽ 2õåR{îD“Ƶlý=Mloãsz¹ì•Áó¨Em‡ÆÂ…KɹÏÅ»9Á)tÞšÏ8òL�põRF¦< & àÅzdz­262£s ×`j:<j§hò sssÕjõÈ‘#kkkÎ`Šºka³Ì9ƒSÁ¦wBÎ6÷r\¹ˆÍàmÚtäM  ”h#É…Ó =4¢Uprj±Xtu¦È#9Ølš7T9)P¸òÑ0o!zG”+§ßãS‘¤G¤‘ÅÀ p¹`®õ.ÞÏçu¼®­­‰ZJË„£“Ū}ûöÍÍÍ=öØcz˜ºŸu K¯J…É|ÝW©TzÚÓž¶{÷î|>üøñýרƒaC[ÌÇ`ñåóGí|  yâ½’ý$ItêÙ ÐP©TòùüYgµgÏžR©´gÏak:ðNåÅåóyýBµZÍf³ ]§NRY£f²bŒ®¶\.­¨'”Ëåt!ÎÁ!â@’4xVîÍHY‚ŽÎq"«Åõ G§dÇ^jCKTŽn²Œ¤–�� �IDATêôK*�Ÿ­fa»æ4æ1Þw'7ŠÑHéÎmè¼ ²•GC_'šFòŒ“ä&’åfs9zÁ�å(îõi”†_|ñ%—\òWõW­VËÏ.*-—.”9÷Èo2ܽr¶í‡0ÔòìÛç±9²Ûí69Šî°›…ño½Î¥cɲ¦xw]&æ}œ‚UÎaáÁ@ûGÛœö ÛClov¸·A?"’ºþ¸ 5D^b»Ý®NgRº6ˆ^ú¿�ñÝn÷[ßúV>Ÿ_]]®Œ˜ÖQ1 Iœ«Á`püøñÁ`P.—Oœ8AÏŸ4¬œó… åÿu¿jTèh“7„Ê}5`ÚÔÔT¥RÙ³g~í¬³ÎšžžÖµ1êO‰UQ,<¨ßß³gÏêꪘÐ4çËå2ͽy n�Øû.ŽÎôϳP(ìÚµk8...z<&Í:¦˜�ªrµMxÞƒÁ@ ®Ë/¡Î�]è^ú·ÇÝõ^Y ”ôŠhr¸õªˆéÎÓã×Xrùô@Ëü—¹îaêâ¹m±‘#z*÷ÎcŒ ÖÛÖÉSõï~÷»>úè©S§´eºÝ.\s>?„€¶!»Ó>ý}턜m«r"O_#§]ï ê&Áˆæ“}º¤ˆtÏ."×&Џ°4‡5£3NÑq¾f0¹FàØAÎ%£1îNØÈ½ø¨Š:sÊxÛ#'"«rx‡‰Šô}¥å²iîäa›3¨ÛíêºÝîO<áŽX.D Á×i¬úÞf³ù‹(×q¯“H©z¥R)‹år¹Z­ê¿ª©S©T¦¦¦æææJ¥R¥RI§ÓÕjUåŽÖÄ9‹#å=uJÏJ¥R­V[ZZ‡Ýn·×ëU«UÊJb¹ÚògNÇ hP�h…®›ÖÉ®]».ºè¢………Z­F³„x¢¥Q纫ÎM÷^‚ß05(‘!€vå†ÖîMàà®AÁ,r³få0ÝéP(°‰]âÊžªK"³"X$¾ÞX¥nNƒ.5kÉ+!OOƒiPù”(z<°Ìù'Êf¸]ÛÊÊJ½^GF½T*¹+¼ˆšîÅågËŽEÛö÷rXOl3v‚;ÂRyè-‹E• Ò‰¢zEIÐ;4NÙò¸âOQë’™“7’$ˆÄ-¸þ36 åç‚/0HϦòVËÊ1;.€ž¸‘ÄEBô®œGüë÷ûð˜y)óóóÙlöøñã</q\Æ*0š«÷H[±X,Ib;Rê:u¥RICþ`€…BAxúÁƒÕÀO¥R³³³sssú'ÅbQ"Ç={îùÚ®¯¥“ô3†Ï¸©{S$†ÏwEmEE¬ÙÙÙ]»vé5›ÍÁ`Ðn·U9ÕëuîN‰¼ê`wR›]gXÀÎûH§Óívû‰'žz›MzªÀŒ.@£K ív›h¤Ë`úÑï °HΙŠDÀ’—QÏ¢6£¯Òшp*´õ\½ÕEäs` Ñ Gª=Ž:±˜Û÷BŸ=™ÛeJ|>Úý¼éÌyàT¤ß*¸‰¤ž‹øEÄQ! îHZ}Ý>*ú·;!g~Èvš°¡CZ§×Y©Tt:C¢ªò´^\àOï½VÐöè$òJ!f"&á@ùâ#Z•Je2™¬­­éKQï� *ø¼KÄòb»FCéç8X—-(Ï«xFùçÞÿÔ?ït:‘dØ'€ÿŠMš‰^>J#ËKɯ#l?ò<?pî¾ZBñ™LF$´³Ï>{ïÞ½»wï`4íÛ·oÏž=gÂÖ:…ΟöÆ—u_ö«Í_M¥ROŸ¸nîºw6ÞyíðÚt’vZW0­68Âå4íßëõêõz­VsˆfffnnNÈ›>GëpuuUž8{ªÜ,ƒª”sêèÑ£>Ú5í!õQF»x9æ„>òéüIÎk%.˜«—Ž@޲>pä–w�ª§Y0ú5J†‘¼#n‡»a ~ .> „N|m"f®}^;’òd!ÁSPQåÒòQñ-ðÖýuhíøO0ë)‡‚‰(l7}l·°Yít'älg¼á´%¡ ¯ÑöcÄš4D©´nÄG &ljæ’ê[HÓ¢‚&b 9äÅ>?oRaL%ØEºð\h-AñPJpÃlŒÜ™•AA€OÖ–CBá)}—'¶:ªé@öŸg.šà¡™÷ûýÅÅEúÁ4¤rÈ›|SÿD$^¢>¹Ùl:Œ®�¹<³ßÊ0ªÕêüüü¾}ûvíÚ5==-"Àüü|>ŸŸšš*•J`tÓÓÓårùõg½þ맿ε]Ü»øU½W½uú­Ö/<Ø?ˆÁ+e xß*Êåò¹çž[*•Ž9¢ÿ*Q :Þ¦În÷'ÆjÈYû!auSR‡Ãb±(È2.V­<p­ŠèIòØ}ñû£³ú"Ól:jqZ ›Å�»´¶‘È‹JXL˜s¥;ß‘ôQ¤h 8ásxU cã¤p’-3¸!Ìí¹“h,—Ð_ºS8sW)¥RI/"’ŠwÄ{0à·ÄÛt‹¦^Îö“¤õî¥üáJæ>¶¢}¢#U ‹kê1©ƒ+ªW¼pù^gEÙ ƈê"¸:¾©!8»5ôÃ0£Sø:o'8{•$2±K]¹©¶¨E0Á:všäÅ\aÚõ™Añ±êNM’À .PY™Ïç»Ý®?Iî+lÖ Ž¸Cî£ìT=:=1±²Ùl©Tš™™)—˪fˆšêv0Ÿ|šËånÍßú²ÞËÜnG—tMÿš[K·þBó|ôê—‚w¹\öŠ9ŸÏÏÎÎ*p:tHÏJXßp/Fu§Ó8 ꥣÇ/Ájut l_ÅœÍr7*ô}Ê„¬g4ùèö^첨8Ž}äÖù`<oÛx­C„óÜŽŠÙéš>=­%§ïÅX=b­#`Þƒ ›UÑœmp‘L’†Íþ¡Î>g­* áÙ*Þ»ö¹Ç Md,NмO�e'äüïþ�äŠj>N éÝ¿h~ÅGÓùð°y$˜f,½A'×ûæ2Òùy ,àç E>ºÕÙéΜŒÀœÝœ/”&ðjhH’úÉÌ“ É“Ç6÷ù¦€³×[ Ä<mTˆ‡O‚1@“:|Ä6U3Åbqnn®R©hŠ“£J…ˆœ~tIårYã ¥/43Í_™þ•Â[ºo¹bx…®êgº?sÍì5on¿Ù}ÿ°¤œ¯–’þÓ©S§ÖÖÖp|ÑîZtØjµ* ®ÝnÓŒÔý^‘|Ð?÷2È /'ÝÂ:£³×ÀAž°á]¥ùHxãI´]}ÀUV½èä{/Kþêáé–Ø: b�µÄe§½m A€cÁM•Üe'ÊõØ}¼”L+˜òˆï/Ò8Z•‘¯žÔ 6ÿXÞ/œU¦J·¶ŠwBÎ6ckÁfƒÙ„Þ¯&…aoèøCìˆBĵú£Zʧs˜'×¥4!>ƃ,ŸÈmɆ`NÃȰ³jÝ�˜P‡¿Y›¸ôYØÐÁô �ºÇLáWÈÃÑŸuÙ Ïú:"AĨa>œ` “£0@9þ †•.s¢'év&Ní“ §J(5TvïÞ-á€J¥¢°!›DD³G¥R)K®ð¹ÛŠ·}¼õñ§ž>?Yüä2ø«Æ_Æ]5IÃqìð<dNUQ™Ï>ûìápX«Õð0žžHˆl]¹\VH@ÞšC¸Ü¯^™3è·ù”1%µ3Ç´ÆfggE B%ˆÇëÂB[E‘¹S@…­^$õ¨›xj¿@aðY‹�«ã´ô6ÜSއ®¹×ÇLx.[×Fìtÿ*g+¸•§›m»{ÖVÁß^¯'lÀÏçXºÔ=Ù¤ï¬B¡ð´§=­Ýn?ùä“®Æä2¸;!gÛHÒÎõ| R2 ˜.‹ QÙ.ë$Ý3Vo¿»ÇP˜Â�7‹Ü¬Ó±èÑ 𖝫ñS‘ÈaÅ3)¼ÑɧÍlRZ_Z©TB+++:’pª‡!Ô©ƒ¨‘�–í3O"h0iD|…߬ÀO¥â§’SÛ¹ZÌ&0Š4†EÊRwAßè4™L¦§§EBE/ \.ë]LOOW*¨óBÞ4“ËåîÊÝõýì÷¹ýËíIûÜÁ¹!„¬} ¯«¾î/NüÅò?¸ {A§ÓQ÷B£]teÚí¶n Ê$I:Ž"z&“Ù»w/ò©úûN§S(æççpQh¬Õj¥RIsc⛈] hF) “ñk.ZÁÀ nâz€!„µµ5Ä“”¿Ó\Ù éöiº�;ßš|™Z¦„â$e¶T%ùAK‹JkÌ·^Ô‡»Èö!3£v§ç™ƒœ<ºH$ÉÕkquލ“qöž‹ïÒ ¹‰5¯G­[®V«—_~ù£>zôèQÑ�òNÈÙ¶^N”‚9÷ÌQlv”Oç¨õL@'·ÏúxËÑíQ¨õÌ$Ûgy¹_@Da ØxkÊÇÙ<Bä|ÃÇž½NÚ¿ÿK^ò’S§NÝ~ûí:õ¢íäÈ25M$‘Óô"CLD·@,#-8äj�»\�Ñ! ¯ç(ƒk€¥òEJØ5UâX,Š8 –z³ÊF“$N†wfï|ñàůè¿âš™k®ï\¯$;Î>oð¼»KwzêÓ¿Ñø E…Ò­«ÕÕÕµµ5%‚ªÕªÞi©T:묳BËËË ™® #uvvvee…p¨ð,yP‡1©•a€b9óÐu‰œÉ[Pî Y4¸†mL”};ßÌKg¶C0[OúOn©ç[Ò§ý=A+‹DͱÒð[ó>"ÿêʉ ‘°¹ ”¸*ƒ5hg¸³C$I·µøpw†°E”kPŒáIêÏKKK·Þz«,q½¶%ÎNȉÛ9‘É4°ud^â&µ¾“ ›ÇËßâ@‹Àծȶ¼¿°±Õ?O’¤Z­êÏþ]NìÆÄ{æ”ü:¾!°yÍçGF.—;ï¼ótŠéë ¡Ò“`ëê,vï÷ˆ°K<¢ÃñÎŽónªœ}}$ÞÕÒühZ#<^o8Ú@üPPÑ„f9u€æóyý¥R{ý&zá™Lf0ücþoZ½)I’w·ßý¶©·]7¼îµí×–’ÒK‡/}ßüû~¾÷ó3¹™_›ú5]ä9õ_2I¦ßïk¢BÒjµu#úFµåôl~o\CE`šê'M¹ú–ãÆ~4+¤¹÷9u”(°GcΪo\fÖ>½\hÇ€±0EY€Á,טÓòE ¸í·(Éú"gûpw®ˆèü²7}ˆÚ!.Qá N§N&:¿Z¶«D‡ÀÖÞ 0šN›<÷1µ ¿/p0ˆê‰v £*gû9ÞÜ‹¦ %]L©IÀ_ m%gs¹z ‰Æ¯�n@Uzœ“̓–“ÍÄ™Îf³_|ñE]tÿý÷ÿà?ð=ìÎ(‘,Ôç[5açŸ>m0þò/ÿrmmMÉ^š€þ9Ë™&P'¿ ‹ƒKÃp;E€ûL{›ˆ˜Íf»Ý.,^|ÀIXIÞyÒ²Žµs¬T*)«¯#Wýð‘¹äˬ$EevíðÚgŽŸùõìׯÛu]H…fªù†ÿáPúÐ[ªoyóý“0é÷ûïÜ÷ÎsæÏyßòû:+˜t:-5R5$D,×@<i]ü¥™™–tµn£®£]}*Qì!¨9¼›èoZ9˜”$´.Î_Òvazž´Eµ»#¥ÞÌ£N…ÇÌ^ÀrI Õ¿×å5¢¹þhn†$ Aoa²T*…!%…>îŠpÎÕ¤âA0×g‰€ÁEâG^ˆ’(ò¤ óAWõ Ä›H¹šú”µZm'älçï÷*‚èYDÄô‘4OñtÜxx ©g¤@E€ÏƒÑÉ€2‡PŠ7o9ô‡]»v½üå/þóŸ?™LŽ9¢Ù:^\*æ[ÂeêIµ"¤(¬Õj>|˜Ëv. fÓ›ÅQgŠ¢KäRÃãe6Ðs:Æv(†*”Zèb½xòž–Ãëz =súèKK¥’¤À&“Éììììì¬Fý2_§Ïì÷ûkkk{“½÷wî¿lrY¡P8w|î/vñ-­· ÃðoJóÑÒG_ÓÍ+z¯øÝÊïê^ÞØzãcÉcŸÜýÉ_Kÿmê=[Å!̽^Oó7™LfjjJ=3Š­R©ä.¥BÛ"Âd7iµ;?ÞÝhуÙ6œçâ|žì{óÃw«Žy/½‘Ñ�¤^5 9L©‰#„\ýBçøC ·A¬…tãv>[¶Ý?ž’š¨ÃDA$ÛˆBiÓåÚàºf§o(iPV—Éd:xçYÞŽÛ·Ãÿ„Ð1??à 7ŒF£/}éK;s9ÛÜˉ�t2µ¾]üà XjvwIòÑB¯KjC;€F«£môùa7::G’åô•v»}Ï=÷,..>ðÀ>�¥ŠV§ùܸûŠ2¹íÖ8þ7lT¿A‚Væª_‘IsôÌðÁÆ­€§Oá)Ï¥åC^‰7<TRE(yÐâ£6[.—“&4Ø <ÖªÕj±XdŽO½z}Z£ÑhµZ¥Æ«¯þܾÏ]¼zq¿ß׿ !4'Í?.ýñy£ó¾Ÿú~&Éümýoõ >Zú裹G—'ËÇ‹Ç&õ*KÜ ‰sœ“KÈ £µz®÷,ËQù›¯1Ô)Þ„¼M#‘ç™ÊèÐdaЇ+á3ÂÙ#Ù/sƒÉšyÈŒH• mF¼ÑèÔÛûÄ­^,‹f<úÖVõéBsü™ý¨uâóª ½ù„Ÿwv]òÎu—JóÂT9JÏÈàCï½×ë>}ºÓé(Ø 9ÛÌŽ"£m®äþ`ޤùnüîÞχ„Ê#“Ì•—`^¿Žü@اÐ%o·ÛwÝu×ý÷ßœy‰';ÝjW—Šö’‡Ÿô©Rç h« Þ3è_Ú!dþ:“ûjŽ(@q®àÓv&–»<ä"p÷q\H‰ªê*¨€ª2U@Ä>ãŽâT«Õg>ó™ÕjU²fÕjUÑE^Ÿêåè}é-è2Êåò¥¹KO=þ+»åwš¿óôðôñxü‰Ò'îJîú©îOýaùÿgãÞ0¼a4YßoêÝtËè–7L¿á‘Ô#gOÎl,—ËRó¹@¡Ž‡ºhx8Çc±Ñr$kïjÇ>óö¾Ê£(¹ñn¢)³tûÀ?9=õNLf©à:µ©½¨­MƒMmG‹Üåh½?ç…û¶½>D@‚KÅóPVt1ƒ ñHéü‡j];ZîfÕÐ^|šµgf?TNÛ¿WO‰è®s&˜b!׳²²òo|c45›ÍÁ›mÖ¢Ö:|Y`\ø¾RWc€ŽYnö€j¼Õ=‰×)Èì®°1w5º½gèôS…„f³6´RtÚÒZwšŠÃôn‚Á޹9Fçõ…$ô¯ïwßÕÍýAnæf:Nï§{Íw7Ko(…ã›(Cdxλ&•£y.)=“:̨K:'’4Ò\x˜M+ ²:ðÒ~Ö³žuõÕW—Ëåûî»o0ÌÌ̈E­ˆèTD½£™™™©ñÔ›»ond¿9ó›'Ò'Â$¼µýÖ÷¶ß{8søçÂÏ]Õ¾j”>£Y>_ÔÑ/¶q8Xoã'I¢aRå ‹‹‹rVh”ãÜòòr·ÛUdµè d³ÙµµµÅÅÅF£Ž�ô-—€ÑФzc`S1¤6%}–€á\o¹Ÿž?gÀ4¨„+€äyÍŒˆæ|TH9¹Ô-5ÙªDAW„’BLä#ç9¨>–KPP]££|¬i©Tbò;¸3𔼣¶ÈN+7rsO×asA£‘Á+Ûg4-//Ãkß 9ÛÏXƒL‸«¥I‘^ý[%DX3yì!ôþf†™ø¡ŠG›ÖG¬ñº¦é­Ý`#Üäª @1PäilØìE‚(ßtª·ôQR©Ôpß°÷ºÞÜ+æöïß¿gÏž#µ#‹ZÌþ÷lë¶VáÅ…3„Àý©Á³©T*¬…ðÝuÝ ·6 »à3­èìª9ƒÓ–|†T2Ïh½nå/1"£x“Ïçgff$áB(—ËÒ-–¿µz9î@LvÌÀJ))ÍŒf>ÓüŒ2 ŤÇÃã§G§kÃÚtfÚûd­ÐZ KÃÑކbp·Ûív»Ífs48p€Ò¡ÛíÊÑ X,*%I²¶¶¦–@è *.5¬÷‰z$FÑi¿K‹uZ_6ú.¼n½Q‡F”Ë6Ý¿9WaDÚKúy=4 É]¬‹Œö¼>‡dѵ$$èn<+¤`‡ŽF#YÚ¥)¹Ñ¤”W?ÄTgµ„ë“!yF$Rý[õ} oFJ¢È/|'älÛOdßâbÌÈ]jµš É?T—†n{в)9:VNùø¥z¦£CŸd-Ú¡ášbE¹Y+>Š7‘1ùaω:íŸl¿Z<xðà 7Üðìg?ûÎ;ïüú׿¾°°0øê`òêIú«éBÿ×ú©r*äB’JFÃÑèÅ£Ô-©É÷&N:ðÑ­yGW×®9ï[×çɭݨ(@™Äd2YXXøþ÷¿/y‘¤ ï’½t†|˜AR.½^¯9l~}ï×_Õ}Õ9“s\�ÿþüýŸ/}þŧ^,ßeVÑÔ9uêli걈·V*•TϵZ-Õ@ð5“Ap_ól6ËqìŠ,î÷[5oHŸ¥žàlÓ‹Vµfd½ìó‰nêá='®ÊÉ&ø‚»ýaCývבŠ\yÜ”zΗ )š(é*4áø‘Á®ñ7¨,:ÌÎùà£QDg¥{¯+lvåpä#bT;ñÒ«XŸнÀ#ß 9Ûr<×€T4 ,5™¬‘(©t ¼3g21gõh°€ž­AŽty}Ã_æóùr¹¬ÖC>» N­-Á&ô ©Ì{×` Æ¾ôÏ,ñ×MöþôÞŸxåO\wÝuû÷ž>uêT§Ó™|yÒxW#óåLÿ·úéÓÉ“Iöl:îå{£—ŽF¯MÚ“Éã}wp†¡q]0œ@:'*E‡Y<Ì;…I/ZX™>Jà•Α———ƒÁìì¬pT]R©T"YVÕlÚ\ åÂý~¿Ùl6›Íáp¸¼¼œt“Oýø'öâÛ“oÿIëOtÍïž~÷Ãé‡CŸÜóÉoU¾õŽï¿C#~mmMõt½^×ñ*³œÁ`púôéV«¥dV¨š~¿^¯+Ì(Þˆõ«®œ;ªHn…Ì”ŒsN êIŒ˜°üØ ®Ÿ°ÌCÓÅú<¶œ¼›âh!ÍK¥_¤í|@tÁå- 2;+5˜ˆ»º#¨_#Ä×ïë\¤Ù£—‡ô� ›Üÿ”Gáü”ð_ˆ0á„n+ ŠPVwÚÞ 9Ûrèjû¸i®JT&r\l }Ñ�”‹9¿a‰S¿³@aR’³h»º†&“6¹*D[M<Eݪ˄‚\0,Jº;¬!{]ßóa¢¦w·Ûít:KKK'Nœh·ÛÝrw2žŒJ£Á%ƒÙΆv(VŠétz܇/…Áó£ý£ôgn"ƒ8gx3«¡_Õ$èX?1•y½»ˆð£:O`b‰¨ˆ‘،޻žšä^ú¸ ‘KЯ¬¬¬®®ž<yr4Ü}ð`éà ò/¸zúêTH5R#é#éIúW×~õ§W~úXëØÛžû¶kO_ûª§^•eôÒwíÚ•Íf÷îÝKÑŒž›Û*+ ž7IKBdK§Aj‘ Nì™óâ¸Ô%-¾§?CætItgŠÅ£ L§–!ZÃ_Fhó¼ˆF¦ˆ„+~Ç­ñ�•€÷¨7å–ê$ˆú}WNÓ¯c_Õd;ƒï\!#è{#X˜b¤L†.ê‹3ü“#2ŽGnᨠúp:EÈùNÈÙ’4&áÞtj²ëU0뀟ô¬€"¿€…³ÖY(„Î?]'Ô­Å·q×8bÚ<Î1CÞµ(e�üнä!—ž›$OÖA›û’•sWn¿ýöÑh´wïÞ;î¸ãÁlµZ× Óÿ–îÿ?ýüGòýÕþYguå•WV«Õ;î¸ãرc…÷ÚßjþSaغ‘¢K¨éHÎÕs“ !/+#ïÂ*¿˜0Ââ«iµZkkkSSS‚`«‹$¦™ ? õuòÖdLRï¨^¯ëѽòð+oÝsëÇ«÷Ú»Óéô‡ŠÚ7ÜwE÷ŠwÔßÑév&Ë“ßì÷?û¬ÏÞž»ý¥­—‹ÅÝ»wŸ}öÙ²†ó…JH†K2™LF³Ù¬×ë+++j䍨Õù(îu0Ó Üt¸`ŸÆ¥Cðï)lê\¼Î5Š"TÖ©¡º ­"ÿêg8‘ÕQló¥‘Ûžëð†Í*ËÀž ·N³Ö?WIAÓÒyaxíÆf¹}’4OàR[ÞàôôdP´u¯¹ßùV­ðX÷ùæ%|êßB'þø�.>.z´r¶ÿug>J="r¿)*í>Hô´xÍÝnÓ0FdÀèH\ýÉaeúú Æ»ØÉb‚2hFÑy/®Übæ$í| ¦›©}ë$º/“É$÷¹ÖÿÛ:õ¦S·ß~{>Ÿ?yò亣×;†å«ÊÝtuãÏ}îso¼ñƹ¹¹ÑhT«ÕZ¾Ÿmæ�� �IDAT­V*¤FÃWåØý-0 TƒA¡P¦¿‘Ãéðþ õ»­ºÂú"éʨ¬”…@Heijn·{ìØ1�•’FjÃT*•·,½e*=õ©=Ÿº3sçÞáÞ®}°<,OÒë'B¡Pxný¹÷LÝó¼µç•R¥|>_©T´T‚ ¥èªT* ö 0­V«Ýnw»]KzNØs{rÞ;÷ëZ8^_úŠÏ”ø J< JpòqWŠŠR´'\Z_YÊIQ£žýåª6äþ®Æ†v�7ÂJ ÚÀyÖ«íÁµƒáeÃQj”J¥R!.““ì§³.ù£â Nd50¢ÅFiJ"·OÆd"XÛÐAŸI÷‡ $�¶ì~Åb1ª‡vBÎ6T9¼f[ÐÉ lò.¦{r¸29ˆ*‹Ì³'çæÓôc…VÕ·FÉ ™»$¡“_�(_3¼'¯9œ»P`SjOtA¨ƒXuŠYÎdnϬþùêä&Ù³Ýn·÷ºÞðÕÃâïG£Ñd|¦GÝï÷WWWkµÚ:30LB*s A<˜étÐîáç—+º²µó§i »Ù0>1„g¥™ºµ‘¤ñ£B÷›²u0,///,,¨¾Q…$ÉgÔ r¹\)Uz×Ú»>\úðùýógR3!{†t”Íf_¸öÂ/œÿ…b¯˜çêõúâââÞ½{ççç¡Ã1]4;;«/‡­VkyyyyyyuuµÝn·Z-)ôÈí3˜\<d?ò*•À È›".é”Ü­}Õ£pÒ\ãËG|ˆ2ÌBœ”ßìuJ›'ïô¨¼©`ã·Nƒ¶Ng(•J ®ŒŸ=Î<˜)}­´†ÿøpxî°ÿ ýüŸå;À@«k¸!dà¥vÄPw­Ü¼‚PØìôê¨Û‡CG�:¸¿ ³=?´=¢7ü«“ç2º5!¤{Z;>_ •VZX`kÎ`9C½LBçf‚ø*]‚“±Y|¨Þ¹¹t&=Iz‹ '¦>Úšz!¯ÍaæÿËdnÎ4³9¼d&!ó—™ò;ËéÓéQf”úýT÷Ýéÿ<ý½ï}ïÃþp’$?üp»Ýîüf§ð{…Ô(•JRÔˆ”2ëgÇôd<3®ª®L³ôîRöX6×ÈíÞ½»×ëÕëu7—9@ Ó›X”ºÇ6õ%ñLö𨄏L²S9ô:úý~±XìõzµZ­Ýn/,,”J¥]»v‘OèY¯žÇ“$ »Ãî¤ÛÌ7ÿhöîž»{4]súšqvœËçz«½ÅÅÅñx|ÖYgJµöP°Wó&•J5………z½¾ººê2K(Î… u(Ñd43úÏzà½^hFŒó°Y)Ð/:Ó-eW,FƒÐ y9µ•Û©|b  Ú:þ¦%]("‘i·YrÈ.•JM2“ñyãp"d¾šÉäÖaêÌw3Fgtã(”¤9ßf-±gÑÎáy¢º õ1ò©óÒTœwÇ­¡ÒN¹‘_ƒ¢ŽK±Šv€µ‰*‡§)çÉèH 6!LéCpþ*ë”úì œ§ ¬ô–-�Wd)„(Y¡Ö–uƒWèö®é%é$“É„o‡Ð8ØpS�þ­ºñÓ~Cæf0ÍÖûóý$9$oOr“õ'Ò!¤C’$£ú(y(^=<õÈ©Ó÷œÎçó½|¯{u7•N¥Žž!s¸ 29gÒ[?œ*WU´Óš¿ßd»þn×åS—;vL£ÔîŸÈk±5lxÁéyâ6 ³€q(ZñÃá°\.kÈ|jjj8¶ÛíN§#/ƒ­´A[Ãá°T*I ºV«íÝ»wjjJ}MCy¸0uá©Ì©ÕÎêË_¼5믷ý½ÔjµÏ~¸—íý[ñß^ØzáÌÌÌôôôüü<o³Ýn/-----‰ W«Õ”»hüS®+++õz]ý-ç•‚ïg.Ðy’æl¸òÞ†¹rs#`�&r¼Þ‚×”kÒØ6˜Ì âo”à êuÂÉx‹ HAp…LÁáN ¡Ò0I’á…ÃÁ¥ƒê;ª£ÉH±ÒƒHîOÆWŽ{¯îåþ2§\Çù^f‘?9\H»0a²L×& ÷…O¡]éLtÔqn}¤ðÆC@RU#’ƒ;!gÛBÁ{úc1™èm:ôõ à|ŦrÔ{Ms:]–†ÉŒ`j7®Èé•Ù›Ãk‡ƒç ’„Tèûã‹Ç™Ó™Â§ ¤EßúºWFOŠê5“8?H‰Ððë¯`š=÷۹ƻ“s&“WLúéþx4ãÿJ>ýDz4¹ïÙ[{×ôræÊ¿[žä×áˆê{ªýörñ¾Ü×ét!pó BOñ¢ö».u}x”KºûŽ˜Hø¹ée5 zÑúü¥¥¥‡z¨V«iT¥\.×ëu˜V«5 æææ¤{¦YŸëû׿uî­—%—}#ÿO/}:„Î¥gffJ¥ÒM›>röG^“}¬H%é¨åÑjµVWW%.Ðl6WVVÄ„ît:­V«V«­­­­®®jˆ”È•|H<<¤ >4Å|N_‡ª]|âõ0þ•ËR�‘Ï9LD%䈑Œ% ?͵“•)²r‚ùû‘<1þìbÕ„´H0²ó9l6;77×n·Ûíöºþt’•Ð*ŽÙrkÁ4>(€ðüWú‚ÊK\! ÃA~O‹ÝàÕ_´+îDop'älçO4;e@äDÞ½t¸†ž¤‚6€25UNë ö\NëÉÅÏÐ}އ„q«g Š—5Ž$IÒn·ÃËCê9©ì½ÙÌ72™tf8Ž^0 †þ[û¹Oäèâbè â[±NUWž¥Rú°y@ÁXðh83sú¡dò´Éä²Éx<NIê;©l!;š¬§ŸQj2™$ÏN&û'™?Ë8¡ “ÉŒw_Ð=qá‰ä;‰“Å1útb•s(¼ÛL.ÅhFa†¢N¹±ðh4Òü¿èÔåry0œ:uªV«-,,Ôjµ™™òY±Æ×ÖÖjµš2qʼn|>ÿ¦þ›þxφ#¡”µTííóoîà¹W¦¯|GûÛõ±›Z7a—©SiaaáÔ©S+++F£^¯×ëu…©4›Íµµ5 ŸªJsjÞN0dÒ*lø¸ ”>˜¹uØÖ+{G†yòzídoÇI8ï´9�àx¯ËqúÔ°<FwŒx>©)„útA’$Ýa7I%t•CÖ$éÄü.@Ã&~àÛ…8CdŽÐ‚?,Ôs/[)eÈ'$·± sŽ Ó;$é ®šËwê$•x"Œ)'ݺ™t„ 8" ¤ƒ§×(ž ÒÚJB¥È@ÙZ¶(úZô*Çãqº_0NJ%_K²ùìzWº¿Ö¼q.¤“Q"á ˆ­D‹h·èÆõi�Œ“Ù{Îæ !‹E`¥ä©${jÃn s†¶Ç=úi’šM%SIîT._ÌïÙ³§ÛíÖjµÁ`V¤3ž5Ì…3–š*YôÏE@ a$Vt!.Ò˜ÇÓÓÓºÇÁ`P.—u(ˆ§ëi·ÛÕju8®®®ŽÇãJ¥Òï÷+•Š&4ÅÞ^]]m6›�­b*OOOOMMMMMe2™ååår¹œÏç÷7öÙsäÍÇÞü“gÿd6›KÍ}¬ý±L'“éež‘yÆßîþ[W.õzýäÉ“'Ož<qâÄòòr§ÓÑ×)]­×ë©H %Œ�À~}¢ƒ ÞµKÙ‚¾zÞã IŽ3S+(+wIiOù£“=ìhòÚ§ta·…vzkS‘ÆÅa¹TTö‘‰å¨@w §i¤Iî ^?H>“H³No¤ÿœ~ê©üï䉋sª•}>ikÅã)všª¼dëÈ9ØžÚ\ú0¸¼Í`Bm*·ÛèÒ¶r‚3Yî­ Bû‰Æ>(Ã| æ‘jü\û€ò·vtºØ«7>9A—b=ñ¹h<¸bPü•b*“šžžN’deee8¦þ-•},Û{M/ÿù­®VL,;^§mé6ïôxhxFü`-k—^ziµZî´Òô®/O º>ÚNÒH>óè&a«o88e¥Ž3ç_é\û™†s•öŠY ™›~¿¯«Å†Dá_Seyjù®þ]ý~fmæ²ÕËR©Ô¾}û²Ù¬êé=ƒ]»v8pààÁƒò¨×êZŸÙŽÎ{è¼þàÁƒwíÚ•N§WVWF¦?žlRÜRAS«ÕVVVNž<¹¼¼,ÖŸÞÝÚÚšLÁµ<er&=t,ÈǘU{¹ï˜OähÀ™î…’¯jÖC$Lœ7îÊâüðÊÜÑYîDív£3 mDn°ŽˆâD(Õ'Þ¤P@ñ‡$6ÓaRO¦Æ—Ãÿ²ÿ]g0^5§J ֣䌈§nÙ«=O:#nw`DL9Œƒ`¾éž(ð0©¼Ñ9Œ¦Ð\6‚ЮüÒÓʳ ?ôH£’ß%Ð# »Ñk#R*ê+ÿ(7wb?l5N§Ósss¹\îøñãú(—4gÕîÎX ŒÆd”:©Q¸ކÎ�6è.ŸP˜|Ü/Jl1VáÔÀÈ@ÿpiiéøñã:Á‘Ô„"A÷•Y¦Y³Ùlz!,'½‹{ÉÃI­VCM²ÿ´þ¤:IÝšòÀé‘ü!r<S˜ÑKQ¼Qš\©TÔÔÕ–n·Û:|™¨( Åb±ÓéÔjµ©©©Oû©\&·º¸:·ãáwö~çò'.?Ð=0??ßét†±4@S­VËå².L¾«j¿äÉ—üÓÁºzáj!u²H¥R_žúò«[¯ît:„áf³¹¸¸¸°°°°°°¼¼ÜjµVVVZ­– ,±Øõ™X¸†c¯×Óq¦€u8àw)VéáH³‡¶–ëÛBÐwç ×fD }âÒë_ÿú^AÐT]333—]vÙÑ£G{ì1"þ¡k>EX““âüxu¶˜sÁÕõ<ÏèjÿSz .L~lýÞSýTòT’ý_Ùq‡”[°/¨oþ½ÔÖ{]mB߇½ÄÀ&×´+ÐûNÄó9ý<´#ê•BLJ゙z‘‰8EÙC’W÷¢a8.yåѦñ1õÈ¡U%3%ÚãÁ,èAŠ|Äsa4ù9OtÝ:EZ”Áiý_P\JDÿ×óÖhÖum.LÏöèÑ£Ìù´)W®¿”(–Ÿqãñ8YH2«™Éå“Ô#) ƒ\.7>{<.³eSé3G!i=dæÉÑù‡¦ÁÜ~¥RÑu …™™£q6SÒ .â©@³Ï½øsW/_]\,Î,Ì‹ÅÌ|æÈ¾#ß~î·_TW‹Åâù矿¼¼¼gÏpQá'ý~_ð—öÿ ¼ðO®ø“Ÿ8üÍf³ÑhèINOOµôÕO?ôéCõCº†ÕÕÕC‡=zôرcâg£ì=ø`THBit#s9Ôã™–ÎDìƒhº"*Í0J+=gDð¢q7÷Oóy ²õ`Ú Î;ÐL«cA°„}�€»-dŸzFâÞ‰. êª"ë ç7sé[Ò뇢á¤ÿ%íf‡ã!ÝGfY‡ÞA 柆û'_M‰æº.¶L´›ÑŸ­RîPìÄŸÿóyÕm<iwBΦÑHŸæõò“)¡É>®å2㨉ø¤ŽÆ}çææ¤ ÓヨñûA°ºº šáÆÕþkÞ’=ã¨ýØxü/ãÞ½ôŸoÒ˜ —‡Ô%©ÜÍMRg�: 26Dަ» +CÏ#ÂÖ"{S·Õq|€ã^!Vÿ!wísfž\–;ÿ™|çÝÆ×•·VB* &ƒú«‡•PzO‰ÔU±¡ùxbo¬ÓG¤�}¸Ð³°ÙáTf3rEc$K‹Â9Ë˽‹n¿¨Õjå«ùb±8W™»`pÁ½³÷Ögë…“…\.7???33#¬¦Ñh4 ‰¶I€Np2™¤‡ékpí{¯~ïk{ÍÙ§Îîv»wŸ÷]O¿ë—¿òËßk|rí‰'>üÔSOÕj5Ñhœpqãôó¨8eÊà> JDÔBçb"etŸñ×꺟a³›ŸGïpÐuËZçU‹ŽA¥«ï]]]½÷Þ{}Zh+¾%l.'x�û�0Ñ`¦;¢ ùæ™FQÈ­Ç9¥Áæ¸éšDô Çë8`¬ eÎ}Á‰…¡îfðA„.IÁBÁ�Œñym:Ö‘ëNÈÙÎÑ–©óǼ ›í“}^[*­?&Ø•&#õŠŸ¹óõ÷:ïüÔ†ÀêRi¨òøš>C•†ðx]9þÃôÍét’N’d|ÕxxÎ0y0¶†:ÓÆÚÿÐ]ÆÉñ&l ¨2lá $°þdèdŠ;રõ|†<‚qÒéô¤3) <L ;Ÿêè±TÞ[£…¤´ë éÙ OÞŒäÔ¼‰ÊU*•V«ÅtiµrRabzVÕjõo.ý››–n·ÿ~EÍn·ûö#oÿùëþµO½ö¾ùûæææJùÒ³yV»Ý‰NÙƒ°SÕ»ú®s¾Îoüà7¾rÉWþñ9ÿ8žýÀ³öæŸm§Û‡G‡Óé´Z8O=õT½^oµZ@+šbJ21Œ>„Ô|ÊRgàBäÔN‡aR ”’Ï!£¢ã3Åa³!‹[?}ÚÔÔÔôôôââb«Õ‚îåþR óz‘­-…‹“ÅH§9ÌIc!�zT-î2G•F2Ç„,31Tf‘QÁµP(0åD›°Y/Çí0œÐL.ÇߺˆyH´£©L=VÙÖ.ÚNÈÙžƒœóe.«9°‹¼<âÀõ^BØàrÝ£(òóÚ‹to×GþoøŒéɼ’JB>Œ/÷»Ÿ¤’T*5nŽ“…$û¿þöÞ=Èòó¬ï|OŸÓ}®Ý=­™ÑhuµdK^YrÙ.|!ÄÈÈ›ë¸À”o›wI¶6@ذY Y ¡Öã@ʆ@²„ÄÖ•pó…õâ²M ¶e"ËÒè®ÑHž[ßOŸîÓÝgÿøNôé÷(ùsÛtÿázÎù]Þ÷}žçû|Ÿïw¶4 ê¹0;zM¶úº™—EÚkîQû¬ñ³5 ‘2ÛÛÍU‡:´‚® Boï.|ß$¥™Ö %—»\Î(QÉ6ÎÐÜ4ó 9ó€s”±&“ÉÞþÞsÏ?·°·pêÔ©k®¹&DµÔ²e¶üñëþx¼2Þên•FyàÕÜöìm¯>ÿê^¯¦u96XYYI-¦ ßðÿ~ëv_î à yË£Ñ(LèÐ¥Œã™Ø–Âw²©M0µö÷÷]ô¸ i>´y\ÕN)‡2ý—^å°÷9ž¹L¢ÀtÆÔ^»àï%<TÔÐJŠ·ͬ„mžy,e ,˜¡9~Ev8Þ­Ä` ùÐd²t/CšŽ=£Ñ¨Ûí’«Ì(Ò^£o„p†»¤žßH;™ÇZõÇ!çˆCMÈ´[QB3Þ•ÎKÜ<.V€UÍíÉhÝuÎe†Fù|ŠJ~ÍýXJpUHê‡JùUsøO7g?3[ÞXZ³­ýÉ~óþfs³53¤pQz÷î%ÑËŒ ·‰{& †ª`»ky•iç¨iÅØÈ4 %eåG:m袚ÅcI3f<×bÛ}†±-(™£™ßh4:yòä`0HèjµZ½~oPiÅçiÌÎÎþÊÒ¯œoÛ¹·•?/Ýn·9×|ê¥O]ºõÒó ÏŸ¾|:ÙIœxb¼–yšñx|åÊ•CywÛÛÛù¿˜î p‚JE„V¾©V,´Ÿ¿fÍB‘Ç8€/ª�²IVà%“o®±ñ iœ{«««!vgíè¬vðód ç&ÖœéæÁ¾KÌ(bÕ®¨ŒDY¸¬ˆmS¾È«aOζ'Í0Ìâo˜ª®\ï²–²œ,RWM_˜‡f¹^ïÁ¼\\<œKUþ[Ç!ç(éüÙLyÖDÞ1G°ûÕ¬òÄOD¿ð  a6FVm~‡òÜ2‘(²Y: *{Í`;Ä”RÚÔÞÛÛ›mÎîííA+(ÎÁ�SfÁbkhÓ§r`*"OiªPàáNɃêõz æp¢<}Ýh4æçççççWWW±�H6çêÄrv”›<7+ã1ºÄWXi‚V¡Ü~fnò «üÀã?ð¯û‰åÃa—---ÍÎÎn67¿Üýòý`wÒ}tñÑÀt¯ºðª/Ýô¥•“+£ £vë*m$©}T ¹$üä/óX¢ÔIS„£ n¯ÀTZ -DØŠd“,ŽN¶ƒDåŠ\·Ù4¹ ÚoîWg=ýsö‘ã3jad‘»p%V0‚Õâm’õ`ç‚ü¶uì\ .ð™¶C­¼Õmÿa jº°lÏÒʇé&;+²˜·Ë#î.!ªHý„ˆeßÒ›PTçËÅ^ú—Ç!çèé‹‹‹É@í\Àj¨øEj†’­Eá …Ý˜Í†L'+¾2þcu²úysv-5À9ržÀ·ó‚[,V·d‹#ºîºëúýþO<‘Ó*“ó¬àü%‰3‚„1{§GMyWéÇ-Òd@@ÌaPº™ÿj•”¸«!WEJ~š6u¾=ã´=Zäò8C‰Ñ�A¹ÊýΫ‡¯þôÉOŸÙ8sËó·loo/ܺð3'~æ¹ÉsƒåÁ\wn~~¾Óé\{íµFã-O¿åCoüÐ-OÝò’ñK0àÊw¥{BA‚õõuO¨ÐK/rÏtV^‰Wúͺ­‚@‘KX÷#s€²æÝ²†‹•nD¦dX„ÔCæ TFæ08lkVd`˜f›q$Öµ&ítÊ⊧CÝŒ4Ÿ£) %Dd¸þ¶_ã_‘QÑz1‘̨”Çb8{!$LúáPzš1‹¸NeÀ’o+n^:ìA;¸3ogôÛYàqÈ9bT-#åYs¦½{XÚ{žÕŸåER NmÛ%%†¿Œ¹ã w&çþÖï3pAñ”ß÷hXþ!”×òF½Yîùý~¿ë­·^ýõO?ý43Ò¡�7 ‚–õ˜ÝÉ,‡µy|ܰÓâ÷œ¦HKˆmɲÍã¨Æ, uYoÛbº�îH RÂbЛ€Úï÷!G%Æ·Ûín·›'û?EÉß~úo䆜mžýäü'{½ÞÉîÉ »Þµù®öoxjøTªn¸á†P®›Íf·Ûí¶º¹¤<äŒÐoÌN–“=Š¥q•¦V†ìV5Ïqcs²HPcJ§DhAªN–øƒ  : 46÷äJyÓáÓ¸{²{@a (š²�½ r8JAR~çH_Ì*‡%yè¿òÕU»Èò©Ü RI ÕN#èêSv{v5Ý;8Mþ^ó;*ÀÓâ n¯Ò b(혱v”?ÈY&÷þ¶Þ­óz}8 2ZµÄ×=7z%0Å4× erõf +AIbÊQÇ8w¹`‡ c^�‡sÉÑhôÈ#<ýôÓ9òh¤S{‘W&h¯y7–ek{>æ—s¾‡—|âÄ ÞBM³’\œàæ—ñæŠi ir9°eH(`z:@ТÊåI­°¶¶¶¸¸øÎ'ÞùØè±‡ËÃãñøî›ï>uý©TfÍfóÌ™3×_}„‡G£Q»Ý¾þúë—Ö–VWW›ÍæÖÖÖp8ìv»óóó!Å5›Í<gzÔ¹€T®F̪ꄜÃþÍžÛ M©œL¬'°œ=KrÅ ¦>'2×V§4ÍTôÊÏšë‘ÿ4Ý‚²l‡UpŒ†íZ ¾¢q»> ïEé�nQ{—˜u]%Ì>0Œç7Ÿo¨ƒ½–T#jÀvë=ÒÝÌÑaUjM P¤pe|rŽ,ä¤7yßÝi»Â (’µyx4½Šµµ52Gmú+ô˜W  Ë8* µ+ayÂ8*Ù¢#BÞ5G–¼¸ Ò”…¼°¿¿ÿì³ÏºEж›}¾x蚣aZ޾2×"ÉL&if,..v:µµ5þ¹gkP:Iþh÷šR° *QêÄ’\�v»,‹ç™Oèv»Éî3)ü'6§NÚßÞÉø%ƒÁàå×¾üîswÿÔu?ÕZlÝÔ½éšk®9Ý?}bæÄÖÖÖ¯t~å[÷¿õ•½WîÏ]­b£`}}÷ž/¯)¬‡Ô+ x´Í«‘)NÒ8ÈñR,Šœ¤aww·ÛíÍ3UÄjcÉÀÜ¡Lý]4DY5–ª Ú†•Sr><eSž¹‡OýLŸ¤”¡ãuÕÞâ@é£*òR8L«pïØMë~VÒºü+¦”Œº eÅZÚ§šp±NùNa߄ͣBE Oìâáph*)5ª‰”°¨†k_…Jˆ4÷€eò"säQ,W¾ŸtMÇ4Ëœz¨ >Ž‹Œ‘µqÀp8$JÌc¾,_…"á@ MšÃ äƒHhøßr W6¹ÊÙçc4ë›\›îÄz2™d°ii)Ù4Ö¼#°±«":ÿ—ø U4‡QHSî¢ÎÉÖe4/à¯8q7A"WøëòåËWN^yºóôï¾úw—ö–þê𯾦¼æúýëÇÍñfcó•ÃW6ÍF³±°°p_ã¾gO?;<=\]]½õÜ­§vOeUìììôz=ØJN'È[Ù”ƒ¹’N§“QPôXƒ€¥ˆDVÎŽ)¤Étã\†²†yž°Š½*ÌvµÚôaJÊEðR¶6mäL'Éò iÎS²—ÃVfLY‚x'lзÏuâ³nº„%JÁrËaÇ@Ø'2S\Q€é® *)�� �IDATª¹Ëe9{Ëò®^J%$ï€ÊfD%‹'L*I‘®È{<ÂvÎqÈ)n‡TŽîp@Ñ¥�xÅg°øÇ E‘†Ö ôŠ<Ïli5ê:ÁÍÏ"Í7¶ 0Në×z°±¯p@ ªåkÕ“‘¬͉O¹CŠW‘/ª‘òp8\ZZ $Åງ~Œã›^Á“a6Ö]S¨<v&"³uãðÅ9¼®á³A\Î\Kæ½÷ööß{ü¾kîûæ+ß|ïÚ½»3»›ÝÍ;ø·ggÏÞ²{Ëû¯¼ÿ “74º'šOüZÿ×>Ýýô½—îíÎv¿xãÿâö¿¸ùÊÍoþÜ›ûý¾Õ”ÝiÈ#êt:™—ä9çâmïÄá̵Å%’q¤8˜yWœ]*W ÙÕ†R²Rüô›ÀAvÅRiČܑ5¿‘”›› ÇÏ/–qC¶ƒMêÂÚÊR4EŒÊòÜü S{ú¾‰;¯|~� ¢š366uÅuÑøé=N¸eò4+™!h^–c™[²í=K‚æÙ1°vÄô¬’ÀVü=yGm%­Ëô\TÖy¯îµššâ_°¼.i W%í|Íç1éxSø-Œf“7»¡PÏÁ96ó’€Mœ ‚"}T ¤ì|þTf ç•••“'O2<O¬*R–#ƒ«ü¶éc[ȬC´sNg~~>lT”åË$@Œ•¼!‘ !­ßï§’HŸcnnîJûÊÎ`ç=Ͼ§Ýn¯ì¯<¾øø·í}Û¸9þùþÏ¿©¼iÒžl–Íï¿æûš}¨”òààÁ_8÷ ÷\¸çÉòäû_ýþáþðmÿáméñdÐsW ÜXÍ ¨ƒ†+­ é¢ÙK± TÆÇ,ºÁëÎÙבÏI Êlõ"ÿ@¹¼àîzP¸¸±Du±ëBêÌ™3¯xÅ+ž{üË¿dNˆNîs XEÎë@…)PY‰ ‹P´yÒÓj›ÓœÝç”ˉ”ת]VMö0uN¨3pí8(©mjt³f<ÖÍ–¸/*IurŽ�U³‰ô! ‚Šd̼–MÀÓ¦èØË2”Æ&º°ÈÈC“¼$¤Ñª)‡…v8a)fgg3äa¸Ã‡‚ýٱѤ¡åq"w­Qcd,Ôп‹OcgZ6”ü‘©òÙÙÙHjš`Ù7Â-ny€*$­ùüØçØô™9˜èŒF££ÇãqDçPZËK ;õM�t˜ö{}íGñ±_Œ÷ÏÉÙ“7•›zÞdÒÜlþìÂÏþ­ÑßúöùovæÙ¿¿ö÷ß½öî™÷¼ú=ßxá¿ý‰o¿i|Ó“×=¹·´wºw:ÖÑ®¤#ˆ®ä”T!°¥÷N¿=„:n8Ü+aS˜ÐÃçwÊÁxlÖv\ò˼kž¹ÅÙÌ­²4Tz?¼#÷¯n#ѰL”š››{ÉK^rÏ=÷Üÿý=ôûWfÌž­7S ø37ÃŒ‹¡opi3åÈÆ¼å‰d6X±ZÜûá÷#€–ë ó0ÙI¡C:pÓ–´¡«W͹ã7Î!4ŸãsÄU¨Ï=°â?ŸŒÄ“ÚÛšи–¥£©y}žVìš”ó� ñT]µ4ºY©Îhì·xiòáì²U(å<p™mKŠt8œY›Q4TÈhý½½½µµ5”¨/áñL9 —ýœ$˜LOÚ9‹ã޳¾¾žÊh4'ì·heww·×ëA$K'/"ÆÍfs¯¹×Ük–VI9E‚ÒiuF“Ñwülóì=ã{~xç‡÷f÷®™¹æSW>õÁ…>~Ûãxæo¾ëÍúº?}ç|çÆÆgº³Á¾(22±ö;i™˜oùK¸–„[HµAœÈLÆC{Ï‚›–Ú›>s™Mëï½ÃF`.•j’I¬zàžyæ¦ìhi8wš–f—XÛ…XÎ=æ (ѪY™Š¨æ9î"õ ctÆ3 Nx–Òiò-Ú·|#—E5C¯y†Î·ÐÆ%Ù¸sSê8äY•XäøáÙ@iäT“À„òê +yÏ+ÉÁσäS@º/j´nwwþÝ®"«>øÞ-³ l[m§Ë .¤)ÍL€­ÛH¦H«Î™Éß…ùqßÕ«;[Pþ,^œu6ÒiM V]‰(«««øZ&›€£ß<䦽^ïäÉ“ív{¼?ÞŸRg0p¼;¾¯ßÛ¶ßvrö¤Y¹¥”7ï½ùc‹{ùîËK)sí¹k®¹&f<1ÀÞÛÛ[]]Í‘‘j,ÀàÎÎNøl9tò܆Ã!#“9¹htUÁ r8—ª@ÑJ¿•¡÷"í²rxα2â„ eV'{„fU�L¸ë’RJD¸Ý.b5rÂÂ-,‡U®sª2á k€ñ:ö‚U¼Ç תzû8‹®â¥‚ÚH ¨_A˳*±g‡½äUœ<°4¡ÿÁI1 ŽÞ'ÝÊ£éšÇ³9m"é„…Z›Á~«!iÞ$N÷T³’p†‡îIyd:¨t)΋ä×Ð HdþPEáÁdY>„1iÜt ! ÇÂØy‘é“­N9åévÅ&µ¬ÜJl+B•Æ`&ÆTTz-A$®V$"{IãiÀGŠ÷ C< -p“rpçö777#Õœ*hss3í¬Ç·Ço}è­¹ö#aäiŒÇãͽÍt>òš­×Ü´{Óâd±–Tyåè•Í>6îŽK)ÝNwaaáôéÓ§OŸ>sæÌ™3gºÝîâââüü|®°(KF¾:¡ܬÛí†Í1gÎ}ž ñÆZJ…šä—Ec0ŒgÓº¨\!S)Ó|¢"IééåNâ¨Ç9AÌ":—[�X+Y¨¨öÐ óÐkÆœi€nTì¸�šF¤”æ#8 ôÞ„”L6`0›•c>a• ãI‘'O~Ìz v!“äÌù($ØdQÇUÎÏå�=‘çfbëkå%€2/dĦaÕ¦ˆfõ›ˆ™a{›½Wž"ôŠÛív8NpÕP³ä”nLHÍÑYÇTܘ‰yo_j·ÛÃá0ëûòå˱­„;kŽ Q'ç5]+ì¤×ÂÔ­e@M‚"P%)fª¦2.ÂÿŠ<áÌ™.--ˉ†êL"G.{uu5oªß笠És‹ÑNŽøèª–ò:®ë\w߉û¾8þâ+G¯L=q©sér¹¼7Þ;¹yrÒ›||åãw¼ë§»?ý¶þÅܾãôw|óð›påÇ3ã¤êy ©]VWWsaKKK¹È+ƒÁ M¯4 ƒÄc8Ö.,p=d�s¸d,šùGYO½Îü/Øüf£8ÉeZdÁÒ׬ ›™fÙ“+d{šÁh`ÖZÕÿ÷à6 ²ÈÐ/lÆø(ª<çDGÍ`{Ò& »T!|”•@íDN¡Oýç _#Á²Óé±Ì¡ Ï3ÄM;ÍH]šîÔ‡œ£¬o²Ö§Ç‘`±>ЉFeÀž<ËnQžȆ7ÌÊm>%Õ=!òø[2$·@rÄ*RIìÖ!P‰Èe'Ñ+’KÉnG÷%ðN‚("ÌfÚ®4ÁØÊ=ì.c …š?`¯âé[ ãbYd6îEÄ(úŒP&ÿÓо\Âm ‹½½½œìèÂå{rúÌ?1ÿòÆËãå¿ñXyl±µ8מ{´õèJcågÎÿÌgÛŸ}²óäÖöÖGoüróË¿>ûë÷¬ÜÓÜjž?uþÜ̹FiÜ»sow¶[v •b³Ùìt:ô{777s flnn†«ÒjµNœ8‘²¬ÕjEÖJ7©:pMž$+HZÑÔ=¸¨Ið`YÔC®¼“c&íp– ¦SÌ¥3ͤ¬mœ¥*… †ÛŒCVöŒ3ü7àeO›ºÕÃi‘a%½ C(˜æ¨ƒÿcHÌ€>“¿§á‡é'=Ý"³XѬÜ>þž(ûßRb‚uó~¹°ãsÄ? -œ£!™n qz&ÎÐ0«h›d“ˆRÙ»¹³GI±Øü¬0„{I‹l µÔÀt»ÝNÊc—_{„ä',%=díy†š±ÆÄ™9¸UsÈ$i‹p˜î\ùpòQ¼‡µeæÝW‡Ê¯!?*5ý~?U:xiÒí$­ôòI]“}ïîî¾üÜË_uéUöÒ?{ªÿT«Ùú¦µoº{öîíæö·”où‘æÜ»uïûž{ßg?ó‹ƒ_üƒ“Ðw<|×Î]ï¾û»·¾{<;¶æEÞff SúDõÆ\¨0¯ŒñÀéù$«ÔÀjóQ…É©zNf:ц1ï†KâsÜ 4®ë¼¾J¼ì4CÌÈÅÀ£+2�å¾"HÑétx ž1"pZÌÈRñ¾(‘ùØ€–Øa;¸²ôí¸ä® rZ,˜JÔ¦8UÞ¶Ï¢d]° uCi›v,=9GCZóqI]2=ÌE€I²ïÑ3Ö]\·…8š¡;Ó··[¥Oãm_õfÜprŽCZÇÿÚ×Ä^ô¦îTâ7 WS™á…cè t˜9ë2°îaãð@<³É“¼&ðâÀ¦ó4ÜjöáÛh4ƒAî¤ìÉ|oTgÒìA”PNíÁ`¦2Á>4â”qÍ·œ;w.áõ½¾ßïçjŸy¶Õjõûýw\|Çû^ù¾›'7ÿÄ…Ÿø+k婿Sï½é½ß¹ñ?zåGOÍœš™apd8úµZ­……+¤­¯¯3{AS$‹ -íÊ=ŒóÅ2&¯—ÃãÆ9XSóE)¹Èl*¦S¢HZl°}§˜÷¬ˆû‰ôTÖ3ÏÖ™g–­•sқѷé0$B4`Âo´øÌÛ4j ïÔ"o­*ìÂSÈ»«Ä>XóL;¤å"ÍÓ1rÀÅ[¡Ã@¨ÕêŽCÎÑÇ›$; Áä]",æ<ôÖbdGʹú€°Q©éä 4ã+‡EzéYÊYy˜»äŸ0 —ꪔw=³B«ÌŠpH¥ǃ‹U@‘¨aOºB"û3ƒ¨"A%¨#Awžˆ&X°&&7Ó• ]¸”——>9…H9P¼Îí�Ù[ô)Lú®Ƭ¬¬ ÿµ³³3??Oƒ:ñ&¿催–ür90#XYYY˜]øñ½lé±w¼ü“Éd°7øÒW¾ÔnµgÊÌîÜ %f¦7ÆãqÜB‰©ý~?ƒ8iJªóÀs VÍ2”gÉÍHSÛa—U\öT (b øç&Yj/hEöÏd¨lx’w•„™Ö8mÏÌ/çÛ+øScepyàX‚aÉѦÂËÃT…ŸóoÙ}F#Àʦ]pøAYû 0`D L«´YI%a2ê@þç9¤*Ú.ï8ä%} ø '²g_\v00\$ÔÊZ·%±~‹6áÔæÈ€XÅ|>¨P“$RñLvñE¹/pyÏ ¡= &ãQ�= Î…iV³ÓL½5iÉ^þŒ13€8I.w „qHÒC"ðˆqí<ÍÍÍ……sÖ)S’Å[Ñ‹íÊÓËoƉ'ÏxÑ‘§±¹¹Iæ‘·•rvo´w÷úÝÿòËÿòªd@og§ì„vH«ÉUBfŒ –ä¿"iš·³²²’ú#ÙC¿ß"59/~e$ûëXh ò=|Hü¡C~ CÎ¥½T¢ÀeäLî4p¤VBGœì• I›MÖA®˜B3`µ'—ÚVº05Æþ°Ù\•ý6‡;�¥øÝAH!çËÛ·Íù“î«¥âqP±[ÄÕ‰cq_ó¥^ñbgaS÷T˜$ør íxr޲ÊAѤr}w KâàqKÓf0a,R'KU‘ÏŒdÕè«N|÷r«“Âc¦�X'Šl3#cCb¦6÷ÒÏõ'9%«%Å!¡rª,y| “t'ù[ó rjþ¯çe·¤•Z˜ò±2X9pý¢‘K#Í…&‘>¿ÀÌ_Zl4v8Uk=<·Èq‚Û„iÆQj¤†æL‰:'&ð§JÎ`PJF£™†”VŒfЕQA«Ýä"#FŒ£[j#"ô»æççúQw2Qð¢>L•W[åfmÅ3K¶óù¼ú\$Õ ñµ¶@Ì󜛛‹ ´ñÛrØZ׺|E.¥Ô@„ɪp4Ît›|B²GÏåMÝzéÚ’®Š FG0n_¤ëC$6ÂOÞ�`‹2%£prŽb@逡o™Hvn²å`2|Ãɸy¥ÙÞÉ—ƒ ‘ngÿSÂgSy¼HÄž¾¤rn V£9Ð4I´É%aõͦÉ×ÓAf-šÏ©g^µ{Ql6Sbl­ ¼�VÎŽ²0š©¢f™¡N ÎcÌ3gýÖÖV*‰rØÜÉ/’Jôl<ö±œ2¡ 䬇N„=ìé!ÿDš|xþ2d?¨G˜½úfjå]t:D… xQWJ´ Ì3‹Š~·éŸøˆòå0²·“½jVVVif#x­’1 ÜÅú¤ø®<2\+óFø^³ü9Ð+z•«%�%cw‹-Oåñ,Ï„A³Îð¨,#/öÑàÙ–)I‘„y:µ~Ìô3S®jìW š´ŽPÕ²@{¥‹hDü™Ìñ©øÓÆ0ŽCÎ×E­ã Â#Öc΂Ø1² V†*0É&{†‰ó“ÀJ7k(T]+ T‹¦Ò¢7á›]êLÊ y[)¶Y݇f\Ô¼ç+çì"Íž*«²üp5ˆ“†?}/ç°Ýn7¨Qn$ Sâh¯×KŒwêG±°°Š!“žÑOã‰ö<£Š¯kÒEB29sgffrîyD¦Ãƒ:L&cݼÌ[äÚò ¥”Á`à„wqq‘ÀÀ(_ÖLúXëëëqÆ4÷’6¯&¿™O^^^N¹àœéõ¼ú \kÛÒãöP¯ÚõnuäåÉX±­R™²‡ž11G/“ªm[`¹— B´lšÝ N¦Ò8\Á@©fc=µfx9·ÉìQ%®S9ä’–qñÄ{úÁYV‡3°ÌÎå® óù9:¶h;úC®žTp 0F„ZFgwrdf²X &GVÒÿg=L€™ QÍè¶=9Ý8ÍÉÝ ØØŸÊ² pI©è»æ d¯'ö ˜iþ‚Áz׎n8cºÓl6¯¹æšáp-�¸Ñq²á¤k6›ý~?¦™(¸%ÀøD‰T¥”ħŒˆÆ|ˆ`’.‚­¹÷D‘Ü``ÒÆH9’°‘Š0âĉ)kÒÈ£ãÓ:Nê'ð[X³�5`†”.C¬½^¯Ùl®­­…‘]¾H'ß Ð¹x&©Y9U{¼hî’t!€!4KêEKR� MQ!Y<F @L&pì&ÑqìÁʲ>M&šX„ Õ²ÎQ1 £VɵÙªÚµž¤UR€œZy¶h2ÚN •P¡sP©;Çü&ĹJ¥×ƒ†ÌfqµÔp4íŽCÎ3lfÃÅD¡…Ô*?`÷*­òâö€Õ—­$V+.3»ceœªìC ª#ìO3àk2’·exØðˆq«’ÅŠ$Ú Qð¯¬qK…G_ݦÅ|~vÈåË—AHªS�ƒ T^rÄ[<‘/a;5YÔR¢Åâl{{;xÑ5×\ãÖ+½´`Y=ÛßßÖ@xü§+ñv‹4ÃòòòúúzÝn—áx’Â9„Õ–vww7‘ÀQ<+¦ ‰Bnaa©¤Ðä¶··WWWË•Y^–Ëé3v&Nd-‘[n5Ç™½Y•H¬Èg]>ÓX¨›ÉÀPsI$éü^à)³<†n˜“E’£²ÙŒè±PQò7½ÍÀ÷¸¥ÒHõ"ŸAµ k&4U©@r ”&dQÄ*«Þq¼ØQÉž^ˆÅÙ�¾ÈÚŠí $îdú8äY¼AfÕ6¬ð+¶“{•œxÄ×ãÜæàk077w×]wííí}õ«_Í$<Ÿ™KÊql«Õ5²Èâde‹xß‹Bˆ| \ت¢7y¬ò q`&=§Bªº¯Tñ*¥»ØBö—øj^ÜèàZ95ìhéÉödÁ´Òrä‘G–——óNŸ>M¯Ž¡ý¢ñÒ°CwNz»¹¹Ùëõ:ñ)gA.8BDyãy‰%€<±ƒã1æF�=rÍh+@ðÝ+&Î%÷GÑÙÍ!ØÉÐOmåMÙI.ü@}öqmæUCÍJy‡ãC.Ì—Zûû%]@ ;¨²9^'>÷m!•ÔT0r›n¬‚²&`3â羬F<¾F>BX±c’T6P�Šä€Ý5Lvÿ“f&¾FYŠÉc…Ä~ÂbwðQyqÖÿ=9Gr,ôBÞ ¶c ßs…°“óaµÂ%eŠÅò±¦£L&“—¼ä%ï|ç;/_¾|ñâÅœS ZÐ,Å»C¤Û‰L„[v2\ º¶Ûâ³²â�3äÈ¡”ƒ�™û) Ã/“NoŽ*Pµ<àØÄŒH]åŸlllXªü0G#ÍR"ýÎÎÎc=6Μ9³¸¸˜÷›Éž0Ùà-ZGèöç3#r“¢3Ó¦9(aä"ƒÁu×]wáÂ…Ë—/£¹—xvòäIpׄ–tŒ666r‘Aí¢ŒåÃ777ù¿óóó+++ȰÒEG±Ñ�i> Ô%(¥·�#bNª &C˜d¿ÀÄ¡® )x¬Å#¿¨ˆÚdåîás=ß° ¬�¶Ì 3(™«]ZZZ^^Žb¿™}Äw¼‚ÆJ@ Pô+ïÑ<:Ÿ9dÌ „‘ÈdͧÂ�`Jk£~ÂFÁò Ãù4Êwzǽœ£ÿÉKâ`…gB® Wº=«5Šl£LSAd…£< ÈêêêïüÎïlnn®¬¬@r:™¡vUye@P9n‘–¸“KfXá^hlEK:šxšß·ÇF¢lò2ã,+òV÷™¼7¸5"PœùÐ6µË§9s¦”�Xï•Á°µyM¡¢¥"‰[’ÐD”<íùùù¼£ÍÍÍóçÏCHÝÚÚZ]]ÍÀ “ó©MóÖÒžaÌ‚úÕ&cµÈ4*L˜Ás!ž@Ȉ»»köiõóq·Ù°'1ƒæ¢Ð<šF ¡ϼ®<Ó ´cš=” €žñ¤˜µÝjµR(íDK¦@þpýõ×ßyç_úÒ—ò¨-ì]5®Êªà$]™éÚ\mÚÏ ¾ ŒpÈ óÛˆ™Ûi<êéxGΨO5qˆ[öô͇œ#øam±Á,i ŸH–nuV®.ØÍx Œ“¿¹páB¦ÜÍQöú6M :=Ϫ'ÄA‰5–I¶‰tŸ€Ccˆl”®$΀?å°l”阦€­üpÜö$\A–«zª»Ì­QRT› 0Š´!±9õJNCäx –Då$ì‘9@vŠ<&hÓ%¨¤=ó ­Vkkkkee%øò9;;;ƒÁ`~~žS 8ºaÔ=qCGRÌc¶�bá€/1¹ îÏ,<…\auê1WHÊæ¬çr Ï�ù"´jLÕ~H˜»˜®ÂíØÖ½êŸÓäóÝâ—¹Œü¾¥ØòróO¾öµ¯5+W®$B»|´\l‘}\^‡ÓPà5äDm¡Ë-Ã"«Üâ+ÐØÄ <çžõ™ã© ÒÑ.±ÁîqÈ9bz´)ï#/È*LýQd½WdùN�ÀŽbàƒžì©6£vÈLGÏÌÌì—ýÒ(£Ÿ_=n”Fû—Ú3¿9Ó*-š“žìcÿ€ÅW=Þª=SyµA Åá4ô¢Någå¡Î"[h€ì+Åô>ÜLB@¿OË$ðQÎ»Ä 'ó4xÚÖT½+œ.7ñ�!2¦_s~h»»»Ï?ÿüÂÂB,pRÜP­‡ÃÑh´½½s3½ý|;¼Çô¢áÂå÷··ñgƒ«R¥áyÚ¹;Ê>Ÿ i¸*û]ÊRÉCN1Áè:FFç�ެ©c->ØeÓS Öþ�+£õ ­€6d|QY·XdZvoooyyyyyÙ%B•ï»$‚Û]4›l›; }æÄI³¬–B±0i ”†æ¡yËó­†g–S%µ�’ŒÝF5rP¤Ôpr޾£Óëõ˜­óB°T±]ÈL7`­8¦ö e›{æékä¼üNÔ·&s“Ñ3Úûo÷:¯ÓþŸÛÍfsë½[ÛŸÚîþ/Ýæ®&æM™Ü#2Õd�Eƒ{¤Æ¬þ€tæ‹<AŠÑÝ/ÏçðbàÃ×éÁ#õÎÏ?L…‘³›(›*0s”­V+3(ù¿ øÊ¥41)GÀd2‰AgŽ­Á`€ìrÅ0ó‚P›ææá¤ZÊ uåÊ•ÉdrêԩД»ÝnÈÍkkk¡Þå½ooogÚ4d<b-¢gåÀËncc­ëàlN¡")DÊœ§ÇÚ$C¼^¯‡‹ŒÙ·à{&¡ð-y³¬¤ÑQ€ëràyS¥ÛÕñ D¬ª‚½zŠ&ŒøF8ýmØá6>ç/|9(y8TÞ(asaèª9Õ㡘:rx´š�Ò‹èªU°ÓÎÙEŠ Ó#zhjµs°<®r¾^BŽÉÐÔËT98•s NLd+­M›Ú–:Õï¹6“L²uíÔI Ùh4Æ×Ë›Ëà-ƒf³YZeîçZjmýáVïM=ŒJm+àû"ó¥|q~›´åðèx¥Ínz^Î5ŠW'0g,gbv5àˆ¿UŠ窙SNŽ€\LD0™‹Êßx–ðF/Ÿ“÷’1‹pÕÊá)qÆkò]1scô$—Ä·›S”Ïúúúu×]Ç I(yz ¨X*Ьï�� �IDAT½eö…³¢<Ê7E^h¿ZÓ‡QÞƒâÍjñÊ(ÊXÒÂmBÛŽX9d-F¨!p-î6«7ÙÈÊm'79±– -òÝ©Jã«/ŠtÙ¼ÇFÝ.†Ø§ž³öó§Ü$|VBP¼k þJ^âô¸[vVÊ)“¡ f­˜ôqÈ9Ô�4ÊeN$É@iPƒ>ÛI¬2 e»BwÖÇ=Ú-JܨРœ››»øß_ìþ_]`büFÛ¿Ö¿gÜþWíÊh˶€Œ¿x4Œ# P±z )ó8¡+z÷ÿs³ìï"5<ºäø&æZ¤.wÄ Œ@AIc}IÿÍú«$~Çq‰'¤EÐ “¨êÉC+¨-çìììl»Ý¦µc?=GiÀ”RÓãÇÃáÐtáÚ•Ã2»EÀ-O/þ yÌ-åcvépÈÃ¥“¤{„À`Tõ–} ƒ˜ÁŸ$ò—@ŽEH|2¬Kˆ$Næ¼ ÜbôÚv4¢Ô0{›LŸ„×S™ZY—ÏôqrËbº½jD:‘€½lMÛJÕͳMù礕 jŽ‘EÞ(°® åîypÕ"§•œÊ1Iúˆ{90_aU²X3ªÍñÁŽõ 5Îb eS Š”©Ø?àæÄ�ZˆÎÌÌì}óÞì?šÝ+{NçäÉ“i,¥ÌþÉìðïË¿*n<2íL4%xXÑÖgg©°9™fwNZ4[š£?ü+Ó¦©ŸŠ4„h•™ÔÀ ¨E3Ö>ÙîHñ [[[ÂI€1= º*¡U48¨Évww3e‚2|´m†Ãáææfe 99.CbQþz°5Ô‘ã‰`j2çQ‚P"k8ÍÈäHJ­Œ¬œÉÊ0’i’áC“ê3WÒç‹Ö§pœ0DFŽ•Ç˜ÇëBŸ5cœÖC©P=Œ¥EOLËÍñ–qÅi‰O:àâÓ «ª[¦)]RØ“†êÁhXŨJP2rŠ]›ãþ@êiãNvàÚô V%#ÊuEêALnÀS89G ©¡ÏW0¢ìRT:€}bÞ…ŽV¥BK2.Ð9DÒL˜clò"i)=óíëëë´…Nž<¹´´tùòeƒcÜEY†�ЦýsÍ9C­µƒ~3¢¹jNëÈ1‹QS+˜‘&Sœø `_á׿|dëæáª ‘L5™²(•¥¼ÈîÅÜz¬åÀ7Œ.tÚ¹pÍ×ÖÖˆëëëÔïõz—Y__gÞŽ�‚ZÜäå¦÷3777 àƒE¼`<_¼xÑ ¡©Éò4öööúý>®e<áˆÙ˜E–šÆÂ<À°>ñÉî4Ièb†Œ“—)“„L¢‘YˆyPÝn7µužy>ךßáeU®q™öå,Haª¤+Q YÒ|³ÑàƒYG¼Öeg<–ñLN.˜& ÕO³Ù´~UNƒ~¿Ÿába عf¿)Îú"×¢¬½f³™~!E6„Ö­ Öj@ddlèÙX"&ˆáµc#ꯋ*‡¢Ø‚°wŒWø °Zš¦©oøkÖÒ'4^œ,8®+z'_¥”Ù?˜~˰û™îòòòææfJœÉd2~ó¸ü?Å8�—¤9lg&$ø·–v.’¨z†|ìv®§ßƒAÔˆ‹\üع¹ílÝ_w |<1vžóþ¿‡{ôTø.ÓØ˜1П§”Cduu•És7P¦Aõ$f \üx<ÞØØXXXÈ£Hy”$wee%'ÊoØ d9…9²¡c-3ÿí´ýŒ²…êL÷œ»ÜX$4~È?ødæó_”æ[1Ðlc#%…ᘙ´É@(+9eü´Žè†r#<+ðIûrVÿ ;cÅFùR³œÒ ‹z½ð^Žxz{Œmú0Õ‚V›LvÈ…Ñ$�éÔO•6*(_Õ$®¤äŽC΄ֱù£†M°2M¼¬*¦ÐM¸t²ij#¬þœó.ý�.‰cš3eößÌnýíò™²µµ•s!ûç¿Þi¿±=žcåY«ðBN>›žA5}fغâ•Ã.Ý c ñù¹!IE˜ã5ÍyVV­'³v¥eùwÎÍÇœSp<&’çvÚº`wH“a@`m=Vp?—”kŽBh>9ã8i8q‚ÖoÁr«yŹÈàH´ VaþBÁÜÜ\ÄÜù2¾ŽZ94–rX·‰çƒ>åTå‚‘%4=hEdò/ ÿZ™9YÙÏÜN7!¬lÆý2\Uuà}GÔUA bY ÛýÑ÷ ^‡yny8Læ« ¼ìî¬¸z ¿ÚX=W°ÉEÔ‰^V5$tr0‘–<òQ ¨§þ¦ü¥�W¨ü„ŽCÎQÒÕ²ÉÍ~á|qJ‹ÿ#  3ì‡ü":å°gÕ#5jÇ.uÇykkkæÜLçÓµO¯uÿ×îÜœk4Ûs{û;¶g0i]Lx'³¬ò¢‘îAtÑH€,8XÍ­0¡‡Nû8L&“K—.EÔ²ÂÜà ‰AU\ƒdpH™\„ ÒôÆéOD‚(7žC…TE£|D‚Ü$`÷“Mõ&ªÎJ‹"Oo4eú²bÌ÷û}Û‡ÖcQQLRì†}jUöúúzxY¬P5òërØš¯’ÉÓKä` ýÛW[èÁqÅ+9©s ´'ù"ZPÎåMwDH¦bv!'Š¢Ë´ŽüØßêìÖa8±È¡<Ù&æ‰ùb2 dnªÛ¥xÃÚlèùÍ�z–ÿ!µ5\9= ¶ª>a3ÑËÅÅÓŽž±Æ ±a£FÛü_±2sÚUMÀy¦Á²²èi:d1‘ü&�´ö[_oÌþúìæû6G?>*¥ÌþòlÿMý™æÌ~cߊ2|#B è°‘=Ü |r_Ýn7sÊ'Œ|äwGA±­dZ4£Ê•À¸eHÆ/8~…WTóEnÄIxóÜ‚VYÔ &©zî.­gæ¼q:3&Ii‹r½ÜÉ&“ _M)¹¸¸˜n[ñy¤LÕ¸U@Ÿß…x–DæF-§ÆT c@+0ñpíC64½„4cü9¼—<10CÖ6e =-ú7NwˆüE�#ÆXsÚåšµdÐÉ3ì (wL§Fƒ}Gâ‚¶ž}uñG‡/�âW-?”M£ „|d­Š6VAÍ~2(ËU6£{!gsu³&I?=âvüŸŠÂd£ º|”) 9_‘Óø¿ÔæçÐIrŽc åÁ¢!¸V«Õû½6Rëî\ºàNÞîHs`BRbY[]à åk!ä2¥ ̃2‡ÂŸÇ„& ÛÒ\u7y7Źïù5œ¶Ø€ÔL´#Æ@D¶ãBy ñt`²•¡QJØ|¾ddP%ñþáôt†‹Gutq€àà¤ù¼ƒG�—ÁúÁ&Y¨àD§VÜüãÉ›L@G…ààŽˆ>Oé’=0Ÿà‘~¤0i`LË£MOæ{Zx¤ÿ=lV§æ“¡:¤™çP“…k`÷Q·ÅI…ó[ãŽÎ®«m€Dk{ ÀYG.Á¥ÛqÈ9ÊB]µ"¡xά‹¨îéFºm`&1pMÕÿGÞ/êC)Û`oûç®2 æ~hnvc¶R¸"„Älö6�‘§—ñ¤r£ôÀJdÏš+æª²á Ÿæwi0ÊP©xq@çÄ÷+`º“wa äêjQ q 7šs$Õ c}nlnwwwûýþøàÇ~*œWÎÐßÒ™ ©]r²ä C¡¶½^>…4{$S+‡8‡™)³&!×…ÆQÅOÉU, p›°Ù ­‚C‰:èIgmƒ£¢¾SÙ´Ðãmh9–ŠãVJ L?sh™, nj?*»nÛéœzïTÄèhí°M‚m†c Q¢¯EoaâQÇ'¢Ëa¨{Øét÷½¬CÍÆ§™iå°Ý”"ÌH õNØ«´EŽCÎQÒ\árFä­g9âEA¹c³µ0Aªð xVÈ'¥”F»±õ“[»wí.þØb·ÓÝÚÚZýµÕ퇶;?ÞiŒ|B¾+è3Mg²8lfÁEª’ëaÇ;Ú¼–ƒ)†¶6 ]LŠí¼ü_€{s–|ˆ$¯´NJ_¥”õõõÙÎl£ßþÀptï¨LJçî¿èî®ívÛ]"P'ÁùáKI’〳†hY_3mâä#Œñ HÛî äòÒt¡«Äd²$ç8 ìü„ÌÍÍÍ ™I£5†t><ïž´!G°P¡ÏÙÇeMb¡¥‹)æì\`£tû+sÉ€ rû' 9ØZ÷b•L¢u´Y)æòÕ”kÓtaúð˜0¥ʤW9¬oÆóñí¸;[ѾMW#.Bl!À;!€.èNp¥¾á¬«¼˜õ;óž<BºÚqÈ©!/@g潑Q;bz ƒ[Ï·gk91ô0£mz=õ9;;»õ?m5ÿ¸Ùþ±öÂ5 ‹‹‹ËËËûïØßþÖíÝÞí¼¿= -·=}Òy6Âì(’Ù]ð›¡ë0ʇDgYEh.Êf¶Zñ|"™#(3»îÅ¥ÕÕæçlk÷»ëï\o°ÝûÉ^«Õš¼c²ö¯×¿:ØÿØ>°Iä;ƒ>±—Ò ¡É-gO-pxÙp¯ž´†|bXn6Ï-™2ŸÊ@dßxæùW˜ÐÉ2ß—f˜ùßDŽH»Ò¶‰ÎÞd2Y]]E”µlÞ >•ùOéÆYzœ¹fÀCx\ iƵUJŽiÚæn'ä2€˜`sP"Gä¡i´É­ÈW´,Y6iÑî®È–ž«µv­]dØïîs`hŸ‘T¨@ð?saèõ9|"_6-3“3¼$§G>Ÿâ‰ZÜŽ®´^Pös; ]"$?Ò±ƒ»˜OŽI9�])CÎÑT9@ç•":½2¦1p‚9X949ƒlvB…KÒaaçúqwï,..¾þõ¯¿ýöÛÏž={ÿý÷_|ìbãÝ»º;_ܱ„ y7|!ë§yH‚"Œk¨8»f qþ²û„b¡“±ší=ñ®X‰&ûºúasúP#«ÑhìÏìo}ïÖü[çK)3³3{{{s¿;·ô±¥Ë¿ùÌ'Ï8ÊòäÝEcÒÈb?dߦÞb8ÍÁGóŒEÎq:CN9íòk<ð&ÈôgggS£ä9C8†%hŽH-"Ÿ¿¸twbŸ³wðcp¬–¯ÌòŸx€ÜŽ•è8ãÌzb½%` Q¦$)y>¤ä¦tò¦h©‚æÙëÓòzU¥R¤ZÆpÚ2þB’Î+… ’šØP‰L$ bÇYªÀæÐ`'ˆ¦W4� Ú‡¹cÀÃ)f\'iGøI¼ü¸*ÊøqÈ9JHº‘“ Àîô9­3}C¥æ’2ToûgO$4›Í½;öZ½Ö©çO½ñ[Þøîw¿û†nxæ™gJ)÷ÝwßjsuùË»Ïìî}a¯û¡ne�S.¹Œõ”˜ !``·œóÅ©%Ù½GŽ˜vô‘š[`þ”Z°HmºH·ÿêÎÇô|böX>ätû'¶;?Ý=Ï™;333ÿsóëw}ð]·“åáªé®��i‘< ,,Òáj Ê k‡`lldvœC*¹ÿ`0ÈÏ-´ÛíÌîä±çõFF;l:%å´Ê™bF`Ÿ 4ÆË»u* ›[_YlTó[n1Òžanšžœçpamð÷)¸sQqfÌ…•;›Îð¯Kgj&÷“xÅÄ ŠBS*A?'dÕQ Ì^$nR~ÅKª|LìÎà¹fè|Ycž¹†Õé‰àŠàhŤCNq¯²rÁ¡|vÊfR ¥>:nQZL 85oÝ£Wyús3ý~ÿŽ;îxÙË^¶¸¸Øn·ïü¶;ûûíÝkwßð±7\þw—Ïßx~ó³›§ÿÉéùÏÏ_¼p1ɲ½:Ø Pª¬åLo<«ÿÆo¼pá.ŠUO 1;?椦ØUܼÐì¡KÛéE5F+ww¢ö÷÷Ço~zÐôo½õÖ^¯÷àƒVšý³›ß¿9øÀ�ª-$ÎnWØðÑ+çËùC`.ú´&YÀ.å|¤Úc5eƒ*¹µååe¨ÏyY›››ÐóHÖÖֈЌ◠f¿²\íòò2ñ€kŽZtÜÊ«kwwwaa!ÞØù_J./`'×Ì$RÅRŠU~ÕôáoÙ»Ï-œ”YQý~ÿî»ïÇ>úèêêj®_sžLDw˜:"™�€²²£oyì<Šü™n&lÊa‡Í¢ÁUt›~‚Bg~ÌL©È5>%P ¢ÒÍó¡Ô¥wµä±V#+ z›↫õ!CÎüD1 ¢3ãñIX£“Y$Ø|cZÊ¥ÈÓP;«„”í Š “Íó»ç?ûÙÏÞqÇ·ß~ûc=öÏîùg7ÏÍl¼õ¿xëSgžúÂý_8óä™?ðà{þä=¿ùáß|ôÑGs@�þV±Ðâ›@‚ü‚Sft2*©‚`ô4l<;i¤±*•Xè¹ÓÈR:ÐLâ‚᧺Ïy’n\ý…»ï¾ûæ›o~úé§6Ë&�”‡iü‚*ÿëÁAw=„š/¤jÀ%Ž'²`†§G÷=ÒK3;;û²—½ì†nxä‘Gž~úi´«Ã’ ®Ð”Žt8(40¤Ïà PÎò¨ójJfkkkz u0 ãE¤$¹Î¶®› ÓVÇÖ°á/£8ÕžC¯×{ík_ûÞ÷¾w{{ûÃþð<@­L¼Í2HU)]ÔÌ“YM™7#é0AùÉSÊL‚ÁóÐðœÄ˜J€4дÛþX¥õz=ãó§˜zT¼È)öÞQ¬1päzŒ ókÖ„<®rŽ¾Ð¡1Xy*Û! :õ¯É©Ä-¨ÕNὓ¯þ×/6÷ß´¿õ [}æ¡_ýÕ_½í¶Ûü/ì|¼³ð×^óÆ×|Ïè{žÏóKKKÍfóŽ;žxýóÿfÞÔ¨¢)SΓïóO"+é‘·¨tT*sœÎÆd*Ë� Â�lß,¨ip‘ÁèfgggcvøÃÖï´>ûÙσ¹¹¹N§³ü¶å¹7gÔÛ@Ió!£Û…ú?5‹‡ ÞÆtÈÙ·V± k†§Š‹A¿ßÅ+^ñŠW¼âÊ•+=öJ<9‰PWÃèeINËŸäbâ× ŠÊ'³îãñxuu•¶„cüwÞyâĉÇüܹså`|¨¹nÊêãYcùŽ¡_»dä´u æùSâ wÉê¥ÍpéÒ¥tSàX:±ãµÇÙžAa7 ëI“T%A%¨`´RˆL¶bƒðAD¡°2G/ÖˆY%nMÉO-j� «UÂZið䋘5ö´S¯×;žË9â¼§²‘Ìy·† ù»Å²䤜vyòb­ØeùŠÞï÷Fstù¯_~ü}onn~å]_ÙïÜuí]ï=ñÞ›çn>}úôx<þ¾Ðüló§ÞþSg¾ve@J çìÔàà�ÞlØZÃà hVÅ4y,ä¹dmlN|š ZƒfxÐr,À!á„<™Lfyvø©áÎGwž{î¹Üoúä«ßµºôÖ¥FóP¥HtHýËßSKx5•ƒ2ºa p@¨ÆJ̵uÆmožèqýÑýÑÙ³gŸ|òI¦”˜Í‚ÐHuŰ=\¯œP *yF£2ktGà¡1EvuXR·Þzë÷}ß÷:uêSŸúÔG?úÑáp˜òÎ&<"JºªñIäc‘Lû—› lá}ÚÎÎÒ:£ÑèX]]F©kA®˜~«\Õµ¸áH•{çýòi$‹ŒdU›ÚŠ uTðˆ7/—!kÈ¥p݃´Úž°Íý©¸yŒ3C}²Ý”Ac릞;ÚÃö8ä6ð‰'æææ.\¸`ýpnÜO&ãÃöƒYQÂ@Nááp˜Ô•F‹IbYšžf™™û's37Ì<þ?þTó©›wîýÙ{ßýæwßvò¶Éì$@Á“O>ùÅ/~qó¯m^ºt öŽFOq_Õ�= ¥zö3Ǻ=wÐåè)r,•aÿ7 øÎÎÎd~ÒškM&“ñÆxfoÆCמà1*Â]³*Å:ÕûûûIcöŸ]ýôjÿÃý™OÏ”RFc4z÷hé.adé±8À(<}IÒñ+BÀ˜I%I³‡´ q®rf‘ئãÍÙßß?{öì¹sçrº™°`–E3 ¤<jÀ}së“esô`�HL²§Kߊ '±ÓdBQƼ5çÔ†§eÂ$�0$×׺/eÔŽ#›™°ˆv?üðÃèñ€.О±q»ëƒÿ %Äö‰$=æôi ´ ý&Ì~OðŸ(nÐuµ¿N9ì¬SéqàÍaJwe‚ #€´#‰…åq)†çÈâ4Iý8äåO»Ý~Ýë^·³³³¶¶–µnþRÕRÆk Ô5e¯ÁÚË Ü±F«Éê òF£q±±aáÍ 333ë?²þÈ•Gîû­û®o]ë­·ž?þ÷~ï÷>÷¹Ï¿þ|ùóˆW²Ñ—лÌ1”N~9PJwBŠÿ 9Xãàãîmîïïo ¶f¾afûÛ¶woÞ-¥Ì~~¶ñgæ6gvgL 38À|ðç…ié]5òš›|vÒÿkýíØýòhR&íO´—ÞºÔh4Ɠ쮧ÙJ&‚G=!¡(!Özïðž}:3…NÏÖZUå`X2ÅD>µ!ŠŒàc[[[éßD¹.z8ò Õ Ì‘q.˜!Ö¢aä´¾<!HŒ ͺHekffæÜ¹súЇÚíö#<m7À7PÁ08­uÛ ¯ arÈi¼_Csðî<Y™Àl3 jªLÆñĉ•v §6n7Ð)’ <lúg³"79« ´ºqÂÞ®a1Û0;ÅÐ G œ:ÔuÑì¨~½ƒ¤jðØ+m\dˆ+Uïãs4?ãñø+_ù ÒUnNšKjÁƒf ôTºŠ�Gɬ§ EŠÌ7M)™}ßìsøÜ~ïŽÇã×½îuŸÿüçï¿ÿþ¯}íkëÿt}þ˜oÌ50±,¶FµUuY©ö¶ ý ¬9Ùñ&e£±U¡Ùl–^ÿwã™îÌÜ/ÍÍ=4WJÙ¿w÷žÝÉí“Þ¿èy(ÝQ§§�i,/&¿a¹ßýýýÞ‡{s¿p•³4iL _ÛXÚ@(›¼”2 òí½^oee…1Ìr GéÏ)$L•VÓÁ(^Óþ…?ÍÂ0ß !8n''l MâD˜‡EÖÈü$`޾”ëT<Fö÷s…³¸v»½¼¼ü…/|Á\R{–¢sœPiåó)š­;@)_dmNN]ã/QÙ|èr á™6ÓRÀ$=úãÙ²œÎÝn—°Ç¸.™¢·§U ÑY°ÒnEª® k¿©êÞ«á°"Ù&1¼=æÃ•g3€lûJˆÁ.›�™ËˆÑ?C£Ç!çÈ~²PΟ?ßl6ƒ›£‡èSÒX Ý9àcNÏ£Q:X€ÏDäœb&œÐùl½¿õèÿñèîŸî^üÄÅ/ùË_zqë}[³¿?»¿º_ö®’;38†Ö'wÄÁÔívð`Êfº“¿ìv»KKK1µê×ìewww²0Ùý~ï»zûûû™F)eæs3í?j¯~zu÷—v+º³™9 [6�£¯´Ch&™ùS4lïòˆó kK…‚ù@¦à¬w£Ë ryzìd:¹¦%îHNw︣ííí$ò„@(Åô™ó:òáæ³@¢£ÆjL6[ŽÙqÎ8ãø»»»a €m:—²eŽv© qP¥[� k%ÁÒÔ´yWž³=`œœyú„Ê¿ê¬UK2ÑÉÅPÐ8’f„áYÉŽ8Ѥ¢µn¯#éE (Fã„ReTfñPÓPIcÉcn'9 ` VÖ”ÔÜ8Ti²V¸Ë£ãsÄs9î{Ûç5Y'kÔRlmh¤ãb Eõ–[nÇçÏŸgªí?çSf4¿¹ûÅݧ¿ûé'ß÷äÎÎÎÌŸÍÌýè\óJswëÖ5bÆ$J éœ}Ýn7'j²)´ƒŠàxòäÉÛo¿½ßï?ñÄO=õÔÆÆÃ7$€¹©­¾Õýþn‘=ûU.Ãÿ87ú§£¹œƒ¢Ãöð¨¼jO?Pç9[G÷—®¯Ã÷ëèbÍo°ŽÇãÍÍM²×¼#\¥y­¤´@.¹°ì(d ÀÚ*’Ò¢,¶42ú§ xù¨ýýýÌÛÞ;ÌI$òL9IĨÈÓɸkD:ö&>$¨äéaFàœ‚]23ˆœeɵ“”ä:c A°„Ž\‘j%–KB ›zÝ*´æUÚ…=‡5Ý8$õ`03 Í[N $èB®³Ü€ÁIö)œf!°êpí5©º8:ZÄÚV7.J ,ºgÍ;öP”KO�-•ÄqÈ9ú�GG­­ÉŠœw=Á®æè¬²›à­èb±7Šlrì ³»»»¿³ßx¦ÑþùvçŸw"$ì1.˜`f¬z¨ÎTs¬ôœ¡úýþm·Ývë­·&ã>wîœIDµˆõéÒZ¾ p÷û}hWËÉ©‰Uým†3µN9Ð/@¨ÔÃVó¼c ‚”´›/ é¶ÓÆÀYœï9)0·Ÿ&;™à[y×ç“#c÷ øBUgˆ§Ò$¿“yF¤˜gâò`Q§£SÙOXqËÞÓþöySàÆäפVve®Ø½æô›úÈsýÆ�� �IDAT¦Ÿ”ÿ{úôé׿þõkkk÷ß´‹’ßDà'P/ÔI�Ô÷ÿIáóXØž¾Aà,Š¡éš®2 `€—(^­=LÖ]VÙëéÊ>˜¬(›·R²)òw7Šˆ2=Yfòuv1à‰y‚šú¥ŽCŽÄô¤­ÀÜÖ6âo\ÈX9·3ƒk=òÈ#P *„Íz6žU¶bµRË„Ø�Û׆±á&cnôQ¹úÀgΜ¹öÚkãWE4ÙiR&öîõàN£¼�OCú¢ë‚=ciJèÞ“n´ ,lJIg÷IO¼ûàf†féý^×s•·±ÇV8ßÉ=©ü*¸[ëÀî©´<Qþ†'V PáÍc›%Óç T`½%¢©Ñ‰UÚÃÉk \‘ƒr‚+= Âj®¤ÛíÞxã—/_†0RI —Ã3ȰØ-8Üëõ(ˆ™8©„£òi¹«jtÔ*mÕ 4« –s’ž¿ß5”0ïA„*’Eè'•“–+Œ•±wxøU{HÀÓl,N÷Gá‹“­&-CÌâ8äe/‡cÂÎ%¬r›U@Dî§•êSxZ:ÞG<vÁ7œwT°é†€N§ÆQM°ã .œø•.=mÕJjó¹çž‹`ûêêj–{¶(õ„ãîû»£ußßÍev»½ö#kíŸkÃh`ˆo—(’<I}I·^$o‘J¨z¯ì^ÎwÏ{’×Ó]¨ÔE‰.¤™L5_ˆ–¯3e’"6”3Ücs?è'þ‹®ò7Õ€’Еb,é<gÖÚÚš«@’nž ¥q [¼X‘TíL_ºtéãÿøp84U—áGZqÜ…mÖp“bënUâ•fZš� næbŽ0Pq2É` &SÁ€ž™ BaÓ#)›ŒpzžÆn *®Ây¼ülÍ ÉÌlôÌ÷+‡B˜V‚IÇ!çÈ~@Eè"@Ád‡“3~e¨ˆ&C!üÁfš`|#^ŸÖÿ'B˜ÉÆLTÎôIÜT4�—·X–ñwl—/_~ðÁ———{½Þ•+Wh¤7›ÍÅÅÅF£±¹¹‰ZëÏZãï7®oì_ÚŸ '“Éd¯·×<ÕœÜ6™ù‹™Ý²k.©£fÕ§× ±ÕЖõ¹©ÏH ªi÷®Êaß*Ú'ÞÒy,)-9Å1g‰k°¾é¢Á¤ž›!‹xꞥ’7Euâ°ÇËʤ q QÂ�U”‹›êvŠdUST+ nWBÿÃo­Â£\ÐÃu |zþüyŸÂŒp–þd)s¡Š…Óï~²ÑÂ!›ñ»dj»å"o‚èY¸œrIaê JHdÙ§ü9wÙˆ¦“Þ¬°7íŸÆ×9Þû’  ²ãþ1§D»ÝÎf phxÚºzqÉwJ€à8äØ5AœI…ò¦™9ð�oZebØ¥Þ-'b‰¢§[”!†iÛÄÜhÕ@M{[ •›z~?ât›Pæh47Þxã™3g~øá .\ýö+3í¶7?°Ùút«ùlsR&{¯Þ[{ÕZç{;T~n˜y0¬D€(5kNÐy;]š¯Ìé`Ì3Ç¥AvNv·úb°­VÅé¢jɑǰz@6Î,R úÌEæ§Ö¯l]*a:Æ'sÍ4á+ô5Q!Ï͆FÖÿ®–S_C»y@dŒÍ²Tª‚ª½nË„1Cø#îØz™C%Ð/…£–Þªe>ª óe¸%C{ÏnpÜôªjPƒã:jk;Jô6ŒAT&¯²¨©­Ðö0n cJ¨H‡ûsÿ%Á@ÛÐ.:ÜÇ!爫œD 6IMQ›‡CX£o ‹Ì�weÕWÕ+Ñðл „ÀÊÍPÛ+8«=Jð:ë⸧’ý³¹¹™¤ Ta<_¾|9…ăf³Ùz 5øžÁðíý»÷ÆìçfÛÿ¸]JÙŸÙ7‚“¸<5Á¡ò'|Ú÷ÚU |éÔ% BEÄ*ðSƒòu€€”abE‘ø|ÐK7ä*©iÇrÜ*‘ †"­¶ÜŸF[˜ P•ÛæfµÑ'÷u:Ã0«Í5`¯g—½tÖq-î™0›îØ‚³ ±6d«jÄŠçM²âiGƒ«VÛ$<¸&ó‚0ô,—Él<†¸+ïµ"+OGˆ&T ¨ààï™@qrkd‚¾£çgÉ?Üñ ÕÖ0©A…ã^ÎÇÔ·œ¤»Ú�Àu+ÒÒ€³´RÚ­o–‘KVe mÕ­Bƹ 76¡ÍøÈð´�TH‚» Œ-//¯®®VÃØY¸sÿ~î-úò‚˜‡7O5ãŽÒº‡n–¦ÐqW¿hÞhÅãPÜ2äÀÊ[ž#̬_Ž-ãQL€’­Ã^CxÍZ¥BÎS:¬á”M�׬H8©;+Ý”¥W‡¦‘%ºheÊ0džV‘×Í®†üMû½*ßÇ4WÂÊX¥ÝàmzvÄójÍY“,: ’ÿyx¨ÃÆ´bšB‚–]÷Š¶ê„Æó@ÔÜèߘKç HÀQxÀ#h³Ò 0ßÓµ\¼_ýqÈ9²Ÿ BRד/°ž0°-)*œW§BIr3£2wËó®TŒŒ£·Ï¦ßXy¿»8 ¸¶îNÎ/L|Ûš V±{íMl®l4›ÍfåØHÖ—4qÙ9uÕìÁ.7›�ìYEk†r;y8!:sÄ3¥DJqX©Ï_ª® FÉxθìÙä&õº¬4˜žÈ”ÞLÑ8a£Ñèv»,kW¢UG°ÙlF8¡Åä1ê0W|f@1§NÚÞÞa„-ýjJ[Þ…-X\Û‘„yü¨š¾´ùÜŸàGW.&œÜÀ›·œ9¢2¸P”ØÐC &¶TL6·W1XƒÞâI«º±Ò�<s ŒZ3ÅI‹Âާ8y5ÁrÅY¤2–dj¸Óéu@ÞŽçr޾CY¼†}½9`ð ŠÜb<AV±×z½ X„Oyh<Öšeõ“úe=¹“ íŒÛòvˆ"GFƎɲNmÚ²N\˜ûäov×z+ÀÕR"ð÷Éy=£Þét,gb:\ÞEž€§”8ø˜/©¸Ë£Ñ¨×ë^&©$ WLÙd=ÿDVk¸iïz‘éQÂã2G(ʳµ‹OU–åýÚ!‚) ® F;z_$Ú¤øiZn|cc#©?<|fÁ£ ; ¿VV•³'®°ìSOI=y7¡ÎîS–À�yv¦ˆª§qÍmóµ±…!›9w4xëÛ¬8¹êrÜLà^R³¡PH¢™äxã´Æa®“úÆK ÀÐu€ži,¹ìv»m°åtÜË9zlÍbûvÉ%©`Ÿ #kn¤ jãàPh¬üÊš�±±:d_ñÐð+"œ‹Æ”#¹$*z{Àp 4ŠŒ:¢ ÍȈy±^îÆdÀ8(}ã$›�y†T^Ô‚¬×Üê^ö¼*b?È{›Í‘jZO’²ŒÝ‹wÎöö6D²ôx˜Q¥åĘ”„š=Ï€‘_ºGÁ çxµô™ÞpÓI·­ ãJ0°ÈtÎ…²/’ Úr;RÖV0"ç ÆÝà­­ChŇʰ €–ç¯GR<ÖZQÍ6¶”;ø- •Mõ!ÀžÙ†írÚjøËí{Äê\7›I_±É ZI,|SVr2¥²f/U•3sl�Ó˜Jã´|“WXòÖ´£ *ˆœ©`ÃÜk¨0qŽ‘ˆ©ä» Õæv»Ýk®¹à‚ÿTñ 8Jª¡ô„Ãü«"MC»8|šºSÙ9´ØMÀ:+sss°’¨º¼à™� qJiÐe(R¾É^F¤ºæ¤ÚUÓE'˜X”fPsaP”Ê•ûʃÊGu:ÅÅÅ0…¬[Uä ÉsŒó”'ïÿ,?Óœ"ÇÇšbJ·Ïh‡^ŠQXÐ^òœ¬ùÊȱ™B¥ÜS¤^AùH–mo4²¥j>·"X³>›¼Á¦Èñn‰%<sº ykKKK7Þxc´`“CR…–Éß8ñJ b®–Y¾È3� Qð72‰ßÔCâFȡћŒàºÖ: ,x³æÖ2¤u´ôãóÇô§¥pÌ-©¨,žÿ'&å—ÃßG«#ÎJͲæð2SªLN´f³yË-·¼å-o¹ùæ›9Üsv¸Ç`…Fj|`ec䇽ÊT„WÖúöö6õYÕ§e¼ÚX9Ê1<ÏKRZÒ£8'rÁð¾*瞬'Nœèv»yžlrtKÝîÎWçÀ7šÍf»Ý Ì`U“wÉjÕò‚^úÒ—ÎÏÏsÖ�Ceò‘Ö·¿Ýãå!ˆßÚÚrFŒwªûHð^šð–xÉߨšÖt$7æàåTË5Àk‰Ic¼öHµTD¾ÐÕ–^¯×ét¹1L”7Ë?äI’¿çórþõ°0oÍX1¥j«ÕºãŽ;Þð†7ä’0ä™ûq�a—ùcËa?:ªÌÊÐC¾L×h4N:µ´´dvˇ*6¯«mþÞ))Å®u¦ÉÏ(‚­~͆µ‹Ç1°vôQ ÆŒFÖ©Ãö) ²æyÑDtŽéøõ’-‚0@pÁáa ÚI©bböìÙ .€s=.#'ªä=|znÙ®º4iͱ1¸jø$J§šz‘‡ ^áÿdÐÜcFIT­?OÞÊé†nÇ=öƒ)Üî6Wͳîù_+¤A÷2oÚ[®myyymm.… TÕ˜=P!œ€3Ö±‡4Á| xeV¤Ã·$ò›”Vv°&T0, 9ŘfE¦\»aCƒm¨•¶£ÔPˆF´`V…ÝBY™W½ ÅY ÿÄJznT€3õ\~ù«_ýêÙ³g———Q=€ìÊÃb¦Õø4@Æ9k³9ø}—n –«««vXwÂê~z‚ÇãGnøU£{ṵ̀¶¶¶ŒÍ€mB?9Güãæ<E'y©EX0Ь”E‚ú×"톰<ÜCuU4BÈÿ†}ûí·Çã¯~õ«çÎËxˆ^&îFXjɬ01WRon®T¤ØÊ±£––1UÁ³ÖÙÒ–è.‡¥'ñº6J3ÝÑ%ßÏîîî>óÌ3NÒóûú‰bÍÌÌLЉr ºO5|/©‰­®98”ÝKöÛÇO>êÈU LàÓ0·ŸÃ³Ì“­^Ž»~G®-ªùvw×­ùèê³H4Ì`KNÏ,!›²»0…6æ^côI_”…Ì+®P\Þ5z{W¦žEË"ñ0#1Æï‹muåÊo[¢K‘{HEÜ7•˰£¬¢[5SM~3ŒlÚ¨¡®(‡•ß »g0-ú EæX•µE?CÎsH í}é:×,+6òO*ƧY¶ÉË’/çð%ib!z‰s"2ÿüóÏš{vÇ0 ‘ƒ²ò•©²æÊO~bâ †‰ÒE§#åô„NJ†è¦·©k•¸x7Oˆ,[(¨]ø EžŒž^ä9˜°€ò¦Õ‹­£e^ Ã𜪀¢D/«’XÚŽË€¹ç _`CºèÖög¸Äo§Ýn¯¯¯[¯oZ)ÀC]¾/ …U°0Ë­H‹‡K½ dàÉÎ$¼q°Ö­ìÒ9ù¯Œ+VòÌ<g7Êc®y#&ÎXœÔ)£ÑÈÍ6GpAE3ØEZ@…Z5çHÙF¶¡VVƒ2Nq|Il>}Q4„n#Dù<„äãë8äq/¼ŠèŠ jö¶Õ 9ìUÏ–CV®6°õXà{v[ßxî¹ç@ä\^˜ œ%r‹Õs§9Î)‡õÁ!ÞÌWcU³Œ¯ï~ûîöÛ·ÆÌg:?ßi]jÍŒf,­ïº„:‰ DŽFëBXkŽ é?¨´¾‰^ö1r¯.à›ß qΓƒôÏÊ o¹è³aÆÅ²A0"¥ ¢¥œ³È`³Ø¦qy£4í$9ËÉŸ3 ™»  Õ\!ĉ¼eÙܯ & 2ÊšåAMé„Ý©´i4°iwC"èbŽÁX¦>M3¬á™0®?‹'ÓÓP¨1:ª 8€«çí‡Æëðð “:ÓÄ‹Hì©5ÁÝzÉ8sž^„3‚øGúHäs«ìò2‘s„j7Ç!§¸Uh’å4¶cx̓ǎ&Ô|º€¨Mî|pq¢ÕèÌ:[.-"NF€/¨ýáã{„ž­H‡Ó †.Û)}*ÍöìÃñ·Çß1nýv«{O·Ùlî½zoë'·ºÑ=ý[§G+£õõõ\b§ÅÍÀ7HÞÉå™ùh·Û§Üæ±@™Ë/£ØtÎh®šS‡T°õ~ŒK8EHœy,'ž6^¤<ªx±Žè©kyÈkwqSÉúV¤vO¨�æPZQÒQ0¶0–õ -0 Lè´yœ~qe¡&Àj“ÅYeâ•3ìzTþeJ½¤tð8lé+ä½›ÿbn¡9&†L!³~»_¯Ì5wžÄÞAz‘—rصòt=Eã<U FY€Û£²³sN\d Á¥š‚Ä÷±yÁ×EÇÊK4ú`­�#ø¸db?A`kkË–Éð2+ne5Ïäí‰q60r™Ä•JÞƒ|Ü} V3¸¼¶éuSe ªU“Fcû‡¶Þ¼°···_ö÷ööÊ_”þ{úÃw>¹cê°#ºmolâ~�õŠÃƒ±à5ê8c–SC¦rU)r6â¼³«‚ç(r‘®F5+ó.Ïl¤3PLÉ“Âý6”ü¹ Ö!v>ž¥Ö©(Ž©˜xR'‡8G?ç”!tK͆䬩’cpĬ Þ>„^ô*êÖ|óšDu°È‰<ØIoŸïâ®yþ€Ãöª�1WHü o‡Uí‚EW¿Ö"miWüf¦ Iª„°B5”ãi!ûô89&±eìëÊú?ÚxsL’.¾¦Q‰Ð¤¤ žpeP¹ÃæHJÉB=d 3Ýk¢AýÓÀ�v(²4ïÖ9—ÿ9]è¶XÇ[è: ž–*!±ÊÚ¥”ÑæÞwõîfggi·ÿQûâ]D¤Îs¦�,ÞQf+˜…™1…$ãööä„•U-RÞÑž–P3¿ j×ñŽ€ì‚lØgwœ �Èä½På8f¸¸ñô%~\ÞÜܪ¯cYi>ÝÀ0™-µ%¶«LÖíÁÃç„{ö¢E ‡#ôbÊh+æUVRVx#ô&Ä&zå¡tšÍ‘W�å ,–¸=’¤¶ËgÒrËgòEžW# ¸2°a³óŒéª19Ê`0€à@Øðæÿ’³R ±ÀÜbû;l %~Ÿ<yÃ@0= 5SÀâ*¯ã*çh~ˆü¼÷~ËÁ šûÒnÆ8oÂ5š<zwkÀ%*&ŸL"ïÙõÿ̨sµ¸íð†ºš n9ÐMñh(²¼ÖÔšL&»wî.üÆÂþþþÉ“'¯½öÚñx|îܹ™¯Îl½b«R€‡ju*äT*îDƒH¨X"Ìâ‘× HÙðp`»/^Î!Fç1/‹i ¼P‘W02iGmީϬ¨8’U“ƒy>n`ð—¤.asøæüò¸ŒËèô“²tÉÜ8qßšâÜ_-</%šê&2D½Ôp™ï‘)À†¼DعTôr\7ÐÛçbü;Y64öPçtªa¬¯²bâ’x›À¹�çäV³5þ'¬¼ü=á ÚÌÁâçÉÑÑívC‚0NX¦ä—òážâð,àqÈ9š*‡Ñ3»„%ß·­:˜l‚Æ2{®p:Tp“O1úfšZ/ÒÃ箦—Ž9`.t5½ß’feÓ`°ë '>âû{ûÒ˜iÎ,--Ý}÷Ý—.]úÚ×¾–u?)ÇàŠ� Í;:©5FáÂrf˜Éà&ç%DÓæÙܠ˸\b3%ˆpØBÁpâVœÅ†qAvÆ=]ÒU°îdÎŽÑûA´‘Î¥Ù I µý—k–ƒ´À³YÈLEš„ót³–bˆÅ–¡÷>:#5,ik­æªŒìííu»ÝÁ`0)èó—&ÎxTÎ ¤å@Æü<ùyd45WeŽ òTWÛ–R…à9»hvÈ‹ ©²í€Öˆî»ûg@v ë8ΫÌ>ûì³¶i°zÐh9˜ÒMó§ã*çèVC!]‚øk39&ÛŒãÒPF¥Âdî#0¤€œVô`CB*ÒëD=+ål{{fTdPǼ2%nOSšìüfgë»¶ºÿgwyyù+_ù NØ[ïÚjÿë6è?}i÷Ná€U âh&[hÄÐ9<à–˜W™§´°°í�HVD¬r ýnë£Êt§Ò½~Ñù Ÿ>Ü…=+8› gܯæò ’X!”¶“û7•[¹kß|o†]�+10ëy‘ ôsBV »‹ÃŠÂ-¢<`‘3óoÃh&å@ðfnnîÖ[oý¦oú¦çž{îOþäOVWWYÕEšân˜UtðiM¸ûå°LµUïœ @eNÀ®Fz‰Ðs*÷[•»µN É–aÒÊÑ„“¬4a’ W l{yÄŽ!Ëj(©pU‡œ£ 9EÚM,G¨œQæ°¯¶ÙN,çrT‡—nq£—\õ-‡žSÉ:¾Ì÷”ƒaoË®¸tpø¬<ŽBO±˜q<ùäÌÆnÌp~uuussó‹—¿±;øÁ§—Hù鏿`J2ªV‡ðHñ2šn÷—´ŽãÜê(’ÿ‚¹kn \rÙ~tû=¥T•)Œ£s…*3„0™fòwGwòh;ÈQYš6f$¶¨rÁñsÂäñ«¢t©~°ÄöRa\)#8f¢[cɦ¦æÛÐýíü$+ÊÓèõz¯}íkßö¶·=üðÃ=ôÐp8Ä^Ïšà½öåc{:á«Þ  –«±,TÚ]yˆ›¹v±ìz•¯”}&cÅ4ÛòêÃb¯Ü¹¨ž+v—G5`çA z~¸š€n^ŸÛq•sÄÀš7’­úòs|¸ÜL>BÓacVž«o»’)™ƒA-,,Üpà ëëë/^¤¸a^Á3g80-2Ϥ®9$¶Ç-RV[œgffzßÓ»øÉ‹sŸküûF³ÙÜÕþèïŒÚ?Ùž\˜”V±ú!ÊW�)¹`Ä4½7(, Ø×�x§ÈÔ™î·oñé ÎY¢K‘«7ÈC.ÔÞ»§Øw«Ûíæßú‘e38’«"[‚ÇW‹lЊ"£¯øùÍÁ`pæÌ™§žz*´ &{ˆÅf#EF÷TÕÖ ôñŠ�hÂ?æ´¬ñfFé®%K�Å _�ÕÀ EiŒÑSùüç?¿³³sîܹ+W®°¿ØM‘ñ¦Âê!•*­,?sssÙ­0×­šœHO…•‰[+U“ªÑ_¨tWa±3j^ PÊržïv¸Êï'b9r a“ãˆ.&·`Œ=©g×q/ç(€ïM¼!IÏ”;ý «¾›~ÃaaN'“=•Œ ÚãàNwß}÷Ûßþö§Ÿ~ú·~ë·._¾Œ•m¦ÈëáÔ¡íäÕï¢ ö½(3÷ÍŸ>ô=7ÓSü_wþÞN£Ñh~¹9¸w€ ¶1%À\UN·Ju”&ª NÈ á10ÂŒ:/‘A꿜)*Ï=‚Šõè¬ÕO–àÆ~*#ì0Gìqb3é"IGËòZVÙ+ÿ›[KTÈY[Ò‚çŸ>EL«Õêõz¥”µµ5@ñ¥&é’2‡C^YÆbò¬rã£ÑÈÄ3šˆÖ™véSÍÁxh <€þ(Š„,Gðã?þì³Ïnnn„È–!jˆö&¢ñàRrî½£œT$VfÝÀ ÛT 7öš6ög¦\†ûZ¤>åÀÿ­L *Õ�V)-œd6}°¬"â÷V!:9GrŠ´°¬Ucm(‹pDVÖÎåðTÍBª) ƆiÄÈ‹``‡f²-ûšd¦9ÁduÊÚ.¸ ÈÀŽe¤jiV@ëc­æï5™0(R”b®vÚlʶlÎz�IŸ• 3¦H8¼9GT1 f‘æZ©åÀÆOŒâ ‹S½óiÎÇ9/LoõØf50o‹¼»LwÁ ­fuIh`ÏÌÌ,,,¼ño\^^¾ÿþû訙”ûßÃL„—• R˼–¦Î¯Uò6‰ÊBð‹›–öa›$¦Úy‹M6qN»H}à ®Ô0 Œ3ÿ�´ˆ(YÂsn„A¼Ç�‚b9,”åã…H@^Ų©hb0u'Ç…·žÍ–~ZaÝtb &Ä×ã^·4ÍLµªörX5�’’w£’"ú@pšñúE¹+‰öÙ³gÏ;·µµµ¾¾î$Úé^óà‡ù>Î;©iPˆJÂDUhrïÁ™ÆÖ%!å°ÜQ53=š`äF…ÝVLV®¨}x¢À °¯¨Éµ�^±*6žmròÕ7wSײ=/z`Q¶‚ å/™z![“7U+Y½Æ€˜ÿk¥žI±¶¶¶²²‚™­o r›‰Nßüx_a‘¿$á¤H™–'½Cëÿ»uÄoB§F÷ÌÈU9êá,&¢WM>c¡&Á+‰à-+/]xáÖ´Îg"XSÍÖƒqcÚºéHE@,œ››KR˜£ƒbÑöÙG”éùÁT»š¶Éà  g“Ò»„®ñxÜív+/àã*çë"ðª2+±šÂÁå>»"éO%Õ¿�L,ÎŒfyšÕvåÊ•"±¿K’�� �IDATªrªœÊaq~SæTŒää¾°!`ÃüM«ж“,«JW]ôÜEb§{T•¬¯KÆ è`üŵP|hb)…lx÷áíz@OïÚE*øþžù"ž†²RA¢™¥âÏ…u:û:s®ù@ô|ðzÅ‚£UN" rˆð¶4xK¯¯¯ÿùŸÿyš:®>=:ƒp€¿Î6ä~¶ú˜ðµZ]UnVðu•… H\6y ~6ž"€»£$ì–¨TtËa jü‡`[°a«¡×ùùùV«uþüy“J9ÈJð@7pV~-i(¡—çÆd$³)‡…Ò %±تñmÆkh…Vƒnå°!!"XÃápZcé8ä ƒ€dŠ]]+Up¤’ÖU³œE l,;°l7÷’=åÏ6vä2 Ý:Ãõ,d$:¢ôŸ -¸n+ÛP¬Ð»ª0t*û‘ Dæ¹ÑŸl´æ+x=2*�Ævܸ6%Ý`ê>ßE¡ Ôr/†ª Yä]fZ ÂÆF˜››s ÁcXØñ9=/sÄM®³t…ïÔüZÛtÒʦEÁ:¿ïþýjÈwõ«§v<Õa>1A‚<:öÞI­øÀ, üë¸rv‡Q k=˜ïÇÒuª‡]&E ð‘¹ø|8PDÒšðŒ‘1ÇÌx)euuµ²;2ƒ€ 01oÚ³ÎÂNö´® »C¡¼É3ÏS¥LdNƒ>S¢R§ÓI±^zÔÁv[8®rŽž! ÛÄD{ró$& ^À¬µà‡µ¹–fó€Ùy&ƒ8»…àÇõTÂÌÙêN¸`Tég»ÝNqfNv~0È1ݰ©†`hE€VÙN'‰ª!>ðCÈ+í°kd‰BÉÂ9KqÃ×yXÄärëKšÄcGŸ‘£^¬'«ª~¾ù"…7æ',»É8ê‹ÚÚsÍÕ+£–uÍÜ C‘ †õNÜ®óÚ«~ÁŽUá þ!oTÊÝiÓ¦)Íç¼Ë¨Wà šIOD ñÊ7ºè!åªÒÂu¾ÅâßÚÚB'QÖÕ’CµQÁiÕ×rx”Ø`³ŠŒÂè±´š] ¹˜€àCƒÌ¸‚sÙ[[[ЩI•òxç­}wrޏ—ƒä‡£Þº%˜*ÀÚGCÖ%œàĤB _ÐFz;ø:38Éô9åì¾°q‹ñ1kN\Ö­‡í#Erf … ëyIm©ì>íR ½VJt´Êò(:ŽëHær*s¥kGÃVõ­-ìÙïmk1ä+ò¬R'å LÏ÷y¬ÇbzEÒ–„ ,¶*b…Éî@�*rª¦“ÖY9ìŽáîš'Ë“›¨e=ÄÊ‚Ì#j·ÛÈ×ÂûªØ4¶l`é& zéYæªÉoqÏÄ8ÒW©º‹óæÕÄ£e– þ¢RRve`¨žÑ®@ËjTÖYˆí½!Ëyz,k„ ¬¢òŽs…Ƕ²>7Hí‘çr¤s Ç!§LVÕt˜]Åx©4Ï™ç�ˆà.É‚ CHÛ8>è0 @E'#±Ê§»WÒI TßìvI`bo`‡Ü£Ç¶ÅÐ:C…ëlÚì ˆFö1$í;d›˜y.!<Ù%�6´:°`q¥ܬÛí† ÈyMIA0'-­4›CC"+·´V¨htÁŸæÙ’»È &Ƀ™>×hË¿‚à@Ž¥¦S sáÀE†óÉÔñÈYyÁXn%ý²µµ•×ÊP$Ç+ QÞ‚ãMåØétÀr«yü­C= …ãÁâ! äT’Á_€!~' ­* %Ùø¼/ øšæÃí›TYM¶t‰Ð•&iþ,1ûÅMÐ#<lCΡ:Ýé!Y¤çÃ-“œ.…[©¤‰@8D9û›¶à%ð8oâPÎÎD‘\ΊýLÀñ]†;|ð•ÃN”,ÆÍMÍ$ˆòH«œ_ÞÕÓŠÕœ„Ç;*ã8`œ¬tIÄu‡ÆîÎùË~¿R½uع£Ü©àÇN½Ì%AÍå Eœ˜ySvúâ3yq¹$fZ1|D$Ô/È2Ø–^õ›²·7ƒ,à6nzfœ¶$ }irj<Á GU½zúRTQ¸ÉAÓJyÔétNœ8Ñjµ677ÍU3·­ŒT»7IÖŸü y7z3Ö50³Ëó4|Q¥CázÚ˜0ßèÊ.#­©ê$æ½ò*ÉÌÜïaú*ÏïÊûvåaŠ q…ÏÙÝÝ {ðÍÚ€ÓÒºÿwÍã³rY©VÝgw1D™Õ_ÉkºWìpž,©^¯ÇðM¸‰|‘H|@»±<­þK|2ÌN';Ód¸‰f7VÝ—\’o“e”ŸÃö æ˜U‡©v±,¾Õ¤ †¾pgff®½öÚ¥¥%vQHÌnF�¡ övò¶q}úóÆ"<¨Äek=F“ó—Š6—A²\¤<ÄpI§Ó±ÕJþ 'õüüüM7ÝÔï÷ñÿöµA7p4ruô 5z6�2&° “[š…î”GyÀKKKý~ßüò4 )*/�rK.±ì)m rP¹$ÃY(†’—ߌ‚5lìÔµN+!Dpïj|ŽíýZ³°åÁÚ©ÖÑ"ÝÖ}à «è1Rؘnvš× Vá»éš’úqÈ9âƒý‹ i”Ç<16ÎÿÎÍÍ]{íµ·ÝvÛ`0È>aH3?Æîùd´½ààŽFì/§·H•„0 "a¦C¶7¾×•»mÖn–&WK~Êò…ýläŠï® g1ÃäÓN½¨IV&fW¹Y6³'ã’/·Z­S§N-..¦MÊI(‘­5666h>ÚívŒg,Lgr»¾ÖTvBvÞè9å0¦Úùqu2Í*ÞÞÞΙemoü1¸å–[Þò–·\{íµ¹µ~¿âÄ T®Érì»zÆùŽ.67W;7+>µmü“|Ík^ó®w½ëÎ;ï„Ì °ìŸ§º¼¼<!ÝÎS zÕ³GˆÐ¸™ç�s¡² Eg…›à¶™wSËÎv_Í t.µÓé¤Â0ƒÁ>2Μ¨ŒÂ)i2w®~Ð,°‹JjSûl¹eÝa> ‰ÒjvðX;ú*‡Qj /BÆuï.ã/߸ߨï÷?ñ‰OÀ~Ž*‰›„vE´€üÅ‹«„pb†f‚=¸‡[&^[^…ÞC˜TYšA¢-×oŽ#Öå@oÍÙÉšMˆÝÞ¬¦^Ìð®´¡f¡ˆ:ý.¼óAŠÜ]ÈÕºÞÝݽpáBž_y©ÂÜ3ɇú‰ñ…Ê ­êmäQW”$N Þ©q°³ 躗Ãs²Ry¼ÖÝÛÛ;wîÜúúú¥K—Ê?¤\žõ¸øð=ë¸pUðèNYAÃó‰®&ÉTHÔÒ›ét:ÖËCHWŒ`ÀéOŽ•çé\×´'÷ RDÁš‹év»œÔørå9ëëí,’ÄBEéÀɃ8¦‡¡[…j¤BŒ <R”WªŽt:*ZYV²*2f„M PàŸóƒ×”çŽCÎÑÇ›ÊÍN½9zÈàXgŸûÜçºÝ.h¾E ­RCw—†g–‹Î5¡Ä cÿ{ogÙY÷¾{Ÿ}ƪÔBBBa38²pŒ"¬€˜ä:É56×v®c;ÎMâñÞĉ3ØIœé:Á@l0ƒcƒ™1’ÀÌ $ËšPKBê¦Õƒª»Æ3Ÿ³ï‡Uõ¯½%¼”¿Ôù _«»êœ}ö~ßw­õ¬g=OäV¸Uš\DË‘u¢ýfâñdb‹IÒ·Š° Ë\ã¸j¦ÒÚfÓf¾��ã#°9)Ër}}=Êó™¹ckb‘ªª–——­“vj¥¤8´¦­$ÚŽ2˜Õí|»"¨£jZ‡)^ ‘}$B‘ˆa‘ÕÕÕèm‚gD÷›BÓM î*|KpÅH­ ]dúFQ`Ñ0‡þ—µ¾ãjo¿ýöûî»occ#˜™n|"ª` `�ŽÍG5“äÌ7I[R­¸b Û%!í”MâªhظOæc:S¬ˆ{‹s¨1L?™kËæ‹B±n"=.Y2‚8å æØX8ØÓÄq>}ßô/Išî·GºÀĪªŠ¬ÇžÄEQ,//£L“žjD?íTÆô&Ìðô�Ü=œU—ÏbÚBPª›emGq|p°ú‰C>/HI3w+ê'ùú�…[ŒÇn"?»ýƒìÒ̶m¿ÓÎ6Ÿàœ¦²®»'oâ¡+ûÆ{d2jâ\Üü@r|R[Ï‘íäWNF_ .NqY�ƒ¿„2˜ÞªeeY8p�YKäÈ`ªA~ñT—GcÏ:lI#±&µs¯úý~¸f¸9WÓò}�z™úÿj;v:R!ÁöôÎbÖ‡^T6äÀÓd®z}’ØU¬ç¨ƒÍ€ŒÇ~‰MJ^hP.{v™‚\öMÍÄñ­v©_‡ü&›€¿ÊæÚížä,•vzZ=f¬e¼C›EqäÈ‘ªªÎœ9“MdÍ[Š�£è»Zù1iÚ”i8Š$¦^œ’˜0º‚ƒˆ!Ä7HÜç·ìq†îþ]p'åü�"ê8Qº2`¾Ý‰g%Þ�Ü|\ÌšKšp¤†³¾dÜ„hdc@¡ƒÀ³æ ¡·:¾& ðÈâ¶t·'c<LÇÂðs ÏhÙãìç9×hYè!í´þ«ªêòË/ïv»_ýêW ÞqJQÅH¢2w†uèS˜êœ|œ$†ØMV!9Š”²É&¿X­<[„&ãxfÈK(@@F¾Û ÙãC»ÝîÂÂBx[XI„$-DH ð9ÓH¥ÈðhpÚ©Fã%ꤊGïó´%Íî³¥EFµux³6]F8Ú¼ù ñò.{kkk±ÛƒA$û‘’“·†Q.¡%CÕ¬iäÇ“Ý3AÞ¨º²µ‚*b 0>caYh Óh]Ú¼Ù R!h0œìp{3Š™xÛÅ"é£pÉân\søSÓp!üE³$k,›0êR+ ÄIê òBÞhì{–ÂS“Ay2éQ2ZÙ”t¦8Ç4HE®°;ÀCŽOd¼ÆæuÔ‘ð}— Dñ‰'žˆ•ÌdO”eÑ'ÈÖ@œ¥P@Õ(|ãÓ;NÌ·{(˜`0Ö|nOrXf0ìÃa:ò|Æ’¼ i‚¦–á^½€º¸À†Y¿÷è••!_„ï‹Qq…¯`ŽÕ·Íëv—°$¶­òœ¯³¢ø¾ª-ýC'2sæ£#øÙ_‘L×ÜÅÝ®¯û!goªD$ ä[c±ªªóÎ;ïÚk¯í÷û_ùÊWÐà;|øðl6;{ö¬û+N H­g“Íê“Z?‘áy4äÉлÝ.Væ-¹f„ÚØ`|œ 3•cÉF߈®)G³ù²Ì'¦­9íÌÓ0zøëëëý~?b¶5Kb÷"ÃÃØç&5”Vq„“(q R.ïŽÇÝívmûF=a¤1à)øc毷§«,'ìð‹«u:OÙAÛÚ‡#½˜Z±r‰í÷ûœÚ¶jöSöÌ¿¿7Šo–-ñœÇ‚Óp­†é^×SBÙžf³íÁ™„ÞãNÆîs™›v*òÅì»Ïê¨iK²Ú#™�ÝæÅ Í—¡Ö�¡™§Š'p#� F·Û ØÕ3»;:Q0YCˆ7ɤŽrœ´2k¦f­¦ýó~ýãôï}þ½ëÿe½ùßšÕƒæ`(2áE}ÅW¼êU¯:}úôC=,ûLÆ›E“QL’1A�„ÊÎ(™Œ4$Z³’„7 ø¸ÈPc ‰fò̤؜‰p£Í`“{ ‚kð±ºjÃF™µЛ“Úé\üŒÎ3'éèÌûH7Î[D¸Lµ%öy‹‹‹“ɤß†)O-óYˆ»«ÈvàÙd®E»á:[·¾€[ëÁiöÔ”áž)KÑ©Y‘ÓWÞ¬“$73ûÛ[Ý®t„®8j9¬-,f¸u •‹#Õ“F03Ô ã‹à;$ÚI¾ JB¶^% ô£áA§žßiKõ\—-Ã(hÚé&L„ËX±#Ìø°¢¶E²½f7^H+f˜‘±‡QçÝS§úMéMoMoýOé?]ñèŸÿÍÏ~f4:<jþÝf6©ë>æ'BÞæÔ©S7ß|³ùfiˊѽØô¶¡MÒ¥fM0ÂB:ƆaŸNýÒôT€I¦¨ˆÉ%<:ÿ0¯2¹‘¢(666 CÙÑZ�NK)Sx7f#2)IºÁ4N YÐyâ|Ç{P xhÔ{þÀ3%Æî<H‘vZ‰ÄOÆ¥Â\¿êª«Îœ9süøqý½n³1З)¯X¼†®*Hi%ßeB^n&ež7ŽßÎmÉN’ïu¢  ¬¼ÊS,©æ/ƒ!ì’ºá†Åm‘ñ¼°¾EÍ=n/-±œŒïC#„BØÖìM—¼>èݧtyê)k£YEÉþOq»ÆãqØ+0©  „Înµñ tù¸æÈbadú¹ì#p×´Ó%Øv·Ü5!?äìÁëCéCgÒ™ÛÓí)¥å•åæ}ÍÖO¶F—ŒÆowÿn&%ÿ5xXÿž9s&rdo¹`ô&iqfâcÙY€& ëÆ'xV”pJöz=w8ÓN> ˜Œlæ™ §ó»áN@7$‚||Í5×<ýéO¿í¶ÛΞ=Ëy @þ΄|ÖYÍ"è $™ßì–Þm7gò¨ÛÅâÄTîô„+dâ Źßëõ†Ã!ò¤ÃþÃ`0¸÷Þ{é�ó(Ý£23Í ]H“8 ýÄù¦H Ãô³P·[Öiç´¯# „F0[¢µïLV Ò w™$MLD*™k±?Õ3}BT°éBd3¸,€Ñh,2¯0VìekÄsD“Ö‘Á.GDVNÜ“èÚÝ3d6ÌRÏJ‡º´%-ƒ)8ÔX æï?ó˜¢à¶n77t’ürEø”zND²ôe?äüÿþÚH÷§û¿-}›O±”RZM¯5fiVÜYdJø@Õe9^XM 2Ù’†Ô}ôC!#¥J#ßOsùŒü”¹.nÞ$ÙºÄâF¿Öà•Åêiûƒ.ŽF£¥¥¥Ùl¶±±aófWZ`0j˜] ‰• ÄØÕZn{ÒÂ1% ÉKJ:F[f³ÙÊÊ mçhÉX!‘£ëòË/¿îºëΜ9sÇw,--ylf�ÂB ODÏ6î<='f!CËÒR]&Ã)cɃøÖqçƒ •¢ýf(3.²¿…®*žkIši5Û›ò”¹œÈ!b¥Ñ�ð:ç,†_CŒŒø4J=h&I³÷T†°ìßÌt0MDƒÌÆ]ÙdEÙ0ƒ¤©|(ü…ÀͨW¸{ Ó`ˆÛ<~*Nï|#•ž© ¢uÀ0­†:ÉóL~îñ7˜ïW9ßÐ×JZùBúÂϧŸC?ÇâlQÝ]¿kܺs[þ‹ƒ&í²!qÛ“Q;žœ× t@Aˬvˆ1}«ÙÛ¡‹6ãu¡íOÔqRæ6;ðz–A¨uœÃw2™?~üĉ±»ØíNoͦejÚ¬2똉Ïò'rŸ)¸0C"žb‰#/7c2Ed[Å`vÇn¯×ûžïùžW¾ò•?üð©S§Â¤‹ùÇlÄrv<ëÌ¡ÕB,¦kåöfmdOÅ�–ûðˆCgÝX &Ù»|$*<x°Ýn‡ò…+*Hwqy`¹i§HU²Ë ‹ÆÚ>ÀxíD,žÕ ží·Þ«žÓÙ¨¬‡¨(È!^‹]€.¸ï¤aaËmÄÉH7†Áä¹÷f÷ôHûˆŽœà‰c bCtg0À°Î\y�ìk!^çwÞ¥—^úµ¯}­ªªa©°RY<°^¯m šÀÖd$ŠX}£YSòãmͽ±Oy)¥º¨ëj«Õ?Ù®‘=9dÉw§«ô6œBféëÛælѵñk€‡)¥P7‰êÁ¬Y3¶"#4=¡ÑhgÌ~ÜÏ!¢Ý~—†‰ÜBwzëòŽt2àuŸfX•e¹ººzîܹ¯ýë«««îñ�×§3.]kH S«c¬í@äM‘·ÅSÚe Dé4–LJé\«Õ qâ &`ÖqñxG‡òºVœ}9ä×f~>%ž TxŽ|#knƉ< ìfë„ Ãòh»ùôØ%¸ qey8úfÕ0­22!WáÌë0%í/¿ŒiAt†ÃœÔÆûìæò«Xu™ëгŒ›g!Ñ}’ô7úÕJ­ Ó…ÇÒ±ËÒe)¥•••'žxb:Öí:ŸªSUÕ®¬ÛZwë‹_uq»Ó~øèÃÃO QB£‹BÐ1 ”N�G î‚~ëtôüÑìõ³¢(Ò¹ÔúõVq¬(O”¤9 <¶Df­7UTB£æ’ÆymÇ3N#'qvÓ[LÌ¢d �D‚3¶kœ;Ô‚qKÑ1/zKl{j~&vlD8þœQ„í�‘éªÓéô¦›nºí¶Û–––N:´hô/:†khÀÄõÇ¡sòLÁ;pO®ÊÊ¡ãv|YË5ƧXŒ³ž^õq|"ÉA]×!–z† w¹f³Ùjµúý¾ËÐ!FœÐߣ‡A÷‘³¥>>7³f0ñÝåh‘RäµÛí………¸’8š-"E„i*J"h8PÕcñ$©q:t(daíD:ˆžÂn > f~b´¨Ôg+%B!3 #Ì%` (ÁI²¸¸8‚j è|—0(—û!çúzZzÚ«Ò«Þ–ÞöÏÓ?”gmm­,ËtIýÕÑÂ/TÍí%>~Õx~ùüþgÜ_EñÜ"]›Ò©ýÙ6ªVv26çÊ2Mž¦š6¨’¡%õ÷Ôó—Ϋ‡ª…W,¤”& “Ñ/ŠsEç÷;­'Z¤r‘O­¬¬$Y§±å8è­ÛÀ:Ê–ŠèåÐBƒš HÁâ(èB§6³he“Àö㣪YÍ‹yõžªy®éȹÌäY[Ú7„+E¾ïæJ¤Æ@(©Œ§ßh4–––VVV½¾ˆ§ ÆqýV™3#1¦qÁßhSù²¹r°b ‹ÌÀCN¦Òù\¦Ko)ôLði 3›Kµ'!„ žÚmÓ+E‰½Jmâ’äñšÃe™¨6ÅA4“Ƶ×^{Ýu×=öØcŸþô§‘&³u¬ƒÍËÜ­ì‰û¥×ë]|ñÅ?þx”òîî Ýda=sv,·“$>ÑUèeZ4+Ó°àøy‘ešÒé+dˆÂš¿ñc1½G®yàÀ(å÷äõ¿®yÁ Ó çiþúôúÕ´oøÓÃÁ?4ßܤ ;NÇ{<»xV-z¿Økÿ\»óób©¨_XþêÀ|Ð$õx¸­ [¤Ìœ³N§×ëe²ä‘|…Ìþø‡Æíßh?í}O»êª«.¹ä’ΰÓúÙÖ¼šÏ®žY¶¤%Ãå ?6 ð¤':]¦0™¤Bub­ûØÿ|L-»†@ËöG W½m(ùý³á›‡íQ»=h§åÔÿ§ýþÏõÝb%‰¶ÙÃ|Ó�O<¯€H„[ôq{©o a¥ôwúN63mo“ªÄoaÛ3[îJŇN¦)‡“£‰ü/�·Ú¢ý™…h’Xx’ gAèJÚÃÔ³;ž:Ê Ú8pèСˆÇvU7€OÊÝÝn×ß—Œ¬èñÏË.»ìÅ/~ñÕW_ÝívíµÁQžÙ®ƒbe*´ï9¾G£Ñ©S§"ꛋŒç…ákà_÷21¼ÉøÔÄ|Qw²2)Y yþ‰UÄ›âॲºº üYÎQÄeuuÕHû~•ó z]š.ýÉô“gҙצ×>þ÷?ÓïþF·ñÑFýÐvn[—õü[çÍ4«[+òÖÖ¶fÿûlüìqýÙºHE&œŽM…¹ž2z Œ=à,²ÔÅÅÅÕ×­6Þ×è¬v^ü/~Õ«^5ÞùÎwÞwß}·4†ÿn8ù³Ic}“gÜï÷ûý>ç>h;R€že³¼ ;‡ b`78Ö$Ýž½ 7OOl4¡9Oº €<ÏôoN‹ ‹o<îKÍf³šU/4fÏq¼ðë ™¡ F4W"Á‰b€A°2°>ò€€hJ0 Àœ‡ó$F—b@U(mI ¡lŸ¹;ôR4¸!Ì“² jFäÂ\0²@|ßX‡ñ,6="ÛuݪÇãq1)Ú6µuO<Pò÷hwqžµ)Š`û¥ºkuÅWÜxãgÏž½é¦›Îž=ëf›[÷±¼MÄ0ÏA1¦óëfOÜu×]gÏž=qâĹsçøF –…©’kŽÙ;J‡ö<©®ëÆ´QO·•�CqÜòánSÅbNËáß•é4™¢‰å¯]¹FG€Ò–ÐQ’ci,ƒ¸ÔÈÿ@òaµq'ã@`oŸ>°7¯ Ò¤ >‘>ñÁÏ|ðu¯{Ý&§Õàk'åé²ù¥f³ÕtC2½+¥ÿ˜êo«‹?-<9oª«¹7UUõz=<Û뺎f¸‘.–àúúúèà¨ýXû’ /yå+_ùßñ“Éä _øÂ#<2^Ï΋ùt4%Íg"Ä€LÚ%iè/íôzI;Uoã;ÆÑ™‰2§0jç[+]€øØ3‘ÅO§Óyw>æ<=šê{ë‹.ºèüóÏ_ZZ:óõ3ÃjX¿´®/ªÓ‰D8tI/2A.â1꓌d”iK<nnF›Ž¨FKÖ´G¶à¬�� �IDAT¥ÝÌ "“墳AìL,…É)oÀ=iJ7RxH÷ùMbæw):ÎôiÓÉ•“éMëKê”RóÃÍéÓÖm­ŒË@”µ(§k¬Éæq"rüK.¹ä9ÏyÎéÓ§ã;:#‰Ègë Ï¢¹K†$<YBCŽÇñïØ±c'Ož¤«döŠçcâÖEGYŠF£1{欸¬ýì(uRªSù¶²z°ª¾\yw0dÆš8^º<5SH଻/ $ †ÁzŽË¦š˜ZÃÞ”Y=ëÛÚä"CùÂÛM) ¼ 0]÷CΞ½<–>°y|—Û“ÕFö‹²¨9‹YÂhÿ™¬ÚQÓÊ&"ø?ŸÌWVVî¸ãŽ^¯·ººú裎F#Š —Û :QlÅ èÚÚo…=IÐû;£O²9pwg[ç­[ß°éõÔüæ|u[Í“é?“€ã_cO"\8ŸÏg—ÍfÏ›ü9tã7¾à/xôÑG?ò‘=z´~¤½|Ôx[Ã98ãGœÚ\môм!êÐ]3œ˜¶¬ÄƒÄlýG@y6$Φ(xŽ<~‹åd÷e""¢&VFÞÁZ6!ˆ“…ì|ÐPÕu==2¼~2?<ïþr·q¢Q–åø{ÇãWëgÔí÷µ-‹É¡I3¯ÓéÄ© FJ™[Ï <ðÀÛßþöÕÕÕPe&'`ýlj²oæz¹#‚ÿº,ò ŽCF%‹Ü4œØDñÕÀ¯6¿ìsŠÉßž”‡ÊÞßë•ã²®ëñë﫟½X}¼Z^^ö`€ ¥¬Yåò‹¿VEÐ> ¬“LÃá%W<�hdB2#�6|¦ÍSמÛ9{r¼¬i»M&“b^�ô“ñPëqM¸r*jæ xÚ%®g4€ƒ¾®ëâýÅôõÓå/-ìc»çž{úýþã?>N§kZÝ\•ƒržæ.Œ˜ºãƒ¾_ ¢¹|æ ’= AÚ…ùééôÚië3­º®gÓÙà×í7·³ÆÏi—à ©HeQv:+¯¼òµ¯}í5×\sìØ±ãÇŸ>}ú\un>žïn#phêfÓm°`.@&à2qÖª?ÆvØ´ž}±1pÌ•°‚½{ãð XnS°¦– Æô!þˆJ´»7£ÎÓëú™õâ?ZÜfT¿§ì¼¯³~Ózó½MÎqnš=Áœd𹘃:"Ì«««÷ÝwŸ1%Jíø•………(7™Jñ“Êˆì°æüõ­q£*‘ûû(Ï„jеïbáMþÒ¤”í_k§”Uc6›5ßÒ,¿¹œþ‹é¡/Z__7þ™ÙP¡T0šíÐOÊÏAý@S<®‘‘XœÐz¶— a'ÚxqåàÉP:!m÷z½ˆŽûê{ü2÷f»íyS5þÙñì…³êΊ%8g¯žõ—wX‡1çæ³·"ξrö üöÈá½åäâÉôÐt鉥µÖêºîúi1ÍŸ7o|¦QŒ ÇŽÈX[ý~Ÿµî|ÍL§Ò37ZÜ=•RšüȤµÑª~½ªÖeQ¦YjßÕž]7›üø¤óÛˆI|À7 è›UU•r0 fƒåååS§N]xá…§N:sæÌd>IeJãä¶6‚Ù>ÐùDŽ0@ {ÉÄ&ôq†>v4®œC$IÌeP8ý_IR§.%ñwÉL?Ãg`t%Œ)Mû¦æƒ’W–åèŸ"Þ¿õGÝÿÔÿ¸ü÷¥y’ñq Á•‚T‚~L\’¥Á1G°î'‚o´¶¶æ˜ÉÁ«æ ºŠâÉÚ¶Êo†°Èl6ò &MmPýb5 ØÔV8Ú~|xüeÇÓ; ™ÍÍ"õŒ ˆú Æ ¹”Íf3hÜAH±óžc­§ˆÜ.Œ%²˜wÚe-E"  n à^ ¼_åìñ ¢Î•åA9=6\5h×íæ›ä¨é_™Î/7kLצe«ä©Ã÷§t0q(ÈTR¼ìý×Óù¡Îð]Ãb©¿g\ey¸þýaóÍægšÑm²Ã ÅûbÌád:ŸôZ,c*Ç“¥⼋ñ‹t$MŸ6~nZ>\IicccöØlzþtrÃ$õRq®°›ˆGX8ƒñØ%î­«[«ïßxì½å-o¹ì²ËŽ;öàƒž;˜|Ó¤ó:³ù¶¨—Ù ˆÈÙ±ÙÜsæÞ†Ö‹¿>¬B—}Bµ”|Ë yE”b:ÊsÙé@XŠœ7~Ë\�:ç|_Dû]‰Zå0ad:Î/˜×OÔ aQa4«æô‰iº>™\kG/¤Ò¸c³C³ô‚4MÓÙ`V}©Š)"“}]²›…ƒývèðœPÖèˆ:Iã I³šŸ•Îw§G äGø ‡¤A½X7VU»ºä’K&“ÉO<1ŸÏ§ýéôì´>R·S;. ¿v”Ô “F«’ˆ:•­tàÀg=ëYkkk<òz ¦I˜œN±lhؘè­¿d:†SW¼DDn¤$;UïkQâMfB¼Ù«ø­fzCš¾j:É–>ÿuuWÕühsZííÜm$©DFlû&�¸FhÏçóÎt¦Ï™NpZ6ÊúlÝýž.ä‹¡9û#¨¸Ï(,<¹Æw§ááÑ6Û¨0ššº©úbõ´ Ÿvýõ×:tè¾ûîûÊW¾RÜY nÌÿò¼yKÓµ5Ú‹ŸÜÌvï©ç/Ÿ¯ýýµ/¿ùËG‡k¯YK—¥ê“UæõBÃÜI’0°ì ²dœ*î be´°öè°4§'NÈUWðtèµ`å ÂæBã™Iþ¤ô¢X p@ÊjµZuÚ!ˆÀX–å,ÍÒ\?KäÍ~d–.H‹ÓÉt2šL¿mZÝV¥Ï'‹ ¬i2˜çQ¼5 ÛwmdI:˜IB�îi1Xêš´äÍÐñx<Nu"lÀõ²sXxµ5“L¯°-‚Q>ô;6 9en !WzQĘLôÚ=d·gÉeiÁ0Œ À¸\v쇜½éådz\Þ�ÝßéN{ÓôŠ­Ñ™7V³ñl^ÌݾÞí,IJPq`ãµåöU’H„7Çîî/:ÿ¬³EÛŠUGÙœnÑö@Æá°ª’ô3ÜõQâÜŠ#c6ßüˆóÎ;ïú믿úê«ï¼óÎ'N ƒT$Ÿ,q Y|—VyÆkÜÙHuš?k¾òÆ•µj-¥T~º¬îªÒÍ©hí¬# ºŠâÁa€MdânÛÿÆÓ¨*`ÁéRÀ‡Ž=èÏYJ2~ W8ôµ´ \ ùjï-µg4̵©¯­(ŠÎÛ;³Uo¯þÚÓlòý“ÖÛ[qî3‚J–ãÞÒøŒËµòi>í’_²²²rzõôú__}ç¨X+Š{ w¶ý]ð«õ߸CÎòv­F»%›NÃ6rÿJöæya¼Ýs`›¹Â™T|©˜ÿÍùìc³Ç|ûö^ZÌ¿eÞ~G›m›q;‰4F³Ý©õbkyy™ÑKÇr;ß@¦0}d2 xü"¥ˆî6…cÙgâoüÍ~ÈÙûFŽawȯ±P&“I½\—ï.ƒ¢Öh46æœJµxÎ òæK</ÆŠ'ýøÄlDÚšxÆaN“"Îþ²!p2Y4"#-u–Ãʈ“½Péü7fñ|<+gËËË<ðÀâââÉ“'766FóQ=¯gÃY•ªLKáªæd·Û]æÝÍâŽ-¿ŸãEcÞ˜ÖSNm= c¶™â!ñº]æš…«‚Ýz}Beñîɾø² {Îëd2 ‹etzLâ`Áí¦Õä‰Qò_à¦XK†¬!½hýYkã‡6ªUc°yÙ²]¦«SãËYÚd.]yå•u]?þøãv3«ªªì–³ÎÎÿ/çó¡oþ¶ïþ¶ãÇßu×]Gßtø‡Å•E}OmÎ MDfc-|ç{žv:²H UÆã¦Õg1·à(G°DW-†±˜i‹?f€=O =MÒüëóé5ÓÉg'“•I‘Š¢(ªÃUqY190©¬ËÆ[¶H2Ùn¾ÌœŸ‘‘>F-=? ºÃ+Áô„†±±Ý½‹õì)]&øEËΚ/cˆý^Î^¾†ixÏ…÷Ô××Ó4m|®QÕà~ŒtËɬ‹—ØÍ\4?ÇP›IM™P#¥‰Omjá$ÓOãu¶Ëô˜‚Uè!ÈÅ&w ŽÄÀ)ÂP«Ë²l|¦‘^”†/žùã3¿÷{¿÷Á~pyyyyyyòòÉ|<¯>Q­‚ÕÇ)a´å­ò™mÔÆ£²,ÛU{6ŸÕ"›Þ [t}–RBm—ÑÔlôÝU]|Í ð¸Be’?®?ꀘ£âÐ÷ôLV›ºìðʺ#êPu¯ˆñ—†Ü !&YcØÒ´®ëÙ]³ÖÇZ뿳¾øžÅòD™R½|4û¦ÙâkSc{e8p ®ë………S‹W¯×ÛøÉß:ü­ç}ëÞð†½èEËËËï~÷»ÿàþ`å-+ËïXN·§ò‰m’$±0zZq@»¿’aÎ0!M傇m†4ƒ·¨˜&€t¡kV?¦èmxR»ùÑæìfƒwªß¨Ò(5Á÷ ʲ<ðÔ­M_œ………g<ãËËËgÏžu1JöæÒ“6ªq|#±ˆ5EgÚ)¥ãE›4n,4Kör¯×K[Þ†¦¤³H‚Šft1kçXî}?ä|£_ïIïy(=tçÓl:ŸÏç/œÏœU©Ü]·ª±A‹ª1¹Í±B·ÙüH‹ Xk’na6}iŽ?IMlEJu÷éüSòÓlÈ£6‘ŒÿîÖ½¦]¼-£pGkü—Ç£KGKo]zòÉ'çóùè £úp]ݶYc[×3(V% ¶ãTu5û“›ÏËŽñ¦tÇEfƒ–¼‰]L2¾)Õ§µ®¹ìl\ŽäÀM ~Ë®$ñ‹</‘*±íBÚ©™Æ/fÖ“…Ç3-©Ò¼¥Yüq1úû£ÙKfÍf³óNõËÕ´ž&é?üðöÜ>õêùâââµ×^û‚¼àÈ‘#Ýn÷ùÏþç>÷¹”ÒzµÞl6ËV™Ò.¯i†Ç7ŠŠÏÓK³h¬Õ ¼�¬÷ìO´ÿ:("}>Ÿw»Ý´¥©³ 8¿½YýN5ü…aÙ+ë¢îü‡NùXY4 ¸jP#s"}ÉôÙ¬FÃ;`#åÄ íËZŒ†ì˜ãˆ@k�;¥ >ØS!5k@x¿ÊÙ›×»Ó»O§ÓÏOÏÞýÏ»ùŸß\Eñšbxù°ø›Eó£Mº‘ì%@y86& x¼ ó£7‹‰·MÚ­ß䕱é0ù�%÷'n>×-ÿì$·+¾ˆÓvÈ6¶¤Ã¨ØšóUU5?×,FÅ䙓·mlÎ-ÞԪﮫ۪¢¹]’–z?ØÔ§¹9XiyóØy“‰ôíÞ¸PlªĬ¼!i`@€9ÆÍ¸ç”„ ë„=ñi§ Ÿ³]70âWâzx(9N™é²'{¸¶˜Pj–¡j4ßÚöb™ÖSË£!tuŒ"Í_^^>zæhxy„gÝÉ“'———§“i9)«Y…& ^ £EJ1À „ Ik Nd±8¼!oÞ›v ±ƒ£2ÈeÕW+XÚ¿Ú&¥«‹m=”Ab ŽÜÈí©²­“ú@°û@nÌ*]Ûɳ)¬ƒ: ƒµH7&ïàäØ$òoÐkœÆ÷¥û^š^zCºáƒõ7uò?ÒªþF5Î<Ý’ZVP_€tc%a’h9Œ²iQ&öy¯×[YY1›‹D’nKÝ Ìµ÷§¤¡ 3Á²ãÒlÓ» f®Ó ì¼W·Wõ­õü‹[Z)ÇŠÉp’ÊdÏGŸ>™ \’°¹­1ôž pP_Ò©J2wñ÷r"™ñ âàïi9`ÛÁ). ž²¥69°Lt"É…„nÓw9þîžáÚ•'ónqéé™ÓLiÍ÷Öc"”Înã[ œ–kNÿÆÆ¯oÜù¦;ßô¦7=ç9ÏyüñÇï¼óÎsçÎmüèFõGU}²æ€–Ï"Ny§À_IªÌ‘¿ƒ¤qo Y¢Ÿ!·À ÀMrÛb’²Ò+‚"Æ�"ê‰�0">Žel:«£ÆÉÀ£G•мÊbÛV¡jÌÀ—°ƒg‚ƆáVøÏv+\wwhP퇜oèëcécÔ¸!ÝRêv»\pÁ¦¿òÒì_ÍÆß>^¸uŽ/;ÉoUUÑæŒ@øË T2ñx¼¾¾ÎÏd‰í ;câ­Íù/»Î™K$ÚÚ\™ÆJ|PŒ¤D¢M“ É«žÕÇ)¥¢*lt€!}ÎŒ¡<a`¾Yhañ&(TºŒ`pV"P7©8£qüÙ4ì·)>0h¡g6»ÝnxŒ2Ò í *]^¨Nâx¾1?à–”%ð(j8êòPøµ‰SÛ:o0JRØd¢=ÊÝ#ZpH•åìáÙ“W?ùé3Ÿ¾÷}÷®®®®Wû×õ§½içO;U±=éÙét,ØTKÊÏ€ª/FÄ�?­yŠ+pB³Ù<|øpY–+++žE5ÜMIòdä Ɍե3JšèmÇ®´ál&²ÇX±ýC‡{ Þp<‡Ÿ!Пw"„RúÄ0ÖX,`;T¡€ÀJË\Y´va·¹Æ¾ÆÚ^¾Ž9rÕUWÝsÏ=›§[¹‰ ËbK§Jï ά`硞«`‡g4\STɈGmTo‰ÚPŽŠ›���EâxÚ­]øðág?ûÙ_ÿú×Ož< kÈÉ»¬l@™¸b7“}í‹ ‚ç€j-¶4|?×1䉖PƒzËÐb€à6‹dþ#®YªH*CÑÎv&:a7‡v³×\úØÓÞCQ¼'l·LÂ˪¦&s‘ür(‘éɇ÷!ÔZœ›ÈÌ,F?=Z¾v¹?ïO&“:Õu»n~ºYÝ^YSÃãV·Òf›ïn›;ž5`${"e³Ù<{ö¬Os™¹£¶ÛH†¹¨,äÁy£eâžIº5iF؆4H©[&F³“æ‚]¯ã¦ã5ÆãÆ:±óó¼eq‡•ïgÍ­½BÕöCÎækuuõرc¦Æ¦:Y§Ö8>…N”Ô¶.ØÉò2§q{]p¬„âr’ße&ØåQ ¦Ä]YÓw!ëÜH’ÌJ6®ªªßïg„Nš1ÅÆ*·( #™üW¦e™R9âŠõ|$9O§0Ê”C³)¼Ì:²ŒS�Uc<дS=¥Ûíöz½~¿�KfqoÿSxÕ<8ó‘ÜiÀ,€È-ÂrvÔ†2Í'«šRñDeÌ]eà—ÇÇ ÖךãØMü§,Ëöo´ë êô’Ô˜7êaݺ©5Nƒ8@Ége°öƒŽiÊ‹0Š¿PŠÅïV Ù ììÙ³DJcMðIÒg�ÝŒ1¸7æ‡åd4¹‹·L`@R$ÞbP m'ê ,áù‹VDÉø”f\!ã ¡°@.›¤óë'Jù,ôz*`Ÿ>°¯—§—ß‘îødúäËÒË666È¡¦7NÓr*¾PÌæÛrò³"MR¢kÇ„Š‘ BÌÐÇQ͉?«œP‘$Ýf;zk]s^gÒú™”$ûÁ–ÕX�¦ãSΞ=»²²2ŸÏëº YÏœ€áIÉØ¸#Ûa…Ip3ÍN{Í´C‹ØØØ`[2Ì,Àbá/`‡�¸ø±€P¸ìjC—u->Y<Yž)§ƒ)IÀnB8>’ `7;Ú€éâ•NVÖ®˜©Ñ:£x¥yr†THoyH¨•‰ÜäL›§ê©IãFјN§uª-zÆ“Šû`r:üü@’©ec¢^2=Jð°1ƒ¯$"�[;y?ÚT4óp£rÛÕU>hít: E6“üÎM©)éò6›ÍÁ`� 69ÏÝ›—У9þ8vÁج@a Àb…¢âÒ꟰röàÕMÝg§g?pó£þëuñ¬¢z´jL©‘v{A:}3páåÎþã& £B(qX»™1‰Qo'}™-q’ÚG_Ø1I²wÛ€`kΙ0ÉÌy= â¬tìT‰#,3êˆâ"ùá8PÐ÷¬3î¼µÈy³ìÕ#‡´Á’zˆ|Y/—@NÿÖ¡×V› ã«Æó+æË?½<9<œÌÿ`>{`V}±òä‡3ƒÈOã>˜ÐaîV´^b‘pjǵ‘‚¸oÇýŒe“¥¥¦±Âãq/,,PÙpÀYc˜› Ö¢sRJò4y±v5-=8¾¡©ãé(S³ÀØÑŠ•�šJË'ËÊä;¯"’y$.Ö k î&ÈE•ÃXqÓ`ìÉ^mqµ<[<ÐFâá"¯¤>÷Ý£Ýê'¾·^äž%OgséÏ?ERâ‹÷­Ø9߸פxWz×§Ò§~öÃãŸE1oÌËûËæû›³rÇaOŽ ÎJȲ9÷ó cªI–דå>Nb¡û€3¾ä®€Uâ!û3'DI‘4—º[g7·0 ÂB/¶„b‹²Õ=ªBžEéô'RH?÷Hƒ×K Ò“úŒã†",²Ü”¢÷îÇ7~öxþ½ó#O;òƒŸøÁg=óYïÿûo}Þ­K/_šž¤?NöuØC¨‘cŪÌn_Ãi&6gÆ@9˜<êÁ=Gn™Ôjµ.¼ðÂÁ`°´´Äs 0ñüâÖe” §-ij¨öLò›‘uû½áú{nÆ]‡:ÿ¦n;ó (‹5ì™9˜™±IƒÑC&Äíµ§‘÷e¬eV²-‘-ñ“A’ÔÖÑåÃÞÐ2™;;°•p]à’sN¨™,5⎑}è4ljT@Õ¸rö,ê Òà_¯üëôåÔ¨í·§ýi*7ÃCœqáååÃPÈS¤o‚ã‡!9L²—d³……^Ü ITÙàäµiu¦OT‹¥o߃™ì€o¢…!ì¸?ñ&aÝá|� @FŸõæ!bm€>Æöˆ #Öœ˜ì.«ra÷釈²äp8œ];» }ÁkîzÍëÆ#GŽôûýéG§·nÿúßûzó›ÖØÞĵn¬û?Ò¯ëºq´Ñü•¦•l)MHÎTŽb©X¤'>âðáÃ_|q:MÍb`$R~sCh¿Å×ìt:Y+K€=i=úg â¥2EFl2E ¹f«VÊ8¾þ,v"*8ŒÚdN¸ñ5C'[ZM©wYQ�›\x#P\I€yíè¡ùb<ðÏ-¥þæjM’Îø2™‹ž§-²ò—ZR S;0‰2p~?ä|£¶ëN^W|¨H4M›sAÍŒ×!b :´xvÚb±P€†ÈbŒkeu´Õþ£;V@BÄzm4ὸ¾¾7,ªxO±ÞoþtúÛ$näïDïs BÃ&d÷†P¸Wi§‚ª{6=q¦ ·ˆö/Æ<l˜O©¥¿;ø%©ÅÄíªªª|VÙyuçïÜùw^ý}¯¾êª«šÍæË_þòªªÖÞ½6ydÒÿ¡~õ»Ðßì¼Ùú{Ö[ÒZøÙ…ù|>½jº|Ëò·¨ÞW ׆œ° 'qÛ¡†ddj ½¼ä%/¹á†n¾ùæüãhш¢q 1]¥ªª/¾øâ“'O’¬­­Ñê'ÖÆc¥àÙ#�ÃlŠ%Ö8ô Ö Ï9ý�“Db,}•cÔìÁìü¥£NF_38ÇÌi" Ĉ›Õ6Á3LF%§Îƒ ÊòÀ—d8z8dÔÕR$¬[ðy»[€üø¸�Òy€±€I•¸Ô¬¸42ßjµ5ÆÏÿå0¥”Fiñ‡gk³éú¾õ^¿"À`Øž4LÊË.ŽBæ!y}iL´úý~ÚÒÏp“íB…ÍÚ¤€«“¯“þÐ ¦9Ì Ž¿ “CáÙtUÙzg2q:Uqº…»öõToLð�†xd7Ü™5¾]`qµx“´Z-#˜ÝÔëõ2ÒpF'ßg—2Î…C]|Y§ñÔÎ?ÿüÞ·ô6ž³ñš#¯yÖ³žŸ~Þyç}×w}WY–ÿ³ý?<þà¡g:sæLüú±?:vñ+.æ¡l|~£sCgý7Ö÷4Ú÷µm±ß%>+N±îóˆ’¹j“ÉäÑG½å–[zè!^àG¤á0@³g:>üðÃ=ÙP”åíŸÄCg¦˜|(SŒæM²î=;e0@Ê¢e˜vê0n… Hábª‹LÉ,Wüë¬ña@Øìä¸$†‹½¶v"ÉnPVÚ‹ÓÐñÆWΔUü Ýwï\5f2?̹ã+Ç[™¦d/ Â^4¢:NúÖ´ñÅ©bñe‹)¥YsÖg¿qo£|s¹röòEbd&sð´?1+ÉSx€N´3?Ûîr€šçc�š¿Ü-åÉ 6{)²TOœd²>€ˆ£®]H¦XÄ2ðÏ'¸{Î`0À¡b¨ÂELUUGŽY__ߨØ�õvR†È‡9™øaÎ,èü¢Ç}2Á͸*Fâ¸3Çz4 ‡Ã¥¥¥g<㇊‡§NZ>¸< «MFÆð†aó¦&×Üét6sÿ¶úßÝïÜÝ¡ñ”çG“¤Ë`‰ÕxâƒÁàèÑ£'Nœ`a˜Ý Tèæd6s©ÓÖd14_“²L4·þ¬G,ãmáËð˜wŠI VT£ç!ì8cxÖtÎJW«dJì�� �IDATLMQ]Å)lí"S¶<ÉMËü×ÍV7ÔznŽ»qÖ“Be¼2Â<*JPT�í5M&›áó4q”¡ô#Y'¨»Âu´pCDµ¸Ã¶þK«¼¯œ§yJ©—Ý¿ÛÿÔxþ’=Í)÷ã‘V²Hš¥ŽF­GhI’²ˆ±8[k“ÂFÞ¹•qšÌ`›ÿæG§çU1;ðDl(KÆÅGùŸä çøn1`+°Y­™™5Sõ8 Êw:+®¸baa¸Æ%`lQ'Âñ>YšïÓL<³ÏeÀúét»—£y¸õZ^^Ž–û©;O-}dé]ï §¸Éd²²²rÛm·}ðîÞ[Ü;þ£ñ¹sçúýþêê깿r®yÓæ®¾æšk¾ã;¾caaa45>Ü¿b õ(>Ôy†YæÑÏsƒÇ1ŸÏ×ÖÖB ÃÅ®gõÁ!Ýiw …ªÄjõÊæ‹½€³îØcÈ—›LqéñR³�:ÎÆG8ôw3†mÍ« Î'uõ™iÐG èížn±¬_à„”P»‰ã¦‹R#þëëÑ¢$Ç,ê­À?Œf{'²£Fßïº!G¨æªÐ¸b"ÖÒüóêjþè¼½õÚ Æ,ç/ž×O߯röôEQ …ÔºñPMH"<¢„I�s–D“Þ•™Æ” l–Í0@Äž‰- <KšÓaú$HÀäzTfÄÝ“ž¡ÉrÖ³»¸ ”ÿôÉ8 ®¨¦ÓéÑ£GWWWùÅ�[Â{†SÉØBY–ëëëG„Ÿ†ª¦ÍZ²ƒ„„÷‰Œ5t}"ÀëÅø+ã[ÞÚ»·÷úÆë»î'?ùÉ[îºå±ôØh<j>ڜכsþE¹-KzõÕW?÷¹Ï½ãŽ;–——»Ýn¿ìGÖLŠv»mõ‡Í1©6l²G즱;LV9A&ö0æ Ç�…z×o‹èQŒ5¥-cŸ›\|k J÷Òf³ÙÚÚšä«XWVóû²‰j;L{¥<›4éÏZõ|’±,XšYÞf"2“¹<Ÿ`O|qâ+G~ãb΂ljØk€ŸQrë¢ëæ-" 0) í¦£Ê©±Ü¨ÆÕ‘ \rÉ%ëëë?üðt:mkN.œÔ½ý³w/ç)»å5­eBׄ-T%œFÅYÇ·ågHg /­ØmÌñ†“…­ÉÄ6•U¼,âK÷˜|–4îõCùEë–ºsk2’ir‘§/,,lllmŸÍfý~?Tæ@iø×ÀPâáŸɈZGË3§%|@3ÌArñp 6Bn~´yúÐé·ÿ·¯Ÿ\?¸pðK_zèMÖ&éà<)ÄÞל>oÚü³æh4úÔ§>uë­·ž>}:¥4¼vظ»a*7Ó†Ù\�#YÚõs!{õŒ=”b‹›¹Äs–ñ­ãËÆƃˆÓΖ9,6Qæ¶gšOYëÑ­­$.˜aϘ¡Ç“õô"{¥ (Ç8§™u¼§#4ZÖ_¡‰b g¾r ¦9ÈTw-&›d¥A?˜5@t7_�\#öJ:^“é¤Y7ëº^[[;yòd¦;·O’Þc`=lÌgw[2 F CEV´«˜6LŒ¹§‘%£gíŠÅаgn ©°“\U|'©MgÚæ` ‹8³'»7Žl›Ò]__gFÙ‘Øúrë ¬ ’;ö3P8A"XìtÅ`¬Ò¶;�›3ê†Þ»{|ø‚/ü“/4š';'Ûÿ¾½xjqT¸3)¥…w,,}l©ó»”Ò¹sç )nüÈFï7{æˆg¾|®Ò.3—•Óé´ÛíÆátD tK°CNñQîåm-óúÌèµÉ,O-œÈŒmr‡“|-w½’˃gÚ²ø�Éò‹UÉ:I,ƒŒó™¤UÈéeAópŸ-²çÜ(+µãþPÒ1ÒD!’¶Ä“vCßYi–ȲçËZ—$É…!³T7Th‘ºÐ–õbk6›í;Û£—Чƒ¥’ “ɤxIQ<Xg‹td?äì]ÈÉ ìsãq9f_bƒqØ!…9Q <c¬i¶(Ø”E6Ítts8“{B>À—MÎE#Š @æÅ©„pè„&½3NN¦k`[0k»ÅMÌd“á�+Æûⳑ4«:Hhr|²Ü€ô £ð™[ ;3Æ8âX F¿õâ^¯7=6ÝØØOÇ–ÊíþBwå÷Wš·4{¿ÝK)Íž=ëÿ›~õɪþZ ÿ‚MŸ,>L‰ô»M-ƒ�Éô.]´î fÖÊTõìi°§CéŽCö“Í8�ª<¦´%ZŠš ?I{Éý6S,Š­3–BO²Ò0%!z.b,šUöh6»ƒ9¡Ïký$Ûh 0»Ý.µš¹<öΰV4mTßhü9hå™{ºj¦8YNÐ ´Ž¶çIÿ¬œýð,]˜ê'k ï²,ëo¯4Šsû!gOµÙl–.L“K&¿±Q¤¢Nõp \*ç§çaÅÄ|gmû‘€WxÞ†õ³£»0~ž²F.!$xb‘¯A þ•ƒ2Ž0ƒ£÷›¿(Š……:ñ+‘Vg-ú@#1„ÈÇ'9ÞšO+Ž<ÃD!®“¶ÿ‚¢†žU¹ùa3cæ¬ÍzB·ãø™ååå~¿O RŠXÝV-üÄÂä†ÉÙ›ÎÖ©®ŽV‹ÿ`1­¥zPOÊÉSú50JE %’Ù÷ޏÛNt#˜ &Á÷íŠÑ=Èø”ápØét²L±EÒ¤âEJÄ„)–¯v iNk™s:{ %miÅšBíEÎL[Š AÞˬ©ˆáÿxdãñ8d~Bœ&ÄîBy:I*ÂØð'##¤5kå!²ŸP4ˆè9¿ÉÚû™” ÏŸ¹Àe{4mll¤-]QÄëà‚g5§9ëÆKÀ*{¿Ð¾q˜F©÷ozeYbýëÍ5Ûn§_ÚÖö”;¾9~xTTÅÂ_[ˆ%2xó IÍßn6jd�l$pd§±h€Úô3ŽNj¿'Õ»\0¥Íù=ž�ˆ8Ðn·Ï;æŽÀFdR4í±›3cœØÆ1‡˜.„%;uZaŒ& ='pô6â #ÂÅ¡a)«‡�ÙÁÍ$á«q^Ó”6ÈF{E6º‘© “äz"‚íÉóÕFë½­Öï· AS>›¢Ùî‰ Óñ­ŒÀò€-F´3f}«ò‡Ð…¿¸mÙ¬ÔB¤w•b|JÌ]Ä/Iêg&Ÿá–Ïn};ƒ�¢iÆyêId»äs&nEƒ*ICÝ+a:÷ÆB5£®ëN§Í'(…t2.€ïbåc2M“q‚ذ§ÜÓÍü“˨± o:rYÏ·›Ïç~ãà_5Þø•T¤b´9 c4r?äìÁ«®ëÉ÷MÚ7·Ë—àÎ ?±0ú[£ñãÎÃ,õ3fM)Ã1agLOÕÐê0«•¢›*Áäc¶Ö[äøFË ®­ÝnŸþùD¥1‹ˆlóâèZ™ÛŠ@: '>#èæˆs ¸Iëá¡8Ë0 ñ»û7žFŸ͢XIйfL�dÊßÕ6i¹ßøÊ1 KÎh±8‡.›ß@Þß}{ÓìüB‰5ëy0bì×YÏ]ù’¬]æ’×9J¬“ ž2›.Ò‚¨A-{Ã=IrÖH;EòÝð³•@fAKÒÀ„?8Î3w|E&dK!nBÐíJKß+0ªn¾Éè°CÓ–“ÇxwB‡ñФ/%ùñØH2™µ×˃۞¹6ÅÆ/¿Zv°»¹ý¥I"ûs9{óš}û¬ÔÕ—«ŒÂ_ÿI]©Ç׌}æúì)K³ClÆK-™^œILf²ˆ‚8ÐÅŠ¡ Fµîs¸Ï!$¾i´©ýV´m²¹™Ì>¾2*2äã´Fã΄Cl#fSE²6Ó8åãMø™Œ4å²)ÂF°6æð|-q Þ€4"1‚šÍ+¹!\a”•”8ô<ì>·›}níT"Ýnׄu³ågÀc¹~—I›P'8.ã¶€ó°8ºöøÌ~L=2‹#“벆ŸG…¼•âÁ±$èefÖãÖV·Lã·l„ÌzÇmcÝ~¬–8³ Fì/¾;;—Óë# k©¹)›¹a¡ˆ|I¦ÏÎóF,¾ÓNw½C›ä±î3Öö´Ê¹ žO棣v»}ÞyçE±´´4¾d\Ve}a]Ÿ·Ýƒm·ÛAœg€£6ò¸˜2ö†ôÄ +†L?T€ñ—ábë3REkl¤”ÖÖÖÆãñÙ³g§Óé`0@Jˉst˜@‡í3˜é§™íã FjìéÂàw¦G¿v”é¤Þÿ ‹– „AŽó¢;±Ç·I[šZ°Z-ß°{êÖ³Dž0Œë1;¾f«ÕzÑ‹^tÍ5×|ñ‹_¼÷Þ{-ÿc°($v\7€ãX9ÑR¡è–k>‚Dü0‚(èZš qfñ7$ì(#h¥ò‘ü$ùD,€€§(_xÏøõÅÅÅ€C3 ÖpvVÚµšÖ‹Å5 ’‘L€Oâám×3}àPwZ”Á6.’ÀôB/Õ’Ø!…Žïª‰h;ÅýÌjÜ´¥\Oe·jbÙ“-±7¨wùIR¥Ø&$[n=fÄþ¿à‚ ÆÏ/µ–¦7NS•æÏ›Ç‹ÆB£ñɆ#gÌy÷0È�râÈAŸaOÞÊo6É y:q!jG ®Ç? ø&™ë¤^–$°œ’f šŠ Àȳ£;'ÑÈòÞ§ÉÙD}’{·irž½çˆ1Éa�zcYNÆmJÉeShã°^XX8räÈW\ñÕ¯~8È3"OÏõö$Mš&vMfë$5‡l®žugú¤,^––Û€ž±34/›h!ü˜$I»Ë{ŠrÄ–<܇˜¨Íø‡<i§V›§îañXÍÚžvÍq…rvü<` ›ë.Ãõ"<½$û¿Y=5ËêŘŽr½å]FªGRkžK,Kôu®2ÛÈúo–WØ9{J¸¯ltõ³ëáÃïv¾:ý–éxe|àgÔÏ­7þúF=¨§ÏŸÎÍ›ïmšÉê¶ž)¼œkÆU3Óe—f¤�z ñþ±'í8�û“íDï4äü‰^‹á#oNV?-hÛ„XkËöÄ-/Ýo¯ë:0¢õõu³!±>ÜÃô¹ƒÅ G0—ÇéÖív<¸±±±¼¼Œù®»ñ0‹à—ÓØp™h³dŽfi#ÔoèwÜñÕ¯~õÌ™3îÆÇ×ÄÓ!¢”h´•›Ñh¡Û‡îgœnYƒÄÒ…¶,»PI6çÜíìC½6â;R±Ùˆ!I2À´~{>ôYœ�Âng¢“k£ ®–¥ð ÊGý L—¶ô ²¡:Ên²‘êqÓ˜v â$Œ@kÍ+R“H¡™íÖƒ.«L±×c 61‚Ÿ·‘’,ñÀ“Éd}}Û™¢2ÞpQµý^ÎÖú~¤Ñè4æ—Ïçóyÿ²þl}vðM/½àÒ‹_vq9(;ÿo§úp5½qJ“9«Ù“„ñ->æ‰hÓQ€é©÷m‚OzÈ&$AK[’<4 Ù$@ätA HA:@.ÐÙ4üZÄ}íé™vz¢ú̦…æÐl6<hWg‹¸loÃ\íÓ¸ æ,o¼ñÆ7¼á W_}5¹dUU‡B8.iÈudf--m2iüà+Œò›[Y>Ê———=º´´Ä·–•çùj< ·úø¯é�Qyøaü"îO@v ¶æ#b ¬aSTŒ^ˆ+™°5«5@‰\‰]™Mç´úCDîø-Šx–ô<¬*Má bBÌ0±%ùÖjòLwFh4׎Üî)‰—A¶4ß•¯@ŠãK²” ž¹«ˆUX¡»šçˆò—�‡zéK_zõÕW÷z=[·Ùï'Þd4™tºrö˜±Öüµfýšzø¥aýººý‰ö¥/»´ÿÇýg¾æ™¯~üÕÝn·z¸ª>S ~h•XLÞÿDp"¿ö°BüMô!hÆ›D¦F ‘ÕÏïö HÒ0��Å‘=ñþžf·VƧä,`tßÍóÑhtöìÙÓ§OãÑ: |„ùÅ!ò·ˆŒ»(Šyk>¸t0zæh|Ù¸Õj]rÉ%çw^üSœ¿NçòË/?ÿüó=šàjeemÐ1-ÈEâuÖétºÝn”8¦¥Æ@ODȦ]ÀD wMVn9d0÷¸ŒvIšÞ5õ /çamìV¯ˆï2Þ.N<AŽ'zàYE‹_�Ç:jfæÅ *÷ eÕ˜£"•éõz¶/Ë|<iŸX´0m ˆáÌ„Š³é‚P¿øEÿ7Žq혽™ähÜ®ˆñ1¶eV‹1~’´ ÿ“›“ÄâP>%ç�i ËKÍ„'B<‚~¿÷ÝwŸ<yÒõœϳžY‹ûÀÚž½Š¢(FEïŸôê+êµ­þéhý’õ÷¬½§Ýl¿çÙï¹çOïYZZJEwÆæze›=€"m†ŒF'èQ’š�(¾@S™L&Ñʶ2 ï»Ñˆ‡…i³¦ÿÈo,±n!œ´5@šv®›TcŽ æ(÷Úèõ‰-_Ïdœ;hÓ£ëGó+æÓë¦)¥².OÜrâ]÷¾kñý‹'Nœ ¦‡Á¡ðÔ‘Íâüøpà¹Àq 1K3†ð=ó,l-ã'Š$I¦ºÑÅÍd˜П'ÂÏÃ]ŒІ¶ûí–âe—möÿdB` à€ a…g¿xè0â:MS´˜4ŠmÔvñ¿Êè„QIÐÁ6êh%‹ˆOVˆÁxƨnLñ”iv+°Y£Ó€¸\Ì® ‡CFæØ»»–å(ÇbÕ*…¨ÃàyïnÝÇ× ò…£ Qõšâ÷a0;vŒ€äE‹Žõƒš¢§¶÷CÎakñ°«¢ñ§Å_ü¦oÿ¦»¿ïï¾ûî8Å&ÓI¶[ßN,Óiø%itŸ#€V=C#Úè,¹ån¡X²vRq7žÄÙÍpë?¢àäv!Ǽþ´e¢…¿e"–;ôÜñØù>~hn8°Q=`eF56ýÛÓÙ¥³âñbáÇêºntk?¼vüŠã­Ó­ôÈv;a0?~ÜŒ±iðX#ÒG §9' ,2ƒÖ3¦b³‹×áÇ‹¢ØØØ0sRÙ1Äð¹q…äÁ‘Ì:Ö—j"•%9‡û7$ãî%8ÑÿÃ(“&<læÈo`P·q®;Q°)u¬.ÎP{¦¹ßéÁO®–PAüsÑŸe9N)Ø&ë#T»Sè÷€¶õDãК {eE'2¦Z8ðÛ°Þ<Ç>ñ» 5l:‹y?eÌÛ9{�¬m>¤Çëæç›ë¯Z¿óæ;Ÿ|òɲ,Oœ8±ºº:»t6{Á¬ùŸ›‘ý!l•Q† (ïnGÙ">o8 qFÆÓ�~kÐÒê@€–S›êÁTëuf‚cÙÁ ÍÂÕÑÊÎÆ&lú™»:èfWåm€(£þ&öĽlÔ}c·z ªZÕd2oŒ»oìNf:½zÚúr‹ü.É …oRÈø¸ƒ"€H´ ¾‰cV±®ˆªˆaò£”»ªÛíšUŸ9â~Ü Ñ0Tòâ›FúÌêu8Ïüý2Žý >¼æX$ñ÷ðP฻"±«¡]q7âv!/ä®»Á.<:i˜03€4ŽÇ€ jÇE:Ì»-DÉ=_*Jdâ• ’Æ6?Ó\¡65W>kõÇ~Éèy†2=þ¶ª`ÏÚŸÐ;x9Þ™¾=ìå쇜 ˜ùhÞx¬1ºvtî¢sÃG†Ô‡“§OæW΋QÑ~²=©&¶óc‡x Á}Qo$3’³)3S©š)Mj£‰ÍBÙ‹Ê�:lhjesÎtnÈ‚ið&)™Ú©7mé]þ@…ðNðIÍ/¢>`rD€x¦Å‰LyÁ9l4 »ÙΚ_j6l<ãϸîºëNŸ>}Çw¬®®6³ÙÿoýâO‹ò‘;Kp·âƒ,Ž’9ƒñQÙJ�±Í–zLZÄ#??S ißÏøÖf‚Áðf¾‡‹á'3§N:…žšÏçq‹8‹9=BÄ—r&Áš:ƒ_v¦ŒÌ6‡Ü–lV7@db=ÃR˜-eÔ Ïëð *ÜXÞµ´Œ†CïªÅ¼ˆßÔC$Rü—&«„I’?où¦€™‘²‚€C¬Ýíl¡¶ ^™£€§ÃT–x Me‰š<²rö8ÞlÞ‘W³³ñÏ‹ÏÍÔ,êbú-Ó4H­ÿ»5.Æ™]Ó'q…„{š<o5{je'l6æ$ìž›áxĪ8àèm‚Tì&†‘ßÙkÄÂïƒbÇ7ʱ´kžÿ)QJü¦lÙÉÞ P@•Ò'¦¢N&“ºªçƒù|:¿òÊ+¿ó;¿ó±Ç{ðÁ766æãyj¤¢,|4¤-ÑU4f®¯¯CSvkÂk<Ĥ‹’M3£ói5ð@d#¬2à(î±’Ìø'“u#+vÁ¯ì•—vÊ6›-ù”Øšíp,MëaF†ÉÜÖJb‰ù\d<E›¶¦›b¥1ŽFhº6+g·/mô3²‡±Ù¸$$"dòVöðã0ËÆoEÆ7ÚÑ"K¤Ìñú/μMÓ8áO=ó¾�ïEh÷ÌÜn´Ðè #b_Ôý³g/»Tï©ZÔšþØtÜO§Óæn–'ÊhäØð*Ƀ‹qŠXXn9Ú§,.[ôë1Í‘s$`}ò2æÐ`7×ÞH=øU†[ªÝTé,{2‘8D{`·&T±}ŒF* Ã5¾2è#±Eû)ÂŽ=úÞ÷¾weeeyy9.cX FÙ(-1Â=ãͷȆ Á6ÍŒ–oF¥…"L˜·'‚›.™äÍ9ÇH\bÁÄ5džåd¬ °ÉÊíòýô{ø³[èDGO/qþf&.Öû"Lb�˜ùU»òb£U!$]Ù¯3[½™Zi‡.Šü“§hw;Ú%ɾq«Ù³N\<þL‘dPÁÞ6 6ØçÆžV>¥šÜÝ‘Ê4£œ5%}·ñdN£ÝL¼ý³gñtx{¼ñ-¢(ªº*Ër<gÒ°´"]î �åJ†c`×Zå“Úº‘ AH3†ã5çQŽfŠÈ-„¥ìJ¸6óÊ@Þ£_Å@eüÙ¬ÈLà,Æû„É "Z5ˆT’»¹]ÏaÇ©4›ÍªU£ŸµŸÕ>}üôòòrÐ.꺾fظµQ¬R¹ gF£f³‰Ó3Z™Æ¬Ü pÏœßËa’«ƒ/..ò =´ŠÂst'ŸÚzÔdÌ ÓÞØ=¯çæGÆ^ñ bÖG±µ§"sGÆg‹ˆKeì9¦†Í±¬2¨oˆl ¢>yR, “* Bf©öå̾¦3$¸£ÙƉƒ¾Ýn£†gX8cÙã_\aÚ<Si2jWó~vNV¨ŠœÿÉ#ýÎúd‡Æbc/³‹“¼_ãÉUöCÎ^¾¦h4ƒÁÀL!O#Æ2ŠÞIˆ_Å©Ál&G'[%›AƒýL3ƽ×x,ÜýBvåñ2äå{1qMBmÜ3C?Šá¤´"RÆQ°Ïco£…mgúÑxH[ÎÎ…³ÜŸ;Àm,Ÿ,'ƒÉüÙóIš¤ãi6›Mf“ò›ËÙ¥³ò¾r²:á�⧃«1·:íTîaœ%~…MÏÈL-¢{üd´ ÒŒ|"sgÉ*Ë$ˆ�‚z½Þúú:ô-§/Ù`M’¨Œ{¶¥/hÏ(¦iZêùC›§*0&\Á@Jƒw&TÞúÚæ™rÁCcTãøë÷û†m Ø W·ÛeÚ&óÛ¥(±`€5½mg#ÝÌÐF£’‹6#ÀVt›M„‡ý2¨N¢˜`dÒ„ókòf" NáMxwĽ`“‰‹;2Ywa ë;ð]öCÎ3¤ãY:À„R¸˜&eÞB¤vÍ$§�Flâ40É•ð5@Ô<pËE¤ ˆ#*eþ Yq³u0^Èõü}A¢Ø¢ø6¢µCóè?îO¦ûb;&iK³ó¯:ýÿ»?¾~<¹{RÏëÉ|R|WQ}¢jÞÒ¬‹š/’é#�@M¶kÁPÓ@’»íÃhã2wŒ<‡CàƒÁ€°çzNнËãÐÄv/R¯×s౟ô&æùw'õ3ëtmJ)MÏMÓí©üR9ýÚtwDßmÕãy ؘVs±D&‘PÔÐÝ�)‚ˆA�Š¥ìñ£xˆÔLæØnw²ÂÈ“4 üFï š{ÎÒÃãIHBá`®c™ R·yLˆ°Ñ-i(_¶‚}¬F_!ë Ûv÷)ÀpEpWWÒû½œ½'ISâøÔsåkõ‹ÌGÙÒÑáò”!N¸Ó;cbe˜ð³›S�,“ÉeYž1=k@qvðíŒxv}aa×ù†Fv¢ÄK7WùÖìwe§¹m¨É �ôí_iÏ/šO¿wÚn·”¦?=å®öû} ?Òµið#ƒ”R¹Z–ÿ¶ÌˆÑñŃ27éOÀœÂ fg¡g ŽzàÀë®»®Ûí~ñ‹_<}ú´ã“3ç³¼Ù\fHÃÀ&?6§Ÿš–ó²wïÈï©ëút}zø½ÃùëæÓ·Mã&�� �IDAT;§;ä.ž8á&xÉYÿ‘\žß‚‰gMn+Q2eÉ;À'Æ)Τp@<»¿p Ô1F³É¥ Mï¶»¶Ë;7‚AÌðC'ó¹É¤çˆsnÔ±Ù-,Bâèa^ëÑÊÂH²ddlÃòÛDb in‹'š½Å\ƒî–×sJ·ßËÙˈ ¸9µÃá0LeHU ðPíÈq`sxE2Ãi Â^¯×›L& Iü—!›Ýà>+’³NŽGˆÈÝ�²²aÃ@l²ç-i~Óª£œÂžÖæt “`¢?€^ƒ‰pž®-Š¢<S–o.U£êTÓ4u+!BïÆ;7Ò¹ÔzG«,ËIo²ö±µö;Ûíßk·- ³Ù ÇœsU”̧jµZxá _XUÕÝwßÍŠ2Ž”åìŒÍ’ó†¹ä¦õŒgß?KEª>SõþmÏÀ¯ÇÉk&¾÷ÀEç_ô¼<¯(Š[o½õÉ7=9ú¯£taê¬îµAÚg÷MF6 €X&âé#Zs¢!Æ Ö_‡ü†€ª4ù°í¡õ… 5ìðLýlÅ0hòE‡JÑò6â-¸Æ'¼ÙM£i6â´áb÷ö̳>\”¿Þ2ž¼½Œ'B0¶ÑµIöfߤ-¡X°‡ý³—ô�4eÆtãx¢Õá>!.˜›ès¾ïÜĉ³˜Îª›ÞLK° ²çPˆýU6;'­ñEy•9»°™½â:£žÃ©:ŸÝ ³~@ÜgknrÖ£ $Á?î$^–®;C} ÂÆÚo¯u~©3ûÚ¬Le£Ñ¨§uûóíñχß5l~¢icó‹\Ènú[##ÀD_ï Ía<///ÿáþaY–O<ñD|>h2êš_¨:Æ"¾x8úw£Þ;z×vêºü•ÁÊ'VZÿµÕ|³ÙØ|ôq(oüÊÆy¿~ÞϼâußÿºW¾ò•óùümo{Û>ðµ¹öäžl¼º¹�ÁŒ3âÜCšqúCá3‰.c–‡­\¨Ò‘rAÇÚ='Ë`ÚǵqŽÕjµ¢Užén…ñË pg=Z\‚¬Í‘)_ØŒƒåN?<P÷xì^f² ÈÏÄ‚ §åû¬ ŽçHÞÖét˜£b¤Ô×M><±0b®A©=t¡Þ9;Pø$ENŒÇã1±Ç:çîŽ6Fª•9Ër ‹ž!H:ç‚íG u(иÁ Ù·¢†‰Ñ±Fc»ÚS�0ÄVŒ&/�^{.=Î ÜÚoêØÀÁáñº¾F-²> Ð% ÈxNxëº^3lk¤•TÌŠ¢ÚR˜å]åìÚYý¹º˜™€·[hœ˜½J>A;:n2Ögä§OŸŽ/©�G' ,;^Q5S|ôk£ƒ×,ËrVÏRJÍO4«WëX¯>^–GSêºNTOêÇ_~ùå‡j4—_~ùÂÂÂêêj]ÖA¦Š›Ã‘dqÓ—y…ÜN¬U`ÞTÅq›™ÂuLotÏ<Ø› 6u%"ýpw>¨MÙ/Ö}ȼ_Í$¤G⺓¢¤Êx€Ç<¡³g³™0kÚš¡fšBžFÔ‘n ÚŒpÚ …S…TÀúİÌì.픕ڧìq/'Óow#í4@ô!è±Ü;¢=`z[Û²þø¯Y¡ö°ñegtd‡>pàÀòòòÊÊJ†ðóÌÆ1‡Îf¶çHÝ}a ¥-IJNÕLŸÊ< ؽ>È2 Ù÷Ê©´ëB.ž#€êÛ8ºqÔù³N¹Rö{W]uUQ=ôÐh4j|¨1üÃaó÷›³33 Â?/¸ò­-EC)I°1óÛ–HlxòPrX瘮™@b§?>mývËS_›2—ojO~bRýêve'þx2~üñÇ?ÿùχbÍŸüÉŸ<ñÄÃáp^Ï]Äóém ÜŸõ“U6îX¤3ª8χ$I[q›®ÿ{ÑEÕu}úôiÎz$“=äî—›—Œ'ÍÆ’¥²˜NPÈ„ˆRö!а&ƒaÇ"Sl+Có†äpY¬uç5s÷à•(¤ . 2N‹­‘˜fÆqFàû²Yºý³7!À¥s–‘G‹£ÜŽõó"X­/©Jh9û NRp¦Õqãì‘ãóÏ?ÿâ‹/ L8#‰~m·¨(GüM-š${Ì;p$Y˜Ž€,yóp¢-±íYà‘xn  8K¶PtÜ 6Ý<ëâ /üîïþîn·ûÖ·¾õøñãF£H¹©I¥PŒÒ–‘ ÏP”5à6¤,ÎG|º–̨SÝb™jH¶Ñh o¶¢iA|Ùæ7×~½ó:ÆúÛÿ½=üÃS?qêcûØý÷ß?xà~¿?þ¿ÆÍÿØtÛ†pŽ÷š"]"0HØëõRJ«««ƒÁ€æJäï$7žP)JrLw>N€’+ÄO=Ÿ9þY ΋¹3Á×x€ñšÝJÉ(HÙr††e%<è#šÙ?-¶§rh¬ªæ8`.HÌÿ¹õYÝ`0°ª +ÐÝ)“n8œ¼Rëd ½‰}úÀ¿Lù'Ms®—v*[€;ÅŽÙS¤`ÞÜ/Sd7n)ïÖ=¤cßh4žxâ‰hd\IkâÆÚ¦ 'ü½E*MdðL‰‘ÆøšL¶«à€Z!«Þ¬ÿ³Ö¾“ÌZ‚õYž$>ÝmäÙ=Ó\jŽÇeU>ùä“7ß|s]×ËËËUUÕ×Å“E=©Ë¢ôÔ!tpÓš;ã‡ArP¤Ž»+�ÆaërÿŽNÉîÙú|©Hͪ�×ÓŸþô'Ÿ|ÊuªwäIEQ”ÇË4LÃç-[¿w}<ŠAý­õü‚yãCõõõ�uD&V,Þ3¦Ad¸úê«/¸à‚Ï~ö³kkk£Ñ(Ö4ÌP— @ºšÅ~(ûâVÓð[__ɉ••>ŽËfŒÂ¤¬RËG¶­=J&7 '´ÑN³Ùìv»Ô=”Ú»á  `uÚòö+S¼ŽßoÔï÷CÅ•@žÙ,TãÀÀ¹¯éÆ3}ÇHLÞ±ÃaœBq1ûk! è¯ÄBÉÙØ &”ƒÈA†þA2#÷{¼QÝÅÉ&0Ü7Šß P\ø.q:ÄRHlfAlH¾ €c<£Üøñ@†Ã2õ6üté”fâÿŸvÁäŽOHÌó@xë]­Ñσ¯î¿ÿ~®jüÃãÖû[õR]—uÆKŽ?D‰f>V<›Þó¿.®Yþ€˜Ë²nª&•Dçfzôú½jmm _œ²,篘7oišXŸØû©ÞÆØ­VN®¤:ªÑô¹ÓÖ»[‡óbN –è£#)[]ñ€yä‘ãÇGÞm`-ë…À¡7¡‘š,öWJ)ÔW­ù´›([ƒ¤Þc.ðIJ�ƒÙùîØ;´XÎ4ã«Î'B`†Oþ‰L1ó¼à¿Ì¨y…6÷'ÑA|…Eb»Ï¢ Á…A°&Œýy¢ˆû!gª(dð&£'loàápHþ•1_ãðr@ò�k@~�ˆÜ£Îni¤]iÖ¥Žó…h¦ßåÒa·œìÈéê;¥Š–õ¢3›6_Ë,r:„UÝÏôáÁjÖ¤òs×4cstÞÞþô0}5UoªšÍf:”F¿<*NÕUQm³Œ  2äµ›œä�’[Ð󌆙‰AÚœÚÝ“}vŶ‘Oª÷[½å[–»ïèfÌ×ÑOz?سtÏ®õZå7•ãïEQž(;ÿ½Óh4êb›]–µjü(-µbÛ˜ wCó,K\YT™-¬ÂP'�€‡ócÁG†žvù¡ùò ƒÅ#µrd²GfIâÀli®‡¿´Ã7¿èQV¢ çjM 7æìû`—“¨NHhÏB4ˆ§O[`Ùƒ_äad?œB{uöCÎvíl r”A ¸È>²nØîÓ#ÐÌÌdiˆ"V1íÄÜ3Ü݆ʉh¿M6M&ö±‘"_*#4[2>{Å`wÞÌÜ”K;%°B}`ÚRôb«¢•p®¤+îú¯ùÉfu¦š<Òÿ\TŒŠ•¢óËt"¥3©l”v…N–¹sø"NlQ¯´SÓ!=³$C­P·c°‰·5íuѺ®[ÿO«ÿ™~ç·;í?hÇãÑKGÓ5mÿf{¾:¯I:¥XJ©ùxsþŽ-ü$Mý\âz Hdl% {öpËü/Lø6ìœvÚñ‘{ÑðclÖ~k* aè8îgV’ìs;µ• ÏØB5(j“É¥¢ÚÔ»¥í2¥dIü+ÛhM¡9 Râf²Ièm ¨kî'ØlOOÅ ÄEÄL®×ó=û!g_$ž°�ø{Ò·H² é0¨/°¼âw±•uýüz:%p+mwˆª£G£íUCdŠ£„xCÒÍqà;LÓX ñuˆ[èadò𱑬+E–·Ûë±ðÌSp c A ü”]@tJ,¨ãþ“gÈË{ÊêîêÐïBä‘¡ÑGkˆw¶h´›L^]Äé'Î}DB ë[$Ÿ¦vàÑóCl‘àa½ñ™F÷¥Ýùÿ9?{ÓÙ”Rã“ÎK;ñ)àlœk¶f"ÍȈÅgÆËd0Vl(8<¥‚rÜ¥PÉcF¿ °ôñ®ƒ±¶þî‹Ï¢ÅH—ÞÔ›L¦6Öa¿ß‡*íuîö!ã,Ñ@‚aèÑ…¸“½^¯ÝnÇ{Z&" i FïkÔ:`µGq¯”s&“­ãÏÏ£ÎæÚ ŒFd"Ëj‹øh Í~ÈÙ{Æ ˆì¢ÄmF+|ÏšÁXCj·›@=Ô™4$fPH2.µW'Ã:LDï!ká¢vœqÀ<´Ìª%[‡€˜•íÿ'Õ™lL~�ìÐRâw6íCßÝâ“eÐüÔ J�ãxê>Ó\°WY¼à]Zâ!ä2mÊÇÚˆQ\ 3=œ ‘8eÞîû­Vól~Ù²*]™·b3iÛ-[—Öj(D8À"®9¾EÆäŽ)3;m9:¢¨•WH½I´]=$¹¨YЖ�i?= ³øjA¨Ë´<h:Ò´wGÇ*¢Øf‰@•¢„h ÐçmèÂüXº`¶l‡´SÝÀ bäX´¬@Mþ¤[FEåÈ‹Ü.Y&­ì‡œ½|Yò9]Ë`ðó±è.4㶪ªáphæ˜Å*ØKdfâ²,âðEÄç©©Ì™5“¥ÆŒY›Éo6›Ñ‹BO F‘ÆE%—‘´Ëy,s ¾P’\˜ÁC=Öt±‚ª‡xÜ öY“vzße_¤q’pçy @Þ‹KvŸ5Ƹ9Î1Ó–FµGC2N6æÙlÆqïÆ~fáEòÁaçEæaŽ>ð‹ÞÊ*ܽÌGÞ~Õ𢕩’IFVÊ`Ô‘±ÉÂKiÖ~6zÌ´ J<ÎŒºÒ¥¤ˆí3³¨É×1<QŠÃÝzfi\9rä9ÏyΩS§Ž?Î5»”4©!i*<í”44BÀûÇㆠkÒ¹YÖi\’´A\p¤€{xöCÎvNDö„„L’ð9, íÔïžã£±xÌn@ÜæêÖê`ñŽ™=žfGz²l’ ÀiàSò¦­AzzÅL€bŸ¸Àe#Ö;)b,W•äâ' 0®‡éF…‰À¦Bö°2b'Ã@ùÊ”'þãu0tiÝ!ÖÇ4òzpù(ŰüÉŠ hЀ<­V«Ýn///SÚ¦-gë»@j@J<�Ï:ɯÅxfÒÐ%ýsðLÏ<9MÆ…Ö’à`q7øvNâ\¦ë@ïšóŽ"À0ž¯©ŒìÝ>„ñ¢âáe€ÞK(~ ±‹©tiªCÝö4åf¹P•E]4ªF1/Êb»épM²…Ä;ýÊ+¯|õ«_}ûí·/--ÅæuaO¹1%Ž ya¶à-îw&¦�ð­ËÉÁ¹â7 º? º÷ÀšqpCgt)B£0svìd…iÏ�ô“DBñ^…&†Ï8ß=Íçf6I@µÎyG;²Y»Ý^YY1àFÒ”ñÇhÿÄ)c4¦Ùlöz½À©‘T‰³ß ô<~ƾ BNDz¸äs¹«‘fF|ED.3õîÏä ИÊt-‰‹®*ˆYw$>%$Å2òQ0CáC!âú믿òÊ+o»í¶/|á «««f@`‡a½JF�F­X!É4zv<3¬¡=›QÏõý‹q·mv‰›;UîöÅW -Õ0ërÃRC$0óR3Ñ‹ŽqÜ÷ñ¼ÁÊ;ÈiS�ή0Š ŠÙ³µ[›>sšŠÔùP§úb5ûâ ìÁãJ Þ!÷wþ‘GyÇ;Þqúôéõõõ`¬!bäR‰T̆7÷”Ç‘fTà æÔ!Ìj xæ·röæÀa–•q[ÝàÍ\Ç=ÎíܶGÚ)ÿìÙ.{ÚÆ†Ï­ê!KК%ÉúfÚæÙwI[Â…nÑÇÑŸ9œfÓþ¶mG2r&"ÝÏ¿ž¸$'aƒ†KµD’È!…ùªÃÔ¶‡`~º»ÔÀ“ŒÖ÷´-)ÚÀ½òw1‘1˜Ë²¼è¢‹n¸á†«®ºªÙl>üðÄ丷!¦Â×Ìâ–ÍÍ|Ôº]A?Š!›ôXÆÍr´¾Ûô~˜h޾fôÛ8Ô’ä* ¢f͘x:¶ÔÄ.Óé ÈÆÖÈš`ñ¹ �¸ÇƱK™›¡©Ì;ÇØ£k\û'mÏ6®'?8™\0iÿJ»óµNQ“×Núÿ[¿ñôFãýŒlMÇËÇB]×+++îAº>sÿ‰ûÀBŠœÌ³ 6Û6)&IdH ³ü²ù*û‰�æg–Eû!go^¡‰Ûï÷ɸ#Að¸¯{dvpo2ár¢Ùl6dëL¨XÓÉÇ [â&‰°¾ E„�1c!zÜ �'dn© ÉÐ}qÃa)¶ä(¢H@ä!Ž2©�Ø>+MœÃ=ÈMf¶7ô°´ÓÖ,;À·÷½‡Éò²´Ñp<C+èx*‚YB£­YÀñ·ÅâJ&“ÉÙ³gï¾û¥»ï¾»ßïï¶íŒŠU•4q޶œùñv…³Ê8†›<ÐêÀ‰’ffªOÙü‹¤ûìå’Ñ=snBtS¼Â¡üºpÜH.åÔÄ(ãmg]—t¦Yz¢+¥T<½˜<kÒùñNY–ª1›ÍÊ÷”Ý÷v7>½Ñz_‹1SóîÜ þ† õ\ìŽ�9¬ñC ³ì©JPG>Ô&¶™³Aȃ}lœ?O e?ä|ƒ^£ÑhyyÙ}þL¶±çïœbWq³Î¼‹R¯½²iÞœ•DdüLâ"ëpýý^Þ–î*»®çË‚ÃDP$¬:ïŽpRo¡üI(Í!¶œ‘ÜÝÓ–F uO’°ýíž1ÒiøFÔv¸ Ç)I±ÙwÝn7È È© <„nÕlë‰0“('Ožüð‡?Üh4N:µ¶¶fgS3Àš|{M¬à»0ÙCíåºÇXbœq,fK(eƒ8ik<6n~p¸:ãë $Ïp·¥!×L·Ÿ¤>3VçE›ï9Q‡ÕnPÑÝr‹Œí¦ÕdÖ�Ù�,õÓ|>þ³aï{U«êv»­Vkuu5îIûWÛã_·~µwÒAÅ×àÍ’™8¡2‘†Óu?ÓE±YÌ\÷½2g‡´Õ„Ï{™n }#;ö«œ½|M&“yg8éN*¶”�ЙóqŸÈøûú/“üwc‰€{&9–¸ j84ã\&c‰[œƒ!Þ–©ÃˆÑ2¡Y•$ƒh]W§i¦dnÙœæVaM—±›s û›¢f5"9f€{@ŽÌ´ÛÍ—0`•hB>„×øtæ(-=BŽ7$Yv’K:rü‡z¨Óédäc3ì9³/O“3ŽÅ‰Kf6âÇtª—(¸¢{*qþÒí‹¿¯ª*JØ`º{ø€4R1“Å™½ëûÿÚ»Öà*«s½B !\.á°@ÀA‘óETˆd„9ØŽÆŽG´ÎX¡Lˤrñ=§ÜSh9ƒ1ƒt°`£I)Òp 5Ür‚\¤!†„ììì½³/ßùñž¬ÍÁv ìÖóà Û}ùÖ÷­µÞw½ïó>¯,t ÁþˆÍ;,˜’” \xdÔeò«ëš‡(=æ¿–,Á›[úúúìsv§ÄNÏ=÷\ÇŽ·nÝZ]]l‡­þ½Eý2f;4sÙ=ų  H¦¤¤ƒA‡Ã!g\ÖÓã0·xçgÄ6‘ð“3(¾±kn©…cÎÇ8'i ŒÉ‰�“‡ß‡uÎ"žñL#â(£•)p0Z“õE[ YÈ‘r%˜rš&ûÚLÅa!Pƒ´Ò ±a’UÔ4H ÜsÏSéqí/‰ê0™#$ؤ8/ Ê’tÜÀ»…2÷—åS¹wKÀq¬†k•ë@3ù8ä/ùHçóùü~¿ÛíFNÆ€³t€pe»l ÜŒG¾_%ül”p›gI\a’°Ó H] E¬Zy b€R}Ò¾}{è÷`ÒÒr{™A'g5nœ v"o—x¾ŠºÎ„k;…Èý ðshRwC:{âÙáRÎn"Ò(ÓXÓ´†‹ ýýä‰ÃÇ’ÖÖÖÖ××{<žÿK³«(´üaìsèCÃ$°Ä¢\p\\\ïÞ½ÁÖ‘À)瀑ÒGZËAøèˆ”BW,+ëšC_G+ÒBvVFarÓ¢­µ�^�çðYî „‡9O. ÄÍ*àörˆŒcúHØ¢2@~‚Uñ9˜Æ=q9±%)ê{ÍY\:‡×K³®Eó°¤Á¬“»kã†Øú™—,ÿ‡Mò@TäFmœ,Q=fÙ!‰ù ÎŽ%’a½ä§ µ'€ç«éùãüÊÑQ.)E¡ S¼Ð³v‘+ƹ›Žœ2ápƒ>¶CÌàÐÔl\1‹„B†2LT !ž‰h'¦7ïJx|œ*‡Gº`§y†kna˜¥ã­´û”cºÙ"¾ÇY 8]±"I“ÀátÅG(ØE!OÃðÛ¶»>Öóš'¸>¸ÿþ¨¨(·Û-àû‰/îã8> "ի牸ܙT§¸¸|^\šÜ;|mšÁÄrîZ¤õ Ó ¡p‚g“-ïvEŠ13ÚÆ­Ò ¶ä-÷—àsö‘ßC_ˆ"X‡ÜKFV $2ù ÂÉmæÚk2´–â¶öœRÂ)ŠƒÝˆ"Á¹YäpÈÈxÖ²Ø ì“l[^¯Æ¦b!¤þý¸»c×3Lؾ¹ˆ@ˆâü|j”¶hAù*µX–øÂ’|’"^ŸDêX#}@—ˆ‰aÈU0ƒ™+í!G/;2 ñ¦’£:Rœz¤˜)õ=šò)vaa Ë —ù©=ÍŽ;J* ÜbpAüƒ6g8¸J_vœxä~â&÷íÛ·gÏžŠúâ`‡.ŸÜd„Ú`€Ùy‚0Êì5!pD¸‹ R̘Шê \n—$rìXÛŽ³íÇìèâäx–]g/VÛ#!È!rïÒñï¹€ † „Oö 72¹ÍøÂ8á‡ç…¥*Κœi3§œˆ1Ö•Æ^€d ¢·°xZ°+¼ Û^Â)}ÞÅÄIÜ´¦èFÅ*ô,ÒÌÚˆª¥4KxûQ™²qqqhƒPzxš‘F®‚sÝØ¹ŸŠ‹‹1|®Þ‡¶Ì�Ò*l$˜ÂÎ2‘ªeƒ&tqÖuòX ›EEE ±ts$rø–rwE˜Nü¶k×.>>>66Öãñ ’&£FPŶíN:Añˆë·ØÀ œEk“ª ³¢?ºö%áK˜-Á`ÐëõbBÂqæi‰(+÷™ÖްÜb€éaâšHØJ+N¥ÜL¶¹¹YZÁãÓ²w’€ÄIvj(¶±ø¿F’†ë )Ï¢¼ôF7ÏSv‡ÜM¹MÑk££ÎE)¥‚“‚¡ÇC&v†‚šÔ/šÂ±öÔÓqÀåc ’üâ¤Ê…‰ÂüZ:µ@ 7]ÅÉTà¢B–ÕÁU˜œ67 3µÈtZœþ®KI²Æ§g@©b¶.âûÜ)DQK®8‘ï‘%EŽjfµb&IL�{¨69%À]Ÿá‚)j/ˆÒWÛ±#³üt˜:dÑùÂøȹt®ø ï]Õ,®3—;€ü3Ë„@‘ýiÀÃæ;Ƨ:ÖpD,u ì°À{4Öòä'°ÅpÿBvïÞ]Bð¬ÛÈÞ­0 X ®IÒZrð§.pYV^ÄÙ‘wdˆS ‚‡!hÆX‘l>닳�WGáL†“.By˜ëXWW¿¡NèÁ0›™98î ¸•ûâ˜Î¤M¦êá,Ê\LLLÌž˜N»:yßôG•R1¹1,x@ëü„)g¿ÁCDìN¦r†ãÀ +aÂCZ O_£œqΓYž#ï?Èþ©EÁY„“ÆØ¨ë˜ Aª<w~'²/ØÙqà8Œ0HÅþë÷ûÅ Ö„ß¹°‡ØØØÔÔT§ÓYUU‰blXcØb A ÓÅ1X-²JQ ÃY"NA¡\Á=f…"³i�´>äì…VΤs¤Êp[4®9;\ ¨®wHË,�¬H~ ž&Ë^±@¯"ñS–—ç•cT.µSJYe ��[IDAT¹Ý&q„aq¹R‡ég¬%ƒèŸW˜Ú„ò,®¾„¨6—‹ÅÆÆvéÒENZ°@œ’ÄÇÏiš•ªe3žáG^Õ² ;¬yä?3ä4ê¿°¶2aµ1=±Ç#‹*JÐŒ€ýC„˹5N\vÜ [ucn@n€÷(²£ø—³€ª¥°&nÖ>ŽÈ| Çõ3)‰ÒÜ‹„B¤µ`µªîÁ#Ž19J;Ùp¼[ª|9|ß¾}{9³¦½Æ&ÂÉšPZº^A §/¼éæ+w •õ ½è¹ñ vÞþ¸2?ѱcG¹`öMˆ þ»H·IhˆÝF¢ÿðš5–N ˜î¨½à-ŒièŠTu‘F&Lî‚ÑL¦QJ( \àݪ*ؾ™jŒX?!ÇÄÄx<­',w¢„¨%N¶m»Ýnœ¥X JšÌ¤ÇÞ òª|˜@¤Ô&vRøÈJ©®]»&''_¸p¡¡¡<=ddkÖò:(\eEmÍœ`b€g!Óƒ–÷Öú»pý&‹—ã€Ë2áðÏ4íZÌ‚Ëæ,æ!‚—�X°.<?5Æ'ˆ‰ÇT0éÁd‚2WÎ1ž;ɲ¾ v<FðÆa‹‹â6Êí¹ŒÉ‰$8, ìÉð6É Źž þ¿&¯œ’S‘9=c6K\ro% ž={E—Šdùaœ¸× Ö¹kœN';n3”_d¢jƒ…àNPª¥Ü=<5ô½æ>(¬V‚°8“DÁïb4¢H#èÄ¢¥hÄ7V2½p9¿ÍÔjéxÄœù’øøxQ£`–¬”Üù §|¹¸ ½Ý@ R$M 5~æ7rÈQ,DxpFQ"ð58¦œNgSS“Øn4Àö€%j¸ª1r?2Xî„Æä4æ¾³\;2‡}>;7Ø(!ÇŽHxÿJ„Œd€™ÆMÿÂ{ß¡Ê –,y\¹Ïç“i ZJ÷²Mâ¾SZãNÐÙ5!ÎxA«YXö;eV#·Ï1myräV\’¸Òˆ‹¢¸!‡j¹¥19«ËÑü/ÎokJˆ\¢IwhUî\ÿˆ´vjF\û ¦öŠõ†ô‹°ê>÷õa©4èŒ!úÄ5 ˆð€k§¨´ NÜ:D µ‚®yÖús„·ÔÔêHþbûÎ*„æ<g0X1âêò›”"©nÍ·:¸\.­¢‡<Øo1Ã,WÊÑ-ö©åqpGvÀÎ;'&&ÖÕÕq 5ê¨öç'Øà8sMg58÷€*]­m <‡‹Ð°k~3O~žÉìÊà„"eêÊÅ Q*O“;w0ÅŸÛ<ãP ^'˜ÊtñNdVà8¥Ññ7”©¡ÔšAEe+˜{ˆãq *óáæð¸C7Sàž=Ì+ÁV#—-ìPÄÉ™XÄL­äþÆäDŒ;€] µ¨aFR—¹@ieýZ¤‚°í"³{Ã9á® ²Á„KhT#@!3åâàa1p‰�<6&t ‘(9sxçÅ÷h?Z‰¼0-Œ ËO”Õy©h[†|6\Œ‘6°ßâ "–®¢L�a+¢¨*PîÀUÔ-["'H/±0ê„Xí†u"Ø`£è…òX½^oBB‚æsà6¢TÌ1­,CµjcY3aµ¨–Byø,»íH_3Od_>»c˜ðwŸó4Hsr—qM½m˜ÍþY8A'<œþáH1ÿ…}ÄŸy~ÂösL•µÈ<ÇîÏLT6,jÇ̹Ԏ;ÆÇÇ»ÝnÐm´EGÉá/&ës{^GÜ;ºqBiEþþ*{“s£ˆ °ù i`d\™;ÀâóòU ;áÁs$Šû" ¹ÎJMìã4 %0õå RvÿšˆñÊT:íÄ�N'téÑTÕ0p»xøÈŽröõªbÿàèo#ÛG/Eì‹#“šÀ¯pØ$ç@¦]¡öO$쳃J u˜‡BÂ÷œ_aÛ#ÿK‹=¥T rx½ÞsçÎµÈ ­rÐAŠEó©5‹«¨]ljâ.æ6Ì îŒÏ烧Ŧº1¹@c#EèO)%eXœBló„‹£¹²{7n©FHw()Iíô€ÓX&IzÉá$+V+œ-tŸBfwÁGá"Å–0AyРAéééùùù•••¸l¡â†s©{<ØvÐ.s’Ó~è®$ÆMfq>“‹çà„19&­q¸†EòÃÖ-#ø,˜ÆÂ…˜aþÂ’ƒçޏ6"¶¬¢ˆôƒ¦ʧ.öƒà óŽÃˆ\ÛÌa@ÖIÃÅ À›õ{pC´V¤|\ƒj�WE åƒ"oèÏ&{(zmÁ~sû² /¨ªÏ›ŠUªIHz–Kky˜ÈÞ#QùKnêîHÎ@¶EÐ#qnà]7ØSänhúIp“™åÅV\Q+¨¬Ê·q¨‡V¸”ʲ*×M—ŒDÌ ™Ä ìg;@ åH ž‘ää"9&,Õcx²èé¦9¨–bwð`4m¦Àhe=,ªg`¹Ù³V��b=“ÚÇ_|qíÚ5&õ° \w€{ŽI‚]k»’³¸LunÜÀl&~pÆäD ƒ ÊÊÊR-ÛšqBË(pda ž|8â°æ¹–óP-‹×øTÎ)™ðøB&Û0W›·QÎúr26œ6ÆzV¼ÏÂïfî:Ã}—µNZK^·¸WÜ/Y+uÔÄ­µø—‘ó“Bæ€o[D˜–ʺڼªY7^33à¹u2ì  Û&^áx& <‹%CåˆûQ2C­>7§Ñ¸$`Q2m°iÄ=ÉŠåbYu‰˜ø«ßB€Ž«¬8‡ C«U1‡/=­&—s<ŠºWH(‰Ë“5B—…”8#«•$#¸Ç¥-|¯5ÕÕNuáuX,ü7L´öµ\ÉjF¸Ð0÷×♚bTTT×®]ɉ†º`Ás î(ŒÆšÁ]?娶½cÇsG n#Æ“ 'NœÈïÓšÁü#ÿëö¾­•\Æ-Þv7oEk¸ŒÛòtÚÆ¹õ5´†Ë¸kãNO³«Dd9߯ï7nÜMLÎM¿B«¾¾ÅUXiØíýàþ~saÿÊ÷·Ú S- Zç…™9l.¬m_X ™"sè30000¸;0&ÇÀÀÀÀÀ˜cr ŒÉ100000&ÇÀÀÀÀÀ˜s ŒÉ100000&ÇÀÀÀÀÀÀ˜cr ŒÉ1000000&ÇÀÀÀÀÀ˜ƒ7o^€öãhÖÍ=ÒÕ}ÖÙBE®y‰2Ý_îÊLP÷q/“;ñDîhóD"òDþ•yáÂ…719ÑÑÑùùù±{»wïv¹\?üáÛ†Ÿ9sæªU«ÚÆXÊÊʾúê«7Þx£Í8Ymé阅Ӛ±eË–Þ½{§§§›§Ã(†_}öÙg#2˜¦¦&§Ó©_¿íøÁ~ÐfÆ’`Ûv›N{:fá´fTVVöë×Ï<¥T0¼ah,ËÚ¿SSÓ_þò—©S§*ƒÛ‡`0èr¹òóóùË_ú€Á]‚19Æä´-Äܵ_r»Ýeee£GVJ¹\®mÛ¶)¥Æß³gO¥ÔáÇËËË»téòÜsÏÉû7oÞlÛ¶eY)))­ê–Õ××oß¾])5a„nݺ)¥JKK+**%½fÛöæÍ›•R£F0`€Rª¼¼üðáÃ111/¾øb+œÛ·o¯¯¯2dÈÈ‘#•R—/_Þ³gRjòäÉ:uRJíß¿ßápôêÕ+##C)åõzsss•Rééé}ûöm=Ù±c2œáyìØ±'NÄÇÇO™2EÞóÙgŸ577?úè£C‡UJUUU<xP)õâ‹/ÆÄÄDv,çÏŸohhHMM•=zô›o¾éÔ©ÓäÉ“å•?ýéO@`äÈ‘C† QJUVV)¥~üã AhÇŽuuu)))–eµ¶§#(--8p`bb¢Rª¸¸øÌ™3ݺu›0a‚R* ~úé§J©'žxâûßÿ¾RêÔ©Seee±±±/¼ðBÄÇrúô阘YÝJ©C‡={¶gÏžãÇWJùýþœœ¥ÔèÑ£ûõë§”:yòä×_za^^žÇã>|øÃ?ñá4778p@V·RªººúË/¿TJ=ÿüó:tPJýío«©©INN3fŒlæ[·nUJ7.))I)uäÈ‘¿ÿýï;wž4iÒ­+:>±O¿ÑÿqôLmãåªÇÿmÄÕܹswíÚ•™™©”úÍo~ãóù\.WAAAzzzYYÙ¶mÛ¼^ouuõ… † ¶jÕªºº:—ËU\\<xðàÎ;·ž}mÉ’%~¿ßåríÞ½{ܸqÅÅÅùùù^¯÷Â… —.]JMM]¹reCCƒËå:xð`jjê•+W>þøãææf§ÓyôèÑ´´´Veo6oÞ|êÔ)·Û}âĉ„„„îÝ»/]º4¸\®½{÷fddz<ž³gÏ666<xÙ²eMMM.—«°°Ð²¬öíÛG|¿ÿýï—/_ž••%¯hYQQ‘““ãóùjkk+**FŒ‘]SSÓØØxøðáäääP(´zõjy²‡zê©§"8œ ¬[·Îår ÅöèÑ£¹¹¹>ŸïâÅ‹UUU<òÈêÕ«kkk].Wii逼^ï‡~(_TTôä“Oæääœ8qÂívóÍ7qqqÉÉÉN^^ÞG}ôá‡þìg?ËEEEÓ¦MKOOïÓ§ÏÁƒwîÜéõzÇ•+W†ú»ßýÎårÉ"6lØ¥K—þð‡?477×ÕÕ?~<‚F4 Í;wíÚµ]ºt1b„Rª°°°  Àãñœ;wÎét>ôÐC+V¬hllt¹\ûöí1b„Ãáøãÿèóù®^½zêÔ©‘#G®_¿þܹsGŽIJJêÑ£GŸÎÆ×­[———÷ꫯ*¥ûÛßÊPXXøôÓOççç555}ûí·~¿àÀK—.õz½²EŒ=úرc[·nõz½/^t8Ç×~Âéöç–ÖìÞ±ýHQ¡ê5Äšõ…/+·~ÙêöÜ9sÖ®]›™™)ÿ´,Kþ;vlccãÆW®\iÛö±cÇ^ýuÛ¶Gå÷ûmÛž>}zII‰Ýš€‹ÿꫯB¡Pvvö|`ÛvIIÉôéÓù ¯¿þú±cÇöíÛ—••eÛvccãØ±cíV¹HÛ¶W®\¹qãF¾HÈ;ï¼³eËÛ¶óóóç͛ǜ2eÊ… ZÃ(ªªª ~øáðÇ$™——·páByç~ô#a~_½zÕ¶í·ß~{×®]ååå/¿ü²öÙHaÿþý‹-Z²d‰üóòåËUUU¶mã"eáØ¶••µoß>,\<Î|Ùáœ>}º  `äÈ‘üʬY³¦L™¢]ä¡C‡~þóŸó#˜:uêÉ“'÷îÝ;{ölÛ¶Nç3Ï<Á±„B¡‚‚‚¬¬¬õë×Ë+²plÛ¾víZEE_|ffæ™3g°p.]º4iÒ$^8¿þõ¯·mÛÙ§sâĉ¼¼¼gŸ}Vþ‰‹Ä@p‘Ÿ}ö™ÌI ð™gžq:›6mZ¾|¹mÛ'Ožœ:ujøOœw²rë_zggçžýÛ)¥¢cx ¾sT»è;dEkkkÏŸ?ÿØcµX¤ÏçËÎÎNKK«©©iÙ?þ¯~õ«´´´êêjD5ï9ôïß?##C‚�m�O=õÔ°aÃðÏ=zôïßßápÌŸ?ݺu÷ÜpRRR222Úµ»‘9®¨¨ˆïÝ»÷=7–¨¨¨ŒŒŒÁƒó‹ÕÕÕÏ?ÿüÌ™3%}o!55UÂe‚ÄÄÄÌÌÌ´´´´´´+VÜž›Ö.úøÎ]{ŠëxÇé‡ã½÷Þ›7o^×®]ÛÆvpùòe9Ó,^¼˜KœîQ,\¸pÉ’%%%%}úô‘•A+Ä‘#G–/_¾víÚ¸¸¸{},ùùùûöí[¼xq›y:yyy«W¯þéOúî»ïÞëc©««ûôÓOKJJJJJfÏž}Û¿ÿŽçHKKKwïÞÝÐÐÐÐÐPVV¶gÏɰݻèׯߴiÓÌ&hp×PVV¶uëÖ9sæ´cÜüùóŸx≷ÞzëàÁƒ ›6mº×G4cÆŒ>}úœ>}ÚÌÕÈ›œ§Ÿ~º{÷îJ©šššÊÊJa×üã8}út\\œpŸÚ�Ö¬YÓÐР”ª¬¬¼×Pƒ½†XswØswØË×lº£I*‡ÃñÖ[oÉßååå–eY–uàÀÛ¶ÀÒ¥K-ËÊÌÌôù|¶m{½ÞÇܲ¬O>ù$ ¶ª|»f,Ë*--µmÛï÷/Z´È²¬W^y¥¹¹Ù¶m·Û-oÈÉÉ ƒÁ`pÆ –e3Æëõ¶6ú€ÏçËÌÌ´,Kˆj¶m8p@®¿¼¼\8gÎ˲f̘!¬®®–7ìܹ3 µž±¼ôÒKø[»È@ °jÕ*˲&Mš„96~üx˲>úè£`0 …þüç?ËG®]»ñ±ìܹsÍš5ò÷_ÿú×G}T®MÑ^¯w̘1–emذAæXNN޼ÁívÛ¶ÝÜÜüÊ+¯X–µhÑ"aâ´ª§#X¸páñãÇeŽ-X°À²¬×^{MæXCCƒ '777 ƒÁõë×[–5vìØÖ°ˆ6mÚôùçŸËß~¿Þ¼y–e½ñÆrñW®\‘‹ß¶m›\üš5k,Ëš0a‚Ì=ŸÏ7qâD˲Þÿ}Yt‘…Óé|óÍ7Áسg\¿Ãá¹ô‹_ü²¬Y³fÉ\úöÛoå ………²¸–-[fYÖ /¼ Ôp¡Áž»Ãžöñ™ný‡Fõb½ú^‰R*©ò“ÙÓ^66ØÀÀÀÀà6¢Ú¥VRõ+sþs²Q00000¸K0&ÇÀÀÀÀÀ˜ƒ¶…Œ5O€Ãgê†%'˜›b````p[pü|ãU;ñ&&§¡û¨Ï‹¾˜ø ¹G·Ÿ9|ݾ§®÷¢¦ºœ¨¨¦ÉË·W}çWÄ79ÜgÌ­4000¸oa'?Y•Øìm¼õÛ<’£¯Û¥TTQQñôÿ^?aæûøž[> ¥÷õOz(ÚÜqƒûùg¢¿<×î;M†RQJ©¦úÚÿ3c㊷c’’zí—x±¼´sÒƒñ]zÈÿ¾ü^·óò%wrsÇ î[øý”jÿ&CìÍ•ÊãÃSú$%%E‰âô½»úø™šŒ7—}燃æäPÕЄkæŽÜ·8ßá‘3žïš=ßùνÙs‡ ì½øí©©©Q¶m+¥ªªª.^¼4ù¥Ÿü#¿Ô.è‹zÌ7000¸ѾK *Æ}·šþ¶-zõJzðÁ•Rÿ ÄÅ3x:ƒ����IEND®B`‚������������������������������������������./saods9/doc/user/catalogs/addlabels.png������������������������������������������������������������0000644�0001750�0001750�00000132604�11332127303�017045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��Ü���mMöó���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ!+G{†š�� �IDATxÚìÝyœ\uèýßïìçÔ¾ïÝÕtv² [DÄqEï£3ˆÎ3úèëÅ,^œË€÷:ÊKî•AQ7ÜÐÄ„=ÝI'½/UÝÕµïuªÎú{þ8UÕÕKB"¨¿Ï+/è®:ÕÕï_U÷·«êTDéº^*•öïßÏ=÷€‹HÕtYÕY†8‡{}$Öe‹À\ÒIt]WU•a.íTŠ¢A’äEnÿä“O^{íµ6› J×õƒþÍßü͵×^›N§—n !\tÈž“Ïšþà;n—1‡Ã½NúþíÛû½ }ÙßÛË‹ÅöíÛ÷Á~PÓ´‹?Õ¯~õ+¯×»uëV]¿¨óº÷Þ{?õ©O=ùä“W_}5U,?ðìÙ³B833/¢Z­–©(/O”ß0•À1ºŽ²�°Y„j­¡é:¡ÕÌ+"�€¥)Š"ku �`8YQeE�8­¦B¹†� HBàÙrµ�àY�P—d�€ÕÌ‹uIÕtcã|¹�`hŠ¡©ªØ��˜xVÕ4IV�v‹P®Öu„H‚0›¸RE�p MPlÈ��‹‰kHŠ¢j��§Í”/Õ��4Er,]©5CÌBUlhº!´›ùÂ!«©ø@(Ša.!Âj⊡†´b åÚÅ@H’0óli)ÄÄ‹¥’aè B ÕÄw@±!B’<Ç”kõK‡°²¢]Bë6DVµgÍP$ËЕyˆ.ÉÊEA®!/†P$),á«¢´BSduYHED]„¦HîR $AÔ^#CSL³²ºBfaaóZ}ÉZ]×@X†¦H¸2\ !Tï€(Òš‰ÅŒ_ÔA¼â/ójµ �¨Õj™Læ7nAI’��™LFÅ lÖîë_ÿ:Çq}}}GŽ¡8pÍ5×\ä÷gl (å2ÃýGßóÆÌ3+»|¹bu&UpÙwohòìTCRÂ>»#àîãª'ä–žJÚL\_ÔŸLd3…ª×a¬ A»NÎf>;-pôŠˆ·R“¦Y‡…wöcc³•Z#à¶ú¨Àpÿ0C“Ñ K§èáñY‹Àöuû2™Ò\¶ä¶›|+BãgÆUM‹ø·cøôÏR½a$kcñ´ÝÌÙ{³Ó©BYô9Í&<Ü?D“DwÐE ÜðpÜÌ3+Ú«àî N M‹ %â³;îáþ1–¡zBn€áɤÕÄ®ê$çr™BÅã0VDFNC�ºNÎf>;%pôа·"¶ =Áøøl¹Ö¸,¾hp¸˜¡ÈhÐ…zxlÖ"°}]¾L¶ ñö†ÆÇUU‹øVO òHª6KÛÍœ-˜-œ”‰oB"Þ|IŒ§ò-HLlÈa¯Ýô ÷²4ÙòÈOÎ-„GO��ºüNÞ>©Ö¥ÉÙ¿Ëâï9$WšË”Ü6“wEhbp\Yé yUmA±t¾\ó9ÍA&<Ü?D5!ÂðpÌÄ3+#Þ|YŒ'óΛ+ämAÜ2$Z*™Oç+»É¿r",qtBèe +»|Ù\)‘)¹m‚wExbpBQÕ°Ïaó:‡Æy†ê {U¥šx:_Z ¡ÍÂðÐ2éáX­.‡½6wD9d qX†§–îxju¹ ÌLÌ•ªõÑtC–±ÌÊ.6WNdŠMÈÙ YQ#-ÇP½a¨ê£±”ÍÌÙ¢¹x:WªyæàÊyÓ)”ÅX2ï´ ®$ä±¹Ãó• †'æ¬&¶o!dìô(B(âwÛðà¤ÊÄLfÄiñÓ¡áþ¡%_6WiAB“ƒ“ÒHCÓG¦/Â1+º¼ÅŠ›kC⪪7/.þ÷¹q[ä"ówžä|§Zö|EQ¤iúÚk¯=pà�õ¡}(™LÎÎÎ^¹ˆ�ÔñƘ7ÝAg¦X‹§J»9pž©IZÄëxìNM°4Ýpª:žNÛÌ|wÀ5=—OD¿Ó ºœ×ÑãwZÍÂѳqc»ÎrMšLä]VS4èO–jrÈcï8|”¦¨.¿“$©ÓãsVï:™r"[ñ:,Ñ ëð™é†ŠzN·ÃrèôÏ0]g]ÖÆâY‡EèºFbÙ\¹tÙ¢A׾㣠#'DZ'‡gÍ<×t抵Xªä¶™£Aש‘ÙjC‹xíA¯£ ñ;u M§mf>pM'ó©B­ é׌6³éèÙX"v@&“Åšòغ®&$à$)j`lÎ*pÝAW"79:8ÝPP4àt;¬‡NOq Óp6mÔ€\cñ&¤{âàyî„ 8s%1–*ºmæî&Dxí!Ÿsÿ©q–¦»€¡É”ÍÄGƒ®éd¡2¡"Øpج¦£gc»r¶²÷Ø(MR]EQcsëºær•ÙLÅë°D®£g§ë Šúgâ:!3Ùl¹pY£A÷ïB‚ì 8ž;1<cæÙî€3W®Ç’ÅŽK¤99Î4!Ѐt]±d1™oB^ê€9X¶+ਈòD"ï´š¢A×9â¶Eƒn 8(º q& ˆÝ =êwz]Ö—&[}4žqX„î€sl&›-5!ûNŒA‚ìò;ž;14câÙî€3_®O· ý£³•zòb ‚�<Û„8c©b2_ó9-Ñ û¥þIb·šŽ Æ–é :«ueb6ï´šºƒÎs“©BUZ¡iª4a¸®€){í–hÐyììt]Ö»; Ý-ˆÝ,DƒÎñ™lf Ä$pLJfLÜ"ˆs`t¶RWÃ^{Ø€P„8;Ñ„ÄÛ€ë¥IE=§Ãj:28ÝÉ9­¦î€shª qýþØÙ„ÐmH*_É”=MH\”õn¿ÓׄÐ]§¬ê#±¥—‰ø&oB‚ÎÂH¢RWÚ“à’æÍ¢ù1<SHëÀøEßü´ Ìk‚TÏÎQ$±s}Èø4Y‡ãùÞ ½ÇoooÿÄO¸\.ªó”sùÚÉñ̪°sMÄÙùå~s|JÕÐW÷µiŸïöšy†”}8Q*T%„.êw½ÛÊ­ ÛNOJ¢¼ìVÙu Í”²å�€$`À)¬ ZcgrâTª"«ºñé5ë|©B½ÒP¢^ËÙxARt†"겪j¯ðÝ0,“¯HñtÙk7ùÝÖs±lYT¢>»Ën~éLœ¦¨î€]ÕÁH<k3ña¯u6WMåÅ ËâsZNŒÎ5TÔr <wl8Á³L—ÏVi(SsE—Uxlc³…BUêòÚ<ËKgâ £$ÈÓi‹À…}¶tQLd«~‡Ùï¶žžH×$­7à°Z„ÃggYšîòÛŠ>>›wXø Ç6*eKõ°ÛêuZŽœ›Uì 9†>5š4qlÄg+T¤xºì±›·Ã|ðt¢!0[� ¸,>§åäè\CA+CNÓòëX¢P¨4!‡Úr1Äç0ûÝÖ3骤õúív‹éðÙ–¦»AÒ¥l©r[½NËÑ¡yÈÉ6¤&ÅSMÈp,[•nŸÝã0<kB�™ÊÚL\ÈkKäªÉ|-à´ø\-HÐi¸cC žeºü¶JCmCÆ…|EŠxl^§¹ Ú!I L¤-<ñÙ2¥úl¦âs˜ý.ë™Étµ¡õøív«éåyŸÍ;Ì|Ðc‹¥Ë™b=ä¶ú@˜6¤X“c©’Çf x¬Ãñ\ITº}6ÃrðtŒ&©¨ß®b¸™[�IÖ ˆ‰;6”à¦Ëo«5´É¹‚Ë*B^Œ‚Œí$I Œ§-<öÙ2¥Æ2›éåÁ&DÒÐØLRé„ÈXv²-H×RHMéöÙÜvËÁ31ª9׆äkÉ\-à´ø]–S£Éº¢¯ :Ì&þèP‚[™Hó)â±z–CK!^[¶Ü™Ê‡Íüòà ³òÚb™yȱ6„eNŒ$މøí !ù6ä¥31’¤¢’±.ô§ê²¾bDÒ&MÈä\1W–"«Çi948ƒ²§ I™;!vsÀmœÊTª9Ô‚È›ÉÛÍ|Èk‹g*éb=ä²ø\ÖcC‰È\"*±dÉm3ÜÖ‘x¾X“»½¶S¸øyclÙ9ÎÆòßüå™á™Â¢ß“^»ðÉwn¿fCxÙAµ§æ‘çN²4©jè†Í]©‚ø^üÍñ©«×‡îû«Í½;„PUUcw¢}ÊdAüß¿=÷¿~Úÿí_ž)´¿‰çO|õ¹ãüèØ÷·'PÇ1W¯ó_Ýg±•Ki¤$©¡âbþÝ–;¯êb¥ÌùNâ´òw]³ÂªeõšHR«ÂŽ;.­qª˜¥ÊÓrFÕtcã»®Y±Ö ©è7ëR.v²;×úÌ,©êàÂßFªØ˜JW\6Ám7M$Ë…šÒí³™îøh 䊠]ÖÀ¹xÁ,pA·%Y¨'ò¢ßi¶[„sñBMÒW„ì4MŸKÓ4Ýí³UÚø\Ùaå}Ns,]ÉV¤°×j1q§ÆÓ*‚}a‡à™éœÀ³a%[nij5Ãä´™Fg‹åºÚ° {|$EPTOÀ.*úÈlÑjæüNËl®–*6‚n‹ÍŸžÊÕUÔr@‚ìŸÈ²,Óå³jŠñ,„YaÛŸÓì°çâ…ª¤¯Ú™%»…÷9ͱL5[nC2ŠÞ‚Låø&D2 .›it¶Xª«=ÏsÇF›z$‘oBìþÌT®® •!$BRó|MéòYÍ‹ 1bM•ê³ÄÚaècijRjC2e)ì±ZÍÜ©ñ¬Ü„g¦r<Ç„½–lYŠeª»Ée3&šÁ€ !.K"_Kë…‚$û'2¤XS&S§Mð8L“Ér¾*wù¬f?>š¹"dWtp6–7 lÐmM—mÈP¼P•´A;ÃÒ'FÓMwûm•†6¶b±š¹SYY«Â§›k®"/‚Dý6çŽÌC†gŠV“ç!Ó¹º‚ú‚¤NMd–îòY‹âòciÉ•K!¹¥öøhš¢é¨ßV•æ!ñL5S–B‹ÕÌ÷Od% ô-‚TåX¦ênCÄÞÄÒ†ê—Ù€ˆmÈx†aènŸ­d@¬Ë@t°�Z™)TZoÐÎ-‚$ÚZº0 !äé©Ç1¯5߆ØMcs¥b r|$Iª7`o¨MHÀe™Ë‹sÄ* ÐH²ì´ ^‡i2]ÎUåˆ×j6ñÆ,¸¤y³è^²ýgf—Î�@º(þhþ÷ÿâ;Öž|ᬪ鵆òµŸzzϹ'~sæ7ǧ��/ ÎL¤Ûÿ „��TûÄsùÚ‹§g�ý™oýòôGoß´&âúÉKcOüæŒ(©�€ïî9û×ׯ3ng!�tD˜8¶Ëc©æçö•$8—Ì\½ãJ›ÃõÛdÈÉoì¶Ÿ)¹-¬ÏÎ#„ „³91èìLë’Xé&¶»3"˜*ÚLôe]v›@ç*ò‰‰<� 47&©’³éˆ@€Èæ ¿|ñØÈl©¡ ¸·¯rö…™Rƒ"a½”–*9†œ&ò-[B=GÐɽx.'«hMØfbÉd±qt4ç03×®ófÊ †"Žå³eÉcc]Vn:#«J¯ßLÓÔ`¬¨èpc·µÚ@ÉŠ…gBnSª(¥Š S°˜ØñdµZ×V‡¬�SФVÌEQejN çµññl=_‘£^3ÏÐçfÊ’6tÛë K”LÝå1gÊÊ\¾î·ó37™ª–Eµ/`!Ij`º� ¹:d)×µ©TÕnbNa®ÐÈ”¤ˆÛd☑ي(éë"6U'†ãEŽ¡{|æ\U™ÍŠç²òMˆo²©ÛZé„”¤T¡t ÖN\â³ó3Ùz®"w{Í<CÍ” ÚÐÕ„,ÝÝ„ˆ¾%ÓÓ. ¢!âìT‘c¨Ÿ9_Uf²¢Çʹ¬|,#ªJ¯ÏÌÐôÙXQÑàÆèü%¾¤H‘Tß"H®ž+ËÝ3϶!¶†F ˆ×œ-+ bá¦ÒµRM]Ù 7!¶HØm2sÌH¢"JúÚpÂ6!êL¶æ¶rîExQVÁƨ­Ö@ãÉŠ…g"MH=èl‹ “EФú‚æbMejN3ë³ -ˆ‰g™¡™rC¾(EQg¦‹‹!.Ò»ZFR`iªw1¤^¨*=‹ Ÿ«˜y&â6¥KR²P8›‰HV+umUÐ !yzª@d_ÐRµXºº"t@¤NHEIäDŸw.!V‡-•º6™ªÚLlÐ%$ ´á™ÑD¥ÖÐ׆mzâï€Ø–ƒtÛjòˆc„ È©A}AKIÔ¦ÓUÇ<Dêꀬï²I*My–޶ ÞNˆ¿ Ñ�±® Ø KHéb#ìÌ<Û‚XupH¶^¨(=>3ËÐgã%ãNWóÀ �ðüw ÷ ÷߸æk?íW5½X•ÿõ™ö ®\¼¬Ç»èŒæGNÔoû«+zž?2iLoü¬?ä±¼|.Q®I��š">ñŽË['mÞ±VµÉTesØýݲ3SV~u"f±9oÝì{ùȉÑíë<èð˃WïºjmÈ4OöD+Ýt*W¾bCwljB׊$}nê7® óPñ8­~3ˆÅcÛWD¡Â$Ê ��ÐaüCºœö[¯¿êê:6Y-Kà-ۺʹTEL¨BèqX7¯ð8=,Jª$VgÇA®²kûfšÐRÉØM7Ô+y ²·lò¿tjääÙñ|,gqw»-–x®Q¬©½^€äè\MVÁ–nk®¦Å2uKG=|¢ gÊRÐÎYxz*]¯6´5A³¢ÁÉtAr}Ø”*«³ù†ÃÄì\</ªJ·[ )r,%6d´1b©ÔõÉ´ÈÑÔ Ÿ0W’SEÉgåìfz:S/×µ>¿IÄH¢¦hpkÔœ©hñ\ÝÊ3a7›—r9ìäy–šH‹¢¤¯™ë2šHW)’\0%ËÊ\¡á¶°n ;!ȱdM:$Ð ´ `1d&/å«J·[`:!’>™9šZéoB¼VÎa¦§³²x>vñ‰¼”}ˆ:Wh¸Ì¬Çº ds·µPÓ§3¢`@Šr¦t>ц؅…šO‰u]±T%4‘ª± ¬ÓÌLgeQíó™ FæZªÏÖ-<é€,5™k’¾.dn¨h"U%IrMД,5!Þ6ÄÓ‚(‹!sE9]’vÎÊÓ“™zµ®­nAô&D›Í×íp´!<CS Y9[£–&„£#.>Q²e9ìäM5™®·!“©*A’kB›Qz<¹ÂÐ=OOeꕺ¶:`Ru8š¬êˆØ6¥*Úln¤Ëųç$Kr²(y¬¬ÓÌIJÒE@BŽEІ¤Jj¢Ðp.„Pd Òe)ˆ‹!~;g@ÆRU »š›À; \¶Ô Eõù…dII+ëê„@bt®&w@Ìq/„d굆“©*AkB¦TYMä›™\£0%¥ù˜¼Ä:O ¸íŠÞuÝ.ãœö JÄÓS™óÝʹýÊIþgu¨ík»}K_ØyÞ‘ã± sÓ:�áó‡'��“™ÉLûôÿt÷u×oî^ôXNUB¿;“=s6¶¨·]•(Öž?{ëfï½æ^746<âš™ÙÙ½/õÛßrM>—ýÕ¾­«ü^¦>SÍ)JôXÿ¹*âWõ„7EL K85ðüKC÷ßèsS‰T é��µG€²¬ÌÎ&fæRS“é¾uþ{ßÛ;S%ï¼e'��€45“N ÇsvÊ|°Âå ôß}J[7®_ë¥^KËrÏ‹_>2–§ìa Ó9¥\×zÜ„ÄdV’T°¥KHU´™¼ÄÑTŸŸÎ)¹ªâ·2VšÊÊ5I_íçë Šç%U‡WôðÓy5U’­<vÒÓ9¹(ª]N–¦ˆÉ¬ÔÑÆ°õx^¦Hr]ˆ›Ê)ÙŠâ¶0N 5•+ }¥—SuËKŠ.šf‹ê\Q6±TÔÃNç”BM ÙY%§²²(¡uA¾"¡x^Ö±±‹›Î©é²ì0Ñ>=“@”å!>+c¨éœ\mè«ý|]}CSY©.£ËZ²bfÜj:§Tꚉç%Y—wÏCz<ìtNÉ×Ôày ›º¸)"Ð~;=—KâÈæˆ©hñ¼ÄÒÔªó@*е ±¼š,ÉVŽŽ¸šH"×etYˆ/´ ëCÜtNÉ´ SmñŒ$«`[·(©‰‚,0Tï²�_mA¶-‰ºYH,P‹!SÄÇI-Èö(/¨É’l1 y¹X3 äbÑ ¡ÝÚ€¬ðp:±¥/;WòU5hgL,9™•EIoC4@\Ñ‚Ø:`§§sM± „\à¦òJ®²�²ÊÇI*X¡".¦ air²)Šz</C’W2eÅe¦=ç…h‰‚´bæHãÇsm"i^ÑÅ·!Á6ÄÅ1™‘¤¦ÇsÓñZûBH</)ÚH—‹‰ååBM ;æ!B|±¡Çs2$È anªbüžY™+i³‰g¨-HÀ¶�R“Q,'i^mþxvBº],Ù„ MaäÜEí~¶èÁžóÀM½î›·v/Úld&f*³ì©ŒÍnÞÚ½häôúíóf™‘!ôØ…»w¯GüâÈDç‰ÿû½×_·©«ó´Æc9Nõ™ÅŒK ‘gÇNŸŠ¯½õºí5IûÁàir4WÍ‹…:RS,–Š2Ô$ ¨4j$Iþ¼nf:^*™xÖnæº{z­6ÇÜtF,gÒ�€ 4�u� i&Sž*ŠÐ(“¦Ž!]á•I#� éHÖMSf›˜Üɺm¦èÊ�Çóår¹QÉhš>—-!k˜rv‹ˆ¨×õ¨“†LæI[Ãl¢¤Í•5Š$. ÒC¥(ê^3å0‘ãYE”Ñj/SWP¼¨ªÜÑÍŒfÔlU31ä 75’QË =b§YN攆6™LMK5à•]ÌÙ”Ru§@ù-äXV­Ih¥›Vu/ª² ¶GØé¼š,kE®ñQÃ¥T×VÊÌÁ‰œR—Ñ:?Sn ™¢ªépg}.­ækš##j4«VzÔID²¥! â²=”nB\ !3EMÑàUËAÂvš¥áD ’­é‰’ŠÐBˆÍ€è+A j²¬±±ÆG·!–å W÷ÐCi5_Ó¬Ùå¤F³je$ÄÎU´¹’FĦ}.­Eݳ�BwBƲj¦¢™r…§ ¡¸&]`r"š-©ºI+…šîH¿ϪUI_á¦5bUVÁå6VÐ ÈZâ·RÖ6ÄÇ”%4[TÕó@º4IÀ„™‡„; æ&d•‡®«`¦¨ñœš©hC®ôP#Yµ\_’(©‚WF™³iµPÓ°QcÄEë�Äò‹!ëôPº !Æ—B¢óî6Ä1Ùb’-QÒˆ%‰œR“Ð*-© ^T \ÙÍ.…„l¿dg$Ø‚ô.‚µdi!Ä2Yëc*óf8­æjše„„“yERš¹’ bs â6Q39Þ†h ^hB&rjº¢ Ù祆3MˆÀ4!L¾büx:øå!Û"l¼¨Í•4†"Öw@l9‘SD­õ1U Í”BØyH—ƒ¦I8Ñ‚¤*š¦/¸cíôdöÉßœ�÷–5ÿÁ¿~h—Ë&,»#@û†ÍÒ}ÜZ²kÜçŸ8°èn¸½§¦WE\o½bÅ¢]¨ESÑm>rÛ&UG¿96iœòK¾~ç†Ùyß„4–ïvs[/÷ñ,%Ö¥çw°ÞP~®xú•ñ³#Cc¾5;‡d E’D�4 �@±¦7öNÅßýÙž½½·_ù–-梨þ|Ï!Ä»U2Æ›q+Çïu¿÷m7(:xy(ýûs¹£s|׉ ¢Hc �@ÕQ²Xl+?r×M??™Þ7¿æê+n5[Rùês¿ÚY½�� A°fD0€.; I0‘×e n ÀÙ’ž¬"„ˆ]ðDB¯HÀ%~ Êju®rÁ†ŠâE¤èÄU0”Õs5ÄRÄz?Hê5„¬„‰c9]Ráe>˜­¡DiˆØ'ZY6ŽèvÀ³i]T@¯ƒÐ˜.ê²/ÁÉ‚ž©!‚ ¶„੤^•€ÏL88’Õ*\ë Í”ª×tƒÓI½PGf†èsÃ3i½&ƒ.A“`<ׄ$Êz²‚tDìŒ.ésAIE±"RtxU· ü°?©×d´æ¥Ø'ç´rc10]X Ù‚'“zU^ÓòÝàLR/Ô‘‰!V-„LätIƒ›0QYá‰Àˆ•tE›‡0±Á’zÕ€°Ð€lðÁœØ„\§ ;éq�€É|2µÄÕ ‘[®„&Vyà™”^“AÄF° (UA"vFqòDÀ ‡2Mˆ¬5!W†áHVÏÖC—u@,,=/YY"Ú Mȶ œ.êé*‚±- OÎ5!ngõ† ×,„ ¦ôüR&òº¤ÂÍ~˜¬ dëZ݆­ð\F«+påBȨ!ç! aåàXNo¨pƒæëh¶¼Ò〃-\ Ķ0<5§W$à1nÓ<¤&£x ©:qu´ ‹1�� �IDATLëy 4±ÆO/l:$dƒç2ºQt0]\�¡Ib£ö/¬÷ÂB%ÊHՉ뢠N+guD$Ö‚lÓ ZCkÜçx›°ài0¾¢£ùá1<Søò3‡Sqéc2ÿꯟüï8z™Ýpù}ÞÀù'Ð?~s߉±ôÒ=¾öãã MíÞÖÓž7‹oå9,Ü'ï¼\Qµ½§bÿýÞëwnˆÐ¹èÌ;Öò¢öÃCñg~ôs)7©H’X˪r¢šÌWœ<+!¶F{þÏÞ±ÊÄË <úós…á—tÞýÙï&ýšõ¯ÿðÿøeöÜïG@,¦TÁŸ·ÛN}ïhcv Q-J¤Ù¶jÝß=v`úÔ9ó†uüf ù›={«SÇ�’¢Açªdq‹–>WMsVo%cëNN•S± ·ê³ï¯N¼\«Ö,+¯þÕ~¥17Øk2mkÔ=ÿíþvvt¼n•ˆE7Ñh8G¨:ÜäÕæªD² uoŠªãTCvôØõS)BÖà ‡®ê`²5^T‡³d¾I^T%(I>rrèl–Pt¸Þ­êp¶5wu©GTU&¬qiÇ“”¬n¢0V€ª·ùµé"‘¡ŽàMÝêÁª¡fýt†P4¸Ú©‰ Œ• †àΰ:"K È`“O;2GI*Y™AÃ9BYénBl»®#0Y„j„€ðŠzh¶ qñ¯�YëÒŽ')© É_²è§3„¼ruX=Ý‚l>$U%æªPGðÆnõPœªÇ2+‚êHŽÌ‰€ðªzh–j¨ÀgBn f EƒëÜZ±¹.¢OPâÑŽÏQ’º¬ˆ!Àhª:ÜúJUN­®Àé2ÔtxuH=nB¶øµÃs”¤‚ YZ‹ 3T]V¬pè'S„¬ÁÞ…ÑübˆWX�)5àL¹™£*h°®BÎCâ%"½â\it@ΤÉbÒ !V µ!µW€€6$ ŽæÉ\B¯ ÏC<© ¹6¢ž˜£Êh°Þ£[ ñiñ2‘®µ~< "V} ½²#¤¶ [—ƒ\æÑ25"Q…:‚7t«‡g(QV¦ =v˜(BU‡ÛêXžÌÖ!„ðê°úÒÈZ·V^ ¡æ!+âH0’‡ª·,qt@úœš¤Á©R ’!‹uH“`k@;œ $ÌÈÆ¢¡ìbó“@R´eç �`:UBËÝdipù,œ±tÅØ-â±>úñ›ŽÌ}ééC�€|¥^®I‹ws:ét:›Í.º³OÕt–¦HrñÄûý©éþþ€'² ���Bº�]îѬ›ùâÿüß²µ—mln��„B€Bi �Òu�!@ȸ‘BH´>H× A‚Ö·‹t­uS€Ñ<wÒ$ „é i�HÍ6¿, Ž!Ùzº@¬wK…™¨R‚kCâá$ßP¡™Ñ7º¥—çx„@·UaI4Rd��Û¼É2¯“‚#âÞ¸ !àæµ.«r*Í!V;åº c°#XïO³U…à(t…¿qp–×™U«ŸË3€n))Ré !¸!"î›TØYm•C9–â+ì2p¢D�®ðׇólQ"(]®ï‹ :>“ê´ÓY!°Î%¥%Zßèé€Ph¤À��¶zÓe:·ÒmUN¦9„À*§ÜhCõþLR?8+,…¤D*µâTŽ%9„@¯]„xMª¿R’ÈÙóCº¬ G¡ÑƒÎqñZ´ qÈ’§Û,[• ŽDWš Yµ³Ú¹<Û‚©!¸>"îŸØXmS9Ú„(€qâk ˜¢D튴 ‚ê7u@dr¶BA® ‰G“|]…&Zß쑵 <…F `‹·»hÈUúé,[‘ –DWêZ§Í±€ËÜRz„Wthcõ5Ny)d»¯1Zd ‚„èúHý÷qACÀ'¨“6ek]RyYˆW:”Xñ4â:»Âi=6åDšCô9dY‡ÓåóBfÕÙɈdÒ€„Åý³MÈZ§|$É!zl /ñ jЬ dšŠLÎT)@¶x¥—<B bU„NH•Ί NNëí€(:œZ٬dWX<˜àe Z}K:’ä I ±"�¸Ü×+2…A@tc¤¾÷‚Áú÷wêÀÿúp!Ÿƒ"�ö Ì|é»//Þí €§þ¿wD[ÏМ™™9pàÀ{ÞóžR©!ÔtôÈŽ¿x:Þ¹=�pEÐñÕ¿ KSÆ©^xá¿ßß××'Ë2„PVõ»þéÇG?ý¹;X†BüâÈø¿ÿð‡nÝtÏ­›Ú·X†q»ÝÍ‘“Ëå.þe~jêÁgN»#«—¡j5W8ùÖÝkîÛEPìëÿHˆVÚ5…œ©14¡oóÔús¦ºJ˜im£«öRÒJ@2I¥y ¢uN1Qc² š!ôþÊ‹s6€€ƒUz¬ÒñŒ™„(jihˆ˜ª°46»jCE¾¢©_᫼˜°Aü¼ìäÔÁ¼@B´Ú^ÏKTRdhB¿Â[=’¶(:´1ê{ýpÚB@Ôe–(Œ•8Š@—9kS® Q ¡_í¯ü>aƒ�xx9 (ý9S¢3U¶b¢´ÍîÚÁ¤•€ (HfZ*òDkbRd2õ&dÿœ ²ÉU.ò…dIý*_e_ ââÔ3-HA¢æZ£i‹l@õé‹‚¸y%d’OeM$D+lºJÄ«,Mè[=µ Cb²Þ„\å«HÚtœ¬Òk•Ž5!’†ÀT…kBJ|E¾hHÆ"kÐʨëõ—S¢ˆY¢ 4Vâ)mpÖ¦—B8%dnA¬º693‰K!Œ>T8/ÄÁ*+¬Ò±Œ™€¨Ç"é�L–9Š@›]µ‘_^ññ²»Ye¯[íÞê1B«ëœó†@£Mˆ«°ù‹„¸k§ó&Q%JÛ꩘³ÉÊhç ‚IÕ™t r0iÓB¢ µ ›\µÑ_–Éù³†ÀÇËN=Ý‚”d*QkBŽg,Ò"ˆIbÈÄ!ƪ‹!.N‰˜å“Y Q¯µ!iD¬ÊÒÚâ®æMµóCÖ8Ät r¥¯úRÒ¢!è`Õ•¶ÆÑt�˜¸�„“=¼r:oZb–4ÂB«œõC) QØ$³¤n@Ö;ÄxÍ7.R0;ùòÑoÜ[,ä_ñhÚÍÌÌìß¿ÿ=ïyO¥R¹ø½«ýë_ûýþU«V#ç"_ù†¦i·ÛMtÞDºÈ§­�õæCúËüƒfóÚÿÛ´öVDñù´Ð?ã?AÄT¯*pºÆÑZk«öçMU•â(m½½¼?iGz8‰'Õ³EI€^K-QcR –!õÎòþ¤ME„•QºL⑌BªÆ+<E UÖêP‰/*4Kꛥ½ ‚„‹•íŒ<7ˆšÅ¼DΊM¢ öÊÑŒ¥¡“fZí³V_JÛ�„~^"€>\H¬´Ô¦*\VbXRßâ*ísè€p°ŠkœÈYæ!UÞ€ 4!úeŽò‹-ˆ@©ƒEI€Km®Æ$ë,CêåI›‚+£tŸ2Ü‚lq–ö´ FîÏ› t›Å¼DÎt@ê:i2 ©&„„Ë@6;K{çì: ì¬âçêdzMˆ¨À©äô+@Äd6 —9ÊSDí6‹‡3VЄ ñŠ`@FJ|Q¦YRßê,íI8ô&DZ Yo¯ËZêi¢µÕÖêÁ„‚úpÉd@¦; ¿oA|6ÕEµ Yc«žÎ›**Å‘ &J,˜ˆóC¢MGce"Ðjku¤Ä–@œóz±r¼ ±5!>^¢ >Ô‚Ä*LFb˜Ea1„"Ð[õL¡ Ùè(#Ýœd¦”3s2Wg]æ(¿”¶Éˆ°2jODGMÈ*ku´Äm®ÒïNVv1Ò©H¼65R @hB3 +,µXm1ÄÆ*A¡~,k†Mõ† '›Ê`ÁT>?$jÓCi«ŒH+­ö˜k/§ç!£-ÈX ²Õ€�ÂÉÊ.V:•·èZ9‘µˆ%PÚZ[õ@ Âj¯1™Ãú&gyŸa”P 25B„²²Ì£$ó+¼ê]«/ò•ÖŒ3"þ€—åiMâ ðÏÆ(²§jfŽÔzL•±ª¹¬0fJYc)Èx�„¦n¦äÁ’&P˜¯ædf®Áó¤ºÒ\>UpH:e§¥.¡z4ï" ðq"�h¬ja ½[¨ÆD!/³&JYc)̺ \LÝÉ4ŠvŠ@!®VU©¸hâHm…©|¶l­i´…’WšÊ‡²n¡—­3„6\±2„Þ%T’ 6-q©ö™KGr.N¦áçÄ' A Û‚”ÆL)k-ÅýËA ¢£Ñ‚¹ dµ¥ô’¡ë.¦Ñ߂Ԗƒô-„ • H5Õ9šw©ˆt0@ àDY‡“53KjÑÈšyHò�B'êOª+Måþ¢½¡S6Zê*Gr. Âz·P‹|®9¸�â äj5•4 ½¦òPÙZUi %÷™K/µ ,¡•­4¡wñ‹!JR;Þ‚¨‰6ÄÚ„¸™†…’Ï”l" !-H´B�4z’@A®&ªDì‚n!$%ñ©®2—µ A®v<¿ÒcªLTÍÅ%+%Ÿ)Ù)…ùZ±Ya* íu²ÑrT¨6 ¬H�4ZiBfD>'s&²óªÕð0S„¬²4!¶Îê¹²&ô_Í4ØTƒHµÏ\>–w*ˆtÐW;žw¸šªÃ‰yˆ©ØºjhAl’LÍ.…˜*‡s.  .¡:+òY™3‘êjKéPó‡½áaê-ˆX_©¨´…RVYJ³n�¡‡­óçÏ;dDÚi)Ä׎µ š&jf–Ð{L•ɪ©¨°fJY4^óy³ì \ä¼™?•Íf;xð`­V[ú�Ñù>˜H=õâ´ÉÝõFz«‰.®XÑØ‚Â�6˜Sçj ,¡öp…!Ñ�ð25 j É �XÉç’²¥ª1�€Íæ¹SÕ��ÀBJ¦6Qw�BlYÒɬb�¬5¥Çë.Y'i¨­²ƒ5�ÀE‹©Ä6�@_È+|Iå��›ÌsU?P •[Ý��?SA�¦d3�`•7lu&�Ú`N Tý��;Õ°Sõ©†Ã€T56ß‚ Õ<ªá C5�ÀÃÔèW‚x™Úx "ëdfâ”uŠ‚új!c@œ´hz%H˜-´ �ÀäBè²óB˜¼"��6˜RCbÒËÎ-¬às)Ù\ÕØ‹ƒd&êI§(¨¯2gæ!r¼a�D¹BAmB6š“§«¾å )[ ÈŒdµÕp´ ®X»0„®1„6Û„äÓ²©²b&%S¯»��A¶¬ 2#_b&åX RTùâBO(® ©€–B6š“ýÕ€qÒõɺ)Õ4Ú€¬7¥†EІPWðùs5ïÅAd?S[YcÊL¶!¦Ì™ª©›IiYÈ™ªO_ñ1UØ‚ô ÙÙW‚ˆkAFD·‚H†ÐVð9â¦kl ÒËç3¯Q™6 Bf²átŠ„úÚÄA×- \Q囚OG'”.®4Ü‚�ÍÍC¬¢Æ?PÄJ5\ËCÒ‡‡æúo·ÖÅKøežÍfÏœ9sÝu×5WܸýññãÇív{8VUõbÎ¥=ŠvìØÍfó·¾õ-EQ��¥R©V«ƒAüfG8‡{•% ›Íf±Xt]ùÊW¾B1 ó®w½«\.‘Ïç‹ÅâêÕ«ñJáp8îU6<<ìõz­V«ªª=öØüór��AD£Q¼F8‡{MÚ¼yóèè(BÈd2‡P‹¶PUÕ¸“ ‡Ãáp¸WÓÔÔÔáÇ·oß~Þ‘£išñ¾Ö8‡Ã½š¦§§‹Åbç!^‡ÃýiÂ#‡Ãápxäàp8‡ÃáðÈÁáp898‡{ÓG]ü¦Š¢œ;wnéáÝÝݹ\®Z­®Y³†a¼¦8‡{µ#'“ÉìÚµËf³mÚ´©óðüÇüÊW¾²oß¾þþþ®®.¼¦8‡{µ#ÇhÆ ?ùÉOŒÏ;722ÒÓÓÓ>!ôÓŸþÔøØçó]uÕUx‰q8gôªËùÁ~pÏ=÷9r¤}ÈÓO?ý±}lïÞ½ßÿþ÷?ýéOïß¿/1‡ÃáþÀ[9³³³>ú(�`Û¶mKýÜç>g2™yä‘£GÞrË-O=õÔµ×^‹W‡ÃápÈÈyÅDQ|ðÁ“É$^\‡Ã½ª‘ …î¿ÿ~ãã={ö,Ý€$Éžžžžžž;vôööâ%Æáp8œÑkÿ¼–eï¾ûîk®¹fïÞ½gÏžÅKŒÃáp¸?ðVÎ…{ê©§ÞùÎw¾ýío¯T*AìÚµ /1‡Ãá.yäx<ž}ûö™Íæö!÷Ýwß;ÞñŽîîî7V«U¿ß‰D~ûÛßÇZ,–Îý§q8‡GÎÅFÓôÆ;ñûý~¿�`³ÙÚ.Ú‡Ãáp8#ük8‡Ã#‡Ãápxäàp8‡G‡ÃáðÈÁáp89x p8‡G‡ÃáðÈÁáp8îÒ[üTÐt:½ì»Mãp8wI¥Óé œd2yðàAü¾8‡ûãÞÊÉd2‡Z:”p8‡{GŽ(ŠEÝvÛmxQp8÷šÄqœÉdZfä��X–õz½xp8÷š$‚,˪ªŸâ=Öp8÷' ‡ÃᑃÃáp¸7V^÷ÿ%KÂ×Ãw¢i¾8ðÈÁápoä8ŽcæÏþm$ AðÅG‡{㧪*BèÏ8ožþù÷½ï}ø‚À#ç/&!MÓxp¸e“eùÇ6ö®±ú^xáEQðe„GÎ_ØÈA á¥ÀáµiÓ¦ œK®R©ô÷÷¯\¹/׎eY¼8<rþ(Y,–7âuÀáÚY­V‚ÀO±À]røJƒÃáp¸×Ó­œøÃ¢(>ýôÓ�€ÁÁÁ/|á �€w¼ãüàßlëõÄOôôô\ýõ‹Ÿššzâ‰'þéŸþéwÖ_ûÚ×.¿üò+¯¼ÒøTQ”w¿ûÝ�€uëÖýë¿þkç–?üðŒ!„?üáñ÷:ì›ßüæ/ùËÎC~ô£µ?>pàÀÃ?|×]wɲüÓŸþô³ŸýìöíÛ?ùÉOÆb±gžyï×óF9¨T*�€‰‰‰}èC>ŸïŸÿùŸß„/�úï|çË_þ2Ïó_ÿú×wìØÑyTµZ=yòäé|Ÿ~úéo}ë[±Xì‘GiøÎw¾Ó˜p_øÂþå_þ¥}Ôààà[ßúÖË/¿_¿q¯çFFFöîÝûoÿöoÛ·o_zl:Þ»wï¶mÛî¹çžM›6õöö�><44¤ë:^½¿Ð.ᎵT*uÇwŒŽŽž8qâg?ûY(zS­Ô3Ï<333sóÍ7ß{ï½O<ñDÿ²›=÷Üs>úèW¿úUãïµ~ô£ÃÃÃÆQù|~ëÖ­[·n½ÿþûÛÛ?ôÐC[·n=xðàÝwß===½ì×¼í¶Û¾ýío_{íµž9sfË–-[¶lù«¿ú«O|â‹N²bÅŠ-­ðµ÷znÑuufffëÖ­ÿøÇ;ôî½÷Þ“'OÞ{ï½�€¥w3àÞ€#Çãñ|ë[ß�\{íµÿðÿðf[©r¹ �°Ùlç?þã?Ö¯_¿ìf•JåË_þ²¦iìééyç;ßyÿý÷ÏÎΪªzË-·ìÙ³gÏž=7ß|ó§?ýi�À#<bµZ÷ìÙóo|ã¿ø…ñ4‚•+W^wÝu_Ón·÷ôô˜Íæ¥öôô|ðƒôù|‹Žºûî»{zzzzzJ¥¾–ãþR*•J;wî´X,·ß~ûßÿýß·ÿV›œœEñÑGF£�€ÿøÇx­Þø#‡ ‹Å� iúMø2ùÈGL&Óã?þéOúw¿ûݶüèG?úÀhšöè£ÞrË-¢(êºNQÔÑ£G E©Õj�€z½N„ÝnÿÎw¾³yófãØ±±±ÿú¯ÿêééyï{ß[,EQ\ö\$IºãŽ;&''xà÷¿ÿýG}ûÛߎÇã““““““øVîuÞ=÷ÜÓÓJ×õr¹L’ä[ßúÖ¯~õ«‹¶4›ÍÆnrv»¯Û_hx'éK¸•ó| ™Lnܸñ»ßý®Ïç»òÊ+c±X$¹˜W0Dõ÷÷ÿíßþ-�@Å ß3öìÙ300pã7Þu×]ŸûÜç–nòìË/¿¼ìÉ3™ŒÙlæy_j¸×O>ùäM7Ýd|\,ñ‚à‘ƒ�€gžy&›Í.:p÷îÝgΜ¹˜g4Mûë¿þë‘‘�À¯ýëçž{®óØññqãv�àäÉ“ù|þ‹_üâ¶mÛNœ8ñ|«ŸùÌgÞÿþ÷ßxãøRÃýåþ…799y¾cu]?sæÌ† ðBá‘ó†-çr¹x<NÓt0´Ùl�€;wîÛ·$ÉL&sá»° „W\qÅÞ½{�‰DÂétŽŽŽöööÎÍÍíÝ»÷g?ûÙì쬱å¿øEdzgÏž ?;wîlµË.» �Ç5M‹F£ëׯÇãÆ±W]u¾ìp¯çúûûÛÏ*ݾ}ûŽ;2™ÌsÏ=·èÏ2£+¯¼rrrrÏž=?þñ¿ùÍoâÕ{cŽœÛn»­^¯�l6ÛwÞ¹uëÖ7áJ½õ­oUUõ‡?üa2™ü÷ÿ÷5kÖ��üñûî»OÓ´H$bì²Fº¶lÙ �7Ýt“ $Iþçþç<��ظqãÛÞö¶cÇŽ½÷½ï}úé§Ÿzê©O~ò“§OŸ6ÎèÙgŸ]öغu«ñüñ}ìc�€¾¾¾Ï|æ3�€sçÎɲF?õ©O=üðÃ/¾ø"��ÿXâ^·mÞ¼ùÎ;ï4¹á†ž|òÉÏ~ö³¹\îá‡~ì±ÇÖ­['ËòwÞi\ùyä’$þóŸã+ö_hÐétf2™r¹<;;;66¶k×.¼(í‚Eqÿþý»wï6ùÉO~ …^«§¼œ8q‚ã¸uëÖ�vïÞýõ¯¿˜î/"ãoÎ÷Ћ  ÃT«Õ?ã+I?ûì³µZíî»ïÆÖŸ7AdYVUõ±Ç{ðÁñk—ÖÛßþö×ð«U*•^xÁxö 7Üàp8ð ãp¸7pxäü9Ûµk„p``��ðþ÷¿ßårá5Áápx伩#Iò÷<¤[o½õÖ[oÅ‹ŒûËêbž€Ãá‘sÉÙíö;v¼ÞȇÃáðÈy#‡RUÕb±T«U¼8‡GÎ}äàuÀáþ€<˜L&ÿ\ç~¾WŠÂᑃÃáÞhýö·¿Ñ4íÏø=àœðÈÁápoüDQܺukû•jq8<rp8Ü1‚ Ú/cƒÃÍ_1ðàp8‡ÃᑃÃáp898‡Ã#‡Ãápoö^yµo~ó›Kß Óèúë¯ß±c^D‡Ã½6#ÇxE}Y–?ÿùÏãMÆŽ9òì³Ïr‡G‡Ãá^³‘s×]w�DQüüç?ït:?ò‘��8Ž3Þ¼ò©§žzñÅxàµk×�î¿ÿ~ãýC{{{?ó™Ï>|øÛßþöÛÞö6Q÷»ßýÝßýñ–É8‡{öªËyúé§óùüÌÌÌ'>ñ‰ÉÉÉüãßûÞ÷Þõ®w]sÍ5ßøÆ7¾ô¥/MOOÿà?xðÁ‰D*•ºÿþûGFFð¢ãp89—Üu×]÷Þ÷¾×çó8q¢\.8p@Ó´Ý»w_}õÕ¥RéäÉ“Æf;wî|ßûÞNž<y¾w®Åáp8ܾWõ‚7ápØãñt¢iÚöíÛEé<0 ú|>¼Ö8‡GÎkI’¿üå/†ùÕ¯~…—‡ÃápF¯åórÌf3�€eÙÙÙÙõë×ò“ŸÄë‹Ãáp¸K¾•!ŒD"~¿¿=]"‘ˆÕj�¸ÝîH$Â0ÌÁƒwîܹsçN�À-·Üòøã?ÿüó‘HÄf³�\.W$aY/:‡Ã½9ƒN§3“É”ËåÙÙÙ±±±]»váEÁáp8Ük’ ²,«ªúØc=øàƒøop8÷' ‡ÃᑃÃáp8<rp8‡Ã#‡Ãápxäàp8îM…—àB™ xžÇë`T¯×u]Çë€ÃáðÈùcEÓ4^�Àþýû£Ñ¨ÅbÁKÃáðÈù#¦ªªñ&@oÚŽ;vîܹ`0ˆ¯ 8œ?n!MÓÞÌ+P*•dYÆ×÷*ûàp8‡ÃᑃÃáp8ÜÐÅ>–süøq„ñ±Ýn_¹re2™œ™™éîî^ôÆ oªN:¥ëú† ,ËêÕ«ÿg:88X¯×·nÝJ—öC©Tõz½]]]KÕuýĉ<ϯ_¿ÿ`àp¸?Û­œ_|ñöÛo衇zè¡Ï~ö³ÿøÇÏž=ûƒü`÷îÝ?ÿùÏßÌË÷îw¿ûŽ;ŸD½�� �IDATî(—Ë=ôÐ÷¾÷½?Í™Þwß}»wï–$éRO899ùÐC½ð ËÛh4vïÞýÑ~ÿTàp¸?ç­œûî» ˆïÿû�€ƒÞ~ûíßøÆ7úúúŒc:433sóÍ7;„гÏ>k®¹æš±±±“'OnÞ¼¹P(LOOßxã.— �ðì³Ï7›¼^ï_Ü›ô8p`nnî-oy‹ñ© ïz×»¼ÿ?{÷Åñ> |®qÔ;ª‘Þ¥)Š]@PDÅ®$lÁnŒhŒ %šØÅˆÄލ`bGEÄF¨ÒáhG»ã¸ãúûÇürï} 1ÚóùkÙ¶Ì–ggvv¦_?„Paaazz:ž?tèPCCÃû÷ï{xxܽ{W$©©©¹¸¸<|ø!diiéèèˆJII)--ÅÿâïïO$¯]»¦¡¡1xðत$333ggg„ÐË—/‹ŠŠFÝv{***’““­¬¬H$Rvv¶»»û€B·oßæp8!UUU___==½3f˜››gggÿùçŸ... £¢¢büøñ4íúõë¸$ôøñãv×��ÿIII)$$„Ïç755Õ××›˜˜´MÔØØ˜––F£ÑŠ‹‹---¥Ré°aÃ8ΣGTTTêëë#""šššœcbb¾ûî;mmí7oÞœ?ÞÜÜ<==}õêÕÕÕÕG­¯¯ÿâ‹/âââ¾ýö[mm파Œ³gÏš™™™™™uÃÜ!T*U"‘…BÙÌÇoܸ±®®®®®îñãÇR©tÞ¼y&L`0îîî»víº{÷.@¸xñbQQ‘££ãªU«óóó >¬¨¨˜“““˜˜˜`ccSTTôÃ?”••q8œýû÷“ÉäAƒ7îÙ³gT*õÖ­[wïÞµ¶¶.//ß¼ysaa!›Í~òä ‡ÃY·nì3Õ'Ož|ýõ×<ïÌ™3ùùù k×®URR*--=pà€‘‘‹ÅúòË/***BBB˜Læ¡C‡x<Þ!C.\¸ðêÕ+2™lcc3dÈù|(..nll´¶¶VVV†k�Ðy E,K$’ôôôÇwªbmóæÍkÖ¬)**Ú´iÓ¥K—† 6}útü‡Ã™>}º……Å6nܾ|ùòœœY]Sssó”)Slll"""˜LæÎ;)JxxøêÕ«óóó£££{P^¼x1;;{Ù²e ¥U0ÀÜÜ|Û¶mááánnnÑÑÑùùù¡Ý»woÞ¼yË–-555ñññááá³gÏ~úô郮_¿þúõë   ððpÐÐP¼L‘HÔ¯_¿ÀÀÀ/^ܹs'>>>--í«¯¾ÒÒÒúÐGB---#FŒ:thLLL^^Þ¡C‡êêê¶oß¾}ûöºººC‡µJÏápæÎkbb²gÏž¦¦¦íÛ·ã²)Ô­�º²b !Âáp(ÊîÝ»MMMe·ZŸÊ’­Y³fóæÍ›6mª®®–ÿwOOÏAƒµº?nÚ´©¶¶¶çæÝ’%KöìÙÓÜÜ,›cmmíééyõêÕû÷ï§¥¥ý›…ëééÍ™3çÚµk­æÏ›7ïÈ‘#L&³í¿¸ººzxx\½zµ“«ðóó“ÕŽ�@w 97nliiÙ¿ÿÚµkI$Ò¾}û?~ÜîÝjݺu—.]úå—_ ;^&‰D²··G;¿xè^¿~½yófuuõ©S§fddÀé��ò:U±víÚµ¸¸8„ººú¸qã:HyåÊ*•:{öl///ùùgΜyòä‰ü …2{ölww÷ëׯÿËAWùî»ïX,–üœ²²²ÔÔÔΞ=ÛÜÜüs¬tÇŽeeeíþßù"N²²²öîÝ ×� kBNLLŒD"ñõõõõõ 6lØš5kÚMËf³}}};¶cÇŽ‡þöÛo¡Q£Fݼy355uïÞ½†††çÏŸçóù¾¾¾_}õUUUÕĉ{V¤qss[·nÝèÑ£[½N>|øêÕ«ãââ|}}­¬¬†¾qãÆŽ |ÁÁÁcƌٺu«¯¯oyyùÅ‹ÛýÚfÑ¢EãÇß¹s§µµµ¶¶v»‹úâ‹/²³³oÞ¼¹qãFggçƒêëëϘ1cæÌ™èx¿Ïž=[TTtèÐ!???¸6��ŸASS“Éd²Ùlƒ‘ŸŸÿ¡öÊyyy²OAUUUû÷ï___Ïd2uuuÕÕÕËÊʸ\®™™…BÉÍÍÅ÷/mmíòòòØØØ½{÷îÞ½{òäÉl6ÛÈÈ@ƒ“!„”••»mÅ‘H¤ÑhB¡Pþ… B¨¼¼¼¹¹ÙÔÔ´´´T*•š˜˜âa±XUUU!]]].—ÛÔÔ„ÿ·ôËÏÏWRR222b³Ù•••ÚÚÚZZZ•••l6'³°° ïß¿§R©&&&MMMššš:::UUU,kÀ€555|>ßÒÒRœnݺ5oÞ¼åË—¯Y³¦®®N__ŸF£!„ q[; …bffÖÜÜ\^^®®®N&“kkkõôôètzii)Ç377'“É"‘¨   íyüøqqqñ¤I“pw��è$eee@ ‰"##·oßÞÙæVVV­æhjjjjjâiù;”üøÖÖÖºººxZ_____¿Ýd=Ž¡¡¡,B´Ú:N§Óñ´ººz«”%£Ñh8*´Íùdò=èééééé!„ÚmÈŽikkË—Z5=WQQ‘-M<ä{" “É=ú¸��º¹ÏÞÇ™LVVV†Î>+‰™ �èþ>ûx9AAAAAAÑŸÕøñã ä� ¯—r����9���þS0õßkii‘u»Ù7q¹\8 ��r>;÷êիׯ_CV���„œÏH*•677 µ !„?¨��9Ÿ+äÉdÈ ��€óyEEÅ®Šv---p��rúPÈ¡R©ÿýzy<^ZZîi�� äô!b±˜Çãýg«‰D÷ïßoii�€ÓçH$‘HôŸ­N 0 è@�ÐûÀ§ ��� ä���€���|„ξˑJ¥ÅÅÅxZEE¥_¿~mÓ”••‰ÅâFsée †@ @‘Éän;Ê��ô¼“šš:iÒ¤Aƒq8]]݈ˆù¡½0???ƒQ[[Û2.//oæÌ™4H$VVV^¿~ÝÆÆÎ'��ø·!'99yúôéS¦L9vìXffæ–-[nÞ¼éççWPP€8::jhhÈÒs¹Ü””<mhhhiiùþýûòòr{{ûââb6›íáá¡  ÐssíÝ»wK—.ÕÓÓ»pá‚¢¢âܹs÷íÛ7{ölAƒ!„ JKK ¤££“––ÆápB eøðá,ëÕ«Wººº4íýû÷–––²1F��BZ¸p!‘H<vìBÈÎÎîÊ•+ÅÅÅaaaYYYÖÖÖ)))³gÏ^±bNÌçóO:µgϞѣG—––Òéô;wž9sæèÑ£«W¯¾yófAAA^^žŽŽNÏ͵ݻwçä䤤¤à¡¦¯\¹ò矎1ÂßßÿôéÓ¡èèèýû÷Ÿ>}ZCCcÅŠ¶¶¶ŠŠŠ>üý÷ßétz@@ÀСCÇwùòe''§7B½� /øÈæOž<‰‹‹›6mÚñãÇ]\\öìÙSRR‚âp8?üðƒ¹¹ùñãÇ/^œpýúuüÓÔû:ˆÔÔÔôõõ-..NNN~÷îÝ»wï<<<LLL233===9Åf³7oÞŒÓ3™LssóI“&ÅÄļxñND��”r>±©S§îر£WÖ#ûûûÇÆÆš™™=|øpÿþýöööööögÏž=qâ„D"‘Oïìì<eÊ”ììl8�PÊù,fϞ݋ß[˜ššÎž=;==ýÞ½{ÞÞÞC† A<yrÇŽ<¯Kúj�€žr~üñG‰D²eË„Ðû÷ïW®\Ó—sméÒ¥fffaaaMMM|>åÊ•?ýô“¡¡¡¯¯offæ³gφŠ‡Ø¹víZmmíüùó—-[g� ëTÅÚ´iÓH$RpppQQQ}}½P(\³f©©illlzzú«W¯6nÜ(ûGMMí—_~ÙµkW`` ƒÁðöö8yòdoʵѣG:thñâÅAAAd29-- ï ««ëÂ… ?.Kùý÷ß—””¬Y³FEE%""bÆ ¡¡¡pÚ� ätÄßß_ÖÆLKKËÆÆÆÑÑQöq¨N?qâŸÏWPP˜7oÞÀñOúúúfffK–,ñóó³µµí57lذèèh.—‹¢R©¸MOOÏÞÞ~Ú´iÓ§OÇÉÜÝÝO:ÕÜÜL \\\Œñ|ü-í¼yóFŽiee'"��BÎÿG$=<<äçôïß¿ÿþòsœñ„’’R«Ä¦¦¦¦¦¦½,œZÍyüøñÏ?ÿ<cÆ ùWVŽŽŽ²éVÙbddÔö‹Z��è­ µO&55uá…Æ ûöÛo!7��àãK9ào9;;gddÉäݱ��@ÈéH$’²²2ä��|T¬��€RN·!jjjþ³Õ …BÈs��„œ¾ˆÏçgdd@7h���!çó’J¥l6»¶¶ÖÂÂâ?^µŠŠ ä?��BNß 9xÈ ��ø÷ ù����(å��z&‰Ô¶„ÇãÁá€�èÕ·•îñAtBB‚¬.�!�Лñx¼V#þ—ž>}š——!BNOÂ`0,X�ù�@»îܹÓAšX,‰D]µmeee]ð�„œÑÒÒRQQ1þ|È �Z9pà�d€ó‰Q(‡Q£FAV� £¦¦ù� ä|zD"QQQñ?XÑ™3gjkk×®]K  ÛAw¦¤¤g)ø,!§²²²m…¬ŠŠŠ¦¦fgVÐÔÔÔØØ¨®®®¦¦Ö ò«¡¡AAA¡m×�B¡°¡¡õùѤRéóçÏ׬Y3è 8ŽüœȦ¹\n]]F“J¥MMMÚÚÚJJJUUUB¡ÐÐЮ‘žúÿ·)6nÜ8wî\{{{WW×ÀÀÀÀÀÀßÿ½“+8þ¼½½ý¹sçzAfUWWoذáÈ‘#l6»ÕO¹¹¹‹-‚ó €ÎÛµk—½½ýäÉ“ÿ"ÿë;wìíí>|îܹÀÀÀW¯^!„¦Njoo/ ÷zm)çôéÓø‰£ÿþæææ‰‰‰x~yyyaa!ž<x°††Fjj*ŸÏ1bÇKKKÓÔÔìׯ_~~>B¨   ººZWW·çæTEEÅÙ³gŸ={öîÝ;mmíiÓ¦Ñh´v …---!EEE}}ýwïÞ™™™©ªªâ’ÐóçÏBšššƒ Âéóóó+** TRRÂåráŒ}Í/¿ü2nÜ8ÙŸøî¡¡¡!›ãëë;xð`›·oßâkäÙ³gcÆŒ¬ë!§]¥¥¥»víz÷î••UZZZ``à²eË/^Ì`0jkk ÆäÉ“½¼¼Ö¬Yƒû`NII)((èÑ!'>>^"‘øûûÛÛÛWUUUWW·rîß¿÷î];;;“§OŸ<xÆŒŠŠŠW¯^½uëBHOOoæÌ™_|ñENNNlllaaá°aÃŽ;æëë g$èË„Battô®]»f̘A&ÿßÝéĉçÎ{óæMCCB(::BNõ‘}¬%&&^¼xqÆŒ§Nruu /..ž6m™L>}úôÕ«Wutt<==‡ † ËsçÎ6lXÎ)••õôéÓéÓ§[ZZvÝÜÜŠŠŠN:µdÉ’ßÿ½¶¶V"‘dddœ:uêÔ©ScÆŒ9vìBèêÕ«zzz§NÂ]VÃéú œþKsssHHˆ©©iPPPfff«”›6mêß¿?BèÈ‘#o}«”ƒ%''‰Ä÷ïßã?·nÝJ&“׬Y£¡¡±iÓ¦^öncĈ‰äÞ½{L&óÂ… sçÎ500h7å¸qãÆwãÆ¯¿þZ™H$Ò÷ß?eÈËËkõ/K—.½t霎 ªªª¢R©mŸðæÏŸŸ””ù!§µ3f̘1C__¿wçTjjªD"qww···¿~ýúˆ# ~ýõ×µk×v¦C‰Dò믿Òét8ç�({—ÓØØÒ»ý«Á <<<V¯^M§Ó‹ŠŠÁŽ;<¸ÿþàààððp\w$••ÕssêíÛ·mÇŠŠêd§‰$::zõêÕ«W¯ö÷÷oõkdddII œŽ�`999¸áR»ÁöíÛ!—úPÈ5jÔ¬Y³âââ,XðË/¿èêꪩ©]¾|Y$ÍŸ?êÔ©L&óÁƒ!OOÏ©S§ÆÄÄ466jiiõÜœòôô$‰wïÞŠŠ=z4®1;xðà’%K,XµqãÆþD"………-X°`Á‚=4hйsç¦NZUUµ`ÁÐnc�z½={ö,ø‹²²rxxxQQщ'ìììÚ&Þµk—ººúÊ•+{ú»á>«³kT*õúõë²O ŒŒ6oÞŒI <˜N§GEEñù|„Pÿþý¯_¿Ž¿533Û¶m[II‰µµun±fjj:{öìÌÌLssóéÓ§ã½?~¼²²²T*UQQÁ}ÖzyyáFÒË—/Ç =÷ïß߯_?0uêT===„¦¦¦ŽŽ‡Ã177Ÿ;w.n$§#èS–.]:iÒ$ù9 ÖÖÖzzz>>>FFF‰ÄÛÛG 1cÆœ?^$ÁX½½<äH¤‘#GÊÏ144444”ŸãêêŠ'”””ä÷‚Ì266þé§Ÿ”””ä?1b„|Ù;-YÃ/¾øOP(ùlÑÕÕ=yò$N€ôA­fÊß=tttð„™™™,»»;d]ÏQÿ3òñæ_ HOO······ é��þm)|t:}ëÖ­ø%²²²D"™7o‘Ï��9}’X,ær¹B¡ðs3ÿꦷ|#“ÉŸo]�|*uuu0�€ó‰Q(EE۰°°°0È �ä}Âf�! „‘‘QZZä�¡±±‘ÇãuÕÚ¡!�ÐWÔÔÔ<~ü¸¶¶¶ ·ÆÔ�èýD"QQQFëÚœ!ä@È�ô~ÀÚÚÚÚÚ²´íq��@È��л@Å�àSPPéÙµ`pw9�€Þ~[!“º|3nß¾=tèP8r��½Ç‹Å]µöÇAÈÓ“‰DÙx �€Vššš:øU,‹D¢®Ú¶ªª*øBNÏSWWwýúuÈ�ZùòË/!�„œOL"‘¨««;²�F¡Pðh„�@ÈùÄH$d�pE€ÿ(ädggË*Fi4Ú€êêꪪªþÑe¥¥¥MMMÅÅÅò•¼xÿ/—Ë-**RWWWTT¬ªªÒ××ÇCA�z¨ÊÊÊúúzù9x´iŒÅb•——ëèèH$’ºº:###55µ‚‚‚––[[[è̦7‡œ´´4ggg|¨©©<xðÝ»w'NœX¾|¹¯¯o'W¶~ýú{÷¦Nš4©¾¾(Ëb±ètúÌÍÍ;øßŒŒ Ÿ9sæŒ?>**ê›o¾ñóóƒã@ϵwïÞßÿÝÖÖVöØzóæMÙ¯ .üî»ïtuu¯]»¶eË77·ÀÀÀœœœªª**• ØkCΗ_~I$ñÙœœìççwðàÁ5kÖÛÙÙ½zõª²²§$&Lhnn~üø1žcbb"ÿä2lØ0UUU„²²2^`RRÒäÉ“:´ÿþìììÂÂBœrĈ4M"‘ܾ}[UUc†²··Çë}ýúuEE…‡‡‡ººú½{÷BÞÞÞ,ëéÓ§8¥……ôò@7·cÇŽqãÆÉ×g<zôH[[[þ¦¡¯¯obbòüùs‡ƒºwïÞ¤I“ ëzmÈ™6mÚÉ“'£££544¬¬¬ÝÝÝããã·nݺwï^©Túúõk„еk×x<ƒÁˆŒŒüí·ß|||ŠŠŠÈdòŽ;ìííŸ={Æ`0öîÝ«¯¯ßîZ233·oßÎáp,,,îß¿ÿõ×_¯X±âÚµkëׯ Ä !tçÎM›6…‡‡§¦¦^ºtéÁƒÎÎÎÁÁÁb±øÏ?ÿŒˆˆˆŽŽ7n\^^ž††Æ¶mÛ‡€A ;vìðáógÏnnnÆ3cbb"""Î;———‡CNBB„œÞr~üñG…ôôôÛ·o¯X±Â××w„ ‡¿!„.^¼?oÞ<‡³sçN—C‡ÅÆÆ.]ºôÖ­[ööögΜÉÌÌ”?·>Œ*,,´°°3fL}}½Í”)Sœýýýúé§ÀÀÀ 6¨©©­_¿þûï¿ÿÛí¬­­ýå—_,,,üüü444nܸѪ¦�ÐÝüñÇÙÙÙx:00044ÔÉÉiÁ‚›7on•rÍš5/^lllüùçŸ!ßzsÈAmÛ¶­©©IAAaË–-m¿±úí·ßøáüR^^–••%ŸföìÙ†††²?ù|~uuõÉ“''Ož<yòd‡nß¾}ûöíââbùÔÑÑY¼xñåË—;ÞH Í›7mÛ¶ÍÏÏoìØ±pŒèÎD"ŸÏo5ÓÂÂbæÌ™wïÞ…üé‹!'44´¥¥e÷îÝ6l “ÉG޹w¥¥,Adddyyù¢E‹¨T*9 žžžNNN8ÙÔ©S 𴂂ºuëêêêH$Ò;wâââ´´´BCCèææöqïétúºuë ÆÏ?ÿ¼gÏž‰ÄQ£FÁa Û ½Ëill„ éÝ:5xÁùóçÏœ9ƒÒÔÔœ0aBÛòÍÞ½{—/_.ÿƯ_¿~AAA¶¶¶ÉÉÉ¥¥¥çÏŸþüyÛ%kiiùúú'''¿{÷.##ÃÃÃ#((¨ÕûžŠŠŠÝ»whó¾ÿþ{ç˜LæÂ… /^¼òå—_¾}û6##Ž1�=Nfffddä‡~ß}÷äR¯ 9Ç—H$¸©â²eËd¿¦¦¦ÖÔÔܾ};00pÆŒ4íСC¹¹¹ëÖ­kii±··÷î]iiiÇk™:uê”)S~ûí·€€€3f˜˜˜,Y²$22²±±qëÖ­ÞÞÞ­Ò¯]»ÖÉÉiãÆ®®®¸T¤ªªêîî±jÕªÔÔÔiÓ¦áú:�@·µsç΀¿¨¨¨9r¤   **jøðám8p@CC#((( �²®'"hjj2™L6›Í`0òóó?T õæÍ©TЧÕÕÕMMMkjj Æ€šššä‹ÃNNN|>_öGGGÇÐа¼¼œÉdš››ã±Ð322$‰ƒƒB¨©©)??_[[{À€ÕÕÕ!KKËòòr‡Ã•¢¢¢‘‘Q^^ž¦¦¦’’ƒÁ044ÔÑÑ)((`³Ù¶¶¶yyyR©ÔÞÞžËåæææâUëêêÊêñ>2 ‰\.÷É“'^^^p®� C£ÑˆDâ‡êÁ”••8NÇÝz–••ÕÖÖÊÏ‘Ý=ÔÔÔ´´´Š‹‹õôô$IMM™™NGýùçŸb±ß=:péÒ¥æææùóçÃÁêZÊÊÊ@$EFFnß¾½³!§–!ä�ðÙBÎg!§{†ˆ��Àºõü{:t��9Ÿ‰D¢Óé¸���„œÏHSSsìØ±]8ž.��@Èé$IÇCí�>¤¶¶–ËåvÕÚá1B� ¯¨¨¨HJJêÚNá,„�@ï'‰*++uttttt ä�9�€ÏH ˜››w<è"è›à»���r���ô.P±�øÄ¨T*™Ü-î-²¡E„�@ïD"‘(J—oÆõëסÓH9�€>ËåváÇ1÷ïß///‡£�!§'!‰ªªª�´‹Ífwð«D"éÂS__/o@Èé1˜Læ¥K—ˆDhgÀÿG `\��!çÓ“J¥ýúõƒñr�‡ÇËáóùà‡w���ݬ”“šš*‘H𴦦¦••UeeeII‰©©©®®n'’››ÛÐÐààà••% eóµ´´,--;þߦ¦¦ÌÌL•âââ´Þvw„F£ÙÚÚÂ�@W)..®ªª’Ÿãîî.›®««{ÿþ}ÿþý%Iee¥µµµ††Æ»wï¸\®««+Ôu÷æóèÑ£¹sçŽ=ýõRnïÞ½ÅÅÅçÎ[¸paçoý[·n½wï^jjêœ9s<==ñ‰E$÷ìÙcgg×ÁÿfeeùúúΙ3gÒ¤IgΜùú믽½½ÿéÞÊv¤©©©¾¾>""ÂÉÉ N�ºDDDÄï¿ÿ>dÈmmí¶!'11qáÂ…ß}÷±YÓºÓ�� �IDAT±q||üwß}çìì¼téÒœœœªª**• ØkCNpp0‘H<þ<B(99ÙÏÏïØ±cË–-›<y²‰‰IrrrYYNI fÍšÕÔÔçXZZ:;;ËåååE£ÑBJJJxIII“'OŽŠŠÚ¿ÿ›7orrrpJuuu‰DK£Ñ´´´ð|33³É“'›šš>þ¼¤¤ÄËËKKKëÊ•+R©tÚ´iõõõ÷îÝÃ)mmmíííåwäÞ½{3gÎ<pà@VV–‡‡Çž={¢££á$�  mܸqܸq²?9ÎÍ›7õôôdsìììÈd²žž^BB‹ÅB]¾|yîܹu½6äÌŸ?ÿàÁƒ¿ýö›–––‹‹Kppð!Cîß¿¿uëÖ½{÷***fdd „¢££¹\®¿¿ÿþýûÏ;——ÇårCCC]\\JKK8ð¡RÑëׯ·oßN$øÇdee…„„œ;wnÇŽ‹-’½¨|øðá¦M›ÂÃÃSSS/]ºôàÁ--­õë׋Åb//¯½{÷þñÇ~~~™™™$iÛ¶m²UìÞ½!ÔÜÜk``àããg��ÝŸÏ?pàÀ™3gæÍ›WYY‰g^¾|9""âܹsåååø>••yÕCuª>ôûï¿_¿~}EEÅæÍ›/\¸àìì ûuΜ9»ví²´´$‰k×®år¹{÷î522Úµk×Ì™3Ÿ?ž€Š‹‹“•`ð¹µ{÷îÝ»wÇÄÄØØØøúú ÐÐÐ]»v™™™:tˆÅbíܹSUUuÕªUë ו‘H$WW×ÐÐPwww@Ð*H$úñÇcbb6oÞg��]ëâÅ‹»ÿÂãñ~ýõ×þýûùå—<¯UÊ%K–ôë×!´eËÈ·Þ\ÊA}ûí·ÍÍÍ %<<ÜÄĤí7V§OŸ^»v-F³¤¤$$$$??_>Í×_mllŒ§ ‚¶¶6ƒÁ¸xñâäɓǪ««Ã5]òÿ¨¥¥5oÞ¼³gÏv¼‘šššáááyyyaaacÇŽ7nœ‹‹K«4›7o>þüž={¦OŸ‡€.G£ÑdïrdLMMýýý¯_¿ùÓCÎúõëy<ÞáÇW¯^M"‘~ýõפ¤$ù6fûöí+--3gŽ‚‚ž£ªªêâââââ2gÎYÃ0Y­š‚‚ÂâÅ‹I$Rllltt´¶¶öŽ;\]]GŒ‘””ôqçîâÅ‹««« BTTÔÓ§O‰D¢ü'5!!!gÏžŠŠòóóƒc@wàëë+{—ÓØØÒ»uªbíÆW¯^EÑétÜnMÞ¾}û>¼qãFù�µ´´f̘¡§§—™™yòäÉv£ˆººú¨Q£ÊËË_¾|™“““››;dÈ3fàâ³LyyyEéU«Vá¢UuuõÌ™3£¢¢Ö­[·hÑ¢ìììÜÜ\ù”7oÞDA¼ ›{ûöíþýû?ô+ŸÏÿæ›o —zmȹxñ"~9ïååµnÝ:o¿ýVöë»wïêëëOŸ>íïïïããC§ÓOž<™íååµfÍ•áÇçååÉ^~ȬY³fΜ¹oß>//¯ÀÀ@33³¹sçž;w®¡¡aÆ m¨|ÿý÷...+W®œ0a‚’’`S¦L‰ŠŠ ¼ÿþܹsÛÖž ¯¿lß¾Î��ºÖ¦M›d—¤ªªêéÓ§óòò"##'MšÔ6qTT”––Ö¬Y³‚ƒƒ!ëz"‚¦¦&“Éd³Ù #??ÿC}}ÈÞߨ¨¨èëë766ÖÖÖêèèðx<‡#Kiaa! KJJðŸt:]GG§¶¶¶±±Q___EE!TTT$•JÍÌÌB<Á`Ðh´~ýúÕÕÕ544 „ú÷ï_[[ËçóÍÌÌ úõëW^^®¦¦F¥RñzétzEE—Ë566.//Ç äóù²Û²¦ÕXqq±H$’ý‰w¤£€L$r¹Ü'Ož@‡7�ÈÃÞ|¨LYYYAAÃáÈ_nm1™LÜè¹íÝCYY™F£UUUihhH¥Rù»Gqq±X,þÛQ®/]ºÔÜÜ Áu9eee@ ‰"##·oßÞÙæm°ººººº:*­~¢P(òs´µµåßšššÊ¦•””d‰µ´´dAbÀ€²³°Õ^/BÈÀÀ Õ©Tj«UË3113�€nBGGG¾6¾íÝC6!÷€«¸GƒN#���üG 'é¿G  C'��€óÙQ(---ÜI���9ŸN1bDÇoA��@Èù·$‰|c<�@çUUUuáå‰r��}Eiiirr2þæ¡«8r��½œP(¬¯¯744444„Ü�r��Ÿ7䘘˜À4 -hû ���B���9���ÀG€w9È#2÷TÝGˆÅâÎŒÁ ��r>=@"‘úÈÎÖ××?}útäÈ‘pÜ�rºŒ@ h;{/Ãår¯\¹ÒjÄ��€ó_“J¥²ƒz+‰D" áX�>h>����B���9���Àç 97nܸrå žf2™qqq/_¾l7åµk×þøã„P]]]\\\JJJßÉÊšššræo%$$ÄÅÅñùüN¦¿råÊ7à �ô¶³~ýú•+Wâé¼¼¼%K–œ9s¦Ý”¯^½zóæ B¨°°pÉ’%'Nœè;Y™››»dÉ’³gÏ~Ü¿çä䤥¥u¾Çõ+V„„„À �èA>¾ÅZjjêãǽ½½KKKsrræÏŸ¯«««¥¥E"‘êë룣£B™™™ ãÆKHHHOOÇÿ¸hÑ"MMÍžžqçÎc0Ë—/?zô¨ŠŠÊ7ß|#û)%%%11qüøñ/^,))ùæ›oh4—Ë=|øpÿþýçÍ›—™™ÓûùùÙÚÚÒétmmm"‘Èçó8€²±±ñ÷÷G=~ü855Ïüúë¯utt:³‘T*õoûo‰®�@·9)))»wïNNN9rd\\Üû÷ïÃÃÃ÷îÝK¡PUTTB …J¥&$$„††ÚØØ899=z´¨¨è—_~QUUíÑwöìÙ”””ŠŠ “üQ(:::"„ÒÒÒôôôRRRž={“””4gÎÖÜܼ{÷nWWWggç­[·¶´´øùùݸq#55õÇ<}úôË—/.\øÓO?]¾|yýúõùùù±±±‰D]]=44ÔÌÌlÈ!QQQááá 9DbGÙ?ÿüSCC,��øÜþmóCCÃ3fôïßÿÒ¥KMMMx¦ººúÔ©SBVVVÇùòeFFFYYÙˆ#~ýõ×Q£F‘ɽä{ [[Û… r8œØØX<GSSs„ NNN‰‰‰………«W¯0`ÀæÍ›¹\î† ôôôÖ¯__RRòðáÃÚÚZ##£;wNŸ>F£É–yâÄ ¼~ýúï¾ûÎÐа_¿~K—.ýᇂƒƒ bcc›››;¿‘ÜxóæMJJ { �è¥lÈ!FFF§™6mšƒƒÃ‘#GÖ¬Y£££³gÏEEÅÞ‘}S¦LiUŒ077wpp¸víþsìØ±êêêüñÇþýû¯^½jeeåééÉd2ÏŸ?ûöííÛ·[XX,_¾\__¿íÂõôôfÏž§_¿~ýÃ? „²³³ÿéFÞ¾}»Ýùõõõÿ(t�@‡œÎ°°°°°°°´´\¶lÙ;w*++¯]»¦®®ÞG²8""búôé3gÎTWW?vìBHGGÇÇÇÇÑÑ1,,ìܹsùùùGŽé` /^üñÇgÏžíííR__ßùµ_»v­¬¬ Nt�@ 9ñññþþþ{÷î]¶lÙèÑ£7mÚ×™ÿ‹‹Û³gBhÛ¶mÇŸ;wîÛ·o{M¯*'N¼ÿ~ÇiL¥R_¾|©££ãàà€JNN^·nݬY³¶oß.âââÛþcZZÚÊ•+§NJ¡P*++ÍÌÌÜÝÝå«àþ‡ÃqrrÂ/™>¤§¿T�ô¶cnnŽzöì™O]]½½½žž^ÇÿâèèxìØ±U«Vikk_¿~}×®]ÁÁÁŠŠŠõõõ·nÝê5Gž:uÊÃÃC__ÿÚµkYYYJöðáCùûþ!C‚‚‚BCC###›šš~ùå—‘#GÊZ¤¦¦º¹¹ÙØØww÷àà`‰Ä`0~øá‡°°°0™ÌQ£Fµ´´ÐéôŽ7O"‘üm��øÏ455™L&›Íf0ùùù£Fj7@ ujI"‘Èd²X,‰Dd2™D" …B‰D¢  €‹/ è¯>"qb‘H$‹ñ¿+((ümËÝn…B¡¨¨¨ðù|ùž¤}||RRRrssq ¡‚‚‚üþâÌ¡P(øMdzµµÍÍÍÅ9ƒþ·MœL–‡AöA(^BH– E,ãfÍA¶ÀO¢¹¹9..NOOÏÇÇ® �À¿§¬¬,D"QddäöíÛ;û.§í­D"ÉF‘¡P(m“‰D*•ú…)2¹×´RûPÎÈï¯|æ0™ÌÑ£G«©©}(sZå!B¨ÕO­2°ãvÏ��ÐmÁàÉÔÔ”Ãát&ކ„„hhhÜ»w2 ��!|Œß~û­“)Ož< Ù��z’���!��@okU___XXØ»÷Q À�@ÈébL&óÅ‹%%%���!ç3‹ÅB¡ÐÀÀÀÀÀ /쯒’t��„œ®!‘H”••­­­!+��à߀æ��� ä���€���|x—�øÄ”””>m‡³ÅbÁá€R� 7#]Þ[¼@ 8zô( (åô´˜ Ý6ðxinn‰D]µm—.]‚O›!äô¼x£¤¤ô~ ÐÑÑa³Ù�BΧTWWwõêÕ^3Œ)�ŸæÆA&Oœ8ò@Èùô´µµ½¼¼ �¡ÑhD"Q~œ\�:^T���èf¥¡PxðàA¯¾úªóKÏÎξuëÖСC‡ y �—ðæÍù9ëÖ­“MçääÄÇÇ»»»‹D¢—/_N™2ÅÜÜüôéÓµµµkÖ¬‘ ôzg)'444,,lÇŽ'NœèüÒ322ÂÂÂ’’’ £�­Ü¹s',,¬´´”úù_³²²ÂÂÂ?~L"‘¨T*n;zôèѰ°°.lþ£RΙ3g:TQQqåÊ•   çÏŸÇÄÄLš4©¾¾>99yÅŠ¸×ËõëדÉäµk×îܹÓÖÖVþ­û™3gÒÒÒðô®]»ÔÔÔ ÷�þþþãÆ“ýY[[jcc£¯¯çÔÔÔäææŽ5jÿþýUUU¡ 6ìß¿²®×–rV¬X!•J'Nœ˜““³ÿþüüüèèèmÛ¶UWW¿ÿ~õêÕÅÅÅk×®=s挋‹ËÒ¥K£££=z$[ÂÙ³gÃÃÃõôô|||.\(‹!÷�òš››—,YòìÙ3*•zøða<óÕ«WÑÑÑeeennnªªª!ùzaÈyðà웯ºººôôt<íææ6kÖ,}}ý””‹õðáC±X<iÒ¤9sæ´ZBVVƒÁpqq™8q¢ªªêýû÷¥R)ä>�`ëÖ­~ …=¢ÓéÓ§OoÛLtèС8äx{{C¾õP­Xkii>|xKK‹üLccc==½V))Ê_|ÑîBÖ¯_¿cÇŽÒÒRÈw��¶hÑ"WW×V3ÕÕÕa„ª>r&Ož\[[›žžŽûéKKKûæ›ož>}ú+Û¸qã¨Q£þoÅdø$�€ŒŒŒìììðtcc#dH_9555b±X__·'ÑÖÖniiiUÜÁpLªªªj[ÓJ"‘ˆD"FÓÒÒòôô,//ÿþ=D�€H$âóùò·©TúðáÃU«Vµ{“!,kòäÉÏŸ?‡Üë…!GKKKWWWÖ/,…BÑÕÕÅÓ***!:®««K¡PÒÒÒ† 2uêÔ„„„¢¢¢®®®ŠŠÊÆ…B¡¬ÑýË—/!Þ�ÐÇ©©©éêê®^½Z6''''--ÍÛÛ;&&&22rݺu***$IWW?ò&&&Ž1ÂÛÛ»Õ= § hjj2™L6›Í`0òóóe_¡°°P(Z[[çç绸¸xyyÅÆÆöèÜ!‰\.÷É“'Ðá �òp‡7ªSVVVPPàp8]Û“tssóüùóá`u-eee@ ‰"##·oßþ);¼Ù±cLj#^¼xñöí[UUUÈn���2Ÿ²vëÔ©S .<pà�Bè믿ޱcä/��€ÏrBÇï}yD$»É¨º���!§7SVV¶²²RVV†¬���9Ÿ‘T*¥R©–––í6 ���!çS†6�|œììì.Ä]þ[�!�Л½~ýúõë×\.· ·Aö5!€�èµø|¾ººz—Ì!B� ÷‹Å "d���9��� ä����ÿÜÿ¼Ë!D"!���ŸF«FÿrÄb14f��ð©ðù|<^Z;!§ªªêÎ;G���Z!‰1ΉDrrrÒÒÒj'ähii9::BÎ��h…J¥‰ÄºººÎÿ á—ÓNÈÁ¸\nss3ä/���„™LÆ_YUTTäææjkk·JPPP`nnÞ¶|ƒGŽþŸEµ]zcccyy9ä2���„ŠŠŠìÃÞþýû;;;·*ý”””´ílBQQQ*•¶š íÓ���|<*•êààðîÝ»Î$†��à#)**[[[UUÕnr†ŠRUUµ··Géë뛚š"„¬¬¬ÚVv-MMM›^êH$77·ž²µ:::Llhh8`À€±_¶¶¶t:½‡žB²«¸“,,,FŽ9räH55µž² C† Á·kkëžu€ìíí;:B¡ðx<|•¥¦¦v߃o|>¿7RUUUWWGUWWs8œîÆe-üz1пÿž²µ***šššLL£ÑzÊ}¼¢¢_À=‹Åª­­ídbsss…¼¼¼¼¼<{{ûž2ð®H$*..F)++÷¸ÛB¿~ý>á•””ˆD"nF&“;óÀñ1=Iëéé}ñÅ¡ÜÜÜ‚‚<søðá4M*•Þ¾}!¤®®niiYQQáààðþýû÷ïßãdÆ SWWðàl‹---KKK D"‘X,–ŠŠ “ɬªªB;VQQ‘Ïç'$$àüÒ××g³ÙÌÌÌ,))ù|ÇÆÛÛ[*•Þ¿_6ÇØØØÎÎ.;;»¨¨Ï9r¤ªªªX,¾{÷.BHKKËØØ˜Éd<¸ƒœéÊÊÊ£GÆw´7oÞà™8Æ$%%µ óm±››[vv¶³³ó“'Odí»Š¶¶¶££#…BillÄ7,CCC„Г'Oššš¼¼¼dNWW×ÙÙ—ýÙlviii7,899äææâqQQQ}}=>ùB')) ?Eâ*Ï}òw™Löööf³ÙOŸ>ÅÇEII)77wðàÁ²båÇ[ZZ¨Tê¸qãB555/_¾Ä§¢D"Áßž;99‘H¤®Ý%%%ggg¼#FFFÊÊÊ999ƒf2™ÆÆÆZZZ=âñx ÅÖÖ6##cÈ!x:++ËÎÎÎØØ8--Édþ›j``€¿f‘ÝŽ†š‘‘áææF&“ñíHv"„¸\®üÉO |}}BÏž=û7U#\.W"‘ „ˆD¢¢¢brr²‡‡Ç§,åhkk›››'&&&&&ª©©á°æááQPP˜˜øäÉ“ &àsÑÂÂbÀ€‰‰‰JJJ¸ýÜСCKJJ½¼¼p/d2YMMÉd¾ÿ¾´´´¬¬LEEÇá±cǾ}û611ñõëמžž¸H;pà@ ÄÄDmmm|—ùLñ&55õåË—^^^²2™¶¶vbb¢†††‘‘Ž7999‰‰‰/^¼?~<.`ZYYéééáœ111Áñ&???11ñéÓ§8gº¤*`Ĉøq8„ÐàÁƒ¹\.ž9tèP|w“b333Ù!Æ;¢¦¦æåå•‘‘!‹»üN×ÐÐ]QQQ\\<hР––¼µîîŠ)))>>>xG,,, ‹ŠŠ*++»áS§‰‰Ibb"…B±´´ÄÅ} …‚zñâEbbbjj*FÑÉÀÀ�年ŽÎç;ùÿŸÄÄÄ‚‚|—¡R©¸°’——‡7vN$LJçÔÖÖ⧇ãͰaÃÞ¾}Ûåf‰DYQ˜J¥*))áÂôðáÃ+**GM&“ Ng³ÙÕÕÕùùù”H$‰‰‰666ÿÁx ºººFFF83e·#æííýúõkÙíHv“H$*•*¿ &à%”””àw÷ K&“q¼‘Õ=àƒû)K9$‰L&ãó###·SRRâóùÍÍÍAÖ»¦¦&-- ß¡ðU¤¨¨(š››ïÝ»7uêTù²*ŸÏ§P(B¡Pþ¡£¥¥¥¹¹Y"‘àÃ*//ûö­X,þ¸ï`;ÿ¼Ããñ„Bá£GðƒñæÍùõ>{öL"‘H¥R …"«¨ªªzõê•X,&ò»Ìår‰DbWUEEE|È q°WPPhnnÆ3q!@þS(ü“lGp¢®®®m«Çÿî™I( *•ÚÒÒ‚GŸ¤R©¸4óìÙ³Y³fÕÖÖ>~üX, "‘(vuD"?'fgg·ÊX.—K&“ÇwëÖ-Ùu‡wOw‡íWRRâr¹<¯ÕÓ=ŸÏ£G~þü9Ç#8%>v²çàææVZZZYYÙΫv¥§§———K¥RùÇ2|ŠD"@@¡Pø|>—Ë}þüùð@VSSSWW‡W$LLL¬¯¯'“Éø>#»QgggËo¹,6àᢢÒö×ÎßXš››åw™H$r8œ´´´‘#G~ÊŠ5ù|ïàW‰Dò¡}ñw°ÌOèúõë“'OFɪÂÚ®—H$zzzªªªYES»›çé鉺Cÿuò$Q‹Ý=ï ÎÎέzÍ ‰b±X*•â‰n[·^UUE¡P¦M›–ŸŸŸ‘‘Ñê×€€€ØØXùª]<]QQѶÿÚµkÓ¦Mc±X‰‰‰­~9rdVV~µƒz¦M›†µ‚d2ÙÑÑ‘Á`tó¯�ñ‰ÔA‚wïÞ999M›6-%%…Á`|îk„@ ;99áGù””Ùåù¡K¾íUO d‡¿Åø¸"NÛ{šŽŽŽ–––P(”=ª~ÊC¥R¥R©@ ø§ÿØÍ¨¨ªªþñÇ ¾¾¾×¯_o7͘1cž?Îb±Èdò¤I“ðL …¢¨¨ØÒÒ"Ÿòþýû Ýd¯) ‰Djµ…=ÝË—/ñ '•––uuuWW×K—.iii¹¸¸¼~ýºÛn9™L®­­½téÒ Aƒ¬­­³²²äO¦¦&ùÄÅÅÅÏŸ?Ç¥ÒnG/]º¤©©9räHÙ Z<_(ÊodKKËåË—ñ.㛑›Í.++ën_Åÿè6˜™™ùúõë±cÇòx¼Î7 ø8zzzúúú—.]Bá¶sSPPhÛd@*•â%H¤Vun {Ëå¶窫«+**Z}.úñ!G(¶´´àvÌýû÷¯¯¯/++c±XªªªD"‘@ tЛÍVQQ‘J¥m‡%WRR’U !„étº’’…BÁ·ìÿÌ_|‘››K êëë?”¦±±QMM ßÁY,nn§©©iggWRR"•JñmÅb©©©‘H$0xðà‡vIɆÍfãC¦©©I&“³²²š››) žÉf³åŸƒä±D"é¶ñIQQQYYY~Gììì^¼xáíí uuueeeŽŽŽ,KYY¹íÓ@—£Óéæææ¸¶³UC5ooïäädmmm±XÜÐÐ „B!ÞMcc㊊ŠîðjÊÍÍíÍ›7ÊÊÊ,K~>Îs„¶¶6¾ˆñÆ«««+))á"ªªªì‹ˆ†††®£‰¤©©I[[[CCÃÜܼ3 4UTTôõõjjjpmüçÞN@ p¾‰Åb …Òn#4¡PÈçóµµµõôô [ÝÊêêêðTUUµ´´ÒÓÓÿé¥G"‘>TžÓ×××ÐÐàp8íFîrêëë qË™‚‚ü’––æâ⢦¦&•Jñ]U Èv²©© ‰ôôtggg33³'OžàO@„B!~(hnn0`€ŽŽNcc#¾ö’““‡ †[¬áf$---²ØÃb±>_[Ò¤¤¤#F „ž<y‚+Ää׋ë@SRRÜÜÜTTTD"ѳgÏ\VVV]]]YYiooß6g$I—ÄœÉ/^¼À/ «««333B999ÄÇ1%%w0Ž‹ØíâÚÚÚnõ.„Çã‘Éd==½¶;"/Æç —ËÕÓÓÓÒÒb0+êšæ�� �IDATÝ*äÔÕÕ‘H${{ûââbÜô¨¾¾WVTWWÛÙÙ!„8NjjjMM N‰ÊÍÍí&M!?~<räȦ¦¦´´4|ãg—ÆÆF]]]|!óùü'Ož >ŸHø3õ¦¦&ü¬†Âo}ºöŒzõê•««kMMMjj*~ü•ÝŽð‘J¥‰¤¦¦ŸZ!ƒ÷ïß[YYÙÛÛ¿}û¶UèýjkkegÂû÷ïUUUi4“ÉÄ©TZ]]-—””àFkòWñÇÇŒƒohÿ4Þà&!---´\­¯¯çp8í~aIÐÔÔd2™l6›Á`dff:::VTT@kW൲²ÂíY� kë�h4ŽŽNNNGö¥ÊGPQQ±³³£R©UUU"‘ÈÒÒOtü_t:D"ឤ###·oßN†c��½ …B100À¶Åbqccã§Z²X,®­­íL9›N§·ýBÎ'ÃápºÉz�€>®©©©¨¨TWYYù ¿Q•J¥ffffff›’L&·­‡ó)CNwëª�Ðg±X¬·oß~òÅ’Éd‰ô·µjUUUD"±_¿~rA«Ö™����†?Þï8MEE…BéTȉDFFF¸…ž‹B¡”””à}é>;" {ôŽÉä²²2@�;Ò}v¤¼¼¼¥¥×#ÁŽ|Z¸óˆOÕ„½ýŠ5uuõžÒÙû‡P©T6›- {úŽ(((455ñù|Ø‘î³#ÍÍÍ<v¤ûì—ËÅZôôáñx§[í‘HÄã~~š¥A!��ÀÀþQêÜÜܯ¾úªÝŸ>ëwv¯^½ n;æÌ™Ÿ©Xcc#c\.Tõ©tŸqÒŽ?~ìØ±î°%ãÇo·•çÑ£GOž< —1øh&Lè Ã”z;ú .ìÛ·rûŸ…œ¢¢"//¯Û·o/^¼¸m¿jõõõ¸²Çãɺ{Á=­ÊÒàþV¹\®¬§‰DÂårqŸ¬ú¸ÉdšššN™2¥ÕMG |õÕW>ìL%£lÕ!Ùæa²Uã.Ÿe›G§ÓãââB¸+â¶Éð‡ÖR©TÖ«’X,Æ?µ»/<O¶¿ò{!¿4„н{÷pÎðù|±XüÉ¿ùÇ;" q›Ü 3Îùƒ‚ûüîò.åù|¾¿¿ÿË—/å7knnÆ3ù|>î›;ùïØE"ÞAù66<è^ÖÝèøÌÇýÉŸ uuuø„—3øz—]ž²Û >gð´½½ý¯¿þЧñ¹\®üÏ‘]\.š³þ³Ãårýüünß¾íææ6kÖ¬°°°v“‰Åb;;»´´´ÀÀÀŠŠŠóçχ††âöo ÁÁÁ......ÙÙÙ8ñÓ§O]\\Ö¬Y±k×®V‘¦¢¢B*•êèèỿ¼åË—õÕW­ºnW}}ýüùóñª‹‹‹™LæôéÓqœàr¹'Ožd±Xk×®Åi^½z%‘HÆŽ‹zôèQPPPTTTdd$‹Å ÁÉRSSå»&ãóù—.]Â?>|¸ÕýQ$ <855ÕÅÅ%88÷ ÓÔÔŠÿåÑ£Gø2À}ÄfddL:566v÷îÝŸöŸ:ujëÖ­;wî¼yó¦|Îàœ„BáÝ»w]\\6mÚÄf³»ü7oÞ¶mÛLLLdÃ&µ+(((>>~Ú´iþùgQQ‘¬W’3gÎà<qâ¾­0™ÌI“&¹¹¹eeeá^X@_põêÕo¿ývïÞ½...111²xPUU5tèЉ'âWâããCBBðOëׯÇçÌ„ †Š;…JOO_´h~èùõ×_ñ vóæM«ªªª\]]]\\æÌ™óE(9!D$MMM ¸\®µµõŽ;>”’ÍfïÛ·oÆ nnnEEEÆÆÆ¡Ã‡/Z´(33333sÊ”)"‘¨¢¢bË–-™™™3gΔ¯À)++ËÌÌ\¹råÌ™3?ôZYY©¦¦ÖÉq¼W®\¹jÕ*¼ê±cÇöë×ïàÁƒëׯÏÌÌ<wî‰DZ²dÉŽ;<==qšŸ~ú©UÀxúôiKKËŠ+~þùgwwwœìСCò¯ÔÔÔ[·náŸØlvÛÉb±<˜™™9kÖ¬ï¿ÿ牱±±l¥x€[™wïÞeggoݺõ“õË—/ÛÙÙM™2eÅŠk׮ŀ‡ ÍËË;räþ3::ºËOPcc㪪*@““Óñð…[·n=tèÐÌ™3.\xáÂ< Sjj*îV.333''çÎ;¡™3g?~üíÛ· .„[@ŸrûömmmíÌÌÌgÏžÉ\X¼xqzzúéÓ§eýù·pöìÙôôô%K–ÈÏ?sæ ‰DÂ'XRRR~~>BháÂ…™™™Û¶m[¼x1d»¼Î~ ª¨¨xêÔ©3fíÛ·oÙ²eí¦TWW?þ|ZZÚСC·nÝ*‹%[¶lÉÊÊJNNFmÆË3fLHHHqqqqq1ƒÁ¸råJnnî¡C‡>4’viiéñãÇ'Ožìîîþq»mff¶xñâáÇϛ7ïðáí~ÅÑB¾ïUooïµk×¶JvîÜ9ü˜#›S[[‹w°¼¼¼m3G ˜˜˜Îo¤‹‹K¡ýߘ?þ¬Y³ð´l ÏVƒjøùùvy'ù{öìùöÛokkkCCCCCC;xÑuäÈüEô­[·dݰŽ9ÒÚÚ”Vã‚‰ÄøøøÎ¼®½ÆôéÓÛ>gܸq£Ý!‹ÕÔÔpß”ŽŽŽ¥¥¥üñGç*žˆÇ§Ž@àcBŽX,~ûöíáÇ7lØ0vìØƒ<x0''GYY¹“ß‹¼yó&&&-Õ¶R{ñâÅÍ›7‡>vìX--­-*::šÅbq8œøøøÆÆÆG¶Ûƒ÷‡455åææNœ8QSS3;;{àÀŸ$7 ûí7<ÝS>£¹ví~ÜÃCÓw7©©©[·nMLL<þ¼³³saa!‹ÅÊÉÉéd#‹ªªª¸¸8<Œ•üh4�|ˆžžNÏÉɹpá‚••Õ°aÃB‡Z½z5ƒ ^ìÞ½{gÏž•J¥,ëC#•AÅÚßàóù«V­j53666!!¡“K8zô¨§§gtttttt«¾ÞJKK_¼xš={vtt4™L¾sçÎ… ¢££ÛíVÁÁÁA,ß¹sçÎ;,+))é½cçr¹.\`³ÙÑÑÑ&L¸zõêŸþÙê.Ü™qçnܸѪÞÏÕÕïàºuëÚ¶¬oii¹qãFw;¶lÙ‚·ÙÇÇG~~~~~wÜ,<<¿&×ÃÃÃ;ùïéééyyyxñ›9Ù(U ïÈÍÍÅC'tÀÕÕÕÌÌìâÅ‹ò3ãããwíÚuüøñåË—è>|ˆßŸ>}:::zçÎçYÊ¡P(3fÌ8þ|EEEnn.¾z‡úæÍ\15vìØŽG½ôòòÊÈÈÈËËCÍ™3çøñã³fÍ;vìáÇ[ZZª««õôôpJü^."""77·Ý“'Nœ8qâD<íéé¹mÛ6•V=qâÄ/^¼zõ !´`Á‹uêÔ)\òuwwùòå½{÷F››‹÷¥¶¶¶ÕýWføðáYYY8Y]]ݘ1cdcÍZZZâŸ8NÛG!±XüêÕ«’’>Ÿïåå…rss{ùò%þ—#Fàn_ÿK'N|þüùË—/B¸2JKKËÕÕõðáÃ<¿ïZþþþIII,+** ŸýúõsttÄ™&‰:n?bff¦¯¯kkkãáfΜyíÚ5‰ݰö5 ·nÝJJJ0`@_øÛÙÙáž’mmme•l¿ÿþ;‘H ’Oéè蘔”„O°ÆÆF+++|;räBH(:99ݽ{r^†¤¤¤òÿÚ»ó¸&®µqà3ÙHز%€ AeqC«¨ VĪx«X«Rë­mÕª­z­¾zk]°ZëµµÚ~¨u«— Öërk­â¢,j�‘ D„$däýãüÞü¸€láùþÑO “džs2óÌræ<ë×kµZ…BQUUåîî.“É F“¹qÈdòˆ#RSSÅbqllì¬Y³0 0`€Z­.++#bÉ’%\.ÇqF"‘œœœ D"‘¼¼¼x<ÞàÁƒ+++««« ‚X½zunnî„ œ››+|||êêêÐl󱯤I“Èd2ú'ŽãNNNMs&…Ò¼ü…Byñâ…Ñhtss –J¥¨ìà§Ÿ~J&“Y,–yWE"‘¼½½'Mš$“É*++ ‚X±b˜Àd2‡ †ã8—Ëõ÷÷Ç0Ìßß¿¾¾¾¢¢‚ ˆ¥K—:88à8N§ÓGŒáäääááñðáC‚ "##ïÑh<tèСC‡²³³û÷ï?{öl Ãüüü´Zí³gÏ‚X¼x1js …2jÔ(ÇL&“«ªª‚h>[Q'OlI$///tÝUp2· ‰D²··ïß¿¿P( ™6mÇóòò²ÌO­S„††J$’k×®…„„üóŸÿÄ0ŒÃáøúú¢[PcÇŽ GÈáp¨TêÈ‘#Éd²]hh¨«««““SQQAÑÑÑ4ÍÍÍíõ×_ÏÏÏohhX¹rebbb“Âí Ä`0 d½xã·¡@Pñ±Öyøð!‰DŠŽŽ.))™9s&ºœN¡P† F¥RqG¿ Ã<==³³³©T*ÚNÑî(//O«Õ®[·mDhwÄãñH$RII AóæÍCS?þöíÛƒÁÍÍ-&&¦¢¢"00ÐÓӳ͋í(NgU=‚ã8…B‘Ëå E©TF6ïòVUU‘Éä~ýú‘H$‚ ŒFcNNNjjj %ÚÄb±ƒƒªHØ„L&ËÌÌ|ã7,uÄqìØ±µk×bvüøñ’’’-[¶Xª™ètz^^ž^¯o1îg0ŒNò:„F£hµÚ   ^½_x•@Ξ=;sæÌNioÑ7ß|óî»ï:;;×ÔÔL:äu(‡ªÕêàààÞÞ#6Haa¡J¥Bµ2_&)));;{÷îÝm~`ffæõë×§OŸÞúvE =R*•Ýü½m¤¢ oÌ%Ú†Þæ´žT*588ø•J´9;;[*ß ¬àììŒðùüØØX8ë-²ìo#44tË–- 4­ÉÓ`�dggÿñÇsæÌéíyÖ©'ëå°X¬9sæ SQOOO@`à M&“= ?8k0iÒ$&“©Ñh¨T*< ÚwL˜0]7kÏÛo¿mÛ»#«K9t:½õ±�–Âf³cbbºâ“Ñ]ýn ¤=¦M›fØ@DEEÙÒO iO í “Íf·§äe×B£Ñ¬­GÚ,Èöª)''''//¯·§StµÑfi2’éñ@ « ĽB )Á¬‡½½}{N;Ÿr ÔÛÏ+étúÇõz}óAn½ º£¨Óél#­Vk©o{0¢¢"Fc¨ÕjóPàÞˆH$jhh°@T*•• zBÐð&“wX8åÉdKêÁ”C¡PL&So„F£Q(‚ « Ķ…B±ž@¨TªµõJ9û´6—@Ý4].—·XÂÄ‚ž>}j.s€aXCCƒD"‘H$Í¿W*•JþO“l\]]æ×yY –¥P(OÎÖ!è ´Ô2->\WW'—Ë¡}À«ü´:±Ñ¡§×;´[0Ïû×ǵ‘r?~<cÆŒëׯ7Þõ#?ÿüs×UÇzüø1š¬Þ<›J¥JNN^²dÉ’%K~üñG4͸Ùĉ—üŸ¯¿þºñŸ¶nÝšššŠaØçŸÞ ½ž’’²ÿþνwÓ¦MPT£¹¢¢¢èèè[·n5ÿÓ‘#G¬aºkÐ{Í™3§Ljb±¸C›yRRRóéƒû¦ÖIçåå<x°ªªjß¾}$©ÉUfùùù^^^b±888˜N§§¥¥™žVVV¢zþþþÞÞÞèÅ;wî444Œ7.++ M™×\bbb^^^ãz-ùùù/^¼ví†agΜÉÎÎn2�쯿þ2Ï=Ó¢¥K—¢q Z­MƒÏårÑCpÅÅÅt:½®®ÎÃÃÃÙÙ9###,, M.[__Ÿ““ƒa˜——šÍ¢°°ÐÕÕU*•Êåòððp4¨R©ÌÊÊruumñ«ÓÓÓÃÂÂnß¾Íb±ÌóQ>{öìñãdž <=lüÑG±X,ƒÁ••”íææ†Êç¼"µZf±sssC—‰Åb±½½=šdèÎ;Æ £ÑhÍ[æÉ“'L&S&“UUU9²ûÒ<xðà‡~Éd{÷îÅq|„ /û­òx<‘HJ¥R333Í?­ŠŠŠGa`žI!##C£ÑŒ7.''§Óó‘ƒÞ¥²²R.—Óh4‰D2hÐ ó [†¥¦¦Òh4ô›©ªª’Édèfö£G\\\Ðvžž®ÓéÐ )<Ï<»D"AeGBBBÌ“_¿~Ã06›=räHhùö¦œ]»v­Zµ*''çÈ‘#_|ñÅËRÎÞ½{  “ÉD"ƒÁ¸zõjCCCTTšÄ÷þýû† 2$66–Ïç߸q#99Y©T–——ïÞ½[(VUUݺuËÏϯñ¾uÛ¶m†5K*•¢‘Íï¥'''£Iq—…ÎËË3Ï£µzõêß~ûÍÍÍí·ß~C³‘öë×O§Ó1âäÉ“UUU‡Ïçs¹Üëׯ£™¸”JåÙ³gÑll¾¾¾sæÌ<xðþýûÝÜÜT*UmmíóçÏçÍ›§ÑhΞ={ëÖ-www•JåèèØdÝ–-[¶aÆk×®ÙÛÛk4šˆˆ©Tš””„òñСCçÎëîî¾jÕªÿüç?T*uÑ¢E›6mº}û¶‡‡Žã¯8­N§ûí·ßÐ6àéé9gΜ¡C‡;v,((hþüù¨eÎ;ÇårÍ-ãîî®×ë‡~òäÉšš6›]QQQRR2oÞ<‹Õ?Ðøøø7Þ½{÷øñã[¶lyYÊùòË/ƒƒƒŸ?þäÉ …’ššªV«'Ož\^^ž””„fr š;w®··÷µk×RRRž>}ºÿþŽÎ>�z©›7oþòË/aaa"‘ȼÑavñâÅÛ·o3 F3iÒ¤ŒŒŒk×®íÛ·ð„„„É“'ÇÄÄüõ×_)))¨¸ðo¼ñèÑ£}ûö>}Z,Ÿ={;Ž5jîܹÎÎÎ.\HIIÁ0ÌÁÁÙ@ã·+å¼þúë999uuu§OŸn½pwAAÁž={¦OŸ¹cÇŽèè訨¨ÚÚZ—#GŽ`¶qãÆŒŒ >Ÿ¿sçÎï¾ûÎßßõêÕè½uuuiii>¼wï^XXX+soH¥Ò³gÏ–••=~üØd25/´páBtxÎd2u:¹ŠD"irÉÕh4ŠÅb´V/^<vìØˆ#Ðáü_|±}ûv6›ê¾õÖ[•••§Nºzõ*†a‡úý÷ßјÂ¯¾úÊ××W ÄÆÆÊd²#GŽÜºuK(nÚ´©Åãšììì#GŽˆD¢U«VEDDdddTWW£ÕøðÃsiµÚººº#GŽœ;wîĉMfì(•JõÍ7ß sµ{÷î·8&AOž<A«táÂ…Ÿ~úiøðáæ– ŒŒœ<yr7e˜:ujfff}}ýÉ“'[¿”‘ŸŸÿ¯ýkâĉ3fÌøì³Ïbcc'Ož,“ÉÜÝÝ?ùä ÃÖ®]›••åííÿÓO?ñùüU«VÁ. O©¨¨:tè† –-[€6º¬¬¬ƒ–——/\¸ðeÖ[·n=}ú´‡‡G|||ãXþüóO‰„¶šC‡)•Jggç»wï>|Çñû÷ïoß¾RN{SÎ{ï½wüøq½^ÿüùóï¿ÿ¾yñ‚ÆGñèºY||¼¹Ž�J ¨lQnnn“Ý\||<ºJæïï¿wïÞÜÜÜK—.]ºtéÊ•+111hÍ&´ZíÀ×®]»sçÎÛ·o7N9æRf÷îÝ‹7§œ˜˜˜²²²ÆB¥R×®]‹Öª¨¨È\eûc¶fÍšVJõ˜[¦ÅihCBBÞzë­âââÖÛß+ÎÎÎÍ+ÂYİaÚ\©;sæÌŒ3ìììh4ÚêÕ«Í-cž)566ÖRCò;áƒ>8zô¨Á`¨¨¨øþûï[™:~ÅŠho¾i‡N”QPB¡püøñæåqß¶m”hëSÆ׼ǷnÝjž>¸1tÝ]N_´hÑ™3g(ÊÖ­[[ù­šwG_ýµÉdBÓQƒÆZ>pòäÉÈÈHWW×5kÖ ÓÌÊÊÊöÏÚ"‰’““ét:No±G›œ| g èt:‰ÔòZùûû¿lª‚]»v5àÐ"½^¿gÏ´V}¹zÒ´iÓ$É£GPý]{{{N·wï^Ô2-Iì?ÿüsTT”³³óºuëPæ(++;~üx;ß^XXxþüyÔË~W�46dÈ//¯+W®üõ×_^^^èþ|àêêJ&“Û3+è®]»h4NïPÝHH9ØÅ‹QO³êêêäääv~tii©T*]¹råÊ•+›&oذÁœ™V­Zuùòe@0sæÌ•+W0 £a>|¸Å×SRRÐmóÆ—’’’ÐZYpŠRäþýû§OŸnñOæx{VNNί¿þŠ÷ž={&‘HÌ2 gÏží¢–é´óçÏ7¹4úâÅ‹VŠ7Q\\\QQ‚jrkÐd2mܸv}Ê7.]ºÔú2 pssËÈÈhüâ—_~³lÙ²V޹Ð8‚ÇôÑG+W®|ë­· Í›hí`víÚµ'Ož,++[¹rå0 ãñxsæÌ‰‹‹Ã0lРAæ1- ‰DhááÇçåå ‚-[¶|óÍ7õõõ³fͺ}û6ºˆÍçó[ŸA= `âĉèÓ‚ƒƒQ‰³={öÌž={À€ ‹-2™LÎÎÎwî I¹*•ºmÛ6ô9ÞÞÞàÔ©S/ûRww÷E‹¡…Þ~ûísqqYºti\\Ç{ÙcÑ‘‘qqqh/++CŸ<f̘.½reooÿé§Ÿ¢ïòññAC0 [ºté©S§æÍ›‡.ŠÒéô-[¶ Åx<ÞÀ_–>»ÓúõëþùçÊÊÊeË–¡"ßýû÷Ÿ6mZÏ!C†¼ùæ›­¼Õ®F ‡……eeeùûûÇÇÇïÚµK¥RMŸ>î}„O^^Þ©S§^{íµVÆ‚Nœ8ñ—_~ÁqÜ\Á+<<üþçÔjõ÷ßßxÉèèè_~ùýÀ"##ÑС„„„wß}펦OŸþÝwßuó kÖF½œ¼¼¼¸¸¸;vLŸ>]—ËåhŽ,///t?£¨¨¨_¿~ŽŽŽ999C‡5yyyèÎsUUªãçç§R©¸\®““Snn.*Ñ1nܸ֋Âfgg6Ì|QN&“¡©‡ø|>*óüðáC‡Fî¢qeæ¹€ÌõrP‰ggç{÷î 2„F£étº¬¬,”*œœœÔj5*³æîî^PPàããcooçÎ4šY¡P •ôðð@“ý=~üØÅÅÅÙÙð»w…á8®R©îß¿oþÀ&wzBBBÒÒÒ„B!“ÉD-ƒaXyy9:É@£0sssƒƒƒI$Òýû÷Ñ †êêjµZ­Ñh^±^ŽF£AÃ\]]ѵidÁ‚ü±y”°V«EÃ·š· †a< ìôsÈ®—# çÏŸ¿wï^s©Öºº:4-˜··7š‰¼°°ÐËË‹Ãádee1Â`0 }Jee¥X,FG¯r¹Üü[Õjµ�êåôµz9+W®”J¥þþþ¨T Úè¨TªV«-,,4ßrÞ·oŽãhà‰yw¤ÓéÐ@j´ÃD·“¥RéÓ§O1 <x°¹°¯ywäããSYYéàà ÕjÑoµõ@l¾^NÛ%Úž<yâããc©‹ûË–-Û¸q£B¡o³y§YU‰¶ôôtTi´ÛöÔmúâ‹/ú÷ï?kÖ¬î9{•@?~Ü¿ÿ6ï¶Ó’%Kâãã===¡D”h{ÙåÜ,_¾œËåvs P¢ ëÄ•VìØ±#..îéÓ§,ëÏ?ÿ„ÓÌžòÕW_yyy½ùæ›Íkx[¡G0vÚ—_~9þüŠŠ ‡6¯ìƒ¾æÊ•+·nÝÚ¼y3‡ÃÖ°¸–SNëñ¿ .—{îÜ94ºŒÉdö‘V¾{÷n§÷ì¨/,Þ#kÖ¬!‘H–:oh ÖÀÕÕõÂ… þvQt?¡CáÌž=ûoû[›Ÿ3yòä‰'öåá¬=rH$R×µx÷ô¥ÑhÔëõd2Ù~:¯²F£Q§ÓY¼Gº¿Y G¬UõÈ«0™Líé‘v†Ùƒ­±ÂQ«Õ]›r<x€¦¥êÕ‡<Z­Öd2ÙL EEEˆõb4ÑÐÄzAÏ@ Çf³-uïå”dU5‚:Áª†¼Š®>�t:>`m´gø@¯Äš‡XæÓ0��� Œ˜ú0��ÕIDAT{4���H9��� å����r���@Ê���)���€”���R����)���¤���r����H9���lHË3I“ÉdKUžî±\J"¡ÿöö@P5èôôôHïê´/íÚ”S___QQÑÛÓiMM ‰D²@ª««m#ššÇm£G0 ³1™L¶Ñ#F£Ñ©ªª²@:–rªªª Co?^¨««3A@ ÖA¶ˆÁ`0½=ÚÚZ[ ‡@, Çq;;;ww÷.L9¾¾¾P¢ÍJ@‰6+ J´Y[ P¢­ë@‰6���½¤���r���@Ê��� å���€”���R4���H9��� å����r���@Ê���)���€”��À–´<“4•Je0½:0TìˆB¡ØF Ð#Ð#Ð#HÀq¼ËSNii©Z­îíé´²²ÇqFXU Z­ÖÁ0Ìyñâ…ÉdÒét¶ˆ^¯‡@º•Jår¹]˜rètº]¯î9*•ªT* XøÊ�…¢R©t:X<††FcUH$&“Ùµg9...ìÕG§ÓµZ­^¯ïíÐh4N§Õj!ë Ä`0¨ÕjÄz!B¥RÙ@ F£Q©TZU P¢ ��@¯)���¤���r����H9���¬š���@û©Õj¹\Þæ2T*R��€Î3%%%"‘¨Í%=<< å���è<‚ @ hsIôà¤���D"‘Z¼bÖX}}}ee¥›››½½=¤���¤×ëu:Éd"âeË”””Ž7®yÊk���,F.——––º»»·x/R��€0 d2•Zh®¾¾^£Ñøøø´øWH9���:† “ÉÔâ)N~~¾ƒƒƒ››[‹o|iñ‚æ×àzTVˆF£ÙF Ð#Ð#Ð#H&˜æ¯0 ½^ßäOÆh4½ì£ZH9þþþÇJ´ñù|Çm X[ †ÙF &“Éñöö¶@¼¼¼¬0KÆ¡A_Q(éééÇÑѱ)‡ÅbÑéôVF#ô¨˜+XN‡@ ¾ˆÑhlñE‹…Nķ>T*uìØ±­|ÜË��ÐjµÚœoÔjõÅ‹Édrë%D!å���è “ÉdooO"‘0 C…À§M›Öú[ å���è$¥R‰aAçγ³³ksyH9���:ÉdÊd2ƒ1eÊH9���ºJ¥ºr劻»{{naÄšÁ`Ðh4ÐŽ���°ÿ±F&“›OëÐ| ™Ln×LÒZ­V«ÕB+��hÌÑÑ‘ÃáP(MÇ„ ZLTA4™‡Ò$)µçþ��€¾†L&;88`|šF£½4åP(•JUZZ ��ÀŒÃá´§,[›šžÉd²úúz>Ÿßæ;Ñå<Ç›Ÿd��èfjµºÅ©6_†D"1 ‚ Ú¼“B"‘ÐùåS†aÎÎÎþþþ­Ÿ^1 ‰D¢ÕjÉdj~��@·¹sçNPPP“«Xm&‡ƒvà¨ðZ+û|&“‰Á±|Êi}Y,ÊŠÕÕÕh" ´ºÐå��ÐS¤Ré Aƒ:ú.‚ Ôj5…Ba04M«Õvõμ½)Çq{{{£ÑˆÎÝŒFc‹½��è-Ð)Az½žF£1™Lƒ¡V«»îÂU»R›ÍÆq\©TšL¦]+��`ý‰‡ F£Õj™L¦ÉdR*•]q^ÑFʱ³³£P( …’ ��Øvâ1™L*• Çq;;;6›aX}}½e÷ü-Lx£×ëÕj5Fãp8F.—FÈ7��ÐGrR©D{~6›M&“-89@ g9ÅÅÅåååîîîööö0��ú ²²2NwéÒ%??¿6«t>å‚aÆ …Âôôt@Àf³¹\.ªˆ���ÀæÕÖÖêõú«W¯:::òùüÈÈÈ.<ËABBBBBBrrrJJJú÷ïO¥R½½½¡'��À†ÕÔÔ444dgg³X¬~ýúMš4 Çq ~~ÍFŒaØ;wÐôÒt:ÇãA¯��€‘Éd2™L$‘ÉdWW×#F´^RºKR2zôh£Ñ˜M"‘ ›Í†Ä��¶A.——•••••Áår»è»Ú;4€D"5J£ÑÕÔÔTWWWUUyxx@o�@/¥R©îÝ»W[[«V«½½½½¼¼¸\n—~cÇF£1ŒÐÐP…BñìÙ3óH6±Xüüùsè<��è)*(`ÖÐÐPZZ*œûõë× ëÙBÊ¡R©,«•÷ ÛJr¹Üd2Q(.—K§Ó¡Ë� §øøø8::6©‡Ö:Ç©Tê¤I“Ú¬!mÁMSÇ3™Lí™Ù ¥%µZíèèØuþ���´G禾tqqiÏßR“ßPšœßtϹ��€¾€L&7.‹ð_)§¤¤ääÉ“ÐF���,e̘1nnn-¤1cÆ@��°t Æ|]î¿RªK m��À" †N§3§˜9 ��@7”�� ›XKa‰dý“U÷ÍòÛVÒ5]Wת·ÏÞV:¶è—Þ‘r(JëÏŸö¸ºº:•Jegg××6'ƒA£ÑzvJJJ8N_« ã¸½½}/Za¹\®T*ûà6B§Ó­ùqøêêjƒÁ`%÷é­ëŠ ‚ ¬°Ïêëë³²² ưaÃúæé°^¯ï©Ê°R©ôÚµk³fÍꛓ\´óÑì§P(²²²¨T*š~¶+!“É233=== å4¥Óé,XñÔ²{½¢¢¢ÐÐP¬¯Òjµ=ui+33³¡¡¡Ï¶¼Ñhìá?}úôÑ£GÁÁÁ}¶§t:ˆÅâ’’OOO+Y>����R���H9����¤���r,êèÑ£W¯^íл/^aÃlƆ """¤Ri“×SSS#""~üñÇÆ/¾÷Þ{ÚíU˜L¦ˆF¶oßþ²%5MDDÄ{ï½÷²Þÿýˆˆˆ¾<X£üóŸÿ4w–B¡ˆˆˆX¼x1¤땘˜¸mÛ6¡P¸lÙ²´´´ö¿Q$ …B+Åh36mÚtâÄ ¡P-“ÉÿI.— …ÂŠŠŠÆ/>~üX(Zç°øÞE(ÖÕÕ%&&._¾üàÁƒ;wîlq1‚ „BáãÇ_ö9Ð#]mË–-ÇŽ[½zubbâóçÏÇŒ# E"¤ë= “Ëå|ðT*?~¼J¥B‡x|>¿¦¦ÆÏÏoúôéF£ñßÿþ7ŸÏß½{÷Ž;|||._¾lÎ4†ÏçO™2ýó×_åóùß}÷l ¯Èh4VWW'$$H¥R‹…F‹–––úøø,\¸Ðüä³ÑhüôÓO}}}ÓÒÒ ý[…Báñx±±±»wïÞ·oßÞ½{Fãš5k|}}ýüü|||W‹7™L/^ôñññóóóõõ=qâ„ÉdŠ‹‹+((À0 =|&‰Ì |þùç}pN‹Û±cGBBÂþýûcbbx<^NNÎõë×Í=rùòesƒ?~Üd2ÆéÓ§ûùùùùù…††a2™®]»f^ìСC½n#êe)çÌ™3Ÿ}öNg³Ù eÞ¼y¹¹¹J¥R¡PDEE]¿~====66V¯×+Šo¿ýÖÃÃcæÌ™ ,ÈÈÈ0•J­¯¯—Ëå:N&“ †Uo/;ÅIJJb2™l6›D"ÖÖÖ:Ô××wÅŠŸ|ò ZlÛ¶m‡>pà@BBBQQ´›ÅƒÁÐëõZ­vóæÍ?ýôÓ?ü ‘H<<< d®”•––7kÖ,‰Dò÷¿ÿýã?>þ|bbâ!C0 »wï^uuõèÑ£D"Ù½{÷öìÙÍûŠ´Z­^¯g2™h‡cooÏf³ÑŸ222,X0sæL‰Dòþûï¯^½:%%%666===99ùÉ“' S§NÍÍÍ3gNTT”D"Y±bÅúõëÏœ9)§ËÕÔÔˆÅb…BÑøÅììì&‹}ôÑGK–,iò"ƒÁ¸}û¶H$Z°`ÁŸþ¹qãÆ%K–,_¾¶‹¨¨¨‹Å‹�b6vìØ4Y211100Z¬Gz©¯¯‹Åµµµ/{¯F£‹Å•••ÐŒ=ÂÓÓsàÀS§N}ðàÁ•+WÌw¯ …X,®©©é•GE½h]ëêê$I¿~ýrrrrrr0 spp(,,ìèˆ�*•:dÈÔm\.—ÇãÁû•——¿xñÂÏÏ/11111ÑÕÕµ¬¬ìþýûÐ2=.!!áÔ©S......M&©KKKC[#GŽtrrjþ^‰Db^Àz_ï;ÐÿE‹M™2ÅÎÎîÂ… èõ¬¬,s¿p¹\H9]%33sÏž=Ë—/7ß;wîªU«Ðÿ§¦¦úùù5Ù`JKK›—ËýñÇÃÃÃóòò.\øá‡Âû8q"%%å‡~˜7ozÅßßöìÙèÿe2™P(lò–œœœ&ç©À"�òóóy<Þ€P›oß¾=:::##C©T6¹€<mÚ´ýû÷‹Åb‰D"̯›L¦7n`6hР+W®TTTäçç0�š÷xzz>xð`ìØ±NNN7oÞl}ÈÍÍ­©©9xðàòåËÿý÷Å‹£1Ÿ“&M:tèPqqñ“'O‚‚‚ åôŒ¤¤¤   ''§ & W “’’JJJÂÃÃ]]]/ìàà™šš ›AסR©QQQyyyIIIæ{i!!!~~~éééF£Q.—C+YŠR©LJJ*((HIIÙ¸qã¼yóp÷õõ½}û¶B¡Ø²eËÈ‘#Gvuu;v¬D"IJJJNN®ªªÚ½{w¿~ý¦L™òäÉ“”””´´´èèh‘H””””™™yëÖ­Í›7÷ïßÚùU¼óÎ;F£qÏž=&“) `ýúõæ /))IJJ*,,>|8Ç»yóæþýû×­[÷Æo\¾|yÚ´iÎÎÎãÇ—J¥III.\J¥;wîôððèE@f2™ëׯ×jµ …B&“ùúúöÌzÉT*Õ`0´2@S¯×“H¤ððpó™B¡ðññyòä‰V«ýã?Î;õÉ'Ÿž?þÝwß jhhX·n]`` \.¯¿þ:™Læp8|>?==ýwÞA·L[W[[[ZZêîîÞ»z×R™ƒL&7.%ÛœZ­vttŒˆˆ0·O]]Ýðá÷oß^QQÁår/^L¥RÇãââòìÙ³¥K—:99L™2¥õá"‘¨¡¡!88¸×yE8Ž3 “ÉÔâ˜Æ‹Éd²ÀÀÀòòr½^?wîÜùóçc6dÈggç§OŸ–——ìÞ½›Á`ÈåòÑ£GϘ1#44´¼¼¼¼¼ÜÁÁaåÊ•aaa†M˜0A«Õ–••}ûí·ååå$)...&&¦õµ­««+))éׯ_¼G¥R)Š^¯os\ßСCíííQ§ 2dÏž= …bÔ¨Q{„Ãá¬X±bôèѯ½öŽãR©´¼¼<<<|ûöíNNNÇG‹ÙÛÛ/_¾<<<¼õo|ñâEyy9Çsqq驯!Âh4æä䤦¦âl礻ÏkŸKµõ/‰æ¬ÛÍh4‹ÅR«ÕxTsĈÅÅÅ2™ ÇqôJrrò’%Kþñ|öÙg-¾¥ªªjûöíµµµ‰‰‰íùŠâââ›7o†††öÁâ,‹F£)•ÊžšIúÂ… ÕÕÕóçÏïkÅ pwpp ¢W\,))IMM îƒÅ ˜L&NW©TV8“t~~~vvöرc{ªx‹ÅJ/ªy^Ûøõú?.ž'éØŸÒ­ »|³ü>êëë7oތƉÂÉ>��tmÚ“1nUØÕ9„b$ Ã0‰lçìNWj1¬´7ƳmÛ6¥Ri>ÅÁ0läÈ‘ ƒ~Ù‰^ddäܹs'Ož ¿��èR ¶“8vVÖÙ½¶pq|ÆŒM^áóù|>¿•³à·ß~~��ÐÍ`&i���r���Ø뺰& ­ó‘u˜[755µ¬¬¬G¾º×›ËåIIIÖ¿ž°Ü¸qãéÓ§Ö¶V=5д¤œÜÜÜììl«•B¡4™/¤0™LW®\)--í©®!‘H}¶åU*Õ™3gzË,Î}vÁ0ìêÕ«‰Ä:w_ ¥ñ語…3ØÎ«~«Á0Œ®,IºßSÏå���°=,ëç|š¨{QüàôÚ p/��@7”���R���Ûò_ÃH$FƒF��`M&íýÿ)‡ rž½Å/4;h&���¯¨¨BU­ÇkÕÌRŽîTXo¤ˆªøŽpµ ��À«ÊUå)¸LNK)Ã0*îLÝðËö–:gj*訋��}†K€šá¡Uµ«¾b¹†Eeü×e3üØO?÷{Τåûþß¹ŽN£×¨ÚùÕa.õ¡NõÐ��ÐG4¸eÕ8´êö,LeØQh ÃUOoÞðé¢h¼¦¦f@ð¨~wô‹5 Ù$žöõAlè��è#ÒÊhI;<ʬº$ÿì¦i%E(çøÁýëw¼56îsºÛ•×Î ôZVm00¡��  Œ›&MQõT«’ß<º)ñè7™Lz½þò®Ä½·Ô;$bÔÜõíü “Ñàªqõ¥Ð��ÐGhÜǼ`ø7ÔUµsù»I_=ÞH<zpZt•JÅÑ<tƒA¡P¤ü~~ùŠÛÿݸ‰ÀMô��ô$ª 'µÓ„ï÷¿9+†ÍfS( ÃþÛ)àý!����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/index.html���������������������������������������������������������������0000644�0001750�0001750�00000035602�11555611700�016427� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Catalogs - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Catalogs</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> DS9 provides full support for loading, displaying, filtering, and saving catalogs. DS9 allows you to overlay symbols from multiple catalogs on the current image and to create expressions to style the source symbols based on catalog properties. </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li><strong><a href="index.html#display">Displaying a Catalog</a></strong></li> <li><strong><a href="index.html#select">Selecting Sources with the Cursor</a></strong></li> <li><strong><a href="index.html#display2">Displaying Multiple Catalogs</a></strong></li> <li><strong><a href="index.html#clear">Clearing Catalog Sources</a></strong></li> <li><strong><a href="index.html#filter">Sorting and Filtering</a></strong></li> <li><strong><a href="index.html#symbol">Specifying Symbols with Conditional Expressions</a></strong></li> <li><strong><a href="index.html#save">Saving the Sources: Catalog Files and Region Files</a></strong></li> <li><strong><a href="index.html#cite">Citing a Catalog in Publication</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#2masssrc">Figure 1: 2MASS Sources for the Antennae Galaxies</a></li> <li><a href="#2masscat">Figure 2: Catalog Tool of 2MASS Sources</a></li> <li><a href="#cscsrc">Figure 3: CSC and 2MASS Sources for the Antennae Galaxies</a></li> <li><a href="#2masssort">Figure 4: 2MASS Sources Sorted by Decreasing Jmag</a></li> <li><a href="#jmag14">Figure 5: Filtering 2MASS Sources: Jmag&lt;14</a></li> <li><a href="#jmagrange">Figure 6: Filtering 2MASS Sources: Jmag&lt;14 or Jmag&gt;16.5</a></li> <li><a href="#editjmag14">Figure 7: Symbol Editing: Jmag&lt;14 Rule</a></li> <li><a href="#editjmag14ds9">Figure 8: Symbol Editing: Jmag&lt;14 Sources Displayed</a></li> <li><a href="#editjmagrange">Figure 9: Symbol Editing: Jmag&gt;16.5 Sources Added</a></li> <li><a href="#addlabels">Figure 10: Symbol Editing: Rule to Add a Label</a></li> <li><a href="#addlabelsds9">Figure 11: Symbol Editing: Jmag Labels Displayed</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="display">Displaying a Catalog</a></h2> <p> This thread uses an optical image of the Antennae Galaxies (NGC 4038/NGC 4039) from the Digital Sky Survey (DSS). It was retrieved via the "Analysis → Image Servers" menu in ds9. </p> <p> A number of the most popular catalogs are listed by wavelength in the "Analysis → Catalogs" menu. More options can be accessed via the "Search for Catalogs" option in that menu. </p> <p> First we overlay sources from 2MASS by choosing "Analysis → Catalogs → Infrared → 2MASS point sources". The source matches are displayed on the ds9 display (<a href="#2masssrc">Figure 1</a>) and listed in a "Catalog Tool" window (<a href="#2masscat">Figure 2</a>). </p> <div class="figure"> <div class="caption"><h3><a name="2masssrc">Figure 1: 2MASS Sources for the Antennae Galaxies</a></h3></div> <div><img alt="[The sources are displayed in green on the optical image.]" src="2masssrc.png"></div> </div> <p> A set area centered on the field of view is used for the first catalog search. The center and size of the search area may be adjusted in the Catalog Tool by setting the RA, Dec, height, and width fields. The "Coordinate" and "Size" menus may be used to set the units for those values (degrees/sexagesimal and degrees/arcmin/arcsec, respectively). After changing the values, click the "Retrieve" button to update the Catalog Tool. </p> <div class="figure"> <div class="caption"><h3><a name="2masscat">Figure 2: Catalog Tool of 2MASS Sources</a></h3></div> <div><img alt="[199 sources were returned for this field.]" src="2masscat.png"></div> </div> <p> Note that ds9 attempts to select the correct (RA,Dec) columns from the catalog data file in order to display the sources. In some cases, the user will have to explicitly set the column names by using the drop-down menus in the Catalog Tool. In this example, ds9 correctly chose "_RAJ2000" and "_DEJ2000". </p> <hr> </div> <div class="section"> <h2><a name="select">Selecting Sources with the Cursor</a></h2> <p> From the "Edit" menu in ds9, choose the "Catalog" cursor type. Clicking on a source in the ds9 display highlights the corresponding row in the Catalog Tool. Multiple sources may be selected by holding down the SHIFT key while clicking them. </p> <p> Similarly, highlighting a row in the Catalog Tool will blink the source region in ds9. If the "Pan to" option in the Catalog Tool "Preferences" menu is checked, the ds9 display also centers on the chosen source. Mutiple rows may be selected by holding down the SHIFT or CTRL key while selecting them. </p> <hr> </div> <div class="section"> <h2><a name="display2">Displaying Multiple Catalogs</a></h2> <p> More than one catalog can be displayed in the same frame. By default, the sources are displayed as green circle points. The color and shape can be changed in the "Symbol" menu of the Catalog Tool to distinguish between the different catalogs. </p> <p> In <a href="#cscsrc">Figure 3</a>, the Chandra Source Catalog has been added to the display (Analysis → Catalogs → High Energy → Chandra Source). The symbols for the CSC sources are set to red diamonds. </p> <div class="figure"> <div class="caption"><h3><a name="cscsrc">Figure 3: CSC and 2MASS Sources for the Antennae Galaxies</a></h3></div> <div><img alt="[The 2MASS sources are displayed as green circles and the CSC sources are displayed as red diamonds on the optical image.]" src="cscsrc.png"></div> </div> <p> To toggle the display of each catalog, use the "Show Regions" option in the Catalog Tool "Preferences" menu. </p> <hr> </div> <div class="section"> <h2><a name="clear">Clearing Catalog Sources</a></h2> <p> Simply closing the Catalog Tool will not remove the sources from the display. It is necessary to choose "Clear" from the corresponding Catalog Tool. </p> <p> To remove <em>all</em> the sources from the display, use "Analysis → Catalogs → Clear All". </p> <p> For the rest of this thread, only the 2MASS sources will be used. </p> <hr> </div> <div class="section"> <h2><a name="filter">Sorting and Filtering</a></h2> <p> The source listing is sorted on position by default. A different column for sorting may be selected from the "Sort" menu in the Catalog Tool. Related checkboxes determine whether the results are listed in increasing or decreasing order. The Catalog Tool in <a href="#2masssort">Figure 4</a> is sorted on the "Jmag" column in decreasing order. </p> <div class="figure"> <div class="caption"><h3><a name="2masssort">Figure 4: 2MASS Sources Sorted by Decreasing Jmag</a></h3></div> <div><img alt="[The sources are sorted on the Jmag column in decreasing order.]" src="2masssort.png"></div> </div> <p> The "Filter" field in the Catalog Tool is used to filter out specific rows from the source matches. A filter is conditional expression that is evaluated for each row of the catalog. The column name must be referenced with a dollar sign in the expression, e.g. "$_RAJ2000". </p> <p> To select the sources with low Jmag values, the filter "$Jmag&lt;14" is used. Click the "Filter" button to update the Catalog Tool and the ds9 display. The results are shown in <a href="#jmag14">Figure 5</a>. </p> <div class="figure"> <div class="caption"><h3><a name="jmag14">Figure 5: Filtering 2MASS Sources: Jmag&lt;14</a></h3></div> <div><img alt="[33 sources are included in the filter.]" src="jmag14.png"></div> </div> <p> TCL expression syntax can be used to construct more complex filters. The filter "$Jmag&lt;14 || $Jmag&gt;16.5" uses the logical "OR" syntax ("||") to select any source with Jmag less than 14 or greater than 16.5, as shown in <a href="#jmagrange">Figure 6</a>. </p> <div class="figure"> <div class="caption"><h3><a name="jmagrange">Figure 6: Filtering 2MASS Sources: Jmag&lt;14 or Jmag&gt;16.5</a></h3></div> <div><img alt="[70 sources are included in the filter.]" src="jmagrange.png"></div> </div> <p> The uniformity of the symbols doesn't distinguish between the low-Jmag sources and the high-Jmag sources. The advanced symbol editing in the next section improves on this display. </p> <p> Before continuing the thread, clear the filter in the Catalog Tool so that all the sources are displayed. </p> <hr> </div> <div class="section"> <h2><a name="symbol">Specifying Symbols with Conditional Expressions</a></h2> <p> The advanced symbol editing in the Catalog Tool allows you to specify the shape, size, color, and text of each symbol based on catalog column values. </p> <p> Open the "Symbol Editor" from the "Symbol → Advanced..." menu in the Catalog Tool. A conditional statement, written in the TCL expression syntax, is entered in the "If" field. The styles that should be applied are set by the other fields (shape, color, text, etc.). </p> <p> First, define a rule that sets the sources with Jmag&lt;14 to be red boxcircle points. The completed form is shown in <a href="#editjmag14">Figure 7</a>. After clicking the "Apply" button, the ds9 display is updated (<a href="#editjmag14ds9">Figure 8</a>). </p> <div class="figure"> <div class="caption"><h3><a name="editjmag14">Figure 7: Symbol Editing: Jmag&lt;14 Rule</a></h3></div> <div><img alt="[The fields are set to display sources with Jmag&lt;14 as red boxpoints.]" src="editjmag14.png"></div> </div> <div class="figure"> <div class="caption"><h3><a name="editjmag14ds9">Figure 8: Symbol Editing: Jmag&lt;14 Sources Displayed</a></h3></div> <div><img alt="[The sources with Jmag&lt;14 are displayed as red boxpoints.]" src="editjmag14ds9.png"></div> </div> <p> The "Add" button in the Symbol Editor is used to create a new, empty form. The second rule is defined such that sources with Jmag&gt;16.5 will be cyan diamonds. After clicking the "Apply" button again, the ds9 display is as shown in <a href="#editjmagrange">Figure 9</a>. </p> <div class="figure"> <div class="caption"><h3><a name="editjmagrange">Figure 9: Symbol Editing: Jmag&gt;16.5 Sources Added</a></h3></div> <div><img alt="[The sources with Jmag&gt;16.5 are displayed as cyan diamonds.]" src="editjmagrange.png"></div> </div> <p> To edit an existing rule, highlight the rule in the Symbol Editor and adjust the parameters. In <a href="#addlabels">Figure 10</a>, both rules have been updated so that the Text field is set to "$Jmag". This <a href="#addlabelsds9">displays the Jmag column value next to the symbol (Figure 11)</a>. </p> <div class="figure"> <div class="caption"><h3><a name="addlabels">Figure 10: Symbol Editing: Rule to Add a Label</a></h3></div> <div><img alt="[The fields are set to label each source with its Jmag column value.]" src="addlabels.png"></div> </div> <div class="figure"> <div class="caption"><h3><a name="addlabelsds9">Figure 11: Symbol Editing: Jmag Labels Displayed</a></h3></div> <div><img alt="[Each source is labeled with its Jmag column value.]" src="addlabelsds9.png"></div> </div> <p> The ds9 Reference Manual has <a href="../../ref/catalog.html">further examples of symbol expressions</a>. </p> <p> The set of rules may be saved from the "File" menu in the Symbol Editor. The output for these rules looks like: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> condition shape color text size size2 units angle --------- ----- ----- ---- ---- ----- ----- ----- $Jmag&lt;14 boxcircle point red $Jmag physical $Jmag&gt;16.5 diamond point cyan $Jmag physical </pre></div> <p> The file can be loaded into a later ds9 session by opening the Symbol Editor and using the "File → Load" menu item. Note that the column names in the symbol rules may have to be updated in order to use them with a different catalog. </p> <hr> </div> <div class="section"> <h2><a name="save">Saving the Sources: Catalog Files and Region Files</a></h2> <p><strong>Saving a Catalog File</strong></p> <p> The contents of the Catalog Tool may be saved from the "File → Save" menu. If any filters are applied, the filtered output is saved in the catalog file. </p> <p> ds9 supports three catalog formats: VOTable, Starbase, and tab-separated file. If the catalog file will be loaded back into ds9 in the future, any of the three formats may be chosen. </p> <p><strong>Saving the Sources in a Region File</strong></p> <p> The sources may also be converted to a ds9 region file for use in data analysis, e.g. spectra extraction or calculating sources counts. </p> <p> Select "Copy to Regions" from the Catalog Tool "File" menu. Once the sources are converted to regions, individual ones may be selected and edited or deleted, if desired. Save the regions from the "Region → Save Regions..." menu. </p> <hr> </div> <div class="section"> <h2><a name="cite">Citing a Catalog in Publication</a></h2> <p> If you wish to use the source information in a publication, refer to the "Acknowledgment" item under the "File" menu in the Catalog Tool. For instance, the 2MASS acknowledgment reads: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> Acknowledgments for CDS This research has made use of the VizieR catalogue access tool, CDS, Strasbourg, France. VizieR is a joint effort of CDS (Centre de Données astronomiques de Strasbourg) and ESA-ESRIN (Information Systems Division). </pre></div> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">08 Jan 2010</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> ������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/jmag14.png���������������������������������������������������������������0000644�0001750�0001750�00000537254�11332127304�016230� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ! ”´iP�� �IDATxÚìw˜UºÿOåÐ9LOwON0C¢¬aÇËUWEtw®UÁQLq”•Õ5"`¸¨WQÄDQt0Ì “CO÷„ιª+ÿþ(l0 .ë]·>Ï<óTW¿uηÎyë¼U眮)Š =Ï#<âóùÀÒÑqæX††††Æ¯(Áp¬Äe¢} p8C4ƒ6› †á7ËÏÏ¿ï¾ûŠŠŠrrrÐ`0¸råʶ¶¶Gy¤  �‚ �ÀýÿãÃÿ¸ñÚßkµ¨¡¡¡ñ«@”¤·7¾ûßw]’Éd~¼yWÿ¿øâ‹óæÍcf(Ư¾úêœ9sDQT÷¨;o«ÿ{{{üñ‚‚‚›nº õx<ííí?ü0A‘Hú†OÜDñ‹ýM¿ÆrVììî ñ¼˜ŸkI³|4‘¶u: ÷ù£8Ž»í­Ý�€Ñùõm>�Àˆ2wK÷€$ÉEn[4Á$R¬Ýb@Qx §IÜ•cîðÛg7J ¡ÃòN»I’å`$iБ6³¾»7ÃPe‰ûHGï`ûŠ"gOˆãż\ ›á#ñ´ÙHëiÒ7Á1¤$ßÑÒÕ?ؾªÔÝÖ3 Šr¡ËO2ñk3ëq íÆ(ËsXÛ{üƒíGUä7¶û”äç"‰4ÃåÚŒŠ‘„ž&s,ú®ÞC#JÝíÇ ËõD2œàv˜9^ ÇR&mÔ“Þþ†"eŽæc…U–¸:¼A” \ÖD*O26³žÀѾ@Œ$°§µÍsŒ°‘åyG:ûY)ɳ£©“qXüᄎ&Vc—/A`dy~ñ%\^˜Ûˆ°Á•cæ1K™ô”É@÷ô‡Q®(t6uö ¶^âêòxAÊwZSL&–`¬&Eâ½þ(£….{›ç¸ªÏkîê“e¥8ÏŽ¥’éLŽÕ€Àð@(NS¸Ónîüª/+pôcL†wæ˜DQE“F=e1Òž¾0‚ÀËG:ަù¤æ“¿€Oúü��˲ápxpcþ½-<A²,ó< …~Ä&»-˲$IªñØ[,–§Ÿ~zÁ‚ …B>ø †a?™:Aï~٠ÓNýŠþØtÊe!Ó©¤¯w€Æ®´wùDž)ÍÕ7´v'ñ±%öCMñXld‘µ¹ÃG rèH8Ú×ï7S0ª=½@âó,dS[O2ó­ýØ2ûáæ®h$Zâ4ôùþ Ý€I<ëñöc@´éÑ–No:•Yh©kêJ$âãJíuM±hlXž©ÛÛ†œf‚M'½½&p¨­Û'd˜r—¡¡¥;‘ˆ-µ×éˆÅb#Š,­ÞP(’o§£Ñho_ÀDB8$vxú1“o£´{’‰øØ{Ý‘Îx,6¦ÔÞÐÒ‰D‹sõþ`ÿ@ЦG!ÓííG!Lj7wô¤’ÉÑÅÖºæÎx<>¾Ô~èHg,«p=½@(×L°LªÇ7@¢²‰„Z»¼<›®pUaãTûX¬ªÐÒÖí …Ây6*‹ûúüˆÔÑÝ+ la}¤Í“HÄÇ”Úêš:ã±Øè[ckw$-rèÁpÿ@ÀJ£@â»zúEÈ5áÍ=ÉdbL±jW–sèHG,+s½}~ ä0á›öøú D²ÐH[§eRÃóMõGK,çPSg,«,0wt÷Ca·•L&âÞ>¿4*·w÷J<[ìÐ5¶zÔªW…*¶6µ÷„ÑÂ](îXh–ùNO,ó.3ÙÔîI&cJìuMñX|\¹šQ´Ôeèí÷ûý¡#&pL·o�‡$´vz™tª*ß|¸ùhի†ç›:{ú‚Á°æ“šOþ2>éñö ûŸ§—³,û“< Çž0aB:Vw*�� @€ †³öcÆŒaYV=VQÔï¡ì± #0¬~;iÒ¤ûî»õz½‘H@PkoÌj V}6ûþH:Å •…65 �€`�€‘Â-z‚ $ËGÓ<€ÛJË Æ3¼(!0d¢q#ËŠMq)VDÈe¥Ã .Í §ðÙ…Ä»‘ %2AÊî´è 3³‚NdI¶›h@mްìs;Ìû[úŒ4>ºÌùe}M`§(ÚÛèŠ2¢ÌÕÖ‰&3¥yv†“ºú£n›ÑlÔî0ÑĈÒÜ= =:›2ªøóºnAFWäÕwR¬P^èˆ$3Þ@¼Ða&I¢±;`Ñ“å9_ñê)|reÁg‡º)7¼`k?NjËs{éHªØi0Òì å˜tùË7-½ SîüâpM`« ¿:â“eeD©«£/I°%yöŒ wöE]VƒÍl8ÔÞo¢‰‘ß ›<²xWE ÑîÆî`2Í—äÄÒ|?^c¦i²¡+`ÖÊ{½zŸ2º`çÁ.GÇ Ë?Ð:áÅaE¹ýQ¦?œ*rZaiî Ùt¡Óº¯9+ÌCèÄʯôJ²\Uê숅bL‰ÛÆKJGoÄiÑ;¬ÆƒmýFUêÜÓУ#°É#‹¾<ìE`0ªÜÝä ÅÓ|YAN‚<±ü“^O5túM:bøQaØÔo…–¨m€åÄŠ"G Êô…’E¹Ú<A›.vÛj›| ŸPîÜUç¡ptBeÁ¾¦^Q’+Kœ"cJÜ6QÚ}á\‹Þi7híS…ínè¡ lÒˆ¢Ý ^#ËÝ-ÞH,Å•åÛS±{ –g7 t}‡ß¤#*K{¼z;}TÁg‡º 3,¯®ÝŸÎ…ŽP<ÓLæZp?â Z di¾ýë#ª0×çuÝŽŽ^ðMK?/JÃKœÞ`2M»¬šOj>ùËø¤‘&™��üäóM¶‘ÏnìÞ÷ÊžãZÝÛ/xÙ´ar¼±7˜º}õgcKrîœušÍH}Vç}ø¯®:§êúêÑ4‰©#:^¯q»Ý×]w]&“ÙUßûÀ«{;úã#Šìf= ÃpgüÑõ_¯û¤±Ôe)vš!ÚôE i°’8öŸ“ '—ê Kœ7Äèõú%WŒ›Pf«oë‰spÃxùÔâ T™K8­ž@’¦È;.ÑéñöE9%�Ÿ’¿b§qÎÙE mž8‡(0ª�Ø@WM+-·Ã# ͱT&˜’RœJdœ]ŽE =h1PE¹¦AÇJ\¦¶¾XFËÜæP‚ˆ±%N“¤@ý ·Mo6Ї»B6#U˜kÚ×Бx‰Ó|ÄQ¨Ômî2¡Wî6³‚ÜHæÛ :ŠhôDrLt¾ÃTÛê7éÈâ\Óáî0‚ ¥.SO0g„r·%Á ¾PºÐaÀ0¬ÙuZt¹Výþö€EO9Í;‚†•¸Lý –—ÊÝæpŠë²ÅN£ ö¾¸Ûª·éCG…}Ó I¼ÄinöF$”¹ÍQ6˜È”»Íœ¨tù“ùvƒAG4tGrLtÃTÛâ7ÒD‘ÓÔІ¤ÔeòSQ†/w[RÑJ: Ž5y£¹ÓfØß0ëÉ"§¹®3„ah‰ÓÜ9HsR™ÛMñ}¶Äi„ ¤­/î²êm&úPgÈj  sMÚ»L-¾˜ +ens Æâ™2—I”Îdž]oÔ‘õÝa»‰.t˜öµú 4Qä47x„”ºL½át$Å—çYÒœÔLäèI?ÒÍ5ë\vÃ7m³Ž,ršê:C†”¸ÌÝþD*#•¹Í±´ÐaŠFFZ{c.«ÎnÖìªÂ¶I+q™Úzc¼¨”¹ÍÁ8ëeJ]&A†:y6½IOî Ûta®ñ›V¿ž&Šæ#žˆA¥.so˜ '¹Š<sš—<T~Žž"‰#=‡™vç÷µL:²(×t¸+„ H©ËÜH&X±<ÏO ½a¦(×€ hKoLóIÍ'ŸÌ³üÁ‹N/WÇr~òA§®®nâĉêXÎâ¿`yñ¸SÛÜ?ëì*ŠÀ jhh3fŒšò#oíë§û©@Œ‰§ù'ÞùFQ@cwhÚè‚\«^Q†×®]‹fG{6~Ñ�8ÜzrÓþûgOåEùï÷5÷„�v5Ÿ3®‚ � Yi’(u[š??ØIñ)™3¼"Ã1Ví‡ìËs`.úâ[[ÌÎ’Û¯<ûH«ÔËÈ’(%ýg /1Ûf8 ›hlë¾B;}Z¹ à@g´ÞQ`_j Æ9…în æZ¨qÅæXZØÓ Ä2ªÚÑEæ±ÅfNÅLJ«ÇMt;,Þ“¤Ò\ÝëªK.¨²+G<i3º¬¤Æ<1Mäšéf_BVàÒ\ƒ'ÈÄRâ˜b³?Æûcì0·1#*=T¾]GXƒ'fÖ“v#ÙØG´È¡ïô§Œ4®ÄÔá‚q®*ß”`¥Þ0SäÐã(Úà‰å˜(‹¨÷Ä(ϳéÚúS §Œ-6yÃl8Á*4‡Sb„)u�€›¼q§…6Ðx}wLON ÝÜ›x¸ËÐd£)aL‘ÉŸüQv˜ÛȉÀHæÛt4‰Õ{bfi7’Gz0‚9ô]tü;a™ª|S2#ûBé¢=¡õžX޲ˆOŒ"ð|»®£?•æäq%æžP&œàGš¢)±/”æê!9ÒwZ(#M4xbz wYt­½ AÃó žM £‹LÁ„0e+\A†ºûy6ZGâ ž˜IG8ÌT“/AHq®¡;ÀÄÓâØbSŒ Ä2•yÆ4§xCé‰c ž¸Í@Ú dƒ'F`X¾]ß1J²òøR³7” %¸‘¦(#ö…™’\=#=ñ\3eÔõž˜ŽÄ]6]koŠÁè"cOˆ Vî2H2ÔÞŸp[i‰×{âFšp˜é&_Bà’\ƒ'ÀÄŽ ã±Ìð<#Ë+=ÁT]GX½'fÕ“6#ÙØÇ0¬0Gß9N°Òø“7Â…â܈SŒ‘úÂL±C¡H£'æ0QfÑУIÜmÓµõ§XŒ9*ŒUhR«¾ÌiÔìK¸¬´æ“šOþ>Yï‰eù¡Œž3þ}÷ü}ÆW=¼ÙDyW½oWýÑÉÏœV’—cœ8š=àÞ?L¹éé’$×w…=ÿ™,+}á�@Gb÷Í>3{€pJ<Ü>klÕ¸‘•_µ…¶ L*w4wöôöù'V7íõçšiO[«ŸÅ$`çd”’<‹�p ­*´Ò(ß U©Ø{¸slaicc4š�Ÿíj.Í!/>}J8Ð{áø*Og›<ÆïKNŸTúîG_/°Y¬{¿ŽáÌm¦.œ×ÖÒ$òÈ^:¬Ä}úðœW׿—L1®¢aŠäÐQ„ÎhÅ•L&6à(É1QXk?ƒÀpY.]ïexQ™\f¬÷2 /+2zB\4%”çêÒœì‹pIáhÛ�CbhjìeL)3Ôy–—N+1µú3 FîÒGÓR_”˳R · 0Ï5M}¬$ƒqEúC=iN'•š{™4'Ì7 Ä…@œ/²Ó’ <!Ƭ',:¬¥Ÿ!¸Â©;ìMó¢2¹ÔXïc^[hì‰ð‘¤PæÐ1¼â grL$M m Ž¡…vª¡—D%+lb‰©ÝŸ‰3â0—>ÆH½QÎm¡Pn`ô$î4M}¬ )ß 37ö2éŒ4"ÏHˆþ_h£eêö3&=aÕ- Pà —¾Þ›æer©©¾—a8iL¡ÑáÃI¡Ô¡Ë 'ÌÚ¤žÀÚ E‹rèFß1%<¡ØÔÌÄÓâ0§>Áʾ(ç2SŠ´õ34¹,dS/+H`J™¡®‡ayr™éH/“ÊHUy†`Rˆñ6Zp»Ÿ5é›hégîÖö¦9Až\jjèeÒœ4ºÀÐåC ¡$‡æDÐbmÒ@am #%ºáXaã‹]A.–*œºdFöE8§™$0¤m€¡4ÏJéû¶ê{V&•ššû3IV¬tëÃ)©?Êå[)‚ÛX#ç‰æ~F–¡±n}÷˜ªU`è Á8_œC ð„X«Ð|RóÉ_Æ' Àß6òßËq±'`6ëˆGo8ë8ûÇ7Ô~o|šRéú¯«§>ðÊîldš6:Áå“Ìzr°ñÑùÔ0 :Œ/,˜î²ê��¾`R7ù9ÆÿYrIžÝ H�–�ò鑨’Õìª=4>Ÿ,3qåNªo œ”ñ£«`ÆNòv«9×]h5›ŠF£¢ ~;Iì;P÷UCW,þhç—ñxŠó#蜋sö§Å(GÌ4òù_¶FPE–ìzÌ¢Çgœ9ª8ß ±a6Ø)XGá=¾ýãO��ÐÝjé ]3ó?æüáŠ@†Üߞͥ•n] ɰL %îÍ`(<2úª“Q�4¦€þ¦›Éˆ`˜“ì ñá´Th#XQé 6=fÖ¡}C†9É}Ý AãŠè½ /*Õ4À%2Jqc¥ž¨kÆInà()É!ô° /Ò}ÙžehDUçc”9HBì‹n AP[€7P¨Û‚×ù2 ʧöv¦e�. ÷{˜Œ*rIO„¥¤ÁIJgˆ·ê1«mèËà2ÜEÖv3�‚ÆÒ_u2¼*]T‹Ÿ‹e”â"‘‘=ÁaÄhnàH)uû{X†&'ì°Mó ÔASb_Lt[pZ¼žDó-ø!‹"ðèzoGZR Qùô–@E.éðÁ””oÃYéñf7 õ}E*Ýdm£�hl!]ÛÅp"î"Û\Œ•‹ìD’“»#‚Àé)¤©Ÿ#q¤,—ØïQ…Ñ»;Ò‚ F¸©úÞLŠ¥"”{c¢Ë‚cÔêçtR`ÃyYÇÒ{Ž £zYF�å¹doL $¥|+.) #È›u˜ÃˆÖ÷f0®Ê#¿î:Zõûº˜Œ†;ÉŽ e¤B;‘æ•î°cÀŒz¤Ÿ#0¤<—üÆÃ@4¾ˆÞÓÁð2¨rS}™$§”äFòF§Ç1¸ÅÏÑRd'zY†Çévw¤E™GÕ©ÂdLHˆyV\P{7Ѩӄk>©ùä/㓊tÙF‚ –—šz"M=‘#ž°ú×Ð$9;)`°1‚ÀenKö¯<ÏZžg¥ ‚¡ÁöÙm^? I’"ÉÊqEß=å@Tâ2/ùýéO¼³ÏãO��*ò¬wÿaªË¦Ï†A� À& ûí(»a’ËL!]>O¡‚™"P= ?ºÈºûHßÌI¹Wžc¢ ¦–öκ6Ÿ®È�¤���e58 ” ÆAfÊëë D“gM¬ Å™¶ÞÈï.<‡%ŠÚ|Á|o°©¡>•¼!†à„Ð9¼¸úlÄZ€H¸/’IE%N)ÑÛµó‰‹Ù´k_½€Ù0�[(gBö{yƒó-pK@àe¨ÌSr ­”XAÝÉe€ r¸O°Ñ°Ëˆìóòç[†>@PîKV)·Á¬�zbrž&1øÈ€˜£ƒFôko$à|3rÐÇc(\`»#R’68ž‘{r¡ F¨%(æêa»ÝïåÍ$œg>*¬À·„Œ •[¡PZö§” ") +"¹ °‰Fêú+»MÈ7=<…Ãf¤q@!¨Ø÷%¤0£”Ù`V=Q)ÏÓ8Ò8 ÚiØeDk=¼€óÍÈ!¢pöD¤*ìp’S|q¹À£Ô:8Ç€~£ 3!|<ŽÁ¸=$°"(³ÁaFH)ÅDPGHr`3êýN‰ÃùføÈ€ )P‘ HÈ!F)³"œ<QÉm„iièìj ÷ð:UX¯€Àpî‰I± ¨°ÃIøâr¾ ÆP¨) :t°Ã€îëáM$œoBxy… ,pGHL  ÜG¹?)™�Am!É©‡­:ä`¯`¡`µêI ηÀÍAP 2ìOÉÁ´RjEtG$·Ö“H}ÿ·Uÿ­°Ã}C…Ø“¢PaƒÓðÆä|#L`p“_ÌÑÁ¹´6+ìÛªïŒH)U+÷%å"3 APkPÌÕÃ6zÀÇg…i>©ùä¿Ú'³O9²^ÞÞðîî¶ã:Êæ]2áÚ걃L“mðO��Að‰O9_6ô>úÖ׃“Ý{¤÷©wjÍ:ÝnÖeÑÁÇ@4¶Ìq×U§?ø?_’z÷¦Ž(²×Í'8Î*µ­}ª]HGºzÃÖâÑG:ß?ÔЬs ÞÆú[Û`6Å V±‹û;ûã%GL/mol¨oõó†¶K¯ûôH¯?¼~oogíAÊù p*êolíjé ƒ68–oM±t~›g ‡ïqB—÷…Y…(’JKkì|$QÛ°‚b™bDß÷ìܽϗBŒy¬ÏßÜŠ÷Ä¢ HO@9:ÐVD.·ÈÞˆg ‘9J€‚i¥Ü2äK(nDbPsP6‘•­!†à“ì‰)IíPúR Ì€aVä¡þ¤R`7e™HÐI v•Ψ’ 1Å›QTÙA$ûSJ± �n )¤ÇAS@ÖáP®t„A+,r*Ì®X8˜VÊ,€—!o\qé! ƒš²‘„l:ÐR�˜äž¸’à Q9J 3Ê0+HñP_RÉÿV˜•‚Ìh Ê8»rwTI ЇâK‚ *m šý)¥È n )2 9 Óª°ˆÂKЈÅ›�± 4®Y8˜VJÍ@!oTqé!ƒšƒ²€ìß +2É=q  HC!F©°F„zJ¾"P¨9([(ÈBæ‚!pžQîŽ))þa± <R M�á– ’CC4e ‡z¥3ªd$hdŽâM‚ °+!¤•3¨+¬8uCMA9[õ²™åžHd ‘9ŠŸBi¥ÜXêM(yˆÀ ¦ l&!+ZB ŠÀùÆïª¾7" nqH*…F€"psP¶ÓI†Á.½ÒUX•£ø¾­úp¤”3ÜVru̓„i>©ùä¿Ú'ÖÛÈ‹¢|b¼�¼ñIãuŽ;6¨sð=–ôîî6A’�L,™Té^ñÖ^Q’?=è™}þè‹þ{Ær²)Ž.ÉYyû»m†»ù$‘DÐR$ΩH63<)èdÑ —p8}8¬HúÓ`ŒêŽc¼CÍPLâ4#ãµ}¼ì8£5EÉö3`„®OJŠÓ|¨_íg ÕÙe¨°´0/÷7%¢(~øå7ž@’¤QìP$ 0@®“(À•»8«,éC&8Âe¾P�6ûa)S(€)€“Ij(‚ Æ;¸¦‘ÁïM`1.6 iêK!vJ$¥3ŠˆìÖ‹Í\”Á×&8 Œ±sQ")@å&>Æ!iÄI‹0:cˆ“rh¹-Љ2eçêC/ñ®9B0"ni$ÈÀùA”!_1’—Û£R×!éa¾$ÍÀEF ¾b#EU:¢+ùz±9‚ ƒ„¶sÝq"ÁCe&>Î!ýiÄI‹(:cÉZl⢠&ع†ÁK`œƒk‰Œ†Y„ƒ8Ï È ä"F\2“r{�”™¹#á£'¢ «²ò}),ÂÂ…F!#B½)ÄJJ4*wD1 V bSøa£ì|wKðp©‰OpHÉ¥E V:£(‰ÈNZlQ…år!‚“À¸®5J¤PaÂ,âOÃn½�ÐE ¸d%å¶(¦(`¤k$ŒA••ïOaa.4 ¼ù’ˆ…”ô¸ÜÅH)úVXöDFÚøžçà#Ÿâáþ4’C‰ø·UïÒ‹-ÇVýØ®=J¤Pn",âOÃ.½�èŒ"z\²“rk“e0ÊÆ5„©úJ ïOc!.0‚y“ˆ™Œ¸ÜÅ`ù#Ç Ó|RóÉ‘OŽÍa;ÒGç|ï§þ}Cíq!gùŸ~;¸‘ÏÎ5¸cæi7?µýè�ÔÙWOc¤‰£Î=˜zÓ“ޝp.˜9ɬ'MzⵟϹ`LE¾í˜G¢ÓN;m×®]©Tj(S¶/ÿ¯ wô/ð²€tÇ—|¬¥-TþxÔóO¦F!r…‰m‰ÓŠŠ ™P‹ñh¾.£�Ø›ÂsHÞFJÍ1Ê€‰eFîPXG#Ò0s¦!¢C ¹Ä˜égˆ”€ê3 ég0Åép¥=N1±ÄÈÕ…u:Tnf„ô$"—3ÝI’“ "C&) AË£9 ]I‚ yz¡!BëQ©Âœ9ÒQˆ\nbÛâ´¤€bC&ÂaQͧ3�‚{RxÉÛI©éXaæLc”†Rú­°]†Wà¾4î¤x.· ì`H#r™1Ó“"3"T¤Ï¤D4Àbnš#PЙ ̸P ê #¹ÜÄvÄ)QŠõ™(E2hž.C'EØ !‡›¢”ËLÜ¡°ŽB¤aæÌ‘( Pb`ý"É#ºŒ À½i<—âM¸Üz¬°aæL]X‡Ar©1ãK¬ê3Œ„0˜›æ(TéHfL,4ð‡#´•†™3TaÆLg’d¨HŸ‰ñX8ƒæë8ž$a#„²MôÚ�� �IDAT\Z<¥ ¨XnæÔ®0±Í1�PbÈ2XœG tI}iÜAòRj‰QFL,UK•†™2õ É¥ÆLošH‹p¡žS«ÞMs4ª´'H&ùÃaú¸ªïJ’¼2q ±hžŽCaÐ$¬¸àÒ Ñcª^óIÍ'ŸìLàd¢ã…Eÿùã|vãù矿ùæ›ãñøP"Â+¯¼2{öluFõOÚ£(:eÊ|ÿ£Ó÷o«3Ö~?²ìlãÄ?ÒUÿœÿdR8¢¸h¶#Iq2’G3a r„‹b%êNQv‚3`RcLoÄD'ÅŠHDvÑ™æ8-ÈM³,áñ<Ša%ØÇ2C rK\gÆ…\Š;6Ò¨ì¢2 Q= 7ÅzÓDRÄòi&) ý,™Ke`XiOÒVœ·‘B]Ä Ç$'•9Ñãˆâ¢ØÎ$ÅÊHÅD8,!\$+¨ë¨0±á[au‰(.:Ó§%ΣY?‹GxÜM1œ {Ó”ƒäHDjþN˜Be'•iˆêaäQ¬/MÄ,Ÿf’"ÚÇ’¹d•¶mÁù’?1èPÉIeê#z nŠíNRŒŒæQL”GýÂI± €:S´àM¸ÐÕ0ÑIsuQ=(n:Ó§EΣ™@sG…õ¤©‚£Q©)®3áB.ÅŠv$¦ƒ ÈM³} ð<šI‹H/Cæ’ VZ: .äPÜÁ¬°¨NæI‘iÍ£˜8ú3„‹b�IÚFðf\¨ê ˜˜KsuUÛž¤yΣ™` q„›bò¤©‚ÓaÒ‘˜Þ„‰ª0•]T¦9N+ä¦Ù~–ˆ xͲ"ìcÈ\2ƒÃJK⻦QÉEeê¿­úž4™Ñ|š‰ è�K8)JG’¶¼•G­zÍ'5ŸüE|2)bƒGO~¨‘ÿÞIh?ÉqÆ?ù#Óïf¬ q €€ à_ן¨ ý¬.&¥T4Ä“ªŒó2ÒÖ;p†€¥¶”Á€ò,Ó‘2@È#“>V—ñR:ä¨ G–P±”„y“H¡Ò–2š0Έòm)#ËN"åaôi +¡bæÉR:È^–Î#“�€Ž”ÁŠet¨Ð–4RˆhǘnFÏ+H!ïÏÐ1(£¢A–à¤;­Ï9*̨GU˜@™ð±º„ˆ—ÑÑ G8ª˜Š1ÖÃèœD…äö”Ñ„rF”kO1Xq)/£OKX)óst˜'ËèhL$zYÚM$!t¤ ,£G…Ö¤‘B$Ît3zNAŠ©X?GG¿ÖŸ¡ È„¨À]i½g)XlKu¨`ÃØÎ´AVà|2ÑËê"^JÇB¼*,® Ë%Ò8,·%F”7¡\{ʈ@Š‹HyY]JÄJ©h€£B<YJGã"ácun"CJûQa|[ÊH"’ƒH{=+aÅTl€£#¡–p_†Î'’w¦õ6œ¥±-eÔ!¢ c»ÒI ÈD/«‹ x ñ”Ÿ£Š¨xFF=ŒÞ38,·§ ”7c™Ž”†@‘:ZõÔѪ/¥bI÷²:‘B ¥-e0cœå[SF–r‰´‡Ñ3ßV}„'ÊèXT ûX:ŸLÊ Ü™6Ø0–Fͤ‘>ZõAA Ʉ據OþB>IE2ÞüÐïr†h ��TXX¸hÑ"Y–�¢(bv\¯TV� 7”TòWúFU X �°È)ˆ¢@8,I $)0 ɤ2A IœŒk/dd�‡EI%F! @PR°ì³, "+KЉ Œ@2ɼŒB@!`1#c?. dRx …€¤Ì Â8UŽvôD†* ’�DÉ @!OFÀ"¯ Êñ'2aÇ—ðÉ ƒ!=*lè%¬ð2…€O&r2ò3„á°(*°üÏV}VØOW½æ“šOžŸ„A’s-:EQNlÒOÜ‹ÅÌf³¾×~ðÇx<n4³)¯± 8Ž+Š"IÒO<:Ž[n¹…a†wìØqÁh¯ûÖÐÐÐÐ8%|ôÑG—\rI*•Ú¾}»(Šhö Nwùå—k¤¡¡¡¡qª¸üòËóòòŽù]8ú#M9“Éhe¤¡¡¡¡qJ8pà@WW×÷‡EQxž×ÊHCCCCã”àñxöÀZ‰hhhhhü2h!GCCCCC 9ZÈÑÐÐÐÐÐÐBކ†††Æ¿/èPŒ|>ßÛo¿}ÜÎÙ³g¯[·nÊ”)gžyæÏËûóÏ?ß¿öãïÿ{·Û­n¿ùæ›’$7î£>š={6�`ݺu\pÁ¨Q£†’rOOÏÆ/ºè¢aÆ�jkk¿üòK�@IIÉe—]vÊ qÇŽ‡Î~œ3gNNNÎ/V…ÉdÒï÷g?Úív³ÙÜÑÑ¡×ësssF‚'Vw¶$ÿ¥444|ôÑGêö˜1cÎ?ÿüŸ<dëÖ­]]]·Þzë?“ï_|±oß>�@eeåŒ3Žûö™gž>|xuuõ?‚ûöíûâ‹/²/¹ä’òòòŸ<jõêÕ]tÑ))äíÛ··´´ÌŸ?ÿàÁƒ;wî¼îºë†yûí·g̘QYY©^8��Š¢æÍ›�xÿý÷ÛÚŽ¾îþw¿û]YYÙIe÷ì³ÏVTT\xá…C1~ýõ×ùÃþ0Ä’¼á†L&“ÖˆŸrºººÞ}÷]µº;::Þ{ï½Ë.»¬¤¤d°Mkkë|pÅWžú§ÇSSS‡+!ŠbMMͧŸ~ú³Oìã?®©©),,T$Éï^¥³víÚ^xÁh4VTTÑßß_SSsàÀ!¦ÜÝÝ]SSsäÈõã—_~YSScµZ³!íÔ²uëÖšššlÉñKúG2™lnnVE¯×swøðáT*¥Óé—çIAQTö\A\’ÿ:<Ïm·Ýæõz+**P½óÎ;?ÿüóŸ<jÓ¦MûÛßþ™|kkk.\(‚Ñh¼ë®»¶mÛvœÁòåË7oÞ|JÎqÏž=555f³¹¢¢¢¹¹yÞ¼yápø'*--u¹\§ªœ7oÞ¼|ùr�À×_]SS …Ô«»±±‘eÙ[n¹åÀÏ=÷Üc=¶yóæ»ï¾ÛjµVTT466þùÏŽÅbCÏkùòåË–-[¼xqöNâÇyá…Ö®];K‹ÅRQQqâÛ¹4N ííí555­­­jh©©©ioo?ÎæÈ‘#555ÝÝÝÿ’§• &\|ñÅj<xê©§Ö­[—mò.¿ürQY–½÷Þ{/ºè¢ì¢ CaÆŒ4M«Ûß|óͼyó,X Š¢úñÁ|óÍ7o¹å�Àã?~Æg åÆpÊ”)ùË_î¼óÎI“&y<žgžyæÉ'Ÿ|íµ×*++G½pᦦ&QgΜyÛm·]pÁãÇòÉ'o¹ådzmÛ¶'Ÿ|òå—_Þ³g^¯ú‰¨…�˜5k ÃÓ§Oæ™gÖ¬YsÛm·™L¦T*õ /H’´mÛ6žç¿øâ‹¢¢¢³Î:ëõ×_—$éƒ>À0lÑ¢E’$]zé¥óçÏÇq|è¹[­V›Í&ŠbWWÏóMMM¹¹¹>Ÿo„ ‡....,,<ñõJ'b³ÙÔsñù|K–,¹í¶Û¦Nzá…rDzìÝwß}ñÅoß¾ý¡‡¢i†áwß}÷µ×^+..~ñŃÁà•W^ÙÕÕuðàÁ1cÆüío£(j(ú†éèè˜9sæÔ©SKJJž}öY¿ß‡§OŸ®–ÞêÕ«ÇŽ»víÚW_}• ˆüüü5kÖ¨Ç ‚ðüóÏ¿ù曆•––®\¹2ëQ?NooïÿøÇk®¹æŽ;î@¤ººð9sæø|>Žã®½öÚ¹s窖étzîܹ@€ã¸o¼qΜ9êå IÒöíÛ<8ôš:ï¼óŠŠŠÚÚÚ6lØÀ0ÌW_}5¸$Q]°`A$¹úê«—.]ºfÍš‡~xÊ”)•••þóŸ=ÏósæÌùÓŸþ4mÚ´iÓ¦¹\®7ÞxãÃ?t8CÉ]¯×#râMA3gΔeù¹çž3™L§vŠ¢7n ‡Ã'N,**òx<»víúïöÒéô矾gÏžO>ù¤¾¾þÜsÏ:uê¹çžk·Ûׯ_ÿñÇëtºššš]»v�Î:ë¬x@=ð­·ÞZ¾|ù;ï¼SQQ±nݺ+Vüãÿèêêºçž{t:Ïó[·nݵk×SO=5nܸ]»v-]º”¦iEQ6oÞl4µ€ñ/¢¹¹ùꫯ6 ‰DbÓ¦MÙýgœqÆäÉ“ _ýõ-[¶üäíÑIĆúúú;v8p ™Lz½^I’Ôýê•°sçÎË/¿üÚk¯ 'u&Ÿ~úéŽ;vìØ‹Å.ºè¢É“'s×ÕÕ�H¥R^¯Wµq¹óÎ;‡o��A˜L¦p8,Šb&“‰Çãv»=ƒÁ•+W®_¿~ýúõ÷ßMMÍ矞ŸŸäÈ‘®®®`0Øßßï÷ûëêêrrrN*pªÝk;vìèííõûý}ô‘Ú!óä“OþçþçÎ;'NœxÑEq÷ÄOŒ7nóæÍ›7oöz½;wîL$×_ýêÕ«ß|óÍuëÖ-]ºô‘Gùä“ON*÷X,’ɤ^¯Ç0ŒeYAA`Y¶···¤¤¤¾¾>‘HœT7׌3®ºêªššš%K–´¶¶îܹóÊ+¯œ;wnCCÃÕW_}饗îܹ³¯¯ï–[nI$W_}õ‹/¾xÏ=÷<øàƒ—\rÉÿüÏÿ¼þúë/¼ð³«ªªzå•WvíÚ5qâÄ÷ßÿÊ+¯¼ì²Ël6ÛÎ;¯¿þú'žx¢££cÇŽ>úè–-[>øàƒ¿þõ¯ê±{÷î}à/^üî»ï¾ûî»ÿû߇˜©(ŠápØd2¢hAAÁÊ•+?øàƒ-[¶,X°`É’%Ùë|ð£>Ú±cÇ-·Ü²pᆆ¯×»jÕª]»v >ü¤jj÷îÝ;vìhoo3fL*•:®$Ÿ~úé7>üðÃO=õ”×ëÍd2½½½ápX}æØ¼yó¢E‹î½÷ÞÚÚZŸÏ·mÛ¶#F8Ž¡w¯X±¢¢¢â›o¾Q?J’´ÿþ¹sç^tÑE@@½p��.—+''gÞ¼y‹/¾ÿþû/»ì²ÊÊÊ={ö 1°�þú׿ÖÖÖæçç[­Ö‡~øÀ>ŸoëÖ­cÇŽµÙl—]vÙîÝ»[[[_yå•gŸ}vÕªUÙ¾\³Ù,IÒîÝ»c±ØþýûF£(ŠW\qEeeå›o¾9qâħŸ~Zm‚Âáðþð‡Q£F­_¿¾ªªê¹çžÓÃ)¤®®nÇŽuuuÙ~પª;wÿîw¿|ß¶}ûöŠŠ ·Û}饗žšŽ5•ŽŽŽÚÚÚ¦¦¦ï½E}ì±ÇvïÞý3Nì›o¾©­­­­­M¥Rêžn¸¡¢¢âŸ,¯É“'gÛ‚ÓO?ý¸W¯^ýî»ïªÛ>úhmmmöãÞ½{ß{ï=õÖéd»hjkkƒÁ zÅ>öØc6lxë­·ŒFãc=ÖØØ8”DžþùwÞyççu¯E£Ñt:MÓ4Šóð:räÈŸ‘àSO=Çÿë¿þësñóÎ;oÆ K—.5kÖ­·Þ:xxìÏþóo¼QYY¹dÉ’¯¿þú©§ž:ñð÷ßåÊ•¿ä59vìØU«V½õÖ['uÔ¡C‡Ö¯_ÿæ›o.^¼Øn·«n=öXÖÿ�v»}ñâÅ?™ÔYguâàÓO"Âý÷߯ns·téÒ1¾óÎ;ßxã’’’Y³fÝwß}ƒEÑ‹¶nÝšýxÎ9çdÇuÎ;ï¼›nºiÓ¦M¯½öÚàC.¼ðÂsÎ9gÉ’%---/¿üòí·ß^RR²xñâd2yÏ=÷”——g}’$ÉÅ‹ƒÁ{ï½wôèÑ÷Üs'N!­­­µµµj÷šJ[[Ûc=vbgÚ™gž™íã9•k—^zéÌ™3�O?ýôq_!2räÈ‘#GÞ|óÍf³ù¤Nì®»î:ÙÆ}(L:µªªêŽ;î`fÚ´iÇÝŠ6lÊ”)—^zé¸qã8Ž;%9Þ{ï½Ùí¼¼<uÀùž{îùüóÏ—.]ªv ü$Æ ›:uê%—\2a„“ʽ  Àf³ù|¾C‡±,ûOžËÖ­[÷îÝ[SSó‹ù·Çã¹÷Þ{çÎ;wî\†axàC‡x ÌŸ?ÿì³Ïž4iÒ‰)äççOœ8qݺu';Äý³™0a¸qãNö¨[o½U§ÓÁ0üä“Oª7æ999#GŽ|þùçÇÇü¯–]SSó§?ý) ®[·nÕªUUUUê yï½÷Þ~ûígžyæ¯ý+A6lx衇†ÒÛ¼wïÞ­[·ÞÿýUUUãÆãy~Ù²e‚ ¶Ù¹sçwÞyã77. �¸ùæ›wïÞ½lÙ² /¼pÚ´i†Ý{ï½ê<‘ššu¨Rí¼÷Þ{;::æÍ›÷þûï§Óé¡Äi!2kÖ¬ÿøÿضm[övÜh4Ž9²¦¦†¦é“Õû™O9?„Ùl&bâĉ?üp:>©Ã€ßï÷ûý‚ X­ÖL&óè£÷,…¢¨Á`H&“úÓŸ†žòO<ÑÞÞŽaØwܑݩÓé‚3f Çq>ø`gg§Ëåzúé§Ÿzê©ë®»níÚµ .\¸pá”)SNIµ555éõú‰'–”” FÈR6zôhQ|ðÁŽŽŽ“½uå8NEEO¶Kð8öíÛ7oÞ¼¹sçžþùjÕðßïO¥R&“ EQ³ÙœN§Õ™r§dÖÃ0_~ùecc£ßﯪª¢(Š¢(«Õ*‚ßï_´hÑyç§v´–””L˜0Áb±0 £¾…Çq½^_ZZ:lذûî»O8òóóW­ZµfÍš?üðÀ'NܶmŽã@ ‘H †ì�µÑhÄ0Ìï÷'“IƒÁpÜsäÉb·Û‡~àÀŽãÌf³Ûíž8qâßþö·wß}Wuƒæææãž/õz=ŽãÁ`0«Û?;÷3Ï<32 3cÆŒºº:«ÕZUU�ذaCKKKMMßïŸ>}ú]wÝ500ðÉ'Ÿx½^Y–Ýn·Ùl¢kõõõuuu~úé3f̘1cFqqñÞ½{/Á�…BÁ`°ªªj̘1êÕ­Žà�ÆŒSPP°wïÞâââ¼¼¼L&3mÚ´W_}õÉ'Ÿt¹\ÙûîD"qæ™g®_¿þ™gž±Z­Ù™uÿ ¬V«Ùlž8qâúõëŸþùÁ_}úé§k×®åyÞjµžš§«ÕZ]]*))©®®6ÕÕÕ<ðÀ­·Þº`Á�À³Ï>k³Ù†xêÜÓ%K–¨—-[¶}ûöÅ‹?þúë¯!??_ͨ´´tíÚµ/½ôÒ£>:ô2²X,çž{®Óé4 j/Daaá­·ÞÊ0Ì#<�¸ûî»ÕÐRYYyÆg9ÎÉ“';ö¤f1bð$Ú3Î8#ÛTmÚ´iΜ9 ,¸õÖ[1 {ýõ×Õ’DQ´ººZy|ÖYg9Λo¾9N«'¸xñâ3Î8cˆ¹‘››ëõz½^/�`üøñf³ÙápF†ÕyÒEåææ±¡ÔëõS§NÝ·oŸ:u�pÇwà8®VñÛo¿=jÔ¨M›6­X±bÁ‚çœsÎêÕ«7lØP]]ã¸Ãᨮ®¶ÛíEUWWŸxûCTUU½üòË/¼ðž={��=ôЬY³fΜùÇ?þQÍ÷•W^)((xþùç_}õÕ/¿ürË–-Ë–-SûgN?ýôçž{î7ÞØ¶mÛ¬Y³n¸á†!fªNÉUå•W^�\{íµóçÏ_¶l™ê“Ï?ÿü„ ¦OŸ>jÔ¨yóæñ<¿páB�ÀÚµkGU]]=bĈ“ºhÕ GOQZZZ]]ŸŸŸ-ɪª*Õ-Y–}ë­·zè¡9sæ��~ûÛߎ5êŽ;îÈd2÷Ýw�`Íš5“&M:ÿüóG �˜2e Ã0'q› ÃÕÕÕ•••�€iÓ¦e‡ÜKJJÔa¤ ©S³> �ظqãÇr\.Wuuu¶ª¬¬T/õG§Ÿ~º ³fÍŠÇã/¾øböêV'¯f󪬬TE’$ùâ‹/.[¶léÒ¥§vÚÚµk7oÞ\]]››»zõêåË—>|ø¬³Î:®Ôøgn‰ª««ÕºÎ^Ñ[¶lɶó/½ôRCCC¶ŠûÛßbfµZ_}õÕŸL:í´ÓvïÞÍ0ŒÚ.'“I­Ä54þ·øâ‹/öìÙsûí·úé§sæÌyçw~ûÛßþ,‡^xaÓ¦M~ø¡æÿæMŸ>ý¥—^ú!ƒ-[¶H’tÉ%—lß¾ýŽ;î@µ"ÓÐø÷Áårmß¾ý믿ŽÅbW]uÕ˜1cþÂêÕ«{ì±7ß|Só‡ÿÿÐBŽ†Æ¿ååå›6mR§´èõzuœüÿ³gÏž9sæÐ'dkü/²oß¾“†ÐBŽ†Æ¿';çóÿ?ŒF£ö£Î_ '{g ½ÖSCCCCãB 9ZÈÑÐÐÐÐÐBކ††††ÆÏà˜éétzè hhhhhhü8étzðB*ß…EQ¶nÝ:00 •‘††††Æ©âûCÎ;3J¥Nj… gpXù.äð<ÅWh¥£¡¡¡¡q Q_Ûz|ÈÑÈâóùÔw$khüê˜0aÂPÖ~ÕÐø_A 9߃ßïW_Ƭ…Ư-Þhh!çׇÃá0™LŠ¢hE¡ñká›o¾QWÐÐÐBίEQ´£ñ+B„ã<–㸾¾>­d~ÙÕžúúúNÕÚÁÿ×°Ùlǽ.ïCNOOÏ‹/¾xÜÎ[n¹eÍš5¿ùÍo.¸à­4ˆU«V¡(zÓM7�DQTW�ÌŸ??''g÷îÝê* ¥¥¥×_}ö¨]»v}üñÇwÞy§ßïÏ®_YY9{öì×^{M] qúôéguVö—_~9g×< ƒÏ<óÌŒ3=OÖlÙ²eüÇ?þ¡~œ4iÒ%—\²jÕªþþ~�Àå—_>~üøluã8þÀ��6lØpøða�€ZÝ,Ë._¾\MáÎ;ï4™LŸ}öÙ'Ÿ|’ �ˆÇã?þøq"Uêëëß~ûmu{ܸq3gÎ|饗2™Ìm·Ý¦9Ì¿ŽT*ÕÚÚZ^^®ÅÏ»éT{)÷ïß²ËñidËp¨O9ýýý+W®\¸pá¹çžû5Š®\¹A-ä|/Û¶m[µjÕÁƒ«ªªÔ3þüººº+V<ñÄ×]wÝŠ+n¿ýö+®¸â´ÓN»ùæ›!ºîºë��œ?¾Çã¹ùæ›=ÏÊ•+xàÉ“'[­ÖuëÖ-]ºô™gžijjš?þË/¿<~üx�À+¯¼òÐCÙl¶lȹîºëöìÙ“——wÆg¨Ë)®Y³fË–->ø`ccãÊ•+Ÿ|òÉòòr§Óùì³Ï>þøãëÖ­Û²eËÍ7ßüÆoÜpà ÅÅÅ7Þxãm·ÝÆ0Ì”)Sî»ï¾‡~8 .Z´hõêÕ/½ôROOÏC=´|ùòo¼ñ®»îZ°`Áµ×^[^^þ—¿üA–––Ý»wïÛ·Ïb±rúúún¼ñÆiÓ¦]zé¥àÛWÏnܸ1™Lj!ç_Ýnß³gχ~H’¤¢(‚ ˆ¢ˆ ˆ¢((Š^Z–e†!RÛYõ+µÉPן†aX’$��‚ ª±(ŠÙ6‚ †ÕýÙ³K²,C¤¦)˲ºl®ºSE‚ ÔNI’ÔtAPEªyA$I’ÑhçyI’Q%©ßNž<ùÀ¢(Š¢ðzjªZ ÃÔª¥ A¨égã AêÚÞ,ËžsÎ9gŸ}vyyùàQ1£Ñ8x=ûj^ÕÕ¦òø¦EÕQUO?Û¢(Šº¤:� ›B–l æ¸U½Õ»[u'Žãê©É²|¢Ù‰|¯Í‰+Žg5H’”­Ü…eýáÅ_ôûý‡ã¸ÄŸèX6lØ´iÓ��/¼ðBMMÍ| î¸ôÒK)ŠŠF£óçÏ¿æškþÉÕàÿ=»)þû¿ÿ{Íš5f³YÅ7Â0|Í5×°,›J¥®ºêªÛo¿ý³Ï>[´h‘Ãáðz½;wî<ÿüóó›ß\xá…ÙDüq‚8Ž#I²¿¿?wuu >|úôéõõõª—Çb±+Vüþ÷¿_±bE8¾æšk®¹æš3fQRRR^^þ»ßýŽ ˆþþþT*¥Öß|‹ÅFŽ™ýéî¬Y³î¿ÿþ3f��Ôu½Þ~ûí>úhóæÍÍÍÍwÝu×_þò—©S§Ò4]PPpÓM7Í;A]»v% žç>|ÆgL›6 ˆúúúQ£Fe2»Ý.Šb:æ8îСCeeeÓ¦MÛ´i“$I{öìéé驪ª?~|$ééé¹ûî»{zzÔ…½ãÚk¯miiI¥RsæÌ¹òÊ+/¼ðÂŠŠŠ††I’V¬X1wîÜÙ³g ‚H$fÏž}ë­·f—ßèêêºà‚ æÌ™ÓÓÓ³sçÎ÷Þ{ïöÛo�x<ž‰'nذA‹(C¡££ã믿VßìõŸ½…WÛ8‚EEÇqµ©"B–åÁfªÚš‹¢¨^òêNI’ÔÑÝn÷ÁƒÕ†ÿ7+�� �IDATLmè³>‚ ‚ ¨¹«{EQã‚ j²ª<†Õ°!Š¢Ú˜Â0Œ A(ŠJ’¤5†©;÷ìÙ£&Ž¢¨ j¾jã¨ÆQ5z©ç’m(QUÛzÕ�†aEQœNçèÑ£yžüÆT*õÅ_üP « ª]Ý£^ÚÇ…œlidCN6®³,›?r²ÙÃó¼ÚÜc¦VÍ÷†œï^Ç=‹¨Qÿ¸€”Ý38äüPQ��†‰D"ßÌ~ÜYkkk7lØðÙgŸ ‚J¥²Êî¹çž@ °sçÎk®¹fÑ¢Eÿ_¾³ §§gÉ’%“&Mzûí·Ç·eË–O?ý´  `ÇŽ .\¾|yCCÃÕW_}þùçïܹ³  àšk®Á0L¯×¾A i:N/Y²$oÚ´IÝùÕW_mܸqÿþýª_~þùç§Ÿ~ººãøÅ_̲ìO<1cƌݻwãÿ½+‹²ìÚ÷ì ;Š€0"¸°) &˜¦¥eJáš»åšZ¨å›¦©•¹¤hi™Y¥© –P.)n¸¢’Ⱦ0ûúýqât¿3Ȇ¦¼sþà7Ì<ól3s®ûœsëp¹¶¶¶)))7nÜ´iSDD„L&»wï^÷îÝa-CÉÉÉñññ¡û­êëëÏž=èééigg÷òË/¯[·nذa—.]âñxB¡pãÆ?ýôÓŽ;ºté{ûöíýû÷}>,,¬{÷îÛ·oß·o_xxx×®]a±ÿþC‡1 77·€€€3gÎ:tŽÈçó…B¡Ù;¹uëVBÈŒ3zôè¨9{öìÀÀ@ŸE‹­Y³æÂ… ‹/Þ¸qãÍ›7éïÒ„ ÄbqLLÌ¥K—d2Y```ffæ§Ÿ~jcccÛ¬f!¹¡Óé¤R) °.f0, ¼<—ËÅ¥ºN§çˆÃáÀt—sèt:@�߈u`Ïd2ýüülmmU*ü4ÀÇÁ·Þ ±“Éäñx¾ rp¹\Œœ4 œ`I­VnAƒ‡¦Ýt—.]X,8txN.B7ŒÃ÷ZVþ߆xcÖt:F£Ñh4"b™BÜ%¸Q¦›qÆ�¿ ¾ „¦Óé,œa‹¢œÆÆÆªª*³ïW(K–,¹téRÎH¬Zµ*==}áÂ…=zô˜<y2D$Ë–-»yóf w¢Õj.\XQQ‘””Ô¡C‡‚‚¸«ÅÅÅ+V¬øì³ÏêêêçÍ›·~ýzBˆH$úꫯà½Ý»wß²eKß¾}wïÞ½fÍšõë×Cü”””Ô«W¯Aƒ}ñÅ„ÜÜÜcÇŽ½ýöÛàPÀJJJvíÚõÙgŸA ÷éè蘒’Ò»w襤¤”””-[¶DEEAýéǬªª‚ßä/¿ürþüù‹/–””¼òÊ+£F‚ŸJUUÕ·ß~›½zõêÏ?ÿüüùóf2e/¿ür§NæÎ?uêTooo£ bcc£¢¢RSSáß;vŒ=úÝwßµbI <)8w€ø”ÁÓ-§R©0cAG˜€ˆÒëõ€ m0™Ì;wîܽ{—~/Ä:, <;8DSt:` D��ð$œ œ²£3iˆ€:àì`cØ ly¹aÆ}õÕW*•ŠÆHNù.ú*¬,óÇj€œ$$$B¶lÙbŠ–C‡:t(!ÄÕÕµíÝ{{û™3g¾ôÒKãÇ?vì˜V«‰D«V­ú¿ÿû?—‘‘Ñ’Ìž=ûÖ­[)))b±Ÿ8pàÀW¬XqîܹÂÂÂû÷ï8p ¤¤ê1\.w̘1ãÆƒÿïÿþoùòåÛ·o‹‹ƒgöìÙsòäÉÏ?ÿüúõë*•jêÔ©jµú·ß~ƒµÒ¶mÛŒJ)³gÏž={6¤Ý!7n\·nÝ‘#G‚‚‚à77·™3gBvïÞÝܵtìØqæÌ™gÏžýá‡V¯^Z^^þÉ'Ÿü“ûcoo?{öì£G~÷Ýw~~~Ím|ðàÁŒŒ LðZ­…ëX±‚ÃË íƒI6È8B€s‡0ói�9àÜÑéÌ Ø`¡âÚµkP,Á ƒ®áf„p&ƒA(Byð�vŽ\„hˆ…jµ³ÙìþýûŸ;wN&“ †ÔÔT³`l6Nî�àF£ár¹VÈy¬öˆÃ ÜÝÝy<ž££cZZÚܹsëëëÛÞ­).. ݳgÏæÍ›¹\®L&“ËåZ­ÖÑÑÑÝÝÝÑѱ°°ÐÛÛ["‘ܼyS©TÒ ‚–——¿Þ›7oæçç …ÂvíÚ•––Þ¾}[(ºººnÛ¶íðáé©©cÆŒ!„|òÉ'EEEÙÙÙHyxxÕÕÕ ‚›7oÞ¼yÔ¾SSSSSSƒ‚‚:tèðû￟={655uÓ¦M„É“'wëÖmÈ! ÀMÐjµþùgnnîÍ›7ù|~ûöí är9‡Ã}J¥Òˆˆˆ9sæÜ¼yS«Õzyy9::ÚÙÙýùçŸ÷ïßwrr²³³‹Å2™ 6öööÎÊÊ Þ±cÇ;wlmm]\\L¯ýСCîîî§OŸ6{{½½½Õjõ®]»bcc}||zôèñî»ïÊårN—““ãîîþí·ßŠÅb…B±mÛ6àø]¸paÚ´iÓ¦MÓét÷ïß·þz[º®d³!-ƒ)/p¸àÁ1ÊÁèA£Ñ@¬£V«a{HIÀ`Ùkòjµàœ>æÓ B%F¯Âf˜S*•ø/æ‘p?€� xD€4@>ä5@>yúôi…B—P^^¼�$…B¡T*!µˆ…A˜ÙÛwŒÃáp¹\ÌõÁ-U«Õ°sn“±š â9¼(Ú �cdø*Ç�÷%8s3®œÉÄÍàˆxΖÍt{øDà+!h2¼4¼^XFÐF'åšû6²ÜÝݧL™¢Ñhòóó!e¦R©ú÷ïïééIihh`±X”H$}ûö5kVUUUff¦\._¾|yçÎÛÒO´¬¬ÌÙÙÙÕÕ5$$ääÉ“/^Œ‰‰Y¶lYdd¤Á`8~ü¸X,4hPfffRRRVVVVV–››rÊKKKýüüúöí ù|>l“=iÒ¤îÝ»Ÿ<yòòåË/¿üòܹsáKÌáp¤R)‡Ã‰á…þøã¬¬¬=z¬Y³F"‘ðx¼œœØI×®];tè�o©¬¬ôòò8p ¦Vkjjú÷ïïããSPPÜ6ggçS§Neee½ð PX‰DYMñòË/Ÿ>}:++ËÇÇ')))((ÈÎÎîĉEEE3fÌxñŇ váÂ…¬¬,[[Û/¿üÒÏÏÏÛÛ;333///>>á•••111ÀÊ•Éd2™lÀ€öööÕÕÕ111>>>EEE¡¡¡={ö6lX^^ž§§ç† T*ÕñãÇÞÿýÞ½{«Tªêêê~ýúÍ™3çâÅ‹]»vår¹7nܘ={¶D"©««ËÊʪ¨¨ˆŒŒ´Â‰Ñ"ÉÍÍ&ò( ‰D’ŸŸŸ››«V«!×åÀ@àèè(—ËM¡bà‰‘¦º1B‰‚¼ iâ¶ácH^ba®ã ä¹aM\?< Á¶Á:<ìNñ#3tšFy3;;;�'6›Íårù|¾Z­&MuoƒàïïOßÉüüüöíÛCÀl|†x‰åUÓò;ž6dM ÷€j €Þ-ò M‰g¸ºVdº½…–DÜ¿)c >kx<yòäúúzooo¨ü©Õê»wï=z”zæÌ¹\~èСaÆY·„K—.uéÒ¾šÖ»ñ/ÚÆÙlö¬Y³fÍš•ššj¬aÙÎ;׳gOšgUSSsïÞ½¤¤¤`I kéööö"‘¨¸¸::‡¡  ,) `ÂŒ$»°ê‡ÃÁ%31à Š_�@(ΊhB’žê†3lÈ7ƒÜ:},Á¥±X,{{{™L¦T* ŸÏ÷òòºsç¼öOßÉC‡A»"’’‘Í`0pužûsù|¾­W«ÕšÆ+¸„(൷rðÄ0¤Í”Jñ†8¤F:CÜ¿iÝ‹ÉdâM;uêTaaaLLŒJ¥YÏcÇŽÍ›7Ϫ>`µ§×ú÷ï?tèПþ¹   ))ÉzC1{ÎdÒI- Mà™L&‘H0èAz1”IÙ %½^^ ÂôÔ�3€ ôrÁ�",àAà‚l4ŒHð´áˆÓƒ ‰Éd •JO"Oi˜‚ÝL¾ôÒK·oß¾}û¶F£‹^¯çr¹J¥²¨¨®SŽööön&�<4Ç kîF÷§9CÒsË+vF'f–ÆÝÂÓ°ü½2…4St4NóZÍ™D"yŒI«Y0//¯‹/â꯮®ÎzO,Xs¢, C©T"�™]Ø%ƒ9ØÙÆXiÿŽˆ…áä© ¿==�ZX™7õSQáþ1œÂ÷‚a N@¡P` „48y¨›õ2r°ÿ#GŽÀåÀõbØd0à¦"ÂY¸É¦ôëÒ L´,# ~-$Ñ™žXs›µÖ÷Ír+¨rÚ ˆØV³ÚÓcB¡P ˜þæu:ŸÏTÀ|ÒÆp]……ÄÒTt!TáÂ$[Cøf؆ ¹`²Ñ°‘€ZX%ÔAT,áp8˜à _Å Î6Æ P.R‚ˆ‚4‚4µøèt:¹\ný.=>³BŽy»r劭­mÛ“T°ZÛ¶Ë—/÷ìÙÓhí©MH÷ì©7Ta0HÓ_FÓ’ŸÉ`À’U§Ó1š–í-®›*ØLCo00èÕ:ƒÁd0 Ž`0™zŽ@Ö®éèJB„è!¼ÀšJòüµƒÁhªH3 -$ܘL‚&“ÕTdÒ ,&ó¯… UÂ!Ø Ï`ƒAo0À5êõzˆ¡PXöLx_ „ôz&‹¥öò"æet1 2HtÝ‹üw „®|¡8µ˜®0ñ…»B !Ó“1JsÑmLôùÀBÁ(ñEw\áÉX¨NÑE|#ÍkoašÎêR›Mé´oßÞz¬öÌ™©3beeqŽ…¶G‚Œ#ƒÁdB6 ü‘V«ePEx$’Ñ D`³ÙzŽI‘€YM~b www™LÖÐЀ)8Hañ¸\¬âà)ajK¯× (ê61Xl6€¢Fc+ÉårlnÎ.ÄU¨jñ ƒÁ�¤kp!˜QÄK£™œHHÈóW4`ÕÝ´RBËÃÛÌæ Ìj¬™ ÒXøÜiH ðŒ@ÎlbÐrP} OŒæìaê¯%T7+äX2'''³9 «Yí©5 Ö›>Ï,,Ôýñ—ˉDúQ°'ƒßD(`5Q€E €X„'táD£a°X&*ç CÀá@â\,½¾.7×`0è ¡P lR6é¤qX,‡#“ÉÄb1›Í.,,DÐét½:X±G•©Óµïر¸¸Ø`00ôz†^Ïáñà¸,ªqçï0¨‰P"ž B Øb5Éí`zÐÀdrX,X¶3}|,@ŽÕ¬‰5«YÍjX`ÂÊ´¡¡ù]°$‡J v±@Õ3*t§vc`‘ƒ!| ka,éõz>ŸeyX(—ËÔQ©T<PöŒe�š™ÍápjÞ@;—Ë•ËåH=@‚lcooßÐЀ-µZ ×U(B‘q׺ MZ=Ó\F-£üØÃVË7öûÇûlöÛ‚•<ÓT¡ÙTñŸ&ÖRRR@E­ÿþ/¿ü²R©|ÿý÷ãââ@ç†ò믿¦¥¥-]ºÔÁÁÁò®jjjV­Z5tèPnyú-;;G×B†ž““óçŸBFŒÛ`6l „ÌŸ?þ-,,ܸqãèÑ£CBB.\Or¹\ІINN¾q㎟±šÕ·¡£Á,ð±ßqègѾÈÍ´X'º-pâ(3ð@‹¤Áþéô49bè¹ 4ˆ¢º³‡‡Ç•+WÚ·oçΔ·° ÛˆFøP~}ÀÍCäCÚ ’âZñΣ‚—äA³MëǦJÏ–îË1müÄýãG`zÛ‘3b6ÑG©0Æ%¢òÅ- Þ¤¦¦.]ºô¹çž NLLÌÈÈP«Õ;wîDÞ*!$((hüøñÍIÓ&•JwîÜ™——÷ ýP vîÜ<~üøñãÇŸ8q¦ ´k×nÆŒ7nÜ@¼Y»víÏ?ÿŒ7ýõ×_ß¹sçíÛ·u:ÝÎ;Æ?zô蜜œ¸¸¸eË–¥¤¤Xý ÕžXôc0`4€`‹Å‚•"æ¯` ÊÞ¦Ê3ví€;Ã\?0ž@†fÁ!a�¤Õjå³åŒ ¿ht:|«4iHÙ ©qH}Öëõr¹–znnnžžž�j?jµZ&“1 ¡P8dÈZ±ÔÎÎÎÖÖŠ:NpÕ? G$<0R´Zë¬~,ä…§NºzõêW^yeâĉsæÌ9r$!WVVΟ?ßÏÏïîÝ»)))qqq¥¥¥Û¶mëÞ½{ll¬¿¿ÿŸþY^^>dȘ˜˜^½z%&&666¾õÖ[„¯¾úêòåËÏÖ=òóó Y¾|yqq1L£Áogrr²ƒƒC—.]pû¢ j\\\``àìÙ³ F×®]{ôè‘‘‘ñ ÅyVky™Lv÷îݪª*½^_YY ÏK$ÒTâÆ´4666XÇ”tð@d` V«¡R"—ËA“  %•J›Aäd0˜k™ëY\!DµQÅÛÆÃ556åà$PèE´««k@@ÀðáÃ======9Ž——è©Tª£GòÁ9Ëd2ÐøA~R©®ƒb:à2EÏšk0Š(^‚™'ÿf@4A>ö½2LŒPª¦f”‹k.H2}‰Þ‰¾ÉLwk6½fö4š»'fíQ¢œæò‰W¯^0a‚ ¦Œ$ÉâÅ‹ßxãÌÌLƒÁ°dÉ’;wž;wîÇܽ{·V«---…¡)Ó§Oïի׳õ‹MOOßµkhÚ´iSjjê—_~éïï_[[[UUEkÓ9sÆ€½òÊ+¡¡¡»wïž:uª©·Õ¬öÄ¢à@B " :M¯Õj±mÜ1†;˜”@b5•Ù1ÛFš¦¨ÑZÔ2™ zBÁÅC †Á`ðù|^:O:HªõÕ2k™Œ* ê¤AúhoZ­xnB¡P(úùùuêÔ)&&ŽëêêZVVvöìY,54Bß>=Su¯´Mé1¦Ò™&£0Dó›Q·Çò}EpP81Çãñ8ÓÄôÍUø¤ééÑ/!ÏUÕj5ÎæÁÍðÐf¿0¦§aö†àÓY;Ífá׳gOÓç=Z^^ÞÐÐ@?uŽÂÂÂg7Ž_µ7&''oݺT;×­[7tèPÔ—<sæLVVÖ‚ $„ *¿õÖ[ëׯçw¬ÐjOr°)ÐPyçß =ðÀ ¸t…b>Jr!“ 9ÊàvÉ>ÝH…šÉdò>çi25†]N9‡[Î%¬¿¡ Î' p8>ŸïììÜ¥K—®]»†……uèÐáµ×^stt„TJAAA}}=Ôrp€Twhä@%SÒÄ»£¡/ÞkíÆ{¬Æ¶Ù``H¯š‹³BBB&Ož<iÒ$;;»ï¿ÿžLKÍv6=Íö /�À$%%}öÙgÇŽ €—RRRþøãBH~~>!FÎ:t˜?ýôÓmÛ¶mÞ¼ÙúU³Ú¿¸fH ‡4ãòŸâèèHillT(P’©-œæ‰mFqýö¾üÍunªÌ3™LP£1 œO8šþÁZ�!( &Á6ÀvƒI¦r¹fÞëõzÿ²²²«W¯)•ÊŠŠ TÙH ÎD£ÑØÚÚ‚`%\£\.‡J¾J¥4B}RÔeø‹KýçåX'î< äôéÓgûö퉉‰<O"‘lÙ²å‡~ðññ!„ìÛ·O,ët:¥Åf³}}}!c;nܸøøx___{{ûÜÜÜ«W¯~ýõ×»víòðððññ)))™9sæºuëlllž¹›UZZ*“ÉÅ×­[·{÷îÁK 2›™™ ÿ^¼xqàÀ‹-:qâDNNÎ¥K—jjjºwïnýÂYíߊr�E`Ž� Õ€¬©©AÞ¶Xbý¹°ø*6]BÊÀ‰4U7qÊ'��jKC­è¯©n¥l­@KªÿªÜ�Þ`JÆétºÒÒR&“Y]]¾|ùr¨¸ðù|í;!†äâüHõ d�V˜\ˆ:ãm1½‡ Pm4yÞb*Ï,àÃHfvM€SäaŒÞ#|ʦ¹,Ì›ét:œu WAšŠm„…BaT¾¢W n ¡„D-LjQ”3bÄ•JuæÌBÈgŸ}«T*§L™[[[ûꫯ®X±Æ';88ìÙ³ç›o¾Ù»wïèÑ£—.] ·8==’Q¡¡¡„;v$''¿ûî»Ï ÞøøøL™2¥C‡ðoDD„F£ùá‡àß¹sçâ… >œ~c»ví¦L™âçç÷úë¯/^¼xïÞ½ÞÞÞXˉuss³ºB«=±(  ÐsÃ0ïù1ìÞÇÙ34%%Ô°t¡T*q°4–v5S �ÚýÅT®Ö Î è&|8"-’¦ººÚÉÉ©¾¾>;;»¾¾ègååå(HJ·’@øB÷¦ yî„z˜CÃŒŸÙ1V{r‰5BÈèÑ£Gÿòùüµkךݲ{÷îF/M™2Åh›=z˜íŽ~j ˆjøï+¯¼òÊ+¯˜Ýòí·ß¦ÿõòò»azÇÆŽkýæYíIF9à—1Ó…*jFBa¨8_  …ºaÈMO :qLy%åØelæ>&°RF²ž3}þ …¢ººÚÅÅåÆHÀ“J¥ˆjØ�gµ+Ȥab f“ÆCXroõ>P«=4äX¶‹/îܹóã?¶Ê‘YÍjO­a¿$úYŒch6Pœ1|¡GJc¯>dÀX,—ËŶx u£ÁÅc£2Ð�«,P½öš®_?[½^Ÿ˜¨<|˜wóæßÚˆ…rrèt:ÈS•••”––«�*3(Ý„R7pi8­�ÓŒ¤‰$ÿ †æZ qÌ©F1×̓ù+Z4ÓT* óW+¼q8°[¬BÑâi˜¿2Æ ˆ4:gÜNNÃt%Íè3"éѧŠù:\ Ð\G¤nã |¼órBCCŸ­Ö·²êêê–L^²šÕžÃ|½©3‚\*à|3e†ó=±�\(Òc¡±ÕŸž&€N @2ÌVA…F£Ñðx<wwƒAüýµW¯rÜÝ \®V£a@„A‡;8‡ó{ð*ôÑc°—ÎÉdòx<¹\NÒáñxèaé¡p¤Iˆ3l …Âì¯Þ²d€Ùí6…´÷7¥!X�¹&WMhaÞ©0AKfð´ä.Yé€ÍZYY™5±kµgÈ…B¡Ù´\Z­æñxXeAÕKZ ÓSB¡”›qUŽ=.�0(àÔjôP©…²Xè†`í?w.?)I;›£÷ÿûˆ8d`¨uADEšê4�KHÝ&Ô„X…†$ºà‡€ç±´ƒç wÉú]zJkmØ.^¼ø,rêÊD"ѳUZ³ZK S:hX’Á „)H£Ãz 4F3@•†x'ob…ÉÖtÍŸPc0 Ñét„0 ÃîÝÌ×7H5aZƒÉ1Ø3°ŽÎ&A ‡îÖ@Tó$MM¬Øçf´|@‚-G€aYsQä¦Lef‰š†J-ŒKð´þ¦iF®%RlÈæxLö°âoVȱd]ºtiÛ¤2øAšº'«µ=Ãú?¢¤Â ”†?øk”‡a2™nnn%%% …‚ÏçËårÀ$¨‹`Z´2±»Ã)Ø{\ føî»+ç/r'l2)ØÀ'†ê -µ*5�™  {Æ#âÒsEq¦"(=V#GD¯›ë´G/Ò¦A¤©;~d?ޱšéØ ‰2Z)õ©0+ä<ufgg×¶é+ééé£Gnll´~ÖmÞ k^X¤Cá}%¨¼ X' KEE‹Å“&MÚ¶mTìÐ £ZÈ eÄó†1ÐÕ«W/]R²ÙÜsJ­?!_ò=®Ô9Q5‘üš@ P*•(�o„�·  Zpä’¼™½ÕbBSø¬fM¬YÍjV{hö|ð°ØgƒþºD‘8�Û€¯¯¯¯ß¶mÎ Mü.0h´µµ•Ëå@…Â$ê†Ñ34Y,ÖéÓœ²2¢›¢»JÈç„”hµL& KDÈ ÀE:ì%ø|~}}=i"G/�ÿÀ¿8 ¹s�`РŒ©ÑTPz<Ls†ÅZo­% ÿfkôn¢³3=-D0ítø…50LÄÑS Œ¶7% ˜$ýçQ»¹ïè¬Y³âââ!ùùùëÖ­›:ujXXn#“É,X0dÈ£.çÁ–�� �IDATH«™µ;vdeeB¯P(æÍ›/ÙØØ¬_¿>==ýÀ„ÀÀÀ9sæB.\¿®9sæZï¡ÕþIn °=d"ôût/< °È„Þ žd2™µµµÀ6L 0$šXƒA;\›Ì»Ì4±jA¶�£+pŽô¨c•€å ü7ØH �6ÂÔ~°Ñ•ÝŒhߘQĬ`s2—´™ÊÀ±L‘ àµXÐc¦µAÑ 77φ43ÉÍèI,2©Ïß(‡ ˆhJŸ§º9ˆú§£Óé~þùg‘H4räH6›]TTôÓO?½øâ‹8Ù4‘öíÛçéé9dÈN' A²83 $Kë>55uíÚµ›6mª©©Y¸p¡]=RSS'Nœøæ›o2™ÌsçÎÍ™3gáÂ…={ö?~¼­­í;wNœ8ñÝwßmÛ¶mÔ¨Q'Ožtrr²ÞI«=‚¡À3Tq he XÝãŒ�ZÛbtÙ°%FBð�s\t› �:A #hcÛWlõ±zSÇþ•± º9Øl€êpÈ\ÀÀ ð­2™Œ4IÝ`L†pBu@·¤Ø°eýÂ<ÞocsÉß|óÍ7©©©r¹<>>~úôéݺuëÓ§OBBBttôºuë�T!S§Naé 6xzzmܸ1***!!!,,ìæÍ›Ö»<räÈëׯ;99ÕÕÕ …B>ŸÿÒK/¾úê«•••r¹¼¦¦ÆÝÝ=<<üÖ­[“&MZµjÕ¥K—œår¹½½½•¸iµG6\D;:::88€æ,LÀVHO¡Óÿ Rfð›Í†ñ¸à�56俊Œ@s®`lét:}^£ÕaÞgâàB)ÀŠåÚA‡@4=s N /ñE 0ö4…Fˆ®è¬£ÙÛhvQo:*†ŠCO¬in"Ž…—¶Èôso9íeð~¶dþMë@ŽYËÉÉyýõ×><qâÄO>ù¤¢¢Âìfµµµ}ôÑØ±c>¬ÑhV­Zeý̓>}úüùób±¸C‡ãÆ‹‰‰9zôè¼yó’’’`ƒ´´´Í›7>|S—K—.…ɤœóm5«5gvvv„¡PhccƒóZp$úMp»ðÌ:‹ÅF3Í!€Á…ƒ Ðma½}–››2žY,V&3¨IK”./aăÔ Ò4z�ª®°uç¹! âZîúï ›€È×\õåÌæ¸ŒFÅÐóc ïÔÛ4Íý’–2xæ‘Éol6[ ×’íµZ­B¡P(¦åóoZ'±Fñõõ5j<îÒ¥Ë믿¼dÉ’©S§Þºuëû=xð`~~¾Ñìœÿq›;wî™3g†š››‹…œâââ/¿ürûöí°µµµMLLÔét¯¼òÊÂ… ¯_¿þÅ_Ð#G­fµ‡5;;»ºººââbd‘a ‚“ÍpÐ'¨ŸÖØØˆ± ݬƒý(ðf·`‡„> ÿ=óÍ`0ô!„ÃbÝhb6ãqá¸OØ›™ÉlZ!f ülC·Ý ƒ�”¥ mggˆ¥ëwæI'Ö!ÎÎÎaaa}ôQLLŒ··7àÍÞ½{ß{ï=³s”q~X¿~ýÞ{ï½cÇŽ­X±Âz—ÕjuCCýU~õÕWg̘a´YddäK/½T^^~ýúõ dddìÝ»×:òÀjÿÐÒÓÓËËËQh€4ÕÀQ±PhÄ´¦'D*•ª¸¸ØØl6—ËÅÑ¢XªA4"M’n| ñ F$@nÍ×WóÁJ€\&“ ÙfÔ{6¯åããñÔŸ0û•$8„ÌÂÁt—Ëåóù�$mCm…BÁb±œœœ„B¡T*…X‘ÉÂÍ|j'Z’ûjáÉ[ÞÕ?¼–nîäÉ“£££ËËË÷íÛGqrrb2™%%%vvv®®®—/_ưÉd¦¤¤üøã„.—ÐÐÐPRR’€³Úþ—íØ±cáááß}÷]NNާ§§«««‹‹Ëõë×Ož<YUUÕ«W/GGG±X|íÚµ³gÏ:99y{{———«Õêüüü“'Ož<y59¬fµ‡µúúz•J…êg„˜Eìw4¢EÁ¿x`|CÏ0†JvÕ ç rtÈ"CéL@#€éêjX¹RÖ­›”Íär9f“0ÌBwûöm@ H”Ñôd¦ÙØØ PÀB, ZÃYÁÐ9­V+‘H —OB]Çl”ðD#Ãà VÞF†· ÆêÐÚ©˜É42¬Äà<išg:(]ãi „¶N§S*•J¥$$À€Sõ<Ø'Ü[˜ËgzèJ’ôXÍÛC'ÖÀ Ô±cGxüÎ;ïp8œŒŒŒ¾}û®\¹òúõëo¿ývTTÔ€à,?ÿüóÌÌÌŽ;ÂàœŒŒŒéÓ§/X°Àú›6l˜F£ÉÍÍ%„¬]»¶_¿~}úôùøã322BCCß~ûmGGÇM›68qâòåË+V¬3f ƒÁèÒ¥KFFì¡wïÞ­˜NµÚÿšA~Éhd'ŠiBX€™4ô¡°=‚‡‹‹‹D"A·Žý7å@ç?–ah_l¤4<j”ºÉÍ1QŠ ‰×(t %":uÁFT4ê”””Ѓs4K(‚2­D@(!d�3$ˆ[¿0Ï�9#FŒ ÿ;w®ÙÍWž{î9BH×®]?üðCëÍ5º“ôÍäñxF·(&&&&&ÿ¥ÇYÍjÿÄzöìéääT[[‹�€KoB®p}Mš$Î0¾a2™*• P¤‰ Fš˜Íl(÷‰ø+}Bu“¼ø¢ö›oØ,™0Asþ<ˈ‚oðvT»cñx<\ò#³�é8l€dæÌ™[¶lÓÆ²B,v&°)vùX¿3ÿäXÍjV{Öíúõ뉄Ž`ÐûcÓ =- #ž:¨Tªºº: †Õ××c”@æSa6ÑB8}bõ6l˜]\œJ(äæäxò' 0‚`˜B< xcPPPnn.M]ðÛ·oäôlhÝLÀ'ì6EX²ä1ÍR+Ffõ:[Âh ¯ 2"-äF›½"ÓL>ê1bÞÌ4öØçå´m+++kÃÜkqèÇ@LŒžˆc4L" ã¤#¡ÊÊJt4€80 †ß@!÷‰ŠÔ0€° tç@òª¬ŒÉf³Û·wËË«3æ`Þœ¦Z­†(`ƒ²:°C‹uíÚ5 S�áßÚÚZlà%†€#0ì{`ÞtƒÖMÄ=r }»ÓÙnf/ÊH€§5Õ¬F©¯¯oÃórºvíjýˆÿG <5¨>•mHS3?!D¡P`è/TˆhÀUƒð…^µ)ªaŒ Æ"˜^ƒ‹ŠîËd<¬-ÑBg8³ 9Ø‹ƒD8š)‡7È‘C‰, à8`‹–Z�$³0²ÌjÖÄÚãµsçÎÁìÛ6l§OŸ~ór®\¹RWW׿¿0Omû��F`Q7�L"MúÐ0ÃF*•‚7‡P€Åb988H¥RÒD<Ãl6QBÜ€oA˜ò0 j”›Ä®OÄBŒÉ (AxÃÁk¨«†¨ƒÙìÈAúÍÃú 2¶áÜp‡Íit"]¯‚V,%ÍH“YŽ<Ìë4ýø0e*ô‰gÛ’ô“–u L_¢âáÒÄtQþÀlžrÌ[pppÛž—£!Ÿ@æ°¢¢âùçŸoÛ%YðÑOsdž2*• †o‚k€n@Ï–†iј‰2>Ÿ/‰¤R)†MÈëE< §D#+ ‡ðù|6›…B•J(¥R© †B¡�¶4v€ÂѱæË€ÅlÖ¡£+ÒDZà .Íh¤›/Œ/a“cú®–|Ì&¦Ì"j=˜Šl>ìOØt”õÃ6ëТ«fÒò~¬Ê]æ ÔH m׎;öÄÆž …Â6|'õzý‰'`däÓiX´‡nGD†S×è„¶ßCê 6Apèfäȑ耰Ñk0(!ƒ‘Ô`ø|>Çóòòruuµµ999yxxØÛÛCW¦¿¿ÿ¤I“1:ÁD–£ÐõÓ+nXÖ`a )N¹¨ƒhÏçÃöp.—KkµY 5±fµ§Ë  ó÷­·Þ²µµµÞ§Ù°ˆË¸:Æ%*¶Ü£V öåÐÉßä‰Á`عs'–FWt:X,...F™jÈ Áqmmm]]]»uëÑ£ÇE©TRQÑ¡¤¤¤²²àäþýû;vì€Q¹*6šr0Á•›› ù=:íïBÊÎS ÕÞè Ð `Ï-d<ù ƒ¹‡Š¤é�衲Íän­ŒH³“ŸŸ¿|ùrü÷Å_”H$W®\ùúë¯ !›6mºvíÚ¶mÛ<Ú„#FÀ§m[QQÑâÅ‹'Nœ8pà@BÈo¿ý÷ÄÇÇç£>¢·Ü¶mÛÉ“' !ƒ?~<!äÆ+W®œ={vdd$½e^^Þ'Ÿ|B±··ÿâ‹/~úé§~ø_MLL­n°7ß|ò鄯¿þ:''góæÍPNX³f !dÅŠ ƒ‡'ÙºÖÐаuëÖþýû¯[·îÖ­[pù­b;vì8qâDJJ üûþûïÂ%÷ë×7S©T“'OÆÊè;i´Ïõë×_ºt ïdÇŽ±½lÛ¶m4^ž={–¾“ÉÉÉGÅW—/_îëëûŒ~iÁ·Â2¢ˆo 8ôe 0k„Þ‡fWÃÌ@2T}ÆÑ,J¥’fŽAŸ¸P( puuíÞ½{HHˆ¯¯¯££”­‡Ç˧N:þ<0°Ùlvuu5´å“¦ÂÖ„f†RÍJ¥ 9؇…(ÒÄŒÀKÃÓß çF—y åø´%Héü!Fx-�Œ2!™ OZ˜&g r´µÖirêêêÒÒÒ>ùä“aÆÁòdÁ‚¿üò‹Z­þòË/·nÝúí·ßªÕꜜœ3gÎ8p ]»v"‘¨ÍãÍܹs/\¸póæÍØØXBÈ;w-Z4yòäaÆõìÙ“Íf/[¶ zîŽ=ºbÅŠo¿ýV*•¾ù曩©©×®]»sçö„Êår©TÊápÞ|óÍÁƒO:uРA3fÌX³fMŸ>}ôzýÏ?ÿ¼zõêéÓ§ã H$’'N 0`Ù²e„ÊÊʱcÇN:uâĉL&ÓÓÓsÿþý‡JKK›6mÚÏ?ÿܺ7A£ÑTVV>÷Üs­E¶¾sçδiÓŠ‹‹«««á™¥K—îܹóÒ¥Kß~ûí„ Ž?.‹ëêêìì쪫«ùå—7ß|sÆŒ ãòåËï¼óν{÷èõiuu5HUž9s¦¤¤b2''§„„WW×+VLŸ>ýÕW_ýå—_`ûâââùóç5êõ×_‡;ùÞ{ï 0@«Õ~ûí·_|ñLay œŸÏ‡õ>Þ%µŽI0À!¨óÁÚ_£ÑÌ«7N¥V3aìÞÍÛ³‡ÕÁGuu¹³³^¡`«T @àèèèêêéîîngg×®]»¦ÄÚÙÙùùçŸwtt¼|ù²X,®ªª:þ¼D" ”Ëå( Ä3NÇà1ô\½Aj�OŠ˜—Æçó¿k´y݆ÉdJ¿rs¹ \x/^>&èpL~±Ÿé`BÊVT‡{6kîîîôw7)))%%eçÎ!!!6lxçw***ôz=½åSh'OžT(;wnlllhh�¡„‡µM›6]¿~½o߾𯯯/Ìú†›‡‡!døðá</!!A.—»ººòù|™L&—ËwíÚJÒ¸·¯¿þúÃ?¼råÊüQPP——g0¼½½E"‘H$*//_²dÉ{ï½GŸê”)SX,Öˆ#òòò˜LfÇŽËËËóòò¸\nÇŽgÍš5{öl©TZ\\ìîîþ8xwÎÎÎcÇŽ}ûí·_{íµþýû·Ê>}}}333,X°sçNxÆÓÓ“Ïççåå•••ÁãË—/<xëÖ­ëׯ÷õõŽŽÎËË‹‰‰éСCffæ¤I“~ÿýwÜalll÷îÝCCC322¾üò˼¼<___>ŸðàÁŠŠŠ+W®466Ò’©žžžçλuëÞI{{{{{ûëׯúé§Ÿ}öÙ`÷=¾e2ʰlC<`’ ¬‚5 (•A%£õz½­­vÅ ^z:§éy- 8@þÇëÔIåí­vsÓ/\¨øÏÒÓ™ ]»vaaa!!!b±¸]»vP%U*•ŽžÉdVW×2Œ€€�½^_]]íìì|ëÖ-¹\ŽZ^ôTпÒ;D?BOÎZÇÉä 2ôß|"†.D§kÐ1¤ †Ž=žt ñIk ñx<f6h Í̇65m:XÚ2YÀ�«YFÁÍÊ•+ÃÂÂjkk===7oÞ¼gÏ£Yæ¤Y÷Ia 9åFWm=0-ù�È9räȽ{÷:vì8fÌX•¯\¹òí·ßŽˆˆ „têÔiÑ¢E„3gΤ¥¥}þùçÑÑÑOç¯î§Ÿ~zÿý÷cbb:uê”——ühcÖŽ;6oÞ¼åË—Oœ8‘2iÒ$èª{àûôé³hÑ"{{{BHEEEvv¶^¯ïܹ3¼º{÷n___„7°×_=,,,;;û·ß~óññYºt©X,.))ÉÎÎæp8ÞÞÞøuüã?6oÞìçç×ê7S.—_¾|Ù××÷?ÿùO||<|Zݼ¼¼ø|~vvvQQ‘··7ŸÏ÷ððX´hQ``àÔ©Skjj²³³þùççŸÞ¬ZùŒ3\]]ÝÝÝ-ZtïÞ½_ýµ²²rÆ ;w®¯¯ÏÎÎnllìÖ­›Ñ»Lïäž={‚‚‚zõêõ¬—sÐçBÊ éÅØþ0@Àáp G+ Ã` ¯¿®Vêõú³gyüÁA#„Ìœ)åru11ªˆ-!äúu–ŸŸÜß_Ãf+]\8îî—=<*œ/ÀÈ`0ØÚ2s˜Wö«Uì› ÃÞÙ¾1¼±¦¦F£Ñ”»•×ÕÖA ÆhL`'“ÉÔõÒißÑ2 ²‘BÈ÷DP(ÀÍøKùªY*BïKžAb 5~ÅqÀ<N¡¦YÚÍ%©01ÒsFÛ Š(މÃÈÉtTšN§C%lL|™æ¯pž´iªíÃ?<yòä„ èWñ@f'dÓGoîÄýLuLI§-¤}?äxyyõèÑG … ¤¤¤ <8""¢S§N‹/&„TUU%%%:uê©…œüqÅŠýû÷ß±cGllìo¼ÑZ{ÎÈÈHLLœ3gà @!FàX¶ˆˆ�oBHddddddJJÊþýû_{í5BÈ®]»BBBŒ '!!(•Ê7NŸ>ýçŸ^¹rå¬Y³’’’><tèÐeË–=z4999((èqÜL™LvéÒ¥}ûö 4höìÙ 9EEE .„Ç)))F_ÖôôôªªªÅ‹oß¾=11ñý÷ß÷÷÷‡ï[@@�¦ãvïÞmrfΜ à¦§§3¦   sçÎ]ºtY¼xñ… víÚ…ƒ‹ÀââââââðN§0räÈgr .¡ÇnÒ+\¬ÀCTQ]]Íd2a<3¾\OA!/ôüó=/_þI*•™Íf߸Áe2u=z0 i$„44°nß¶ãóùööö"QgÀŸÇsg³t:&!†ªªêªª*Ûîã;KêÝÔ²ÚÚÚ®v]KJ»ñ»åÜÊá^åÚ4Ú(ä ¢!Ä@ˆ°™ì¿jLÁÓh5 /!„è¹L GÎA¨ÑhX–ÁÅÀ¬e;‚3rŒœ8*#ÐÝ ú«ý[‰µ   Áƒÿ½5›=g΋5iÒ¤½{÷Êd²)S¦$%%ÑÅí§Ö"##]]] †§§g Çä=Ðnܸ1iÒ¤ L›6®"´ðíR©´±±ÑÅÅ¥ººÚÖÖ–.†Aû¤££#.I*++E"Ѽyó`ÍÞÜ>W¯^ýå—_æäätèÐáqßÒ^½zý“;Ù¡C‡Ï?ÿ¼…‹#BˆZ­®©©qppˆwrrJNN¶°qee%›Íþî»ï6mÚ$°ŠŠ .—‹7–ÒØØ(•JáS°³³£¹ã555l6ûYÉŠ'”…†<`†ŽZ”1ᥦ¶íµkü£GY™™A™V«…,h}}½^¯?z”a00Μá‹D//²ys«+÷øqg­ÖO«õV*»tíÚU*•æææÊdNN>;G TÕýYô§››[;m»Ûõ·kjj®½¦;«3È ƒ¥e!sÃä`žô"º»:aw¡F¥áÔr´Z-‹ËBÍ7ƒap7!!÷‰Î[ÇÉá° ¨Pÿ@yPÀ]Ô;€/! 9}„;L(†…åÍÌ ôvÒÜ>%Éš5kT*•P(üøãéΡvYØÿöï˜nÿˆcj\.wÞ¼yL&3!!aáÂ…ööögÏž­©©quu}9œV´?þø#66Ö`0×××ß¹s§wïÞÿpŸZ­¶¡¡áþýû€;v 1bÇKLLôôô<}ú´\.‹ÅPæ1²o¾ùæÃ?<}úôüùóÝÝÝôz}hh(!dÖ¬Y„-[¶À–eeeAAA|ð¯¯ï¹sçÒÓÓ ÂÃÃíììzöìyãÆôôt@\TT¤Ñh.\¸�¡zddäãð˜UUU·oßnhh çò=ôz‡Ínß¾}s¯ŠD¢ôôôk×®‹D¢ììl¨åtíÚnBYYYTT”Ù·0 {÷î£F2 ¿þúkAAŸŸŸ««ë¢E‹JKKçÏŸ_]] кuë6nܘ••õæ›o¼ôÒKp' !cÇŽõöö~Ö‡©Ó%üüÀLJ„ip¾ØN©Ã={ª™L¾\^ûçŸÜº:öºuë°”Âápär†ZÍ®¯g¿ø¢«@ ppñx<…BQUU¥R©:uêT]]——Çd2Û·o_WWÇçó;vìÈãñŠ‹‹¯\¹’››{ñâEš‚ìât:ç ‡q‘¡ÕkYL‹ó—6¦Ëôz½l³Ìæ9ƒ!ß/gŸa;i$ ^0îÐ/;’„@™{X’4æ¯èü˜Y_aê¦a{#FÙ½6´L-[¶ 8Dô§LšôŠxÚ�ãB£]C~éYá…C»i™¬'ËÝÝ}Ê”)&??ŸÖÝb0ÑÑÑ®®®xÝ»wïÓ§!x<žƒƒCBBBiiiCCÃk¯½ÿ4ÿêþóŸÿèõú˜˜˜}ûö]¿~ÝÆÆ¦¹›eeeÎÎÎÍ­ß †H$ŠŽŽîСƒÁ°³³³µµ­¬¬¬¬¬´±±éܹ3“É yõÕW;uêTTT¤×ë'Nœ¥#ƒáèèØ·o_¸«L&ÓËË+66vàÀUUU•••QQQóçχ—ÂÂÂð¸B¡0::zÔ¨Q:®´´´}ûö‹/îÔ©SŸ>}àè/¼ðÂôéÓ™L¦¯¯oMM <éïïo–I˜ŸŸÔ’‚“Ù;�‰µï¿ÿ~äÈ‘F©?#»{÷n×®][BÍ„=wéÒvØ»woGGÇ?ÿüS$½ýöÛ~~~øLHH¨¯¯¯¬¬‹Å|ðTèï'ü>räHOOÏÂÂB6›=}úô°°°¸¸¸ºººÊÊÊ.]º|ðÁàb|||^xá…¨¨(úNÂNzôèbù´ïÞ½Û½{÷§P‘O¡PH$’[·nåääÐS´Z­P(W‹Âþ¨² ÷„xÃ`0˜LV‡:­‡«ºšQZʆ7Ò¾µŸ…B¡½½½££c»víàw剙†ââb©TZ[[[WWwâĉcÇŽåççWUU*Ðýí¨Oc4Ω à±&ÁÐ3Øyl6›­×ê×¹†f"ÐÑ�]‡°>ñnݺ¹¹¹aõ"??¿]»vHlÁ·Uéin1îÙ›™VP¥?šþRØÿm ¦­Eôþi‚Cs"t ÇÂùÓ56¼W¸«iÓ¦Õ××{{{–«Õê»wï=z”zæÌ¹\~èÐ!àC·U;uê”­­mHHÈ•+Wè>#»téR—.]ìììÚpV÷ðáãGnll|´·WWWgggBúõëg9·vìØ±—_~ùŸCOÚêØ±c¯¾úªB¡xÚέ¦¦æÞ½{ܹs§‘S€ôÐààh^AáNÜ'„¢‹�.5ÊkÂ>Y,–‡‡Gûöí…B¡»»»V«µ±±qss vppÈÎΖËå@ˆohh(...--­««Óëõ ê­£:Ã,ðn8À<)=ëÖìp!¨™äÖ!J¥u 0øƒk„nÓÑ£GÇÇÇ÷ìÙ%:`ä1€PÞ\”ƒ.éf³jxçñð‰<ð“5Eä˜ÒÌöåÀÝêQîÿüùó………111*•J$566ÍêH}� =•§§Ü\\\G“©Õ‡¡z&Òši?y3¬ë@ æe ˜F>ç € …BÀZzÅ S–Ùl¶R©´µµ…ô)¸6±XŒƒ«!¦¬¯¯ªü…“‘Édòx¡ð�� �IDAT‰D06›4i}µ@Ÿ)¢išG€Ñ.Àµ���Ja?¬P(ÄQ‡všf¼u4ßkA~† ÓcáÊ�!Ä4j¡‹Ffå$ðd0èi:ð€Am9fS‹¦9C!w %`i¼iÖŠŠŠZ˜zíÑRjfZ­DÚj”ó”Ÿ!~‘ lcô× þ‚ ¡¨‰¥…«W¯š¾ŠwPðIn A ÀJ™Ïçß¾}²¾Ðþâää$***JKKkkkKKK%Icc#xIìÂÁ‰ð“9€|tÐßjÔìîEªu%(`8‚3Lù|~ k9–?÷~+èV\#H° oC¿d™ÐÂóiÉ%›mßy„qVȱä”Ûð¼œÇÄŸnîëÞ†k„V×wxÂøtº?°<5¸`ð¿8ìY¡P…Bè•ÁØ¢‡††‹>ð^lîÑëõååå"‘ø�B²³±±âhYY™Ýýû÷ai"•J‘)€±ÝW“°q ¡X˜|ÃkÄ•¸^¯‡ 0½%„;€¸ô¨«÷{|f…3æçç'žÚñ'­er¹ü ¥wïÞ Ãßß¿Í/PžòÜŽÚ„™Ó´*3ºÚþØ,Iþ»\ (…Œ5�'� à#H¥R…BQ__Ïd2AûöíKJJ`®¨X, …ÎÎÎ …ÂÇÇsV‰K8p8GÀ±lŸÁcñ01n£¯äÚPŠ !åËEú2‹Ù("gô’é<fÒb€Ù”�<À žÙžSÜŒŽŠŒvEWõé³ÅØ÷_™zl…3VPPpÿþý‡Ò^}ÍÑѱ9†q+ZnnîSXWou‹ÅØ úâ ¸o(c�¢p¹\(ÂC·Š‘=>¼?=c ž`Ê'à÷á½<ö¬V«¥R)öÁ888¨Õêââb>Ÿïèè¹,Fcggçéé |6ÌïA4ƒs} ‡°‡†&àJ#:ƒ+ÂÙ9ÀGP©T(³†£P˜Cƒ1½hÏÞŠâf¦¬ ³çCx¦D5Ó3Ñö„ç5X!ÇŒétºØØØ¶=¢­´´ÔÓÓó‘k-7FÿL>rΪ¢¢¢]»vO-²bÒ t—‘H(B ’cà”±þa ÄÄØ+ƒ5yÄ�@�­ƒ¡¡¡´Ô�ÆêëëKKK¹\®½½½@ `±X*•ÊÙÙÃ{{{ƒÁàêêŠ�1 ŽÌAV$œò p²5nIñðð(**¢Å­Iw€Á€š 8VáÖê­óïäÚ0IúÔ©S£G~2ÇÒëõm8Ð1 gΜyõÕWŸÚ3¿Œ•6›%ŒNпC§$â 8w,r�8Ñ6À�J "‘¢“êêj¨ÜÀ6%%%Z­ÖÙÙÙÉÉI¥RI¥Òºº:¶P �S^(µ `€A•Z­†s3B;ÌïáèOÌ"ÒÒj�·ô¨7œ‰€Œjx¯ÙH‰FQ…ÙQp‹žaª­I· áK¦{3í³1JS ,ôÙXP礅 ,7è´œie…«Y­rx<fØ`ú20Ö0ãÙ*$#¡‹GŽÎ - a‰0†ll 466âüi­V "î¶¶¶ÎÎΉ„Çã …B ÀÆvÐ…<(Ç@Æ h¾�N€^ÀR+,,„ äâT*•½½½B¡�PD’4BŠ­ÁU4·Ð4"IÓ~¹…ƒ8mt“Í&¾,iˆ9(rš;ybn^Ž…†!r,¬¿iÈy`>£Ù—/^¼(‹ÃÂÂbcc###'Ožü°4§ÊÊÊØØXœ¸eÁ–/_.‹ŸX ¶OŸ>S§NÅ“X,Fi™Ö²†††·Þz+:::**êwÞ‘J¥·oßîÖ­[lll@@À™3g ÅêÕ«ÃÃß{î¹øøøÚÚZ|ïž={bcccccûôé#‹333/\¸àïï‚ü×®]ûí·ß`ƒèèh±XÜŠCÒÖ***Äbñ¦M›àßcÇŽ‰ÅbZÓ¬U¬ªª*...66¶wïÞÛ¶mkhhˆm2??¿1cÆH$’ &ÄÄÄDDD,Y²„žmSQQѧOŸØØØž={îÝ»·¬¬ ßëãã3kÖ¬ÚÚÚ‚‚‚€€�ÝÖÆŒ&àJÑIÑm1ôR\3ÎÎH€ß)²“élUCCC]]]}}½B¡Ëå*• Þ%—Ë•JecccMMMqqqmmmYYYmmmmm­L&ª4(I#Wë˜Cï }?·žJÉ©T*ƒÁ�%%ÒÄùÆa¦Øåƒ“jÁnµÖL¬étºúúúO?ý4!!§¼ØÙÙUUU:uªOŸ>®®®‡îÚµk@@€J¥:räH·nÝüýýÓÒÒ`æDTT”Ýœ9s ¬zøðaøBÄÄĸºº]¸p"‰¨T*ëëëŸX"+44ôúõë7oÞìÖ­Û‰'lllÄbqëââÅ‹æûï¿/..<xpxx8Ly9|øðÔ©SÇŒ“œœüÙgŸíܹó¹çžóññÙ²eË|�ï}ã7Þxã ¥R¹zõê'N8;;ïܹsÖ¬Y³fÍ9r䨱c¯\¹ƒj¶oß¾iÓ&//¯ë Äãñüýý³³³ËËËíììN:åéééììܺG9tèP—.]¶nݺuëÖÅ‹ÇÆÆfffB.\¸0yòä^½z={–ÍfÿôÓO¹¹¹#GŽŒŒŒÄ¹DóçÏohhÈÊÊúøãgΜ™ŸŸï=sæÌäÉ“322@µúÉPøþ•Ô¸c táf€‘HÔ¾}ûÆÆÆúúz¹\ÏãØP\ec%M\øhžLZcc£H$Ò5¼ÚÐРV«agqq±H$R(\.ª22™L*•ªT*zTiêœG‰x jBÈq€TŒ]T*�À òP[‹ ÃÄš)ËËlf _‰>ÐBÕúSFb=Ý•Î@>ŽïU Ó‰˜XS*•[·n½zõêþýûW­Z5eÊ” 444L™2eáÂ…ÙÙÙ+W®œ9sfFFÆ–,Y2eÊ”>ø ++ë“O>™1cÆñãÇ:´jÕªÄÄDƒµeË–'/›¸fÍšE‹Í›7/<<ü‡~X»ví‹/¾Øº‡�üÍ›7_¹r%22ò$$IRRÒ{ï½¼aÆëׯ/]ºôÎ;3fÌÀm>ú裾ð ÿ–;spp˜3gΘ1cƌӽ{w�ÎVçnMž<yòäÉ÷ïßOKK9r$êþAÄóî»ïB† ¢P(öìÙÓ¯_¿æÔóh[¿~½@ €›rÚªÞ�*@yþÇÉÉiøðáwîÜ9pà�x.̧Aô€%,ÔÓ™.,¨€ß‡ÔSMM æÓàм)•JÙlvxxxVVœm«««ƒš“ÉìܹsAAÖrH“À –vÀ·òù|šâ…§JÏŸÆRÔdC€Dêî¶¹q˦‚•¨ „¡’e3¥º™5< r£óýÀÄ2 ñÄ7'ÍT=Áìë–&Öðg9lذ÷Þ{oøðáýúõc³ÙÇŠŠ:zô¨^¯_¾|ùþýûÏž=»`Á‚ÐÐÐ1cÆ9r¤¶¶¶¾¾þóÏ?Ÿ>}:Î):xð —Ë3gNRRÒ”)SìììfÏž½víÚ9sæ466â0à'f666+V¬èÔ©SRRÒÆ[oТ¢¢ÂÃà KKK7lØpõêÕaƵ0ï4þüðððQ£FÁ¿íÛ·4h³³ó¹sçà™ÿüç?ööö‰‰‰ÿ®/ëӧϨQ£–/_>yòäÈÈHöÓê¦ÑhÆïèè¸zõj=pàÀ“'O®_¿·™1cÆýû÷7mÚ„cîš³äääììì 6ü/¤2x< ºàœµZ ¡C]]Ýõë×]\\ªªª ÛFO7€m0yÏ€¯?H7T’&Ý-p¯ …B*•â8�à( ]¹rE"‘@b­ªªª¢¢¢¶¶V"‘ &BCC=u<ñ0vÁÖNôªˆ7`a$Ôh €vo¸"„R+cíñ¦y-¿<kÖ¬½{÷¦¥¥mݺ(ŒXÎáp8ááár¹üêÕ«ÙÙÙÞÞÞ;vì8þü¾}û¢££ïÝ»g Åb±8::šÇã]»vmèС±±±&¿>>Ójµ‡þí·ß|}}ßÿý²²²Çt ^½zõèÑ£´´´²²222òêÕ«{÷îma7Ì•+Wœ1iæììíèèxåÊxF&ÓúßÿŠ999mܸý~üñÇŽ;¶ú!***žþùÎ;õÕWíÚµƒ'KJJªªª |¬««7nܽ{÷Ž9Ò’xåÞ½{uuuÿ#j{ …ÂH˜ÓPeR©T+W®¼té¢ ŸÏl`2™C† …"�l�œ O“Tàßy<žF£: dÒ´Z­R©T«ÕJ¥R.—K$’û÷ïËd²ºººŠŠ ø[ZZ i=8hMM Vepñ®ÓéfΜ ‡ÃÚBÊ�Ã'c¢ 3U*À0¡”uÀ§Y6ÃhÞǧf™óÖÂL—ÑKFSV6öOι¥ÃãñlmmmmmͪGDDÌœ9sáÂ…jµfm]ºt)///99ÙËËkΜ90gŒ¶¼¼¼ýû÷ß½{wñâÅS§NÍÌÌD¹Ö'iß}÷ ´¿páBhhèØ±coܸѺ‡¸sçÎþýûëëëñ™ãÇ_¼xÑÖÖÖB~äȑӧOC¥4M´„bÆüat'+++ ð”$mÀ=¦OsÅŠ·nÝÚ±c~«ªªrrrúôé£öìÙsäȑݻwà p+û÷ï¿víšéÞJJJnÞ¼ƒQxÛ6š� éð×@€&M0”¡Û!µZíï¿ÿ. a4°Qo<æ¦�t:ðPR…`ü«T*U*•R©„š1¬;1RQ(4ƒ”„M°~ݲe ‡Ãl0jˇd †>xbH�þ7±à%�-¡Pˆ™Ãæœ)ç¿ 5LY-3³\dx ˆÚF†¯šÝn†OBW¯©,4iâÍ®nnÿP袿0–O¬%5­J’~î¹çRSS«ªªàßúúúÄÄÄ#F… &à€Å‰'&&&.Y²äìÙ³!!!ýû÷OHHHKK+--6mZzzúžU«V…„„@…yÉ’%AAAééé-)�´Ü îuâÄ µZröìÙ5kÖ ><77wæÌ™0£å»ï¾;uꔟŸß Aƒ!‹/îÞ½{tt40è`P!äîÝ»~øáàÁƒoß¾={ölBHjjêÍ›7;ö?kµÚ%K–Àãyóæåççïß¿ûöíôBÖ®]kggG;v¬««ëôéÓ.\8nܸììì%K–œ?~„ ¶¶¶'NœHKKKMM¥€¶a£uÆh­~ Jš¸³Ð^ƒ%� PQîat@Èô2`ÔQ0h€ÇtR[y0¤ÀäM;i}ps˜£ÇÐ+w¸4¸¡P(—Ë‘`¤™†)8£5;¸`t¬Öô×cü66÷pÏ|}}ñ™E‹ÁܪøøøððphÎïÝ»·ú‚_|±]»vfèСݺu …iii^^^nnnZ­vèСþþþööö+W®¼}û6!$((«ßfêµ®%''ÛÚÚÂcWWW8ÉÖ=D``à¶mÛ�Œ;tè ‹}}}A·mèС!!!|>ݺu h8eÊP!ÛµkTS—.]*•Jé* :t(Ìm›4iÒ /¼ðô8ÍåË—?>Æ×üùóLJÿÚÚÚ¥¥¥á ZøNânnn"‘(--ÍÓÓ³cÇŽôwR DEE¥¥¥­0öïßOO§nc†Œ/ðæà»-0%‰är96PŒ4qˆ‘Ɇüt†5Iƒ€ê€.—ËU«Õèô•J%öcÒ"7€FtÁ†¦œA¬‡†“lj8ج ‚Є8=nçïôNÑ. ûL­ö¤!G$EFFÒÏàÏÛÃÃÆ*Ëd²O?ý477wíÚµ¸ÌQFÃÐ. !......FÛ<1£O’Çã=¦ðõõ¥1›Édï$ÎÆîÖ­›Q†Óè½ÞÞÞOɪucDËwŠ ô 1½“ô÷Êè;éäädú‰ÓˆÕökü/q „¨w Ñ &yP.àyÕ666 ØÙ­ tä£ôz½J¥BTCÏNK‹‚˜ ŒMƒ ƒ4•a ‚s�jœ„†‰)Ô´¦§�à~çMšÚaot ' &œ$"\Kî*HÉ‘feÿ$G0ßÜ™À=‡ÇzÍfºL·7%é™g{ìÓ+,,¬ªªÚ½{·… öV³šÕþ]`P©T˜E�· n .PË@½åý1åÁ‡Ãeh2@]gäCŒx†A º0¤##÷Ôè‚išP�3Ø¿B¡ ¡Â(Ð=¬[\‘* Þól(€”<tÓ-̵X‰mÿäøûûùå—mõÖ\¼x± ÏË¡ûó·)•ÊóçÏ[lÿ–Ñ#/iœ \è^K/HS·#ÒØ€‡;‰BÝ6(ªÃªŠùjƒ8�E¡p‚g‚±èP ŽE·ûÐ%š0†œ4Ò¤* 5$ggçšš”þĦT$×aù48Kž^ÈiÛð¯Ì“x2ö$§Šñx¼'9îÉÛSÎ|Cmô°¶Â^}ìs„PC¬Ü 3 €¦cîƒ�'Œ3P²8f8èÛ6qJ ”^`þ4i"t!â 6„IÈÅÑ­õ8wRjJ¥3uð€$ŠªÀ,Ë,ã‹P2b¦âÿtÇ¥2ªÙü¾тÈ=ñOÒtp5}Φ»¢Ï¿É(4§‡JwFù7Ó†Y+ä´Ô222Ú<ƒÖÁÁáÉTÑ~úé§6<¼�ÌËËë©—r˜ƒù˜ð¯““Suu5¡»ôÔj$@ÒL§ÓA‹(-¯‰¼j¬î°Ùlà’@]<)ìj 8ƒ$ŒÃPK 9ÐèƒÀ©V«…B!p¬ôàÒ�iPf¥Ø0õ‡<俵5é‘BfQ‡4£ÅÙÂl›D‘‘6Ú?}†“™''ftªF€×ÜKôθL·BŽy‹‹‹kÛª¢¢"±XüæåBâããÛp²Â`0”––º»»?µ°=…Ïç+•J>Ÿ¥‰D‚Ë[Ì\!Ïl”¦Ã—0U~zB¦½Á€ô“A#äÄ02 w0Ɇcªéƒ·AE ‹I(lƒI?j#¹àßš•iM¬YÀϲ­^ÝÙ³g[]É´9æR†œ¬¬¬§y^æ¦hæ”p M�÷`Ãd2]\\4Mmm-ÒÆp'8tF#À§#à ¼<MA†ý &!‹3`¨È‰*mHI€HK©T"73˜ ĬÎh@L¥rØèÂÒÃÆ FXˆ̲ãh65 û7}£Ùužébµ…½œVȱšÕ¬fñGÎf @P[[ º/8‡Ö(à f ¸^^*•âàÒD‡ãñx …Ãä";88ÀTØ rw´:�zR,ïÓÌcHsF€N§ƒñÄ@Áš«†}ÒBÑpªvƒòRÔ~Ð_?ÚTPzVf[9–k-¦Ø�•˦-ïß,äà, nkuÈ6‹iYYY...û÷ïo“?ÂÀÀ@l-,))qqqiu…ÇšššqãÆEEEõéÓçÍ7ß”H$¹¹¹b±866Ö××÷øñãR©tÉ’%½zõêׯß!C***ð½8/'44ÔÅÅå×_ýý÷ß;wîÛ©S§ .༜¾}ûº¸¸|ñÅÿÖ,//wqqÁƬ#Gޏ¸¸Àt€V´ââb˜y¼~ýúúúzœyãáá1bĈªªªøøøèèè°°°yóæ544à{ aLÑöíÛKKKñ½nnnS¦L)//ÏËË‹ÅÐéÜö  B©TVWW+ Ð}Áº=$”^yå777Å!M/B¡<©L&ƒÙ3�BPº·³³kß¾=tü€C„â4šúúzœÑ ‘²×pJÎò¡s\È‘ÃyÒ^^^Ы‹E&dCÀ„7\æãn‘n‡`šo�ÁKð÷±¶¤XXÖXƒÕAZZZEEErrrrrrMM <(,,$„”––¿ˆL™™™?üðCqqqrrrII‰L&Kn²§*µ2xðàÂÂÂÜÜ\ð’­^û½~ýº““Sjjê¦M›öíÛwìØ±iÓ¦ffföïßÚ´i—/_þâ‹/–.]zðàÁsçÎ}õÕWøÞ7Þx#333---...00ÐÝÝýøñãï¿ÿ~fff¯^½¦M›Ö¿ÿÌÌÌÌÌÌQ£FuìØñ±¶aZ6@Я_¿ììlø¸333ƒƒƒ;tèкGùý÷ßûöí›™™9sæÌ>ú¨¢¢.ÅŠŽŽŽqqq999îîîüôÓOwïÞMku¿÷Þ{:.33sܸq‰‰‰Þ»dɇèèèóçÏýõ×r¹¼­&ñ‘îÅb±@¯ü>öZêtºôôôššxÕº äæž={~@Á†Á`´oß>,, š"i….Zé�µèÆRÒD=€íáUš1…¢d˜I+**ª®®¦¡…cå }vY5‡º€@uÁR̼!Î!ⵌŒÔzh¢vsÁ-kMšÑ ¥ƒS³œ>Å€÷µ°[<7Ëá…³¥dzćN¬­Zµ*..ÎÇÇ'99ùôéÓ?ýôÓÆu:Ý‹/¾¸lÙ2‰Dâí혘8~üøï¿ÿþ×_Ý·oßÑ£G/\¸0iÒ¤m۶ݾ}{ÅŠOÉpÅŠK—.7o^Ïž==ºùÿÙ»î¸*ËöŸÅ9l*Š[++œùjÎ,12ÃR“@MÍìu+•áHâ5WjYZæÈ˜#g¢â@q¢¨ Î^¿?®øþ®ÐÔXÙ¹þðƒÏyÆ=®ûÚã‹/ºtéR²Ÿhß¾}ûöí?ýôÓ3gÎtèÐA’�ÿ0››ûÕW_Mœ8ñé§Ÿž3gιsçF””Ä»|öÙg/¿ürçÎËk%===ß{ï½ÐÐÐððð§žzjÅŠS§N•”NøûЯ_¿~ýú]»vmóæÍ¡¡¡¨«öõ×_çççSѹ®]»êtºeË–uíÚõab²¿üòKF!„xýõ×·lÙò¤Ê•èïÉÛÞ zÿÊ›•¡Ê/”É[[­Ö+W®$%%ç¡kpÉ­‡…®óRf¨óFÌ‘odFsuuíׯßÞ½{¯]»†(�Ä@y‡™MlÉÝÝ % ˆÞLæ8ÁÂÏÀ•ÿ²Æ'Í’–hi“l̓YÈ#é²(;„Õ.ô\4ˆù!ùå"¼›ïeþøZ†Q¯^½;wFDD´lÙrß¾}&“i„ ‹-ŠˆˆP(±±±§OŸNII ¡†•BˆmÛ¶ùûûGDDÔ¬Ysë֭纸¸L:õÙgŸ]µjÕ²eËJœß�zôèÑ­[· .\½z5&&æÌ™3]ºtÙ»wïÃ<;tèжmÛ†……ÑkÕªÕ¿ÿêÕ«ÿòË/teìØ±^^^S¦L)ߍANœ8ñí·ßnß¾}¿~ýJã+&“éí·ßöóó›={¶———bãÆ{÷îåÉÈ™™™‹-úËR@+V¬ˆ‹‹‹‰‰ù7˜2¨Ù%<4T8�Ù6ˆ  4pí zM||<é7ô,ñ$äêsåá”ÄCv<Qȩ̀—À»Ã‹’/„n¦~ñññ·oß&›=N ìx¨ÍIe·èt:¼7Ý‘ÉdÎÎη?:ñ8 kåfXûK8yò$u¤OOOÇE•JU¯^=ü÷àÁƒ;wÎÊÊ¢²•Ìfó7ß|0tèÐk×®•Ò‡š4iÒ¨Q£{÷îeee5kÖ,%%å×_}H—””äééIåS…^^^Íš5óððHJJ¢+ÉÉÉ*•ªÌÏ è,Z´¨^½z¹¹¹[·n-àò””jv·|ùrª¢/„HOOÏÎΦvAéééÁÁÁ¹¹¹±±±5jÔøËÞ¾};??¿Ü[ • دÈAB"?¼T½p¸Súp!j PŽŒfô"ñ¤µX,—ÆSƒ .+•Jêæi±X<<<à@R*•^^^ÄTH·X,qqqZ­V @\ -3PŒ�õö‰GÒiüà»f³Y¯×s?</Ýö—üæ±ÏØ‹ƒÜ&ʼCO‰Ló/Gøø,'??ܸqýúõÛ·o/ ¯Óé~ýõWn_Ú·oßĉ{õêUqNàêÕ«cbb.\¸oß¾W^y%<<œü:%/^\½z5ïôÓO?íÚµëÁè²qãÆ={ö!h Ñç»ï¾“øäOœ8qçÎê¿ðÄÃüùóoݺµdÉ\¹{÷n\\\ÇŽ©[Áúõë÷ïßÿ¿ÿýÙÕ«WÇÇÇ}¹ñ^yå•b»@=y�ŠL$±tùöëQjXá  ë¢zk¨0M,þ©ºuë._¾üµ×^Ãw‰ÃÑËU*UÆ ÉiDƒ¤R¿·qã"Ó¬C?vȯ�� �IDATÓxÇ…k4Ò$-q'µåæÆº[}$g2” ~2@±6(¼–V¬X(íZ×Ęï×_çÁüƒ¼ß=$íââòþûïÇÆÆfff0`ÅŠÍ›7oÚ´é‚ ¨ü¾b̘1ÑÑÑ#GŽŒŒŒ¬8‡ðóÏ?oÖ¬µ¨=zô³Ï>»gÏž¯³~ýú}ûö™ÍæŽ;¶jÕêĉ'N <uêÔ˜1c6lØ£GÕ«WïÚµ«I“&Ä<fÍšõÔSOuíÚuÅŠBˆÒ«rssçÍ›×¹sç‹/ÒJþüóÏÉÉÉ£Gþ—Èé‹eäÈ‘ô÷ĉ¯\¹²eË–åË—W©R÷Ìš5‹êT¯^}Ô¨QãÇ4hÐ|0räÈÓ§O2ÄÝÝý÷ßß³gÏ?þD}²%8Kø‡×¤„Œ÷^ã’¢‚6ü.¼4’1…iii ,8sæŒ(täðÎÖv»=..ÑÒv»öX½Î £ýÿ±ÉuD3åíÅàs‹¥(„ÚѼ Tá¾,§iÓ¦¨U«V@@�mç´iÓF%„ íܹs:u&NœH(Ò°a×^z©J•*}úô1 7nÜX¾|9|*©2`À€ UdÓ¦MhY­ZµÀ~U‚&µåË—“–S¹rå5jÔ©S‡üê hܸ±Z­^°`õÀvww¯[·®bÆ Ôêcîܹ<›½èJ2¤W¯^§_ÎüùóK¯§xddä!Cð_//¯€€€ Ëá$nð÷÷wuu=pà@µjÕªU«¶iÓ&2øÔ­[W£Ñ´oßþÀ´à€_~ù…ØÕ“Ô �•ùy¥2Î<ˆÁ899yyyQ7[¸`|ãË(„ƒ>’ô¢  …V«Ý¹s'…PïQn¿B04º©¡¯ðñ“.Âë \@03ŠŸ¦ò‚Õ£ØndÁZmx”Ëquu%©}«p¼«T©B¢¥““4ƒçž{níÚµS§N]¶lÙ•+WjÔ¨ááá¡R©Ê²|äÃ*.½AÖªU«V­Z\‘—|+Yt`MÑAV¯^½Äc‘ÿH(x©®$Iî|AŠ®¤`¥K%AäžžžEw¼ÂVHûûP©R¥š5k^½z&)QXgE—‘C.üJ|H¯×SÉAN£¹µü4(ņLò¦·ðõõ½zõ*¢¼O^% £§ÐyuwhäÈ …ÉF¢°‹6´"êÑ@ovuu%  ¤Ð ‹Õp³Z­:N£ÑËu¸Ö½ ŠcÑTPXÛ(ÈB°ˆ5Þ§ØüPXØ }õ0AƒµP­VKŒö(4‡Í’ÉdR‘PÔhÆsNq?ÆPÔ$ÈïÿËÖ%Y} ÿþ‹e÷îÝBˆ… RK8Àå O?ý4±ø07„¡œðÐÈQBÑ¢ÐÝêi·ÛÝÜÜ”JeNNŽÑhD/òÇ×'%%…— žˆX# ʼ8h®ã´LD–ï$ÿ‡(,Mw~ƒŠƒÚ64M†àPtÊGËy< ,‡'Ž;æè—S"`0Ž9ò¤®dŧPJ¥ò×_…N€j7H¦A /Ã…wFƒ2${"Ö™ÏÎÎF‰3ؾè~â:<7l"6x Bàâ#qÛ@Ö¦èz91^›§ -ÿ‚ÃñŒQcøÇ°œ'l6[óæÍŸàš²­Zµ*³Ù©TªÇÈ„ýÁ*ÞWd&Í1`DdI3�›âÂëÐÐãdjC¥�º“rh<ô8ŠèYú¢F£!Þ@!Ôð*/$çÏÝ»waƒ‚*Ã#À¥h dC“´ÌAŸSŠF£Å<¨šx$¿çQ—†,C°V4ԸشӢ ¯hA„b“‡Š•%o£\%|ý~3R(¥×ºÅÁrЇ<ñ´žžžmÚ´)ƒýüóÏO¼äX»vír,;ô0вOÈ¢E¼ :ÄPø’n&šŽäö& Ý0‚ÁI£T*U*ùWèNz­Éd"«¬XÐxˆÖ«Õê?üpÆŒ(HCzˆæ"䌼»»;¥þÐ áÚÑëõ#¦¹PM¶;Xçx0’–UÍ-Ú«MRÕæ~ÚpыŞ”‡hòUÃPK5ÖÁrЇÎ;W«Ví ¶ê^¿~½AƒeÓ/§"ö/HII©]»v…í—# K5ó gÒoë6M„ž'~R©f´ãä Ê3£M�îAQ5´\CÞ(ÌkÜÒEn$R‰fΜ‰Ò;4*µZMEkx·JPE6üËãˆc!ÏEØhA(-”fîÚ(ºã €ÃZ9À“Ý/'..®AƒeiØyRWÒn·Ÿ<yñœ“ßðtô@ÀžÁ«f¡TLdˆ`F‰Ls îAyMQW†**•ª  �)2dpS*•:н$77ƒñð¾ÐØÐ¦Œ~kxÖÛÛ;??Ÿ‰$VΙ\ð†Z°¦ËÅC+¶_5~Ç…E¶‡Q/¬¾­ªÉKû<À?]l9NÜÏK IW?x`Ër`„Å÷ÐÈáñ�e-¨Níc¼A’Rƒ,©3o6›‹F1bär9Lª%ERaÚ÷Ê`¨$<>¤%—ÈånHV¸èêQŸ  Ët3¥C=‘@®u2Áoo4œœ I…aPô fè@ñ¨Œ‰gÉ`5‚.’:‚ΛT‡ô ™LÖºuë'N Î¥ôƒóŠg`~h‡¸�I,5îÇm@UAAÀ™h²T`›‡ð¥ò0'rÎ}?–Ã9Óý^Å‹jóÀ‡Çc9¢H®•„Ï=†=×å£-ÚHû°ñRpõêÕÛ·o¼jÕª’=C† y饗ß~ûí»wï>êÌfsp!ôìÙ³zõê3f̨h§Ýf³;vlòäÉÕ«WONNæ?åææN˜0¡C‡=zôèÞ½ûÍ›7/]ºÔ¼yóàààÖ­[/^¼X«Õ.^¼¸uëÖÁÁÁÍ›7¿téRiöòåË­ZµêÚµ+5§øKx÷ÝwÊw…>ܤI“ààà¦M›nß¾£ÇÒ¥K[µj””tóæÍ×^{íµ×^ëØ±ãØ±csss·oßÞ´iÓààà&Mš>|ø f9ÄT(’ò=œœHÛ€šB=@÷‰©  dv^g…pxWPúÝHi�Ä'âããÑt‡ô Š7ƒÂ+œ( ?#O."boÄ2Iß"…ŒG9ʈ^Ú¼™o'JúQ[¬‰Êǰ6vìØ!Ä™3g¾üòË·Þzë‡~hÖ¬Y^^Þ•+W„Í›7á…~üñÇV­Zѧ{„AAAµk×¾víÚÎ;…¼ÆpjjjµjÕ¦L™b6›_xá…Í›7:ô‘†®R©vìØA¯Y³æÖ­[m۶ݳgQöfÍšµiÓÆ`0€Yöïß?+++---##ãúõëuêÔ©\¹ò‰'ÜÝÝÑ®­4XÎÖ­[ŠþtæÌ™•+W®ZµªcÇŽõêÕ[½zõ¥K—ÌfóŽ;>ùä“™3gvêÔiæÌ™'N?~|£FfÏž½víÚRņÏ>û¬]»vz½þ«¯¾úè£Ö¯_ïæææççwìØ±~ýúyxxœ:uê÷ß§-æAhqqq'NœBÔ«W¯[·ne‰Á#FŒxþùç·lÙñßÿþEçrrr¦M›6~üø‰'>õÔS3gÎ|öÙgãââ.]ºôûï¿÷ïßÿõ×_ÿïÿÛ±cÇU«VõìÙsĈ4…'HcP«Õð»€#`šÔIÜ0î¤êŸÐ ¸ÏAeÄBÈ™hib!¤M:99Ñ{, )ñe@º8ŸÄUå‚6Êêp•‹ê–"¢ Àêèfâ=¢0¼äeCiy¹ÙêñäÊDQ5«h×®q‹ï+!þÜåó…à`âºÆó¨SûËŠsk†:tèД)SöíÛÛ¤I­V;tèÐôôôQ£F-]ºtÞ¼y¯¼òJ@@@ttô©S§^~ùå­[·îرcÉ’%~øa•*Uºwï>uêT­V‹Æ‹Ï?ÿüóÏ?¿`Á‚'N¼ð ¨_ù°råÊyóæ-[¶Ìb±Œ3æ½÷ÞËÊÊ5jÔ_|ñÝwß9rdĈ111çÎ ž1cF¿~ý”J娱cÃÂÂêÖ­;mÚ´‚‚‚GexËҕʹsçÆÄÄT|!zï޽ǎÛ°aý{÷ƌӳgÏ äçç¿ûî»{÷î=}úôˆ#FŽÙ®]»)S¦lذaüøñà#GŽ|饗jÔ¨1fÌ›ÍÖ½{w‡4WqÀfl×΢PØÈBZ‹Lf·Ù„L¦Ëmv»(Ô`¸3†È¹PQ {ŠL™\.àY¡÷>bµZÍ*ñ “Lö‡$— »ÝD¹¥r¹¬0hM&—[ IèßÔÿOÖ!šøgóÎØí ¹Üj³ ôm“Éþ¡Ý.csán*b¼4!“ ÖoÍàç'%kí1zWK YœÄ“íQrgQº_”å ,~`9îM’`eÀ´x5‡tlÿ]–3oÞ¼˜˜˜çŸ¾aÆBˆøøøßÿ,þµjÕ:räÈ¢E‹RSSFãåË—çλyóæC‡}õÕWW®\ùä“O²³³><a„   ÈÈÈ£GJzý†„„<ûì³ï½÷ÞÉ“'é ß}÷ÝÌ™3W¬Xѹsç¥K—¦¤¤tïÞ=555**êæÍ›±±±õë×ïӧ϶mÛöìÙœ˜˜X·nÝfÍšM˜0A&“õéÓgÊ”)‡.%–ó‚K—.ݸqC¯× †¤¤¤””!„¿¿ÿàÁƒ“““cccCBBÎ;7~üøêÕ«oذÞ¾};11122²I“&'N¼pႃåT,SÆ®]²J¥¼œóFœ òÇ úòG>¿B!‰¥ˆêõzÄ ƒ?Ym6µZm1›ÿ¨Šf³Ù ãÜ„L¦B^˜yJê…ÉdR«Õv!ˆo™ÌfºÁbµÊe2‹ÕJü ~«ÕªP*eBP¤™B¡PªT&£Q—™LíäDÆU+µCe\‡Ø¤­°QYÕÀ„är¹Ó+¯ˆvíhS>†µ‰'’améÒ¥Bˆ;wÖ¯_?55u̘1D›’+:tèé§Ÿ.ÚžÄÏÏO§Óååååää<Æèóòòâãã}}}ÿ=OJ òòò®]»Ö¨Q£É“' !êÖ­›””¤×멞<‡b£³>þøãJ•*µk×ÎÏÏϱž ÷îy¤¦"’wù´ÙlòB—;õÏùÿ®6›L'µšäV³Å¢P(J%%^’ mrè J¥’8˜B&S’ûÄfS’H²¬V«Ýb*•]ç ÐÐ åk…Õ*—Ëe6[Íš5³³³óòòþÙ y‰/™Ì¦P¨d²?Ne2r ýQLÚjU-®Ð¼†Ú92!ä …°Ùä …‹“¶ÛíŠâÜ“ˆà¿ò Ö¢÷}›$¡ç~Ê$™”ßÏþEà ð1@ìÀø0‘b_ÂóJưÆá‡~8tèÐéÓ§¯\¹òæ›oþåýaaa£G^¾|9'FÉÉÉ»wïþ;V«õ£>:~üøÿþ÷?IÍÇ »wï¾qãF…b“.\X¶lYLL $ j6Zl õÆ‹^œ1cÆþ󟯿þº~ýúå;—“'O;vìÕW_u0‚víÚQÿ^L–ã$£ *r V»“—·9ã´Îy4°áT_”ÑAßÞA¢sprÆC·áÅ úØxïQ$=E«lÌúùçŸ/º†UªTA' ðO<ÀóQ46šó’Ø£øB q~@èbQób¬–Æ }X|^…’ð¡b#Ëï·ÃrþùçÈÈHÿàààèè謬¬bïôöö6lئM›=ºråJü¤Ñh~ûí·ØØXµZݦM›®]»>ê0,ËW_}Õ Aƒ/¾ø‚®Ô­[·uëÖ“'OÖëõ-[¶œ2eÊ”)S _î ›6lˆ‹‹{ë­·bbb6mÚôÌ3ÏôêÕ+//ïäÉ“ƒ ºpáÂðáÃýýý‡¾eË–K—.)•ÊaƕﰟyæÚî=zðë=zôX´hÑêÕ«ïÞ½ûwÜrS¦L™0a AƒNœ8A[|àÀÙ³gŽ1bÛ¶mç2|øp//¯;vŒ=:33388ø™gž™2eJTTÔ Aƒ.^¼8þü'•å4jÔè_ÒŒ®¤àöíÛ’PL77·öíÛ;VæááôéÓÔ>Qª´µlÙòðáÃ:nÛ¶mœ” †ÔÔÔªU«R‘œœœÌÌÌÚµk“7)--­  ÀÅÅE£Ñ¿qqq©^½úÝ»wF£¿¿VVVvvv:u @«T*‰A&33“ìiîîèC‚Ýn¿zõ*¿âååe±X èo«ÕzýúuúÕßßßd2ݹsÇ××W­V߸qÃÛÛ»R¥Jׯ_×h4¼_ÎÉ“'5jäááQR© ¹¹¹µjÕ¢|—´´4NW·n]ZU¬žâÆ$ÈøúúºººjµZZ=¥Réïï_‚ñóÏ?÷íÛÕŠÝn!„³³s5ÒÒÒôz½ŸŸßíÛ·õz½‡‡ÇÓO?=~üøˆˆ¾ÝBWWWIç¡]»v½þú륗 j³ÙÐ׋ð3;;;++ ÛÍWïÎ;TcжÞl6“ËŠä•Ç+òa·ÛwíÚ\«dee¥¤¤´jÕJÒÓ îîîDI„;wî|뭷ʦTÇ“TàÎd2¹»»çççïÚµkäÈ‘÷Õr4 ·xyyyyyá¿ÔùŠþFC"”Ðo¨G½««ëý,->>>>>>=™LVì›10Rîø=J¥ÿÅ’Î4¥žžžžžžEG(YUâ‹ü¿X½’…¿Ün!D||ü€úöíûÔSOy{{ûûûÝî²¹\.Y¢J•*Nòí&tR©Tån,U }!džƒ>€ß]§  À±† ņÉÉë „fÍš-Z´H«Õž8qbÖ¬Y¡¡¡Ž5q€ðH਱v_8tèЂٟ$!îá¡C‡:txÔ§ôzýo¿ýæÀ(8À–S P”΋/¾ød÷,›ÙQWàN:=Ùã85p€ƒå<&P°ÊßöñG….]º<Áe¤ ¬VkEî\à�TD–#“Éžàbºp€à€ Ärìvûž={+â�8À(ApssCžÓŸ kÍš5+—@@9/ß0DÞ3±BA…˜Pœñ_‹BX›ÍV1£Q¨=R\º ¾§ù„JJE”û`ÜÝÝQþàO,ÇÃÃÃÕÕõ/K–,X,–ììlWWW777Q~”¼¼<ªlèææVÆ+ð`ÈÏÏ·Z­jµÚÝÝýýÊ233œœœËxFcAAF£ñðð¨P{G­T*ÓÒÒŽ9Rl>vùBåÊ•›5kæââ"©¸\î––æææV&­VKÅI=<<* ÍÉÉ¡–eOÌ‹5uuuuE"­4|Àl6—±#477÷ìÙ³TL¢lÚÅ™3g|}}ýüü¬V«öQJ——ÁÀªT©R»vm‹ÅR¡&C‡½øâ‹Tø!ë½–ܹsçöíÛ-Z´°Ûíp‰Ž=Ú¬Y3!D:uZ´hQÑTWWW:w:îQ[Å”X­Öß~û åéõú (I�Õjuƒ *鈋‹kÒ¤I•*UÊž˜…'NÔ¯_Ÿç•;RAà�8Àe–ã�8À(#xü¼œƒBkkӦͱcÇêÕ«Wl­û²ìì츸¸çž{îòå˦eË–gΜÉÊÊêܹsÙ `÷îÝ~~~O?ýt¹oêñãÇsrrjԨѴiÓŠ‰vùùùz½¾J•*ðp¦§§“3Æq&c»-KÛ¶m+Â`Nœ8a0^|ñÅŠ¼bÿˆA– \»v-99¹}ûöÎÎÎÅÞpïÞ½øøøæÍ›í›U¦ZΖ-[|ªîÝ»Rl•2ƒÄÄÄÇŸ?>99Y±páÂûµ¸( 8uêÔÍ›7ˇ~ýõ×?~üÆÑSRRŽ?Î}Â999ŽlÊǃiÓ¦7®‚ föìÙ#Gެà+–œœ|þüyæ!¶nÝ’žžþ�ö_žZζmÛ"##333ívûSO=õý÷ß¿ñÆøuذaTÇ~„ Åõ×û›pùòå©S§ !T*Õš5k„K—.‹‹{ï½÷膋/V®\yÛ¶mÇŽ+((˜7oÞĉKv ˆ‰‰™={vƒ öíÛ·lÙ²9sæŸ_Iä~èСmÛ¶ ëÞ½{XXØØ±c=<<¦M›¶dÉ’Ó§O¯X±¢ÄçàÁƒcÆŒ¹uëVNNŽ››[ß¾}gÏž=}úôŽ;* Ê»êÚµëÀ'OžA+9gÎj:lذöíÛ_¸paÖ¬YB—Ò$@¯×'&&úûûW­Z5//ÏÉÉéúõë÷îÝ{úé§ëÔ©CëY²™™9|øpú»jÕª‹-úöÛo·mÛ&„hÛ¶í‡~(„§Š 3fÌpqqÙ¾}»Z­Þ½{·¿¿·nÝ–-[&„X¿~})-ËüùóOŸ>-„ yã7ÒÓÓGŒA?­X±ÂÅÅeݺuÛ·oB¼øâ‹|ð\µjÕîÝ»…;w–t|/A[ú6ÅÄÄxzz~ÿý÷›7o&SÆ)„ rÆŒ:.((§d6|øðZµj5lØpãÆÀgÉ ézhhèÕ«W322Ê~BˆÓ§OÏŸ?ìØ±õêÕ6lXïÞ½{õê5dÈÆ=zÞ¼ygÏžB„††öèÑãîÝ»£F¢W¯^]zM úöíûÆo„„„äææ:”®GGGãdÍš57oÞüÕW_Q€qi9]ºt puu:tèÕ«Wwî܉¥aÆíÛ·/**ª^½z½zõ¢ž+%V«µ[·n>>>QQQIIIýúõ[³fÍœ9sÞ}÷]ÈV<~ü8d‰ïPVVÖo¿ývåʳٜpôèQ½^¿sçÎóçÏO:õë¯¿ŽŠŠjժջロ””wâÄ ½^OÓjµ¿ÿþ;Ñ”‡–-[vìØQ1zôèÔÔÔ;wvëÖ->>þÿû_ttôûï¿?hРiÓ¦ýðÃ?~|TT”³³ók¯½Õ¼yóþýû'$$¼öÚkÕ«WŠŠŠˆˆ(=–sáÂ…Ê•+Ÿ:u*777---///???---))ÉÛÛûÔ©S¥Ñ¡ÄËË+**jöìÙçÏŸß¹sçøñãCBBFŽ9wîÜU«V………%$$DEEU­ZõÕW_ÍÌÌœ5k–ÑhŒŠŠúú믷oßuëÖ­·Þz«4ÖdÉ’%QQQï¿ÿþ›o¾9wîÜ'N !¢¢¢ ÅàÁƒ÷îÝ»páÂððð?üpΜ9$u !~úé§)S¦DDD 2dÆŒßÿ}i ¯G&“)**J£Ñ 4(66v̘1o½õÖ˜1c>þøãåË—ÓmÛ·oŒŒ Å ;¶jÕª¡C‡ž9s¦4º85yòä3gÎÒ u:Ý믿ŽA¾ÿþû;wî¼zõêñãÇ<Xì ×®]»oß>Ÿnݺ•F˜\^^ÞáÇ“’’t:ÝÎ;/_¾œ••µÿþëׯ/\¸páÂ…3fÌxã7fÏž}êÔ©W_}Õd2}ôÑGBˆR’!FM›ûúë¯ëtº¨¨(“ÉÄ;¨íÛ·oñâÅ999ùùù={ö,SÚ«««F£‘Éd¼SÌ#F£1>>þîÝ»ÙÙÙ¥s™••EæE½^Ÿ™™©Óéôz}Íš5.\øƒüûúöÛoŸ?~Ú´iÓ§Oæ™g€R&“)>>þæÍ›¹¹¹r¹ü›o¾Y»víÖ­[!­lß¾}Æ ¥:ÎÎÎ...B4"jܸqBBÂÉ“'׬Y£Õj/^¼¨Óé¨MY~~¾¯¯¯³³sVV–¯¯¯»»{nn®ÅbÉÊÊJOO§¾_¿×æÍ›SGz žÐu³Ù\Ù …Â××wýúõ2™lóæÍƒA«Õz{{W®\Ù`0ètº¬¬,ºÇÅÅ…¦¯×ë•J¥¯¯¯Ùl6›Í¾¾¾J¥²ÄÅ)‚êÕ«wéÒåý÷ßwuu]¿~}Ë–-333©…àºuëÖ­[×¥K—uëÖÙl¶ÄÄD½^O[IƒÔétIII/^ä×K\GT«Õ¾¾¾«V­Ú¸q£ÑhÔjµ•*UªR¥ ­$ÝÆWƒqvv9rdbbb±žÿ>xxxÌž=;11Q¡PäääÄÇÇçååeeea¤žŠd½zõf̘A‡¢4Ù¡C‡áÇðÁ÷îÝ£+C‡urrZ¼xq~~¾ÉdªZµjHHÈñãÇ›7oÞ¼y󬬬¨¨¨°°0ÞR¹ÄaÙ²e•*UÒjµF£1+++///>>}íÛ·2dˆZ­þ;È_òe=IðoҤɤI“\]]K ïœ ôö�� �IDATú÷ï_³fͼ¼¼r±vëÖí—_~YµjU@@�e]pHHH¨Q£Æ¤I“ªV­Z¾ÍgÍš%—ËOŸ>=jÔ¨¢ã¼ddd$$$ 0@ÒÈõÉ€¤¤¤#GŽDFF>¶q ôà­·Þzë­·æÍ›Ú¾}ûE‹InHLL9rdãÆI¶À•+WjÖ¬9iÒ¤‡ßë2ƒZµj 2¤ôÞ�Õ3???!!áÕW_¥.·ÿPX¾|ù… FúÑGq#j©­^```ið’’vss7nœ¿¿\\\)UøhÖ¬Ù¸qãÒÒÒ.\¸@WŒFãŒ3нùÌ™3¥avïÚµk5Ö¬YóÜsÏI\V2™lܸqÏ=÷\\\œN§kܸqxxø_|1vìØ>}ú¬Y³fĈ’ö”¥ gÏž=}útXXXXXØCèÆwëÖ­¤¤¤ÒU¹¸p322† R·nÝR’µÿ&lذ¡OŸ> ;vìÁƒÑc›¤‡#F\¸p!..îí·ß.64æwÞéÝ»w\\„èR‚yóæÁ©S¡AƒãƳX,ä!ˆŒŒ¬ REË–-çÏŸ¿aÛÍ?oÞ<~ÃÑ£Gûô链{÷îÅ‹?ýôÓ° –Ô«Woܸqv»ýÌ™3üúñãÇúé§¿ùòÇÔr¼½½kÔ¨!„pww÷óóS©T~~~111o¼ñFçÎu:ÝÔ©SK\ÄP([¶l3fLçεZíîÝ»Õjõ¥K—F=a„Q£F9;;W«VÜ΋-êÝ»÷ªU«æÌ™S³qãÆ’¥Uáçççåå5jÔ¨”””Î; †aÆըQC©T¶hÑbÏž=-Z´ÈÊÊÒét­[·.VD-ðòòòóó“Éd...~~~NNNBˆ>}ú\¼xñÃ?lܸñ‚ ¾üòKƒÁP«V-!D¥J•jÖ¬I²‚ŸŸŸ»»ûÆ'Mštøða“ÉôË/¿”Æ ©‰NÍš5Ï;×´iS///ggg•J%“É(XS©T:;;—F‘(³Ùœ™™yòäÉ·Þz«zõê«V­;vì¤I“äryXXØ€úõëH¶iÓ&WWW???÷h‹ÅŸ›—,íÞ½;$$Äl6OŸ>ýÅ_ܺukxxxçÎsss·lÙRµjÕQ£FM˜0¡N:K—.]¼x±Ñh¬S§N¯^½H"B´mÛ–Êy”8lÙ²¥oß¾;wÎËËÛ°aƒŸŸß„ ¦M›¦P(úõë÷Þ{ï;wÎb±¼öÚk4H¹\ñî»ï9rä~a¸%¾¾¾ˆâ½ß çλsçN!D•*U<H:D¥GЛ4irþüù—_~ùÒ¥K†ÜG}õêÕàà`“ÉÔ·o߯5jàÀ›7oÖëõ?ÿüsi †¸B¡Ðh4~~~ÎÎΛ7oîÓ§­Þúõëoß¾íççGMnݺuíÚ5 y<µlÙòðáÃ:nÛ¶mo¼ñ†““Sy¼qss+Ç‚7§N¢‚7ÎÎΪhJ||<¼©h“Àž={^|ñEwww…BQ^oÜÝÝË׌Y,8p Y³fZ­–Y¡Æ†‚7...ƒ¡B¼Ùµk׫¯¾êââb4ÿŽ'ÿîÝ»'Nœxá…t:]@@ÀŒ3xdÝß¼Aé ò…#GŽPÁ›’%æ5zá…Ö®]ûHO;v¬~ýúõêÕËÏÏßµk×È‘#-Úà�<ÉŸŸ³yóæJ•*=õÔS$gö_ –ã�8àI†† .Z´ˆRåÞ}÷Ý [’£‚Ê+xuNËq€à€â¡~ýúõë×w¬Ãß’ò*‹*¡·nÝ*Ë™ð‚”””ò²&çææúúú !´Zíõë×+ÎNçææR4„N§«P“�¬ÆÙÙÙiiieù霜úÃjµVÀ%‚N.—«Tª 56 ‘ššJ5*p:ššZÆÞÁG‚¬¬, @5 ýàÎ,{bþ€ÁÏr¨ÝHÙ;`ëÔ©#„0™LùùùåÅr*W®ìááa·Ûu:]…rAûøøxzzVÀÝD¥RI-CÊxœ”¹)„0p‰jÕª¥V«år¹R©¬€­]M&“Âl6T(ÊÞ¤IX~~~Ef9žžž>>>v»]¯×Wô«Q£†‹‹Kys øúúJ’{þ±ÆË8Àp€ð÷BI‹‰XËÈÈØ¿é+Ak@@@�e•o‡Z«ÕJ†A77·Šß¡½X×ÙÙY©ü÷ºôÌf3IÐåŽK¥1)OOÏŠ÷\ªPPP`·Û’““Ÿ0|–ËåÿùÏ*W®ìææöCQƒÁ ) 5¬ùùùµiÓ¦‚OC­VÛív“Éd³ÙÊ7>++ëâÅ‹mÛ¶•ÉdÙêUìvû/¿ü$“Ét:]Enô[ªpýúõüüügŸ}Ön·ÿ³vðpéÒ%»ÝÞ¸qc›ÍöÄLêÁ@F«ÕÚ²eKÊq~bÀÙÙ™ê Z,–R*Wz@y9¼&€£+¨à�8 ¬”6Ç8Àp€*:˱Z­—/_ÎÌ̼sç/>Xaáúõë·oßvlù“ wïÞýGàá£Âµk×îÞ½[²Ùlt¢q%;;ûòåË‹¥èÍ·oß®È!ûnݺUšü–#ܹs§4¶øñYN^^^«V­¢££7oÞüÅ_TüìÑ£GÅo‘ë€Ç†‰'¾ôÒKOÞ¼^zé¥ok[,´jÕjÉ’%¸rôèÑùóçÛdäÈ‘Ov€ëÚµkW¯^ýo>PcÆŒéÞ½{‰¿¶B;<==+W®œ””´fÍšþýûoÙ²¥fÍšï¼óŽbÞ¼yäÞoذaBBõðññ=zôŽ;:4lذèèè   2«}´nÝ:êzеkW*ÐûÉ'Ÿ¼üòËׯ_ÏÈÈ;vliàûï¿¿téRhhèÊ•+ûöíÛ´iÓäädÂo77·‰'îÛ·oÏž=‘‘‘©©©k×® óõõ¥AvêÔiΜ9äE0`€——×çŸÞ½{÷‹/” OýôÓO)û²ÿþMš4¹xñ"û6lتT©²ÿþÉ“'_½zuýúõ$=;}úôÄÄÄ7<xåÊ•Ï=÷œ““Ó±cÇ„-[¶ ÆW~úé§S§N <8&&æÍ7ß<tèe˜öîÝ; àÚµkÔƒR£ÑL:õ·ß~;wîœ^¯_½zuxxx,Bjj*µé•Ëå³gÏBüøã§Nò÷÷oÚ´©‹‹ËþýûÝÜÜ DÛMƒÜµk—¢aÆáááß~ûí7zõê…ƒCÄ=,,¬qãÆ‰‰‰ß|óMÙÌEëׯ¿zõêäÉ“]\\ªV­ªP(èt !<<<&L˜ð믿^ºt)''çÛo¿ ]½zurr²¢[·n:tÈÌÌä8Ù©S§lwtttÏž=i%‰!Þ|óÍæÍ›—ÁLwìØÑ¤I“5kÖ˜L¦   „„„7n4oÞüÍ7߬T©’Åb9qâÄO?ýDkݺ5ï†ùã?¶iӆܻwïýû÷ß»wïÅ_ìÞ½»Á` ”BŒ;6##cõêÕýúõ«]»ö¼yóºtéR²ÑÍ›7cbbèoÿÁƒoܸ‘š;ÈJ•*íß¿?66VѸqcÞåä×_Ý»w¯â™gž -7-‡oÛªU«RRR¢££#""j×®=}úôõë×OŸ>}ݺuAAA™™™áááÉÉɃ ÒëõAAAÑÑÑŸ|òÉáÇ£££CCC£££y[‹Ò>NÓ§O§ Ã#FÄÅÅ 8ðôéÓGŽ™9sæºuëÊ` ±±±‹-úüóÏõzý Aƒ’““ÃÃÃ333ƒ‚‚Ö­[7}úô¸¸¸èèh­V{íÚµèèè”””üüüèèèS§NM:õ»ï¾ JOO÷Ýwoß¾ýá‡Ξ=»4Ú…9sæ,_¾<(((///"""999"""///...44tÇŽÇŽ‹ŽŽ6—/_ŽŽŽNMM ?þ|PPÐÁƒ?øàƒ¤¤¤èèèwÞyç‹/¾˜4iÒøñã4hðÔSOMœ8‘÷JØ¿ÿÒ¥Kûõë=dÈÏ?ÿ<((Èb± <8999,,ìÎ;AAA?üðäI“êׯ_½zu•JÕºuë²A¤ÐÐÐëׯíØ±côèÑ?ÿüó¤I“5jôÑG ><))iýúõTã=66vùòågΜùïÿëééÙ¡C‡™3g~ýõ×;vìˆŠŠŠˆˆ ƒ³zõê   ììlZÕhµZjY–üæ‡~Ðétß}÷ÝÔ©SO:}ëÖ­ˆˆˆììì   Õ«WÏš5«Q£FU«VuvvnÑ¢Å×_=sæÌ:xzzþ÷¿ÿ=sæ m÷Þ½{ '¼Ý7nœ>}zPPЕ+Wú÷ïd·Û‡ R6V»Ã‡‡……uêÔÉÅÅeøðá^^^M›64iÒÏ?ÿüã?nذ!11‘hT£F&L˜@ÁÞ½{ß}÷]àdýúõýýýÇŽ{àÀaÆ>|8((èìÙ³7oÞŒŽŽ¾zõª^¯ŽŽ>~üxLÍËË+(((((è—_~Ù´iÓ–-[&OžüÜsÏÝo§N1bD¥J•Úµk7cÆ PÂßÿ}äȑժUkݺõÔ©Sÿ~ƒóˆŒŒìÔ©SVVÖÍ›7/\¸`µZ}||œ½½½·nÝ:pà@£ÑxéÒ%z¤jÕª·oß4hPÙœ¨›7ofeeµlÙ²I“&7oÞÌÉÉ9{ö¬··÷¸qãʲg—‹‹ËçŸîï”¤ÕjkÖ¬Ù¶m[¹\N]O^yå®ÕvïÞ½{÷î~øabb¢Íf£U=þ<7kµÚï¿ÿþÀe0òüü|Ï>ûlÈ![·nuss»xñb­Zµ¶mÛv?WÙºuëfÏžíãã£T*![äåå]½zuâĉwïÞõôôôôôLKK+Z)§~ýúTóß`0´mÛ¶nݺÉÉÉZ­–ú®¶mÛV¥R?¾fÍš•+WV*•O?ýtÙì Ñh<sæÌ±cÇV®\9oÞ¼»w獵§·jÕjíڵź”ž}öÙíÛ·¿öÚkÞÞÞ999)))B›ÍÖªU«Û·o×®]Ûb±øøø¸¸¸\¸pA«Õ&%%Õ®]û³Ï>+ã¾–={ö W(‰‰‰tÅf³Ùl¶}ûö%%%ýðÃ&L¨U«–———Z­nܸqJJJNNNëÖ­5jtãÆ êER¹rå‰'¢;;¶ûôéÓ;vìhÓ¦ ßî+W®´mÛ¶ZµjgÏžmÛ¶m½zõ._¾\fÑÀ ­ZµjРÁµk×üýýŸþùôôt‰ólþüùÏ?ÿ|QüLHH�N6nÜø™gž¹}ûvFFÆ_|±xñbµZ}öìÙŽ;~òÉ'#GŽlÞ¼yXXXØQ„îîîm۶ݸq£Z­Þ²e‹Á`ðööž6mZûöíùå—_|ñìÙ³žžžmÛ¶ýñÇׯ_ÿüóÏoß¾ýÕW_õööÎÎΆ+++ëÖ­[îîî•*UÊÊÊJMM-Ã'''ž™ŸŸ%„ ±Z­Ÿ}öÙñãÇ›4iÂK9}ýõ×¥Ú»é!A¥R)Š2ûœL&{@Ê- †ù0 …‚*tåææbUéʈ#Ê,›êã?ÎÏÏçwÚ·o?lØ0È jµú~ɰëׯÿòË/ÿóŸÿ¤¦¦¢í²eË<==©ƒÜúõë}||BBB$µårùªU«„e¹5 ÇŽûí·ßF5gÎ.úQ3«¢pïÞ½©S§¦¥¥ñönÞÞÞÔjZ¡PhµZl+p£ì󲋄J•*;vlûöí&L(((X»víÃTxT©T¼ºm÷µk×F­T*+à†>�î·§0üLž<¹S§N$X+ŠvíÚÕªUëÊ•+o¾ùf™ÕÙKNNNJJZ¹r¥Z­ ™:ujÛ¶m»víº`ÁN´…wïÞ2eJFFUt”ÀæÍ›«W¯òÔSOU,-GÞÞÞ111ÁÁÁ^^^™™™_}õUpppLLLEà1صk¯2�ƒÁ@®ˆûÙRãââ>þøã£G*•ÊþýûÓO•+Wމ‰éÙ³g‰ÔTX·nÝ¢E‹–,YòòË/GGGçææÒõÕ«Wó´Ü¬¬¬o¿ý–þž7o^«V­bbb6lXì;©i# Îÿ˜qëGéAdd$9-|}}çÏŸO­Vë—_~Éo;xð uóMJJúé§ŸÞ{ï=~Ú9xzz’×ÊËË Ì{åÊ•åžýWPPéääôÙgŸÙív>ÁóçÏïÛ·¯Ø§¶oß~õêUÉÅ£Gîß¿„ “'OO.Ì›7¯qãÆ111Ô‘/99yÔ¨QM›61bć~Hþ’20çŒ=ÚÏÏÊ>|822òý÷ß<xðž={âââpç·ß~;kÖ¬ÄÄÄ-[¶ :ô“O>)ú¶áÇüñÇ^^^Ê}Ë”åÌž=Ûd2Ž=ºvíÚµkמ<yòŠ+?þøãýû÷oÚ´©ì±¡_¿~mÚ´ 1cFÿþý[µjµxñâ#GŽœ={¶ôº +ººº®X±bòäÉ 6œ3gÎwß}h2™È§(„¸xñâ!C Å+¯¼"„ ØÀÀÀ1cÆÔ­[·ì+¿ð ëׯ<xð… f̘ѰaÃ3f¬]»V©TÃoÑ¢Edd$Ü*K–,Ù¿```ÿþýïÝ»÷é§Ÿâm/¿ü2E¾ýöÛ7nܨ[·n±3fLÍš5cbbÆ×°aÃO?ýtÓ¦M999ü±bÒ¤I®®®‹-*ÛZÓ¦M###çÍ›—ŸŸ¿páÂ=z¼üòË#FŒèСf}îܹ}ûöQK €Î;wÀ€´ÝGŽÁÛf̘A›>jÔ(??¿ZµjM:uõêÕjµš„Ðò•ñýüüFµpáB*îåË—Ï›7¯E‹½{÷ž;wîÀh»/]º„ÎÐE·{Á‚#GŽ\²d Å<a°xñâÓ§O¶oßÞÕÕ5,,ìøñãݺu KII9qâDŒ!--íСC'Ož 3fLýúõ/_¾Ü·o߃¾ùæ›:u §NÚ¢E‹-Z„‡‡Ïš5kèС³gÏþæ›o(Ê£M›6ýúõ›:uj¯^½7nüw <¼¬g›6m®\¹òð&£Ñ¨T*ív»ÍfS*•f³™Ú×›L&ÒM&"-Ûf³Q½'''ª_ûx¦¼y¤ÞÕ&“I&“©T*³ÙL…§hIIIJ¥²N:}úô¹rå u<$ àÍ#µ@4hPllìµk×hÅøÊÈd2>`»ÝίcUùj?Ò¢àÍc4ú-v[U*U“&M¨U- X‚t¿ÅbáÏ !, }]¡PðêX‹Åf³aÖØµ‡Y±‡Ÿ Þ<jkÂ@>�p||<±Æ2‡ !h"V«Õb±Èd2Z™¢ƒ/vU- U¡~ø±¡àÍ£NЬT*i%år¹Åbqrr²ÛíŘ&9P/^trrò÷÷ïÙ³ç½{÷Ž= <ÇvËårz¹(ìé€í¦U’˜èÿ¨àÍ™3g¼½½¾à F­Vcµq hFXš/?hEL«D3%ßáï´¢àZ­~x•øÉWXrÐàà Õ¾~Òõ¢'ô!íÏ%ÙˆZÂ-Š %š\./G#5#!IK—.={öìàÁƒïܹCºEÙ�_ þ÷_X²ªå¸’÷<ü—(AtªX<–\”,ƒW¬  ¨7®è,$7( К¿<&X–“*ºM4àb]÷ÃϨ¨¨«W¯FDD¤§§wïÞ]²S|»9ååËÌÓƒÁ%MÃý¶¬è€ù*ÝáËì´‹Ÿ}Hü,ÙqtsçÎýî»ït:Ý€à/)U -©{ ¦M›F†ã3Ô©SçÓO?%#þ¿>ùä“7êtºÁƒ—K^‘*28XŽ |½²üb—.]žÈ•¤üß9T«V­ŒÑ©¢§§ç¿|ð,G.—WüøE™LFæQ‹Å’••UŽ#A¼–¢|Gò¨ÀoäææÂìûoø­Vë?k�:Ž‚BËý€” -Ð?‚‚=*¹£?L&Ó?n7‹¶6ÿËÑh4¾¾¾¿E%!D^^•®)_©Va6›Ë}$ äeµX,W®\)ß¶Cå Ô]«Õþãvð@Îüüü'iR€êÕ« !¼½½K$Ô¾b2Ô¬¬¬Ün*•JI\õÿG¬ýüóϽ{÷vè}p€à€’e<ÅD¬Ùl¶rI”q€à�<ÁàááÑ®]»?Ø®Êåò¾}ûþ;WdÛ¶mýû÷—Édd¶Ûír¹œ:¿ªT*£ÑH)0ªÚív«Õj·Û)|Ðn·“{ÉÓÓ3((¨M›6«W¯Ž‹‹ƒY™ôbrŸÐ«èŠL&£ñŠb´X,f³ÙÙÙÙf³ÑS5Oéf³Y£Ñ˜Íf“ÉDI�”A‰ô¸R©T©Tô_³ÙLÓ¡+ô!J €}›ÍF/¡g)!ƒ†DWô ›®+ www“É”““Cyø‰§ÿRN …öÓçГVLÿµZ­HR(ô¬ÙlV«Õ´,ô \.·Z­40…B¡ÑhŒF#ým/¬6ÉY2™ŒÆC¯Òëõ4H¿Åb¡YÐØh$Ø !Š"M)U‚¾ˆéØl6•JEij”z"˜^ECò÷÷wqq¹}û¶Á`ÈÏϧE& Q(t¦@/î)•JZ"ì¯J¥²Z­4`ºBÓ¡©b !¿bÓiI)åB§ÓÑ@KBuz‚¡i¦´Å4Mú½“ÐL¡ÑhT*UAA­9vœ0þ+—Ë ±ñ+åµÐ”  Ã)ÿO|£ï"ˆ€è˜Ð°éýô7ýDXª×ë•J%aM7›ÍNNN4º{A£l$ Ž}Qzšé'Ìg‡Œ~ô7Ìb±Pnzrqh5 …Ùl¦“B_ÇB¢ð‰q´\ÎÎ΃C¥QÅÇÇ7hРl¬ÕjE~˜#bíÿY¡m'Q^›ÍFî/œXY!>Ñù'ZcµZ ~ýõ׳gÏÞºu )r Â„ „+D &OG‹^EwÒÓ¹Â颜,Ð †µˆœÑOÎÎÎr¹Üd2qrFøG§Ž2×ø`€ëôBÞ¡‹¾H§+;;›¾3ÏåÊ+¤å¥ÓB4l¼¯ÅL©â½t„³.2ŒIÊtVA‰„...wïÞ-(( Ò@+CKJ¯¢Å§ù‚þÒYµÛíF£,) O´z\ÈàäÏf³Ý½{W¥RiµZHÈ"$^‚e§D`ÁÂ=héøšF .h(M–ÐC:ÕiãÀK@¶p ˜4ý×ÉÉ (GèG+†Í¢‘ckÀ¨V݆‰;99Éaw ½­ÒÍ é8b´/œ¬›ÍfˆbtQ­V+•J­VKï¡§@š‰/ªT*:ôfš�M[&9˜]1›Ítaб‰ž¾HH…=‚0DC¢O«T*“ÉDæë@iº“„9`(L\%& A–ˆÐ'ý‘2mKÒÈæà7´UÌdµ HÒm”˜ [KdâÞ½{÷îÝãÒ ½Ä‹ž“““^¯Ç‰i ¤'„Àké8`xDHÓá£3Œ—Ó JA_§G8%⼄ð: §ìøÒA&E†<peâ1ô+Æ�.K7@›¡¯ÈåršFHÄ ” T 3M"M„žB¡puu­R¥JFF­$äY¨8 Â8ÞD­8Õ…ùç˜ Ír -t#®á‘¸  ‰íÆK»ÎKdÒ ´é40f®OcO$‡ˆ� VéÇb±€ÍHÄboô6ú›è&ކÕj¥’ `HxJ' %Æ#c�¬¦;Á`€'À7º‡+R`Ø|_¸ÒIH¶É<ž¤:<X”tÐC A¢’Éd...|„àsd´à¥©rƒs>¾×`–\,ƒZC»Ï?Zn~¿¡m#áš2”_Nå9Aá¦NƒèŒÆ€')$t!òGøA50ËôæT†Ó’:¡8Ó ¡§€ÎÎÎx z?Do’¡ «B@æè ®³qJÎ÷xô!X<È&NC”æA(BµZM“"Ç=P¡P 6qŒl2&ç=0DÐ:§§§çååét:ìÉòÜvJãc¦ B¥ó † ã­LL Ð0TÒE'''’=ix`àî 0‚Ûæ’1-ÒVé%0ªpk“VÎ$gItÖh4ŽÑ¼‘h‹ÁA¡©`›¨àÝÀ—‚–Â8ñi²(�ùq¾°wth(W‘ —8ú‘á Œz$ŠpŒFHÎàñ!QX !ØPH4^Ú‡þ€YçÂg´‰˜/Œ+1„®®®$SË9 ™qó ¬)œ¦9XNyN2„Dú¯F£)Š r¹\£ÑP™Ž=˜ô� BpU„•\ Çp<¨”$ŽvX¨²$T|"%L¡P)í �� �IDATR:99IDòˆ€v€šÍf²íU"Gª‡qUnÃQçz ·GAu ¿¹Å6¬ Ò"=B^4ºË +}ˆ†ÊÝl¤âÀJ {N§ËÏϧ€´NE¨À‰iñ¡çÍ€M‚'‘¿.h:ü ÜHH›žŸŸOÔP­VÃìF^C«Õêææf4]\\d2™N§ÃÚªT*www;wîèõzîarvvæ64ˆäÜ/o„ÄJØ ¦u€× �˜‰ÓÁÅs˜FÆpÔÁ`�ôƒ²чLOÜABœƒ½!±ÁéääDû‹·ZBÈ ™âCø‰Ð8ŸÁ`  îE–^bÄ® + „¾ˆ)C :‘“œ˜šá!$’Á` •‡áRQX- Ö0»ÝNu¹ðG7Cž#~B2œF£qÖÊYËŒ í•è8¨?°Ön·»¹¹¹ººÞ¼y“ÒYà„…íFˆîsƒ7/pãpÆBJîŠ üƒ"Ù ‚Ô.‘Ø ch½«5¼š$®ú‚ÃÙ�®Ã6wÛr?3­!ÉnDg%�L‡Þm T`Ö0h`øெý,ã|R0àE!�{ãJ�T4T9_¤e…èMß%ê@’&7]Â. ?¦)„0 DÔ¸ÐS§N:uê>|X«Õbeø\`†â¾ ÜF*¸„n‚ësë"”Z"ñÐA]ô8m=,0—K†ˆKòB€BEÞunRƒÁâfŠ“Â1á0÷¡N%ˆ2í ‹‹ b1¸EËEŸ¤ hN`‹…h7É À+˜¹`G-j' ªD@ˆ§ÐŠèºV«EqOØ`¡ŸÙ V b\†]ÝÁrÊUÝ+ô-ãxƒZ9Hx±Z­yyyƒÖ�8Q±¹á\²Bî€á†WÄ´ðp,hÄô6È50AcÀS8í°ù©…|þÄM7¤Ïqå�ú ?º@b| ü”órrð3„]àrˆßŒ‰`äÜsËŸg¥ˆ˜€ïš¬ ìô9œRxì`œA!g8ØA^%Ä‘V¢:Ü<Àh<Üoç†Dº‘BD¦Øl6ƒÁpóæM­VK5/xw,•B # *qBÀlÅ44 =¢Ñh€·„9$7@§"HÓàEw"ö ‹ŒÕÃÊÓ|M‡_á@å<›È1þ˹ÓQ‡I¿!):Ü=ƒóˆå’RV®\ÙÅÅ寮à2ÁñäuhoØîz$áƒ,®$é‚…Ð0È)qÈñ°#nå*ˆbv8 t°œò8B±m„©œD‚»@ÿ€¨Îc¨ˆU¨T*ƒÁ�}œP š>œPèôrß8[¨_ï(—ËI'¬Òëõô®þ#Ž“G ƒ"u c:Ýãìì òM ¢‰Ÿøá!!—ËPýŒ+@°ÛprÛW8$¢"È"¾‚>‰ÇŽ4K¸8c¦1;;;s+xlt$=ÔŒ@ ¢¶èÙ €y“ õp#Óªò¸/B3Òx¾LC"C"X2§ˆ�º ç9»áz”C±OÜó§M [ðq—¹„žÅR±{¦árÇ$^¨T*I£Â\ˆÂrÆ)‘$8¾Áxŵ ¨ …‚Tj BXƒ¾ SžU«Õnnn¾¾¾7nÜÈÈÈÀ¯ÐÈi÷‰]ñ€‹ 1à\–âÞŒS“°agâ‘â>$If€ŸCx*vªè0Ê.VËÁlŠ¢ï¡+ …‚�ê�rÿ 9K Ñƒ^ð DH“‘—'jµš‡;é„¥®T¸myÀ¨Éd‚K–0Œì¹¤999ÑuúR<Z­Öh4â…D¦!r‰ž+:¬!Cc#?*"x~ h(oµÂmN_ŠRòQIŽ.ܤ†;üyôÔ8-(Æ+IÜçÄw™~5™LZ­–v„‹ÀdÒA€È+½_bÿqçÑGàa<è�ŸF€�üFƒøŠÉc.¸Ø.qÓZE–¬<Äaˆ#°rrOSC /¬[kˆ£_§Ýï[L\(AÄ\Œ\êçÑ’`3PS „ñH FÃÂq¸hé2‡½Ðét~~~]»võññúîêêJd]¡Pää䤥¥Ñ#Ä#¹­²‹$z˜$¬™Ö™Vé|ÊàF£Q«ÕâPs‘— ƒ-#<ÁÎ> a¼CË)ëÈ>ÜÖÁãÜR m&4IVL±pÀÿA¸E9Œ0¬Ãl {‰IÒ4¬F\é!.…‹ðTAô#ÛHzÅ1€ã”/ð°]`-{2Á“ƒ·‰´º_è "ųsÀÀ ;ƒLÐÍd!D\,´"nX#‹…x B—ÓnIÐ÷Ó�ãNt„·‰ãY·|xÇ6îëÆJêõzZsXM!ÎsC(7Íc³ŠÆÒk‰S‚C ÚžóodqsÔD£ÑHÞ5Üm)‚¤nCƒ†}G¼8P`ø¢5!³àa ˆ Vó€1äiB±#‡9WޱÅÐþiAè Ñ¿’tTXRRRjjjvv6®SfN:ðMb™D(?pìfR`/·»r îdù Çx(,·(às 8ÜU¬ì[ ;XÎ}U` UÞˆÉh4’pXh¬ç-èPq…£²ä¸™ˆŽ«““ï& â‹€"Pþ*>>p±Kâ¨$.È“í‹*9vÀý”üO”‚§¦ó< d&Zœ[RéÀíx…`xÅH¨T©TT <jh:¢`± œÊóÅAø(wHHô ØÍ Qr·þ%Y› tÔ††Pì2¡–$ „'l"ÒO°\H,)”®Þ!î nv ¾E �œ�Kµä D(ÐÖ$.MóPRbrœg9aJòöövwwOOOÏÏÏ'ɆÇ݈Â4Xå€?Ñ1©…|¢8V<‹ÈF+“———ŸŸÏuH„8‰<W N&ºŽ!Aõ'1 '’ê`›õ‘ ý:ùù⺠v™o7Oóâ ˆÞvÖÊ €(Óµ€6Y„D8ˆôðü =è_ÒyyˆÄÎ ™r' {Kbó‰=Ð)œ é)À3”À¤ˆ°J<:ÄpŒsÅݤ<ÙBŽL§V&8oˆ_­/$S+¿““y¤0eȼ< ,Ÿ[ì€Â3ܤ`0ÈJIvn¯ãyòĈß`F4Z¸Íi»ÝÝÝ===‰"“•ô $öI:çPváC ¦âËXG¡FHè5ÏG g!´xÍ%ö ¸¨Šƒj÷ÃÃ8á  ™$€‚Kè´§Ð;I>.`U±dàgNNNíÛ· ©]»6Í®¨ áÁúЧaŸD¨$iÉ„¥<¦x.1ðâ<r_ôolÙ¡‡Ç`Ïà¡ÿôB:@E,2´vÎ? ?A𢵂BÏ# ˆ>PÐtA¬]$ÑÄ>Pþ.ˆ\j ýC2d^ˆ3´G”¯x‡6 Rà(†v¿=‘KÂT@H$¡8êhIª·áÍðåBE@>ïríT •ÙཔpPˆót>F#L^HŸ¯›ÄÁæ:,“<Û ÿ`á‹E§Ó„ÝÉn·S´(d[ž² w¼q–À}ÜXGT B4¹hkŸD+@Ë ¤o®™Ñ´à4*^°‘ip† – ÏcÒà&¡¯€0At¬,Òª ¿s¦;*|òDØ¥Óé Âò$Hº“`@E%—°Ydç„°E"?(;>‡èê„„„ÔÔÔôôtB{~ál'žŠ`I}?‰„‡ (%œ V½Æc2™È· $„‰Fd:㘠4†CØê¡«a¦t3ewâ<ªÕj˜þ¸Õ—p "ói7ôrØ?H®B ÉLåÛRÈÁr†D‘G^å QżÄ!¦¹ˆ'©lÈEEx5DaiHÝbk.ñXd^à@°â0ÎPJpG^©¥¨è ±—[½ X‘4J8Íï¥Cô2z­Z­&ÿ'B]é°Á£ƒÕF$…óÑÁ{æv�ˆcÜ+‹ƒJ?‘Rš ?ÌY’ðI85s6‰þòly`/\Ľ8<"æ2^Ú‹p1Šà»Pwx¤rå›ÎŸøš€‹ðr–Ï+ p¦Å=¼(ü” ”(MÄË©!îNâ7¨÷ K5n€/¶&‰cÕl6_¿~=%%.ùƒéR¢‹@ì£jR4NÂLóåjT ^VŠ˜4&">ŠÍâ+ ½„»Wñ9øyN(9)ÃZ½œ•Â’ †mEô)Ì×\êâ =’l<G*h…0¯ñª|@tî0Œ3ØÚm6›bBuHÛºDꄈ[{áæ¬¯Ù šË³ü¸s[V�¢c2™ð »?¬y</•g2r þaž…�¶ñçÍðÒ’Œ jÁË}$ÎGá4p«B…ˆ»¦«/Àm}¼Â|%%¿xÌ47Y@„Dò&nã¡ÀÜ8NqÜÒÅÕ/¨>P«¡Â„<LÚ¬XÜê -v^ß Š´ ø~x6‚/‚Ù°ìPh`B”Ø|ÔjµB¡ ¨-ÁJ^ÒV¢^Ž„ßð¼4,/"3q:h.z½žö…RxyÔ¾äQpÈœEÀXg™®®®F£‘xVËþ4lîfGâ?Dtœ©Ò9‚Jø"sWy‹r2 P_¸ß—G½J¼ž8˜#b=8‹ÂûáæyH_Nyp ¯©¥tRš_3çïËWžWª?S«>UY;Yó÷æÛ\l¼–*<¢¹$Vo’ß¹QE°âZÀTîêç¥3¹…—ùƒ~ o?iÖ8](lÅ‹Ãk •‹”q"ôE¸xÀ7Ävœ[ص!œrçVäîwÁ*ã®ũ9W}îÎc¥xYkÎ!¸ÁÙ¯pá¸ò"›È”¢ÙÑÜɆp,„K‘iž CE°8w×!’WˆàÜ…×C"Ï?ñ([ˆÓâ>!X\ÉVFs””Tàj´¤Ð'w ‘Ë4H® Ð®®®¯¼òÊ;ï¼ãçç‡`9DpÑGOh Cý 6ɵ^Š[Ã`b¥i"ÕŸ§vÑûé[ùùù8$‘Q”–‚®VÐ!<£–·ð”åål’ƦR©<==áäeÙx ÏžæÅXi�jµšÂÇ1|š¦·?,®\8†° [7­·&KbùZNùDHK,’4}m½õU«s{ç?da‹M—)f)´ûµÊÎJIO~æâ9yˆrq[Ñ )$kI¾$…ˆlk’Ö;¼ |›,4}ÞíTчÎ2À%=ièåÔ€î B-jƒ’ä¢ú'*îpÛú•Piî<!ƒ36^B~ 0T¸ÁÈþN4 +‘{ZRRÂxN¡ä †At–ÞO ÑžW%áøfIdš:À?G>s^m Š&} ÔMü¹p…lèõzñç|IÉ9;”àbg$¥Éûrîܹ”””¬¬,¬�Â…É" Ëj ‚ÞI´›()„ÞëV/Oã½sx 휓D"À‡BK$¡ ë\ªÑh(ç |gŠ:?ïÕ0 ÔWåÚ<}E£Ñ`Åx)Î` "5߸éçNIh—DŒæ?GYÏ ””Ã÷ !d¯Ê”»ÿh3ãííMu!F£b¯ÂÒÙ"Ûó§¢^\Rã>Lpˆ¢Ù’X&næ†,ž0AXˆx-®ÔÃ-þœ³ÉåbÁªÄó²cHš!G·˜ñî><ŒG‚’^…´Vn‚ãžxŒ)„}¨ÊËxà:¯µÅ0 ñßÏt‰}áa¼¶ÄX‰§§Âðx3^G€Çzð U>BìÅqÀ¿…ª P¹x¤,½ŒH SÜj«Ø9þåE x š¤Ó7ÚH°J&“éܹs |؃ÝÚœFdƒ")›ÓM°Rê‡$M<‚Cµ•Ër¹ÜÙÙ™ŒrÔ#‡‡“ñÆt(ˆ‰p³'Lˆáù¼j-oÏC\™TâC‚Uöƒ†'þÜHÖ^i›×ÂAd¤¹ÀÉüDú*®¨É$ŠtºâüÆÑ/§BpDò*“CúXÝ:»iÜ5Í›7饗.^¼¸oß¾ôôtÛ6Óû&ç½Îõ¿råÊ$øët:ªÁÕWWWooo!%±£\( ¯ {7\ \Š•bLO’†žü„=*q\©V1Ìú¨ýŽ#‡ðÿÍC™¹ƒ –4.ãÝ\PÀC⨀s•> R #Éäö  â9¡ÜæÃ‘y´Ò}@\$Å•‘ZÈ;ÑÁÚ†EÀ&rg!N>ÖSŽ…÷ÃׂÙIÈ8îÜ¢ÐGÄ[ÂÔ éD"4ð¤N.eÓö¡Ê-Bïà5D1¸»———‹‹K^^Â(l6[vv6´"¸0eU«Õ’æ*iG Ö#6¤N:Ï<óÌ©S§’““!Tñ”5sŸ&é—dzâÁÐhÀ<ÊÁ¢\¦Œ+ú O¸á™ÎàT žÛÒ¹ÃS†ùYæi³œ±ñú¿\Èà%s@$%!,§Ü¸Ž(ÌÒâ^hLó÷÷ïÝ»wÛ¶m5j”ššš““cUZ…\”ÈÕÕµFr¹üöíÛd`á²°‡‡‡ŸŸ_­ZµrrrnÞ¼IéÍkÈž§œö¼.½ã¹ÊýùüÈIr<Q\ÑÏÀcDgJ*§G¬ï–ÆÛäHj�ó–<âÏí¤xЈ)ï€ÉkWCt•ôß”tãa~ü„óz©Ô)KA ùçüR"<Τþ ÃVƒ×Å.ÈÕ2ñçú§45KÆÓÚÁ}%¥Za´!õH­V«TªÜÜ\Øš ð¬CR=ÅŸû!IºØ‘] ô›yy�„< Ð ½È«‹‹ u\õöö®S§NFFFZZjsssÓétyyyt^xü$/i ‡$ ò*ñøÐ\µZíââäáÇ8ZR¸E~ V@ëFJ<—\c†E‚`æ5,t:Ùc~-©²z›!/2«)oW ©v6”!à¹\4AÎêV@ÔãÖxË)çžÊÃ.-‹ì‚L_WïÞ½ .T©RåòåËv»ÝÞÈn¿`Gg”6¹}û¶««+9*¹ ÒdddäææÆÌÌL²ÝCºDFúæBü¡à.Þš^ü9‹“'…p~‰Äi˜bP   zÜâ_4Ž\ü9KŸGˆÁ4Á;‰q»¼MÒÍËŽÁèÇIªÄwEðÊ+0‹Ñ�¨q ÜQ4eÞº†gíøøø×-œyl.jŒ’’Ä£ûèôõá­Y —pu Ž$;óø±¹>Á´PÆ+¡ŠÀòˆ^Ä@£Sà…¼¯9©2(8„ 7ÈX‚˜ ¯Z5NF£Ñh\\\Ôjµ««+äOOO…BqöìÙ‚‚r;QÉ5OOÏÜÜÜììlÔÄä8†`\”„ùr׎"!!áÚµkÄ«x¨7Êj4gŸ}6+++!!AÒ¿<¼-hš ¤'!IƒîÈuVˆPÑÀKpmC­V ^u^©TÒŽÓ1ç¡ f³¹  ÀÕÕÍœ$Á#\}牃<–ºIÜ«–Sμ4Ï&qZàdgÌ–³eË–'NÜ»wïîÝ»V«Õ0ÜàÜÞÙ*þ¿íeFFFAA$_‰zžžžÎ‹�òîÎDˆ‰@dƒçœ›§øYåq\Üœƒ¤fn“G—·¨‘Ôaä¦þf(7¼.ˆ·¤#E%và…{â?μm!à:j3KB¹ÎÇCx5jäãã“™™‰ÒœÜʇ@I5Fl%Dr^?Fâ†A(rïyoiî– ‰ðúͨ‚#Št(‡’!éð_yì2=‹òØh#†Áã~Áz6…$Ò€Tåˆ 4’A¦<ÚJo¤›É±êììì\«V-WW×´´4½^/Qm±bÁ¥Óé&éJ@÷ †¢º_ašKvvvvv6¦è>(4Jýì½måçYæ÷œ~=§{ºçUÒHÙ‹$,ƒã2`Œ Ø&k\!66؉‹5!ÉÆP$EÕ²•%»µ©Ýª$Ke¡v+ä…Ä’à-’�[€m@`a¯_ð"‹2`[öHš‘GšÑhf4=ÓÝçœ~=Ýùp©úõ}TùHûÃé.¹§»Ïÿåyžû¾¯ûº¯ &};,/ä©»¹¹¹ðÝ�#rw¦�BÐÄìy;‚ïy«Ò®£‚É”›_¢8¶)õ¤—óBZ³GÎK”ÖçÚÔ—¦Öu}ë¿Ùºý•Û[ÜÚ{ÇÞì?™-í2 gñvvã±Øvqü5Í훌Dí<.ž|Ü3h¾5ÏW¶1µfäѬ_~²È768˸ì=8Ñr²ÛN@™’‚ïF£` ž·‡^ŒX¤û%%14 ¡HÛå¿páÂåË—ãšj:{Îî<v&º›¬È|›ZQ½KÊ/2&…Ëø8 áùóD_À´&ïsjG>Îy U¬—–‹§"Ñï�–+áiµœS¹6ð7ƒ–¹ßãÇ?~|yyyee%ÕX®'ðZ 6ò¡<í‰öz½^¯wÏ=÷\¿~}ee¥ôÕzè¡7¼á .\øüç?ßï÷Íûj‡õ‰”f—q±m~â‰'Š'Y—á5Äæ¤€oS…§[æ0ï¹4wbHéHM,Ûê‘;S9Ì€H]"Ò |%j÷5Y·qyÄ1Á›T9Go8F}¸ f3S¿>Õ>Ö6þáÆÖ[{û{s™›ùÇ3íbu^Ô±ðd%óÃáDÌ=ä"ÆœjÃ#ŠYßèN‚tg7ZU¦Ü³²é·ç E>‡ä ïÞ¥¥¥Øo�.™ÐŒÝ¯d޳Ñh´°°`sbŽfŽ?T�L[ ce‘”‚É™c 0j†=¶³‡ØÌíÀàä©§žroŸ¶¹Û9¤‡ìp,Nó„¨xÙ2‚ÿøbå±Djzkgý0RãHPºýPswÑ”3š—J×¢>yø ç¤wíy:ÏtP$sÜšžž>qâÄ©S§ÂKPŒ|™G‚¦æQdõ景¬¬t»ÝcÇŽÝyç[[[ý~į÷ïÿþïë[ßúè£>ùä“¥UF&pŽ%|lÖž»#ðÛ <¿Bƒ¤IõÒnLãx²IwöâcmÃ$òãr²’´¿ÏÜL‘Õ·Áå Mraj,þZ;¹Ìå|CôrØê™\Ixñ›+»óƒùù¿;fý‹[zêÐ|Œ¶¦1­’¥ï&¹˜ë‰IÊ0Ô ÆB+› P õí°xÁp8„çê>–3Jý˜$êÚ&›Ç#8j)‰Š•éΩœì¨–“7ó…ªø4IJèAXF‘2ƒÀ„1Cÿà“v Î+°¤þ/7’ŠÆY<Ù@¡0Z 3ÞפF !-—̵1.h‡^ 0Â)ã\I3üHø?~üøwÜ133/.é³[;'Nœ¸ãŽ;÷ööbt†WEnp0t»Ý³gÏ^½z5扭­­¿ø‹¿è÷û_úÒ—nܸAq6®÷ÃJÈ•SØÙ")—Wšs;k1 öOâHmÑäï—êqN§Pn¼y|»\¶‚JS ÂÕ4ñÒ«Å­‡šÃG'óhšä µP]&!çhB'§ÕôÁWöƒUØ¢¦Ïº'ï:ÝbïeP±mYhæ«'{øWýžö2Vc5¶v0Ê‚C Úã)Ôã¤xnxo:(F¨ +Ú° Å„UX€"‹›x4©øRJ¢Â’“"¯ÉB¹ü õ%ø´·ÆXQ~#z¥Ç`IžvÊYoŒ¦�ŠyJP?\…Û Ü6µàoà6 v¼ä\ptíx8Œâ—Ó<ým®–£0€S§N¥ÊL•ǞDz´´ôÊW¾òܹsÃáðìÙ³ý~?œº"„d@·Û=qâU~ˆ[»»»_þò—ÏŸ?¿¶¶F_Ê!Çù>Í’©žq)RLžá‡ùIÖœ¬»Yù'$ !U{¥Aèpubb™éþd?ùÜ&6 ˆUYñ:…— o¼Ù'N,//ß¾}û¨ü &!çCƒVüòòòÒÒRZÍæ;z †&GY¹‡H( œ€›fº<žrªïÞ2Ô‰ˆg8`øxs2Vin‰ž[‹¶®2zã1~ë:;ÜÚÆƒ¦À€8eI·û±`z&w¸‹^h{lTf¸!w-,,�ѳ±ƒ½Ý9 ½Âªcéþ=$(N`ºƒ‘z¶ ©7Kl­­¬+^WÙEóö=‡o?JóMø#E¹µV¼^XX8vìØüü<ÖD\Øüü|Š›sçÎe4íU¯zÕ3Ï<sëÖ-+¤…É™q0„[Øëõnݺe3½ôxÌH2P PÓ=pcSb�g±)éM"R¤hvØD™¢Ið›NŒe5Ðà ØXÔ*ø°íK%Êg\8פðëUx_ôRí^4zâĉW¼â9Ÿ„œ£‰79ûœÈgé0@`—Ã&-–/$ßor°†“¬Yù ü+bSÙ AÕÇeCmOÀZôÑC8)L³rZ™ûïö~ñ–/†`í°n¿%æ\q<9è2»n‰FºSüSâ}¡_{iOQ`lãZ ]šU'ËKÌ0’áK”�� �IDATßc.f^ø4ÉW„‚œŠÒrïºiPßC?û±¾ºvXðÔ>È€˜¨eS¸ðrüè~AD €ÜÂÂÂÜŠD5²þùùù{ï½÷îo½ûÒw^zß+ß·ÚY]ÿàúîÎngØÙî¿æç^³ÔYÚ½¶[Ö�ÖDQÛ„‚Ñ„Ž‚2äÜ‹E›*ýÖmN]Ó•ôL4)¦C‚k>§ª¶é¤oäQM,†"ˆšé§f1~M– bäy‰–Ô3Ça|ÒÓ2O×®][__‡G5š3 9Íï™aVóîîn¢¯Ÿvú…<c]Jà¸yV¾;ÞœËì/øýMzþXõ8YÁÓ£`Pl<ãWÜE1Y`WƒÑ4*l"΂€ûaR Ô˜4ÅcR ·˜cÚ³°Üi#3(¦3C3ì^2úÇë&=d4ʨ5¬mE“–vrsà<<1Û†z¢–åÉ•.—™(`æjÓBY�¶Íœ"ºM‹âÒ.×DÀr b’˜gýt»Ý^¯g9Ú°�B˜>wîÜü÷Ì?òöG¾oæû>ÒùÈ/µ_zfî™ÑôhùkËg~ûÌïÿƒßßrÿÌGÎôú½^¯Gê³¹¹ÙëõÂaÉKÉõ'Í'¢X€™2Ô´`C¬á<plO¡0XåÜ‘xÏô¨-Ψxb¨“ž®ªíÞíkÙ\s ó?]Œf×Àú! 1%ÚŒ_ Õ¶{HCNq8 9GÖÈq¯Ø§v;¬F�ð n½z'9vQâ¹67EM¢µ ‹Q{Ÿæ2-ž ž5”\üTš”Ö<ü.‹5iL8¦¨çª,øfãHå<}‰¡ËA ÿе6:XÒ'»´˜ M&ŠHá¼ÙÞæ¸Ã\ŠJtJ:^«½\=ìb2/baa%cÚfÄVa177?Ã4b“ìXN¨n·k¾ X%òqsss9Cç-õk2÷ÄVLj«f%1/»ãøñãwÞyçƒ>ø‹oüÅî|ôÔÞ©4ÿÞ¿ùþïÝÿÞ­­­Ÿ}ÍÏî}ËÞwý·ßõø�?õSkkk©Ð¥?´´´tãÆ’-y>ÿe焬D`f‰ Ó`„[ªp~‹¤Ío§dv žzi‡Q‹ƒN!> ‹z͘uíë/¢m.— ¢ìY爅½ÝÛýÍMÌ ^zg#ñ)@™ŒFa·Û=}ú´Õ—©L‰)¯q¾lŒv0�o(W¤tç. 㺓\ælìS@ŸÉ4'ë“úŽÚaebËJZ5 V»œ .³ó3èç+1ÑÓVŒF½¹}’ÇàEÌÓ”ÙÉü<†AilUÿHHÀÇåøñãgΜÁQÛYÚep4èÜ”§ì|êE³E<‡ašF·Û¥Ú3éhü±»Õ±4×Üï÷oÞ¼ékB—Ç­Àš@Ìòó•H‰³¸¸ˆÖNÞãâââ‰'¾ù›¿ùñïxüÇüÄì‰ÏÏ|þøÞñoÙû–8|¨ó¡çþös÷=pß7}ý›:÷v¦¾åE|бcÇò©–ðטŸŸ‡žUMËœŽ¢M`¼Ôg+›ËNn.©=“=mé R¶j‡Õž<¬êÉ@ˆÒ1-ájüåÚ Ü{*¥OÞÈ-³¨64œLLªœ#.tl›h¿ :ùnGyWOá™þ„߉£—ÿ²=Ùèg–˸q$¢èn*€„؃2[«ŽÁÊÍ÷AcÓ2ž6Ž3Øÿø¨‚ÿ0ÕÄ¥²Á`…jÀÞ8ÇJªÜ÷SÖ7] ‡c+ˆ@ÕË€9\:éêâââ›ßüæÅÅÅÏ|æ3Ðsi?KÌŒ=†b³Î\ç# G—ðbK€ÉÃ)Ô;¯R»?¸:·1ÔsJ¹ä´” Dô¼ô;ï¼óî»ïæà>vìØâââÉ“'ï»ï¾W¾ò•{ì-í-Qçrçroªwzÿt3¯Ÿ~ýú½ëï{ÿûžøÒ¿þ-¿þàß~ð®o¾+ªÓÓÓý~?þ.`ƒ}ÅzÜ¥?L´‘<�@H Ž¤Qš‚~/‹~']Uô–$�ÖØ&vSçØd ‘ÐCÙgxÎD5ÜŒlÌC-åW_ü|y2Àõèý“0ä WжRGxÒNBN#Ç’÷Ê œK& 32iEéòÒåv‘‘­ev�•F~tû qd³…ÞʉSõd¯Éß³ú9m‰H$p³¾…Hc¶X“bÏ%£¡B—ó^ëV£Ï™ñÔd“‹b@‹‚ ùl!äœ9M,\MðKÁ`ÛD»gžyfnnn8r–&së8ï"7¿ÂÓ.Ìëřƌü&3‹²Ìðš/}~û‰Hrb†â .“ajŽ­ÙÙÙ^¯#aaa¡Ûíæ_———gffŽ?Þív—––‚‰<yrvv¶ÓâYÛoû/´^<1Ûþ]gïšoówÝu×<pOïžÑh´¶¶võêÕ˜ª¥Š:yòäæææææf¢¢|íÀôõ{=bŒ÷ÿ×ÖSyõyžÐ,?hå!³ÂHPàOšV`µ[bà¥ÅZ0Y”ml Ã%?�Àà îþ椲¸µG¾J|ÊŸ2ýÖÏ$äÙ—áõrd»‡lF2U ‡&t–©àâ{H„(Gp™J±ó4s�tGs”ß"„ECÍ|»Œ¤ZÄnkåS’Œ‰¶¹H =€"ßÄ©GùeÊY±“ º•XÈŸ‚¿DžcÅc@¼ +Ð�Õ„/K¡PøÜ»»»çÏŸzM“=dqR eÚUÁ5( hÊZ¸.‹Qn¥bfª1)ùÙ³gÏž=ûÄO„mLM“:�JK¡Ã%®Pd{¾¤I¿D,7x8žR(G"½(Å%ªÅAêU¯zÕƒ>ø·^ÿ·>}ß§ßÔÞôÚý×>Ùž|vúÙWî½rzzú‘ÙG|öÁÏ|ò3Ÿ_ÿü37žÙxæù™­­­Á`Ðï÷gffƒA¯×ë÷ûW¯^½}û67÷uæÌ™ÑhtãÆ C–S³—[Ï©ÊRyØëÑ…xbV1MAO.ÛRÏe¥¹ ”Jé÷¤€Å4Ý;…ãyP(g°h¢ †ÿ8ÚíahŸÖŸ„œ£§J³ itS[¸¬vû'àÍg§ù°¹L²ä€vóÆ ö9I3â°±±±¾¾VÀð6‡ÉÙI*#«œc: ‰v –U:@P?­·AR _0nªhp¡¶bgÆ¢ÿoz›{`Ö Xlf€èXxˆ„ÏuEÈÌWÀ O‰—ák„d 7œ‘Œc3ß¾}õå俥…æ9V¯\•ý8L)š1Ý"¦ú2<yJ¶AgÂ.Peð ׬99åike© ‡C/˜øÊäÆSˆ¯­­­®®¾yæÍ¿ñŠßø{3ï¡ÑC™þÈ¥v龩û:ε?ºó¯î¼øÄÅ'¿ùÉÝçw·.lÝÞBÐxu¤Ö-Í£ ®$,kc ˆ*$…ö2{"·éçÑh‰ë«W¯ZÐÚ¥s;°qsíëP׫;©‚©lp˜àashšm–5¹GrFÅ“É^+¦Θ)¤&Œµoú@èIÎ “lúŒ6ž´×dâ¦)n ƒºàõç²½!=#ß277÷º×½î½ï}ï¾ð…Gy$ÞVÀ5¨’vk¢‘•@IÙ\k—ÉÿàõÆÙò)˜æâ5€²ˆíͲ3}–yâ¢ó‰ˆÅ7Œ>„ i.=WÊ8ö¶P &+ *þ7m˜«�YùHŠ-..&8Y®ØlZÞrGÃ}XΔ)q`Ö1?tùòåçŸ~}}Ý‹‡£Ù˜'/Ù&(¹IÆO,Ñ^2Ç™ÕÔÜí`b:‘ã¹çžû«¿ú«ŸYú™÷¼õ=oš}ÓOv~òï/üýu>ÔZûÞ¯}ïÂ3 ¿ñ¿qú+§_ý‘Woïm—Á~•ålkíöíÛÂ1«‚2ÚÉA^\ÚÖ%âÕ„|œ°—'“#‡%^JÉ`Ùð‚òײV·û8${KHàÀËp«y³Åµ½Pö-غnM[rÓÀÑ㔿IÈ9Ê/–‚{‰…°è™2«A$x.Ú6Å:žÁšœD¤É–ÂÍ%­¯¯Ÿ?þÊ•+`MP¹\PM{êD”À2wÜqG†À$x¾þ›é7Ôy’õ «õWÀ¯ŒÒ cÅC¶ÂãdîÃঢ#`ë6˜Üy;©QÀÊW¸;N‘2¦GªØ$M”�í,\õòljÇü+3L9zJ?‰ˆë€GE’(†ðÙd¶–ÈÁGšïFZ¦—677C ûˆ¹E4RS÷¡UÈúÛÛÛ‹‹‹¶`ÈûZ__D6??ÿ s¿pík?wöçfvfî¹qÏúúú¿Ýú·ŸûîÏ}ÛOÛ\gns{=:¿‚0´­ó .ÅÎŽÁ&/!_§¹Ëyeiïgýß¾}{}}=š£2OŽŽk#2•bZÑFÂÛaÑk@-HÒÔs¼}ä6&ùìNŒ)l(Hp‘–›WšŸ„œ#ûr.�âÁTGÇìÒ2ÐSšŠMþЄ4†<Ì$qé½³³sñâÅçž{n8æÀŽídp3Ë™˜Ûnð[ßúÖ×¾öµûØÇ{ì1ã9ÆYîîÐ6ùÆ›@?<ža4!ž*É٠Ꞣu‰ÀÍK88sÁ£lUW2îÈÔb‹Nj+29„jØkD¸BNµìÊÍù­Ð KÙü4ò˜¸ô½-åÂya¤Ñ l…y8N0†¤œnx¯‘Öpă»¶Ö‚°A‹¬j¢u·Û][[{æ™gÜxðÃSÞÜÜüØÇ>öøã¯¬¬ìììÜÚ¸µÛ5ê ÎÇ ‡Ã8 X¯Øœ, TB½:«B䑺ÕפiÄAÍ ‡&­ð¯¼q†vËĆ  iˆ_iöÀý±§‰«dd2J3Õ4Z6÷> 9G¬E}/^yI-¡f–®&«9]ÈZ’ð=Wì=sªBxk‡ç%©WÚá)3*ªíííË—/OMM­¬¬ðAí°ö(È%œlvÂøŽ{±Ø¾Å]Vwœ­ûD¶tŒ“tröâAGµáÞOÓ¤*(­]è­îý67©'=DÔ‡—‰y&½^ú•b±H:F1Ó§ ܶ¢umÙüB0cÏ&½o¼ns1ý~ü§è°9&öçï§*2zCÄâ"×ÖÖž|òÉÍÍÍ{î¹g}}ýâÅ‹W®\±~P]Cw4YÆØ˜Ó›Î9‡0Šëèbúe�â&»âÚ(–î¬õ,Úôl©«yV"Ĥb$šËíXÔŠ' Ç¿b¸@ÃÏCÊÆ !+Ú}nrޏc9NKñç_#Ù½G/_b‰¥jñyc?$1äšÜ>räá|N@¢ÃÒ@šF…„É£Æ?ÿó?ôÑGé:dÆÐйÙ-î ÐEO)3??Ÿ±$zÙ KKK÷Þ{ï /¼pûöm«k禰,ƒ–íлs×ÎÔÌÔþÞþè¹ÑÞÖ^¨>¶#–s=IVµG`y4oQ ,GŽ�´ëm[`S¾òÍ·;ƒñI ww,š Šg²¸¯ÂNdu¹¿d†žŠÙz) Ò Ëâ ›<LŠrfY-†äƒ§ê!J”=gffÒLÊK±Òï÷óRfgg/_¾|ëÖ­«W¯†ôÌ¡[êADÕçççCÀƒ9FZ€´L"ÕŒñ+óYÈä€Â� JåÚÏCHËKÌä�ô}‚ó'Š$k‰²ÈíLh:(¹lVQñ/§È¶ŸSîšÉ$3‚vØ1°‘ï™,rM“sôTi^¶#:±ôQ‚$¸°0ƒ¾°«YjŒòe.Ïå.RìdOÎ{…=i™�8鯷ƒÁC�CÎ5Ó2¼ ù2õFgU{ç¸eí'0 ²7Üê Ï‚kæ€xqJà5Û»÷îŽþΨuÚÞþÞìÏv.vö>ûR•PžFNK²·ÃÚ”2ekåø06b¼ÓIûÓäî’jXƒÙ I;lzmTj % ®9|"`~zÉ8}JzÔ‰”?·™¡Ë”n×qòôÊd‰k ˆ 8�G ÙR†f<Rê¬%WÄ,áËÔä×~wñNÎdO§Óé÷û)þƲ͜6k ¨µÁsÍ”¡9— ÜÊ9n›mç¼nXþâ, 1Ov{Â:"…†P8ã&IMº;dºÙS1ÿ&y¥<oŠppM·o2 zô_fÄÛŽzjj ‰Æ¼¿S§N---=ÿüó!Ѳއ�” º÷ ȤšÆÖøD†o€Gœ=YÁÓ&Vd²}�¬kw¤�|+ôÅ>4•³´vºÝn‚ «™¼µµ•É>žÜ¤ÿ”ÿÎUí|ÛN{WÛßÞ?öŸÛÛÝÛÝÝÝù±ýïÞß_ÞŸýƒY›¶YÓÚÐb!=[pž£ *”©kVAƒ¢Kø'!™´1OøÝÝÝ…ý~ßñÏ£žä0F »7KÈÁØÒ|M¢;ðX*”æe¶ŒHzËl¬[÷¼e3k9Uéô@|ØÜÜ\\\,kƒs|kkk}}ýرc9Ù©u²~rI³gffb«òÈs0§ ÖÍ(À¯5 ù¿ž]cÔU¾g_hY½ìd7)˯¸c”1)o+QÁ0ʱó9'‹ŒÊÂ{‚GLaó´Ã$ä|£DÒÿ§%ßÙÛÛ‡œJ>²ÎŠö¸%•�ÈôÍS,pн=²� Á1MÁÙè$ah©àðbðÒqvŸï$¸¨aR: ì §………~¿oi¸§d;¯ÛéÜìÌýos£ö¢ahç_uvÿÝýíwþðßÏáŠçÆ9‹Ê€³oË ÷ӹ嗳 &UjÓMËÙùyÎKKK÷ßÿÚÚÚÅ‹›TbÉ3¬MndÃG$Ñ¢´`(@ßç‚ݸ.¯žQy7]hwñú ©±¨RòœËPaÆ6{½^x´{½^SSSÃá0L‰Í¹¼¥ç³VWWƒ2¦^iAåÑåã,¦iTœ„ÉBË·y FA=ád—©&ujžÿ‹#5(1ŒW@(Ã\•öžEM®3}ßù¬Ñ`˜üM£"/âcž6;0il8¡òî :1‰jžþyRo×ãF]pdšÇì~³•¼²ÉÔ¾%$øÜá°È^B…‰Ö®2ûíÀ¨ƒÎµ”™»Fœ9’L j¾a® ©À¯¢æ¹»»‹§¤e­‰î³³³»÷ïî½ioê×§F£Ñk^óšw¾ó=ôÐÌÌÌÜWçÚ—ÛÖ°Uh.œ„ZŽKÕ%¼†› Ü{7ÛJ>""`yÔж··777/]ºôüóÏ›àçBÆü8ˆ¼þe]ŠS;æœWõÄÌ9Ä .ð=gâø„Byã¦vù­< ¬üoè�ÑXcmŒF£~¿?=¾uëÒúÑ*¥4dÌ+øAú=ްo<+f>¤ç¥ÉüèÊÜȘב>ׂ>4‚½ì¿3^&Û8ÍÙ}Ž\Žó^R²)m‡rZ-;N‡™Ù¥!T>(Y²ÝîKcrRåÁ(Ss(FÑ gÉΨ£‘îç;$wf›²bnt‘Âe&Y¤ßrâpãÓ^t˳ø¢DàšÀJ<ü2>è� °…˜Ëq‘çk&§Îš‡ÅRÖ‹'ÈÞÎþÌþôÎô‰Ó'Þóž÷¼ýíoôÑGåW~åÊ•+Q§³Ð¡«Á i¦g€Qž.,8 njœêέ™â®A7dÔ.ξL•ÀC^\Qé´Y ØÊuôè'%KHÙšhDyÚd‹GèPÊ áCÛc´)KHS@l“šôåÖ­[бŸéþþ~�ÆápøôÓO¯®®æ ÝЂî•?€h}}=a•NTõ„“<–3Þ[kR!™ÂƒŸË`F@•¦óˆ%®ù ž?e¾›ÓÃÒÐ,Êiš(|<ª{¿¢ áÞpZ­ÖwšB¡ÏtC±ÉÄÏÄñ Iúèk†M¨q¢òÒ@ÿåœjR0s7Ûš,w×ɧR²°t`¯ÑjFº…fƒÑ¦l[Ã\§•©ˆ"M#ýì‡\j¯×³À­±õbóž]´ÔîEøâ¥ÙÎêêêÓO?}åÊ•“ñN›šš:sæÌÌÌ̳Ï>Ë>$_+ª9ã:¤¾'­†y\¤w8‘ÝB 3ãÖÈŒ¡yþ I:}uÂ!×üV¯×KoŒ{$øy~¨¤AÎ*Úaµ:«?˜À]º…aOag¹{ÇHóåR”ìììœ;w. Ì6 ¼Á`póæÍ„Ãø`³¥Ù¶´´´»»{ãÆ¶Ý³Á—“n I’_e>²ŒGhm¼d®0ã/îÏYYŽ•×Ä¢ò!€øåz4¹EBH0‡tí0F\tAOSÙ}S}"±ìÝõñBJ€ÏyUZM“s4!‡D©Lnú F@yuâ@%QÚ3Î;2þM³¡È4måb(h>˜;S#®åËPH±óñ¬Y£…c"‡©èÓã—ÉÑ Zå‰WÚQ/ö«ž™î|©³õέ•?\ùèG?úùÏþÚµk7oÞœ~Íôö}Ûsÿë\·ÛeΔc×@ºLÅnllUçy2•iÝø&[Ldzœb9OËTQv´nR°…Åò‚|+éHÓpñÑA)!Äß1c‚@ˆ1§ª«7ØV9¾Ñ¨) ¤Ô4›››«««ËË˸fà™¦N*3Þ ½|R²gæuu•Œj„æ<£ÊYwÙ#M€œ µ�dçgä„¢4ó E%.�;SoÙMŽLÂýTð¤]í“û΃Ÿ$Fˆ?5Í8·ÃöØMc§@,–¦v̶åÇ$äÙWŽò™™™(2qÜw[Þ(dDjŽ]|àIióÃã½Y^î^X­9ë5}~€5¬‰U\^iüššœ…kjðŽ'ÞNEmŒ# fZ~Ù·œí°�Znd{{»³Ýé<ÛÙ»ooç•;‘ÛÝÝÝ?·¿÷ª½¶ÑöžÝ{nñ9ð£üž*·‰œµèR%yP8Ž*¨½(íóZIŠÝÉß ¼^†ïx_Øaœœ±˜,Œ�&u6ÍhŽ3ÓˆÔ‘iãCQ±¼X^ �¬»Õx˜œ¹t×ý¶··¯]»¶½½½´´„ÅNžÏææf´8ùB ¹v@„ãÌ¿w žíƒp‹‡y¸,<~ÝòqÐâIM\šýOâRLªü¨Ë!yãV0ÛívCÏýΤÔ#¥ã:SóÔµ#µAò¹ð8/¡˜F…–ÝQ¸þ<®$“sô%ާO7ŠRï}~™¯Ìß™ššZXX@1—«Œ^6M27ÍR+à¦ÓÄÖP@ðÅãçÄÙ˜ '3ç…¯éMȲN<.‡æ3lQRZ6¿Å¬ip¬ÓéÌl~çÇv¶ÿéöÞïïMw¦[k{oÛÛ»¹7û_ÏîOíg6¸h5nRfûãYï™®A¡¦Q>¿_;øœmÜÛ›rÍ´ËzåÙ ’Å“s<q—y È랺…ø^ ˆIÉЄÅö©Mž9ë͆+(}²ŒS‡9Ù‚kî–õÖÖÖÊÊJ¿ß_^^Nk'‹öرcóóóƒÁ€Ô;£Ïííí~¿ûöí`­(è˜ÌX8+»Àµ¸'Š0`ªºa·nݲ¢³Ìüßlö ¼Jþ2fäI&œPZGÑbƒ¦¬)Mƒ¶ÈžQJ7cÌuzåÍ}54z„C “sè+Uˆqð2’ŒX;ò´áØ*^:Û/ÛóH‚–<ú¯Ç츜FNgÄÖø>ßÁ-ÑÜY§·f,·Ã±Î½#ïæy#bUÎPSÃi§[C̃~ûûûÓÿ×t÷ÿìnÿôöhz4==ÝýgÝÎõN›;$ßbCjšT“ èƒ)Ùd«Õq,ß™CÖ®w9+“–R^øI6™Y°„Ì\wc,®ÀT¨0YŒð”&_ º¤í¤ÆžVáSº¡Xš÷kÖì¢ÄB׃hšŸIîââbDœ<¥äJâI¿ß_[[ˉozU^«ùiVžå\FÔ]F*QZtÄl¤f‹·&tš¬„Šæ"œho$<xƒæ”R\&ÊšTbh汜'•A.׈6æ¹g �ç’ Ä-3a¬ýä Oãìv°·Û`†ï¶@€Õé©£±Tòљ¨ÉߺD/ºð ¨~<‡‘C"%¿ÈІ¹LZ¸�·B½69•~Œ/C)¨£IPÓÓÓSÿó¡„šQD:6‘ÀV»Ø¥H´‘uÒÀ'8•i<T¬DZÈÖ4æ ¡Ãé-á¤HuµÃÓ‚DSŠTvNеµ5žRP¦ÍÍMÈT0§yªMZ>6k!@’[¬C Ù`lhÇ“ãœðà½Üºu 7ñ'N ƒÁ`€xAd5"LàF7–Ø¥ðòœÓj“‘õ©üz4x`*ZAƒÚø6«|Õv�ìkz“ly›Ž{”‡‹!æÙ»ËeÓTË#bjÛ‚PæJuî±*¢×ÒÒÒ;ÞñŽÅÅÅüã/¼ðÂËÊHNBÎQL'IØÕy%h†Qæ2Z\ìžÜ´ã™g?Ë�󯯆=mAXЀvX‡A¢fac&²ÔGù~Ú¼ôxHºÇ˜l€Ñðº6¨åA9ïU:Ø9ÜË%¤IF'é_—ÎÊÙŸNKÇ“÷¤2—àQ_À‡``q4Ÿ-œE}L¦ŒXÁÁ¬­Ùdà�� �IDAT?Ìj£R$&Á|@ražöo‡ ÁÌJ°Ë'¢p‘ Rgdµ°¿ÜktýšÆgÞ#KÎñÑh”xó /ð´qÇ 3ðk Áº¥¨Œ{l�Á4ªgi�ô’Ë-g!ÑÇBÓ³´'ÕüÁ®Áyà¹ævØ÷ÚƒDqrmHëa-»ïxÖ–¬%žaÀUr,D³ø;ÛÛÛW®\Y\\4Wûh¿&!糞ú ض“ÂsÖ#N쪜®õb‹ðxÈ<@Uî¾XùœàgB3¥ŒõÜŠ6CøÆ¾ÉþTÜsÊÍ2OêÒ(` ëÿgÿ˜ïàá¤zrF$>%v† fšâ˜b¹Ü&}bdö‰s¶‚CŽÃ2�ñ¤¨fâؤàãIOk(:3žÉéOÞJzaüp\¢É"–SÆ º|¨iKyÏÐU†[(”æ/Ñu3û#¯‰3šú ¨Èª“FøùA#k¾…øÇج稾±p@±±`»q²£sHF•‹/ÅiŸ‡ÿ]é¶µ\ð7hÓ6#H7ΩeJ B¸ EÁÝÍZ#¥ä[¹x¦‹ÆoŸ,\h±ù¸Ä®$rø¶%ð?öØcÓÓÓP%©NBÎQ:eÁƒœ=g6¨mƒÄdÄeL¯œÀ²™ŠhÒÑñÀP& à4™!º.¶ëê €Ž†3¥†i<”l Ÿ‰àu¶Ÿ"èr¶â)ÂAÆ–£4±Ö º,6¥NO¤Ž¶3Ý"h¶aòf¥“Òl3êâ—ëA÷¢�ä1^÷ÏJ9E�/Uoì‰ ½…|ºývºCú“÷ÎøºH¥]çšÆýE؆ÄoŽ#AkÞJ“¥!°ý,`I@Ü·V& ¾T“.hHtìô W>‹R%(–=jͰ¥¡ø=Ö͆¥ÏÁu‚à¹õ®7âêâ›ðl§y£âÔôž£ŸÈ±ž‚×/… V>ÛõhN'4¾¬Cñ$äAÈ1Þ’Ü6€9K�ñžâÎâîõzv\/úÄ$§|LóY^Oœ¼0Dì²¾•?”]a)O×1&ää¿“3"ÜË&Ï-ÓІ]]ØÌÓs‘FV-^Ò„0›faa!£6tt‹n±9KI¨-d‰äOÀ»Â؇«GvzÔÃÕ$E0åiÀ î†z¡hÇG'D°2€;=™âD¦«D¶áÞ2h˜§UÆ. o“V»[šé—zÔ*)¶B÷{§)¿€¹€­¬á¿°SÈÕìyƒ¹x&RŒK/f÷Jé–:¹I¡˜Í½*1Ý Ÿ¥î,dÿð—ÉG/+EÁ5”ï›ÛF*ÉÇ»_D 0ᶺ„÷£Ëw[MBÎk6ÚK•Z†™ËÌù縻ʬ?`"ö wätpdì§7k‘ê›lEëpp=ÆÍ™‚dœò«ÛíÑ» d\Ù„1v‚×±­Õ(& ï¢Ã_šCèw1.@Êœ­Òï÷)Ügæ±�ûÄ\™b4Ï'Ýê$›�ñé´ñ- Â«‡¶V´IòGЉqmáÅ“‰}ÏN±H�6á¼beƈ⸠ež�}§B¬²e8‚g2$`Nn6 4çO Qž&N)c¾ë§"‚¹‘ΔOá[2šx�ÜÄq¢;†@< V§Rò³9»í*äÖcÒˆ„¥t4{½^“°\>âd&‰dÑ’!R"Ñ=÷ÂèB‚·yq ´¥tƒÊÝ"5Y.ØRŒ1™ÇIÈù›þr:`åJ–88ðNIêãUM Ýf) +Κpã¾à³Y«w+Øb®‡€ÂÆ5 ¬ëNÆÞ‹í`œÐÛžö’{ût,ùƒôH¸<S`¹r:·´r›€íðL5[:i¯µM­‰ë9V×£†ÎÌqȉќ©±¹k‡ X v�²æE½üUº5\-xKÂm–§3Z �¼ÀYe¹úð5alj{{;•·›=nY'Ÿ€QVbl_ílÉý'8/î÷$­[HñA(Í+ÃPÙõk±Þ€ÞÍ´-© ã´Ð(§XBàÆ¹fF†›ü¥0 -ZS®ã#€Š6{­(|Ÿ9sf{{{ee[ oƒs‡Æ œ¥Eí¹`E‡–”øö‘3õßL„”`íèkÔÔ— ¢UÀd/oŽn¤»¦ö“ý1õÒ4ãi73场óLÙ’ØØ@îl‡5£Hé^‚éyíH—@öêh³‹8V8ɋݭáz,ÅíÃÚÁo4À†pq�4fh¯FO±X–Øê‡}\/º×îƒ]Ôp8n²t4ª£åÐ'2=Éjz$\Ð ³_~7ÅÈgñzÀ2•T×nLÙs7»0ˉT9nQ+Ø ¨XˆÎ+€ìUáBÍf¬X}üâÌäš¶ ï Õ;e;6».Ì+ˆìt€GƒT›››Ýn7²¶ükr »]€4aÜØ«ðìÁǼ€áˆº+Éaâ‹LNPtÍ'!çhær,éa¦€wéa@È$›ýܶ°$qu3 iœ¢:Þ$°Ïâs 4•rÞŽÚãüæˆlBF—+²ˆ¡Ñχ&”Ãbœj\$åéý´Ãšù´‘9)@ rj›øJ¯ÕÄ_sŸ`y£Æ’²xtf²„ƃñt3wᶖ̉kάj.P˜ð üXX%Ÿ’aI{#E‰Ùò£&U <3H–À½0«á1#†-G ̈¢Y”æãy¾Ø¤sË`ÓAD‘½Œ,ªÁ``>±e1‰èžU¢…F ²RM»âÏë”?¥ ¢±è&ùãÕÓ/ëÁŒ•À¬Uá}팢óm„ÀÅ™‰v™¨]__§Ú›7¢—ù r…$‘–Q`©[þÜ•Ö$äe¼á0²f0óvUÊFŠªVóNœ eYvÂð¬�4qaJ&bvVÉ;RŘÀ玙šô Šb¯×KúFÜ¢‹F‹Þ'iQèâˆ!ë$Š´ÃÊ…ý<ÞK§eꊤXP›ÆÆ!bp¦IÅŽ¼ÕÌ7õõÏüä²e½–Я¤'Ÿï'M§›ÑàT£¸ü)\@&Ñ 34d¶´ýs;<@BNx>… äÚà«PKò‰¼bj»2f{üøñw¾ówß}÷'>ñ‰ÇÜ^éöňN“#ÙFÚŽ¬^ãÌ>mQŽ ý:uêÔþþþêêj6,B5œÅ øåØû®Øç¿S“™}ËÑó–¨i/§Rȸ› –•_Ф<%ƒ{Ð/™ðe¼)_›››~û“sdÀp<H €†ô¢°ø˜+ý^gdæ1bmå(³}LÚÍ3¼Ÿžm‘5+>XfQÎç íõzÙ¢^ÙnœÈ˃oÅòÜÆ´+bŒicnäpß›eÐÇi8@œ…œ†9ñ›†ØýüsË0=ÚÉ­õ@Ž2a×–Ïžö6$HX|ÃÃ81Æ»z -ú™4M¹'Þ´ÃÊÖæCçmÍPúvEßÏ2¹ßœ§0r˜ò¡Æ1k¡¸dj¬)`‘ç+y8Vèp­x t¿²"ô@µ A‘e` Œ†M–G¿h²ïtÃ2‡>>~8yüHÀ­{X0¼#»ò<Ù5~G1ò°’ëT‘hÔ"/Bb”lUo»nû½OBÎ3À:XŽœ2aÎ쌒§Ê¶‹-J_í@l$ÚølQtuEl’3°h —þÞÞ^ð:S÷ÌÊc.É’¹¹¹»ï¾{ÿúõë©Ûˆd6÷ÅÏÃÉ&¡Å&¸!.Þ­ $Û˜ˆ¯ï…þ¿*Q)q8#Jaðªœ>à`:!G g™Îò̉¦(i’{ M—,‚À(p0 <ÃK±bntQ€õ|­rëþE  @ü u¦ïsfÝ&ö>øŠ33›¬(OÈ’„õûý?ù“?™][[ƒS–ånJ1pÒ³µµ.íhQ$Y ºR¬­­Ùf­H�°˜ÉB¼·8åsûÎ-‹Ø6B,6j£¾q†]v¬Çãô×\ó‰`ôq³æ×Œo™IÈ9šxãÝÅùÎQÌÁ¦Åg$ ϲK>h<ufùX|?9³Æ1ëôš7‰L–À"Œa™•ZŠƒ %vôÏ2ç&± +ÚdÐÔï4-BD¶uXr@#Še>ޱvDÔðÈÓÃÿžNj*—¹~˜x&º3,Ÿ'ãA¶c)y›2IÄ¢Xàæäª4ÏqÈ+°5i&Ä �`¤$éœ,®¶ùf Ü[櫸E‡›ŒÛÈ^I¿<ôšÙ&‹M4Y(%¡Þ5??ÏOBÌß\YY±z&^QÔ§×è?¯¤+þRÅÙ= >‚ÿ¨¡{2ºÌ@q5ÖZ‡´Tg´1‡CÓA¨*6°>aÊ‘òéîòb¯ÛÈ/®¨(ðð•L”¤¿Hk¦“bðgÓÀ̇b e‚#0=Í7~Qµ1™Õœ]J RãÀœSØßzùz42ÇVÄU·AÜ}ü‰œÅ6_ {ÌG�³$® ÏTJ>"R� AÚÍXCžœϱ?£© o–Þ± 3½b»©’rnoo‡C畈ÜÀYÈ ‡¥n(5¡xÍßäw‚ÌjÉ/Rû:ͽXâ !·@€=éåiæææ ~ì.¤/·s�cá°Á°’ÇDrV"ŠÃbf‘g¸„«Í¦ ß䔯†Ýž‰5)¹Ý`)A“Ø8¤q„ëÇpæ’ZÛ¿ É5)Ò’!¥kE˜ŽýX*Å¢ÚIÀ¶ygv}vq'H‹É2­•g©Pæ\$q’�€OBÎQ~Ao5Œ æ¹íÓAùéôÐÅ% ·î²eC‹4K‡‘( %l]³ã êa—Y ¶z;”F‚ÌÝoÆñ̆"w¢lc6¡7Ii’ÓnñÜ_;¬TOkÔØe%¬5‘qhÈ'vO ¥h†¼Aë”Ð|‡éx‘\¤à«á;Pb–sÙãJ¼ÐȪ&f™ý&§‰ ®™âÉ:=|ñèÌ]4”䈉Wú=hF´Ã†˜EÙÖ¤>&{¸f4&P²`•"Þá0;Ü^…Èëà]Ô§¼V­Çc-8JRwjMª6PÉ~1Íݲr†©é®¹á_j‹ãŸˆ‘‰[Eƒ~žG—Œ°y ¶–dä Ûò.o60F™`„œ#�Ö ¾ÏJµÇ”Q/ÖbQ^2m†bÅ=m†ÇçÀ 9V;v!ÌÊéòBé$pëÞšÓ ¢ÎÇ×�®j¸.l3P&—@¹IýgDg‹-)~À¢2Æ0ø'³g’§'WðUÙïÄžãÆT(ÅþN;<ŸkA³�‰¹#|ešæm ™›<–²ÅÈ}\ÄÃàÒkÌ“¶. *™Ul— ÎÛt#ݪ²…Þâ ¦HP^ØÆÂÐ\¨É™•öˆÙ3-vJt1JÇÔÐËkx'xƒ=Zânží�è±› *àÈj:&4"<ØO”ð0Ò»eX Ó¡C©õyS{ÄÌAìÄ`-n'!ç(IÒS�IÑS±T™ŽÃC“€ãxÏþf R,}Wèîmj· ©§”-cL ÈKÓêô¸>RçˆO{JŸþÍ8< l…I.0Öä¶§V“|¡½³@lœ³sF˜=?ÇdŠ&k#!³³³i•r¿Ó¦É!h\ñé6ìBÐìÿ§·d!N ’(脚áwçl�`­hàóMûô@yÊõ£¸cyVÓ™Šôµo‹8¸Y•÷BãÇR”{xqŒ¾ãC:33³°°@s.‰ùô¾ý g´ôX')¸)=Ûa)6»k§½Á�ž )¦Úa÷[›âØÌIò‡oÊvMù &R{�ÙÀ AÎPŒI,Ësù&tQzVÚÒãM²ë“sdœHqx’€>00šûÖ×3´JUß H8Öäg¬eN5_IúØ x­S=�U¥-OAøÝÝÝÑþhê;¦6¿osãÝûûûÓ§ýʱхÑô괹ݥ²iÒÊ-­¦ì@„„AÙ·ùfÀz|<-Ú˜³5#œ(‰å‚-íLn›óš7Ø$Ð@9e)Ùt¯×ã dœ³ŒÐzˆ» àád=œ:uêþûï¿}ûö¥K—ƒA.u8â[Áp«½´Ýòåˆá¿9§Ü»öt'>J3M:✼ ùMóž†þ Úäigzœ|B ߤôôœ?ôe¸R¼ë°c¼´š,VY`¦)z2ºìb7´Š]m9H:ZeÀ�#{{'û×a°Z¦6l,7ç»=lo‡•¢Œ�‡Cai è�–LLÙ„ŒáѶ“óRÈ1€Î»¤2@šƒ¤z‰GÒ²R3±_?¬Í ÇŒ$³Éø§€C‘ƒ~Éìó¸Â?~Ê¿õFG£ÑÎïì½}¯÷g½“ï9¹³³³sßNÿ§úíb›ÿõùΠZB¦o™, iÏ`æ‹2Èøû¨àžgÇ?\ÙØÆ1Íí°fÉOMèð¨Š!l›Í>Ït:½1�Ïá{VÔÒœ9Ž?þ?ðïz×»ž~úéßþíßþÊW¾BÖïwCÚèknÊk`†þcþ)•˜ûµÃ²ÐFœ@ qs(ö ¾ÍoúïXßõ¦¸ (ËN âê”…3ü+V [XXðÎ2Ç,‘Œ68A×TOVÄ<¸þ¨¿Ó›4k™ hÖù_Ty 2oA2·ÔÆüaÒs6é¼éA;ý%…͘~§õ"óF™s2²: 9G¯^;0›pÃG˜G8Úa‡ ×¶n¶+e‹zy14Y(Á |;ìÖc�0]Ù8†ë —,·0üéáÿÞ³³³™ÎÔÔT÷ÙîÌÏÍÜúŸn;bvæéPoƒHØzškGJk7ªõõu›šP~áÆî7??’½ü|ÙÛé P,¢ÃæQ :@›^XX°ïb´48Umˆâ>SQôAñèôéÓozÓ›^÷º×:uêÑGýÚ×¾f“j¯¤†õ€UÓ~hòZ¶¯ŒEŒz½$1Ç RÝü7`¼…?e™H`¢¼ ¤HÇ% <$ëM€¯ Ed“2æOž‰¡, ®R¢©ÞÖv‚¹`HÓM>Î+Ù)sÞ —²8 !ZíÆôJ ,[˜ÜSÒ>Fè¤8‹ò–[kóóó9vRU›ÀV¼ûÀQ'!ç(ƒ ˺T÷)PΞ={õêÕ š9/z½ž{wLwŽÖ$«C&bö”‹LÐ0hÝY±x> >Ë}Ú0©®_¿žÌÌt†ÿÕðØ??ÖétN:uêÔ©~¿¿²²2–~aiý¯ŸùÏÏ8..È4™<ÑFX…çõÒËq-b©`ó…ÕtÚÈ-iÅ“]º³Èf§Q&ŸÐ|ã0rNÌËë~YUÐÝÝÝÛ·oñ‹_<sæÌÅ‹Ÿ~úé"š‡]ÝV—Èë�<ÉѼµµ…Ô#ö©333ƒÁ ̘…20—¶./ȱl,í‡â-æ>e±ö˜>øB½Æ¨ Bº†áßÇÉE€–AòˆI²tÌçô½ä?Nfë!—ü&ã;æ2.ݤâÑÆ,…’u`uÚü�7›0×™Bßß!û¡CV&æççC§æú×ÖÖh¶YÀÛŠ#ôg›„œCÀšùˆö&‰³žÝs©<)⤆%…²ùoȸ9ãk3''b{8gq'@ÀE:ç®uò¡ùß86¾˜ÜÝ»7÷ÇsgÏžý‘ù‘·¼å-.\øÕ_ýÕ«W¯¶ËmtïÈ”$#cãÃFþ&ú(|z"œ=Tr^¤€�‚ îñrn¦Ý “AEhHˆ�XáÔk5—DßâG`9Ó®¼· úQKeðînݺõ;¿ó;Ÿþô§‡Ãáµk×È0r¶Ò1rÛB.bLWO9õX?ã”Ë,N&+ÁýÛ’1[*-}zöžl :;%%²³r�gä ˆåxt�#–çÔwYæ¯< EÌfUµ² †i�KsFÇÍ|ÑSÕÆ®Áå9˜á¾3¢Ü g®Š|ˆc!ÿT´šà˱ óÓ…²z:Cù_óiq¢sfvå$ä%Iš“šTÈRf7nÜ`­›­¨ *T”I3’ëígš5=L³°èx›åõmkzNÏ0ž­sƒª[®ÍŒX†�N:uâĉååå—Z—m¿ð­­Rô#T³nrš€xp<a½“=@‹« ŠÚ†5ß„ÃmUiç€fîŽ}49±‚é™HÊ#ŸŸO^ìª(éÛ±øÿêêj¶=ˆ™á¾ÒÞ+>’®H€ã,$jv¬Ö`˜ÃfhnÚOºÌôxâÕÞhÜ{J;î¸cww÷úõëYcfj1VìÆIø@‹1 ‘ؤgþxD?DdKù-î‚­TÏðHÅE²x~1üj wþ —±À^RR!`ˆC [Pí°Ë3æî9ùs ¡楠æ`ã#„[[[qÔ…Ë}œClr¾!FsBÔa ËÀ.+ÕS 7¶h,sa®»ÁL,Òì™AªuH)øàP¶«`añ1Aß›œˆDþ%ëÌ­¿ýÆãSŸúÔ•+W.\¸pýúõN§3ü±áòo.Ã.CÀUÛpvXHV±Ý!áã?Úú²§Ûò3¨ðÇç=Cgtl‡‚¡oE†ærÁéBûŸLËK1}ÁDBKt¸›Üq<a3ÆÚª»ÉDߥö²,õ¥gMì±Ô$È{'Åö/²èÜ€S>îïï/..¾á o ›››7nÜðÈWT™(H°ñÙí.šm>Ê3ÅÉÍM¦÷ûuH³ûµ‰˜ïñR€:M4õÏ ¹î'œ—n]6Yª£Å¦Úø9+ÄÜô2žePÔø¤‰þ¦!Jm§T7›Çÿ&!çhâ …(Ì™¹v¯×[XX¸~ý:ÖôôWÈþ<“ßõø›w¸ÍÊ"Æ>'ñæwúl lÉé¼Û¹âÁôg¦·ÿéö`{ðÅ¿þâùóçƒÁÎîN›i[ßµuò8 —¿ÐÊIa1yŸàœÔVzvQdáÝž]\\¼÷Þ{»ÝîSO={¢Èx®`]†äž‰.žXZZºÿþû/_¾|ãÆ Ã˜†;(¡Æ7'á?9âÖ-3@B³Í)§Bµb Œö\�®EuÍŽÔ\<ÐPò ÞBV)ÿJÚ[‹Â‚/q>ÿüó·oßNX¥çaë[¢2.ãV°$]q>ô0 ek²®<äápè¬ËOàTD¦Â2‡Và9Ë\ZùÐÔD³�ÈŸ¶··SyD¬ø.À¦÷ “=0³‰1°ïüA<§) ¤lÈu<~ë)«ÒvµÉÅ$äq/‡.%{ƒ¶$¯†¥Fй)MWæTX‚Èv»ÝùùùÁ`€x¢‰’Nfâ=icùb\æŠÍcf×÷ñ›¿søè°÷p¯3ÕÙ}Õnÿ?îŸü';Ouöö_F`&“ádyôöÇûÆ–KH‰xp¶(„4ªBÈéÓ§?ðœ:uêÃþð“O>N0¶rÌyÅ ŸœeÙrÝn÷ìÙ³7oÞäfggûý>ÅM©„^6;1•™æV>}~~ž!Mæÿq…(¬œõt¹hàÛ6‰Ž—ünÝ7¹„1eRåM²°¹;~ž-°¼¼<7¹£ÒÚØØøÊW¾Â, r®0¡½®Ì(e™iÍV¶EÑUÒ)/3ß a¬ÉiÆ*‚ ÖlU¢²'“òcXÅ$‹2K³°Âõ”4cjÐPy84kñì‡[,>mŠšÕó u+ëû]êMkߌ5P]F Lkvë%ºXö¾%Ùd‹#Fÿln\îÔŒ¼Ì2£‚täw±]w„dÿ [0==½»µ»üÎåö¶6xï µ6óõ™3ï>3???êŒV+ÃEqdiié®»îZYYÉÃÛª?ô¥ ‘)ƒÎ[¬ßï?öØc½^/šóü+3 Ó|ÓŠUæÅ­®®~ò“ŸÌ,K‚Ü=÷Ü377wéÒ%ä}*1jŸÊƒ ÚŠpœ\,vÞf×üHS€È7 Û5~¢Cõ~à¤ÌÐ[¬jÌL•É,o¯ó¨i}å’fP±¶ ¨²"ʹ˜ì庿¿ìرp%ì-íü/§95™5÷èÑ7š›› ô½,(e¹&Ë1@3? ¨Ü$ tE­´+ú¯w@ ó»‰p@mHÕ•®…óEÊÁÌ¥!&b½j.µX NkGüåqK^¹•û½&·Ðn1‚á䈂—¾…Ù)L-Øšâœä¹akd%1å O,b àí°Jѹ?Ÿ›ÿüA3¿³„0Ê" ¸€Cæ!dŸŸ<yr0PµS5;y¸“žiûÑüØÚÚÚg?ûÙn·‹‰¡q•âÇc‰C‡º&ͺœ\\Õæææõë׳9ˆ/cãÂŽ¥½ì±˜ÂÀÎ_³áqž!Ž&eÐį 6V8¶b©{…Íñdån“—b÷0"™wŒ6›gAV„TÍ.M~qð¦Ü¯¶#À¸Þ ÿFš¥óžH“L¢ì s¸Ë<µñƒTNŶÙn#žCrTð¥òé6IßÚ]­ÜlÁc€Q°Z,±Œ"0÷ÊÀ ÔµbÔëéqÉÔIÈù›9Mv¿Iâ<‰°e,¤ŠRHÒ,_ºâ…¢ælË£…ö”,42å%£o® ¸Rz‚q…zËü=Þˆ\™' ‘ô Ú[‘Qà,î÷û_ûÚ×677ÉOI®Qa!S‹Ür¯×ËHçi,ûõ�� �IDAT»ë*´à,ðÎqV†dÝZ@;ø›†?xÎúú:YÎÍñãÀ>¾lv“�5ù,Z<dŸ_$+M¢“,BërZ}‹Š-…<ÛȃWiãIº›UoÀaÜ?÷§ l”5 ôe<5Vl¢*ðjç^¢�Dä(–Ý3§ ™×^¯]êPò‰Ž©Ýá�òꂳoÓ¨…MM cÄšTÔ°—&7rVš Q ÎR[øið;Ü2¤œ¢”a²—ÞÆ~'!çhèæ±p”Ø7—Í–¬3+Û@°É?<‡©ÅXu®Ç'Íi!Ew•fù¦$'sI©8ãªÜž(ø EÄ!“úYèiEäÔ†Ážáf3óL¥eÆA1³}¶Îuò Ù!ƒÁÀ2Y™º÷)/wû±‚ÿ È’#¾0ˆ4ÖD1m$ 'æ'HŠà¦mWüÃ&ÚÑ�ðmk§B1 Õý NU\‡MÉ;µ:=9,–]ÍäÑå¾Òq‚UL†pè 0 SÞA@à![A*X„s: y:Š“åN“ Z' ÊñÌR„ë‰ý¡û -æ£Ù L¹l#-z–ÍXdØtX‰ÊüämeÆÙå Ñ‘¼—áp˜~p“à/\§\pó]"OBÎQ¶s0Åüqnˆ³svÅçfœ£ìr~œàŸÕf½2«Hqº!h]EÅY„RøÁã4ÕrÚžìXX¤e<Í¢nÏzÔsp ½/äæ$réf}ªq6pGùkã˜' ªLY'‚ÀéJsÆh?» *^ö¯$ÃuªÁpŒŸUÓÀ9“&ÓgUÐÚá8¶Æ m�è¼BŹÔʼ KùùÑ•îʼ·Á Y9¯{¼Ëmå'd Ê~)v¥†¬yh~ãô´(Ê›¦³ÝÎäM¥pç NBfõ3 mxΦÀ•,!A7™—Y=µùèÆ¢ù1—òMþܰҙ=ÊCN-ôÂðˆ¦pê&!ç(«´gŠG2¼Oú(&ò{ðÍ4JÓuмä!öxÿ[2 Ä*³ï½ñø¢?Ok¡è]HÌAá=“ìñ:‹“æïGñÚy³ì<Á6póÖ¤FÒóðlDž<wÄdŸ³u2_3ÔÍGô¿I™ /T;Òg:½PàŠœ“Q¦íÒ¼a/"uÉßéø„õ,•±!Sú𨩥l}m] ã„{C[öJo‡ÿ9ÓƒP`¾CÑÝñiË6!»Úé\ͦà._6x»eâT†Ú+á'§íöövV²éï…ëåί’½ïËÚ˼ªŸ¹%-2ÖÆëä QÊÓWæ‚6éWü(šKÉœÖp½]|ŽŒ<‰7,bzq°ŸA«‘å�Ù KïÓÖùE¬ nÐn5}e4eõçƒrxá@êvg±�rêEø€ÈŠgôaww7f”FØ)±lF­ÑA1ù3ö?ðœ×èÈqS³¹ ñÒyÝš……0ËÛ”Ö+Ý{Æ;Š™tQ›fÈ™;.?l K›_CsÈcr”9 Õ$g7þŽF™{¿¬¥’Öø¸I&‘’©kùo–² ¾ƒ?h¼î·Z6.ʧÈ'$˜!Ý”Ó(òŠSa°DsÙÿP4 ](¦·Æ‘òÊš<Ûõõõœ¿KKKѬ[__ N³LÊ` pØŠ¨ãòt.=©fËììì]wÝu÷Ýw#ÿÊ£`@›uk¹ÏäO4o\ BBo÷Áåœ�ØÓÇE1Y˜T9GoHL˜#c,`|1@Á¸O(ò$®µIèŠB"GmséÙEi®šÉÊqëž.¼{l\k£9–,lŠg‘Ÿ)ê#‹‹‹ãk;˜4´ iWö9³hØässRŒ‹“ú(ĨÔúZîåÚÜšD•ÐXNUŸ×¹<Š�*<Ú0{F.šÄ£îúÀܼyó¹çžÃ‡u5rOÊ2ŽKJìYȆÚgÏ]ß‚Ça ídÅ7ÎG'ë/Öœ©ha”˜¹k¼pgŒ§‘‘¿psS%o#½0ŒóS¯@¸hrÈK̳â?øõäpÝnw8"–XˆyPFql3=Œy8î*™öq™›žžþŽïøŽn·û‰O|"#ôÉìcíÁ)ò�*E ÛkšQ-ÊôMÓ£hòŽï…IÈ9ŠZOüHZÍN¬ÅbÝhO –AbˆaIÓÊqcÿÊ|t2;ÂËÅ.p桺“á{ +Žp̺çLáL‡bä³›”ߺE*´Ì'fÿx0…û*Zî%«µh˜}~;t拲ð‰d伿^SÀò9;7‹ìG"JÀ;JÀþú׿ΤQÖ€çuÆ]`\"[XFŒ Z–ß øÂ>²Ä?ŸUü–¤) -úøhËL³æìWFíBï©OZîXë6c»ÎöÛ,#bÉíÏ´,,sE›››HJ[ôo¡-R¥È6þìÉeöÃ$IŸûÜ禦¦ÂÑ·H6ð¦»}¨á1rŽò²âT96$¤ÐLŒ„C.Ò+rޏÊ¿NÐdBÃyŠ+"æåZΙ5wÝÍhb“†näv´[âî-QJ—0ŽÌÚp|J¤tzݽïv»(Lc/èÖGä„‹ ¢U«iÀæÄLE•g QÕ] Kþ�>@I*ªS~&†ÈlÌU´ ik™ B³íÝÜ– }i·ÈÓ“6UÞõíÛ·}TÐÍÀ=Æ;ëÄù…²Å–X6tªrpÛqÙÒ2ReP†¿Vz×´ô02õƒ?èé‹«–Üx ¤|. M3{;1 ‰l9–{¼ZD¥†³ œy8š@˜a_�‹ºhà ç ópÜdžvíÛ••OJQè½itáβÏ'‚„ûHaaC#Ä ¾µºßï'ÜúM”¤~.Ǫ‚@I!Gnoow»]KÔ´‘ ’»¤0e¬T¸&e1(Sô-ìžâªµ§€8LS:ÉöóïšxcpÏ3n½^ïôéÓ+++xу3øâú‹üß¡-T8âì%·4ñã2o£ßt€2Ø„™§ÿ蜗9ÜbdÎn¦)o(² ¶Ã*™pÿðÆÈ`f3g!ñšÈÚ0åñÉ&å‹&‰û¬4“€-­_*1µ‘•4ùãà$ FºLv°¬�Ú üŠí–YÝèüÍ�Ôîü‘EÙo´ŒË´Ãvyí°fþT·Û]ZZÚÜÜŒ)ÉSyVN(y•EDù8W¢¦\ç@�3�ëcÛzŽ‚¾‹Ã•]3НhÚ½d*†4¬ÆmØ?:333ÇOŸ¯Tó“sôUŽÇ’g-¦‘ò–¹Aàï¬!ï1~ÝnŒz´1 +—Øì4ØYœÅÔû޹<ËÎÎΦA’¥ÏÝ‘jY-¿rüøñÍÍÍaÌ y2€ÙÌ……'Jã£ÔÖ³!Lºü÷-Çã¬ÅAqQntÔ½y$挕hÇÅP›ÆÄ»‡Ð=¨ðÜÂÉn‡içà$Í“»ãħ@´ ãëæG™“Rð@^(ojIšp Ð`¢aÿâ1jÙ) Bk)L‡çvØ*"7ˆ 6JÌ<s¡&õRF`ˆä9 ã‰í¬éþèОícÿ1­fI;¹h6¿ 4k†qG>ˆydZˆà®Ù˜Î?²2ëäÏvïN….ÆCˆV(UQ2“$ó3ÙA۱׉yÁÑW9lo²ÐÐöØ`–HÒ÷ñ¬G[dÉ]ƒ5sbù#翌m›HcJR;l±îQvO•“j/ =›››.\È~v“‰.±‡Bh/s×®9J¶´jšD€{'Á÷®C8A?æË {˜h H|ä*òáü ­¦jŠW¶wîˆÓ–rþnÀtÕ 3KL¼NHÒ~ ü⑬befÖ¥q0ª‡yÂVë)É™E/­0ÁI¡¶··á¿¸ˆATJ S€`ÉÜIì5 ºDü¤¹a´3ÍnÈCË^ OcÎŽé-փȋ0­¨©^N�’Zf°¼¶ÝÞsfàe\…½¨²\ƒA¼Œ¹Úñ±¤IÈ92gqˆ(ñ®µq!8ûÜ<}–²é{ãxF̸ ‹¯X–£ØÒ]È^™ÍY“D{L9“Ê‘AÁ=y—í *ÂÉI Ç0¶)ÿ%.Ú‡­_¼;ó�3…G¢Íùåóѧ­£µµJ=ÅÒëuæœ2·‡@q 7ÞYjž3®ßN}ã<fK—¿o~ çQŠó ô6~ÆŒ8™NYˆaÿÃø‡%Ï5„G}ùu*ƒœ¤ùN¸p©#=öhŠG-¨&uO†ðiNQ<"ã&Dö"eææŠŸ­W8kÌõ(YX·˜a‘iBƒ Ï­…jæ‘Ó¿»ÌXaX3�¼n('fHy¡NærŽø‹Æ Šû^‹)i£¼¯É€X“u“gFñâˆ`$Ð~\fÙSS¿lž’,>["dbv{>k\®Í Z©ž15–ÃŽ2È|»ó:«rŸ nÁÉ­8uÌùc«…¹2•¶9ú ºÝ.CænØØJ’‘|¾Î Ø@d !™åá3"ù� V“× ›ÌêË}š&¯‡’X ßÔí !‡@~XuVWB Ç]S­,½aï/‚ŸY”q¬°s i�Ö•çOSUsªZÿMÖvV‚]£à¿ âÑË4KŠ9¦ù×^¯gª4¦ÎLæYxÔ{–Oò0ZPÞ³@Ç#TN¹ë2=çPÞÑýõªƒ×à‰± vÙ/&”{³!¶6©rš©P£ïMÍMíìîÌüÕÌÌÚŒGžžž¾÷Þ{O:õä“O®¬¬”hjvW<¬øÈŒg`0£�ÁYÝn7vdîLIÖ‰ úŒŽ,ƒ#éÐ&äDèdÖ"¡îÜÒ~äPã”14gD*w³ Ôä¡Á¬~F™H¾éý@|J…4™ çÛúÜn¨„`ÚËþÓG!ÆGoÔì)¥ð63 M©&Sœ¤êž²jr¹æåægÊI“è Ä)ÔãSÕ<»<X_œÂÚ`g¥+¿Ï{E ÏÌÛ¡ÀÅD 5gè©n¹†�­9ÇxàN§óå/™5kÉZŽièp¸]„Aý§¥AÀ( Gaµ9§ÉK±¨]~ëôéÓ[[[ý~?[ÏDDPÙRî�b.G=mÿìÂø×Íq‘ëGeŽiVûHïWr¬IÈ9ʳû–ÝöÝ­-·©é©Ñh´ÿÆýÝvgÿ÷Yw5Àî¸ãŽgŸ}Ö¹¼Ës`VkT4¼&¸«á1FÞ<°Æ²³ÞhÚ-é1æ�ìjä²^Íæ RT'c%$t¹$žƒy½î@Øñ+p :ÿ¸<‡Á åC9nž› Íôù›&j)JÚÁÃæŒMs»¶†>çÜÐbžn1îÏ™UtÛaé6_dQº£V๡ÄÊä`"%…½Øš|Ûøt>%¯›Wf`™Ü­x^h!=›8 G^ùd82Y†7Å[ÞÚÚzá…ìk”5üï©@M˜dxÀÆ,-cÚEÌbü¥Xúç°¾¾NHc‰?”IYÀÄl„_-£Ê€­"XNìÍÂŒÍCHô* C;úxeNBÎÑ|í}ç^û¾6wanñ‘ÅÎNg0l¿i{ôM£ö_´¹ÿeiÀô‹/^¾|93!$+¤çÁöŽx—Áë‚AåX¡MJ•S¦;I^¨â]ò|/$ã´lÜ8Øð…»lø;|-çã¡q–¹`·ôµg&œÅÂ$ ÁA’;v›±c™ž°£»n>},reU]ÇÃJVzå£Ï;7ž{î¹q™úgˆSØÀ~Ãü¹y]欧âFENI˜܈ &Ny«œ™Î9K0ÎÐ$GSÜjité«<BðT5ý0ÎG¼d`l¢dhÒD¾yíÚ5Þ©v¼ò).ý¾ˆ ~Å]‰:ÛÛjü‘š® k4O/™Mt p@Ç$Ñîïž‘âÁÒòtÐò|(7sš0܈5L u„ÜIÈi­µ½¶·vzmfsæøŸ¿÷Þ{Ο?ß´?º>þƒag¦ÓÙ=äzÁ|&4�—=ûæÎ¹û(ãD�™ÞpKÓ¿^Ö®WNðñÁf~’ Ù$ÊK4¥eròäÉùùù[·na&ã†'Nܼys8îíí ƒp‹9ùË Q›±VnÄPƒË%ºÐÉÓ††N¼,ð½›.e€±vÐÉb‚Çqؽ~G<ÿ¥¥¥÷¾÷½W¯^ýøÇ?„BÍó•ôz½<±2FjÅ9bRް@ <1Òï2½xâÑç€FÝ�o˜iTr´£òú ç"�Y�ó×7î·[w¼xmØ4ˆ :ä j5‡bÉl!zBåYѦµ ]!2 ÈD*› …«1G&{©Ý=Žm3lZqh Ö†õC]ˆWÄ%Œ$•!1jÝ”Ü褲&-q4 9Gðu¹]þ‰?ù‰3¿væÛ^ÿmøÀ–——?úÑ~âŸX½¸:÷§s£ŸÍýs¦í敃ƒÃÎäâ¿ÙW…•Ú›uàé6RάXW®K“ �aƒœ:kÔÞh% }àœgΜév»¯ýë~øaˆ ùkìöŒÀƒ¢åK$€íCB7Å 2ÀéEy6Û™µ 1IÛḛÞê `¦å·A,éxyl *ÚÆÆÆ'?ùÉ­­-Â!˜éi&¤ù³™.rõCM ·ëÑ‹„ÆLYäììºÔë ™M âøa–"þƒÏm0û³/Ñ<(ÂEż’˜)àT´¹£âµQª¬00Ö;…RÒ0Fz]âT„iICÑÃÿö&@o†-o:cÿ~k\ /‚ØŒ×8ët$/ÔR›öñ´R ²)e2vCôõ€‘Ÿ©ío4 9Gù533sîܹüÁ|Ç;Þ)§žzêÉ'ŸÌ FÓ£b³ÁYÆ{5ÍÆ¢¶E€*–üòȺq{iÐOv—¸ÉpÁ\dkfŒ+/d*³²ÍVWWwvvΟ?Ÿ±g+=‡½Ê‰ïY<c&$¤f‡»ù\”·Ü Kz^LBŠú$r­æI@s~ŒòÓ¸Oæó"ég±£Þßß _úÒ—Ï,ö”ÀbÔ ´"œð(r˜² òó®Sy&¥q²Af£¥¸!ù0ÝÜÅ“¹…¥X${.‡jÆ9™ÙV~teä¹T3Xê1_i€C†[~=í=S`x&ÄË Q»x!éï1Ila=`L“,Ø;Š2V./DPÏí¹³ÂK§ Ã'Z¯}ffæŽ;îxÍk^³µµõ•¯|%ßLTÒÿà XL¤(ÄOBÎQ`k{{è lllܼy³ßïommíîìZ& ˜{}}½P³ìò2SøHÁBú<qâÄúúzŽïâsìža5à)w³Yë\°¶ó\´sUz­V»šŸŸ„>ch¹CUH³š*žø¸!m(ÂJò™hÇìX,¨ ªÃÕÒø1‹¯ŒSÐ*0kˆ,Ø%Ö0týÄÊÈFA|bìéáGg·Ím5F.Œêצ Õz˜^Z\¹Lh;u3ÏùM™–…ÁÁxÛ î®»A‚_'Ï!œÉ FÖb`ƶiĘ ÏÅ(y­ù`è8 ;”&c³“)‹ÆcÙw6Äb6/—è^€\àD„6Xئ–E%b¶ýR ]P±ÑE½÷Þ{¿ç{¾çÒ¥KO=õ”¹E°ZÌrß6º0Q’>ʯW´WüòÛù—~â—æææ¾þõ¯ÿÑýÑÃ?|åÊ•½Wîí¼mgá.¸S’¼žWh+0¾ã€áf -Í3gμë]ïúâ¿ø…/|Áæ¸öà¡@˜aI`tvEþÛ„]Úå_‘ LŽã3¢ÉÓÅ%Wڡȶ‡³ëVvܸÉ:­-m2’{ûð)Lv>èÖ½ÇåMo‡Å<€ <õfolLÐÛì°GW6"0%ÇÚõÖ&ðH \Ucý =öQõXUNaÛÐñ¿L×Ò5DÆ’+À‹•„RwÒ…*Ãÿ¼ˆ T6æP>‚ÑÙŒÀÀ`É3xË´ˆpµñeôz=ÈcÈù$„VmVF»Ò׋´—éQçdgëg·ö¾k¯uÚÜï̵ßjk½ÑX.Ò™fÏCî*”`€[SNR©~0¸<Kg–qˆüd¯×ãïÀog0Ãv<½7nüéŸþéµk×nß¾·“ýX,DÞ5 ‘½IÈù›þšnÓgÖÎl.l>v×c—¾ô¯ÿß}ùòå­×oÍ<8³ÿµý•f5Ü2†NG4T0zòΑ7nüáþáúú:ÒLEjÓÁÌyÞ3NT¹†ÍÍÍðJ_‡=ŸCc“L f.¬GèA‡fÍ—ù“jÀ Q…²14ouÙcÎËøPúáíðø-ÒU®ð÷ËØñ`nnî¯xÅÝwßýå/Ùf‘fšQ d1ØöŠxã2ˆ1?™^TQ€h`Ÿb!:ç?~îܹ•••«W¯f%ÐW·„ã#i2A™åû”•d÷ˆ¿1Ø\cU´ñgX@ª„G¬·”pbg;û.£Ï_f<݉ìt:[{[;ÿÑÎþ¿¿?÷‹s³??Ûét¶ß·=øåÁÔ‡§ºÜeò†µÚ4\Ü]AÈŠèô8¿±)CQ·¼7ù¯¦¸ÂãÒdMOf–ùÅL¼17ÆÙ²¿¿åÊ•«W¯"—5Ÿ7ÁµŒ'!omrZkmæÑ™¿{ã×Þükw½ëÖßÚÜÜœšÚ¾¾=ýKÓÓsÓŽÌ—µe*“y,…xÝÆk—.]ò€?e"YÌ ѽ€(iÃAÓÀ¾@á ×à4\ü@=wÆÖÂs>ÑÂö9Ž_Ö-‚làËEÝ®ˆ Á>g‡Ø=…GÊ©´¹¹éf1º2â`û;ºëÞ‡v¬ŒizBaâQó•&“MÀˆ¬ÍÉ›¯åååõõuØÒê8uêÔý÷ßÿøã_½zÕ6zÝn×°RÚ´¾i<pn:!(š@Öà~óšî¼óÎÅÅÅk×®Á†p@Ûc¼%iy�7»$ØÂÇS8L™X?©³ÜÙ{ÏÞ±÷Ûßߟ™ÙÝÝm¿ÙºÿOwøéáÔ'^šÒõäV¡«1œk*ë‡y²rp›éØÅ>uo’ê–©U[1Œ²™–[ZZ ©\ÍÍ{)c›I ÃNIz&êß�QçßÌÌü›™Õw®¶™6;šùÂÌÞõ½6ûR‹…ÌÝ…¡¦|Y·Û…žï>$IòÖ€*æ«D…`JJ04Q›ÙTEž’xI¾†¸²õ’A¢éÇZä¦C¸¤ú!ýϵ¥qE€)2þFÀàƒZ ÁG­¹ý4ó rüî£ë Ôâ å3®_¿~íÚ5 葤ƒO2îcœï%]Ô<y;ä&έí*`c÷¿[·n?þÚµkŽÖRìšÌ§d㥻1éá$KGC‘B+º×ë½ño|ík_û[¿õ[_ÿú×í³@=šgs©"ŸJA`—?»·<pͺÝüùÍùÿn¾Óé,//Ÿ>}úÆ7oÞÜßߟùg3›ÿåæÜ?I¡I-ÿ4w^Í\'8†£¸QL†lU^Äý<vŠË²1ïÉ>O/åe8qbyy9#D\Œ‘ð<Ò'N dJzQFôe‹Ñ$ä}àEÿ®‡g¦ÚTgÿ%½)2P— ´‘ZñieeN3îà\ÆóhÔYUá¡B&»Áù†t*¶…)Aì^P{´¡¹&aæn·‹¹“C]ç‰æ­æ¬'?yö[Ýn%ì NüqÊo;¬eh;€‹â�(ÖGO®3ßgpÈÑcù…qÎr¢ÏA¶›£Ÿ¿æ®»ŸÕÆÆ†‡…ÛÕÍöööÆÆFìG‘ €jEˆel:˲V)æòóƒÁÀ~NŒï|õ«_½víÚõë×ó¿pî�Ö§bÎß³ ŒÇ›ãa2ªE1Tt÷Þ¸7÷ósgÏžý¡ú¡oÿöoÿÔ§>õð+++û±¿óŸì̵9¿ "Ÿ½_Ûá!ÐèQAÈä R©˜DG0³ÜÙ¡5RAæ=Nkê õ4䑤S)v‹.ªÍG à%ç[ZZj­E1‹^i¯×˺¾I•sÄ_®C9 ²©Üð@1Éä"³6 ¾öÔ"ä¸l²K<;“@BÓ/ÿÝÇ\;Ѐ2þ㌛‡n‡' 4s‡<âÖ=K3 rU|º}6y&p3 @ü+MQ`n‹µ¥GíÌwò¬¼RºY4ÚÔÕ ¹Ì%;Ñü@ã„2fb í°lL~˜Sž²ÌÞ6ò¡öm¢v;poFý~Ÿ¢ÄÕ j`e"’‹éÎÊ=æs…E·˜—çvñâŧŸ~š(’;ŠÌ—)[Yfy,¾Âb½Úëõ4™äi8¶t;ð±u DëìÙ³¯ýëï¿ÿþË—//..®¯¯ïÏìïv^’¥±ó¡Ã¼m¨Ž…Í»cÆ œ¶IÇÝÅ+í1÷:Pf¹™×Z[XX ïÉscVl™b1¾½aô4éêæ\¿~½l(4¹ÛË9¨NB·ÒjÃJn-Àø ?غNÊL3E”¾s¬ FG³cCõ±ÿ§(­•ލm~@ç^r^[•‹CÜ-kÃ5¶‹&—:Ll¹ì WTô{¢p¤�� �IDATlœÓ¹ÝEõÃæçĤÊÉ>ÄkŽ=F8Å:0ÑÖ(9ó:LGòG8ˆ4ü&¤Á4<8q\½¹…`œÓ’¯^c`Pv“ã¥ÀþâÚø @XiMÔÊO2É]­I' + öÌŽ![B‚Ì-Wö¶ÕÈ£Á"û±cÇ666†Ãa“-¡µé)ÙGYQy¼Dn²¨Ñh4õ¯¦ú?Ü¿øðŇ~ø‰'žxôÑGoÞ¼¹···ûîNÿßÓÀÚXð±ðÜMlsÓ³³³KKKá€Ñý²Ù6íLû¢’ÐØ¤ªi>´xŒº¦¡²¼ãŽ;ƒZ“,wÓt0æ½™ v‚¥ƒ¶*ÄîIÈ9²/ú-,VT`3R#ÅÒHƒ¥nq»Ð¦XqoÓ3dЗ¶ßhþÍ4ºde~ˆ™8[ü²ÃëgøSœP™·`'pkžj‡¥Ï(>¸S8€­¡!õásÓ”Œ‘fð˜d©V‹w¯aýÜ;ŠÔœïÜuQÓ)ž%EªÒp¿©"Ä3(y©ýºíçmg»>5¸MhüµÝÝݰM‡ÜïØYüoÜÒðHG;PLð©GY@éàÖ©[Þ±cÇzè¡gŸ}öÂ… żyÜÓ9õAÓ�o³ÒGöw>²³þÛëŸüä'?÷¹ÏeÐmoooû‡·ß¶85=層ð²gS]QJæ5ݾ};7 ASím>ÌÕ†IŒ…¬ìåYŸO„§cCŬ±0çš9jbUÀÓ¦±Ê ¥jš7ëurŽàËô0Öz˜çEЦ”A&¿[C“—²ÚÙVº¡ƒ´°€ 3ùJÀ—¼KÉhLl+5;!IÂ鑎Áp%¹æˆäA!oÌ„MIÍì½ÃŽù!MhDeÿ‡ œs—l¼ ï9—§ä3…YBO¡¾,Ùâ‘áQ›ü–‰PëÇÎ:¶Ïò³rˆM¶nv–6AuÊܨ¬sa!¶Q›úi ®\l JÍMœ ;æé{“”Xÿß .M¸ÔˆaNnoo_¸p!ý!ƒÏ áþB"BCÙä*Ÿ2zn0×~¥­>²ºù/7§¿0½»¼»ÿŸíï¼gé§–Fû#œG˜³ìÐa¢Gæ§¶Åb”fR‚+óF(ÓË&ÆHÊE(nëgΜY]]õÌi>Ñ…¸‡LÙV™Ø³».å¯' ­#^ÐÝIÈ9`͵ˆ©½®¬b”þ^!™!æÍ¡à> ˜Ó fs²9_<ö|,¹sÆëìXœšÆò±œ,))ì›â– Çí¥|zæ×¦¦¦¢PÛc”kýeNÎqî—™ø~vhóblþ·­ÛÐA@Ÿ ›Q{Î}k(ÀdõýÚ* Ä´+òA$˜ÅŸ&Ÿ×j.7™Ç§7R°µ§~âç-O×4…jÕ¥¬:hß=æôS|´Ãvœ¹þk\0%'ÆÚés¦¬X´ùùPvwwQÙ ³Áà€?îDÍcašØ_Yosss£?MÿñôÖÏlm¿»µÖý½nïû{”ìTêî/Zì2`ˆ. š¡ Ò’'Š ¦ È™Œ-±°S“=U¼µÌM/ÊWÒ då ÒÎ#…3 ¦b……&M IÈ9úZºm‘:vS€ÂX™O[kjA÷twš3Ë 3h™ØÐÚwV=Iû=cñà’±„%ýŒ2óou€„™qßu¸¡9ý³²ñió(’\VòOÐí!0^jÂw“‰‰a9ÊÀž®9;È,@‡ß’ÀùOPê,*8–á0‚ŸÈga äRÌ…3Gôìr^äu#äê±›ÂÌ´­ÄM{³!ì=cÕQ$*ˆC™K5ÁÚu Ža®ºXÀ©¶MOÏ/†göææfÅxóÿrþ%2áþ‹äÀ¢¯lr‡õv ¢ˆKö’N‘»”9YC‹¥ÕÊò ìe 7ýÑÒÌõ<ÿüóE‰ÊÀciµ/@œÉ±Î¢ À”ÄzrŽX³®«k ›5®)Ëi^œ\èdYÐÚåìó”�Mš~ÆÓ<uOvi§B®ĭjea¨&sÌC‹cfVY³ ËЇ(ÊQ…ZÊxQÐb£í°ÚU;0ª(Œ&?¨vØêÍŒ>ÊV׎ÜÌ@~ û‘§q•ëÉ‘†n½ðœŒnðŽ+EU³†›µaÊki^n}îŽ;ÂUH–ß5kÃ-"–S‹\O^ >•Vûn²g¥t¦éè@î9nOÎÁ]H:fR±>Mú Íá¯1 ¼Ü‹­ªæçç““eÍÏÏŸ:ujcccuu•M‡btví¯x‰ôIIaTƒ§y°ÉCknæ/oooã;•û¾”ç‹ÉÏ@wyA”¤äµ&ÑF hò^ê-‹qLBΑEOÃrraˆC;_­µ »áliýâ²ekEŽ`SÀ‹­¨ï±ör¢¹scÓOÛ {EºTi{¸)’z«×ë-,,$à ~•çÖ»ãx6)üZ÷“Û·®‡ll]„Oò¯d”LùÅÚ©ðz0+º¬¶´ùæb$ou:É8ý ¿_—A– À)î)hm¹±Üd4—~rÖ ¨yÆfe–Ò§Ô¯^ö– Ì ÷!kƒfƒÙü>a ʹ҂ßL­iP—2ë&BBaU˜Üh¡L_9Zv½^offæØ±c¯~õ«/]ºtëÖ­BûdVÿÅåžÎôk§×þÉZ§uZk½ïí¯í·›„Òö¬¬|.�£+W˜®îæ:ȱØh,a,½°°Àå¹{dßtÄ,æççK‹¬Ê“^Î7D•ʬ÷)ÏLÞ-D0 Ž6ŠnZˆu4±Ø§¶×(jĤ9£¥L±ŽYÖe‘ 1'ùr@ÿ&-œ2VI&nâÍh4ºóÎ;———/]º4Qâ*½+ÇRf[LÒ"zq÷@\é¢�ÄÑ_`kâ´…X€_R¢Ñâ9“ÒR†rÜ›âQeüú@BÔµBOQ©°•@ „¥ELvl ÎìÒ§×%rÖóH[kÃáµ]`ºÄn‡¹WpB¨‰~éNòxÂÅs“ŠÓR›èϺ\�jvsÔ°R:ƒ-bÏ:»È¬­­ýõ_ÿõææ&ï—š;·ð¢”êCÛ»ÚÙ˜9þïÏK\ýµÕÙK³óÿÇüÞ…—Œï°ƒ7 Ê½›\NìdH‹‚‰¹oô¼%X„06›ìí’—¨ïîï–Éñ$äÙ—»n9¶ÃR€œòãc›Æ¹àéëüÔÃíVô2¢‚_ö*°8ö¶Š%÷7½ß8,Ê +J‚Æñš¤ŸØ*¶ØÚÛÛ»téÒ}÷ÝÓŽ§Ÿ~z}}Ýyœ‡„ÌUã°ìŠçW¬1ÌyÁ'¯&A…8Ô$ßY¬!Ý@F™;IÁô‹5—פm ³âx¶76¦¥°°ô'–‘TÉîÞåu[1–ÞCæK¬çVè‘, Ïáš](ȼS/Kþ¿^øœ©uÈ!¡Ký9‚•†Qž%Ë<³‚ca>%aÒ]‡di$ì?hRDuYI8fe&šê‡(woö#³K/¾ëtP¸¹¿3×~ªí|ßÎô…—ú¬ÅŠÉX®ÉA†4­xÞË3÷ ¢HeFÛž¤ö†w6ã‰.’ƒvX£Öí´#G™›&Iàœ9ÈNñqCIáuÓäùj£L†ÉOq¿pÈa´…cˆ&е`ÃRãpA?£ ï.ò‰®¦Ýf„XìØPæûrÞ›‡ÃáÓO?ýì³Ï¶Ö–––Š%x‘Åò´s .Û&z~¸|àr©¢ú!¨˜¶7Ûs§ìç<í| â’&Í{¶Ã£|.(UË܆{`Ì'!HãÇW}IÜ ³ÈÞ0Þ˜¸ëZÜ Šy–*¯»#Ï´%˜mnn†É *CWãÀ/›…$ŸŒ†£aCË¡—×5:ìGPÙ,÷ùScm½m«=Óº_ï>ôÐCüàßýîwŸ;wn~~~öáÙÑ£ýWï3Εçl9Z~9â]¬—©dC⮌ÉufggCáñݱ4 žfo$+_ÐpÐŽXCdóþûïßÞÞ~æ™gÀ‹r0Ñí°_¡½ÿšÌhùŽOÌÂx&<C÷”\iz»£ØÊ'1@E)ÒUëøæ”Ì_‹”E•“>$Î,ùœ„ñÊ•+×®]3#+GÏ“jP)[†ù’ŽA`M[>G=|Ï£ þX\‚(ÝBË“†no:KP;²Ü R7ž-®nIÆq+ºÅÂW%¼6xk„|sÍ­ºõ‹Ú]"«‘†:ïúÆö0¹ž¢Ýâ3”øÁp.,,Wx¥¡Š«P¨î.PèÓÄêv»Ä†&&„� ¼òfÓn<vìX¿ß¿}û6$C |œ¬ùìië¯ØÞš>9uòGôGßö¶·¥‚ÿ½ßû½í•íÝ“»åŽ¥E½Œ­˜Dl¯B7ißÂ\pD„Xä1[u² Üœö!ìDt1¿À%ï$äe/§µvîܹ~ðƒÃáð7ó7/_¾Ìô�c"d‚èp°¥›ÌÕ¶eø+›ßÆ´´‘ÝŽCð•}Âö‚ }Íft¨Æýz‹-t!;yhƒ/ëÞBè xž¹{̰µ˜ÐôXá< N”&Æ]Ò;÷G^Áò‘ü�2ɦ?$÷71Ýh`beF žò”¶%£‹Kž˜ÿÛö*í°? •YI…ÿí{ôZé3»®`f-A ÈÍ&Ôæ®É~«5öåc w³üÊÜB·¦ÛE´î{½^¯×‹Ü€ h >FÖ"*8=== ,÷ç0@KæEŒ«½E¬¬¬¼ð «««/¼ðBt1F£QÛkÓmÚ°¡)yîK%*³0Š4'oÖ†õòæ}™KbS(ª61…ØIÈ9z`mwwwmmíÏþìÏâEíÉprj†X*Êž]&­Ù,êmÑ2)x´¬íÍ칸dšèlIù&+9³Î¬LJnN3³XZEIÐ[š®‰û4&tyr(“€(èXÌÇã´hü4éL›ºf–9÷XfbxtL5q“…s1hrB²±û&=S¦z‹°Y€xxo›¶dH3eÀ á W½@(¼w»,×XáÍDG+ia•^º3n3ø-¿ŸÏ…;WŒS‰=íÀxͶ.õˆj%;3#Â-,,|ë·~ëw~çw~õ«_ýìg?‹k±½ÙÚÚZ[[ët:½^­‡¦ië¶­­­´N)ò:ÑÙyÏÎêñÕßýÝß=þüÚÚÚ_þå_nmmm¿a»=Ûfo̦au5h®½^åas&Ò…Ò_ää¡F ”ê"HšëfúIžó»³ÄµÿÎ$äq¡³¿¿óæÍGy$ Ñ„tDÆõÇÈ49žÜl'@°Ï;ͺÎ9J@?œÅPF`I«™l´hÅÛF°Ie$óÓÓÓ'NœÈr§DK5–]”#2¶`kkkƒÁ D¨n›ù ¯é<@>ˆà ørî|â±µµÅwê0[Ó ,})'’Nùó<“¢šÎç]ZYA7õÜó+ŒZ0Æô®µD¡•Ò„l œP‰666èÕQzrxÑ/ôZ*¢´EÈ+ÀÑÿÇÞ›Ùš^Õ™_ž“Ãs¸y§RUݲd I%ävd 4в,»  &ÆѦ1F¸=A[ÑØÑn0 ¡ÀÆMG;ÂØDXm0HÙ–ÔÈjIFR•D¡RªéÖ­¬;åœgÈ3döuó©'ß#úg§~dþP\e<ç;ß÷¾ïÞ{íµ×òÈ0‡ ±¡+ÞLj17ˆq½^ )&ÈÁ R#r߬*ÁÁ §5\Lá °ººú–·¼åÝï~÷<ð¥/}éÎ;>Á!Ý%xÇ‹!ßݼ ÊôÀwd$£Ñ¨z¬ªþRutõèÉÏ?yãÆ˜²×jµ£7Íßžoí·Æ cžˆÉG•¼Õ‹QKóÁ?‚ˆ_ÌÓüU'ƃ°K˜}¦³[ Á¯(§Ü0&i89güC,ÙßßGCž’%ã…‚K 7ýÜð0¾– ãô®²éñäh0%bÒüü|»Ý^ZZ:88à¸7PK5 z6XÆ1$é|ððððàà ³,ãñQtzUUmnn¦%Ón·çææÂ²-ù•••………Lzf|ªÕjÙ‚âÚk9‘9ÔLB%šÉÊ=@pÜ4ú:œüÆù Ä?d˜á>¸Ã2þi¯DŽf+p«Nû,Ø6baaammí[¾å[úý~D*¡-Ñ*ÚøäæP%íHäºÙ-:Vï,’› ƒß¨²GŒ©Ìät?Ò¾†ˆÁŽ¸ÃŽ=(œ“ò•wvv¾ð…/,,,<úè£qs¨NKrx~“ [pOâAB¹AÈ{ZVÿóÂàçÃŽ?pO›|ò/' ÿa¡þë½QÏ °øhdšþ`«P›Ê3‘V -ÑRZZZB؆ëÏ~!†Ñ/d³³rë¨ê|Û󇜳,q ì�7qú4›M[:G°~†[ú)íÉmg[çä(á´µ: bš´Þüæ7¿þõ¯ÿô§?ýØcU§-n˜g—FF@ –Ý7R.î;`wîKÍÏÏ¿üå/ÇO<ñ„Ù8É‘×××WVV2xO%´x¼ƒ>G**RQº5…Å/ažt¾È•Ã-6 ó°:mˆ—ÀÌv6 ÍÁ«…¾ƒ_€Hš…ë¹Û@ˆ'‹_ÜVdÙ.]ºôðÃïííýÎïü'8’�A9€#¡Ï&Ò£•çê‡AZNyŠ�ò•‚éêÃR£^d/ä+8›É/áqß<vSì8„PÑ<­4™k@¯�ƒÁ£>úå/yww7˜­©•Å&b†×,ê”UU…PÇây©a9­·~°5}`zø÷«ãj2t¿½Ë€0xrvwÖ#nT*Yç…²"K Â3s™§ÉoòÜsìXóZ ‘‡Â•ëq"ëß›¥rrΦı†¹%­¸#;€„Cƒ:¿ô»Y˜6K‡L‡¹tŽNhÐ…D4& f.\¸ÿþû/^¼è¢t»Õk¦KåƒB`µçJ5£`'ÁãããÛ·oÃn •Ëytç΀ožóOs~VÙÞœi~~hCåbøÉâ»i›æPÉ3Í yK51/g:ßÑrX~îÂtø‹¶–g€ø:TÌÝnw{{ûßý»7 z½”h> MLÈN•ôîøv¤Û2RqB;,§ T”O‰èè{L_>Ô’–“(~é½6« ƒÈB%­U‰ÍySæÂˆ©¤ 6-ts=C›9Y3Þ5GGGõõÎtà§µiáSnKÐbˆ +²ÐLË*uu¤Z,æFf+Qè‡ìÀr*h Œ®›öVL(ûQž‡œ³läøá‘¢ Ć:ži·ùMžkˆq.)L‹‹!8[¬W+?÷¹Ï}õ«_½}ûv�tê¦n;°¦Ï|ƒô×Çï>¨ªjþ×ç—þé’Qx¬™Æg<âîÝ»>§ø¾GGG½^ooo/¸œÅ.] øOðG(¦# C<\ìUmƒVC4ÈŽåNz:2'ÝûB¡™ƒ‰f/¬tʘ‰WXp Ã b@‡N%wÕªŽívûU¯zÕîîî3Ï<CwÍœ{9n™Œ ÉÅ’õÙÁ‘\Z¡0 æÆÑFnNm: ûêĝӿ nÉ ¨TØyX‰€|ÎsB&m’´ájhÜbÀ…GÏlUN˜b`¯<¾i¡At'~¯¬¬,--õz½^¯†æ¹*oÞ®àG6)ƒù 7<‹Ø“×Ó©ÉhÁ f‘ÿós–…Næ.9ú-²ÈlbÁá„âQ/AX’T-7‘$Îk„:ÏßdÝolllnn†ô OŸ®’_¦çÌ…½4êøžª÷ã½ÆÝ?Û=<<¿w|ð‰ƒæšKŸ\bé# j㜰ÌÑM:G^ìyRHVrÒñïbP”IÊ#z ¨ï˜|‘ÖTžÈ¥K—öööŒƒU’áQÖ«ýa”Ͳ€lA„Ë‹i#Ì0™[aG�c}‡‡‡_ùÊWBšàm‹¢­kŽH˜„6>o˜ /.·ˆA×D èûPïÈ„`6SÁ0,,M�æ8vÄ“µcfÎÁÜdbsÑ]w]μ úÍô™¢'ÆË´®=Å=®*¨X‘G"xêž @b¥¡Ý lßñßÑív?ò‘Їã"m2TpXr+@P@G“Ô¹ÙÚ.ÚŒßÚ¨¨#)|¥¢Ð?9göCÓÒö\ÉMŠÆOuzøyVa³˜Ùv«â° !¹*Öœ"øoEn0mÖ¤‡ký½Qëm­f³¹¸¸X;ªÕ?T¯ÿj}ÿãû ïXð®öPoî‘L0q.‰ûà„˾z½æûÜ›ÐBÎ oÆ%Œ£×d|¹“ûûûk5pç'âr“ \Øœ$Kàv5c8ËãGqpÔt¹V8S€}ÙÈÕ./„Š£)>üĉ ¦ÀÚ{&“’¼xqq1ZÅ…úQ1ñ^ظ€$;¢è8³A€¬˜ø 9¥ð”>É8½Øf”¸ê‚ûîò¨ûCl”5€MN%¢éȺJGkÄBpܜǼV«íìì8>ÑcÒ™É'óA"am6›/^ÜØØ€B ŒoÖ¾ qæmšå¢m~~>Ùáž´ç!çÞK0|JÈH‘¤Çhf”Q`ÓI‹3«X¤uÞÒégrÚZÊТ¶<0wè¿B;VU5ü† \XZZzà.]ºôüóÏollÍÿüüð†KÿlɃ“žüÈÑ�Úh5¥ É—½óJœØЫÍGfk|Œ²mìû`â©K“©Ž÷÷÷ïóŠA‰YÝŽ0ì/quP1ÁÔÓ©ýÌÃó^ÅQ°Úh qKmd D^ê9T` ©±ÒÌÐ…òž'ë¨ézÔA¥ ¼Ñžá4dýSLX¼• Ï%Ÿ¨³·^·Xiœ¶4> PIxÚ¬¸á0E+  ‹¶EVažÿ›‚2创¤A£Ñèé§ŸŽïƒ­1dX*Ü¢€„nó¬ƒÁÞÞÉ™'œ<aÌ[]ŒÓºéëÝzrÎøÇViæÆ° A0Ꭵ20Yø y´œSPÔ|ü»Ãa×yõW§§Ž=»ç^=:Z/áuÿýdå]+<øÀw÷wÿÑ?úG?ñ‰O|èCº{÷nó×›½ßkÿ‹¶ŸÕi“4¶P%¹¹ê´G�é›_ìœ6kgÀ´‹âÑX‘ÌVX¨yJ8æ´õ¦<Ñí¾]%½E“­›Í&^ E©d ‚%‡¶­)ž�CL­&O÷}€<’%*mŠLyÁº‚lFkÐêÜI¸HWŠ\› 5»®ö ¹A˜„ÄE}™}aÕ‰€?¦&ÚÄEd^Ñ#“³Üg°GMö˜‡½Éd’§¸bVm8š^ã¬Ú!ÅV®ªèÚº:¤¤óÜ´/Œ×ã+8÷öö<hEm\'è”ZxküWŸuç!çÌèÕi…] ÙKÑ2Úà'¨µYÍÆåáy_@¥86%GUÚC?V‚±ß"uR?í–——ßô¦7½ë]ïzàjµÚc=Öï÷'õI¯ê™×àq ÛÉ$ô§³û:áÂq0¥%ëÜ™!å´PwpŒÕqŽÆQXØÁÙÇÉr%Ÿ±YìÈ•(ÜVòßÙbÂcUd!ÜÍÏÏ Ñ#[=Ï×é|ˆÎ³Pmft¨K(¼`ÕS‡™óæüN54Ù<Áêôx<e"¡=U—E¾©‡ÜÙ†¸‘Ó0·"¦ÝFð²¼¹iÈàÀ”CeoŒ¡Ð¦sÖbe)»|æ;2•Þ'FŸEmê¾#‡x¡ø`ñ7>Å<h)”€èÒKdª×ëív{qqñöíÛØX¼Î#küW¶9 K”q `a Må¿’Jž÷r¾.ær6H¾ˆ"niN1™y.ÔP¬éd¨K(ÿæªÚda|rLË® cÙe 7uÀh4šûðÜÖ[¶¾ò•¯|îsŸÛÚÚúô§?}ýúõÉdÒ{{oî?Ü›xG΋™O8£§ž0o`ÆM*Ys&™e'˜_G¥°G#ŠgÂ)žÙŸdÙœ ® Ü•!E ›&)¦¹ œ•KÂBØm9Zß ô¥Ég+ù�URs›¬„šôù ÷I{ªR˜’ºú_Íž¤s²á©x†D'ÔòqÖ¢�<e M&= ÀÃV²WiÑšm Ùq¹Ã¨Ú%ø®`1¸äboæû¢‚Á08å¬I†(à Â27ýâh¨h“æ7ÄZL”øV³ÍµÅ-;aßÈÄ8Ó4ù¨ÃÎoÎX3á=– !óðÀª“°”Ø´.é¯ðÒðÂ…´'§žÅ§í¡RŒ‚g±ÒüÌ¿1Ld5;pz§ñ£Æ?jô»ÿÔŸ|ê_ÿ뽺ºúÜsÏݾ}{2™ ß?l¾µYÕNõØÌ¤Ô+:†¿Â²úµÑ'˜Å\mÑ+: È$}cÛ"€hkWoÏN¹$Ê— ïÈVßF9 ãzœÞàŒioÀ)> †’[ý,�»žXT;@œOg‚ ‡T«Â‚'BsÈóÿžyœ•˜¬$ÊÉŒ=·¨H³Ü&´Èz1FmaiFY+ÉM2’bÍ< ‹ƒÙEÉ1 d¬p`*f€øšÝ¼D‰š s á9Ê)Où Kò¸+ÆÂì=>>f‚ Ä´f+ñÅ�A>™¶±nž•ŠÌí»š3�� �IDAT€˜“=Ö¾.ªÐICHUüä¬]~°Ù2ìI@–”ý]àe] þpDâÆQI¼òßšL;»odhøžõËÏ.Þù÷wt>ÖÙÙÙ9ú®£Ñ_5º‰Ð!ëÛó}¯!“ÎõƒbçîY À–·‚tfÊ7òþœ 9 ÖpîP;º] ¬`‚–r‡i;k]{¨ÓûÓq�†¦œ!”Be`Ÿ¢!ŸÓ<ÇzÎ_ž¯#µêd¨– »ª$Bá$�Y³x0£ÅÀ:´Í]‘3AŒ,&Ï`m¡”Úh4|búžXRÏÓ342=EC+}P$ž(°l³¹LeZaŒ³¸:íÿMX¥ÜLt‡.è”ÅU#ž¡˜9ÔS§/fHÎîÚ#ÏÆÞ‹™–zˆà·8kd ¥FûÎÝ,öȹ’ôÙÿØFÐ'vó-„ÔîqÀ†Cœê9‹é£8á*&Ú´<ÁàaÌJÙv0™Íóžì³ìpÀ¼·þ¯Zë7Z‡?zxð7ަG7VÿÌêx0�´¬S¬ÄÂLŽ›\OˆiKXd p·$À$ƒNWZZÞ?âW—á%ã§v»·‰�³Ÿd¯xÅ+Þð†7<ñÄ=ö¼�"“}_`XÑ4²Pw\W�n§‘›ð._”Qyä‹C—‚…4Ä n гà-“É$løË—/?üðßûÜçnݺÅvü3#Ÿ‹{£0Âg “î& §dd^‹éOðôy@•<“òCÚ$ÏHÆCÛ•OÂíñœ¿@µéj°=!T(—Ó‰!YáQžiXZZ¢Ê!ã 4’M› l{!Ö 3y,BïkÖ¹•ãó5‘¶"_1ÈLD´S Ùyçç!çì  jÁÕ‰–~“_lIDc²lëÀQ„A3êOTd©‘F9"Ú×9gz 2z*€äždĸ±ÍÍÍMŽ?ÕhÿL»×ë5š£ê¨:®rþ2üHÐe�;Øl(Jø( £MgÄÃÞ_&5اdzÓ$˜dÓ>°hV[Ÿßc ¸P7/çÝÚíö+_ùÊ›7oš;ë} ?ÐùµI\�Y¤®6 ¨$/THq÷ŠtÛ>°nÑçq·Ûí¢I…jÛî–´šÒYŒùw’j˜RÏp>Àr¦s’ÚP£0‹‚BVöètxxxˆ–‡s8ûTZ;�¼ÎÜ9b†§n]@&,šç”#ÌWrPôC%ÝÓ2³2c3o+UÇ’jV8Gà P½éHaEh¶… œn;q' ƒ—¼¦®¹¶³Üß9°vÆ?NTÍa‡ÝÁyTp œ\�@þÄ@7–×uOØÔ ˺pÆ!–;ø>äºlû¼{ÃA­{»¸+ëþ§‹³JãµZm0Ð<É{¾2é¼¹m†›8A 2C¯b2´Ða£–ò v%–lKÆ Á¢¹¹¹‰P±n DàB7ªÂÃm! çVwíRlÔž´”G‰wœ xÕɰªa7rdN_<Ë{gg'Ö–6ÂIÎni;?zÜŽQrQ×-¶µŠžÖwuÚ£ÓÀ²i“vI@¡À*gœéyen¢/<ÆH‘~ =ㆊû—¼¦`Íp ¬æIäð �ƒ å\؆CTÁ`4…Õg½Ðfóô~P©´ÎçrÎþ'�½O:ðY=Ì[¶°ÈhŒ“6‚ù¤z€­d½t¤”)_8à•"s©¤Ë ›3˜¨½/€æJÓ©Q@1Ÿ2§*dbs„òAQk¹ÛAÄÊíN Jº‡]²1ð¦ô¸(ÌTp O×òoÛSÍ ƒ§žzÊ})º;„.ÓöŠ¢“Jl“uÂu†žÔi{‹$Ë6EÎÔN AªdƒdèÌÄ}D€àJî¡d€õ9‚‰ Ž,@îS~V¢›¤'ûÂN ^NöT5ÖãŸGˆ¸{ÁŠáG.÷¢s„.À `g¾wÆ.VƾX*Þé,jëô°ÌìWëv£S¨(àØ¦Pƒj𽬊/Î2ƒ<#ŠªJ£¾ç!çlkxvjcØÍ¤1*•V«W§ ø `Û›îe—Ï$æ4�lœNÅPHʵ³¥jÍæÏá5 òh’¿Àî9‡Ã¡[GÄ<æºrÚ‚°g7Uwȱt$·i®c]7¤²‚ÄAÌð­€>äÔ¡’yì8^?;E1—;ccºC5´6”Ô=0 8ÙƒÞXºŸ°DŸÜ¹Bþ|4Õ:µé«¦“?;¾ux||<ÿ©ùƇÕãÕñÁ)=lƉ@qMž6ÏSVªìàQ  AàÇdYâŸ1�½g¶ì˜Nk,R\è‘6%ªNˆ°;À á³Ñwd!™ƒJmgþ,Fg|ÂØ¸ýP2ÈE>2‚%›vgS„[Éà#ýÕR!3ŸÓciiiqq±Ýn·Z­ƒƒƒó*çŒ9“É$U'†T•´Z!ù0VF˹SE«Ó^˵3šW8vT÷,j/~có´âÚ ){'¤ÎÍ= 9N³âÝr†ŠóÖÅÅÅV«uáÂ…xÂ[!ù•ÂÍ,;ŠÁFhZ°Ý̳ø˜5ÜLHË B"¡6òɱÒn·iÑ6ƒ˜@mJ ×ÃR(Ìëp‚¤·\,ŠB8xžê(Ìêë'?tþ rʸ$.DtOã2à’Û8ú ££×5>ÔXûéµáp8xÓ`øýÃ걪þóu7<œ¯ø­LÌQKQXIÚÊ@v ¤¬,iÒÓ«“bú+hø›ÕYˆéñ5YÏTØ„"B>ÿÄÐUÊ@]‹3ùñ±êòŸ2c#7 7t?å ‹™E*Kædó$04¤âöÁ §...ƒ~¿OÈ!s‡¥—ùÍßüÍ=ôЗ¾ô%ÏC΄–v°É·¦¯{õT»Õ‰f{áKa’R¡ï[É'£àX愪:=rƒËÔ#Û·Ìzê 7<kmbóh{rÞF£ííí„ç’ùùy¤¥ð~÷¼±g45Pnp¶Îg…§dÍ4m}ýFÿiäP ¿º°°°²²rß}÷=óÌ3†0w®h&Íš¯³ÛÀÑÂ!ܬw.­(©ž‰^<¦ÔU<b"kêÅÜç^¯çÁC†FÍëïxùËkkk¯{ÃënÞ¼yãó7꟪ïýç½…zoÆ+g\!„Á·°Úû‹î™±ì£7ŠÝ§£‹£/a †f$ó%…oºAÇ]@$(ˆn¶W§U‹(§È#- °Øhövb’7ߎFÈÑÑQÖ¹q@Z|Õ�Lj"EÎqµ`ì…;;) ß1Á­J©f šutt´ººúž÷¼ç•¯|å¬�ÊyÈ9ƒ¹ƒž,e•Y_d6c5Ó„@ËÒù/)|²lŽ'VmÑ)0Ù¢/–ÆÙ3Ì$”¸p,æÍR¨_&ln´ ìâ<1, ÏEf뮬¬¼á oX[[û¾ATòDZúéK¹=«¤’[¸‰ð¼&“É`0¨dµBP·L=—›TÀȱ˜!­Kš‚ìf0UÞ“†Yœ†ãV€2ïÆ#˜ŸŸo4îc t°É7þÂpíGÖ®ÞõÛ¾íÛÞóž÷lllüʯüÊ—¿ü壿vÔÿgýÅXtýǹïVŸ©áÞ#¼Æä½V‚Oe•qv ÅŸéÈè&´Ûíªªâ³NçÆ/sx6¯ Z`~sÊ4¥¬² „[É öðð°ÙlÒ¦¦¾¤4ôTŒ OÉÄÑx¡Åù++''ƒ8£ˆda™$Œj'šTu;;;ŸøÄ'y䑯|å+g¥ysr*§rîê»\ÉýŒ£¡ ’y[†¦Ø ,{»Ur„=ìŸÍéë4Ð\èLÓ‰aÆ0«6ghŸ`Á Z&°b®*Ç™ÇBÈÉ×AX—K¢ 4â‘ìÒ­”Z­öêW¿úÒ¥K_ýêW_|ñEß=I¡Â‚N”íÎB˜•K'‡H¿ßþùç‹Lb¼ÓLƘHÃáÇ'…;—Ì:àå÷^QùvÍf3¹v¢K£ÑÈÍŒ˜|@¨v¡?aš{®!æèHi_3¼´ué-oyË÷}ß÷½æ5¯ÙÝÝ zûÅÛýW÷[­VêTÊ&{EÃRaBÈäuCm!¤X­ƒe¡z�A¶¢@Ÿ†îi»Ý~øá‡?ûÙÏšèEø!‡Ë¢Ês!Á²’-ØIÎ2l¶H–±Çz¨cÌ;Í=ÏjÏ;d‰"¥Á·3÷á¢Bz§Œ´¸µ­çu²Ñ­é”0DÜr†”䱄|úÁÁÁG?úQÜ&ÏCÎGÇ’¢Hiœ“ÂTNK;gµe×§U’ 5}¥ÈÂXâY.p“ ¸™ÑÀücv¾[Óä­˜Ò烸¨2÷ßûœ¹[&[Zƒ¾‚!;‹ÕMBÄÜÜ\¿ßÿð‡?\¯×·¶¶ˆ[9è툌˜AœåŽÑ“`Àmv „ÛbˆÜUn¾{þ‰p25wp×jPá¾Ì¿S£¤˜)¹ÕjåÚâaC°©4·‹7vRøü>·}4µÛí¥¥¥~¿å¹±étz÷îÝ;wî\»vmssóÎ;ûûûÃÃáÑñ‘9YŠð;Ȉ äZo&ÅS¢î¢”Q4ÞénÚ%:wxg<gX ¦øêêj³ÙŒ'! ÕtI¡è­Îö~ó|L'Ò³P…• <Úå²ÉÔ>¨ÏŽÓ,¶b8&‹Ídè‚kࡱ"¶ò:ïlÑ‚ê;PI²«€ ÎCÎÙÄëh¹|ùòáááææ¦ ©YÑ't¶RT'FÆ<žÉŠô⣠kk&G5gåö„g‡,..v:~¿O–”³HdŒ¯P°ºó»'I4gÚ—ZÇlQOçF£›7oš!ŠÍ‰û·svqö¤”ý[Áˆšæ¢Pçä×¶.”kéHÙú,gzB5b¦nÆx¾àÂåoP;Îââb·ÛM Qxz‘ÔL*ª©åaBUJ3ìÚµk¯zÕ«>ûÙÏÞ½{רàÑÑQçç:7ÿÒ͹_œûµ_ûµ_|ññÇÿíßþíÍÍ̓¿q°ðS –2!LRá>V¦Å&<~ä©X?8užàqÇ ¢AQµç¿ƒgŸ}6c§óóó/^|ç;ßùÀüæoþæ“O>Éi1ï¬bR’ÍhÅLnVp€AY€¾ˆ{®…÷Rî,!Èn¢Ø†'ùSÁ&-ÄLá­TÒ�L»®àÅÑW³¡iú³…¨¼ÿïÆ›ós Xc2 ¸Ñh¼â¯ØÜÜÜÙÙ1%¿’Ö$Г@fE–*9±Û±`¯¡Xì=_¼¦8 #]ØÌèþ‚ªy•’”é¢+ž‚0Š¿½Óy¢,„+g—Õ‰ˆ£vÊ¡œãžY}Hev°Ú•‡ø ŽaƒÔÛt&S×xÐT·Txê•4"ô’&ç#åm»ÝnhÍÍfsiiiuu5…Tšáp¸¿¿3®Á`@IšY ˆ” ˆæJ¸*/¿GöûÍ…½ÿqoóoþ—ÿç¿<ýôÓw·îNŽ&ãÿv¼ø¿,ηæ9méc®‚SqlÑS´3!l.SüS7à×NIMà©g+¤Ùá­:ÑÃ^\\|å+_ùÞ÷¾wyyùúõëׯ_GM9O$(%Ó'Ì>SjS|SÕÁM(ö”­†ŠygZ¤àufÆÍœŒÆ}2°»J"ñE‚BêI]U0Mõ6aV›Ë&ŠÎb¤’ë¹EÛ×�î@¯×{ä‘G˜½@#À=ÜæÙc€¶9>ÌtrÍÎØpÚÈÖíà4)Ö s…ø¥»ì`W 6Œ þxª1—[—`®½˜/<xÛª—bv«¿ é¹<Ê…å‹ð¸žàEþD”c`.a ªzX1BµGUsÁ˜á¹9CüÖ®zf°ˆ›---]¸p¡ÕjµÛíN§Óh4šÍæòòr·ÛÍÝ>88F[[[Ãá°ßïïîî²RÓÌÍÍ¥f=88ÈJÇÏ>ûlŠ$˜KdBììüûþ¯õ÷Û6†ƒïLÞ7iý@k¡¹`½×àuv,X*dô´©q€t†3Ót:í÷ûèûQ €š¬á¶œéO?ýô¯þê¯...~æ3ŸéõzV—àjÉð,¨lM3Wíü/ú­fi2et±ø #]N†L]¡jôÈ3ÓVB*r"S¨>Iè-U'J\Â6fQh8l^Tç~9gi ¥Š¬ªÐjÝM%1ZÏ0KÙ³oFáœf¹ç¼³Þ-Z C&¥@¥ø¢'á~8ê÷Íf3 ¬º§ÛìkkšW*{Ãî/¼ –\`hðT§•ÿ í)Kr!`šQµœt6Úq Yxñ}Q¥ŒV¯×3ýÏSrVÜ"o° õ„‰¾~*faÄ ƒf³ÙjµºÝîêêj·ÛmµZ+++ëëëëëëFcmm­Óé,,,„£µ½½Ýëõ&“Éîîî­[·666ö÷÷ƒåf™q ¦«1Ã/oµZyÊI«ÆãqçÅÎÂ{ßw¸÷§÷¦Óéܧæ:ßÑ©ÕjGÇ/ñ³mìævWAÒÃfÂRgUU»»»8I»¼«$÷Rˆ*vQÉ™•NWkkë£ýhk:FænÁ¡(D¸³�„zއïÛ-·Óö‰¨«|ÒY�„Ötsø;æ|FÊ–Z…ZR>Å“­t‰lu<À6ää”°–*©º9üxnzá<9gr*Í~)"!Â^fŠ&X9‘³›Ã1ÍÐ8Ý⇻£5=%7,ÛâfѺ�@Â5hü|î¾cÊǃ«ä’³3nà ”ð ·sñ¸9A“Å ìd2ùÃø/..>öØcwîÜ)¨á6ª¦„þh4ÊqÿÐC­¬¬looooo‡Ã½½=ÄÖxR` pCrr&z¶‰ÅGf5¼ @°ªš¥¦!ØÜwß}ËËËiÀ\¾|9ÌùÉÖívsö÷÷¯\¹²²²rûöíùùùÝÝÝp F£ÑÝ»wiW’”Å*„ëõzóךõߨß;›ækÖݱ` S_–Ú+p'º˜4®`£ä÷4±ÝÆç4t¹ìÊ&„`ˆyÔŽ¡¶Cca‡Â¥äÜçâ-dN°A §fã#Ï�«—B–qVIÀÅzaz2¶0£³„k%5nµ)š¼`}}½Ûí>÷Üsûûûf0ݵê´Ì9ƒS•¦ÏCÎ÷r¬\Äfp›‡6yè%ÙHqgá´BÍâÁ@´ N&¡6›M«3É•fÓÜPå¤@)À£an!º#Ê•Óïñ”F!éQhd10\®’k½eØ—––r¼îïï‡ZJË„£“šÄªûî»o}}ýÉ'ŸÌÍÌWð¬]úT*Læç{µZ­—½ìe—.]ZZZºqãÆý¯ÿµ V'ÚbƒÅ—Ï·Ú|  yâ}’ýZ­–  NgiiéÊ•+—/_nµZ—/_¶–ƒ�ïTÜÒÒR^Ðív666ºnݺ•²&ÍäĘ\m»ÝZIOhqq1‡âl $Iƒ³r7#YHd ¹99lj@¬ë"ŽNÉŽ½ÕF–hljú%€g«YØÖœÆ<ƽq;¹QŒJw¶¡sd–GC_§˜FrÆIrSÈr³¹Œ^°@G¹�Šû¼¥áë^÷º‡~øßü›Óëõ|vQiYº0zä|G^‰ÂéyÈ9³ÀbPËÙ·ç±9²ûý>9Šî°›…ñ·®séX²¬)Þ­ËÄœ Ç)XåÙ?Ù~à$°_Øa{³ÃÝZý(H>è6úvAj(¼b‡ÃaNçR¹6ˆ^ù¿�ñÃáðcûØÒÒÒÎÎpeÁ´.ŠQøHá\Çã7nŒÇãv»ýâ‹/Òó'Í+ç|!hyø— žó7Šmñ†HY“L[^^ît:—/_ÎË®\¹²¶¶¶²²’kc2Ôw‰UÑl6¯]»–×_¾|ygg'Lhšóív›æJžK<P7€ì~€ÅÑ™þá~6 .L&“;wî8“fSL�UYmž÷x<¨kù%Ô`" Ë�Ý+[pÜ=†ÌJ Œ WD“ÃÖ«!¦›§ÇËXqùt e~Èe®=L-žkh‹\øÓPùîÜÆB`½ÍNž&¨ö³Ÿ}â‰'nݺ•-3ášóþUU¡mÆnÚ§Ÿ×yÈ9³*§ðôõ9íz/¨kü›ü¡˜Oöt7:Héž]D®M±°4‡5£3¦è˜¯YI®8v¹d4Æí„Ü‹GU<êÌ)ã¶G1NDVex‡‰Šô}£eÙ4»9ls ‡Ã\Ãp8|úé§íˆe!j¾¦±æs ‘äà9îs%Uït:Íf³Ýnw»Ýü×4u:Îòòòúúz«Õêt:õz½Ûí¦ÜÉú8‡bq¡¼—NIâY«ÕÚÞÞ¾{÷îd2‡‡‡‡Ýn—²’Xž¶<Å™é i��­ÐuË:¹páÂk_ûÚíímš% À[ˆ–FuWÍMw¯ Áo˜”¿È@»²¡µ½ äÌ 7kVÓ]…E[Ø%VöL]R˜Á"ñzc•Úœ]jÖ’+!§§•4¨<%Š,sþ$Ù W’kÛÚÚÚÝÝEF½ÕjYƒ^ DM{qùl9·h;û^ë‰mÆN°#,•Gžb³ÙL (ªW”Ý¡1eËqÅOEë’™“·$(Ä-¸þ—l@OÊ5Î/0HϦr+Ȳr@̦3Ð%Ðó€I\a DïÊ8âßh4‚ÇÌC¹xñâÂÂÂ7¸.q¬aCXÌÕû�ÊVl6›ãñ8’ØFJ­S×jµ2äØh4‚§_»v- ü¹¹¹µµµõõõüI³ÙLœȑx“ˆ«Íô¹"ÙÌE&b­­­]¸p!èàà`<÷ûýTN»»»|»$ò©ƒí¤Pva›÷Q¯×ûýþÓO?õ¶0šrW-@£+ ý~Ÿh”Ë`úèw¬s¦" p„äeÑó€¨Íèkt4 œ m=«²ºˆ|Ö 2Rí8jb1_ß…>{2·eJ<m?o:sœ‰ô³‚›HêYį Ž!�uGÒ‚èkû¨âoÏCÎüȶMu¢CZ—ÇÙétr:C¢ª-ò´^,ð—ß»× Ú^œD¨ bbî�”/îÑ¢èt:ÇÇÇûûûùPÔ;@ˆ žw)X^l×b(áÓˆsÙò\Å3*ÈŸ»ÿ™? …du"O�ÿ›4]>F#˃¥ä×… ¶<çæå£#???Úƒ>xõêÕK—.… 0Nï»ï¾Ë—/Sœ[CÒ&OŠiOW˜5kÑúC™ö?<<ÜÝÝÝÞÞ6Ä¿ººº¾¾ä-ï“u¸³³“ /œ½Ô@6Ë *场~ýºG»Š¦=¤>Êh‹—cNè‘Oó'9¯a”X07²žÇ8²åÀ@êiL^F‰À02ƒwÄ-ðpæepñ!râg1síyíBÊ“…O!E•¥å‹â;à­ýuhíø§’õ”¡`" Û-ïÛ­:­vzrÎ2ÞpÚ’P×dû1bM’T: ·à#V’ãDsÉÆ£ùÒ´¢ )XC†¼Ø'ðgàM&Œ¥ä;¢HžË%*C 6ÌÆÈYxçl9$´žÊg9±ÍQÅH²ÿÜóÐü�=d>îܹC¢’€¦A*CÞä›ù“t’xˆy烃Àè Ë3û £Ûí^¼xñ¾ûî»páÂÊÊJˆ�/^\ZZZ^^nµZ`t+++iº¸¿eÓ¨qy¡DZC,EC»Ý~ùË_Þjµž{î¹ü׈J€Ôñ4svÛŸ«!³öBÂꦤžL&Íf3d\Lù¸áYÅä¶{ñ{ƒQ‡Y}‘i¶µ8­U§Å�»²¶‘È+JXL˜³Ò7E!}T($NXb¯ dlL 'Ù1ƒÂÜž,@#`ù[V ¿´S8sW)­V+¢Š7â=ñ[âiڢ鼗sö$é<û(XÉÜc+Ù'9R“°XSI\E½â:Àò½fÙ Æ‚jÜßÔœÝúa˜ÑT>Îí³WI![êʦÙZ •ëØi‘³Â´õ™AñØ ug¦ I`¤¬\ZZ‡¾“|¯ê´fpÁ²²©¹u¹ca,,,´Z­ÕÕÕv»j†¨™nó‰À§¹B&w¼!³zôêW‚w»Ývż´´´¶¶–ÀùÔSOå^%�ç³�îè 'A½rôØøÜ¨6GgÀFðUÌÙ|”Û¨Ðû” YÏbòÑö.vYT…Dlî’ù`Ü·m\ëáœÛQ1›®ééé,¹|.ÆÒèqk€¹YVE3¬0Úà"™$­Nû‡š}ÎZM½M¼·ö¹cf 2'hÞ$€rrþÿþ�dE5O§“BºûW̯x47¯NÓŒ¥7hr½7Q>Èç5°€‡OAŠ<:ëˆlº3'#ðg7ç ¥ ¼’¤‡>Ù+Ùb²!crl³Ïw%�„œ]ofó²Q¹!Ÿc,€&&uø8>ˆm©fšÍæúúz§ÓÉ'GU ‘8ýä’ÚívF1^>+$aß?‚,)“àÓRʺuëÖþþ>Ž/ùÉ·¶Ûíˆë÷û”Yù¾€W$ôÏ]¹ð2éÖ-¸yªï¢"ÍGƒO¢mõ«¬ºhò½‹Â’½ž¶ÄÎmŠÔËN»m A€cÁ¦JvÙ)rÝúߨ�� �IDATÄÜv—’iURñþ"£UYøä¾A�aóÛò|á¬2U:Û*>9gŒ­Uš fº_M ÃÞÈñ‡Ø…ˆµú‹ZÊÓ9Ì“gRšŽãÁƒ ÈOá¶ä£¡’Ó02ì¬Z�êð7+`KŸU3¶¡!@ÊƯ›“ç²AŸóqD‚‚QÃ|¸½GšA ÓPǰ1¬´ÌIî¤íLLí‹ gJ¨4T.]ºá€N§“°!›D$³G­V ¿»J#¥zÎ$ DZà¹Éœª¡2?øàƒ“Éd{{Ó•••€„ÈÖµÛí4å©Âåûæ‘™q@¿ÍSÆ”ÔfŽe­­­…@…J·×ÂB³¢È|S@…Y / ’zÔw/ûªƒÏy[XÓÒÛ°§7]s×ÇL8—‚Àk#vÚ¿Êl[yÚlÛîY³‚¿‡‡‡Á|¶˜ci©{²Iï¬F£ñ²—½¬ßï?ûì³Vc² îyÈ93’´™ Î§ %£€iYLøˆÉvY$éÎXÝ~·ÇPXÂ�7‹Ü¬Ë±èèMË×jüT$qXq&…·#:ù´y+MJçC;NUU[[[9’pª‡!ÔV¨ƒ¤‘�–í™§4˜4"¾ÂoNà§Rñ©dj;W‹Ù&@…ÆpHYé.äŽWVVBBE/ ÝnçY¬¬¬t:¨óAÞ2㦵ˆð†à”îEF»èÊôûýÜ”µZm0äõóóóW¯^E>5¿ FãâÅ‹ ¸$4noo·Z­Ì…ov% ¥p18L>ÄË,ZÁÀ nâ¹UUíïï#ž”üæÊ,”¯OÓ…l¾5ù82Z¦„â$e¶4%ùA+‹*kÌ[¯hÈÃ]dû™ñ@éÃ93c“[Wˆ$Y½†WsDMÆ!Ø;!ߥrk>·:_¹Ûí¾ño|â‰'®_¿¡£@>9gÖË)R0sÏŒb³£<“Öw%]€œtÜžõqËÑÎö(ÔúO*™dûP0ËË~…`ãÖ”ÇÙ<Bä|ÃcÏ®“î¿ÿþ·½ím·nÝúä'?™S¯ØNF–©i ‰„‚˜ Wb"ºbYhÁ!WØeDC®ç(ƒk€•ò%IØÃr†aÑl6CHË'½Ùd£îƒ^ZdÌÇ"Œi¶ÜO§Óýýý$‚ºÝnÞ°Õj]¹r¥ªªÍÍÍ„Lë#äH][[ÛÚÚ"&<G´àËغ»æxi]"Ó y É]˜!+×°)²oóÍ\:³*ÙzÒ²k†·¤§ý ‚•¢æXiø«¹ÈR]-üx€Í-PbU:kÐΰ³C!I7[|Ø¡šÑåc¸“ù÷Ý»w?þñÇ×ý°3,qÎCNÙÎ)L¦­ ó›Ôz' ¯N—›ßb ‹E`µ+²-÷·‹6v`úçµZ­Ûíæßþ,»±qÏœ’?Ç76×|>2¿á¾!§X>*= ¶nÎb{¿„]ÚàŽ74;ÎÝÔ8ûz$Þji>ª­n¯Û�Fˆ *™°É,gÐ¥¥¥ü2©}^‰^x¶½y‰,¾{­Vë×ú?|á‡s‘?që'ækó£Ñ(y“^¯wçÎ|‘|bÚr¹· ?‰7ÖP ˜6 –––2dõ-ãÆ>šÒì=á èD„½sN}c™Xûtòp¡›,îñX¢ra¹Æœ–-à¶%nQ’õ"gûðí¬ˆh~Ù[Þ$íKT¸Áiêi¢ù¥Ð²­bP³½+`´œ6xî1µ ¯H8CõD;†Ñy•sö7÷Š)ÈHWURjÊ?ð×B[Él.«×hüàT¥÷À‰P0Ù´L6 gzaaáu¯{Ýk_ûÚG}ô÷ÿ÷½‡íŒRÈ"A=ßš ;[|zÚ`:nllüò/ÿòþþ~†]š€þ™åL¨ÉoÁâàÒ0ÜN`Ÿi÷±‰ˆ Ãá/>à$¬$wžr ÌÂq a޵Z­ÄãôuâJŸ�>1—´e sK6Üë®Õ'h}à‹õ/~ààÇÕñh4úÑû~ô¡‹ýíÍ¿=Ø$ÀÔëõ¨‘¦!â@`1¸áIçà/­®®"°”«µzŽNtõ©D±‡ æp7ÑOZ¹’”$´.Î_Òö`zNÚŠÚÝH©›yÔ©ð˜Ù X.e¡ús-¯ Íõs3$I@y‚ “ÍÍÍacHID¡Ï›[Î\M*s=KÌn?zJ¢ÂW‚̃8Vu… âM”\-}Êíííós–?<Ü« gÓ#iNñ’S8<Ô3R"À³Á @t2 Ì!”âæ-'BþqáÂ…w½ë]ßüÍß|||üÜsÏe¶ÎÑ‹Kå¼%,SOªU u@a½^ï™gžá²Í¥±`6½Y\s¦$º.5Ü^fÓyÛP  T¨´Ð!źxrOËÃð¹HÏœ>ùÐÐrOÖÖÖÖÖÖ’0æÅ|\Þs4äÈX]]ã©ýüüÏ·Ž[?tøC?ÙùÉüæ/ôþ“µ'ÿÅ¥ñÃõ¦MB}{›8ƒùðð0ó7óóóËËËé™QlµZ-»”m+“Ü”Õn~¼ÝhÑ+Ù6Ìs±Ÿ“}7?¼#XuÌ{Áè-Œ õ¦YÈaJM\ äé’ ˜;à›@oƒX éÆv>³Ûö§¤&ê0QPÈ6¢PEÚÇty6x®Ùô$ ÉêæççƒxçYžŽíÛáBè¸xñâûÞ÷¾étúë¿þëçs9gÜË)�t2³¾-þá–šÝ.I-t]‚PÚ4Z¶Ñç‡ÝhtŽ$Ëô•~¿ÿùÏþÎ;_úÒ—<�¥ŠVÓ|¾¸}E™Ü¶5ŽÃFõô\°2«~&ÍÅ=78àÁÆYÀÓÃ.ÉsiùWâM•‚TJ´ø¢Í¶¸¸Mh°Áx¬u»Ýf³É_zõy·½½½^¯·¹¹ÞZBlþ6»}caãÓO/-Î׿ÿíî¿Í#ø`ëƒO,>±y¼y£yãZíZeb‰Ùœãœ\AN­Í­°Þs,Gão¼ÆPs¡xOr›F"÷³0•ɡɠWÞ™¢áaˆì…l‡ËÜJ²f™©´ ˆ¾¥nïo²z=XVÌ 8zk§ú4¬Ê¿ÙY'žWeèÍ~îìZòΈº¥Ò\˜&JéY|ä¹Þ¾}{0$89gÌ."Ñ6ë#ٌÑ4߯ïö~Î8$T™dv¨¼Tòú5òaŸB”¼ßïÿÎïüΣ>Šœy‰';Ýj«K{ÉaÀ“€ž*5_ [eü?GoUU5ÿ+ó‹Y$J#Pœk ø´‰å–§ƒ\îáqãBITSWAL•™‚�"Vjk8†Ðív_ýêWw»ÝÈšu»ÝD—x}¦—“ç•§Ëh·Û´‚ÜØ8::zjî©-~ìŸïýó÷MÞ7=¾¾ÿõÿþÑéGÿÜÊŸûÊÜW<~°±ÝnGÍ3ä‚„::é¢ááttt6ZBNdí­vì™´÷SÉ»‰¹¥8ÌÒíÿäôÌ?81=2ÌR'À: µ©½¢­MƒMm'‹Ür´îϹbÁ¶Ï›H°T<÷eE‹ÙÇ)Ä ¥ó¯©um´ÜfÕÐ^<‡ÍÚ™Ù×”Óöçæ.ÝsÎTR,äz¶¶¶þãüÓéôààà\ðæŒµ¢µ_¾oÔÕ c–›†A„= Ϻ'qàš‚ÌîªNæ.‹F·{†¦Ÿ&$T'Z)9mi­›¦b˜žÂ&¸Œ`ÌÍt~tÍë«jÕè=£áû‡‹?µ¸úVƒÁá÷üØAëϵª§(CdxÎ[“Êhž% ¥gr@ÃŒ¹¤ s¡A`¦ða&uCfkÒ{ït:¯yÍkÞùÎw¶ÛíGyd<¯®®†Eˆè["CžQ*i™8奄Ö&¾÷翽ÿíÓúKšå“Éä-£·üÕþ_ŒïµñkµZ†I“+ܹs'ÎÁ qœÛÜ܇ ¬–Ü………ýýý;wîìíí¡#�}Ëà0C‘To l¦1†Ô&°¤g Îu‹È~z¾Ï€i¨„+X�€äyÍŒˆæ|QH™\jKM¶*QЊPQˆ)|䜃æm±Í…1:ÊÛæ–¦ä¥¦az¢Ó‰¥7¸ŸÉlîi6£Õ( ^Ù>Óétss^ûyÈ9{ÆdâVK‹"}ú·0”R;ö ºà ÂÌ0?TñŒnxįk:níVá&We�"ˆA §±Õi'Ð"ù¦©Þ>è£ÌÍÍMî›~ïáúŸX¿ÿþû/_¾üÜösw~æÎÂ?Zè}¢×xkã%BàýsãoÏÍÍUûUõÙ{ºA¶6 »à™VtvÓœ@ˆÁ´%ÏFæ­ÒÀYþ#2‰7KKK«««‘p®ªªÝnG·8þÖéåØ˜ì˜SWQá›Ö§·§··'Û+ó+î“õªÞÝêîd:£‘<‡ÃáÁÁÁt:}à(†Ãa šÍf!@P­VÛßßOK 4ˆŠK ëÄþ1EσÄÈÖüCø]Y´¨ÓzÙä³ðºu£(Ë6íß\€«0 í¥¼ ^{{{É­ÎGÖEÆ û#ïC²h-† WÙ­‘{…”ìÐ ce!%KKr“I)W?ÄT³Ú@Âóά¨‚Dš¿M/ÐÓHx3R~áç!çÌ~ û‹1#?LtÙÞÞ¶ ñ#u ié¶Ó†T’õDÉÑX9UHákàKu¦“CŸd­Ú¡ášbE¹9+¾ˆ7…1ùaÏDþ×o~¤yíÚµ÷½ï}ßøßøéOú·~ë·666Æÿ™ãúGêUU~x4מ««Ú\m:™Nß:ûèÜñM:ðÉWsG7×ïIFkÎ{ëzžÜ ììÆDˆ�É$Ž766~ï÷~/ò6!I› oÉ^:C&G4‡ËáááÁäà·®þÖŸþ野²�þ£K~¨õ¡·Þzk|—9XCH?æÖ­[°¥3všÛÞZ«ÕJ=×ëõRÁcÌLA¾æ ÇVd¡p縟ռ!}Žz‚ÙÓ+Vµfa½ìùD›z¸çÄU™lBt·ýa#ývëH®<6e§žóR!E %=…&?2Ò5~ƒÊ¢avÎF!ÌJw¯«:íÊaä£`T›xé*Ö“�&Už‡œ39Î5 •y”ÏK0 …›–ý笴háýE +HÀ, gk ÈH—ë~¹´´Ôn·ÓÚa¨Ó³«àÔÙìJBŸÊÜ»C�5öÒi‰ïñÕï¹ú­ïýÖw¿ûÝ÷ßÿÊÊÊ­[·ƒÁñoï½oþ7æG?>ª?V¯=[[øÒB½^?\:œ~Ûtú]ÓãþññW=únp†¡ñ\0œÀ:'*EÃ,ó¦0åA+Ë[¼Ê¹"òæææx<^[[ ŽšKjµZ$Ë©º*M›‡!’\8¶pØ677kÃÚŸûã¿xÿ/þöñoÿ“Þ?É5ÿØÊ=^ü;Çßù¦êMý~?Q'%éx<ÞßßO=½»»›ã5f9ãñøöíÛ½^/ÉlPµ¼~ww7a&ñ&¬ßt}0ÈàÜIEB€´f%S2Î5V85¨“˜°üØ ÖOجä¡i±>Ç6‚“»)F i^&ý"í€hçIÐË[@e6+µ’ˆ{º#¨_#ÄÏëó‹4;ŠpyH°°É]ð_@y$Χ„_P` ÝV@” ¬vÚ>9grèjûØ47%*9Û@Bßa R€Šc1ç!,qêw(LJr–lWkh1ec«B´EÑÄ)ê¬. r•4²`(åÛy°†ìõÞž¯ŽÓô‡ƒÁàîÝ»/¾øb¿ß¶‡ÇGÇÓÖtüðxíƒkU¿jvšõzýhï¨úõjüߌ§÷OëO¿4pSÄ™áͬFrüT“ `ýÄTæQòì ÂOê¼€u‰%¡d &b3yî xiZ¸ô± ‘%è·¶¶vvvnÞ¼9N¯]ºv­uíÍKo~çÊ;窹ãêøïìÿ××_¿Wí]9º²UÛÊ.íâùùù .,,,\½z•¢=7Û*' ž7)K"dKÓ ³H'vfc^·€º¤eÁ÷òoÈœ¬(·ìÃäèÄÔ2Dkøeæ1Ï‹H`aŠH¸â5´Æ4Tžcž”-ÕIóz+§åˆ×±/‚j²Á÷®ò¹,Ì@1R&Õ‰.ꋎ~炌ãÈ•AN§9?9g@’Æ$ÜÝHS“­WÁ¬N|ѳ2�E~ f­Y(„Î‹Ö µµsø6vã ¦ÍcŽúóÖvüš”ð+ö’C&.;Ü·HžÜm©m½|듟üät:½zõê§>õ©Ç{¬×ëMÞ1©ÿn}ôwFK?·4Ú]¹rå[¾å[ºÝî§>õ©çŸ¾ñFÿcýÆŸlL'6R´„Z.€€”áÜÜ·XÑrYYx·PùÅ„XM¯×Ûßß_^^|[=$±ÌLø4ÌÇÅ[“1É<£ÝÝÝܺ÷>óÞ_þø/táÇö,1õ_5þÕ7Œ¾áGvd0$Ng†¢véÒ¥|0Öp^¨„d¸$ÇÇÇ{{{»»»[[[i䤨Íùîu%Ó Üt¸`OãÒ!øƒ6s ¯³FQÊššËÈ*²øu¢~†óYÅà0Z¸íY‡·:­² ì rkšuþ<%MSHç^E€ê$pŒF¥-︼2E³{Í~ç³Úà±öù-æ%<uŽo¡‰?€ÃÅÇ¢Gç!çìPwÎéÃñ—Ô£ ‡ðÊP‰h÷A¢§=Àc‡˜†1"F—@bõ'ÃÊô-òŒw±“ÃeÐŒ£y/Vî13‰ ;ßj`•t3³oMR ûr||¼øS‹½ÿµwë/Ýúä'?¹´´tóæÍ{Ž^?2i{{ø†ùâäü‘ïû¾ï[__ŸN§ÛÛÛ½^o®š›N¦\•±/ú[`¨ŒÇãF£+L¿‘ÃépÿÀdý¶ÕBW8]™”•‘¢¨©Œx6Ÿþù€”’˜N§iÃt:¿|÷//×—éò/M¦“¹úÜOïÿt{Ò>®ß;"ý^rˆ N'K¥’PJ©Æïèè¨×ëõûýáp˜`@Ï„=Û“óÜù¾ÖÂq}é1Ï”ø¿V'JÜ Jpòq+E)Ú–ÖO–†rRѨgYÕ†â€ÜßjlhðEX T8ϺڦÄ÷ô´w(µ‘œÈj`D‹:Ó”D¶OÆd"8ÛР‹gÒ}3ÀöA€=á×l6‹zè<äœA•ÃcöØ „NNØJ“p1íÉaerU™³'sóéúX¡DõErCæ.Ièâ�ÊWÄ ÷„ ã5sÁù lIí‰.u«^‚b6çç?9¿óîÿïÇ - ‡ÃÃï=œü™Ió6§ÓéñÑK=êÑh´³³³½½}XWsU%×ă™NíñèhRNŸ_W´²µùÓ4m6ŒO á9if®!m¤hü$„Ðý¦lÇ›››©oR!Eòµ‚ÅÅÅÖ\ëýûïÏ Ûl6«…—HG¡8‡ P¯×wwwïܹsõêÕ‹/B‡cºhmm-:™L2…º¹¹¹³³Óï÷{½^  :r{“‹‡ìG^eQ ŠÜ±|¤)¹³}Ô£pÒ¬ñåQƒYˆ“òJÀ^SÚœ¼Ó£r'2ÁÆ·¦ÀA[§3dÂtøxŽ=I¹‚ ÿ!—ÚCÝZ'Ü|A¨:íôjTƒíCÈ¡#�Üè<äœÍmâI ÿÅ*ÄäÃ\F[Bº·x°Çqò)ÑÂ[3ƒæ õ2 ÍñLº'­`³x¨ÞÜ\:“fO’Þ"ÅI©OöC¦^ˆÇ÷€ÇƒÉüÿ1?ÿkóï`òð¤:®æy¾ý£íúíút~:÷¿Í q¸òC+_üâög¶V«=þøãý~ð÷ؘ›ÎÍÕæ¨)eÜíô(u.æÒ¥K‡‡‡»»» o–9@ ÓÍ�,Jí±M}I<‹½&¶`#–I6•#c45›ÍÃÃÃííí~¿¿±±Ñjµ.\¸PIIšêp)™Dš|åL¼‰¸çÑÑÑ•+W¥Y{(اy377····±±±»»»³³c™%çªu(Ådé<ýç<ð^šã¼:­”èWœéf‹ÙU‹Ñ ´!/§vr»”AŒ$ A[ãoYÒF£™¶Í’!»â qs€´Æ~ †{BÙç‚) ˆ�š}ê\‚Šóìøj¨4A„KnäkHÔñ°«èXûº¨r(qš2OkaÇ0%píbŠ…)N@ì LËNúÌyÀUXÊ#!JV˜µå¡nð ëÝÎŽÚØ€¿M7žcÚ1dnÓüs¯??ªÕn×j­¶x|ïŽUõªªWµZmº;­}¹6yçäÖWnÝþüí¥¥¥Ã¥Ãá;‡sõ¹¹ë/‹9\ñƒ`š!þ`o|ãŸþùŒRÛ?‘Çbkuâ—û‰Û4ÌÆ¡hÅO&“v»!óåååÉdFY¼ fi?¶&“I«ÕJ´ØÞÞ¾zõêòòrú(™ †ò@qÌ2Häã _XXX]]]YY¹xñ"O³ßïß½{÷îÝ»áÂmoo'wÉøg\¶¶¶vwwÓß2·®´xŸ¹@[äIÉë-¸ònÀ\Ù܈ü€‰×[ðÚR cMû•“y@ü&9\ ÎP'ÌHÆ[A ‚+d wjˆ”†\m¶I,b£QiT3ÑÈ|—YäO¦ƒi&L–imr_øÙ•f¢[PÇÜúBá;†€dªF$ÏCΙ…ƒ{úc1™è6úzp¾bSuÅ^Óq.‡ ei˜Ì¨¤vcENTf7-H`IZ©f°ZA‹uŸŒžÕ5S8?H‰ÐðõƒW0;ø÷÷Þ¿wüÐññŸ8ÕGGÓ£ê¨ZúðRýéúôxjß¾‚ÁkZ§-ÿÈ# dlÞTè¯h¿éJ×7ïŸ\Òî;a"áç–‡µ··G/:ï÷îÝ/ùËÛÛÛUi·Û»»» 0½^o<¯¯¯G÷,³>ÅàENÉÕÕÕèC7•••X‘FÒ1Ë£×ëíììD\ààà`kk+LèÁ`Ðëõ¶··÷÷÷wvv2DJdG%Ƀç€g‚tÁ‡¦8ƒÏéu˜ÚÅ'¨‡ñW– ¤�"0LD%dÄŒHÆ…ŸfíädЬœJþ~$OŒ?[¬ÚA(‹#;[A/,,¬¯¯÷ûý~¿oýéTÀÕŒUA% <ÿ•¾`ò’+‚aäw6fƒW?h+îOð<äœåO1;Yd@äDî^®¡'™` L-•Ó½ûâbÖ“ÅÏÐ=ÇCÂ8ëYB†â²Æø@­VÃk²’C‰Ýhèâbè â-ŠXgª+g©”>lÐE0<^š9ý™ÚñËŽ¿éøè訶W›û/s …éñ½ô³èBån<1¡€©þ»wï¶ÀE=Ys(Üm&b4 c0ÃP§ìFœ�<N3ÿ:u»ÝÇ·nÝÚÞÞÞØØØÞÞ^]]%Ÿ k|{{;™xâD¦Ð ÌÑJÀ«8ÿ¦ÎàÀÚØØ¸uëÖÖÖÖÞÞÞîîîîînÂLÔ ö÷÷3|š*Í.Ô<Jɤ5TØðqA)=˜Éb³ï`d˜;ŸÇNöVpü˜„s§Í�€ñ^ËqzjØ�£‹ž'µ …PO0&A÷19iµ ù�6ÅðŸœÀ u¶*¡X¨ç.[)eÈ'²„f:sd˜.8'I]pÕ,ß™“4â‰0¦LºµW ÒA‚Ó5Š“AB³$TŠ ”­s g¢¯E¯’ã;×Foä:—¡ ¨5+½[òÅó‰i�!öžÙ\UU5›M`¥Ú µ…['vó/ÑöøŽ>M2†EçË—/‡Ãíím™*IZ¥dÉŸ‡€@ÂHèB\¤1{tt´²²’ï8Ûív>7Œ¸\O¿ßïv»“Édggçèè¨ÓéŒF£N§“ Ͱ·wvv¸ÿa*¯¬¬,/////ÏÏÏonnFýÎzøµÁg2C\ ÖV —ÝÝÝ›7oÞ¼yóÅ_ÜÜÜ ù¸¤¡«¦HMŽ%L:`¿ž(Â`‚gm)[ÐWç=VH2ÎL­¬Ü’ÒNù‹“=ìbòÚS¹°àÛA;ÝÚL¤±8¬òlÿ «-b9&ØZ– ‘5šuA½`)æR+{>i¶âqJ—…¦*Ù:r¶g6WþLnoÓèŠÆíº´‡œÊLD„½•Š´ŸbìLŸÁ·Jþ¡©Æï`íÊÜÚ“maâž''èRp|(­¬¬Ôjµ­­-*-‹ŸÛÕŠ‰eãuÙ–¶y÷~+Â0üà,ëoxúÝnp§YHÓMZ6^:HϹ¶h$[ ÈF˜"‘O×Ä>Ù4oâ~–¾}ÒÞ0 2s3rµØ$üçfæ¶4›Í^¯÷ì³Ï¦/=77wß}÷-,,¤Ž‰Þóx<¾páÂ<píÚµxÔgu¥ñAœè@ç°ˆ|@|´ŒÊ¦ ÙÞÞÞÚÚºyóæææfXyvûûûy«Ü£LfÒCÇ"fcVírߘOáhÀ™îBÉW5½ôy�� �IDATë!H&η²8?<2;:Ǩßïct–,ªpƒ5Bö>ˆ¡4ïLx‹BÅ’ØL;Í0íAô›-♯ìjÏIgáÃmÇFÄ’3Á8¨ä›îD›IåÎa1…fÙB{®ÜiåyÈ9ƒz¤EÉo ô‚CÂntmDJE½Bbå·²¹ûaÖº^¯¯¯¯/..Þ¸q#oeIsÆQ=pÇàxnUU9©­pÖD+Þó vù„Âäq¿"±ÅX…S#ƒüáÝ»woܸ‘IM(t_™•aš2E¯íímÔ$-bOàt$(ÏfòPo’&w:4ussúý~_&*FHeÛÛÛËËËyeæ7éÇk0ìííåß év»ív;–á›ü ‰jºÕÀ?ƒaøàààÎ;›››½^okk«×ëå…Åž÷Ä2Àއ‡‡9Ίü®ÄªÜœÔ[´µ¬o AßÎÖf-D =qé:Æë?Ÿšªkuuõ›¾é›®_¿þä“O‚ñ‡Ö|*°&“â|¼š-æÖ& zî'±ÙB·vbÓ%·`_PßüA©­{]mBßÃ^a `“á%mzïD<O‘óIÑÏM;7¢þz)t<WÉÔ‹LÄ5fIF¬îEÃp<òÉ£3Lã1õ¡U3%Úã•,è9p=âgÝ‘THIsLÛu”"ÀNþo ¨‚¥Dò·³Ö¨ksa¹·×¯_g®ÈÓ¦\O~Q,ŸqÙT `@ÌQÛ…ÞÓ¹ÉÌ“£óMƒ¹ýN§“ël4«««!Fãl–¸’<ÄÓ€f«««ÃáðöíÛ›››Ífs}}½^¯÷ûý§žzêîÝ»Ífó¯xÅæææåË—ÁEƒŸŒF£À_Vä›L&{{{¹“+++QKÛÝÝÍ5ììì<õÔSׯ_þùçÃÎFÙ=ø`TH©k…<ÞA‰_I˜ ¯IwhípdCÍ ÙJ—4¢w³šçÈÖ+i+˜w™VcA°„=�À·-dŸ:#±w¢%A­*’Æý¤ÿQÉÉò¦×HRURlrÏ5/\ÁGS¢Y×Ãb»•D»ý™²C±‰!žÿó¼êž´ç!çÔh¤§y]~ÂÐÍaíq-ËŒ£&âIŒû®¯¯3HA§Çƒ¨ñû ØÙÙͰqµ_æ–,Ü'\ÿþ?pd6UÆ"GË· +CÏ£ÀÖ {SÛêø8îbórÏ>gæÉ²Üœžpæ{(„¡“øxboœÓ'¤€¼yгê´Ãi&1ãŠÆHVº,0ekµÚý÷ßÿÊW¾òƽ^/Ê4¡–%üìïï/..^¼xquu5XÍÞÞÞÞÞ^DÛ"@—@˜h41 ÎV¯×oß¾­\މ_|ñ™gžyá…¶··C qÂAƧŸGÅSû,$I ‹)”Ñ=/âÇjÝÏê´›_¾Gw8èºKg^uèTºùÜ/|á žš%"÷d€Æ’q°p€©NfÚù]8kº{Ëäÿ&¨4ÇMפ W¯ãX€±‚–9ß N, u›Ásº" 0ÆóÚt¬ =Öós–£9,SóǼ­NÛ'{^.ÖìI“‘zÅÏÜüÅü>çOm¬–Jc˜ÃkÚTÚ$‰”ÛA!¡’7± YÍ)׈7ÕÉ€*Ãh õ¡“ìÛª°õ<C^À8ðŽpaÉÍA˜2‘�¡ÜÛà Ñ›‰œš›¨|P§Óéõzàuܱä¤ÁÄr¯ºÝîåË—ónNçþûïOÔ‡­Vëõ¯ý'>ñ‰›7o†Eêè’=;M½›ÏŠ6Áh4êõz¦‡”iá¼ð »»»½^h%“CLéB&†Ñ‡š§,³$�¯’ §6†I5PJÞ‡ŒŠþgŠ«ÓV„,lýònËËË+++wîÜéõzнì/•0ŸGPØÚ²˜MV4‹6PNs˜“ Æ4B�ô¨ZZ*ùº&™cpŠ™‹m&¸&«@W‰…ZÖ˱† Í,p9~èæ!ÑŽ¦Z%õtZe³]´ós6!95æË,«^8°‹\qທPp™ÆF÷¨H…|^»Hw»¾ðÃg,oèÌ Ät�úPb¬lfø®šQ_7ó²(¡ˆL>k|omžH™ííæªCZAB³ÉaŸ›<:›Q¢&’mœ ¹YæSåæç('bߺukwww~~þâÅ‹.\HÓ%µlþ®cÄ4ÓËiµZaZW'Ò;;;é±Å4:õ`0ÈäGþoàµÐ¥ŒãžØ–Âwn²©M0µŽŽŽ\ô¸ éF y\ÅN©Neú—^Õiïs<s™D 茩½vÁ1ÞKx(¨¡…ošY Û4<óXÊ@Y0Csü*Ùáx·ƒ-äCCÈÒ½ i:ö ‡Ãf³É‚7˜QI{¾Âî’z~#ídRkÕŸ‡œ394!ÓnE ÍxW:,qó¸XV5·'£u×9—åý)> ù5÷ca9ãªÔ•ràrO ·ì\•w/‰^Ö|MÜ31lTÃØí\Ë«Ì:GÍ*ŽÀÎ@¦-)+?ÒiCÕ ·%͘¨dæ¾Y^¡:‘Ñ£ÉD°LA™+‡ëëëN‡ÐÕn·“&ÚPZu:„“Üœ¬OÝãµÌÓŒÇã­­­Cyv‡‡‡ù¿˜î p‚JE„V¾)V,´/�³f¡ÈcÀ�Y$+ð’É· רx†4νÝÝÝ»³ö@t V;øy²„sé#Îtó€`ß%fT'bÕ®¨ŒDY¸ Ò å;¼öä`{Ò Ã,Îñ†©êÂõ.k)ËÉ"uÅô…yh–ëõ¤ šRعTá¿urÎ’>À¿Í”gMäs»_Í*O¼ñDôK7úfc�³L¤Šl`–ƒÊžƒC3Ø1•ücœÐU'ÎÁ�SfÁš$jÑ Ž¢9 ªPàáNÉjµZ æp¢<}=77×ív»Ýîîî.�Éæ\XÎŽr“ûfe<F—ø+MЪñ1”¯Ÿ™›¼�c•V«YϰËÖÖÖ¦¯ÕjW®\ID™ŸŸ_^^nµZ‘6ÉŸ“ÚG• KÂO~™Û¥Nš"mpÃx¦Òm1ÃXI6Ébáèd;H~ Èu›M“Ë ýæÞxqÖ¬H36€‘e÷îê´¦ìÅ6Éz°sA^†m;ׂ ¼§íP ouÛØ‚š†.¬Ûó´²GRà¦Ð´Œ ¥!÷Çš7ù Ìϱì{Bº`Šâ|`Ù ØKÿò<äœ=}`ee%¨ X ¿ ’Z†¡dkQ8Ca7f³!ÓÉŠ/ŒÿX¬~FÞœAK pgŽœ'ðí¼à‹Õ-Ù¢Áˆ®^½Ún·Ÿy晜V™œgç—$Î"Æìyœ5å]¡Oc´H“1‡AéVpUi¥Æ] š2I(ùiÚÔùôý´=Zäò8C‰Ñ�A9eJœ4<ôÐCF#¾ÑÍf³Ûí6Ë—/›‹ ó‹I÷8„‚ûûûžP¡—^É=ÓYy!^é'ë¶ E.aÝÌÊšwË.Vº™’aR™ƒP™Ãà°­Y%Ã4ÛŒ#±–¨5i§S<êf¤ùMI(!"Ãõ·ýEFEëÅD2£R‹Ià ìi„0é›CéiÆ,â:…H¾­¸yè°íàμÑogç!çŒQµŒ”gÍ™öîaiïyV–I%8µm—H”þ2 äŽ+llÜ™œû[¿ÏÀ…uÔ³dÙ'ùC( ®åz³Üóúv»ýò—¿üe/{Ùõë×™‘.ÌÇ´¬ÇìNfuZ›ÇÇ ;-~Ïé…ä¶„Ø–,Û<ŽbÌZ—õ¶-¦Ë¡*%,½ ¨ívrTb|æ=Sâdÿ§(YYY™ŸŸßÙÙÙÚÚ:::JtÉòè÷û¨ºÿþûC¹Îïsè‡)9ÍxctаœìQ,«4µ2d'а¢yŽ›{•Å1¦tJ„v¤êdÙˆ/0ªJcsOþAð ”÷1]>Ëѱ'»wä–€¢) Л ‡£4!$å7qŽôÅì¡ê´$ýW>zÖMÇ“Ñù‚H%T; «OÙíÙÕtïà4ùsÍï(�O‹ƒ¸½JƒŠ¡´sÆÚYþ g™ÜøÛz·ÎGèõá0ÈhÑ^7å7ôJ`ŠY®Êä.êÍ W‚’Ä”£ŽqîrÁƼ�«M“K‡Ã'Ÿ|òúõë9òh¤S{‘&h¯y7V'ÊÖö|Ì‹s¾‡—¼ººÊS(À¢YV’‹30ܼo®˜Ö&W'6  LOZT@¹" {{{+++¹ÃãñøæÍ›ëëë/^LeV¯×¯\¹ò²—½,ÂÃéU$‚îîîÖëõR …W¯×sŸéQçR¹1+ªrû7{nƒ4¥p62!°XœÀJpö,ɃT˜úœÈ\[qžÒ\4SÑ+?oh®GþÓl ª Ê»[IÀ�Úµ|Aãv}@ß‹ÒÜ¢:í]bÖuA”0ûÀ0žß¼¿¡öZRŒ¨Û­÷Hw3G‡U!¨5ý)@‘^ üÕñyÈ9³“BÞä}w§í ƒ HÖ"äiàÑô*öööÈA´é¯Ðc^6,ã¨(Ôb¬„å ã¨dˆŽ> y·pšÊ‹ MYÈ GGG/¼ð‚[Ä¡h{°Ù狇®9fåè s-’Üããã43VVVÆÞÞîÙ”N’?Ú}„¦l‚B”:±$�dii)X÷3ï9ç›sŽ'lÿ‰MÀÅ‹ÓÒ­ ÒÎÓéô¾ûî»téÒÊÊJ¢ ŒçÄ1A o­ž{\p¼<¦°R¯$àÑ6/F¦8Iã ÇCAŹ:±à›L&Íf“É-súD†ÉmŽVî|1DY4–Š Ú†…SrÞ<eSOý†LŸ¤”¡ãD¥¢ÈKáh0Ù£®ºb;4«ûYHëòWL)u@ËŠµ´O1 àbò¾%›G…*)<±‹c©`Ô®:‘QlÏB5üXûº(tPB¤¹,“™#b¹ðý¤»h:¦)XæÔCUðq\ÉYôû}¨Ä<æËòÑX(N�ÄФ¡9 šA>ˆ„†ÿ–¯�re“«œ}>F³¾Éõ°9àÛ˜Rg°mm-Ù4Ö¼#°±‹":ÿ—ø U4‡QHSî¢ÎÉÖe4/à8q7A"Wø+J)S2‘ƒ·c(UU-//jîS/\z¡©¿»»ûò/¿8¹˜U1â<[šÎÞ )s%F#£ è±K‰¬œSH“鯹 e s?a{U˜í"j!µÙÔ”‹0à¤l!mÚÈ™N’å˜'ó1MºÀ”%ˆwÂ}û\'>ë¦KX¢,·:íXãûDfŠ j�0]1W`¹,goYÞÅC)„äPÙŒ¨dq‡I%)’ÀyŽgØÎ99•Û!…£;Pt)�^ñ¬NücТHCÙszEžg¶´õ ‚àæg%Í7¶ 0Îê×z°±�¯ q¶¢ßXIõ„= µ‰­È‰O¹CŠW/Š‘nr¿ß_[[ $Åງ~Œã›^Áa6Ö]S¨Üv&"ñFK“NŒ§£KMâræZ2Ž:N£U³¼¼ [)ÿð4ø3õgþeû_þçæ~ûÝ·7š<ðÈç_õùk[×Þñ¿£Ýn[MنܢF£‘yIîs.ÞöN.Á\+P\"GŠƒ™wÁÙ¥rµÐ‘]m(% ÅO?Y�dW,•FÌÈ7²æ7’²‹‹‹áøYâÅ2nÈv°I]X[YЦˆQYî›otjOÿÀ7qç•÷ ATsÆfõOÃÂ.z�?½Ç ·Lžf%3Íòb,sK¶½gIÐ<;ÖΘ>UØŠß“wpÔÎJëW'"²î“#bfŽ‹Þ½zkÞ@^$ !á*¤£¯ùÜ!F"o ¿…Ñlòf7ê98Çf^ ‰3CP¤Ê­C”Ï‚Ê ô¼³³³¾¾Îð<±ª’²\á·MÛØBf¢½˜Ëh4Ýn7lT”åË$@Œ•¼!‘ !­Ýn§’HŸ#Õ@»Ýn6›}¬ÿÖh4Ž{Uï/üàã WUõ{ßûà¾íöÛž­žý©7þTÿ¨ÿ§>ù§‚ÂeÐsW ÜXÍ ¨ƒ†+­ é¢ÙK±TÆÇ,ºÁãÎÙÇ‘÷ `h¶z%ÿ@¹@!£pqc‰ê„c×…Ô•+W^ûÚ×¾øâ‹¿û»¿Ëœ Üç@±*9¯¦@Id%*¸F.BÑæIO«mÎrvŸS.'R\+vY1ÙÃÔ9¡ÎÀµãtr ¤¶©ÑÍšñX7CHXâ~MIªós¨šMô $cæÅà#�O›¢ck,ËlP›èÂ"#Mò’F«¦:-´Ã K)°°°!Ã>ìçÈŽ& -¹k#c¡†üY¼;Ó²¡äL•/,,DRÓ¼�˾n‘ólq(¶4öß#}f&ºÃá0ÄèñxÑ9”ÖòÃÃN}@Æ€i9þBøfð°V«Ý]¼ûÝï|¡öÂßÚû[ß¿÷ýµƒ¿øÆ¿øæÛoþÎg¾óÁñƒÏ^}vº6½ÔºµWÒDWrJªØÒ{§ßB7î…°‚)Lèáóšêd<6k;.y1Ïš{nq6s«, •ÞψÃ=·Îm$–‰R‹‹‹èý¡·½ímŸýìgüqö®Ì˜=[o¦:-àÏÜ 3.†¾Á¥Í”#ó–'’Ø`Ájqï‡×GÐ(׿7`²“B†tàf0,iCW¯˜=r‡ÐÎ!4ŸósÆUÿ(Ï=°â?ŸŒÄ“ÚÛšи–¥£©y}žìš”ó� ñT]µ4ºí—cEË#V§O-×fÁ.[…RΗٶ¤’‡3kÓ"* r ZE?8JÔ—ð‹¸'ÈЇË~N L&ñ …HÎâ¸ãìïï§²Í »¼¼Ì× ´’ÙOˆdéñäAÄø ^¯7›Mf÷B6³´þ7ü÷ë¿ÿ¶ñÛ~tô£Ó…é…Ú…n}ôg—öéoxúgžÿ™w¼îŸyÓg¾ç±ï988àL·s6ØEFXp`¿q€õ<r¡|õÙ§¡§O¨6ˆy‚ÉxìÉÓ´ÔÞì™Ël \ï6s©T“|‘Ī/~ñ‹Ï?ÿ<Ó v´4œ;KK³K¬íB¬ç s”hŬLATów%õ ctÆ3 Nx–Ò“ô…|‹ö-ŸÈeDQÍÐkî¡ó-úˆ$[�wnJ‡œ3«r�‹?<hÂ"œb˜ð@A}`a%ày%9øyÐ| H÷k­[àÝ·ëÈŠ·¾wgË,Ûd[ÆéòöíÛiJ3`ë6’)ÒÆ¢sfò7BaF~ÜwõÁêΔ?K€„—g݃tÚCˆUW"Êîî.¾–ɦ Åè779‡i«ÕZ__‡Nb•qÇãñgšŸyÍä5ë ëfåVUõŽé;~cå7^=yuUU‹K‹.\ˆD[ °§ÓéîînŽŒTcG£Qøl9trßúý>#“9¹htUÁ r8—*@ÑB¿•¡÷JÚeÕé9Lj‚–YìšU0ýæ®KªªŠ·ÛE¬FNX¸…Õi•뜪LøÂ`<¤Ž½€`ϱÀµŠÞ>Ž�Æ¢‹øÇm) 6êWÐrvíFÖ_@¹ `ОXîgċϫœ³ÿAúÅ==À1H54ü™ë¶«&¢õõ\ž3®ìɃb$}‹/‹>û$½n{£Q{5 Ú ùˆì´RTÖNíÓo€@œ—ÙÛn4É#sgºíaøn€kX\’OuzšÏ–ÓêÂC!øI*³©á#·&Tif×ûý>¢pü!md¿˜U‡$e4ܲ“s3a¡úƒ“WŽW9¹«þ¹Öϛ㪪šæòòr§Ó‰D[̶ó)Qd¨N”%¹°‹¹æDÖ@mÕ‰¤©çÝ®(œÜQ°~¹3c7P]Ò<Hœ­\ â ƒ`2”2¹?«·ù˜0“ïÞ;Z;¸t;èQᮋjA¸@§ßæ%ÓÛË6§þ�—&xØ Ü�hÓ‘|Û­HdÛ{p0;PÙ1לΨ›¦¦HäkÆÖ$û÷œ>pös9œéä¹I±õµò@ ™2b Ó½RDÓ 6 ,G$Ãö6{/<Eè/--…ã”A¿ -Þ@XäøéTÀ17‡²†àKKKKý~?Ôææfl+áΚcCÔIN×Ê#;éµ0ukP“ ð9NRÌTMa\„ÿ3:¹Ãá­­­Ë€:ª3‰¹ìÝÝÝ<©¨vÆ„¦V«Åh'htÕ ÚD+sŠÔ¹ƒÁ ?×?nxçï[Ý?hþƒ¿;ø»s{ߥ÷½µÿÖÚù¡qmœT=7$µËîîn.lmm-™HÙétcÐÐétàX»°À!Ô0EÉXiæ?9‡2õ:ó¿t`ó›à\I.Ó" –¾fmØÌ4ËžÔ->uÙžf0˜5¤Vôÿ=¸Í‚¬dè6c ¼Užs¢£f°=±È.Uoe%P;‘Sè“NUR*‚¯‘C06 ©ß"Û£f¤.Í?wjÏCÎYÖ7Yë³ãÇH°XŸ ‹¾_aÀ|ÀnQžȆ7Ìê² :-†ÕÑ(s¦l�ÞÙ¦×@|¡Á¥ÖÁn%¹R.۾Ö} ¼“ Ê€³™¶+M0¶r»ËØBA¡æ̵x:ÄÈXéT'2ˆ ÷"b”ÀF}F(“ÿ)€¢/—p›Âb:æd'ÍÌLìÉé“Ъªâ¬“²#gú+†¯x¶ñìàpð­ÃoýRýK¿¼ðËoÛy[}P߸¸q£vc®š{ûèíÍ…f5©¨(•òøz½^Ä,ƒ^¯®ÊüüüêêjÄá/˜Òà4pMî$+HZ¥©{pQ“àÁ²�š<¨”Ëø0i‡ó°\0È`–§™”µ³T¡pÁp›QbÈÊžq†ÿ¼ìiS·ú]:³Y éeÒ@Á 6FüNÊë3Ñð³·z1[M³h[¾>5 Êßþ[úˆ`Ý<_.ì<äœñC‹„çhH¦ÛÃBœž‰34̪Ú&Ù$¢önîì�nx€ŸTBZdó`ÃdˆKKKIyìòkâ„¥¤‡¬ÝJž¡f¬1qfnÑ2IÚ"¦;F>œ€¼•ïamL ûš÷á,³uwq&“I»ÝÎ[A•Žî@Òí$­ôò‰I]“}SÚÆ† !¶ÛíÖëõo¯¾ýýõ÷¿}ðöŸ|ñ'?¾òñ_èüÂZÿOÍqó‰Î¯½îûûßÿ½ƒï/Œ­y‘§™Ô>QC½ÑX+@ã³óIV©Õæ£ “7R+Ó¾yÜ´a̻ᒌ…ræÁ¿(r-TSì|+àÑU2�å{uŒù­¹ª«Jn0qŠ÷׉˔æiçTI¦IæÖBy,ÈY±`*Q›âTUxÛ>‹’uÁ64Ö ¥mÖ±ô<äœ iÍÇ%uÉì0&ɾ› ¬!º¸·äh¼¦!oo·BŸÆÛž¼Éä".Øðˆ=½°WaO8³ô®¦2à ÇÐ  ÉÖe`ÝÃÆá†xf“;yMà Ä9h•Mçn¸ÕìÃwnn®ÓéäàNÈžÌçFu&¼gÔHé�åÔŽµÀ:4â”qܸͧqÃ=­<ú½½½ùùùv»ý]w¾ë'þÉkÇ×~âöOü±½?ö\ý¹¿òà_ùîƒïþ›[óbíbm¡ÆàHÌÙx@±?°BÚþþ>³A¡  ¥]¸‡Ù®Õäõêô¸qÖÄÔ|Ý)«Áº­Â×â•,`ûN1ïY÷é ¨¬gî¬3Ï,[+æ¤7£ù5Jr8€‰… ˜p k‚Ÿy›F­áZC¤à­…]ú[´uMùaÍ3íB–‹4OÇÈo…¡V«;9go’ì0Cö ™„5 zë12‹#å\ÀÜÞÎ49(ÍøÊa}É,å¬<Ì]ò't2a%pô{tÀ3+0SÁ¬Ü䬾Ö8\¬¢�ŠD {ÒÙŸD *A…ɺóD4Á‚51¹™®LèÂUUÁå…zG!%!_ÈÞ¢/HaNN~ŒÙÙÙAþk4u»]fûoòʰ9²ZòâêÄŒ`gggyaùǧ?þÔÚSßõêï:>>îL;~ùÑ¥ù¥ZU›,¾Tbfzc<Ç-”˜Ún·Ó?OýD¨Î Ï5˜/`( Î’›‘¦¶Ã.+¸ì©PÄ@ñÏM²Ô^9í+Hzn­#Þ„ä]$a¦5ÎÚ3ób ßaêc¬ÌÍy48ŽdfÍó‰V;5~Îß²ûŒF€•ͺàðƒ>2²ö`Àˆ@ ˜Vh³’JÂ0„‹Dþç9¤"Ú.ï<äœ%} ø '²g_\v00\I¨•µnKb4yl©͑±Šù>}4„áÏ$RñÌvñAù^àòžB{LÆ£�$z0œ Ó¬f§™zk4Ò’½ücf�q’\¾)p”Ä1‚³\¸ùññq¯×[^^6g2 '}þòÊ8ñä>o82r7z½™Gž<TÊÙépúúý×ÿÒ—~éžd@k4ªFë¡Õä*!3FPK2õ³ÛÙÙIý£ɳ�� �IDAT‘ì!Þ£ä¼ø•ì¯c¡-È÷yóf³ /ä—0è\šÑK% \FÎäNGj!tÄÉ^Ø ‘´ÙdäŠ)4ƒV{r©mõ   Scì›ÍUØos¸s0Pª¿;)ä|f©¹gÉö¤¯–ŠÇAÅn9X«V^ñbgaS÷˜$øêDÚñ<äœe•û¶p}wj¦² zøœ¹P+©“¥ªÈ{Ʋhô'¾{¹ÅIá1S�¬eÞ³3>Oä@“#L¦^I'¸’3P’S²ZR<*§Â’Ç:Iwb¡‰¼Ö|ˤ§m:5£ì–´²@ S>V«N\¿Ìó†D`á)¬h-&’Yl4v8Ek=<·Èq‚Û„iÆQj¤†æL‰:'ÿ&ð§JÎ`PJx’æz²RpdЕQA«Ýä"#FŒ£[j#"ô»ºÝn@?êΔîÛ‡©ðj+ܬ­xfÉvÞŸG•ª$Ï×°ñÛê´µ®uù*¹”R&‹ÂÑ\8Óm ßãŠMe_ÍèœzéÚ’®ˆ FG0n_IׇHl„ï¼@ÓÄϵ3þºn™Hvn²ÕÉd8ø†“qóJ³½“/"ÝÎþ§„Ϧò4x%={ú’ʹ1hY'ÂR ZînÂR%N¬àÑÌO©‘Sϼj÷¢Øl¦ÄØZx¬ÜÙ€{¦Ššd†:i,81ÏœõƒÁ •DuÚÜÉ/’Jôl<ö1¤Ò2(ƒlZB/Ied°g‡üiòæùeÈ~P0{õ— ¨•gÑh4‚àE])tÐ60Ï,*úU|MîŒÏD¦ýó ÐõªNîµ³³H3Ák•Œ™3Ö'Åwá‘áZ™'ÂçšåÏ^Ы\-(»ƒXly*gUÒK„f¹`PYD4ì£Á½­f$Eæ=“7òc¦Ÿ™rEc¿`Фu„ª–Ú ]D3 †ÃaâÀxÁŸ6†qr¾.jg)°s4ÀŽ‘e°2TI6‘Ø3LœŸ4�þ ܬ¡Pu­€R,šB‹Þ„ov©3)ÿƒæm¡Øfu[šqQóž/œ³+iöY•凋Aœ4üé{9‡m6›AòE:1†™ïÔ2byy9Ãh4:<<Œ~wŒ°Ç‰Éa+ ¯!™ÿ—½w±ü>ïû~3çÌåÌÌîìrÉ]™W-%R&EØfE‰¶‘¤¶Y©l¹p�…ݺ²kÇ@‹A›pÑ´/âi㤲£ /QÛiåKäJ*Šˆ‚d™¤%R–H-ïär¹÷ٹϙ™sf¦/¾œ?ó¶oG/μVËÙsþ—ßï÷<Ï÷ù>ßoÎÜÉÉÉœû™Èɉ€ÈtøoP‡ÉBÀd¬›—y‹\[>¡µÊ5¯rqq‘ÀÇ»½½5“>Öúúzœ1ͽä„Í«Éoæ“———S.¸gz=¯†¾×ÃÚ¶ô¸=ÔK»Þ­Ž¼ <+¶•)Usô2©Ú¶–{)¢eÓìîLp2•Æá  ­ÊbJ þ ¬2S y=jµõ"ÞÓΪ°:œev.(w1TÌç{ählÑvü?†\=©à`ŒµŒ,,,ÎîäÈÌd±@MŽ,Òÿg=L€™ QÍè¶=9Ý8ÍÉÝ ØØŸÊ² pI©è»æ d¯'ö ˜Qþ‚Áz׎n8cºÓétn»í¶­­­ˆ¸ÀŽ“ ']”›cš™6¬ñ“ÔN¦§§S ´ÖŸ2"ó!B‚Iº¶æÞE˜„Ï ŽV#„é„T„y§NJY“†DŸ6;;›ú üÖ,@Mš‚0!s^ÓÛÙÙ‰êÁÚÚZ˜yAÐå›tò­�‹gÒ™*•SÚãMs—¤  ¡YR/Z’��ijŒ Éâ1b�b2¹€c7‰ŽcVFõi2ÑÄ"T˜¨–uŽv�µ"×Öd«j×vx’VuJ pjåÙ¦Éh;¡Bç <RwŽùMˆsE¥×ƒ†ÌfqµÔp4íÆ!ç˜6³áÀb¢ÐBjÅؽJÎwÚï¶'à„uëÅŠËÌî€hA=bZPidš_“‘¼…lm†÷@Œ[p,vÐ$Ñ‚e[*<úê6-æó³C–––@HÊ)€ÁDÆ-ÓåNà±X=\Ò°Ø···£¶-g;;;Á‹n»í6·^é¥ËŠèÙþþ~´Âãà?¥X‰·[¤–——×××C(èõz Ç“Î!¬¶”°Ãá0‘ÀQ<+¦ ‰BnÿäÉ“Y–¹Í<ŠÕÕÕvhe–—årEúL (Ӿر‚¾‚½Y•H¬Èg]>ÓX¨›ÉÀPsI$éü^à)³<fí%O«X‘^)@1¢ŒN3?`CeÆ Ì<7WÛ°æ`BS•Ú$·@iBE¬²êÇ‹•,Ê…Xœ à›¬­Øž@âN¦Ç!çØâ €ô0KÛ°àWl'÷*18ñˆ¯Ç¹Í;@]jzzúƒüàÞÞÞ… 2 Ïgæ’r›ðju,²8YÙ"Þ·ð®"ß¶Tô&¿fÒs*¤Ò}¥Š·P)ÝÀ²¿ÄWó88àF×Ê©aGKO¶' ¦í”–û‹/¾¸¼¼œ·pÇwЫch¿i¼4ìÁГÞnnnÆ›€ø”³ !¢¼ñ¼ŽÄ@žØÁñs#€¹f´ NøîÀç’û£èìæìdè'Hç¹%o·Œ1<—¢g^5Ô¬”w8>äÂ|©í¨¿_Ò݃*»‘ãuâsß2PIM`A#·éÆ*(+ uÐ( €·£nifÁN\$#4ò$m �4É»k˜ìþ'.ÌL|7Œ²“Ç$Ù~çPb•9èÖÿ‡œc 9z!ïÛ1Ðï¹BØÉy‹°Zá’2ÅbùXÓQÞûÞ÷þôOÿôÒÒÒ7rNhAg°ì^ u’n'2rlÙÉp5dèv(Øn‹ÏbÅfÈ‘C(23öS@†^&ÞU jy>À°ˆ‘ºÊ?ÙØØ°T 2øaŽFš!¤DúÝÝÝW^ye{{ûܹs‹‹‹y¿™ì “Þv¨u„n>3"7):3mšƒv@.raaá=ïyÏõë×—––&H<;sæ ¸kBK:F¹È vQFŽòáQùÌÿ=qâÄÊÊJoHÂzà97YAÁk‡ºse1'UP“!L²_à âÐW… <Öâˆ_¢6Y¹{ø\Ç7l«Å�€-3È JæjOŸ>½¼¼Å ~3ûˆï2x Œ•€¡=YRI·|˜iËÓÈ!cN ŒDn$k>6��S \õ6 –‡�ΧQ¾Ó ÷rŽÿ'/‰ƒž ¹6\aèöd¬Ötj²2M‘Žò$ «««ôG´¹¹¹²²Èéd†rØQTåÅ€ 8n‘–¸“KfX' ‘åÈÙ_‡¤ÉóªMF¢lòw2ã,+òV÷™¼7¸5"PœùÐ6µË§;w®µ6??O>Á&4ÜÇ–HÓÓÓ©H"†¬/•Ö‰'òŽ677/_¾ !µßﯮ®æáGÀ†ÉùÔ¦ykiÏ0fAýj“1ŽZd&Ìà¹O dÄÝÝ5û´úù¸ÛlØ“˜AsÑhM#áÐg^ WžÑ„Ú1ÍJÀÏxÒÌÚîv»)‚v¢%S ¸óÎ;zè¡gŸ}6Ú6¥qÕU�'éÊŒÖäj£~nðMX`„CN˜ßFÌÜNãQÆ38rF5xª‰ëüCܲGovrŽá‡µÅ³¤A6|n YºÕioª&ÓÏT¤ׯ_Ï”»9Ê^ߦiA§çYzB”Xc™D`›H÷ 8Ô8†ÈFéú@â øÓŽÊF™Ži` ØÊÇmOÂd¹ÒS-ì2·FIQm‚Â(~Ð†ÄæÔ+9 ‘ã%X•“°Gæ�Ùi(òX˜ M— ’FôÖÖV>!>+++ÁßÏÙÝÝ]XX8qâ§@ptè{↎¤˜ÇlÄÂ�_brÜŸY"x ¹Ârê1WHÊæ¬çr Ï�ù"´jLÕ~H˜®ÂíØÖ½ôÏéGòùn ñË\F~ßRly¹ù'×®]›˜˜¸uëV"´ËGËÅ6Y1ÑÇåu8 ^CNÔÞ Ü2,²â_@co+DðœwzbÔgާ‚HG»Ä»ãsÌôhS-ÞG^Uˆ¡Ž ø`È�°£F „Øø`£'{jÁ£Í¨2ÓÑæ€Q2{Ò»i“¬ßÓd¥Ç[Ú3Å« â� ,O ¦ÍuŠŸ•‡:›l¡vL4²¯Ó?Vøp3 þ>-“ÀG9ï',œÌÓài[Sô®pºÜÄ„Ș~͹¿°°CÖm8^½zõäÉ“'NœHP±}ÑÖÖÖööv<xRÁP`Á{L/.\>|gg6¸*% ÏÓÎÝQÖðù<XHÃ¥ìct)K%9Å£cè8²¦Žµø`—N)Xû¬ŒÖ7´ÚñEeÝb‘iؽ½½åååÐØÛÓE�eåmî(ô™'ͲZv> Ť5LPš‡æ-ÏK´žYNEj$»2rФÔ09ÇßÑ™››c¶ÎSÁRYÄv!3Ý€µpLíÊ:6÷ÌÓ×4Éyù¨oùÄÌ`]–o¡)Sƒ{D¦Lö¸Ð4¸GjÌêˆAg¾Éˆq¤Ýýòx®œ_§#ŒÔg8?ÿ0FÎn¢lªÀÌQv»ÝÌ äÿ&`à‹KibRŽ€ƒƒƒtæØZXX@v ¹b˜yA¨Mó ópR-儺uëÖÁÁÁí·ßšr¯× ¹ymm-Ô»¼÷8•%Þ:p_xÌ„z‡Öup6§P‘"eÎÓcmŒmöÜÜ.2f߂·äExD̲’FG®Û¡çMI·Ëñ D¬*Á‰^=EF|#œþ6ìpŸó¾”<*o”°¹0tÕœêñ¿PL‹ÞkQ !×Év`z :g7)&ŒŽè¡©aÔÎÁr\å|·„“¡ ÔËT98•s NLd+­M›Ú–:Õï¹6“L²uÖ‘ãåðePÃà2iWÚ¶ð}‘ùR¾¸Ç¿ÀMÚvtt¼h³›ž—s¢ÇÕ ÌË™˜] ø�âo•&Ź2sÊÃÉ“ÉÅD“¹¨üi o´ñò9y/³W­g¼&ß37FOrI|»9Eéñ¬¯¯¿ç=ïaÐ$ƒ<½T,èÞ2ûÂYQå›&¯ ´_-ŽÇéÃ(‰ïÁNsŽ»=2·‰Åþº`ƒ&ž±ŒÛ¡ ±ŠÅÉkq´Y½ÉFVn;¹ÉAˆµm“ïN)ý¯¾+Òeóu;¸bŸzÎÚÏŸr“ðY„ x×@ýE^âè¸[vVÊ)“¡ f¯˜ô8äi�åÇ„²'’d 4¨AŸí$V ˆCÙ®Ð]€õsZ‰™£ß2‚Éë9Dr¢áÃn13Û¶€Œ¿x4ŒOT,C$e'tEïþn–ýà]Ä£‚€G—ßÄ\‹Ô厂8ÑH"(i¬/é¿YEâp—xBZÍ0)ªž<´@m9g§¦¦fffhíØOÆQ0­µÅÅżÄÁ`°µµe ºpíÚQ „Ý"à–§ÿ…¼æ–ò±@»t8HäáRƒIÒ=Bà§ÉžÙoÙ:ˆüIÂ! 䨤Ä'ú„Hâd®äR.wXÛŽF”fo“éóðzŠ©•uùL'±,¦Û«F¤ ØËÖ´-ªnžmÊ?'­UsŒlòFum(¯Épσ«9-r*c’ô1÷r`¾Âªd±fT›ãƒëþ2Îb eS 𔩨?àæÄ�ZˆÆû+ų³³gΜÉH£¿×G¦‰¦+Úšâì,6'ÓìÎI›fKsô‡eÚ4õS“†­2“ØcµhÆÚ'Û)~¡ßïg?P$Æô0誄vTÑà &‡™2A>Ú6[[[›››yx”%ää¸ ‰9DmøëÁÖ¨Mã‰`j2çQ‚P"k8ÍÈäHJ­Œ¬œÉÊ0’i’áC“ê3WÒç‹Ö§pœ0DFŽ•Ç˜ÇëBŸ5cœÖC©P=Œ¥EOLËÍñ–qÅi‰O:àâÓ +Õ-Ó”.)ìICõ`4¬°JiJFÎA±ëasÜH=mÜÉ.ãC\›¾Áê¢d$£B¹®I=ˆÉ x ãsœ ùŒq#Ê.E¥Ø'æ]èhBX’ÉpÎ!ºfÂc“7IK™è™oIW>ùÌ™3§OŸ^ZZbr"ŸIMì•Þ£iéRÀ1%ÆÄVÚB…Em7Ã&EÔÔ &G¤‡ÉT'>ØÄWøµ9Ùºyø€*h$SMF¦,Je)/²{1·k;ô £ v.°äÚÚ1`}}=ƒússs—Y__gÞŽ�‚ZÜäå¦÷3==½°°�,âƒÁàÆVMM–§±··7??kO8b6f‘¥¦±00¬O|²{Mº˜!ãäeÊ$!“hdbT¯×Kmgž䵿wxYÅ5.Ӿ܂)L•t%J!Kšïqc6|0눷£ºìŒÇ2žÉÃÉÓ¤¡úét:Ö¯Êi0??Ÿába عf¿)Îú&×¢¬½N§“~!E6„Ö­ Öj@ddlèÙX"&ˆáµ±õwE•CQlAØ;Æ+|X-ÍÓÔ7ü‚5ké/Nœ×½“¯änÁÙ–——777Sâ°øŒp0¸AšÃvqfB‚kiç&‰* gÈÇnçzú}aa!jÄM® ~ìÆÜÜv¶î¯;>ž;ÏùNÿßC„=z*|—ilÌŽèÏSÊ!²ººÊä¹› (Ó z3P.~0lllœ<y2"åQ’Ü•••ž(¿a+åR@räȆÆZfþ3Úiû?d' åL÷œ»ÜX$tÈ?ødæóß•æ[h6‰±‘’‰ÂpÌLÚd ”•œ²�~ZGtC¹žø¤}9ËBÂÎX±Q¾Ô¬§t¢žG/¼—#žÞc›~#LõÁ€ Uã&“ra´ @:õS¥ ÊWšÄEJnrŽ!ä°ŽÍ5¼Àh‚•©hâeU1…nÂ¥“MSa%ðçœwépIÓœ)H ôûýœ D3æ­Â !8ùlzeṵ́uáµ£.Ý c ñù¹!IE˜ã5ÍyVV­'³v¥eùwÎÍÇœSp<&’çvÚº<7¤É0 °¶+¸ŸKÊ5G!4Ÿœqœ4„N:E뎷`¹Õ¼â\dp$Z†«PÅB(˜žžŽ˜[ _Æ×Q+‡ÆÒŽê6ñ|çœ*.YB£ƒVD&ÿò¯ÅÌÉÊ~ævº ae3î—áªÒ÷QWEˆeeh�g÷GsÜC"õ:ÌsËÃa2—Xáe8®¬¬¸z χ ¯`“‹Ô‰^V5$tr0‘–<òQÔSSþR�+?¡qÈ9NºZ6¹Ù/œ/NiñTab†ý_CD§•ã,=R£vìRwì‘Óç°Rz>'¨:P;ÞÉ,k„¼h¤{P]ô VóGË�&ôÐQ‡ƒƒƒ›7oFÔ²`npšÄ  × A&acƒ4½qú‘ ÊçGáŸUÓ(‘ 7 ØýdS½‰j³Ò¢ÈÓÛÞÞÎôeaÌÏÏÏÛ>°‹Švh²b7ì#P{¬²×××Ã;È’`µ€ª‘_·£Ö|EH&O/‘ƒ!0ô#l_m¡Ç¬ä¤Î5Оä‹hA9—7Ý!™ÂìBN D—5hù±¿#ÔÙ­Ãpb“C#x²MÌóÅdÈÜT·K ð†µÙ>Ð%ò›ô,ÿCjk¸rt"l©>a3ÑËÅÅŒéÇÏXcØ°Ñ £mþ¯X™9í*pži°¬,zšNYL$¿‰Æø@Îwú(V”áJ@‡ìÉàá“ûêõz˜SF8aä+ G¸; Šm%Ó¦U®Æ­'[鯀†½+³Óš,O U5¤Iªž»KkÁÙŸ9oœÎŒIRÚ¢œF/7D²ƒƒ¾šRrqq1Ý ·âóH™ªq«€>¿ ñ,‰ÌZN©ÆV`âáÚ‡lhz iÆøsx/yb`†¬mÊ zZôo6œî ø5Š�FŒ™k¶Ë5kÉ “ fØPî˜N:ûŽÄm=ûêâ_�į,?”M£ „|d­B+P³Ÿ ÊrÅfÔb¯ äl.°nÖ$ ããQÐcþa'Àÿ)&]Ðå£LÁhÍùBNãÿRP›ŸC'É9Žf”›†à܃iÕÌ©‘ù‰É£?í¨´Œ16!$%–µÕ5Œñ±àQ±Bn#ÚÀ<(x(üy,@ØiÒ°--ÀeQw“wS˜ûž_Ãi; HÍD;b Dd;ž!”±O&[¥„ÍGáKFVUïNOg¸xTGNšÏ;xp¬lò˜щ N„¡qZaÅÍ?ž¼IÀ$pTîˆèó”.Ùó éG “ƨ<Úèd>°§…GAJñ߃Àfuj>Z CšÙqE0Y¸v_u[œœßwtv]m$zXÛk€l�Î:s{.ÝÆ!ç8 tÕš„â9³B.¢º§é¶™ÄÀ5¥ÿ¼1^ÔGR¶…½ÿñmfÁô6=µ1U®È!1›½ @äée<©Üh=°ÒF¡óƒìYsÅ\U6<áÓüÎ&­FŠŠtN|¿¦;y¶@.W‹jˆ¹Ðœ#©Nëscƒp;ççç‡?öSáDœèoéLÐŒÔ.9Yr…¡PÛ^/ŸŒBš=’©•CœÃÌ”Y“ëBcƒ¨â§ä*–¸MØì„VàP¢zÒYÛਨï›z<° -ÇR1n¥H`ô™3ŽÃ’੆œíºm§sê¼S££µÃ6 ¶Ž ƒD‰¾½5º@þae^ê6B:Ý}/ëÐCs ñifZ;j7e†3h½öжÈ8ä'}À.gDÞz–#^”;f0[k�¤‚WøÃs°B>i­MÌLôÿÛþðƒÃÅ_YìÍöúýþêo¯î|ggöïÏN &ø„|WÐ!gšÎdqØÌ‚‹T%×Ã,Žwþ¨y-S mm@»˜Û#xù¿�÷æ,ùI^i”0¾Zka„ÓNg>¿“šÏH=i].„,%UHŽÎ e}qÌ´ý ˆ“0ƃ m»ƒ’ËKÓ…®oÉ’œã€B°ó27773d$ÖTÒùð¼#xÒ†h l@ÀB…>gÿu#”<4‰…–.¦˜³svÐí/:7æ’äöNr°µïÅ*™Dëh³RÌå«)×FéÂôá1aJ7”I¯vTߌçãÛqw¶Ð¾MW#.Bl!À;!€.èNpQßpÖÕÞÍúy·~‘®69òtfÞ%°#¦·0¸õ|{¶–C3Ú¦×SŸSSSý¿ÓïüYgæWfNÞvrqqqyyyÿoîï||gøŸgÿÑ,ô0L´ÜöôIçÙ³_ Hr@dwÁo†®Ã(aœe…ÐÜ•ÍlµâùD2GPfv#:"Ü‹K+šŸTr‘`€•ŽGuÐ'öRz!4™£åì©/îµ£óÖO ËÍæ¹%SæÓBˆ<Ï<ÿ “º#ùCæûÒ 3ÿ›ÈiWÚ6ÑÙ;88X]]E”µlÞ >•ùOéÆYzœ¹fÀCx\ iƵUJŽiÚæn'ä2€˜`sP"Gä¡i´É­È×µ,Y6iÑî.dKÏÕZ»Ö.2ìw÷9°´ÏH*T NøŸ¹0ôú>‘/•™É™@^’Ó#ŸOñD-nGWZ/(û¹….’éØÁ]Ì'Ǥ€®DÊqÈ9ž*è¼(¢ÓK cÊ'˜ƒ•C“3Èf'T¸$†vïÜ´Á쫳‹‹‹ùÈGxà—^zéÉ'Ÿ¼ñʉMô>ØÛ}f×&äÝð…¬Ÿæ! Š0®¡pvÍ@ãüd÷ ÅB'c57Ú{>â])°ÿLöuõÃæô¡F  N}޲<ywј4²ØÙ·©·NsðÆ<c‘sœÎSN»üšÅǼ 2ý©©©Ô(¹5ǰÍé¡EäÓâ—îNìsö ޵£ÒàÅlÐ)?ñ‰ÈíX‰Ž3ά'Ö[RmD’’çCJnJ'oŠ–*hž½>-¯W*•&Õ2.€Ó–ñz4A)ùä:†ÚHd …g©›Cƒ š^h�´-rÆ€‡SÌ2¸NÒŽð“xùqÊø8ä'ƒ�$ÝÈIP`wúœÖ™Ž>Š¡RS˪·ý³':ÎÞƒ{ݹîíWoÿ+?òW>õ©OÝu×]o¾ùfkí«_ýêjguùŸ,ßî}c¯÷é^±N€)—\ÆzJL0°[ÎùâÔ’ìÞ#GL;úHÍ-0J-h C“œÿÕÑùÄì±|ÉiØZÎ\K!Øu;Y®šî �6É“ÀÂ".SP¦�Y;cc#°›äRÉýòÀs 333™ÝÉcÏëŒvØt!KÊi•3ÄŒ$À*>4ÆË»u* ›[_,6Êü–[Œ´g˜›¦'ç9\Xü} î\@Tœsa BcqÇ`ÓþuéLÍä~¯˜8AQhêAôsBVŽrP8`ö&ét“ò /©ø˜ØÁsÍÐù²Æ<s «ÓÁ…àxŤÇ!;¡äù�� �IDAT§¹WY\p(Ÿ²™”B©Ž[”NÍ[÷èÃÛ<ýéÉùùù|ðýïÿâââÌÌÌCŸxèÿë?ž>þ¯_ú?–.ß}yóK›wüã;N<}âÆõI–íÕÁN€Re-gzãYýwß}÷õë×qQ,=y€Äìüd|˜“šbW¸y¡3ØC—¶Ó»jŒww¢(çççÏŸ??77÷ÜsÏV²ÜÞ½®¡¹¯Æ £WΗó‡À\ôiM²€]ÊùHµÇ$,jÊUrkËËËPŸó²677¡ç‘4¬­­!( Åo‡Ì~e¹Úååeâ×µè$¸•—k8ž<y2ÞØù_J./`'×Ì$RÅRŠ¿júáзìÝçNJ‡¬¨ùùùGyd0¼üòË‘¤“”Wœ'ÑJa’ �(³:}ËcçQäÏ t3aÓŽ:l6 ®z Ûô8ócfJ!×ø”@1ˆJ7χR”ÞÕ’ÇZ¬0èmbˆ®Ö‡‡œcøÉ¹Ñ™ñø¤¬ÑÉll¾1*åÒäé ¨UBÊöŽÅõƒÝÍÝËÃË_úÒ—|ðÁxà•W^ù§íŸÞû3÷Nüí‰ûž{ãÜßxòç^?÷Ü?yîç¿öó¿÷ë¿÷òË/ç€�ü-±Ðâ›@‚ü‚Sft2ŠTA0z6ž4ÒXJ%zî4²ƒ”4“¸`ø©îs’fæ‘G¹÷Þ{/^¼˜À‹ç²9ìü‚Љ‡õà »BÍR5àÇY0C‹££ûé%ƒ™ššzÿûß×]w½øâ‹/^D»:, â MéÐáHWƒBCú å,:¯†ñ ´aúýþèê‚ñ"‚GRH’\gÛ?×MÐQ«ckØð—Qœ‹êÏannî±Çû¥_ú¥_ÿõ_ÿæ7¿I­L¼Í2H¥ˆ.jæÉ¬¦Ìˆ›‘FL§r¦ç)…Ÿbð<4<'1¦  4í¶?VisssÆç!O;1õ¨x“S0ì¼£XcáÈõæ×¬ 9®rŽ¿Ð¡1X<•í‰Hú×äTâÔêÑùMsœ:Ïtöÿíýþ‡úßù7ßùÍßüÍûï¿ÿ¹ï}nös³'ÿÆÉGÿÊ£?³ý3WþêéÓ§;΃»¾ö‘×NüËŽ F…¦L9O¾Ï?‰¬¤GÞ¢ÒQTæ8ÉË� ú°q|³dX v¦!ÀE£›šš J¶¶¶ö¥/}iaaaccczzzvv6³)Fí°=�”42º]¨ÿ¿fñP£ÁÛ˜9ûÖ*#6PaÍðTq1˜ŸŸøá‡~øá[·n½òÊ+(ñä$B] £#”%9A,’‹‰_€**ŸÌºƒÕÕUÚŽñ=ôЩS§^}õÕK—.µÃñU BäR¸)«gåwr8†Fè’‘ÓÖ1˜çO‰ƒÞ%«—6ÃÍ›7766ÒMcéÄŽCÖh>y…iÜ(¬'MR•h• Àh¥™lÄá+‚ˆBae*Ž^¬³"nMÉO-j� «a­4xòEÌ{Úinnn<—sÌ?xOe#™ón òv‹e3ÈI9#ìòäÅZØeùйÏÏmÿGÛKcéÕ_}ussóùŸ}~w°ûÁ³ü¥S¿tïô½wÜqÇ`0øÆ7¾ÑùRçüä?8wíÊ€”ÎÙ©ÁÁ¼Ù°µ†ÁЬœÅ4y,ä¹dmlN|š ZƒfxÐr,À!á„Lvww÷Ê•+¹ßôÉ9ÝGi‡ÝFÿò÷T�Ä^MqPF7Œˆe¬Ä\[gÜöæ‰×W¾ò•—^zéõ×_gJ‰Ù,TW ÛÃõÊ • bg{{™5º#ðИ¢ »:,©óçÏÿÂ/üÂí·ßþÅ/~ñþà¶¶¶RÞÙ$GDIWŸD>ɨ¹©ÀÞç¡íîîâ!M¡³½½ýÍo~suuu{{;u-ÈÓoÅUÝY‹þ€T¹wÞ/ŸF²È˜@VÙÔVL�©ó ‚G¼y¹ YC.…+è¤Õö,€mîOáæ1Î õÉvS=®›zîxÛqÈilàS§NMOO_¿~Ýúá ܸŸLƇí³¢„œÂ[[[I]i´˜$–¥èiòÅÉé<=y×ä«¿ÿê7vïÝýÑø£Ÿúè§î?sÿÁÔA€‚×_ý™gžÙüë›7oÞ„½ã„ÑSÜtàéâp9Öí¹€.GO;”c)†üß$àYô�VF“�mš¼GÙfÉ#(â.ÙÁEæuØ9oQ¼ÇÓ—à„_º�ÆLŠX$ÍÒv&$ Ĺ6Ê™Eb›Ž7dÿ¥—^ºtéRN7Ì2 h¦”G ¸on}²lŽ �‰Iö4ãá[‘á$VcšL(ʘ·æœÚÃð´L˜À�†äáZ÷¥ŒÚqd3Ñî^x=ÐÚ36nw}ðÿC ±}"I9ý@(íBÿ‰³ß“�ü'Št]í¯ÓŽ:ë=¼9Lé.p ¨0H;’XX—byŽ,N“ÔÇ!ç8fff>üáïîî®­­e­›¿TZÊxmº¦ì5ø@{™;Öh™¬"?111qcbÿúþÉžœœœ\ÿ{ë/Þzñ«ŸýêÝ;ÏŸ?ùòå?ù“?yâ‰'.ßy¹ýEĉ+ÙhÈKè]æJ'¿*¥;!ň,Žñðq÷6iD[‹ÓƒfM’€Ì7�q^˜V.4‡Ü©¹yfŠ»Ö1[ÉäÀ@ð¨'$%ÄZïÞ³Og¦ÐéÙZ«ªK¦˜È'£6D‘|¬ßï§åº<ê­­-ž�´º€92Ð!Î3ÄÚ4ŒœÖ—'‰‘¡Y7©lMNN^ºtéÓŸþôÌÌÌ‹/¾m7Þ)¨`ž<§oÖc[á•!L9÷khÞ'+¡#Â`f-¡¦Êd OœXi·pjãv-Ò! Áæ6ûhr“³ *@«'ìè*vã±³S QÁp¤À©C]ÍŽ¢ðëý$ TƒÇ^´q‘!.ªÞãs<?ƒÁàùçŸGºÊÍIsI-xcÐÌã#ÖU8Jf=j(Òd¾iJÉÔ¯N]ùò•/ÿÜ—ƒÁ‡?üá§Ÿ~úÉ'Ÿ¼víÚúÿ¼~â—OLLO`b Xlj«ê²Rí1lúwXs²ãMÊFcª‚ s`tîx(ÝQ§ŒS€4¶w“ß°Ü/ɯ‡`âúë,Ä@Gaaa!ß>77·²²Âf;Ô£ôç´C ¦JËt0Q–Âþ4 Ã|3„ผ°)4‰a6Y#ó“`€A8úZP®SñÙcÜÏRÌâfff–——¿ño˜k@jÏòCtŽÊ"­|>E³u(囬ÍÉ ² rü%*›Ý•#<ÓfZ ˜¤G<[–Ó¹×ëyX˜ Æ*·E–6ƒÆÆ¾Fõ|‹ÞŒG¤´k’íaÃÛ3a>\y6#ð�ȶ¯„ì² ¹ê€ý+;wrŽç' åòåËN'¸9zˆ>%¥Ð>ædñ<¥ƒøLDÎ)f Ïî?ê¾ü?¼<üóá?½ñ—ù—7Þw£ÿ«ý©ÏOí¯î·½·ÉCë“;â`êõz x0e³ ÝŒÉ_öz½Ó§OÇxÔª_\g°K}˜€d÷Os%ÌÌݲÑ�}Ñ¡™dæOÓ°½Ë#Î/¬- Äù@¦à¬w£Ë ryzìd:¹¦%îHNw︣折SñýîîîæuäÃÍgDçªÎÙ@n9fÆý9ãŒã‡Ã0À6KÙ2 G»Ô…8¨Ò-�†µŠ’Ç`Y*ö/ÏãÊs¶Œ“3OŸPYâWµjÉA&:¹ G2ÃŒ0<‹ìˆM*Zëö:Ò˜^”€b4N(%£2‹‡š†JKs;Éi�Ó�!°²¦¤æÆ¡J“µ°Â]CÎ1Ïå¸ïmŸ×d=œ¬QK±´¡‘Ž‹-Õûî»o0\¾|™©F´ÿœO™YÐù|gøÌðâ¿ñõ_}}wwwò©Ééÿrºs«3ì¿ÃºF̘D $³¯×ëåDCM6…vPÜÏœ9óÀÌÏÏ¿öÚko¼ñÆÆÆÃ7$€f 4Ù³¥N(:lJÀ«öôuž³utéú:<p¿Ž.Öü¶ë`0ØÜÜ${Í;ÂUš×JJ ä’ £q…±7Õ�¯ÀÿÄóƒ4± `°ò_3Gl{ï0'‘È3å$E@£&L'ã®騛ø ’§‡Op ztÉÌ N¸Ì�×c‚%t ´àš$P‹DX. %lêu«ÐšWI£\‹n’z0˜…æ-'t!×YnÀà$ûN³Xu¸ö T]-bm«%P– ݳæ{(Ê¥'Œ€–â19Ç@ ƒãÈਵ5Y“ó®G"ØÕ%» ÞŠ.{£É&ÇÞ0Ãápwâ͉™ÿefö3³öL03–Þª3eŽ•ž30Ôüüüý÷ßþüùdÜ—.]2‰¨ˆX“êFÚU’µr 3t†3µN;Ô/@¨ÔÃVó¼c ‚”´›/ é¶ÓÆÀYœï9)0·%;™à[¼ëóɑƱ{`é ñ´Sšäw2ÏÈ€óL\,êttŠý„·,à=êoŸ7U*Q‚+Üã¤æô›úȦŸ”ÿ{Çw|ä#Y[[{òÉ'£]”ü&?zx¡N ®¸ÿO ŸÇÂöô gQ ÖÔpÅ,€^¢xY{˜¬»4,ÙëébLV”Í[”lšüÝ"¢LOAVÂL¾Î.<1Oð�ASC£ôÀ8äèAJOÚ Ìmm#þÆ…Œ•ƒq{03¸Ö‹/¾•  lÎгñ¬²«•vT&ÄØ¥ç1ÃMÆÜè£r#ôÏ;wöìÙø•ѱMöFrASwŒªAú¢ë‚=ci"tïI7@< ›RÒÙ}Òï>¸…qÃÉ’Ø¥žó¨¼…<¶ÂùNîIåWXàn­»§ÒòD!øFœL A…7l–LŸ'PÀzKDS£« ÚÃÉk \“ƒr;td ÓDá^¯w÷Ýw/--A)Èíè 2,vKÀÏÍÍQ3qR„£òi¹«jtÔ*mePšÕË9É ÏßïJ˜÷ ÂN…dúIqÒ²b…±2ö¿´g€<ÍÆât¾8Ù*"Rc`íø{9¥Eá>™>³`ì[Ïôz^§88q`§|ÃyG5øK4$�d(Òd⬶ .œøE—ž¶j‘Ú¼råJÛWWW³Ü³E©? ³abs™¿‰< {Ì�ñàM’'©/‰âÖ‹äâ-R Uã•ÝËùîyOòzº E]”èBšÉQ@Qó…hù:Sv iaóH9Ã=6÷ƒ~⿱è*S¼<à€.б¤óœYkkk®Iºy&”Ä!€n]ð `ERµ3|óæÍÏ}îs[[[¦êBq¤Ç]Øf 7)¶èV¯4ÓÒhp3s„ÂÉ$ƒšLzf2e„Mx¤l2ÂÑy»-$¨¸ çñBð³5C*$3 °Ñ3߯uubZ“Æ!çØ~@Eè"Ø‘ÅÓ‹yf³¢ÉP°™&Ø߈קõÿ‰f²1•3=d7 �äå-–Uhf9¸—––ž{î¹ååå¹¹¹[·nÑHït:‹‹‹›››è¡¹È`sB¶5ˆ+9'V¦ ó@Ðb98ú“O°îýè4{Wí¨oíoé<–”–œâ˜³Ä5XßhÑàRÏÍÈE<uÏRÉ›¢:qØãe«$ná1J Šrq3Ê!DV5ÕIYQpó¸ú~krA×1ðéåË—} 3ÂÙŽú’¥Ì…*N¿ømÈF ‡lÆï"©í–›¼ ¢gárÊ%…©7(!‘IdŸòçÜQ¤1"šNzDx³ÂÞ¨_çxïK‚<‚ÊŽûÇœâù[sÚÓÖåÅ%ß=.‚qÈi°k‚8“ åM3sàÞ:µ<ÊİK½[NÄE¶(=B Ó¶‰‡8ÑÊ@M{[ ÅM=¿qºM(sLLLÜ}÷ÝçÎ{á…®_¿fMôElÍ¡ÎÔU†Šæ€ Wˆ�QjÖœ> óvº4_™ÓÁ˜gŽKƒìœìnõ3Ä`[­Âé¢jɑǰz@6Î,R úÌF ­_l]Š0㓹fšð}MTÈs³¡‘õ¿ËrÊákh7ˆŒ±Y–JÙ)¨ Ùë¶j@3„?⎡—•h@¿<ŽZz«–ù(æËpK†öžÝà&¸éUjPƒã:jk;Jô6ŒAT&¯²¨©­Ðö0n cJ¨H‡ûsÿ%Á@ÛÐ.:ÜãsÌUN¢›$ ‹¦¨ÍÃ!ȬÑ7†Ef€»Xõ•z%#z7aXÜ|µ½‚A³ Ñ£¯³.Ž{*Ù?›››Iš@ƒÁÒÒR& ‰$˜¦œY| &q<5Á¡xÈ>í{íÎ*P>tê¡&�bø‰©Aùº@@Ê0±¢I|>è¥rEjÚ±·…"Áb‡lÒjËÝñi´%Œ™�U¹mnV}r_§3 ³Ú\C�ö:q6qÙK—îkqÏ„ÙtÇœ%ÄÚ­Ôˆ…çM²âiGƒ«VÛ$<¸&ó‚0ô,—Él<†¸‹÷Z“•§£ND (ê8ø{fP܀ܙ ïhÂùYòw|Cµ5LjPaÜË9æxƒú–“tW�¸nEZšp–vBjX³õÍ2riÂÊó©]:� QÁ‘»pcÚŒ O«q+ô!¸ ÂØòòòêêjÆ&ÝæÄt/Ý›§Lç¸#ņ´î¡›¥)tÜÕoš÷täó#b$;q·xËs„™õ˱e<Š P²uØk¯Y«”@ÈyJçƒ5œr  �áš Ç!ugÑMyW*p94,ÑEk#†i<F0´B^7»ò7í÷R¾#Ži®„7”±J»"ÀÛ,|ö¬¢BÍY“,: ’ÿyx¨ˆacZ1J!Aˇ®{¡­:¡ñ<57‡ú7¦ÅÒypðšGǬ´Æ†Ì÷t-ïW?9Çö“AHêzòÖ¦Ö %E…óêT(Infô@ÆànyþÀ•Š‘qäËØÀô‹÷»‹Škëîäü”Á±m¡Ù`…Ýklbs±Ñìt:”c#Y_ÒÄeçÔ¥Ùƒ]n6سŠÖ åvòpBtæˆgJ‰:•â ÿ°¨Ï_*W#‹d<g\ölr“z]VLOdJo¦à“½^¥ÂaíJ´t;Nô€ZL£sÉg „sûí·ïìì„0‰–þ5¥-ïÂ,®íHÂ<~T¦/m>Æ÷'øÑ•óÑÅ„“xó–3GTŠzÔÄ–Âds{ƒ5è-ž¤±ª+ À3·À¨5Sœ´ˆ ìxŠ“W,×XœõAб$Só³³D·ñ\Îñ·s(k€×°¯7 ~A“[Œ'È {mnn,§<4kͲúIý²žÜI†ö Æmy;D‘#£cÇdYwPM§6mY'.Ì}r7»ë½• àj)øû伞QŸµœ‰ñ½¼‹<O)qð1_R¸ËÛÛÛsss —I*‰ÈS6YÏ?‘ÕšnÚ»^dz”ð¸ÌŠòlíâSʲ¼_;D0¥ÁµÁhGï‹D›Ô?MWmll2õ‡‡‚Ϭ1xd§&á×R`•œ=q…eŸz¢Iêɸ uvŸ²ȳ3EŒP=kn›¯- Ù̹£Á[ßfáPä¨Ëq3{IuΆB!‰f’ãÓ>‡¹Nê/-�C×a�z¦±ä²gff 6°œÆ½œãÇÖ,¶o—\ ö :²æ&AJ¡ 6…ÆÊ¯¬ «“Aö5 ¿á\Ü6¤É%QÑÛ†k QdÔMhFFÌ‹õr7&†ÀAé'ÙˆÈ3¤j¤ð*ÒyøpÍ­îeÏ«v(öƒ¼·iЩ¦ñ$)ËØ½xçììì@$K‡UZPN,€II¨ÙópÿüÒ= ½8Ç«¥ÏÌðFmtÛ :®T�›Lç\(û"É -·C!em#rž Oo(hB+>Ã*0�Z>œ¿IñXk¡2šml)wð[0@*›ò!ÀžÙ†EKЀ¹éEí¨5ª ž’UØ‹ø“ÿ@r‰ZA“_MCÄĶ23kbÑ1L¤Œƒ `Siœ€–oò KÞšv4@AÈ™ 6Ìí±†‚‰s|äˆDL%ß­6ÿ°×ëÝvÛm�ü§Âƒâ()Cé ‡ùWMš†vpø4u§Ø9´ØMÀ:+ñpe†<0Aiv›ÒiÐehR¾É^Š]›m¨< Ií&¥Ô\¥rå¾ò òQ³³³‹‹‹a Y·ªÉ’æç)OÞÿY~¦9E:57Ä”nŸÑ½£6° ½ä9Yó•-c3…¢ÜÓ¤^AùH–mo4²¥2Ÿ[Ö¬Oà&¯F°)r|‡[b Ïœ.HÞÚéÓ§ï¾ûîhÀ&‡¤ -“¿q â•@Å\–Y¾ÈíL†(ø ™Äojƒ!q#äÐèMFp]k– ¼YskÒ:^úÀ8ä¼Cã1½Çi)sK •ÅóÿĤürøûhuäÏY©YÖ^fÊAµ‚iÉÖétî»ï¾}ìc÷Þ{/‡{Î÷¬ÐÃH¬lŒü°W™JƒðÊZßÙÙ¡>+}ZÆë µC¡C1Áó¼$E¡%=Ú¡s" ï«8÷ä`=uêT¯×Ëód“£[êvw¾:×�¾Ñétfff˜Á*“wÉj1!m­<yò}ï{߉'8k€¡2ùHëÛÎßîñòÄ÷û}gÄx—¡ºO€ï¥ o‰—ü­i-@Grc^N%°\¼–˜4ÆkTKEäÛ]Ýh™›››EäÆ0QÞ,ÿ'IþžoÌËeø×ü5cÅ”ªÝn÷Á|üñÇsIòLˆý8€°Ëü±í¨Ufñ�ôoé&&&n¿ýöÓ§O›ÝÀòÀ¡ŠÍëj›¿wJJ±kiò3Š`«_³aíâ1ÖŽ?ê�Ô˜ÑÈ2uØ>CÖ<ošˆÎ1¿^²Eè�.8<lAû1)ÕÉ“'cbÿÒK/]¿~Ô˜ƒ8è9p9Q‘÷ðQè¹e»êÒ¤5ÇÆâÒñI”N5õ"¼ÂÿÉ ¹ÇŒ’¨Zž¼;•Ó]wÝ5 ^yåS;¸Ým®šgÝó¿VHƒîeÞ´·\ÛòòòÚÚ] ¨Ê˜=PNÀëØCš`>ƒ¼˜Õéð- ‡ü&¥•¬  KBN1¦„Y‘)×nØÇ`j¥í(5”ш–Â�̪°[(+óm¯BqÂÈ?±’ž[#p¦žË/_¸pᥗ^Z^^Fõ�v²+‹ušVãÓ� æ¬Íæà÷]º%X®®®ÚaÝ «KX@øÑ ¹áWF÷ò™aôû}c3`†ÐÇ!ç˜Üœ§èñà$/µI š•²è@Pÿ73%ô6©®šFùßp£xàÁ`páÂ…K—.e< Ä�/w#,µdV˜Ç˜‹Ô››+…[;ÚQiS<k-m‰îvTz¯k£4£]òý|àp8|óÍ7¤ç+öõÅšÉÉÉíPuŸj,ø^0R[]sp(»!—ì;·Ÿ|Ô!‘«@˜À§an¿ŒÐz²ÕkÀq×ïȵE™owwÝš®>›Dà ¶äô̲)» ÓâR—9üQ2¯¸ ¸¼kôö.¦žEË"ñ0#1Æï‹muëÖ-o[¢K“{H!î›ÊáEXð(«è–fªÉo†‘M;õ"Ô•ávTùÍà°[qÓ¢¿ÐdŽU´¨-ú99ÇÌ %´÷¥ë\³ ¬ØÈ?)ŒO³l“—%_ÎáKÒÄBôçD e þêÕ«€æžÝ1ŒÆBä ,¾2%k.~ò£gè(L”.:Õy(§'tR2D7½M]+âràÝ<a ²l¡ váƒ6y2zz‘ç`ÂÊ›V/¶Ž–y €r ÃsªŠ½¬Jbi;.æž'| é¢[ÛŸá¿™™™õõuëõ*x¨Ë÷e¡°Â ³ÜŠÔöª Ô JžìLÂkÝb—αÈe\Ѱ’gæ9»QsíÈ1qÆâ¤Né˜@ØÞÞv³ÍÅ#\PÑ v‘P¡–æi"[ÀÈ6ÔÊ2(ãÇ—ÄáØMCè6B4‘ÏCH>¾Æ!ç˜{9à-PŒ@W\P³·­ÆHÈa¯z¶²rÙÀÖ `e€ïÙm |ãÊ•+ r./LÎ’ ¹Åê¹£ ç´£ú`„ofOÒ±`¢¥õ]—P"P'„ÈÑHc]¨kͱ!ý•¶Â7ÑË>FîÕ|ó{!ÎyrþY;T@á-·C}6̸X6F¤”A´”s…:Û(.o”Æ¢Ý`ƒ!g9ùsFƒ!s—0PÍõBœÈ[–ÍýjÐ`Ò £¬YÔ”NØú@›F›v7$‚ .æŒeêÓ4Èž ãú³x2= …‹RÀÙà�\=n=4^‡‡o˜Ôè$^DbO­™îÖKÆ™óô"œtÄ?¶$‘Ïa¬Øåe"çÕnÆ!§¹Uh’å(¶cx̓ǎ&Ô6|º€(Œ&w>88aÑjtf-—'#ÀÔþðñ=BÏV´Þ³Õv)Û)}Šf»§P-’Ÿ³fnn®ßﯯ¯çú;-n¾AòN.ÏÌÇÌÌLà)·y,PæòË(63š«æÔ!l½ãN’gˉ§) ·¡v"�� �IDAT/Ö=u-Ùcí.nЬo!µ{B0‡ÒŠÒŽ‚±Í€±¬OhaB7 Íãôˈ+ 5Ù�V›,Î’‰'fØ ô¨üË”zIéàqØÒ;WÈ{7ÿÅÜBsL 3˜Bfýw¿ ^™kî<‰½ƒô"3.í¨ jòt=Eã<U F4Y€Û£ØÙ9'n²„àRMAb‚{l^ð]Ñűò>X+À>.™ØÏŸCè÷û¶L†—Y¸•ež ÈÛãl`Œˆ+EÞƒ|¼˜ÙLMMËûhP7U¢Z±˜$@2Í@6ûÎ4?—,„Rb‚k…ˆAx0¶�¼F½gÌrjèÁW•&g#Î;»*xŽÒø!9á2ªYÌ»<³IÎ@1 'N ÷ÛPòç.X‡Øùx>”Z§P S1#ð¤NqŽ~Î)Cè–š É-XS‘cpĬ Þ>„^ô*êÖ|óšDu°É‰<ØIoŸïâ®yþ€Ãö*€˜+$þ†·ÃªvÁ¢«_k“¶´+~3ÓŒ…$UBX¡ åxZÈ>=Nމplûº²þ7ÞŒCN+ø’qRŸMw·½ÕÉ< —#Œ…ŒÉèu=Ç\);ø"†Нš÷à^ŠsX© ˜Ê¦ž#Êc¾ÌCžRd­ÄǪ2 ™­­­28i‘GÏE¶‚3ßp"ç<ŸSú™ñ¤AÒäA—ÿ„>&³ÏG+Që5$%„An;È&I4Þ,5±YN Ûy9P•2~Äx˜�äF,Qrd\³sÃòúòˆ|Q³–ò‹ÿ› R@KÔà,!¢ˆ=‡L6A�•t0É|žÍ@jÔ ¶  bÃÈ'(( ê<‘Üè:sÁaZ«F†—úý¾„… d£«k›Òä4ØdPÄ@›™™Y\\ÜÞÞ^__÷ði1ÄÒUà8äç÷›å°\F@.›#8žm ×™Or—(,L>Ùþ›¦ ”Å:…J´vÔà–q�:<š,oG5µò™1r?sæÌÙ³gƒÁ¥K—r:¸MÅ>A &t 9EÅôÉ *–³ƒxä@‰ë¤á¦°N‰d !Fç1/‹i ¼P‘W02iGmީϬ¨8Š’•ÉÁ<Š70øK¢£Ï¯TIö=.ã2:S–.’µnœ¸oaMñ÷—…çâà£DS½£D†¨—.ó=2%Ø—;#—Š^Žëzû\Œ'ˆÆêœf9ã)VLüC`ao8àœ<À2[ãÂÚÈÁïѾ Í,~ž½^/$ã„mD~)î)ÏŽCÎñT9ÎßMWeª./Œæ6`Æ2µŽ=W8 ÜäSŒ~ ™¦Ö‹ôð9„«Ñ¥c‡‹s|‹ûb±NƒÁ®'œøˆsäid®û‘G¹yóæµkײî‹þUÉß¡±yB2µÆ(\XÎ 3ÙÜ䲄¤r6ÏæÉX9»›á(|‡- g!nÅYlä&õßÑ’®À¸“Qq“…ä{“ìC'›!)É ‚Ù2t’$Úrf‚˜…L1Ѥ¡I0O7k)Ñôfä3#ÂH KÚZ«¹*ÞN®­×ë-,,lmm!‚¿4qÆ£rV m‡6 äçÉÇÈ#£©¹*sd·�(ÎMY‚çlQ7`€¼�èŠÍ ¤j#tßÝ?£�bXÇ©p^e®ð­·Þ²Mƒá  Ñv8¥›þ.æOã*çøVC!]‚øk39&ÛŒã<Ä\Içzž‡wƒiN+úÀŽ @|šô:QOÁJ9ÛÞž… ê˜×FÄíiJÒðÄÄÄòòòóÏ?vâÎ1 îÂ+ âh&[hÄÐ;:à–˜W™+<yòd´ Y±Ú¡ö»­ŠéNѽ~×ù Ÿ>Ü…-…œ8› Çb#”æ `ÀÐ̯¦p)Kíë®89J†]·âÿÄÀ¬çEÜßvöÀª.v;*²‡[D<`‘3óoÃh&íPðfzzúüùó?üÃ?|åÊ•¯}ík«««¬ê&Mq7Ì |TSî~;*SmÕ;gP™°ËH/1zÎ(Çí»µN É–9«ÅÑLŒ¬4a’ W¶½<bÇe5”T¸T`ãsœ!§I»‰å•3Ê–ãuÃ6Û‰¥à<AŽrXÀþr‹˜»ô-‡žSÉ:¾Ì÷´ÃaoË®¸tpø,G¡§XLŽ0mzfffuuussӫߣùçE %P’Qµvt8”€GŠ—Ñt»¿ñŽ3“­Iþ æ®!r \rÙ~tû=¥TÊÆÑ9ŒÒT#<ƒ&ÓLþîèNm9*KÓÆ ú,?'LO±*A—êKl/Æ‘22€c&º5–l*aj¾íÝßÎO²¢<¹¹¹Ç{ì'~â'^xá…ï|ç;[[[ØëY³¼×¾|lO'|å j¹ËB¥Ý•÷ˆ¸™kË®—|¥ê3+N4¥È‹½¸sQ=v—G°ó LwÜ M@7¯Ïm\å3°æd«¾¼ÅîÇ�7“0¾Î°1+ÏÕ·]Iš”ÌÁ Nž<y×]w­¯¯ß¸qƒâ†yÏXdœ <àÀ¨È<,\sHlŽ[>$¤¬ ¶83—!¹óþþ~üi3à`¨Dù %L³Ý{ƒÂ‚AWû�ï4™:Óáö->½±±Á9KtirõyÈe€ÚsG%ÀØ=ž[½^/ÿÖ/ˆ,›Á‘\ÙzD<¾ÚdƒFt'£§`ô………sçνñÆy#´‘‰…b³‘"# ªjkPúxE�4á s8x3ooo§»–,+z ÔÁ)‹ŠÒ£§òôÓOïîî^ºtéÖ­[ì/vSd¼é…0„„zHQ¥¢•Eãgzz:»æºUs€é©°2a£PÕ1©ý…¢» ‹±Pr$'˜Ãk²Û`Ȩ3¼v³ê-WŸãˆ.&·`Œ=©g׸—sœ?À÷�ú8Ü$C$·b?—6Â\¿@gVi³#:Wøt:Gyä'ò'/^¼øÙÏ~vii *ÛL‘×Cì6*BÛÉ'«ßEU`¹…¹oþtÑ]·<xNÒUcJ$€¹ªœnEu”&ª NÈ á10;Ž—È õ_N”Ås b=:Ï‘%¸±„Ê;Ì{œØLº<®&©Mƒœ…Á­%*ä¬G-iÁÕ«WSÄt»Ý¹¹¹ÖÚÚÚšG øR“tI™Ã3DÁ:¿œd", Ú”¡V¯jÏÁxh <€þ(Š„,G𫯾úÖ[omnn„È–!jˆö&¢ñàRrî½£œÔ$VfÝÀ Û…û{C2¤\Λ"¶èf¿8ù0®ëì‡UJ '¤M,«ˆø½UˆŽ'¿ÇCæ\ò7¬—)Ì82ŒŒ¹Ôµ ºÁîd+++1ò‚¬•o‚²ÝJèógA$ñéÈÊ?´YÑ-eÞÅp3˜^ÐÛQ])S‡ÝÍU1‘`ÛGÿß"_oûëŽZWÑìe·Gr ©`¢~º8¼NÏ2ók‰‡2pïÒGñ À–ÂæðÏvi•{ì÷ûˆæÙ§Òõ|QàÍÔÇ?ò#?òýßÿýÓÓÓ3‚ædpÕ¶4„?@Pe7öG)ÂMjǬó|ûîînHÃf”ÐíXð‡Á`°±±Á° …]qm 6x"Ê=Nkñv\L€[”©'÷ÒueF•4™ØóÜåh¯Å}8êT$”XNVjð|·ir]’Kf¤œ€‚ÅAIg.B±ã*çxBšf¦Z•„½U €¤dôßÉ } 8Íxý²D²â_zé¥K—.eŒßI´Ó½Îáó}æà{�Í •„‰ªÞœÜ;Bp¦„±uÙü¤;J3“mi¯kóyì¶b²r¡öq¬À °¯¨Éµ�V>¶*6!Ö69ùê(ÀânêZ¶§0ŽJ§ ‰i'†º� IùyS�tfV^ë)ê™$kkk+++˜9Ñú¶ ·™è4ðÍ÷6ùKr`5)"“*Ñ;´þ¿[Gü&tjtÏŒ\µC© —|¦É8 –§W«±s¢€^oe&".™ÇÔÔ²…˜j¶ŒÓFÐýKG (báôôt+9:(-`Ÿ}DœÎ¦ÚÖëäáгIܤVƒÁ ƒ –¶÷r¾+O *³Ë.÷ÙÉ ŠTü0 軹°pþÖ­[M2bƦۈS@;*ÎÏbÊœŠ‘œÜ’hl˜€¿ÉÔ hîÛe ´.I–;Ý£*²¾.Î ÐÁøË(õ€§jE8S ÙðîÃÛõ€Þ#ŠÄBðü=óE< d ƒ ièŸf ’Ï…ÍÎÎÚ×™sÍ¢ç3€× ŽV9`È!ÂØÒà-½¾¾þñiêPMÙíð×Ù†ÜÏÖ@é¹ÕêÌÈ/â= ÍĪ2MÌe“—àgã)8`±; <kˆ¢¢[°ÜCð‚mÁ†¥–Í??qâD·Û½|ù²qd²\©�gå×’†zynl@öH2›vTh Z"‹´’Š%TÖ÷b ."X[[[£Kãs< ’)vu;ªTÁ‘JZWf9›ØXv`Ùnî%{ÊŸ=GÍeºu†ëYÈHtDé?A[p'ÜV"¶3 X¡wU0t*û‘ Dæ¹Q0=rÃ0_Áë‘QU7áÆµ)éþS÷ù. Mø£–{yha’¼ ÒLÎŽ2lhŠ0Ó Á¬h!x ;>§çípŽØ"ë äñŽìè ‚"˜V6•( Öù}÷?èWC¾ð¸«çX=µã©ó‰ äÑÑwHjÅfIà_Ç•[²›1XóýXºNõ°Ë¤(ajÕ\|>("iMxƹ`ÓOlJ›²ººZìŽÌ àLÌõ¬³°“=­ dbw(”7yæyª”‰ÌiÐgJ´#CšM±^�=ê`»-Œ«œãgHÃ61ÑžÜ<‰ ƒ0k­›im.„¥Ù< B@vžÉ În!øq=E˜9[Ý Œ€’~ÎÌÌ u œŸ rLé”!˜&c‚¿ûŽ0°Ý¤"sgýO(Y8g)nø:‹˜\n}I3‚xìè3rôÀ‹õdUéç;‘oRxc~²›Œ£¾«­=×\^µ,qÂh!Ícóî¢yüÂͶÑ_ð£+ gîÖ •rwÚ´iJóÄ9ï2êxƒfÒSH¼ò.zH¹TZ@¸Î·Xüý~?E^âeĪ Žª¾¶££ÄM®Hf3„ÑcE"»$@r1Á‡F“ª–á\vG¿ß§…Cª”Ç 8oí»qÈ9æ^’ŽFxë¶g.€õ¨8œàĤB _ÐÙÞÞÔ ÜÁ×™ÁI¦Ï)odßð…[ŒYÛ €˜ö>5–gŒ<Éi˜-.¬ç%Ý& Rì>íR†^ Êq–Á>ŸuÉ\Na0³¯Š,¬ë[[$س#ÞÛÖbÈWäY¥NÊïóX¿L 'ȑ҆ïPˆ–wP‘S54ú°ÎÚQw w×<ùÛÜìlD-ë!VdÑÌÌ òµð¾xe„R¯FèU9îÓá(S–´¾,îà™Gú’ª0°8o^M<úXf êï*%e‡P†ÚÑíZ–QYg!¶÷†,ç鱬I04²Šâç me |nÚ#ÏíXç@Ç!§Ve:Ì®b¼TšçPz�"ø_†K² èÒ¶Ž: àüÔÜD9¡~Z: 4ƒê›ÝN Lì ì{ôض£#°Zgè °c u­( Ò©6C¬L3¬ l9ÎŒÑA `†V,®T‚›õz½°9¯))f ó¤¥E³9ã5H$˜‡´V¨htÁŸæÙ’»È &Ƀ™>×hË¿‚à@Ž¥¦S ³.ÁE†óÉÔñÈYyÁXn‘~é÷ûy­ Er¼Ò5 xSœgggÁrË<Ô¯Phá¸@g0Å„xÈ9•äFð`ß Hë† HI6>ï‹gBÝ(¡œ£tjYÞ]"´«1>$Xbö‹› ÇxØŽCΑ:Ýé!Y¤çÃIÕƒY»¬ËÔg›qˆrö7jÁKàqÞÄ¡œ‰"¡ùµž]ev½°3}ý®rXÁѶV ä.€iëyp~yW*B–9 wã8`œŠŒ.LeK•�oæ/çççQª·n3w”;^pì4ÑË\ô7ÑŒi‡ÂÌ Eœ˜ðÑ}‚·£V ¹$‹C£Ðœ¯ð 2?ØÒ«~S™bÜÆMoÀLtP, H_šœO0ÈQ¥WO_Š* 79hZ)fggO:Õív777ÍU3·­ŽT»7IÖŸü y7z3Ö50³Ëó4|QÑ¡p=mL˜ote—‘Ö”:‰y¯¼J23÷{Xþ„âù]<¼ÛQWÎWøœápöà›µG¥uÇs9ÇÙÎ1+—• Šm5L†(³ú‹¼¦{ÅþçÉ’š››cøŽÆ&\‚Ã%î yÒXUÿ-óD¾Ì¦©·Q‚‘hvcé¾ä’|›ü+£ü¦Ì¬°g0Ç,¦vÔÅ’ c6ô…ë<99yöìÙÓ§O›°Ë<Jvãöö6@h‚½­ <`”þ¼±k/rÙÄZŠx¶™àâ‘ ÛÍV+ …äOœ8qÏ=÷ÌÏÏãÿíkƒnàhäê<èj:ôlì5àNVdiºS=!�Ÿ>}z~~Þüò4 )HÆÝ®÷<¿s#J[‚d.Ép–Š¡äå7£` ?›°˜åiÀ•°^n%cÿn†Ù©ÖÑ"ÝÖ}à «è1Rؘnvš× VQ¼9jqHR‡œc9ØO±’FÙxüïôôôÙ³gï¿ÿþ……üQ²¶òcìžOF+ðäÉ“ˆ^ppG#¤lò ȉ–ÆI\@ìíQwÛ¬Ý,M®–ü”å ûÙÈ;ß]Îb†ÉGzQ“,&fW¹Y;º7–Ã÷öÛo_\\L›”“P"[k{{{ccƒæ1`fffzz±5 Gg&7,„<{ËaíIÒg˜jç§L/VñÎÎNÎ,k{3ȉÑÀ}÷Ý÷±}ììÙ³¹µùùùS§N¡rM–ãùSÐ3Îwt€°Ñ¸¹Ú¹Á@XÑ ð©m³¸|à£>ú³?û³=ôdn€eçø<Õååå­­-H7¤óÔ‚X¯Ò¢b3}‘xS4Uyk¹žìÁà¶™wSËÎv_Í t.uvv6†é¼ö‘qæDeNIã¹sõƒf]T0@bµ¸eÝa> ‰Ò2;8ÖŽ¿ÊÉB÷ñ&CZú?;;ûƒ?øƒóóóú§ û9ª$nÚÑò7nÜ(#2áÄ Ì!zp·(L¼¶¼ ½‡0©²4ƒD[®ß9,Ú¡Þš³'’5›»½Y¦^Ìð.Z„P³PD}Þù Eî.äja]‡Ãëׯç)!ð•w‘ú Ì=“|¨Ÿ_0ê2ÚÛÈ£.”$N Þ©q°³ 躷£s²Ry¼ÖÝÛÛ»téÒúúúÍ›7Û¡?¤\žõ¸øð=ë¸pUðèN‘I´C×>Oƒq ½9Ú—Yw.!]1‚§?9Vž§sT\Óž ß2HQPèõzœÔ¸®qå9ëëí,’ÄBM4*ôqLC%¶„j¤BŒ <R”;á ² £R¡•EPg~.e:Ì›d“²ÍtÀkÊóãsüñ¦8°Ù©7Gëlccã‰'žèõz ù†ö“Hf €sF¨5iÜuȆ´d�«Ó.�Tß&h%åñ<'çˆuäÊ`¼‡^ ­Ö²ìTl–Ö6›¶ø�ÌW`s299¹±±‘2żAfîØZR,PÔívWVV(JŒŸŒêJ˜ hÐv”Á¬nçÇ• Žr¨iQ¦xþ%ûH„"‘a‘µµµô6B£àÑý¦Ðtˆ§ ß\1©´‹bÙ‚)C‹tªÛQ-™ápøôÓO?ÿüó›››afºñ™Û ø{pl{³º“çÖ¦ItìDnò±faÐðp aã>™é¢X‘g‹‰§1L?™kP€eóE¡X7—,… N9èÆ°)6޳iQjcWÐï’4Ýot‰E³ |œµ²²‚2M{·ývTÓ›°àéÜ=œU—ÏbÚBPª›emGq|p°ú‰C>/H-˜ÖŽ*ê7ùú�…[ŒÇn"?»ýƒìÓÌ6ñ›ët¢`-Q wÝ8ù]Ù7Þ#“©ˆsyøAr|R[Ï‘íò«…ËŒ\q^[ ¶H’˜Ã’@BL_\ŠOœ8‚¬%92˜jÈ/žj²6sEÖº§?oR;Ïjkk+®nÎÁÕ´ó7€^Qßà¿Â>€‰ƒHÛÓ;˺jÜ‚‡x›ÌA¯o»ÊzNlF�d<öK6)y¡A¹òîŠ!l¹S3qü¨]*åvÈoÊ �üU6—„2Èá r< ú]ÁX+¼C›MLLÜvÛmÝn÷Æej¤4o)Œ¢ïj§ƒ¦iS¦á(’˜zqþHbÂè "n„{Ü qŸß²Ç ý·àN>ÊùDÔq¢teÀ|»Ï%Þ�<|\Ìškšp¤†³iBBZ e (:¼k®z«ãk“Я,G°•=ã`ê<†Ÿ˜SxDË—ßç\£Ed¡‡vÔú¯ÛíÞwß}½^ïÅ_$xç” QÅH¢2O†uèS˜êœ|œ$†ØP&«p›EJÙäF“_¬V^¡É8žòÊdä§ Ja‘=¾´×ëÍÏÏÇÛÂJ"ˆ 4i!Âà@ÐHÀg“k@ˆad6®Ò¼DTñê=cÞ¥ Ù}¶´(T[‡7kÓÂÑXðæ»âÈG|ÉÖ×׳Ûûý~’ý¤ää­1Ê%´TÍš@®9žìž òFÕUÖ ªˆA`|faYh ‡iZ—6o6‡T ';ÜÆŒ2oÛ¢X$}.%îæšã[LMÃa„ðÍ’ÒX6aÔ=$¤V88:ÉIê òBÞhì{–ÂS“¡<™ô(­lJ:Ó œc¤"W ðÐ…óŒ×ؼŽ:¾/ã2A¯\¹’•ÌdOʲô ÊZˆ³ ¨…o¾}vv6óí &X¦ÃšÏíIžË †}¦“à3ÖäUH´µ ÷êÔ¥À6,ýNÜ£WWW „Ü÷‹Qq…[0ÇêÛæu£%, m«<çë¬(÷›Pmé?:!ÈxÌ™¯Nð³¿"™®¹‹£®¯ãs<U"ŒPò­±ØívOŸ>ýðÃomm}ûÛßFƒïÔ©S{{{·nÝrÅ i£õlʬ>Y¡õžGÞœ ½×륻žë‡äñ̵±Á| 3•³dÓ7¢kÊÑl¾,ó‰ípN»x¦‡¿±±±µµ…”:ñ#»Æî87‘¨¡´ÊFL¢ÄH¹`¼;¯»×ëÙözÂHcà)øcæ¯gÙÀ 2‹Ìä=ìðËÕ:§ì ííÑ^L­¬œ ±[[[œÚ¶jö[öÌ¿oŠEŒ7Ë–x ÎcÁi8„Å•£Ìi(ÛÓl¶c#8“°Ñ{ždvŸËÜvT‘/³ì>«£¶CÉjdt›ƒ4_A­BÝ´|‘'p�£õvõ ÆîŽN &k‘ã6™ÔQŽ“V–fji5CÎñôr0¯$#À E&¼¨ßûÞ÷~ò“Ÿ¼~ýúK/½–}Q…ñËfÑ"ŠI2&€PoØ!–Þ²»‰=|zZ¯ºŒyç(Ò­ÁCŠÍ™7Ú,�6¹Ç ¸+ùüµµ5sð6²8.¸íCà#”ô.¿ãóâ$μÔ|x8o‰pEµ% û¼‚………Á`°µµer¦|¼µâ³§‘Ud;ð2™kÑnø„ÎÖ­/àÖz8Ížš2œÂ;e):µ"+rÚáÊ›uÒäff¿s{«Û•ŽÐ•£–ÃÚÂb†ûX·P¹8R=i33– \7‚ï@1H´“,|”„l½JèWËnG=¿Û¡ê¸.[†QÐvÔM˜WXÙf|XQÛ¢Ge¯Ù… ÒŠfdcÔ‡œwr® ÂFYŽQ” i­Óé\»ví‹_ü¢ùfíЊ±88±,`ÓÛ†¶I—š5Á é<N„}"8õcHÓSi�&EQ“Jxtþa^¹‘‰‰‰ÍÍMÃP6F´€ÓRÊ>Ùˆ"%I7˜Æ $ :OœïxoÊCF½ç<Sbì΃í¨•H~3— sýþûï¿qãÆ¥K—|ô;ôºÍÆ@_Q^±x% \UÒ"*Ÿ|m"±Â£ã·s[²†dÁ{‡((ë“WyŠ…#Õüb0„]R·”ÙAèželž%„j_0À™™™àK¡#–Sø>4B(€mÍÞtÉëƒÞ}J—§ž"°6šU”ìÿ”ǵ»»{&UÁ¢ÐÙ­À,{ÒÖdYE?—}îêæaÛQ¹kBþ8äÿ”¢3èt&5x¬oܸã[.ŒÞ&-Î">VÎ4QX7>ÁKQÂ)977çg;ªÓSÈfžÉp:ÿ®¡—Ë1òñ>ðïùžïyê©§nݺÅy @þ΄|鬇:(Mæ7£òãvs&º]œ”'©&Üém“Šv*`QÎý¹¹¹íím4äI‡ý‡~¿ÿÜsÏÑæUºGefšº &q@ûs§H Ãô³P·[Öíè´¯#¹½�� �IDAT „F0[¢µŸL)iÅ]¦I‘JæZ¬ÀOõL_‡6]D6Ãýcììì„EæãÆ ƒ½l¼GÔ9iìrDdå䙤kKt/È2ÌR/%‚C];”–Áj,Pó÷ÀŸyM)¸­Û̓äDã$ÿ¸"|W='H"%}‡œã)tx7æ’¬UC–åx`5ÊdHR÷Ñ…Œ”ªIü|<Íå3òS溸yÓdë’Å~­Á+‹ÕÓö]ÜÙÙYZZÚÛÛÃù˜Ù‚Qñ`5Ì.ÐÄ*1öcµV‡Ûž´pü¦¼¤¤c´eooouu•¶sZ2VHähãÀºï¾ûüñ7n|ýë__ZZòØ Í�„…žHÏ6Ožž³Ñ²´TWÁd8e,y»Î“ï÷û€HTŠö›¡p,\dß…®*žkiši5Û›ò”¹œäYi4$À¼Î9‹á×#?BC ÔƒfÒ4{Oþg‹½�HÕäaaÙ¸+»ƒ¬¨ 3xAšÊÁ—Â_nF½ÂÓö¨�CÜæñ·£võ|5‡I±¬¶,!Æ·täy&¿÷ü fÄã*ç8â3ˆW ¡p+˜µ·=µ£áÉéàq J´Ìúg‡Ó·š½ºh30^m¢Ž“2·Ù×KN¡Ö=pßÁ`péҥ˗/gw±ÛÞšMËÔ´Y=dÖ™ÉwùyÎ\˜!O±äÈ ãfLQD¶U f'9vçææ~üÇüŸøÄ+¯¼ríÚµ˜t1ÿXF@,gÇ».­b1íØX+·´‘=i”,÷á‡.ÝX &Ù»|$*Ÿ<yrff&Ê®¨ ÝåòÀrÛQ‘ªd—µ}€ñ"Ú3ˆ>X>¼Ô ží·Þ«ŸÓÙ¨¬‡¨(È!^ÂË.@ÜOÒ°°å6òF éÆ0¸“<÷Þìžž´èèÁ Þ8¶ 6Dw ëÌ ‘Ïñ�ÀXû®ø9}úôÝwßýúë¯3_ª1 §RÚ4­ÉH±ú$F³¦äçcͽ±Oy­µƒ‰ƒƒîa«0á:Ì®Àħ«ô6œB–ô‡õms¶t­€G<Çð°µu“TfÍš±ˆŒ|Ðô„N§Θý xžCD»%~—†‰ÜBwzëòŽt2ðºÏ3¬&''×ÖÖ–——ßzë­µµ5÷x€kˆÓ…‹A×ÈÔÃêk¦ˆ¼£)òò¢xj#Öp@”Ncy}˜ÎMOOG\‡¸‚ ˜u\<^FÇÑ!„|…®gŸCùµ™ŸïŠ'§Qêï‘;²æfNä~¿o7Û¬2 Ë£òé±KpAâÊòpô-Õ0­22!WáÌë0%švŽ—_¡DZá0'µùœQ.±ŠUW\Wœ…nž…DÇ$écþY]]½råŠy&à!ìØóçÏ÷z½ .¬­­¡„F¡BÐ1 ”N�G î‚þÀpçûvö~nobb¢-·é_›žxsbòò$iíG“¨Â¬õ¦J%Ä1j.iÎë´ Ï8MŒœä즷˜˜EÉæçç=�ˆg¶kÎjÁ<R4EÌÄKo‰mO­ÃïdÇ&ÂñçB¶Gd�"ÓU‡Ãá¾ð…§žzjiiéÚµk@‹FÿÒ90\C&ןC-sòLÁ;°Ü*p<¹*+‡Ž Ø]ø²–kÌ·XŒ³ž^õq¾‘äààà b gr'ÈMMMMOOomm¹¬bTÀ ñ=zt9ëQêã{‹5ƒ‰ï&(§EJ‘7333??Ÿ+ÉÑl)z$LSQAêžÅӤƽ¸¸YX{ ‘¢§0*Ág ÁÌOŒv‚j@}¶R"Ô22Ââ( �E N’………P-€ïR†r99Çù³³³³¾¾nÝSöÉ[o½•S›4U+;›se™&ᨦ ª´äàÇöÿê~÷¥îü¿;ßZÌvþ«‰å‰Ùÿ}vúÊ4©\ò©ÕÕÕ&ë’ ¶½Ò@² ¬£l ©D/‡ÔÔX@ GA:µ™u@+oØþÖNwª»?±ßýWÝ©å)ï@Îe&ïÈÚÚ¡¸!\)ò}7W’¡X¤2o¿Óé,--­®®Æ½¾ˆ§ ÆqýV™3#‘Ù$1–‡'´<MI,áe‘xÈÉT:ŸËté-…^ÔŸÆ0Ë\ª= !,XðÔn›>X)JìUj—&× —QmŠƒ4“:ÎÃ?üøã¿ñÆO<ñÒd¶Ž5cТyÅÝÊžèÙ/sssïyÏ{.^¼˜RÞݤ›,¬gÎŽåvšÄ§ ]…^¦E³Š†OÀï‹,Ó”N_!CÖüͯez\óĉ)åÇ!ç8¹”¥fS¡ïíí­¯¯;MŽóØ4\ÔØÒœ€I”"ƒH‘º!gÍæ§6gÿîìéþé;î¿c{{ûÚµkÿÅÁγ³÷þ½‰«ÅcØÔ2G/Óò@ÿ´%ø‡‰%wvIáVVjOÁ‹Iº‹r"b6ÕÛ³5?³·û£»3_é»»»»[okjujê¿›"oõïÈœ~ìaƒ�7c†…^œ‹VfŠâ»\¸–™TW™ ˆÕèAL‰CÇC£y¶T~ 'tȈ²ÅZØ5´}VòÕæìYº”zˆR›Ix V…™rù´'N ‡ÃˆÇØ·´¨æ¸÷ÓZëõz6ª¡¥Ñèæ£]ѹçž{{챩©©§žz*Ân’a…sô{ÚŸ•iò=[cggçÚµk‰ú†¾¡ÉŸ‹T-`›EÝ?g.ÉÒì¼” ì˜/ÃãB”ºIêpwwwmmÍ��é#‡tmmÍHû8ä[Ô1CÑz«„X4�5fïýÑ– %DÑS`,ÄÀYd© k?»Öùlgvmö±z쓟üäÎÎÎïüÎï<ÿüóÏt¶ÿûíÁ7·yÆ[[[[[[œû íHz–Íò6@Cäàø´l²ÂNÒíÙ ró&ñÄN§ÍyÒUäy†?1œ8;qâÓ'Úómjjª»×íüYgï{÷vewþ׿‹¡ F4W’àG¢`¬ŒXHã- B f˜ÓaY&Fˆb@U¨J ¡l_\IíéZÙMË'¸mЈ.äÂ\0²@ÜoÖaÞ‘íP ,WEŠà Bþž Ê •¤*E°ýRݵzï{ßûñüÖ­[_øÂnݺåf›[÷œÚV¹%zA"H 5½˜nöijÏ>{ëÖ­Ë—////sG –ÅÔ�É5“!Kéà Jÿ(Ž[>Ümª¼ æ´@½H+í‹HO‹w—ò—¯]yÎE€Ú¡ÐQ“ci–A.5è%H>¬6žd†ðÆôãÿ)Gó(¥­4${½ž¤£î^æÞt»Ý¹¹9<ÛSߤ‹%¸±±±srgæ™;ÏÞù‰O|â‡~臃ÁŸýÙŸ½úê«»+»Ûg¶÷'ö‡;C4N˜1 ÓFä#]ë´£^/í¨êmî1‡Te¢& ï#t„ËÖŠ  !œ=äj8î÷ö÷ïÝo¯µƒçÎ;wæÌ™¥¥¥oÝØînüÕƒƒsír#º\Ù —ñŒzd’‘‰îv( 7·Ð¦)S\·Ñ€)Ì "“å¢Ë v&–Âä”7àÞ4¥Ûëõò;ÄKÓð¬Ü4 4O›¨‰,“ñ"¢¬E9­XcM6”Þyç>øàõë×sÎHùläY´‚.ÌÌÌ$Hx²„†¯#ñïÍ7ß¼zõ*]%³W<“G—§,§¶Ÿv;*Ô4 ÍšOœˆ—.oÍ8ëîË<`$–X‚ø©§š˜ZÃÞ”Y=ëÛÚ䢠|ñ¶@S Ö~oûý>L×qÈ9ÎxÃ*„Àî]š…”hH6ÉýRÃ’fMD› U0©;âÿþ`uuõë_ÿúÜÜÜÚÚÚk¯½¶³³C1aYbPÄÅ Š®¯¯óá)¤èIB²o±3ú&›wwÞÑyëìþâÛ^OS¿9µ¿öŽš'Ó&ç¿fO"\¸¿¿¿wÏÞÞ#{'ÿùÉÅÛ?þñ?ú裯½öÚç>÷¹—_~ùàÕƒítþEÇ98e%§6W›¾š7ÆsÜq1¡#gbpj;�46$.S¼GÃ8p1lÃã$ /ËÃ(\[Öj´ ò1ƒâƒ†zÈ$%h÷†’,‹É¡I3ovv6§*<=Êt>ÄÐñ… ~ë·~kmm-À9ë?'~dßÌõrGÿu7*Xä¨ÊÅÃå£ÛTh8ÙD¹µ”žQ#ÉfOÜ}÷Ý·nÝZYYñ`€ ¥¬Yåò‹¿Çgy@û,°NІ¯cÏ_[f>K´†vXT Ø@�¹MF;ã*ç˜CŽ—5m72ßœÚä_>” Ó³@ͼBȤˆë à3&þpbøsÕ'W>ÿùÏë[ßÚÚÚºxñâp8þÍa÷‹ÝÉþä~ÛwaÄÔ}ŽŒª¸)ˆR¾#ƒ`eìPéQ˜¿=><œþòôÁÁÁÞp¯ÿû ™6ãÙI¤ÉØ*ÖB ¡M´É‰ÉÙÙÙóçÏÿÔOýÔ>ð7ß|óÒ¥Kׯ__î.ïïî3ÌoŸ¨> Q¶º1%„üt2!�—‰³Vý1¶Ã¦õì‹C@0W öîÃ` ¸#HÁÚŽZX0Ó‡ü9ˆJÚÝ|cÐc†9ìr,š)[lŒdð½ ̡΃Ñ%=_[[{þùç)QjçŸÌÏϧܤ;è7Uˆì°æ|ûָ˨JråE¨];ð./<z*pífffNŸ>½³³³±±aü³ØP¡T0šíÐoÊÏAý@S<ÜjBݼI!ͤ1/šÒx2”NHÛsss,ƒqÈ9æ^Žíó,á¾÷ÔÔTj3µœNâ³kÿ¥v(j;*äìøwFŸ›¼g0\.]YZ¿°~pp°Õßj mÿ‘ýΗ;»Ž ‘Y[[[[¬uw˜èpJÏÜ4 -ŽNe·Ö¿0˜ÞœîþZ÷àåƒÉ‰É¶×fžÙ{|oð·³ÿë,ÍXó/ÈÅÚÑ)în·;Ù™ìï÷û{ý•••k×®={öÚµk7nÜìÚdk»ïT]à]%ˆòa€ö’É&ôqîD…‡+çMs §cà«IêÔ¥$þ.Åô1|æ1F@WbLiÚ75”<ü§É¦1NûÊ<É|EŽ!¸R”èÇä’, Ž9‚u?‰ÜÑúúº`‘)‚WÍ ºŠâÍÂí CXd¶€¼ŽàŒÙ13°¹¹yáÂ…l[$¼2››%õ̤~‚1h.åÔÔThÜ!¤ØyϱÖSDn—Æ’YÌ»X bH¨ƒ‚ÛB¸—«œcþA¨¿¨,ïííŒZn9I\æ,¼È—GÁ3íÌùHjÆ~°÷{®göS³Ûÿr{bib÷_íNNLNžšÜþåí©ßžšúòÔþľeW`³ œLç“^‹ÅcÌ@5ê]λÜf»­ o¿2œ|erqqqjjjsssï½á™áà¯Ú\›Xž°›ˆGX8ƒ‚x¼ J<wÐýóîæÏl¾ñÛo|æ3Ÿ¹çž{Þ|óÍ^x¡ÿ½ýÁCƒÙ¿;»·ÿލ—Ù ˆÈÙ±ÙÜsæÙFëÅ·ßgf]ö„ µ”|Ë y%J1å9r:–’óæ_™ @çœûE´ß•¨UcFr†ò±)€òŸ8||ûègÄäíu²¸×mÃ6ÜëïuŸì†Oe²¯Kv³3Øo‡Ï •FFÔME$Íj~V:MÈOøì÷û‡e¾']¨Á`påÊrÄ&¥güÚQR7LšV%u*[éĉï{ßûÖ××_}õUô L“09bÙ౫·Rþü‘áp§®|~""R’ªÇÀÚwK¼)&Äü 6Ø$ÎÁÄŠ5h’T2×ÀD ,†#Dò;ûÌÿÃádgòàÖAïÇ{[,†æì âL&SXxr{'ˆz´­„ØŒ¦¶^ë~­{ûÙÛ?úÑ...>ÿüóßþö·'ž™è¼¿ÿ‘ý©ÿ{ʵ5Ú‹Ÿ|;ÛýÖÁþÇö×yý›ÿì›/¿üòöööú¿·ÞîiÝÓ-^/1¤ê£üls(ƒ,g„ŠgFX-¬½�:,Íé‰rUã¼z-Xy‚°¹¤§Íxf“?)½(–²¼J9-Md«c9–ÈÛû…½vGë¼§3 ;ƒá‡‡Ý§ºí«ÍŒ/„5Mó<Š·ΰ6GÇ]ÛY“f“€{ZðŒ \–· òfè8g=5\/;€ÅW[3Éô Û"åCñÍ7ßì÷ûðZáå#äJ/ŠSD¯Ý³Iv{‘Ü,ƒ¢!Ã0€q¹rŒCαÑÕ¬ÇU�\·7è.º}=ê,�LŒt#<‚NŒsZбYlí;³öí(ÒyG±Êâ(ÙÞHÂx VU“~†» >Jœ[qdìí¿ý§OŸþèG?úþ÷¿ÿ™gž¹|ùr¿ßoÍ'KŽ!‹ïÒ*/ܹÎ3vÐöß·¿úéÕõîzkmò‰Éî³ÝöÅ61}d°Ž(è*Šÿ „h"OÛþ7¶”FU N—>tìq�¸j)Éü®pè9jiA¹òÕ:Þ[jÏh˜kS_/ø P‘ñUNùT±¥CÙétvÿ“ÝÉõÉÛ_¸ýÎ}çêêêõµëÿÎÆÎ_Û™XŸ˜øÖ„;Û¾üjý7î³¼]«Ñnqp‚Nqcϲ7Ï ;àYÍÖF·Yööö.^¼è¦¿FEk<Hc4ÛZ/† X+++žÇr’d3YFKHb¼öø‡H”"Z8j Dz/âoüÍ8ä#ǰ;ä×,”œÔÙ½Yý1Œax³uç "ï`¾”­BIÿŸ˜h‡ïÀ8ÌIxRÄÙ_'“E#2i©³$VFœì…J翳×ÙÝßÝ›Ü[YY¹páÂÂÂÂÕ«W777wöwöö¶÷º­[´´þ¡:ÁæÀölgê/§&¾~è÷si¢³ß 9µIôx5ŒÅCâ1t»âš…«‚Ýz‚>¡ˆŠ²ŽgèÚQ%à|Y †½ çu0Äb“8Xcp»i5qÁ<6Ü”µi˜ÁÒ ®ËfÒÑùóç.^¼h7³n·;Ù›Üû·öÎüOg>¸øÁÿ؇/]ºôì³Ï¾ü‡/oÿí‰óß:0ç…&"ƒ¾ó3oG =+m©Z}s G9Á]µ c1Ó–?f€=O Ã×ÞKø„Z„ׂxE6‚‡_È&Ú¡SÇ@ Ó3t‡W‚é cP5çˆÀÛa‰þ¡egÍ—±Nĸ—sÌ?(sØ £@·,‘b]\b”¹h~Ž¡6“šŠP#À§6µp“é§ñ:ÛezLÁ*ôäD GbàÆa¨Õ“““/wÚ‡ÚöǶoü_7~÷w÷ÿøWVVVVVìïîwÿŸîÄô«?Ç)aÚòVù,µóZgrrr¦;³·¿ªE™Þ [t}ÖZCm—ÑTÂ^yàdˆ!ð¸BÍm2±˜: sTE ?¸6uÙáTº#êPu¯ˆñ—†Ü !6YcØÒ”@`úÑ.ŠjÀÁÁÁüü|äÔò377·ùŸnžúÒ©8ý¿ø‹¿ø¡}heeå÷~ï÷~ÿ÷õ3«+¿½Òžn“WÞ!I ÓÓÊíþJÁœ L傇m†4_‘Á[ÔL@ºÐ5«_SzžÔnRG¥´ÅÅ<Q~~þ®»îZYY¹uë–‹Q²7—ž´ÁˆX|#±ÈHÚÚŽJéøÚ²Ió`¡Y²—çææÚ¡·¡)é,’PÑŒî¢-dí˽CÎqbklx[e@Æ/”6ÏŽ1Ûác…n³ù‘l ›Úr`ä:Sóô>„ýTÓFù¨²ú­PB¾o¨M$¡Õ™vñ;2 _ŸÞýÈîÎÝ;KÿÛÒÍ›7÷÷÷w~qçàÔA÷©·k¬°u=ƒbUj;NUQ³?ÍD‡kÇÓ6¥;Y-ù»˜¾)Õ§µ®¹ì2.Ç9Uæ…yÔˆŸæò¾<Fn¨Ä¶ í¨fÿ° BïJÇÂã™ER%~ö¸Ll~å•Wl øÎ©w°¿°°ððÃ?ú裷Ýv[¯×û¾ïû¾¯|å+­µîÆÔÔÔäôdÙ8.¯i†çŽÐ…BÍÌ8!ÝñÒáÙ RcÅMÚü‘ˆÎÈ6J¯Îy,|&Iÿœø=ªÏÆŠòª0zì€APLþʉAÚWZŒ†ì˜ãˆ@k�;^¥ñöT¤f «œãÖpŠÅTŠn${ PŽÉ/(þc‘ÛÑùíbÒnýv ¯Â¦Ãä”Üßøö{=ôÏnr»âFœ¶C¶±%FÅÖœïv»S_™šØ™Ü;Øü›oÏ-~aúà/ºOu'¦Þ)IK½ì jáÓÜœN¬´¼yì¼ÉD:qÔ(6UÈ`0™Õ’dS¼èëZYÄ\X'ììÂçl× Œü“\/… Gé˜.{²‡kË„ P° •{K~Åæ[’ózŽu0¬¬¬¼|ãåxyijîêÕ«+++ÃÁpr0ÙÝë¢IcƒWÃhI‰À¢•¼,±0ÙèùÓÏCÔÕ+Ò#ÏŽ¾èeX€Š „a@Ñ£ ’18r#w>Þ™*;¬Ñ9 „Är‹|©tm'Ϧ°þ êP, ¾Ô"U<@€A>Áɱ;I6䇜c 9xIœ„ú¤ &¿\(›ebŸÏÍÍ­®®šÍÅ"I·¥nsí½Á)i(ÃL°r\ºƒm`z”`æ:ÝÀÉ{÷éîÁŸìíP+å͉Áö M6{>úô).pMº“æ¶fè½ pP_Ò©j2wñ}9‘,<æ"ñi¦òˆmW‚S. oÙR›X& :‘äÂ�BYW£Ž¿£³#¼P»òï—žž9-Jk~¶¡tN¸Í] œV5§ÿygó×6Ÿùg~ã7~ãÁ¼xñâ3Ï<³¼¼¼ùovÿÏîÁÕƒƒ‰·¬ °üx9å^�5©2'IãÙ:²D!¿Cn€›ä¶7Ä$ e¥W EþŒDê‰��Ç ›Ž;ådàÕ£JE^e±mC~ÍãÀ¼ôåÙÊZŸÖQeUpŽù4ÓŽù§×ëÝqÇñWæô§‘AÚG>Ía΄¿Ì@%ÓÙÝÝÝØØàwÊFb»†A`gL¼U ±9.²ëœÙ±-™lYYÓ…Qúã‹2’’D›&A“ÖÁÞAçb§µ6Ñ`°Ñ†ô¹CyÂÀ|³à?| •„.#œ•(^ÃM`êÎhŽ?»‘Æ~›âƒzf»»»½^/£Œt EcC{ƃB%°Ë ÕI–SúÆü‚OXR–àQÔpÔ+ä ðµaÄ„2ÑFM ›¬C´GyzD ©ÉÍɽWön¾ÿæ7žxî³Ï­­­­m¯m=¾5œÎþÅÿÛÞ›GÙ]ÖyþÏÝêÞºU•„ ÙÃÂ@‘¾•- ËO<öhì_à8?[lNËI«à9ƒ3Íâ0Ò-sPø66b0“�AdBBX’TÖJR¹U·î¾|çOê•w=7jÏà†ø}þà„äÖ­ïò<Ÿõýy¿SñÈþIÏT*¥„”j ùPÕÀ‹1ŠŸÊyŠ+å„D"1jÔ¨h4Úß߯³¨Zî&‰$xÒÊ1VMaÒ´ fÞEg=’=ÆŠU?Tëá: `_X©TLÏÒŸžD�¥ô‰A¬)q0˜DU`@`§yª€lZUaWqc­•«»»{Ê”)«W¯&ô ãÑm E£ *Îì`Cu®‚îÁp¢J|„çpÃE{!`óC³„Œ@ '„yÒèÌîhÔ¨QÇwÜÖ­[wìØjHƒwUFP¶`-(ãWTÀMÁ¾9¼æ7´Z~ÀûiCœ¨j@ou꞊�SîH)÷-ò0F;•3ñªª†¢®]Ñkšú¨¦½Eñª/ ^ÊÚ©ÐdŒÁ/χ™ž¼i¯á2)*ç¾ÊÌ‘ò5åì´l¡Q¨V« ‚dø}"¾<®œ:n¥îV´¢ï®2w¼kŠE€ìñ”‰D¢¯¯O­¹™iG­YH†¹(/äÅéAóÈ=ðÖ(I3£N ¤•f^7‰W# uBp§d€l Õó&èÔ§­Ã¶*dŶª x?åÜjUU-t9ûÖÀÀ@OOÐXíß**—m5K/Èm5a'Êó”Æ u&Æ—è]z„]:ŠÁ”¸fÖô]ˆú)n8¡ÌrBlÇ …‚褙aSlìr%ea$£ÿò¸LÀ1“Ê@g‚_Q¾�5I§“y̡ޞ'àABTúWkžº Ežöööt:](¬ÀâIÜ«þ)¸j^œâ‘´Ó€X�žX„Ò¨¢6Yk>)«)eÆ<U~yMfn¾ÐlO@Õä¨ÿD£Ñä]É`LàÎr±F,(móÚjµšHYÌVjßáÔñtBH"„nVÒ„n\[)Dcl°¾¾><¥ÖšÔÁ;¡>£Ð̓öÆ4Åa;)�šØEŒÕ(ILèó •Àv,Ï@žÏ(i…¥Œëä W0†bY7œ Û0~^P«¯rºœ¬|>O ¥8pŠ1 UÍy$°j€l*`„>Cyø³Ëqn80†ÕãºÖ߉f¥’'rT²‹6´F___£Ñèìì ‚@U°Ô)ªòuÔ‘Ua…Iêfjš5ìU4 j1˜YìêêÊçóK†MkÕ�� �IDATÉM)°(ñe+pñ1+¡pÙÃØ†ŽHuŽìÜÙÝ­kÍ ¸pt$q”Ýì½XWÀ ˜š¼Òi@ÊZ3f²@¸Î”kˆù³_Ê á-EBre<71Ó>«º³›‹EbµZ-p’žñ¦�â™ÐáçNtH•6ÆòuKÓ-1Óð¶œp)¹»N/°yTT”©R®[Û®šåS­­ÕjétZ“ü:¶ENI—7‘H‹E@€ Éyïž”"øiúŒS£ÅX/Aá�…�¢¢©Ù?!t9­_Ô%œ()K ¦\ñEÚXf»sþÍܘ`”ºRö®'L¢Uo ú<Yb'l^ù~mS« `Î7‰ Æ^‹E³•ê;)ª˜ ó„:쟸H>l~_‹:íY[³˜×‹^uä6˜†<Ÿ×ËőӿU׫âÐê*S*£Ùk²ÕQÕbo±ñ‹Fý­z|q\'?42°øÔžƒ:»e­Û$Xm¤EA¾ó<mÛxa©ÂØpáöº;::Èl0pÊ1ÌÃdo霕I%y›Œ¼(w5-=ÕúÔÜŽKK^ «a”’J²59À¤iË7ËÎä k\…'Ó‘8ÛK4ü•K° gY¾!Ëí¡Y€±'ÕjCsVUAéŒtìnˆ–‚!¥rßyì'úlu“ë,¹r6Mýù' JôâõQ„.§es9ÇyÆÚ3Oê4*!ÊÆîk‚…Šdé~RºOu'¶ÑÕÀi}I»ÊÏ­1'DJád.µ™§ÛJ1ŠB„‚qUŠ#ÊÃÔQâ,R7ƒ?BRñÓ©ázq´ÀÙ™F¤af¢WÈÒ¦½w}}•ã*Ï5ºï¾òÙ+=òØ9sæ,9eÉž ÷TGUÝÓÎÓàáCÔˆYQVfm_ƒiÆ7{ÃÂZÅ0é¨Ïºe^P[[ÛØ±c‹Åâž={x/VÌ|?{tž%Ånˆš¨=“üŠŒðºýºÁúëÜŒvÔýÓùW¨a³2/{Xgæ@fÚ!5D‘W5ôÜ‘€Zf'«$®Åþ `'lëðò!o¨4šf‘jhÃ’­Ëé8ÇèïBŸªŠÆêð“ŠVP* k ]N+— º�±àËv0<¯œ7íÔ)A:‚Ôñ‹Å"­{†®1—ZõZJô¢ 'ƒŠJm‚QÓoÅ+«n#îG¥Eb¾ñZ¶çc_bÒRÀàÁgõð౬­z[Gd±Æbrº”• ¹O}‰0K–J¥ú´ú˜ä˜ËV^vñ¼¸»»»P(Ô~[[^\¾õÿÝšx:¡ÛZ÷PÚ4m« 2}…§ÛVQ’û£F?~¼ :àMÅÀ,ˆ…üŠ ¡ýf·™J¥¼–.PödÏëg´ˆç†ÓiÅÆcÄP!W ìZVò0¾ú»8‰°à0jã)áÚm#Ž·µÌ›’ï²£(lrmÔëR!¥Ð…˃ºˆ2æ)dÀ æj$íáe<-6 8O•TðÒ_rA@%Lí€$òŠó¡ËiMaM¡¥õ„×ÔCØT×¢³ÓJF`…ÒQŒÖµ¼<ZÙþ­;B­€€ˆý‹ÅL{qppl˜U¨ì;©Œ™{Ðó¦¿þ6ñ;^GÏ9ÏMË&D÷ZBáY¹á ªÚ³Áô˜M Çí_Œâ°A"K¿Ùù9a‹±ÇÇ£ÇFS—¦¾øê/yé”)S‰Ä…^Çs媪…/âÿ×ÒioßbÛb±ˆ…¥rbh¸•ŒZBc¯««ë¬³Îºà‚ æÏŸÿÌ3ÏXE‹Fk‰é*ÅãñÎÎÎñãÇïØ±ƒè$—ËÑêÇ×Úk¥ ³G ½)3¬Fq†h¨Þ)túVltB£Ô×öZ1£Šôì/u’0úš†9V6wCIˆÞ¨z(JNž”íAg·T*épÁ¨fKL°o©Ï«º•A�ˆÿð @GLl˜P‰Kõ’K­Ì·µµ©òí¨PˆºõË ‚íN¦‚ ÙlÛ™)¤an”GÖ—FD«P(¸!þ mrÀ]ˆ¢°¢6IÀêxãë„?tƒi³ƒíoÌðYޝ9 ßL$N§Ê¬›©K!_OöÆÅi.÷fµ»3»lW‹6‰ ÆÝ”N§=а'Þç”Zeœ uuö‹ujomôèÑéSÓùãó—u_vì±ÇÚo?ì°Ãf̘FžüùÛ[ÞyäÈ]»vÙ›åå¥äóy…«ÄŽÝ‹ý.³bFܧ#JŠU«V«7n\°`Áºuëx)?B …œ=µZíwÞÁôxCQJ¨úI¼tfЉ‡<Æh¾ÄëÞsRŠÅ" ,Z†n8“–[A’¸(ÔE ˜ ’Ù®è×)LJ„l—Äp±î8¥¼J²¶FH+U‹SKsø½r¦¬ìGè¦h÷N³Fæ‡R<7’]hz2v¦ÓÄ.…B!•J©¿qÂΠDm¡ËiM#‡-%8Ѿ«ê³“t ¢íGOÏCew1 ŠóÑ4ÙLåÉ 6gÉ¢T8ñh?Ô�áG5w!˜bë~ÞɈ»Î‹E0T UhÇ»»»‡›Þ¯ŽòQGÒ0ê‡b¥€ðƒ:îãnÚU1ÏÀb¬Ëår©TÚ³gϤI“FŽiÿZ*•vîÜ™‘-•Kñ|œñIÞ¾¥˜æÌ©è\¥<}5Nx”bÕÞx±X\¿~ý¶mÛØŠî¥T¨Í ÀlŠ¥vC“ÅÀ|”¥@såŸÕKûZð2ü ¦'EA ʨFÏ ‚ÉqÚð¬Âa°•š­m05EveVX¹‹²¥C‘<4O]Ñê U>7õ»fë ¡<\n% *!íU˜Œ7çÓÄ–†ÒdŸÀî ÖQ‰Ì«QÐLH'©[UX‹†þF+­D‘4KÕņ&j‰f­Å©´>Édä5¶R#N3ƒlÅ¿©‡0Ó©óªˆèDh(¥&´‹·ô߉‚²Ùñf2`e`S~bfÖª‡uТ|*•:úè£;::(×h hGTaû/ÌW‹©H<³ÚeŠõµZÍN/¦¹4´²Ù¬µÜw¾ºsÏS{~–ÿ™)ÅU«ÕþþþeË–ýzÕ¯×DÖTž¨ìÝ»·P(   ë 'œðÉO~²££Ã`i:‚j¿Tã E™[?O¼ŽF£‘ËåŒ C“]Õ§©vu´Ø­7C´½ ì=põ=Zòå!“\êx©¢�:öÆG0ú͈a•æÕ擼‡üLaÀGµ ×<Ý¢´~V'$…jŽ+1¥ö_}°:ZäD1‹|ËêZÍnV»·w•»zê>W¾m• aÂözqÉ¡¥£a/§Å‹¤©òÆ5!ˆÐy6%øH˜FI49T³Òã˜R�›Òfhˆ3cÍJyš)ÓaúÄ i›âG9ŠŒXÂû¢ g`²ØzNôŸ>¹ŽŠÅ¢fTµZmýúõü [L{«¤µ…h4:88¨ã¨”Á§Áª©b-ž¡§BÂ÷XÄj¼>æ`"ƒ‘Êë•%#–¤×¤¿ûR{ª}áÂ… V.Øä6•+åÄÆD#&‡ec%S§N=ñÄ_~ùål6ÛÞÞNŽkHŠd2‰lù‡Šc’m¨Èy°6µóÁd•ÈøÆ\¬ñ@âhE`­…ê4®v¼•D¢µ&7Dc¬v“ë·»&¡Ô^Z½^Ïårú"€`ؾR6<U_V šV„”yÖɤ³ý={Uç“´–JÓ‹ÛˆÌd.@OP}Otqì–Qå!™SÂ5è5ŠŸ–òè¬ë¦!šyÊ„€Th‰u,åêîîž8qâààà;ï¼\",¬µ±Æîl¦×T.º&hÆ*¡a”Ù23ßJ?C8x‰ÒŠª©¿Á²p´�#)° w¥,^JâK÷˜x–0ìò‡òƒÊ[ª[#)LÎâôŽŽŽ|>¯Õöz½^(ŒeŽ* ÿju˜xø'\2¤‡Ê£¥3§Z”PÍ0Á5ÂÃV‘P!äÄo½#{úÜ18¢cÄÒüÒuŸYWÍUG\?¢ážîªÕâžþù%K–ôööÒ…R*S³¹�F²thWß Ñ«ÎØ)VòoE.ñalwm7kWh/¬-ۨˆ2Ýã|òZÚzQ§åD„ fEg ¡Ç›ÕéEUC WO MÙ ´ó¤Ó”žÀã�nÖ‰}æp•›Ï­ªhš²{³Jl{£Þà\ `3† ÀŽRT·–W $/~K.—Û±c‡òÎ…£ ÅPo—€¢¹-é¹­ hÊ¢*ƒ]Ù$°–‰÷ÔÊ’VÏ<Ø›b¹¦Âv¢ª¢¶Ø Û´ÇmNM€a ÇTˆÓk&[…MiŠrŠ(FS²#°U3¤­/jÜqž)…ã$ ÅNW\½ˆUúêÀá´ŠyCú±ô˜ßŒyé[/%:;R;’ßOvîì,ežŒN·wï^ì#(Q°ƒ‡xÔ´¸¹zi—Z«ÕÚÛÛ͸‘ÞR ا¨)×í­\ ŠëSD¯ŠÌò6á±h@k›<a'º–ÍC¯ÄòÔ=nYô (Éòƒ:ªâu’ØæÓ W!ÖÙÒ#æá9+ÉžÆF^ªmχ”Ž‘&7DžÔ\úöR+j‰l{nVyI´ÏïIªk©PIêŒ[V7ð6«7@©�gnèrZìr<AÕ¹Ñq9f_`›¦ì¹U0¨SiÚd›Œn¿Î[LhsØ£{‚>@/›˜‹F@…‡I´fMæÎ¤·‡Éñx TL¹ÝX´è ¸:rï™{#iÊþ©NB M꟔n@_ð ­Â{j1œLã0³nP.—Ç?0>N×zjù|¾R«(U>¿×lvb`…1â˜Ç¯t*»€½3�$Ó»(tѺc(˜Y+…ª{ÿKƒÝ JW?¤z²&‚*¯É ‘–ÂæÂ'i/i¿×dÛƒdËÜŒR¡;‘ÒPH‚õ5‰QòP/³‡³Y›1ˆSP!T{­·ïD¶ØˆA+Ÿ²'õz”tÏJUŸ °@þl°rO= ^5…8) 2@Ò:RJ@Ò Jßð)„.§Å…5ï 7ÙW2t Zaã0¼¿Fm$û€{:Â.åÄô€.šè¶ãÒˆ%í: 'fñp «ù¨s‚Æd°õ~ìðG"‘ŽŽ:ö#V{-z#¤€F`ßhàlpkj­0yZ&2r¯(¡ò_@Ôà³207†0Ñfö2Q¡ÇiP;¶Ïd³ÙB¡@G¥Né/;!(£óáé5謱}BWŒ¸¶èF0L€¯ËDíAÚo)•J¦ ª˜d‹ Á ‹!¦H¾ªj€Qs*—9ÖYÇPÜW¬B¨u“óÝc‚÷<ij« 0YbJFócä4FvgÌÓN¨"”�ü¤E„´f•yˆèÇ l`Àzcßxí} H…Οi‚Ë v¹\6œ=¼à ÿ¹r È8³®õ%±Õ8e$ ]N‹±X+E²y�$êÈÆÂª¢Ÿf°Ôú=:©®õbMÒ¦ñ=+uuu%“ɽ{÷Rs‡`Ã")šöÈÍ)b‡:¾ 3™.€%UêT†1š(ôœÔÀÑÛ0C†‡3£`ɡ(²S7·" ·†½¦)­E6Ú³`(¼Ñ ]˜ W'!, ÐÉsŠB¼Âp{ž4ÛubCáøÊŒÀö�-†·S0$(Ì*ê£fÈ@úâ*˦L-8NÍ3ìíWÀĬ¤ËVñsBõFƒÓ£ÏЖO3Á¾*ƒP6„Ó {ª“ÈšìÏ)pËTN8ÔuÇBL§½1cÍ‚ •Jó1H!Ý#  Âw¶™&‰ñ0AXS®ÓÍü“–‘ciySÃ)Më¹;B÷ŠrZ ]N –ê¨áð4šT¡’ƒM*ƒ™PeLª¡Õ¡¨V’n²Ó°U¾EÌ7\vmÉdrôèÑ#FŒ€¥ÑóˆÅÅѵRl+éÔ�±øFÐ#ÎC�h MZ2[†XˆN°kÿF§‘˜*PR,'Œ¹Š˜ <â1+©¶‚V¡ûµ[¶aXbF%‹SÂe3¢ï×¾=ÆÔ³_0±z=¦@´ö«�Y»ÒKRî2 l5F±}â•§(aaå J{Ã3q¢¬á†“äkÃO¥< Z‚&ü©S¡|8³yäË"!•â1!¬Q•@iéë´ìŸ‡¯`tСnˆ‡IÇx5î£CK€Txɉ6œˆÌªÖÛƒÇÎÝaŽôÏö¸|u´®U‚p.g˜×ñ üPh¨Íµê³NY*ZÑÈf´‘ TK /ö(&=ÚHA4~ÐÅŽ!¡†½®v„rŸº»SkSëWѶñæf<x»eü4ñ8­Q³ÂqˆÊˆ©¨"Q³–Xyû>ã¦4m2·a¨ †9t¾–¸ÞPi„b"5¯äp…–V2ÆOÏCÕçšÑçʪF¤½½]ë8f¥Ÿ¡ËõkúèDaèæÒ u6'D×:¾C²@?¢žÄ‘‚뼆ŸŽ éQ²Ç– —éI{àŒÍ*·ºÒD1~ËAð¤w´m£µn}­Jq¦*v¾¸wN.Öé#ÜR´ÅO F èK<6h{w:oĶQÀ·®ï®BïÀ&y­aa­õí¤8ì°Ã"‘Èž={*+ÑxÔ5\d{¤QÚY$“IÎ3@‡PqœM™PÖ©'ì"}PQ|°¿4Õ•>#TTŽ ç\.—«T*}}}µZ­X,B¥¥³u˜¨«Î ÇŸ¦h±`¤F5]üöXãè7ÐŽR8©žª‹JA‚åHwìŒAoã†8µ@µ*}CóÔ­Îéü .C»…qÛm¶µµýÕ_ýÕ 'œ°xñâ5kÖ(ý‹ ¹òT¼œ0Và±h ©ÐÇ²ê–æ|8 û0„(ðZ*à,�b)ûv%(Ãi¹áô‘|’xÂ6€•§H_øNûñÎÎN+‡z ìaÏVªj5­%×�HF0A} oU=P¤¸�òN« ‡&IÔôŒ/U)± ÝUÀídÏÓËqÝs•½Y˜´UcÛžh‰³I9|—O*Ù1Q0ʺœÖ¤8dÊcÆŒ©œXÙÓ¶§vqÍÅ]‘E‘ĦDlaL Ge0ç¡u-2P9QÏAŸaO¾JÞT<ÆKäéL˜1‚ÔÀL ®ŽjÁ׉¸Ž®eI�‹•TªB±)0rÀTÑ‹†7Rúa§ñ�ÞD½õn…Ééì=&F¨PS ×Z–ã*JÊhi“çhÍXwtttww}ôÑk×®¥¤3" §§õªIêdšXs2±vÂæàÍÕ³È;Íè²x =ØðèÊÑ«æy-¸IÒîR1éˆJòð ³ëáÕñ¸á\m:uŠGÙ¬UAUs4À9Û>O1"›æ7\†æ‹Š3¦g¦úoÊ¿îšyù¢MGi¾¥§ŒP Vq.¶-á×a¸JÑFÊÿ¦ô ¡Ëi1HÚö}©TZ›Z[;µVé¯tÍêŠV£år¹ü˵Ô#‰Ù E²j[O!¼Ø5­«z¢Ë:^êè%Ø÷Û™Ô èO޽S£ó3j½-éád÷Ó‚V™åÚÒ?ëÄJ^j¿=« *«öH{˜jwxÁsyX·ööö#Fäóùl6‹ø®vãA/§±¡i¢U3˜Õ rT”6Dö%f@_~ùåµk×îÚµK»ñv›h:˜Í‹Væf8ZèöÁûiÖÍk¨„•FéB+-v¡œÈœó´½_ª{ÃM…œP(¬ŸÆž}6'amg“«x*®–­Bá—*ù7e:7Äá Õ‘vë(¡‰` A4ÃÑ*g„2RHÁ™­­;uº4®<Æ^KP#húì1’QKìêêªV«ƒƒƒT°5RÔOÚ¶°ªºœaïÜDáˆBl06âž“&MJ&“===î W?¾^¹¶ÒöDù¸N‰SЙL*{W9ÇðÊùôÇ^ìDxØ#+T)Yð=í/•ñÐÃOþN䋼ŽYhÉ‹f•ƒ èììL&“ù|¾YkÎ —¹T˜)00õŽŠÌÑQü®®® .¸àä“O~ê©§–/_nÐÞÞn6žñå(Rœ\­ ­“x yåÀ7 “´á3:¡©bY ‡ÃN)Ên�Ũný%9.ìÔ„Þ�&Êlâ¾”Ám Þøµâ,ðèŠôõøÈ-ܯ˜=eÀÓüC]‹Öjì†æ9Søx%OŸ¢¤ïª¥¤ûÙªsL «ÂºÞ‘F`ÊÐÌÉRž%RS*•…Å’ÐUâOO;¾pKÛÿvwwŸyæ™›7o^»v­•Í5˜c33,è)o….§e…µ}›ãÈÀ}Îu}³ë#§}äÊ+¯ìììüå/ùÜsÏ•Þ)5þÐ(~¹Øñp‡îBà7L_³ó˜·ÂxCûVÓh…ƒ…« €Ò¼âè©PÐ |¶“À¸™òâ�¢¥Ÿï† µ k–ó0•Ò××A–›ÌP¡Ïf¦F£‘N§9r‘H¤ÑÖ¨L¨D"×pmŶ‰'vØaöˆì.R©ÔäÉ“÷îÝ»eËÚ¼šÍ î¥I6ÎÀЖ¥1àbͳ Ùã²>’š"D0@:ÍÛeÞ“aª:ì"í“kzªr:E«Ow …c B#Õb,%­ÓjQHÑxû#Ï/‹°üÙe@pg%­úrÁpr+i!µG¦¾ì7’Ê(.ÀS÷æçÜp5³§ïùÛB6¤¥<bk‡<|k^”‰ G¸©ä[Àôé´YE1‘H …U«V•J% …yV(ý „ä隇.§eYξÚZ*(µ•:ÿøÇ§OŸ‰D¦M›öÚk¯íÙ³ÇE\%UQ¬—‚ÐÌO BOXÝÌ,«ñ»V4<dâÆ`*vÞ˜ú¦ E—XÇßìÂ8?V³ÆY˜lào‹+u1jT:¸® ÅØ Žâa¯µz üÄJ_Ïdœî€M—Ï/7ŽnÔΨ9ç¢AtÛ‚m?[ó³Î9Û¶mÖJ%ÃPèÔ‘ŠÅéëCY€÷B\Y,m6–0³k>[q*-ëÇk­.&Ãø!ÞŸ×Puí·+·1»¨¦iŒk áEñNÔ‰EìFì:¦¨dÒ0¶‘ÛÙÿ*£F=@Eß½™yû°Au”!á­záœì0Ó43°)G§ŽòP—³Ù53ßJç! •Ú™¼‰U-glÒ¸$¨4·îí6-ÕVz*,XÕA!þöŠÅbOOA­ž, ì :µºœÖ¬}/;1êøÕ«W¯X±"‚U«V™«Öª šËNf›ëhJ®^¶¬ ,j¡FõÏu‹F\R†yz”;™S­Š;Z™Ñ gÆ]džø€Y.ôµh‡RÇPºCûÁ+ˆ–([Ë€êØÕ‘2£Sû|­>¹ÙéøjG±T,÷_r[ŽÞÒÖÛæ6ìo'‹Å-[¶hçalJ‘Ê©¦k®Õ*2TeØÓä–q9£F2Ñ6Eî€ó:�ÅVS­2°Úä#ãøõRµEMÌ¡Ù<Á¸öÔ Q¤ežCÇ¢mŸ[|‚€v ß ›€¦\¶»°¡ª™¦ýNüäjqø?%gò¢ )´„ˆ2/§ÌãÔA` ^OÔ ±ì�aKP”nNåù½^»EËwÚ@òøæ98ªß ¨Ñ„‰²DkÙnB—3¬°æœ 6‰ƒÿaðÕù¯îÞ½;nÛ¶m`` >¹^ÿX=ñƒ„E[y!¼‘WQÕpÆ¢EtÞ¬v Åb9:  _¢´f"Ah͇ìA;¨Ê×éŽy†šW[+Û›PÑOoÜU®wUz ÅbÔ_=ö`Ëç•ÛÜ+o‹W«ÕJ¾ÒþãöÚ¬Zmj­íµ6â;mqÁðMi¿nĈªéiœüÆÌ¨b­Ñsµ0 �T%!€ —o©$Àk+âµ··+ªÞSÄÁýàþ)ÄÃ’gwjá3»Wݹ§ïça4@W2ç„Ö›Äþ wÍHTÕPUï8ªÒf z!íºk±‹ O"Ì PóÔ1 €Úv‘êæµ10D =7e)2~H™ ´T¥õgzÈM+ïµúµ´ëagtŒ÷€%2Eèè©W¿¢“È ¢yÐô…½œƒ¥¶Ö(7b›båiå½ãö–6”b.V*•ªªc‘r$¹;YWU΢S€›uP $h…Ÿ*2•¬™ÔÄJmÌc²Ñ©ìYf�Ö8µ¼9g(®‰‚µ§ªÓmZ=ƒÆw¨} D×€ŸóĬ͈( ¤ØqC£‘ØÕ¿RO,MÄÞŽMš4éŒ3Îèíí}ùå—w' ?,DVD¢öµŽ »e¿HÉQ<e0n– ‹�ÛTRI {ÅÖ“ÐwŠ µI<¼µ"Á@x3ßÃÅðIO©ÓŒ¯7?Ôh4ìa‹1Ž:BÄMi$Áž·<ƒ§,¬‘24Û/¹6Z¼Yýæ‘ëA: ¶ä1)輎öÃ`‰Õ¾#8 R †Ó†"3àöú`Ùà]h ¥RÞŠ§À»hñ–¿a L2¨‹Uu;•ÐvC¯ô꬚M1Ÿ¨EEu«¨f5ØÐå´Þßì{"ÏÄë]õÊ·+‘E‘„KD‚HíÔš+º¶ï´U"O® è‹ðz+�� �IDATÙ ˜Ñä}cÔTSËÓ8Q(ŽE(ªžëÕñðUfàÜM!•Šf`ñj(ñ»’A±íŽ¼Ê˜kšç?`•R!aÚÆ_Ú?i¯»YUhŸˆV<hZã˜cŽ9çœs6mÚôöÛoçóùF¥áb.¨ipC¤«jh8‘Hdpp\™&¸ xµ—h”t–Á)¢Ó…Öy´jõ@h#´¯®^\ñžðG9ª= /Ù¥~¥Zyn8m³RU°¶¦r8ÚZ×aF†É´­å„ˆÅæs¡]Ð)Z74Ý ¸€Æ89¢ÂµÙ9ͺ´ÖÏðRÆfí 0—ÉW©î€¾-är…öSæ†ÑVoáRDH ¥ãÆ™·£éBTÁä­¨ðnø(àšæ™¹æjX5ë Câ©S‡.§5KÕ â¿Œ·=ÑVûj­ÒV©Õj‰$¢Û¢ÖÈQÁ+'\ŒSØÆÒ–£ê4S‹ó6½Žõ8a(ÀŽXYŸ¸Œù8Øk¯•zêW^X©Ú*íù`LÄÑhã¢Ã+¶šQ EùÙ-SRO¬¤ý$aëׯŸ={v6›µË(EJ±X,‹*ÅÿÕoî‴Fæ<xòÖòUnP^4þ: Å‚ñSÊ šsz¸Ø†±kð4ˉ<Ø!J‹Ã&*W•Oë—ÀßßµÕ¡PFµn )ß -@åûÂM"�èéUk2¤›V¥¹C{s<zÞîõØ ´"­®‹†"ÿ¤S´ÍŠvNhßxÔœY \tü™$I‹ ªm€MuntÀS™OÉ&›;RÇ#èy¥Åó„'�syG t9­ô7T‡÷7þ$‰DâA<V–V¤¦;@é@¥á#•y¬îuÚ‰ HÓŽî9ªütš�nÁ-yWâ â¨&#ý**íÏÚÁ²ÈÔêØb´OÀËR)¢UI%±›¶ë1vX¥z½2^žUN›ìÝÒ›Íf vAé²RlI,¾#î¢ûËÙår9‘H ô W¦Ö¬´ =sN¬Ý)’à Š7íììäEëÐ"UÞ£vòI ìáØ“5-�ÈÑçóv©6?<ôŠ7h¥}Õ±VرEîöÊØcÔÙÌã’S'Ô©aÅè� U_K9x}â$Û ªÔ"¤Ç‘ªºœÞmjc‡vÔ;8*kD ÄS ¤•=þU+WF£P((ŽC¡4ž µfóúî4X!+Òøš<ÔïìON¨m6Î2§Ø‰ö«OQ%t9­\PSÄb±b±¨H!FØ�XïÄÌj ©…é䨨ä%ó\žà÷Ý‚¶Ð½»G§êˆçcy¹/&® ¨U…õLãb¸*-ó”ö1jNÆ-éÃC¿AŸÃnHÙÁÐØŸ'ÀcŒîŽV‹ÕÆqª«º-®^¯WëÕèÉÑúäzôhu`ÿ¸Fœ~ “}Þ‰æÃ`Æ¡µw¤H-¼»}ÒZP Z<ᩳx™¥+¥ÓéÁÁAà[¾xƒ5NHe”°g¿°ô˜DdR¤æjA1h¬ÛgU)c‚´J©ÁíÉx„ÊÍU_•y&]P=r-¨šù+ Z¶Åa«(¸­öövFO¼á_’%A   •=êKú0LÎÚTp¿*Ó ¶Ù8Dpp¨^Ù‰%ŒL�šÐøÀ›þör,.Ü„ž{¶æl<rqõLÊ»±…ò;p/¡Ëi1BÚÞ¥:S‚b,™é9¢Qᆻz”SFT2DÃ@'ª´`„¼–¨“¢Œ2ŒškAR)ÅÏåá'HÛíÞ9äJ—�àÒ‰&‡ù$è~5ÇÒÒ¿=÷EGÓµ`â†ø7SßM¾S¨œ_©®ª Ú¨FfDâÏÆ A$àF<>cû¥Šé°_M´«„¡ q¢Ø­:Œ*\¦#ÃH§Ó6ÿˆÛÓ¡},…¹^óåö hbkÏ6R:VÇ£zÒûjžS Ž Ü4çœ«í­¹å.º4Z{·ÖìÑ›¥zt4¦²¹(E&‘@Ô t£R8�K½ °ŽÙK$gRŒ€ŠÂ5+ŒL1Ic'¥¶Þ;8÷ œ¥‡Ç›¢ l„W€¸DÖIeþI“c'3θIÂPn´‚úè ³Ý‚×VÙuÔ§(PW¤îª™tØËi=HšG­žf¾Øzפ£¬ÔѦòäUœP§×ˆ‰¡€ŸfLeîÌ‹ò´¦§Ü*ØîNk#ÊÁÕÑÑAŠëÁ®ÁÑ„œ(þR›«Ü5çA»GvËÌ{zú.@“©þQ OÞœlŒkÔ>WK&“]Ñ®Ú55žj¡P°/RµÏyOsÅÿ¯èœ‹D£ÿ3ê£íÆ 2gêOŠ?(…ã0Ÿ1uÔ®®®3Î8£½½}ñ⎽½êŸ4òÐx–ïQ4—"¤A`ãñû*N_¯EÑô›éîí‚ 7è-}®Ô¸¼Q{°–êM»èÄ A·œò?ËóS ñ”™I™(™²äÀC¡ pŠxªþÂ5Çh5›X Øt³ÜµªÌqr͘�Dn8¹™VV Ak4Žj0ÍBÕ}à‰ô8r”ì™Ú†Òoã‰)MóXt¢Y˜æ ÍôzÒ…½œV.**TÀS[*•Œ…PE‹¼TÕ Ä¨8¼E<ÁiJ.¸½t:]­V©~8á PŠ*—óÊÍÚ!×d!"v£å ZI®À¼9™ßTÖQ¬°NkcÝL$¯ÀàkP œN×F"‘è®hôÞh,‹§â5WÓV0B¸Þü#y·×µ=ÜF«éjîw¹ä#Éä£I-‹«, ³Þ fNcU˜OÕÖÖÖÕÕuúé§ÇãñU«V±£´ŽäÅìŒÍ󚸤N·èàªr–c«—U»>×5nô¸S>vJ$Y²dÉî{v—ÿWÙu©a£60c6?dh#€�¨+œl@?ì2Ì[cÑ c¦Öj·£»(ÌÚÑ�"o²=´¾ P@ g‡z¦¸éŽÅaÐä³™¢ÒÛ(5e=î´Ùåxøfz˜u^HÅGNkjÎÒ_=2:yCõÒÞÎX…®d¯è7DKí!t9­„P@Ã(3¦kæ‰V‡ö ‰p9À p(O¢–Å4Þר‡Š¶˜Îª6½™–`ZÉ£`çÙ²lNŽi,kzG%ÊSvá0ëù±ëììì´|¥^à|ªfèõì9;á s¢RÅ…AÉ¥È"{’hYjÞiìæ6r÷çR×§êïÖ£.‹Å‚Z|1Yùv¥4£”x6¡ÆŠ/ÒDÖž3##”‰t|Õî˜C¥RÉf³?þx4ݾ}»>54tM_–5Úcg4Xë“Ø^½åüÍùÃn?ìè#¾ü?]~É%—4|pîܹ¹›r»çîŽ]\�a Âfw@�Û¦ýv | ¢óå&+W©TŒ:¼oN–'À´?EÍðs<¨¶¶6{ ï†AØOQẔçªQ RnùBÅ8Ø®¦ôà Õªš˜,èglÃŒïKM’ÈP(wJÜf‰NI½ëæÕBˆ™k†Pª…*Ô¡ËV…wB¶¦ãözØ£<çÚ!l´P(³W|€,K}˜õ ©¤cT~W¶18�ûʨ¡ÀhÛ£v\US€bˆJ1*xâµÎ¥›-`�B[»v§é¡¶4”#g_|ø@Ÿö~í÷Òð�Œ§o¥J±ž˜ëw‘z$b¨F¢+£õiõà… RÖÂÕ™å8Qô*ñíh{ÈʯjΠ··×nÜBL'Ì3¯fï@U°ÌRk‰™|À)A¸˜ ªÁ¨‘£Ž:ꨑ#GÆb±£Ž:ª££c`` ˆ¦²‡ƒIÒߢðe–ÑíØ^å™hÌ÷PÕyVÅLÁ::otÃé5Í’ò¨S©”y>úáÚù 7å¼(ýªXAŠ„ôH4ï$i#¨Òz€Žyg÷f”ÓVg¨9ƒ !QnMÛTéÖÀÁ§Š¡`U”_�æ‰Ý¹á´R!| Å½-1{Ú0n¸�¢Aû@½ÃÚì*Åö¨»â¿Š U’`# íÀF›!5jTWWW6›íïï÷*¼ø<EãP1ÎaV: Î<j÷…#ä†()±ª?•â,@÷ª!ó ͱV´8N\<&€ìÇX¾¸œz%í¦;ÓS¦L‰D"ëÖ­+—˱'c¥ÇK‰KÔwÕ)þ1çÊ]+ ©$ÎF‘ß*‰Ä'%†ÕSs&å™' T}k…‡Ñ^j4•jeóæÍ/¾ø¢1Ö<÷ÜsÛ·o/•J ¡I<¿Ýƒ©0„B0gÚ±pÃgT¡ÍÖ:$±ˆ"80s¬pûßqãÆAÐÛÛ‹­·*®–´Ñ¢òÞª@ád6–È §ÅÔ�…H/ÖT½{Ò�”ÚxkÆß£vCã*b8Ï×jçÕS×Á 2Q@\€EœJ¶F`ê ÇižrŸ7KºœÖ¸ê�j(5–aéh±¥Û¶ÿl^D ¬Ê/b¡Šq9«!vÂ& ‘ŽeÇTWÜpÖ?6èèÑ£Ç_,™p†úµªEY:¢wªd NhùL’ÓQPI Þ©ép¢Jb+¿ŽÄó�5SÊ’N7œ—^ Oëõz$ˆŒ;ö¢‹.jooà¶lÙ‹Å"Η"UP)#»/lÅ"e—Ñ6 ,ì#:]8KfÔÉn‘LÕ’,q®¥°�ä¥ÐJ­?ù£déÆÒΫwþîw¿{óÍ7Ëåò[o½U(*ߨ$îHhÛwŽöš*EjŠÀ a:vÎ ‹Eš+¿{úLvÙTŠœ(¦k<Žƒ·”ËÈOußSüSz40/Š1¼¾•¯ifJ†AŠ*¨’«’(…}DE6‚O³ã© 98Ö¬ª¦p”¹�M0ÿ§­{¹ÅbQYmØÚRÐ fAƒWrf­ŠÕ†.çƒ^ ù'LÓXÏ g¶ v¬ÞÈ^°åÈ:ÕHöÇæ~™ê ºÑ–r3ï!ûX,¶}ûvkxXIåĵ½‹J &Ìþ^I*È 3%Zi´Ûd²_TÙ¼ìMùÿAÖªî$³–Ôú”žÄ~»¶a g×9˜ÄžD¥³GwïÞ=þü ²Ùl<Ƒݑ D#Q:®°fõöa*90R[ƒ]3�ÆAëòÿ¶NIóì }>n0™LN˜0a÷îÝ@®=ΛH$Ýu%W:±Ô“í\3X©TŠ‘bpZÐÓˆ=´ ªŽÐÀ ·£å͉ÄÔ©SÇŒ³hÑ¢\.W.—mÿ[à v+¨WS²Ò>{Ô4ür¢¿¿Ÿ_ǃå0Z¡ ¤ìR¥Âm+÷(‘\±X´:¡m{Z¡íííä=N䈼ò¯†bµÒÖå1^£DU«Õ …‚±¸âÈ=™ƒÕ¨càcÚ×ÔÆ3}G ¼Ãi²ÙÅ„kE¢cýÛ(^cûQµ%zÎ`1dðßh‘„ÈHû=zPµ‹ãM`hßÈ~ªX,qá^Ì:Ø’k!|°" ì@rS4(£‡¨ÈPÆ0½ =]:¥ù¿’Ok¤#.žŸ§ám?k+ÿÿåÈ"Å­Å7ß|“«ªü—JÛœ¶`OD—l0bÍ|»HðráX(Êÿb\4geø`.Ju€ì©2°¢QªEß¹\]ªóÍÅ鯧ó·å˹rÿŽ~¸r¼\;±ÖöX[l]¬iASKTÓ†Iòv—½  6lÙ²Åân-¬y½Ð"¤ã h$'³óåœ3öUå|j ÚÑ ¨×1pbÞ €Êıñ´c¯®E‰à&£õU'Œ`†Oþ‰HÑÓ¼à¿`@t‡kÙ\Ÿ<œÄ+l• Ñ9B¸!¸0�Ö¸±?FŠºœd9: àl€›´ž° Œ—J%â/ùjÆK’hîOÑŸP"×Qgmi¸&…4å¥6ûB ÔãïrÃ%Ýp.8-d[üHW_C*si^/Ú“iáðp HfÓA¬Âè¾ÇO­bM2?íšzhŽÔC©Ò5%·ÖÅï‰' 7Ò•o(GvDâoÅ#ñý(#à‚ 9ZnÁ!'8�äfð<­†)ל´bj›'û°&Ôßñô¼)8»¼æ{O+±A´ýc[ô¤håœJ$‰n‹¦~”ŠÅbAd?ºÌkÕè«Tª•1p—ÖÐt-D]ZX™=Ýtž!UV|›mx‹Ð]“š^`0Û`„Vê™T‰Cý¨Ž.Ø+P´4×Ã_R@ÖÔQV¼ ÎÕ*€^kÎúTåIJBÚ3ZBT�oŸ¶(EWü"#úÁ µÖë„.gî¬5ÀQZÄP™äfÞOîSG u0Ó£¥Á‹(ãˆÂN{†£öŸrBÚï‰ÏkŠãÉa1ƒ­ú’ð<Ú+Vymó¨#ƒrn8–±P˜VªzvT¬¢åP®¤+®ù_ba"¾+^ýHµðB¡)Gú#©Rn›s»\4UQàdúLðAN¬¤^n8?¦f„ôÌœj»ªwÞɷÁ.ª:³öÍV5›N É><ÅæDãá¡ú‰«é{±ë"á¡•”Ø·‡Ú˜§¡€o-;»ár|Ä^4ü›U½5+*@ ¡¥c{ž^RH° Öнg¯åIÍ,¥B½Ñžá«šƒ2ýPIf“Ø¿ZðD9K¡"4G©”h3 Ú$#ûÔeîÇÐOŠÕJ °0"zt½:ߺœ/OP�ü=á›YЈuÐP^ö³ÈÊjþkøz:%`+UîVGV­<“™ü A7æÌŠï MmƒÚíà·àÃðè5í )¯QÞåÓ©16³jGeÌ+h°F‡ö;�bEéPéÖòèêh|U|俎¤AÂШ£Ú5Ø7+i´6™”xê"J?f÷! Õ²¾’äÓÔAÜz~-â<”²Èê{ôÛìfé&*µ„­I34bvã@ ÆŽ5‡2(ÛS2–<fÔø{ŠJ}†«Æ`¬JÿQî³ßE‹‘.½Bo<šZÛ‡…B¨´îsm2Îb $à:º`O2N'“IûNå†1BØGÉ£žkØ:@µiE{¥Ø¶Ž?kñÜòl® Ȩy&¢LJmæ¿! ÑD9t9-F¬±8Éš”h›‘ÍJõCgÍ@¬Á@Õ¬&`¦‡Ü£fDÀ ᇥÖÝɰÓÖ{ðZ¸°{0Zf×­ @ L™U5ÀþÕ,Ù‘¬™&?(ìÐRÂŽk4­F_»)ø'_Ñ·¦E Ê8:uïq.¨VQ¼Àk¨F—©¢|ì kÙ•0Óƒ±@CfetUµ7ÍŠ·¢bÒ*·¬¼´Ê†‚‡£XÄ5Û]xHn›2Q¤¢úN•¤: £¨2¯zhköàDEM mqª§GéÌnÍ�u—MGšöÚÑQQˆ�Tf ƒNA•¤oM¡O¡æ Á·­KÍ–ãà†³hQÑb,&Œ�üI·ŒŒJ=·mrUÉRÐJèrZ¹”òÙ6]¥Áàó¶é!.TÄm</•JŠS² ·"qÙf|aQ{ªPfOšI©Æ´f­èL¶x"‘°^|b ‚ð4šT‘rieÃ5)yÊ@¨!€rB¦ÅCMz”ÓETuˆG»ÁjkÜpí;Oà‹0Ð,©îtE‰F�%º÷c<1ÝGµŽ†x˜l:Ìõzs¯}O‹àc§ŠÈC1ú”_4 à«”å§ç鈃û@¯¼€µR�U‚ðf'À Fi›8̰”ŠÚ÷F™¶‰Gã­j¦KJaǧR©x^“ÛÑò”y)Œ»6ꙥUçªòîîîã?~çÎ[¶láš5•TPƒ“©p7œÒP+|¿½nа :×Â,{Œ0Î µ]°…€-t<¡ËÙ=A!ã„øˆ†vò÷æ9><¦¹ ®âêÊÕÁæ³ ÕfÖñ4U¤'Ê&²Ú ]òqмnhž^1 x#;'Úà²!ë-•J$1JWåDÅË, 0®‡éF…‰@¦‚÷²<`–ˆa |¥'þlãu tiÝAÖbfz=°|¤bHþxÉ0hŠ<mmmÉd2›Í’Úº!gåwÔ�•¸m�Þµ½­g:º¤N=Sgž4LF…V)'¨ƒÙÓàî4\0»L×Þ5öŽ$†‚¡½_…2ê`ï~{$5^X<tÀw ) } vŠÉtiªÝÖiÊ}éB< "±x,ÒˆD#û›.® ¶ 8ã¤sÌ1—^zéòåË÷ìÙc‡W]gJÓ…¤Óq!.ô6¼’;Ø“±€É øÊËàÑÁiƯÕp´õ…5­ƒkéŒ.…qzÊ.€”aZg€)ôD[̈âu*0 †}×i>m`z“dëØ;Ú €Í’Éd¿Üš<üí³2ZI$étÚêÔPª˜íãg­znŸQÝF*B©TJi”à’ßËSµ0Óü+$rž¨å~Î�Ž)׿¨Y¾ÓëŽØo1J1<‚ôªðÆqþùçsÌ1Ë–-{饗†ò52R`Ô±%Ap"Hj½ U<Ó²’¹voFÝÔ×´§­b—°±i§J»}v ´…€z]nPjzZj ô¢c„!¶ç�àÞ> „7Aé Ò°É ÎšaDÆDêG×s_ÍÕŽ¬¹ˆK=™Š/Ž×ש=è¸o£{°'¿aƇ~¸··wppÐ:piªD(¦‚7^-î€ s¤ 3²a*Š©ƒ˜U!àž^\èrZ³ŒØÄ²<l«6x=ÕqçÖØ¶‡Nÿ¬³]ªQ¨26„xÚÚ!R zŠfNh}=nsï^Üq¡¶èÍô{ §Þ´¿JŒ€ÀVE2b&"µ+î5~uâ’˜” 0\²%‚DŒâo°“¨<óCÀí8¥Z¸`’Qù=U–n`½Ò'¯É„‡`ŽF£ãÆ»à‚ ¦L™’H$Þyç\²=[#Sá6=¿¥âfjjµ]@ß’!éQ7¥£Õ§MfëkZ¿MGSÙ ZDõš1övTR!8§ƒ$Y#å³ßË�€öØ0»¤¹^5•yg{ÔWõ“öÏ6Œ ªWV«cªÉ›“©wS‘H¤ú×Õ ± ±Øœ˜¶¦ã¥f!‚þþþ|>¯=HÍÏ´ÿÄs`#YL¦³ *¶­ s$!1\Ìöóæ«TO„b¾'YºœÖ,ãÄ- DÜ 踯ö0ˆìÀÞxÄ!ÄDõzÝdˆÖ™PQN'57i€›Â:ðÈ<36¢Ž›QÀ1š[²@2t_´¡nÉŽà(¼ˆ•È¥T*‘p*ÔV*põ m2s¼‡¹á²Ô²­˜ í}=ÃDy^بåp†Ê £SÌ*0Z9 0ßPq«°˜]IµZíëë[µjÕž={V­ZU(še»(FÙ®³L?G[Nññª CÍÊÃth¹IZÕq¤é‰*Ù[Vü…“{oiʨ=s‚uSt‡ùÕÄp#±”†&Zƒây¸m¯Ë¢)Â,u¢Ë9™©[M]•ŠF£±x¬^¯GmŸÝžÿ}¾íWmŒ1ha ¡q~ƧÁßàä,Ÿ³ÓaEåøÁ‡)í©*©:òKUÄÖSvÀ é`ç1¡„.çZår9›ÍjŸßã„�m¬ówbh]E›uŠ{ÑqQò¼—7íÁ—SÇEy#^'ߣ¸ðú\?¦_w§Kí*k^ÏÍR‡1§ˆ[Õ¸Û\Ž•³ z3æ7 Biqä´’ƒº»âh!ïq¬úªž`>RÃ:ê–Û¡‚lVÀ‚bEßµ··Ä99N Á[UZ3‰²cÇŽßüæ7±Xlçι\N•]šA­I¯+¸&{Ƚ4ïÑZ¢Ù86³R(yƒ8nh<Ö¾a¸)uÚí@$ΰYÒk¦ÛOPï «Ûû²¤MŸ9^‡Ý®EEí–+ÉX3¬Æ“ð`•8µôßKéÿšŽ·ÅÛÛÛÛÚÚì™$¿—¬ü×JÛ÷ÚìIªSÑkÐÃâ‰8¡2‘†Òy?ÓEvX¹®ÏJ1;„­ ¨Ñy/…›ßð,@˜å´rU«U£yghÐíd¨X©(i<®}_ýK'ú»Ì™{ÛÈ^í:(/'¹ŽM³Ë„`lq%çÀ"Ø×2uhžÀZ&4«œÐ */ˆ:W ÓVà©ec[…4½]F3æ 4ò-*ŠêåˆÄ˜VÜ£äÈL»ªùâ”%—àÕ~;s”J=BŽ/$XÖ —µÅøëÖ­K¥RøXöXg¯ÇKÄÃÛÄÆ±9QÉôFü˜NÕ-J]Q{*féöÙßÇãqKa é®Ã¿H-S°8³÷Ôúì @ƒ}Ä8baa`¢:d-^!<uÛünˆóÑ8ÿ½f ·J–'•ƒÍAWw×g>󙎎Ž'Ÿ|rÛ¶mµZ-è Ü6¿Ìn‡3WÃSÞ]­Vëìì¤u:uêÔz½ÞÓÓc9®òéiX%ÞuÀ™Ú& ?ËAùj×*©ED~Lžä)„.§‹ž<qç\I<=à™4$•ñÆ´íÑúBœe§‘©–à‰(AÊy<˜k+G‰p€y£æÃ¬êD4È+Ü«æ©iœÀýeUÅ1k…#¥}i<¨RÒ©€›ª…*öWéSU»H)à´V£³JÔ:èBS1³‡þRSºr¹\­Vóù<=yœvé(€èd»™ã±ïä« ŸÍ@‰Ê<[ãŠM¢Aƒv%†X½½2¸Ã��=IDATñj€6}’L&áïÁ�yíF{¼Š ³\M…SA'ª¹äý:Qiæv…¨zü:Dêö≲'ïŽ4‚QínRi´mìqZ"˜¾Ÿ½qb,»Á]»võ÷÷‹Å}mvAòG# ÐçðCã”bÑ.8•JM˜0´ŽNµLKŸ¶(ÇÁðèTJáÃ5Ϫ¼æðëxCZtgí. &%Ú–E =|¥C'œxXûÍJ*VAØ«%2­éÓ°e2À~…²âk1M zrb’œè^kW‹ÎÍóÒ†{Õ<Ž4È:{\› r`ú—lÿÃf} -*ªP›6Kp*øc¥²šsvú*i†iõRß‚'O@äëñù“¿juTGJ4QˆšuøEW5Ë2 T Oý"´4GƒZ+»È dŒa2-D=“j'Û[­¯O[å0qh¥ ?­;ܺÅ1›â­É}ZÚš-õ=íâ�.ÐvdEÖ&Á‘]i …_4ð4Ž?‚ă‰â—Šõë/¾øb$Éçóvåÿ\N=œÒ‘V^‡àI¸=ÛTÅbqÙ²e@ðõpytïÄÞ6ÃŪ�„ªytÞ ¼blùAO¤„nÆ3Ü ² š·ª!oÅ%ÅìÓߣo@ΡjÉØ „"Smn+ÖÞ+”!-¥²öÚR"‹Òb7õ" Ú›¥¯@’Çé®U²ü“™­R©Ä…)©y›?E‹Ú†~ÚaÂ|ë% �¢´¿ELÍh‹Wô·ŸbÑ«eY,lÍ'²ÑóiÕHZÇè^"†Ñ«P³NÚCGoYSC> Pr¦#-¨§  ¨H›ïñ˜O±Â†¶nûÓ{›ÖÊ[ ÖàÜhÚáÐ)}äM)I1f‹Å&Mš4vìX'º8XXÃòÙC¦Ô†Öà b:Æì="päR‡)Þ8£áÚ].Ÿ³FN‚T|,ˆ-ÛŽWÚuBð‚*D‘ÃèÞMñÏ�.P‡a7¢™=àF—#Ö ¦ ?ÞGÕ"<rMí´…YNËkT¥±4c¨Þâx[ø= ðv4…hK_í ƒdâ(¹y¢¨Q) ½’4+7¢NÍÒ,?j[6•J!C©M“½ ÏIÓ«Ð^76Q'áù©T*edø:½·n€¶Š: …°+M¤.p¢€.íº3'Ï l‰D XÜœFŽ>RUWÄ…hã7¦ÓéD"Q,©¤Ù]ST ‚ «« Æ#ßRÃ8‹'“ê³¢î}IóÄ»¥^¯—J%6$³nKª¬ª3í¥°*1 ð0HHy­d¥*&[©TL ˆPL³%ºwÖ€$a2K c›’ÿ{ iBy–ñÒýjžoísÚ s ±ûc‘Íç\ý’zããö‹ÛëºGõ‹(œrÀžN‚«i M~ RíÂŒa¸–¤Ó+´¨è* 1Í&p™Uvp×D§­taa­õ‰Î°ìoˆJR9¾´=¤JѺÔ÷U)ĉ¤‡NœØ÷Ø‘à3M¢¨Vv’Õ°¡ÞvÔ–€ª>‚9‘dô•´‹¬DXÄé¸:ºèzašj/]'~šµ aÍÒ9s{ôŸ•&F^ôiÀaëÓ¬N9™³±£n…�ÔF°¶ÏПÀĨ~!?üp+Á+o£B ÔZ±`¬€BBg’<©@-’uÀUXûKrGµÈJY­¤®´£UTP}™œ ét9™.¥<(æÌ;öõõ7Pê„FÑÌŠ) Ýa¸UuIÓ´©P=rA sñx<þ\¼ë™®ÒWKõÓëιøœxÛmžò%Sí~QÁ£¢:F›©ÚáÓ:0`%6<ÔJ¼}r¦=K6³½Gµ?t j8kqó"t6nh�TEàÜõ“t_°Î8èˆ�#îA ©ØßjµjQ°Gü®ƒu‰Ä´iÓ²Ùì¦M› (ÆpÆ01pØ6e8†Ób§”íi Šq Š{Š ¥³5�Ò‡Ú½ðÆYtN«ŒÇâaÍ58ÐI@7¤Æ_*°ú)"M¥½R‚^'ä§J/¯'gAªŽÚ9çòù|¡P°@«“: ?S.ªCš¯(´‰ñ,¾„T[ÇʼnÄÈ‘#-ÓÂiK’'ϯó8+Ýp1ÝÍ)¯.£ò  àhþë7+@΃þj‹–‰²iéI#;D°(Áÿ!¢ãÆ*“º/µßWEöï èÔ&ÀÈÎð¯vÝpbMgŸY³p®_AIŠV- ikὩÕkaŠºçe6Zï¶)_-ß'“IË‹•ÓÞC‘YkÊâqCÔ}Í¢;ìWU µó`Zô*|‚5Q󧓉üŠŽŽ»`»ì‚GÄDünÔmVÒ°QoŠê?Q3UcSj`»3{¡&LaèNXué?Ó ³gE1ZÁT�¥ ’ ÞXXU0ß 5¦Ör</‹ž&¬*QBjI&A>Ÿ'—RZ0˜4ImÅÇ(­ª&Tê–ØmbI‰‘s£Fš<yòÖ­[ÀéÑE0Óìõu\UFmϰ1ÀYØöЀCé½=}ßTòr\¥ '>ó¸k=0 —‡Q6 s¡G�ÔÞE÷§çØxƒl< ‚¤¨�eœS�½*É*¿ ‰Þ#¸Gʘ�Ö9ì¼, ä1Úãµe8@eä ]N+—– =Ù,“lÅPòz€øc"¯Ú²’‚B韱º%¹ Z©×ëï¾û.C—NhùqNªõÂ9·´&›Íjà¦5Cû ”b6ˆ*„*A¹át÷Djè^«в•PW(ø.…AS… QLÑIIK Òk^‚Gío+´Ú³`_’N§BQFx){2öƒÚòÕá*´Ý�P9¡¦†_ñZr4Ñ\œq¢B^CkªµZ-›Í ó*4 þ@)jtªCLïÇnV•М¦Øw¥«Ð�Âöp¹\ÖàC už"Íú•”Œl€LSÑ¿fí;¦¬ð ä¹òr¹lÛÀ §îUŸ¤ºSžp'pvÈC;^pÕÐ…Õ¸Óv5½}­©xÇS+Ÿxqkâš E©¡–jUŽ2t9-›Ëñâ/ío{Lˆ:âQwxSî:ÿHIÚËšiƒ{?è±½rÞh?(Y€²î«®R¥Á3FõIg¨ð€µs2ÚFGXGҸљgOŸ£YRÓ›#¡ü¥þ£Uç¼v¸YsêjŠ‘rBµ Ò,ú¨kµZ.—ó&ŠHòðßæ†•®T«[SÛëÐ2ŽYÀ#Ftww÷õõiu¦ýµ¤£ 6g©Ò®†ö˜Òõd#”๙„FC+ðͺùu'k(ÃßPŠ´­kC£ÔÞ¦*w(Ä_ežIjÁõhqB¡ ÷°èÄvé”wæÏŒ©! [3@P&[AîQÇÓTæãáè-¨B•Š)¨fâJ05vÙ†¥N®À"å8Ph¥êw„.§eج µÌ0ÓÔU,VZ•¿–Vf—Î þF{6†]¡²¡€K8ª)PØŽd\¬‡AG8ð&TC¬J®µ¼|Gðã(…ye;~Ƭ®GÅ3ö³Íd$T~Ô à¿-¤–¢¡Õ?€¨q2hÏF�ð¯NÔ²­rB{Iù€™R¶å‰P‡ÍЃöZK¥Rgg§sðÕ9æe¸áDmJkf¨7œ(ŸÕ°öµâD�ûjîÎ]°á=ì¾öihsªÊ¸ÇÞ,b 5>khá‘ýH)þEcêϺ?ñýZSU.2ŠçXE¢ªkTR;E.Ø¥vtt¤Óé|>ÜÆ;Ô¼J-)X_ìõ©* õ#mèÒVÔïo!³gèrö1è�¶¾!ïõP¦ãªØ%Ÿ·¯ìÄ‹×J”êRÐ`¯+S“FÁd^c€­o°±sâkSªP:/c�Ó /=¢ÂLÃvéíÓÕî7óªæÿôÀÛ˜ùÐꥑ}ieÒ#8Ðó†Íz0š*ìŠÙCÍH4fJà)ÌÃÐCù^û+ê{ìŸìf±‰ŒRå(•J›7oµ¨ ­–èÐbñbjÏã:‘ Òú!•(µàD¸ìmÜ O¦\.i)F¡n .0ÆXj¤”þœs6†¥Í!j;ìŽÖÉbl7Ô¤ZKÒËÈ~Ì3YÓËÞˆ6Y9­[¨OÑYáiPl€8Š‹4_¢�åc=öì³Ïž7oÞÆ¹lƒòÀuTN#Ìr ìImû¡®dΑYò3;\¼'B—ÓbК–k”$¿ùõxjiZÁWÂ4%.d‡iù‹#GäN]›Š­²(Ò~ð8C5ëÒ8ˆ�Y-Žr êl³–•'‹aÀ[ù{x ž©¦k°èT-,,$oè³™ Ek ÿ­ò doLÕ³ãS9¥e€µgu´Vo“î= è/UÔµ9°ž™Eà‘ä je¸Á¦ØÓðø““å¥^܉”,«ömZêQ„×謲rðÈXÅ Î$=  ŸI;€†j%wd}#»H­ Ûôox¨kæà†“ÝÁxÜ ñÆz¸Y¦gpŠ*öì ��¬WP{OOÏoûÛ½{÷*¨GiY<ÜÏœM‚•à ª*¹R€ÛVWáE3é‹ ]NËÖ±Ç;kÖ,7\ÖL›^GA+Ë”5tó‘â(ç¹×ópÇ×4+×–L³À_¨`Åj«Õ®¯6c›acÊg¥v–¸[ HTuFu—=¥NO’@Ï-ÏJõ’½QGÜÚ«ïé¹¾):úèÔ#vRXªòjë©VÞh¢fEÀ«t PÛäo´ž‰ƒW²dXŽTRêêõUœÆÃ@I ¤dÞ6P×È3d¥t±Êº¤){ƒŸRö[ètÊJ{¨8Zoйùèy3¹Úãq¢^a¥$Oö�iz¿J¤¤Yo$™âžŽ¶è³r"ªëeuÍsý³L<ùZäšÑL4¬:â^=Ó£@ŒD"£F ]NËÖI'tã7†Ï!\á W¸Þ×r¬…+\á W¸>ð,'‚ùóç‡O$\á W¸Âõ®óÏ?ÿ�.§^¯_|ñÅú9O æßóOïíÇ’Ëøû ÅÁpïÉÛ94ÞÈŸ¾†ƒá2>°×ñ~o˜Ðª´ä8¿‡ßÞyçÀåð+¼éë?ñ_×4öÞþàûýýá…ýß|ÿA{anø@ÃÁyaá/ìо°a4EaÒ®p…+\áú`Vèr®p…+\¡Ë W¸Â®p….'\á W¸Â®Ðå„+\á W¸B—®p…+\á ]NøÂ®p…+\¡Ë W¸Â®p….'\á W¸Â®Ðå„+\á W¸B—®p…+\á ]N¸Â®p…+\¡Ë W¸Â®p….'\á W¸Â®ÿãu`ñäÇëVt÷¦láZ'^âBõ—d'¸¿`-“÷㼯*>áiÉù¿±Ì7ÝtÓ\N,›7o^KüÞ³Ï>›Ëå>÷¹Ïnüšk®¹ë®»{Y¹råË/¿ü•¯|å ²¥·œƒyý⿘0aÂÙgŸ¾õ@qýÛ‹.º¨%7S(²Ùl«~û{¾N<ñÄCæ^:;;ƒ 8dnç{;áÁ9˜×Æ8âˆðí8çêõú~G“Éd^|ñÅB¡ð›ßüæŠ+®pá W¸Â®p½w«^¯çr¹yóæýã?þcW¸Â®p}@+t9á W¸Â®Ðå„+\á W¸­ÿÀ~S>Ÿ_¹rå™gžéœËårO=õ”sîüóÏ;v¬sî•W^Y»víÈ‘#?ó™ÏØç{ì± 2™ÌÔ©SªGÖßßÿôÓO;ç.¼ðÂÑ£G;çV¬X±~ýúîînk¯AðØc9çÎ8ãŒcŽ9Æ9·víÚW^y%á _87ÁÓO?ÝßßüñÇŸ~úéιÞÞÞçž{Î9÷ÙÏ~¶««Ë9÷â‹/öôôŒ?~ÆŒιR©4gÎçÜÙgŸ=iÒ¤ƒçFæÏŸO‡³ù"W¯^½fÍšt:}饗Úgžxâ‰J¥òÑ~ô¤“NrÎmÚ´iñâÅι/|á ñx¼µ÷²eË–iÓ¦Ùÿ¾öÚko¾ùfWW×g?ûYû›_þò—µZíôÓO?þøãs7n\ºt©sîoþæo 4þü¾¾¾©S§f2™ƒííØZ±bÅ”)Sº»»sË–-Û°aÃèÑ£/¼ðBç\½^üñÇsŸøÄ'Ž>úhçÜ[o½µråÊD"ñùϾå÷²nݺx<n§Û9·dÉ’wß}wìØ±çŸ¾s®Z­Îž=Û9wæ™gqÄι7ÞxcÕªU©T xáܹs‹Åâ©§žzòÉ'·üv*•ÊK/½d§Û9·mÛ¶?üáιË.»¬½½Ý9÷ûßÿ~ûöí“'O>묳̘?ùä“ιóÎ;oܸqιW_}õí·ß1bÄ%—\ò§W,Ý=ñˆ3ÿÓkv önúø_öþÝÕu×]÷Ì3ÏÌœ9Ó9÷½ï}¯\.çr¹… ž}öÙ+W®|ê©§J¥Ò¶mÛ¶nÝzÊ)§Üu×]}}}¹\nÙ²eÇw܈#»vË-·T«Õ\.÷ì³ÏžwÞyË–-›7o^©TÚºuëÎ;§M›vçw är¹Å‹O›6m÷îÝ?üp¥RÉf³¯½öÚôéÓ*óØc½õÖ[ù|~Íš5‡~ø­·ÞZ«Õr¹ÜóÏ??cÆŒ… .Z´¨X,¾ûƒƒÇwÜm·ÝV(r¹Ü¢E‹2™L2™lù],\¸ðG?úÑí·ß>kÖ,ûï"ׯ_?{öìr¹¼k×®õëןvÚi÷ÝwßöíÛ_yå•É“'7»ï¾ÛÞì’%K>õ©Oµðvn¼ñÆx —ËÄöµ×^›3gN¹\Þ±cǦM›>ò‘Ü}÷Ý»víÊår+V¬8æ˜cJ¥ÒO~ò»ø¥K—~ò“Ÿœ={öš5kòùü›o¾™J¥&OžÜÂÛ™;wîOúÓŸüä'ÿ÷Ï_.]ºôª«®:ûì³'Nœ¸xñâ ”J¥žžžÝ»wŸtÒI?øÁr¹œ¢SN9eçÎ?ûÙÏ*•J__ß믿ÞB'Úh4®»îºûï¿äÈ‘§všsnÑ¢E .,‹›7oÎf³'œpÂwÜ188˜Ëå^xá…ÓN;­§§çßþíßÊåòž={Þzë­ÓO?ýÁܼyóàà૯¾:nܸ1cÆ´ðí<òÈ#<ðÀܹs¯¼òJçÜààà¿üË¿˜X´hÑ9çœ3oÞ¼¥K— …wÞy§Z­N™2åÖ[o-•Jf"Î<óÌÕ«W?ùä“¥RiÇŽ===§žzª÷+²ùêœÛŸÿô«K¹ñÇg¾ùÛò¬9ý·ÝýHð¾­k¯½öþûïŸ9s¦ýo&“±?œ{ƒƒ<òÈwÞÁêÕ«¿üå/ApÆgT«Õ ¾öµ¯-_¾<8˜ÿòË/7ûî»ïž{î ‚`ùòå_ûÚ×ô_þò—W¯^ý /Ìš5+‚ÁÁÁsÏ=78È–]dwÞyç#<¢i7òÏÿüÏ¿øÅ/‚ ˜7oÞõ×_¯7x饗nݺõ`¸‹M›6-\¸ðä“On~Mv‘sçν馛ì“ý×mÈï={öAðíoû™gžY»víßþíßz?Ûªõâ‹/Þ|óÍ·Ür‹ýoooï¦M›‚ à"íàA0kÖ¬^xƒÃÅspî¹çžûµ·³nݺ… ž~úéú7ßüæ7/½ôRï"—,Yòÿðú ®¸âŠ7ÞxãùçŸÿÖ·¾A6›ýô§?ÝÂ{i4 .œ5kÖƒ>hc'‚½{÷®_¿^/~æÌ™6lààìܹó’K.уóOÿôOO=õTkßΚ5kæÎ{ÑEÙÿr‘ÜùÄOØžä?ýéOg³ÙG}ôöÛo‚à7Þ¸âŠ+šÅ–lmÖœþ/þó‚cŒ:çbñ¶¶ôˆH4ö>yÑ]»vmÙ²åcûØ¡Q‹,—Ë÷ÝwßôéÓ·oß~ÜÎ 7Üðï|gúôéÛ¶m£ªù¡[GyäŒ3¬p¬O}êS§œr ÿ;f̘#<²§§ç†nxà>t·3uêÔ3fD£û;ÇëׯO§Ó&LøÐÝK$™1cÆqǧ¹mÛ¶Ë.»ìšk®±Bô‡kM›6ÍÊe¶º»»gΜ9}úôéÓ§ßqÇïÍC‹ÆÚÒ#FM86‘êxßá===?ü᯿þúQ£Fæ ··×ršï~÷»:âô!]7ÝtÓ-·Ü²|ùò‰'Z*\ázõÕWo¿ýöûï¿?•J}ØïeÞ¼y/¼ðÂw¿ûÝCæíÌ;÷î»ïþ»¿û»ïÿûö{éëë{üñÇ—/_¾|ùòo}ë[ïù÷¿ï=Ò+V<ûì³+W®|î¹ç¬Ãöá]GqÄUW]Áp}`kåÊ•O>ùäµ×^{h¤q7ÜpÃ'>ñ‰o|ã‹/xôÑG?ìwtõÕWOœ8qݺuá^m½Ë9çœs?üpçÜöíÛ7nÜhèšp…+\ÿþµnݺT*eاC`Ý{ï½ι7~ØÐpý¯ñÇg®›\7?¸ýÞGß×&UOOÏ7¾ñ ûóÚµk3™L&“y饗‚ ¨Õj·Þzk&“™9sf¹\‚ T*}üãÏd2?ÿùÏëõúAÕo7ÀL&“Y±bEÕjõæ›oÎd2—_~y¥R ‚ ŸÏÛfÏž]¯×ëõúC=”ÉdÎ:ë¬R©t°ÁÊåòÌ™33™ŒÕ‚ x饗ìú×®]k7xíµ×f2™«¯¾ÚnpÛ¶mö 4ƒç^¾øÅ/ògï"kµÚ]wÝ•Éd.¹äöØù矟Éd~úÓŸÖëõF£ñë_ÿÚ~dïÞ½-¿— Ü{ï½öçßýîwýèGíÚ¬]*•Î:ë¬L&óÐCÙ›={¶} ŸÏAP©T.¿üòL&sóÍ7ç z;¶nºé¦×_ÝöØ7Þ˜Éd¾ô¥/Ù°Û™3gN£Ñ¨×ë>ø`&“9÷Üs†Côè£þêW¿²?W«Õ믿>“É|å+_±‹ß½{·]üSO=eï½÷f2™ /¼Ðö^¹\¾øâ‹3™Ìüc;t­]Ùlö«_ý*øˆçž{ή¿§§ÇöÒ׿þõL&óÍo~ÓöÒ;ï¼cX´h‘®Ûn»-“É|þóŸ·ôÖÖàºùÁUo}äI‘ñÇg®üárçܸ?ÿÖUúàp…+\á ×{¸¶åÜK\ÿ޳ÿÛgCöp…+\á ×´B—®p…+\á ]N¸Â®p…ëÐZûkÅÎc^ÙÐwÊäÎð¡„+\á W¸Þ“õú–Á=A÷\ÎÀágüjéª)ÝG…Ï(\á W¸Âõž¬_-í)>Ì iQË\N$RhŸ|ûÓ›þìW¤ =ù ᣠW¸Â®¿ØLþd¤»RüÓ+¶OŽ ùç\déÒe_û^xÍùž?ýóFãìIÕKNˆ…O<\á W¸þb×¼ ±?lŽþY—á\Ä9Wèßµà]ýÈߎ7ö¤#ºw¬]1bÜQé‘cìŸÿĪ–òÙÞùÉcÂ'®p…+\±«Zmw.ùg]†ù›Ý_?uêÄqãÆEŒqú¿ÿî×7lŸñÕÛþì×k•ÉM'uî Ÿx¸Â®pýÅ®-íÙP<¬V)þÙO>ßu§L™ðÝo_=mÚ´HιM›6íØ±ó³_üÏÿžß­—cõbøÄîp…ë/w%GÖ"ñ ñçÙôŸúÅCãÇ;ꨣœsÿãHÈ9r(����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/editjmagrange.png��������������������������������������������������������0000644�0001750�0001750�00000544641�11332127304�017744� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ ,À"x�� �IDATxÚìw˜UºÿOåÐ9LOwON0C†‘¤¬a ãå*«"º»Š×Àªàª(¦‹:ÊÊêQLõ®˜@\QPEQ@ ÃÌ09ôtOèœ+‡ß…-ÁÕÁe½ëïÖç™gžêê·ÎùÖ9o·êœÓu UUÃá°Ïç{ðÁ�øAºbî<;ÐÑÑÑÑù% 5M”yl#´…B.—k„ÆápØápÀ0üÃf………wÝuWIII^^‡W®\ÙÙÙùàƒA�øGÿÿÀ߯¾ü·z-êèèèü"dù­uïü÷ms8Žûáæ]ûÿ /,\¸a˜‘¿òÊ+óçÏ—$IÛ£í<t[û?00ðÈ#]sÍ5¨Ïçëêêzà ŠÅbзÀ0|ô¶(I_ìný%–û¨Rwß`D¤Â|[–⩬Íl0Px Çq´Ôëìè�Œ¯*lê ��ÆTxÛû†eY)ñ:â)&•a6ŠÂÃá$Mâž<k·?t¨}n£¼È5I0¬àvZdE ÇÒ&é°û"0 U—ytj_UâîŠð‚Toc9!–ÌZÍ´‘&Ã1CÊ ]í½C‡Ú×”{;û‡%I)ö8’i&™aV#Ž¡CáEb.{WðPûqU…-]Ue…y¡X*Ëðù³ª‚P,e¤É<›±w ÁИroK×ÂòýÃ1޽.+/HÑDÆb¢ÍFÒ?ÃP¤¢ÈÕv¸°ê2O·?$Jr‘ÇžÊpÉ4ã°  %H+rÛ;}‡ p gPUÔ²g8žÉ0œËn† Œ¦ 4á²›{ac+ ›/áÊâüPŒåDOžU¥h"c1RÝ?EQ¸ªØÝÚ3x¨ýè2Oo $ˆr¡Ûža¸Dб[ ‰ãŽ{œ¾#ª¾ ­wPQÔÒg4‘Ig¹<» ááH’¦p·ÓÚ󪾢È5N0œàγH’‰§ÍFÊf¦}ƒQG—ºt&L÷IÝ'Ÿ c��–e£Ñè¡ù÷¶ð)Š"B$ù›Ü¶¢(²,kÆ?`o³Ùžxâ‰Å‹û|>$‰Ü{fýhê½óe CL6ó úc³ÌfÒaS ¸ÚÕ¦<ߨÜÑ—J%'–9÷µö$‰±%ö¶n4+Ê£cÑøàPÐJÁ¨*öô�Y(°‘­ýétr·ö+œûÛzã±x™Û4 ÃN& ¬Ï?„ÉaDÛ{üÙLzl±­±µ7•JN*w6¶ö$â‰Q–>ÿP(q[ 6›ö S˜b¡ξ€È1•Ss{_*•œXîl<ÐH$Æ”Ø:zü‘H¬ÐIÇãñÁ…„pHêö ªWè tùÒ©äÄ2gãžd"1¡ÜÙÜÞ‹ÅKóÃÁðÐpØaDU‘ë󡪘gÆÛºû3éôøR{c[O2™œ\îÜw 'OTy;áP(’o%X&Ó&QÅBB½~ÍVyÍš°Iš}"QSlëì D"Ñ•L$ƒAHDîîPD¶8>ÐéK¥’Ê­=ÉDb|™£¥£/‹—¸ ¡pth8d§Q ½ýƒˆ*æ[ð¶îþt:5¡T³ONªÈÛw ;OTxÍþÁ`0qYpžÍúC"Ûh¤³'À2™Ñ…–¦ƒ%–·¯µ'OTY»û‘¨×N¦SIÿ`ЈUºúd-uZ:|ZÕkÂÆ•Ú[»ú£ÑXqž!‰‡l4+BoV•líò¥Ó© eÎÆÖîd"9©RË(^î1 ƒÁHžy¦/0ŒC²ƒF:züL6SShÝßv°ê5a£ -=ýƒápT÷IÝ'Ÿôù‡DžýÏ•,Ëþh#Ãðþýû§L™’Ífµ*��‚�C� †áœ}KKË„ X–ÕŽUUí{(w,à kßN:õ®»îBý~QQQ,Ô1°›H·Ý˜Ë~(–Ͱbu±CK� �`¦p›‡ (Í ñ¬�àµÓŠ ÂINd†,4n¦qEUã>ÃJ(yìt4Ågyñ8>»â4“‘ljrn§ÍHXiœåhŠeÅi¡�uú£.«Áë²în4Óøø ÷—Mý40¦dgK�¨ê˜ Oç@,žæÊ œ /÷޳ÕlÜß=l¡‰1åù;šû $6}\éç}8‚Œ¯*hê eX±²ØKsþP²Øe%I¢¥/d3’•Ey_ð)|ZuÑgûú(4ºhwÇ/H£Kó¢™áX¦Ôm0ÒæäY ….Û7í& ŸPéþb?M`µ5Å_(Š:¦ÜÓ=˜ˆ¥Ø²''*=ƒqÝä°šöu Yhbì·Â¦-ÝÖèCh|•·¥/œÎ Ey‰¬ÐLåYišlî Y Ĩ×ο‘ħ/Úº·—ÄÑI£ ÷t s‚4ª$(Î E3%n;Œ mý§™.vÛwµå„ùh­­.þúÀ€¬(5åîÞáD$Á”y‚¬vÄÜ6£ËnÞÛ9d¦ñqåîÍý›6¶äËý~ã*½­¾H2+Tå¥XÑ7œ(̳TsOÐb F†ÍüVØÄQ…û:‡Y^ª*q…âÌ`$]’oC1¬Õv˜èR¯£¡5`¢ð)•îm> G§Tíjd¥ºÌí ¦Â ¦ÌëT¨+Í·ÝNËžŽAMØöæ~šÀ¦Ž)ÙÞì‡!0¶ÒÛî%2|E¡3ÃI}ɧÅl¢›ºƒQ]æÚÙì7’ØŒqEŸíë#Pd¨‚Æ®`–«Š]‘$7NçÛp?à ÛMdy¡óëš0Ïç}ŽN]ôMû É£ËÜþp:Ï–zìºOê>ù󸤙&™��üèóM®‘ÏmïíßõòŽ#ZÝÏ«=Ö( 9ÒØÎܸ곉ey·Î;Áa¦>kô?ðÚWŸZseÝxšÄ´¿ßx½Þ+®¸‚ã¸mM÷¼²³{(9¦Äi5’0 ÷ %zóë5Ÿ´”{l¥n+Aë¿h'MvÇþsjñ´r£‹`a™÷G£Ñ¸ôÂIS*MýI.r™/˜YZ倪óÉ"·ÝJÓyÓ¹cz|þÁ8¡„ àãòWê6Ï?¥¤¹Ó—äFU�›hââYå•Nxl±5‘áÂ9ÃË‘ç¶òlÆ=]a›‰*É·ìé8Væ±t&8Q©ðZ#)~8Á–¹-² u¥¼£ÕDïï8ÌTq¾eWgÈ@âenëLU¡r¯u(ÎDR|¥×ÊŠJ_(]è4(¢Å˳Ѕ.KCGÐb Kó-ûû¢‚”{,ýáL’+½¶+"Ùb— ð¶@Üm3äÛ»»B6#Yâ¶îíVæ±t¥XA®ôZ£~(ΖºÍ*€º“^»Ñn¦÷õöMgˆ&ñ2·µÍ“UPáµÇÙpŠ«ôZyIí ¦ &“hî‹åYè"—¥¡=h¦‰·¥¹/ #H¹ÇâgâŒPéµe8ÉÉ»L޵úãù6ƒÛaÚݲɷµ±'‚ah™ÛÚ3œÊòr…×σ1¶Ìm† ¤s0é±z_OÄn¢Šó-{ºB•z,턨¨^k(Á†’\…Ç"ÊjÏpºÀi4Ȧ¾¨ÓB»,»:‚&š(q[›}QBÊ=–h6–* lY^îgŠòŒ$èç[ §é›ÎÕ@–¸-= CÊ<Ö¾`*ÃÉ^k"+ĘR·‚‘Ž„ÇnpZ {»Ãš°½]a’ÀÊ<–΄ ©^k8É\¹Ç"*PÏpªÀa´©ý½Q§™.Î7Ó4ÒD©ÛzÀS!¨Ücˆ2Ñ4_U`Í ²/”)Ì3R$q ?æ²ÒÞ<ó®ŽÅ@–ä[ö÷F)÷XûBé+UX“Yq Ê”ä›mHè>©ûäÏà“Nóp0|ÎŒJm,çGtkkkµ±œ%/|Á Ò!§¡mhÞ)5AÔÜÜ<aÂ-åߨ5ÍF3¡“Ì ¾ýª‚–¾È¬ñEùv£ªª0 ¯^½Íö¬û¢�°¿7òØúÝw_2S”¿®ÛÕÖ�¬ÝÖv꤂�€¦I¢Ümnokù|oO,#drÂèbH ÏØA|rÖVæÁ|ü…76ZÝe7^tʹ'Á)²$§ƒ'.³:]VŒ³8 [hlÓžÁb'}B¥`OO¼É—Sdž\n'y…no çÛ¨I¥ÖDVÜÑ%8MíøëÄR+/*—…²áºIµ^—Ía8Q.Ï7Üó×7.žsVS=àË*˜Ùc'M4ÞìK˜h"ßJ·RŠ —ç›|a&‘‘&”Zƒ !˜`GyÍœ¤ö‡2…NE`;„ÕH:ÍdKEЗ±'˜M1ò¤2Ë@Œ'ùšBKŠ•¢L‰Ëˆ£h³/‘g¡l&¢É— ¼ÀaèÊ0¼:±Ôâ²Ñ”0®ØÍHC1¦Üm�nõ'Ý6ÚDãM} #E¸mtÛ@JRáÑS˜gÄ %–`J ÆÙQ^3/_(]è0Ð$ÖäKX ¤ÓLèOÁZâ2ö†²Éï„q5…–4§"Ù’<#¡M¾Dž‰²™ˆf_‚"ðB§¡{(“å•IeÖþM c‹-ñŒ4cÊóŒèOºm”™&š} #…{l†Ž”(ƒÑ&_„§Åñ%–pJ޳U“¨@}C©m ñf_Âb \Vª5‚ ¤4ßÔb’Yib©e(Á‡\u9Ë«þH¶8Ï@âX³/é0‘ÙìKVè4vgÒ¬2¹Üêp‘?¶Èg¤Á(S–oD`¤¥?™o¥Ì¢É—0¸ÇaèÈð_bî°±C„UzL²u ¥¼vÚ@âM¾¤™&\Vº5R!¸,ßä 1‰ƒÂ„P‚]`fµ?œ)rHkò%ìFÒa&[ú“†ç{†³)Vž\fñÇøH’SdI0ò`”)u1iñ%\Êj šû4‰{†Î¡ +‚ … ãŠ-ZÕW¸M €Ú)Ö}R÷ÉŸÁ'›|‰\#?’Ñ“ÃÆÿ¡ïï^‚¿ÏøâSF·ùc¢¤lk lk:8ùù¬Ê òL‡&Žæ¸ówÓ¯yb‹,+M½‘[žûLQÔÁh�` ±».9)w€ hFÚß=ybͤ±Õ_uF6ï M­tµõô kkJ[wó­´¯³#Èb2pò J))E�8†ÖÛiTŒDê&TíÜß3±¸¼¥%O϶µ•ç‘çΘ œ=¹Æ×Ó©$§MÒgN-ç£/G9N*5¼×Èð*æµRgO)èlo•r–*óÎ÷Ê›ï¦3Œ§d”*» a0Ûq•ãî²< …u 1 WäÓM~FÔiæ&?Ãò¤³/ÂÇ3be¾!Ë+ﲎv3$†9¨–F”Àô S£Ÿaù„2KGK1Òh1ž•ã|B`¸s˜1Ñx¾…hdeL*1îëÏò¢2µÜÒ2Àdyyl¡i8)†’B‰“–à‹0V#a3`íC ÁUnÃ~VÔi忦�ÃòÄbsLˆ¥Å —T”˳4v38†;©æF”Ôœ°Ú2KWK2Ò(1ÁÈqÞk£PîfŒ$î¶­ƒ¬(ƒéß ³¶ 0YNS` ¥¤`B(vЊ õ‹‘°ˆöa¨p•ÇØäÏò¢:­ÜÒ4À0¼<¡Øˆ Ñ´Xî2p"è²N3i$°ÎaCÑ’<º%pX O)µt‡¹dVå6¦X%ç=V C‘Î!†&0l`EL¯05ö3¬¨L«°`2œ\S` §¥á„Pä U�wY‹p˜ˆö!FUáÑ^ã~–•iå–æ&ËËã‹Lq!’Ëòh^ýÖa"MÖ9Ì 0R梛6¹ÔÜæY±ÊmHsJ Æ»­$!à E vêÀà·Ußϰ¢<µÜÒ6Ä¥Y©ÚkŒfä¡8_h§ îfÍ4žg&Ú†E&zþê~\‘i()†“Bi-ÊÀaí&B÷IÝ'Ÿe�ÛÈ/GÄž\D€aØj ºêä#ìYÛð½ñizµç¿.yÏËÛs‘iÖøÂÅLµÉCΧ†a¸Øe~~ñ™»�§µxS˜gþŸ¥s œ&mÈ@@° O$–®z[þɅd……¯tSƒÃQNT'¯™`4-8íÖ|o±Ýj!P(K¢ôí$q°kOãWͽ‰Xô£­_&“);.Œu£óÏýÕ)'ž`"T³³ÒÈç_|ÙCUEv1›Ÿ}Ò¸ÒB7ÄFÙp `…ÛŒøæ?m �@ß@¤½?rÙÜÿ˜ÿ» C¹»;ºè²óª½†P$ƱL(£ìà0[@}Õè�šPDÓÇpå&{#B4+;VR{£¢ÃˆY hË G`È(7¹« hR ½³‡dPã¡Z‡ù§–æ Vî‹ùVœÄá¶ažÂ‘²<bO?‹ÀÐä×]YIÆP–@…‹ ¦¤¡¤äµáu†…zmxc€ÃPx\!µ³'«�h|½ÛÇp¨Ê'}1!’‘‹/«=ÁnÄì´yÃ1d´‡lèc�M*¦¿êaT{¨ö ŸàÔÒ<"Å)¾˜è2c4·ó$Ž”»ˆÝý,CSJ¿¶?ÀfPî"Ãi0!ym8‚@!ÁH¢…6|_€Ex|½³;+«Ð¸BzO?ËŠ *ŸôÇ„pF.tࢢvG›sšÐ¦AG‘j/ÙÐ˨�šXL7ô2¼F{ÈΟ`•'‘敾˜è2aF iâI©È'vû4aôö€1^ªi€Ë ÜED2Ò@BòØp :‚¼@Šø>?‹ ðÄbzÇAaÔ^?ˈ 2ŸHH¡´\hÇet‡«s™Ñ¦CášòëÞƒU¿«—á$0ÚMv‡…8#;‰¬ öEÅ<f¦ÐC<!•ùä7>‚ É%ôŽnFP@—jäÒ¼Z–GÄÙÝVÇàö OH‰“ØëgžTbØÞ•ThlÕ¨ s‘C i8%Øq@]aÁB£n ®û¤î“?ON)1äy‚XAníµöÇø¢Ú_s_D”•ܤ€C®ðÚr•öÊ;M` jŸÛDåЇ!YVeE=b è»§‚Ê<Ö¥¿ñèÛ»|Á� ªÀ~ûïfzÆ\�’l¡°_sš¦z¬Òð[!XU(5Ò¸( ãKìÛ ΚÑ©Êdiïêiì J<�@*���EQQ“KUBY`Œ@Äe¥üÁP<}rmu$ÉtÄ~sö©,áRUÐúíÍMNôGF8€‡SbÏpúܺS{�Ià—‰‡ÊŠÜrj`0îRÃ6«eÛ®&s`�¶Q À‚ìö Úàö((P…g”PV-³!¢ úb²Ç›(dÿ è aÙå(.´!̓"€ "<”c¬Zé€Yô'”3Lbða)Ï�»Íè×>ÁLÀ…Vdo@ÀP¸È÷Åä´�ªp’SRJ±F¨=,åa§Ýí¬$\`=(¬Èw„DN*íP$«3j™ ‘UГ=&ØB#ƒ¢‚½ä›~Âá"+Ò2,*TjƒSr”Q+0+þ¸\`†ii–œ4ì1£ >ÁDÀ…Vd_@@Q¸ÈûbrŠUN8Í«¤RdQj I.œgB¿Ñ„Y=Çà"ÜY T8à(£ gÔR¢¨;"»M°•Fö |'ŒÄáB+|`X”U¨Ä§”£VØ^¾¸ì5Ã4‰4‰N­„ûƒ&l@D`¸È÷'䪜pZ�¤Rh1j I.ì2¡»ú Z=~Gá"Ü‘²"¨tÀqFJ+%V@PgDva»Ù; Ú(X«zƒ mp[HU¨Â3J8«–ÛQ}1Ùk‚$Ò4ômÕ+lÿ ÁP± $ä8ªpVþ„Rh† n Jy8ß„6ä„}[õ=19£ c•Á´Rb…!êKùFØa@÷„œ0Ý'uŸüWûdî)GQÁK››ßÙÞyDGÙÂ9S.¯›xèir þÑ�� >ú)çËæ‡ÞøúÐdwxüí†[æÍpZ 9côÐc šXáºíâ÷þÏ—$†Þþ»™cJœGtó)�N²jCGȘé³±Þ¨½tüž÷ö5·<£Gw²ÁŽÎa˜Íð¢]ä“Áž¡dLÍS!Ë‹›[š›:‚‚i¸³äÓk>=0Œ¾¹s §a/åã½&8¶tô¶÷ Ó-aœ(´gXº°Ó7Ü/ô»!‘OE£¬J”(�Ždåu ÃN!–jhÞ Aà ®1&}[·ï ds¶ E’ý •(*1PžtFUI…+mŠ?’46O 1P8«VÚ�'C”ê5A$µ… Ù)ÐQa.²(¾„š ñ.u0¢ eiJ«Ef€!p[XqP…­!…Ä`¯Y퉫YšàRýigAÄ88˜QK-�@pGDu #ZCЇò ;ªŠ*\eSú5aN5ÄÂá¬Za‚ù“ªÇQÔRÌ$ä0€Žˆ ¸È¢ô'ÕËS‡²P”QGÙAF€Ójá·Âìd¥@kXÁ1ØkVúâjF„&¸Ô@ÄXPí�qfÔ €`¸=¢ºhÈD‚¶BkÂbª CcòT $8hŒS ³p8«–[¨@þ¸ê1B4µ…9¿VbQú“@6œ…"ŒZeŒ ¤ÔBD P[X±QmCà³Ò—P3ÂaÂ<œQ‹-�áö°šGC&´† ‡ÝFµ'®r246Oõ§A‚…Æ8Õ ‡²j™È*ÔU݈ơְ’«zE…K¬J ¤8hlžd HV­´V‚Rj "0¨5¬XIÈNöˆŠ"p¡ù»ªÈ€F;@R€‡Ój± ÜVœ4dÑ„a°Ç¨öÄUV‚Æå©o«>ÊÁ¡ŒZf €;£j¾2à íaºOê>ù¯öIF‚ß6ò’¤o��¯}ÒrÅÙ“*GÆœCøKzg{§(+�€³j˦V{W¼±S’•O÷ú.9c|žÍø=c9¹Ç—å­¼ñ,½ÓÑÝ|²ŠÈ舨2ïVeÈ Šd…+ŠxœÞUeã 0Fõ%±nÁ¥JV(&qšQð†AAqØ‘¡ç‰0B7¥eÕmÝ7¤JΓ`•LHªb†8*./.ÈÿUY‘$I~ù/”&iÔ§¸TÙL‚d*ðÅ•^Þ®ÈF�ÁŽGpE(€ÍÄÞ!XæÊ�03p2-@]1UTÀdß#8 Œqþ–àáR³˜¡Á â¤$Q{â((^£ÔÃ%Lqñ-Q‚—Á'ß'Ò"Ti<2œEÜ´C '09V:㘤€qN¾)B2˜ìâÛb#Ñ61”E \h% ¤ ![q¥+ŽA(·ð-1B”Hcq.1‹Œ f)ѨÚGpX-4Jm1\<DØx'ß—$RTa’<2”EÜ´„B 'И⢥Ž8.)`Š“oŽ‚ &¹øöÁH`”MŒ0Hˆ L¢¢Bþ8bÆe+©tÅ0�@…•?=x"š°»0˜Áb,\l9 È vR¦Q¥;Ža°Zl–Z£‡ çú’XJ€Ë-BŠG†²H>-a°ÚGIDqÓR»&,Ÿo‰¼ &åñq"+‚*«e‘`öE ‚Þ8bÂe;©tÆ1Uc|Ë!ÂX ÔØ…¡ eáb³(ÈP ØHÙˆ+=q Ô’o…åNd¬CèOaI.3 Ê"y”„[õ£Ô~xÕOÌã»âDF•V1Æ"Á,ì1J�€ž8bÄe'©tÄ1Eã|sô°ª¯¶ Á,aà"“(Ê?X ÙŒ+Ýq †@©Y8p¸0Ý'uŸüùäÄ<¶;{pî�IÀwþ~æ_×6r–ÿáׇ6ò¹¹7Í=áÚÇ7Ü€6›àÒ3'˜iâè¨sÇïf^󨇓«Ü‹çNµI‹‘¸gõçóÏšPUè8ì‘è„Nضm[&“É”í þkÈÿ3¼, Ûý¥@iU85åý“©QˆReaÛ“´ª‚Rá°„€8Àþ žG RnKP&Lª0óû¢‘GY¹æ˜”237Ä)6rœŒ 1˜‡â ¸Ú•$͘Tfæ£*¶²{"FQ*Ì\_šäe¨ÄÄ¥E4Ìb4! 7MØp±À(6Çh#*WY¹½…(•¶3IË*(5q1‹óh!ÍîÏày¤à$åÖÃ…UY¹–8 µü[aENPáÁ,t%loĈ#J…™ëÏœ•¹Œ„†XÌKó zR„‹ŒbÓ!ÂHD©´°ÝIJR¡R#°‡8‚|ÂIˆy´Ô§L¨Taá÷E "²râ4@™‰ rDZ@Š œ¨ÂY<Ÿ,¸Òq¸°QV®1jÀ ¥Ü̲+ÁÅFŽ‘ÑaóÒ<…ªÝ)ÒŠIÅ&aŒ6¢ò(+·GfæzÒ¤¨@%F.!`Q-4ð0 |iÂAˆù´t N™P©ÒÊk%\eaÛ?šÞu�� �IDAT4� ÌÄ…8,) ENVá@w‘‚”Û”“ʵFåQ®)f@!¥ÜÌ d‰¬y­ê½4O£jWŠ´`R‰YØ¥¨úÞ4)ÈP©‰KŠX„E < ƒ¾4aÇEAl‰VõºOê>ù3ødO 'SÝÏßòŸ?ÜÈç6ž{î¹k¯½6™LŽ$"¼üòË—\r‰6£úGíQ>}: ¾ÿÑéû·µk?ÃYqйö÷tÍ@&÷?™ލšíNS¼‚ÐL”ÇÂ<á¡XY…ú2”“àM˜Ü’0š1ÉMñûb&Q<4×–¤�yiv˜%b^@1¬ ÒEr¢´' V\̧ø½Q3*ŠkŽQx)ÖŸ%ÒVH3ibÉ|Šƒaµ+MÛqÁAŠ1““Ý·?fÄÕC±=iŠUЉñXˆ#<$+¨÷ 0©ù[a1‰¨šëHÒ² ÐlÅcî¥^ýYÊEò$"·}'ÌD¡Š›âšãFÈI+¤™´„²d>É!°Ú™¢m¸G ûb&*»)®)fÄ`à¥Ø¾4Å(hÅÄ4ÈnŠUÔ“¡„`ÁÅæ¸Ñ„InšoŒ DõÒ\G’–T¸€fBå ëÏRyO£rkÒ`ÁÅ|Šß;(ì@Â�A—f"!â4“•†Ì'9 V;R.æQüÞœ°¸AæËY - ˜¤€9ÂC±�€ž4í +.6Å&LʧùƘ&ŒíJÓ‚ ÐL˜Ã"<á¥Q|Y*à ˜| a´`’&ŒDŵ%i‚¼4;Äq/ YV‚ ™Or8¬¶§¾+a•=×ômÕ÷gÉŒ„ÒLRD‡YÂM±P»Ó´줸?~xÕë>©ûäÏâ“i ;tôä5òß; íG9ÂøGdúÝŒµN¡P�üËú“Tdˆ5$D¢œŠGr˜£ŠÉ¤  }Y£ gXî̘L¨`Ã¸îŒ ‚@™°†´„—Óñ0O…y²ŒJddÌÏÜD…ÔΌقñfTè̘qXqcÌÊX•æé¨@–Óñ¸H°t™�tgLvŒ3 bgÚL!’cú£ "Ådrˆ£"QAÅc¢&,%¨H_Ö˜wP˜ÙˆŠš0€2` ) ¯ ãaž ñT)•`d¬Ÿ1¸‰, )]³åÍ(ß•1c°ê!2~Ƙ•±r*äé¨@VÐñ„D °´—HCèΘlgDÅŽ´™BdÎô1F^EJ©ÄOÇ¿6ÄÑEdJRáެщ³,ufÌTt`lOÖ¤¨p!™` ) /§A–Ô„åYV:Óf3*XP¾+cF ÕCdü¬!#aåT<ÄS,§ãI‰°/‘!µë 0¡3c&ÙEd}Œ‘•±R*1ÌÓ1‘ÐJx£ É”¬Â=Y£g)Dê̘ ˆäÀØÞ¬IVá"25À’"^A'"ä©*É)¨1ºp‡•®ŒÉ„ VŒëΘ`™ƒUO¬úr*‘–p?kðR;3&+Æ›P¡#c&`9ŸÈú#ómÕÇ¢‚NÄEr¥ É´¢Â=Y“ciDêL›éƒUoU¤˜Lé>©ûäÏä“TüGãÍ?ú]Îí¡�€Š‹‹o¹åEQ��’$avD¯TN�` ’VòúFU Y�°Ä«ˆªB8,Ë*$«0 )¤Š A*ɼ‚n/r �„Ã’¬Â² £  ª ©ØQö¹ –DQTƒeU…$F AA! °Ä)Ø C TAA H% ™;J¯ êažÈH…A² €¤"9a�¨äQÂXTD=òDF"ìÈ>Va0¤ …¼„UAA  ðÑÂ$^A~‚0–$VþÙªÏ ûñª×}R÷Éãã“°(ÊJ¾Í ªêÑMúÑ{‰„ÕjÕ"Â÷Úú1™LšÍæ\Êßk,Š"ŽãªªÊ²ü裢.—ëºë®c†á-[¶œuÖYúë¾uttttŽ }ôÑœ9s2™ÌæÍ›%IBs_ † .¸@/ ãÅ\ÐÒÒRPPpØïrÀÁi*Çée¤££££s\سgOooï÷‡UUAÐËHGGGGç¸àóùìõÑÑÑÑÑùyÐCŽŽŽŽŽŽrtttttô£££££££‡_Б·Þz눗\rÉš5k¦OŸ~ÒI'ý´¼?ÿüóÝ»wç>þö·¿õz½Úö믿.Ëò¤I“>úè£K.¹�°fÍš³Î:kܸq#I¹¿¿ݺuçœsΨQ£�� _~ù%� ¬¬ìüóÏ?î…¸eË–ýû÷ç>Ο??//ïg«Ât: sN§Õjíîî6ùùù?!Á£«;W’ÿRš››?úè#m{„ gœqƲiÓ¦ÞÞÞ믿þŸÉ÷‹/¾Øµk� ººzöìÙG|ûä“OŽ=º®®îŸ?Á]»v}ñŹsæÌ©¬¬üÑ£V­ZUTTtÎ9ç—BÞ¼ys{{û¢E‹öîÝ»uëÖ+®¸‚a˜·ÞzköìÙÕÕÕÚ…� (jáÂ…�€÷Þ{¯³óàëîó›ßTTTSvO=õTUUÕÙgŸ=ãW_}Aßýîw#,É«®ºÊb±èøq§··÷wÞѪ»»»ûÝwß=ÿüóËÊʵéèèxÿý÷/¼ðÂâââãÿ”ãóùêëë£ÑhÕ!H’T__ÿé§Ÿþäûøãëëë‹‹‹µIò»Wé¬^½úùçŸ7›ÍUUUA Õ××ïÙ³g„)÷õõÕ××8p@ûøå—_Ö××Ûíö\H;¾lÚ´©¾¾>W2Aüœþ‘N§ÛÚÚTU5<Ïïß¿?“É †CËó˜ (*w.¢(Z’ÿ:|>ß 7Üà÷û«ªªP½õÖ[?ÿüó=jýúõùË_þ™|n¾ùfQÍfóm·ÝöÁa°|ùò 6—sܱcG}}½Õj­ªªjkk[¸pa4ýÑ£ÊËË=Ïñ*ç 6,_¾�ðõ×_×××G"íêniiaYöºë®Û³gOUUÕÓO?ýðÃoذáöÛo·ÛíUUU---üã‰ÄÈóZ¾|ù}÷Ý·dÉ’ÜÄóüóϯ^½z$–6›­ªªêè·s麺ºêëë;::´ÐR__ßÕÕu„Íêëëûúúþ%O9S¦L9÷Üsµxðøã¯Y³&×ä]pÁ’$±,{çwžsÎ9¹EFÂìÙ³išÖ¶¿ùæ›… .^¼X’$íã½÷Þûúë¯_wÝu�€GyäÄOÉáôéÓÿô§?Ýzë­S§Nõù|O>ùäc=ö·¿ý­ººzüøñ7ß|skk«$Isçνá†Î:ë¬É“'?öØc×]wÏçûàƒ{ì±—^ziÇŽF£qä'¢�`Þ¼y0 Ÿyæ™O>ùä³Ï>{à 7X,–L&óüóÏ˲üÁ‚ðÅ_”””œ|òɯ¾úª,Ëï¿ÿ>†a·ÜrKKK‹,ËçwÞ¢E‹pyîv»ÝápH’ÔÛÛ+Bkkk~~þððp ˜2eÊþýûKKK‹‹‹~½ÒÑ8í\ÀÒ¥Ko¸á†™3gž}öÙ<ϳ,{ûí·Ÿ{î¹›7o¾ÿþûiš†aøwÞùÛßþVZZú /„Ãá‹.º¨··wïÞ½&LøË_þBQÔHô3 ÓÝÝ=wîÜ™3g–••=õÔSÁ`0žyæ™Zé­Zµjâĉ«W¯~å•W‚(,,|öÙgµcEQ|î¹ç^ýu ÃÊËËW®\™ó¨f``à÷¿ÿýe—]vÓM7!RWW‡aØüùó�Ïó—_~ù‚ 4Ël6»`Á‚P(ÄóüÕW_=þ|íreyóæÍ{÷îyM~úé%%%k×®e櫯¾:´$Q]¼xq,»ôÒK—-[öì³Ï>ðÀÓ§O¯®®þãÿèóùA˜?þþð‡Y³fÍš5Ëãñ¼öÚk~ø¡ËåIîF£A£o2‚˜;w®¢(O?ý´Åb9á„P]·n]4­­­-))ñù|Û¶mùïö²Ùì矾cÇŽO>ù¤©©é´ÓN›9sæi§æt:ß|óÍ?þØ`0Ô××oÛ¶ �pòÉ'ßsÏ=Úo¼ñÆòåËß~ûíªªª5kÖ¬X±âïÿ{ooïwÜa0AØ´iÓ¶mÛüñI“&mÛ¶mÙ²e4M«ªºaó٬Œmmm—^z©ÉdJ¥RëׯÏí?ñħM›V\\üꫯnܸñGoŽ!6455mÙ²eÏž=étÚï÷˲¬í×®„­[·^pÁ—_~y(:¦3ùôÓO·lÙ²eË–D"qÎ9çL›6çùÞÞ^�@&“ñûý¢(jË­·Þ:’x� Âb±D£QI’8ŽK&“N§3 …Ãá•+W¾ùæ›o¾ùæÝwß]__ÿùçŸ8p ··7 ƒÁÆÆÆ¼¼¼c œZ÷Ú–-[‚ÁàG}¤uÈ<öØcÿùŸÿ¹uëÖÚÚÚsÎ9‡çùG}tÒ¤I6lذaƒßïߺuk*•ºòÊ+W­Zõú믯Y³fÙ²e>øà'Ÿ|rL¹'‰P(”N§F#†a,ËŠ¢(Š"˲eeeMMM©T꘺¹fÏž}ñÅ×××/]º´££cëÖ­]tÑ‚ š››/½ôÒóÎ;oëÖ­ƒƒƒ×]w]*•ºôÒK_xá…;î¸ãÞ{ï3gÎÿüÏÿ¼úê«Ï?ÿü³«©©yùå—·mÛV[[;<<üÞ{ï]tÑE矾ÃáØºuë•W^ùè£vwwoٲ塇Ú¸qãûï¿ÿç?ÿY;vçÎ÷ÜsÏ’%KÞyçwÞyç¯ýë3•$)Z,‚ P-**Z¹råûï¿¿qãÆÅ‹/]º4÷`}ï½÷~ôÑG[¶l¹îºën¾ùæææf¿ßÿÌ3ÏlÛ¶môèÑÇTSÛ·oß²eKWWׄ 2™Ì%ùÄO¬[·îxüñÇý~?ÇqÑhT{æØ°aÃ-·Ürçw644>ø`̘1.—käÝÅ+V¬¨ªªúæ›o´²,ïÞ½{Á‚çœsN(Ò.�€ÇãÉËË[¸pá’%Kî¾ûîóÏ?¿ººzÇŽ# l�€?ÿùÏ ………v»ýسgO Ø´iÓĉÇù矿}ûöŽŽŽ—_~ù©§žzæ™gr}¹V«U–åíÛ·'‰Ý»w›ÍfI’.¼ðÂêêê×_½¶¶ö‰'žÐš h4ú»ßýnܸqo¾ùfMMÍÓO?­†ãHccã–-[sýÀ555[·n---ýÍo~sè}ÛæÍ›«ªª¼^ïyçw|:Ö4º»»Z[[¿÷õá‡Þ¾}ûO8±o¾ù¦¡¡¡¡¡!“Éh{®ºêªªªª²¼¦M›–k f̘qD‚«V­zçw´í‡z¨¡¡!÷qçÎï¾û®vët¬]4 ápX»b~øáµk×¾ñÆf³ùá‡niiI"Ï=÷ÜÛo¿ýÓº×âñx6›¥iE{x;vìOHðñÇO&“ÿõ_ÿõ³¹øé§Ÿ¾víÚeË–Í›7ïúë¯?txìüãk¯½V]]½téÒ¯¿þúñÇ?úð÷Þ{oåÊ•?ç59qâÄgžyæ7Þ8¦£öíÛ÷æ›o¾þúëK–,q:Z‡ÛÃ?œó�€Óé\²dÉ&uòÉ'=øô£ˆ¢x÷ÝwkÛ<Ï/[¶ìŒo½õÖ×^{­¬¬lÞ¼ywÝuס"GèE›6mÊ}<õÔSsã:§Ÿ~ú5×\³~ýú¿ýío‡röÙgŸzê©K—.moo饗n¼ñƲ²²%K–¤Óé;²²2ç“$I.Y²$ßyçãÇ¿ãŽ;ô8qéèèhhhк×4:;;~øá£;ÓN:é¤\ÏñìX;ï¼óæÎ �xâ‰'Žø A±cÇŽ;öÚk¯µZ­Çtb·ÝvÛ±6î#aæÌ™5557ÝtÃ0³fÍ:âVtÔ¨QÓ§O?ï¼ó&MšÄóüqÉñÎ;ïÌmhÎwÜqÇ矾lÙ2­áG5jÔÌ™3çÌ™3eÊ”cʽ¨¨Èáp}ûö±,ûOžË¦M›vîÜY__ÿ³ù·Ïç»óÎ;,X°`Á†aî¹çž}ûö} ,Z´è”SN™:uêÑ)ÖÖÖ®Y³æX‡¸2S¦L™4iÒ±uýõ× †{ì1íÆ<//oìØ±Ï=÷œËåúøãÿÕ²ëëëÿð‡?„Ãá5kÖ<óÌ3555Ú £y÷Ýwßzë­'Ÿ|òÏþ3Ak×®½ÿþûGÒÛ¼sçÎM›6Ý}÷Ý555“&Má¾ûîEñP›­[·Þzë­W_}õãÒ�€k¯½vûöí÷ÝwßÙgŸ=kÖ, Ãî¼óNmžH}}½6T©õÞyçÝÝÝ .|ï½÷²ÙìHâ´Î™7oÞüÇ|ðÁ¹Ûq³Ù<vìØúúzš¦iTï'>åü#¬V+Aµµµ---<ð@6›=¦ÃC¡P0 ƒ¢(ÚívŽãzè¡#ž¥P5™LétúøÃÈS~ôÑG»ºº0 »é¦›r; A&LàyþÞ{ïíééñx<O<ñÄã?~ÅW¬^½úæ›o¾ùæ›§OŸ~\ª­µµÕh4ÖÖÖ–••!Çÿ‘¥&lüøñ’$Ý{ï½ÝÝÝÇzëÊó¼$I(Šk—àìÚµkáÂ… ,8ãŒ3´ª!†á`0˜Éd, Š¢V«5›Íj3åŽË¬!†a¾üòË–––`0XSSCQEQv»]Å`0xË-·œ~úéZGkYYÙ”)Sl6Ã0Ú[hq7ååå£Fºë®»´Ù‰#¡°°ð™gžyöÙg?üðÃ={öÔÖÖ~ðÁ8އB¡T*e2™rÔf³ð`0˜N§M&ÓϑNJÓé=zôž={xž·Z­^¯·¶¶ö/ùË;ï¼£¹A[[ÛÏ—F£Çñp8œL&µíŸœûI'dž™={vcc£Ýn¯©©�¬]»¶½½½¾¾> žyæ™·ÝvÛððð'Ÿ|â÷ûEñz½V«u„®588ØÛÛ;cƌٳgÏž=»´´tç·.Á�ˆD"áp¸¦¦f„ ÚÕ­à�&L˜PTT´sçÎÒÒÒ‚‚ŽãfÍšõÊ+¯<öØc'wßJ¥N:é¤7ß|óÉ'Ÿ´Ûí¹™u:ÿ ìv»Õj­­­}óÍ7Ÿ{î¹C¿úôÓOW¯^-‚Ýn?>O9v»½®®.7.TVVVWWg6›ëêꪪªî¹çžë¯¿~ñâÅ�€§žzÊápŒð´¹§K—.Õ>Þwß}›7o^²dÉäÉ“¯¼òJQ µŒÊËËW¯^ýâ‹/>ôÐC#/#›ÍvÚi§¹Ýn“ɤõB_ýõ Ã<øàƒ�€Ûo¿] -ÕÕÕ'žxbII‰Ûíž6mÚĉiÖÙ˜1cD{â‰'暪õë×ÏŸ?ñâÅ×_=†a¯¾úªV’(ŠÖÕÕi3O>ùd·Û}íµ×f³Yí—,Yrâ‰'Ž0w‚ òóóý~¿ßï�Lž<Ùjµº\.³Ù ð6Oš¢¨üüü6”F£qæÌ™»víÒ¦�nºé&ǵ*~ë­·Æ·~ýú+V,^¼øÔSO]µjÕÚµkëêêpw¹\uuuN§“¢¨ººº£o`ÿ555/½ôÒóÏ?¿cÇ�Àý÷ß?oÞ¼¹sçþþ÷¿×ò}ùå—‹ŠŠž{î¹W^yåË/¿Ü¸qã}÷ݧõÏ̘1ãé§Ÿ~íµ×>øàƒyóæ]uÕU#ÌT›’«ªêË/¿ �¸üòË-Ztß}÷i>ùÜsÏM™2åÌ3Ï7nÜÂ… A¸ùæ›�«W¯7n\]]ݘ1cŽé¢Õ.m>Eyyy]]]aaa®$kjj4·dYö7Þ¸ÿþûçÏŸ�øõ¯=nܸ›nº‰ã¸»îº �ðì³ÏN:õŒ3Î?~<�`úôé ÃÃm& ×ÕÕUWW�fÍš•r/++Ó†‘/^\RR¢MÌù$�`ݺu#Ëñx<uuu¹¨ººZ»@´9̘1CÅyóæ%“É^x!wuk“WsyUWWk"I’|á…î»ï¾eË–p «W¯Þ°aC]]]~~þªU«–/_¾ÿþ“O>ùˆvP矹%ª««Óê:wEoܸ1×οøâ‹ÍÍ͹*þõ¯a˜Ýnå•W~4qè„Nؾ};Ã0Z»œN§õ×Ñùßâ‹/¾Ø±cÇ7Þøé§ŸÎŸ?ÿí·ßþõ¯ý°žþùõë×øá‡ºKü›SRRræ™g¾øâ‹ÿÈ`ãÆ²,Ï™3góæÍ7Ýtª™ŽÎ¿góæÍ_ýu"‘¸øâ‹'L˜ð°V­Zõðÿþúëº?üÿ‡rttþ¨¬¬\¿~½6¥Åh4jãäÿ׸ä’KæÎ;ò Ù:ÿ‹ìڵ똆!ô££óïűÎùüÿ³Ù¬ÿ¨ó—±Þè¯õÔÑÑÑÑù™ÐCŽŽŽŽŽŽrtttttô££££££ó8lú@6›ù::::::?L6›=t!•ïBŽªª›6mÖËHGGGGçxñý!çí·ßÎd2Ç´BŒŽŽŽŽŽÎshXù.ä‚pá…ꥣ££££sÑ^ÛzdÈÑÉ´w$ëèüâ˜2eÊHÖ~ÕÑù_A9ßC0Ô^Ƭ…Î/=Þèè!ç—‡Ëå²X,ªªêE¡óKá›o¾ÑVÐÑÑCÎ/UUõ£ó BÅ#<–çùÁÁA½d~¹Õž×ÚÁÿ×p8G¼.þþþ^xáˆ×]wݳÏ>û«_ýꬳÎÒKóñÌ3Ï (zÍ5×��$IÒV�,Z´(//oûöíÚ* åååW^yeî¨mÛ¶}üñÇ·Þzk0Ì­_]]}É%—üíoÓVB<óÌ3O>ùäÜ!/½ôR2™Ì­y‡Ÿ|òÉÙ³g·´´ø|¾œÙ}÷Ý·wïÞ¿ÿýïÚÇ©S§Î™3ç™gž�\pÁ“'OÎU7Žã÷Üs�`íÚµû÷ï�hÕͲìòå˵n½õV‹ÅòÙgŸ}òÉ'9‘�€d2ùÈ#!R£©©é­·ÞÒ¶'Mš4wîÜ_|‘ã¸n¸Aw˜™L¦£££²²R/ŠŸvÓ©õRîÞ½ûX—ãÓÉ•áHŸr†††V®\yóÍ7ŸvÚißY£èÊ•+ÑCÎ÷òÁ<óÌ3{÷î­©©ÑB΢E‹W¬Xñè£^qÅ+V¬¸ñÆ/¼ðÂN8áÚk¯… èŠ+®��ìÝ»wÑ¢E>ŸïÚk¯õù|+W®¼çž{¦M›f·Û׬Y³lÙ²'Ÿ|²µµuÑ¢E/½ôÒäÉ“�/¿üòý÷ßïp8r!çŠ+®Ø±cGAAÁ‰'ž¨-§øì³ÏnܸñÞ{ïmiiY¹råc=VYYév»Ÿzê©GydÍš57n¼öÚk_{íµ«®ºª´´ôꫯ¾á††™>}ú]wÝõÀ„Ãá[n¹eÕªU/¾øbÿý÷ß¿|ùò«¯¾ú¶Ûn[¼xñå—_^YYù§?ý AöööíÛ·ïÚµËf³r¯¾úêY³fwÞyàÛWÏ®[·.Në!ç_ÓéܱcLJ~H’¤ªª¢(J’„ ˆªª(Šº8´¢(0 C¤µ³ÚWZ“¡­? ð,Ë��A4cI’rm A0 kûsæ–E HKSQmÙ\m§$IAh ²,k鈢¨‰Ôò‚ H–e³Ù,Š¢ ²,#¢IÒ¾6mÚž={$I’$ †aíÔ4µ†i;5KQ ‚ÐÒÏÅ‚´µ½Y–=õÔSO9å”ÊÊÊCGÅjkku_:&†‡‡€Ëå:âñG:ÖF5kÖ,�ÀóÏ?___ÿþûïç’;ï¼ó(ŠŠÇã‹-ºì²ËþÉÕàÿ=»)þû¿ÿûÙgŸµZ­’$­[·†áË.»ŒeÙL&sñÅßxãŸ}öÙ-·Üâr¹ü~ÿÖ­[Ï8ãŒ_ýêWgŸ}v.‘Gy‚ žçI’J&“½½½£G>óÌ3›šš4/O$+V¬øío»bÅŠh4zÙe—]vÙe³gÏ&¢¬¬¬²²ò7¿ù ACCC™LF«¿÷ß?‘HŒ;6÷ÓÝyóæÝ}÷ݳgÏ�hëz½õÖ[}ôц ÚÚÚn»í¶?ýéO3gΤiº¨¨èšk®Y°`‚ Û¶mK¥R‚ ìß¿ÿÄOœ5kAMMMãÆã8ÎétJ’”Ífyžß·o_EEŬY³Ö¯_/ËòŽ;úûûkjj&Ož‹Åúûûo¿ýöþþ~maï#¸üòËÛÛÛ3™Ìüùó/ºè¢³Ï>»ªªª¹¹Y–å+V,X°à’K.E1•J]rÉ%×_}nùÞÞÞ³Î:kþüùýýý[·n}÷Ýwo¼ñF�€Ïç«­­]»v­~a„îîþZk|s×î^k—!RUU’$ÇEQ… EQ5Ól´Ö\’$í’×vʲ¬-ˆîõz÷îÝ«…­¡Ï5ú‚ˆ¢¨å®íQUU‹[‚hÉjò`Ö†$IZW Â@„¢¨,ËZðÐb˜¶sÇŽZâ(ŠŠ¢¨å+˲–…&RKáÐÔ!Ñp�� �IDAT@ˆ¢(Çq¹³€aXUU·Û=~üxAý£Î±Âq\,;zÿ¼c­¡¡aíÚµŸ}ö™(Š™L&wGsÇw„B¡­[·^vÙe·ÜrËÿ—ï,èïï_ºtéÔ©Sßzë­I“&mܸñÓO?-**Ú²eËÍ7ß¼|ùòæææK/½ôŒ3ÎØºukQQÑe—]†a˜ÑhÔÜ]ƒ¦él6»téÒh4º~ýzmçW_}µnݺݻwk!çóÏ?Ÿ1c†¶ãø¹çžË²ì£>:{öìíÛ·ã8n4׬YóÄO<ùä“3fÌÈf³}}}555Úm� ±±±¼¼üÐß[%“É;wŽ7®°°Ðl6Ï™3'üõ¯=÷ÜswïÞMMÓO<ñÄÿcïËãª*·÷ß3Ì“" TF%qK³Ò4Å9KE-gÅœKÓ2sžKs@3²«—2ÐT(‡'QQdRæéÌÓï'Öwÿк÷vŒ»×~ÎÙçÝÓëæ}öZëYÏúñÇwìØÑ¢E‹¨¨¨;wîìÛ·ôùvíÚlÛ¶mïÞ½íÛ·oÙ²%Þ3öíÛwðàA@àîîtæÌ™ƒâŒr¹\©T>u&7oÞÌ?~|ëÖ­š“&M öõõ={öòåË/\¸0gΜuëÖݺu‹û,½÷Þ{*•*22òÒ¥Kjµ:888%%eÙ²e666OÅ6Þþ$¸a6›«««¹àa2™°d‹D"¬òR©øaX²ávH$| €!7>‡ÙlV(xàëÀq …þþþ¶¶¶z½@2<½Ø¾ŽP(”Édä¾rH¥RòœŒF#® g, àœ:5°�Ó¢E ‘H ï¸ Ü2\7òÃx{~ö/\“ªªª¢¢"xÁµL«ÕΟ?ÿÒ¥K 8"±dÉ’¤¤¤Y³fµnÝzôèÑðH.\xëÖ­ó &“iÖ¬Y?Þ°aC“&M²²²0«¹¹¹‹/^±bEYYYUUÕ´iÓV¯^ͳ³³ûú믱o@@À¦M›ºté²k×®åË—¯^½þÓ† ^z饞={~ùå—Œ±ôôô£GN: ,//oçÎ+V¬@ ”Žéääß¶mÛ 6ÄÇÇoÚ´©sçÎŒ±/¿üò‡~(**Âßä±cÇΟ?ñâż¼¼¾}û2n_QQÑwß}—––öù矯]»öüùóO}‘ùì­·ÞjÖ¬Ù”)S¢££ÇŒãããSk@TTTçÎðuÇŽC‡ýðÃù¿ÞÓ°’bq„àË17¢%“Éôz=E,¸ž �Q‹Ø@Þ†P(¼{÷î½{÷¸ûÂ׉DXÙÅb1Î…ëÆÀ;�`#.ׯ Ùq#i„@³ÙŒe !8Oq¹>}ú|ýõ×z½ž‹‘f³Y,Ó}Qh‘fê r^yå•Áƒ3Æ6mÚTë'‰DÒ»wïÞ½{3ÆÜÜÜÞÔ888L˜0áÍ7ß1bÄÑ£GM&“Ý’%K¾ýö[™L–œœüïdÒ¤I·oߎW©T´±G=zôX¼xñ¹sç²³³>|¸ÿþ¼¼<äc¤Ré°aÃÞyç þöÛo-Z´mÛ¶îÝ»cË7ß|sòäɵk×Þ¸qC¯×3Æ`0üòË/Z­–1¶eË–Z©”¬¬¬I“&Mš4 a7ÆØºuëV­ZuøðálqwwŸ0acl×®]t/M›60aÂÙ³gÿùÏ~þùçáááááá=úâ‹/þ›yŽŒŒŒŒŒtpp˜4iÒ‘#G¾ÿþ{ÿ?üÓO?%''S€—·ó½G"‘ˆÅb,¸X¯éõ„X,¦T BU:ÅnÅÓ�9XÜiÑÌØ�0¬Vëõëב,!'ƒ›1¢a„¸«ÕªT*‘žààä¨áÖࢠ|‹Åݺu;wîœZ­¶Z­ p³p±XŒ‹Ä �‡ŒF£T*å!ç¹Ú_l^àáá!“Éœœœ§L™RQQÑð¦&777<<ü›o¾Ù¸q£T*U«ÕÆd2999yxx899eggûøø”——ߺuK§ÓqA…,##½·nÝÊÌÌT*•5ÊÏÏ¿sçŽR©tssÛ²eË¡C‡† Æûâ‹/rrrÒÒÒàHyzzæä䔕•)Š[·nݺu jß !!!Mš4ùõ×_Ïž=›°~ýzÆØèÑ£[µjõúë¯<Ü“Étÿþýôôô[·nÉåòÆgeei4‰D‚cVWWwìØqòäÉ·nÝ2™LÞÞÞNNNööö÷ïßøð¡³³³½½½J¥R«Õìã㓚šºcÇŽ»wïÚÚÚººº>yïôðð8}úôS§×ÇÇÇ`0ìܹ3**Ê××·uëÖ~ø¡F£1›ÍW¯^õððøî»ïT*•V«Ý²e 8~.\;vìØ±cÍfóÇù¿Þ÷½R,6”ºHˆD"¬àäå÷`4áë ŒGH �CiÊÉ À}Ч!CƒŽÑhįFÁ1NG_qµÜã�?� tF@x ð¢à0ÑÆÓ§OkµZÜ£GÀ;� iµZN‡Ð"Ý9aü3óüLäáác4333²‡éõúÊÊÊnݺyyy1Æ*++E"Q=ÊËË»té2qâÄ¢¢¢””F³hÑ¢æÍ›7¤I)((pqqqss ;yòäÅ‹###.\Ø©S'«ÕúóÏ?«Tªž={¦¤¤lذ!55555ÕÝÝ8åùùùþþþ]ºtÁg¹\Ž1iii£F 8yòäåË—ßzë­)S¦ˆD"‰D"‘Hª««%Ittôk¯½öÛo¿¥¦¦¶nÝzùòåååå2™ìêÕ«8HË–-›4i‚] ½½½{ôè¯V«µ¤¤¤[·n¾¾¾YYY;v·ÍÅÅ%,,ìÔ©S©©©¯½öKvvv©5Ö±cÇ·ÞzëôéÓ©©©¾¾¾6l ±··?qâDNNÎøñãßxã>}ú\¸p!55ÕÖÖö«¯¾ò÷÷÷ññIIIÉÈÈˆŽŽ&Fxaaadd$X¹jµZ­V¿òÊ+ÅÅÅ‘‘‘¾¾¾999ááámÚ´éÓ§OFF†——ך5kôzýÏ?ÿ\YY9oÞ¼¶mÛêõúâââ®]»Nž<ùâÅ‹-[¶”J¥7oÞœ4iRyyyYYYjjêãÇ;uêÄÿ×zIrwwçy´ZmyyyfffzzºÁ`‹ÅH¿#\lP(NNNæI¨€¯�ž«ÉÆtq#QˆkQX ·>#xÄ¢XùÄs£œ –~l„ó³` 2Š¡á2/É3ÃÑ€®ÖÞÞà$‹¥R©\.7 ¬†S ‚‚‚¹3™™™Ùºukþû¬¼¼¼¤¤ÄÇÇ™?ƒÁpïÞ½#GŽÂÃÃÏœ9£Ñh<اO~¦c—.]jÑ¢M~6êÑÖ­['‹'Nœ8qâÄ„„¾³ÆŸÛ¹sçÚ´iÃåY•””<xð`ÿþýñññ”’Q.ÝÁÁÁÎÎ.77 :…•$ \ ^)à0QDÁ.ʺÑH$Ä¥æz tŒÃ/�$0gŒEoD“°á² Øè°ä�B–(pçÉÁÁA­Vët:«Õ*—˽½½ïÞ½‹q´èèèèèhîL<xpĈüöÙƒ233###õz=d==:mÚ4^}€·׺uëÖ»wïdeemذŸ¿= ¹A-rM°E­V———“ÓCôb¤IˆÙŒ”‰ÅbÁ»?ÜZ©3À:/yB¬& ÀƒãBl4òHè²qFÄôà$ …B…B¡×뱑xÒDsÀò¨�“o¾ùæ;wîܹc4Ax±X,R©T§Óåääà)äèààÀ?3Ï1ÌËOÁŸ8†<c²~ÍÛÛûâÅ‹ôÒ]VVÆÏɟ؉²NGh�bvQ• "TŒ1 &¶1eÚ±¾b‘»ƒ8R/¨éhQfž‹Zä àøäNѾ0 ¸á´Z-•! ¼)¨wˆÈáø‡Æíà~Ém²Z­˜4@ !ÿ,ñS–••Å?|¼ýL©T*Š'£Áf³Y.—(E´1z¯¢Da«Iº0Nân ‘­‘DߌÊ0‘–“ ø—H¤5@Y" ¡°D"‘Püœ0ú•œ$\'“ÔÁm"$H(È¥B°š³Ù¬Ñhøg‰‡œº¶+W®ØÚÚ6<IÞ¶]¾|¹M›6µh¾¦Áƒ5mÚX¬V½ÕÊVó¯ æ•_( ¾Æl6 j’.¿W¨ÔP™…Åjpån¡@�?B ZÌf†¨]ÍÙuŒ ³À½ œJ òü>L ÔP¥ 7¡QF(Õ$™,V«H(üýE“Âa$®#0«Õbµâ- |(k âáÈÜá«•1«Å"‰ ÞÞŒ'­ñS÷!ÆóóÀÛßΞ,+¥¦JŽAÙ#£R«U "†8•Édp’ðD$«E+€‹ ‹-f³P$‚Ka6›EÜøjµº²²’BpaɤRÊâÐ%QhËb±(8ÔmfµŠÄb€¢•1£Ñhkg§Ñh¨¸ò<ð«HÕþŠ@ � rk¸Š(Ò­q™’W^aaaüƒÄCNš³³óSc¼ñöˆõOnfg›ûM*•ÚÙÙFÔ£P]޼†P ª¡„E a@JÂ3nâÄhˆD¡ò3@!‘ p‡�—Èb)KO·Z­­V©T”5Š�Ê4‰H$‘HÔjµJ¥‹ÅÙÙÙf³Ùj± ‚•jT…fsã¦Msss­V«ÀbX,™ çq wþÏ ª!ÔAÄSÀœ-QÜ…­B¡D$BxPèëËC9¼ñÆÛ¿°?yCÂk~ee%ñ»P›‚L U± ëŽñ”¤!â2ñ›áF3DŸcp\h¤\.§´<ò+•J¥@½^/“É€"82¥m�6\f¶D"Q(¤yƒr4©TªÑhˆz@9Œqpp¨¬¬¤âPƒÁ€ûBŠqÈ Ä¸ã_4ërâãã¡¢Ö­[··ÞzK§ÓÍ›7¯{÷îйaŒ?~<11qÁ‚ŽŽŽ~¨’’’%K–ôîÝ›„[^|KKK£Ö5Œ±~ýú]½zõþýûŒ±þýûCc¶fÍÆØôéÓñ5;;{ݺuC‡ ›5k6J¥RhÃìÞ½ûæÍ›Ô~†7Þž·Q &ÅÐð‚Oõö„+ ŸÁ â"ÈÍ\±NVC`Ã"N23€®HŽÏmXÀí&'†Û7 ¢¤îìééyåÊ•Æß½{—ämà–c›ÐˆþÊâ¯Ü<B>¢íÌ)Ž`žã£ø'¿%$$,X°àå—_ 9sfrr²Á`ˆ‹‹#Þ*c,$$dĈ$!̵êê길¸ŒŒŒ¿ÑìdeeÅÅÅ…††Ž1bĈ'Nœ@—F?þæÍ›„7+W®<pà�¾šÍæAƒÅÅÅݹsÇl6ÇÅÅUVVŽ1bèСW¯^íÞ½ûÂ… ãããù‡·:ó~¬V+za è‚U"‘oŠ¿B7’½»Ã•*@º…ZÑ€ñ T€Þ3—G8DÉdÒLÒB~/ 1›ÍšÍhÒ°²Qãˆúl±X4 ^õÜÝݽ¼¼ r?ƒA­V ¥Rùúë¯sKííímmm‘Ô!pÂ]Ã%?Z$üKO‘·ç 9©©©cÆŒùüóÏûöí;räÈÉ“'0�BÈ………Ó§O÷÷÷¿wï^|||÷îÝóóó·lÙxÿþýG½þúë‘‘‘/½ôÒÌ™3«ªª>øàÆØ×_}ùòå¿×ùûû‡……………-Z´(77Ýhèéܽ{·££c‹-h|=Hµ{÷îÁÁÁ“&M-[¶lݺurròßÈÏã­rõjµúÞ½{EEE‹¥°°ÛËËËY’ …•àÐØØØÀõ¡`UðÀ³ dJ4 4ÙpR¤pôz=†Ás²Z­Â•ªÕU"©ˆ1¦_§—m‘›Šr¨“zP+ãææÔ¯_?//////‰Dâíí Ý#½^äÈ ®Y­VCã‡ø:\ ‡é@QG|Fþ™©/§ÖSKŸ¯]»öÞ{ïÙØØPȨ¼¼|Μ9ï¾ûnJJŠÕj?~\\ܹsç~øá‡]»v™L¦üü|4M7nÜK/½ô÷𣤤¤;wž:u _ׯ_ŸðÕW_–––qµéΜ9ƒv�°¾}û†‡‡ïÚµk̘1OªqóÆ[y9à  O‚[‘c2™¨lË1¹;” ‰jÒìmc5]Ô¸ZÔjµ5¡X⑃r¹\–$«îYmò3 K…‚"PtÒ¾íÍd2ç¦T*•J¥¿¿³fÍ"##q^77·‚‚‚³gÏRª Ðh0H�—Mº×µ´M¹mLÉ¥£ˆ"oÏÃþ } {÷îmÚ´yrû‘#G=zTYYÉÝ‚<Gvvöß–…BꢱnݺݻwoÞ¼ª«V­êÝ»7éKž9s&55566î cŒPùƒ>X½zõŒ3øgŽ·º‡*Š$4RÞ¤þ7DÞ�œ@( Ü ’ù$¡FL6â(Ó kz-j¡P([+3¦­;­’Gé#)ýtá ©‚D"‘Ëå...-Z´hÙ²e»víš4i2pà@'''„R²²²***Ë¡ Èîp‘ƒ”LY ïŽ ¥tãØ—¯Æ«7ÈáLqßþ¯ìÿ·°°°Ñ£G5ÊÞÞþÿø æîK¯£9zíµ×�06lX±bÅÑ£Gƒ‚‚ðS||üo¿ýÆËÌÌdŒ¡åÌÁƒQÀ¼lÙ²-[¶„„„lܸ‘Ôx«Çw&@·I3½þ3ÆœœœcUUUZ­)¬àmQ7OÒ߬å÷p¢Ú—ÿã:×dæ…B!Ôh¬V«ä ‰±›Q±R „Ò00 cÀvC'SFƒž÷‹%00°  àÚµk999:îñãǤ²O Wb4mmmÑ­�÷¨ÑhÐ G¯×HŸ”t~çRóýrêr:tè°mÛ¶™3gÊd²òòòM›6ýóŸÿôõõeŒíÝ»W¥R™Ífj¥%‹ýüü±}çw¢££ýüüÒÓÓ¯]»¶uëÖ;wzzzúúúæååM˜0aÕªU666»ÉÊÏÏW«ÕUUU`ñµjÕêÁƒø)**Š1–’’‚¯/^ìÑ£ÇìÙ³Oœ8qõêÕK—.•””ðoõåå�EÐG€„j€%%%Ä[£KÊ\ ýJE—ˆ†œXMv“º|�H[¹¢ß»ºå‹M +þ=s¼! ŽIÆ™Íæüü|¡PX\\ܾ}ûE‹!ã"—ËÑÚÁ‰�0�Mr©ør€^\Ö+…BÛÑétð±xA½y9ýû÷×ëõgΜaŒ­X±"**J§ÓÅÄÄDEE•––¾ýöÛ‹/FûdGGÇo¾ùfûöí{öì:tè‚ ð¿›””„`Txx8clÇŽ»wïþðÃÿ.xãëëÓ¤I|íØ±£Ñhüç?ÿ‰¯S¦L¡éׯwÇFÅÄÄøûû4hΜ9{öìñññ¡\NTT”»»;ÿðñVg^ ‡ d�%o¨œ!úð$%š$Ô¨2F§ÓQciJí0NO4�ÚýÎT.6+Î)¨“À€+M’F£±¸¸ØÙÙ¹¢¢"--­¢¢ô³G‘ )ù^``sYsŒÓ¾ó�WbhñCöˆ`ê rcC‡:t(}•Ëå+W®|êÈ€€€Z?ÅÄÄÔÓºuë¿W§#Õèkß¾}ûöíûÔ‘S§Nå~õöö¦ÙxrƆÎ?y¼Õ¥—ƒu™"]¤¢Foýô‚OÌn‚‡ÚW´p4VÃõ"Œ!…q yÕ Ê‰ ĽB8ðŠˆ,G×̽~­V[\\ìêêzóæM"àUWWªQ®¹+DÒp;€:êÇjêo¸Í~ø:кxúov¾xñb\\ÜÒ¥Ky92Þx{a >y*à"‘f¬¹ 8ÃûÂí�C%Z¡Pà+õøàÊTsý!| ž¡Ó§ëNª ­‹åõþþFÊúʼ%œš:÷0Æ ²²²òóó‹ŠŠÊÊÊt: Z€[Ø®“SÀ-zýwJ y{Ž^Ο[xxøß«´ó?²ââb¾ :o#ÓjµOÿ#¯Q ÅêoF­Ì¨¿'%`€J¥’ÛšJý¹ÝÈ· ÉŠVáŒF£L&óð° ,0ÐtíšÄÃÃ*•šŒF< ®»C}H)¾‡_QWÄmC@µœ¸6¡P(“É4 ·•ŽL&#ŠÛŽÕ1^jµZþ¯þÅ…œ†m|`—·¿‘999)•Ê'õZ¨ºk´Á`Éd”e!ÕK 4‘â€H$R*•Pn¦°Õ¸�`à" EE°"…œ$ÆØ”)ò ôQ“$–Àÿ;#5™Ì€J�L*•’¦�ÁQ·§‰A,‰¢ ‰[ŽƒS`;¥vèš1Kü³ÄCN]ÛÅ‹ÿŽœºÿÈìììþ^©5ÞþòÎ5JÉPn ‘ĸî·!4y3 JÃ_¡Î›”¡!²57çÏ8mÈ 1›ÍŒ ¬Vë®]ÂAkªíLV«ŸL…T Gâlð`Ôj5·Zƒr(JÆjŠX©0×Vëõ€„‘à[Æ?B<äÔƒµhÑ¢a“ÊðùäòÄ[Ã3Êÿ* fåhøc½&y¡Pèîîž——§Õjår¹F£&ÐÌjôÓ • ãŠå` Õ¸A9,,¬];ë÷ß_9QúÞšj!6 ´>A'³r *5€L(èàÈtFºAn_Qê©CÊm«CŸ‰#ÑkÊlñÆCNš½½}æ¯$%% :´ªªŠÿ¿nð†0b\z½˺T*¥ôT^H¬èòøñcÐFµeËP¨k¡y $0Cå8\Qò®]»vé’N,–žÓ™ÛÊØ?d2,ýPç$ÕB> ŠB¡ ²€D"¤aG\�  …†-Ôò‡H @&B/8‚¯q)|¼=ã½HÞxkàFeùXaE"*7±^ã3U·Pt øQQQ±eË¢®‘ï‚5™[[[ªÁ¤ Vv¢ÀQìëôiIA32_cl-cy&°…Á\‰)Tóà›\.'7‹8ƒÔ ™L& Ñ ‡hÔ,‡º0Œ)m$6ÞÅ©/Çd2Mœ8±{÷îƒfŒeff®Zµj̘1íÚµ£1jµ:66öõ×_¯UÉÛSmÇŽ©©©Œ±=zDGGkµÚiÓ¦á§%K–¸ºº&%%íß¿Ÿ1<yòdÆØ¬Y³***c“'Oæç·ÿ&¶F¼aZyk5€[‹ƒHÀ¯Lp‚B¡°´´!*Ã$×\"* Ù¿_dµZMýLi»e—…V6Ü HSw…pñ¨<•¤à¿áP< l P„®–bk¬F‚7B-vpýT¼Õµ—c6›8páÂüÇäääüøãùùùZ­V­V«ÕjtªØ»woFF†^¯‡¤˜ÑhT«Õˆc¶ó–°råÊvïÞ}Ö¬Y?ÿüó°aÃîß¿ÿᇖ””DGGŸ;wnòäÉmÛ¶=zô²e˾þúëùóçŸ8qâÃ?´³³2dHii)?¼ýÅ?òg�äý‰CŒŸ(‹C»p»y²nÅ èÈÄG �ø¿·*ฬ¦úR(Úöµ•\’ˆ.‰dëeÔŒ‡�ª À ’Ï!aib.€e}D"‘L&Óétä�Ñ©yÙ”àÖ5ÅUå­N!G&“íß¿ûöí &::zܸq­ZµêСÃàÁƒ#""V­ZI"ÆØ˜1c ,½fÍ//¯œœœuëÖuîÜyðàÁíÚµ»uë?Ë ¸qㆳ³sYY™R©”Ëå999 …ÂßßßÎÎîáǦ¤¤ÄÃÃÃ××W­V£ƒêÙ³g 5ƒƒÿòÅÛ_6r;œœœñ"ˆÎTjƒ8-úX!e†ŸÄb1Ú°O,åPc#þãè¡ÅHx( ²dYŒ&#³2áC!5>`E�8[„7Ä Ã)ˆÍí9 (Â%ѺhÑ ÈB!¼+BSþ™©kÈyª]½zuРA‡9rä_|ñøñã§+--ýôÓO‡~èÐ!£Ñ¸dÉ~–a§OŸ>þ¼J¥jҤɠAƒrss7nÜx÷îÝ?®SwïÞmÛ¶­L&ã'·¿fAAAöööŒ1¥Riccƒd;¹>Ôᆖ]üDÎH$R©TµzšB 9 52 õ6Ê—Pãwwwb<‹D¢ÖBaH–(-ô$?CLâ#Ó’1¬&ME¥£ÔÏ’RH\qå®É€[$^P‹¥Í[]CŽŸŸß!Cð¹E‹ƒ 4hV«3f éZþ‰ýôÓOcÆŒ©Õ;çܦL™sæÌ™ôôôéÓ§Ï›7¯I“&r¹üÆÛÙÙ}úé§QQQ»wï†,.o¼ý ääææ>~ü˜r”·'N¸#\á2ø%UUU仜ÀÏ h-Ö€%Ô„›€sÁ1�� �IDATýÿ=߬VkÆ"jÎNÌ4®k‚Ï„ \Ý6J8ÁµBgZ­çÀç¦ÒQVS1ŠÀ<!Œ´··‘÷Ã?3õ�9...íÚµûôÓO###}||BCCçÏŸ¿gÏž¹sç>µ2õïƒuíÚuîܹG]¼x1?˃¡²²’û(ëõú×_}À€^^^OÝE£Ñð0ÃÛ3±¤¤¤Gq5Ç(˜†ð8–i¢–Qx ‹²^¯ÏÍÍ…kZß±îÛDúlð°è£E0ÌÏÏøñÇ:…‚)R¡Pˆh3é=?Ù^Ë××þ*Š(úöNaoo^8”’J¥r¹ÈDCñ4‘Häìì¬T*«««jµZ¼Õu`môèÑ=Ú»w/cÌÙÙY(æååÙÛÛ»¹¹]¾|™Üv¡PÿÃ?0ƤRiPPPeee^^ÞàÁƒ©WÛÿ²=z´}ûößÿýÕ«W½¼¼ÜÜܦOŸþú믟<y²¨¨è¥—^rrrR©Tׯ_?{ö¬³³³Ïš5kÚµkwòäÉìììàà` OóÆÛjz½žÔÏcèMIªwqE±¾“ì&AW© ¼!®< nÿM Ž/  ¡››õ³ÏÔ­Zé l¦Ñh@: T?WUúÎ;@ Ê�œ8#1ÓlllH¨ 0FK‚Ö¸*43™Lååå`%`#ò:¼—ó\í_”‚öìÙ³iÓ¦ø<cÆ ‰D’œœÜ¥K—Ï>ûìÆS§Níܹó+¯¼‚îk×®MIIiÚ´)ç$''7.66–Ÿå>}úÆôôtÆØÊ•+»víÚ¡C‡¥K—&''‡‡‡O:ÕÉÉiýúõ'Nœ¸|ùòâÅ‹‡ Æ“ËåÉÉÉîîî3fÌpppà§‘·¿l7ã¶ì$1M*ÄáÆ—(¶FàáêêZ^^NË:ůÈËAå?¥aè8¬&c‡16dÈï²"‘¤ØˆxM {"âÒ»ál‘GÅE¼¼<nã8pÄt j8ùgô+qÕ(^Ç?0õ9ýû÷ç~2eÊS‡®¼üòËŒ±–-[~òÉ'üäÖšIîdÊd²ZSÉÝ2cÆ ~Þxûï­M›6ÎÎÎ¥¥¥�ä©°â�eP°”S¦‡º…êõz @±šŒ «)!`#¹OÂê_Àj²)Œ±7Þ0mß.‰Ø{ïÏŸQƒQrkHîx¬Â¹d2XÔxÄä#€$s,Ë„ 6mÚ„ËÆY½¸•I(k¥*þ™©ŸÀo¼ñÖ�ìÆåååµ< ‹Q6^.—#\AÚÏMš4qqq!Ÿí8k1Ç ³F½j¸*mÔ"!;Ôx$úô±¿rE|ó¦rÏ?ÆQZ#€¡nrb±XRc`uSÅùF $$„ö¹ðëÞ½{¹ n5œ<ê¼�ÿ‰¼7ÞêÇËù_¶‚‚‚üð‘`;o Þ &ÆíˆS«™&zÈqr=¡ÂÂB~E¼ î$8ámCÁ4¬ãÔÄš®FNAP,7nìž‘Q 3NŠ>÷. 4 �°Á•Áß&(‰®_¿NX…d¾–––ÂÅÁeWUUÁ'ÒP‹rûx5rêÍ***p¿œ–-[òÿÅÿ#†•îH­´  ϹV«%×/GGG4*\FpÕãâ¾µ¢%BŽƒGB¾…×08'ç¡Z-£ÜµáÁ`jzMM?Ik€´¢‰)Ç%Xs»'Еr(%±(mCš7„µü3ÃCN]Û¹sçÐj·ÛéÓ§ë _Ε+WÊÊÊüãééÙ¢E‹óÚàX��àFPR�“X>4zØTWWSt ¨ãèèî>ˆg £"Jø ´ Á é~’Ãdµ¨¥•æ’O§„௑®¡5‹CEɘr+IYMšŠ4rL&®Èwå!§,44´a÷ËAkÈ:ˆ>~üøÕW_mØ)Y¬Ñ/,Ó‰Ä`dCóM P4€Û[ƒ¹¢è†@™\.·³³«®®&·‰ªý ¸]¢‰FÍär¹XÌ”J¥^¯JA?ÍÆÆF«Õ‚-Mí|X4…ïˆçÆj*F öHjš¼+VCZ£ÿ&ÜZ­–n�!~õ{®ÆÓžnJ¥’qäž=z´ÎÚž*•Ê<“‹åĉ¢"Qï†L U;R#2Ràܨ½ )PNÞd2iµZ,èF£qÀ€ìÿï€ÀÕ5 ò<ƒ‘Ëå2™ÌÛÛÛÍÍÍÖÖÎÙÙÙÓÓÓÁÁU™£Frrr"ï„e”Ž¢ðZhh(·<¯5”X"¬¢.×€:x{r¹œ$ pý\Š¿�ò^o/–eee¡ò÷ƒ>°µµå'ä…~¯¬©Äq¹y*¹‡[@íˆe@©šfÒÌjµÆÅÅQj„pÅl6«TªÜÜ\DºH,�çµµµusskÕªUÇŽ[·¾X]]þøq“¼¼¼ÂÂBÀÉÇwìØV¿/Ub1HeT”žžŽø7솽p:À œ�­�Gæõ 9™™™‹-¢¯o¼ñFyyù•+W¶nÝÊ[¿~ýõë×·lÙòÓO?A›€1Ö¿¼ø4lËÉÉ™3gÎÈ‘#{ôèÁûå—_0'¾¾¾Ÿ~ú)wä–-[Nž<Éëի׈#c7oÞüì³Ï&MšÔ©S'îÈŒŒŒ/¾ø‚1æààðå—_2ÆV¯^}éÒ%ÆXttôÛo¿Íüþûï“ÎÖ­[¯^½ºqãFƘ§§çòåËc‹/¾}û6cŒ.òÙZeeåæÍ›»uë¶jÕªÛ·oãöŸ‰íرãĉñññø:oÞ¼ììlÜr×®]i˜^¯=z4¹P[·n=tèО={={6÷˜µf²¤¤„Ê˶lÙÂÅ˳gÏÖñLÖ¥£ƒ7}*pƒä<u»!ç€ÔjÑ©±Ž£/'·µÉH‹D"NÇeŽx­T*ƒ‚‚ÜÜÜÂÂÂüüüœœª3yz¾uêÔ©óçÏWTTÈd2±X\\\,‘H(bFµŸÀ3jíðÐét”È¡–ØHD±fÝ]6PׯMó äÈÇÖêrÊÊÊ¿øâ‹>}úàõ$66öرcƒá«¯¾Ú¼yówß}g0®^½zæÌ™ýû÷7jÔÈÎήÁÏ×”)S.\¸pëÖ­¨¨(ÆØÝ»wgÏž=zôè>}ú´iÓF,/\¸5wGŽY¼xñwß}W]]ýþûï;::&$$\¿~ýîÝ»T !5‰Dòþûï÷êÕk̘1={ö?~|hhèŠ+’’’®_¿>uêTZpËËËOœ8ñÊ+¯,\¸1VRR2}úô!C† 4¨cÇŽB¡ÐËËkß¾}LLL;vìBCCŸí$ÆÂ—_~¹cÇŽÏŠl}÷îݱcÇæææcË‚ âââ.]ºôÝwß½÷Þ{?ÿü³J¥*++³··/..>vìØûï¿?~üx@pîܹ‰'~òÉ';vŒŠŠ’ËåS§N-..‹Å{öì©5“sçÎõððX·nݬY³ÆŒóý÷ßãtÙÙÙÇ3fÌÈ‘#1“ŽŽŽ›6mJMM}~3Y7†eT.—ã}ŸÞâ©Õ:Á€CÈóðîo4§L±¼óŽÞ`0&صKöÍ72d_¨ 49ÅÅ\\,Z­X¯( '''77·öíÛwêÔÉÃÃÃÞÞ¾Q£F5;ƒ‹‹Ë«¯¾êäätùòe•JUTTtþüùòòr�¡F£!Q8ÏÌf³@&°H-Öj+ÒB„¸5¹\^õ}•Í ¡PXýeµtŽTZ)žtû £69ô`óxSÏ5GGGî³»aÆøøø¸¸¸°°°äää5kÖ̘1ò´Ü‘/ <yR«Õ6oÞ¼ªªª²²B ÿ©­_¿þÆ]ºtÁW???ôúÃÍÓÓ“1Ö¯_?™L6xð`Fãææ&—ËÑ­nçÎgΜéÝ»7mëÖ­Ÿ|òÉ•+W~ûí7ÆØ•+W¬V«OUU•N§sww/((¨ªªâê¥ÆÄĈD¢þýûgdd´k×ÎÙÙùܹsŒ± .H¥Ò¦M›Nœ8qÒ¤IÕÕÕ¹¹¹σwçââ2|øð©S§8°[·nÏä˜~~~)))±±±qqqØâåå%—Ë322 ðùòå˽zõÚ¼yóêÕ«ýüü"""222"##¡šêäääîî®×ë¡_^k&‹ŠŠ|}}=<<¾ýöÛZërYY™ƒƒƒ‡‡‡ÙlFí¤Á`hÒ¤‰££cEEU¨ük •QÚ†›ð@'D¢ŒF#”ÊÉÇ`plmM‹Ë’’$5ÛM¨%þ˜L&kÖLïãcpw·Ìš¥ýè#Ǥ$¡B¡hÔ¨Q»víÂÂÂT*U£F%Õét‰E(— ‚   ‹ÅR\\ìâârûömFƒ0 ¹/µ¨X³ô·°sÌl0KR$È1._ G`3›+Í‚jÀ,0 \µ7Ò¥Ê!ò„ÐÞG…ú„œÃ‡?xð iÓ¦PýÒh4Ÿ}öÙÔ©S;vìÈkÖ¬‚gΜILL\»vmDDÄ‹yŸ?þøã¼yó"##›5k–‘‘ú× ç©vôèÑiÓ¦-Z´häÈ‘Œ±Q£F¡ªî_îØ¡C‡Ù³gC?íìÙ³Ó¦M6lØœ9sΜ9ãçç·iÓ¦‚‚‚Z» 4¨]»viii¿üò‹¯¯ïš5kd2YrròôéÓccc'L˜€aŸ}öÙo¿ý¶qãFÿg>™æòåË~~~}ôQttt­@Ö³2ooo¹\ž–––““ããã#—Ë===gÏž<f̘’’’´´´¼úꫯ¾úê“»?ÞÍÍíþýûO /[¶ >+A²³³ó[o½•œœ\]]Ýðêd©;�\Ôè¦'õu‹Å …B"‘ F‡2ÀjeƒYBCu‹åìYÙo¿IÆc&TK¥æÈH}ÇŽ&ÆØ"M` Q,Ö¹ºJ<<.{z>vq¹€Ù¶Z­¶¶Â«Â+ûôÚ"ñ-@ààâPÕ¾ª¤¤Äh4>rTVZ† —¦Á8½JÍ/™M3L­€­cŒ1ö¦ÈVÐ0ù¹~¢ž1&ûJf-·r5~‡ã@ݨ 5—¥Í[ý@Ž··wëÖ­)nß«W¯Ž;6kÖlΜ9Œ±¢¢¢ 6œ:uê……œ~øañâÅݺuÛ±cGTTÔ»ï¾û¬Žœœœ<sæÌÉ“'o�9Œ±mÛ¶ýË};vìðNOOŸ:ujŸ>} «Ö¥K—-[¶" ÁµÁƒãƒN§[·nÝ_|qéÒ¥3fŒ9òý÷ßÇO .<räÈîÝ»CBBžÇdªÕêK—.íÝ»·gÏž“&MúË“““3kÖ,|ޝ%Ÿ””TTT4gΜmÛ¶Íœ9sÞ¼yxÞ‚‚‚(·k×®§BÐ)™Zæààкuë¥K—>xð૯¾ÂF''§/¾øâêÕ«Œ#Ö0ŒzÒ°šZ %!6… ¼Šââbt˜FÚƒÕHa …¬,kF†$44äÕWÛ\¾ü#°°›7¥B¡¹uk!cUŒ±ÊJÑ;ör¹ÜÁÁÁή¹B(“yˆÅŽf³1kQQqQQ‘mÀˆæåîuiiiKû–ù•ù­ä­®Þ¾*½&µ©²Ñj´ÌȘ•1+ Å¿çf„™@f4ÞÆ33v™ ‰FÂjJ8F£H"²ºZ…¥Bfÿ;á»Ö(µâŠßàö)ØÈ[ý@NHHH¯^½þo´X<yòd‘H4jÔ¨={ö¨Õꘘ˜ 6 õ n:urss^^^ÏªÉæÍ›7G;vìXÚHÙˆiÕÕÕUUUR©´_¿~ƒ š5k.¬ºººI“&­[·æÖrÚÙÙM›6íÁƒÇ§ İaÃ>øàƒ‰'"ãúùçŸõÕWW¯^mÒ¤ÉóžÒ—^zé¿™É&Mš¬]»–^ÃÿåxƒÁPRRâèèíìì¼{÷î?\XXøGÅ@7îÕ«×Ö­[Ïž=Ë«ªªª®®vuueŒEFFÚØØNeÃ0Š8‘,4âTÔ€9\ýM(câ§š²Óõëò#GD))Y EÉdB´¢¢Âb±9"°ZgÎÈíìÞÞlãÆ277éÏ?»xzzšLþ&“N×¢eË–ÕÕÕéééjµ£³³oóæ{èËîçÜwwwodjt§âNIIÉõ#×ÍgÍVµU ˆL"b.H„г±—˜ùžY 4ê’R‰ÉdIEGøííaeJÆ2³YrU"b"P' ž@ò À]Ò;`5]ÝxÈ©OÈyÒ¤Ré´iÓ„BáàÁƒgÍšåààpöìÙ’’77·çÃy†öÛo¿EEEY­ÖÜÜÜŠŠ 4xþ/i2™*++>| hÚ´ipppÿþýe2ÙÌ™3½¼¼NŸ>­ÑhT*Ò<µlûöíŸ|òIJJJYYÙ£G’““cnnn>œ;wîÂ… ³²²üýýÝÜÜ BBB>þøc??¿sçÎ%%%eeeµoßb‹¹¹¹'Nœ`ŒyxxTUUÆ . :ß©S'GGÇg>™EEEwîÜ©¬¬äæ™þã‡O,nܸñýlgg‡Ìhh¨]ZZr9-[¶Ä$tîÜÙÅÅ¥eË–iiiF£ÑÕÕZ>¯¼òJ@@À!C5j”œœL3Ù¹sçüüü¤¤¤ââbääV­ZµnݺÔÔÔ÷ß?((èÍ7ßT(¡¡¡¶¶¶NNNGMOO zÓX—Q5.q�‘ÈÙ0a‹/UÀ`'êp›6¡P®Ñ”Þ¿/-+¯ZµŠÊHc‰D£ ⊠ño¸) GG;™L¦Õj‹ŠŠôz}³fÍŠ‹‹322„BaãÆËÊÊäryÓ¦Me2Ynnî•+WÒÓÓ/^¼¡)Dÿˆ `6›%W$‚‹“Å$ŠD’ßµ (\f±XÔÕ6/ÛÍ>øŒØÙä\^^NwÆEáÀŽC”9>°ö\Mäáác4333¹º[ÀÑÑ1""ÂÍÍÜ€€€: !“ÉœŸŸ_YY9pàÀèèèù¯î£>²X,‘‘‘{÷î½qã†M@@ÀS¸¸¸üÑû»@ °³³‹ˆˆhÒ¤‰@ °···µµ-,,,,,´±±iÞ¼¹P( {ûí·›5k–““c±XFŽ‰Ô‘@ prrêÒ¥ fU(z{{wéÒÅÁÁ¡Q£F8ˆP(D·Ðììl±X<nܸvíÚ!ª1dȳٜŸŸß¸qã9s渹¹ÙØØ8::b_™LÖ²eK??¿’’l |*“0333$$䯥ÄkÿøÇ? @dŠ§Ú½{÷Z¶lùoŠˆ‚-Zà€mÛ¶urrºÿ¾ÝÔ©Sýýýé™<xpEEEaa¡J¥úøã½½½CCC ÊËË 0hÐ ÌmûöퟜÉîÝ»—••¶hÑâã?ÆãëëûÚk¯uîÜ“öÚk¯7®uëÖÈ)•ÊI“&Q4ï©÷ð*òiµÚòòòÛ·o_½z•ÛeÀd2)•J,µ$ìOýHò™[Ë"Šš41»ºš<=EÅÅ‚üüßûCs×n„°@‰vppprrjÔ¨þŽÀ¨FK4Drss«««KKKËÊÊNœ8qôèÑÌÌÌ¢¢" W2€ôij‰aµ¹7pµc‹@œ!‹Å“Ep]`Ô¹Lº`ª(bUi¡PغuëV­Z¹»»“—œ™™YÒP ÌÊËËKJJ|||€åƒáÞ½{GŽ„‡‡Ÿ9sF£Ñ<x|è†j§N²µµ »råJee%·Î£–]ºt©E‹ööö ØÅ>tèÐСC«ªªþÚîÅÅÅiiiŒ±®]»þylíèÑ£o½õÖã ½øa«£G¾ýöÛZ­öE»¶’’’üôÓOqqq´€B…BÔÐPã¯p'§†´ÄÀ¥&yMS$yzz6nÜX©Tzxx˜L&ww÷ÐÐPGGÇ´´4FãèèB|eeennn~~~YY™ÅbªJGÍf3¹YÀ œìmêáÆíu 7Bšip÷[cŒét:Ò) ç÷ˆjÓ¡C‡FGG·iÓ†%<ˆº:Þþ}{ðàAfffdd¤^¯·³³«ªªÍêH}€ ý-2O/¸¹ººþ­K#ÿ§ŒÔ3‰ÖL(Ħ¼Rèä•"’žžŽ5šú À”J%°VÌ1©TІÖ:ÎÖÖáSà‡J¥¢ÆÕð)A@G….F­V#äegg‡¶Ù¬Fë÷‚:SBVÓ€$¢átRGøv¤ð?SBéáí9/xó‡–““Ó€¾º¬21™Lh¨^Î ~…ôlcZ¯¡þB¡¤‰}­Vëµkמü•:îà ‘Ü$ A¡P Î_.—ß¹sG(úùù¡üÅÙÙY¡P<~ü8??¿´´4??¿¼¼™HrY, uÀ¿òq6<Õ¤Ùî„¢§ç4¼(°ÅRêa*—Ëù\9õ¶(7à~9ω?ýG‹r¬1Æ^|Uz…'E2n}(°+5–`¬¿ÔìY«Õ*•JÔÊo²R$¡ÐûRqÅbyôè‘ø�!„ìlll@-((°··øð!^Mª««‰)@¾Wi:aSÆa=Pð¹Y,D€¹#áî�q¹­zøÕ‡œ:5…Bñ¶?yV¦Ñhêà,mÛ¶ þå­Q«M«Õ < Uf®–%hÒö§bIV£½ÆjÔ3©…3ñlll¨?´H$ª®®ÖjµB¡P¡P4nÜ8//}EU*•R©tqqÑjµ¾¾¾Ô§¼¼œR88Ĩ-ùgð{ð™Ši hM~÷¡%ARl™$æÆj¨}üÈCN][VVÖÇXqÆ“æääÔ¹sçç}–ôôô0¯þÌM¥Rý ¥­ÞñË7Ò@©TŠ$<ªUjiápÛç`õçöXÃ8HŸ`ÝǾ2™ G6 ÕÕÕTãèèh0rssår¹““bYF£ÑÞÞÞËË |6ŠïÁ›¡¾>Z­É!ª¡áð@g�- ¡3ÜõÎA¯×“̵r al|à lóÆCN™ÙlŽŠŠjØ-Úòóó½¼¼þ2cíß7£ÑÝÀêùkŬ?~ܨQ£Y)hÝeâƒá½^©T"ƒàeÊ[Ÿ˜je('O P( v©¬¬„–`¬¢¢"??_*•:88( ‘H¤×ë]\\Èíppp°Z­nnn„ðQ¨e±"qyă ÎÖ4’1æé陓“÷f5Ün Ò\ ¶r·üÈCNýÄðûΩS§†Z7ç²X, ØÑ±Z­gΜ©Õ`â…2¬Ë”¹‹Å”’!ï„ÖwTJ®`q§$À‰aÈd2(ÚÙÙÁ;)..FæcòòòL&“‹‹‹³³³^¯¯®®.++ƒ³EZ�ò"©M€9Uƒ×V í(¾G­?)ŠÈ•VÜr[½QObTc_~õã!‡7Þxûë5*£¡º/ƒ±F%;­¢ºKZâiÇ^¼(—if6›A¨ªª¢þÓ&“ "î¶¶¶...ååå2™L©T‚n€Áp;¸´:)×AÄL&“Á•?—z$"lˆÅéõz­V P$’4A‰­á.øÀÚó}ú£.^¼¨R©ÚµkÕ©S§™3gŽ=ú?¥9FEEQÇ­?±E‹©Tª:ËÁvèÐa̘1bR©T›6mzN¯ÀP©T?þø#”oZ·nÕ»wïË—/GEEEEE½üòË*•jÅŠ´×7ß|ƒŸ:tè R©RRR.\¸AþëׯÿòË/¡R©ža“´ÿÔ?~¬R©Ö¯_¯GU©ThL÷ ­¨¨¨{÷îQQQm۶ݲe‹^¯ÿñÇ1“mÚ´Þöĉ}}}1-§Nâ^a‡0rÏž=Q5æëë;qâÄÒÒÒ¬¬¬   jÝÖÐþÈ9ÄzÓG­>y�ܲ*jqF½s� ø;%v27ZUYYYVVVQQ¡Õj5^¯Ç^F§ÓUUU•””äææ–––”–––––ªÕjP¥¡$MÒ¹¡ . 9¨¥§� º0’’ÓëõV«)%VÃù¦f¦TåCøºœzórÌfsEEŲeËL]^ìí틊ŠN:Õ¡C77·C‡µlÙ2((H¯×>|¸U«V‰‰‰è9ѹsg{{ûÉ“'#­zèÐ!<‘‘‘nnn999.\`ŒÙÙÙõèÑC§ÓUTTÔÙûExxø7nݺժU«'NØØØ¨Tªçq¢cÇŽíØ±ÅnÉÉɉdþüùPdaŒ¥¤¤0ÆæÏŸß¼ysÚëÝwß}÷Ýwu:ÝçŸ~âÄ —¸¸¸‰'Nœ8qÀ€Ç¿rå ÕlÛ¶mýúõÞÞÞõõ�Éd²ÀÀÀ´´´GÙÛÛŸ:uÊËËËÅÅåÙžåàÁƒ-Z´Ø¼yóæÍ›ç̙ӹsçC‡a&ÃÃÃ?øàƒ+VdffvïÞýIïéÓ§WVV¦¦¦.]ºt„ ™™™˜ö3gÎŒ=:88899A˜€þ�� �IDATªÕuC᫗Жcº¨ 3`ÆÎήqãÆUUUÛ©m(«asQ%—¸ ø·-ˆ¤UUUÙÙÙ™k ¿VVV ôâÌÍ͵³³ÓjµR©YµZ]]]­×ë¹­zXÖ5I ` 9!â8 •|½^àÌ_€„±©´NÖþH –·çëå<Õt:ÝæÍ›ÿñ|øá‡¹¹¹111?üðc¬²²2&&æ§Ÿ~ŠŸ1cF^^ÞîÝ»gÍš•““søðáo¾ùfÖ¬Yyyyqqq³fÍÊÏÏŸ9sæ¾}ûòòò&OžœPÇ·½|ùò   iÓ¦-X°`éÒ¥+V¬xóÍ7ŸÇ‰–.]:wî\|þôÓOe2Ùµk×,XPRRBc>ýôÓ   jJV^^¾aƾ}û†††®Y³&**jÁ‚wïÞýàƒ¸û¶oßþµ×^«¯ÈÑÑqòäÉû÷ïÏÈÈ(--Ý´iSÿþýŸ9wkôèÑ7n\°`Abb"dÓ¶oßîéé¹`Á‚êêêQ£F%%%]¼xÑÆÆfÁ‚$³ýç¶zõj…B1~üøèèèíÛ·?^v/”oº�] ¯ó‰ÄÙÙyĈ½zõÂBLu‘ÈôPŠžqõXµ)×çƒZˆšL¦’’DÕ ƒV«· •7•••-[¶ÌÉÉ&JVVVvvvnnnaa¡V«$4oÞ4:>I©Ìb±ÈårRÙ¡þÙܸ¾R¢ˆKx#AR‚Ú‘†zƒœÕ«W÷éÓgîܹýúõëÚµ«X,îׯ_çÎ9b±X-Z´oß¾³gÏÆÆÆ†‡‡6ìðáÃ¥¥¥k×®7nžrÆØO?ý$•J'Ož¼aƘ˜{{ûI“&­\¹ròäÉUUUÇŽ«ãÛ¶±±Y¼xq³fÍ6lذnݺ7ÞxãyœeݺuÓ¦M£¯_~ùåæÍ›{öìyõêÕÑ£Gcã²eË4Í¢E‹žÜ}úôéíÛ·2d¾6nܸgÏž...hÊûè£fΜY¿ÏP‡† ²hѢѣGwêÔiàÀÏ):Ô³gÏV­Zedd¨ÕjƘJ¥êÙ³§T*½xñâ€<8pà@WWרØXt%øÛ½{wZZÚš5kþþÈe2 ºPŸƒÁ�P)++»qㆫ«kQQ¢mÜîCÁ+l¡*nA%¢#T¯£Õj«««©�8ÊH–\¹r¥¼¼µ¢¢¢Ç—–––——“&Bee%·=6éxÒ-ïB¥äÞÀÁ"$ÔhZp›ˆÎ{‚«·Í[=@Îĉ÷ìÙ“˜˜¸yófP)#‘HÚ·o¯Ñh®]»–––äãã³cÇŽóçÏïÝ»7""âÁƒOr?T*UDD„L&»~ýzïÞ½£¢¢ê¥ó«Éd:tèÐ/¿üâçç7oÞ¼'›oþ÷¶k×.£ÑتU«ÜÜ\dš5kqî+W®`Ø­[·L&Sppð“G¸r劋‹ Í\\\"""œœœhߌŒ ©TÊÕÿ®svv^·n ý~øá‡¦M›>'ȉˆˆðõõÍÌÌDÌÓÓ3""B*•fdd@8²C‡ÁÁÁ999\'ò©öàÁƒ²²²ÿµ=­VKA*l¡0^öõzýgŸ}véÒ%B¹\l …¯¿þ:(ÔŒ1…B°8¡N“‚TXße2™ÑhD‘4“ɤÓé ƒN§Óh4ååå>T«Õeee?Æ¿ùùùëá¤ø$î2«aÜM˜0§£ÜAÉ€áa¬Fn�A?À0ã(ë`M#2oõ92™ÌÖÖÖÖÖö©jÁ;vœ0a¬Y³ zm]ºt)##c÷îÝÞÞÞ“'O.++«µKFFƾ}ûîÝ»7gΜ1cƤ¤¤\k]Ú÷ß¿lÙ²+V\¸p!<<|øðá7oÞ|¶§ðööÎÌÌ\µj؇~å•W¨q'ìöíÛ999ܦ–‡>}ú42 Œ1ê pðàÁß~û­ÖL¾òÊ+/HÐkÐsúß¼páB¸ôưoß>tð„}óÍ7íÚµËÏϧ-z½~ß¾}ׯ_òhyyy·nÝŠŒŒ$/¼a—�ôÖkDØX Œ$d¸å&“é×_U*•h L\2$ø"À³Ù ¾�Ij’p�п:N¯×ët:äŒñÞIž Âkr¹á2¸MxÝ´i“D"6<½s]º0" €ÿMI,üÐR*•D²àQá¹Ú›({ùå—ŠŠŠðµ¢¢bæÌ™ýû÷W*•ï½÷ž ¶9ræÌ™óçÏ?{ölXXX·nÝœ˜˜˜ŸŸ?vìØ¤¤¤:ž%K–„……1þü¤¤¤?jŸó× œ(ÆXjjjJJÊèÑ£u:ÝòåËçÏŸŸžžŽ6ÉG޹téÒöíÛi¯9sæDDD€A7qâDl¿wïÞ'Ÿ|Ò«W¯;wîLš4‰1–pëÖ­£Gþ/<¦UUUüñ¥K—ÒÓÓèæævþüù/¿ü²sçÎÕÕÕ111hŽ·råÊŠŠŠnݺVVVŽ7nÖ¬Yï¼óNZZÚüùóÏŸ?ÿÞ{ïÙÚÚž8q"111!!žÏþGÎÑãjõSKPV#ý‰òÊè�0 ¢FUÄXD•Ø�9 øÌ ÊQ)¹£ øÍ�?®–·m«¡E+ƒQ*•†xµ4Ó(WË•‚óÀPŸm™={ö¸qãcÑÑÑíÛ·Gq~Û¶m}}}çÏŸ1o¼ñF£FŒFcïÞ½[µj¥T*½½½===ÝÝÝM&SïÞ½>ûì³;wî0ÆBBB(û ¸l÷îݶ¶¶øìææ†‹|N碙tqqn[ïÞ½ÃÂÂjÍ$lçÎ(ÛFbœ¶?Íñz÷îŽm£Fzíµ×^œEsÑ¢EÏñÕ½{÷ï¾ûN£ÑôîÝÛÏÏÏÍÍíã?†Ó·oßöíÛ3ƶoߎhŒ§§§···ÑhLLLôòòjÚ´)÷™T(;wNLL¬õ†±oß>''§†úwNŒ/¬æX»€²³³Óh4”Ø u2VÃ!&&UòsktÈ­A$ ê€; •J -ú:Žê1¹"7@#n†K9ƒ¯†Sãâ©#«Bš1†ÓqÛíp㴌ӳ€ZìP)ou 9vvv:uân¡>Óžžžh«¬V«—-[–žž¾råJÎÝ‹‚…’ÌÕÕÝæ¹cê̸)“Éžëpg²Ö‰h&ɨ7v«V­jE8kíëãããããóâ<IÏÖG|Òjµe´··¯5!µdX% ¨õL:;;?ù?Üj¨5?±ÊÃ[€€9–cx3 ´]ÜâUÛØØTVVReJA¹žµB°X,z½žPVv®´(ÄlÐ6 N«IÃÀÂ5@…þ—-MšÖ¤ÝIÎ +A &·»(¡&.’ކ4°–]TT´k×®?é`Ïo¼Õ¯ôz=E°ì"‘C .¨eP¯!y.·I(CCÈ€t©'4|à9%¤:C¤j,ýø ×ëE5¨ ʸhµZ.TÔrtÀƒà6«¦W¢Jt)ÎF‚=DÉ£°aÅZxÈù+!£¯¾úª¡NÍÅ‹p¿ðŒëÆt:Ýùóçù?¶ú2nËK.Np \¸µ–p/X(ÑØÀCÃAÐb�‘(ÒmCre$óje€E‘8¡+¡þ7 Ñ‘ÎE-×èªZ¸ÌiR¹�9$—’’ª(¢¢T"ב†xNÄ“¤_\ÈiØÔ€›gÔeW1™LV—áêÞ^pæiÛÐ ‹°ÕêSÛf¸2ä Pæ†ZË� ¸ôbŠÝ‘sp"?ƒ$«Á1£F×@AJ±šÔ úO))ŸO9rP¨¡91ŒÓw!5NG‘:|à6%u`‘HE~õã!§®-99¹Á3hë&‹öã?6xî©··÷ Û/ͧ)†þ˜øêìì\\\Lë;I°1PöÇÒQ®¼&ñª)»#‹mllÀ%A^ÎŽbLjŽ@Nùa¤¥Fœúp ¥R Ž5âo„^¸5 ÉŒ’…þ¨‚‡q˜Ù¬†[Á×åðSÖ½{÷† ÊÉÉQ©TuÐ/‡1Ý€ƒV«5??ßÃÃã…mÐ@å)r¹\§ÓÉårJ”——Óû>E®ˆÆmÏ\+LG?Q¨ ë>5ôD�K{Ã� w#9F(ÄALŒ<¡ZîÙ¨M5÷°;@)J&Q+ ú‘Pã p ~ä!§ – õîΞ=ûœ”LŸ40—0䤦¦¾Èýr(6ÅåbQL k.ÉÆ„pcVB¡ÐÕÕÕh4–––mŒqbA7 …k:áÞ°Ês)È8a±(FŠœHQâ‡züèt:â&P$‚8,.‡"Lå ä°qK¼=?ãKmyã­¡¿WŠÅV«U©TÚÚÚZ­Vè¾PR nO6"£Æ�S]]­Ñh°"c‡;‚`ê`¨Û ©¢9::r³ýˆÝ¢¸Ž/1†‚r $` Õ‡BG¯¹=¤ K¸¸a7jæF,5Zx<|WÐzƒœÔÔTWW×}ûö5ÈÛ~çwð9//ÏÕÕõ9)<Z­Ö={ö`&5««k@@@­~9]»vuuu]²d íEýrÂÃÃ]]]?þ믿6oÞ<**ªY³f.\ ~9]ºtquuýòË/ëk&=zäêêJ…Y‡vuuEw€gh¹¹¹èyºzõj­Vûí·ßb&[´hqÿþ}ÆXLLŒ»»û“ýr²³³ƒƒƒ£¢¢‚‚‚¶mÛ–ŸŸOýrÜÝÝcbb=z”‘‘¡R©PéÜð ¾…N§+..ÖjµÐ}¡¼=�¦oß¾îîî$ŠÃjÄÊ”J%<µZÞ3X¸‘º···oܸ1*~�68 u£©¨¨ ð<ˆ½F]¨—7ÆE9ê'íííZ]J2ÞÈa¢Ã""cOH‹r};buóÀP?5„5Û¶mûóÏ?3ÆÞxãÄÄDÆX×®]}||òóóOœ8Á“ËåÐNII)))騱cJJJ÷îÝIkРAOj«ëÕ«WjjjzzzhhèáÇ===ŸSî÷ÀÀLb9^ºti¿~ýð+–æo¿ývéÒ¥ÜRGôËÑjµ .<þ¼‡‡G||ü¼yóbbb 0vìXê—³aÆ;v<ï2Ì?1…Bѵk×´´´¼¼<GGÇ”””ÐÐÐ&Mš<Û³üúë¯]ºtY½zõæÍ›çÎÛ³gÏóçÏc&ÃÃçM›öùçŸß¿àÀ6l¨µïܹsÍfsJJÊÒ¥KgΜٷo_LûñãÇ'MšqþüùãÇk4š†ħªü©r\’¢IJJ"´ ·%â cA¾yó&Vm,å78yò$rõÔZ«t@}6Iw‡ŽÏ­ž!AOjÐI=ïÊÉÉÁŽè¯ƒÏh+‡ò6™Lð‡ˆ,G~uÐ!í5¢hS:ŠÏåÔs`mÉ’%7n4™LqqqóæÍ3™L?ÿüóôéÓsrrbcc8`2™.\¸uëÖŸþyÚ´i<˜>}ú”)Snܸ±`Á‚­[·šL¦M›6qßâëÝ/^Ü¡C‡iÓ¦ÅÆÆ®]»vÍš5={ö|'Z»v-õ/X¹r¥@ 8yòdll,©Òa{«V­ øÆµŠŠŠ­[·¾ñÆK–,iß¾}llìíÛ·§OŸÎÝ·mÛ¶s«spp;vlbbâ7ÊÊʶoß]™g{–áÇ/_¾<66vÿþýÆ óòòZ¿~½££clllUUÕøñã?ž––¦×ëcccñVô/í«¯¾’Ëå£Fzë­·Ö¯_߀ûåPO¢È- _I=“Z´‘Œ[ C¼ê{÷îíß¿½×¨è’ôXù%øL2¢P ²á{ÙÛÛ9Òßߟø¢k&ç©–¬�Ñììì¨eØäñpõÙ‡1Ák¬Õ?ä˜L¦´´´Q£Fùúú9rdÔ¨Qááá)))ƒaöìÙëÖ­5j”H$:vìØ•+W>|8xð`¼€3Æ<èãã3jÔ(OOϼ8·­T*?þøã¸¸¸¯¿þº{÷îÏã,Ë—/Ÿ={6}ݹsçwß}7bĈìììáÇcã¢E‹ ôäî|ðAçÎß}÷]|mÚ´éˆ#š4iBKê‡~èèèøÑGÕïdâ"çÎ;dÈÈÈHºµgk"‘hĈááágΜ©¬¬dŒŽ1B.—?~|È!ÉÉÉãLjåÖžjÛ·o¿páÂæÍ›ÿþÈÑì’Jg @‹;1£’8#õš´´4ÊÖPf…jõ¹¢œäs ˆq<r&p@yEÄA`5Ôô;HKKËÏÏGL»#@Gq<Ò‡¦›e52†Èmº#  ÄQD®X«gÈù»té:ÒÒF‰DâëëK_O:UZZøâܶÑhŒ?vìX›6m>øà$ž­mÛ¶Íb±¸»»C½ôáÇz½ÞÎÎ.,,ÌÉÉéöíÛöàÁ³ÙÌ•O%»}û¶ƒƒ‰~:::†……ÙÛÛÓ¾wîÜ‘H$uF<ûGgݺu¾¾¾xNär@æåå• ­ûF………I$’;wî` jÞ¼ùãÇ+**þühùùùUUUõÞj¨ÎL§Ó¹ 8 dƒ"õ¡ –ÕjE?n^¾ jtà+`AG6¼§"Ø¥T*[¶ligg(qY,Ëår,ñööö”@‹ÅŽŽŽ\‡Ìd2]¸pA­V�Ø�”¢–DOÀ¯ÄµÃâú wF£V«Åñqj®t7/.äTUUÍœ9søðá)))5¢í XdddJJÊܹsŸl´\¶sçÎÍ›7¯]»6%%¥gÏž#GŽLOO¶§hÕªÕãÇwíÚ•””èíׯ·I(c,##ãÁƒ}úô¡-ûöíCeÌ!µÃùþûïkåä/^¼XPPðd8®AÚéÓ§wïÞÍõ¼wîÜyáÂÚ²gÏž¨¨(n«=N·sçδ´´'–žžÞ³gÏ'¹ø\Vd,©ÄÀFª·G$éªa¥¦bOò�]Ð[#…iŠ˜ÕâF7kÖlÛ¶m½{÷¦óápp‰Dâïï½N\$¤~¹Yî]?D¹*ÖašväòÂår9| nKPV“ãQA·fˆ·ça½.G©TŽ?þرc%%%£GÞ¾}ûK/½¼jÕ*Èï3Æf̘ñå—_N›6íØ±csæÌyqn{õêÕaaaÈßÄÆÆ†„„?~üÙjÀDDDDDD0ÆRSS‡þÎ;ï,X°`Ú´i—/_ž1cc,99ùÊ•+;w/^üÿØ»Îð¨Ê¦ýlßͦ‘PBïJG^Š‚¢£bˆ U@é½¢XB‘˜Ï( ª  €T JHHB ée{û~Œ¹ßñ}AIw~p…ݳç<ç)Sï™iÚ´i=¨‰Î°aÃèóüüü¨¨¨îÝ»_¸pfrûöí©©©'Nü7lS™L¶dÉ’“'O&&&¾úê«ÕªU»|ùò'Ÿ|Ò¾}ûÂÂÂ7Þx£F›7o^°`AaaáÓO?ýè£N˜0aêԩÇã7Æúôé‘#Gzyyýúë¯{÷îýöÛo±QnB NÁþQ/�^&Þ{ùe¿'úqØFHÆBddd¼ÿþûÔLçñ€¹ÇÅÅ¡{Ëå‚¿^/¤sÂiơςõM€sèòþ•€Äœ bé&¸SsJ÷,“sÜh4nÛ¶«ÛƒáÒ¥KµjÕºsçŽR©¬_¿~ZZZaaaóæÍ333oݺդI‹ÅB[¤aÆ©©©UªT1™Lf³ùÚµkááá7nìÖ­ºm6oÞ¼â¬eRR’N§#—”ÍfKJJ €­vòäÉFy{{?}3éãã“@6nÜX£Ñ`&Q\'))I«ÕÖ­[÷êÕ«&“ P4$ŸÉ[·neffþåYݾ}{ÿþý`õ+W®˜Íæ’Ø¹üñ…^øû© )))äO«U«V¥J•hV‰QÚðÚµkäO«Zµ*5gJLL¬V­ZµjÕ’’’ÈáS·n]//¯üüük×®Ñ߸ÿùóç½¼¼þBÛ$—Ëõã?†††VÀêÙÙÙW¯^ݺuë_|Køc൸ðP«Õz½žf’§³À !¿üiÄè)û’¾¢¿É Ñëõ  ë)$#?0Œ¨N(}Kå¥16²EH–�K6qÈÎ,$КÙlFiŒ¥zx ]—ËÕ§OŸ>}ú´jÕ }#·mÛ6pà@·´¸/ºzõjJJJ×®]) PXXøã?Ž?þ­½^OZ?úVá4V©R¥J•*BµZ ËàÑG]·nÝœ9s>þøãK—.Õ¨QÃÛÛ[¥R•eùÈ{'ÎK{˜IQ¢˜&f²äÀ$š’ƒ¬^½úÇ"ÿª[·n©Þ_Ò‡Ï*‘¤{R©ÄAèããSrÅ+l…´¿O•*UªY³æåË—á’Åu6Qt™1Á·$*L&iEpF Ö·ÝØPŠ è2Цõpùòeô'E> jÏÓ'ë„~Žº;4r2YP5�²‡@ pÙ©T*º³^¯' �’¬ÀãQ 7‡Ãa4µZ­Û±VAk%iàÀ¡B,]º”ºXºÉMn*_ÊÊÊjÖ¬‰¸¤àn‚‚fÂÃn @= E‹âp ]L|ßÓÓS©TæååY,ô2@–ŒÃáHKKÃÓé¶V«ˆ5 í R�¢8h®ç° xQ\¾“"F¢¸84I)Þùaêx%Cp‹œŒÈB 2ä¡™šcÇŽ¹ûå<2›ÍGŽyXg²âs(¥RùÓO?Á&@KâѨ–&Xüœl\.—V«„ 5c€u¦Ÿçææ¢Äòÿézäf¢‚˜A¢(d \v<҇mˆÐÒ”nN†—ÁÆÛñÔT^Ì�´uàÉ=núgˆœ‡†œNg›6mâ<äöíÛ—ÙÛ©T*I+臌*xÅ{‚Ÿ‘{Š$1Y² f`¸ð:4ôsrµ¡<]ÆY9,z ²5é·ôD­VK² Ôô Q [ lÿÛ·o#S†# ¥èȇ&i™ƒ>§„Fƒ Å•T¤WÞÄÚMn‘S¦tàÀ‡AëããÓ±cÇ2xÐöíÛzͱvíÚåXvè^ dŸG EP|LA}Ûà.CNÔ¡ìM#ÇàC†jqR|…®¤ÛZ­VòzÁ‹‹‡x½F£;vldd$JA+ ­VK‚3ð^^^”úCƒDhÇd2¡É½ %ÀÒ+Àwï³!iÉÍ�Ý"§¬©{÷îÕªU{ˆ½ºW¯^mРAÙô˩ȅý¥¥¥Õ®]»ÂöËBð*/¼¦`ݦ‰ÑóÄOF 1nB‚~EòxQ\Ɔ„–kÈ…{{º(ŒD&ÑüùóÉù†F£)((ÀÈSGà7º B2ôtàHb!ÏhB(-”Þ€:2æÜVŽ[ä”=ÜýrâââîZò ô;ëLº\®“'OþtuYÊžn‚h°3Àmy©¸È€`F‰L)à\CQB‹¡S••JUTT„r¸)•J£ÑCŠn’ŸŸ¿!x$„€ÅÆ«Æñ~kø­ŸŸ_aa!¯´œì.xSn"NXæ¼Õù!”µP(¨Ôt_D‰¥:Èu橽‡Ä¿„Ëåt2‘¸@ÊVÔ½2*)÷Ø„›ÈåîÄ6ÌpÉÙ£ÚŽØ*¤,ÓÅHÂxøˆBëä2BÜÞb±¨ÕjäBRa=#ND^ƒ�9:ø-9¬`F ™/Y,TÿìСÉ'PçrzD1›W<ƒðCã8à$Xj\˰hTEEE�2@2ÑËRmásSiíÆ?Ñ‚«W¯Þµk×ÐÐÐÐÐÐÕ«W?Øgee9ò©§ž ~å•Wnß¾}¿w°Ùl¡ÅÔ»wïêÕ«GFFV´ùu:ÇŽ›5kVõêÕ©Ø(??Ú´i?þøóÏ?ß«W¯ëׯ§¤¤´iÓ&44´C‡Ë—/7 Ë—/ïСChhh›6mRRRJ{´/^lß¾}=®]»v/×4¨U«Vå;ÇnÒ¤Ihhh‹-vìØÁ·ÇÊ•+Û·oÚªU«äääëׯ?÷ÜsÏ=÷ÜO<1yòäüüü;v´hÑ"44´I“&‡~ˆE ªåìr¹ÔjµZ­&kf u<ß'¡‚RQ *ÀŒD¹¤P‡wEs6âãh P(âããÑt‡ì ›Á`‚N°BפC ²'‰L²·È ã(gxÑK-¨!Aé_²‡È¸Áœ¸©|k“'O Bœ9sæ£>êÓ§Ï7ß|Óºuë‚‚ÊýnÓ¦Íc=öí·ß¶oßž<]#„ ©]»ö•+WvíÚ%„ðööæ5†ÓÓÓ«U«6{öl›ÍöØcmÞ¼yÔ¨Q÷A*�˜�� �IDAT5t•JEåË„k×®½qãF§NöîÝKœ½uëÖ;v4›Í–ÌÉÉÉÈÈÈÊʺzõj:u*W®|âÄ ///´k+ ‘³uëVàtæÌ™U«V­^½ú‰'ž¨W¯Þš5kRRRl6ÛÎ;—,Y2þünݺ͟?ÆŒS§NmÔ¨ÑÂ… y±Ò ÷Þ{¯sçÎ&“é“O>yë­·6lØàééxìØ±x{{Ÿ:uê×_¥%æ ´¸¸¸'N!êի׳gϲÜÁãÆkÙ²å–-[† òæ›o¢è\^^Þܹs§N:cÆŒ¦M›ÎŸ?ÿ‘G‰‹‹KIIùõ×_øÂ /¼ùæ›O<ñÄêÕ«{÷î=nÜ8z…‡Èb <|°c ˆé“!Á ãJªþ ›€Çü*#BÁ| ¥I„5IåÈþ #žPdë@òIB50nD1Heu¸ÉEuKy7`¦iT¢¸@œ(ND…l£ò²¡nÁPn"tèСٳgïÛ·oÏž=Mš41 £Fºsç΄ V®\õÌ3Ï´jÕ*&&æÔ©SO?ýôÖ­[wîܹbÅŠ±cÇV©R¥W¯^sæÌ1 h¼Ø²eË–-[¾ÿþû'Nœxì±ÇP¿ò/ЪU«¢¢¢>þøc»Ý>iÒ¤×^{-''g„ ~øáW_}uäÈ‘qãÆÅÆÆž;w.44422rÀ€J¥ròäÉuëÖ;wnQQÑý ¼{_¥rñâű±±_‰þùçŸ;¶qãÆÌÌÌI“&õîÝûý÷ß/,,4hÕ‚7nÜøñã;wî<{öì7N:²süøñO=õT5&Mšät:{õêå>Z‡l–Îí …“b“dµÈd.§SÈd ¹Üér‰b †cȰ ”)B&— DVè>Å?q86•Šä„U&ûÍ�’Ë…Ëe¥ÜR¹\V Z“ÉåŽâ`9ăڿc„BÈXj’‡œ.—B.w8¢ø+«LöÛ].{"¼ˆp¹h0B&Åö™Óé4Š2ÌZs‹œßQTTTlllË–-6l(„ˆÿõ×_Éã_«V­#GŽ,[¶,==Ýb±\¼xqñâÅ›7o>tèÐ'Ÿ|réÒ¥%K–äææ>|xÚ´i!!!Ó§O?zô¨¤×oXXØ#<òÚk¯<y’q¿ôÕW_ÍŸ?ÿ³Ï>ëÞ½ûÊ•+ÓÒÒzõꕞž}ýúõ={öÔ¯_¿_¿~Û¶mÛ»wohhhbbbݺu[·n=mÚ4™LÖ¯_¿Ù³g>|¸”DÎ?ˆRRR®]»FUò’““ÓÒÒ„AAA#FŒHMMݳgOXXعsç¦NZ½zõ7â‡7oÞLLLœ>}z“&Mf̘‘””ä9ëÿø£lÓ&…R)/fç� E~*„oé[»Ý.W(dB¨YЍÉd‚Cì7^, d2™ÃéÔh4v›Ê̺ù·§Èd*!äÅ™§è̦Ñh\BܲÚltÝáËdv‡CVÜ™4 ¥R&!Í …R¥²Z,BÜDÈdµšœ«ê3ͤ‰IPBr¹\ýÌ3¢sg÷¶)‘3cÆ r¬­\¹R±k×®úõë§§§Oš4‰xÓ=J…C‡5kÖ¬d{’ÀÀ@£ÑXPP——÷F_PPðïi|RJTPPpåÊ•FÍš5KQ·nÝääd“ɤÓ騞<§»¢³Þ~ûíJ•*uîÜ900Ð=ŸŠ™™ÞééH„:ÿ›­8äNýs�Pv82!Ô ¹§lv»B¡P(•”xI4´É¡;(•J’` ™LIá§SIñ¡ß÷½vÙíB¥r ¡+. ú›ÍåúÍÉæpÈår™ÓY³fÍÜÜÜ‚‚‚ßË+^2™S¡PÉd¿%œÊdú­˜´Ã¡ _\±{ µsdBÈ átÊ 5ÃI»\.Ey‡'ÝŽ5)}óÍ7‡:}úô¥K—^~ùåÿy}DDÄĉ?ýôSÎŒRSSwïÞýw26Ç[o½uüøñÿû¿ÿ«U«Ö?hÒwïÞ}íÚµ %&“’’>þøãØØXhÔlô®@êM›6•ü022ò?ÿùÏçŸ^¿~ýò}—“'O;vìÙgŸuo¢Î;Sÿ^L—ã¤0 *r V»“—·3HW-ã lpb<À"N†¾ ¼-‚Äæ̇ơۈÇü&M‹-x`ã½kZÊ%ŠÜ\>oÙ²eÉ9$·{/•È Þ¾}ûôéÓƒ‚‚BCCcbbrrrîz¥ŸŸßèÑ£¿ûî»ÄÄÄ£G®Zµ _iµÚ_~ùeÏž=¦cÇŽ=zô¸ßaØíöO>ù¤Aƒ~ø!}R·nÝ:Ìš5Ëd2·k×nöìÙ³gÏ>|x|||¹7lmܸqÏž=qqq}úô‰ýî»ïš7oþÒK/œ<yrøðáIIIcÆŒ 3fÌ–-[RRR”JåèÑ£ËwØÍ›7§åæM.„­Zµzþùç—-[¶fÍšÛ·oÿ°Ü_ Ù³gO›6møðá'Nœ %>pàÀÂ… ƒƒƒÇ·mÛ6¹Œ3Æ××wçÎ'NÌÎÎ mÞ¼ùìÙ³£££‡~áÂ…»ö8¨Q£Fÿ’ftŠnÞ¼)bæçç8pÀ=3÷N6›ÍÛÛ»äçØ/Çl6§§§W­Z•zŠäååegg×®]›„EEEZ­–䇇GõêÕoß¾m±X‚‚‚rrrrssëÔ©c6› �­R©$™ììlò§yyyñ¾¢÷H.—ëòåËü___»Ý^TTDûûû;Ž«W¯Ò·AAAV«õÖ­[æÚµk~~~•*UºzõªV«E¿gñ ûåÐ~ÍÊʪU«å»dddƺuëÒ¬bö„×®]#tM@@€^¯7 4{J¥RRœÿo’¤_Î]—[¡ÓéjÔ¨‘‘‘a2™oÞ¼i2™¼½½›5k6uêÔ!C†ðåBèõz>“âÁõËù#r:èëEû3777''ËÍgïÖ­[F£‘”¡J•*Ùl6 Y‘¾ò×r�+r¿œœœœ´´´öíÛ»5ôû%///â$Bˆ]»võéÓ§lJu<LDî¬Vë=õËÑjµÜCâëëëëë‹ÿRç+ú uˆQ¾ñóó#ôGžÿ¿ü>2™ì®wÆÀÈîæ×P¯9úH:Ó”ùøøøøø”¡dVE‰¦/2{–þçr !âãã‡Ú¿ÿ¦M›úùù•\î²'¹\.™¢J•*ÑžäËM$é0¤R©ÊÝ XªDëB 7¼/‚¼!¿NQQ‘{ÿ‚¡s—ëž7Ý#µnÝzÙ²eƒáĉ ,wω›Üä¦û"wµ?¤C‡ÝUJ?|JܽÓã?þøãßï¯L&Ó/¿üâÞQnr“›Ü"ç.D(.]º<ÜýËæí¨+p·nÝî ã>5nr“[äüE"°ÊCßö¯:÷KO>ùäC\FšÈápTäÎnrSE92™ì!.¦ë&7¹ÉMnª@"ÇåríÝ»×=#nr“›Üä¦HžžžÈsúc­uëÖåD‘óò…!òž‰Š*ìÀ$„âŒÿÚ-ô'3ãt:+&…Ú#UÀ©«àkZ‘O¨¤TD¹ÆËË %$~'r¼½½õz}7)²Ûí¹¹¹z½ÞÓÓS”_¥  €*zzzV¨6M………‡C£ÑxyyQ–hŤììlN§V«u:]O Åb)**ÒjµÞÞÞ°ÅVnn®R©ÌÈÈ8räÈ]ó±Ë—*W®ÜºukIÅår§ŒŒ OOÏ 80  *Nêíí]Nh^^µ|,{f^’¨©«^¯G"­>`³ÙÊ8šŸŸöìÙ®]»Š² hߕΜ9èp8 ©tù™3gªT©R»vm»Ýn¨À5Õ:Ô¥KªF|õ^ݺuëæÍ›mÛ¶u¹\pŠŽ=Úºuk!D:uÚ¶m[ÑL½^OçÎh4VœV1‡ã—_~¡By&“©"7ëLLLÔh4 4¨ ¬#..®I“&UªT){f^’Nœ8Q¿~}žWîNu“›Üä&7•¹EŽ›Üä&7¹©Œè¯çå<xV[ÇŽ;V¯^½»Öº/ÊÍÍ‹‹{ôÑG/^¼¨ÕjÛµkwæÌ™œœœîÝ»—Í�vïÞجY³r_ÔãÇçååÕ¨Q£E‹sÛšL¦*Uª ÂyçÎ ƸÏä_Xn»ÝÞ©S§Š0˜'N˜Íæ.]ºTäûG ²lèÊ•+©©©]»vÕétw½ 333>>¾M›6%ûf•©•³eË–#Fœ*¦ÌḬ̀°°»¶Q)3JLL ;|øðùóçSSS…K—.6lX™ àÔ©Sׯ_/÷=ôÓO? 6ìøñã×®]«°=--íøñã<&œ——çΦük4wîÜ)S¦TÁ,\¸püøñ|ÆRSSÏŸ?ïÞ9Bˆ­[·†……ݹsçOÄsXXX|||yZ9Û¶m›>}zvv¶ËåjÚ´é×_ýâ‹/âÛÑ£GSûiÓ¦µ*…þz/^œ3gŽB¥R­]»V±råʸ¸¸×^{.¸páBåÊ•·mÛvìØ±¢¢¢¨¨¨3f<Ø18p 66váÂ… 4Ø·oßǼhÑ"Šó !¦OŸNì~Ô¨Q:uŠˆˆèÕ«WDDÄäÉ“½½½çλbÅŠÓ§OöÙg|r<8iÒ¤7näååyzzöïßáÂ…óæÍ{â‰' å]õèÑcذa³fÍ2dÍä¢E‹¨èèÑ£»víš””´`Á!„‡‡Gi d2™ƒ‚‚ªV­ZPP V«¯^½š™™Ù¬Y³ÄÄÄ:uêÐ|>XÊÎÎ3f ý]µjÕeË–}ùå—Û¶mBtêÔiìØ±BˆÁƒSÅ„ÈÈH;vh4šÝ»wõìÙóã?Blذ¡”¦åwÞ9}ú´",,ìÅ_¼sçθqãè«Ï>ûÌÃÃcýúõ;vìBtéÒå7ÞÀW¯^½{÷n!D÷îÝ%ß /}›bcc}||¾þúëÍ›7“«ãBHi4CBBppìÀÆŒS«V­† nÚ´ ûY2Hú<<<üòåËYYYe?H!ÄéÓ§ßyçÉ“'׫WoôèÑ}ûö}饗FŽÙ¸qã‰'FEE={VþüóÏß¾}{„ ôÃ5kÖ”^Ó£¢¢¢þýû¿øâ‹aaaùùù£F¢Ïcbbp ²fÍš›7oþä“O`\FVΓO>ÙªU+½^?jԨ˗/ïÚµ ¥Ñ£GïÛ·/::º^½z/½ôõ\y€äp8zöìéï<`À€µk×.Z´hРAЭ<xüøq>ȾB999¿üòË¥K—l6[BBÂÑ£GM&Ó®]»ÎŸ??gΜÏ?ÿ<::º}ûöƒ JNNŽ‹‹;qâ„Éd¢ †_ý•xʧvíÚ=ñÄBˆ‰'¦§§ïÚµ«gÏžñññÿ÷ÿóúë¯>|îܹß|óÍÁƒ§N­Óéž{î¹èèè6mÚ 80!!á¹çž«^½zttt||ü!CJOä$%%U®\ùÔ©Sùùù………ÉÉÉ~~~§N*%¾¾¾ÑÑÑ .ÌÊÊ:þü®]»¦N6~üøÅ‹¯^½:"""!!!::ºjÕªÏ>ûlvvö‚ ,Kttô矾cÇŽèèè7nôéÓ§4ædÅŠÑÑѯ¿þúË/¿¼xñâ'N„„„!¢££ ň#~þùç¥K—<xìØ±‹-"­Kñý÷ßÏž={È!#GŽŒŒŒüúë¯KcxÏ?ÿ¼ÕjŽŽÖjµÃ‡ß³gϤI“úôé3iÒ¤·ß~ûÓO?¥ËvìØ1}úôððp òرc«W¯5jÔ™3gJÖuàÀèèèY³f9s&88˜i4_xá òõ×_ßµk×åË—?~ðàÁ»rݺuûöíó÷÷ïÙ³giÀä >œœœl4wíÚuñâÅœœœýû÷_½zuéÒ¥K—.ŒŒ|ñÅ.\xêÔ©gŸ}Öjµ¾õÖ[BˆRÒ!ˆ&NœH‹¸gÏž^xÁh4FGG[­VÞAmß¾}Ë—/ÏËË+,,ìÝ»w™:Öôz½V«•Éd¼SÜ#‹%>>þöíÛ¹¹¹¥¹ÌÉÉ!÷¢ÉdÊÎÎ6&“©fÍšK—.½ÇAþ} å•WΟ??wîÜyóæ5oÞ[ÊjµÆÇÇ_¿~=??_.—ñÅëÖ­Ûºu+´•;vlܸ±4¶ŽN§óððB QãÆNž<¹víZƒÁpá£ÑHmÊ t:]NNN@@€——W~~¾ÝnÏÉɹsçÍðõ{} Ô¦MêH/Ù'ô¹Íf+l …B°aÙL¶yóf³Ùl0üüü*W®l6›FcNN]ãááA¯o2™”Je@@€Íf³ÙlJ¥ò«SDÕ«WòÉ'_ýu½^¿aÆvíÚeggS Áõëׯ_¿þÉ'Ÿ\¿~½ÓéLLL4™L´”4H£Ñ˜œœ|áÂþù·5M@@ÀêÕ«7mÚd±X C¥J•ªT©B3I—ñYÅ`t:ÝøñãïÚéùï“··÷Â…  E^^^|||AAANNIæ)讃¬W¯^dd$ŠÒäã?>f̘7Þx#33“>5j”Z­^¾|yaa¡Õj­ZµjXXØñãÇÛ´iÓ¦M›œœœèè興ÞRùÓÇ\©R%ƒÁ`±Xrrr âããѧÔµkב#Gj4š¿³ù|YORü›4i2sæL½^_Jû>!!aàÀ5kÖ,(((hÏž=øá‡Õ«W·jÕŠ².8%$$Ô¨QcæÌ™U«V-ßf‚ ,Ëå§OŸž0aBÉqþeee%$$ :TÒÈõá äää#GŽLŸ>ý/;JúôéÓ§OŸ¨¨¨ððð®]».[¶LrAbbâøñã7nLº…„.]ºT³fÍ™3gÞûZ—ÕªUkäÈ‘¥wÿV­ZÁô,,,LHHxöÙg©Ëí?”>ýôÓ¤¤¤ &„‡‡¿õÖ[܉ZªD³\ üÁƒ¤===§L™WJ>Z·n=eÊ”ŒŒŒ¤¤$úÄb±DFFÞõâ3gΔ†Û½G5jÔX»ví£>* YÉd²)S¦<úè£qqqF£±qãÆƒþðÃ'OžÜ¯_¿µk׎7NÒž²´éìÙ³§OŸŽˆˆˆˆˆ¸GÝ”)Snܸ‘œœ\z£*—nVVÖÈ‘#ëÖ­[Jºöߤ7öë×oèС“'O>xð zl“ö0nܸ¤¤¤¸¸¸W^yå®Ð˜W_}µoß¾qqqP¢K‰¢¢¢Ô©€Ô Aƒ)S¦Øív MŸ>½‚híÚµ{çw6nÜèt:ãã㣢¢øGíׯ_BBÂàÁƒwïÞ½|ùòfÍšÁƒZT¯^½)S¦¸\®3gÎðÏ?þý÷ßÿÍ›ÿE+ÇÏϯFB//¯ÀÀ@•Jèííûâ‹/vïÞÝh4Ι3ç« …bË–-“&MêÞ½»Á`ؽ{·F£III™8qâ´iÓ&L˜ ÓéªU«FaçeË–õíÛwõêÕ‹-*…Ù´iÓ°aÃÈÓ*„ ôõõ0aBZZZ÷îÝÍfóèÑ£kÔ¨¡T*Û¶m»wïÞ¶mÛæääÆ:ÜUE} äëë(“É<<<Õjµ¢_¿~.\;vlãÆßÿý>úÈl6תUKQ©R¥š5k’®èååµiÓ¦™3g>|ØjµþðÃ¥1Hj¢S³fÍsçεhÑÂ××W§Ó©T*™LF`M¥R©ÓéJ£H”ÍfËÎÎ>yòdŸ>}ªW¯¾zõêÉ“'Ïœ9S.—GDD :tÀ€ÁÁÁ´Á¾ûî;½^Hê-±ø}³óK!!!»wï ³ÙlóæÍëÒ¥ËÖ­[ܽ{÷üüü-[¶T­Zu„ Ó¦M«S§ÎÊ•+—/_n±XêÔ©óÒK/‘F,„èÔ©•óxà´eË–þýûwïÞ½  `ãÆÓ¦M›;w®B¡0`Àk¯½vîÜ9»ÝþÜsÏÑ årù!C täÈ‘?‚á> �Š÷¹xñâ]»v !ªT©ò烤CTz ½I“&çÏŸúé§SRR´Z-Ü'NœxùòåÐÐP«ÕÚ¿ÿÆO˜0aذa›7o6™LÛ·o/ÁW(Z­600P§ÓmÞ¼¹_¿~4{6l¸yóf`` 5hÕªÕ7®\¹B€‘¿F²víÚ>|Øh4nÛ¶íÅ_T«ÕåUðÆÓÓ³ Þœ:uŠ Þètº U4%>>ž ÞT´IhïÞ½]ºtñòòR(åUðÆËË«|ݘw¥´nÝÚ`0Ð +ÔØPðÆÃÃÃl6W¨‚7?þøã³Ï>ëááa±XþN$ÿöíÛ'Nœxì±ÇŒFc«V­"##9²îï Þ tPùÒ‘#G¨à̓eæ5zì±ÇÖ­[w_¿:vìXýúõëÕ«WXXøã?Ž?ÞÝ¢ÍMnrÓÃL………±±±›7o®T©RÓ¦M+HÎì¿–Ü"ÇMnrÓÃL 6\¶l¥Ê 4¨Â–ä¨àôÙgŸñêœn‘ã&7¹ÉMw§úõëׯ_ß=‡TtPYÒ½qãFY¾ O HKK+/or~~~@@€Â`0\½zµâ¬t~~>¡!ŒFc…˜„à5ÎÍÍÍÈÈ(ËGçååч£N"pr¹\¥RU¨±q€Fzz:Õ\¨Äù@zzzGï‹rrr€j6›+ÂöC8³ì™ùŸ æî"‡Ú”}�¶N:B«ÕZXXX^"§råÊÞÞÞ.—Ëh4V¨´¿¿¿OXÉET*•Ô2¤ŒÇI™›B‹ÅR§¨V­ZF.—+•Ê ØÚÕjµ !l6[QQQ…âìMš4¡Vd‘ããããïïïr¹L&SEØ~5jÔððð(/f.¡€€�IrÏïk¼¼›Üä&7¹ÉMŸJzÄZVVÖþýûK¯xÜô´jÕŠ2Ê·C­Ãá Ç §§gÅïÐ~W›W§Ó)•ÿÞžÍf# ºÜ÷Ri¼”OÅÁ=—*¹\®„„„ÔÔÔ‡l?Ëåòÿüç?•+WöôôüÇmQ³Ù,) u¬vìØ±‚¿†F£q¹\V«Õét–/>''çÂ… :u’ÉdÙëU’\.×?ü"“ÉŒFcEnô[ªtõêÕÂÂÂGyÄårý³VðO(%%Åår5nÜØét>4/õçDN‡ÃÑ®];Êq~hH§ÓQ½A»Ý^J¥óJ(/‡×pwu“›Üä&7••Ñæž7¹ÉMnrSE9‡ãâÅ‹ÙÙÙ·nÝâÅ+,]½zõæÍ›î%XéöíÛÿˆ}x¿tåʕ۷o—ÁƒœN'h|’››{ñâE»Ý^òâ›7oVdÈþß§7nT„&¿åH·nÝ*%þë"§   }ûö111›7oþðÃ+þ >ÿüó¿E®›þ2͘1ã©§žzøÞë©§žzàmmïJEEEíÛ·_±b>9zôè;ï¼s×þ ãǸ®ëÖ­[³fÍ¿ù@Mš4©W¯^ü¶�ÚáããS¹råäääµk×8pË–-5kÖ|õÕW…QQQÞ<xpÆ ¨€¿¿ÿĉwîÜyèСѣGÇÄÄ„„„”Yí£õë×S׃=zPÞ%K–<ýôÓW¯^ÍÊÊš<yrià믿NII _µjUÿþý[´h‘ššJûÛÓÓsÆŒûöíÛ»wïôéÓÓÓÓ×­[@ƒìÖ­Û¢E‹(Š8tèP__ß>ø W¯^.\(***™úî»ïRöåÀ›4iráÂ*ö7zôèT©Reÿþý³fͺ|ùò† 0Húí¼yó7mÚ4bĈU«V=úè£jµúرcBˆvíÚ…††â)ßÿý©S§FŒûòË/:tˆ2LûöíÛªU«+W®PJ­V;gΜ_~ùåܹs&“iÍš5ƒ.ƒIHOO§6½r¹|áÂ…Bˆo¿ýöÔ©SAAA-Z´ðððØ¿¿§§çðáÃi¹i?þø£¢aƃþòË/¯]»öÒK/áàsˆˆhܸqbbâ_|Q6ï"¡ 6\¾|yÖ¬YU«VU(tº…ÞÞÞÓ¦Mûé§ŸRRRòòò¾üòËððð5kÖ¤¦¦ !zöìùøãgggó=Ù­[·?Y˜Þ½{ÓL+B¼üòËmÚ´)ƒ7ݹsg“&MÖ®]kµZCBB®]»Ö¦M›—_~¹R¥Jv»ýĉßÿ= ¬C‡¼æ·ß~Û±cGpß¾}÷ïߟ™™Ù¥K—^½z™ÍfÚBˆÉ“'gee­Y³fÀ€µk×ŽŠŠzòÉ'Ë@7º~ýzll,ý4bĈM›6Q3⻲R¥Jû÷ïß³g¢qãÆ¼ËÉO?ýôóÏ? !š7o^nV_¶Õ«W§¥¥ÅÄÄ 2¤víÚóæÍÛ°aÃÂ~åC�� �IDAT¼yóÖ¯_’=xðàÔÔÔáÇ›L¦˜˜˜%K–>|8&&&<<<&&†·µ(íã4oÞ<Ž7...nذa§OŸ>räÈüùóׯ__cسgϲeË>øà“É4|øðÔÔÔÁƒggg‡„„¬_¿~Þ¼yqqq111ƒáÊ•+111iii………111§Nš3gÎW_}rçÎAƒݼy3&&fìØ± .,¶@%iÑ¢EŸ~úiHHHAAÁ!CRSS‡ RPP¾sçÎcÇŽÅÄÄX,–‹/ÆÄĤ§§<øüùó!!!|ã7’““cbb^}õÕ?üpæÌ™S§NmРAÓ¦Mg̘Á{%ìß¿åÊ• ˆ‰‰9rä|b·ÛGŒ‘ššqëÖ­o¾ùfæÌ™õëׯ^½ºJ¥êСCÙl¤ððð«W¯†„„ìܹsâĉ۷oŸ9sf£FÞzë­1cÆ$''oذj¼ïÙ³çÓO?=sæÌ›o¾éããóøãÏŸ?ÿóÏ?ß¹sgttô!Cèà¬Y³&$$$77—fuèСƒšE–¥¼ùæ›oŒFãW_}5gΜS§NÅÄÄܸqcÈ!¹¹¹!!!kÖ¬Y°`A£FªV­ªÓéÚ¶mûùçŸÏŸ?ÿñÇ÷ññyóÍ7Ïœ9CËýóÏ?ÓžüóåÞ´iÓ¼yóBBB.]º4pàÀ—Ë5räȲñÚ>|8""¢[·ncÆŒñõõmÑ¢ÅÌ™3·oßþí·ßnܸ111‘xT£F¦M›FÑÏ?ÿ<hÐ ìÉúõëMž<ùÀ£G>|øpHHÈÙ³g‡ rýúõ˜˜˜Ë—/›L¦˜˜˜ãÇ—Á«ùúú†„„„„„üðÃß}÷Ý–-[fÍšõè£þÑ O:5nܸJ•*uîÜ922œð×_?~|µjÕ:tè0gΜ¿ßàüæOŸÞ­[·œœœëׯ'%%9N—˜˜èçç·uëÖaÆùûû[,–””úIÕªUoÞ¼9|øð²9Qׯ_ÏÉÉi×®]“&M®_¿ž——wöìY??¿)S¦”eÏ.>ø (((99Ù`0$&&Ö¬Y³S§Nr¹œºž<óÌ3ܪíÕ«W¯^½ÆŽ›˜˜èt:iVÏŸ?OàfƒÁðõ×_8p  F^XXèííýÞ{ï9rëÖ­žžž.\¨U«Ö¶mÛþ(T¶~ýú… úûû+•Jè—/_ž1cÆíÛ·}|||||222JVÊ©_¿>Õü7›Í:uª[·njjªÁ` ¾«:uR©TçÏŸ¯Y³fåÊ••Je³fÍÊf-Ë™3gŽ;¶jÕª¨¨¨Û·oß¹s§}ûöëÖ­»kHé‘GÙ±cÇsÏ=ççç————––&„p:íÛ·¿yófíÚµív»¿¿¿‡‡GRR’Á`HNN®]»ö{ï½WÆ}-{÷î=xð`…B‘˜˜HŸ8N§Ó¹oß¾äääo¾ùfÚ´iµjÕòõõÕh47NKKËËËëСC£F®]»F½H*W®<cÆ tgÇrŸ>}zçÎ;väË}éÒ¥N:U«VíìÙ³:uªW¯ÞÅ‹Ë œÐ¾}û \¹r%((¨eË–wîÜ‘ÏÞyç–-[–ÜŸ Ø“7nÞ¼ùÍ›7³²²>üðÃåË—ûûûk4š³gÏ>ñÄK–,?~|›6m"""ÊÀ"„ðòòêÔ©Ó¦M›4Í–-[Ìf³ŸŸßܹs»víúÃ?téÒåìÙ³>>>:uúöÛo7lØÐ²eË;v<ûì³~~~¹¹¹ˆcåääܸqÃËË«R¥J999éééåïXã¤V«yFdaaatt´",,Ìáp¼÷Þ{ÇoÒ¤ /åôù矗jï¦{$•J¥P(Êìq2™ìORni0¼È‡ÅbQ(T¡+??³JŸŒ7®Ì²©Þ~ûíÂÂÂW_}µk×®£G†® Ñhþ(vÆ }ôÑþóŸôôt£ýøã}||¨ƒÜ† üýýÃÂÂ$µårùêÕ«…e¹4÷HÇŽûå—_&L˜°hÑ"®úQ3«’”™™9gΜŒŒ ÞÞÍÏÏZM+ ƒÁ€eÅÞ(û¼ì’¡R¥JÇŽÛ±cÇ´iÓŠŠŠÖ­[w/U*¯îCË}åÊ•‰'*•Ê ¸ B´¦âø™5kV·nÝH±V(;w®U«Ö¥K—^~ùå2«³—šššœœ¼jÕ*F6gΜN:õèÑãý÷ßçL[qûöíÙ³ggeeQEG mÞ¼¹zõêaaaM›6­XVŽ„üüübccCCC}}}³³³?ùä“ÐÐÐØØØŠ c$ôã?Âð*2›ÍŠø#"_j\\ÜÛo¿}ôèQ¥R9pà@úªråʱ±±½{÷~ µÄï—Ö¯_¿lÙ²+V<ýôÓ111ùùùôùš5kxZnNNΗ_~IGEEµoß>66¶aÆw½'5m$Åùï3îý(=š>}:-ÞyçúÐáp|ôÑGü²ƒR7ßäääï¿ÿþµ×^ã§“E­|}}!¼W­ZUîÙEEEÓ§OW«Õï½÷žËåâ/xþüù}ûöÝõW;vì¸|ù²äãGî߿ڴi³fÍ/EEE5nÜ866–:ò¥¦¦N˜0¡E‹ãÆ;v,ÅKÊÀ3qâÄÀÀ@*?xøðáéÓ§¿þúë#FŒØ»wo\\®üòË/,X˜˜¸eË–Q£F-Y²¤äÝÆŒóöÛoûúúÞ¯ô-S‘³páB«Õ<qâÄÚµk×®]{Ö¬YŸ}öYppðÛo¿½ÿþï¾û®ìwÀ:vì9pàÀöíÛ/_¾üÈ‘#gÏž-½îÂwÕõzýgŸ}6kÖ¬† .Z´è«¯¾ ¶Z­Ó B\¸paäÈ‘ …â™gžBv 88xÒ¤IuëÖ-ûÊÄ=ö؆ FŒ‘””Ù°aÃÈÈÈuëÖ)•JƒnÛ¶íôéÓVY±bÅþýûƒƒƒ˜™™ùî»ïânO?ý4! _yå•k×®Õ­[÷®4iRÍš5ƒƒƒccc§L™Ò°aÃwß}÷»ï¾ ÎËË{ûí·…3gÎÔëõË–-+ßZ‹-¦OŸUXX¸téÒçŸþé§Ÿ7nÜã?Ž·>wîܾ}û¨¥q«V­† ¶xñâ¡C‡Òr9rw‹ŒŒ¤EŸ0aB```­ZµæÌ™³fÍFCJhùêø&LXºt©‡‡ •N÷§Ÿ~Õ¶mÛ¾}û.^¼xذa­Zµ¢åNIIAgè’Ëýþûï?~ÅŠ„;xÈhùòå§OŸîÚµ«^¯ˆˆ8~üxÏž=#""ÒÒÒNœ8QcÈÈÈ8tèÐÉ“'ÃÃÃ'MšT¿~ý‹/öïßÿàÁƒ/¿ür·nÝ0È9sæ´mÛ¶mÛ¶ƒ^°`Á¨Q£.\øÅ_Ê£cÇŽ ˜3gÎK/½”иqã¿ëàáe=;vìxéÒ¥{wÑX,¥Rér¹œN§R©´ÙlÔ¾Þjµ’ílµZ©(YÙN§“êí¨Õjª_û×\(xs_½«­V«L&S©T6› OÑ “““•Je:uúõëwéÒ%uÜ#¡àÍ}µ@>|øž={®\¹B3ÆgF&“Åð»\.þ9f•Ïö}Í! Þü…F¿w]V•JÕ¤IjUK–l ºÞn·óß !ìv;=]¡PðêXv»Ýétâ­±j÷2c÷þ.(xs¿M¬iòЀãããI4†……‘;TA/âp8ìv»L&£™)9ø»ÎªÝn§*Ô÷>6¼¹ß—¢+•JšI¹\n·ÛÕjµËåºë€i`’uáµZÔ»wïÌÌÌ£GbŸc¹år9Ý\÷tÀrÓ,I\ôÿ“¨àÍ™3güüüî½à F£Ñ`¶q è0ô¾ü •0ͽ)Å$þ¯V¼Ñh4÷nòbò–48h¶ÿhÒç%Oè=úŸd#j‰´(逖(hr¹¼ÔŒ„%­\¹òìÙ³#FŒ¸uëÙeC|6øßÿsÀ’Y-Ç™ü£ÁcÀÿsKŸºë>–|(™„?Ÿ±2 ’Ѹ’o!¹@¡P€×üÏÁãËò¥J. ø®¡Ç?ÚŸÑÑÑ—/_2dÈ;wzõê%Y)¾ÜœóòË,ÒƒÁ”dMÃ-YÉóYú£ _f§õ®ûS²Eïq>Øqw‹/þꫯŒFãСC/)U P-ö*Í;—ÇÿfªS§Î»ï¾KNü'-Y²dÓ¦MF£qĈå’W䦊Ln‘#(_¯,Ÿøä“O>”3Iù¿ÿrªV­Zo§ŠF>>>ÿòpÓ}ˆ¹\^ññ‹2™ŒÜ£v»=''§G¼–¢|Gr¿ÄoäççÃíûo#ÄÇ?kÿ„ŒF#BËý€”¡-Ð?‚ƒÝ/»£?¬Vë?n5K¶6ÿÈÑjµ¿E%!DAA•®)_­Va³ÙÊ}$÷KeµÛí—.]*ß¶CåKÔÝ`0üãVðOˆ<œ………ÓKý U¯^]áçç÷@ öS æääüãVS©TJpÕÿE¬mß¾½oß¾n»ÏMnr“›Üô`Ï]kN§³\eÜä&7¹ÉM1y{{wîÜù7ñƒOåryÿþýÿ3²mÛ¶Êd2ò»\.¹\N_U*•Åb¡”8U].—Ãáp¹\t¹\^òññ 騱ãš5kâââàV&»˜Â't+úD&“ÑqB1Úív›Í¦ÓéœN'ýŠPó”.`³Ù´Z­Íf³Z­”@é”(@?W*•*•Šþk³Ùèuèz¥ `ßétÒMè·”AC¢Œ+úƒ†MŸ+ ///«Õš——GyøŠ~Nÿ¥œ‚öÓãÐ&“fLÿu8HR(ô[›Í¦ÑhhZè‡r¹ÜápÐÀ …V«µX,ô·«˜0Û¤gÉd2ÝÊd2Ñ iüv»Þ‚ÆF#Á !hT„4¥T z"^ÇétªT*JS£ÔÁb t+RPP‡‡ÇÍ›7Ífsaa!M2í…BA—áè†Ø{J¥’¦ë«R© ˜>¡×¡W£„ |‹E§)¥” £ÑH`[ÒV§šÞ”–˜^“D÷¤m&„Ðjµ*•ª¨¨ˆæ+N;þ+—Ëicã[Êk¡W¦ÝH;œòÿDqÁ7z.’h�¸€Ž ›îOÓW´KM&“R©¤]D¯@?·Ùljµš^‡®ÄZÐÀ( Çž(Š#ÍôÞg‡œ~ô76˜Ýn§Ü :#t7äâÐl( ›ÍF'…žŽ…Dì$ÆÑtét:³ÙŒ¡Ò¨âãã4hP6 Öáp ?ÌXû¯¡íEËIœ×étRø 'VVL´Ÿèü¯q8EEE?ýôÓÙ³goܸ9paÚ ´WˆA�&OG‹nEWÒ¦§s…ÓE9YàA4 G1;£¯t:\.·Z­œÑþ£SG™k|0ØëtBÞ¡‹žH§+77—ž 3ÏõÊ+¤é¥ÓB<b²·Å›RÅ9º?ø]`d ’”鬂 !<<<¼½½oß¾]TTD¬f†¦”nE“Oï þKgÕårY,ˆp¤4‚=Ñìq%ƒ³?§Óyûöm•Je0  ‹d ¦ƒ{ÐÔñ9·X,غà¡ô²´=DqP²l G@¡P@HÓÕj5¶m?š1,Ky@µÚè2¼¸Z­†Ãê@{ƒX¥‹ÁÓqÄh]8[·ÙlPÅèCF£T* ݇~ÖLrQ¥RÑ¡ ;Ó[@�Ð+`É$‡oDŸØl6ºŒvе‰žžH› keˆ†DV©TV«•†MŸcKÓ•¤Ìa׉âÄUÒPd‰‰a[â¤ßW¦íƒt²¹å -sl2¨ZP$é2J̆ˆ¥%6‘™™™™™Éµº?˜<µZm2™p¢ÀhÓÓ†Àmé8`xÄÈÒã£3Œ›Ó NAO§ŸpN$„pÕ«giÓF»e íKØ4œ @³ãSòtf •IÆÐ·¤,]�u b†ž"—ËéEÀeˆys«ÂÀÂa¦$†H/BO¡Pèõú*UªdeeÑLBŸ…‰.ŒãMÜŠsmQœŽw¡7…^B“�Ûˆ[x¤®‚±BFb¹qä®ó™t-:‚™ÛÓ`ëØ’M ¢ÚÝn‡˜‘¨/$Þènô7ñM ‡ÃA% ð[tR°-1#ìjºûû®á†6_ntÒ&„؃æO Z~X’uБ@Å‚F%“É<<<ø!çÈiÁJ¯YÈ.ùøZCXrµ f ­>h¹ÅuÜò†–”GXÊ0~9—ç …»n8¢3Fû˜v d±BÚ.ÄþhP Á2½9—á|´NÎtBèWØ:w D÷‡êM:tU™LæÒhL³f)Μ±ôè¡Þ³‡ ]¸HRrAˆ}ûÀ‚ǃ|b4Ä)à„a!„Ðh4ôRÄàø±Ç* Ôæ!©ƒqBLBÇ䲎šç;wîF¬éòÜwJã`¦„JçÎ%š1¸˜À á¨¤Õj5éž4<HHw0 8ÁHlCŠ0 éK…DGùî!ÄäÃÃ¥‘ä,Ð ‰ÏZ,Úcô^´‘h‰!Aa©`™¨à]À§‚¦Ê8Éiò(`óã|aíèðPn"Ó^âÛ_„°#iT´ÇøPá„äÅEq ÀÁ‚…VAãá¥}è¸%q. üqA‹ˆ÷…s…o !„^¯'ò®’–wÏÀ›Âyš[ä”'á$CI¤ÿjµÚ’T.—kµZr£ÑV¦c!;@²!¸)ÆJ¡¨c8TŽ FßvPX¨²$T|"#L¡PЦT«Õ•‡""àöÚµ sæx f³ÙLÓ¦ÙívýþýÄQâŒk¯4Tø”¸‡Wò�ø÷ØÀ'ƒ¹¢¡B[¤ŸP>gŒ�Œ•DCåa62qॄ¿Îh4Ò @[§"TÄ4ù°ó f &!“(^ <qî$¤E/,,$n¨Ñhàv£¨¡Ãáðôô´X,2™Ìh4bnU*•———··÷­[·L&0ét:îCƒJÎã"ˆFH¡´{±i5�ÀÎÄéàê9\£ØÆÔÁa€ícª¹žx€„$wzCcC$R­VÓúân´-¡dЛâAøŠ¶I>³ÙL3@Ò‹<½$6H\ÁV&{¯ 3Û‰‚¬Ä¤ÐÐÑ>„¦BC2›Í4ópœÂA*Š«¥Áær¹¨."Wþèbès$oÀ(  @‡ÓjµåeèÈÝòÆ>@­£ÿR¦$v­§§g5t:¹à¡íBŽ)ø¸¿›{ðx(•¤?pPyd +b0kï!VyCî#bˆ !M›š ÐÏšEìIÿî»®V­,ÁÁ0àŽGaGH×傜<Î$V¹¯±î‡Aw {b0t —Ä< Íy ¾¿Û‚‹ e%)*�9âó$Ñqú9ð‹0eˆ]ÒôÒSˆAo÷'&‹iäf-¥Ùl.**"©yY§N6mÚøúúÛBPL¦žF£AäŒÆjµRx�Ñ5xãÞE‹ÅBÜœW,åKC» ê?6d¦‘t2pOL2À s"nÁ½jô.\ô6\M V5­j’J˜;WiVŠçgЦF£ÑétxSSù‘ä‡# h( E{žv žf€nk0rrrÀa¸«7—à•Hâ>›û*ãë9¥cî+ª`ð–bíÉ€p8ÙÙÙ'´]$Ê `C`1ÄpiûBhëÁ®ŒÎο$ŒA ÿ—~Ƚóv»Ýh Õ~õ•¸y“ø…\.ׯXá 2¿ð‚Z­¦ÃÉÙwÂjÁ'ˆBáE¸NͽÏ$œóÐ1ç;¸'î�C2ǘ{‡ ÕDq-g„HðH*¼0Â` ÀR{•ýž`F€%AEö8;WÆùš�"Ac³Ù|ýúõóçÏSÍ Ti,)D¹iŽ˜ÅÌigâõÁ¸¹îEÛ†‡hÿkµZ„ë`ñ ÜEûŸû0q„Ç1±ðUb{ӨǢ h�oœT’è#Ç!D’›1Ⱦ¡kèž¡¹¢×Á¶„øw¹\•+W®S§ <dÂÁ~8°Þ€>å’’ø†J¥¢gÀ6F,–ë‹Ø]’mOÖø p¤x')éPu;ÖÊšÀ»±l´SÁ"i]éHAÍ„íµ{:™*•Êl6Ã'VKÁ�`:a 6Nb8ëï(—Ëɧ]e2™ _Ãü#æˆa˜´}Õ¹¹¶¼<[£FêK—t: T§NgkÙÒã»ï‡«ç™r•p/"‡ŠÁÉŸ;ªñƒYÃ÷±ÄÃ<ˆÏsæŽG%ÿpL*BJ\œ“mJþ(b…쎴’C�DÏVì�|¡ri f•ã¾h›‘Öø2 ‰dØ:SÈå ­Ás�»¹N«@Æ <!Æ›€³-D‰xȃáÂÒ(Ä´ ôHÌ~C¥RIá"¼ 8,牗Å÷œWÜbC°„,$—ËE (IÐÏ$®üV£Ñxzz\»v-++ ßïC«OâŠ/¼XP[¹õ I}ÁHðj|¶Óé$oAüi#•Lf€³<+Urn+§Ü<lâ÷=t%P(xÒÀÀn_!£°`ð :�BšÜh8Ñh4îL¬“Ø<!ðñ J>„di‡‘Ç482Y)ˆŽ£°PãlÖÌÖ«—Á`°X,ÖÚµóßßsäHuVzäÄß6=Ì|:ºôDü„c»pC¬›Û œ¿”ä8Dd–IŽ.¤Z­–ü9ú*?‚¤ÀB5æZØk«Õj0hExÀŸ"F�8€½B¿æÎn‹Àzƒ ãN$<�ÄÌf3ö8&Ç\pµ]:¦¹"Ž,™yô¢Ÿ ›_âw>%¨5$QJâ×iu;Á“Ä– æN7ö%hIˆô�Ú›#5´Z-‡ãpÑÔ2‡µ0=zôð÷÷‡©­×ëá2ÍËËËÈÈàîen_Bwáqba•Àšiži&‘žÁ_Âb± j®òrÿ÷ÒÓ>ÁÊþIÃx·•SÖè>°9ˆ‰@½¤ž}(˜PÐ$YiHFAQYÚ[”È€$1°oÄð¦Ð³Èè{aì~D°¡±z-[V4v¬Q©T§¥™Ÿ{Îköl œrð‡íb×Ò±'4 9D›Èš¡ë%@O0)žÝl‚.&—4p±°Š¸¿…œ!ñ�B—ón èÆ ¬(D\¡~ò6q<ë–ÏïØÆcݘI“ÉDs¯)ÔyHGxð à Ž!¤Û’¤„„@ €ËodÁìàŽ)ŠÙ (Ü€ˆ®Á'FÛŒ´žc ë¼8WPè]è�²à8 ¯»šƧ ÃŽæ8Ü8ÆÃú§ O™‹R§Ó™œœœžžž››‹Ï)3 'û &8GW‡ÍLwæxk:ÜÈæ±IZ_@ïh?ÐãPXîQÀãÀpHûıRÆ-r*ЉÃ#Ÿp©A‰¶X,¤\#H ‹•ï9Út¨¸Â·ÂòÜMDÇU­Vón’à `¾N€ãð[ññð·âN*ÀÁm6›êƒ¬#F˜}Tûå—Š¬,Ó÷y¢8ÆÀŸC·ÒjµÄ)xj:Ï“À Á†à¡ÉÁ¹%“ÒŽWF „”J•JE ³a6§‹ á\žO à\<à˜¤qs{~3h”° §‘ajC G(V™¶‡`5±'‘üO¦F7ï€û"iÁ·žEd$¦fؘ1P“ƒÚ4üÕõCÈq™Í W’ŸŸŸ——×;w I³á¸Qœ §öT4:ŒX/ºŒ< <kJâ`¤™)(((,,ä6 4BœDž+†ô&Ä_y‘‚Š XMÚ x}u8c˜ÄæþLWÃ6æPIœž ô¶[ä”ñÂ`‚<qŒG†yH\·Ìã™_¤Ëpv‰%—ÈQ"mœp¾Ñ)ÜBdú–PCØg䇩Ã@�|©î‹Ëå’¹\šuë„23ÓQ¬xò>â<G\I?€`q›Ê>¹Íf3)È茂ÁpA‚Op£Õ!l.ž!g:]i6›|#ÓD"ª9¾îX¢P0±”:Žà探^hÇ($žÇH3�BL‹çBò:Äy¹®³sH ÇG ¡Å;—ôdpPL‘§‚òDN8B%Ù'Ü ,X^0ñanòÍÌ5tFCÔã¦È¸zGR«Õ]»vmܸñ–-[Î;ÇÃ{ÜÁ+)–!)ú�D5Š8c¯ÉÓ}$Þcž¾ V±Š &”`ð¸™[ÏôÊjµÚh4bWÀ•TrÂjr=À<’CtºyéŠq�!g¯[ä”[¶"h�� �IDATjgâ´¢H&€Î u@{´sç/Ц}L¦�Űî ²X,d¿#ó”6 ÿY«ÀgKª·áΈåÂD@>eü×z°Zí·n9‹ý‚eí¡N ß Q<Ý <铵kÁÕÀmœvžmƒ„ÀÕìv»ÑhN ~jÝ–§¬ÂÅo(P$a¬ÜYG J4…hiŸD3@ÓÂA‰¼¤÷IÒ„Ó¨xÁÈÃ9ŒË'„I€{äö?m?Tœƒ�àz1‡ªfSJ¯¯P(ˆ!’ Ë“H�çÅË¢n•\Âb‘Ÿ,˜�D;9ÀÁiÕGBBBzzú;whÛ#÷�Áv’©�ãHêûA @õ÷ ¨HZî …&±J±UlBð}8 éŒch ?†ðÕÃVÛÒŔ݉ó¨ÑhàúáC`˜$7÷ƒÂþçþ²ã¡ ‘FR¾-…Ü"GÀ³U‹'lõ¥ F=`Óà8’ʆ0kp aãC­æ™Ì¼ævÃ𘠔 Ø+ŽºÊ›‚ÕYx½8Ì{š;ߥzÝV£ÑPü“޳ˆè`¶¤"8lˆgî OW`¡éÓq¢ç‚kЩ†È'w–>ÀA´\1‡-Kü—gËc‡ðÂE<ŠÃ-žÀ„Ò^°«ù€’[‚•Wëä¹bPøœpÓ›‡ÃÒ ãy.´xäÅAœŒ¥‰¸N Ü‚$oPïžj\€X:|M’ÀªÍf»zõjZZ’o�ùƒëó�”6„ŒQ˜#ØÿüDp˜LRý'!ç&,-ŸIx&xxC,ç„R‰¥¨ÕËE)<™`XVz;Hz?((’2Ü[î9åï^ãUùx"ç ³YG«%„e\m6‡ÃqT£Y¯ÑH´ND€¸·aÁ 1ñšÍà¹ZpG…I˜¥øqè-2®QX(ª\ƒw 솗sæþ Ö“fˆ:žs÷ /cLü‘$ÁiV…6 §<M V_€C y)À|%%¿8f¬«ô!w4q(0wŽîƒ{u¸ùÓ™C‚ÕPdžçŸrÏÏßäRäÛóÅqÐ{°^и¹ˆå•ý��»˜—nCÒ/nDìØßß_¡PjK°’—´”¨—#‘7(Èë陉ÓAïb2™h](U€—‡k‘£àJ ÀD™z½Þb±LâyÖÐý‘SÌG^ˆ{ÃjµÂ³Mž[>É<¾ËMÞ’’ (Ì÷å¨WIÔ“;½¹ñ„8“(®+Ïãmd »­œŠ¬:mÁvNçkrù;FcS›Í%ÄJ…╪º!Nç–‚ ¸à�âz1"Æ<‚*)OI\€TŽ9á `pëq6„Ò¿8]�³rÿÇAüp6âÒȰáaU>‡hš€ä5~%fº-Ç&݈Uîtâtx­00V>ÂÿVX`ʼ#ë…P¼8&ÌM°Hº†*êûÒhiZàÙ©ØK\p"8 Ÿ*Ç;aÛÐ:Rb q^¬¯`÷¸ŽÏ¡Œ¤5ÓÎÁÌð„A1’@ïà¦ÛX¯×?óÌ3Õ«Wÿúë¯oܸÁ ¹’¼![™r<ÁZ/xÃU(0S^¦BÐ)U¡uI±(»ÝNaÁïix$BH?ãþ(”ÃÒR’ÃmDÌ3)y¤ªT*OOÏüü|8®)bÊÛðU൯°!én4` „+ž—”Æ’AXÒWT) •yðŒç6¸ENy"¤%ž IšˆÅåjl2Íq:zz^P*ívûëË6£ñ½Þiµò‚ÜÏc–[²P-¹aKÙ9Ð(Á‹±çJº€$P`¸ó„tB…|ñûj¸¼ìÏ¡Œ jPM)uw nƒ‹Q„+Pµ¤J’{ˆêŸ`‘\AÆr 03Q×ø0y„™äâÀb! Fþw”ŸB[ä¨ó”½‚b+ŠËÄ!=–”ÇùqÎù~›æeo(lΫÁФgir®MÌ]£ÑØçKJžÈ±¼’}EK #˜ÏªÅb9wî\ZZZNNf�pa „€TˆîI&)æh(À{½Àë…âi¼wð�_ð?W%‘ÕDxIAhÚuˆ«kµZÊy gŠ$ ?ïP.1 ÔWåÖ<=E«ÕbÆ$uCpÀ¡ ²&ÜõÇs§$¼Kü¾ø¹ËzV ¤~¨xLXáçrÕ‘ÉFkµµÚª~~F£ñãÂB»ÓÙ·8éDRï Æ2aBB”Ìþƒ{_É{|a/‚ïÐ.D 7êቿÏÙD©„Ïã¤ðB¸ÇŒw÷áJG‚Rn ÒZ¹ ŽßåSXZ¨Ê[Âàs šÀXa[`žyÆ»º.±.ðBp}™6+ðdCîE‘,¯#À±´ÊGˆÕ!â[°Þ`mp¤,ÝœHàSÜk¯Ä9þåE h3VšãµxD¿&fÉjµž;wŒÉöðÛÀšDЈ|P'ã|¢”ºÃ!I?Á¡€ÙÊu ¹\®ÓéÈæ 9<I…7¦CG"Q¢`æŠ!ÐW'‚W­åíyH*“ÉKr£âx9ñûF(üÃ+mck“•^‡âq;xÔá3ç,ŽËw¿œ !u‰ 3¼LU…h"D¬·w»6mžzê© .ìÛ·ï‡#» àËâX/æX¹reRüF#AE¹¹£×ëýüü„”ÄNz4ç,¼j,üÝã+XaÄ·Á\ Hò†žü„—<P*q\©V1Üú¨ýŽ#ø�~‰ 18/,i\Æ»¹ €‡$Pà*=¬–”Ëĉ¥ÑãÀËÄñšÄ¼6Ð"H÷s‘WFj!ïD‡&‹Èƒ…8ù˜O  ÷G¬EÎð„(GFëDnôxKÄá%5Fkô 1ɵlZ>’Ä(¤ù‡>¼Gƒ¯¯¯¿¿¿‡‡GAAüÕN§377V 1\�LDqÏ1ƒÁ@–«¤-D#|D4’:uê4oÞüÔ©S©©©PªxÊÇÁ}Ê_“ìKoooïqp¬Ô`å¹Â7�ðO¸á™Î”<À›¸ÃS†ùYæi³\°}I” ^2L@’›á9å&uÁ£ÐPƒ‚‚úöíÛ©S§F¥§§çååÉ„+äÁ�'Òëõ5jÔËå7oÞ$ ×…½½½kÕª•——wýúuJo†^Cþ8Çy4eº!Šs=”Çóù‘ãnúnô3ö1Й’Êi“H2àÐiFü>‡_Ræ`tI5OÎLyáE¨¥<yVÒSÒmŒÃüø ‡íHƒñððBPhþ8$ÿ£”ǃ5Ð(EŒ�€¤¢ `o¼–3Ö…^cÉxZ;¤/ãó 3K£Ñ¨Tªüü|øš ð¬C2=ùü8Ëç?¡Ðl_žÈ ½ Ø³ÂÃÃ:®úùùÕ©S'+++##ƒ£Ú<==FcAAŽŸ¤§P¢dÀp‰_�ž«Ñh<<<°yxÁ1¾- îAÈoÁ èaÞÈH¢%C@E⑆âÅ̼†…Ñh$,à×’*;à'ðò"CðšòŠ®ÐŠàgCž›ÁU$Y#0U{ãÝ"§œ¨%Ì‹ãÒr…Èr:ÕIIIUªT¹xñbVVVK»=¾8‚»zL&ÓÍ›7õz=*yÛ*H“•••ŸŸo±X²³³ åY–t°9†4,Jèã.)è}‚¥­qqž;†ePÐHÑãÿ’8rñû,}Žƒk‚wã~'D›ÒÍËŽÁéÇYª$vE?á•Wà£Pr(ÂQôʼu ÏÚñ÷÷§¨ Z8sl.ïP A÷‰â¢ýð}ÁF!WnN!ÏŸtg(ÅÜ^áöoÐB•Áh;¡,GôNeof ¯|nØ]ؤI�©%ŠKäa‡À…‡ V«ÕjµF¯×CÿðññQ(gÏž-**¢°•\óöööññÉÏÏÏÍÍEML¾Ç�¿æpå¡!DBB•+WHVq¨7ÊjµZooïGy$'''!!AÒ¿ŽØ7êÂ!šˆé•ô$ä˜4ØŽÜf… E¨^’€[”*K+}ŽVœŽ9O´²ÙlEEEz½Íœ¸“œûñxÞÇ ¢û—$¼ê9åŒ à y6Éu¹ü„L6ûöí·7o>qâDfff“7>((èá1Èl楨h-³²²ŠŠŠxEznžß¹s‡äµîg‚E\’{ÒYøY,”»³àЀÖÌ}2ˆèò†ž’:ŒÜuÀï ã†×ÅSãžt¤ÈààÑèxÓ@xê?΢Ðm¡ðh¡ÆÜæãÞFùûûggg£4'÷ò¡@'¶¤#–*9¯# Ã�q‡j¼·4KЋðúͨ‚#Jt(‡‘!éðo9ˆ‹~ XÚˆað¸^°žÍ¼À>¯†ý@U޼¼¼|||ÈÈ W­¥7ÒÅØwÖétµjÕÒëõ&“IbÚbÆ4V«5Ä»y¾·›ÍfsIÛˆÏ0½Knnnnn.O¢`./ÕÌ ^ð ÷9<M55xå'ޱæ~WøŸa�¡-:GÏó2 ’Þó¼Z Âu°`(Ë/"àvôPRÈxSjw,§¢€Öx⿇C¸\G »ËõjZZÕ7Ç™lŽVký}z ×,¸Ï;óÀ#/œGc3ñ]Â3xG�¢Ð™wú‘„÷%¹,‚õ…äÞˆ÷•â‘pˆ ð2 †X!àg(ƒ ç;Ø7Šmcô!ù@x¾=±”|æ‘aúW 9 ARÚŽ˜ø¥K—nܸA]SaÑ{aÚ ¬u4_ÁZQõŽ„ýiRè2^Ò¡ÁóÏIú™&XïsØŽx×c`Åò­Å'I‰~ž¥í ñÒjħ$… ¸Ó’Þ×ÇÇÇÇÇÇÛÛ;''‡¬1¹×ÈÕ}ˆf› ‰êt:NW£F;wîPÃ1I¡)•JÕ¬Y³6mÚ\ºtéèÑ£EEE÷%~_ÿ’’£ËðÔ¶9%%EÒZw¯Içpp3 ˜˜a€ßx…M^·:v ¹Û–7|’dmƒx”jIM¸ûàäZmZ*© Ê/Ô-rþË”ÁF9s‡$ðb½É$d²êN§V!D ™¬@&S»\¿GËyf%ò‡ ;€ÎK<žÌ‹1“µÁSi£î$<Ýty!d€ñ‘åN;ñvô§âŸÃl¢öÆTFŒg9@�KJc!DìÌápP5^\Db¿£ �‡-@cE"( &®9’+ 6 ²ŽPx˜×c†R‰“ Ñb6›/^¼Ècû<Ç:>ÔCœp0,psQTﲄ·N§£™Ç±§R H¡ç5Œi³¡E—’h? ƒôvf³™d[¤nðž4F@g B¶¤”'4�8N“È-…BáëëëççÇ•¨(­`=“È›JSa¶Ùòzö´)š;rrr´Z­§§gÕªU-KQQ<~èõþä“O>ñÄÇOMM•„Ê I pޤÛ,?M ÖQEâ ¬ê%ïÆTÒŸÌAwPzøÞ’ˆOB¼’4ÿœ}\ÂìãЮŸq7Ly,ÜM§Üºór*D,GºžÀ“ T*[xxØív:?„¬çNs:Ã9À!dÈVáõ:¹jÆ¡hhäGŽrî%@Â|,eƒCÁ) `Ô‹ß/0À¹ò8×(yÒ‰rÛH6žA"¬&‘¤‡;“åÄ;ªgA7Ž"§ ç&¤òD  ¸§¥Ì€Ç€ƸëþI^’–€—ô§ÿâEˆC!°-Ú€ÂÀ+ord<?\j°ƒH3›ÍäŽãi@Õ �K‰«•ý+ rj<ýÈÇǧJ•*TJ•T4RŸyhÇ××·J•*z½Þétfeeeuëf«ZU˜ÍY={Vþá§Ói0´Zm@@À­[·¨¹„„Åb9yòdQQѹsç233aœ•¬÷ƒ@#‡aÇ;PÊÅw×íx-Tû‡âÛB°þ~ÈôD†W¡xà Z^ ÿ…B ¥d òí�^òÝÂ-Z8!h ‚4¥¿ ‰*º¸ENùˆp4^šˆÎ›üˆrø,És;{—$*J mñBë@¾òÌ<‚[ý<Û‹ûjx56Qœ*I8'•‡«B<çœ.à6¼ "(ÜC%AEs· ¯k‹\‘’nðGC•ƒ‰LIâ´L¨-XOØ—ðÿ�öÃC%˜¤ò¤*p|0o �.�Ï*üÔ Ç)úÁ­p¸æ!n¹kx*ßÂr@A¦S];LRñ%ÜœâÛ-X!A�üüüÈÊ$-Ц¦ÅËË«víÚF£1  ¨¨(???«W/™‡G½M›,ËÍÞ½ ^~Y¹y3G«Õúúúò tç„„„äää‚‚Ä¥¸Èáú>‚ÿØHšÁs\$¥˜à£æHÐZ'Ë£YôJTÍw�Ü:áÀ6hBî퇋|¼&Ú4ÐAà©r¼€…¤v”E¬¬¯¯¯··w^^^yõ/pwýï©æÂ{ÈÛÛ; ÀÛÛ›­:è¼Ð'J}�êƒìNžYÂA&’@(W¨Q÷E’†Š%Uî§â;8V¹H°Ìv˜SÿÏÞ»ÇI~–eÞOUWWWuOÏL&“0!ƒJ‚¨/A@P‘]+âŠ,"¬DÅed1о GQ\Ž" È"Èk|QAvW‘3rV YÃ)‡!sžLÏôtwuuWWÕûÇ•þæÛOåï·ý£û|&}¨úÕï÷<Ï}ß×}Ý×e“M|EQó´‘}Ú+%4î*ádœ gWTæÂº",›cí¯Îõrþr ¹tð>LY}L>ܧü‚€]äo+QÞ|‡ú’ˆè„€PêNŸ©78N“Z[–"æÞúÝ<s³Á¸®©ùD8y»ªä²cÒ ÿÐ’¬ùÑÞ½{/»ì²ýû÷<xðòË/ŸŸŸ?ôèG÷KÞ÷¾|Þ½ïyOouõÔ“Ÿ¼±±±²²²ºº:33Óíva-çŽ-,,œ8q"´fž;è«Ùçì5 ¤SìÂÉ`Ö“›E¢™,rÛ[uÙ¥‚œe 6WÙc ¾6W¢Að °«ç[€µ²µJ´ù8"îÝ»÷àÁƒ»wïÞ¡ls¼ÉQåD>‹Œ» g¹°°|!ù~‘Õ˜5üAl-…i˜´¶OÖÖ¤l¨í ˆ.d‹‘*¦™MÆØº†¶ùŽÛþ•!XÙªÛû *‰� ]I0»n‰FºSü(”§Š~]ÙK{Š"{Þy.¡‚!DÇ!ËKW˜!Ž&æ#ð¦ü!_ r*JȽë¢A}ýX쇌ÕÐ_Áq¬NO &jÙ„®U2}ë~AD €|„ÙÙY¸iõ‘õ?åÖ[·°Ðêvg?ò‘ÎË^Ö(ågúýÿýØÇ¶KyÆ[Þ²¶±1ºÃዾýÛGŸøÄÙŸú©•Ç?~Ï'>‘«ŸŸÚ& r …Œµf‘ð¤ªþ?ë¶NfèJz&ù‡×|NwlÓIßÈ£šdE E]Èi0a£eÙ Fž‡Hàñô›UKŠü/ |R<<yrii©×ëm×hÎNÈ)~öÈ ³š766uxü´CП¨È3¶Ñõ¨Ž;¤N°òÝñæ\ö`…_!Ñ_¤ç‚§Cg´Ïµ|œÔmNí½oý€–Lϱe"Ûy…€ûaR Â0g8Æ ¬2··2Ç´?fÀò€`Åt†Jm»—Œþñ¸Aí-†héb#k[Q3 ­“'‘›çáŽÙ6Ôµ,H®t¹Ì¼@‡?W›æÊ°mæ1˜Ð½(Ê+—&p¹²)–s0׆YÈ„Ýn×?a„0}ï³gþú¯_´÷K_j~ìcÓ§çΞýÏïyÏÅ+>ô3?sÇç?ÓÊʺóÎÖh´þã?>/üô§ÇSSý~¿Ûí†Ã’‡’ëÏT2Å̰?L 6ôÇÎ Çö4'¾çÛ(6gåV°ðàÙÇP'=]/TÛ½Û×0²¹æ yæºÍ®õC@bJ´l¿V|T’fr $$ÜiÞ 9ÛÙÈq¯Ø§vÙªF�ð n½z'9vQâzÜMQ“h­ÂbÔÞ§¹‡L+Ï솒+?•"¥5Ød°r¨ôr°#@‡…‡ ¢H*çék$~]Zø‡®µÑ¡â‰Ódîœ#¦¹û™("…Oðf{›ãs)ˆbJ:+¥ê]·â’KÖžö´F)Sï~÷øÌ7ð"vå.<€)S0¯«´õà50X$;–ªÓé˜oBù¸XOv:ÐÁ+üÇݦCàžØê˜¢qÕ £$æewìÙ³çâ‹/Þwô襗]vñ‹_\øÀÁ/üBëƒ?ô¡Í›oþÑo}ëƒßó=—¯¯?ì}ï[m6O=á §úý Þõ®•™™¨D§?4??úôé*[ò|þ=Î Y‰ÀÌA¦Á·Tá6ë¬DZ}—ÌŽÁBÂS/e«"jå SÈ„˜”rdÖµ¯¿ms¹LeÏ:G¬ØÛe«-ÐNÈÙ6`¬$yËÁm9|;ÎÜÜÜÂÂBefem1ÆGŒÛ&ɪ$„=Ðc”ƒÊÚ¬•T` :þU°žAyP)§Ãfa’ýYŸ”uìj2 O`;UÐãî,5ÃÇ�´{]¶²U Ñîp)›lyPD ™íeÓhŽZpïÞ½Ngaa!•™³$ž[4X§¦úÿ÷ÿ=óö·§¦ú/~ñܯÿ:XõX @Ä9úöArh­*­ê¶[9›(Kß{4-//¯¬¬xâç V¨ãVpÍXö¥ã277×ëõÐçŽèÀÞ½{ï{ßû^tË-ûßüæ?üÃÆùóÓ¯yÍú³ž5|æ3[§OßçMoºúå/æ[ÞrùüüôÚÚñ}û.þË¿,› Á®]»ò\R-e÷E¥Â¥mÕÎ$¸E:Ò—ýGL`)Rs/r ñý$Já8e‚rBÖú›î¨œ€ZªÃ+œ-àŠöЂ<¸S$GÇ$yÖvBΖBÇ+€…n– *²ðÈ»z Ïçl¶+à¯&|LÉ’­X.“Æ‘ˆ¢»©�bJNÿü ýÞ|ßtþ*¹|•6N2râ‹y:©&.•igX¡†°7À•ƒ7†Ã}WõMWÃáØ "0;2 ÅiË%± ·sssxÄ#æææ>ûÙÏBÏ¥e,q4Í8°øš×ÌýöoOŸ=; ÚoxÃÒŸüIçê«›++DýÜpæ¢8 9ʦèɼXÓ3æ2I½ó*µûƒ«óxC=7 ”kàFAN›™™ÉÛe1ýâ‹/¾ä’K ;ìÚµknnî‚ .¸Ï}îómßöm]wÝô_ÿõÊÃ6õÑ6o¼qpÅëÓ_ܦϟÿ¯þ¯K/½ü=ïù…ÇýøG5`jjjyy9^æ`“–ÅzÜ¥?Ä´‘<�@õ@Iz‘‚Gö¬«¼‚å•ÞRÎn€5¶‰ÝTÁ96™FBC$´ÆPöžsÃ0”G"…íº§¦˜HãÎ�×›ó‚vWVuf-xñmœÝ 9ÅÉ<–<WåŒil˜‘I+¢’.¯ºÜÌÖ2;€â#?ºý†8²Ù’|qâTz2@:Ð]`~ç‘HàÃÚÎù@3©“?cÅèuéãrÞkÝ*pô9óA<5Y䢯¢ H>[9§@N W;a4îaÂO^ð[ßúV»Ýîõz\€¥Éî>µ<÷+¿2ûªW5NŸžîvÛívïÈ‘é׿~ð›¿Ùý³?k<Y1#|¬WÎ4fä™Y¤æ`†¿¢ùÒç'êØQ;'ffEÄå5¦a¤”ckzzºÛíBÁÈ+ÌÎÎv:üt÷îÝ­VkÏž=)ôçç烉]pÁÓÓÓ…ç›Å£)àRÊ%û÷?çoþæ>oûÇ_õª=÷¾÷p8<þüñãÇ1Uët:\pA¿ßï÷û‰vˆòQ²RÎc¼G*> MDž,?hå!ÊnS„²�*¯O#n‰—ÚU=‘),�Þ¨*­òË[ó0ƒ»¿øÂÁ1ÜRŧ¼”éï°~vBζ}^¯Žl#?˜äÔÏÞbÃV3žF„¨Žàj*ÅÎÓÌÐÍPýÉ ,òhæÛÝ`$Õâ v[+ï’dÜH´Í�+ì[Z}.ümÕ\¶z蚯¶IΞoÒ‡·A˜§Y­+Ð�ˆJ¢P°ãQ.ছnŠzM‘}Ù”û%EìÛW–—GËË­Møqcccª×ôzý]»:GšŸ’²TÄe1p.3SIÉ8pàÀ›o¾ùìÙ³ÝV«•:�JKE‡K\¡Èö|I‘$~±ÜàáxJ¡‰ô²©—¨Ön·÷íÛwùå—ßï~÷{ä©S—>ýé­÷¼g¼oßèßÿûö?ýSÿáoÝ|ó`×®æ½ïý¯þðî}lã‚ >ýéOß°k×ÚÚÚÊÊÊòòr«ÕZYYév»ËËËÇ?wîNnù\û÷OŸ6a95{I°õœê¡,•g½KÂR͈ÌòûÜ:rAöïËJs(• ÒïI+ÓtïŽ T uX ÌèCÓY„ÿiÒ<!Ú§uÇwBÎöS¥Y…4º©-\V»ýðÇý%l.“VÉa§�� �IDAT,=b”ßÖËiÏîÝ»wuuuii ¬ §�‡;m›²9ž|6#ATòŽU•ÝÅúi½ ’J`htÀøP•j+vf¬ôÿMoóø rP,63Ò/¹ ;¬ÐBõ™èˆÉP¦I*7¶êA¸Å!hÁ“ ç\gç«_•Òÿßiÿꯞ;w®ÕjµfgW~û·gÞò–ÑW¾²¡º³šcõ ÉUىÔ¢™á!OŠ˜ûÎä)Ù2?v²ñ Lîœì€0Ž©à{iÞ°`â+“S,…øùóç¿óäÉÝÏ}îžç>·80üéŸn}ðƒ³×]×<yòÄã¿çâ‹öÇ|ëhtë¾}‹‹‹§WWQ4^©uDKsëÒŽ¢’°8¬- ªÚE×ì‰|L8‡ÃH\?~Ü‚Ö.ºríëPG'f²uJ{Òà0ÁƒŒ 3_ç£Èó˜«FÅÉ^«L+œ1SHí0Öþ­ÐBOrVˆã:g´ñœ ½&Mq[ԯߗí éù–v»ý€<àIOzÒ¿øÅO|âñ¶ª�\ƒ*ŠN4²()›kíjò?x½q¶¼ ¦¹x  ,b»ÆÉyÒJY’¸hÁ|"båF„4—‰´Žtp‘=”LJl5YÕ â¿ykÃ\•„ª077×l6û×_?óÊW®þÙŸÍþÆol4›½×¿¾sõÕåÌ9 ÷Q`9S¦ÄYÇüБ#GNœ8±´´äÅÃÑlÌ“‡N‚Ì, ¨©­_hÈg$ÚÁKæ83£šš»lz%r;vláÌ™Ó_ÿúðÝïÞýùÏ·_ýêÒï7××K)÷ºõÖæúúÿáîµÛ?þoø4´,AR±œãçÎcˆŠAK“0Q%9ȃKúDÄ€™:ùz ð8œ= &ÄÊ«e­"ÎäAlHö–À—®¾y³•k{E$±`èº5mÉMGORþvBÎv~±ÜK¬‹ž)3w¥âA‚ç2ø]YÇ3X““ˆš×R¸¹¤¥¥¥›nºéèÑ£`M˜]PWšö$Ô‰(e.ºè¢o}ë[gÏž5’àù>¬ä¬ùAç!YºZüÊø!Í0V|eÈVñ8™;Áp¸©2€±uLî<Ô(`åŽ+|:N‘2¦Gªh¢ ¶´î:°Ž}ík×^ð‚ÑÔÔô‹_¼qò$ñ1.f˜rôTý$"®Ir  Âg‘ÙZ~!i¾i™^ê÷ûN'zhi“0·ˆFjêžJh²þúúúÜÜœ%-ò¼––––——oššºìï\}ÿû[»v5ùÈÑhtúô饥¥µ~c8üÑ/9§æÂ¾}¬XzŠ< Œ-Dë<†KegÇ`“—¯ÓÜåðúÒÞÏú?wîÜÒÒRÞ4+*]Üd,biø{/SD:ï± ¼ý–ˆ”+©çxú ÉeBòÙS$ØPà"-75©4¿r¶í˹�ˆSu=>³K«žª©XäMHcÈÃL—ÞƒÁàöÛo?vìX¯×Ë)€!ÚÉàf–3á¨JöÔívõ¨G}Ï÷|Ï>ðë®»ÎxޱD–»;´E¾ñæÐ&GMˆ'‚J£A穎PuOÑ‹`ÈÆæ%œ¹àQ¶ª«2> ©Å: ÔæðF&Ψ)÷$Ÿ¥uèPùÀ½ÞøðaÞ=gð#NÕUÙü4òFé{3>bŸ$#ŸG…!b8ÔÜ'Ã{´†#ܵ”„ ’XdU­;ÎÇ/½ôkW]uÿûßÿ~÷»ßƒô ~¿ÿ|àÆo\XX 1ÀM‚ÕÜ”$‡j<55Õëõâ€`M¼²i#DpâÜäþŠèÕ™ [êV_‘7=6+š´ÂOy"0â íVWEJEdfÊQWü¬¦µìiâ*™Œª™j-Ͼr¶ X«õ½DxäUj 5³êj’±šÓe©.–)œýØ31§ªoe뼤§U¼7¨¨Ö××9Òl6x£²U{䊭’"‰ó'ôb±}‹»¬î:8[÷‰lé0*'éEÒR.>¨6Üû)šTe¢µ ½Õ½ß"ã#õ¤‡h€úðkþë¿6ƒF«­0RêQÌôi·­Òº¶l~E0cY¿"½o¼ns1ËËËà?h][)Õ3"y"9î±ÚäNV™Áùóço¹å–~¿ï{ß{iiéöÛo?zô¨õ;€ªèº£É2f~¨2°éœs£¸Þ‰Þ)¦_VÃ�@ÜdW¼ béÎZÏ©MÏ–ºšg¥!rALªŒDókù8µâÁñS høyHÙ8!dE»Ï턜mnç°­¢ÈJÊ` ôJ½8|‰%–ªÅçý€('pn9òp>' Ñሠi M# KÃd‹Qã¾ð…k¯½6ªÀ°¹bhèÜ¿Ú-î ÐEO)333“±$zÙ óóó¼óÎ;Ï;guí|(,Ë eÏ4›å° ׫ÙǃAcccºÝ>Óh¬É:ŒXÎõP$YÕåѼE)°i8Ю·mMMøÊ7»Ý®™ UÁ4© G—˜èeÀ§O‘ÀS„`ôôW‚ÌÐS1[/eAšaY<a“‡IQYV‹!ùà®(ƒfgg[­VšI¹c)V–——óP¦§§9röìÙãLJôÌ¡[êADÕæææfffBÀƒ9FZ€´L"ÕŒñ+óYÈä€Â� ªÊ•2—A ²é'}Ÿ äü‰"‰_€Ú^‰«šJ.›UTù—SdÛÏ)ŸšÉ$3‚vØ1°‘äšvBÎöS¥yØ>ŒèÄÒG ’à úŠ]ÍRc”/sy./p‘b'Sd€38s¡Ær÷% Lð›[s®™þáµÁ`T¤êÊ�ßWZ %X#w`ee%{£š™ÏPGVÿ•Ãáÿ»¼ü¥f³ÑhüØ`ô³­ÖùfóàòòÛ§§¯‘Jw#'ˆ%ÙËVmJ™²µr|1Þé¤ýiòé’jX¬× IÙjzmTj % ®9¼#`~zÉ8}JzÔÉ"ÓYIM\|C JRïYÔ²U4¥"•�ñå¸çÙ¥!D›5ì¹ÎÁ`p‚ejòk?»x'g²§Ñh,//§ø›LÈr4GþÀ¬²U ÖÌ5Ã͹\Á­œãvÀ2|Êã†åO!Î’�ód·'¬#>TÑ*ŽÀ¤IR‘î™nöTÌ¿I^)À-€Íï¤Û·3 ºý_fÄÛŽºÙl"јç·oß¾ùùù'N„DË:NP‚ê6Ù' “*[³é+ô8eœ*zì½™j5ÓÎÅ�ø¢~é‹}h*gÕÚét: *¬fVðÚÚZ&û Pxr“þSþ=7F£ÏLMý]«õÐñøË­Öh<FÝFãt«µ±uÐSÀ:˜FAMéæô± ÈØ*¨`PÔa ÿ!ä/“6æî1�¿±±‘£pyyÙñÏ£žä0F »7KÈŠv–æ+[Ew´âaA­ôl™N<ëÖ=OÙÌZNU:=úýþÜÜ\µ68Ç×ÖÖ–––víÚå“íZ'ë'×™4knn®ÕjÅVä9æ`NWX7[ ~­IÈÿzvÍÞ"Tùž}¡eu“ݤ,? DU½,7‘ üÊçœ,2* ï )ªZU;dž^;!çßDÔ©úÿÔ¡ä;£Ñ¨×ëq*ùÈ:«´Ç9Ñ<ÞA¦ožb§Ø‹Ð# ÐŒ!psÐT8$ #^l¨á@:Îîó×�5LŠ@Ç4ƒâ4;;»¼¼li¸§`kemí1ÃámÍæÛ¦§§ÛíÁ`ð×öûÿϦãHE¯àô¶Ê€³o»÷Ó¹å†WgL ª"Ô¦‹,–³ósŸçç篸âŠóçÏß~ûíE*±äÖ&7²á#’hQµ0à¾Ï»q]=zFåÝt¡ÝÅã3¤Æ¢JQhµ=cAÛìv»áAÐnìv»i@6›Í^¯— &Œ�4Ê’h㛋Ï{-..®¬¬ cz×òØlAåÖåí*1@³ÑÆT ·¹!FA=ád#«"ujîÿÅ‘š[”Æ# ¿a®J{\*™™}­Üö·</˜äÆôðvï_:LŒ xÚl{À¤`à •goй“©æÄ‰¤Þ®Çºà0È4Ùýf+ye“©|KHð¹Ãa‘½„ ­]dö˦Qj)3w8s$™”ÏE®Çô«…:Úívü666ð”¬|¨¨FO nß65õ]÷¿ÿãÿøïþîïþ?ÓÓ¿Ó鼪ß/ÒK4²sZÑr\ª¦(á‰0äXdàÞ»¹­t°Üjh ëëëý~ÿðáÃ'Nœ0ÁÏ…&ŒùIyý=º§vÌ9 ®뉙s—Uk†eIÐ5ì‰PžeôœÈçæ�aå¿¡ ÈI ¿¼¼Gµ\öÙ³g‘Öo6›ÁèòƼ‚¤ßãøûƳbæCz^*‘Ì·®š»óÚ ÒçÚ@°Ã‡&B°—ý:“e"±ÓœÝáÈå8Ï%% ‘’`‰úu-;N‡™ÙUC¨z£dÉv»¯“;UÎ6|2• Ê(ô,Ùu4Òý|‡äÎ cSVÌö[@Ü¢5^+U”ST|Ú+Ýò,¾(¸&°Ý!ùÛ´°>.Mû"ÇuIMÃëõz•P.¤¬»|ÙRÆSS{.¼ð'~â'ýèG_{íµo{ÛÛV¾õ­9QÚ€Ú‘6�C¬š.¬p*|ª pë}˜)^¶ŠyóFµ‹³/“FUà!/®Qé´¥£cT bR>,ý¤d ¹9‰F”§E¶x„^�¥¬ž8´=F ™²„4ÄéI_Ξ=›Nê¼x�Æ^¯wèСÅÅÅ\¡Zнò²ˆ–––Vé4@UO8É}``9㽕b ÂÏ®Œ= gŒÏ/TcŸà©IïœfUúè–€¶`QNÓDáãQ…@V"¡¬zÃiµrsª4…BŸ=è†b‘‰Ÿ‰ã;$éíg¬6! ܣзå¥þ«sªHÁÌÝlkN°Ü‘  ŸJÉÂÒ½F«éš F›²åo&ïe4‰wo·±\j·ÛµÀ­±õÊægîµµ5P;ð ‚ñâââ¡C‡Ž=jlÿþý­VëŽ;î`’¯Uª9“:¤|OZ ó¸’ÞáDv (¬²Ð™14Ï ’¤ÓW'"qÍ_u»ÝôÆøŒ?ÏUi³Š²U­Îê¬=O4[oßíq;™Z–¸jqS” ƒË.», Ì6 ¼•••3gÎ$&À›­šmóóó§OŸiÛ=|9éÖ$ùQæÝ!Ëx„ÖÆKæ 3þâþœ•åXQ‰peS,*oˆ®G#[$„Tæv !à0q$00^‰@£pè‰eï®R|ΫªÕ´r¶'ä(U“›þ‚P‰¼:q ’¨Ú3Î;2þmŸËmåb¨Ð|0w¦F\ËWC!•ç´gͪÑ9Z8&yHŠ>=x™Í Užx¥EI÷‰©©K‡Ã‹î¼óïÿþïÿùŸÿùäÉ“gΜyÕÆÆ[Ûí°c™3åØ5ÐÁ­.›S±«««AÕ¹ŸLeZ7¾ÈÓñ,§XÎÓjªRv´.R°…Åò€|«Ò‘¢)àÊGcR¥ !þŽBlŒ9U]½Á¶Êñ®(@M¥@JMÓï÷wïÞk.œiê¤2ã ’e€MîܹÅÅEz0¨šóŒ*g=Üe4`p2T65>�Ÿ‘OŠÒ̯(*q€Ø™zËnrdî§‚ íʃæô7ϳHLñ§¢ç²Õ»hìˆÅÒÔŽÙ¶üØ 9Ûö•£¼ÕjE‘‰ã¾r·å‰BF¤öçØÅž”6¿<ÙK0Ñ™ååî…Õš³^ÓçXÃÛXÅåU_S“1‹cjÁ‡¼#‰·S¥6Æ‘3-¿ì[N²U�-d}}½4§Z­µfóÏúýgÞqÇʱc?[[›ÿ¹ÙŽFÇŽ?1Êï©r¾ ‡ÑPË€9õfÇN†8jÏ$ êpŽ^¯†ïl»—W,Â89c1YL*ÔÚ4£9FHÌL#fPG¦EÅòby(�°ÆÍäÌ¥»îû°¾¾~òäÉõõõùùy,vrúý>Öp4–ÈWfff²�"gþ½Kðl„ËX<ÌÃeáñç–ƒOjâBÐì—ʤÊÁº’7nå�³N'ô<Ðïü#¥)×™šÏ ®© BÏE€Çy Å4*´ìŽŠëÏíJb±r¶¿Äqã´ÂÓ¢TŠ÷>¿ÌWæušÍæìì,йXÕèeÑ$sÑì!µn:eSl _<^pNœ'0Óª±S;Ó›ex\ݚϰEIiÙü_°¦aÀ±RÊ· ‡oµnš™ùâÒRvØ+;CƯ¯ÿk»Ù@â¢Õ¸I™íg½gZ¸…ŠFùü|íà[ál“ÞÞ”k¦EX (ÁŠ)9Çw™·€¼î©[ˆïUA1)yš°Ø~#µÉ=g½9ðc¥O–qê0'[pÍݲ^[[[XXX^^Þ½{wZ;Y´»víš™™YYY!õÎ[ÌÌÌDøgyyùܹsÁZQÐ1™±p VvkqO T€©êR„={ÖˆÎ2ó¿ÙìAx•6xÍð\’ çT‡ÖQ´Ø )B�kDJÓ -²gÔ„ÒÍs†^ù¯¹¯†F·qt'älùJb¼ÉFF¬l ùÚplU^:Û÷ØóH‚–<ú¯Ç ?±ÂÈéŒØßç;¸%š;ëôÖì/å²ÕƒÀ#ÖùìÈ»yÞˆX•3ÔÔpÚéÖã§§†Ã´Z÷ÞØ—ò’éé»>æx|y£qxfæKÓÓS›„T³RÓ¤š4P@—LÉ&›X­Žcùβv½ËY À˜´”òÂw²ÈÌ‚%dæºc‰¤·<Kªᩚ|UÐ%m¿»C¦i>cJ7Kó| Ãú‚]”XèzJbEóó1É››‹ˆ€“§”\IÃC<Y^^>þ|N|Ó«òXÍO³ò,çrʯ"Ç´c6R³•·&tš¬„ŠæJ8»ôD¼­Ì)¥¸L”5©Ä ÐÌc9Oª¹\#Ú˜äv’5�hœ H*<¶Ìcmû¿ ·Pxg§.áä*2tÁ° Â»-`uzêh,•|tæûUITäo]E/ºð ¨~<‡‘_C"%ÈІ¹LZ¸�·B½69~Òž1” uœššZ(å»]ôðPollL«üòpFÊ)÷*Ãl$ÚÈ:iàœªi<T¬DZÈV4æ ¡Ãé-ᤒê*[§‰(¦ TRÙ9)Ο?Ï‚ ÊÔï÷!SÁœæ®iùج…�Ina°-dƒ±¡#NŽOp€çröìYÜÄ÷îÝ»²²²²²‚xAd5"LàF7–ØUáå9ÿ¢Ô"?*"+êSùóhðÀT´‚´ñmV øªí�Ø×ô&Ùò6÷(C̳ Ÿ.—MS-·ˆ©m 6B™«ªsU½æççûØÇÎÍÍýÃ?üÃwÞy2’;!g;¦“$ìê¼4Ã(s5Z\5Ø=¹iÇ3Ï~VÌ«««ô´a…”­Šè8 5+6¶a"K}TßO›—I÷ä�s‚ 0^×µ<(ç½J;§ƒ{¹$€4Éè$#ýKC‚âÒY9ûÓiédòž€TÍ%xÔð!Ø#XÍg gQ“)c Vá`ÖÖ,²æ µQ)“`> @¹0Oû—­†`f%Øå“FQ¸ÈRgdµb¹×èú5Ï<G8–œãÃá0ñæÎ;ïänãŽAfàÇ>‚uKQ÷Ø�‚iTÎÒ"�è%—œ…D MϪ=鍿çv ®È Ï5—­¾×$‚Œ“kCZ·Ö²ûŽçamùÁZâ\%ÇB4‹×Y__?zôèÜÜœ¹ÚÛûµr¶0ë©ʦm;)<g=âÄ®ÊéÚY/¶™¨ÊÝ+ŸüLh¦”±ž[¥Íþ±o²¿÷œòa™'õŒ i°†õÿ³ÌwððR=9#Ÿ;C³Må˜b¹Ü"}bdö‰s¶ ‡œ„e�âIQÍÄ °IÁÇ žV$Ptf<“ÓŸ¼•ôÂBa“‚E±œ2fÐåMM[Ê@x†®2ŒØŠBiþ]7³?ò˜8£©*RuÒßÿJÐÈšo!þ16ë9*†o,PÙX°Ý8ÙÑ9$£ÊÅWÅiŸ‡ÿ]é–Mµ\ð7hÓ6#H7ΩeJ B¸ •‚»›µFJÉ·rñLM~|n8°pE‹ÍÛ%Æp%‘ÃÀ·-ÿºë®›ššZ]]…*iLu'älg¡S "x³BÏ&™ÍjËæ 1q5¦WœÀ²™Š(ÒÑñÀP& à™!º.¶ëê €Ž†3¥†i<”l Ÿ‰àu¶Ÿ"èr¶â)ÂAÆ–£4±Ö º,6¥NO¤Ž_¶3Ý"h¶aòf¥“ªÙfÔÅ׃î•ÇxÝ?«Ê)ðd©êxcOLè…(äÓí·ÓÒŸ<wÆ×Ý@ªÚu®iÜ_„mHü6á8´æ­YûØÏ–Ä}keÒØ àK5邆DÇNÏ ¯Y$*A±ìQk€- =Àï±n6,}®ÏÈ­w½Wß„g;ͧ¦÷ÅäDŽõ¼Þx(L°ò¾Ø®Gs(p:¡ñŠwBÎ6„ã-ÉmS˜³ï)î,în·kÇõJŸ˜äÔàƒiÞË뉓†(‚]Ö×¢¢ò›²+,åé:Æ„œü;9#½lò|dÚ°«+6óô\dD‘U‹¤ô!Ì&™Í¨ ÝJ·Øœ¥$Ô²Dò'àƒ]aìCƒÕ£G;=êáj’"˜ò4àŸ†zEÑŽNˆ`e„wz<2ʼnLW‰lýeÐ0O«L:\@ߨLZíni¦_êQ«¤Ø ÝϦt^s[YÂa§«Ùós ðLn8¤—2^Ìî•Ò-tr3’B!1›ÏBªÄt'|B–º³ñÖ/“îQŠ‚k¨¾on©$7î~%j€ ·Õ%¼]¾Ûšh'äl3°f£½T©Õ0s5óE¾Ã9î®2똈}BÆÁÀ9Y#ûéÍZäƒú&[Ñ:\qs¦ ™�§üêt:•h]2®lÂ;ÁëØÖjwÑᯚCèw1.@Êœ­²¼¼L¡à>3·Ø'æÊ£¹?é.P'Ùˆw§o=´°µJ›$/‚NŒk /žLì{vŠE° ç+3F'e(sè£Ø8b•-ù0<“!sòaÃ@sþåiâ”2æ›±q*ò(˜éLùT|KæO€›"NtLj»ÁªóTJ^01{8þðµ§>µýªWÏóÍáÖ¥a–¤d EÂNpù|ˆ“a˜$’EKn„H¹O ŠD÷|F¼Í‹c -¥T&覰©ÉrÁ–jdŒ¡’yÜ 9ÿ9°r%Ëx§JêãU9šºÍR@Wœ5áÆ/|Ág³>,VïV°=Ä\…Mj@Y׌½Ëæ8¡·=í%÷öéXò‚ôH¸<S`¹r:·´ò1=ÊÖ™j¶tÒ^k›Z×s¬®G ™ã'£9Scó©*`%ØÈš7õòWÕ­ájÁ[n³$8ÑJ�àΪ–«_ÖÁ¦Ö××Sy»Ùã–uò e•CŒí«-¹ÿçÅýž¤5p )>¥yd*»~­¬7 w3mKªŠqZÑ(§î²=ü‘üÈtÿê¯Ö~ù—§ÿüϧϜad¸È_ “ÐJkÊu|¤PÑf¯U ßû÷ï____XXÀ–‚Æ›ÇàÜ¡1(giQ{.XGÑ¡%%¾}äLý7!åã°¶ýŒ5jê — ¢UÀd/OŽn¤»¦ö“ý1õR4ãi73场óLÙ’ØØ@î,[5£Hé^‚éyíH—@öêh³‹8V8ɋݭáz,ÅíÃÚÁo4À†pq�4fh¯FO±X–Øê‡}\/º×îƒ]Ôp8.²t4ªFË¡Odz4’ÕôH ¸ Af¿úÛ Ÿ•×–©¤ºvc²Èž»Ù³œH@•ãVµ‚ÍЀz€õˆè<ÈÁ^.Ôì`ÆŠÅÑÇÎLÎáp8xÜãÊ÷~oû÷¿5Ou:«Ï}nó÷¿!ɪ¢"3Ö uaAd§<¤¢àè÷ûN'²¶ü4¹…Ý ˆ.@š0nì€UñìÁǼ€áˆº+Éaâ‹LNPéšï„œí™Ë±¤‡™Þi¤‡= “@nö/sÚÂ’ÄÕÍt,¤q*Õñ"}Ÿ¡i¬”óvÔžä7ç@¤?Äè²qE1t úùЄrXLR+Iyz?e«f>mdN P‚œÚÄf ¾ª×j⯹O0ˆ¼QcIYytf²„ƃñt3wá¶V™5לY©`\ 0áAø±°JÞ%Ã’öFгåGMª&xf,Ϭ†ÇŒ¶­`FÍ¢4ÏóÅ&[›"ŠÔèedQ­¬¬˜OlYL"ºg•h¡¨¬”AÓ®òç½ë¦=êQ£ïû¾]þç%¸ëu×mœ9³ú†7Ì=÷¹$<zºñÕz0c%äð�kUxŸF;£Òù6BàâÌD»LÔ.--Ñ-[ÍÑˉü¹B’HË(°Ô-îJk'älg¼á0²f0óvUÊFŠªVóNœ eYvÂð¬å¦Á�� �IDAT�4qaªLÄ:í¬<’w¤8*cŸ;fjÒ3¨4»ÝnÒ7â]„„4Zô>I+….޲N¢HÙªìP±Ÿ'{é´L]‘TÔ¦±qˆœ)R±#o5óÍc}•úgþ r‡GY‰²^KèWÒ“Ï÷“¦LRÍhpªQ¸¼®N “hÐ2H[µýóq¸„œð | ȵÁWE-É;òˆ©íª1Û={ö<þñ¿ä’K>þñßxãöJ·/@tšÉ6Ò†t$`õgöitz¸ÿêOþd÷Õ¯n,.^°oßx<^\\lß|óð}ï¼üå3¯~µ›ö³³³øåØû®²Ï¿S“™}ËÑó–¨)÷¤Rȸ› V+¿*’r— îA¿d—ñ¦|õû}?ým€”vâç],iã‡#†®Íɪ§âD\XÙ:mçùpÏo]<ØÁŠdÚ r«LMÀG`‰ã@Gö>ä–ø<šÍ um’FU¶¾Ð�j³þŠ'ÛÝ`7¹¹Õju»]*³o¹árbWçò rR|xÿcçAt.Àã¥Ü@N;§È�³h^jphÍ üÚDœ‡Xuõh2ç\3]AâMÅ‹³‹sZß•f(užW…Ÿ&s3±ø$º YëVi*E–7=‹0`‘ç+­Lc4ÏßL¼¡Ä ß/Ï7[/_E•Úæx<nœ:Õùó?þâ/Ž )v×ýèñýP÷U¯2„ LÊgÌBÊ»‡íaa\6¸�:‹<Vž‘¥@Ì/…ˇìo³Ù\\\¼óÎ;íðm_QÏ#»zv̆¶ƒî×c’êN•³Í °œnýÎ쌒§Ê¶‹-J_eSl$Úøl¥èÆ!R$g`Ñ@OÞF£àu@Uî7˜•Ç\“%ívû’K.ǧNJÝÆ(™Í}ñóp² Vc\‚ï‹$b™ñõgá@çoC%ªJ�·*0x•øê@ÎG˜D>ŽÎ2Õ='ú¢¤IRì1L4ÀÄ(pœSžá¥X17ºR€õ|­rëþE  ‚øAêLßG©Òm2lk€®ò`ff“å³’$lyyùcûØôôôùóçáÔe¹›R™p^[[—&ZX̺×ÝÏúúë›33«ÏzÖø5¯)½ÞúþèÆw~çìë^WI�°˜«¢Ó6zè3YðÛ<UFw+R85‹Qp†]v¬Çã‘ s œûÂè¿1¿frË서í‰7Þ]œï%ÁlZlqFê¡,»$¡ÆÓXg–Å÷“3k³N/¡Hp“Èd ,–Y©¥8RbGÿœ!s^pqq'“AS¿S7$ϵuXÚF«ù8ÆÚÉ÷ðHrÃÿžN²i*—¹¾™.¡ˆî ‹ÀçÉxíXª‰<Ž ›2IÄ¢XàæÔ 4ÏqÈ#°5i&Ä �`¤L¤;eæ—yf Ü[æ«òa«t¸‘@5²W¥_zÍl“Å&Š,”B÷OM?33ÃoBÌk.,,X=“ ¯RÔ§×èáO‚hUþR•³{|ÿÆè‹_ž9sþµ¯mýÅ_4¾ë»Úo{ss øé$ç�²ó}ëõz´Tg” ‡CÓA¨l*6°>a˜Õ»»Ë‹½:l#?¸JEÉ:î¾’%éC¤5ÓI1ø³i`æCGLp¦§yãÆ/ª6&³š³KIAj8‚s û[/_FæØŠxbx¥eSw¿#g±Íè”Ë&¿‹lº©ÏTJÞ"·R� Aº*=dúiŽB‹ðƒL&¼YzÇ2ÌÐCí¦Jʹ¾¾ÞëõœW"rg!3–º¡Ô@D„â5¯Éß"™Õ’?¤öu*šÏb‰3d„Üö¤c”»Aj·ÛP?ÌdB¾"}¹“Û˜«Þ|BÂ*]ýœ•ˆâ°˜Yä.áj!ÝÁ÷ù_‘†Ýž‰5)¹Ý`)i³±qHãEÍ›on¿âƒ_ù•î+_9˦¹?¯Õ©„³©Ù2ÜU@EòËI9àJµ“€m3òÎìúìâ œ -&Ë´Vž¤B™s‘ÄIÂÐÒNÈÙÎ/è­æƒQ¡Ó<·}:s!tzèâ’†[wÙ²¡•4K% "Q)”°uÍŽƒjl¨‡\ÍRX³™™PkšAÓtïòœiKìºHKsþV•¾­†B<÷W¶*ÕÓ5vgYI'k•šÈ$4d»'R”MCž uJà ôz½n·kC¼Ê)øjº/”˜Õ¹ìq%hdU³+™ý"§‰ÕÕU®yjjjí?ü‡æ‡?l¾¸uæ.zÜÝ-1÷{ÂŽ)[ 1+e[“ú˜ìášÑ˜ ‘É*E¼Ãav¸¼*"¯ƒw¥>åµj=kÁm9Ò~ÉKF›‚ Šü×@%ûÅ4wËʦ¦»æ†%P‹X?"F&nU*ˆztÉ›Ç`ËVIFî°-ïòdcT¬;!g€µ ßg¥Úcʨk±R^2m†b%‡l‘S¨K5V6-}ÖT‹Øô\7<M\¡—@šiŸÁ\C. _¸ªáº°Í@™<\å&õŸmœE,^PiIñ •1öh„Á¿™=“<=¹‚¯Ê~'Þð¹·ØWþNÙ:ŸkA³�‰ùD´â‹æm+27y:-\‹‘û¸4ˆ‡Á¥×—´þÜ玆õ§?½uÍ5+V±]‚èo{lÓ#MV•­œÁT’”¶±04—&f¥=âFöãL‹]ŒªcjhÈåŽ5¼¼Á-ñ7Ïv�8g›_ *àÈj:&4šyä‰r¸'&@zb×êÆ0:”ZŸ7µW…˜9Hƒ¬³Åícm;IÒ‘]á©€�vpÅ`ŽgÄFQÉËLUB‡ðǪƒ8øp\CÀüÔj6Ȫˆ¶\é`ƒÔa¼8DUOÀê¡_•ÄÜœˆ¼¦¿cäÚP¤ mBÅ7ÇMZÏÆ›ÙQ6gܸ°�œ{s¨Bµs.;)!è“G£ ²WBs”bvcLüîv»N‡îŸ1Ç"´WønQ' &Žž÷¼ÑÑ£Óï|ç¨Ûí?éIg·\ð\ŽéÅ~²„"·øó\`&‚oyÐl™äé¹òü¾>ƒ,æÓÍ‹à4ä7ôŠ*:$Ûó.¶O{´-MA÷M+—K|òP•D Nh‡¶V3ï˂Е¢àù‡‡vA³m‘ŽÚz.ÉsÌòR¶ƒÌ\__ÇKÂ6’E¢;UÎ67r"ÅáIúÀ�)Àh> ¬¯gh•<"ª*ÆÇ@p¬ÉïXÊ*œ äøUÒG³¯uª ª´åéo#ÿº……«66úÆþñøÞÃa)e¥Ñ¸­ÕÇ—ŽF¸øâ¢ipW6EZ¹U«)§ñ$°lªçæ›ëññ´hcÎÖŒp¢$– ¶´3¹mNž`‘@唤œìÝnûÆ9«ZOñ©(¸9Yûöí»âŠ+Î;wøðá•••\j¯×÷‚áV{iWaÏ$7�Ÿ»TffVöggÎ̼ÿýãñ¸ýŽw¬?ïyå§~jýoÿvzs8 „¹RdVÆsÂ[Ñ¢r·+gzœæ‹#Ugk›r<÷®Ï:ì/­"‹U˜iŠÿÕ.vC«² ¢-I'B«LÏ�cdbïdÿ:0 6 ¹Z•ž¯Û|pžI­wÄ*»#*æDtKK@@'€Y21é#2†Û{Øî„œ»CŽgž%•©‡˜D³Y:ûœ­â¢>û•à‡µ™á˜Óq6ãp(rpÂ/™}W˜={ö40Ó¬7Ú(åW÷ìyÐ`p Ñ¸¬”Ñh´\Ê­SSŸj6ß¾´DÖl±QËdI{3_(êvwüÁÓãìXâó³dÒ7Núœ¤ÏŠAF)áVc¡-,›ÂYôÆ�@<‡ïYQKsæسgÏã÷¸'>ñ‰‡zßûÞwà 7äz*7ÒF_óq Ì±öf¹Œå§=mjc£õW•ÎÊêêê̛߼þßþ[yò“÷w®NŠ ™ŠÜ*{Ì ÞôëXßõ¦rA6P–Ä•EËZ­à⯯¯ÏÎÎzgYs:‘Œ68 c¦z²(=)RQ§7iÖ2Ð&¬ó_Ty*dÞ‚ îéšõW W1ælÒy™Ðƒ vúK ›1ý6N§ÄKZA™IªÕ³ýðàµÓ³iÁ‘|„yD ÿ õ:™$VÍöÊJÙ¢^^L€ÑJ0(_¶ºõ¸—®lœÃõ„K6›kk­Rž»ºúßöíûÊÜÜÆÆÆñø¥gÎ,µÛˆèØŒ€z‹ž§6™` ---ÙÔ„ò 7¶|„kQB£—߯öv ?ŠEtØ<ÊcAhÓ³³³öA ä„SÕ†(î3UŠ>(]xá…øÃð€ìÛ·ïÚk¯ýÆ7¾a“j¯¤VC�u 0Räµl_†ÛK)Ýn’˜ã©nþ ŽÁ„µj™È²)÷0 ò,"”€²«7`�°Ed‘2æOž‰1ÆšdR¢*k;Á\0Á oç•쎔9o—²r žB´Úé!U(µ¸…É-ùãc„NjÕNÚÞm˱“ªÚ¶Ê»Q°^Îvw £çY^~ùå™Ç¦¿×l6‡£<æ"ë3›VYþÖuÄ-ÈÇäÝ üÙ!)ªÞ)ù’b°¡Ò•­^ kkk§N:}úôÔÔÔ®]»c|ãùó?·oß7/¹ä>÷¹Ïff~gïÞGll\º‰òÓ~�œq —) †¨éHåxå<¥Ï‘ŸVtß+3÷ؽGÈKYQ-ïž`lþÞÝñééáÞÐØ¿Ÿê„ɧ—¿8)’6:êÀ�&­>wîÜõ×_ÿ•¯|åºë®;tèPôÿ¡ç`Íx&•F±Dß|($�hhF£Ö_þåF)O{ÚJ¯·¸¸Øh4¿ökå›ßœþ_ÿË 4;ÚùÒ3óâ·ïŽpFP+ Ø(«×6fh̪nÃÀ¿¯|N˜éFTÏ"gåÌÌÌž={B#ý¢«ÁBÅÜ“9| …àÌ`\Á´yžê'BCa%0îFŸŽVÅßÉ-ÊÛY‹¶…« BP;1^àpǧ¦¦VVVXx¶N ‹võåN•³=Àšùˆö&‰³žÝs§§§‡—]¶öŠW4_÷º™›n2ш=I[‚ö è2nÎøŠÄÌ9éò…€J™ðTg5»Hgàܵ}×€QV%¹ïp¸ré¥Oyò“ùÈGÞvÛmïxÇ;Ž?¾{4šÙJI2269läoæã`I@Ži•(9OàVVVª¦1Qjuu5&ƒŠÐ �°¢­}WNºgÏà9Ïéüïÿ½ø{¿×zÅ+¦våj*ö=:õô£–JÊ̳;{öìßþíß~æ3Ÿéõz'Ož$óÍÙJLjOW U¸\ˆ1]%xÚh4ÊÆFûškVÿËéýÄO4ÿîïÖægÇŽMÿÏÿÉÉâd²Ü¿l*S±%¿±Ñ§gï) ¡³#-À"¦px°bë⑬ʽ0çµMóÈÜy5€¬l±ŽeUƒÚX]ZÏÇÌÌ̬®®&½èv»!|sh‘’$½ó„ƒs¯Š¦QäE”«¢ùÄ‚©4r˜(2M¾ 21](û §3”ÿšO‹ƒ3³+wªœí$IÓ|†d¶ëéÓ§WVVî6½ï}×~îçf^úÒõŸþéå«®‚¬B®T­›Ê®˜ígšµqìs”rrÉo¦J~!º„ɘÀIHS¢ùt Ö¿oß¾½{÷îÞ½{Ò2µ%H ¬)2`Y?ªHM 8e¹9d*ûƒ¡“•[D€T΃,쨻Îñ¹¹õg>súúë›ÿò/Ý«¯ÿâ/¿ïû˜î¸È-EI -5WoNS|…9æ;væÌêÃ}V=)’7}Ëq†Ï“õç5766¦ÿäOûö­ÿâ/6z½öûßïü³8· ÚDÛ2œj€¤Fº³ã<â‹.ºèÀÖÌ6à É›èNÙf­rÇð0�«ÛíÎÏÏ'©f´O ÇIéP0²Ìû1Ä0î ÄÔJõŽIˆ× UùÙòžHcÚÆX·QA 0W„°×*Ž>Û*C ™ Èu†PC‹½™ÈÄ ƒî§Óv9ìT9õhNˆ: dØ%Éj<ØÚÓfþæošGŽ4ÞøÆþÏÿ|™žžþ—XUÍ…±{݃±H³gƒ¿Ó‘fƒq~y3Mž; 'Þù”$ ¾qfæißüæ§>õ©£GÞvÛm§Núá~ÿë33ÿ—Øeæ5¨Åô†…ô rv‡÷ ~”MõeO·åw²=VàšëëS_øl Vž¡sË3·Õjõã7¦þñ§>ó™Öôô`q±ý®w­ýçÿ<µ±1úêWI#rÁéB#{z7UlóÅ©&M™#3à +rÇñl„uÌkwªî&}óòIgÿôO7~ìÇZÿðE•. ê<Ù$‰»Hn’-@ç†Ü žsss~ðƒWVVúýþéÓ§ ™NÍq6==͈IÑdnU[L^p5càÉ'«K˜�fþ½Ý¯Hc¾ÇC 4ÑÔ¿î;œ‡n]6«ÄãJe�Í ÅçÏÊ„pµ‰p0 ÀEØž+˜D°áUï0Ö¶?ÞQ8€€Â\…´»Ý¥W¿ºûâÏ-,ÌîßêÔ©Ùk®Y{Á Ö_ûZVê¿ÄÔ3=þæn³²H±Ï,WÃü¦¬˜kÙMuØPÀ’ ÿ¸{÷ûî¼³|îs×ÜtÓÊÊÊ÷¬¬üÁ™3ÿý —7cø†Á.Ÿ“÷ ÎI ŽL»Ê©w—Û³sssß÷}å{¿wØn7·Ü2™ y¼ZTÒÒ¯½ßýÝö‡>ÔüÜçæwï¾âŠ+Ž9rúÈ‘©k®é½ä%í«¯--î@7orsþ“PËZÖfg³Í)¿²b Œö\�®•êÚÔ>ÐØ”kã→gð‚îòS¦}SóÑ¢°`àËFœ'Nœ8wî\Â* [ß•qw?É’t•ó!r8–HÖ•›Üëõœuy¸<é "SÅ2‡Và9Ë\ZùÐÔIJUooˆTk�¾£OÃÄèf61ö߈ûà4…t‚ ¹ŽÇoëܘ¬~a'äl/‡‘Iö³è4]§¦¦Î¿æ5í׿¾qäÈÆ¦üTkq±ñ®w­¼ä%Ýg<ƒ<‚õj9�æTX‚”ÿNgfffeeñD%í× ïÉPËWÆe®Ø<öq7 o0øöµµ§îÞýäóçÿÏñ㥔Úíçìß_Ji ¬$‘Èä¾%0žCߘ½ßï#œ- !êrá…þàsŸû±+¯¼ê×ý–[nY|Ó›š¯}û–[À !¼š“ã³ã®^ÈoýVÿóÎÎÂÂΜ93¾à‚þ/üBûü¹éÝ»———)n'0._E8S™inåÝgffà•Ë‚±ZÙ« ¶ŸÍÒX¯Þ­¦Ö}‘K˜)&”ÉÂæÓñûlÝ»w÷z½Œã¸£ÒZ]]½á†˜eAÎ&ô–uµùeì Z³•m‘ÆÜ&ò2Ãñ½"Œ9͘4a¿ê�ÎkÏ~†ÌY zrç1Þ…jh¶Q¸ LI¹äACåæ�’š ñ­«€Íj²Â,êÊ•yhA›|k5³Œ5Œ˜ÖœgßyþóW_ö²Ñž=£Oú®,õ~÷[ûÉŸl¿èE8]:Ù·™5Æ#0°îÔŒ¼Ì2£BšÌ-î €f˜-ÈJüƒnÁgÛí«ƒï›Íæ;ggóçÿqiijjêÓ› ¯k»Û²Ïçççïu¯{-,,œ9sÆ o«þ@jBiÍ3ü9g­vöüËñøÇÞþökÏŸÇÝç=¯ÿÒ—?ô¡òOÿÄŒžÝr©1¥m»ë(ÿÍß\¿úê…}蓟üdojjõ—~iêsŸk_ý½/¿¼Ýn>|ØJ'@†JèÇâëJmE8ή ;O³‚×|KS€È Û:“pÇ«=ßpRf„P­jÌL•É,o¯ƒàâíŸBÅÚ&¢ÊŠ*ç>`²—ëx<ÞµkW¸ö–vþ—ÓœšÌúnŸ‰m·Û+++¨ÂXPÊrM•ƒ«TÞó4M‚FÙJUB£ ).ÍÆ´âbþ6¨ ©ºª«Dá|‘r0ÝÇÜ V<½L2ªKwBζ}yÜ’GEnU)¬L¿þõ¿üËÃápøéO·¾ã;úOyJãÝïž:zt´u€,•§[±SàFWýÞ|“v1'akd%1å O¬Ä@Á1ÊV•°¿žžþëéi,ܱ´¹5‚’Àܰ’²Ï/¸à‚••ªSb*'b™ Ëµ»Î…G=jáÊ+÷½îuŸÅÄp0hÿÑ­?ãe8,ŸýlåÇc‰C‡ºÜíéååÆ;Þ±ôô§w–—ûOyÊÔG?:õ™ÏôG£S§Nes2:_AL ;Vd6ÅÀàþx‚äG“jÐį 6–l±b©{&}¸OÀaP‘ÅÒƟ©Låšc™»+ÈͶ¶Éf Š6óÕ�J€ksþÎ?²;ð=‚yO¤‰^µ/Ìá®æ©¤rªl›í6â9$G_*7™^`‘ô­YÔÕ‡­ðX#`¬K4@ZâMöfÉ8€8¿ûvutvkw?~§BäݱÌÇåܹéw¾sô˜ÇŒøÀÞ+_Ùzë[›·ÜR‘¤ËVq” ¾ã(t¯Åø•=E&}—=ô€O" :nÇs~ff&‘Ì«Ü"1¦ ew!åɤgv8 =Wµ¼¼üo|ãÎ;ïä›�_Ü[BÙ¶­´#ç]ú—¿<¼à‚åÝ»{½Þòòò]Çô·}Û¨Û-7ÞÈÝó #G›¹OÌ™—;îè¼ë]kÏ~vyï{§?÷¹tw—––Ξ=›ÍŒù[ELpGÇòšy 0Ù0Bç-CB ìnBPdŽÝ… Q NCãÕ \ãš™7L ÷cuÆÃÉÅ}H"‚ãµýŠŠÊ 1 †s_]Žu­° ÖÖÖ¢±fSËêLô4 ±ªßïGR(Ý#ÔùZ­Ö®]»Ð%Ê V½¥|p:a6c´*k6ÁÒ¨¼ ö­K=xªk¨ü•~eS¦„x !·\š`Æ ù„C+ü2§Ï“*gÛèæ±€0Ø7P¥Ó錖—[¯|åÊÞ0ûK¿4ÞØmîCж®Æ2¨s!RWœRTïÕè5<HÞ€él*Ž{¢à/`19#‰R]9ïÒŠH0°‚!É~>lfž©´Ì8¨ÌlXý`ë\'÷°Óëͼìe+ôG£·½­ùÕ¯–R†~ðàgv÷ _8Ö7ç@ÃCÝ€ðfóà»íNšùÕ_ÇEt¦Ü.4QLIÉù àD²uo[k‰‘¼ ï1F9l¿f<–°õì4ê~Fˆad!ˆÎq<â}Ñ¡wå¢'ãbt\ `U&C8t”M3*ûNÜd+H1ªIÈ´n!=B%mhù0`4([ÀÝ–"„žN~º?œ¡Å¼5{‚)—ípbÑ3TM‹dØtX¡ð:±Ê¦éÂ+SÉséõzéÎQÂ&;I¸búuLjúßD;‡äðÇtU¸öÌÙµŸ÷¼ñVÈŠ£ìr¾È#«?«Íze)àtCÒ¸"  Æ6óxеG-sB\1´‚ÖdÈQ†>È—­¢ovðˆGA=ÇÐ+ðBn`N"—nÖ§º«úµ_ë¿ìeS{ö ›ÍÑ£5{õÕ²µØâdçÌ7 Lߟ«š’±¶²±å&8UM,rFË0;_^ ä”­çyq“é³*híp[ã„6�t^¡ÊÂÙ¼ä¢AEKùùÖUÝ;n#”.Y¢nƒUdå<îÉ.·•Ÿ0­öKeWjÈš›æ'NÁ‘Hc¡?$ ÊVIÐ|p'!³ú™…6¬N]Á•,!A™“®YjkÅæp_¤wUäÏ +=x£¡<*ãÐ S1[ya»€µS ïPÅ»Ÿ ï¬ÌD~+šFiºšWÍò"Þÿ– ¨b•Ù÷Þx|ÑŸZ©ôF‰.$æ ð®»-6lqÒ¼~¯ I3gj–§"ØnÞšTÃhBÐ$ÏF ƒÙ?ù“ÕŸû¹ÆÆFûMoÊýI6m;’xSfgWóX+Óæïì"ô£¢ÀU^pNV D™¶ ° Â^‰Ô%·Å�?²’•1qÎÖ“n¿ùVSKÙúÚº,!‹Q‚øñ_èyä�>T ©ƒ¹ÕÄ9³i ØÙÖUBØkÎÕl îrðƒ·[&Ne¨½~rÚ®¯¯g%Õ¬¸^îlñ(ÙûÞ¹¬½“ûž[Ò"€¬<'‰Rž¾2´ÈdàGÑ\5œ¨qókp}p™ë¸r¶3êI¾[è‹C³ qœtƒzY]ß|M ¯ ³³³�(©Ð8­:@Õà=×:d³�z¹¼ŒЉñWä÷ Á“ˆìÉ ß`‚™P0¹)j¡R†La²Àîºÿ§NM¿ãÍRÊÒÒúh4===;;»¶¶FîéÞƒ[¯V'CÈ«Jù9qPB¦…LJŸJÕÏp`FsssAqpLóÙ‘‡¨rvš@Ud ESú•Í«,žxîªõµÌñcõMÖý¬ÛJþ‡Ü‹»JùXyÊyVßö-H|â\ÀfÉ8­¾ {p œÜ &®˜³°´´”G077ƒçjñ¸èÉê�� �IDAT¡Â¨lð:+¢Ò,¬vŸá;Ëá„ý±ÿþ©©©cÇŽ1ă¡x‘wœGŒóR‘ä±ózEeò9“u³@|Á•ÊNÈÙžxÃZ bË2æ¼ëLú„"DèZ›„®:ïØ¢ì+K¦aòëŒò ðtM°q­æX²x°](ž\¡ÕPXâsss“kÙœ4ä³A»Ý<âÁ=I¾™×O𯀫¨Æ¹sf³µiTj}-÷rmnM¢ŠËduª:=Ìåq–Qáцá eä¢ÈA|8v»Ý+¯¼òÌ™3ÇŽÇu5rOʲŠJP6h€Ah4j_Ñ[+Œ8[h&„ªÎ['믬9SÑöû}[ ¥»`òsšU/Úxµ/‘Õ€›› (yé…aœÿM½Ó²Èu"1÷Šðç TN§×ë!–Xó Œ&ºWðÌëä—+£Øê&.[ô!yH§ÓùøÇ?žúdö±6Ӈ܂(Òjµ¢Šb„€Á�;:ÀMfy8}Ü©r¶óËüÈ,&:F«*í CÑ š{Œ `“kpÜÀ"H!Exc¹ØÎ<Tw2üY@Ã*G8fÝs¦p¦3 ê³;4Ô ­ðOj\Í'fÿx0…ÏUi¹ƨ·|+&ó/XUÕì-·Š²1i¢J£ÅI±8Öéi£çssŠ!`ó›ßdÒ(kÀó:$ª¦\W€de«ƒ˜£‚–å7¾³°Ä¿kGgÓÒT -úøÅ+hËL mدŒÚ…ÜSŸ´Ü“qN³Œ yž)¹ã™–…e®¨ßï÷ûý2!Ò<‰ÐVR®zm1îZDÑ3˜TiŸÿüç›Íf¦‹˜rÃÌÝ>¨qXi ü”ú üÙ„¹N‰‘T?àr««« ~ìж¿Ê¿NPdBc\ˆáóüoþ î:¦ò®7£‰Mb\º‘ÛÑn‰»·Dã1ÏJÀœlˆF7NÃ4Héôº{ßétì~ èÌËÁJ±±æ²UµšlNÌTT¹·Œq¸«aÉæO¡$UªS¾'ž6°1—KL ‚¹ÿá)Y”·Èf‚‹!ÀX?”ä}0œ;wÎG•}Ð Ð$ï¬çÊ[bÙЩÊÁHLѼz‘åZ5(ëU½kZz ™úÁ zºÇ!O/È¢˜à-\Pz@Ùr,÷6x ´ˆªÎj4,0äq{½Ú<3(¤Ê¦µï§» ð0¹9n2Ï»Œöí‚A`" ½7 ºpgÙçûý¾SI·‚Ì›·‘ùììl§ÓY^^N¸¥s¹JÒ;!g FaUଞ”QÃõœM c’»¤0Õ XUáš”UÙºÍБ„ºƒjí© ×6,àÍï¿5ñÆàžgܺÝî…^¸°°PÅŒ8R\%?Åw`7Uqö’[šÈ›7èÞ’‰lBˆÌÓtΫ9\·Xïî)Gv† Y Á”­*™pÿÜMÁºÑB«œ_YHEJɹ«m˜®p+¢Hù¢Hâž‘ º–Ö¯*1µ‘•4yqð@’#]&;XV�mþÄvËά­€À @m{§ÉFHiÅ3NkŽb^ªÓéÌÏÏg‚ÇÞwÕ½rBÉ£¬Däs%jÊu0°>¶­ç(àñ;\Ù5£ò Ùáî©5AðΕ³ÒòDöìÙ}UÍí¯r<–à8k1Ýì=N2‹‡±÷n·F=Ê„†•KlvôÎbê}Ç\žeã �x§#Õ²ZþdÏž=™ËcÂ.@¹S¶”)³³³N”&G©­gC˜tùï ñƒ`uuµÒqGÝÌlŽƒìŽv\ µiL¬°£BoÁD·p²Û{½^Ú98Is'Áî8ñ)-ÈÆøºùQ$Ŧ–Øi†VSò 6(4ù\L’Zª‡J%¿ÉXh…ÐZ ÓáÙ-h˜È`Óh¡ÄÌ=w*R/eT�¦oÙœ<%3ÃJ§H$:4„g;ÄØÌF«YÒE.šÍïÍÎz0nì¡]£ÁyšÆTyâfc:ÿÈvoÂÉŸíÞ §'OåJ =ÓÖ5I2¿> 3¤ˆ½î0Ö¶¿Êa{{…†¶Ç³D’θg=ÚJ–Üå0X3'f%äü7r^V†¯äËÊV‹u–¬›±@Ôn©•RJ¿ß¿í¶Û²ŸÝd¢Kì¡ÚË|j×U¶jÕ”My4¶bÔ9Éï *VÌÖ®6èÇͼGaö˜òç‚Ït#ºn¬ ¼”`Ò»ÿo#º2øc:ûf"صâž&@ÛßÌ#Š•ë ©@Úo_<’UY™áS©øP=08̶ZO•œA÷°”xÕÚ3pœj}}þ‹‹Du¡´0E�†`ƒ·àœÍKKKt‰øM°5è�ÎÉXcÙ ôiÌÙ1½…°šÌ.06K¾EÍT6} áõ­Ú{Î ¼Œ+ûj/ª,ט„Vö£“ à³= ÏâQ8â]k;ã&BXgÅk@9PiD'ï1ã2¬ˆ ¦o¸�|?©™èm+ÂÈt‘3›?#ž‹ËC;³­i ÑÙ”ÿ*.ѰiÙáˆ3†EJ¢Íùåóѧ­£µµJ=ÅR¶êuæœ2·‡�ù§OlELM“² ½g¿N¸ªíä®�ÇŠ«j¾o~ çQ*çèmüŽqü¹¥íl8Ë´ª¹¶Pò\CxÔ—?§2À=¬lÊÛ¤ŽôØ£)^µ šÔ=·ÒÑ*ø‘`y:¸š˜v­ÙD\—Ëv‹ããfXdšPa{lKa™ˆäÞ~•]y’`Æ‚„ÚðàqC91CÊ uÛNÚ`COÌÚ¥ëÕê2ív»ÛíRû{GU>ÖEž•/@#öã"�¸÷syJ²ø`hl‰‰Ùíy¯jÝÿ`hƒ<:×cj,‡­ íënŠ—ã¢ÙP´¬Ù<.’µ1ç­æÊTÚæè#‚èt: ™»aƒÜ!°Œ L$°È°€4˃3bãÁîÿÖo57ŶaŸ»¢R£ŽáÁMëË}š"¯‡*'°¾©ÛB$ü°ê¬®„@Ž»¦ZYzÃÞ_?³(ãXQy°BÃñæ1*T<çÏÊ¿ÃàÇ7–èhZp†R=%]4.]QÌ1•ÈO»Ý®©Ò˜:#3háQïYz<ÉÃhAyÏsŒP9å¬ÊÔïByG÷7 ŠUþh+ÎÌÌd¿T¶­,§mÄÖvªœRúýý_úÒ£ƒ&§Óž”ª”õáðP«ux“%ÉÀãÁƒ÷íÛwË-·,,,T#ÐÔì®xXñQ~Œ*TF1�‚³:ÎÊÊJÑH)Ç´wG’u¢lBŒŒy.,>.ñËAàÁ1ÏÁp^¤ýÈ¡Æ)c2hΈTîþf…P“‡Û¢~¶Y&’oz?ŸPWDþ’Æ›iTŽël¹4´*£eθˆkkk4ØÉú ‡áæAl\uÕúÓžÖþèGמõ¬éw¾³µéšGFSªÈ'©º§¬Š47y¸ù´1gËá•DÝ Ny Ÿªæ)ØåÁúâÖ‹8+]1ø¡xÞ«RÄð̼$]LRs†žê–kКsüÊ+¯l4_ûÚ×ø©YNÔrLC‡Ã ƒ$ ê?- FrT¬6ç4y(µË_]xá…kkk‘ Å4‘híç<ˆ¹õ4¼¾";sÞŽ¥1œáo«íoÀ­È¯a»°µSÊ©S¾ìeššj6›ÿuy¹3—RÞ×j}«Ù¼ßhôùñøÍb ä ˜½è¢‹î¸ãçò.ÏY­QQ4ò˜à®†ÇDyóÀšE| 'i·¤Ç˜S�°«HkÈz5›‹{NÆJHèrIÜózݰãV"àtþpyƒʇr2ÜÜ7šéóMÔR””M‚‡Í‹ævm! }ιaî$ü«Ñh´ñ˜ÇŒùȹ¾0BCƒg?{êo´$l‹²UºÍY)ÝYÚÙ z¹côeÓ‹Å %GUž5ïλäqóÈ ,S‚»Ï­H•M…#À|²X%üÖ¹ókkkwÞy§r²†¿üÉu�(¢ “ Ø8ƒ¥eLÛ²7úZ¹ßºGµ´´DHc‰?”IYÀÄl„_¡t&I¢j¬z½ìÍŠ››èU1 íè㕹r¶çëëÍæ Íæ“F£îÛ·^Jouõ‡ƒ¹ñøýÓÓ66›FãöÛo?räHf2BHVHσíñ.ƒ×•c…6)UN5ÝIòBï’ßà{åA2IËF‡ _q— ‡¯å|<t Î2ì–¾ö̳²0ÉFBpäΣÝfìðj¾ÃŽîf¸ùô±È•Uu{ +Yéuø#?2~ÀfßúÖË.»l8ûàWðû/}iûå/÷ñã,zcöœÔµ$7Ïâ±ËmÓ²I` ðA\0qÊ[åÌ,pÎY‚q.€&9šâVK£³H_à"€§ªé‡q>â%c%C“&òÍ“'OòL°ç1±›\,úy!¬_ew%êlo«É[jº6¬Ñܽd6Ñ5À“4rD»¿{FŠKOÈOÐAËó¡|(˜Ó„±€xVr¢SÉ&íôr¶ç«=ß<þøÞ½×_yåmzЧ.¼ð ssß;Ï—2LÄ×ï÷———Ý ˆ º E`¦`k•½qEð7;N¤e*Û.*b`“=LWÉô-oTv;ÅQo§Šiœ\xá…_|ñô¦{[^¼Ûí^rÉ%ÈX­¬¬¤j‰«ŠGðh*~*5ÒIs*öFr4€u«IâDÂÁ^Á÷UÓËæ+ •C*!&é*ÉF£Q®¼rø„'L½ûÝ»‡Ã'=éIxÄ#ºÝnëSŸj}õ«kÏ>ÅóL›ˆe™¿ëö/ýD—Ó&qj>UHå^LƒªHîx‡ƒo´!66¿8Ê!dÛ¤a=*3ÒoÄ’.:4°û ¡Xh5y}5(# •�‡{N<å{EXÓmEèmt_À<ˆæ—éã¼ µ»¥©·l\¸¸AlF‚òès‰÷¾R–à®Õ¨‘,G›÷J(2d'älÛ×ËììmßÿýÏzö³Ÿóœç<ö±ííÞý¼Nç7»¶r±ºÅ8‡T ÞJô0ø² ºX”ö�‹ƒAÜœ&éÔA{©a0k%¯ ÜOÊ_5]ÀÐrÐÃÙ³gÏE]ô‡<äa{ýy²­ÕÕÕ‘ XdWøwH„‰«ØF/ǵ¬bj§Éî*góû—ióBËa–3Gy¢¬û·D¯ÕÕU؉Läð”ÝñÞØØ˜ºí¶©}lãgvuzú“Ÿüä—¿üå~¿?þØxèCw¿ím6âl4½^¢|¦‹ –så4¦ËE¦÷P{<Øøöo÷ÁǺò ³çms ôùb]q¶$ÆXFÈ}~Üe°Ì¡vTkÀ3Î<Ü<_Ð0‹ØT¼›(¾°n=Í­†0rštOÙ¹ù_BµiÙ |´Š hõ‚.D 8D $ÐaÈóÓ„2À7^${Y‡n·;??Ïs·cº1ŒI™.tµwHÒÛüu¯{Ýë OxÂcûØH Üzë­Ã~¿,/{xäÅs”>iÌŠ� Ùp¢<²nÜß^Nñª�NI³�€Å'•N*/delÒl6ƒÁM7Ý”±g·¼cÀœ`)žÅ3fñÆìp7Ÿ+eÆ„wÂM€T"Ä&ï’çZÁŒÍçÇ(ßä0ûdîÙ¦ðàÎÔÇ>VÚísÏxÆW_ÿúéééµÇ<fxÕUÓ/|áh³DŸÍæ1®º<i 8‡©¹¼žpº›±oßúÏÿüh<ž¾æšÑw°l8FI\8µ‰.¤·>•Š„ÌÝ÷IM' ]"°0½KÑc¶Õ–[·uäÙÇ"´.Ÿò†(@a¸åÏù\ÈrO}-`‰ ’3Ê)_¤˜ ÏfÁɲa¾NÐ"}¡‹éÉ9g'\06 ïÈ8DnÎE]tÿûßmmí†nÈ73B¤i'bgœ”bÀ°r¶‡$‰ú™3g–——§Bl—IYXѽ.íòD9Rñ‘¢ÒçÞ½{—––r|CÁ´š]j ?¹›ÍZ÷à‚µmýó‚v‘D¯ÕjW333Iσ„XÙ2w¨ )ÿ¡ÑŸ4¤¡ð·pCXI>í¸ƒ‹•k¸Z?fñU㴠̢Ácxk º¾cm­~p¸´´òò—w>÷¹+¯l¿ùÍS›Ç®!{:dö?fÔms[å협ôuƒßùö_üÅÔÚÚúÕWÏüöo—ÍÅó7I Æãq1<ÆK½X%Âúq†ÁÁxÛ î®»A‚_'÷!œÉ$ûÖb`ƶhÄØxm ò[óš¿àPjChœlŠä &;+6ÌŠ²H«1[óúX¢LÒ ´ÁÂ6µ¤RT"fÛ/•Ð]ÔƒþàþàáÇo½õVs‹(ÑÌrDÂÇM»%émþúäÌÌÊéÓ?tâÄ7úðG>ò‘|dåÈ‘·./ÿF§Ó7¶šl"Dϵ <O=ÃÍ@ààýû÷?ñ‰O¼þúë¿øÅ/ÚFœ ø2sǮȿÙídšä¼I”°‘®Î�Š"ó,úˆ»dvìp¹Óé°¯\6ÑSõmá(ä|€à|°Â(*ìÈ$sp™Ûõ¤›C þ¤Ã]ÙdˆQ!U‡f' ÄÌ?ÿs)eíßý»é×¾vjÓæžWŒö8v¢¯Š¸Güè‡1—Þ˜ŸüÁ̽éMÓwÜ1¿ÿûý·¾uö/h,-Ñ„ãÊxËÖùG»Bd ²1„òÙ›P}Næ<eF‚€‰|inQ?%µ æ“.T‘§²ÉŸ¾F£Ñ‡WVfF£ÒhìÛãq£ÑX)¥×ï7Æã¯MO?Sˆ<ÍìyÈ]e˜0@îRùòQý8`py–άÆ!ò›ÁÓ¨;ó¬1G¾ÚmWîÞéÓ§ÿñÿñäÉ“çÎËÓÉ~¬,¶éâ–VŠS;!g{¾VK¹µÙ¼êÿpùر3ŸúÔÁ“'iuõ›¥œ/k4¦d KR:d½‡@Rm1 ›5zúôé}èCKKKH3UR›fÎãðžq¢Ê5ôûý¨FæP°ØŒ½M™üg“‚™ ëzС„™ôªù“j`‚¢ 2d“šÒuµÇœ—ñ¦ívµß"]…á ¯_ Úíö¥—^zÉ%—|ík_³Y¤™f”aUÇãÖç>7ýùÏ{èÝSŠˆw…¨™n{ÅX«|"ˆý&:/¾xð+¿ÒþÓ?½àìÙ˾뻎?¾ñ¢­¼ð…sïxGóða.#ç‰4Š Ìòý"—<`F¨’ú¡~„*Úä=¬@ª„G¬·”pbg„|dî‹ìD)ƒüܔ̌Ç?Ùíþ@³ùèõõoÆ¥\?5uýôôãñl)áF{¿˜ç‚g \§14[PûÂø°¼7ù•+<.MÖô¤Åfâ¹1Ζñx|ôèÑãÇÛeÑ[8Õxò6òÖvBN)¥|ç`ppzú†={žñŽw<~4*¥üe«õÍfóIÿGé¨vBŒqJX¶ ä@)1/�&ôáÇÍ%sã§šA³‚†è^@”d Ù û5£p†kp&Å®†ðø¡Ã¼¾¾žhaûƒÇ÷è–M»Øô3fQ­nW‰ Á>7‹¸Å-åTê÷ûÞi£«FlGwÝûÐÀŽ•1 '–pâlÜÒG‰É w;mo&àТ¦¦¦vïÞ½´´äÛáž=™µµ}ûö]qÅ7ÞxãñãÇËêjY\ÜØ¿êСN§cX)íŠ\@ªqÖïâ”ôÁ„v�Ÿ7éâ‹/ž››;yò$lW�´=&[’¦Þ¸Ù%Á>žÂaÊÄú1€HR4=míùÝîí33ï÷ÿhyùÙóóÞ8žÜªtwεü9ë‡y²êà6Ó°ËoGo’ê–©U[1L²™–›ŸŸ_YYIåjI=Î.³±™Ä0ìáÄ‘¤gÕvk¥\tÑù½è_G£Ož=ûË»výÌüüÓfgÿ¾Ýþj«õ7Î6(RN‘8Î|Bt:ÙÙYul¦‚**°ÃÒyÆÞÑ~n¨¿°b@Qx)cÔæã �V Í´Ž(Ô*ëå" ¿~ÙÔ>(2Û¶ @Åa5ƒ<¨Äª‘°ø'¸K°Ò aÛjª;1O/ÿf<»”rêÔ©/}éK°°8 ÜàåT"-õŒ=Ž!žN‘ ]¨óPJCÃ8:/Òh4¦o¾¹¼÷½+ÏyÎÙµµ›nºéäÉ“ãñx㕯løÃ/|Á,j;òyH…”…Çjm‹J`Xé”<߇>ô¡O}êS8�¡ÎGmY(�®•Qg±ö3'Ê;˜„EãÀLJ¢ Í'Ÿ8>vöÄ<xp×®]Ÿn4~yfæ½^ÙªvèK2’ØÈa`æ·SÓVñ À*u)Ï–ÉO·£RÑ 0ªód‡Q�Ù½{÷¤¾‘E}ó÷îÝ»k×.OqQž²©nwŒ¨·ï«Û=þýßÿ÷IÁÒhŒ7OÆ»ªÍ#žr– S–ûô¤‚ §Ó’©$Î<FÍ‘¸…õz`²›Ê¹ûQH½žÎ¡ÁN^S…Lô­Ë¦Ðœ'{:æNN u8O4o­bþÀzò½G>‡i·˜ Pn&AHȯe«~”¡í�nÜ.N ‚E_ W0ÈHWjÙ=£Îr ”MÝâªëî{µººêaá\dû[ßZûÝß=ö†7ô_üâa«Õ{Ë[¦_þòÖñãã̓˜rþ:q²VÙ«meeÅ~NÌ*}ýë_?yòä©S§ò¿pî�Ö§bxÀv׌ǛÃúŸÕ¢ªtÛ¥|g)K—^úôÿø¯ºêªO}êSüà¿´°pÕÚÚ—6£)¿Œ­¢½_ËÖ!ÐèQAÈä R©˜DGc¹²Ck¤¢¢äqZS©§I\"¾—b·ÒEµù¼äóóó¥”(fÑ+ív»™ârÚ·£±¶Í_®C9 ²©Üð@1Éä"³6+:|Ùê©E?1{Ø.ñ.G@Høý²)«îcŽ2Åøúù¶ý ÛA•m×öUhiy#}š‘«âÝí³ÉÝp1Äèñ¯jŠRü!àXY[&}¦kMç&ЛÜV%Ü4]cô;™Vƒå4?Ð8¡A31вU6&¿Ì)Oõfoi5ç‘0&–ƒÁèô驾ðôóŸßX]m½á Í£G›500.%Э1œ•ϘîúÒºÅ<¸Ü·Ûo¿ýСCD‘|¢È|™²•e–Ûb†te½Úív4™äi8Î31Vzå"óŽxàxÅW9rdnnniiÉڶǵ٠ûM6,ìù†&à´E:î²( Øû\†¹vnæ•RfggÉ{rß²z£a9> ¬mÍöÔ©S§ª …&w¹'Õ³Í!‡´Ú@[  Fá[@×I™i¦Ì<VÇ+#«œ*;$Q¶œù?•ÒZյ͠ Íœ×VåâwËÚÍÛE«à¶\ö†+*z6ÎéÜî¢úaósbRådâ5Ç#‚bÃw7Ѷb€ËG|ò¹^gR7Ò`ÐTNWon!X—Þ’¯^c ÛM®h€ŸR©=:sÍ5Í={7ß<Ò�`ZS¤ä| &9Œ Ùé<@. ¨Ù1dK œîl¹²·­FnE~ÙwíÚµººÚëõŠl :R²²¢r{‰ÜdQÃápµ”ÏŽF—ßrËG>ò‘›o¾ùÚk¯=sæÌ“ûý÷NOßwS ¡[ªnb®<#Õóóóá€Ñý²Ù¶gN=2lâ™÷W‘›Ž«"î$•åE]´²²â›V$Ë]4Ì…yof#p&Xš1XÍ·V¢;!g{¾(„mmR¥K&\ ‡ÃÕÕUÏ…ø©Œ ä0Xê· mŠ÷6m0CÍqiû²éß ¦ï$+óCÌ|pÀÙâ—ÿpÆ0t®?óì>š'‡ÊVé3Š>)ý~-�¬¸ó øÜ”M%ãT$ãÖs£æ¨¼{Ùóî(Rs¾ó©)àîѳ¤’ª¤µæŠÅ^¡ä¥Fôã¶Ÿ·».vï>5¾ñf³9ÞÌÐÍûÊí kÑÄqÈýŽ•ÿ;ÿé(›zq>õ( (¬Fê–§°k×®ïþîï¾ãŽ;n»í¶Ê¼yÒÓ9õAÑ�o‘Òj£q]«õÆ'~ó£½fnniiéÇ——ouõéóóW÷z”Œžm�j¦ÿÇ»‡ÃsçÎ¥&@ÀBÐT{›sµacEVöòƒ¬Ï;ÂÓ±†MÖX˜sÍ5é·q·sÿ!ò@£uè¢Õ·r¶íËô0Öz50Ï!›µËè%)ƒÉïÖä䥬v¶•nAhÇ -, èL¾ð%ïR2Ûª‚š¤ÏÍmôö¸fV09cŠ3KªÐrW“í—ÃŽù! iDeÿ‡ œs—l¼“Š2çðSÝ%Ÿ)Ìz õyÌvoµZQiÌ­6ù :H E£…4ºÝ�à^9ÄÂ!k¶Ã&¨N57jë\XˆmÔ¦¾ˆ+W¶UÍMœ ;æ2½DRbý ÌLàR#†9¹¾¾~Ûm·¥?dð"üêÊ&Wùw‹Z–r¸Õzf³yõ©SJ)ïšúONw“tÍš¼dvvëjqd~ÊVE(FÙh&%±2<kD2½ÚDXŒ¾�� �IDATÀsÊ:Y]]Ý¿ÿââ¢gNóŽ.Ä=dʶ qÉîº`€ž€¶Žx…îíÖ\‹˜ÚëêS2çrž®³T3ļ±­äèÈAúC¡`§ª.R~÷ÉóWÁÇ’;g¼ÎŽÅ©i,ËÉ’’¾)nÉp<Ñ^Ê»g~­ÙlF¡ ¶Ç(×úËúµœã|^f>˜!e’6/6ÀæÛº „ü#Ÿ1ÏŨ=ç¾5`²úóÚ*]δ+òF$˜•? Xy¬(ƒ‹L<=½‘‚Õ¨=õ¿Ïƒ0gŸ’о9zÌé§ø([í68sýj\0%'ÆÊ¦és¦¬X´ùýv»3• 2 xq'j 3ÐÄþÊzûש©WözÙ_h6K)—7¿5”Áà‹›/ÅaM‚0ZÙÔÃÑeÁÀ@3tAº@òD1Á9“±e#V`*[•=‰‘-Æ]Ò Êí¦7œ[ gLÅ4Ô"M ³ýµÓ¹ìÊ@x׃ÕkM-¦ÉÜæÌrÃß Z&6´öÀÛ/…9}Oû{|ÄB2?÷3ª™«$ÌLú®Ã ÍéŸÇH‘˜G%Ée%ÿ-Ђã¥D›�UÄ0‚\.»èª äì {°�~Kç<Ae¨ÓCDçØ²–><ïD¾JnÕ5ç:Ü+d^ºyÜx xìÆ¿iD5Cc6„½gLÖG¢‚8” eÎJ�Ð\ÎDW],`óž ñE *¢Ýn÷ûý {þ̌ۙèwñÙzD׆U¢ˆKö’N‘»Ts²†«V+˃°—ÜôG«î`®çĉ••G /™ûC±n-¾Ê7Ý�L•XíÖxx¶¦!1Ƀr&à4§ôñÌ£5Z»œ}Ô¼¯›~ÆÓ<uOvi§B®ĭjea¨"sÌ-‹£Õ‚FÖlEBÃ2ô!*娊ZÊxQÐb£e«ÚUÙ4ª¨M¾Qe«Õ›}”­®=�ä6¾5HìGžÆU®ôZ¸ó9ÝàTŠdZÅsì\@5Äš[š‡dŸOÇ'bH–¿5kÃ-"–S‹\O >•Vû.²g¥t¦éè@î9iOn¡ñI' E7GsCs¿{tAk (/ŸÅVU333ÉɲƒffföíÛ·ººº¸¸È¦Ëð °ý‘Þ!))Œjð4"GÖ‚}Rä•×××ñÊç¾”ç‹ÉÏ@wy@”¤äµ&ÑXå:ùœÉ{©·,Ʊr¶-êxŠ~”“ [ÉæÔ(›f'YwÃyÒá£"†ùŒó�`‘e,ÑΓð“FgîÜØôÓvÂ^‘]ªj{¸)’z«ÛíÎÎΖMƒ¤ÛêrßÜèâà á׺Ÿ\6½u=dSY°JÊOÉ(™"òƒ#´S!åns|¯Xlió)ÌÅHÞêt’q ú~¾.ƒ,€d—Ì­-7–‹ŒæÒOÎÚ5ϸB†Y™UéSÕ¯^ö– Ì ÷!kƒfƒÙü>a ʹÒbbŸZÓ .eD š¼;2ÛfU˜Üh¡L_9ZvÝn·ÕjíÚµë;¾ã;>|öìÙŠöÉõSƒõzË¥´K6ÇÃÍf/,å©ÝîÍí¶Û´y^�¤´3MdiåÖ¹›ë Çb£±„±ôìì,+ÊÝ#û¦#f133SU±Œú¢L±ÓËù7Qå°âë}Ê3Ódʾ `mÝ´=êhb±Om¯QÔˆIs8F«2Å:f•°.ˆdˆyäËý‹´pª±J2qo†ÃáÅ_¼{÷îÇ÷z=”¸ªÞ•ã )³-&ie .‚€ô¤Iȉakâ´…Xlx•üÀnC<²Ì$’�Âô³Ì¨eüø@BÔµB©Œ••@«± �âÌþ¨ú4àºÄBÎzniâq)¥×ë±¶+˜.1Ô;ìV€Ï´µÒ'‚Üîpå¹IÅiaôg].�5»9jX©:ƒ-Ÿ°¶smçÏŸÿÊW¾Òï÷y¾ÔÜùƒÁ Ûlþq£qs«uåÔÔãF£áh4Þ;5u¨Ùü/Ãas³Ö‡†Pjpƨ“H¶ˆLPWÀ0Ò’ÌÃE€ ›ÑÊeÇAšÛE‘¨ïîÏ–ÉñNÈÙ¶/w;Ür,[eZ8å'Ç6­ê0°ù©‡Û-bD%µSxÀâØoØ* ”Üßô~³Sge­$h¯Hú‰­Â=It9|øð}îsŸ˜v:thiiÉyœ‡„ÌUã°ìŠçW¬1ÌyÁ'&A…8T$ßépU¶ÚŸ ÌФÂô+;j.¯HÛf-ÄñlïDÊê(‡Ë�Žs×Q‰ à·åò}ô­õ[UŒÅ·×ÝGSy¦^–¼^ñ9SëT’-ަä#Xi9++É2ϬàEwI˜t×!Y »ÇŠQ]VR@�ŽA$1YünÊÀpØl6_1¼·ÛýÍK. ÷{çÏÿ»©©²µSY1Ë59È&·ÑO*ReSxü`R7ÈÙŒ'ºHÊVZ·Ó¶ae'عæDÈA†tŠJ ¯›"@ägÊæ„vе³g¬9Á ÈᢉbÙ4”¬¨Ì, Xõ–Éß+Ñ·!;6Tó}9ïˆÍ½^ïСCwÜqG)e~~¾²D/ò±XÝmËI9é[Ú$@ï±J„.¸>ÖÙ¨Óöà¡âf{>)ûwN&"I8œ”@øf´‚¯Š‹eßLW«®oÜc> Awh<¾êKâ³0 ‰ì ãX »t¶•8¼ Ë UÆ£¾æápØï÷ÊäUCWÿ{o'ëYVýÞ5Ï]=íy'a“C¨D^&Ã(zWQ1 ð ‚PÏ^õQ&5‚r</ˆ *8€ HB $1BB†=ôz¨®y®:Ö®Vß­_Oó¡û¿M§ºê©ç¹ïûº®u­k­íÀ/›…$?5 GÆ–‡^“Ôèd°AeµT¼Ï�õóãñ‡Ëå¯?ñ‰×\sÍüÈ>|øÚRéX2ùì²J§Ä‡…ýæGG¼ëÑT²Câ^“ëd2QxüÛ9bé0 xš{#¹ò ×]úÀkz Ùlö’K. Ç/ÒÁD·Ãý ÝûEãºÎ~bFŒgƒ»2GBmη¦éíEÅ–>Qˆªø(J‘®ºŽ¯NI½›¤œ(ª<éCâÌ%Ÿ•0ž:uêìÙ³ÎÈÒÑÆýd TÊ-Cˆ|JÇ °ª-¯#ƒ¾Ï£ Ÿ¹Q>z Mwº{ÓX‚Ú‘ àl܈Otº«›’qä>#݊ȯ 6 Jþ(>øÚà©òkîªKP¿¨-Ð%¢µuÞë·‡ÑõDÚ-~†?Î……å^TˆP ÉUHTï.PèÓÄ’?7À#! !�(ßGz²j7–ËåV«µ¹¹ ÉGk^{çü¼Ôhô¨ÉäÜüüO½ä%W^y¥*øú§êmnèõ|žß;+Ð&#ª·{z‘ö-̈‹|ÌÖƒ:Ynžö!ìDtq~—¼»!g'{9!„Ç_sÍ5NçoþæoNž<Éô�c"d‚èp°¥IØ]@&È0nLKÙû¢ÀqBêµù½ ÆšúЏ¤ú="òël¡#²“-bðåº÷„:ÃŽn¸Ÿºfb@N @óY®u¦•ã ˆ¼KìÌ Þ ŠC4Œv+z9ýQp'Ym7yŒf¤€à)OiKP2zqÉó»½JØêOH嬤ˆÿíßÑ¿© " }æ®k�˜ZKPôe#Qp{„åG!Ø—ëˆ�y7Ë™·Ð]ÓÛEpA …B¡P¯®Ð|Œ¬IT0•JµÛm—ûó0@Kæ<ÑT4“Ñhcccmm­^¯¯­­õz½óÔüñ8ÌpT(lÒ—RTfaDÒœ<Y°àˆðaX_Þ</ç’¸) U7q "°»!gçµÑhÔh4nºé&yQûd89µ†¸T]k—EŠÌr ÞFZ& âÕ‰L.ÃåNæÚÒt˜òsÇefÂÁëÉÍifF–VRô-M×Äû4NèòÉ!M¢ ã¢ `>>N‹ÆO0i§®9ËœïÍÄDñÔ.ëà|*ß‚9!E® ‘o77ßL÷vÖ� ÞÛN[rHSeÀ ÃA^õ¡ðÜÝe¸ÆÞœèèJš@XQ/Ý3ngð#SÍÞ;çx ¾) Dk7#pÕ×°Õ ‰ã:¹úÐb±øøÇ?þÉO~òÝwßýå/'ÖÈö¦ßï7D"Q(Ðz6m­ÀÖï÷Õ:¥È !ük:ýŒZío?ñ‰{î¹§ÑhÜqÇ˽޾Éä¶t:•N'MÔŠD»²P(¸Íp:éBÔ_ää¡F ”êD4¯›é'ù¬˜?;—¸ö÷Ù 9;\èL§ÓõõõÏ}îsZˆNÈAGd»þ™&Ç“7ÛIÜg‰æºÎ:J@?<‹¡ŒÀ$ƒV3Ùh˜iÅ»`0•ÍÈ]CËMÕ@ÊúF»ÝÖ!ªäf>È×´n ÄNð ørÞùÄ¢ßï3­:Ì­é…F})O$=å×ýTíât>oÑ©•å#èN=÷ùÆ�Z0Æô®k‰B1ŠJ÷=BGT¢n·K¯ŽÒ“Ë~¡¯¥H”6òpä#ÂĆ®xGŒÉ¸AŒS©T·ÛU1Aî°!5"÷ÍU… 88ÂÓ.&r˜ŸŸêSŸúÜç>÷ðáÃwÞyçêꪟàî¼åÅЛb$a”é‚ïÈHÔ¾ú÷Læ'ƒ}wÝõž:%SöÏw:·%“ßH$òù|fÖŽõçy«G£þ.Íÿ"~4OCòfƃ°K˜}¦s·@‚_TNyؤa7äìð±¤Ùl"HÉ¢q„HÁEп7ý¼ááøZ&ŒÓ{•MGGƒSò!&¥ÓéR©”ËåZ­ǽµTÓªGhƒË8Š$}ÁôûýV«¥Y–ápˆ(:½ÂúúºZ2¥R)‘Hˆe%òÕj5“ÉlnnjÒS#xäSÅbÑ-è!ž¡½†‡X°ÑT0 >$,ƒÉŸè¤æ¦Ñ×ápÓ-òAˆÈ0Ã}ðÈø§{=øHD4áèl%ÜÂVŸ·Èd2 ßÿýßßétn¼ñÆf³ m‰þSÔÆ'7‡*éŽD^7{ˤŽÕ»�ÉÍ„Á免S!9“Óû‘î»á1ØwØc„"ç$}åÍÍÍÛn»-“ÉÜqÇ­VËAGèF–ÌÚò ÂÓÏóÎd2¹g:ýÕbñ’Éäî•ý§.ÇÉä¯õzNg2cÒSjŒF£d:Ý{Îsúß÷}¹w¿;e3U<7•g"-Z¢¥”Ëå¶áúµ_ˆaô Ùì,Ý:ª:¿ížó톜,qØnâô) Ô¹®"îû9ئþ“¸öŒÅ8§E^G §­«³ ¦IKà)OyÊãÿø›o¾ù®»î [-n8]—9ˆXv'OžT¹¹ï€Ýy_*N9rd8ÞsÏ=ÎÆQ޼´´T­V5xO%´øx}UT¤¢tk"‹_·øD82˜Ä€®n±#œ0ÃVC<f6°g£Ð¼ÒQèÂwð IsázÏÜÝ@ˆ'‹_ÜVdÙöìÙsÙe—5¯}íkœàtJé�RŒ„>«HVžW? Òº#-_œƒ)ŸÏ««Kz‘½ ¯àÙŒ~ €ôˆûæc7ÑŽCÍÓ`“¹èE�c·Û½ãŽ;¾õ­oÕëua¶N­Œ63¼Î¢VéB¡ŽÅ£ýÎx|åxüúÑ(‘H\ŸÉLCF¯ï÷Éäp:­ÍR¬Qµ~zÏyNâ²ËR·ÞÚÅ+²ø@ºÛÕ:”YÒ�>3§yýFÏ]ÇŽk¾–0Hä¡pF BðDÖï,•ݳ3%Žk˜»¤w®ãäxˆ^þn.L«¥C¦Ã\:G'4èH"š #³ÅÅÅC‡-//ûQ z»ÕÖœ.¥-`,nwœN§ç΃Ý�J¦óhuuUà›Ïù«9¿]ÙÞ9Óüü?Ù>üäâ»i;Í!˜gš7ä]ª9*€ˆy:ÓùŽ.‡åoÙU8þ¨­å3@|*æJ¥R«Õ>ñ‰Ot»Ýv» %šÏB²S0½;¾¼AHª8¡FƒS‘*ʧDtô=#¦/ê’.'ýÒ÷ÚvmD‚i­Nˆë*IUꈩ¤ nZèÍEô ÝÌÉ5ãõoÉån±>þáQñm– “Ÿú©ÉòrîíoO¥RÃd²÷ú×—ÞþvjY·©¥/Ñ/[ÜT`ªxÂL>Ç {"Ú£ëN{‹&”ýQläøÃ#D6ˆêøL»›ßè¹Jç’È´8‚ób ìʼn•·Þzë}÷ÝwîÜ9èÔ1~˜zÛÉk½ìÝýþQsd8ÿW‰D"„»‰_Ë磃UÓøŒG¬­­ù9Å÷L&ív»Ñh—s±K¯üOðGˆ¦##C<¸Ø«>¶ Z Ñ@;–;éÓ‘:ÑèÞG ÍL4{a¥ûqãL¼0³<à@‡AÄ€*J4J¥K.¹¤^¯?øàƒtלáÞE·œŒ ÉÅ%ë9²…#yi…Â,˜G¹9u¶Ó1`؇™_§›/(4zKE¥ÈÎÕÈç|NÈI›$m¸º n4à£çvUN7pŠ{åñM#ýˆ‡¹y?ú£“ùùôûß_­Vs¹\û‹_lÔë­ßû½ìßèÌ~h¥ž‚ÐõüPýÍà„ƒü‘ž‹¸'¯O§*£'ØŽü,t4wÉѯh¡Eæ&Ž@(>êÅ!K’ª%â&’ĹÀ¡Îço´îWVVÖ××Eú„§ÏÆ�WÑ/ÕsæÂ´O.^˜ÏI$^>=}4 !ÜL~4›=“J}°Ó!«BÔsÄpŽ&h²Ð9òbŸ!…tÃJN:þ Š2‰ByD/õ'_¨5u…ß³§Õj5 ÇÁ‚Ið(#ëUþ€NŠ‚0ʶ³€Ü‚—§0ÃäÜ wp¬¯ßïûÛßi‚·ŠB´®9"aºñxÄLxqºE º*Z@߇zG&³™ ž€áÂÒÞ‰ða/gÝ1Sç n2±9ê®{]μ úÍô™¤'ÆÓt%\÷÷ìpEPAÅŠ<ÁSïÙ�$ž_«—_®¸"ÿÇœK$žýìgW*•O}êS›nJ<8~ÝëÒï}¯—æÎf$éV€( €Ž&©;äjk{Ñæø­U�u(¥€¯ú;@Þ 65™$—^T4âÙÞr irëÙHe$ábË: 3 @ÿІñ=à9‹„\$Ñ}gÏn"ñˆéô/z½)pÿþ§ÎÏ2•ú@·»ßd4½!D–Ê ì '¬ŒÌÕ£ih¡ËµPsÞ|vºkd1[Z_Ÿ_¢ƒëж6ö`0h6›Ng»Gxt|ûœ„}¡(~˜ê  ¾q2w˜‰A slž× hÇ£(DX~‚:½†{A´ù�§D“êî¬ì”} NúcÚÈчm¾#"±ZÈ,PÚ2³�Òáp(%gyÑhŒž”&i×ñhˆXT]XÆE2 dñ\ž¨çŒô*ZcG«=®×D8}÷xØ‹ý›ßL~þóƒ—½lR©Ü}÷Ý·Þzëæææô…/ ‡§þìÏ\pd0¨o1QÝf^kX)—Ë-//»$‰‹¶^ærøa«Ä»¤¤¤ÈïV9;öƒS“ø”‘\D’£3£v:i´“ÝáÊ#S?“6€Ÿ.!ê–Î]ºÁ¯Ðõþÿ}<~SµúÐE=nÏž'N|ieå Éä϶ŸNú䇎øÐaæÈॠɗG½'v�ô0Ó|d¶Æ“k@v÷}pâ©—N¦šN§ÍfSü:CqPb»îGç#®T*<kJRç;0ñ5ÉU蕳Úh qKÝÈ’øD^¯ðØ…ÔXiÎÐ…ò®'ëCW^:VÞhÏP¾³þ)&\¼•ÔÁJ¢qQgxë%˜æ +>O‡ (w|Ú,ºá0Eƒ  9íY‘¸þ¯B”ÊovN§Ópýõ‰¯}íï|g¿ßï¾øÅ¡ZÍýÑMg‚~ކA:‡¯àAųîv»FRŸ§ >ᘷ:ÌÆi½éë»u7äìð[¥yÅ&Á<„w,ý #‰C?’GÓ9EÍ?`7ÇpØu¾úÃÖ©cŸÝó^=:Zàu!„«¦Ó¿¼à‚ÿØ}ï÷~ï¾ð…ø‡ø÷µµk{½ÖL»‰AаÕ$s?˜Ü\ØêÀàº;¾¸sÚv;¦ ü°ˆ+’¹Õj>%œsÚõ¦|¢ÛûvÁôl](ðbðV¾’ïÓPÁ•„Lœ‘CÀ§V3£ê÷ò4NH.ÑPé¦ÈZŸyA6£5èêÜI?p‘®ˆ+¸6.ÓÇ£œäa’qz ”îÍ3rÒ+ÈÑÑq«=•&Üg°GšÜcö&“I>Å%³j‡£©Ò¶«Rl¥¿øÅq§Së[7Þ*•܇>”0)O0óhnÚ/Œ'‹¯àp8l4>hE‚6®'èD”ZxküW?ëvCÎŽÑÂV…] ÚKÑrìÂÿAœ€‡ÃjŽŒ¨}xÞ/@ŠRŽT÷,q†á]O,º�ô:I‚@4O~ò“Ÿõ¬g>|8™LÞu×]N'Ñlz¥¹­¸ŒBot:{_G�“Z²žûûÌŠ—‘á·zQþtˆU‘"‰6OÊ“å`>c^zFw’a÷"Ú^LøXYwÂC"zh«ëùz:‚ç°­ÞÉ}UOæœ7ÏßéTs0A“Õ [Çã) íªº¯£òÎ6Ä †º2íöiP-on280édÙ;ÆiÓyÖâÊRîò©ïÈD”zŸ}Fµ©÷9Ä#ÅãSœ1“7ßœ Ozþ=ï è–‚—J¥l6{îÜ9ì\¼ÎGÖø¯lr–"-XÆ-hιДþ+©ä:»!g Âàº.ïꮣÂVQ`"’ÒU 332#§úq‰'˜sUÝda|rL—]AƆ3ËabÕ¢Ê|i4*ã·ÞzëÆÆÆÍ7ß|üøñïíõnN¥3£� çÅÌ·L<£§ž`ë‹ÐøaÜ$˜5§’Yv‚óë #DöhDqÍ@xŠçìO²ì-í+8¡+CŠ@6MRLs8K—„…°·åh}s€Ò—&Ÿ æLHÍÛÔ`5ˆ èЄJ¹Oº§*…)©«#ð«í'©‹9¹á© ð ‰N¨wV¼w�ø°€…žã¾¡#倛×y?Þ•>¼Îæ£è.™Àw‹ÁK.ö¦¾/* ƒSÎ: Â!Šó¦±·ßn¿] Éé×GE ð”›PÜka0Q⻚­®MnÙ «øFÒ½sŠ6˜Ûå솜-˜;„wY‚ŠÌà ³0•ØÌmÐ_á5¤á‘ =hN=Ÿv•hœn')§¤ÜÇ[÷\ÂMœþ!„$“qçïþàÿß½{zè¡£§O¿½ÑxU6û¶mŠìFúØ*õ¢N€Ã_â¹úµ£7ž`FsµQo,ê( [ ômïD[wõöÙ)/‰ô¥Ä;r«oG9 ãú8½ƒ3N{`ôó(b(yûà®'.ª- ÎOg‚ £3ôÞ"ožÍ!Ÿÿ÷™Çí“ÁD9µbå¥YÞ&t‘õhŒÚ…¥e &7ÉHŠhê¹8˜»(yL‹˜¢ ¾¦`·ˆF7ø¶Ì„ë(§<åƒ\’Ç»b,lÀÞétÊ@ˆÓš}\‰/�òÉ´ëæ¹R‘3 ¶ÏÉîkßUh¥!¤*þä\»ý`g˰' XRîï/“èâàG$nÁÄÛ)ÿÝ@SM¯ÀðunÒ}éôkÆãßu×+CF_áçÒé‡ÒéÐï«@a}û|ÂkȤsý:ë••3¤¢ vË[‚ôÌ”oäûs{Èa°†s‡ÚÑÑÑÀ &(ðh)w˜¶s­kêôýéq�†îª 7AÀ¥¦£AEhr:Öuþò|=¡:fCµTØ‘8P0 O5“3Z ¬C·¹‹r&„£É3&PJÍçó~bú=qI=Ÿž¡‘éÓQ4´Ô…xé.ÛLW†Ë9¢i„­þß„UÊMEwØ_ž²xÕ¨§FZ�`è^Dž¾›Ù^üy×6yvì=š`©+~ OKH5º(ÞÍbì*IïüÛºÀ‰»ùFBjz±ªZC„•XÁœ³ÑD›-Ÿ`pŽl0‡lwp2›Ï{²gœe‡f"‘x •úd»-j|*‘HN&W%?0†áð›[}|¡Ä `G׿ðÂü‰ú"Rî÷û.²�¹[`”A«+-Mï/ñ+—á%ã§v»wf?É$.¾øâË/¿üž{î¹ë®»à™Ü÷†M#ê>¯co€·ÓÈŽð.•Qyè‹C—BñhˆA]gÂ[F£Q¡PÈf³{÷î½ì²Ën½õÖ³gÏr‡=þ9CŸ G™Q á3†Iw“S22¯ÀÅô'xú< `žIúŽ"m’g(ã¡íÊ'áŠö¸Î_ Zu5ØŒ>!)—3 L²Â£<ÒË娄tgÈ8èAÓfÛÀ^ˆuÂL‹Ð÷5ëÜy¤úšH[‘¯8%¢È¼�� �IDATÈLDt§²ŠªÝó]QèHP †ƒ¯Åä/vIDÇdÙ*®Eͨ@iH©H£<"º¯³ÎtdôT�Ê=Ɉµj_;7çoÕn·å6x~ºp6Ž£kc:•/u¾ºúêñsŸ;úìg_øoÕívѦsÄý¿œÔà>=>;M‚I6íÍj×ç÷±Gí+²Ø K¥RéèÑ£gΜqî¬ï[øž_;‰ ‹ÔÕ ‚É …™dw/J·ÝÖ[ôzF¥R)êC�BRg«@¡ÚvwKZMê,Êü‰;I5L©çp^À²¦)‚]PÀ•PÈÂVN¯ûý>ZžÃ¹Oe4O73”˜áS·^@&Œšç”#ÌsPô1†`ºNËÔʔͼ[©z,ñ å„R÷‰@õÊ­máNo;q'#ƒ/yºæµËýík;ü㉪sØawpEœO.� "b Ÿ§óž°Sƒ\Ö…3´ÜÁ÷!·ÐídÛëØ¼ƒ—…­îÞ•õþ'ÅÙàprÙeÙw¼cðÒ—S©ì§?Ýív#hžä]_™tÞ¹m7q‚@e†^…‘Z¤ÃF-å3ØÁ<Z´-‘2Oäúú:BÅ®pã@„\è&PUø°…¶†s+ˆ»îRì¨=i)ï8'à…Ù°ªÃnäÈœþ~ñ,ïÍÍMY[ºŽröh ‘GÛ1êAž@Däu[ƒZ E‚GOë;lõèt`Ùi“î’€BFp¦ë•ºQˆ¾ðôu n{{Æ*Þ¿ä5k†Ø Î.mŸÖrŸu¾Ð79ê߸ç¬?wwÀóÚ¾òN”ˆÈ©´vçrvþG�½ŸtNÀgõ0oAÚÂ"£1NÚæ£ê¶’Ï`#¥Lù‡ˆ�™K0]^xØœ‰Àô@ è}ùÔ:gŸPœO©S2±s„’Éäð{¿wtÅù÷¾7Õh$?øÁÑë^7i·“7ÝDŸÙZP˜ÜóÔéI´Ù}ØEoJ…™ îdáÓµüÛíÀ©fºÝîý÷ßï})º; ]NÛ‹ŠN*9°MÖ ×)zP§Û[(YvSdMíDÐô§`6Hýƒ™xฒ{èF2ÀúÁDPŽ\€ÜOùíÝ$=Úî¤àËÉ=UáËÆã_تvÁˆ ]UˆX>ºÞ‰Îº�3€ùRÜw±rì‹¥â;e@Íá:=,3÷«õv£§ PQ:v 5¨ß+’Õî2ƒ.í¡¢*lU—Ø 9;ÀXsçÿTð#"퀌Q©‹E¸:ÁW�Û>l†q€È&ÁÜyQ$cuz½÷7ª]ªÖyÃü9¼DäãßÄSž2zñ‹ËozS6“ɔ˽N'õö·wßò–éd’üêW‰yÌ3*té,HÍæLEØs7UïÓL"wÓ\Œõº!"•E$b†ß èCž:3ï‚Çë·BQÌ)N¸€±ºC5t':l(©{`@q² ½qé~Â}rÏôçŸn6UäžL–¦ÓÂF2y2™ Óé „g—JÄ~Ɖ@q<ílx@<Ÿ²ŠPe‘Ð�þ˜\¹œøç�Þg¶Ü1×±DHq¢Gº)QØj Âî�'„ÏFß‘…äTj;gáoÇèŸplÜýP4ÈEŠ)2‚JnÚ­M!n…$ƒ'öUK‘̼N\.—ÍfK¥R±XlµZ»UÎ7rF£‘ªN ©‚iµBòa¬Œ–)rN [½–}ÔÎѼ0sì&îÕ^üÆÍÓ¢k‹¤ì=!õÜÜg!Çã±V¼÷‡¼Ç@CEÇS÷ÙÏN_}*™,‹‹‹‹ò„ÏÞpÃð9Ï™|å+>¿¹™iG1ØM ¶›óßÀĸxWÌŒiz(C$ÔŽ|r¬”J%šC´Í &P›’BÂõp)æu8AÔ[Ž E!<ŸêˆÌêS³:ÿ‘9eœ"ºOã2à2Óé‹‹Åç‡á¢bq0œO$“ÿœH|´Ó‰D‘£ðì’¬F@r8@K¢³ I7]•–4ã™Nÿ ³bú+hø;«Ókâh~V·˜šPDÈ'0ðŸºRY¨ëâLþøXuúOš±ƒŠ7t?ås ¨,™“›'¡!Õ°–�=5›Ív»])×Ñ„ö²/*Õ˼âŠ+.ºè¢;ï¼Ó »!gBK;XÉwQHïÕS톙f{äKá$¥Hß7˜OFÄ)à#\e+l¹‡ÁåÔ#·oÙÞðvk·q-±'óŽwt_õª~¡»á†Z­Öï÷ÏyÎðèÑâ;Þ‘N§%8Nñ~÷y=bÏ`0Èçó¢Üàl­ÏOÉ5Óx4ýNIðgçÍ ôW3™LµZ=pàÀƒ>¨açÎEͤíæ+äìnàÑÂC¸³Þ¹lD´¤¤ÂFôâ1©®âYU/ê j·Û, p!§]LC8<^3ÿÎÁƒ™Ë/?sæL顇þ Vûºþ:ã"! ¾…«ÝxÑ{f,{™`÷éÑÅ£/a@†f$ó%‘oºƒw‘  z³=lU-ri]ÚŠ|qØ€ÑFso'&yqÍ!Ó:wœ_5À1¢HT£óA\-{äÎNÊÂwT°G@+ØDª³5™LæççŸÿüç=zt»�ÊnÈÙ¹=YÊ>Væú"Ûs1V3M´,=ÿ%…W–ÍñĪú"&õEØÒø1û 3 %.$œ9G`³x}À! ·59?üáþk^Ól4z_þòä©O?éI™?ù“q³95ᅦNBo£Z­^~ùå ·ÝvÛ¹sçÜ7ŒÖ…ýô¥ÀÜ= fm¹‰ð¼F£Q·Û fµÂáë29ôT¼Ü¤‚ô�Œ‹3D¸uJSݦÊ{Ò0“Ó°Ü PâÝxét:ŸÏ{ÛÁ@6çŸio~ç’K.¾êªç?ÿù+++ûØÇ~ñ›ßüíõõ`º dèdÖÞ$ZúNK#_Ž<§ØŒŒ“Ù5NGF7¡T*…ä³NçÆ_æáÙyeÐ#ð3šS¦)EåÏÿƒA¿ß/ ´i©/) }ªŒ Æ„OÉÈÑñ:B‹ç¯¬„ÀQÏãŒ"’‰åU®QM¢IU·¹¹ù…/|áöÛoÿö·¿½Sš7»!'x*ç]}ïs?ãhˆˆd¾-ES쎖{»r„=ì>›Ó¯ÓæHgšN 3†Zµ:C•ø ÑraRÔUé8óql¿Ÿx×»:¿ó;Ó……ÁWäßüæÂؚÑË:ÞJI&“~ô£÷ìÙsß}÷>}ÚïžI¡Â‚N”Û„0qV.="NçĉÑ�&1ÞÓLƘHÃáÇ+…;§Dx’VóIRšÒ…BA¹¶¢K>Ÿ»)N‹_NwI¤HÎ ª­™£ ¥!œìõŽf2>ýé×\sÍ¥—^Z¯××ÖÖ>^¯©Õ:!‹EÉãS6¹W4,&„œ¼îP›)®ÖÁÊÔÐ=H€ ·ÈDŸ†îi©Tºì²Ë¦Óé-·ÜâD/Â9œ•ž –Û)¹;É™Æ-¢]éc=Ô1Î;Õ=N¥wÐEJƒoçÜk„‹"éH24ÒÅ­ÝzŽQ'7ºu:% o9CJò±}z«Õºþúëq›Ü 9;u<–D@JcNåtig­6í:ð´`²¡N_‰²0–¸– Ü$ÜœÑÀü£v¾·¦É[1¥×5ñ¢Ê¹ÿ¾Ï™ûqËd]sþþÏÁ¯üÊÜoÿöØø»Ìñ¸^úvBD"‘èt:Ÿüä'S©ÔÆÆ‚ð:èÝ1ÿˆ8Ë£'Á€Ûö)n‹ @论; o®çC¦Ngà¼ë�5(r_æßªQTLˆ”\,umÙl¶Óél‚Ííâ­^¿×à ¥R)—Ëu:ð(ŸÇkkk«««^xáúúúêêj³ÙœL&S£Ÿ¹Q&ü2br]oFŧD½ˆRFÔx§»é.ѺÛÀ;ÃáPÃR0Åççç …‚< Y¨.@§ŠÞêöÞÇ<?¦é…Œ¹P…+øh——MNíƒúìqšÅ 'ÀÄc±9:âøÐX”»ò:ï종Ôï@0É®*Ø 9;o\GKÈÞ½{ûýþúúº/R³¨OèÙJT82æã™¬H_|´a-dÏl‡Üž’ÍfËår§Ó!KÒÙG¤qÀ=µœÕí8¯c÷$‰Ù?üÃɬïå—ÇlQŸÎ gΜq†(6'Þ¿ fE1ñà S*òíM­@éÉÀƒv[—0AWGŠ W(G&“Q¨FÌÔ›1> qáô· ¨år9›ÍV*•¼¹}ÓV~­'E¾ÂÓŠª¤fØ…^xÉ%—ÜrË-kkkŽ ª—óWéôe·ÝöOóó§OŸ¾ûøÅ/>÷Ì™'“?6ã¼/­0¦s\É |·ùT¬?8u>Áã/ˆQÕ®ÿÚív;¦±Ót:½¼¼|õÕW>|øßþíßî½÷^ŽH³ñMJ²]1†›+8À ‡,@_Ä{®‘÷’î,!ÈÞDqåO›43…·LPíºˆG_†±ýèÏF¢òþw0Þ솜-À“zÀù|þâ‹/^__ßÜÜtJ~0­I '7Ù.²̉Á±íì5‹}ÏG¯‰NèÈD63º¿ j>‚JIÊá©¢W<a{O牲®<» æ¡©Q wÒ¡¬ãžY}Heî àjW>Äqü¤ÞNgrêšê– σz0M ½èý~_\,o[©TDk. ¹\n~~^…”š^¯×l6eÆÕív)IõG–"餹"®Š—SRß”J}ôĉßÿìgÿþþûWNŸ~ê™3¿Ùjýx±øã3 ’÷AG’p*Ž-zŠîL›Ë)þªðk§Ž¤&ð©gWHs‡·0ÓÃÎf³G}Á ^077wüøñãÇ£¦¬/(”’éfŸ)µ)¾©êà&D{Ê­†\ŒŠs_ ’'îEÛs2?ôÉÀÄG ©'uUÄltª·&aµyÙDÑ Ó`ݵhûîâÀh·Û·ß~;³hxÏP§¹ö -Ç„Žg:yÍÎØ°ÚÈ®ÛÁi­æ ñK§þð ÓíviØ0‚ øãSº$Ùº£ðÚ‹øÈƒ'2²õÄÍw«?"éyy¤ Óáp=Á‹üQ޹„-˜¨ê `ÑÕUÌ?8À<Ÿ›sˆßµ«…ž¹˜ÄÍr¹Üââb±X,•Jår9ŸÏ …¹¹¹J¥¢»ÝjµƒÁÆÆF¯×ët:õz½ßï³TÓ$ Õ¬­VK+m8;vLEÌ¥‡“’áð¥•ÊëÏœyçñã!„Of³×”Jy›(‚‰yD·1b©ÑÓ¦Æq�~ ÐÎLãñ¸Óé ïG)�vêd oË9½óøÇüÇl6û•¯|¥Ýn»ºWK†ç‚Ê®iæU;ÿ‹~«³4ÝŒÜûíþAŽty2äÔªFyfú•"„œÈǪŸ$ô–ÂL‰€«BØòÂv›/ª]¿œ4‘R…V•hµÞM%1ZÏ0KÙgß…ó„TË]çžðnŒ ŸêÂT €zÞGý¾P((õ…îÓmîkë:ð¾RÙîþ›`ÉFOتüiO¹$¦UÓIçF;žB†™ßUJY`µÛm§ÿù”œ+n‘7¸ õ„+üú©x˜I„×ív …B±X¬T*óóó•J¥X,V«Õ¥¥¥¥¥¥|>¿°°P.—3™Œ8ZµZ­ÝnF£z½~öìÙ•••f³),WËŒQ]áp(~y±XÔSVr XõÏÙìK‰ñ`p6þ‹™¦ËO ‰DâŸfD2E1owE$=l&ARà !Ôëuœ¤½¼ &÷‰*vQÉ9+®þÆÆÆõ×_¯ÃšŽ‘s·àPD"ÜZ�B}އïÛM·ÓíQWù ¥sQ�Z§›ÃßqΧD¡ÜR+RKÒ§ød+]"·ºà6ää”°–‚©ºyøñ¹éíçnÈÙlöÛ‘""ìU`F¡h‚•9»Ó`8¦§Aüðî(dMŸ’:¬í q3j]� aÁ€4~ ~î;|Ç”®’KnŸqf „w`¸‹‡ÀÍ B˜Œf`G£Ñ£õ¨l6{×]w­®®FÔp7ª¦—„þ`0ÐqÑEU«ÕZ­V«Õz½^£Ñ@l'7D÷Gg¢Ï6±ôÈ\ O(¬*fªi6˜››SfïÞ½Ò`ÖŽ°J¥¢ûÐl6÷íÛW­VÏ;—N§ëõº¸ƒÁ`mmFq0IiP,ʵ÷U«De2ÿL&“0[]>}ìó.a›è†w1i\+0ÀFÑïib{ŸÓÐËe¯lD†˜Gí(j;4v(\JÎ}.Þ…Ì 6H¡óÔÜxÆ‘g€«—22åX0i�/Ö#Ók•餰‘K¸SÓáV;E“,--U*•‡z¨Ùl:ƒ)ê®…­2ç N›>Þ 9;ÜËqå"6ƒ·yhÓ‘70P¢$wN+ôÐ\<ˆVÁÉI¨…BÁÕ™"ä`³iÞPå¤@áÊGü…èQ®œ~OiD’‘FƒÂ傹ֻ {.—ÓñÚl6E-¥eÂÑÉ�bÕ–––î½÷^ÝL}Ÿu K¯J…É|}¯b±xðàÁ={öär¹“'O~õ«_¨ƒa¦-æc°øòù­v>Ð<ñ^É~2™ÔwTÏFQgqq±\.çr¹}ûöíÝ»·X,îÝ»WØš¼Syp¹\N/¨T*™LfeeE¡ëìÙ³*kÔLVŒÑÕ–J% õ„²Ùlsf+ÑN7<â@’4xVîÍHY‚nŽÎq"«Åõ iQ²c¯Gµ3:e.µ—§bÔn³MŒâèEy0CU悃Éê°5<*¸ñRÄ£¡¯M#yÆIrÉr³¹½` €Žr÷z7JÃÇ=îq—]vÙG?úÑv»íg•–KJœïÈ+Q8Ý 9;öóð$ÝÖA-Ͼ}›#»Óéã è»IPëu.K–5Å»ë21'èã¬r Ú?Ú~à$°_Øb{³Ã½µú‘|ÐmôÛ©!òjôÛëõt:ëÒµAôÒÿˆïõz7ÜpC.—ÛÜÜ®Œ˜ÖQ1 Iœ«ápxòäÉápX*•NŸ>MÏŸ4¬œó… åÿu¿jTèh“7„Ê}4`ÚÜÜ\¹\Þ»w¯^¶oß¾………jµªkc2Ôï«¢P(\xá…zýÞ½{777Å„¦9_*•h®è¹Èã�uxÀÞpqt¦¸Ÿù|~qqq4­®®z<&Í:¦˜�ªrµMxÞÃáP ®Ë/¡Î�]è^úÛˆãîz¯¬ÊzE49ÜzUÄtçéñ2Öƒ\>=Ð2?äe®{˜ºx®C[läÈŸž€Êwç6Fëmûä©‚ú-·ÜrÏ=÷œ={V[¦×ëÁ5çýCh‚±;íÓŸ×nÈÙ±*'òôõ1rÚõ¾P ®ñoð‡h>Ù§»ÑAŠH÷ì"rm¢ˆ KsX3:ãçk“kŽ€ä\2ãî„Ü‹ªø¨3§Œ·=¢q"²*—Uf"„¢}_)G¹lš»yØæ êõzº†^¯÷À¸#– QCðu«>·ÕjEþ"ÊÁuÜë$Rª^.— …B©TªT*ú¯jê”Ëå¹¹¹¥¥¥b±X.—S©T¥RQ¹£õqÅâHyOųb±X«ÕÖÖÖF£Q¯×ë÷û•J…²’X®¶<Å™Ó1(Ô��Z¡ë¦u²¸¸øØÇ>vee¥V«Ñ,a�Þ…hiÔ¹îªsÓ½×…à7L Ê_d ]¹¡µ{8x kP0‹Ü¬Y9LwE: lb—¸²§ê’Ȭ‰¯7V©›Ó KÍZòJÈÓÓ`T>%Š,sþDÙ W¢k󯯬×ëȨ‹E×`…QÓ½¸ülÙµhÛù^ë‰mÆNpGX*=ÅB¡ D:QT¯( z‡Æ)[WÜâ)jýQ2sòF’‘¸×Oq@¹Æ¹àã Ò³©¼ä²r@ÌNg K çn$q‘½+§Àÿƒ<fÊòòr&“9yò$÷ÁK×°¡ Œæêý�ÒV, Ãá°×ëAŽd(…ÑiÈ 0ŸÏ O¿ð ÕÀO$ KKKú“B¡ ŠG‘CñF V›Óç¢dS©ˆµ°°°¸¸¨Ôjµ†Ãa§ÓQåT¯×ùvJäU»“BØê:ÃvÞG*•êt:<ð€ÔÛÄhÒ]ft9�]ÒPèt:D#]ëÐ~o€ErÎT$޼Œzµ}•ŽF„S¡­çê…¬."Ÿkˆ9RíqÔ‰Å|}/ôÙƒ¹]¦Äç£ÝϛΜNEúí‚›H깈_DB�ꎤÑ×í£¢¿Ý 9;ðã@¶ëЄ™N ig¹\Öé Yˆª6Ê;Ðzq?ýÞ{­ íÑIä•BÌd­ˆ;�å‹wŒhQ”ËåétÚl6õ¡¨w€|Þ%by±]£¡t„sœF¬Ë”çU<£‚ü¹÷?õçÝn7ò‚ 3yø¯Ø4 ™èå£4²|°ôaÿ…­6Ø~äy~àÜ!}´„âÓé´Hh\pÁþýû÷ìÙ#.Àx<>pàÀÞ½{)΄­!i²Ù7,/ÿq³ Âî–¦^g#:@HÓþý~¿^¯×j5‡øççç—––„¼é}´777Uታ§ÈÍ2¨J9§Ž?î£]QÓRe´‹—cNè#ŸÎŸä¼†Q₹zèäø!ëóX�Gny0 zš£—Q"0ŒÌàq <Ü õ2¸ø€:ñµ‰˜¹öyíHÊ“…OAE•KËGÅ·À[÷סµã?Á¬§ &¢°Ýôn°ÝÂVµÓݳ“ñ†Ó–„‚¼FÛkÒ¥ÒZ¸1˜'šKn<ªO!M‹ šˆ5äûþ ¼I…1•\`GéÂs9 µÅCe(Á ³1rgVÞY[ m„§ôYžØê¨b¤Ùî¹h~€‡>d> VWWéOÐtÊ!oòMý‰:I<D½s«Õr]ryf¿•aT*•ååå,..V«U–——s¹ÜÜÜ\±X£«V«jºŒÇã3éôŸV*¿Úí¾±ZýÕvû¢YkƒWÊ>ð:¾U4”J¥#GދŇzHÿU¢ u<MÝîOŒÕ³öBÂꦤF…BAd\¬Z¹áZÑä¶ûâ÷ F-f ôE¦ÙtÔâ´¶Švim#‘•°˜ 0æJw¾)"é£HÑ@qÂ%æðª@ÆÆIá$[ fpC˜Ûs' ÐXþ.+ _ºS8sW)ÅbQ"’ŠwÄ{8â·ÄÓt‹¦Ý^ÎΓ¤õì¥üáJæ>¶¢}¢#U ‹kê1©ƒ+ªW¼pù^gEÙ ƈê"¸:¾©!8»5ôÃ0£Sø8o'8{•$2±K]¹©¶¨E0Á:všäÅ\aÚõ™Añ±êNM’À .PY™Ëåz½žßI¾Wتq‡ÜGÙ©ºuºcbd2™b±8??_*•TÍ5Õí`>øTWBXÍå>–Ïÿt·{t4zC·û±BáÇz½#6%νRRð.•J^1çr¹……Îûï¿_÷JXŸp/Fu·Û8 ꥣÇ/Ájut l_ÅœÍr7*ô}Ê„¬g4ùèö^첨8Ž}äÖù`ÜoÛx­C„óÜŽŠÙéš>= §ü¼OG&£Ýí5ŸÏÃ" çªh΋Œ6¸H&IÃVÿPgŸ³V•…poï]ûÜc¦ 2'hÞ%€²rþÿþ�äŠj>N éÝ¿h~ÅGÓyó°u$˜f,½A'×ûæ2Òùy ,àç E>ºÝÙéÎ$zÀœÝœ/”&ðjhH’úÉÌ“ É“Ç6÷ù¦€³×[ Ä<mTnˆ‡O‚1@“:|Ä6U3…Baii©\.kŠ“£J…ˆœ~tI¥RI#‘Hô‰÷”J/éõ.ŸLB2ùÈñøGûý ¯— ºäTõq+'Á«¥¤ÿtöìÙf³‰ã‹~ô­E‡­T*â:ÍH}_À+’úç^yáå¤[Xgt¶à8ÈfÞEQš„1žDÛÕ\eÕ{N¾÷‰äÞžn‰­Ú)PK\vÚÛ–8ÜTÉ]v¢Q·ÝÇKÉ´‚)øþ"£Uùè¾A�aó·åùÂYeªt{«x7äì0¶l6˜MèýjRö†Ž?ÄŽ(D\«?ª¥|:‡yr-PJÒ1àc<xPÁù‰Ü–ühæ4Œ ;«Ö € uø›E°‰KŸ…™¦O�Ð=fÒ¿BnŽþ­Ë}ÖÇ "F óáK˜lˆ…Êñ'VºÌ‰î¤Û™8µO*œ*¡ÔPÙ³g„Êå²Â„lÍ‹Eü^77÷ÜÑè‹ÙìcÇce•^ÙíþúÜÜŸonê�êv»Ç>�ÏMæT•ù‚ .FµZ Ójµ*ÙºR©¤&€ =5‡pù¾zdÎ8 ßæSÆ”ÔÎÓ[XX • n¯ mEæ›*l§ð² ©GÝÄSûªƒÏz[X§¥·ážrÜ|tͽ>fºÀs)ܺ6b§ûW9[Á­<ÝlÛݳ¶ þöû}a~¶8ÇÒ¥îÉ&}gåóùƒv:cÇŽ¹“Ëà#I;Ôó)HÉ(piÇ�� �IDAT`º,&|De»cSN„ C:æíw÷ø SøàfQâ€u:=:‚AÓòu5~*9¬x&…·#:ù´yƒMJëCËåraccCGNõ0d€Ú"u5À²}æI &ˆ¯ð›ø©TüTrj;W‹Ù&@‘ưHYê.è¦ÓiµZ ½€R©¤gQ­VËå2Ôy!ošñ¦Ý+z½¿Êç/?Ëýt·›þŸùùßZ_ïê^h´‹®L§ÓÑÁMA™L&»Ý®"z:Þ¿?ò©ú}·ÛÍçóËËË ¸(4Öjµb±¨¹1ñMÄ®4£Ž‡É‡x™‹V0pƒ›¸n`¡Ùl"ž¤üæÊv H_Ÿ¦ бó­ÉÇ‘9p¡eJ(NRfKQ’´´¨´Æ|ëE y¸‹l23jwúpž™1ÈÉ­‹D’\½†Wçˆ:‡`ï¹ù.0‘›XóºÕúÊ•Jå‰O|â=÷ÜsüøqÑ�ònÈÙ±^N”‚9÷ÌQlv”Oç¨õL@'·ÏúxËÑíQ¨õ? f’퇂³¼Ü/ ¢0l¼5åãl !ò¾ácÏ^':tè™Ï|æÙ³g¿ô¥/éÔ‹¶“#ËÔ4‘DBDLЋ 1ݱŒ´à«ìrD‡,¼ž£ b¬r”Ê p(aˆE¡Pq@-õf•zøs¹Ü×Óé7´Z_*õ‰ Ïk·?^­¾´ÛÝ7™ gˆ¢BiÖÕææf³ÙT2! ¨R©è™‹Å}ûö…Ö××2]AGêÂÂÂÆÆáPáYò _ÀÖ»kÎ<t]"§Aò”»0C ®aeßÎ7óÒ™íÌÖ“þ“[êù–ôiOÁÊ"Qs¬4ü«y‘?¤ºr"CäÇlî%®JÇ` ÚîìIÒm/>Ü!lÓåÒ3==ŸN][[ûüç?/K\ï‡í`‰³râvNd2 l™—¸I­ïdèÃÖñrç·8Å"pµ+²-ïoG#lì@õÏ“Éd¥RÑ¿ý³œØˆ÷Ì)ùu|C`óšÏŒl6ûÈG>R§˜>*= ¶®Îb÷~»´Á#:oèì8ï¦ÊÙ×Gâ]-͆0ÓáözÀÑ⇂Š&l4Ë©4—Ëé—JíõJôµí‰Ä ¹Ü}™ÌëÚíj"ñãƒÁ³ÙÉäûNzíïÿþcf:{0ãƒT2¹òÒ—.»LoÒn·WWWõEô‰jËéÞ*ü(Þ¸†ŠÀ´n·›Ëå4äê[ŽûѬæÞäÔQ¢@Â9«¾q™XûtôM¡;YÜÇc©º"Ë5æ´|Ñn»Ä-J²¾ÈÙ>|;WDtE²7½‰Ú!.Qá N§N&:¿Z¶«D‡ÀöÞ 0šN›<÷1µ ¯H8EõD;†Ñn•³óoîES’® ¦Ô¤௅¶’³¹\½†€DãW�7 *½N„ˆÉæAËÉfâLg2™Ç=îq}ìcï¸ãŽï|ç;¾‡Ý%’E ‚ú|«&ìÜâÓ§ ÆãñÊÊÊ_ÿõ_7›M 'ziúç,gš@@ü&,. Ãíî3í}l"b&“éõz°xAð'a%yçIÊv8ÔḆb±¨x¬¾Ž\ ô#ÀGæ’n™uG_L&©Ó©&!„Gôû¯í÷cná oxÔp8n4Ê/|¡îÿÆ?ØŸŸ¯þíߦΞM\~¹>Bj¤jHˆ8 X ®xÒºøKóóó,éjÝF]G'ºúT¢ØCPsx7ÑŸµr0)Ih]œ¿¤íÂô<i‹jwGJ½™G ™½€å’ª®ËkDsýÑÜ I‚ž Ãd‰DCJ" }ÞÜᜫIŃ`®Ï3‚‹Ä¼%Qä+HAæƒ8®ê*ˆ7r5õ)kµÚnÈÙÉžîUгˆˆé#ižâ)§ðð@RÏHŠ�Ÿ ¢“e¡oÞr"è‹‹‹ÏzÖ³®¸âŠétúÐCi¶Î£—Ê…ù–p™zR­© k·Û>ø —í\̦7‹+¢ÎE—È¥†ÛËl çt>ŒíP  T(µÐ!Åzñä=-†×õ@zæôчŠ {²°°°°° „Q/æãôžƒÁ Õj]0-þvqñåÃaq:M&“{ÇãŸétn¾ë®w¼êU¡×›\p_§rÝuóÇŽM+•Å+¯¬—J@šÁ䢇`0÷û}ÍߤÓé¹¹9õÌ(¶ŠÅ¢»” m‹“ܤÕîüxw£QDfKHØpž‹Kðy²ïÍ߬:æ½`ôFFzÕ,ä0¥&Žrõ IPœ;à7Þ±ÒÛùlØvÿxJj¢‘l# U¤}L—kƒë𾡤AY]:îv»là}œgy:nßÿBÇòòò‹^ô¢ñxü/ÿò/»s9;Üˉ�t2µ¾]üà XjvwIòÑB¯KjC;€F«£môùa7::G’åô•N§óõ¯}uuõÎ;ïô™�(U´ <Íç‹»¯(“Ûnã¿a£úô!8ae®ú™4G÷ÜÁlÜxúžò\Z>ä•xÓÁCå€ U„’->j³e³YiBƒ Êc­R© æøÔ«×»5v»½¾¾žN§Ÿ7~¶Px©ô‹ý~*•ú·löÎdò·;ñ$77‡O}êàéO?»'“¹z}|è„Aõ(KÜ ‰sœ“KÈ £µº®÷,ËQù›¯1Ô)Þ„¼M#‘û™ÊèÐdaЇ+á3ÂÙ#Ù/sƒÉšyÈŒH• mF¼Ñè·ÔÛûÄ­^,‹f<úÖVõéBsü›ý¨uâóª ½ù„Ÿwv]òÎu—JóÂT9JÏÈàCϽßïŸ;w®Ûí*Ø 9;ÌŽ"£m®äþ`ޤùnüîÞχ„Ê#“Ì•—`^¿Žü@اÐ%ït:_ûÚ×î¸ãä4ȳH<Ù!èŽPC¸ºT´—< ø$ O•r|üi¿¿0ÓbH̆þôç7%^(D#Pœk ø´‰å.O¹ÜÃÇ}R¢ªº * ªL±„ϸ†£x•JåÑ~t¥R‘¬Y¥RQt‘×§z9z^z ºŒR©¤Ï¿0ü~>ÿ¤ñø¡túç[­Éxœ¹é¦Âô5¯i¿ä%ºÉ¥þçôuץ￿ùò—ÓtÉf³¥RIjž"(ÔÑáP §Éd"6šBŽdí]íØg>ÐÞWy%7ÞMÔ-Åa–nø'§§þÁ‰é#Ã,u¼Cg¢V#µµµéa°é íh‘»­÷ç¼bÁ¶×›Hp©xîÊŠ.fãÀÀp8T!)ÿ§Z׎–»Y5´ŸÃƒfí™Ù*§íŸ«»Dt×9L±ëÙØØøÌg>3[­Ö®àÍkQk¾,0.|_©«1@Ç,7  {@5ÞîžÄëdvW˜Í]Fnï:ýTgz«Õ 3­¶´Ö¦â0=„›àF0‚cnNçG‡Ñy}OšL^™ÏF£ß¿g:L&J§ÿ1“™ ágƒ?7ÊY'žó®Iå±Ê%"¥gr@‡uIBç$BƒÀLä)Â(ŒêÍÖ¨÷^.—/½ôÒ«¯¾ºT*Ý~ûíÃáp~~^,jED¿¥"2è©¡¢–Éó¦ÓäpxG:ýó­VfFŠ­_{íàÅ/†Òý‘_wÝÜ/ýÒpÖÆO&“&U®°ºº*ç`…F9έ¯¯÷z=…@V‹î@&“i6›«««Fè[.£1IõÆÀ¦cHmKú,ùÞ"r?=¿Ï€i>P W0�Éó"šÍù¨rr©[j²U[ó!ªs×ìq «O 1b ª ct”·Õ--‹¬@^ƒ;wÉ;ja›ì´r#7÷t6G4ª¼²}Æãñúú:¼öݳóŒ5È$ˆ»ZšéÕ¿…¡¤ÒØc™ ÷<¨03ÌÄU<Ú´>b×5Hoíá&We�Bˆ OcÃV'Ð(Dù¦S½ý8 ’H$F!\:];™üÖ¥—¾ýС‡zèù§O¢ÑxQ±8N9<b–ô=L ãqªßÿìL1ž^P ʆj€«9ƒÓ–|†T2Ïh½nç/1"£x“Ëåæçç%áB(•JÒ-–¿µz9î@LvÌÀÊù|3„çO§Ïêtz½Þh2I §:{6i<Æéh”ZY !Œg§<1¸×ëõz½V«5>LéÐëõähP(‚’Éd³ÙTK t—Ö‰ûÇD=#耴Î?„ߥE‹:­/}^·Þ¨C#Êe› îß«0"í%½@^FÃArWç#ë"ã„=¯÷!Yt- º[#÷ )Ø¡ãñX–6diJn4)åÕ1ÕYm ázgHž‰T«‘)ŸF›‘’(ò ß 9;öÙ·¸3òÃD—Z­æB2ÄÕ%¤!¤Ûž†0¤¢¬GJŽŽ•S…D¾~©žéèÐ'Y‹„v¨ÃÀC¸f†XQnÖŠâMdŒF~GØs¢Î\—'“ø¨G=ú'~âGó˜›o¾ùÓŸþôäÁr8L&“ÿc<Þ‰3ýÐpBXK$þ2› !\3\67G¦à ¢¯æ]]¿O2ºæ¼o]Ÿ'w¶v£¢D�eÓéteeå›ßü¦ämD’v*¼KöÒòarIu¸ôûýQ«B(_w]*î¼ùÍú"ù?û³ÒÛÞ¦óH¾Ë¬¢ ¨söìYØÒ;Õmo­X,ªžk·Ûªà1j&ƒ á¾æ™L†ãØY(Ü9î·kÞ>K=ÁÙ.¦­"jÍÈzÙçÝÔÃ{N\•“MˆînÿAØP¿Ýu¤"W7e§žó¥BŠ&Jº M8~d0¤kü•E‡Ù9|4Šá¬tïu…­®Ž|DŒj'^zë“�ú.ðÈwCÎN†Ï5 • Ë@M&kÆG$J*ï̇ŒAÌY=, gë@#]^ßðË\.W*•ÔÚa¨ÓgWÁ©µ%ØÁ„>!•yï ÔØ—>K|n:}J¡ð‰«®zîsŸ{èСjµzöìÙOu»¿wÿý×§RÓDâ/S©ŸH$~¦\N$“åáðùÃá_f³W ?±Ñwg×à T¡Cp¢Rt˜ÅüS˜ô …•é­^éÜy}}}8.,,GÕ%‹E’eU]Á¦ÍÅQ.,[«ÕFëëë…••ÊÓž–ÛÜL/-U^þr]óà™Ï?á ã£Gß¿wï3ûýl«¥‹ßl6UO×ëu¯2ˇçÎk·ÛJf…ªéõõz]aFñF¬_u}0ÈàÜQEB€t+Ì`¦dœk¬pjPOb|Ä„åÇqý4€Í`š.Öç±àäÝG i^*ý"í€hç’  .o•ÙY©ÁDÜÕAý¹ öøù§9¸v\šqyH°°É]ð_@yDÎO A€ 't[Q„²ºÓönÈÙáCWƒÜÇMsU¢2‘ãbHè{ˆ†Ô� DLâüB „%NýÎ…II΢íêš@LÚäªmQ4ñu». rÁ4²`(éÛù` ÙëùLj:ŒÇB„ºÝîÚÚÚéÓ§;N˜NuV-e2û¦Ó7ÏÍõŠÅT*Õm4ò!\Bf¶IÀ©|4ÊÞÌj(ÇW5 z�ÖOLeEÏ."ü¨ÎX§X"j€b$6£ç®€§¦9—>.häô›››gΜٷºúýßúÖ4—KèCéoû|}|ß}ƒNçÿ~ìc~Ï÷¼cyùuÿñ墫‡¾¸¸˜ÉdöïßOÑŒž›Û*+ ž7IKBdK§Aj‘ Nì™óâ¸Ô%-¾§C朚¤‚º3ÅâÑ&ˆSË­á—šÇ</"‘)"áŠ×¸ 5 ¢ðõ¤ÜRQ¯wå4ýñ:ö…PM¶3øÁ2‚>7‚…(FÊ$Ìt¡P_ô˜áï‘q<r GeЇÓ)BÎwCΤ1 ÷n¤S“]¯‚Yœø¤gå�ù,,˜µÎB!<p.ø±è:¡ní,¾»ÆqÓæqŽúó®íøŸRÀ¯ØK2qÙá¾Iòä¼K"q_·{òßÿýƒãñþýûo¼ñÆ»îºë±ÍæWgI߇[­ƒssåÅÅøþï¯T*7ÞxãNœøƒVë ãq2™ìÏ�}ès>‡äb£ÎÕ}“Ž�B”>â= ÊxƒŠ.Úív»ÙlÎÍÍ >‚­.’˜f&ü4ÔÇÉ[“1I=£z½®[·v饵¾p¹¼üú×ë’joxÃû¯¾úðïþî3?ó™G|ß÷½çÈ‘þÎwöonŠ¢¶gÏž .¸@Öp¾P ÉpI¦Ói£ÑhµZõz}ccC»:Žf„›ìÓ¸tþ+…M]ƒ‹×¹FQ„Ê:5T—¡Uäâÿa¦~†óYÅà0¹í¹oت² ì rë4ký¹J š¦Î}ª“À1¥¶¼Àé•2(Ú¾×Üï|;‡Vx¬ûüFó>uŽo¡|�=Ú 9;ÿƒº³NŽ?¥9„WŠJD»=ís¯×Ã4Œ0:WrX™¾…>‚ñ.v²˜  šÑctÞ‹+÷€˜9‰@;ßŃéfjß:IîËt:]K$ná×zèÿ¿Z(œ9sæ)íöuýþËr¹_še‘ù|þIOzÒ5×\³´´4kµZ²Û ÃáhÖ‰:.ô·À0P‡ù|^V˜nüD§Ãû.p@Öï¶Zè 냤+£²RRU •Ïz½Þ‰'�TFhHb< …ÁÁƒ­ /\¸÷Þt©ÔþÕ_F‰DâõÚB«õ¿-/¯=º”HüøÊÊ玹âÞ{/Ed(—ËZ*Á„RtHÉxTÎx“ɤÝnw:^¯§`)@Ï {nOÎsçûºŽ×—>†â3%þ_ÃL ‚[A N>îJQQŠƒö„Kë+KC9)jÔ³¿\Õ†â€ÜßÕØÐà‹°¨6pžõj›xùå‰é4uçzmä Nd50¢ÅFiJ"·OÆd"XÛÐAŸI÷› $�¶ì~…B!ª‡vCÎT9<f[ÐÉ lò.¦{r¸29ˆ*‹Ì³'çæÓôc…VÕ·FÉ ™»$¡“_�(_3¼'¯9œo¡À¦Ôžè‚P±êa)ëéôk©Ôu“ÉOž8q8‘‡·&¿^,Ž’Éép81˜~0lnnÖjµñx<ÕÖmcˆvˆ—>¨ËPÊéç—+º²µó§i »Ù0>1„g¥™ºµ‘¤ñ£B÷›²u8®¯¯¯¬¬¨¾Q…$Éçl6ÛÙ¿ÿ;/}éÁƒ5DùžJåÒDâý~ÿ×=?Í7Ol·sÆGÿøÇ;— ¡^¯¯®®îß¿yy:ÓE úÐÑh¤)ÔõõõÍÍÍN§Ón·¥P `Ð#·Ï`rñýÈ«\Tƒ"oЏ|¤Sr·÷uTÂIs/!ð!Êh0 qR^ Øë”6OÞéQy'RÁÆ-n‡J,!'Lgó˜îýXH&FxàR"—¹‚ ÿ!/µ#†ºk8àFàé„ÂV§WG5Ø>„:ÐÁý톜ù¡í= ä¿X…˜|8—Ñ­ !ÝÓÚñùJ¨´ÒÂ[s Ìêe:7ÄP霴ˆÍâCõ®aCgÒÙ“¤·È@qR`ê£ý ©âñynw¿ÿ·½^aq:ÍM§!„‹‰ÎxœN$nI&“!¼¼\þP½þ†;îøãd2ù»ïþÉzýþdò?R©H$ga/eîv&½§>5<íiå÷¾wÜjéböìÙÓï÷ëõ:țˠ†éÍ�,JÝc›ú’x&{MlÂF\&Ù©zƒÁ P(ôûýZ­ÖétVVVŠÅâââ"ù„Xm/ïõÞ<7÷äv{o:ÉdVªÕ÷..îït®2™n«µºº:™LöíÛG(ÕÚCÁ^Í›D"Ñh4VVVêõúææ¦Ë,¡8fêP¢É0ÒyúÏzà½^hFŒó°U)Ð/:Ó-eW,FƒÐ y9µ•Û©|b  Ú:þ¦%Ïç#‘i·YrÈÎßp²´Ôûß(þʯ$‰Ö;ß™yÃ’µû€î eŸLJàù ¹O—† â<;¾*Má”ù5(êø°«hXû®¨r(qšrž ÖÂWÀ”Àµ£)¦L8±3p œ6°ÒgÎ#�®ÈR Q²B­-ê¯8 –ËáÈÞ}wĘpS�þVÝxŽi?ˆ!s3˜æ?™Læi…|k?kt·Õ:7׉Wž<ùå3g2™Ì£‡Ãg÷ûÈf‡Vkr¸ r~ˆýiO_uUú–[Ú/{Yá#Iõz O|âOœ8¡Qj÷O䱊Øf^pºŸ¸MÃ,`ŠVüh4*•J2Ÿ››FN§ÛíÊË`;íGÐÖh4*‹’‚®Õjû÷›SEÄP2™ÌR"ñûµÚÛªÕWw»ítú¥Ò%››ëÙìc66²éô(“™ŸŸ¯V«ËËË<ÍN§³¶¶¶¶¶&.\­VSî¢ñO¹lllÔëuõ·œ[W Z¼Ÿ¹@[äIš³a4âÊ{äÊÍ€˜Èñz ^;Pjd¬Ic?Ø`2ˆß(‡Ô)ê„3’ñA‚à ™‚ÃB¥áí¬'<¡ÿÚ×îù…_( ½^/ñš×4ÞùÎâÿú_Óo|$Öù^f‘?9\H»0a²L×& ÷…O¡]éLtÔqn}¤ðÆC@RU#’ƒ»!gÇBÁ{úc1™èm:ôõ à|ŦrÔ{Ms:]–†ÉŒ`j7®Èé•Ù›çÏ”_ø…H 2™Ä׿N5ƒÕ ¢X¬{eô¤¨^pP3‰óƒ”¿~ðŠóÍ­^:Þ›Í>v<þßÛíÂj"ñÙì“§Óƒ³Íê îG0üáN>þñso}ët:í¥RW¿ºøGT¯×o¿ýön·‹ ›÷�zеßEWS×WG¹¤»ïˆ‰„Ÿ›V£Ñ ­÷_[[ûÖ·¾U«Õ4ªR*•êõºL»Ý‡KKKÒ=Ó¬îvy<þÆ?‹‰Dâðdr8ŸÒxü¯^øKƒAu8”©$µ<Úíöææ¦ÄZ­ÖÆÆ†˜ÐÝn·Ýn×jµf³¹¹¹©y R"wTò!yððL.øÐgð9}ªvñ‰ÔÃø+— ¤�"Ÿs˜ˆJÈ3"K~šk'+Sdåó÷#ybüÙŪ=i‘`d—L&§OzÒàyÏË¿å-™Lfii©ÓétNʾõ­½W¾2—Lî¹GU#°GØfULト�Ï¥/¨¼DÁÁ0ä÷´Ø ^ýA»âNôwCÎNþD³“QDNäÝK‡kèI*h(SSå¤M"dƒ˜Á0c»4 "Ó3`\2/kH&“xMö®½6óÉOfNžìüìÏfÄÌ’–..†ž€!¾EëTuåY*¥›tŒ†T*õ×ùü‘ÆãñWÓéÍ€ÇétšÍdnM¥FÓirVFN_Ý«¯N=ò‘¥÷¿?™JM&“§?= Z¿ù›á-oY[[ƒm‹ z²Î¡ðn39¸£I…Š:ånÄ ÀãñXóÿ¢S—J¥ápxöìÙZ­¶²²R«ÕæççÉg%•Öl6kµš2qÅ M¡O§Ós…Â8Ÿ¯¥ÓÏž;†*éô[æçßÞlRgp`­¬¬œ={vcc£ÑhÔëõz½®0#µ‚V«Õl65|ª*Í]¨y:Á<’Ik¨°áã‚Rú`&‹ÍxG†¹ó:ïÈÞ"Ž“pÞis�Àñ^—ãô©`xŒî45ð|R;Rõéí‘Ìúz¢\ærƒfS9Äd2™–J‰B!½¹é ~— a ?ðé œ¡N2GhÁê¹—­”2ä’ÛØÐ9G†é‚]’ôwWÍå;u’J<Æ”“nÝL:ÂÒA‚ÓkOim'¡Rd l-[ }-z•çYpss½_þåä¿üKþÖ[‰Dùÿ¸õ®w%ÞøÆÄ¹sµª€Z±Òw‹¾¸>1""# €q2{ÏÙ\!„B¡ðÀhtÏp8œs‘¨&“ÉqIÓ»õÓ$\vY¸òÊâ{Þ“÷>ÜëõjµÚð‹_LW«ýŸÿùÌûÞLÒJ%‹þ\FòhEâ"ÙÉdR­Võ‡Ãa©TÒ¡ Fœ®§ÓéT*•Ñh´¹¹9™LÊåò`0(—ËšÐ{{ss³Õj´Š©\­VçæææææÒéôúúºÔ?S©T=•úÀââNŸÞW©ìÉå9Ýé<w0øÝ¹¹ßít­¨p©×ëgΜ9sæÌéÓ§××׻ݮ>N©€èjý~_Eª�},a4��öëELð¬]ÊôÕóWHrœ™ZAY¹KJ{ÊŒèaG“×>E  ¾-´Ó[›Š4.Ë¥º ²¼H,GAÝ-Hœ¦B˜<ôPæmoë]w]ýo®¯§R©Ä¡CÃ7½©ôk¿–ètƳàG1§ZÙç“¶W<žÒig¡©Êã@¶Žœƒí©Í¥�Ó[ÀÛ &ÔF ¢q»ƒ.m»!'8ñáN¸y+E-h?ÑØ˜>ƒoÁüC#R¿ƒkP¾àÖ®l ïÙøä]Šór,Õêð•¯L}õ«™[n©..&“ÉÜ+^1øÓ?Í¿ï[‡ð�� �IDAT}Ó;îpÆ0t&–¯Ó¶t›wz<4 ¼ #~°–µŽ¿Ë/¿¼R©wÚiz×—§„n:&¾ñä¾}­¿xúW%äD"1ø=úÑ•·½mb8Œ L‘È«kâ>Ù4oä~¦á\¥½bhæf0èj±!Qø¯V«¤í…B¡Ýn;vL}éD"qàÀL&£:FzÏÃápqqñðáÃ^x¡<굺Ôxèv»WµÛ9räg{½¥Tj8Öëõ¯¦RŸ›Ÿ¿vcclÃ*hjµÚÆÆÆ™3gÖ××ÅúÓ³k6›2×òp”É™ôб cVíå¾c>‘£gº:H¾"¨!X‘@2qž8:OþÃ#sGg¹u:ŒÎ$´¹Á:B ^ ˆ¡TïLx“BÅ’ØL;œÏfšÍÒ«^Õ{Ï{zþçãétøêWîç¦! mr™‘>¯ö<éŒ|¸Ýq€1åL0‚ù¦{¢ÀͤòFç0šBsÙB»òKO+wCÎüÐ#J~—@8$Þ$§6"¥¢^!±ò·rs'öÃvèT*µ´´”ÍfOž<©·rIsÆQ}àŽÁ‹Q:=ÎåÒ››’Þ§OöíËΰ&˜>¯à.ŸP˜|Ü/Jl1VáÔÀÿJ¸¶¶vòäIàHjB‘ ûʬ Ӭ硞ë¯ï‡Ð~õ«kò'©Tªû‚L.º¨ü0uל³L¨Ñz<™@»AñFir¹\VSW[ºÓéèðe¢"ŸÏ …n·[«ÕæææôÊ^¯÷¯\ðôo|Æòòr·Ûm4ú·h*•J©TÒ…ÉwU­ãÉdòÈZ­ŸJ}àÈ‘W­¯WBø÷túÎbñ×Ö×ù|·Û% ·Z­ÕÕÕ••••••õõõv»½±±Ñn·u‹Äb×{bàŽý~_Ç™RÔá€ß¥X¥›#ÍÚZ®o Aß/�ˆXZîsC¾ïuŒ¯}® hª®ùùù'<á Ç¿÷Þ{AŠøC×|а&'Åùñêl1炪ë~›©3 ×^Û{ÙËB…k¯uQåì ê›ÿ*µõ^WDÛcÞ܇½ÄÀ&×´+ÐûNÄó9ýÜ´]#êï–BLJ゙z‘‰8EÙC’W÷¢a8.yåѦñ1õÈ¡U%3%ÚãÁ,èAŠ|Äsazölî#¼æ5‰z=ÜwŸb÷moK~ìcɯ=9/ÐWÖà´þ¯ (.%¢ÿëyk4kº6¦{{üøqæŠ|Ú”+×/%ŠågÜd†Â%?ûÙq¯WûÍßÌÜ|sØ»·òŒlƒ£Ž´n2óäèüCÓ`n¿\.ë:óùüüü¼ˆÑ8›)®èñT Ùüü|¯×;wîÜßìÝ»˜L~üÏø¥cÇ:Îý÷ß¿¶¶V(.¾øâõõõ½{÷‚‹ ? ‚¿\‘ï’3gJ!\{ñÅW;vÛž=?qüø(Ÿ?]«Õëu]Ãæææý÷ßüøñ'Nˆ; œ6²7öàƒQ! ¥ÑA˜Ë¡Ï´t&b'Ì@ÓQIø"ºÏˆàEãnîŸæó@dëÁ´œw ™VÇ‚` û��ß´}ê‰{'º$¨«ŠˆÍÈý<¿ÅNžL}øÃ‰ét²²’šáä*ïP˜åz1˜îŸ|4%šëz¸Øn0ÑnF¶H¹C±C|þÏçUwð¤Ý 9[F#}š×ËO¦„&û¸–ËŒ£&â“:÷]ZZb‚N" ÆïÁææ&h†Wû˼%‹£v¯×Kž>]x×»ZïxGú-oIÔëÝ_þåôßý]æ¶Û[k,6RT7­Ò· +CÏ#ÂÖ"{S·Õq|€ã^!Vÿ!wísfž\–ûü©qÓM‰Dbôßþ[þÝïÍÆQÉ  :‘'öÆ:}D Л = [Ne6#W4F²Äб(œóСCG=¶²ò©½{÷¥ÓW¯®ž,þîòË_tÏ=…B¡Ùlf³Ùåååùùya5F£ÑhH´Mt „úˆ|>? ö:u寯'/¹äÅ7ß¼:Öf¶r:&NŸ>ýàƒž:uªV«‰&@㄃Œ/N?ŠS¦ î³ ‚F-t.&RF÷y¬®û¶ºùéAqôýQ·¬u^µèTºúÜÍÍÍÛn»Í§…¶‘á[2Áæ’q‚°ð� fºó!ºp®éž:uÊáAÒˆ`sÜtM"z…ãu 0VÐ2ç{Á‰…¡îfðA„.IÁBÁ�Œñym:Ö‘ënÈÙÉÑ–©óǼ [í“}^[*­?&Ø•&#õŠŸ¹óõ{w~jC`u©4Ty|M;Uf4¥›ÍìÏþlëºë’ÇŽ¥¿ô¥ô׿>1YH¨äM,hV³Ê5âM˜ ¨2lá $°~gèdŠë媰õ|†<‚qàF£ÜW¾’¿åÝ„) €ÑÒ½ž ÙÉ©y•*—Ëív›é Òjå¤ÂÄt¯*•ÊÞ½{ÓéôGîÉå^1¤«Õ#ýþ¸ÓùÔEýP:½ö¹Ï9sF,8)R‹D§ìAØ©ê]}–´ ƒAæÜ¹çÝ{ïú`Ðëõ( ÔÂ9uêT½^o·Û@+šbJ212—©ù”¥Î2À«±Eî± &åJÉûQÑ¿ñ™â°ÕŠÅ€­ŸÞmnn®Z­®®®¶Ûmè^î/¥0¯GÙÚR¸8YÑY<°tšÃœ1Îgófl¼c*™cB–™*³È(બ]%jت—ãvNhf1€Ëñ{@1‰v4Õ‚©§Ó*ÛÞEÛ 9;rÐba¾ÌeÕ#Çv‘—G¸ÞK3.§±Ñ=ŠR!?¯½H÷v}äÿ†Ï˜ÞÐ3/]Cæ-oI>ùÉéÏ~<ƒDàï"îâÙœ_U¤¾îÌË`ÚkÞ£ö³Æï­›g+Rj{{sÕC|6¡Ùä°Ï<º=£DMDÛX?º6Õ+ó 9çë('bM§Ó³gÏ~ti©4¾d0X<p@Dµ«Z­d¹üÏGºá†c‡œ9ÓétÔË)‹bZ‡™´Áææ¦zl2M€NÝív;Žžr¯×ZŸHÆqOÜ–Â9îÜd§6ÁÔšL&^ôxÒùÐÎãŠvJØj”é¿ô5¶zŸã™Ë$ l@oÀ8µ×]pï%<DÔÐHŠ7Í\ ÛixnÌãP” 3tŽ_0;ß­Ä`ò¡ÉäÒ½ izìéõz…Bï`F0í5úFgx—Ôç7ÔN›By46¾rv,äЄT»%4Ç»Ôù`‰;‹àªæîÉèºëœË òþ‘üš÷ca9㪠Ô•ràòd2™\]Í|æ3Ó­ô0¤pQz÷ÝK¢§¾&nTÃØÛ¹.¯²Ý9j»âì dÐ’råG:mè¢:èÁmQ3f8 ×bÛ3z c» ¤Žf:|½^oii©\.º. >½wïd}Ð&“É+/ª×[_üàòòñbñµÚ|¿/â�’õª{d¼¦yšáp¸±±¡bHÏ®ßïëÿbºƒÀ *pZeø&Z±Ð^üüuÖ,yŒø h�@«‘d^2ù–Ã5n<Cç½z½.b·Öˆ®ƒÕü|²„skÎtçÁ¾SÌ3±j¯¨‰rá²0Û¦|'GÞœlOša˜Åy¼aª:r½ÓZÒrr‘ºhúÂyh.×ë{pb£Pø¢Äq·ÊÙyú�ÿv¦<kBϘ#ØûÕ¬rÅŸˆ~øFÏ a6†V­^Cyî2‘Ph³tTö984ƒÝ!&˜Œ'taæ 0å,X'‰ºèGÔœUˆˆ ðp§èF‹Es8Q>}H$*•J¥R©×ëX�(›óêÄåì(7¹o®ŒÇèáJ´jüÒ××Ì^€±J±X|B¯—©ÕÞµ¼üºZíÐÜÜ8“ùX¹|Q‡oý¾ï{Á?üC«ÝþìOýÔ‹n¼±˜NKÚDNj/UA. ?ú¥n‹”:iŠp´Á ã8•h ¶`²I.ŽN¶‰È¹ngÓè2h¿yo<:ëS[Y‘ÎØd �F¹ Wâ F°Z|›h=¸s^†m;×xO·C¼ÕÝþÃ-¨ièÂp{x––öˆ \š.cCiÈýqÍýF!*˜ú Ë}OHÜ„":X6(öÒ¿Ü 9;O¨V«Ê@ݹ€Õñ ‚©e8”ìZž¡°µÙédÅGƬNV?#ožAKpç9ŸÀwço±¸º%[T|‡ýû÷—J¥|P§•&çYÁú%‰3‚„1÷<Všò.Ò'–1š¤É€€˜Ã tsþ««¤È] ¹*’PòSµ©õé:úi{0´Èåq8Š-¢‚rÊ™Læ²N§•H¼?Ÿÿé¯9RN&/ìõÞW©ü·Ür,Ÿ¯¤R¿xûí{ÕUÙ{ï}d³‰¦P}–ºÇ"è h6›>¡B/=˜{¦gå‘x¥?Yo« Pä%¬÷#u€²æ½e KÝMɰ©‡œƒ™Ãàp[³`†j¶9ŽÄZ¢Ö¤NYñt¨›‘æóhJB ®¿Û¯ñWdT´^œH樔Å(p öt„0é7‡ÒÓ³ç‘ð…|·âæ¡Ãtwæíýö,p7äì0ª¦‘r­9§½û°´ïyV¿–I%8µÛ.‘(1üå(w\acãÎ乿ë÷9pá:êZ²ìý!”¯åõf¹ëõ¥RéÈ‘#<~ü83Ò¡�7 ‚–ë1{'3lÕæñã†&¿çn·K¤±MY¶ó8¢1 h]®·íbº�îH RÂbЫ€Z*• G)ÆkÞS%Žö¿Š’jµšN§sêÔJ&óG>©×;šÍÞɼâ;ßiu:¨:tðà5'OþÛÅgOž¼`}]‡¾˜rú¦4«9èќױ%а¾—|zhÌ(\†EÍsÜØ¼LPcJO‰Ð.‚T­,ñA@u@iÜÜ“<(åý˜ŽŸŽËѱ'»÷ÈGXŠª,@o‚ŽÒ„D”߉s¤/Î [%yè¿òÑQ»ÈåSù‚H%T{AWŸ²ÛgWÕ½ƒÓäŸëüŽðtqo¯Ò b(m—±¶“?ÈY*÷þv½[ÏGèõá0ÈhÔ^wʯè•ÀÛ¹^(“{Qï¬r%(ILù1ê(ç./ØaÂ8/€ƒÃsÉ^¯wï½÷?~\Gtj/2âÈÄí5ßa¦lížz±Îwñ’çççy X´•äňܼo.9I“&‡™ (CBÓÕ‚%PN‡ˆÂF£Ñ¨V«ºÃ?{6×l>ãàÁá¾}ë•J;‘H¥Rûöí;xð`µZ=›L¦J¥Ç/-UK%MÒ¤R) …B¥R).•Jé>Ó£Ö¨ruÄ,ªNÈ9Ü¿Ùç6HS"g#'F‹X ΞKrÉ ¦>'2×§4©è+_oè\0SZP.Ûá*8ކíº|Dãöú€¾¥¸EØê]â¬ëˆ(áì‡1ðüæýê`¯)•Áˆ°ÝõénêèpUjMÿ H_ üÃ+ãݳc!G…¼“÷½;í®0Šh-BžU¯¢Ñh9‚hÓ_q@yÚ°Œ£¢P‹±–'Œ£’ý!:"øH#/‘Ó”^ \iÊB^˜L&§Nò±(Ú>Øìç‹]s4l—£ÌµHr§Ó©šÕj5ŸÏ7 þÜgkP:Qþèî#4¥`D¢ÔŠ%º�8 ¹\NX÷SïP(”ÝkR Tøl–——ÕÒ¸4•J$¥Zíe'O^{ôèk‰ÇÍÍU«Õ³Ùg³¿uæL¡\Ï4ud‚@ßHZ5<w=8áxzLb=¨^QÀ£mLq’ÊAއ‚Šs˜YðF#éðGTWS�îäJÕßÁ†(£ÆR”A»aG䔬7WÙ¤{îçþ†LŸ¨”¡ã%D¥¨ÈSáè`òW«ºd;´]÷3’Ö寘RrÔ�M+Ö¥}¢I�/Ö)ß)ìà[‚°ù¨P0…'vq§Óq*)5ª‰”°¨†ïkß…Jˆ4÷€eô uäQ,G¾ŸtŽé,çÔCUðã8˜1""²nÐétH ó˜/ÓGc¡H8C“†æ0hù þ·|+7¹ÒÙçǨÖ7¹6|;s@êétªÁþ……eÓ O¸äÝøÑù¿Äo¨¢:ŒDšp'uN¶.£y7xÄŠ» ºrÁ_RêÌL§ÏY[ûû‹/.ÇÓlöã¹Ü»ÖÖFéôd2)á ¡Ñ(ÇýÁ`2™ìétÄŒÈf³ívû¾|þ;ù¼œ§uKóù¼7²*u%ù|¾5s¨ã¡ë5x¡º'+M% Oœ5Ìý„Uì«ÂÙn ¢.¤¶ý0%å" øR¶6ÝÈ™N’Ë+0OæÇ4éS– Þ ôíuø¬;]Â%JÁrÃVÇ/€°Od¦8¢�ÓEs.—åÙ›–wôP"!y¨lFT²¸Ã¤’IàŠ<Çlç솜àíÈÑ(º�¯ø †™ ZjH` B¯Èç™]Zz…ÎGÄGðæg0Í7¶ 0nׯõÁƼöp€ã”6_¾®zàd$@;âEä‹h¤ƒ›ÜétªÕªà5¼|¸Žã;½‚;Ãl¬wM¡fpÛ™ˆÔ֕÷Jçðº†ÏqYs-Šãñ¸ÑhL§Ó[Ž©•J?sêÔ§(g³¿Úl2 ¾ÿíoŸN§ŸþéýÿxîÛßÖ/]yesyùª¿ÿûÏ?ã+Oy Äï4èåóyÍKrŸuñnïÄáÌkŠK$ãHq0óŽ8»T®.tä®6”’‘â§?Y�dW\*˜¡oäšßHÊf³Yqü\âÅeÜí`“zaíÊR4E•å¾ùM€NíÓ?ðM¼óÊû ªyÆæêŸ {Ñøé{œpËä©V2CÐ<,WŒenÉmïY4Ïvµ¦h•¶â÷䵑´>t,§ç¢²Îsõ^«SSü.¯KBÂIG{¾æç1éx§ð»0𛼹 õœcg^ ‰3CP¤Ê­C”Ï‚Ê ô¼¹¹¹´´Äð<±*˜²\ä·MÛ±Í:H{Q—‘Ïç+•ŠØ¨(Ë –Q€+yƒ"BZ©TR%¡>‡ª¯:Ô®T^Öhdþ?öÞ=Èö³¬ó}W¯î^½.»÷5Ù$ä .Ž@ Ãu`¦jDÆ£¥…fL/eÊ:ƒ£Xè–t¨Åò äà(x;SŠ# GQkÔŠb ÃÜö&’½“½³wß×Zݽºûüñe}òéweæO›ª³º,k³Ó{­ßå}ßçy¾Ï÷û}ïX]ý­nw£Ñ8VÊá?ýÓöG>Ò<wno~¾û_þËìùó¬®c?Ü{üñD”cÇŽ¥¬‰ØÝ‚»90Àê áJûBºhöR¬•ñ1›nðºsvçuäsÒ‚2[½h~ e.PÈ(\ÜX¢:áØu!uòäÉ›nºéܹs_øÂÐ ÑÉ`ú(VÑäu Â(‰¬D÷ÃÈE(Ú¬ô´Ûæd g÷9år"eáZµË*eªsBkÇéä@ImS£›5cY7"$Fâ>£%Õ4ä�ªæ!zЇ€*’1z±@FFc}}xÚƲÍ¥±‰.,2òÐ$/ i´jÊ~£NXJ¹¹¹ˆ< wøPð<G@vÆhÒвœÈ]kÜ‘…:ðwñiìLÛ†’?¢*Ÿ››‹¥¦y¶}#Ü2M�þ±Y|Ä¡Œ¥ñü=Ògt0ñ‡!FoooÇt§µ¼Äð°SßÐø3°”{®¸býòËßòä“ó33s­Ös[­;†ÃY\|çêê?¾}ë­³O<1ó•¯ÌŸ>½{âÄöÕWŸÿÙŸ]j4žý¾÷¸ë®€3—]vYFGc¸’Ž ¾SR „À–Þ;ýöêÜp¸WÆ ¦0á‡Ïï”±<6k;Sò˼kž¹ÍÙÌ­²5Tz?¼#÷¯n#ѰL”šŸŸ¿öÚk¿ù›¿ùî»ï~àØLefسýfÊ~t3h\ }ƒK›)G6æ-O$«°ÁŠÕâÞ¿C£\g˜ß€ÉN Ò›`ØÒ†®^¥=rgÞ<>‡Ð|¦!瀫þPž[°â?ŸHâIí=šи–­£©y}žVìš”ó� ñT]µ4ºY©Îh<„oñÒäÃmØåQ¡”óÀe[RäÃáÌÚ´ˆ"Q!¢]ôƒSá@} ¿ˆg‚Í}¸ìç” ÁdxRˆä,ÎtœµµµT6@£9a¹Í@+Ñ~B$K'/"ƒffgºöÚvéÒl))§æææf÷ö¾u8üƒn÷§šÍ½ùù½F£”2¸õÖõóošƒÁå·ÝÖ~á ç;<ín·{äÈ‘õõuÎtOÎû¢Èˆbì7`­G®œ/ >û4´ú„jƒ8‘7˜Œ‡öž 7mµ7yæ¢Mëï½ÃF@—J5É$VÝ{ï½=öêO´4œ;IKó”X ±;œ{$è (Ñ*­LET³Ž»È}ÃñLƒÖÀRzb#M¾Eû–oä2â¨fè5ÏÐùÞ¸$[�wnJMCÎU9€EŽÖš°H#§RÈ#¨l¬d žW’ƒŸ…äS@ºÏ8hÝïîü»]DV},ð½;[fxlA¶e&]ž?>Mi4ÝF2EÚXuÎLþÆ(ÌÈû®>XÝÙ‚òg ð²à¬[ØH§=4ŒêJDYYYa®e²é�hô›‡œÃ´Óé?~<t’ïùÊW>yÕU³ÛÛ/s=þóÂÂÒì쬮îííÍÿîïÎ\¼È2+½Þò/ýRçw·uêTn­5?ìØ± ãÉ�ì•••©Æ nmm…Ï–C'Ï­ßï#™ÌÉE£ ¨ .�‘ùTŠVþ­ˆÞ‹¼ËÊ~c5ˆ‚–YìšU0ýá®KJ)1áv»ˆÕÈ ·°ìw¹Î©ŠÂÖ�ò:ö†UÀ®Uõö™`,ºŠ<– j# ~-ÿÚÀŽýfÏ{É«8y`iBÿË{'–ûñËÓ*çà°~qOp R tÝžªI†h=—çÈ•­<¨$iì[æ‚°è³OÒëöl4j¯……tBùŠì´RTÖNí !ÐñlS¸Ñ$èÎ*tÛ‹0ü4À�5l®ɧìWóùÀrZ]ÍP~’Ê,DjøH†˜[ª4Úõ~¿)ÿ62ˆ_†U‡%åìööÿ¶½ý7Þxl}ý¦ÝÝ?îtžÚݽ}c#ϳ÷áÌfwwwëŠ+Z33³<’¿_h·{½Þ`0èõz¶o‰#C;Kra9s͉¬ÚÊØÒÔ:A·+*'wì_GîŒìªKš‰‚“•«aX\a0,À†Òb “û³z+“ÿ�‰ 3 ùî½ãµÃK·ƒÓu±C­ø43w½dz{ÙæÔàÒD‹½À-��™m:’»‰<ö Ã\vÌ5§3ꦩ)¹ÍŒ5ÉþÒ^—ÙNž›´‘±¾v^¨!óÂF 1 Ñ+E4­`ÓÀrD"¶÷°÷j¦½âV«ÕívG£Ñúú:\5œÄl9eÁ ©éTWÀ17‡²†àK­V«ßï’ºxñbÆVÂ5dž¨“œ®•%;éµ ºµ ¨IPÌ9NRŒª¦\Äü+4:yÂÑ™=z4°Xê¸Î$rä²WVVò¦ºÝnŠ›<· Úɺ±±‘ø½±±Ð&^ѳ[[ß;üâË_þm£Ñ£Íæ[WW›33ýÁ Ñï/³öø{W\±ö½ß»³ß‹afì7¦C¾´ßﯬ¬äÂŽ=š‹L¤ìõz ÐÐëõÖ××àX»°`B¨ÀT%c‘æ?9‡2õ:ú_:°ùÍFp.²Ë´É‚­¯YfšeOê–9uÙžf0˜5¤Võÿ-ÜfA ô Å„*ëœè¨lO,²KÂGÙ Ô“È)ôI§ŠœŠàk$äŒÍBªÌ·Èöh§©KóÏÚiÈ9Èú&k}R~Œ‹ýðɰèûU؃xZ”Ùð†Y]”ýöhŒú EgÊà“=ôˆ/T2¸Ô:Œ[‡@I®”ËNj_d—’ÝŽïKàQ"h3=®4ÁØÎ=ì.c …š?0^Åê@fŠeÛ &l`Ü‹‰Qõ (ÿS�Å_.á6…ÅÎÎNNvÒÌÜ`bONŸL-¥üÄý÷ôúëäìÙíÙÙ½ñ™>¸ùæÖ”nwó5¯i}àƒÕÕÅÅù/~±”²ù†7´þüÏgšM£IÍf3ug^߯ÆFÄ,ƒpUfgg9qÆó˜Òá4pMž$+HZ‘ê\Ô$x°,€& •’c&íp– ¦SÌVâ4“²¶™,U9\ n3J YÙgøoÀËV›ºÕïÒ™ÍRY/à uðà`Ì™ÂI™b&I ý¤6*v�+šµ‘Û§¦ÁùÛÿoC°nÞ/6 9üƒh‘0à ËtÏÀ°§5q††Yµ@Û$›D”j¼›;{ $€ð³Â€JH‹<<Øpb«ÕJÊã)¿ž’Cœ°”ôµ[43ÔŒ5gæàVÍ!“¤mÂaºs5ȇ²ðÖ–Áº¯ùÎ2îŽg4u»Ý|Téø$ÝNÒJÿ ߘÔ5Ù7¥íê¥Kÿ¬ßb~~ffæÐ¡C‰Ó¾ã;N~à³£Ñ^¯·7;{ü~ái²Ý.c  ¼Íh SúÄ÷Fc­�A~eÈ'õIv©Õ棊!o¤Và´~‘Io�� �IDATf:ц1ï†K2ÊQ˜Gÿ¢rȵQMµ;˜[®h�(÷Ô1ÇlhÍÅP]MÓ€‰ƒU¼oJ$S¦l0O;§H’L“ÌMS By,ÈI³`*QÅ©¨ªð¶}%ë‚mh¬JÛäÄÒiÈ9ÒšKê’I1&ɾ› ¬!º¸–[r4^Ó÷l·ÊŸÆÛž¼Éä".Øðˆg>bzáY5†¬pfé#®¦2cŽ¡3,@“íËÀº‡Ã±f“'{Mà Ì9h•Mçi¸8ðáÛh4z½^î¤ìÉ|o\gÂ{Æ”PNíŒVX‡Fœ2"Bó-gΜqO+¯~uuuvvöÐêêÚîî“?õSÇxà¹ï)e·×{ü×~mnnîÈûÞ·þ¦7õßúÖg=+S 2œ4;;»¸¸h‡´µµ5´A¡ à¥]Mó¸n@T“×Ë~¹qÖÄÔ|QJ.2›Šé”(ê6‡ì¹Sè=+â~"=•õÌs€ufͲ½ò`Nz3š_Cð(²Ã$H,„h€Â® ^|æmµ†wj‘Š·VvéoÑÖ5å‡5Ú!…,ižŽ‘.ÞBíV7 9o’ì ‚!{…Lš½µ@ŒŒÃæH9R6*7”f|å°ˆ¿d–rVÃ]òOèdÂJàè·tÀš˜©`Vnr–g’ãA¯  XÔ°']!‘ý™AT‘ Tˆ‘HÐ'â ¬ åfº2¡ —RàòB½£’Û²·é V˜£ñ†1ËËËØmmm:tmâM~3lެ–ür#¸PÊ7|ô£Í¹¹™F£à ùOÇægòv/yÉìUWÍÌÌ4†Ã¨7¶··3-”˜ÚívÓ?OSŠPžk0_ÀPœ%7#Mm‡]VqÙS1àˆãŸ›d©½r z® é¹½Ž<ð&$ï* 3­qr<3¿Œ¡ƒá;†ú+ssÏŽc„̬y¾Ñn§ÆÏù·ì>£`e“SpøÁYÏ@`D L«¼YI%aÂE"ÿ³© „—7 9I~‰lí‹ËÃEF­¬u$ 6@“·`3çx¢ˆ]¢Ñ÷Ñè£! †$‘Šgr`_”û—·fïa0KHô`(8¦YÍN3õÖh¤-{ù3ƒ™ÄIr¹Sà (=˜c"‚³]¸ùÞÞÞÆÆÆââ¢9ë”)ð�­üõùËofOžñ†##OcccƒÌ#oêììì#¯~õ#¯~õáÇ{½^‚JÖ¡¶Ûí½q«ÉUB4FPKò_±4ÍÛY^^Ný‘ì!³G×××Éy™WF@ò|mA¾Ï‡·ÛmÈx!¿„¡@çÒŒ^*Qà2r&w8R+£#Nöj I›‡¬ƒ\¡B3`·'—Úvº05Æóa³¹ªñÛî\� ”2žw!…œÏ,5÷,ÙžôÕRñ8¨xZDÎÖ*‡U Wf±³°©{*L|[;NCÎAV9°o«©ïôÁ�µH4èásæBy,r'KU‘Ï R5úªß½Üꤰ Â�ûD™÷ìŒÏŠhr„ÉôË|‚‹&%9%«%Å!¡rªFòø@'éN,4‘מoÙô´M§FÊnK+´ ò±3XOý2ϧEƒi1‘Ìf£ƒÁ ]zwDÂs‹'¸M˜f|¥FjhΔ¸sògªäƒR‚4¶SZ!-ŒÐ© ÝnrH‘cÆÊ [j#"ü»:к3¥{àžÃTÍj«¦YÛñÌ–í|>¯žQª^x<W\;ÀÆoËþѺöå+šRJ D˜¬ GsáL·|ÏTl*û2ásê¥ë‘tUl0B€9‚qû"_"±~ò�MŸküuÝ6‘ì¦É–±2|Ãɸy¥ÙÞÉ—ƒ ‘ngÿSÂgSY ^äG♾¤rn ÚÖ‰°DH–»›ð•U‰+xA4óSjäÔ3¯Ú½(6›)1­ ¼�Vî Ù€{¦Ššd†:i,81ÏœõƒÁ eÿp#,¿H*ñ³±ì76b9eBÈY,{.26Ø“"ÿDš|xþ2d?¨G {õÍÔÊ»XXXHT‚w¥ÐAÛÀ<³¨èWq›<Ÿ‰¨ýó"ðõªNîµ¼¼H3Ák•ŒÍë“⻚‘áZ™7Â÷šåÏ^Ñ«\-(»ƒXl{*˳Šü¡YG *‹‰†çhðlË„¥H¼5y³ã3ýÌ”«ûƒ&­#\µlÐ^ù"š1ÿ�Æ+þ´1ŒiÈùº¨uœAXR`?æ,h€#Ë`e¸“lb±g˜8?i�üÏLp³†BÕµJµh*/z¾Ù¥Î¤üš·•c›Ým™ÐÌ5ïùjrv‘gO•UÙ~¸â¤áOßË9l»Ýj” è”8ÚétãúQF,..¦bØÚÚÚÜÜŒOŒ°Ç‰Éa+ ¯#™œ¹3339÷{½ˆ<&Óá¿A& “±o^ô¹¶|B)%”k^åáÇ y¼Ãá0k&}¬µµµLÆ4÷’6¯&¿™O^ZZJ¹àœéõ¼ú \kÛÖãž¡^µëÝêÈ Ê“±c[å2eY¥11G/“ª=¶Àv/„hÛ4Ow&8™Jãp…Ve5”üþX ™)†¼ž'½ÚŒzïégUØÎÀ2;”»¨˜Ï·äh:¢íà ¹Z©à`Œ·Œ,,,ÎîäÈh²X &GVÖÿg-&`˜ QÍè¶'{rºqš“»A°ñ|*Ûr€Â%¥¢ïš'(³žØ'4`&ù ë];ºáÌÐf³yìØ±~¿¸Ñ™dÃI×l6»Ýn†f¦ kü$õ‡S‡ùùùT¥”ħHD3|ˆ`’.†­¹÷D”ð9Áñj„0°‘Š0âÈ‘#)kÒÈ£ãÓR?ßš¨IS&dÎë`z›››N§Ùl®®®†‘]¾È'ßйx”ÎT¬œª=^¤»$]`Í’zÑ–”��XS3¨,žA @L&pì&Ñqìa”d}šL4±&ªe〬»²k+«ê©íð$íê”àÔγEÊhO­Œ ƒòHÝ9æ7!ÎU.½¢Íâj©áhÚMCÎ3<̆ E¡ÔªyÀîUr¾Ó~÷xNX·^츌vD êûІêX#ûÓ øšŒä-äÑ&lx bÜꄃd³ƒ"‹6hü+{ÜRáÑW÷Ðb>?;äâÅ‹ $Õ)À€‰¸¼¤ËÀc³z¸¤a±‡Ã¸-¤Dˈ³ÍÍÍàEÇŽsë•^Z°¬˜žíîîÆk <þSŠ•Ìv‹5ÃÒÒÒÚÚZívpf’Â9„Õ–v4%8Šg%Ð$QÈí/..fYæ6ó(VVVÊx”Y^–Ëé3vâLCúâ‰ô<›X‰$ÀŽ|öå3…º™ ,5—D’Î/0 <e–5aö^²ZžˆôJŠ15@:~Àl Tj30óÜ\mÚƒ MUê ¹J²(b•]ï8^Za<<Ÿc&I3nXlO q'ÓÓs`ñ@z˜U۰¯ØNîU2àÄ_˹Í;À]j~~þ…/|áÎÎ΃>%<Ÿ™KÊqlÂk%̇„eT™ÊØ#½º¾.lUÑ›<VÍ q`&=§Bªº¯Tñ6*¥»ØBö—øj^ÜèàZ95<ÑÒÊödÁ´Òr?uêÔÒÒRÞÂe—]F¯Ñ~‘¼4ìÁГÞnllt:˜³‘8‡­Ôh4bD”7ž×‘XÈ“qp<ÆÜ G®o¨¾;pÅĹäþ8:»9;ú Öyn äÛmc Ï¥òÇ3¯jVÊ;&>äÂ|©eÿ|¿¤ ˜aUv#ÇëÄç¾GÈ@%5ŒÜ¦« ¬8ÔA£€^öOK3 Æøpâ"¡‘,é<†� @‘°»†ÉNàáÂÌdî†Q‚bò˜„"Ÿ`r(±ÊtûÿNCÎ…½wƒíè·®vrÞ"¬V¸¤¨Xlk:ÊÞÞÞµ×^ûßù/^¼páBÎ)-è ¶bƒÝË@¤Û‰L„ìD\ ºŒ Û=â³ÅfÈ‘C(63ž§€ ¼L:½9ª@Õò|€#`3bu•²¾¾n«lðÃ94"¤Dú­­­‡~x8ž<yòðáÃy¿Qö„Ɇ€·Œ½ŽðíÏgÆä&EgÔ¦9(aä"{½ÞW\qþüù‹/bLxvüøqpׄ–tŒÖ××s‘Aí¢HŽòáqùÌÿ<tèÐòòr oHÂzà9‚‚Wƾs•‰˜“*¨É&Ù/p™ÐW… <Öæ˜_TDm²r÷ð¹ŽoØv‹ �[FÈ‚%ºÚ£G.--Å1ˆßÌ>â» ^Ac%`…@¨ÆO–TÒ-4my9dÌ „‘ÈdͧÂ�@¥ÀµQ?1FÁö Ãù4ÊwzÓ^ÎÁÿä%q°Â3!׆+ ÝžŒÕžNEc£LSÁd…£< ÈÊÊÊ'>ñ‰ååeˆ@N'#ÊaGQ•Wª‰[¤¥�îä’ë¤áaIYˆœçë4Y¯Z4H”MþŒ"!ã0Îâ%@Þê>“÷·F„Ê�‚3ÚCíòi'Ož,¥t»]ò 6¡yä>Ή4??ŸŠ$&lØúRi:t(ïhccãìÙ³RƒÁÊÊJ~ lPΧ6Í[K{™õ«‡ŒqÔbÓ¨0a†™ ùðB$îî®yN«Ÿ»Í†=‰4m€fi)‡>z5¦òL&|ÐŽiöP‚�XãI#0k{vv6…BÐN¼$` äÏ~ö³_ð‚|þóŸÏ£ö�›ªqUÆ® €“te&krµÉynðMX`„CN˜ßFÌÜNãQOÆ38rF5xª‰ëüC¦eOÞì4äÀk‹ f;Hƒl̹déV§Mh¼©Š†~¦Ú Ý8þ|Tîæ({}›¦žgÕâ d4–Ié>‡ÇÙ(]HœÊ~Û(Ó1 L[ùá¸íI¸‚,WõT+v™[£¤¨‚‚?hCbsꕜ†Øñ,‰ÊIØcs€í4yF˜àM— ’Ft¿ßÏ'dŽÀòòrð7ìs¶¶¶z½Þ¡C‡8’€ãFÝ“ièXŠYf î�øÊMp´Dðr…Õ©‡®”(ÌY “Ëm<ä‹Ñª1UÏCb`é*܎ǺWýsú‘|¾ÛBü2—‘ß·[^nþÉ“O>Ùh4.]º”íòÑv±E£˜èãò:œ†¯a'êÙ Ü2,²jZ|{ƒØ!‚‡à¼ÓŠQŸ9V!HÇ»Äv§!ç€éѦ<Ú¼¼ «:ÀC†�À8j Bˆ=€ôä™Zðh#µ£@FmØÎøZé]¤Ä$ë·š¬êñVí™jVÄXF<f˜6CÔ©æYYÔY4`ÇD#Ï•Býc‡7“0PàïÓ2 |”ó.qÂÆÉ< ž¶=UAoà §ËM<Àˆ õkÎý^¯—CÖm4=ñÄ‹‹‹‡JPñø¢~¿?3ƒ' ¼Çô¢áÂåÃ777™ÏW¥JÃó´sw”5|>ÒpUö!]ÊRÉCN1t #£s�GöÔ±ì²I•‚½?ÀÊh}C+  ™¹¨¬[FdÚvgggii)ƒˆ*ÐØÛÓE�eåÇÜQè£'Ͳ[v> Ǥ5LPš‡æ-ÏK´žYN•ÕH2ã6*ÉA‘SÃ4ä|G§Óé ­³ !X*‹ØSÈL7`­8¦žÊ:6÷Ìêkä¼üNÜ·øåç?ç§~jîŽ;Ê—¾d€k’¦L n‰L¥ìq H¸GjÌêˆAg¾h&r¬Ýý²<‡‚_§…Fê#ÎÏ?L…‘³›(›*0:ÊÙÙÙhPò?0ðÕ”ÒĤ{{{Йc«×ëa;†]±̼ ܦy†y8©–rB]ºtiooïĉ¡)·Ûí›WWWC½Ë{Ϥ²ÄRî‹3¡ÞáuœÍ)T,…H™óôXÛ36»Óé0EÆì[ð=“Pø–¼KÄl+itຌgÞTévuü(«ªàD¯‚¢ #¾NìpŸó¾”<*oœ°¹0|Õœêñÿ¡˜V~¯•c¹N¶ÛÐ[xrrv‘c¤DO £v–Ó*çë%ä˜ ]A½¨ÊÁ©œkpbb[ioÚÔ¶Ôé¬~ëÚL2ÉÖXÇŽ—Ãwnnnûæ›wÞøÆöOÿôðöÛg?þñÆç?OÚ•6†Ç ø¾È|)_Üã_à&mÙ/¯¼ÙMÏ˹FÑãêæŒíLÌ®|�ñ·Ë@‘ã\¥9åáäÉäbb‚‰.*c!-á6^>'ï%2‹pÕÊ~•8òš|W†¹!=É%ñíæ¥Ç³¶¶vÅW 4 Å O/•‘ tï@ѾpÖ@”Çù¦hVÞ¯6ÇãôAJbá=ØiÎq·Bæ6±Ø_lÐÄ3–qû«XœH\‹[Ðf÷&²rÛÉMB¬-h‹æîT¥¿ñÕgDº<¼Çƒº \ ±O­³öó§Ü$|VFP¼k þÊ^â¤Ü-;+å”ÉÐ3ÖLzrö5�ò3„²ƒI$É@iPƒ>{’X5P€8”í ÝX?ç ˜9úm#˜¼~øâ^óšöwÎ_¼ØüOÿiðÝßÝØØ˜ûò—Ù-ff{, òKÃ8’�+ÑI™å„®èÝÿÏͲ¼‹xÔ@ðè’㛘k“ºÜQ'0:�I %õ%ý7믲øgJ<!-†f )ªž<´‚ÚrÎÎÍ͵Z-Z;ž§ã( ˜RÊáÇÓãÙÞÞî÷ûö  ×®ì!ƒ±[ Üòô2!¯ÝR>h—‰<\j0IºGügö[öb’pÈ_9y ñɰ.!’8™ó.p‹ÑkÛшRÃìm2}>^O5Ôʾ|¦“‹ØÓíU#Ò‰ìe{ÚV®nÖ6埓V‚ª9FÍFum(¯hàž…«69­ìT¦$éîåÀ|…UÉbT›ãƒk %g1„ÅeS Šœ©Ø?àæÄ�Z˜ÎÌÌtnºiõŸÿóÖ{ÞÓî÷_~ùòùóåÃ^{÷»çüÇËòr‘CAÑô¢)ÁÃŽ¶¦8;K…͉šÝ9i‘¶4GøW¦MS?yÑ*3©=P‹f¬çd»#Å/ ƒˆðE`Lƒ®JhÇ 5Ùh4ŠÊgøxÛôûý< f”%ää¸ ‰9DmøëÁÖpGÎLS“9„YÃiÆ GRjelåLV†‘L“Œ94©>s…Á!}î X´?…ã„!2r¬<Æ<^ú¬ã´¥BõDK‹ž˜–›â-ãŠÓŸt, <ÀŧVU·¨)]Rx& ՃѰŠP•& dä»›3ýÔÓƒ;Ùe|H€kÓ7X]”ŒdT8×¹¡Ü€§0 9 ©áŒ+Qv).À>Þ…VåBK2.Ð9DÒL˜clò"k)=óíkkkÿò_¶ÿý¿Ÿ[Y9~ÅG½xñâÞÙ³ ¿ôKïyOûmoƒþ›C@‘Ú?ל3Ô^;ø7!𫿴޳È5µ‚Ééa¢*àÄG€M|…_›ó‘­›‡¨‚G2ÕdlÊâT–ò"»—Aàöc-ã¹at¡ÓÎ…k¾ººJ X[[‹P¿ÓéD.³¶¶†ÞŽ�†Z1Üäå¦÷3??ßëõàƒÅ¼`{{ûÂ… vMM–§±³³Óív™ZÆŽ™Yd©ilÌ ëŸì¡IB2N^T& ™D#³ó Úívà¦<ó| ¯5¿Ã˪¦ÆEíË-ØÂTIW¢²¤ù–³ÑàƒÙG¼ì÷eG‹<“‡“ ¦ICõÓl6í_•Ó ÛíF\Œ!,;×ì7ÅY_4µ(k¯Ùl¦_H‘ ¡ƒuk‚5…~6¶H‡ bxm:ˆúë¢Ê¡(¶ ìã>ì–æ ÓÔ7ü‚=ké/Nœ×½“¯RJçïìÿЕO~r顇666ƒÁΫ^µùú×wÞþö¹kø†‰À Òögü[[;YT=C>v;×ê÷^¯7⢩ ~ìÆÜÜv¶ï¯;>žç|§ÿoÑaž ßeÚýyJ9DVVVPž»Ù€3 ®'³³³9Ð6­¯¯/..æQ¤<J’»¼¼œÀç7Æ d9…9¶¡c-šÿH;=~ÆÙ‰Bu¦[gã.7#šãò>}þ3Ò|+š‡Äx’‰ÂpÌLÚDÊJNY�?¯#º¡ÜÏ |Òs9«ÿ„…±b£|©Y Né„Å=^x/G<½=d›~#¨ú`@Ъq“Éra´ @:õS¥ ÊW5‰++¹iÈ9€Ã:6ÔðÒ;SÑÄ˪B…nÂ¥“MSa%ðçœwépIÓœ)Û.´~ã7¶n¿}}8œ;uj÷¯Øú‡ÿpîW~¥1nÒ0ʳìwá…œ|6=ƒJ}fغâ•ýSºÆñù¹!IE˜ã5ÍyVv­'³v¥eûwÎÍÇœSp,ÉsH;o]°;¬É@`o=Vp?—”kŽCh>9rœ4„Ž9B뎷`»Õ¼â\dp$Z†« ÿ‡P0??3·@¾È×q+‡ÆRöû6ñ|0眪¦`d M ­ˆLþì_«aNvö3·ÓM;›q¿ˆ«ª¼ïˆº*&D,;Ct»?šã©×až[Ê\b„—Ñh´¼¼ìê$<‚½‚‡\TAèeWCB Š´¬àAÊ@=õ7å/¸B5Ohr’®–Mnö ç‹SZæ?ª ˜a?ä×0Ñ)ûí8«©Q;v©;ö€ÈésÌ=ÛüÕ_Ýø™ŸièCÃïøŽÖÏÿüÜêêîXÕÏ4¬uY"Z(ƒ/z «ù£•�zè䇽½½§žz*¦–æ¡È ªâ$ƒÃ"Èä"ÆØ0@šÞ8ý‰XåÆsˆãðOƒªHÊG$ÈMAv?ÙTo¢Z଴(òô†ÃaÔ—c¾Ûíz|8`=#*ÊxÈBŠÝ°@핽¶¶ÞA–«TüºìÍWÉäé%r Ã?Âã«môà¸bÁJNê\íI¾ˆ”syÓ1’©˜]؉b貯# ãïužÖa8±hB#x²‡ ˜'拉ÈÜT·K ð†µÙ>Ð%ò›ôlÿCjk¸rR ¶ª>a3ÑËÅÅLéÏXCHlØÇè„Ñ6ÿWF™9íªpÖ4ØV?M'ƒ,&’ßDã{{{ ºo{Ûà—¹÷ö·ïììlíÈÈ©ƒ°}ÚÍгx›ûj·Û˜SF8aä+ G¸; Šm'Ó"*Wã‘ _pü ¯¨ôEÓˆ“ðæ¹­²©A MRõÜ]Z ÎþÌyãtF&Ii‹s½ÜÉ2j:O)yøðátƒÜŠÏ#EUãV}~âYÑÚN U ²G ˜xLíÃ64½„4cü9¼—<10CÖ6e =-ú7NwˆüE�ctÍžrÍZ2èd‚ã (wL§Æƒ}Gâ‚·žçê2¾�ˆ_µüp4‚`ò‘ÇhU´± jö“ÁY®3j³Wr6X7k’„�‹ñ©ô€Ø ð* “]Ðå£LaОó9ÿIAm~$ç8šq,Áå[ºo»G-pjD?1³ÿ§ì·–1æÀ&„¤Ä²¶»†1"><Ê!ÖFÈe˜e…?;M¶¥ ¸lênònŠsßókLÚN`R3ÑŽÙÏ0ʃXÈL”­ˆF)aóQÌ%#«€*ÉìNOg¸Ì¨Ž/œ4Ÿwðà2Ø?Øä1¢œCã´ÃŠ›<y“€ Hà¨Ü1Ðg•.ÙúKú±Â¤1i6©Ìö´ñ(H)ó÷ °ÙšO†èfvœCL®ÝDÝ#N*œßwtv]m$Z¬í5@6�gÝžK·iÈ9ÈB_µ"£xά‹¨îéFºm`&1pMÕÿÇÞ˜YÔ¥”îìüؘÃã .óµÛ_3pÈ!1›½ @dõ23©Üh=°ÓFEçٳ犹ªlx§ùE^#H*/èœø~¨;y\]-®!äBsޤ:AÖçÆáv4u»Ýíñç©p"Îô·u&hFj—œ,¹ÂP¨=^/ŸŒCšg$S+‡8Ç0S´&!×…ÆQÅOÉU, paó$´ %êà'µ ŽŠûN5¦…lCÛ±TŒ·R*H`ò™#ÇaIpƒTÃÌ£òÔmO:§^av*ft´vØ&Á6Ã1AH”èkÓ[£ ävæ…¡n±Öéî{Ù‡šO3ÓÊþqSfˆ ‘Àë°Wy‹LCÎAÒ\árFä­g92‹‚rÇ f{ 0©Â+üá9X!Ÿ<k4Zk4~mvöèÎÎÿ3æbþE¯÷øhtÛÖÖñ­­ÑxW绂9Ót&Ë„Í,¸XUr=hq¼ó'‡×r0E`èÑ´‹I±-ÁËÿ¸7gɇHòJûp „ñUJY[[ÃPkknng8̹™½…ÔIp¾AxÀRR…ä8à¬áÚÖ—‰™âä# y¤mwPryiºÐUâ ¢,É9(;?!scc#"Ó i´¦Â·çÁ“6DãHà,Tèsž¿Îc„2à Mb¡­‹)æ<¹Àƒvðí¯|nÌ%6Èíœ4äàÑj¼À…ÓÝ�� �IDAT»d­ãÍJ1—¯¦\›¤ Ó‡gSº¡(½Ê~3žoÇÝÙŠömºqb Þ tAw‚+÷ g]å™F¿£7°jð�éjÓSC^€Îè½±Q;B½Å€[ëÛ³µœZÌè1½V}6›ÍK;;?±¹Ù*å%×^{øðᥥ¥;ÏÛÝÝýÍæl³™ gm¿‡®ÓM…€œE’"» ~3t¤|X„q–U„æ2v6ó¨ëÉA™Ùøˆp/.­h~~ {à ›ïxGçƒl<ð@,`¥3£:è{)½šÌñr¶jÃË÷Ê~ý£=äÃr³ynÉ”ù´PbÁ3Ï¿bHÝ‘ü!ú¾4ÃÌÿ&rÄÚ•¶M|ööööVVVð¥F-›÷œÊü§tãl=Ž®ð"ÍLmÁ•’cš¶¹Û ¹ &ØÔ…ØY47¹ùÊØË’e“áîŠli]­½k=E†ýî>ã=g$*P'üÏ\~}ŸØ—MÚÌäL /Éé‘ϧx¢÷DWZ/8û¹…/–éØÁ]Ì'gH9�])§!ç`ª óÊ^SŽ8Á¬šœAvB…KÒaaow÷å£Ñ=ss9qâ¯xÅ 7ÜpúôéwüÝßÝöÄ·ìì<ÔéìmlØÂ„¼¾ýÓ,’ ã*ήhœ¿€ì>¡Xèd¬æF{ÏǼ+VâŸÉ¾®~Øœ>ÂÈzºÐüÆoÜ~ã{wÜ1xË[G¶þæo*u·_©ˆPÙì‡ìÛÐ%§9øcÖXä§3ä”ÓS~ÍâCÁo‚Lnn.5Jž3„cX‚æˆôÐ"òi™—îNÆçìŒ Ž•ýÖàÕ°A§üÄ' ·c':Î8³žXo XE” KJž)¹)¼)Zª yžõi{½ªR)r-ã8m‘¿Ðƒ¤ J!ȇ¤&6ÔF@"“� ¨Øq¶*ðph°LÓ+€íC›Ü€10Ã)Ã2¸NÒŽð“xùqU”ñiÈ9HHº‘“ Àîô9í3C¥¦–!ª÷øg+šÍfcgç›G£ß?yò›^÷º·¼å-W^yåæÏýܹÕÕÞhôªîÚÚ·ŽF%MæÝÝ ¥üx«UäМ`À£äNØ·œóÅ©%Ù½%G¨}¤æ‚Z@-e'T½1®«­mŸY\ÉéÜÜÜðê«÷¾ýÛýöoÏ^¸Pî¼spÛm{››Ï}ŽhJÒš,©šî �Ù“ÀÂ"®TP¦�Ù;„ÁÆF6`7È9¤’û÷z½<ðä­V+Úæ¸„MZUì°é0–”Ó*g ˆI€]|*Ð/:vûT.6·¾±Qé·Üb¤=ƒnšžœu¸°6øûܹ€¸8#sAP¡±šŽÁ¦3üëÒ™šÉý$^1q‚¢ÐÔƒÊÐÏ Yu”ƒÂ³Y§›”_ñ’ª9&žÎ`]3t¾¬1k®auZ\±3¬™ô4ä÷*«)8”ÏNÙLJ¡Ô`ŽŽ[”6NÍ[·ô𩵰pã7>ïyÏ;|øpû©§>ÿ]ßõð_üÅ«¾ô¥°³sS);3ó¾v»uüø¿}ì±+U³:Ø PªìåLo<«ÿª«®:þ<S«ž<@bv~2>†“šbWqóBgð ]ÚNÏè1ZMw7!jwwwwqqû§úä{ÞóÜÅÅÎK_zß}÷Í|øÃýÿñÙ~¿}ú´MˆQ´8»]áoH¯œ/ç¹èÓšd»”ó‘j%,nÊUrkKKKPŸó²666 ç‘4¬®®!( ‘â—±³_Y®vii‰xÀ5Ç­: ÓÊ«k4-..f6vþ?%—°“k4‰T±”bÕ¼júáз<»Ï-œ”YQÝn÷E/zÑööö—¾ô¥•••\sÍy21ÝAuD2�eg ¤oyì<ŠüA7 ›²Âf‘pÕ4ÓO˜€À™3S*rO ƒ¨tó|(õ@é]-YÖjd¡·‰!n¸Úrrà'ŽI‘Ç'mÄ`Nf‘a{ðI+—¢™ž€ÚY%¤lôWF»»ÎÌ4ÏŸÿ»¿üËo¼ñ†n¸~0øì¾ðs=v¾ÛýâýÐo_ºÔüô§ë‘G¾õÖCüà5W_ý¥/})ào m¾ $È/8eÆ'£²*FOÃÆÚI#U©ÄBÏéÌ»WÁ†FÀŒ§Ùl®ýäOöî¼samíE¯zÕsžóœG}tweeác[úá^xûÛ¹l;¿ j~‰ÅzpÐ]áæ ©p‰ã‰,Ñâ¤tß’^2˜¹¹¹ç=ïyW^yå©S§}ôQ¼«Ã’ ®Ð”Žt8(40¬Ïà PÎò¨ój¥ 3 &U¨½^¯×ë/"X’B’ä…žŸë&èä¨c{Øð—qœ‹ëÏ¡Óé¼üå/ÿÁüÁÍÍÍ~ðƒ÷Þ{/µ2etò6Û U¥@|Q£'³›27#é0AùÉS ?ÅàyhxNbL%ÀhÚmF¥u:ãó§˜Z*^4)ö³£Xc–päzŒ ókö„œV9_èЬf*{B $ uê_“S‰[P«Â{'óE›ûGÃá³þûÿÈG>rýõ×ÿ>zËòò×]÷äW¼ä%/ù×]÷ñ£GïÁ¿ýüù¹½½Ì36÷”¼Þ™å<ù>ÿ$¶’–¼Å¥£r™ãt6&Sl�РÇ7K†jg\d0º¹¹¹ýÑÁ»Þuñž{þò/ÿ²×ë­¯¯ï½ìe›ÿøºãD$dšðe¹¶¤ùÑ=…ú¦ÅÃ†ÙÆtÈÙ·vñ�^%O•)Ýn÷¦›nºé¦›.]ºôðÃãÄ““w5á,É bû“\Læõ¨âò‰Ö}{{{ee…¶„cü ^ð‚#GŽ|ùË_>sæLËW ±Ká¦ì>ž5–ßÉá¡KFN[Ç`ž?%~—¬^Ú O=õÔúúzº)p,ØqÈzƲ­AA Ã4 ûI“T%A%¨`´RˆLÄá+‚ˆBaEG/ÖˆYenMÉO/j� »UÆZiðä‹Ð[íÔét¦ºœþaöT6’9ïö°!a·Ø6ƒœ”3ÂSž¼X+vÙÌÌÌÞööÌÌÌÛíçíîþŸwÝÕþoÿíÙËË7ÎÍ}ñmo{áC-=úâ¿x{{ûsÏzÖö‡>ÔX[Ë÷,/J çìÔàà�ÞlŒµ†ÁЬ:‹9hòXÈsÉÚØ*œø49ZƒfX h;àp ÞÛÛ›)¥sçƒÛol8œû›¿=÷¹Û¯{]÷Ãn^¼¸½ŸZJÆê"é_þž €X«©&(ㆀâ@%+1×Ö·góÄë®»î:}úô#<‚J m„Fª+Äöp½rB%¨ä‡Ø¬Ñ‡†Š6ìê°¤®»îºïû¾ï;qâħ>õ©~ô£ý~?å‡òˆ(éªÆ'‘E29¿ÜT`ïóж¶¶˜!M¡3ï½÷Þ•••ápøè£Â]äCÈíìŸDÖâ†? Uî÷˧‘,"3Ȫ6µ@ê,T°Ä›—‹Èr)\A÷ í¶gls*nrf¨O7eÐØrÝÔs{ØNCNa9rd~~þüùóöGpã~2c?Њr ÷ûý¤®4ZLËÒŒ%Æÿ¾µõºííf)Wîì4Ö×{{{ÍÑèÚ÷¿qggïŸþÓ�<òÈòòòñÑè©§ž‚½ã„Ñ*n:ðtq¸€ëž¹€.GOÛ±T øŸIÀ³è¬Œ&ÚÍe›9$[FP™»| ´yòÉÖü›ïxÇÎÆÆÖ[ßÚûÉŸÜ[YiÌÏ3ÈÒ²8À(fú’¤3¯_�c&•Y$ÍÒvâ\åÌ"±MÇ›²»»{úôé3gÎät3aÁ,ŠfHyÔ€ûæÖ'Ëæèa� 1É3ÍxGÌ­ˆ8‰Õ˜&Ž2æ­9§¶ž– J�À\c\ë¾”Q;Žl4a1í~衇ðã] =ãÁí®þ”O$é1§H§]è?0ñ`ö[ À¢¸Á×ÕóuÊþÉ:•³9Lé®FÀ Â íHba{\Š!ì9²8MRŸ†œƒüiµZ7ß|óÖÖÖêêjÖºùKUK™Y[ ®){ >Ð^FpÇ­”Õ›››wÍͽ¬Õ²Æo­®.ÌÍ}áu¯{ñm·]wÝugï¿ÿþèû¯ÿõ kk¯ëR+$ y ¿ËCéä—±SºR摃Å!ï�wo“Ft£Ñ5›;Ïþ̽÷ZhVd¹8€¾ø‹ó´‚t‰ 9lnnά¯úÙŸ]}Ï{ýð#3´Œt’­dr` xÜŠbí÷ïÙ§3*tz¶öª*c±dЉ|2nCÁǃAú7q®Ë£î÷û<husdàCœ FÄZ$FNëË AbdhÖE.[333gΜùÀ>ÐjµN:o7Þ)¨`ž<§oÖ²­ðÊ0&‡œÆû54ïÎÊÊf3˜I pSECÆ“I¬´[8µ™v-Ò! ÁÃCÿ<ì£hšœ]PZÝ8aï@W°ƒÇ B4Fѧw]<;*‡_ïÇ i <öÊâÊÕ{ræg{{ûþûïǺÊÍIsImxcÐ AOå«p”Ìzr HÑðMSJövwïh6ó÷ÿ77O¿öµŸýìg/þíß¾óá‡ÿm³ù’™™ ]dsdÇ„@»ê²R=cØ.ôDãMÊFcª‚ óÝÝÝá÷ãĉf§Óüô§aEW$>Üú�ÆòLö¶ûÍ3o¿ãEb#˜¸þ:1ÐQèõzùöN§³¼¼Œ ³Œý(ý9eìA‚ª´RãxMaš…a¾FpÜNNؚĉ0‹F#ó“`À€püµ \§â1²‡ÜÏR†ÅµZ­¥¥¥Ï}îsæÚ³ü0ㄲI+ŸOÑlßJù¢ÑæäÙ9þ•͇.cçkÚLK“´ôÇÚ²œÎívÛba2»ÜV†°´‘ûšôó­üf,‘vÐBVdÛƒÃÛ3a>\y6#ð�ȶ¯„ì² ¹Œ}@Œþ†œûÉB9{öl³Ù nŽ¢OIc)tç€9Y¬G£t°Ÿ‰È9ÅL8¡óùÄÖÖ;ôçþÊ»ï¾qiéÔ`ð¹¹ûggËx2UˆËXµ»râ`j·Û x0e³ ÝŒÉ_¶Ûí£Gfð¨]¿¸Î`/¶ú¾ýí³§OÏ~â›ß÷}sÛÛ»÷Üã?ôɬÁfÅÃ⣯¼Ch&™ùS$¶wyÄùÅhKËBÁ| SpÖ»Ñe¹<=v2¹¦%îHNw︣ÍÍM<{Щø~·¶¶ò:òáæ³@¢sUçl ·œaÆý9ãŒãF£õõõ0À6KydíR2A•n0¬]”,ƒe©x~yWž³gÀ89³ú„Ê’yÕY«³²DÑÉÅPÐ8’f„áYÙŽ8Ѥ¢µo¯#éE 8F3 ¥Ê¨Ì⡦¡’f$¹ä4€i€Œ²¦¤æÆ¡J“µ°Â]MCÎërÜ÷öœ×d=œ¬Q[±´¡‘Î[(ª×\sÍöööÙ³g–ãýç|Š¥°\Êï ‡;Æ‘ápñ©§®ØÛ»¶”—5{¥ìHö™1‰H:g_»ÝΉ†›l í "L<~üø 7ÜÐív¿ò•¯|õ«_]__G|Cø4S`nnë­o-=4÷§º³µ5÷+¿2ø¹Ÿk^¸Ð|ä‘"—¶‡¥ðª­~ Îs¶Žï/]_‡î×ÑÅžßÀº½½½±±AöšwÄTi^+)-K.ŒÆƒ½©xþ'ÖÒÄ&€ÁÈŽØã½ÃœÄ"Ï”“IŒŠ&`:wHÇÞć•<=†ø§ Ç—ÌŒ�âgYrí$%¹Î † XBÇÀ ®Èµ²Ë%á„M½nZó*i”‚kÑÃR3RhÞr!Arí N²Oá …`T‡k¯íímª.ŽŽÀ€6±ö¨%P– ݳæ[åÒÆ@K5?br€>@Ç‘ÁQëÑdE“w-‰`WstVÙMðV|±ØEcr<æ‡ÆGm«ÕŠG¡5˜3b‚YÌXõ6p©t¬ôœ¡ºÝîõ×_Ýu×%ã>sæŒID•‰õÞÜÜÎ[Þ2³´4ÿ'Òív·šÍÁ ù¯þÕàýïŸÿÍß,ŸûœOaDgLf£Ö)cÿŒJ0<jžAÊzš/ é¶ÓÆÀYœï9)n?Iv2Á·š]ŸOŽ5ާÁª:C<í”&ùèH¡gâò`Q§£SŸ°ã– ¼'çÛw»Ý4)]‰<Xá1Nê`N¿©<aúIùŸ—]vÙ+^ñŠÕÕÕ»ï¾;ÞEÉobð¨‡ê$�êŠûÿ¤ðy,lOß pÅÐdaM W @ÀK¯ÖCÖ]VÙëéj|0YQ6oådS4ßÝ("ÎôdU˜É×yŠOÌ  hjè´˜†=ˆ±õ¤G¹­mÄ߸±r0n 3ƒk:u *A…°9CÏÆ³ËVF­”ý6!€]õ<b¦b¸É˜}Tn„>ðÉ“'/¿üòÌ+ƒ¢šì´×jNœ˜ðAË*www§Oï<÷¹ó÷Þ[éhÀº†`ÏØ¤2º·ÒVM)é<}ÒŠwÜHaÜp²%vUÏY*ïÁB–­p¾“{RõV,p·ÖݿƢüAœŒZ€ o3Ø,™>O ëmMN¬ªÐN^SàŠ&('¸Ò“ ¬æJÚíöUW]uñâE#•rÙ¯A†Ån 8ÀáN§CAŒâ¤2ŽÊ§1 È]U££vi«„Ò¬.XÎInxþ~×P¼1vªH¡ŸT“´ìXa¬Œ½ÃïÚ3@V³±8Ý…/N¶š´ 3‹iÈ9È^Ç„'—°Ê=¬" p?­T·"'­ã}Ä3N#ø†óŽ Öà/-hH�XXXã(‡&ØqPNüÊ—ž¶jeµyîܹ¶¯¬¬d¹g‹R@8nnn6~õW·àv76Öî¹çk¢–w¾sî‹_œûä'â/ؾÅàx‘åIêK¢¸ý"¹x›TBÕãxe÷r¾[ïI^Ow¡r%ºf¢" (j¾-_gÊ$E&l–”#îñp?è'þ›®ò7•À ËèÊ1–tž3kuuÕU I7Ï„Ò8Э ^¬È²²F)å©§žúã?þã~¿oª.âGZq܅Ǭ1MŠ­ºU™Wšii4¸™‹9Â@ÅÉ$ƒšLzf2e„‡ñH Ød„“zO[HPqÎã…àçÑ ©Ì,`Œžù~eÿ„P'¦•aÒ4䨍]Od±z‘#ÏlC4…ðÓ»à™õiÿ"„™lhâ r¦‡LâF ¢€½¼Í²Œ¿C`»xñâ}÷Ý·´´Ôét.]ºD#½Ùl>|¸Ñhlllà‡Öh4ZËËówÞÙ×»vWVgÎlþàv|pæSŸÚÙ?Ä•œ+Sy x±ìíÿÉ'Ø÷~RÍãÞUÙ?·Šö‰·tKÊG[NqÌÙâ¬o²h°€Ôºb�¹ˆU÷,•¼)ª‡=^V”.Ä-fŒ¨¢\ÜT·Sd«šê¤ZQpó¸ú~kå‚®càÓ³gÏúFÂYöÏ%K™ U,œ~ ø=ÙŒßE S[.šM? —S.)L½Á ‰L"û”?çŽb ÓtÒ#›ö&ç§ñuŽ÷¾$È#¸ì¸Ì)Ñjµ²†ÙV[W/.ùîALCN]Ä™T(oͼujyœ‰a—z·œˆ%=Ù¢´„¦ l‹8Ñ*AM{[ Õ4õü~Äé6áÌÑh4®ºêª“'O>ôÐCçÏŸ³ÞÝÝ-«« ÿú_ñwzhþüù¹O~rsk œÚ s�"oÄ:@˜Rs°æô÷¤Kó•9Œyæ¸4ÈÎÉîV?"Õª8]T-9ò«dãÌ"¥ Ï\4üÔ¾ñÕX—ʘùd®™&|…¾&*ä¹y ‘ý¿«å”Ã×Ðn²Y–JµSpò¬Û2ö€0fÄ;B/*1\¢ýòX8jé­Ú棺0_†[2´÷<Ín‚›^UM`5Ø8SG=ڎǽ€ c•É«< ÔÔVh{ nÀ¨‚P13K0¿$ØhÚŇ{r¸ÊI´`“daÑõðpò�kôa‘à®FõUõJ$½›°@¬¦ùj{ƒgâG ^g_÷T²666’4*loo_¼x1ŠBâ æh4j½ë]£òOfÿà¶5 &qexj‚C5Cžðé¹×î¬åÓH§.*2 VŸ˜”¯‹÷(&(&V™Ï½tC®²šv,ÿšaë¸dî8f<nbÁN†çæ¶„1 *·ÍÍj£Oîët†aV›kÀ^'Î&.{é"Öq-nM˜‡îxgb=­ª+ž7ÉŠÕŽWí¶IxpMæ `h-—Él<DÜÕìµ¢QžŽ:1M¨@Ѳß6Þ=È¢A¬4v0r)÷ÈÏ’¸ãª­aRƒ Ó^ÎÇÜ·œ¤»Ú�Àu+ÒÖ€³´RÚ­o–‘KVžOíª�‘Å» 76¡ÍøÈ°Z �*¤Á]Æ–––VVV*1öÓàx¿ßüØÇvuΚŸÆ%QuGŠ ißC7KS踫_¤÷täó#B’¸[Í–ç3ë—cËx P²uØk¯Ù«”@ÈyJçkLÊ&�„kV$‡Ô•oÊ3R«CÓÈ]´210džV‘×Í®†üMû½*ß1Ç4WÂÊX¥§bÀÛ¬Fðyfj¾ÈšdÑ•üÏâ¡Ê ›¡“¼|èºW´U'4ÖQsshàcZ,' GAàKÐ,³Ó 0ßêZ.Þ¯~rì'BHêzòÖCìAKŠ çÕ©P’Ühô@ÆànYàJÅÈ8öel`úÕìw×öÝÉùÅPÄ Í«Ø½žMl®Æh6›Íʱ‘ì/iâ²sêªÙøÜl6°µŠö åvòpBtæˆG¥DJqX¹Ï_ª® FÉxÎd7Ùä&õº¬4˜žÈ”ÞL‘œ°Ñh´Ûm– ‡µ+Ѫ#Øl6ãœÐbòu˜+H>3H Œ˜'Nlnn†0‰–þ5¥-ïÂ#X\Û‘„Y~T©/=|ŒîOð£«ÎGNnàÍÛÎS¦P”x0 E &¶TL6·W°½ÅJ»º±Ò�<s H­QqÒ"‚°c'¯&X®±8ûƒTƒ%Q /,,u@Þ¦ºœƒoçPÖ�¯1¾Þ0øEÓb¬ «ØkN,§<4{ͲúIý²žÜI†ö ÆmyOˆ"GÆƎɲNmÚ¶N\˜ûä–7»ë½• àj)øûä¼Ö¨/,,ØÎÄø^ÞEž€UJ|èK*îòp8ìt: —I*‰ØS6ÙÏ?‘ÕžnÚ»^D=Š |ccÃ(bž­éæUY–÷ë ¨4¸6íø}‘h“:0OÓvãëëëLýá¡à£5‚ìTdüZXUΞ¸Â²O=QdõdnB§OÙäÙ™"ƒP­Æ5·Íׯ†læÜÑà­o³âPä¨Ë™f÷’êœ …CÍ$ǧ}4sÔ7^Z�†®Ã�ôLcAØg°å4íå<¶f³}OÉ%©`Ÿà#kn¤ jãàPhìüÊš�±±;d_ñÐð+"œ‹Æ”#¹$*zÏ€áhuÄɈy±^îÆdÀ8(}ã$›�y†T^6Ô‚¬×Üî^žyUÆf?Ø{›Í‘jZO’²ŒÝËìœÍÍMˆdéñ Q¥åĘ”„š=ÀÈ/ÝR0èÅ9^m}f†7n{¤ÛvÐq¥X4tÎ…²/’ Úv;RöV0"g r7xkDAûÚñ¡X@ˇó×’ËZ+*£Ùƶr¿¤²©>Ø3Û°ò4`nzQÙ?Õ…OÉ.ì•ù“ÿ@r‰[AѼš†ˆ‰m•fÖÄ¢P¤Lƒ `ª4N@Û7y…%oM;  ‚ÈQ涬¡ÂÄ9>rDb¦’ï‚V›Øn·;pÁªxP%•(=á0ÿªÈÓÐÓ>MÝ©Æ9´xš€}Væçça%Qu!¼à™� qJiðe(r¾É^‡¤ºæ¤zª¦‹N0±8Íàæ‚P”Ê•ûʃÊG-,,>|8L!ûVÍ…ä@9ÆyŠàÉû?ËÏ4§Xçñ±æ†˜Òí3Ú¡—bÔ,h/Y'k¾² r<L¡rî)r¯ |$Ëöl4²¥JŸ[¬YŸÀM^`Säø·Äž9]¼µ£G^uÕUñ>€MIZ&ãÄ+йZfù"k�Qð7– ™Äojƒ!q#äÐèMFp]kŸ– ¼Yski,}`rž¦ñ˜Þã´Ž€¹%•ÅúbR~9ü}¼:òç¬Ô,k/3å ZÁ´áDk6›×\sÍÞð†ç<ç9î9;Üc°C’XÙùa¯¢JƒðÊZßÜܤ>«ú´Èë •±PŽ¡ Á³^’¢Ð–e<9‘ †÷UMîÉÁzäÈ‘v»çÉ&Ç·Ôíî|u®|£Ùl¶Z­^¯‡«RÞ%«MTË Z\\|îsŸ{èÐ!Î`¨(i}{ò·{¼<„�ñƒÁÀ1³ËpÝ'@‚÷Ò„·ÅKþÆ£im@Grc^N%èQ¶�� �IDAT°\¼¶˜4Æë©¶ŠÈ·ººÑÒét0¹1L”7Ë?äI’¿çórÿZ,Ì[3VL©:;;{ã7¾ò•¯Ì%`È3!ö3„]æ-ûçÑQeV3�-ò­`ºF£qâĉ£GšÝÀò`B›×Õ6ï””b×>ÓägÁv¿fÃzŠÇX;ø¨PcF#kÈÔaÏ) ²çy‘":Çtæõ’-‚0@pÁa±íǤT‹‹‹búôéóçσs=.#'ªì=|Z·ì©º4iͱ1¸jø$J§šz‘‡ ^áÿdÐÜ2£$ªöŸ'ïNåtå•Wnoo?üðÃS;¸Ým®šµîùÿvHƒîeÞ´·\ÛÒÒÒêê*] ¨*™=P!œ€3ö±‡4>ƒ¼V¤Ã·$ò›”Vž`M¨@, 9ŘÊL¹vÆ<†±¡vÚŽSC%i) À¬ O ee†ªnÎBX�ù'vÒsk¤œ©çòË>øàéÓ§—––p=€ìÊÃf¦Õø4ÀõÙü¾K·Ë••OXwÂê~RÁcù‘~•t/ŸöÁ`006¶a}røÇÍyŠ 'y©EX0Ðì”E‚ú×&톰,*’òÿþᆶ··|ðÁ3gÎDžbÀ,w#lµdV˜e̕՛›+)¶šØQö[˘ª`­u¶´-ºË~ëIf]¥™ìè’ïçG£Ñc=æ$=_±«Ÿ8ÖÌÌ̤˜(c×}ª±à{ÁHMluÍÁ¡ì†\²ïÜ>óäã‰]Æ> sû9Ü9ˬlõpÜõ;rmQéÛÝ]·ç£«Ï"Ó0ƒ-9=³„<”Ý…)´1÷ãOúŒ,d^q…âò®ñ ÀØ»*a-Z‰ÅŒÄ¿/¶Õ¥K—¼m‰.EÓC*⾩^„eݪ™jò›adÓŽ@½u•x ìw~38ìVœÁ´ø/ Ǫ¼¨mú9 9Ì %ôìK×¹fر‘R1>ͲM^–|9‡/I ÑKœlüO<hníŽa4"e5W¦Êš«yò“gè$L”.:Õy(§'tR2D7½M]«ÌåÀ»yÂ@dÙBAíÂ-šÉhõ"ÏÁ„œ7í^l-ó�åÃsªŠ½ìJbk;.æž¾À†tÑíí¸Äo§Õj­­­Ù¯oÒ)À¢.ß—Â*X˜åv¤fЇK½ dàÉÎ$¼q­[KçXä¿"W4¬dÍ<g7Îc®y#&ÎØœÔ) „ápèf›#Š%\PÑ v‘P¡VÍ9ÒD¶€‘m¨••PÆ)Ž/‰ Â'°/ŠDè„h"ŸEH>¾¦!ç€{9à-PŒ@W\P³·íÆHÈa¯Z[Y¹ÚÀö `e€ïyÚøÆ¹sç@ä\^˜ œ%r‹Ýs'96Î)ûýÁ!ÞÌV~íN¯¾zþñÇ9@m­ïº„:‰ DŽFëBXkŽ é?¨´¾Ÿ¶Õ#÷ê¾ù½ç¬¤VÆ(¼å2ögcËÈ”2˜–rÎbƒÍb›ÄåÒp[6Hr–“?G ™»  Õ\!ĉ¼mÙܯ & 2ÊšåAMé„Ý©´i<°iwC"èba,ªOÓL kXÆõgñD= …šAGUçàêùpû¡ñ:,¾A©3ÑI¼ˆÄV­™îÖKäÌyz1ÎÀ:â[’Èç0VË‹"ç�Ýn¦!§¸Uh’å$¶cxÍÂcG j‹$Ÿ. *F“;œGœ°x5:³Î–K‹ˆ“à jøø–гépÚÁÐe;¥OåÙnêîîîè–[6Þüæùßû½¹»ïnµZNg0¬­­åú;mn¾AòN.æ£Õjžr›Çe.¿ŒbÓ9£¹jNVÁöû1.á!YpôXN<=x‘ò¨âÅ:¢§®å![Öî⦲õ­HíV¨�æPZQÒQ0¶0–õ -0 Lè´yœ~qe¡&`Ô&‹³ÊÄ«ḬèQù—)õ’ÒÁãðHï\!ïÝüs Í11Ì` ™ý Üý2xe®¹ó$öÖ‹h\Êþ)¨•áÕEôgðTmQ4ÜÓ1ªqvΉ‹FBp©¦ ¡àž/øºèâØy‰F¬`—(öóçƒG&Ãˬ¸••ž ÈÛŠq60ƒˆ+•½ù¸û@¬fpym“uSe ªU#& Û¯yÍîË^6ÿÞ÷nß~ûL»½w÷Ýfß™æç’…°Q•˜àZ!bŒ-�¯Q¯À³~0ÕT•¢ÉFœwžª`¥ñC. v•T³ÞeÍ&A:‚bNœî·áäÏ]°çc}(µNE1pLe•:9Ä9ú9§| á[jn4$·`M•u³6xûL ôz WAP·ç›×$®ƒE“Ès‰ôöù.îšç8l±Wˆ¹Bâox;¬j8ºúµyK»â73ÍXHR%Œ*QŽÕBžÓãä˜Ç–ñ\WÖÿÁÆ›)IºTø˜FeB“’‚z•A56GRJê!cèœé^C *蟰CÑøHónsùŸÓ5nËèx]ç‚ÁÓR%$VÙÛãéLüæ›G·ÜÒþß謮Îÿú¯oÝrËú _¸´´„Iu¦�,ÞQf+˜Å0c: IÆ=CÚÊ ;«&Z¤¼£3<i¡f~AÕ®ãÙÙðœ~Üup6� “÷B•ã˜áâÆêKæMpyóó󸾌e¥ùtÃD[ê‘Ø®Z²î<|N¸gÏXÄp8B/¦Œ¶c^5JÊo„Þ„ØD¯ü(fsä@9K %î™É RÛå3É„ò™|‘õj„WØì<c²jLŽÒëõ 86|…ùŸä¬C,0w§ØþÛ�h‰ßÇg` ˜š©`qÕ¯i•s0?D~^‰{¿e¬As_ÚÍçML„¦ÞÝp‰Š…É'“È[»þ¿:W‹ÛÞpWó€[ôDSf4¼ôÔúZšvóÍ›ßýÝÏ~ßûN^vÙö‘#gΜÙúå_îßqÇÜp8sß}fÙÁCµ;Hr*w"„A$\,1fñÈÏÔ HÃQx80‡Ý—YÎ!Fç1/ µ³P±W02é‰Ú0¼SŸÙQq%«”ƒy>n`ð—¤.asøæü²\ÆetúIYºdnœ¸oaOñ ‹ƒ§©z'‰ q/5\æ{D%Ø—;#—Š_Žëzû\Œ'ˆÆîœN5ŒõU£˜ø‡d�Þ&p.À9y€•¶Æÿ„µ‘7¼G+|A›9Xü<9:ÚívHÆ Ë„ýR>Ü*k§UÎÁT9$¡˜ÚzJXò}Ûk²L¡ ɦn+Ž6R4;;ÛétÒtµ_…Ñ c&@öÔI“K§rLá|ñ‚¶I¶ÓaJ¨hôPر÷vvv†ßù ø‡ÇºÝ½èEW_}õÜÜÜî`0÷ño¿ùÍŽÁÔFÈi«…n'i¿ »Tɸ‹¼O<Hð£Ö̇„hKŒÏ¯%·¢Ú7Õ*5.È 8I« Ó¯FÀÈd0+ÿ]Ù`:é¶{�ytŒlÉ¡™ËH‰°¹¹I†­'ŽÅ9ûý~Âaåvã´š’—W†87UV2k²Óé õH¨6ö>:xwíÉÖ)£)ò[­Öñãdz)ÊxÀ–?“´¶¡+û¼‹”¼xÙåš«¶?Ô¡Êi&ßb$Ũ±±›‚_Êš»X ³€4XáöÎ(ò¯Ë·ä®É´X“£ÑèñÇÏP;+œ<ï©/ d¥xV9É ° éÄ_ó˜Y©€<—†2*&s!€Ñ |� œº„ΰ7/§î)ŒRζ÷ÌŒŠ ê̽L˜Û;Âqø¶ßûÞ­·½íÉãÇï¿ÿþ¯ÍÑyýë·^üâÎÏÿ|sŒþÓ—vïXEÁð©”mlSd“ˆªy£Ü’ó*ó” YÁ>(cïw>ª†îT¾×ϨÏ0dÇ]x¤gäŒûñÕ\D;„Òvrÿ¦šVîÚ7ß› ØX Á¬õ"èç$ 2v‡Å´ˆJxÀ"Góï=ÐLHæç篻îºW½êUçÎûô§?½²²Âª.òw좃OzêÀÝ/ûmªízçÒ*sŽøJÒKj=§š¾ãQån­…“B²e˜´šè  >™ÊÛ‰¬µ—GÆ1dÙC ­"ýŽ0˜†œ}ÐûÀÊÈôðI¤à­”É,k÷0ä¨ Ø_nqã—\õm‡žSÉ>¾è{ÊXìmÛç韂ÇQh‹É0Íö66:¿õ[o¿}pþ|ãÓŸÞyå+·_úÒ¹;ï,ý~Ÿ&ùç•AK& $£je¿8”€Ìiº§¿µ9–ø\�µH¾ì!Ü@ µôeû=Òí·J©Be‘£s…*3„0L”Žîäæž ‡í£icFbËØ• ŽŸ&ËSìŠFÐMƒMUÒ!WÄÊÈ�Ž™èöXòP Só=Ðýíü$+ÊÓèt:/ùËßøÆ7>ôÐC<ð@¿ßg¼ž=;À{=—í鄯zƒ€Z<R¢í®¼GÌÍ\=Øv½ÊWÊØŸÉX1µx^}XìÕt.ªçŠÝãåQ ì,´ çÇôBÐÍës`›V9 ¬y#yT_ÞbŽ÷c€›ÉGhx‚°òLôT’"'sð–ÅÅÅ+¯¼rmmíÂ… 7à*ÖXDÎêR™Ì£aj‰mÀqÛ‡„”•CÁ#ÎŒìíím?ñÄÜ¿ûw«wÜ1×jí¼þõw¿{g0ØÝÏ-𬠍• ÆLÓ{ƒÂ²€ç€ò u…àöm>½¾¾Î9Kt)šê!U.dÆOOñÜ­v» êX$¸c\žµSdë1A°|µh ¢(2úŠïßìõz'OžüêW¿ÚÊbFE1‡ÙH‘Â=Uµ=(}¼‚ï%üƒ)Ѳf6óp8Lw-YBÒóü×v‰©Ñ3%¥1XýÙÏ~vkkëÌ™3—.]b±›bãM/î!•+­,?óóóÙ­0×íšÃü\z*¬L¦µRÕ[Å¡ò]…ÅŽ,Ô¼ œå¬ïv¸Êï'b9ràa“ãˆ.&·`Œ=©g×Ôcí  ©˜xC’0—6¦]ßM¿á°0§eOecÒêN ½èEozÓ›}ôÑ}ìc/^d•ÇL‘×é3*’íäñÀÔ.„Æ7±…Òc4sßüéÊw}gg§ììÌýØÞõ®…w¼cg\$å­Lê0PÉéV¹ŽÒDõ€2h8Fc Œ Qç%"¡þË©‘R š¹GP±µGd nì¡2Ùæˆgœx˜t‘¥£mù-«ì•ÿŸ[KTÈY[Ò‚'žx"ELú‚¥”ÕÕUK øR“tI™ûý>¯,²˜<«Üøp84ñ z¤}¦]úT:‹ÆÀè¨HÈrùË_~üñÇ766 BÐP›¥¦ñ&¢±ð�+9÷ÞqN*2+³ï`FÕ1*r¸ñ| ÉÁÞ°Ì)—á¾¹Oyð?«¡•k€o0T‘»– [EÌïíB4¥dÈuVÍèåÍyðŸÅ">\*Ö1}7H+tƒÝÉþ–——3È ²Vv>Weiž¥-YÐôœ+PbÐ á§ò-Eïb¸LÏ�zë=ï)û}¥Ì3¦MÅU¡HðØGÿÏʾÞbûNŽ®B×Ínå\^¢~º8¼NÏJók‹‡JpI„&5ƒ€±l&e@þ&üó„]Z僦yžS ¿#²½½½±±‘²¸¸øÚ×¾ö¿ñÕ€þ�ÍÉàªÇÒü�A•í7hßIOÈ%¬fçÛ·¶¶ƒÃ?túàœ÷¸¾¾¿œÂ®šÚ@l°"Ê=N{ñv\L€[T=<RO}e&4QìYw9ÙkqŽ: %–“¬Oâ6M®3íÛ3èØÔ<òö­Ü˜ör8ä˜sRäÙW‰™í€o±Ñ$'DôàÛ0ë—%’úôé3gÎDÆï$Úé^süƒ¾Ý Í¢’0QÕ›“{ÇŽîŽ!f6?icàŽª™ii‚‘C¶‡§­˜¬ ÇéFSÊ{ÒäZ€‹WìŠMˆõ˜œ|u`q7umÛãî±7-û½¢zÁrÍž˜¼©J®d÷bþ¯•{& Äêêêòò2Üh}ÛÛLtøæÇû ‹æKr`9"“*Ñ;4CÏ­#~:¾gF®Êت‡Â%Ÿi2ÂÒjÒ«ÝØ‚¹Q@¯·3—Ì#$7Ò’$G;3nLÁ÷/) (góóóa¬äè X´}öq:? Õ®Ô6y8ô<¤‡.L¿v»]Ížör¾.O *+³*Sî³+’ATV]ð À4Àâ,`taaVÛ¥K—ŠlÄŒM—‰Ie¿9?‹):#9¹/ưaþ&SõpßSªÖ%Érb§{T•­¯‹³ è@þâ¦7P†3»"ÉžÛTÄN¾ô€žÞµANðæ{æ‹x6È YÈ,ßx.laaÁs9×| ZŸ¼^±àh•†€b<ÁXfK¯­­ÝsÏ=iêPMîÛí2ð×y ¹Ÿ­>Òs»Õ™‘_™÷€6«8ñ Ò•Yól,€–qGgmQ¹èVØÓC˜?Û‚ [‰^:4;;{öìYãØd%¸RÎʯ% }Ú„püÜØ€ìTôÒ %±Ø*ù6ò+7\�•ý 1Áê÷û“KÓs0 ’)vuÙïTÁ‘JZWi9‹ØXv`Ùnî%{ÊŸ=Ø‘Ë0të oi“‘èˆÒ‚¶àN¸G‰xœÅ ½« C§"ñ<ŒÈ¬Ó#7 ó¼Pucn\›’î? ºÏwQhZ[SñP+£‡¼ ÒL›AXlhŠ0jÐ`V´ŠüëÇçô¼ŒuÄM®³u…ïÔüZ餕M%Šƒu~ßýúÕ/,wµŽ  Jg+ºàËä2Þ;©˜%xˆ+gwPØG4‰û­¼p25 •!@&ì@ˆ`ò!~¤¬[@ÂRÊÊÊJ5îÈ .Àļəu6vòLë 2ñt(œ7yæyª”‰è4è3%Ú‘!-,,¤X¯�=ê`O[˜V9φmRöKÌ8ß-¼€YkÃ{sa,Íæ²³&ƒ8»…àÇõTÆÌÙêN¸`Tég«ÕJqfNv~0È1-Ó©D0tnA«<N'éþ„#\X<nÒ�‘¹³þ'”,œ³7|Å"&—[óhFFŽx±VVUý|'òEoè'l»‰Á3Žµçš«WF-Kœ0ZÈC³lÞ]4Ë/Ì‘ü?ºªÁãÌÝž¡ RîN›6Miž8ç]F½oÐLzÊ ‰W¾ÑE»ÿU•ÖÓž³Ê·XüƒÁ�œDYWKÕF']_)F‹Ì~\#º1 —l²b¦™£¾_5õÇÜcnFDsw´pH•òxçí}7 9ÜËÁòÃуÀFê¥i¼ËœàÄ$ñ†/h‡ ‡Ã@½À|œdúœòFö _xp‹ñ1kN¦¬ÛÛ#‹"9 ³…Â…µ^ÒmÒ` Õ¸OO ©D¯•Õò1Mq‰.§b0W¾v4l`õØßÚ&ÁÖŽxoó èdäY¥NʘÔ÷YÖc3½"kKÂ#¶*b…­ÇÝ�TäT >¬³²:†»kVþ–ñ$7O6¢–µˆ•™GÔjµ°¯…÷Å+#”z5B¯ÊqŸG¥²¤õeskbé«TÝ€Íyój2£e– þŒVRžŠ`¨ì×hW e%•uâñÞå¬Ëšá�C#«¨fǹÂc[ÙŸ$¶ä¹¨trÊ$`U©Ã<UŒ—JóJ@ÿqIBÚ¶ÀñA‡œŸš“Ov¯¬“@3¨¾Ùí’ÀÄÞ0À¹G˶Åð:ËÁÁá^eÓž•‹K©g„’ö‰Ì8d1³.!<Ù%� ZŒ`q¥ܬÝn‡ ÈyMIA0'-­<›#¯Á"Át8Ü -X¡J ÑšgKì L’ „™>×hË¿‚à@ÎHM§f]‚‹: ç“©ã™Âgçc¹³³³ƒÁ ¯Q$Ç+ Q“Ј7ÕäÀ……°ÜJÏ�õ+ÔZ8.Ц˜¡�çC§’Üó!ð;iÝP)ÉÆç}ÙÀ×4ŸŠÐÎQujYÞ]"tåIš?KÄNÉ)È4ä0°fþ+«ÜÂvïÇ»Âe \¦2Ö63!ÊÙßä^ó&åìL ͯµvízÅÎôõ»ÊaWˆ¶½R wLÛσóË»zÒ²ÒIXÞQ Ž6aRƒ.‰¸îÐxºsþ²ÛíâTï©áhî(w*xÁ±ÓD/sIðßÄ3¦Œ‡ €qbÂG÷ ^öZÈ%¡ieà#&¡~AæÛzÕoʳ½²€Û¸é ˜‰ M)º<ù¬=«j*ü¶È*‚*ŠirдR-,,9rdvvvccÃ\5sÛÊXRíÞ$Yò§ô“<+ݾfvYOÃU>®§ ó€®ì2ÒšªNBï•WIfæ~+ПPÍü®fx—ýSyœ%®ð9£Ñ(ì!À7{NZëNu9ÙÎ1+—•j×}v"ʬ~R>Á†ðv†÷ÔétßÑØ„€K@\âžP5ËÀÍaßQ¥ÿ òE›b¤ÞSD³«îK.É·É¿ªL³“Ѭ°gŽYu˜Êþ)–(Œix /\ç™™™Ë/¿üèÑ£&ì¢GÉnŒhœ.©¥,0±hþBÙ?Æó³)bàPÑæ2H–‹œ‡ÊØLaaaÁ£V…ä:tõÕWw»]æûÚ 8¹:z†›=�XŠŒÉmÍBwÊÒðÑ£G»Ý®ùåØzÒo÷,�r[.±ì)m rP¹$ÃYCÉËoÆÁ6vêZ§•"¸w 5>ÇãýZ³°ò`=©ÖÑ"ÝÖ}à`«h)lL7;Ík«°Àn²¦¤> 9r?Å"HEbBÚB¶5??ùå—_ýõ½^fFtTØ=ŸŒWàââ"¦Üñ)ûµ“E3r¢¥ñcÐ{{rºmÖn–&WK~Êò…ýläŠï® g1bòÉI½¸IVCÌ®r³lf;baÏ|âĉǧMÊI(‘­5×××i>Z­VÏØ˜Îä:w} {öW.²7zn%iŽ3†jã\¤^¬XÅ›››9³Èf¨“!²&¯¹æš7¼á —_~yn­Ûí9r$!ÓYŽõ§ gœïø2`�áAãæjã Œ-§¶ÿä¿é›¾éÖ[o}Á ^�™`Ù9>Ouii©ßïCº!§dô*P!ý!»ŒC_$ÞTžª¼µ\Oö`ð ™wSËÎv_Í t.uaaÁ&å@ŽåÉÌ<^ºŒÅ§ö»ÂæÎÕžž¢’ÚÔs¶ÜDzï0…Ei¥œk_åd¡ûø“!-ý_XX¸å–[ºÝîŸüÉŸÀ~Ž+‰›„žŠÈ‘º³³sáÂ…J"ƒN†a€™àOîᅉ׶W¡÷&U–fhøc8 S£Ðù¯:=î{©ó‘Áí›ed&Ô,Q'ß…w>H‘» ¹ZX×£ÑèüùóyJ|å]¤>sÏ$˜@W늰êmäQW”$N Þ©q°³ 躗ý:Y©<^ûîììœ9sfmmí©§žÊ÷¦z�)E¾êôF–)-FGá;Ñ"“H£ÐÌÕ$™ ‰Zz3 öcðSY· ±¹ë<Oç"¸¸¦=¾e¢Ê@¡ÝnsR3o”+ÏYXhg“$*3œœ!Ä1= —Ø*Tcê`là‘¢Ü ‘5P• ­,‚:ú¹”é0# ³ÓŽe;›éÀ¬)ë¦!çàãM5Í“zsôÁ±ÎÖ××ÿê¯þªÝnƒæÛÚ 4Nv"™Î5¡ö¤q×!Ò–¬NOðôZIy,’ç¤ã±\%Œ·èµ¢ÕÚ–ƒ=ŠÍÖÚfÓVs �æ+)ó;ëëëž¡â?–¨¬õÉ5///S”?™ô•0Ð' í8ƒÙÝÎ+AçPÓ¢(8LñýKö E"b‘ÕÕÕô6B£àÑý¦Ðt¨hvQ‘©´ Æð/h˜Cÿ«Zß¹ÚÏ~ö³÷ßÿÆÆF˜™n|æö···ð÷àØ|5Q³ÈnÀ|“2¶j5À•5ì) ¼V[(g²&ÝP¬ÊwàG<I+VžÅOæTÀ²ù¢Ð@ì›À—,AœrÐaSllìiâ8ß> úuA’¦ûmIWÑ,µd=žIÜh4–——q¦)Ï$Ñ/û1½ +<=€»Åi·XhR$H4j A©nr”½âøà`õ‡|^Ú0­ìwÔ/šën3OÁøÙílÿ‹4Ûû]öKØ|‚sv@šªºîœ|ˆEWžoÉdjÏË ˜--Lš\9¿¹â¼¶leIbK e0=yt>ÿСC(ÈZ’#ƒ©†übU—GcÏþrE’X“ÚyVý~?S3Üœƒ«I!H4­$œ†.=ŽŽTL"ØžÞYöUã,ràm¢+‚^_dv•õœ:ØŒ�Èxì—lRòBƒrÕ»«ÂVwj&޵K¥ÜùM¥€¿Êæšœ^4YªìŸi= 9ÌX«x‡–›5cÇŽÍÎÎ^¸p¡RTÍ[Š� £è»zÒA‘Ú5Eªç_€$&Œ®0AÄb$îóÛö¸B'ÿ-¸“îþVÓ�� �IDATr~õ¬o*/Ï%Þ�<|¦*˜5W¤p¤†#—O ¤’ÅwÍBou|-2á•å¶s¢•1–�Sç±0üÄœÂs Úö¸ú}Î5ZD6z(ûGÿÍÎÎ^sÍ5ívûÔ©S!ª˜�ITæÉ°} S““Ä*eUžOV „È&¿Ø­¼Z„&ãX3ä%”ÈÈO”Â&{|i»Ýîv»™ma'Lмap` h$à³É5 Ä02Wi^¢NªxõÖ˜—±4»Ï#-*ª­Ã›½é*ÂÑÔðæëâÈG|¦ì­­­e·gò+AòÖv»íe…ªÙÓÈ5Ç“§g‚¼QuUkWÄ 0>³°l4Ã4­Kð.s·Šl¡Áp²ÃíAfM ¼m›b‘ôQ¸Tq7×Üét<ÖšÃã/š%UcÙ„Q÷°Záà@t’“Ô-ì…¼!ñØ·–ªÉPžLúÀ”ŒV6%éÎ1 R‘+LxèÂùFä5^G ß¹LÅsçÎe%£ìIY–>Aµ–�âl…ªFá›o_XXˆ¾Ý¢`‚e`:Fó¹=Éóa™Á°ßÙÙIK&[ »}É(ˆ ½îÆñÿÉÒð¬r³Ê«£Ñhee…@Èp¿ !®pk�æ¹*öŽ¡o—°$[e¯³¢ÜoBµ­ÿ`è„ c™3_àçùŠdºæ.NN}†œƒ©r0at€’oÅÙÙÙ£GÞtÓMý~ÿ‹_ü"|GŽÙÙÙ¹té’û+N HígSiõÉ íŸˆx{s2ôv»îz®n J=â™jcƒù:4f*gɦoD×”£Ù|Yô‰e¬Ó®f¦‡¿¾¾Þï÷±R'~d÷bÃìŽs‹J«aÄ$Jh” Æ»óºÛí¶Ç¾QOi <ÌÜbãõ,Df‘™¼Çøf‹åjÎSvÐö€öÆáH/¦VVNØ~¿Ï©íQÍ~ËÖüû¦xPÄx³l‰—à<6œ†CXMå¨tZ”m5›ÇޱœIxÐ{ždvŸËܲߑ/ÚvŸÝQËØ²Ú’L€nób°æ«Pk€P7m_dn�ft“³€]=ƒ±»£“‚ÉBä¸ECê(ÇI+«fjÕjš†œƒéå0¼’Œ€á`821‹úÚk¯ýÖoýÖóçÏŸ>}:,ûÊÆ/›ESQL’1A�„Šxñõ–§›xæ‚OOûUW2OâEº=xH±9áF›À&· ‚kð±’Ï_]]5±‘ÍqÁ <>>B•¾QÀåw,8¯&I§3ï#5Î["\åÚ’ƒƒ}^A¯×ÛÞÞî÷û&§1”·VÍYÈÓÈ*ò8ðJ™kÓnø„ÎÖí/àÖz8ÍVMNá²Z‘9ípåÍ:)šfæyçž­î©t„®µÖ63ÜǺ…ÊÅ‘j¥ÌÌŒå¸æT=I¾ NB½JèWË.ûg~—±ë¸.[)hÙ?M˜W±<²#Ìø°£¶Mª½æ)\VÌ 0#ã�£Î4ä”RÊæ«_=¼õÖÞïýÞÖ˜2d¥NÖ}ô±·yòÉ'?õ©O™oVÆ£« N, ØôC[äKÍš@ÂB:džaŸNýiZ•`R9*2dŸ˜W•ÝH£ÑØØØ0 åÁˆöpZJ™Â§¡¨¬$éÓ8dAç‰óÙÛ€òPÀãQoý5%Æî,¤(ûG‰ä7s©0ׯ¿þú .œ9sÆG¿C¯Ûlú*ç›WÂP`ª VZD⓯Í";<:~;·%;A$ Þë8DA@YŸ¼Ê*ŽTóˆÁvIÝR"dá{Ù<K×¾`€­V+øRhÁ˜åT|! À¶foºäõAï>¥ËS«ìf%ÏÊãÚÚÚÊx”ª`Ñ@èìVà–=ik²‡,ŒÊ?—}îêæaÛI»kBþ4ääÏ_”ò®¿þë™Vkø]ßU~çwf&lˆHgRƒgôï… ˜¸Ç– £·È‹³2«Î<QX7>Á«¢„S²Óé¸ÃYöûôÅTd3k2œÎOœ€nH„|üüç?ÿYÏzÖg>ó™K—.qž¿£¯:«Õ„:(EÃo&í‡'ÇÍ™<êvq"Pž@TML§÷˜T¼S‹rîw:ápˆ‡<é°ÿ0 î»ï>:À¼J÷¨ÌL³C—Ä$h¿qîka˜~6êv˺ìWû:Ò@h³%ZûÉT"í±L—)òÄĤ]‹ø©žéë¢Â¦‹Éf¸,€ÍÍͰÈ|¼ÂXAØËÖÈ{ē֑Á.GDVNžIº¶D÷ŠYé‘YêU‰àPWÆÖ2 ‡Ú Ôü=ðg^S nûvó`9ñøÁ'É?®ŸÑÏ ’H•¾ü}þüÿÝ}àÿ-å®R~¡”ù_ÿõÝnwôæ7Û‚Âó6Ê~cÝápˆ®ÎÛ ÈuòP0é~r¸l�\“ªÙEÿs¶ÒN�ÍCaC>YŽÅmá½é•üMxI3Ñl_¼xñÌ™3L>æt3m„…ôD><u*Ó0c¶Ñ^£@áÝ00g:Üß<œ•••ðrœ¹uD öL”k®¹æo|ãk^óšôä¸`{n¦Ò¿Â¦Èšyî=êúaÜ‹ )R–\|> ¥$Øjü %¸ G “,HòÀf¸' ív;\5V{¥‰ÚJóÉUf‘‰ÕO`�Þ/®€@Žöþõ² ô_‹=l†å€D•é!U0_ª‰ (C­ú4nly¯—¶¡1áuáèyK¹ËÄ6ð.‘ƒ°N(‚Pi* ÓZdÕ]Õ°qI7!±9: 9?/åT)?QJæ ÎèC¥ÑØþ¨D6œÔ§fÐ#_àl‚cq8ûŸ€} B•zÃVoÆÐm 38Ô,ëQh§›ÍRöÛ[Á‡\kOÌlï3gÎÜÿýƒÁÀK†žÙIÉß+n±+‰Ê~Øå8¹(¤¸/(¤˜¡´0Ýl,NÚÛÛët:ßò-ßrÛm·}Û·}ÛUW]…n‰–€P�”•ýúX 7\y5†Çà çWnœIç D5O<3mhWѹqIl–.»ì2—˜äìp° §¯`U‡½®!¶À6àFº½e0¬®®âçof\csã–™ úîz¶:ÍÜ–Bä1AíÈÏðv²«›‡oº dYº•bò…—¨g™[ákJQE˜ ¤”’QfÑâXHŒ¯ö»Ÿ¸U4œerþ¾þº”ÿQÊ÷—²PÊÑ£GsÐô>ñ‰Æîîè{¾§²WÊ©ÔívßÝêÅК2gŠ8¹Ùâl½”2Ûh´Ji•2··—ÿ[h4ZÆ|)ó{{MÁ,V>‡SŒß”ÿ*ýš _6R'ÓÛâׂ³ŽGbóÜUºÓ›Íf»ÝöXU‹lé–ÿŒÎŽ!wû³÷�[LVö4-PJžÏÌÌÌêêêÒÒÒã?¾ººZÆŒhP -°jp#É%‹Ä¡.[s@ç`KÁ§;»ïpbÚ;Õ†o¤Þ&eÂ\€-YÆ6t Š]‹ÄÿæCºÄqœã¹@©T§\¶ëÏÙYZ¥P ©_I> ö¸Ø‚k "D"t _^‡+ºKʆÅ•"•¢™ ¹p%’¬d}: "H#æ…À]‘×ð"x ãÉ]pƒ®ê\u‘ ÃQ²ä|J’>˜Ÿo.åT)ÿ¹”ï-eeeåܹs£Ñhë5¯Ù}ö³Ûï}ïîØŠEsõK_ºÐë=|×]«««8¡ÑE¨!ì(Ó@ G¸ÇNw‘®ànn~ûÖÖR£qtoïÆRÊV)Ÿk6K)/ØÝý½Þò¨aZ0ŸŸ ³Ö›*Ǩ¹¤Y¸iX Ë©MØ€/Ú`31›’%B“ü’Šf»ž¢'œG hàí”ÞrÚ¿üN0¢$æü¹:=#2ÌtÕÑhôgögŸùÌg.^¼øä“OÒU2:ÓähÀäúsD'*ˆÊÕv«ÀñðžY9t\0> _Övù»“ëÑK¨Jᜰ¹ž˜e§cÈÓ0ø^¿ß÷`JNd¤5hGs:ûÄÏô6G^5 ——ñÝå´H íV«ÛíæJDÛDŠ j** h8PÕ³xŠÜ¸>[XÏ@‚M€ŸÂ¤Ÿ{]f~2h'¹ÔgàPcÈ (g«‰Z(¸sa½^oss3T dLFkÀýB¹œ†œøùRþïR~£”“››kkk»ozÓî7|Ãüwìs–§ç³?~굯mÎÏÏž:5³¾í=[Ñ“Œ ¼Ú¦ÉD8Ô 6ð¨0ëw·Z'J¹loïY9ïvwm4în6ß½µ5777?Fù“L­¬¬NÁ…-ÇAo‡4 H h©C -°c˜u6GÁ:µ™u£Ñèðhôæäõx°‘Šÿ½7·ô¬Ê¼Ÿ=½Ï>çTU*$$!!I%’A›«‘´€jdhEü”¦5LJ°AhQ»™DD?$‘A¼hˆ4ä£ C4 B”0ÅRÈTIŠT…Jª*uêŒ{8{x¿?Vö/¿óìèÕßÕ˜ÃE¿ï¹*Ugx÷û>ϳֺ׽î{4}¥^ÿ¶N´M=…&â†p¥  ªÐOŠ�§ªÛW1îpäÈ‘åååpo£Çkp<k¨d²ÿf$FrŠÚžóÐlBËÓ”Ä^™ë$Sé|.Ó¥·z¦Î@øä05€8‚Oí¶™•’,6~µM\’<^³`Àùî¦:)_mÅsÏ=÷q{Ü]wÝõå/i2#Ûf Z4/s·ÊªZ­Ön·O8á„}ûöE‹‹ïå㛸Éí$‰Ogt c‹fe<¿/Ú¦tú¢p•_Ó{äš QÊ—!g ®ßLé#)½«(Ï~vñˆG̼óî‡Ó¢ïÿîïÎ|úÓÝnçå/ŸùOÿ©2¡—UŒÞ4\ÔØÒn·E2ˆ&D&ÿacãÍÇÿé“Nêõzkþþòò\äÝ* kd Ú̘–_™žß±„íšuSiB ReeI»º‘tgʉˆ±©Ža4º´ÕÅ{ûýê`RúÓvû®jõ‰£ÑzQ|k2÷Î?ø•Y ö°ÁG€ƒ›1ÃŒ^7Z™Q|d¾Ë–@ö ÏM¸�pŠ`sÚIL‰CÇdŠx¶T~èv[e3ka×ÐöY‰_mΞ¥K©‡(µé68%2e.Ë Ãá0:û–fª9`SJ³³³6ª¡…1‘¤èÌhWô`N9å”óÎ;¯Ñh\{íµ!ìfàŽÎÑïi³<诰5úýþÁƒ#ê{ìš\æsU }MpõL÷/£¢¸às å0C· y\ˆR'Inll¬¬¬� }äáƒF/­ 9[v=/¥¥'?ùêë®k}ðƒ*Ùš)5½?û³Ö{ß[»õÖz¥R[\ì½ÿý­ /N°àL8› s=dô 1à,²Ôùùù™Ñèâµµßܹ³õ„'ü‡Ÿû¹~¿ÿ‘|ä­ßþöou:O‡ƒÁpR…t:N§Ã¹{)@3â,o4DŽ1AË&+è$Ýž½ 7OO¬Õj¡9Oº €<þÞ~ÿ¤áðç‡Ã'oß^­×‹¢øÝµµ³Šâ‹“Øà‰%Œ G‚Å�ƒ`eÄBšÑ ”àq¦+29Ë$F(y!Ä€ªPšH ¡lŸ¹“ÚÓµ²›–OpÛ ]È…¹adø¼±ã]˜õ/4îŠÁA…ü=‚('T$UQÛ/•ˆ3ÑOúÓ¯¼òÊÅÅEs² QTÆYwè$­éÅ|;iÇ`0¸þúë8pôèQ>ƒeaj`^ &+<@éŠã–·½l¼ æ´@½H+í‹é€wåo”ei³£+¹Bš%9–Ò®s'¾¶O2„¬VÒ¶æj¤têW¾2óŽwT;$•‹J¥’Ž;®ÿº×µ>ðÖwÞ_ìßßzË[zo~sk×®Ì*4mv÷2‹¿R©´Ûm¦¢¾‰ÍÖ“±×ÖÖ666N.Šá‰'>ó™Ï|žðÄ'>ñŒ3ÎÌÎÖ«Õ¹”ÆE­T÷Š¡ÂmóÈjp7W¦EpãËbû‹IW=^N:‡u<¥°öŠ#Œ„7hå1ÌT®j¥rÜx¼P/›Ÿ?râ‰ã³Ï¾ïøã_´°0,Š3Æã4ù\_æ`B|AÔ(n•“3Òbj*°D¢‹Y´‚<ýÃßsdæAÂÌ@0RâöÀŒ¶O5­#‚M–˜¶µ…ý“Ô£‡‘&ƒúƒù‘ø‚˜­É,a<¤lö6p“õx QÀת×ë'tÒ£õ¨]»v}ˆ¬C’ZsD8 ’Æ?Û0z30DHq‰ø·ÿþk¯½vïÞ½Vò* Ktvv–!͸¯œsŽ¥f]#BëBÈ  e¢,ø~öÒM‘&B™¢9ìyrÞ‹ŸXü¯ù“d`NⳄ›Ù±+‹¢èv»ÓDÁ²Êy¨/S¿à}¥”ŠSN©öûÕÅEÔ,Æãq±¾^]\L§Ÿ^?|+˘SÐT B³&æã¿¨`ÆÊÊÊîÝ»ÛíöÊÊÊÞ½{£m"P’?.ñ1(ºººÊBŠž¤G 8LÑg³2T'nlüú7“Ѱ¦+}šþóŒ»%#::£ñøi£ÑÛíC{سžþôÇ<æ1{÷îýÌg>óÞ[oýÂêê«ffÆ"FüÊJNmî6úFhÞÏqÇÅ„"ŸõÐ`ؘ´ÀBAnó],'»/µ!jâi$@Z¬ÕhåCÈÎíê! ˆ ~ù—‡?üÃÍíÛg®¾Ú'ƒ*ñhæµZ­8—3J:mêLÁá–[nù¯ÿõ¿®¬¬@#hÅÉ~ȾÑвl3 (­Mëæy¤”zAºM Çì|F²é+•Jÿ‚ ÒqÇ—_^»þúF£qòÉ'/...--±h9ô}âgBøŒ hŸÖI¦ákÄØó×–™%š6OC“#N«2RÛ]�ä&í”ÀÚ‡/kÚnÅu×U†Ãî+^1ûÆ7{½û¹­¿ÿûõË.K×]7˜pE,ÞîÁ1ṼÎj¡6íÚˆHðçõú¯>|ñç>wã7v:}ûö=ºßT«7ÕjÕJ%ÉÙ0V'ÍòD‡@ˆRKŒ¤>6< 0RJi×ÆÆ“Æãÿ^¯ÏÇï˜L¤ÿÇ™™•jõ9£Ñžjuÿä»&3ã6ã\F£JÍfóôÓOÎsžsÖYgíß¿ÿî»ï>tà@Z]¥bãøsÁ€Cÿ&óÖEwÀédB�®l´HÐØ›¨ÄóLxϸˆ´‚½{ãð Xî"a6[X0Ó‡øs£ÑîÞ4œqÁ©Õš}÷»7.¸ j_ù öK”DÖ¤`tÆ=€ø½˜ƒÙ FË•••›nºÉõ4¥v|ËÜÜ\ Qtý¦l‰d£w|kÜ…šu0Ë}”gB5 Ç€wyáEÑ}Õ«ª·ÝÖ¼òÊÞ ^:ùŽ9æ˜~¿¿¶¶fü3³1$ B© t è7í Ê<œ).^Q7OÍv i ˜ea*ðd(ˆµÛm–Ar¶ò2÷f“-Ç 7Ôí¾÷½s¯xÅh8ì½ë]µ·¾µºwïhrdÓÜ£Gsgö_JQÛi!g–àCÉWW«oé÷k¼ue¥(Їw:ïߨ¸¤V;P©ROD-ÍkеÕétXëî0ÑáÌt* 9úÓæÙFVçM•Ê¿Ï3;·ýÎÁàŽ¢øÖDÈ™¬ÜÓy"GVÞ¨VëëýnweiéàÁƒÇüÁƒ>\ ú›}¬Áµ² Jû—# 6½d@ùK„ô©ð°“ qå"Ib.ƒÂéߤÍó§üKIü]2ÓOÄðQ—`L8 ørdü‰I2fZ­þ³ŸšÍú‡?œúý™| û;¿SÜ{oíŽ; ³ÙÂ.˜ZQâdʱq(nÉÒà˜#X÷“Á'Z]]õÌdŠàUó]Eñf3Âí['Xd6yÃá°¨Õz/yºé¦…«® Õ÷¼§÷'RÃn¹å–ضžg2s„Â"êé™™&{¨®ˆ4F#hÜöÚyϱ֊Ýn—Ʊò¡Å¼Ó”µ £~uPp[q÷R0À²ÊÙâ a’Ley4 î¸cæoì¾éM©Û{ßûwÞYLæc.Á‹èAy*3,Ü9IÍØö~Cî‡Sú½ùùÇ ‡{I)®T~­Ù¬T*¿<ÉÂì0hñ¾�ÐN¦ó ›€UëîÐ “ó.>æÌÌÌÉÝîZJ4›ý;ÆúúúK†Ã×®¯Ÿ2}}ccc³›ˆGX8ƒ˜š®V«£áðcÆé?³gÏyÿûO>å”ýû÷·oºéŽ}ÝÜÜX¹!G',::‘rÙ±ÙÜsæÙFŸÃ?mVa€)]hN[ÎJ<M.÷œGv:–"çï2€Î9ŸÑ~W¢Ä]X étŸõ¬áñÇÏþÅ_443Ó_Zj¼öµï~w÷ƒlM*’L�[ôJ¥òÈJå´Ñh<UÆãƤ£¡u8ïž™L Kv³ÃèÅžÊ]Q']g"iVó³Òùtz„ýO„Ïè[ 7دTÆ/|aõž{ZŸûÜI§œ2 î¹çžâ%/YûÀú_\½õV øµÓÍ2L,� êT¶ÒÂÂÂgœ±ººzçw2î aš„É鈑, ¹z+ÅwÁ‡áÔ??"¢µx†v,,µï‹x“™s5›Íâ»ß­þõ_³³Å7R» @à}k-N*ñé å¹£ãšRÚ=3sþpøÓNQï¬×kÕê¸(ž1W*•«kµž&Û{òÛ!3:y ¾Æ lèëÑ6Û¨€ÿþ»Áàív儞yþùÛ·o¿é¦›¾õ­o]5þ?kkŸj6Ý…ö€Žå�ì6.ŠqQ\U­þx§ó䯽uã»z½v·{Y£‘Š¢&Ÿmð‰“tg ®eµÐ$11š1œò|qÐPÃØÍÌW#±(ç')£x*cÚ FØ\ `<3ÉŸ”^'8 eÍÌÌôÎ=·zõÕ,Èûg~¿úÕâǼróÍiîß²~ãñø9ƒÁã‡ÃÛkµÓÇãg­­¥”º•ÊffRJÏ ~vfæ  EzéYÅì•ãÖþ¹Qú[×9I3c¾ÐÓ‚gìš´äÍÐñÆÆÆxÇŽÑqÇÍìÞm|4�‡7ÞX<úÑÕ={ÀâÀ«ù,Ö†·BUÖ°‰_7÷ïßßív‘ç—+½(bL&zíž H²Û3ˆäÆ2 d7áØþ&ïYù© 9[ÙËñÚòXYvó[ß*Šb¨î¢Û×ÓΑ¤4›Mbà#e#F–½÷ùJåK³³nDƒyòΰµ·ÊÁ‡Å”6ë>Yû9mV*4jÊ!q“ÇsÌùçŸæ™g~ó›ß<pà@uyÙI.­,‹ï‚¹e‘øI£Q«(ª•Ê/®¬TVVRJŸ¯VWR:}<þH»íÁ:¢ «(þÑæ•<CûßXö UèX.|èØã€þ~EtÈq…€CÏQK Ê•ïÖñÞ0FÃ\›úÞ*•JëÝïÞ¸à‚a¥RýÊW¢É4|Ñ‹Š¢h¼ï}Ãj5Î}FPÉrœüu£ñã£ÑÑÙÙ?:ãŒõõõÎââOu»ŸªÕΨVGãñH~”þ,»ùoÜ!gy»V£Ýâà5œâÆždožØwÀã!»{:+‹‹õK.¾øÅûö쉻êÿþï×o¸aæÊ+Ç�` Žž%ŒÙ†ŽÅ(ÖÒÒ’ç±2}U+™Ò†!–ÄxíñX¡±6m Dz/„ÿƒâ¤ÍeÈÙšFŽawȯ±P⤎Ý«? c`@¦Í®ãœAäÈTÀ€²U(éÄ'f#`�ã0'áIgÙxV%„E<„]ø?œ˜îà…Jç¿Z­öSªÇ+KK·ÜrËüüü½÷ÞÛ]_Oý˜J›AR üCu‚FjQwÖëÏ™›‹ ðfl Zœd÷$z¼Fm7goèv™k® vë‰ö{0’ÔJrªÏ&ûâ¿` ÃÞ¶|dX,›¢M‡€5†2­&£À‰F´˜øa®–±Ðz½^_[àýÿø«kkéÚk7~ù—ëõzíÒK«›Û{§Ÿ~zQûöí³›Y½^¯Å|JçÕjïù±{äãøî»o¼þúá-·œ3Ä£jò†&"ƒöŽó3O› =+m©Z}‡ŽrKØÞ1ŒÅL[üÁ0ìyZè)¥Ú}÷ÞÿþîýÑèo¬,.ö_ùÊÖM75®ºj4é!Ù–-Ò…L6‚‡or ó3#pÔ¨e£çgxx%˜žÀY°–¹»w±ží°Ÿ”UI•»Ñ–Èüʳu×ñÇWwíªÜu—­ Q1 è–%’Y.1Í\4?ÇP›IMÖ:Œ/cþŸSÛÒ¹`»Æël—IŠgg'²<¡“Pp¤ˆ¬LPc]ó€ @¥òžfóƒñ=÷|ô£ýô§?½´´ôGŽüÊhô®V+IÉ-ÎÁÀ.¨ðî§ ˆî9Liÿ¤Û9 ù€‰|g£ÕÇ=.²E×g)¥ð¥÷h*a/{àdˆH.R¡¢š÷u@Le üÁµ©Ë¿ PÊlà?ÉuÔ™5ÿµòk»eò[. ƒêpØ|ÂTÅe�� �IDATÓ›zo{c×®ÊÎÍ÷¿ß#À±2Š¢˜›› 9µ¸Úívm}ý/VV.|ÚÓž}á…}ìc—––.»ì²­®¾äÀ§­¯W*•ê%Ö¢í†ÂÚ¬âšÍ~º]a¿"3¤ù1x‹:€iHºfõkŠÞ†'µSJ•#Gf~ã7úù—é›ßœÙ¿¿rùåã ù%¢þÜÜÜ#ñˆ¥¥¥ÅÅE£do.=iƒ±,øFbk ÒÖ´YJÇ÷›4ìS“½Ün·ÓÄÛДtIPÑŒî¢-dí²¨2äl͵’ÒØÃÏ~íÒKkûö±9YV56hcQ5&·9Vè6›É–°©-–ÈÔ<½a?ªi›âP1Yƨù¾ £6‘Œÿ2ÍvŠü(m!¼¼Ñxô`°ë»ß¯œ>U«íšìÆ`ëzŪÔvœª¢fòð¹ìoJwÜ$·ÊiÅn44á¶Õ'QÐy+ø›ƒ–—qH»ÑÄ7Ú÷SØP rë¶ùÇ:WH›¥c!!ipƧáÌ«_ÝéKçþò/«“Š–:¬(Š;î¸Ã–€´ôÇã”ÒÙçœó˜Ç<fçγ³³~ô£ÿþïÿ~öèÑ´¾Þh4f6c2¾aˆ^?ÆÒ…b¼Ô8!ÝñÒáÙ RcÅIÚü9tGôñx<;;›&š:FÃZoxÃøg~¦uÅC)�‘$ñí‘Ì™Ól:\¦h�a:™3ô÷81Hû²£!;æÆ8"Ððt98^¡ ЏBjÖ€pYålåõú”N¼ùæÊ'?Ù{ùË·¿õ­ƒ£GiƲ3¬Ø$ö!·r†kÔãf1Ù¤J›‡ 36]¬l:À&ª>ð^'þÙ´7ÜøqÚÙ†;·Q±=L+•ʳƒ]•ÊLQ<³Û¿ÿl­vÆx|Îx¼{v– JZêý`\P ŸæætZ™ß`:ÊcÄQ£ØT!á¨fã ´„ü{n ’0Ö ;ÌZb9ð=²þø–¸^ AÎn+6]öd÷*@mÀ2 Tñ½íK.©ŠOeü`9g#À½½{÷~ç;ß©×ë‡Þ½{÷½÷ÞÛívã­…J¹¥c³^¾“`ÑF²¼,1c²Ñ󧟇¨«W¤Fž}Ñг�U¥R)ò×=žÀ¢‡2Ⱦ}ûm¶}œ§Ê�Ó8 „ZÈ-ðY¥k;y6…õoP‡² !ÜÁƒ²�Øc²�•ô´[RrŠ«“ÒkRzyJwÅ»n¼q梋Vßþöö«^UY[£óÇV ±’P =ždg™4™ìt8w–——§ÅEbŸ[ÜÓVÆùáìTqmPÎÇ¥;ئ§ f®Ó ìÔëõ¿Ÿ;7_ð{‚‰Í¿83S™`Í>}2gÜ$ÝIs[cè=à ¾¤S•dîâÏåD2ãAÄÀßÓrˆ7Ûjµ"8Å Ä[¶Ô&ŒsN¨ áeM;þNÏŽðB!v§Í>èάãï3¥5?[‰P:G¸OrZ¦9=¯Ýþå/}éC³³'uÖ¾}û®ÿæ7wèаßÿbµ:’Àk °üxqÊ;½�þJReÆB”‰£BÚìn\ˆÜ/�7ÉÁby öA’‘5Bˆ^˜þ¡a#�Ò€�Ç26Ÿ”“Wßè¼ÊbÛ†ø2'¹D÷Œì3É ŒÑ:ª¬ Î1Ÿ%}` ®Ã)ýEJ¤ô#)Ý3;{ÜqÇ­//_ûÚõ×¾vö}ï«ÜumŒûÕÕ&”$8òÑ挈õM;ÁбÃ×ÖÖøšl#±]ƒA�–B5J~Ëݳ¶b×9³c Z2Ù²²¦ £ôÇ/Š‘”H´i¤”z•Ê1£>É›ê•JµV+‚†«�Cúl¦)ç2r�ö iµZÜ' •„.#œ•(^ÃMHS®¬qüÑÜŽ}K&È逶MüüÙÙÙf³*Aߌ·`M¹ø‚ Øå…ê$Ž×èó>aIY¢†£^!ÿ�…aþXŸ–‰ó€Q’Â&ëíQžÑ‚CªV¯¨Töu»çÿÍßüÃ7¿™ÖÖþÕÊʯv»—Õjÿº(ê“|"c-ØTKÊÏ€ª/FÄ�?­yÉœù/FcÇŽÕjuyyÙ³¨†»)"IžŒTec°(iÆ 3ïÏÁ.· óš8J|2îa€ø­V+–*f: lO Æ ’l‡*XitMÓ ª6œà^©±öP_GRª¤tlJ)¥;wîÚµëÆo,ºÝê‘#é”SPœZÉÊù¬ÑvkÁ:õ\;<£áš¢J~DäH›M°{!a„óC³„Š›���EâxrvŸhÇŽ?ôC?ôÝï~÷Þ{ïµ¥<÷ig«P&®ØÀÍdßLÞõMF­¶Á|?×1䉖PƒzËÐ"ò‘œÌÄ= KI%&˜î°ŠC»Ùk.}¨'Ü«ðÏ´¿€%¼ˆÙ”q0ë É¶ðyyÚñ:Â{ juðZ­V¯Õ~vcã¦jõŒ^ïÝ·Ý–RZOé¢Fã¤ñøŒøi2ýã8Ü:H›ml¾»mîx×€E쉔Fcqqѧ¹‡ÌÜQ›6’a.*KyqÞh™¸gšÒ`åiÇmÀ)uËÄhvÒ\°ëuÛ—„¤µI¥Îóû¼µ=q|c 2ðý¬¹µU¨ÚÿÑ!ç씞›Ò;SzKJ+++û÷ï ½7¼¡ñѦݻǓ.©¢¸b©EyAmë‚,ÏD‡ÌL³Ùlf~—™`—G1˜weMß…¬p#I2‹ýW§ÓÉ43bŠUnQF"2ù¯LË3¥ r&ÄëøHržNaïÈÇYÖZO²‘7@‡h†Edî&€<³³³ív»ÓéÀâä#iþ”‡�u;ã#¹Ó€¦/‘Z„å H`M™æ“UM©x¢2æ©2ðËkŠã&~TØ»ª¶›\ÝOU*{ffRQì©×?ßnßìÇãÑhôÇ­ÖÑJ¥2y_qVk?áI&ß‹ñÓ ø õ Xün¥±À‰”Æšà“¤Ï�ºcpoÌ%ËÉhro™À€¤H&¼Å2 ÚNÔQÂ:…²hE”ŒjÖÉ2® ä²i³vpü²¤ÖˆK†Ü–!ç¡»ÎIé)½,¥Ÿ[__ì÷{þç3ï~wuÏx2ð1b‚ I‰®•ÌM…¡§¤V¹}ìé ÇIaÌŒ2Ä&‘·x"ûÁ–ÕX�¦ã·,...//ÇãùùùP;Ïzæ OJÆ~ÀÙ+L€›ùhvÚk6 Í1ãX\XXX__g[2Ì,Àbá/`‡�¸ø²€P¸íz¥²³("58¡ÕÚ6?_¹ï¾Je8EÑ«V{š6û9â7>’ `7›A€éâ•NVÖ®˜©Ñ:£xEY6ä ©Þò P+¹ãÝQ«ÝU¯ß?SU­VI«V‹ÀrEH¡,³9~¾ ɇԲ1Q¯G™%HxؘÁÀ3"ë g¦<5ëš§k©Üvu•Z;Ûí¶7“üÛ¢¦¤ËÛh4ºÝ.$@Øä¼÷ÌJþt&}Æ®1›(lX¬PT\ºQý³ʳe×q)ýyJÏ:þøî+_ÙúЇê{÷¦‰RxˆcŒÓ7^îìÿ8nÂ0Ê!„‡µk&B†z;éËl‰“Ô>2ø}·©}0çL˜äæ¼’R¸> 9:Uâ36ˆê7ÉÇ‚¾odX°$ ifÙ«Giƒ%)ôù²^.œþ­C¯Í¡ã[άÕ.»÷Þ›gfªµÚßxc­(RJßh6—*•†ÃKÛíÍͱ{É "?ç`B‡¹[Ñz‰E>‰µ(ÌWR`žg,›,-5¯{nnŽÊ†ÎÃ<LÖvˆÎ<H)ÉÛdäÅÚÕ·ØëÓµ5–!/Ój¥IŽ&œ4·x³¬Lž°ó*"™Gâb-Ñð·–à4A.ªüÆŠ‡0�cOöjÃsÖ.ˆ°Š<ã…{š(À’P¢{4­~’™9™^”Í!A®3·žö§å©æË³eQçµÇóü/~±~à œÙaOŽ ÎJȲ9÷ó cªI–דå>Nb¡û€3¾ä®€Uâ!û3'DI‘4—:-‡3ÍmŒˆ°ÐKgYÉÂÃô¨ y¥[ПH!AüÜ#Å1(6j”žÔg7a妽÷^ßxü?[­OlÛöo†ÃO}êŽ;nºé¦[ï¸ãîÁ WÍ Ú’ˆÖèåy’­[EÂÍ[ž¡+f«ÝpprâÓ!·Ì š™™9þøã»Ýî‘#Gx/æ ¾€QX<ºÌƒ’â4‘¦†jÏ$¿™Y·ß+®¿çfÜupø§óoªá&gÞÍ#ýž™³a­V F™מFÞw”°–YɶD"´ÄLIR[G—/bL&“á2‹Rà K–.»â£K¼ ?U›Æzø n #ˆB[xÞ–!'¥”*7ß\¹úêb_І‰3.¼¼c ™HÓ8~·Û¥uÏÐ5Ç¥Ù¬Ea¡7H’A68ym'EZ©ÄÕb铯™îbI1€o¢…!ìx>ñCºÃù �€Œ>ëÍCÄ <Ú�}&ŒíF¬91Ù]VåŠÍF"ϘwÀ⃕•z½þ3?üä'_÷ºá±ÇøÒ—V/»ìW¯ºêíveÒ;AZÜòinÛP™Æ¾éé±T,Ò¿bÇŽ'œpÂÒÒÒÁƒ‰¦f10 )¿¹!´ßâc¶Z­¬ƒ•¥ Àž¬yA¼´YψM¦ˆ°æC?óab�T6Ó¥ö�?>³Ô1�Œúý*§€˜$Ù °É½×1Å=˜×ŽšoÆÿ<RêoîÖ$éŒ/“Ùh±HàyÚR!+©!•0µ“(çÊ«4¢N”5‘ Æ[ ×äÌx-É&ÀÊØ¦·aÃI ÁŸì˜]ç±y‚wA¬´n1c F£Ýnɘ"~M ÎåÈ›lå%‹Ú \¬ÌºÑö©<7Ã&ib¬K†Ål©eøDöd3XúÚL$Ž9„u E¨øº)7öŒ×o<~r«Õ:eåGžò”Ù׿þŒG=ê„NxêSŸúÈç?ÿ¿=þñoZY™™07›M ¯ªÕj±m[÷’KÆ;wFòËÁÄùÅH#C?eÙŽOÑh4¶oßþ?ñ/{ÙË~ôGÔnª:FËæE¿ß{¤XEóóó§žzjäñÁWWW———{½ynäαŠâýÒ‡€ÅÐëõ,ÝÍO£3„ͳ5HP sß%b[ü" 3ä÷§'ÆáÜ) lûäFïv»LwÁ| ·Óp’f[Q±¹ˆ·\f<Û0¦Cï9Êœ¡™â‡;^™°™ŽÇ2Þ°j†Q%EøPQ2%ëf1‰Q¯×+33\0ø¥_Ú˜­K#ê­¿"ìGÂnÇV»ÊÇjà(Œ’GqJb¢ÕétÒD?ÃM´ q6k“ý W'_'Ñ ¦9'Û¬ÛíÆÎ Û8~;?™LœNUl­p—ЧGnÄRe.‡î*¹) ÄÊçWħØŒ#˜ÝÔn·3ÒpF'ß÷Vg6Þ²Hèý _ßh4Ž=öØsÚíæÞ½:ûìêYgÅo?æ˜c~ê§~êÄ#G¶å+;î¸Gnß~øðáøöð–|rï×ý˜w¼céÍo®¼ï}µ={�ë-HŒ'[UH¨äæª ƒ½{÷þÝßýÝž={Hx9Ù‰šH Ù3ï¸ãp­l(Êò€öOâ¥3SL�³²HÖ½g§t»]HY€i³“áVØ€.¦ºø †‘Ìrſ΄ÍN&ãqzǹìßóL´F(+íÅihŽÎŠïœ)«øº)îÞ¹jÌd~˜!%GŒ?Ê4%{a�F#ªÕjÕëõQQlüûŸŠbüð‡¿ôKµË/G¬¯ 9[¬)ïÎêŒì ç,³Ns’ö-$WK|:`X§/ãù€æ/§¥<™Áf/Ef퉓LöÃq”dÜê¢,bøë“FÜ=gÐíváP1TA?vûÎ;×ÖÖB‡›Þ¯GùÀ‘ø-™øbÎ,è|£Ç}2Á͸+Fâ¸3Ç:H>Ýn·Öëmß¾=þµ×ë9r$¥ÔïõÖ'ŒŒûÀI'užûÜùË/ßvð`ÿOÿ´÷‚T>÷¹Êõ×{.(ϯ&I—Á«ñÆ»Ýîí·ß~àÀ†Ù½nN@f3—:M&‹¡ùš”e¢¹õg=b?¾ `y§˜Ô`E5òz8ív{4Åð¬é0œ•* Û`jŠŽNœÂÖ.2eËC‘<´ÌÝluA­çæ¸g=)TÆ+#Ì£¢E…ÂÑ^Ód²>OS†fš„¨»Âu´pCD5ê쿸èv—^šRÚxéKןûÜúG>böD ¬mMÈámÑb5 ªœHN 63U¼±8[k“¢ZwnåCœf3Øæ¿9BLz˜x"6”¥ ãæHrPŽs|Z Ø lVkffÍT=Nƒò­Vë´ÓN›››CtÄ%`lQ'Âñs²4ß'¦™xÆIüIãÔ‡±{9š{“kii)Zîû÷ï¿qçοüå•k®éõzƒÁ`yyùÚk¯=ö#ùÐŽËËËGít:+++Ng8}Ík殼ò_ Ox¶­¬T>ô¡Îsž38é$€²ø¥Î3Ì2hÅ ^G�bëëëvrôD…=ÄÜiw …ªÄj4Š•4_ìœ=pÇË<dŠK—°ÍÆG8ô§Ã|L³Úà|R÷PŸ™F}Ôæ#ÓÓ-–õ ä™jš8naº(5â¿~°-JrÌ¢Þ üÃóFÞ‰ìGà¸éÔÓëÜzÛ¶ a"ÖR­Vë_xápqqþão6›Ífsæ’KÆÕêÆ¯þêörÊ*'yEÚ2ÀºñPMH"<¢„I�s–ÉI7\kL™ÀfÙ Dì™8ÑÊs¥ û™é“à:“ëYP™Kt_Lz†&ËYÏîâ!PþÓ'à¨Ûíº¢‡·ß~ûÊÊ ß`KxÏp*[¨V«kkkG„ŸF{Ìf-ÙABÂωŒ5t}"À¬‡RÚ{×]ç¾øÅ÷|ä#µvûk_ûÚ™ü`ÿž{n˜mMðœøö•÷¼§õŽwÔ¿ûÝ3ögÏ>ûìÝ»w/íß?é¥Ëo}kë…/Œmßëõ¢»Câ3 sLª ›ìQ»iÌŸéy¼×IŒ¹Ôjµ��ùÔnHD˜ÆuÇÛ":DcMi"cìs“ûOMAi"Éh4Z]]õ‹€‚ëÊjxv_6Q͈•g“&ãïY«žO2–K3ËÛLDf2"ƒçìï‰/N|äÈo\ÌY°ƒM { ð3J@]LÞ8E‹ˆŒA B'Ãð±–RósŸÛ¹sçI'´¶¶vÇwŸüäð7³ÿ“?Yk[y9O™–×´– ]´P•pgYß–Ÿ!¼´b·1ÇN¶d$ÛWVñ²ˆox™˜ÉM÷Æú¡|£uKÓd"5“61M.òô¹¹¹õõu£í£Ñ¨Óé„Ê( ÿ8J<ü!ÑCëhyæÔ „h†9H®ãiÇ—EƒŠüñØn÷Šv{ÿ1ÇüÁ3Ÿ93ŸžÒ;þð›¶m{üúúí:5Š¢ØñÊW½è¢Ú‡>ô¥/}ék_ûÚ¡C‡Æ§žºúë¿>÷†7˜Êôa67ÀH–‡vý^È^=c•Ãâßf.ñÅœe|êø°q‡ñ"ât£³e‹M”yì™æSÖztëÅA+ÉÄlÂ’Gýy³ž^d/°ÔA åç4³ŽŸéÍÏÁB-ë¯ÐD±…³©vEsÉžÍ*±ìyŒþDL7!›A‚; ¨%,¯J:^•|xá…ųŸ½úéOß{cÁ ÚhŒŸ÷¼tð`íª«J’ôkìac>ÓmÉ,$0 YUpT¢I`˜sO#KFÏ2Ú‹aÏÜ0¯ÊNrUñYœ¤6i››cÆn'³'»Ÿ‹¦èÚÚ»0ÈŽÄÖÇ[_`‘ܱŸÂ©Ò‚³DWÜÑÆ*ýa»°9ñ¨Õj‹£Ñ—›ÍÓÖÖjÝîegž933sï½÷öÖרZ=”Ò7 æÉã·/¼ím½_ûµC÷wi÷îá‰'~åWš—]VÙ¿ßñÌ—ÏÕ@š21sY9gggãpiµZA "G¶·„« G¹—·µÌë3£×&³¼M´p"0¶ÉNòµœz%—7δeñ/�’å=ª’u’Xf]òöq°†E‚Ê4Û-ü“¤“ä#Sl(éi¢I›¹n³Ò ,‘eχµ.I’ Cf©n¨Ð"uA²õb»¿"ßû/|áÊ¿ûw£~t4u^ò’ñâbëc—k[r2CûÜx\~al0;h—‘ÅÀ3ÆšI–‚`SÙ´ÍŸ›Ã™Üò¾mr.Ql�S(³¦rgÒ;ãädº¶³¶[<„ÀÜI6Y÷VŒ÷Íg#iVÿt0Ðäød¹¿8èFá3·vfŒq´Z­•zý] lœpÜqív{ÿp¸¾¾Ž"g£^g·(Š™ûîKýèúK^Ò<z´÷êWϾç=•›o…ó�Ç2­xËAÚvóš¸ec¬”ÊP0³V¦ªgÿKƒ=mJw²ŸlÆ På5¥‰h)j.|%í%÷ÛxM±<(¶"ÌX =ÉJԄ躈±xhVÙ£Ùìf <uBŸ×þøI¶Ð` ÎÎÎR«™Ëcï kEÓFõ3ñ˜Äý–q­V<k`£«fŠ“å­�IëÈ’€£ÑhæÃ<ÿùkÏ~1?_Ù¿¿ñ‰O4Z­-œ-CΦ¸2S»Ý˜­=¶¯TèNZQã`Æ"#œ„3˜Û6DÃúÙщ]_OÙJ¨9A¾„ü+'daGï‡I…¹¹9:ñ-‘Vg-ú@#1„ÈÇo r6¼5ŸVy†‰B\'%lÿE9’ sóÅ&fÆÌY%š)ô„ nÇñ5KKKN‡¤ÎôÁ`öøâÕ‹/n¾úÕµõõñæÎGæ×€&#»)` ÁwÛ‰nsÁ$ø~\u¹ºrêõz­V+[À[$ I*^¤DL˜bùj×€˜²–9§³­êÒD+Öj/rÞ`š(&y/³¦l †ÿã•mll„ÌOˆÓ„Ø](O'IEPÖ“ PTÑšµòÙO(ÄÀ@ôÆœßdíýL J…5]à2ˆÝï÷×××ÓDWñ:¸àYÍDÅiκñ‹ØVSš¹ì²Á¯üJýž{f>ûÙa­ö â¡eÈy¨¹÷ç>Û·o\pÁ`a¡ù¡U—–HÙ² �68²ÓX4@múG'µŽ'Õ»\0¥Íù=ž�ˆšÍæÑ£GÁÜ؈LЦ=vsf쀳Û8æÓ…°d§N+ŒÑD¡çäŽÞFdD¸8Ô ,eõ ;¸y€$|4ÎkšÒÙhÏ¡ÈF72ua’\OBDBàÉó¢(++­½¨ÑhBáMÑl÷ĆéøVF`yÀ#Ú™Œ æc~Ô ùCèÂ_ܶlVj!һΈÈÌ#DN·@ü’¤ÞhpfònùL ìÛØM3ÎS+P¸Ø%Ÿ3q+TIê^±Ó¹7ª14 Í'(…t2.€ïbåc2M“q‚ذ§œhÇJ¢´:\o:rYϧƒx2[—^ZÅPü½’±¶•L•îË_^»å–´¼Üûߨ½ã…úÿNýŒYSÊpLØÓS5´:Ìj¥è¦J0ù˜†­õ9¾°An6›Ç{ì¶mÛÈ""›Á¼8ºVæ¶"ȉÏç#| Û…YÐ%&»˜…pŸÄŒÌv3~Ж­|;b!båo‹j›´ŠÜo|ä†%g´XœC·Í‹ ?ß}{ÓìüªkîÇ=¦@Œýš ë¹+ß’5#œØ:G‰u’ÁS&JDZ5¨eox&IÎi³H¾~¶È,hIÐn§ÂùræôÈWdB¶â1!­ÑN ´ô½£úçᛌ;4Mt˜<Æë¼:Œ‡– 5Øx)ÉÇÀF’ɬ½vX<v>Ç‘ÿ‹Ä×£u%cmë£Nïo¬}ùËõ/~1¥4\YY}Ë[š¿ýÛÐR©…ixd=C†¢¡Àš²âq$‹&ib?D¯8Va(]:at7•Myñ%CvfeÂi2ïó”CqkbLæ�ÏG¦áéâ/C´œ¾Q¥qF›Ž‘¹¢ù@´Ëd¶¯È \É uSÃë“® AHGƒ$äI@{Hâtæ@Œãxfffmmͳ‡ý~?^¢9éùÚr�NæqGäÎŽ0Š×$Á¡i»{>V`æ¿°8#ÁÏ„VQp°o¬Ksëiò„³ZÙ­~>¥¡õ<%íVˆt¼)s;3!%Dð²]à¶ Û“0Ý:ÍÊ5¤ÑR2±…R†háS‚PdäÙ+!M:âðÜ€ ž Ii_eæ~í)ì$ÕÄi§ó2älÅ57·ñš×W]5wÍ5gµÛ•Jeõúë‡ñÃ׿~æÍo.Š" ‡µZm±RYk6ƒ8Ï�Fmäq1e"잤'NÀXÈôca>Ä_†kˆ­ÏH­±‘RZ]]ÝØØX\\‡ˆM™ö--û zHÈm§lÆ‚‘{º0øíy`4Å0 ÜU¶,¦épŒ˜™,ºBIeu�� �IDAT{Œ-Êá «Õò ÓS·ž%òü»À0îÇ4îø˜333}ìcÏ:묯~õ«ßþö·-ÿc°($v\7ù@, NñyjC?Ÿ1×|œ_ñÅ¢ kéSâ,Ì âoHØ)â Z™Ë |”ñÆcDô¢|ágÆ·ÏÏÏšI0°†3ú€]«i½X\"½FðI<¼íz`¦¼�"‡ElÃá"‰ z©–ÄŽßUÐvŠç™Õ¸i¢\oe·jŒçÀÞ$)!¢ð•ä"±Ml�F˰ 9[vÎ>{xõÕ37ÝtòxüÉûîÛ=33Ÿ¹{wc÷î”ÒWjµ#Õê#76>Þh¼W­?–>sÆ= 2€œ8rÐ'dØ“e‡7›Çd…<‰8Œ5ˆ#²¬3n¾Iæ:i³—%8 §¤¨¦b0²ÁìèΉF4²ü°çi2BA6Qï,Ø49ÏÞsĘŠÈ&�½±,w6 ¥dD¼Ò6ë¹¹¹;wžvÚi·ÝvpgDþ)žž=êíIš4MlʆM¬“Ô²¹z.æUãÐ'eÉ`d¸ðÑ3–c†æe-„“$iw™dL>nKžC”ÿÐ'mÖjóÔ=,«YÛÁ®9| ‚¡ÐñÓ�Ù<Kçz”zž^’ƒý߬¿žš(Ž_+ÁЦo6Ï%–%ú: W™mdý7Ë+”!g+¯ÚîÝͯ~uð²— Þö¶¯×ë—µZëvßôªWÍ~ðƒ ãñr­öÙz}§È!&¥dâNœkÆU3Óe—f¤�z �\jœÞ–,zr~�D¯Åð‘7'«Ÿ´mB¬µå?{âÇ–—î·E1;;Ûh4ÖÖÖ̆ Äú<rÓç/ÁܧÛììì¶mÛÖ××—––0ßu7für.“™ŽfÊJÏFÄ#èîÝ»o»í¶Ã‡»O‡ˆ"P¢yшà!,žè¢ÅÇé–5HìsÇt¡3]g7 XŸ<íì—zmÄg¤b³C’d€iý4ö|è³8iª¹‰N®‚¸[– ˆóCÔßÑÈC33m¶BÏì£HõxhL;qF µf„‘+)\!ܺsÐ¥q•)öz,Á&FÈôÅc¤$ä\XX kkkLï9SôW¢Ì½•\­2ÞÜÏúÚ×êŸúÔÆE ‡ÃÇ®®î{ó›/ï÷/?çœìÜyùÌÌsƒ$›Î¬fOr…±ø˜'¢MG±{6\dì™M6! ZšHòÐ0d“ТDR ŠäMïEÜמži³G!ªÏlZhFc~~~Û¶mvåq¶h€Ëö6ÌUÐ>ÛðhÁr~~þéOúK^ò’3Ï<“\²^¯oß¾Ḥ!_Ô‘™µ´´IÈû³3a©B �„ñQ¾´´tûí·9r„'o9,wGøh¼ wSø¯é�Qyøaü"žO@v ¶æWÄ µfST\0ˆ+™°5«5@‰܉]™Mç´úCDîø.Šx¡ôl¬*Má bBÌ0±%ùÖjòLwFh4׎ÜîA‰—A¶4ßÕ¤V»½eSöFbó*Câ&%ñ—�Û·oÒ“žtæ™g¶Ûm8Ùj$~H¿ß7é´¬r¶˜;0«7ÜÐø½ß{Öpø‡¯~õîÕÕ×<á óOyÊ'>ñ‰/|á ¯¨T>·¶öZgÙÒ·G'8ùŽ9<q”OÂÀŠ!ñäÜÇò�h>;¶à(³jY²µZq3ëâ°yàw¥Í¾ÊZF5ËÂ<L¥,.."e$&3L˜æ BaÇív{<oO鸔RDÉx­ö¸;Ooµ>_­BnµZ'Ÿ|òÑ£Gï¾ûîØ¢ñƒ©aÕmÊÍ¸Õ CG•F�æd‡¸ÅÉ=™|$-4žŒYøž~çÍ2ïɰ ¨ŽÙõ ž¹í6<Eë§ y Æ>LB£5  dœÖ  )„ðø›Ïïv»¨üÅm p€’Q_nà ‹‚=2õ…û OØã>–¬ÍæçÒf7Œ³ç¿ÏXű„b ÈPž‡ØàÚa†Þš?œ~˜G,¾MŸN[ ŠF£ÓéÜpà ½^ÏÖ<«ÈH˜ÖðŒpr¶¸Ê‰÷× )ûßþÛ^ô¢sÞy•JåÜsÏýÇüÇñh4»¶V4á’3.ô$§Óʲ¶4jdZc`sÅ~cêŠ.±ÇßâÆØ?¦úà¯ä…l‰[º8`‡´ypÿå³gæ(÷Úèõ‰-_Ïdœ»jµúKëëÿ~4úN¥rìxüSQ]¥ô©^/½ýí?4Ý3??žœ5½^/8ž:ŠŒxЇƒ³€=Á"…ìv»1KÁ±1Û< [Ëðê ÀI’©ntñ0æ ñFøz§¸Ë¸ßn)îPvñMÓ˜Ðbš@,ìD>F›ÍÌÌĤQl£¶‹ÿe’‘N•„Mß³™ùøâf³I Çb›Q/‚Süeši6kt�—‹Ùµ8¾-gÔ7«eáb`±j8+…¨ÃàyO·îãcù¼D¢ê5Å?žC·ÛÝ¿?I­w-:ÖódžÚ.Cεs¶ªTRJNçÆo¼îºëŠ¢¸á†VWWb«õí4Á2†_œÁqЊ ghD%·Ü-´K6#àÚˆ—„4s܉"ev;Šc^š˜hA<¥ŠÈ‡å=÷C<æ4'ws|Ê(¤¤êX™‘P_Òh[ÇT«WÅ$]µú°áðÔð&py·Û½ûî»ÝùÀ›5"}”pšsÂ"3h=cª7»xíØ±£R©¬¯¯Û$‚œ×)Ž´bHøÜà_G=á™Àï[5Ž<šœÃý’q÷„èÿ1Ïá±èXç‘ßÀ �(æ\#v¢&à’+Vg¨=ÓÜï4ó›»%Tÿ,Δe9N)Ø&Ì#G¨v§Ð?ÈÁ¦´™7.hp„7–Ã^Ó¥<¿7k·Xo× ¤LožcŸøiB &`‰yeÈÙ`-¥Ô®®Õfz½b÷î÷Ýw_µZ=pàÀÊÊÊEÝîÅÍ&[e”!ÊÓíñHCð·¶gô`84³¶ª5hiu0péMõàªõ:3Á±ì`…‡fáêhe{3Äæ1â^´ƒnvWÞŒ³0êobø¿ƒWÍÏßž›/«VB÷Ì3éBá›2¾rÛ¶m -¨oâ‚Ul*w‹DU İ ùQJ‚݈7;;kV}æˆCøqˆ±!s"}fõ:œgþ~Gƒ~=ÅÀ]cú•Ò ÒÜb²òš"ÙìáÍîË ‘qçžVñ‚Œ?£“†‰�3`žVL€¨7é0ï¶ $ô|¨(‘‰CV.0Teü™æ µ©¹òY«ßÐnÆñïƒBdfèx×;®xV4™¾²—óý‚­UF£ÅZm¥Vûãƒ_Ýíö«Õ½ÞŸôû;ŠâïªÕãúÔ°kÂ}Qo$3’³)3S©š)Mj£‰ÍBÙ‹Ê�:lhjesÎH\“ÓàMR2Í:RÈÝ·°! Ò#ĹÌ\€±S<ÓâD¦¼à6…]µRyg·ûŒ……#|äÏ?îq‡Ú½{÷ûWVþÃpø²n÷-Æh’ƒw+~‘ÅQ2g0> *;P ¶yø”I‹xÅÑ“ð;Å&Ú$ßÚL0ÞÌ÷p3|eæÔ‡o6?4ãqs8z„ˆåL‚5uß,ìL9ú= !d`õnï…Œo�j5†¥0[ʨž×q? •X÷1‚£¤ð0œŠtÎàõ@Äàø¦"‘r£†·Õ܉.oùü8˜‘²‚€C¬Ýíl¡&¯ôêàé0•eÈFSY¢&”!g‹ãMüéäñøŠZíÝÆKK³E‘Rz[£ñùZíñ£Ñž”ÆÒ†JÅujÛ Ä¡ÉûæP³§VæqÂfcNÂG¬Š.Md A*¦‰aäwö±ð»Å XÇñ‰2d,iŠÓ˜a†Râ7eËNö…‚{ÝÓ®B÷›h¥ÔL©—Òé§Ÿþä'?ù®»îºõÖ[×××ǃA]p“½`sd»±R©¬­­ASvkÂk¼Ä¤‹’M3£ói5ðÀKþù•Ë|ŠÌø'“u#+vÁ¯ì•—6Ë6›-ù ØšípÜZ÷0#Ãdnk% ±Ä|n¬ÆLv/M¦›!°ÒG£F4]›•3íKýŒ¬Äal6î!Vü(ûøuÈåã»" ãíh‘%Ræøa]ÈgÞŽ¦‹iœð'žy_€÷B®™ž™›FÛÞpd`Y¥àÍ_±ÚŽV*Ÿ¨×VÕjõÛmVÃÊâöZíê 8à‘Lë�sba¹åhŸf°¸lÑ{¬Ç4GΑ€õɢ?@,Ç\{#õàWFl©vS¥³ìÉDâíi3.:L¨bûTš_|dÐ!Gb‹ösÒÝ~ûíŸüä'————––Š¢¨OP—šTPý_Ïxó)²aC°MÄ@Õ¢wm*-a¼%IÜtÉ$'hÎù3"´—y–“y°B,KÀ&+·ËgôK⸤Î~MeôéÆà‘Ø&.Öû"Lb�˜ùU»òb£U!$Fв9ßg¶z3µ#Ò]4ù'OÑN;Ú%ɾñ¨Ù³N\<þL‘dPÁÞ6ØìsãO+ŸRMNw¤2Ç(gMIŸ6žˆ÷533Cb”m2äle¼‰Mµ63ó—­Ö&òq½Ž–p¥R©M ­H—;çøÈˆàDNÕ:,X¯uÚ‰‘ AH3†ã5çQŽfŠÈ-„¥ìN¸7óÊ@Þ£_Å@eüÙ¬ÈLà,Æû¾,H­D*ÉÝÜ®ç°ãTŠ_÷gÍæk66^~èÐÒÒRÐ.þÕh´c8üÒd€œÒï÷2whe³r'À=svl|R,‡IÌ7ŸŸçE{h…÷èN>D<œ0ƒˆ¦9ú|Ù*uó#c¯xP1ë£ØÇÚ´ãÈÜ㕱ÆÀÙ"âR{N…©aóG,« ê"›‚¨Ož äJƒ™Fª}9³éÆ  îh¶qâ [#Ïlez€nˆ²Ôw<ÕN§c‡©4™ µ«y¿;'+TEÎÿÀä‘~g}²Cc±±—ÙÅIÞ¯qÈdŽ*eÈÙÊ iŠZ­ÖívÍò4b,£èÄ CœÌfrt²U²4ØÏ4cÜ !Þx:gSÏié²ë<òFa”)Ã3qMBmÜ3C?Šá¤´"RÆ—Q°Ïco£…mgúÑxHg‡l<¹?OàÏ’»ªÕ³Çã¿\YyçÜÜ`0¨ ‡ï >ÑhÜ:r­ŽCœ~ ®ÆÙI–æ£`Ʀwd¦Ñ=¾2ZP iF>‘¹³d•e’ D�Aív{mm ú–Ó—l°&ITÆ‚='¤´m8LEшØ +/ÞÔ­BW¢ ¤4ˆàñd2AåiÔ×6Ï” ö#7 Ç_§Ó1lKÀöXh\³³³Œžd~»%A� pBC¢²¾ä‡‰l.ï:øIš´�m;ÄDUŽg$bÁG1ÁȤ çä”Ó£BNáMxwij`“‰‹;2Ywa ë;ðYʳŠik6Çö'(¼/™žË$½…H7¨<\›è¯Üµ‹‰¨É> ˆú€ÎcY£(ƒô¡qD¥ÌŸ!Ë#NP¶Çgg“Û Âe’'"»¸Qcúç“龨NÆ€Iü–Ápøc)]Q¯ï®>z4¥ÔOé·[­T©œºyðžÂì/½â±PÚ2¡iH’c·}m\掑ç0b¼Ûíö<BÏI¡7by¼šØnàÅBj·Û<ö“~ÕÆÆÅ}•ÊéëëþLµšRzF¯wúü|ѧ­z<Ój.–ÈD#Šº E1@±4C€=~/‘šÉ›ÂM'+ŒL1Iˆ“M©£÷NÍ=géáñ¦�$¡ð 0×±L)ˆÛ<&DØè–4”[Áƒ>dŽõ†-þûà¸"¸«+é²—³õ$iJŸz®|­~‘ù([::\ž2Ä wzgL¬ ~¦9À2™ÜY–åÓ³gŸÎ؈5¸æææèQYòݸ "Çî帹ʧf?¸{™yÏÌßj2èßh4új½^ÆãCÕêïµZÍf³ÙlÛí‡ÃOÌÌ,7›ýn×BDOîõþíp˜ìžÉ]QŒÆã?jµ:RÀ Ê\<¤?p '`˜…ž18êÂÂÂã÷¸ÙÙÙ¯~õ«‡r|ræá|Öô¼ 3¤a`‰Õjµ2\<3óóƒÁávûK EQt—–NÜØøD½~î`�ù›ñI¿\(‹îÐxñ˜)ÏšÜV¢dÊ’Ÿ�Ÿy“ÂñìþÂ=PÇØèŒ\ Úô´Ýµ]æØ¹ B@!´YÜ,#+[B0ãšC ¶‡ˆËA£²°’ìÛ°ü6‘hšÇâ‰fo1× ÓòzNéÊ^ÎV^ * àæÔöz½P@!U1hÀKµW ½e›Ã›(’N¹öÚíö`0�ýHÒ à¿ ÙLƒû¬HÎ89!"wÈʆ A¢0O1yû‚ðÖº›™ö‰  âyŸgZÙr·T«·¨\¯ÕZõz¯ÑFK2£€¢(þõpxoµzM½þcÃá›;”Ò‘JåWææ*Õêu:íJ¥#ʇ„°£Ï0 ¡ åÚ‡§”ë………ýÑ­×ë7Üp+Ê8R–³36KÎæ’žnñàª5Ë]©<m<~õ#1÷èGW*•¾öµ8ð#)ÇÝ£6h¯M?dd# �؉5`"Þ>Ñ!6H&RÜ´ñ tDM[Š|¿ß‡Õ\Ȥ>b›'o2–GüL>2/ ñ=Ï9ð, ·Óø„7»Ibô -Âö€[¹àb÷ö̳>mcÏ0ð)@/ãŒmtm’=7Ì÷Æ“ŸÖ8/CÎCM�@ãPfL7Ž'Zî’á²à°‰Ža1çûÎ}@œ8‹é¬ºéÍ´«0ô¦8b?G•ÍΉƒ€œ×¢¢”w Q™³ ›Ùû'îs~~C3A²Éjo'¤k йG…$—™Eñ$ñ²tÝê±ùo.Š÷¬­}¾V{ضmµjuû`ðÙNçc³³Ë“¯7–Í'u!Ï™‘`"¯Æç…æ°±±±´´ôñ¼Z­ÞsÏ=qðù É¨kf|¡êˆ;_¥R©Ÿ|r÷þ õ_þKÚ½›s‡W¿¬õ`ð™õõ§<ö±¿ð‚<ó™ÏÇõWõÁÿñ?~ÿþÇôû3ª‡  bN ËXo &CáËØÌ,[¹Îƒ¯A%›“å 0íÈãÚˆ8ǃ [6 ÓáÿÔëõO±¬�Çqªq ²6G¦|a3–k8ýðBÝã±{a˜É‚p ?S("Ün› 2H¡|Rò¶HL2$Íî'š|xbaÄ\3‚R[èB]†œM(|’Øš Æ1æ³æ¼‡çÍ6R•9Ër ‹ž!H:ç%…Q~hÜÆ`0`E £cÆvµ§�`HfÅȼö\zœ @¸µŸ4=tKÃ9ñ̳>÷~Ñx†EBM‘ïÉ)]^¯¿¡Ñ¨W*Eµzoµú¹¹ŸO𤷙€·[hœ˜½J>A;:²õU#:t(>x¤,°ìxÅ+3³½©íÚÕ{Á fÞõ®îóž×h·k_ù 3ùSîÇîSšß±ãÔSOݾ}{­V;õÔSgçæâ™*G’‹éË\!·k•gâ"˜Ÿªƒò, /¾Æ¬HNv·dâ$åQ·Z­ˆ|ôÃÝù 6e¿X÷Á³b$[¾apl“Ò$©2à1OèìÙì5m=CÍ4…ÄÚš±0@éÖ Á§ÍP8UH¬/@ ËÌîÒfY©’>°Å½œL¿Ý=Œ´Ù�ч Ç>pïˆö€UèÉñ®2¯YS®M<õzµ‚Sd;vìXXXXZZZ^^Î^bžÙ8 æ‘qèC€¶#]Vw_ØBi"IÉ©šéS™g»×Y4gÆF´ØNÜ<G�Õ›G^º±ñ#Û¶ÍÏÎîÚµ«R©ìÙ³çûýŸÏ |@…ÿTpåS[ІR’`cæ·-‘Øðä¡ä°Î1]3ÄV«ÕúqÇm¼èE3Ÿþtõæ›Ûo{ÿ%/V*3_úRû¡ÒîÛ·ïšk® í _øÂ=÷Ü3ØÜh$T[%cµ°~¦½¥=øâUd³C’‹¤‰ÀAǦ«Äÿ>üá/ŠâСCœõâúÎÝh±,?�8D;n´jX?NPÈ„ˆRö!а&ƒaÇ"Slû>ðÉá²XëΫííÓæÁa*QHÜ@dœ[#1ÍŒãŒÀ÷e³teÈÙšàƒÒ¹ ËÈ£ÅQnÇú‹y¬Ö‰T%´œ}'© 8Ó‰ê8Šñ öÈñ±Ç{ 't»]&œ‘D¿¶[T”#þ¤M’=æ'p$Y˜Ž€,yóp¢-±-Åï‘x  8K¶Pt¦Íºô<:þøãŸö´§ÍÎÎ^rÉ%wß}7çiÚìzéwÍA ’™4»guw°!eq>âÓE°dFêËTC²ñ¿½‹/ž{ÛÛßùN­Õ*z½â¯þªsá…ãÕÕÖ7ræÞÏ©T~«ÑxãÝw¿ésŸ»ùæ›ûýþ-·Üò“KK·¥t«¦_MkÆ{ÍN‘.$l·Û)¥•••n·Ks%òw’ß6HQ’cºóq|”\!~ê üÌñÏòhp^Ì ¾~ÀŒ×L+%£ eËN”–ð uof#ü´ØžnÈ¡±¨šà€¹ MD¶ç!VèÝnת6¬@w§LºáXpòJ­“½&ô&JúÀ_¦ü“¦9×K›•-ÀŽâGì©FR°jî—©²·”§uéØ×jµ{î¹'ÚWÒš¸±vqIa*(þÞ"•&2x¦ÄHc|L&Û‰Up@­ÎUoÖÿ‡YkßIf-Áú,O¿ÝmäÙ=S«ÕîªVO®¿ï¾¿ýÛ¿-ŠbiiéØz½2­Ä •{µc­fm™Ç’ƒ"u4Ø]0ö[—çÀøwtJ¦g_èóm\tQ냬ÞqG³Ý>ñÄï»ï¾î}÷UÞ÷¾îÿqýw7­­mš©Tn­Õ.è÷_½wïÿ{ôhucã'{½ßÝØ¸¸^_Oimm-€Œ:¦‰™­Œ6‘áÌ3Ï<î¸ã®¾úêÕÕÕ~¿럆Ó-hü�gFñ¨iø­­­…äÄòò2¿ŽËf¼¿¡%RV©å£ÛÖ%“ëv»Ʋ§:;;KÝ“dG”Á¼Àê4ñö•)^ãD5;N¨¸È3›ƒ…jø2÷5Ýx¦ï É;v8ŒS(n¦ÔXû¾(t¢¿ %kldc7v[¢ç ‘ƒ ý›$i2#÷{¼QÝÅñ†˜ùÝnŠ Ÿ%N‡øÔãRà›Y’Eƒà·P7~<aŰL½ ?]:¥™ø¿Å§]0¹cÄÍ“ó2)Ã×·Zoï÷ß°ºúù›o.Šb¶(^ßíªT¾Gêæ)w"z„hæcõÈ+°é=ÿËá⚕ሹ<(û�á¦jRIJií¾ñE«5úâ£NŸvÚøyÏk]|qµÓŠX¿îY)}¨^|¿Å)¥ïV«Úlî&x“0ÓàâHÊVW¼ ;ï¼óî»ï޼ÛÀZÖ -B9nB#5Y쯔R¨¯& ÆÖ ©÷˜ <±lÀ6q,<wìZ,gšŒñUç!0À'ÿD¦˜y^ð_fԼ ›ûɓ蠉@¾Â"±]ˆçÑ†àÆ XÆþ)QÄ2älA•ã…L`Þdô„í ÜëõÈ¿2æk^H píèÏ�‘{ÔÙ-4åf]ê8_hfú]i³ÅaÚ¬g ;òGºúN©"¤e½è̦…ÍÃGÀ2‹œaF÷3}x°„5©üÜ5ÍØ•JåíÍæ9ƒÁ¿íõ*•ʰR¹¹^ÿFµúc“iÆ$+³hž³ÉI ¹=Ïh˜™¸¤Í©žì³+¶ìü¦f.º¨ûÂ6jµÑ—¿\ìÜ9xá ûXmÏž¡¼ã“þ™™sF£úhôfó›Hñǵjõ­VÒæV_¥¥Vlä.chžEc Ë!‹€*³…Uê�ðp~,øÈÐÓ”šo2X,0R+G&;qd–ä›fý³Oíÿf‡o¾Ñ£¬DAÏÕš@oÌÙÏÁ.'Q О1„hoŸ¶(À²¿ÈÃÈ~8…¶6ê”!çÚÙä(ƒ¶IžÖÈì>=íÁÌL–†(bÅÓNÌ=ÃÑýg¨œˆöÛdÓdâ4e¾Ë ¶5<ü7ðyÜ+»óðfæÆÈ \Ú,ê#�Ó–* ÷[%­Œh„s%]qרí.W* EqF„«”¾U«ýZJgL".¢ÐÉü“&ø'¶¨Wڬ銞Y’¡V¨ÛÙ½õL~ê¢EQŒWVÚ—^Úÿ­ßu:ë/}izÝëÆ{÷¦™�ާkëšMT�X-÷?ðIŸƒLŸPí=à*a·±Ìÿ„oÃÎi³¹ ?Æfí· Â†ŽãyfE!É>G°S{üž³–'˜-\JS½ñžáGMVúIf‘Ä¿FòœeªÍQ7“M‚¿€ºæ~‚ýÈöôT¬‘@`QDÌäz=ßS†œ-¾H<að÷¤o‘d/»m�� �IDAT!#ÒaP_`yÅ÷b+ëú7øõtJàVÚîUGFÛ«†ÈG ñ†¤›ã,Àw˜¦±@ãã·ÐÃÈä5c#YWŠ,ïAíÓÁ§U ]ÀŒe€)ðƒbtx¿3¨a–Hw<Æ‹gf.šv‰ìÀ8èNÅO¶h´›L^]Äé'Î}DB ë[$Ÿ¦vàÑóCl ¢%‹‡·þäO:ú§ ¿ó;ýÇ‹Iˆqå\C°5iFF,>83^&ƒ±b;™‚r<¥PÉcF¿ °ôñ®ƒ±¶þî‹ßE‹‘.½©7™Lm¬ÃN§UÚëÜÀ#ã,Ñ@‚aèÑ…x’ív»ÙlÆÏ´6L¬Ò>  ŒÞרuÀj3Žâ^)çL&[ÇŸ žGͽAÈD– ÔñÑ@š2äl=cÄNvQâ6#‹¾¿gÍ`¬‘{N» ÄÑCm‘I3A"`…ô'ãR{u2¬Ãô@ô².jÇÌCˬZ²u¨XYyЮñ¯qBQí‘ÉÆñÁäÀ-%ÎqgÓ>ôÝM!>YÍoÍ 0ާî3Í{…‘Å{�ÞU %B.Ó¦|¬hÅ0Óà €Sf+º6_óš¡Ô†,3aïNׯ ÕZ—Öj(D8À"î9>EÆäŽ)3;m9H˜¬<S^!õ&Ñvõä¢fA[¤ýô€Î⣡.Óò éHÓÞ«ˆ"`›%t�UŠ¢5@Ÿ·¡kSðcé‚Ù²ÒfuƒŠ‘cѲQ4ù“n•#w,r»d™´R†œ­¼,ù‹ƒ.‚“e¾>=Â…fÜÖëõ^¯gæ˜Å*ØKdfâ²,âðEÄç©©Ì™5“¥ÆŒY›Éo4Ñ‹BO F‘ÆE%—‘4å<–9á†�_(I.Ìà¡‹kº¸^ñ»Á>kÒfï»Ìà‹40NÒ�î<b¡È{bÉî³ÆÇ9fšhT{4$ãdÓaF÷nìg^$v™ø 5.}à'ü(«üñô2qxøUÈV ¤J&Y (ƒQGÆ"$ .¥YûÙè1Ó6(ñ8o0ZèJ—’"¶ÏÆÆF5ù8†§"Jq¸»QÏ,­ƒ«ò;w>êQ:xðàÝwßÍ=»”4©!i*<m–44BÀÏ× v´y¢`–5F—$m7)àž2ä<‘=!!“$|D‹B;õ{6LJƌ̧‰X,hku°øb‚ÇÞÌO³#=Y6IP`ƒ4ð©ÇyÓdž^1 D£Ø'îpÛˆõöz=ŠËU%¹xÅ HŒûa:„Q!F"ðA ©½¬ŒØÃIÄ0PF¾2å‰?Çx ]ZwˆµÄ1¼\>J1,²bôt€™™f³¹´´Di›&ÏÖwÔ€”x,�Þu’_‹ñ̤¡Kúçà™žyršŒ ­%'ÀÁâiðéœ.ĹL×Þ5çE €a¼_S=ØûÀy$Œ/ô\²@ñð[ˆ]L¥KSêöÂz•JuR.•J½VK•Jlò¡&ÉÜgEâŒ~úé§ÿüÏÿü׿þõ#GŽÄæuaO¹1%Ž ya¶à-îO&¦�ð­ËÉÁ¹â7 ZŽ‚n=°fÜÐ]ŠÐ(Ìœ] ;YaÚ3À�ý$Ñ€…P¼W¡‰aÄ3ÎwOó¹™MP­sÞÑN€lÖl6——— ¸‘4eü1Ú?qÊi4ív;pj$Uâìã{=¯±o#ˆP«Õ²¬€.ù½<ÕH3#¾""—™z÷grhLeº–…TA-ýbåS“°ŠÝ› µei/O~ÇŽçŸþé§Ÿ~íµ×þÃ?üÃÊÊŠØaX¯’€Ñc+AH2$Þ†Ï +EhÏfÔ³A}c<m›]¢ÆæN•»}ñh A5̺ܰÔ ̼ÔLô¢cÄAÏÂ}|o0‚òrÚ€3Æ­ËËߩՊ¢8{<ž/Š”Ò¾jõP¥2[×Õj¯œuqcÄ;äâÉßyçþð‡:´¶¶Œ5DŒ\*‘ŠÙð&Ãâô€â8rÃŒj„Ü:„YMÏüâʳ5Wh�‡YVÆmuƒ7s÷8·s7Úi³ü³g»ìQhR<·v¨‡,Ah–$ë›i›gŸ%M„ Ý¢£?s8ͦým1ÛŽdäþLDº+ž5~=qIN  —j‰$‘C ó7T‡© lÁüt;v© &­ïi[R´=zå'ïbÂ æøŒøÃŸò”§ìÚµ«ÑhÜqÇ„äx¶!¦ÂÇÌâ–ÍÍ|Ôº]Q-Š!›ôXÆÍr´~Úô~˜h޾fôÛ8Ô’ä* ¢f͘x;¶ÔÄ.Óé ÈÆÖÈš`ñ{�pc—27CS™wޱG׸öOâ•í¯Õ^>7÷½Þi)µSJ•ÊÁJåhJ?]8E¶¦ãåc¡(Šåååõõu÷ ]Ÿ¹ÿÄs`!ENæÙ›mÛX!IdH ³ü²ù*û‰�æg–EeÈÙš+4q;w$÷uƒÌîM&BN4†€l k:ù¸aKCÜ$öÀt ˆ f,D›à„Ì-Õ�$º/nc8,Å–€E ˆ<ÄQz½�»Âg¥‰s¸¹ÉÌö†–6Û:€e˜àö¾÷0Y^–6î€ghOE0Khb´5 8¾‘â¶±XÜÉ`0X\\¼á†Ž9rà 7t:iÛ.À¨XuQIçhË™oW0«ŒÓa¸ÉÔpN”43S¥xËæ_$ÍØg—KF÷ÌyÑMñ ‡òëÂr#¹”ScP¼ Œ·uY\Ò™f鉮øËÇ Oÿóììb½>;| Ûýj³™äÇa` £q~‡;Oƒ¿!ÈE=»#@küÃ,{j Ô‘_jÛÌÙ äÁ>6Î?¥„R†œ‡èê÷ûKKKîógš°-› »¥é'¼‹R¯½²i~88!*‰È:ù™ÄEÖÿàþ9ú½:½-ÝUv]χ‡‰ HXuÞ!'à,¤ÞBù-’PšCl9#9¸»§‰F uO’Zšýíž1ÒiøFÔv¸ Ç)I±Ùw³³³A‰@NMà $t«F“+a&Qî½÷Þ+®¸¢V«<xpuuÕÎ.¦f€5ùñšXÁga²‡ÚËu±Ä8ãXÌ–PÊqÒDL6~p¸:ãã $ÏpÚÒ{¦ÛORŸ«ÇûŠ¢ÍÏœ¨Ãj7¨èn¹EƦi5™5@6�Ký4O7¿na¡×nYYYùŸÃá/ÎÍ}¬Óù‡IíМ²¬ÔÎfÉLÈP™HÃ郺Ÿé¢Ø,f®ûY™³CÚjBç½L7…¾‘�e•³•×`0™wV€“bK �9÷‰Œ¿¯ÿ2É7–ø¸g’c‰ñ�¢Ö‰C3ÎeR0–¸Å98âÇ2u‘à~ç•I³*IѺ ®NÓL+Èܲ9̭š>ncšs û›¢f5"9f€{@ŽÌ´ÛÍ—0`•hB>„×øíñTÑ‹d©€YJ„ü—ÔÞöE{öìiµZùØ {Nç¬ÇKÆÃÛäŒcqâ’™ø1ê% ®èžJœ¿tûâïëõz”°Át÷ð/�i¤b&‹3{Ö[�ÎGGNX˜@‡¢eÂË"…§£‹?M4=Aó?k–PpÛ°™R{<ÞØ¶íçžñŒ¹¹¹Ë/¿üÀ{ÆãÓÇã¯M†™ìýÞüO'Cñ¿óóó´NÏ<óÌÑh´ÿþ¨q­§ç°-Þ=à ¶IÃ/jP~ص-µ(ƒ¨©“2Gƒ2älÁEOž¼}nÏŒx– )e²1ƒÑ™¬/¶±é‘‚'£„)—é`:×6ÇB8Pƒ²ÑŠˆaÑM2 Ê€{{ž†ÇIœ¼qX›ûøvWÙ}]·¬-Ig7»…šûkùT{YÎXg•À:èBƒ˜Å·#é’®ßïƒõõuzòwé�@<ÙGƒÍxâgò£‚ŸÍ@‰mž£qÅ"qÒ¤®Äk6^Ó'Ífý ¬Ý× º¨Õlœ ;ÑÇ%ï7ÉufZÛ ¢ý øu˜Ô±\íìÉ»£Œ`TÅÝMÆXÆ™¦5)BøûÅ¿Ÿ4AÎ>¼¼¼ÜívùXþ8À}Ž>4!Á‹qíVëÄO„­À©{À´ôùul‡à£ƒ”¢‡‘ÕºæèëdCZtgãSÄwÙä© 9[|‘¸‡o9tÒ„‡Ý'˜P²Yi¯!2cú4l™ ˆ_aU|ƒiô"åäHJò½v× óô¼´Óð ÍcKì‹§Á½Ùƒ£ß¼äø/¶èT´Q››%â±e‡óaÎί’f˜ÑK¿…Ìž€Ì7Óó§~5:ê‘RMLñÂ³Ž¸è‰q»éD•IZ`ƒ>Ç!3 ÍÑ vpe…Œ1L¦…À3A;YÞ>•x}n•£Äa¤‹8ížÝ˜Ãñ6ì>£ìÀÍ|Ï]Èn!VmâÕ•K(âb§ üEQÜ[©|»R9oqñšk®©T*ëëëÕjõ?ÿw£qÚ¤%ã*–±ÏJ{ƒÇˆEÕív¯½öZ(øÞ\™Ü;9A¶Ìˆ6€°kQæA— BQÁ›ƒ`²åC=‘R†™ìàÎiˆm쵇|€KæìÓߣDö¡½db"‘éBÄÍmsí3  k)ÛÚ»¥De°¼Š„{³ô(òøD^µ›!>űÕëõ¸1 ˜F„ˆùSü¸Àîœú¹ÃÄñí!J D¹¿ENÍhKúÇw1˜aY‘ Gó)†l¼?¤uœ‘>Ð%21Œ^…Ìž´GŽ>Nd—†|©äLGFROÀ¬È˜ïÉ”O9…ƒ%+<Ögö6çææ¢•·®#Ä?´ÑÜáð”~œþT<ñ<yÈxÄ#Ž?þø$_NØàòÅCj#�;yB˜Ž1ûLœBă\H+•Êݕʟu:g-- –—Ãák66^>~Q„7îü–,„(h{$@Ž{ǾrF|WöM.ǬÁ7æ†ï‹­µ¦;me•³eŒ5PiΚ1 ·Ä�ÞqÅ;ÝŽé¡·ô}F2H%Ž“[fÚ•Uè-ÒlmÄ´YšeÚ~4–l«Õ¨ÍE?E¤éU¸×Í™èIx¾«Õj…¾§÷Ñ# ÐVq0…Ý2‘i³Á‰ ]îº3'Ï„lV©T‚XÝœFŽ©Ý !nüV«Õv»Ýh4ºÝ.HZ|j@•¢(P<òü– ã,™Mj&ÌŠ?zöC¦'–X-£Ñ¨×ë± Iœ½,AYí3•°¶0=,R“€­âµR•ÚLvccã¾ûîëv»¤b®–èÞE’‚)NjÛ,þŸ‘¤I2åYÆK9ÜÛ)l4.¬VßÓíþðxœRzO£ñ¼fóœÊf§êÈã™[ûõt \—54ù#I …=òZŠÎ h±é*1Í&p™µ:xšbxÛ€®Ö¶¾ÐÙTýM¤$­ñåö ”*³uÁ÷í’déቓø9±%ØäL“˜ÕÊJ L€34[Žn Øõ™,É^ÑWÊvNd a‘§êè¢ûÆ\º—iïBT³<gO€þ³eBPäÅŸ¶Ÿ˜«:k82g[=€g�>£!XÇ×П¨Êj3†ˆ??ìa Þº¦ø´b9¡X„„g’2«@ƒ‡T]p­�Iíèq <>BŒ“dó­/n4OGQ“Qéå!1Ñqqq‘¼¨=³™Í) Üa¸Õ>”é&mšªG-eî³õú³66Š”¾\¯yþübJEQ|I^M@¦î~à¨ÃŽq3Õ>ãÀ•XðH+ñö3Ê™{–,æx>èþ’Ô2p¶ÅÍ‹2ؤÉ�&40¤Šà¹û+é¾p:;qðˆ� #áÁ@*çï`0ˆ,8~÷`€C£Ñ8÷Üs—––îºë.$Š9Øc1hÄ2e8†Ý»”w‰Ü‚b\pϬP:+H`}èîE6ÎbÒ9­2KÆ5wràIÀ4qHã/-�œ$?E¦iÙ+ ô&‰ŸZ^Þ;Ÿ`@ªGíRJëëëN'a"®'uL?³– èëS›Ïòô%¢Úk4Û·oJ‹ä–$Ož_—iV¦Íf^Ó%oÚlc{Xp4ÿý“M˨ÿÁÚ¢ebµ1COÎxb¡¢„fñ†ˆÇ‹¢øÃÙY'FY)Iâ’; ÈÎ𯻀i³°&½O‰ì*œû7)É i{‘8)¤­E<Φì¶…%NrRVÙïŽ)_Ã÷Íf3êbkÚgl"*kPÙOšLP“ôM›î°^í@û!¼èm|ÂiâãÏ“‰üй¹¹¸áø8œ ™ù{H·4ä´Ñ ôŸ¬Ô8œXîÌ^ø3 =IU—þ3°xV€Ñ&SA” J‚¼9}PUáø6Õ¬#äz½Þív3OX;Q"jI%QÅúú:µ”eÁPÒ4“ž³•cYU õPKâcr’’#§”vìØqòÉ'÷»ß]YY§G!Žæ¬¯Ãવ³p€gËà ‡å½3ÏoZ¼œ×2áäg™vmFfáö8”CÂ<#Dx ÀÚ ºx}f7ÈÂ3&=<@”=9g½d­oBaçÏïÂ:›—eÃ@c<Þ¸‚hE®2älåeX Ø“Ó6ɆR×{�âŸ2yu( S醞±Ã’G.ÈVF£Ñw¾ó†.“dù NözaŸGY³´´äÄ͘aüF¥˜ …°TÚ,wO¦†ïµ}P¬V,n’(ü.Ó A!h:Y´Ó ?Øèô’<º¿mju8™³?¤Ýn‡…YFD©x2ñnùz¸ o7TIÒÔ¨ñ›ßhÈ1"Ä48“äB_Øêp8\ZZêt:?l4àx`‰OupÓû‰k'4“ÓÌ}·\…ˆXÃý~ßÉ %ÒyND¦ý+ŒbÀL³éß´÷SVDXòÜy¿ße6K÷:&Ùw*3î„Ξ y¸ã…V ]X籪éíSɶ§‘O¢x4qÃÈCQ<“p£'¡´er¶l.'Ë¿ÜßΔ=’IwdSîž’ΪfÚàÙ7fj¯ì7Ú °ê¾}},•†Îè“g@xàÚ%¶‘Ä‘Ö@f7žyÎü9¦-5³9à/ÇiV!šóîña# Dªë”C*IjÁÖ,~ÔÃápuu5›(¢È#~G¶\©Ñ-çÔñ:,ã'à¶mÛvîܹ¸¸hu¦ý é¸ÁFâì™*w5Ü{`J7³°Àó´S+øÍ^ü^ÉNeø ÈXºq34JãmÚ¹ÃÛ<SÔÂë18aF¨é‘Ī œÊèÎü™„ƒ15 DPk†Êd+Ì=p< z˜‡ã`‡*›)سǼŽš¸í`‡‚“›XdS+íßQ†œ-ãpj PË 3M]sŒ´Z¿–VÇ.â{6Á]Ù0áj�ŠX‘Œ‹Ã5b3xD€ ÏÁ„kH äæ8øäåçd?ÙˆYX#Äö euo•ìȈï#ùq ~G&–âTôÏG‘¤©Àx>(ÀMrËä„ö’õ€™²Úu"°úað"^k¯×›ŸŸÏr#£š0Dz±Œ´Y¨Í²fÁjI›…òø^§í´¯ÍìëÚOÁ‚ϸûîÓÐæ´Ëx¦Þ-9ÐÎϦ TxTÿ$Ræ¿8öú$öSµà9§¿™¨µ3s!nunn®Ýn¯¯¯C·É65¯Òð—Éú6°÷>²*'îGnèÒVôÏßBeÏ2ä<0Äàl¿¡ìõ�Óq5wÀâóñ£ ;ñâDÙß@ƒµn¥&gÁTYc€¥_cçä×6ój*]V1ÀéD—Sa¦aH»üñ鎺ûͼjÄ?=ø6q|½ ±/#“™À÷?¶èÁ¸ 4íŠÙCW$ÎÙ¡dó(ô�ß»¿âØÿ–3‘Q*¨½^oß¾}°­Ð…-–,§Î"n’]ñC(Ÿàd¸¬m O¦ßï“i™cª›É¡ F ô—RŠ1,7‡ÀvX'Žöd1g74#¤FK2«¨~"2EÓ+Þˆ›¬ìV’-ܧè¬ð4�Žâ&#–˜ |Æg<éIOºòÊ+÷îÝËmîQ9g<;Ø%°&ÝöÃ])‚ &³Ôg±#¸yƒeÈÙbÒšá‹äO¿žÌ-;Ó,\È 3üÅ–#s×±µŠ"í‡L3ÔU—ó dŸ8Ö@ôl³a@ë¤q3 x[¿‡’Y‘º\C5ÀS´|8ayß-ÎP¼¶ˆß¶oÈ(ËøÐèdª†œ˜Ê.Í$¢=ëÑZLº÷4*¿´©ët=ƒ8¡GR7ø”aà†3%žF¦ŸDšl–—£x’•*«ñÓ õ˜aÅý0*kU®Ý2˜¡™ä û™²j¨‘@ÞQôâ& ÇôoŸx¤kLsH›ÅîÈ`2mS`²±>,Ó3E›=g�ëMjß¿ÿßüÍß=zԤ˲d¼ž9‹„S‚=hWrK€ÇR·qƒÙL~qeÈÙ²ëŒ3Îøíßþí´ÙÖÌMˆ¬£`dXËÇšçYÏ#m^sUî–Ì´Á?Ðdsµ}Œºëëfì4mÌzV>gÉ»-@b×û.gN™%÷-ÏÊ~É?5·Îð=‘ûMÑ9ð£sD„ìdZªuµ½«­MÖl¼­èX8Àm“¿1žI€·X2*Gö£4CÝQßæ4×�I‹’eËÀ¡‘gÉÊr±V]r‰ÀÚ໬~‹�§¬ÜC%ÐfSÌÓ[/›Éu'ɽ" $'g„4^ )¹#›$îy´ÅÏ*ÉT7«ê¦ç(Ø,þ³ &™}­'ù fL ÛG<Ã33 ÄJ¥²cÇŽ2älÙuÎ9ç¼éMo*ŸCy•Wy•׿èUj¬•Wy•Wy•×C^åEñ·û·å)¯ò*¯ò*¯ïáuþùç?HÈFOúÓýu™ÌÿÊ?}o¿ìûä6þ™/{(Å÷Ãm|OÞÎÆùçïáûá6²×ñ/½`ÊSeK¶ó÷ðçÿôOÿôƒ„œýÙôõ?óß45ö½ýÆéŸ_ÞØÿÎÏÿ¾½±´y áûóÆÊ5\ÞØöm’)*‹¾ò*¯ò*¯òzh®2ä”Wy•Wy•WrÊ«¼Ê«¼Ê« 9åU^åU^åU^eÈ)¯ò*¯ò*¯2ä”Wy•Wy•WrÊGP^åU^åU^eÈ)¯ò*¯ò*¯2ä”Wy•Wy•Wy•!§¼Ê«¼Ê«¼ÊS^åU^åU^eÈ)¯ò*¯ò*¯ò*CNy•Wy•Wy•!§¼Ê«¼Ê«¼Êëÿ÷õàæØcÖmôô˜³EÚ:ó’Tº¿<$+!ýìeò/ñFþE]|Ê7²%oäçdþÃ?üà 9µZíÊ+¯Ü’¸wÕUW­®®þÂ/üÂFÅ+^ñîw¿ûã³\ýõ»wï~ñ‹_ü“dý ½rã|?_ûØÇN<ñÄ'=éIåÛqªûoŸö´§mɇét:KKK[õÛ¿ç×ÙgŸýóYæçç‹¢øù8?`o§Ü8ßÏ×Þ½{O9å”òí¤”F£Ñæ¼óλæšk:ÎW\ñ‚¼ •Wy•Wy•Wy}ï®Ñh´ººzå•W¾êU¯*éåU^åU^åõ]eÈ)¯ò*¯ò*¯2ä”Wy•Wy•×ÖUÈ~Óúúúõ×_ÿÄ'>1¥´ººú™Ï|&¥tþùçüñ)¥o|ã·ÝvÛöíÛŸñŒgÄ×_vÙeEQœwÞygžyæ÷Õ#[^^þìg?›RzêSŸzì±Ç¦”®»îºÛo¿ýÿkïlƒšºÒ8þ X‘U´‚°²€CD¥ì‰¯ Q‡vfp:;®Úu¦Ë´£‚èn\¦(ØÒÑŠˆÀ(¬Ú()ÃZ@5„¤ò"c ¼Š!7›×³Î4eìŽvg´ x~Ÿî=œ{ïó?ç<çIÎyrqss#Ûkã«W¯Àºuë–/_�÷îÝsrrÚ¹s§‚[·n†††ÀððpUU�DGGÏŸ?�îÞ½«T*½¼¼ø|>�°,[\\ �áááK—.µ!åååÖÎßÙÒÒÒÖÖæââCêܸqÃ`0¬Y³&((� E]]�ìܹÓÉÉɶZúúú4 —Ë%§ÍÍÍ<˜?~tt4)ùþûïM&Shhh`` �ôööJ¥R�xÿý÷I‚PyyùØØ˜¿¿?BÈÞz‡ —ËýüüÜÜÜ� ¡¡¡§§gÑ¢E‘‘‘�`6›¯_¿�ëׯë­·� £££©©iöìÙ;vì°¹–®®.'''âÝ�P__ÿèѣŋoݺ�ŒF£P(€M›6ùøø�@{{ûýû÷­é…"‘hrrrÕªU+W®´¹ƒÁP[[K¼�T*Õ;w�`ûöísç΀Ÿ~úi``€Ãá„……‘ɼ¤¤�¶lÙâéé �¿üò‹««kTTÔóŸåèâæí³éïÍ=#ÚaÅÚ¿…¼:U‰‰‰·oß�ðÅ_èõz†aÄbqxxxSSSii)˲*•ª¿¿?88øÌ™3ccc Ã444¸ººÚϼ–––f4†©¬¬Ü²eKCCCYY˲ýýýCCC\.7++K£Ñ0 SWWÇårGGG/_¾l0Ôjuss3dz«xsõêÕŽŽN×ÖÖ6oÞ<ww÷ôôpe2y��&IDATt“ÉÄ0Luu5ŸÏ‹Å‰drròÑ£GZ­6 ##cbb‚a‰D‚š3gŽÍUˆÅâo¾ù&333>>ž”<cdww·P(Ôëõ###ÝÝÝ!!!¹¹¹Z­öÞ½{Çb±dgg“ž­¯¯ß¸q£ å?~<??Ÿa’bÛÜÜ\\\¬×ë ÅêÕ«³³³GFF†‘ËåË—/gYöÂ… Äx©TºaáPØÖÖ¦Óé<xàììÌápl(G$]¼xñÂ… ü±µP*•ÆÆÆ†‡‡{{{×ÕÕUTT°,«T*GGGƒ‚‚¾úê+†aˆ }ûí·ƒall¬µµÕ†AÔb±$&&æåå-X° $$�$‰X,žœœ|üø±Z­^±bÅéÓ§µZ-Ã0555!!!J¥ò»ï¾ÓëõOž<éèè -((xüø±V«mllôôôôðð°aïæçç‹D¢}ûö€V«ýòË/É ‘H6oÞ\VV&•J'&&>|h4ýüüÒÓÓY–%SĦM›ZZZJJJX–T*•«V­zæj±X>PY~«Q*¯@tä?úøâñŒìBüÊHHHÈËËä!D"""´ZmaaaVVƸ¥¥eÿþýãuëÖFŒñÁƒe2¶'¬ÆÿüóÏ‹%77÷üùóc™LvðàÁ©öïßßÒÒRSS1ÖjµØÎ FbŒ³²² §I„œ<yòÚµkã²²²¤¤¤©cbbúûûíA…B¡‹Å+W®ü}7#E"QJJ ©ùÞ{ï‘Ìï'Ož`Œ;vûöíÎÎÎÝ»w?s­­¸{÷njjjZZ9V(c«‘Äq0Æñññ555VDZouœóçÏçææÚVNWW—X, ZräÈ‘˜˜˜gŒ¬¯¯ÿä“O¦vÁÞ½{ÛÛÛ«««=Š1V«ÕÛ¶m³¡‹Å"‹ããã H qŒñÓ§O»»»§/zzz¬Ž3445Õq>ÿüóÒÒRÛöN[[›H$zçwÈ©ÕH««‘7nÜ cÒ*pÛ¶mjµº¨¨(33cÜÞÞ¾wïÞß?¢OmŠ/ßu²Âu±ï,�ptzã W‡Yޝ(ŠŽŒŒôõõ½ýöÛ3c-R¯×çææòx¼ '99ù³Ï>ãñx*•ʺª9íðõõåóùd`°qãÆàà`멇‡‡¯¯¯R©LNNÎÏÏŸvrüýýù|þ¬Y¿íwww»¸¸,Y²dÚiqppàóùS U*ÕöíÛ:D¢§\.—,—ÜÜÜÇãñx§OŸ~96Ëñ ×…Kþ:Ûù/¯<}@©Tž={6))iáÂ…3c:&ßiNœ81õ'NÓ””””´´4™LæííMö¨(vHcccfff^^ž³³ót×RVVVSSsâĉÓ;"‘(;;û£>:uêÔt×266výúu™L&“ÉŽ=úÒïÿÊ÷Håryee¥F£Ñh4MMMUUUd‡múâããK'AÊŸFSSSIIIBBÂÌø—œœ¼~ýúÇ×ÕÕi4𢢢é®(..ÎÛÛ»««‹ŽUÛ‡œÍ›7»»»ÀÀÀ@oo/É®¡P(œ®®.ggg’û4ÈÉÉÑh4�ÐÛÛ;Ý?€Rþo¼Qb9N,Ç™9E¯t“J©T>|˜wvv"„Bµµµc“É”žžŽz½c̲ìÚµkBW®\1›ÍvµßNfBr¹cl4SSSB{öì1 cNG*…B³Ùl6›/]º„ cYÖÞÒôz½@ @‘D5Œqmm-±¿³³“LHH@ÅÅÅ*•ŠT¨¨¨°X,ö£e×®]ÖãgŒ4™LgΜAEEEYÇØÖ­[B/^4›Í‹å‡~ —<}úÔæZ***rrrÈñ?þ¸fÍbÙˆfY6,, !téÒ%2Æ„B!© Óé0ƃaÏž=¡ÔÔT’‰cW½CHIIimm%cìøñã¡>ø€Œ1FCä[,³Ù\PP€Šˆˆ°'***ºyó&96III¡?ü?::JŒ/--%Æçää „"##ÉØÓëõï¾û.BèܹsÄél‹Z­>pà€5?¢ªªŠØ¯T*ÉXúôÓOBGŽ!céáǤ‚D"!Ε‘‘Ú±cø ýœXŽc/÷,ò rð DûÎÊ�À³÷ÊÑØÝ4S( å%¢b «Æ{…ÿŒ¦o P(ÊŸ 9 …B¡!‡B¡P(3‹ß2Ö&ç-¿×3Ì™G…B¡P(/…Ö>íìö?BŽÆ}ÝMé}?·e´( …òR¸)Uê½ ¿þ/ê)¿Ëqp˜˜Ëɼ¥xá-\&”ót=´)) åµs6Œ;¸Xíó«MÎå8þo�ÀA*m8øï‚ÈCç¬÷yþõ‹%|©1j…#mq …Bym)ëq¼óxÖ C€�LŒT|Wxú˜“§çâ ·ÁN¹«ç2—äÏÏÁÈêÔÃC:Žmq …Bym1çÌyaÈ ñf´·u•¿·§§§yãô¿Ne·ö ðd¼ðb³ÉÀ±(‚æ=¥-N¡P(¯-}sW÷L¾i2L¾°funb°ß’Çâ¸\®Æ� ÅààPô®ü‘'Í2ëÍ“´Å) åõeΓƒ¶¼ømú¥×.yyy.[¶ �þ šib š©É����IEND®B`‚�����������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/editjmag14ds9.png��������������������������������������������������������0000644�0001750�0001750�00000531147�11332127303�017510� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ ɲnS�� �IDATxÚìw˜UºÿOåÐ9LOwON0C†‘¤¬a ãå*«"º»Š×Àªàª(¦‹:ÊÊêQLõ®˜@\QPEQ@ ÃÌ09ôtOèœ+‡ß…-ÁÕÁe½ëïÖç™gžêê·ÎùÖ9o·êœÓu UUÃá°Ïç{ðÁ�øAºbî<;ÐÑÑÑÑù% 5M”yl#´…B.—k„ÆápØápÀ0üÃf………wÝuWIII^^‡W®\ÙÙÙùàƒA�øGÿÿÀ߯¾ü·z-êèèèü"dù­uïü÷ms8Žûáæ]ûÿ /,\¸a˜‘¿òÊ+óçÏ—$IÛ£í<t[û?00ðÈ#]sÍ5¨Ïçëêêzà ŠÅbзÀ0|ô¶(I_ìný%–û¨Rwß`D¤Â|[–⩬Íl0Px Çq´Ôëìè�Œ¯*lê ��ÆTxÛû†eY)ñ:â)&•a6ŠÂÃá$Mâž<k·?t¨}n£¼È5I0¬àvZdE ÇÒ&é°û"0 U—ytj_UâîŠð‚Toc9!–ÌZÍ´‘&Ã1CÊ ]í½C‡Ú×”{;û‡%I)ö8’i&™aV#Ž¡CáEb.{WðPûqU…-]Ue…y¡X*Ëðù³ª‚P,e¤É<›±w ÁИroK×ÂòýÃ1޽.+/HÑDÆb¢ÍFÒ?ÃP¤¢ÈÕv¸°ê2O·?$Jr‘ÇžÊpÉ4ã°  %H+rÛ;}‡ p gPUÔ²g8žÉ0œËn† Œ¦ 4á²›{ac+ ›/áÊâüPŒåDOžU¥h"c1RÝ?EQ¸ªØÝÚ3x¨ýè2Oo $ˆr¡Ûža¸Dб[ ‰ãŽ{œ¾#ª¾ ­wPQÔÒg4‘Ig¹<» ááH’¦p·ÓÚ󪾢È5N0œàγH’‰§ÍFÊf¦}ƒQG—ºt&L÷IÝ'Ÿ c��–e£Ñè¡ù÷¶ð)Š"B$ù›Ü¶¢(²,kÆ?`o³Ùžxâ‰Å‹û|>$‰Ü{fýhê½óe CL6ó úc³ÌfÒaS ¸ÚÕ¦<ߨÜÑ—J%'–9÷µö$‰±%ö¶n4+Ê£cÑøàPÐJÁ¨*öô�Y(°‘­ýétr·ö+œûÛzã±x™Û4 ÃN& ¬Ï?„ÉaDÛ{üÙLzl±­±µ7•JN*w6¶ö$â‰Q–>ÿP(q[ 6›ö S˜b¡ξ€È1•Ss{_*•œXîl<ÐH$Æ”Ø:zü‘H¬ÐIÇãñÁ…„pHêö ªWè tùÒ©äÄ2gãžd"1¡ÜÙÜÞ‹ÅKóÃÁðÐpØaDU‘ë󡪘gÆÛºû3éôøR{c[O2™œ\îÜw 'OTy;áP(’o%X&Ó&QÅBB½~ÍVyÍš°Iš}"QSlëì D"Ñ•L$ƒAHDîîPD¶8>ÐéK¥’Ê­=ÉDb|™£¥£/‹—¸ ¡pth8d§Q ½ýƒˆ*æ[ð¶îþt:5¡T³ONªÈÛw ;OTxÍþÁ`0qYpžÍúC"Ûh¤³'À2™Ñ…–¦ƒ%–·¯µ'OTY»û‘¨×N¦SIÿ`ЈUºúd-uZ:|ZÕkÂÆ•Ú[»ú£ÑXqž!‰‡l4+BoV•líò¥Ó© eÎÆÖîd"9©RË(^î1 ƒÁHžy¦/0ŒC²ƒF:züL6SShÝßv°ê5a£ -=ýƒápT÷IÝ'Ÿôù‡DžýÏ•,Ëþh#Ãðþýû§L™’Ífµ*��‚�C� †áœ}KKË„ X–ÕŽUUí{(w,à kßN:õ®»îBý~QQQ,Ô1°›H·Ý˜Ë~(–Ͱbu±CK� �`¦p›‡ (Í ñ¬�àµÓŠ ÂINd†,4n¦qEUã>ÃJ(yìt4Ågyñ8>»â4“‘ljrn§ÍHXiœåhŠeÅi¡�uú£.«Áë²în4Óøø ÷—Mý40¦dgK�¨ê˜ Oç@,žæÊ œ /÷޳ÕlÜß=l¡‰1åù;šû $6}\éç}8‚Œ¯*hê eX±²ØKsþP²Øe%I¢¥/d3’•Ey_ð)|ZuÑgûú(4ºhwÇ/H£Kó¢™áX¦Ôm0ÒæäY ….Û7í& ŸPéþb?M`µ5Å_(Š:¦ÜÓ=˜ˆ¥Ø²''*=ƒqÝä°šöu Yhbì·Â¦-ÝÖèCh|•·¥/œÎ Ey‰¬ÐLåYišlî Y Ĩ×ο‘ħ/Úº·—ÄÑI£ ÷t s‚4ª$(Î E3%n;Œ mý§™.vÛwµå„ùh­­.þúÀ€¬(5åîÞáD$Á”y‚¬vÄÜ6£ËnÞÛ9d¦ñqåîÍý›6¶äËý~ã*½­¾H2+Tå¥XÑ7œ(̳TsOÐb F†ÍüVØÄQ…û:‡Y^ª*q…âÌ`$]’oC1¬Õv˜èR¯£¡5`¢ð)•îm> G§Tíjd¥ºÌí ¦Â ¦ÌëT¨+Í·ÝNËžŽAMØöæ~šÀ¦Ž)ÙÞì‡!0¶ÒÛî%2|E¡3ÃI}ɧÅl¢›ºƒQ]æÚÙì7’ØŒqEŸíë#Pd¨‚Æ®`–«Š]‘$7NçÛp?à ÛMdy¡óëš0Ïç}ŽN]ôMû É£ËÜþp:Ï–zìºOê>ù󸤙&™��üèóM®‘ÏmïíßõòŽ#ZÝÏ«=Ö( 9ÒØÎܸ곉ey·Î;Áa¦>kô?ðÚWŸZseÝxšÄ´¿ßx½Þ+®¸‚ã¸mM÷¼²³{(9¦Äi5’0 ÷ %zóë5Ÿ´”{l¥n+Aë¿h'MvÇþsjñ´r£‹`a™÷G£Ñ¸ôÂIS*MýI.r™/˜YZ倪óÉ"·ÝJÓyÓ¹cz|þÁ8¡„ àãòWê6Ï?¥¤¹Ó—äFU�›hââYå•Nxl±5‘áÂ9ÃË‘ç¶òlÆ=]a›‰*É·ìé8Væ±t&8Q©ðZ#)~8Á–¹-² u¥¼£ÕDïï8ÌTq¾eWgÈ@âenëLU¡r¯u(ÎDR|¥×ÊŠJ_(]è4(¢Å˳Ѕ.KCGÐb Kó-ûû¢‚”{,ýáL’+½¶+"Ùb— ð¶@Üm3äÛ»»B6#Yâ¶îíVæ±t¥XA®ôZ£~(ΖºÍ*€º“^»Ñn¦÷õöMgˆ&ñ2·µÍ“UPáµÇÙpŠ«ôZyIí ¦ &“hî‹åYè"—¥¡=h¦‰·¥¹/ #H¹ÇâgâŒPéµe8ÉÉ»L޵úãù6ƒÛaÚݲɷµ±'‚ah™ÛÚ3œÊòr…×σ1¶Ìm† ¤s0é±z_OÄn¢Šó-{ºB•z,턨¨^k(Á†’\…Ç"ÊjÏpºÀi4Ȧ¾¨ÓB»,»:‚&š(q[›}QBÊ=–h6–* lY^îgŠòŒ$èç[ §é›ÎÕ@–¸-= CÊ<Ö¾`*ÃÉ^k"+ĘR·‚‘Ž„ÇnpZ {»Ãš°½]a’ÀÊ<–΄ ©^k8É\¹Ç"*PÏpªÀa´©ý½Q§™.Î7Ó4ÒD©ÛzÀS!¨Ücˆ2Ñ4_U`Í ²/”)Ì3R$q ?æ²ÒÞ<ó®ŽÅ@–ä[ö÷F)÷XûBé+UX“Yq Ê”ä›mHè>©ûäÏà“Nóp0|ÎŒJm,çGtkkkµ±œ%/|Á Ò!§¡mhÞ)5AÔÜÜ<aÂ-åߨ5ÍF3¡“Ì ¾ýª‚–¾È¬ñEùv£ªª0 ¯^½Íö¬û¢�°¿7òØúÝw_2S”¿®ÛÕÖ�¬ÝÖv꤂�€¦I¢Ümnokù|oO,#drÂèbH ÏØA|rÖVæÁ|ü…76ZÝe7^tʹ'Á)²$§ƒ'.³:]VŒ³8 [hlÓžÁb'}B¥`OO¼É—Sdž\n'y…no çÛ¨I¥ÖDVÜÑ%8MíøëÄR+/*—…²áºIµ^—Ía8Q.Ï7Üó×7.žsVS=àË*˜Ùc'M4ÞìK˜h"ßJ·RŠ —ç›|a&‘‘&”Zƒ !˜`GyÍœ¤ö‡2…NE`;„ÕH:ÍdKEЗ±'˜M1ò¤2Ë@Œ'ùšBKŠ•¢L‰Ëˆ£h³/‘g¡l&¢É— ¼ÀaèÊ0¼:±Ôâ²Ñ”0®ØÍHC1¦Üm�nõ'Ý6ÚDãM} #E¸mtÛ@JRáÑS˜gÄ %–`J ÆÙQ^3/_(]è0Ð$ÖäKX ¤ÓLèOÁZâ2ö†²Éï„q5…–4§"Ù’<#¡M¾Dž‰²™ˆf_‚"ðB§¡{(“å•IeÖþM c‹-ñŒ4cÊóŒèOºm”™&š} #…{l†Ž”(ƒÑ&_„§Åñ%–pJ޳U“¨@}C©m ñf_Âb \Vª5‚ ¤4ßÔb’Yib©e(Á‡\u9Ë«þH¶8Ï@âX³/é0‘ÙìKVè4vgÒ¬2¹Üêp‘?¶Èg¤Á(S–oD`¤¥?™o¥Ì¢É—0¸ÇaèÈð_bî°±C„UzL²u ¥¼vÚ@âM¾¤™&\Vº5R!¸,ßä 1‰ƒÂ„P‚]`fµ?œ)rHkò%ìFÒa&[ú“†ç{†³)Vž\fñÇøH’SdI0ò`”)u1iñ%\Êj šû4‰{†Î¡ +‚ … ãŠ-ZÕW¸M €Ú)Ö}R÷ÉŸÁ'›|‰\#?’Ñ“ÃÆÿ¡ïï^‚¿ÏøâSF·ùc¢¤lk lk:8ùù¬Ê òL‡&Žæ¸ówÓ¯yb‹,+M½‘[žûLQÔÁh�` ±».9)w€ hFÚß=ybͤ±Õ_uF6ï M­tµõô kkJ[wó­´¯³#Èb2pò J))E�8†ÖÛiTŒDê&TíÜß3±¸¼¥%O϶µ•ç‘çΘ œ=¹Æ×Ó©$§MÒgN-ç£/G9N*5¼×Èð*æµRgO)èlo•r–*óÎ÷Ê›ï¦3Œ§d”*» a0Ûq•ãî²< …u 1 WäÓM~FÔiæ&?Ãò¤³/ÂÇ3be¾!Ë+ﲎv3$†9¨–F”Àô S£Ÿaù„2KGK1Òh1ž•ã|B`¸s˜1Ñx¾…hdeL*1îëÏò¢2µÜÒ2Àdyyl¡i8)†’B‰“–à‹0V#a3`íC ÁUnÃ~VÔi忦�ÃòÄbsLˆ¥Å —T”˳4v38†;©æF”Ôœ°Ú2KWK2Ò(1ÁÈqÞk£PîfŒ$î¶­ƒ¬(ƒéß ³¶ 0YNS` ¥¤`B(vЊ õ‹‘°ˆöa¨p•ÇØäÏò¢:­ÜÒ4À0¼<¡Øˆ Ñ´Xî2p"è²N3i$°ÎaCÑ’<º%pX O)µt‡¹dVå6¦X%ç=V C‘Î!†&0l`EL¯05ö3¬¨L«°`2œ\S` §¥á„Pä U�wY‹p˜ˆö!FUáÑ^ã~–•iå–æ&ËËã‹Lq!’Ëòh^ýÖa"MÖ9Ì 0R梛6¹ÔÜæY±ÊmHsJ Æ»­$!à E vêÀà·Ußϰ¢<µÜÒ6Ä¥Y©ÚkŒfä¡8_h§ îfÍ4žg&Ú†E&zþê~\‘i()†“Bi-ÊÀaí&B÷IÝ'Ÿe�ÛÈ/GÄž\D€aØj ºêä#ìYÛð½ñizµç¿.yÏËÛs‘iÖøÂÅLµÉCΧ†a¸Øe~~ñ™»�§µxS˜gþŸ¥s œ&mÈ@@° O$–®z[þɅd……¯tSƒÃQNT'¯™`4-8íÖ|o±Ýj!P(K¢ôí$q°kOãWͽ‰Xô£­_&“);.Œu£óÏýÕ)'ž`"T³³ÒÈç_|ÙCUEv1›Ÿ}Ò¸ÒB7ÄFÙp `…ÛŒøæ?m �@ß@¤½?rÙÜÿ˜ÿ» C¹»;ºè²óª½†P$ƱL(£ìà0[@}Õè�šPDÓÇpå&{#B4+;VR{£¢ÃˆY hË G`È(7¹« hR ½³‡dPã¡Z‡ù§–æ Vî‹ùVœÄá¶ažÂ‘²<bO?‹ÀÐä×]YIÆP–@…‹ ¦¤¡¤äµáu†…zmxc€ÃPx\!µ³'«�h|½ÛÇp¨Ê'}1!’‘‹/«=ÁnÄì´yÃ1d´‡lèc�M*¦¿êaT{¨ö ŸàÔÒ<"Å)¾˜è2c4·ó$Ž”»ˆÝý,CSJ¿¶?ÀfPî"Ãi0!ym8‚@!ÁH¢…6|_€Ex|½³;+«Ð¸BzO?ËŠ *ŸôÇ„pF.tࢢvG›sšÐ¦AG‘j/ÙÐ˨�šXL7ô2¼F{ÈΟ`•'‘敾˜è2aF iâI©È'vû4aôö€1^ªi€Ë ÜED2Ò@BòØp :‚¼@Šø>?‹ ðÄbzÇAaÔ^?ˈ 2ŸHH¡´\hÇet‡«s™Ñ¦CášòëÞƒU¿«—á$0ÚMv‡…8#;‰¬ öEÅ<f¦ÐC<!•ùä7>‚ É%ôŽnFP@—jäÒ¼Z–GÄÙÝVÇàö OH‰“ØëgžTbØÞ•ThlÕ¨ s‘C i8%Øq@]aÁB£n ®û¤î“?ON)1äy‚XAníµöÇø¢Ú_s_D”•ܤ€C®ðÚr•öÊ;M` jŸÛDåЇ!YVeE=b è»§‚Ê<Ö¥¿ñèÛ»|Á� ªÀ~ûïfzÆ\�’l¡°_sš¦z¬Òð[!XU(5Ò¸( ãKìÛ ΚÑ©Êdiïêiì J<�@*���EQQ“KUBY`Œ@Äe¥üÁP<}rmu$ÉtÄ~sö©,áRUÐúíÍMNôGF8€‡SbÏpúܺS{�Ià—‰‡ÊŠÜrj`0îRÃ6«eÛ®&s`�¶Q À‚ìö Úàö((P…g”PV-³!¢ úb²Ç›(dÿ è aÙå(.´!̓"€ "<”c¬Zé€Yô'”3Lbða)Ï�»Íè×>ÁLÀ…Vdo@ÀP¸È÷Åä´�ªp’SRJ±F¨=,åa§Ýí¬$\`=(¬Èw„DN*íP$«3j™ ‘UГ=&ØB#ƒ¢‚½ä›~Âá"+Ò2,*TjƒSr”Q+0+þ¸\`†ii–œ4ì1£ >ÁDÀ…Vd_@@Q¸ÈûbrŠUN8Í«¤RdQj I.œgB¿Ñ„Y=Çà"ÜY T8à(£ gÔR¢¨;"»M°•Fö |'ŒÄáB+|`X”U¨Ä§”£VØ^¾¸ì5Ã4‰4‰N­„ûƒ&l@D`¸È÷'䪜pZ�¤Rh1j I.ì2¡»ú Z=~Gá"Ü‘²"¨tÀqFJ+%V@PgDva»Ù; Ú(X«zƒ mp[HU¨Â3J8«–ÛQ}1Ùk‚$Ò4ômÕ+lÿ ÁP± $ä8ªpVþ„Rh† n Jy8ß„6ä„}[õ=19£ c•Á´Rb…!êKùFØa@÷„œ0Ý'uŸüWûdî)GQÁK››ßÙÞyDGÙÂ9S.¯›xèir þÑ�� >ú)çËæ‡ÞøúÐdwxüí†[æÍpZ 9côÐc šXáºíâ÷þÏ—$†Þþ»™cJœGtó)�N²jCGȘé³±Þ¨½tüž÷ö5·<£Gw²ÁŽÎa˜Íð¢]ä“Áž¡dLÍS!Ë‹›[š›:‚‚i¸³äÓk>=0Œ¾¹s §a/åã½&8¶tô¶÷ Ó-aœ(´gXº°Ó7Ü/ô»!‘OE£¬J”(�Ždåu ÃN!–jhÞ Aà ®1&}[·ï ds¶ E’ý •(*1PžtFUI…+mŠ?’46O 1P8«VÚ�'C”ê5A$µ… Ù)ÐQa.²(¾„š ñ.u0¢ eiJ«Ef€!p[XqP…­!…Ä`¯Y퉫YšàRýigAÄ88˜QK-�@pGDu #ZCЇò ;ªŠ*\eSú5aN5ÄÂá¬Za‚ù“ªÇQÔRÌ$ä0€Žˆ ¸È¢ô'ÕËS‡²P”QGÙAF€Ójá·Âìd¥@kXÁ1ØkVúâjF„&¸Ô@ÄXPí�qfÔ €`¸=¢ºhÈD‚¶BkÂbª CcòT $8hŒS ³p8«–[¨@þ¸ê1B4µ…9¿VbQú“@6œ…"ŒZeŒ ¤ÔBD P[X±QmCà³Ò—P3ÂaÂ<œQ‹-�áö°šGC&´† ‡ÝFµ'®r246Oõ§A‚…Æ8Õ ‡²j™È*ÔU݈ơְ’«zE…K¬J ¤8hlžd HV­´V‚Rj "0¨5¬XIÈNöˆŠ"p¡ù»ªÈ€F;@R€‡Ój± ÜVœ4dÑ„a°Ç¨öÄUV‚Æå©o«>ÊÁ¡ŒZf €;£j¾2à íaºOê>ù¯öIF‚ß6ò’¤o��¯}ÒrÅÙ“*GÆœCøKzg{§(+�€³j˦V{W¼±S’•O÷ú.9c|žÍø=c9¹Ç—å­¼ñ,½ÓÑÝ|²ŠÈ舨2ïVeÈ Šd…+ŠxœÞUeã 0Fõ%±nÁ¥JV(&qšQð†AAqØ‘¡ç‰0B7¥eÕmÝ7¤JΓ`•LHªb†8*./.ÈÿUY‘$I~ù/”&iÔ§¸TÙL‚d*ðÅ•^Þ®ÈF�ÁŽGpE(€ÍÄÞ!XæÊ�03p2-@]1UTÀdß#8 Œqþ–àáR³˜¡Á â¤$Q{â((^£ÔÃ%Lqñ-Q‚—Á'ß'Ò"Ti<2œEÜ´C '09V:㘤€qN¾)B2˜ìâÛb#Ñ61”E \h% ¤ ![q¥+ŽA(·ð-1B”Hcq.1‹Œ f)ѨÚGpX-4Jm1\<DØx'ß—$RTa’<2”EÜ´„B 'И⢥Ž8.)`Š“oŽ‚ &¹øöÁH`”MŒ0Hˆ L¢¢Bþ8bÆe+©tÅ0�@…•?=x"š°»0˜Áb,\l9 È vR¦Q¥;Ža°Zl–Z£‡ çú’XJ€Ë-BŠG†²H>-a°ÚGIDqÓR»&,Ÿo‰¼ &åñq"+‚*«e‘`öE ‚Þ8bÂe;©tÆ1Uc|Ë!ÂX ÔØ…¡ eáb³(ÈP ØHÙˆ+=q Ô’o…åNd¬CèOaI.3 Ê"y”„[õ£Ô~xÕOÌã»âDF•V1Æ"Á,ì1J�€ž8bÄe'©tÄ1Eã|sô°ª¯¶ Á,aà"“(Ê?X ÙŒ+Ýq †@©Y8p¸0Ý'uŸüùäÄ<¶;{pî�IÀwþ~æ_×6r–ÿáׇ6ò¹¹7Í=áÚÇ7Ü€6›àÒ3'˜iâè¨sÇïf^󨇓«Ü‹çNµI‹‘¸gõçóÏšPUè8ì‘è„Nضm[&“É”í þkÈÿ3¼, Ûý¥@iU85åý“©QˆReaÛ“´ª‚Rá°„€8Àþ žG RnKP&Lª0óû¢‘GY¹æ˜”237Ä)6rœŒ 1˜‡â ¸Ú•$͘Tfæ£*¶²{"FQ*Ì\_šäe¨ÄÄ¥E4Ìb4! 7MØp±À(6Çh#*WY¹½…(•¶3IË*(5q1‹óh!ÍîÏày¤à$åÖÃ…UY¹–8 µü[aENPáÁ,t%loĈ#J…™ëÏœ•¹Œ„†XÌKó zR„‹ŒbÓ!ÂHD©´°ÝIJR¡R#°‡8‚|ÂIˆy´Ô§L¨Taá÷E "²râ4@™‰ rDZ@Š œ¨ÂY<Ÿ,¸Òq¸°QV®1jÀ ¥Ü̲+ÁÅFŽ‘ÑaóÒ<…ªÝ)ÒŠIÅ&aŒ6¢ò(+·GfæzÒ¤¨@%F.!`Q-4ð0 |iÂAˆù´t N™P©ÒÊk%\eaÛ?šÞu�� �IDAT4� ÌÄ…8,) ENVá@w‘‚”Û”“ʵFåQ®)f@!¥ÜÌ d‰¬y­ê½4O£jWŠ´`R‰YØ¥¨úÞ4)ÈP©‰KŠX„E < ƒ¾4aÇEAl‰VõºOê>ù3ødO 'SÝÏßòŸ?ÜÈç6ž{î¹k¯½6™LŽ$"¼üòË—\r‰6£úGíQ>}: ¾ÿÑéû·µk?ÃYqйö÷tÍ@&÷?™ލšíNS¼‚ÐL”ÇÂ<á¡XY…ú2”“àM˜Ü’0š1ÉMñûb&Q<4×–¤�yiv˜%b^@1¬ ÒEr¢´' V\̧ø½Q3*ŠkŽQx)ÖŸ%ÒVH3ibÉ|Šƒaµ+MÛqÁAŠ1““Ý·?fÄÕC±=iŠUЉñXˆ#<$+¨÷ 0©ù[a1‰¨šëHÒ² ÐlÅcî¥^ýYÊEò$"·}'ÌD¡Š›âšãFÈI+¤™´„²d>É!°Ú™¢m¸G ûb&*»)®)fÄ`à¥Ø¾4Å(hÅÄ4ÈnŠUÔ“¡„`ÁÅæ¸Ñ„InšoŒ DõÒ\G’–T¸€fBå ëÏRyO£rkÒ`ÁÅ|Šß;(ì@Â�A—f"!â4“•†Ì'9 V;R.æQüÞœ°¸AæËY - ˜¤€9ÂC±�€ž4í +.6Å&LʧùƘ&ŒíJÓ‚ ÐL˜Ã"<á¥Q|Y*à ˜| a´`’&ŒDŵ%i‚¼4;Äq/ YV‚ ™Or8¬¶§¾+a•=×ômÕ÷gÉŒ„ÒLRD‡YÂM±P»Ó´줸?~xÕë>©ûäÏâ“i ;tôä5òß; íG9ÂøGdúÝŒµN¡P�üËú“Tdˆ5$D¢œŠGr˜£ŠÉ¤  }Y£ gXî̘L¨`Ã¸îŒ ‚@™°†´„—Óñ0O…y²ŒJddÌÏÜD…ÔΌقñfTè̘qXqcÌÊX•æé¨@–Óñ¸H°t™�tgLvŒ3 bgÚL!’cú£ "Ådrˆ£"QAÅc¢&,%¨H_Ö˜wP˜ÙˆŠš0€2` ) ¯ ãaž ñT)•`d¬Ÿ1¸‰, )]³åÍ(ß•1c°ê!2~Ƙ•±r*äé¨@VÐñ„D °´—HCèΘlgDÅŽ´™BdÎô1F^EJ©ÄOÇ¿6ÄÑEdJRáެщ³,ufÌTt`lOÖ¤¨p!™` ) /§A–Ô„åYV:Óf3*XP¾+cF ÕCdü¬!#aåT<ÄS,§ãI‰°/‘!µë 0¡3c&ÙEd}Œ‘•±R*1ÌÓ1‘ÐJx£ É”¬Â=Y£g)Dê̘ ˆäÀØÞ¬IVá"25À’"^A'"ä©*É)¨1ºp‡•®ŒÉ„ VŒëΘ`™ƒUO¬úr*‘–p?kðR;3&+Æ›P¡#c&`9ŸÈú#ómÕÇ¢‚NÄEr¥ É´¢Â=Y“ciDêL›éƒUoU¤˜Lé>©ûäÏä“TüGãÍ?ú]Îí¡�€Š‹‹o¹åEQ��’$avD¯TN�` ’VòúFU Y�°Ä«ˆªB8,Ë*$«0 )¤Š A*ɼ‚n/r �„Ã’¬Â² £  ª ©ØQö¹ –DQTƒeU…$F AA! °Ä)Ø C TAA H% ™;J¯ êažÈH…A² €¤"9a�¨äQÂXTD=òDF"ìÈ>Va0¤ …¼„UAA  ðÑÂ$^A~‚0–$VþÙªÏ ûñª×}R÷Éãã“°(ÊJ¾Í ªêÑMúÑ{‰„ÕjÕ"Â÷Úú1™LšÍæ\Êßk,Š"ŽãªªÊ²ü裢.—ëºë®c†á-[¶œuÖYúë¾uttttŽ }ôÑœ9s2™ÌæÍ›%IBs_ † .¸@/ ãÅ\ÐÒÒRPPpØïrÀÁi*Çée¤££££s\سgOooï÷‡UUAÐËHGGGGç¸àóùìõÑÑÑÑÑùyÐCŽŽŽŽŽŽrtttttô£££££££‡_Б·Þz눗\rÉš5k¦OŸ~ÒI'ý´¼?ÿüóÝ»wç>þö·¿õz½Úö믿.Ëò¤I“>úè£K.¹�°fÍš³Î:kܸq#I¹¿¿ݺuçœsΨQ£�� _~ù%� ¬¬ìüóÏ?î…¸eË–ýû÷ç>Ο??//ïg«Ât: sN§Õjíîî6ùùù?!Á£«;W’ÿRš››?úè#m{„ gœqƲiÓ¦ÞÞÞ믿þŸÉ÷‹/¾Øµk� ººzöìÙG|ûä“OŽ=º®®îŸ?Á]»v}ñŹsæÌ©¬¬üÑ£V­ZUTTtÎ9ç—BÞ¼ys{{û¢E‹öîÝ»uëÖ+®¸‚a˜·ÞzköìÙÕÕÕÚ…� (jáÂ…�€÷Þ{¯³óàëîó›ßTTTSvO=õTUUÕÙgŸ=ãW_}Aßýîw#,É«®ºÊb±èøq§··÷wÞѪ»»»ûÝwß=ÿüóËÊʵéèèxÿý÷/¼ðÂâââãÿ”ãóùêëë£ÑhÕ!H’T__ÿé§Ÿþäûøãëëë‹‹‹µIò»Wé¬^½úùçŸ7›ÍUUUA Õ××ïÙ³g„)÷õõÕ××8p@ûøå—_Ö××Ûíö\H;¾lÚ´©¾¾>W2Aüœþ‘N§ÛÚÚTU5<Ïïß¿?“É †CËó˜ (*w.¢(Z’ÿ:|>ß 7Üà÷û«ªªP½õÖ[?ÿüó=jýúõùË_þ™|n¾ùfQÍfóm·ÝöÁa°|ùò 6—sܱcG}}½Õj­ªªjkk[¸pa4ýÑ£ÊËË=Ïñ*ç 6,_¾�ðõ×_×××G"íêniiaYöºë®Û³gOUUÕÓO?ýðÃoذáöÛo·ÛíUUU---üã‰ÄÈóZ¾|ù}÷Ý·dÉ’ÜÄóüóϯ^½z$–6›­ªªêè·s麺ºêëë;::´ÐR__ßÕÕu„Íêëëûúúþ%O9S¦L9÷Üsµxðøã¯Y³&×ä]pÁ’$±,{çwžsÎ9¹EFÂìÙ³išÖ¶¿ùæ›… .^¼X’$íã½÷Þûúë¯_wÝu�€GyäÄOÉáôéÓÿô§?Ýzë­S§Nõù|O>ùäc=ö·¿ý­ººzüøñ7ß|skk«$Isçνá†Î:ë¬É“'?öØc×]wÏçûàƒ{ì±—^ziÇŽF£qä'¢�`Þ¼y0 Ÿyæ™O>ùä³Ï>{à 7X,–L&óüóÏ˲üÁ‚ðÅ_”””œ|òɯ¾úª,Ëï¿ÿ>†a·ÜrKKK‹,ËçwÞ¢E‹pyîv»ÝápH’ÔÛÛ+Bkkk~~þððp ˜2eÊþýûKKK‹‹‹~½ÒÑ8í\ÀÒ¥Ko¸á†™3gž}öÙ<ϳ,{ûí·Ÿ{î¹›7o¾ÿþûiš†aøwÞùÛßþVZZú /„Ãá‹.º¨··wïÞ½&LøË_þBQÔHô3 ÓÝÝ=wîÜ™3g–••=õÔSÁ`0žyæ™Zé­Zµjâĉ«W¯~å•W‚(,,|öÙgµcEQ|î¹ç^ýu ÃÊËËW®\™ó¨f``à÷¿ÿýe—]vÓM7!RWW‡aØüùó�Ïó—_~ù‚ 4Ël6»`Á‚P(ÄóüÕW_=þ|íreyóæÍ{÷îyM~úé%%%k×®e櫯¾:´$Q]¼xq,»ôÒK—-[öì³Ï>ðÀÓ§O¯®®þãÿèóùA˜?þþð‡Y³fÍš5Ëãñ¼öÚk~ø¡ËåIîF£A£o2‚˜;w®¢(O?ý´Åb9á„P]·n]4­­­-))ñù|Û¶mùïö²Ùì矾cÇŽO>ù¤©©é´ÓN›9sæi§æt:ß|óÍ?þØ`0Ô××oÛ¶ �pòÉ'ßsÏ=Úo¼ñÆòåËß~ûíªªª5kÖ¬X±âïÿ{ooïwÜa0AØ´iÓ¶mÛüñI“&mÛ¶mÙ²e4M«ªºaó٬Œmmm—^z©ÉdJ¥RëׯÏí?ñħM›V\\üꫯnܸñGoŽ!6455mÙ²eÏž=étÚï÷˲¬í×®„­[·^pÁ—_~y(:¦3ùôÓO·lÙ²eË–D"qÎ9çL›6çùÞÞ^�@&“ñûý¢(jË­·Þ:’x� Âb±D£QI’8ŽK&“N§3 …Ãá•+W¾ùæ›o¾ùæÝwß]__ÿùçŸ8p ··7 ƒÁÆÆÆ¼¼¼c œZ÷Ú–-[‚ÁàG}¤uÈ<öØcÿùŸÿ¹uëÖÚÚÚsÎ9‡çùG}tÒ¤I6lذaƒßïߺuk*•ºòÊ+W­Zõú믯Y³fÙ²e>øà'Ÿ|rL¹'‰P(”N§F#†a,ËŠ¢(Š"˲eeeMMM©T꘺¹fÏž}ñÅ×××/]º´££cëÖ­]tÑ‚ š››/½ôÒóÎ;oëÖ­ƒƒƒ×]w]*•ºôÒK_xá…;î¸ãÞ{ï3gÎÿüÏÿ¼úê«Ï?ÿü³«©©yùå—·mÛV[[;<<üÞ{ï]tÑE矾ÃáØºuë•W^ùè£vwwoٲ塇Ú¸qãûï¿ÿç?ÿY;vçÎ÷ÜsÏ’%KÞyçwÞyç¯ýë3•$)Z,‚ P-**Z¹råûï¿¿qãÆÅ‹/]º4÷`}ï½÷~ôÑG[¶l¹îºën¾ùæææf¿ßÿÌ3ÏlÛ¶môèÑÇTSÛ·oß²eKWWׄ 2™Ì%ùÄO¬[·îxüñÇý~?ÇqÑhT{æØ°aÃ-·Ürçw644>ø`̘1.—käÝÅ+V¬¨ªªúæ›o´²,ïÞ½{Á‚çœsN(Ò.�€ÇãÉËË[¸pá’%Kî¾ûîóÏ?¿ººzÇŽ# l�€?ÿùÏ ………v»ýسgO Ø´iÓĉÇù矿}ûöŽŽŽ—_~ù©§žzæ™gr}¹V«U–åíÛ·'‰Ý»w›ÍfI’.¼ðÂêêê×_½¶¶ö‰'žÐš h4ú»ßýnܸqo¾ùfMMÍÓO?­†ãHccã–-[sýÀ555[·n---ýÍo~sè}ÛæÍ›«ªª¼^ïyçw|:Ö4º»»Z[[¿÷õá‡Þ¾}ûO8±o¾ù¦¡¡¡¡¡!“Éh{®ºêªªªª²¼¦M›–k f̘qD‚«V­zçw´í‡z¨¡¡!÷qçÎï¾û®vët¬]4 ápX»b~øáµk×¾ñÆf³ùá‡niiI"Ï=÷ÜÛo¿ýÓº×âñx6›¥iE{x;vìOHðñÇO&“ÿõ_ÿõ³¹øé§Ÿ¾víÚeË–Í›7ïúë¯?txìüãk¯½V]]½téÒ¯¿þúñÇ?úð÷Þ{oåÊ•?ç59qâÄgžyæ7Þ8¦£öíÛ÷æ›o¾þúëK–,q:Z‡ÛÃ?œó�€Óé\²dÉ&uòÉ'=øô£ˆ¢x÷ÝwkÛ<Ï/[¶ìŒo½õÖ×^{­¬¬lÞ¼ywÝuס"GèE›6mÊ}<õÔSsã:§Ÿ~ú5×\³~ýú¿ýío‡röÙgŸzê©K—.moo饗n¼ñƲ²²%K–¤Óé;²²2ç“$I.Y²$ßyçãÇ¿ãŽ;ô8qéèèhhhк×4:;;~øá£;ÓN:é¤\ÏñìX;ï¼óæÎ �xâ‰'Žø A±cÇŽ;öÚk¯µZ­Çtb·ÝvÛ±6î#aæÌ™5557ÝtÃ0³fÍ:âVtÔ¨QÓ§O?ï¼ó&MšÄóüqÉñÎ;ïÌmhÎwÜqÇ矾lÙ2­áG5jÔÌ™3çÌ™3eÊ”cʽ¨¨Èáp}ûö±,ûOžË¦M›vîÜY__ÿ³ù·Ïç»óÎ;,X°`Á†aî¹çž}ûö} ,Z´è”SN™:uêÑ)ÖÖÖ®Y³æX‡¸2S¦L™4iÒ±uýõ× †{ì1íÆ<//oìØ±Ï=÷œËåúøãÿÕ²ëëëÿð‡?„Ãá5kÖ<óÌ3555Ú £y÷Ýwßzë­'Ÿ|òÏþ3Ak×®½ÿþûGÒÛ¼sçÎM›6Ý}÷Ý555“&Má¾ûîEñP›­[·Þzë­W_}õãÒ�€k¯½vûöí÷ÝwßÙgŸ=kÖ, Ãî¼óNmžH}}½6T©õÞyçÝÝÝ .|ï½÷²ÙìHâ´Î™7oÞüÇ|ðÁ¹Ûq³Ù<vìØúúzš¦iTï'>åü#¬V+Aµµµ---<ð@6›=¦ÃC¡P0 ƒ¢(ÚívŽãzè¡#ž¥P5™LétúøÃÈS~ôÑG»ºº0 »é¦›r; A&LàyþÞ{ïíééñx<O<ñÄã?~ÅW¬^½úæ›o¾ùæ›§OŸ~\ª­µµÕh4ÖÖÖ–••!Çÿ‘¥&lüøñ’$Ý{ï½ÝÝÝÇzëÊó¼$I(Šk—àìÚµkáÂ… ,8ãŒ3´ª!†á`0˜Éd, Š¢V«5›Íj3åŽË¬!†a¾üòË–––`0XSSCQEQv»]Å`0xË-·œ~úéZGkYYÙ”)Sl6Ã0Ú[hq7ååå£Fºë®»´Ù‰#¡°°ð™gžyöÙg?üðÃ={öÔÖÖ~ðÁ8އB¡T*e2™rÔf³ð`0˜N§M&ÓϑNJÓé=zôž={xž·Z­^¯·¶¶ö/ùË;ï¼£¹A[[ÛÏ—F£Çñp8œL&µíŸœûI'dž™={vcc£Ýn¯©©�¬]»¶½½½¾¾> žyæ™·ÝvÛððð'Ÿ|â÷ûEñz½V«u„®588ØÛÛ;cƌٳgÏž=»´´tç·.Á�ˆD"áp¸¦¦f„ ÚÕ­à�&L˜PTT´sçÎÒÒÒ‚‚ŽãfÍšõÊ+¯<öØc'wßJ¥N:é¤7ß|óÉ'Ÿ´Ûí¹™u:ÿ ìv»Õj­­­}óÍ7Ÿ{î¹C¿úôÓOW¯^-‚Ýn?>O9v»½®®.7.TVVVWWg6›ëêꪪªî¹çžë¯¿~ñâÅ�€§žzÊápŒð´¹§K—.Õ>Þwß}›7o^²dÉäÉ“¯¼òJQ µŒÊËËW¯^ýâ‹/>ôÐC#/#›ÍvÚi§¹Ýn“ɤõB_ýõ Ã<øàƒ�€Ûo¿] -ÕÕÕ'žxbII‰Ûíž6mÚĉiÖÙ˜1cD{â‰'暪õë×ÏŸ?ñâÅ×_=†a¯¾úªV’(ŠÖÕÕi3O>ùd·Û}íµ×f³Yí—,Yrâ‰'Ž0w‚ òóóý~¿ßï�Lž<Ùjµº\.³Ù ð6Oš¢¨üüü6”F£qæÌ™»víÒ¦�nºé&ǵ*~ë­·Æ·~ýú+V,^¼øÔSO]µjÕÚµkëêêpw¹\uuuN§“¢¨ººº£o`ÿ555/½ôÒóÏ?¿cÇ�Àý÷ß?oÞ¼¹sçþþ÷¿×ò}ùå—‹ŠŠž{î¹W^yåË/¿Ü¸qã}÷ݧõÏ̘1ãé§Ÿ~íµ×>øàƒyóæ]uÕU#ÌT›’«ªêË/¿ �¸üòË-Ztß}÷i>ùÜsÏM™2åÌ3Ï7nÜÂ… A¸ùæ›�«W¯7n\]]ݘ1cŽé¢Õ.m>Eyyy]]]aaa®$kjj4·dYö7Þ¸ÿþûçÏŸ�øõ¯=nܸ›nº‰ã¸»îº �ðì³ÏN:õŒ3Î?~<�`úôé ÃÃm& ×ÕÕUWW�fÍš•r/++Ó†‘/^\RR¢MÌù$�`ݺu#Ëñx<uuu¹¨ººZ»@´9̘1CÅyóæ%“É^x!wuk“WsyUWWk"I’|á…î»ï¾eË–p «W¯Þ°aC]]]~~þªU«–/_¾ÿþ“O>ùˆvP矹%ª««Óê:wEoܸ1×οøâ‹ÍÍ͹*þõ¯a˜Ýnå•W~4qè„Nؾ};Ã0Z»œN§õ×Ñùßâ‹/¾Ø±cÇ7Þøé§ŸÎŸ?ÿí·ßþõ¯ý°žþùõë×øá‡ºKü›SRRræ™g¾øâ‹ÿÈ`ãÆ²,Ï™3góæÍ7Ýtª™ŽÎ¿góæÍ_ýu"‘¸øâ‹'L˜ð°V­Zõðÿþúëº?üÿ‡rttþ¨¬¬\¿~½6¥Åh4jãäÿ׸ä’KæÎ;ò Ù:ÿ‹ìڵ똆!ô££óïűÎùüÿ³Ù¬ÿ¨ó—±Þè¯õÔÑÑÑÑù™ÐCŽŽŽŽŽŽrtttttô££££££ó8lú@6›ù::::::?L6›=t!•ïBŽªª›6mÖËHGGGGçxñý!çí·ßÎd2Ç´BŒŽŽŽŽŽÎshXù.ä‚pá…ꥣ££££sÑ^ÛzdÈÑÉ´w$ëèüâ˜2eÊHÖ~ÕÑù_A9ßC0Ô^Ƭ…Î/=Þèè!ç—‡Ëå²X,ªªêE¡óKá›o¾ÑVÐÑÑCÎ/UUõ£ó BÅ#<–çùÁÁA½d~¹Õž×ÚÁÿ×p8G¼.þþþ^xáˆ×]wݳÏ>û«_ýꬳÎÒKóñÌ3Ï (zÍ5×��$IÒV�,Z´(//oûöíÚ* åååW^yeî¨mÛ¶}üñÇ·Þzk0Ì­_]]}É%—üíoÓVB<óÌ3O>ùäÜ!/½ôR2™Ì­y‡Ÿ|òÉÙ³g·´´ø|¾œÙ}÷Ý·wïÞ¿ÿýïÚÇ©S§Î™3ç™gž�\pÁ“'OÎU7Žã÷Üs�`íÚµû÷ï�hÕͲìòå˵n½õV‹ÅòÙgŸ}òÉ'9‘�€d2ùÈ#!R£©©é­·ÞÒ¶'Mš4wîÜ_|‘ã¸n¸Aw˜™L¦£££²²R/ŠŸvÓ©õRîÞ½ûX—ãÓÉ•áHŸr†††V®\yóÍ7ŸvÚißY£èÊ•+ÑCÎ÷òÁ<óÌ3{÷î­©©ÑB΢E‹W¬Xñè£^qÅ+V¬¸ñÆ/¼ðÂN8áÚk¯… èŠ+®��ìÝ»wÑ¢E>ŸïÚk¯õù|+W®¼çž{¦M›f·Û׬Y³lÙ²'Ÿ|²µµuÑ¢E/½ôÒäÉ“�/¿üòý÷ßïp8r!çŠ+®Ø±cGAAÁ‰'ž¨-§øì³ÏnܸñÞ{ïmiiY¹råc=VYYév»Ÿzê©GydÍš57n¼öÚk_{íµ«®ºª´´ôꫯ¾á††™>}ú]wÝõÀ„Ãá[n¹eÕªU/¾øbÿý÷ß¿|ùò«¯¾ú¶Ûn[¼xñå—_^YYù§?ý AöööíÛ·ïÚµËf³r¯¾úêY³fwÞyàÛWÏ®[·.Në!ç_ÓéܱcLJ~H’¤ªª¢(J’„ ˆªª(Šº8´¢(0 C¤µ³ÚWZ“¡­? ð,Ë��A4cI’rm A0 kûsæ–E HKSQmÙ\m§$IAh ²,k鈢¨‰Ôò‚ H–e³Ù,Š¢ ²,#¢IÒ¾6mÚž={$I’$ †aíÔ4µ†i;5KQ ‚ÐÒÏÅ‚´µ½Y–=õÔSO9å”ÊÊÊCGÅjkku_:&†‡‡€Ëå:âñG:ÖF5kÖ,�ÀóÏ?___ÿþûïç’;ï¼ó(ŠŠÇã‹-ºì²ËþÉÕàÿ=»)þû¿ÿûÙgŸµZ­’$­[·†áË.»ŒeÙL&sñÅßxãŸ}öÙ-·Üâr¹ü~ÿÖ­[Ï8ãŒ_ýêWgŸ}v.‘Gy‚ žçI’J&“½½½£G>óÌ3›šš4/O$+V¬øío»bÅŠh4zÙe—]vÙe³gÏ&¢¬¬¬²²ò7¿ù ACCC™LF«¿÷ß?‘HŒ;6÷ÓÝyóæÝ}÷ݳgÏ�hëz½õÖ[}ôц ÚÚÚn»í¶?ýéO3gΤiº¨¨èšk®Y°`‚ Û¶mK¥R‚ ìß¿ÿÄOœ5kAMMMãÆã8ÎétJ’”Ífyžß·o_EEŬY³Ö¯_/ËòŽ;úûûkjj&Ož‹Åúûûo¿ýöþþ~maï#¸üòËÛÛÛ3™Ìüùó/ºè¢³Ï>»ªªª¹¹Y–å+V,X°à’K.E1•J]rÉ%×_}nùÞÞÞ³Î:kþüùýýý[·n}÷Ýwo¼ñF�€Ïç«­­]»v­~a„îîþZk|s×î^k—!RUU’$ÇEQ… EQ5Ól´Ö\’$í’×vʲ¬-ˆîõz÷îÝ«…­¡Ï5ú‚ˆ¢¨å®íQUU‹[‚hÉjò`Ö†$IZW Â@„¢¨,ËZðÐb˜¶sÇŽZâ(ŠŠ¢¨å+˲–…&RKáÐÔ!Ñp�� �IDAT@ˆ¢(Çq¹³€aXUU·Û=~üxAý£Î±Âq\,;zÿ¼c­¡¡aíÚµŸ}ö™(Š™L&wGsÇw„B¡­[·^vÙe·ÜrËÿ—ï,èïï_ºtéÔ©Sßzë­I“&mܸñÓO?-**Ú²eËÍ7ß¼|ùòæææK/½ôŒ3ÎØºukQQÑe—]†a˜ÑhÔÜ]ƒ¦él6»téÒh4º~ýzmçW_}µnݺݻwk!çóÏ?Ÿ1c†¶ãø¹çžË²ì£>:{öìíÛ·ã8n4׬YóÄO<ùä“3fÌÈf³}}}555Úm� ±±±¼¼üÐß[%“É;wŽ7®°°Ðl6Ï™3'üõ¯=÷ÜswïÞMMÓO<ñÄÿcï»ã¢:—÷ßíXº"u%4A±Š‰ÆäZ%6ÔX°w ÖÄD£Iì"ÑØQù¢¹+Ø7‰¢"*VP”ÞaY¶×ß“{~hÊM”{æ>»§Ÿ—³ïsfæ™g~úé§ýû÷ûøøDFFæåå;v èó]»víСÃÞ½{=æëë ïÇŽ;uêƒÁprr HKK;u꜑Ïç …Â—ŽäÎ; !3fÌèÔ© æìÙ³;vìèéé¹dÉ’õë×gdd,]º4..îÑ£GÔgéã?‹Å·oßV(;v”H$ëÖ­³°°x)¶ÑöÁ ƒÁ —Ë©à¡×ëaÊf±X0Ës¹\ÀØ ¦lp;8|@€A7|ƒÁ à�_&“éíímii©Ñhà§HO/ì ¾“Éäñxè¾ rp¹\ôœt:\œ`I«Õnƒ§,€ññña±X€a°.n\7ôÃhk:ûפ¡¡¡ªª ¼àF¦R©V¬XqûöíV‘X»vmjjêâÅ‹;uê4iÒ$ðH>ÿüóGýŃèõúÅ‹WTTÄÇÇ·k×.??Fµ¸¸xõêÕ6l¨««khh˜?þæÍ› !VVV»wï†};tè°}ûö^½z<xpýúõ›7oÿ)>>¾sçÎ رc!$;;ûܹsóæÍƒ ¬¤¤äÀ6l€(ÓÖÖ6))©K—.ñññIIIÛ·oïÙ³'!dÇŽ?þøcUUü&/\¸póæÍ[·n•”” :tÔ¨QàöUUU>|833󫯾ںuëÍ›7_ú"ó_Ù!CÚ·o?wîܨ¨¨˜˜FDFFöìÙ399¾îß¿ôèÑŸ|ò ýëý‹3)Lî�!ð_†é˜Ñâñx#TÏ�P�QF£°½ &“ùäÉ“§OŸR÷_‡ÅbÁÌÎf³á\p=€1à��ÀB¸¸6jÈŽICÌ�Ô1 0MA·Ç¸ÜàÁƒwïÞ­Ñh¨i0Øl6Þ†ég¦Å çí·ß9r$!dûöíVq8œAƒ 4ˆâèèØú†ÆÚÚzæÌ™ÿú׿ÆwîÜ9½^oeeµvíÚÿû¿ÿãñx—/_þ+™={öãÇ“’’Äb1.ìß¿ÿþýW¯^}ãÆ‚‚‚ÂÂÂãÇ—””@>†ËåŽ3fìØ±°ñÿýßÿ­ZµjïÞ½ýúõƒ%‡úõ×_·nÝúàÁF£Õjþùg•JEÙµkW£TJ~~þìÙ³gÏž a7BH\\ܦM›Îœ9KœœœfΜI9xðàïÝ‹››ÛÌ™3¯_¿þÃ?|õÕW¡¡¡¡¡¡åååß|óÍ?爈ˆˆˆkkëÙ³gŸ={öûï¿÷ööþ½Oœ8qùòe ðÒöß{8›Í† æk|ý‚ÍfcªBUjµ&wpƒ0ž“;Nú�36�&“éþýû,A'ƒš1ÂÍáJL&“P(„ô à5¸5pÑ µZ-|f³Ù}ûö½qã†B¡0™LÉÉÉàfÁØl6\$Œ�àN§ãr¹4ä4©ýÍæÎÎÎ<ÏÖÖ6%%eîܹõõõ­ohŠ‹‹CCC:ôí·ßr¹\…B¡T*õz½­­­³³³­­mAA‡‡‡T*}ôè‘Z­¦‚ ZNNüz=z”››+ Û´iSZZš——' wíÚuúôéäää1cÆB¾ù曢¢¢ÌÌLp¤\\\ŠŠŠêêêÁ£G=zjßÉÉÉÉÉÉíÚµûå—_®_¿žœœ¼mÛ6BȤI“üüüÞ{q#G7A¯×?{ö,;;ûÑ£G|>¿mÛ¶ùùùJ¥’ÃáÀ1åry÷îÝçÌ™óèÑ#½^ïîînkk+‰ž={VXXhgg'‰Äb±B¡€=<<ÒÓÓƒ‚‚öïßÿäÉKKK‡ïýÔ©SÎÎÎW¯^}éðzxxhµÚDFFzzzvêÔé“O>Q*•ƒáîÝ»Îη‹Å*•j×®]ÀñËÈȘ2eÊ”)S Caa!ýëý«ï•l¶N§ÃÔ=€‹Å‚½ôt:ø:Z­¶‡� ¦=0'¯Õj~`ÒÇxdh …£Óé`-l†Á1µZ_áj©Çü�HÀ3¤ò!¯¼(p˜páÕ«WU*ÜByy9ð�T*•Z­†Ð"Þ:aô3ÓtÆrvvž<y²N§ËÍÍ…=˜F£‘Éd}ûöuuu%„Èd2‹Õ¿©TÚ«W¯Y³fUUUI$¥R¹jÕª·Þz«5 JYY™½½½££cHHȯ¿þzëÖ­ˆˆˆÏ?ÿ¼G&“éüùób±xÀ€‰$>>>=====ÝÉÉ 9奥¥ÞÞÞ½zõ‚Ï|>¶ÉÌÌœ8qb‡~ýõ×;wî 2dîܹ,‹Ãáp8¹\Îáp¢¢¢Þ}÷Ýk×®¥§§wêÔiýúõR©”Çãݽ{âëëÛ®];Ø¥²²ÒÝݽÿþðÕd2ÕÔÔôíÛ×ÓÓ3??¿{÷îÀm³·· ¹råJzzú»ï¾ ‰%++«t³uïÞ}È!W¯^MOO÷ôôŒ ‰D—.]***š1cÆûï¿?xðàŒŒŒôôtKKËï¾ûÎÛÛÛÃÃC"‘äääDEE!#¼²²2""X¹ …B¡P¼ýöÛÖÖÖÕÕÕžžžEEE¡¡¡ÁÁÁƒÎÉÉquuݲe‹F£9þ¼L&[¾|y—.]4MuuuïÞ½çÌ™sëÖ-___.—ûðáÃÙ³gK¥ÒºººôôôŠŠŠ=zÐ?àF/INNNT"J¥’J¥¹¹¹ÙÙÙZ­–ÍfCúÂe€ ÀÖÖV©T¾à+�OŒ˜³ñ]ÔHĵ�Qˆ™Û†Ÿ!xˆ…±>ô3ç†9˜úa!8pØ2Œ¡Áe ^¢g€D¼Z‘HàÄf³¹\.ŸÏ×jµÄÌ)`0þþþÔ‘ÌÍÍíÔ©ý€ýW&•Jkjj<<< ó§ÕjŸ>}zöìYFhhhZZšR©<uêÔàÁƒé‘"„ܾ}ÛÇÇMz4ZÐâââØlö¬Y³fÍš•œœLwÖøc»qãFpp0•gUSSóüùóãÇ'%%aJ séÖÖÖVVVÅÅÅ0¡cX‰Ãá€k(¯à0aD‚]˜uG„Ãá —šê1à ¿� P8c˜(BxCš�\6 €„% Üódmm­P(ÔjµÉdâóùîîîOž<áhQQQQQQÔ‘<uêÔ¸qãè쿲çÏŸçææFDDh4õ<wîÜüùóiõÚ^_ëÛ·ï AƒNž<™ŸŸOÈߌž3™Ô º&°D¡PH¥Rtz^ id6CÊÄh4»?¸8SÌ�6ày0Ð"æ$�8.ÈFC/Î1=p’˜L¦@ Ðh4°yÒHs€èQLþë_ÿÊËËËËËÓét@x1\.W­VÁ=bÈÑÚÚš~fš0ÌKÁ8†4c²eÍÝÝýÖ­[øÒ]WWGÉØï‰²0 µZh�dva• D¨!°1²1Óó;"º;§‚Ô Ôô�hafžŠZè ÀñÑÂ}Á0à R©°<� ipñ7êDäàøgΜÛûE·Éd2Á "ÂÑÏ 9-`ùùùôÃGÛdB¡P ¼ 6 |>PãQHÃ÷*L„ 6sÒ…P'àÖ Ù’ˆÀ7Ã2LHË“ ðI¨5€Y"@D5À‡ƒñ7tÂp-:Ip°1z`€:p›D¤R!ˆ¹ÄÇ`0(•JúY¢!§¹-++ËÒÒ²õI*ÐÖºíÎ;ÁÁÁh¾ú‘#•ÁÁF“Ic2ƒ˜ÿ2̯üLêk Ütù­BÅLef2F“‰A•»e0˜ ø &Óh0ˆÚ™Ï®&„AˆÜ Ì©˜‘ç·Í †™*Í`0ôpc2 &`˜L–9Éd4™XLæo/‚”Aqƒ˜LF“ îÑh4‚e2#™šàA|5b2™,–ÖÝФ5rš?¤Ó¶m[zh{ãìŲVz:çìY({$X c21˜Lˆ†AœJ¯×3(Ix$’5¢€‹Àf³“Å—Â`0° pÀ·pvvV(2™ CpÂâq¹˜ÅÁKÂЖÑhP¨ÛÄdb±Ù�Š&Bt:¥••R©ÄâVç¿ UmÀ_a0€‚TÆÜFñÖ¨LÎÛo“úA¢!§YÍÎÎî¥1 Úh{m ˆõ/.g®]ãr¹VVV:êQ°.‡o&°Ì”0`Qƒ0 &á 5q¢Ó1X,“ ò3 CÀá@à\,£±.;Ûd2U*¡P 4+Í:i‹Ãá( ±XÌf³  ƒÉh„ V¬Qe mÝÜŠ‹‹M&ÃhdÎË¢îüÇ 2ê@Ä“A8[,³Ü†ML&‡Å‚ð ÓÓ“†rh£¶?±?xC‚×|™L†ü.¨ML V±@Ö¶Ç$ —‘ß n:Cø™Ž nÉçó1-ùår¹€:†ÇãŠÀ‘1m`Cefs8@€š7PŽÆår•J%R ÛX[[Ëd2,Õjµp_…"ò2îèÍ–„œ¤¤$PQëÛ·ï!CÔjõòåËûõë:7„‹/¦¤¤¬\¹ÒÆÆæUSS³víÚAƒ¡pËëo™™™Øº†òÁܽ{÷Ù³g„aÆÆ6Ø–-[! ,€¯qqq£G Y¼x1,är¹  “˜˜øðáCl?CmMmXƒ‰14xÁÇz{Ä ŸDE2 7SÅ:‰™À“8ÊÌ�<PEÒàøÔ†ÔnràÄPû&PAÕ]\\²²²Ú¶mûäÉ”·· ÛˆFøP~}ÀÍCäCÚ ’âè¦ Å?X—œœ¼råÊ>}úÅÆÆ^¾|Y«Õ&$$ o•8nܸߓ¦š\.OHHÈÉÉyƒF'???!!!((hܸqãÆ»téthӦ͌3>|ˆx³qãÆ“'OÂWƒÁ0bĈ„„„¼¼<ƒÁ “ÉÆ7zôè»wïöë×ïóÏ?OJJ¢>ÚšÍû1™LÐ ŠN@°ŠÅbÁ›"Ư  ÊÞ€»C•*€t ¶¢Æ3 è=SYpˆCè�éõzål%#ð·ƒÁ Ü©Mb&›!5©ÏF£Q©T«ž“““«««@ €ÜV«U( C(¾÷Þ{TÅR‘Hdii I'¸kp‰€Ÿ†-þÔS¤­i!'===&&櫯¾:tè„ æÌ™3|øpB®¬¬\°`··÷Ó§O“’’úõëWZZºk×®:DFFúûû?{ö¬¼¼ü½÷Þ‹ˆˆèܹslllCCÃôéÓ !»wï¾sçΛ5FÞÞÞ!!!!!!«V­*..†n4øt&&&ÚØØøøøàöýû÷GÔ~ýúuìØqöìÙ Ã××·S§N—/_~ƒü<ÚZA®^¡P<}ú´ªªÊh4VVVÂr©TJÌJ6V‡ÆÂÂ\ ¦ax6�Z­2%J¥4Ùà¤ÂÑh4°xN&“‰¹‘Ù°¹ÅeB4qÞ.ò°±(;)€BÔÊ8::|ðÁööö®®®®®®ÇÝÝt4ÍÙ³gùàš hü ¿@­VW‚Aa:`Ô>Cú™i/§ÑS‹ŸïÝ»÷ñÇ[XX`ÈH*•.]ºtüøñ‰Äd2­X±"!!áÆ?þøãÁƒõz}ii)4M™:ujçÎ߬1JMM=pàÀ•+Wàë¶mÛ’““¿ûî;ÿÚÚÚªª*ª6]ZZ´�:thhhèÁƒcbb^T㦶fór€ �%ð$¨9z½ËV`:Fwƒr�H,sš£mÄÜEªE­P( &¦xÈÁ0 >ŸÏKåÉÈõ^zf-“QÅ�T@4ßíM¯×ÏM( …BooïöíÛGDDÀyËÊÊ®_¿Ž©&€F­V‹ØpÙ¨{ÝHÛ”ÚÆ]:Œ(ÒÖöwèýúõ ~qùÙ³gËËËe2ua`` ä9 ÞTXf2±‹F\\\bbâÎ;AµsÓ¦Mƒ B}É´´´ôôô… ‚;HATž>}úæÍ›-ZD?s´5?ä`Q$  ¡ò&ö¿Az4à € 07É|”PC&r”Á&ÌéT¨™L&o+O'Ñ™˜8ån9—°þ]p…ØÃáðù|{{{__ß®]»¶k×î£>²µµ…PJ~~~}}=är°dw¨ÈJ¦ÄÌ»£B)Þ8ìKWãµäP ¦¨ïÿ©ûÿ-$$dÒ¤I'N‰Dÿþ÷¿qcê¾øŠñÑ»ï¾ �¿aÆsçÎÀª¤¤¤k×®Brss !ÐræÔ©SPÀ¼nݺ]»v~ûí·ô£F[ ¾3$P›4ãë?!ÄÖÖ–ÒÐРR© %38„¶°›'êo6ò{¨«°öå?\gsfžÉd‚Édâ|ÃÑõÕ 6 �Ai0 ¶¶t2U*•ÐóÞh4úûû—••Ý»w¯¨¨H­VWTT ÊxZp%:ÎÒÒºÀ=*•Jè…£Ñh�PŸu~ãRÓýrZrºuë¶wïÞØØX'•J·oßþÃ?xzzBŽ=*‹ ¶Òb³Ù^^^±;vlTT”———µµuvvö½{÷öìÙsàÀOOÏ’’’™3gnÚ´ÉÂÂâ¬ÒÒR…BÑÐÐ�,>??¿çϟêÈÈHBˆD"¯·nÝêß¿ÿ’%K.]ºt÷îÝÛ·o×ÔÔtèÐ~àhk)/Pú P àDMM òÖ°Äó(Wƒk±è¢a�NÄœÝÄ.Ÿ��¨- ¹¢ßºº•²õ=©þ-sxƒ.8^(g0JKK™LfuuuXXتU« ãÂçó¡µN�Ã`0 I.öï¾@/\ÌW�nG­VƒE3ZÌË6l˜F£IKK#„lذ!22R­VOž<922²¶¶öÃ?\½z5´O¶±±9tèо}ûŽ92zôè•+WÂ755‚Q¡¡¡„ýû÷'&&~òÉ'o ÞxzzNž<¹]»vðµ{÷î:î‡~€¯sçÎÅùàƒ¨;¶iÓfòäÉÞÞÞ#FŒXºté‘#G<<<0—éääD?|´5›—ƒP2�“7ØÎ�œ!üð"%%Ô°2F­VcciLíJOh(�h÷S¹Ú ¸!ÀzLª84Jètºêêj;;»úúúÌÌÌúúz Ÿ•——£ )ú^ÀÀ¦²æ¥}5Œ¸zCÈdè¦Å ‡2zôèÑ£GãW>Ÿ¿qãÆ—nÙ¡C‡F«&OžÜh›N:½YŽ€¨†_‡:tèЗn9oÞ<êWwwwG,::š~òhkN/æeŒt¡Š¾õã >2 ¨ l_  G#f®b :(8‰cÈ«QPŽ]Æfe‚ó^’åðš©×¯R©ª««>|ˆ<¹\ލ†@p…»‚HÜ@v„#æúj³º´9^€þÉηnÝJHHøúë¯i92Úh{m |ôT0À…"Í0çÅ<p_¨ áPH‰ð{|Peª©þ|Àž¡ ¨¯\‘1™&£ÑøÉ'*oof}På ¼%85vî!„”••åçç—––VUUÕÕÕ©Õj$ ´�nÁ.àñÀuâ½#S�u ¨E¯¥Ä¶&ôrþØBCC߬ÒÎÿʪ««é.è´½A¦R©^þ#7+ â�ö7ÃVfØß0€B¡ÚKý©Ýз@’7­„Óét<ÏÙÙÄ`ý½{gg—«×éàaPÝìCŠñ=X uEÔ6XË ×Æd2y<žR©¤¶ÒáñxèBQ›Â³â¥J¥¢õ¯/ä´n+++£»´½Afkk+ _ÔkÁêN˜£µZ-ÇÃ, ª^b  X,–P(åf ‹a � ¸È¢N X¡¿‚N!dî\~|¼&r6ÇèÿŸ3b“i€ €ÆårQS�a ©Û„ÒD!Å@¡ ‰Zާ€å˜ÚÁk†Q¢Ÿ%ršÛnݺõ&rêþ+³²²z³Rk´ýƒij˜’Á ¸)H£º Ô†ÐèÍ�Uü켉$[Ssþ„Òæ�½ƒÁ@Ãd2<ȱE®ëª7™8 ñ caá8x0 …‚Z­9%#æ"V, ‚kkôú€[�Ý2ú¢!§ÌÇǧu“ÊàùâôD[ë3Ìÿ#*@(ÌDÑð‡ùåa˜L¦““SII‰J¥âóùJ¥0 ÍĬŸZ™`T±Øk\ Òµ«éûï³nÞâ~¼EΤÀ†@ �­O “™(*5�™  GÆ3â RûŠbODPj[üŒ9½ÆÌm4ä4«‰D¢ÖM_IMM=ztCCý¿nõa4ˆqi4˜Ö¹\.¦7@åÅ:]***€&0qâÄ]»v…ºz¡—€3XŽC5@èÞ½{·o«Ùlî µÞŸ=„ü›Çƒ©Ô9Q5‘E  Y€Ãá�¤ÁŽp�!�Zа�¡[þ © Ñ A¯Q)|´5…Ñ^$m´µrò|˜aY,TnÂ| Ÿ±º£[€õõõ»víBêú.0GCæÃÒÒk01È3;Rà0öuõ*§¬ŒF½° 6¦JLA5 ¾ñù|t³¡Õj:Áãñ˜L&4ÈAZ6ËÁ. (cŠ QvqZrôzý´iÓP´&77wÚ´iÔm Å´iÓŽ?Nâ_7I•J5ÍlÕÕÕàvÀ×øøxØX*•N›6íôéÓô¸ÑöÏck:ifÄ\•‚E ˜`§6Å¡òÐWÀ(j ÔÖÖb–΂®Æ ¾|ü8«°¡ÿ@Ÿ™È[’Ä}­%)k—.Rq”:ÿ‡ÉÀ¦ziÇCìăS£ˆÚÁpf¡è\NË@ŽÁ`8yòdFFücŠŠŠ~úé§ÒÒR•J¥P( tª8zôhNNŽF£I1N§P(à ›ÁrÚÀêêꢣ£=ZXXSVVöÉ'ŸÔÔÔDEEݸqcΜ9]ºt™4iÒºuëvïÞ½bÅŠAƒ=zôÁƒôÐÑö~äfgœ©1’n z'T¥Kj7ObÖù§VÌ�ù ¾�‚Ó‹ÝϘL¦åPKÎmë6‹·‡Íx°þTA3P>…¥‘¹€n˜õa±X<O­V£„Äæ=@ÈÆh]á¨ê¢´5+äðx¼ãÇïÛ·/99Y©TFEEM:ÕÏϯ[·n#GŽ ß´iHBbbb@XzË–-®®®EEEqqq={ö9rd×®]=zD2ذaönÝ Ÿ“’’Nž<)4R©¬©©qvvöôôT(ÐA•uh£íŸV;ÚÚÚÚØØÀ‹ tÀRtƒ¨�@Ê V±Ùlh@Ì"ž0•ƒòß…Œ€�[BrJ‚ŒùF^GL„YÈÄÆ„¢�^â 2èàHƒ¦öœ(‚KÂèÂÍn€ä(ÄA0M[óAÎKíîÝ»#FŒ8}úô„ ¾ùæ›ŠŠŠ—nV[[ûå—_FGGŸ>}Z§Ó­]»–eBÈ… ú÷ïO]R\\¼hÑ"KKË}ûöÑãC[ÓY@@€H$"„…B H¶£ëƒnpÚ…Uè ±X,±Xܨ§"„¼°‘ª·Qce`NNNÈxf±X˜Ì@³–(Nô(?ƒLä# Ó“1Äœ¦ÂÒQìç†I)H\Qå®Ñ�·P¼ K›¶æ†//¯Q£FÁgŸ#FŒ1B¥RÅÄÄü•·ï'NÄÄÄ4êó?k/^|ôèÑœ9sp‰J¥š9s&“ÉܰaHÇÓF[™¿¿?@NqqqEEv‹Á¼=jt‚;B.¿¤¡¡}„ð30Z…“5ÀÔ„"›€üÿ=ßL&S7BÂÍgGfÕ5ψ TÝ6j¦ÊQ_l=|n,%æŠQ¬'[ŠD"@#ô~èg¦ ÇÞÞ¾k×®_~ùeDD„‡‡GPPЊ+Ž9²lÙ²—öQÆþ}`½{÷^¶lÙ¹sçV¯‰Aóã�� �IDAT^Mraaá¡C‡† 2þ|BÈš5k"""Ôjõ·ß~ëêêJmMj©©©åååTÍ1 ¦Ax¦i¤–ax &eFS\\ l0Yãüó>"ºM¨Ï~LúÐ"0ÌËK÷Ùgj€\&“) !j‡<f¼x�$OOOð· ¢£À^ƒSˆD"è…ƒÉ!.—Ëçó™c0žÆb±ììì„B¡\.Tk”Т­¹k“&M ///?zô(!ÄÎÎŽÉd–””ˆD"GGÇ;wî ÛÎd2“’’~üñGB—Ë Éd%%%#GŽDÚÛÿ²Mš4)##C"‘@.çÓO?%„h4šû÷ïÿúë¯×®]³µµ‹Å÷ïß¿~ýº‡‡=h´½*«¯¯×h4¨~F.јäÀz@#ª¨3Ìï(»‰@U*ÞP#z²È`Æ´€ã3™L€éèhZ³Fáç§e3¥R ¤LõSU¥óòò�- PÀ gÄZN jCˆEAk¸*h:§×ë¥R)°`!äuh/§IíOJA àææŸ-ZÄáp._¾Ü«W¯5kÖ<xð`Þ¼y={ö|ûí·¡{àÖ­[%‰››4ι|ùòÔ©S.\H2š‹‹Ë¼yó|||Æ_[[{ùòeBˆ@ X²dɶmÛ.]ºtçÎÕ«W3†baa1oÞ¼nݺÑãFÛ?4Œ›Q[v¢˜&âPãK[CðpppJ¥8­cü ½¨üÇ4 ‡˜3FàâBFúMö‚Åb¢Ûo­tÌ9X©ƒ²ÐàÖP‰vTÔ)))¡ÁC¦å †k‘«†ñ:úi1È6lõëܹs_ºâJŸ>}!¾¾¾_|ñ=¸/šX,†‘ l´*"""""‚ºÄÊÊŠFÚþ¹ÛÙÙÕÖÖ"� §BÌÄÌ ÀTŽ™ìªÑh0�EÌb.åA`C¹OÄì_@ÌÙBÈûïë÷íc³Xäãu7o²°Á(º5(w xXçâñxÀ¢FÀC&70P2Çh4Μ9sûöípÙpD/¬9G ; 2)mÍX£6ÚZ=xð@*•6ò`0,†Ùx>Ÿá Ô~n×®½½=úÐŽ³s dÖ°W U¥ [$@Èt�$ee±>9âE(Jk0XÂÉf³9fV7Vü oÄ`0q/8¬=zô(•"A­æ';/€ÿ„Þm-ãåü/[YYY+~øP°¶Vo &FíˆÓ¨™&Lô ÇIõ„*++Qøâ]à^€'xèÄ`0 æqlbŽU#§¬ŒÉf³Û¶uÊÉ©3œú`Ü¥ �¸2ðÛ„²X¬û÷ï#VA²¾ÖÖÖ‚‹—ÝÐÐ�> ¶H@·X£!§Å¬¾¾¾÷Ëñõõ¥ÿÅÿ#35¸#Ò6�-ðœ«T*t}€âecc ®t:pÕ ÆE}kAE5L„@8<ôE0¼*<Ì-aØ›^cÓOÔ@­hdÊQ ÖÔî x%¨ŠI,LÛ Ð'b-ýÌÐÓÜvãÆ hµÛŠíêÕ«ÍÐ/'++«®®®Õ?0...>>>¯çµc��n&ÕqÀ$bÖ‡†6r¹£[€:666r¹œ˜‰g Ã"Jðp„ÔýD‡ÉdÒbK7,ÍA,DŸ œ„7l¼† Üu°YTä Œ)µ’”˜ÓT¨‘£×ëáÚð€tWPrZÀ‚‚‚Zw¿h Ù ‘ÃŠŠŠwÞy§u§daŽ~m™N(A6h¾ H�(Ü€Ú[6¦Š@‡4”ñù|+++¹\ŽnVû#P»D#+ ›ðù|6›…BF(úi*• ØÒ(ÄIÌ ¤¾Cž1WŒ"ì¡Ô4zWÄLZÃÜZ£–n�BôìפFÓ^nB¡Pä[Ÿ;w®ÙÚž …ÂV<’F£ñÒ¥K|>ÿµ}˜!S‚Վ؈ ¨7loƒJ˜“×ëõ*• &tN7|øpòÿw@ ê „ zƒáóù<ÏÝÝÝÑÑÑÒÒÊÎÎÎÅÅÅÚÚª2ýýý'Nœhkk‹Þ Ê0…áµ   jy¼Ö`b ± »\Ô·ÇçóQ’�®ŸJ1 '@ÚË¡íõ²üü|¨ü>}º¥¥%= ¯õ{¥¹ˆË°°Qgôf0«S0þ%ÿi&ML&SBB¦FW ƒX,...†HŠÀy---ýüüºwïÞ©Ó-¹\ZQÑ®¤¤¤²²र°pÿþýZ­ËQ‘W Ml‘KÍd2³³³!¾G »Á^p:€,<B:85�´82Í hIÈÉÍÍ]µj~}ÿý÷¥RiVVÖž={!Û¶m»ÿþ®]»Nœ8Ú„aÆÁ‹Oë¶¢¢¢¥K—N˜0d:þùgOOÏ/¿ü’ºå®]»~ýõWBÈÀÇGyøðáš5kfϞݣGê–999ß|ó !ÄÚÚzÇŽ„Í›7ß¾}ÖÆÆÆ‚V7Ø´iÓ ž¾|ùò€€€ëׯûí·„—õë×'&&ž={7^µj•——׫™L¶sçξ}ûnÚ´éñãÇpû¯ÄöïßéÒ¥¤¤$øº|ùò‚‚¸åÞ½{¿¸ýöíÛá™<}úô‘#G "ºdÉê6FÒÍÍ ËËÚ´i³eËܲÑHBV¯^ýøñcBþ»ßPƒ¹^óÁËÿ’ó0ù"® ÷F( žH*iN­VKm­†2Ò,K­VS™c@¼ …ŽŽŽ:t ñòò²µ•¢wqråÊ•›7oÖ××óx<6›]]]Íáp0b†µŸ€g@3Cm7µZ‰l‰ ‰(bfFà­áeêÀµQÓ<r¤ck-9uuu)))ß|óÍàÁƒáõdáÂ….\Ðjµß}÷ÝÎ;>¬ÕjïÞ½›––vüøñ6mÚXYYµúñš;wnFFÆ£G"## !Ož<Y²dɤI“Ìf³?ÿüs¨¹;{öìêÕ«>,—˧M›fcc“œœ|ÿþý'Ož`­R©”ËågÚ´iŒ‰‰0`ÀŒ36nܘ––VRRž„^ÀÔ©SÓÓÓSSSwïÞ=uêÔ={öDGGÇÄÄL˜0¡{÷îL&sÙ²eo¿ý¶^¯?|øðŽ; Å+NWYYÙ§OŸîÝ»¿*²õ“'O¦L™R\\ ë!+W®LHH¸}ûöáÇ?þøãóçÏ‹Å⺺:‘HÄçóu:]bbâ¦M› Ã7fÍšõÅ_tïÞ=22’ÏçÏ›7¯ººJ:d^^Þ¥K—-ZMmŽR\\¼`Á‚Q£F1FÒÆÆfûöíééé)))S¦L9yòdPPЛøÐÂ4 ƒF a«u ‚AžÐÞýu:ÝܹƱc5Z-ƒÆÁƒ¼C‡x}Á&Ðè|TW—ÛÛU*¶Fö¶¶ŽŽŽaaa=zôpvv‰DmÚ´1î´öööï¼óŽ­­í;wÄbqUUÕÍ›7¥R)�¡R©DQ8 ž aäMr¤…3àÖø|~Ã÷ #,˜L¦|‡œ»”Ë•qa_¼} Ða›|°i¼irŸûWÛØØ8;;ÃÏn||üÁƒBBB®^½ºeË–˜˜˜ŠŠŠòòò×r~ýõ×sçÎ=yò$33ó—_~ù{Ù¶mµ×€——Wzzú´iÓ ‹‹ !äƒ>1bt¨stttpp€ÏÀ~9`{öìñõõ•Éd×®][¹reee¥Édòððؾ}ûåË—çÏŸŸ““£R©¨y‚ššƒáììüÅ_¤¥¥ÙÙÙ¹¹¹•——çääp¹\777kkkggg¹\¾nݺ•+W6'ÍÞÞ>::zÞ¼y666¯ä˜^^^‰ÞoÀ\]]ù|~NNNYY|¾s环¯ï‰'!7oÞÌÏÏ…Y­V+“Élmmœœ4 è—GFFN:õÅ‘>|x§N‚‚‚rrr¨XîêêzãÆùóç—””ÀHÖ××kµÚvíÚÙØØÀç77°†ª»TÅ,m°ç@ …B¬¤db±X––ÆÕ«y}úXôík±oš4Bè œ ççGú÷×FGk%’†wÞ11™L ‹6mÚ„………„„ˆÅbWWWha€¬ÚÚZN,‹ýüü¬­­13D­ÓÄ é@Œ±FÃ{M åñü_ ˆa1èÚërÃðÛ¾T±pŒÐ{ƒƒBx< -æå€9sæùóçnnn ú¥T*׬Y3oÞ¼îÝ»BÚ·oAŒ´´´”””­[·†‡‡¿ž÷ùÓO?-_¾<""¢}ûö999AAA ÍóJìܹsóçÏ_µjÕ„ !'N„ªº?ݱ[·nK–,±¶¶†¨ÎüùóÇŒ³téÒ´´´%K–<þüâÅ‹•••[¶lyë­·p¯úúúuëÖBF%‰ÄbqIIIff&‡ÃA=ÐC‡vîܹ)S©TÞ¹sÇËËëÓO?ŠŠjÈzUæîîÎçó333‹ŠŠ<<<ø|¾‹‹Ë’%K:vì¨Óé®^½Ú¯_¿Ã‡B<<<úöí{âĉ¬¬,Ü}ÆŒŽŽŽÎÎÎFröìÙJ¥233óèÑ£ãÇmo´Ë—//X°`áÂ…3gμxñâéÓ§7nÜøðáÃVÎÁÜ>„¼^Œå/jt0óÁ`0L&2b„1(Hm4¯_ç]»Æ™&î™3å\®!"BÓ½»žòàËÛ[éï¯c³Õgç;..ööPx`2™,-™w™YÇ4ª*ö#ƒamoÝÖPSS£ÓéÊÊëjë C¥iJ¯RCgƒ~‘ž¡b8B!ÿ&‚nÆ_É×ÌÒBxßñLRUã‡P8Øm¼½F,mÚZrÜÝÝ;uê„/ƒB¡páÂ…IIIìÞ½{ûöí—.]J©ªªŠ¿råÊk 9?þøãêÕ«ûöí»ÿþÈÈÈñãÇ¿ª#_¾|966vΜ9€7�9„½{÷þé¾Ý»wðÎÎΞ7oÞàÁƒ-ZDéÕ«W¯^½!©©©cÆŒÉÏϧB—ËíÔ©Ó‘#G¦L™²yóæ“'O®Y³fÖ¬Yñññ§OŸ4h!äÀÇo"ÈQ(·oß>zôè€fÏžý·!§¨¨hñâÅð9))©‘h|jjjUUÕÒ¥K÷îÝ»|ùrxÞ–,Y2|øð°°0„œÍ›7?~üR\`3g΄F9 Bεk×-Z4a„iÓ¦BÞyç½{÷ÖÕÕQû&ö¤!æZ %Al ‚NàUTWWC‡iH{ cÄd2óóM99œ  ÀwÞ ¾sç'¹\<f6›ýð!—É4têÄ$¤"“±òòD|>ßÚÚÚÊê-ÀŸÇsf³m &!¦ªªêªª*ËãÞ’Ö;iµµµ¾"ßRY©ßïîã»Ü{\‹ •REt„˜16“ý[n†Éà1x:½ŽáÎ „!wƒÁà(9Ä\©ÓéX–ÉÁĬeÑo„ïF¶¢ŠßÀíc°‘¶–œÀÀÀþgk6{Μ9,kâĉGŽQ(“'Oާ&·_[ëÑ£‡££#ƒÁpuu}UôÇ'Nœ¸páÂ)S¦àBÌFü©Éåò††.— ±¸Å‹Ã…íØ±cÛ¶m@=�3 •••º¼qãÆÉ“'_ªPSSÃf³_UÈë¬sçÎÿd$Ûµk‡‘ƿҤD«ÕÖÔÔØØØ<xðàæÍ›„‚‚…B1gΜåË—÷íÛW¥RáÆ•••l6ûûï¿o4’½zõêܹs||<.ihhËåjµz̘1Ó§OŸ5käxd2™»»{XXXmmíý#LjÊB% 0Cª¿ ʘ°Ê\v£¿Ÿö,K"ÉÊôzýÂ… êëëFãÙ³ “‰‘–Æ·²¸»“o¿­stäž?oïââ¢×{ëõjµ¯¯¯\.ÏÎÎV(lìì<ßz«{Mݳ¢gNNNmômòêójjjo¸n0)L ƒ¥gaì‹Ãä`œt&†§a¡N£ãÔrôz=‹Ëq„ߨÞÎ&"$¤< œ»auÔPpõˆ¹« 9- 9/—Ë?>“É9räâÅ‹­­­¯_¿^SSãèèèííý:ßêµk×"##M&Sqqq}}ý“'Oºtéò©×ëe2YaaáÅ‹ !nnn;v6lÇ‹uuu½zõªR©‹Åæidûöíûâ‹/$I]]]yy9ô2ptttrr2™L/^ÌÏÏ÷öövtt,++ üì³ÏºvíúøñãÔÔÔüüü°°0‘HüðáÃÔÔT@�ùíèèh&m^UU•——'“ɨ}ùþë‡ÍnÛ¶íï­íر£••Ujjêýû÷ƒ‚‚¬¬¬233¸sçÎS§NÁ6111.\˜>}ú‡~øî»ïvìØÑÁÁ´|Þ~ûí:Œ5ªÑHz{{Ã�VWWƒ´iÓ¦¸¸8‰DR___\\|éÒ%Bˆ³³óÝ»w¿øâ‹­[·fgg4„7iTJ€ŠH6› ä ï 'q¤k™L¾RYûì·®Ž½iÓ&,#%„p8¥’¡Õ²ëëÙï¿ï(ll¬x<žJ¥ªªªÒh4íÛ·¯®®ÎÉÉa2™mÛ¶­««ãóùnnn<¯¸¸8+++;;ûÖ­[ 4Ñ?Ä$ N‡q‹¡7êYL‹ó›6†ËŒF£â[…E ƒ¡<¦d§±íôvR©ïw…v 2GÖšÔXÎÎΓ'OÖét¹¹¹TÝ-ƒaccîèèˆn‡ }K·nÝx<žÍÈ‘#KKKe2ÙG}õ:ÿê>ýôS£ÑqôèÑXXXtèÐᥗ••ÙÛÛÿÞû;ƒÁ°²² o×®ƒÁ‰D–––••••••o½õ“É ùðÃÛ·o_TTd4'L˜�©#ƒakkÛ«W/U&“éîîÞ«W/kkë6mÚÀA˜LæðáÃ]]] ØlöÔ©S»ví QÍðððQ£F †ÒÒÒ¶mÛ.]º´}ûöݺuƒß}÷Ý©S§Âa;uêò’››ø÷Râ kÿþ÷¿‡÷ïÙÓ§O}}}ÿ¢ˆƒÁðññvéÒÅÖÖöÙ³gVVVóæÍóööþ½grðàÁAAAeeeR©tøðá#FŒ€Uaaa/Žd¿~ýêêê*++}||>ûì3˜b<==á¿`ccƒÉãñ>úè#GGÇgÏž …ÂÙ³güÁ=vèÐá5TäS©TR©ôñãÇwïÞ¥vÐëõB¡¦ZöÇ~(ùL­ea2YíÚô..¬êjFiéoý¡©s7„°€mmmmkkÛ¦Mø£Z¢A¤¡¸¸X.—×ÖÖÖÕÕ]ºtéܹs¹¹¹UUU€ TÉ�Ô§i$† .ª½W›Â02Ø9l6›mÔ÷:¥=$ ©³”>HàöÁoÇÏÏÏÉÉ %3rss›Aª•™T*­©©ñðð�,×jµOŸ>={ö,#444--M©Tž:uŠÊj}våÊKKˬ¬,™LöÒ:°Û·oûøøˆD¢VìbŸ>}zôèÑ o÷êêêÌÌLBHïÞ½ÿ8¶vîܹ!C†ügèõ[;wîÃ?¤†õ^«©©yþüù‰'pE„`2™PCƒs x…;q{lX€S<À�p©‘Çd±X...mÛ¶ …ÎÎÎz½ÞÂÂÂÉÉ)((ÈÆÆ&33S©TÚØØ�!^&“—––ÖÕÕFPuƒÒQƒÁ€nàœØÛØÃÚë<¸ÔLƒ²Pˆ­BÔj5ê ó÷Õ¦£GŽŠŠ F¦è©S§ ®Ž¶¿nÏŸ?ÏÍ͈ˆÐh4VVV @³úRÀhoDæé57‡7º4òÊP=ÚÛÀTN}ÓÇÆšØw�½RH§fggÃýÀ„B!`-›b\.Z«ÕjKKKŸ~ˆÅbl\ %Ð!‚£P( äeeem³‰YëîêLuˆ¹¦ÁéÄŽ8àÛ¡Âøyè˜"ê HmMd´àÍïZQQQ+~øš³ÊD¯×ƒˆ@kõr^ó+ÄÇÉÐÀ6ÆùÔ_° õ1a_“ÉtïÞ½×bǼA’‡ÃHPçÏçóóòò˜L¦——ÇS«Õvvv ¢¢¢´´´¶¶¶´´T*•644@” ¦±ã�üŰ Õiƒ§5{€û�BÑ„Òs¼P" fÅRìaÊçóé\ 9-6)·â~9/vÂnÒI¹Ö!¯¿*¾Â£"víŸ�»ŸÁ ó/6{V©TB¡jeÐ7ïA&“±X,(ô}±¸Çh4B…8ð�„ dgaaÄѲ²2‘HTXX¯&r¹™èKQ•Ö°6vÁ!Ößð±™›Ñh„0uKpw�q©­zèÙ†œf5ooo@ðÚ¶?yU¦T*›á,]ºta0þþþ­þå5­a«M“Éx€ªÌT-K˜ QÛ‹%‰Y{˜Õ3Q�yØšÅbÉår•JU__Ïd2AÛ¶mKJJ@ì@, …B{{{•Jåéé‰Mq¤R)¦pàt:õ7á.À?¿>c1 È ßF½G0@)6„Ls#fj=ÒÓÜ–ŸŸ_XXHàj•fkkÛ³gϦ>Kvvök˜Wå&‹ÿ€ÒÖâxÓ7¤1�Q¸\.$á¡Z…J¤Æ,=•6Fí±†â1X ó>ìËãñàÈZ­V.—cŒV«-..æóù¶¶¶ËÒét"‘ÈÕÕølßoûú¨T*Ha •€t ¥Aè î{ç�A£Ñ Ì¶r@alø@ئ†œf2ƒÁÙº[´•––ºººþmÆÚ_7NõW*=ßP3™LmÚ´ym‘ƒf »Œ|0x¯ …ƒàLʘÿ@·|b¬•Áœ<b€@ °‹L&ƒŽS�cõõõ¥¥¥\.×ÚÚZ °X,Fcoon‡µµµÉdrttD �õÐ —‡<ìl[B\\\ŠŠŠ¨âÖÄÌ ¶`@Íl+‡pKÏ4ä´LÜ©¿ï\¹reôèÑÍs.£ÑØŠ“É”––öᇾ¶Wó2fnØl6¦dÐ;Áù*%W`rÇ$€5ÂÀãñ §§••x'ÕÕÕ¹mJJJôz½½½½F£‘Ëåuuuàl¡�†¼ Å‚u?èTiµZ¸¶Fh‡ñ=lý‰QDª´À-µÕöD@F5ìKÏ~4äÐFm?°†e4aƒîËÀXÃ’ŒVaÝ%Nñ8ƒÃ^° à èR™fƒˆ� ØZ¯×744Èd2KKK{{{©TÊãñ„B!Ð `cp;¨´<)ÕˆÇWø)p@„Äâ4µµµJ¥PD’4BŠ­Á]е¦}ú½·nÝ‹Å]»vŒŒìÑ£Gllì¤I“þ[šSeeedd$vÜú[µj•X,n¶l·nÝbbb0Ä$‹·oßÞD¯À'Ož‹Å?ýôS^^žŸŸ_ddd@@@ZZšJ¥úꫯÂÂÂúôéEò:tèPdddddd·nÝÄb±D"ÉÈÈð÷÷ŒŒìСÃýû÷þùgØ <<\,¿Â&iÿ­UTTˆÅâmÛ¶Á×sçΉÅbª¦Ù+±ªªª~ýúEFFvéÒe×®]ؤ§²²²W¯^cÆŒ‘J¥üqDDD÷îÝW¬XAíTQQÑ­[·ÈÈÈààà#GŽ”••EšÍÓÓsÖ¬Yµµµùùù¨øÙÚ~äâ�¾éC­>z�Ô²*lq†½s�àwŠìdj´J&“ÕÕÕÕ×׫T*¥R©Ñh`/¥R©V«jjjŠ‹‹kkkËÊÊjkkkkk P¥AI ¨sƒA0¸0 ÈZr €A€†RrÆd2AJ‰˜9ߨÌ«|àt]NKz9ƒDòGŽ™––úÄ"‘¨ªªêÊ•+ݺustt<}ú´¯¯o@@€F£9s挟ŸŸ¿¿JJŠZ­&„ôìÙS$Í™3Òª§OŸ†"""ÂÑѱ¨¨(##ƒbeeÕ¿µZ]__ßlï¡¡¡<xô葟Ÿß¥K—,,,ÄbqSœèÂ… û÷ï‡b·±cÇzyy>}:&&f̘1‰‰‰6lHHHèÓ§§§çöíÛ?ûì3ØküøñãÇW«Õ_}õÕ¥K—ìíífÍš5kÖ¬áÇGGGgeeõíÛ—²wïÞmÛ¶¹»»·ÔÄãñüýý333ËËËE"Ñ•+W\]]ííí_íYN:åãã³sçÎ;w.]º422ÒÇÇ'//ïСC………ׯ_g³Ù?ýôSvvöðáÃ{ôèO,!dÁ‚2™,==ý믿ž9sfnn®D"!„¤¥¥Mš4©cÇŽ—/_Õêæ¡ðµHè¦c taf€++«¶mÛ644Ô××+•JXŽmC‰™Í…u@È;�� �IDAT”Tâ2Àx°"i VVV³ÁZ™L¦Õj¡gqq±•••J¥âr¹•Q(r¹\£Ñ€/‚de8)J À@&È !ÇJPÑwÑh4�<�3È@al,-' kèóÑÖ¬^ÎKM­Vïܹóßÿþ÷'Ÿ|R\\<yòdh¶(“É&Ož|âĉ¤¤¤E‹•””$&&.^¼¸¨¨hòäÉgΜ9tèÐâÅ‹KJJ/^\ZZ{ìØ±’’’9sæ$''7óm¯_¿> `þüù+W®üúë¯7lØð¯ý«)Nôõ×_/[¶ >OŸ>ýùóç+W®ÌÉÉ™>}úŸî+•JããㇴeË–ÈÈÈ•+W>yò„ºï—_~öî»ï¶Ôdcc3gΜãÇçääÔÖÖnß¾}ذa¯œ»5iÒ¤o¿ývåÊ•)))ǵóçÏCeû{ï½·oß> ‹C‡õîÝû÷Ôó¨¶yóf@0cÆŒ¨¨¨}ûöA+—Vl€7º�º¼Îs8;;»qãÆ 8&b¬‹„L¦è %Q³6æZÀùÀ¢z½¾¦¦¢jZ­V¥R· *od2™¯¯oQQh¢äççWVVªT*€„·Þz hx|”6@R™Ñhäóù¨²ƒý³©q3øŠ‰"*á IrpGZ r6oÞ<xðàeË–}ðÁ½{÷f³Ù|ðAÏž=Ïž=k4W­ZuìØ±ëׯ/\¸044t̘1gΜ©­­­¯¯ßºuëÔ©Sá)'„œ8q‚ËåΙ3'>>~òäÉ"‘höìÙ7nœ3gNCCÃ… šù¶-,,V¯^ݾ}ûøøø¸¸¸÷ß¿)ÎGmÇrãÆ [[Û899ݸq#((h„ ëÖ­ƒöw/Ú‚ ÂÂÂF_Û¶m;`À�{{û7nÀ’O?ýÔÚÚ:66¶eŸ¡nݺ5jÕªU“&MêÑ£ÇG}ÔDÑ¡øùùåää(Š{÷îÕÔÔ4Ê›1cFaaá¶mÛ¨í…^j‰‰‰™™™[¶lù_ø‘óx<tÁ>Z­@¥®®îÁƒUUUm£v7€m0xK€Ž ¡*jA%DG°^G¥RÉårl�eH–deeI¥R¬UUUUTTÔÖÖJ¥RÔDÉdÔöب㉷€¾ –v¢„x’Ð@B ‡n¢sÈž êmÓÖ3kÖ¬#Gޤ¤¤ìܹ(Œ˜Îáp8aaaJ¥òÞ½{™™™û÷ï¿yóæÑ£GÃÃß?þ"÷C,‡‡‡óx¼û÷ï4(22¢pÍlz½þôéÓ?ÿü³——×òåËËÊÊ^ù)<¨ÓéüüüŠ‹‹!£póæMkkkBÎÊʲ±±Y·nÝ… ~/“••eooA3{{ûððp[[[ì} ͧ©úß-bvvvqqqPè÷ã?º¹¹5䄇‡{zzæææVWWÇÆÆ>"–*•êÉ“'cÇŽ}þüù™3g°5êØóçÏëêêþGÔöT*©` †¡àe_£Ñ¬Y³æöíÛˆ.|>°Éd¾÷Þ{@¡&„��'¨ÓÄ Ìï<O§ÓA"iz½^­VkµZµZ­T*¥Riaa¡B¡¨«««¨¨€¿¥¥¥Öƒ“ÖÔÔsV#{ƒaæÌ™ÔžÓ(;î 2¼a3b–€ ‚À0¡(ëÀœ†d<ÚZrx<ž¥¥¥¥¥åKÕ‚»wï>sæÌÅ‹kµZèµuûö휜œÄÄDww÷9sæÔÕÕ5Ú%''çØ±cOŸ>]ºtiLLŒD"A¹Öæ´ï¿ÿ~ݺu6lÈÈÈ ŽŽ~å͆ÝÝÝsss7mÚì ðÿ¨TVVž8qB*•ZXXàÂ3gÎ\½z2 ÄÜÑ’rêÔ©k×®5ÉÊÊÊ·ß~û5 ÚÀÔDÿÍŒŒ áâû©››[\\Üúõëëêê &MštæÌ™ƒb|L£Ñ;vìþýû/­¤¤äÑ£Gè…·n£ !½ó5D؈™�†2ÔrH½^ÿË/¿…Bh Œ\2$ðE� ðPR…`ü«V«5Z­†œ1¼w¢§á5>Ÿá2p›àýuûöí°åyð%˜êúà…!Y�øß˜Ä‚U�ZB¡I4*4©ýÓDYŸ>}’““«ªªàk}}}llì°aÄBáÇŒ“é„ bccW¬Xqýúõ¾}ûŽ92%%¥´´tÊ”)©©©Í <k×® óŠ+SSSÿJà¯p¢!ééé‰dÒ¤Ijµzýúõ+V¬ÈÎΞ9s¦V«MNNNNNvqqñöö0`�!déÒ¥:tݬY³àhOŸ>ýâ‹/˜——7{ölBHrrò£GÎ;÷¿ð˜644|öÙg·oßÎÎÎþè£\]]wïÞ «BCC]\\úõë—““³qãF‘HD‰ŽŽvttœ:uêâŋǎ›™™¹bÅŠ›7o~üñÇ–––—.]JIIINN¦‚}kþ‘StƨZýØ”˜¥?¡¼3:� ¢†UÈXH•2`0Ði€ÏÔ –ò KÁ1 j¿Àª¥Fm[@Ì´teàF„B¡R©D^@#Í4 Á5re�A‰i`hÈî™——.Y²d t�‹ŠŠ ƒâü.]ºxzz®X±¶yÿý÷Û´i£Óé äçç' SRRÜÝÝ]\\œœœôzý Aƒüýý­­­×¬Y“——G Äì7xÄÍ`‰‰‰–––ðÙÑÑ.²‰Î…#iooºmƒ áóù›6mAÃÉ“'ƒ Ù l{åÊ•r¹2cÆ hŽ7hÐ èØ6qâÄwß}÷õ™4W­ZÕtŒ¯~ýú>|X©T4ÈËËËÖÖWíÙ³‡ÇãY[[‡……áB'''++«””WWW777ê3)zöì™’’Òè ãØ±cÔö2CÆÌæ0wZ`�ÊÊÊJ©TbbÕɈ™CŒL6¬ä§Öè [‘4p8 ¡p¸\®V«ÅI_­Vc=&UäЈš°¡RÎÀWƒSÃÅcG,VAhBœŽÚn‡§%”žØbëLiknȱ²²êÑ£u ö™vqq¶Ê …bݺuÙÙÙ7nÄÍBCC©{áA`¢Dsppppph´M³õ"y<^“^�u$G {cûùù5Šp6Ú×ÃÃã¯$-šÍ^­ø¢ý^[Fl~úb«o±FϤ݋ÿq*bµ¾À?a–?ܘÃt Þ PÚ®†nòª-,,d2Vö@)(ÕóÀVF£Q£Ñ ªáÌN•1h›N1§aÀ‚k�jð?¨liÔ´FíNtV�©ÔÀD vEÔ„‹D„£á5 ¬TUU<xð:ØÓFm-k� £0íB"'\ –z ÊûS¹ÅDeh2@]gì > à:%¨:ƒ¤j˜úáƒF£a™  kh0ã¢R©¨PÑÈѵY5–¸"U@ãl(؃”< 6[¬…†œ¿2úî»ïZëÐܺu«÷Ë¡Öç7µ©Õê›7oÒ?¶–2jËK*NP \¨µ–à^³(ÒØ€‡‰BÝ6HÎG’ùjÊ�*ŠBâ¯ûß�‰µàà\Ør ¯ ¡…ÊœF•k @ÉÞÞ¾¦¦+а(ÉuèA< ND“¤__ÈiÝЊ›g4gW1לášß^sæjÛà a+¬ÕǶÍàÊ +€™l-H@¥cì�'ô3P²8fØèPSDÄœzþÓ€”˜ÏLj:(ØPBé;!5µZ‘:ø@m$Šê>À, }èÙ†œæ¶Ë—/·z­MódÑ~úé§VÏ=uwwmûå@óiŒ€ALøjggW]]ó;J³( ûÃÔ%¢TyMäUcv‡Íf[XX�—ò:à|ÀÁ¡›# “„~j©!§� }8µZ­P(Ž5Äß½àÖ�iPf¥Ø0ô‡<„ÂÌ&fn]—CCN X¿~ýZw‚ª¨¨H,7C¿BHTTT+V˜L¦ÒÒRggç×¶A–§ðù|µZÍçó15"•Jñ}#WÈF£¶gn¦ÃUª‚yzB�J{ƒ �9¨ Ñ1‚Bˆ‰¡'ÔÈÝÁ ¶©¦^ì )L&a+ ú¡P¡ àôHCN ü,[ëÝ]¿~½‰”L_4`.µbÈIOOûå`lŠÊŘ̹(ƒBY1™LNW[[‹´1lÄ ºN§0§# á fy*Žƒ˜„,Œ€¡"'$‡0ñƒ=~Ôj5r0ˆÁ@8,\ 1•*ƒÀFM,ÑÖtF—ÚÒF[k¯d³M&“P(´´´4™L û‚IuHÀP{²!™j\�`är¹R©„fppG Xu0ØíUÑlll¨Ù~ˆÝDQ_*"Â6”Jlƒõ¡ £¯©=¤K¨¨a7læ†,5Zðxè® -9éééÇŽk•·Ý±cDZcÇÂç’’‡&Rx4™LGŽ‘ÌÎ΋ő‘‘^^^çÏŸ—Ëå+V¬èܹsïÞ½ß{ï½ŠŠ Ü û儆†:88\¼xñ—_~yë­·"##Û·oŸ‘‘ýrzõêåàà°cÇŽ–Éòòr,Ì:s挃ƒtx…V\\ =o‚‚‚6oÞŒ>SQQQppð°aꪪ¢¢¢ÂÃûví:þ|™L†ûtìØÚíÝ»·´´ûå899Mž<¹¼¼<''G,C¥së3ð-ÔjuuuµJ¥ÝÌÛÀ :ÔÉÉ EqˆY¬L(‚£P( ÷ Lܺ‰DmÛ¶…Š�8 v£©¯¯Çày { »$`/jŒ 9rØOÚÝÝju1É„lèð†2F ã Ò¢TßÁYÝ40´Œ—aÍ”””ŠŠŠÄÄÄÄÄÄššøPPP@)--…¯ˆL‰ä‡~(..NLL,))Q(‰f{­B+,((ÈÎΆYÒÅÅ¥‰r¿'Ož<yò$Œä”)S:vì(‘Húöí;eÊ”;wîìØ±cåÊ•'Nœ¸qã*¸BÆ/‘HRRRúõë×±cGggçóçÏ/_¾\"‘tîÜyÊ”)}ûö•H$‰dÔ¨QnnnM]†ù&z÷î™™ ÿn‰DÔ®]»W{–_~ù¥W¯^‰dæÌ™_~ù%<~<Ø¿]]Á`¸{÷®³³ó‰'Ö­[wðàAj¸eË– ‰D2vìØØØX‡C·bÅ ›ððð›7oîÙ³G©T¶Ö >Ò½X,èu¼µ–ƒ!55µ¦¦–Ã*Ø ˜Ð@nü�o†Á`´mÛ¶k×®àm 5Ò­Aí�ja)1SÐéBN,'æÎl6»¨¨¨ººš -„h+å;p@ˆªq8Ðý Pè@Š‘7Ä9dCйœ–¬­]»öÛo¿Õëõ Ë—/×ëõçÏŸ_°`AQQÑÂ… Ož<©×ë?ÿüó={öœ?~þüùÏŸ?_°`Áܹs<x°råÊ={öèõúíÛ·¯]»öõ¹íÕ«WwëÖmþüù .ܺuë–-[@âì•ÛÖ­[±Á‚ ž>}ºpáÂÌÌÌ üé¾õõõ{öìyÿý÷ýýý×®]¶páÂÇS÷ݸqc—.]@Ì­EÌÚÚzÊ”))))<¨««Û·oèʼڳDGG¯_¿~áÂ…Ç3fL›6màý¦cÇŽÐ;çwÞÙ¶m›@ ؽ{÷;ï¼óW8Ùß}÷ŸÏŸ8qâ!C`ßÖú#ÇþžH†¹çn\‹ê™Ø¢ ‰dÔäU?}úôøñãÐ{ ‹.Q_€˜%pÐ/Ï(C:� Õ !|/‘H4aÂooojà ¯§F²Hg°²²Â– ÀÀF‡ªÏF(Œ Zc­å!G¯×gffNœ8ÑÓÓóìÙ³'N •H$Z­vÉ’%qqq'Nd±X.\ÈÊÊ*,,9r$4¬$„œ:uÊÃÃcâĉ...'Ož|}n[(~öÙg »wïîׯ_SœeýúõK–,Á¯)))mÛ¶7nœX,NII ™:uêêÕ«‡úÒݧOŸÞ³gÏñãÇÃW77·qãÆµk×.%%–|òÉ'666Ÿ~úiË&\ä²eËFÝga±XãÆ MKK“ÉdwïÞ­®®nô›8qbMMM\\ÜŸJíÛ·/##cçÎÿ ?rhv‰¥3 €“;2ÀƒÁ”8CõšÌÌLÌÖ`fkõ©Î Ò ˆâxÄœ³ƒ�t¡ò&rˆ™Ú�ý233KKK!¦»ƒƒ‚q<ԇƛ%f™N¥R‰¤6Ýa0�â0¢?:°ÖÂóvûömèH_YY‰ 9ާ§'~½råJdddmm-ÈV¾&¦Óé’’’.\¸<}úôgÏž½òSìÝ»×h4:99ziaaáÝ»w---CBBlmm?~leeµnݺ۷o?~ü¥Gxüø±µµ5ȧBlllBBBD"ÑãÇaI^^‡Ãi6âÙ8:qqqžžžõõõ'Ožl"r9ƒÁ quu-((¨­­7oÞСC 4\.ÏÊÊúðÃëëë/\¸àììü§G+--mhhhñVCÍfjµãW §³ ˆƒ½p°Ñ§Éd‚~Ô¼:ø.P£ƒA38LñàUèõz¡PèëëkeePÄe6›ÍçóaЉD˜@b³Ù666T‡L¯×gdd( ä�6�JaË ¤'ÀZäÚÁÂõ#îêt:•JLJSS¥Ûh¼y}!§¡¡!666::Z"‘@ L©T^ºt ¿FDDH$’eË– 6ìõ¹íìܹsëÖ­‰dÀ€&L€¼Î+4??¿ŠŠŠƒ¦¦¦ôÖ××S7(++;pà@AA•!sìØ±‹/B` ±Î÷ßß('ëÖ­²²2è¿ÐêíêÕ«‰‰‰ø•Íf‡„„<xðàÁƒ2™¬¬¬,66öçŸÞµku’=pà@ffæ‹Gƒ4Þ€^ÚªõÎÈ0¥"w�b½=TA¢®ÌÔXì‰Þ�@è­¡Â4FÌq£Û·o¿wïÞAƒáyáààÇÛÛ’Fp‘ õ‹—GUœ¢÷ó†Å:@˜Æ©¼p>Ÿ>µ%(1KÏaAµfˆ¶¦°¿_—# g̘qáÂ…šššI“&íÛ·¯sçÎ;vÜ´iÈïB-Z´cÇŽùóç_¸paéÒ¥¯ÏmoÞ¼9$$ò7 . ¼xñâ«Õ€ '„¤§§§¤¤DGG;våÊ•óÿ{ß_óýýÿº+wdJŒ„›ªÖVŸ¥ÕЦ­¦E**fQåcï””Ž •æÛ¢ÕÒ*EÍ5+ˆ!b† $7óîõûã4ÏßñŽöC›U½ç¸÷}ßï×û5Î|žsÆŒ9qâÄøñã…¿üòËÆƒ‚‚7nLÂcîܹ=öX×®]¿øâ !ÄàÁƒényyy±±±]ºt9þ<Íä–-[ÒÒÒÆ÷oئ2™lÑ¢EÇOIIyã7jÖ¬ „áþýû©_αcÇæÎK õ Aƒ‚‚‚ÆŽ;iÒ¤!C†¼ýöÛcÆŒ9yòä°aü½½ûí·Ý»wÿý÷ب6¡§` ÿ¨� /frvÏƈ»À6B2¦"33óƒ>8uê”(’ñÎÖ.—+11Ýk\.ü ðz!N3}¬oœ{‹ 7…EylØ@<‰.ðððp7/(7‘Ó´iÓ}ûöÕ¬Y³yóæ´œ³fÍ¢ÀuTTT—.]j×®=uêTÚ" 4xöÙg«T©Ò»wo³Ù|íÚµÏ?ÿœN>•T4hP…*²aÄ‹«U«¶oß>ø¯Jœ0“¾¾¾W4hP£FÔjõ|@=°½½½ëÔ©#„X·n¥8,X°€g³ŸÉaƽúê«§_ÎÂ… K¯§xûöí¿ÿþ{º?Í$¾úꫯT*•··7ÇP„„„xzzîÛ·¯ZµjÕªUÛ°a9|êÔ©£Ñh:vì¸oß>špÐO?ýDâêÑ#j€Êü¼R™$=…Úøùù‘EŽðœo¸ŒB8ÄÄ‘ÏOx02h ÃöíÛ WF‰>Ü04º«¡§ðñ“-Âë�®  „á§©ü~N—¡#’uxm¤…º©Dާ§'iýè[…&fUªT!˜‡‡,ƒ'Ÿ|rõêÕ3gÎüôÓO/]ºT½zu•JU–å#œ8ª¸´‰™ÅŠib&‹L¡)>È   Ç"ÿ’pð'ênWœ‘Ì$Ÿm ˆÜ××·øŠWØ iŸ*UªT£FË—/Ã%%Šêl¢è22c(‚oI™L&*9Èy4÷¶Qœ¥Ø€.£h I‹ÀÀÀË—/£?)òi «D$§Qw‡FN& ª ‡$\v*•ŠîìééI<<�dÐ�G5܇ÑhÔh4n©SAkÅ©_¿~¡B,^¼˜ºXºÉMn*_ÊÊÊjÒ¤ ‰(øp7Á«†fÂÃn @= E‹¢p ]L|ßËËK©TæææZ,ô2 x E}ÒÓÓñtº­Õjb,*ˆâ ¹œo°Nð"¢¨|'EŒDQqh’R¼óLÔ¶¡×ä0·ÈùLj!ÄÀ™©9r䈻_N‰Ùl>tèУ:“ŸC)•ÊŸþ6 \†«J°ø9ظ\.F’=u¦Ÿçää Ä|_t=I?¨=Cb†ÐÌ\–�ÇS|x؆-Méæ$lxl¼oËÆ¡:�  ­OîqÓ?Cä<2ät:[¶lùç!·iÓ¦ÌÞN¥RIZA?bTÁ+ÞüŒÜS$9ˆÉ’e�1Åס¡Ÿ“« •è2ÎÊañÐS(¢ßÒ5 É‚P#ª„Šj.—+ àöíÛÀÈÁ”áˆH)zò¡IZæ Ï)¡Ñ hq%U#é•7±v“[ä”)íÛ·ï‘GÐúúú¶k×® ´eË–G^s¬U«V9–zCÙ'äÑBQ�BPß6¸ËP “$ ‡½‰"äœ`ÒP-NŠ¯Ð•t[«ÕJ^/x±`ñ¯W«Õ£FЉ‰AAªÐC‚3ðÞÞÞ”úCƒDhÇd2¡É½ ! èໃwŽƒÙ´äf€n‘SÖÔ¥K—jÕª=Â^Ý«W¯Ö¯_¿lúåTäÂþ%BéééµjÕª°ýr„¼Ê o…)X·ibô<ñS­VCŒ›„ _º& EÕÐr y£p¯qO…‘È$š3g9ßãQ«Õùùùyê(AEØð/ÇÄBž Š°Ñ„PZ(½5ºk“1ç¶rÜ"§|èÑî—“˜˜X¿~ý²tì<ª3ér¹Ž?<gÅ”7<Ý=Ð 0`g€ÛòRp‘ÁŒ™�ó ®AyMQ„+C••JUXXˆr¸)•J£ÑCŠn’——‡¿!x�ìBÀbãUãx¿5üÖßß¿  €WZNv¼)7‘', sÞê¼De-¨Ní_¸ƒ$¤4YRgžÚ{HüK˜¹\N'“jI‘Fg˜VÔ½2*)Ø„›ÈåîÄ6ÌpñÙ£ÚŽØ*¤,ÓÅ”õH…ÖÉe„¸½Åbñðð@.$†AÑ3âÔH”á5â…ð¹¼T*Ìôà!óA ‹Å‚êŸmÛ¶=vìê¼QíjQÂæÏ üÐ8¸� –×ã2lUaa!€ Lô²T`›CøÜTZ»ñO´à   Ž;FDDDDD¬X±¢dœ••5lذgŸ}6,,ìõ×_¿}ûöÃÞÁf³EQ=‚‚‚bbb*Úü:Î#GŽLŸ>=((ˆŠ­òòò&OžÜ©S§—^z©{÷îׯ_¿páBË–-#""Ú¶m»téRƒÁ°téÒ¶mÛFDD´lÙòÂ… ¥=Ú‹/¶iÓ¦k×®ÔàRÿþý›7o^¾3|ðàÁÆGDD4mÚtëÖ­|{,[¶¬M›6Í›7OMM½~ýú‹/¾øâ‹/>ýôÓ&LÈËËÛºukÓ¦M#""7n|ðàÁGXäP¡\HÊ÷ôðð kf õ �ß'¡‚R4¢T€‰.rI¡ï ŠælÄÇi�$'’’’Ðt‡ì ›Á`‚N°BפC ²'‰L²·È ã(gxÑK›7SàíDÉ"ãsâ¦òq¬M˜0!22RqêÔ©O>ù¤gÏžß}÷]‹-òóó/]º$„hÙ²åSO=õý÷ß·iÓ†<]#„¯U«Ö•+W¶oß.„ðññá5†322ªU«6cÆ ›ÍöÔSOmܸqøðá5t•JEåË„«V­ºqãFhhèîÝ»‰³·hÑ¢]»vf³²_¿~z½>333++ëêÕ«µk×®\¹ò±cǼ½½Ñ®­4DÎ?þ˜œœ\ü«S§N-_¾|ÅŠO?ýtݺuW®\yá›ͶmÛ¶E‹Í™3§sçÎsæÌ™:uê¤I“6l8oÞ<^g¬4èý÷ßoß¾½Édúì³ÏÞyç.£5_�� �IDATµk×zyy9r¤oß¾>>>'Nœøí·ßh‰9-11ñرcBˆºuëvëÖ­,wðèÑ£›5k¶iÓ¦þ÷¿ÿEѹÜÜÜY³fMš4iêÔ©=öØœ9sžxâ‰ÄÄÄ .üöÛoýúõ{ùå—ÿûßÿ>ýôÓ+V¬èÑ£ÇèÑ£é="‹A­V#î^ À4™Ü0®¤êŸ° xÌ 2!ÌZšDY“t»ÝNF<¡ ÈÖä“„j`܈"4Êêp“‹ê–ònÀLÓ¨DQ±Q”ˆ ÙF?äeCÝ‚¡ÜDèÀ3fÌØ³gÏ®]»7nl0†~çαcÇ.[¶,66öùçŸoÞ¼y||ü‰'ž{î¹üqÛ¶m}ôѨQ£ªT©Ò½{÷™3g 4^lÖ¬Y³fÍ>øàƒcÇŽ=õÔS¨_ùhùòå±±±Ÿ~ú©Ýn?~ü›o¾©×ëÇŽûñÇóÍ7‡=ztBB™3g"""bbbúöí«T*'L˜]§NY³f>¬À{ÐùU*,XPñ•è_~ùåÈ‘#ëÖ­»{÷îøñã{ôèñÁôïßÿ—_~9yòäèѣnjÓ¾}û3f¬[·nÒ¤IcÆŒyöÙg«W¯>~üx§ÓÙ½{w÷Ѫ8d‹Ž¶´ooW(œ›$«E&s9B&SÈåN—KY0<C†­ÈP lL™2¹\ ²B÷)ú‰Ãá°©T$'¬2Ùï\.\.+å–Êå²"КL.w“È!†üÔ>ø=#„BÆRs<ät¹r¹ÃéèÛ&“ý>B—KÆÞ…/"\.ŒÉD‘}æt:ÍÁÁ¢ ³ÖÜ"çŠMHHhÖ¬Yƒ „III¿ýöyükÖ¬yèС%K–dddX,–‹/.X°`ãÆøì³Ï.]º´hÑ¢œœœƒNž<9<<|Ê”)‡–ôúŒŒ|â‰'Þ|óÍãÇÓ#–¾ùæ›9sæ|ñÅ]ºtY¶lYzzz÷îÝ322âââ®_¿¾k×®zõêõîÝ{óæÍ»wˆHII©S§N‹-&Ož,“Éz÷î=cÆŒƒ–’ÈùÑ… ®]»f2™Ìfsjjjzzº"$$dèСiii»v튌Œ<sæÌ¤I“‚‚‚Ö­[‡Þ¼y3%%eÊ”)7ž:uê¹sçÜ"§bò;dë×+”Jy;ç8Áå Ç †þ{>¿B!ƒ¥ˆšL&8Ä~gá¬b›ÃéT«Õv›í÷ªhN§³ç&d2•ò¢ÌStfS«Õ.!HnYm6ºÀîpÈe2»ÃAò q‡Ã¡P*eBÒL¡P(U*«Å"„ÀM„L¦öð 窃ڡ2©Cb’F”„\.÷xþyѾ½{۔ș:u*9Ö–-[&„ؾ}{½zõ222ÆO¼é¥Âš4iR¼=Ipp°ÑhÌÏÏÏÍÍý £ÏÏÏOJJ ü÷4>)%ÊÏÏ¿råJÆ §OŸ.„¨S§NjjªÉdÒjµTOžÓ}ÑYï¾ûn¥J•Ú·oìžÏ EŠ»w}22 uþwZQÈúç� ìp:eBx¨Õäž²Ùí …B¡TRâ%9ÐÐ&‡î T*I‚)d2%…OœN%Ň„€#Ëáp¸ìv¡R¹„ÐU€þÝærýîds8är¹Ìé¬Q£FNNN~~þïŠd• /™Ì©P¨d²ßNe2 ý^LÚáP/®È½†Ú92!ä …p:å …ÃI»\.Ey‡'ÝŽ5)}÷Ýw8yòä¥K—^{íµÿy}ttô¸qã>ÿüsÎŒÒÒÒvîÜùw26Ç;ï¼sôèÑÿû¿ÿ«Y³æ?hÒwîÜyíÚµ %&Ï;÷é§Ÿ&$$@àf£÷R¯_¿¾ø‡111ÿùϾüòËzõê•ï»?~üÈ‘#/¼ð‚ûxµoßžúðêd¢¨'…IP‘S°Ú¼¼ ì˜A¢¨jo`à T㉒":è›ÀÛ"HlÁ|hºxÌïÒ´ÈØ‚W�6ÞûG°šÙ\Â¡È ÁÕèófÍšŸCy»÷Rùˆœ°°°-[¶L™2%$$$""">>^¯×ß÷Jÿ#Flذ!%%åðáÃË—/ÇWæ×_ݵk—Z­n×®]×®]vv»ý³Ï>«_¿þÇLŸÔ©S§mÛ¶Ó§O7™Laaa­[·ž1cÆŒ3† ’””Tî ›AëÖ­ÛµkWbbbÏž=6lØðøã¿úê«ùùùÇ2dȹsçFŽ2räÈM›6]¸pA©TŽ1¢|‡ýøãÓr¿ôÒKüóæÍ›¿ôÒKK–,Y¹råíÛ·ÿNXî/ÐŒ3&Ož<dÈcÇŽÑïÛ·oÞ¼yaaa£GÞ¼y3á\FŽéçç·mÛ¶qãÆeggGDD<þøã3f̈‹‹2dÈùóç.\ø¨ò† þKšÑ•ݼySÅÌËËÛ·oŸ{fœl6›OñÏeÔLÞh4nÞ¼™³³Ùœ‘‘QµjUj"’›››]«V-Bfffêt:FCòF§Óݾ}Ûb±„„„èõúœœœÚµk›Íf@«T*‰C&;;›üiÞÞÞ¼¯è’Ëåº|ù2ÿÄÏÏÏn·Ò߇ãêÕ«ômHHˆÕj½uëV`` Z­¾víš¿¿¥J•®^½ªÑhx¿œãÇ7lØÐÇǧ¤RAóòò²²²jÖ¬Iù.™™™F£±N:4«˜=!ĵk×]èééi0hö”JeHHH nˆ-[¶ôéÓÕî»ÜB­V[½zõÌÌL“É|óæM“ÉäããÓ¤I“I“& 8/·ÂÓÓSÒyhÇŽ/¿ür饂:Nôõ¢ý™““£×ë±Ü|önݺe4IªT©’Íf£é+-ÐåríØ±#""¢VÐëõééémÚ´qkèKÞÞÞÄI„Û·oïÙ³gÙ”êx”ˆ ÜY­Vooï‚‚‚;vŒ3æ­FÃ=$~~~~~~ø/u¾¢¿ÑP‡%ìâAäi øËï#“Éî{g Œìn~R©Äñ‡¤3Mi¯¯/ï*†Jf•ä"ÿïŸÌ^ÉÒÿ\n!DRRÒ AƒúôéóØcùûû‡„„_î²'¹\.™¢J•*ÑžäËM$é0¤R©ÊÝ XªDëB 7|(‚¼!¿Naa¡{ÿ‚¡sŸëž7= µhÑbÉ’%ƒZ>GEE¹çÄMnrÓC‘»ÆÚÒî+¥=%îÁ©S§N:uzØ_™L¦_ýÕ½£Üä&7¹EÎ}ˆP::tx´û–ÍÛQWàÎ;?ÚÆ}jÜä&·Èù‹D`•G¾í_3t–žyæ™G¸Œ4‘Ãá¨È Ü䦊(rd2Ù#\L×Mnr“›ÜTDŽËåÚ½{·{FÜä&7¹ÉM%H^^^ÈsºÇ±Ö¢E‹r¢ÈyùÂyÏÄ Ev`BqÆíú“™q:Bí‘*àÔUð5­È'TR*¢Üãíí÷ˆOOÏ2nRd·Ûsrr<==½¼¼DùEPòó󩲡——W…jÓTPPàp8Ôjµ··7e‰VLÊÎÎÖjµZ­¶Œ'Ðb±j4Ÿ Øb+''G©Tfff:tè¾ùØåK•+WnÑ¢…N§“T\.wÊÌÌôòòª€“Á` â¤>>>á„æææRËDzgæÅ‰šºzzz"‘V °ÙleÍËË;}útÇŽEY´ïK§N v8†ŠTºüÔ©SUªT©U«–Ýn7TàšêèСU#~Àz¯%E·nݺyóf«V­\.Wœ¢Ã‡·hÑBQ»víV­ZU4ÇÓÓ“ÎÑh¬8­bǯ¿þJ…òL&SEnÖ™’’¢V«ëׯ_AXGbbbãÆ«T©Rö̼8;v¬^½z<¯Ü ê&7¹ÉMn*#r‹7¹ÉMnrSÑ_ÏËÙ¿?¬¶víÚ9r¤nݺ÷­u_6”“““˜˜øä“O^¼xQ£Ñ´nÝúÔ©Sz½¾K—.e3€;w7iÒ¤ÜõèÑ£¹¹¹Õ«WoÚ´iÅÜv&“©J•*ˆpÞ¹s‡‚1î3ù–Ûn·‡††V„Á;vÌl6wèС"ÏØ?beCW®\IKKëØ±£V«½ïwïÞMJJjÙ²eñ¾YejålÚ´ièС'ŠèîÝ»‘‘‘÷m£Rf”’’yðàÁ³gϦ¥¥ !/^<xðà2À‰'®_¿^î{èçŸ<xðÑ£G¯]»Va7zzzúÑ£GyL877×Mù×hÖ¬Y'N¬ ƒ™7oÞ˜1c*øŒ¥¥¥={Ö½s„?þøcddä;wþD<GFF&%%•§•³yóæ)S¦dgg»\®Ç{ìÛo¿}å•Wðíˆ#¨ŽýäÉ“›—B½‹/Μ9S¡R©V­Z%„X¶lYbbâ›o¾Iœ?¾råÊ›7o>räHaaallìÔ©SKv ûöíKHH˜7o^ýúõ÷ìÙó駟Ο?ŸâüBˆ)S¦»>|xhhhttt÷îÝ£££'L˜àãã3kÖ¬>úèäÉ“_|ñE‰OÎþýûÇãÆÜÜ\//¯>}úÌ›7oöìÙO?ý´B¡ ¼«®]»<xúô餙œ?>51bDÇŽÏ;7wî\!„N§+A‚L&SJJJHHHÕªUóóó=<<®^½z÷îÝ&Mš¤¤¤Ô®]›æ³d);;{äÈ‘ôwÕªU—,Yòõ×_oÞ¼Y:jÔ(!Ä€¨bBLLŒN§Ûºu«Z­Þ¹sgHHH·nÝ>ýôS!ÄÚµkKiZ.\xòäI!Dddä+¯¼rçÎÑ£GÓW_|ñ…N§[³fÍÖ­[…:txûí·ñÃ+VìܹSÑ¥KIÇ÷ô% oSBB‚¯¯ï·ß~»qãFru`œBÉ cbbŒFcxx8NÉläÈ‘5kÖlРÁúõ뱟%ƒ¤Ï£¢¢._¾œ••UöƒBœ<yráÂ…&L¨[·îˆ#zõêõꫯ6¬Q£FãÆ‹=}ú´"**꥗^º}ûöرcé‡+W®,½¦G………}úôyå•W"##óòò†NŸÇÇÇãd56nÜøÙgŸÀ¸Œ¬œgžy¦yóæžžžÃ‡¿|ùòöíÛP1bÄž={âââêÖ­ûꫯRÏ•$‡ÃÑ­[·€€€¸¸¸ÔÔÔ¾}û®Zµjþüùýû÷‡nµÿþ£GòA–ø éõú_ýõÒ¥K6›-99ùðáÃ&“iûöígÏž9sæ—_~צM›þýû§¦¦&&&;vÌd2ÑÀ Ão¿ýF<¥Ä©uëÖO?ý´bܸqÛ·oïÖ­[RRÒÿýßÿÅÇÇ¿õÖ[C† ™5kÖwß}·ÿþI“&ÅÅÅiµÚ_|1..®eË–ýúõKNN~ñŃ‚‚âââ’’’Xz"çܹs•+W>qâD^^^fff~~~AAAfffjjª¿¿ÿ‰'J£C‰ŸŸ_\\ܼy󲲲Ξ=»}ûöI“&EFFŽ3fÁ‚+V¬ˆŽŽNNNŽ‹‹«Zµê /¼=wî\‹Å÷å—_nݺ5..îÆ={ö,9ùè£âââÞzë­×^{mÁ‚ÇŽ BÄÅÅ)Š¡C‡þòË/‹/0`À¨Q£æÏŸOZ—â‡~˜1cÆÀ‡ óí·ß–Æð^zé%«Õ§Ñh† ²k×®ñãÇ÷ìÙsüøñï¾ûîçŸN—mݺuÊ”)QQQä‘#GV¬X1|øðS§N•¬kß¾}qqqÓ§O?uêTXX Òh4¾üòËä[o½µ}ûöË—/=ztÿþý÷äêÕ«÷ìÙЭ[·Ò€Éåçç<x055Õh4nß¾ýâÅ‹z½~ïÞ½W¯^]¼xñâÅ‹cbb^yå•yóæ8qâ…^°Z­ï¼óŽ¢”t¢qãÆÑ"îÚµëå—_6qqqV«•wPÛ³gÏÒ¥Ksss zôèQ¦Ž5OOOF#“Éx§¸G,KRRÒíÛ·srrJs©×ëɽh2™²³³F£ÉdªQ£ÆâÅ‹pŸ"""¢¢¢^ýõ³gÏΚ5köìÙ?þ8¶”ÕjMJJº~ýz^^ž\.ÿꫯV¯^ýã?B[ÙºuëºuëJcëhµZN'„@#¢F%''?~|ÕªUƒáüùóF£‘Ú”jµZ½^èíí——g·Ûõzý;wh†ÿ¨ßk‰PË–-©#½dŸÐç6›­4²1 E``àÚµke2ÙÆÍf³Á`ð÷÷¯\¹²Ùl6z½ž®Ñétôú&“I©TÚl6›Í¨T*K\" zæ™gÞzë-OOϵk×¶nÝ:;;›Z®Y³fÍš5Ï<óÌš5kœNgJJŠÉd¢¥¤AÆÔÔÔóçÏóÏKÜFT«Õ+V¬X¿~½Åb1 •*UªR¥ Í$]ÆgƒÑjµcÆŒIII¹o§ç¿O>>>óæÍKIIQ(¹¹¹IIIùùùz½ƒ$ótßAÖ­[7&&†Ei ²S§N#GŽ|ûí·ïÞ½KŸ >ÜÃÃcéÒ¥V«µjÕª‘‘‘GmÙ²eË–-õz}\\\tt4o©\âôé§ŸVªTÉ`0X,½^ŸŸŸŸ””„> Ž;6L­VÿÍ_òe=Iñoܸñ´iÓ<==Kiß'''÷ëׯFùùùåâíÖ­ÛO?ý´bÅŠæÍ›SÖ§äääêÕ«O›6­jÕªåÛLpîܹr¹üäÉ“cÇŽ->Î?¢¬¬¬äääAƒI¹>”ššzèС)S¦üeç@éQÏž={öìÕ±cÇ%K–H.HII3fL£FH·Ð¥K—jÔ¨1mÚ´_ë2£š5k6¬ôîß¼ys˜žÉÉÉ/¼ðu¹ý‡ÒçŸ~îܹ±cÇFEE½óÎ;܉ZªD³V ¼äAÒ^^^'N ILL,¥ -Z´˜8qbffæ¹sçè‹Åsß‹O:Un÷®]»V¯^}ÕªUO>ù¤$d%“É&Nœøä“O&&&ÆF 0àã?ž0aBïÞ½W­Z5zôhI{ÊÒ¦Ó§OŸ<y2:::::út'N¼qãFjjjéª\B¸YYYÆ «S§N)éÚ“Ö­[×»wïAƒM˜0aÿþýè±MÚÃèÑ£Ï;—˜˜øúë¯ßóÆoôêÕ+11Jt)Qll,‚:êׯ?qâD»ÝN¡¢)S¦T­¢uëÖ .\·nÓéLJJŠå>|¸wïÞÉÉÉ عsçÒ¥K›4ijPݺu'Nœèr¹N:Å??zôè?üð7oþ­ÿêÕ« !¼½½ƒƒƒU*Upp°OBBÂ+¯¼Ò¥K£Ñ8sæÌW1 ŦM›ÆߥKƒÁ°sçNµZ}áÂ…qãÆMž<yìØ±Z­¶Zµjv^²dI¯^½V¬X1þüÒX˜õë×<˜<­Bˆàà`??¿±cǦ§§wéÒÅl61¢zõêJ¥²U«V»wïnÕª•^¯7mÛ¶½¯ŠZ"äçç,“Ét:]pp°‡‡‡¢wïÞçÏŸ5jT£F>øàƒO>ùÄl6׬YSQ©R¥5j®ìíí½~ýúiÓ¦<xÐjµþôÓO¥1Hj¢S£F3gÎ4mÚÔÏÏO«ÕªT*™LF`M¥R©ÕjK£H”ÍfËÎÎ>~üxÏž=ƒ‚‚V¬X1a„iÓ¦ÉåòèèèAƒõíÛ7,,Œ6؆ <==ƒƒƒIÝ£%÷6;/Y ß¹sgdd¤Íf›={v‡~üñÇtéÒ%//oÓ¦MU«V;vìäÉ“k×®½lÙ²¥K—Z,–Úµk¿úꫤ !BCC©œG‰Ó¦M›úôéÓ¥K—üüüuëÖOž<yÖ¬Y …¢oß¾o¾ùæ™3gìvû‹/¾Hƒ”Ëåìß¿ÿ¡C‡þ†["ï rÁ‚Û·oBT©RåÏI‡¨ôzãÆÏž=ûÜsÏ]¸pA£ÑÀ}ܸq—/_Žˆˆ°Z­}úôiÔ¨ÑØ±c¼qãF“É´eË–Ò 1p…B¡Ñh‚ƒƒµZíÆ{÷îM³·víÚ›7oS“æÍ›ß¸qãÊ•+ùk$kݺõÁƒFãæÍ›_yåò*xãååUŽoNœ8Ao´Zm…*š’””Do*ÚÀ$´{÷î:x{{+Šò*xãíí]¾nÌûÒ¾}ûZ´ha0hjl(x£ÓéÌfs…*x³cÇŽ^xA§ÓY,–¿É¿}ûö±cÇžzê)£Ñؼyó˜˜ެûû„‚7(T¾tèÐ!*xS²Ì¼aÆO=õÔêÕ«êWGŽ©W¯^ݺu vìØ1fÌw‹67¹ÉM2$$$lܸ±R¥J=öXÉ™ý×’[ä¸ÉMnz”©AƒK–,¡T¹þýûWØ’œ¾øâ ^Ó-rÜä&7¹éþT¯^½zõê¹çáïPIE•ÅÐ7n”å›ð‚ôôôòò&çåå ! ÃÕ«W+ÎJçååÂh4V¨I^㜜œÌÌ̲|tnn.ýáp8*à!'—ËU*U…hdddPÍ…Š@œddd”qtð¡H¯×�Õl6W„í‡pfÙ3ó?ÌýEµ)û�líÚµ…V«µ   ¼DNåÊ•}||\.—Ñh¬P!耀�__ß 8°â‹¨T*©eH“27…‹¥NQÍš5Õjµ\.W*•°µ«ÕjBØl¶Â ÅÙ7nL+((¨È"Ç××7 Àår™L¦Š°ýªW¯®ÓéÊ‹™K(00P’Üsb—7p“›Üä&7¹éïAIïƒXËÊÊÚ»woé+Ao@óæÍ)¨|;Ô:r zyyUüí÷µyµZ­Rùï éÙl6Ò Ë}/•ÆKùúúVÜs©Raa¡ËåJNNNKK{Äö³\.ÿÏþS¹re//¯Ü5›Í’‚�RÇZppp»ví*øk¨Õj—ËeµZNgùáõzýùóçCCCe2YEöz'—ËõÓO?…‡‡Ëd2£ÑX‘ý–*]½zµ  à‰'žp¹\ÿ¬üºpá‚ËåjÔ¨‘Óé|d^êωœ4‡£uëÖ”ãüÈV«¥zƒv»½”Jç•Q^¯ àî ê&7¹ÉMn*+£Í=nr“›Ü䦊.rÇÅ‹³³³oݺŋVXºzõêÍ›7ÝKþ¨ÒíÛ·ÿûðaéÊ•+·oß.ƒ9N:Ñø$''çâÅ‹v»½øÅ7oÞ¬Èý¿O7nܨM~Ë‘nݺUKü×EN~~~›6mâãã7nÜøñÇWü|饗*~‹\7ýeš:uê³Ï>ûè½×³Ï>[âmmïK………mÚ´ùè£ðÉáÇ.\xßþ cÆŒy´®«W¯^¹rå¿ù@?¾{÷î%~Û€vøúúV®\955uÕªUýúõÛ´iS5Þxã !Dll,…÷ РAƒäädê#0nܸmÛ¶8p`ĈñññáááeVûhÍš5Ôõ k×®T wÑ¢EÏ=÷ÜÕ«W³²²&L˜PÚøöÛo/\¸µ|ùò>}ú4mÚ4--ö·——×Ô©S÷ìÙ³{÷î)S¦ddd¬^½::::00Ù¹sçùóçSqРA~~~~øa÷îÝÏŸ?_XXX62õ½÷Þ£ìË~ýú5nÜøüùóTìoĈûöí«R¥ÊÞ½{§OŸ~ùòåµk×bôÛÙ³g§¤¤¬_¿~èС˗/òÉ'=<<Ž9"„hݺuDDžòÃ?œ8qbèС ¯½öÚ(ôW¯^Í›7¿rå õ Ôh43gÎüõ×_Ïœ9c2™V®\9`À€2˜„ŒŒ jÓ+—ËçÍ›'„øþûïOœ8Ò´iSN·wï^//¯!C†ÐrÓ wìØ!„hРÁ€¾þúëk×®½úê«88ÄÜ£££5j”’’òÕW_•Í»HhíÚµ—/_ž>}ºN§«ZµªB¡ Ó-„ðññ™<yòÏ?ÿ|áÂ…ÜÜܯ¿þ:**jåÊ•iiiBˆnݺuêÔ);;›ïÉÎ;ÿÉrÇÇÇ÷èуf’Xâµ×^kÙ²e¼é¶mÛ7n¼jÕ*«Õžœœ|íÚµ–-[¾öÚk•*U²ÛíÇŽûá‡h`mÛ¶åÝ0¿ÿþûvíÚÑ€{õêµwïÞ»wïvèС{÷îf³™¶„b„ YYY+W®ìÛ·o­ZµbccŸyæ™2Ю_¿ž@‡„„ :týúõÔŒø¾ƒ¬T©ÒÞ½{wíÚ%„hÔ¨ïròóÏ?ÿòË/BˆÇ<**ªÜ¬¾l+V¬HOO8p`­ZµfÏž½víÚÙ³g¯Y³&<<<;;{À€iiiC† 1™Láááñññ‹-:xð`|||TTT||<okQÚÇiöìÙ:=ztbbâàÁƒOž<yèС9sæ¬Y³¦ ưk×®%K–|øá‡&“iÈíÉ[i�� �IDAT!iii ÈÎÎ_³fÍìÙ³ããã Õ+WâããÓÓÓ âããOœ81sæÌo¾ù&<<üÎ;ýû÷¿yóf||ü¨Q£æÍ›WmŠÓüùó?ÿüóðððüüü¦¥¥ 80???111**jÛ¶mGމ·X,/^ŒÏÈÈ0`ÀÙ³gÃÃÃ÷ïßÿöÛo§¦¦ÆÇÇ¿ñÆüñ´iÓ&MšT¿~ýÇ{lêÔ©¼WÂÞ½{—-[Ö·oßøøøaÆ}øá‡áááv»}èСiiiÑÑÑ·nÝ ÿî»ï¦M›V¯^½   •JÕ¶mÛ²ÙHQQQW¯^ ß¶mÛ¸qã¶lÙ2mÚ´† ¾óÎ;#GŽLMM]»v-Õxßµk×çŸ~êÔ©ÿþ÷¿¾¾¾:uš3gΗ_~¹mÛ¶¸¸¸ÒÁY¹rexxxNNÍê Aƒ 5‹,KyóÝw߯o¾ùfæÌ™'Nœˆ¿qãÆÀsrrÂÃÃW®\9wî܆ V­ZU«Õ¶jÕêË/¿œ3gN§N|}}ÿûßÿž:uŠ–û—_~¡=ùç˽~ýúÙ³g‡‡‡_ºt©_¿~ááá.—kذaeãµ;xð`tttçÎu:ÝÈ‘#ýüüš6m:mÚ´-[¶|ÿý÷ëÖ­KII!Õ°aÃÉ“'“Æ@ôË/¿ôïß{²^½z!!!&LØ·o߈#<~úôé^¿~=>>þòåË&“)>>þèÑ£eðj~~~áááááá?ýôÓ† 6mÚ4}úô'Ÿ|òyâĉѣGWªT©}ûö111à„¿ýöÛ˜1cªU«Ö¶mÛ™3gþýç% ˜2eJçÎõzýõë×Ï;çp8´ZmJJŠ¿¿ÿ?þ8xðà€€�‹ÅráÂúIÕªUoÞ¼9dȲ9Qׯ_×ëõ­[·nܸñõë×sssOŸ>íïï?qâIJìÙ¥Óé>üðÃÔÔTƒÁ’’R£FÐÐP¹\N]OžþynÕvïÞ½{÷î£FJIIq:4«gÏž%p³Á`øöÛo÷íÛW#/((ðññyÿý÷‡ öã?zyy?¾fÍš›7oþ£PÙš5kæÍ› T*¡[äçç_¾|yêÔ©·oßöõõõõõÍÌÌ,^)§^½zTóßl6‡††Ö©S'--Í`0PßÕÐÐP•JuöìÙ5jT®\Y©T6iÒ¤lVÐb±œ:uêÈ‘#Ë—/½}ûö;wÚ´i³zõêû†”žx≭[·¾øâ‹þþþ¹¹¹éééB§ÓÙ¦M››7oÖªUËn·ètºsçÎ †ÔÔÔZµj½ÿþûeÜײG P()))ô‰Óét:{öìIMMýî»ï&Ož\³fM???µZݨQ£ôôôÜÜܶmÛ6lØðÚµkÔ‹¤råÊS§NEwv,÷É“'·mÛÖ®];¾Ü—.] ­V­ÚéÓ§CCCëÖ­{ñâÅ2C'''·iÓ¦~ýúW®\ iÖ¬Ù;w$Á³… 6kÖ¬øþLNNÆžlÔ¨Ñã?~óæÍ¬¬¬?þxéÒ¥jµúôéÓO?ýô¢E‹ÆŒÓ²eËèèè2ð£!¼½½CCCׯ_¯V«7mÚd6›ýýýgÍšÕ±cÇŸ~ú©C‡§OŸöõõ ýþûï×®]Û¬Y³­[·¾ð þþþ999ˆcéõú7nx{{WªTI¯×gdd”¿c“‡‡ψ,((ˆ‹‹BDFF:Ž÷ßÿèÑ£7楜¾üòËRíÝô€¤R© E™=N&“ýIÊ- †ù°X, …‚*tåååaVé“Ñ£G—Y6Õ»ï¾[PPðÆotìØqĈÐÔjõ%î]»ö“O>ùÏþ“‘‘b´Ÿ~ú©¯¯/u[»vm@@@dd¤¤ö¢\._±b…¢,—æéÈ‘#¿þúëØ±cçÏŸÏU?jfUœîÞ½;sæÌÌÌLÞÞÍßߟZM+ ƒÁ€eÅÞ(û¼ìâ¡R¥JGŽÙºuëäÉ“ W¯^ý U*¯îCË}åÊ•qãÆ)•Ê ¸ B´¦âø™>}zçÎI±V(íÛ·¯Y³æ¥K—^{íµ2«³—–––ššº|ùrµZ9sæÌÐÐЮ]»~ðÁœi !nß¾=cÆŒ¬¬,ªè(¡7EFF>öØcËÊ‘¿¿BBBDD„ŸŸ_vvögŸ}‘PdŒ„vìØë Èl6S(âˆ|©‰‰‰ï¾ûîáÇ•Je¿~ýè«Ê•+'$$ôèÑ£Dj‰?,­Y³fÉ’%}ôÑsÏ=Ÿ——GŸ¯\¹’§åêõú¯¿þšþŽmÓ¦MBBBƒ î{OjÚHŠóß?fÜûQz4eÊ Z.\¸>t8Ÿ|ò ¿lÿþýÔÍ755õ‡~xóÍ7ùiçäëëKQ+???ïåË——{ö_aaá”)S<<<Þÿ}—ËÅ_ðìÙ³{öì¹ï¯¶nÝzùòeɇ‡Þ»wïäÉ“§OŸ.]ŠmÔ¨QBBuäKKK;vlÓ¦MG=jÔ(Š—”;gܸqÁÁÁT~ðàÁƒS¦Lyë­·†º{÷îÄÄD\ùõ×_Ï;7%%eÓ¦MÇ_´hQñ»9òÝwßõóó{Xé[¦"gÞ¼yV«5,,lܸqµjÕªU«ÖôéÓ¿øâ‹°°°wß}wïÞ½6l(ûÝзoßvíÚEEEÅÄÄôëׯM›6K—.=tèÐéÓ§K¯»ð}u@OOÏ/¾øbúôé 4˜?þ7ß|fµZ)¦&„8þü°aÃ’““ ÅóÏ?/„ ì@XXØøñãëÔ©Sö•‰Ÿzꩵk×:ôܹs111 4ˆ‰‰Y½zµR©$1`À€V­ZM™2a•>úhïÞ½aaaýúõ»{÷î{g»=÷Üs„$|ýõׯ]»V§Nû>tüøñ5jÔ KHH˜8qbƒ Þ{ï½ 6„……åææ¾ûî»BˆiÓ¦yzz.Y²¤l|kM›62eJlllAAÁâÅ‹_zé¥çž{nôèÑ:uÂ[Ÿ9sfÏž=ÔÒ¸yóæƒ^°`Á Aƒh¹:„»ÅÄÄТ;688¸fÍš3gÎ\¹r¥Z­&%´|uüààà±cÇ.^¼X§ÓÑPétþùç±±±­Zµêիׂ ܼysZî . 3tñåþàƒÆŒóÑGîࣥK—ž<y2,,¬cÇŽžžžÑÑÑGíÖ­[tttzzú±cÇÊ` ™™™8~üxTTÔøñãëÕ«wñâÅ>}úìß¿ÿµ×^ëܹ39sæÌV­ZµjÕjÀ€sçÎ>|ø¼yó¾úê+By´k×®oß¾3gÎ|õÕW“““5jôw<¼¬g»ví.]ºôà.‹Å¢T*].—ÓéT*•6›Ú×[­V²­V+"+ÛétR½ª_û×\(xóP½«­V«L&S©T6› OÑ SSS•JeíÚµ{÷î}éÒ%u< ¡àÍCµ@2dÈ®]»®\¹B3ÆgF&“Åð»\.þ9f•ÏöCÍ! Þü…F¿÷]V•JÕ¸qcjUK–l ºÞn·óß !ìv;=]¡PðêXv»Ýétâ­±j2cþ.(xó°M¬iòЀ“’’H4FFF’;TA/âp8ìv»L&£™)>øûΪÝn§*Ô>6¼yØ—¢+•JšI¹\n·Û=<<\.×}L“¨óçÏ{xx„„„ôèÑãîÝ»‡Æ>ÇrËårº¹(êé€å¦Y’¸èÿ'QÁ›S§Nùûû?xÁŒZ­Ælã@Ñaè}ùA+>`š%zSŠH6ü_;­(x£V«ÜäÅþä3,9hpÐlÿÑþ¤Ï‹ŸÐô?—d#j‰´((hr¹¼ÔŒ„%-[¶ìôéÓC‡½uëÙeC|6øßÿsÀ’Y-Ç™ü£ÁcÀÿsKŸºï>–|(™„?Ÿ±2 âѸâo!¹@¡P€×üÏÁãËò¥Š/ ø¾¡Ç?ÚŸqqq—/_8pà;wºwï.Y)¾ÜœóòË,ÒƒÁgMÃ-YñóYú£ _f§õ¾ûS²Ep–슸»‚Š |óÍ7F£qРAˆ—”*EEE•T‹½ E³fÍ"Çñ¿™j×®ýÞ{ï‘ÿßI‹-Z¿~½Ñh:th¹ä¹©"“[äÊ×+Ë'>óÌ3äLRþᅵªU«VÆÛ©¢‘¯¯ï¿|Üô"G.—W|ü¢L&#÷¨Ýn×ëõå8ൄå;’‡%Þx#//nß!èp8þY+ø'd4 Zî¤ÌmþìaÙýaµZÿq«Y¼µù="G£ÑVümt–„ùùùTº¦|µZ!„Íf+÷‘<,Q”Õn·_ºt©|Û•/QtƒÁð[Á?!òp<J/õ'$„ð÷÷/¨}Ũz½þ·šJ¥R‚«þÿˆµ-[¶ôêÕËm÷¹ÉMnr“›JVðܱæt:Ë%QÆMnr“›Üô“Oûöí?øT.—÷éÓçß9#›7oîׯŸL&#/°Ëå’ËåÔùU¥RY,J)€SÕår9—ËEðA—ËEá%__ßðððvíÚ­\¹211ne²‹)|B·¢Od2ýw £Ýn·ÙlZ­ÖétÒ¯5Oé6›M£ÑØl6«ÕJI�”A‰ôs¥R©R©è¿6›^‡>¡Qº�öN'Ý„~K 4$ʸ¢?hØô¹B¡ðöö¶Z­¹¹¹”g€¯èçô_Ê)!h?=Ði2iöhÀô_‡Ã$!…BA¿µÙljµš¦…~(—Ë L¡Ph4‹ÅB»Š³Mz–L&£ñЭL& ’Æo·Ûé-hl4,‚FEHSJ• 'âuœN§J¥¢45J=,Æ@·¢!…„„ètº›7ošÍæ‚‚šdÚ! …‚.Ã+Ð ±÷”J%MÖW¥R90}B¯C¯F ø‹NSJ)F£‘þÀ¶¤­N?$04½)-1½&=ˆîIÛL¡ÑhT*Uaa!Í9VœvýW.—ÓÆÆ·”×B¯L»‘v8åÿ‰¢‚oô\$Ñ�p6ÝŸþ¦¯h—šL&¥RI»ˆ^~n³Ù<<<èuèJ¬ Œ²‘°ñp艢(ÒL_ápvÈéGcƒÙívÊ ¢3BwC.͆B¡°ÙltRèé8PHôÁþAbM—V«5›Í**))©~ýúeÃ`òÃ܈µÿ/Bh{Ñrçu:þ‰•í':ÿÄkGaaáÏ?ÿ|úôé7n E\˜¶íb€ÉÓÑ¢[Ñ•´éé\átQNx ÃQDÄÎè+­V+—Ë­V+gg´ÿèÔQæ ö:݇wè¢'ÒéÊÉÉ¡gABàÌs=†ò izé´Ã†˜ìÄmñ¦TqŽî>ÂEF‚$e:«àDBNçããsûöíÂÂBb 434¥t+š|z_ð_:«.—Ëb±@„#¥ì‰f+œý9ÎÛ·o«T*ƒÁ�m�Y„$K0í”,܃¦ŽÏ¹ÅbÁÖ¥—¥í!Š‚ê´p%`[8 …Bšþëáá-GÛf ‹E#ÇÒ@P­6º /îáá!‡Õö±Jƒ§ãˆÑºp¶n³Ù ŠÑ‡jµZ©T ºý ¬™ä¢J¥¢CAw¦·€� WÀ’IÞˆ>±Ùltí j<=‘6ÖÊ ‰­R©¬V+ ›>Ç–¦+I™Ã®E‰«$¤¡ÈöÄI¨LÛ’t²¹å -sl2¨ZP$é2J̆ˆ¥%6q÷îÝ»wïrm…îæEÏÃÃÃd2áD5Ц§ ÛÒq/Àðˆ‘¥ÆGg7§3@œ‚žN?ᜈËÚ—°i8€fǧ:)2äéÌ@*“Œ¡o1HYº�êÄ =E.—Ó‹`„ļÀ¹ÀUa`á0Ó C¤¡ƒ§P(<==«T©’••E3 }&¸0Ž7q+εEQþ9Þ…Þz Ml#nᑺ Æ ‰åÆM»ÎKdÒ´è4fnOcM± $›*8D´»Ý1#Q_H¼ÑÝèoâ›8‡ƒJ*@ á·0:é¤`[b<2FØÕt% ö ö]à )l¾.Üè¤M±Í2ž´:ü°8ë 5"Š-J&“ét:>BÈ9rZð‡Ò«Ar…ƒK>¾Ö–\-ƒYC«ÏZnq·¼¡e#å–2Œ_Îå9Cá®΃èŒÑ>¦™D¬¶ ±?ÚTC°LoÎe8_ ­†3úv§V«ÅˆÑý¡z“] 2ß¾jp;¤ä‚û÷=ùÄ iˆSÀ=ÃB¡V«é¥ˆÁñc T(¨ÍCRㄘ„ŽÉe4ÏwîÜÉÏÏ7XÒå¹ï”ÆÁL/=”Î36œK4cp1AÃQIzxxîIÀ„t³€ŒÄ6× Hh‘µJ7S…{ó0™4Ûpàpi$9 4Hⳋ…ö½m$ZbHPX*X&*¸Gð© )…2Nrš< Øü8_X;º�<”›È´—øö#Ç!ìHí1>T8!¹€ÇƒDQQ(pp„`A¡UÐxxiúnIœ (\`Ð"â}á\áCáééI:å}%,3îž7…ó4·È)OÂI†’HÿÕh4Å7¨\.×h4äF£­LÇBv€dCpSŒ•B PÇp<¨Œ$¾í °Pe':H¨øDF˜B¡ Méáá!Qy("Þqh³ÙÈ·C\‰¨ÆMuº GÛ%ÜÓþæød0W4Th‹ôŠ¢Ñ'ðÌ€€±Òƒh¨<ÌF&¼”ðׯ‚‚šhëT„ ’˜&vÄ Ä$dÅK á‚§#®À„´èÄ Õj5Ün5t8^^^‹E§ÓÉd2£Ñˆ¹U©TÞÞÞ>>>·nÝ2™L<¤Õj¹ *9‹ !q„ÒîŦy@Ô�;§ƒ«çpb#P‡¶ŒE¨>äzâ’Üé ‘HZ_ܶ%” zS<_Ñö#Ég6›iHz‘§—ĉ+ØÊ$a/â•aa;Q’˜z#Ú‡ÐThHf³™fŽS8HEQµ4xÃ\.ÕEäÊ] }Žä èpÆíX+g+:2¬Wâãàþص.—ËËËËÓÓóúõë”΂ ¼(j7B|Ÿ;ĸ{;7°WàL MÉC´ÿ`ÈC·‚"³†kF¤öÂYD7äf ¯&‰Ïiû‚#Ø�©Ã 6Ûò83Í!énÄg%�¼Ý Ö¸ þÀ[áIàw@¼þòŒó—‚†(:Ä7`¢¡Ê!ä"M (Toz.qÒ4¹ë~QÄ!ðšB³ÙLL+=µk×®]»öÁƒ f†¿ ÜP<VËÈ—ðMH}î]„qC“@,6(výœ–¸ËH$#>Ä5yÁ ¡EÑuîRƒÃêÞ'…ïÀ%àîCJ0eZAN,÷(`aè“VË Òn·ï&]û n.øQ‹ûÉ!�HG©ê)¬"úÜ`0 ¸'|°°ÏœE¯‰@®ïî9åjîÅ–q¼Á­°9Hyq8ùùùf³Þ�QhcÑæFp›z/p¼ÓÂáX°ˆénÐkà8‚Å€_á´ÃçK¬úäwÝ=ÇØ7üèbãqX—` \–ƒ•CžvCÈm ~1^#ç‘3xöøÛqQ Äb×äý�g§Çá”"bç 9#Àö*aŽ4ÛPÕæÁ>ÅÃãFaHdÛ+2ÅétšÍæëׯ ªyÁ‹¸cB8V @GT„€ÛŠièE°Ùè'û–vé °i`Òë@ñ¢+=Ã$cö0óô¾@Óá[P¹Ì&vŒÿrÀ!º�eÀ÷0Ù7ä` C‡‡gp1] eåÊ•u:ݵk× ]!d‚ãÉ=ê°Þ°(<ôHÊy\IÓ…¡aRã°#îå&˜0;\ºENy¡X6Ú©œEBºÂþ€ªÎ1T$*T*•Ùl†=N[ –>‚0èôòØ8[˜_„w”Ëåd‰Ó®2™LtnþÇÉÃàÄÈ™N×hµZ0°oÚÐ`šøŠRr¹%±Ï¸¿ g7ð}qƒC¢*‚-â)€ðI"¤áX"$À3Y«Õò+d|t¤=Ö q[ôlÅ€}“+õ#Ó¬rÜm3²x�_¦!‘#"™À)¤"€/#x`7B/ÐrûÄ#Oˆ±qÞ¶…(ù`0ÐKè·˜jbvÏ4<p@˜Ä •J%YTxâ°\pJ4 ¾ßà¼âVÌ…BA&5P Ö /ƒÄÕߪÕj//¯ÀÀÀk×®eeeá[Xä´ú$®øBÀ‹Å•È ®Kñè F‚W“ˆag’‘ñ‡’$3ÀÇžŠ•*>Œ²Ãj¹…MñmÇ{èJ PP@ÀÀn_¡` ,zð :�Bšœ¼8Q«ÕîL¬ž:„R¶å€Q«ÕŠ,í0òç’5æááAŸÓÐÚá0 ‹7$6 õkôÜÐf uÅQ8àù%à¡¼Õ W´9)Îqˆ(F%9º“j4ðçè#˜#ZÆI<æÄW™¾µZ­ƒV„«ÀäÒÀì•î/ñ‚¹sôdàÑ� nd6›±ßÀ19æ‚«í’Ð1ÍqdÉÌC†:ß)g÷ôj�ò»µ†$Jqü:­b'Xb’‚ØÄÜ)Äȵ~Ž–„˜™#Œ#54 ‡ãpÑÔ2‡µ0ÁÁÁ]»v €ùîééIl]¡PäææfffÒOHFr_+t v˜ÖLóL3‰ô þÊ‹Å`0àPs•—~EKFû+û' ãÝVNY# ûp_ǹR k &4IV\± þA{‹ráX‡Ûþ(‰KÚ4¼FÜè!)…©‚êG:,ÛHzÅ1@à”ƒ8l»–Ž=¹àIÈ!ÚDÖ ]/z‚Iñì0èÎ`t1y‹…UÄkä"ˆºœwK@G<Nƒ=�Œ;ñÞ&ŽgÝòyàÛx¬3i2™hÎá5…:Ï¡Ü5Å*Ž!¤Û’¤„„�ÚžËodqwÌD‹ÅBÑ5(<l-‚´îCƒ…u^œ+(p|ÑœP�ƒã,8 ØìjCž& ; ˜ãPpãK ëŸ&„ý+IG¥¥¦¦fddäääàsÊ ÃIÇ~“x&åÇÞƒø›»—û]¹†p2œü´hq(,÷(àq`8<S¬ì[ »EΚ8Ø%PTy#&‹ÅBÊ5°°Xùž£mA‡Š+,|ë KŽ»‰è¸zxxðn’à `¾�ãð[ññ�øÀÕ.I ’¤ O¶/nX`äì€ë)ùŸ8OMçy$Ø\"498·dÒAÚñ ÁˆŠ‘R©R©¨@d6Ì&ðt `1!œËóÉ|œ ‚‡$$öüfÐ(yXÿ’®M:jC G(V™¶–Â6ô,S £›wÀ}!ÌŽí‡g‘Á‡ �I€©ƒÙv¦F ÛÞ$®MsŒ8) 9.³±9áJò÷÷÷öö¾sçNAAi6w#ŠÒ`á”ÃþŠÄ´ЉâXñ,l6š™üüü‚‚n£@#ÄIä¹b2ÑçLR³pÒ¡9¡– ¨?¨\è×ÉÏ·±Ê|¹yšO�zÛíX+7Âæ@™˜´ØÈ"$ÆA¬‡çOÀéAÿ’ÍË!"PC¸<€fÊyœ(êI,Áæ“x 'œ é)Øg(+€—"Æ*‰è8à犇Iy²…ŽL§^&oH^¯,$W+¿‡‡E¤ðÊÐyy D>÷�ì€Â3Ü¥`6›ÉKIvî¯ãyò$HÞàh´›Ór{{{ûúúG&/ øXü“tÎaì"‡"¼˜/Wà…!á×<-œÁ†Ðâ<—Ä'lââ&ª @߆Ã8ðF�ŒL à:­)ìNÒÏĽ,` KyæááѱcÇÈÈÈZµjÑÛ÷ÁâE8Xö4ü“€J’•L»”c±Ï%^œGë‚ý… 2ì0ì1ø38ôŸnHG�[“ «ËèOP¼h®`Ðsdñ Áļч¤š¸áåÂZÁµZ?$@ç…: =Pj¼âÚt$È@ Ö=âöÄ.i— ²�`H`‘´ÅQGKR½ wF,&òð ¼Ë­p1TfCôR"A¡ÎÓù´X,py!}²b›ÛðLòl$üC„Ûív£ÑH2~'—ËEhQè¶<e(xã"Ç<¸³Ž¸”h ÐÒ ?‰f€¦>hßÜ2£?hÂiT¼`i† – Ï1i“ÐSÀ˜ º V– iUÐß¹P‡1 {¢Ýe4aÂò$°Hº’;` ¢’KX,òsBÙ"•œœ€Ï]œœœ‘‘qçÎÚöpü"ØN2`I}?‰†Œ.«ÞFly]Ž�� �IDATã±Z­[Å&„‹Nd:ã˜�Ã!|õ°Õð¦t1ewâ<ªÕj¸þ¸×ÀK„‘ù€´º9ü¤WAC:Sù¶r‹ÁÑ(òÈ«<UÌK6ÍU<IeC®*"ª!ŠJC‚íÞ·æÇ"ó‚·€s†êTB:òJ-ÅUW¨½ÜëÅŠ´QÚÓÜù(Ð0Èè¶jµšâŸ€ºÒaCD³ $Áùè`C<s?�Ô1•ÅA¥¯È¨ÏE î, |@§†bÇ&ñ_ž- ñ(GÄÂ]ÆK{ÑÞ�FræG:p+_t|âs)Âä–Ï+ p¡Å#¼(â”`”(MÄË©w‡ ÉÔ{…§ –_“$°j³Ù®^½šžž„ p]Jl¨}TMŠÆIû/‚÷åfL ^VŠ„4^Lr‹Ågv ¯âqˆòœP RÃZ½\”“ †eúîk®uñ„I6ž;´B¸×xU>lt!ÄGf³–VK9,e›ÍápV«×¨Õ­ îíE˜G°BL¼f3x.ÏòãÁm ¬�LÇjµ"á~xóx^*Ïdä*âÃ`7< bê!Ï›á¥!%jÁË$ÉGp„U¡ÂAÄCÓ‚Õà¾>^ 0_IÉ/Ž™æ. ¨HÞÄe Ìã„ûàž.n~Áôá(X î$ä0 XKðbq¯/¬dømx}3j°*ûá9@X>!�³aÚaÐÀ…(ñù¨Õꀀ�…BA¨-ÁJ^ÒR¢^ŽDÞð¼4L/™8ô.&“‰Ö…RxyÔ¾ä(8dΰ�ÂE¦§§§Åb!™„Ùãº? ›‡Ù‘8ÁgªtP Ÿdî£ã&oqIæ ûrÔ«$ê‰ÓwÖƒ‹(Ü1`ž‡ä9å ¬:mÁÖNç›:N._h4>f³¹„X¦Pü¤R ît®eI!ÈÀ€ p I‚$RxéL®] •‡cNx‚Üzœ ÁYÓ…X÷_qÜćt#. Våsˆ¦ (ÜÀ¯Ä¬B·ÅàáØ¤›�±ÊN¼‚¯ÆÊG Á-Ä`õB(^æ&X$]Cõ}i´4-Èãá!ì%.8†O•ã°mh)dEœ—'óõâ‡ÃÎÁÌð„A^`_½ƒÿ ˜F lcOOÏçŸ>((èÛo¿½qã/äJò†leŠ€¢‚2ÊKcÿ+Šˆc½x}RbîT[º UÎF¸KR,Ên·SØ_%Þ,@"„ô3îBŒHKIf ·1Ϥä‘v¨R©¼¼¼òòòฦˆ)ogÀW׾†¤»Ñ€V�2®x^RKaI_Q61âs’(—Ëç9僖x*$i"—«‘É4Óéìçåu^©´ÛíoY,›Æ—==V+)’P*ŒYnÉBµä†-E³yZ;4kI¾$…ò­IZïð‚NˆmJ°Cüx cƒ*úPJ2À%=ièæÔ€á B-ä¢ú'X$W±¨_ 3‘Þ'dðð2/!ƒ¸°Xƒ‘ÿXÒQIД’Æ0¡�r…Æ@lšîO ¹Å«’ðý.6ÍËÞPÌœWƒ¡IÏÓ÷ΠȆÉd÷æKJžÈ±¼’}쌤´3q´3gΤ§§ëõzÌ�àÂ5Ü“LRÌÑP€÷z× ÅÓxï.àiE8pN‚<À‡ %’‚дë�.Õh4”óÎI~Þ¡\b¨¯Ê­yzŠF£ÁŒñþRèS‡ƒ¡Qó»þxwq5šk3’ä6·È)ç¤~¨xLXáïrÕ–ÉFh45šªþþF£ñÓ‚»ÓÙ«(é„` )së˜KˆâÙ,÷ sGO˜ ]¼7êá‰÷æl’$àÞÜ–—‡Bí ÎìP¸*’¤; ¿“𣤏·Ûþ°œ x|Îkmñàh|ÀäºÄºÀ ÁõeÔÖƒ·Già©0ÜÂãu8ÖƒƒVù±:„ã@| Ö¬ Ž”¥’ |Š{àUƒ8Ç¿¼HªI:Mp§ €Y²Z­gΜã`~X“‘ŠâdœoB”Rw8$iâ'80[¹n!—˵Z-ÙÔ#‡ÃÉxc: Ä‹p·'\ˆ�‰ðü^µ–·ç!©L&/É!Á*ûÁÂ÷6’@«!^i›×ÂAe„Ã×á†xFÜuøÌ9‹ãòÆÝ/§BH  y•IÚU…h,D‚Oë–-Ÿ}öÙóçÏïÙ³ç3‡#;?ÿë¢XVr¹¼råʤøFªÁÍOOO!%±£\w!æ 7B \‹¦j@k’†žü„?P*q\©V1Üú¨ýŽ#ø�Çs(3að‚Á’Æe¼› xH®Ò£ÁjÁb$™ƒ8±4Z`x=l^“˜×ÃZé>`.’âÊH-äè‚Â$`y°'ó)cáþˆµàí ¤¿"Ž·ú¼%âðÐN$JOêäZ6-ªÜzÏ'òˆ!Ýýüüt:]~~>üÕN§3''V 1\�LDQÏ1ƒÁ@–«¤-D#|D4’Úµk?þøã'NœHKKƒRÅSÖ8îSþšd_úøøxƒ;`=Ѐ9Ê`QnSÆ=…'ÜðLgÈ?ªÏ›¸ÃS†ùYæi³\°ñú¿\Éà%sÀ$%!Ü"§Ü¤Ž(ÊÒâQh¨Š!!!½zõ mذaFFFnn®L¹BA p"OOÏêÕ«Ëåò›7o’ƒ…ëÂ>>>ÁÁÁ5kÖÌÍͽ~ý:¥7C¯!œãÚó6ºtCTŒçz(çó#'ÉñDqY Ÿ±Î”TNC˜D’‡N3âÞ~IH™ƒÑy$“›H.áÇå÷y:I¦·¤%TW^^ŸS§,!u€æCò?J‰pœ1XýAŽ5̯‹[›eâÞú§ôjKÆÓÚ!}%¥Zá´!óH­V«Tª¼¼<øš ð¬C2=Žý$]ìȯþÎݼ¼@� (ôBw#öªÓé¨ãª¿¿íÚµ³²²2339ªÍËËËh4æççÓyáøI^Ò´xÀp‰_�ž«V«u:6/8Æ·%Á=ù-X=ÌI´d¨H<ÒP¼8‚™×°0äüZReü>C^d^SÞ®Zül(CÀs3¸j‚œ'Æ êqo¼[ä”3‚€çrØ¥Ýn7 ‘åtzdfž;w®J•*/^ÌÊÊjf·'å@pWÉdºy󦧧'*yÛ*H“•••——g±X²³³ …²ŒƒÍ10¤a™ÍfÞš^Ü›ÅÉ“B¸¼ä¡HxÛy;8týáÿâ8rqo–>GˆÁ5Á;‰q¿¢MéæeÇàôã,U»¢ŸðÊ+p‹Ñ�¨q ÂQôʼu ÏÚ  ¨ Z8sl.jŒ’‘ÄÑ}ôúúðÖ,(äÊÍ)äù“îÌ àCÅæöoÐB¯´P–#zF§2Ž7ã…¼¯9™2(8„ 7ÈX‚š ¯Z3AF£Ñht:Z­öôô„þáëë«P(NŸ>]XXHa'*¹æãããëë›———““ƒš˜|~Íá <2ÊC;Bˆäää+W®¬âPo”%Ôh4>>>O<ñ„^¯ONN–ô¯#öºpˆ&bz%= 9& ¶#·Y¡Bê„—$àÖ†Z­6›Í¼ê¼R©¤§cέl6[aa¡§§'š9q'9÷ãñ¼ ŽAE÷/IxÕ-rÊAÀ;@ól’ërù1™lÆíÛïnÜxìØ±»wï6¾qãÃüü~:]³™—¢¢µÌÊÊ*,,„æ+1ÏïܹË�òî΀3AB4ÞÞ¹HàMa$!þ 5>Dty‹IFî:àw†qÃëb©qO:RdpðPbQ„÷¡þãü ê�ÝÊ>Gmf Ô˜Û|ÂÛ°aÀ€€ììl”æä^>èÄ6TcÄRB%çõc$a î{Ï{K󰽯ߌ*8¢X‡r’ßø–ƒ¸è·€Õ¡ëëÙŒ-$©†ý@Uލ@äÊ£U ôFº˜ûàÎZ­¶fÍšžžž™™™&“IbÚbÆÔjµF£1Ä»y¾·›ÍfsqÛˆÏ0½KNNNNNO¢`./Õ N�­¸·¼Ϻóðð0žÆ{Öq!s„·EçèyÞ\Ò{žW D¸ e¹ñEä8Ph˜7¥vÇr* h÷ÈA'árR(ì.×ééUoÜp8§d²™õÞô@®Yp-žwæGIÛ.°?Áòö9 ¶sñÒè¤ó4þj<¿R«ÖŒòh¼¾äJIù&ˆ ð2 í=Àш³óv2p(äÀ燃| <ß}VP,’ÇK$Š!‡!HJÛ¿téÒ7¨k* #z/L;´‚µN€æ+XB+ªÞ‘¢"M ]Æ‹;4xþ9I_8Óë}Ûãz ¬X¾µ¸ñ$)Ñϳô±]!þQZø þ7î´¤÷õõõõõõõññÑëõdÑxȽF®6èC4ÛTHT«ÕjµÚêÕ«ß¹sG¯×Kâj$š4iÒ²eËK—.>|¸°°ã¾Ä½õ!)9º oAm›/\¸ é‰�­‹»×8#æ˜ø·a…S´Œ‹yž—Æ#1Pé šð²­<åŽC98– ׈A ""© wŸ`­Û0<Ú´TRA”_¨[äü¦ 6Ê™;$¿kL&!“9!„Me²|™ÌÃåúµ(ZÎ3+‘?LØJ°à1dI1f²6xŠ"íoÔ„§›N#/„ 0>²Üig#ÞN<ås |¡w¯··7µßàYÀh÷Ëd°3‡Ã¡Óéxsb°f°?Tà°h¬ÈC…ÁÄ5Gr…Á¦AÖ ózÌP*q2!ZÌfóÅ‹ylŸç¸@LJzˆ†nN"ŠzñTð}±hZ¨ÔRèy cÚlhÑÄ%$Úè ½Õ”ãÞ<¤nð’hF@g B¶¤”'4�8N“È-…BáçççïïÏ•¨|™`=“È›JSA»—æ\¯×k4//¯ªU«Z,–ÂÂBxüÐëý™gžyúé§=š––& •A“@á^‡7k§·ƒàç Âé'Võ’wc*îOæ ;Þ‹{H">]\ñJÒüsBôqq³OÒ#ä n˜ò:X¸›(J¹uçåTˆXŽ:Õñ„'A©T6Õéìv;BÖs'ƒ‚9áà2d«ÐÖçAèbÜž –DŽrî%@Â|,eƒCÁ) `Ô‹{‹Fà\y‹k”<釃D¹m$O ‘�V “HR‡ŠÃÉrâÕˆ³ ›�Ç ‘S…sR y¢ PÜÓˆRfÀãÀcÜõÿ$ïLKÀKúÓñ"Ä¡X‚m@a€h‘ ãùøáRƒ @õ¸Dî‘(V§ °C¾€‡Ç-iÔ€ø÷õõ­R¥ŠR©.ŽÔgÚñóó«R¥Š§§§Óé¤FgÈT¥4 &00ðÖ­[ÔÜBÂb±?~¼°°ðÌ™3wïÞ…qV¼Þv†ï@A*ßi\·ãµPíŠ#l Áúû!ÓN\…â7hya$ü D”’¬&^òÝÂ-Z8!h ‚4¥¿ ‰*º¸ENùˆp4p+dGÓy@`“QŸå1yn§óbï’DEI¡-^hÈWžÙƒGp«Ÿg{q_ ¯Æ&ŠòO% ç¤òpUˆçœÓ<ÆD…{¨$¨hî–1Á«°À)éæ�4T9ø—ÈTa!NAËÄ åâØ—ðÿ�öÃCؤò¤*p|0o �.�Ï*üT Ç)úÁ­pÞ œ·©…ÿ ~xí°PiÀTדƒT| 7§ø6F VH�²2I‹¢i§iñöö®U«Vpp°Ñh ,,,$L¤DÙ=Ööóóã èÎÉÉÉ©©©ùùùˆKq‘Ãõ}ÿ±‘84ƒç¸HJ1ÁGÍ3 µ O–G³è+”4¨šï4�:¸uÂmЄ8ÜÚùxM´i@±jîYáè¼v”E¬¬ŸŸŸOnnnyõ/p‹œ{Òpb ïãããííM¡fŽwä 1âµA+çI$¼²‹¸·ß(?EÜ<‡{Š«ZÔ»W’ÔÉKì€áÃ'Ò*96Š-òÖUÜ{ÃÓøy]g.ny†,‚8�Ü!³J7ǧÇÁ<Š.íá rÁÌÜ�wét:¸³áìywN ¼‚[¨\6@]@ÿ((\!�Ò>RžÛ„Ro¼Ä–¤Öí+ ø¾Ë&§(­>ÏÃçý(9Þ7‘Tn÷V¼Öét^^^T„9 L­V“qL©i!!!ééé999¼B!9‰! ÂjµÚœœÞLb</@ÊúÑqÓy oj��^Ì!é‚‘‚ŠÆ;l¢2…`¿yI'<58 l ÍVc‰Ã̸%Š‹)]rN° ¿|W“¼—ÔKåÝ+�¥‡úùùÕ¨Qƒ§œ»ENùÈâ}\‘§­ƒÞåP°ÂYܰàå ¡ï Ö€×ð‡Ç–—Âänx{€ö!¯zñ²¡¼=ö"g='¤™„[qì?ïKzËK‚‰{ëöcÇKL"°'.t‘»ÎK4":…¯HÞKà×’öÒ<‹m¸-…º,VA8ñòÒŸ!M>OsáÈ ÎMˆ¨PWEâ±kÁõyÒ/ö»Ž~‰;;Œ .&زd¸`q¹ àS‡Ò/("Ž�ô :Ø ’jÐú{^¼ø¼^¯Ôju;vhfÏ– Ñ×l¶Ùív›Íîpä«TN§SëpL«SçlQ|Ê„··7UÛC:"o!R‚¸î…M‚•’Äÿ±o%ŽSn#*És¢¡br‘Àm>®ªò6ÿ½7±<½ÎûÞÚï­êêî©îž™žE$%ö0\DP¢¸˜”µÄ¢&V(‰¡ÓØB$N(°d 1ìØFK°X°hJ˜( µ@á"8I‘Á™!9"gaÏÖÓdïk-÷ÞºµçÃÃúͯÎ䣊n}ôÔrïÿþÿïûžsžóœç¡oäQM,†"ˆšé§f1~M– bäyˆ€ž~+!„ýî,*ÿ¸zõêÚÚÚ`08¬ÑœqÈi~öÈ ³š···uxü´CП(äÛèzTÇÈ£°òÝñæ\ö`Á¯èoÒóGÁÓ¡ˆ3ÚçZ>NÀ6žñ+>E1Y`WƒÑ4*l"΂€ûaR Â›gg'k”¹½ÅÓþ˜%€å#62ƒb:CQÛÄî%£<nÒC‹!Zº˜ÃÈÚV4ii×!7Îóm¨'jY\ér™y®6Í!” aÛÌ)b0¡{Ñ´(.Màrm_,!ç`®! ³ »Ý®=~ÂaúžÛ·/þÃxêäÉîãO~âׯ/ܾÝZ[9}úèÊÊÿúßùôúúOݸ1½»ÛívI}†Ãa·Û ‡%%ן4ŸˆbfÊPÓ‚ ý±†sñ=…Â`•rGâ=Ó£¶8£â‰¡Nzº^¨¶{·®adsÍFÌÿt1š]뇀ĔhÛ7~-|TÛî!=9Åâ8äZ#ǽbŸÚí À'¸õêPXäØE‰çÚÜ5‰Ö*,Fí}š{È´x.xVÔPrñSiRZóðº,Ö¤1ᘢž«²à›P •óô5¿.-üC×Úè`QHŸìÒbP44™("…Oðf{›ãs)êÑ)éx¬örõ°‹Éx<ˆùùù(wálèÃ*,æææw˜Fl’Ë ÕétÌ7«D>nvv6'cèà<eC£~LæžØê˜¢qÕ £$æew;vìÎ;ï\ºxñÞûî»ó—~©½éM[ÿïOüã{o}ëä3Ïœ¿ë®{?ÿùéõÞrûöúääp8¼víZ*Â�té-..^¿~½dKžÏÙ9!+˜ÙA"È4á–*œ¿"ióSà.™ƒ…„§^ÚAEÔâ SˆdBà¢^3f]ûú‹h›Ëe‚({Ö9bao·ƒ¶@ý_c#ê—ž™ÅH| P&£QØétNœ8áDõeA*SbÊD…Çkœ/Û£íÀÊÃÕ)FÇùqÝI.s6¤Ãnºšæd}R¢vP™Ø²’V ˆÕ.ç‚KÀìü úùJLô´£Qo>~12`ž¦ÌNæ÷ó•„Ý gþ‘€Ë±cÇNž<‰£¶³´Ëàhй)'NÙùÔ‹f‹xÃ4N§cÊÐÑÛîV^\s¯×»yó¦o¬ ]·k1ËCÌWÞ"%ÎÂÂZ;yŽ Çõ«_}êÔ©“¿þëÛ¿ök;ï}ï̇>´õS?µñË¿¼õ«¿úÊn÷è¥KÿÈÜ<}úû×ÖºN*¼Ñ‘#Gò©–ò£t顃gUÓß2§£h/õÙÊæ²“›KjOÆdOA[@ºÂ…”í…ÚAµ'«z2¢tLK¸}¸ö÷žJé“grË,ªƒ 'ã*ç Ot’^›åDãIGyWOá™þ”„ð×  >&ÞÐÏ(,—QãHDÑÝT� ±%n.ùX¹ù¾1èüUrù’6Ž2Øÿ˜Ð€ÿ0ÕÄ¥²Á`…jÀÞ8ÇJªÜ÷]Ö7] ‡c+ˆ@ÕË€9\:éêÂÂÂ;ÞñŽ………Ï~ö³ÐsiAKÌŒ=†b³Î\ç# G—ðbK€ÉÍ)Ô;¯R»?¸:·1ÔsJ¹nä´” Dô<ô;ï¼óôéÓÜGŽYXX¸ãŽ;^ùÊW~Çw|ǩǛù½ßë¿ímSög“O=µuæÌæööÌwvwwgVWÿöûÞ7ÙÚ½O>ùÖ·½íλîŠjÀÔÔT¯×‹—y�Ø`_±wéÓm$�¨#i”¦àƒ_ÀâßIW½¥ €5¶‰ÝTÁ96™FBC$´ÆPöž3Q ÃPv‰‘ÞSSL¤qg€ëÑû!&aÈ® /~ˆs ãóÒVó9»óÈQ²1+ 32iEéòÒåv‘‘­ev�•F~tû qd³…ÞʉSõd¯Éß³ú9m‰H$ðaíW*1{¦µih®É'Ûá³Ô)iUàèsæƒxj²ÉE1 ŒEA|¶rNœ&®& ø¡`°m¢Ý7¾ñÙÙÙÁ`ÀXšÌ­ã<‹Üü w»0#|¬g3ò›Ì,RÈ2Ã_h¾ôù‰:vÔΉŠW€¸¼&Ã4Ô[333Ýn F^a~~¾Óéä§Gžž>vìX§ÓYXXX\\ &vÇwÌÌÌ4žo¦€[kwßu×äÝw·Öxàî=÷ìì쬮®^¾|SµN§sÇw ‡Ãáp˜h‡(_Û7}g=t»]šsöƒ€zç6†r?!¡Y~ÐÊCf…‘ ÀŸ4­À,j·ÄÀK]E%2…À†K~9�€‡ÜýňG¾J|ÊK™þëgríËðz9²ÝC6#™ª‰C:ËT°ƒŽå.S)vžf€îhŽ€òW$ƒ°hÈ£™owƒ‘T‹ƒØm­¼K’q#Ñ6w� ´oiù\ø'Úª¹ôÐ5_#±—‚¿DÞEŒñh,¬@?�T¾,…BásoooŸ={6ê5M>öÅI,”iW× €¢)kháº,F¹•Š™©Æ¤äwß}÷ÝwßýÌ3Ï„mLM“:�JK¡Ã%®Pd{¾¤I¿D,7x8žR(G"½í+Å%ªÍÎÎ.--½â¯xÍk^óÎk×îý™Ÿ™þÝßÝ[ZÚý[kö/ÿrøö·O?óÌÖ‘#“÷Üóå?ýÓ£ŸøÄöw|æ3ŸyòÈ‘~¿ßëõ¦§§ûý~·Ûíõz—/_^^^æöæs<yrggçúõë†",§f/ ¶žS=”¥ò,°×3¢ ñĬâ&¯^ç‚ì5Þ—•æ&P*¤ß“ÓtïŽ äA¡œÁJ uŠ>4üOàh·‡¡}Zw|rŸ*Í*¤ÑMmá²Úퟀ?4ŸæÃæ2É’ÚÍ+Øç$͈ÃúúúÚÚXÃÛv&g'©Œ¬rŽé4$Ú¾X@Vé�Aý´ÞI%|9tÀøPEƒ µ;3ýÓÛÜó�³Åb33�DÇÂC$¼¯+Bv`¾nxJ¼<·X#$-x´áŒd›yyyõå俥…æ9V¯\•ý8L)š1Ý"¦ú2<yJ¶AgÂ.Peð ׬99åike© /˜øÊ䃧_]]]YYù®«W~àÇ>ðv÷Ý;ï{ßôÇ?>ÿØc“W¯^yðÁcwÞù¶ßøçvwŸ[ZZYY¹¾¾Ž* ñêH­#Zš[×ï÷]IXÖÆUH =ìeöD>¦œwvv"q}ùòe Z»tnû6n®}êèãï> \˼šwCF…™¯óQOÑ‘œQEqg²×Ši…3f ©1cíÛ…>z’³B×9£çí5™¸iŠÛ .xý¾loHÏÈ·ÌÎξño|Ï{Þóè£~ò“ŸŒ·Up ª¤Ýšhd%PR6×Úeò?x½q¶¼ ¦¹x  ,b»F³ìLŸe‚¸hÁ|"bñ £aBšËDÏÇ•2޽md#¨ÉJƒŠÿæ­ s +ÿˆ¤ØÂÂB‚“åŠÍ¦å)çM‹~�� �IDATp4ÜGåL™fóC.\¸råÊÚÚšG³1O: ²;LPr ’ŒŸX¢¼dŽ33ª©¹ÛþÄt"Ç¥K—nݼyýé§w~çwŽ~þó³ÿâ_´áprs³µv×sÏMnnþ«øÁììýë> í„KT,çøòò2¤€p@̪ Œvr—6†u‰x4!'ìåÎdÀÈa‰‡R²X6< ¼ZÖ*càv‡do xn5o¶¸¶ʾ;@×­iKn8z”ò79‡ùÅRp/±=Sf5èƒÏEÛ¦XÇ3X““ˆ4ÙR¸¹¤µµµ³gÏ^¼x¬ *— ê¢iOBˆXæÔ©S7’àù>øo¦ßPçyHÖƒ®Ö_¿2~H3Œ_ Ù “¹ €›ŠŽ€­Û`rçé¤F+w\áÓypŠÜ1=RÅ&ij¤hÿp`᪗'óSf˜rô”~׊$9P á³Él-¿ƒ4ß´L/ ‡ÃPÂð.bnÔÔ=Eh²þæææÂ‚-ò¼ÖÖÖz½ÞÙ©©û~û·×ÿð§™xç;www¯_¿¾¶¶¶1nïìüí¿ú«œš·––X±ô­‚a?†¥¸'0\ŠƒM^B¾Ns—óÈÒÞÏú_^^^[[Ë›fEÁ¨ÌÝ££ãÚˆL¥˜V´ý‘ðvPôP ’4õO$¹H>»cŠÊ\¤å¦F•æÇ!çоœ €x0UÇÑãÃ1»´ ô”¦b“?4!!3I\zomm½ð —.] 9°#D;ÜÌr&æv§üƒ?øƒ¯ýë?úÑ>öØcÆsŒ%²ÜÝ¡mò7/€~x<?ÂhB<T :“³9>@Õ=Eë!›—ppæ‚GÙª®d | S‹-:u@¨­Èäªa¯á 9Õ²C(7ç¯Bƒ. dóÓÈK`âÒ÷¶” ç…‘F3°mæá|8Á’rºá½FZÃîÚZ ÂI,²ª‰ÖNçá{ï}âÍo~ík_ûš×¼æ{¾ç{†ÃáG?úѧžzêÖ­[[[[1ÀM‚5¹/Ižg‘· q@°&^Û·"8Y¨„"zuV „È-u«¯IÓˆƒ›MZá§<q†vËĆ  iˆ_iöÀý±§‰«dd2J3Õ4Z6Ÿ}r X+Šú^"<ò’ZBÍ,]M2Vsºµ %á=Wì=sªBxkç%©WÚÁ)3*ªÍÍÍ .LNNÞºu‹7jµGA®(Ñàd³F?騋í[Üeu×ÁÙºOdK‡QÁ8I'g/tTîý4Mª‚2ÑÚ…ÞêÞo“qƒ‘zÒC4@}x™ˆ‘{Òív©_)‹¤c3}šÀm+Z×–Í/43&pðlÒk@ðÆë6ÓëõÀŠ›S`b^?U‘Ñ"¹ººúì³Ï‡Ã{î¹gmmí…^¸xñ¢õ;€ªèº£É2ÆÆ´˜ØtÎ9„Q\ïDïÓ/Ë0�7Ù/h£Xº³Ö³@jÓ³¥®æYiˆ\“Š‘h~-Ç¢VÜa 8~Šá ?)'„¬h÷¹qÈ9ävŽå8-ÅŸŸF²z%Ž^¾ÄKÕâóÆ~HbÈ/4¹}äÈÃùœ€D‡#* ¤4, “-F_üâyäºY£14tî_v‹{tÑSÊÌÍÍe,‰ÞFvÂâââý÷ßãÆååe«kçCaY-{nròT»·LNîîímomMloÏÌÎÞœ˜Øu±œë¡H²ª <Ë£y‹R`9Òp ]oÛ›šð•oF¸¥ØŒNZ¸»cÑLP,8“Å}v"«Ëý• 3ôTÌÖKYfXOØäaR”3Ëj1$ÜUQ¢ì9==fRîXŠ•^¯—‡233sáÂ…Û·o_¾|9¤g6ÝšP"ª¶°°077Ì1Ò¤e±¨fŒ_™ÏB&HP*×vp¦BZb& ï„œ?Q$YK”EngBÓAÉe³ŠŠ9E¶ýœò©™L2£!h‰ù¾‘É"×49‡O•æaû0¢K%H‚ 3è »š¥Æ(_æò\^à"ÅNöä¼'QØ“– €Sn|Û<0ä\3ý!ÃkÑ/SopVõ°wŽ[Ö¾ý~?{íÎð,¸fˆvvþ¯^ïñÉɉ‰‰ÿxk+)èg§§W''ïïõþÝÌ̇$!cÀ4ƒ~.õ ÿãÃØˆyðN'íO“O—TÃÌIÚAÓk£"PK(YpÍá»ðÓKÆÀùèSÒ£N¤üù˜QÃLÙáv‡ w¯L–¸¶ð€Šp’-ehÆ#¥ÎZr%AÌN°LM~ígïäLöLLLôz½£ YŽæN›5Ð ÔÚàƒ¹fÊМËnå·–áS7, q–Ș'»=a‡BC(Q“¤&Ý2Ý쩘“¼R7E8¸¦Û7=ü/3âmG=99‰DcžßÒÒÒâââ•+WB¢e'(AuíI5­ñŽ ß�8{²‚§M ¬Èdû�X×îHø2Vé‹}h*giít:V3+xcc#“}(<¹Iÿ)ÿÞÙÙÙÞÝý‹©©ÿwzú­{{5=½»··»»Û˜¸>=½}pÐSÀ:˜FAMéæôáhƒ eêšUPÁ ¨Ãþ BÈ_&mÌÝc�~{{;Ga¯×süóh§'9Œ‘ÂîͲ¢¥ùšDwà)°T(ÍËl¿ô–ÙX·îyÊfÖrªÒéø0ÊÚàߨØX[[;räˆCN¶Cj¬Ÿ\gÒ¬………éééØê€<òÀÌé‚u³ ðkMBþ׳kL€ºÊ÷ì -«—ì&E`ùwŒ2&åme"!*F"v>çd‘QYxOðHÂ)"lžv‡œo—¨SúÿÔ¡ä;»»»ƒÁ€SÉG@ÖYÑ·¤ �™¾yŠN±¡G !Cà æ )8$ #^lV@:Îîó×�5LŠ@Ç4ƒâ4??ßëõ¬3 ÷l­mlüÈÎÎó““¿9333;»µµõ}ÛÛÿópø¿Ïκ[îLÍ©"ç,*ξ-ƒÜOç–^Î&˜TE¨M7Y,gçç>/..ž9sfuuõ…^hR‰%ϰ6¹‘ ‘D‹Ò€¡�}Ÿ vãº<zFåÝt¡ÝÅã3¤Æ¢JQÈ}.C…Ûìv»áAÐnìv»i@NNNƒT0a$6çòxl”ž÷ZYYé÷ûȘ~kyì· rëòvÓ4*NÂd¡eƒÛÜ£ žp²ËT“:5÷ÿâHÍ-J ãŠÀß0W¥½gQG“ëLßw~�k4&¯IbTäEÜablÀÓf‡&ƒ 'Tž½Aç"&RÍ•+WH½]uÁai³ûÍVòÊ&S ø–às‡Ã"{ &Z»>È ì·}£:ÔRfîqæH2)¨íû†¹.¤�¿Ššçöö6ž’–µ&ºÏÌÌìíîþôÖÖ3{{¿95õ¼öµ>øàë^÷º/ÍÌü“NçŸ ‡Mz©$ÖA(Â<�bTx)Jx" 96¸÷n.¶•¼EDÀr«¡-lnn‡ÃóçÏ_¹rÅ?š0æGyDäõ/ëRœÚ1ç,¸ ¬'fÎ!nø}ï9G'<Ê5µË_åæ�aå¿¡Dcµ±³³Óëõƒ£Ç·oßFZ?Z¥”†Œy?H¿ÇñögÅ̇ô¼T"™o]™»óÚ ÒçÚ@°Ã‡&B°—ý:£e"±ÓœÝáÈå8Ï%% ‘Òv!§%вsát˜™]Bå’%Ûí¾4&ÇUÎ!|2µb z–ìŒ:é~¾Crg†±)+æF)\f‘EŠð-'g1>íE·<‹/J® ¬ÄÃ+ñA`h€-Ä\Ž‹<_39uÖô`0(Fp²¾å¶µ5×ÚÞÔÔ±'~ò'ò‡ø‡yä‘ßüÍßìã ¢´µ#m�,†8X™.,8 >Õ8Õ[3Å]ƒ:oȨ]œ}™4*‡¼¸ ¢Òi³°•ëèÐOJ–›“hDyÚd‹GèPÊ á‰CÛc´)KHS@l“šôåöíÛбŸéÞÞ^�ÆÁ`pîܹ•••\¡Zнò²ˆÖÖÖVé4@UO8É}``9ã½E±&R©Œ=[|f¡JSyÄW‹¼‚çO™ïæô°ô�´‹rš& *ÄÞ¯(h¸7œV«5¦Pè³ÝPl2ñ3q|L’>|ÆšaÂ�j…h€¼4Ð9§šÌÜͶæËÁuò©”,,Øk´š‘®A¡Ù`´)[ÅVÀp×ie*¢HÓH?û!—Úív-pkl½Ø¼gW'íµ¿ ¯¬¬œ;wîâÅ‹FÀNž<9==ýÍo~“}H¾VTsFuH |OZ ó¸Hïp"»…fÆ­‘Có¼ I:}uÂ!×üU·ÛMoŒÏHðóüPIƒœU´ƒjuV0»t5 ÞÂÎr÷Ž‘æË¥(ÙÚÚºï¾û²ðÀlÓÀë÷û7oÞL8L€6[šm‹‹‹ÛÛÛׯ_iÛ=|9éÖ$ùQæÝ!Ëx„ÖÆKæ 3þâþœ•åXQ‰pm_,*oˆ®G#[$„”sH7ÐÞcÄEô4•Ý7EáÐ'ËÞ]/¤øœW¥Õ49‡rH”Ê䦿`‘W'T¥=ã¼#ãß4ŠüA“ÑV.¹‚惹35âZ¾ …;Ïš•Ñ9Z8&yHŠ>=x™Í Užx¥EI÷É©©{wvNݸñ‘|ä _øÂÕ«WoÞ¼ù϶·ÿíìlر̙rìèàV·ý©Øõõõ êÜO¦2­ßd‹éx–S,çi*ÊÁŽÖM ö¡°XC‚o%iš.>£"(%„ø;fL±1æTuõÛ*Ç7º¢�5E”šf8®¬¬=z× \8ÓÔIeÆ´—OJöÌü¯¬¬Ðƒ1@МgT9ëá.{¤ ð �ƒ“¡¶¯ñ€ìüŒ|‚P”f~¡¨Ä�bgê-»É‘I¸Ÿ þ´«}’`ßyð“Äñ§¦çvлiìˆÅÒÔŽÙ¶ü‡œCûÊQ>==E&ŽûânË…ŒHíϱ‹<)m~y´—`¢3ËËÝ «5g½¦Ï°†õ!±ŠË+_S“³p-àáC ÞáÄÛ©¨q$ÁL Á/û–S£@ËÙÜÜlצ§7&'ÿýpø³ßüfÿÒ¥Îöö¿ßؘÙÛûÂääÎîî¥K—ÀOŒò{ªÜ&rvÖ¢KQ”äAá8ª öbÊc%)vS$¯x½ ßñ¼°,Â89c1YL êmšÑ#$f¦3¨#ÓÆ‡¢by±<�Xw%ªq39sé®û>lnn^½zusssqq‹ÜŸáp-N¾PH®á8óï]‚gû \Æâa. ?·|´xR‚fÿ“¸“*?êrHÞ¸•Ìv:Ðó@¿ó”z¤t\gj>ƒºv¤6A>ç%Өв; ןەÄbr¿Äqã´àéFQŠâ½Ï/ó•yÉÉÉùùys9°ÊèeÓ$sÓì!µn:m_l _<^pNœÉpB1s^øšÞ„,ëÄãrsh>Ã%¥eó[|Áš†ÇZkß±³óðôôÙ¹¹G×Ö²Ãþi§snbâ67¿<;›Ù@â¢Õ¸I™íg½gZ¸…šFùü|íà[p¶QooÊ5Ó",ë ”g/HOÎñÄ]æ- ¯{êâ{)h &%o@Ûo¤6¹ç¬7gv¬ ôÉ2Næd ®¹[Ö·nÝêõzGMk'‹öÈ‘#sssý~ŸÔ;o£ÏÍÍÍ^¯·¼¼¬“¹ §`e¸÷BLU—"ìöíÛ¶@t–™ÿÍv`«ä•1#O2ᜀêÐ:Š4E`Hi´EöŒšPºÃ`®ÃÐ+ÿ5÷ÕÐè!ŽCίT!ÆÁËH62bm_ÈІc«Pxél¿lÏ# Zò\迳ãrV9[ãû|·DsgÞšý²ÜzxÄ:Ÿy7Ï«r†šN;ÝbüôÚÎÎCÓÓ÷loïµö?ÌÌ|ëcîí½bbâüÜÜã33Sû„T³RÓ¤š4P@—LÉ&›X­Žcùβv½ËY À˜´”òÂw²ÉÌ‚%dæºc‰v¦B…Éb„§4ùJÐ%m©C¦i>cJ7Kó| Ãú‚]”XèzJbMóó1É]XXˆˆ€“§”\IÃC<éõz«««9ñM¯Êc5?ÍʳœË)w¼ŠX`ÓŽÙHÍoMè$4Y 9ÍE8ÑÞHx.ðÍ)¥¸L”5©Ä ÐÌc9O*ƒ\®mÌr;Ê�4Î$ˆ [fÌX;ü/È-žÆÙí`o·Á, Þm�«ÓSGc©ä£3ß/%Q“¿u‰^tàPýx#¿†DJþ¡ s˜´pn….zlr6<*ý_2†RPÇ©©©[­ýF·‹¾êííí•_ÎH9åR1ÌF¢¬“>Á©LÃà¡b8ŽEް¦1ONo 'Eª«œ$¢˜2P¤²sR¬®®²`‚2 ‡CÈT0§¹«MZ>6k!@’[¬C Ù`lhÇ“ãœðà¹Ü¾}7ñãÇ÷ûý~¿xAd5"LàF7–Ø¥ðòœÓj“‘õ©üy4x`*ZAƒÚø6«|Õv�ìkz“ly›Ž{”‡‹!æÙO—˦©–[ÄÔ¶¡Ì•êÜcUD¯ÅÅÅw½ë] ûØÇnܸñ²2’ãsÓIvu^ ša”¹Œ—»'7íxæÙÏ2À¼¾¾nAO[4 TDÇa¨YØØ†‰,õQ¾Ÿ6/=’îÑæ`4¼® jyPÎ{•vN÷rI�i’ÑIFú—†Å¥³rö§ÓÒÑä=©Ì%xÔð!Ø#XÍg gQ“)c Vp0kk6Ùs†Ú¨‰I0P \˜§ýÛAC0³ìòI£(\ä‚ÔY-ì/÷]¿¦ñ™çÇ’s|gg'ñæÆÜmÜ1È ü˜ÂG°n)*ã@0êÁYZ�½äò‘³èc¡éYÚ“Žj~Ž`×àŠÜð\s;è{íA"È8¹6¤u‹°–Ýw<kËÖ÷0à*9¢Y¼ÎæææÅ‹ÌÕ>ܯqÈ9À¬§>hû¶í¤ðœõˆ»*§kg½Ø"<2P•»/V>'ø™ÐL)c=·¢Íþ±o²¿÷œòa™'õŒ i°†õÿ³ÌwððR=9#Ÿ;C³MqL±\n“>12ûÄ9[Á!Ga€xRT3qlRðq'ƒ§5 ”Ïäô'o%½°Pب E“E,§ŒtySÓ–rž¡« #¶P(Í_¢ëföGg4õAQ‘!U'ðý/‚FÖ| ñ±YÏQ1|cá€bcÁvãdGçŒ*_Š!Ò>ÿ»Òmûj¹àoЦmFnœSÊ”@…pŠ‚»›µFJÉ·rñL~|n8°p¡Åæíc¸’ÈaàÛ–ÀÿØcMMM­¯¯C•4¦:9‡Yè”Arôl”Ùl ¶í“—1½BpËf*¢IGÇC9˜0 €GÐd†èºÚ®«+�:Δ¦ñP^°%|&‚×Ù~Š ËÙŠ§[ŽÒÄZ/è²Ø”:=a:~ÙÎ4v‹ Ù†É›•NJ³Í¨‹®Ý‹ÇxÝ?+åx´Tu¼±'&ôBòéöÛééOž;ãën •vk÷a¿M8Ž­y+M–†À>ö³€%qßZ™46(øRMº !ѱÓ3èk ¤JP,{Ôš`KCð{¬› KŸƒëÁ3rë]oÄÕÅ7áÙNóFÅ©é=G1:‘c=¯7 ¬¼/¶ëÑ œNh|Y‡âqÈ9„c¼%¹m*�s–�â=ÅÅÝíví¸^ô‰IN >ø˜æ½¼ž8yaˆ"Øe}-**¿)»ÂRž®cLÈÉ¿“3"ÜË&ÏG¦¡ »º8°™§ç"# Œ¬Z¼ ¥a6!Ìüü|FmèèÝbs–’P[ÈÉŸ€v…± Víô¨‡«IŠ`ÊÓ€|vê…¢ÁÊîôxdŠ™®Ù†{Ë ažVu¸€¾QLZíni¦_êQ«¤Ø ÝϦt^s[YÂa§«Ùós ðLn8¤—2^Ìî•Ò-tr3’B!1›ÏBªÄt'|B–º³½ƒ_&½¬×P¾on©$7î~5À„ÛêÞ.ßmM49‡ ¬Ùh/Ujf.3_ä;œãî*³þ€‰Ø'd Ü‘ÓÁ‘5²ŸÞ¬E>¨o²­ÃÁõ7g ’ pʯN§SDkì2qeÆØ ^ǶV£˜€¼‹i¡ßŸ�)s¶J¯×£PpŸ™ÛìseŠÑÜŸt¨“lĻӯ·€ ZØZÑ&É‹ ãÚ‹'ûžb‘�lÂyÅÊŒÅQÊÜú(6N…XeËp. ÏdHÀœ|Ø0М?Dyš8¥Œùf¬CœŠ< æF:S>…oÉüiâpCĉîq7XužJÉ &fsvÛUȭǤ Kéhv»Ý&a'¸|>ÄÉ0LÉ¢%7B¤Ü'E¢{> £ ÞæÅ1Ð–Ò *tSXˆÔd¹`K52ÆPdÇ!ç¯ûË逕+YFààÀ;%©ÿUq41t›¥€®8kÂ_ø‚Ïf}X¬Þ­`{ˆ¹ Õ€²®;={/¶ýqBo{ÚKîíÓ±äé‘py¦Àråtni!äcz´ƒ3Õl餽Ö6µ&®çX]:3Ç!O$Fs¦ÆæS;TÀJ°5o,êå¯Ò­ájÁ[n³$8ÑJ�àÎ*ËÕ‡¯ ë`S›››©¼ÝìqË:ùŒ²âcûjgKî?Áyq¿'i ÜBŠBi†Ê®_‹õôn† mIU§…@9Å7Î532Üä/…IhÑšréT´ÙkEáûäÉ“›››·nÝ–‚Æ›ÇàÜ¡1(giQ{.XGÑ¡%%¾}äLý7!åãX;|Æ5uÁåˆh0ÙË“£鮆©ýdL½4ÍxÚÆÍL9çƒî<ÓF¶d'66;ÛAÍ(Ò@º—`z^»D#Ò%=‡:šÆì"ŽNFòbwk¸Kqû°v°Ç[Á °!\�ÍÚ«ÑS,–%vÀ†úa_�׋îu£û`5Ž›,̓*Âh9ô LF²š Ä4Èì—¿MñòY¼°L%Õµ“EöÜÍ.Ìr"UŽ[AÔ 6CêÖ#¢ó {U¸P³ƒ+G?839¦-ƒÆóBõÎCÙŽÍ® ó";àÑ Çp8ìt:‘µå§É-ìn@tÒ„qc¬Â³ó†#ê®$‡‰/29AÑ5‡œÃ™Ë±¤‡™Þi¤‡= “@nö/sÚÂ’ÄÕÍt,¤qŠêx“À>‹ÏÐ4VÊy;jò›s ² ]6®È"†D?šP‹Qªq‘”§÷ÓjæÓFæ¤�%È©Mlâ+½VÍ}‚AäKÊâÑ™ÉÆÓÍÜ…ÛZ2k$®9³r¨¹@aƒðca•¼K†%í%fËšTM0ðÌ YŸ…Y 6l9Z`FÍ¢4ÏóÅ&[›"ŠÔèedQõû}ó‰-‹ID÷¬-4••2hÚ^§ü)M•ˆE7Éžn|Yf¬„¼�`­ ïÓhgo#.ÎL´ËDíÚÚÐvм½œÈO+$‰´ŒKÝòç®´Æ!ç0ã ‡‘5ƒ™°«R6RT•°šwâlh({̲€g ‰ S2ë´³òHÞ‘â(Æ>wÌÔ¤gP4»ÝnÒ7â]„„4Zô>I‹BG Y'Q¤Tv(ìçÑ^:-SW$Å‚Ú46ƒ3M*vä­f¾y¬¯¨æ¯ wx”•(뵄~%=ù|?iÊ(ØŒ§åÀå¥pu™DƒÎÐAÚÒöÏÇárƒð)l ×_…Z’wäSÛ•1ÛcÇŽ=øàƒ§OŸ~øá‡Ÿzê){¥Û :MŽdiC:°z3û´E9‚ôkiiioooee%¡Îâùùyürì}WìÆóïÔdfßÁrô¼„%jÚË©2îGƦ‚eå—")wÉàôK&|oÊ×p8ôÓ‡œCÖ€ àA‚T�,Ð0¤í„ÅÇ\é÷:#3¿ˆk+G™ícÒ6hžáøôl‹¬Yñ)À2‹r>gh·ÛÍõÊvã´@^|+–ïà6¦]cLsk$§€þ|X}œ†ÁY@Å€6µé=Xç±'mÒå¨Ô9Ê„][>{ÚØ añ  ã@Äíê1´è{Ò4åžxÓ*[›§Y4CéÛ}?»Çæóæ<…‰Ã”75–ˆY Å%S«`M‹<_ÉͱB‡kµÀS »ø•¡ªmŠ,e4l²<ŒÄrš#çÃVÍ¡ÎF?pë ÏÈîŸÜOvŸQŒ<¬„ä:ÕE$µÈ‹%Û@ÕÛ®Û~îãsÈ °–#§ G˜3;£ä©²íb‹ÒWÛ[#‰6>[Ô]]›ä ,西»»¼ŽÃÔý³ò˜Ëc²dvvöôéÓ{{{×®]KÝF$³¹/~N6 -6Á%qñn!‰ØFD|ýYèoñ·¡•‡3¢$¯ÊIá¦òqÑ»}1�� �IDATÔp–é,÷œhŠ’&I±Ç0Ñ@� ð  ÏðR¬˜]`=ŸA«Üº(?HéûœYE·É°­¾âÁÌÌ&+ʲ$a½^ïŸøÄÌÌÌêê*œ:°,wSŠé€“ž piG‹"ÉjЕÊ`uuÕ6kE€ÅLâý›¸Å)>“¿ÍSet·Â©i\Œúƒ³0ì²c=§¿æ˜O£k~Íè–‡œÃ‰7Þ]œï%ÁlZlqFÒð,»äƒÆÓXg–Å÷“3k³N/¡Ip“Èd ,–Y©¥8RbGÿœ!s^0‰UXÑ&ƒ¦~§i"²­Ã’Q,óqŒµ#¢î€Gžþôt2PS¹ÌðÍ´À3Ñaø<²K˜Èã(Ø”I"Å7'W¥yŽã@­ùH3!VÐ��#%IçdqµÍ»0fàÞ2_åÀ-:ÜdÜFöJúå¡×Ì6Yl¢ÉB) u𮹹9~`^óÖ­[VϤÂ+Šúôý"üI*°â/UœÝ³à#øº'£Ë< Wc­µÁ`@KÕxFq8ô7„ÚA¡B`ë¦)ïî./öê°üàŠŠ’_ÉXIúÛˆ´f:)6 Ì|(ÆP&8ÓÓ¼qãU“YÍÙ¥¤ 5Á9…ý­—¯G#slE<1PuÛDÁÝÇïÈYlóºÇ¼0Kâ ÚøL¥ä-r[ P‘¤ÝŒ5ôçÉYð‹ð3ššðféË0Ó+¶›*)çæææ`0p^‰È œ…ÌpXê†RŠ×¼&‹dVKþÚשh>‹%Îr Ø“ŽQîhvvê‡Á.áBúr;0\� )yL$g%¢8,fy†K¸Úñ`ªð}A~@ù iØí™XP“’Û –4‰CGh±~ g.Y µýË\“"-RºVôA騥R,ªl›wf×gp‚´˜,ÓZyv eÎE' �ø8äæôVóÁ¨ÐižÛ>”ŸN]\Òpë.[6´H³qh‰¢PÂÖ5;ª±¡Vp™¥°f33¡Ö4ƒ¦éÞ;ä1v©%v¼Ù„Þ$¥IN»Åsí R=­Qcw–•t²VÔDF¡!kœØ=”¢í"ð­SBói0¤ãEr]<‚¯†ï@‰YÎe+ñ@#«š˜]dö›œ&Ö××¹fŠ'ëôðÅ­3wÑP’ &^é÷ Ñbe[“ú˜ìášÑ˜@É‚UŠx‡Ã ìpx"¯ƒwQŸòZµµà(IÝ©5©Ú@%ûÅ4wËʦ¦»æ†¨E,Ž#·Š ý<.aól;(Éȶå]žl`Œ2Á:9‡�¬|Ÿ•j)£^¬Å¢¼dÚ ÅŠ{Ú 'ŽÎr¬vìB˜•Òå„ÒIàÖ½5§D=œ¯\Õp]Øf L.r“úψ6Î"/(ZRü‚EeŒ=aðofÏ$OO®à«²ß‰7<Ç©>PŠývp>ׂfó‰ð•iš·-dnòtZÊ#÷qiƒK¯1OÚº€vªdV±]‚h8{lÓt«Êz‹3˜"I@ya Cs¡&gVÚ#nd?δØ)ÑÅ(SCC.w¬áà öh‰?¸y¶ Çnnt~-¨€ «é˜Ðˆð`;8QÃÂHOì–aU0L#„¥ÖçMíU3i°ƒu¶¸‡œÃ$IN$EOÅRd:MŽ£}<û›J±ô]¡»·a¨Ý&¤žR¶ Œ1"/M«ÓãúH#>í)}ú7£ð4°B$¹hÀX“ÛžZMò…öαqÎÎaö ü“)šü­„ÌÌ̤9TÊYüfL›&‡ qŻ۰ A³ÿŸÞ’…8J¢ j†Ÿ³€µ¢Ï7íÓå)×âŽåYMg*Ò×>¾-âàfUž KQîáÁ1úŽéôôôüü<͹d$æÓûã=£¥Ç:IÁMéÙJ±Ù];í à@ð\H1кßÚÇÀf6H’?äpxR¶kÊ+˜Hídƒ9Cm06&Q°Ü.Ïæ›ÐýqDujèYiK7É®CΡ5r"ÅáIúÀLÀhîsX_ÏÐ*yDTU||ƒ áX“ß±”U89ÔX|%éc3àµNõ�T•¶<ýmáÿ—[·Þ¼½=œ˜8¹·wÏÎNk­?1ñüôôÞÞÞ½»»o¼óΦipož&­ÜÒjÊDH$}›o¬ÇÇÓ¢9[3‰’X.ØÒÎä¶9¯y‚M ”SF’Mw»]JÆ9Ë­'øÔ�Üœ¬‡¥¥¥3gÎ,//Ÿ?¾ßïçRƒ¾ ·ÚKÛ-_ŽþÍ9åÞµ§C8ñQšiÒçäÍoš÷4ôgÐ&w»8ëÐãä›jø&¥§çü¡/ÕâY‡ã¥Õd±Ê3MÑ“Ñe»¡Uì‚hËAÒ‰Ð*ÀÙƒØ;Ù¿ ƒ è¼Ð 4í acùàp¾‹ÐƒÁövP)Êp8––€€ aÉÄ”MÈîa;9/…è<K*S�¡9(A* —x$-+5ûEðÃÚÌpÌHÒ9›Œ¿q 898á—Ì>+̱cÇ ü[ot¢µÿúرïÙÚº{bâ¾Övww{­=75õéÉÉ·¶ÆdŒÅF-“$íÌ|QÿqüÁÓãìXâ‡+Û8¦¹Ö,ù© U±1„m³Ùç™N§7�â9|ÏŠZš3GÀ±cÇ~ôGôÝï~÷¹sç~ÿ÷ÿÉ'Ÿ$ë÷³ƒ!mô5Êk`†þc~”ÎJÌýÚAYh#N ¸9{Ìoúu¬áÏúGS\ ”e§qu ÊÂþ+†ÍÏÏ{g™c–HFœ kª'+b\ÔßéMšµÌ´ ëüUž‚Ì[¤Ì-µØl+ÆœM:o#z$ÁNI@a3¦ßÆéD½È¼Q朌¬ŽCÎáÃk€×N̦ÜðæN„vÐ!õ­›íÅJÙ¢^^L�MJ0(ߺõ�LW6΀ázÂ%ÛÛÛ›ÜØ˜níëëÿÝÒÒW¶··ïÞÛûå›7×fgѱõP Ç.)­Ý¨ÖÖÖljBù…¸ßÜÜJBhôòûeo§7@±ˆ›Gy,è�mz~~Þ¾#ˆAÐÒàTµ!ŠûLEÑÅ£'N¼ýíoã߸´´ôÈ#|ýë_·ÉµWÒÃzÀªi?4y-ÛWÆ"FÝn’˜c©nþ XÇ oá¥, L´µµ•g騔‡d½)�ð¤ˆl’CÆüÉ31”ÄõBJ4ÕÛÚN0 iºéÂÛy%»#eÎ[áR§àQ!D«Ý˜RB©e “{JÚÇTgQÞrkmnn.ÇNªjØŠw8ê8äf°aY—ê>ÊÝwß}ùòåõõuš9/ºÝ®{wLwŽÖ$«C&bö”‹LÐ0hÝY±x> ÞË}Ú0©®]»–ÌLº ¿ººúŸ.-­>ýÊ¥¥^¯wëÖ­rüøÏ¯®Þ»vsšdšLžh#¬BóŒzé帱T°ùB„j:md‚–´âßd—î¬�²Ùi”É'4ß8Œœƒóò¸_Vt{{{yyù+_ùÊÉ“'_xá…sçέ¯¯Ñ<ì°趺DàIŽæ ¤±Ožžî÷ûE`Æä(”i|„¹´uyAŽÅ`ci?o1÷)‹µÇÔþê5FhÒ5 ÿ>~H.’ð�´ ’GL’ Ë`>§?Kþp2[¹„ä7ß1ï”qé&6b)”¬ �³¨Óæø <)Ps)ôý²:deinn.tj®uu•f›¼Í¡8D¶qÈ9�¬™ho’8ëÙ=—–»'EœÔ°¤B6ÿ 7g|MbæäDlç,îd¸HgàܵNÞ4ÿc#'é«wvú÷ÞûÓï}ï;ßùÎçŸþƒüàåË—îîΤ$6ò7ÑGáÝáì¡’ó"\¿ßw—s3í®P˜ *BCB,�À §^«¹$ú?Ë1˜vå½mÐZ*Ë€gwûöí?øƒ?ø‹¿ø‹Á`põêU2Œœ­tŒÜÁ¶P…Ë…ÓÁSN=ÖÏ(å2‹“ÉJpÿ¶¯dLÅ–JËFŸž½'[‚ÎNDI‰ì¬À9(b¹Àˆå9µG]–y5€´£ˆÙ¬ê¢ÖCVÁ0 `iÎè¸ù‘/zªÚØu ¸Ü3\ØwæA”È™«"bÁ˜CÈŠV|9dbºPöAOg(ÿ5Ÿ):gfWŽCÎa’¤9©I…,evýúuÖºÙŠªÀp¡BE‘4#¹Þ~¦YÓÃ4 ‹Ž·IP^ß¶¦çô ãÙ:7¨ºåÚ̈å [ZZ:~üøÑ£GG- –±€ì´p�’†3×M#$ד=@‹« ŠÚ†5ß„ÃmUiç€f}49±‚é™HÊ-››K^ìª(éÛ±øÿÊÊJ¶=ˆ™á¾ÒÞ+>’¾íÀq5;Öë 0Ìa³ 47í']fz<ñjo4>{JS§Nmoo_»v-kÌL-ÆŠÝ8 ¿ h1†!›ôìÑè‡è‘l)ŧ`+Å3<Rq‘,ž? ?‚-àÎá206�ØKêãQ* qt ªty`ÆÜ='¿¯c!´À<Ôl|`„pcc#Žºpy sˆCηÅhNˆ: dØe¥z ôÆe.Ìu7˜‰Eš=3Hµ)ÅÊv,#,>&è{“‘È›V÷«ss÷Å?ýéO_¼xñù矿víÚ ‡OÏÍ}·Øe£ª`›�Î éÃ*¶;$|<âGÛW_öt[~unòèü£gèŒÎíp@0”ã­ÈÐ\.8]hÿÈT±<Ó7L$´D‡»ÉdzÖ1c¬Ý©º›Lô]ÚA/ËR_zÖÄKMb€<wRlÿ![€Î 8åãÞÞÞÂÂÂ÷~ï÷öûýápxýúu|åF•‰‚ŸÝî¢Ùæ£\ð(SœÜÜdz?_‡4»_›Ø‰ù¨ÓDSÿšë¾ÃyèÖõ`S% :ZlªŸ³BÌM/ãYEOšèo¢ÔvJu³yÔñor'ÞQ8€€Âœ‰kw»Ýùùùk×®aMO…ìÏC0ù[¿y‡Û¬,R`ìsÏÑa~§Ï¦À–œÎ»ë±$èŸ=úû7n´Ï}îCgÏöûý×÷ûÿòæÍuâDo?†•‰wóýoØÅˆr¶ÇF.…ÛåÝåöìÂÂÂý÷ßßétž{î¹Ø«EFsë2$÷LtñlÄâââ™3g.\¸pýúu؆;(¡F7'á?9âÖ-3@B³Í)§Bµb Œö\�®EuÍŽÔ\<ÐPò žBV)?%mwLÍG‹Â‚/q^¹reyy9a•ž‡­o‰Ê¸Œ[ýÁ’tÅùÐÃ4”­Éºr“ƒ³.;<Ra™ ËZçü-siåCSÍ ÚÜÜLå±à»�›ÞƒLöÀÌ&ÆÀ¾óqœ¦0N°!×ñø­§¬JÛÕ&ãsȽº”ì Ú’`<~–6Aç¦4]™Sa "#Øétæææúý>â‰&J:™ˆ÷8¤å‹q™+6}¼ÔÌØÚzÕÆÆß9zô½««_º|¹µöäììsòdkmV\€"ˆD&÷-žê¥ol¹„Tˆg‹BH£z „œ8qâ}ï{ßÒÒÒoýÖo=ûì³ác+ÇœGQ òÙÁY–-×étî¾ûî›7oò óóó333½^â¦TB/›˜ÊLs+ï>77Ç&óÿ¸B” VÎzº\4ðm›DÇË ~·î›\˜2)„ò&YØ|:~Ÿ-pôèÑÁ`¸É¥•Öúúú“O>É, r®0¡¬+qJYfZ³•m‘ÆAt•tÊË Ç÷Bkrš±Š ¨5[•¨ìɤüVñÆ�É¢ÌÒ,l£pA=%͘4TnÍZ<;Fá‹O›¢fõ<HEÝʺÃ~¤zcÆÚ·c T—‘ÓšÝz‰.–½oI6Ù¢EãˆÑ?›[�—;5#/³Ì¨Ç† ¹Å]lWà¡YÄ?è|vvöÍ[[oÙÙ™œœüíùùüùO¬­MMM}f?áu-bw[öùâââ]wÝuëÖ­è0¼­úC_ j™2è¼uÀz½Þc=Öív£9ÏO™9 Hp˜æ›V¬2/neeåSŸúTfYäî¹çžÙÙÙóçÏ{ èÃP‰QûTdÐV„ãìàª`±ó4 ¼æ[šš�D¾iض¨ñÕª÷ 'e†ÞbUcfª Hfyãx[Më+/HšBÅÚ&¢ÊŠ*ç>`²—ëÞÞÞ‘#G•°·´ó¿œæÔdÖÜ£{Dßhvv¶ßïÓ÷² ”åš,Ç�AÎü4 r“€ÐµNÒ®<êc¼Þ-P\Ìß&µ!UWºz@Î)3—†˜ˆõª¹Ôb8f¬ò—Ç-yTäVî÷šÜB»Å†“# ^úf§0µ@bkŠs;䆬‘•Ä”ƒ<±ˆ‚c´ƒ*a¿73ó{33X¸cisk%mž–›}~Çwôû}ª–bªf'wòÁ3m?š_[]]ýÜç>×ét014®Rüx,qèPפY—“‹«‡×®]Ëædt ¾ŒAŒ ;–ö²Çb ;¯fÃãÜCMÊ ‰)^Al¬plÅR7ö šãÉÊ7|LŠÝÈdÜ1ÚlžYR=6»4ùÅÁ›r¼ÚŽ�£zƒüŒ4Kæ=‘&™DÙæp—yj㩜Šm³ÝF<‡ä¨àKå&Ó l’¾µ»Zù°5FÁj±Ä2ŠÀÜ+7P׊Q¯G¤G%SÇ!ç¯;ä4Ùý&‰#ð$–±(J!I³|銊š³-ÚS²ÐxÈP<”—Œ¾í»*àJé Æê-ówôx#rež (DÒ7hoEF³¸×ë}ýë_‡ä§$ר°©En¹Ûíf¤€óˆ´ÝuZpxç8+C²n- üMÃ<gmm¬?çæèq`_¶}»I€š¼-n²Ï/‡@’•&ÑI¡u9­¾EƒÅ–BžmäFª´q'ÝÍ*‚7à0îŸû]¶ ÊšzŒ2„+6щ‰ xµó/Q�"rËî™Ó…Ìk·Û.u( yA¢#Djw8À£¼ºà¬ÃÛ4*EáESèq£&5ì¥Éœ•&Ã@T‚3„Ô~ü· )§(e˜lã¡·‡ßqÈ9ú€y,%öÍe³%ëÌÊ6lòÏaj1–AëñIsZHQG]¥Y¾)ÉÉ\Rj�θ*·' þF1GÈ$‡~zZ9µa@°gø°™y¦Ò2ã ˜ÙÀ>[ç:¹‡ì~¿o™¬LÝû”‰—»ýXÁPdÉ_˜ Dk¢˜6’†ó$EpÓ¶+þeíh�øck§B1n Õý NU\‡MÉ3µ:=9,–]ÍäÖås¥ã«˜ áÐA` @¦¼ƒ€ÀM¶‚T ;°25æt@òt'%Ê'M.h4([Ä3KB¬'ö‡îO42´˜·f/P0å²MŒ´èY6c‘ `;Ða%*ó:ÉÛÊŒ³ËA£#y.ƒÁ ýà&Á_¸N¹à4æ»D‡œÃlç`ŠøãÜg æìŠÏÍ(GÙåü(Á?«ÍzeV‘âtCк ŠŠ-²¥$ñƒÇiªä´=Ù±°HËxšE Üžõ(¨çàz^È ÌIäÒÍúT£làŽòj£˜' 7ªLY'‚ÀéJsƨ3¸ *^ö¯$ÃuªÁpŒïUÓÀ9“&ÓgUÐÚá8¶Æ m�è¼BŹÔÊ< KùùÖ•î·Ê<·Á Y9{´Ëmå'd Ê~)v¥†¬¹i~âô´(Ê›¦³ÝÎäI¥pç NBfõ3 mxΦÀ•,!A7™—Y=nµùèÆ¢ù5—òMþܰҙ=ÊCN-ôÂðˆ¦pêÆ!ç0«´gŠG2¼Oú(&ò{ðÍ4JÓuмä!öxÿ[2 Ä*³ï½ñø¢?Ok¡è]HÌAá=“ìñ:‹“æõ£xí@‹¼ŠYvžŠ`¸ykR £ éyx6"wžOÄdŸ³u2_3ÔÍGô¿I™ /T;Òg:½PàŠœ“Q¦íÒ¼a/"uÉßéø„õ,•±!Súp«©¥l}m] ã„{C[öJoÿ9ÓƒP`¾CÑÝñiË6!»Úé\ͦà._6x»eâT†Ú+á'§íææfV²éï…ëåÎ’½ïËÚ˼ªï¹%-2ÖÆëä QÊÓWæ‚6éWü(šKÉœÖp½]|<Ž7,bzq°ŸA«‘å�Ù KïÓÖùE¬ nÐn5}egg'«?oDÓÞr„í »‰�rêEø€ÈŠgôa{{;f”FØ)±lF­ÑA1ù3ö?ðœ×èÈñ¡,2fsâ¥ó8º5óóó`–·)­Wº÷Œw3é¢6Ì3v\~Ù–6!¾†æÇä(s@<ªIÎnü2÷~YK%­ñq“L"=$S×òž,e|¿ÑhÝo?´"l\”O=OH0Cºí+§Qä§Â`‰æ²!þ¡h@ºPLo#å;”5¹·kkk9£Y·¶¶Öï÷wêzÂýec$UѪ séI5sXfffîºë®Ó§O#ÿÊ­`@›uk¹ÏäO4o\ BBo÷Áåœ�ØÓÇE1YW9‡oHL˜#c,`t1@Á¨O(ò$®µIèŠB"GmséÙEi®šÉÊqëž.¼{l\k£9–,lŠg‘Ÿ)ê# £kÛŸ4´ iWö97³hØä}sRŒŠ“ú(ĨÔúZîåÚÜšD•ÐXNUŸ×¹<Š�*<Ú0{F.šÄ£îúÀܼyóÒ¥KøP ®FîIYÆqIé€=0KÙPûì¹ë[0"à8l¡¬øƒóÖÉú‹5g*Z%fîš�F /ÜãidcäïÜÜT@ÉÛH/ ãüoêM®yˆ¹Wüƒ?O×étƒb‰…˜eÇ6ÓØ׃ஒi/—ù°SSSß÷}ß×ét~øáŒÐ'³µ§È¨¼#Njl¯iFµ(Ó7M¢É;ºÆ!ç0j=ñ#i5;Y°‹u£=X‰!†%M+Çý+óÖÉìo,»À™‡êN†? hXq„cÖ=g g:#ŸÝ¤üÖ-R¡e>1ûǃ)|®¢å^²Z‹†™Ñç§Cg¾H ; ›HFÎkî5\!_‘³óa‘òHD©�xF Ø/¾ø"“FYž×uiL€q‰\lu`1*hY~3à ûÈ@ü¼Wñ[B¦4´<èã/Ж™fÍÙ¯ŒÚ…:ÞSŸ´Ü±ÖmÇví§YFÄ’Û1žiYX抆Ã!’ÒýEh‹TG)²?{r™}gÀ0IÒç?ÿùÉÉÉpô-’ ¼énjxŒœ£ü„¬8UŽ )4#á‚Ë…tÇʇœC®rÀ¯S4™ÐpžâŠˆyF¹–ócfÍ]w3šØ$Æ…¡¹í–¸{K”ÒÁ%Ì…#³6ÜŸ’)^wï; ÓØ º5ÅÁ9á"ƒhÕj°91SQåÞBTuWÃ’?€P’Šê”ï‰!2síBÚZæ…Ðl{7·åÀB_Ú-òô¤M•g½¼¼ì£Ê€>hî 4ÞY'Î(”-¶Ä²¡S•ƒÛŽË––¡*ƒ2¼Zé]ÓÒcÀÈÔ^ÐÓ-W-¹3ð@Hù\šfövb@Ùr,÷6x ´ˆJ g58ó`000þ�?tÑÀAÏææ¸È<ì2Ú··nÝò¤…Þ›‘Fî,û¼#H¸64BÌà[kA¡{½^Â- ßXIúðçr¬*”räææf§Ó±DMÛ™ ¹K SÁJ…kRƒ2EßÂî)î Z{ ˆÃ4¨“l?ÿ­‰7÷<ãÖívOœ8qëÖ-¼èÁ|HqýE~ŠïÐ*qö’[šøq™7ÈÑo:@lBˆÌÓtÎËn12g7Ó”§�Y ÛA•L¸x cd0³™³xLdm„òød“òE“Ä}VšIÀ–Ö/ •ƒÚÈÎJš¼8x Iƒ‘.“,+€¶b»egÖE7:¯€Ú?²(û–q™vÐ.¯TÀÌKu:ÅÅÅápS ’§r¯œPò(‹ˆòq®DM¹Î�f�ÖǶõ}‡+»f_Ñ´{ÉT iXÛ°t¦§§;–>_©æÇ!çð«%8ÎZL7"å-s'‚ÀßYCÞcü¹Ý õh#V.±Ùi°³8‹©÷?ry–œ™™Iƒ$KŸOGªe=´üɱcdžÃaŽ0fÐ<Àlæüü¼¥ÑQjëÙ&]þû#Çã¬ÅAqQntÔ½y$挕hÇÅP›ÆÄ»‡Ð=¨ðÜÂÉn içà$Í»ãħ@´ ãëæG™“Rð@(OjIšp Ð`¢aÿâ1jÙ) Bk)L‡çvÐ*"l-”˜¹çBMꥌ ÀÉ}@ÇÛYÓýÑ¡!<Û!Æþc6ZÍ’v(rÑl~h6Ö £Ž|óÈ´Á+\;³1d;d6ÖÉŸíÞ 3\Œ‡­Pª¢d&Iæw2²ƒ¶!b¯có‚ïrØÞd¡¡í±Á,‘¤3îãY¶È’»kæÄ,òGÎÛ6‘Æ”¤vÐbÝ£ìž*'2Ô^z†ÃáóÏ?Ÿýì&]b…Ð^æS»æ¯óß�� �IDAT( ØÒªi�NDìßC¸Qà<ý¸™/+ìa % ]ð‘s¸ëƪÀ&½ûÿÖ1¢+“OÄiËœ¿p#]uÃÌ“$¯R´ß¿x$«X™™uiŒêÁaî°ÕzJrfQ�¤ÄKkÌÀEpR¨ÍÍMø/.bÕ…Ò X2w;F…F`‚.¿iníL³rÓ²èÓ˜³cz‹õ ò L+*dª—€¤–,¯m·÷œxAa/ª,×~¿/c®vt,irAàY" G¼kmgÜDÎ>7ÏCŸ¥lGúÞ8ž3.Ãâ+–å(¶ƒt²—pfsÖã$ÑSΤrdÐEpOÞe;ƒŠprRÃ1Œmʉ‹öáFëïÎÜÀLá‘hs~ù|ôiëhm­RO±´ƒz9§Ìí¡P\ÃÍ€w–šûÌëç…Sß(ÙRF…Áåï›èy”â|½ß1#ÎFg¦SbØÿ0þa…@És áQ_þœÊ 'i¾.\êH=šâÅQ ªIÝ“!|šDȸI‘½H™¹¹â{ëÎsFE=JÇÇ̰È4¡‚AƒçÖB5óÈ鎟] f,Hˆ0¬�7”3¤¼PÇs9‡üEc Å} ¯Å”´Q^×d@¬ÉǺÉ3£xñD0h?.³ì©©_6OI -21»=ï5*׿† ­Tψ˜ËaGäN¾ÝyU¹O·‡àäÖœ:æü±ÕÂ\™€JÛ}„@N‡!s7ll%É€HÞ_çl 2†Ìòð‘[|�«‰Éë†Mfôå>M“×CÉ ¬„oêv†‰C ?¬:«+!㮃©V–Þ°÷ÁÏ,Ê8VØ9ÛŽ4�ëÊ󧩪9U­ÿÆ& ƒ?k;+Á®Qð_Pñhå šÆ¥ ÅS‰ü´Ûíš*©3“yõž¥Ç“<Œ”÷,Ð1Ç•S®Áz LÏð.”wt½êà5xb,¨]ö‹ åÞ쇈­«œÖ†Ã“?þÃA“ÓiOJÕÚæÎιééóû,ɬ©©©ûï¿iiéÙgŸ½uëV¦fwÅÊÌx3ŠœÐétbGæÎD ñ‘d¨ ÏèÈ28’mBN„If-êÎ-íG5N“AsF¤r÷7 BMjÌêg”‰ä›Þħ4QH“ êp¾­Ïí†J¦í ì?}b|ôF}ÁžR ?ÐÈaa3s Ð”j2ÅIªî)«&—kn~' ‘8‰ºAœò@=>UÍS°ËƒõÅ)¬ qVºbðCñ¼WQÄð̼ \LRs†žê–kКsü˜˜˜xâ‰'ø©YNÔrLC‡Ãí‚$ ê?- F9 «Í9MŠEíòW'NœØØØèõzÙz&"‚Ê–rxs9êiûgÆ?¸nŽ‹\?*sL³ÚGªx¿’cCÎ!}]»vâW~姦&''ÿA¯×ÙÛk­ýþôô7&'_³»ûù½½_k Áüüü©S§¾ùÍo:—wyÌjЦ‘7Àw5<&ÂÈ›ÖXvÖM»%=Æœ€]M"€\CÖ«Ù\AŠJàd¬„„.—Ä}0¯×;>`%.Aç?�—ç08¡|('ÃÍ}3¡™>ÓD-EIÛ7€ xØœ±in×ÂÐçœZŒÀÓ-Æý9³Šc;(Ýæ‹,JwÔ Ü7”X™L$£¤°÷¡[“oïλäqóÈ ,S‚»Ï-¤ÇbGáÈ#0Áƒ,�G&Ëð¤xÊ7nܰC®QÖð¼§�E4a’ág°´Œi1‹Ñ‡bé?îÃÚÚ"uŒ%þP&e³~µŒz(¶Š`9±7 367!Ñ«0 íèã•99‡óõôää“““ïÙÝýÇKK›­ Ö×ÿæÖÖÂÞÞÎÌܽ°ÑØœ˜˜xá….\¸™‡‡Œ’Òó`{G¼ËàuÁ r¬Ð&¥Ê)Ó$/Tñ.ù ¾’QZ6nløÂ]6ü¾–óñÐ8Ë\°[úÚ3Îba’„à ÉG»ÍرLwØÑÝ 7Ÿ>¹²ª®ca%+½òÖ÷ÝwßÎÎÎ¥K—Feêsœ!Na_�û ó#ró,»ÌYOÅŠœ’0ø .˜8å­rf8ç,Á8@“Mq«¥ÑY¤¯ðÀSÕôÃ8ñ’±‰’¡IùæÕ«Wy¦NØñJÈ»¸Xôó"B€øw%êlo«Ñ[jº6¬Ñܽd6Ñ5À“4rD»¿{FŠKOÈOÐAËó¡|(˜Ó„±€xäF¬aR¨CäŒCη¾f÷ö^»·÷ðñã_yõ«; gÏž}tm탽ÞÓ­íœ@Ì¢‡0Lh�.{öÍs÷QF‰�>,2½á–¦ÿ¼¬]¯œà£ƒÍü&²I”—hJËäŽ;›»}û6fb1n8~üøÍ›7ƒÁîîn¿ß·˜WfˆÚŒµòA 5¸±\¢ -ÜmhèÄËß»éRÛA(&x‡ÝëgÄý_\\|Ï{Þsùòå}ìc@(ÑÜ1_I·ÛÍ+c¤Vœ#&å Êm±Q#ýfùO<úШ àM�3JŽvTŸá\„� `ÞáúÆýv뎯 ›ñA‚9ˆZÍ¡X2[ˆžP¹W´imCWˆ (2‘Êæ‚@ájÌ‘ Â^jwcÛ ›VH†µaýP—ƒâÕq # GegHŒZ·}%7:©¬IKCÎá|ýG;;_[\|þ-où/Þ÷¾£G~ä#yøá‡ÿÛíí/÷z¿ÔéÐRæLLùbš¼S þ;*¬|ÐÞ¬O·‘ræ`źªp]šäÔY£öF+°°hèçÔ8yòd§ÓyÓ›Þ4??ÿÐCAdÈ«­¯¯CF°Û07Š–/‘�´@Þ+È�§åÙlgÖ6Ä$m‡ãnz«{0€™–ß±¤ãå±-¨hëëëŸúÔ§666O„`¦§í›æe3]äê‡8š@n×5¢ ™²ÈÙÙu©Ô2%šÄñÃ-Eü;ŸÛ`ög_¢yP„‹Šy%=0SÀ©hó‰Š×Fq¨²ÂlÀXïJIOÀéu‰P¦% EÿÛ›�½¶¼édŒýû©q1<b3^ã¬CÒ‘<PKmÚÇÓJ%È:¤”ÉØ Ñ×F|¦>¶¿Ñ8äò×]wÝõc?öcïz×»"%ðÜsÏí ‡­×Ãò„“³ŒçjšEmŠ�U,ùå‘uãþöÒ Ÿì.q“ႹÈÖÌU:)^ÈTfe›­¬¬lmm={6cÏVz{•ß³xÆLHHÍwó¹(3&n¹–ô¼˜„:õIäZÍ“€æüå¦qŸÌçEÒÏbG½··×ï÷¿öµ¯1žYì)ŨhE8 àVä0eä÷]§rOJã„eƒ*>ÌFKq3Bòaº¹‹'s K±H<ö\ÕŒs2³­|ëÊÈs©f°Ôc¾Ò0�‡2 ·üyÚ{¦ÀpOˆ –¢vñ>BÒßc’ØÂzÀ,˜&Y6d¹Q”±ry!‚znÏ:mÞÑzíÓÓÓ§Nzík_»±±ñä“O曉j@šàÜ‹‰…øqÈ94’4&ê7oÞìõzS!¶Ë$ ˜{mm­P³ìò2SøHÁBú<~üøÚÚZŽïâsìža5à)w³Yë\°¶ó\´sUz­V»š›› „>ch¹CUH³š*žø¨!m(ÂJò™hÇìX,¨ ªÃÕÒø1‹¯ŒSÐ*0kˆ,Ø%Ö0t}ÇÊÈFA¼cìéáGg·Ím5F.Œêצ Õz˜^Z\¹æççMh;u3ÏùM™–…ÁÁxÛ î®»A‚_'÷!œÉ FÖb`ƶiĘ ÏÅ(y­ù`è8 ;”&c³“)‹ÆcÙw6Äb6—è^€\àD„6Xئ–E%b¶ýR ]P±ÑE½ÿþû¿ÿû¿ÿüùóÏ=÷œ¹E°ZÌrß6º0V’>ä¯OÍÍõ¯_ÿ›W®¼xîÜŸ>ôÐC=Ô¿páßöz¿Ðétwv¶þöŸ·ßqÀp3–æÉ“'ßýîwå+_yôÑGmŽkúØ „–FgWäß&ìzÔ.?E‚09ŽÏˆ&O—\i‡"Ûή[Ùqã&ë´¶´ÉHîíç0!Øù [÷—c4½ó�.ðÔ›½±]0Ao³Ã]ÙdˆÀ”sh×[›À#pUõƒöØGÕcU9…mCÇ™®¥kˆŒ $W€+ ¥î¤ U†ÿy"¨lÌ¡|£³Á’gð”iájãËèv»ÇóI'¬Ú¬Œv ¤¯ÝÝÝ?í÷çvwÛÄı½½Ù½½‰‰‰~kƒápbo™ŸÛbG:ÓìyÈ]…2Ì@pkÊìvª .ÏÒ™e"¿ÙívyÒàíÈWÛn€»wýúõ?ÿó?¿zõêòòržNöc!°]xÖ€FöÆ!ç¾Ö[{nròÍ¿ök½K—n~úÓ÷_½úŸ­¯¿ØÚµû&&¦d KR:d Žh ©`ône^¿~ýOþäOÖÖÖf*R›fÎãðžq¢Ê5 ‡ÃðJ_‡=ŸCc“L f.¬GèA‡fÍ—ù“jÀ Q…²14ouÙcÎËxSúáíàø-ÒU®ðúelˆx0;;{ï½÷ž>}ú‰'ž°Y¤™f”i¥ØöŠxã2ˆ1¿™^TQ€h`Ÿb!:ç;vß}÷ݺuëòåËY ôÕ-!ÁøHšLPfù>e%Ù=âo 6×Xmô*áŸÁë-%œØÁÎ~†Ëèó—Ow"'&&æööþ“n÷oLNþðææ«vw÷ZûÊÔÔWffžÚÛû—ûDJ¸ÑÞ/&ŹàÈNó›2õqË{“OðhŠ+<.MÖôdf™?ÌÄscœ-{{{/^¼|ù2rY£~Hù}\Ëxò!òÖÆ!§µÖ¾kkëþ™™'û{üàƒ»»­µÿszúÅÉÉ÷loIé¨vÒ,î™È ¼nãµóçÏ{ÀŸ2‚,f†è^@”´á é@`_ p†kp.~ ž;cká9ŸhaûƒÇ/ë– A6ðå¢nWÄ„`Ÿ³CìžÂ-åT‡Þi£+#¶¿£»î}h`Çʘ¦'&5_i2ÙŒÈZÑœ¼ù:zôèÚÚšliu,--9sæ©§žº|ù²mô:Ža¥´+h}ÓxàÜtBP4¬ÀçÍcºóÎ;®^½ Â�mÑ–¤å9�Üì’` Oá0ebý@¤‰Ö¾gw÷ç66~®Û}ann{{ûíÃá¿éõþ«ÅEoOnºù¦r±~˜'+·™î€]~;z“T·L­ÚúŒa”Í´Üââb¿ßOåjng—ÙØLböpâHÒ3V8Ô¯S§Vñ¿ü¯ÿu»}û³GŽìŠoúµéé§÷{9dî.,E0å³È:ô|÷!¡H’·T1_%"(Ä�S’P‚¡‰ Ü̦*ò”ÄKò5Ä•­— M?Ö"7¥²À%Õé®-+L‘ñ7Ôj>jÈí§™•ãÏp Xg G`(˜qíÚµ«W¯Z@$|’q³àüYÒ•AÍ“§CÎaâ,ÑÚŽ¡æ±rìþwûöí³gÏ^½zÕÑÚ@Š]“y—€l<t7&=œdéh(RhEw»Ý·¾õ­¯ýë?üá¿øâ‹öY ž ͳ¹T‘O¥ °ËŸÝÛ ¸ÎfÝ.ìí½{gççæç¯?~ÿ‰ׯ_ÿÌÆÆ>7÷ƒvÐÆ­I-ÿ4w^Í\'8†£¸QL†lU^Äý<vŠË²1ïÉ>O/åa?~üèÑ£É ãbŒ„ç–?~%SÒ‹2¢—([,ˆÆ!ç¯÷«Û½ü–·|$)ØÄD›˜ØÛ?¿…Pí.” ´‘ZñieeN3îà\ÆóhÔYUá¡B&»Áù†t*¶…)Aì^P{´}¡¹&aæN§ƒ¹“C]ç‰æ­æ¬'ß{ö[Ýn%ì NüQÊo;¨eh;€·‹â�(ÖGO®3ßgpÈÑcù…qN GŸƒl7G?¯æ®»ïÕúúº‡…Û¾ÕÍæææúúzìG‘ €jEˆel:M{ÈZAl ¤˜Ëï÷û}û91¾óôÓO_½zõÚµkyŽÀ_8w�ëS1çïYÆãÍ‹ñ°NÕ¢*:³­}Wkk÷Þû3?ño~ó›?ýéOüãüÖ­7ol<¾Mùe"Ÿ½_ÛÁ!ÐèQAÈä R©˜DG0³ÜÙ¡5RQQò8­©ƒÔÓG’N¥Ø-º¨6€—œoqq±µÅ,z¥Ýn7èNøÆUÎ!¹å,ȦrÃÅ$“‹ÌÚ,tøvÐS‹qÙd—xv&„¦_~ÝÇ\Û×€2þ㌛‡n‡' 4s‡<âÖ=K3 rU¼»}6¹&p3 @ü+MQ`n‹µ¥GíÌwò¬¼RºY4ÚÔÕ ¹Ì%;Ñü@ã„2fb í lL~™Sž²ÌÞ6ò¡öm¢vÛwoÚÙÙéõz%®NP+‘\$H/pV>cn8WXt‹yp¹o/¼ð¹sçˆ"ùD‘ù2e+Ë,·ÅWX¬W»Ýn€&“< ÇÁ–nû>¶n¡Cƹûî»ßô¦79sæÂ… kkkÖ¶°=®ÍÙ¿h²aaG€Ì˜ñ§mÒqwñJ{ÌÅ=†”YnæµÖæççÉ{rߘ[¦XŒoo=Ž©y"×®]+ MîörªãsÈ!‡´Ú°’[ 0>ö€®“2ÓL¥/Ç+ƒÑÑìŸD}¬Àÿ)Jk¥#j›Ðy€—œ×VåâwËÚpí¢‰ÇeF‡[.{Ã=çtnwQý°ù91©r²ñšcA±L´5JμÓ‘¼Ç‘†×áfBLÃÇÕ›[Æ9-ùê5e79 ì/®W�ÂJkÊ V~“IèjM:iXi °gv Ùdîl¹²·­FnE~Ù9²¾¾> šl ­MçHÉ>ÊŠÊí%r“Eíì쬷öÙÝÝW<ûìC=ôÌ3Ï<òÈ#7oÞ|ïpøá™™WïKA#t‹¡Yé&¶ý¹é™™™ÅÅÅpÀè~Ùl›v¦}QIhlRÕ4Z<F]ÓPYž:uªßïû¦5Ér7MsaÞ›ÙÈ‘`'Xš1hÛ¡Bìþëÿ›4ÎArdz‰ÎSŠ lFÊ!>'4눔ɻ„+- ¤ò³†’JsäAo…G%ä�f\ (—nQ5ç,¶ñmºdÁáí”)è\¤%|- HhÎÅ[‡”V9¡éuŸãÀ–W0½-ñ;ç¾¹M®µÑµÉ]6ÂÊ]ÍqFÚáRÌí(×pFØ‹é™%phé¨Ê°žO«#›[e8gÔ†¦÷ÙÀ¹½ypþ¼TŸn9�õx<Å’w¤VØ:ä¶sÓrÇŠ›ú4ÀqNçu¯{ÝwÞiÿÊ>³Ã ÙÔm «³ËÖ'&›žþ•+WzögúЇ¾ô¥/ýx¯÷Ï××ÿ¸Óiò@§Ù"ë»ó¸———c ™ÇÁt”gtÜ É)_ˆp&1–‚ÞøGMªø„^K ŠTó܆»3ópÍàu0ªä^Àf½Ž«œCø2=  ³ ÌŠ¢)eÉïÖä ¢¬v¶•nAn6§Ïh®|É ‰m¥ f'$éC8 }#Ò1®,bì¹QÈ3aSR3{ogß2?Ä  ¨ +!(§þÀåo„ÂF{Îå.¾Ëk2Kè)Ô—å1ÛA<R"Üj“ßr¦#ÔÆú±³Ží³|¯@>Á<ÍβÃ&¨N™µƒu.,Ä6jSß Ä•‹mA©¹IhÈŽù€ô½9à¬ÿo—¦ \jÄ„¥ÍÍÍçŸ>ý!ƒÏ$.¸¿Ðc§Ž¡lr•ÿ’¨ekç§§vròç¯]{ÛînkíÃSS?Õét÷C;4k@Âùùyt˜ˆëÈü´ƒ¶XŒ²ùèg®+ŸÑUˆ]Ôlzm¾eìtI³NÖ××Ož<¹²²â™Ó¼£ q™²­’¢Ù]—Pä hëˆtwrXsWÙÔ^WV1JŠWBfˆycs(¸OæÆ4ƒÙœì@ÎÏ…}%ñ B’ñ:;'ý±|,'KT8í›â– ÇyeÞ=ók“““Q(ˆí1ʵþ²F'ç¸Ëw‰ 9pèäÁ‡ÿmë6tÐgƒÆfÔžsß 0YýymŠbòô¼ fñ§ÉëóX-Àå&óèôF°/£öÔOü¾å隦P­º”U훣ǜ~ŠvÐnƒ3ׯƃ&yb¬í«!àgÊŠE›ßåa{{• 2 xq'j s ÈþÊzûòÔÔ? ²#¾89ÙZ{ÅÄÄ¿µÕ¶¶Ý)kjS‹]¦LÑeÁP%] yb*€)(r&cËfc[©Éž* ÞZæ¦å+i²ré ç–™fÍh“&Ð8ä~­ݶH»©Ž‰±2Ÿ¶ÖÔ‚îéî4g–þf(Ð2±¡µî¬z’öU¹±x¸Ñ’±„%ýŒ2óou€„™QßuªõœþÙ Àef“[€Ë3Ô… C4rAÛ-GMúI­cbA‚2lWœd–� ÃoIàü‚'¨<Q[Tp,7Âa8!>‘ÏàÈ¥¾3Gôìr^äq#äê±ÿÝ“ Ê Ùöž±ê(ġ̥š`íºÇ0W],àTÛ¦§çóG {8’šä‰üÜÜœ!k ôoñÙê+›Üa½]‚(âR„½¤Sä.eN–Á Jïä«óŽÈM´ts=W®\)JTV ,"­¶â…–br¬³(0%±‡œÃÖ¬ƒëêÇÃæAjÊršg:Y´v9û<%@+ü×xš§îÉ.íTHCØ•¸U­, ÕdŽy`qLOà #k¶"¡aº”E9ªPK¯# Zl´T»jûFU€…ÑäÕZ½™ÑGÙêÚ‘O3ßDƒÄ~äi\åzräef…Á[JæÿGmèÆ1ío¥¢âÉm݇<ÜH§ðéøD¸JÉò·fm˜ªÄrJb‘ëÉ£Á§ÒjßMö¬”Î9s“Xr‚9jOÎÁ]H:fR±>ÝL Íý¥Ñ­1 ¼|[UÍÍÍ%'Ëš››[ZZZ___YYaÓ¡]cû+"¤pRRÕàilòä™57óÊ›››øNåóF_ÊóÅäg »< JRòZ·I#P 4y/õ–Å8Æ!çÐ¢Ž§ˆáG9¹°¿ Ä¡­ý¯ÖZ†À›|h,­_\¶l­Èlªx±õ=Ö^N4wnlúYȬÈB—*mO@7ERou»ÝùùùļaÀ¯rßÚAwÏF€#…_k^YÛ÷ÖõM£‹ðI~JFÉ‘¡ ¯³¢Ë`K7M#²±CWå}ó‡ŒSÐÏðóud™p�œâž‚Ö¯Vl.#n”µ(jžqA†Y™¥ô)õ«—½esÇÂÏÚ Ù`6¿OXƒr®´˜Ø§Ö4¨Ku!Á!Ó*MZmôì<==}äÈ‘ïüÎï<þüíÛ· íúÏOomýâ`Ðkmvbâô~âx~r²ííhíït»ÏÌκM›ç@jº d<–Vn»¹r,6KKÏÏϳ¢Ü=²o:bsss¥ŠEÖeŠq/çÛ¢ÊaÅÖû”‡Í…w ÑLƒ£¢›¢GM,ö©í5Š1iÇh)S¬cV„u™@$CÌë$_èߤ…SÆ*ÉÄ­¸³³sçw=zôüùóƒÁ�%®Ò»r¼!e¶Å$-¢l�ÄE. @ý¶&N[ˆø%%m!î3)-e(ǽ)ePÆ$„A]+ô• [ ”@XZÄdÇâÌþ(}p]b!g=·4ñ¸µ6 XÛ¦KAìávXm'„šè‡î„ 7;\<7©8-µ‰þ¬Ë f7G +¡3Ø"&eÙEfuuõ«_ýêp8äùRsç#lmmu''cbâ™é馦~twwgwwow÷ÃSSç&'ÿËIßa5j@•Ïnr9±¶sßè5xK&±óàÒÜ.ŽD}wwxvùåÍÍM’ãqÈ9´/w;Ür, H3ªÛÁ±Mc\ðôu~êáv+zQÁ¿/{XÞª­¢@ÉýMï7‹²ÂŠ’ q¼&é'¶Š-¶vwwÏŸ?ÿÊW¾2¦çÎ[[[sç!!sÕ8AÀ,»âùk s^0ÅÉ£IP!5ÉwkH7Q憢mL¿ØQsyMÚÆÈ% ­Ÿíi),,ý‰e$U²»wyÜVŒ¥÷&½õÜ =’%á9ܼ t[õ¸ @Ôg±YÍì^<ÇŒ-{/X•À+ £<K–yfǼK¤»ÉÒHØ-$Ѥˆê²’pÌÊL4Õ_¢ ììLNNþ[[îvÿÑéÓAáþùêê85Õ6`Š“±\“ƒ iZñ¼—{îD‘êñƒ"Âl“„šTáaÕ[‰Çí´ñ\Ρ åðÅD4Ò)>n()¼nš<_m”IøqÃ0ù)19m_’„cˆ&е`ÃRãpa°  ï.Jð÷ýéb86”ù¾œwÄæÁ`pîܹo~ó›­µÅÅÅb‰^äc±Üí|„íõõu“�½ÇŠ?\>p9†‡²Q=÷CŒ‡ ‡ ˆ›íù¤ìg†Q˜ˆ´êï‰s;ú*\,P «.ú.™°Dl° ;4_õb 6ó�� �IDAT%ñY˜…d…Y“Ä]×âNPÌ›°¼Py4ØY¼<Ál8†É/²»_6ƒ&>3 GÆ–C/)jt2Ø ²Y*îó@ýƒÿãÈ‘/½éMïÿûüÇü¾ûîûŸ^œœ|×>²J§Äþùåˆw±^¦’ ‰»2&×™™™ …ǟΈ¥að4{#Yù‚†ë˜>pÈÀ"›gΜÙÜÜüÆ7¾^”ƒ‰n‡ý íý×dFëñC«<™ñLx !2†Î&'£éí"Œb+ïÄ�U|¥HW­ã›S2¯)'Š*'}HœYò9 ãÅ‹¯^½jFVŽ6î'Õ R¶ !ò%ƒÀš¶|Ž zøžGa¦¯¸Q>º…–; ÝÞt – vdù,HÝäÂ@±ìê–d7°¢[Q\!|U°QPòGñÁkƒ§FÈ7×ܪKP¿¨-˜ µ)“ƒåja¾PN‘Çø %~¤“GŽâ™6Îw/'®*„» ú4±:ûðxeReB�Êû(O6íÆ#GŽôz½ååeH†,ø8YóÙ;ßš—ÚÞ~`w÷Úñã÷g~æ‡~è‡RÁÿñÿñpyùôpèy~wV Mª·½ ÝD¤} sÁb‘ÅLÔÉ*0psÚ‡°ÑÅü—¼ãs˜½œÖÚ}÷Ý÷þ÷¿0üîïþî… ˜`L„L¶t“¹ºÑ¶ eóÛ˜–6²û¢Àq¾²OØÞA¡¯ ÙŒÕ¨_o±….d'-bðeÝ{Bac€£€�÷3×`¶šë!|‚§Á‰òÀÄè±kçþèÇX>’_@&Ùô‡äþ&¦Û L¬ÌHÁSžÒ– dtqÉó¿m¯ÒúS�R™•TøßþŒþ¤Vd@úÌ®k�˜YKPòaê s×d?‹Õûò±Ž»Y~dn¡[Óí"¸ Ýn·ÛíÆW×4#kœššê÷û–ûs %ó-¢ih&ÛÛ·nݺqãÆÊÊÊ7†Ãá·¨ù;;mG…2``“¾T¢2 £Hsòd‰µt¶€¦­=ÃT¸$6…‚¡jcSx‡œÃÖ¶··WWWÿò/ÿ2^Ôž '§öhˆ¥¢ìÙeÒšÍr Þšuã4oÒGµ7³käâ’i¢³%囬äÌ:³2)¹9ÍÌbi%Aoiº&îÓ˜ÐåÉ¡L¦ˆ±Ú?ù&Ù7Û† o5uÍ,s>c™‰áÖY­Äâ& çb(Ðä„ÄôŸ_“Á:n8ºôö6k�ïmÓ– i¦l4䪅çn—eà+¼™èh%M ¬ÒKwÆm¿å÷ó¾pçŠq*±§í¯ÙÁ¥Q­DbgfD¸ùùù7¼á oyË[ž~úéÏ}îs8±Û›ÕÕÕ‰‰‰n·‹ÖCÓ´uÛÆÆFZ§y­µNOÿÍÛ·ÿŸ?ú£³gÏ®®®>þøã'‡Ã»vw¿<==5==)¯3JìÊn·Ëò°9éBé/ròÐ#Ju$Íu3ý$ÏŠùÙYâÚ¯39‡\èìííݼyó“Ÿüd¢ 9èˆ@š2/ í»‘tû¢5‚N3´4všus”€~8‹¡ŒÀ’V3ÙhÛ׊·`“ÊHæ ¦¦¦Ž?žåN‰–j,»(GdlÁVWWûý~ˆPÝ 7óF^Ó¹¼;Á*ðåÜùÄbccƒîÔa¶¦XúRN$òç~"ÝF(u‹.­, ›zîùÆ� ­@cz×Z¢PŒJiB ¶N¨Dëëëôê(=9¼èz-QZ„ú³,yd˜CØÀЯcĘŒÄxjjj}}=Å9¸aCjDî›U… 8˜@á´†‹)ÇÇ;ÞñàƒÞwß}_ýêW¯_¿îÒ]‚w¼†û€Iezà;2’´¯>33ó¾ÍÍ»žxâ_¼SöO _žœüÚÄD§Ó™ÙoÇúùoõ2êoUPøGñË< É_Ûaƒ]Âì30Ý ~¥œrؤarù‹X²¶¶††<%KÆŠ‚K 7ýÜð0¾– ãô®²éñäh0%bÒôôôÂÂÂÜÜ\¯×ã¸7PK5 zA,•’ôý÷ß¿±±Ñëõ2˲µµ…(ºõCoÞ¼™–ÌÂÂÂÄÄDX¶%‘?vìØÌÌÌòòr&=3‚G>5??o zˆgh¯!¦Ù4š †�ćuq“üINjn}N¾ã|â2ÌpÜá�ÿ´×ƒG"Ê„£ÙJÜÚAŸÛFÌÌÌÜqÇo{ÛÛƒÁç?ÿùµµ5hKE–±ø¦PÔB½-,g<\žWï(’› ƒß¨²GŒ©Ìät?Ò¾†ˆÁŽ¸ÃŽ=(ÎIùÈËËË_þò—gffüñ¸9´ƒ’žß$èîI<¨B(7™xjoïçççÏìî>}éR~ôîùùÉÉ_ƒÁî>“žR#2ȇé¶ µ©<ieh‰–ÒÜÜÂ6\ö 1Œ~!›Å[GUçÛîœor³Ä1°ÜÄéÓívmèÁúné§´'´mÛÎÉQÂikuÄ4i ¼ýíoÃÞð…/|á‰'žh-n˜g—FF@ ËîÂ… )ŠûØûRÓÓÓ¯zÕ«¶¶¶Îž=k6Nrä'N;v,ƒ÷DPB‹Ç;ès¤¢"¥[S,~ ó¤óEb W·Ø'ÌÃvÐ/™ ìlš‚W9 -|¿�‘4 ×;s·O¿8¸­È²:u껿û»WWW}ôQNp:%‚r�%FBŸM¤G+ÏÕƒ´œòä+9ÓÕ‡¥F½È^ÈGp6“oÂ# =â¾yì¦ì8„PÑ<mšÌ5 W�ÆõõõÇü©§žZYY fkjeÙDÌðšEÒ¡µB‹'oúìÎÎíì|`{{bbâÏfföZÛÙÞþÀÆÆÄääÖÞÞíýÔ'—šMê7*•¬ó¢¬È’¨ðÌ\æiò<÷;Ö¼–›ç¡pFåzœÈúûf©ŒCÎá”8%Ì{Òz)u.$Ôù¦_Í´Y:d:Ì¥stBƒ.Ñl˜(˜---Ý{ï½'OžôQÝnµÀšéRy£Xí¹ÒFôì$¸··wíÚ5Ø ¤r9®_¿ðÍsþiΛrãî‚{æÙí ¡r~²øÄn¦94y¦¹!_ôä]�ór¦ó-‡å´"K“œŒøK[Ë3@|*æÅÅÅÛ·oÿÑýÑúúz¿ß‡Í{¡‰ Ù©IïŽOGº )#'´Ã28U$PQ>%¢£ïY˜¾¼©%3,'Q¾é½6ª ƒÈB“Ö*ᄸž’4%`.Œ˜Jº`c7Ñ3´™“5ãó¿87÷Eõáð/ŠX‚– ‚(¬È¢™–Uêê„IµXÌÌV¢ÐÙåTh Œ®›öV&”ý(Ç!ç09~x䃨ÀÂa#½$¢¾.PJç¹F8±§lÂ&Éjïdw€Ønoo?öØcÏ=÷ܵk× SÇø0uÛÉ€u~í×76^}Иdoo/û‰_ètÊÁši|Æ#nܸásŠÏ»»»Ûï÷WWWƒËYìÒÕ€ÿ„2Y ñ p±W=¶ Z Ñ ;Ö0<‘œhtï‹B3Í^Xé>nÌÄkû–è0ˆСSE‰Æ]õPá™3gVVVÎ;GwÍœ’¡·LÆ…äbÉzŽìàH.­P˜sãh#7§Î6†}Û÷ë´ùBB£[2(*;+ÏyNȤM’6\ -ƒ[\xôÁV…áô·A€)öÊã“ý¢;ñûرcsssý~¿ßy.‚Ê›W£ëø‘ú›Á ƒüŠϢöäõtj2Zp‚Qär³ÐÉÜ%G¢þilG zqÂ’¤j)ÜD’8 ¬ê<“uéÒ¥›7o†ô OŸ®’o¦çÌ…eŸ¼q{û';WMLü½ííïßÞn­ýùääÿ=;{ejêw²*$AmœÖ€9š ÉAçÈ‹=/B iÃJN:þ]E™D¡<¢—€úŽÉiM} …?uª×ë­®®k’áQëÕ€þ€N˜z™M[X­m_„—ÓF˜a2·ÂŽ�Æú666¾þõ¯‡4ÁË–¢­kŽH˜„6>o˜ /.·ˆA×D û¹Á „û€wŽÙ’M&˜¥Rða—³vÌÌ9˜›Ll.Ýu×åÌ» ßLŸ)zb,°<A+áÚSÜÙአ‚Šy$‚§îÙ�$6 ía{×»Þµ¸¸øñœ>i“¡ÂaÉ­�Q@MR;äfk»h3~k£  Ž¤ð•J¡?9‡öEÓÒö×ä&¥ñÓ?*l–™m·:!Ër«b Á)‚ÿVêtƒi£&=ß:&&^¹·÷Û¿pôè/ÏχÿÑïÿoëë?»?ÛÌ®öP/î‘L0q.‰ûà„˾©©©Á``GHoB 9'¼—0>VF¯Éør'×ÖÖ2ÖjàÎOäÿcï]c¤OÏòΧ«Ouìã{š³ÇøÄ °‚0X!/JX–8Q2”݉²ÑFQ¾ä´Z’•Xb­–X« EÚ$@vN€`"vÁpÂÁ0¶1c=§÷}§ßcª»«ºº««{?\Ó?ÿú)³·ý¡ûƒÕ~§ºê_ÿÿó<÷}_÷u_—ËM6p9³9I–À)ìjÆp–Ç,âà¨ér­r¦�û²‘+·Ý”³£)>üĉ ¦ÀÚ{&“’¼xaa!ZÅ•úQ5ñ^Ù¸U€$;¢ê8³A€¬˜ø 9¥ð”>É8½Øf”¸ê‚ûîò¨’ûCl”5€MN93ê ]­Â�YWÉáhXŽ›óâ‹/6Ç'úaL:3ùäa>èB$¬­VëÊ•+P¨ñÍÚw!Î\ M³\´ÍÍÍ%;¼À“ö2ä¼ùà Ÿ2’E$é1šeØtÒê̪i·tú™œ¶–2´„¨-Ì]ºÁ¯Ð΃yÿÿz2ù»Ë˯?õÔ{®^½uëÖonlüíFãÏŸY#{pÒ“9àC­¦”!ù²7b^‰;�z9Ó|d¶ÆÇ(ÛÆ¾&žºD0™êôôtoo/ü:¡”˜Ö}àÃþ’WL=ÊÑÏ<|5ïU«·ÔF–`Aäõ¡žC¶+Í ](ïy²Žš®GT*Âí»ƒ{Üݲ™=PR‹:KpëÅq‹•ÆiKãÓP•„§ÍªS´H�ÍX´-²,QÃ-JA™rÄÍNÒ £££W^y%¾^´Æa©p‹ºa̳>88ØÝÝ%9ó„“ç1Œ¹q«ËÙ8­›¾Þ­—!ç‚l•fn ›0óîXú “E¿’GË9EÍǰ›1vW9?uìÙ=÷êÑÑ¢x*¥¼ïôô'žxâƒß÷}ßð ßðñüç~îçþãÇ?2íŸi7Áø,çMÒØBErså¼G�é›_ìœ6mgÀ´‹êÑX‘ÌVX¨yJ8æ´õ¦<Ñí¾]‘Þ¢ÉÖ­V /†ªT²„Á’CÛÖO€!¦V“§û>@žÆ É�•6E¦¼`]A6£5huî¤\¤+*Å ®Í…„]W{Ü LB⢾̾°êDÀSmâ‡"2¯è‘ÉYî3Ø£&{ÌÃÞd2ÉS\1«6M¯qZíb+WUum]RÒynÚÆëñÇ»»»´¢?„6®“ ôG*J-¼5þ«ÏºËsaôr^aHöRD´Œ6øâµ6«¹Â¸<<ï ˆ¢‡£Ñ£ä¨J{èÇJ0ö[¤NŠàG¢Ýâââ7~ã7¾ÿýïüñÇÆ /¼0göö\iUn+¶“Iè­Ng÷uÂ…ã`JKÖ¹ÿ42CÊi¡îàªã£°²ƒ³Ž“å"Ÿ±iìÈ•(ÜVòßébÂcUd!ÜÍÍÍ Ñ#[=Ï×é|xPÓPmft¨K(¼`ÕS‡™óæüN54Ù<Ár~<ž2‘ОªË"ßÔCîlCÜÈi˜[Ón#xYÞÜ4dp`Ê!Ȳ7ÆPiÓ9k±²”]>ó™ˆJï£Ïª6uß‘C¼R|°øŸb´J@ti%2ÍÎÎv:………û÷ïc`ñ:¬ñ_Ùä4,EP>Æ-€…-4•ÿJ*yÙËùŠ˜ËqØ ù"ЏX¥9Õ\dæ¹PC±¦“i >.ñ3WÕ&Óã“cZvÎ,c¸©ÒŽúÍããîþá'?ùÉ­­­O|â7oÞü†Ñè³³ï:£� çÅ̧œÑSO‚O´peãÿš÷äNRçÁý£¿=Ý-Èl 'Å´? Y6'ˆkweHȦIŠingå’°v[ŽÖ7(}iòÙ" "!5·©ÁjAÈ¡IŸ¯rŸ´§*…)©«¿øÕôIj1'žZ€iHtB-g-Z�À/Y�¨(tŽø†Ž”7×y?ÞJ®³¹Ã¨Ú%ø®b1¸äboæû¢‚Á08å¬I†(à Â27ýâh¨h“Wæ7ÄZL”øV³ÍµÅ-;aßÈÄ8Ó4ù¨Ã.o.X3á=– !óðÀÊÙXJlZ—ôWx ixåBÚ“SÏâÓöP©FÁ³Xi~æw YÍœÞiüžËû?ùÙÏþï?ù“ÿϵk¯¿þúÓwî|hw÷¿[Xø'SŠìFfRêU�Ã_áYýÚèÌj®¶êUd ’¾±í @´µ«·g§\åK…wd«o£q=NopÆ´7àŸGCÉ­~€]O,ª Χ3Á†CÞ[å Á¡9äùÏ<NKL‰rfÅšåU¥YnZd½£¶°4£¬Er“Œ¤Ø@3Èâ`vQrL«˜ª ¾f`7/Q¢&ÂÕÀHxŽrÊS>È’<°{OOO™`1­ÙãJ|q�@O¦m¬›g¥"3 ¦çd/µ¯ˆ*tÒR?9k×£l¶ {Ѐ%ex™Dƒ?‘¸q‰·SþÛ@“ig÷ çO¾87÷×&“¾ðÂ_-åøøø·Jù¡¹¹×çæÊáa Ö·çû^C&ëÅÎݳ@€-o-éÌ”oäý9r¬áÜ¡vt#ºXÁ-åÓvÖºöP§÷§=â� M9Ë› `©éjP‘q“ë9y¾Ž@PÔÊÙP-v%T$Bá$�Y³x0£ÅÀ:´Í]•3AŒ¬&Ï`m¡”Úl6}búžXRÏÓ342=EC+}P$ž(°l³¹LeZaŒ³¸œ÷ÿ&¬Rn&ºCtÊâª1O´�ÀÐ^DN_Ìœ.þܵ­Fž½W3,õ$ÁoqÖÈJö»Yì‘K%é‹ÿ± Nìæ[ ©åÅ©jI VbsÎVmZž`ð0f‘C¶ÝLfó¼'{Æ,;0gff^™ý¥Á ”Ò(evf¦qrò¾™™o;=-ãñ÷ñ…(�r*d­\OˆiKXd r·$À$ƒNWZZÞ?âW—á%ã§v»·‰�³Ÿdo{ÛÛž}öÙÏþó/¼ð¼�"“}_`XÑ4²P÷›:öª�ÜN#;6á \¾*;04¢òȇ. hˆAÝgÁ[Ž[­Öµkמyæ™O~ò“÷îÝã;þ™‹‘ÏŽQ˜ á3†Iw“S22¯ÀÅô'xú< "Ϥ|Ç6É3’ñÐö@å“pE{<ç/PmºlFOUÊåtbHVx”§@©„rgÈ8äAÓfÛÀ^ˆuÂL‹Ðûšuni¾&ÒVä+™‰ˆv*!û1ïü2ä\|¡C A-¸œiég1ùÅ–D4&ËV±|E4£>ðDE–i”#¢}s¦§° £§HîIFœUû×—–üVƒÁ nƒoNžé³1SM9Ï šÙP”ðQF›Îˆ‡½¿Lj°Og§I0ɦ}`Ѭ¶>¿Çp¡n _λu:§Ÿ~úîÝ»æÎzßÂt~m@©« Šä…Ê™dw¯J·íë}žQ§Ó©ú€ÔÙ)P¨¶ínI«)Ř?q'©†)õ —à,g‘"Ø‚fTB!+ç=:]¢åáÎ>•Ö�¯3wŽ˜á©[— «æ9åsÁEŠc(Ò}0-3+36ó¶Ru,qÐ2¡Ô>¨^ÙŠÐl 8ÝvâNV%.yM]smg¹¿K`킜¨šÃ»ƒó¨â8¹�€ªü‰n,¯ëž°©A–uáŒC„-wð}È-t;Ùöyö†ƒ„[÷v7pWÖýOgEãFãàà ‚æIÞó•IçÍm3ÜÄ •z“¡•µ”g°‹<Z²-'Oˆäææ&BÅV¸1a€ ݪ [x´…4œ[AܵK±Q{ÒR%Þq&à•³aUÃnäÈœþ¾x–÷ÎÎN¬-m„“œÝÒv~ô¸£ä¢"¯[l j% =­ïrÞ£ÓÀ²i“vI@¡À†œéyen¢/<ÆH‘~ =ㆊû—¼¦bÍp ¬æIäð @Ÿ å\؆CTÅ`4…Õg½Ðfóô~P©´.çr.þ'�½O:ðY=Ì[¶°ÈhŒ“6‚ù¤z€­d½t¤”)_8à•"s)Ò兇͙LÔ€Þ@sÑtjP̧̩ ™Ø!G…|A”>³ZP˜«LO¢Íîa—l ¼)=. 3ÜÈÂÓµün;pª™ƒƒƒ—_~Ù})º;„.Óöª¢“Jl“uÂu†žÔi{‹$Ë6EÎÔN A*²A2ôfâ>"À p%÷ÐF2ÀúÁDPG ÷)?-ÑMÒ“}a'/'{ªšáËÆñÏ#Dܽ`Õð£G—À{+Ñ9B`°3_Š;c+c_,ït–5‡uzXfö«u»Ñ)TplS¨A5ø^VE‚g™AžEUѨïeȹÆšžÚv3idŒJ¥ÝnÃÕ©¾(Øö¦{Ù…Åå3‰9 �§S1T’òUíl©Zó†ùsx ˆ<šäãÆ/°{NÆÑhäÖ1yÆ„®œ³gs¦!ìÙMÕršI¤ó6Íõ`¬ë†ŠTV‘8ˆ¾Їœ:™wÁŽãõÓƒPs¹30ö ;TC;ÑaCIÝŠ“=è¥û KôÉ+äÏeo/Eîã''ë§§¥”­Fãv£QNOJùÎN‡ØÏ8(®ÉÓfÃâyʪB•<*¡4ü˜¬\Nü3À£÷Ì–Ó)p%BŠ =Ò¦Då¼»œ>}G’9¨ÔvfáOctÆ'ŒÛ%ƒ\äs!#øP²iw6E¸‘ >ÑOU-U2ó9=:N»ÝÞßß¿¬r.¸‘s||œªCª"­VH>Œ•Ñ2EnÀTÑrÞkÙ£vFóÊ™cG‘¸gU{ñ/6O«®­’²wBêÜܳ“É$+Þý!÷h¨8o]XXh·Ûkkkñ„·Bó+•›YvƒÐ´`»™ÿ&fñ1k¸™–„2DBmä“c¥ÓéТm1Ú”®‡¥P˜×áIo¹Z$…pð<ÕQ™ÕÏžýÐù¯ È)ã’¸Ñ=Ë€Ëd2™9=ý`»ýñø-¥<ÕnÝ™Ln5¿83ó3Ãa%Š\…gK²BÉá�5—$gYv ¤¬,iÒÓËÙ@1ý4üÍê¬Äôøš¬g*lB!ŸÀÀbè*e  ®Å™üøXuùO™±ƒŠºˆŸr †ÅÌ"•%s²yRñ�û` ÐS†Ã!!‡Ìv”^æ7}Ó7=õÔSŸýìgM¼ 9rX ØÁZ$ßš¾îÕSí–3ÍöÊ—Â$¥Jß·È'£âX愪œ¹‡Áeê‘í[¦=uО¶6± Œy´Ž=9ïŽŽŽ¶··žHæææ–ÂûÝózÄž£££f³Ê ÎÖù¬ð”¬™Æ£±Í¢¯ßè?̓ ôWççç———yä‘W_}5ÃæÎUͤiórv8Z8„›õÎe#¢%Â3ыǔºŠGLdM½˜û< <xÈÐè—ÐàR?=}n2ùáGöÙ»wïv^ýG··_§θJƒoaµ÷Ý3cÙGo»OGG_Â@ ÍHæK*ßtƒŽ»€HPÝl/çU‹(§È#- °Úhövb’ײ±¬s〴øªŽEªâjÁØ+wvR¾c‚=ZE©f šurr²²²ò|àé§Ÿž@¹ 90—cГ¥ì±2ë‹Lçb¬fšhY:ÿ%…O–ÍñĪ­ú"&[õEØÒø1{†™€„ŽÅœ#°Y*õëʄ͔]<‚g"†eá¹ÈlÝååågŸ}vuuõSŸúÔýû÷íFëÂ@?})07£gE*¹•›Ïëøøøàà Èj…Ã×29ôT\nRA:�#Çb†·.i ²›ÁTyOfqŽ[Ê@¼`nn®Ùlºm0ÐÁæÍgZÊß=>þá·¿ýmï{ß>ð|ä#ÿÃýÑÿ´¹Y¤Ë@†Nfí&yÕÒ7-|¹òœ6°Y'³k(þLGF7¡Óé”Râ³NçÆ/sx6¯ Z`~VsÊ4¥¬² „[ä{xxØjµhÓS_RzªŒ Æ„§db‡h¼ŽÐâü••““ÁÎFœQD²°ü« FµMªºüãŸþô§?÷¹Ï]”æÍeÈ)NåÜÕw7¸ÈýŒ£¡"’y[†¦Ø ,{» 9ÂvÏæôuh®t¦éÄ0c˜3œ6�� �IDATU›34‰O°`- XH1W•ãÌã!ääë ¬Ë%QñHvéVJ£ÑxÇ;ÞqõêÕ/~ñ‹wîÜñÝó˜*,èDÙîŒ „ˆY¹ôxrˆ ‡Ã[·nU˜Äx§™Œ1‘†ÃO w.¿Tx‘Vó$)MéV«•\;Ñ¥ÙlæfFL> Ô»ÎП€ª@«#æèHi7F£§ççŸü–oyî¹çÞùÎwöûý‡þ|¿ÿÖíía)ív;u*e“½¢a©0!dòº¡¶R¬ÖÁ2ÈÐ=H€ [Q OC÷´Óé<óÌ3§§§Ï?ÿ¼‰^„r¸,ª<,Û)Ù‚ä,ãÀf‹d{¬‡:ƼÓÜó¬ö¼C–(R|;s¯.ª¤w*É8ÐH‹[ÛzŽQ'ÝšN CÄ-gHIKȧïïïìcÃmò2ä\pÔq,©:”Æ9)Lå´´sV[vxZ‘l¨é+UÆÏr›dÀÍŒæ³óÝš&oÅ”>×ÄE•¹ÿÞçÌýØ2ÙÒô ÙY¬þË"fff†Ãá/ýÒ/ÍÎÎnmm·rÐÛ1ÿŠ8Ë£'Á€Ûô·Å¹«Ü|÷üá<dj:ïà®Ô Ê}™ßS£¤˜)¹ÝnçÚâaC°)šÛÅ;)|þ=·ýèè¨Óé,..‡Cð(ÏM&“‡>xðàÉ'ŸÜÜÜ|ðàÁÞÞÞÉÉÉ©èg6Ê„ßAFl ×z3‰(žu/¥ŒªñNwÓ.ѹÛÀ;ãñ8ÃR0ÅWVVZ­V< Y¨ K Eouº÷ã˜çc:‘>Ș…*¬\àÑ.—M¦öA}vœf±Uà 0ñXl&CW\Uy°•×yg‹VtPß"É® *¸ 9o¬£HäÚµk‡‡‡›››^4¤fUŸÐÙJUóx&+Ò‹6¬­™Õœ•Ûž²°°Ðív‡Ã!YRÎ>"M1¾BÅê6Îkìž$Ñœi_ju³E=wttt÷î]3D±9qÿ–cÎ.Ξ”²+¸QÓüCêœüÚÖ…r-)[ŸåLO¨FÌÔÍOÂW\¸ümj·Û]XXèõzM¹}ÓN~'E¾Âˆª”fØ“O>ùö·¿ýùçŸøð¡±Áôrþ¯¹¹g>õ©®¬Ü¹sçÅ_üOÿé?}×Ý»ÿºÑø¾3<Ê}鄱œãIVà;ð¸=~ä©X?8užàqÇ ¢AUµç¿¼öÚk;››»råÊw|Çw<þøã¿üË¿üÒK/qDZÌÆ;«š”d3Z1†›`C /âžkå½”»Kò…›(¶áIþT±I+1Sx+E€i×U¼8új6ô#ÍB¶•÷ÿ½ÀxsrÎkLä7›Í·½ím›››;;;¦äiM=ÙdZd©È‰Ýƈ{ Åbïùê5Õ)�™èÂfF÷TÍ#¨”ä N]ñT„QüíÎe!\9»,g"ŒJØy(‡rŽ{fõ!•ÙAÀjWâ«8~„ RoÓ™L]ãASÝRá9¨i Dè%/8<<L ÏG ËÛöz½Ðš[­ÖâââÊÊJ ©$4£Ñhoo/f\”¤y‘¥€H¹€h®„«âñrJêß™ý™[·þ—_ûµŸ}ùå;wþôÝ»ÿpÿÏ·Ûþ ¤‚¤Ç}È‘œŠc‹ž¢ as™âŸº¿vêHjO=[!ÍoåL{aaáé§Ÿþîïþ¥›7oÞ¼y5å|Á ”LŸ0ûL©MñMU7¡ÚS¶ªæi‘‚×™ÿes2?ôÉÀîŠDâ«…Ô“ºªb6šêmÂ$¬6—MÕH‘ë¥EÛW�îÀ`0øô§?Íìîæ4Ï´å˜Èña¦“kvƆÓF¶n§Iµn˜+Ä/Ýe»âàà€† #¨€?žjÌ%ÅÖ%…k/fà+Ƕ2åRÌ.bõW$=—G¹°|^�׼ȟˆr Ì%lÁBUO�«F@¨ö¨Š`.øà �ó <7gˆßÚÕAÏìq³ÅÅŵµµv»ÝétºÝn³ÙlµZKKK½^/w{ÿèèhkkk4 ‡Ã~¿xxÈbHM333“šu?+m<¿öÚk)’`.}))¿¿×û›wïþ¯7o–R~iaá¹N§©‰"˜èGr+– =mjàáÌ4™L†Ã!ú~”`§&k¸-gzç+¯¼ò ¿ð ÿù?ÿçÁ``u ®– Ï‚ÊÖ4sÕÎÿ¢ßj–&sQF«2ÒådÈÔªF<3}a%¤ !'ò1…ê“„ÞR9S"શ¼0BÃaó¢ºô˹øHS)UdU…Vën*ˆÑz†éXÊž}3 ç„4Ë=çE˜õn±Ð­2)Š૞„ûá¨ß·Z­$°^èžn³¯­Ih^©ì »¿ð&XrQ ÁSÎ+ÿWÚS–äBÀ4£j9él´ã²œyñ}Q¥ŒÖ`00ýÏSrVÜ"o° õ„‰¾~*faÄ´Z­v»ÝëõVVVz½^»Ý^^^^_____o6›«««Ýnw~~>­íííÁ`p||Üï÷ïÝ»·±±±··,7ËŒ1]ñx~y»ÝÎSNrXõ‹ iffrttonî_žiºü…££™™™žÉ @ÆÜîªHzØLAJà,¥ôû}œ¤]ÞɽT¢J€]Trf¥ÓÕßÚÚúØÇ>–ÃšŽ‘¹[p(*î,€�¡žãá;ÂvËíÆ´}"êj ¤t�¡5ÝþŽ9Ÿ…²¥V¥–”Oñd+]"[ݰ 99%¬¥"U7‡ÏMO#œ—!çBNÑì·‘""ìU`F¡h‚•9»i0Ó Ó ~¸; YÓS2pò]!nV­ �4,PƒÆOÁç¾á;¦|<¸J.9=ã.Ì@ ïÀp;›„0YÍÀõWõ /¼ðàÁƒŠn£`úHèå¸ê©§–——······G£Ñîî.bk<)0¸!¹?9=ÛÄbÈ#³^P XUÍRÓlyä‘¥¥¥4`®]» æüäëõz¹{{{ׯ__^^¾ÿþÜÜ\¿ß×àèèèáÇ4Š‹$¥A±(×þåe¢r�„NNNÊÙêòô±ç]ʔ膻˜4®`£äßib»ÏièrÙ•MÁó¨Cm‡ÆÂ…KɹÏÅ[Èœ`ƒ:OÍÆ3Fž �V/…,ã ¬HÀÅzez2¶2£³„k‘š·ÚM^°¾¾Þëõ^ýõ½½=3˜ªîZ9/sÎàTÑôñeȹà^Ž•‹Ø nóЦ#o=` $)î,œVè¡Y<ˆ6ÁÉ$ÔV«eu¦Ê#¹h6Í UN ”<æ¢;¢\9ýOiT’•FƒÁåŠ\ë-þ¸¸˜ãuoo/ÔRZ& Ð$V=òÈ#ëëë/½ôRnf¾‚gèÒ§Ra2?ß«Ýn?úè£W¯^]\\¼}ûöïþîïVÔÁr¦-æ1X|ù|«Í§�š'Þ'Ùo4ùŽéÙ ÐÐív¯_¿~íÚµv»}íÚµ`k9ðNåÁ-..æ½^o~~~cc#¡ëÞ½{)kÒLNŒÉÕv: •ô„öÎlÅ!Úå†WH’gånF²ÈrsrŽX-Ö'¤iDÉŽ½ÕÎ蔹Ô^NŨ3l³VMŒâ袼ÈP•¹à"Y¶†£‚—* }jÉ'ÉM%ËÍæ2zÁ�å(îón”†ïyÏ{žy晟ù™Ÿ >»¨´,]=r¾#¯Dáô2ä\ØÏ—&éÎj9ûö<6Göp8$ÇAÑvS 0þÖu.K–5Å»u™˜ô8«œÃÂÁ û'Ûœö Û#lov¸[‹ ÉÝFß.H •W£Cìh4ÊéœC*×Ñ+ÿ ~4ýú¯ÿúâââÎÎpeÅ´®ŠQøHá\ÇãÛ·oÇãN§sçÎzþ¤™`åœ/-ÿÔsþ¦Q‘£-Þ)kòÑ€iKKKÝn÷ÚµkyÙõë×WWW———smL†ú.±*Z­Ö“O>™×_»vmgg'LhšóN‡æJžK<P7€ì~€ÅÑ™þá~6›Íµµµããã8“fSL�UYmž÷x<¨kù%Ô`" Ë�Ý+[qÜ=†ÌJ Œ WD“ÃÖ«!¦›§ÇËXqùt e~Èe®=L-žkh‹\ùÓPùîÜÆ B`½MOž&¨?ÿüóŸÿüçïÝ»—-3àšóþ¥´ ÁØMûôóº 9VåTž¾#§]ï…ußIpÀªùdOw£ƒT‘îÙEäÚD KsX3:cŠŽùšErÀ°ƒÌ%£1n'lä^<ªâQgN·=ªq"²*Ë*3Bу¾o”£,›f÷ ‡mΠÑh”kF¯¼òб,D Á×4Ö|îþþ~å/’<Ç}N¢¤êÝn·Õju:^¯—ÿš¦N·Û]ZZZ__o·ÛÝnwvv¶×ë¥ÜÉú8‡bq¥¼—NIâY»ÝÞÞÞ~øðáñññh4:<<ìõz”•Äò´å)ÎLÇ hH�h…®[ÖÉÚÚÚ»ßýîíímš% À[ˆ–FuWÍMw¯ Áo˜”¿È@»²¡µ½ äÌ*7kVÓ]•E[Ø%VöL]R™Á"ñzc•Úœ]jÖ’+!§§ETžE–9’l†+ɵmmmõû}dÔÛí¶5XáÅ@Ô´—Ï–K‹¶‹ïå°žØfì;ÂRyä)¶Z­” щ¢zEIÐS¶WlñTµþ(™9y+I‚JÜ‚ë§8 \ã\ðøƒôl*·‚,+Äl:]"�=¸‘ÄUBô®L#þÁcæ¡\¹re~~þöíÛÜ—8Ö°¡ ¬æê}�e+¶Z­ñxIl#¥Ö©k·Ûòl6›ÁÓŸ|òÉ4ðgffVWW×××ó'­V+O"GâM"¬6Óçªd3™ˆµººº¶¶–´¿¿?‡Ãa*§~¿Ï·K"Ÿ:ØN å¼ë ؼÙÙÙápøÊ+¯D½-Œ¦ÜU`FËÐ芆Âp8$å2X‡>úÝ�«äœ©H!yYõ< j3ú §B[Ïê…¬."Ÿ5DƒŒT;ŽšXÌ×w¡Ï„Ìm™ÏGÛϛΜg"ý´à&’zñ«ˆ£A@Ý‘´ úÚ>ªúÛËs?²­CSÎtbHëò8»ÝnNgÈBTµUÞÖ‹þòï¶W'‘*ƒ˜ÅZw�ÊwŒhQt»ÝÓÓÓ½½½|(ê DÏ»T,/¶k5”ŽpŽiĹì@y®âäÏÝÿÌŸT^åLž�þ+6 h&º|ŒF–Kɯ+lyÎÌÊGG(~nn.$´'žxâÆW¯^ `2™<òÈ#×®]£8 ¶†¤MžÓ*ž®0kÖ¢ô‡2íxxØï÷··· ñ¯¬¬¬¯¯yËûdîìì¤Â g/5Í2¨J9§nÞ¼éÑ®ªi©2Úâå˜zäÓüIÎk%ÌÍCG LJ¬ç±�Žly0zš“—Q"0ŒÌàq <܆y\|@ˆœøÙDÌ\{^»’òd!ÁSHQeiùªøxkZ;þ)²ž2LDa»åÝ`»•ój§—!ç"ã §- yM¶#Ö¤!I¥³p+>b‘'šK6ͧ¦UMÅ2äÅ>?o2a,%ØEzð\è,ÁðPJ°a6FîÌÊ  À;gË!¡ðT>ˉmŽ*F:ý瞇æxè!ó£££П(Ð4HeÈ›|3’N1_¿o]ryf¿“aôz½+W®<òÈ#kkkËËË!\¹reqqqii©ÝnƒÑ-//§éâþ–M ÆQä…i ± Nç­o}k»Ý~ýõ×ó_#*RÇÓÌÙmb¬†ÌÚ «›’úøø¸Õj²ƒŒ‹)7<«¢º“Üv/~/`0ê0k /2Í–£§µr^ܰ+k‰¼ª„Å90+ÝySTÒG•¢Aâ„%æðª@ÆÆ¤p’-3¸!ÌíÙÉ4–¿eòv gîŠ#¥ÝnçATRñF¼Çã1~K<M[4]ör.ž$gå+™{l%û$Gjkê1©ƒ«ªW\X¾× ¢*û ÁX1P-‚›ã›‚³;C? 3šªÀǹ`ö*I"dbK]ÙÀ4[ Ô¢H°Žy1+L[ÿ˜ÝPwfº6pAÊÊÅÅÅÑhä;É÷*ç5ƒ+î}”M…È­Ë ;`~~¾Ýn¯¬¬t:T3DÍt;˜O>Ír0¹ã ™Õ£¯P¿¼;Ž+æÅÅÅÕÕÕΗ_~9÷*8ŸpFõÁÁAÀIP¯=6¾7ªÍѰ|s6å6*ô¾�eBÖ³š|´}§‹]U%›»d>÷Äm×:D8çvȚkzzNy÷<Pô8ˆµFÀ܃,çUÑÌ«Œ6¸H&IËyÿP³ÏY«ÉB¸·‰÷Ö>wìÒLAÆâÍû“P.CÎÿß?€ƒ¬¨æétRHwÿªù¦óæåüH0ÍXzƒ&×{ó�åƒ|^ xø¤È ÓŽÈ¦;s2_pvs¾PšÀ«¡!Iz蓽È“ É“c›}¾‹4rv½šAÌËFå†8|Œ9°�š˜Ôáãø ¶¥šiµZëëëÝn7SœU)Dâô“Kêt: Õxù´„}ÿ°¤L‚OK)ÿéÞ½{{{{8¾ä'ß:tØ^¯ n8Rfåû^‘|Ð?wäÂˤ[Xgt¶àä)gÞEUš„1žDÛêVYu/Ðä{„%?z3<m‰Ú¨%–vÛ‚�Ç‚M•ì²S刹í/%Ó*Rñþ"£UYùä¾A�aóÛò|á¬2U:Ý*¾ 9Œ­Í³ ݯ&…aoäøCìˆBÄZýU-åéæÉ³@)MHÇ€ñàA ä§r[òÑPä4Œ ;«ÖÀ„:üÍ*ØÄÒgeʶ 4ˆCÙÃørsò{.ô9G$¨5̇Û{”¡¤0 õx ÃJËœäNÚÎÄÔ¾¨p¦„JCåêÕ«èv» K²ID2{Ôn·ñk°«´1RªçLÒp{�ž›Ì©*óO<q||¼½½‡éòòr@Bdë:Nš@‚òÔ áò}óÈÌ8 ßæ)cJj3DzÆVWWC B%ˆÛka¡iQd¾) Â4…—I=ê»—ýU„Áç¼-¬ÆiémØSŽ›®¹ëc¦ œKAàε;í_e¶‚­<m¶m÷¬iÁßÃÃÃ`>[̱´Ô=Ù¤wV³Ù|ôÑG‡Ãák¯½f5&Ëà^†œ #I› ê| R2 ˜–Å„˜lw"åD˜0¤cn¿Ûã (,ရE‰nÖåXttƒ¦åk5~*’8¬8“ÂÛ|Ú¼E“ÒùÐn·[JÙÚÚÊ‘„S=  ¶J$°lÏ<… Á¤ñ~s?•ŠO%SÛ¹ZÌ&0ª4†CÊJw!Ÿètzzº¼¼*zN'Ïbyy¹ÛíBò–ù7í¬E„€7§t/2ÚEWf8æà¦ l4yýÜÜÜ7OÍ¿4›Í+W®0à’и½½Ýn·37¾IØ•€f”ÂÕà0ù/³h7¸‰ç–RöööOJþNseÊ×§éB 6ßš|™ -SBq’2[ˆ’|ˆ •E•5æ­W5äá.²}ÈÌx ô᜙1ÈÉ­«D’¬^È«9¢&ãì‹ïÒ ¹‰5Ÿ[¯Üëõ¾îë¾îóŸÿüÍ›7!tTÈ—!çÂz9U fî™Qlv”§sÒú.ÒÈIÇÁíY·ílB­ÿ¤È$Û‡‚Y^ö ¨( ·¦<ÎÆà"à{vôØc½÷½ï½wïÞoþæoæÔ«¶“‘ejšJ"¡"¦èU†˜ˆnXVZpÈÕ�vY�Ñ…ë9Ê Æ G¥|É�Gö°œaX´Z­ÒòIo6Ù¨ûÀ —óñcšm�÷“Édgggoo/ÉD€ ^¯—7l·Ûׯ_/¥lnn&dZ!GêêêêÖÖá0á9ò _ÀÖÝ5ÇKë™ÉSHî Y5¸†mL•}›oæÒ™íPdëIÿɮޒžöw‚VV‰šc¥á¯æ>"Hue8´òã6·@‰Ué¬A;ÃΕ$Ýtñaw†2¥Ê5Ìééy:õáÇ¿ñ¿K\÷Ã.°Ä¹ 9u;§2™¶®ÌKlRël€¾œ/7¿Å@‹ÀjWd[îoW#lìÀôÏF¯×Ëïþ,»±qÏœ’?Ç76×|>2¾ê«¾*§X>*= ¶nÎb{¿W„]ÚàŽ74;ÎÝÔ8ûz$Þji>ʙַ×m�£ Ä•LØd–3èââbþ1©}^‰^x¶½y‰,ƒÙÙÙ¹Ï}®óc?ævq¾òÚÑÑl£±ñýßôÌ3y“Á`ðàÁƒ|‘|bÚr¹· ?‰7ÖP ˜vpp°¸¸˜© «o7öÑœfï E' $ìÕ˜sêËÌÀÚçËæ›B;6YÜã±DåÊr9-/ZÀmKÜ¢$ëEÎöáÛYÑü²·¼IÚ!–¨pƒÓÔ ÒDóK¡e[Å :¦{W$Àh9m*ðÜbj^p<‡ê‰v £Ë*çâ9nîUS‘®*RjÊ/øk¡­d6—ÕkH4~pªÒ{àD¨˜lZ&›…3=??ÿž÷¼çÝï~÷g>ó™/|á ÞÃvF©dˆ žoÍ„->=m0™L666~ú§zoo/É.M@ÿÌr¦ Ôä·`qpin§°Ï´ûØDÄùùùÑh‹pV’;O9P¦á8P‹0ÇÚívâqú:q%ÈO�Ÿ˜KÚ2‹†¹%&“Iss³Ñjÿú_Ÿìîv¿ç{rÿ·~ò'WV–ÿÍ¿™½woæÙgóQ#MC"ÄÀbp “Î5À_ZYYA`)WkõèêS‰bAÍán¢Ÿµr‘”$´.Î_Òö`zNÚªÚÝH©›yÔ©ð˜Ù X.e¡ús-¯ ÍõWs3$I@y‚ “ÍÌÌ`cHID¡Ï›[Î\M*s=KÌn?zJ¢ÊW‚̃8Vu… âM”\-}ÊíííËs‘?<Ü« gÓ#iNñ’S8<Ô3R"À³Á @t2 Ì!”âæ-'B~Y[[{ÿûßÿMßôM§§§¯¿þzf뽸T.Ì[Â2õ¤ZR6 ^}õU.Û\ fÓ›Å1gJ¢KåRÃíe6Ð9‡± Åp @…J R¬‹'÷´< ŸëôÌé“  ÷duuuuu5 c^ÌÇå=ŽŽö÷÷sd¬¬¬€Î}iêâw~gþ×ýä‰'ø:½xåµ×N{½µoÿö~§¤Y$8ƒùðð0ó7sssKKKé™QlµÛm»”m«“Ü”Õn~¼ÝhÑ‹l æ¹X‚Ïɾ›Þ¬:æ½`ôVFzÓ,ä0¥&®òô IPÌðM ·A¬…tc;ŸimûÇSRu˜(¨dQ¨"ícº<<×lúF’†dussslà}œgy:¶o‡ÿ ¡ãÊ•+ßû½ß;™Lþý¿ÿ÷—s9ÜË©�t2³¾-þá–šÝ.I-t]‚PÚ4Z¶Ñç‡ÝhtŽ$Ëô•ápøû¿ÿû<øìg?ë™�(U´ œæóÅí+Êä¶­qü/lTAÁ+³êWeÒ\Ýsƒlœ<=ì’<—–y%ÞtðP9 H¡äA‹¯Úl Ñ„ŒÇZ¯×kµZÌñ¥WŸwÛÝÝ ›››á­%ÄæoßL`ÉO4vvÆúO}Ë·¼ »7‹ýþä±Ç" šG™Xböç8'WFks+¬÷ËÑø›¯1Ô\)Þ„Ü&„‘Èý¬Lerh²0è‡Ã•7G¦jExF"{%Ûá2·HÖÌ!³"U‚¶Aq£Ñ·Ôí}âMV¯˪™‡CoíTŸ†Uùý˜uâyU†Þ<áçή%[*Í…ir ”ž•ÁGžûáááýû÷’F\†œ fHWÈh›õ‘ìÆáHšoãw{?g* ŒL2;T^м~ü@اÐ%‡¿÷{¿÷™Ï|9 ò,Ovº#ÔV—ªö’À'=UÊññÏWÏ´fΆþòç¿33óÏ[­jŠs Ÿ¶3±Üòt‹À=<îc\(‰jê*¨€©2S@ÄJ-b Çðz½Þ;ÞñŽ^¯Y³^¯—è¯Ïôrò¼òrN‡VácÍÿÎï”RNÿÚ_ü¥¿”›ÜùÅ_œûð‡ç^~yï¦ËÂÂB§Ó‰šgÈ ut8ÒEÃÃéää$l´„œÈÚ[íØ3hï§<ª’wsKq˜¥ÛþÉé™_81=2ÌR'À: µ©½ª­MƒMm'‹Ür´îϹbÁ¶Ï›H°T<÷eE‹ÙÇ)Ä+¥ó/«um´ÜfÕÐ^<‡ÍÚ™Ù—•Óöçæ.ÝsÎ)r=[[[¿ú«¿:™Lö÷÷/o.X«ZëðeqáûF]:f¹iDتñ´{®)Èì®r6wY5ºÝ34ý4gúþþ~9ÓJÉiKkÝ4Ãô6Á­`cn¦ó£Ãh^ßןœüÕf³u|üÆãÿâôôäää§ææ~a~~©”8:úç¢ ‘uâ9oM*Ç*KTJÏäò-+�� �IDAT€†sIAç"BƒÀLå)Â(Lê†ÌÖ¤÷ÞívßùÎw~Çw|G§Óùô§?=WVV¢NDô- ‘!Ï( •´LœoJ—Rú?ò#Gü „”ƒ?ûg'þðÒßú[ã³6~£ÑÈ0ir…Ä98¡1Žs›››£Ñ(!Õ’;0??¿··÷àÁƒÝÝ]t o\Fc(’êÍ4ÆÚ–ô,ùnÙOÏ÷0Í•p+�<¯¢™Q�Ñœ¯ )“Km©ÉV=:ŸQ[³ÇVO 1b š ct”·Í-MÉKMÃ"ôD§;Kop?“ÙÜÓ:lF2ªQ¼²}&“Éææ&¼öËsñŒ5È$Ä­–Eúôoa(¥4vì!tÿÀA…™a&~¨âÝðˆ5^×t ÝÚ-á&We�"ˆA §±å¼h ª|ÓToôQfffŽKyçññœœüï|ç‡{ìõ×_ÿÀ;ÿnw÷{ÛíÓÓÓ¯::zËYÒ÷%ZàññÌd2{xøkgŠñôÒ€JP6L<Í „L[ò idžÑz! œæ/1"“x³¸¸¸²² çRJ§Ó‰nqü­Ó˱1Ù1+¦®¢Â7œêÞ½†xŒ§Çdz¥”ÉÙ)O F£Ñh2™<þøã”£Ñ(Ž­V+ ¨Ñhìíí%‡%DÅ¥†ubÿ˜ªçAbäˆHkþ!ü®,ZÔi½lòYxݺQ‡F”e› öo®ÀU•öR^¯‡ÝÝ]ƒäVç#ë"ã„ý‘÷!Y´C†«ìÖȽBÊvh†±²’¥%¹É¤”«bªYm áygVTE"ÍßfdÊÓHx3RU~á—!çÂ~*û‹1#?LtÙÞÞ¶ ñ#u ié¶Ó†T’õDÉÑX9UHåkàKu¦“CŸd­Ú¡ášbE¹9+¾Š7•1ùaÏD¥Ržm4þ·¯þêwü…¿ð_½ë]ŸøÄ'~åW~åäÕWÿâxÜh4þ›Éäj)·Jy×ññ9—RÎÌüÄÂB)å¹££g––ÈÔ�|€AòÕÜÑÍõ{’ÑšóÞºž'7;»1Q"@2‰ÓÓÓ?ú£?мMHÒ¦Â[²—·É$Íárxxx¼¿_Jé~øÃ³ssÿ÷÷òEš?þãòOrÅw™ƒ54ôcîÝ»[:c§¹-á­µÛíÔsƒÁ 5<ÆÌd$ìk>??ÏqlE wŽûiÍÒç¨'˜M`1½jQkVÖËžO´©‡{N\•É&DwÛ6Òo·ŽTåÊcSvê9/R´PÒShÂñ#ƒ!]ã_PY4ÌÎùàÑ("„Yéîu•ó®F>*Fµ‰—®b= `Råeȹàã\R™Gù¼“P¸™aÙÎJ+VÞ_İŠœÁz¶‚Œt¹¾á;NZ; uzvœ:[‚=P$ô ©Ì½k0Pc/}–øÒéé7·Zÿî}ïû®ïú®Ç{lyyùÞ½{ÿ÷ÁÁÿüòË›=™ù‰ÙÙÿv<~efæºÝ™F£;`<þ‰……o~¢Ñwƒ3 ç‚á¦Ð!8Q)fq˜7…):XYÞ*àUΑ777ÇãñêêjpÔ\R»Ý&YNÕU4m†HráØÂaÛÜÜlmlôþÌŸYÜÙ™[_ïýàæšÞûÞÉ×~íäé§gçæ†Ãa¢NJÒñx¼··—zºßïçxYÎx<¾ÿþ`0H2T-¯ï÷û 3‰7aý¦ëƒAçN*¤­0‹LÉ8×XáÔ Nb<bÂòcƒX? `³ÈCÓb}Žm'wSŒÒ¼LúEÚÑÎ’  –·€ÊlVj‘ˆ{º#¨_#ÄóiY;®͸<¤XØä.ø/ <’çSÂ/¨0á„n+ JPV;m_†œ 9t5È}l𛕉‹m ¡ï0P ©@…˜Äù…@Kœú “’œ%ÛÕš@LÙäªmQ4qŠ:­Ë„‚\‘F ¥|;Ö½¾™IžžL&A„>|xçÎápXNOsV­ÏÏ_?=ý{KK£v{vvö`w·YÊÛK™?Û$àT2ÛYäø©&AÀú‰©Ì£äÙU„ŸÔyëKB È@LÄfòÜðÒ´ 'pécA#KÐommíììܽ{÷úƒêÿøtqqî§~jîsŸ{³>þâË`0wïÞìûߟÀÀ™˜‡¾¶¶6??ãÆ ŠfôÜl«œ4(xܤ,‰-MƒÌ"AœØ™yqHÜê’–ßËï9YQn-؇ÉÑ&ˆ©eˆÖðšÇ</"•)"áŠ×XÐÐP xŽyR¶T'AÌë­œ–_¯c_Õd;ƒï\!#äs+X˜b¤LÊ™.ꋎ~犌ãÈ•AN§ 9¿ 9@’Æ$ÜÝHS“­WÁ¬N|ѳ2�E~ f­Y(„Î‹Ö µµsø6vã ¦ÍcŽúóÖvü²”ð+ö’C&.;Ü·Hž¼iÄ23óŃƒÛÿñ?þädrãÆßþíß~á…Þ½·÷»gIß¿Þßti©»¶ömêOõz½ßþíßþW·nýèþþ×N&Fãð Ї>ç9$‹f87÷-V@9Q4<âe ¼ÁD—ìÆÁ`°···´´ø¶zHb™™ði˜‹·&c’yFý~?·îá;ß¹ý=ßs£Û½ò7ÿf.ið7þÆÑòrç£'Ng†¢võêÕ'žx"Öp^¨„d¸$§§§»»»ûûûý~kk+œ»9ý.2 ÂM‡ ö4.‚?Ia3×`ñ:kU¨¬©¡¹Œ¬"‹ÿ—3õ3œ‡Èê(¶�‡ùÐÊmÏ:¼å¼Ê2°'È­iÖùó”4M!{ª“À1•¶¼àòÊMï5ûOshƒÇÚç·š—ðÔ9¾…&þx�‹]†œ‹ÿAÝ9§Ç_RŠÂ+C%¢Ý‰žö�y4aƈ ]‰ÕŸ +Ó·ÈG0ÞÅN”A3zŒæ½X¹ÄÌ$‚ì|«éffßš¤@÷åôôôáÌ̯—ò÷_ýO&¿Ûjݽ{÷›ƒþ•ÅÅ¿u–E6›Í¯ÿú¯î¹çÖ××'“Éöövãà ŒÇÇgíªãB •ñxÜl6c…iãw r8îXà€¬ß¶Zè 烢+“²2RU •ÏF£Ñ­[·�RFdHb2™´Z­£GÝòÉÕ—^šëtçïLŽgffæoÞœ+åø©§&O?p/Mñx"C·ÛÍR)JÉ!ãÑ8㜜 ƒáp8,è™°g{rž;ß×Z8®/=†â™ÿ×r¦Á­ '·RT•â =aiýdi('Uzö—Um(Èý­Æ†v�_„•@µó¬«mJ|OO{‡R¹Á‰¬F´Ø( 3MIdûT`L&‚³ ºx&Ý7H�lØ~­V«ª‡.CÎT9<f­@èä„-š|„‹iO+“ƒ¨²Èœ=™›OÐÇ ­ ªïŒ(’2wIB¿�P¾*f¸'T¯™ ηH`KjOtA¨ƒXõ%)ëÓÓß›ýðÉÉ_¼uëñ™™ñxüÉ™™¿ßn7§ãñ‰`ú£££íííÉdrš­{¶!Úq r\z00—‘”Óç—Ç­lmþ4 d› ãCxNš™kH)? !t¿)[ÇãñæææÆÆFê›TH‘|^XXÞ¸ñ…ïÿþG}tmm!ÊÖÙ¬Róøxew7çfggûýþƒnܸqåÊèpL­®®æC3…º¹¹¹³³3ƒA  :r{“‹‡ìG^eQ ŠÜ±|¤)¹Ó}Ô£pÒ¬ñåQVƒYˆ“òJÀ^SÚœ¼Ó£r'2ÁÆ·¦À¡KgÈ„éðñ{ ’ s þB.µ+†ºµN ¸$ø8‚P9ïôjTƒíCÈ¡#�Üè2ä\ÌmêI ÿÅ*ÄäÃ\F[Bº·x°Çqò)ÑÂ[3ƒæ õ2 ÍñLº'­b³x¨Þ6t&Íž$½EŠ“SŸì‡L½ßävþ›Ñ¨”²vzºxzZJyÛÌÌp2™›™y¾Ñh”òƒÝîOõûû3Ÿù§[[Fã /¾øûý—?˜-33³Î°Kw;=J‹¹zõêááa¿ßy³Ìj˜n`QjmêKâYì5!°±L²©yGGG­Vëððp{{{8nll´Ûíµµµ"%iªgÀ¥diòE”3ñ&âž'''ׯ_'”fí¡`ŸæÍÌÌÌîîîÆÆF¿ßßÙٱ̊såÌCÊ@5F:Oÿ9¼×…fÅ8/ç•2�ýª3Ýl±*»ª`1„6äåÔNn—ò1ˆ1€D%hkü-KºÙlV"Ó¶Y2dW½!nÖØ/�ÔpO(û\0%ã@³OKCPqž_ •&ˆpÉ| ‰:–b]k_U2NSæÉ`-츦®]M±0e ˆ)pÙÀIŸ9�¸*Ky$DÉ ³¶<Ô ^a½ÛéQ›ð·éÆsLû †ÌÍ`šæççÿL«ßÚgMnã?Úß¿?™lÏÌüÕÛ·ëîÝùùùwŒÇßyxø¯ƪ59\ñƒ`š!þ`_÷u_wëÖ­ŒRÛ?‘Çbk9ó‚ËýÄmfãP´â;N†Ì—––ŽÃ(‹—Á4í'ÐÖññq»ÝN´ØÞÞ¾qãÆÒÒRú(™ †ò@qÌ2Häã ŸŸŸ_YYY^^¾rå Os8>|øðáÇáÂmoo'wÉøg\¶¶¶úý~ú[æ•‚ï3h‹<)y=C WÞm+›‘0‘ãz ^;Pje¬Ic¿h0™Ä¿$‡ Ôê„Éx‹ HAp…LÁáN ‘Ò«Í6‰Elô ŠF5Ìwp™Eþd:xö`Âd™Ö& ÷…O‘]i&ºuÌ­¯Þ¸cH¦jDrð2ä\XÈ!0¸‡‘¡?“‰nÓ¡¯�ç+6•QWì5çrZ–†ÉŒ"µ+rzà ¢2»iAKÒJ5ƒÕ ¢X¬ûdô¤¨.8¨™ÂùAJ„Æ€¯¼âÍæV)ß?¿´°ðîÉä¿ J)ffþåÂÂ7žž>z¶Y•ۀƾú~¿ÿéOúàà�›÷�:Å«Úï¡«¥ë›÷O.i÷0‘ðsËÃÚÝÝ¥÷øðáÿñooogT¥Óéôûý˜Á`0×××£{–YŸjð"§äÊÊJô¡›Íæòòr¬H#é˜å1 vvv".°¿¿¿µµ&ôÁÁÁ`0ØÞÞÞÛÛÛÙÙÉ<)‘•<$žž Òšâ >§×ajOœ Æ_Y6ˆ4Â0•3"K~𵓓)²rŠüýHž¶XµƒP Fv¶‚žŸŸ___‡ÃáÐúÓ©=Ê”UA‘ÆžÿJ_0yIƒÁ0 ò;³Á«´wª'xr.ò§š¬2 r"w/ ×ГL0ÈH¦–Ê)›$È1ƒac»4 *Ó3`\2—5Æ^“E%v£¡‹‹¡'`ˆ·(b©®œ¥Rú°y@ÁXðh˜ýéfó­¥L&“ß›û©3àñôôta~þ“³³Ç§§³B°rú xbBSý>„m‹ z²æP¸ÛLÅhÆ`†¡NÙ8x2™dþ?têN§3ïÝ»·½½½±±±½½½²²B>©´½½½íííd≙B'0G+¯âüNÁµ±±qïÞ½­­­ÝÝÝ~¿ßï÷f¢V°¿¿¿··—áÓTiv¡æéy$“ÖPaÃÇ¥ô`&‹ÍN¼ƒ‘aî|Î;²·ŠãÇ$œ;m�Œ÷ZŽÓS;Àðí4X5ð<©])„zº€1‰Üÿ£££ä¤5Ö¨ähØTÃ|zp3ÔÙª„üa¡ž»l¥”!ŸÈšèÌ‘aºà’$ýÁU³|gNÒˆ'˜2éÖ\&`DH N×(NiM“P)2P¶Î)œо½ÊüNžNoä:—¡ ¨5+½[òÅó‰i�!öžÙ\¥”V«õÊññçÇãñ™1‰j£Ñ˜”ÒÞ­O“Œ¡DÑùÚµk£Ñh{{ÛD¦"I«”,ùóHÉ£]ˆ‹4fONN–——óÇãq§ÓÉ熗뇽^ïøøxggçää¤Ûíu»ÝLh†½½³³³¿¿ÏýSyyyyiiiiiinnnss3êŸpÖï >“ÒàZ°¶R¸ôûý»wïÞ½{÷Î;›››ù¸¤¡«¦HMŽ%L:`¿ž(Â`‚gm)[ÐWç=VH2ÎL­¬Ü’ÒNù«“=ìjòÚS¹°àÛA;ÝÚL¤±8¬òlÿ «-b9&ØZ– ‘5šuA½`)æR+{>iºâqJ—…¦*Ù:r¶g6W~¦·€·iô@Eãö]Ú.CN1ñKpy+U-h?ÕØ˜>ƒoEþ¡©Æï`íÊÜÚ“maâž''èR€¤(-//7­­-*-‹ŸÛÕŠ‰eãuÙ–¶y÷~«Â0üà,ëÏ>ûl¯× î4 iºIËÆKBé9×dKÙHØS$òéšØ'›æMÜÏÒ·OÚfAfnŽŽŽrµØ$üçfæ¶´Z­Á`ðÚk¯¥/=33óÈ#ÌÏÏ§Ž‰Þóx<^[[{üñÇŸ|òÉxÔgu¥ñAœè@ç°ˆ|@|´ŒÊ¦ ÙÞÞÞÚÚº{÷îææfXyv{{{y«Ü£LfÒCÇ"fcVírߘOåhÀ™îBÉW5ë!H&ÎGçÉ?<2;:Çh8bt–,ªrƒ5Bö>ˆ¡4ïLx‹BÅ’ØL;Í0íAô›-♯ìjÏIgåÃmÇFÄ’3Á8(òMw¢ÀͤòFç°šB³l¡=Wî´ò2ä\À=Òªä·zÅ!q“œÚˆ”Šz…ÄÊoes'öô ôìììúúúÂÂÂíÛ·óV–4gÕw ^€ç–RrR[á ¬‰V¼çìò …Éã~Ub‹± §þWùÇÞ¾};'8’šP$è¾2+Ã4+dŠ^ÛÛÛ¨IZÄÞœ…"¡F;ô8™@»!ñ&ir·ÛMS77g8æðe¢¢Ùl†T¶½½½´´”Wf~“>p\°vwwó{hz½^§ÓÉ…eø&B¢¤.D5ðσƒÂðþþþƒ666666677ƒÁÖÖÖ`0È- ‹=ï‰e€5sœ% Uø]‰U¹9©·hkYß‚¾/�ˆXZö¹!KpãõŸÏ MÕµ²²òµ_ûµ7oÞ|饗@ŠøCk>UX“Iq>^ÍskP=÷“Øl¡[;±é’[°/¨oþ¤ÔÖ½®Š¶GÏÕÃ^a `“á%mzïD<O‘óIÑÏM»4¢þJ)t<WdêE&bг‡$#V÷¢a8y‚äѦñ˜zåÐÎªŠ™íñ" z\øYw$DÒÓv¥€°“ÿ›�ª`)‘ü_ç­Õ¬5êÚ\XîíÍ›7™+ò´)דŒ(–ϸ“3.›è€9j»Ð{º"7™yrtþ¡i0·ßívsÍfsee%ÄhœÍWr‚‡xÐleee4Ý¿ss³Õj­¯¯Ïη×_~ùáÇ­Vëmo{Ûæææµk×ÀEƒŸþ²"ßñññþþþîînîäòòrÔÒúý~®aggçå—_¾yóæ­[·ÂÎFÙ=ø`TH©k…<ÞA‰_$̅פ»´v8²¡fl¥ŒKQ»Ù?Íó@dëEÚ æd¦ÕX,a�ð­A Ù§ÎHìhIP«Šdq?é9™B~ÃôIª"Å&÷\óâÀ|4%šu=,¶[$ÚÍèÏô€”ŠM ñüŸçU/𤽠9çF#=Íëò†nkkYf5OêdÜw}}A :=D@ßÁÎÎh†«ý2·dá>áú÷ÿ#³©26ÈØ9Z¾]z¶VÙ›ÚVÇ×ÀqŸ›ÿ‹{ö93O–åæô¤€3·ØC! ÄÇ{ãœ>!ä̓ž•ó§™ÄŒ+#Yé²À”m4=öØÓO?}ûöíÁ`ešPË~ööö®\¹²²²¬fwwwww7¢m K ÌG4›ÍŒ˜g›½ÿ>¶r9&îܹóꫯ¾ñÆÛÛÛ¡ Ð8á ã‹ÓÏ£âŒ)ƒ}’ˆ¤…ÎÅTÊèžñcµîg9ïæ—oÅÑú£îÒ™W:•n>wggçSŸú”§…¦‰Èð- ±d\àì`ÊùÁL;¢ gMwo™üߤEsÜtM*z…ñ:Ž+h™ó½àÄÂP·<G¡+R°P0�c<¯MǺÒc½ 99šÃ25 É[`ÐrÞ>Ùó pù³þ˜`OšŒÔ+~ææ/æßsÞùÔ†Àj©4†9¼¦M•¡ý@’H¹Ô*y šÕœrxSÎT¶°@ ¬ï Ì`ßV=€­çò Æw„ Kn”‰À€è åÞOˆìäÔÜD僺Ýî`0�¯ãŽ%' &–{Õëõ®]»–wëv»=öX¢æh4j·Û_ó5_óñüîÝ»aÁE‘:$ºdÁNSïæ³¢Mptt4 2L3( ÒÂyã7úýþ`0�ZÉäSº‰aô!¤æ)Ë, À+„$È©M‡aR ”’÷!£¢ã™ârÞŠÅ€­_ÞmiiiyyùÁƒƒÁ�º—ý¥æó*[[³ÉŠfñÀÊisÄx^œIÌ›±ñ68Æ"L2Çà31#0ÚLpMV® µœ×˱† Í,p9þÐ%ÌC¢Mµ"õtZeÓ]´Ës1!-æË,«^9°‹\qທPθLc£{T¥B>¯]¤»]_ù¿á3–7tæb:�ý(1V63|W¦Ô×ͼ¬J("“Ïß[›g'Rf{»¹êPŸ Ah69ìs“G§3JÔD²ó47ͼbªÜ<àåD¬ÓÓÓ{÷îõûý¹¹¹+W®¬­­¥é’Z6¿„ë1ÍôrÚív˜ÖåLÚ`gg'=¶˜&@§>88ÈäGþoàµÐ¥ŒãžØ–Âwn²©M0µNNN\ô¸ éF y\ÕN)ç2ý^å¼÷9ž¹L¢ÀtÆÔ^»àï%<TÔÐJŠ·ͬ„mžy,e ,˜¡9~Ev8Þ­Ä` ùвt/CšŽ=£Ñ(2H7®|Í‹”/Îp—Ôói'“âX«þ2ä\pÈ¡ ™v+JhÆ»Òù`‰›ÇÅ °ª¹=­»Î¹ÌÐ(ïOñQɯ¹ ËW…¤~¨”—{J Ò¸e䪼{IôB°ækâž ˆa£*ÆnçZ^eÚ9jZqv2 hIYù‘Nº¨=¸-iÆD%3÷Íò åLF&Á2e®p4­¯¯w»]BW§ÓIš hCiÕívNrsB@²>uOŒ×2O3·¶¶R åÙæÿbºƒÀ *pZeø¦Z±Ð^¼�Ìš…"q�T �d5’¬ÀK&ß2\cãÒ8÷6úý~ˆÝY{ º«ü<Y¹‰ôgºy@°ï3Ê™Xµ+*#Q.ƒ´BùN ¯†=9Øž4Ã0‹s¼aªºr½ËZÊr²H]5}ašåz½O4Š�…¯J/«œ‹§ð»™ò¬‰<cŽ`÷«Yå‰7žˆþÒ>ƒ†Ù�DÆÄ,i€"˜¥Ã ²çàÐ ¶CL‘Œºræ 0e¬I¢¡à¨š“  ‘Nà”ܨv» b'ÊÓ×333½^¯×ëõû},�’͹:±œå&÷ÍÊxŒ.ñVš Uãc(_?37yÆ*ív;²ža—­®®"Mßh4®_¿žˆ277·´´Ôn·#m’?'µ*A —„ŸücnK”:iŠp´Á ã˜J ´Å c‘l’ÅÂÑÉv¨ü@‘ë6›&—Aûͽñ꬯X‘fl2�#ËîÝ弦ìÕ6Éz°sA^†m;ׂ ¼§íP+ouÛØ‚š†.¬Ûó´²GRà¦Ð´Œ ¥!÷Çš7ù<,˜Ÿ%bÙ÷„tÁ&ÕùÀ²A±—þåeȹxúÀòòr2P;°*~A‘Z†¡dkQ8Ca7f³!ÓÉŠ¯ŒÿX¬~FÞœAK pgŽœ'ðí¼à‹Õ-Ù¢ÁˆnܸÑét^}õÕœV™œgçIœD ŒÙó8=jÊ»JŸ8Æh‘&bƒÒ­âªÒJ»4e’PòÓ´©óé9úi{0´Èåq8†¢‚rÊ”8wïÞ=<<|ê©§šÍf|£[­V¯×k6›×®]3æ“îq9ööö<¡B/½È=ÓYy%^é'ë¶ E.aÝÌÊšwË.Vº™’aR™ƒP™Ãà°­Y‘ašmÆ‘XKÔš´Ó)‹+žu3Ò|ަ$”‘áúÛ~¿"£¢õb"™Q)Å$pö4BH˜ôÍ¡ô4cqÊ€$ßVÜ<t؃vpgÞÎè·³ÀËsÁ¨ZFʳæL{÷°´÷<«?Ë‹¤œÚ¶K$J rÇ66îLÎý­ßgàÂ:êY²ì“ü!”×òF½Yîy}§Óyë[ßúè£Þ¼y“éŠPÀ|AËzÌîd–óÚ<>nØiñ{N/$·%ĶdÙæqTcк¬·m1]}$P)a1èM@ít:£ã3(ð�� �IDAT'û?EÉòòòÜÜÜÎÎÎÖÖÖÉÉI¢K–Çp8Ì@Õc=Êuþ=‡~˜rÓŒ7æ@§ËÉÅÒ¸JS+Cv «šç¸±¹Y$(Ž1¥S"´‹ U'ËF|APP›{ò ÁƒRÞÇtEø4.GÇžìÞGXЦ,@o‚ŽÒ„D”ßÄ9Ò³‡ÊyIú¯|ô´›Ž'£ó‘J©vAWŸ²Û³«éÞÁiòçšßQžq{•Ci—Œµ‹üAÎ2¹'ð·õnÐëÃa Ъ%¼nÊoè•ÀÓ\/”É]Ô›5@®%‰)?FãÜå‚&ŒyV›&—F/½ôÒÍ›7säÑH§ö"#®LÐ^ón,gÊÖö|Ì‹s¾‡—¼²²ÂS¨À¢iV’‹30ܼo®8I“&—3P†„¦§-* \‘„ÝÝÝåååÜáñx|÷îÝõõõ+W®¤2›½~ýú£>ááô*Aûýþììl)†BŠ›Í}¦G HåjĬªNÈ9ìßì¹ Ò”ÊÙÈ„Àjq+ÁÙ³$W Raês"smÕyJsÑLE¯ü¼¡¹åL}¼jAUDyw+ @»V‚¯hÜ®è{Q:€[”óÞ%f]WD ³ càùÍûê`¯%•Áˆ°Ýzt7stX‚ZÓŸéÅÀ/®Œ/CÎ……œò&ï»;mWE²!O¦W±»»Kæ¢MÅ€ó ´aGE¡c%,OG%ûCt$ðQÈ»•ÓT^ \PiÊB^899yã7Ü"EÛƒÍ>_<tÍÑ0-G_™k‘äžžž¦™±¼¼Ül6wwwùsÏÖ t’üÑî#4¥`T¢Ô‰%¹�8 ‹‹‹Á²¸Ÿy‡È9‡Üœs<a#øOl®\¹’–Fh‘vžL&<òÈÕ«W———]`<§ Ž }£hÕðÜóà‚ãå1…õz%¶y52ÅI9 *ÎåÌ‚ïøø¸Õj1¹åqNŸÈ0¹ÍÑʯ†(«ÆR•AÛ°£rJΛ§lÊ=÷ð©ßé“”2t¼‚( ôQy) &{TÀUWl‡¦u?+i]þŠ)%£î�hY±–ö©&\¬S¾SØÁ·aó¨P‘»8– FíÊ™Œ:`{vªá—ÀÚWD¡ƒ"Í=`™<ÈyË•ï'ÝEÓ1MÁ2§ª‚ã"cDDdm0I ó˜/ËGc¡H8C“†æ0hù þ[¾È•M®röùÍú&×Ãæ€obH}zzšÁþÕÕÕdÓ OXòŽÀÆn¬F|ˆèü_â7TÑF!M¸‹:'[—Ѽ€<âÄ݉\yà¯(u¦LÉDÞByˆÝ¼ìîv'“㣓““«Ãa˜ ƒÁà‹ÍæšÍ8Oç–¦3„·BÊÁ\I³ÙÌ((z¬AÀRD"+gÇÒdºq.CYÃÜOXÅ^f»ˆZHmú0%å" ø)[H›6r¦“dyæÉ|L“.0e â°Aß>׉Ϻé–(Ë-çk\�aŸÈLqE �¦«æ ,—åì-Ë»z(•¼*›•,î0©$E¸"ÏñÛ9—!§¸R9ºÃE—àŸÁræƒEÈžÓ+ò<³¥Õ¨Wè|T|7?‹4ßhØ2À8­_ëÁÆ ¼v8¬ÄÙª~c‘ê {j[‘Ÿr‡¯"_T#Üäáp¸ººHŠÁuýÇ7½‚;Ãl¬»¦P3¸íLDâ– &OG!–š*$Äå̵$fL&“hÕ,--ÁVÊ/LƒßøÐ‡NOOwÿò_¾ñó?¿ø¹Ïå_ûöoß»rå}?û³¿ñ­ßºñÍß ñÁ†Ü¢f³™yIîs.ÞöN.Á\+P\"GŠƒ™wÅÙ¥rµÐ‘]m(%+ÅO?Y�dW,•FÌÈ7²æ7’² áøYâÅ2nÈv°I]X[YЦˆQYî›otjOÿÀ7qç•÷ ATsÆfõOÃÂ.z�?½Ç ·Lžf%3Íòb,sK¶½gIÐ<»Ö.˜>UØŠ'ïਖÖ/g"²î“#bfŽ‹Þ½zkÞ@^$ !᪤£¯ùÜ!F"o ¿…Ñlòf7ê98Çf^ ‰3CP¤Ê­C”Ï‚Ê ô¼³³³¾¾Îð<±ªHYŽ ®òÛ¦ml!³Ñ^Ìe4›Í^¯6*Êre’ ÆJÞHÖétRI¤Ï‘j Óé´Z­À>Ö[þå_nýÄOÌÞ¹sº°Ðùµ_›»ŸÕµöòËÝ7ÞHDY[[KY“a{殸±šP WZÒE³—b¨ŒYtƒÇ³;#ïÀÐlõ"ÿ@¹@!£pqc‰ê„c×…Ôõë×ßýîwß¹sçÿ𙢓û(V‘ó:Pa ”DV¢‚ûaä"mžô´Úæt g÷9år"åÁµj—U“=Lê \;N'Jj›ݬu3„„%î—•¤º 9€ªÙDúAE2f^ >Òþþ>ð´):¶Æ²Ì¥±‰.,2òÐ$/ i´jÊy¡NXJùùù yîð¡`?G@vl4ihyœÈ]kÔ 5tàÏâÝØ™– %dª|~~>’šæXöp‹œüc³øˆC±¥±ÿé3s0ÑF!FÇãˆÎ¡´–‡vê›�è0LËñÂ7ƒ‡3o¼1~î¹¹»w¯¾ºð…/œ\¹2~â‰ûÿøoÏÌ<ú¡]ù­ß 8sõêÕ¨Ý ¸’Ž ºSR „À–Þ;ýöê¸áp¯„LaBŸ×”³ñجí¸<äÅ<kî¹ÅÙÌ­²4Tz?<#÷Ü:·‘hX&J-,,¼å-oyï{ßûüóÏ¿øâ‹ì \™1{¶ÞL9/àÏÜ 3.†¾Á¥Í”#ó–'’UØ`Åjqï‡×GÐ(׿7`²“B†tà¦0,iCW¯š=r‡ÐÎ!4ŸËsÁU¿T‚çXq‡‰OFâIímÍ h\ËÒÑÔ¼>O+vMÊy�Žxª.ŽZÝö˱"ˆåËyçS˵Y°ËV¡”óÀe¶-)ÒápfmZDÑP!¢UôƒS¡@} ¿ˆ{‚Ì}¸ìç” ÁdRˆä,Ž;ÎÞÞ^* Ñœ°KKK|Í@+™ý„H–ODŒfgg[­³{!›q‘³³³§ §33¥”ƒçžÛÿ‡ÿpöààÚü@ë=ïYh·s·;ÎÊÊÊþþ>gº³Á¾(2‚û¬ç‘+å ¨Ï> =}BµAœÈLÆcLž¦¥ö¦Ï\fSàú{ï°˜K¥šä‹$VýÁüÁ­[·˜^°£¥áÜiZš]bmbu8÷H˜+ D«fe*¢šç¸‹Ô7ŒÑÏ48áXJOÒò-Ú·|"—E5C¯¹‡Î·è#’lܹ)ur.¬Ê,rüðl  ‹4rªI`Âyõ…•<‚ç•äàçAò) Ý/k´nwwþÝ®"«ÞøÞ-³ l[m§Ëû÷ï§)ÍL€­ÛH¦H«Î™Éß…ùqßÕ«;[Pþ,^œu6ÒiM V]‰(ý~_ËdÓÐbô››œÃ´Ýn¯¯¯C'±Ê8ƒãñ¸yzºð‘467Yf¥ÛÝù±kä#‹/½”¯¶¸°°¶¶‰¶`O&“~¿Ÿ##ÕX€Á£££ðÙrèä¾ ‡CF&srÑ誂 @äp.U¢•~+CïEÚeåüœceÄ AˬNöͪ�˜~s×%¥”ˆp»]Äjä„…[XΫ\çTeÂÖ�ã) uì«xŽ®Uõöq0]Å?nKµ‘@P¿‚–Û°£jÿ0²†øÊU�ƒ€öÄr?#^|Yå\üÒ/îéŽAª¡áÏ\·]5É­¯çòœqeOT#iì[|AXôÙ'éuÛÚ«ÙlÒNÈGd§å¢²vjßl6¡!б·)Üh’GæÎ*tÛ3:ÂðÝ�Ö°¸:$Ÿr~šÏ–ÓêÊC!øI*³©á#·&TifׇÃ!¢pü!md¿˜U‡$e4ܲ“s3íÚÒýÿÁ™ÍÉÉÉÑ‹ÆÜk¯åß›­ÖÒÒR·ÛD[̶ó)Qd(gÊ’\XŽÅ\s"k ¶r&iê9A·+*'w¬_GîÌØ T—4§+Wð¨Â X€ ¥‡LîÏê­Dþ$&Ì$ä»÷ŽÖ.ÝzT¸ë"‡Z.ÐiÆw‡yÉôö²Í©?À¥‰ö·��ÄÚt$ßv+Ùö ÁTvÌ5§3ꦩ)ùš±5Éþ½¤\ü\g:ynÒFl}­¼PCæ…ŒÃ4D¯Ñ´‚MËɰ½ÍÞ+OzÅ‹‹‹N'¾^pÕP³ä”nLHM§ºŽ©¸9”}4_Z\\‡¤677c[ wÖ¢NpºVÙI¯…©[Ë€š…Ïq’b¦j*ã"ü¯˜ÑÉluu5°XÔQIäÈe÷ûý<©¨vÆ„¦ÑhÄh'htÕ ÚD+sŠÔ¹3ÃáÊÙ2ký³vzãÆÞ_ù+“óZ 3½‰0ò¡Ãá°ßïçÂVWWs‘‰”Ýn7!0 Ýnw?a�޵ Bm�S•ŒE3ÿÉ 8”©×™ÿ¥C�›ßl4�ç"¹L‹,Xúšµa3Ó,{R·øÔe{šÁh`ÖZÕÿ÷à6 ²ÈÐ/lÆx+ª<çDGÍ`{b!]ªÞÊJ v"§Ð'*R*‚¯‘C06 ©ß"Û£f¤.Í?wj/CÎEÖ7YëÓãÇH°XŸ ‹¾_eÀ|ÀnQžȆ7Ìê² œ—GÃêƒh”9S6�ïlÓk ¾P ÈàRë`·’\)—m_wPDë¾ÞIe@„ÙLÛ•&[¹‡Ýel¡¢Pó ö*ž±2V:åL1aá^DŒبÏè�eò?PôånSXL&“œì¤™ù‚‰=9}2š® egúÁ7~ãâ‹/–NçðÛ¾mñÇü`ww²´´ð ¥”ÃïüÎÅ_ýÕÆì¬Ñ$J¥<¾Á`1Ë`0„«277·²²qø ¦t#8 \“;IÁ ’V4u.j<X@“•’c&íp– ¦SÌRâ4“²¶q–ª.n3J YÙ3Îð߀—=mêV¿Kg6K%½ C(ÔÁÆÁˆÿâÂI™b}&~öV¯f« cmË×§¦AùÛ‹¶!X7Ï— » 9üÃÐ"aÀ9’éöÀ°§gâ ³j¶I6‰(•½›;{ $€àg…•Ù<ØpâââbR»üÚ#$‡8a)é!k·È3ÔŒ5&ÎÌÁ­šC&I[„ÃtçÊȇ·òà=¬-ƒ t_ó>œe¶îÎ Îññq§ÓÉ[A•Žî@Òí$­ôò‰I]“}SÚÆ† !¶×ë%N?ø¾ï»þã?>w||ÚížÎÍ­ÿè~ „lµÊ™Pžff SúDõFc­�A~dŒNÏ'Y¥V›*LÞH­LûæqÓ†1ï†K2ÊQ˜[ÿ¢RȵPMµ;ð­€GWd�Ê÷ êó! Zs1TWEn0qŠ÷׉˔æiç$Ó$sÓÔ¡<ä´X0•¨Mq*ª*¼mŸEɺ`ë†Ò6íXzr.†´æã’ºdz˜‹�“dßMÖ]\[r4^Ó··[¥OãmOÞdrlxÄžˆ^ثư€'œYú WS™á…cè ‰Ðdë2°îaãpC<³É¼&ðâ´ÊÀ¦s7\øð™™év»9¸“²'ó¹Q ï5R:@9µc­°8eDBó)·oßvO+~wwwnn®·»»wrrïüƒµ_|Û?ý§¥”“n÷ñ/æççW>ô¡ý?÷ç†?ôC“G‰‹AÌÙx@±?°BÚÞÞ³A¡  ¥]¹‡Ù®Õäõr~Ü8kbj>ˆî”Õ`ÝÖNákñJ°}§˜÷¬ˆû‰ôTÖ3÷Ö™g–­•sÒ›Ñü‚G‘ Ab!D&èš ÅgÞ¦Qkx§Ö©xkUa—þm]S~XóL;¤å"ÍÓ1rÀÅ[¡Ã@¨Õê.CÎÅÇ›$; Á½B&aMƒÞz@ŒŒÃâH90··sMJ3¾rXD_2K9+s—ü LX ýðÌ ÌT0+79Ë—ǃ‹U@‘¨aOºB"û3ƒ¨"A%¨#Awžˆ&X°&&7Ó• ]¸”—ê…”„| {‹¾ …y|öƒ`ÌÎÎò_GGG½^ÙþÄ›¼2lެ–¼¸œ™<(åÿößÎÎÏ7ff†o{þÓúÿpžÎÁ³ÏÎ=þx£Ñ˜2½1ãJLít:韧~"Tç†çÌ0”gÉÍHSÛa—U\öT (b øç&Yj¯ˆö$=·Ö‘ oBò®’0Ó§í™y1‚†ï0õ1Vææ<š Ç 2³æùD«?çoÙ}F#Àʦ]pøAYû 0`D L«´YI%aÂE"ÿóRm—wr.’>ü„Ù³/.;.je­Û’€Ø�MÞ›pjsd@¬b¾F aø3$‰T<Ó†]|P¾¸¼g†Ð“ñ(�‰ çÂ4«Ùi¦Þ´d/¿cÌ N’Ë7‚Òƒ8&Cp– 7?== KKKæ¬S¦Àôä¯Ï_^'žÜâ GFîÆ`0 óÈÓ‡:77÷Ú·~ëkßú­ËËËÝn7A%ëÐ[­ÖéY«ÉUBfŒ –0dêg·³³“ú#ÙC¼G÷÷÷Éyñ+# Ù_ÇB[ïóæ­V 2^È/a(й4£—J¸ŒœÉŽÔJ舓½²A"i³É:ÈSh¬öäRÛêA@¦ÆØ6›«²ßæpç` ”3¿;)ä|f©¹gÉö¤¯–ŠÇAÅn9X«V^ñbgaS÷T˜$ør&íxr.²Ê}[¹¾Ó7�Ô"Ñ ‡Ï™ å±H,UEÞ3@JÕè«N|÷r«“Âc¦�X'ʼgg|žÈ&G˜L?¼H'¸È(É)Y-) •SeÉã¤;±ÐD^k¾eÒÓ6šQvKZY …)+ƒ•3×/ó¼!Xx +D‹‰dNÕZÏ-rœà6ašñA”©¡9S¢ÎÉïþTÉ J OÒ\OR Ž º2*hµ›RdĈ±btKmR„~W¯× èGÝ™ƒÒ=pû0U^m•›µÏ,ÙÎûóè±Rõ‚Dã¹âÚÁ�6~[Î[ëZ—¯È¥”ˆ0YŽæÂ™nùWl*û2¥sê¥kKº*6!@Á¸}‘®‘Ø ßy€¦‰_küuÝ2‘ìÜdËÙd8ø†“qóJ³½“/"ÝÎþ§„Ϧò4x‘‰=}IåÜ´¬a)ˆ -w7á+©'Vð‚hæ§ÔÈ©g^µ{Ql6Sbl­ ¼�Vn‡lÀ=SEÍ2C4œÇ˜gÎúƒƒƒ”óæFH~‘T¢gã±ßÈˆå” M g=t² ì¹ÈÈ`Où'ÒäÍó!ûA=ÂìÕ_6 VžE³ÙLT‚u¥ÐAÛÀ<³¨èWñ5¹3>™öσ@ת:¹×ÎÎN Íl¯U2fÎXŸß•G†kežŸk–?zE¯rµ dìb±å©<žU¤—Í:sÁ ²ˆhØGƒ{[¦$Eæ=“7wöc¦Ÿ™rUc¿bФu„ª–Ú+]D3 F£QâÀxÅŸ6†qr¾"jg)°s4ÀŽ‘e°2TI6‘Ø3LœŸ4�þ$ܬ¡Pu­€R-šJ‹Þ„ov©3)ÿBó¶Rl³º-͸¨yÏWÎÙEš=UVeùáj' ú^Îa[­VP£|‘€NŒa&Æ;õ£ŒXZZJÅptttxxý4îa“Ã:W^B29sFÎýLääD@d:ü7¨Ãd!`2ÖÍ˼E®-ïPJ åšG¹¼¼L`ÈíFY3écíííÅÓÜKNØ<š¼2ï¼½½rÁ8Óëy4ô¸Ö¶¥Çí¡^µëÝêÈʱb[¥2å±JcbŽ^&UÛ¶Àr/„hÙ4»;œL¥q¸‚B«²2¥†?VΙ)†¼ž§µÚŒzïégUXÎÀ2;”»2TÌû{äèÒ¢íâ ¹zRÁ1ÀjYXXœÝÉ‘™ÉbšYIk@üœõ0f*D5£Ûvöätã4'wƒ`c*Ër€Â%¥¢ïš;9P¼žØ'4`¦ù ë];ºáŒéÎìììÚÚÚp8Œˆ Üè8ÙpÒE¹9¦™iÃ?IýáÔaaa!Õ@)%ñ)#¢1"$˜¤‹`k¾{¢“ð9ÁÑj„0°‘Š0·bee%eM¹u¼[³ÙLý~ k &MA˜9¯ƒéFõ`ww7̈< èòE:ùV€ÎÅ3éLÈÊ©ÚãEs—¤  ¡YR/Z’��ijŒ Éâ1b�b2¹€c7‰ŽcVFõi2ÑÄ"T˜¨–uŽv�cÝ•\[‘­ª]ÛáIZÕ)(À©•g‹&£íZ :å–ºsÌ+!ÎU*½4d6‹«¥†£iwr.˜A`3,& -¤Vù»WÉùNûÝöœ°n½Xq™Ù-¨GìC ª#ìw3àk2’·­MØðˆq«’ÅŠ$Ú QðWÖ¸¥Â£¯nÓbÞ?;dss„¤:0˜È¸eºÜ <«‡Kûh4ŠÚBJ´Xœ/Z[[së•^Z°¬ˆžœœDk <þSŠ•x»Eša{{{oo/„‚V«Å€p<IáÂjK {||œHà(ž•@SD!_ii)Ë2_3·¢ßï—3+³<,— (ÒgíD™†ôÅŽôìÍ ¬D`E>ëò™ÆBÝL–€šK"Içx§ÌòL˜µ—<­b]Dz¥�ň0:Íü€ l TÓ0f`æ¾¹Ú†5šªÔ ù ”&dQÄ*«Þq¼`Za<<ïc&I3jXlO q'Ó—!çÂâ €ô0«¶a…_±Ü«ÄàÄ#¾ç6ï�u©………÷¼ç=“ÉäsŸû\&áyÏ\RŽc^«áÁ¼IXF•¨Œ5Ò«¯À§À…­*z“Ç*¿fÒs*¤ªûJo¡Rº;€-d‰¯æ5ppÀ®•SÃŽ–žlOLÛ)-÷—^zi{{;OáêÕ«ôêÚ// {0t礷ƒÁ Þħœ¹àå‰çq$–�òÄŽÛ˜/è‘kF[ê„¿¸bâ\rÝ‚ ýé<·òé–1†çRéã™W 5+厹0_j9ïï—t1ì ÊnäxøÜ·… TRXPÁÈ×tc”…:hPÀËy·4³`Œ'.’ù@’Î6P�Šä€Ý5Lvÿ“f&¾FYŠÉcŠl?s(±Êtëÿ^†œ 9z!ïÛ1Ðï¹BØÉyаZá’2ÅbùXÓQNOOßò–·|ðƒÜÜÜ|ðàAÎ)-è –bƒÝ‹¡NÒíD&BŽ-;®† ]ÎÛmñYYq€ƒräÐÊA€ÌŒýá—I§7G¨Zîpì�bF¤®ò'ûûû–*A?ÌшC3„”HttôòË/F£ëׯ///çùf²'L6x˙ֺýyψܤèÌ´iJعÈn·{ãÆû÷ïonn"Lx¶¾¾îšÐ’ŽÑþþ~.2¨A”‘£¼yT>ó{½ÞÎÎNoHÂzà>YAÁ+gºsÕ< #bNª &C˜d¿ÀÄ¡® )x¬Å#¿¨ˆÚdåîás=ß° ¬�¶Ì 3(™«]]]ÝÞÞŽb¯Ì>â³ ^Ac% …@¨FO–TÒ-fÚr7rȘ#‘/’5Ÿ �€)®ú ËC€ çÝ(ßé\ör.þ'‰ƒž ¹6\aèöd¬Öt*²2M‘Žò$ ý~ÿ£ýè`0ØÙÙät2C9ì(ªòÊ€ rÜ"-p'—̰N "Ë‘³¿I“çU‹ŒDÙä_vHÈ8Œ³x¬È[ÝgòÞà«á€2€à̇¶©]Þíúõ륔N§C>Á&4ÜÇ–H ©H"†¬/•V¯×Ë3 Rúý~n~l˜œOmš§–ö cÔ¯6ã¨E¦!Pa ž yóBFÜÝ]³O«ï»Í†=‰4-€æÑ4R}æÕpå™Nø Óì¡<ðŒ'À¬í¹¹¹ A;Ñ’€)_}ôÑw½ë]ŸùÌgr«m`S5®Ê™ªà$]™éÚ\mÚÏ ¾ ŒpÈ óÛˆ™ÛiÜêéxGΨw5q?Ä-{úË^†œ øam±Á,i ŸH–nuZ„Æ›ªÈô3ÕéÆýû÷3ån޲׷iZ`ÐéyV=!J¬±L"°M¤ûjCd£t} qü)çe£LÇ40lå›ã¶'á ²\ÕS­Øen’¢Ú…Qü  ‰Í©Wr"ÇK°$*'a̲ÓPä±0A›.A%èáp˜wˆÀÎÎNð7äsŽŽŽºÝn¯×ãHŽnuOÜБó˜-€X¸àKLn‚û3KO!WXzÌ’²�…9kÁ¹ÜÂ3@¾­Sµ†¦«ðulë^õÏéGòþn ñb.#¯·[nþäÞ½{333[[[‰Ð.-[dÅD—Çá4x 9Q{7ð•a‘Unñhì b…n‚óNOŒúÌñTéh—Ø`÷2ä\0=Ú”G;P¼�� �IDAT‹÷‘db¨c>2�ì¨!ö�>ØèÉžZðh3jGÌt´9`”Ìžô.šÄ$ë÷4YÕã­Ú3•WÄX,ž@3L›!êT~Vê,²…Ø1ÑȾRLÿXáÃÍ$ø÷´Lå¼Kœ°p2wƒ»mMUиÂér"cú5ç~·ÛÍ!ë›v|||÷îÝ¥¥¥^¯— bû¢áp8âÁ“ † ÞczÑpáò懇‡ø³ÁU©ÒðÜí|;ÊÞŸ i¸*û]ÊRÉMN1Áè:FFç�ެ©c->ØeÓS Öþ�+£õ ­€6d|QY·XdZv2™looLj¨½=]ü¿ì½kíguæ÷îÞ}Û»ûÜ$!$$GBbelʘÛx\À»‚Á ®'Ç.k\cO¦*©© S‰?85ãT“IÅI˜r&)<N°]±ËÎÀ@€ … 2·K:H‚sŽÎýô½{w÷ÞÝ;ö_¯­äkó¡ûu8ê³÷ÿò¾ïZëYÏzÊ,Ê;ÛÜQè3'Nšeµì|Š…Ik˜ 44Í[ž—h5<³œŠÔH2veä I©á$äG§ßï3[ç)„`©,b»™nÀZ8¦ö e›{æékä¼üNÔ·|bæ0ƒ.˷Д©Á="S&{Ü�hÜ#5fõÄ 3ßä Ä8RŒî~y<WÎÀ‡¯ÓƒFê3œŸ˜ #g7Q6U`æ(ggg3ƒ’ÿ›€A€/.¥‰I9Æãq :sl-//#;†\±̼ Ô¦y†y8©–rB­¬¬ŒÇã{î¹'4å^¯róÆÆF¨wyïq*K¼!uà¾ð˜ õ­ëàlN¡")DÊœ§ÇÚ$Ûì~¿‹ŒÙ·à{&¡ð-y³¬¤ÑQ€ë6ñ¼)év9þ�”ˆU%8Ñ«‡ hˆo„Ó߆nãsþ—ƒ²‘‡Cå6†®šS=þŠiÑ{-Š!ä:ÙlCoáiçì&Å„é=45ŒÚ9XžT9ß+!Çdèõ2UNå\ƒÙJkÓ¦¶¥Ngõ{®Í$“l]€uäx9|Ô0¸LÚ•6†m|_d¾”/îñÀ/p“¶/Úì¦çå\£èqusÆr&fW>€ø[e Iq®Ìœòpòdr1Ád.*ãAZÂm¼|NÞKÆ,ÂUkG§Ä¯ÉwÅÌÑ“\ßnNQz<›››÷Ýwƒ&¡äé% b©@÷”ÙΈò(ß4yU ýjq<NFI<xvšsÜí¹M,ö×4ñŒeÜ&z€Ä*'#®Å=Ðfõ&Y¹íä&!Ö´M¾;¥ô7¾ú²H—Í{lÔí`àbˆ}ê9k?ÊMÂg‚â]õhx‰ÓãnÙY)§L†6˜y¼bÒ'!çHÐ(?v ”8‘$¥A úl'±b(@Êv…sÐJÌý–L^Ï!’ ÿv‹™Ù¶düÅ£a| bz )ó8¡+z÷ÿs³ìï"5<ºäø&æZ¤.wÄ Œ@AIc}IÿÍú+¿€ã¸ÄÒ"h†I Tõä¡jË9;77·°°@kÇ~z0ŽÒ€i­9s&/q8îììXƒ.\»vÔBa·¸åéÅ!¯ƒ¹¥|,Ð.y¸Ô`’tøi²gö[öb’pÈ_96i ñɰ.!’8™+¹”ËÖ¶£¥†ÙÛdú| ¼žbje]>ÓÇÉE,‹éöªéDö²5m‹ª›g›òÏI+AÕ#›¼Q`]Êk2ÜóàªEN‹œÊ Iú˜{90_aU²X3ªÍñÁŽõ g1„…ƒ²©MÊTìpsb�- Ä ãý‹âÅÅÅ»ï¾;#þ^7™v&š<¬hkг³TØœL³;'mš-ÍÑþ•iÓÔOMB´ÊLj`Ô¢kŸlw¤ø…Á`!ü@‘Óà«ÚQEc€ƒšl4eÊeøhÛìììlooçQàQ–“ã2$æµá¯[£6'‚©ÉœG B‰¬á4##)µ2²r&+ÃH¦I†MªÏ\apHŸ;L,ZŸÂqÂ9Vc¯ }ÖŒqZ¥Bõd0–=1 ,7Ä[Ƨ%>éXx€‹O'¬T·LSº¤°' ՃѰÂ(¥ (9Å®‡Íq õ´q'»Œ pmú«‹’‘Œ åº&õ &7à)œ„œã„ÔPÈgŒ+Qv)*À>1ïBG«¨Â’L† tÑ…4曼IZÊDÏ|{LºòÉwß}÷¹sçîܹÃäD>“š:Ù+½GÓÒ¥€cJŒ‰­´… ‹Ún†MЍ©LŽH“©N|°‰¯ðks>²uóðUÐH¦šŒLY”ÊR^d÷bn=Ö6ñ £ v.°äÆÆ1`ss3ƒúý~?ã2›››ÌÛÂ@P+‚›¼Üô~æçç———áƒE¼`8ÞºuË ¡©Éò4–––p-ã GÌÆ,²Ô4æ†õ‰OvÏ IB3dœ¼L™$dÌB̃êõz©­óÌó¼Öü/«¸ÆeÚ—[° …©’®D)dIó=nÌFƒfñvT—ñXÆ3y8¹`š4T?Ýn×úU9 –––2\Œ ,;×ì7ÅYßäZ”µ×ívÓ/¤È†ÐÁº5ÁšB ˆŒŒ =K¤Ã1¼vbDý=QåP[@öŽñ VK³Ã4õ ¿`ÍZú„Æ‹“çÀuEïä+¹[p¶ÕÕÕííí”8,>ã�\Lnæ°]œ™àßZÚ¹I¢ èò±Û¹ž~_^^Žq“«‚»17·­ûë„'ÆÎs¾Óÿ÷Ðaž ße³#úó”rˆ¬¯¯3yîfÊ4¨žÌÎÎæ<b¶ikkëôéÓy)’ä®­­%ðDù [,§’#G6´0Ö2óŸÑNÛÏø!;Q(gºçlÜåÆ"¡;ù!ÿà“™ÏYšoa Ù$ÆFJ& Ã13i“PVrÊøhÑ åFxVà“öå,ÿ ;cÅFùR³œÒ ‹z½ð^Žxz{Œmú0Õ‚V›LvÈ…Ñ$�éÔO•6*(_i)¹“s !‡ulþ¨áF¬LE/«Š)t.lšÚ+?ç¼K?€Kâ˜æLAb`0ä\ €˜1‡h^ÁÉgÓ3(Óg†­ G¨uéNcˆÏÏÍI*¯i~ Àȳ²j=Șµ+-Ë¿snæ8朂ãà1‘<‡´CÐÖå¹!M†µõX Àý\R®9 ¡ùäŒã¤!töìYZw¼Ë­æç"ƒ#Ñ2DX…*BÁüü|ÄÜù2¾ŽZ94–vT·‰çƒ>åTqÁÈš´"2ù-fNVö3·ÓM+›q¿ W•¼ïˆº*"D,+C8»?šã©×až[“¹Ä*/£ÑhmmÍÕ3Hx>y›\” Nô²ª!¡ ƒ‰´¬àA" žú›ò—\¡ø „œã¤«e“›ýÂùâ”ÿG@&fØù5DtÚQ9ÎÒ#5jÇ.uÇ9}+¥çs‚ªµã̲FÈ‹FºeÐEO ²à`5´ `BöqÇ·oߎ¨eÁÜà 4‰A®A28$‚L.ÂÆizãô'"A”Ï!ŽÂ? ª¦Q>"An °ûɦzÕg¥E‘§·»»›é˘_ZZ²}8`=mb²b7ì#P{¬²777Ã;È’`µ€ª‘_·£Ö|EH&O/‘ƒ!0ô#l_m¡Ç¬ä¤Î5Оä‹hA9—7Ý!™ÂìBN D—5hù±¿#ÔÙ­Ãpb“C#x²MÌóÅdÈÜT·K ð†µÙ>Ð%ò›ô,ÿCjk¸rz"l©>a3ÑËÅŜЎŸ±Æ ±a£FÛü_±2sÚU&à<Ó`YYô4 ²˜H~ ŒðœïôQ¬(Ã7"”€Ù“Á Â'÷Õëõ1§ŒpÂÈW@ŽpwÛJ¦M3ª\ Œ[O¶Ò_ {Yf§#4Y*žA«,jH“T=w—Ö‚³?sÞ8“¤´E9^nˆd±šÎßSJž9s&Ý ·âóH™ªq«€>¿ ñ,‰ÌZN©ÆV`âáÚ‡lhz iÆøsx/yb`†¬mÊ zZôo6œî ø5Š�FŒ™k¶Ë5kÉ “ fØPî˜N:ûŽÄm=ûêâ_�į,?”M£ „|d­B+P³Ÿ ÊrÅfÔb¯ äl.°nÖ$ ã'£ ÇüÃN€ÿS(L6º ËG™‚Ñšó…œÆÿ¥ 6?‡N’sÍ(6 Á¹Ó4ª™S#ó3GÚQiclBHJ,k«k#âcÁ£b-„ܦ´yP&ðPøóX€°Ó¤a[Z€Ë¢î&ï¦80÷=¿†Óvš‰vĈÈv<C(b!žL¶24J ›Â—Œ¬ª$Þ?œžÎpñ¨Ž.œ4Ÿwðà2X?Øä1 ¢œCã´ÂŠ›<y“€ Hà¨Ü1Ðç)]²æ<Ò& Œiy´éÉ|`O ‚”â¿ÍêÔ|2´@‡4³ãŠ`²p ì¾ ê¶8)8¿5îèìºÚHô°¶×�Ù�œuæö\º„œã,tÐUkŠçÌ ¹ˆêžn¤Ûf×”þ?òÆxQ·Ö¾ïàà?™pxœÁåb~«×ûÆ„C&‰Ùìm�"O/ãIåF+è•6 dÏš+æª²á Ÿæw6i0ÊPT¼8 sâû0ÝÉ»°r¹ZTCÈ „æIuÂXŸ„ÛÑh´´´4œüØO…!p ¿¥3A3R»ädɆBm{½|2 iöH¦Vq3SfMB® ¢ŠŸ’«Xà6a³ZC‰:èIgmƒ£¢¾SlZèñÀ6´Kaĸ•R égÎ8K‚¤p¶ë¶Î©WðNEŒŽÖÛ$Øf8& %úZôÖèù‡•ya¨{Øét÷½¬CÍÆ§™ií¨Ý”"ÌH õNØ+Ú"'!ç8é®p9#òÖ³ñ¢ Ü1ƒÙZ˜ ¼ÂžƒòÉý£Ñf§ó?ÍΞ;8ø½ÝÝ\Ìß^^~i4úùýý»÷÷G“]ï :äLÓ™,›Yp‘ªäz˜ÅñΟ6¯å`Ê€¡­ h“b{/ÿàÞœ%"É+­SÀÆWk-ŒpzÂéÌçwRó©'­Ëåð€¥¤ ÉqÀYô¬/Ž™¶?qòÆx¤mwPryiºÐUâ 2Y’sPv~Bæööv†Lƒ¤Ñš C:žwOÚ# X¨Ðçì¿Îc„2ƒ‡&±ÐÒÅsv.°ÑºýEçÆ\2`ƒÜ~ÀIC¶Vã½X%“hmVй|5åÚ4]˜><&Lé†2éÕŽê›ñ||;îÎÚ·éjÄEˆ-x'ÐÝ .êκÚËY¿3oàÖï1ÒÕNBN…¼�™÷FF ìˆé- n=ßž­åÄÐÃŒ¶éõÔg·Û]98øG{{ ­½ñµ¯=sæÌêêê?¿víðððÿévg»Ýœ9Ïö›J@7p Iˆì.øÍÐuåC"Œ³¬šÛDÙÌV+žO$sef7¢#½¸´¢ùI@% XéxT}b/¥B“9ZΞZàð²á^;:ÿh ùİÜlž[2e>-”ÈCðÌó¯0) ;’?d¾/Í0󿉑v¥m½ñx¼¾¾Ž6(=0jÙ¼|*óŸÒ³ô8sÍ€‡ð¸ÒŒk ª”Ó´ÍÝNÈe�1Áæ .DŽÈCÓh“[‘¯M´,Y6iÑî.dKÏÕZ»Ö.2ìw÷9°´ÏH*T NøŸ¹0ôú>‘/›–™É™@^’Ó#ŸOñD-nGWZ/(û¹….’éØÁ]Ì'Ǥ€®DÊ“s<UÐyQD§—@Æ”#N0+‡&gÍN¨pI: #Œß<ýåÜÜGî¹ç-oyË£>zñâÅþÅ_üüõëo;8x¶ßoo[„¼¾õÓ<$AÆ5ήhœ¿€ì>¡Xèd¬æF{ÏG¼+VâŸÉ¾®~Øœ>ÂÈ"4Âi ÏQ–'ï.“Fû!û6t‰á4aÌ39Çé 9å´Ë¯Y|LðÀ› ÓŸ››K’[ƒp K0БZD>-~qéîÄ>ç`òcp¬•/fƒNù‰O<@nÇJtœqf=±Þ0ŠhS’”<RrS:yS´TAóìõiy½R©4©–qœ¶Œ¿Ðƒ¤ J!ȇ$×1ÔF@"“� (ì8KØìÑôBC� }h‘0<œb–Áu’v„ߘÄË«PÆOBÎq2@Òœå�v§Ïiéè£*5µŒ¡zÛ?{"¡Ûív~t4úÃW¾òMïz×/üÂ/<ðÀ{¿þë×66–G£w,mn¾4ji2Þjí.,4)4'àb”Ü ;vË9_œZ’Ý{äˆiG©¹æO©Mah’óῺó1=Ÿ˜=–O#9M`[Ë™k)»n'ËÃUÓ]�Ò&yXX¤Ãe Ê k‡`lldvœC*¹ÿòòrxnaaa!³;ÝI ›´:«"ØaÓ!„,)§UÎ3’�«øÐ/sìÖ©4\ln}±Ø(ó[n1Òžanšžœçpamð÷)¸sQqf̅ŃMgø×¥35“ûI¼bâE¡©EÐÏ Y9ÊAá€Ù›¤ÓMÊ/¼¤âcbwÏ5CçËóÌ5¬NOvF`€ã“> 9ͽÊâ‚Cùì”ͤJ |tÜ¢´˜pjÞºG¨™{ì±×½îugΜéݾýµŸù™ç?ýéw|ó›?xpðxk_˜™ù/{½…»ïþË—#¬T¼:Ø Pª¬åLo<«ÿÁ¼yó&.Š¥'˜ŸŒsRSì 7/t{èÒvzYÑâînBeâÒÒÒùóçûýþÓO?XÉr;|x›x]C=r_AF¯œ/ç¹èÓšd»”ó‘jIXÔ” ªäÖVWW¡>çemooCÏ#iØØØ BP@3Šß&Ì~e¹ÚÕÕUâ×µè$¸•—k4>}:ÞØù_J./`'×Ì$RÅRŠ¿júáзìÝçNJ‡¬¨¥¥¥'žxb8~ó›ßŒœ ¤¼â<™ˆîP “L�@™ÕÉè[;"f › ›vÔa³ipÕ4ÓOp@HàÌ™)…\ãSÅ *Ý<J=PzWKk5²Â ·‰!n¸Zò$äÃOÎ5ˆÎŒÇ'mD`Nf“`{ði)—&OO@í¬R6ú+£ÃÃK33Ý›7ÿⳟ}ì±Ç}ôчƒ'Ÿzê×/_¾¹´ô_þåß]YéþùŸô[ßzþgöÔ‡?üЫ_ýÍo~3ào‰…ßäœ2£“Q¤ ‚ÑÓ°ñ중ÆR*±Ðs§DG:óîU°a€ã±3??ÿÄO¼æ5¯¹téRC.žËæ°ó *þ%Öƒƒîz5_HÕ€KOdÁ -Nî{¤— fnnîu¯{Ý<ðÜsÏ]ºt íê°$ˆ+4¥C‡#] é38”³<ê¼ƃ҆ ÓS¨ËËËËËËÆ‹I!I²E¡ýsݶ:¶† ʍþðúýþ›ßüæ_ú¥_ÚÛÛûð‡?üõ¯Z™2:y›eJ)]ÔÌ“YM™7#˜NåLÏS ?ÅàyhxNbL%@hÚm¬Òúý¾ñyÈÓNL=*Þä û�ï(Ö˜G8r=Æ„ù5kBžT9Ç_èÐ,žÊvˆÄ¤Nýkr*q jõôüfá8ýÁÜÜ_ßݽÿ«_ýÈG>òðÃÿÝK—Þ¶¶výüù÷Ý÷Æ7¾ñoŸ?ÿÇçÎýþ3ÏüôÍ›sãqüŒÍ=%¯w&E9O¾Ï?‰¬¤GÞ¢ÒQTæ8ÉË� ú°q|³dX v¦!ÀE£››› J¶±±ñÙÏ~vyyykkk~~~qq1³)Fí°=�”42º]¨ÿ¿fñP£ÁÛ˜9ûÖ*#6PáUòTq1XZZzüñÇüñ•••çŸ%žœD¨«at„²$'ˆåOr1ñëPEå“Y÷áp¸¾¾N[Â1þ oxÃÙ³g_xá…+W®´Éø*P!r)Ü”ÕdzÆò;9C#tÉÈiëÌó§ÄAï’ÕK›áöíÛ[[[é¦À±tbÇ!k4Ÿ<ƒÂ4 nÖ“&©J4‚JP`´RˆL¶bƒðAD¡°2G/ÖˆY·¦ä‚'‰5�†ÕƒŠ°V<ù"f=íÔï÷OærŽùï©l$sÞ­aC>Ân±l9)g„]ž¼X »lfff<ÎÌÌ|¸×{ÝááôùÏ÷¾üåW­­=67÷¿÷÷¾ïÙgOŸ;÷ýßÿýÃáð+÷ß?üíßîlnÆÅ=Ë‹’Â9;588€7¶Ö0¸š•³˜ƒ&…<—¬­Â‰O“ƒAkÐ ZŽÅ8$œp‚éÁîïï_»v-÷›>9ç û(m"ÑM aô/O@,áÕetÃà€8PÆJ̵uÆmožèq}þóŸ¿xñâ·¾õ-¦”˜Í‚ÐHuŰ=\¯œP *yvww‘Y£;)Ú°«Ã’:þü/þâ/ÞsÏ=Ÿüä'ÿàþ`gg'åMyD”t¥ñIäc‘Lû—› lá}Úþþ>Ò:»»»_ÿú××××wwwSׂ\1ýV\Õµ¸áH•{çýòi$‹Œd•MmÅ:*xÄ›—Ë5äR¸‚îAZmÏØæþnãÌPŸl7eÐØãº©çŽ÷°= 9 |öìÙùùù›7oZ?œ÷“Éø°ý`V”0Sxgg'©+“IJ4#‰ñýýw ‡ÝÖ88èlm-ÇÝÑ赿ù›§Æï}o€‚o}ë[kkkwF·o߆½ã„ÑSÜtàéâp9Öí¹€.GO›È±Ãþoð,z�+£I€6MÞ£l3‡dq„ìà"s „:윷(ÞãéKp¯]�c&E,’fi;â\åÌ"±MÇ›rxxxñâÅ+W®ät3aÁ,ŠfHyÔ€ûæÖ'ËæèÁ�˜dO3Þ¾Nb5¦É„¢ŒykΩ= OË„I� `H®®u_ʨG63aí~öÙgÑã] =cãv×ÿ?”Û'’ô˜Ó¤Ò.ô˜x0û= À¢¸A×Õþ:í¨³NÑãÀ›Ã”îb‚ #€´#‰…åq)†çÈâ4Iý$äçÏÂÂÂÿðïïïolld­›¿TZÊxmº¦ì5ø@{™;Öh™¬ÞÛÛûüÜÜ-,X 㣋ssO½ë]ßÿó?þüù«.üéŸþéåÏ|æ©ÍÍwLæRVH6òz—9†ÒÉo¥t'¤ø‘ƒÅ1Þ>îÞ&hkqzЬIrp€ùà/Î Ó Ò%‚æ;57ÏLq×:f+™õ„„¢„Xë½Ã{öéÌ:=[kUµÉ°dЉ|2jCÁǃAú7Q®Ë£ÞÙÙá @« ˜#â\0C¬MÃÈi}yBšu“ÊÖÌÌÌ•+W>ô¡-,,<÷ÜsÑvã‚ æÉsZñf=¶^ÂäÓx¿†æàÝy²:" fÖjªLÆñĉ•v §6n7Ð)’ <lúg³&79« ´ºqÂÞ®a1Û0;ÅÐ G œ:ÔuÑì( ¿ÞAÒ@5xìEâ¢ê}rŽçg8^¸pé*7'Í%µàA3XWà(™õ´¡H“ù¦)%ãÃÃÒíþ/ø‡²·wñï|òÉ'ï|á ÿéóÏÿF·ûÆ™™ ]dsdÇ„@«ê²Rí1lz"Šíx“²ÑØ€ªàÂ݃;JwÔ)ã íåä7,÷Kòëa#˜¸þ: 1ÐQX^^η÷ûýµµ5Æ0ÛDÒŸÓ&$L•–é`¢,…üi†ùfÁq;9aSh'Â<l²Fæ'Á�ƒpôµ \§â1²Ç¸Ÿ+¤˜Å-,,¬®®~å+_1×€Ôžå‡è'”EZù|ŠfëPÊ7Y›“däøKT6ºM”#<ÓfZ ˜¤G<[–Ó¹×ëyX˜ Æ*·E–6ƒÆÆ¾¦õ|‹ÞŒG¤´k’íaÃÛ3a>\y6#ð�ȶ¯„ì² ¹Mt@Œþ•{rŽç' åêÕ«Ýn7¸9zˆ>%¥Ð>ædñ<¥ƒøLDÎ)f Ïëûûìtþú¿þ×oýâ[]}n0øÐÜÜ…ÙÙ6q¦ q©vWNL½^/¦lV¡›1ùË^¯wîܹZõ‹ë öb©ìþi®„™9 [6�£/Ú!4“Ìüi¶wyÄù…µ¥80ÈœõntYA.OL‡#×´ÒÉéïîw´··Ç\s*¾ßýýý¼Ž|¸ù,è\Õ9È-ÇìÀ¸?gœqüÑh´µµ¦�ئs)[Fáh—ºUºÀ°VQò,KÅþåy\yÎö€qræé*Küª³Vg%9ÈD'CAãHf˜†g‘q¢IEkÝ^GÓ‹0PŒÆ ¥dTfñPÓPIcÉcn'9 ` VÖ”ÔÜ8Ti²V¸Ë£“sÌs9î{Ûç5Y'kÔRlmh¤ãb Eõ¡‡‡W¯^eªí?çS,…µÖþåîîA§svw÷ôíÛ÷ǯmí‡:qkû@̘D $³¯×ëåDCM6…vPÜï¾ûîG}òãqO�� �IDATtiiéÅ_üö·¿½µµÅð  ™MöìE©ŠÛãðª=ý@çlÝ_º¾ܯ£‹5¿mÀ:···É^óŽp•æµ’Ò¹äÂh\aìM5À+ð?ñü Mlì€ü×ÌÛÞ;ÌI$òL9IĨÉÓɸkD:ö&>$¨äéaFàœ‚]23ˆ.s#ÀÃuÆ‚` -¸& Ô"–KB ›zÝ*´æUÒ(×¢‡¤ fF¡yË „]Èu–08É>…SÀ,V®½†Ã!UGG`@‹XÛêÆE ”%C÷¬yçÁŠré ã� ¥øGœ„œc ÁqdpÔÚš¬Éy×#ìjŽÎ’ÝoE‹½Ñd“co˜_žµ Ñ(ô 挘`f,½ TgÊ+=g`¨¥¥¥‡~øüùóɸ¯\¹bQ±&Õþ&´«$kåfè g6j6Ñ/@¨ÔÃVó¼c ‚”´›/ é¶ÓÆÀYœï9)0·Ÿ&;™à[¼ëóɑƱ{`é ñ´Sšäw2ÏÈ€óL\,êttŠý„·,à=íoŸ7U*Q‚+Üã¤æô›úȦŸ”ÿûŠW¼â-oyËÆÆÆ¿øÅh%¿‰ÀO ^¨“�¨+îÿ“Âç±°=}ƒÀYCÓ…55\1 `€—(^Ö&ë. KöãzºØ“eó%›&w£ˆ(ÓS•0“¯³‹OÌ<@ÐÔÐÇ(=prô &Ò“¶s[Ûˆ¿q!cå`ÜÌ ®õÜsÏA%(›3ôl<«lÅj¥• ±véyDLÅp“17ú¨Ü}àW¾ò•÷Þ{oüÊèØƒ&{#¹ )ƒ;FÕ }Ñ€u Áž±4Hº÷¤ ž…M)éì>é‰w܌¸ádIìRÏyTÞÆB[á|'÷¤ò+,p·ÖÝSiy¢ü #N& Â›Ç 6K¦Ï(`½%¢©Ñ‰Uíáä5®ÉA¹M\Ã4Q¸×ë=øàƒwîÜ0R$ÛÑdXì–€î÷ûÄLœá¨|EJ[”fuÁrNrÃó÷»†æ=ˆ°S!Y„~Rœ´¬Xa¬Œ½ÃÃ/í O³±8Ý…/N¶ŠˆÔ °vü½Ž‰Ò¢pŸ€LŸY0ö­gz=¯Sœ8°Ó¾á¼£Àü¥�2i2qV[PNü¢KO[µHm^»v-‚íëëëYîÙ¢ÔŽÙ0±¹Ìß,Lwæ/X¾Åàx“äIêK¢¸õ"¹x‹TBÕãxe÷r¾{Þ“¼žîBQ%ºf2EPÔ|!Z¾Î”HšDØ<RÎpÍý Ÿøo,ºÊß”/$8 ‹b,é<gÖÆÆ†«@’nž ¥q [¼X‘í¨³FkíöíÛÿøÇwvvLÕ…âH+Ž»°ÍnRl=Э"^i¦¥ Ðàf.æ…“I5™ ôÌdÊ›ñH Ød„Óó4v[HPqÎã…àgk†THf`£g¾_;êêÄ´&„œcû¡‹`GO/rä™Íbˆ&C!üÁfš`|#^ŸÖÿ'B˜ÉÆLTÎôIÜT4�—·XV¡™åà¾sçÎÓO?½ººÚï÷WVVh¤w»Ý3gÎt:íímôÐ\d°9!aÛÄ•œ+Sy h±Œþä¬{?=ÍãÞU;ê[EûÄ[:%å£%§8æ,q Ö7]4x€Ôs3Ä�rOݳTò¦¨NöxYÁ*‰[xŒ¨¢\ÜLs‘UMuRVÜ<®„þ‡ßZÁ£\ÐÃu |zõêUŸÂŒp¶£¾d)s¡Š…Óï~²ÑÂ!›ñ»dj»å&o‚èY¸œrIaê JHdÙ§ü9wiŒˆ¦“Þ¬°7íŸÆ×9Þû’  ²ãþ1§DÄŸxþÖœö´uyqÉwK€à$ä4Ø5AœI…ò¦™9ð�oZebØ¥Þ-'b‰¢§[”!†iÛÄÜhe ƒ¦½‹-Œâ¦žß8Ý&”9:΃>øÊW¾òÙgŸ½yó&˜5ѱ5‡:SWfD(š.\a D©9Xsú€ÎÛéÒ|eNcž9. ²s²»Õσmµ §‹ª%GÃêÙ8³H)è3´n|±u)ÂtŒOæšiÂô5Q!Ï͆FÖÿ.Ë)‡¯¡Ý< 2ÆfY*e§ *d¯Û6Ñ€0fÄ;B/ *Ñ€~y,µôV-óQ.Ì—á– í=»9ÀMpÓ«Ô ÇuÔÖv”8.è-lƒ¨L^e3PS[¡íaÜ@Ç”P13–À¿$ØhÚE‡û$äs•“hÁ&É¢)jópò�kôa‘à.V}¥^Ɉ†‡ÞMX 7_@m¯`Pà¬Bô(Á묋ãžJöÏööv’&P…ápxçÎLH0M9³ø 8Lâ"xj‚Cñ'|Ú÷ÚU |éÔ% BMÄ*ðSƒòuÑEÅÄŠ&ñù —nÈ©iÇrÜŠH‹ ²I«-wǧі0fTå¶¹YmôÉ}Î0Ìjs ØëÄÙÄe/]ºw®Å=fÓ[p–kC¶R#ž7ÉŠ§ ®Zm“ðàšÌ Àг\&³ñâ.ÞkMVžŽ:M( h;*ïd“Ñë„;¹”{ägÉ?Üñ ÕÖ0©A…“^Î1ÇÔ·œ¤»Ú�Àu+ÒÒ€³´RÚ­o–‘KVžOíÒ �ˆHˆâŽÜ…›Ðf|dxZ  X¡Á]ÆVWW×××Ë06é6'¦{éÞ<e:Ç)6¤uÝ,M¡ã®~Ó¼§#Ÿ#Ù‰»Å[ž#̬_Ž-ãQL€’­Ã^CxÍZ¥BÎS:¬á”M�׬H8©;‹nÊËRË¡id‰.Z›2Lã1‚¡òºÙÕ¿i¿—òqLs%¼¡ŒUÚ-�Þf±à³gj¾ÈšdÑ•üÏÃCE ÓŠi Z>tÝ mÕ ç¨¹94п1-–΀£ ð€GÐ<:f¥56`¾§k¹x¿ú“sl?„¤®'_`=a:` ZRT8¯N…’äfFd î–ç\©G¾Œ L¿±x¿»8 ¸¶îNÎ/L|Ûš VؽöÀ&6Ín·A96’õ%M\vN]š=Øåf³€=«hÍPn''DgŽx¦”¨S)ò‹ú\ð¥rU0²HÆsF0v“MnR¯ËJƒé‰LéÍ|²×ë±T8¬]‰–Ž`·ÛpB‹ÉcÔa® ùÌ 0bî¹çž½½½F8ÑÒÿ æ ´å]؂ŵI˜ÇÊô¥ÍÇxàþ?ºr>º˜proÞræˆÊàBBQbc@šØR˜ln¯b°½Å“4Vuc¥xæµfŠ“„Oqòj‚勳>H1–djxqq‘¨òv2—süíÊà5ìë̓_Ðäã ²Â^ë÷û€$`>å¡ñXk–ÕOê—õäN2´h0nËÛ!Šm ;&˺ƒj: ´iË:qaî“{¼Ù]wè­\�WK‰Àß'çõŒúââ¢åLŒïå]ä xJ‰ƒù’Â]ÞÝÝí÷û —I*‰ÈS6YÏ?‘ÕšnÚ»^dz”ð¸ÌŠòlíâSʲ¼_;D0¥ÁµÁhGï‹D›Ô?MWmmm2õ‡‡‚Ϭ1xd§&á×R`•œ=q…eŸz¢Iêɸ uvŸ²ȳ3EŒP=kn›¯- Ù̹£Á[ßfáPä¨Ëq3{IuΆB!‰f’ãÓ>‡¹Nê/-�C×a�z¦±0Øg°åtÒË9~lÍbûvÉ%©`Ÿ #kn¤ jãàPh¬üÊš�±±:d_ñÐð ÎÅaCÊ‘\½=`¸EFÑ„fdļX/wc2`”¾q’M€ˆ<CªF ¯"m‡×Üê^ö¼j±ä½MƒæH5­ˆ'IYÆîÅ;goo"Yz<̨҂rbLJBÍž‡ûç—îQ0èÅ9^-}f†7j{¤ÛVÐq¥Ød:çBÙIm¹ )k+‘ó |zxkDAëZñ¡VÐòáüõHŠÇZ •ÑlcK¹ƒß‚RÙ”öÌ6,Z‚ÌM/jG­Q]ˆð”¬Â^ÄŸü’KÔ šüh "&¶•™Y‹Ža"å$Ø�¦1•Æ hù&¯°ä­iGˆœ©`ÃÜk(˜8ÇGŽHÄTò]Ðjó{½Þ]wÝpÁ*<(Ž’2”žp˜Õ¤ih÷‡OSwŠ-C‹Ý¬³¯WfÈÔ™f·)=‘]†&å›ì¥ØµÙV€*Á’ÔŽ`bQšAÍ…AQ*Wî+*µ¸¸xæÌ™0…¬[Õä ÉsŒó”'ïÿ,?Óœ"ÇÇšbJ·Ïh‡^ŠQXÐ^òœ¬ùÊȱ™BQîiR¯ |$˶7ÙR™Ï-kÖ'p“W#Ø9¾Ã-±„gN$oíܹs>ø`´`“CR…–Éß8ñJ b.Ë,_äv&CüG…Lâ7µÁ¸rhô&#¸®µÎKÞ¬¹µ i/}à$ä|—ÆczÓR8æ–*‹çÿ‰Iùåð÷ÑêÈŸ³R³¬9¼Ì”ƒjÓ†­Ûí>ôÐCïyÏ{^óš×p¸çìpÁ =ŒÔøÀÊÆÈ{•©4¯¬õ½½=ê³Ò§e¼ÚX›ÈåŠ žç%) -éÑ&Ή\0¼¯âÜ“ƒõìÙ³½^/Ï“MŽn©ÛÝùê\øF·Û]XXX^^f«LÞ%«Å„´µvúôéGyäÔ©Sœ5ÀP™|¤õmço÷xyâƒ3b¼ËPÝ'@‚÷Ò„·ÄKþÆÖ´ #¹1/§X®^KLãµGª¥"ò퀮n´ôûýÅÅEDn åÍòy’äïùƼ\†=,Ì[3VL©:;;ûØc½õ­oÍ%`È3!öã�Â.óǶ£~tT™ÅÐC¾¦ët:÷ÜsϹsçÌn`yàPÅæuµÍß;%¥ØµÎ4ùE°Õ¯Ù°vñ8ÖŽ?ê�Ô˜ÑÈ2uØ>CÖ<ošˆÎ1¿^²Eè�.8<lAû1)ÕéÓ§cbñâÅ›7o‚s=.#'*ò> =·lW]𴿨˜@\Z >‰Ò©¦^äa‚Wø?4÷˜QUëÏ“w§rzà†ÃáóÏ?Ï`J`·»ÍUó¬{þ× iн̛€ö–k[]]ÝØØ KaU³ç  8c{HÌg€³z ¾%áߤ´²ƒ5¡‚aIÈ)Æ”0+2åÚ òlC­´¥†2"ÑR€Yv ee†ªnÎBX�ù'VÒsk¤�ÎÔsùågžyæâÅ‹«««¨ÀNvåa±NÓj| aܵÙü¾K·Ëõõu;¬;au ?=Áãñ#7üÊè^>3ìƒÁ``llÃúIÈ9æ7ç)z<8ÉKm’À‚f¥,:Ô¿ÅÍÌG ½Mª«¦Bþ7ÜèG}t8>óÌ3W®\Éxˆ^&îFXjɬ01©77W )¶8v´£Ò2¦*xÖ:[ÚÝí¨ô$^×Fi¦;ºäûùÀÑhtùòe'éùŠCýD±fff&ÅD›¨îSß Fjb«ke7ä’}çöñ“:$rø4Ìí—ZO¶z 8îú¹¶(óíî®[óÑÕg“h˜Á–œžYB6ewaZ\ÀAê2‡?ÍBæ—w^�ÂÞÅT³hY$f$Æø}±­VVV¼m‰.Mî!…¸o*‡aÁ£¬¢[š©&¿F6íÔ‹PW†ÚQå7ƒÃnÅL‹þB“9VÑ¢¶èçIÈ9fî�)¡½/]çše`ÅFþIa|še›¼,ùr_’&¢—8'Ù(cðׯ_4÷ìŽa4"eñ•)Ysñ“Ÿ†˜8C§a¢tÑ©ÆÈC9=¡“’!ºémêZ—ïæ ‘e µ ´É“ÑÓ‹<PÞ´z±u´Ìk�”cžSP”èeUKÛq0÷<á lHÝÚþ —øí,,,lnnZ¯oZ)ÀC]¾/ …X˜åV¤¶W¥^P2ðdgÞ8Xë»tŽEþ+㊆•<3ÏÙò˜kGÞˆ‰3'uJÇÂîî®›mŽ(ႊf°‹´€ µ4çHÙF¶¡V–A§8¾$6ŸÀ¾hB·¢‰|Bòñur޹—ÞÅtÅ5{ÛjŒ„öªgË!+— l½�VøžÝ–À7®]»"çòÂTà,Ù[¬ž;Íq°pN;ªFñföT  &ZZßu %uAˆ4Ö…±ÖÒPi+|½ìcä^]À7¿âœ'韵‰ o¹MôÙ0ãbÙ ‘RÑRÎYêXlÓ¸¼Q‹vƒ „œåäÏ †Ì]Â@B5×Cq"oY6÷«AƒIƒŒ²fyPS:awêm lÚÝ‚º˜c0–©OÓL kx&ŒëÏâÉô4j,6Jgƒpõ|¸õÐx¾aRg:¢“x‰=µf"¸[/gÎÓ‹pÒAÿØ’D>‡±b——‰œcT»9 9Í­B“,§±Ãk<v´0¡¶iäÓDa4¹óÁyÄ ‹V£3ël¹´ˆ8¾ ö‡ïz¶¢õž­¶KÙNéS4Û=…j‘üœ5ý~0lnnæú;-n¾AòN.ÏÌÇÂÂBà)·y,PæòË(63š«æÔ!l½ãN’gˉ§) /Ö=u-Ùcí.nЬo!µ{B0‡ÒŠÒŽ‚±Í€±¬OhaB7 Íãôˈ+ 5Ù�V›,Î’‰'fØ ô¨üË”zIéàqØÒ;WÈ{7ÿÅÜBsL 3˜Bfýw¿ ^™kî<‰½ƒô"3.í¨ jòt=Eã<U F4Y€Û£ØÙ9'n²„àRMAb‚ûļà{¢‹cå%}°V€|\2±Ÿ?‡ 0 l™ /³p+Ë<·'ÆÙÀ%Wмùx›2³™››—÷Ñ6= nª Dµb1I€dš0löi~.Y¥Ä× ƒð`lxzΘåÔЃ)®*MÎFœwvUð¥ñC. rÂeT³˜wyf“ bNœî·¡äÏ]°±óñ|(µN¡8¦bFàIâýœS>†Ð-57’[°¦"ÆàˆY¼}½èUÔ­ùæ5‰ê`“y. ±“Þ>ßÅ]óü‡=ìU�1WHü o‡Uí‚EW¿Ö&miWüf¦ Iª„°BÊñ´}zœáØ2öueýo¼9 9­àKÆI}6yÜÝôV'ó(\Žx02&£CÔõs¥ìà‹>(¾jÞc€{)nÌa¥2`*›zŽX(ù2 yJ‘µ«Ê0dvvvÊà¤E=]Ø Î|É œó||NqègÆ“I“]þú˜tJÌ>Ÿ®D­×”¹í ›$Ñx³ÔÄ>d9)lçå@UÈøMãa8�±DÉQ|qÍ6ÎI ËëË#òIDÍZÊ/þo‚J-iPƒ°„ˆ"ö2ÙWÒÁ$ó!x6©Q7Ø&€Š #Ÿ  l4¨óD>`p; [è̇i5®^^^^ n*N¬®mH“Ó`“A �maaáÌ™3»»»›››þ#í æXº < 9Çùãýf9,—PË&äŽgÃuæÓ€\Á% “O¶ÿ¦i¥F1¤Fᇭ5¸¥E€†&ËÛiM­|fŒÜï¾ûî{ï½w8^¹r%§ƒÛTì´aB—STÜAŸ "¡b‰0;ˆG”¸N@Îa ë”H–�b´q󲘖À y#“vÔ†áúÌŠŠÓ(Y™Ìó¡8pƒ¿$:úüJµ‘dßã2.£s0eé"YëÆ‰ûÖ/pYx.¾{”hªwšÈõRÃe¾G¦d�òagäRÑËqÝ@oŸ‹ñïdÙÐØCÓÌ g<ÅŠ‰,ìm眓XfküOXy#ø=z´™ƒÅÏ“££×ë…aœ°MÉ/åÃ=ÅáYÀ“s<UŽówÓU™ªË £¹ÍX£±L­cÏN‡7ù£h¦©õ"=|ájzé˜Æáâßâ¾X¬Ó`°ë '>ây™ë~â‰'nß¾}ãÆ¬û¢UòwhlÞÐL­1 –3ÃL¶�79‡,!©œÍ³¹A2VÎnÄf8J _Àa ÃYˆ[qƹIýwº¤+°îdÔCÄd!ùÞ$ûÁÉfHJrƒ`¶ $‰¶¤™ f!SL4ihÌÓÍZŠE4½ù̈0RÃ’¶Öj®Š·“këõzËËË;;;ˆ ä/Mœñ¨œHÛDÆü<ùyd45WeŽ ò�Ź)«Bðœ-*ã �]±„´Bm„î»ûg@ ë8Ϋ̾ôÒK¶i0¼4Ú&SºéïbþtRå?ƒÀj(¤KÍc&Çd›q\‚‡˜+é\Ïóðn"ÃiEØQˆ"P“^'ê)X)gÛÛ3£AóÚ”¸=MéBît:«««.\À ;ñçP÷Nဠq4“ ƒ-4bè¿pK ̫̞>}:Ú¬ˆXm¢ýnë£bºSt¯_v>çwaK!'Î&ȱØ¥9ð4ó«)\ÊRûº+NŽ’a—À­ø?10ëy÷·=°ªK…ÝŽŠìáQXäÌüÛ°šI›ÞÌÏÏŸ?þïxǵk×þüÏÿ|}}Uݤ)î†Y¡ƒOkêÀÝoGeª­zçl�*své%f@Ï™†ã¸}·ÖÂI!Ù2gµ8º‚‰‘•&LäŠÀ¶—Gì²ì¡†’ — ì$ägÈiÒnb9BåŒ2‡åxݰÍvb)8@£°¿Üâæ.=dË¡çT²Ž/ó=m2ìmÙ—ŸÁã(ô‹É¦M/,,¬¯¯ooo{õ{T"ÿ¼´ä`J2ªÖއðHñ2šn÷— þÀqf²5ÉÁÜ5DŽ�„ A.Ûï‘n¿§”J™Â8:‡Qšj„gÂdšÉßÝÉ£í GeiÚXãCŸ…ãç„Éã)VE#èRý`‰í¥Â¸"RFpÌD·Æ’M%LÍ·= ûÛùIV”§Ñï÷ßüæ7¿ï}ï{öÙgÿê¯þjgg{=kv€÷Ú—í鄯¼A@-WcY¨´»ò7síbÙõ’¯´‰>“±âDSŠŒ°Ø‹;Õsa÷xy”;ZÀtǽÐtóúØNªœcÖ¼‘lÕ—·˜ãÃýàfòÆ×6få¹ú¶+I“’9ÔéÓ§xàÍÍÍ[·nQÜ0¯à‹Œ³‚˜™‡Å€k‰mÀqˇ„”•CÁgæ2$w><<Œ? r¬�•(_¤ä‚i¶{oPX0èj_à&Sgº#ܾŧ·¶¶8g‰.M®Þ ¹ P{§Øw«×ëåßú‘e38’«"[‚ÇW›lЈîdô´l˜¶¼¼üÊW¾òÛßþvÞmdbF¡˜Ãl¤ÈE‚ªÚ”>^�MøGÂÞÌ»»»é®%K�ÅŠ^upÊâ„¢4Æè©<ùä“ûûûW®\YYYa±›"ãM/„!$ÔCŠ*­,?óóóÙ­0×­šœHO…• …ªŽIÕè/ÝUX쌅’Ó 9Á^“ÝC¾@áµ›Uo¹úGt1¹cìI8»Nz9Çù| ÃM2Dr+ösiÓ!ÌEñ tf•6;¢ÓqõˆO·Û}â‰'~ê§~êÒ¥KôGtçΨl3E^±Û¨m'Ÿh¬~UYhäæ¾ùÓEwÝòhà9IW)‘�æªrºÕQš¨68!ƒ†#`4ÆÀì8^"ƒ Ô95R Ï=‚Šõè<{D–àÆ~*#ì0Gìqb3éò¸š¤6 rþ·–¨³5¶¤ׯ_O3;;Ûï÷[kâKMÒ%eÏëür’‰°$hKP†lX½N¨=ã¡1ð�ú£*²Á/¼ðÂK/½´½½m"[†¨i Ú›ˆZăHɹ÷ŽrR“X™u�3lPnì4mì Ér9oŠØf ›ýâäø®³V)-œd6}°¬"â÷V!:žüþ$Þ‚0ç’¿a}°¸L±˜`Æ‘adÌ¥®UÐ v'û[[[‹‘d­ì|”íVBŸ? : ‰HGVþ¡-ÈŠn)ó.†›Áô €ÞŽêJ™:ìFh®Š‰Û>úÿùzÛ·X÷pÚºŠf/»=’SHõÓÅáípz–™_K<”;xG>жl„4‡ž°K«Üã`0@4Ï>•î¨ç‹o¦>~ç;ßù?ðóóó3‚ædpÕ¶4„?@Pe7ö§)ÂMjǬó|ûþþ~HÃf”ЛîXð‡áp¸µµÅ° …]qm 6x"Ê=Nkñv\L€[”©'÷Ò&º2ÓJšLìyîrº×â>u*J,'+5x>‰Û4¹.É%3RN@Áâ ¤‚3¡Ø“*çxBšf¦Z•„½U €¤dôßÉ } 8Íxý²D²â/^¼xåÊ•Œñ;‰vº×ü0ßg¾Ð QI˜¨êÍɽ#gJ[—ÍOÚ¸£43Ù–öº6ŸÇn+&+jÇ ûŠš\ aåc«bbm““¯Î,e{ ã¨tª@˜vb¨ ”Ÿ7å@×af啱ž¢žI±±±±¶¶†™­o r›‰Nßüx_a“¿$V“"2©½Cëÿ»uÄoB§F¦›�� �IDAT÷ÌÈU›HõP¸ä3MÆa°´8½Z-˜ôz+3qÉ<æææ ,ÄT³õ`ܘ6‚î_:R@ çççÃXÉÑA±hûì#ât~0Õ¶^'?€žMzèà&µ‡l°´ÕI/ç{"ðª2+±LáàrŸ]‘ ¢HuÁ/�Óðˆ>°› wàWVVšdÄŒM·)§€vTœŸÅ”9#9¹/$ÑØ0“©AÑÜ·Ë@i]’,'vºGUd}]œ ƒñ—iêOÕŠp¦²á݇·ë �½G‰…à?ø{æ‹xȇAÒÐ?Í@%7ž [\\´¯3çšDÏg�¯­rÀC„'°¥Á[zssó/ÿò/ÓÔ¡š<²Û%௳ ¹Ÿ­>Òs«Õ™‘_Ä{@›‰Ueš˜Ë&/ÁÏÆSpÀbwxÖ2EE·`¸‡à?Û‚ K-›~êÔ©ÙÙÙ«W¯‡@æ +Á• pV~-i(¡—çÆd$³iG…Ò %±ØH+©YBeq/¦à"‚µ³³3­±trއA@2Å®nG•*8RIëÊ,g“Ë,ÛͽdOù³ç¨¹ C·Îp=‹‰Ž(ý'h î„ÛJÄv+ô® †NEb?„È<7 ¦Gnæ+x=2* êÆ"ܸ6%Ý`ê>ßE¡ Ôr/0-L’wAšÉÙQ† Mf4˜-aaÇçô¼Mæˆ-¹JïÈŽÎP!(‚ieS‰¢`ßwÿƒ~5ä »zŽÕS;žê0Ÿ˜ A}‡¤V|`–þu\¹%h°ƒ5ߥëT»LЦVÍÅçÃ"’Ö„gœ 6ýĦ´y ëëëÅîÈ .ÀļiÏ: ;ÙÓº@&v‡By“gž§J™Èœ}¦D;2¤ÅÅÅëУ¶ÛÂI•sü iØ&&Ú“›'1aðf­u3­Í…°4›DÈÎ3¤ÀÙ-?®§3g«;á‚PÒÏ……´.�”ó“€AŽé12Ó¤@ãaìBðwÂÀ¦¶›4@dî¬ÿ % ç,Å _ça“Ë­/iF}FŽx±ž¬*ý|'òM oÌOXv“qÔ—µµçšË+£–%N-ä¡ylÞ]4_¸Ù6ý ~t¥ÁãÌÝš¡ RîN›6Miž8ç]F½oÐLzÊ ‰W¾ÑE)—J ×ù‹0¤ÈK¼,¸CµQÁiÕ×vt”¸Éɬ"c†0z¬Hd—H.& øÐhRÕ2œËî ´pH•òxç­}wr޹—ƒä‡£Þºí™ `=-Ž'8±©PôCvwwõwðufp’ésÊÙ7|aããcÖ¶ ¦½Oå#Erf … ëyI·Iƒ»O;…”¡Wƒrœe°Ï]G2—SÌì«"K«ÇúÖ öìˆ÷¶µòyV©“ò¦çû<ÖÃ/È r¤´á;b…¥ÇÝ�TäT >¬³vÔÃÝ5Oþ¶‰“›¨e=ÄÊ‚Ì#ZXX@¾Þ¯ŒPêÕ½*Ç}:eÊ’Ö—Å<ãH_RuçÍ«‰GË,Aýe¥¤ìÊÀP;:£]@Ë2*ë,ÄöÞå<=–5 †FVQ¼ã\á±­,Ï ’@{ä¹ëèIÈiÓ€U™³«/•æ9”€þ—á’,:„´mãƒ8?57QN¨Ÿ–NÍ úf·H{Ã�;ä=¶íè,†Ö:(ìØB]+ ƒtªÍ+Ä k[Ž3ctШ�˜°¡Õ‹+•àf½^/l@ÎkJ ‚è<iiÑlÎx  ¦Ã¡íª]ð§y¶dÁn2ƒI2Á`¦Ï5ÚòƯà8c©é”¬KpQ§á|2u<òEV^0–[¤_ƒA^+C‘¯4DMB#ÞçÀÅÅE°Ü2Ï�õ+ÔZ8.ÐL1!BrAN%¹üBàwÒº¡R’ÏûbÇ™P7Mhç(Z–7A—íjŒ –˜ýâ&è1¶'!çHîô,Òóá¤êÁ¬]ÖÀej“Ùf¢œýM[ðxœ7q(gg¢Hh~­gW™]/ìL_¿«VpA´­•¹ `Úzœ_ÞÕÓŠeNÂãÅ8ا†"£ SÙR%À›ùË¥¥%”ê­ÆÌåN;Mô2—ýM4cÚD˜¤ˆ>ºOðvÔj!—dqhšó~Aæ[zÕoÊ#S ²€Û¸é ˜‰Š%éK“Sã 9ªôêéKQEá&M+åÑâââÙ³gggg···ÍU3·­MFªÝ›$ëOþ„¼½ë˜Ùåy¾¨èP¸ž6&Ì7º²ËHkJļW^%™™û=¬@Bñü.Þí¨+g‰+|Îh4 {ðÍÚ€ÓÒº's9ÇÙÎ1+—• Šm5L†(³ú‹¼¦{ÅþçÉ’ê÷û ßÑØ„€K`¸Ä=!¯BËÓê¿eþƒÈ—Ù#õ6J0Ín,Ý—\’o“e”ŸÃ”™ö 春ÃÔŽºX2Á`Lƾpgffî½÷ÞsçΙ°Ë<Jvãîî.@h‚½­ <`”þ¼±k/rÙÄZŠx¶™àâ‘ ÛÍV+ …äO:õêW¿zii ÿo_tG#WçAÏPÓ¡gc¯?p²"K³Ðòè øÜ¹sKKKæ—§YHA@2îv½çùQÚä  sI†³<P %/¿kØØøAØ„ÍÀ,O®„õâØht+ûw3ÌNµŽéÖø(€°îYE‘ÂÆt³Ó¼V°ŠâÍQëŒ Iý$äsÈÁ~ŠE4ÊÆ3x„äçççï½÷Þ‡~xyy”¬­ü»ç“Ñ <}ú4¢ÜÑiGg'›<r¢¥ñcÐ{{ÚÝ6k7K“«%?eùÂ~6rÅÎwW†³˜aòi§^Ô$‹‰™ÃUnÖN£îåð½çž{Μ9“6)' D¶ÖîîîÖÖÍ'bÀÂÂÂüü<bk@ŽÎ$Ln2X$yö–ÃÚ“¤9Î0ÕÎO™^,¬â½½½œYÖöf£‡zè=ïyϽ÷Þ›[[ZZ:{ö,*×d9ž?=ã|G—›« „ ŸÚ6‹Ë¾éMoúÙŸýÙ7¼á ¹–ãóTWWWwvv ÝÎS b½ THˆŠÍôEâMÑTå­åz²ƒOØfÞMu.;[Ø}5ƒÒ¹ÔÅÅÅT¦cð"ØGÆ™•Q8%CæÎÕšvQÁ�‰Õâ>–u‡ù($JËìà °vüUNº?0Ò"ÐÿÅÅÅ·½ímKKKögû9ª$nÚÑò·nÝ*#2áÄ Ì!zp·(L¼¶¼ ½‡0©²4ƒD[®ß9,ÚDoÍÙÉšMˆÝÞ,S/fx-B¨Y(¢N¿ ï|"wrµ°®G£ÑÍ›7ó”øÊ»H}æžI>ÔOŒ/u™îmäQJ§ïÎÔ8X‹YtÝÛÑ9Y©<^ë\¹ressóöíÛm"Å)—g=.þ|Ï:.\|'ºSdmâÚçi0nÁ¡7G[à2ëÎå!¤+F0àô'ÇÊót.‚ŠkÚ“á[)* ½^“×5®<g}`=¢E’X¨‰F…žÀ Žéa¨Ä–PT¨ƒ±GŠr'DÖ@aT*´²êÌÏ¥L‡a“‚lR¶³™xMyþá$ä¼)lvêÍÑCÇ:ÛÚÚúÜç>×ëõ@ó- í ';‘Ì@çPkÒ¸ë iÉ�V§]�¨¾MÐJÊã!yN:ÎëÈ•Áx½Z­e9Ø©Ø,­m6mñ0�˜¯Àædfffkk+eŠyƒÌܱµ¤X hvvvmm¢ÄøÉ´®„©€8mGÌêv~\ ê(‡šEÁaŠè_²o€D(ÙØØHo#4 ÞÝo M7xªð-Á“ZA»(–-ø2´H§ºÕ’FO>ùä… ¶··ÃÌtã3·?ð÷àØöfu'Ï­M“èØ;ˆÜäcÍ áá AÃÆ}2ÓE±"ÏOc˜~2× �Ëæ‹B±n.Y AœrÐaSl,gÒ¢ ÕN\A¿GHÒt¿=Ò&Í.ðqvÔÚÚÊ4íåFôÛQeLo‚§p÷pV]>‹H4j A©nr”µÄñÁÁê'ù¼ =´`Z;ª¨ßäën1»‰ üìö²ÿM3ÛÄo®Ó‰‚I´D4ÜuwàäC<teßxL¦V ÎåáÉñIm=G¶wȯ.3rÅym)Ø"IbK e0}q)>uê ²–äÈ`ª!¿xªÉþÙÌYëžþ¼Ií<«¸f¸9WÓÎß�zE}ƒÿ û�&"lOï,ëªq ràm2W½¾Iì*ë9u°ñØ/Ù¤ä…åÊ»+†°åNÍÄñ£v©”Û!¿)3�ðWÙ\>Ê ‡3È“QÐï ÆZázܬÓéÜu×]³³³·nÝ*S#¥yK€`}W;4M›2 G‘ÄÔ‹ó/@Æ@Wpq#„Øã‰ûü–=.Hàô¿wòQÎ/ ¢Ž¥+æÛx¦(ñàáãª`Ö\Ó„#5œMòÒ)c@ÑAà]s…Ð[_›„Fxe9‚­œèÉ�Sç±0üÄœÂs Zö¸ü>ç-" =´£Ö³³³=ôP¯×{î¹çÞ9%CT1’¨Ì“aú¦:''‰!6”É*Üf‘R6¹Ñä«•—Eh2Žg†¼„²�ùiƒRXd/íõzKKKñ¶°’"MZˆ084ðÙä�b™«4/Q'U¼zϘ·‰4»Ï–…jëðfmºB8:¼ùžøòG²ÍÍÍìöÁ`d?)9ykŒr -U³¦kŽ'»g‚¼Qu•µ‚*bПYXÈašÖ¥Í›ÍÀ!‚ÃÉ·‡1£ÌÄÀÛ¶(I…K‰»¹æøSÓp!üE³¤4–Mu ©†Nr’ºÅ‚¼7$ûž¥ðÔd(O&} JF+›’Ît瘩Ȧ<tá|#ã56¯£Ž„ï˸LÅk×®e%3Ù“²,}‚²–�â,…ªFá›o_\\Ì|»‡‚ –é°æs{’çÃ2ƒa‡éäøŒ5yÒmG-ýzu)p K¿÷èõõu!7ÂýbB\áÖ�̱ú¶yÝt KB`Û*Ïù:+Êý&T[ú†N2sæ«üì¯H¦kîâ´ëëIÈ9ž*F (ùÖXœ=wîÜã?¾³³óo| ¾³gϬ¬¬¸¿âŠ´Ñz6eVŸ¬Ðú‰ Ï#oN†ÞëõÒ]ÏõÃaRxf„ÚØ`¾Î™ÊY²éÑ5åh6_–ùÄ6™Ó.ž†éáommíìì ¥NüÈîE†‡±;ÎM$j(­r„“(q R.ïÎëîõz¶}£ž0Òx þ˜¹ÅÆëY60ˆÌ"3yû¼ÅrµNç);h{@{ãp¤S++'HìÎΧ¶­šý–=óï›âAãͲ%^‚óXpaqå(sZÊö4›mÇØÎ$lôž'™Ýç2·UäËì»Ïê¨m"Yí‘L€nóbæ+¨5@¨–/òn�btÓ^À®žÁØÝÑIÁd !rÜ&“:ÊqÒÊÒL-­¦“s<½Ì+É0C‘ /ê×¾öµïÿûoÞ¼yñâŰì‹*Œ_6‹¦QL’1A�„Šxñô–ÝMì¹àÓÓzÕeÌ“8G‘n RlÎD¸Ñf°É=Á5øXÉçoll˜ƒÇ°‘ÅqÁ l¡¤opùœ'étæ}¤æÃÃyK„+ª-9hØç,//‡Ã“Ó0åã­Ÿ…<¬"Û—É\‹vÃ't¶n}·ÖÃiöÔ”áÞ)KÑ©Y‘ÓWÞ¬“&73ûÛ[Ý®t„®µÖ3ÜǺ…ÊÅ‘êI#˜™±å¸|ŠA¢dá› $dëU²@¿^t;êùÝ&ª?àºlFAÛQ7a"\aydG˜ñaEm‹•½f.H+f˜‘qŒQç$ä|7ç "l`”åE™ÖºÝî7>ùÉOšoÖ&VŒÅÁ‰e›Þ6´MºÔ¬ FXHçÑØp"ìÁ©CšžJ0)ŠŠ˜,P£óóªÈt:íímÃP6F´€ÓRÊ>Ùˆ"%I7˜Æ $ :OœïxoÊCF½ç<Sbì΃í¨•H~3— sýᇾuëÖ•+W|ô;ôºÍÆ@_Q^±x% \UÒ"*Ÿ|m"±Â£ã·s[²†dÁ{‡((ë“WyŠ…#Õüb0„]R·”ÙAèželž%„j_0À………àK¡#–Sø>4B(€mÍÞtÉëƒÞ}J—§ž"°6šU”ìÿ”ǵ¿¿{&UÁ¢ÐÙ­À,{ÒÖdYE?—}îêæaÛi¹kBþIÈ9þ:(EgÐéLjðXÿÞºu Ç=¶\½MZœE|¬œh¢°n|‚—¢„S²ßï»ÃÙŽêôŲ™g2œÎ¿lèåßrÌ…|üú׿þþûïÿÒ—¾´²²Ây @þ΄|鬇:(Mæ7ÓòÃÓvs&º]œ”'©&Üém“Šv*`QÎý~¿¿»»‹†<é°ÿ0 ž~úi:À¼J÷¨ÌL³B—Ä$h¿qîia˜~êv˺öu¤ÐfK´ö“)"í±¸Ë4ib"RÉ\‹ø©žéë¢Â¦‹Èf¸,€½½½°È|¼ÂXa°—­‘÷ˆ:'­#ƒ]Žˆ¬œ<“tm‰î…Yæ‘Yê¥Dp¨kiLÁ¡öÀ5ü™×”‚ÛºÝ<X@N4~ÐIò+—Õs‚$RÒ—“s<…ïÆ¼C’5 jȲ¯�¬&P™‚ìICê>ú¡‘R5‰¿‘o‚§¹|F~Ê\7ošl]²¸Ñ¯5xe±zÚþ ‹{{{wîÜ988Àù˜Ù‚iñ`5Ì.ÐÄ*1öcµV‡Ûž´pü¦¼¤¤c´åàà`}}¶sZ2VHähãÀz衇ÞúÖ·ÞºuëË_þò;w<6H3�a!†'ҳ͓§çÄ,d´,-ÕU0NKä®óäƒ •¢ýf( Ù·Fa‡«ŠçZšfZÍö¦<e.'9DV ð�¯sÎbø5ÄÈÄÐ(õ ™4ÍÞ“ÿÂb/�R5yXd6îÊî +*à ^¦rð¥ð‚›Q¯ðô@§=*À·yüí¨]=_ÍaR,«-Kˆ±EÁ-]'yžÉï=ƒñI•sœ?ñÄ+ÐP¸ÌÚ” ‰ÛžŒÚÑðät𸥠Zfý³CŒé[ÍÞ]´¯‹¶?QÇI™ÛìÀë%'‚Pë8‡ïp8¼råÊÕ«W³»ØíNoͦejÚ¬2ëLŠä»ü<gŠ�.̈§Xräq3¦("Û*³“»ý~ÿ'ò'ßûÞ÷>ÿüó7n܈IóeÄrv¼ëâÐj!ÓŽµòxKÙ“FÀrqèÒ­Å`’½ËG¢òéÓ§¢|አÒ].,·é¡JvyaÑXÛ/¢=ƒèƒåÃKÝàÙ~ë½ú÷9ÊzˆŠ‚ Yâ%|°ìtÁý$ [n#o¤n ƒ;ÉsïÍîéIûˆŽœàc bCtg0À°Î\ù�œ�kß?çÎ{ðÁ¿õ­o1_ª1 §RÚ4­ÉH±ú$F³¦äçcͽ±OÁwj‹Ng¶µqk3“ÕÖ™i9PÆãC9={‚Úž=îm8…,éëÛæléZxŽ5àak-ê&©Ìš5c;ù é Ýn7œ1ûAð<‡ˆvKü. ¹…îôÖåédàuŸfXÍÌÌlll¬®®¾ôÒKîñ�×§ ƒ®5$©‡Õ1ÖL;yGSä-äEñÔ¦¬á€(Æòú0›ŸŸ¸q0ë¸x¼ŒŽ£Cù ]+Î>‡òk3?_ON£ÕÞ#wdÍ͜ȃÁÀn¶Y'd–G›æÓc—à‚ Ä•åáè[ªaZedB®Â™×aJ4í/¿B‰´ :ÃaNjó9Ó\>b«®¸®8 )Ü< ‰ž¤ùg}}ýÚµk晀‡°cÏŸ?ßëõžyæ™ ”Ðè"B:"¦’ Ñ àˆÁ} ëìíýôþþj§sn<~ìà µ¶ßÚWºÝÖÚpyymREáÌç'Q…YëM•JˆcÔ\Òœ×i8žqš9ÉÙ Lo11‹’---y� Îlל;Ô‚y¤hŠ˜‰—ÞÛžZ‡ßÉŽM„ãÏ…"lÈ�D¦«ŽF£O|â_úÒ—îܹsãÆ  E£é®¡“ëÏ¡–9y¦‚àXn8ž\••CÇì.|YË5æ[¬NÆYO/ú8ßHr0#–z† w‚ÜÜÜÜüüüÎÎŽËÐ!FœÐߣ‡A÷‘³¥>¾·X3˜øn‚rZ¤y KKK¹’Í‘¢GÂ4%4¨êY<MjÜgΜ‰,¬=HÑS˜–à3`æ'F;A5 >[)j ™aq”€€¢'ÉòòòÞÞ^¨À€Îw)C¹< 9Çù³···¹¹iÝSöÉK/½”S›4U+;›se™&ᨦ ªÌú×îiíãñý9ï/u:_ìvmnnn~Ž%ŸZ__o²N! bËqÐ[! 4 ÛÀ:Ê–Jôrh¡AM¤`qô¡S›Y7ÎŒFÿ^zæh°O§ƒƒƒÿ{vöi €rÎàÚDÜ®ù¾›+IP,R™·ßívïܹ³¾¾÷6ú"žf€Çõ[eÎŒDJd“ÄXžÐò4%±„—Efà!'Sé|.Ó¥·zQg |Ã,s©ö$„°`ÁS»mú`¥(±W©M\š<^K00\VDµ)ÒLêv»?þø[ßúÖoûÛŸûÜç&³u¬ƒÍ+îVöDÏ~é÷û÷ÝwߥK—RÊ»»ƒt“…õÌÙ±ÜN“øt¡«ÐË´hVÑ°à ø}Õ›Òé+dˆÂš¿ùµLï‘kž:u*¥üIÈ9Nî�e©™ÇTè›››ÎFÓ…ãÅÃ<6 u�¶4'`¥È R@¤nèN æ¿¿¿ÿï½÷O^õªÝÝÝ­7þÑúúRònM±€´L3h‹1-_ôO[‚˜XRpg—ne¥V0ñ¼˜¤»('r fS½b4úw~wqñp<þÐÞÞÌpØZû~ÿÛ33ýà`{<þÆdî1ß‘; 8ýØÃnÆ ½8­ÌÅw¹0,p-3©:¯25«Ñ9‚"˜‡Ž‡Fól©ü@Nèe‹µ°khû¬ä«ÍÙ³t)õ¥6“ð@=¬ 3åòi§NF±oiQÍqï§µÖëõlTC J£ÑÍ F»¢òêW¿úÍo~óÜÜÜ—¾ô¥»YH†ÎÑïiV¦É÷l½½½7n$êú†&W|.Rµ€m"]tÿ@ž¹$K³ó"P^€°c¾ Qê&©Ãýýý �¤<rÐ #í'!çØ¢ŽŠÖ[%ÌÀ¢¨1{‡ì¶)!‚Œžc!Î"K]^^ž?8øg[[÷®»ßþö¿ÿþ÷ïíí}ô£ý§O?ýîì¼ýðp4Ž&UÈÎÎÎÎÎç>h;R€že³¼ Ð98>Ä-›¬p “t{ö‚ܼI<±ÛíFsžt„Þø‹{{¯~j4úÑ3gffgÇãñ?ÜÚzýxü™IlðÄF4W’àG¢`¬ŒXHã- B f˜ÓaY&Fˆb@U¨M¤†P¶/®Æ¤öt­ì¦åÜ6hDra.Y î7ë0ïÈ6QËU‘"8¨¿'ˆrB%©Jl¿Tw­^ûÚ×þÄOüÄÊÊÊ'>ñ‰••7ÛܺçÔ¶Ê-Ñ A­éÅüs³'¾öµ¯­¬¬\½zuuu•;b°,¦H®™ YJO PúGqÜòánSå1§êEZi_DzZ¼»”¿´xíèÊ£p.„Ð&BGMŽ¥Y¹Ô — ù°Úx’9Â;¡ÿO9š§)m¥!ÙëõÜ v÷2÷fvv¶ßïãÙžú¦ ],Á­­­ýýýÇãÑý÷¿÷½ï}ûÛß>¿ð…/¼ð ³»»K­ ºAØ"/Ä›"éZ§õziGUos9¤Š(5yé¤#\./‚.„pöL«Ñh4sxøŠÃÃÛÎ///¯ÞÿÝwß}çÎ_ìtþùúú#‡‡/Nª"K3º8ûˆL¸žYgÔ#“ŒLt·‰x(ÜÜB›¦LqÝF¦0/ˆL–‹.ƒ Ø™X “SÞ€{Ó”n¯×Ëï/MóNpÓ€z8Ð<m¢&²LÆ‹ˆ²å´b5Ù<NRúªW½ê±Ç»yófîÑI"Ÿ­ƒ<‹VÐ………… O–Ðãu$þ]¾|ùúõët•Ì^ñ|L]ž²œÚ~Úí¨8PÓ€6k>q"^º¼5SH଻/kð€‘Xb â§žjbj {Sfõ¬ok“‹‚òÅÛM)Xû¼ 0]OBÎqÆV!vï Ô,, DC²Iî—– 4k"Ú©Š€H…Ø ÿ[k_þò—ûýþÆÆÆ‹/¾˜v´ã\“?.ñÝÜÜäÃSHÑ“„8dßbgôM6îîÜ¿¿ÿ~ôo&^O`MÿÇÜÜ%Mÿ™œ ËžD¸ððððàððÇ>Óïß¼çž÷ýÄO¼éMozñÅ?þñèÙq²õ‘�� �IDATgÿ¯ÍÍÿx~þpBÄȇPVrjsµé¡yc<Ç:r&&§¶@ƒA`Câ2EÁ{4ŒÃ6<Nò²<ŒÂµeñ`­F›Ð(3(>h¨‡LR‚vo(ɲ˜š4ósªÂÓ£LçC ?óÌ3¿ó;¿³±±`œ€õŸ?²oæz¹#‚ÿº,rTåâáòÑm*4œl¢ÜZJO‚¨‘d³'|ðÁ•••µµ5ØPÊšU.¿ø{|F´Ïë¤hø1öüµeæ³DÛÑihgE•‘€ tÛd´sRåsÈñ²¦íFæ›S›üˇ²az¨™W™´)q=£|fÖÄ7;ûs·ný³õ¯žzê©K—.½qoo83s¡Ûétšœ ³:i$[ôlšIS¾#ƒ`eìP©µöðþþß8<üßgg—ÿ›ÉDú?˜Ÿß˜™ùÀÁÁÅ™™Ë“…4[Å:@4ä\\XX8þü>ð׿þõ—/_¾råÊÍ«WÛæf›Œøqü¹à�À¡S¦Û`Á:]€LÀeâ¬UŒí°i=ûbcàÌ•°‚½{ãð XîR°¶£– Æô!¢’v7ßôƘa»‹fÊc'|os¨ó`tIÏ766.\¸`L‰R;ÿdii)å&ÝA¿©Bd‡5çÛ·Æ]FU’ûû(/B5èÚwyáÑSk·°°pîܹ½½½­­-ãŸÅÆ€ ¥‚Ñl§€~ƒT~¢èšâáVêæM i$ yÑ”°>À“¡tBÚî÷û,ƒ“s̽ÛçY.Â}ï¹¹¹$Ôfj9Äg×þKm"j;-äìøïŠc¶öoff~}o¯{õê?ÝØǯÜÙùíýýÿ¹Û½:·Nçp"ji^SÖÖÎÎkÝ&:œE§Ò37MC‹ÓSÙ­µ ÎFíààM½^.û7‡ÃçÇãoL„œÉʉ=äbíè÷ìììÜÌÌp{{o0ØX[»qãÆ½÷Þ{ãÆ[·nu‡Ã½£Ã¶à]%ˆÒþåİ—L6¡3p'*<ì$h\9‡h’˜+P8ý_MR§.%ñw)¦Ÿˆá3 0ºcJÓ¾©ù äá?íL6qÚWæIæ+r Á•¢@?&—dip̬ûI„àŽ677ý�‹L¼jnÐUo¶h‡XÂ"³läEpgÌŽ™ííígžy&Û– ¯ÌæfI=s©Ÿ` šK977w)vÞs¬õ‘Û¥€±ä@ónSÖ‚’ê à¶î¥�Â'UÎ1ÿ Ô_T–�F-·œ$.s ^dÈË£à™væ|$5c?Øû=‡Ä÷µöÁåå·ŽF/Þ¹ÓZ»ÕéüüÂB§Óù[“,̃ï P€p2Oz-1Õ4 ¨w9ïr›óóó[­ýÂÂÂÞÙ³sssÛÛÛg4ú϶·_}pðäþþþQ7°pñøNOx4úý¹¹óûûóâÅÿñ·ûÁW¿úòåËý ~muõW—–•r´q¢®˜”ÈŽÍæž3Ï6Z/¾ý6™™uÙ2ÔRò-3 ä•(Åt”ç<Êé@XJΛe.�sîÑ~W¢Vy ŒAÉÊǦ�Êâ<òñí£?ñæ5Îk:‡‡s“vABëèððËóóÃÉtÉnrûíÐá9¡Ò舺Iã ˆ¤YÍÏJçÓéù ŸƒÁÀâ°Ì÷¤ 5¯]»FŽØ¤ôŒ_;Jê†IÓª¤�¢Ne+:uê‘GÙÜÜ|á…Ðk€0MÂätŠeCÃÆB®ÞJùWðGF£Qœºòù‰ˆ<HIvª>Ö¾WâM1!æµÁ&t&Vü´A@“¤RéÁPž[`1¡ÖÚ—ççß=½kgg<ÿæìlwfæp<þ·;οévw%„åÜÓ3Û¡Êdb O®qïQ¶•›eúï‡ÿA¿ß¹ï¾÷¾ûÝgΜ¹páÂ7¾ñOFÿrkë,­ï´=>933s8ŽÇŸž™yÇÎÎ>ùäâSO=¼»Û >67ׯã®@|¶=£ûNÒ ZÊ Kơ♀Q VFK�k/€Kszâ„\Õxo‡^ Vž l.éi3žÙäOJ/ ޲B´õ*å@´4‘­Žiää¿~`8|ÛhôÍn÷üááû¶¶ZkƒNç_ÌÏ·ÖÞ7þäüü A‹ c&ƒyÅ[gX›£ã®í‚¬I³IÀ=-xÆ.ËÛy3tœ³žš�®— ÀâÀ«­™dz…mŒò¡ÇxùòåÁ`�¯^>B®ô¢ˆ1EôÚ=d·gÉÍ2(B0 “—+'ÀIÈ96ºšõ¸ €ëöÝE·¯§€‰‘n‚GЉqNK1¶Ö>Õé|¶×s#tÈ“w†­½=„ñ@8¬ª&ý wAÝ¥pnõÝ3©!Î;÷îw¿ûu¯{ÝW¿úÕ«W¯Î¬¯;É¥•eñ]0·‰ÿÆÁÁâx<ÓéüôÆFgc£µö©™™ÖÎ~´ß÷`QÐUÿ÷»ZAÑD&ž¡ýol)ªœ.|èØã�pÕR’ù5\!àÐsÔÒ‚r%ä«u¼·ÔžÑ0צ¾6^ð "㫜ò©bK‡²µö¿Íͽãà`µ×û'<²½½½³²òÎÁà»ÝGffäGé{Á¯Öã9ËÛµí'¨á7ö, {óľžÕlmt ™åàààÒ¥KnêðkT´Æ‰4F³Ý©õbе¶¶æy,'I6“õh±„$ÆkˆD)¢…Ó¦p,û"þÆßœ„œãoäv‡üš…’“:»7«?†1 o¶£®ãœAäÈTÀ€²U(éâ³m2ñŒÃœ„'Eœý•!ðR%DF3¡ˆ,‰ÀfÄÉ^¨V„Ükmöðpcmí™gžY^^¾~ýú`{»íïïe*mv¶hi#üCu‚Ìx<~avöKKÙ�ÿX›�D+“ìžDWÃaQ<¤�‚nW\³pU°[OÐ'QQÖñ ];ª/‹Á°·á¼‡ÃX,£Óck n7­&#˜Ç†›²– 3XCzÁ5pÙÌB#:þüx<¾té’ÝÌfgg»ãñrkoîvë-oyÍÛÞvëÊ•§¾öµÑ3ϼa8Ì£iò†&"ƒ¾ó3oG =+m©Z}s G9Á]µ c1Ó–?f€=O Ã×ÞKø„Z„ׂxE6‚‡_È&Ú¡SÇ@ Ó3t‡W‚é cP5çˆÀÛa‰þ¡egÍ—q¶zÒË9æ”9lŠQ [–H±..1Í\4?ÇP›IME¨‘ àS›Z¸ÉôÓxí2=¦`zr"„‚#1pcŠ0Ôê™™™ÖéüÖÂÂO‡‡×®ýÞïýÞŸüÉŸ¬­­ýÈ;ÿþÁÁ»¸Ø¤ä–s0Ø^Qùl­Z»<évD>`aá;HãââááaG‹lÑõYk µ]FS {å“!†Àã uv,sý©2GUøƒkS—~A ”eà¿ÉuÔ™5ÿ joIÿ\’í–ÉKl¹”Åà)˜~´‹¢0—––"§–Ÿ~¿ßÝÞþ66~åÇüßþ•_ù¡ú¡µµµ}ìc¿¿¹ùw®^ýñííN§33AG‰µh»å€v¥`Î@¦rÁÃ6Cš¯Èà-ê�¦ ]èšÕ¯)½ Oj7©£RÚâbž¨¿´´ôÀ¬­­­¬¬¸%{séIŒˆeÁ7‹¬¤­í¨”ޝ-›4š%{¹ßï·‰·¡)é,’PÑŒî¢-dí˽Ÿ„œãÄÖØð¶Ê€Œ_(mžc¶ÃÇ Ýfó#Ù6µåÀÉu¦æé}û©¦òQeõ[¡„|ß„Q›HB«-2Ó‹ž“ýÓ¹¹7‡¿ôR~sùàà»Ý‡'»1l]Ï X•€ÚŽSÕAÔìO3ÑáÚñ´MéÎE–AK>Ä.&…oJõi­k.»ŒËqN•ya5â§ù‡¼/‘*±íB;ª™Æ?,ˆÅ»Ò±ðxf‘TɇŸ…=.›Ÿþy[~÷D><l­ýµ7¼áMozÓ]wÝÕëõÞøÆ7~þóŸï­®¶íí¹¹¹ù£˜Œ/¢Wâ¶c‰ Ð%Hň莗Ïf+n²ÐæÏ ˆDtF¶QzuÈcá3I’øçÄïi}6V”W…Ñc ‚bòWN Ò¾Òb4dÇÜGZxÜñ*ÿ³§"5k@ø¤Ê9~` §XL¥èF²—�åáØ˜,àñ‚â?f¹ß.&íÖoò*l:L>@Éýßy¯ÿì&·+nÄi;d[ÒaTlÍùN§ó¾áðáNg~<~ï`¿ÿ?»ÝGßpxøå^ JZêý`\P Ÿæætb¥åÍcçM&Ò‰£F±©B†ÃaȬÞ40 ˜âE_×Ê"æÂ:a‡ìd>g»n`äŸäzx)9NÅtÙ“=\[&T€Ú€e@¨Ü[ò+6ß’œ×s¬¹_|1^ñ¬»~ýú`0È[‹J¹¥cK¯ŽQy°h£@%o�K,L6zþôóuuãŠ4Âȳ£/z baPô(ƒ\ºt ÙfpNv–ÉÊ> „Är‹|©tm'Ϧ°þ êP, ¾Ô"U<@€A>Áɱ;I6ä= 9Çrð’9 õH:,L~¹P6-ÊÄ>ï÷ûëëëfs±€HÒm©[À\{opJÊø.L†½\y¸Tf®Ó ìÌÎÎ~~4ú™¥¥üÂ5“Í¿2?ß™`Í>}Š \“­z/Ô—tªšÌ]|_N$ ‚¹H|š©<bÛ•à” È[¶Ô&Œs›áe]M;þNÏŽðBíÊS¼[\zzæ´(­ùÙzL„Ò9á6wrZÑœFì÷ÿÖg?û‘^ïU¯ý¥K—¾öÕ¯¾õæÍÑÞÞgff$ðš!–ï"§¼Ó à¯&Uæäï i<['C–(äwÈ-ðp“Üö†˜$A@ ¬ô „ ÈŸ1€H=�#àXaÓq§œ ¼zT©È«,¶M`ȯy˜—ž#¡<ûBYëÓ:ª¬ Î1Ÿ'ôcþéõz¯xÅ+â¯ÌéOã;êΓ´Ž|šÃœ™J¦³¿¿¿µµÅï”Äv ƒÀΘx«@Ìw\d×9³c Z2Ù²²¦ £ôÇe$%‰6M‚ÖÚn§óBfÔ'yÓl§3ÓíŽc½£�Cú\Œ¡<a`¾Yð®…JB— ÎJ¯á&0õg4ÇŸÝHc¿MñA =³ýýý^¯QF:¢±¡=ãA¡Øå…ê$Ë)}c~Á',)Kð(j8êòPøŒÚ0bB™è£&…MÖ!Ú£<=¢‡Twvöj§si0x÷ŸýÙ¾úÕ¶µõý?7|¬ÛýÁñxv’Od0Ö‚@µ¤ü ¨:ñbD ðÓš§8±'ÌÍÍ={vfff}}ݳ¨†»)"IžŒ4™±ºtFI3̼‹ g‹Èž‰£Ä'ãáÈîïïÇÏèÏ;B)}bk†³€© ¬´â È¢µ »Í5N4ÖŽóç®»îzøá‡Ÿzê)R*/kX(Î2@œYÁÎC=WÁ/4\STɈí¨é�v/$Œp~h–Pq�� BOÎÎrGgÏž}ôÑG_zé¥ëׯÃròng«P&®ØÀÍdß"ïú¦P«mðßÏu y¢%Ô ÞzêÄ‚)wdÉýd‘ǶIA'ì†âÐnöšK{Ú›”ÌgÚ_À^Ví45™Ãˆä—çC‰LO>Þk„L Pkqv»ÝÙn÷'÷÷/ÌÌ<²»ûß?÷\km»µÿjnîU‡‡äÓdúÇ+p¸u6ÛØ|wÛÜñ®‹ Ù)çææVVV|š{È̵i#æ¢J"È‹óF+âžMº5ifÔ †´eæ½H &FÚ$pg1@†ý¼I:ý´=lk#+žpPø~ÖÜ:.Tí$ä|çgccãòåËPcÝ¿!U´�W–ZÊ j[ìdyÅiœÙ31Q\nò»,‚]Å`JÜ•5}²~À&ɬ&aãÙÙÙB褙‘)6V¹EY‰(ò_EË3¥ r&ÄëøHržNaïÈÇYi­7‰ ³õ¯±ˆânÈÓëõúýþÎÎN�–bqoÿSxÕ¼8ó‘ÜiÀ,€È-ÂrvÔ†2›æ“UM©xRóTøå5å¸ÁúBsž€Ýätÿ¸Ó¹8?ßÆã‹³³Ÿê÷¿ìþ‹ÅÅÕN§3y_9+ÃÚ#ÏBfˆºÒDnÜ­²1ØÊÊ ‘ÒX“|“ô@7c î¹Äa9™�Mîâ-ìHŠdÂ[¬�•ÐvRg` ÏïX´"%ãËšur…Œ+Da\¶UÂǯ$µF\ r{rŽág{{›Ê<xŠ1A µç<X$5P6M…¡ÏPžV9¡¢Uæ`-Z×®ñ›<+-žÈ~°e5$7´WVVÖ××———Çã±]°í|N‚;²V˜$�7óÑì´×l@{1äX<uêÔöö6Û’aFjS� ;àâסpÙ³Î]ãqRƒûO//wnßÞïtFÃáx<Þ™ÙÕ¤°ÙÏ‰ßøH$€Ýò^Ò€éâ•NVÖ®˜©Ñ:³?§!Ç_¾”!Ò[@Rje"wÞÑóÝî·gg¿3S53Ó ’633–+B e™ Èéðó M>¤–I½ž2=%H<lÌð#òÓ¤QdqwO/°xl*ÊTi‘ëvÛÕU>híh4ê÷ûÞ Lò{l‹š’.ïÜÜÜ`0€›œ÷^¬áOé3vÁØR ° B@QqéFõÏF8 9Çÿ.Ñätd•Žró‹ÜXf¹³ÿsÜÄ0Ê!„‡µ[ŒIŒz;é+¶ÄMj¾@ÅmjÌ9&9‚9¯CRŠûçw%G' JްbÔÁhŽ“¬œ˜àT ByVðÖ’ó–ìÕ#‡´Ášzˆ|¥—K §ëÐksèü“×u»»~ý¯æçgºÝw<õTw<n­}eaa­Ó¹o4úÝ~ÿ#KKì^2ƒä§y&t˜»•ÖK ø$Ö¢0_IyžY6%-5ž×½´´DeÃga&k;¢s)%y›Œ¼X»á{}º¶£Æ2äeZ £” ÉirÀIsË7ËÊä ;¯"’y$.k‰†¿µ§ r©òÃ,ÏC ÀØ“½Ú𜵠"¬"Ïx!ÇÞ& °�†$”Ö¾+ê'~¶^äž%ogséÏJRâ‹÷£8 9Ç6—cñÚrX—ãɱÁY Y6ç¾qrL#Éòz²Ü§ÃIº8ãKî X%ž[cNˆ’¢i.uZgšÛ a2®-¡Ø¢<LªgQº…þD âç)ŽAÙ¨ÐÙ™F¤a– ±�YnJÑ{ÿîë;<üâââž>ýãÑ]ïyÏÙ³g/\¸ðìóÏ_wÇã… º(4Cýây’­[EÂÍ[ž¡+f«ÝpprrwÈ-ó‚æççï½÷ÞÁ`pçÎÞKÀÄò—˜»JŠÛDšª=“üfF”n¿W \Ï͸ëàðOçßTÃig^Ö°gæ`ff“†ÑC&Äãµ§‘÷e¬eV²-‘-ùƒÉ Mjëèòaoh™ —Y”nX²tÙ}ç]â]ø©Ú4ÖÃO6­�* j< 9ÇùcC¨#I¾²‚Ñye¿¹Sgt Áñƒ­{†®9. È–……^Ü iT´´ ‡š¼ÍW¶o#áÇÖ¢¦»XR à›ha;Ï'ëçƒ�8P� }Ö›‡ˆ<Ú�}Æöˆ #Öœ˜ì.«ra÷é—ˆ²äpccvvöoîïßþèèWut÷ÝW?ûÙÍ}ìç>ýéÑïw&½¤…Á=,›æ¦± •i웞ž¥b‘ž|ÅÙ³gï»ï¾µµµ7nMÍb`$)¿¹!´ßr›‹‹‹¥ƒUÒ`OÖ¼Ç ^;ª¿gĦ(bØÈµP¬>`X©p|ý]ìDTpµ)N¸¹Í݉““—V¢)õ.+ `“k¯cÊ2B–ÐEË\ÄŠy¦ ´£ÃÔ\­IÒ…/Sl´X$ð<m©PÊ_jAH%LíÀ$*àüIÈ9`ÍÔÒd‹ñš#D– C‹g§-F…4Dc\«ÔÑVûOw¬€„ˆõÚív㽸µµ7,U>d,áÁûÍßN›Äü¨ã}Îs3lBvo…gÕŽ*¨ºgÃÑ“3œ<"Ú¿ó°a"¼¬–þtðkR‹ÉãŠó»oÜxúg~fñƒ|Í£ÎÍͽç=ïùÌììÿº½ýŸþóÿõ™3Y@”M¼ý䶃Á€ä$jx #SKhì:uêG~äG~ìÇ~쓟üä§>õ© Z4¢h\#HLWivvvyyù¾ûî»~ý:ÙÉææ&­~bm^+=�Ï–)–¬‘8ô Ö ï9ý€M"1–¾Îkå5{°œ¿tÔ)Âèk†sl5w C)ÈÞÀ ¦PÉ©óà‚²<èìîîîz8dÔÕR’ Ö-ø¼Ý­B ÿ#~ .€t9q0©—úÿ¶÷æQrW÷™÷­¥»º«É-@ Ä"›À6†’…Í&dƒÇ'cËy=&~ýâ…$<gÈÂ&؀È1ÆÀØä°ÈF‹MØBh!vIHH-´´¤VuWu-]ËoþøRž¾%Û™3@ ùÞ?8¢Uªþ-÷~×çû<^r©•ùöövU~¢„¨[¿Ì  Øîd*˜Í¶™BæFyd}iD´ …‚kðgh“îB…µI�VÇ_'ü¡Ls˜l?1Ãg9¾FXä4|3‘8*³n¦.…|=Ù<Ct¤¹Ü˜ÕîÎì²]-Ú$v0GPtS:ö@ÃdœxŸSj•qF(ÔÕÙ/RÔ©½µ &œN§6n<öøããÇg¿ýCúÐÌ™3Ù½{Üo~sÀ>nÜÎ;ퟛå奌ŒŒ(ìX%vì^ìw™3â>QR¬Z¥RÙ¸qãã?¾nÝ:^ÊPÃAa�gOµZ}ã70=ÞP”Òª~/™bâ!ÕBÖ/ñº÷œ”b±(‹"¤ËäåVЀ$. uÑ&ˆd¶+úuÊñ¡aE'Û%1\¬ûN)¯’¬­ÒJÕâÔÒþF¯œ)+û'tS´{§Y£Góà )žÉ.4=;Óéb—B¡ÐÑÑ¡þÆ ;ƒµ—ÓšF#ZJp¢}WÕ'f'éE'Úžž‡Êîb@ç£h~ØLåÉ 6gÉ¢T8ñh?Ô�áG5w!˜bë~ÞɈ»Î‹E0T Uh“L&ûúúòù¼ñpÓûÕQ>êH¦QýP¬pþ¡Žûx„›vUŒÄ3p§kù‹ÅD©4nÜ8ûÛR©´{÷nç\¹Ti 2´ˆg)¦y s*:—C)O_^¥Xµ7^,ׯ_¿uëV6†¢{)js0›b©]c²˜¯‚²h®ü³:bi_ ^†?°Áô¤(¨AÕèy€A09NžU8 ¶R³U¢ ¦¦È®Ì +w‘B¶t(’‡æé¯+Z] Êç¦~×l=!”‡+ÃÍâD…B"¤½ “ñføtšØÒPú‘ìØ]Á:*qƒy5Jš é$u(¬µØå( –WýfÚucµ¼Z“âðI0»8v¢A�T‰3©Œ|^‰,µ[C ‚Xà¬ÖîØ¯žÎ뚸°Ý¡FWñvL†NA+± «yä‘7n, Úç 2N¦½¯¥¬¸çfnM;p jq”T_ww÷îÝ»û«Õûúvþú×G~zjÖ¬(І‡‡—/_>ñž{þ×øñCCC{|ÕTùÛÚÚŽ;î¸I“&=ýôÓ»wïnn°[9‹6Œ¢ÌÏ­¬¬¶»r¹œ7º X�^W}¹ŒˆñˆlÃà„\Å™Zy¬þžWlFdÝüÀÌ‘ç)bŠÅhW¸6ŠKbX•cùõ×i9W3 u3°àè÷èt‹: (ϽDꔨÕ0´M¢v©_í÷* öo´Š®¥æÐÓÊTÝ<©c/‘jM¥R1 j',Ô¡—ÓúÅ>�Bª¼ñ@M"t… >¦QM•ñ8¦À¦´Z Â~ÙѲݬ™2-¦O\CÛ”hšψ%¼/ z&KtÌàôŸ>¹ŽŠÅ¢fTÕjuýúõÃÃÃüC+¶˜ö îVk ñx<ŸÏë8*Ž |¬šjj5¡$Ô£n6Ôx}¬:Ÿ«V·:·qÓ¦i_¼íž{éôÒ¥K§ÞygyÛ¶5zÏÍÆJ¦NzüñǯZµ*›Ív6ˆMÍõ–J¥T*…&ÿPqLL¿FäÁÚ4ÖΓU ãÀs±Æ6Èì”ÖBuW;ÞJ¢cwªRžØSë2jƒÄ®ßî—©½´Z­–ËåôEàál_)žª/+PM+BÊ<ëdÒÙ~Î^Õù$­eÒTžA¤Ý ý È ó ^‚/$õÔdN ;8Ô ×(~Z È£3—ïdìÔ\8e PvDŠ@Ô,åêëë›4iR>Ÿã7€K„ÂZ‹kìÎfzMå2¡kB€f¬F™-3ó­ô3„3€—(­¨Ú˜ú, G‹ˆIm¸+eñR_ºÇTÆ ÁÞh®Æ?TÞRíÜ*IarÖ5íêêÑj{­V+ Æ2GŽÂßZ&þ — é¡òhé̩Ɔj ‰^™H@x˜—øqB±øH:Ýÿ¡]yþùíõúçnž8ñ•ÞÞÓFFÖ‹ÕÀC”Ëå§Ÿ~zéÒ.5Ož�� �IDAT¥t¡ÊÃTÁl.€A‡võ½ÀЪ3öÄÑJþ­È%>Œ-ã®ífí íE˜u£³¥Qæ±{œO^ëQ[/ê´œˆ€pÁ £è,"ôx³:½¨¢jHáñêÉü”­@;O:]@é <àfØgW¹éðÜªŠ¦)»7«Ä¶ç1ê®Á’EQZ�;Jšhe7^1t¼ø-¹\nûöíÊ;FA÷‰¡Þ.Es[Òs ZÐ2”EU»²&–‰÷ÔÊ’“éQvÅf…ØFË”¤8ÀNTUÔ;a›ö¸Íé0,¢á˜jqz)Êq_4Eóù<§ˆb´•ìTÀTͶ¾¨XpÇy¦N–f(v­0xã>:²§ê�NC|$‰ÁZíשԑù|¢X¼oêÔöööíÛ·—FFމÇœ{®­yr º÷ìÙ£“}% vðš7W/íR«Õjgg§ƒ#’ PÒ€pŠšrÝÞÊÅ ¸>EôªÈ,o.‹´Äv¢kÙ<ôJ,Æ×ã–E¿�vKþ¡Žªx$¶‡ùtÂUˆu¦²G³]‰œð$i³]!6¤tŒ4iXqên½ÔJ«Ó^l§¼$Úç÷$ÕU¡$uÆ-«› x›Õ T€37¸œ»OP@unt\ŽÞ�lÓ”Ý` · u*M›l“Ñí×y ’ m{tOÐèesgâ�¨ð0‰±?Õ<Ê„{ZáqÂk ²`Êí†À¢}@ÅÕ‘{ÏÜISöOuZhRÿ¤túâ€o¨<Œ§ÃÉ´1ŽŽŽŽádòöôXeãàL§ÓýÕêÈÈŒœmÉ$C¸°O”9Æ<ŠcW¼ÒAªìöÎ�Lï¢ÐS*CÁÌZ)TÝû_ìnìPºú!Õ“õ0TyMtA`sá“4o{Âk²íA²enF©ÐHi($ÁzšÄhGÊËìálÖ¦âTÕ^ëí;‘í�¶�bÐʧìI½%]ųB¦ ÏX 6X¹§ž¯šBœ”NP Á’(% i¥oø‚Ëiqa Æ{ÆÂ­çF†®A+l†÷רdßpü ï[ËúžéD.ŒÏ“¶ãÒˆ%í: 'fñp «ù¨s‚Æd°õ~ìðÇb±®®.íÃuB–c´WZ@#0ÈÇo4p6¸5µVÚ5å(¹ŽW”Pù/ jðY˜›ƒð„™½LÔcè1BÔŽí3Ùl¶P(ÃQ©£Šè´.8N|*O¯AgÕèëºbĵíD7‚¹`|}\– jÒ~K©T2mPÝÀ$[ NX¼‰˜0EòUUŒšS¹Ì±Î:†â\± ¡ÖMÎt ÆïyÒÔV`²Ä”>ŒæÇÈiŒìΘ§PEÖ TÑšUæ!¢c4°ëi|ãµ÷=*»uþL\±Ëå²áìáýÏ•k�AÆ©˜u­—(‰­ÎÀ)#Qp9-Æ`­@ÈæM�p¨#k ¨Š~šiÀRë÷褺֋5]P\²Æ;ôx¬@ÔÓÓ“J¥öìÙCÍ‚ ‹¤hÚ#7gW¥4q Ô”C¦ âK•:•aŒ& ='5pô6Ìáą́ÁzàåCÙ©›[‘„[Ã^Ó”Ö"íY0Þè†Ç.L«“èä9E!Þa¸=Oší:±¡0HeF`{À·S0$(Ì*ê£fÈTúâ*˦L-8NÍ3ìíWÀĬ¤ËVñsBõFƒÓ£ÏЖO3Á¾*ƒP6„Ó {ª“ÈšìÏQŒ5Ç }S¥þÄþbví;5#Š¢ŽŽ`>†÷£{äaTøÎö�"Ó$1&ˆëaÊuº™¿ÒÁ2r,-oj8¥i=w§Cè^QN«‘Áå´`©þ‡O£I*9ؤ2˜ UÆÔ©Zî”Rš,OjÃVù1ßpص¥R© &ôööÂÒèyDƒââèZyøWÜ’â¡ùÕèۃ硤£raÊ?¨)"»ˆ…è»öot‰©%År˜«ˆ Ê#ó·’j+t¿vË6 K̨dqêB¸lFXôòýڷǘzö+)s?Úó` Dk¿d( ©Ð™ÎQ©äf?£Ø>ñÊS ”°°ÀrP¥½á™8QÖpcIòµá§Rž-AþÔ©�+Îlù²HH%…xDLkT%PZúº-ûçáãe•ÍÖ5x˜tŒWãNà0:´¨A…—œèñhaÉȬjí°=xìÜæHÿl‹ÀWGëZ… ˆ£^ǃðC¡¡6תÏ:e©hE#›ÑF‚R-)¼Ø£˜ôh? Ñø@;†„þAöºÚÊ}êBìN­M­_EÛÆ››ñàÑ!sf�á>ñˆCTFLE‰Ú˜µÄÊÛ—ð4¥i“¹ CmXcI{ ÚWÂ*PŒ@¤¦â•<®ÐÒJÆøéy¨ú\3ú\¹SÕˆtvv*`Ǭô3Ôc¹~M(lÀ\Úc¡ÎÃæ„èšâ§& Ôñ#êáI)¸ÎkøQ¤Eû ¤$ÆQy9!‰Qº&Õ1"=E!¢YzGÛ6ZëÖתgª‚aç‹{çäbý‘>ÒY:E[P,ñÔ°`Ä€¾Äcƒ¶w§ópl|»±úî*ôl’× k­oç”J¥®ööc;;c±X.Ÿ¯[}ÌlDµšH$c±|*eÀyƹ™Â#޳)*Âz uâ„C¤o�*ŠöCS Ñ GBEo¬,—ËŽŽV«Õb±•–ÎÖa¢:¬:ƒš¢}tÆ‚‘ÕtaðÛc£ß@;Já¤zþ©.*!rÆ6!ݱ3½kŒ‚jUúe4!Ƨ¡ªóO$¸ •Z 4‡%y§žzêqÇ·dÉ’—_~Yé´XÉ•§â儱wˆEcH…>–U·4çÃI؇!D×RÁ �g KÙOØ•  §åÆÒGòIâ Û�Vž"}á;íŸwww[9Ô£``{¶RU«i½(¹@2‚ ê“Ìq«ê"}Àw*€Xe84I¢¦g|©J‰mTèè®*p�n'{ž^ŽëÌUöfaÐVm{¢%Î&åò]>I¨dÇDÀ<(p9­Iq,¥84ŠæîÚµª½½Z­ž?:jYôo‰Ýñøá££´µýHZl}æ<´î¡E*'ê9è2ìÉW©Â›ŠÇx‰< 3F§Sˆ ÂÕñO-ø:×qcµ, `±’Š@U(6F˜*ºcÑðFJ?¬ó4 @kZ}¬¥À*O�B¨PS ×Z–ã*JÊ…:Z3Ö]]]}}}GyäÚµk)éŒÈoÃé©F½j’:™&ÖœLE¬2è“ÑŠ%y§}B/¡;�ÝC9zÕ<o¢÷£ IÚ] 2&QIžƒav=ü¡:7–«M¹�@ñ(›µj"¨jŽf0gÛç)¦QdÓü†ËÐ|QqÆôÌTÿMù×½Q3/_´é(Í·ô”êÔ*ÎŶ%ü: W)ÚHùßÈ€›;¦Áå¼ß iÛ÷ÕjuE2y_GÇŒbñûÝÝ.í©×‡‰G“É>‡((Å#w®i]Õ]ÖñR@/Á¾ßΤ6�ArœèŸÝˆõZ´|¤‡“ÝO ZeB”kKÿ¬?*y©ýö(ЬF”Ïç ‹U{¤=Lµ;H¼`‚¹<¬[gggooïÈÈH6›E|W»ñ ‹À—ÓØÐ4±­1sƒi&­ÔÙ{¤ö%f@W­ZµvíÚ;wj7ÞnMó"@¢yÑÊÜ «<Ý>x?ͺy Õ€°Ò(]h•Ð.”™sž¶÷KuoØ=’±)A‘Ê�…õÓØS£Ïæ¤ ¬íLxrOÅÕ²U(üRå#ÿ¦Lç|ÞPi·Ž²êñИÖDƒ0­rF(#5œÙÚºS§KãÊcìÕ±1‚¦Ï£ÒeÙ^êéé©T*ù|ž ¶FŠúIûÂVÕ‚Ëó>jµZT«U«ÕSs¹=ÿ6eJ"•êïïŸ:<|k©tkƒ^IùtUÚ’â‰F1êZ”êJ¯œOOpÌã•‚4Ó#+T)Yð=í/•ñÐÃOþNä«,aNT|0J’f(êîîîT*522Ò¬5çÆÊ\*̘zGEæè(~OOϧ?ýéO<qþüù+V¬° èìì4Ïør)Î@.‚V…ÖI<мràëõºIÚðÐT±,…Ãa§”aE7€âT7È~HŽ ;µRé�&Êl⾇u¨·�~­8 <º"}=~r ÷+f}«tžkÑz£B]cΑ3…W Kð)Jú®ZJºŸ­:ÇÔ°*¬ëi¦ Íœ,åéQM¥2QYX, P5,úô´ã ·´ýo__ßé§Ÿ¾yóæµk×ZÙ\ƒ963žòVp9-+¬½m»c±?ªVoèí}vúôÿú•¯tww?øàƒO=õÔ·b±_åóW6ð¦ìBà7L_³ó˜·ÂxCûVÓh…ƒ…« €Ò¼âè©PÐ |¶“À¸™òâ�¢¥ŸïÆ îµ k–ó0•288A–›ÌP¡Ïf¦z½žN§ëõú8çtΙ©jÜøÄDbF_ß”ŽŽ'âq À“'OÞ³gÏ–-[hój6ƒº—&mØ8C[–Æ€‹5cÌ"0<dËz<¦}ZhŠÁ�é4o–yO†]¨ê°‹´O®é©Êmè­>UÜ-Œ}(dT‹±”´N«E!ECà ì'Fž_,aù³Ë€àÎ JZõå‚áäVÒBjL}Qœà 븢$¼ù97V ÄÃìéÏ=¿b[ÈÆ€´”§Cl`íGƒoÍ‹2qáWã •| ˜>6«(¶µµ …5kÖ”J% …yV(ý „äéš—Ó²,ÇÞ_{µ‹éô©3fLŸ>=‹M›6í…^¨×jù|\J èi† =aµVN½9bg�· ÇÄŒ/ÀTì¼1õMŠ.±Ž¿Ù…q~¬f+²0ÙÀ Þ'2uR7vp]A5бAÅÃ^kõ@¹ñ•¾žÉ8-ÜÅãñ/ŒŒ|©V{3›P¯Ï43ç*•ÜxL­¶­»»Þ°5¥RÉ0:u¤bqúúPà½W‹E›%ŒÀìšÏVœ…JËðêqÀcr豄ßÄä ôáiqĨËh¿Ý>cõ@cvQMÓ׋â¨;·K€e£Í¼&ÈTt*Åzävö¿€Êè„QPÑwofÞ>œJ¥HCÙ 6+£U/œ“ýfšf6åèÔQêr6»fæ[)à<„¡R;“—#±ªå,ƒM—5ƒæÖ½Ý¦¥ÚJO¥€«:(ÄßžC±Xìïï'¨Õ“E¡‚ýC!A§¶ƒËiÍz{$3sÎ …_|qåÊ•Q­Y³&—ËõØ–Ö·† JÓIì£ÎL è´"èjEž%m¹+ÑŽmYURÑn<x6m†+ÿ#!³¶£p9Šëw ôµh‡RÇPºCûÁ+ˆ–([Ë€êØÕ‘2# ¾«­mB}(Ò&éâñªÕŰá5ÊåÅbqË–-Úù@›R¤rDª)ÁškµŠ u¯jdoªâ5~üxmSä.8¯Pa5Õ*Ó¹«M>¡12Ž_/UkPÄÑĚ͌k/AEZæ9t,Úö¹Å7 h€a×ð° hÊ…B‡—m(—jWkçWÿSr&/ÊÑBKˆ(órÊ<^AĶàõD]ƒeðˆj4³™s¨Ñ^ËwÚ@òøæ98ªß ¨Ñ„‰²DkÙn‚ËSXsΕkµE‰D{©­ZuÛ®]ñx|ëÖ­ÃÃÃ7‹7¦RüAlåA†ðF^EUË‘ ±Ú1g¶w1F^UÁ ;¬køƒ8КÙƒvP•¯Ó#ó +84%®¶V¶76¡¢ŸÞ¸«:]ïªô@ŠÅ¨¿{øÃç+•oww¿bš›££ßŒÇÏkæ™Pé‚á›Ò>ÙÛÛ«šžöÀÉoÌ *Ö=W @UȰqùh±05U«Õ:;;U¯ 8u?¸ ñ°äÙZøÌîUwîéûy ЕÌ9¡5Ç&±ŸƒC㮉ªªêÊÕð4ìqA/¤]w-v±ááICD€™jž:PÛ.Rݼ6f�†¨¡ç¦,EÆ)s–ª´þÌ@¹©bå½V¿–v=쌎ñîµD¦=õêWtT4š¾ÐËÙWjk±Zm0‘N$®Û±ãÒb±÷•Jÿ£\EÇãµµ%%©g³ÂQh{p³j€T ,7–MË£ß'5±Ró˜lt*{–�‡5N-oΊk¢`í©êt›VÏ 1ÆjßBQÀ5àç<q+F3" Ã#évÜÐh$vñXìæbñ³==»?üÂ3V­Zõ“áῪV¿Y,þ}[[­ƒvË~‘’£`q48¥£ò�ÛTRI {ÅÖ“ÐwŠ µI<¼µ"Á@x3ßÃÅðIO©ÓŒ¯7?T¯×ía‹1Ž:BÄMi$Áž·<ƒNYX#eë÷00‘²wëYð@ð:óH®Ò±%IAçu´K¬öÁYRè0œ6éœ÷°×ËïB)m”‚ðV<ÞE‹·ü„)`0Ê  .–?€^a‡XâK¯ÎªÙó‰ZtPT·Šj&Qƒ .§õþÆþ4¹^$‘¸¥­í‘l¶3Šœs?hk{"‘8­V[ç\]¸¡\ƒqÜÖ@f4yß*!êMë‚…s•öÚ˜:*aÎ5h ©T4ÈïTkD‰ß• Š}lwäUÆ\Ó<ÿ^«” ÓÎ0þÒþJ{ÝͪBo‹h9—r®äÜ”)SÎ:ë¬M›6½þúë###õJ%)å&eôÍáÆX,–ÏçÁ•¹±Z®š3™›·Ò£ÝÞt¡už�­Z=Úí««wcu9u~Å£Õ†—ìR¿R­<7–¶Y©*÷Z[S9m­ë0#ÃdÚÖrBÄbó¹Ð.è­kL7.`§1ŽFލpmvN³.­õ3¼‡±Y»($ÌeòUª; ¯C ¹\!»ÆKcßcæ&"BR(7μM¢ &mEÕuc'@×4ÏÌ5WÛÀªYorO:¸œÖ,Ûm{b±“É¢(_—N³ˆ¢õ‰Ä¢Fq@G21ÖhÁZÀ®å~%>Që£Cs:6A™Eµ~m1 D‡ô<¨N¹±ê žDB¥=¬“‰ø!ÚÍb\t˜`ÅV3j¡(0?»eªCꉕ´K·~ýú¹sç e³Ù(Š’ªKBXPõ¿:ãÍ]ì•ÖÈœOÞZ¾Ê Êë€Æ_g¡ø‡`ü”r‚æœÞ£.¶aìNí‘h”ø@9è<õn ãèw¡íi{óø- )ß -@åûÂM"�H�ÁCÆeêf£Ui.ÄPàÞ^§·{=¶­H«ë¢¡È_ém³¢Ú75gV&IÒ¢‚jÛ�`SðTæS²É掔Çñz^iñ<á {_íííFÞ.§•þÆU¾½ýÇcÀÇÉ$\±X,Ñp0´"5Ý�J* ©ÌÓ `=­uJ^È(‘?éØñ&ÅL3ÉàÜ’w%Þ Žj2Ò¯b Òþ¬,‹L­þ€-Fû¼,•"Z5T»i»c‡U²_wS*uÙèè_ d³Yƒ]|¸V_­>Ý çKÊår[[JÏpejÍJ;Ú3çÄÚ"9LРxÓîîn^´-REá=j'ŸÂŽ1YÓ€}>o—jóÃC¯xƒVÚGQk…[än¯Œ=FÍ<.™1uBVüˆ Põµ‘C×'N²¡ J-Bz©ªËéݦ6fpH`G½ƒ£²F´@<…Ð@ZÙãoµrU¯× …‚â8Jã©Pk6¯ïNƒ²"ÿ¨ÉCýÎþä„Úfã,sŠh¿š‘ñU‚Ëi傚"‘H‹EE 1€Äz'6è`VM-L'GE%/™ç"ð¿ïTÚB÷:ìªC"žQä徘¸& VÔ3?Šá¨´ÌSÚǨQ8·¤ý}k<¸†²ƒ7¡±?OàÍ’ÑÑMñøñõú‡‡oîêªT*‰jõÖJåÁ¶¶]ÆS ªÕfÄéÇ0Ùç ‘xa> fZ{GŠÔ»Û'­Å�©Åž:‹—Y:¡°BP:ÎçóÀ·4|ñkœÊ(aÏÁÎõV«.ŠÚÚÛãñ¸k òìM½.ÕKD¬Rj@p{2¡rsÕWežIT\ ªfþ …‚–mqØ* n«³³“Ñoø—¤DI(h@C Feú’>LãF#“³6ܯÊ4¨m6ª—AvbÉ#€&4>𦿽‹‹7¡§Ãž­9\\=“ò.Bl¡üÜKp9-FHÛ»TcJPŒ%3=çQ4ê"ÜPbWrŠÂˆJ†hèD•–âl€×uR”ƒQ†Qs-ˆC*¥ø¢<üi»Ý;‡\é�\:Ñä0ŸݯæXZú·çãñ¾èhºLì·TªÕ;÷H2yT­¶hÏç\Ù¹9.;¢ÑLÖ Ãý£—='”ÉÊ…Ãàôª£ —iÇHç0Òé´Í?âöthKa®×|¹½šØÚÀ³”N§Õñ¨žô·GG‰¢]±Ø”‘‘Ój5+ÏÇsŸ-•¦tw{½YªGç@c*›‹Rd D J7*E€€±Ô«�ëø‘½Dr&Ũ(\s°ÂÈ“4VqRQjë½ÓAsÂYzx¼) ’ÀFxˆë@$aTæŸ49v2㌛$ åöA+è 2Û-x½a•]G}ŠâuEꮚI‡^NëAÒ¤8jõ4óÅÖ»&e¥Ž6•'¯â„:½FLì ü4c (Ëxtg^”§5=åVÁvpwZQ®®®.zT\nŽ&äDñ—Ú\å®9Ú=²[fÞÓÓwšLõ¯V«-I&“õzO½>¯£#•J¥R© ÅbµZ}°½}(•*‹ö…ö@Î*•þSµêTÔ‚»(ªÕë×vt„Ï sö@ þ¤øƒR8CÑYðSGíéé™1cFggç’%KÔ?iä¡ñ,ߣh.EHƒÀÆã?âñx¬R¹±½ýÂJeg:ýtOOEÅlöÑÑ“Éi• àoÆ'õåYÔnEÊ€ÄSf&e¢dÊ’o�O =„‚Â)â©ú ×@£BgÄRÀ¦›å®UeŽ“kÎÀ$� òpcÉÍ<°²RzXs qTƒiªî§H¤Ç‘£dÏÔ6”~OLišÇ¢ÍzÄ4m¦×Ó.ôrZ¹¨¨PWLm©T2B-ðRU+Þ²ŠÃ+PÄœ¦ä‚ÛK§Ó•J…ꇥ¨Òq9¯Ü¬rHÖ"b7 YÞ°¡U”á Ì›“ùMeÅ ë´6ÖÍD‚É*ø�| „³ë|-MÈÉD¢#™,µµU­¥ß˜Q0@E'W«ÛãñÅÉäÇ«Õk çÜîXì¿tuÅâñk …t,VÈ !GïÕ4t …'¦âF@®{zzN9å”d2¹fÍv”Ö‘¼˜±Yb^—Ôé\UÎrÍTΫ×/=ôЮ|$‹­Yºôâ­[OrÎ0î:j3fóC†6€*±ÂÉôÃ.ü5 2fj­v;ª±‹Â¬ ò&ÛCë Ôpv¨g*›îXM>ëð‘)*½RCQÖãN›]އo¦‰Yç•4Q|áTB Âv´u†» ziog¬B× ²ç‚ù·öä›9΃Ëy¿áÐ0ÊŒéšy¢Õ¡}B"\0Ê“¨e1÷5ö¡â„-¦³ªMo¦%Ø…Æ7…Q°ólY6'Ç 1/eMï¨DyÊ.f=?vÝÝÝ–Ï¡Ô œOÕ ½~€=g'\aNTª¸0(¹YdO-KÍ;}Àÿ«Qtk>ÿD"q@oo"W©<Z(ÜßÙ9Ôø¼Ö²¹SMdí932B™HÇWí~9ŒŽŽf³Ùx oÛ¶Í Ÿº¦ˆ/Ëí±3¬õIì¯þmZëJeþÈȧO=õ/ºèüóϯ×ëwß}÷óæý·þþ•Ë83²£ cv KÛo &áS‡,7Y¹ÑÑQ£Î¯AÅ›“å 0íO‘Gs#üª½½ÝˆÇ»avÆS”V�sì¹jT‚”›Ãc¾P1¶«)ýðBµÇ£ê…&&K…ú™xƒ âv•™ ò�Ê·A¢ARïz yµbæš!”j¡ up9cªðNÈÖT`Ü^{”ç\»#„ª�eöŠe©³ž!•tì‚Êâê` Ñ6€�eÔP`´íQ;®ª)@1D¥¼@ñZçÒÍ0�¡­]»SôP[Ê‘cÏÜèÓÞ¯ý^€ñ4à5Ïw–s'“ÛÖ–ŒÅ¢x|{<þÿwu]P­Nj„·ZìÒ™å8Qô*ñíh{ÈʯjÎ```ÀnÜBL'Ì3¯fï@U°ÌRk‰™|À)o×îë?þˆ#Ž7n\"‘8âˆ#:»ºì˜Ê&I‹Â—YF·c{•g¢I0ßCUæY3ëèd¼Ñ¥×4KÊ£îèè0ÏG?\;䦜å}ð´_+H‘‰æ$mUZÐ1OàìÞìrÚê 5gP!$Ê­iƒª#ݸ3áT1¬ ¡€ò àÃ<±;7–V*ÀZÜËѳ§ ãÆ ªÔ±Ô;¬=À®Rlº+þ«¨P% Ö1Òl´²ñãÇ÷ôôd³Ù¡¡!¯Â‹ÏS4òñL�� �IDATs ‹0ú� UŠ‘.«v_8B®AI‰Uõø©gºW ™WhöŒµ¢Åqââ1do:êôµÑÑ“z{»;;:ê¨X,¶nݺÊå êõi*¥Âßæ\¹k¥¢!•ÄÙ(ò[%‘8ðġİcjΤ<ódªo­ð0ÚKö"6oÞ¼xñb+£=õÔSÛ¶m«Œm4⪕ÅCµ°¼ÌF;nìŒ*´ÙZ‡$q ‚3Ç W±ÿ8qbEØz«âê•k£Eå½UÂÉl,1K‹© ‘^ ¬©zö¤"(µñÖŒ¿Gí†ÆUÄpž¯ÕΫ§&®ƒd¢€2¸�‹8•lÀÔŽÓ <å>o–.¸œÖ¸ê�j(5–aéh±¥Û¶ÿl^D ¬Ê/b¡Šq9«!vÂ& ‘ŽeÇTWÜXÖ?6è„ >øàb±È„3”hÔ¯U-ÊÒ½S%uB{Ì7`’”˜Ž‚JzhðN}L‡U[©øu$ž¨ œR¶tº±¼ôJxjuÐAwÞywÝu×–-[°§n¬ê¥¾k 1•L'³{Ê.£l@YØGtºp–̨“Ý"™ª%Yâ\Ka-,�ÈK¡•Z<û˶¶¿Û²åª_ýêÕW_-—˯½öÚÙÙìZç^—éW…5£½¦J‘š"0H˜N§sÃÃÃÅb‘æŠÅïž>“]6•"'Šéãà-å2òSÀ÷ÿ” Ì‹bg ¯oåÆkš™’a¢ ªäª¤JáAë^‘àÓìxjCŽ5«ªé�e.@öZuˆ•—[,•Õ†¨Ý)Ý`4x%×i–ÑÚ«Xmp9ï÷RÈ?ašÆzn,³µcõFö‚-GÖ©FB°ß6÷ËTѶ”›yéØ'‰mÛ¶YÛÀÃJ*'®í]TR0aös%©T ƒÎ”h¥Ñn“Év|Pegð²7åÿY«º“ÌZRëSzûíÚ†ž]ç`‰Ä¦xüˆZmõ®]=öXEÙlvB2«Õ†í…6À{JÇX«§”E€JŒÔÖ`× €±Gк<Æ¿­SÒ<ûBŸL¥R‡rÈ®]»€\{œ7±XÌÅb¯'_-—/ݸñ—{öÄGGÏ.•.½1™q.ŸÏÛ�V( Z^îÁÆ�2L:õÀ\´hQ.—+—˶ÿi˜1ÝÇ¥coÀÈ5 ¿|>o”CCCü:,‡ÑU e—*}n[¹G‰äŠÅ¢Õ mÛÓ íìì$ïq"Gä•7x5«]C7Z—ÇxUµZ- ÆâŠ#÷dp JT£Ži_SÏô- Pð§ Ëf8Öö‰DÇú+¶Q¼Æ†7v£jKôœÁ bÈà¿Ñ" ‘‘ö{ô jG'0<™BûWÅbˆ ÷bÖÁ¾|\ )àƒY`’›¢Á@á=Dmüè@†2†yìmèéÒ)õÈÿ•|Z&íqñÄ€ø<Êðo::~X.ÿm.÷Ä«¯FQÔES,ÄbK̤ŽrÇ£› ±fþÛS¨ 5 ˆp,å1.š³2ü0—¥:@öTXÑ(Õ¢ï\.‡.Õy¢8Š¢?rî%“§•ËlÝêœ{+ÿ~*5¾^?@Ê›¤€&ÉÛ]ö‚6lذeË‹»µ°æõB@‹Ž+ ‘œÌΗsÎØWµÚ ´£AP¯c.àļ�•‰cãiÇ^]‹Á)LFë«OÁ žü‘¢§yÁÁ€èײ¹>y8ˆWØ$*¢s„pCpa�¬qc¿1¸œd9: àl€›´ž° Œ—J%â/ùjÆK’hîOÑŸP"×Qgmi¸&…4å¥6ûB Ôãïrc%ÝX.8-d[üHW_C*si^/Ú“iáðp HfÓA¬Âè¾ÇO­bM2?íšzhŽX,öÃTê„Jå?•J±X¬‹½šL>¼q2U‡Ñ‰”™år‚@nÏÓj˜"qÍI+¦¶y²kBýOÏ›‚³Ëk±÷¸Óyíí'ÔjÉZí¹Têy¨øëõD<þNL˜¶jôU*ÕŠÊÆ¸Kkh:‹Æ¢.-¬Ìžn:Ï*+¾Í6¼Eè®IM/0˜m0B+õLªÄ¡~TGì(Zšëá‡u4æê(+^Pçj@¯5g}ªrbÙ ¡�í-!*€ˆ·O[”¢«~‡ý`…Zëu‚Ëy'wÖà(-b¨Lr3o„'÷©#Ð:˜éÑÒàE”qDa'Š=CQûÏ@9!í÷Äç5Åñä°˜ÁVý�É xí«€¼¶yT‘A97–ËØG(L+U½;*VÑò€F(WÒ×üïêbq(뉢£Í]9÷R"ñçŽnx&TD“é{t2Á9±’z¹±ü˜šÒ3s"¨eìvªÞ {&ß»¨êÌÚ7[!Ôl:=$»ëåmm+S)X�Ø-o?ðFŸƒHW­-zŠ«¸=ÔÆ<ý |kÙÙ•ã#ö¢áÇØ¬ê­YQb-Ûóô’B‚}L°†öè={-Oj¶`)êö _Õl”é‡J2›ÄþÖ‚'ÊY ¡9J¥D›IÐ&y›@]æ~ ýÈñÔ©X­¢� #¢G׫ó=Áå´xx‚àç„odA#fÔa@_@yÙ¿EVVó_Ã×Ó)[©r‡°:êh´jÕà™Ì”àoº1gV|ijÔn¿†G¯iIy¥ˆòö*ŸN±™µP8*c^Aƒx¯5:´ß+J‡J·=ÆÛÛoh�vñœ@³t§ì›•4Z›LJ¼Fu¥³û„jY_Iòiê n=?È *e‘Õ÷è·ÙÍÒMTj%[=’fhÄìÆ(Œ[(˜Øð”í)K3jüœb€RŸá_Áª1«Ò”ûìwÑb¤K¯Ð¦Ööa¡P�*­û\ Œ³X øŸŽ.Ø“L§Ó©TʾS¹alÏöQr AÁ¨ç¶PmZGÑ^)vÆ£­ãÏZ<·<›k2jž‰(“R›ùoHC4Q.§Åˆ56'Y“m3²Y©~謈5bÏf53=ä5 fP<,µîN†u˜°Þƒ×Â…íØÃ€éÐ2»–hh�R`Ê<¨ªö·f¡ÈöˆdÍ|0ùAa‡–v\£i5úÚMÁ?éüо5-JPÆÑ©{sAµÂˆâu�^³@¥x0ºLåcoX‹È®„™,ˆE�2+£«ª½iV¤¸“V¹eå¥U6<Å"®ÙîÂCrÛ”‰"Õwªä nÞ¢ry…Л@[³'*jJh‹ƒT==Jgvk¨ó¸<h:Ò´×ŽŽ²ˆB 2Kt ª$%xk }z 5‡P¾m]j¶7–Ý@‹Šcé 0aàOºedTê¹m“«J–‚V‚ËiåRÊgÛt4Xæó¶é!.TÄm2™,•JŠS² ·"qÙf|aQ{ªPfOšI©Æ´f­èL¶x[[›õ¢à„§Ñ¤Š”K+®IyÌSB ¼º0-jÒ£œ.š¯èvƒÕÖ¸±ÚwžÀa YR+Üé<Š�Þ3Ktï5Æx8cºGµŽ†x˜l:̵Z s¯}O‹àcç‘ßã‚ѧü¢_¥,<=OGÜzÕକ¨„7;f0òHÛ„Äa†¥TÔ¾7zÌ´ L<7hµP3]R ;>£££ž×äv´<e^ ã®zfiÕ¹j…¼¯¯ïØcݱcÇ–-[¸fM%Ôàd*Ü¥4Ô ßo¯4lmìD3…Yöaœj»` [èx‚Ëy'&"z‚BÆ ñ1, íäïÍs|yLsA\ÅÕ•«ƒÍg<ªÍ¬ãiªHO”MdµAºäãy]cž^1 x#;'Úà²!ë-•J$1JWåDÅË, 0®‡éF…‰@¦‚÷²<`–ˆa |¥'þlãu tiÝAÖbfz=°|¤bHþxÉ0hŠ<ííí©T*›Í’Úº†Æ³ò»�j€JÜ6�ïÚ‰^‹Ö3 ]Ò?§ž©3O&£B«”ÔÁìipw.˜]¦ë@ï{GCÁÐÞ¯Bu°÷{$5^X<tÀw ) } vŠÉtiªÝ~‡X/‹7Ò…(K&.³C^•I2í³BqÆIŸ2eÊ…^¸bÅŠÝ»wÛáU™ÒtD!ét\ˆ ½ ¯äöd,`²¾ò2xtpšñkA5Œ‚¶¾°¦up-Ñ¥0ŽBOÙ°“2Lë 0…~‚h«€Q¼îB†áϰï:ͧ Lo’€l{G;°Y*•Ò‚A“‡£ýcVF«1mmmétÚêÔPª˜íãßZõÜ>£ºT„:::”V@ .ù½<U 3Í¿B"ç‰zQî÷è à˜òx-#aUêe>Uð‚¬ìôzDm^ØË“?~ü¬Y³¦L™²|ùògŸ}vxxXÈa(_)#F[Q'‚¤ÖÛPÅ3-+™k÷fÔ½A}ý‡ö´Uì66íTi·Ïn¶PC¯Ë J ’@OKM^tŒ0Äö�ÜÛ”ð!(=A6YÁ™ ãõ¡¡7‰(ŠŽ¯×»£È9·9ˆÅ:£he"ñ_;;5¹ÑŠ·Ñ=ؓ߰aÃÏþó|>o8HŒ4U"SÁ¯·W…9Ò†Ù0ÅÔA̪pO/.¸œÖ,ã�6±,Ûª ^Ou\ǹ5v£íáÆÒ?ël—jªŒ !ž¶vȇ”‚ž¢™Z_ÛÜ»× .Ô½™~OáÔ›öW‰تHFìÏD¤vŽƯN\“Ra†K¶Dˆ‘Bü Öar•‡`~¸§T L2*¿§Ê’ ¬£Wúä5™P³Ýãĉ?ýéOuÔQmmmo¼ñ.Ùž­‘©p›žßRq35µÚ®¨fÉŠô(›ÒÑêÓ¦÷ÃD³õ5­ß¦£©l-¢zÍ{;*©‰œÇÓA’¬‘r‚Ùïe�@{l˜]Ò\¯šÊ¼³=jŽ«úI¼²þDâ/ººÎ(•Žt.휋ÅvÄb{œ{¦V»¤ lMÇKÍBECCC###ÚƒÔüLûO<6’Åd:Û bÛ*¬`ŽÄ"$†‹Ù~Þ|•ê‰PÌ÷$‹‚ËiÍ2NÜB¡@Äm‚ŽûjƒÈìGBLT«ÕL†€h åtRsѸI ¬_ÀÌCP1c#긣¹%�$C÷EÛê–ìH�ŽÂ‹X‰ÜÈQJ¥�§Bm¥çPÒ&3Çx˜+ë@-ÛŠ ÚÞ×3L”ç…Zî�g¨ ::Á,¡£•³�ó · ‹Ù•T*•ÁÁÁ5kÖìÞ½{Íš5…B¡Y¶‹b”í:ˤñs´å¯ª0Ô¬<L‡–›®Ž&MOTÉÞ²â/œÌØ{KSFí™ó¬›¢;ȯ&.€‰¥44Ñ/ÈÃm{]Méf©]öÃU*Ÿ¨×ÿ{gç`2Y«ÕN­T~Z,.I¥œèqha ¡q~ƧÁOpr–ÏÙé°"‡rüàÔöT •Tù¥*bë);à„t°ƒóÛ˜P‚ËyŸV¹\Îf³Úç÷8!@+¬7®-Míp‚{ÑqQò¼—7íÁ—SÇEy#^'ߣ¸ðú\?¦_w§Kí*k^ÏÍR‡1§ˆ[Õ¸Û\Ž•³ z3æ7 Biqä´’ƒº»kp´÷8aKSýGUO0©aõ ËíPA6+`A±¢ï:;; bŽœœ@'à­ª5–ÂL¢lß¾ý‘GI$;vìÈårªì¢Ð jMúxXÁ½0ÙCî¥yÖÍÆ±™•BÉÄq 2Y{ø†á¦Ôi·‘8ÃfIC®™n?A½'¬nïË’6}æxv»µ[®$cͰOÀ€UâÔ#ëõõú_÷ô”ÒéñííÃÃÃ˪ÕÿÜÕu¡ðl#÷µÒœ e)S;‡Åq Be" ¥ò~¦‹ì°(r]Ÿ•bv[P£ó^ 7¾áY€å´rU*£yghÐíd¨X©(i<®}_ý¡ý]æÌ½md¯v”—“\ÇŒ¦ÙeB0¶¸’s`ìk™:4Oð¶òJ£Yå„QyAÔ¹j˜¦°O-‹ Ø*¤éí2š1W ¡oQQT/G$Æ´â%GfÚUÍ7 ,Ѹ|�¯öÛí©ÂÉV¡v¤T"Ä¿„ö*_´nÝºŽŽ|¬{¬³×ã%âámbãØœ¨dz#~L§ê¥®¨=³¿tûìçÉdÒRXCºëð/R Å,Îì=µ>;(Ð`1ŽXX˜¨YË„—EOGÝ6¿kp2zç¿×,!áVIÀ”séz}´·÷ÿùìg»ºº~øá­[·®«×§ÔëKÃLªýßøO †ì»»»iN:µV«õ÷÷[Ž«|zÚ�V‰wp¦¶IÃÏrP¾„ÚµJj‘‘“'yŠÁå´`Ñ“'îãœ+‰§<󀆤2Þ˜‚£=Z_ˆ³ì4Ò#Õ<%H9Scm…â(Ð o´Â|˜µ@ˆy…{Õ<5¸¿¬ª£8f­`¤´/UJ:pSµPÅþ*}ªj)œÖjtV‰Z]h*föÏ¡¿Ô”®\.W*•‘‘zò8íÒQ�ÑÉv3 *ÆcßÉW>›•y¶Æ›Dƒ'ìJ ±zã5Ô�mú$•JÁ߃òÚöxAg¹š §‚NTsÉûu¢:ÓÌí Qõ øuˆÔ±]UÙ“wGÁ¨Šv7©4Ú6ö8­ LßÏÞøÛ€ Få|çÎCCCÅb‘_äF Ïá‡Æ%(Å¢]pGGÇ!‡ZÇ §Ú¦¥Ï¯ã8J)|¸æY•×~oH‹î¬ÝÄäA¢m_YDÚÃW:tˆ‡µOÐL ¤b„½Z"Óš> [&ìW(+¾Ó´ g!'&ɉîµvqµèÜ</­a¸WÍãHƒ¬³§Áµ© ¦_qÉö_0lÖÒ¢¢ µi³§‚?VÚ!«ù0g§¯’f˜V/õ-xòD¾Ÿ?ù«VGu¤”A…x¡Y‡_Ô‰qUÓ±,“°@úÔ)"@Ks4¨Õ¹²‹ BÆ&ÓBÔ3©v²½Õ*ñú´U‡VºðÓºÃ=¡[³)ޚܧ¥¨ÙRßÓ.àmAVdmüÙ•¦PøEOãø£(Ú‹½‹e/^‹ÅFFFâñø¯Tþ¡­íÈFKF³XÆtVZ¸=ÛTÅbqùòå@ðõpytïÄÞ6Ãÿ©�„ªytÞ ¼blù~O¤7ãnÙÍ[Õ·â’böéïÑÆ7 çPµdìB‘©‰ˆ6·kïÊ–RY{m)‘Ei±›z íÍÒW ÉãŽt×*Ù þÉÌV©Tâ”ÀÔ<„ÍŸ¢ÇEíNC?í0a¾uˆ�QÚß"¦f´Å+úÛ¿bÑ«eY,lÍ'²ÑóiÕHZÇè^"†Ñ«P³NÚCGoYSC> Pr¦#-¨§  ¨H›ïñ˜O±Â†¶nûÓ{›]]]ÖÊ[ ÖàÜhÚáÐ)}äM)I1fH$=ôЃ:ȉ.Ö°|ö)µá€5x‚˜Ž1{œDD¹Ô! Çb[b±› …ã²ÙÊÐP[µzÙèè_T« ðÆõS¿% Á ª<E£{7Å>¸@†Ýˆfö€\ŽXƒ^˜6üx_U‹ðÈ5µÓ²œ–!Ö¨Jc hÆP½Åð¶ð+zàíh Ñ–¾ÚA ÉÄQróD;P£Rz%iVnD7–š¥Y~Ô¶lGG8”Ú4éÑ»ðœ4½ íucužÕÑÑadø:½·n€¶Š: …°+M¤+p¢€.íº3'Ï l‹Å XÜœFŽ>RUWÄ…hã7§Óé¶¶¶b±H%ÍJE===0éü–:ÆY<™T˜}tïKš'–Ø-µZ­T*±! œu[ReUi/…U‰…‡ABÊk%+U1ÙÑÑQ“"Ól‰î5 I˜ÌRÃØ¦äÿHšÐÁcže¼ãžvnG[Û%ñø­Åâ‰õºsîÖ¶¶ÿ7•:at46V©ÚâE{æÊý{: ®¦54ù-Hµ 3†=âZ’N¯Ð¢¢«$Ä4o˜ÀeBVÙÁ]Â[èBa­õ‰Î˜ì¯A%©_ÚžR¥h]êûªâDÒC'Nì{ìHpÈ™&QT+;ÉjØPo;jK@UŸ ÁœÈ 2úJÚŽEV",ât\]t½0Mµ—®?ÍÚ…°f霹=úÏJ#/ú4à°õ‰iV§ŽÌÙØQ·ÂŽF�j£XÛgèOÄEjÓ†°?pÀV‚WÞF…¨µb;ÁX…„Î$yRZ<$뀫 °öCrGµÈJY­¤®uÑwhW~q%@Óé(r22]JyPÌ™w$n Ô Œ¢™S@ºÃp«ê’¦+hS¡zä‚@æM&ÿht4rî×Éä¯ÅŸÿì\EO‹V%Sí~QÁ£¢:F›©ÚáÓ:0`%6<ÔJ¼}r¦=K6³½Gµ?t j8kqó"8×ÀU8wý$ݬ³:"@Àˆ{ÐB*ö·R©Xì¿ë`‡¶¶¶iÓ¦e³ÙM›6AQŒ àŒabà °mÊp §ÅN):Ú%Òã÷Jgj�¤µ{á³(èœVÅÚkp “€®¡Æ•�Ø ý‘¦Ò^)A¯òS¥—ד³‡ UGíœs###…BÁa<®Nê(üL¹d¨i¾¢Ð&ƳtúRmkkk7nœeZx mIòäùug¥+F [¢9åuce`T^ÍýfÈyÐCmÑ2Q¶1-=iÄc‡%8#ð DtÜ8Š¢«;;50òRIoöFv†µ èÆkò8û¤Èš…sý JR„´j‘hPH[ ìM5¨X Sœàrœ—Ùh½Û¦|µ|ŸJ¥,/VN{MDf­(oˆÇ5&¨ úšEwدª@jçÁ´èUøk¢æO'ù]]]vÁv;؈‰øÝ¨Û¬4¤a£ÞÕ¢fªÆ¦ÔÀvgöBM˜ÂаêÒ¦fÏŠb´‚©�J$A¼±>°ª`¾jL­!äd2Y,=MXU¢„Ô’L"Š¢‘‘r)¥ƒIS‘ôØV|ŒÒªj2A¥h‰Ý&–”Ù97~üøÉ“'¿õÖ[ÃÃÃàôè"˜iöú: ®*£¶çNØà,l{hÀ¡ôÞž¾‹Îo*y9 ®Ò„Ÿyܵ˜…ËÃ(…¹ˆÐ#�jï¢ûÓsl¼A6žPAÒƒT€²NÎ)€^•d•ß„ÄNïÜ#eL�ëv^– òíñÚ2 2r—ÓÊ¥eCO6Ë$[1”¼^ ~›È«v€¬¤ ÐF:‡Æg¬nIG.ˆVjµÚ›o¾ÉÐ¥Z~œ“j½pÎ-­Éf³¸iÍÐ~£¥˜ ¢ ¡JPn,Ý=‘º×ªƒ¢l%”Å$ ¾KaÐT!hStRÒRDƒôÁZ§—àQûÛ ­6Å#Å,Ø—¤Óic£P”^ÊžŒýCmùêpÚn�¨œPSÃÆ¯øF-9š‡h.Î8Q!¯¡5ÕjµšÍf …‚ùP 5:Õ!¦÷c7«Jh NSì»ÒUh�a{¸\.kpƒ¡„:O‘fýJJF¶ @¦©è_³öSVxPò\y¹\¶màÆR÷ªORÝ)O¸8»Gä¡/¸jèÂjÜi»šÞ¾ÖT¼ã©•O¼¸5qMH‡¢x&¦FO@©r”Áå´l.Ç‹¿´¿í1!êˆGÝáM¹ëü#%i/k¦ îýCí•óFûAÉ”u_u}”* ž1ªO:Ó@…¬“Ñ6‚8Â:*ÞÀÎ<{úÍ’šÞ å/õͨB8çµ{ÄÍš°PWPŒ”ª•fÑG]­Vs¹œ7QD’‡ÿ67¬t¥ZÝÒ˜Ú^‡Ò¸™ìíííëëÔ23êLûkIGlÎ:S¥] í=0¥ëÉF(Ás3 †Và›uóëNÖP†ŸPŠ´­kC£ÔÞ¦*w(Ä_ežIjÁõhqB¡ ÷°èÄvé”wæÏŒ©! [3@P&[AîQÇÓTæãáè-¨B•Š)¨fâJ05vÙ†¥N®À"å8Ph¥êw—Ó2ì�V†Zf˜iê*H+­Ê_K+³Kg£=îPÙPÀ%Õ(lG2.ֈà#x ª!V%WŒƒZ^¾Ç#øñF”ˆÂ¼2‚?cVף♠û·Íd$T~Ô à¿-¤–¢¡Õ?€¨q2hÏF�ð¯NÔ²­rB{Iù€™R¶å‰P‡ÍЃöZK¥Rww·sðÕ9æe¸±DmJkf¨7–(«a;íkʼn�öÕÜ»`Ã{Ø}íÓÐæT•q½Y Å@k|Ö Ð Ã#û'Rü‹Æ"ÔŸuâûµ¦ª\dϱþŠDUר¤vŠ\°KíêêJ§Ó###Àm¼CÍ«Ôò—‚õUÀ^Ï‘J b‘P?Ò†.mEýþ2{—ó΃`ëò^…`:®ŠPòyû*ÀN¼x­D©¾! öº25iL6à5Øúö;'¾V15  ¥ó20ðÒ#*Ì4 a—Þ>ÝQí~3¯jþ@¼™­^Ù—V&=‚=ÿ`ج£Y Â®˜=ÔŒDcv žÂ< =”ﵿ¢¾ÇþÊn›È(PŽR©´yófP‹ÊÐj‰-/¦ö<®¹ ­R‰R N„ËÞÆðdÊå2‘–B`ê¦àcŒ¥FJ,„n9��øIDATéÏ9gcXÚ¢¶Ã>Ñáh,ÆvóH=@ Ñ¡µ$½ììÇ<“5½ìh“•ÓJ°…úžÅˆ£¸Hó% P>úè£Ï<óÌ lܸ‘Ë6!\Gå4âÁì —ÀžÔ¶êJæl™%?³ÁÅkq"¸œƒÖ´\£$ùͯÇSKÓ ¾¦)q!;LË_9"wêÚTl•E‘öƒÇªY—ÆAÈjq”Qg›µ ¨<i\ ÞÊßÃñ¤H5]ƒ5@§"hù`a!yCŸÍl(Z[øo•oð Ë8xãèdª†˜ŸÊ)õ(¬=«£µz›tïiT@©¢®ÍA€õ Ì,$oP+ÃÀ 6Åž†ÇŸD˜¬(/õâN¤t`YµoÓR"¬¸Fe••k¯GÆ*fp&éýLÚ4T+¼#ëÙEjMئÇx³èÄC]£07–ìŽÆã†PŒ7ÖÃÍ2=ƒST±go��`½‚Úûûûÿýßÿ}Ïž= êQBwÀ3g“`%8ƒªJ®à¶ÕU¸AÑLúâ‚ËiÙ:úè£çÌ™ãÆÊšiÂë(he™²†n>Rå<÷znìðšfåÚ’i8à l£Xm5£ÚõÕfl3lLù¬ÔÎw+‰ªÎ¨î²§ÔéIè¹åY©^²‡OõÈ­½úžŽ‘뛢s N="`'…¥*¯¶žjå&jV¼J'бÐP�µM~¢õL¼’%Ãr¤z”ŠPW¯¯â4Ö�J%%ó¶ºFž +¥‹UÖ%MØü+e¿…€N§¬´‡Š£õ¦˜›ž7“«='êVJÒñd¦÷«DJÚ‘õF’)îéh‹>+'¢º^V×<GÁaÑ?+ÀÄ“¯ÕI> ÍDê#îÕ3= ÄX,6~üøàrZ¶N8á„«®º*<‡°Â +¬÷t޵°Â +¬°Þ÷,'Š¢Ç{,<‘°Â +¬°ÞÅ5kÖ¬½¸œZ­ö™Ï|F?ç‰ÁüGþêÝýØ>r¿ãcïç£Ø.ã]y;ûÇùÝ×°/\Æûö:Þë ¬JKŽó»øýçœsÎ^\Î^¿Â›¾þÿuM£aïî?|¯¿?\ØÿÍ÷ï³æÆ4ì›öp¸°ýûÂÆÐ…¤/¬°Â +¬÷g—VXa…Vp9a…VXa—VXa…VXÁå„VXa…\NXa…VXÁå„GVXa…Vp9a…VXa—VXa…VXÁå„VXa…\NXa…VXÁå„VXa…Vp9a…VXa—VXa…VXÿÇkïâÈ#Ö­éîLÙµN¼Äõ—÷e'¸?`-“÷â¼§*>á´äüßX櫯¾z/.'‘H,X° %~ïÉ'ŸÌårüǼ¸ño}ë[·ÜrËþq/«W¯^µjÕÅ_¼ßYûÓÛ g_^÷ßÿ!‡ræ™g†·£(©?=ï¼óZr3…B!›Í¶ê·¿ëëøãßo»;Š¢ýævö³·ξ¼6nÜxØa‡…·ãœ«Õjï8šL&³xñâB¡ðÈ#\tÑE.¬°Â +¬°Þ½U«Õr¹Ü‚ ¾ýíoø@Xa…VXïÓ .'¬°Â +¬àr +¬°ÂÚ¿Vò}ûM###«W¯>ýôÓs¹\nþüùιY³ftÐAιçž{níÚµãÆûìg?kŸ¿ï¾û¢(Êd2S§NݧÙÐÐУ>êœ;÷Üs'L˜àœ[¹råúõëûúú¬½EÑ}÷Ý眛1cÆ”)Sœsk×®}î¹ç’Éä¾ð…}p<úè£CCCÇ{ì)§œâœxê©§œs\pAOOsnñâÅýýý|ðÌ™3s¥R顇rÎy晇zè¾s#=öÎæ‹|ñÅ_~ùåt:}á…Úg~ñ‹_ŒŽŽ~ô£=ᄜs›6mZ²d‰sî _øB2™lí½lÙ²exxxÚ´iö¿/¼ð«¯¾ÚÓÓsÁØO|ðÁjµzÊ)§{ì±Î¹7.[¶Ì9÷§ú§zì±Ç§NšÉdöµ·ckåÊ•GuT__Ÿsnùòå6l˜0a¹çžëœ«Õj<ð€sî´ÓN;òÈ#s¯½öÚêÕ«ÛÚÚ>ÿùÏ·ü^Ö­[—L&ít;ç–.]úæ›otÐA³fÍrÎU*•¹sç:çN?ýôÃ;Ì9÷Ê+¯¬Y³¦££xá¼yóŠÅâ‡?üáO<±å·3::úì³ÏÚévÎmݺõ7¿ùsîsŸû\gg§sî׿þõ¶mÛ&Ož|Æg˜1øá‡sçœsÎĉsÏ?ÿü믿ÞÛÛ{þùçÿîß•H÷M:ìôÿò†ùM?õä÷î®.¿üò'žxböìÙιø‡(—˹\náÂ…gžyæêÕ«çÏŸ_*•¶nÝúÖ[otÒI·ÜrËàà`.—[¾|ù1ÇÓÛÛ»ïØµë®»®R©är¹'Ÿ|òœsÎY¾|ù‚ J¥Ò[o½µcÇŽiÓ¦Ý|óÍÃÃù\nÉ’%Ó¦MÛµk×ÏþóÑÑÑl6û /LŸ>}Ÿò7÷Ýwßk¯½622òòË/wwwpÀ×_}µZÍårO?ýôÌ™3.\¸hÑ¢b±øæ›oæóùcŽ9æ†n( ¹\nÑ¢E™L&•Jµü..\øOÿôO7Þxãœ9sì'ÞE®_¿~îܹåryçÎëׯ?ùä“ï¸ãŽmÛ¶åóùçž{nòäÉõzý¶Ûn³7»téÒO~ò“-¼«®ºê®»îÊår±}á…zè¡r¹¼}ûöM›6}ä#¹í¶ÛvîÜ™ËåV®\9eÊ”R©ô“ŸüÄ.~Ù²eŸøÄ'æÎûòË/ŒŒ¼úê«“'OnáíÌ›7ï§?ýéO~ò“o~ó›üpÙ²e_ÿú×Ï<óÌI“&-Y²äñÇ/•Jýýý»ví:á„þñÿ1—ËÙ!:餓vìØñÏÿüÏ£££ƒƒƒ/½ôR h½^¿üòËï¼óÎqãÆ|òÉιE‹-\¸°X,nÞ¼9›ÍwÜq7ÝtS>ŸÏårÏ<óÌÉ'ŸÜßßÿ¯ÿú¯åry÷îݯ½öÚ)§œr÷ÝwoÞ¼9ŸÏ?ÿüó'N<ðÀ[øvî¹çž»îºkÞ¼yögæœËçó?üáÍ,Z´è¬³ÎZ°`Á²eË …Âo¼Q©TŽ:ê¨ë¯¿¾T*™‰8ýôÓ_|ñŇ~¸T*mß¾½¿¿ÿÃþ°÷+²#•‡Vn{ò±GŸ_¶È|læ;ÿ^žóÐÐ ·Ý½gë²Ë.»óÎ;gÏžmÿ›ÉdìgŸ}v>Ÿ¿çž{n¾ùæ(Š^|ñů~õ«Q͘1£R©DQôo|cÅŠѾ´¸øU«VÕëõ;î¸ãÇ?þqE+V¬øÆ7¾¡øêW¿úâ‹/>óÌ3sæÌ‰¢(ŸÏŸ}öÙÑ>¶ì"£(ºùæ›ï¹ç½H»‘ïÿû÷ßE ,¸âŠ+ô/¼ð·Þzk_¸‹M›6-\¸ðÄOl~Mv‘óæÍ»úê«í“ò'bÈïÝ»wGQô½ï}ï‰'žX»ví—¾ô%ïß¶j-^¼øšk®¹îºëì6mÚEi'Š¢9sæ<óÌ3.žƒóãÿøŽ;îhíí¬[·náÂ…§œrŠþä;ßùÎ…^è]äÒ¥Kÿò/ÿR_ÁE]ôÊ+¯<ýôÓßýîw£(Êf³ŸúÔ§Zx/õz}áÂ…sæÌ¹ûî»í'vp¢(Ú³gÏúõëõâgÏž½aÃÎŽ;Î?ÿ|=8÷w7þüÖ¾—_~yÞ¼yçwžý/Ép‘¿øÅ/lOrƒŸúÔ§²Ùì½÷Þ{ã7FQôÊ+¯\tÑEÍ¿bK¶:ç¡¡/~ÿñÞƒ;çÉööto,žx¼èÎ;·lÙò±}lÿ¨E–Ëå;î¸cúôéÛ¶mÛnçÊ+¯üë¿þëéÓ§oݺ•ªæn~øá3gδ"À~°>ùÉOžtÒIüïxøá‡÷÷÷_yå•wÝu×îv¦N:sæÌxüÎñúõëÓéô!‡ò»—X,6sæÌcŽ9F¸uëÖÏ}îsßúÖ·¬ýÁZÓ¦M³r™­¾¾¾Ù³gOŸ>}úôé7ÝtÓ»óÐâ‰ötïøCŽnëèzÏáýýý·ÞzëW\1~üøýà XNsíµ×êˆÓt]}õÕ×]wÝŠ+&Mšd=ª°öÁõüóÏßxãwÞygGGÇý^,XðÌ3Ï\{íµûÍÛ™7oÞm·Ýöçþç?øÁ>è÷288øÀ¬X±bÅŠßýîwßõïÏ{¤+W®|òÉ'‡‡‡‡‡‡W¯^ýÔSOY‡íƒ»;ì°¯ýëÁ†õ¾­Õ«W?üð×]vÙþ‘Æ]yå•§vÚ¥—^ºdÉ’ááá{ï½÷ƒ~G—\rɤI“Ö­[öjë]ÎYguÀ8ç¶mÛ¶qãFCׄVXÿñµnÝºŽŽÃ>íëöÛovÎmܸñƒ€†õ¼>6sùcÑåE7Þ~ï{Ú¤êïï¿ôÒKíÏk×®Íd2™LæÙgŸ¢¨Z­^ýõ™LföìÙår9Š¢R©ôñ<“ÉüË¿üK­VÛ§úí˜Éd2+W®Œ¢¨R©\sÍ5™LæË_þòèèhE###ö¹sçÖjµZ­ö³Ÿý,“ÉœqÆ¥Ri_ƒ”ËåÙ³gg2ªEQôì³ÏÚõ¯]»Önð²Ë.Ëd2—\r‰ÝàÖ­[í?þx½^ßwîå‹_ü"ö.²Z­ÞrË-™LæüóÏgÍš5+“Éüô§?­ÕjõzýßþíßìŸìÙ³§å÷òøãß~ûíöç_ýêWýèGíÚ¬]*•Î8ãŒL&ó³ŸýÌöØÜ¹sí###QŽŽ~ùË_Îd2×\s!qö©·cëꫯ~饗l]uÕU™Læ+_ùŠí±ááa»‡z¨^¯×jµ»ï¾;“Éœ}öÙûÂ!º÷Þ{ùË_ÚŸ+•ÊW\‘Éd.¾øb»ø]»vÙÅÏŸ?ß.þöÛoÏd2çž{®í½r¹ü™Ï|&“ÉüèG?²C×Ú•Íf¿öµ¯xê©§ìúûûûm/ýÕ_ýU&“ùÎw¾c{é7Þ°,Z´È× 7ÜÉd>ÿùÏÛ zë­áèòÇ¢¯ÿ|ÄÃOˆ|læÏn]᜛¸ñ_¾ûõ/VXa…Ö»¸¶æÜÍKÝÐösÿæ‚À>VXa…Öû´‚Ë +¬°Â +¸œ°Â +¬°ö¯õb­Ø=å¹ ƒ'Mî%¬°Â +¬we½´%¿;êÛ‹Ë>`Æ/—­9ªïˆðŒÂ +¬°ÂzWÖ/—õ—'|È5´¨e.'+tN¾ñÑM¿÷+Ò…þî‘ áQ†VXaýÁ®hò'†b}£¥üïþX±sr¢áoœs±eË–ãïï>÷[?â{~÷¿¯×ëgZ9ÿ¸Dxâa…VX°kÁ†Äo6ǯËp.æœ+ í|ü^rÏMßKNœxÐ ‡õm_»²wâéqÚ_ÿŽU)dvŒL>0<ñ°Â +¬?ØU©t:—ú½.ÃüÍ®/}x꤉'ÆŒqúopÛK¶ÍüÚ ¿÷ת£“ë›NèÞžxXa…ÖìÚÒù‘ ÅUG‹¿÷“OßqùIGrí÷.™6mZ,Š"çܦM›¶oßqÁÿ¿ÿÈoŠ×ʉZ1<ñ°Â +¬?Ü•W%£úïgÓŸÿÏ>xâGáœûßùíÞõ·����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/editjmag14.png�����������������������������������������������������������0000644�0001750�0001750�00000117335�11332127303�017067� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��Ü���mMöó���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ 7Jaë”�� �IDATxÚìÝy˜\uèÿï÷ìçÔ¾ï½%$Â’‚Jäâ2A×—¹?AÔßüÆŸç2>s¯ÎÎ8ЍpGTdDGL$„ìéN:é}©ê®®}?§ê¬ßß§ªºzI‚:À÷ýäѦúTW¿¾U]Ÿ>uª« BÈ0Œr¹üâ‹/ÞqÇàÒtCÑ –¡�‡Ãáþ{$Õ›À¼ª³†¡iüºs©ªJI’—¸ýÃ?¼k×.‡ÃAeÆ¡C‡>úÑîÚµ+“É,ßB¸ä”}'§?<ó§ï}¾Žq8î¿Iÿï?|ïÀýw�d¬x¿½â‰ñxüÀú§ªëú¥ŸëW¿ú•ßïß¶m›a\ÒeÝyçŸÿüç~øá;vP¥Récûؾ}û „³³³ðE1[U_ž¬¼i®*c 5�à° 5±¡¡ÝÊ—ª�€¥)Š"ź �° œ¢jŠª�ÜvK±""�(’x¶R«�x–�Ôe�`·òR]ÖtÃܸP� M14U“�� Ïjº.+�Ài*µºIV W®J��Ž¡ J �`³p YU5�àvX e�@S$ÇÒU±±bjRC7 ¡ÓÊ/ qÙ-¥ßBQ s1Av Wúí 5äe›P¬ˆ—!IÂʳåå /5–CH†¡/ v ß!¤†|AIòSë¯Â*ª~Q ¬7ÚEÓ]4C‘,CW †¬¨—¸†²B‘¤°2„¯IòrM‘µ!U !ôª 4Er¯B„ø:AšbÚžU´e‚° ›·êW 놱Â24EæáR ¡zDÕ‘Ðl<nÞQñŠwæµZ � Šb6›}ÅÛ_P–e�@6›•$é"›µûÖ·¾Åq\ÿÑ£G©ƒ^wÝu—øý™›ÊùìÈÀ±7Ǽ±òÌê®@¾T›M=ÁÛ™:7ÝÕhÀé yGÆ9†êxeF¦S ×ßL%sÙbÍﲆVGG‡!„Ý!7ç°Žœ›8zUÌ_åédÎeãÝ}áøø\Ul„¼ö�ah²'ì1(zdbÎ&°ýÝl¶<Ÿ+{–ÀªÈÄÙ M×cA—Íë93ɳT_Ô'+úx"ã´rÎÞÐÜLºX‘nkˆ‰Ž Ó$Ñö72’°ò̪6Ä.xûÂÓÃ3RCœîwd`œe¨ÞˆW`d*e·°kºC©ù|¶Xõ¹,¡U±Ñ3#€®›sØFÎM ½*ê¯J-Ho811W!-Ða(²'ìA =2>gØþ®@6ׄøû"Cš¦Ç.»¯‰ødMgœVÎÑš‹/ƒ„Ü”…oBbþBYJ¤ -H\j(Q¿Óö Œ±4Ùñ)ŽLÍ/ƒDÇÎŒ�º‚nÞ¹�©Õ婹E Çì½�$_žÏ–½‹UdrhB] éøTMkA’ñL¡"ÜÖ0¦šad$ná™Õ1¡"%R÷"ˆÃñ· ^-H0*d UŸÓ\½�V‚¸:!ô Õ]\¾œÌ–½Á¿*:94©jZ4àrøÝ#ƒ<CõF}ªfŒÅÓMH"S(/…ÐVadxÈÌH\¬+Q¿ÃÛQ/lA\¶‘¡i¥ûb>±®´ ¡ÙÉùr­Þ!ºÃ^È2#c³6YÝÌå+Él© 97©¨Z¬áª/ê“4c,žvX9GOh>‘É—E¿Ë^½�a: ÅŠOÜvÁÓ‚D|ot¢ÄÈä¼ÝÂö/†ŒŸCÅ‚.Áåš2!RCœÍ.‚¸mA:220¼ Èå«-HdjhJ^ièÆèÌ%@8fU—¿T•âómHBÓTs÷âÒïÏÍ}‘K¼çï<˅εâåJ’DÓô®]»<H}üãO¥Rsss¯âRD�€xsÌ›î°;[é²Ïií yNÌŠ²ó»B>çÁÓ“,Mw…ÜšFf2+ßòÌÌÒE)è¶÷„=OM€è ºíVáØ¹„À±Ý!wE”§’ÝÒö M¤Ê¢ñ9»CîçOŒÑÕt“$ufbÞ.ðÝaw2[Iæª~—­'ì9rv¦¡¡ÞÛë²>3Í3LWÈ]WôñDÎeºÃžÑx._i„=Žž°çÀ‰1H±›ãØS#sVžë »ó%1ž.{Öž°çôè\­¡ÇüΰßÕ„݆†g2+ßò̤ 風„ Lö„\«åعx"u@¦R%Q‰øÝ!Or“58>o¸î°'™_€ši¨¨'äöºì‡ÏLs Ór7T}Ì„„<ã‰&¤{ââyî¤ ¹óe)ž.yÖî&D‹ù‘€ûÅÓ,Mw…\�ÃSi‡…ï {fRÅȤ†`oÈå°[Ž‹ ìRȹÈþãc4Iu…\E ŽÏÛ®;ì™ÏWç²U¿ËÖò;7SWQOÐís·!.¹2›ËUê!½'ì}þÄ$È®K๓#³Vží¹ó•z<Uê¸FZSLMHwØO•R…&ä¥ÈÑsqe»B®ª¤L& n»¥'ì9oB¼Žž°×„ÄB.ŠnCÜ)â´õ„MˆÑtû=ö—§Zc,‘uÙ„î{|6—+7!NŽC‚ì ºž;9<káÙî»P©Ï´ csÕzòB ‚�<ׄ¸ãéRª ܶž°÷¥)â´[ŽÅ–é »kuur®à¶[ºÃîóSébM^¡ij`,i¸® ©ø¶ž°ûø¹™ºbtw@º[§Uè »'fsÙe‹ÀžµpK îÁ±¹j]‹úQB™âÜd’hCBž—§Tô†Ü.»åèÐL$ï¶[ºCîáé6ÄóüñQ² ¡Ût¡6›­øš„¤ÝAw  ¡»BnE3FãË! º,ß„„ÝÅEdµ®¶'Á«š7KæÇÈl1Sªó޾ùÐ.0W­ _dP:7O‘ÄÎó?SEi$Qè ;{ƒÎöö=ôÇã¡:Ï9_OMd×DÝëbîÎ/÷ëÓšŽÞ½£¿}J{äœ|·ßÊ3¤¢#Ér±&#tI÷õ^;·.ê83],KÊŠØfskx¶œ«4��$CnaMØn~v6/M§«Šf˜ÿy݆@ºX¯6Ô¿í\¢(«CuEÓôWøn–)TåD¦âwZ‚^ûùx®"©=§Çi}él‚¦¨îS3Àh"ç°ðQ¿}._K¤°ÇpÛNŽÍ74Ôq <w|$ɳLWÀQm¨Óó%]ùãsÅbMîò;|.ÛKg {B.Hg&36‹™’”ÌÕ‚.kÐk?3™e½/ä²Û„#çæXšî :ª11WpÙø°Ï1“.çÊõ¨×îwÛŽžŸÓ츆>=–²pl,à(VåD¦âsZB¯ËzèL¢#0_ yl·íÔØ|CE«#nËÊûx²X¬6!‡Ûr)$ಽö³“™š¬÷N›åȹY–¦»—@2å\¹ñÚýnÛ±áÈ©6D”é&d$ž+KjwÀésY‰7!�ŽNç.âw$óµTA ¹mO v[îøp’g™® £ÚÐÚ‰d±P•c>‡ßmmBÂNHRƒ“ÏÅŽl¹>—­\Ö Ç~v*Skè½A§Ónyy‚&æ .+ö9â™J¶TxíE¦ )‰J<]ö9,!Ÿ}$‘/KjwÀásÙ‰Ó$Õt€iAæARubáŽ'y†é :Ć>5_ôØ…ðbÈKC @=a'IRƒÏFŽl¹±Äayy¨ ‘u4>Û†T;!ŠÖDÝl Òµ"ªÝ‡×i;t6Nµ çÛ‚˜Ê‹!·-è±KÕUcuØeµðdž“Ü2Èd²T¨Ê1ŸÝï¶^ñ;r•ÈtÖ„¸Ö—‡f™ÅˆßÏ.@Ž·!,sr4%pL,è\ )´!/“$Õ2!Yû2ÈÀDº®«–@d}*Ù„LÍ—ò9æ³ûܶÃC³ˆ {›´µâ´†¼¶¡élµ¡™Ã-ˆ¢£ñÙ‚ÓÊGüŽD¶š)Õ#[Àc?>œì€Ì7!’O•½KÈkMJ¢Òíwœ&À¥ÏsËÎp.^xðé³#³Å%÷“~§ð¹Û¶_·)ºâ Ú70{ß§XšÔtô¶­]é¢ôÏýúÄôŽ‘Oý­}!'„PÓ4óéDûœ©¢ôŸ;ÿoÿ5ð½_™-¶¿‰§ŽL~ã‰÷ýôø¾8Òžp@ÇìØÜÑÕ^[i¤e¹¡âRþ…½¶½×t±röBgqÛù÷]·Ê®çuQ$©5Q×»¯Œ¬sk>˜£*3JVÓ sã÷]·j½r)h5ä|<êfw®XYR3ÀÅ¿t©1©z‚×i™LUŠ¢ÚpXîÄX䪰SÑÁùDÑ*pa¯-U¬' RÐmuÚ„ó‰¢(«"Nš¦OŽghšî8ª }b¾â²ó·5ž©æªrÔo·Y¸Ó Áþ¨Ë�ðìL^à٨ϖ«49Ñ粸–±¹R¥®õ†ÇžMÕrJª1:W²[¹ Û6—Ó¥FØksØø3Óùº†ú#.H“9–eºö¢¨šßbÈñÑ%¶ ¸­.›p>Q¬Éƪ°“YqÚø€ÛÏÖr•6$«-ÈtžoBdâqXÆæJåºÖrð<w|¬ ©w@’…&ÄiãÏNçë*ZqAr1$½�)ˆjWÀn]‰›{º\Ÿ3!öCŸÏP r’­ÈQŸÝnåNOä”&„8;ç9&ê·å*r<[ó9-‡e,Ù„&„\ ñØ’1Uª‡C’˜Ìš’¨N¥«n‡àsY¦R•BMé Ø­b,rUÄ©à\¼`ذמ)7ÚáD±&ë«ÂN†¥OŽe(šî:ª }|)Äf·r§'sŠÖD] Î4!ö|UYé :ž;>º�™-Ù-&DZ€Ìäë*꺒:=™eXº+`/I+CNŽg$W/‡ä—CØcЦ{‚Žš¼�IdkÙŠñÙìV~`2'ë  ¤¦Ä³5o"-‚ôµ ¶6¤Xy¬&DjC&² Cweb_b€EÈÈl±ÚÐûÂNn $Ù†ˆ™dЄD\g¦óÇÄüöBⴌϗK-ȉÑ4$©¾³¡5!!m¾ Í›»0dB"Ë ©ŠÛ.ø]–©L%_Sb~»Õ›³àUÍ›%’½xvnù¼�dJÒOîÿ—>°öð³ç4Ýê7qúÑ}çúõÙ_Ÿ˜�¼4478™iþA�¨ö™ç â gæ��“Ùï>}æÓ·nYóüü¥ñ‡~}V’5�À÷ûÀ Ìý,€ ÇvùlµÂü¡ñ² çSÙ×^ípyžLEÜüænç¹Ù²×Æœ<BB8——Ân À¡Œ I€Õ^âŠpwV‚ƒÓ%‡…¾¬Ëéè|U99Y@€��”çÇe-Dr¹BñéŽÎ•�‚wûwÔ•-7(Ö˹š'`Äm!ÿèòHoÈvs/œÏ+ZuXX2UjË»¬Ì® þl¥ÁPÄññB®"û¬ÇÎÍd¥RMí ZišŠ—Tnî¶×h2UµñLÄkI—ät©v 6 ;‘ªÕêúÚˆ�rpºH‘Ôêµ$iñ¬è¶q~ŸÈÕ U¥ÇoåúülEVÁ¦ng]ãɲ…£»|ÖlE/ÔƒNÞeå¦ÒµŠ¤õ‡l$I Î$×Fl•º>®9-lÈ-ÌÙ²óZ,3:W•dcCÌ¡ÄH¢Ä1toÀš¯©s9Éçà<v¾ ,@¶tÛ«²œ.6ÂnÁÞ +@N~6WÏW•n¿•gèáÙJCE›ºš¥»›)° rf¦ˆÀ%AtDœ›.q Õ°jêlNòÙ9g¥bMí Xš>/©:ÜܳpD/)Q$Õ¿’¯ç+J·Ïʳmˆ£¡‚1â·æ*j҄ظéŒXµÕhâè€D½+ÇŒ&«’l¬6!l¢ÍæD¯ó.$JŠ6÷8ÄšHUm<kBêa·àX™*Q$Õ¶–D-žÝV6àZ Ï2ó•†rIŠ¢ÎΔ–B<&¤õ´ 6¤ÈÒTßRH½XS{—@d41_µòLÌkÉ”åT±r  ;™ªUëúš°BòÌt‘ Éþ°­$éñLm Dè€ÈªšÌK'ï^B¬Úªu}*]sXذGHÂ3cɪØ0ÖGFì€8V‚t;DeĵBäàt‘ Èþ°­,é3™šk"wu@6v9d Œ%K<K÷´ þNH° ѱ¡ ذGH•™R#ê¬<Û‚Ø pH®^¬ª½+ËÐçeóA×r`�xᇄ.xè#o_÷ÍÿÐt£T“¿ÿÌÙö®^¾¬×¿ä‚FNOÐñ?®ê}êè”9u¾ý‹ˆÏöòùdE”�4E|ö½W¶ÎÚ|`­$éSéêÖ¨÷oÚ™­¨¿:·9Ü7o ¼|ôäæží|èÈËC;v_³>bO¤zc¡Õ^:¯\µ©;>=ièE’¯‹�õ·¯òPõ¹íA+ˆ'âÛWõ@•IV@��`�Âü‡ô¸7ßpÍŽ:>U«Èà®èªäÓU)I ^¡Ïeߺ*pò̈$k²T››ùêîí[iBO§âïØ¼©^-ȽiKð¥Ó£§ÎMây›·Ûk³%ò’¨õù’có¢¢Ë»íyQgë–îññÉ¢’­Èa'gãééL½ÖÐ×…­ª§25ÉQKº¢Í. rr‰‚\¬©Ý^¦Èñ´ÔPÐæ˜­Z7¦2GS«Â|YI—ä€sZé™l½R×ûƒ£IQÕá¶k¶ª'òu;ÏD=Ü\AÎW•¨›çYj2#I²±1b­+h2S£HrmÈ’ª¨óņׯzmì„ ÇS¢|H¨jAÀRÈlA.ÔÔn¯ÀtBdc*-q4µ:Ø„øíœËJÏäéB:êá“9÷ m¾ØðXYŸ}ÈÖn{Q4f²’`BJJ¶|!ц8…ÅšœHKu]³Õd4™ÙEÖmefrФõ,£ó-HMOäê6žŽu@–šÊH¢llˆXšL×H’\¶¤ÊMˆ¿ ñµ êRÈ|Iɔ哳óôT¶^«ëk[£ Ñç u§À„\mÏÐÔ%BV/@À¶[ÂÑ1Ÿ,ʹŠuóŽšÊÔÛ©t Éu‘ˆÃ„¨½>\aèÞˆƒ§§³õj]_²hKÕ DlŽZÒU}.¿ÒåáÙ @Re%U’}vÖmeâ¹Fù ×hCÒe-Yl¸C(²é²¥¥ “s‹ ã階ˆÍ]MˆC`® ‰ÚDBQýA!UVS¥†ÏÎz:!›•ˆ•£cÞÅl]l˜8•®¹.bIW´d¡ ™Í7Š IV›Ç4૬ó,�‚[®êÛÐí1ä´Qº(™Î^h/çÖ«WQ$ùOïPÛ×…þüÖËû£î ŽŸCøè;6�Ÿ:2 �œÊNeÛçÿ»Û¯¿ak÷’c95ýælîì¹|Ô¦ÝrÃ5’$>u:þέþ«ú¬}>nx|d6‘�Äu³ssû_pþÑu…|îW·­ ú™úl-¯ª=ÇÎ׿¦7º%faXêäéÁ§^¾ëöP¿—J¦ÓÈÐ�¨=r�Tun.9;ŸžžÊôoØrñ?úÑþÙ¹÷¦���Òµl&=’È;)ë¡I/Ôrýð‰_žž.oÛ¼q½Ÿzy<£(½/zùèxrFFÌäÕJ]ïõrS9YÖÀå]BºªÏdަúƒìL^Í×Ô ± ÔtNecm¯«(Q5^ÕËÏ´tY±ótÔMÏä•’¤u¹Yš"¦rrCA›£BA2…"É n:¯æªª×ƸmÔLN©6ŒÕ~N3@¼ «:¸²Ç2WÒæKŠ…¥z|ìL^-ŠZÄÉ ,9S$móU% ŠˆÍ]ÜL^ËT—…8虼²¢® ؇@Íä•ZÃXäëÚ+@Š˜ÎÉu]Ö‚+ãµQ3yµZ×MH¢ +:¸²{ÒëcgòjAÔ€léâ¦Mˆ@ôLA)K‹ [cB¶ª' 2KSk.�ih(Þ‚Ä Zª¬Ø9:æiBbMˆRWÐe¾Ø‚lŒp3y5Û‚L·!$²²¢+º…dYK¡úV„„øZ rÅJ/ ‰ej)dÚ„8¹ÙÞÃ'ŠZª¬ØLHA)‰&„\ !:!´×F›U>Î@ ¾âgg j¡¦…Œ…%§rŠ$mˆˆ«Z§@‡œôL¾ !V€kCÜtAÍWAÖ8YË TÌô!,MNµ %ÉHhB j¶¢z¬´ï‚=Y”—@¬iþx®oBdÁ«ºø6$܆xX‚ ¦²rĈF"/3¿q.†$ ²ª/‚ty˜xA)ŠZÔµ�ÙáK #‘W AnŠrÓó~f d¾¬Ïež¡Vµ !Ç"ˆ¨ x^Ö¼ª§ùãÙ éö°d‚¶Ä„Ñó—ôô³%{Í�·ôyoÜÖ½d³ÑÙÂÙéìŠç27»q[÷’‘ÓtvΛF„Ðçnß³!ðË£“gþ?wÞpý–®ÎóšÇrܺ'`•D˜*"9$ÍŸ9XóõÛEYÿÉÐ$iñ4W+HÅ:Ò�S*•K 4�$ ¨6D’$C¡`Á°² (—-<ë´rݽ}v‡k~&+Ur��@:€€†<›­L— Ué”E7�Çžèj‚$Í‘�Ð ¤èˆ¦)«Ã,^d½KÏêÇó•J¥QÍêº1Ÿ+#{”rwKˆ¨×7 !˜Ê«²¶EÙdYŸ¯èI\¦‡³jI2üVÊe!'rª¤ µ~¦®¢DIÓtxm73–Õr5Ý«¼ÔhV«4Œ˜“fi8•W*Øf²¢ž,éÀ«»˜siµ(n ÚÈñœ&Êhµ—Ö (iŠ¶ÇØ™‚–ªèE® P#Yµ\7BvÊÊÁɼZWІ Si Ù’¦pg/}>£DÝÁ‘15–Ój £ÇMDry BÄez8Ó„xCfKºªÃkV‚D4KÃÉ$'ɲ†ÐbˆÃ„«–@ŠZª¢³±.@·!¶• ;zéáŒVu;Gv¹©±œV]‰°óU}¾¬“±%BŸÏ¨%Éð-‚Ðñœ–­ê†\åkC(® A—…˜¼„æÊšaB2jQ4Üt9­&«¼´Ž@¼¨)¸2ÆÆ‹º YlB‚vÊÞ†˜ŠŒæJšvH·›& Ø‚0 hÄÚ„¬ñÑu Ì–42‘ײU]`ÈÕ>j4§Uê+@’eMGðêæ\F+ŠºK CjÜ„xh€xa)dCˆδ!ÄÄrHϤ» q-@¶F˜TUO–ubd2¯Š2Zã£e $Jšªƒ«»Ù刃âW‚ì쀄[¾%’ž*/†Ø ëLuÂŒd´¼¨Û–@H8UPeµ ™/ë ¶¶ ^ å³’mˆÅ&d2¯eªºÀý~j$Û„L²)Ä: æ§‹_rEŒM”ôù²ÎPÄÆˆC '󪤠õ¦&£Ùòb»�érÑ4 '[tU×E¬™Ê=üë³�@óѲæÿ@ð÷ßíq+> ½c³ü9‹v†–=5îË\ò0ÜþÓ3kbžw^µjÉS¨%SÑë>yËÍ@¿>>ežó«Ÿ¸aç¦ÙùØ„4Ëw{¹mWx–’êòS¿9To¨ÏŸ/½mÃêĹÑÁáñÀºæ!HÑ€$�ÍH��A¬ë ÷ôôM'’?üžU}}·Þpåå—[K’öä¾Ãˆ÷š«dŽ7s/'è÷~è]oS ðòpæùóù“cóúþw'«ˆ"ÍU€��Í@©R]p¬þäûÞñä©ÌÁÄu;®ºÙjKjOüjlí6��€ÁZÁ �ºœ€&ÁdÁPtxyΕT !Dìì‚'“FUÚàpN¯«p64”(!Õ ®‰áœ‘Kƒp0eˆ ˆØ Æó†¬ÁË0'¢déˆØÝN%õŠ Ñí‚ç2†¤‚>a 0S2^SE#+"‚ .ÀÓ)£&ƒ€•p p4g44¸Þ«2š-#Í ®ëgRF±Ž¬ Ñï…g3†¨€.A“`"ß„$+FªŠ DììYÒﲆâ%¤ðšiA6á@ʶÖåƒØÝNÍë•ÆR`¦¸rEžJ5ø-+Cvvƒ³)£XG†X³2™7dn Ádu„'B‹ ^6T}ÂPĦ L5ÂB²)�óRr}8mBØH¯‹��Lšé• žNˆÒ‚tµ 4±ÆϦ Q1Á.‚ téˆØÙLˆ›'Bv8œmB½ ¹: GsFND E\Ö±±pì‚dg‰žNlB®Ù’‘©!HWDá©ù&Ä+À‘œÑÐàºÅ¡´QX¡ÀdÁ5¸5SU”jݪ۰žÏêu®^ 3!ä$d#ìÏ nòÃBÍU–Bz]p¨Ë!¸" OÏUø,„ײ�”(#Í vt¡ŒáÃÕ—�� �IDATQ@ë|ðÌ2È– @"x>k˜Õ�3¥Eš$6áÀ2ÈF?,ÖQ²‚4ƒ¸¾ ÌëeânBz\щ· Û£ðÔ"ˆÞPá:ï þ&$ê xL,†haxŒÌ¿öã#颴ü˜Ìg¾ñÌÃÿß»Ž^áéÎ�¸òsÞÀ…'Ð_=xàäxfù3¾ù³ Mí¹¢·=o–î嘹lÜçö^©júþÓñÿsç ;7ÅhŠ\ráækIÿÏÉÿôI9?¥Ê²XÛš·å%-U¨=uNF¬Hûþcÿxuòå†îò|qä%ƒ÷~é‡CÉÃϰÁŸø§§sçŸ\!©”Ö„`Áé8ý£c¹ÁF­$“VÇš ñÀÁ™Óç­›z @Ô5ðëÁÔ¯÷í¯MŸ��ȪÝkR¥ËõÌùZj„³û«™8Úpjº’žŒg¹5_úþ‹µÉ—Åšh[½ãW/ªù¡†$*´£Q÷ýÏ}nnlÒºaˆˆÍ°Ðh$OhÜâ×çkDª ßÑ£JP 8YÐë4N§ E‡«\†f€©2Ô xuXÉ‘…:$ xUX;œ¤d ,ÈÍ¡s9B5àF¯^¬Ã¹*ÔÜÝ¥KR5Xh°Î£ŸHQŠºˆ"Àxj¼"¨Ï”ˆ¬ ßÑ­š¥ðð d5Îd U‡kݺ¤ÂxêîŒjƒi²Ü€ ¶ô£ó”¬ˆ Y4’'Ô%î&ÄÑ qS%¨u@¯Šh‡çšÿ õýDŠ’ÛÂÅ ›q&K(‹!;¢Ú™dë é1_ƒ‚oïÖ'¨º q­�¹*¬æÉ¼ ¯‰h‡ç¨†äÐPŽPu¸Á«—ZëcÚ‰$U5!>ýÄ<%ë ËŽŒ fÀm¯YãÖë*œ©@Ý€;"Ú™LryP?2OÉ[‘­Ù¼2KÕU`gÁ*—q*M(:ì[ +,…ø…ErÎVZyª*:!ä$Q&2‹!îÅFäl†,5 ½bgÐp"¾´!!m¬@æëBxMtâë„ÈMÈ®˜vržªÈ@ ÁFŸ~|9$ '*DFlýxšÄìÆ`f)äÚˆ6Ô‚l[ r™OÏŠD² ßÖ­™¥$Ø™6ô:@`²5niã2W‡ÂQí¥eõ^½²B-@bvÄ‘`´�5^¾ÄÕéwë²§Ë-H–,Õ!M‚m!ýH’’5²"‹†sK!,LYÕWœ7�€™t­´ËÒ$àù,žñLÕ|6ZÌg¿ÿ37ÿ꣇�…j½"ÊKŸçv»3™L.—[ò`Ÿ¦,M‘äÒ‰÷ü陯<6è‹­��€a�„�@�B»ÿck‡Ægÿ÷¿þ_ÅÞÇG677��B!@!t�€ d2�­ÿÈÐ!A‚Ö·‹ ½µ+H@‚h^:„��B„ H�„t€�$ˆæ›_–È@È€lý¹@lôÊÅ™¬Q‚]éHŠohÐÊ›½òËó<B Û®²$-1�€+ü© ]¨“‚·Ç¤ý AGÀËë]võt†C¬u+u Æ«4àÚp} ÃÖT‚£ÐUÁÆ¡9Þ@ bÕ¬q¾À �6{å”DeDBð¶˜t`VÐ àdõ5.õxšC¬r*ÀÉ2 �¸*X)°%™ t}´~ !,Z@ÐÏäX„À\’—Ahc³¯B¡Ñ"�ØæoÌTèü2H·]=•ákÜJ£ Õ²mHýМ°’–¨ôrˆ[=žâ}N\â·hÁHY&ç. 鲫…ÆŠ º�ÄÃë=mˆK‘u8Ó†äØšBp$º*Ô„„­š“ÕÏØ„L‹„à†˜ô⬠ÀÁêëÜê±&D…�L˜@c¤È”d‚„hw¬´ ¥¢sU Bp]D:–âë´ÐÆVŸ|¸á)4Zd�—ûñK†\ªŸÉ±U…`ItM¨~°qqú¹<‹�¸Ì+gAxÕ€ÖXçV–C¶c%¦Ø HˆnˆÕŸO:A YôÁ‹Xï‘++Büòáä2ˆ¯‘¨Ò¹%Nïu¨'3B ß¥(œ©\²jîHV"S&$*½8ׄ¬w+GSB ×¡ðb¿ …­ú`¶ ©*äl‚`är¿üR’GÄìªÐ ©Ñ9iÄÍé}Õ€ÓË ×†ë/Î^ ²;*JòŠ팱Á#Mñ&„$Ðx‰�\hŒ—˜bƒ z{¬¾ÿ¢áúc¿9}ðß>Q,ä!„€ƒ³_ýáËKŸvÀ#ûÞžÖ_hÎÎÎ<xðƒü`¹\†êºï§'^8“èÜ�¸*ìúÆ_þKS湞}öÙ`0Øß߯( „PÑŒ÷ýÝÏŽ~ôoÞÍ2Bà—G'þñ±#¿yË7oiï±0 ãõz›#'ŸÏ_úË$<zúžŸñÆÖ®8BµZ¾xê'¬·ÏÚ¿› Øÿþ/@@B´ÚÑUrVdh¸Â'ä-u°ÒúføRÊN@±ÈeŒ”x ¢ n))2¹ÍƵÁê 󀀋U{íò‰¬•„¨ÇÖÐ1]eimõˆÃ%¾ª’i\¨¾t@‚¼âæ´¡‚@B´ÖY/ÈTJbh¸Ê_;š±©t0Ú:gýHÆF@Ôe•)Œ—9Š@—¹Åé*W”)†0v«Ï'�¯„u oiB4b¶ÆvB,”¾Õ+JÙ ‚l¥áOA´Þ-¥$&[oB^œw  C¶xÄ‘_UI–4® T´ N;Û‚ej¾9–±)&ÄU?’¾$ˆ—W#åtÎBB´ÊѨkD¢ÆÒ„±Í'^â’Rõ&äš@õ`Êa àfÕ>»|¼ ‘u¦«\Ræ«Ê%C²6E‡vFÛિœ¶Ŭ2M ñ2Oh“[œYáÔˆµ±7êúäLÞ"-‡0Æpñ‚«®²ËdzV¢^›l�0Uá(mõˆ£e¾²ào ²ÆY/µ Ûýµã&„Ö6¸ Æš)^e —ñŠg I#JßæÎÛ B‚lgôóEÁ„¤ëL¦9”rè‹!=6µ [<âX™¯(äÂECà§iAÊ •›Y›¼b‘²qIñÚRˆ‡ScVåTÎBBÔgoÈ:¯±4.÷Ö† ñÂu.)Ó‚\¨½”²éºXmµ£q,Ó„��&/ᯞ)XV‚Xe°ÑÚ&wýpÚF@µ(,i˜.)!²…Æ%CŠ–ó§^>öí;KÅÂ+¾M»ÙÙÙ_|ñƒü`µZ½ôgW?óÌ3Á`pÍš5æÈ¹ÄW¾¡iÚëõ»H—øg«�@£yH…Ðêsïú,ëoF‰úü!ˆYê5ΈM õŽÚ@ÁRÓ(ŽÒ7:+/¦œB'ó¤v®d! Ðg“"“n° ilvW^L94DصË"ÍÚ!„a¡¡`¢ÊSZc¯ —ù’J³¤±Õ]ÞŸt!HxXÅÉ(ƒ+A€«TÉ9‰£I´ÉY=–µ5 ÒJkýöÚK€0ÈË0FÊI€Õ6qºÊåd†%Ë=åýó..V p“yۤƛÁ&ĸÌUy¡(m¨d! ÐkçE&UgÒØìªL9TDصû‘ärwy_ âb”‚• @·U*Èäl¤n’nBH¸d«»¼Þi�ÂɪA®~"ׄH*œnAμDJÕir™«r(mB´n«t$kMš¨ &d´Ì—š%mîò¾¤ËhBäåÎêñœ­®“Z_k¯jA(hŒ”-&d¦ò| ⛨¥.iMÈ:GíLÁRÕ(Ž\±PÚPÑB\ÒÓÑ 4^(­µ×FË|qĽ�©—: 'ÚGàe Ã-H¼Êde†Y–B(­sÔΛͮÊy'‚ÐËÉVJ=[´¶!óu–!Ñe®ÊK‡‚;£õv@ Ô„¬±×ÆÊœ ¹ÂSþMÒe@ÂÍ*F>ÝIˆ I'j„&t²Ê&ÆÅ¥«†…úñœ BµÔœjBªCEKå›”é€ÎØDÚi­×*¾œY€Œµ ã-È67«xXùtÁF k1ädÎ&é”@é뵃-ChmHBd² †!-îʨ‘$bi,†u…£$—r—^óS«/ñ•ÖÌ "~‹—åiMâMðÏÁ¨Š§E+Gê½–êxÍZQ+¥®³•f}�BS·RÊPÙA(Ê×ò 3ßàyR[m­œ.ºdƒrÒr—P;Vð8 �4^³±„Ñ-Ôâ’PPX ¥®³•弦îfƒ%'E 'Ö4*!Y8R_e©œ«ØE¶QÊjKåpÎ !ô³u†ÐGªv†0º„jªÁfdN µ~kùhÞ£!ÂÍ4‚œt²è&!s’ a[²ÊX)u½­ôâJb'¤äj´ G/ Yk+¿dB躇i ´ âJþÅአ©¥; Ç  ‘.¦jABœ¤pJ´²¤ÞÓY·�iØAèd]àImµ¥2Pr6 ÊAËÝBõhÞC@lAÂèj ‰Ï· ‡A\œ(j¤ é³T†+öšFÛ(¥ßZ~©a m¸b§ £‹_ Q›ñD ¢u@&Û{âe6J9[vPŠ-† ¶ = ±K€ s¢¤ñ‹B¸Å´Ì ¤¶ÆZ9Þ‚„9ñDa)¤×R¬YKË vJ9[vRŠòb©Ye)–œurÐJP=bBX‰�h¬Ú„ÌJ|^á,dçM«ác§/ YckB|l#´óM1¾–m°é/Z¿µr¼àVé¢N<Qp„8Q3àäÄRjÝ´¶ ŽHY¡æ–C,Õ#y„ ÀJ0LH—P›“øœÂYHm­­|¸ùÃÞð1õDª/†T5ÚF©klåC9/€ÐÇÖù @N\ "´áÅã-ˆn€IÑÊF¯¥:U³”TÖJ©KÁë>oV|Á‚Kœ7 çr8‡Eqù¢ }<8™~ä…‹·ëÍôV]\©ª³E•�l²¦Ï‹>,¡õrÅaÉ�ð3"õ¤l�¬æó)ÅVÓ�ÀVëüéZ�`#e#NÖÝ�€[‘ 2§Z��ë-™‰ºG1Hêk„Ü��xhI ÕDÃ�èå‹•/k�`‹u~°D� ¤aËc’�dªÀ´b�¬r‰†£nÐ@›¬éÁZ�à¤Nª>Ýp™šÎZaѧ™¾8,ú��>F¤_ âgĉD1ÈìÄ­µBÖ„¸iÉòJ([mA�€©ÅÐe„0U��l²¤‡¥&¤/ž_YÅçÓŠµ¦³—ÉNÖ]²AQÐX'dÏ.@”Dà �èáŠE­ ÙlM©V‚€”b3!³²CÒATÃՂĸ’xq-2„>ׄ2Š¥ºb%å�S›¨{��a¶¢"2«\ b%•x RÒøÒbO¨1® ©€–C6[Sµ qÓõ©º )‹:mB6ZÒ#’OCCh«øÂyÑi%ÈTÇ—AÖY²Smˆ%{¶fBêVR^r¶0CL ¶ ýBnî• ’Nç[QÉ«"’!ôU|Þ„xi‘mAúøBö• "3&DÈN5\²A‘ÐXß‚¸èºm„+i|" yBíâÊ#-ÐüÄ.éŒùeBìTó2$sdxþÞÿys]zwæ¹\îìÙ³×_}£ÑxÅÛŸ8qÂétF£QMÓ.åRÚ£èÚk¯…V«õ»ßý®ªª�€r¹,Šb8Æov„Ãáp¸×X2™t86›Í0ŒÑÑѯýëÃ0ïÿû+• A…B¡T*­]»¯‡Ãá^c###~¿ßn·kšöÀ,ü]�€ ˆžž¼F8‡{]ÚºuëØØBÈb±˜§PK¶Ð4Í| ‡Ãáp¸×Òôôô‘#G¶oß~Á‘£ëºù¾Ö8‡Ã½–fffJ¥Rç)^‡Ãý~Â#‡Ãápxäàp8‡ÃáðÈÁáp898‡{ËG]ú¦ªªž?~ùéÝÝÝù|¾V«­[·Ža¼¦8‡{­#'›ÍîÞ½ÛáplÙ²¥óô¿ú«¿úú׿~àÀ®®.¼¦8‡{­#ÇlÓ¦M?ÿùÏÍÏŸ??::ÚÛÛÛþ,Bè¿þë¿ÌÀ5×\ƒ—‡Ãápf¯éXÎO~ò“;î¸ãèÑ£íS}ôÑ?ÿó?ß¿ÿc=ö…/|áÅ_ÄKŒÃáp¸ßr/gnnîþûï�\qÅË?û7ó7‹å¾ûî;vìØM7ÝôÈ#ìÚµ ¯2‡Ãá~›‘óŠI’tÏ=÷¤R)¼¸8‡{M#'‰Üu×]æÇûöí[¾I’½½½½½½×^{m__^b‡Ã™½þ—òìí·ß~Ýu×íß¿ÿܹsx‰q8÷[îå\¼Gyä¶Ûn{Ï{ÞS­V ‚ؽ{7^b‡Ã½ê‘ãóù8`µZÛ§|êSŸzï{ßÛÝݽyóæZ­ c±ØsÏ=g~Öf³u>‡Ãápxä\j4MoÞ¼¹ó”`0 �‡£}â’mp8‡3ﱆÃáp8<rp8‡G‡Ãápxäàp8‡Ãᑃ—�‡Ãápxäàp8‡Ãá^}Kÿ4“ɬønÓ8‡Ã½ª2™ÌÅFN*•:tè~߇Ãýn÷r²ÙìáÇ—%‡Ãá^ç‘#IEQ·Ür ^‡Ã½.qg±XV9��–eý~?^#‡Ã½. ‚ (Цiæâg¬áp8î÷98‡Ã#‡Ãápo®(¼8îuþM– „ÿ¾]×ñÕG‡{3ÇqÃ0ðo#™L ‚€¯<rp8Ü›?MÓBÀyóÔSO}øÃÆW9o˜ªÕêÏþs¼8ÜŠ}ä#¹ÈhF£ýÔØßÏ>û¬ªªø:Â#çT&“ùÛ¿ýÛ+®¸/·¤ƒ~èC"I/œ×-—ËõÑ~tõêÕx)p¸v,˾óïÄë€Ã#çõÏf³mÞ¼ù¿ów˜Ëåc±X?¾¾p¿‡ìv;Eá{Ü«ÿ]Λ¡J¥ò /œ>}/‡{ÜO|âí'~ íÝ»wïÞ½ÿñÿñ\¯‡zèùçŸ_~úôôôÿú_ÿëwzÑßüæ79²äÄD"ñå/�Ðh4jµ¾AãÞ@=øàƒ{×ùÙƒîÝ»÷ÑG}øá‡÷îÝ{ìØ1�Àç>÷¹½{÷âç¼q»¤]ãƒV«U�ÀäääÇ?þñ@ ð•¯|å-ø ?øÁ¾öµ¯ñ<ÿ­o}ëÚk¯íüT­V;uêÔïèr}ôÑï~÷»ñxü¾ûîë<=ŸÏÿÉŸü‰Óéü³?û3|SƽáÝ¿ÿ?üÃ?lß¾}ùg3™Ìþýû¯¸âŠ;î¸cË–-}}}�€#GŽ †Wïͼ—c–N§ßýîw<yò¿øE$yK­ÔüãÙÙÙo¼ñÎ;ï|衇VÜì‰'ž¸ÿþû¿ñoüô§?�|úÓŸ1?U(¶mÛ¶mÛ¶»îº«½ý½÷Þ»mÛ¶C‡Ý~ûí333+~Í[n¹å{ßûÞ®]»:OTåøÀW¾ò|#ƽ¡[µjÕå­��³³³Û¶mûÌg>Óù£wçwž:uêÎ;œ�Üpà xÝÞü#Ççó}÷»ß�ìÚµë‹_üâ[m¥*• �Àápø|¾ù—Ù¸q㊛U«Õ¯}íkº®:t¨··÷¶Ûn»ë®»æææ4M»é¦›öíÛ·oß¾o¼ñ _ø�à¾ûî³Ûíûöíûö·¿ýË_þ²óႳgÏööö~ö³Ÿ�8ÎÞÞ^«ÕÚyA¡d2Fñ÷¦©\.ïܹÓf³Ýzë­ù—Ùþ]mjjJ’¤ûï¿¿§§�ð³Ÿý ¯Õ›äa³Ù��4M¿_Fⓟü¤Åbùþ÷¿ÿ…/|á7¿ùÍE¶üô§?}÷Ýwëº~ÿý÷ßtÓM’$†AQ”ù`4�@UUQ�õz §Óùƒü`ëÖ­æ\"‘èííýÒ—¾455õoÿöoúɼúê«ÏŸ?oÁ¸7zwÜqGo+Ã0*• I’ï|ç;¿ño,ÙÒjµaþ†×í ~šã«ØËùØÇ>–J¥6oÞüÃþ0\}õÕñx<‹]Ê+"„̃.’$]è‘?þã?Veß¾},Ë^ä«íرãñÇŸšššm4ét_A¸7h?üð;ÞñóãR©„��üøÇ?ÎårKNܳgÏÙ³giš~ųëºþ|`tt�ðÌ3Ï<ñÄŸ˜˜0÷{öíÛ'Šâ»Þõ®h4z÷Ýw›©-ÿj›6m2ìn4‰Dâ_ÿõ_»ººðu„{3ý†755u¡Ï†qöìÙM›6á…Â#çM[4Íçó‰D‚¦ép8ìp8��;wî<pà�I’ÙlÖ<øy¡ „W]uÕþýû�ÉdÒívõõõÍÏÏïß¿ÿ¿øÅÜÜœ¹¥ÅbÙ·oßäää¿øÅ;wšG}–Ï?óƒáááÏþóÿ÷ÿï|_G¸7bæÃe�€íÛ·_{íµÙlö‰'žXòk™ÙÕW_=55µoß¾Ÿýìg>ø ^½7çȹå–[êõ:�ÀápìÝ»wÛ¶moÁ•zç;ß©iÚþç¦R©üÇ\·n�àûßÿþ§>õ)]×c±ØßýÝß�zzzÌ]—_~y8�¼ãï$Éÿ÷¿ûî»�›7o~×»Þuüøñ}èC>úè#<ò¹Ï}îÌ™3×××g>ç­Ý¶mÛÌ/Ø™Íf»þúëñí÷FlëÖ­{÷î2OyÛÛÞöðÃéK_ÊçóÿüÏÿüÀlذAQ”½{÷š7þûî»$É'Ÿ|Ï›7hÐívg³ÙJ¥2777>>¾{÷n¼(í&&&n»í¶¯ýë{öì1OùùωD®¼òÊ×åëŸ<y’㸠6��öìÙó­o}ë·{1·ÉÉÉï|ç;k×®ýøÇ?ޝ5Üï!»Ý ÏŸ?¿âËz ‚À0L­Vû¾’ôã?.Šâí·ßޝ¬?l‚ (Š¢iÚ<pÏ=÷àÖ^]ïyÏ{^ǯV­VŸ}öÙ§Ÿ~ÚüýÎåráÆápoâðÈùC¶{÷náàà �à#ùˆÇãùí¾ŽÛí¾å–[Ün7^R‡GÎ;’$w‡tóÍ7ß|óͯ}×uùaîw×¥üa�‡GΫ.›ÍÞ{ï½?øÁðRàp™¯ÇÃá‘óº‡{ì1¼8Üò>ñ‰O´ŸÜŒÃá‘ó:ÄóüÎ;ñ:àp¿E‡J¥R¨K—$ _xäàp¸·DÏ=÷Üè訮ëÀïpÂ#‡Ã½ù“$iÛ¶mæ+Õâpxäàp¸ßmAà#=¸nx p8‡G‡ÃáðÈÁáp8‡ÃᑃÃáp¸·z¯üŒµ|pù»ašÝpà ×^{-^D‡Ã½>#Ç|E}EQ¾üå/‡B!óMÆŽ=úøãs‡G‡Ãá^·‘ó¾÷½� IÒ—¿üe·ÛýÉO~�ÀqÜã?�xä‘G^xá…»ï¾{ýúõ�€»îºË|ÿо¾¾¿þë¿>räÈ÷¾÷½w½ë]’$ýæ7¿ù‹¿ø‹Ë.» /:‡Ã½5{MÇr}ôÑB¡0;;ûÙÏ~vjjê3ŸùÌ~ô£÷¿ÿý×]wÝ·¿ýí¯~õ«333?ùÉOî¹çžd2™N§ïºë®ÑÑQ¼è8‡GΫîúë¯ÿЇ>Nž<Y©T<¨ëúž={vìØQ.—O:en¶sçÎøÃ¡PèÔ©S¥R /:‡Ã½5{M/xF}>_ç)º®oß¾]UÕÎÃáp ÀkÃápx伞‘$ùôÓO›3 ó«_ý /1‡ÃáÌ^Ͽ˱Z­��–eçææ6nÜø¹Ï}¯/‡Ãá^õ^„0‹ƒÁöt‰Åbv»�àõzc±Ã0‡Ú¹s§ùžf7ÝtÓ÷¿ÿý§žz*‹9�€Çã‰Åb,ËâEÇáp¸·fÐívg³ÙJ¥2777>>¾{÷n¼(8‡{]AQMÓxà{î¹¿à ‡Ãá~OᑃÃáp8<rp8‡G‡Ãápxäàp8‡Ã½å£ð\l Ïóx–„’$ ¯‡Ã#çuަi¼KæÍ“O>¹k×.¼8œ×?MÓÌ7Â�ž~úéB¡€×‡Ãá‘ó»ú½^×u¼fÙl–$I¼8î·?}�‡Ãápxäàp8‡Ãá~‹.õXΉ'BæÇN§sõêÕ©Tjvv¶»»{Ƀ¾é›ššÊçóëÖ­3ßè5Ç3™L¿ùizz:—Ë­]»Öf³½öËM$étzõêÕN§sùg‹ÅâÄÄD0ŒF£ø‡‡Ãý^÷r^xá…[o½õÞ{ï½÷Þ{¿ô¥/}æ3Ÿ9wîÜO~ò“={ö<ùä“oµ%»÷Þ{÷ìÙ344ôº|µçž{îÞ{|Å-ÿéŸþiÏž=ƒƒƒ¯ËåîÛ·ö}Œâ�� �IDATïÞ{ï_ñ³‡Ú³gσ>ˆBp8Üï{/çSŸúA=ö˜ygtë­·~ûÛßîïï7?{øðáÙÙÙo¼Ñår!„üqóôP(tÝuן:ujëÖ­Åbqffæío»Çã�<þøãæn“ßIÏ3Ï<S©Tn»í6‚ J¥Ò³Ï>kž¾víÚÍ›7Ÿ8qbrrr÷îÝ~¿ÿ©§žª×ëï{ßûªÕjû͹ûûû·þÿìÝw\Gÿ8ð¹~pp]éMADTÄŠb¯$&¶HbBŒ± LP£hÐGc7ŠkLTTPT@lH)Òvp½þþ˜ïs¿{@‘8?ï?|»ÃÞÍÌî~vgggú÷÷ððÐÕÕ533KHH¨¯¯Ÿ8qâ•+W´µµ½½½oݺ…S:99õë×Oý«¯^½Šûm3™ÌO?ýT}Õ“'O GŒ‘‘‘ÑÐÐD¥Ry<žj‚p[[Ûôïß_[[ÛÜÜüÎ;µµµ&L¸víF äp8<@åæææää899Áq�è$--­°°0±XÜÜÜ\__ß§OŸÖ‰ÓÒÒ˜Lfqq±½½½R©:t(Ç»sçƒÁ¨¯¯mnnöôô<uêÔš5k Ÿ={vúôi[[Ûôôô+VTWW766þúë¯õõõ ˆÿöÛo 322Ž?ncccccÓ K‡@ Ðh4…B!•JU ¯]»öòåK&“YZZºmÛ6‹åàà°k×®ØØXƒqûöíÄÄDggç£GnݺÕ×××ÊÊjÚ´i¿ÿþû²eËbbbbbbtuuœœœÎœ9>räÈŸþ9..ŽÁ`¬Y³æÎ;`ÿþý #!!!))ÉÙÙùÉ“'/^¼˜3gNZZÚÊ•+™Lfaaá¾}û¬¬¬Õo†"""D"QEEÅöíÛ)Ї‡ÇîÝ»wîÜÉd2ïÝ»wãÆ GGÇóçÏoܸqذaÑÑÑû÷ï×ÒÒÊÊÊÚ¹s§¥¥¥ÁÙ³g_½z¥££ãééimm­^&D"±oß¾pð��Þ‰B¡Èår…B‘žž~÷îÝv5¬­_¿~åÊ•EEEëÖ­;wîÜСC§M›†Wñx¼iÓ¦ÙÙÙíÞ½»¡¡¡¡¡aíÚµQQQß|óMNNÎï¿ÿŽ“ñùüI“&999ÅÆÆr8œ-[¶P(”¨¨¨+Vœ8q¢Ç•#—Ë]µj•®®nxxxcccLLŒ­­mTTÔ´iÓîÞ½{çÎO?ýÔÑÑñÌ™3QQQMMMË—/çñx;vì°²²ŠŠŠÚ²eËСC[³yóæ5kÖLŸ>ý—_~±··ŠŠŠˆˆðòòR5::šËånݺuýúõÕÕÕû÷ïãÏ a³Ùááá **ÊÒÒ2**jΜ9>üûï¿[¤¯¯¯çr¹»ví²±±ùüóÏB#GŽüä“Oà˜�|І5„PXXÇ£P(Û¶m³¶¶V(x¹¿¿¿³³³*ÙÊ•+ׯ_¿nݺêêjõ?;vl‹ëb‘H´nݺÚÚÚZpŸ}ön!|›€€�‰´nݺS§N………­Y³¦±±Qµ¶oß¾¸@®\¹Ò"ºûí·¥¥¥qqqx‰‡‡‡‡‡B¨E`Þ´i“X,~Û·Ïš5ËÌ̬ýÙY¾|9¼à �è!gíÚµ"‘(&&fÕªU$i×®]wïÞU=ËQ·zõêsçÎmß¾ýÏÃI$’››BhôèÑ–––Y¸%%%<!”““ÓÎñ ¾øâ О”}ûö¥R©ÞÞÞ[A�@ÏÕ®†µ‹/ÆÇÇ#„X,Ö˜1cÚHyáÂ6kÖ,___õåÇŽ»wïžú …2kÖ¬!C†\ºt)--­ÇܦM›ÊËËÛHpðàÁèèèE‹>}úÁƒ_|ñ…úÚ{÷îÍž=ûüùóïü¢[·nÍž=»uÏÀéÓ§úé§—.]ºÿ~ë¿Ú¶m[{zÁ½Óï¿ÿž�Ç �àÃ…œS§N)Š€€€€€€°°°¡C‡®\¹ò)Ïž=ÛÔÔpàÀˆˆˆÛ·oã' #G޼zõjjjjtt´……ÅéÓ§Åbq@@ÀçŸ^UU5~üøWp3fÌX»vmCCC||¼±±qllìóçÏvïÞ=}úô3fdffVUUyyyùûûkii%$$°X¬dgg¬ZµŠN§<ø755ݳgÏÓ§OqëééyzzªÖîß¿ßÐÐ0((hÚ´iÙÙÙÓ§Oo½…É“'ÿøã•••ñññººº‡ÎËË øé§Ÿ&L˜€Õ´Wñ¹sçÊÊÊZt–�€÷F000àp8MMMåååo믜——§zTGG§W¯^õõõÇÄÄ„Åb½~ýZ ØØØP(”ÜÜ\„N744,++;{ölttô¶mÛ‚‚‚šššz÷îg ÁÉBÚÚÚݶaH$2™L©TÊçóU +++qFªªª$‰ƒƒ@‹ÅÅÅÅ8‘‘QUU—˵´´ÔÖÖ.,,”ÉdŽŽŽ‰¤¨¨'Ó××766Æ}ù,,,jkkE"‘~¦"‰JJJÚÞ BˆJ¥¶èQ¶fÍšC‡?ÞÖÖVµAõïe±X&&&555 ¸…B¡­­-‘HÌÏϧÑh¸×"—Ë­ªª244lñÈêäÉ“$iÖ¬Ypð��ÞI[[["‘Èd²¸¸¸ðððövppph±ÄÀÀÀÀÀ�VêvMLLðg333õÚêÉzUFÔÏõ4­EŽLMMMMMñg[[[üJ¥¶Hfbb‚‹ˆÁ`¨/§ÓéíÙ`¬¬¬TŸ[¯±±±±±1¾€xc¥èéé½s@��øg×ñýd2Y[[&:û`¨Tª¶¶6t?�|Œ!gþüùååå ,€²þ0"##ËËË{è€��9����„���=LDýn"‘¨´´ÊSu\��9L(>yòäéÓ§Pÿ§!Ãn�€Ó Wô|>_"‘¸ººBi¨@ÿC��„œN 9d2ÙËË Š�� ät.@§Ó?ÀI$’vŽû ��r46äÐh´Îþ–çÏŸ3™L}}}(p��„œ\.WŸ!­cåää<}úÔÛÛB��B@ …¡ÙêêêÔÇ �� ¯‚��€���B���ðÚû,G©Tª¦ c0xª•^¿~-—Ëñ_š­ººZ üÿB$“ß9Ë.@ …baa»��BN[RSS'L˜Ð·o_gbbÛ»wïiËËËkkk5¾ÔV®\ù×_9;;Óét…BQYYyéÒ%''§6þD.—0ÀÁÁ!%%v;��„œ·JNNž6mÚ¤I“8™™¹aÆ«W¯âýû÷Wïã+T'V {{ûüüü²²277·ââ⦦&*•ÚÓËîÈ‘#|>ßÂÂbÑ¢E÷îÝãp8/_¾ÄkÍÍÍBiii<ÏÛÛö6��„œw[°`‘H<pà�BÈÕÕõÂ… ÅÅÅ[·nÍÊÊrttLII™5kÖÒ¥Kqb±X|äÈ‘;wŽ5ª´´TOOoË–-ÇŽûõ×_W¬XqõêÕ¼¼<### +J‡óçŸ0àåË—ÞÞÞ¡¡¡¯^½Zºt©‹‹KUUìm�€Ü{v¸wï^||üÔ©S:äååµsçÎ’’¼ŠÇãýðö¶¶‡Z´hQBBÂ¥K—ðªÝ»w;;;ÏŸ?_KKKÊîüùó‡>vìƒÁ˜4iRNNξ}ûFŒqèСqãÆ=z4==}ÇŽ¥¥¥QQQ/^¼€½ ��!çÙ<yò¶mÛvîÜ©£££eWSSSQQ±aÃ}}ýÕ«Wã…;wîLMMm‘xË–-°·�>rtôY³fiR­èèèØØX777„‰D¢Ñh0å��ü㻜üQ¡Plذ!”ŸŸ¿lÙ²S§NAÙa‹-jnnþý÷ßñ]\\–.]jii™››ÛÜܬJe�€»œw›:u*‰D )**ª¯¯—J¥+W®´¶¶>{ölzzú“'OÖ®]«zGWWwûöí‘‘‘ÁÁÁååå~~~S¦Lùí·ß4¾(]\\V¬XñÇçääŒ5ÊÄÄäûï¿/))Y¹råœ9s>†B��€rB'NTõ1c³ÙNNNýû÷W½êêꪧ§wøða±XL¥RçÎëììŒW™™™ÙØØ,^¼800ÐÅÅE3JmãÆøV!D§Ó¯^½Ê`0Ølö²eË|}}q;;;33³#GŽðùüÁƒ›ššjF¿ ��èÜC$}||Ô—ôêÕ«W¯^êK<==ñ--­‰­­­­­­5¦ÔT!D"‘T™e³Ù-2Žêß¿?þÐz��|T`Œ5���r���@È��� ä���è¾`"êw“H$555´qõI���BÎGM,gdd<zôŠ�� ät"¥RÙÔÔT[[kggש_Ä`0 ´�r>öC¡P† E��ÿt����w9�€ž‰J¥’H¤îðK„B!T„�€FŸVÈäî0Ó|BB‚j.�!� É„B¡B¡èªo¿ÿ~^^„9= ‘HÔÖÖ†r�àx<^kår¹L&ëªßöúõë. x�BÎ{jll¼ví”�-Ìœ9 @Èé`2™ŒN§9Š�]]]&‰ (�„œF$ét:”�*ZZZÊt|È©¬¬lÝ Ë`0 ÚóÍÍÍ,KWWŠ� ÒÐÐÐâižiuuuL&S©T677jiiUUUI¥R xrÖ®][\\¬P(^¾|I§ÓBãÇ kÏœ>}ú»ï¾Û¶mÛ’%K ¸�*‘‘‘ÿùϬ­­U×£‰‰‰ªµýõׂ Ö¬YÃb±Îž=éãã3yò䜜œªª*¨™!çèÑ£øŠ£W¯^¶¶¶ª}¢¬¬ìÕ«Wøs¿~ýôõõSSSÅbñðáÃ…BaZZš±±qAAB¨°°°ººÚÄÄJ� nûöícÆŒQýŸ=ôõõUKúõëçääôüùs<òúƒ>ùä(:Í 9oTZZùâÅ ‡´´´àà௿þzÑ¢EåååµµµåååAAA¾¾¾+W®Äc0§¤¤BÈ�´A*•ž8q"22rúôédòÿ>{òäÉgÏž544 „Nœ8!§‡zÏ1ÖÏœ93}úô#GŽ 4(**ª¸¸xêÔ©d2ùèÑ£üñ‡‘‘ÑØ±c‡Œš3gÎСC¡¸�-ܺuëèñùü°°0kkëùóçgff¶H¹nݺ^½z!„öíÛåöqÝå`ÉÉÉD"1??ÿwãÆd2yåÊ•úúúëÖ­[¸p!”/� mo|0ãää4oÞ¼¤¤$(9-MŸ>}úôéfffPš�€*88Xõ,§±± D³ý«É |||V¬X¡§§WTT$‘H"""~ùå—˜˜˜¨¨¨¨'>qâDVV”8�àrrrpÇ¥7’H$áááPJQÈ9räÌ™3ããã¿øâ‹íÛ·›˜˜èêêž?^&“Í›7oòäÉçÖ­[¡±cÇNž<ùÔ©Sl6J� nçÎ_ü—¶¶vTTTQQÑáÇ]]]['ŽŒŒd±XË–-ƒgÃ=T{Öh4Ú¥K—Tó%÷îÝ{ýúõ¸“ôüùóûõë§§§wðàA±XŒêÕ«×¥K—ð»¢666›6m*))qtt„k��•¯¾új„ êK¨Tjpp°£££¾¾¾©©©¿¿ïÞ½ …ŸŸŽ@Ÿ|òÉéÓ§e2ÌÕ«á!‡D"1B}‰………………ú’AƒáZZZꉭ¬¬¬¬¬ ¬�êììììììZ,T?{á666ªC† ¢ë¹`"j���r���hIú]1™Hd0, Š�� ät.CCC˜^�� ät.…BÑÔÔå�À{hll …]xðB@È�|jjjîÞ½[[[Û…¿æÔ�Ð|2™¬¨¨ˆÉd2™L9�B� I$GGGGGG( Ðt’���!��€f†5�@£R©ª9=»ž¸@È�hîi…L¦R©]þ3®_¿îíí Õ!� ù„B¡\.ïªo¿{÷nQQ„9= íÊ€7jnnnc­\.—Éd]õÛªªªàmP9=O]]Ý¥K— �há³Ï>ƒB�r:˜B¡`±X£G†¢�@…ÉdR(‘HE ät<‰…��à…œììlUÃ(“É´´´¬«««ªª277×××oçFJKK›››íì슋‹ÕyñÛþ[@PTTÄb±ètzUU•™™žè�ÐCUVVÖ×׫/Á³Mc\.·¬¬ÌÈÈH¡PÔÕÕõîÝ[WW·°°P$¹¸¸À`6šrÒÒÒ&Nœèéé‰÷]]Ý_~ùåÅ‹‡þæ›oÚùe¡¡¡7nÜHMM0aB}}=žP–ËåêééíÞ½ÛÖÖ¶¿ÍÈÈð÷÷Ÿ={ö§Ÿ~zðàÁ%K–BýÐsEGGÿç?ÿqqqQ]¶^½zUµ6!!aÁ‚kÖ¬111¹xñ↠œ““SUUE£Ñ �56ä|öÙgD"ï ÉÉÉ¿üòËÊ•+CBB\]]Ÿ<yRYY‰S„qãÆñùü»wïâ%}úôQ¿r:t¨ŽŽBH[[o0)))((hÏž=111ÙÙÙ¯^½Â)‡Îd2 Åõë×uttèt:^îææ†¿÷éÓ§>>>,ëÆ!???.—{ÿþ}œÒÎÎFy ›‹ˆˆ3fŒz{Æ;w ÕOfff}úôyøð!ÇCݸqc„ Ptr¦NúÛo¿8qB__ßÁÁ!88xÈ!×®]Û¸qctt´R©|úô)BèâÅ‹B¡°¼¼<..nÿþýþþþEEEd29""ÂÍÍíÁƒåååÑÑÑfffoü–ÌÌÌððpgggwóæÍ/¿üréÒ¥/^ Æ !ô×_­[·.***55õܹs·nÝòôô ‘Ëå/_¾Œ=qâĘ1còòòôõõ7mÚäìì Õ @ ‘H8°wïÞY³fñù|¼ðÔ©S±±±'OžÌËËÃ!'!!BŽ&‡œü‘J¥¦§§_¿~}éÒ¥ãÆÛ³g^;þ|„Й3g®]»6wî\·eË//¯={öœ={ö«¯¾úóÏ?ÝÜÜŽ;–™™©¾oíÝ»!ôêÕ+;;»O>ù¤¾¾ÞÉÉiÒ¤Ižžž'Nüé§Ÿ‚ƒƒ¿ûî;]]ÝÐÐÐï¿ÿþ¿³¶¶vûöívvvúúúW®\iÑR �èn._¾œ?oÞ¼ÙÃÃã‹/¾X¿~}‹”+W®<sæLccãÏ?ÿ å¦É!!´iÓ¦ææf*•ºaÃ;;»ÖïXíß¿?88ø‡~À—!eee[·nÍÊÊRO3kÖ, ÕÅbquuõo¿ý„ãÐõëׯ_¿^\\¬þ‡FFF‹-:þ|Û?R__ýúõEEE›6m =z´Ô1�Ý™L&‹Å-ÚÙÙ͘1ãï¿ÿ†òùCÎæÍ›E"ѶmÛ¾ûî;2™¼oß¾7nØÛÛ«ÄÅÅ•••-\¸F£áC¥RÍÍÍÍÍÍÇŽëáá“Mž<ÙÜܦR©«W¯®««#‘HýõW||<›ÍÞ¼y³³³óàÁƒßïÙ žžÞêÕ«ËËËþùç;wÞºu‹H$Ž9ª€nkÊ”)ªg9P š­]“œ>}úرc!ƒqãÆµ¾¿‰ŽŽþæ›oÔŸøÏŸ?ßÅÅ%99¹´´ôôéÓ>l½e6›P\\œœœüâÅ‹ŒŒ Ÿùóç·xÞSQQ±mÛ¶·ý¼ï¿ÿÇ9‡³`Á‚3g΄……}öÙgÏŸ?ÏÈÈ€: ÇÉÌÌŒ‹‹{ÛZ‰D²fÍ(% 9‡R(S¦L™2e îªøõ×_«Ö¦¦¦ÖÔÔ\¿~=88xúôéL&sÏž=¹¹¹S¦LY½zµH$rss{ñâEiiiÛß2yòäI“&í߿ʔ)Ó§OïÓ§ÏâÅ‹ãââ7nÜèçç×"ýªU«<<<Ö®];hÐ |W¤££3dÈØØØåË—§¦¦N:·×�º­-[¶Lù/ƒ±o߾ƒ6¬uâÝ»wëëëÏŸ?Ê”)Pt=ÁÀÀ€Ãá455•——¼­êÙ³gJ¥f±XÖÖÖ555ååå–––ÍÍÍê·Ãb±XõÇÈÈÈ¢¬¬ŒÃáØÚÚâ¹Ð322 …»»;B¨¹¹¹  ÀÐÐÐÒÒ²¢¢¢ºº!doo_VV& q¸¢Óé½{÷ÎËË300ÐÒÒ*//·°°022*,,ljjrqqÉËËS*•nnn 77µ‰‰‰ªï=2‘(îÝ»çëë û �*L&“H$¾­L[[›J¥òx¼¶‡õ|ýúumm­úÕÙCWW—Íf›šš*Ššš===„ÐË—/år9>{´áܹs|>Þ¼yPY]K[[["‘Èd²¸¸¸ðððö†œôB�r:„œîr`"j��� ëùnt��9ŽD"éééáFd���r:‘ÁèÑ£»p>]��€óQP(mOµ �x›ÚÚZ@ÐUß—‰r��‹ŠŠŠ¤¤¤®äÁBÈ�h>™LVYYiddddd!@È�t"‰DbkkÛö¤‹àãïå���€��@³@Ã� ƒÑh42¹[œ[TS‹9��ÍD"‘(J—ÿŒK—.Á ‘r��@Ð…/Çܼy³¬¬ jBNOB$utt �x£¦¦¦6Ö*Š. 9õõõªùV�„œƒÃáœ;wŽH„~�üæ�r:žR©466†ùr�P‡çË‹ÅPà‹w���Ýì.'55U¡PàÏ•••%%%ÖÖÖ&&&íÜHnnnCCƒ»»{VV–T*U-g³Ùööömÿmsssff¦‘‘ƒÁ(..þGßûÆŒ0™LØ�è*ÅÅÅUUUêK† ¢ú\WW—ŸŸß«W/…BQYYéè訯¯ÿâÅ @0hÐ hëÖäsçÎ9sæŒ5 ý÷¡\tttqqñÉ“',XÐþSÿÆoܸ‘šš:{ö솆†±cÇâ‹H$îܹÓÕÕµ¿ÍÊÊ ˜={ö„ Ž;öå—_úùùýÓܪ2ÒÜÜ\__ëáá;�]"66ö?ÿùÏÀ [‡œÄÄÄ ¬Y³ÆÊÊêÚµkkÖ¬ñôôüꫯrrrªªªh4 Æ†œ"‘xúôi„Prrr``à¾þúë   >}ú$''¿~ý§$3gÎlnn¾ví^booïéé©Ú”¯¯/“ÉDiiiá &%%<x0&&æÙ³g9998¥¿¿?‹ÅR(gÏže2™l6/·±± ²¶¶~øðaII‰¯¯/›Í¾pá‚R©œ:uj}}ý7pJ777õŒÜ¸qcÆŒ»wïÎÊÊòññÙ¹sç‰'`'�  ­]»v̘1ªÿòx¼«W¯šššª–¸ºº’ÉdSSÓ„„.—‹:þüœ9s è46äÌ›7ï—_~Ù¿?›Íöòò 8pàÍ›77nÜM§Ó322B'Nœ'NŒ‰‰9yòä”)SòòòÁæÍ›½¼¼JKKwïÞý¶»¢§OŸ†‡‡‰DggçË—/gee………<y2""báÂ…ª•·oß^·n]TTTjjê¹sçnݺÅf³CCCår¹¯¯ottôåË—333I$Ò¦M›ÜÝÝU_±mÛ6„ŸÏ?{ö¬¹¹¹¿¿?ì�tb±x÷îÝÇŽ›;wnee%^xþüùØØØ“'O–••áó@VV”UÕ®öÐï¿ÿ>44´¢¢býúõ¿ÿþ»§§ç”)STkgÏžiooO$W­Z%¢££{÷î9cÆŒ‡&$$ „âããUw0xßÚ¶mÛ¶mÛN:åää ‘H|||6oÞicc³gÏ.—»eËåË—·g®'ÜVF"‘ ´yóæ!C†H$’id2Ù?þxêÔ©õë×Ã�@×:sæÌ¶ÿ …;vìèÕ«×gŸ}& [¤\¼x±±±1BhÆ Pnš|—ƒúöÛoù|>…B‰ŠŠêÓ§Oëw¬Ž=²jÕ*<fIIIXXXAAzš/¿üÒÊÊ &†††ååågΜ úôÓOBuuu¸¥«°°PýÙlöܹs?Þö400ˆŠŠÊËËÛºuëèѣnjãååÕ"ÍúõëOŸ>½sçÎiÓ°Çë½�� �IDAT¦AõÐå˜L¦êYŽŠµµõĉ/]ºåó1†œÐÐP¡P¸wïÞ+VH¤;v$%%©÷1ÛµkWiiéìÙ³©T*^¢££ãååååå5{ölUÇ0U«•J]´hQcc#‰D:{öì‰' #"" 4|øð¤¤¤÷Ûw-ZT]]M <xÿþ}"‘¨þJMXXØñãÇ<u@w z–ÓØØ¢ÙÚÕ°våÊ•?þø!¤§§‡û­©Ûµk×Þ½{×®]«> ›Íž>}º©©i|||ffæo¿ýöÆ(Âb±FŽYVVöøñ㜜œÜÜÜNŸ>ß>«”••µq+½|ùr|kU]]=cÆŒƒ®^½záÂ…ÙÙÙ¹¹¹ê)¯^½Š‚x@7÷üù󘘘·­‹ÅK–,RÒØsæÌüpÞ××wõêÕ>>>ß~û­jí‹/êëë=:qâD==½ß~û-;;Û××wåÊ• cذayyyª‡o3sæÌ3fìÚµË××788ØÆÆfΜ9'Ožlhhøî»ïZwPùþûï½¼¼–-[6nÜ8---À&MštðàÁààà›7oΙ3§uë™D"ñý¯ððpØ�èZëÖ­S’:::GÍËË‹‹‹›0aBëÄd³Ù3gÎ ¢ë‰§©©©¼¼¼  àmc}ªžß0 33³ÆÆÆÚÚZ###¡PÈãñT)íìì¤RiII þ¯žžž‘‘Qmmmcc£™™ƒÁ@)•J„P(,//g2™ÆÆÆuuu ¡^½zÕÖÖŠÅb›W¯^Q©Tccã²²2]]]†¿WOO¯¢¢B XYY•••á ŠÅbUm}}}U×j¬¸¸X&“©þ‹3ÒV@&Á½{÷`À�ÔáoÞÖ¦­­M¥Ry<žúáÖ‡ÃÁž[Ÿ=´µµ™LfUU•¾¾¾R©T?{ËåòwÎr}îÜ9>ŸÁu9mmm‰D"“ÉâââÂÃÃÛÛ} u³X,‹…ƒJ‹U ÅÎÎN}‰¡¡¡úBkkkÕg---Ub6›­ –––ª½°Åü½!ssó¤Ñh-¾Z]Ÿ>}`� ›022Roo}öP}P?{ÀQÜ£Á ���>IúÝ è��r:…Ba³Ùx���r:‘žžÞðáÃÛ~ ���Bο¥P(Ô;ã�Ú¯ªªª ¸L„�øX”––&''ãwº @€Š€�ÐpR©´¾¾ÞÂÂÂÂÂJ@È�tnÈéÓ§¼@Zƒ¾¿��� ä���€���¼x–ÓŽ2"“ñHÕ ¹\Þž9X��BNÇ#$é#Él}}ýýû÷GŒõ�€Óe$IëÉØ5Œ@ ¸páB‹���B·¦T*U3i*…B!•J¡®�º���€���B���ÐY!çÊ•+.\ÀŸ9N||üãÇߘòâÅ‹—/_FÕÕÕÅÇǧ¤¤|<EYSSÓFɼSBBB||¼X,ngú .\¹rö`�€¦…œÐÐÐeË–áÏyyy‹/>vìØS>yòäÙ³g¡W¯^-^¼øðáÃOQæææ.^¼øøñãï÷ç999iiiíq}éÒ¥aaa°�z÷ï±–ššz÷î]??¿ÒÒÒœœœyóæ™˜˜°Ùl‰T__âÄ „PfffBB˜1cÒÓÓñ.\¸ÐÀÀ §ÜÉ“'ËËË¿ùæ›_ý•Á`,Y²Dµ*%%%11ñÓO?uww?sæLIIÉ’%K˜L¦@ Ø»wo¯^½æÎ›™™yíÚ5œ>00ÐÅÅEOOÏÐÐH$ŠÅâÝ»wãUNNN'NDݽ{755/üòË/ŒŒÚó#i4Ú;Ço—H$ …Ž�@·9)))Û¶mKNN1bD|||~~~TTTtt4…B f0! …B£Ñ6oÞìäääááñ믿mß¾]GG§GÜñãÇSRR***úôéóã?J¥Òþýû#„ÒÒÒLMMSRR<x°uëÖS§N%%%Íž=›ÉdòùümÛ¶ 4ÈÓÓsãÆ"‘(00ðÊ•+©©©?þøãÑ£G?~¼`Á‚Ÿ~úéüùó¡¡¡gÏžU(,kóæÍ666<xð`aaaTTT;C‘ØÖìË—/õõõqe�@gû·Ý,,,¦OŸÞ«W¯sçÎ577ã…,kòäÉ!‡aÆ=~ü8##ãõë×Çß±cÇÈ‘#Éd yÈÅÅeÁ‚<ïìÙ³x‰Á¸qã<<<_½zµbÅ KKËõë× ‚ï¾ûÎÔÔ444´¤¤äöíÛµµµ½{÷Þ²eË´iÓ˜L¦j›‡f2™!!!¡¡¡kÖ¬±°°066þꫯ~øá‡ssó³gÏòùüöÿHÁ[<{ö,%%¦=�ô€»làÀ½{÷n;ÍÔ©SÝÝÝ÷íÛ·råJ##£;wÒétÍ(¾I“&µ¸°µµuww¿xñ"þïèÑ£Y,ÖåË—cbbþøã‡±cÇr8œÓ§O_¿~=<<ÜÎÎî›o¾133k½qSSÓY³fáÏOŸ>ýá‡BÙÙÙÿôG^¿~ýËëëëÿQè�€.9íaggggggooÿõ×_ÿõ×_•••/^d±XIÇÆÆN›6mÆŒ,ëÀ!###ÿþýûoݺõäÉ“ûöíkc gΜùñÇgÍšåççV__ßþo¿xñâëׯaG�ô˜síÚ5Ÿ‰'FGGýõ×£FZ·n]|||{þ6>>~çΡM›6:thΜ9ÏŸ?טQUÆóæÍ¶Óôë×F£=~üØÈÈÈÝÝ!”œœ¼zõê™3g†‡‡K$’øøøÆÆÆÖ˜––¶lٲɓ'S(”ÊÊJ›!C†¨7Á½ÇóððÀ™Þ¦§?T�hZȱµµE=xðÀßß¿®®ÎÍÍÍÔÔ´í?éß¿ÿ–/_nhhxéÒ¥ÈÈÈ:^__ÿçŸjÌÀ‘GŽñññ133»xñbVVÖےݾ}[ý¼?pàÀùóçoÞ¼9..®¹¹yûöí#FŒPõHMM<x°“““D"2dHHH‰D*//ÿᇶnݺ{÷n‡3räH‘H¤§§×öÏS(ïL�� ÁÀÀ€Ãá455•——Œ9òé$‰jPK‰D&“år¹L&#“É$I*•* *•Šo_¨T*úï‘8±L&“ËåøÏ©Tê;{îv+ …Á`ˆÅbõ‘¤ýýýSRRrssq !•JUÏ/. …‚Ÿô…B—ÜÜ\\2èÐÄÉTeH T/„â­!„TH¡Pär9îÖL Tì|>?>>ÞÔÔÔßߎ �À¿§­­-‘Hd2Y\\\xxx{Ÿå´>µ‘H$Õ,2 ¥u2"‘H£ÑþïfŠLÖ˜^jo+õüª‡Ã5j”®®îÛ §E"„Z¬jQ€m÷{�€n &/xOÖÖÖ<¯=q4,,L__ÿÆPh��9à}ìß¿¿)ûí7(.��@0’4���9���4 4¬µW}}ý«W¯4;‰*��!§‹q8œG•””@Q���„œN$—Ë¥R©¹¹¹¹¹ùÇ_---¨t��„œ®¡P(´µµ¡(��à߀î��� ä���€���¼x–�è`ZZZ;àì{ãr¹Pp—�Ðd¡ËG‹—H$¿þú+ÔÜåô´˜ Ã6ðx·áóù2™¬«~Û¹sçàÕf9=/Þhiiý£‰ŸøH555A9�9©®®î?þИiL蘙<~üx(�!§ãúúúB9� Âd2‰D¢ú<¹�´<¨���ÐÍîr¤Ré/¿übddôù矷ëÙÙÙþù§··÷СC¡¬�êž={¦¾dõêÕªÏ999×®]2dˆL&{üøñ¤I“lmm=Z[[»råJÕDï@3ïr6oÞ¼uëÖˆˆˆÃ‡·ë[·nMJJ‚‚�´ð×_mݺµ´´”ö_êk³²²¶nÝz÷î]‰D£ÑpßÑ_ýuëÖ­]Ø| »œcÇŽíÙ³§¢¢âÂ… óçÏøðá©S§&L˜P__Ÿœœ¼téR<êehh(™L^µjÕ–-[\\\ÔŸº;v,-- ŽŒŒÔÕÕ…Ò�Lœ8q̘1ªÿÖÖÖnÞ¼ÙÉÉÉÌÌ /©©©ÉÍÍ9rdLLLUUBè»ï¾‹‰‰¢ÓØ»œ¥K—*•ÊàààñãÇçääÄÄÄœ8qbÓ¦MÕÕÕùùù+V¬(..^µjÕ±cǼ¼¼¾úê«'NܹsGµ…ãÇGEE™ššúûû'$$,X°@.—Cé�ÔñùüÅ‹?xð€F£íÝ»/|òäɉ'^¿~=xð`„zˆrnݺ¥zç«®®.==<xðÌ™3ÍÌÌRRR¸\îíÛ·årù„ fÏžÝb YYYååå^^^ãÇ×Ñѹyó¦R©„Ò�lܸ1ð¿¤Ré;wôôô¦M›Öº›¨··79~~~Pn=T{ÖD"ѰaÃD"‘úB+++SSÓ))Ê€Þ¸‘ÐÐЈˆˆÒÒR(w��¶páÂAƒµXÈb±`†ª4äÕÖÖ¦§§ãqúÒÒÒ–,Yrÿþý÷ø²µk׎9òÿ¾˜ ¯�PïÞ½]]]ñçÆÆF(=äÔÔÔÈår333ÜŸÄÐÐP$µ¸ÝÁpLªªªjÝÒJ"‘ˆD"“Éd³ÙcÇŽ-++ËÏχ¨�Édb±Xý4¢T*oß¾½|ùò7žd—Ë zøð!”ž†6›mbb¢–B¡˜˜˜àÏ !¤§§gbbB¡PÒÒÒ8yòä„„///„N711a0k×®•J¥ªN÷?†xÀGNWW×ÄÄdÅŠª%999iii~~~§NŠ‹‹[½z5ƒÁ ‘H&&&ø’711qøðá~~~-^è=ÁÀÀ€Ãá455•——¨¾ÞëW¯¤R©££cAA———¯¯ïÙ³g{té‰D@pïÞ=ð�uxÀ›·µƒikkS©T×µ#IóùüyóæAeu-mmm‰D"“ÉâââÂÃÃ;rÀ›ˆˆˆáÇ?zôèùóç:::NNNPÜ���T:²uëÈ‘# ,ؽ{7BèË/¿Œˆˆ€ò��Ð)!!tèÐ!Í+#"‘ØMfÕ��9šL[[ÛÁÁA[[Š�� ät"¥RI£Ñìííߨ)���„œŽ 9l�x?ÙÙÙ]8‰»ú»>�B�@“=}úôéÓ§  ƒêmB�!� ±Äb1‹Åêò‰!ä@È�h>¹\®¯¯¯¯¯EZ B���€���B���ðÏýϳ@$B��Ð1ZtâøŸ#—Ë¡3;��€Ž"‹ñ|io9UUUýõ”��€ˆDâ{ÌsF"‘<<<ØlöB›Íîß¿?”,��€h4‘H¬««kÿŸà>ñ|9o9˜@ àóùP¾���Bd2¿eUQQ‘››khhØ"Aaa¡­­mëû<sôÿlªõÖËÊÊ ”�� „ †êÅÞ^½zyzz¶¸û)))i=ØNW*•-Bÿ4���ïF£¹»»¿xñ¢=‰!ä���xOt:@ ¸¸¸èèètëãííÒÑÑqssC™™™Y[[#„Z7v-'''ßuH$ÒàÁƒ{ʯ522²³³kgb KKË‘/==½º ©Žâv²³³1bĈ#tuu{J©TêÀñiÁÑѱgU››[;CûQ(¡Pˆ²ÔÔÔîrð)@,ãçF:::, !T]]Íãñº[WõðÓ`¡W¯^=å×2 ƒv&f2™=å<^QQàžˆËåÖÖÖ¶3±­­-•JÍËËËËËsssë)ïÊd²ââb„¶¶v;-S©ÔÜ ––‘HĽÑÈdr{.8Þg$iSSÓ „rss ñÂaÆ1™L¥Ryýúu„‹Å²··¯¨¨pwwÏÏÏÏÏÏÇɆÊb±nݺ¥úÅööö¥¥¥}ûö%‘H\.—Á`p8œªª*„ÐèÑ£étºX,NHHÀåeffÖÔÔäì윙™YRRÒyuãçç§T*oÞ¼©Zbeeåêêš]TT„—Œ1BGGG.—ÿý÷ß!6›meeÅápúõë×FÉt mmíQ£Fá3Ú³gÏðBwwwc’’’Z„ùÖU<xðàììlOOÏ{÷î©ú;vCCÃþýûS(”ÆÆF|²°°@Ý»w¯¹¹Ù××WUq&&&žžžøÞ¿©©©´´´ÞxxxæææâqQQQ}}=ÞùB</)) _Eâ&ÎÞùÛL&ûùù555Ý¿׋––Vnnn¿~ýT·•·o߉D4m̘1¡šššÇã]Q¡PàwÏ=<<H$R׿EKKËÓÓg¤wïÞÚÚÚ999ýúõãp8VVVl6ûÎ;B¡B¡¸¸¸ddd 8ÎÊÊruuµ²²JKKãp8à§š››ã·YT§#ooŒÁƒ“Éd|:Rů^½B õŸ@  „<xðošFB¡@‰D:žœœìããÓ‘w9†††¶¶¶‰‰‰‰‰‰ººº8¬ùøø&&&Þ»woܸqx_´³³³´´LLLÔÒÒÂýç¼½½KJJ}}}ñ(d2YWW—Ãáäçç—––¾~ýšÁ`à8<zôèçÏŸ'&&>}útìØ±ø–ÖÙÙY__?11ÑÐПe:)Þ¤¦¦>~üØ××WuOfhh˜˜˜¨¯¯ß»woorrr=zôé§ŸâLSSS\2}úôÁñ¦   11ñþýû¸dº¤)`øðá¸Êx<ž»»;B¨_¿~�/ôööÆg7U󯯬ªgDWW×××7##C.—wù™®¡¡!;;»¢¢¢¸¸¸oß¾"‘ÿÚ!C†Ðéô””œ;;»ÄÄÄW¯^UVVvëÎ>}ú$&&R({{{|»O¡PB=JLLLMMe2™82™››ãluÞÎÿøûû'&&â³ FÃ7+yyyø§â×ΉDâ˜1cð’ÚÚZ|5# q¼:tèóçÏ»üÅ "‘¨º¦ÑhZZZøfzذa‰‰‰£F"“ÉAOO¯©©)##£ººº  ÀÙÙY¡P$&&:99}€ùLLLz÷î Su:b2™~~~OŸ>UŽTG1‰Drww§Ñhê7nÞBII ~Æñ~²d2ÇUÛ®Ü޼Ë!‘Hd2︜–––X,æóùAÕ»¦¦&-- Ÿ¡ðQD§Ó% ŸÏ¿qãÆäÉ“ÕïUÅb1…B‘J¥ê"‘ˆÏç+ \ý¡²²²çÏŸËåò÷{¶ý×;B¡P*•Þ¹s/)//öì™ú÷>xð@¡P(•J …¢j¨ªªzòä‰\.'êYD"±«šNÇUöêÕ+ì©T*ŸÏÇ ñM€zS(¼J•|QWW׺×㇇Gf’J¥‰„F£‰D"<û$FÃw3<˜9sfmmíÝ»wår¹D"!‰ê{W7A$ñubvvv‹‚d2y̘1þù§ê¸ÃÙÄŸ»Ãï×ÒÒB¡°ÅÕ½X,–H$£Fzøð¡P($8%®;Õõ @<xpiiieeewدÞ(==½¬¬L©Tª_–á=P&“I$ …"‹ÁÇ?ÀYMMM]]þ"õÓ`bbb}}=™LÆçÕ‰:;;[ý—«b®ƒÑzmûO,|>_=ËD"‘Ç㥥¥1¢#ÖÔ˽µ …âm Þûàoc›èÒ¥KAAA!USXëï%‰cÇŽÕÑÑ!ª†¦7þ¼±cÇâ î0~ú%É{´bwÏó‚§§g‹Q3ˆD¢\.W*•øC·m[¯ªª¢P(S§N-((ÈÈÈh±vÊ”)gÏžUoÚ577ÇŸ+**ºÃï¿xñâÔ©S¹\nbbb‹U#FŒÈÊÊÂvðEÏÔ©Sñ*Ü*H&“û÷ï_^^ÞÍßÄ;R ^¼xááá1uêÔ”””òòòÎ>F‚•••‡‡¾”OIIQžo;ä[õAUø)ÆûÝâ´>§±Ùl©TªºTíÈC£Ñ”J¥D"ù§ØÍ;¨èèè\¾|™J¥\ºtéi>ù䓇r¹\2™<a¼B¡Ðét‘H¤žòæÍ› Ý$× …D"µø…=ÝãÇñ'ƒ!‰X,Ö AƒÎ;Çf³½¼¼ž>}Úm9™L®­­=wî\ß¾}³²²ÔwÂææfõÄÅÅÅ>Äw¥Ý$ŽÒéôsçÎŒ1Bõ€/—J¥ê?R$?gŸŒ\]]›šš^¿~ÝÝ*Åÿè4˜™™ùôéÓÑ£G …Âöw x?¦¦¦fffçÎCá¾sm£R©­» (•J¼‰Ô¢Í­a@ ‚7ƹêêꊊН‹¾È‘J¥"‘÷cîÕ«W}}ýëׯ¹\®ŽŽ‘H$mŒÀÓÔÔÄ`0”J¥»»{ëiɵ´´T h¡ÆÆF===--- …‚OÙÌ€rss B}}ýÛÒ466êêêâ38—ËÅÝí \]]KJJ”J%>­s¹\]]]‰D úõëwûöí.¹³ijjÂUf``@&“³²²ø|>…BÁ ›ššÔ¯ƒÔ«X¡PtÛøD§ÓµµµÕ3âêêúèÑ#???|sPWW÷úõëþýûs¹\mmíÖW]NOOÏÖÖ·v¶è¨æçç—œœlhh(—Ë$‰T*ÅÙ´²²ª¨¨è¦üìÙ3mmm.—«¾—9BÈÐÐDøÇ³X,---|K§£££z#¢¡¡¡kã¨B¡hnn644Ô××·µµmO :Î`0ÌĮ̀TjMM nïìß)‘H$ .7¹\N¡PÞØ M*•ŠÅbCCCSSS ‹§²ºº:¼6›žžþO=‰ô¶û9333}}}÷ÆÈýCN}}ý«W¯pÏ™ÂÂB|‘’––æå奫««T*ñYU"‘¨2ÙÜÜŒk"==ÝÓÓÓÆÆæÞ½{ø©TŠ/ ø|¾¥¥¥‘‘Qcc#>ö’““‡Š{¬án$"‘H{¸\nçõ%MJJ>|8BèÞ½{¸ALý{qhJJÊàÁƒ †L&{ðàA¿~ý^¿~]]]]YYéææÖºd E—Ä\È= «««333B999ÎÎθSRRð�ãøûU\[[Û­ž……B2™ljjÚ:#êçb¼ÏSSS6›]^^Þ­BN]]‰Drss+..Æ]êëëqcEuuµ««+BˆÇ㥦¦ÖÔÔà”¡ÜÜÜnÒâîÝ»#FŒhnnNKKÃG1¾vill477711Á²X,¾wïÞ°aÃðŽ„_SonnîÓ§¾VCá§>]»G=yòdРA555©©©øòWu:Â5¢T* EMM ÞµBæææùùùnnnÏŸ?oz;Cmm­jOÈÏÏ×ÑÑa2™ßp(•Êêêjõ£¸¤¤wZS?Šoß¾ýÉ'ŸàÚ?7¸KˆH$j£çj}}=Ç{ã–‡ÓÔÔT^^ž™™Ù¿ÿŠŠ cíýnxpV��èÚ6�&“‰££‡‡ÇS½©ò †««+F«ªª’ÉdöööøCÛenn®§§G"‘ðHÒqqqááád¨��Ð0 ÅÜÜwÚ–Ëåµe¹\^[[Ûžûl==½Ö¯`CÈé0<¯›¼ �øÈ577á—ê*++;ðU¥RicccccóΔd2¹uk<„œŽ 9Ým¨�ÀG‹Ëå>þ¼Ã7K&“I$Ò;[ÕªªªˆD¢±±ñ»CŽD"iÑ;���ÀðËûm§©¨¨ P(í 92™¬wïÞx…ž‹B¡”””à¼@FºOF¤R©••UΙL~ýúµD"ŒtŸŒ”••‰D"ÜŽéXxðˆŽêÂþæ†5‹ÕS{ÖÔÔ$•J{zF¨Tjss³X,†ŒtŸŒðù|¡Pé>øE‹žž¡PÈãñºUFˆD"ž÷³c¶7‰���>P�ûÈóþüù¨¨¨w&»zõê–-[:êKïÞ½ûÝwß½mmš' €žnܸqm ˜ò6Ož< iúßÿ}×®]PÚè#ì±& ñhx0† &à6J‰D‚»aP("‘Ø"™P(Tu©À¯5!„èt:‘ø?1[.—ãa¤¥R)•JU òŠ·†›DB>>>ƒ BI¥R P(d2ÞšP(Ä#g¨ýó/áq¬©TªT*¥ÑhªÑ9 ™L‰DøqÕ@תAn( K,ãþŽxTïÖƒÐýÉd2…BÑâ𬫫SlÐÍ!��:IDAT(@uxâ£"ƒO x.|ãÃÄÍÍmÇŽx³R©w¦ÑhªYð%ªˆ@ €î¬ã]Nuuµ——×´iÓð@;ñññ‘‘‘¡ï¿ÿþÈ‘#‹-ÊÎή®®5j”——×ĉ[ôgçr¹aaa^^^^^^©©©-†h½víÚ7ß|³wï^//¯#GŽà¡28Îøñã½¼¼|}}ñËÀ·oßþöÛoB;vìØµkך5k¼¼¼îܹ#“É|}}›šš&MšÔQY®¬¬ôòòš0aÂÍ›7ç΋:räÈÆ·lÙrõêÕúúúyóæáìàœ¤Réßÿ—DFFâãdÉ’%—.]š5k–———jê9�z–?þøãÛo¿ŽŽöòò:uê”jÀ½ªª*ooïñãÇãƒýÚµkaaaxUhhèµk×ðQ<nÜ8ooo<(TzzúÂ… B|>ÇŽøx¹zõ*㸪ªjРA^^^³gÏ~[(9šã“O>yðàAffæ/¿ü²iÓ¦kcbb–-[æêêêïïãÆÌÌÌC‡ýðÃêi~þùç!C†dfffff®X±¢õ¨± t:=33óåË—xnÊ©S§=z433ó?þP9­røðáÀÀÀÌÌÌŸ~ú©¸¸øþýûzzzªyýþ=ŸÌÌÌß~ûmݺuª…çÏŸwuu4iÒÒ¥KW­Z…³ƒ§ ÍËËÛ·o^¢¯¯ðàAü'QQQ™™™~~~pØ€êúõ놆†™™™<PM¸°hÑ¢ôôô£GªÆóomÊ”)ÇOOO_¼x±úòcÇŽ‘H$|¼$%% „,X‘‘‘™™¹iÓ¦E‹A±Ô k˜Mlll‹…^^^êK,--8Ð"Y~~~rr2¾Ñn½å &ü£FÞU«V}€“¸……ÅÁƒñýBhÞ¼y3gÎÄŸU}ªîظ\.Î`qq±ªçÌîÝ»à€=Ú´iÓ,XÐbá•+WÞ8å]qq±®®.›²ÿþ¥¥¥—/_~ÛÆwîÜ©jíÀGŽ@�Bοrûöm<M½››Û{L5ÑÝ\¼x_îá©éBû÷ïWÝBƒŠ©©©žž^NNÎï¿ÿîàà0tèP„О={V¬XG%;vlÛ[¸qãÆñãÇ•J%—Ë}ÛLer>.iii¾¾¾m'knnNNNö÷÷W_øÕW_Íš5 _µ9OŸ>ÅsöuÍÍͪN[ذaÃ!CBñññx‰³³ó‰'BYYYÝvz`�ÞCnnî‹/ðÈÿo3hРììì3gΨ/¼víZdd$•JíÛ·/¾â|ãŨ›››¡¡aHHH~~>‘H|öìYDDûÇr¾üò˃â©£Û˜£ó³Ï>;vì@PŸ§6lXVVÖÞ½{Buuu­o¸\îßÿœœllllkk‹š5kÖ… H$’B¡ÀðÛ&‹;öùçŸwH–.\¸wï^¹\þÆ7¹ÆÿðáÃÇ#„ðœ@l6{РA8ƒ|>ϲ€fhhhøóÏ?“’’,--ÛxÃßÕÕ”ìââ‚—ÿç?ÿ!‰óçÏWOÙ¿ÿ¤¤$|¼466âÆç… îÛ·!$•J=<<:ðѬø¸º„††* ±X¬¯¯›tÝÝÝñmr@@€j÷úöÛo‰D¢X,ÖÕÕýꫯB}ûöÅ÷:ãÆëÛ·¯X,‹ÅË–-ÓÑÑiñžžžcÆŒ‹ÅxŠ­¯¿þZ[[[,S(”åË—#„ìí탂‚B#GŽT==úòË/Ùl6BhÍš5ï1·÷Û¬[·gdÉ’%xÉÀqO„ÐܹsÍÌÌpvpÿSSÓ/¾ø/ñöö1bBhêÔ©ÖÖÖøOV¯^ ‡ 衆 2räH±X<yòdGGG„Ð’%K BHOOOõ¨àÀt:]KKK5Óó7ß|£­­-—Ëñu–––øi¨··÷ðáÃññ2wî\ „Ð÷ß/‘HÄb±‘‘ÑçŸ.•J===¡{ÃmzzzøtÙsÑh´ŒŒ ©Tú!3rùòå„„„Ý»wwà6©Tjff¦X,îÛ·ï{üù† ðK¬Ož<‰ŒŒÄžw‰™‘îƒJ¥fee …Â~ýúAFºIF²³³ù|~Û-fñññ?þùçŸß¹ÁGݹsgüøñmo°32’““Ããñ>ð÷¾ã¾ä¿Þ¨¦h0`À;‡õÌÌ̤P(ýúõƒ)Ú>.ƒÆ÷s,kÕªUP �´íñãÇÿý÷Ô©S{úµQ÷!§#y{{w·žÄ¸Ý@WWWÕJ�ÀGhĈîîîïLfee5kÖ,Üì>PÈ¡Ñhm<]ïð ,8#ºººí™,ïgdâĉm@F #ê‡gWÅÿ(#T*µ»ÕÈ;'dû·!'===##£§‡SÜÚ¨1yùò%d¤[e$332Ò­2’••¥ÉÎÎîV¿JGG§=7ˆïrœ{ú}%FËÊÊ’J¥NNN=:#ø‰¢D"ÑŒŒˆÅbggçžž‘ÜÜ\‘H¤ …ª¾š=7#yyy@32Âçó»Uï-Ü}�.×Y!‡D"õô÷êi4™LV*•==#xÈ[¹\éVÑ€cg„L&CtŸŒP(”îV#8ätØÖ���ða���9��� ä����r���@È���!���€���B����!���„���r���€® 9xÚÐàºÐ€ј j²ÞÛ›G’&‰ ¥GgL¡PH¥R‰¤‘H$P#P#P#o£T*5£FpFºa…ÂÎ 9ÏŸ?ÏÉÉéé—<b±X©TjLFrss!#Ý'# …"//2Ò­2’ŸŸé ºººýúõëÄÓ·oßn5GÐ{ ÑhR©´§g„J¥fffŠÅâ¾}ûBFºIF²²²„BaG„‘Ÿ‘ììl>ŸïææÖÓ3’““ÃãñºUFð|9%%%³5���|˜�E����B���9����„���r���@È��� ä���€���@È���!���„����B��� ò摤I$™LîÙ±”HÄÿöôŒH$ͨœ¨¨¨‘žU#ø\Ú¹!§©©©²²²§‡Óºº:"‘¨©­­ÕŒŒÔÕÕͨ„fÔˆR©ÔŒQ(‡£ùg!‡ÃáÈd²ž~½ÐØØ¨P(är9d¤ûdD.—kFFd2™B¡èéihhФŒ(•JÈH‡# ÃÔÔ´CNŸ>}`жn¦hë†)Úº[F`жÎS´��è‘ ä���€���B����!���„���r ���@È���!���€���B���9����„���šäÍ#IS(:Þ£3†';"“Éš‘¨¨¨ÈH— rJJJ„BaO§ÕÕÕA$AFºUFÄb±d!¤©©©Q*•‰D32"•J!#B¡vbÈ¡Ñh £G×…Báñx2™ 2éà–2™ÏçK$Èd¤Ã3"D"Q·Ê‘HÔÒÒêÜ»6›mgg×£+F£‰Åb©TÚÓ3B¥R%‰X,†ŒtŸŒÈd2¡Pé>‘Ëå|>_2¢P(x<^·ÊLÑ�� G‚���B���9����„���ÝŠ���@û …B.—ûÎ4 B��€÷§P(Š‹‹óòòÞ™ÒÌÌ B��€÷'—Ëß™¿ø!��À{"‰ol1S×ÔÔT]]mll¬££!��À{’J¥‰D©TÊåò·¥)..ÎÎÎ6lXë=Ö���t.—[RRbjjúÆg9r���ü2™ŒD"á©Zkjj‰DVVVo\ûÿÚ»û &Î?à»yÝ$$ò" D+Á‚â[¥B5-õm®Õ³*¶Tí µ­öjéØjÇŽéMÅÞàKǶ?Óž×üN¬Õz¥ž¢Ä/ÖˆC‰„ Á „MHBØÝûcor4"‚ äûùK—ÝÍîód÷›çÙgŸ/„���£CEQC6qêë냃ƒ§L™2ä†L^pÜÄB§âp8“ãD F F FàDÆ1ÀÜ¿Ã0·Ûíõ'§ÓI’dRRÒƒv5DÈ™1c†H$š)Úd2Š¢“àD¤R)œˆ¿‚ “ãD(Šš'39NdêÔ©~x"C¦Œ£ ^‚ãxee¥H$‹Å£9|>ŸËå3a¢ “¹Â‰À‰ø—Ë… œ!IrÈ…|>ŸnÖxš>l6;55u˜]Á³���ÂápxâÃá8wî“É>…(„���‚¢¨   ƒ <;;{øM ä���xD6› A‚ NŸ>-º>„���ŽÇãY, Ã222 ä���Cv»½¬¬,22r$+1bm``ÀétB9��@þ:bÉdÞ?­g||üýÕ˜Læˆf’v¹\.— J��À`b±X$±XÞcÉ’%C*‚ ¼æÅay¥‘<ÿ��h˜Lfpp02Ê— 9ÎC‹Å²Ûí---P¸���<D"ÑHÒ²=”wûÈb±ôööÊd²‡nIwç¡(z# ��Àæp8†œjóA †aA<ôI ƒÁ Û7¾9‚„††Î˜1cøæ†az½Þår) Š¢îF��à‰¹~ýzRR’W/ÖC‰H$¢oàtâµaîù<~Ç÷!gøCäóùtTìêê¢'¢ª��Æ‹Ñhœ9sæh·"Âáp°X, Ã8ŽËåë›ùHCŠ¢AAA$IÒm7’$‡œè ��ÀDA7q‚p»Ý‡Çãaæp8Æ®ãjD!G(¢(j³Ù(ŠU_!���ÿ<A8N—ËÅãñEQ6›m,Ú 9€Åbá8Á��&wà¡(Ên·£(*„B!‚ ½½½¾½ó1áÛív8G$9N«ÕJ’$Ä��Øc³Ùè;¿P(d2™>œ`ˆVNss³ÉdJHHˆŒŒ ‚1Ð��€ÚÚÚúûûþùg¹\þЬr Åܹs5Mee¥B¡ …‰„Έ���`Òëîîv»Ý.\‹Å2™léÒ¥cØÊ¡Íž={öìÙµµµƒaÚ´il6;&&j��&1³ÙÜ××WSSÃçó#""ÒÓÓQõáþÒi6þ|A®_¿NO/Íår¥R)Ô ��L2‹Åb±hµZ&“>þüáSJIÈ¡¥¤¤$YSSÃ`0p …x��`r°Z­mmmmmmAH$’øøx±X<FŸ5Ò¡ cáÂ…N§³±±Ñl6wuuuvvFEEAm�Àe·ÛoܸÑÝÝíp8bbb¦N*‘HÆôG7 ðäädÇïÞ½ëɦÓéîÝ»•��ãeT <úúúZZZ EhhhDDÄ8Î!B›ÍæóùÃlC?V²Z­E±X,‰DÂår¡Ê�`¼ÄÆÆŠÅb¯|hÃCQ”Íf§§§?4‡´Gx‡©TJQÔHfv£Ã’Ãá‹Åc×ñ��`$mê˰°°‘Üð}5ù Ë«}ódÚV���“Éœá/!Ç`0|÷ÝwPF���|eÑ¢ES¦L"äDEE-Z´ ��€OÐ`<ýr 9t^R(#���>aX¿'äÀÌi���ž9���žILÀ`0ü²êÀL¿í'U3v™qýúúœh©Càz™!‡Åb ÿþé¸ëéé±Ûí Ð.' Ã8ÎøƒÁ`‰D–AEÑ    tÀV«Õf³à5Âårýùuø®®®?yNï_¿¡‚ Â묷··ººð¹sçfsØívWfX£ÑxñâÅÕ«Wæ$#|5{Üá8^]]Íf³ééçáñ‹¥ªª*:::>>BŽ·þþ~f<õí]¯±±199 T.—k¼º¶ªªªúúú¶äI’œ§ßÚÚúÇÌš5+`kª¿¿ßèt:ƒÁí'ÇÃ���@È���!���€���BŽO?~\©T^¸paT[åææ*•Jÿž0i|üñÇJ¥Òh4z-///W*•G¼póæÍJ¥ÒétB¹=Š¢”ƒ<hM§Ó©T*7oÞü ¶nݪT*y°Æðé§Ÿz* Çq¥R™›› !Ç©Tª}ûöi4š·ß~»¢¢bäjµZF㇣'O>ùäĉ&++Ëb± þ“ÕjÕh4íííƒÞ¹sG£Ñøç°ø‰E£Ñôôô¨Tª¼¼¼#GŽ8p`ÈÕ‚Ðh4wîÜyÐ~ FÆÚÞ½{¿þúë;v¨Tª{÷î-Z´H£ÑhµZ9þûƒÎjµ¾ñÆF£qñâÅv»þ‰'“ÉÌf³\._¾|9I’?ýô“L&+,,Ü¿llìùóç=‘ÆétÊd²ŒŒ ú¿?üðƒL&ûòË/ábxL$Ivuu•””F>ŸOmii‰Ý¸q£çÍg’$?ú裸¸¸ŠŠ ÿ>Äb±¤Réš5k ¿øâ‹Ï?ÿœ$É>ø ..N.—ÇÆÆÎOQÔ¹sçbccåry\\܉'(ŠÊÉɹ}û6‚ ôËgZ­Ö³ÂgŸ}€s øÜþýûKJJŠ‹‹W­Z%•Jkkk/]ºä©‘óçÏ{ üÛo¿¥(Š$ÉåË—Ëår¹\žœœLEQ/^ô¬vìØ± wM°sòäÉÝ»ws¹\¡PÈb±Ö­[WWWg³ÙpÏÌ̼téReeåš5kÜn7ŽãŒŠŠZ¹rå† ®]»æÙ ›ÍîííµZ­ýýý‹e```TÙ[Áƒš8jµšÇã …Bƒ‘ÐÝÝ=gΜ¸¸¸mÛ¶mß¾^mß¾}_}õÕ¡C‡JJJ¡Ü|x0 s»Ý.—kÏž=ß|óÍáÇõz}TTÔÌ™3=™²***rrrV¯^­×ë_ýõ÷ßÿÌ™3*•*11A7ntuu¥¤¤( ½^_XXxèС¢¢"(ÞÇär¹Ün7Ç£o8AAAB¡þÓµk×6lذråJ½^¿uëÖ;v”––®Y³¦²²òÔ©SMMM}}}Ë–-«««{ùå—333õzý¶mÛòóóOž< !gÌ™ÍfN‡ãøà…555^«½óÎ;[¶lñZˆaØÕ«WµZí† ~ýõ×]»vmÙ²%//®Ÿhoo×étƒ“�"’ššzèÐ!¯5U*UBB”ظÔ­··W§Óuww?h[§Ó©ÓéþüóO(ÆqýÔSO-[¶ìæÍ›eeež§×8Žët:³Ù<!M cíééÑëõµµµµµµ‚744ŒvD�›ÍNLL¤«M"‘H¥Rør?&“ÉÔÑÑ!—ËU*•J¥ okkûý÷ß¡dÆ]IIÉ÷ßæ5I]EEýckÁ‚!!!÷o«×ë=+øÏëëƒîðõÕW322ÁÙ³géåÕÕÕžz‘H$rÆJUUUQQQ^^žçéèÚµkß{ï=úßååår¹Üë‚iii¹?‰äèÑ£iii·nÝÚ¸qã›o¾ _îÇtâĉÒÒÒǯ[·Ž^2cÆŒ—^z‰þ·ÅbÑh4^›ÔÖÖzµSO:�êëë¥RéôéÓé2/((ÈÊʺvíšÍfóê@ÎÎÎ...Öétz½^¡Px–SuùòeAfΜYVVÖÞÞ^__?}út(ÞÇ}óæÍÔÔÔ+W®  ÔÕÕ™Íæ#GŽäååýøã¹¹¹ô˜ÏôôôcÇŽ577755%%%AÈjµ:)))$$dÉ’%ô’††µZm0ÒÒÒÂÃï¼téÒòòr¸ Æ›ÍÎÌ̼uë–Z­ö<K›={¶\.¯¬¬$IÒjµB)ùŠÍfS«Õ·oß.--ݵk׺uëP‹‹»zõ*Žã{÷î]°`AJJ ½rxxxjjª^¯W«Õ§Nêìì,,,ŒˆˆÈÈÈhjj*--­¨¨ÈÊÊÒjµjµºªªê·ß~Û³gÏ´iÓ œǦM›H’,**¢(*>>>??_©Tzj$--Í`0¨Õꆆ†yóæI¥Ò+W®ïܹóÅ_<þ|vvvhhèâÅ‹F£Z­>{ö¬Ñh<pà@TTÔ*&ÇËÏÏw¹\8Ž[,–¸¸¸ñ9&“Íf 3@Óív3Œ´´4Ï/2Çccc›šš\.×/¿ürúôéÌÌÌíÛ·744œ9sæµ×^KJJêëëÛ¹sgBB‚ÕjU(/¼ð“ɉD2™¬²²rÓ¦Mô#Óáuww·´´DFFN¬ÚõUä`2™ƒSÉÞÏápˆÅb¥Ré)Ÿžžžyóæ´··K$’ÜÜ\6›ýÜsÏ­Zµ*,,ìîÝ»o½õVHHH|||FFÆðÃ7´Zm__߬Y³&\ò˜Ç„¢(†aE ù$fðj‹%!!Ád2¹Ýîµk×®_¿AÄÄÄÐÐÐÖÖV“É_XXˆa˜ÕjMIIY±bErr²Éd2™LÁÁÁï¾ûî3Ï<ƒ È’%K\.W[[ÛÁƒ•Je{{»Édb0999«V­þh{zz CDDD�vÁ±Ùl‹åv»:®oΜ9AAAt¥$&&á8¾páÂÁ5"‰¶mÛ–’’òì³Ï¢(j4M&SZZZAAAHHȼyóèÕ‚‚‚òòòÒÒÒ†ÿÄŽŽ“É$•JÃÂÂÆ«p‚ I²¶¶¶¼¼‡ªÿq¯ûžÑÕÛ!&:<Q÷ ãp8|>ßáp<«šóçÏonn¶X,(ŠÒKN:µeË–?üp÷îÝCnÒÙÙYPPÐÝÝ­R©FòÍÍÍW®\INNÀä|>ŸÃáØl¶ñšIúìÙ³]]]ëׯ´ä(Š1!z Cyyù¬Y³0yÇãr¹v»Ýg’®¯¯¯©©IMM¯ä|>¿²Ñ|¯»Oõoù¿œ;Ãp“ȯzÆoí‚z /@¾½½½{öì¡Ç‰Bc��Æ6ìY°ßÚ=ÁɃÅB„Á` B#¹6‚´LÄóÙ·oŸÍfó4qY°`AIIÉÓO?ý †ÞÒ¥K×®]ûüóÏ÷��Æ& ô#O¥®®þûç“¡s|ÅŠ^Kd2™L&¦üÊ+¯À÷���ž0˜I���„���“‹u¬i4ÿ|eæÖ-//okk—ð|V«U­VûÿqÂ5rùòåÖÖV;ªñh:BN]]]MMßNŒÊb±¼æ E•••µ´´ŒWÕ0Œ€-y»Ý~òäɉ2‹sÀ^#‚\¸pA¯×ûçí‹Åb ]5¾PLúÞ™áÚZ0~¯÷r���L>|>ÿoõ­éh¾ùÿ²žå���xB ä���€��`rùËðƒÁáp P���ø„פ½ÿr¶¨•ŒÑu8Q(&���©±ÝÞåF»¼!BÎ�7¤¡—di;ebèm��𸪴·p O4TÈA„ Ú}ÿy}¤©ÎyÎv®ò¢�@À‹w`Q.ûˆò+šœ|6ö—n3ôëoþöåµéy_ü_[§ßévÚGøÑÏ„õ&‡ôB��@€¸Ý7¥Ú<àrŒde6&`q0AðÎÖË_}üÑ«Y¨Ùlž>káßèFûÁNÜ’.u½0Su���¢¢ó?ÆQ2ë2Ôÿý“lCãM–H$úöHqþþNÍùŒ+†KG¸ Âíêw9xP�� rtÓ¤á­.»õÊñOTÇ‹D"”¢(·Û}þ¿Ër6¿3[¹pmþwD‘á­ÄÝu���¹¨›Ñ×Ó9Âõÿ¡þ×»šËªãG²³2Ùl6JÏC700€ãxégò¶½?òÏF)¥¨�� 6…2F>iÉ¿ÿÓêUB¡Åb!ò¿ôÁ¡"õN`����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/2masssort.png������������������������������������������������������������0000644�0001750�0001750�00000446746�11332127303�017106� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��Ê���‰* è���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ*÷ãÛ‰�� �IDATxÚìÝw$×}'øgó¥+ï«Ú›ñƒ˜@IˆE*tÒ‘º¥¸:‰¡?$ O!1(®„B« ÆéB!¥»Ø ]PîtZR$@ <0~zzÚ{請ªËûª¬t÷GVvW¥]Ýõ7&&ª²óÕ'_v×ûÅËÌÊ‚¦i�šÍf2™Ã0M�‚à0‡9Ìaó_/†aB|Ï£±®ëã÷ÚÊ*ð½pKKKáp˜ã8���$“Ép8\¯×­5~äËýõK#«Yýg?úØáïû0‡9Ìaþ+æ;¯\?Ó!þÒ³g­bð€c¸iš_ýêWÿäOþÄ0Œöå?²áÛo¿mÆG>ò‘çŽ=šL&Ãá0i6› ø�AÕjõí¹µ¥þ›þU! ÆMM³cŒTM�`„„ª®�B�M7��#Óºa��(Ɔaè¦ �àÖtkâ8JTU7 �`”4UÍ�ÀQ¢¨ÚO�5 ݸ %DÕÞ …�RrO"ˆþuP‚Qó.#J Öÿ%Q`í_…¡AÍV¯¢š®[ïƒJISýÿ�ºÿGµ‡ZL!�þ¥Ð;Þ³Bmïíó“@„&Êú�²Ùl©T‚{†d¬­­=`„„°^¯3Æòù|¡PxÀ†sssc§Ó™ÉdH2™ ‡Ã¾¡– !Hm¯OÕ»õBèwËgu¿14Œ<=1ÿÕÑEŒPo,àvŠc3k££½�àÌrœ|úHg±\[ÙJq_8Ù·±“ÙNå9Jž<wdba3W¬0Ž<óè‰K µ†Â3úñ§Î|ÿÚ¨aš‘ÿУÇpu BèsËçŽu¿ÞBÝ=±àÕÑŒPOÌïqJ-´'!œ¶ÐÁÎbµ¾²¹K ¾pªo3‘ÝÞÍq”<ynprq+[¨0Ž|øÑW&ªu…gôãOžùþõ1Ã0d‘æ±ß¿: !ô¹¤s'z,4âw÷u¯Œ´P¯K›^%é‰ §—â„àÓƒ•jcÙBOön%sñÝGÉ N-ų…2ãȇÙGêÉÓ/^× CÙ3´P¯K:¢÷µ¡) íï ^YÀuGý>w 쌧—¶,´ZS–6’”àó'{㻹x²…N/Ç3ù2ãȇ9~mj©RkðŒþÔ§_¼1®ë†$°>~ò uJNõ¾:4… \]áË·ç1BÝQŸßã›ZÁéS‚§·Á§:ªu=ѳ*l%³%ÏÌ®l§ï@9úì“§_¾1¡éº$°^<õÂÕ¡Ç)>rª¯…ú]ƒÝáK·çBÝ_ÐÛB»Â%Ó‹›„àS±Z£¹¸ž¤?|¢'‘.l&ltu'+1Ž|ðÂñSKåjƒçè³OœúáÍIUÓEž{ö‰ÓÏ[¨C|ôLÿ+C“Âßu¤'rix!Ôñ†|®±I 1ŽN/l‚OöÇꊺ¸ž ?|¼'‘i¡Ÿ˜_ÝIµÐc7¦VÊÕ:ÏÑ=qê•›Sª¦‰<÷SOžùÞÕÛB·C|ìLÿ+C“°Ïy´7úŽ…†½a¿{lrc4Ðâ-㓱†¢.¬'(ÁçŽwïfK;Ž’ÇÏôϯ'SÙ"ãÈÓç M¯”*už£½x굡©¦ª Œ~ü©³6*<~vð‡CÂÏy¼/úö­9„PgØ ¸Ç&–1F!ç¦ç7Æ'ú£MU›_KP‚ÏëÞ͵ÐÇÎô/®'wmôÖôj±Rã9úÑ‹'_š¶ÐO|àìw¯Þºeቇ_š€½Îý±·oÍ"„:ÞhÀc¡ýA‰gm¨>¿¶C ~èXw:_^ßNs”<vºi3™Ì%8txf­X®ñýÈÅ“oÜšQšê>  Ë!<ynuœèxkh!ÔòÄBÞ±ñ%ŒQGPùé¹u‚ññ¾¨¦ëé-pü„5¦½×’óà­ì‘¿íƒ[…BÁëõ†B¡d2IëõúƒÏolš��ýÛ­7^—xz°ãµ³áÏÙö^]Ƙt†=NY¸5³A0íïò›&˜^Ù¡„ï Jµåx†£ÜÙ£±õl<Uä9îÑ“Ýã‹[ÙbM`쩇úÞYª6T‘gÏ\8òÂ;º "ÿó/¼3!öºÄ3ƒ¯î¡ßåÑ% u9D íëô›�L-ïPBõ… •úòVš£ÜÙ#±l<U`÷ÈÉî‰ÅíL¡&0öäپˣK•º*òìÃŽ|ÿÒ¤f�Y>x~ðù·Ç!ħxöhÇ«×gÂAŸ³'ê¿4²„é{Üqhz`Ò×€N.íPB÷†K•Æ’n&ó[»ÆqœèžZÞNªcOží½2¶\¶Ðóƒ/^žR ü/±Qá¡£]¯\ŸA½Žž˜ÿêö8[ho‡!4±´M =Ö*UK›iŽrg£[6záD×Ôòv:_å{âLïÕñ•r­)2ö¡ ƒ/^™Ru ü‡9ò½·Ç!Än‡pîx×¯Í „^G_,ðÎíEŒH,äöºä›Sk“¾?Æh|q›z¬'T©)‹›) § ›É<㸠ǻfV)½6¾Rª5Æ>taðå«ÓMÝ”xþÃýÞ[cú°…Bð9ú:ƒoß^Ĉt„Ü>·|cjÍê)!x|1N =ÚªÔ›‹)ŽÒÓƒ±íTÑBÏïšYM¤rž±‹gz¯O®”ªM±ž|ùÚLS3EžÿÈ£G¿ûÖ€ØãΟì~ùê4‚Øïu tß^°zð8nL®Lzc>JÈØ‚…kæ‚…Dw2Å„…vέ&vsžcÏôܘ\+V±žxåúŒ¢"Ïä±£ÿüæ(€Ø#óœì±Ð€Wì½e¡AWÐë¼>¹J0é‰ùm¡GºƒuE_ßå(=5MfJë‰㸇uίï&³ežcŸé¹9µV¬(cO?<ðêYE5Džÿ¨…ì–ùGNö¼te BðÈGºÃoÞZÀˆDƒ®Ïy}b•`Òõ1ŽŽÎoYh£©µÐþh2W^ßi¡ -”{ütïÐôZ¡Ò°Ð×nÎ5TÃÚ½ßyc�ì–øÇN÷¼h£ÇzÃoÞšGˆD®°Ïumb•`Òõ Œ™ß¢„v•¦6·¾ËQz²?šÊ•×v²ŒrçŽw.nî&2ežã;Ý;<³‘/7Æ>ðpÿ7çêM]äù<zäŸß3rÉüã§û^¼<!ö{¤c½‘7†æ"‘€3p__Á˜tG½ÏÌmRB»MMŸ[Kš�¾×zsÏ’c˜ WªC÷!ñ8„w©7åZ³¡n™±–ä+Šª—HÉ^É�KKKŒ1ÒÞÞ0Án¾ÊòHí¯ØPõ\¹!óœÏ%î¹{%!(r„ç0BPÕŒr]µ¦·í#<%È0Z‡,îøÏa‡@ Õ¦5m|È<•xÒ¾¤Pm*êhÎ쑹|¥ÙÔtžÒSý‘×n-!„ƒ^¹3ì¹<±Ž1‰.Y¸5§„ôF½� É•]ŽÒ#]þb­¹Ï1Ž;ÙÜJ•â©’À¸‡£Ók©L¡.2öȉŽëS›åº*ñì‰3Ý?¼¹¨êÀ!òOžíùþ•9±ÇÉŸêî¡]aïåñuŒI,àt9Ä[³qJHOăvú˵ær<k¡ñt)ž* ÷БÈìZ*]¨‰Œ]8Ñqcz³\k¡¯-6uSø§Îö¾pe@ìsðg£¯-!„¹;â½4¾f¡§84'6:±œäìòWêÍ¥x–QîD_p;SÚÚ-òº‘Jç[èÍ™x©Ö”xvñt÷«·–›š) üê}áò,€ØëàÏF_ZD<ROÔwil c 8=Nih6N0éŽzÁ6ê«6Ô¥­,£Ü‰ÞàN¶b¡g#ó™T¾&2öÈñØÐl¼Tm¡¯ßZV4Sø§Ïõ>o£¾rsAìwK½1ß;ck‘hÀásË7g¶&Ý!d|)É:Ðé«)ÚâV†Qz¢7˜ÈV6÷ЭL*_»p<vk.^l¡]¯/+ªa£3�`¯ÌŸ;k¡©/ægt#iC»"Žñ¥%t ÓWoj‹›FéñÞàn®²‘,ðwf0¼¸•ÙÍUÆ.‹ ÏÅ‹•¦Ä³‹§ºÞ¼½Ü°Ð‡z¾wy�ì‘ÙÃG;~xcBìóHþ·m4à‘oL[¨›ãèØR‚Úßák4õ í îæ«-t ¼¸•³ÐóÇb·v ¥…ެ6š-ôù˳&@™?¼ãe u‹·FV1"a¿#èu\ŸÞ$˜t…Ý<GG-Ô«¨ÆÂfšQz¬'˜.ÔÖžãN„—·sÉlE`Üùc±}üT×Û£«õ¦. ülÔ-ól4àtßYÁˆ„ýrÈç¼>µI0é »yž]Ü¡„öux›š1¿a¡t±¶žÈ[èÊv.‘­Œ{øhltq'_VDž=~²óí±Õº¢Ëÿ³=ß¿:k�ä–ùGNv¾t}Bìw‹GºƒoÞ^Aˆ„ýrØï¼f£"Ï,ìPBûb^U7æ7Ò¥G»ÙbmÍBûë;¹D¦…Ž/íäÊ ‘gì¼4¶^StYàŸ:Ûýý«ó† ]2ÿèÉ®—®ÏCˆý.ñØê“#~×µÉ ‚IgÈ% lÕ sn=ÍQÊQò^§w—ë™ÿð7×ï9Ÿ8ûýÏ<êsŠ÷¬:…jó›ß¿>›øÍO?ôñ =£™bý?|ëêòNá?}჋XUÇ0 ëR…ým5L0¹–ùÊ·®Ç|òŸþêSQŸÜª7MýåáÕ¿|aì©SÿóÿhÐ-Ù³¤!ŒzÅŠô‡dh»Eå{7×ã¡ý !(Áõû¶3•x¶j佌N÷ú?ûdÏ7ž]I«“)9ODž>æuœÀ³R¥Z«7¾õÆÂbZG˜¾K«¾¨û‹Ÿ>ùõZHªzS}d!p‹]!ו©8Á$ê—ݲpk!I é 9‚“kiFi_Ô]i¨ËÛžãŽvy¹êVº,2îd¯!žKêÏ/$K5Õ!°GŽ…ßÛP4Ó)òOFpc@ìs°Ó½×GÖÂ~·Ør]žÚ˜D|’Ç)ÜšOPB:CNŒñÄjš£´/ê®*êÒvçèÑNo2_ÝL•Æìõ/Æó{èÈb²XSe=r4üÖø¦¢î¡K�`Ÿƒî¾v»…ö„]—'÷Ñ¡ù%¤+è$duÕmi;ÏsôH§w7_k¡=þ¥íün¾.ñìì@`d1Y¬6e]8~gb³¡N‘¿x"úý›Ë�`ŸÌÎö_½½† ö¹…žˆçÒäF$ì“|6ÚtR‚ÇWÒ¥½W½©/Æ[hªPÛH•,ty§°›¯I<;Û]Þ-ÜüàÆ² °×B‡[h_Ôsib #öK>·tsn‡bÒrp¯¤,´¡Úh‡7U¬oìZ¨oe§Ì×$ž;Ó[N*MY`ç„/OnÕ›†Sä?yñƲ×Á ½2¼º‡¾3±iõ4`£!ãÈØJŠ#´7êRT}!žç)ìôfŠõõÝ’À¸ݾÕD1™«I<w¶?8¾’Ê·ÐÐå©x =yihÅ�Ð#³sƒ¡W†W!ÄA·0ó¼=¾‰ ùÄ€[º1»C0é:xŽŽ-·PU7æ·rŒÒÁNO¦T_ß- w¢Ç·–,&rU‘qgûƒ«©|Y‘öð‘Е©xMÑ"ÿØñÈËC«º =2ÿð‘ðo­Bˆƒ.a c y¥ë{(OG—S¡=—ª›:ÐéÉ•kÉ¢ÀqÇ{|ë»ÅD¶*2îL`r5++2Ï>º:¯)ºC`ˆþphU7¡[æÏm¡?Øé{k|#ôJ!¯ãúÌ6Á$tˆ<]Úåí‰8uÜÛÌ1J:<¹²²‡nì–vltj½…ž?º6³]mè=v<úÊðªf@·Ä_8~yhÅBtúÞÛÀ‡¼RÄç¸f¡‡Äs#{¨ÙB;<…ª²š( w¬Û»‘j¡§ûÓë™l©ÕÓ³Û•†æØ£Ç#¯¯ipIü#Ç"-ÔÉíò½9ÖêiÄßB£YÙíÅ]ŽÐî°Ó0ÁìFÖê©¡Tßÿ,'S¬ß³Þ��®ÏlÿŸ/M~ùß]¼ç,çïÞ˜»>›��üå÷Ç‚gû‚ÿË^Þ)��¾ü×—þá?ÝtB+•ŠÓél•«e©ª|å[×�ÛÙÊýÍõ?þ÷Otõ¦þÊðÚ_¾0�¸:÷:…/ýâÅöYŽ“§9ë÷s/¾u}za- $âYWxÐíu›�Ô-_iv¿ø¾›3›7´í’pñ#Ã0ËuµÒÐL�µf}wñ–ʺ¢]‡ Ã,×µR]ey%!0LÓ*§5E�ÜXÌÞûÐéè#§|ûÅ×'6wR¹ðñ‹¡`'F°ÑÔs•¦¦›n‰: !¨+z¶¬�š†‘œ»^C¢7Š ¸øÎ ãÊL’ ö n™ /¥)! c<¹žg”ö„äzS_N”ŽD©Bc+Sw¬Ó½’(§Š ™çNõxÇײŚêØÙ>ß•™Ý†jºDva0ðòí-`ŸÌêö¾>¾ ¸øî ãÊL#ñ ^‡pk1M éðKãÉõ£´7$7T}i§Äst êL—”Í´…ºV“åÝBCæ¹SÝÞ‰µl¡ª:öPŸïêìn½i¸Dv~0ðÊí-`Ÿƒžêö½>Gû]|wÐqÙB=‚×)ÜZLSL:ü¥xb-gõ´¡{h¦¤l¦+"ãŽu¸Öv[èÉnÏäZ¾PU{¨Ï{­Ý2Lèsp§{}¯µPÖr]žN`„Ã^Ñï†l”Y(!=!GS3wŠ<Gû#ÎlIÙ°ÑõÝr²P·Ð©|¾¢:v¶Ï{}n·f¡þWG·uzeîL¯ïµ±8´Ð°ëR üNah!E1‰$FéøZŽ#¤'èhêæâ¶V”TEdôh‡{=UMæëÏìöLoäó•¦CàÎöúnÌïÖÃ%²‡ü¯µPv¶×ÿêhBìs±¾È>p 7-Ô/ _Ír„t‡šn.lyJû£Î|EY·ÑÍt5‘¯K<w¢Ë3³‘ÏÙèÍùtUÑ-ôõñmÍ€™=ÔßB.Öq½3•À‡<BÐ-í£ŒŽµPù ª¶Ð˜{3SMäêÏìòÌlåså¦CàÎôú†Zèù~ÿãÛš<®ßÿÊÈ„ØïdÑ}4ä–ņ&1¿(2:¶’åé ɆiÎÇ‹<¥ýG±ª®í–ŽépÅ3Õ\«§s[Ŭ…öøn-¦+ Ý)²‡ûýoŽo«pKìáþÀ:s¿=¹ƒz„°Wº1¿k¡OG-4(&œß*ð”öEÅÚhMb܉.÷zútr[Õ[bç?´Ñ#1÷Û“;á Gˆx¥ës»“¨O”:²’±PÓ„³6Zª©«»e£ƒ1×N®¾m¡ ñb¦¤8ît÷öRº\×";×ï{2ÑÔ[b?¼½!ö9¹#ž·,Ô-DÛP‡ÈF–3!A@8½™g”ö…庺œ(=u"üþ¬½ë©pw[ëqÐ#:E®Tk�þ·çÇÚõ„\Œâ;ZíÏr(ÁQ·U6S¥çþþÆïýÂ#ó[¹o¾0j­ã–ù˜ß±.Ç„†‰"^9ê•nŽÜzýêm…' ç¿ÐÓDF2uü¿³ôá“!‘‘ó¾>ýϯ-}ö‰#œQ•Dq5«ÿÝ›óÖ¼#Ôvÿâ‡úœTW5c)­¾>¶=ó|ü\°R©bL$‘ÿΕåÑõ:¦,[VÕ†³†=ª¶S…„ê 8õé§ŽŸètbS­Üwo¬g+úÏ]ìêt 7k&ÿ7o,�Ó¾H@�pÀÉuúÅksŒqØÃ{$îöržóò£©"£¤Ë/*š±œ¨ í ‰Ùrs+S—ŒÈéênAqðܱ˜<³Y,T5—Èèr-eëŠá‘¸3=î7'wuúôD§ëÍÉ]-Tº:—Á‡ÝÌ+³á圅rOî£ær¢"p´/(æÊêf¦&1:‘7Óu =“g¶J-´Óyk)WS ·Äéq½5™Ò èkCýN®;І:ØðRŽóñÅ“ë*¨š¹”¨í Š¹Šº™®IŒ„å­L=i£sñr¾¢:îd§óÖRÞBOw»ÞžJi:ôÉÜÉN×6”®Ì¦-Ôï`·–r“¨—gO¬%h¡ªnDež9öÐÎÛËùjÃF§Óš¼2;ÕÝB®ÇFCnæwò{(OñÄzÁê©f˜‹;P‘Ñþ°ÏÖ“ù†ÌÓ£QÇ|¼œÛCWòÕ†á¹ÓÝ®KÓiU^™îv½>‘„´7$_ži¡'?´ØBFÆ× ŒN¿ æâN…çhOP,ÖÔõT ÝÎÖ6º°SΕU§ÀèpŒ¬ä+ Ý-r§º]—fÒª¼2;Óíz}¼…öí¡.tñC‹YŠIÄËDFÆ× !~Á0ÀÂN™çHOP*µ£¹z$êXÜ)g˪SàŽw8F÷Ð.×¥Ù´ª¯ÄÎô¸^OBˆýÚ–/ͤ1ÂA ¹ù›‹Y‚IÔÃ$FÆlÔ4Ál¼ÌSÒËumÍFùÆN®….í”³å¦…Ž­åËuÝ-r§»\WfÓM x%v¶ ˆ8.M§ÂA »…› 6ÊÓ±ÕGH‡O��În•xJºƒb¥¡¯íVmTÙC—“ÕL©…ޝ,ôT—ëÊ\¦©ÄÎö¸^Ûe:q¼3B‡\,ìn,d &st´ ±Ð€Xmè«»U‘£ýai· lçê2O£²…:îXÌ1±V,Õu—Èêr]›Ë(ª¹pÐ#6tr¯…∇wtt%o¡™ÍOIO@¬*úêîþ¡£÷Wr�Gñ@Ľÿbv±)V•»+ÓÞÓÏ=s�ø½ëË¥ªÒ^oú£î?ý‡Â^ù¾%Ç%±ÿø+O}õo¯/lå��kÉâÿôÍ7öÚ{dþ³>ñù¾ã\!cT­Ö°#,y y‘NÅk×nÞ:ÞåûÔGŸôê‰ço€“Ýî—Þ¸ú›C˜°w¾­Ù›Ï<~æÃO\øö÷×u#�xúÓ]¦ãoÐ þÜÇž(eQw—³˜KÿÓ‹—?wâÔ`Gq{¾V R �€yf2„BDD÷Ùƒ‹¼øú¥™¥ßùåŸ}$ šãBŸ÷û|2ûO¿÷ËÅŒ…|Ý.9cÜá®/1ÂaõHtd­L1Žz8Žà©­*£¤ÓÇTÝ\Þ­ éð…ª¾™U$FzCB<§ìUOÂÂB¢ž¯ê.‘‰ˆ£kåšbz$z,&]™/hôËôXLz{&!:I‡_¸¾XÀ‡ÝÔ+s·WKÊžÚª0J:|Ü´¦of#½Aa'§$‹MOûÃÂb¢ž¯j:¶^®*†G¢ÇcÒÕù¢j�ŸÌoC»üµ…F8ä¦>GJñÔf…QÒáå4,%kGºü|±®ofl´ $ -t)YÏU4—@Dű}ôÚBQÕOæŽwHoÝ^-QŒ#Nàðäf…Òáåô}”•êúF¦!1Ò%QhZ»·Ø(W†G¢Ç¢ÒµÅz¢Czk:!8IO@¸j¡.êwpÃ+w¢1/g˜`1q'Ú’…溲[ÏZhÄFEz,&]_,6uà“¹“Ò›ê =Aáê| 8Ù-žØ¨0Bb>Îpa§&PÒígE_O[(Ÿ,¨Ú:€NnVË6zc±ØÔZ=}s: 9poP¼2_@]4àb·VJ㈇“™Ø¨p„tø8�àÜN§¤« ð»Eu'ßB×RõLYs t0"Nmí£7—‹Š|2=Ñ!¿9“�‡¸¯ ¹ØÐ²òdÜB½�pn»…Vc-Ýé ð©’º“oÊ<íñêè`DœÞª–ê†[¤GmÔ+Ñò[3yà ÷‡ÄËsy„pÈECn6´\$Gܜ̓ñõ2GHÌË!g·«Z³PŽôøtIÝÎ+2OúBÂZºž)«m¨îéѨtk¹ØPÍ6¸?,]žË#ˆƒNnCÛCQ íô³ºj®¦ê"Gz‚|º¬nçZèFFI—T§@ÃÂìvµX×Ý"=•n-—öзgò@A K—l4âáo. Æa7çl¡8æeÁ™ø¨@ÑOäò[üÆo>s÷õi¯¬,&ï7Ë~þ£'6Óå·Ç7ÛKΗÿÝ{S”{—¡×Á?÷ù'þønÌndÛ{üg>tüß?{º­14�ÐÊUõRMíŽEºS0QB.ö±s!tÊ-pXàyÜ,+¼®†n@g×¹Gýù§·û¤× €‰•œÚ¨·®A¸z­¶´ºîí8 !aëµb±¸º“;uN�˜�˜�êöerVm74ä9B0\_]NÖå¦ADÍ ÆâÜ´ê=¥ê@æÌjv€‡¬YNM×W*á° »%r{£ÆaqŽ ©í:OpÌCTÃ\N5Ewzi±®oæTÃÝ>.QP“%ÍÅ“Þ�]N+¹ªîH_€›Œ×+Šé“È@ˆÝ\©6u”É`˜{¾ !Š8p‡—»¾\!“+¢�� �IDAT‡ ˜#hÒBÝD3ÀrJ¹ZR“EÍÅ“ž�]¹'d7W«MdrÄFÃÜáå®-W0Â!öJdx½…2Š&ã-T7ÁÒ®"r¸ÃKË }#§Ê wù¸dIMX¨Ÿ®¦•¬…¹éíz¹aúD2dC«UE™ †Ù;óe�¢Nì•÷QžCñ:OpÔc£wxiY16²-t·¤&ŠšÓB3J¶r'Úd·ÖªŠ2 ±wZh—»j£>^¯QŒÃn,´¡&�sIE¤¸ÃC+бÞBiª¤î5'Oºýt-£d*ºG ½Anf§^²Ð^¯6öÑŠi¡~îêR#tbŸƒÜZ«RŒÃ.,04¾Ug{h¢aõ´…r¸ÓGSem§ÐB׳J¦¢»Ò°PÃFk $2b—*&€!wû¹+K qȉ6qaÑFc�˜µÑZÓX˨2‡;½4]Ѷmt#«¤mt.Ñ(Ö ¯HúCìöz­®‚€DBìòBE7aØqu’!•özê&�‚ÙDC°Pµ…vyiÆF{üt#§¦Ëw¡A6²^««À/‘Á0»¼ÔB{ÜåÅ ‚(äÄA'Zmí^‰Gc6 ˜9ˆJîòÑLEß.¨NFº}tóÞ(7²¹^Yªè& µÐ2‚(èÄ!½¹Z¥‡]XÐØfÍB3; âi¨æj¦)q¸ÓG³U=žWŒtûèVNM•5 ]H*ݬÕTÓ/‘»ºTÑ,4È]:ˆZ£“CÀ£û(´Ð˜‡44s5ÝBÅ;/XM Ue¤·—?4b”Ü»ä€ýKÕÚë=Þƒw¹bmc·”/7î87·‘é ¹Ež¾[ÉÜâ}î‰?ýÇ›SkéýzóÁã¿üì™;6Âýãye|£p±§óãÌ•ªaQ`J£î“Ðk·f „¯ BPo4J5u°¿ûQM½÷¼yýôÑÞO?óÀÐU�@CÕç7s±Ó¡Ï|ò™Pï`2SYTÑCáŸ}ö©ÁÞ¨iÖL�ô¶’c�`ÚÊ6²x¦úä#!~ŽqÓ‹«»óô‘îO~ä¦w@ÑŒÑéÝ÷¬é�BNèÐÈV“Ã(ì‚S •'(êFº–2šDQÌÊŠ¹‘× uxðnEO” :½x-«ek¦W@]>2›TË ð‹¨ÇGno*ŠC2ìñÓ++  ˆ "nr}MÁ…Ð#Ú¨2‚,4âBº –ÒšDQ̵ÆÜm¨¯ç´lÕô ¨ËKæ’jÉB½ddKih0(Á^ß>³PØBoï¡Mî@EŠb.TUÌõ¼îàP‡§+úŽnäµÌº«–À/¢nßôêŠbqD%t{³I1 ;!߆š�,¤4‘¢¨û]P=S5=êò’ù]µh£cq¥n£×VÃDaèðk«-Ô+¡a(šhCçvmT5×sºÌ¡7ÎTŒí’áb¨Óƒ·òzºjzÔé% w * J°ÇG¯­)º #ØŽúd4¼Ù¤…PàÐÄv mhM5×rºÌ¡˜g«ÆvñN´ËKRj±|"êö‘ñ¸RSAPB=~z}MÑLqÀN/¹ºª`ˆ‚Nè—ñ-ßV™ÎÚh½­ÛEÃÉP§Ç zªÒBÓj¡nÚhs½±¦h& ˰ËK®®*¢ øe|kã(DûhC5Wm4W3âEÃÉPG 5<<êò’¥6tb§YSA@B½~zsMQ –a—\YQD!ðËdh£I 9 l¡Eœ!0›ÔŠ¢.ÔÐÌÕlëwÚŽn[h§‡,§Õ¼…zÉäŽZm‚€„z|ôæz íiCƒN2´Ñ$…œPfh,®2ŒÂNˆ˜ÙCu°šÕdÅܸP7¶ ­Ý»SÔw+†»îD‡6Õ€¡64؆†PæÑX¼i¡™¤*u¡¦V²šÄ¡˜êÆV^k×w ßx~ôŽiƒ•¯|îÉŸz¤Ÿ£èž•ÃzvW½�Àƒ§r´]Kÿ÷LŒ¯¤î°þ×oß~òñA‘¨:èn8앾ü?<þÐ@h¿ÞüÔ™»7Â:°V×À;s¹Œl×kµ�ʶo ¿=² EÉ9:·¶“Ê–jê[3²ãaþêðÄ;[Ÿ=Ò4ȵÑù\±œ*6n/î&3…+³;Wr¡€·²»üÝ×o\\^«Ä ZÀ-Q­ÒTU¥©Z¨õ/žSFæ·²…’ÐÒný¥Ñm¹½¸òæÕ[¯]›^«¼0wø"#óÝW¯¾54UAžs‰|±d! ËÀÅÃу`q@Ãé]ƒ#0ꄺ2¦@aÔ +M°–7%Æœ0]5·KÀÉ`‡ nÌt ºØáB‹i£¨@Ÿ:Üh|Ǩk( º¹¡k& ;@ĉnnêˆ \Ù6‚dNÙ¨öѪÚB£N˜©µÐ˜nÍtºys¡ÅŒQ°Ñ‰„QÓP@ntsK×L’Aĉnlê°¸8²m`ÃÈ(œJ4XȘ¼®Z¨ fkf¼ MÙèRÆ(4Zèdrºê[hÄ…“IƒÃ-t>ÝBkw¡cN/š©*pó°Ã…–²F¾½"èp¡©¤QU÷QÕD!Ä\èú† ²ÐÛ6*Ü­«`5×úfkæ–…ºàvÉܵÑe îDoméªq'êáí¸… ¥F0·‡j`%gŠŒ9a¾nnïDc.´r­¨( 7ÞÒ›w¡>Û¨HáD FB0—6y#NذÑèAt§d&+ÀÅØ­d\½…Î$Š ý"èp£áx íp£kû(ŽÁ°ˆ\ XhÊä Œ8 ¢e-ÔÍMMì¡.´ÚŽî•&ô‹ ÓnÇuÅ@!tºÑµu@–_FÃqÝB%Ç-Ô ‚³)“u@EËYS¤0ê„…†¹Y²…–÷ѵ¼‘­C…¦Œ²…ºÐȶ®è÷@oméÁˆÈm(nC›mh±an€Ì`Ì “3Q.v´£n4k£6”Z¨ PXÁ;P{t"ÎX¨6 °”5E cNXRÀFÜñ¹œÿçù{Ö�Àü‡k•Fóž•Ã:wsw½±zßYÎó×—G—w­…§z<Óå–Y«êü—¡L±þ#f9V•ë8ÿà3ý_¯LöG=w×+{ŸË)*àÊJýõ[Ͷ©«Dô,Vv•|ܨ—'ê CŒJ/Mæ«ñIµ˜„„mÖäÚÖ0 Äd½!Êôær½.H*ÿ½±|-1¯U²p|ø”.E6RÕf~‹§(W(î¤r@ôî}þôêRéõäB³HĨ¬™èö–zulMÉnšB¥.1päʆùÚФ’›†Î…No«¾¯??W© Ž  !r2c,‰(2#’A1œI#›ÙÐ ´R@1"²YUÑf 9¨‘Íl %ªÈÍôˆÃÜ.¡Lùx="›Ë9Tj€ Ed0“‚u †E-"ƒ‘¨™0&iA m#͈l8´Ð°lpNÛ¨aÀå‰>ˆæöPÙÜ)£Lyy=â0W󨨴ÐÙ¬í¡ ¨0*iaì¡.¾…Fdƒa8B<6#’a¸E"1"²YWцæëh§‚Üœ¾7ª‡¢£ ¨¶£À ˆ›‡£‰Êc8B ›ùG .NÈf¢ŒÒ6º–G="ƒÙ4¬i0tz3Ž0#²~:•B ›aÙ�mhCCëE$S#,›ùFZAéòòzDn¡~A8À\VÕ:–€MF%-Ò†zx8’@šÙài È�pÞB¥}4"›…Ú¶Ñd¥jÈËô°l®·¡ó6–Áx:G�€ˆ¬í¡aÙ(œ´Qà| ĈȦ҆ÛÐÝ JÕ‡éÙÜ( ü]hÄÑB#í¨¤yÛz*R8¹‹2#²` ËfSGk{¨‚¶ËÈÅéá;Ð"Ê7 Ÿ×#2XÈÀŠN$¡¢·Ð›6êáí(g£svO÷Q‡YRP¼Œœœ‘ÍTíÞ Zèn Ë`(ŽL�bQ‰Â‰]Ä!3,øž¨|­î£›E”³ÑÅ ,«0(h˜´ÑˆÜÚF&�1Yó‰pxahF$CâZhD60‚³$`#"›ªV H¢FX6Ë Ú*#'gÔ©Ù>ŒŸê ̬gÓÅÚÝ%çgºîw`Mdôtoà­ñ »¼€½:“-ÕOöî˜åì=>Öå]ÚM䪧û¿ûß=r´Ó÷­W§¾}i®XU.žìîG”œ½*×r=÷?>ý.'ŸL� Ó¾û�•øð >|bÿ7®Ž÷:@è</t¶ž:Ž}ôÀ½Î�pxº¬Çb÷£ûË1 ùDȼK‰›“‹É*½ž}�:ÎBÇ�† �@œó¶£,|’…OÚç~�v„]'�ÐÐÁx SdFD• 8›¡<6¢¦hµHD¢‡$½ª¢­2qP=,éùNT‰›ÓB¢‘¨Lûx5(êëE®¨ € Ec>ËÕ4›јH1Õ€1Iñ‹æp‚GÐŒŠªÌñg¡†3ʰ5À+E*=,êum–‰ƒê!q ŠF¢J2uìejHÔ׋´¨àwA¢yËFßåÈÝ(€+¹û¢.N ŠFÒFƒ{(¯E}1ÇUÕ:™bMNð�˜QYur`¬ ÎP†È>j„E½®¡Í‘©õBïT‰‹ÓB¢±[%é:ö2-(èEZPp€Ww iÖÔaTjDc8Á�"²Ò޲6�¸`£ m”ˆLõ°¨¼S¹Zj¡A¡…†„¨_4†“<0ADV\Ýå4#’Ê0˜Nsí¨`¡úýPœ®/Ó‚¢¾Y¢ûy5(èK9®b¡‚1fŠ… Æí$3MØ!+.¶òL¥9aQ�Îç¨@Œˆ¨+:Z·Ñ’‚·m4Uéñ0-$[%’TlÚP7Fw9 ͈¤ ÄF% 8Ÿmõ´i£!urZH4Òíh™äØÏ«AQ_ÊßI2Ý„²âæÁHòN4"iÂù,ð>*݉êíh¼Lr6ºRàÊMšAÁ˜I³†#b3 £6ê9ˆNÚ(‚pÎFU­Ùh¹‰ã6š©áÝñ0-؆l4(4ƒ¢1“a í�Ú!)^ÞIòšQI)˜LµP á\–òØKºj µ"‘ˆõJÅ+ÄÉé!Q¯Òcø/<}!¸ÏïßmÓª�üî/<æÙ=KŽ×)|ágþóKíë[«î þüÓÇïwÝÁ§@N­e~áécG;}Â_ýÄY„`<]þõŸ½àw‰ïVrî7«º×Õÿ7¼YI7çW·‰YÓÐ0ïd‘(¸ ð“ùƈ¨`çò<CzXlê&Z+1‘èaQ­i8^aª…f^¡ÉçæÔ€ &k\¶A}¬éãµÍ2+6IW|¼¶TàkŽ /¯OgÕ@bÝ͌є�ˆ‰5‘‚ÉŒH ÁÙÏ›:@kE^ÄzHPë:Þ²ÑBsÝ­qÙõ²¦_h¡64,4<¼>“šŠYhZ4ìkC3*6†³9žÛC ¼Ð†ÊduQ5(¨©:—±Ñ­=TЖ |ÕB™>“»í’jwoÔ�hµ…6÷ÐÐ,6i¢Æ¹¨ØC¹¦_PãV°Ñ•"_U[èlNhê(&Ö=ÌK‹€]RMæÌ‰Œd¡ÙÏ!#,6 €–m´¡ã͉VYA!¦xm¥ÔB½¼>—O‹† »¤šƒ3Ç-TjpÌäDaa ßM7¸týNÔ'h«%¾¢â0ßðòú\^PtêfŒgÚÐôhDl€¢Ñ‚‚ZRÉN•s¶¡®°Q?S|| µ¡Q¡î扌¨›°Sª98s,-!hƤÃ`:+Ò  <õ°Ðlx£ÜBË6<ˆnWYþ^è|^hÜŠ5§FŃ(„ yžÇzXl6 d¡¡ƒh¶Á¥êÔÃ5ýѵ_¾ õÜ%û(´ÑÐA´¢âí»Q^ÝiC×mÔwÌŠš ;Åš‹™£6Ê0Õ†ÎÛ=U ´n¡¢…2'UƒB3Û Éê3‡_xúØqÅšß%~åsO<àÕníO?uqðÓOi_ò«Ÿxè~âþ¶>x½±šmgòÿoö숈ŽÈþ<ü„^–@#*Ô„óE‰!=,44­UDk!¾^ÓÈVMp5À•KÖy7U|LI5XFa>®áášñªPTiÕÝœºZ«‰ðU'§ÏdÅ@BE¦údÞi�Ø-–ybNåšQ¡Š!œ+JÒÃB]3ÑZY°êuýG ^®¹] MduOêâôuP}*ïÔMØ-–bNæš1¡Š!˜+ÈÒ#B]7ÑjY°²Q™¨A¾QT¹DwQÅÏ·Pï]èZY¬h$Â×\œ¶P’ýNT$ædÎFу£M?¯d,m¡¬…ÚÐ0_sqÚbIjè8Æ·¡Â” 0k£ÆÊ×Ù¬ 2Q÷Gwj|¾ÉXÝÍÔu e÷F»„²H̉œA3ÚB2"BÝh¹t´¤Ò=TaéóÒ6”«»™ºQËw¢U§Mçš »„²tJ[(\,‰|*5È7ÊJš^É*,Õ`^ªøÚPS7ªbY%aVs·¡NN›±Q™9‚fL¨Rf ŠŒh •x¤…ùºbª á}ÔÙ†z¨âcÍDÏ59ÿAÔÅiK%©¾‡š‰º„²Ìã6Êa0SpPhD„º ábQâ‘n£¢…VTº]ç¤é?ˆ& BY¥¡64ÊWœ6[p¨&ê*2§ç\Øh¾…l´ÙŽjt»&8IÓÏ”œÂíî¡u mx˜ºYJ÷@õÙ‚¬¨S¨ÈTŸÈ¹�0;…*‡ÁtÞAîBU¯ßåßÿ=ÖÞãà÷¾2çÇ[%ç½’ÿÖoëi�!X(;9¤GXE3ÉzÕ! 5Ī5Æë²Œ•�W+ª,©ˆnÒðq´"d›¼Ö<TÙiHE• rU׫rU§Vvm©ìT ÜÉŠ6fKnÝ„=|ž!0]ô`hvðEÑ|ÙÉA=Ú††YµÞB›{¨‹4|\#£M4Ăʂ\ÕEš5¹¢@;XQÜG ›ÓEÚG]6ŠïFƒm¨ßF½´æ½'Ê•e¢-— +¹4uó›S6Š š/¹(Ô£¬¢›x힨ƒ ­g>ÓÚÑ�Wu·¡Ž6T"m(1§Š,ΕÜí(´0«6 ºe£e%l4«ðé¦à¥õ}”V]¤¹Y“+ seÕ–+ކN:XI"ú*Øh'_Äh-ßJ-”K4$iøiÊ)Ɇ˜·PÚܪÉe]©:ê:‰±’Dôù’KµÑÉ¢³“/µP'´H²Q§ÕÓ&ŸV/­{¸ÆAT*kÜýÐ.»§ÀFgKn+&^µP¾ªtÓBY­¢q; ÉI”€zHÝÛ†º÷ÑŠƒª«íhÙ¥6Z¸ åË&ÀKe'CZ„¯(¹õsõ|“OÙènCÌ©ÌO«nڌפ’Æ…¸Š³ •ÛP‘˜S7�°SÈß.Z(k¡"Vƒw jª¹&ï§57UÚѵª£¦“(+ÉD_(»š6:]t›�öyj£|�´‡6 ²Qw´£|�5‰ò~JÎ{üÁÁí7¤”¾öÚkµZ­}º´wïžÿC‡ç·o¯W™Ã÷oýÛx¤…¸ÊFà �pÓMÛŠ�à" i»M�à£5@F�!®¢¤ ñ�€+5¾¢s�€n¾°Û”�ô ¹†[3�àˆ˜Y¬ù�=|a¥î�0¤…ÛPiÄmT@ZòÑ.¾²Ñ>!·y/´—Ï/×}áÊë ÖãŠËFÕdÓa£fF•��A®Ò4pA��QV*i¬¢3•µÐ­†K5±….Õ|&€‚:IC´Q/­¡û e•m4Ý”ê½Bn¹æ�pH²ÒzÝ�±ê¥µxÃB7“J ÅÐL7[¨jâ¼j£:+k6ªJu�z…\\q©� Š™åºÏ4!‚fß}P­mÙ¨„›‰ZÇаѪj" °rEç,´“/fTÑFóqÅi£Ù•º×0!‚f¿[²Ñ+­½+ê¡ub£®ªÝͪbÍF·góÁP«~uE¾ª›(g£U+½+: fWë^Äš6J‘ÞqÔ›;6J¡‘zW´ƒ/æl´GÈïÜs@Ì.Õü�� õN¾¸Z÷�¤¸êfà �p`ÅA”Å �ð:Ezª)�ü´j�˜SE�@˜•k:-i¼ 5³Ð„âP b¡kun"ÌA1»ø®¨Œ§ºIkCë¥ìўȩ¿¦iï2hß±�ðÆo<ûì³ïuð_]]5M³»»û=qÖÂgŸ}RJ_|ñEEQ��Š¢ÌÌÌ<üðÇ_´w˜Ãæ0‡yŸ}øá‡­cq7oÞüú׿N „ûØÇŠÅ¢U‹b±Ø¹sç÷Ôas˜Ãæ}Æï÷Ÿ;w®Ùl†1<<¼.Çšø8΋/î¦Ãæ0‡9ÌûÏÅ‹‡‡‡{{{ iÕš;¿ŸÆ4ÍF£q¸§s˜Ãæ0ï3“““###±XìÝJŽu^ç0‡9Ìas˜÷“™™™f³Ù¾î”Ãæ0‡9Ì¿NKÎas˜Ãæ°äæ0‡9ÌaKÎas˜Ãæ0‡%ç0‡9ÌasXrs˜Ãæ0‡%çpæ0‡9ÌaþuBÞÓÚ/½ôÒŸÿùŸß½üw÷wçææ^}õÕ¯~õ«O?ýôû߬¡¡¡¯|å+íK~þçþ×ý×÷žþÕ_ýÕw¿ûÝßû½ß›˜˜xã7ž{î¹'Ÿ|ò÷ÿ÷ÇÆÆ¾ùÍo;vìÇs¯_¿þÕ¯~Õzü©O}êw~çwî¹Ú׿þõ×_ýk_ûÚSO=uÏ>ó™Ïär¹üà‚ üx[òÿøý×½÷ô‹_üâ'?ùÉÿÖþz>ÿùÏ'‰ï|ç;n·�ðì³ÏRJ_zé¥9ñ _øÂÆÆÆÞÓ_|‘çùÿßW###_úÒ—¬ÇÏ>ûìüÁ¼ÿ×üéŸþi]×_xá…Ÿù™Ÿñx<ßþö·¼íßÿýßë[ßúµ_ûµÏ~ö³?©>.,,üæoþæÞÓ~ðƒôGôÊ+¯üÙŸýÙÏýÜϵÿè'›™™™ö7æ3Ï<ó‡ø‡?ö«ýÒ/ýR2™üçþg—Ëõ.«ÍÍÍýÖoýÖùóç¿þõ¯¿WâË_þ²u¯—½üÝßý]$y¶SSS_üâ�O>ùäsÏ=÷ÿ»’“ÉdFFF>ûÙÏÞñ÷‹Å^yå•‘‘‘|>ÿÙ¬R©422òÌ3Ï|ík_³–øýþö¶¶¶FFF²Ùìç>÷¹O~ò“ÝÝÝ�€¥¥¥‘‘‘jµúc׹߸ßèëë{î¹ç^~ùåo|ãÂßþíß¾{Íõõõ‘‘‘B¡p¿—šœœÜÝÝ5 ãÇÛ’ú§úã?þãO|â¿ò+¿�ø‹¿ø‹/}éKèÿeïÍbìþÿÿ3MÍ´ïû>*u·P"ƒ¦(!J!ÙR¡De )Ê.IÒ&!B‘ˆ¸Ý’î[Q -SѾ—öMMû23ß?Îï}}æ—å–å¾»9¿®9×¹®sÍëœë<ÏysÃÆfjj:¡JOAAAMMÍâÅ‹“’’xyy©T*@ø¡z“påÊYYY�À’%KæÏŸÿüùs<?¡Ì’——çèè(%%åëëûôéSXöîÝû·ÍÍÍ%gϞžåþBšššrrr–.]ú½þcEE… ×¹sç��/^¼8uê‡sqq9{ö¬ˆÈZc¾´´ÔÎÎŽŸŸ?((�ðüùó3gÎàp8OOϯ.õµµpQäÏÐÛÛ›““ÃÇÇ÷u¶ÊÉÉ9w–l¨-[¶ìáÇbbbŸ¿°¸¸ØÞÞ^HHèìÙ³üüü?G/çkk¢¢¢ZÿãÙ³gŽŽŽÏŸ?Óé!ÿŠŠŠ¯~8,!Ø(¸rå ™LŽŽŽÆâ\¾|ÙÑÑ1//ÏÍÍ 6%6mÚTVV6Þ´²³³BCCµ´´¶lÙ’°zõê7n`ÿ%&&�pòäÉ„„�€‡‡Gzz:�`ëÖ­XœwïÞ±Þ–Édb§ÌÍÍa`ee%™LÞ¼y3•J%“É{öìó0mmmÍÍÍ𿋈ˆ444@9÷ôôÄnøöí[ØL#“ÉæææØ)¸‡F#“É–––�€ªª*ì,ÔÑgÏž‘Éä£G>xð€L&Ãwø+(..#®XZ¶¶¶�€üüümÛ¶½|ù>|øáÇð844^uîÜ9ìªÇôÕTUU…fÁãñ………L&sxx»pùòå0&´pNNvêСCð>·oß&“Éááá°»ŒE€Ù - Ûd2¹¤¤d\Öxûö­­­­¸¸ø… ´´´6nÜøøñãõë×ÇÅÅa ]½zë.ciii��2™\\\<&[±†ÔÐУ£ãž={ZZZÈdòš5kÊÊÊÈdò–-[`„çÏŸc÷<}ú4lS_¼x� �8qâçåË—_‘郃ƒ<<<0/º»»ß½{÷âÅ GGÇØØXÖ‡L&ÇÅÅ�Ž=Š…dff~Eº•••Xºòòò]]]õõõ÷ïß'“ÉÁÁÁ0Úùóç+á^�� �IDATÉdò;w|}}=ztðàA˜(–­d2¹²²’õÎÆÆÆc^ÈÚµk¿KU;iÒ$øÌD"±´´ÔÔÔ”L&÷ööΙ3gppKÑÊÊ �PVV¶fÍšªªªâââÈÈH…§OŸbq ·)22’L&GEE’ÉäßÿýÈ‘#X¬>$“ÉÕÕÕ+W®$“Éðyôõõa´E‹ÁÚÚZìZ¬S‘œœŒ|Cƒñþýûîîn&“I§ÓßšÀÀ@øV`!®®®�€€€€uëÖ�®^½jooÏÅÅuáÂ*•ª®®.##“››û~œÜ¾}�°lÙ2ÖÀ³gÏ 9;;ïÚµ ö‚CBB¬­­¡ß ¸¸XOO�pýúõ–––ñ¦øàÁè»` Þ´i•Jµ··¹páByy¹™™�Àßß¿¡¡aÍš5œœœW¯^¥R©JJJ²²²EEE�€úúúÉ“'*•šœœŒÇãõõõóòòdddÔÕÕcbb Ž.Z´hÌÃÔÔÔ¸ºº ‘H¤àààŠŠ *•ZWWçììÌÃÃH¥R§OŸ.--žž®®®�““cmìwvv¾ÿ¾ªª žÊÏÏ—••USS£R©—.]âââ²µµŠŠ�ðòò¤³³óx¦¨¨�øë¯¿455›››ñx<W]]¼¼¼„„•J‹‹#æææ \\\+V¬ R©¾¾¾¼¼¼T*uÏž='Nœðññؽ{7•Jµ´´‹“\AAÁ¤I“äääH$REEE^^•JíèèPTT„}¬ÄÄDvvöyóæ½xñ�ÀÉÉÉê¾X¹r%¼¯¯/�ÀÍÍíäÉ“‚‚‚nnnT*uùòåbbb·nÝ‚-IIIè²{öìÙ¸l’””�˜7okàåË—EDDlll¨Tê–-[„„„‚ƒƒ÷ïßÏÇÇwøða*•:þ| ‰GQ(�€´´4ì/ÊÉɱ³³?}úTCC‡Ã±³³744��ÄÅÅaƒƒ@ ]»v““sõêÕ>”X°`•Jõööæçç÷òòª©©Né;vÔÔÔ¸»»óññ;vŒJ¥Î;WRRòÉ“'ãÍú–––¨¨(NNN‰dccÓÐÐ@¥RËÊÊBBB��NNN555T*¾8�€Ó§O»¹¹ñòòž<y’J¥R(IIɧOŸŽ7ÝæææÈÈH˜®]}}=LVÁ®®®0š››Tt{{{11±   *•j`` ))yýúu¬jÊË˃…ôôt0yò䯯FQQQ*•zÿþ}`jj ³uîܹïÇÏüùó�?†?'OžŒ•I¸„¿¢¢"•JMHHààà066nii¹~ý:�@OO¯¸¸8>>^\\|ñâÅT*ÕÓÓS@@àðáÃpôAXXÖ‡¢¢¢¼¼¼¾¾¾T*U__Zxúôé��YYÙGIJJÊËË×ÖÖª««³±±Q©ÔÔÔT<?sæÌ‚‚YYY*•zåÊ..®uëÖÝ¿_\\ÜÔÔ”J¥8p€ŸŸÿСCãúï—/_>{ö,l1{{{ãñø¯éå\»vMSSSSSóÒ¥Kžmii’’"‘HD"±¡¡addäëä011Qóœ:uª»»ûýû÷BBB;vìÀz ’’’pà{]¿ssóÔÔÔƒ’H$AAÁŽŽó� !!ÁÍÍ}ôèÑììlSSS‰D êëëY;éÕÕÕ8ŽD"ÉËËÓéôwïÞŒŒ444ÀšâĉŸêÞ¹»»§¥¥ÍŸ?ßÛÛÛÐÐ0;;›¯µµµ¯¯OBB‚D"qrr666bë½{÷îÏ?ÿ,((((( Ó¦MëïïŸ3gލ¨hRRÒÈÈH}}=‘H$‘HÒÒÒÍÍ͘ÇÀÐа  à«Çêêê`ó�ÀÃÓðìÙ3‰$++;<<ÜØØÛ§4D"‰‹‹÷öö’H$˜­°Ñ#""B"‘øøøÚÚÚ>tÊÈÈ$$$<~üxppB¡,Y²DRRú9ÙØØ ‘GGGëëë±–¸œœ´I@@À£G¼½½oß¾íëëkoo¿cÇŽ®®®®®.aaa,ÑÞÞ^xmssóùóç  ¢#===° Á?ÛÑÑÑÓÓ#**J"‘xxxà‹ã766ÆÄÄ0™ÌÑÑQ…Û·o´TËÉÉ?^ZZzpp°¹¹yúôéOŸ>=þ<‰D£Ñh0]!!!¬njooïéé‡é677c鎫©º`Á‚ììl//¯¸¸8==½ÐÐPVOü³ wïÞuww_³fM{{{oo/L—‹‹«¹¹ù+V&‰‹/ÎÎÎöððˆ9sfxx¸˜˜ØÊ•+÷ïßõêÕ   °°°K—.íÙ³vPÚÚÚ¸¹¹I$77wss3lÉÖª)::ú·ß~ÃápÕÕÕ £¶¶Ç)À߈­­-¬Êªªª?~ [¥µµµYYYùùù¬e¾­AZZ�ÀÅÅ%))Ù×××ÚÚÊËËK"‘DEE»»»±þJggç–-[ ?eáÐÐP===vvöºº:ƒQSS� ‘Hùùù‘‘‘ðÅ!¬UDkkëóçϯ\¹²uëÖŒŒ èêÿçÆr°Ö¢‡‡l Ÿ<yòSö%˜Q¾Žyóæa³¸¹¹±átXéÿhxyycccýüü`Õü)7£ ìÃŽëÿ„Ï8sùøøøøø:D§Ó¯\¹²{÷n¬³eË"‘8fØ,99yêÔ©lll��×ÐÐÀd2›šš$$$$%%¡¡°°PUUuÌ*{–––gÏžý:'5ëhùŒ3èt:�€““söìÙ�€¿u‘ÁÇÇ'00F£}*|QÓÒÒÈdr{{ûÔ©S `®ªª �cÚ´i±±±pjƒ°°pÿû÷ïûúúºººxyy1縯¯opppOOëµW®\Y²d Ç¿âï¾{÷®;;;–éÒÒÒ¬›cpppˆ‹‹×ÕÕÁŸœœœEEEÐ÷ðy!Ù»w¯··www÷·8HdddÌÌ̘L¦ƒƒÃ7p8œ¶¶ö˜AY''§;vpssÃ]»vyzz~fô Óµ´´d2™[¶l¹~ý:‡óõõèíí¥Ñh¡§§g\µ„””ÔGÍû Æv¿9›=iÒ$è—¦Ñh–á1üþûïÏž=“³{öìÙ±c4òÎ;=<<ÆXXBBâ£ãlll222PüàP™ªª*¦ÄFFF¥¥¥>ôòòº}ûöúõë½¼¼þÉáææÿ|œ°°0lë¯ø"‰›Ð%22ÒÛÛ{Ó¦M»wïöóó;þü‡qÖ¯_ÿäɓ۷oëèè,\¸ð+†‘>äÒ¥K>>>;vìØ¹sçñãÇétúµk×°Ë™3gŒ1e‚ÂÂÂPo`¹íAAAV¹ššÚDZª*%%VRߨ7PwÛÛÛ±ZfÚ´i<<<&&&_~Ÿ]»vmܸë-9»dÉ’¢¢¢””EEÅœœœ)S¦´µµaƒ×¯_Ãc<«`¨7Ðeèîî~ïÞ={{{Ö9N;wîÜ´i–(t± þ[z�ïHJJʆ æÍ› ›†åÈ‘#pZï+ð/^<}úô;wîXXX0ŒÍ›7‘íÐÐÐààà}ûöaz‡‘ _úëÒ}ûöíÒ¥KáÀêòåË †³³3L×ÎÎŽF£ùûûÃÉŽŽŽjØ\PPðÃÚLLL “:>>>Ö2üÑ›˜ššb*œœœp”———ufì·XXYYFåàà€5ðúõë™LæÞ½{CCCÙØØ¾e~ øqßåðòò ®]»VCCŽ(|GŽ?ñ™ ,(//×=çÌ™ýäÉ'''�À­[·ddd<<<ˆD¢   ‘HühgîñãÇ£££ðÿŽkêTvv6'ü¡¡¡®®.¸‹ט¤yxx544 ?ê—�À^YõÇ –””hhh°Î8ÿ.TUUAÍc2™4MPPp¼bÆÅÅ%((xüøq gôöövuuÁ&!???k³‡Ã jhh`ïÛ˜Þ�77÷ðð0ÌPÖW”““SPPÐÇÇGCCãÛgxëêêÆÅÅ¥¦¦ÚÙÙ�îß¿/##ó퓤ÕÔÔ¾Ä 5::Ú××µ–µ¢Ç8tè!àææ†ãX¯^½ïóÐéô®®.Øõgggÿ°}pþüù£GºººŽ™Ý Óݾ}»††Fvvö·¤ËÁÁÁš.‘Hääääääüè û)´´´>åÆøÇ€e¸¿¿_CCãì þþûïþþþë‡mÛ¶ihhäääü­ËWFFFWW—µŠ(//×ÐÐØ¼ysRR’ŒŒŒ›››½½ý©S§†††¾ÂûM½ÇÆÆÆúª³±±ÁìTTTÔªU«V¬XÃáètzrr²’’Ò׈!Ûï¿ÿ)�€Í›79rdhhèÔ©SÞÞÞpö�ÐannnjjúçŸ*+++9<¿xñb8ýáþýû cýúõ~~~çÎ;~üxHHÈþýû·nÝêééÉÉÉyîܹááá7FEE]¹rÅÒÒrÉ’%8.99ÙÞÞ^WW—N§Ãú·¡¡ARRþ ii霜66¶ÔÔÔyóæ:t(66ki²âìì<44äëë [4 # `Íš5«V­¶µµ…¶}øð¡––«0TUU±.פI“ÒÒÒæÎ+!!Ád2õõõ###?~üá…ãÍ#¬kÅÅÅ ijjJHH¨¨¨¤¤¤ÌŸ?ßÂÂK ÌÃ=<<†††<xøða:òá[—œœL¡PÈd2¼Ïèèhmm-?ƒ˜L¦¬¬lrrrII ë³A¬¬¬†††rrr|||`ˆ»»ûÐÐÐáÇ=Ê`0-,,âããÇ\8^›ݺukõêÕ𑬬¬‚ƒƒ¯\¹ràÀK—.1Œ8;;öÅÎ;ÝÜÜètztt´‘‘Qpp0kê999S§NUWW‡ Ìu ãŒ1)‡›?þõë×7lØ !!±fÍ??¿ýû÷sqq8p`hhèØ±cÇŽkjjÚµk—‹‹Ë¶mÛètú7æÌ™3Þ¿©¡¡‘””djj Ë6“É´´´ »uë|<:N§Óá,²“'Ož={vxxxË–-[·n¥Óép$f¼éN:5!!ÁÜÜK×ÊÊ ÎY€/Îàà VªY«,x<¦èÂÀ¼¼¼©S§ŽŒŒ477spp”——«ªªÂìSWWúôinnî‡%ê««Í1ïì—+**Âåääž>}:æÂÅ‹_¾|yóæÍ°vrppØ¿ÿÙ³gYï8<<ìää´eË:~ûöm==½þëÚÚZhCׯ_ãñø—/_êëëÃg “Éׯ_gcc utt¼sçìÈ~û·A8088ØÝÝÍÆÆÆÏÏÏ`0>ãIG|;p<666ðâÅ ssóE‹Áé×â[ `2™Øw¸ˆ—{÷îÑh4kkknn�´àÍ?Muuµ²²²‰‰ Fëïïgggÿ¨@Œ‹ááá   €€€ú=2âu¬!¾I“&=}úÔÌÌ úOÍÌÌX¶A _GlllxxøÞ½{á 1$9ˆÿUUÕñÎn@ ŸgýúõëׯGv˜à Ç@ ä I@ Hr$@ Hr ñÏ0v’ôèè(Ü@ ˆoáõäÙÇœ.))INNF–B Äw‡UoŠŠŠÞ âñ½œÁÁÁÔÔÔI“&!£ â»ÀÁÁÁºùÓÿϱÆÉÉi``€l„@ ˆï??oo/Üæ  køÇ@’ƒ@ $9@’ƒ@ ’@L\Ðm?*•ŠŒ€@ ~>äääÄÄÄäL, ôõõ‘ÄO@@½œ ‡›6mÚÀÀ�2ø9x÷î—¨¨èÐÐ’œ “ÉoÆ ÄD–!!!QQÑñ^ˆ¦ âb½œŒŒŒÈÈHxljjº|ùòF ÍÏÏß½{·ššÚG#8;;3Œððð_ÍÖ]]]{÷î…ÇŠŠŠ��êêênÙ²‹™””tçÎ¥K—š››Ã¨¨¨ÔÔTGGG===,š¯¯oee%öóôéÓ‚‚‚ðxóæÍL&‹ˆˆøúúŽy˜7oÞ„„„°†˜˜˜X[[øØ—/_~õê•‹‹‹¶¶öGÿ—››[OOOXXǘSMMMÄ~jiimß¾½uÄ/Ë—ör^½zåååÕÞÞnnnÎÁÁáëëÿ)eŠ‹‹kkkûÔ­âããïÞ½û«º§§ÇÉÉéùóçæææÚÚÚÇ�´´´ÄÅŽ|ù’5rYYY\\\aa!ü}æÌ™¸¸¸ýû÷gggczséÒ%MMMsssssóçÏŸ;99õôô��âããa8…B¹~ýú¾}ûÆ<Osss\\Ü»wï`4...??¿;wî|øä:::æææ’’’Ÿúk>Œ‹‹£ÓécÂ[[[]]]333a“&M Boz9Ÿ#33ÓÃÃC@@àØ±cšššS¦L)))QVV޽ÿ>Œ³eËCCÃÀÀÀœœ�ÀñãÇCBB&OžìááQ[[ ã\¸pŸŸ»m__Ÿƒƒ<–••=}ú4� ¤¤äÈ‘#:::óæÍ  P(ÎÎÎ?¡‰D↠œ ‹ŠŠ¼¼¼ÒÒÒX-êêê �xòäÉ7��8ž}ûö­‰‰‰±±qHHHcc# LOOïìì444„ƒ&%% �þøã·téR(i;vìxúôéGŸJFFFkmmŠŠ***ºwï&<›6mš?þË—/_¼x!##síÚµ¼¼¼Ã‡GEEUVVúûûËÈȸººÒh4�€]LL kþ&''kiiÁ$üüü²²²��/^¼8wîŒfnn¾víÚ;wîÜ»wÏÖÖÖÔÔôâÅ‹)))Û·oùòeVVÖîÝ»W\\|òäÉsçÎÕ××à #""xxx˜LæÚµkaˆ°°0¼m]]¦²S§Nõðð@¯:ñŸéå´´´äççËÈÈhjjB§Ð¢E‹¨Tª¯¯¯¸¸¸ƒƒƒÁðôôLKK366VPP��,^¼XBBbß¾}7nÜ055uppÈÌÌ´±±éïï‡÷Z»ví«W¯ÌÌÌbbböîÝ[^^îêêÚØØ(&&¶gÏžÄÄÄ7oÞü†&‹-244llltssSRRòññaísäççÃãÚÚÚ’’ìÔµk×444-Z$--íïï;:GŽQUUuww·²²jll ‹‹‹ƒŠC§Ó­¬¬ìíí…„„âââÆøÐ>Ó=q℃ƒ÷òòJNN~óæMbbbKKKvvvbb¢‹‹‹††FII‰ƒƒCKKËš5k¸¸¸��ööö˜FB$%%kjj¬¬¬¼½½§L™çîîž‘‘ááá122âàà %%åççS^^ž˜˜XSS�(((HLLlnn¦R©‰‰‰Û·oŒŒLLLtrrЉ‰133sppxõêÕÚµk‡††V­Z•œœìàà`mm}÷î]gg熆†Í›7———;88É䈈ˆýŠbâör> ™L&‘H²²²=JJJjnn¦P(pôiÓÖ¬Ycff6}út..."‘˜––†íKJ§ÓSSSÅÅÅ«ªªúúú233W­Z•““3wî\ ‹öööŸFoXÅÛÖÖ¶££#22rÌÐÈóçσ‚‚ÔÔÔ.^¼Cà`LEEÖ®‡=žöövhá .Ðh´íÛ·ÛÚÚrss_½zŽ¦Ì›7ïþýûƒƒƒk×®µ²²»|ùòGŸ'-- vA-,,¯]»¶víZccã?ÿüóÑ£GX§ ÃÚÚÚÌÌ,,,ìÕ«WsæÌÁ#9\\\+W®œ4iRYYÙÑ£Góóóuuu:_XX¨££cll\^^YUU5æZVrssOž<©¡¡±sçξ¾¾Y³fMš4éÖ­[ÃÃÃììì)))ìììÆÆÆCCCýýý¯_¿æååMJJòôôœ6mšˆˆzÕˆÿ¶äÈËË'''Ÿ8q�P]]ýÑ8ÚÚÚ[·n…q:::¾üæÂÂÂêêê?™­;::V¯^ÝÞÞ~óæM---ÖSúúúsæÌ)++ÐÐÐ022ºték-|ëÖ­ŠŠ Ö«¦N �¸~ýúÚµkëëë­¬¬îß¿;: …N§ÇÄĬ\¹’H$nڴ飪£®®îéé‰uJ>5>ÇÊ”)Søøø¾ð/sssS(�Àž={Þ¾} ï0.»<yrݺu|||¼¼¼XàÌ™3±ãáááE‹ŒŒÀŸ²²²‰‰‰eee€:K øKÎõë×}}}—-[fmm}öìÙ‡~gëÖ­<8þ¼¼¼¼µµ5lžÿštww[ZZ¶··ß½{÷C5VVV¾téRZZš©©©œœ ˆˆ¸}ûö¶mÛ–-[C>|àÀ‘˜˜˜¼¼¼ððp--­ØØØ+VäææÂjwáÂ…L&3))iÞ¼yqqqVVV˜×n """¬u÷÷¥±±ÑÆÆFYYùâÅ‹«V­‚ªS^^>^ÉQSSû¼È±³³Ÿ<y..®™3gBQß¾}{qq1‡ƒ“5Ä@r >èçççîî~ëÖ­ÐÐж¶¶ÖÖV~õf``@]]]EEåôŸáåË—Xëûç`tt´  @AAáS½7“êêê‚‚‚;wÂ}L&³©©©µµUVVv��‚‚‚©©©===ååå¹¹¹plL]]H$b·ÊÏχ{ðáñx8üöÏ0oÞ¼””ìçÐÐPnn.t¥òòò*++ÉMΜ9óÇüm´¥K—vvvþõ×_��666®®.333iiéÓ§O¯[·NMM-88ªNUUzÕˆÿŒäðóóoܸ‘ÉdÆÅÅuuu-^¼ØÅÅåüùóAAAׯ_߸q£¹¹ùÁƒ………ýýý»ººœ}}}ÝÜÜÖ®]»råJ¹zõj##£¡¡!<ÏÉÉù×_-\¸POOodddÒ¤IQQQâââ.\صkWddä¶mÛÜÝÝ2s766bÖL™2%"";% ##ÓØØ(%%C>3¼�8þüºuëììì Ø466>zô~—óâÅ‹™3g„ètº¤¤d\\Ü—<ž]SSÓùóçcccÛÚÚöíÛ·téRÖ™uåÉ“'††† N´Ã••µµµ…OÒßß?{öl???>>¾#GŽœ9sæõë×]]]ëׯ‡ß$µ´´œ={v×®]<ø0¡¨¨¨eË–­X±‚ƒƒ£ªªêÉ“'!==L&ëééÑéôžžžèèh))©ýû÷oÚ´éÍ›7³fÍò÷÷G¯:1À„ÁÁÁîîîþþþ„„++«OEíííÅÆcøùù…„„ºººº»»¡_hxx¸··WLLŒ››»¥¥eppPRR’H$666Bo¬¬lcc#¶¶‚‚ƒÁx÷îüÉÁÁ!-- �liiáââÊÊʲ±±YµjÕý£Ñ¨¨(WW×÷ïßcB$%%%Z[[¹¹¹ÅÄÄz{{‡††DDDh4Úû÷ï GNXXó,µµµõ÷÷‹‹‹sqq577³®£#++‹Çãá161öudeeÇ<kºc€]]]˜»¯½½½¯¯>ÞÀÀ�k¶ÊÈȰ³³�Þ½{Ç`0àdEVFFFX' pqq‰‹‹�úúú0/+,K�€÷ïßÓh4¬,‰ŠŠö÷÷÷÷÷KHHprrbšÙÈÉÉÁ9ÙØŸÅþéððpSS äää”@¯:ñÉÉÉúí·ßþv)/~~þÞÞ^ƒàãã3ޱ^^^Öñ[èäÁ>w�`ó‚Xßp($XÁz9Û˜JêÍ›7«W¯ž5kÖ§fXýwùðÏbµ0ŽY˜ŸŸû€‰ÕÂ��V…øÌç™MëSé²" �¥CTT:N¹¹¹?š­æ,ÇGSáááááá($$µ+KÆ“î§þ,@ø[ ˆ êXûÇPWW°µµUQQZ²d r‰ ’œó4ìì&&&ØT`ø™!@ ä|ðx<ë¢8?###QQQ¨´!ˆŸƒA¡P~Éùù`cc#pý4øiD’3áX·n6 @ ~é&82@ ä Ž¢Æ�� �IDATI@ Hr1aAÓ~8hî�ø)¡!É™X<xðà£+m#Ä EEE$9 66¶uëÖÑétd ñsÐ×ׇÇãÙØØþvYO$9ÿL&³§§Ù@ü`+I» Žl‡@ ˆ†/êå´¶¶æççKKKkhh`UUU•••“'O×*ñ)))£££&&&t:=99™H$ÀnZFFMTTÛóKÈÏÏommÕÕÕÎÌÌìîîž={ö‡Kßÿ» ¥¦¦òððÌž=›F£½~ýZXXXWW—Õ‚‚‚EEE0¾’’Ò¤I“XïPPPÐÔÔ¤­­-&&–““ÓÙÙ ÃçÌ™ƒí,€Yø Ÿª©©©  @NNNMM ½âß—œ×¯_ÛÚÚ®Y³&,, ¼s环¯ï±cÇÆµz˜½½=Fëèè½zõª   A__ß7Nœ8¡¯¯£ikkKrNŸ>ýèÑ£û÷ïþñÇ•••êêêMr:;;­­­•••³²²ªªª¬­­õõõ>|�xõꕊŠÊÓ§OÕÕÕ+++544öï߯¤¤/óæ§§gFFFLLŒ°°ðÎ;…„„ÓÒÒ<¸víZ¨:vvv===ŸßTãùóç[·nupp8}ú4zÄ¿/9¬TUU½yófòäɬyyy555ð˜L&KJJ¾xñ¢½½ÝÐÐ077—F£™˜˜ððð$$$À-ÿýwssó•+W‰ÄèèhyyùÍ›7kjj¦¥¥ÁMÞ²²²°&¿––� ¸¸¸´´êèè(((deeÁ- ÓÓÓ555§M›—£~òäÉÀÀ�ŒlaaÁ`0>|H$çÎûäÉ^^ÞùóçOœ••îèèØ³gϺuëŽ;¦¡¡áææ-_WW#Ÿ:uª¸¸øÉ“'zzzÞÞÞééé–––XGgéÒ¥L&ÛË™‹‹káÂ…4-99YHHÈÐаµµ5##CJJJFF&''fëÛ·o¡…bBHNUUÕéÓ§sss-,,Š‹‹a`nnîáÇH$RFFÆÒ¥K·mÛæçç—––æééÙÒÒrçÎ 6$''ŽŽB%X°`Á† ÄÅÅ_¾|™šš �èééyùò%dž LLLäå僂‚’’’fΜYQQ!$$tðàAvvö'NÔ×׫©©åääÌ™3ÇÍÍ-//¯¥¥�••emm}ìØ±œœœW¯^UVVººº‰Ä»wï YXXlذïøñãIII999AAA ,øwó ±±1##ƒL&_ºt †”––¾}ûVCC»víÚŒ3Èdr\\ܘË;†?xð`ddäâÅ‹±±±Û·o_¾|ùààà‹/BBBH$Ò† f̘ahhXTT´aÃ33³íÛ·¿yó�PWWWRR‚$@üPÆ7} --íÖ­[óçÏŸ>}:¶á|llljjªÝ… tuuà±Þ›››¤¤äºººüýýá–kçÎÃî),, +M999ÖžÓ¥K—Èdò… >,%%U]]]WW',,ìíí}áÂCCÃëׯ¿~ýÚÑÑQ[[�°sçNeeeì^^^ïß¿?}úô… ‚‹‹ )//?~üxss3k}ýoñæÍ› .`?KKKO:UQQqàÀSSS(¥Â˜‡ ãÉ“'ÑÑÑÑÑÑ4 †ìÞ½.'îââB$/\¸àçç×ÙÙyðàÁ&=cÆŒ 6��æÎ»råJô> ˆ‰åXƒ˜˜˜P©TØ@†¼xñbhhs¯AöîÝ+##óíOI¡P°í€ÄÅÅóòò®\¹RRRòuwãåå=vìØ˜GýwQTT444Äô¦¼¼ÜÓÓêMffæŸþ9þü™3gFDD°^UVVÖÕÕßÐÐàììÌÇÇ�X¿~=G%@ü<’ó!ÍÍÍååå³fÍš5k–œœÜzÜœœŸþþ~mmíîîîŸ&¦L™bccê7‹/†§>|XWW'""’ŸŸ_^^�xüøñ»wï��Û¶mÓÓÓ{õꕯ¯ïêÕ«¡äœ8q‚}n…@ &"_ù]NvvöëׯYC¬¬¬Nž<I¡P¤¤¤þvÕƒqþüù/OîÍ›7ÁÁÁéééÉÉÉÉÉɦ¦¦'Ožœ9sæ‡1ãââà¸Î…ºº:8i j||üìÙ³1½�èëë+**655555A§Ùû÷ï?úÅï•+W°¹Ÿ¡¡¡!>>þÃðÜÜ\Öyêñ/÷r¦L™bllœÍÇLJÕzFFF¯^½zòäISSÓ½{÷TUU—,Yò©;lÛ¶íÔ©SgÏžíëëû|ZÊÊÊfffEEEþþþ999mmmššš³fÍ"“É©©©ÃÃÃbbbZZZ S§Nµ°°(**ºs玴´4¶´Œƒƒƒ¯¯oXXÏèèèÎ;'`TTTܼyséÒ¥¬U¿¿¿?<¦P( .\¸p!üÙØØXZZºvíZ(º7oÞLMMmoo߸q£€€€¿¿?Œ¹k×®ÐÐPÿ¾¾>~~þM›6‰ŠŠ®_¿>99ùæÍ›X4�€ººú‚ òòòDEEg̘^ ñãÀãñx//¯¡¡!8¨®®®þa$'&&¦¯¯o`` ¬¬Ìd2gÍš5wî\(--Í`0˜L¦ššš“““²²2‡›2eо¾>///›®®îœ9sˆDâìÙ³ÙÙÙq8ÜÞ½{ÙÙÙ)Šžž�€›››B¡hkkãp8AAA8x£®®Îd2™L¦””ÔªU«ŒŒŒäååaZ .ÔÑÑa0ªªª†††""" ÃÆÆFVVV[[[__ßÐЋ‹ Fž={ö¾}ûp8ÜGý¡&~óæžžÞÐЇãää¤P(Ó¦M�ðóóS(MMMaaa …¢¦¦†Ãá$%%'MšÄü ²²²ÿ×'ecSSSƒ6‚mÚ´ið666===}}}<¿pb2™&&&[¶láááéÊÉÉ­]»KTBBBUU•Édêéé¡W@ü-MMM\\\bbb»z$‘Hf2™/_¾LKKÄÁÁÁîîîþþþ„„+++dÍïKTT”««ëÏ4ò„@ ~q°5ÖþvYO~~þÞÞ^ƒàããƒÖXC Ä?’@üC Ù´ÿt:MC ? íííBBBHr&j_’D"!; ˆŸ‰WÂD’3á P(ƒƒƒãÚâ@ &>p™f$9 EEÅááad@Ó$@ Hr@’ƒ@ ˆ‰ š>ðÃ{ ÄOÆàààx'­!Éù'¸yó&2ø™˜>}º¢¢"êåLDº»»Y·'@ ˆÿ4D"QPPÁ` É™ˆàp8~~~dñsÀÉÉI$¿dOÈ1 éø‡‡äÜ»wOéœ>}ž<yRII)&&†5æ† ”””rrr¾üæåååJJJ+V¬@Y‚@ ¿ºä<xðÀÙÙyÑ¢Eùùù®®®þþþ�€þþþÎÎÎÁÁAÖÈçÏŸÏÏÏ×n›t:½³³“F£¡,A ˆ_Zr=zäàà`iiÄËË»}ûö½{÷úøøbqvìØ!!!ñðáC�€½½=ÖË™7ožÄÿèè耑¥¤¤`ˆ¦¦&� ººÚÀÀ��““caar@ ~]Éa0£££lllììì��<Çãét:6]ÁÝÝ}Ö¬Y¶¶¶?…›]ååå½xñ¢¥¥EDDDYY™F£IIIŽŽ¶´´”––¶µµM›6D"¥¦¦�tuu<x€r@ ~]Éù[üüüV¯^ý©³ýýý½½½L&sL¸  `KK •JEÙ€@ ¿ÿÄ$i <�ÆápÈè$瓉DÆÏÏß×××ÛÛËËËËÃÃóþý{��FûÌí?ÿüSEE¥­­N§óòòbá £µµÇ‹‰‰aÃÃÃ}}}_·Å)@ &2_äX[°`ÁùóçSSSÝÜÜÞ½{áéééää#ÇÄÄôõõ‰ŠŠrqqaJHHppp455½{÷N__þüù}}}²²²�€wïÞijjÚØØ��888$%%‡††ž>}ºoß>”1ñ‹J�ÀÔÔ4(((//oÙ²eñññ{÷îuvv�ˆŠŠÂÏtêëëKKKÃÃÃç΋]cllìææ¶lÙ2>>¾´´4^^Þ¬¬,‰´lÙ2{{{]]Ý'Ož��”””îß¿ßßßïÞ½‹/¢ŒA ˆŸqŒå˜™™™™™ ܱcÇŽ;��Ë—/?xðà‡WùJ’™™ùa ªªjvv6ÊøÕ{9_NuuuOO’’²/@ ~ ä\½z•ÉdFDDÀÏ<€|ÿIÒGŽAfýˆ¡ÙÑ¢Ýâg鬰}ewÕƒ?'//Ï:;@ P/ñC Óé‹-ïv­1ÁA[´MDúúú -Ú$@ Hr@’ƒ@ ˆ‰ š>ðÃ!‰È_Îèè(NGvørp8@@vørFFF¾bªIÎNNN¸'7âo‘““ãççG’3.ØØØ Fqq12Å— ªª -†L$çç„Á`¼|ù-ÿó÷e‘U_GOOOnn®²²22Åç!L&m‰$çço‡êèè ;|..."‘ø™½þŸ——•±/±;;{oo/2’âûÐÞÞ�——ß´i2ñß“œüüü[·na?çλpáBÖqqq¬#JJJȾÒÖÖvóæM¸É¤¸¸øúõë��]]]++«1ñÒÒÒ��VVVºººXø¥K—,X   0&þáLJ††°~ÜĨ½½ýÌ™3°Þºu+k|*•zçÎì§‘‘‘‰‰ �àáÇ�€U«Vikkó•••�€íÛ·KIIM@óvvvKKK×××ûûû3 GGÇ_¼È=þ|xxf+äîÝ»poªõë׫««³F>{ölkk+öóèÑ£###° xxxŒ¹YYYdd$�@[[{ÕªU0055õñãÇ�€E‹޹äÚµk%%%�€­[·ÊË˳ž:zô¨‡‡šñ…üùçŸÉÉÉfffsæÌïµ£££ÞÞÞ<<<^^^ÿØÑ$é7oÞ>|8''GEE¥µµ5<<üõë×câ<{ö,<<|``@EEEEE…››•†1twwïÞ½ÛÓÓóöíÛX`iiill,4Z]]kíõ¦°°žMHH R©�€Ë—/ïÞ½ûìÙ³---¦råʉ/ªÿþýû3gÎÀƒqîܹ1õE^^žÊÿzSRRC~ÿý÷üü|(rXþ†††~4õžžžÄÄÄ-[¶ìܹsïÞ½p×ó_–ôôôÝ»w?~<++‹Uojjj`>Þ¾}{̼ƒØØXaaa¬<àp8ƒáéé  ùøø°Æ///¿qã<ÛØØ �HKKKOO‡ÏŸ?g½äêÕ«]]]ðìÅ‹ëëëYLaaahAÂ/GDDDEEEPPð+® ¿zõêÄêåx{{§¦¦Nš4‰‹‹‹L&ß»wžzøðaRR’••USSÓ«W¯ìììÜÜÜÆ´YAGG§µµ•õ%çççŸ;w.ܽûæÍ›+W®ÄÎæää mܸ�àââRUU5mÚ4%%%"‘»>ÅÎÎŽuf6@ “É�€¬¬¬Ã‡»¸¸°ÆŸ<y2L#++KFF:99UWWO:UIII]]]RR�@¡Pììì$$$&àèèèèëëëáá1æOý‚ˆ‰‰éèèttt°fddèèèØØØ��lllêëëûí7ÖVVV$ ûÉd2uuu׬Y�hll\²dÉþýû±³MMMEEEpË’Û·o§¥¥­ZµJLLláÂ…Ó¦M�9r¤°°µ£C"‘”••edd�� ,X¹r%l:tHQQÇOp«æççGDDÀcøÂ&&&>zô®ZµJ__ÿúõëYYY›7oÖÒÒ )++Û³g‚‚‰'š››aL???...ƒ±cÇ...ooïýû÷‹ŠŠ:t¨¾¾þÔ©S0šºº:tNdeeA�`þüùMMM¹¹¹$©°°PNN®¢¢î¹¼eË–”””ÒÒR�À¾}û …<øþý{xy``à¿b½¿ïå Ã)!!¡¢¢‚…ÿñÇ'Ož––ÎÌ̬¬¬,--=qâ„““SaaáÏúÇÄÄ899999eee…‡‡;99}ùäT...›¥K—²JIIA½ÉÌÌ,++[·nì,ß¿ÿS÷™;w®Í˜êþÀ]]]ðØÕÕÕÉÉiûöíð'Ô؋ڳgϘ¾xñþ©øøx²bÅŠ¶¶6¨¡¡zFFFPoNž<¹aÃx<Ñàåå;wî… œœœüüü~qÉ™<y²Í˜ik×®­¬¬„™;kÖ,8—Òßß¿ººFðòò‚gûûû�8êMOOÏ©S§Ž?�¨¯¯?yòä§ÒUSS›6mZBB‚““77÷üùóYÏÊÈÈ:99­\¹k¤ÆÇÇ/^¼x‚ÇööíÛ”––R(çççwçÎÄÄÄ'NôôôP(”ÆÆÆÃ‡§§§§§§GGG¿{÷�ð×_EGGwtt;vìâÅ‹jjj åÁƒ...###ÎÎηoßÖÖÖÞ¶m[ttôƒšššvïÞžžN¡PÄÄÄBBBΟ?Ÿ““ãíí]]]M¡P†‡‡}}}<xŸŸ]RR’™™yèСÎÎN …RPPàééÉÎÎN¡P`O·©©ÉÛÛûòåËS§N¥P(wîÜqvvž ’#-- ½„ŠŠŠÓ§O‡=:q℺ºº‡‡‡ŠŠŠ­­mdd¤“““©©iYY™»»ûOù•À­[·üýý¹¹¹Þ½{—žž.-- =QßHvvöÇ—.] -L"‘&Ož<®;rrr�–,Ybjjj``°mÛ6,BCCÃÙ³g—,Y2oÞ<Ö gÏžííímjjjjjZQQ¥®´´”››¶µµa2�€¤¤äŠ+øùù'`µµµ…„„œ={VMMíâÅ‹Hu>¤¨¨HPPfnCCC[[�`æÌ™Ð9sâĉ•+W³;wî†Wõ÷÷ïÝ»wñâÅK–,�ðññÍš5ëó )))™ššŽŒŒÔÔÔ|xvÆŒ¦¦¦%%%4 �àááááá! 0Á­×ÔÔ”žžÞÔÔD£ÑÜÜÜ8 ¦¦VRRRPP ¥¥emm­¢¢’““S]]íèè8cÆŒ 6ïß¿ŸD"Í™3'((ÈÞÞÞÚÚšH$ÆÇÇÓéô¸¸8<¿råJ###˜ FKJJ¶¶¶644„‰ÖÕÕ½~ýº¾¾~hhÈÝÝ}ß¾}cj‰¬¬,IIIkkk™´´4555kkk‘¤¤¤îînƒsçέ_¿ÞÚÚÇÇÅÅý+üÊkeee�€•+WÂO´µµ±æÛ·o?~ü¸½½ýç{Wß¾}k``àææÖÙÙ«¯¯¿lÙ2qqño¼-•J½{÷.ë(ýW|`±`Áx`ffúúúÜÝÝáÜ­ææfŸ5kÖèëë¹P^^kf[ZZÈÈÈXZZ�?~ÜÐÐ0cÆ ¨7ÒÒÒ–––¶jèïïõêUpppww7‡KNNvwwÿE´¤  �ëyP(”-[¶|4Z^^žŽŽÌܸ¸88&G¡PàYccc,æÎ;ág¹ÃÃÃ...ëÖ­Ãú+°wþTUUUUUóóó+**°ò‰²aaa]]]aaa:::°Ù4‘ÑÖÖ¾qãÆË—/SRRLLL´´´ž>} �¸sç•J-**‚1§OŸîëëëîî~ÿþýýû÷;88 ¹»»Ã![¨µ¦¦¦¬‹*++×­[‡ùEÉdò7ž={væÌ™ÄÄD33³ß~û óLü-&&&;vì€Ic3Œþ3’ciiI bbbTTTÌÍÍ/^¼ø×_mß¾ýÃí'CCCCNNNNN.88xöìÙß®7ùùù7oÞ´µµ2eÊwyB;;»ˆˆÖ†¿——צM›>Ú,}þüyII‰““ÓßÞÙÇÇGFFÆÂÂâëÆ*ÿafÍš•œœüët_¤¥¥ííí1‡í×Ýd×®]ûöícõš2 ;;;''§¿ÕŒ„„„ÎÎN8\ô!þþþFFFp¤’––VXX‰{{{ׯ_ûö퉹w»¸¸øâÅ‹ádž†¾}ûû°TGGgùòåXE�xöìY]]�àÉ“'æææBBB{÷ñõõ•HOOÇ:‘ETTËPqqq)))))©©S§2™Ìˆˆˆ¢¢¢q}Óº}ûö;wî„„„<}úôßš£ñ•™J"‘ìììŽ?~øðaWRRò矲Ž{#¾ŽŽŽ†††ï¥7�€”””1ßðæåå}Ê ‡¿äι¹¹úúúÿ ½ù5f ýu¼|ùrÌ׸L&óÙ³g111_~“wïÞ544|¦™5¦Àc;¾zõÊÉÉiÂN"ÈÎÎ>~ü¸¾¾¾««+“É<wî\YY™˜˜tN˜˜˜DDDüñÇ®®®±±±ááᎎŽzzzܺuëÅ‹_½zÕ××§¯¯¯¨¨ÈÚ.„n ;;»1Í&“7oÞ<xpæÌ™½½½§OŸž?þ®]»˜LæåË—+++¿\uÒÓÓ ÄÅÅñxüLr�� ÞÞÞGõöövpp0119}útdddIIɱcǾc:¡ “••-,,„-hqqñ¬^½ZKKë«ïùúõëÅ‹ÃcSSÓmÛ¶Ý»wF£ÙÛÛÛÙÙ]½zž]ºtégš™6lð÷÷‰‹‹³²²¢ÓéÎX�444`Ihjjúùùeff&%%yyywvv³³gφ…~Ó¦M‘‘‘0ÐÒÒóºxzzb.µ .ÈÉÉMÀ<ª¯¯wqqÙ¹sçž={„„„ÁÕÕõÒ¥K0s­­­¡ËtïÞ½ªªªááá^^^p^Sdd$‘Hd2™ÃÃÃXù‘””¼råJUUUppp``àÔ©S-,,àY--­;w²—-[uECCÃØØØËË+,, Θڼy³²²2ÏÿUIììúúúvM%%% …žœœÜÒÒbffæèèÈÁÁQYYyíÚµ§OŸÖÔÔ¬X±bÊ”)wîÜikkÓÐÐ044LMMíéé9wîœÍÆ999ÃÃÃíìì,--ããã---ׯ_¿mÛ¶—/_�äååCCC=<</^ÜÝÝÍÍͽ|ùrQQQ88”ÐÔÔdeeekkõ…O±jÕªuëÖqppÄÄĬX±:Wÿapapp°»»»¿¿?!!áÃO�]]]•••"""ŠŠŠmmmuuu’’’pŽc}}}KK‹¼¼|__æsTQQ™˜cËß^—yyyååå9;;[YYíØ±£¤¤d÷îÝfff¼¼¼ŸºŠ/<<NEƒ}Žªª*ìû;V^^ÎÚ•VPPhiieµ0�@QQ‘uªBYY™´´4–nAAªª*l7åææ2 l•ááá·oß²>ÏäÉ“»»»ÛÛÛá‡;íííµµµ°6‰Â†*ü$D" �***º»»Y}Œß×óŽ-xó-Žæ¡¡¡Ç;;;+((àñø+W®Œw"Æ<ß××—’’bjjúÑÍÍÍ CZZ ©­­…£­JJJ°ÛZZZ*++ «þ‚‚˜ÚÚÚx<žÉd D"QSSs`` ¶¶VMMµ c³«[ZZà7222ÐMW[[ËËË Ë0V–ÔÔÔXõö´´´ØØ~Ⱦ*Ø‚7£££_}XÂc1118ÚÔÔÔØØåååÅÄĪ««;;;¡…ËÊÊzzzàŸ-,,�L:µ  €N§O›6J¥âñx™É“'“H$*•ÚßßMÂ€ã»ØÄBø¶666655ÉÉÉ ¶µµÁZ¢²²~ùÄÏÏ_RRÒ××ßÖ·oßBWžŽŽN^^“É„?uêÔW>ùùù{{{ F@@€ÏI£±±±££CVVVHH¨¶¶–F£‘H¤Ïè͇’ƒø¡’UNoáææþ–Àø[ÉA|_ÉùîÌ;—@ $%%µµµa’óÓØ|Œä 5ÖÆ‡´´4ÖZüp±ÄD€H$~‹Ÿø‡ £P(d2™N§KHHü[Ó—ÿä ÍyFÚ�� �IDATÄ¿‰ºº:\òöYî\äüàp¸Ÿrpë»[ áëßdvvTÆþ»eŒu…¡Ÿ¼ ¢Rø£Áãñööö?h8��ˆ‹‹›››£2†@’ƒ�pfë\/Äg€³h_Nïééÿê'娌!ä ò@e ˜X ž8@ ä I@ Hr1qAÓ~¼ª£©«ãÉd¢ÁpTÆ~(c–ZG Éù©àççG3¤¿...:Ž&ûŽ <ÏÍÍÝÛÛ‹Lñ%ððð N¨5Öä ¾'t:ýêÕ«èËð¿‡Ãéééý:ŸaGÚÚÚâââÆ,ÉŒøhwpáÂ…Ÿ_‡$ç¿oevv¸eâó]¸’42ÅW ""‚V’þ[°•¤‘)þ5ÕG&@ ÄDéåtuu•––Šˆˆ(++·¶¶VWWKIIÉËË744À-˜��$I\\»¤´´´««K]]ïíÛ·ýýýÚÚÚD"‘J¥ŽŒŒÌ˜1ãWí,//ÇV×ïîî.))ÁΊ‹‹ñ,ÕÕÕ555�&Mš÷»�”””Àñ!MMMèNÉËËc™9s&<),,ÔÖÖÆNõôôÀ§………UTT��0[±rrr¬Ûyý·ÊËËãææ†¦ÑhÅÅÅBBBݨ­¾¾¾¡¡A^^^JJêóÅÅÅ4 ³0Fvv6NÇ,<éèèèêêÂö jjjª««ÃÎ***JHHŒ¹¤¨¨H^^žÕãßV�€žž¶æððpqqñ˜½ºººZ[[ÇX¸©©‰N§ËÊÊb!ÕÕÕpÓ?¸éƒÁ`deeqppL›6íW—œ×¯_¯^½zÅŠ?Þ¹s§‹‹ËñãÇ£££}}}I$’¬¬¬³³ó¢E‹°K8ðôéÓÄÄÄ™3gnݺµ°°0//OAAÁÚÚº£££©©éûî&ù_axxøõë× !!!ééé00''ÇÑÑQCCþ\¸p¡‹‹ vIMMMTTTVV�ÀÔÔÔÊÊJLL¬¨¨(<<¼¦¦�`kkkjjÊÃÃcoo/!!A$á…<`0ïß¿÷òòzóæ ¦7üñÜÇ^EEÅÑÑQMM-11Ñ××n;�°±±±¶¶þ¹¹¹yÑ¢E/^¼��äçç/]ºÔÔÔôæÍ›FNMM½uëÖÆ?º#ïÞ½{ÓÓÓŸ={6¦†]¶lYoo/ܪy¢ÑÙÙYXXøâÅ‹ÚÚÚððpxûöí+W®`Û;mݺ•ÕWXXØÙÙéáᬫ« 333úûû�{öì100}ùòeGGÇ‘#Grssa4–ŸŸO¥R333oܸ‰MEEE||¼°°°—— ¬¬¬ŒŒŒ„åÐÒÒÒÒÒ©+###'Nœ¼~ýú¯.9Ÿ‡B¡,]ºîG[XXØÜÜÌú~feeA·iFFÜŒ’œœÌÆÆ6wîÜ_ªTõööõõõ ×ÓÓƒð!QQQBBB¿ÿþ;�ÀÅÅELLÌÊÊêØ±cŽŽŽFFF�€yóæ©««Ãm­¯^½ÊÚZ 3û«¤¤$::úÑ£G�€?þøãôéÓ—/_�,Y²äôéÓ?·ý››› ᱂‚‚²²2™L–€]½’’’††MMÍÖÖÖÖÖV¸‡7Öêêíí3g''gjj*N�¤¤¤Ì›7o¢ýÇššš   ––¬YµjÕþýû?zÉýû÷sss±M”!7nLII½j ‰–––ááá   ¸ƒ2FcccPPPGGk·øíÛ·/^¬­­µ°°ÀÃÃõ´´Ž?�X¿~½¬¬ì‚ þ£©­­ kÃÉÊʪªªÖÖÖVTT())ŽŽÂý¹i4fRmmm‘œœ•’’¸«¾¾~ff&ÜÚÈȈ}ÇŽpæôôt ÌÌLAAA¬ð«HŽ˜˜ëëÇÊäÉ“ÓÒÒ®_¿0}útOOÏþþþ5kÖÀmÕa[»³³�»páB˜””“’’=þü_Gr„……ãââ***ìììXÃ[[[�222_²¥®®nMM ¼DCCs†¤¤¤À–ã‚ ØØØ899ãââZZZLLLþöžuuuð†JJJ° þùô&44ôÁƒšššµµµJJJÞÞÞ÷îÝ;uêÔñãÇçÍ›çííÝÖÖöÿØ{Žîñ{v—Ý¥÷^D:RDŠ bQŸ5±ä±k¬1&*&**ö5ÑX¤)¢ô"½÷^Ø^Þ?æ÷Üw¿€ˆ )óùkwîÜÝ;çž™3sæÌ̪U«ž>}úæÍ›   xcrrr~~þ³gÏüüü¼½½ïÞ½ ÝM·nÝ…&ÇÒÒ’B¡<yò$""B0½¬¬ ¾_CCÃÉ“' ^:pà��`Á‚Cÿ²¨¨(…BihhX¸p!–hhhH¡P¢££oݺ…%Ι3gΜ9çÏŸ\`ddÔÝÝ ŸAUUsE{sùò嘛›×ÕÕ©ªª9r$<<üÈ‘#ÞÞÞ4íùóçk×®-//ïììTQQÉÌÌôõõ]¿~ýÁƒ-ZTPPÐÑÑñòåË?ÿü3::šÁ`DEEݹsÇÙÙú0âââ<==ÕÔÔöïß÷îÝÎÎ΀€�kkë dr,--·oß~éÒ%l4 �(---..^±bEggç… ��W¯^MNN¾}ûvee%œ{��=z4>>þíÛ·çÎÃÆÑ?þçŸׯ_/8…01QTTTWW‡£MMM×Ï3èÈ2000!!ö¤¥¥�³gÏÆZ:þ®�9YYYCCC8lÂ"ÔÔÔ†Ï0eÊ”eË– :ó1† R©°Œ………ØHåâÅ‹«W¯¾páÂÕ«W÷îÝ«¯¯O$áÕÛ·oÇÆÆ^ºt©«««¶¶Vð§"##/\¸––¶eË77·k×®½xñ¢··w 9@tuu333áû577_¶lY?«3XYYA•³µµ»“… åååÿýï7nÜøÏ?ÿlݺUWWZÐG»»»ÇÄÄTUU]½zÕÛÛûܹs™™™ÍÍÍ�€ƒ&&&š˜˜XXXüôÓO¥¥¥òòò***ß~ûm?­£R©EEE¿ÿþûìÙ³;öôéÓ çXKMM½~ý:6eúüùó'Ož˜˜˜ ̹mÛ¶¤¤¤˜˜˜wýÔõë×Ñù&&&ÿý7ü|ïÞ½Û·oŸ9sfè[Ξ=+èX³¶¶622:uê–AYYÙÃÃcP!ëèèüøãЇV__qNNNNNN0ßþ²sçαnrBBB`Ÿ´Ÿß‰B¡dgg¿ëÆ7¾zõ Þ 9räˆàøXdáÂ…ØÐdß¾}±±±ßÿý?Ã;wLMMýõWèXÓÑÑ£Ž5ssóãÇ¿zõŠB¡dddô«Ëœ;wîŽ;°aßÖ­[?â_TUUûí·~¿?>V䘆†ÆŒ3***:::|||DDDrrrLMMûù‹Acc#¯|"ÁÁÁÃ\Ñ¢¯¯ýúõëׯoÚ´ ¦”——c#žñºº:,c?ÛÙØØ‡Çã}||Þ;š7`sˆO¤¾¾þܹsG‹‹+..¼äááM >ÉäL:Õ××÷õë×ÕÕÕ/^”––^°`Á ò‰‰©¯¯˜þèÑ#´‘É@ ±È¢OáðáÃ]]]ïÍÖÚÚúâÅ‹~‰ÉÉÉ>œÒ¶³³»xñâO?ýdmm=èØ%!!¡ººz8?Åãñ°­QNTTÔóçÏQ]û,¼}ûöúõëVVV/^ôññyoþØØØÛ·ocs ˆÏ¶û€““Óëׯ£££ƒ²<==ëëëïß¿ßÓÓƒö5´?nhhxíÚ5�@OO££#� 77—ÉdZ[[[[[çææÂ«***0Žyîܹ¹¹¹eee��GGG8I¶råʧOŸ�Àwß}÷.×%NOMM…Žã¾¾>WWW�€¡¡a]]ü>Ÿÿ®h‘1¶¶ö¬Y³Š‹‹¯]»–œœ\UU%Á5cÆŒÄÄÄøøxuuuP4¾¾¾—.]º~ýú ]«Ñé JMM…ïWBBÆ7ÆÅÅijjjkkz‹…BêôY¼p3fÌ(++ƒÏ §§7iÒ¤1ªH“&Mrss+//¿ví•J1cF^^^¿tSRRââ⺺ºþþûoMMMX¯��@8xð “Éd³Ù¥¥¥PÂápÄÅÅg̘ahhÈf³eee´´´X,–ŠŠŠ£££›››ŒŒLww÷ªU«`ª“““”””­­-‡ëîîÞ³g·°°˜5k§Ñh666áMÉäôôt333¬w 7ƒ_åä䔕•“’’¨T*œº�”••õôôèèèèêêöôôäççS©Ô%K–@c0uêÔââ⪪**•ºaÃ8ëàà×ÚÚJ¥Rûí7l±-ŸÏçr¹öööð«”””––V||<•JÕÒÒ‚Ý4555‰”žžN¥Rííí¡yˆD¢‡ÃQÈ,¯­­-”0—Ë%‘Hööö³gφ¡«T*UJJÊÇÇgÞ¼y,KQQÑÁÁÁÍÍMAA¡»»{Ù²eeee%%%+V¬PVVÖ××wrr’ Ñh¦¦¦...d2ÙÅÅ…F£õöö9rdTx*ðx6›]UU……r8iii¬.Ož<™ÃádggS©Ô9sæØÙÙ�222¤¤¤°Üt:}êÔ©ØN€ŽŽŽ111mmmT*õ÷ßÇz0P¼ð0¸\®¨¨(¦á6›­¬¬Œ™4CCÖ––¢¢"*•ºbÅŠ)S¦|Y‘H$<Ïb±>z3iyyyccc¨H&&& .¤R©²²²Ó§Owpp€qS¦L‘““ëîlÛ¶mºººt:ÝÀÀÀÙÙY\\œF£™™™¹¸¸H¤¾¾>kkkggg:ncc3cÆ ‡ckkkccÃãñ‚ݘî’Éd‹Åçó_½z•˜˜ˆƒ‘àÝÝÝ4-,,ÌÓÓÙáÏ‹„„Ä•+WV¯^D14Øk#ï€ÍÎΞ7ož‘‘Ñš5kBBB‚‚‚Fa ô»º}}}qqqhµ÷‚í±†<.#†¤¤doo/Çó÷÷?~ü8ÚÖ�\.÷Ù³g™™™¦¦¦%%%žžž#FŒ@LÉA €››‡ƒa]ÞÞÞè ™œ± ‡Arx. }Mmœ={ö˜Þ Ç#Ž”ÉÿZîèèˆm¸‰@|v$%%­¬¬Ž!ÉA�:®££7åE¼—O W›˜À¸&UUU¤cHÇÉA�¸Y,ñ…àóùHÇcäÙD 29@&@ drL@ &<(b @ Þ@U‹mÙlöX<™x?8îën!HqqqWW—291náp8Ã<~÷ËQUU•šš:F·D&çËÂçómllˆFAA!44tôÔ课yF<™Äÿ¡²²rïÞ½HÄG@§ÓïÝ»‡ä0n@&g$PVV^ºt)’ñAàp8‹…L29ˆƒÍfß¹sGLLì›o¾AÒ@ †orˆD"’Ãx­Ë ø|>•JMHH@¢@ È伇ÐÐP•Á8wîÜo¿ý¦¢¢rçÎ�ÀæÍ›UTT"##‘Xm™Ž@L~þùç~MeRR’`[[[•¶¶6G§ÓUTTLMMǽp†åXãñx cåÊ•/^ÄRà)¿þú+ƒÁàp8<Éd2 ‹Åçóq8—Ëåóù0?@Àáp� $$„}@Ú‰@ Æl6›Á`\¹rÅËË ¦àp8Øéäóù6•�€¼¼<��çp8 ƒÉdr¹\0ÑG9˜ÔðÿãüùóJJJçÎîîÚµëéÓ§�€uëÖ%$$0™Ìùóçkhhhjj*))óù|CCC…ÎÎN%%%MMM¤šb¼"Ø`âp8ƒ1{öl üü|¬/®§§§¤¤Äb±à¢Î¶¶6[[Ûñ-–09,««««««kЕPþþþË–-�ܺuËÙÙÙËË+---,,¬¾¾^GGÇÎή©© æÔÖÖ–”””’’BJ‰@ Æ+4­ëp8œ¥K—fggGEEmß¾½¶¶V0'@(//�ÈË˧¥¥o±|€k+44411�àëë;ÌSÖ;;;[ZZúÍa(((áñ(r@Œ[>ìçç?ÿý÷ßXztt´……EUUÕĢœ¥K—^ºt ~>sæÌpnÙ¸q#ŒqTSSÃlLnn.²7b|sòäIooo$‡79ç©© NŽ=xðÀ¢®®ŽÍfËÉÉ!q#ˆ N]]ŒŸ‡ÓØØ¨¡¡LÎûQQQ‘¨¯¯ ¢R©"""ÕÕÕ¢¢¢+V¬ áááHÛÄ¡±±±¸¸~ÖÐИ4iRvvvUUÕÍ›7›››ûeÆápzzzíííiii§OŸ¦P(ÚäHJJšššª««c)ŠŠŠ¦¦¦ ¦¦¦psäÈ>ŸÿÏ?ÿœ:ujúôé›7oö÷÷‡·?|øPAAÁÈȨ«« yÕÄ8FMMÍÔÔ400000¦œ={öêÕ«�€?ÿüóÎ;?ÿüsCC@066îííÅáp±±± ,ßö�€#‘H £»»›F£………yzz"ùŒðù|EEÅ?ÿü³­­­°°ðæÍ›H&Äp›'ŽÍf›™™|ý¸8›Íþê»8¿zõÊÄÄdÚ´i£ÿ%JJJöööòx<ÿãÇ£@ FÊr#Œ�x<^SS®@F dr_vH¾zõj$âCa³ÙHÈä >�>ŸŸ——D@|(T* ™Ä°xñâæææÛ·o#Q Á¼yóÉA wëÖ-$b|@£Ñà~h_‘ÖÖVdrbœÓÛÛ›••…DL@|Ax<F£Ñh𠯎‚‚291nMް°°ŧ€–‚"™@ “ƒ@ 29@&@ ±öÅABøt˜L&ÇCr@ ÉA ™LFBøDÒÓÓUTTÄÄÄ(drïÏçÓét$‡#///''ÇÅÅ™™İ`±XHGuu5FCr@ Æ(|�@ Èä ™@ ÉA þA\\\XXxb¿¦¦&<<¼¸¸ib”0Üð¸¸8???ìëÊ•+¿ÿþûaÞ»víÚÚÚÚ{÷îÉËË#‰0+W®TSS›€'Å2™Ì`0ðx¼°°0ƒÁxï-~~~qqq¿ÿþ»ÍX/~mmí[J!µ¢Ò¤·§¯¯ÿÞ[6nÜ(xþXPP¸¸8ªDˆ‘69/_¾Ü¾}»¡¡á¾}û��=úã?p8œ¯¯ïpnÏËË+--e³ÙHÜ#›ÍNKKëè蘀öFXX˜N§óx<G$‡cuÊËËÓÒÒºººÆzñëêêòG’c‹…úØÜÔÊr[…ÓÓÓú®·oßæååýûï¿jjjK—.?~tt4ZX†øŒ ˱ÖÝÝ]]]-++knnnnn®ªªÚÒÒÒÜÜ �¸pá‚ýÿˆŒŒ�ìÙ³ÇÞÞ>##cÆ 0½ºº�°dÉ’qP“Ç.¾¾¾ùùùð¥ìÚµ+!!~>qâÌsçÎìm>zô&9rÄÞÞ>11qÇŽööö¹¹¹c@­ñxÌÞ��ø|>›Í†ç ó¶mÛfooŸŸŸïëëkoo_[[ ÓçÏŸåãä䫆½½ýòåËkkkííí%loo¿ÿ~xWpp0–xãÆ ˜xæÌ,1..&þ÷¿ÿÅaÅùêëë³… Ç õ±�:‡üª²ô~TiiépnŸ2eй¹yDDDuuµ³³3—Ëe2™ØSyyyÁl………XâÏ?ÿ �ˆˆˆ°··?yòä£Gìíí¯]»vãÆ ,ϳgÏàûöíÃóóóaâŠ+°D¸ˆÅba)Ë—/GUxrfÍšuìØ±'N¼yóÆÛÛû‡~˜7ožŒŒÌ¥K—NŸ>½nݺ•+W9rdË–-/^¬««+,,\³fMGGƒÁ¸ÿþ¾}ûªªªÎ;'!!$þµ`2™/^¼`0wîÜyýúõîÝ»i4Ú;wBCCOŸ>ÇãÕÕÕ9²téÒ 6œ;wîÀáíÛ·ýõ×þý÷ßx*âè·7¢¢¢4MpƒhuH$Ò0=l555………+W®<sæÌ¾}û-Zîë뛞ž'**jmm=sæÌ§OŸ–––.Z´¨¦¦¦¢¢"--MYYùêÕ«‰‰‰Äápvvv»wïvqqÙ³gÏíÛ·ýüüðx|OOϹsç6mÚ´|ùòƒnÚ´éêÕ«? ¼pႹ¹ùªU«ÜÝÝÃÂÂÔÔÔ>¨ø ™_ˆEèœÿÌÇà§T–€HœNWWw8¿£§§‡Çã‹ŠŠ¸\®½½}KKK|||ss³‡‡‡——×±cǼ½½åååoܸ‘’’²oß>giiYXXX__O"‘ÚÚÚ`WfõêÕß}÷Ýü±k×.œœ|çÎcÇŽ988üðëV­züøñáÇãââ‚‚‚TTTfÍšåààššjgg×ÜÜœÐÚÚêîî¾|ùòÀÀ@T‘'„Éûî»ï/^L¡PüýýïÞ½»víÚ­[·¶··wuuÉËËëèèHJJ677÷ööbzÿ÷ß[XX(++‰D�ÀäÉ“ ’ø×µ:ííí:::µµµ4­§§GGGGQQ‘J¥¶¶¶nܸÑÑÑQRRRJJJZZº­­ ¦÷ôô())=z´®®.99y,ÚÌê°X¬á[�À‰'œœœÈdryy9›Í®®®ær¹ZZZâââ9998fãp88.77·  `åÊ•“'OÖÑÑ)++ëëëknnvqq‰‰‰—‘‘‘••íèèèêêêìììîî¾zõª¾¾þ… h4š¼¼|@@�NWSSÓÑÑ!‘H¥¥¥烊ßÔÔ”ö T"ª„Àè#ÉM®,¸Õ8"KJJêè興ˆ°Ùìšš‹UWW§®®®£££¦¦æìì,"" � R©«W¯þù矯_¿~þüy999)))¨K;wîܸq£¼¼¼ˆˆˆ°°p]]“ɬ­­e³Ù?þøcBBBJJ Ǫ¨¨ÐÑÑ…ŠªðD19��QQQQQÑ 6ðùüßÿýäÉ“xüPN¹Û·oÏŸ?Ę@BBâÁƒþþþ�€žžž~Wa1Ê‹@§Óccc-ZÄçóÍ�­Niii__Ÿ¹¹ù{PII‰D" zICC��'ÉÔÔÔ¢££åååá×´´´)S¦0™L¬Çzøða��Ö'Û³gÏæÍ›ýõ×mÛ¶‰ˆˆœ={vîܹð’%|pe’jgIFãYÜÁí1‹+žT)íÐCšBúÐí0zzz¦L™ÂåòËÂÂÂP•+WúùùIHHHII�üýý¯^½J¥RáU99¹_ý5::“�àÙ³gÇÕÕÕÞÞž@ dddÀôÞÞÞwý)bŒ2¬¹œˆˆÝ»w‹ˆˆlÞ¼yÿþý}}}}}}CÜ"++‹ìÍWDGGÇÔÔôƒn¹yóæáǽ¼¼’““}||Æb©áÑôÏŸ?"OiiiGG‡±±ñgü_ iaa‘œœœžž^^^~öìÙ   ;v¸¹¹%''oܸ3ðÊÊʧOŸvsskjjZ·nl…�W®\INN....//lÊß ‡Ã‘0™<íÐP¡¤Æ?z(»Z~ÄöKâââÉÉÉ©©©åååpÖö]ˆˆˆºÐ7nܘœœœ——W^^¾téÒ­[·>zôèèÑ£ÉÉÉS§NÅ:4ÊÊÊp ÝÔÔdbb£ÄÄİ?Åäƒÿ&‡Åbutt@C&“EEE?îÏÌÍÍvŸ_‚ÎÎÎÎÎκ…Á`ÐétYYÙÓìk׮Ŧ¸G-8NFFÆÎÎ.44tÐ åååmmmVVVBBŸº» †††¡¡á»F²²²™™™æææ{÷îe2™}}}²²²ØHñèÑ£Ož<¹páÂÒ¥K{{{±NIIIYYÙ•+Wš››×ÕÕ}ÐSqø<™™¦–¿­ôªá¦¥êÞÎlþ°Î€°°° R©%%%ÐŽÃádee™L¦¹¹¹‡‡‡`Îøøx Ìš´@²²²þþþæææ!!!½½½,KBBBVV{ ®®®}}}YYYÒÒÒ˜êÂ?e³Ùæææîîî¨^OÇÚÂ… ¯\¹²iÓ&8}Çår·lÙ²{÷nØN8pà—_~áp8—.]Z¼xñÇûÝžœœlmmmnnž››‹"F†ÚÚZuuu%%%>Ÿ¯®®þêÕ«²²²¡oùñÇétºŸŸßÙ³g8°~ýúÝ»wŸ9s†N§¯_¿þÖ­[]]]ß¶+�� �IDATÐY?Ê­Ž¬¬¬­­mXXØ‚ /UVV655ÙÛÛcs0Jnn®6R^^Ž9Ê fff¡¡¡‹-RRRâñxsçÎ={ö,§Óé»wïþûï¿7oÞ¼{÷îãÇ>|xåʕ۷oß¹s'‡Ã¹qãÆÜ¹sÝÜÜ–.]ºxñbÇf³“’’>h”óÿ¬+ëbnñë÷Y¿Þü?öfƒÇ$ŸÙLöûÇ7666ðŠ‹‹��ÕÕÕšššPTUU###…„„ÂÃÃçÏŸK:{öìóçÏ þζmÛètúÑ£Gýüü8ÎÉ“'—-[æááÁ`0V¯^Çã)Ê‘#GÜÜÜbbb¾ûî; Çb±***H$Rmm­††üS4ÊàH$ƒÁèîî¦ÑhaaažžžH(Ÿiii>ŸßÝÝ=žÃáÀ¹\<ïååýâÅ [[Û‘|†ÈÈȆ††… Âæo˜´··¿yófîܹx<žÏçWWW×ÕÕ988L­#‘HmQÙ¿ßæsy8<^ÿ÷Éÿ™;Ì  â3"))ÙÛÛËãñüýý?Ž6¼A ÅÞ½{ÕÔÔ=zÔÛÛËápDDDÆJØ¡œœÜ´iÓbbb`°Smmíı7��‹%ïfe¶¨°ÞÚEÈÞ F è¼ÄPœ:uŠÇã8pàÀ�€ÀÀ@kkë±òð fff EMMmæÌ™íݱX,ÅyÖšKg2™LdoÈä Æþþþ0rz,¢¤¤´jÕª ûîX,:1ª@Ž5@ “ƒ@ ˆñr¬|>ÿCWÉ 0Ðä29ˆ°7ÁÁÁH™Äï¤ÇÇÇКÄ@ÐþI29ˆ÷C£Ñ.\ˆä€@ (|�@ Èä ™@ ÉA Äè…|qÞu¬$bPàÞÕHÇÉd~è±:55µ'B!É'ˆˆˆ¼}ûÉa8¨¨¨ˆŠŠbG8#†C___FF†¶¶6Å0QRRBB@&gÜÂãñbccõõõ‘(Þ£‹BBRRR}æìDFRRrÖ¬Yh›†÷R[[«¬¬ ÓHÈäŒ[Âk6F‡ƒd2™N§#Q|\ωî½deeÙÙÙIKK#Q|-Pø�@ FÓ(§¤¤äéÓ§&&&‚‡É§¤¤$%%¹¸¸|Ü™]l6ûÌ™3‚)JJJÿùÏƱ¬{{{/]º„}USS[½z5� ¼¼<00�`jj:þ|x555õåË—��A ?þ¼  ��àå奥¥…Ôw ÝÝÝW¯^LÑÒÒòòòú,?~éÒ¥ÞÞÞmÛ¶æÒÒÒ'Ožc{^¼~ý:!!~vuuµ²²�„††bSŒ+V¬ÐÔÔDÊ3¨TjeeåÔÔÔäååßuõöíÛ---?üði0Œ;wž>}ZXXxË–-‚™ïܹ#˜"øZdzÉ)..öóó[µj• ÉILL<qℨ¨èG›???11±mÛ¶�ÚÚÚþúë/çëë;^•µ§§çòåË›7oþL<�PQQñèÑ#¸Xnn.ŸÏ_°`Ajjj||¼� &&�`mmRXXïzðàj&ÒÕÕåç秨¨¸~ýzA9Ο?ßÔÔ´iÓ¦Ñir*++ïÝ»WZZ¼bÅ Ø6½yóæøñã<ÏÉÉ)66655õÀ~~~†††S¦LyðàAYYÙ¡C‡444þ Çääǽ¯ìôª¢½ aÒ¤wÝ{óæÍ'N´¶¶¶¶¶:tHRRòôéÓT*uÛ¶m~~~RRRýLNCCƒŸŸßäÉ“aß´°°088˜Ïç/Z´hœ›Hvvö³gÏÜÝÝ¡½‰‹‹Ã.…„„¤§§ÃÏ>>>·oß®¬¬üá‡ÔÔÔΟ?ßÖÖ¶sçNIIÉ~¿)&&¶k×.�@QQÑÕ«WïÝ»çëë[QQñ÷ßÃ æææË–-{óæMhh¨ƒƒƒ››[lllBBÂüùómmmƒƒƒ333½¼¼LLLîÞ½[ZZ ïÚ¸q#œ$mHIIÁòbTUUåææÞ¿�pïÞ½¨¨¨ ¤§§³Ùì½{÷�:”••emmîâââéé �X¾|¹££#29ïBAAAPÎÅÅÅ÷î݃Ÿ§M›¶xñâäääÈÈHggçðððW¯^¹»»×ÔÔdgg¯X±"++«¤¤Ä××wòäÉ�€‹/¶´´lß¾}´Wf!! ÁÄŒŒŒ—/_îÞ½{×®]===‹-ÊÊÊ*((صk×Ò¥Kß¼yóøñc___dr† ‰Ê”Îmô’Þ,'eeåw…\þû￞žžÊÊÊgϞݾ}ûÀöpP455¡2?yò$(((""bÑ¢E©©©/^¼€ÜÜÜž?ž––¶lÙ2ssóþç?ÿÑÖÖ¾~ýz]]ÝæÍ›ýýý»»»á]‡þŒ½±áóYXX ?§§§¿~ý³7'NœhhhPQQ‰‹‹ûõ×_KJJ‚‚‚ZZZ��wîÜ èëëfOíðáÃ***­­­üñGPPP^^^@@@rr2�àÕ«WÙÙÙ�€èè耀€ÒÒÒ;wîœ<y’F£©¨¨<yòäСCð¯GûöíÛ·oß… PÕJJJ~ýõ׸¸8•†††'N„„„dee@NJJ ÈÏÏŠŠ 8räHKKË‹/>\SSsáÂ"‘;¤£¹¤[¶lÓ]àqÌ•+Wêêê|||¶lÙ"%%åçç×ÛÛûq?•ššzôèÑììl•üüücÇŽ%''ÇÇÇ�ž?PSS�xôèQ@@@GGÇ©S§Îœ9#!!¡¢¢råÊ•ýû÷öQ,jPPœœ\XX˜`ríÚµŽŽŽzzz©©©ÁÁÁëÖ­Û¸qc]]ÝÙ³gååå[ZZ8 %%5¨¯içÎТ¦¦¶eË–ÆÆÆçÏŸ»¹¹mذáÉ“'÷ïß߸qã’%Kâââã¾ß¼yããã3uêÔC‡ÕÔÔÔÕÕmܸQMM­µµuº>¤¤¤~ýõWø™N§Ÿ?þ¿ÿý/ªŠ_‚ÆÆF¨WºººúúúáááK–,Ù°aÿÿþK¡P’““ÕÕÕßu¯ªªª§§gbbâ³gÏ~úé' …ÒÑѱråÊÌÌLèê[Ìœ9sÑ¢EQQQíííiii0qÅŠ………wîÜIJJ*,,D 3 öƒïÞ½{øðááÜXZZ •¹²²ÒÊÊjÅŠÉÉÉ[¶lÙ°aCGGÇÉ“'sss—/_žŸŸïÞ=ìÞ‹/VWWïØ±CYYùþýû½½½§Når¹£Ý䨨Øhkk§¦¦jjjÊÈÈ,X°�[[Ûªªª€€��@VVÌ<þ|<¿gÏžšššƒþøãƒ®· ‰­­­7oÞ433[¼xqJJÊÀlS¦L±±±n4,1%%¥¤¤dçÎZZZëׯŸ7oÞ… öíÛ§¨¨øóÏ?Â8HQQÑï¿ÿóRþüóÏÈä|!DDD,,,ÀG-ú›5kÖ .&ooïÇòÎ@Œ÷îÝ +fMMM^^�ÀÁÁáÈ‘#p<55)̈qâÄ ™¶¶¶áß"!!aaa‘››çíííààPRR20›¾¾þ;w£ÂÂÂZ[[—,Y"--ýË/¿ôôô8p€Ëå’H¤³gÏŽv“£­­mccsáÂqqq2™ MÎÇO:åàà`oo_PP�Gs�€œœ8rÌÈÈ`0âââSXXø›o¾éííÅáp'Nœ˜9sæGÃÉÉ � ®®¾{÷îÈÈÈ–––³gϪ¨¨Œ*mëêê:yòä±cÇPÅûÒHKKóÍ7ð3Œ¿˜ÈÃþrtt4Lœ1cÆŒ3��Ïž=ƒaˆ/Ç™3gÊÊÊöíÛg÷îÝ»k×®á,¥RVVþæ›oêëë�‘‘‘ÿüóÏÇ=Ã’%K��’’’7n¤Ñh,«_lçÈðaÓGNNN¶¶¶JJJp’••U^^nmmíííuÿüóÏk×®ýôÓO·nÝÊÎÎÞ¼ysggç»~V\\|Þ¼yC´sæÌñòòzöì‘H¼uëVkkk\\œ¯¯¯�àüùó¾¾¾p~L[[;22röFétzhh(ª~£ …1œœ»wïîêêsŒŒŒôõõ}òä‰`â­[·|}}1?âKßÖÖ6{ölïÿ!""<ü #ÔÔÔìì쪫«‡xk¾¾¾ööö—/_ž1cÆ­[·ÂŠ‹‹<ãŒöîÝëëëëäätíÚ52™L¡PFû(�0yòd33³êêj##£˜øí·ß–••]»v-,,ÌÑѱ¶¶öÏ?ÿ,//ooowvv¶°°8~üxdd$ƒÁÎ_î۷ﯿþZ½zucc£ƒƒŒvÕÑÑ166~üø1÷ððxýúueeåŽ; ‘³·· ܱc‡œœ\GGÇñãÇÕÔÔF›ÚÉÈÈìß¿Æ;ÊÉÉAO®©©©‹‹ LÔÖÖ†ž· ÂDKKË9sæ��~üñLJ¶cÁ‚S¦LA5y8˜™™íرãþýû«W¯®««suuýöÛoEDDòòò½¼¼ôõõËÊÊÞuûÑ£G7mÚ´k×. …2L5=èéé ?~œB¡}ûí·®®®ÝÝÝAAA?ÿü³ŠŠJvvö¾}û'�£¨ÃÏŸ?/+++))Y¹rå¼yó��>ܺuëÂ… ÿþûïööv'''8>oÞ¼uëÖ­[·ŽD"q8œÛ·o•‡Ç‘H$ƒÑÝÝM£Ñ‡/---999ªªªÆÆÆµµµt:]__¿¢¢¢¼¼\___SS³°°îekffÖØØØÚÚ o´±±‘””LIIéëë›9s&™LÆ~“ËåÆÆÆ’ÉdèIëëëKII‘’’š>}zGGGFF̦¢¢bbb?WUU•––êêêjii×ÔÔa¦%++ óÚÚÚJHHŒý¸rå ´t:=)) omll`†ÖÖV€% +++a;% óóó¡’““g ÛðæS¶õ„–Œ4Á$ �PWW‡ÖJXOOÅbÁ^TWWWCCƒ¹¹¹¢¢bfff{{ûôéÓ¥¤¤^½zÕÛÛëàà––Æd2gÍšE FÜ:::Þ¼yãéé ýذ¶¬8ð³Á¤I“u �`ee%++;먨(¸áÍGï±VWW÷êf b\Õ W·y«y;TàŒŒŒŽŽØ”ÄÄD¬ûâêêC$ïêîî~󿬬,\½ÛÜÜœ››«¦¦fddTSSS\\Œõ* ¿{­uxàŸÎž=‡Ã€Ì%%%{{{y<ž¿¿ÿñãLJerŸËä ¾´É™€ô39ˆ/mrŠ3sgNôª¸†F[¡erжž1\$DÞ1(äÀCûy 291\Èd2™LFg “3ªÁáp£gniÔòU¶ß7´··3ôn"ÓÓÓƒ„€LÎøoIW­Z5ª&œã999´ÕÍp@s-ÈäŒóŽ@s«Ö¿|> გ’š9s&F‹ûñŒ<t:é29㇄€ørQQQ¤fˆ1òž#™@Œ/cí‹3è© ˆ¥··÷km·>Ê!ƒî™‹øP°ãËÈäŒaFfW‰q ŸÏ œ:uêGÊ#CBøD»zõª——Š,E&gœ(4ê@}4‘‘‘pë3$Š!àp8hÛæþýû(rzd@s9@&@ Èä L@ F/à èííÅNs‚ÈÈȆµ´´tww+++£Í+¿ UUUýN´ÕÓÓÃ>s8œÊÊJ‰„õ†ÑÓÓÓÔÔ$))©¤¤ÔÕÕ…­'///##�hnnƶêQUU�ÔÖÖb=iiiÁ}VÊÊÊà>"x<^GGçk‰‚ÍfWUUa_EDDÔÕÕ +˜YNN;š êp¿’" |>_ðàTA]¢Ñhõõõ‚™¥¤¤±¯mmm ÒÒ҂ꤦ¦&** �¨©©Á¦îª@ÐÖÖ�À“ô¾Ö‡Ã Èçó‡ØPvòäÉD"�P^^ÎãñtuuËÊÊÞUq%,!!¡¬¬<0OkkkWW—¢¢âè_’1,“·fÍiiixg{{ûìÙ³:«±±qß¾}ÁÁÁ¿üòËÚµk±cï#†——WYY™¬®‰‰‰ð€Q‡“àéé©¥¥õøñã~:µvíÚ5kÖ>|øìÙ³÷ïßWRRjiiñòòÚ±c“ÉܳgONNŽ””TMMÍáÇW®\ÙÒÒ²zõj‹%,,\ZZúàÁGGÇÒÒR]]]WWWõµ6nhh˜>}º°°°ŽŽF“‘‘¹yó&lÃÃÃøáUUU˜yíÚµ¾¾¾P‡÷îÝ›‘‘!--][[{ðàÁU«V¡Å.L&súôéBBB,‹ÅbB]JOO_²d‰„„<l�àáá±k×.ìÞ‹/ž={öäÉ“ ,عsg~~>T§ß~ûÍËË«¹¹yÕªU<L&—””P(”3f”””Ìœ9ÓÀÀ€Çã544DDDhiiÅÄÄ|ÿý÷ðµJKKߺuk`j$ZL!¡!¶¢Óé,ë]{¢WTT¬X±¢¬¬ìÑ£GÎÎÎD"qÖ¬YT*µ¹¹žÝ)Ø[ÂìÍãÇ<¨©©I¥RŒŒüýý1Æ8sæÌåË—¾ýöÛñãX›?~RRRRRÒO?ýt÷îÝ›7oÂôsçÎeffZXXœ?>..Õϯœ'Oà "‘H...0±½½ÝÇÇÇÂÂBXXxíÚµïº÷åË—III{öìIJJZ³fÍ¥K—(Ê©S§BCC:”””äèè¸k×®ŒŒŒM›6Þ¾};))IUUuÙ²e]]]óæÍc2™ 111===‹/þº¢ÐÑÑIJJú矨Têúõë+**°KIÿÚ›úúúýû÷gggŸ>}:))é»ï¾»ÿ~QQÒ¨~HKK'%%=}úTTTtÅŠØAÈ��GGGLª‚öFû÷ï777$%%ÙÙÙmß¾=''gÆ %%%ÿüóORR’²²ò’%K¨Tª››—ËMJJŠˆˆèîî^ºticc£¶¶vRRÒ•+W²²²vìØñµäÀápzÞAjjêš³~ýz!!! ‹o¿ýó( F£P(‡úæ›o’’’ZZZþý÷ß¶¶¶¬ÿÑoà^]]••ÇëeeeYYY}}}EEE £  �ÞÂårsrr²²²rrr`q²²²Þ¾}Ë`0²²²°×J¥R±©©©ÑQÎÔÔÔ455mß¾Ý××÷‡~(--íìì„>ÄW*“’’Rlllaaáš5kÞ¾} G?ýðððððð€íoCCäI“”””Û”±ˆ‰‰‰¿¿¿»»ûÁƒïÝ»÷®l—/_~úôéÙ³gçÎ �8räÒœ!PUU½}û¶Í¦M›bbb†ãÎ;wîÜ �(--íêê244œP~ø‚‚‚¾¾¾7n˜˜˜XXXdee)(( }KaaáÖ­[œœüüü��ÎÎÎÎÎέ­­çΣP(šššõõõ³fÍÚ»w/v‹ŸŸßÇïÞ½»páÂÝ»wÇÇÇGEEíܹsóæÍOŸ>íèèÈÌ̼ÿþÙ³gY,Vvvvhh¨––Ö¬Y³”••O:õÇ0™Ì[·n©««ß½{÷Ô©Súúúmmm:::'NœÐÒÒÑQNsssbbbbbbee¥††G_¿~=88ËsìØ±ÔÔTT-¿ oÞ¼/ˆÇã͘1�ÐÓÓ³jÕ*,CYYÙöíÛ‡ø…ºººãǧ¤¤>|Z ñGcccâÿøŒ}· N{{;&UÁYŸmݺµ¯¯ïòå˦¦¦GD;wîìÃ}óÍ7·<<""âÂ… áááÿùÏþùçŸG½÷®üñèÑ£ááá222žžž>|ñâ‹ÅZ¾|9ÌÐÕÕzùòå’’’;väää8p@OOïÌ™3§OŸ¦Óé/^¼éQNaaá¹sçjkkKJJ¶oßîããƒ]*..މ‰é7ÄCŒ07nÜ “É '((Kg0111µµµï°ž<yòÕ«W‡Z¶lÙx•R^^Þ¹sçàgooolñ)TTT`R3gŽ®®î»zú{öìéíí=wîÜÔ©S'f¿°¹¹™N§¶SRRºtéÒÛ·oáWWW×ÖÖV86ýã?¦L™2Ò&ÇÙÙùÒ¥K‘‘‘‡®¨¨(++ãñxUUUS¦L©®®¾q㆘˜˜²²rff¦µµ5Úkä¹v횊ŠÊ÷ßáææC&“­¬¬nܸ�°··omm �(((XYY Ú›S§N¥¤¤ìß¿ëøŒKæÌ™ãïï´åóbmmýï¿ÿb_««« µµµõõõ±Äüüüýû÷÷õõ>}ZP÷&ˆ¥éìì´³³‹ŠŠ�XXXÄÇÇÇÄÄp8œÑùÀ&&& %##c÷îÝžžžNNNÇŽÔ'ÿMVcKKK<hhhÈf³Ÿ?~âĉü^ýî»ïN:ekkëêêŠêáWáæÍ›ÊÊÊkÖ¬©¬¬\¿~½’’Òýû÷ᥜœgggèj›3gÎDZ»"##ïܹ³mÛ6OOÏq#ŠŽŽŽ””EEÅéÓ§‘ÍØØXKK+''§¶¶VCC#--­±±ÑÎÎî½®ö‰I___ll¬¤¤äÌ™3ß•'<<|ïÞ½;wî<xð –xýúõÄÄÄ¿þúËÚÚz¢ íØ±cÐdii‰i݆ †¾KFFÆÁÁ¡µµ555ÕÖÖ¶¡¡!===;;{8ÿ˜šš:œ…wÑÖÖ–’’¢¬¬üÇìÛ·/!!᯿þú,}5´­ç„CAAaÊ”)MMM %--MSSÓÊÊŠÅb�ŠŠŠ( Ì6uêTKK˸¸¸7oÞàñø††EEEggç’’’¨¨¨¢¢¢¾¾¾… ’Édÿý700Ãá‰Ä¯±ÖÝÝM¡PÊÊÊnݺµiÓ¦­[· º€°2A|òäI8¼|ù²ˆˆˆ®®.29ý`2™ ¥µµÕÏÏoݺu¿üò v©¡¡“ª¶¶¶®®®™™T§¢¢"sss¼¼<�Àëׯ±c'''—ÒÒÒÈÈÈ·oßÒh´E‹‘H$û÷ïS(ƒA&“.\(&&6wîÜüü| …R^^®  àèè8î®­­íïï¿k׮ݻwoݺ5==ýŋӧO·´´,++£P(0ÈÀÀ ¹¹Þ2}úô”””””>Ÿÿ‰&çÆT*õ§Ÿ~²°°hooÇŒå'B d2™l6»´´ÔÈÈh`&:Îf³íììàn¾===BBB°9sæäÉ“±UPP˜5kª®°º~¹¿hjjÒÖÖž7oü¯ÚÚZ“yóæ544L:uöìÙ0›Íîîîž7oÞÆ«ªªªªªX,–——ך5kz{{ñx¼ˆˆHÕÿÐÐÐpww¯¬¬¬ªªRPPØ¿ÿ”)S˜L&LÔÑÑ9}ú´””Ôüùó***jkk­­­O:õKW^^ÞÓÓ£¯¯?œå™§½½]SS³ªªŠJ¥Î›7³74ËåJJJbeTTT„kfMMM%$$`¡äåå÷íÛ÷Y|#'“É<ö¾|>¿¾¾ÞÀÀ ªªª¥¥ÅÉÉ ³7 ƒF£)((`Rwww×ÐЀòÙ¸qã¬Y³:;;¥¥¥Y,–ÓÂÂbÉ’% æÔÕÕõ÷÷—X°`A}}}EEE]]ÝôéÓÿüóOQQQGGÇêêꪪªîîîùóçoÛ¶í30??ŸËåš››¿kIÍÿi1 „~+¯M/‘HØúµ¶¶ªªªº¹¹IKKc9õôôLMMMMMay§N:gΜ~7ÊÉÉYZZbµÕÓÓóСCÚÚÚPbD"qݺuóçÏïêêwrrrww'“É•••k×®UPPPQQqssc2™šššsçÎkhhÐ××_°`@¨­­577Ÿ={vss³¥¥¥‹‹ ›Íîêêš6mš»»»¹¹9ü_6›íííýÍ7ß|œlÉd2‹Åâóù¯^½JLLÄ‘H$ƒÑÝÝM£ÑÂÂÂÆ“_e” --/øàá .Dý˜w5‚èð‚O^ðí·ß¾÷¼"‘Èb±JJJ½Z]]­®®>hÇ}Â"))ÙÛÛËãñüýý?Žkc‰ØØØ¨žžžØ®-Ä'òøñãÎÎNÁ·~ýz$Ç£Ñh]]]ƒ^•’’B•qhÉK´··Œu~×øûÍ #GíÈyÐ�� �IDATár¹bbb666HÈ䌼¼¼¼¼¼_Ž-[¶ ! ¾èð@ “ƒ@ ˆñr¬\.7-- ÉáãÀNXA AOOOzz:’ÃÇ1jw@&ñÁðx¼„„ló"âKXåäää¡÷ÓD É™Ðétqqq;;;$ŠO8;DŸ†Ãá((( uKŸÈ{×"ɰÙì¯uD&b"Àçó Ò1ÄØ°ëH@&@ Èä ñáüŸ¹'..Ž„‚@ ˆÏB¿ “þÉ¡ÓéOŸ>E2B ÄçÂÑÑ‘L&br‚††@ !“É¢¢¢q£˜˜‰D|”ƒÇãeddp!ˆˆˆH[[Û‡.iwqqQQQçå br -cF �@JJ z¿ †´´ôÀs333ÕÕÕŽoˆDb¿ÄALŸÏ§ÑhHÐÁ> ÷ó„ ‹‹‹‹‹‹ôIHHôõõõKDAÒøHðx¼µµuCCC}}ýpò£ oñ1 ‰DaaáiÓ¦ Ëš|˜ÉÑÖÖ¶´´Ä¾æçç f°³³«®®nhhôvww÷/^°Ùl·|ùr��“É W¥¥¥gÏž �hiiyùò%LÔÔÔ´¶¶�”––æääÀD333}}}�@FFFee姈 ûSHCCCJJÊ …�äää”–– ¦888”––677�fÏž--- � Ã<“Ë—/Çáp‹>—˜;w.� ½½=..&ª««ÛÚÚ�*++322†ÿü®®®‚ãÙ&“‰}%‘HsæÌyþüù ÷ª©©©««¿~ý� ££caa�(,,Äf---µµµ�©©©uuu0ÑÅÅENN�ÑÓÓ—,YB$ù|~``à'*±………ŽŽö599¹±±~Æ$ŒñôéSÁmçEDDœ_¼x�‘‘quu�477'&& “'Ož6m� ¤¤$77&š››ëéé�ÒÒÒª««a¢£££’’� &&¦³³ó …éRqqq^^Ôa6pÒÔÉÉ)??¿½½KY¸pattt¿×êîî?S©ÔÈÈHøYQQqæÌ™ðsMMÍ›7oF ÑQTTÔ××OJJš€ ®–––´´tVVÖè|¼™3g´µµ êRLL ƒÁø\Ãá ‹Å"“ÉIIIÚÚÚªªªŸÓä„ÚÚÚÌÌLøÕØØØÀÀ ¸¸~µµµmllÔÕÕåñxMMMoÇBå<==a,,,¼xñâIII›àà`¬æ¼|ùrÒ¤Iªªª0QWW×ÌÌ,77×ÔÔ”ËåÂDKKK‡5'2¿ª¨¨ØÛÛC«#$$TSS#¨O\.·ßíD"î>;{ö윜œ®®.�À¼yó¢¢¢ ÆòåËŸ?ÎãñˆD¢‡‡ÇÓ§OÅÄÄáÃËÉɹ¸¸ÄÅÅ©ªªNž<&jiiYZZb~/$)!!þ/T©ÐÐP6› Ÿ¶V‹-Ôêàñx8¹§­­-++ ÀÐÐÐÈȨ  À¢··&ÚØØðùüúúzggçÂÂBØ º¹¹½|ù²··wÉ’%QQQXOâ­‘HÌËË«¨¨€_íííy<4ê$)>>¾»»ËÜï˜Ãÿ¥¥¥­­­áÃ+))988$%%ijj*++ÃD===SSÓ¼¼<3336› ­¬¬ø|~MM££ceeejj*�`Ö¬Y©©©‚ú¡Lž<Y^^þ…‰‰I~~¾µµ5ŸÏ///l#ÔÕÕ ÛˆÄÄÄùóç÷{­ð×��’’’sæÌ‰ŒŒTPP066ÆÒ'Mšdmm=§4áñxÁØ @8=>z ‘HýöÆþ¼oJXX˜L&cÝk[[ÛálÅýÁŽ5Uºàg‡ÇãßûÇAAA°ù&p8†Ãáüe.— ‡Ãáp8˜·Ë…*Îåra"‡ûôýÆù|>V¢ÚÚZ<ogg÷êÕ«…‚ØØX>ŸÏçóa£�܉D6› £¡jâp8!!!¬˜°ìPbýŠ9|Øl6öý*€‡Ãyo­¨¬¬¬ªªÂ¢¡Hác`r†%Âd‚='‘Häp8Ðä|–ˆ½_�@bb¢³³3ÇkmmíWØ!èîîŽŽŽ†%âñx˜œ1užjLÄTWHH{Ðoùô‡R]]]SSFðý„~Ú‹iŽ æp8ý\P¯à玎Žèèè~5�PQQñ‰€eÒ¤IjjjÍÍÍrrriiiS¦L!‰ØPrÚ´ip(™’’‚õ]]]ÃÃÃíìì±Aó×ÂÛÛ›@ p8œÇÐFFFPOØlvaa¡µµu{{;ÖmrvvVQQ�DFFbã×%K–ˆŠŠR(”¥K—>~ü6#†——W`` §§ç£GÈdòüùó17Œ¬¬,tÃ466ÆÇÇÝ_§Óé, ÓÞ¸¸8CCCXØÏfrúµò˜¤ìììjjjjkk]\\¸\.왾«M�Éä <yòdôô  ÙÀ 8°°ïÒ Ø àp¸E‹EFFÒéô{fA=_¾|ù£Gø|~TT”»»û³gφ.5‡322ÂápÐó3J€¬!îסÁÌä %�(++ ]sFF©p8œ¡¡!‘HÌÎΆéééé²²²:::p ãääTTT$ØáX¼xqLL F „m—Ëåp8ÁÁÁ>>>}}}!!!|> ¡¥¥%??ßÇǧ®®.)) K1p8œ¶¶6ŸÏïèèX½zuAA›Í†CIKKK*•úàÁ�ÀŒ3x<^mm­««k~~~KKËܹseee¿º¦y{{Š——×Ygff–““#""âãã“––¦¤¤Äçó+++gΜYRR’��˜;wîëׯ;;;—,YM£Ñ–/_þELjïꔄ+V<~üxõêÕt:=<<|É’%ÁÁÁÐ=�ß”ŠŠŠ““|òw qú5tÎÎΟ”£«« ýûx<>77·°°P°íÆ,ïý2™¼pá   Ñ<pÖÓÓœWÈÊʼˆƒ¾Å¹sçÆÇÇŒ ü¢Ì;]=~üëçÂn/Ö»¯Ý200Â&ÌF'óæÍ´ú å]Gãp8EEE##£ØØØ¯þØ8N___XXXÐO ­Aâñø˜>°N1™Ì{÷Šz{{S©Ôˆˆ؇kjjºwºº··wuuõëׯGØêTUU¥¦¦êëëgee™˜˜ÀôÌÌL<ic?{¾hÑ¢ÑðŽàHåCÝ üüüüü|è/--•——‡é/_¾$ýÊŽÃáàë¦P(«V­úr…š5k– R —>|§™ƒ‚‚DEE¡‚uuuEFF§Ý€CÁ)F˜cbbçA?É)--…bcccøz ƒˆÏç[YYYYYaí/+ô ô«KcÂÞ��JJJž'Ký*3‘HtqqINNyçÀ‹/à\ÎâÅ‹‰D"T‰Äãñ–-[óôööBoŒ gOÐÞèéé‘Éd¬>j 8­B"‘°Ñ=¦úpnc4Ø<¯««+&&6pŠ.--ÍÎÎŽËåjhhTTT466bÍ4|_ÐÅ›f‰;•°¼4íÁƒRRRsçÎ ƒ•‘ÃáÔÕÕ=xð@[[{úôép:êK´Îµh‚¥¥¥––¬>#ìñ>ðC?uèTxWGgVHhÆŒ° ù‰Ÿ˜˜˜––ìëÒ¥Kßûfà`Ç:%‡8$iÐ0WWW6› ‡õŸÇä`¼}ûvêÔ©VVV­­­‚úíææÆf³[[[çÌ™“˜˜H¥Rï]¾|ù½{÷F¡ÎA÷úÐuiÚ´i---˜£ô›7o>e’ùÓ ñòòzúô)›Í^¶l™ „a˜ÜóçÏåää,,,°p ˆ¶¶¶””ÔÈ8}($‰Ãá Ñ[‡1 ÷ïßL”––¶²²‚¡k_É“'ËÈÈÀÈÀ°Ùl8=Ù¯Œ+ΪU«<x@ <<<=zÔïwÌÌÌà¼Î—FRRÒÁÁ!44t˜ù§NÚÝÝ ŸÙÁÁa Ãc”œ� ]—°I}W]]Ýw¹›âàà€9ÖæÏŸ?°íUÕ Vø¦TUUa`ðÀ‡Ãá˜Lf¿!Fbb¢™™6Îûl&g˜0 aaaø"­¢˜˜üÀãñèt:ŸÏg±X0ëªÃz1K�»ê0žúþéPìaàòXãK$±K°ïÃf³™L&@€é cÆ2Óh4¸‰ƒ¨¨(œ1†q<ÉdÂlX7:è±bÑÃútàä?ü/!!!Li„„„°‡‡Åd±X˜œ¹\.ö1™0™L8x¥Óé"""D"†ÿ}3ƒ=Œ¥¥¥` §ˆˆˆà‡>Ló :—_+‡Ãa2™ÐtÁDåܯ˜ðÇûóÓÝS‚ŠÅ‹]JOOŸ1cFmmí»–ôƒÏçÓétì×Èd2Ô"Á7û¥IP‰Dâ{ƒnY,ö: S„@ `B¶³³ g¦ÀÚÊãñÂÌ™3ßµ´ _m}W³+Ø�boãñx&,,ŒÃáfÍšõq~¼/÷f±va;@ vÞ5ÄÁ¼yt:ý]µæÃL‹Å1“É„•‡Á`ôÐh4ØHÅÄĸººB•‚‹r`K­†¡Óé‘‘‘T*5-- &¶¶¶Â0庺:ËËËóóó�ÆÆÆ01;;»¶¶öE,$$„=LSSÖe±XŠŠŠ‚«vòóóËË˳²²,--azjj*·Òh4¸~Á`0ž={¶xñb8 ‡]B–œœ ïíèè€ëE±bVUU}Ðl F|µ½½½Ð ôóïa›uttäååÁÿjll„Æ•Íf+((`%-,,„ËVÌÍÍabZZ\“””äèè'{ccca‹º`Á¸.gˆ …á÷Qôôô`t“ „aamll3?þœËå>þN0Œˆˆ¬]ë÷Zkkk19—••ÁXä·oßš˜˜ÀÄÌÌL¸üèÕ«Wöööp¡RBBB¿1ú‡Âf³åää°‡)...**Âê|lÌŽb§ß›…/-<<|Á‚0±§§:ÛÚÚ °\ÌðÙéééÁjk[[[rr2,&l†°Všs�� F‡ùÓÓÓÕÔÔ`Eppp°²²Šwttüê­mHH¬­P£Þ•­©© Ó¢êêjè‹f±Xð­1™Lhé±&155ÕÎÎnêÔ©�€—/_N:µ¯¯/22rΜ9"""aaažžž_Έö[×Ñ××ÛØPàp8¨T<Öåîî l}dYY™™™™ Gç½CÈëׯ§N*%%5È Ú«îînâââB§Ó ö;X,ÖHb}v–ŸÇã}õ¸Lbb"&&‡ž�€E‹%$$ŒªÊˆÃá$%%û%r8œÏ7ƒ] è/á éBNNNGGGDD¤®®ŽÃáL›6­««ë½Ã;èšc0âââp'iÿãÇ>Êèr­««åáLC3cÆŒ~3Z½½½Ã÷É"ˆÏˆ‰‰ISSAbíïèD" lÛÚÚÞ5'÷AL›6­°°¶ÚØ:î1Ç+))¦!pww8K7¸ÉéîîþÜàX!,, Õsb”ðúõk›)S¦��’’’FxiÁ{a2™_® Œ‹‹svv†±‘‘‘£yˆÓ6›­©©©©©9üÁܰL@Œ€Õ™°eÿºË“¿"ƒŸ—3üˆ{@Œcî-ù™M—Ë¥ÑhC,{vUH¨ººZUUõ7Ë=„ææf ‰!Œc<W5IHHŒÁÀžÞÞÞѰ›Ëg,Tcc£²²òxjjkkGU°ò'6­­­¢¢¢ŸeѶ„à š�€¤¤¤`pðXGJJêâÅ‹³gÏ7&G\\üéÓ§fffŠŠŠã£DÂÂÂéééx<ÞÈÈh|”ˆH$666¾}ûÖÉÉiÜØððáÃñÔ8HJJÞ¼yÓÙÙyÜôÞÄÄþ?ö¾<.Æõýÿi¦iÓ6-Z¥¤E§dO¡…I¢lm…Ä9Öl"$ÛAHv*¢½(íQZU´Ð®TÚ—©iZgæ÷Çõúܯç;ÕÈzè×û¯ÜóÌóÌýÜËuÝ×}Ýï÷˜çÏŸ+(( T†þºnÌ`0€Èwp.G—£Å(F1ŠŸ´¬dÿq]]]II þ Vii)1ûã?þøã(ÌÊÊ6\¡LkxxøÂ… Á•`0àÛ"±©ÖÖV b‘@Ž!°b¦¬¬ Ç©0 ËÍÍi¸™3gqB||ü”)S†Êhkk{ýú5Þk«ªªåEEED‡ ²Z³gÏ–““Ã3kÖ,tú'$$…­^½ðžž¤e‚a™L644„7 ztrrr Ò†aXQQ¤!jhh@J{DFFêêêâ׿@YÁÅÅ…h£( “700ô>………ýýýˆæ 5«¶¶ö¸qãÐ.�###tp!88X!V­Z%4 ÎÓ /\¸ÿ8iÏr¨“=&Ož Òp€°°08x¸råJ–DÌŽŽ º›?>þ£>´´´ f-((�=ºiÓ¦Mœ8ð´´´?¢ë,X�ŒŒ„S#Ë—/êßAû0”––R©TÔ‡1 ËÉÉÅ?---””˜˜G_.\ˆ×£ 655e þP©Ôääd###øo}}=$ý7N[[ ‹‹‹á¸¢ºº:~™žž.--šuP úP„–––7oÞ 7Œ@EEESSsàÀÌ›7(îãââ€ÏñâÅ(¦ÔßßO ~Ü1ÉA�gÃ9!Bsss\\†aRRRh>,//FUUÕÉ“'³iÖÿ±±±Ó§OGBŽhà@¤2YÐÔÔ”ŸŸ?Zèïir£¢¢ KKKÑ+.)) «¨¨€×Íd2ÕÕÕ333Ÿ?㤮®ÎÜÜ| Õ Ùµk×ëׯÁä<|ø ‰D¢Óéfff@ÁüBBB ÃÀÀ ²²288f½’’&“9uêÔ·oß>{ö z555Ë—/GV'66öÀ^^^Ã19T*5$$¤¦¦&::™œêêêàà`è1EEEL&D$Ñ ¢ µµµæææhÄ>þÜÉÉéñãÇ`r“““á˜N·´´¤R©;wîD ,''ghhX__æSTT”Édjkk………ÁįšÕ‰ŒŒlnnvuuŽŽF&çÑ£GHeŽN§¯X±¢££ãÉ“' ^" À`0@1÷ïߟ>}ZUULÎëׯ###Yš5666>>&_ …biiÉÏÏœœL§Ó988ètº……Eww·ŸŸ°&‰š«ªªþý÷ßÎÎÎašœ„„„ššš‹/^¿~™œààत$Hréííµ±±Á7«ŸŸª)NÓöæüùó\\\`ròóóŸ>} ‚íUUU¦¦¦JJJ·nÝjllDÎÄÌ™3EEEŸ>}úâÅ ¨4ÍÚÚšD"ùúúwôᡪP^^ž’’òòå˱cÇ"““ ´‰Ÿ>}277—““‹‹‹ƒ£*mmm‚‚‚AAA4mß¾}‹/ÆÏþ7oÞ|òä ¼Û†††€€�|_ÒÑÑ).. } ÓTSSËÈÈ(..~ðàƒƒÃP&êäädddÄËË ï9<<|Íš5Ðôááá•••ÉÉÉÈädee>}zΜ9ð_...¼É)++CÚ¬/^¼8w”TtttBB€ooo·´´3fÌ“'ORRRèt:À?~œ’’„7ýýýà)"ãêïïÞ‰°°0ƒÁÐÓÓ+// ·ZVVÆd2555YšÕÌÌì?´:±±±uuuçÏŸ¿ÿ>29ûöíÓ××·‰D" 49ÍÍÍ×®]{ýúõÏ699990 RRRêëë=<<0 swwŽŽVWW TQQùçŸ0 ³µµURRb19¯_¿Æ3>åææÂM,X`ffV[[ûðáCðѯ]»f``]XXxýúu Ã<==CCC§NúôéSøúŽ;233ÁäDGG'''C÷zzzrrrZZZð…¹¹¹999wïÞÅ0ìîÝ»x“¤  àììŒaئM›aÄFDD¤¤¤àéÅ>œššJ&“™L¦””ð“ ÃÏF())‰Í€€�mmm`X+]]]ãââØ˜œÂÂÂêêj–“À»víÖÖVmmí+V444ܽ{ìPJJÊÙ³gYLÎû÷ïŸ>}úéÓ'UUUd},X ££ƒa؆ &Nœ(++ëááqðàAXiiiòóó<x0++KPP‘-,,:::.\¸�D^^Þ®]»`Z¬®® ª¨¨f3•••½ÿž%»ÿÈ‘#qqq°%!!79ÍÍÍ7oÞcžž~òäI09!!!?~„Õ txÏNNN)))À²cgg·téRüãÜÜÜîß¿_TTT\¹r%‰DÚ»w/8uuu‹-bcrš››srrª««ño555ºººàÌmÞ¼YAAANNîÚµkÿý7Î;×ÀÀ@PP0??ŸB¡°œ”ìêêòññÁë‡R©T"‘Õ ~ðàŽŽNRRRKK ž<y266VMM­ªªj`ÏgAAAA[[>U©»»ûСC`�º»»srr@4™3g²ôp„U«VÁ 811QLL ¦ˆK—.¹¸¸�S”››°{8p //¸ ”””~šÉÙ·o_II 77wgg§††ÞäTUUàwttô­[·ôôô222*++¡¾ñññµµµššš!!!222‡Æ0lË–-òòòÿ¡É)---))x2ÆÝÝEÐo\ýüüŠ‹‹ÿƒÀš¼¼üùóç¼¼¼Pá¤I“jjjÀ`$TŸ…»»»¿¿?>¬tæÌ˜ôýýýa¾ “Éúúúpçîîn RTT”••…ÂŽŽw·nÝrtt¨50DEEÏŸ?ŸŸŸÿ÷ßãk=aÂôDä²±ÇÕ«W]\\>+ÿÞÙÙ wE¨oÄ®]»0 ƒÐ‚½½=´ƒÁX·nÝpîóêÕ«¶¶¶%K– N#‘‹‹‹›0a‚¼¼<†aK—.MOO‡@Í¢E‹ °¶~ýzˆnÙÙÙ±yÊû÷ï333×®]ûüùóaVnÎ;‚¿¿?¸ü›6mÎ}Þ¾}ûþýû5kÖdee±¿2::<-SSÓÏ ¹3gΜ9sæÍ›7ñŠéȪ%&&ÊÉÉÕ 8räx$,ÁÃ+W®„††Z[[CÉ„ ¶nÝ «™>°DñX±bÅŠ+¶lÙÂæ7ƒ‰×çââZ¿~=ü-!!qþüùììl˜[Š‹‹¡‡khh 5v¼½½ÍÌÌð!¾€€€¦¦¦mÛ¶ JÉõ‹£   ))iêÔ©l^øèH˜áîÝ»¼¼¼û@mmm`` ››ÛÉ“'ÿ›½ðññqrrBP‹——w8ü¯>411ÈVÔ××wýúõÞÞÞýû÷ÃOXXîL"‘`òòòrssC!›ôÙgÏžMž<™}`z8àáááååEOdóæÍËÍͽ|ù2Œ.3œ={6{íU¨‹­­-ܹ¡¡ÁÏÏÏÂÂBFFfêÔ©pü¼<Xíjjj¶´´@aff&ËFÈp )) âààÎ;)((hii™7oËÌkóŒŒ sss˜#DEEkkk!`H&“aÒ—””¬®®†ÔlÞCUUUnnî’%K¾½×Ž;I;³<QPPÐÄÄÞÚ•ùðáCIIÉ¢E‹>Ëyldd”——oïÑ£GVVVRRRVVVáááPYt‡­[·ÂS¾…,!!!55ÕÔÔTCCcøß‰¶ 6 ü¨¢¢"00püøñàÓhhh444 ¾ô-Ó"ûƒJJJºººðêZ[[™Læ@˜˜˜˜ &àeýýýúûûïܹcgg' °yóæ[·nAö×·7Ïž=ëììlkkc2™³gÏž;wî›7oà…T+øÏagg×ÖÖ,;×®]Û¶mú¨µµ5::úG/+¿Ìädee555ÁÅÝÝ=)) OŸ<>>>?~tttD‘D�ƒÁ¸téǾ}û ¤¡¡!$$X355æfX‹‰‰Ôu ÏÏÏ·´´dã*bvá˜ùøøð/š%NUPP€kºººøù^†a0í­_¿þ³ùˆ|||ÇŽƒ¿ß½{çèèhaa¡  `eeZ/]]]`r´´´˜L&ìU~ÿ¼««+>°Æ~PPPðôéSMMM###“ûúõkSSS”´9�� �IDAT'rïÞ=|`ÍÌÌLHHÈÝÝXsppø”šššGÉÉÉYXX°‘OHH@¼DK—.UQQª)ñµ;v Èd²££#ôuVTTøûû+**®X±Â××—ý«[¹r%Ú²611ÑÕÕ•’’rttôôô„Hâ&9räÈéÓ§±ÿ<âãã322–,Y‚vž‡ƒ¾¾>NNÎÝ»w³ˆ6UVV>yòd„ ¨ ³fÍ‚‰ ÕP÷ô÷÷G+° 6àÓ4ðvîÌ™3lÖFüñêá^^^ÑÑÑMNPP¡¡!>PÜÙÙ¹{÷nIIÉ3f¬\¹R@@àÀgΜéëëûv]’ÞÞÞÉ“']¼x1!!aöìÙà ‚ˆå¯y M¹ CFFÍ„ åÖ­[ÂÂÂööö?”âÇÞܹsGSSóÆ02/^¼èììÌÍÍíîîÎÃÃA¡oLa£UUUuÿþ}YYÙƒÁ€ùâ[ŒŒÀðÀhüø±°°0Lduuu·nÝ:|øð É ]]]·nÝÂOŽ(щ€€€„„(œ={6Lë®®®?º æååEDD0Œœœœôôô¾¾¾W¯^Í™3'&&&;;{É’%(í[ðñãLJ®Y³ÆÍÍ­°°°¬¬ìÙ³gW< ÍŒþþºg‰ŠŠÂ+…½œ²²2sss777XÁÄÄÄ œ„††ªªª4uÈŽÞ¹sþ ‰ð”ººº¯ ï‹ÏÌÌ422Âï±Óäœ?þ¯¿þrsskmmmjjºsçÎÆ«ªª=z¤¤¤Ä²!<kÖ,0<lB%Un¿………ÅÅÅÃIÞÃÃÖÖvàÁR'''0r·oßþ•MÎÔ©SQ^ ÂÂ… ÁðàS\¾|yóæÍO‰¶µµ]¿~ÝÎÎÎÍÍ­ººº²²òñãÇ?bÅócM޽½=l±Âˆ†]¼x•;V®\‰Â\a(‘Á½{÷~ãQШ¨(üÂÎÊÊ ©êž¡ô i4š§§'‹É©¨¨HNNÆï~c–‘‘ÑÖÖöñ´¯ƒ¦¦&Úú¡\ø7..NEEå‹>l ''gkk sqq‰DXÒ±`þüùßx´µµõáÃ‡ŽŽŽ¨dâĉhÃÍF8<<œ@ °˜OOÏÕ«W³øþ'Nœ€D’¯©ÉÊÊâs¦‡ ‰±hðc888`ú¨ªªJOO?pà�þâÌÌÌ––¤f=¾ËÌRXXɯ䄇‡O˜0á³Ì™3gvîÜ9h÷øõ#((øE�~2®^½ºnݺ&GXXÍN<<<D"ñý2“3sæÌ††pîàôŒ‰‰ÉË—/¡#¹}ûöŸþ ™Z€7nlÙ²i@BBBNNNcÇŽ577‡BnnnبÔÐÐ(++ƒB~~~9†††qqqP8~üø)S¦(++#Ūèèh ‹á'D±`Ò¤Iêêêpó1cÆ€ðWbb"ƒÁ˜?>??LLLHH†ajjjjjjøP^HHˆ ¤‚8pàÂ… à9B´a̘1pg‰s"‰Djll„B^^^ðOyyy!ÆŠ¿_Z‹cÇŽÁlH `³°°€qqqmܸBjùùùkÖ¬Á:ºººÀ)—¥°±±™4iÒ¦M›¢¢¢ÂÃÃ1 ³¶¶†õÜ¡C‡Îœ9‹h¬-[¶ Ê:88ÈÈÈìܹ­J ÂPëŒáÀÉÉÉÃÃ^ïÑ£G1 ëîî¾pá¡C‡ˆD"NG5Ý´iÓøñãÑ£}}}³²² ûSOO/&&®ObÍš5ééé ©¾`ÁØ ¹|ù2ÄyvíÚCQDD¾K$÷îÝûµxúô)r„---ÕÕÕmmm ·bÕªUƒJù’H$Tòòò˜˜+++øoii)VS¦LYµj//ïÛ·o!»DPPð[”Ðxxx:Äæ ôøùùa#66–‹‹ ¢Ó±±±ÚÚÚxmc{{ûˆˆPëÖ­ƒ±#&&vüøqƒÔ‰Ÿƒ#GޏººÂsaø´µµÝ¹sg÷îÝÒÒÒÆÆÆP5ð`¦NZUU…&CHåçç¡B%%¥ïå±}G<xðüùóø©©³³óÊ•+û÷ïGý*==½¤¤%}_‰D¢³³3h+((ôöö666‚£ÇÅÅ%++‹¶ûÄÅÅÉd2•J%“É è,ìõ‘Éä%K–@Êr]]œœ>¿@DDdòäÉœœœú&“Éd2Y\\\]]——WII©®®ŽL&«ªª‚ ;v,…B!“ÉZZZpºMFF†››»··NS²8¤BBBüñ )OffæäÉ“®r899¥¤¤Pf0™L–’’jmm%“É3f̀龭­‡‡GJJJNNröÉd²±±1ËÖ‘°°0T|MM€€�™LÞ¼y3<HCC£ººšL&ËË˃u7n\ss3™LÖÔÔ„Ý] AAÁÎÎN2™¬§§7¨#ÌÅÅUXX(!!5%“ÉÈ+™1cƇÈd²„„oeeåÚÚZ2™¬¢¢¦”F£õööâÏÒòòò*((@šÖ˜1cÈ8¨ªª «¨¨tttH$2™lii éS§N­®®…3‰¤®®•UPP`9XÇÍÍ-'')pø†øôéǠšjVMMÍÚÚZ~~~2™looÏÁÁÁ`0ª««'OžÌÍÍ­¢¢5URRbqºyxxäääàØ´´4_ww7™L^°`¬®AË’L&›››Cn‚ººzSS///™LÞ°a¸MÓ§O¯¨¨€òNEC‹J¥666BMyyyåååÑžËëUQQ!“ÉÊÊÊœœœd2Ù¡2e ËšH$JJJÂ/'‘H"""è†ð†ÇŽ+$$}iÞ¼yøSx(›ÙADD=”H$N:•@ Àaì ˆ­³fÍ‚ÑÚÚÚÊÇÇ¡3~~~eeeübQUUµ½½‹‹‹L&[YYA’LåІ™Žø-àææÎÉÉQQQ™5kVee¥¸¸8¤fô÷÷744À|2a„††2™¬¦¦Á411111±ööv2™¬­­ ŽÚ¸qã899ûúúÈd²‘‘ÊÈÿ™àââ*--%“Éð>………ÿøã>>>ä‹ÀÔ$""boo €ÚÚZ¼u$‘H222pf€H$2™L*•J"‘ÚÛÛûúú†ŸÆÉÍÍÝ××ÇÅÅÕÛÛËd2SSS“’’Qíèèx÷îËÑ„ßÀ±fmm=ʱöËb”cí×âXôÈúo àX[ºté(ÇÚPÝl¨‚vvvâ*²èå°¨‚Žr¬b£Å(~FMÎ(F1ŠQŒâ'aðôð}5þó€�†a|||C¥“ýv€c‰¼¼¼#¦™ i¸¸¸FL ×qrrޤ¡ÔÓÓóÝT~‘ÉỨËü:“Ïwi&€§òúQ&§½½ý+ŽüÊ ÓéÃ'Yù-ÐÔÔ”šš:bІµ´´prr²ÐúýÖèìììììIC©¿¿ŸF£°É¡««+&&fÄH´aV__O¥R‡ôÛ!$$ô]˜ŸØ™nnnHW3f ð9Ž˜ô*•*++;=ßo..®ââbŽ_ïýû -NÎæææÊÊÊ3”888BSSÓHšøøøjkkÙœÖúí&‡žžIIÉA“ì¿¢“H¤ïȤ0¸É!‘HßѬýçâààIBÔüüüÙÙÙbbb#)c­®®Ž@ Œ˜ŽG"‘BCCÈ©d¬qrrޤÉAPP““SRRr$e¬ˆˆˆ|—fUÅ(F1ŠQü®øŒÉyýúõÁƒñ%ÁÁÁúúúúúúÀ} ¸pá™ùA±råJ /Å0ŒN§ÃõÕ÷rss÷ìÙ'$$èã€d¼¼¼ Å”ñWâõÙ£¬¬ (¾á&.\xýÅ‹áÓøøx(Ù»w/þÑÕÕÕèâŋ㩠›ššà8ü’’GèAAAøw{¬]»–Å 100Ð××Ç„üðáÜ/ÖÀ‚‡Ú¬‰‰‰,WnÚ´ A._¾ýZD9ÕÐÐ�%HÎ ;;_/ ‡&þúë/¼6 †aæææpŸ|Ã?~„¶oß%¯^½Â?ˆ~ r†ÿú‘#Gà2Ðh@°°°�ýJ�þ†Ÿ­Bppðµk×ð%—/_†¯ÇÆÆ¢Â]»vA!(",Y²q¼vttàŸú�iii ;� Á_ ²†9sJØ+n˜˜˜°!-,,Ä8¡@',€ôC·mÛÆ2pLMMÑeˆUäçÀÐÐP__PúçwïÞÁOBóaTT¾F,ç×ÙîÚ¶mhN² }}ý¡Xµòóó¿æ@ Ix“ŸŸ¿yóæÎÎN<JhhhVV–§§'†aaaa÷ïß_¿~ý¿ÿþËÇÇ…žžžD"q GËÊ•+_¼xf° ÅÌÌ Q ¬[·‡Ÿ>}:ÜðÇìzãÆ à+Ã0ìÞ½{ÁÈȨ¢¢bݺuH|w8g jjjV­ZÕÓÓƒßIJJ ‚›'&&^¼x‘@ÀA"‘àS///"‘¨§§WVV¶yóft®"]K—.mnn]Q(§P(ëÖ­ƒïVWWoܸñÎ;ÙÙÙÛ·o§R©øcáúúúè_¿~t9‡ÂÆ%óĉø;\»vƒƒ£³³séÒ¥áááUUUNNNðôâââ¿ÿþûÒ¥K,·òóó;vìbB»xñ"///¾Y]Š]DDbú:sæ ´,N‡NÜÒÒ²qãFøîÇíììnݺÕÑÑÁÇÇwþüyøÖ0w¡öîÝ›’’RYY‰þ133Û¿?pàå‚>}ú´k×.xtiiéŽ;<<<ÚÛÛEDD¯%œê¿ÿ¾——WCC~t=zTYYˆšÎœ9³gÏuuõµk×–•••––â#Ú¨g655!Û6("""Nœ8ÑÚÚŠ?AyåÊ�7¹yó&‘H400ؽ{·®®.ÐU<xðìÙ³ãÇ_¶lYcccQQbÞ¤ÓéUUU ó 1I ÃÞ¼y³mÛ6*•Šç¥nnnVUUENtÎsçΠã¯\¹B$ÑÀÁ¿áúúúââbôP*•jaa98VVVÝÝÝxòܶ¶6IIIä<±PÒYXX ª·ƒ‚⃣££±±1Ø­;vxzzJJJæçç�‹ÇÏL1544<þ<‰Dêéé122Âg¹¹¹ÁËÍÍ=xð ››ÛìÙ³Qðöö%ЫW¯úúúÖÕÕ?~ü?76ÿýwfffEEÞ«.((ðöö!˜A7Þ¿¿víÚo‚ùb“3qâDooï´´4 ÔB½ª··&ݰ0púêëëUTT °½½} |ÈÊ•+÷ìÙ“——‡oB¸žN§_¼xU"b˜Îƒ#§±±Q@@�¾N£Ñ@µðqãÆ±Qψ±cÇz{{Ÿ;wvtttttÀ}ÒÒÒðšZPSø®„ryyy–G{xxÐét<¥UEE\Æd2 tÒ¤IÞÞÞ/_¾Ä/#DDD`N¼q㆜œÜ d*Çïééa9 ^XX8iÒ$/�§···¦¦žÞÚÚ:ãÖßßÿýû÷x%ĺº:Ô¬‡BbEvvv«V­Â·&bÍÒÖÖ¯™N§£ÊBÅá~~þ/j# ÃöìÙãàà€wäÁ–L˜0&Т¢"üG}}}UUU¨7¢dy´©©éܹs¯\¹ÂâˆÌ˜1®lllÁºS§Nõöö²ðqÀ5 寿þN­¡0oÞ<ooï'Ožàõ---999ÁjR©TèÆ?~ƒ;úô –5—.]‚¨Àÿ·œœ,ÕQQQñööNNN©|wb¹rýúõÜÜÜ0²(Ê â /^ìïï700@% 9ËÒÒÒÞÞÞhÎ Õ¾’’’@{Ò¢à•VTTHHHÀW.]º„¶»UTT~~vQQ‘ŠŠ ¨‚²Èbvww×××Ãשׁª‚™4ßÇyyyAÖÁÂÂÂÈÈÈÍÍíWXßìß¿¿«« 9‘ø;”ÃWRRâââòÏ?ÿÜ»wïg›EEE–¹iÅŠ4 Ü(+++öø@‡´´4KbWW—–––˜˜ŠPõôô455 ºåÕÞÞÞßß?¨Œ‚££#¸{¾¾¾ÃaÓ#‘HŠŠŠH-¿( TÐØØ9òì±aÃØ{ V% ÕÂûhd2ùáÇpgyyy??? ÃxyyñË^<Z[[A¹ŽÍ£a=Ç’l“™™9eÊ&“) �º;Ÿ…Béïïgy!G >wîZƒ×ÔÔˆ‹‹Jô[^^Î^²()) Þ€‰‰É©S§†óÀå |^„¨¨¨U«Vµ¶¶b6Lm˜˜xôªU« ô„èÈð—¹»»;;;WãéÓ§á+àñ šÑD§Ó«««ÙgÙ ˆ‰‰áMêÌGŽ™7o’Ó} –/ðÛ!H�}‰EAÃ0Xmß¾ÖOˆÅnß¾}¦¦¦ƒr}BðåççGâ\\\ŠŠŠ …å[ ”ˆa˜µµõPc§¾¾^GGQ~a¶fÍÐAF ÃfÏžÍÁÁÁÅÅ5|‘ßÿmmm ÜDQQQQQÑŠ”ÿ `.xÞhîܹ@ °„ŽÁ7mll”‘‘ùq¿ê˘¤#""ªªª@üþýû=b/g‹aزeË®^½Êéêïï×ÑÑ‰ŽŽnmm?~||<pÐ>~üx 0e@@@II ‹ä- ®\¹‚äN:õ¥Þ4 55õåË—PÁ°°0OOO<{îÐÛÚÚ€óÿÎ;(Þ½aÆëׯ:Q(”íÛ·ÃËËËY¤…Y�"CŸ}½C…࣢¢`)faa‘””Äþzÿ²²²C‡±È“¸¸¸¸¸¸DGG;vŒ““sþüù¶¶¶{öìÔ¢O™2e`ÆC[[;''�ggg|0ð‹`ccsýúu°†††ø%—¬¬ìÕ«W¡z{{A\nþüùH:<<üäÉ“Cu§S§NÍŸ?¢C;wî”––f£/ÐÙÙ¹xñbð/‚‹‹Ë„ V­ZõEçóóóá ssó   A¯´´´D¢Dwîܹ}û6"Êtrrš>}ú²eˆ™©ÕÙÙ¹zõjàØFFFÈBž={©áGЂ þüóO|ÀíÞ½{JJJ666<––NKKƒh^__ߌ3~q«óðáúºº5ýe‘œœ ap&“©©©ùöí[¼Ëèäääïï?ü½ðnrºººúûû‘¤ÞkË—/?|øð´iÓX–8œœœñññd2™@ 466VVV:88êÀCÙ¨P³l ttt ª'¨¤¤;+""" Û7ÝÝÝÝÝÝPA`NeqWÿùçè^(>Žw“a­0è FKK ܹ¥¥¿=( Üñuá…úúz nnîÆÆFö¥¥¥¹ººâOä[YYqssÃkÙ°aƒ•••¾¾>òFYÊ>c›‹‹ õnnî>2†a'Nœ@«–Ë—/¥ZÝØØ(** cÙë"‰Ó¦M{õê†aYYYð8ôhNNN6ÒÑ …‡‡.¦R©ì#0™Ì¦¦¦¯VÊ8~ü¸¬¬¬¥¥å—¦çT¶¶66}‰5+“ÉDöÀšššæææ°Z]»vmJJ ZAÊÌd2Ù÷%ôÞØ¼dx½xûzóæM"‘ØÖÖS!êE===ì72Ðh4:Î~vú¥€º+ƒÁÀ¿Þªª*;;»AAÁ_Èä|)ÚÛÛÍÌÌ`yÞÙÙ©©©ùþý{hüLM§Ó³³³Á!¥Óé½½½ëׯ¿ÿþðdgggmm=DNNl—}Ëé4†QdÉÊÊ꯿þÏß½½½°Ó€ýO÷z̘1ýõüŸ ©Tª­­-x4ÍÀÀ %%eø'7“““oܸñàÁ6×ìÛ·3üj"‘QäÁÄÄIJäPý·8qâÄØ±cׯ_ÿ')ŠAvvög¯|ðàÁ‡ðù†:thÒ¤IkÖ¬A®Ã7PjÏ@Ïc˜xúôitt4>p8`ñG544ÒÓÓ¿úgŒ‚=¦M›–�»P,>ñÛ·oñ“°Ïofr¢¢¢PÊÖ”)SâââuPŽoZZÚùóçQ„Çßß?++ ¥9 …îîîÏ*¥óóóãQÐ#GŽÈË˳¤8wuu}»ˆ/ <==;;;Ù+b}/¬^½¥ª{xxtuuá%5ñxôèªéüùó½¼¼@xVEEEì)Cèt: ~nnn¼ÆÒW ²²ÒÊÊ V9ø@îgý¦zòäÉ,É Ã•}݉wüz…=úúúf9÷ôôÀ‰NT²Uöuèïïg“QaØž={æÍ›÷Yá¯ÎÎÎ¯Ö ÿÉðññ)..þE’†‰¡^¯œœš„322ÜÝÝPÁgr988ð]sýúõªªªa÷î݆>}úÝ»wP¸bÅ Èj777ÏÈÈ ‘H\ÿpŸšš¸~þüùyyy°Uˆþ¡?—>|¸­­ ¾®­­ IV>>>wïÞ…Â3gÎ _ŒeØ›™™Á}Þ¿úôi Ã.^¼6ïøñãÅÅÅðéÒ¥KAè,88øÌ™3PxçÎ$g‡_ a&**—mÛ¶ íÄB†ªˆDâðIŸH$ÞšÖÕÕIIIIHHÌž=öÆïܹƒÞl8GDDlÙ²…@ °¼|xîéÓ§ß¿_133366æääd¹ÿP|eÅÅÅ£££á»;wî„s'zzz[¶lÂ/^@Èk¸ž''~+;//oþüùp+àdëèè�¡ñãÇß¿>:qâä’-^¼xÅŠPøîÝ;hÖAßó­[·‚ƒƒáÊC‡áEÇY^2*þÚ ÿ NNÎ#GŽHüðï¿ÿBÉ7ð¼2ø§ '''Ãe›7oƆc° Š WòññÁâ•““sÏž=èÑlLðm*((È’ÇÅò¬åË—/\¸îYUUYÂgΜÁ74K;>{öìèÑ£ð•'Ož@šFyy¹†††„„Äĉ¦Vþ8�'–„„„††daTWWCú¸¦¦¦››üÎû÷ï{{{5;¡jþ:Œmœœœø~[TT¤¥¥%!!!##6¦¹¹yÊ”),“0‰D4~þí•hû-1*ÑöëcT¢í·À¨DÛg»ñ¨DÛ(F1ŠQŒâ·Ä¨ÉÅ(F1ŠQü$ ­1jfø˜ÀªÑˆi&”L8Z£_¼F#rrIÍô}kD ¾ozÔ&g [âï  ¥Óé#ÆäÀÙ#ƒ1bš‰F£uwwóòòŽ˜ÑétÈIC "GR( ƒÁIC Γ}¯ŽG§ÓÙ'"~“ÓÖÖÆž6ê·[ Ðéô°°°crB{{{RRÒÊ*ùOœ2àÚù¡ÇÐ~2 ox$ % Ã:;;GØäÐÝÝ9’£T*µ¥¥å{‰Î;ŸˆûCLް°ðÈËX[¶lÙhÆÚ/‹ÑŒµßb.ƒŒµeË–˜É2ÖŒG3Ö†êÆ£m£Å(F1ŠßŸ Ë´µµÕÖÖâ)2kkkáœÔ¸qãÐáó²²2‹PUUeá{~óæ þ¤ôìÙ³‰D"“ÉN'...tÚ®³³x!………wÃ°ÆÆF8€&--tt***à� ÝB7/((7nÜѸvvv–••á%FšššàH¹¤¤äÀådyy9|ĵžŸŸŒaS§NEDééé@ˆ0gÎ(éíín·1cÆ ²È¶¶¶‚‚ ÃÄÅÅ‘ À§OŸ@Ý`üøñÃqU²³³ÕÔÔð 1püž““SKK Jh4°j ©««ã¿^__g¡‡¢fÅW6//¨ç¦M›†N­Ce988ttt ¤§§ñ•Å0¬¥¥¥±±QEE勺i^^ž¼¼<žº"33èytttX¯]]]@#((ˆ777éX|³~üø±ªª ð &�e5†a………ÀZ¦®®ŽxA²³³!î§¥¥ÁÌAû0ÔÖÖvww£>ŒïKÊÊʈù õ¥)S¦ †½ŒŒ `{C}©¯¯/##Ã0>>>$¶„ú’˜˜zè/ÉÉÉ!”ÒÒÒúúz Ã&Mšä@ƒ"==}æÌ™CEœ¨Tê‡ÐF ##Ø,•¨©©‘ÉdTYÀŒ3¸¹¹ÑÀÁ0ŒH$þL*©ÔÔTƒ1èC;::rss1œDCCžže>äççÇOMÿ!rssQ_BÃ0À"•„&á³Ä79íííYYYoß¾MKK¦}è¾þþþpÚyÖ¬Y–––ãÇ/))ñööjÛÅ‹›™™¡é ðíÛ·óó󣉨ÇLJ/!!tJøøøµµµ;;;Ÿ={x·"�� �IDAT7nܦM›&OžÜÐÐúS¦L±¶¶VTTüðჯ¯/Ì) ,X¹r¥„„D~~~cc£‹‹ËéÓ§êM Š®®®´´´ŠŠ t�»©©)88822fœµk×âO€—––úøø@Ï322233ûöíÍ›7?}ú„a˜µµµ±±1//oJJЇ‡l»õ÷÷ëééõõõEGGß¹sÃ0QQÑ-[¶Ì˜1£­­-44444æ[[[UUÕêêê'Ož€ðŒ¶¶¶……¹¤×¯_wttìØ±ãÙ³gˆîìÅ‹ ÀÆÍͽcÇ®®®ÈÈH"’––¶··×ÔÔD7‰ŠŠ:sæ 2xVVV+W®´Yß¼ysóæM˜;lll/^ÌËËûêÕ+ÞÞ^Žþþ~]]ÝÞÞÞèèhÐIÛ²eËôéÓ[[[ß¼y“‘‘QTTïa˜¦¹¹ÙÙÙùÒ¥Kè ZjjêÕ«Wa+»§§gþüùèzˆË7””””½½ý”)SmÖÊÊÊGÁÄ­§§·jÕ*iiéwïÞݽ{9ÍÍÍMMM333===! ÅÞÞ~áÂ…D"1>>þêÕ«`S·mÛÆ¦×ÕÕÕ½ÿ>22’‹‹ ‘g—••ùøø�ïÂ… W¬X}éöíÛ ÇbeeellÌÇÇ—’’rõêU0x}}}úúúýýýÑÑÑ@ %""²uëVèKaaa!!!†)))ÙÚÚNš4©¦¦æÉ“'@%>{öl 99¹âââ€Êê’%K–/_>P$55µ»»{íÚµ%%%àXô÷÷gddèêê‚û’žž^ZZoðäää ¸è²eËð&'..]™ŸŸåÊ•… îß¿¿»»Ùu///qqqKKK 8½ÏËËûÓLNRRÒåË—ét:‰DÚ±c^g²££ãéÓ§þþþ†啺ºz||üñãÇUUUášÕ«WËÉÉ•••}üøÑËËËÄÄ„½ÒÕOÀÛ·o[ZZ8póæMäUÛØØ(++Ã6‰DÂ÷[ùðáC Ãdee7mÚ„Ÿ%~¸É©««óòòjjjÂÛ˜˜˜šš`Jwww ܽ{÷íÛ·UTT€ßÂÖÖVVV–EÉÕÃÃ?qcfii NVCC òòòªªª®^½ Æ,11ñĉOž<yõêÕÛ·oáqžžžÞÞÞ...>„Â;v¼xñbõêÕÏŸ?ýú5,}†‰ööv///¾ÛŒŒŒ””¸ùÝ»woß¾'G¹{÷®‚‚‚‹‹ †a›6m’––611qqqÙ·ox÷{÷î3g//ïÆSSSÉd2“É”’’ª««koowrr‚qþñãÇëׯϘ1ãÓ§Oè}xxx\½z5""¢µµ ]]]CCCÙˆN•——#…oÀš5kjkkA¢M[[»°°ðÓ§OçÏŸ¯<%%ÅÅÅ)±/^|öìY| ¾Y7lØ ##cll|ôèуÂ, ¥¥5mÚ4yyy[[Û¬¬,AAA:>nܸOŸ>Q(”ƒ‚¹ÊËËÛµkWlllMM ¨pâg¢Ï"222''‡%”¼y󿏏8ØÇ’€¾„Vl§OŸC’žž~äÈ‘°°°ÌÌÌW¯^Á+}õê•’’R`` :99ÅÄĬ_¿þÂ… Ë–-ƒWqìØ±ºº:AAÁ'Ožœ<y–AŠŠŠoß¾åçç·²²‚çÖÕÕ-Z´OÏ‚¢¢"//¯?âMcjjª––nnÞ¼YJJjÙ²e®®®ÿý7ØÌ;WSSSIIÉÛÛÛÓÓÖîPY*•º{÷nXRnÙ²åÅ‹µµµ?~„ê_ºtéúõ뢢¢PxòäÉ¿þúËËËkêÔ©`üllläääªõøøø477#wæ£ 6€1nmmõòòÈ®§§‡ÔâY`oo:{¹¹¹¾¾¾hV9}úôÀ5âǾD›µµuII H´!δD»{÷.(DGG»»»ç¡¡!‹º.hZ¾{÷ذþ[„‡‡çççãGÀÛÛ{P®¶¶¶ŒŒ è-III®®®ìV¾³ÉQVVöóóKHHÀ÷!99¹ÊÊJ¤€;(Éù@$$$ÀðX¸pá Ò^ߎ½{÷böYÆ@<$$$üüüòóó‘ D]¤¤¤ ‚ eøKËäää¶¶¶£G²§1§Ñhñññ P¦¦¦¦¦¦V__Ÿ™™Y__ÏFše(À}X­±±ñÓ§O988zzzØháQQQµVRRúÒ¨×0¡®®îçç÷ìÙ³ÀÀÀá ”¾XT ,XðòåK$ªT?(jjjrrräääðz-ƒ"##£¡¡aûöíàþƒŠ‹‹ëêê200øÒ,A=====½›7oâEf‘ üöíÛ±cÇ¢°Þ@ å͈ˆccã¡.›4i’³³3˜ÀÚÚZˆ¶°^YYÙû÷ï ÂðóŽ`‡w899‘LŸŒŒŒŸŸ_vv6‹ìPuu5ô"gÁ¥K—ÌÌ̦M›†"À0' 3ÉÃÃC ØÔ÷WÀÇ¡¾ŠŠŠm³¶¶¶¶¶òÉÿÐÎ�QQQðªY좴´ô™3g ú]RR‚bò?u/‡òòò999à snúóÏ?‘ •J]±bÅ ©{‚‚‚Ó§O KXÜ; sss!6ª¦¦+z Ã*++Õ4üjHIIÉÈÈ@ÇÏ¢†0yòäOŸ>Á£!úYÍÍÍ­­­ÍÍÍ+V¬Š ¹««+(((!!A@@€N§#Ÿ·®®.88XZZú‹L&˜šš†††2™L..®ádÊËË ¢f]¾|9 °`Þ¼yùùùED D“ÈÈH‰„ÎpssëëëËúÌŒ‹- ‡¸%Kùøø´µµáÑø *XM¾yóFNNÄ©†º9H„544ÔÖÖ®X±muDGG755~ÇÄôœœœÐÐP“Y³f±¿2,,ìéÓ§Ÿ HÖÕÕ‰D¼¸_qqqpp°ŠŠ ¦NÚÜÜ ¯šr8 ‘Hì­»¬¬¬¤¤$ô"yyyƒ1]÷õë×ÒÒÒHùWOO///öZ[[W¬XÁÇÇÝ vúûûMMMM{#'''""õUTTd2™¿E²å’%K`¹aðsNkkkpppKKËÒû²Áóòå˺º:"»»»?{öì³VÂPhUdll<¨É‘––Þµkøìõõõ0ªgΜÉ`0€C»¨¨LŽ™™Ypp0¼µ/Ф=~üMˆ è9èðúõkØ„¸{÷î£GðsÓš5küüü`o öÕYYYgÏžUPPÐÑÑ™;wîP&§§§§°°ðöíÛïÞ½sttD&GSSóöíÛwîÜ™>}ú·7êÖ­[ñµÏºŠººº£Ç0ìÌ™3Ïž=ÊäìÝ»÷ܹs °‰²Bþý÷ßÝ»wwuu!RtAAAWWW_` ú±Gvv6l•a¦££ƒöcYàä䄬áY&ÅÅÅ<xìØ1Ø™ÃÜøùùoß¾=°Yî:uJCCÃÄÄdÊ”)È主»Ãäbbbò ¨²OŸ>]´hÑg·+‚ƒƒaëˆ}–}}ý@{ ÁÅ‹Ÿ<yòùóçÊÊÊ666ÞÞÞÐAu-!!…_Œ‡RJܵk0cÆ ¤9âåååïï?Ðäܾ}ÛÐÐ-qœœœð_×××çããCŠ;===JJJ¿¬ÉÑÑÑAÉ2/^ ý-LÎ… àƒ!##ÃbrÚÚÚ(ÊÓ9ýá ÃÃÃuuu* ĸqã †˜˜xíÚ5(ÔÒÒ‚õ§§'fff`3vìØ1ü_’––s"??ÿP&ç³°°°°°°À0 úb¶{÷n|&ÒPf‘^®««ËÏÏÿlœçG£¤¤¤¥¥e˜ëhˆaBÓ°ôc8o %d2Zör†ùK*++‘R¡ŠŠÊP&‡=$%%áÑééé'Ož„ÂiÓ¦mذa8_ß¼y3Ë\¦¯¯ÿ}í³²²ž?¾`Á‚Ïf»¤¦¦ž={–ýɾúúz‰„·7EEEííí7KÖ®]»víZß{÷î&øêšVVVVUUáwÝ?‹¨¨¨iÓ¦±ÈªSõ¯ƹ¬¬¬¡¡a˜ÉJ¿üýý—-[6è…Byüø1•JEcü·49îîªŸ59­­­‰‰‰,– ¼¼¼ªªŠå$]VV‰D§5ÿþûï7MKKü޾Lii©§§çnrRSSóòò†cr"""¦OŸÎ’ýéëë»jÕ*|'îêê ±´´üÒ_bffö¯·££#**jåʕ߷«©©}_“"++‹’žÙàÈ‘#IIIŸÕH-++‹‹‹cÉ INN.++c19¯^½ÂgQc6”(ß— ###Ù˜œ¤¤$iié & ’Ë—/»¸¸°˜œƒš˜˜üú&'33355õ·39ÎÎΆ††ƒšœ††oooÈ•ýULŽššZMM Z‚Àyîܹïß¿‡Â‰'–chh¨–––¤¤äš5k"##aoii Uµ··‡ë x[}}}oß¾…ĤžžØ×êììLNN†£T*Z·µµ5;;Þ‹¤¤$Jíý.PPPPTT„ßÖÙÙ ã'++‹ÉdΘ1£¥¥%)))11®„•©©iFF$³B*ˆ­­­¯¯/h�¯“——wåÊ•pç¾¾¾U«VA8QSS »ºº Ô¦¡¡ÑÜÜ …$é+r ¶lÙn>ƒÁ°µµ…–¡¡!ܳ··‚åååeee†††jjjÕÕÕð)“É„à¾Y¡²µµµ=‚F422‚Y¸²²òæÍ›`Î7oÞ Ëôݾ¾¾ï.¯²víÚ'OžÀë…<¨ÞÞ^__ß 6ô÷÷çååÁR©··ÎÉËËËOœ8‘¥Y§M›–žž…ÂÂÂ`ê ‹‹‹¡pÖ¬Y`\׬Y“ ••¬6ìììà2:þué°ÉÉÉh÷kÑ¢E²{ýú5ìmüùçŸ(­èÎ;°ßK ¶nÝÊÍͽzõjxz?ô% êªªÐØTQQY°`ººzCC‰DÈ)hnnNMM…ƒ***Ôçâ₾4&Nœ(''Ï¢R©tÊÈÈàä䄉" @[[ߟ—/_þêÕ+8¬¶dÉH½Ù¸qã½{÷888˜L¦ÝO›‹íììnݺÏåßŽŽŽððp+++qqñ9sæ@Õº»»ŒŒàÕ•——CaOOÏpÎfý °µµõññ±£µ««ëÉ“'ëׯ‡¾ºœœÜÈ»#‰Dggçžžž¾¾¾ââb…ÞÞ^tXÁ` 8ƒŒŒ 77÷Û·oi4Úœ9sôõõ1 SVVnmm---¥Ñh+W®„¡›žž>~üx!!!--­×¯_755Ñh´ýû÷CŽ¿¾¾~dd$F#43fŒªªêË—/i4šŒŒÌºuë0 “ÊÎΦÑh3fÌX´h†a&L ÑhEEE4ÍÄăÃþ§ <pEÅÃÓ™™9yòä«&“I"‘ÐЏ¸¸˜˜Xff&FÓÔÔ„7^VVÖÛÛ+//¯¤¤D¡PJJJh4š¹¹9ä³M:²i4Ú¶mÛÀe›;wnbb"ßÁn‰Dš1cF\\FܶmDŸdeeÓÒÒh4š²²2LÍãÆãääÌËË£ÑhzzzƒæGpqqJHHÀLÔÛÛ;kÖ,äDDDÀ±Èøâããûã?^¼xA£Ñ$%%!ÄTWWWUU¥¦¦&--ÍÃÃͪ££IÊÊÊmmm,Í:mÚ´wïÞÕÖÖÒh4”Ð5oÞ¼øøøööö®®.Èúåââš>}:TVXXxëÖ­è—3 !!¡KNNÎOŸ>qpp°ø¼¨e555Ñ:cΜ9/_¾lkkƒ× ¡ ¡®¡¡‘˜˜H£ÑÆŽ ñO|³Nž<šU^^¾¿¿ÿÝ»w4mÑ¢E°¯®®^]]]YYI£ÑÖ¯_Ó±––Vff&ôáÀ{Ö××þü9F#‰ƒ"ˆD"•Jmll'ŒN§KHH œ±þþ~***âââS¦L)..†¾äàà�›U===pYWW—žž‰Dš5kVll,F€5 ƒÁèêêB7ž4i’¬¬,‰DÊÍÍ¥ÑhhÇNEE¥©©©¬¬ŒF£­^½šÍvlOOÏœ9sàˆ ''§®®.@(((€æc0ÜÜÜh�Ž;VXX8++‹F£MŸ>æåââbƒÒþþþ‰'JJJ¢ûOŸ>½   ®®ŽF£íر¶Ítuuãââ:::zzzþùçŸ=sssçää€…ŽŽŽ¦R©ýýý‰×ÝÝ––¦¥¥% 0qâÄääd6~üxkkk 䤤ƌ“““C£Ñ´´´ð±Šþþ~EEE6Yˆ?\\\¥¥¥d2ÆKooïÔ©SÑîã¼yó`´ÂÔÔ××—””¤­­Íd2ñ]ˆoòäÉprŸJ¥’H¤ööö¾¾>”ý1œwÛ××ÇÅÅÕÛÛËd2SSS“’’FUAKŒr¬ýúUý-0ª úÙn<ª :ŠQŒb£ø-1jrF1ŠQŒb? ƒ§ÄØ82†ñòòŽ$½ ø¹¹GL3Áæ<‰D15‚6âää15âàà�&½‘79ððð|6'ðwì½}¯Éô„~¸É¡R©@E<bÀ`0^½z5’„¨ÛÚÚrssójd ¶¶–D"±°ÞýÖ P( e$ ¥¾¾¾îîî69ôôô¤§§µC à °¤;øøøØÐ“C$Ùs…ý^€õ€€Àˆ19ÜÜÜUUUcÆŒ1Íù0ÐL#ÆÙäàà€¤²³ àààøðáÃ›ŠŠŠøùù¿—†æ¯09ÔÕÕñòò~—f"‰ßwQË9Ôfá~þ­!$$”˜˜¨¤¤4’2ÖŠ‹‹ƒndÔˆ‡‡‡J¥„Óñ c­½½}ÄÔ2ÖÞ¼y3’&AAÁ´´4EEÅ‘”±VYY)--=ª :ŠQŒb£øÿŸ _æååEEEáOºÅÄÄ�Ϧ¹¹9JÏ¿sçfþûï¿Y8q<ˆç¾uëZ¦uvv:99M:BaaappðÁƒá¿ÉÉÉp~ñâÅèŒ÷£G€3ÜÞÞŽ£bvöìY �8~üøðIÚ?~üxëÖ-P…¤§§±àŸþ9•ëÞ½{À¤°}ûv® ggç­[·"ÏbË–-T*•ƒƒäÂ0 kmmå999777(ÌÍ;H8Ó}ÿþ}t[}c_‹}ûö999áQÚØØ0™L~~~¤=Q]] ÇBË=BBB­[·ÐW¯^·¿víÚôéÓYèp:´}ûvt(ÌÞÞE>xð�Jš››ÿúë/ ÃÆl­†½}ûØÑçÎëàà0ünêêêjii‰ËpttÂÐÀ~)§OŸà|±²²2MExùòeii)œ-Ç0,00•mmmÇû¥K—@nÇÙÙéáîÝ»=///8Uçâââ/^d_…˜˜˜††ü·<xuA‘'Ož&u777D1çàà�J¬>>>h¥ÞÜÜ|êÔ©óçÏ£æççC¿š={6ÐÆÆÆG-ÀÒÒ'÷ôôœ6m{–£Í›7_¹re(Á‘òòrŸ#Gް €‰‰ žñ Ôcñ4û÷ïßµkœ…ƒ¢^øžù£akkÛ××ÇÃÃøIJKK¡/M:æÃ¤¤¤ëׯ£ Ð|èííýüùs ömÛ6B££GnذéP ƒa¾{À|s¯šš‹2Å79ÅÅÅÎÎÎÍÍÍø‰,666%%x/²³³ƒ‚‚ÌÍÍïÞ½K¥R¡000@ àÏ %%%ÙÛÛ£¹ L{zzlllN ¤¤dÇŽè lJJJdd$Ü9??ß×××ÚÚÚÏϯ¦¦ ãââ‚®®îÙ³gEEE¡ðÂ… ûöíû¬X}}ýŽ;:::ð:T™™™ÁÁÁpŸ÷ïßß½{ouîß¿O¡PàÓ°°0"‘ˆìëáǽ½½Ñ„²yófSSSXª[YY=|ø°££c×®]ð]ê;}útAAÁ½{÷ °¬¬ìÚµkÛ¶m«¨¨ ‰Àó&›Z8p ¼¼üÕ«Wx7+++øÙ===›7o¾qãFmm­««+<¨®®ÎÕÕ®»ªªŠN§#¢RüÌîééyåÊd3áëë‹èOìììÌÌ̸¸¸˜L¦…BÙ»w/\ÐÜÜ|èСS§Nååå=xð� \n8VÇÍÍ è½ñÌùÛ¶m322ßÅÆÆæÑ£G裆††£GÂSêëë;†¬Nrrò¡C‡P“•––•)))þùç¥K—øøø ðúõ뎎ŽÊÊÊ{öìÑÖÖV ‡›7oòððDGGƒ~"ÌŒlªðâÅ‹«W¯VUU-X°�z{{·´´Àƒž>}J fÏž}òäIYYYø…§NúçŸddd¶nݺdÉȧ²²²zôèQggç† º»»ñLêïß¿¿}û6ܰ¼¼üÊ•+Û·oWUUEÍôøñc»uëVttt~~>â<‡æææ„„$AF£Ñþþûo˜¡jjjvíÚE¡PðÕµµµ P ÿe€³gÏ–‘‘¿Ï;‡È[ÁÞ<|øÈWÀ6_¾|ÆÎÏÜÒ_¿~½••(&lܸ¯ñáÇ‹/›üøñã¹sçöîÝ;qâDônCCCÕÇǧ©© ÊŸ={6PéùgÂÕÕ5///##t766ÖÝÝXKX|µšššS§NÁÿôéÓÉ“'„Õ²E%%%ß¼y“ššŠÿMàfggWTT`VTT¤¢¢…¾¾¾@‡Ž‡ŽŽKðh©ìììðZFåååçÏŸ777a˜2š››áΓ&MÛPVV& �…À©îóúõë¡ÐÝÝ}8YOBBBŽŽŽÈ1Ç0¬±±±¾¾îS]]×r3¬  �Ÿúùù¡asøða ¼m~ùò¥»»;¨‚‚ñèííÍÈÈ€â»wïÀ?jmm­¬¬„R(”„„øúøñã‡)­¶zõj`‹ÀÆÇÇûúú‚xxd4-//V<HöqãÆ |âõë×™L&‹Í;xðàÔ©SÁ=GSê… ™L&(Ž÷ööfffÂôD¥RR¥¥¥¥ªª žÒÚÚ êÈŸÅÒ¥KuttXº~RR’‹‹ ìc±ð›uuu48øÝOž<AîËÓ§OçÏŸ<hè½ð{@î–õË–-ƒÂK—.ðeZZšƒƒXâ­[·ö÷÷cF †ÙFªªªŽŽŽøÂ9sæpssÃ,ìïï,é999ººº@qtìØ1 ,²µµ>}:øjPYnnnGGǦ¦&¼+ÐÚÚZQQ?)88HVV–ÝOž<QVVÚ\===%%%ö˲õë×÷ôô€Œ, ¿¿ÿåË—ð7™Lvtt,))aQÛ“’’ꨪª‚"ƹsçV¯^¼R''§™3g²�/×öÓpãÆ Peá9moo/..†ªEGGË¢””PÚ„……IIIÁ’NGG5k@@À@EΟ‰eË–éêêâ…úúúƒª‚’Éd{{{`ÿJJJ ÿ©«AAA===ƒ79FFF â<ºººkÖ¬Î36oÞ nà£GÀB0™Ì””˜¨TjYYÙºuëÉDEE]ºtiùòåÈ‚øFhhèÎ;‘Rá—‚‡‡GOOOTTorfÏž][[ œ>}:žŒ Þ¼y³|ùr|~ˆ¯¯¯èÕ‡††~éo Mšõë׳É@˜Èâe‡††‚Œ&//¯¯¯ïpžøôéS Oµ²²B“xqqñ´iÓXx£ß¼y³jÕª3ÂòåËûûû‘b,¸½›6mš0a•+W¾ºƒ‘ oÞýû÷A°g ù---zzzðb1 [³f··7´µ‘‘p‚ }}}ð];ÅÅÅøÁ•ÿý÷ß™3g²!`Fj:Ë—/ ß_OO/øYTVV„qãÆa¦¤¤¤¤¤„–hlŠ_dŒ3}…OOOO@@€ÅäÄÇÇÃ;Y¶l‹f~5fff†’nß¼ycmmÍÒÌÍ͉D"‰DúбóóQ]]Ýßß«:Ô¬/^œ>}ú÷üR�Ýþ@ôÕ«Wsrrrpp<{ö _ÎÇÇöæÝ»w=ruuýörX�ðSbcc_¼xaeeÅþ+7nÜ€™ðuëÖª¹‰‰ ~n‚!qîÜ9––|yll,™LvuuMNN¾yó&Ð߸qÃÞÞ¤¹ Âw$ÿ/,,,((€ ¦¥¥={ö ïï888xyyÁã>|ø�>ãþýû7lØÀ æîî¾sçNpùAåp 455W®\ 7lii5øòåËÍèóçÏýýýUð0áââÂ<4ÍÝÝyúCÁØØÉÇÆÆB�óêÕ«ŠŠŠFFFøåȾ}ûìììA.[¶ÌÍÍH$.Y²úqccãÎ;]]€`[ç�� �IDAT]?}ú´}ûöo±:qîÜ9GGG°ñ‡ÆûÈ’’’LJWJ¥Ra%”ššš˜˜xðàA¼ÛþâÅ hëÐÐÐׯ_³È]#ܼyÓÙÙß`OFȶ¶¶¦igÁÅ‹ùøøðÚ£l<ÖC‡}6ðãÇûûûÙó@ÝÝݧOŸfGÀCOOÏÏÏþ~õêÕ7ð>"sæÌAöu÷îÝ,!àà`XG‚$(R`ú5ÚØØÈÂx}éÒ%`ŽÿŽÇY¾üýýûúúÀï766fY|CÔêÂ… NNNß—¤ÿ+MNSSSww7Lˆ±±±xeÌ¡€Ÿ‹ ètúŸþùï¿ÿjhh ]¬êêj''§“'ONœ8?)`6cÆŒíÛ·ËÈÈddd Èµ©©©µµµ˜˜Ø½{÷XLèëëƒD™LÊ{jkkkmm… æææ²ÖdeeV¯^ q°73fÌX¼x1‹›–››«®®µœœœ¡~’€€ÀÒ¥KÁ‘áä±cÇ¢Ô爈ˆ¯X›çääL›6 kHd“ ÄÄÄÄÄÄà︸¸ºº:OOOƒamm3ûöíÓÒÒ222¸Ä9uêÔ¬Y³ð•>~ü¸ŠŠ ^ó—{xxÀb 'NeA^^žšš¼%–×ËÍÍm``�‘¼¼<??¿ŒŒ Ÿýû÷ËÉÉá{ô^hëÇã%Döáãǃî5Ú~Gnèì}ÅØ»téÈÉdöWššš:;;5=~]]“ÉdCl¼k×.´ø{ðàÁ û t:}_"“Éè¼~ýzÐEXEE…’’DuvïÞ=oÞ¼E‹g†÷ÃàžžHú•ÑØØØÛÛ‹¶©0 »|ù2‰DN³þ‡K à ÆÀ©©¬¬ìĉ...ÃÏÀú±&ç+`ccsòäI¼&GAA,V FKKËòåË/\¸ðâÅ ˆçtuu555íÞ½„&………ñ͉<Y4E^^^íòiöE@Êíꩨ¨ˆŒŒ„¬¡ÊÊJkkëÐÐP_ üüü  QTT&Çßß¿¶¶Ò½~š§VRR‚ÏK¬­­}üø1xîµµµÉÉÉ"""QQQç΃Š[XX„‡‡CëüñÇ©¿`F"‘>+R>kÖ¬A3ãð9ÒYÀÍÍ ¯öB:::ÂÂÂ`J¥P(ÝÝݲ²²øMÄá�y|(Ö4oÞ¼anG e\‰D¢¥¥å Qu<–.]zôèQð!~Pؽ{7¼«oyíqqq°Ç6Ìë?|øéš«V­Šˆˆ””\¸pahhèoÊ©såÊ++«Ï6ë…%K–øùù zJ´²²òÀçΦ„Ò/jr***ð)aå€ÕF{{ûŠ+<<<$%%ÑŽQvvöÍ›7ñ¢èß ***ß8hÏŸ??nÜ8Xå G… ­¬¬\]]ñr à TÞ½{—%M¼µµu` Æ…BaYKíܹ¥ê9;;ëéé͘1ÃÃÃUÖÂÂÂÍÍe›çÛ1vìØ¯0TxÔÔÔìØ±¿Á£££ƒö½ÃÂÂòòò@jøX½zõÙ³gYÆ!Rnþ:444ÈÊÊgb*++SPPÀç†}>|H¡PØK¶‘“4:::Øtuuýì]y<UÛûÞæy K¦T¨‹¤9¥yÒ<h”F*Jº Ê(¢ˆ•Û•Ì’DQf•Ræ!dž§Ã9Îq†ßïç»>û³‡ÜrËÏókï³×^k¯ñ]ïû<S¦LÕ+ ü¼¼PsZ¿~ýµk×`Y\\Ìd2‹ &44´¤¤äĉøÏª¤¤ôËÎ7P½ø¥!4­¦¦æ§Î7ß=å¬[·ŽL&ƒ!hëÖ­°Y9}úô•+W ñìÙ³ ðµk׮Çëéé…„„ìØ±Ø~"""DEEÑqVkk+4w„5µ Ü‹/noo‡'¯^½–á‡vuu…D+++0tܸqãäÉ“VVVð7øÆ �óæÍkkkƒ‡/_¾üôéÓ†ùøø0™Ìýû÷ïÞ½ÛÑÑ‚xlmmMLLðk1ðTÏ¢øøø¥K—’H$...X_KII=yòž¬ªª€a˜®®î¢E‹ qîܹp�cffvÿþ}H477€ >##câĉ,KLL ¼àTTTœá™ºººà¸ñêÕ«—/_:;;¯]»}Ö-[¶8p@LL ™ÔDEEGŽ),,Œ7€ðóó+++Ã’?!!aáÂ…<<<>|À0LZZúï¿ÿ†ª««Ã±óÔ©S[ZZ ÑÄÄ õ½ˆ]»vmKK †a )ÙÑѱtéÒ„„999ÈE[[ûþýûBBB¨uÉÈȈ‹‹ƒ²Üž={nݺw<x´«¯^½zæÌMpvv#‡‡ÇŽ;ÀR vÅôôtø­´´4Þ¯ÿpttôðð€¿¯_¿¾páÂÛ·o=z|ǽ¼¼ÐkÏš5 ‘„öfk200°°°€Wš3g üjkkc2™ÿÞÈ#**úöí[7,Z´ˆD"Á ¬Zµ B£nݺ%((þ÷šššÈ*‹_œá›Srr²±±1…BáççOKK´±8--mÚ´i4MHHH䪫«÷ìÙóüùó & Fedd„œýH$Rww74§?ëµk×Ðû‹àÍ›7K–,!‘HÜÜÜÐ[[ZZÖ­[•………PL ÃfΜ‰<úQèC¢F£Q(¼¿…BdÔzH$,X$$$À¡¾µµUDDÆßææf8”‘‘Á/ÖX,VSSÁDÖÝÝÝÙÙ‰– ]]]p`+,,Œâu:::À ..Žø_ÛÚÚÀÚ.%%E Kâ ÑF§ÓI$¾CR©TpE$Ed2™ÅbAaÙKŠßˆ‰‰!ÃKcc#“ÉÄË\2™L80àååE:Fƒ3-AAA4“Édðå%XºQÿÇK´577KHHà † ,‹››U/N‡s/~~~¨^*•J¥R!Ó?+ ½½]@@€PXBŽ ËÇLJª·ÇÂ8K´á›>GØÚƒÁhjj"dšSww7²*tvv‚Û›˜˜Z=ôØØÛ0‹Å‚Í(aÐA¦E¼D…Ba0ìm5QÔqÀ*0bÄhKMMMhYНaƒÑÖÖ†?lë±z ùrþ¬466JKK£^ChëîîîèèÀ×0{oíììäââ‚6L"‘øøøz$l&4'h½½IÄþXà%Úùâk¸»»–8h<$4'Ÿu0Ah#ŒK콕Éd¶´´HKK£ŽƒÖ’’’?\¢­]???!öXHHˆÝÌ*&&F0â·–½¹mpqq±ÉðññáÛ#©¸¨¨({bןî×.——0* ˆËðƒ>{IÏa/777;%???{"aKÑ'Øk˜½¯òòò2Â8=~VÔ'ûÌñß¶?`·TrÄ·%žÞr!4'öùµ·†Ä^Ã\\\ßUBõö؆{,ió“ðV=Vïw}VΕÌÞU mž½·â«—Ë$¡ ƒ0ÓôB¾øæããc¯[öòööYÿC°op Ÿ•››Ú‡Žó1̱6Œa cÃ$ O9ÃÆ0†1ŒAB¯z9¿Úöðß�Lᢢ¢CI¢ Øe†Ògb2™BBBC¬áñññ ¥ÀÄkupR;dTAapø] qDýÄ)§¡¡ÁÇÇg(M­t:ÝÇÇg(M9t:=,,lÀ¾³¿ìÊ ==}( gL&È܆ º»»‡ØàÐÝÝýðáÃ!68”——ÿ¨ÁA^^¹±ý¬)gĈà±64�kfffCI¢ ï±6ÀÙcíwÁcm€à±64€÷X%"x¬ýûf<,Ñ6Œa cÃø-ч“4„kà—Ò$ Â;$$$CgSSØûdee{óî­¬¬TPP�×{<¥.š©TjKK >F¬³³Â;ðÁ‰†577óññáÝ.ëëë!bF^^¾ÿ ÖÔÔ„§Ÿ"“Éo!**ÊîŸÚÜÜ ñ+222È´¶¶"9!’£²²K1zôh&“ ñ°�~~~”)…Béèè@š¨†RRR}ú³VUUÉÉÉá]y0Xª««1 è"¡­­ÅbÁgE%à¿lMM´´4Þ{¾¢¢¢dð¡Ët:½¾¾O B¡P@ñADDä»(‹jkk¥¤¤ðŸÕðèÑ£ ›×KÊþYÛÚÚˆaÒÒÒ¢¢¢©ƒL (Óªª*yyy;‚oü¼¼ì´LH$:Ž÷Xí±-ÕÕÕuuua¦  €¯áòòòQ£FAI{kK]]]À"!,,ŒšS{{;”HJJ"ÿïþtXø¬ÊÊʽÙ½Õ0Ú=ôXXÀÈ‘#Á{›½ï@a!>‰Ô 8äK¥R”OHH‡È‚ ÛÒÒ‚ˆ_û¬ÞÁA?{+aC#((øÃ¹Eú˜rººº***ÒÓÓ###Al[[Ûßÿ š•kÖ¬Ù»wïˆ#®_¿ŽTAW­ZÅëPVV¶páÂÔÔTèí7n„23 –••E£Ñ¾}û–}÷î]D©M"‘‚‚‚*èáÇeddšššš››¯_¿nhhˆä«««ÏŸ?ÿùóg ÃìííçÎÛç¬ÓÝÝ]VVVTTtíÚ5xy˜áBCCAÜÐÄÄäøñãxWý††777¤ ºfÍQQѪª*[[[`®trrš9s&ßüùóEEEÁ–ÊÏÏŸ””ÔÒÒ2yòdO>~üø‡R(”ÊÊÊÄÄÄ·oß"%Ð/^� VVVxù5öNB¥Rׯ_ŽPqqñ–-[@ôîÝ»jjjÝÝÝIII  :nܸ+W®°‘­­­..."""{ÿàÁôÝkjj¼½½—.]ZYYI¡PvîÜéííÌ»%%%»víUP??? ƒQRRRYYikk‹ÈÉdrTTR=uêTÚtuuuggç¾}û®^½ŠbÐJKK÷îÝ »=“Mtww§¤¤ UPGGGeeåÎÎΰ°0PCŸõÞ½{žžžhsæÌ™U«V>}:%%»Þ»wOWW÷Û·o4ÍÔÔ4..°ˆÞ›Á`Ðéth{=¢½½½®®.00L&Á†a7nÜ�ÚKKËuëÖA[²³³Cª ³fÍâçç/--¥ÓésçÎ-..†#îöövÄ“¯¥¥åççG¡P¢££‘*è™3gäååÛÚÚ>|Ú ëׯ߽{·””T}}½‹‹ ˆ¾XYY­\¹’½ÃB¦&&&070™Ìoß¾ë3ôV}B,é111GŽAõ³mÛ6<Ëν{÷QsºwïÞÂ… Ϩ¯]»6mÚ4^^Þ¯_¿‚�ߣG~¿$ œª ¾¾¾ø|©Tj\\R½pá‚‚‚B{{û“'O@´tÅŠ–––ÒÒÒ®®®Ož<Akñ+W®àuùUUUd2y×®]·nÝBlž%%%¢ûøñc¼#FKLLDª }.¤~ä”S\\¼ÿþŽŽ| ûöíÈô:99=xðàøñã×®]ÓÒÒ‚¶¾sçÎ#FàáQ'OžÄ¯(ab0ïÞ½ƒáµªªÊÜÜœB¡ààÀ Ù<å… BBB>|X[[‹'Öõðð°°°�‘ùóç+))±#444@ËÆ‡þ½}ûöõë×£¯¯ïµk×ÑU777UUU¸jaa1bĈåË—:tÈÚÚ„„·mÛ¦©© ›¶ØØXB–¬¬,ü!??”Iñ¢¼6l�·úúú;wîpÞ ØÛÛççç(½gΜYSSLÒÓ¦MËÏÏ///·³³ƒÜSRR:D`¡onnöóó BücÇîËÊÊJgggØi9;;gdd”––â{ôèÑÈÈHQQQƒ1jÔ¨êêêöövsss†?ÀÌËËKKKƒwxúôéåË—/¸ºº¦¦¦r\¹råëׯa±)''‡'ˆjÈ%==ÝÒÒ2"""!!!66ÃÃÃ?~|ìØ1 ÃöìÙÓ0NNN„ƒÌ?ÿü³¤¤„@5 Oc0ééé@AÛ’““š››×¬Yƒ&MšÒ {÷î•’’255=zôèÑ£GAdeæÌ™¾¾¾šššÇohh@tdhOFhK………oß¾…ÄÐÐÐ .ܾ};((¨¶¶üüüŽ9âä䤧§sÿÖ­[eddØuÕNœ8Q__¤ïèèX¼xñׯ_a΀ÞJ8J\²d >'ÀÚÚÖ•••NNN0©;::ÚÙÙpÆäÉ“CCCA*0++KDD„J¥jjjâeì*æÎ[TTmººº  Šv´aaaP111666~~~QQQ999ø÷߇……¯Ï‰'zÓ d8;;øð_ ÃŽ;!&&Æd2•””ð‡4555~~~P¢ÄÄÄ£G Þ”£££“””oC222ˆòºŸ;/33³ÀÀ@Â<›˜;w‚@€ªªjRRÒ‡ðbõ&&&°Fhll¤Ñh`¢Ù³gÏž={`*F€ ¯¸¸˜D")++÷‡†VQQ1)));;ûèÑ£(¬…P@ …B8SRRêêê‚«ø¹ª°°°³³$Š!%++ ì~zzzh¿‚‰\OO/)))::/¥Œàëë+$$´iÓ&¥€EÖ~Ò¤IÀÄ…˜ÓúDHHH}}ýþýû C†a—.]Z²d hœ þ¤øùóg %“’’JJJ*--©D€A[[[III{{{?m&ÎÎΆ”l´µµóóóAÌqÝ#+“ššÔsuu5~º™úúú¦¦¦È^w*++£ílii)$jjjÂÈ"~„ŒÐ¾ßÂÂ"//C–,Y²dÉ’;wîàmqH‡©¼¼\\\œ$,6:/)((8~üxx=77·ööö¯_¿¶¶¶þKrFàEÅ«ððð eœŠŠJRRÒÇ j­ÍÍÍðV²²²½]Ÿ?~õêÕ°D¥‚‚2™¬¦¦Æ]]Ýììl~~~:ŽÖæÿ-ÆŽëííÝÑÑQTTÔØØˆö—04UTTÌ›7+++¡TTTþ[½à‚#¬'@èóçÏ ƒÐ¤UTT<x@&“ jkkÒþòûh= KJJ`¸766OÎÈÊÊ;v,»™‹Édfff‚¨eŸÛ‘€€�AAAvÅ'öñ733sïÞ½&`Ÿ0a‚®®.ÐÐР¼´lÙ²{÷îÁÕõë×#Y³ÜÜÜ´´´ÊÊʃ.X°@PPPOO‰_ºtÉÐÐO]]~+''gmmÍy2€ÓˆäòåˑПþÙçýp 6zôhöù¦¤¤DBB¢7Î<Þ¿ñâÅÞÄèrss/^¼8iÒ¤³<}úôåË—á4„‹FŒ±mÛ6(þèÑ£éFà  àààÉ“'ïÙ³GEEEQQ1&&î\¶lÙÆGŽ©¡¡ºUæææË–-ãÜ�2hI1�”––úøø,[¶ì»¼Úxyy555áÍeeeO:…ÚR~~þ¹sçttt€´G¨ªª’H$pFï¿Ü”   a‚!@ZZšD"Á[M:u×®]쫊¯_¿JIIvÿÅÅÅGŽy÷ܹs/^¤Ñh¼¼¼ý—B”––ÚÚÚŽ; ëëëýýýŸ?>sæÌ;w*++=:((¨f×®]Ûñ½ÿçÏŸ§R©=ê~‚=\UU,ÿñ”óâÅ‹ŠŠ atrrzòä gÝ‘ÌÌLGGGöóê®®.sss‚Á¤ÇÑ000——·?#ÁæÏŸ¯©©ÉnXKJJ‚?øøø¸/©©©‰‰‰P@___///¼aÍÇÇGUU(-,,äää€ÇÚÏÏÏÇÇGKKkúôé&LPWWG»ƪ­­G╹¹¹ŽçÞ�ç(œ·8½aÅŠÃZŸ5ÌÇÇ·oß>D‘‹·kÍš5«O=ÝÔÔTggçþ8N›6-::úéÓ§®®®ì†µ’’D,8nܸ޸¶¶mÛÖ›a­¶¶öâŋȰvêÔ)x«¼¼¼9sæDGG£ÏºiÓ&T½666/^¼Ø±cÇéÓ§>ðåË—«©©qF£P(`kØáÁƒLLLú³tÃCTTµ¥üüü}ûö!Žç)S¦DGG‡††:;;÷F|èÐ!ì YYYÈîm``Ðã‰wggç¦M›8vÖ¬Yè­¼½½ïÞ½ËNîââ²`Á‚3fàa¯3yòd]]ÝQ£F­_¿þ?1¬õ ]]Ýèè蘘{{{???ß Q¹¹¹ùùùÙÚÚîÞ½­S÷íÛ'++»jÕª_pÊ c7¬¡-]tttbb¢Ý Ö~Ž?¾uëÖ‚‚‚‚‚*•š°bÅ ¼cgÔÕÕ…„„pssïß¿Ÿó_¾|QRRâ¼wwwqqñÞ¦œáÊ•+•—¤¤$###<óqwwwzz:‰ûÿ qqqoÞ¼Ù¿ÿëׯ¿~ýJ¥RËÊÊzÔ…ì ‰‰‰^^^Ož<ázÖÒÒR^^Þ£y áíÛ·hbeeõég̘×5Á0¬¬¬ŒÅb!‡@NNÎÈ‘#V²¸¸øñãdzfÍ€Œ:NOKK#´¥ÖÖÖÒÒÒ~n¹> KuÐE ÉÊÊBÖ˜9YÕ××744 ­ðñãGuuõò&H$RAA;ƒòÂ… CSqq±€€ÀÑúIHJJš:ujƒ0™LÎÊʘØù¯2åLŸ>IÄ“ÉäÇ/^¼˜———ÅbÅÅÅõÙÙRRR>þÜ͆«W¯îرƒý§OŸZ(èîÝ»SSSñ„ööö½{÷‚3R¶ð ñ󠤤ÄËË gBoff&L9999’’’}÷víÚ•‘‘A`ïqYpëÖ­§OŸr¸ÇÜÜ|ÐBACBBº»» î®®®¦¦¦ý‰ƒf2™ñññöGzøð¡²²òÂ… ðÛŽŽ ‚Jznn®³³3Á+¤GäääHHHàÏZð¨FJJÊ‹/zsÀ0,;;[ZZðçŸ^¸paÀÛƒ†’’’3gÎÄÄÄôyç£G”””~÷aaa‘žžÞãÙaUUÕ‰'5è—˜rTTT¾}û†ì'à1©££ÓØØ‰ŠŠŠ`CKII7nr Å0l„ ÞÞÞp°Ï`0öíÛÇ¿œQYY‰²ÓÐÐèm<244,--…;uuu¼n’——WTT„ç´µµu®°°ÅbiiiéèèÔÖÖÂUè<Ó§OÏÏÏw&0ý/Z´èõë×üüü, Œoüüü³gÏFOæl»þüyWW×€c¼—/_ÁÅÅE£Ñ@!JTTÔÀÀ�roll„ÃÛšššêêj¼ÝÌÍÍB¡ SÀ½{÷ôõõû³3‹ŠŠ‚¥1á¨AVVVUUÞ¡¾¾ï¤÷½X°`Á›7oÀS²£Óé¯^½Z¼x±°°ð”)S —¦¦&()á³Âɇ¦¦fnn.$ŠŠŠÂy»jrãÆã lF§Ó---ññ1ß‹ììlÔ¶'Ož¬¨¨8uêÔÂÂB£Ñ××ïí‰ÏØØ~ÛÞÞmIZZZCCkjjà”t̘1555ÈÍÍ ‹˜>´µµÁªbÔ¨Qýtâååå¬6¦¨¨8räHÈ«³³¶;ùùù<<<0PܹsgÚ´iÓ¦MC?™9sfNNØvŒŒŒ  -Y²äåË—¼¼¼ céÒ¥ƒ6/]º4**Ї‡‡N§ƒ¯…BIII111‘””ÔÖÖFu;eʨºüü|Hìîî‡ mmíªª*H9r䀕-ZôêÕ+š ïÐh´7oÞ,\¸PTTT__^¾¡¡áÇš‚ú;åÈÉÉá ¯ÆÆÆ, DW¬X‹Á­[·þý÷ßà¶´ÿ~ØÚ§¦¦Ž9t¶|ùr´æââZ½z5{vÒÒÒÆÆÆè_eeeäµxñb4åüñÇø®rôèQwww¸óÌ™3ý “À/Tõõõ™L&¬ÔæÌ™³eË ÃŠŠŠ`ÊÙ¼yó?ÿü¹ìÝ»×ÀÀ�Ã0kkkgggÒ¾xñ"¼Õ7Ž;Îï°stt?Qeeeü¹¨‚‚¾‚9Ø'/^Œ­¸{÷îÞ½{¬|Ìääälmma1;vìXxÚÚÚŒŒ (`ܸqxÕp}}}‚Ý `bb‚ŸÔW¬X›øùùÑ”#**Š_ÅO˜0aÛ¶mð>S§NÒ~ÂØØo5½~ýúÉ“'!.N»»»cbb/^,++{öìYpšÐÐЀƒ===&“ Ûå9sæ€5iÅŠ, ¾¦™™4¼xyyA¢µµ5~£¹dɼ'$77÷w™é544ð•6qâĘ˜Ô¶•””Ož<yíÚ5!8þ<~C`jjŠ¢PEDDœÁN¨¨¨G&ZZZ»víwmCCCðµ111a±X A»jÕ*ÁwìØñðáCÈúàÁƒ¼Âð™ ÎÞFŒï­S¦La±XÐÚMLL6nÜË5~Ôµ{]�� �IDAT~~˜r ~t¶¶¶W®\ ÎË—/Ã'¾uëÖ¡C‡¨T*ßÏP¥ì ·oß¶´´ìîî�mx2™ Y•ǃ[ìĉÁ&9cÆ &“ ÞŒK–,mãÆOž<ºÝ½{7LNÿ-æÍ›‡ßÓ¸»»†&*•úêÕ«… *((ØØØ€?θqã@…ù‡£UСª ¿)†9Ö~} s¬ýæXë³ÿXUÐa޵a cÃÆ axÊÆ0†1Œa x{ÛA™m&‚€€À1¬!ö¶!ó™Àk“——wÈ”NAxxx†L‰¸¸¸ètú`LJ] >>¾R"à]ý¹SNWWWvvöPšo˜LfvvöPRa"‘H_¿~Ås÷þ©áççJߨ©©©µµu(u%*•J£Ñ†Øà@£ÑòòòðQt¿;Z[[¿}û†ç´þ7àããû|ؼ½ Ðßå1õëïo0 '¡Q"ðqìêêBEC`—Ãb±h4ÚixÜÜÜL&“Á` ™qqqqqq ÉÁL&÷?Dý ?ä3ñððüØA¦çZú7a¿$$$222þøã¡ä±V]]­©©9ì±ö+÷üšššîîî!Ó•Àc­¨¨h( âââ999ºººCÉc­¹¹yXtÃÆ0†ñÿ}ì%‹ŠŠ’““wî܉RRRRÂÃÃ1 ›?>"˜ bÚ­[·ö&TãààpìØ1ˆX<}ú4Ða&)) ì³ÕÕÕ'¨¡¡±gÏ Ã>þ a§�cccˆ ŽŠŠÃuëÖáÙ2îܹ3þü£{CMMMpp0^íË—/?Æ0lêÔ©ìñªaaaõifftawïÞ-**B7X[[ËÈÈ\¾|i òòò…b{{;ü!//ŽYYYÙÙÙˆê?!!tê/^ÜÎG—]»váoÇEXXq™ÔÕÕAœ ªªjoœuoÞ¼¡Ñh¿1z€;vÀþÃËË«¬¬ ð'NÀëÒ¥K@ê k" œhmm…Ð9EEE¼<DNNNff&ÄØö·oß^ºt)>ÂÕð•+WÜn ¤¢¢bii‰aXnn.RÀÃ0lÆŒ+W®Œ‹‹…4ÀÚµk!pÏÏÏÎ*öíÛ‡§©‡L?vmƒqæÌ ÃÄÄÄΞ=ÛgRRRš››Š€jxÓ¦MˆÍÇǨ3;†=þüŸþ Æ …‚%†.--ÅNêëëC0fRRD&.\¸E=#¶ãíÛ·s`E»pá‚]o‡‘‘‘ˆ²uÀœ9sðܨã�ÌÍÍ‘—»»ûÆÙIììì ¿ ãßàÖ­[«W¯fçA8sæ b»'tÀرc¿+^ûßîrÊÊʬ¬¬Îž=‹Øa1 KMM?~üøñã?~üøêÕ+˜oJKK!188¸Ç£ÅË—/{zz‚Â.†aãÿeee˜TjkkoÞ¼ ‰T*BÊKJJ>~üˆn†.***;;R¢££?|ø€aØýû÷­¬¬\]] be�‚›§OŸÆÓRegg‡††ÂÃKJJŒUaaaÅÅÅp5,,ìË—/†=½aDD„Äkjj¢Ä{÷îaÖÙÙyùòeH‹zåääœ?>..þMLLLJJ‚;ÓÒÒ@½±7\¿~ÝÊÊêæÍ›x•_kkkT½0倞)$2Œƒºß¾}{ùò匌 øW^^áÝ»w0Íxzz2™LH¼~ý:°>?zôh̘1ã‰Dú믿 …ŸŸßÕÕðÂÂB++«sçÎ!ª‚þàÎ;VVVnnn ` °··G¯L øÏzíÚ5¸Äb±<==aV@eiiiIIIÁ0LFF%æææ‚柟_ss3$úúúB©—.]òòòBmU²œœ\$ðïß¿·²²²··G©0ßž={¢¢ÞÞÞ4 ÝÝÝ¡È.\°²²òòò¢Óéð[*•êïï^ÖX555oÞ¼A‰0Ä$'''$$@Êû÷ï¡•——Cb```b?/^$dJ¡PÎ;‡–/VVVgΜÁs‡—””dddz+¾9¥¥¥?ôÍ›7­¬¬ÜÝÝÙ5Nž< g†———••Õ7ê‚°$õññ!$òóó£oÄËËÛ§ÉÞ刊Šæååá—ð………mmm ›áääôåË—ùóç¿{÷NKK vB;w¨ (ÁØÛÛ+++ãiAz’L&ÛÙÙAwmmmMNN†Y÷Í›7žžž°ÑQWWÇï±0 SVV3f ¬¸>\RR2yòd AAAü2ªOVVVVVV¢Äòòò²²2¦}}}ÓÓÓñ÷ïß«ªªÂûXXX”——Oœ8qº8::¢…?,01 ;rä(tuuEFF‚#ˆ€îC^^Þ“'OÔÕÕ{|^^ˆ=Ã0—§!`„ òòò„Æáçç‡/¸xñb{{ûÛ·oaÛ‘’’âììLØè$$$$%%á¿S¦LUÿƒV¯^ ´(/_¾´µµò%##£ýû÷IÉ–-[@6íu¦OŸ|0YYYVVVVVVââↆ†üüüßåe§©©)""B  Ä‹\»v ]êè舋‹ɉôôtKKËQ£FA}¦¥¥UTTÀê{âĉP¨ccc vzûö-¢õ\¾|yCCp‘]¼xqôèÑøõþãÇaÝP[[»hÑ"ºDÒÒÒ†††x…M ÃF¥¥¥ä{÷î-++›4iRll,^t×®]#GŽœ4i…BA¢à�!!!B¿€í!1??¿££²³³çÍ›—ššª§§¬?[·n­¬¬‘7<&MšD&“ñ¬ÝÝÝOž<m‡¡¡á·oßð¿bï­S§N…fsÿþýuëÖÁÖjܸq#FŒ`_‚?~\__ô³‡1`hiiIHH°¯Y­­­'NœÈ~°-!!Ÿ¯¤¤¤°°©Ò”###cffŸrfÏžÝÔÔ„&ƒ~’îEFFâ·l�KàÞ––ÙÍŸ?Æq&^½z¥££íxöìÙ†qf)fŸSÍÌ̲³³ñÖ•?þø£¤¤r5jA®fÆ pUOO@íååJ îîîüoŠ©©©)..Þ¼y3¢Ûš7o^XXÜ©©©É™lxñâņêÐÓÓ(¶øøøØ«½G’Éä?þøƒ]¥-55uÉ’%œ"9ÂÇÇÇÍÍ ôt‚‚‚«V­jhh8s挘˜ äååÍÌÌ$$$‚ƒƒûÿ™`ºÅ[l`¹cooá ¶‚o·„Ú“””$|ýúµ¥¥O+‡aØÇUTT€NmÏž=Ïž=ƒÅûÊ•+‘a-22288V �ÈE@@�æòÞ ¦¦¦¦¦ÖÙÙ‰WEçÁƒººº„WÂ=ÜöövÈ]QQ‰ÔåææB"âXë[¶lAÍxúôé=ZÂa¹�Mrhj733ûøñ#aÊA½ÕÄĤ7©§äääÕ«W+))A§["áž§OŸ:::þ$ޝÿ?˜7o, éAAA/^äP½ ÙÙÙ³Û åðíÛ·ŽŽXÂd{ÃÙ³g=Ê.@B¥R­­­a8Æ0LIIÉÂÂv?pä3eʤòTTTôôéÓ 6À¿ÚÚÚBBB•••ý'ñìµµµ555PÀ’’’œœ¼sNnn®¨¨(\}÷î]mm-ôØŽìÚµ‹0.ïÛ·q¹Óh´ÄÄDøm[[[bb¢‰‰I~~~ttô±cÇð"ceee]]]pgvvvIIÉØ±c¿«QQQ+V¬�&騨XüùAxûömuuõæÍ›ÁRŠÇ½{÷tuu;á©S§½¼¼`²Dƒ/2™Ì½{÷¢DXXxÅŠ­­­IIIÐú^½z5{öl`’ [¿~=ºD&“ß¿µ×ÔÔ”ššŠ(ÎRSS ¡á7LRRRHGããÇJJJPÞ„„„––iii;;»cÇŽÉÈÈàøâÅ ˜ (ÊëׯÆyüàÁƒööö5kÖ|—s‘ˆˆjWíííçγ··×ÒÒÑn Ã*++}||z›u²²²FŒTÓ©©©õõõì Šì�âTL¦S¦LAÆââ �´×Ç›Iõõõ9̯†<xÐÝÝ}Èxÿÿj8r䈳³3÷¼ÒÒÒ€€�$TøKL9+W®DSNŸó¶¶öÊ•+Ù#‰ Æ«W¯àÌþ«V­SIVVœm*))¡1ÝËË /6££££££‹7‹qÆ–-[ÀgABB¢7†ÚÚÚÚêêj( ¯¯/Ò­B'=ªªªp5<<ï8˜˜˜¸råJÂçùóçh N£Ñ ßÜÜÜû÷ïz{{oÙ²eòäÉ›8•J…\>þ\\\ü½522òÎ;`Xëód;11ñõë×›6mš0aû”“™™9kÖ,tö8}útnnn°¢SØiÁ7…ãz42®\¹2++ ØvûƒG¡­À‘#GÛ±±±§OŸ†ÖËjü”óîÝ;¨öôôtüi\eeeSSA#.//OZZ¹œddd ÚOKK‹ŽŽ{ŽŠŠ‚õcmmíÀÖƒ>À|›Wh`:ƒN$--CCCñ{w@<n~úôi]]ØÜઋ‹ êtxÐétÏ„ýzooö{>~ü¸`Á¼[X¼xñòåË9Ëý c`8|øð¼yó–/_ÎaFommÍÍÍÕÿ~Êù^¤¤¤|øð )ÍÍÍæææOž<é-U\\/AAA˜r’““?~üˆ”Æþþþ¦¦¦ßû2Èû¢O1±ÁAkkkxx8®Ô×××××ß¼yï;78¨ªª †é¼¬¬ŒÉdŽ;–U0RÑ@¾p»víºyó&þ³¶µµÙØØpPëâðpäIðû¯œœœ‘‘m¸¥¥Ú0^Å``xôèQKKËúõë{ß9£££ãرcÀ<ß‚LlméÒ¥è³ö(ÞÕ¤¦¦¾{÷ï8�ÄÇÇWWWûùù±X¬îîîmÛ¶äó0~Þ¼ySVVfj:¾yófÿA~‡Ÿ;å\¿~yReffîÛ·6t cÛ¶mxèòòòëׯÃI;B}}=ûZ©¤¤„°™è¿eó'…‚ÚÚÚZXX¨««ãÍÌÌ=zÄ!¤yܸqÈs7%%%55u`‘ÿÞà‹F½àà`*•ŠÌhžžžãÇÇ;/œ={ÖÌÌŒ­™˜˜ˆüšÐ–ï`ÝŒ;ö'…‚&''øðáÈ‘#øÄþùGXX˜³ì««+rÿôéÓ¾}û~È’¥¨¨HYYy�ó ‰‰‰ì+˜ÌÌ̽L?å«9£®®Ž³èíÍ›7'Mš„ô�{Ûù!ŦÄÄDü¦yÿ÷îÝC„ioß¾e_à–••yyy999ý*SÎ’%KÚÛÛa/bll '„¸sç$nܸ–K§NÚ±cþ „ŸŸêÔ©°¡c±Xiiix³‰¬¬¬±±1<DMM ŒÂ³gÏnhh€ÄiÓ¦Á6eÇŽ¾¾¾hjjúc ¦M›V[[ 744„˜&“¹eË–½{÷Þ»w®®_¿í=¿|ù²fÍ‚†cZZX·à_ wwwø­œœœ‡‡‡¸¸8ê~---ÅÅÅpfcjjúÏ?ÿÀóçÏ€6ɳgÏ €IHHæu%%%[[[x¦ŠŠ wƒ­­­-ògÍÈÈ P(H¹½¸¸X__ïíºeËWWWðp=wîXH¶oßÞÕÕÅÍÍ 1[’’’ׯ_‡ìäåå!ÜêÂÏÏÏÒÒf‚°°0°§™››ÈËËŸ?²=z4ê<---„S±òòrü¸úôiOOOPè277?~<þ³âÛphh(ä"&&†úé?¼¼¼ÝÏÎÎnÖ¬YnnnàfccÓ›ÁMTTÔÓÓr—••…·ÕÕÕݰa$êèè€ïøòåËýýý!qÞ¼ypèuøðaHܼys?u EDD^sà{ëÔ©SwïÞ _J@@�Ž`‹ŠŠ¦M›Æ~¬‹‡‘‘üÁb±¸¹¹{³¬c`ÀKÆqssƒ—f[[›¥¥%l}:;;‹‹‹ Æç‹>$ÚH$RCCÞÄÑÐÐ�Ç'òòòÈ&[QQ®ßªªª°1/..VPPÀKUfgg7Vý,ëË—/„‚Q(”üü|èÃH±¹¹Œû#GŽDCCuu5œ·=/Y\\,//Ï.ßËA¢B¡”——ƒ¯*Z-–––b&##ƒ/ÄúÀkee%øøŽ3©)**â óŽŽÞ$ÝÝÝ s!!!‚ÛEkkkkk+øãÂöTº{Ô &H´åææjhhàWߟ>}Â0Œ‡‡i>vuuA†¨¨(¨42……*“ÉÄVaaa| cVXXÜMãLJ|(,ƒÁàââB‹ ;TBaÛÚÚZZZð™8Þ°×pvvvww7†aÀcÄ`0rssÁù •TDDÍ1ì…Å0¬¦¦†›››PÃ¥¥¥pX¥©©IhK„6 » >>>BT�€ ÑÖÐÐ@£ÑP®ªªÂGá;Ƈ7ßšjK‚‚‚ÈÅ™D"ÁÉŸ””{[RPP@nåååS¥¦¦ÆAµ)A¢L&WVVâgqÔ[eeea¾Ä×pyy¹¨¨(>`PPP ¢¢‚ÚBffæ 0ë y‰¶ÂÂÂQ£F±›‚QõÒéôüü|hÃìãá—hVý-1¬ úëcXô·À°*hŸÍxXtÃÆ0†ñ[bxÊÆ0†1Œa zvàááÁó— ƒ�ì ‡˜*¨ˆˆÈùLði‡X‰øøø†RW"“ÉÜÜÜC©DЕÄÄÄØ“~ë†',,üC>òØü‰SNcc# Ò Óé„8†ßT*5""b(EÌuwwsqqAHÖÐ�ƒÁ`0C©+±X,ĺ;dÐÕÕõèÑ£¡$GK£Ñ*++Ôà ''÷OX{žr$%%QHù€„„Ä;wV­Z5dZ•ˆˆHTT”¶¶6…å÷…  à§OŸ¸¹¹ñÞ2¿5øøøêêêòòòÀuhl¸¹¹CBBËÀ€¸¸¸ŸŸßâÅ‹‡Œû€°°ðëׯUTTØ ÖŒY,;õžr¸¸¸~‘ý( ??ÿ™r¸¸¸xyy‡Ìgâçççáááææ2%âãããååJ%µ¡78@‰†L¡¸¹¹Ôà�k?ðõxûÜG3™L<!“É„7€%!Zd¢ÓéøP|¯ŽY,ƒÁ@-›Øcv(‘Á` Í7ίÑg{Ì‘½øø,Pî(‘Êé=ŸØc%s6àpssã‹ÜÏêe/ö?ëvÿ Ûcvì…E/€_2÷³™ö§€ì_sCB¥#¼OD‰œÛ0êö»ª—C÷AÅì±z{+c:,{¦œûNŸß÷ß”wpð]ª·òö³n „¾ÓÛÐÄyTü‘{e=„L&¿|ù/à'"******W¯^…X<fmm ‰¡¡¡øÏ€@¡Ptuu!ú ðööv¸ßÀÀ�Øò™LfFF$nÚ´ X †¿¿?$þùçŸ]ww·½½=$úùùA îØ±CYYYåàL¼ª•L&gddàif FHH<ÄÆÆqo�º»»mmmájPP””J¥®]»¿|ùýÇÐн xdzX¬²²2HY°`(}1™ÌØØXH<xð dG§Óoݺ‰nnn„&B@WW™L622F��™L3fŒŠŠÊĉ¡z!öž¹víZDzAèo×®]Cáú4ÍÆÆ~‚ »zõjHÌÎΆÂR(555”Ýׯ_á¶E‹AaäååQµ¤Õz•J%“ÉË–-C,¢£<§½½ðYsrràÒªU«PC EùB=ß¼y½Œ‚‚pyÑh´={ö@âÛ·oaìèêêš={6$VWWCFmmmbhhÈ®ø@¨X2™ìåå…$Π-ÙÙÙÁPõnذ333!w …B&“ÕÔÔ:\kkëÈ‘#Ñˉõ»wïPŠ’’PÅøúú*(( t`•¥ÑhLJ”gÏžõÖaÉd²††*‹ÅBÃàššŠ')ÇçE :¥Ñh'Nœ€Kááᨼ+W®„ļ¼<ÔœÈdòÀ¨€þ (Ц¦¦ŠŠÊøñã ”Éd¦¦¦Â{nß¾U@@�¾¼ žÔÝÝ}öìYÂgý¯�}gáÂ…xzbmmíÑ£GÃöHQÏd2Ø‘ú”“™™©­­ ¬?...®ªªªªªâââòððÀ0ìܹs:::Cx‰DZ°`>ÖZSSî†ÂÂÂ'N@âÁƒ·mÛ†aXDDDBB$ª««ƒ\ÇÕ«WGŒ‰>| gúùùUý´u***´µµ×¬YƒO|ùòedd$z~ŒÀ0ìÂ… èÍ£££AmÓ¦M666hccÑן>}‚”œœˆînnn^ºt)$Þ¼yiRRR¼½½!qþüù NýøñãöövHììììô°aÃmmm K@PSS«¨¨¨ªªJNNú¬’’’ —d×2¡R©·o߯k•ž;wN[[~ ,Â6l8sæ $îÞ½ ;qâÄwïÞUUU•––%~cc£©©)Üæêꊦyóæ¡o„×Uã€hkkãç æL™ Ï&„òòò]»vÁ¥³gÏÅKLLLDD$ÀhxäÈH)..¶°°�+„¥¥åêÕ«!ÝÅÅò511yøð!$Κ5 x !åÅ‹ˆ³G„‡‡kkk4•µ´´à qqq‘‘‘†mÙ²åØ±cxøðaP¤ž;w®¶¶6ÁkHVVÕ$|###ø·¬¬ÌÃñ¬îÙ³Ý óÐ¥K—¦OŸ)OŸ>Er´x˜˜˜hkkã§s‰„èBJJJ´µµÙµ Ö¬Yƒò"P˜ÛÙÙéé顾BòkÖ¬¹pá$nß¾hM¦OŸ®­­ ëËÁ„––V~~~UU }øKYYYè=wìØFE333T^Ÿ¹té’ŠŠ ¤ÄÇÇ#¬ÿÚÚÚ 8‹Gnn.¼aII û–(-- äû~zݺêëë—––ÆÇÇãù€…„„xxxÐäÑ'4{ó „AuxHss3O¥Ç…|{{û† €}DDD„ÉdÂÏùøøÐ¡_[[$JIIõ¦ÖŽÇèÑ£KKK³³³ñÜ·ð:Nà¥ÓépîD—ZZZº»»Ÿ?Nبjii777·””ü¶½½ö ºtvvrqqq®dP= ÐdÉÊÊ+‰Dê³zÑ„]SSsêÔ)´¾ë­°=r¦|aI$b¢R©Øgèû÷ïc¶lÙ2|¢´´4’.&pvqssKHH@.x^dhH+V¬ |VuuõÍ›7c&..ÞÕÕ?á`Û),,„%!hêp(ÂÚµk×®]{çμDR?#‘Hüüüªä«UTTKQxI^^^B[Љ‰‰ŽŽ†zƒÅ;Ü)** m ©Ú´·· ö˜5huãù¸¸¸P1544JKK?~üÁø†¼„……Ùy§ Ç®®®7n@¦RRRð °ä�WS<O¿ðM…Àwõ+�dU5;Bcc#Fãââbç»ËÏÏ?{ölPPa…4xg9,[¶¬©© ˜4·nÝŠ·¹õ†úúziii‚Y0** "%%“‡””Aá½#ÈdòãÇ]]]W¯^}òäI ‰]»v¹ººÂÏ­¬¬ BGŒqáÂøÉ7fϞݟY‡3f̨¯¯‡‡/_¾œ SdiiéèèWmmmgΜ‰F[WW×¼¼<ooo###4NUWW#§ ///ø­ªªjŸºî$ÉÓÓSNNn×®]ß[Šèèh‹%&&†vÐÙÙI§Ó \[D…µ³³·+™¶¶6øLx‹_uuõ–-[ètú‹/¥¤¤<<<à·êêêàS+ ðõëWH411¹pᚊ¾Ož<Y¿~}KK ´%ü%…K—.A.ÚÚÚ@y #o`` ““Ó²eËlmmÑTÔÞÞÎÃÃÆÇ³gÏž9st69o—Y,VAA¥¥e||üÀ ÒÚÚjoo¿dÉ’ïråææ€2ª¨¨øúú"Þ£®®®ÎÎN4 ‰ˆˆÄÆÆÆÆÆÂRfÿþýhºmnn^pPÔí"""œÛH&Â[­ZµÊÚښТZZZÎ;÷êÕ«sçέ\¹RPPÐÕÕÕÒÒ–)÷ïßÿ-¦aaáääd(ïÆ=ú[„+)((�u:77÷‹/ðL:ÞÜÜü³9´¾Ïq;((vÙÙÙ\\\}ºçWWWïÛ·ÏËË‹Àöchh †9C]]ÝÉÉiÅŠ+V¬ÀËȃ~ß2ú§�� �IDATFvv¶¢¢"È-{xxHIIÁÏ333Á"áîîžý?\¹rèA (ýðÇÄÅÅÅÄÄÀs´´´ñW¯^½ª®®Wãââf»­­í¹sç²³³­­­ñ+Ù)S¦¼{÷õ·M›6ÁoœœØx´µµùøøHJJôÇú ƒ/_¾dggGEEÍ;—óÍÿüóOkk« >ÝÑÑQKK ^8&&Ì/÷îÝ €ÏJ?€M›6¥¤¤|üøø—ššš¶nÝ ¿½|ù²™™†aS§NEßhÆŒ£% ©© }& í ,†GvxUUUGŽKÇGvrrr~~>ðrâ?«››ÛÈ‘#a‹ƒa˜Í²eËàç·nÝb7Jà盼¼¼ƒx¾ijjrtt466&ìáú„¸¸8ªÉk×®áEQ#""ú8jrÙÙÙ4 i766^ºtiõêÕ0bÖÔÔ jïÍ¢ÕÑÑÁ™,nÑ¢E(¯Q£F±NoÞ¼9þüìììgÏž‚õÎ;mllà'–––èœì·ÀÊ•+QyÅÄÄÐâæÇ›7oÐà‰gK£Óéiii·nÝâÌ>Ø»œïÅÖ­[Oœ8A¥R ètzqq±””To~JZZZ?~„JñôôDû*ü Ôªªª$%%9ïm·nÝ ç±RRRp ó£p÷îÝ䆖––‡ ïÛ·oš`dddrr²­­mAAACCCWWWSSK²Ø žy Ã8–’ÉäææfÎTƒ~~~_¾|¿/_¾Œô¡ÿ=æÏŸÿcm¹¹¹‡îñ ¤?hhhpww722@Œ ƒÁ(--ElëœwQ4°n­««»víÚ¢E‹É寿þB¸þþþH#õ»@"‘:::8(~þùçŸ}j¢ÿFhoo'“ÉýÑðþ¥P\\¬ªªÊîVUUuèС€€€‚‚‚òòr  ÿ!Ä ƒ:åhhh ¨ÖÖV++«ØØØ'†®®®ÊÊÊþô¢ò<ìVK<’““Óg177wüøñÈ100°©© Ü6$%%KJJ`;ÕÐÐÀd2'Mš´}ûöo.--9räÀÌÖïß¿¿uëÖÓ§O9ÜsìØ±Ád’®««ãææX8í¼yóà”n`pwwWVV˜_‰DZ¶lYAAûF¤©© êüõëW‚óØÕ«Wõôôð¦<ðú—xýúõ‹/ û›"***55õ‡kAýl,[¶,==]û•ŸŸ_\\Æ2™\WWçææ†¶ËÿÙ”####((ˆÜ‡`†5j…BD)))(Laa¡¢¢¢úí„ ž={£•žžÜO"‘`PWWgoo'ùuuuà†$%%%..w"­EEÅ––HDòêêê 8jÔ¨~ú5ô8þJIIÁsÈd2èåÔÔÔ€ TYY¹«« ®JJJBIÇŽ[]] ‰ªªªˆ©iùòåYYYè\‡——wܸqp[mm-hœˆ‰‰ÉÉÉAb[[:­­««C•¬¬¬ü½6n===Ø/’ÉdÐËTUU…gVWWƒsdkkkKKËâÅ‹ÑèãææF¡P`¾5j8‘ã?«§§çÔ©Sá=ÕÕÕáxÒ¤IYYY‚‚‚L&äxyyµ´´Pv —#...++Ë^Ø@WW777,{#ƒÁÈÎΞ4i??¿ºº:ä‚Ô\ðŸ¯Açëë+""‚7rªªª677ÃH¡g„ _¿~mkkÃ0L[[…e oÄÏÏ?€mnEEz‚ššš”””¦¦fMM {["€‡‡g„ p[]]ÒËNü¤.++‹rÁ+•••¡¬5448Hæà3EÚK=ß[©T*,«««¹¹¹åååGÝÙÙ W¥¥¥!G---ÄËB||üñÇ™™™¼¼¼4 |óh4Zaa¡ŽŽŽ°°°²²2¼|CCèÿJKK‹ˆˆ@"ƒÁ€S[ü!..>àÓÊŸ‡‰'fgg ±X,è;t:=77wâĉ`íÄ0,==ÝÁÁágÌ7}O9x}­eË–1™L°t™™™þàÁƒxæÌò»ÿþöíÛñ+V4þ>þôx¤¤¤@¶REEåüùó‡†oë2cccƒO^µjÌÀæææ÷ï߇ÄcÇŽíåâÅ‹çÎ WWW‚&4 ã‹éÓ§£—.] B­ŸaffvàÀOOO¸zêÔ)pprr²±±s“——:Ž344Äï^tœ¿ÇŒ–ÃI“&íÞ½ÜIá4E^^¾²²™wïÞMðäîqŽÁO/^¼€X 111€”””þúë/9ÕÑѹzõ*ìÃð.JJJ(dçàÁƒ7oÞ„×°µµ Tggç“'O‚·7XQ‚‚‚Ö¯_ßÙÙÉÍÍýüùsø¬·oß×;55µ›7oÂKš››ÃçÍ›N¥ý„¶¶6ÞÍìŸþÙ²e ¸@ŽT*ÕÑÑÑßß_AAÁÙÙyïÞ½0U@·™6mú¬K–,fa˜³³³spp€/ øÎ;àjŒaØ“'O@íjòäÉè9òÁƒœ‹@°ÀŒ3&88VÐqfΜyåʕӧOãnݺ…¦FhNÈ"-&&vÿþ}pÞ=z4r£—””DÓ:o@vÛ¶m0¹ª©©=þ|Ò0 ³··ïMŸ©ˆˆHPPþª¨¨(Þ½bΜ9(/SSSøqqqëׯ?|ø°»»;\={ö,Xe¯_¿~üøq8y½{÷.~i…7Û"""LMM»»»A­µµµÕÍÍíîÝ»ššš666LJ:ï’  Fµ~ýzhí{÷îõöö†Dkkë_A*IGGo– ܰaCGG¸Þtvv:;;C\j`?ÏØ0,Ñö[bX¢í×ǰDÛoa‰¶>›ñ°DÛ0†1Œa ã·Äð”3Œa cÃ$ôÊ$=°PÊ_|||Cưáåå2Ÿ νxxx†L‰àä’››{È”ˆ‹‹‹Éd±Áaèu¥["ð§øéSFÃú °X¬ŠŠŠ¡¤ÂŽŒ?¶5ü·hjjJ ¯¶¶–L&¥uuuÑéô!68twwWUU %E†ŽŽ  úQ@^$ß%ÆÑãxÛó”C¥RRph€ŸŸ¸‡Ì”ÃËËK¥R«««ÕØØå@,áK¾ûc{)™Lîèè2] ºOww÷Pøøø FYYÙOâêÿO …RSSC Yp3–@±k@kÙŸNZ^^Žw¹ìcÊ2R††IHH̘1cˆy¬éêê{¬ýÊcx¬ ™®k555Cip///722öXë­ƒÇ~Sˆt48 55µG†åa÷a cÃÆ`mÂúÜ}þü£óåË—7oÞ`fdd„µâããAhéÒ¥ÒšþùÏ ½ÿ~d ¤R©~~~H|¢¡¡ÁßßðQ£Fá‰@rrrŒ ï/''‹âçÏŸã7û›7ofçåî¯_¿ÆÇŸ›®®.;'æ›7o€lñâÅHà(88â·lÙ‚ØÉ|||ººº¸¸¸Pàagg'QÊÈÈ@-ÔpXX†aZZZ‹-‚ÄOŸ>%&&b6}úôþxÁûùù™ššâ‰l=<<X,–   DäaÖÔÔôøñc Ô””q999ˆ¢ðiÓ¦á¹2cbbTUU‘,MPPÐ/nݺO›ïééyàÀÂ>²¹¹ùåË—@šYQQv�mmm“~6Óààà3fà£)ïÞ½K&“1 ;t赯¥¥âÚ×­[‰ÅÅÅø†ÿ¬ééééé醣Ðú¨¨¨ââb ÃÖ®]‹{ýüü òtïÞ½uË`0€ÉQDDÄ¢Ï"|ùò¥­­mÖ¬Y(åíÛ·@ºhÑ"---H Ù333d͸sçˆJ>|Õ0‰D ÅS¡;v,b”ÈÌÌ„¨rôYQo¬\¹²7&ooo ‹ÞêêêQ £ŽÐ××GTë€×¯_çää`¶lÙ2¬ýôéÓÚÚZ öoß Ðqà*??ÿþýûm4¼uëƒÁàãムi<jkk!ªZUU‡¨ãLž<b¥1 KHHÈÌÌ$|ÖÿOŸ>;w.QÇH(áÇCˆÍWVVî3}€–ºÞ.TWW»¸¸899Á8…ºÍ‹/H$‰DЇî—žž‰!!!;¯§§ç·oßHÿ’‹îîîvvvvvvFâƒàžüü| I/((pqq¹rå ÐEæ¼íïïÿùóg”Kĺ[[[]\\®^½Šgå).. …‡¤§§Hß¼y“––WÃÂÂŠŠŠ`.((€Äû÷ïÃÀäååÕÐÐ@"‘ÚÛÛÝÜÜ0 £P(^^^p[YY%TTT<yò?~ü óMLL $¾~ýúÇJñ÷ß»¸¸\¼xò¸¹¹µ··“H¤††///…ïß¿Ï,(( „‘gdd R“H$¼fèË—//]º#4ßÂÂB¸íÞ½{­­­ð‰]\\Ο?O¨öÖÖÖ«W¯Â `VRR‚>1‰D⬤‰âââboo1šÎëêêà9À/ŽÐÖÖv÷î]¸TXXÃÄׯ_CBBŸ5===>>_¼x+‰çÏŸ£†ôøñc˜\>|XQQ‰7oÞ— WWWH©­­åL©ž““ãââò×_–šoRSSá ááá ¾ŒÚ’¯¯/Ôy{{×××ã ÛÕÕåâââììŒ'øª¬¬ô÷÷‡Û>}ú£ffæË—/!1..¸;###SRRЇèÑ.ïãããââráÂD,M¥Rѧlnn†¾ƒ×àÈÉÉA™ÐŠ`¾yÿþ=\ q°€€€ââbH¼sçœ= '´´´Øá~*<<<Z[[I$Rss3º®®ÎÏÏÞ*;;;<<Ê ‰ ÉÉÉðYQ݆‡‡³óà &¡ïàÍbÎÎÎ04 D___4Jö.‡ œ£aSSÐ¥899%''ÅÄÄhii™››c¶sçN]]]ßÌþýû ÒL&ÓÅÅÿp‹5räH �&é5kÖ€7š¥ðóÍ»wïé›6mâLëÙŸæååÇ»¯¯oLL °»bccUUUa[faaQPP ©©Éd2·mÛeÓ§O_³f””Ô7À”Éb±Ž;Ëa`yÉÍÍ=xðàÖ­[¿}û–žžŸ6((èÙ³g‹/f±XS¦L•ø¥K—ÒÒÒ8ltØ‹€a˜££cMM WKKË´iÓ8ÐÜÜ ')))ÎÎÎhq ˜<y2An ðèèh{?‹ÅÚ¾};؈ŒŒÖ¯_/))Ùã;´··{yy¾‘††{.œÑcðððxýú5œcÉÉÉ8q?Ï‚fPEmذÅbiii™ššâ?+мÂûØØØ|úôiâĉL&síÚµ°]¾|ùܹs*ðáǰ}WWW‡:úmmmí¢E‹8ÈLôX‹µpáBQÝ»wo^^ÞØ±cýýý= ;¡™3g®ZµjĈL&ÓÊÊ håää€v…½ÎËËËSSSa—¾dÉ‹ehhmØÁÁ!556:Ë—/ç¬üÈþ|*•êêê PP"ö®««ÛÛ÷ŽŽÖÕÕ…=YXXÔÆ£G.\¸�¯t÷î]¸}Í+W®à¿ìφ³³sQQ‘€€@gg§®®îÁƒñ[œØØXÐ;މ‰£BVVVuu5Ìúééé07³X¬ `¶oß¾¼¼¼ÿp£ÓÛøyâÄ vZOX÷‡‡‡'%%a–˜˜xãÆŸA3Ñ딣¨¨hccCP500¨««Š!¼•€nÞ¼ kkkè9L&óæÍ›999h %##³cÇŽÊÊÊ{÷îñòòÔ¸qãÆçççGøÞ¼y£  ðÇ,x0¤îÞ½»?Âé’’’ Õ*„€qãÆM˜0 ÈÏÏW2…rrr2\…wÃ0lÆ È ±nÝ:0¬8qL[†…šìÖ›šš‚ƒƒÁÞ5f̘iÓ¦Áùøø`L„a(111..NPPmØ{ôa¹C8{ö¬½½=†a\\\ýì´ïß¿‡×˜={6²;ÅÄÄèëëãÏóÁyçÎêêê7k! C„݉D ô÷÷OMMÅ-!—‰'ö“D=è#;vìöíÛP½H^}ÖM›6A.<<<°ˆÑÐЀ #33³¶¶ŒN³fÍzýú5Ü)##ò™øùùÃäzàÀa:–á'NÐh´+W®pqqá…eÙ¡£££££CPE†âððpMMMNÈÈãàà�º   MeeeŸÀÛ˜œœüêÕ+AAAtìÖˆ7âIñËDØ¿¢D‹'--mccî úå˨O##£EçÂÂÂ>þ¼aÃüªÔÛÛ»¶¶öСCxË0‹ÅºqãØÜ~e¼ÿ>**jÆŒ@öŸõùóç>|ÐÐÐà,ñ÷³Côááää$((ÈÅÅÕ£fÕÏÆ÷¹P(:.+++++ËÅÅÅAD áðáÃZZZð“+W®€•öÂ… HÄ>>>YYYaaa`íí¯^½! Ä[¶l144„\îÞ½‹ßH~¨T*•J…çðòò6ž¼¼¼pîD—nß¾ÝÕÕµsçNX>4551îÄ;È·´´¸»»;Ž7h4™L†ÛðÙ‰ˆˆÈÊʲX,dxí?à™#FŒhjjêóþÉ“'oذ~òîÝ;8«‹ŒŒTPP€˜�)))YYÙ¶¶¶Þ|%;::¼½½ ³ººúž={ °t ¸ÕöV½°šikkƒK¢¢¢`ú|þüùùóçÓ§O‡qt¾áN:Ž7ô=zô¨±±ÑÌÌ xK›››%$$àÎææf´l„ŸKIIõ§’{DxxxQQ‘©©)Á À{{{IIIt.ø]Æ·%SSSccc(N`` Øôú³dÆʲCWWwÛ¶mðØ/_¾€•ÐÐÐââbYYY°¢ù¦««KVVÖÝÝÿ±ÎŸ?³×¯Œ>ÄÆÆ?ú«W¯Pº¨¨¨¬¬,F#XØÚÚŽ5JVVVFFæüùóƒÿß'^››ÛÚÚ ëJ''§?²Ÿê€?™×Ðа¶¶¾xñ¢¦¦æ®]»ð- ''gii †µ%[^½z•‘‘±dÉ:~;2þü5kÖ°KE:u  QQÑÞ꺴´ôëׯ°/ñõõMJJ‹J%''ã k¥¥¥°Šñòò¢Óéøãôà kÐyÚÛÛõôôŒcuuõçÏŸ‘a-..ídõõõõõõ/]º”™™I8†íÞÞÞxÃAN›&L@«ì«W¯fddtvvæåå-_¾œÀL �£œ‘‘‘¹¹9Þƒ�­K._¾<iҤ͛7ãmÙÊÊÊè¬òéÓ§ñññìç“H¹rëÖ­À!Ï???¼aíòåËxƒÞ‹/ð†58ÛÿòåKDDÄœ9sî2Â+ÙØØäææ‚…çÑ£GÍÍÍ6l@"âxÃÚ©S§À¡–ÏÒÒ kÖÖÖ›oV®\‰üPzÃ… -,,æå¯§§§§§çààðéÓ§Y³fÍž=UXwãããÁcð“'Oö(–A£Ñ<xÀA/Q]]}_ooï””ÂFGFF&×mÛ¶}ûö ,NŠŠŠ[·n•––ž<yòîÝ»‘ÁÇÛÛûßÈ ÄÄÄŒ§OŸîææöþý{¤(8gΜ9sæìÛ·¯¸¸XGGç—zç;w¢Å™’’ÒàÏë?ÝIÚÉɉÐt<x™™yôèQ[[[‰ÛÚÚZäJÀŸ>}ŠŽŽ¾wïÞÑ£G“““ýýýátýîÝ»¹¹¹œ«£££«««««Ûã0:`xzz²X¬M›6qPÒ„55°Äãeƒ{DBBø° RSS ééé±±±·oß>zôè‡<x�>N·nÝ‚ƒ_ Ñh>LKK;zôè•+Wªªª®_¿çd}êw)((èþýqé'²³³CBBŒÑPÛ>|ØÚÚºnݺ>m³ÿò˜¡ÿó͹sçFmnn>€XŤ¤$¼— 000-- Ÿ¢¦¦†ª½7‘ž>‘™™‰'ÀgǬY³Ø7s+V¬àÜq~ehiiÌ-ááá#𯆳gÏÀpòŸír€gÏž­Y³¿nrwwƒ ™LŽŠŠ‚£‹ÖÖÖÈÈÈ>—ŠK—.E­eee***àHúæÍÎQ„Û¶mû¡ ±±±ÖÖÖ}údwuuEEEõGõ(??¿¢¢bÕªUƒÖŠŠŠ²²²ðkÖ¬A•™ŸŸ?vìXØÍÄÄĨ©©qxÚÿ±÷ÝaQ\_س•]`²ô" "*b"bE°aIl±w01»,`7hlQQšAE¤((Ò”^\aé [¾?Î÷»ß<CÕ`ãÛ÷<æÎ23·Ì9÷ž{îû2™L´¯‚c HTQQÓµºö°aþÄQв²²âââžl=ÆÇÇ;::öä Ý¿ÿþ{äÈ‘ÿ“ÑÔÔìÖßÀò7>>þóø²Þ¼ySPP@Ø6KJJâóù#FŒ@%ŸšwÓ!Š‹‹Ÿ<yŠPÿ7n„<Ï©©©ß³\E@@ÀÖ­[?[Äòk»œ±cÇr¹\ˆTN:ðyóæÝ¾} ‡ »úÞÞÞ³fÍ200ؽ{÷É“'0 Û·o“ÉDÓüÚÚÚC‡ö»ººú’%Kà&JJJâÕ¦¦¦hGîÙ³g–––p¤`Íš5aaaþþþ†ÍŸ?_[[ûóšÃÒÒ²¨¨^CGGv\"""ÄbñôéÓçÌ™ƒjjii ÎVrèÅ8ÎÑ£Gÿý÷ÖÖV‰„´jjjÐ]]Ý;wÙÛÛC¡ººú/¿ü‚aØ„ BBB X§ç8{öìòåËÅb1N‡‡ÃY¹r%ܳ_¿~0COKK{öìÙÊ•+ Ý:cÆ ccc”ñðáÑ#G¬ëÖ­AAA¼fÍš-NŸ;w.2y!!!`ÑLLLlmmá)âøyðòòÚµkÊa‹»¹¹ù·ß~óññQRRZ»v-<EAAMbž?ŽßÎÎnÞ¼yS§NEíljjŠ@§OŸF«Ìßÿ]__÷îÝLJËýû÷Ã:àÔ©Sð· ©­nܸ@ ÃV­Z5tèÐM›6…††‚DÛ²eËÐ9¤7BÎ…BÁçôã1`À€É“'£±áߟ~ú©¶¶%ˆt-\¸ ã‘#GöPÏ?“èlºPVV·ÕÕÕ…Ï<44Òp,X Wmll 0îááqóæMø@6lØ€–;=‰yô.Nž<¹víZ‘HD¥R?Ža—Ë=räÈtttæÌ™/¯¢¢Él#GŽ|ÿþ=êëëÃÑÅŵíàÁƒñçÛ¾=ztûöímmm$ ²ÞëëëwïÞ}øðaUUÕeË–ÁË+**nÚ´é¸333HÊèéé999ÁÔlÀ€ð ‰TZZŠa˜••l¢Œ=æÅ&L P(àrìííñ“5ЋÄ0ŒÍf;99 SRRÂOÁÆGHNCAI{±±±¡P(UUUðèžÇd´µµñÑL555'''P×ÑѯÑÈÈ6 D&“‹‹‹1 2dÄú=<<ðÛª²²²°£P(7 »A, zÞPYYÙÉÉ lƒÓ××wrr‚8¡±±1áhmg&oýgΜ Ç÷h4x,YYY'''ø¤ûõëÑ�uuuø$tuugÍšACCCBZ篿þŠlߘ1cÈd2œ?~<^mðÂ… „#™àZÐF‹ŠŠŠ““, 444 ™ª‡Ø±c>ÇiòäÉÀ2‡aÌ{h4¡ÊÈÈ899ÁØSPP€­!C†üõ×_èÏašbddäää›çfffP¸zõj8‹€ûØÙÙQ(p9öööжNNNà{¤¤¤z²J˜8q"> 1oÞ<¼ð%ŒQ£F‘ÉdHF;v,¡?~Ä/ÓñvYIIÉÉÉ Æ$Kýû÷Ÿ5kt¨‘‘tñàÁƒI$Ps:” WJ˜» ƒÛ4 šŽƒ]OT'''===005466†xààÁƒÉd2X ôбcÇ’ÉdØÓýé§ŸÐÔÛÏÏïë3žÍ˜1ƒJ¥ŠD" …{ÃÒÒÒгòòò(T£¢¢2|øp0NNNh‡Âõæææd2¹¨¨f¥=IýÒðôôƒ˜:u*•JÅ›&)))˜‹°X,'''˜=+**‚¾s¯C¢ úCB¢ úýC¢ úC@¢ Úí0Æ«‚ ‚aÆõ„c-<<|Ê”)4M¢ *H Á·ÄåH Hð•Ðñ^…B=‰>À0LVV¶ÏÖ Ò---Ýgº ö¤¤¤úX °Ðg¾£ææf2™Ü—Œ NÞÍ�� �IDATt“ŒŒÌgg‡ŸÆÉdöJ7‘Éäžùÿ¯.çãÇÀ‡Øg  ¬0?:jkkcbbú’$pCC™Lþ¶Lˆ½  ¨èKŸ’H$jhhècÆ¡©©éöíÛí“_~\ðx<.— ´Ëÿýúõëú\D/¸YYÙ/”®ðMÀb±üýýGŒÑgV9ÒÒÒ±±±è¸L€””TVV™LîÅÁýTê‡ :$ úAd2922²/YYÙaÆõ!j&“™ ¡¡Ñ!‹Ä§‚F£‘ÉdH9þ‚.‡B¡�ccß�d$+((ô¥Œ5Æb±úL71 &“I&“ûLh4ŸÏ§Ñh}¦F±Ö—úÃ06›M&“åååûRÆN—••í•n‚Œµ^t9’ô $@ ¾ÖZ¹ëË ¼k×®™˜˜˜˜˜œ8qîÚµ ñ"TŒ7$§0 ð{<aeNNÂ!|@hh(<xpÃÝ»w#¡µk×šà““ÓÃú¿~ý©�"##á&r]ïÝ»®‚Ä$†aK—.Å?Ô1Jw(**‘À“'Oàgˆð‹/BagGÍ ˜<y2^Á Ã0øsü‰Ú¼¼<(ì‚’ÄÏϯÃnų/X°� ñdkÆ 311iÏ`ˆg[ILLÄ7þa·pss#XŒ=î#?.,,„KHz566ÿèýû÷Cù‰' ¯CˆºÍP Ã/m[[”tËÛ†>IÁþýûáxÂ%K–@!aOkذaˆ–˜Çã᫃ØQQ ãoΜ9ƒÖ�îîîÝj >¼‹ 2Bøp�íévîÜ —ÚÓéOŸ>¯ì0dÈ“ÎH]¿,,,LLL«Ïž=#È¿@õ‘··7¾ÚÓi}Ì™3oчÓa ¿yó.!öÏöÈÉɹÙàE#ñè”}àÅ‹ÎÎÎmmmxÞ:ÿÌÌLпóóó;}úôêÕ«÷ìÙ£©© …Û·o§P(ˆQaüøñ™™™ˆõÝÌÌ ´m>~ü8f̘øøø¼¼¼-[¶ÀMRRR–.]záÂ…;wî<xð� oܸqèÐ!dúÏœ9ƒ(Ëjkk8€ÎÜõ„} ´´ô§Ÿ~øãý< 'íÙ³/)±ÿ~¸ºcÇ …2iÒ$¤œ8yòd°€#FŒð÷÷ý¼ |ûöíO?ý„Î$'%%9snxÿþ}www//¯+W®Aá©S§ÎŸ?´ºÛÃÑÑ133“ #`bb^WW7bĈ¤¤¤âââÕ«WCá‹/-ZtåÊ­þùçOOOD¿gÏ ø“ß~ûJ¥ÚÙÙ¹¹¹-[¶ Fª‹‹ËÅ‹µµµ‡ $+++ MMM‘„hIIÉ„ ùPkk«±±1Ò‘ìacéÒ¥qqquuux¤1cÆ\ºt ö±ÌÌÌ^¿~.•••-[¶ ^;==}Á‚×®]3f ”À@‚ƒ÷§OŸnjj‚roooÄÓ³|ùòððp4õ™<yòÁƒ¡"¶¶¶ñññ222æææ0†?|ø0vìX{îÁÁÁÛ¶mkiiÁsü<x°_¿~ðô;w‰÷ŸþyþüùÀQ4oÞ¼Ó§Oëëë9²²²²¦¦}>b±X  Ía`CxöìÙñãÇá†ÑÑÑ[¶lAvðܹs{÷îE~èÏ?ÿ¼víZCCC[2£G®¨¨À?´¾¾ÞÎÎ.55fööö�n·¥¥ÅÚÚ^"¥øzzzêééÁë¹»»S©T$Ë4cÆŒÄÄD4u2dHxx8“Élkk4h¨µ~ 4(::šF£5772)c–••5cÆŒ¶¶6ü¶\pppRRÔèòåË>>>7n\³f rK›7oîÉ‘É/‡E‹%$$ÔÕÕáeª««###ÁB6 Ö¯_5zþüùÏ?ÿŒhÝø|þÀÉzד“kO!Jí¢ÒÓÓ?~Œ·M|>_(¢-khЦ¦& ……­­­ÈþâýÍÙ³gñÜ‚555ˆ’FB¡°±±  (ÇÀÝ L&#E“(**V'²²²Ÿ´—®©©™žžžýÛo¿¡ÂÖÖÖÖÖV¸•J%´W‡5V0LçΘ˜iii‰$‹‘·¯¬¬tvv C ÇaÆ?žÉdBÌ’[ZZÄb1¡‘;ƒ¿¿¿P($HHÔÔÔÀƉD‚Y9¾y™L&A¾™ÂÂÂ7"×ÕÔÔD¥RáO|}}Á®Õ××3™L(„ÅàïåååÙl¶P(D•-//Ÿ?~HH^¾ŒF£}j¾Ã©S§Aô¶¶–Ífí“)ˆ;Ã%iii¨)zî­[·ŠŠŠ`•Ž6…B!ZC¬X±ÂÑÑÈ“�AAA 2šx<Xa4†[[[»w“jooéÒ%¼àØ–-[H$$¶µµ¸5¾y¡y£££Åb1”L&Z²­­­¥¥ ét:Jl=þüû÷ïñ—;vìpwwïZV.**J$á—­b±­ðôôôÒÓÓÓÓÓñ²0è¬ñÃéäÉ“(ÓÒÑÑñ?þX¿~=¾såååeddø|~{}“/x.¨‚žkbb’žžžœœŒº ßÔÒÇaÈmÏÖ­['Mš„—>ùú8wîœP(K<:T‰D][ �…Bé!Q‡{çÖàhXC„… p8‡#‹»µøÑÆd2 ojjâp8æææŸÁiÊçóÉd2!?xþüùðbøéIW!E2YVV–ðt‡éÓ§Ã}²²²PMüsssáêäÉ“Ô ¡¹¹YJJ ¥ùC}µµµW z´¥¥ÿD …-—²ï! ûžÐ¶¥¥¥jjjgĈ :Ð-ÚÚÚ€”P¾qãF‡.§ç‹ÅÍÍ̈́扉ÖÃ[À®Á`0dee C<--ÍÖÖn|VÚÚÚ—/_†K{öì!Áµµµ‰D"X`Ñét¨¯§§§Š7¶´´Ðh4ü¥¥¥¡[ ôôéÓO=î@¥Reee «::xÆ vvv]ðKÉÈÈ´ïâêêj¨c·a½ö= ‡ŸºîÐöG¾Øl6Z¿Â·C0†Â[u5]·n‡Ã‰EÍ‹ÿj¾ßí‡NêÛµ¢P(ŸúÕô.À8´w àp8íž‹½®^½šŸŸ_YYYYYI"‘º5‘mmmãÇ¿~ý:žWörLMM+++ccc{Hd  …Ý¡\„ÿý·ºº^ÌÝݽC;Ûú?´_‡áãÑááápSSS‚ÎîŸþ9`À�¸zïÞ=´ƒa˜½½½¯¯/~禭­MOO¯°°¾vÐ?~ùòeû™ÅÝ»wCBBÎ;tÅŠêêêðé~†³[QQQYY™””ÔmóŠD¢Ë—/çççü+†aÛ¶m³¶¶®¬¬ ÁW¶[”——O›6àûÇÇår¡õÆסÀ¥@ @Ýsü1dÈØØX¸,+ñîvñâÅpéÏ?ÿÄ«À$&&¢È §={ö¨©©­X±‚L& ‚+VÌ™3§={7U¢££QâiYYôA-ð“ó–-[lll\]]?ÉæÊËËüøêø÷ßwÆá&‰ÎŸ?_^^Þá®dgÍŽ"iÔÕÕu-«<sæLÔ¿ZZZíEŽ·lÙ2f̘ÊÊÊ7nDEE ‚3f<x°£PXXhnnÎáp>›þ›cóæÍÖÖÖ„0Ìw‚7oÞTUUUVV¾{÷î›x/;¹˜4i’···ªªjCCƒX,nll„M¥R “ÓâèÑ£$iñâÅ I€pKKKg¢Èxß®¯¯¯¯¯ÿÅ---³²²`&[__?jÔ¨„„„†††¦¦&‘HËp¡P€v8�«V­‚O·‡ëÈÿ‚[·n%''ÿñÇ ÈîÀ%ooooø$ðx¼qãÆÅÇÇ·¯l·¡í}ûöéÿwîÜù¢ommõööVTTDÓ—õë׃žcCCƒP(lnnFÂN¶¶¶¡¡¡øƒt:úèó6Z[[ÿøãKKK´ôI+Èž¿víZFF†‡‡êÙÎ&[nnn¨Ù‘<è§B tÝ¿GŽÁ[a— 6A„¶©© y»ÂÂÂÊÊJ wMSg³Š¯ƒ/»îc³Ù苪­­7nÜ«W¯ÐæÇç-Ïž= º±±188XIIiæÌ™Ë–-[¼xq×òÅÅÅ_è\„àñ‹h++«ÄÄDV‚çÂlN(644Ì;744411ñï¿ÿFyw(°#‰¾š†N¿ÿ>ì¨oPRRêyà«Ã�®H$ÂWvÁ‚ÁÁÁOž<9uêT××wíÚõ…˜¤ÁàâÕNž<I"‘ð5•‘‘ùóÏ?az^__ÿâÅ‹ÐÐPKKˉ'^¾|™ÀË fŸý>{÷îÕÕÕussûŒ¿åñxÖÖÖÝÒ4HIIEDD@:êÙ+V´ÿ%MýGDDDÜ»w¯[áW‹…^†ÇãMŸ>0ÖÖÖÊÉÉý¸Gè`×ê»=å3dÈäää÷r¾G—†í‚ÂÌb±2 hë?²X,¼ òÀãããÁߨ¨¨Àïkjj@è…J¥²Ùl(lll„î…B¡Åb­]»víÚµhnii ÊHòòòMMMðK‹õÙ!TƒÁ`0à>mmmróYYÙkŠaØÜ¹swíÚE;TUUÁŽ4‰Dâp8PžŸŸ¿xñâÐÐPd Q{2™L99¹ÀÀÀ¼¼<H1 ‘Hx+ÙCp8ÿ®¯¯GÍ+''B»ë---|>ßÉÉ EŸ|||š››Á ³Ùì¶¶6TYH@RPPhhh€Byyy«¨¨TWW†Ãá°ÙlTÙ7oÞ,_¾6Tètº´´4ü-ŸÏÿ/:ÓÊÊÊ\."o ß ‹«««UTT(м¼<<¥¾¾ífß»w/..ŽtÞØØˆ_NNÎÛÛ¥ö:99Á�ƒÿýðáÚÛàp8$iìØ±ìËår‘@ß§ÎTÐÓååå ¾yåää:Û¤%‘HŠŠŠð³ÚÚZA¢Óé222PØÒÒ"''çêêŠVÞÞÞ$©CÓó™D×Ò· ƒN§Ã øÒ` ㇓ɔ’’Âç%9òêÕ«ÉéàààïïÏ`0ÚÚÚ¾¦6‡ŠŠJUUFkiiçB:LgËd2i4Ôì”ïÙ³ÇÄĤ[½ùoeeå>@ŽTS$q¹\eee …‚·_èÀ/µ[Œg®®®"‘ÈÞÞð_ýD…wìØ±wï^(<r䈭­-†aîîîk×®ÅK«ihh €õ‹/ ù]II)66Ã0ooo¸Éˆ#À4@Î1.\¸ Sݯ_?dŽOž<¹fÍš;wbÿ;9ÔÃúÓh4|´ÄÖÖ=ÑÕÕvA¯_¿.‰V®\¹}ûöÀU///´¨âp8„Iºº:st:ýùóçÿ¯Å©TB•’’*))bæèè¸wï^77·+W®@áúõë{¢ž©¦¦†÷²éééb±XNN.>>Ã0'NÀ=‡úÏ?ÿ`–pÿþ}///üªí3ÿþûïûöíƒ?9|ø0të¥K—/^üâÅ ÃBCCA<!!aÔ¨Qõõõ .á›)€ÙØØ…B¸á´iÓ8ðIæ�ß±±±¶¶¶ ŒOllltqqyô葦¦æ¹sçà)–––—/_†?‘––F¢“¨²—.]B³"OOO¼ þ‰ªªªxc””$--––)³ÊÊÊ111=™Ôã§– —.]Bf÷È‘#'Nôóó[¶lœ Äsÿhhh ‰¿œœH[a¦¯¯ݺvíZ¨¸ƒƒ¾[¡²„uƒ¢¢b·+iMMMôW, %š£w ¨,X�µ¸rå ƒÁøå—_vîܹ{÷n¸zìØ1Âþ“ªª*ÊJJJ1bDSSáÃùÒxþüùСC[[[¥¥¥“’’`Ö¸bÅŠððpôµâëëèèˆlÅÒ¥KÑÞ¤‚‚ÂwE{ÊápðÉ#Ož<3f Ç#“ÉpÖÇãÍŸ??::ºÿþÇŽƒ >üüùó_â}$m?$$mß?$m?$mÝc¼D[ccãСC{;mll”H´I Hðm q9H |%P;[AÛCL_@‚Û7êÂo~Ö¬7ç>d2üWR£ïyÔ¡C}Ï8ô¥nêÅQ(”.NÈõšË …_“jâK£¶¶V,óx¼>³—S[[ËçóúL�ðúúzƒÑ——ËmmmíK5jnn‰D}Ì8…ºººoˇֻhiiiOÛóÙèöÈc/¸œ†† ,ì#K9*U$%&&ö¥IY}}}FFFŸÑ•"“Éuuu$©ºººÏL6[[[ûاD"‘ZZZú˜qhmmMIIé3! …RSSÓÜÜŒçzÿ/=®¨¨Ø+™]¹6›2wû� cmâĉ’Œµï’ŒµÂß@ÆZ_2±öÓO?I2Ö:ƱÖk“KL $@ ¾Î²²ëËUUUùùùxÉœ‚‚8@„×{ñâp¦Y[[#1@LL žÚ}úôé4M,Ãù5))©©S§Â¥ÚÚZ8ª¢¢‚¤ÛJKKá8˜âOÌÌÌÌÍÍÅ0lÈ!ºººP˜�GîÇßs†|—––†¤;0 {÷î(‘èéé¡Ãç/_¾„åêðáÃÑ$âñãÇp,ÑÎÎ 0 ‹ˆˆ�²2t¶¿¥¥È1Ùl6’ª¬¬„vZZZˆü-//˜IMMMŒŒº­ETTÔ¨Q£ð<èÀ?¢O¯««{ðà†aJJJúáââb<çÀ;ëÖGq¹\ Ã&Nœˆ¸‹ÂÃÃÛÚÚH$’¨hnn099¹ &@áû÷ï!&ƒ¯lOðøñc333|·Þ¹sÈfÍšEX¼Ö××/€¢¢"ZatØ­999 edaa¡¯¯…IIIååå†;<ŠŠ-ÞiÓ¦A0S$Á1RƒAàïxÐôôt i6lªÅ0,>>B‹&L@ h,¡Ê¢±Äb±ð<Oïß¿/..ÆKóåçç êV ÃÒÒÒŠ‹‹1 1bDÚ'áááS¦L錡¦¦æÕ«Wí[`hhH ”íâ¡<1b:A&Èd2p‹|5ܾ}[$Q©Ôö„ÿ?~Œ‹‹Ã0LUUÙCôá 0� =tØ­ßqqqƒnÏpsûöíöÍËãñà\³²²ò˜1c¾ªËùðáÃrrrÞ¼yƒš¸  àöíÛ@ü—›› 2iii°òz÷î““Þëxzzêèè C<yòdæïï’Vt:x<^`` @)((…ÂqãÆ•––†„„€�WNNŽX,¶°°ÈÈÈ•­ÒÒÒ™3gêêêÆÇÇGFF‚ê(—Ëuvvî–­¡¡¡!""âíÛ·÷îÝC.çÝ»wÁÁÁÙÙÙ†©««‹Åb¼Dà‹/"""À½}ûÖÉÉISS3...22ÜjMM««+0ýÄÆÆ‹¢@ puuåóù7oÞ„SÍ222@âPUU AEEE$Y[[çææ†……Á¨ÍÏÏŸ1c²:›?îÚµëþýûÈåܺuëáǰ(3gά¯¯�ç-'''‰ð;?>yò$’Ÿb2™ÆÆÆiiiwîÜÊ¢n}øðáýû÷¡²µµµ®®®²²²!!!±±±€D" —–––[·nAeeeeE"Ñĉ+++ƒƒƒÁ•‚øÅðáû =ª¨¨8räÈ™3gË ‹‰‰+ÌçóñÜ£  è)''' mmmñݪ¦¦Ýšb”EEE3gÎÔ××úôé½{÷`QUUåì쬤¤tïÞ½èèh )kllœ7o•Jõ÷÷fÃ].**JNNŽ‹‹SRRB.çåË—ïÞ½ƒ±4kÖ,--­GEFF®oMM‹‹ ›Í ‰‰±ÔÖÖ6gΜÖÖÖ[·nÁÞ$Œ¥I“&UWWÇÄÄdffâ]N^^^hh(Œ¥¼¼<±Xlbbòüùó;wî�¯IyyùìÙ³Û3 ‡……555mÙ²%??HûÛÚÚîÞ½ ‡@ëêêîÞ½[\\üèÑ#ärž={¶wï^¼·Ã»œÔÔÔ;w(//wrrB^çþýû›7o —+ Éd²P(üjÇNƒ‚‚bccE"…BxòšššÀÀ@à¹PTT‰D£G.**º}û6Ì}_¿~-‹ÍÍÍñÝZVVæääô ½ÎÇ+++½¼¼.]ºDp9«V­"¸œºººÀÀ@°òòò"‘èKÄ„©]XäÄÄÄòòrüçÉ“'••• h{èСÈÈÈÞºuËÈÈÈ—,Yb``@XèìÚµËÐÐ_²qãFX‘TUUM˜0aÆŒW¯^}ôè¸åS§N7.555''çìÙ³†9s&$$Ä¢´´ÔÚÚú÷ßÇ0lݺu)))ºººçÎC´žvvv#FŒèÖå´´´$&&¾ÒÓÓÓÒÒ@ ïâÅ‹·nÝ»œÀÀ@=== ÕYºtiÿþý555³³³—/_sä‘#GŽ?žÅbmß¾=11QAAA,«©©¹ºº ‚‚‚hºììì5kÖØÛÛçææ>xð�h=¯\¹bmmÇãñà—{÷î}ðàA.çÕ«WeeeH¼°~ýúŠŠ ‰TSSccc3sæÌªªª .À ãéÓ§ÞÞÞU·qãÆ”ƒ¡[¡²?ÿü³¾¾¾†††Ïo¿ýfÅÚÚÚÖÖVVVÖÝÝ=55$Ú´´´\\\ÚÚÚ ¡ ›6mš8qâëׯãââ€ÖóÖ­[W¯^í‰Ëyýúuvv6A-jÇŽ111°Åápð.‡Ëåž={6%%ðäääýû÷ÛÚÚÖÔÔÈÊÊÂû nŒŒ$‘HPèîîþäÉ}}ý¼¼<gggà$6mš•••’’Ò¾}û._¾ ê±úúú³fÍ’••Ý´iŒá÷ïßOš4© —S]]˜˜XTT„gë*));v,,7W¬X¡£££¥¥uâĉ 6ÀìrôèÑcÇŽe³Ù©©©�sÌápæÌ™#rssáÍ_¿~½råÊI“&ÕÕÕ%&&¾{÷/ÇYYY©¯¯çû÷611)**š4it¢›››‘‘Q{—“ššZ[[‹ùnnnvwwÐÜÜœ˜˜ŽáÇä®üýýÍÍÍÁJ\¸p¡¦¦\ν{÷?~Œ×BܺukFFH´~5—³iÓ¦¼¼<h377Ç»œÒÒÒÀÀÀ¨¨(˜ä;wnôèÑÉÉÉÅÅÅPß”••™››—””Œ3,õÊ•+¡[¿•ËC{¥5ÿäääö|Ò•••/^|òä ¬¶}}}¿ªËÑÕÕõõõ}øð!žÖØØøíÛ·ˆ{§‡âä`ÜÜÜà{X²d ÜD �Õ´‚‚˜1c °©© Kú÷ﯡ¡… `¡ —”””™™ÉápÀØÙÙeggÃŒÕÆÆ†À¦Õ!”””|}}333ñ:::zzzðÄÚÚÚ.”zV¯^ ³Âªª*[[ÛÎØ*eddöìÙS__óæM>Ÿó 555sssx\]]]·r[íÖ„AôóÏ?Ù¶P(œ?~Oî“ ¯aii Ë›¼¼<(ÔÓÓÅ£)S¦<{ö,33Úknnnþþþð’é,k÷îÝuuu·nÝâóùŽŽŽ†ihh 8ðS+ <~(ú ˜;wnpp0;èB¤ÁÌÌÌÌ̬  àáÇ]wëâÅ‹Á¬”––ZYYÁ¸urrŠŠŠ‚¸Š‹‹ A°[ >|øðá~~~0>Ð&°ÄÔÒÒ"¨þà±gÏøÇÅ‹pOZZä8ëêêbcc!˜©¯¯ïëëhåÀoÁ¼$%%…B¡À ±ÿÅÆÆvhwïÞa"Ÿ…ÅÜ‚ àß ä”––F”ÊÏχþ555í°‘=z”——ggg‡âáÇŽóöö†¹æˆììì§OŸZXX@ º5!!!''GSSÏ’÷õ¦ ÷xüöÛoYYYׯ_ÿ÷r`±Xt:âûšÂÎ0gΜ÷ïßßœ?~ÅŠt:]GGJÈdò€ ¤¬¬ …RRR°h‘‘a2™P(++‹_¸p¹Ü¢¢"Ä ÇápÊÊÊ@<XYYù³S‡¥¥¥eddà‰222×5jÔ¨¬¬¬Ó§OÃ×…¿T^^š]]Û#@PTTD£Ñ òË`0äääàqL&³k¦ÞžCWW5/Ú¢è<x0ü L]­¬¬³²² °_¿~@©¦¦öâÅ ˆh¡ÊjkkÀ¤ ™|e!ÀÂ`0Øl6ÜPZZúóØ—ÚÚÚ¹¹¹pB þÇf³'Ož }D\ihh(**jßoúÂj�� �IDAT­í#VII ²˜`- S~MMÍ^̦}ôèÑ“'Of̘ѭÎÛùóç‹‹‹<ˆ¯Î¥K—ÄbñÆ»þÛÚÚÚ¢¢"6›Ÿ=xð ))ÉÅÅ¥‹54d2™ÐÔŒ1ú¶£^'..N__¿©©)((ÈÙÙYGGçöíÛ£Fê­aÿMüÍ;wjkk?|ø€øð¬ÓgÐÀi\ºtÉÍÍ­ÃS¢òòòvvvðíôJ‚u/¸œgÏžUWWIí¡C‡=z„6�:^üÑÀÀ`Ñ¢Et:}÷îÝøÀÚÂ… aWÖNŸ>=uêÔŒŒŒüü|X»ÿ>ÄS§N:uêºuë^¾|9`À€k×®ák&LhoÑŽ?fQZZº3÷œœœÌÌLX‹ˆˆ@‰ 0LJF€¸þAækäÈ‘S§Ní‚–_AAaÿþýXsvv.**zòä ¬aó„§§'>°Öí:`èСˆªÏËË+..ÎÊÊ*""ÂÈȦÕ?ÿü³‰‰‰žžÞ… ðµ3f°Ùìàk¨mûõë·ÿ~¬Íž=»   )) Ö‚ƒƒñYÈCøZ¦#íáåå…¬ÁlµðºuëN:!xü_YXXXXX´ïÖöX´hÖF­ªªzüøq|`mÉ’%ŸºÐél_711qêÔ©ÝF Î;WYY¹k×.”(ÑÔÔäççG¥Rׯ_ßíƒ ‚·ÿþøøxHˆŽŽ~öìÙ¬Y³ %=88¹çE‹u˜}ÓÒÒràÀ¥K—v±”D²çλwïÁåÔ××O›6ÍÂÂbáÂ…æææ©©©ÙÙÙK—.í"á;GKK‹©©é”)S|||bbbËqttttt\¹reFFFOæ|_ .\x÷îÝï¿ÿÞá¤\YYyÕªU`o¿Üiß/ž$}éÒ%ØÕï-<yò"õŸŠ¦¦¦æÿ᳟>eÊOOOOOO” rëÖ-ÈeèÍÍÍ…¹¿9^½zÉl½…¦¦&¸ŸŠ¶¶6ÔGŸ}æYII úè—_~A|Œ¨ „‡‡Ã†ð—F\\\RR’ƒƒ^à£Cœ9sæãÇhfÚÒÒròäI:Þ¡˜7/^¼€,P<¢££SSSg̘žZZZP³6»É›7oºr>}:Þ¹^½zµ²²òúõë^^^>|8þ|]]Ýår† BHVŒ‹‹ƒ¨ï>>>B¡ðĉ^^^B¡/ÊŽB¦ðí@„ùÛ¯r>çÏŸ5jTϳ–{‹`±X=Ùy&`ûöíÿñ(htt´‚‚»ûÆšššÝn6558q„×¾7¼|ù2##åmÿw466ž<y <÷vvvÿñ(hmm­¿¿?áÑyyy!!!hû¤ „††:::v¶ºêEÄÄÄhjj¶ÏÂo'NÄÇÇã*¶´´\¸p¡[UP ÃÒÒÒ KçÈÈHKKK4gÂ0¬‡~]#''çÞ½{„]·.°`ÁÈ™ôcÚ±±±ÝÆ~¾Ö­[‡÷ë„1—Ë ^¾|ù}‡Os9VVV•••žžž†1™LH­™<yòÓ§O¡ÐÌÌ B×.]²µµÕÖÖ^½zõ7`ƺnÝ:Høã?à÷d2yóæÍ†©¨¨Ìœ9 i4ôš™™åççC!ƒÁ€¸Ù„ âââ P[[‚àóæÍKNN†\‹)S¦ Y°O…±±±©©)z"La?~ YÅ #::$›Ð±¤Å‹ÇÄÄ€³‹‹ ìlÛ¶Í××âxôÑ<¸3…B]q]]Ý‘#GB¡””ì[[[×ÔÔ@¡´´ô¨Q£>µ;wîܵk|Æ k§¨¨èââ÷¤R©0…(¢‹‹‹••Õû÷ïQ·B¼kÊ”) Phjj ݺdÉ’èèh8p3wî\Ø]óðð8zô(¾²222Ë–-C•…P[ÿþý­­­QeÿË‘‹Í›7Ÿ9sæã £Ççó}||<<<Èdrss3ª)ÍÌÌP·Nž<ð1cÆÄÄÄ@¡’’˜ ggçÔÔTÈýé§ŸàèÕêÕ«¯_¿cxýúõ`ýwìØÆð¦M›>£÷î݃t Ã\]]MMM.\øèÑ#XqΞ=‡:™Êd2ÚÐÐ�ÿÀ0LUUµ³©Ì°aø\nû±tûöí¼¼<ø·››!¡´CHII¹»»wñSSÓ¼¼<ÔÈÀPK£ÑÆŒ3uêTd%,,, €ßö ^ºt)¥Ø¾}»··7 'HLý:øý÷ßA6D"mß¾¦/W®\Y¿~½ºººƒƒ²Nñ4xðಲ2ÂWcoo…¥àoü†‚··7ì666ž9sfëÖ­d2+¶páÂ/ñ …òÇðùü¶¶¶ÜÜ\==½ÖÖÖêêj8H£ÑÔÔÔЈTQQ‘““«©©a±X£G†$ ]]]±XÜÒÒÂb±¦M›IeeeÚÚÚ²²²æææ4Åb-[¶ >×aÃ†åææ²X,0 L&ÓÐବŒÅb 0�RNA6•ÅbY[[ã©©I¥RY,Ö¤I“À0�T€X,Öœ9s40 ãÙ³gƒ j?“¢P(***èL«‚‚‡Ã©ªªb±XC‡…¬*.—K§ÓÕÕÕuttH$Rss3‹Åš2e ÷ᜠ‹ÅZ°`Xá!C†3™L6› æ�vÑ Y,–¶¶öœ9s0 c³ÙZZZ,kРA°ÎPUUe±Xµµµ,kܸqN„étúëׯ9ìO²Ùl 4>|xnn®¬¬¬’’— †‘‘Qii)‹Å244„ù~CCCsssÿþýUTTäååA;|Ô¨QЭ°W •:u*„¤MLLjjjH$‹Årssƒü‘!C†JKKËÉÉÁòò#ŠŠŠX,–ŽŽ¤HÉÉÉijj¾ÿžÅbYXX ó¡ÿwîC¥–——w¦v,++kff†6c---KKK ‹ÅZµj‰D‰DÅÅŃ–’’211)))a±XРݪªª Ýjee©Ÿ £¾¾žÅbM˜0fý--- £ììì Û ƒ j?†‡ŠÆp‡Q …ÒÐÐP]] ¶UJJ Ÿ2Ëd2Y8+((ÀX‹Å,kþüù`³Ù ‚Îb±Øl¶••‰Db³Ùèo•••ÑÒF£©««ÃÈ„8 KcÇŽ·*--´‰‰Ig»rrr–––0¦R©VVVd29++ G¡P8Ê>PTTIrBÀnÙ‡ †ššš®®®H$+1}útB†Œ˜ZYYHKKËËËÃÌì‹BJJêÅ‹FFF#FŒÈÏÏ—‘‘QPP€™~[[Û»wïÌÍÍeddú÷ïÿöí[h.˜‰*))õë×Ëå²X,ØàÔÖÖ&“ÉMMM`"zâË{t:=??_AA\8‹Å233k¯�+//ãA$•””XXX0™Ì +ça)ŠX,nhh Ñhuuummm=ß{“’’jkk£Óé­­­b±8111>>^¢ úCB±öýC¢ úC@¢ Úí0–¨‚J HðCBâr$@ $øJè8}€L&‡‡˜þK@�Ã0iié¾$‰aƒÁè3Ý]C§ÓûL`ÔQ©Ô¾ô)ñù|‰Ô÷Œ“É„ ‰qhß>ÿåTIO]N]]]ddd_r­B¡ðþýû}f/Ã0.—›œœŒ'Ôê5¢R©½¨ÌñÍÑØØØÐÐЗ>%@ÐÜÜÜÇŒCKKKlllg„Ù?"Þ¿ßÔÔ,éÿl6»= _/»))©.HŸ~8ÈÈÈëééõ—Ãd2y<žººzL?ètz^^‰DÒÖÖî#*õãÇ¥¥¥}æS"‘Hd2¹ªªª/iiéwïÞéèèô £Ä÷�ƒÑÔÔ¤ªªÚªÉž c:Ž'xý".‡F£õ¢òè7‡œœ‰DÒÔÔìKk/^¼PVVîKkUUUd2¹Ï <F¥R«««ûL cJ¥ö%ãÀf³©Tªººz_ÊXËÉÉé-õh‰*¨H ?*ºq9©©©pº!44ÔÎÎÎÎÎÏ‘îãã… ¼Ö!æÎ‹äA…B!üñ¨c–ŸŸ…øCÎÑÑÑPˆ'(óóóƒB8øý÷ß¡$Ýzˆ‚‚‚5kÖàK=z÷ñõõmÿû'NÀUÐ@lÞ¼ ñ³fͲ³³Ã+6r¹\øžRâùóçP'ŸPxãÆžÔâçŸÅ-„‰'ÚÙÙ!N Ê‹‹áž@÷Ð!üýýñÝêëë ‚ç–߸q#âyšíìì@rP]] ?ßæKII¿þú듆é¦M›i¸U{*¶²²2¸„—¥xüø1úøø ÂË—/C!žm÷îÝPê·€%K–@!â ikkƒ8ÕÛ-BCC ¼s§N‚;€#`ëÖ­PH òutto Ãêëëíp€ã·@Y„pèÐ!øqPP”\»v ÿþú«[É€™3g‚ôj‡xóæ žÄ}8€¿ÿþ›ðû£GÂ%` AXµjþÃÁ0lúôévvv@ñ51yòd;;»ÎŽ$¾zõÊÃã}yPPÒsé¬[¿!Ö­[G ½G•m_XXX/ª(_Þdee­Zµª¡¡Ï7þüùócÇŽav÷îÝ«W¯.\¸Ð××WJJ ÏŸ?O¡PÚs´Ì;„#‘Aƒ^WWçââP\\ìéé 7yýúµ»»»——Wllìýû÷¡066öìÙ³¿þúëùóçëëë¡ðÚµk ÅÞÞ~ÇŽƒ ©®üùçŸè�vg(//Ÿ;w.‡F…Ož< ›ÇÇÇ?~ÏÔ{òäI2™ Wÿùç …2vìØÍ›73—=<<Ž9¢©©9kÖ,±Xlgg÷àÁ·dÉøÛòòòåË—ûùù½xñÂÏÏ Ÿ?~ðàÁß~û-(((;; ÃÂÂnÞ¼Ù…Q[¾|ù›7orssá`ggwôèQ‰ÔØØ8kÖ¬·oßzxxÀ=óóó7oÞÜžÑïÖ­[»wïe ÃŽ?N£ÑàO.\¸@¡PF½qãÆñãÇðÖ­[}||ÔÕÕwìØÁd2Aê4**ª¦¦fÙ²eð·oß¾]¹rå¹sçRSS/^¼…)))‡êð&ÀÝÝ=))©°°‰µ€¿Ù¸q#®ž8q"ž¹²¢¢bóæÍð”ÂÂÂ7úøø$$$Aá“'O|}}7lØpõêÕ÷ïßCá­[·ÈdòôéÓwïÞÝ¿çòññÙ¼y³©©é’%K.\1Ì9sæIKKOš4 Æ0Çsuu†ìyàÀ.—‹Ÿœ>}Z$ÁÓ/]ºD¡PÆ¿uëVà2رcÇ¡C‡´µµgÏž]]]7…B!HRÂÿBªU}}=‰DBÝ Ä·oßÎÈÈ€§„‡‡ß¸qcÞ¼yG½}ûvYYYçÎÎÎUUUø‡644¸¹¹EDD`VRR²páÂææf<_{MMM¿~ý€ñÃ0‹Ä±cǤ¥¥áMüüü(ŠÍúõë_¾|™ŸŸÿʦM›¶k×.)))@àààðÕR<H¥Rù|þ´iÓ ¦€ÜÜÜeË–566¶ßh Ù¹s'úB‡ u+™LnO—þÕ°yóæçÏŸ´§M³··oO?ZZZºcÇxùÜÜÜ­[·>|øë¹œþýûûùù%''ƒÄ:àãÇ|>äOîÞ½ ªFFFPÈãñÚÓÁΙ3gݺu Žüü¾ªª %jjjû÷ïj.— ³×ÐÐ�¿|òä Lä+++Y,666ÉvIIÉøñã¡°¼¼¼'Y}ÊÊÊ~~~yyyÐÄ€ºº:÷yþü99±¢¢BOO®ÖÕÕAM‹ŠŠœ¡ð¯¿þÔ““cddª  hª ð³�MHcc㇠ðÍ›7@íÅårÞ¾}¹3üñÇ---®®®øÂÌÌLsss/€ÅŸÏÕB°M j‚G```VV^ ±¼¼¼}·nÙ²EII l\II Ì»³³³A¼ }ea) 6‹ËåBaNNÎË—/{2@ׯ_¿téRMçëׯ ¡©³²²ð—Z[[KJJà)MMM°VÀw«––¼64,^½zøÎËÊʆ …»v퓚——§££“¤ÓƒÆðû÷ï»fØ´±±ñóó À ^¸¸¸P©T Gª¯¯‡�@qq±££#ܶ¬¬ V^^^ =?^æ�üRø.—ÛÚÚ …aaaPå L:?GiC‡ ü]$¡…¦šššŸŸ_vv6a)£  Ðþ­Ðp277‡«ö²uëÖææf]OÿþýÉd2ŸÏo//öå=pà@P%<W[[&ˆ7oÞ$¬\Ÿ?Žÿú***444 š (®óM°iÓ¦¦¦¦özööö‡nOã‹·µµµ„¥çw9L&ÓÈÈÑœœœA›ÙÕÕ‘Ãw¢¢"---¼(PBBÜD^^\š””ø›´´´K—.?~üK÷F322Iy„ñãÇ×ÔÔÀ»Mš4 81ñ³†#GŽÀÕM›6áç/K–,yõêU@@@×êpåååÓ¦M344$ŒÝÏ0¡š””4tèP êBò3]T‡•••‘·Þ¶mÛáÇ¡²[¶lájD6wîÜÇ…mdx!êîÝ»sçÎ…ÙFBBþ’††ÆÑ£Gáµñš¶÷îÝÛ±cÇìÙ³ Z–í±qãÆÇûùùõŠŠ°œœœœœ‡ÃÁ«‚¢EÀ®]»FÝ7°ÛRx¹\.ÔQ__? � “““¡ÐÞÞ¾‹Ð%‡Ãáp8°Fìú¡øsl²²²Há‚N§566þêîÝ»ðóæÍ#|;€?ÿü3""âðáÃ@n ‹B¢?¸vkkk‡~±) (är¹„r×ÚÚª¡¡æ…7n<vì4† ð>ûëFoûóFyyyß*—êÓÒîß¿ÿöíÛðððððp‰„Æz˜={öñãÇ544x¸ÉñãÇñ~ëÕ«WÞÞÞ‡*hPF±éuëÖÕÔÔ@aHHHï6GrrrBB¼›®®®ŸŸþê… ´µµájrrrbb"ò7nnnááá6l�³òðáÃ)S¦˜™™á'}UUU‹- _·n¬Ä‡ ¶xñb¨KO¢L=„““Shhhxxø¹sçz¢{TPP@à öóóÓÕÕ…Ê&$$$''£KóæÍ[³f L#?~loooff†ÔPÿý÷_¨—³³s¯Ú_~ùåøñãðnøí@Xsìß¿.-Y²y—¨¨¨{÷î…‡‡+++ƒ¶æòåËÅb1¼$~ÏlÓ¦McÇŽ ?rälç¯]»~Ù»ÒU{öìÑÑÑqvvþ¤S{l6;==ê¸iÓ&h++«gÏžAá Aƒ€ƒyîܹêêêðæxïûhllìšZxÒ¤IIIIðÒÒÒGŽ!ü`×®]úúúááá7oÞìÖ—ûûûgó÷‰°°°ŒŒ ÂôåâÅ‹ªªªÐ©©©„]«ïãÇ¿wï^‡ç^õôô<£¥‡Ë‰Þ\åt6ìòõõõÝú›­[·6Œ0G+//‡›Ðh4´ïíééyñâE¤oÍd2çÌ™Û\—/_†Y›ÍÞ²e Ð3w;]ÅÃÄÄÑûõ뇼 RïF§Ó ö…Çãõë×®677£8ɱcÇÆG£Ñ>~üûUjjjáááAÃŠŠŠ7oÞTTTäñx ™-%%åàà�´½%îÍ µn³oß¾˜˜èéé‰ßÓ‚u‡ÃA•E«Ÿyóæýúë¯Èß@e#""D"‘P(nZ2™<hÐ Øbyýúõž={zøæ�ÑUhU‚þÞ¯¨¨¨@`° …\.^ûíÛ· «aظqãöíÛÇf³i4bþ^·n|Z{÷îÅ[ÆiÓ¦Ñéôºº:$¹}ýúuèY˜}÷ öíÛ§¦¦6oÞ¼O=ÏK&“ñß K¨ÉdBœPFFféÒ¥ùé0Í™Ðq÷îÝ…,Åbq×c‰Éd¢ R©ícJ[¶l™3gœ!ˆê¶‡††ŸÏ'tî÷ƒ;wîÄÄÄìÛ·ðÕðx<YYYh>Ÿß»çö{Åßœ={ÖÈȨÃ%•Jµ±±Ï699ŸIôÍ\Χ¢¦¦fΜ9àoêêê† ’™™Iè$´ÖÛ¼ys`` ¬¬,aI ¤¬¬,ZÈËÊÊÂÏ>é[MLL„†îuÚ…öçÈ`�œ€B¡´?œE§ÓÁtvèørhii¹zõ*ˆaƒ!`±Xk×®íðÇóçÏ_¹råèÑ£ s¨,>yŒL&C½@q¼çÑgdïz—UEJJª} ËÈÈÀSð“>99¹öÑQ¤1Ø[ƒçÀŠŠŠ‹/î:Û!x<žòÍ€”””ãÇÿûï¿í=Ô®=}=ÂÉ“'QjO‡ŸgOp÷îÝèèhüÎ(,«'¬¥¥eBBBoû=€Ïçûûû‡……Á¿E"›Íþ<Ù¤¯ .—;iÒ$í­­ÆÆÆ„ü^*• Ÿ-š÷ãÀÚgŒÂׯ_geeeee©¨¨$$$< ~rÚÜÜL¸†Ïsxyy>}ú3^Fþø ÆÝÒÒ²'˜§OŸöŠ ã³³sQQôÑæÍ›W­ZÕ…HIcc#ƒÁ ø›AƒrF>|ø�¢;Ÿ &“‰ºéKŸ?~üxû´½1aÂBÊòGss3™Lþ ó˜öI: ýæÊåË—»N@s8ÔìŸÍûÒÚÚÚÔÔôß[ƒ¾sÛíè舾eË–u6Kû®’’’““¯M§Ó_¼x¿ ÇT¾ô;tïrðÓº… Âö#†a•àÀ¬¬,(œ9s¦ƒƒ†aNNN))) Cú P(L&Ö%%%ð{[[[”¹„nÂáp #vúôé666PòîÝ»?ÿüð­[·VWWCáðáÃ!}ùòåþù !ùIa ôïÉ“';::Â}²²²à¬Œ¦÷îÝ›——W§L™š»‡‚B???P¨{ö왵µ5‡ÃQSS{ûö-DÕ¢££ág«W¯†X›¥K—Battô‰'0 [¶l™ªª*ÊÊÊ®^½º'UÀ¯”ß¾}«¦¦ÆápFŒ)d÷<tèP`` LV®\I¥RQÑét:¶ß­ŽŽŽÞ$‘H3fÌ@ÝWiiiVVVGKK ë())Áo6lØ�’©cÇŽ]¶lÆÅÅuçi‰„¯àË—/mmmñïP__B;ÚÚÚW®\K{÷î…Ý>‡™3gºuíÚµmmmPhhhçÎ †B‰ŠŠZ°`&%%ÁĨ¨¨JìííñÙ˜=¬™Lþã?PK‚ÔìÍ›7= %gΜÁ'úãÿV^^>..~¶|ùrˆ„@Î1Þ½{¦e .D`0x³H3Ý~l6»=gþŽŽŽ&L@®ÎËË Fõ¡C‡^¼xW]]]ñûê„–ÉÍÍ533ãp8½îé»@aa¡‡Ã133ËÍÍ…ïÈÆÆ¦Ã¡P(~5»víBÆm„ =Ñ>ÿÒÀ7/“ÉD¯M&“aùËårŒa˜¾¾þ±cÇàå=Ú[)NÄ÷‘H´ýˆH´}ÿH´ýH´u;Œ%mH ü¸ $@ ¾:ÍXë3jfø°@«™Lî35‚˜g_ꣾZ#‰qøÿªF½¾Ñ©Ëùþ“Fz”ÞÓg*ÕØØ( ÅbqŸ©QKK ŸÏ—––î35jkkƒ ®>S#±XÜÇj„aX}}=œŸë3•jjj‚”÷^©Q[[[·‡¨zÁåÔÖÖ÷¥Õ€P(ìuª‚o[£úúúGõ)C‰#û“ˆÀ¿ó >Ÿß—>%àŠícÆ¡¥¥%""¢Ïä‘Éd oÄsŒý—WVV644ü².G^^¾ïe¬Íœ9S’±öÝB’±öCøÈXÃSbÿ而µ©S§J2Ö:Ɖ6 $@ ~Ht³òâñxïß¿ÇëjTVV©µ††ò¢EEE@ôdhhˆ¨A�ø3ÉC‡¥P()))(Î(%%‘áÜ¢œœpûcöáà¾WUUÖd ÃJKKÁëöïßyssskjjÐSÌÍÍ{H˜ÑÔÔTTTdjjŠJ>~ü˜——‡a‡Ãrk„’’¼ªlNNl 4Q§¤¦¦X¹Z[[ḯ´´4¢ûäñxJRTT$hü¼{÷ŽD"©««w[‹W¯^á§iÀÂI¥Rô Ã°æææW¯^Á´ÎÄÄÿçUUUx9---uuuBe �LûÙÙÙÀ­‡¯ìóçÏ…B!‰D>|xg•­««ÃŸ%TVV†c³=Avv¶¶¶6žœ"-- XÀ‡Ž_¼òù|¼,ª,êV={å]»�� �IDAT==¸úöíÛwïÞa¦«« §›1 ËËË‚2DT‘žžq?+++|¼B dddXZZv[…ÊÊJ>Ÿ\A-l``€˜ÐXÂaTY<Ã[kkkNN¢Ríl,½ÿNËjjj÷Wqq1ž…ÈÈȨ3v“ÔÔTKKËÎv¡KJJЪµ0@MM .Ó™•ÈÌÌÔ××ÇsÁp"“ÉŸÇañÙxöì™H$¢P(íž444€L†¼¼<²‡èÃQWWG¤ã¨[õõõñzBß YYYºººˆ> %ÁZ¸©©)##£C+ñÅ]N]]]zzúË—/üýýÑð½u뜜9rä‚ ´´´ .]ºœ»ŽŽŽ3gÎÄ3‰­Zµ 8àýýý¥¥¥§L™2räHdz.\¸ÐÔÔ Dr:::¿þú«©©iuuuPP¨XYY-Z´HOO¯¤¤äêÕ«)))†9888;;«¨¨ ªã—/_Þ¹s§3Ý„–––gÏž]¾|é÷q¹Ü N<xð’%KðfñÁƒH>òõë×G6mZffæéÓ§bàçŸvpp`2™ÉÉÉGŽ#åáá1jÔ¨¶¶¶˜˜Ð6UVV^·nÝàÁƒy<^XXr›˜˜,]º â•••<xÐÀÀ  O¨l}}ýªU«îܹƒ\rBBo3Œ-[¶X[[777GFF^¼xLÏêÕ«ñ ‘‘‘ýõ2Rnnn®®®gΜ‰‰‰QSSƒÂ;vX[[gddœ>}ÌôÒ¥K'MšÄ`0’’’Ž9ÂçóI$’‡‡ÇÈ‘#ÛÚÚ<x�"˜***k×®<xpQQÑþýûÑ·:lØ08—ÞíóñãÇß~ûÍÇÇ‚”””cÇŽ¿ËÖ­[ÇŽ‹~_[[‹žRWWÇf³Ã¸\îíÛ·¡ï,,,–,Y¢¯¯_VVvíÚµ§OŸbfggçêꪪªúúõëóçÏÃáó¹sçN›6Íf§¥¥ùúúœfݺu¶¶¶°…& £¢¢¶lÙÒþX>ÁÙäææÞ¹s‡J¥îÛ·ÙßË—/mÁ´iÓœœœ”””233Ïž= K–,™<y2“ÉLII9räDº»»=Z $&&VWWïß¿QÁòx¼ððpPŠ366^ºt©‘‘QEEÅÍ›7ž`ôèÑóçÏ×ÔÔ<qâD||<µcæé鉿%)))|>Þ¼yyyyà AZZ|¶MMM©©©yyyH™÷ñãÇÈÏš5 t /^„IÏÌ™3gΜٯ_¿W¯^ñx¼M›6]½z¸¤¤$ooï¶¶6 …âîîN8ÿÿ嘘èåå% i4Ú¶mÛ€lù›;wjÿþýW®\ibbRUU�ÌÖÖÖnnn:::EEEW®\N™:uêìÙ³¿¡×ÉÈȨ­­Ý¶mÛßÿÈ…çÍ›§¯¯Ó&äŠhVyéÒ% ôµµýõ×O¢qù¯.§¢¢Â××—Ëå¢Ùö?ñ°È‡ ؼy³ŸŸŸ‘‘pñ.Y²D]] qzæÌÂî…B› p¹Ü¤¤$(Œ‹‹Û½{÷­[·ž<yòòåK(<sæ Fýûï¿`Gàû‹‹suuE”Ò©©©.\è 5!Çóõõ%aƒxÜüâÅ‹ÿý7^wdéÒ¥ w”}åÊX`íܹsÛ¶mð)Ž9rРAúúú~~~ÿü󬬬X,VSS{ÿþ}]]Ý–-[@ú);;{Íš5>|ûömqq1<.00Ð××÷Ô©S°Œ»yófRRR·Ú¦×¯_/,,įð0 ›={vEE0IÛØØ¼~ýº¼¼ÜÛÛÌëÓ§OwîÜIH¦˜:uª··7áæ«W¯Æ[ ‚‚6lØ�kPkkk ]]Ý… ¦¦¦‚D›––Vyyymm­»»;¬Y3226mÚôàÁ ¨iUUUPPPÓiBCCÓÒÒÀÉá;"&&ö±8~ÎÎápà)uuuááá0ïNII‰GÝêçç÷×_¥¤¤ôïßûöí`Êïß¿¿xñâÇ;::‚"( 6ìßÿ=xð ,7õõõÓÓÓeeeE"QtttOrrrNž<YVV†gy‰>|8°Â¬X±X…víÚµaÆ1cÆ€‡077744<þ¼ŸŸ¬· ²---¾¾¾„<¢wïÞ@AÙöìÙ³wïÞ­ªª‚Âýû÷ƒþæúõëÝÜܺxç .p¹\¼ uSSÓÂ… !äðñãG__ߺº:BöÊøñã;k³gÏš››ƒÇõöö.**êׯ_```vv6,}ð¿¼víƒÁàóù†††x½ó/Š9sæäååD›¹¹9žk§  àÂ… =uàÀ«W¯ÆÆÆæææ¢OJJÒÑѹxñ¢††®\¹8À¾•Ë ÎÈÈh¿ sýúõ×µoß¾=zô(.ÄÇÇïÚµ ˜±¾’Ë122 |øð!~ iii#iØFâããa¤ÚÚÚ¡X,†›ÐétkÒÒÒòöö®­­MJJª¨¨è9§;wîÜ»w/! Ö!8N```ff&ž9”ÃᨪªÂ»ÕÕÕu¶•}âĉ‰'vÁcZèÑÑÑÀÞÞ¾³Ÿ™šššššVUU¥¥¥UWW£•YXXXKKKúÓ^^^†VÇööö‘‘‘$‰Ïç÷P·´´j­¯¯æYYYP8xð`˜ƒ‰LLLäñx–––ŸG÷›ðòåËÊ·€î ÐÙáM[BB̾;SÁ*((¸zõj2ÆÀÚ’››[XX(##Ó…°>zô¨¹¹y̘10CË—/OOOo/»NÀøñãÇïç燗hC‚ßÊÊÊhÍÑHy3** Æ’¬¬l``àÛ·oñ^ôôô„EUee%šÕv6ÿ…–±´´ÄÏ) wðß•J…OÊiiiõòòr¸­ŽŽN‡a™W¯^•——/Z´ ª þ‡�³l*|–ÉÿˆÒÒRíBÕû[ÆCûäÁƒ£>Ìïk/‡�˜âž•‰‰IO’‹ÆÿèÑ#øw}}ý¬Y³¨Tê”)Sà& C(¢Fár¹7nÜPQQs ®®®¬¬ S†ÌÌLXUA!aôôéSØrø<hhhhiiÁ»õïߟ þ‹bYÊÊÊHdäÈ‘¯_¿]¿o`` ŸÏµ:>vìXxí²²2‡zãÆ ---¨uQQŸÏ711?ýpuu½yó¦X,¦Óé=QHÓÑÑa0¨[œœ `nn…………NNNÈ,FEEÚÛÛC€ØÁÁ!::šF£!ñ))©1cÆ@eñvb³ ›øÙ˜1cF`` Ló m(¤öêÕ«Ñ£GÃÿªªªª««Ãû¼zõ ¿é•žž1xð`M°²²Bëx‚ dXX؇¦OŸ.çîÝ»ÉùôéééÁÁÁÓ¦MëV†çîÝ»W®\évÇ($$D$¬®®nEET'77h e=[\\<kÖ¬½4­ëD5uuõ~ýúÁm œœœð[¤ðáäçç—””999uýÐðððÐÐÐþùç{ö7%%%AAA/_¾422rrrB;Ðß3&Mš²Ä?mÚ´ïÚåÄÅÅUTTÀŽË¡C‡"""ºÞiÀ0 ¯a Nš4‰Íf£‰LUUÕ„ `à \ÚåË—ãââŽ=zëÖ-kkk‘HÃ.//fC³gÏ ‚V#Øn///ÎÖ^(j)%%ÕY xZZÚ³gÏ ‚/^ü÷ßÛ ú^¼xÑÆÆÙˆmÛ¶y{{ƒÂ!LwîÜ9Xc±Xýõ¨óÔ«|ùòåÀÀÀóçÏoÙ²åöíÛÚÚÚÎÎÎHõS±lÙ2B`­ëß7%òzyy…‡‡oÙ²eÁ‚Àç {TºººÈÂÂìÉÚÚzÔ¨Q222'NœØ°aCSSŠ•±Ùìýû÷ƒÎ)AÄ!55õùóç™’ôôt$;ommÝÙÊcóæÍøÀZ{¾Þ²²²Ë—/ÃÌåE"ì-â…......îîîqqq‹/^µjÕ™3g`t\°‰ëëë;88DEEAT  >4¶··ïv»âÿ°wåñP­ÿÿÌ0c_K“ÈZé¦]%‰íh¿¡•ÒJ´SÒmQJË• ¥Ü%•¥DD–ìe߯>f,3fæ÷Ççõ}^çuF“6·ü¼ÿªçŒsÎsžåó<Ÿçóy¿<xðøñãË—/ ò§Óéááá|>±›˜˜ðù| .((�“cccƒ´b׬Y£¥¥%&&†¼[³gÏîRÝ£­­mëÖ­B¬ìĉQðÈåË—CBBÒ|G500°²²ÒÒÒ²û¿ÿ~dd$¸ ~ñ-F 8{öì½{÷\\\~}“sîÜ9øÇSQQùÑÏ?Åä|?~<mÚ4B'”˜mnnNHH af``�Ò××¹ì---aC°uëÖ¯²—0'ÊÈÈüج#$óŽb"îÝ»7þ|‚м¼<([ÃY¬I³³³ñ¾¯¸¸¸¸¸¸åË—ß¼y3##CTT4''ç'…Žà}Pg&Ïáž?>zôhØnâJp–%ŠŠŠPY8Ëéæ› VÖÔÔâìúZŒ7ÞÇßß?//܆<O0Ìg1 C ÀÇâ7mÚtæÌ™›7o²X¬¶¶¶ˆˆˆ¯¥©OKK{ôèÑÌ™3¿è—»wï^llì™3g„ Ñétð¼Ô.LMMÁ=…¢*’““ñÒŸïß¿‡o‚a˜àhíþü[^^ކ€ ¬­­» pçθ¸¸oÓÄêaþçzW_ ØU›PÓïarŽ;æïïOèÄÛ·o'˜œªª*OOO‚É)***//‡ÓTüX¥P(‚¡ÑÑÑzzzBvëçÏŸÿþTÐÄÄÄþýûã‡kTTÔüAx®‹‹ËŒ3ðíÚÑÑN6ü ëããƒ79Æ ÓÔÔÁÇÊÊJ2™\SSó³MÎëׯ333 &',,lذa“sîÜ9‚ɹ}û¶……¾²mmm>ty•—— I\ºté÷§‚677ÇÇÇã=eee?~$œ<}ú”ÃáLNll¬††ŠýxxxàM޵µ5´QGG‡ÃÉÈÈøZ“®ªªŠ\BàêêÿE=ÍÂÂÂgÏž¢Brss Ú| öÒ××Ç÷aˆ)øN¤¦¦FFF 19Ý„³³sfff¯¡ÕøÕàââ‚ÎÔ“3bÄˆŠŠ tž ù4S¦LÉÏχÂ!C†Àp}øðá„ h4ÚÒ¥K£¢¢^¾|‰aØòåË¡ªýõüžËåÂ2AAAÁÈÈ ÛÚÚÀö0ŒØØXˆ@e2™àË¢Óéééé|:Nð2W®\qppè~ªG—ÐÐÐ2d¼ƒÁ€ñ“––ÆçóáøáîÝ»zzzxÏLiiinn.Ì&&&rrr௠„rëìì|ÿþ=x™Øl¶……†aÊÊÊ£G†Ç1™L###´«×%…B!L”Ý­­-¬èy<&ÉÉÉ™˜˜ÀƒÚÛÛá4¾¨¨èÓ§O&&&Ç///‡«|>²LÍ 'ÉóçÏûö-„ºÎš5 V×®]ƒÊ®[·šõýû÷GÇf³QÐNNNNrr² Xò×bõêÕwïÞ…Y bêØlöíÛ·áLžN§ß¸qo�---qqqúŒšu̘1ÉÉÉPAyyy°ë•••©©©pF5~üxðÝ-]ºôéÓ§à¦[¾|9…BAÑ} /_¾Ü¿ÿ7Ô"!!­LMM‡ bff–šš ÞØØ…Â+‘Éd;;»ÏÝ5"†a:::ÆÆÆ/_¾„D%Hâ™6mÚ§OŸà—C‡%dÏ|T*Tì>‡!C†¨ªª¢±AÆ)))¢¢¢cÆŒ™:ujaa!\ÕÑÑþP˜(¨TêÚµk{f*\»víõë×I$ŸÏÇ#ÄF¯X±¢ÿþðò­­­àÔÑÑùøñ#²ÙlpZNž<ùÇP¨ªªúÓÑÏ€••ÕíÛ·ñ£µ½½ýîÝ»þù§¼¼¼±±1aþáqssƒÅZ~~¾¦¦&›Í®­­…� .—+))‰¢_TTT¨TjJJ ƒÁ˜:u*D° 6¬®®RØ–/_g†¯^½RWW—““›<yò›7o Jxß¾}ã4sæÌˆˆƒÁçó!JUZZzøðáÏŸ?g0ÊÊÊ0 8PVV611‘Á`Œ;üÈÚÚÚL&3++‹Á`,\¸Ÿê¨§§×e쀸¸xrròèÑ£w9„Ì/%%¥~ýú%$$0ŒÑ£G/Z´ðüüüöövÈd³Ùšššøô̱cÇfee•––2Œ­[·Â`úôéQQQõõõ N³¨Têĉ### †´´4¸UUUãââ ÆÐ¡C { 6›­ªªJXq£ñŸ››K£Ñ`&jkk›8q"J¦311¹ÿ>ƒÁèì섘"III]]ÝgÏž1ŒÀ´UUUURR2jÔ(|³N™2‚&ðͺtéRhÖqãÆedd”••1ŒíÛ·CΑ‘ÑÓ§O˜L&ÄÊS©ÔñãÇ?yò„Á`ÈÈÈ 1J.—+%%ÕeÊ”¨¨hee%:uy0fÌ´W644|ñâE]]|^8ŠŠ‚ 1¸OñK{%%¥þýûšºzzz:ƒÁ˜;w.,hôôôŠ‹‹?~üÈ`0à ¼» Ї]]]ñI‹|>ŸÃátéa2™µµµp“ÎÎN<W›Ífà0|øðŒ;6;;»¤¤„Á`888ÀÖ¹µµµ©© ~ÖÒÒ‚öÄ|>ŸËå¢ —ËmiiA7”““9räàÁƒEDDÞ½{Ç`0¦OŸË—#FÔÔÔäåå1Œ•+W 9ôf±X†††`ÚEEEŒŒÈdò‡`'Êãñð¹Æ4M^^ž0Zsrr¸\®ººúðáÃét:ìºV¬X߸·¶¶Ž?å*²X,TßÖÖV|ÒÕÏ€˜˜XZZÚ°aÃfÍšõðáæ¦¦ööv nmm}õêÕäÉ“eeeµµµ_¾|É`0 ¦wРA’’’oß¾e0“&MBv¨¹¹ùÇ ÃÜÜŸ¨Ûc R©……… 0^ÚÚÚÆŽ‹öèhjjii©©££ãÅ‹p.;räÈèèhƒA£Ñ`­,""Âçó™L&…Ba0§;ÉéèÛr8*•Êf³ù|þ›7oâããûTAKôq¬ýúèSý-Ч úÅnܧ Ú‡>ô¡}ø-ÑgrúЇ>ô¡=„®ÃÈd2ÞaÝ †‰‹‹÷á?¨ˆ˜˜X¯i&80 P(½¦FÐF"""½i(q8‰Ô+'‡/Æþ^C‰J¥þf=¡Ÿnr˜L&ä6öðx¼ÄÄÄ^s–ƒaXSSSVVžúwGee%…B²Î^ÓFÍÍͽi(±Ùìööö^69ttt$''ÿA³_uuu|>¿²²ò‡ÜMBBâ{(]þ?îr$$$H$Ò·‚ýš£P(½i—C¡P{Ó ZDD„Ëå2™Ì^S#‰$--Ýû&¨Q¯19bbbT*õGM¢¢¢?vÿ×õWÿYê¾rrrqqqC‡íMk………jjj½)b­µµ•L&÷šŽkL&³×Ô"ÖÒÓÓ{Óä ++ûöí[mmíÞ±VVV†×3ûÎnܧ Ú‡>ô¡}ø-ñ…½dVVÖ³gÏðYÑÑÑAAA†-Y²1Ë^¿~ø¶lÙB ÒwssÓo^ºtIBB‚ËåB⫝̸œ¢™+)) ¬Q£F9;;Cáëׯ!vΜ9ˆÎ($$tÛlmmQ¦ØéÓ§A&îàÁƒÝOú---õ÷÷žJÀÛ·oA´fæÌ™ˆý!((ê6oÞŒ˜=?ԙǎ†éíÛ·#:K ……;vìÀ0lðàÁˆí4++ RÙ ìíí¡ðÉ“'ÀÈ»lÙ²îP½îÝ»w÷îÝø$ʵk×òù|iii¨ †a 0|øpÿ`ll,žgséÒ¥•…˜1Pf¥‡‡¤ñ#  Ã6mÚÔÚÚ*""‚îÓÐÐ�ÝF]]Ñ;fdd�9æ”)S6nÜØýnzìØ±+V8Z€õÚµkr”ªª*È/ÖÑÑqssƒÂääd ÃŒ!¡ýÁƒx9¿þú 2%ÏŸ?Ÿ’’‚a˜‹‹ J“ܳgH=^¸pˆß;;;!WN^^(æ„#::º¶¶vÕªU¨äÆÏž=Ã0ÌÞÞetzzzû€»»;¢˜Û²e 0ÆBz<Ö×ן8qÔ+ðx÷î]RRi-""‚D"A,àòåËúúú.6oÞ|öìÙÏ‘£|úôéÖ­[H¿� À¼yóêþþþ111Ðv(ôèÑ£………†yyyáY£lmmýüüzx6´³³ãp8âââ‚Ê?~„n<fÌèØhj ù088”u6nÜøýô?ß#GŽØØØ Œr4pðSBYY ™#FÀ ê9“SPPpàÀúúz¼dì‹/^¿~ Ã&==ýþýûK–, `0Px÷î]2™ŒŒ‰‰Y·nš›€šÐÆÆˆX€žöüùóååå^^^p“ªª*///ggç7oÞDFFBavvö­[·V­ZZVV…ÑÑÑd2yÚ´i§N’——‡Â3gÎ8::v™´Nß¾}{KK è-¢ázïÞ=¸O^^^`` Ò5{S__W#""@ÆÌ ĸ»»<xpàÀOŸ>uww‡¹ "—ZZZáo]]]=<<²³³ýýý¡°¨¨èÒ¥KöööOŸ>MIIÂÔÔT‰DP‹ÁÃÕÕõÓ§OñññˆŒÃ0kkëU«V^P#WWW»»»Ã=kjjŽ;æûööv¤ÆòMMMð'÷îÝ7nœ‡‡ÇàÁƒ¡}9räÈ‘ØÛÛÏ›7J¥òx<` innvvv†¿mhh�£¬¬¬ÀÀ@(• 6|±ƒzyy¥¥¥%%%ቇAš\Õ666x:~øðax Nwwwwss{÷îÝÝ»w¡0??? ÀÆÆ¦  €J¥¢¬F°gçÏŸ§R©ðËË—/oÞ¼YGGÇÙÙyüøñ˽eË–K—.‰‹‹¯]»úpkkë¶mÛÐÊIqqq¾¾¾¥¥¥x2½àà`d>|H&“'Mšäéé9pà@à‘:~ü¸››Û AƒfÍšþtkkë   ‹egg×ÞÞ.(_öþý{gggBçðà‡‡ⶸvíÚ³gÏ222ð,ïlÙ²¥¾¾þùóç°D€jîÞ½ˆ”***›››ñ:{••• ÀW‹aRûFö†ÉdB}CCCÉd²¾¾þ‘#G455a‘zàÀþýû¯_¿žÉdFEEõ°ÉY·n¥¥¥ˆˆ‡ÃY¿~=ÔP\\ìíí /_^^~æÌ™;w–••1™Ìõë×ãûÏÍ›7ét:üòÑ£Gd2¯.ÚÃ8vìXfffbb"^&îéÓ§ø© ߂LJ—¯®®öôôüVç³&hQÒÓÓAòÙ@‹Â>ééé œ—““3lØ0(¼}û6AãÃ0CCC;ä³gÏ`š`³Ùp6°JЉ‰uÛêê꺺:¸sQQÝÈÈÈ@¡ºº:„R¤¥¥ÙØØ€îÎßÿMЭé222vvv%%% / ¨©©©®®†›WUU!"}@nn®¦¦&\ Îãäää3fÀr‘L`fbb‚óÿ믿€Æ1;;ÖG ÅÅÅpÚš`Ë/))éèè€BÊR‹%K–€6 ¾0*** �Ä @A€Åb¥§§ƒ vBBÂýû÷ ÷QSS#è5egg£fUUU…èÛ·oMLL`<x°µµðçÏŸ{yy*(Pé°ÙìÄÄDX@µ´´€ºv}}}ii)Ü0444>>¾;tΜ9ãÆ#Ì­111û÷C؉¶µµ¥¦¦‚NARRìcèt:jV===§­­M¨õÌ™3 �ûEت¾~ýzÆ Àæ')) Ë&Ô‡«««>,¤ :::vvv±¸I“&‰‰‰Á>&<<¶P)))HÔÝÝÞsÕªU“&MBk5 ÃÄÄÄìììêêê[œŒŒŒÀÀ@SSSÐB<|ø0##¿ œ:uªººº mooÇ·Qgg'ƒ——·³³+,,$t¤Aƒ}Nõ+;;[OO®ª¨¨€ÀyRR’™™˜777XüYYYj{OÐÑÑѾ¾¾  Š—mÄ0¬¹¹977¾XTT¸y`\ê;qâDÔ¬÷î݃fý¯`ff6iÒ$AÙ-SSÓ.UAåååmllÀyÿðáÃÝå�$™LÆ›œ9sæ477Ãö|Ê”)]ªc bÓ¦M-¬—†µ··/_¾\^^þ‹ªS]âêÕ«<غuë7³,KHH˜˜˜deeáMΤI“*++¡‚cÆŒ!,ÃmmmÙéÈ�� �IDATàêÂ… ñLìNNNyyy>>>(.nõêÕ0M€@…B™6mZMMÍúõë•””Μ9ƒwå¹»»OŸ>ÝÑÑð ܾ}žbhh(\ †+!ïîÝ»@l,..Ú?_Ä£GÀ¢¯\¹ÏÇ~îܹèèè={ö|ƒ zUUÕÆ555»ãwú€¥ t9üüü¶oß3rXXþFsuu…¯§¢¢‚ûÁxêÔ©¹sç"§Ó­[·^¿~ >ØJ•ÜÑ£G“““W¯^?'·³³£ÓéÁÁÁàÇ §HII WvQVVVVVþôé^­ÑÑz{{?^ˆ„b›¥( ÃDEEMLLÊËË ¿lhh(//711Á›œ²²2‡ƒw56lذa¡¡¡BÞÞÄ%))‰¦Z)))XQLNLL hùÇ™3g^¾|éââì|]\å¿E¤OTTÔ×ÒÒVЬ/^|òäÉüùó»Ãþó�®4å"¬^½ZTT”D"EDDàË%%%ÁÞäää„„„€pOŸå––VWWÞÛ˜˜˜×¯_4áëë kap—߸qCRR’Ëå.[¶ÌÍÍÉdZYY¡®ÜMøùù­[·ÎÕÕ¼[]jw~òóósrr ‚ÉÉÉQQQè|¶ýû÷‡«aaa¹¹¹02wïÞ½téR77·ãÇ«¨¨Ü¼y“ÃáÀ_-\¸$¿`áêêZSSãççwþüyp建ºfffž:uj÷îÝ)))L&ž˜˜øµ”Vžžžàmkk;{ö, ÁܹsÑÜL°77ntuuOHwÄNjkkwïÞíêêZ]]½}ûöï±:‚8þ¼8Ž9‚g~ljj ƒ¯WZZzãÆ Pº‹0`€««kJJН¯ï¦M›V®\‰&zð êÜåË—Ïž=Ûßß___¶­vvv...òòòÖÖÖ7oÞ”8yò$=¶´´øøøtÓ´pîÜ9111KKË~ýú ÿ¥……ÅîÝ»…X¦¬¬¬ÐÐPt4‚¶8t:ÝÖÖööíÛßùÍ;::Μ9#äpbúôéhù{\éõÙ³g¡;ݾ}[DDDø1Ò¯SSSä<|õêUPPbÚž7oÞ¸qãîÞ½›““CÐ^ùÏqëÖ-˜šø|þ¢E‹`AL˜Ásø“4S¾ÎäÐéôööv°„111ÝI5ÂÓgddtvv‚ÑÝÝý?þ ÓéÀ¬þU˜;wîêÕ«•””nܸAnÞEÀõ,//Þåo ‚ÙÙÙH· PZZª©© W¯\¹äü°Fž;w®””ÔÎ;!S -óù|Vˆ‰‰Mš4);;ír†º}ûö!C†”••¥¥¥£†ÃáÀS¢¢¢¾!<199yâĉàXƒ{ Ç€P°ull,jVssóeË–õë×ïÒ¥K¨²Ý„¼¼¼››ÛÈ‘#333Á¸v.\€Ãs Ãöïß?ü œXèééÁ;ÃQ?~fÌÏÏG‘h5£§§·yóf Ô¬ƒ BGŒwïÞÅ;„Á�=z”ÉdBÉîÝ»©TjFFèm§¤¤ÀSª««¿¡ƒãNTT¾°ð_š››;;; «ÎÉÉ9{öìÞ½{µµµ‘Éyüøqbbâ¦M›húçàè蘚šŠ]º<år¹è7]BQQ½áû÷ïÏ™,,,–-[¦¨¨ˆ<–¿5ú÷ïöjoÞ¼Áo:544444®]»ÖýÙ©Ç€¦&‡Ÿš�Ÿ>}òððpuugøor¾k×®=|ø0¡“H¤ï¡õVQQé’â^8¼½½a·þÃs¾tttõ:`ñâÅAAAxaºææfÁC™ÿ\TãÁƒ‚šâƒþâlø9P(”oà„¶´´DaK?$«�oAD�!00Ë墠 À¡C‡Œ¹ŸGŒñcU­.\¸ÀçóW­Zõżnssó={öLœ8Q]‹ÅŠŒŒ„°I ýwwwWWW¿uë‰ÕÖÖ‚•íRÅrË–-è|kàÀßV£—/_ÆÇÇÃίK¨©©ác‘~w<yò$==ÎJ.^¼¨¤¤Ô͇ÿ‹- Æë "”””ìÛ·ïØ±c?uFúé&§°°Ífÿ ßzÔ¨Q=æ ÎË˃µ0Bgg'Äÿ‚hllìy ô.1pàÀ/¨««CÎO„òòòîÄž|?ª««UUU»Ã#’——§££#œPWWL ¸ž={fgg'!!Â¥üüüH$ÒçD·ÆøÛÐÜÜ\QQý¿ASS“ ›§ººú×3œšØlvyyùÏ^ɱ´´d±XĹråJÈKpvvöòò‚Â={öÀ qýúõcÆŒ ݰaì:ÃÃÃÁÿþæÍø½‚‚§iii:t ÿøãH¡˜={vss3.Z´ÂáÎ;…[·n…SßÓ§O»¸¸899avòäÉoÎŽž1cFSSÜ|îܹôÏ?ÿðx¼ 68::ž<y®:::‚BÝ¥K—víÚ'ÒçÏŸ¹ÃèèèE‹µ´´H$ˆ¿PPP†¿ÕÐиyó&†aãÇ·²²‚ÂéÓ§CàÓªU«®]»…VVVø(ínâíÛ·cÇŽåóù222E¤¦¦vâÄ ¸ç¨Q£  ëÅ‹QQQžžž¨YW¬X3øfuvv†œ•+W®ìܹη.\¸�‘/^˜™™±X,‘ÄÄDð±Àßjjj‚wkÒ¤IõõõP8cÆŒï9œŒŒŒ\±bøú€ï‹Éd.\¸ðåË—***gΜ§Œ1B]ŒŒ›ÕÖÖÖ×× 7lØ�fžžžû÷ï•O' [¿~=̧¬ñúõkø[EEEÈûZxyyA !†aÿý·©©é… A¾ÏÛÛYccc09¢¢¢G"@\\…æççKKKÃf÷ë×D"}S–´´4ŠXë³gÏf0ðM.\›f___ˆÕtqqñôô„«{÷î…?§¯¯/„±ýWxõêÕ´iÓ /'66ðªª*{{ûˆˆˆ#F8::ÂË?‚Y,XÐÒÒ…–––Ðj;wî<}ú4îÚµ Ùÿ‹àùóç ,`2™d29)) Vœ+V¬€\¢‚‚xy æNŠO´úQø‚D[GG‹ÅÂo‡Y,,¥¥¥Ñî þ&VH ¨¯¯—‘‘_Dmm-áÐh4´Xƒe5™LFއSWW‡a•JEþœ¶¶6pûJII!?ƒÁ�?€œœ Öjhhèèè�+„Š!‘hãp8ÍÍÍøø™ööv˜Ë$%%aÄ2™L˜¾ñ5•——GFõõõ°“SRRB^»êêj8:B‰Ë娨(r vtt444À¬fô‘eddÀH ޼DNïׯ~yŸ—D"!?Igg'xWÐçmoookkƒ‡v³Yñ›ƒï©¬„„!LS¸D¾;jjjx<z"ŸÏ§ÓéЗPM) jYÁfÅ0¬¥¥Nkdee‘k´±±äúõ뇞H§Óamˆú0ŸÏ‡X|&¸ñm,‹Ëå öa�~à@_BÝÕ€ÿÂõõõ‚ŒGøfE€jâûRSSÓi¸ª««i45‰6Á±#8ZaÕÏí~w‚Ü3/ÑF5ø/Ìf³á`FLL ͇­­­VÙå섟"z‰¶ºº:999ü”H­<¯¶¶–F£¡€šþp‰¶/ìrÄÄÄÔCRRR„s ˜Ó ¡xø3€.Ï]û…B,”l6YYYü1 àÛÜÄøY Í}„×ÀTÁš*‹÷JDDD+(&&&XØåGÁyG𞢢¢„B<a{7›¦Â[Ùî@ð fy‰„JkÚe³Âtjw¹üÂ$é«êBø¼]öáîÔÿ…»dØë’‡_páÒefÆ›UøØ­øÏÛýîÔeîŠÿÂT*Uð•$%%É‚?ײÿ¿0¡YÑš©ËóÃÑDZև>ô¡}è!ô™œ>ô¡}èCAôs{ö_joø�Ç¥ŒŒL¯Qà=Ƚ£™ÄÅÅ{Y(Joª;÷¦A3IKK÷& Ã$%%T3¥ìÏ59µµµ/^ì5_ŸD"uvvB˜V¯—Ë ïM:§pHžÐ›æ2T„½©ãõ²ÉÃáøûû÷²6*..þQ“ƒ²²2>£ÿ§˜EEEˆXë±ö›‚±Ö <bíw!b­wÌÎøˆµÞ|ÄZï¨!bíû»qŸD[úЇ>ôá·Ä‚¤;::˜L&>p“ÉdB(ºŒŒ ò655A(º¢¢¢ K´¦¦òr”••á4Ÿ¥,""A{29ÄÄÄP`_kk+¤SHKK£ËææfÈ3——‡ØÓúúzÈ¥� 0€šó9p8œÆÆFü^¡­­ rG¤¤¤IkZWWù@�&**ZUU…Ï¥�’+.— ™¢¢¢(òµ½½âý%$$Pœ7úȲ²²]RS~á~ýúáÓà “Édõˆ>/•J [g±XQšÕЯ_?½­­­…Ĩ)\­¬¬„3Dç…*K¡Pàóvtt@Þ@RR²û™‰µµµrrrø¼ô… Ä:;;AWÕ}d´ ”——oiiÁ ö¥þýû£•¯`æóù|ŽÿÈBÀd2¹\.>J}ak‹º¡WVV*++£mz—} }á/ö¥ÆÆFH‘érÀ~î¡°ÙìææfÔ—ÐÀAñ.+ûmÝ©g�£†D"!ò=|e!gE\\͇hÔV–B¡|UžÃÏCmm­¼¼¼à|XQQAø¼hà�ðópO˜œŽŽŽÊÊÊÄÄĈˆDCÛÒÒTíË—/···———¯¯¯?yò$$¯:::.Y²«^QQaooméïﯧ§G&“/^ ó—Ëåñx™™™l6ûÕ«WÀÞ?zôhЪb±Xaaa S±`Á‚;v(**666ž?ÈÊ6oÞ¼råJiiiDøQYYùìÙ³/:;;;ËÊÊòóó½¼¼8Gkkë½{÷@–jΜ9ŽŽŽxs[__êÔ)>Ù¹s§………””Ô å*› ¥¥ell,..s•JMLLär¹ïß¿Fwuuu•öööÈÈÈ£Gbfhhèææ¦¤¤Ä`0üýý™øÏ?ÿ´³³ÌfÀ^6›mnnˆìŠ‹‹---!}5((HMMÃá$$$�}ÃÈ‘#ÿþûo|l~KKË7 QÙ²e›6m’——¿zõ*¢ ¦ÓéW®\™7o^UU•££#0oz{{ˆŠŠ–––þùçŸÀ>¦¡¡Àb ©©yþüùAƒ¥§§#Zn&“9gΜîÐ}VWW·µµÙÙÙ8qå •••ÙØØÀh EB�Ь‰‰‰Û¶mÃ0løðá§NRVVNJJBʶ---–––žžžW¯^õññA« 777 :~èÐ!hÐ#GŽÌš5KLL¬¼¼ÜÞÞ Ìõë×uuuÉdrAAШ+((\¿~)xviljkkCBB˜L&REkhh8}ú4ÐìØ±ÃÒÒRJJªººÚÙÙ9++ ðӧOO:•B¡”––r¹ÜéÓ§À4Íãñ222€ûcðàÁ/^„¾ôôéS °˜:uê /ÀAŪU«6lØ ''WWWwâÄ èó{öìY¸p¡`r <ÔÈÈ(//lÇ«¨¨�îd‡S^^þáÇ .�{†aOŸ>ݺu+²@ÖÖÖ  ððð¸ÿ>²yÞÞÞ†††UUU;wî"(Ÿ‰'ŠŠŠ–””€Z…B ù!d<ÝAqqñŠ+€}àÖ­[xZH6› š †7ÎÝÝF£1™Ì[·n„¹¹ù–-[š››;fdd ~ÿ!`ìX[[_¸px4ð•8q"AÛ¬¼¼ÜÂÂ-…Gމ—Íýé&'??ýúõ, D�áááÅÅÅ@({âĉk×®íÚµ f<==1 [»v­‚‚žÊiÏž=>>>Ð~ÚÚÚ©©©²²²@ÚÁårß½{wìØ1˜:¯_¿wމ‰Ù¶m[hhè›7oJJJ Ð××÷ܹs‡ 2dnݺUVVvùòåHO¥´´tïÞ½ÝqËÖÔÔ¬Zµª££ŸC 7÷÷÷?yò$Ô púôiôh[[[…  £ÔââbGGG´ùò%~ßÒÒrèÐ!øÛììì5kÖ¼|ù2%%åÆPxçÎC‡]¸páéÓ§$ =´eË–ÏÕÂÍÍ-''‡ài<yrUU0Iäææ–––º¸¸À=6mÚtïÞ=ôû/^°X,¸êåååçç·{÷n''' ªªª:~ü8äzxx8;;%ë¤I“`Fظqcdd¤´´4—Ë<xpeeess³»»;Ü033ÓÚÚ:::zâĉPÒÒÒrçÎîÐÃû$$$h‰çÍ›÷üùsØ<Ñh4üÒ¬¢¢b×®]𠤤¤7þûï¿FFFPÒÜÜ|ëÖ-¤¦±qãF-£ÏòåË¡M,X@£Ñ&L˜°bÅŠ€€�0lZZZéééÒÒÒ¶¶¶pÏêêê9sæ€z—ˆ‹‹;räHSSÓÒ¥KQappðèÑ£Á%X¼xñ–-[DÛ´iÓüýýuttjkkÑ;ÃâÚÍÍ žž››»zõêØØØÔÔT4‚îÝ»·ÿþK—.………UUUAáåË—<x°fÍšãÇëëëƒüùš5kAÛ­[·ÖÔÔàÊd2MMMAï«¢¢¬a{7oÞ<A g„ýû÷Ø›ììì:šOãÇ¿wïÞàÁƒ×¯_ÿüùs ‰ŽŽAFêŸ0ê Ѧ§§‡úÈÉÉ9uê|ƨ¨(GGÇ   ‡feeAa``à;wÖ¯_óæÍ7nÔÔÔü xÉÉÉx•&@AA Óš††T§­­íéÓ§hßC&GOO/11ñåË—ø>¤¨¨(&&–™™ ÿí3('æåå±Ùì¡C‡âIYZZZ¬¬¬€aISS300°µµõãǵµµ°´155555mhh€µ<,Ìaí\UUUWW'èû²··?zôhw˜·UTT³²²ð €²²²rrrPÁ¶¶6Áýµ¬]»Ö××­v³³³ÁCû-yyù°Ùì¼¼¼ÊÊJüœ�DC[SSC&“…dXÀ EÐÕÕÍÌÌ$‘H,«;¢ çVWW¦‹ðÄC‡™™™& pß¶µµ©««ƒ}…uî‡:;;AÉMQQ1""*[^^½ $dnÂ)îáÇ€¥Á/‰¾ˆ‡æçç£ N‡¶4hlgAß¾¸¸¸¥¥…F£ .ÿ@1“Ëå çô›7oÞ¼yó®^½Šü@ÉKK!Y[Â/ºedd=z«ïÒÒR!} ¹Vª««ÍÍÍ»lâ]ø™LF}ICC#11155t‰á{öë×OpìTTTÀUuuu!ñ»à/ôëÇ’Ô××WVVΞ=f§-[¶lÙ²E”ý?x׳gÏþðáA)ŒŒŒk×® JéôÄYÅÅÅà£055¬Ìçàîî^UUuàÀDÅÁãñ²²²Û½’’’;wjkkƒ‡ ””têÔ©iÓ¦áuïÝ»¾téR<áO~~¾ŠŠÊ÷¸Puuu  ‚“'Oó† ªªÚÞÞþîÝ;]øK¹¹¹êêêÈ->zô胿Ož< ò|àNÙ¹sçÀ cµËMq@@À!CV¬Xñµµ8yò$tzIII!úöÄÆÆúúú𵤤DVV–pèræÌ™¼¼¼Ý»w㽎ÎÎÎôÐбÄÎ; ´oß>¼›»©©IHwï8pàÀHÀ?ܘZZZÐF¹£††&“ ¼«† 8ðñãÇÐÖ‹/^µjò\ÿóÏ?‰‰‰7nîÕár¹ >>>Â6… ´´ôâÅ‹óæÍÖÔ¯›Íމ‰ ñóó;D£Ñ âø:N ŒŒŒœ={¶Íçès¾ ð�àV‚ï9uêÔõë×ã#¦ÔÔÔ"""À›geeµdÉ99¹aÆ•——ƒÿ‹aØ3‚z÷¯†ººº[·nݿƌëÖ­ûªê…ŒŒ ð î­­­åå忊^ΣGÊÊÊ€œøÄ‰7oÞì¦=.aäXƒfeeUTT„ÿÙˆ#¢££cbböíÛ‡†±™™™™™™¯¯ïÕ«WýðæÍ›7oÞ¼uëÖèèèåË—£YoÏž=ÇïòЉ …Bù3]BBB\\TÐßßÿÂ… xÇÚ¦M›.^¼4Ãx­_ ömÛvòäI4C¡—çóùÊÊÊH}àÀÑÑÑÙÙÙ›7o~ùò¥cÛ›7oªªª‚:ç×ÂÌÌŒàXëÎ_YZZZZZzyyݼys÷îÝPø÷ß¼À/;iÒ¤#F *?zô9Ö dРAÑÑÑ™™™[¶lOŠaØëׯããã¯]»ö9:œuc6tèÐÏ©õ¬^½úsŽ5eeå“'O‚‚xKK ÞX>þ<336jp$ãììüèÑ#І8Ö444;H>ŸÿêÕ«‹/†„„|óáÁ?ÿücbbò ²¶çåË—aaa`o`3mooÖ½®®)q%$$L™2%::ÚÃÃ#$$N¹ÈÎÎFŸ}̘1]°X¬¥K—‚c­K¡~rùòå+W®À–íêÐÆÎÊÊJYYyöìÙ§OŸÞµkôO||ÇÛ·o=ŠN‰~Y¤¤¤L:5::úìÙ³pØó+#55õøñã·nÝdáCÈËË»zõêÏ3ö?]/çÝ»w#FŒâ @¦5''gܸq‡@}}=Á„‹ˆˆ9­r*�a0rrrß&ŒLœåùÙ›7o&L˜€!ãp8ïÞ½Cú%BPQQB£ÑþüóÏžéˆUUU,ë‹þX"©««¼@‚•e³Ù©©©Ý©,ÏŸ?G“š££ã·IÇ«ªªÂ±|RR’‡‡‡ŸÏ'ˆæää())u'PçåË—W®\ùf{óéÓ§ÀÀ@CCÃî» :;;£££ïÞ½ <cÆŒŠß»wïéÓ§P¸dÉ’uëÖ ¿áíÛ·3227æ×çF+Baa¡”””`hrr¢U`BB™3gðg¿,æÎ ³ÁïwwwØ óx¼øøøž×Éþé&gûöíp JX!ÆÆÆâ ¥¥¥»ví™ „W¯^=}ú”À�’v‚‹µ´´4 !q·ßŸ«ŸŸŸ/!!!8 SRR†ŠwOÿõ×_oÞ¼Á¿ ƒÁX·n]vvvw¶’=é~öìYff&œ'æ_yyyü4±ÿ~‚-±¶¶~÷îAÕÎÎ"¯Žˆªª*!Á„¶¶¶ßé¾okkKKK›2e ¡¼¦¦¦®®ó;wîp8BøÀ©S§/^Ü<èU«VáwW_ UUÕ9sæ|Ãß2™Ì;v܆EEEhsóUÀoG¾¯_¿ŽŒŒüÜÝåË—õôôá))):::„Ìš5k233¸to0 344 †óx¼K—.L“ÉÌÉÉùÜÎþ?09jjjÅÅÅH Ž…GŽÙØØ…ÊÊÊà,NJJ:t¨‚‚‚¡¡aJJ ¸¡ŒŒŒ <œËåÚÙÙá³sdddF 7©®®†:+++÷ïß ÛÚÚ`5tèÐ’’(TPP@þÓãÇ;88|n‘ÕMÐh4pñƒ‘€£éÂÂB>Ÿ¯££óöíÛºº:ðrÒh4ä?xðà¡C‡ðç&&&111bbb|>îܹ†Q©Ô©S§Â›šš`ýÞ¯_?MMM(¤ÓéèdëÓ§Oè#>ükuúæÎûøñc‰ÔÑÑN)))}}}ô Ш¯®®®ªªÒ××<xpQQ\åóùh»sõêÕ±cÇâ;å¤I“rss!ýbܸq°y555}ñâ•Jåñx¨²S¦L666"––%߃™3gÆÇǃÿfíÎÎΘ˜SSSø†øéÚÚZ¨)¸UÓÒÒ®\¹‚n¢¥¥•›› /)%%g<úúúP8tèPN> ±¼FFF0òx<ÔFÆÆÆ_[‹ììlt}}}eeå‰'ÂÕ˜1c„œJvtt ¿•••6mZMMMpp0¸p«««AhK]]½²²~I&“¡#éêꢫªªÚ͘QQQSSS!?PVVVRR‚Û¶¶¶B¬A~~¾ˆˆˆ––Ö¨Q£šššàªŠŠ <ôÉ“'ÙÙÙ°§œ0arè=}ú<?¢¢¢=¦r6{ö쨨(‡[϶¶¶¤¤¤3fÈÉÉ1^¾¢¢œ1***òòòPÈáp~ÞáÇž©ˆF£ùa³Ùñññ0Q”””üóÏ?µø~®É0`€ú¯±±1ǃ)cñâÅédmm†a˜ƒƒ¬³bccÓ@mr�� �IDATŽ?¾oß>…:wîô*‰DXHª¨¨899Á‘û¨Q£ <wòäÉ<òEfÏž iË–- …Ç­[·ù^ ºAG€œœ~³5nÜ8 clllee‹}09kÖ¬¹qã<ÚÞÞ­ j=.\غu+“É$‘Hׯ_›zòäI8\UUU…“Ø#F¬]»Ò€P´Â!CÞ¼yOÁ0låÊ•_49³fÍÂOOׯ__·n¹ËÀ÷íÛçææ†aذaÃöîÝ ƒ'99Y__ßØØ˜ÏçÃyjV˜õ~'F‡Íè±cÇ`âðõõupphmmC999OOO8RSSC‹h†lÀ×®Îð_ØÛÛ{ÇŽpü�1{çßÿ5550`ÀþýûáHCGG…i¨¨¨ð/^Ìçóá;¯Y³l†ƒƒÃ…  pïÞ½°;÷ôôtqqÙüüùó0.X°�µQÿþý¿hr† ‚ÏêÕÕÕ}òä ºÃ€”••A‰5..vøãèùóç£hO …bllŒþV]]}Ú´iÇ·µµ…­êĉ!ÊÔÔ”ÇãA~•……Å‚ ` îïï¾uëVyïø‡JJJ¨Õ`A‰_Žðx<0ê³fÍ‚cÈììlèX»víõë×á¡[¶l‹èæææîžžž`{æÏŸAz`Ë{ÌäüóÏ?6l€¼Ø«µ¶¶>yòdƌ۶mƒ¾?þøò ù|>t¿ùóçãI€Î##£.µ‘-Z„–/=“#++û ‘,_…/¨‚öôq¬ýúèãXûõÑDZö[à'q¬ý(UÐ>޵>ô¡}èC¡Ïäô¡}èCz¢ŸÛA÷šm&•Jí5mà!¤R©½¦™àL^TT´×ÔNADDDzM@wª—M½o(Á,G¡P~HDDDð´Å?Ëä´··w'œ÷7ÇËÉÉéM‚f---EEEøºßÕÕÕT*O‰ô»£®®®¹¹¹7 ¥ŽŽ6›ÝË&`fê&÷üo¦¦¦ÒÒR Ûÿ!ËÁ(™ÚµÉár¹(¹�BŒðLõ½`ÇÆçóY,$·öŽ]—Ë…H–^³Ëéììäp8½¦F$‰D"ñx¼Þ49ÀV ¥¥¥×¬u ]"HH7Jߟkr$%%¿-§ìׄœœ\jjª¾¾~oŠX«®®:th_ÄÚ/ ˆXëììì5C "Ö>~üØ›&YYÙœœœÑ£G÷¦ˆµÆÆÆ>UÐ>ô¡}èÃÿw|!´°°0!!OS‘˜˜‰Z3gÎDt„oß¾Å0lÕªU@_pþüyDj‰aØþýûÅÅÅy<cJKKN÷ööF?6l<4-- d‚¦L™ öÑÑÑxBÌeË–AZ�”ĺoÞ«ªªîß¿¿iÓ&T’••©s'NDI‘<�zÐ+V ²€«W¯c¶mÛ6Sïðl"ׯ_Gra€ÜÜÜÔÔTD1ùæÍ›‡¢«fff_¤;sæ (¡H”€ôO Ãjjj@ìNCCÏÉaXJJ žÒjÖ¬Y&ج~~~x–âÝ»wC†æÑ£GÛÛÛÉd2¤¸2™ÌãÇ£Ÿ©ªªâ¿pfffnn.Òhè®^½:wî\<ÕÐñãÇÁU}ôèQBTHmmíÙ³g1 SSSC\àBšõñãÇŠŠŠxŸÀÀÀ)S¦HçNž<iooÒ9ñ\àòòò¼,‰‰‰ óæÍC%>|óæ †aË—/Gù˜è oݺÉè;v $5ÝÝÝa§Ž¾ð€úÆÇ!WOOò¦1 {ýú5dÈ›šš¢|Õððp ÚúóÏ?…l+=ºwïÞÏr”——?~üTñ_`hhT„°¶¶Æ+>x{{¯Y³±¸>|˜Íf‹ŠŠ‚â\áàÁƒT*ÑÀ#”••óššðgúô鈻5+ajú¯péÒ¥E‹ ²\¦&@uu5H 2D8äßå”””8998p�ñj`–””ôüùsMMMMMÍ”” "ˆˆ(((€ÂððpÂÑbHHˆ”””æÿ�³ƒ‹‹ üWAAˆ) úMgg'̹ééé>„BÄ¢  €~‰hH�—/_>sæL7™¯êë뜜\]]ñÊw>|‡›€j~ØäååÁÕû÷ï‡Ø•+WÚÛÛ¡ðüùóx­eWWW”°Íb±œœœ\\\nÞ¼‰~ðñãGà\@$Œ°ÓGÌÍÍ}ÿþ½Zx{{;99y{{ãOªÐçURR‚^UWWwþüy(looÇó¾`–ýþý{ôPÈU&4ë‡0 SVVF?»sç<ôðáÃ4MSSS]]ÒþEDDÐÏÄÄÄîÞ½‹ÿ‡BÄÒ_„ŸŸŸ““ÓéÓ§ñÍêáẾ·¡¡áìÙ³p‰ÍfÃ4‘ý¹fŒŒôôôDPÁÁÁNNN§N*++C¿9uꔓ“Ó¹sçðRʨ‚ýúõNá“’’âäätôèÑ„„¼½ÉÉÉ;üûï¿ÀªùÏ?ÿ°X,(ôññÑFwww FB•mkkóðð€ …öxB¡°ªª ”|bcc¡0)) D·ÂÃÃ‹ŠŠ 0,,¬K¢q'''߯0¬½½�:îäääææ†_©&&&¢ÏBà㈋‹£Óéè*žç÷ìÙ³ÞÞÞÀQó>t3UUU´`긹¹©ªªjjj*++LNEEÅÕ«WáÍøÝ»wq©©©™žžCøÑ£G¨Y<x€ÈRÿ\¹rÅÉÉéÌ™3øIIpjB Óé>>>ðò,‹@ûÓw9’’’zzz ¿ªÍÍÍmnn†õ݉'ÒÓÓMLLÞ¼y3lذ¿þú ðµk×–””ÖMË–-#ÐzêééJ+N711quuUPP°³³ƒY¸¤¤§Ÿ>}ª¨¨€ý¯¯ïÛ·oçÍ›7nÜ8à8 ›3gJ…½|ùrggç)«¨Tªžž^EE^8«¤¤¤¨¨èÀ†ùûû¿yó¿"†ïikk[\\¬««éää4bÿþû/Ruqq6l:=ÕÓÓ«¯¯‡Õ%òºêéé‘H$ü|:jÔ(àv{òäɤI“fΜ)¤ÚÚÚ 1%¼xÁš››_¼xS^BB¢÷G9r$Ô aРA#FŒ�樿þú«¤¤dÔ¨Qh‘îåå…ôrnܸ´ž ^pìØ1 ¸[uuµ··7¢(ÍÎÎ USSÃËM ‡††…B!=ܾ}/^€—Ìiiiyöìl΀IÚÞÞ¾¤¤äÓ§OЬùùùhv‹ŒŒÌÌÌÄóF«©©q¹\X¥"èèè())…‡‡ã ¡‚,ëàÁƒ‚‹b<ôôôÐCÊÊÊÚÚÚ@ ¸aÆ¢¢¢Ñ£G?yò¯ jcc3`À€áÇ/X°�B`h4š§§gGGGxx8ÐzææænܸqÇŽÕÕÕ`€IzåÊ•999L&Ö3fÌxýúµ¾¾> À5kÖ”•• 2>”ÅQ ›Í†Œ˜˜˜žž^ii)ay§­­MèExh=aƒ.!!çÒ ÊÌÌ”’’UÐî >}'ñª ø V]]]bb"Ô=***((ÈÆÆ¦   ¶¶ŒbVVØæ¤¤$ø7nüôéA¬'¡©©)..þìÙ3B9ajBhnnމ‰yõê†añññÞÞÞBZóÇ›%%%kkk‚*è´iÓêêêÀI¢®®Žß8 Á¡C‡€føäÉ“ü°fÍ6›½}ûv*•J —¯©©ÉÊÊÿ̸qãJKKáqªªªæææO…¾¾>â{þü¹ƒƒC÷¨ddd¬­­³²²ð+î?þøããÇðÄAƒ!%ÀÒ¥K>|Wÿøãü®ÙËË«¨¨hÿþýˆP9$$$33‹‰‰Y[[—””àw9´¶¶~òä Þ#žžN¡P„§ƒ³öÂçÎNu …‚×û‚ØØX¨×üùó‰ ä‚‚‚ÆŽK`âzðàŸŸx™¼¼¼\]]!cï…Nüúõkäd«¨¨øøñ£¥¥e÷Õ8ÀyKÐðððððð`³Ù°FÆ_êׯŸ½½=ÔENNè°�ÉÉÉ×®]344D>Ìôôt111ü644444Äïì±ÿ±QÀOõ÷ß ©‚–––––VGG~qƒt:uuu…È#ùêmÛ¶kô;±jÕªGÁ'š<y2Á�J0Ò� ///ø·œœœµµujjêëׯñõöí[¸­±±1aìÀÒlùÆÑ؉ŒŒ<yòd``àoz2{ûöí9sæ,Y²äW{7 'îDŠíÇõ_å,‡€ŠŠŠÖÖV¨IAAAQQÑã‹>ŒB*ÁC!Þd2yÖ¬Y¯^½BsŸ>}ºwïÒ«©©©¯¯‡Ç ‰ïöíÛªªªèÃÇÇgæÌ™Ý]ŽÚÚÚššxbIII^^~.ÈÏÏ—––†«iiit:Nœ8±hÑ"mmm///¶k×®cÇŽ}O ÌzænâÅ‹³fÍ"‘Hl6;..aúôé(h`u`÷#%%•ššZ[[«¢¢…îîî¶¶¶HÔ ..nÚ´i …ÏçGGG£C:~ñâE´ÈÉÉyñâ…ƒƒþlïÛðêÕ«É“'Ãç}òä ^È®­­-==Ú¨±±ñÝ»w°MLIIyðàÁ¬Y³JKKoݺÓ.‰Dš7ožà˜ì&ÚÛÛ]]]»4EÝDPPPcc£……Å%j¶lÙbdd„Ì †jffþ÷òòr!º«¹¹¹òòò !ñîÝ»ºº:AAtvvÆÆÆ aW›0a8$0 +.. Ã×ýù矈 8,,ŒL&=ÚËËkÅŠ¿æ×"..®_¿~³fÍoíâÅ‹—-[vÿþ}h…ääd33³_íwíÚåé鉜1x 8ÐÎÎ^¾¶¶¶Ëßüijœ.QTTÔÒÒbaaaaa ý~n•jñ?<{öŒÃá G“………‰‰ ^û¯¡¡!;;’òòr:+))‰×_IOO—““IJ …baa!<bØÆÆÆÊÊÊÊÊÊÁÁás¿©¬¬¬¨¨€'ÊË˧§§ã¯fddÈÈÈÀÕÊÊJ$ihh…oß¾e2™;wî400°´´üÍð°ãX»û÷ïÃûÌ™3‡°`ÿœó µ‰DÂ7ë¸qã,,,***Pe1 {ùòåøñãÑAúÇÍÌÌ,,,–,Y‚?&a±XIII°MÉËËóóó377Ç“ "88ØêHJJúÜÏ"##Q¿"œ·µ¶¶¾yó.éêêÆÇÇC¹ŠŠŠ¹¹¹………œœ\zzúãÇ322ÌÍÍ¿í £Y8** ðµö¦¡¡¡;öÆÁÁÁÄÄÄÒÒRH”ÿþý-,,ÌÍÍÍÍͅ뤥¥õë×>QIIIuuµ§§'úìxI<8ΣG„ÜVEEõ")))t<3f ºZZZZ]]}âÄ %%%h¿©ÉA‡B¡À¶žžj…oSºû©Ø±cÇ”)S,,,ºœš`rƒ—‡I855•àAéé]Î7ÀÙÙyÇŽ„x PøQHMM-..wnn®›››¯¯¯ j=ÙüáÖ{Ê”)Áãââb83ïììü±•ýxñâEqq1A;òúõë***ß YÙ%îß¿_^^ŽaXuuummíåË—Q8ÞÂMŸ>þýc¿ÊÊÊúúú迟>}ºsç,)òòò$$$† ò ‚Ðߌ7nÔÕÕ-]ºô‹Ó¦M›æÎ;þü/Ò5õïß¶§òE˜šš¢CLë>SRR¶lÙÒåÕk×®ihhà&Y,¼gYYÙŽ;üýý»£Çúë@MMMÐ-‰Îb‘ïƒçÏŸ—””@ÀTgg§••a‹/++ ]HNNîíÛ·555ø³çßÃä$$$Br1 <Ñ‚-”ŸŸ_wN i4ŠJܽ{7Äö`VZZjnnÞeÇ={vϤ‚^¾|¹½½µ±`õ¿ˆˆˆˆöövtäð³Q^^ž““#¸Íê’Ú`ß¾}ëׯ´èÔÕÕ9r=Œ9t K$''wIé?|øðžI]¼x1Ì `\i4Ú×ze;;;mmm¿YÑ<//OUUµ; áØØXww÷/î˜!4ãСCßð2ݧ£‚êêjÂΜœB:ZpuÕªU?6Ëý?A@@@ÿþý¿ÍÞ€ðZ45¢***þþûï3gÎॠÃùŸ™œ¹sç677ƒœ6mœnذÁßß ÍÍÍAƒkß¾}kÖ¬9r¤»»;Pùúú‚’Ø;wà÷RRR q„aXKKKaa!~)jhhH§ÓÑi6ÅaöñãGeeet´€–†ÉËË7î›ûîäÉ“«ªªà‰úúú°  áñx«V­²³³»~ý:\]¼x1øˆÜÝÝ}||Ž;†aØž={ „o$2™ü r)eee\.÷‹ÓúçpïÞ=;‡UÌ AƒöìÙo>xð`°ë ¯^½rvvž3gNSSjV0u7n¼víjV”¶’––¶téRüþ믿:::H$ ëêèèHOOŸ8q"Z;£¤ €úýVÿ­[·BÈ2,ÙZ[[íììnÞ¼I£ÑÜÜÜàµUUU¡]&MšTYY‰šuÆ ƒFÓýóçÏÕÕÕ„ƒÇã%$$â¾vü£…°‹‹ËÔ©S9ráÂÀÛ½{7J/[½z5$LjˆˆDDDHKKŸ?ªÓ¿ÙPUUÕÑÑÂ#FÀèüùóoß¾ …Ó§O‡“˜Í›7£–µ´´ì¦½‘””DÆ]bÚ´ih´Ž?6ÍÁÁÁbbbK—.Ý´iz¨……Å„ ðŽ))©I“&AÜÚ­[·Ö¬YÃápDDDBCC{l: ]¾|9—Ë¥P(ÎC§ÓÝÜÜ®\¹¢­­½~ýzxymmmÙ9sf}}=€œ£‘‘Ñõë×}}}1 [´hÑ3êzx·6ššš››·mÛ ¨¨8}út¨‘ººú‘#Gú÷ﯬ¬Ìãñ~à;|A¢Á`ÔÔÔàCœét:Þ 4MúÅÅŵµµØÿbva§¢¢Sff&˜V}}}Xéðùü”” Ã( Š]imm-))!,6ëëë!J›F£T0ÌÈT*µËà´ÜÜÜÁƒ|…H´µ¶¶ãWÖ ?~Ä0lÀ€àÛc ˜’JJJ`G¥¥¥…2rssA<XWW—À—’’‚Òùùùpr‹ÐÔÔTWW‡O<¬®®îìì’ÐJhËÌÌ:t(>Z!99Ã0QQQdÂÛÚÚà0LFF¦ûÆÆÆ††0]6k—•ÍÉÉQSS#|áÔÔT.—K"‘PeÙlvnnn—¢ MMM©Sá„7‚Íúþý{8?~<‰Dâr¹PÙöövXnKKK£îÔØØXXXˆa˜’’Á–—••‰‰‰á h4 >dddŒ1åEòùü´´4!‘f‰6:ÞÑÑì\YY>Œ?p ÛiÔ¨QñŸžž±y†¡/Ìáp aKBBùv œÃ)**¢uOMMMii)†a***Ȭ ØÏ¹¬ÇŒƒz‰6‹UZZа‚£µ¢¢‚L&Cx‚‡feeikk£PièNd2Åõý<à%ÚÞ½{ÇãñDDD YîF+“ÉO€¼¼<škkk!\YYV;>dÈ”ÜÚ“ H´åä䨫« f ©©³³óÇ™ÕÚÚ D²²²pÌùÃ%ÚúTAKô©‚þúèSý-Ч úÅnܧ Ú‡>ô¡}ø-ÑgrúЇ>ô¡=„®ÃDDDŽìßÝ!�»¼^¦ *%%Õkš j$..ÞËjD¡PzÓPjmm%“ɽ©F0'HKKÿ@²_¡ãIJJþf"‘H?JêM˜É©««óóóëM¦µ³³…Æõ´··?|ø°×Q ÃØl6‰Dúáy�ÿm¯ãr¹½i(ñùü¶¶¶^69´¶¶÷&ÉàöööŠŠŠ%:7`À€ï'vù‚É‘——GY/½�²²²~~~ .ì5½JJJêñãÇ£Fú½Rç„@LLìýû÷d2ù{è�~-‚¨hMMM^^P¾öŽå3™L¾ÿ~oŠ-’‘‘ ž3gN¯ ””|ñâ…ššÚׯýw ²ú‚÷¢Ÿë[½¦°ÿ Q‹‰‰õ“#..N&“)J¯i&qqqQQQ2™ÜkjD¡P¨TjoªD¬õ¾ÉjÔ›†Òœ bí¾^_ø@úЇ>ô¡‡ðY“ÃçóÙlvTT’Ä0ŒÇã]¹r…F£n—ËÅ0ŒËåîÞ½ ïÝ»×¥Iäp8#GŽD»³ÖÖVø½®®.$ôÁãñ\<ïÖ­[ðKWWWô¸C‡Aa`` <®³³såÊ•PøöíÛ.™Zº¬`ZZžY‹Çã…‡‡Ã}á‰\.×ÙÙ®Þ¹s½|ùrÚÿ ¨¨i¤gذa4màÀ(¯¬¬ ~fdd„jýìÙ3(ܸq#Hnp¹\(<}ú4á?,›Íž0ažŸÍf8F£ 6 =(33î¹hÑ"¤»E¨Ý©S§Ð�—Ëutt„? Gß™ÍfÏœ9O±Êápttth4Ú Aƒ ²|>¿¸¸þvæÌ™ð<ïéÓ§P¸iÓ¦.ßAðD333ÈFOÔÕÕ…[¤wø|~NN\š?><=—F£)))íÝ»*èéé …W®\A\»v-ÆÅÅAGâp8Pˆb˜L&”èéé!²Ú.Áãñ@,/8Æår÷îÝ w EO777‡Âôôtôt6›­¦¦†¨JšššQLMM1 KHHèׯ*®3??¿þýû£Â .À£·oß%<øÜ€e³ÙmmmøBüØIJJÂ3%ß¿ÿÅI'''%%%t(¯:;;ÍÌÌ $//ê €²¿{�l6{ðàÁ 6HhP¨oll,^?…ÇãÀ{>|ÍNÀ%O£Ñ€µä?œÜa옘˜*űÙlÁTz>ŸŸžž/onnÞÍúÃLNjjª––ÖÚµkñ…AAA………555555HÅÕÕUWW #""ù[[[§OŸŽÏµÖÔÔ„ß¿xñ} ´´´€ áÑ£GIIIðKUUUÑñôôTTT„Âäädà;Y»v­­­-îÛ·?!~¥¥¥ZZZˆ¥ðäÉ“À}F…Æ0ìÀC‡…«‘‘‘@Ò %ÅÅÅüñœçOž<Þ¼ªª †M}}ýœ9sà—¾¾¾³gÏÆ0,111 � gÍšŠÂ~~~5ÿ‹ÅòŒÏaÉ’%ZZZx= ÃÔÔÔªªªjjj!wúÓ§O7n„{îÝ»WPšÃá\ºt ¢@³Ž5 þäÁƒ p³fÍ---Áö„ Þ½{WSSSVV‰ýuuu ,€¿õöö†‰)>>UÍØØ˜ Æý9ØÚÚjii™Âرc_¼x·"°ô—––ÚØØÀ¥@B_¾¢¢1·_¼xQLL Ê ÈÞÞÞÒÒ ½¼¼ÀΙ™™Cá”)S €GKK Jž={&<9îîÝ»ZZZö³ãÇ£¾ Ì7+W®Üµk:88�]”)S´´´QCJJJ¨“ Á§éÓ§£B(ܰa*õýû÷@IHHhû0mÚ4---¼Ô,ƒÁ@´R?~ÔÒÒ"èWa¶téRô,¼ÖàÔ©Sè*ÐÅ®\¹ÒÃÃJþüóO`}ÍË˃’œœÉÅO…¶¶6LnYYY„Å>hiiá520 ©\xU999;‡ÖÐÐ@“A;±‡aee%8Z1 c±Xººº‚¥°°ÐÁÁ^~×®]øÍ•J•뤥¥%%%» nú,ÇÚ¸qãÊÊÊmbbb"""ˆŒ¯å'3fÌ Ã/ˆà& ¨Ë‡ZVV–’’‚X\¸páÂ… ;::X,ǃ(F .**úÍ´ÐêêêeeeYYYH:>(•J…› jŒJJJr¹\¸J¥R šðfff¾¾¾0BØUcc#ŸÏB(b`````ÀápZZZ8Î7 0à“'Õ+((466â?ïPYYéââ‚Vµ’’’¨²ðAÞ˜À¸ Ì+PY‰$++ Ëb±¾'Xx3 <‰òòò È“Ÿ—L&KKKã[[[‘ $$äǧOŸÆ0lëÖ­†µµµµµµ‰ˆˆq|ÜÞÜÜÌåråää¾öDpÙ²eË–-»zõ*~'Šv<, N}>÷ç`n ¼Úhˆˆˆ îg‡ƒÚ ‘൷·C¡„„Œ àc±X‚Ý�Êxf ‰„ú’¶¶vYYYjj*aMÖÑÑÏdµ¢‡’�� �IDATXa±XpUZZê‹4à›››¥¥¥ñ3ŸÏ9rä÷K+ýèêê–••œ.Þ¾‚|Q{{;ŸÏ‡o‹Ÿ"„7k�˜âÉàuuu?|ø DQIø^"Â=I=jnn^¹r¥ í×å,^¼XMMmêÔ©S§Nåóù666_ü“úúzyyyB¸Þóçÿ×ÞyÇEyeÿ™>ô¡H)AŠ0 MŠ.  X£&Æ–¬.fMôÃF×D7vÝ`%I (ÆÄM &Š10[$*Ez¯" 30ÃôöÌ<¿?î»óÎ" * Œçû<ó´[ž{î9÷ÜsrÐMºå÷}œ .DFFr¹\”éråÊ•"‘]>nܸõ¬‹ŽŽŽE7¯­­í6_³fMcc#ú5::Ú0‰@ °´´ìV¿qqq‘‘‘(á|ܾ};22ò?þ@0šp¹\.—ûlñׯ_G/¹hÑ¢þDPW(8Žw×®][[[‹î‹²#÷AlllLL̵k×0 ³±±IMME×&''ëcHgÏžMHH@÷ï6Ig³Ù{÷îE?}ùå—†Ù>”J¥F£é&ÿ¾úê«ÈÈHWWWÃŒã=òÆoDFFž>} ¦ööö¨PܰgC,oÛ¶mæÌ™O•Ë‹D"Q©TTÆ7ß|Ù«étz]]:¸aÔÑÔÔôòåËèàÑ£GQ TÄŽ;"##_}õÕ¾3é177ï;_“ɼ{÷.zÖîÝ»QÔA=–––GŽA¿ž?^¥Ro¾ùæÉ“'õÁý0 kooï†ßˆ\.OKKÓét(ÿìªU«Z[[Q1'L˜ÐwùŸÏ·³³ëqÚ„¦/¨WëõоE©J¥ÒétÓ§Oï1ÆÓ‰œŒŒŒ†††ŠŠŠŠŠ ‰d¨�õH{{ûòåËSSS»Eû A7ÉÌÌ|b«,X° ¢¢‚Íf£ô‹‡¶¶¶F—ö?)ÅÃÿÒ[*$ ³²²ÐÍ}||º%Éþä“O<<<Я999†¬ß|óÍ;wÆ?EÆÉòòòn)œ{¬+**bbbPŽzd¼š6mÚ´iÓVñ´–——WTTdee=QTÈd²ÿüç?�­pèINNöññA…ÍÊÊêÑüÒM×ÑÖììì|뭷е»wï^¼xq?ß\(ꛩÛ"!S¦LÉÌÌD÷ïX³¥¥eÕªUè§?üÐÐ2|áÂ…¼¼¼n®uëÖUTT444<1hqNNNEEÅÌ™3ÑÀ]PP€Ú¨GûC? ›œœ<yòänÖÝ'beeUñ_:„Œ‡¡¡¡úƒS§NEi†õ­PQQ¡V« ÷ÓìÛ·¯¢¢âܹs7oÞäñxújïm]J"‘DFFöñV3fÌÐ?ËÅÅÅP!@Ö<ý¯¿üòË7ôCÄŠ+>ÿüónj\``àã¡á†T*=yò¤R©Ô'2Þ¿¿‹‹ *æ­[·úŸp}hhmm]°`ANNNû^ÇŒsèÐ!Ô«7lØÐ‡DA[èz;á÷ßG[†{üupóå¼õÖ[6lÐétuuuZ­¶¡¡ÁÚÚºÿ»¥R©\.¨È• ,@«y666ÙÙÙƒZðÆÆF—'nÅR(B¡ðq÷ù„„„„„ ÃÐòÕ ráÂ…?þøcÛ¶muuuJ¥R(öa ì±°®®®²)õĉÈL‡V;*A\o#>AúÙ}OV» h4Z•år¹Ï jwvv~öÙgOLþ8:®¹¹¹[<ìû’H$Òh4Ý6oñù|ƒa¨í%%%Ý»wý}æÌ™g3¹H¥R™LÖ›jòøC1 {ôèч~¸{÷nÃ0ê#‰DòÃ?H$’>FçáÆôéÓ?Îçóù|>Aõõõݺ{{{£^}ëÖ-´Tß›¢ƒ\*zTûpŸ2eJocÈàŠwww½ãŠ@ XµjÕµk×ú¿bqõêÕ¬¬¬”””y™»wïÒ¾œ¦¦&Õ­3fäææ>qàÎÏÏ?tèÊjh£Óh4CfU°²²ªªªBÙ>:;;u:¿¿L¦z¦NšŸŸ? Ñ5Ö­[7H‘¤Åb±T*EQôõâM£Ñ m oÙ§Û°XYYù<)>ûì3ggçnþ2ý/ËôéÓ»¥/,,Ü¿ÿ¹sç þôÓOuuuhñÆPY^ºt©þÈ—_~ùü5üÛo¿]¾|¹7ËǾ}ûƇ&RzV®\™””ôx5VUU ÿÁ/^,++ëc\†xzz" †a8Ž/_¾ÜÐì¯V«[ZZº ¡Þ‰D"‘_ѹ}û¶R©ìc¶ýt"ÇÖÖ–Á`è^¤°Ùl…B²X,4ôÔÕÕ9::*òçÒ¥KHÞŒ7/‘Hú¥Àb±,,,ЙjµŽŽŽ"‘433CÃú+¯¼ÒÑÑŽ=ú™Ã%!w t…BŒËÈ/9+•Jô+:]õÞ{ï%%%~$§²²ÒÔÔ” ä3F¥R½¼¼Ðµ­­­ÞÞÞ†™››5 ‹Å(™Êõë×KJJÐä—L&?ƒ’‡ª—D"Éår4‚3 777ô .—‹’©ˆD¢®®.Ã…„Ï>ûL¡P y3zôh}³öqüüüÊËË‘[JC¥R===ѵ=BöF ;;;}»?Ofx__ßêêê¶¶6TX ôZmee¥ŸŸNwwwGOikkÓ§ùý÷ßsss¿þúkýMìíí=z„Îd0(µ‰›››P(DѲ··wCC²§ùøø }nõêÕÈÒ+‹Ÿ-Hkk«þSrssc±XcÆŒiooG]]]{óh P(ÞÞÞúÖÔ÷%{{{tP$!?I[[Û‡¢ƒ$iÔ¨Q†9;;Ëd2tÐÚÚºŸs2™¬÷X{âתR©¾ÅårQ=z´\.×?T¿pX[[«_ðõõEÇÅÅ544 ñpìïï_ZZJ¥RU*JA¤V«ëëëû˜X} ¢l6%'D¾ŸÎ;C†áŒÄÁÁÉÇ«««‘³Æ¶mÛÐ$¬½½½oÙÓ£¢ƒÜ ¢¢¢ú0<AäXZZ®OÌž=[«Õ®_¿ð¥K—¢‰Òš5k>Œnß¾|SRRÞ~ûmÃ>¤_]ÏÊÊBܵµµ¡ ÝÜÜܰcccõ{ã7PŽÎwÞyçØ±cèàºuëíe×®][·nEQÔŽ9Ò=ÝÔÔÔpZ©âìٳ׬YƒŒø:néÒ¥«V­:zô(úuË–-úeŸnyHÏž=;þ|‰DB"‘Ð++«ôôtägéîîŽ&ƒAAA+V¬@7ŒÝ¼y3*©N§C—/_ŽR¯>QÆOW¯^>}:AÈ;ÃÙÙyÏž=+W®D'£±²´´ôÆh áää¤_×ýç?ÿyäÈôÛ¶m3´ãs8C¤ÌÌÌyóæÉd2 …‚Œ×ÖÖÖiiiK–,Á0ÌÃÃùy‡„„üýïG7Œ‹‹ëz¡§[ gdd,^¼yå!§|¥R™””tæÌ''§¼óÎ;Hê³êÚØØtû„–.]úí·ß¢÷YµjZPÙ¾}ûÇ|êÔ) Ã8€:ð‰'–/_Ž\xúé'TöË—/#?:›þ,¹ÙÛÛîÒpqqùé§Ÿrssѿ۷oŽŽÞ·oßúõë‘\LII1Ü•¬7]ZXX|ûí·h…ÌÍÍ yg$&&¢âLž<¹¢¼þúëú¾ôöÛo£î·víÚƒ¢ƒIII(o„„„èjnnÞM…2333üZcbbôßÎ믿ž˜˜ˆaXvv6ƒÁX¼xñ|pèÐ!ôëG}„|||| #ž:u M°BBB†>PÈ¥K—^}õUFÃd2‘ssWW×Þ½{õohnnn8­´µµmooG%BÝ)!!!11ñË/¿D7nÜóÂÅŒ¯¯ïãÞƒ˜Aöq™L¶k×®ï¿ÿÞÕÕu×®]¨á»­Æ=®èÉänŠÎ½{÷Ôju>z EÛˆR´  EÛˆ�R´=±÷–¢Á`èt:½¿IWW×;w‚‚‚ô Š¢ ���3´^.,,Äqü‰’D���ð, P¼† …BŒÖDûº¤7 ºo{ÜH„F£a „J¥M3! …bd%B1}¦×ét:#ŒïSØQ©Ô¡õŠ…B!“É%%%Aô¸hÔ/‘£ÑhÐb©Ñ@DKK‹1ea’Ëå|>¿ï€’# @À`0Œ©ãµ··+ c*‘R©ÄqÜÈÇÛÚÚŒIŽJ¥ÒŽŽŽîú¾…BAÑ ýýýŸ¨âô*rT*Ucc£‘‰ÃWÆññ·µµuuuM‰D"Ñã™F4‰D*•Ó§„ã8ŽãF68à8ÞÜÜ<P94‡É|‰¹ÚËÑÛ¯jµº¬¬ŒD"õsÃe_8Fóðð7¦^¥P("""ŒIË¡Ñhžžž}l—q -C¯~°áñx<mò0ÐÀ &Óà ÑhÂÃÃIË)..f³Ù•2¹4£¿ÉdòãÖ\]]Y,Öãëq¼íAä0™L777}^ã€Ãáðx<c*‘³³³R©ÔçP1Ðö@#ëx(Ë€1•ÈÓÓÓÈJäííÝGË‘ˆƒƒƒV«ðf²¶¶¶²²z\ì-T„F£y<<µ›PêÏú���ðRA£ÑФÐ0kß3ð?"y×TWWCý���zýf@6–bÖT*UYYY?cê¡Å^´'ZbT*U2Ž�ð8( q,ó e�GøÖrLLLPÖ“¾… •Jmmm%ÂÙÙ™L&£Ôß�04”””x{{Ã\�ž r‰œ¾N§R©}ä¯z^‘óDaC£Ñ‚ âáÇ ÅÙÙY£Ñô±]�œ‚‚7779�ðÌ( ‰Ä`0PtΡñEz ‘C¡PPÀjN§Õjq×jµðÍ��ŒDPØx‚ ô‚G§Óæa"çqa­��`‚i9$‰Éd’ÉäA<Ô' ƒA„V«Õét l���Œ ‚ àA‘¡™L&…BÑjµƒ!xz9èÁAà8Â��ÀèZ­Ö ƒÏÀú…ö rd2Ùõë×Y,VXX9Ð���/•àÑjµÅÅÅNNN(Ýû`‰6fÌ¥R™••eccÍ���ðò  ‘K[@@Ààj9(´¢Z­655•Éd¿ýö›½½ýÀ>���†ˆÅâ{÷ŸÁÁÁ¦¦¦´W‘£<ÎÎÎ*•ÊÒÒR$eee=Ú˜bâ���zd2ÙíÛ·5 Žã ÃÆÆfÀŸò5ƒáäädcccmmÝÙÙyùòe777‡Í��`(•ÊßÿÇqµZE£ÑCØôKä胃ƒ•••½½=—Ëýõ×_===}|| ©���F.8Ž_¹rE§Ó)•Ê)S¦P(kkëA}âSD`2™L&ÓÜÜœÍf·´´üòË/ …ÂÏÏš ��`dAÄ/¿üB„L&›1c™LFQ×›§Ž±†™™™««kyy9:XTTTUU­ ¥)�*�ž‘H4gÎ2™lii9díAäôÿ H$N òõõ…&† cÊ,�C ‰DJHH@Yמx¦F£,‘cnn/•Jû CšL&C+C‰L&ƒJ�€ç‘:ýê0�A÷¬ ƒ½v���¼T‚­W‘#‘HRRR Ž���€âõ×_711éA䘚šÎ›7*���,-- …Þ4Gí¦Q©T¨#���`@ R©(úÖü��€!D����"����‘���� r����9����ˆ¨����D����"����@ä����Ö¾ÂÛ…‚‚ý¿NNNÃ°æææššww÷1cÆôvmAAP( {Îä?\.·¬¬Lÿoß���F¤Èéêê:qâÄW_}ŠaX[[›••Urr²¿¿ÿ… ¶mÛ¶qãÆM›6õvyRRÒ­[·®]»ü<ïwãÆÄÄDWWW‡ÓÐÐÀáp¶nÝêáá-��`<"§¦¦fçα±±?üð†a?ÿüó»ï¾{ìØ±÷ß©UUUÕÕÕÞÞÞ%%% èªÐÐP6›ýçŸvtt`vóæM¼¼<©T:mÚ4&“yéÒ%ÇçÌ™£Óé.^¼ˆ®233‹‹‹ëã-§NzàÀ‹/îÚµkÏž=›6mòôô,..nllD'„‡‡;::Þ¹s§££#::º¨¨H,ÇÅÅ™™™avùòe”ÕŽL&Ïž=Z��à…@¡P(Û¶mS©T¦¦¦™Î0 S*•UUU<ÏÊÊJ$±X,¥R9qâDN÷ÓO?µ··“Éd…B±cÇŽ7nðùüS§N …B‡“}óæM™LF¡PbccW¬XqüøñwÞyÇÂÂ">>þÇ\¿~ýéÓ§W¯^M"‘<x––6vìØu—²²²_ý5$$dÚ´iÞÞÞB¡ð믿vvvf2™III·oßæñxß~û­H$òóóÛ¼yógŸ}fff–ŸŸÿé§Ÿš››ûùù]¹reåÊ•8ŽWWWïÛ·ÏÛÛÛÇÇ��``0jµš ˆÜÜÜ[·nõê>àáá±ÿþ   S§NmÙ²¥¶¶vùòåûÛßbcc.\ˆaØœ9sfÍšUWWçèè¸cÇŽ´´´ˆˆˆ”””¢¢¢÷ßìØ±†mݺÕÙÙùñ›kµÚÕ«WS©Ô™3g=z4>>þÞ½{OUŒÓ§O_¿~}Ù²eiiiaaa_~ùeII ú)??ݺuNNN[·n …ÿú׿ärù_|‘ššªÑhÖ¬Y���à…Зû€——×_|QVV¶}ûöU«V………%%%ýå/1<gÞ¼yl6»¢¢¢¶¶¶¾¾¾ŸO%“Éo¿ý¶Z­þàƒ>þøã¸¸¸7Þxc Š´~ýúÇåÜwß}©€���†©Èioo?þ¼³³ó¬Y³>þøã>úèÚµkÝDΟþ¹k×.2™ìëë+‰ú/r:¤P(ÈdòÚµkmmmµZ-Rž‰ªª**•ºråJ&“ ­��ðBèÕ°ÖÜܼqãÆcÇŽaæïïÿ׿þõñsþüóÏäää?þøcÞ¼y{÷îíÑ9íôéÓB¡ý}üøq•J…a˜N§;zôèþóŸ={ö,[¶¬³³óàÁƒO|ׂ‚‚»wïFDD<ƒÜ®]»>ùä— }���À‹Ôrœœœ.\˜ŸŸ„AYY‡Ã‰Ç0lüøñQQQ¹¹¹†…‡‡Ëd²œœ¡Pèîîîååuþüy__ß… ÖÕÕ}ÿý÷,+!!áøñã_ý5…Bѧ#åñxiiib±˜Åb±X¬eË–õñ–EEE¼sçŽL&Ûºuktt´\.ÏÍÍÍÎÎæñxUUUsçÎuwwïñÚÄÄÄ}ûö9r„J¥~òÉ'ëׯ‡V��x!ôê±fii¨Óé´Z­V«µµµ]°`ò0vvv3fŒV«<yò’%KFã¸V«}íµ×8Žã~~~“'O¶²²ÂqüÝwß5k“ÉÄqüƒ>011™0aBttttt4º9•J:ujbbbo¯hooÇf³—,Ya˜§§'›ÍFÏ;vlbb¢——RÈ¢££-,,0 ‰ŠŠŠ‰‰¡R©8ŽëtºÉ“'ƒÈ��2ºy¬‘ètºR©‰Dr¹üÒ¥K ,€:���KKK©TªÓé<¸{÷nˆ±���  r����9����ˆ�����‘���€È���@ä@���� r����9�����"����‘���€È���€!á’ÉdKKK¨���``Ô2¹W‘#•JOž< u��� 3gÎÔ§cþ‘cbb2}út¨ ���`@077×ét=k9$ÉÔÔê���(‘ƒòå Á}����"@ä���� r����ã‚úÌW2™L½ÂðÇq™LFÄ€ßÙÔÔ”N§kŸÐét …B£Ñ øi4š™™Ù­–—¹;i4™L6w677§R©#¨¡R©”Jå€ß™D"YYYˆñA©TªÕê¡9ú¶É©S§¦OŸ>xcܰ-ûó ÕjïܹC&“ýýýõ»YÕ¢Ñh¾ûî»™3gžͰ­•J•––ö·¿ý úƒN§«««+++‹}9kC«ÕÞ¿_¥R½‘£T*U*Õ0¬šÌÌL±X<¨Ë僡 ¼XŠŠŠ CCCGâ”yð8{ö¬D"y9»ÓÉ“'»íæp¤R©V«þÝ µµ5;;ÛÍÍmP¥Ú`\ÏCiii^^Þ3Ë Ör���€!D����"����‘����ÏÀP¸'–••=îSH&“<x@§ÓǧT*ËÊÊÌÌÌ|||Œ©~ ýO Fž`ööö...Ý~jjjêèèpww·±±yyz§L&Ó¯¨†7­R©T*•&&& c¤Ô‰N§+,,Ôw'OOO£üpz,¸áº:•J577×ÿ«V«år9ƒÁ011AG …J¥êæ€.•JqG}I"‘tóY`±X#¨BÚÛÛ[ZZÐß...J¥’Ïç¿òÊ+¶¶¶/»Èùûßÿ^SS3~üxög2™éééñññÎÎÎ%%%ñññ¡¡¡W¯^5¦ïdÆŒZ­6""}---§OŸîÍß#++kÕªU+W®Ü»wo·Ÿ~ùå—Ë—/oذ!&&æ%‘7R©´¸¸X£ÑÐh4±XìëëëììL¡PðÍÍÍÕÕÕg̘1#¢N‚¸qãÆ¢E‹ÂÂÂT*—Ëý÷¿ÿ˜˜h|Îãò¦­­­¸¸í\ÁqœL&ZXX`¦R©êëëëêêØl¶¯¯/’: õõõ®®®†Ó_>Ÿimm]PP ‘HX,òÇ …vvv#¢BÚÚÚ8íââÒÔÔ4{öìÖÖÖ_ý5%%eñâÅ/»ÈA|÷ÝwNNNèï›7oº]*м¼< ÃÄbñƒ‚‚‚AII úÕÉÉÉÛÛ»¥¥¥®®¹'655yzzŽ=zDtvéÒ%ÔK8Ί+îß¿/‘H Ð ¶¶¶þþþ<¯ªª ðGÕ××S©Ô††wwwÇ>|àëë‹aXiiigg'º6$$ÄÂÂâþýûr¹|âĉH¨ßºu ðèèhÇÿøãt¦™™Ù º>,‰¤´´ÇñÀÀ@‹UVVÖÖÖfgg§V«õ3S[[[‰ÔÑÑA"‘lll:;;Éd2ÒqïêêB§Ñét”J¥RéMLLFâ¦Ôëׯ/\¸pÆŒ§Nâóù+V¬8vì˜þW¡PX\\Œþvpp@zúpÐÁ1cƸ¸¸ÔÔÔ´¶¶úøøtvvòùüqãÆ ÕY©TZXXüå/Aö€ÜÜÜÊÊʰ°0 Ãx<Þ£GìììD"QSS“¡Â'•JU*ÒbÅbñãnè!!!h¯Õ•+WþüóÏÙ³gÿnÐÚÚzðàÁ«W¯nÚ´iÉ’%ß~ûíÙ³gkjj %kGGú;88õÿ{÷î) t0**ŠB¡èt:4V /"<<ܨDŽ!óæÍc2™eeeè_‘Hôý÷ß#Uñܹs®®®ÇŽ;~üx```[[›½½}rròï¿ÿ¾eË–ùóçcöóÏ?ïÙ³'11qäÎß¿ÿþûO>ù$,,¬³³“D"<xP,çää`V\\|ûö펎Ž;w¾õÖ[R©ôÂ… è´´4ooïuëÖakk{ÿþ}ÔçÞ{ï½ÚÚÚòòr$Ô.\ˆf….\øÇ?þ1iÒ$¹\ÞÜÜœ––†ô­áO]]]ggghh(²uøùùa& MMM)JGGGpp°££ãÝ»wI$RHHHcc£X,?~<‹Åjii©¬¬´±±Q«ÕA0™ÌúúúGYZZÊår ‹‘h‰Z°`“É<uê†a£FÊÌ̬¬¬œ8q"’7'Nœøê«¯‚ƒƒ¹\®µµõž={,--8pãÆ //¯ÚÚÚÈÈÈõë×§¤¤¤§§ÿóŸÿÌËËËÍÍÍÈȘ:uê0/8…B±±±Q*•<F£Ñh4{{{¤ñ(•J‰DbooP__ßÕÕ%“Éôó‰úúz d©®ªªÒODF4W®\9~üøš5k–,Y‚aXBBBBB‡~xüøq ÃJJJ>üðCFcgg———·~ýú¥K—–––._¾ÜËË‹Éd^¿~===}Ö¬YW®\Y¶lYll¬R©¬ªª:qâ’èƒÊйäää\ºtéÒ¥K†¹ŽŽŽÄ0ÌËËkÇŽÅÅÅ{öì ËÈÈX½zõµk×ôS¹Ÿþ¹¤¤dÖ¬Y¯¼òʲ  ‚_»vÍÔÔ4&&¦¹¹yÓ¦MÞÞÞ[·nÍÏÏÿôÓO£¢¢Þ{ï= ÃfΜ™€®ýá‡jkkgÍš¥7|úé§ùùù[·nÍÈÈðööÞ´iSsssz=1â�� ›IDATLLŒ©©éµk×Ôjuvv¶N§›9s¦R©\¾|9‹ÅÊÈÈ8|øðÇ7nÜ8¢¿4.—keeN£ÑòóóQ_"¢­­-$$D­V)ŠÒÒRssóðððÀÀ@>Ÿ/êêêFîææÖÖÖöðáCc2=UTTìܹ3888##cíÚµ7oÞLII©¬¬äóù7nÌÈȘ?þ©S§ÂaØçŸ®T*gÍšeoo?üKÇ`0BBB,--ëêꊊŠär¹———··7Òxêëë 5€G^+‹•JeWWW›Ö;::¸\.—Ë%ÂÁÁÁz¡C‡îÝ»·yóæŒŒ __ß-[¶444¬[·ŽËå.X°à»ï¾›7oÞ?ü Õj—,Ybjjš‘‘‘ššÊãñ>øà£Òr.^¼ˆb²õsJÕÖÖ–™™™ŸŸoxpìØ±[·n3gÎêZ­öÌ™3jµúÒ¥Knnnû÷ï///GsöÌÌÌÒÒÒ>®åp8ÿþ÷¿§OŸ¾víÚo¾ùFüÎ;b±X  ÷ïßõêÕÕ«WϘ1ãÝwßÕh4ß|ó\.GsÀÌÌÌööv#ø–8ŸÏGFEÉ ‰D î1è“……2'¶µµa&—Ë[[[‡óîî礽½=33óþýûèßøøxww÷’’’ÌÌLd¶Õ3~üx4±)Ec2™¡¡¡r¹¼¸¸8//ÏÒÒÒßß_oì­e­¬¬ÚÛÛY,—Ë%“É £›àár¹È-ÅÁÁ!88ØX;F\\œÏ¦M›‚˜9sæœ9sH$†a&33S(Ù› È9xð ~-§ŸÏåË—1 [´hÑøñã‘F<wîÜ‘%o0 £Ñh'NœJ¥ï½÷^nnîåË—ÑŠTWW—¾€!!!=^;þüó´Þ¿ÿáÇ!!!!!!ȼðꫯž8qâüùófÁ‚ú3U*•þ)†ë¨#W\\Ìb±úî P(ô=z´••Õ`ǰzø|¾¾¹ÃÂÂjkk÷ïß_\\ _ÑA¬\¹rÉ­V‹dƒƒƒÃ¸qãJKKù|~]]‰‰‰P(455e0¨e---Åb±¾eÝÜÜ„B¡P(T(^^^|>ßðÎþþþ/C^Ê]»va¶yóæM›6)•Ê#GŽüõ¯Å0 Çq}‡qtt4*‘Óÿa-i¥¦¦Ö××ß¹sÇÃ㛺3â077ß»w/ÒZNž<‰aؘ1cRSSÛÚÚrrrº ƒŠŠŠôq·÷ßÊ”)YYY|>™­“““Ï;÷¯ý ð£G¢) šå¥¦¦J$’óçÏ k@ÐÑÑaeeebbÂãñT*UuuµR©ôõõ533»zõj¢r©T*§wœµµµ ”H$]]]¦¦¦#Nä¼õÖ[gΜÉÈÈX´h‘L&;wîÒÞ ÐÔÔÔ¦¦¦[·nyzzÞ¸q###ãý÷ßOJJJNNFêõHD¥R!÷333OOO$9ººº]\\Ñ™µµµ•••†îÎ666555¦¦¦ún0Òñöö -///** ,,,,++«®®îã’ .ˆD¢mÛ¶‘ÉäcÇŽ­Y³9¶™˜˜¤¦¦Êåò³gÏ"/ƒ—Eä°X¬×^{íÁƒr¹|êÔ©ÍÍÍéééùùùyyy6l0¦‡µµõܹs‹‹‹ÓÓÓ«ªª®\¹²nݺI“&yyyEFF–——ÿú믭­­=^;eÊ”dee566~þùçqqqè[¼xqJJÊÂ… ‘'1•J]²dÉ… ÒÓÓ;::RRRV¯^=kÖ¬QEH×ÖÖ"ãZ¶··G–zƒáääÔÜÜÜÜÜÜ£ZÉf³…BaSS“T*år¹žžž,ËÎÎN*•655uvvJ¥Ò±cÇŽ¸žsøða …²víZ©TÚÕÕuøðáøøxô“££ãŒ3šššÒÓÓ<x››»~ýzŸˆˆˆ’’’ôôt …2nܸ»wïòx¼Wp*•Êf³ASS†a2™ÌÄĤŸ«P...ŽŽŽC3¤QQQÛ·oßµkWrròŒ3.^¼(“ÉôFÅØØØ‚‚‚ììì‡r¹Ü9sæØÚÚ^¹rå‹/¾àñxT*õÍ7ß$“ÉË–-ûñÇÓÓÓE"Ñ¡C‡V­Z5wîÜÁ~y …BÙ¶m›J¥Òh4555§ÿ€J¥â8þÄɦD"áp8S¦LÑo¸‰Daaa1112™,<<<** -ö [[Û-[¶@À`0-Z4þ|µZmiiåááџ׫¬¬T*•~~~ƒ‘‰„F£Q(FóDóŽH$?~ü”)S0 #B©T†‡‡O›6 V H¤¹sç.[¶ Y{<==Ahhh\\œµµutt4r”P(NNN“'OFé:;;§§çæÍ›Ùl6zVLLŒB¡Ø±c*2•J‰‰ …@©TÆÅÅ­]»¶?öL.—Ëf³cU™B¡ÐétNןÉVVVT*U­V«Õj33³±cÇ"·xtÄÇLJ µZÍb±¬­­GE„V«µ±±±···¶¶Öh4huÇÑÑÑÍÍÉdZXX k©Tª«««ƒƒƒV«¥ÓévvvO4­TTT¨T*???ö»™LŽ‹‹Cm*—ËcbbÖ­[‡ãxDDÄ´iÓÐî@@§ÓçÏŸL©îîLš4iâĉ¡¡¡“&Mê§¡»¨¨ˆD"éÕˆ…N§“ÉdäXØwϱ±±AmjجA Ïx½8Ñét4ÍÎÎŽÁ`0 ;;;­VkaaÁ`0´Z­™™™FCíííû¿ÙK"‘ÔÕÕ±X,ww÷¯ ‰Äd2Q>ž'žìæææææ†ZÖÖÖvÅŠ!!!ŽŽŽ“&M2"<<<6mÚäìì©Õj;::A``àîÝ»i4Z||<êK2™,&&¦?3{×ÚÚêèèØ+ƒÁ@í›››{ëÖ-NÏ®Tt¶6j5JqíÃe€¾A)ÚÐßa8ÈÌÌìêêZ¸pá`l¿@[š ÷Æ ú䃑/¥h¡É Äbñ¢E‹Ãî?Ì»J^0Hùrz 0<Ñ'/Œ|9(EÛHI^Ðÿü–––—ó*ÕÚ¯w®úíj6UG`kHÒ:U§ Ä����` ¹ÕB)(íT7íË!‘H£œÍmÙP5���À�ë²¶l‹QÎ3ß%‘)I���"@ä���� r����ãây÷å466644 ¡p/ƒJee¥q’1D£zðèèèÐg|)<žðiÀ©¨¨‰;f„ÂÂB©T:üßsFµZ}çÎa[Ïç¹DNMMM^^Þ RÃâââ_Ä”Á†Çãݾ}»[àE ¨¨¨¨¨èåìN¹¹¹eeeÃs¯Å£V«srr Ó€–óÿÑh4t:}0vo ƒ”íeì-0š0H¡q´Z-Ažžžžžž#±Z©;¡½®Ã¹;éã' †úhee5a„Ô )&Ú*Îf³õ›»‡-ÖÖÖ/@ähµZ+++SòeC«ÕÚÙÙ”‚ÃNÇ`0cçöˆÇñ—¶;á8>üGØ¡ü@Œþë�÷����D����"����žÿYË!‘HæææP)���ÀÀ¨5drÏ"GG1©·›õù•Úw'†j���ž“c7aÖ25­‘CÈJšM Ÿ;"¢ˆ���Ü–NFÖQh=i9†Q¨tÜÚcçùºþßÑ\Rm&o‚š��0zv¨ÌÒW&äö÷|k*õ’d’ªkj&Æ¿¶<­ì¿§Z\Ýÿ7ˆwÓL`k %���Œž»íÌœ&ºN‹÷ó| •Ž‘H†u4–œýèõû7²¨n®®ÞCD¢Ðú»ÅZÚÙª”à Z��Àè!‘H$2…B¦<í…ZZ.ູ¹Rétzuei`Ę׶Ÿ¡Ðèv¯Œ{ %K§Õéð'&l���Œ‚xÚ+:K´õ¹¤y5Ut:DAÍͽÆúšÙ8ÎÙúãÓ<^g-)·RÔCC���=¸s¤È*@Òñay/$/– ¸5U®®.$‰DüWj©Õꦦfçéô,‚À0Z��Àø!‘0ŒL<͘_Y^îææJ§ÿ?'‚ÿŠÉÔ'����IEND®B`‚��������������������������./saods9/doc/user/catalogs/cscsrc.png���������������������������������������������������������������0000644�0001750�0001750�00000633313�11332127303�016415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ)Ýœ´�� �IDATxÚìw˜UºÿOåÐ9LOwON0C‚¬aÇËUWEtw®UÁQLq”•ÕE õ®¨âŠ¢(Š:Hf†É¡§{Bç\Õ•¶W—õ®¿[Ÿgžyª«ß:ç[ç¼uÞªsN×E ƒçñÇ÷ù|àéè8s¬@CCCCã—€”`8Vâ² Ò>8ŽAƒA›ÍÃð›åçç?øàƒEEE999h0\µjU[[Ûã?^PP�A�àýÿýc¿å†ßjµ¨¡¡¡ñ‹@”¤·7½ûß÷^žÉd~¸yWÿ¿ôÒKsçÎef0Ư½öÚìÙ³EQT÷¨;ßVÿ÷öö>õÔS·Þz+êñxÚÛÛ{ì1‚"‘ô-0 Ÿº-ˆâš~‰å>¤ØÙÝây1?×’fùh"m1êtîóGq-vÛ[»��#+òëÛ|�€aeî–îI’‹Ü¶h‚I¤X»Å€¢ð@0N“¸+ÇÜá oŸÝ(-p „b Ë;í&I–ƒ‘¤AGÚÌúîÞ C•%ÇÛW9{úC/æåZØ ‰§ÍFZO“¾Ž!%ùŽ–®þãí«JÝm=¢(ºlñ$O±6³ÇÐþ`Œ"±<‡µ½Ç¼ýˆŠüÆvŸ¢€’üœ@$‘f¸\›QQ@ ’ÐÓdŽEßÕ‚`hX©»±ý$a¹ÞH†Ü3Ç‹áXÊd zÒÛÁP¤¬ÀÑ|¢°ÊW‡7 ˆRËšHeâIÆfÖ8Úˆ‘Và´¶yN6¼<ïhgŸ"+%yö`4•b2«‚€?œÐÑ„Ãjìò! /Ïo8±„Ë s{6#¸r̼ †c)“ž2èžþ0ŠÂ…Φξã퇖¸º|^òÖ“‰%«IG‘x¯?Jàh¡ËÞæ9©êóš»údY)γ‡c©d:“c5 0<ŠÓî´›;ÿAÕ—8úƒ1&Ã;sL¢(‡¢I£ž²iO_Aà¡ÅΣ'Ó|RóÉŸÁ'}þ�€eÙp8||cþ½-<A²,ó< …~À&»-˲$IªñØ[,–gŸ}vþüù …B<ò†a?š:Aï~٠ÓNý‚þØtÊe!Ó©¤¯w€Æ®´wùDž)ÍÕ7´v'ñÑ%öÃMñXlx‘µ¹ÃG rèH8Ú×ï7S0ª=½@âó,dS[O2õ­ýè2û‘æ®h$Zâ4ôùþ Ý€I<ëñöc@´éÑ–No:•^h©kêJ$âcJíuM±hlHž©ÛÛ†œf‚M'½½&p¨­Û'd˜r—¡¡¥;‘ˆ.µ×íˆÅbÊ,­ÞP(’o§£Ñho_ÀDB8$vxú1“o£¶{’‰øè{ÝÑÎx,6ªÔÞÐÒ‰D‹sõþ`ÿ@ЦG!ÓííG!Lj7wô¤’É‘ÅÖºæÎx<>¶Ô~øhg,«p=½@(×L°LªÇ7@¢²‰„Z»¼<›®pUacTûX¬ªÐÒÖí …Ây6*‹ûúüˆÔÑÝ+ la}´Í“HÄG•Úêš:ã±ØÈ[ckw$-rèÁpÿ@ÀJ£@â»zúEÈ5áÍ=ÉdbT±jS–søhG,+s½}~ ä0á›öøú D²ÐH[§eRCóMõÇJ,çpSg,«,0wt÷Ca·•L&âÞ>¿4*·w÷J<[ìÐ5¶zÔªW…(¶6µ÷„ÑÂ](îXh–ùNO,ó.3ÙÔîI&£JìuMñX|L¹šQ´Ôeèí÷ûý¡#&pL·o�‡$´vz™tª*ß|¤ùXի†æ›:{ú‚Á°æ“šOþ<>éñö ûŸg—³,û£< ÃGŽ7n\:Vw*�� @€ †³ö£FbYV=VQÔï¡ì± #0¬~;a„|õz½‘H@PkoÌj V}6ûþH:Å •…65 �€`�€‘Â-z‚ $ËGÓ<€ÛJË Æ3¼(!0d¢q#ËŠMq)VDÈe¥Ã .Í gðÙ…Ä»‘ %2AÊî´è 3³‚NdI¶›h@mްìs;ÌZúŒ4>²Ìùe}M`g +Ú×èŠ2¬ÌÕÖ‰&3¥yv†“ºú£n›ÑlÔé0ÑİÒܽ =:›4¢øóºnAFVäÕwR¬P^èˆ$3Þ@¼Ða&I¢±;`Ñ“å9_õê)|beÁg‡»)3´à@k?Ç‹C‹s{éHªØi0Òì å˜tùË7-½ UîüâHM`ã« ¿:ê“eeX©«£/I°%yöŒ wöE]VƒÍl8ÜÞo¢‰áß ›8¼xwE ‘îÆî`2Í—äÄÒ|?^c¦i²¡+`ÖCŠû½zŸ4²`ס.GÇ É?Ø:áÅ!E¹ýQ¦?œ*rZaiî Ùt¡Óº¿9+ÌCèøÊ¯öJ²\Uê숅bL‰ÛÆKJGoÄiÑ;¬ÆCmýFQêÜÛУ#°‰Ã‹¾<âE`0¢ÜÝä ÅÓ|YAN‚<±ü“^O5túM:bè1aØäo…’¸m€åÄŠ"G Êô…’E¹Ú<A›.vÛj›| WîÜ]ç¡pt\eÁþ¦^Q’+Kœ"cJÜ6QÚ}á\‹Þi7líS…íiè¡ l°¢= ^ÃËÝ-ÞH,Å•åÛS±{ –g7 t}‡ß¤#*Kû¼z;{DÁg‡» 5$¯®ÝŸÎ…ŽP<ÓLæZp?ê Z di¾ý룪0×çuÝŽŽZðMK?/JCKœÞ`2M»¬šOj>ù󸤑&™��üèóM¶‘Ïnê>øêÞ“ZÝ»®åÔ!r²±7˜ºkÍg£Krî™y–ÍH}Vç}쯮=¿ê¦ê‘4‰©#:^¯q»Ý7Þxc&“Ù]ßûðkû:úãÊìf= Ãpgü‰ _¯ÿ¤±Ôe)vš!ÚüE i°’8öŸ '–ê Kœ7ÄèõúÅWWf«oë‰spÃxÕäâ T™K8­ž@’¦È»/ÖéñöE9%�Ÿ‘¿b§qöyE mž8‡(0ª�Ø@×N--·Ãà ͱT&˜’RœJdœ]ŽE°=h1PE¹¦ƒAÇJ\¦¶¾XFËÜæP‚ˆ±%N“¤@ý ·Mo6ÐGºB6#U˜kÚßБx‰Ó|ÔQ¨Ômî2¡Wî6³‚ÜHæÛ :ŠhôDrLt¾ÃTÛê7éÈâ\Ó‘î0‚ ¥.SO0g„r·%Á ¾PºÐaÀ0¬ÙuZt¹Výö€EO9͇:‚†•¸Lý –—ÊÝæpŠë²ÅN£ ö¾¸Ûª·éÃÇ„}Ó I¼ÄinöF$”¹ÍQ6˜È”»Íœ¨tù“ùvƒAG4tGrLtÃTÛâ7ÒD‘ÓÔІ¤ÔeòSQ†/w[RÑJ: Ž5y£¹Óf8Ð0ëÉ"§¹®3„ah‰ÓÜ9HsR™ÛMñ}¶Äi„ ¤­/î²êm&úpgÈj  sMÛ»L-¾˜ +ens Æâ™2—I”Îdž]oÔ‘õÝa»‰.t˜ö·ú 4Qä47x„”ºL½át$Å—çYÒœÔLäèI?ÚÍ5ë\vÃ7m³Ž,ršê:C†”¸ÌÝþD*#•¹Í±´ÐaŠFFZ{c.«ÎnÖêªÂµI+q™Úzc¼¨”¹ÍÁ8ëeJ]&A†:y6½IOé Ûta®ñ›V¿ž&Šæ£žˆA¥.so˜ '¹Š<sš—<T~Žž"‰£=‡™vç÷·L:²(×t¤+„ H©ËÜH&X±<ÏO ½a¦(×€ hKoLóIÍ'ŸÌ³üÁKÏ.WÇr~ôA§®®nüøñêX΢—¾`yñ¤SÛÜ?ó¼*ŠÀ jhh5j”šòãoíï§û©@Œ‰§ù§ßùFQ@cwhêÈ‚\«^Q†×­[‡fG{6}Ñ�8ÒZ±ùÀC³&ó¢ü×Mû›{Â�€»›ÏSA�¬À4I”:-ÍŸꌤø”LŽZˆ‘á+ˆöCöñå90}é­­fgÉ]לw´UêŒedI”’þs‡–˜í3÷EY…M4¶í`_¡>«Üp°3Zï‰ +0Ž-µãœB÷4s-Ô˜bs,-ìm bUíÈ"óèb3'Èb& ¥ƒÕcÆ»oˆÉRi®î῾uíåWÙ•£ž´Œ]VÒ@ã ž˜&rÍt³/!+pi®Ádb)qT±Ùãý1vˆÛ˜•ž@*ß®£¬Á3ëI»‘l쉣ZäÐwúÓ FSbêpÁ8W•oJ°Ro˜)rèqmðÄrL”Å@Ô{bçÙtmý)†SF›¼a6œàGšÃ)±?”: �ÀMÞ¸ÓBh¼¾;¦§§…nîMˆ <Ôeè ²Ñ”0ªÈäOþ(;ÄmäDà $óm:šÄê=1³Ž´É£= A‹ú®@:þ°LU¾)™‘}¡tQŽžÀÐzO,Ç@Y Dƒ'Fx¾]×ÑŸJsò˜sO(Nðà MÑ”ØaJsõŒí‰;-”‘&<1=…»,ºÖÞ„ ¡yOˆ&…‘E¦`Bˆ².ƒ CÝý‰<­#ñO̤#fªÉ—€ ¤8×Ð`âiqt±©?Æb™Ê<cšS¼¡taŽŽÄ±OÜf m²Á#0,ß®ïH%Yyl©ÙÊ„ÜðS”ûÂLI®‘Æžx®™2êˆzOLGâ.›®µ7ʼn`d‘±'ÄFŽVî2H2ÔÞŸp[i‰×{âFšp˜é&_Bà’\ƒ'ÀÄŽ ã±ÌÐ<#Ë+=ÁT]GX½'fÕ“6#ÙØÇ0¬0Gß9N°ÒØ“7Â…âܰSŒ‘úÂL±C¡H£'æ0QfÑУIÜmÓµõ§XŒ:&ŒQhR«¾ÌiÔìK¸¬´æ“šOþ >Yï‰eùÁŒžœ0þ}÷ü}Æ×ž7´ÙDyw½owý±ÉÏŸU’—c8>q4{À¿›të³;%I®ï -|á3YVúÂ)�€ŽÄœuNö� á”x¤;|îèª1Ã+¿j í8˜Pîhîìéíó¯*nÚçÏ5Óž¶V?‹IÀÎÉ(%'x�àZUh¥Q¾/ªU±ïHçèÂÒÆÆh4>ÛÝ\šC^vö¤p ÷’±UžÎ69=q”ß—œ6¡ôݾZ`;§X÷~Ã)˜ÛL]2.¯­¥Iä3½tH‰ûì¡9¯mx/™b\ECÉ¡£ÑŠ+™LlÀQ’c¢°Ö~á²\ºÞËð¢2±ÌXïe^Sdô„¸hJ(ÏÕ¥9Ùá&’ÂѶ†ÄÐÕØË"˜Tf¨ó2,/UbjõgŒ8Ô¥¦¥¾(—g¥n` 4žk"šúXIcŠô‡{Òœ O(55ö2iNžoˆ 8_d§%xBŒYOXtXK?Cp…SwÄ›æEeb©±ÞÇ0¼4ºÐØá#I¡Ì¡cxÅÎä˜Hš@ÛC íTC/#ˆJVØøS»?gÄ!.}Œ‘z£œÛB¡Ü6ÀèIÜi&šúXA“¾fnìeÒiXž!ý1¾ÐFË ÔígLzª#Z À.}½7Í ÊÄRS}/ÃpÒ¨B£/‡“B©C—@O˜µI=µ 0ŠåоJx\±©#˜‰§Å!N}‚•}QÎe¦0iëghsYȦ^VÀ¤2C]à òÄ2ÓÑ^&•‘ªò Á¤8ã l´àv?kÒ6ÑÒÏ( <Ô­?âMs‚<±ÔÔÐˤ9id¡7ʇBI͉ 'ÄÚ ¤ÂÚFJtÃ‰ÂÆ»‚\,-T8uÉŒì‹pN3I`HÛ�Chž•:Ú÷mÕ÷0¬ M(55÷g’¬XéÖ‡SR”Ë·R· °FÏ1ÍýŒ,C£Ýú:ï U?¢ÀЂq¾8‡$à ±V¡ù¤æ“?O €¿mä¿—“bO6"À0lÖOÜ|îIöOm¬ýÞø4©Òõ_×M~øÕ=ÙÈ4udþü«&˜õäñÆÇæSÃ0\è0¾8šËª�ø‚I5Þäçÿgñåyvƒ:d XȧGc‹×|°»öðØ|²ÌÄ•;©¾pFPÆŽ¬‚8ÉÛ­æ\w¡Õl"P(Š‚øí$q°ÿ`ÝW ]±Hø£]_Æã +Îw¢³/ûÕySÎ2ŠQŽ˜iäó/¾l Š,Ùõ˜EO?gDq¾bÃl°S°ŽÂ-z|ÇÇŸ6�� »7ÔÒº~ÆÌþÝÕ y #<ïú+*ݺ@(’a™@J>Ò›ÁPxxõU'£�hTýM7“Á'ÙâÃi©ÐF°¢Òlz̬Cû2† q’û»‚ÆÑû:^U.ªi€Kd”â"ÆJ=Q!׌“8Ü<ÀQ8R’Cìa[¤û²=-Êа<ªÎÇ2<(sþ„ØÝ‚ ¶�o P·¯óe0‘OíëLË�Y@ð0Tä’žJI6‚“”ÎoÕcVÚЗÁ1d¨‹¬íf�)¤¿êdx Tº¨?Ë(Å9D"#{"‚ÈÑÜ4À‘8Rê ô° +þNØ›æA©ƒ ¦Ä¾˜è¶àµx=‰æ[ðÃ>Eà‘ô¾Ž´¤@#òéƒ=,+€Š\Òáƒ))߆ ²Òâ-:Ìn@ëû28ŠTºÉÚ.FÐèBº¶‹áD0ÔE¶¸+Ù‰$'wG‡ÓSHS?GâHY.qÀ£ £÷t¤ sSõ½™JD(%öÆD—ǨÕÏé¤À†ö².¤÷Fò²Œ�ÊsÉÞ˜HJùV\R@G7ë0‡­ïÍ`(\•G~Ýu¬ê÷w1 u’A>ÊH…v"Í+Ýa!Ç€)ôh?G`Hy.ù‡ hl½·ƒáePå¦û2IN)É!"Œä N3Žcp‹Ÿ£ ¤ÈNò² )ÒíéH‹ 4<ªS…9Èþ˜8󬸠ö o¢Q§ ×|RóÉŸÇ'Çé²<A,/5õDšz"G=aõ¯¡;$HrvRÀñÆ—¹-Ù¿ò<kyž•&0†Ž·Ïnó‚|üÃ$)’¬œ4PôÝSA%.óâßžýô;û=þ� "Ïzßï&»lúl�’�l¢°_°&¸ÌÒåóš!X‘)ÕÓ¸ ð#‹¬{Žö͘{Íù&Ê`jiï¬kóéŠ\�@ ���YVPƒCQ�B™`Œ@Äa¦¼¾¾@4yîøÊPœiëüæ’óY¡( ÍÌ÷›êSÁbà�HÉ˪ÏC¬%�ˆ$û"™T4PRà”½}Q;Ÿ°˜M»÷× ˜ °…y&䀗'08ß·^†Êlp0%ÒJ‰Ð‘\Ø@!Gú »ŒÈ~/Oáp¾iè�XàÞ¸a•rÌ  '&çaƒˆ9:ØiD¿öðFÎ7#‡|<†Â¸;"%yPaƒã¹7!š`Z‚b®¶ëÑ^ÞLÂyæc ,pk@ÈÈP¹ ¥eJ)± ’º"’Ë�›h¤®O°R°Û„|ÓÃS8\`F‚Š-p_B 3J™ fEЕòŒ0#¢†]F´ÖÃ8ߌöñ( X`ODJp Â'9Å— L0Š@ÍÑ¡ƒs è7ª0rÐÇã\`ÛC+‚2fä”RlA�u„$§6ÓÈáÞï„‘8œo†’Ùà„b”2+ÂIÀ•ÜF˜&‘†~Á®–p¯S…õ  Xàž˜Ë€ ;œä/.ç›` …š¢C; èþÞDÂù&ä —ÇQ¸Àw„Ä´�Êmp”‘û“r‘Ô’œzتCõ  V«žÄà| Ü*³Áþ”L+¥VDAwDr`=‰Ô÷[õß ;Ò'@0Th}1)š68-�oLÎ7Â7ùÅœk@k³Â¾­úΈ”R…±r_R.2õÅ\=lÓ¡}|V˜æ“šOþ«}2û”#+à• ïîi;©£lîåãn¨}üi² þ©�� >õ)çˆÞ'Þúúød÷í}æÚ…3϶›uYcôøc ]æ¸÷Ú³ùŸ/I ½ïw“‡ÙOêæ“g•ÚÖ€>Õ.¤#]½akñÈ£ïnhÖ¹†mcý­m0›â«ØÇÅýýñˆ’£@¦—w46Ô·úyÃ@[È¥×z´×Þ°¯·³öåáÜ8õ7¶vµtÐAË·¦X:¿Í3ÐÃ÷8!K„û¬BÉ�¥¥Mµv>’¨mØA±L1¢ï‹{víÙïK!Æ<ÖçoîÅ{b QP¤' h +¢—[doÄ3Ðð%À@Á´Rn ò%·"1¨9(›HÈJÖCpIöÄ”$t(})fÀ+HòPR)0 ›ƒ²‚L$h È$»JgTI Ð(‡âM‚( ªì ’ý)¥Ø�·†‡Òã ) ëp(W:Š À¹GfW,L+eÀË7®¸ô…AMÙHB6h )�‚ LrO\IpЈ¥? …eˆ¤x¨/©ä+ÌJAf 4eƒÝF¹;ª¤h”Cñ%A„•6ÍÀþ”Rd ·„ HÐiUXDá%hXŽâM€XfW‚,L+¥f È7ª¸ôAÍAÙ@@öo…™äž8P… ¤¡£TX#B½ %ß�(Ô”-d¡@sHÁ8Ï(wÇ”‚°XH)…&€ÀpKPÉ¡! š‚2…ÃN½ÒU24<Gñ&AŒ…†Ù• ÒJ‰H ÔVœ:ˆÆ¡¦ œ­zY‹ÌrO$2ÐðÅÏ@¡´Rn¬õ&”<D`PSP6“•-!Eà|ãwUß› µ8$•B#@¸9(ÛiȤ Ã`—^éŒ*¬ÈQ|ßV}8RJ‰È�n +¹:H‡ƒæã„i>©ùä¿Ú'ÖÛÈ‹¢|j¼�¼ñIã—Œ91¨œsŽ à{,!èÝ=m‚$�._2¡Ò½ü­}¢$zÈ3뢑9ý÷ŒådSY’³ê®‹vÛ §vóI "‰ 5¤HœS‘l ghRÐÉ¢.+àpúHX‘ôgÁÕÇ:x‡"š¡˜ÄiFÆkûxÙ1¥5EÉö)0B×'%Åi>ܯˆös`…ꋉŠl„2TXZ˜—û«’Q?üòO IÒ¨Gv(’ ×I à‰Ê]œU–ô�‚! á2_ (�‰Cý°”)ÀŒÀÉ$µGAc\S„Ȉ`˜÷&°…´�õ¥;%’ˆÒE DvëÅæ.Ê`œƒk œFÙ¹Î(‘ rã4â¤E1D‡I9´ÜÅDŒ°sõ!‚—ÀX×! µ4dà|ƒ Ê/‰˜ÉŒËíQ ‚@©‰kŒ‚t‚0_‹fà"£ÀP_ ±‘"*Q‡•|½ØÁ…ã„´sÝq"ÁCe&>Î!ýiÄI‹(:cÉZl⢠ÆÙ¹†ÁK`Œƒk‰Œ†X„ƒ8Ï È ä"F\2“r{�”™¹£ác'¢ «²ò}),ÂÂ…F!#B½)ÄJJ4*wD1 V bSøa#ì|wKðp©‰OpHÉ¥E V:£(‰ÈNZlQ…år!‚“À˜®5J¤PaÂ,âOÃn½�ÐE ¸d%å¶(¦(`¸k<N+‚*+ߟÂÂ,\hx ò% )éq¹3Š!Rô­°ì‰ ·ñ= ,ÎÁ%F>ÅÃýi$‡ño«Þ¥[N¬úÑ9\{”H  Ü,DXÄŸ†]z�ÐEô¸d'åÖ(&Ë`„kŸPõ•ÞŸÆB \` ò&3!q¹#ŠÁ(6òGO¦ù¤æ“ÿ"ŸÃv¤Í øßOþëÆÚ“Bβ?üúøF>;×àîgÝöÌŽc;�Pg\7m”‘&N:÷ÿnò­+>[áœ?c‚YOšôÄÃë>Ÿ}ñ¨Š|Û DguÖîÝ»S©Ô`¦l_õ_›@îÈŸáeéŽ/ùX/J[¨ü±¨!çŸLBä Û§2¡ ãÑ|]F°7…ç¼”šc”ËŒÜá°ŽF¤!æLCD‡@r‰1ÓÏ))Ôg2ÒÏ`.ŠÓáJ{œ4bb‰‘« ët¨4ÔÌ éID.3fº“$'AE†LR@ƒ,–Gsº’„òôBC„Ö£R…9s(¤£¹ÜĶÅiIņL„âšOg�÷¤ð’·“RÓ‰Â*Ì™Æ( ¥ô[aº ¯À}iÜIñ\n;EØ¡Gä2c¦'EfD¨HŸI‰h€ÅÜ4G  3A˜q¡@/Ô'ŒDärÛ§D*Ög¢<É yº Aža'„ZlŠRT,3q‡Ã: ‘†˜3G£4@‰õgˆ$è2‚÷¦ñ\Š7árë‰Â†˜3uaɥƌ/M°"\¨Ï0:À`nš£P¥#Aš1±ÐÀ‰ÐzTbÎT…3IR¡"}&Æcá š¯ã`x’VU‚R�� �IDAT„riñh”2 b¹™SK¸ÂÄ6Çh�@‰!È`q-Ðe$ö¥qÉ[H©%F1±T-aTbÊÔGt($—3½i"-Â…zN­z7ÍѨҞ M˜Xdä„铪¾+IòTlÈÄ,Ä¢y:…Aw’°â‚K'4FO¨zÍ'5Ÿü|²3“‰Žþç7òÙ^xá¶Ûn‹Çド¯¾úê¬Y³ÔÕ?j¢è¤I“`ðýNß¿­ÎXûþȲóŒãOWýdpþ“Iáˆâ¢ÙŽ$ÅÉHÍ„9,È.Š•¨;E٠΀I1½w8b ÙEgšã´ 7ͰD„Çó(†•`C:È È-qr)îPØH£²‹Ê4Dõ( ÜëMI˧™¤€ö³d.•a¥=I[qÞF uƒ“œTæHD#Š‹b;“+#yá°@†p‘¬ ®cÂĆo…ÕE $¢¸èLkœ–8fý,áq7Åp2ìMS’#©ù;a •T¦!ª‡aG±¾4°|šIŠhKæ’VÚ´çsHþpÄ C%'•©è1¸)¶;I12šG1Qõg'Å*�êLÑ6‚7áBCToÀD'ÍÕEõ¢¸éLkœ8f<ÌÖ“¦rŽF¥¦¸Î„ ¹w8rLØÑ˜‚ 7Íö1DLÀóh&-"½ ™Kf0XiMè,¸Cq‡²Â¢:U˜'E¦E4bâ<êÏ.Š�t&iÁ›q¡>ª7`b.ÍÕETal{’æ8f‚,ÄnŠdÈ“¦rN‡IGcz&ªÂHTvQ™æ8­@›fûY"*ày4ËŠ°!sÉ +-‰ïJ˜F%•©ÿ¶ê{ÒdJDói&. ,á¤X(IÚJðVR8=±ê5ŸÔ|ògñɤˆ?zòùï„ö£œdü£?2ýnÆÚ §ÐÈ�þeý‰ ÒÏêbQJEC<9¡ É8/#Ýi½gXjK (oÁ2)<2écuI/¥£AŽ rd KI˜—Ñ9‰ )m)£ ãŒ(ß–2â°ì$RFŸ–°*6ÀÑaž,¥£Qìeé<2 �èH¬XF‡ mI#…ˆvŒéfô¼‚’ñþ ˆ2*Ta ^AºÓúœcÂŒzTP…)�ä‘ «Kˆx rT€£Š©#a=ŒÎI¤QHnOM(gD¹ö”ƒ‘ò2ú´„•R1?G‡y²ŒŽÆD¢—¥ÝD‚@GÊ`Á2zThM)DràL7£ç¤˜Šõstô[aýº€Lˆ Ü•ÖÛq–‚Ŷ”Q‡ 6ŒíLdÎ'½¬.!â¥t,Ä«Â⪰\"Ãr[ÒhDyʵ§Œ¤¸ˆ”—Õ¥D¬”Š8*Ä“¥t4.>Vç&R0¤´Æ·¥Œ$"9ˆ´‡Ñ³VLÅ8:"j ÷eè|2!)pgZoÃY ÛRF"Ú0¶+m¸€Lô²º¸€—ѱOù9ªˆŠgdÔÃè8ƒÃr{Ê`@y3–éH`ä©cUO«úR*–q/«s)RÚR3ÆP¾5e$`)—H{=ómÕGx¢ŒŽE²¥óɤ¬Àiƒ ciDlKécUo¤Lh>©ùäÏä“TôGãÍ?ú]Î í¡A�€ .\(Ë2�@E ÃNê•ÊŠ��ô†’ BþBߨJ!+a��9Q‡%I$F!‚AF HÁ!‰“Ñí…ŒŒ�á°()°¤À($A� C vŠ}vƒ€EAAdÂ`IQ QHF ™—Q(,fd쇅!Œ@ /#¤”9E'£Ê ÂŽÈ`…A’€¨ Ya�(ä)ÂXäD9ùD#ìä>]a0$£Ç„ ¾„^F  ð©ÂDNF~‚0E–ÿÙªÏ ûñª×|RóÉ3ã“° Hr®E§(Ê©Mú©{b±˜ÙlV#Â÷Úÿ1ÆlÊßk,ŽãŠ¢H’ôôÓO£‡ãöÛog†á;w^|ñÅÚë¾54444Î}ôÑå—_žJ¥vìØ!Š"šýB§Ó]uÕUZihhhhœ)®ºêªÆÆÆ¼¼¼~—ŽýHSÎd2Zihhhhœ<ØÕÕõý!GQžçµ2ÒÐÐÐÐ8#x<žã{`­D44444~´£¡¡¡¡¡… -ähhhhhhh!GCCCCãßt0F>Ÿïí·ß>iç¬Y³Ö¯_?iÒ¤sÎ9ç§åýùçŸ8p ûñ·¿ý­ÛíV·ß|óMI’ÆŒóÑGÍš5 �°~ýú‹/¾xĈƒI¹§§gÓ¦M—^zé!C��µµµ_~ù%� ¤¤äÊ+¯<ã…¸sçÎ#GŽd?Ξ=;''çg«Âd2é÷û³ív»ÙlîèèÐëõ¹¹¹?!ÁS«;[’ÿR>úè#u{Ô¨Q]tѲmÛ¶®®®;î¸ãŸÉ÷‹/¾Ø¿?� ²²rúôé'}»råÊ¡C‡VWWÿó'¸ÿþ/¾ø"ûñòË////ÿÑ£Ö¬YSPPp饗ž‘BÞ±cGKK˼yó:´k×®o¼‘a˜·ß~{úôé•••ê…� (jîܹ�€÷ß¿­íØëîó›ß”••VvÏ=÷\EEÅ%—\2ã×_Aßýîwƒ,É›o¾Ùd2iø§««ëÝwßU«»££ã½÷Þ»òÊ+KJJŽ·immýàƒ®¾úêÂÂÂ3ÿ”ãñxjjjÂápÅqˆ¢XSSóé§Ÿþäûøãkjj ÕIò»Wé¬[·îÅ_4Aô÷÷×ÔÔ<xp)www×ÔÔ=zTýøå—_ÖÔÔX­ÖlH;³lÛ¶­¦¦&[2Aüœþ‘L&›››EÑëõÇ9r$•JétºãËó´ (*{.‚ _’ÿ:<ÏwÞéõz+**P½çž{>ÿüó=jóæÍùË_þ™|kkk,X ‚Ñh¼÷Þ{·oß~’Á²e˶lÙrFÎqïÞ½555f³¹¢¢¢¹¹yîܹápøG*--u¹\gªœ·lÙ²lÙ2�À×_]SS …Ô«»±±‘eÙÛo¿ýàÁƒÏ?ÿü“O>¹eË–ûî»ÏjµVTT466þñŒÅbƒÏkÙ²eK—.]´hQöNâ‡yñÅ×­[7K‹ÅRQQqêÛ¹4Îííí555­­­jh©©©ioo?ÉæèÑ£555ÝÝÝÿ’§•qãÆ]vÙej<xæ™gÖ¯_Ÿmò®ºê*QY–}à.½ôÒì¢ ƒaúôé4M«Ûß|óÍܹsçÏŸ/Š¢úñ‘GyóÍ7o¿ýv�ÀSO=5eÊ”ÁÜNš4éOúÓ=÷Ü3aÂdzråÊ+Vüío«¬¬9rä‚ šššDQœ1cÆwÞyñÅ;vÅŠ·ß~»ÇãÙ¾}ûŠ+^y啽{÷êõúÁŸˆZ8�€™3gÂ0<mÚ´•+W®]»öÎ;ï4™L©TêÅ_”$iûöí<ÏñÅEEEçž{î믿.IÒ|€aØÂ… %IºâŠ+æÍ›‡ãøàs·Z­6›MÅ®®.žç›ššrss|>߸qãŽ9R\\\XXxêë•NÅf³©çâóù/^|çwNž<ù’K.á8ŽeÙûî»ï²Ë.Û±cÇ£>JÓ4 Ãï¾ûîßþö·âââ—^z) ^sÍ5]]]‡5jÔ_þòŠ¢£Ÿa˜ŽŽŽ3fLž<¹¤¤ä¹çžóûýápxÚ´ijé­Y³fôèÑëÖ­{íµ×‚ÈÏÏ_»v­z¬ /¼ð›o¾‰aXiiéªU«²õÃôööþþ÷¿¿þúëï¾ûnAª««1 ›={¶Ïçã8î†n˜3gŽj™N§çÌ™8Ž»å–[fÏž­^’$íØ±ãСCƒ¯© /¼°¨¨¨­­mãÆ Ã|õÕWÇ—$Š¢óçÏD"×]wÝ’%KÖ®]ûØcMš4©²²òü£Çãáy~öìÙøÃ¦N:uêT—ËõÆo|øá‡‡c0¹ëõzAN½É bÆŒ²,?ÿüó&“鬳ÎBQtÓ¦MápxüøñEEEg÷î݃ÿÝ^:þüóÏ÷îÝûÉ'ŸÔ××_pÁ“'O¾à‚ ìvû† >þøcNWSS³{÷n�À¹çžûðë¾õÖ[Ë–-{çw***Ö¯_¿|ùò¿ÿýï]]]÷ß¿N§ãy~Û¶m»wï~æ™gÆŒ³{÷î%K–Ð4­(Ê–-[ŒF£0þE477_wÝuƒ!‘HlÞ¼9»Ê”)'N,,,|ýõ×·nÝú£·G§êëëwîÜyðàÁd2éõz%IR÷«W®]»®ºêªn¸!œÖ™|úé§;wîܹsg,»ôÒK'NœÈq\WW� •Jy½^AÔÆåž{îL¼�a2™Âá°(Š™L&Ûíö@  W­ZµaÆ 6<ôÐC555Ÿþy~~þÑ£G»ºº‚Á`¿ßﯫ«ËÉÉ9­À©v¯íܹ³··×ï÷ôÑGj‡ÌŠ+þó?ÿs×®]ãÇ¿ôÒK9Ž{úé§ÇŒ³eË–-[¶x½Þ]»v%‰›nºiÍš5o¾ùæúõë—,YòøãòÉ'§•{, ÉdR¯×cƲ¬ ‚ °,ÛÛÛ[RRR__ŸH$N«›kúôé×^{mMMÍâÅ‹[[[wíÚuÍ5×Ì™3§¡¡áºë®»âŠ+víÚÕ××wûí·'‰ë®»î¥—^ºÿþûyä‘Ë/¿üþç^ýõ_|qÙUUU½úê«»wï?~üÀÀÀûï¿Í5×\yå•6›m×®]7ÝtÓÓO?ÝÑѱsçÎ'žxbëÖ­|ðÁŸÿügõØ}ûö=üðË-z÷Ýwß}÷Ý¿þõ¯ƒÌTÅp8l2™‚@Q´  `ÕªU|ðÁÖ­[çÏŸ¿xñâìƒõ#<òÑGíܹóöÛo_°`ACCƒ×ë]½zõîÝ»‡zZ5µgÏž;w¶··5*•JT’Ï>ûì¦M›{ì±gžyÆëõf2™ÞÞÞp8¬>slÙ²eáÂ…<ð@mm­ÏçÛ¾}û°aÃÇ໋—/_^QQñÍ7ߨ%I:pàÀœ9s.½ôÒ@  ^8��—Ë•““3wîÜE‹=ôÐCW^yeeeåÞ½{Ø��þóŸkkkóóó­Vëc=vðàAŸÏ·mÛ¶Ñ£GÛl¶+¯¼rÏž=­­­¯¾úêsÏ=·zõêl_®Ùl–$iÏž=±XìÀF£QÅ«¯¾º²²òÍ7ß?~ü³Ï>«6Aápøw¿û݈#6lØPUUõüóÏká RWW·sçκººl?pUUÕ®]»Š‹‹ó›ßß¶cÇŽŠŠ ·Û}ÅWœ™Ž5•ŽŽŽÚÚÚ¦¦¦ï½E}òÉ'÷ìÙóNì›o¾©­­­­­M¥Rêž›o¾¹¢¢âŸ,¯‰'fÛ‚³Ï>û¤׬Yóî»ïªÛO<ñDmmmöã¾}ûÞ{ï=õÖét»hjkkƒÁ zÅ>ùä“7n|ë­·ŒFã“O>ÙØØ8˜D^xá…wÞyç§u¯E£Ñt:MÓ4Šžðð:|øðŸà3Ï<Çÿë¿þëgsñ /¼pãÆK–,™9sæwÜqüðØÿøÇ7Þx£²²rñâÅ_ýõ3Ï<sêáï¿ÿþªU«~ÎkrôèÑ«W¯~ë­·Në¨Ã‡oذáÍ7ß\´h‘ÝnW;Üž|òɬÿ�ìvû¢E‹~4©sÏ=÷ÔÁ§E„‡zHÝæ8nÉ’%?`|Ï=÷¼ñÆ%%%3gÎ|ðÁ9H/Ú¶m[öãù矟×¹ð o½õÖÍ›7ÿío;þK.¹äüóÏ_¼xqKKË+¯¼r×]w•””,Z´(™LÞÿýåååYŸ$IrÑ¢EÁ`ð9räý÷߯ʼn3Hkkkmm­Ú½¦ÒÖÖöä“OžÚ™vÎ9çdûxÎdÇÚW\1cÆ �À³Ï>{ÒW‚ >|øðá·Ýv›Ùl>­»÷Þ{O·q “'O®ªªºû™:uêI·¢C† ™4iÒW\1fÌŽãÎHŽ<ð@v;//Op¾ÿþû?ÿüó%K–¨?Ê!C&Ož|ùå—7î´r/((°Ùl>ŸïðáÃ,Ëþ“ç²mÛ¶}ûöÕÔÔülþíñxxà9sæÌ™3‡a˜‡~øðáç^óæÍ;ï¼ó&L˜pj ùùùãÇ_¿~ýéqÿdÆ7f̘Ó=êŽ;îÐét0 ¯X±B½1ÏÉÉ>|ø /¼àp8>þøãµìššš?üáÁ`pýúõ«W¯®ªªRgèœÊ{ï½÷öÛo¯\¹òÏþ3A7n|ôÑGÓÛ¼oß¾mÛ¶=ôÐCUUUcÆŒáy~éÒ¥‚ o³k×®{î¹ç–[n9i\�pÛm·íÙ³géÒ¥—\rÉÔ©S1 {àÔy"555êP¥ÚøÀtttÌ;÷ý÷ßO§Óƒ‰ÓƒdæÌ™ÿñÿ±}ûöìí¸Ñh>|xMM MÓ§5ª÷Ÿrþf³™ ˆñãÇ766>öØcétú´~¿ßï÷ ‚`µZ3™ÌO<qÒ³Š¢ƒ!™Lþá|ÊO?ýt{{;†awß}wv§N§#bÔ¨QÇ=òÈ#.—ëÙgŸ}æ™gn¼ñÆuëÖ-X°`Á‚“&M:#ÕÖÔÔ¤×ëÇ_RR‚ H4ýG–ª°‘#GŠ¢øÈ#tttœî­+Çq¢(¢(zº]‚'±ÿþ¹sçΙ3碋.R«† †ý~*•2™L(ŠšÍæt:­Î”;#³††ùòË/ý~UUEQEY­VAü~ÿÂ… /¼ðBµ£µ¤¤dܸq‹…aõ-´8ŽëõúÒÒÒ!C†<øàƒêìÄÁŸŸ¿zõêµk×~øá‡?~üöíÛq‰DÂ`0d¨F#†a~¿?™L †“ž#O»Ý>tèЃrg6›Ýn÷øñãÿò—¿¼û477Ÿô|©×ëqƒñx\ÝþɹŸsÎ9Ñh”a˜éÓ§×ÕÕY­Öªª*�ÀÆZjjjü~ÿ´iÓî½÷ÞO>ùÄëõʲìv»Ífó ]«¯¯¯««ëì³Ïž>}úôéÓ‹‹‹÷íÛwü,�€P( «ªªF¥^Ýê.�`Ô¨Qûöí+..ÎËËËd2S§N}íµ×V¬Xár¹²÷݉DâœsÎÙ°aÃÊ•+­VkvfÆ¿«Õj6›Ç¿aÆ^xáø¯>ýôÓuëÖñ<oµZÏÌSŽÕj­®®ÎŽ •””TWWÆêêêŠŠŠ‡~øŽ;î˜?>�à¹çž³Ùlƒ<uîéâÅ‹ÕK—.ݱcÇ¢E‹ÆŽ{ÓM7 ‚ŸŸ¯fTZZºnݺ—_~ù‰'ž|Y,– .¸Àét µ¢°°ðŽ;î`æñÇ�Üwß}jh©¬¬œ2eJQQ‘Óéœ8qâèÑ£OkÖÙ°aÃŽŸD;eÊ”lSµyóæÙ³gÏŸ?ÿŽ;îÀ0ìõ×_WKEÑêêjuæñ¹çžët:o»í¶t:­žà¢E‹¦L™2ÈÜ ‚ÈÍÍõz½^¯�0vìX³Ùìp8ŒF# Ãê<iŠ¢rssÙPêõúÉ“'ïß¿_: �¸ûî»qW«øí·ß1bÄæÍ›—/_>þüóÏ?Íš57n¬®®ÆqÜápTWWÛívŠ¢ª««O½ýGTUU½òÊ+/¾øâÞ½{�>úèÌ™3g̘ñûßÿ^Í÷ÕW_-((xá…^{íµ/¿ürëÖ­K—.UûgÎ>ûìçŸþ7ÞØ¾}ûÌ™3o¾ùæAfªNÉUåÕW_�Üpà óæÍ[ºt©ê“/¼ð¸qã¦M›6bĈ¹sçò<¿`Á�ÀºuëFŒQ]]=lذӺhÕ GOQZZZ]]ŸŸŸ-ɪª*Õ-Y–}ë­·}ôÑÙ³g�~ýë_1âî»ïÎd2>ø �`íÚµ&L¸è¢‹FŽ �˜4iÃ0§q› ÃÕÕÕ•••�€©S§f‡ÜKJJÔa¤ùóç©S³> �Ø´iÓ Çr\.Wuuu¶ª¬¬T/õGgŸ}¶ 3gÎŒÇã/½ôRöêV'¯f󪬬TE’$ùÒK/-]ºtÉ’%guÖºuë¶lÙR]]››»fÍšeË–9räÜsÏ=©Ôøgn‰ª««ÕºÎ^Ñ[·nͶó/¿ürCCC¶Šýë_cfµZ_{íµM:묳öìÙÃ0ŒÚ.'“I­Ä54þ·øâ‹/öîÝ{×]w}úé§³gÏ~çw~ýë_ÿ,‡_|qóæÍ~ø¡æÿæM›6íå—_þG[·n•$éòË/ß±cÇÝwßjE¦¡ñïƒËåÚ±cÇ×_‹Å®½öÚQ£Fý,„5kÖ<ùä“o¾ù¦æÿÿ¡… #ÊËË7oÞ¬NiÑëõê8ùÿ5fÍš5cÆŒÁOÈÖø_dÿþý§5 ¡… /NwÎçÿFíG¿N÷Î@{­§††††ÆÏ„r44444´£¡¡¡¡¡… ŸÀ ÓÒéôàÐÐÐÐÐÐøaÒéôñ ©|rEÙ¶mÛÀÀ€VFgŠï9ï¼óN*•:­b444444~˜ãÃÊw!‡çù«¯¾Z+ 3ˆúÚÖ“CŽFŸÏ§¾#YCãǸqã³ö«†Æÿ ZÈùü~¿ú2f­(4~qhñFC 9¿<‡ÉdRE+ _ ß|óº:€††r~y(Š¢…_‚ œä±Çõõõi%óÓÈ®öÔ××w¦Öþ¿†Íf;éuyÿ0äôôô¼ôÒK'í¼ýöÛ×®]û«_ýêâ‹/ÖJó±zõjEo½õV�€(ŠêJb�€yóæåääìÙ³G]¤´´ô¦›nʵ{÷î?þøž{îñûýÙÕà+++gÍšõ·¿ýM] qÚ´içž{nöW^y%g×< ƒ+W®œ>}zcc£ÇãÉš-]ºôСCÿûßÕ&L¸üòËW¯^Ýßß�¸êª«ÆŽ›­nÇ~øa�ÀÆ9�P«›eÙeË–©)ÜsÏ=&“é³Ï>ûä“O²"�ñxü©§ž:I¤J}}ýÛo¿­n3fÆŒ/¿ür&“¹óÎ;5‡ùבJ¥Z[[ËË˵¢øi7j/åNw9>lö)§¿¿ÕªU ,¸à‚ ¾³FÑU«V!¢…œïeûöí«W¯>tèPUU•ræÍ›WWW·|ùò§Ÿ~úÆo\¾|ù]wÝuõÕWŸuÖY·ÝvA7Þx#�àСCóæÍóx<·Ýv›ÇãYµjÕÃ?<qâD«Õº~ýú%K–¬\¹²©©iÞ¼y¯¼òÊØ±c�¯¾úê£>j³Ù²!çÆoÜ»wo^^Þ”)SÔå×®]»uëÖGy¤±±qÕªU+V¬(//w:Ï=÷ÜSO=µ~ýú­[·ÞvÛmo¼ñÆÍ7ß\\\|Ë-·Üyç ÃLš4éÁ|ì±Ç‚ÁàÂ… ׬YóòË/÷ôô<úè£Ë–-»å–[î½÷Þùóçßpà åååúÓŸiiiÙ³gÏþýû-ËI!§¯¯ï–[n™:uêW\¾}õì¦M›’ɤrþÕØíö½{÷~øá‡$I*Š"‚(Š‚(Š‚¢èñ‹C˲ Ã0Aj;«~¥6êúÓ0 K’�@D5E1Û¦@ðº?{`v`I–e‚Ô4eYV—ÍUwŠ¢H„Ú© I’šŽ ªH5/‚$I2‚ ð</I‚ ª$õÛ‰'<xPEQaVOMU‹a˜ºSµ 5ýl\ H]Û›eÙóÏ?ÿ¼óÎ+//?~TÌh4Ο??»÷I‹j«erÒ(š,ËßkvÒI’²…œMÿÔ–z09OvUoY–OMÿTNMêTa0 gõgÓϦ™µÇ0 EÑ+Vøý~‡ÃqÒât¬ 2dêÔ©�€_|±¦¦æƒ>P÷ \qÅEE£Ñyóæ]ýõÿäjðÿžÝÿýßÿ½víZ³Ù,Šâ¦M›`¾þúëY–M¥R×^{í]wÝõÙgŸ-\¸Ðápx½Þ]»v]tÑE¿úÕ¯.¹ä’l"O=õAÇ‘$ÙßßÇ»ºº†:mÚ´úúzÕËc±ØòåËûÛß._¾<_ýõ×_ýôéÓ ‚()))//ÿÍo~CD*•Rëïƒ>ˆÅbÇÏþtwæÌ™=ôÐôéÓ�êº^o¿ýöG}´eË–æææ{ï½÷OúÓäÉ“iš.((¸õÖ[çÌ™ƒ ÈîÝ»‰ÏóGŽ™2eÊÔ©S ‚¨¯¯1bD&“±Ûí¢(¦ÓiŽã>\VV6uêÔÍ›7K’´wïÞžžžªªª±cÇF"‘žžžû§§G]Øû$n¸á†–––T*5{öìk®¹æ’K.©¨¨hhh$iùòåsæÌ™5k– ‰DbÖ¬YwÜqGvù®®®‹/¾xöìÙ===»vízï½÷îºë.�€Çã?~üƵˆ2:::¾þúkµ-È^ÿÙ[xµ]† HQQqWÛJ‚ ÔÖ*k¦Ú¨­¹(Šê%¯î”$I]Ýív:tHméÔ†>Ûè#"Q=�� �IDAT‚š»ºGQ5n!¢&«ÊSÛ8EÕvMMGmaQ•$I j SwîÝ»WMEQAÔ|ÕFP£jôRÏ%Û¼¢(šÉd²gð¢(N§säÈ‘<ÏÿÆd2¹{÷nõ”E95�œÚ�~¯Ù©~¶¥FäBŽZM'…œSXžçO:ðøôƒZÎÇg¤VŠ*/[•ÙÏöëaÃ0‘HäÔdDAmmíÆ?ûì3AR©T¶ î¿ÿþ@ °k׮믿~áÂ…ÿ_¾³ §§gñâÅ&Lxûí·ÇŒ³uëÖO?ý´  `çÎ ,X¶lYCCÃu×]wÑEíÚµ«  àúë¯Ç0L¯×_¯4M§ÓéÅ‹‡ÃáÍ›7«;¿úê«M›68p@ 9ŸþùÙgŸ­nã8~Ùe—±,ûôÓOOŸ>}Ïž=8Žëõúõë×?ûì³+W®üì]i|Ìg×¾g_²oI$#"²/D ¥´T‰%¨§­„¶ˆ( Ú¼Õ–Z*TQKìZ­"¡Š©]HlBö}ÏìÛûá4ç¹;3™†¢‘gοÉÌ7s®ûœs넇‡‹ÅâGùøøàîÆt¿U}}ýùóçýýý]]]---_{íµ¢¢¢U«V >üêÕ«<O(¦¤¤üðÃÛ¶móòòŠŠŠÊÍÍ=pà�Ðç{öìéãã³eË–ýû÷‡……uëÖ Ö8|ø0ƒÁprròóóËÌÌ<|ø0œ‘Ïç …BƒOrãÆ„÷Þ{/((PsÆŒþþþóæÍûâ‹/._¾<þü”””»wïÒߥ7ß|S$EFF^½zU,ûûûŸ>}zùòåfff±ÍdF’jµº©©‰•J.œ“Éär¹€°xC;8¼@€Á0bµZ-à;�±.L&³k×®ææær¹~€dðí…}!Öa2™<½"—ËÅÈI©TÂUÁÙ– à1xjÀ�///‹ŸÂeÀ-cР­4•ž<Ó ¿Ù3ýßdzsZ6ÀiÓF3ƒèˆ€dàzŒ_ncccee%DÁ:&•J“““¯^½ÚŽ3Ÿ~úiFFÆÜ¹sƒ‚‚&Ož ÉÇ|÷îÝÖçÎ[^^¾nݺŽ;æååÁS-**Z²dÉŠ+jkkgÍšµzõjBˆ……Å7ß|ûúøø¬_¿¾oß¾;vìøâ‹/V¯^ ñÓºuëºwï>xð௿þš’}üøñÄÄDp(`ÅÅÅÛ·o_±b”@ñ˜666{öìéѣǺuëöìÙ³~ýú>}ú@ýéàÁƒ•••ð›<qâÄ¥K—®\¹R\\<bÄˆØØXXÅTVVîÝ»7++ë³Ï>[³fÍ¥K— .dË^{íµÎ;Ïœ9sôèÑñññîîî:DEEõéÓ'-- þܶmÛøñã?øà–´ÒÀ“‚sÿepÇtF‹ÇãÉår\·Ò‘& �¢4 `FL&óþýû< ÷…X‡Åbgg³Ùp.¸ÀpO��ð&\ \²£3iˆ€:jµÜ¤àp{ÌË >ü›o¾‘Ëå4FªÕj6›÷…©EÓwæB ñ8nÜ8BÈúõëu>âp8Æ 6l!ÄÁÁ¡ý=++«iÓ¦½úê«“&M:~ü¸J¥²°°øôÓOwïÞÍãñN:ÕšƒÌ˜1ã?þسgH$Â7 4hР%K–\¸p!??¿  àÇ,..†z —Ë0aÂo¼ïÞ½{ñâÅ[¶l‰ŽŽ†wvîÜyæÌ™5kÖܾ}[.—ÇÇÇ+Š_ýU*•B6mÚ¤SJÉËË›1cÆŒ3 íFIIIYµjÕÑ£Gà''§iÓ¦BvìØÑÒ½têÔiÚ´içÏŸÿþûï?ûì³ÐÐÐÐÐв²²eË–ý“çiee5cÆŒcÇŽ}ûí·]»vmiãC‡:u ¼&kåºV²àpÁ_ãò6›¥HUÉd2@pîa> œ;:}€� ­V{ëÖ-(–`AWŒp3B¸­V+ !�<€ƒc ·!b¡B¡€×l6{À€.\‹ÅZ­6-- Â,8Äc€CJ¥’Ëåš ç™Ú/pvvæñx666ééé3gά¯¯o¦¨¨(44tçÎ_}õ—ˋʼnD¥RÙØØ8;;ÛØØäçç»»»×ÕÕݽ{W&“Ñ ‚–““¿Þ»wïÞ»wO(vèС¤¤$77W(:88lÚ´éÈ‘#iii&L „,[¶¬°°0++ )—ÂÂÂÚÚZ@p÷îÝ»wï‚ÚwZZZZZZ@@@ÇŽûí·óçϧ¥¥­]»–2yòdooï¡C‡Ž7¸ *•êáÇÙÙÙwïÞåóùŽŽŽyyy‰„ÃáÀ1›ššÂÃÃîÞ½«R©ÜÜÜlll,-->|XPP`kkkii)‰Äb1lìîî~ñâÅÀÀÀmÛ¶Ý¿ßÜÜÜÞÞ^ÿÞ>ììì|îÜ9ƒ×ÝÝ]¡Plß¾=**ÊÃÃ#((èƒ>H$jµúÆÎÎÎ{÷î‰DR©tÓ¦MÀñ»|ùò”)S¦L™¢V« L¿ÞÖ§V0Oà<8F9=(•Jˆu l!�,{`M^¡P�ü€ÓÇ|Th „£T*áSØ “c2™ ÿÄ´ ð Ïȇemˆ¢ `Â7Ï;'•JáÊÊÊ€w�€$•Je2¤ñ¦03)r¹\LCµ2Ÿ©ù«Ñ9(àA@ÅàN#ÿ›\. QýWTÃ7ñ¤¸# ºÎŽÆ‹:p©Õ„çcÙlˆÐ‡¾°ÇŽrìíícccÑvëÖ-66ÖÆÆ&666((häÈ‘L&3%%…²yóævÙ¨ïêêºaÆmÛ¶mذáí·ßþøãáéýõ×½{÷þì³Ï~ùå—ƒ.[¶,%%%88xÆ °ãË/¿Œ©È!C†”””ÀƒâñxkÖ¬Y¿~}ZZÚíÛ·“’’¦OŸŽ§ ŠõððØ·oßúõëSRRFŒ±lٲÇÇÆÆîܹ6KHH@¾æÀàO‡ØØX???&“ùÚk¯õìÙ~^^^[¶lÙ½{wJJJbbâ¼yóvïÞ­P(àª! ,سgÏÊ•+SRR"##׬Y‰SÈe­\¹2::ºW¯^|ðAJJŠ““Ó§Ÿ~jkk ×vùòå>ú²ŽB¡066/ÏÅÅeĈ±±±P3fLpp0Dc L&óôéÓ_|ñ„Ñß|ó··w~~þˆ#ÜÝÝ·oß>}út++«!C†¤¥¥ÙÚÚÆÄÄäåå­]»¶k×®³gÏ6ÁIkLÞ|«¬9'† x=…FÃf±4s0™J­–Iˆ–É䘛755!H°˜LÒ\·W6ûw¥FÃ`2U„¨š p²,–F«•¨Õl6[¥T* p² BÔ*i.±¨Ì ‹¥Òj•*•–Ãã`t"ÑhXl¶–ÁP5'ÖÀÁa”Æd2áBIs΢a04�’ºùÆY,––ÁPR…¥?CÀîÝÛxšôUûžÏe0BCC333%ÉáLJnú}B®^½êååeiiijýw-%%…ÍfOŸ>}úôéiii¦ÉÆíÂ… ÁÁÁ4ϪººúÑ£GiµµÛ¯\ÁdƒVËÂ’Ió ô# B´Z-³9‹…ÅØW­Ñ0¡Ê‘‹õ§soöòl ¶a4çÇ0F †`0 “ÁÐhµ~JüÒ„À^\G«Õþ­®AÓœ¸ûó"›oS£Ñ0 &‹E´Z“©T(´„pØlV ÷¢…#3 &S£Vk´Z&“©Q«Ù޽]iY¦™LæÿX;;úI>|ØßßàÀ€LصÆ)ë3Ä[Œ…w$GÐ;¤,c0¡““¤wÄÅ.Vv±Ççóa ªR©tÊûP¶æŽÜ\!ýÑÏŸ?ŸŸŸ)—ËAÖóøñã³fÍ2©˜¬íÚ€† öÓO?ååå­[·Îô@žÌ8gÏ vï†d 8/2 †i7,×ÓD2HŽ)•J!H÷B6À ‡Ã>¬a^…Á`°›“lø&K£AŠî‘׉ŽÉÖLµh,K.—× ëR°=\L&ƒCÁ°ÙìW_}577777W¥R±›ùÓ.W©TJs• xnlƒÍfÛýç?dРþر1ˆvÙ45C'\À”Ãô±JgƒÈ„†Éúz©¡%9b-A@æ¦yM?È–¬®®î‰“&{*ææævåÊüAÖÖÖšž‰kI”…Á`Èd2$@#� ³ »d°{6F¶1VÚ!WG@T�B3Ô~ ÎÏãñÔj5–^hÏK÷v zÁñ¡çðàO˜i.ræ&JF#•JÑñ!! .ê¦@½Cª®V«=zô(ÜÜ/viµZxh�¨ð)"Ï"a… ÷eС°–°Ê á¡h'f$mÓšD rOœ2AN‹–——÷¿|&3Ù³6¡P( öIðù|@L”a¾‹öeP?GŸH/Ì¥€dk‡°d6 ,©*t¯ð/’Pk� E€:ˆj¸�®àUÑ,j ’à:ac¤ÏêÀmB0‡(HS!Hs‹Z­–H$¦ïÒ³3ä¶ëׯ›››·?I“µo»víZpp°ÎŠPöìöööµµµàˆá€0Àœöib÷(®Ê±ý…4'ñáSx³yp¨Ä@ z|,òÃuÒXçEÂÌ›ÎZetpÂ5š@…dk&ÀžM€¨ÖÄúEzÕO§õk9tÌ¡#… V«!ä2¨”ƒ…%š`¦s|ƒ¢�ú‡¢‹éQK›áýb§”ñ¸ÊxÌdr©-¦tMÏÁd/œµTy†‚4Ë [Z¡PüÉ:S*ÁãkšË-t÷(íãàPÈLƒ£™‡y6ggg‰DÒÐÐ@$ñ0´ÂNLp÷ëÃ3Ò½Ÿ¤¹aff†žT­Vƒ<lŒÕ.— jH‹ÀÛÁ åàþäÎ5ƒ–Aœ@ G0èvé71 3èîü7áñõOµ }·�´¼>Àèã]kéRñÆCN+»hMcØlmm æ(Lf²6k/^ 2è år9(')•J™Lå,äÐ~ˆ�L&„cÐI¡wh·ÎáphÔáp8UUUÀƒ …L hZ�·8ŽX,‰Dl6;??Ÿ^òõ.ÂYØl¶ ´vÒñ lgž: a0Ð9„obˆPX>SbÍd&3Y{0ãÅaƒÑÐЀ¢j„J 6!f ÝÔ‰Ù,Ò€›ÆÜRݰ ¤Ñhø|>–å‘áø "—Ëy<^QQÖr0q‡(‚œ:‡#Pó3¹\®D"Aêä`++«††lU(p_P…"y.®fé<@Zs1óQˆUø©Áãè‡P­œËEÙ±Ìf<û§÷üÂ?”~aÏxªð)@Ξ={@EmÀ€¯½öšL&û裢££Aç†òË/¿¤§§/\¸ÐÚÚÚø¡ª««?ýôÓaÆ¡pKÛ·¬¬,]Cyýõ×oܸñðáCBȨQ£@cìË/¿$„¼ÿþûðg~~~JJÊøñãCBBæÎ or¹\Іٵk×;wpüŒÉLö¬ =�æ °ßqb¨»ÐH-Ö‰A]ƒ¡)ט‡ãÓ h9HÌté§whug—ëׯ;::Þ¿åm ,„ŒmD#üP~}HæäCÚ ’â ûJª:‚Ä"T=ÇƒÚ '­•%D%`°ždd¦€Áo…‘r5¦ÝPëÁ ä´¦¡ç/'5òYZZÚÂ… û÷”têÔ)…B‘ššŠ¼UBH@@À¤I“Z’¦­©©)555''çú¡æå奦¦Nš4iÒ¤I'Ož„):txï½÷îܹƒx³råÊŸ~ú ÿÇŽ›ššš››«V«SSS&Mš4~üø7nDGGüñÇ{öì1ùA“=·èÒY;w¶²²"Í‚U, VŠÐ` ,DÓ-/(>Î3Z ÉŒ°Ë|ÄÒL}–Ì0þ¬¯¨ÕjÉF '™FÒàt‰–zNNN®®®�b …B,3 ¡P8tèPZ±ÔÒÒÒÜÜRmNp×6àˆ„¿MötV?FòÂñññŸ}öÙˆ#Þzë­„„Ð!„TTT¼ÿþû]»v}ðàÁž={¢££KJJ6mÚäããåëëûðáò²²¡C‡FFFvïÞ=))©±±ñÝwß%„|óÍ7×®]{±žQ×®]CBBBBB/^\TTÓhðÛ¹k×.kkk///Ü~РA¨‚íïï?cÆ ƒÑ­[·   S§N½@qžÉÚÁâT,?xð ²²R£ÑTTTÀûuuu¸Æ´4fff8’ S^ÐÁ‘ €Ho±X,‰DšlpR(áÈårØ "'­VË\Él\ÝÈâ²!ò9oyØ:ª\.T÷!ªpppðóó{ýõ×íìì\]]]]]9Ž››[ïÞ½ !r¹üرc€|pÍb±X¡PÀî “ÉdPÔÁÕ:-† ¯a‚äFVžÎ’ŸaÈŒ|JwAéŒZhéPŒVMˆøÛu":~Òý mÙôf<UÈlý·_ß¼yóÍ7ß433ÔQ]]ÝüùóÿóŸÿœ>}Z«Õ&''§¦¦^¸páàÁƒ;vìP©T%%%04eêÔ©ÝÛ¶„‘¾eddlß¾ýìÙ³ðçÚµkÓÒÒ6lØàëë[SSSYY êa`™™™0�lĈ¡¡¡;vìˆ×Wã6™Éž[”\�H(!ŒNÈÐõÒÜ=ƒ94È,Ñev̶‘æ)j´µX,†žPpñPƒa0|>Ÿ—ÁkܤòT1k˜ŒJ j²Ñª*• xÃB¡P(víÚµsçΑ‘‘p^‡ÒÒÒóçÏc©  Q¡PÐòqH®Ã[¦4uÎn' a’Ñ×÷ÔHƒÇÇŽ¡$˜¢Ù0p¤ý¾¾áL#4ƒ#pxÍfdG‹¥sý@ó£ÿ/ðË iÙðÔôX#ÙÂ'¡DGGƒ2£Ž;v¬¬¬¬¡¡~3 �êùùù/nù)))»víÚ¸qcß¾} !«V­6l¬³�o.^¼8{öl !ˆÊï¾ûîêÕ«çÌ™cò€&{þƒM‘¨LƒrÂØ^ƒ"Í€7àD€P€+Y(æÓ­6øûx€½†R›:*ÔL&“·†§<­Ôn×rÊ8Ü2.aýºà ‘KÆápø|¾——W·nÝzöìÙ±cÇ1cÆØØØ@*%//¯¾¾j98@ª;4rÐ :ˆOˆ4xã°¯©ï™ÛxdCs0h†Á¸)$$dòäÉo¿ý¶¥¥åwß}‡ëPÝ0ßÛ¦½üòË�0ëÖ­[±bÅñãÇýüüà£={öüþûï„{÷îB`äÌáÇ¡yùòå›6m øê«¯L_5“ý‹k&€zH3.ÿ !666„ÆÆF©TŠâö0”¦ìм&:¡„…wüձɟž² j4Z­–³Œ£ ¬�òx<hm8ŸÏ‡"‰D3ï5¯¯oiiéÍ›7 e2Yyy9ªì`ß(!D©Tš››ƒ~6Ü£D"¶P¹\hQ¼�˜ ¡i^ο9½zõÚ²eKRRÇ«««[¿~ý÷ßïááAÙ¿¿H$R«Õ8J‹Íf{zzBÆö7Þ=z´§§§••UvvöÍ›77oÞ¼}ûvâââiÓ¦­Zµ [º^ +))‹ÅÀâóöö~ôè|E9}ú4üyåÊ•AƒÍ›7ïäÉ“7nܸzõjuuµé g²+ÊÖKªœ¨®®FÞ¶XbýåjðSlÞ„Ô €i®n¢v$��œ )ÈNu+a«*RõgåðC(¼P2N­V—””0™Ìªªª°°°Å‹C>ŠÏç×ÕÕA»C… n ¤”q~ðå�z1S¤T*ÜŽL&#Í ×ß�Wäï¸Â(3¸™V«‹Å:;òù|¤W<áX{ƒ¦o_OÌ›Ðg¬ÇlcQΨQ£äryff&!dÅŠQQQ2™,...**ª¦¦fäÈ‘K–,ñÉÖÖÖ;wîܺuë¾}ûÆ¿páBxôŒ %„lÛ¶m×®]|ðÁ‹‚7qqq;v„?ÃÃÕJå÷ßΜ9oäõ×_§wìСC\\\×®]ÇŽ;þü}ûö¹»»c-'**ÊÉÉÉä MöÜ¢Zž)g¨f†™% †ð…>%%Ô°3F&“á`i,íªo†uÚýÉT®R .P&Á�. •:1 ©ªª²µµ­¯¯ÏÊʪ¯¯úYYY ’ÒÝ*¾ÐÍ1Hž†ç�¡æÐ0ãÕ#Óæ_K¬BÆ?~üxW®\ipKââât¶ 2ØÝf ˆjøçˆ#FŒapËÄÄDúO777|úOlâĉ¦ožÉžg”~3]¨È‚«~BIœá|I,ðà˜�œ; ÃhúsÆZs€B £ÁšZ')Ç.e3÷3!ø€¨Érú‹n­V+•J«ªªìííïܹƒ<íÁl¡j6P»B5,tÃ!‰€PzP7‘¤ÿeÈ1nW®\IMMýüóÏMrd&3Y›5ì—D?‹q Í&�Š3†/ôHiìÕ‡ ‹Åâr¹Ø¡n4ŠÙ@Ü€ 4ÀªÙ³åcƨûõ3×h4II²#GxwïþW›�±e@‰� c¥¥¥yyy%%%ð)€  ÜŽ'€7! A¶4Îb@¡´GµZmK-†ðôP[q_àì8š¨F—¸5¯AçȰ#<1ÒÂ8#rmtF Õôõ=éïÃc¥Âè͌Ȟ¶2G÷ '44ôÅjí|,«ªª2¢a2“µ5m1?òfE�T�rD�èæ°aÜ7xp¡Pˆñ$£ T¢§  ÓÇ� ³UP¡Q*•<ÏÙYË`__ÕÍ›gg-—«R*aÐáüôèü| }EôìåDÁl'‘HèQ:<¹Mw4|$•J[úÕë°à zä–^´&x¢§Õéc@k Ç x|çÉÇH·âøÆï×DlÑJKKM‰]“½@fcc# ú&Z®F¡Pðx<ZõbL4¡â�‹Å …‰„N‹a �  �t« .ÿIs©yæLþºuò¨ïÏ¡BP ꂈŠ4×i�–ºM¨!:±1@äÄçóév8¼¥zÿbñiÿ·kíØ®\¹ò"rêË,,,^¬ÒšÉZcs2�6Xƒ0Ibt¸€ãs° @"—Ë!^ÁÉ›X¡A²5]ó'ÔliŒBÔj5! ­V»csì—MÊž*­–É1Ø3°ÅÙ ‚‹Å:òšp¨æIš›X±1®Mgù€[�ò}%›óLõ#!¤ƒ#î¾èe!ýÎ`@£¯áf<Š2AŽaóòòjߤ2øA>®$ŸÉ^D£'§ODZ4Èò0L&ÓÉÉ©¸¸X*•òù|‰D˜uLþÐÍê´Xlƒ=.HP éÙSûí·×/]á¾ùe“‚ @�ZŸP}¡%U@¥ tàÈxF¼Az®(ü‰¨‰\;zþÍ‘ÑkƒãÑ0ÂÃÄ—>ä …K24âE´VæßôÖœc‚ÃfiiÙ¾é+ãÇoll4ý_·{ƒ4ä¸är9¸u.—‹>T^P¬Ð¥¼¼œÅb ‚·ß~{Ó¦M8W†F/ŒP`ÛqhQŒnÞ¼yõªŒÍæ^©| ÙLÈw<¸~PçDÕD>ðh@&“¡@�@ì�  Z��Ø Ç„¸ U >D¨Æ“™k&3™ÉžÄ°-<,=%Ik¸ Ž‹____¿iÓ&œ/@šù]`Ðjnn.‘H M“làÙq Œl®sç8¥¥D§¾IÈBŠU*&“…%"ä`ˆ|>¿¾¾ž43¿€ƒàOƒÜ9�0 hPÆÂ)ì×AjYk"�xu Œ{Œ  ³U¸=ýˆt?OjÑê0¸#^ã¹~:í/P-V~3²ýã®ËÙ-}G§OŸ=nÜ8BȽ{÷V­Zß³gOÜF,Ïž={èС:]&3hÛ¶m»xñ"!dРA£G^°`¨ùBÌÌÌV¯^‘‘ñã?Büýý!sçÎ…_WBB‚¿¿¿éšìŸäÖ�KÐOaM è÷é^œ úM&“YSS)lÃÄÐC"l ùñG–V«U½®ÊÚÅ»ÆÔ’‰ A–�£+H—aJÛƒ€å ü78H �6ÂÔ~°Ñ•ÝthߘQĬ †Dk¸ºx«°¨£4„Ä,2ÑÂÒúȧ_Y¡Ÿ- xðV¤…ñ?FÆÞðù|8,ÆÖ?»ÁÔâ?‚µZýÓO?YXXÄÄİÙìÂÂÂÉäém�� �IDAT~øá•W^ÁÉ ‰´ÿ~WWסC‡ªÕj¡PÃ6€3ê@²4ýàÓÒÒV®\¹víÚêêê¹sçZZZÆÅÅ*mrrò½{÷®\¹2þüÄÄD??¿˜˜wïÞ½£GþôÓO›6mŠ=s挭­­éIšì žÁS@ÑʰºÇ´¶ ŽŽÆ”æÄs\t› �ú\ #0íÆd2ÍG˜k¢4j¦šý c ô’p(Ø�Õá¹€.ó¡aDe°X®á„.ê€n)H±a!Êô…y¶ßÆ–’¿?þøãÖ­[ÓÒÒ$ÉèÑ£§NêííÝ«W¯qãÆEDD¬Zµ @…ÂÒ_~ù¥««kaaaJJJŸ>}Æ׳gÏ»wïšžrLLÌíÛ·mmmkkk…B!ŸÏ‰D]»v=qâį¿þšžžzãÆÉ“'766r¹\333¥UQQ!‘H¬¬¬LÄM“=±aØacccmm š³0Y�[m =…Nü/H™ÁGl6Æ`Z`�ÔØÿF(2~iaKˆ$ %H“§Qª”DK˜L|@(E�¶P® tp ¤AÓ3§Šà’ðÆoP¤�c/@ShÄèŠÎ:ŒÕzF?d$)è¼ ?jË_ä\™—ó¬ ǠݸqcìØ±GŽyë­·–-[V^^np³šššO>ùdâĉGŽQ*•Ÿ~ú©é7vîܹK—.‰D"m+**úý÷߇ bii dddÌœ9sñâÅ'N„©BÇŽ»ÿ~=èy·&3Ùc™ŸŸ|Ç„B¡™™Û1ôÁ 7èvá#˜u&‰tfšÑ}ò˜šÃ$˜Î/'''d<³X¬ &3 YK”./aăÔ Ò<z�ë%�W˜çÁynHEƒ¸‡–»þo†‡ÍÆ @HäÃÄ£ÁÜTÏtކÓht†Ù´å±x‘Ш„2tðÿï<•Öø!ÇÓÓ366^{yy;vìØ±R©4>>u-Ø¡C‡âããufçüÛÌ™3ãââ233³³³ !yyy?ÿüó¸qã@:þèÑ£|ðÁüùó'MšDIÕŸ|òITTÔ®]»@×d&{óõõÈ)***//ÇšêÐ È „#´pÄ%» œ@œA¯èiÅp¯È& ù¦Õj{Ñ|vd¦Ñ¡ iîqT uÛ°à¡LÖÑ=|nl%Í P:€H¶´´´Äµ|ë&{Êcgg׳gÏO>ù$22ÒÝÝ=00099yß¾}~ø¡Á9Ê8¿¬_¿~~øáñãÇ—,YbzÊ …¢¡¡A§À(‹¹\.,".\¸0sæÌ÷ß„ ¦Çe²§keee(4@šµaP±Ü4ЈiMOpÊr¹¼¨¨ØÀY£ÇR ¢i–tÃà‰g0"0ÌÓS¹`L —ÉdB¶õžõÇkyxx@¼õ'ÌþA% Naii ³p�Ø`(5ŸÏdBŒÁ|‹Å²µµ …MMM€jXÐj)±¦“ƒz\:õ?ILµ›† c‰µÉ“'GDD”••íß¿ŸbkkËd2‹‹‹---®]»†a;“ÉܳgÏÁƒ !\.×Ïϯ¡¡¡¸¸xܸq8«íÙŽ?öí·ßÞ¸qÃÕÕÕÁÁ¡±±q„ ï½÷Þ«¯¾J‘H$555ÕÕÕ¿ÿþû™3g=zSàΜ9“ŸŸïïïéi“™ìq­¾¾^.—£ú!¦Dc‘û]�hQgðïXÆ çcé^©TbW rÞ G‡Jg LíÒ¥boo(›I$¢Æ3mhµÚÜÜ\@ H”Ñôd¦™™™¡PÀB, ZÃUÁÐ9•JUWW àM¨ëŒr¿�÷"l6:o†ƒœq´Ná®E}tæIkµZ¹\.—Ë!8ƒ Cl“Ë岿Ý¸Š =D;êç÷t:m±’†˜ŠVp`*ô oœV85’Bü›ÜâàÁƒ;uê¯çÌ™ÃápN:Õ·oߥK—Þ¾};11±OŸ>„ékÖ¬9}út§N`pΩS§¦N:{ölÓo~øðáJ¥òi+W®ìׯŸ\.OLL„a£„ww÷ÄÄD©TzêÔ)BHÿþý“““ù|þ©S§œœœæÌ™l“™ìÉ ófôÈNÓDÿBç—0·†àaoo_WW‡nnÚ@ñœ€2nI3W›«hvOL”bCâ5 ]C‰ˆ¦wC°…:ÅÅÅôà$ÍŠ‘L+à§ÈUÃ|é óììo gÔ¨QôŸ3gÎ4¸âJÿþý !ݺu[´h‘éáê<Iúaòx<úuéÒEÿ‰Í™3ÇôÜLöÏ-88ØÖÖ¶¦¦€–oÁå0ÍÂÂå<N •Ë嘀"ÍÒÌlF`C¹OÄ\Ѫä•WT[·²Y,òæ›ÊK—X:Üh|ƒÝQíÎÅãñ°”̤à°m�’iÓ¦­_¿.΂èEw&°)vù˜¾3ÿä˜Ìd&{ÑíöíÛuuutƒÞ›fèiiñtìØQ.—×ÖÖ1¬¾¾xÕ¤Y:dž1a-d€Äˆ]pÔÛðá–ÑÑr¡{ã†!ñŒ((�VÉ„Ü2ÜpBA@@@vv6M]ðÛ¿?äôlv…Av›", Â×ÒCÆŽNÔNmI®íÉ á1ñ@Á†Hss•ªl^™@£Q(Y® nŠ…¼VWˆ½.ïnykùè›qýä´h¥¥¥í˜»¢/Œa²öj &FOÄѦ ‘ÈqÒ‘PEEºÀ ˜Ão°Þ€lfˆ`�`(‡@òª´”Éf³rrj€Ä '…9˜÷\Q(0€�ld±X·nÝÂ0Pþ¬©©Á†P@ÐØØ°4‘€aŸqF€‘OuƘªAµ•GøÛÔ¨‘3â;4Ǣꦪü ’[Çí7FôŸêêkÖü-;KYY,Á³âïSˆ:Gk½™ çI¬¾¾¾ÏËéÖ­›é¿øÄÀSCe[§lCš›ù !R©C xY[[àB@®„/ôªEGQ cX)c,‚é5ظ°°@,æam‰:Ù=XÈÁµ3áh¦M°ÖŒ†, à8`‹–Z�$C¬m7ÿõ’i—m.n·™¯×Õ²¶î)Og½c¦JÞG.øQ`J¬µ!»pá̾mÇvîܹç0/çúõëµµµíþ ãâââååÕ6¯  ��#°¨Ž�&‘f}h˜aÓÔÔ„-8€:ÖÖÖÐ"Ä'̆a%Ä ¸  è€I«UàhlÍA,Ę ‚„7¼†ºjˆ:8,:rPÆ”î$%Íe*djÁŒmTÿ¤õÊt‚ :«FM'ÂÀP‰®–a GY‹Åbz,)}šÝ ÏØF|Õ?²3!ÖÖÖ }, -̼ã$×/÷éCX¬Ëjõ«ÅÅæm‰S³¯²™ÅLýI²ôíÓú¸щ{ð±ÐSþLóØؾçåÀhÈç9,//饗ÚwI|t›e:¡ $Ù`ø&øH@áôliؘ€ i(ãóùMMM6a·?â=%Ya8ì€Ïç³ÙD(Êår@)¹\Î`0ÌÌ̤R)°¥qœœkþø]9o°Y‡Ž®H3i ÿ›àÖtFº×t¡ƒ'#':3‰Ï¯eDP¯R_"SÿƳgi´(Çcz2-k³»~lÈF¡ÐN&S©T­¬Âoj†’ëWÌlU,Ø@£©þ m}¤¡¯°5¢I¹Ë°AñMÛ~íøñãÏmì©P(lÇOR£Ñœ<yW¯mаh ØÏ t ÇÛ úD•J%•JÁ¡+•ʘ˜t‹Øh‰5”ÁÈj0|>ŸÇã¹¹¹988˜›[ØÚÚº¸¸XYYAW¦¯¯ïÛo¿mccƒÑ &ʰ…1A`` ½À‡e –¥è Ý©�uíñù|”$€ë§µÚÚ‹©©Éõön¤´••,ÖY+«è­\Dzç’LQŽÉžÄòòò ó÷Ýwß5777=¶l؉ Äe\ÌâÒ[î!,ÀñÈ2ÀÄTó0i¢ÕjSSS±4‚¸¢V«E"QQQÊTCyÎknnîàààíít¥©©®¼¼cqqqEEÀIAAÁ¶mÛ`TBàŸ®ŠÍ†¦ìÊÎΆüvƒ½àt�'Øx„tp:´8²q=!F?=ÐJÉN: 'jå¼gƒá¢¯~ð¡V«¹ÙÜ-‘–Kþ(ëy›dzzÂrÁA* ²¹·ùemé>µ¦^cüøúkLáIƒŽàik!çÞ½{‹/Æ?_y啺ººëׯoÞ¼™²víÚ[·nmÚ´éСC M@5j,|Ú·Ο?ÿ­·Þ4h!ä×_…gâááñÉ'ŸÐ[nÚ´éÌ™3„!C†€rÚ;w–.]:cƌ޽{Ó[æää,[¶ ^'%%­^½úêÕ«„Ñ£G9’ÞøwÞAɵ͛7߸q㫯¾‚?#""ÌÍÍ;†/^¼ØÓÓóé>†††70`ÕªUüñÜþS±mÛ¶<yôå!}ôQ~~>Ür¿~ýô·_¿~=|'9²oß>ȈΛ7ÞŸ$!$))©S§NØ^¶iÓ&/ÏŸ?OÒÅÅå‹/¾Øµk׳~’Ï3Е>6¸@|Åy¤/cp@;šN ¾f D€ $ÐX,–L&£™cÐ'. ýüü|||BBB<==mlšQ¹¸¼vöìÙK—.›ÍfWUUq8ÌDaï'àŽöðÉdXÈÁ‘ØPˆ"Í̼5¼l@¸6ºÌ)Gƒ¹5:ýerèöû–6£ BF ‡´NÞ†nc "Z­æ]çÕŒ­ù¹¯çˆÓ•½nÞ<â訖H^¹ukíû$7W ¨P—éÔŸ‡w„©BÒ 'œÚÚÚôôôeË– >–'³gÏ>qâ„B¡Ø°aÃÆ÷îÝ«P(nܸ‘™™ùã?vèÐÁ¢ÝãÍÌ™3/_¾|÷îݨ¨(BÈýû÷çÍ›7yòäádzÙì?þzîŽ;¶dÉ’½{÷655½óÎ;ÖÖÖiii·nݺÿ>ö„J$’¦¦&›ÜÜÜß~ûmÕªU‘‘‘<oÆ +V¬ÈÈȸuëVbb¢:ܺºº“'O8ðã?†É;wΜ9óÍ7ß &“9pà@•JµwïÞ¯¿þf‡<]S*•ýû÷Zdëû÷ïO™2¥¨¨¨ªª ÞY¸pajjêÕ«W÷îÝûæ›oþüóÏ"‘¨¶¶ÖÒÒ’Ïç+•Ê]»v­ZµJ­V_¸paúôé‹- ŠŠâóù‰‰‰UUU õ‘™™Y\\ 1™­­íÀSRRæÎÿí·ßÂéòóó'NœÿÖ[o…‡‡3™Ì?üðY?ÉçcàFá¡Ñ‰#µŽI0À!¨óÁÚ_©TΜ©yã ¹BÁ „±coçNT_p4:£ªª2;;TÊ–ËÀÆÆÆÁÁ!,,¬wïÞÎÎΖ––:thNÜ)ììì^zé%›k×®‰D¢ÊÊÊK—.ÕÕÕJ$…â™Z­fð®FÛ¤‹˜·Æçó¿m4kÆd2›¾nâÎçr¸°/Þ>&èpL~±_éh`Âæ›ÆÆFH]êlÖay‡Ì•ço¿,|ÿ3ëžÅ÷CÄ…SÒ¥âBþñ-ü7Á µµµ³³3|Qà>×­[·cÇŽÔÔÔsçÎ}ùå—ñññåååeeemrΜ9süøñû÷ïgeeýöÛoOvµk×nݺÿôôô¼xñâ;ï¼SPP \\\!¯¿þúرcÅb±D"qpp°··‡×Û·o_³f }´Í›7wëÖíÖ­[qqqƒ¶¶¶þã?ìììe2™“““­­mcc#­—Çb±F•““Ãçó æÌ™3räH&“ùðáC+++gg禦¦åË—/\¸ðYpÒììì&Nœ˜˜˜xùòekkë§rLOOÏÓ§OÃúÌÕÕ•Ïççää”––Âëk×®uëÖíСC„K—.åååÂ,¨¦ÚØØ899ÉårÐ/ŠŠš:uêúõëO:5kÖ¬œœ©TÊçó+++ù|¾³³óîÝ»o!<¯S§Neee999\.·S§NÏáI>·ÄªîÒŠ/ØÚ`Á@  …ØIÈÄb±ÌÍ5K–ðú÷70ÀlëV¦J¥‚ÞIÈ¢€(€·74H1q¢âô鯗^Ò2™L33³:„………„„ˆD"WWWa€‰¬šš¥Réçç,‰¼½½­¬¬°2G†Xç¿K{¢IÒ¨‡ªåýå° FÆóŸ|B†:D­ì¬d41ê?÷¥Å~tÆ»áªÜøˆº„ÎÔ3:k‡a"¾À™ª(M†Ê@´,îkdP žîÓO?=xð`jjê‰'&NœÔsÓVkC—…ºîï’ôá©Ãƒ÷•3z¹¤ºhš4¨˜§S¾Ò¿#‘?&"åïÏsýõù<a-çèÑ£=êÔ©(K$’¥K—&&&†‡‡B:wî IŒÌÌÌôôô5kÖDDD´Í_Ý?üðÑGEFFvîÜ9'''00´yžŠ?~|Ö¬Y‹/~ë­·!o¿ý6tÕý펽zõš7ož““<Ƭ¬¬;v×Þ;vlÏž=³²²~ýõW… Òû®X±bذa„;wÀЧn‰äÚµkžžžÿ÷ÿ7zôhDÖÓ2777>ŸŸ••UXXèîîÎçó]\\æÍ›çïï¯T*Ï;½wï^Bˆ»»û€:týúuÜý½÷Þspppvvž7oÞ£G~ùå—ŠŠŠ/¿ü’ÆË—/‡˜©ð<O$geeq8wwwxÿ™>Éç‰:XÛ‡”Ò‹±ý2`€Ãá@úPƒ¡Õ’±c52Fsþ<ï÷ß9à©Á¹L›ÖÄåª##åáá*BÈíÛ¬®]%¾¾J6[foÏqv¾æâRngwž¶V«57gÞ`^? —V²ï2 +;«Æ°Æêêj¥RYæTV[S 5š¦ØÉd2ÕÝÕª9*†”AR!„|GùÜŒ¿/Ÿ.'„ð6ð´uZZã‡Pœ¶€S¨i–¶Á2ÍPh©–ƒa?AÖ‘Á`466êGT:ó¤é´Md§_À–ÉÉÉW®\ùÏþ¤õ`!¤  €]Âîr®Ë~™Lµ\ULŠ‘B( ºÚ„O�#WZI§²…‡‚ˆSç 9nnnAAA8Y(Ξ={Ïž=C† ïܹóüùó !•••ëÖ­;{öl›…œƒ.Y²dÀ€Û¶m‹ŠŠ‚ÿ¤§b§NJJJJHH�¼È!„lÙ²åo÷ ð†ÇHÙ³gÏBCC[ÚeܸqðB&“¥¤¤,[¶ ÷]·nÝ‘#G�r¶oßóŒ¥X,¾zõêþýû<cÆŒ'†œÂ¹sçâëüŒ322*++çÏŸ¿eË–¤¤¤>úÈ××nvÞ¼y111aaa9«W¯þã?è©BÓ¦Mƒ š‘‘1a„¼¼<Bˆ••UPPÐçŸþèÑ£ 6Àf555?ýôÓÒ¥K§OŸþÜžäó1œIƒNä¦ é.¯ªªŠÉdÂxfÜœl^ž6'‡ðÒKÁ×®ýÐÔÔ<f6›}ç—ÉT1 i$„44°rs-ù|¾•••…EÀ—Çsf³­Õj&!ÚÊʪÊÊJsŸI]êêâšššn–ÝJJ¼ùÞ7þ¸Á½É5k4“J¤DIˆ–-a3ÙÖf˜ ƒ§T)n BQr0 Ž„ƒŽ[©T²8,­½–YÃ$–¾u¾ZÐ=.pû˜l4Ù3²¿œ€€€!C†üwk6;!!Åb½ýöÛûöí‹ÅqqqëÖ­ƒAÔmÜz÷îíààÀ`0\]]ŸÖÍ;wî¼ýöÛ³gÏž2e ¾‰Õˆ¿µ¦¦&˜<Ý·oßwÞyçý÷ßoiKµZ]QQaaa1kÖ,X³cb̘1óæÍœ«®®f³ÙO+åeĺwïþOždÇŽ1ÓØÂB¡¨®®¶¶¶¾}ûö¥K—àöÅbqBBÂG}4`À�º¯­¢¢‚Ífûí·k×®š££ã!C6oÞ|þüyȃƒ`¥þŸÛ“|¦†'”…J`†4­¿ ʘðQsjHuëÿØ1ÖéÓyA©J¥š={vjjj}}½F£9vŒ¡Õ223ù77òÕWµÜŸ¶sqqQ©ºªTî2™W·nÝššš²³³Åbk[[.]ÂÉk>trrê ê[Ÿ[]]}ëØ-õyµV¬eÈ, ×à&ól¤;Q?P }„J¹’SÃQ©T,. 5ß †ÖYK„„µ»šsƒÃ", N€zʃî¢ÞižêöL!‡>8¦ÎžìPuuukÖ¬Q*•àóÏ?o‰Þ¡~CÏãΖ6¸±~ïŽñc>6IšËåΚ5‹ÉdŽ7nîܹVVVçÏŸ¯®®vppèÚµk[þáýþûïQQQZ­¶¨¨¨¾¾<ÿó"^CCCAA`@§NüýýGÅãñ’’’\]]Ï;'‘HD"”ytlëÖ­‹-:w›Û72224Mhh¨§§g‡N:•——×µkW‡ÒÒÒ€€€ xzz^¸p!###///,,ÌÌ̬cÇŽW¯^urr„‰'º»»?Óà•••¹¹¹ té±×;l¶££cKŸúûû[XX�‡"00ÐÂÂ"++kÈ!7n<|ø0lâĉwß}wäÈ‘/¿ü²¿¿¿½½=hù 8ÐÇÇ'66V«ÕþòË/ø$ûôéSRR’‘‘QUUЪU«RRR.^¼|çÎŒŒŒçù$Ÿ[VvIÐÉf³±Àƒ<ä}¡Çô}p°‚ÉäK$5rkkÙ«V­Â6RÈ«H$ …‚]_Ï~å@`mmÁãñ¤Riee¥\.ïܹsUUUNN“Éttt¬­­åóù:uâñxEEEׯ_ÏÎξrå MAöñ� jµšsøÂPiT,&‹ÅaaN “câ¯ÄfýÍ †ä€„ɶUÙÖÕÕáã½-°ã I”¹g×—CËnb ™ûúÉ'Ÿ,]º‘ÃÌ̌拣ékàl$U÷Xׯ¯†£¼0Uh¼·‰åìì§T*ïÝ»Gën1 kk눈¼IŸ^½zA‚ÇãY[[7®¤¤¤¡¡a̘1£GnË¿ºÿû¿ÿÓh4‘‘‘û÷ï¿}û¶™™™ÁKKKíììZZ¿3 ‹ˆˆˆŽ;2 KKKssóŠŠŠŠŠ 33³.]º0™Ì‘#Gvîܹ°°P£Ñ¼õÖ[P:b0666}ûö…§Êd2ÝÜÜ¢¢¢ TYYYQQѧOŸ÷ßßÇÇÇÕÕ5??ŸÍfO:µgÏžÕŒˆˆˆU«Õ%%%ŽŽŽóçÏïܹs¯^½àì/¿üòÔ©Sá°AAA!!!FȽ{÷ZSp2ø ±öÝwßÅÄÄàÔƒöàÁƒnݺµrj:ƒÁðòò‚öèÑÃÆÆæálj‰‰]»vmé;9|øðÀÀÀÒÒÒººº˜˜˜±cÇÂGaaa111:O2::º¶¶¶¢¢ÂËËkÁ‚àb<<<^~ùå>}ú<Á“„{ôññiƒŠ|R©´®®î?þ¸qã=e@¥R …Bpµ(ì*ËðLè7 ƒÉdu쨶·W¹¸°ªª%%·¦}7j? …B+++›:Àïê0 2 EEEMMM555µµµ'Ož<~üø½{÷*++hÉ�Ô§Ñç!ª½W›ÂÐ0Ø9l6›­Qi·J‰#$L©‘¿Ê·ÀeÃõy{{;99!ìÞ½{:tHMMÕ/iè/öin±þzψº½FGðÆàޏ»™™™™™™@ àóù¥S¦Æ‡:âõ¿´ú†µƒw¤_v‚ç3eÊ”úúzwwwÀr…BñàÁƒcÇŽ1BCC333%ÉáÇi¾Pû³³gÏš››‡„„\¿~½¡¡Á`ŸØÕ«W½¼¼,--ÛqV÷È‘#ãÇÇbæãZUUUVV!¤_¿~ÆskÇíµ×þI0ÔöÓVÇ9räc-ŸUWW?zôèСC©©©è@!˜L&ôР'…æîÄíqB(ºx€àR# ŽÉb±\\\…B¡³³³J¥233srr ´¶¶ÎÊÊ’H$ÖÖÖ@ˆohh(***))©­­Õh4 ê­£jµÃ,pÇ8À¸ô¬kXkàf®èá…L&C�ÈP(ãÇ=ztpp0*J>|ØÏϯ_¿~­¡à£3ؾƒÿ úQ=¬HŸî¬ß¾ƒÝKÀOÓ‰¢Œ4hã…ÑQú:ý ƒ 1¤Íc$ʹtéR~~~dd¤\.·°°hllšÕÿú@dd$¼x!*OmÜìíí¡ÖdmßP=S­VC¶ ½êÓ`]JèèY œÓhÀGã|0¡Pn‹M—Ë…8F�� �IDATÖ2™ÌÜÜÒ§€"‘WCLY__Tø.F,ƒKµ°°€±Ù¤YëîúLuHó<$Lƒ†{ (…ý°ÀÇG„´æÖDä�ôpßMÏè¸?Åy©:´49 ¦£1 ÑÁ*z‰Œmdx"}1žÐ£±G¬D>|†:×ótj9ÿ;VXXØÊtЋhO–R{2S©T "Ð^£œ6~…ø5F24°Ñ_ƒú 6„¢>&iÖ-¾yó¦þ§8qoäÆáp�8P>ŸŸ››Ëd2===y<žL&³µµååå%%%555%%%uuuàmQa'н ¤y²´Á·5{€û�BÑ„*˜CôJèåq†)ŸÏ²ZŽñÒ:nÓÊoK+ÕEl¯ŸÜ£3Šøâo+ôAZz2ô Œ¿½5äsÊíx^N@@ÀótÊí8±F®AÇE„ðé€:P½�,O .ü/æy¤R©P(„^Œ zhhh`±XÐèûbsF£qà �ÁZÛÌÌ ˆ£¥¥¥–––°4ijjB¦�ÆR´ÒNÂÆ)8„b=`ò i4È�Ó[b'#ò÷ZêË1ÙÓ2ä°®]» ‚6;þäi6‹=SëÑ£ƒÁðõõm÷ ”6ž[ÃQ›@X¢U™i-KpШíÍ’ä¯#a�¥±à¤)H(±X¬¦¦&©TZ__Ïd2££cqq1ˆˆD"¡Phgg'•J=<<p(N]]–pàtJ¥õ7á. >ƒ¸^c3 ä‚0n£ï$ PŠ !ÅÜH3µï =©¡ñ:aƒÁÀÖc}`ƒT$\¿~b^þêôoOdÑÀŒµ(#×Oꦵ‘ZÚg^ �žÈ9­µ¼¼¼‚‚#sÎÛ‡ÙØØôéÓçYŸ%;;» ÖÕŸº‰D"??¿6‹7ྡŒˆÂår¡Ý*4‘«ô4s‰ž±†2-Ø ^öåñxpd…BÑÔÔ„}0ÖÖÖ …¢¨¨ˆÏçÛØØ@.K©TZZZºººŸ ó{Íà\©T  4è @KƒÔÜÎÎ>‚\.G™5å€Ux¡¯eÙú‡Üš4š¯BWJô!!‡V7ÐyÇx~ ‹@-!žZ:ŽÆÞ&>:¤š §µ¦V«£¢¢Ú÷ˆ¶’’WW×'f¬µÞ”JåèÑ£[)íþ"šV«-//ïСC›EVLšî2òÁÀ•…B¨Á@r œ2Ö?0¬˜{e°& ìÒÐÐ�Š“�cõõõ%%%\.×ÊÊJ °X,¹\ngg‡a‡•••V«upp@ €õÐ —‡<œl[B\\\ iqk\ŒÓ#PsÇÊ!Üš| )±öïäÚ1IúìÙ³ãÇ>çÒh4í8ÐÑjµ™™™:&Ú”_ÆÊ ›ÍÆ’ F'èß¡Sqœ;9�œè `�ǃ™žTUUAå¶)..V©Tvvv¶¶¶r¹¼©©©¶¶‚-ÔÀ””X°ïƒ*…Bצƒv˜ßÃÑŸ˜E¤¥Õ�néQo8Õ°¯‘̤~Ì¡åÐQVéõ¥Òè_|Ša%=ÿF?ñEÏ Å³_tTæè ý¸ŠfÜáöúQbê_Ø“k¬™Ìd&{Ñ Ý%Çà L_ƺ3ÌV¡×Cœ{ xz 4ÓL­V ±±çO«TªÆÆÆ††sss;;»ºº:ߺl a‡NÝ‚N÷a &,@(ü¸  G‚߇\œ\.·²²’J¥�ŠH’FÈA±5¸‹–š´‹7R;ÑwÐôéûbšëÜRŽŽäf¼EÏÃÖg á¥~1IÞú7Kc>1lè1&¶ˆW®\‰D={öŒŠŠêÝ»wRRÒäÉ“—æTQQ…·ŒØâÅ‹E"Ñs«ÁöêÕ+>>SL"‘hýúõO÷ ï¾ûnDDDŸ>}æÌ™ÓÔÔ”››ëííåçç—™™)•J?ûì³°°°þýû=º¦¦÷­­­0aB¿~ýzõêµhÑ"‰Drùòe__ߨ¨(Ÿ[·n‰Åâùóç÷îÝ;""bòäÉõõõÿ–;+//‰Dk×®…??.‰t4Íþ¹UVVFGGGEEõèÑcÓ¦M¸°ª¨¨èÛ·ï„ êêêÞ|óÍÈÈÈðððäädz¶Myyy¯^½¢¢¢‚ƒƒ÷íÛ'—ËwîÜÕ·oßŠŠŠššš‘#Göïß?,,lùòåЂОŒ&àJîÐm1´«׌³s�àwŠŽ†ÎV544ÔÖÖÖ××K¥R‰D"—Ëa/‰D"“É«««‹ŠŠjjjJKKkjjjjjÄb1P¥AI ´/¦¥\€ jiÈ)�^JÉÉår­V %% Ap˜)vùÀ)Zß—c²§ŸXS«ÕõõõË—/7n\ff&¨êZZZVVVž={¶W¯^GŽéÖ­›ŸŸŸ\.?zô¨···¯¯ozz:ühûôécii™�eÕ#GŽÀ"22ÒÁÁ¡°°ðòåË„ ‹AƒÉd²úúúç–È ½}ûöÝ»w½½½Ož<iff&‰žî)®\¹¢T*¿û¢¢!C†„……­^½ÚÓÓóÈ‘#ñññ&L8vìØƒ¾þúë.]ºxxx¬_¿~Á‚°ïæÍ›322îܹ“••5a„¾}ûNŸ>½W¯^»v튉‰™8qâ¢E‹`$«‹‹Khhh=¦OŸþ¯|x<ž¯¯oVVVYY™¥¥åÙ³g]]]íììžîY>ìååµqãÆ7Ο??**ÊËË+77wçÎööö;vìøé§Ÿ®_¿þàÁƒ˜˜˜Þ½{Ã7–òþûï744\¼xñóÏ?Ÿ6mšObbâ‚ fÏžíáá1oÞ<ww÷_ý5??ÿĉñññÆ%|^ÄÔ¸c táf€ GGÇÆÆÆúúz‰DïãØP\´b%M\øhÞLZcc£………ºÙàÓ††…B³8‹ŠŠ,,,¤R)—Ë…ªŒX,njj’Ëå‹ YNŠð Ô„ã�-¨»Èår�€ä  06¶A†‰5#l«'Ž2ñ˜Fd h¼ÿ‡ITƒÁÐ߯Áú‡ÒIÄÑi7y:Š2Þ~ôxw(“É6nÜøÝwß}ðÁEEEqqq0l±¡¡!..îСC{öì™3gNqqñ®]»æÎ[XXwôèÑ;wÎ;·¸¸855uîܹ%%%III(..NHHHKK{Î?Â/¾øÂÏÏoÖ¬Y .üüóÏW¬Xñꫯ>ÝSDGGoݺÕÑÑqóæÍ½{÷~÷Ýw=z´p᜜œwß}×ÇÇgëÖ­¡¡¡7nôôô|饗^Dwfmmðã?æääÔÔÔ¬_¿~Ô¨QO»5yò䯾újáÂ…ééé111 ±öóÏ?5m€7Pº�º,ç9Ž­­í¤I“† Žû"ÁWb‰žP…zpRXkàGˆªTªêêjȪ) ©T Ü6è¼ihhèÖ­[aaá£GîÝ»————ŸŸ_TTTQQ!•Jºté4<>J 3J£Ñ ¼ª½Á§ôüixgá á }%BîøtŸ<‹Åâ7»öÄ\YøÿÒ±V²!Øcð_‰-M:FþJé~<ÈY½zõðáÃ?üðÃ×_$†^ýõ>}ú;vL£Ñ,^¼øÀçÏŸŸ={vhhè„ Ž=ZSSS__¿fÍš©S§¢d¡C‡¸\nBBºuëâââ,--g̘±råÊ„„„ÆÆÆ'N<矟™™Ù’%K:wî¼nݺ”””W^yå(11ñöíÛ_}õU·nÝ.\¸`cc3xð`''§ .ÀË—/OMMMMMíÝ»÷ êËzõê»xñâÉ“'÷îÝ{̘1Ï(;4xð`oo±X|óæÍêêj#By&£#QtÁ90˜’Á`ÔÖÖÞ¾}ÛÞÞ¾²²²môtØ“W8tz_0kÞ‡4÷ˆ€—J¥MMM8�8Êú¿~ýz]]$Ö*++ËËËkjjêêêP¡¡¡:žx »Ð³5á~o ÀÂÕ7H¨ÑH�íÞpGôLÓwæ¦y<}úô}ûö¥§§oܸ(ŒXÎáp8aaa‰äæÍ›YYY~~~îîîÛ¶m»téÒþýû#""=z¤¬‰D¢ˆˆwëÖ­aÆEEEý+©s•JuäÈ‘_ýÕÓÓó£>*--}ꧨ¯¯Ÿ2eÊ•+WNž<éááA¹~ýº••!_¿~]"‘|òÉ'»wïNOO÷÷÷q¿C¶¶¶)))ÐèwðàÁN:=#ȉˆˆððð¸wï^UUURRRLL ÈsI¥ÒêêjÓ¹%“J¥:u]LCÁb_.—/]ºôêÕ«ˆ.|>°Éd:(Ô„@�`à}š˜¤ÿÎãñ”J%ÔQ “¦R©d2™B¡Éd‰¤®®®  @,×ÖÖ–——ÿ%%%Öƒ“Â(r—I3ãnÚ´iôÌi”ÆðÞH0Úh˜ø JY|šñ¤þXèV~¤³Î´S#PךÃÌ¡éœÂà;-…J´Ô)":=ZûŸ‚ì¿]Q$ Ÿ6mÚܹs`ÖÖÕ«WkkkwíÚ5mÚ´„„„Ó§Oëì’““s÷îÝ€€€ùóçÃFƒƒdžµ}ûí·Ë—/‡±Íï½÷Þĉׯ_ßÒ,ƒ'³|ÿý÷™™™Øo¬_ìY½zujjª§§'¾yôèQ++«1i>ÅwŸ®]¾|¹°°pÔ¨Q¸>íÔ©SJJ !¸¶ú ¹\þÓO?µ{ÕƒÖ2i¿Nê(PéAŠMR©T¿ýö›P(433+//Ç„ ‚ ø&´ ‚Í(©Ù<ÞM¢5˜Â‚xH«ÕB¯P«ÕF …BœUŠÕÖ¯_ÊÐ:<¡±}%¤Ú°‡n¾û…§7Âçóh`¤š‚Ä3D5U¬>$àä7¤$èof¤C“Ö÷4ÂXÃOéwôõ hFœ‘’b¼L&Ó¹ÚV†€õL[ 9kýû÷OKK«¬¬Ä¥}RRÒ¨Q£„Bá›o¾iffï¿õÖ[IIIÉÉÉçÏŸ 0`À¸qãÒÓÓKJJ¦L™’‘‘ñŒ\UKöé§Ÿ†„„@…9999 ##ãéBØÚµk¡–>f̘iÓ¦}ñÅÉÉÉÙÙÙ8&ùÛo¿Å€ 4þ|Ÿ¹sçþøãË–-«¬¬|饗¼¼¼¦M›¶k×®äääÜÜÜ3fôë×oëÖ­æææí¬Ü­o ,¸zõjvvö˜1c\]]¿ùæø(44ÔÅÅeÑ¢E3gÎ\¹re}}ý€|}}¦N:wîÜ7Þx#+++99ùÒ¥Ko¾ù¦‹‹Ëĉþùçêêj>ŸkiiyäÈ‘O>ù$??èС;wngOÖ£°8ý´× ð€O5쑚N }@``Ð�¯é¤¶ò`H«iôhÀo¨ µÔè±:�âP(”H$3:ši˜‚ÓY§CHÛ›kÏöÛØÒÀ=£àóæÍƒ¹U£G ƒæü=zxxx$''Ã6¯¼òJ‡”Jå°aü½½…Bazzº›››‹‹‹“““J¥6l˜¯¯¯••ÕÒ¥Ksss !/¿ü2®SžÏmïÚµ £7¸È§{ŠaÆÑUt—ÀÀ@Ðm6lXHHˆ\.OOO§7 „lß¾](úøølÛ¶ ÆùuêÔÉÕÕõ½÷ÞƒáxÆ ëÙ³'›Í^»vmII !ÄÞÞ¾-Ìc]¼xñ³m‹ŽŽÞ»w¯D"6l˜§§§ ~´yóf`Ímݺ²1...nnnJ¥2==ÝÕÕµS§NôwÒÆÆfÉ’%üñ!$&&¦{÷î„;wÑÜÝÝÝÙÙ¹ýýΑñÞ|7 & ,,,$ F$¨NFš9ÄÈdÃÐnì Í%hȤAu€;Àår :}™L†ý˜´È  ]°¡)g°B‡SÃÅãDlVAhBœŽ·£³¨§Ñn ûLMö¼!ÇÂÂB§ ~ÍÅÅü£X,^¾|yvvöÊ•+q³ÐÐPz/<Œ¶D³·····×Ùæ¹}‘<ïY\€“““¾d}">Ÿ¯^œííí­“áÔÙØÝÝÝÝݽí|“žEŒH[PPÁ÷qd§Ž +‡ÃÁ'¦ó´µµÕy˜í;ÿ†94ðòÇ@X�B2àŽ!š,ÒÕ0Œ@^µ™™YCCvö@+(yà(F#—ËÕгÓÒ¢ fcÓ0{@0×�*ÔÐliÔ´Æ¢+:9+d"ÐÓE5á"á V8pò¦AÓï!…j<¤-èÁ`FïXO{a‡¦~ÆÏ =®êŠþH7…Bœ‘§œXËÏϯ¬¬Ü±c‡‰¨j2“µY`Ëå˜E�· î .¸ P¯Ayš[Ìáp8(Cƒê:ãLhpÍ€g”`ñ�IÕXæu�V³¡`%ôÐ�£ Èo4Tè:Àƒ ‡Uc‹+R¥t1φ‚=HÉôás˵´332~û©Aޝ¯ï† Úë¼råJ;ž—C÷ç?k“Éd—.]2ý&ÿ-£G^Ò8A7¸Ð½–^f=P¤± û‰BÝ6˜Ž2tö@ª Hn¨( ^ ªª@X€Zpp.¹†W…ÐB3§qÙ6XqÛÙÙUWWcG6¥"¹#0d(´¾‘ÅdO9±f2??¿'žÑöíyNãñxÏs"Üó7Ì~´MCmô°¶Â^}¤œA(ƒ¡�Vnp´ M/ÆÜ7�Ng d5ÆpÐ5  –ˆHséæO“f!/„Cä¼!LB.ƒB̓”šL&ÃLJgÒ! ž"Ý�8r—ðô¸ýmô›ð êiâŽøôô9Ç´‚Ýä‰8¤#”`¾LO¼Ö™2 ³Y+—/:×OgüP—þ_LóvêÔ©6îGþ¹Y[[?Ÿ*Ú?üÐŽ‡€¹¹¹µÙy90|3`0þ´µµ­ªªB7‡’è(‘[ ®ZDiyMðh(Ï ™™pI ®Áª8ƒ$ŒÃhebð¡ÐèƒÀ©P(„B!0ã!ÿ†è·Hƒ2£(ņ©?ìà!•m¦G D:)g0”¤F<3Žôñì/Cž~vËàÑZ™ûj ðÐóuŒ|j‚œÖZtttû.PŠD¢ç0/‡2zôèvœ¬Ðjµ%%%ÎÎÎmv@¶§ðù|™LÆçó±4RWW‡ë}Ì\!Ϭã[ñ#LUßÇž@£io(ÐS�5§T*ù|>–<F c’âtDÉ� ),&á(Lú¡P¡Èp “4%ÖþƒŸe{½»óçÏ?u%Ó– ˜Kír.^¼Ø–çå`nŠ^bN |.6™#„Ð9+&“ioo¯T*kjjL…ƒ8Á¡+•J@�>ñ�—äàåi 21 Y ˜CENH%aágüÈd2ä&`&“pX¸<8b*-ƒÀF–ZZÚ·©–ý"ƒƒyôW{tâîoƒª'0ã) ä˜Ìdí}]ÉfkµZ333@PSSº/8‡Ö(à f ¸^¾©© ç æRÇCíNˆà€ÖÖÖ0•6ƒÜ²“uú~à_d¨T*HsF�èÀ¾pa `M‹UÃ1i¡h¸TÔÅ©¦XzAMRÜÑ ÿÅQ›8j#c¤.`ðúŸâòÚødÕÜÅ‹ííí8Ð.„þþþo¼ñ¼...¶··ÿòË/Ÿî)ª««ßxã>}úôêÕëwÞ©««ËÎΉDQQQžžž?ÿüsSSSrrr÷îÝûõë7tèÐòòrÜ·¢¢âµ×^‹ŒŒ MJJjllüí·ßºtéÕ¹sçË—/×××'$$„……õíÛwܸqŽÿW¬¬¬ÌÞÞ³Ž=joo¯/tô­¨¨fÞ®^½c¦ÂÂÂàààQ£FUVVŽ=:""¢gÏž³fÍjhhÀ}óóóýýýaLÑ–-[¤Ré×_ ï„„„”•• <¸ÿþÝ»w_°`Áóäò=¨ÉdUUUR©æ~bÝJ#FŒprrBùNÒ܉" !‚‹Å  ¥{KKKGGGèøî�§ÑÔ××ãŒNˆ<½†SPí†Îq!GçI»¹¹A 0™ Þ0`ÂÃ"ÝÁ 4ß�1*‚àß6'ÿ£‰5X¤§§÷èÑãçŸ&„¼òÊ+Ð0߯_?ww÷’’’“'OBø|>èŸ>}ººº:<<üôéÓÑÑÑÖÖÖ0Ý€2vìX`þ¯Û!C.^¼˜xôèQ—§^û½}û¶­­íŠ+ † ½zõj˜—3eÊ”'N466nݺU$yxx|óÍ78/gûöígÏžÅy9ƒž>}zŸ>}`^Δ)S-Z´{÷nœ—óÝwßý[órA¿~ý²²²Š‹‹­­­OŸ>رcǧ{–ß~û­oß¾«W¯Þ¸qã‡~8lØ0//¯Û·o8p ¶¶V­VïÝ»÷äÉ“8/祗^Ây9~ø¡Z­>}úô矞””šœœŒór>þøcww÷Ë—/㼜!C†´3!쪟*ípQŠ&##Ñ—½È‡îïïçÎðÚàÊ}||Μ9µz­F+`äÿ³÷ÜqU•ï¿÷ž»Ùà@qãÊGþpÛC3J%1ÔÔL“!ŠEÉÙÀ‘DV̙8rä"QCd¸@QP6Ü}Ï9¿?yz» ©1®~ïóŸË¹çžó¼ëÙëîàóéì,è‰ :Qÿ�{×;wP~GéÚÊAúõí`èË>z°=äsh¤ã­§T/Ugdž2òÒ×!f”!TËcN÷�5jtý„ö1Zª±ØZ-}QéÀ¹ZÔ£ÿ>°lÙ²¡C‡¶mÛvûöígΜéÛ·ïñãÇýõ×µk׆‡‡³,ûæ›o.^¼¸´´ÔÕÕ5<<Üßßÿ§Ÿ~:vìØÎ;’’’‚‚‚¾þúëììì¥K—šÈ!\ºté¢E‹‚ƒƒÝÝݾüòË¡C‡Öí+ 0`À�ƒÁ>pàÀ^½z…„„,Y²$444%%%$$¤cÇŽÐLsÑ¢Ennnõ×@¡^ÁÆÆæƒ>ðóó „@‘‘‘F¥þ;Œ?Þ××7444==ÝÏϯY³f ßtëÖ z瘡v–„3ÿéêËô·t³2¬r†eÐ0Au‘7ndff‚ï„]C²Œ(p.e†uÞ€y`ä˜Ñ,,,Æüøñ[·n!ç Ã0¼9©j§Í󼕕JÀ4 x2ÖÙDa×Rcî´†€”—&²F}ÌjÌöÇ·ÐAÕ´îõ8"NëaX:¯–z£5²dÆÕyÓÔû¡ «CíOøwÒ`0¤¤¤µmÛ6!!!((¨W¯^'NœÐétsçÎ]»vmPPÃ0G½|ùrnn®¯¯ïàÁƒá·û÷ïwuu rrrÚ·oŸéB…BùÒK/mÞ¼yãÆuÎo¦L™’““³aÆvíÚýöÛoÍ›7÷÷÷oݺ5VW[²dI||üŽ;°ÔÍsžžžóæÍ{ï½÷ 0~üøúx Ã0þþþ½zõ:{ölyyyjjjaaaý-Ü‹Ðì=4P8�³m0R�,`˜@ƒ®¬^“’’ið[àIHã袜¨s@–Še‚ÞºØ(jK„èw’’rïÞ=°éÁÏÁ@‡v<°"3�* ª•J¥ÂÒMw\.§½è`ÑÕÇlX«WøO“{éÒ%èHÿàÁ¼(‹¡= ÀéÓ§‡ R\\lRe¬ôzý÷ßôèQhÖyëÖ­:Eaaá¸qã®_¿½™ !™™™–––=zô°³³ËÌ̬¬¬ŒˆˆØ³gÏüA—O}µk×¶mÛ¶¬¬lß¾}õ\.zôèáì윓“S\\<kÖ¬Q£FåäähµÚÊÊÊúèxô"F£Áàfp€LF6¨ˆƒ½ph§ºV«EñÈ6"A5,š°œ Æ.…Báææfee¬—¡Y�xkkkt ‰D"[[[`* ¶ †¤¤$¥Ri �\ [f`1øu5ÀðG¾«×ëÕj5@—n«…ß<a¿™ïGTƒÇÝù8Ô O¥øÒ¯®ý™O…©5áÙ#Ö***ÂÃÃCCCA]Àë*• <h_Ú¾}û‘#Ghn£Ã–-[âââÖ¬YóÆo„††®_¿¾nò÷ìÙ“pöìÙÇÝœœüõ×_oÞ¼™ö|ìÚµ‹.“l€3gÎܺuËßßI^=¶nÝJ)//gYöÒ¥KÕ‰ì?þø¸b ÿS@wÊÁؼŽV/ˆc~qí!FSa°JAMtËc 0ŒmÚ´Ù¸qㆠâããQ­A6&‹;t蘘ˆ±ÎMš4©¬¬DwµL—Pžk§×ë±D)ÚÈd2ø€uhS”ôc)�� �IDAT´å}‘¯Ý”ô´ö+Úð…ý\ ô5mOÃûTU”éX‹Qƒ†×3ªìi˜0 ݉w?xïŒ8V-3�ñèuÏr Ň~xôèÑ¢¢¢‰'~÷ÝwݺuûüóÏû°°°ØØØààà£GFDD˜Î!üâ‹/zôèñÆoBBCC_zé¥cÇŽÕG ˜U«V yÿý÷ÃÂÂÀ”œœ†ÌïäÉ“„×_ÝÛÛ{éÒ¥;w^°`Áþýû-ZTTT4|øð.]ºàLfddDDD¸»»¿úê«6l°°°ððð2dÈ ïX½zõ¥K—ÒÓÓßÿ}Œ0<}ú´““Ó²eËfΜ¹téÒŠŠŠ×_½{÷î!!!sæÌ™<yòG}|ùòå©S§º¸¸Lœ8ñÀ¹¹¹r¹<00ÐÒÒòСCyyyo¿ýös­qÖX‚“P ÿè5A KwÚq‚䩺0‹~º4&cB >ÿüóÔÔTRåÈ¡;[ó<Ÿ””„ÑÒ<Ï£½­^˜Î‰dùzJHUý캆JrM,Mû«oÁ À{ÌÍ êËrºuëvêÔ)wwwXÎE‹…„„Büüü† ÒºuëyóæÁéС믾ڴiÓ±cÇj4šœœœo¿ý–2qâD(©2qâD“*²{÷nlÖÙ¼yóS§NUo4ðÁÇǧOŸ>ø¯‹‹‹‡‡øÕ'Nœèææ¦×ëO:…7€K|çÎ2™¬M›6Û·o½°yóæÍ›77šI†aÖ¯_ñlmmë¼Ùϳ1×úë)Þ¯_¿_~ùžïââB7NýþûïÁ–»eËèyÓ¬Y3hÎtêÔ)˜½Ý»wƒØÕ¦M++«E‹åääB¦M›+_YYIiѢŋ� °2?]©ŒfÀ`$‰­­-Ì$ºÐøF.c\qÌçÇh†a”JeBB„`/NZÃÀ › F�©·ÐøƒYŒ®w@=„Ì ‚Ü X·aG¬‘C×V öÌÐÐ,Ǥ~´ó ]kÚ´)K‰D‚šA÷îÝ·oß¹qãÆ7n´lÙÒÚÚZ,7dùÈ'º¹K=!éàà�ý@i _$•J«¿3* PÉ-ZÔy,òún¦iÔÁÍÍ >u‰D8cF½|lllŒ&“ö>¾x`ggçäätóæMôÒ“ªXX,ºŒö1pà·À‡Ôj5¤Ò49Ø K±a¦ xS€[8::Þ¼ymG˜Oƒ¼ ¸p/ø9ÖÝÌ13”T%ïNÿ‚=žlaa<ì[ƒß0[â) ÕT¥RÉd²Ç•)ÃÛ„jóLÇ.ý=R„ꇚ;Ž?„<Yò˜TJì¸SÝgƒ†8h*ª*|€È 8´è@¨ºpôˆª÷¿T_òÏÐ;šOW7ÜUí«ÃZuð÷÷7 Á³fÍèbi3˜¡q¡°°°K—.ÀrPÀGsÒ;lF€NxÔÀQ…¢I•?�nbdii)‰JKKµZ-ö2À,–essséÒÐÁ#Ö@£Bå‰56סsPÐî‡)/¨Zk˜BUc,Ûƒ*z‰`˜t‚YÑi-çÙ ((è…™šÄÄDs¿œ:Fsîܹu&MŸB‰D¢ßÿu¬vƒÉ4˜FC—Š¡£d2†"BÇ:ÃÏKJJ°ÄÚ¾à~ÌÍD Ù ûÈK0S|ŒÜ6¨C€è fC—Á¦S…ª&T ¶u {†šáù`9/ pçááñ×”íÝ»wƒN,µ‚~Á –Š÷&²™AóÀ*a@dA3@6ƒŠ ]‡†TõQÆz0¨Ѥ5x :а³P(”ÉdÀ „½JÀ Á9äààŸŸOwš1ÊB—ÝlhF-s°Ï)DÖ!£Å;é jà‘ô=õ·ÐÓü³ÛÐî1ÚŒIªÚ ª“iíšô~@Ýï® O gX{‘àÔ©S¦Sž§žÀÆÆ¦oß¾ ð¢¼ð’c«V­Œ<F¦¦è`ö X´0 ‹B°ð%Ü 4“Wè°7R9†F0tÒˆD"±X þ¸«Óé€2¢ 5 õR©tæÌ™QQQX ša™LŒC΀Á[YYAê ‰®µZMÞ`,C@ÛZçè`6LZª?…˜®UóT‡‚®¦ƒz!~E—zÜ««æôýuÕJ‡Ôäm2³œ‡!C†4oÞü¶êÞ¾}»}ûö Ó/Ç” û× äææ¶jÕÊdûå°ƒk ˆ]U¨!¡ð<‚ãtUÉ7BxB8†á9Žg:Ê@Å3J=zÄfª”Žã„UQÈb‘ˆã8­N'‰t #d2™e z=!„£XDzD Ð  óóu“&Ñþm™••²¬ì- z=#ñ§æyF(d9N °ÀØ8ŽãyÂ󡃊×B!ÏóZB8žÂrH߬Á ‹5O#ê ~6ø„Fß­›™�š k�/v¿œ¤¤¤K@yáûå\ºtÉâÔ;ÿJ%[ZJ·qäx¬dƒAP•£#‘H8–"€X5B€Á^(Âó¼ãˆ@ÀTÓ ÀÂÆq¡ <oà8±X,eY¢ÕBô,+H† "‘H¥TŠªZÉ«B z=`‰|«¼´”Ty›8žg@Á"DX%¨XVÄ0p€ç9–0 Çób‘ˆ­ Ÿ½ÀÞή¢¢‚ã8ϳÕK«žo0 ÃTņ­2tL0’â íª ;BEˆÑv?¼ŸnjT3­v²S{#|ú¡«â¤¦êýuè!Wï]ÝbFw @å©㤨2¡£¦ÊQÔíIÀ B´E>-%‚Ô’u#f²,dG휡PÑ“ÑAœ¸ §Xß ÕjéPÎÚÈnÄm`4ÃÕg©lHƒ‡›e2Ù +W^¸ ß¹ ‰p‡ˆ%a•žñ(b­ªè©Š¢VˆD@VÄUá¼Xu†çyqUÀ4£Cö¶„a8Ž“T9´Z-œt@ЧOŸ‹/>ªÕV¨-‹…U­ä®"îM€= à6tö`Ô¡’~DU¬®k…B^/‹ÑÛÄUT&Óëõ"Ðð´Z2fLuÂJ“lºÈ¦ËÁ‹HÄéjÕ­vF ÿºšµÛýªW³¦©Ð“âjg9µàO[üjy¬°)¸E‹ ðñññññÙ¼ys݃©S§¾úê«^^^ï½÷^~~þÓ>A¯×ûTÁ¨Q£Z´her&Ç%&&.X° E‹ÙÙÙôWeeesçÎ8pàÈ‘#‡~çά¬,È!]·nR©\·n]Ÿ>}|||<<<²²²êÛëׯ÷îÝûµ×^ƒLÉ… &¸»»7î Ÿ={¶S§N>>>ݺu;xð ½=6lØÐ»woww÷ÌÌÌ;wîŒ1bĈƒ š={vYYÙÁƒ»uëæããÓ©S§ZJ=ïðˆÓˆD ùž‰œ.@At óB€ˆc%Š‘¬Ðu¦‘úÓ]A±D ;lÀ0LJJ 6ÝŸ ]nüϘ ‚U×@†ÀÊž‰[€†ŽrÆÒ ØKcyø ® ¦8'fhÃÚìÙ³}}} !©©©_}õÕèÑ£þùç=z”——߸qƒâááñÊ+¯üòË/½{÷†÷B¼½½[µjuëÖ­„„Bˆµµ5]c8//¯yóæ .Ôëõ¯¼òÊž={¦M›öT¨‹ÅâC‡Áçm۶ݽ{×ÓÓóرc@Ù{ôèÑ·o_FƒÌÒßß¿¸¸¸   °°ðöíÛ­[·nÒ¤ÉÅ‹­¬¬°][}°œ}ûö¥¥¥Uÿ*55uÓ¦M›7o4h$ÏgeeéõúC‡­^½zÉ’%ƒ^²dɼyóæÌ™Ó±cÇèèèíÛ·×ënøì³Ïúõë§V«¿ùæ›O>ù$>>ÞÒÒÒÙÙ911qüøñÖÖÖÉÉÉþù',1„–””tñâEBHÛ¶m‡ Ö;xÖ¬Y/¿üòÞ½{ƒ‚‚>þøcl“SZZºhÑ¢9sæÌ›7¯sçÎK–,y饗’’’²²²þüóOÿ·Þzëã?4hÐæÍ›G5kÖ,‹ eK¥RlÏLw¦Á>žX¯ŒÎŒ;¡ú'–Ô¤}þ¨g� g>FK mR"‘Às (ñe�ºr>,†e0ÍU4a3¨[Šhe€¬nÞƒÒ=ò6T˜pŒµ[´žÜ⊆2ºrè3Ë ÕµDµzF*­Ñ{kL}ÂUOü¤•9ŒT¬m Oø²3gÎÌŸ?ÿ£>š?~HHÈìÙ³yž/(( IIIY±bE\\œƒƒÃO?ý4þ|‡³gÏΘ1#''gæÌ™.\pppXºtéÆñ/¿üòòåËwïÞ½xñâW^yåÕW_}æÅØ´iSttô—_~)‹ÃÂÂX–}øðaHHÈ¥K—"##wìØáàà°k×®9sædffߺu‹a˜Ù³g?~ÜÁÁá“O>‰‹‹«/–.-_¾é )ÃñãÇCBB>øàƒcÇŽ%%%}þùç³gÏ>tèÐ/¿üžžžœ››»páÂùóç;v ygppðýû÷AXXÊf0ÀŽ8´Ý ­±††#:"MRÈôC`1V¾Á8hàÂæoH|é jFœÙM"éºj … eD] cÞè^8Èä虤*q˜ÖÄbktk «q™*xÂ6Œ²Ã‘>®Ï“�S €ëÐφm0'ÿ OÎrŒ ú£jŸŸ™»+V 2$88þMIIùóÏ?·nÝúý÷ßûùùõéÓçÚµkyyyZ­öúõëcÇŽmÙ²å™3gÆŽÛµk×Ó§O—””œ={ÖÍÍÍÛÛ[¯×Ÿ?Þèù¾¾¾AAA×®]«^ ø áÇ\²dÉW_}5dȬ¬¬ÜÜÜáÇ<8##ãÎ;Gutt;v¬““Èôôô6mÚ¼õÖ[÷îÝcÇŽå8î6ª<9deeåää¨ÕjF“™™™››Kquu2eŠ‹‹ËÑ£Góóóÿúë¯~ýúM™2…þá½{÷ÒÓÓ{÷îýꫯæåå]»vÍ<™&~²/±Ö/f±@6tŒcvú�DU�B}ˆ.èI÷“¦¯`·Pdu€ŒN§ƒŒä…t+RÍ5yE„°ª …B¹\/¥‹@‹Åbq•φ§Ü90p`±F èÐÉgî—Ó˜†µyóæamÆ „„„„víÚååå………mzB®pæÌ™.]º`9,ggg•JU^^^ZZú Ø———§¤¤8::V²žv&oݺձcÇ BÚ´i“™™©V«åry“&MŒn®1:kåÊ•vvvýúõƒæ@f0 …–––mEwù¤Ka"•ö�< 40ÍÁ=Ðó2{°M>„…œ¡¡VÞÄ‚Íð@T¹°l0ºÉ4¨ NNN%%%àÂÁØ�-i `œ¨2€ò``ôÃLR/ä ¡ÿ8–C§¸¢“©Få9½‘!ëÙÄ£ÇÒo¯n«n¬±Ñ5}ÑèÊ“˜ÚèGÑŒ†ž…åÔ?ÿüó™3g°Ïü¿Þúí·ßÒÄ(;;ûÈ‘#ÿ%cƒeÙO>ùäÂ… _ýµ‹‹ËsDŽ9’““cRlòÚµk7nŒ‹‹C cáÂ…„©wíÚUýbTTÔÿýßÿmݺµ]»v;–K—.%&&>§½ëúõëý èêd¨:�KÀŠœ„ªÝI—·12Ó£Q™íºÇ+X‡.¢ƒ±gt[x0$#ÊES[ôÇ ¹‰Îj42”!‹ªN%ñ¥Ø*G]c¥¦M›N:µºï„æ4Õ㻪ßV÷ÔßE3`2Ý6ü3Ö¹?Jõþ+_©å+~@^ޝ«3–ãååuàÀˆˆWWWŸØØØâââï´··Ÿ>}úîÝ»ÓÓÓÏŸ?¿iÓ&üJ&“ýñÇG•J¥}ûö}íµ×ž ƒÁðÍ7ß´oßþË/¿„+mÚ´éÓ§Ï‚ Ôjµ——W¯^½.\¸páÂÉ“'§¤¤� 5عsçÑ£G“’’F·{÷î®]»¾óÎ;ååå—.]š<yòµk×f̘áêê:cÆŒ½{÷fee‰D¢éÓ§7.Ú]»v…å9r$}ÝÝÝ}äÈ‘k׮ݲeK~~þqË=,\¸pîܹ“'O¾xñ",ñ©S§¢££½¼¼fÍšµÿ~ˆs™1c†­­í¡C‡BCC‹ŠŠ|||ºvíºpᘘ˜É“'gdd¬ZµêEe9;v|áKiÔ-Ü»wÏ(ÓÒÒ²_¿~æ™yr¸|ù²µµu ì šÉ«Tªýû÷Ó¤D£Ñäåå5kÖ šÈ–––µjÕ " *++ …L&~£P(Z´h‘ŸŸ¯Õj]]]‹‹‹KJJZ·n­Ñh �Z,dŠŠŠÀžfeeÝbžVå¼yó&}ÅÖÖÖ`0@ã[[[–eoß¾ ߺººêtºû÷ï;::J¥Òœœ{{{;;»Û·oËd2º_Î¥K—:vìhmm]W© eee………...ïRPP R©Ú´i³Š³GÉÉÉkµ£££………R©„Ù‰DFÅùÿ#8p`ܸqX} Æå&„Èåò–-[¨Õjggç{÷î©Õjkkë.]ºÌ™3'((ˆ^nBˆ………Qç¡Ã‡¿õÖ[õ— Êqöõ‚ýYRRR\\ŒËMÏÞýû÷¡È,½^¯—È+ÏfýàyþðáÃ>>>&X} ¸¸877·wïÞºšÒÍP XYY%!„$$$Œ=ºaJu¼H�ît:••UEEÅáǃƒƒ«åÈd2ÚBbkkkkk‹ÿBç+øL7NFrcooooo4èq––;Ê<9‚ŸŒˆrGß#‰ð_ü`Ô™¦>ÀÆÆ†î*†Í*©Öô¥–Ù«[ø×å&„¤¤¤Lœ8qܸq;w¶··wuu­¾Ü B¡ÐhŠììì`OÒË `ÔaH,7º°^Ö[M›áÉù Øu*++Ísø´PcQsl†žzôè±víZ¥RyñâÅ¥K—úùù™çÄ f0ÃS¹ÆÚcáÌ™3OR üâž8pàÀ§ý•Z­þã?Ì;Ê f0ƒ™åÔ�ÚÑ¿ÿ»?`ÃŒº<øÅÞ0æSc3˜YÎ3«¼ðýhŸMÑyZ:tè \F€eY“í\`3˜(Ë/p1]3˜Á f0ƒ ±žç±j–Ì`3˜Á u–––˜çôÃZ=%‹œ7n"–c2µ3YÄŒ�+BþÏn¡ZfKȘ@{$œ:_SS>¡ORѹ!‘±²²ú»Iýµµµ……Å)wú `0JJJ,,,,--IãyPÊËˡڒ¥¥eÏ@íPQQ%­¬¬°¦¡ BQQ‘\.—H$r¹¼'P«ÕVVVÊd2kkk“Z;€’’‘HTPPpîܹó±š4iÒ£G…BA—Å4(((°´´4AÄŒ@©Têt:©Tjmmm '´´´ªÕ5<1¯eeeÀÂÂiÃôz};BËÊÊ®\¹2`À�ÒPí!55ÕÑÑÑÙÙ™eY¥Ri::55µiÓ¦­Zµ2 &…˜œ9s¦ÿþP!ñ ë½ÖÜ¿ÿÞ½{={öäyÞ§èüùó=zô „´nݺgÏž¦¦âXXXÀ¹S©Tµôn``Yö?þ€ByjµÚ% „ôôt©TÚ¾}{!III:ujÚ´iÃóêpñâÅvíÚÑyåæTP3˜Á f0C™å˜Á f0ƒž=/çôéÓ¨µõíÛ711±mÛ¶5Öºo())IJJêÞ½ûõë×e2Y¯^½RSS‹‹‹‡ Ò09rÄÙÙ¹K—.¾¨.\(--mÙ²e·nÝLsÛUTT¨Õê¦M›¢‡óÁƒàŒ1ŸÉgXnƒÁàééi È\¼xQ£Ñôïßß”gì¹@²aàÖ­[ÙÙÙ Ëå5ÞððáÔ”ê}³TËÙ»wï”)S’«àáǾ¾¾5¶Qi0HOO÷õõ={öìÕ«W³³³ !kÖ¬™4iRƒ!œœ|çÎFßC¿ÿþû¤I“.\¸““c²=77÷Â… ´O¸´´ÔœMùl°hÑ¢ððpA&::››,dgg_½zÕ¼s!ûöíóõõ}ðàA-ìÙ××7%%¥1µœýû÷GDDñ<ß¹sçŸ~úéí·ßÆo§OŸuìçÎkÔs¢Nàúõë‘‘‘„±X¼mÛ6BȆ ’’’>øà¸!##£I“&û÷ïOLL¬¬¬\±bżyóê‡S§NÅÅÅEGG·oßþĉ7n\¶løù !@î§M›æéé0|øð€€€Ù³g[[[/Z´hýúõ—/_þî»ïê|rNŸ>v÷îÝÒÒRKKËqãÆEGG/^¼xРA Ã@ÞÕk¯½6iÒ¤ ÁL.[¶ šNŸ>}À€×®][ºt)!D¡PÔ’jµ:==ÝÕÕµY³fååå‰äöíÛ>ìÒ¥KzzzëÖ­a>늊Šf̘Ÿ›5k¶víÚ~øaÿþý„OOÏ™3gB¡bBTT”B¡8xð T*=r䈫«ë°aÃ6nÜH‰¯§iYµjÕåË— !¾¾¾o¿ýöƒfÍš_}÷Ýw …bÇŽ$„ôïßÿ£>ÂnÞ¼ùÈ‘#„!C†5 ¯C[ömŠ‹‹³±±ùé§Ÿöì٦ēb„dTT”J¥òööƃS·ˆÍ˜1ÃÅÅ¥C‡»víÂýl„$\÷óó»yófaaaÃ#I¹|ùòªU«fϞݶmÛéÓ§3æwÞ™:uª››[hhèŠ+®\¹Bñóó9rd~~~HHüpË–-õ×ô¨²²rܸqo¿ý¶¯¯oYYÙ´iÓàzll,ÞH:99íÙ³ç›o¾�ãÒr†êîînaa1mÚ´›7o&$$`„ÒôéÓOœ8Ó¶mÛwÞyz®Ô!°,;lØ0‡˜˜˜ÌÌÌñãÇoÛ¶mÙ²e&L@ÙêôéÓ.\ ‘¬ó*..þã?nܸ¡×ëÓÒÒΟ?¯V«®^½¹uëÖ˜˜˜Þ½{O˜0!333))éâÅ‹jµS*•þù'Д:‡^½z 4ˆš———0lذ”””¯¿þ:66öÃ?œ<yò¢E‹~þùçÓ§OÏ™3'&&F.—1"&&ÆÃÃÃßß?--mĈ-Z´ˆ‰‰III ª?–síÚµ&Mš$''—••”——WTTdffÚÛÛ'''×G‡[[Û˜˜˜èèè«W¯&$$Ì™3Ç××788xùòå›7oHKK‹‰‰iÖ¬Ù›o¾YTT´téR­V³uëÖƒÆÄÄܽ{wôèÑõ1'ëׯ‰‰ùðÃß}÷ÝåË—_¼xÑÛÛ›Ã0Ì”)SŽ?¾fÍšÀÀÀ™3g.[¶ ¤.Bȯ¿þºpá   ©S§FEEýôÓOõÞÈ‘#u:]LLŒL&›<yòÑ£GÃÂÂF¶råÊo¿ýn;xð`DD„ŸŸ"™˜˜¸yóæiÓ¦¥¦¦ÖGXשS§bbb,XššêååHªTª·Þz ‘üðÃnÞ¼yáÂ…Ó§O׈äöíÛOœ8áàà0lذú“+//?{ölff¦J¥JHH¸~ýzqqñÉ“'oß¾½fÍš5kÖDEE½ýöÛÑÑÑÉÉÉo¾ù¦N§ûä“O!õ$C�„††Â"=zô­·ÞR©T111:Žî vâĉuëÖ•––VTTŒ5ªA k2™L ÐrÐ<¢ÕjSRRòóóKJJê#沸¸Ì‹jµº¨¨H¥R©Õj''§5kÖ<!’ÿ|||üüüÞ{ォW¯.Z´hñâÅ]»vÅ-¥ÓéRRRîܹSVV& ¿ÿþûíÛ·ïÛ·¥•ƒîܹ³>¶Ž\.W(„lDäææ–––véÒ¥mÛ¶)•ÊŒŒ •JmÊ***åryqq±£££••UYY™Á`(..~ðàÌðãú½Ö xxx@Gz£}×úÚÖ0 ãèè/öìÙ£Ñh”J¥½½}“&M4J¥*..†{  _­V‹D"GGG½^¯×ëE"Q‹S�-Z´:tè‡~haaß«W¯¢¢"h!¸cÇŽ;v :tÇŽÇ¥§§«ÕjXJ@R¥RefffddÐ×ë\G”J¥ŽŽŽ›7oÞµk—V«U*•vvvM›6…™„ÛèYEdärypppzzzžÿ;X[[GGG§§§3 SZZš’’R^^^\\ŒH‚zŠP#’mÛ¶ŠŠ‚CQH8pÆŒ}ôÑÇáÊ´iÓ$ɺuë***t:]³fÍ|}}/\¸àáááááQ\\@·T®sظq£R©ÔjµÅÅÅååå)))اaÀ€S§N•J¥ÿeó×}YOü;uê4þ|Ød�€�� �IDAT ‹zÚ÷iiiþþþNNNåååb6lØo¿ý¶yófwwwȺ !--­eË–óçÏoÖ¬Yã6\ºt©P(¼|ùrHHHu<………iii'N4jäúb@ffæ¹sç"""žÙ8P0zôèÑ£G¯X±ÂÏÏoÀ€k×®5º!===88ØÍÍ d #¸q㆓“ÓüùóŸ|­ \\\¦NZÏwwwGÕ³¢¢"--íÍ7ß„.·Ï)|ûí·×®] ñóóûä“Oh#j½Ìž——W}𺒶´´ wuuMJJª§ =zô/((¸ví\ÑjµQQQ5ÞœššZf÷×^{­eË–Û¶mëÞ½»‘ËJ „‡‡wïÞ=))I¥R¹¹¹~ùå—³gÏ;vì¶mÛfÍšeÔž²¾áÊ•+—/_xB]xxøÝ»w333ë«FqáN:µM›6õ$kÿGعsçØ±c'Nœ8{öìÓ§OcmfÍšuíÚµ¤¤¤÷Þ{¯ÆÐ˜÷ß̘1III(D׬X±:&íÛ·7 àˆˆˆ0©¢W¯^«V­Ú¹s'Çq)))+V¬ o8þüرcÓÒÒ9²nݺ.]º µ mÛ¶ááá<ϧ¦¦Ò×/\¸ð믿þLJ?£–cooß²eKBˆ•••³³³X,vvv¶¶¶Ž‹‹{ûí·‡ ¢R©"##ë\Ä`fïÞ½aaaC† Q*•GŽ‘J¥YYY¡¡¡sçÎ ‘ËåÍ›7·óÚµkÇŒ³yóæeË–ÕÇÂìÚµkÒ¤I`i%„8;;ÛÚÚ†„„äææ2D£ÑLŸ>½eË–"‘¨gϞǎëÙ³gqq±J¥êÓ§O"j€­­­³³³@ P(ÎÎΉ„2vìØŒŒŒ™3gº¹¹}þùç_}õ•F£qqq!„ØÙÙ999¬àììleeµk×®ùóçŸ={V§ÓýöÛoõ$4Ñqrrú믿ºuëfkk+—ËÅb±@ €`M‘H$—Ëë£H”^¯/**ºtéÒèÑ£[´h±yóæÙ³gÏŸ?_(Lœ8qüøñ^^^°ÁvïÞmaaáìì â,1ùg³óºooï#GŽøúúêõúÅ‹÷ïßß¾}C† )++Û»wo³fÍBBBæÎÛºuë 6¬[·N«Õ¶nÝúwÞ‰˜âéé å<êöîÝ;nܸ!C†”——ïܹÓÙÙyîܹ‹-bfüøñ|ðÁ_ýe0FŒH …    &œ;wîqa¸uŽŽŽÅû8$—/_ž@iÚ´iíHÂ!ª?‚Þ©S§«W¯¾þúëYYY2™ ÜCCCoÞ¼éãã£ÓéÆçææ2iÒ¤={ö¨ÕêÔ2@À†‘ÉdÎÎÎr¹|Ïž=cÇŽ…Ù‹¿wïž³³34pww¿{÷î­[· `äÙ@ЫW¯³gϪTªýû÷¿ýöÛ‰¤± ÞXZZ6bÁ›ääd(x#—ËMªhJJJ ¼15ÄŒàØ±cýû÷·²²b¦± ÞXYY5®³F8uêT=”J% iR¸aÁ…B¡ÑhLªàÍáÇß|óM…B¡Õjÿ‹'???ÿâÅ‹¯¼òŠJ¥rwwŠŠ¢#ëþ;`Á,Ô¸pîÜ9(xS·Ä¼cÇŽ¯¼òÊöíÛŸêW‰‰‰íÚµkÛ¶mEEÅáǃƒƒÍ-ÚÌ`3¼ÈPQQ·gÏ;;»Î;›HÎìÿ,˜YŽÌ`†:tè°víZH•›0a‚É–ä0qøî»ïèêœf–c3˜Á 5C»víÚµkgž‡ÿuåUWBïÞ½Û#¡rssËš\VVæèèHQ*•·oß6•.++ƒh•JeRˆZKJJ òÕ¥¥¥ðeYœ"ôÀ …B±XlR¸ÑyyyPsÁ€¦yyy ì|*(..†�TFc ÛÝ™ OÌkA¦f–íFÞÛºukBˆN§«¨¨h,–Ó¤IkkkžçU*•I¹ lllL±ê‹(‰ eHã ™›„­Vk‚Säââ"•J…B¡H$2ÁÖ®:Ž¢×ë+++MвwêÔ «¨¨0e–cccãààÀó¼Z­6…íײeK…BÑXÄÜ’{þ±F—70ƒÌ`3˜á¿„’Ö±VXXxòäÉú+W‡Ö�wwwÈjܵ,Ë‚aÐÒÒÒô;´×¨óÊår‘è×¥§×ëA‚nô½Tƒ²±±1¸çz…ÊÊJžçÓÒÒ²³³_°ý, ÿïÿþ¯I“&–––ÏÝÕh4FŒ kÎÎÎ}ûö5ñaH¥Ržçu:Çq_\\œ‘‘áéé)LÙêUxžÿí·ß¼½½J¥2åF¿õ ·oß®¨¨x饗xž¾V°ÈÊÊâyÞÍÍã¸fPµiX–íÕ«ä8¿0 —ˡޠÁ`¨§Òyõ—C×0w5ƒÌ`34”Òfž3˜Á f0ƒ©³–e¯_¿^TTtÿþ}ºø ÉÂíÛ·ïÝ»g^òòóóŸ‹}ø´pëÖ­üüüxÇqp¢ñJIIÉõë× Cõ›ïÝ»gÊ!ûÿîÞ½k M~îß¿_Küì,§¼¼¼wïÞ±±±{öìùòË/MGŽiú-rÍðÌ0oÞ¼W_}õÅ׫¯¾Zçmmk„ÊÊÊÞ½{¯_¿¯œ?~ÕªU5ö ~±\·oß¾eË–ÿå6|øð:l„vØØØ4iÒ$33sÛ¶mþþþ{÷îurrzÿý÷ !+V¬�÷~```‡ÒÒÒ €ƒƒChhè¡C‡Îœ93}úôØØXooï«}´cÇèzðÚk¯AÞÕ«W¿þúë·oß.,,œ={v}#ðÓO?eeeùùùmÚ´iܸqݺuËÎΆýmii9oÞ¼'N;v,"""//oûöíŽŽŽ€äàÁƒ—-[^ĉ'ÚÚÚ~ñÅÇÏÈȨ¬¬lžúé§ŸBö¥¿¿§N222 ØßôéÓO:Õ´iÓ“'O.X°àæÍ›ñññˆ$üvñâÅééé»víš2eʦM›ºwï.‘H !½zõòññÁ·üúë¯ÉÉÉS¦L‰‹‹{÷ÝwÏœ9¦cÆŒqww¿uëô ”Éd‘‘‘üñÇ_ý¥V«·lÙØ�“——mz…Batt4!ä—_~INNvuuíÖ­›B¡8yò¤¥¥åäÉ“a¹ÉÇB:tèøÃ?äää¼óÎ;xp€¸¸¹¹¥§§ÿý÷ 3#ˆ¿yóæ‚  E³f͆ÓM±¶¶ž;wîï¿ÿž••UZZúÃ?øùùmÙ²%;;›2lذÑ{rðàÁµ,wllì¨Q£`&BÞ}÷]é¡C‡:uê´mÛ6Nçíí–––““ãááñî»ïÚÙÙ †‹/þú므XŸ>}èn˜¿üòKß¾}á1cÆœ<yòáÇýû÷>|¸F£-A™={vaaá–-[ÆߪU«+V :´d£;wîÄÅÅÁgWW×)S¦ìÚµ š׈¤ÝÉ“'=Jqss£»œüþûïÇ'„tíÚÕÏϯѴzÙ6oÞœ››ÔªU«Å‹ÇÇÇ/^¼xÇŽÞÞÞEEEÙÙÙ“'OV«ÕÞÞÞ±±±«W¯>{ölll¬ŸŸ_ll,ÝÖ¢¾ÓâÅ‹!èpÖ¬YIII“&Mº|ùò¹sç–,Y²cÇŽÀáèÑ£k×®ýâ‹/ÔjõäÉ“³³³‹ŠŠ¼½½wìØ±xñ⤤¤ØØX¥RyëÖ­ØØØÜÜÜŠŠŠØØØäääÈÈÈüÑÛÛûÁƒ&L¸wï^llìÌ™3£££ë£-PuX¶lÙ·ß~ëíí]^^”T^^ž””äççwèСÄÄÄØØX­V{ýúõØØØ¼¼¼ÀÀÀ«W¯z{{Ÿ>}ú£>ÊÌÌŒ}ÿý÷¿üòËùóçÏ™3§}ûö;wž7oÝ+áäÉ“6l?~|llìÔ©S¿øâ oooƒÁ0eÊ”ìì쀀€û÷ï{{{ÿüóÏóçÏo×®]‹-ÄbqŸ>}f#ùùùݾ}ÛÛÛûСC¡¡¡˜?~ÇŽ?ùä“3fdffÆÇÇC÷£G~ûí·©©©ü±ÍÀ—,Y²uëÖC‡ÅÄÄÁÁÙ²e‹··wII Ìêĉ•J%4‹lH~óóÏ?«Tªü122299966öîÝ»AAA%%%ÞÞÞ[¶lYºtiÇŽ›5k&—Ë{öì¹uëÖ%K– 8ÐÆÆæã?NMM…å>~ü8ìÉÚ—{×®]‹/ööö¾qㆿ¿¿··7ÏóS§Nm«ÝÙ³g¬P(f̘akkÛ­[·ùóç8pà—_~Ù¹sgzz:ШŽ;Î;$€ãÇO˜0÷d»ví\]]gÏž}êÔ©éÓ§Ÿ={ÖÛÛûÊ•+AAAwî܉½yó¦Z­Ž½páB ÍÖÖÖÛÛÛÛÛû·ß~Û½{÷Þ½{,Xн{÷Ç!™œœ<kÖ,;;»~ýúEEE!%üóÏ?ƒƒƒ›7oÞ§OŸÈÈÈÿÞ༎Ã"""\\\|çÎk×®±,ëàà —ËÓÓÓííí÷íÛ7iÒ$­V›••?iÖ¬Ù½{÷&OžÜ0'êÎ;ÅÅŽzõêÔ©Ó;wJKK¯\¹booÞ=» Å_|áêêš™™©T*ÓÓÓœœ<==…B!t=yã7h­vøðáÇŸ9sfzz:Çq0«W¯^…àf¥RùÓO?:uª0¯¨¨°¶¶þì³Ï¦Nºoß>KKËŒŒ —ýû÷?ÎU¶cÇŽèèh‘H„²EyyùÍ›7çÍ›—ŸŸocccccSPPP½RN»ví æ¿F£ñôôlÓ¦Mvv¶R©„¾«žžžb±øêÕ«NNNMš4‰D]ºti˜Ôjµ©©©‰‰‰›6mZ±bE~~þƒz÷î½}ûö]J/½ôÒÁƒGŒaoo_ZZš››Ká8®wïÞ÷îÝkÕª•Á`pppP(×®]S*•™™™­Zµúì³Ï¸¯å¨Q£†IOO‡+ÇqwâĉÌÌÌŸþyîܹ...¶¶¶R©ÔÍÍ-77·´´´OŸ>;vÌÉÉ^$Mš4™7ovgÇå¾|ùò¡C‡úöíK/÷7<==›7o~åÊOO϶mÛ^¿~½Á¢ÓÒÒz÷îݾ}û[·n¹ºº¾üòË<0rž­Zµêå—_®¾?ÓÒÒpOº¹¹uíÚõÞ½{………_~ùåºuë¤Ré•+W ´zõêàà`€€€°£B¬¬¬<==wíÚ%•J÷îÝ«Ñhìíí-Z4`À€ß~û­ÿþW®\±±±ñôôüå—_âãã_~ù僾ùæ›ööö%%%èÇ*..¾{÷®•••]qqq^^^ãÖhH$tFdEEELL !Ä××—eÙÏ>ûìÂ… :u¢K9mݺµ^{7=!ˆÅb†aìu –”[@†.ò¡Õj† ]eee8«peÖ¬Y –MµråÊŠŠŠ÷ßÀ€Ó§OGYA*•>.6>>þ«¯¾ú¿ÿû¿¼¼<,F»qãFè ïàààëëkT{Q(nÞ¼™ÒK󄘘øÇ„„„,[¶Œý ™UuxøðadddAAÝÞÍÞÞZM3 £T*qYqo4|^võƒ`gg—˜˜xðàÁ¹sçVVVnß¾ýI*<ŠÅbºº,÷­[·BCCE"‘ .h-ð¸5­Åð³`Á‚Áƒƒ`Í0L¿~ý\\\nܸñî»ï6X½ìììÌÌÌM›6I¥R_____ßÈÈHOOÏ×^{íóÏ?§‰6!$??áÂ…………PÑÑöìÙÓ¢E __ßÎ;›––cöööqqq>>>¶¶¶EEEß|óO\\œ)ð#8|ø0*^ �\°¥&%%­\¹òüùó"‘Èßß¾jÒ¤I\\ܨQ£ê¤–øÓÂŽ;Ö®]»~ýú×_=66¶¬¬ ®oÙ²…NË-..þá‡àóŠ+z÷îסC‡Ÿ MApþïÇŒ¶~ÔDDD€ÓÂÑÑqÕªUp‘eÙ¯¾úоíôéÓÐÍ733ó×_ýàƒèÓNƒ x­lmm‘yoÚ´©Ñ³ÿ*++#""$ÉgŸ}Æó<=À«W¯ž8q¢Æ_<xðæÍ›FÏŸ?òäɹsç.X°€¼¸°bÅ 77·¸¸8èÈ—Ò­[·Y³fÍœ9ü% `Î uvv†òƒgÏžˆˆøðçL™rìØ±¤¤$¼ó‡~XºtizzúÞ½{§M›¶zõêêO›1cÆÊ•+mmmŸ–û6(Ë‰ŽŽÖét^^^¡¡¡­ZµjÕªÕ‚ ¾ûî;//¯•+Wž<yr÷îÝ ¿Æß·o_??¿¨¨(ÿÞ½{¯[·îܹsW®\©¿îÂ5Ê€ß}÷Ý‚ :tè°lÙ²üÑËËK§ÓOÏËË‹’‘‘1uêÔ´´4†aÞxã BÄxyy………µiÓ¦á+¿òÊ+ñññS¦L¹víZTTT‡¢¢¢¶oß.‰€aöìÙ3""Ý*ëׯ?yò¤———¿¿ÿÇ?ýôS|Ú믿‘„ï½÷^NNN›6mj|iXX˜“““——W\\\xxx‡>ýôÓÝ»w{yy•––®\¹’2þ| ‹µk×6Œm­[·n+V¬¨¨¨X³fÍÈ‘#_ýõY³f 8Gý×_8qZ»»»Oš4iùòå'N„å>wî>-** =$$ÄÙÙÙÅÅ%22rË–-R©„ÐÆ•ñCBBÖ¬Y£P(�U8Ýß~ûíŠ+zöì9f̘åË—Oš4ÉÝÝ–;++ ;CW_îÏ?ÿ<88xýúõwð‚Áºuë._¾ìåå5`À� ‹€€€ . 6, 77÷âÅ‹ €CAAÁ™3g.]ºäççÖ®]»ëׯ7îôéÓï¾ûîàÁƒÉÈÈÈž={öìÙ300péÒ¥Ó¦M‹ŽŽþþûï!Ê£oß¾ãÇŒŒ|çwÒÒÒÜÜÜþ«‡.ëÙ·oß7n<¹‰F«ÕŠD"žç9މDz½Ú×ët:Ðu:-›ã8¨·#‘H ~í³™°àÍSõ®Öét@,ëõz(<HfffŠD¢Ö­[;öÆÔñ„€ožªòäÉ“=zëÖ-˜1zf’ažçéë8«ôl?ÕbÁ›ghô[㲊ÅâN:A«Z@ØhKÀýƒþ-!Ä`0ÀÛ†¡«c ŽãpÔ¸jO2cO>,xó´M¬aÒ�Â)))À}}}ÁJ°,k0ÌLuäkœUƒÁ�U¨Ÿ7,x󴃄E"̤P(4 ‰„çùÄŒTFF†D"quu5jÔÇÏŸ?û—[(ÂÃIUO\n˜%#ý¿¼IMMµ··ò‚7€ŒT*ÅÙÆ#€ñÒ­:Â0K0Rðmøg;­XðF*•>¹Ê‹û“ža£ƒ†˜íÇíO¸^ý„>¡ý¹.Qq‹êh#M(6¢‘‘1"I6l¸råÊ”)Sîß¿ºEÃ�=ôçEØhVq&‡<"ü¯[èTûØè¢Ñ$Ô>c �Õ½qÕGatÃ0Hkþy`Cªú2Â5º·?cbbnÞ¼ôàÁƒáÇ­½Ü4å¥/6˜§‘©Nš‡Ç-Yu„éYz܆o°ÓZãþ4Ú¢O¸?ëvEÌ]AÉòåËüñG•J5qâDô—Ô+øùùÕU‹=“‚E‹áøZ·nýé§Ÿ‚ÿV¯^½k×.•J5eÊ”FÉ+2ƒ)ƒ™åÈ×kÈ7:ô…œIÈÿý‡æÍ›7ðv25°±±ùŸ3<Ë …¦¿(À<j0Š‹‹Œ×"„4.&O tã²²24ûþ¯úY–}¾V°P©TÚè¤Á�Û=ìiÉ|ÐétÏÝjVomþ–#“ÉM¿Eœ%BHyy9”®i\©–¢×ë“§ð² †7n4nÛ¡Æ胮T*Ÿ»¬ÀÂYQQñ" ªhÑ¢!ÄÞÞ¾NBíM“¡?w«)‰ŒâªÿŽX;pàÀ˜1cÌzŸÌ`3˜¡nO kÇ5J¢ŒÌ`3˜ákkë~ýú=b?xU(Ž7îùÉŸþ9bÄ6ÇPzŽã†_˲3ÿ2 ò,ÄÎCÚÃ0Šö_©Tª×ëY–û)Çq�\G·)ð@‘HTr¸D1X!•JmllZ¶lYXXXPPÀqœº»Zà/Ï‘Ãc±û7še…B!t–Åyxä@Ö‚®‰Ný…ÚÂςҬY³—_~ùÞ½{™™™ƒA?JϹrÒuRÈpô¸ £ U¬0|¼G£Ñð</“É‘H¶JŽã¤R)¤e V€ü~Â0Œ^¯GlÅb1ÇqpW°‚ÙÃüžç!é„aLÔ�ô„B!DvjµZÌØ€_°@€?¦À0±ª dä@ò¼‘çy\wø ‹7C’dK�’ð.Èúüq�&¸…àN‰D×a#á&Äá 0‡k k·Á à|ò<ϲ,ú!ཤ*5&¯C6 ,%\dYV$Áp ÌìdX_¸÷<¼]¯×ë7\n&, ¼Z$Á“a€€9~ .}'Þ, % Ž † §R¯×ÃRÂW0¨ö$`¤€3<"ð”>ð-î7Ø9B¡Pè"äšq"‘ˆ/âÉ-O@œá±š5Ò<©x¯˜a;;;½^_ZZj0\8n•V[É0S¥RƒÁ ‰Ü‚µJå÷É E¹NgøØ +–Ù¶›0a‚¯¯¯……EJJJtttnnnéw¥L#Ì{´ùa¼0‡ƒF{�Öv –ŒçùYC„Vk™œLÜÝ !$#ƒôéCæÌ! š2¡fYóÞûˆ5š^`^*�œˆ‹‡,-¤;pŒ‘ÀÖjµ®À p�Äb±H$ÒjµðL< B¡Pœ(æðìy¶¸¸¸¢¢âQN¥€û ™?ÿ&"p3¼1dð zÛà� Ô——gee•——?ºNx!ó(=f�2F!;.Âø Î!¤˜uˆ¬i˲À±±@†€ôfžL ‚$ É|S ¸±U@“9X&äa˜  /‚…¦9í(†Ü7¸‚Ì’ã8XJüì@ñA¿…ÉìþâÀa«Áx‘ßàudT¸Rƒ–©3ð0Àf y$ ¦¶7lc V˜Ü܉ŒZ"‘TVV¢8S B¬>L 3šÛ&(ŠÁÂca)°1œ ”ðPòÀõ‚í³Š<ÀÇ";Á¤&x£^¯—ÉdÈÒª/n`Ø3(¸ ¡Ðàk8 M Z¢”˜\FtHdÈ{Ä€ôz½8F¬:¡²>`­Õj<x�sNéë©ÿ#]¸Yg%4€A¦èõÊd¾ƒË–ñ<˱ZV©T&&&¶iÓÆÖÖöÔ©S………*•ÊÀ„¼ãèI y<¬¸^¯©NŒb­H4bøð¾£F‘­[‰XLüýIx¸‰óc#ÛóÎr`‘É& ì0¤(!b@ ²ŒlÁK‹Gv9¦I#)Çxž—'ª™³ !D­V<Ãë|t–¯Y² �™`‚d©MžP¬fF |DƒT*Õ;whþJ8‚íi pÃ3 ô ° ƒÅYBÖ×Dc¤×Àwéó 7 ÎH»éƒDª"ˆôz=êšH#!&€?0{šuÑ¢+ZdB(Ìâoá™t8þŸL“'x2KØ60p Ë8(äÇ(òïpª‘ðÑ£B'µÔ!ð ì´FˆC‰D …ö9d¼ÃóaJ± �l ”s@÷ªk¸ÉqÕ°Ò½” µ�Ú(±á6ƒáët:@¶%\GA97ò˜ àp?ŽÓ3q_áðA2 i4rJ”±`ÂqŒxÜtá:æ6#Þ'_sǶf¹Áœv†Vþ‰\¨â2Á�%_HÔŸ©…ç„ÒR‘H¤k¡ÓÍÖí¸Ë¼“ÆÏR©>—Hà±m9ÎG¯·´,‰D„p'8ý½ò„2%%¥²²R*•Þ¿_­VóÃyÁŸ®‹UMÅý§ÅZ/”ã8ÝLמã8NºW*˜;—\½JΟ'GæÍ#Ï[<úsÏrhLLX*¶#b°ûi±H&“a©f$@x*à M”Lv¶uü%¨<Qiñ‘I'ŒÑÎÖê‡éeSd(#ÃÑ‚Wƒ¶„f@•Ž#D_(’""> 6Ä[Ä,Ë‚±K&“ñ-yn(§X©�QÍ ôXhb´�‰8JÜ€¸PاíH*• ¨Ètp‘&F<Ïk4 $4(ŸzÕ…P¬’‚â9 ÈȃÁÂO …¸ '?£Ö‚aàÈoÐ0ˆœ÷­EÒæ�� �IDAT‰Åb­V«V«Ñv‡J0Öü@U�Q *g ³ ‹ª‚1hN¡oÆñŠÃêÃÞF%^¯×ËårFC눴Ù•]”{€s0 âr”¢"…e‚€/‚5&æ”Ï`ê�[±X\YY Zr,P¹Ð:ìÞ‹sB›q6цJÚ!ö7zBınN%‰E2 ™Z­ænrÂBÍ! µBPÎp[2îÇz²Ç+!‚\â …á†á@…áØYÍgB¡ˆH­v¡LVÄ0 0¼4!ÂsÖœºX}ýúu—Z«ÖtÒt"ÒŠDâGNœaÀV­VÓ¥tÙ!¯¤Ö/ҋ׉E§D„'ì6¨[PÊ+)Ò¢JÂq¤¦ªÏf–Sï€äþiÀ#›O(@(£U\{\uÀQ»Ó ÂGbµŠ—+|'¨ÜPÉu䈀H?“Z®¶äyž<ò" j" 5 °ôñ�zx®à�?ÒôD”#ÒôÕ°ÝYæ #!ƒÁ k£ãÛðL)#|(Dq!< ­…`e¢o4CÞ€t!€�²=…B¢|@¹‰ rt Œ@s-,,°4œ1àøv4 ©Õj0dÁK±@ Ï¡V«…Ò^"äÄðv è€*ª€ÀN¤R)®#J!P\ ù:´h¡µ$F´ù·L&ƒßÒ…ì¿P\ U^T’P€v¨ã¤MgȘA€I£U4šj©q = (G¬8½Õa&á]h€Ei ·+<°E}6$ÐMµZ¼ð„ ‰Ì¹;ŠÈÝa' Ë $'Ä °(À~åƒ5‚ëªÝ*Ù;2¹\ÞµkWww÷Ë—/§¦¦j4Ë‘–Ê“J‹Á0‡ð|ÀV™ª”gÈÉ&‚ž7ðzƒþ7…b”N7eûjµ“¬¬´JåbYV$Ñý Ó©uüw<k`99§Yªm ÷ e–¼§0KpBa'ÀìÏCõ—´'ìxÖöu[4º¢ ›^ÙÔ¿oÿ$‡¤ç5zíyWq°ð-CÁvG2„}¤Î(ö¢�ˆv�#)‹¢ŒŒŠÚ ƒâCÅßæ ò·•Œ¶ Ñ® z(tÆO‰"ýx=y…ðo0ôÎz‘Adñ‰…5 !žTUTD“m.G¿:0<i«]™‘ùQÉCýhÌAC¥QȆF£Aêƒv-ÚvGϰ‘.‚³Jë@×PmB¼ý°phX£‹{¥]¨ÅÂÄtÚÃmZ­–ÖÏh'"Îês(Ñ1 ¸ßp›ÑšºU°|$©ª Ië ´ Ë_¡Œ÷£EŽÖá šàPß‚³_±,+“É@õ‡…S(:޶\ኣý (Êì4Í Fþ*œIä…‘LŸû§e#ÚCçå!RU^¾(ŽãÄ"±T*uww4hN§ËÌÌ„‘¢F-´½f„Ý ã˲³«ì«`³ÅE—ûËÙö¬v†–ÂUpV¯Z N¡P /BÛ)à‹…4 6ÈÎÈìììÚ´i#•Jóòòòóó…Bá2ä89>” 5³œ†,ƇÑS¸YaÇãΦÍâ°;$Á1JWÆóƒ‡I Šêà:Âñ‡thÒV¤FޤG(/žpØÑÖCŒì˜ŒËò2^À DDÒB©P"¤£tÐZˆÞÚ[€ ¡è+‚Nµ+?Ú!ld_‚#€ôÎ<<–‡ƒNt›£:Ese¤;èyÆ™DG+ ŒXÒ˜ö«ÓNfø-l‡‘ýÐ: ºh¢à‚HpÑÂiÛ†Ÿá¥·FK¸@1aŠP<¢Ë/ÒnH:NeY `3t°:/1¬^‡<Fa´g8޳±±±´´¼ÿ>î`t„ª÷aÄ{Po£702<œ˜Ud!´²‚«‡ x<+Zì —¹ñèPIÚ¤‰†\‚F£9wîÜÝ»woܸ¡R©ÐÏ„;÷?„¶‚ƒ2hîûeð<Ì-îÆG&ÜÛ"A¸�H“H,¢eœO[tRêÞ×9x9ÈšÊzöìéîî~áÂ…S§N1 @>'Ÿ›YNãh9´çE:ÌÉ%½–tà!ó c¢Ððw”šX §‘~2îP¦Æ]ˆ²§‘» ( Ó§Cc†MÏü€]§Ó %BôÁg…ŽœøFôR Âà1<ü4 0 ¨CüQ eD/`Ô´q ¤ª,<m·ùÛGU¥ÓEK$ùƒ_Ñ–n$^7H»ëi6Æ7¬„A(׃(Z‹ã¤Ñü›ÖcÀ …ÏAèJ¥ŽqçF{T!ÞÝ(¬�‡»,´M!_¤Õ2šƒâDÁæAË3ZÃV«Õ`m†©€ÉAž„ì¶fóS3ÁÃpð[ ¡CÁV?Ùƒ}˜m:" =èP?3²ÒQÑtŒ|¥S¨¿P“@’••uûömØi@µ^%›!CäiÒ¡P(hÁPäéåC® h€ ÄAšÒ9Fº2ìþÂëtºÒÒÒŒŒ Áƒ—””<ﵞ{–ƒÒʉhäY µo̶!U},Ðó‰òíí C§ÀÞ…Ò=¼,vem§LùF–( ÷Ä^ôF72»á)5Š@ÿ?X–ð'œfFÇÀ3•J%mçÁð3šÒÑL˨zP8`5. ºþ¶DSB+ðlx/*”F¯CÕ¾¥‡‰æ>¼=FHàØúIºap¤èTC* ñ©J¥N8ZW íF?"­Ãg`ƒ)pw¶´Š †5:æÂH­D^¼í½´¼"—Ë!Ð]ô€*hW°o‘‰ÂüTTTÀl‹•ÉdJ¥E"Úª†ÚÎ<½½QÍš çd#‘T*ÅEOäc!Ÿ@#ÞCwuÂÝÖ?TåA:¤…¹GFŽÛBÞÀëz꘻Œá¾A,³v,׎#ÂÜ`8á?Ìztð: ”ðF:”ûB!“�¶ ‘è TýPÐ; €89ØÅGx]¨sÕ ï“““ËËË;wî “™E²Ú‘vf–Ó8,vzQD!§àÅÅà1z7ÃaƒoiSn}¸6¦æ`2;a;&Ú:„Ö :ç�ÝxÅvŒ²\‘£ÐF? XÂ+Ìf¥™ rS£\E”ß‘C <‹×F¶):éNŠ:HRÐB›§Ðò#|EçHñ?: q ‚6šæHUö°^ä´vˆônFÝH*•ÒQÀ0hû*ÓèzÁˆš4£‰Ì( Ž¶Ú¡ß]´<îÌ‚† :Ë LÖÁ(Ú„KïFTÑ0úƒÎÒ1d| +檪¹ mÀÏ‘Èbø OZ®5²U@†ƒËJG^`²ž\Z¿Çõ¥e†a,",ÔsÕÜCNP"0 Äšš$+%"½H/УA^‹BG]¢¾‚[š¶Ã.3/>Ð7àŒ Óa&é”gÙ ™v¡V<Y¬V«ÓÓÓsrrôzýǼŒ,K"æðÆ�”^1Ú7”­hEãa°g%Šck€EÿíRF3Äé<Ad ¸é¨Gú„Ц$^F\ s¹ŒÔ(ЪÜ�c:Ñ îÁ+4ÍEŸ-Úß‘âÑ¢cÛÐ5‚< ©0:Ìa¶ "Œå$aâ…‘ÍUIš-ý·Z•_‚cé˜[8±h–T@ý.8ÿ˜ØøÓü›¶í BFÇ.#פÝô€ë@Ù‘QÈØð 0E4/§Õ,šÇ 'U©²F‘åh†}Nç»”––âÚÑÑáF«†[:±ŒÂp€ªâ”‚f‰§ L¦tî:°…ÖPéxb£`BŒ& É½°Hh5ßÊð²í̲,Ë_á%g$@  ¤B;Òèø£ü9\;Ph€Ç`ø;Ò<†ÀJ‘¡"òô{\˜B¡À RªX•,FF2‰Á`Pû¨£ZG- ̆µFc9¸@Фk]ÐiØB¡ä> ÏÅsK¨&Ç½Š¤ ¥~òÏüsZÊ&UóðÕ4_Aÿ$¯ŒŸ1š“6& E›N9Dê&—ËiÝy ¿H^øœÊÊJ:õ ^¤‰ètAómèCB"¡D"A*€„©*üjÒ,Œ˜ Ý˜Se”øI£Ò¨ž´bG—E¡PZ§µd«‘V¥Çi0ø- /jEÈj¥r–\®­’ÊÑ«‹Vq0˜ã8k`ŬX&æyžp„ðÿP²qGÑüÕÈÁNûíÐg4X°ô¢ZS=‘é8]InûMÇDÐA€ðRˆG¥]tå$ÐÂÂ"ð! fѱ$FyÙ¨ò¢lAÇ‘ca —G;ó#’—*’ü%Ý…²¸™éÁÂ!牎[¡Ma¨TÑAL¨ñ£"HûAiÛ5m©CsàxtêËYñ&1ïÄ«g«Ù¬P ï¿?~TÓQf–Óh†5L§@CˆHÝ@¸Û ¶t :[Iªjˆ¡eXê¿hõFá 6<ȱf ½5ñ#• È%ˆŸhâCù£i4š,  ÿ�úÔ¬ù;‹؈Œ •zÚü…úD"·6­9¡P‰î_¬±†Œ |ŸmÍE×4CƤ„¶zÁoqÔ´²…‰8èá@%â„ɨ˜‘¯½} ´a+x:¬ùäfÒŒ &¹£@¡V*-P«×‰Å„BXMAèÔKÚ`(  œ+ÇÎf+ùJ(bä6á¯ñô¼Â¬‚1DZ­Gû–Ãp\&£² 4áI£Ñ`J5íf£S—h‹mÚÂmO a´%=¬h'c& (ðY*•ÊåržçU*îa#Wæöb8 QIW0Âú{´ÔHšj4‘H˜ K7š=€Á€ yÜt>,îÌSbmÒ¤áäŸÅPh}îQ¦p¹€”ùrxÛ‘mD`f9©èÐ&,\~š„aI8$tú=Zoèâ``®Áœ8´GíÅX‡ 6­Ê`¦>¹Uh"ò:Ñ’v-ÒÆ¤Y Ê`„.¡ª[‚VGç™ÒÌ ‡(‰t}FÚž€.kŒz • <EtüšDÐq´‰Ü(rŒ.óEGÁÑñK8!Fêí B½ör‰(›í(š~¡cÆ(›çywà-fžDBÑ0LÁ°Y&+«B=3‚†£Gÿ:n'`ÖoZ?ò‹,Öú˜ýŒø/qõ8£ƒõch- öÐyÇ8ÃÕë×ÅVà!B#n~:‚73Ì$–Π A§C¡®€á|¸?1Ô �èÊ¢™4]P%?ºÂ˜²Q£-oˆ?]²V&“a+n$ôÝ¢ËÙLõóˆ^dz§Ññ(H¡Qš.C`~‚[½–ÕóÙò¼³Ø%˜‡~$‚hj£-`F’ÛƒU}­R}­Ò.×¢üe”PFÛÖ ж°aeLÜ—Î@×ÎÁ¬4¼ñ¤ýŠx?ò3Øm@¶@dÃH‡'`~ <Ÿ®GWÏï(ֈĸžç¥„„ªÕX8€Ž£EyóÌá<c…´%Ò~ð~<Þ€?Ö"Bmƒv˜¡ct%Ú厴ë´"{€Y"TÉ^šX&è€5Eo3Ír°,7ή¼®•^ï£×ÇËd% ¦Ó‹ÏK¥sµZf„ÐFB–eÙ×XIŠD¶B†äF±\!N³Cÿ¶ÒY>°åputÊ-®5ͱhLgÏ oŒPep2Ò:-íAj$ÊøFZi†W @† C¨I׊¦³Upéñ,m~ºFhH¬e2²^Ôí�P—B †P9Î5– B-™¶îÂÁ¡ã0ÃVasbP®;IIJ§ôÀQ"U•¶ŸwŠ-|ÞU:÷ ™dPã=hÓ m¾r$Ål寕º�<Fn¹ÖRrHRz´T=^M˜¿™™Q/ºmCR"-nŒO%U)l´‚Bû„QÓÇ o<t\,-®‚Þ†¤÷(†Ñ©‘Fþ CÓÙ£iÔë×+•™ ó‘J%¬¢hGÅhý4º$%‹Ç²¬¥¥e§NiÓ²X¼‚ÈÓ¶;˜X” édä÷´ ŒR©’<èÚqtñÚgô È]‚Ðë…UmàþG«OÈn«L–Ï0qjõ×––i2Y’D²C(Ü ÕŠ«T. ?ùß¿¼ðÿÙ{Ó8;«*k|Ÿg¾cæHbhƒD•VPÄÖWmlZ[µQpxQ_T´p@œZ&vÂH3Ɇ$!IUªRÞùùØuW­:åÿ«1üRüÅP¹÷Î9{ïµ×^ËwÂ[C½)¨U¿­Ê¨ìÜgQ"îÞã-üÍ<Œ…ºYÙ­ Ö÷Ô°Áè°V…ì´çE‘5³PÂz ëS­Õjx•è0ãäMèh€}Ž€ªæN’ïûa¢úGѬà!~K$ô acâ"1¡`z"1�j¬g`nؘ 6rÏM÷²úf²º@ ½lýWqƒ»XÛ™½}aœt0XÏ -(XX¦½«zõ3ëÞ¨—eYa iÕîž×-/Í-†›ÿ8Ô8[g¸õ>Ö_�a‹áÆ­ �e81Q©á˜²„ŠE'SÚ7Ò|@ç� …¬Vö¬ª÷%ÉùQô”ï¿ÎóÞ™çß‚” &™©£ƒ§:>>ÎÓBzÙØ™A¬Zµ*Žãááa¦N±`6rI«;%$`ŒlW< =Úô×”øÄ¤ƒ"‡å¶5-Ï\[!™öÝQV(Sµ…Èçëõ3“įªO…áX«–å²Nçì,ûŠï¸ß¿4жܘX mê2Ún!E:šêÛŸ?¾º`T•qŒ4„Ñ3Ö Ÿipe>ª²¡V'$äà ò¢õ ç (×ÁO$Cx•ZÕd†4NRí—`–VU֣Ĭn‡FßàXÁüFè;(ÈŒQæ7B‚EgàÏÜB™åÒ$$]¡‘†‹EÞ­,C®[C¤†õRõï5•Ägõ£ÝUÎάrØ™;w®¦Wz(  Óç_÷¤ã8Å ç^lj–»ÏóܹÕ)ž_xõ¹ [°†ùw6�Å€íj%¤ìîúº��-‰0ýaZŽö¨.ß$I@CJÈÁÝ£%EqjYþ8жã8?1f\ä탎´>gþ&ÏžNÙÔqœáááßþö·ëׯgêwhô®Y‚¡Lefò¯Y½ŒÑቱND†ív[鈵q#‘d2:c³\è`ñ ncÖŠüÆu·‹ô|?ŽãÕqüº~ÿÜ ÷ý~Y.¥ž‡>E¤¬JãL21€ À“1Xà·z1ÚZ`. ƒ•q 2<æ„ Y¹vÈu0>ÅRëZsXÔa¡‰cX©â�#¦hâ#ÅÓ@KÝ2ÍÆ¯!ÿ` _Á <XfH²Â/º/¬–¿n”O¿:MS®¢xq2MR,U$KX‹Õr­¹ˆ]½ÊÙå{98ƒ�[³j¸�³éðUUGæÏ&Ë‹¢XºtéK^ò’=öØ£,ËàÆ inj†û€}f§üÌÄ^Ì`ú (áaädö +3rOÙ.ÓCYkG»¾ 3‚±`Á‚¹sç2d¹îûºÝ<ï¯Ô7úIn4æ} 3ã_Y#D؇ y£ ë÷û0¡áƒ€÷›°1hÎcÓ^Aƒ½Š&–År;�¸¿þÌŸ?_'‚¹—‹×Ä£µBâf8\ºáðYÅ_<ïwžwN¯·"Žœü®çUÕûâø:ß¿k€7â”䞊¹Ç”Y™*&¼}ûv¥B™˜*®‚‡LÔB9ÕÇYÛ#–5f9\0ˆÄ€@$Ä$Er@F¬…º‡uijß—æ\Vò³eÖ-ª´@PÆáÉ+~¸Õb9[¢VÌ ã`̺–€{%€pÁ"³èZ!ÞcIsŒ±”vñ*¹Àbº²=Ï‹¢ˆÕ¦wÓv>°–çy¯×SOìFÐBÐÕ4 -M×uÆa‡vÒI'í³Ï>TCMWßü³u'õs@wf1‹ú¥;I«#€MX=AHúBhÄ #SŠ™5 Ë:TÌFÅ’e¯ÇqJǹ%ŽÊóÚ å“çyX–¯M’†¡slƒÆ¤jAà„ðŽB.ŒYÉLU}Àßù™c<^®—à°êqÃûw9ökPTGmÂY4¡ ÏÊ¢‡á©c–,Y²÷Þ{·Z-°í9¸Ó÷/ Ãsûý+‚`Èq.OÓ/úþ½Ú¥ˆò²YÍ¢tlô&ØTýª\Qšöª(ŠªYÉ?‰ô$}"eGÐö4>ÁDG—kTód’jØ X2ÃJÁF«Èð&\'¸àñUÎ8Oâ¼­~\YBC°ÑÝÄ<®È±Dµ)VÌ€9V€Y†LQUàÁΞ¸ÂFæl†™¨fÔ% 0Mw(~_oŠÇHuå(*ÈR ¬ñÎŽ¾nÀæ¬ø¾»—³ÓBssq,v’C†rðOqƒÈ2)½RõeŸ|òÉ7ú¾Ÿ,Oä ÉãÜ©ÐÏØ`”ÛÐtBÁCÔh`"—çcÇ:™ÍfSÅtW°0;Ÿ<®%œ#¬ml!ÎUUŽŽZžÊ"r½çyþö~ÿ»AÐwœ"ïM’ójµƒX¥Úeè6i7<Z=Ñ4åÀÝ&° >ËyºnÔ$I4¼iThµZ###½^IhнÇz@ [ZƒôöíÛ5Îñð<“Ñ­4`©^öÈÈH§Óév»ÐÌ€ÙÌŽó¹ 8#MkUu~m6¦Ü«,ŸYægæ2_Ĉsc4έŽv†¦'¿ZO>ž$oJœoL]pïÝ=ï>¯þëâNË@ yçá\Fá¸ôW¶ÂÆw@úbkv)Ðð�sx 1[×bó£•b¡šÚZãY1äyèyð€šª â2´åV·�=ÔU¬mÊ€n1 ëWËfN(€ôÐ×WŒBm,<¶šLXÉØÈ<?Çòz¸Bäú0Ñò”¨àÓ —³Ë›ðPê¼K¼bôfŠwtµÿ<Ž~åÛó¡¡¡ááá©“î´Âÿ±/]q<‡»4ˆ– ‚H,Ö¬‰ ìf!�ƒá/f¾jkT}¶ûœ»ÉñI¾Wî'\zw{ÌødUýçÀ렂ŧ•ã8ÿí8ÇÇñéiú3Ï;9MX¯?™eˆ7xÂèg"¼ñt¡þ=$è…ÄTÒ"¹S)0—ø@nZhâ¯ØsÏ=W®\™$‰¢=(ae¦_ƒYG–x°‹¦,[‡$Z¥0õ[´´‰ÑòqЯ{ÐqnôýžÈFcª=Ëì-™4¤öš?îWU•œ””ÿR:{:ÎÏVæ>¸ 7ýpZU•S?£îô˜¼1ºh‰»pú…¦=äb¹§¢&Ðd¦¬îO˜±,f<3M«¯€áhX60¼Ì‚x5L9A‘Ò�Ì… Q`îåä­ $nù°LÏ-¡l‚?ž1F§ªN×ß©Õj\v0I•çØd¦O+·‘˜ˆ/ä$䫸mÉIì9;§Ê᮲÷Ë@8Ï&�¬(ŠÚ—kñ§cs¯ñ.öªªòöôzõÜ]÷!WÈy@*<ÊôœB*Ä—dÍ$¢€rÅ8ödžç*cƒbh¶µ—j"LïÏÏûïîûñ½MžˆÄÇÆÅ»ŠÖÙ-7VUÀfÖ>3o9Ë|póÏ|ÿiúþ$ùŽïß73^‚‡ lúLàÀÈn(¼4ïÓ>B‹Ì’EN€\ûß³cÇŽ,Ë&&&ð›,˜­?šÝ³s^"*N©èÒ1އ™†«ð^’t¦ué½üoc¼²ÌVeU«Š>URI eY?d¾t¾Ñiÿ¢ ã/q²¬}¢6=gã:œÖ�É´F^‡Ô…ªûpá!¸gXøLäLàL²t:_$ã(X™GŽÙ)Ë„g(ší,ýdŒµÃÁ Ã\*à&Ìô ¬ÎNòX¨ÉН–)´K˜Š¾L0ð „°Ô0†Áö >ðz½ÎãY2Ó$9¦ëxÆ|W§ <}B§fœ}(“éí(fYd×÷}ù³„O†ù¡yüÇXŒdÃYtNä{ÕŽª› M¬QÐrâ‚BEÇÄf€‚/Dz0ÙÐï÷5NpÎhå^erjÒøLÃÝæJ_Ò4ÍoÈýùþä7'ç¾m®vª0 Ô &ïp‘œßèy¸îS3ågPé3Cc­HÃq„a ;_Ͻ+Æ€ÄÒmÐÆã-Š¢ÓéLNN²’²Q¤„xø˜¢àv:ôz¹:Ñ_ÓÊ� ;èé<2¬bþ 4AyAË <Ï•€«Ã+½^¯ Ëøqí=5?ð}ßo·Û£££Y–•#¥w¥×w?øj�Ss$ PFç#9BÜ”†D&{ä°î-7 žë«Ç “ñ¬‰1èÍ�ʺ…P¤%)óhx0Ÿ©¯@Èí5Š%'È س0 …L´ _}3· Ù koCp·¦Cly”é�®E¬Âp+Î €2p”PÀŸChwY£W Ó#EÐGÇêî³sz9\g@RZÐ~Эµ`Á‚v»ýä“ONNùcä¯�� �IDATNÊ@l\6‰ó¤]éÙR…Õ{ªí8ËyÚ§Bª_«äf K…² G#ˆs ¡ÍZźš§Žãçî㮳Á3…›Ž1]“åù¾yuo…)} C€Ÿ L —Q¸©ÚŘ­ŽSÑ̦Æ dÀ]˜!M†+™ÌÃz,ìÍónØí–,·>pµFmü%öѱx€¨e–å4YqТ`ám�ž�?Ä—™ö<0[¬‡¹}pÓó</Ü¢œ[šQã†î3ŸùÌý÷ßÿOúÓO<á8Ž3é”óJÎj-•<L½pcí–u±r/xóèËÒÈn­ÁчÉÝ{¶©fµoÆy6±Ò.Û½Ñ,A6� 0XþehÛàzôÐׯVv»z¡0° ÅÙ´IÔ÷�÷ô=j £6Þˆâz1¬` 2*Œû¸‘†l‰'Xq×ÝnWÅsQßp§ŽD`¼w«¦ßrvÆ Ìôä©°>4*Ërrr9>OÎëZÑxƒ®8„îÙ¾·,Ë3’$, ×u×Öjl:€6 zà A‡y 3‰-¹{Œ€€›$$•VEÿ?úí#Ûâ "œ~uý«õÎ{;í³Û |#‡E¤á…‹á–9HXý|_옂hyð0æn5i¸sk5Ø,ím=•0X‡™vmàŒz׬G!{Ìp Ï'5› à^¸1¥ÎV)Öüèœë¹UY)bhhhýúõšèø¾/žUãKú¡¥“ 24m0QŒp!/ mEàôDäf‰0ÏðüñÍG0 ¡-Ñh!ù]ÀMcÞšF»Q‹ –¤S/WhÃÔɇ¬&`M¤Î›7¯ÕjmÞ¼Œˆ™Îeô’‘|2Êq€ÉØ™¬äÄœu7ð7–ûv<“Ä#¨»CÎNûaçDÌ¢c»²z’JÒv:T묌`A÷­j°czNÓ᪪>Öï¯ñ¼uaxFžÿÈq#|Y dpzäX¥$QýXýv­Æàlˆ&!:F<äÈH‘id¿V«aáfE&3ueæD×mø›Àü3ò5”bìyƒäç@& ¸ßê´ Íê2x%3=ð¸À±("Qñ1 D#º³Ýw06~9^º–2¸3öÁñß0$Ô�^XûÄ÷}'s‚k‚üäÜù3<<<22¢ý²Qæ¯Ìkß®!¾â]@1š³K½{¶2,7KøÝ¡)ˆy5v¹fàT?9…Û¬åÝ®Zù# maÙpÙgÅõÙB«l‚Ε((-ºã”]ÂwŠDÇú] QÕëõ lݺudd˜*G;`!ˆhw)(Í$[êñH²ƒ"ÿ½eµ…ÿ[«ÕôpÐ^ŽÕEc/®)‘Ѳsñ.?Iù4èGñ’å=W"¼š,€9q(ý±-çé5c>”$k<ïQ´Éu¿äyœ˜hÄ1$Ì“V ‹Ì2XCƒQ0!¡¡ˆ?øaÙ(™”¢>Ð%I‚3´l”JsÊÇU‹ÕÙâiAP1QË$Nþ·`R€0ÛՙÉ>Ì4·F¡ ½ ù[¦×B>›x¤LF²|õ…âøF‚¬Ç ¢³b,œÇ(øÆ÷ÂZm<žiqƦŽÝB¼¼êÙ•³ÄqƒŒÅ'›Ÿeó³êþJ;n[X+”¸‡Ô÷-¯Ù]h< %¤`RdöÀ D0q¿5Å’æç¯a� ËEô€‚rfÃ%¯ ž†Ñˆ®‚oZÄãŽPX`:MÿÒ´z Ë–-;á„öÚk/ÐÒ²–±±±§žzJÁá¢(Â<ÿJ§³d¦Ý-?(–(df§ƒ¡©R~/¼öxfp èì\*B‹4 ðî*ç‚A€„ZÏ_ í`¡Óˆý`)3«‡Ý—õý$ysšÞWU·ø~•ç"Ò ÃÓç²8þj>D‡kª£^æl KúÊ(z@ëÄ|3mÂ0Ô)‡àýÁÄ—&æýÛ<- >Ùû½öQmq(;s€ÊS 3ÚE: stqÑF;ƒઢ'Äf$ÀÄàÞÈà'°Ç‹¢'‚™©ð ÊVn °Þ0T¨Ùð”Ë_+öó¨•îvEo@å`߫寂ÿ ï¹·¹fÓ½´ë߯F+cLÿ•ýjqåŸìn9î„ñð<¸fÛh¦š È÷B²p÷ÑŦ¶c’ öjRØÊŠO¼˜Yþœ €ˆQ8ŠÔL…¹3UUéãÅäSÈŸWß2°Ôš,›­kï±ÇûÁ~022Âj4¸N¨mú¾¿(ÏÏL’¯…áÆñeaxÿ�âãa,Ðôu·BÀ9Í ‡BÖÿ«f–@h™ßÈÌ Ñ·†²^/Æ]»CÎÎ9ìŸ ÐHàTEñ(ÔÎzºAS'rö1­<ßJÒ#z¦<æ8{Ń®« ZhJÎ.³`üŒ©u0J…Ù€eF §]t×u˱Ò[çußßõì;O:eY¦G¤ÙÁYí§µÙôq±Ä›¡»¼cÇkr4h´¾, j¤fì댽ÍcnzwŠb+‘Wß ü’[C.Œ}EaX¦[ ã ¹ ¹«Y£²�.ôð¼P&Ö"ÃÑÒ F,SÂËÕþ:t~á$ïN̳M%UôÈYëh¼aÓ3Œ…bNˆu¯Y9E °•¯Å �=‹YÄeÊ•ü <?:/ËÒl2þ÷}¦N q†¡ÆkŒå3f㢀¯1ív»ÕjMNN²8·æ&X`yqwQV$RÀ�Ç4ž6R=äLl›k¥;ú<ç–åÛÒô×½Wä¼ xG’DQt;q£9ðX~¬š*)cž§¸°åÙ5Êj¹ ”@Š] ,½+<d¶DÚrvf¼ù›bèrë`„Ë|n롵™ ªªo»îéYÖuÝuƒU~~ß캿÷<¡!GV«ÄT³ž pDÂÂ>iHa€u ·BðPOØ ï:Ùó²îÙ]Y*"âß㻹Á A)%¦Ä-|œ4õSà…‡=yMë_A €‰fñ¬}�Ñly|…ÑŠ =�},µZ-MÓ~¿á�ˆ{êgb+–u¡E–c-@Š¥¨¶›¶â”,díg ‘Žp®ÀªØ,Ð2›”‡ÑHåyž—€ÈÄNÌ-/m6»DtÄqÆ¥�n4r[¶³(›ô+Sõ®î™GŒ{‡ë9^µ¨ê¿_»¼æÿÙ·$ÒQbíé ™ˆº Ašù¾ï|ðÁ|ð7ÞxÏ=÷0 gñõ!òfÁwLµGÁ a!ugHÁ²^*‹Æ¢Àb2‘~þÇ{½«ÂðNcLU WÕ•žwfÁÃ3Us°_A ]X} ðОEØa%!\ö&à5L°ñØh¥8(v Þüô£ˆþÄnÇX ìÅæÈ©úÊõM[M<¼{Ïó¶:Ηªê‹ýþÇ‚ ï‹ãÿ ‚[}ßÄ6 Ãó¨¿%ë ø…'æ„t×q#z²à¼†SÎÔ¨ÊSâ?å‡w„UPåEîNºnÏE§ Â<ðtBí÷û<*OÇc–q!Ú!L®ã^>ü€AÕS�kÙ’ŸaR˜iSù8á < 0'ÿqƒ+¯ ´Z°ža±úÙΰŒÑ)‘£2ÓÑ’ùV!‚Ì”¥š­ÞïìÏÔËãÐ`ÉÝc¦BòE{0\µ‚Zjâ4¤+ùpnŒ ÿ[¿NßÙâ„Cô#¹¹¢»IAPÙ#iÃ<™5’Y–å¶mÛ|ðÁ±±1K�‚³{Ä3Ü[|òdJ nÖ2úÔÕ« ³29{ãËÐ7òÿºÝoUÕ}ƒòÚqœ-EñmÏ» ßg½ÞÀÅ!ç<¦’w¢(Ò‚L1€\Ž@ªŠî0ŸÄ¾ò8%ô(Àvà˜´[ðæb.GÈî“ÅÀv·øìŠ’[T+! wpÕ¼cº¾v½þåÉɇªêÏûƒç a5\" °Í{Fõ“$IE˜-ÇIÊà ¼¼ðEzhVUånw¥§pĈ¸¢ó}<c¡ ZÉrzBáÔÓî.Ö=$2áØÍ­`œ2š2+*¢ÏD&•Y¿‹)I@’$ÑჺeYbs¹É¢ÈV`ÐSFç1õÉh«$œ;œ<ò!®—¡3ÂÐâÓƒFñ°B`Ìc)Ø’µÆÅgóÅ9Z3ö‚‘XôlxVIž¤e…<1õéJÎîœÙêÌ ç)XY—f³q×¹ùA¹yÔ€ ]¯×Á¸Sì¸%ÒT„,êÁ´àõë×?þøã–èú1ˆ1Àá A¿ßG …â�õ d“˜ÎÓQ2‰ã˜+T‹jôïQtq¿ÿ×ýëà¥ì%rzš^†ýAÞÀäfD°Ãº`˜¼ÇˆG…ØW¿©ŸÆ¾¨lîniHî9;™«†Œž LO ŸÊ~R…ù£q׸Xš¨*�…ñ°=þXËY–E/*Ë›¢ÈñŒù6ÈVнg8ˆ=÷AÙb9Tâ–¡à×�sPŸñ€¦[ÛòT&Îe66æ¾(Î/8úèWxA[e/Éó­ž÷Ø ˆÄûÌseÉMr>”1¤ÉÝ”=ÚÛY,UU¿ ʦÅrØçXfŽÙ31mmZä^.JCaV#äl„ù>Kt¶ÑÓ4Ëa‚�^1£j /@ã§Ý3!á}6#‡w¦è]×í¿«_ûFM÷Èœ9s<ÏÛ¾}{žçÑ%ÑøÍãÞO=LÞ@]Ovž$Ã…WÂ`¬R³Pí¡úÇbž {Kªä­IîæÆ˜à¢€y.@¡yIÀ]i [±i4›T±Ä�h¨I’œçûgÅqàû·{Þ¼¢x[–]ëy¸®;HŒ¸ÿÄFJú¨µ¾ÄºÕ—‹^£ ¬ÐYH檳kkc¨ûÑ]á6Án’ô?DSE+r穞ÛE÷]Y"Î=Žù«)/{?ìUó¦í°x P)”<,ŠHY–›³ì¿íbî¾2ÉG^…\-À÷o޼Y.ÈP=y[nðA 7€¨ÑÀä™>p—-T\ p„1V‹y~YQUg¥é|êà…´�‡Û8òøó>pޥǤÝtƒ"xö_Í™wKñ–¢weOh“BÎ@lô€–8 ˜õAU w³q„±ê<=æPk$Æá‹êå°{„4TzÁ-Ä#²jt˪Ž%0´`Ò¥ÂÔg|o½^?üðÃßò–·¬X±VuúoÁÅDz×e£4nÈ;±.Ül–6×%€¿Ð(Ò2ÔqœøSqü‰Ø½Ï­îªän¿j¼j?ÏóN§¬ïh3JRô˜žÃ›—†,r'|ÿ;AðŠ,;´VûÏ~ÿ:ß¿+°‰¸Ã.®œég*€©®6X±ÜfÆ^¶Tk™d9¨¥?‚Èý7g’vW9;¡Ð±<lN&µ$ÿ`¾7ô'}““›â…Óvâ+cÿõ>¿<žYÁT6ÓÜg“4ˆcàèÇÅXÚòÜÝQì‚A$ÔÀ»þZ§ šü@tSu»]!¿^Kó˜I™`H³c w}9Ñf]=¸ŸÑížRUç×j1_ìv?E;È¡Ìžç ªTfzý )%ë1WT–G•µ÷×öÜ.jä·yÞ›ï®~5¯5þ½nã­ =˜Ð†ÕWÐÜb¢¿¢D[¶Q‰�‡¾öÛ€drQË…,ÈŠˆF8þð½hïCàÕòãB¶†aÇÌ“™r‚L³:êàΠ³è8Ž7e»tÅ-ŠbÛ¶mêç¹ÌgÌÑè¨KQïþͬ\ǃ;иÔèÈæ1ìQåSî¼ïÜì¸÷¸îŽ©n¥s—“½6K^Ÿx?öžZ*KŠü_òìm™ˆx{ŧŠj´’Lx¢üÒx¦Ø²†^ýJÐl ªª…"]ÇrœKÃð³;v|¦Ù|²ªò³d?&1ê'[VÐ÷C„™Ñ~eHóÅL!±eYsœ3ÅðNe97Ý-xóÁX³" ¿ç%޹ßT›+·æÎ™7'MÓN§“oÉÍ£&?87·Ï8j‘¶`MXµKA‡)²ZÓ=ŸµÜ1y ]Ë.—½mXõ ½V ¿L.ÐÓMq-hèà›ˆh[X¿îËï}½<êEoùûrTc$ý¢ø×¢ø@­æ»îdQ|´Ýþh·{¹ïo |œýR™ .#~h`L½Ç”•ÎÃÎ›Š·ÿsÿíô«ª|ÿ«×ÞgU)Ïí´‚LJxÚ”{WBžoìq äæÂeKý33c(*Àª¨Š[œL0…Wÿ^»_8ÁÙ~‰E€Ð/áÐ 8ä˳«`¡,XPUUí¼Úä-“Þ‘^ÇwÞyç]wÝ¥¸Ùäç&£s"Œà_ˆ¬@žŽw1z½f°Ä°³§ÜS4Î=‹ÊTîF×Ýáªþižç½­=wƒ›í›¹m×ïøzÈfGdÙ»2ï:¯ud«,K÷¹n碎û{7º**z'‚˜å’:e®? c½¤}Ëòy~­173ì8ÿ†B–hÀ–…d˜J§oAh™õM„´áÁn>‡ˆÁY–…UuJž/¹Üq¶$´†@Øe7°¶ó£ õ€#¡"I?–Ö?_o4«W¯~ãßøò—¿|áÂ…Æÿs~üÁ:¸d‹/^°`A½^g$ï8Š¢¹sç.Z´¨ÙlB%„Æé-E«LaË^v Á4ëlL)’Àq¿oqk—ESÈ4q¨áî¸3i‰0bG±I0µçy‡—å1yþÉ(‚`Á˜ç]†'&ÉÞ$†6È6�|¬š w§¥FžçIžôOîöM÷Uy~þ~aë”Vë”Öåÿ[o'å[ÖäýíÿÁ§EÑï÷qRc‹ÂUÁ¢ÕZ [¬4“0îÊ¢à e1)ô A•� ç¯F)+´c0[‡@–EÁRçYB̲€Ôî_é'KŠW´÷—•ñ¹±¬w‡Ë²’­Vkþüù .œ?þ‚ -Z´hÑ¢yóæÁh\IhC³ú›Žãäçäñ¹q÷œn±|ÚÙz #=<•Mâ>êc–.]úâ¿xùòå"ܸÏv½}<¼£øü¸ñæ†wåT»Hî—Æ›Å!E¾xF;' ùsçꆹÚîb˜tß<?.I.Ãý‹âøÉ“†sõçUÜë1ùd‘hX#\Y¬–Yã2—·ê¿eÙˆãüÁ˜3³¬5H–°+GÜ]åüC¤­‚ ­öÚk¯N8á˜cŽyâ‰'ÆÇÇÇÇÇûnßqE°u›Íæ^{íåûþÖ­[!v‚UÒjµ–.]ºbÅŠ~¿¿iÓ&õnAKûÒ ƒàXp…!vØÝ8áƒÞjYAýÍdÍ›8aç `eÐPldÂ+#,3*3oø6WÕ"‘Ðqzƒ“:˲vžçU5Z†»„DÕø‘0rȨ,Ê}ÊòUGÇß”hòê V Çév»ß.ƒ“?&§/©¾7(VôLà87óõaTˆÉ¾hûË,çŽÇÞÛmv:ú:ãÙI½Ç(ŠÂ0œœœd§%èîG¦ޝFîiU½,ӻƧ¢ ̃šr+¸º–™¤ÏIûolï—^pN†•[ÕjµZ­¦ñFWøðð0š(ƘF£Ñív;àJ‹‰§Ÿžœ¦¯M£ïFE¿0Ƥÿ‘šÊ4ÏmN ´ÏD&æÌ™³|ùò­[·Bv!MSßñ1É»“Úe5ð¡5‘2Æ„‡éûSsö ¹3Þ(È»†EÕ<Ï›—¦§åù¥aø„ã|# O‰ã×äù¯G a>†Iÿ–!®cgEè<±¬».øs³ì~Ï»^É¢Að™8~ß .D2 w «—¼«×O‡&º² ó˰$í¤ÓéìØ±cll¬ÓéLé‡/žšôœJ’dûöíív¢°à\éYÓï÷7nÜÇñÐÐ~8N\fѤ3û´##ænŠ%íŒÑ0Ž0ä‹k åæ*,6;Bî ¸g1n‚¸LUb*ÂÒðc®{¾ï¹ßÿH£±5I\×= ª^Ÿeç×j]o€"Cà ±\3JpÑ»H%"í%Yq^öóÊmµZš%,ÎÓCJß{±).ð¼_{˜0×ÀƒÔ^>8t0Z­ål€â-àær1…fâªá‚JRBLSÏ# izyxeàC¼™ët ôDÏ¢ ƒç†)cܦ1¦,Êè–(ÿSîþÈ-òB2 {a†y0 ›Í&>mΜ9sçÎÕÁÊQµˆ æÎ;66666¦«š§ Ê²,_] ‹úYu³Ý8…S–¥ÿßYíŒ}f¬õ‘ÖÔÖˆÝbn‘»¹Wx<òˆî#cLQ+Ê~éåS@qº_ꎰ^¯ï»ï¾išÞ{ï½eYº÷¹ÅÓ&ܺIÙc-¨(qʸHä³iúÁF£ëy¾1qY^g'ÉÑ"·ø~F¦ÚÙÆ{AF¢SÌ àÃ1V‹?E,÷n·Ûh4ôß&IR3æ]eù€ïÿ6\Ç1ÆüÕ˜n]ÔïªVë ^"«»ê[`ËÔÝ!gçÿ°ör‰ÎŒzWôFOýùÏ~×]wmß¾ý‰'žÈó¼ÿÕ~tx”IfÕªCCCNr ʧiúÔSO ãAÔ` èI¡È  ^¸%£3PCwùÏxCË A@¾Ðqa5¼àp=Š0uH™Tš^œ@»¾ÿaßÿP·ûuÏ›[o(Š…¡Ç³Ð¤¤e¦¿Î(’SÒxo­]õ¯ùûR÷M^µq¿ýžñŒg ]wÝ1Ãc§Ìñ¯ô°B?Fƒ"繺˜²¡62z~§ˆÇˆ¸\¤¢ªF5©_ ¹3 œ±þ8W ) ÿE$Ó‚�'¦^0�IÕ}A˜äB`8 ì±õÀT;ΰã9žïûííV«Å¦všƒ«y¥> `�GQ´råÊíÛ·ÇqÌÆU½*VÎ:G†ÄõÜ(ŒÒ4MÇRÙ$e·Œ÷ŠÝÇ] ö>ß+,ånét:ÝnwŠÌöÆÔÀ÷ö*wàp*Ót¼/}þajôEÉÅtk>CW§õû? ‚IÇqD¢(êv»ý²¼ÖóÎLÓ? ”x¤p7°FÖ€ 2ñùƒ`ÌA¼ÐÕUÕ(Š¿†a)R C%5lHÓõÆU–¿ o}5Hz²Wf^乎kîÚ½wÏ=÷<ýôÓ³,{ä‘G<ðÀ]ëê7mÚtõÕWËLY_�YeYJ%Õ²*{yÖYß}xtÛ¶mýõÓ·¥æ/Æ¿ÓçbU³¦0 7aaCÀ쎖ÇË¡lQf:A­áýrÑ�C›ÝØIŸ‡HØ{Ë]Èx˜g X6‘é Ö`Ÿeø4|©ë>fÌë³ly–}©ÕÊgö]’QÙX}x”S³U‹¦°…=ÊôÔôö½Í ךCº’NN~xݺ÷¿#]ãTõÊé9r¿°v;+Þã¬ç{Ôj@k}Gál•ÄG6""Ïè0)œÙ+àtqÓCZŒòü³Îd–´¡# Y9W<�r¹-‡°e¹9sæÌ™3gÞ¼yyžOLL�]\¸pásŸûÜZ­¶nÝ:EuÇÙú–­cÿ<6vÈX¹©l%-ÕåS]8�€ùÒ<=%>9޳råÊ#Ž8¢ÕjŽŽÆC±Ybòýs÷öH^eGdž…w÷To/=/•† œ¡H‡¸ù¹ÿg¿(Š‘‘Øä¯Ë-NíîóéٞDzài¶5AðÊ<_^–kG‘´çÅk²ì2ßÀ˜Âa H”¢kȽÖ£ÒØÌ›gÖÌHä"'–å]"É %öÞ,Ûäy¿ò}vŸ:&OÞœx‹=Y$ÕÂ*~~¼±½ñ…òÂ]‹Wœ¦é£>zýõ×ïòŒ5XÔð¹ŒsßMÜà[Aù¼29-IV%eYºw¸Îç÷�ó>Rº½6 SuˆÓ‘ü!q+IL—;è4Lp�ÙI·’Ùð5EÕ[(Äx®çy­V æŒ/ƒqÄ¥&(”ÔëõrðƒóŽ'Š0NoÍ$‚—¥åÑ#"? ÃAÐø(#ÜêãÕ,¶%€¼Šbº½ ¨„»JeYÊCâÜî”AyÙ…Ù)O­=÷÷—Æ|`MñÎ,(O*ý_ø…™atB•{€øƒlQ ¬ˆºê;ÅcÔª+ èÂú¨yì_ÈLÏšß ºYæú½ˆ:láº<P~fEsŸù2ÍPi!¼©�Ýüùó“êÕ*M¡VŸA 9´éèM{üfj¢*ŠbôäÑÑy£«Î[¥å‘ò?­‘Ì(Š^úÒ—¾úÕ¯¾ÿþû·nÝš¦ib>z¼›=gÒÉž‘õ~Þ›Â!/Ü-®ó Ù¹ÞéŸÓ/>_pßÞ“¿&¯ýßš¾„´îP§òNA¢ã8Î×=ï­izœÈ/E–;ΩEqI>Y–1ÔY &—’è rÇH ¬c¤w»ªª5ž×-ŠOÇñ<¯(ŠsûýÿuÝ›=ÏÌÄ'¦tÙ/œCgÓXÓÈâ¬(ŠƒŽ:hþ²ùÉE”îÖvNÔÁ{ÂH0^¿1&y*‰F#ù³­ ,ʲ[VÝŠ­)€}qÞÒù‡³:»ÁóJB$×]@xrËZ—£’Ó0Ï–)÷×J„ñ€F2 is’e Cá„åëÁÊkýe䉀þx7âyx¦&Š'„0z MnB×?õOÆÅ½Óu[®üPÆu~ÒÎÃS�� �IDATéÈg<¯µÕ|ý€äœžŸl›²¢A±Š0“ˆ8QËhŠŒ;xÝì‰�”uÛPÛ)ëm�yR„%A‘,c^2úH™'¢2þZ@ð¢Òwªý6¬Ë‚H£5K2ã^0ÿ¤)N³Ù\ºti­V‹ãX_z«ÕR6fʲk6› ,Ø~ÀölßìÀϘåRJš¦áa²(YÿÉõû~jß(Š–.]ºyóf}•©Ê^Y4‹¬Ÿ=þøãwÜqÇ}÷Ý7<<\8Efrƃ§/·‹÷Û©|+ß–»¡ëùÓ´Çqæ¾iîØïÆœëœðû¡çyÅ~Ew‘ç<î𪒆ñ/¸–€GŽp;‘eß0æ½y~LYž”eçù”NYúÍú`ù?¡ÆÕÙÒ³Ñó¡^¯ëëÖ84Ûo·ªª{çËAð…NçIǹÍqnö¼r0R†© ²,Å—re)ÛĻɋ%ÖÛ9´<t,ø²|yB&ÚÒÞrþÞ?œ¡ƒÎ¨H‹¦¨SbM]§Š«ª¬¤šÎ#°dQ‰ãÓXo ÒÌÁð@²{u‘™ê;Vúƒ˜'3 (™p‰ßaПã D2¬=ü’D\…|—¡G( ò6–ë”Nƒ4œŸ€Åé@¡¥—Ä5Ð4Ui`4ÉžŒz"? ’Ó“Ãß×;äçÎ'²(ÇÌ/Úä~ðseX<9sŸq9Ë Ïeð†±¬ ÷N\×U"€ib’㪪¹¼à‘T]Î�ÞáåaŒHD4·ð<OMôéÁ‚Å¢H/Ê=(ý›Í¦ ¨³F»ôÍfsùòå+W®,Ërñ²Åk÷Y»hhQ£ßH‚©Þä&èã£ã£KGç>5·V«ÍŸ?_ÝNÍNxs˜–¹_qï»ï¾G}tll¬×ë•«Jy‰ÔßUϪlFf ¦©*·ªŠ ÝPv•­Òzy+EÞ¿ /"Þ#^óåÍ<Ïp†­$PQÈ"·@þ:Œ†ó¯úþG’ä¬(ê‰È (‡…¿ ¶.ÅÒÂ’f¦ ËßY$OýLTÉПÝàºWºîJ‘›}ŸIL@¹‹¢È÷ÊÓ—¦ÑÛ£¢*F«Õêt:®ëî+û¾P^x•\u–œµ;äì†4wÑqpÔëõv»=>>g=FÒÙ­�ôäyM£*·šºì cMÆ€ÇÂöÉš¨êÅp_‡>–7·ÈþúLóÇâÆ¤!·1°O )f! XfƬN†‡ ‘ä郞¸tC±Ï!Îúq‘,UÂÃüØÜ—Òÿzâ%ÕÞNôÉ”žWaàžï>¹Ã¹1*ßÇ—Á¶�„®ʇé�._3P r¥oV“SÆú ËEˆLH#@Oà¢å#ú0Ak•:,ÖÇã´è2äËâF¬| Æy£Ñ˜3gŽ:EMY* œß¢(RùµåË—/}øawÑ¢¥«–n:xÓ‘Ÿ;rS¾‰å Òmië¶ÖèËGý¯û:ŽEÑøø¸ëºÎƒNö¬¬^ôó£###eY¦§¦åò2¸&Ðü d nŒq1ÁèñTŠsƒ[¿®>„Œ ñBdb* šOº°¡$¶$Þìêõ<Ï ywÂKž·V¡Ë2?ÖÌœþ=XÖÑàùÄ}ax¹ c"˜ùŽ™êÎ;wåÊ•›6mÚ-ë¹ó«fÐsCóÆœùZª—lÜËy¥e‚%Èœ%`&ˆULzf§Bh^Y2\Xà‡å¼0…ƒØ´ÆË‘Œ ¬ÐIFxN%®Û˜³À>Ä{ð¸vƒTŒ ”1oh,GYÃE7!„D �ßɬqëG|ÿ•q\ûJM3ýÉÉɲ*—•åpUõf†Lõ²Ô"ø˜›=ó¤½7LN°)î‘Mnø´ä¢Šý/ÐEc§j¤á(—ñ*!Á èpBö²¬}ÉG¶^3{4èoÖj5¼5¸é›r]wñâÅÿôOÿt@Q¬yøS{Þ^ÿåÙîÐò¡þã†8Ž÷½`ßyÙ¼iÞ¼TÆ1( Z­VÇI’a¦{¦ßžPD¤þËzq}áÝéN‚íüÐòr¢c!Kˆ#X“ XlúoÁ¯cAn®°:"–„wq` €ÙÏt{`³ž�Å®á>"óèp1¼8µJÖÏ,L!Ú±±±Ç|rrr·_ÎN&B ÙΊOЇªè epF`b‹‡E°¦ÙÖ ŽIúᨠX3 ò8pY{Êy˜Wç¢ajyQn9<â7±Ï1_ÆmÌáìÆŠ·& ‘#ÚqŽ©íÐ0 ëõºBÒjêÌ:+À zì(7Y"…{­ð´Œ†#KB |ßGç?ëõ¯w»m4F»]©ª£ãx…1ÿ†…ëÖÃUÀe¦Õ4V¬4Æ‹‹rEÙÿ\_DÄHû}ídcâxÐAÐçV«ÕÀiû�O !|¯RÞ•»ÁÝ#$Ñz›X–P4«PªšD€d5€̓´:ÒëõôªTÝ@'(õc›Í¦ÎTÂîOçœ\×Ýc=–²ì·«¾ú/¾à™¼æ“/þÉŸ®øåxl®9àºó®+ž,–|qIX…íyíxnìOúº5”Œ ‚eYúùÑc‘¹Ó8®ãº®LŠÉL)Ó´c`P–#84¿ažÄÚEêóÄDGn âÁbñèâä–o1‚Þ•JòCž½±;t-éëc\-=|”LÁöó¬¾È˜§…L“'3ÎNrFâ]îeY6<<¬÷ø <x«Üú_ò_»CÎN9–Ñ3ŒùZÀŽu<‹ÅÞ_@Š„ôÌ™~jeR|ر„»,#*°àd7­â gi£±›ÿ%j ˆ]‚RÁ¦dÀ…}ÂÞn`R�PÒ“„ZNúx�h¶û 6?ªZŸA+i PP³bžqÔó¾Eïê÷¯ ‚gçùAÆ|¡^‘jÐä‡TÁLc—°)’È~Yvj&"Ñᑾ÷Þ%½r{é|×1ë§07UË×`Ã'#Î6k’f­ÞÜôdáv›/(UDÅWÚíöÐÐ;R#g¡u�+LÂêñ‡~›¦bqã¸Ô�Ün·,X°Ï>û¬ ¿û­oP¾àß]ú—û…^x̵Ÿyã[ÿíÕ{¿è‚=ðŒFNYð•cõ±á#†W¼gEN±ÝšÍf³ÙžNóÇÄñœ¢,˜Æ¢')Ãbo2ªÌ� oÐÞ`ÛöÙä¡.Á'„Ûcn<‰5›éÉÅÃäÌÿ•møÖ¬Cƒ‘OÖñ/TUU••yÌ”/+³2ÿ×¾bŒ¹ÅܲX,‡î9;“´Æº„�PÏêR‚ ÑhŒó¸;ð7�¾¬}‹RÆb+à×0ÓŽ–²öÉqæ²Ñ€ÔËŒãì`¤ˆ3 Ä!Kx”Á@`ÍØÒÌêÆÁÄ©š¡#Hp@½ í@Ðñ‚gš<*„VSEðµd‚8¿V–é}XäÇ99Ž'ŒùlxïÍñ˲¬ÕjÍfsllLiÙPX@ñ7-zbÜx·x¥3µÏïiôŽëeÇfòðô ÆE1‹®G D¬ xF€9Éq.÷ÌIaªtõõ¿öz= ,d­–T>›Ë-•BÙl6áÆ­?µZ­Ýn?ó™Ï<¸ÓyÓ£/Žæ•ëöèNœôš£“g›Vkõ{¾qÙ÷ßû•ç=´`¿OlŸxÌlÛ·eI6çš9š14 }2­VKgòuÂÊoP×'ÛðÐnÄÂZ­N›)×÷(e,7#HñgjÔQ?i”–¨Œ…ðζøãù'èØž/ŽÝ1ÓÍrŒØO}õ_ÜÜËÍ Lú‰TŒTRm}ÆÖ½d¯3åÌÝÀÚÎ9èXð¸"泬ßaIî»�äEl`b;cÉêzš¼h2_™§& ¿ÿÌv4áâ�¢)hZ²Ž$²~ðy4* Ãî…z B¬Åœ™Tðâpô #mÑŸØuK–᪠tÉù8šLÂÃ#>€õЄÐ' ¼,ä­÷z^îy]×PÒqvDQtðÁ/]ºôÖ[oFâÉʪzmýCúAÔÖÖ ·Póà©sð÷^úîTž+å}3•f+oâAÁ‹oÙ²­Dã ÍmˆJXFyP ã@®ÉÐå2 ´u9*x£‡¾¢—:ï5þüeË–a™Õëõf³9oÞ¼+V¬Zµêÿš—ýê%‡â±ãš‰¹åYÕ³’41[¶¼ ;ä£×wÞ~Ƶ£¤³°s轇.[¿Ì›ðâƒã(ŠT€@±Á~¿¯P,Ú,Ü´L}Ú<„„'ß hŠ£¥O€Ê¢ElÀãB¨Ðf*FÐÞ‡¢.&=¡V a•a10z8¨X…èH2Ó ¤V´²¦zÙJ"âßæ»w¸éai)¥ˆ¼ùÈ7¶Ça»{9;“±c.=ÙV]Û9x‹qc–B^ì‰ú©5ŒðÊÀ`ÆÒ'ö}¿ ªÎ›:ùÛòæ¿7 NY”ñûâÉL6NoÈ“S46nÞ°‹Ö"þ$‰³ÊqC×qg‹#"¤þ?ìv0'ÄSë SÌn¨²œólLÉ©U~¡í´ncÅÜÁå¶Žâ‚çìõz úagfY8žZúìN=ž„?'''•–ʪ‹hD#ÚÛëòJF§>¼Ñh$I’$‰¿Ã/j…¿ÈW,ÖƒÞ ,Ï„ar-[…6íQu)ÄÏlinh©D›zÐ…Ôkˆã˜…¢ÁGI­À]­VÓ.”J,+zþüùsæÌi4µZmΜ9Z¦,]ºtîܹÛþ§ßã½ãgæ£å""µuëüË//÷Ùçs¯Yû¥e¿wD——-›»lÿû—¯,'''·lÙ²cÇŽmÛ¶©,›Î)Ù¡Ûíê+ÀjÇs•Fccã(LqLÃNMw.ć@<ӗ¢Úl .�aÖ’ò|bRÏÌrOQc Üá|@yª‹™QqXYëï°F;çpÀ¾cAEïÖ©ìÙL<mke)7Þ(¯xÅ®o�8°„—5ˆ¿· ‰ÌôeP 92ÓláÌð=Zå³Ëbÿ¢ù²æA Í£OG¹›wÓmýKK—&l§Á±áŠDa"ß÷‹Õ…yŽÉ_žça^UUíþZµ¡2×Ns±˜R…¨ÀjcÈ ñpPC@yL£‘~)‹ßàðÒ(މt¦Z±(\ yVΘè �sY·Ï ”¡O«Àí�—gâ™zJ®]»6Š" <L Ö6e­Xä’O‰?j×]cô@=ã1b8ô§O[/3ÿú‡yóæ-Y²ºãÀo»Ý.Ð60Ð(_Cùô,OÉ<LË‘ 6-&ô®£(Z²d ;LC¦såÊ•«W¯®?·þäòáí—\¸ì“§§Ö¶Œýdï­):è¡eãΡÿç¡?>|ÿºû׸vÛŸ·=üÈÃI’t:N§£ªÞZB ŽŽêãÕºJD4 ±| RèH!ûá],äïx ¯k†]«ùÉp¥³õáhƒÃ‰ˆªÀi¿ßç#;HMG¢¹̘2˜*+f+hXÚð»úÏÌ*ç®»¤Ó‘×½n×b`ÚËØ@"cŒyŽÈ’8¾i ¯e±ÑäZô–Bᾑ1&ymâÿÂטÑn·Ó4ív»Né7åkK÷7®®*H."¡l¥4§âYEv\æu½èÜÈtM–eÅk‹jUÿkìÏ×Ôž-óí«NЧ®cÈ [½"@¨ú¹c©³ §c¾86’5ÄÊXpKP3ôɳˑ> m‡hvÉu8èÙê”)IÆ®F!‹>feå>eùp911¡¯Ã“íŸUãU¹n†Ý/#ÈY ýe‚¢^mE .ܶmÓ¢`Ƀ\úè ZãÉ8Ô¸7®9“Þ,uz%Ào'''ÑbÔjC¿Z™Ò4˜˜˜˜˜xAõ‚o-üÖqãV}ék¿ÿï™sSÕÞìXqÍëšó§9›ïݼvÎÚ±‰±ywÌЇ”R¡+o:5¢å-‚¨…F \øãq"bi•ê£Ã-3­¶ £££Ø³ûÿ\(sÏŸg0{Ģ»2l‡Ãu «à0éVÛëÃÿ²¿ b¨[äì]—â’AÎ:K}T®»n×*t€Õ2 ÊêaXHEsF¯÷ü$yá@7 2k?s†ÂòMànª÷É×襙û;×ó¼½÷ÞûïxÇQGÕjµª¼òÖxùKrîŽ@I=Oûg˲¢*ܯ¸ÒPН 꿪ç¯ÊY ‰Ù3Z’#CõÃF¥A‚±Ô¦v°=�ݬ'–±A[Ë>°Ô<@@6ªÿÜSÀ&p¦@ŠŠg…œ] tÚq‚�¸×¨£¥C¸1_Ê%–Ä”ÔЪÜôŒÙlpbêôŸ~&cú|Ü ¿E±yhhèî»ïâSF‹æÙskÓ¦Z8B ±™Y-Ü…†ÏoÁþ•¨ç4rlÞ¼yíÚµÇßsüGÌG>¼ê’ƒO½d¿­í·õ£ÞpÉúMëçß?ÿG'þèñç=þŒ[ž¿g¦` Ÿód[Y–£££###H�„bC!µG•5¸±ç*ÉÀú°íœ9sÀýa. ± P”ëí°†!-800“ô ~—)ËNžï›¾S¼VÝbÀ±R`:g†Iî¬Ô]¿Êiµäßÿ]Î?_|_Ž>zW™ËAž‹uù}! Dx–UÕÎ;£¨¹0IrcîìvxÒ�šàôGÙ2ZhëdTŠÁ–~¿¯àÉÔA/–ò KÁ,1åeí-5ÏóÚíöÂ… ·oß>>>n6›ðçaï¬^ø•Œ ѼaòDxRÝ¢zcD�DRð‹€ÅqE±|ÎˬdM3-'Sî£êë@äÖ4¤"0TËÕ.¡SÅczxBBàlG4þRú_è›wšè£Q^åeU&'ÁAã3Ò)a®…9>´¸-„‡f¬¶¶žkº }ãÐ×cNë�E¹/¥ß…žG¿ßÃC] AÜÒ’E`<pn0hq£º,*£Š«:ÊÁÙrvwu÷E+O”/%#ÙÜþèÃEÉq²ßîךlåÝi¾8¼[’$©ÕjX] rß‚Gú±$pz Œoã²$Š ð´°Óïít::„u 5^ý5¤h¸kLX3…Áâé×ñ4¥ãèŽå !Ý¿yRá‚i³¡%ÂÜhŽ2üiDð<ùÔ§äã—¢cÝ%¢ÌÈßuéè{ïE÷ÛsÊò”<žç8ÎG|ÿ‚^/rœ?Î<…YF ƒ˜ E¨’(wnwÊCËôöô‰'ž¸êª«ÔB±¢xnáþï”í9rXðÙ:u¾&0AE‡vØ?ÿó?ßtÓMùË_Ô<Füô<œþÌCë•™¸ÚÛlj©¬ ÍÜu¹kìT é‘›gzË 9o"Ùä1R·œe£ÑZ«¶°@/˜{¬lÍÂɨu@ˆàÞ›¾& œI±=vñ*/8'p—ºÝ ºeYeQ;¾æç~%pNH”jW\vØ •çÞY4gÚÙ»8£™ ޝ1À”vÔÔ¸¶Ûíò,!F‘Ø)ÕÎÜ8Ža„£?@Ø|ßß±cdž ¢(Z¯þÍA¿Éóüæ›oþë_ÿ:44”$ÉØØX¿ìC—Aw€2Ïó4ÁÂáÈSP* ‡Â»©€®%VÃ㆜PäAÀ 8 ¥Ê6w<׉: Ä M³´ëì Yµ•§¦,»5-j'jB£ì,¤ÏfNKz…ýi·ebb— G#µ±ºúl¨…•·ºªŽ/НÁ޲ôÇýçkµÓûýšëÞ$–ŸÁÁÎ]l„3UN]åå§åÑQ¿ß3»tÊâÄÂ?Ú7QH^R8ÖYMÓï÷·mÛÖív§N.3C磦ÐA6Å€[e㎰úaòã=qìz^-ϯ 0D|µ€2nÆòõÿY<Kciê‡6OªѦ13µ˜°Ž’€ƒÅ½Öw¨„…ÆÝQ·ñ®†XQi}ƒ^¦>± `À`1!)#œqÀy˜¥2;kä†ð™»¥_411.Üöp<á8Žªë3Ë2Õ¤Áípa¡_4>>¾~ýú8Ž/^\źuëüq $LkÖÀœ€{€0}‚àÇœOËÀrâÓÙéeΉ ö‹>Võ.’Ìè›2Íh6ç V΄Ë6rGå, K@å\éâšÑUå7Žáî;²æ¡µ#`§òô¢èÏg?+«WË 'ìBíVsamGèIë»ßîûŽÈ^"z$"âÅò²ü-tÙl­¢ÁCìs¤]Y–yë½l}Ö»±W{W­|´,Š";'Ë_žï ¸Á œ—>€GɤD×FñÉqyU© ðN§( Y"É˒袧Û�sXå<‘z]÷*¢#/Q­X±bllìŒ-[îñ¼[}ÿ´~ÿeŽsó`wáÀé€p‚1rÌüÂÌ6ÉÈß‘òtÿ™Õ0e¦LKp'‰Ë&v1°ä`cq,gqÀl7‰[ã^1Óüx ±x+…Bdè`ãôM£Ä8嵃ÂS;Ìkg6ˆ¢ÞE– ã8I’(|EfÐ9޳qãÆ<Ï·lÙ¢8'ä™Q``EÓat‹kÀ© .8ê6žñ²¤»ypsi ¨¡LDþ÷7«I”³¨°ñ±L“c_nAA›@—«¾ Øï2:Í$l,E¼  ¬úÁ¤Ö‡ Á†A]àçÜÈ|zõrz=ùÆ7dõj9þø]k”1þî‹®³Žã\X–ŸŽã¤(ÖTU†{¤éiúÎz=ŸY'Y¬J\à¸gG,Žõ}¿;Ö5ÿk~ü͸zf%"‹ò5É;¹q zËLËÆ@$ËúYõpU¾´,Vý }UñsŸéÊÞRõ*g³Sz¥ ¤i #8œ¹(wÐÅam¶%æBÞ•å™Î½Žs½ë–UuqügšvËò à Lá óól^–}>«æT•TÁ%s·S=Z±w€õZ»³Õ‰f[Pá„_�W‡3íà¤XUCÉÅßÂÝ`fåËÃÈó‘ƒPPU•cÌq"Ïë÷¿ÚhL Fy ±Ï#Sõ©*´ÅŽÕ-¡ÄÅÌgaê ÷µZM?&UµÃ–ɸ0]`’$é÷ûNG¡0HáiØÃêÒÛœ;w®ïûãããªk�a$4ô«£(ª×ëØ,‚"qHÅX£Hß&»o`‘ƒ%Ä8Ú$,º_D_k›`ÔŒŒ4Ìcô /ÔBnñX tÇbêàøèÓPw"XhãFØ÷ ׌ìJ•ñžv$é²”o~S,Ø…ê,K–UñeàÅ:­Ön·GFF’$9'.HÓºçM–åªêýµZ<àk2®Â==œ×–†´%ÚTc<+ë§×ÙlÚ0.D5 ­O¦›?wŽ›œ”w”UR‰H±QIåŸãn1`Pzðd¦˜ CÆ*$¬[ì>”)Už¿lݺuEqmBuñü(úx¿ßÊóÿ¡,^KI§ÕiU±¼h¾½Yí¨ò<OÏJ‹³Šòg¥÷Gš˜€Ô8“e4Éâ­!Ù”çzÈøàl–a3˜T88€~¤iªµ…~Žnx}/Êîëõz qpÇÈbÖrï]Æ«Êrß²ü}ž–eß6fh¦H6ËÚ—Ì"ä|Œ'Œ%Ás£˜¦bé?–IÆP”mÁÜÕ;íõzªìiQQ»t»Ý0 u*­ ²,«ÕjàïiV¯×}ßïõzãããжP‡Í¢¸ø³¼�¸L±,—X —ÉlBBËlKÁ¼”,Ìp€½€’KHv«eö ƒ+·.F?Gó?Tl¬æÎÓÓºòRU¬FÝ#PÁàu(äOa‰�=-ªœ=÷”Oܵn€1Ε0lÁ£Â�^>ëºï.ŠZY^†Ô&ØË,8¤ç–>û ðÜ(ó¦Ðaæ„É*[Ó5û¯MíÚZ~JnšÆó<çëNõxU™)ŽHL3CDÄWèc<E�vMÕïyn²¬?×užç}cÂÁç³2tɉ8R{w­”)œ$üZXìUáŸCÐ ˜ff)– áà9 zŽ»À)¯¿ù,‡ZáÀâ#†3z°¨Ã0Ü{s$Ù°aZÄØðÌ)‡9ûÖ”eybš.©ªÏ×j"Ræù{z½O Æ  b Í#¼aÕáv”è1IPhY©. ðaÊh¤6ù£(Ò‰”µZM%¨UBCN·Ûíõzz’꽫 ÀtçÒ󜜘˜˜œœ‹Kv}Úk™˜˜˜Ý eUl.M¬W¤/<«À]±Ù4b˪ °VÆäYâvöÓÃÌZw³·’eŒÂ ¿¯‹ÓKÖßãu ãyb)²ãÓh.gW‹7ÈõtW yRYóØÝn÷©§ž‚úS§ª®pÝ+]w#AÉ̆p ÎV‹¥ÉaFM«Ø1@ňq–aª›GÃ^ðýÀ»Üs.uŠÇ¦õ†a¢Œ%ò›uµ,`cy—ñpˆ"W7›Ïò¼cÙuÝ%É}¾ÿß DRÏód¾'înžç‹-:øàƒW¬XẮ»Ýuotã7Æ,ÎÍç,Ï�qÏ™;Rº½µ(a¯ÓІÕ#Ï:eô9ë©Í¸Âðz†Ž³Û´5s„¬Ž®ˆ¼:M—sÅ`¬êw®{ï_›XÆ=�� �IDAT<ð„U’´¾ c èi¨æC„!2v9š é T[¤ ¤Ãº’õ~±º´ô×\'¯"½^0‘¢jXºÊ®†: ÖéX>W*8©±Èuüeöq¬o«l%9ˆÍ¬Z«Ç½š/ á:&føùð„)ÒS–8“Y&jålCŸp¨Vå"Êj’ KFìG=©ý@Þ—]|øJ4`[sOGÆÚ®óÃÒœŒøs*d;(Å«†¢0‚2Z èßp*4¾c.ëPFCXw”.Mà<3ш¼a_A— G‘pˆ Õ¡DXlž�ˆ¤¤+êmö=ïÒfóCU’Ü–çïH’Û\÷ ,ý›–iµ¸ržrZs[ÇwÜ 'œpï½÷^~ùåO<ñD9RÊ~K0Ù@æO3ºÄ|º †K´"YŠ2ú4ºÝ.þ“U!ñ«·ö3JI][·nEgB ‡pž]ÇÛ;Ž_”e…aì8Á�ßûkYÞbÌ»z½ÿ C½ZEáÙ¥ }8 E¬ýÅ&FhºÀGY?3ËHV´àÐ�Â1)œà+ã¹^¯««)3Ô1„´aýlÍÇõ×�rôÓ è;vè@ °šd0­©/H³"ý-CÁFѶB;‹Ûª rAüYÿ“Þ2G)èY0Ó €$Ü7˜0b õ¢ZBüã^£¾Œë¢Qqq†ï@¨ãV°J„=�'ìôÈ׃‚ž© »CÎ?ÀmD ϨsÉëðå <KlKLwóœŽ{¬=Ö™yÌô6qÒ ÖœÇåd¦Ò”ö˜yvF¥™÷‚µ«Y?æ$Ø)„Uo?†çÆñ~Eñ¸Èõ²€fëЊæ&–ÎNMNNNU-Ž#ív; í[·êÎd)ËÁH1w ßgûde0³Ñ®ýBnžŒ£ê†w ¸ SûŸÔ/²„ËЩ戋+¼V»Þ˜ÓòüU59ÈI_›e{WÕEŽãš:›ªÀ,�K˜¶1èŠ6Nd”‰ ¹°ü㈯Jý×¶’$Ë–-ã—«!Dᯑ‘Œèãpç6aUUív»ªª‘‘‘‰‰ È8¡a£©½åXÁ ‡ú±š™~´Ü©…ÄoÀ …R�û2ØÀš°:ç¡7HT°\:€>ägоb¥vÜ+.ˆˆånc‡r•iÑC,(‚Ù2˜cÕÛW´Ý!gg¢j(Qy“[oѲõäõDƒGX¸Äæ…‚a,q¶CGlÀ_ê^BÑÃ2ŽzIàÚr `óZ0d¶‚E@[ã"r|’ÜéºOЄ,inl"SûB“eÿ=À%,ûÔ)°¹ë¸rÓW¤£7Œ^wÝu<ðÀ¶mÛ¶lÙâ,t’ç%ѯ¢V«¥cxø³Ñv<d Á…årX"3xÈ€ÔàŒ�ô’-Ÿ™Gk ÇXÌZˆž!WÕ ¨%E½^Ç›rçVÏ‘¥éÇ]WDÞ˜¦sE¾†ùÕrå ¶+·�Ù%–Õ_Àƒ°|Öñ9J»o™÷L>AD:N»ÝFo ŠmÚÎuž'R1ü¯«hrrrÇŽPâ`¤�Ìå°ª›0ñý!·jV4D±z6h^‚öP8±Ù5!–#ûäv Ö ¶6 úf, Ô°g({XàšÁé°*½ ÛOAsÿ'ŒE$¸'®¬°;äü½~"?ù‚|ADºe<¬]ØóñÁ¦ÑÎç÷§û–•uá*¿ Û•a"™eÀ�îUð`#Óxsjœþ€Ó-/€ì akiÊ©Ûé˜$ÙSäUýþéõºÐœ ³°à²£ðˆëº™Èµ¾ïd’žnEQ˜Ø88Ùó3ùoyòÉ'·mÛ6U¬4¤\UÊ]2ÜV<v–Æ"w­0êïan›Y5ôÐP aL„§ðp pS Ãçø!':–TA~ rÐÌô:¡?«çMxÞ׺Ýßúþ|c®Š"wpñ\—ˆ )ÑiÌ€Õ7ž6c/Çë`¥ZF’5>©ÅîNÏJd z Û¶mËó¼ÙlÿAo¦Óéèr]?ADdûöícccã·~Y}žûA–ƒÙ´(ØIy„æð!fŠo™ ªóŽÀêBPç‘ ž@©‡Á)}lÞÇ«H/B£.V`­wÈá$‹zX±7¨»Üí^Ýuí†ß }ßOH&ož ߆kCÎ`v‡œ¿ÓÏòÀ©rêIrÒmr›ˆÜzà­/ýóKåj1?2’ˆÕÈaÙAkXË”¥P,§š€rše 9°Ì]뙨ù#vp˜Æ#Ô^šˆÊ|ßòlçšé˜4=0M/Œ¢ ÝþÖØØyÍæ&²“ÒËÓ¢ÑB!2|ž¤â¨Ò0éíßä›å&¾5.>ZdÝLDòwæÅü"x}P:¥zÀsÌ -¸Ö±æNðFØ•„©h�Q¹è„¢B>ÓdáD©\,Ögc0MO(øî�_-Šâ®4ýZ“çÿU«còAÏÆ2¨Æy¡¶7ÚßFïZÏ,¨ €Ïh* =àRñ„uèé†, ­;Ô¾zGqOLL¨ƒzHFCÉÍp%‡Üªþ}§ÓQ£# ý€S€l�i;8]Ⱥ0ãÉD ÀÏô!ë•LLL°›™–š4 |ažFtQ¾(÷A9F©ôµ¼æY+‹B‰?°#ŸU‰b¿À¥<„šx#ó”÷†õ½÷¯î7jVUå{¾ˆø·ùÞ7½Þozþý¢³Xû»ÿœ*§Þ.·O ÷¹µcjé·ÒìO™»nZ4Â"œ`M`;abÚª0,é{¶âPŒX›"@ü¡ùˆ3Ž•]t'ð©:›.ÌL$tÔÁãÂ/0—‰µÙ-êØ$Ù¿(¾4gN(RŹQtf’üÈ÷"Ú(ƒ‡úX ‹x(Ô1[·à}Û««ž\¤sRÇu¢K"g­SùÓ`™˜ý…oˆ·ëÃA2Æ0ˆÑúÖ3xøÊÄÄ«~…ö-Ð…ª<85âŠ$€ë0Ô©6f%€„aø`U=èyf0e;Q~×h#Þ‘ÁL;—­Hð| Ú­M~y ä"EÐrŸ«=oðƒ¶ÊUm6›ÍfS6xà:®)å|ŽëâçAz½$ÎTXìü^ÿ\t¢`Å@‚.PhîŒrC7‚ŠYŸ’^0ò?ä¯Â€Óztgù¬˜=¼Œ-ZÇ‚»Y –»k(7Ñ*f©@ójãÝä•E mû<Ï=×óoðÓcÓèÑÓÀ¼`W 9WÉUo‘·XYU•ù¶INNç7ØÉŠ[sì^.4|‡·Žß·kx$0´D‘p‡†…–Yz‹åXt—Z:VòŽÎÔ,@=8¹ôëô=>M÷(Ë‹ DЭ¾ÿÇ9©ßÿ^£±™ÄÐE]ÏüV«íÉ,*ó‰éGÄ⸬ƒÎ'ˆl&†sÁÒ …¤#2+u²47½ MÏZ #s'�×�¥,nò±7Þ2§É|” [o6›Žã¨lJ%Õ­à©XÜ_¡ÅufçcÖféb&°�G )÷6 ίGg–e£££–‚ hµZ WêXžçý~rrR)¿ì®‚9§ÙWÈÁ›gP>¢ñÃÚwJG´\Õù@Ÿ="ŠÒkŒ{BüÒ™»ˆg“ÈPEd¡iE†^¥¬{‡[÷ˆ³×™¾+­ŸQ7Ž©Õj‡vØÂ… oºé¦ÑÑQÿb¿÷‡^xMø4 Ø•BÎägÉYwÀó<ó'Óÿl• Ïè2ž‰@{Y …« Kβš9R®¯ƒ Ò ?ÕSÛ¢f1ȃ‚¹’¬‘¼™ŽµñàZˆ³¾œwøþ':ïTU8ê8ÏJÓ1ߟŒ"‡,5ñgú˳ÉK%ê~Ó3šUëQ²(Š0‹eÄfØ(:-Nª¥QÍzï\+ —C£ˆ ¢ñÐn–KšÛ Äqï]f / ™ £“ÄCB`ô¢Ç ]–c•XÜ/ãÀ\1ÖÇȤekMMb¨%¨ˆèì§^!²Ÿ0 u xxx£Ti@’æoAaŒYaúõ8æBeØðì$­R@È ÐŒáÀ†ßš5GÜ’1 e–ZŽœµ` ë¶Ò~à¬/Ň#öàÌæà †k;Ðæé °JPç yÏK%OŸ]›±Æ0hûÐÄØ¶ž àXŒ~dm–N Ðjذ3ùp¹.H²o pv!9BCÑ+ä™2–„‡šÀ\gÈÀ»ñ›‹âŒfóŠññ϶ÛŒ)ŠâÕiúl‘/7›å€€ 'oxÜ”^.@ÿrgèuꣃW>gàh·èÕ3åÚR=±Ðs˜*b{s‡¦( •â×bo„sLrÀÓÌ2)稖$‰"`§ ™iÀÅ`=¿½ruhÖ.‚žÅÆS‹ÅŒ`U Ød)`ââù@Ô÷ÎÊÓ¬«¤/Z§‚fäÁ/°ü5‚6‡…ZÐè¿ÅÃd‘'¦Yâ 0/O ºSØt@>QG2•FÈ-Ô2—c«M05ýbgè@Õ‹ƒ5Ø,H5X<Íp#¨œÔìäoKå«9Žò˜§‘XŸ€(]×õõÜg»Åï‹n·»fÍ×uUÂ?ÀwqØ'twÈù{ü¼L^ö;ùÝAr1"R¾¼ôÿàcÓêX€.,N<Y% ù5à @˜¿=F× ,`;œuP½XÏŸc â@ˆ£º¥‘óx“_Á²caÝHk4Nët®‰¢ÊóUEñ¥V«, ËË€‡?oôØ…`(³k8_ÆÇ �Ü,Z¾`Xk�=Öù’е†¡ÎìcŽ;%Vc *à b.ÇŽaäÄiBOž?ß2B³M+N«y®«’K�Ù­RYjÀ͸AÅî LsÂ?dkm$ËÜÖÖÄ\WL•8«à&"úùZbdËz„|ëIZÝr«†œþlš»€bŠtžëc4èŠR…þ@­²uQé«×õ†D„¥àˆˆZ< „ V‡bî R*Ù‡kƃb==ëœáŠŠ�F ‹¢h~´¹ãÆ—5T4Ÿî»“Ó»æ§?ÝE•bd†àÍ?üÏÉrò÷ä{Ö_º®[œRøß÷±JpZJ‚PÁ™ŽL_Û’XâLí^õØóü G€áp4p:À$NVgb£h…xçpG ¤vuc¶óÃ(:>Ž—‹\:g…80Án9…�øÖ'Y\ü™!ÝêÌ¥¨X«Õ4„Ü«ÕqÿCï]#6!;¨rŽý^Ub’µIf’–÷‡ÕAœ}pL,9<X ÞDEk)î™ÕÊ@tÙêjà‹Š[8Ž‘J#²X—<莻Ei“™¿LÒE0Ö-À-.¬CP�ðv˜‚;B6®¦Ú¸€À.Ax×X–L%‡†“î5Í ¡~×v-gÁÐÃH,SIui¡AN6›…·ÆQÁoæÛä䀅Eôq¢ÿÞäÜfÖEˆþÒÚwj½¯öò£§ü,òCòì²Ìýµ[ö§Îsá…òÔSrÅ»CÎ߉Ap¨z¡\˜I–I–vþ§ãÞæ:O«¡Í`I*aIáá¶0dØVÉ,4yN“;¥ìBÆ­]yªÆ%tn@¨ÕßgíHžÀD2X–áPc…a¸Áó¾ß CC¿À3�©€Ÿ€-¦ÃóüœÞÂÎ9Ë27tÝÈ_ʪ§<ŽcJç}‹¹E€/õ¡&Šy<KbR†ØØú$õaZ_˜¨Åç(¬+�¹$Î2((#N` È 3‘,ZFGðÂA,hüœPcÝâsXã+Žc6Ä´¬ Z¸cI¨Ñ§BQä— Ë¿ÝÑûC¯÷‡^±¸Wœñà:q9N€j¯ Q;¼T<Ï‹¢È <'túWõ'o™œ¸e";:KËÛô-.Ðy‰‹Z–Öýÿp±ö ž<T„ˆÈJ�ýðkðé`þhâØï¬@?àþÀ /ËÃÊôÖ´÷û^ö¦,¸,ð¯ô}ãGAð¢Øÿu¯“3Î8–þPvÁ±Ð]¬—³Ÿìw»ÜþSùér„ˆôîíÕ^Qs§( ¤Wœô!çe‡Gæcnf”@× ü‘Øëšg9Y‰KI¨Ú.Ræ.cLZã¿çA`ã™M&Øð2…½ 65³ÖÏß®m­4ÅÔ‡7+á£À·ÐyåõÛuR¯ªªbiá.sûîKKĈw…çÜç¸÷L; ‡Ÿ.�4*@ØcÇwø3 Uÿ!H!PåkVu;F,-x§^X•™ ¼9e‘\€E0a§z¦3 á}’B¢ônã8f >ób–udžzH¼)ð Z€bi{ ç¬ëºÅÒ¢ûÝ|¼~D]ŸóÄÕùÖ<¼0ô·ù8C-/"HÏóêõ:ÊŽcŒÔ"ßOgõ"~{Ü;¶W;­<”e™|4)ÞSxï÷œ‡þã¸g N®fX:lùÁÅ«ã8 .,Šbdd2T €ó’`x��²ª4EV”ç2†Ôt¡‚e“÷r÷~·~ÝùœÃ¸š'ož˜Ø`Ì}ÏzÖ‹êuy÷»å¢‹äÇ?–7¼Av©îÎ.iÀp¢œ¸FÖ¬‘5—›Ë€+ ´%µÉŠñ ̓5€ªå³ ”60FŽïÂÇ&Ǿ¦tfý eÊæ.ø:®½tG¡£¹6R*äŒùàE«ª [ËÎÁ85ņ2ã0(#€ö° ƒˆËŠä­Iüº¸~j½ùŠfûض‰Lþ¯yyl‰m waÖöæ–B&[ˆêÁ¡¨ƒ?UU-)Ë—ÌDP˜‚¦h;~·:R !�­6X ŸÑ|~ÕÖ½g6`½^ë/ÔBŸ@±^„^—®aˆ²à`šmT̨ŠKÖlE‰~ *ØúY–EpìÆ'ÄoŒÍ¦öú«ÿ½/ ³³ª²ÞçuTB €LeRA[fPÐVThÁEPQA¡‘©Q&drlEidT@% 0$$© U÷Þw~Ï÷cß»jÕ©þþ5ð„'õƒ'$U·Þáœ}ö^{íµf:3º9*-ÁHÆ£f”‰Um°õPc±¯zolY­Ï9Ý<-×)Gö‘§ðTë›­ö!íâÛ…~¯1!ÕtL1Ý‚zBä¦i–eœOð瀯`ÞŒz%ø3Ì2X:ÝP@DzºL†¯¼1æ°²LÃð†Ng2<áyî9¹îº5UÎËÊXCÔàñfG6›Sg•ÙY­?ô]‘ù‚1 8 £ÎØü˜ dì=À#,²ÉYÄwÀ&ÓG½0>ɪ\�X˜äÆÀÅ,z­À7rCîeª.Cà «ª*^[X±Ñ ‘ LcÏó’$ùºy~fÞº¹…“%¸SŠÍ&»01Á4ò¼Oåù2Ï«¬½?Ž‘¨r³]HÞQc+òD~¤ÜíC/ }>'GÁ"q´2u1pÑF=ÏísÅ":ÜVawNÔ(¬. ú5;W‚™ÂA”üáX$�‡y]¡çÄä”Á¼óEåWáƒ!ŸY–Ù¬ÝÆV¯¯üÇ|PêqÐ:NÏ<ÛÄ>{¨\UQ0 ž[`ëêèúH‰yúÛ«ª*VáMa½íýb’|ȲåÎ0œÃqHÓTÏ~ò8çôںݮ §hyÆs¤¦‘bªb‚rÌ?€¶2­ÁPÀ6Ä4:Û½àÂÚdFú}i·×ôr^¾/Œ’€Òªï•í#µ>àí¤ ;Xd,vÉ|$](Œì³ü"«¾Ã™8žÓªÅµa[b9jí¢>ó ^“5ªpôÄ@ÜäÊvOPä}!ìF™"#�—=�‹æ˜æà¦óƒÛ*‹ˆYl‚›‚òð’³ËÐZ2‡ÿƒK9‡ ÐIº¦¹(MÏ÷ýˢ耲|í»gÒó¿àži#_1&“&@àFщ‚óF¬ ÌÓ…¬qÇ“ù ï¡ns¼e•‘ì¸È`ržŽ¦BÈTîðór£‹‡á Í@^äÞ†žõ­ÿœßjµvÝu×<p³Í6ó}_žñD6œl2)…tŒ&ñÊD±Î´œ¨ü¬±Å6…¹×cfΜ©þÍžçM?7ÛOéĨïzZœ=è½ëkMÓT§a -(ÑíãÖð!Ñ<®}QéãE"ò¿r7À^Ë@ÏrdâËàlì ‘¦®Ì2ŒÊ7¾!oz“üË¿¬9r^Ö*(¸[ •kÒ0ªË:†È³8öö,À1£ÀÌEÁjC<&V1Z‡¨Ü§ðô‡?‹¨ =YÃ0lµZŽÐ!¬é9Ƹ°‘س)ª^ë¼1™µñ;Û6‹Œ€ ù¾¬3©ª¹~žŸ›¦oÎî èÔ»Ð3¿ oGH4ųnÓœÙ4g´ZÏEÑ2k?EŸLÓ×Sxuôßpx󉂓ƹqÌT¡íÓKrš¦zUˆDúÙ S š8k2˳º ’8<c• ÃPÅ œ ÄÁ«ä¬Ùº1Fµ®A@`ß ™f”§l.¬$%Bb¸ª®¶É&›¼îu¯Óksº˜NÊ¢•îK¼,Ë”À¦ƒ<}#à«èh¢.¿:iR‚CªÎ¹Þe˜$¼É^·X ¢°ˆNt&CkÎÚ‹†”n·ûâ‹/b0€Ëb`kè×òØy%d{ž÷Ã$™eíÖ>(Ý®œ¾l¹¥¼ï}²ºé¼J€5¦ur5ÊD~6æ&36íô!a@Ò@عaÃ0Žcð…¼Ï'È}r Ä¢ ·¸ï;ZÀEQ´îºë†a¸téRH!0€.4$Ë,, ­]QäR€Ÿ�[¶à²{I%ææ"VÕ·âø¦™]U·úƒ^‡~™êÛˆËØÐ÷Íó‡ácd¬?Õj}±(n´öŽ¡¶¦3PÅRÙ<ÛgúŽdðÊ€t ÃJSÉm&à„`$8ñüÖ8ñRdå7­Š0lÈ95˜`<Ê÷ë€T¼°Y¤Ë ŠÑ¼‘døÏùU]5›6ÙÂìæ›oN’dÅŠÆs¿njïýŒéOàò ¬ÔáG~J�N¡à\‹¹Ó”;•É=Éøøø¤ßLbêíêàp³ 8#ÁR0‡ ¸ B6¼…µuŒøÃ…Ôµ™ ¡®©<ÎÕ6'¦àé(`+É´)é¢(. ‚÷ýá;ŽË†Êþû‹ˆ\{­|ðƒkªœ—é‹§4nr³j1 qEÌ…H÷XFˆ†š^±¬hKÎ8ºÓs„ÒÆ E°ÂgêÄ Î9\ƒnW–RM@÷O�n�Ðô!æsG Û�ý$¬xžq1ÆÈ¸·Õ{“išŠˆ?×/ßVÆ¿=Ï[ÏóŽ(Kßó"c.h·ßÐ4{ )×Ìüa)ÞÿxŒý²lDÂaA3(2|¿mmJ„ZnpÁ [¬VÞdûj~e¼¨°$Àfb â,Æh˜\çœ1úÒ³,sÜ @Œt$ݘ½‚ÑVg{­ €lš‹ ž2;€½YuÆÃÅžçE "ɥت(ŠbéÒ¥O?ýôøøxUUÍë[[ï±I>!6<R\9šn@ýN­h™NƲ UUùÖO~›¤û¦Y–©Ûéàhi™r÷2¼)ä¶Ê&VèFȲŒÏižÒc§W¦Þ&áÔëZâfgt Z¹ïp*Ç1?öÚac*&×ðRàuÇ/o|£|øÃ""§&ccré¥kŽœ—µÐQY-„T¥DóÄ5£œÓ1Æ 0[Ñ1HçýïX_àá±O™3ìÆ‰’.Ù4MUÞJ�M,Kãpí²,[¶lÙ’%Kt_Á†˜x’$8yÊGQÀÐ<“ Òé%ðó Ïÿ‡oßd͈1Þ _¶‘õ×ñëukû°móÍ~ÿÂ0¼Ð÷Ï2¯ª~ØjíÐ4oošpêŒ#šÂ}½àe"‰üK]o=ü¯,ÏëvÏ Ã‡£Z/ŠÀp[‚ë�:Ç! R¢>v8SpâÌB¢A4¨ékBÀ¡<¨=²¦2pKV­ç‘ÖEôA È'KŒƒ.…ª‚•~øLB ¿ZûIø~†ž¢DÕžUï½*®šVSEÕÄ'Ê}Êä²wÁY9¢6>Ç3—éX¥º­€‚„984’2ñû‰zËÚ¶­mÛì´lüGãã:üëXÕ›­íœ´ ¬B0!‘ua2Ï™eŒß ŽL`…€ ý$÷ñÁ™—Â�º Õ€…±£À+"²ß~RUrÆò–·ÈG?*e)×\#«‰•Îjï ʬy¬'V‚üBóÌ{†•ˆa ͱÎPKñ|([þ±Ëìô©–èàCŒr^Ïs<œÉ¢®ÇÌ<£aÌûu:F/Ñäp<ªqãZ±=÷“Ñn ¯ýÎ6ë6Ýë»É¹‰×ójSÙÌläßG6‘æs½ÞEƼàyµµÇt:gÙ·“äê(ú|–=EéTÌÓ±je•_}›+=ïä ¸ (.ªª›æDk¿†O×µ/¢…,Ïýð'èŧiªI ·ÙU«qrêhóÔ_Ûoê¦zª ÐRD£… ÷™Ò4å).gÄX“Š• È#[5vŽ-ý²yºñŸõ¥‚ºj¸éð‘c‚®•œªÏ I$I¢×É= p½@¹ö‹¯²,͘‰?×3ëþûÖZ12r؈,›R+èÃiµZpÙ™®-„Ù8VÖAçZAoMcè|á�� �IDATw½¢N.J¼ï{Ý »ÍF1¦ý­¶ÿŸe¨x ª€LãÄŽ¿aÞQ<†‚‰…š]a‡¢øÐíÀê‹ì^Ác¶Žg#r\~³z1܃„º–ë 2ôzrÉ%²õÖòž÷ˆˆ|üãröÙrÝuò¡­9r^ú�ãZV,±-áü¥.¸­Ð¿âé–uaN«P#÷äC‚½a€íèna; ²'.÷5¦è$àÀÄsèƒôV1_=ÏЫÐì‰)ÿ2”³UÔNÏÊà˜|Ì0‚¹Æ„W‡ùI¹a=Ï‹/Œ½Ç¼M›ú ¢87IÞŸ¦³Ëò¦ ð<ï‹­ÖG{=kÌ7£¨;ìðCÇŒ·âôT N'´Û'õz™ç]ßj½ ’à··ó  ÎxVUÀÙ9ÅXoK“ïÛ9¶i5"Ò¬hê~^J)`µaìÉa<;£ì<¹É9xæKþžÜÌ1MÒTRÉ„”ãerebºSœRqGZ¦#gño}A8->Î4$P 1I˜–wtü´òkš&ŸÈ[ïm¡z6¾MÖ>°ÌÁ/r,øp/ŒÖjA 5ÀMØ5£;“|¶Â¦fàšIbzŠ@ƒŽË/<.Tù"éUpjr„C²g(Ô(Àr‘ý m¢,!gÐ M>0#x m°Ì.ºH6Ø@þõ_'·Êg>#çœ#?ú‘rÈš#ç¥%IƒÃä+V¯r @3¶gupÕ!˜ÝVÐå†hƒ;±† ˰㨃…"‹ç ³÷‡1„ùph?#â8ßÏÈD>ÝèEc‘[ÙB +2Õh¬½ÖY­ÁÎ1¶1M¿iÄZ¿®Ï¢ÿ°ÖÅÍQä‰$"WEÑ‚áÜ wìQ•Åcç¯~QœEó|ÿ¯¾ïMÅ€eX ä4f´óˆ®µÖ¬kÒÃRïA/üqØZÕjš&}n·´Ù³Öi-í$k”Ãxކ0 šŽ2BÛ È&¶8®ˆˆåW" EDª-«ê Uþ…<ùBÂÏ–Y \[êäËÊuB¦ `?22¬ým,`Dìȧ4_ ú¬Rît¸Må°;&Ttœž1RGJ´LýN8z°«)ËðDT¸Šâ.=Û¾ÁN/†ÎÀšcZ؉Ž®_ 5–6àitŒ p6ÉjFÚõDêÝOöôâbAí‹õè訬ZåFÃeËdë­×ôr^ò*‡MÀ¸‰ P) « ³±L•GćëÈG+Ž&š§£9¯@0Ÿ¬b¢ë‚êøB\Ð(�žþ>sPS÷ª:ïì°|w9vÓØÒß,]~ñò¦ÓT^Å#AÓ±6ßuœ›ñÛaŠÃYrOŲ؅;ð9‘ïEÑ1y>Ò4—xÞ››f§²<£×» I#eUÀÜ(û8@ê-CèL_ÍŠ ¸¯i´Ó—ÈG2œÑ VKϮתem‰tG6Ùd“õ×_?ù{â]çÙ·[iIQЉ¡æ1×ÖHÀ±*XábðÒGm³Iÿ46Ï¥Ú¿h—Û–6± Ú É¹â²Ñc``Íiq¾ =V2+ËZ«Lø˜ÌÓ©|àq[-MÐÚÁØ£3Æ  o“û.¼ÑdªP)€x×±ÅFÖ›Ušv=wÅÐÈá ?«ϳwØ>ØÑB.Y˜%×O`€é…x5@8õÓ”AÀ D¨&ÐcMX^Ïòoÿ&¾/W^)Š–¥|õ«²Ë.òÎw®9r^ò#Çyålþ‘r$¿˜mıD#¾M`¬)¼Ön·UóÊÁ›F8f+h˜`éO¤¥Ì–ÁÖ> ÓÏ¢(5k˜Q<«\½±Zuɪj«ê5ï{Í:û­3óÔ™Ë/_ž~<­:Ì@hÖ8®Òàb¡ÙâúÚ�PX$(̬Àái À8¤rMÄññ##_)Š ëúº0ü`QéyKIX™Q˜ÞÀ2AŠ'X!oê0ýÔs {oYþ¬?} é¥í£ÛNgçw>ᄎ8âˆ7¼á q·?ÕîŸÓ×õ \?JE3ñú´¨¢H'y™ ¢—ÈØ»¦—”("¯W«7˜šôØgˆk RlLˆà¢¦,ÀýÅ0¦?TeùÆ<Ǩ™â®(XyCûJÓTÁ+T¥hœ8KpÕ0Š„]É6Ûz¢¨3 ­½X¥†ÙøY<RˆÛ²f ‚;¢3»Ä¢†wŸ“\¢RaAwî�]Gÿ_¹*€Ù1ˆÃªç(:± °ð€ñâLJ’¤Ýn#·ÀÎÕÃv“„8–#”+äškdbBÎ;O¶Ûnµ8o^%Œ5À>`;аì"̬JGC1te.± ºšŽŽˆóÛqŒñd5 Œ…"¥å a\› zfÍš5sæL=@ŽÐõ×ýJwÖÇgž7ª¿:Y’¬}ÐÚæ5ÆßÖy ± R«7×(˲ßï£4lµZÚæardT`*Œ8A6æ#}±Õ: ª.Šo…aªÇ¨ænPmaìK²`è‚艎÷ÂãDøA^ÁiÄØŽLs%ð}_Œø¾¿öÚkï¶Ûn;î¸ã.»ì²Å[h5ã&½)twY÷Ê0�d /dîú­VK§5yEqGÝi–‰tzÜ ^ªÙ:²’õ§>T–﫪=‡mB[Æ©ƒ%Á~9p8Ô¨ Ã$sì]è§ñùÁOŒý§¹&à"•­Ø0í´Rø cdŒB  ì;Àø$švŽâχ10ÀZp¼/dªý§e,6Ȫ6úš:N§Ó7¹CBÉÁ|‘ã—•+åüóeãW# ‚Õ»—ƒ\ƒ…ñâ£(Zgu–-[¦ZÑÖÚâ EöÉÌã­òF>;Âh§{Ž*ډ܅L £ö�”5¡æ€ÈÒ~hÀ8«5p›ªªÆÆÆôUóCK«¢(²²ä¦Dú22sdtt4Ïóñññº®Û?n÷é·iWiÅÃ%çqÉ<êJU?dRð„®Ü÷/ošVÓ<åyùÔiç€Å±ÍVrƒÐüN))m`Íã&>}ŠX'^‡#m�p_ÿvsì&‰$·×ë=ùä“O<ñÄ¢E‹žþyeœ;“›UC©7v¢ڣqÇín’áÈË Ã3“‚ç…™ÞÆòÎD-JX]Æÿ^–ÈyQtxQApi a*�›b7Á»Òé\ž˜eç*®É4;ƒn„Àmæ,èì¬: ‚%†µú¡ÌåÍÈ |ì¡iê˜b0‹9ßl«ãèç¢|g}ký&¯ÀFE½^/MSPXÁïàns _Ÿø„Ür‹ì½÷j´_ Œ5äJúñ†¢(ʲ̶mï=o‘7rúHÝÔv–]õ»UÁ‚䉔Âtx@iÔC,pòÝÌÒA,ãáaNÀQ3,Ë(‚øoéÑÑú`0‚³uÕùSgVgÖž{î¹óÎ;/^¼øºë®{þùç£G£U[¯j¤aK>$pm k(ÊMÅ üÚ�knð Âx'£R|¨¨¬ÄH÷O~rVRŽå‰I@ãæYd¬,®Œáͺ®ý9~ïg½ðÖp䌑º®óMóî­Ýè;Qp[`ÅÚÌšÔ8‰¿Ã–ž>8 4©®ëø³q÷]9Y~ýë_?üðÃý~Á‚EQd_Ï:Çv¬?IKL‡F#õ¨ØtöL0öí·óKòöÇÛ i ¶ßirl—è«KÑÈè°r.Ï­#¬CÍîcßß¿ªü0üi«Õ-ŠK“䤢˜(ˇ‡ÇrmTiN\cÛ:^Æ€j­æ"ŒêºBÅ.Ô<O «iM’DUs`ÄîØòâDZy1©æ Wà6Ét,ó&BV@¶„'�ØPžz«ÕBEËš°ããã aÝBŠ ‡«#¢1øZ­Î›WÉ\ŽÓš/0½²,ËE‹éÖí^Ü>…‹Âº®=ã‰H´ST}©*v+ü›}ÅRtÒBÓ+gþéÛt¼¾/`ßÂߌý ÃY-ŸXPc·+Mõûu2�ËÑó=íÍlµÕV¯ýëgÏžÝétdªü³vYxƒáú1,0Çéß궇¬:ºVž &ÆSxå>e~T^¶vm5»6õnõø3ãáÃúÂÚ·>këò6æö€ÃšøÙDg÷Î ÍlL°40_1ù§óüØÜK=ï>ϻ݋î‹Lf´ë¦ý!‡ ÈaÆFêºözžïU»W‹X<ñèD]×é†i½aí?çËå6s¯¡Â‰rÖáMM÷¹ñ<Ï{Γ\Š]‹ð¡,±›Ø7NÔÇ"çÇöo‘Çã±(:14¦w„åÇ“h­CÍ×÷/Š™UuI§3gt´%²téÒ“Ãðœ<¿Ú÷ï¥ËŒ^½e-,”$âžê¹ˆÐ9]¸šG£´[®pœ.�ÅT!°Ë·®©®pßy°Z‘a€äðàWÀãzmL.gö)â>(<ÎØ¸L5J‡ïŽCTa» Ž0ÒÖ_­—Š}„G§U²v¶T± ÒDÒ™üúÇ?dýõettÍ‘óró¤!&ÈÎÈñëºnvlÌ£&è<•bŒ îÌŽÆÜaÌ€d’$A-ÈÙ U¶7æƒëzÒ;F,ùì„TG¨MÈÍZ0tQø@÷ÿè÷·ë/{`ÙwÜ111±páÂgŸ}ÖSîZ¶în™Æ�0ÑÄkmØ8ˆNš`‚ÁßHkòë®/Y¯9;)KvNdW©>[y³<[Ûø;qùñÒŠõþkp 3jäÀGŠ)M2‹ö•ø÷1â•TöÛtšàÁÀŽÙöíjǪػ¨¶«âócü8 û𼋈 ›–øöR›} “7KmjkmÕ^âÅ'Æ0E„Å[Ð'¦g¹…ù˜w`±AªÑõ’s’â#E¾Cn kŒy[Pïûùʲä£U5’çw/¹vLÄQ‡;e >žœ9ªišÍÒôOž×jµ¶Ýv[yà–-[öP¼1ÏïK´ÖP€ÌÆ”9î–±ÁDø<Œ¡-à{ØŒ¸/4ÿ® ›KÉPŽ™ ›ó¢µ†óP0~/¿2]ü a£1ˤ>Tb{ü°Ì$äC—õO1E‡°€Þ£Aî8%òhê ð=ü°üä'EròÉâykŽœ—¯—ÃÎÁ| Ièy^¾S=…½°ökW_±bE†ö6Û?¶Ÿt›"Ö3†™9w8uírk 5Ã/B’ºœqg¬Ö)ÕÙà™›ªªü›ýþ±ýô²ôÁ|â‰'z½ž–AýwôgÜ4ÃÔ†{Lyâ‰<Žk€õÙ߸¥~¢{Të-ä'äñ·âú­uôŽhÃåÎþéìg&MÓà– ½"µb£ #çÅ¡ ATÒx­P¼§h_ÞO’$Ùd“M–÷—/Ø{ÁŒ}g4MÓ½µÛœ×˜?™ðaúÇ4<w²ÏŒËæ¤Dœ¾+0ý£MüHÜüscÖ5b%|$ „¼ùêPO˜ ©lC]˜M<á^ë«­ò-e³~³­È~6W>ÓYì7—zÞayÞ·öaž ¾˜¾Âoašd=hYÜE“•óãøð¢˜iíŠ,ëõzEQ|¬(úÆ\Ûj5Cä‹P#8Ïœ²< Oqi FÏoA*Ðó¼~¿Ï`.›Uýõíàî9Ĩ)5Kx°ŽŽÀ¡¼Þ¸×‚ŒD‹cÇ—{'eY–Љ-�,ÍÅ<U($±ó4�Ff<:dôÉ,™ê6¦9 ãÂ…rå•rÔQ²p¡œt’œuÖê„K½ z9Ìa\‚bMݰ›,8õbDÌä§á ¦€¥IfÅsµìU}¶ïN.Âu};46cF¡Íp·(yaÆÑ3VüpÅóŸ~þ…â…ñp¼xC±øW‹ƒÿ ØŠ±xå}9n:ðȈÆMä‰zãJ×ðÁýXð»ª*ÿÏ~3¯™íÏ>88ø¨#ŽÚ|óÍÃ0lÝÛ²¡­ÞX™¶ù:o ]2~58–l£fÆ›o¾ùÄ¥#‡à:“a’>ã¨ý‹ûØ®œ™:Õ0£öèféïmß߆¿ ½'&mÄ€%²ç dÍXgZißCý‘Lp_°é/ü£¯«.zª½ØóDdy_Òé^×[ySŒ1”Ê\ŽJNîpà‰é{_iÌ%QôÖ+â¿üå©Ç;`|¼oÌÏÛmœ…h¡cœÈQ É«š±>à†�Õd—]'Në?ˆ·Æ®<ê«âx8AëÇL»0qÀaÇpkw¤M{}¿ìž…zQÑi6¾â)i¾GœÂ§/Ì31à€ŽçYˆõ쑘U«äÄåÄ嵯•=öýö“SN‘,[Så¼|U‹.ó:Fo3XëMÔ4YÃl™f³Æ{Ö ›°j*ÆÜ@tfF— D…d`^‰ ŒO‚Œ]ÍŽ�`¾1Œ†7ÆÎ9µdZgõb5²ßˆì.cß+þ þÚû®­úTl]ì¸|² h»Ýž={vš¦ccc<ÿ¬©º¢íŽf¢âþ`ï@<XDìVÿxá® ûýþÄÄÄÀ:aüOÐ?¼oΠÒxYIPkã8V¶+ô¸üøÅæEðpÐëõn½õֱώ%Ï'•­‚í‚‘#[l±Å“O>Ùëõüe~3wRò•×mÖ*b„y¤Õ<‚Žþ¶ úØÃ‚Íq–¨.Ö�¨ŒtQç—EÑJ ¾MøþQt\–02‚vFNó èÈœ@æS\¿'­ëÓÂðÌ¥K_†~Qü0‚!eŽC¶þ"}2 ÞéÍ2ùX±uÊ•@¡j=sœ�<™­€Wg›úý>ØÌn`tšÿë˜?¡Àbwlaîí³F*ì-@ Rë€qxã@kõ·#,pYÆÉ%+&è¼²°¡Ø4 :üÍM3zÚirûí×ÁÝw—,“óΓ£Ž’™3×9/G¡ƒJ†cãü$ȯÌëjÿy_ÛºVÒÓàÆ@VŠJ4+ü2Õ­H=ä4tõƒÙ‰ Œ­2xZe6ÐÕøËô$ðåCjAý9j}x0©ÚHƒSžu¬Bc,Ïó(Š’$Ùpà —,Y¢k€ P@ž%¸ƒÇ<@”û—"²jÕª[o½U‡{D¤8°rµƒ–á>F±MÚ £þí}ï^¿ß÷<¯±ƒc¯{Lwî…s/^<‰Zш‰qTžža‚ãz˜.(äUêÈ2kÒCÈ1mDi2@‹Bû‚l*¬ßR:ËFDn:ÖìX–»TÕ)Ãïçt+“:ÿL'^$ }àŸNŒãÊâ’86ä¬ÃKî±¶,>–G,5”«2*®Ôñ9I†Æ.jME 4Ï`år&ß³v-Ï�éKaoïŽ7¤ˆìl÷®ÏGKUžÀ$΂UìnàD!†7­2ìÆe–¢³­üv¦ãêΫë™ÛnëÚ²­·žÜ}·LL¬GΫXcé0V$D[–eøí°øJQœX €g”½«zuQûù¼¸7Èp*süÙ¶™ Ò.ždÃ`‡h„Z!±‹ówèñAäÚ9}‘±!€,Øîêe§iúøã¿øâ‹ø€×�ñYœFËç‰ ½×†å‡pj SZ„W†ì¼€GÇ 9Ä ‘çyñ©ñÄ奈ø§øý«úÙÕ™ÿ°ßýGwÉ’%ú貓²èŒH¦ú—€§ëttسõusÑ í ¼&–áwQHë öÜaG�t;2c.I’ªjGß÷·­ëóüÒ(ꑈ™sÁì*$K¬A Óïle ï¥A…jÌåQÄùŒ†¡áñøœâüƨŸøÀFÁn¤€ó<ïv»üHuMò8m»Ý1GHŽéþ:‚ < G¼VB¡àÄ}¶ý…¢þ‹[Cƒ­~±Ð*^5o@OŽ™ñPxˆÊ�>:Ó¸BGÖÚ[ÂðÙÍ6“Ï~2.X W_-‡&l°X{ùHk<t¤•‰ÁÁŒ¯Î(·+ûê‹o¥—|"±+­°µ©ö3Ç0äŒLŠ]#]#‚¼Y.—aàì@–1eíÈ¢7€Ï‡z.N6\][Ñ0ŒÑ0üÂ.,ú߉‰ =`ô‘´¢B‚Ä[sÿú3š1qíDõÙJ®”ž×ûxúÉ4ùFbÖ6fÓ:¹Uø� È"’w6þSœ,L²=²îm]k­×óZ_nyÏx^ß˫ܟá{3½jëª}OÛ|Њ¢hµZ¸<4äqöOÆÐº~wU½Æ÷/÷ýœjXü)ŠÅ"`]sŽ+‡=…<†mîÆD.òý/¥©oíÁEqj«5áyÕÏ$r­ƒ¹OŽ+Œ¢ˆÍgå¡’©o>ͳa9KFÕÀyÓö‰bGÓ-S±„ !pÀ¯Á%Cƒ œ^§º rûMŸ’2/Pa@ƒÊ™¬Ò÷‚á)cF¹õŽ�ƒèÏ©j ͸‘A^V\Åì*S%õ™sô@šóœ%A¨~’æpè2I³ÃišÆî²‹4œ|²|éK’eròÉrá…²ÖZkz9/ßy¦66Ö²æ¢(¢¢pQ8ó×3y]òçŽJ´vþ!¸‰“+BBа`u2Çî –ì ;a? ¸ò oЙ´äRõ_ð©xóƒ3ÍÒŸŽFº¢º™1ð¡'’Ñ™Ý0)ãÿ×:´•}/K¿œ†·…þí~k×–}›­ÞZ™ù¦ZQ1~Åš£·8 *ŠgŸ±ÁeAòä®ëz‹:ýZêßæ{{U]5Û7õu먖 M€@ѼRo\ï<i!mù÷7Íæ"/ÖõÁEñ£8®§ö¨Yô•+bŒYM€™ô^Ó¼ÅÚ»‰éZkíx~®Õ:½×ût§Ã¼ sáŠ9c0—ãZ Ï– /ÐÐb„^5tÍy•âùëG)� ìË!€¡.t¼éœ€/IŸë„âûñ|` ÍÅåô’$‰eýEú¢y®y®„g³Ø‘DoP:,oN ØÔŒa„³%‡W-¤´æÌ®ò±$4ÀŽTÇTÛ[ß,Ø7²ãŽÒïËyçÉcÉ~$S‰ kŽœ—–>Àä4NÒu ß ©·xKóˆ"€l–6Ъ©.ÓŸ8‰vÊ£a†4Û©±H¥C½e€…i¸Z*ÉT-w&à : Ã©’é,ùœd™:öÌT ñèè*Î]&þd\ÿsí_b©¾PYc›±¦}NÛ <‹˜™Ç‡è‰ÎêAº«¡åe­5ÿ0­[õûêæm/~xoØùn§®kñ&³ud¯LືPY®çûç$‰ˆ|¸,ÿ£i¾O¡VI´(R™*†N/7áX~Xä°,›+Òò¼Ûià‘/FDNÔc|볎úí,GÆj=Ž}µ3^;ƒ30¶ÑS1×Ì*ë LyC’„§ËÃ8,lU^öŖdáQLa¤”ím˜ëÅY&ÿƒ•Ãìdš±±bðÄ ¥kb‰½þ ~Ëe+1¿T@±L6Bóÿ3ÜšBùÛk/És9äÕë¼yõ�k¨�ÔèbÅì´³…ÌE0ÔÜ‡Ý X§`+—º]Y?F†^;”û:Ø ¼÷¸UÃ.["222¢ �oÖ£ RvBäEŒ¸ƒ,ÌŠ"OädÂ_Ê©EÅ�ø‚g5‚Ûƒða½wmëy^ðç \TšÈ´Z-­ 0É)'³ ð*5Ê€é4€û~š†Eƒ?�a˜<¢ïíMYB/ò¦ID¾7Ò¾ªiÞ›¦ÇYûÝá}!½ÅJàœ ÈÑÿ`¿¯cò|‰çý*IŽ(Š¢ªîô}‡"Áz9ºJÁn@ÆÝA€WгaûTþbC .°x0 "lËI¶}â,CÀZÙâ¬( …‰0ø‚}> *{¦ÂŠÂ^V‡5Wš�4•y±±…—<vͺg¼ÒØ ‘ÙPF˜9sfEK–,ÁT8DCX2‘å ô“µåàç¼ëi+®õÙ-EHÉ …ãä÷»WÇpýjõd)\‹xª‘÷ž#§±ïˆIð´?Gy.­ðùøql*m²2&à wfÐd! œÀ"„$Y€‹©eàƒ"v«¸“i7v;óÙ€ê÷èºó  ¹�NÌ5ÆÿàÙJ(UUõz=†\X¨›…ÂÀûrf¹ùÃõâ•¡ ¸ š eZ9N  v©ª­½¨Õò£h«­¶öÙgoi·)ËýÓô'qŒÚHË,L†Oúß ¿”t XÐ —åaE±Ä˜Ÿ‡¡sA|!Mû"ÑÔ âú+@Nôøäz‚Îô6U·›3kýWE[Að¢ð¬½6 ³áU1.‡UÇx/Zòšd¡Ot;pÔ1 Å\aø˜écHÀè–ž p@/Se -Ûn·Uéœqf1'ÄwºQÖsW‰íá:Œ~í°Ã묳Î7Þ¸dÉÌ«êNG]ˆM¨“QÅý¸zcê£Oï ¢Ò¤jzn±š~­ÞGŠLkÝÍüvç•က~íUjÇ( Â(º÷pHä&þ¨ãd·uº #œ×0D£‹’5e¡‰�ræÃæF¯˜³`mò (7x€ÐBrVÕÃÌ1_ѧ­ÿ„!¦®²’YÇâOƒ#/3Ž˜' ýGG3ÍfÈ£wç8þ: ì?øþúu}`Q\íûÏ=÷œ~ò~eWÕõaØTœÄ˜p£Ú‘=Æ£ö<L�� �IDATÏX{pšZßÿÉÐi»kí)íöYY‰Ü;Àt<å g¡í(ˆHbì‘GÐ?äî‹çyïï÷;žW‹|°,/ŸÆZævšê8Ït è‡ó„“GÊ` � ‚†&ry<@Nдg{M! ‹É9u­Š¢PXX†â7ø'äpxðoæy^ð¼ñÐÀä„Ë-J¦eßÿýªñŒ´CW0On¬ê~ÔSpļצØ×XÕúLE’~¿vœ“þ®–A{u¯r˜$£ƒÄŒ lA——PÀ F;~Jè¾`l…éO@l1ò .“LUصZH’›O<óù¸²Ì:ÛHÐô¸åÙýü C€³ âè$¼  ÞgÏiŸ ‰Aq±¤žÅ³ñÅÆ c ÂËsá-°8÷$'xhªŸ ¯ž›ê×ÇqטÃûý+V¬Zµêƒy¾¶ÈI‚Üt±Ht¹ßÎk×ošç©µ£Wõ”çÍެëÏr åÑŸi B¢–ÅZÒ{Dh;¼,GÂðâ8¾$ }‘’\.£cœú0ZˆÃ€Ñ'LÅsíˆZ´4¬(ü+×ìðË‘)@$I¢uJjLª ‰ëà˜#À:å¬üă2pzuôôðãK—.}þùçAO`Ò¢n >Ø& ð=Ôz`² ƒÜÚÄ-Äq<kÖ,õmÃò@ÛlÍ‘ó ÏåpxBÏFÓ[í:¢ÊµJ×,Ë4‡Ãsh–�c#�ç2xvO\"—ãÃ[…ÿ)-k71e� 4Š¢Y³fÁ…ò˜·@GGh É5J@žaÄ ŸRNóP†`PƒS/XuYP~!x¡ªC1Šß‚H„žáGÍVFŽt4³¹4'½Æ÷Ÿ3æ3y~hUUuùp.‡égLJä8È»(ªt‘äuý½8~}Qì2Ìf‚ øTQ,²öša ¿aôØàžÎœIœ+Zˆ3_Ÿ«g˜ª5MsdYu}e’èÓ»Ì÷ë 8rX…CL…ke]ŠÐïÐ%ciµ·Ñß ½�ÔX°®phr8f8Àe;cd2U¡öQtµ`X °c6Êk› G´-õ^P,b,Fƒ;œìõW8H8ÞôGd8ì)4Îi(Ž(åàÇy¶On¤§h©FQ´ÖZkÍœ9“ÃÚ«^ ^UÞ·¢dàŒN®×¹^µv•^Ši×¶/XolRn€¥JØ íqeýó,±“ü2€Á ƒa&kqóp‡6@údGaΑAB[gu@cCÊÉŒ;}JY–iÎå´p²‘r‚¦ß_0Çø®µºÒž s@ádØø¸Ö—œ÷±×‘¯"C7šÆª´¢Ž*SúC��™’‡'œ¦©6„Á³ÐPø+k÷÷¼9ey±ç Y“q¦ëa›„3†Lu!­òýïÅñIyž—åƒÖií3Æü2©@"jA½]Z˜eaš>W'(^¹{§WµOž·¹6Ž-n?óýêê½Öþ†ø‡ÊË€Y;@@´`´OPa Ââ ÑÉSxMëùÛóúøÚŠõ^ð:'uü•~ØqýúKñ˜�ÉG{žç:Mì¸o8ˆÑl]L÷gLê(ÞÌœ tGXÄAÝYadRð‰:µÄQ²>ƒ´8>5L©äæ@9‡X¾|¹îàFت|Í‘óJ:ßu6…ùÄ“¿›•ùGóºSì1¢+#=?•ž$—%á“!<c„Ì?\ QÆÖ„˜êâhuh‹Ë@7‚'™…UÈý[$ò<¹ÉÍÝœEQ<õÔS˜>AžÅ œ=*ö#dÅ¡ñ‚Ù·Ó¹8Q0Nt Ô5q„V'§vèwèNžˆ³ -Vêääyrìg¼2ÐѶ՘ˆtÞÁ¯‚ ò¼"Ïý©Rx| hb©èâ-ÀQˆµïy_ŽãodÙŒé‡á/”œBVzmšXè±ÍGÇÂŽgàÑ〃è–$Y/Ëþ5MX×Þªp@ž§"7ø¾™*uêhb”R—{܇ÃsŽã¸×ëaý„d»P×uóö&û÷,| lïÙnšÆn`óoçöÏ6¼< V@õé\‚J¢ññqFÖÝ+Ÿé�ø'ÈÐaßÁþ‡[zìg¡Q¬U|ƒ®"8Ü`V}N³°ëeªu,_$ïeNXYª±Ûí‚nÃËþUPå¬öÀ³`—²™nÓ4Ù»3óÓ:¦…“›·åûKÌsq4—¡ÄºXgpää¨ÑCDXçð`G$û<iÈ’½Z°4Lkð9N]UUU¿ßר„„ÔɱdGƒÔiH2èÁ“: µa„ EIY–JfÍw2—¢Þ¬žà¦ˆªèqÓ‚)¸Ù7õ XÌ´f]ttóƒóì”,ýbZî4ù6‘˳š2·Íõ鋯#ž€ã.�ôå8Î|ÿš8vÐä³W_=+©À'”#r,îkp¼Ì÷+cþc˜tY–Æó.%R"sm€-¢?® DEŽs ,Ü/J4ü`¬ëºû¹nxlé[óù3Ÿé¿Æo¶œÔïA©!$ß7½`-Ng¾’=@ùó¥âÕP΋u¿.i°é:8 17_ñ.¸Æ2ìø4:„xgÎI?D78øŸì5ÌðZ¡kŽœW~(‡a@Í›Ó2ÁÝ“ä ÁŸ=ëÙr»’‰mÓÅ_Ù+ô ¹±Ï^Ÿ€­Xp© wò5.ëvò9Òq¦éôŠXß—1F¤Ã¼Eñqïš÷€ã7ì ‡ÌBväÑôϪ±ˆ¿Ô¼ü=l0¤˜E ÃP'œ¶F@„˜1Ëÿp+HyQN馅ìÕàûÿ©îÿ¬o[6¼'ôîôªÝªôç©”á=rÕN£ö}1%ó4HEKc®ãét¬Oåë#”³G2“_iQ¤8ìN†ãêGa8áyGçùQE1Ñ4×´ZÜ Ä#ÒßËyÜJÄ‹fv >GÁ.œ£¬Tþ[éÿÄ‹[nyžû—øÕGª&˜âu†w„š{ Þ™ŒÆcÔkSMà {`c¢ƒ%¤ K„|ˆ ˆï˜FÀ&Bu l“}ÕGÏØ[’áh*.”E¸buñ„�8«k€µW¸—#"²qP–¥¿Ì‹A=h¨Ìõj©Ã%¡ñͺë®;{öìgŸ}våÊ•þr¿öjY[x™% P% Õv†W+kµZÝn±2¬†ÀI¢šgZ{r¿ÿ#ߘ ¨÷AUJdÙÿ«+Œµ¶Ú êïÔ¯Ž®D$x!ýê¨]eƒtÒô…“eýd6ètH5,±ÌS¸xJpFøˆ‘$I€i°é=ž*wªÂôè\¾ƒP€A0¨¤ÿªŸÉ>fUUEGé'Òö´ýžoJÓ4§ßÄM~]ÞyoZ ƒy\ƒ‹6!X£Á9ÑhA¨ËNŸy2léà ˆLµ]áPÈò} NAßš»h?µvÿ¢ðD~†fª€μé20¬¿ÉÉB:,¯ Bžçe›eɯñ‚8˜7o^»Ý~ä‘Gò<÷óš×5V¬ØIŠ<#Ã@±`7Ç»'ÿ.ðÔYmfbþLu˜° "³gÏ.˲Ûí¢e8©T;d<3TÀ.˜¬à\ Î@L<A§Õ$fê¯)ƒ_|ð5GÎ+väÔ›Õf[S¾³”™Ò4Mx_hXÿ†ÉÂE±ïûk­µÖÖ[oÝëõÆÇÇY)Ç™'EúÌX.zLB8¸ çã,eíd͘MYÛÚ#òü—íöÁ½^Ûóî"ß3ÀÁé°”8—e© fk­ÝÅf‡gÁŸƒÑ½F1v#»êk«’G“Ù×Ï®—Ö ªqâÏDg(ó#þÊPôäTýYøm;ªÆœ0‚Ï£»�+œâ)á…Œnf ¬ÇŸ%¦VÁJr2|~þO¹yÀØ¥ÖúÖxFDLßø}ß{ÌkÞÖxžâ¬ƒÛÇAè áózp<ôô‚•:¡-N@[è¥ñ4 {]óZBiÈúª,æ¸~éIy­ï7Mcš&¢‰>&Y•-sà Ã|³é2¯(˜ô:™Ü(vÀKìõzÊÚÀÂhš¦)ù;[Å0 ”k/ôá°P¹”Ç05STpUB:1l˜äÈ%¨˜:&{ໃ‹%õØrÕ¨ÛÐ:ÂÜô ' µó·>bïØÉš{÷¢Çþ^ºz½G}Æ:`.¬îØÚj~äll›5AŒž>¬ z½^ñ®¢Øªð?â'W%ƒ“c¾­ßRW[Vf¾yæ™g–,Y¢åˆÝÊÖU,HtÏÚfy(€*J‡e3AÇ霗„¦»ñ#øÁ°®HÓ?Åñ"÷„áqyž„ámÄ:Ÿ áØ§W5þùñÎA/õŒo‚ 0‹Mô±hüŒñjÓ*\‚M ÀÖÑ ª`£e ÜíÄ7s±i!f79SìoÍ ¾�6£R$BFˆqH ,ÀÌ£9H!‹Ï­]ZÆ3žç)»oñâÅeYÆÄé©irWÂýh;:Ê(\€hì!’#X§Ds=ЦøŸR‹ž%Ètýè™Í±bÔ:xP‘a–}3Á%AIçÄG¦æ³¥¾h>z¡†9pÀû}\ìVw¶°‹-e¿Ø§ÿ'ô­ï“®¬ýFH X„ æ°×çtÕ(|?÷&AO`ž›2ËÇÇÇ­‚b(|à@Z¥3Ó»y›‘H@E¤Ü¹¬ö¬Ž~¶h=æóä÷Û4’Jëœ2ˆp¬rXpœJÖôr^¡#g[Z–»”ãßïÖk·ÛñÍqëòVq@1éü´‘BÊÍJkm¿ß_¾|ù€¹i-µÔó½k�;<ì­ï½™*~ÌØ ‘v»}—1%M²¾Ñïÿ*~om–eݺ¾4ŠÞZ×; § õÓÎÎs.ÃŒ‚L5¯­ª*ýHÚúq+¨ÏóFFFfÍš¥pöœ«ç¬üðJñ%Žã¹sçb* £HpUÐá89ú¸Ü_uËÍá—Þ T[°aX>aÎñ»cª( â¡@Ädª¨ß}²+ƒVD»ÝÞwß}wÛm·N§Ã9($<ƒ¥ LEf<ŠG¸0o8ꜜÃ`4ŸµP0±N &Ô²Ïŵã¢Äó^h¶!:#[g¡R(50)€Å³1êȃ;ÎŒˆ¾Ù¦i‚;‚z‡Ú$“˜Ø€ˆµGíÿÑ·Õ¤‹³H°$œÑzœ—ŒRE„f F ø cQW¼œUúô½+ÆÅsǨ˜Q›ò`5®£ßx€zfhŸ XUUå›Êz×ú”ßÖOÿ°}Å¢ö®ß þùçžü]Ò“SÖ1‡ ™4ªL×,^sä¼_OÊ“ûåûu~ÖÙþÌíOùë)§l{н×V®š^__(ÐØO.Lê®»ÿÝm6mêyu³iÓýy7ß5¾3(Z1w‚ Ú8< ‡q-t9#F,з×msjYþ&IcE«‚ Xéû?Œ¢Åœªò} 8'Ë® óûýÑ!© 'P †×6·Íãͬ³Ö[o½·½ím{íµ×�†~Ü+æ˜4Ôs  Œ±1)ƪÖ@œm·áW�{¤œõ¬aÒÐZ;Gäâ<ߊD0–È–¬ú$u?£·Ï®(Ë2´1 d)d@Étdó¢iæÞΣ>úÄO¨2|³vŒM¦–ú6•þ§/Q[å 2€¥OIytBÒ>ˆbx°ƒÜÀn4â{›{2"ì2‰[Ã;Ź‹'ŒH„’ZknvÍ€â'6ì Šù$”¤š`ÖÃiÁbê쑪û[Q^ïŒCg¤×¥ùYy¹qYlT”o/Ç?.ïÞÉäLa–ªsÌx@R4`-+–óà­Ê…5§‰H¡tƒè,$O€Cjâ|¬‚_Àк®Re�NO§D$LÂx^sÜ’â‘?ÆÿÓDãaøýÙ³?üyób7µÍhƒ6›Cìô§JÁ"[]ÝOÕX{¿¼?8ßúò­ßó÷|hßµZ­MîØäÔºôÁ¥U]eí ¹‰Ôâ}Á3³Lï;=]Ó#ÿ>R-­Œ1&0L=d’1ïa¢†Ì8$×d¨þÕXl ë¨NtEžÞjÖëå"æ§s­ýHQ\EË=oCÏ;,ÏÇù~mÌÇ‹âRß#óc¤ÿ“LªÆzÆ›˜˜hšfáÂ…‹-RRÓ4V¬ç{žxý~_q€ò\ª+˜ÀˆóY‘Ü¡· Em!yPqØïK?jƒº>ÂÚsZ­£Òôš ¸Ÿè^,ÜÀp<ûÞLgcæµsi‚™JíO·{çõ¢DÝn÷þûï‡djzV:º×¨5=$6a•<„EPr¡À­Ó!Ôôk^×äÛå{oßßçbïû_lþö@hŸ±ñ1ÓöXAƒYˆÜ4â~2{L°Ú×m“têM*ûkÄ”+Jï÷·0Ù/ƒû¨é‘ÅOWKã÷ä3‚º[·÷m7ooò/çV¬¿ØÙ}¤,ËÆkX¨¬½}gôýyÎ縓Áƒ5Žî»£=”‚¹¸w¹`—9ädIÌ‚’€êdß÷MU½½ªþèûA´fúœ×_úíø¦8XkÖ¬Í7ßÜZûõÇ?qÑ¢ÎurûáÝä?.=Y—&L_Ó «ë‘s½\ôuûukíèèh§ÓQÜ,üq˜ïŸÛ;¬ïùÌ ‚ È‚òßÊw½±C9ŒâÅ#`é„—–Ì###ý~Ÿ» œ‘1Ù”gÄAÿpZº®[ÖÞäy-k*ËÛâø~‘v]že¿‹¢¿ùkFMó±¢8ÇóºÃÔÓ“¶W7úõÞuÿ®~=^gY¦ lÇý}úÉo[Y/ò´g«ñ1‚~¿/4uèøˆ09‡Ý?™ß ½8®á »ÀV³ëúˆªº1Žó¼¯GÑGó¼÷ ·7„#Ä�PÒB‡¯m7piÉÅ7bŒiV5þ}~uF^VW"R¾£¬w«“«g*´lfU c,Sm&P k«lð9óšâÀâ •ÕF_.è†þ·òï•¿nÝëÁÀ˜¸M«[­bº\út9mxšqƒÓðñSÆMf¼¾'"²±ØÝlð³ øK€‹¥2RdŒyþ 8/AAô·þl½»†d}ScÎ׌¶ Úø8`êÖ Ž… Ó5¬¡í6)hŽ(ŽãÞËæ& x°sƒ–˜-åúoð˜, ¬ísKJÕÌ\"ÏÁܹswß}w•nó¼¹fÒÛ› ÷ŒNVêSêÖ9/÷×rã§åÓ³·œý|ÇZ;66v×]wÝpà Ëï[Þÿ]ß[×k}§…6 LµOgøe»Ó€qÔøu;­µÖZï|ç;Ÿxâ‰{ ˆî¡ó# 7 Æ vK\lÌ‘EÑõýƒ‹âûqüßoÊòÌ,»0懡øwû~7ŽÏÊóc†&Îeû¾ÝM|ab$iÒ¦ßïë.˲÷öÞÈ/Fª²22¨Hx š…mö­ãGÂæ 5 éj2ºøqkíé½Þw“ä1ß÷Yaí‚à¸,[)òשpŠ£c† ø”Å¡ ³^”¡ð�U<DDÌ„ñ/ñímù‰²x]!"Þí^xKÝ!ñ2Ð_Êa³nŒï#eÑ@\–e5·z\¾æÜäŠ8Î#ÿÏ;îé7ïôŸ½¢¯hÝ#fiœEÊ©Û%Qç±:¸ãû¢ŸÖûV/þYÜ<×x{žçy³¼b›¢<¨ ÇÃæÉÁÉŠÌ�Ò ÜšâÑ4ýÒæZ/è<镳 ‡“laÉ體ǖվ•ñLpc`.2μºVL �ˆ:}ʨ/ך³’iÇéÎ A Rà$}\­V Ï�Æàš¦ùL¿ÿ÷0¼ÝÚ×uæû·FÍ÷ö>y¥-ëúù¢xôÑG_|ñÅã^|ñf‘ß~>k|r%Êâkz9¯ì¥{ÛEÛ57‹f,ºý®Û/½ôÒ;ï¼sUk•lcšê±Šmàà˜ãcÑp—›¦éõzì„m\–åªU«î¾ûî  sÈ“’hóâóñ¯ÐFä1ˆ"çÅñ¾Uu¦µ¾ÇÔõÊUg7ÍQy~f«åd:l'#"3žÑýI7ýFj¶4fKSíZ­¼eeô`>‚<£I+ï@ÄS�u±£³Å :êLå‚T‹ñ@ø·ûý‹ãøÃÆoÇcaxIŸ¦! ŸâÂ0Åò3œß¡˜‘õÖ[ïMozÓèè¨>pVÝvhKÑxÞ¶¾ÐJ>˜´>ÔjŸßŽîˆl1éßųºèîè‹Ccé_Ö>Ðæ kʉHÐñßup¾ÕWãK‚@Úíyóæë­wÚÈÈ™/–ó¾”'•,é¦Í?t‰µQ„%ÄqòÌ,y‰®!¸¶2Wê×Ôáa´ ¬Ì®çÿÁ—Lêyµ£&©&y¹ ¦•ôªÑê€'O(ëà‹z©a%0¯á¾Þ£Nÿzc^çÐNçN°<ÿýx¶K¦¯çŸj)qaç¨oÈT©ß÷[­–2bx¤“•èðA©ÓaZHWÒ æ©*$ˆRŒSÏ™Ap|Ó<‘$7Ó‹¢sãxŸ<ßi•—]Ú>ó»ošÎ}úé?ßzë÷Ü󻢸Ý^ñÁ"þn̸²·É(7]Ô“²Ökªœ—ûkGÙñn¹{›¿l³ôÚ¥ß:ø[óž™7ö–±î–Ýê¨Jî“àÈÀ¶¥5Ô¢ï.¼d Ø;Á¬˜4MçÏŸÏ-v°v¯pG‡?”SiU}1ŽË² ‡‰óâ0¼8>š¦WDÑ¢Ø@äð²¼8ŽŸ'¸\†&%LÄôºÞȾ#ÕŽUÿľˆø/øsß=·ª*ÅÐuCB³#ú™yæ½ »-˜Pø£MŠª™>÷‡Á·þTŸ™e~Þ7 ÚÔ˜CÒôkA X•-�´hŽÏÀ*çÔ§1kÖ,çül!VϹ51´²“ˆ#ƒ ºJ ¦a’—ð4ÀŒŒ¤iÚívõ×%ÙçZïÇ6öâp­µÖzË[Þ2þüGÆÆ~áùNg‡a`ƒ$I¨Q˜— Q˜â"ÙØFH›­Mö³ÏgÁ×Eá¬Y³:ÎòåË›¦INKú·÷“[yÃibÆÓQé‚WÆFŸX0àãìdL®xžW~µœ±ç øÃVWUk:½Û{Þž“Š|Üw2 B7ßÃK—ŠBÎÓ€øcÃB¿YHwŽ4‡×Îÿòlí‡ó|, åûž1N'Ïó/ó•~ß<.¿“ýÜ¡á7Ö[¼ª˜/róî^=Ïz÷xurN�� E±«vîš#çø:JŽú'ù§óåüðw¡‹¿è#‹ìlëÍôLÛD_‹¼`ÒåÄ™êQ?]@Z×´uÂ4àbˆ ¸ R݇HEyƒSB=Æ@isæ0À/úkÓ$ApdY~ϘUÕo|ÿaß÷H®˜k2LT F7îâ{ãAØš¢$-¤ Ç#5Ð×ÒX¬²ÐŽ}ŽÓE`îœ3¥Á³åÈú¿‘$ͲȘ;|­ª:´inH’ÇªÊ §ýUO—a±éNú<B¿dÉ’¥K—BX‡rþ#@�ˆG˺a�.°áÑÒ×gËóùšªCG?œÍC­µyl¾yŠýø>ycí3ÝîO<±hÑ¢Ó´mí9qlíä‚䎳QPù9“ˆ†èð³*Ì )ñÎiqo»í¶Ûo¿ý/ù˧Ÿ~\3z&>àØ\ŠEqØå/ Q’§#™wé Äëì?²è¢HD:ÎìÙ³W®\©µ‘¾Ÿ•‡ÿKäq%ó�ôc*ØÞ¼/ø—jòÇRœásËA›ÙCË1"A;à\Ôõ cž«ë,ËFFFæÌ™³téÒ¢(V³ö#ÆoKµSõåSå6ýu™åM³¤I.HÄcÌŒ3¬µÝn—Ç9å’¡–è«€'½kçËùGo}tzdZ×upUàÝæ•û•á•aøb¨æ1(eØÍ“•žYHJq G§D†j,¶Ïô*p|‘ç¦E�Oi€K šµ#‡|§µ? ‚Ó‹âcîª*93q<-ˆÄ31ñ÷è|²¡^6ƒÜàrJæ¿çyî*ó 9âŽ~Û*c.óý=Šbë¢8#ϯÃG†y€"BÎ!Íà J"ç·þ­Ì²,ƒKcPzå,ÈÓ» :½z=2ÕjLž…â^R~¿ÏW"™Œ]ÛºüXshžÏIÓ'Ÿ|r¯%K’ªºl¶_î_†?ZØ«ð€Q6VGÙá¸àà’ÊÍ`Úllllþüùƒ—%“DDýpj�€†|:Š5Ðô{¦ƒÉüN¹U&"ÕUôÓhÖ¬Y{íµ×'>ñ‰}öÙgΜ9Aø×ûù9·ë¸Å5%NbXuè-«ëOïOÇÆÒw &4{tP ç OO$‹È&‰×"³uÓ¼C$˲ŋ÷ûý/äù߃à7­Vð@ž–¿ oº¥åßà{{­+[ hŒŽŽê„2kÅêm PÈ—kM•óÊ|í ;œýØÙûu÷Ëþ˜e’ùøí´›~#"y“ ibpûJÈ,<gŽ¡nðÄàu/S'õð€].Î$Y,† ‡ub fÝ‘ù¾œçMTU8ÌÄc¢°Â.&ÿáØ¦9#K¡èÍ* ›”0¶†ÊO‘k4l8d—0Ô|Y–1ÀhkíŠ0üf~;MOj·Wy^™¦Èã0ø­ï ð<´ÏbbÜ$@ýЉH=ã5KPIp@Ð(©(äI—•Xö�� �IDAT`\ ÃyžXdZ^Ó|{A¦R–e`ƒp~¸ðÝéç· .úÛØ¯{Éì¦9o^˜Ï­Œ5æS7ƒ™V5ž�Z`M× T_U¸` rÔpXÀñ‰qï†^°[PÅßÿþ÷ùóçëQÑûv/>>.ËR{rNñªâ ˆõˆª0ÑЦº¾/—X8G}Œ|>Mšnx&Š¢6Úh¯½öÚn»í¢(z衇úý¾iL)%SQ€K£«¯q™¥˜Ð¹¡/ Îù˜~r¼.G)æÕ@TA#Æ3£(Ê9·®¿œçyÓ<Ô4ÇWÕ_“äcTƒ±,ËìÎlR6;˜lL.[¶Œ‹0}§ŠãÕ³ÊÆš#çûj5­èš(¼:„ºŸ'žç{ÈCeª» ô9çƒGÈÝiT²Þ3–²~m*ò`bN2 ”ë}†À˜ ,Ìl¢«YôÕ»ÖÎ-ø]Cs'à MÄCûèµâlfF5ÃÍ KÕuÝÙ¾ªþ@ý0•ÊVBvÖ4ŸH#RO5(WmjæÝò+`O–ÅDñ§ Dp>˜¡¦õŸ«7¢ (XÜ]ÇB⤛ë`Ž}IƒY{?êŸy‡9®›~'Iê7VURÅÇÄf8ª+á•m•™ºÍïBïèHnD¤.jÿV¿9¤i4ÍýMY–ÞºžÝÇšUF–ˆƒG!”ë„,\*&‹\ʱ½ÀÌLµÑw§Å¢áz/XuÞÍ^o—ÞÂ{ÞqÇãããwÝu×’%Kš¦±ï²Þo')[z:Þ€(wôÏzþ͘1£×ëÑ ÝGÀð‚âZ› WvÊ‘©^,ʉÎnEsçÎí÷ûccc؃UÓ|)о’çÛó¼ïß¶®ƒaiÂîÈ䔆 CÇÈ™<íPÖ9¯ðmn:aX4€/Pâ8¼&ð,á]áLÞq~Ä €XRXÄŽœ0¤¥p:ýjGÕ B#Øÿ(•xž½\$š7h�@ç–îÌs0×y°ðåE8ÆBaÇŠ}®,³¦ ÃðCÓI=Œù ±ŒSÉÌ àG„ïañG§ÛÁÜY`)[ÎØÓšâF4+LƒQÂt8¸z–©Â¦Á-ÿ[¿:´>{}뉯ˆ£ù‘zk„ðúˆ¼<0'öñ4D¹,"ò5‘OJóÚ&;0So±\DK"I&S1îŽÀ’Y³ø-¶ØbùòåO=õ·<™Í'3—Ê“Cül­µæ«&»+Çø-·Ür×]w­X±B@ûŸë·wk«𫪪ü¶Ÿ~%¬ð3ƒfYãØ'öz=5ÐÔ/Pg·u-¦‘„ ¢†vÜ™›`ŒIÓTÿŒíøýëaø^Ï»!Šª¡?ÏÁ1«ÕjeY†B9JžGž.¿æÈy¾81a^—±QµWð—³ °ƒ˜ùƒa¹*ØñŠˆ&§Šo°"‚Èt5>ŸÇ qLêN�™ `X² ¹p0<ÖCcJ’F.°~1h‰³–ŸS*°ÐE×Qòˆ§Åž÷ÄÈÈ1EÑ«ªû‡“ €Y¸tÀX øoà ±Ä2šal7Âú¾H½acwTöÆ 35Gs%Çþž8KÐσ / &ˆ#èó!äû¾\5„yàCfƒ%SœÍxxDfŠpµÙ ³©ÚÑ…Q3·)6*‚0ÓPþ*MÓxád$Y 4x@4M³|ùr%àM™«%w%ˆD°Až!Óñ±ÆôŸ’s’‰'ÊóÊ¿^Q–¥}¯ÍË;çwÄš Z¤ŸM›]›‘³FtÊ*;/óŸõ['·˜çÐÉ„Ì/0á�â‰&N‡é0¬)€í¬ -0jXÍ;wÅŠxƒçéûÿm­ £ ºÅÐ%Ò_Ôëõ°¯Á^¶¬˜Å dõÿ V÷Ç1Lü_y„<Qè`k¬Fì°E…œQxJðô©X% k¶0a•{Ý9žç©‡J–eÊ”…f:FŒ!àtŒ¢Hç'mYu ›:d bzÊKƒC è¢;~<É ª Fšæè²¼% ï0&ùª1ÿ™eu«õà0âÓЋ¢H0œFz1›Psg¥5n3ð‹Ž†–Šxªý0wA¸‡sÍ Äq‘´«jxxƒÚƒÎ'¼A–oÀÑ‚ÜY¡*,4MõÒ4Õoã™P$¿<FƼ&”æH#œ‘żø¾ïžJû°P^«Õân7´ªªzæ™gtakÀef#+šó‰ËŠD2uZ¾Jq׿©Ã›ÂôizBjÅÆ7Æ3˜i3›—98ýUU5Ç4æY½?ò=¿ª*S™äþÄîj{_è§P@Àþ‚t#êÚ£‡MoÁ‚CêÉ "¢ÖŠÔ9†j|  Óx’žçõû}½ ,?`àŠ^ ÕŠ~[—òŒÚ«Àô%8rú}¹ûnÙsÏ—íÔAú‰Xî"gÆŠs4yár‡µ‚c¦  ›KrðBaÁD:S ÙM@·Ž2Œ1ô¬ÿÔjµxîÄÑÝÑiJÿ„¼1cöPA Áó QøþYö¨çýÁ˜P‹ï&Ž¿Þï·ãø.ÒŸŒ(w°½uۃͬ¹@UŽƒþˆÆJ8æA—Í|¨Y³È&nQ Ü,AH3QfANÍ1EFÈÑÚA¹ÀU#/]}’Ìãgív@u¦t¦è3×3Ÿ¸ˆ\އ…𬫋† C”Š_qþÁ��Ôü´ÖÏGy¡_É·ù–`ò“Iƒtj}¿˜U˜‡LPU3” êÀ.¶iü×úþó>ø2¬Æ¦(%8àÐ 4úó¶ÂóGÁ¤Éë íŸeXZè éªxî¹ç¸Í†>«~Ô˜ãŽq]­·x(‡íB˜µÄ%ÎYÏi_g%I"E!ïz×ˬMÏ(™ºÊ>Ðà`NnB¶ÇÈôysâwõFJÂŒúÉpmÁ‡ë•(´Â\^¨æ`”¹¶n�ÇQåÀ–FI§±0—Д Ûð×L,ï™™Al²Ö«ë‚«þ73&&ÁD¦Y³í<3Üpl8m*aq?ß9ÚyQO#6®F$Õ”–c1®JQu¶æeÆô\èl:¤y´”xºSƒ,œý��âLrÂóüÌŽã^®À(ÁÀÊŒ¢ß +å?qøcãÖ’a CGÀ[H‰CW ðàŸ…zLê3‰ã¸¿iß®mãû⪮â8ž={vžçÝnןïWýªÞ¾ž PèC·MCÀeÀV’‰ó†íÝÛÐò‘#\Ì7‘+VpC‹G‘xš˜™�É$ fåèJyBìâ¸æÈ‘O”}÷•7¿YÎ9GfΔvzN0‘taiâ†èIDRt0¾§â ¡³¸ê�„„`þ(•ÐÁtRFºÑKG‡ƒãWcB3­Ð¼¸Á´4 vè¦èõÃÈð"#Â(÷À¹lâ:ü ïû}c. ã‹b<ŠîƬ3úýŸ†á"fHÁbâ5¶±&§Æ˜v»­¡™/�f0HBõàÔ‹«˜Û<KaõI\N%G ŒñÂßšO2gñ8ŸìõÂŽ¥úÆ¡ZÆyÇz îO}Å:qæpù0æâ•®‚8($eÇ€=®Yw’Ú¹`b%,”w8_Ñ"Å©~&q| Œ¿¯ãGíû~Ñú‡N§³ùæ›/^¼Xý|Û*nˆcÂõÉ«'ÄŠˆtîÔKkN(±µâ‘;¼kh®cÛ2¶É5"' ƒë¡¦Ýns°b÷?îÜ åÝ{ÕXæüß9ããrᄇÇ""§ž*Ÿú”ø¾ì°ÃKzÞTUe61²ž¬úöªñ—Cÿ9¿~²vØÀ˜œÀè™G½â8æ¤u’n't›þBQ9 ”ðºÏq ñh7OÃ�ÏaÖÃÀcqˆAcž €«Í „‚ÆS–åf›m622²`Á‚4Mµêg/gÕÉ ' ?}n°é†áúþiÚÄñß«êØ<ÿYýÙ÷½áE GÒ‰[P l¨ò8¤RxPÂyÐv¿˜|¥÷îè¦ O×µ¡O�lo–æÄ¡ÅÙ(8‡@ópð ^ [�§D0¡$ÄÃ[I’�ÝeDE…ïÒ4ä…0‡l}0½?ìV²×28Ç:Í#SÕ-õwñ ‹æÔì“ˤí—] F59G†„³H&š(€¿0ë3¸ò•¥)Œee¹¤iú·¿ýM¿Š¸¨Mõ#¤÷.×*‹S‹l£lÆ~3Œ1Vìø5ãþ³~ëŒVýBí¯j몇=¦ù€VãðÊå(2%tXu©kúË$Àa|)dê›Â¹WVÆœWÓ¯ÿ£«OS¹øbÙf›Áy#"ž'çž+?ÿ¹üîw/í¼AªUÕ¡U²s2{ïÙ3ö˜ÑìÖäGæå›K¶ßD–-HÔ"ºDe8A³žm h(ÁîE?u:È<õ0mÃV˜,êŽàÅ-(žÀ@LˆAe€'ÕÖ}úé§ó<ßj«­¶Új«N§Á½�ä§è–ƒ»ÅÚ쬟=¨±Œ9©ÕÚ/Ï?Z×÷ûþÖÚá‰dƒ%Vgð' CMÿÿ×bK;#ëS*ÈÅ è éK²©0XÇøÙÑYÐAy\ ¡gŒ£ƒ�Ã4m;鬻¾/s:§û1&Ƨƒé3ßÞ”°ÎC¤S&1Ÿ¦xà�v4­Aù‡(mBJt�ÄT'Üg›„óÊþûýöÓw¦\šãe±¦{ðp`^0Õ»*Í*ÆÇÇ•­îíà™Y&ø}€$j¯æcMø›pôàÑ9£s:qÇ6|wèÿÖÏÍ‘*añ0Å�’ ¨l�ˆq÷8¶£¬ÃLB6¡Çkå‚›‘Ïfˆiav˜ñÜ»]sä ’¡×3,¢!BÑKÁhöl¼¿{­Z8-âÓâøâú_kžTžãÈž6ŶÄù¡‰3KÓ3;™‰Ñ<¯ƒýÉ"äA:¹ÆS{Œñ„?[ð2)‹qvQ`MÛØ¿‡W°n¶^¯÷øã/[¶lÆŒsæÌaõk RzÞàš9jLWkF[UD¾áûsK ©‡!Pò„”i�­`~P㟩l…a ™jz¯ÍX™:ñª»š§YÏ‹—Å,¼;è °2[t³±)‚WñOÓ/€u8~¡šÔ‚ÙUt€�ÉTÝnÍ”Q…páËÏ +D?œñ"}Œj„_G*SÇ?×AH†EU‚èÑ+)mdK¯¬7®³³³êí§5èÀ+AtGTm^õOïãô-¿X{æ¿ Êw½¼¦iÊ-KklüX¼ñÆ¿ï}ï{×»Þµá†Æq<ØÐ6[6ŽB~q–À NI4‹üÖ˜Z©“7x/€ë±ýY˜]&+25 °F_­–u”|÷»2:*»ì2øËOZ8@vÞù¥»úæ¹×„ׇMÓ¬¿þú:IPUUøPXn_f;gÁmvn™DÀY¬ð®$÷,?…^4‹2 Á†’ªÄŠG¶…Õ¯)?ÄcÐXÆG!ubç]h¾äØÄa¤!.m .|ñÅùWè‡ Êè~Æø'JÎFÑÛ×½‘‡áo›Æ7&I(0ò£ƒˆ v¬ãƉ?Z<+ ”púÒÜMaÙ´ÙY“_KUEQœøÈ¥$â,ž�ÒP•Î_—§¦FŒ©L{Ÿ¶L•.fÆ<pKÖÍ[/›…Gµ©€£‘åÝdª.kküA='44 ¨”3 «Ÿ†•øKO2�±†Yá‚mX9דŸ—›+Œ¿ÔO^Hªª’¶T[VåJo¹Wÿ}2kµZqw:¢(ÆÆÆ¼xþU~¹NÙ¿­Ÿ™ÌŠmÙªæWÁA#žRÚ³ ðڸò|otåè¿þ/ûï¿·ÛM’ä†nè-î5­F6û˜å&?/Kœ%ºòa:î É2Õ$u6öêB>]ðZ±ª© ìhè'1’ÌIÌš¹ú•/}IN8AŒ‘m¶‘ï|ç¥>oDÄŽXY³ÜÌ]wî±ÇkŒ¹æškž|òÉjUå5^=kRë"Tº¤8@žˆ« N)ù�Ç@&F¼@_(0åAƽ‰ÔëÕý3ûƒQÇÓ£f~=i¤Ã4$j@3å‚e8J J‘¡O­†6è™M’¡@™nýWÕ_À·ÉTs6„E=90ïu2´:ÁFp„›'H.gA"'€ò”c›øþv»Í–-ôqÊ}&h?8L?ýY}­:, €°‹þ¶c™*"ÍFMvzfÆÍŒ½gˆˆ‰ÍÄmæVŸ›•“,E$�! ¿ŽËS<m8Maçr ¼’¦)æ”цáI>PCåyÎî, É`ˆ…|ЧÄÂÓ@Œad¸í …‘ˆäëäv¦  ck¯´/¼û=³‡i¶hÌߦ¬7 èbNŸI›'šÎž+ÖZë{~S6~89S æ›6o„ Ó ÜY×µÔb¬qTz‰¨ÛA ‘QV™*?È’9 ›âàgò'¶¤£á„ó†qñ<58úUàÒöÊX3FÎ>[¾øE¹ë.yë[_êó†I eYþío«ªjùòåì(Ì ,ö9ÃèÜ´°){f`¤`úÏâ&©ÃÆØ×Ûò ÒÌ2É.‰žýÏ÷eWi~Ù4÷5L¥cu=‹AñL8R$ð›q€†s¨:ËR¡Bg:µLf×­€Ž2 '˼m4åäÜâ#NGT'Hýôá#ÚbØ…"™áêü¥žß\9ÌIuÒOô„˜8 )6ö¬Ä fŸË‚3‚à‘ L¢(ênÝÞ­][Ùý¬w­ÇŸŒ£K‘/CH2Ù¡6±LSg-H.ÅHS¦ë'¨Á%ýdÖšÉÄà;0yDÎxh1O°É÷“$H6Ûl³m·ÝöùÿÇÞwÇÛU–Y¿»ŸzûMR„&”"M„„¡)|€Š Ê 8(Š€(‚ƒ3Žˆ…ÆbBq@¥„6!‚”@Bbé7 7·œ¾Ï®ßϹë®û^¾ïO3#¹þ~übrî9ûìý¾ïó<ëYÏZ›6-\¸0÷'nã…Fî÷9ŽÁ¾ï—J%©x°[wÀ0Á´”P‡‚öíhC}8nþãÿØßß_­V_yå•J¥ÒœÜL‚ÄÛê)Ciô6T–2<‡=Ž5ÏjCZkJã°z:†¢À¸/”G£°öXØ[[<Z»£Êùü\u•zñE5gÎߢµÆ4Íø xxÑð£>Çq£ÑHÓ4Þ=Vye-²R#e†KÑðÜ(cî,Zƒ=ÄŸÏ2¦¢‚Å4ª´xtj¿k{÷zÙšîÎü FŸŒì×lEúÚœ#ÞI>ìvU(Ç�·Rº/±lÛîîî®×ë"X"œrÆÄbŒN˜crÔ‚Ë‹£mÙp[†ôŒQÈù24ãT<sÃÓ$` 1:ľ5ìIЉ+„R(`Èâx¸�Èð¬> <7.MF¥•Õ»ÊÙêØN«–9sëy+<#ô¦xIßíTÒ(Ò]ÕÄ¡‰‰ñ –ä ®‡|)øw¡bc$¤A|)©°™À‚ÑW?¸ tb71y[ܘh‘„Ë‚|>ÿÑ~ôÔSO]½zõòåË·lÙÂÏüŽÁ83˜Œ Mw©êÂ0TK”q¢ï¯|rå–-[’$‘ÅŸš¡™]“M¼ŽŒÖÖX‹±RʼÞ4V³»Œ³Ž© ôãòäm…_‡oÇÃé5Õ\BÔX!A–ôfÛ…!gìO.÷·‰7J)ó=Ó¨j•¼™ µÊ‚4I&'‰“˜kM?ô¡€‚%z5VŽP7㉠ØOñófì“êµ{3Ù%Éܘœ%€ž·Ä  ’ãµ@iY*ÎG *²„ rÇq¦N*É ÄW¶ ÆpeYÕjUäiÁYkàq¿l6ë8N½^—ÏÅ…1¢¸ŽB„{Z¬˜Œ›Om”SÈépjàb¼‹çæÆ ²ÿ31LÊx:Ûk(¨êhØB"^8Ä<D‰EÂ"°P¹OÓ4Ý3µ,·ìfr™Y³f%IòÎ;ïT*•ô­4º8²z,c«¡©}³—(›ûiRrH5´ŒÁ[›^DFÂC©hÕ õ‚96@Æ­Íc±Ð‘Fš¾€6Ÿ„°Úº¤T%iÒl67nܸbÅŠåË—·Ô© ÅG*ÐW¬m‚G:IFC@]¶foQ@ï±ü«ýæyÍèÌÈ0Œ0ƒ?æzÓýþ¨B¦iÖ/¬GgEÎ¥NÆ–e5®j¤*õÎõ epQˆ„Ǩ9$ˆ&PÇ™LFàA(œè°Ž0²f ð¨GD©²žÛù'MSë6+¸*h>ÑÌ~;›i…Á·k£•»<'‡&ajü+­ÏNrÄs΋V?Úœ!ék‰if“ÄM‚ÍAh„ûí·ß>ûì³dÉ’¥K—Æå؈Œ´#µL :ŒŒž¡ÉÕ/ô®Û¶nݪ”j4pð KA±åõ»ï¾»mÛK–,âÙĉ»»»ß}÷]y½ìy[´—°€D ¾'¯¾Œ�Ìß]œ¡È|¡¤‚qÜI´Ó :ÈIä8N£Ñ€b)“Ë»I› ÷8’Ðÿ@Ï<°%B›©e‚äˆ,uâ8Nâ$Žã)S¦œp QmÚ´©\.+¥,ÓjúM+± ®&#–‚Vñ| TT@#™ù†g¹™¨êÄ_@Î/ß꫉Âpá¹Ùlʯ@°"À{ßbÇ¡êÒ2},E@a˜°¶¿aûOùæ©æ+¯¼²xñâáááZ­æº®“Ÿùz†K+|"‚"7–d„‹—ƒAX›¬Üʤ;©?[—·*žQ´JV†±ŠYZÍuÝæ§š–c¹Gº8rçåÒ}ÒúOëî…. ãϠꌗ mœ–k”E®!¥ÈpOàHßJ©$¯Äçî9Ûí§µ{ÿÝñ®÷ê×ÖUª,ËÊ}9gÚa‚Æ —± ‡ñê‘£Õh𰮸"í/¤ÌHZÉ]Úü˜6mÚìÙ³…lFj¦9J‘ù#[ ðÅ}ö}_®ÕEµf#$Ÿå ‡††XÜØ`’$CCCAÔj5á NãäïÑ HgG9‹²p¢ªÀ¤‘΋Ü#Uã|ìñ¹<«È C¨½À‡æéQæ °¹8£y¬ýaEŠG|D©$ËZn%‡&î·R©<òÈ#aÚ¶ìX›-³Ü*Úø<Bpeé#M8 6i0È\·'ùÛ!“�á Å?8î 1´«á˜E­Æú^)E¡ 4-'0ÊŠ–‰û˜ëÖWÅ•*a¦]i㌆êWª_i € ¸æØ©È—ÛWø'kÀ*[”˜±²”¶ ÈòQ¸sh¿aó¯GQdÙö{¶±¯‘,NøépÚ§Uù˜ØEÏñÈØ€33þ&‚ôM`#ëäï`"çï¤Êi-#ßÈ]–ÃØ¬bÇ1ûTE³<aMO)Þ¾€í&;Õs¸T‚¾¢³É‰¶Fêpe¾j.Z´hëÖ­[¶lñ}?Ù-IЉý[û (õ‘Ië-œáÔ¤q|#U©ùºéýÊCòÅ4JôiàXÓò¿"ÕN.•J¥T* æÀ/€‚!WQ CŠuSx–ûÿåÁò§èZAŸb.Y.O®­íð•݃˜¬Å.; á`EìdÁ1 ”øtü¹5}µÐŽ>MÿØôädùòåÒQHÓ4<"´—ÛV¿&!hoÈåñP¢¡ü’RFºnÈ @âb6”™E—g!¤ Vtf‡o´=P©+À†ø©,iTWr?¡ÊÁGÌ«fê ^�ö9^æÍó̳ÍðÀ0<3L’DÕ”µÄ²ï³íM¶2ßG)ªÔG"(�IÞh˜jÐÔ=´Î+ã±H2‚® Ý'µn°â4Îçó™LÆ÷ýz½oˆÕJ:Kn�Ë]}‰åò#³DhGip®&Ãʽ=F\8´ƒÇÏ3 lª²#älÏŸQ³÷­@ÙNØœŒcͱÃkh¾)ï;M¦Ž¦4ŒQÐxKl ñÌX½¢6nÜ800Ðl6•­’ɉò”±Æˆ’¿‹ËN·ˆ0hìlÔæ×ÜG]ï^†áþaøßaö›Y÷u “gØÚ�8!r1ð³Áz`^2ÆYØX…G µÉGЫpv`òÐ< ”A¿G)ÕÓÓÓh4J¥’FBCˆÒ¤ó$„¶M+繇ã­ç Ñ‘³rÖ5Ñ-Êã›P¸¡°â†ÉÜĺÐJÔȵGkös¶5 f‚>ÚÝòæ,A&˜À¶øuÁyŒæ"’9„üð¯ìÜÁ4 ¡âwemCü“¿‚tq+^뺫±60I’x÷zV›MŽ’$‰*‘³ÎAYL'µ¡ÿ¯HUcsj¬o:º@ñ@Œ“4x¢ùØÇ>6yòä§Ÿ~ºR©p-Å>îÜzádˆ]1�¥jÎeÑmQÛPÓžÓ�p+@Qd¿#äl§/0Ò£CY†teœjÐû Cè…½«YûY+üYt 8¨·bÒ†¹>ÚWÚUU5M3¸406¹Ës±Šµ7”SL\E¢Îò‚æüföȬçyòAÁ;5ߪ>RuÎůɽhl6¤¢|(°^^Æ J'PßJ’¤^¯súŒÍ  °R5‡wÐÑ}t�� �IDATˆ�2¥$d‡ÿQ‹� mæ/�çü�úøÖÓ^Ìz‹wQEÉ÷âIÌd]baŻǕÇ*iš¡‘?:Ÿ$I‡–eår9€‡ü†Ü槃j¯ñ<ÕÕ´¨É+“6gܪ䪚G¡E(Œ%3@äc] ŽldÀu9Š'p:Pp·Ø 2·™¶i[±¥÷q“ƒx¥™ÝByî¨ÕØñX¥” ÄÌlnõC+ ’I‰7à‰Zèðð°iš*§Â\hn1aÂ+Á3K)ò°”l(Û¶3™Ì„ úúú$U•”Wzf84™{ “få/¥…Ét;BÎvûÁ º$ìÜ{1ÅÜx`üGõTç‰-ƒˆ¬Ñ{êõº"Yú¹rÉÍIýßërFx_õìQ66Ĥa�óŽ[.#Ç5­Ç,˲&L˜ÐÛÛÛßß¿iÓ¦$I¬?Xþ?sš•  $­š ¦Ö±ð†|tþÑ7æ©~&XΈLsâ<ì^QÐâ: €‰æEÏÐ(¾ÞGúÀU4|’c-ÎA¶ìS¤• å(š°tKCVªÒ¥FÛœ¶Ö1팢örN7e`Ø81.„ ‘sý7·Ô&:9s‚\T]p¸``™e,ä¡3 ¤jìl/j2ü —ïÜc“ó—I’œþ£k˜3`XøÒâá²;²0Ñ�WÛl6Óµ©ù’Ù<­©æ©•+WB%(™šÄûÇöOm˱¸k‹k“%„Ù nË‚ Z­B«F$Dá7ˆ‚üà1r‚¹dâÎC< -î9Û“>€–§m°¬ÍÉ pM!‘õüµÞ©l<°«¹‘�æ±FlõNÃÄ»Üu tF·ãLñÒp¿$IÂóÃüWò“&Mš;wîÁ¼hÑ¢‡zh`` s{¦ö\-÷`ߎ'K˜û ùšhíz€{‡ØšÇ`5û†Ë%�XS‘‚ŽŽ66 ÀÑÜ œÖÁƃ�„®£ €OÕ…Ç=Äš¼ óð˜½EÃváÀ¸^Öd �N²P gÇZëò¬¬ßŒ›ÌÝ>7!‹_sob4”*® °�=�7F¹†éTYc¨ØwŠYÔÌgߥt@ƒ3¶?˜ÍÊ5j•çÔX7q$U¸<Ôdîn´OäÿÌ·/k%‚þ¥~:9ÍÜ“IÕhš‚¼3LŠtWÙ#² ÃÃüZc—qœ-²¿7ó“E³@rÜ1—³Øæˆ~VÙR4?¬?´ŒŒMj¬· Ò0sFȯrŒ2•Eså¾=çÔ,sÂnNÿÐ¥( ìqÀ)§œ²Ûn»í´ÓNË—/íµ×Â0¬u>=±ôÁ†Š—¦¬Ìò‚²c`…Ýx5N†g-9'…†›;×ÉÍOHæô\£ªc¿¥Fj¸FóÒfóM¥”ó°ãýÌ3Ý\€çNXd)ϲpëìppgÅ® 1üc€ÖÊëÙêD8TBœì�Ô  Ã±8&JL`w°7•ó VêŒAb9zÄ{²yž¿%ßê5íhÆ -ÀD˜åZÑÏVÊ\×jÕ!sPÞ±%šÞ@=RÀâ¸ÎÓâXœ)9xA+ùX£ÌŸšV¯Uþ¯rê¥*UÖ¬ÜséŠÔpÇÔá.aÛv©TÂ4(—ŒçàhÕ*6L/ð–Ç\3ÞJË¥°ƒvT9Û™±6:—7²ø!b¾Zž±W@E¦:n°Û9ãÎü¡Øo<ó(î&ÐÄ•Ý"ë'ö1s—¢ òBúNZÞ¹¼aÆ•+W:޳xñâ¾¾¾(Š3é’´V«A Cìǽt™÷dâ ^€\Öj¬hQ8mqб¬ËÈY/NÌGJ(pQ¾RišZ¶ÕüT³þ…zöÆlîßrJ©ðSaõájþ¶¼ýDK1Ê»,F€(Žž<óôðEZ}²fÈ §üš™ +”`T87{ž'Šƒ›¹Ý¸3­ú5 û`‚R(1†l0ðÁPÈá²e¢d„بÈú™à‹À2 ˜@BÒ†. SoÀ­RdÏÌKxC ixò†X Š´þiSñ¾}�K“^²JeP -}nʲõxëAôé{iana€MÇ8|KÀ–Ž”çyÅbQ4¶yP¼yœ'È[ÓB–Åß/5¤l@vš9¢ÔŽ*gûÏå`†_Ò4ˆ» … ¯D äÜ+FÂÈæTØ–ÌÛáw–ÊF3>á]- œ´°W¹Zb7E¦,q{W{õêïžøî=÷Ü3qâÄuëÖmܸ1Š"ÿ:ßûŒg˜c¬Õx7âcG#DÈNF&Ë3 ½²ð¨«;ñ‰Zži€¨ šùè�vCÐJTRÿb={L5Yæ÷ã£öR-}$e5ZÊÊl½b.'­±Ïcÿ8õrS¸h´pÈáûÃNqÚl2—ÝȰ<°Â™tŽ'ñ€¹øâÌâ¤8‚á ÊuƒTì*Äâ¨ÛpaRæòÅóÜ6bÅf0øÄ _Æ;,OçõƒÀɾLkdÇz< mÊ[nòúJ¥":, Áuz3ŒŽrA šM¦Öð^-`ÿ}¬ý=�kŒa\N›»Ö0Yî%0=‰+ ̓�[‹eÌ—ØE#]Ö°~èÁIÇ£a¬sÌ#¨ØÞϼÁ›?¾xͳkÊår4; .œ'+°”9ªi̓"oy¹ç±jÌʰ¸:CŠÄ:5Š øo肾oÈm 6¢g HÇl^f~˜à€Ã:sC&¸<ð®÷´sP•˜Ô¬¾ß×Hu¸!ÇLb®_ÁŒ�“‘H„ï˜P€8„³XkJAÖLHCª±~ƒ8±1uÈè¢ÑkA$Ÿ’ÉdX,™ÙçìÝŽZI˜"k¤_ø²¼ºxÁð.ž5R16<8Ìä¾i ø³*;÷àâ%ÅÁ±z…ê™OqƒÍ3 &yEBœÒa+¦wjòEºÃZsã…ÙÈ`GÈÙnñ†Ýs19!‡˨h½¡špfI¦�-aiœ&È9æ!'b/g4Z±!ûϬ9> ÙéÙ0 óÓxÃhœÞ¨\R‰ãØ]äæoÉ'kG9Í´‰ão Õί4c§n¤c:nââ_áP‰ãž§ÒXHGŒ4<i…L½hŒËðÌ„¦AÀc˜ÁäHi†œï~Ï5còäÉ»îºë–-[V¯^DZóßNóŸ›Æ cHM,‚É ùjì¾ÅjlÜêçàʲFèÍ ûFNŠ¢™}¬aT `‡•ßÐRJ wßZèmQe2Çq:::fÍšµbÅŠM›6Ødy!`¼¸6V�ùBj¨aòȈ„4ž©Ô„à¥$™cú�NyèÝ៑@mÄž}–¥…Ù,挰’,JD&N`hÍQ©ºÀqÀ#ã„·ÙÐHÃ8SWx<�™ײ’% ÉÃ%É¿ Â*ë0iζ0UAšòwÀ“þ{åž3¤øeÕ CQ‘;,Ü¥`ŸWY¬šPÎ)™ÖV4¾Î[ꊲcyÒl79„5Ò§»‚ìCÄ 0”mÛfb¦«RãG†u½U¯×9L¢¤5ÔˆÈ?πش4+PÍšá‰aš¦áÖPýF%Ë“\5—ÉdѲÖjš ’ÁpH›,a›mþFL½CüÖ>‰«Lr¢'­Ž‰'üñ .|÷Ýw[Cy©Ò´™qÄ0âÊ}2ôó¹ŸÅR. ˜ž„iÎ*P†âŒƒ=e¡PXÂ…—–&#™@€ö°¬$LµZ 7ÖsX¨ã¶å£EÈ©èÁÈí•o&÷«¹7t]Wd–˜v 1^»´OXôE¦d˜r¯ ”øœ?¡0E³Dchœ ñâOì-›Éd ßǯ\1§C+—£–}-K ,m®ƒøi¨)ftà’ÇRªè½i®Õ£ôCbe©ÔHUÛ`m»F­ƒÂh~~ãqð§‘3óÏèîjŠŠlÄX“öÐA(b‹,PhÆ Êá, ‡)w>Ù`FôV4’ÝB9ÎŒÓSë5«pb!Ic£vaÍ8Ø0k6š‘Œ\<|Tñ)’£±ù›볉Éx[ɭØZ_Ï(åPÃt­u9øÜ‡ÜæiMs¾¹lÙ²z½>00 —×<½iÿ— Àß]ÕËB<“›,Ç„6Ý©H{9&kÉ 4ÑÜ3å$•+—o-Ô/È"à,†¹$C¯\ìò©Çl´R©´dÉÖ¢–”\ø„ Ã!;†e�Sfà£Æ:#º@#•<Põ²úŸQðCòηa46)Óå‘m ÅÅ4j ù )ÎØ²¼ öNE¡ŒÇÊÆ3œre¬¹†Cx5ܸ±êðí¸]ÊcmlC*N(`¦õ¡Gþ>~2)Q†2 ãÞÎ{W¨ÿ¨þqGÈÙ>?P0Ô¤V4 2ãàp‰Êm@æ³±²º¦8Éc§˜ÁNÀg4Ì‚l¨–XL '/ä­´üZ÷L&ƒ<JœÆ6k~©Y˜[H‚$µR˲’Iñ»ÅêÕdrb2”¸çÁÞÑ)ý‚Ñÿý~¹…oœ²£™|ða„£œÇ}XñZ`)Ü)i•8?s+U²÷ekµÚòåËG¡ù ¢üÑyH\Î<ŒïñD§fVÆôtMõRÞg¼V©d* é|M{Æyغj(lϬäØA=!¼W‡hi †+GÒƒ|K›Êâ‹Ç²×îÎAf"Êòmä¬õÀcœç1=1[0ë†ØÀdÎuÞ· õ ë,�“dF‰6® £±Ã ÕpûÆŒŽ|P;Î aêì  |»�¾1í%<(Œ>%+ï§žc8†aô~¤·1¹ñsõó Õ…;BÎv¨r@OÏèàÚY� ˆHbÂMÖ°Òl»XVOòY,8Fø\Ànœø°š¬šAýûò¦pm<ª‰Ñ &)´Þü[Aáæ‚m؉X'°uþùêÍU÷l—é:rî²n±ã8FÆþÆp°_Ðvy›Ü“¡ŸYk¬ü¿ä`Œ¥7´X;U‘”¡";/f"0 {ØHŒÜõ¹ú uïfÏxÆHUšœœø_ô3WgÔ8C©šéƒöþÌ9FbÁ¸<¢.E &m[Ð4ä‡I+B…¦‡mXFZLƒÏþÙ¾RÊZhå~˜KkiñK†¥ óëX–¹ð —OÇúaMnɰȩvöiÛ XcU1Wb|'üOÍò¥ª<VçKÇý 1â¢_d IV<q¼ wM “©kš†ôá„ÕÍ>¶‚drâ‚ SÒD>mxÂZ‘…K§GIì8Çùãºn6›m6›Ç©ãŠªxƒºá ê ®rw„œ¿õh@‰èS¡°-eõã‘c¢BöÜÚÙcµÍ†˜! 7|dgép•{›HÓ¸cÄlQ Ïh<â\�ß-Î8¿“0ÖŠL óOfÅ®ë …žžžááak›•N£¸,6$HÑù†aè_è{‹¼ü5ydßÝgw7m6.md•,,;–‡Ñj/ ~Lbª‡Ue-‹ñSqî±\pIÞ¦iêüÞÉwG9 X™‘¹XFâ,cáP3AÕœíå>ßl`¿‡À¥ -¢QÄ 9æäÚ [Á-qðeMÓŒ>_2÷fÚOjÃÐ?ȯÞ]µî³Œ» 36YvLèÄ„“"}n52ÜM04Û%¥À v~³Ùx”U³‡Ìš¬ @Ó£nlüއ²‘¨1"÷bÒH´¤„«gˆª¥ÑhÈw‘I¶^åêJ2l1N&ÔÈbè›Ïà€²„!-¹?¬Û$9\.—k6›õzS¸œK­Óf¦R'*çŸ'ãì¹çž3gÎ\±b…ã8³Ô¬©Ý®nÿ²úòŽó7ýÁd™æ¡ÄnÄ£6#kEÄ�¡ZâŒ`æ(jä€XCHØå€Ã†ç±F'˜ÄZѲ�pkΘÜÃGêš1_þ]žŠãX%-fZ¹\½¯(ŠÒ$•ÑWù^’±‡Qó¥SÓØ‰Ã%¡c8â¸U¯×-Ër7ºÍý›ñŒØ_çóh¶+àuîðãðB`À …mÛù|~„ råÎŽ3¯¥(œX£l7spjaG2Æ…¸Fä‰z&yã–g¢¨Ùlær9d Â+×B·WÂÇÈ F7 ³o•RÍï4‹/‹ÅÝ÷ؽ\.o|c£}ª]~ œùC&îÑ|æF'±¬UÛ mñA/j˜Øš4 )‰h•#‡ã68X I’D‡EÉA‰RÊ\aZ[lºŒÇ¤Ñy'jdTiø!p– !c,Oð ñ5Žãl6ËŠ‡Õ"®ðD4«âäir _ ) èPüäÞ0xÎÀÒ$M’¤P(œtÒI³gÏ^°`üv�kÛ!äpÇËZ3¿z_1Œ†�øBEÂ3\hu¢°\ưyÉ)ò<¢é<¼3˜-²dQ‡±t.ØŸðßãC5ÃYÜÞ=žÿ~b\Ý’·úBàüÊ-†ÆÎõŠã8žy#³"“/æ÷ÜsÏžžž¥K—ö÷÷«UÊHŒx8³1ƒ ŽOv6Æfõ_<;ž[DmÇÝTr|o™¿Àí 𾉌¡ÝÅe 8­®EG¡|#Ö©““WÎkHüâ28o–Š]åŽx^~Zèíí=øàƒ?þøJ¥òÐC-_¾<{c¶yyÓ¹ÒáÓSb(Õ¦ôyí±—2¬[E‚¶ )°Ó«"[6vjGÇ"“ɆQ/Ô?lXË,û];Ui´[þ:Ìü0“¼“p'º>jœn,«ä1�¨ ØðÐ%¾²”­R4€›ŽÒ–‡s™‚Ì-}èÂ1bÖ�%q6EK,–I2<}Ð:U–O¿”Oy´¨#h4Ë–-^¾|9!;BÎöáFsË2î  BGÓÕSÅ„I)›™Åðq®qšÉbÜãU$ˈEÃ0ì(œ¹˜ “J_Î> BÓB&ŽˆÂYªü¤¯ÖœùÛ†?Ów'¸q5«¡mÛ͸™¶¥Éþ‰ó G“×D¤DÂ4Í0 “´ÕÊš={öŒ3†††úûû“$IÒÄ6mÝ  ç2[7²w–œã¸r½F‡À²¬F£±nÝ:)逡qƒçïÀsc†4n¬àl¨Q¸ Ÿ ßE.[°ùW‰"ÙlV¸àRíÊ(-@®Œqj+¥ä ú#_jøˆá®í:ðÀÏ>ûìÙ³gû¾_©T*•JÿÛý›ÿ}³�wH@¸gx ôtf¦`½àcŠ 2ðMÁÄ™ ú;uB²3—Ëí¹çžŽã¼øÍ³ßÈšƒf<›†™x‰ó¨ãßÏŸ3|ƒâä×™’€Ãß…AgÄZé,òˆîØ;˜³Æ_Tž–%M I â ˆK<ƒÌ<=5VƒŽgtð­9±ÛX«¬ç¬àœ zWuÁ‚‚¦4›ÍjÅ«êÕ¨ì9Û¡ÊÑÒ .TñPå°€n<¿+UNI¨çjv)lÉ«¼[ø–Kxе¢Î+r*a A.’5ÖÐÇ–CJÎ…ñZ�Ì}`ÅÆ4M3'g†²–ZöÓvj§éÄ´qfÃçšï˜ÊP1ÆÍ8C𦯡B÷Ä¡JQßßßïû~Ò•¦á•=8„ÂOŒ7?,ö'F›A“DºÎÈ:%£yÃfB™LF|e8–HÛœI«L~…¿/+e18é8NÁÇr¹î­VcÒ誶.ãPÒR–G)¦“r `L²u,o"¯ ‚@‰¼•1[‹ßaÒY/Kn5×ÖÒyuÑ™Äl4²!J‹Ô 4€…!ªÉZ­–~8U}*Y‘$*ÉçóÙl¶T*Åkbs­~8tÿìb¤Èè~quÅ‘`¼ö®„C ØšÎó!µy^~Ò_ÁªïF‘€/kÜ lÈ\G>yX‡žÅUA7ÀjÚtŠ^™U„P7Ê •±ÆHNÕ'Tõ¹ªªª$I^‰_éQ=3ÔŒvÕ¾#äü­ Å®ã8I’ˆÅ$*¿bFÛcZ@â¶¼�³�ˆ%­ Fš·X‘ÜêúÇçl'Çqòù|³Ù”¬ “ê’à Q¾j�Ž<ÔÈE²ÍrŸÊ¥¥ÁÉA”FöV»xZóä {ÂɈAKuø#8*ˆ‹¢'£¾¾>ÔsÍý›–kyox‘iL!Ö»Õ¬ áRªHáŠ7-@YQ›� $iÛà/ÁíÎf³üM!µ‚fþ•ÇnPk:Ž“Íf3™L>Ÿ—§�ZÀ:Œî3% Jh‡Hç|òäÉ3fÌX¾|ùæÍ›™™$I晣–Þ¿ôÑG-•J6lxüñÇ·nÝZ;©f=hwÌ”Ì#Dü‰³�k@³ÿÁ²áj Å0OíÀ•lIþµÑh¬^½ºòÊs®cYV±X<äCvÝu×^xaåÊ•ÆUFí¹š{Œ;Þ;c¼BƒxpXà˜²\3$�xah~tlä#ûÙ+î IõFŒ©iNZ¨fÐóÇÅãæh6IØZ«ç4gÛ¶­—,#oDGEÆ­âµ^;@ð õÀÚvÃÖ$–�Cp]w=ö¨ÕjK—.ÅÚåÞú¾Z,ãEõeQòØ$´+Ak6” L³˜dµ~/Kï(Dz µ(‘Ùçó]+¸Ö· ‚×L÷/­^e¤"nx°V±F•ÏÊ?¯ŸS8~ íkmò†¥ëJivÜ×!G9øÄØNŒ"¢�a‹³QSB´ªˆ5E¤Œ�ª)¾¥šœÄð¡Ç¾"b6N"�#žç ·Ìçó’ÁÜ û“J¥DZ´Ç€Õ 9Å�K)•Ëå¤Ëæ~²aÞ|opÁ ýSûÅ_\»ví{ï½·iÓ&ß÷›g7í´ÑX‚¾hoò7ÀÓÀ·DÁ ÌE¡”ÄÌ¿QÜÑZßHÈØ†‡›.išªTIõ3cÆŒSO=u—]v©V«7n¬T*ÊPXðB?ã�нœy, %/rE®3¸*–NÀ¤<x\†uT5€ÞÌÙC)Ìh9r>œ*`r¢šáÁ>¶ÄbÖÔíÐ`’ÞÁ^`›O™ÑIQlÄfj~ÉÿÒ¡êнœír8ïœwÅŠ@i˜è‰ŒØZèÆË–íÇ7ÿ…)pŠ"Á×ñJ¬ F9 ,Á4m6›µZM‰à>Oí†!ÌfÉ£9‘”¿aD¾ÅÙ3l Šl—%/á¾nš¦±ÂÈÞ”Mz“ÁƒJ)e¨¶+ÚìͶ5dÅÖ¨ë|©NÆoP§x‚D*<9¬ÙÌŠçEX€ÏÆÄ<”èoÉßCÉJµ#Bî,õ£ ™ä/»ººòù¼”8¨uŠÅ¢ÜÛr¹Çñàà DR­Tµ«Iœ†‘-g1®ŸÏçF½^—•ÇñÚµkæ7™•»87üÔ°ÿ€_}¢êû~å˜JðÍÀû‰çú.øñ²DYY™a%îCðéû> 4bHH.LÑ´|ÛòTÀè8K95;̸oÛ¶íõ×__»víâÅ‹}ßó±*š0)U¾<ÙL&ÃÄ3&b¨‘IþuMÞ#Pjœï‡4¼: Ã$`ô¢Ñh`î‚é(7É«k<x {�N5&!»? Ägê‡6*kFò»$›ÉÆql|e‡ÆÚvýa}V46™Æ„NdOB:b\EC‚šÙ˜N<Ö¦sE‚‹”Z„›Þ\!i®?¯?‡ÄMžQ`r§F³†&.39lØ…¶Ô‹7¶îÛ=·ä=¥”aª& ‚”Íf«Õª\3ð¶ãØÆ,/ƒb ´r&e Â“»<MÂŽo¹<vlÉ,ÿÍf³BóEqã8Žïû¹\.›Íæóùöööb±˜ËåÚÛÛ»ºººººr¹\GGG[[›mÛ…BÁ4ÍÁÁÁR©ÇñBµ°f×Öíµ.Š¢°Nûý4§Ï)l.H˜¨P[µZ•¹b±Øl6´ÏF£Qx·àç6Îhl½~k’$ÆËFþè|ëÌ5VuÒh÷ì—ÌÕ<0dN4 £\.£RÁ©-ûÏ‹×*Wùr«ÙÁV)•;7W{®–?:¿uëÖx@ÖpÇþÃ~ñÓÅÄHX΀é£h ° — Mª€›RrÓÐ âMÁe´¼!-ž§Á{²ã‘äI¨„«Õj,ªùšk*JЕG× [ Œ‚�ð!Æ*± ùß Úr¶}�Õ7'nØH²š¹@Á È*ëho²Mª]H ²x³€�ÍÁ.<¯ >±[;ŽEœ¤�×ógŠ+ƒ€;:‹3ÎlƒƒÌ Xï0œÎOÁŽå¦´†FQ4eÊ”B¡°|ùòž´@ú¦IΘ¦™ÏçåÀÍd2;ï¼s{{ûðððÐÐÐPUÀtÔxÕ2—lšï*np;WB”C=Ï“:¦­­­­­-ŸÏOš4©½½Ýó¼vÚiÊ”)Â@ÉårB}6 £X,&Iò¤ýd5_ºmêœgçlÛ¶mÓÖMúÄŸâ½ã®·º:ú:1(’( •™¦)‰,ËüC�.}‰�� �IDATyó¿Zp™i›ìøÂôb^·¼øµ}Á (h;A°¬EÔš³ Qr¡fJ’ÄþƒÝ¼¼™y9¾Aï‡'†ÖK–à5 !Š"‰í4Iˆà#ð& —ñ ú‘¼fX¤‡y@ QG•#rÀ¬ßÌÕ#ÒƒŸ+X¡­­­X,nÙ²¥\.kæ—Á\¦ Ó³CIz;£jÚ覦 \2‹ù¾ëºâÝ c‰#àÔan¥�®Îx—dÃeF?–/\jp8A €Û[áj± ÁÐåÙoæûó—ãSHºE@¨éŠv¥Raóv %ƒB‰eY;ï¼óÌ™3·lÙ²mÛ6ÁÁŸ€ÄL‘p½išÅbqúôérnÛ¶íµ×^äP‘ÔÄT¤Ka„›†1I�^p¤f³Y ’&\²L&ÓÝÝ-œ &Lœ81“ÉLž<¹­­ Š&È2™ŒRê…â Ÿ¯}~¦=sÓž›úúú\×µŸ¶ß<òÍÌ¡™ /N¨ÕjX8pÃ0Ìår’Ǩ} Û¶E4Æ368:¹t–Ež¡"é~¦’#Á’Ç$d8"'ãyREÖÜQGÿOªXI†Pp»?uãccÿã¾ÿU?Žbs½i½d™/›Qc´ ¤ @ ÎÚ‹YÅ,V­èjD@“›=h¥à"ùtõoJF`Ýø²€é´ùn“~$ü d‰ò ð¡}hÿý÷_°`AµZe²53§‘ÿÉÈ*ׂ<1ý¿—ú{ I3“‹FKdÈ‚›bÓbCª±~_šCÏÙ –h[BÒ4XÒ"¢Àš‰«djLè_9/äeêbß-|(h—¬‘ÛG],Ú¡Æj ã$ŽâkBuT^€ çþ믿¾jÕªþþ~ž¥à£ ³±%°Iu544A{{{¥RQ#½ÅÐ&e¤Él3i•¡- *àÈŠ`6›ÍårÅbQŠ›l6ë8Îĉ{zz:::¤¬‘ÿ¢º•/ò`æÁ}£}÷J÷²söÔ©S%“íè蘴yÒÃG<œkË'„7 3Á”W�=Œ¼hZÌ1C³ µ­­M€²ñ“Œ,,ÆRc  h 5¸l: H÷“Pâ£òˆ+qú»T=­œ.ÇŒMUWj@)S¥FÊç>úXÏh« å.Ÿ9;yRÈ– 8Ë‚4À-x’šûðØæìÓÃÓu(_XJ† ¬èÁÊo<c‡-&_ Êò—+W®¬T*ï½÷žü¢ìk5¢ýŠ\å&»’Z`e¶!g»…V‡d’¥L!hX*9$ÛE²£ üiŽÅX[¶eF,|æyò†ky†§Y³):ja‡DÙEðñ”Š q‚Ü #ûì "g½6C‡8Ôl6åtT#®Ìσˆ"9µr¹,}uLº Œ£elÝœŒ¾ï¯X±J_Ì´o )__6|µZÏ×€0šr<I«&›Í i-­X,¶µµõôôär¹¶¶6©·º»»…, ¯ADg™†šQsRÇIÃ4äÍ%tutÛE;Û–u‹n³Ù”DZd¸ò!9!]k'&zÀŸ†¥(þ ‚ ³³söìÙÛ¶m[¶l™ü¢,$ !‰fBƒÉl+ Í!§‰�$=ìhÐ:”«fRILÃTJ™öa4™{Õ´Øú×! iìIÀæi9(Ǩ±Nç’Žðç¢æÀk@š`ª§(JÀe0&ÀLvH¬ZGLÞaK|Á$I6oÞÜßߎ)§L „W¼3y@0²½#äl7`M+)Øc  ¿ Ã.’=IÁJ‰!¯~NŸÁébøÏ.ଣƒ0†q¬TmšÅ; )Lö@Ú 4b6ã,%3¼áʶÓÌJb €{B\dJ¬B5þ®Ü„ÎÎNÏó6oÞŒºMѰªLS'] ‹1Bö¤<¡;CS2Ìö‘�€>ŠFmmm“&M’â MS‰4rýRîäóy‰1}Ý}ó»ç[–Õ“ôœœ§¹Wpã„Ãáï&ün}Ûúf³Ù×ÙwÊΧ„Ca­V“f•€uÕjupp°\.Ë"”QòƒB¡ @?V7Þ¸K‡éݾ¾¾jµŠæŠä+2Ÿ!3Ô èd³YA,å·Øg 8»iÔAT¢©Ì<@^3ÜÒÀ×i6›ÇT$û¯ÆšBaã ªC"ÂΊ<îÆˆÇÜ1mš r \ W™šm¹ä ìÎ�$ µ# )Ù R Xæé7¼ ºÈßá˜Ê)ÚŽ*gûW9šÙ i¤ÊAkN¿èú ?J¦»yÈŽ¡d0A4œ­WE¾L¥¸+-ùEiÏð3Ûgqó3›Íš¦))¼liÉøŒŠÍØ Þ T½ñ(9Ž~5N÷×÷}ÞQÜãoÈßȵ)òPê%ÐÔ‹%!Ðtä6jõ ûïqXbb8¬ð÷A —ËÉ‘'åËÎ;ï<qâÄI“&a(¯§§gÊ”)AÔëõ8Ž[Ëd2_øÕÔN‡‡©QskŸ/|þœÚ9Ç…Çi.,džÇÞ™¹s­¹vZ<í)÷©ßx¿ùÿ´|ªë©Õ¹Õ÷|ïWú¿R*•Êå2rÇqÚÚÚÚÛÛ…¨&ß±Ùlʬˆ®ÊQ+§›"q{)‚ñp}ß_µj—Éd°tK¢¡†g‡9¼PcõÙPײ”ôØeû`¡Xáâùœfs ž7¦Mñ2OƒŠ²Ù¶L$Äǵæz…ábf—±ð³Âxn –w’rñ¸¢8W±ñ!¿Ä¬Ôñ:¼\îp}–ï¿‘¦oŒà„ìwôr¶çŠœïìý qm¤\¶ŠìÌñ6j¬D&˵ɧ€ÄL¥:/ Í„j i`[ò ˜Ó‚qq…„ßBÿ™ýÔˆ)µ†ÆDQ”¶¥I>q\'޽Z F@0Àï"µäÊF* !j€²@:ŒZ0æ944O nBpZ%,UÄ{I ÀŽÃc’Ñ%®Ï�¸AY�àŒ›ŽŽŽ)S¦ôöövuuÉ{öööÊéßÖÖ†;ÜÞÞ^(¾Ôû¥ï”¾Ó¥º:U§R*N⣂£nËÝÖõìì«È­|BsBìÆk“µ+Í•ÏÏ|oà{“­ÉÃöðúdý å>’~äs¿ñµ¾E5Ñ—Š6û ¥é6J@æ‘CV€M‰äÅ@“$”âäB£NJj¤í</…ÑN6fæY`9‹¥&¿Î\,Ù ZuË=T”鲄öP<©e'–®Ñd=‘Gj%&#Ø9`÷ÁÁh|ç_“ß–¯£H¨—µÔ0ÊdWðò¹”a_m–Ж±mÃ2(EQ†'5fŸ¦?Îd6Òt ÷uv„œíIµ%½’¿@ï ¢2o´‚‡Wpî#7ä¸Å“è±\¹À1~ÅŠ–˜“@ö„öH_œ ÊtŽ«‹Ìå¦XħH-MÓ ²Azx${$ Õ0—›áË¡»ÐU%¹-Lî’šŒõíl@Ïñu[†2¥‘¨ŠÁ…ÑNËy.MÄ?°àøT‚ÌôIòžÏç;::òùü”)S&Ož,Ì(ùW±-A¾"ŸžÉdVº+»Óî]Œ]<Õ’6ðLoŠš²{¼û²Ì²}£}MÃäöªá«®n»ú×Å_S?fYvÙRsé½Ù{ç4眜ÓtšÓœiñžñ‡rÚ°aÖ-[äL”CG n9Ô„À&T‚(ŠêõºTo’1Z‹X"$Ô$ ¡áN�Š.XÙ-t¸¡¨HŒ™ç¦µ|Ksõf™´!¥$KTópÓQ±Èកï– “ÊZd#Àl0ЬmWÞ§¸3ìÎŽeÉj°`ÇàÆÂ‰Çæ!áò@ÿ´rð$ߟaY· J©ë«Õ_¥é_F&ð¸i½#äl·œhhÞp¯­Xo±Ý½"Í.@Þ óâc¤˜M5´6/a§ W‚)KšƒÎ/§-f8°¾5,þÓHKÑhÁؾZøåÐ0 ÷a×ZdEQ”ÎN£¹Qp@`_k3b®UiFƒ•BÄô4W“(­p2JåÄEŠ3Îð€¾ö3ÜE;&r»<ÏZ³ž‹ÅbWW—ð䤖&Š£òˆeæÆ¶íùùù¡Þœ¿9MÓã¢ãŠ’=×?÷„ŽÎòÏ2ƒùE¦i^SºfAnÁÑKœ%®åþgõ?Ó4“Ø5Ü3£3ÿ8í_I¾"ÃFrÙ‘[‹E(5 Ñ€«“–æƒHÆü%œà|z¢á‚rìßÊg+D Ù¥c>†=§™€ŽgÇG6ra‰J bB.—Ó²7Àhj¬º¨¸(ßPùn�`ét4!¤„†ûÏ}Y)ÙaÈÍØÌd9LtŽŽH(­±é¾F«ãàgšæ§Ã°ËqnrS)Ã0þ-“¹0 ÃøË8­!g{2žóàS~ºÈÎäø“@Å´Wæóh2,©Nxé`asÀdÀȘ,Ë . ¢C"CƆs¯PXê0ÁI„ÒÃ(°{¦zKʯMíÅqÎ ³Gf•¡b[–•¼™x‹¼úóu 9`”�Ý6­1œ[,’Tj„Tæ51–ÍI1:m|á« B‚C„­"€ìkŒ))k¤­-®½ÝÝݽ½½Ùl¶X,²œf`å:E�4›Í.t>‘}â ÁöJ÷J’d·àÆü¿)ÿÆQ-òÅ9íç¨D}¾öùÃˇËÑcÛ¶aÉ^ìyTvh‹DÛ”)SªÕj¥R‘;ì8N±XLÓ´^¯Ë% MNƃ$7ÇÌ;\È5KžW)Pb&b!wæiGyRÂ-Ä<�FppgÀŽ„¯&¨,fkP31«»›˜_–k–÷g9áFr`Àª@@Õ¨Ò#„„üˆx†Op~ÃäUvïÖ\zù ^«Õ4p“OФ ó±[1" Ê—útd•úU&ã9Nwwwš¦›6mú¥iþs’Ô’dÕ…Ô“$j`@õönßxƒ §æ4á¿‚1I†jŽ<$ÍAÁbÏ16>- ·œ›hÕ 95!­*ÒUlÕdŽÝ8ºÑøvÃþ‰íýÆ3M3>=öÿäÛ_µ£Eê-€$ò»( °�S€292ùÐúƒõü™ù8¥ã8N©TRJåÎÈ5jx§yØ/ËAÃÓþò¥@$cDP,ù áš@ªdÌÈÐè:œ•#ƒ$ÏÞã #�4À*¥:;;hZ.—É�Ñ9–ƒf™L¦­­MP¬ ΆùùùŸ >µ{´ûÇ›7”qHpH]ÕOo;ýôÊéóºæùÊ¿­ï¶œ—»3wç§üðçÞ›ôZ–ef>Ì÷Õû&§“…$ÒR: šÛÒmív»ã8&L‚`ýúõQ G@†uºººØ¢8ŸÏ‹š¸<n±ce¤/°!G]·ǽ¬Opa„a†€Ÿpß`ØåˆämåqƒKÂq°øÀz�Ü:ÞMŠñ�Hq3ÐÊnÈ y F;L^�º€í£ Ï‡è¹#�L«AfƒÎzl¸LØ  g vYï'C€÷ã8þ½mÿ ^Œ¢rw÷¡‡ºqãÆ÷úú Ãõ]æ_Û“Úo|•QJ©-»oÙ¢¶LR“>x!çÑGÕO¨/YÍšµ}{9üghhbº ‘† <è–óúШ,À(X€#î˜Ü„ç9T¤ø’0 Áb”–e©6}-ê8®£5`o(çgŽýS»ö|-{d–e䙱ʄ"ù\¹�u—#)éH¬’e¹Vww÷ìÙ³ëõú«¯¾Z¯×Õ J;GÉ~,Œ²ÏÀr yœ"e9TŠ ¡—¦ÆZA³N À.œ8,¤Îc¥/¨À­Zøu‚)'QÇœÔ1ò %ô:Ž#ò¯Û¯ÏŠfýsãŸOí8õpÿð¢Y,$…|š÷Rï•ì+GÖ<½qzOÐãÞ×ý¯9øò©SNÿî|Ó4ȸȿèÆî¯Ú|•ïûh3 ø·ïqûü­ó#Éiǀט!!¹§§gxxX(ÚÈ‘!;SE*!mØVÑòøñ2ù›Z­&ß]̨âѳÞ({ Û&¤VÝrïÅ‚¶$ëÄhm{fôo<Ìy=d„<9ÇŒGVžÆfS€¹9ˆàº\ëŠñÆÑ¦P*iÃ¼ÌÆÆgÉ¯× ã’lö'õúÛ¶½ôÒKA|2 'ìlÜðÏi²W˜;9§šÊ0Œ[ÜòûC~ÿõ•Ùjö)äÜwŸÚ´I]v™ºë.uÆÛ1êpvÌt�6³â]ŒUÎ/>±:5VÆÅщ#Uþ ‰œ«c¬<É¢(Š>Y¿±$·Êçó8ƒÜùnøéйÏ»¢üeYcM>BµÃ5ÊP©RJµµµrÈ!ýýýK—.m6›Q)c´õÊUÂGŸÕ(ãà!¦)³j$*ÑÖ…ï�ÂOùiŽË(YW¿ aEËl¯�\Ò¿‘_—x#37xœ¶ècÿ,÷³§†Ÿ2MósþçnÎÞ¼¿ÚÿÄÆ‰†aL§¾æ¾vbpâ‹ÅŸÎ<mšæ±µcg…³Ž©ódæÉ£†²,«×ííÉõÜÔsÓ±K펺Ó4}e—WVv®Ü`m¸®p¡ŒóÊçu¶u è·yófLJ,Ìd2 ™ )d5™¸ „†�M?îÁ°°4ðX€A«V«\<a3%P[Q$šÉôen¶!åBÇBDÚd;@+ŠfU@ÔU<; =MЂØá Zèvk0”6jŠ}¤¹Jc&—u<)fi¾mÜBÖAÚÄ“àã¿8˜ž¾Æq¾Üh¼¸qãô(ÊƼO¸f)ÊœÁm¹V][P…ëÕõ¿R¿úÀ„œPýýꢋT6«Î9GÝpƒºæší‚°¡ÉÌQ¬o¡)5Ág§'< /+ÓLt 'îh'šyûx‚™6~Ÿ$‰ºŸ=2kÆôéÓ÷Úk¯U«V½ûî»išº¿skójÞýPA&ej®',r#ãÓœ-¶ +¿åÕ¾_Ë|#³uëÖ‡~¸V«U«Õ(Š‚ë÷›.¾…Ä�䳨]òOGʼn–7FiÅüZ–šç™p ò‹ò �žÈÙ§aq`Iqòeò²òîåEÿ´È¶ì¶¤íœÇÎ~š@mRúH®ÏçÍgÖ³‚³žsž[f.ûtû§ ÃxÎ}.QIdF_k~­;íV±z<ÿøOÚ~rɶKîï¹ÿ¨ÒQqïlìüÿ3¯V_½c¯;JNI¥jC熪[ýÑÊ Ã0¾ÛóÝÉÍÉ_ø¢é‘g$s©’sÈE²µ9êHmx^f0¹ï¢ÜÃÜŒÁ^ß“áJ®„ d΃hà@òvcqÐ/µ!|ž>–?KñU=Ö¤ «gÍPºìÂv2`ˆAå- ÿw¼¬‹§¡ íw†…yÝÅÙ+[N¸Òd>Ôˆâ�›Wmû.×=ß÷ׯ;ÉÁIæ?2¦ÝEµoºš¾¯Ú÷ê'«“ÿÞCN’¨ÇSkÖ¨¯}MÉÒÙuWuíµê ÕÍ7« ¶Ë((* ¢kóá¼¹èa8›Ž ,I M‘Å+³6³@=Ü0€Oïèè8ᄎ>úè lÞ¼¹^¯³P#ûàj¡dŽ7:µöÊQÚñ«freÒœÜL+éÒ¥Kã8Nò‰9ÁT»+ï O$°`•ˆ“f_ØÃ|îpÇѦ¥jœ\†38{eA0ÈGâÛ¡ŸÌ>’<M‚éœV;§W½ù/o¶•ÛŽºý¨ÞÞ^³Ëœwî¼ÙïÎ>mãií˜K�lã0 7ÖXkî=¸;é6Móg•ŸíîvZý´T¥³{gÕ<êoüKñ_Êny‹¹¥fÔ~\úñçwúü'ýOöôôÇl§x§Ãʇu­ìJÍôé]Ÿ>¦zÌ?Tÿ¡;í.…l6{àЯدÌëšwÆÖ3DMšç(³dj•íäZŸñ®0¨3�Žñ¨¿ñ”b©=°.Y£…4ç㊆ÿepv5œñ 3è ñ1VŒ„§AÇCœ% ró|1š¯š`’³Ë€q„8&I>(›Í‚Œ'ú ¸‡ F éà eypïƒõ÷ú’ä'ŽFÚ–ÆÝ±Îhko›3gN.—{â‰'LÓ,¨B—êZ¯Ö�ªßW?®¾ô%5’ªd£Î<SÝq‡úö·ÿö!GV?ÛCh@Ø,œ:iZjì:.¿ gÌ=É’@!ÃFÁb8@Y#·­ ^è˜G™áëáªU«ÇY¼x±tàÆ֟GÅÓ0nÉj¸8D ŒígplÀJ’$wi®ñÃFðF¾ºŽL âÙqîÒœ"ßx1 ¯§‹q‰7€ Ê!‰æÉv~gÜdü®$ò…x-ªÞ`  ʵ«%<ZÞGþfõ¥«÷ûù~SšS²Ùl¾‘ï¬w^rÏ%Ï~ìÙ {lØ«¹¤3qÄK¦R.—E‹îpî˜U™ÕcöÜ:pk&“¹¸óâIjÒ9µsfÄ3 e<•yªÏêÛdnúNý;ÏÚÏÊøNûwÊFyµnkvëkŠ|Ó4wÊí4hº®;½:½=lO­VR  ¦kå‡:ÒàB¹\Ž€BÓ(•J•J¹3[ çdR"ëÀbC‘Ÿ7$2™ œÎ1Z >iØlø¦HÖ?I=ôçÁBæ6!DÞxÿ gp`ÁÀÌH埰!€Zí}ÛŠ°xgÈN»]²‰„Ɖ!Ÿ"¦Gˆ£h·«âý«Yq#ÉC‘¿¯)¥À8¹B)L?`Œµ\N]q…úõ¯•Rjß}[y÷ÝjÛ¶¿}¼áÒ•É0è—0ȆÜ ¦@e�Pç€<á²2ÜÌêA€üÅ€�¢‚{[ým5=%}å•WÞzë­F£ÑÒc¿"ÎO¬e—ö Dhg:ãà̳m;\æÎÍÅÇÅÉ~I¤"çm'{K6MÓT¥,ÇqtZ}8R†²^¶œ§ù¾!Æ¢¹çrÓµ‹¨2ËN’>pÖy+ø–ºJŒrá1#܇ß-Pn[ß–id2¹ÌŒ3:;;…ëupùàå–Y:²Ýiòô-Å[jFͶís£sgD3–šK¯ì¹²«Ôµ·¿wg®óÇ]?þ\ãs?¯ý|¾;ÿŠâûûEF¤”êIzNNµRëâúÅzîïïÿýì÷Ÿ÷ž¿²ýÊ}Â}®(]!œÍfÛK^i·U»5 joõ—½¿4MÓíóûÎïÈv¬è^qDx¤º¤«$‡£(�Ùl ™5ê3ûuJ*-S¥fÍ=…&!«¨±“üØ 0÷c3CF¡™ö"ŸÂÂ3XBlª­6ù{ä²£…hÇâR<õÅï Ò¦\ƒ„%°Ò™þÇ3ÝÌ€ȦQüÁ‘AùÎwªÑ:AÈe#s•oŠê?Š¢ô½Ô^iLJÅà ‡üq¥Ôððp’$[ÕÖ5jÍ)ê”F/gÚ4uî¹êúëÕUW©I“Ô½÷ªrY}éKÛ‘;À"ù�F¡ÓŽlQ�t1l@€Y<œ€hMËBg)@Lxñ`ðe)ƒ˜ †MÈcnª¦ÜÝú#õðºÐzÉr]7<# >Øß·Gm¯F|5Ö—A6Àü_žZÞm=k©gG8{¶b;MÓh¨þïukUüK1‚èÃQí¢Zö¢¬Ú ¸á ‚(©í2ÊÇÐ"<oØwUî$�4±kãQã#i�!ÐuÝÁý»·t·%mÓ§O?æ˜c:::–-[æûþÔpêSŧ¢fdÛöÿë‘â#ç7ÏÏÄ[Ù7Ú7®sÖmÍnÝÏßïTãÔ!sèÖÌ­?:Ï×gõm1¶üÕþëѵ£ÍÔŒøyïù+‡¯ì5z™ýå*kÕ€5p]åºo¿5­1í€úW·]ýíú·s¹œ”h‚1Þºÿ­mmŸQŸQJ …CL¿`“³éŒ gH¼”ç+4 IkÆðð°tÚ <㈄ÆK�@¬ÿÊêéXÒŠ PU$ᣠ.&äí“PÖ¼ï"FŠ8¡±ÔXœ~´L°£áS®ÈÆFŽiÈ!*[ÓÚE\öá¿,¦ÀÀ£4ÿd1 L-1åÚŽ‡d¥Éªá¢ØÅÌðZÆŒ5†Œteš˜ÆŠß{ï=8rõ«þõjýêÀ }`útuÝuêüóÕ™gªÍ›ÕÅ+jþí{9š3ÏаîlGGG¥R LMèa0õýs(TØ ­#ô�9?R#ÂéÐ!-Ç0 C™ùïQ¯qy#¸.ð ß{ÈËŸ—¢8mIzHûÕ4NfL(hÒl:µ‹áuI’V�óTýûõö/¶wgº{Úz6oÞ\ZX²n·êÿYÏÌÍ@6Ô*XÑ„ÈP†ŠTº>…ˆœQÏiÂqRpH±î[f!7¬\ry6]å^Â?TúÅÛõÝööövÚiâĉžçutt”J%¡J;ŽóbáÅ­Ù­¿(ÿ¢f×^·_¿-sÛjsu1-ö™}>>-švxzøñåãoÊÝtTxÔÁêà(Œ¾—ýÞ~ÍýLe*¥®._}GæŽç¼çº’®K›—[=öeëe¥Ô}í÷V=m­¹¶ä”ºínÇq:Ì×pç2ïK>q®'ìÒ±‹iš•f¥cMÇ/º~Q­Vººº`$w¬Ñh¤iZ.—¥ÞÕú+<¢„xÏ´¡Ë�� �IDATj†:ÕˆÒ"ud�¿\7}î 8vg¼e�Mö| 1:ƒ¾ˆFCta‡idà‰ÈÜn¥RÖG.Šdr0µ£Fœ€â²ú�ËK3¦'_D‚["‰è5k„â(ʼhj²ˆ3†Ø¢`c3ÉBølU‹V˜ÄŽ.ŽšjzxI’$QòO™š¥fýZýú6—“Ï«ÛoW·Ü²]ð4 Xƒ®IóC•=P.—¡ÂÂÓ-0%”Zî¬"ƒX-ÓW˜á£ébÓÀ4MÝÄ5ûÒó”7ÊV‰2Æø�áÜ Ñ(Ôâ6ƒü‘O.$ªµ#jîî$oÒÜ9s8à€×_ýÙgŸíëë‹ÞŠÒ£Rw¡›¦i4'ŠgÆÑ!‘ai#µØÑ’È^nK¦‰³ŠråÂ]f¨ &è4XÄü% $|Þߌ‡ë­õÊSËi>}ï½÷/^ÜÞÞEQ[[Û¦öM;;¥iº>³þCá‡V8+îÎÞ½O¼Ï¼ê¼ òœœþ½Ü÷nËßöVæ­OW>½›±Û¬hÖzgýµ#âfl»¶ïû©J•RNèÜæß6§kÎ3ågÒ4}ÆxæÜös•R £ñ‚÷Â[/¸±óÆ«6_¥”šÙœ¹s×ÎV>¶ïØj¶Zµ«ÙlÖPÆ@ïÀ’ Kz«½A âuBÝ–xS*•¶mÛÖh4$‘ .¡¤—Ïç+•ÊxN9²MK J,þz½.KëDÏûò>4GA–,Ã. ª4.{0çž)ËXÛгàrA‘ ÄÊ0ó€À@î ¦†…› ÆJº¡Ú“ïˆ�Æ$#¶1("fÿxî{JÀíO0âŽ2âPt$ͦiªHeoÉ&7%Ÿ77PJݾË퇩Ã>0½þ)¶o¼a\ç/ðb®ôÁüa» .„‘$‚OÂ^U@ÀÇ#f|"H|â¶¡v©h™�M’ët]7ŸÏK¾£Q®Áü‰G¤ýà³ÂÔ~Ù*<} öqhœ0©©uZ}'ÚùS;äèœzê©3gΜ2eÊàà`½^7n2†îrNu³ÂtJj¬1òçå-Ë ì øb~(MN¿ŽJ=¢•­H>DTÅDåA.O‚²l°þÔX¯0Hcd¡äã‚Ë{ž7å/SÞüÄ›Õ5ÕJ¥Òß߆aGGGÇÏt>sÀеfíå]^þmé·gwœýþt׿¯]j/=18ñŒæxLH&\Û~íùÑùּλî„Ú Kã¥nÕµ6XÇÕŽ{tÖ£Oæž<¥qŠRê ûGœGî÷îWJ”éOz2ך›kæ$1‚ÀÏù¹(÷ÌîÏäòwís—뺪¨’fòÍ5ß¼òýû¯Ù¿=nB£d²õz½R©T«UpÇ…%-eT“lèˆ ÝœŒèos¤çˆ;`òŒ$[Är]àº,ºŠÄŸ?Ì1ÁÉ„ {V¦”¤ž€¸³�gqòÇÐ÷ø„OÞV˜¸èÂ\�Ÿ‹ oüÌ~ä”�Ýâl›"K±9,¬À3 ˆÙ<N /Õõ8¿µķMÕý¿˜>`þoç?°ÉO|�ò#±꼬jƒ±Jd7HÉq2Bae<Û„›²+dù2‚Œ&c{ä›Sv# *è¸ ÂáG‹aò#JSÌ=ås =*æËr.&¤5ieKC¥%¤¨Ò8Žƒ¹AþùÌ2­!ʦåÞì¦qOeÐAöŠAymDGŒ …rªÚÆÔ½çyÒ‘†<lªqý ݺ®[($fôØA O[ø§“ÿ$uC_½ïНˆ’hæÖ™2r¯wï\n{Üþªûêƒîƒß­÷²Æesƒ¹J©ß9¿»ºqõƒöƒ‹œE&ßŠÞ úƒêò꾋öUJ½”}é m_Xe­º(Ѽì¼Ëª—)¥6™›æ ÏùÕÿñx×ã/t¾ð|æyá5¥i:uhêÛû¾}ãá7ÞÞyûmùÛ¦%Óîi»gCnƒÇ‚jÊÑÖl6kµšöÈ3‚ôBVˆ¼ë òJœžÈ*¸^‘£PNC ðâ‘l!2!Ò°A�+<_à]Ü<gÏM î€,¡ˆ¬ò¤˜;£FP» SÖ§æ‚Á¥¨wÂ;×ô @ÜÀ†‚Ó¶!v.ë)H/б"‡*ìzù!Á‚ƒÀ¶Ù,„1¾_À$Uš£è¯ÊùŸñƒò™Ç­¹½©H�dJéâL!šWœà�¤‚@µ‹d«°Þ¢,/Àµ€Œ1-RþF ÕÉGˆv½ü †:¡—Œ(Ç W]Œt#Ô¡úa«lÉ%G} 7¥b饗^r]wæÌ™/¾øâÂ… K¥R¼gln2ƒ‹ûv°2èhëØ{ï½ÛÛÛßyç 6¸7¹þ/}o±n Á§sDÑ9†oDz€ÿ/\$ð²ï#Š<mŠþ¶ˆ¤!Jå7ç»û¸ú>õ=é_-Ë*D…Ë_¼ÜS^ÎËÅÙØkz¯¥¯ÅÑÛöÛ5£vkæÖùÞüµæÚ š¼f½vƒsôxÚjgõ+Î+ŸÝå³{oÜ{΢9•JeŠ?å¼gÏ{ê°§–¹Ë~<üãÇóïïqGîŽÝÃÝÿOýÿô4zö~o墳SØxÄcÍ>é>m™¶.³ë¾ýî»íÝÛfy³ÚÒ6Ã0²IöÄáïl¿siqé‰á‰‰1ªhW©T*•J©T”<Z b„ü�j~šç îÄÇ8ç`½5œ¤èá¶ó /£^|¦cš¡$yˆ¢™Þ²1ž¾„ƒ{:d+BíG<Öê'¡ÏÁ1!ŠtFjØFj¦ÍµMÓSrIèÍd2 ®0-o‹Ò` ‘ø-–Ò¨×ëXº¬¨HÇDn5kÄñä,�i1yý#IÿOý�-¦ü»ñ¼±¤Hd¤Xf—_БFµôžƒ@º´£±dÊʃœ>Æ,@2è,½"&†Êò6H=ò *ÇK.°˜Y‡ƒ†5ì=dÙ²ùšœ;Ùó²¥ß—Ì“ÍgžyfáÂ…}}}2äÜüE³pt!¸$0cÓµÝY³fþù“'Ož?þÃ?\­V›^3ŽcCçÀû ·œhr+`&¼±JåxåL}òùƒ8¤¼ÐëøkÇŃ‹[E±FÐöÝôe»]6wpîýùû¯Ì_yUýª——¯ª_unñÜ­ñÖõöú[ßzÍ.×<ÓóÌþÛöŸ·v^}°Þ—ô Ó4O*tþ›çß½ûÝ_ëùš´v¾YùæJweWÒ5MMûï ÿ½¾mýÛ]oGf´ïð¾û©ý Ü5Úu§®&ÆíÔ6”‘¤I.Ê)O¶õ°‰îDø/$I"zÍf³Z­V«ÕZ­†Ù[ 3Làîçá(çé(q—û̦MÈ»Ù,€I4LêÕD‰Ð±`©'T<xšZÇ‚Û9܃Ý‘ƒ@` ¨@ÀøVà›¢;8ª¸Oêïé7jž¡ eýÅ2ÖÖcÓp0 �šàý˶Ũ8¼¥ñ\€ºóíè')zZÚl4ÆÐÕŠe u‡õöüaBêS ÿÚË´T…×í°¿ÏžácL<h²‰j¬…3Œâ9ë”EŒO”J‹ÝPÝk&öhÆò$CÀ`µJ@E%ô¾r8ò)VdÙ ìò5åä÷Ivi¶Z­‡ñ‰qæL’$Iš©¡”ä G^’$*UÊP` ©=`LaìR‰r=ï ÔŽHli>A%À4;äë©‚I(ð©ä°RÒMšrÐÐAwgï~>ó<VÂ/r¿˜ÌþTýS¯º¯®[½.?)¯”:yÑÉk·¬E…!ŸmÛ—•/{¤ó‘Ùáì(‰~›ûí'›Ÿ\é¬üåÄ_V;ìsƒŸ[”Y”˜É#»>rPßA/ä^ÈmËÝ¿{Wo× ¢ ’$IÜ乘usÙ„eªWy5O®Ê÷ýááaqÓ‘ŽŽ(P^Ä•Ž6ñœ:p¨@ù þ’e´P£c©s�R¬—ÃB«LBC=|˜l²”€fm �<Ü«GÇ6ìˆÚ ßK(Þ3O ͪYøf!­¥J©àä Ü-Œ?{ó=`¼À!àÜ3^{W<*‹ï‹K¥›pŒhÂÛš9ä´Ñ †\Lw„œíOЦAÁóˆ±5$#¼¼$©„î$àŒm –š[%NL€#̓S r«L¡e©Ì™aó4šh)F£±‚‘o¢eš$I½^�¬”ŠƒØ¹Ý‰÷ëgÔ+ûTÒ$5ÿlºO¸Î›NlÆîƒnóëMë-kùòåwÞy§çyo¾ùf­VóÏòí¶9h*£5Åͼ)^µïÕÂýBÓ4s¿ÎÙµX�ÅbQ)U«Õ°÷P®ÉîvVðY ‚þô›MÓô}¬×kµZWÒué_/½vßkFC)u—w×eËr*÷­Ü·^ï|}³µù®îê]Õûá5^ Ö¥ëDúLÈÁINÓw¬þ±ÔL/©_ò¦õæsùçvIwy5ûjœÆ³†g5ÌÆAéAͺh‹µEEê”þS¼.ï”öSTª2*sáà…¹ÜJ{¥ˆb”Ëe¹°¾¾¾áááR©­P-˜æP—ÕŽ§¡vd2.hÐÌѹK³µEB€,«¶eOt­Q¨�9¾Ö6ÇÈz–€„´”‰\"mÂ]‚K´ài*QÞmžã8¡†‘{<çOöƒïÆý›CsßÉ“&�g!—å12weÏ-) 9"¯BRˆ3è½*Ò´f¹¶½œÿGŽ<¬](O09 õ>Òt°¹‡/ŠapC@ëã8Ó—Nóìmµœ?Ö+ÕT0of²Ò–ƒk¡R½†9Á¬ÿ°žv¤*Uî­®õ¦e¾k‹C/—UÜåz`œƒ¢ "¤ò2ÍÙLü¹ŠaÿÙNßHc#NÓ4 S+±LÛ4³¹¡©eìilY¶eËoñ</H‚úÔºšªÌ—MŒÖÐPIÓ4TaxF\ä®ÎÙÿj;ŽœTŸ®v~µ³ë½®|ä#Û¶m[¼x16*n Ü_Aº-)¹ç…B¾¿|VÊÓ Ã0—Ë5f³ÙÙÙ) ˜ÒÕŸ`M(†Å]ã]}Ã_o­¿"…§¼ Ñ„Ó6väÚ#Ï:ü¬åÓ–ðà}Ëú‚ž@Lk ©%§äê?º;s·­ìýƒý'›“×™ë¾^ÿúÑ£?YøäŒ`ÆÝ“ïþ“ù§ýJûÛl·×ý؄Ǻœ®[*·ôÄ=a–7—××Ö«¼Ø20¸iP‚J½^ß¼ys©T*—ËRî4›MÆÑ¢¿dË2vùDo€ ¢4- ³4c•,j�'Cäõg#f¼-…mÛa6Œ'Ɔi¨¦JW§èÀ±3,è‹2 ��蜔þØòí0H‡9Vè$ÕëõHÛŸ çä× …‚ïûÍfÓ\o:t_j8óFÛûÌÑ@6ÞÓ%¦ŒÊ1éõr-K’„ÚH@4f˜ˆ9'€€.q4Ù¶-SÒ;BÎöÖøy#@Ÿ À1ð`=À*¶€¡5Î%VºÒ]d¯ø4M£ƒ¢úNuu¼2ä/æ:ÓyÖáÉ>VAý4ÊéÚÙ ?Æ3âÜçsfÉŒã8üj¸ó]ë% “n,µ ßKô%Áªd×wœÐ×ÒÓÖ54R•*Ó0±yä{yßò†®JH7ŒÀ;‰ˆ3gÜ…n”ŽªHÉO«{49ŽæDÅ[(Y¬¼[¼Üm¹Á'3'g–,Y"­rÜM¶�Œ‰‘̹’?À‚S Q<!ïy^©T‚¯íÄqüÈÀ#Í—´_²ÜYþIÿ“‡ÖÝRÛòXæ134§l›bÙ–€„Òö}¿»»Û÷}é¸tzíVûÛ™·ŸÉ<ódæÉ'·<ù¦÷æ‚Ü‚ª[]Õ±ê’ÁKîé¸ç²ä²G&=²Æ\óoþ¿õ7ûïÈÞñÝÊwãF\.—êyhú_§ïF#‚F£Q«Õ+•ÊÐÐXÈ2h6›€¶P”3ðÈ‚Ó(÷Q—Ëh‹+²Ð×D¯Ó$x‚<‚&·Ž=8Ç×F¦üSýxJlìo¤*UUeýÙ2ÖÊ–ðk,ä£ÍÿsÆÞä€ò°xÐÏÃË e¤vš-yºÞÞ^ß÷ûúúÒ$ ¡åY¢,À{D‘:,!Vòÿoº€ °A‘¦ì.õ¥Ñ”wæ$2(ÿÛeÖþ×W9½Æ¦brÖfÇ’â¹}5"emp…‘ä °†&z6*(`áÁaxDh Þ=yeóŒf²oå#û6h]¼nxAK؈gņid/È*¥LÛL’ĽÕ5¦ëù…y¤®|ú0:Ç™—œ× Ã¢WŒ$QSoc˜Œ�ùÉ|;“î’Æ§ÄIš¨ºòÎ÷\Ïå)5Ö$:'2k²‡•¼öÁìðIÃñ#1¾‚ñ1BtQäh H–‘%Å$,I{ £äMŽHäéâý:wýÜÛ§Þ~låØ9朳Œ³VgW_Ò}‰L9öÛÃöܲç_gÿµ>¹ž/ç…Ý088844äºn½^/•J¹0÷‰Â'Š…â¯»™Ñ5í×¼”yi¥³ò‹õ/.Ê.:,<,ïçïÌß91™xfóÌ{3÷ªDåÃü«Ñ«Å÷Š7N»1è>´òCÛ¶mmyâ•J¥\.‹*Zâúƒ[‚(ƒì©œq¸'’‘àÅŽ`î2zèŸ#„€Ñ ò˜à<l}ÄÎènâ#šÿÔLÝÔYáx?óÄ!0úlôÙ{ó0»Ê*ûÿ=ÃkN BDŒ íN­ ¢B«ˆÒÒ"Š-­­¶8`Û~mÅ °APA±Aid–„CÈœJªêVÝùžá÷Ç®úÔÊ)úéŸíó˜nMý‘'©TÝ{î9ïûî½×^{­æ‰ÍÂ5…܆¼ø”âÈL Ù¾ª¯@“=k†¸»I—ŠÍ˜åì¸ ?Àk€ Õ\S3W$vt@UÇùDÆÛûª5Ý_> [ÏÒh;Ö�6þ¼¨ÿw|ñäHüÑœ©hävvA~Ö�¦î y)dÄÊ ‡Ï[ÄÇÁ¶ ÷o90èâõÅÖ­î‰ÝüÍyR!Z/š:M.»þ$ù«¤ô…»n’#»5 ~tÞÚ ®™$§iŒÂÖö­#…u©Ê–î=Ð?óÊFÿžñ _/L#ŸmèâLê8¼:껨/Èù|~hh¨ÛíV«Õ(Šrwäšç4ÓMÏ`£Ï& 5GƒiÿØÁ¤úvtö÷÷Û'5TÍT¢;ޱ­j1ŽÜóÖ=?:t~k¢uÒøIOô?ñšè5£#£_9à+üæ€B\h-kÕësÆçØd’ÙíMqÇŽ­VkÏæž'Žœxcï ¿ñÒ-/}}ïë …B!(´Óö~ýæ¹yØçg4Ïxuòê99¿iüæÒ¹—ÞPºa 8ð’Û^Òù]§óLgÇÄŽV«522b—לú²"U=ý ,òyI›&›ЛÊfTRLrtBEgztÜ’–†&Á^ÉØRàÕD„°—ê×-½½äOø±‹»Ýn0ä¿–o¾íïí·×´!}¹)- ²P‡YN5ðHÀfœœÎÙ἟xÝ·uý«|ëNâ{yé+Ò¿¨UŸ†~¾ªžgr â´›å¤éK,ÇÄ]CˆYÁ ô¢0&,=²2‡Ó9»CÎ.îâp<Ùã7@ŸÑ0­Íõ/&› ¹ÛR5žiò‘¡¨M–D‡tãƒãò¹åÈEô Ûívá¡‚÷B/zsäßàg šÔ³}Raº'ßœ×ô7ø~è  ›¥OÚI8¶µht±Ê=ãlh—g¸³ršœêFÒi;k–Ь:à€öÞ{ï+V ÿWtA^ÙŽ6•6¢gœÉä@¤X…¢Š¢°á¥æ'm^ŸÐLÃÍÃøø8u€ N§§§Ç®á“}òc/üØa»kÇ]¹ñÜê¡Õ×/¼>J£þþ#pd§¯S*•Úív»Ýîíí]¼xñ¢E‹Ì÷ÚŠÓ@‹ãøÌϼùÀ›?¹ã“ƒƒƒË{–7›Í;vø%ÿˆÎÿ¸ Ü!ÝCfí˜õLôŒ¿Õ_òØ’í¶¯[·nÛ¶mQU«U»Q f,^ô“�QÄ`¼MCdô–O¦Œ0M '‚è(%ƒ¥tü“.ó´jžß,\\ðÆ½ lpʨùóóµ×»ÃrPÖ Óñ5F235­ [”øê`WžOòÑÓQüqxH¬ &[/‹üdïÄ5]´.JüiÏFúžuqnX0 A±Í¦ÍÐFË(»S)‡È*¬WÝÛŒ[ó¹°cv“¤w}/‡V„v5UȈ˜¤lúngÙ{¢¶Œt?C’Vf¶í7Û¨Iœ¤^wbÏ󆆆J¥ÒæÍ›Ó4m5Zi”&iâ:“}~eždFµã$&´Z-¢VóSesr1`ôö[™9!…’UóQÀeÞV¯^=<<¬TQtÜ ¸i ÿ¹\.wO®û]÷KçyÞèè¨Ý«0 kGÕÂ_O‰êV×^`Ù%ÚÕö_xl˜×zTvÖj5EMîÁœž—ç–ï5Ü××÷ÖÑ·~Ö÷oZxÓaë›(O¼ë®wÍÛ1/šýó›ÿyí>kþr¡û¾¾¾¡¡!S™L’¤R©DQdÕÏó7>ÿɾ'ýºÿ½â÷^[}mÚLó¹üzP,i·ã†kxžW¯ÔkíÚ¼ óvlܱiÓ¦áááF£aü4;îíD¶´À‰Î,.¥™°hb* Ï$+’Œ:¡óê ¨ h,TQP+3´lÎqf,*¨X”ýÅ. ´‹iÑó¼r¹¼dÉ’‘‘‘5kÖDQäº. Ò0ÆÝ0Põu€¶ÔŽZ¹pJ|€±I8DW—=’»;ç zÍ÷7K–’vâœë<·ãbWº ”¸Ä"e0Z *Zï°õ½Ð×P‚œóV² ƪp [äaÔ¬ÊnUíZŸý`{ý)0Ö°FB9ï2„ßÕÓ�6©å¼UáÛÀ# åéF]'VÁ´Ç“$‰Ü´÷†êXp=DÁ¸‡÷„ñëâà–�U˜4M£Þ(><.ý´D`°ùZ9Å1÷ˆ½Oý¬Tçyžycà ¢ SàËŽ�¥\Ož)ß̵þ©UþϲÅNûß\.×~g{àÕ™DR€e¬(,®å¦\ò ú˜Þ0ýªþþ~;òjµÄ'D½ÚívÒ›ÜòÊ[âGxäõ£¯ÇâpÐ9wöSg¯X´bÅÁ+jw׆V é¹vŸµ•JeÁ‚:_b×c\2»¼7=þ¦¾ê£ï»ÿ}Oîõä—¾œ„ÉS¥§¶v¶>Þÿø¬ú§Çž¶‘ Ç+¯X»×ý{=¹þÉ­[·ŽµZ­ññqû ßp*Ñ»²dǜݷg‹Ñ©af82ò,{X' #óé öáe…“ÍÐêPÌ-$@¡ôRÏü,0f‡çyav›]¨žœª•uBE÷…öœôþðÖx÷éÜwþæ|pSÐyG'-§žç…—„ù-ù8)ÔìÐב&L YŠ“)†`—GÃ.Ö¥z¥3Ò”iÕ(Å\á5†xT„M‡„v‡œÿ½jPir%xÀ$æÊ{QU_¹\ž3gÎÈÈHµZEUI•Ö8Ý’$‰VFîI¿!Îß’†ÝžÄ{ÅùòÎsJ\V^Ü´0I+I—§Ñ £à–€) ß÷½/>0?¦Þ4ÄÑjµø8J´—†ÈJ-¯}=æ2ó€a)Ü”³ƒFHé�m£O춸Âê?¯—?Z Ó4­¿»Þ=©Ûÿ±~¥Ò?°š,Žãr¹ ×ÀDëÍØÉˆx=S« z{{'uH§4­ ‚¿÷“×ÿä/ù‹%•%Ûl{ÅšW4'škž¿fõÀê/,ûBè…[ [½!/ßÌï?¾ÿ'nýÄOþé«xU.ÊU«U¾ŒðfՃݢv»}ÂʾqÄ7Þôä›mX4ÚØâñ÷Ç—/_n:Í—sYc¢±ÿö_¾|ùöíÛëõúÄÄ„**YDdÐ]5Íìš)Ãî- Lb4ùÕ>y€VÕ3í™9÷ÍcB§#  S?*'Vfðk8j ß.´/hçîÍ?ðÀè¡uÏê†ß ;õNšL¢p‚�!SE¯­S…>Õ“[0µÃ™¤?|'?=+SðíˆbÀîÓy#­ufòË!¦Û¾0„“1)*TKÒο’lPÓ4`:¶²^»CήüJ’sÛíÿ‚»ŠÅŒT³qKÈ›43ÒÂYµ+�s¢(2-œ-[¶Øš€ßi)52ÓÈ…¨ÐÙÜIöI¢çDáŠIãêdqâè§ÛÓdÛ´–†7Ú ²%;¹ìnõÓ½Ó‰;&òËû¾ïûí÷¶Ó9iù”2§�)°Ú/ê+žÅX’í¦¢WŸ Ev¬ØC›ÆÎg ú> u¶ƒð²°ÿßû럫7¾ØpΕ¾]ê?¾¿ÛìæÂh5œ7ë•J…‰•IE Õ.²···ÙlŽŒŒXÅ@êÝl6“$™3gN†;úv¸‚;¬qØí‡ß~zçô¹Áܸ'^T\t—»kMÏš…í…ƒñà†¡ ¿QZSjlol;b[£ÕèŽuMÒxddÄ®Ê÷ýz½N¼_òø’¥«–þô°Ÿ>tÀCI’,]±ô]?x—Ë»½íCv?¹ô˜ê#ÕgFž™˜˜€yo†”�ÃU³�� �IDATG-I:%FçC‘“ 2g¢r[Ô…“W³:F{@Ê8Àyä ŠG¹\Ú±cG½^gZe²D^—¦­48,ˆ6GOOxž—Òø€8—w¹ çç&Ñ9ÕpR©Y*'{â@‹Þ)â4¶’•¯­_×¹=UT53z@-²ÌR©d'€Š5Xìò «ˆð ï™hm[Ue& aÒˆq:¸—¨rì9»ìk4=­Ý¾>—{e»í¢è¶|^KÄ6§¢G=SÝ]³'0Vó´WIfeES»)ysw£ëþu·uF+¸oJ‘ú°ÄÛä•/.'~ÅEI ¶i;ç’8Éÿ[>¼,l~ºé zιÜWsáŠI Þe:¡Ü+tÉɺ^y¦±„PPBQÆXšÄ<“™BŽÊçò¾ó‹*N£—ó=ñš úe(õS>Ÿ·F4’ùØ“øàñìüÇkÿã”»N‰ã¸u¶lÚ2¿>þüù=•ž£»G¯K×ýhí+<vÞüóúžêÛ–ßvíÑ׎•Æ~5ø«çmyž ZÛ| ¬ccc&@—ÏçËåòQ?;jY¼¬Õj5íõíiš÷©ãÚíöØØØÖñ­£££F}æ µ¬–.4ŒRZCÓ±M£X ÈdÉ~¦C9³ˆÉ›•Æ©jOÀ“$IëNõ|R.Œ½Bñìb÷Kݤ–xOy¸²‹‰ƒïþc~âM3?èdSõÂ�]TNWƳGy4ꘅ“©fê[</NÚ¿±uN¢‰ôµ–eN„>Ûí¶Õd¼Ž6ÛÔ�ÔMß‘éòyÕ# ÉD–´v»CήøŠ"ï‹_¼; ïóýß gu»¥n÷FÃÎàÅ`kºñH*UØ\9äœÅÔ:´dÙ’$)~¯^vOŸ=òŸÍû£¾u,3#Èï§iÚh4Ü”P.%|á¼Â´{£ŸjÐìRkv¶+² $Pð^Ü”M€Â2ŒÚ±è5wSc HÒÈ·Ó`¬œ¤ì%®9£ËK貞¿Õ&Ïcß´?Õ£6õì"i¨×ëCCC¹\®R®TÂJ˜ ói¾··÷ÉÒ“w•ïš—Ìsέª¬º¯ï>ç»·þê­¿êýÕŠ£W¼è×/š(O<þ‚Ç~æh 1MÅÀ\mÆÇÇ-øU«ÕF£a™©±�ZS_&ÓiþL Œ«Åµ U3hY ÿ,$†´œX?¨+3«Â^™î£ŠEBXP#£b”¶›l„¨Ùlêœ#Âι‡ äè$ñ»Ÿ?3OC"£òG]¥a†Õ8I?›š-SÓM•2·‘Jv|n–¥ý õ¥ŠÖ ³íœ32!&P«óµëÔ  ½Q4«¸6 î1Ò8·»—³K¿Þýî­oxÃ}·ßž&IìyW•Jïj4^•$wLµÊÕÚùšŽVÑ~d¹«Œ¹s5/ÑO\êrßÎÙ’Àh=‡‘ sƒÒFâ¦Ü€2ˆ³ú²$bj:—±hÌHe+—a¦”Õ…v£,‰Cm…tÆDš¦år¹¯¯Ï XÙêt›T>@q õ<%´8QqWš¯©ŸG‡Eì²­w=éwâ{©K£(:~Ëñ×|íÝ#žöŸ>¤qÈòüòNØÙ\Þ|mϵïßôþ¾}¿>ê×£C£µ|픟òÀË( —ì80x§ÑhØÔh4ì}m>”OjgºIAë¡ti_™TǪy:"ÙÄN%Ztje ISMBÉl…èpO†Ú Óωקr#­Eˆ…ZS—\ÇÁï‚üºü¤ýLÙ;B@ÐùVÕ̶X[—LÖI¦žÓ†(™½ÝMy‘dr5"¢gZ߀[ªB¼Nt*åÕØŒ¬[ðj4IŒ,ÒkH×–d‘'íÃý_W»ù¿rþéŸÜ›ßìæÌ Ãp`` Ó錌Œ\DÑÚbq½³šJkB­5o˜9ÇÃ*±^‚Ѝ+µQ+_¸§èލê({Ï”ƒÕ~TG5uN³`J ¾i'E±X(—ËÃÃÖb—J%3µk  eÏv¸]å@c:`[=@‹Å"¿Ë€1tÈʲÒùlÈÔ䪈ú©Ú2TÍ^Ön#Ö«V±Ñäà.•Jƒƒƒ†ÅÙëßýâï>õúO]ðã æFs{Òž5å5›Š› Û Á`Pè/|¯ï{/‹^vÁ¾„óÃ=GöìÖ»§?xúÇݸ£´ã¶çÜöòG_Î}¶ 3Ÿ!ÓåD/@¡5«t¿.?NOaRÑNL±X$Õͼš…g]<4гáéØJÈð$»Ý®­UüäY‡aØÛÛk ]Ø3úPr¢X)‹ö²ÚCâÌe‘« 3šßö(Ùz*VMB‰O°!Ór"ÜN;“ ›¡N øfIžÂé`¿ªû©5ÊÌ|Û7%5Fý‰söÊð5-âc*ªeÓnúÀ.úúÄ'ܧ>åZ-ƒ×£(šçÜiIrM±¸~gþ•¤ÀeQ•Ëe¨AÔ¹Ýn×8ª‡¦Äy Z²µmZ;ßAö4Ù$2©[»Å{ec[jêŠ4uËŽ¢DþÞÞÞ%K–,Z´èÆo„HÆ_àÅYÈ!ÅVól^ý¦qÎ…Ù³gó¹,Odp›>:´ìøtÈ>Z^oƒcsF%À»³ƒ/#Vd\/Ã:ranÉú%·î{ëQ¹£Îyúœ¯.üê¹'‚V°-·í­7þ¨ô£íþö£FÚcã‡>xèw_öݹ{Ìýç_ÿómón›'òù¼5ìv»ÝF£aìm»ù¶ZìÞÚM«T*´�-DqÏa Rf!ö19Ä3ÂzÜgbfˆãNÜeâ86æO“îŽyú¾s*hM«ów¦ ¨v&�â´¹)À(°Î¼–,lhl¶Tôvé(\˜Œ 0ëSµg2ü1Åú˜hVPZ¥zx_©¸®Mê qžt†ænI—.ø?y!¦>*2½;ä슯óÏ_xÞyÕnßÇA}0MR,>´³7ŒRUZÍ?‚zLÌ`ƒa§<Ý]öNMj‹�Isq‚YDdÒ X3”ßø¸êþB×Q«ûÌ_():κuëªÕêÄĈ¹1Èì@œheª¼fåtz … XærŒ@<88h}r¥)ÃÂ@ …;4¬*˜ (¢EbÛ„hL©ÇÁ°{í£™8M†hpìcÇÞ½ßÝw ÜõË=úᢱEk*k\àxqÜíç^9úÊW®yeôLtû‚ÛW/\ýƒ±ôïÑ¿¾´¾íµ7 núðÚ׫õr¹l*œ6jÇq¦§bÕž5‘F¤~eáex’`Œ™Ê�ð“"#ãp¡‡,`‘Ý.£·ñjö¤ÈÐ-§V’Hfø‘4KÓseöÛ©j¹<ŸTµGµªÓUa±Ö––)|ƒT뤳ί¨(uŒF8pfnaÔ «ºuC0ZÍlº\hÀdÀ n‘­ tK¶þ$ê�'*_NUÝÈüP�bÁhszwÈÙ5#9ÛN<qŸ/ùõiúÆ(ú|¡ð;çRf'e R“¡«N8ç‚!6©§š¯vj«n&¸°Ê†’%ÔÂùÓÌ.RÅ*U1 Ìì{ãz"÷ëf8÷t»Ýõë×oܸ]ôÞ•±“™~…f¦Â9Ú|&B0©Ã‘gÓþýýýù|ÞæNtf‚8Ün¦¾3çšjQs~Ù~6²»µ1°am4zšØë›´{«Õ‘³Ã¥Çïyé/Ýâm©÷Õ Bsqóþýî¯%µ“FNª×ëýþýÁáâð3î­Ü{÷ÀÝæþùöÖÛ?ô‚1|Ä;×½³ÕlÙ9nÚ9FáH+_ì†Û}.—Ë„Á®Q mNÆ×ÛÂ9‹¹ &F)³€Ð.Lu*¡ hg-˜2:ëŠ+§Ÿ+´ú)cÅ òO{öór,A¡–¢{Ï¢µ¤2-šµÁîÄzGùœ%_¦¨¨`ôZX–* ¥é‚橼N¦ˆà»««4ç†iüèíEŸ” Å‘¤dwÈÙ•_ ÏûJ±øÑfóSùüïâ8&¥Ú Æq–‚£ÓŽ{�.×!æâ<ω¬kõÛÖ ö¡g¥ŠîmÖœPiw( c´14&±ÿ-5ÓÁX'jh4A+²×·�foA…ÞƒZ3é§ÝOûçøøx’$¾ï›$ðfÝfÈuœôƸ½Ü%ìæ&&&ìš[­V¥R±÷µg! �Ю<ŸÏW«Uo‡WÙ\˜3$Éë·½¾4Vï½ú‹s¾è港ï÷õƒ½Î½n4}Gë³Çg?<<áO,ê.úÇ­ÿxgÿ—-¾ìåÃ/¯÷ÖÇFÆ*Û+sÜœ±±1;P*•Š!xõz½P(•Ë]†™˜LN±X¬×ë|{X˜¯(~H›s €*5 >#vÇä¼ÛÙ€“WõÙ´˜°ŽÍ³Âh3‘#bMÂ1á‘eä¢í¡àȨ2kØÞÅ Ví’rIöÄIŒ4Øâ´ \ÔrUÑY9h ©ôq75lK´V|äÉuÊBÙ*1¥q‚€ýº‰ºf² ]¸Ÿª?½;äìš/{Æ•Jq‡Bñ„1 *ŠâlÆäØæ3råzLÛï*Å… i}…LWY§*ï¦ý¶+Ôt°EYj¬T·³ZF¦M­­ÅÌ5/•$%§›é}`;§g2н„uPýýýl$%ð,2u¡‚oڻ漦-dMo;7m8ÆÈc÷"õñâ²éI[}Û}o»·yï†9VÏZ=/žw䨑kúÖü üƒëò×}¨þ¡ÇNüØàÇ‚þàŠ¾+"/rÎ]=ÿj»’?ý⃶tøý‡[Í‘yÊzÊ‹ÅF£ë̲{ë#ZϰªBÂZ»ð'è´ Xf�¼°Úô·Xj‚§@ŸÎx)é¹ méÙm?€ò­>˺°WñC}Ö¶°êÉØÒÐëRÙ=ÕøÉîüÝrA»]Èè'uSZvh8là—“ä±+5lèXAH©˜À_öó°ðh CcBfÝ@öQ·r3T v‡œ]ó…fx†ò¡¤I:lQ[‚†>!a >c™©‚Å$>jÁ¤ø,© ò‚L(v§õ €²BÆTô-µÂ@û>$[šÚEg›9ëUà]íÖÙQ*j¢ TC9zT|:úêccc³gÏž4Ën·2za@uè~YÙ§}f¼×øt…BÁ@-«¥ì˜5±ga†J‰#Y©T²–Ñ|swpÇ·þÖ¿åÿííWl ·ø©\ë¸ኳgßÜsó½å{ïu÷žÓ8ç®à®|š¿§xsî¹cÏ­õ×Zqëg/üÙ«ï{µ!lv„ÙͬÕj¼»Jœáêˆ}´o…éu8‘Ÿb%3Å©3aÊ/WÇ?xqöøxwú”еêœ�P˜.ÍëYÏÊu´?/^\­VW¬XaE;ˆå1Ó/À‰´+ƒ>H)«>¡Ž¹°Øej^®¥¹"~Zó1…¦¹¬r.O¹øó¸Ã: ¦û”ÚV§é«*KB¹æ@ŽÄN÷߯ì9¤/e8q¬R2ª$‘ Ùß­%À¢aå)þ ¦„+]ô:ü¯% (?ç3Û–n»©iSËøìäR¦N®‘xÎ0WAš©í–Ìê$ã³°ª¸nE²3f;täBÍ9ìþ4‘‘j&†43cªF¢E¯Pï¡^˜y ¢(*‹Æ3$ü·ÛmkéXaƒhº@(·æ ó.†ê\yä•ï}ô½ö»κpÿöþ¯«½®V¨×:ïMoÚl;«uÖ¹;_ÕzÕÆÂÆbR|sýÍù4sts.ͽdô%ÿ²ð_Þðèsƒ===6j7ÄzV¢AüƒbõçF6µ:nÔ‡‰D*Ã­à¹ØÀl¦j´ó×z“ÔôN¬e2²˜º¨×©2«!{}†·¬$ ÃpáÂ…Ç{ìŠ+Ö¬YC“ƒ„ŠÌpð”F ô"cã–! Ìô[ÓÞ¤êÄk¤W¡²7‰µêy¨9„ÛYLK•ôÈ})ýQÞckïŠõ°;äìúó_‰{Û~S‘súL„©Ë¤²Â26œœÊdS~4qmÝ�šcf…æ?ëröLáÅúžÕ”AÑ'çVA‘ —TÑ ~€(’Ù¥:/ t“I{í×ÇÆÆ”m¡HˆŠˆXrGe”Y£är9û‡i¶™ÅŒ‰‰‰8Ž›Í¦6±ëõºM¨KE===ιf³i92 *óî^°eïû{¶÷|ßÈû^¿øì9go 7^[¼ö©à©ÁdðºüuƒÉàGú?rCõ†‹ î¦áçç|þ´m§}íà¯ÿäù×½úº÷<ø#V«U[oè4ÓÏ3$°V«Y›‡uÕjµÌ\ ,c„Sñåt2H±kKµ$;š­›h”0dñ´…Fé©k€ÒjH£) ù–½>3#±~ÌÊ•+/¿üòññqÃé*ÑÿYµ[€võ`Æ+!Û~žù¼á2x©!nʆл‡Õ›ÅH[<÷–ZØDÔî”Û&œ¸${Ä ðü‰½é´;¢¸ìžËÙõ!G !Šé¶W•ò!Š`s@^éd”/#£æ€™ P^Ùú=ö G†ÃMÌ ]̧ã‚A3TT‡€ƒÀ‰æy^¥Réíí­V«Ífº6ñ l&ïH9€Šˆ}LéUW¾ƒfm@Z¸Ø”(§ -qÈ–MÛ£´=Ì›Ú=± _*•¬„-—Ëö}ÛÉ…Bahh¨X,Zàét:o~Ë™‹Ï<¶zìÛn¼pàÂc“cOî=ùèÎуéàñíã/è¹à¶Âm Ò§GqôÁú»¥nýýý¹0×ßßo”î,ö`Ø:11a$:D‘ÍÁ®Ç:L&@Ó£ÚËÐì1Á¡@¤ÏÏ£äùjá«}°» zƒÛ…"o¼>pZ¿jȬV«Õj5ó¦6q#ÑŽ~{(ª‚­‹hjk˜ëÔL9 "+¹âZjÀ£Z5H~èÇÑ ¡3™¡&êÈÕäI+*6Žéõ©š�#rS úuKÚrvY‰£\fÅн0�J˨,+@ONL�5»·cŽö µK†U©´N:ð¶ó-U×ÁiU¿Ö:ƒ.Ⲫg —%›ˆ=ÛǤÀ× $0 ;ÈŠÅ¢qÁ3cžèté蜒‚xY• Íx`;q”Ð~Lª ¤nGòø“jöb€¹È< `@ �Џ‹Meöõõ™j� ì±«Ž½vþµï^óî NÝvê§æ|êÐΡo˜xÃû~Üñ:÷çî/¤…:'lò7=<urëäÉú)I=Ïóœ—Ëå ùÂàà U]õz½Ýn› ©ã°–fŸÈVŽ]³ÙÉXà;Õt'Ã"#Q ­‰PGíŸaCÃ3ñ z‘¸¨à“½‹¶íL×姨�S½Ä'Ö†c{ ê?"¢24œˆd?L¼eŠ~%+ÛºRs ¨_TÕÉÍP_"ðµZòÿ`'Ï”òJ #ˆàgûÅðgŽ…à”<¢!“ذ:éÿºÒÚŸBÈ!r(¹Å~Ü[©L9›¨‚±ÌR˜ÿgÌ U+IQ&•þ% …ˆ’Ïç{zz¢(ª×ëÚôÆË@Û6¼¦›’Z1eINö¿:~dÍFz¶£Ls°T*WÊþDÂD«(½« ØQ)"EcÑõxõ…è© S/�@C,ÉïhSYŸf``À¦:jµš²¡ì³Û¯Ôj5cX³ÇØišöôô¨¥¦¾F8ö}áðÂï.ùî µ:qçïˆÞ‚‡ÊýÃìØlöS£¿1õÒ÷÷¼ÿsÏÝ–»íÀäÀØÅ«ÃÕ_êýRêÒÏ×?ÉÀ%lº€ FíÔªÕª]@oo¯5çl}ŠZ­A¥R1>Ê@lM…ô9Fa1)zÌÝ#ôÒxSc'CÊv©Ú\¡¨ëA dÙD¶×€¨Él%ÛÒ‚?M`#!S¼Wc+9…œ¾©h/’hvôƒ ÓD´¥B`³ž²u´¢²Ï¥r½TiÄ&i(¶2à¼Ý@î§Ý%mâ’YR¨)b©Ø£àèø¹gÓßrþx_ÆÍ ²Øã·äQyeJíe—* :"N\f5 S2‚JV“2´¯Ä$ß÷PÉL‰3i-5•×X;ÚþNjo‡Œ,»ìÞÞ^¼&혆%ew§Ó1Ù1;2�¸oÜc‚) ¢Ç‰¬Ï¢~õÔR 9DJ¥r&Ö¹a Ç>2Cv4ÓðHc=°z½ÞÓÓc7Êf_ÝÔnœÅãññq+ëõúi?>í‚7\°lÛ²—Æ/­D•vÜ.vŠ×Œ]s@í€ë ×ýnèw¿.þºšT‡½á{ƒ{[֊£ƒ}ç»áYnÖÞþÞÍ\“Xk^2v …Z­f×fˆ£Ñ˜˜˜°³~ppж0 mh”óÔ>&‹Ê.•g‘i4*OÚBU)“§–PÇ[©AÞ‘LUÖ/gœe<º¼íᲪµž &PãvJg-Ž-M±5©Õ­~Km³AÚ4K³Åkü–5¬ ­Ê+hÍÄP¿G5aÓ_Ķ Šêˆ êŠCyµ‹ä™’Ô³iä€+’¸ì9»ò‹ÃWu3)¡Æ7%a E  ŽTæxØÌꮡT`e %Ω#ø/LÙÃd4™¾•ݨ“dÙ™b`7'c_ÆiEØ£6ÊèÍd¨z6!X@⬠»vÒqŽPúd0 €Gm¿ag‡^{R(¬˜k�]û¼v@3Öj�é¤a~lÚväkùso:wùþËošSàü•Õ_©T* ¯qPá «óW¯Ì¯<'Žsî¶üm®r…¼¸ýâáŠ/U¿Ô ;[Ði ³¶ÖŽ? 9vÊ(o‚ŠÜ^Á’YÕfÖÇíÍxg —L¹Å‹gÇà “Å Í ”Þ¦4Eº*3¨iÊ%Ñü .%|Kõâ4~”ÈP¶XngYk*'ë éV•hµñ¶EHiîDnN­@Œ¡!¨ÁŸ=À …%Âé°Ç…d`–{a«=9¶¤Îí9»x4'CY!ÆôÑÇ66*Qljf «*Ž[Õ£Ý&ëÉQÜΆ1zÈÚ‚Ó¡™rg:t©, Ee*YŽv1Žд”$Jñ¡#°×t(0Âa§mXœFé„«z˜’ í¥ì Và‘çØÛÛkÓû¤É´ël²Ò º ÙµÛmà +•ŠñƒArŒF ÖÚÓÓc˜Û–-[Ò4]úÔÒ#6Q.—óùüŽhGµZ Ãp^}ÞY[ÏÚгá‹Ïù¢‚žµý¬Ñ‚0 Ÿ×~Þât±ŸóÒ¶Î ‰¹!¨v¾Ûý©×ëLؽµv‹Aš—0õ¥ ujDž&KZ´¶iPš¨ãƒ®%ð(7CMMt˜TÓÒNê&¨êÚ6J“˨­3F­‡iFVC­•à¾ë>Uf#ñ�ê?5�Uê„–ïêV@óÒV áÓÞÚ“RüMAg¸¨yO­{!ì¨'·‰wÍÒv‡œ]öÅPˆõx´ذL5ƒS¨ššWc4GâUùƒ1²T6uà «eç zûÔé*ȦÎíŠ-dd¸7Qª’9zòM²4lìÅí¤YÑêP{}qˆRhÒðñI¨É é`Y7Ûn£5ÌŸ7ž¬ŒC4…f€Å íIpyö§È¤½µZÍ2GÃîM¡ÀîCOOQ ¬o)ˆÁ;HU«Õ±±±=ƒ=— .9¸qp¹§ÁÞݽ+~erX8èb~l´·(Š˜ñ²' Îi”îJ¥BX­×ëår™G ­¦ùªAÀÝVR¢’qñ-µ:'Nk4Ë~gR¥0ÇfîZØbÎŒRiû!ãæIZÆŒ‹æûà·„«Ì¼AÆ-Py(jãK Ö&ÎÁ É«u ÅLö¶‚¼©}Xl�•ꉲ‰Z'ºDjñ Š‚ÚU¢6Õx:´ßv‡œ]F@ÂK§5i‰++TÕ” è±,•• g†¬Ê�ÍklÔëu>ÈÁÚ©š5˜yž­Ý*1Ò^CÔË–ÿRkraý]õÁ3M± ?;ñ-=gÖ>#XŠªæ doªH7QÍnµZÆÕjµ¾¾>zÑá¼I‰F•æD¯Å^¤V«•Ëe“À©Õj•JņO¡ÒÚOšPg&ìvÓ¬rÚ·±o1)FQTê®â&&&ìqOp2Hhç—QÔŒÎ`˜B=Õjg9ÓS°©Ò{eSIðä‹LèÅÓ–ºŠ~Ú³3#m7åZDÔ±âÆV)á”×*d�'«é6å;ë“&çyæ¦C %›å¥¦ ÷iôÊ(Üè˜=«*f:p«)'³ÌFW³„Ò‚(+ ¼Dƒ:ŽsÈ>J{# Ó£m¶°©.¨¬ålÙ!uűjЩpÜî³+«œŒ ¹òG©Z�|숱Òªñqê\%•ZJ ’£®M*©Ñ³›"ƒ  2p[%Ðá×ÊjƒëT<GÊsŽQûà4�”ô n�jŸéQ;ñͯ#fèH)ɸõ(>2¬uÖ¢åK”ÊHÐCþQþ®ý°4dÁt˜ì&[Œ‡ØF·©ÓéXWß>µ½š•#Öû±7µIL›þÑn3cðv¤Ú)Öú2™QˆFŒ¡Úb¤mB……ÓÚbÖ˜©aÜL‹vZš¾ —i—W*•fÏž½eËb-¿¨Í!"E0~æÂÖF·²¹xjX‰£EäDbCH0z�� �IDATYsìßb±h'ïLs¦LäÈzP³v;›ô(Ñ@ A `«Œœvkˆj,ZUyàç!¨ã0x)N¬‚øÃ[«€JÔg²ÏÝ!gW~©S¬J^*…LŸöf˜i`k!ËÁ … -îÆ¹h¿È¥Î¿ÒwwO£d¼ahÿ¸½ã”é ItI­<¬y Á‰â™nBNXÁ3ír7.O=Nœèn9ñ_ÑA%6‡§€îº/ê´H\áªèçƒc°!MwY}‰ XæÀQëDãÉaS%¬ZjI—Ân–“®ZuÏá÷A0»3ûäO6Vz¥Rñã\†Õ‘Ý„Üe'¾‰ñ˜ ŽçyõzÝê°f³i‡£G“|¾µ˜£1ƪÆQr—‚¥õz}óæÍyáf•ÛyªŸ~$$l•\RÊ .|¬%mŽRøò}xT†ýl ¡eÄ©3¡JÅ0LFõŒTnFBµ±U7Ö(ÚÚ´d’OY<Z„Q’ü)Þ®IñÞÉ 8Ñ×nö»*<“³°Ût×kº¦g&*‘ƒb(ºâN–¯Ñ%­³EE‘ó]tbÔøP£ð™Bùú²çy“õO×ËYv §N –C™æ‡A: ©KÙɸ²J—«¸€ZxÙú¶wQ^rgÁ"Êå2õ0½Þ¢™f'NDÞ83c¡œJåì}kµš¢„R‹–t’áÎöööZ¼·^‹MibŽ:*g7nr¦·ÆS@žÒfþs¹œ £ÙãhµZõ´þÝ7~wß±}øø4Mëýõ ^{Ákž|ÍKž~‰ÂJV÷¨¨}§ÙlZ»ØX„ðžžSâ*¡id­\.711Á°Ú¦:Hh¨ % v>"¬ûCy\äÔ3‡]H54 ²ÇÊk¼¡Ab™¸ý sQj| ¾¢N§ù/'Vc8 ª³'T`’Ñ×a…ðëJÊH+©? ½O¡ÃàíÔËJ'iT‘V£…Rx”‚¨2q)¡&iÅCášnÌ ùTÍdwÈÙÅô(� W”ù:œ—¡öhœ§vT™;éüN½ÏIãׯ}G÷MîÉ$î¹°ÇÿŒ?vÛØÀ«ìP�v³ÜG%�lQ@aÀ2‹<h•2Sª†Ø;spè›qÎ6›M ”êÆa¤êd|33¢Ð‡jؾÝc=Úí¶ lê)zhöR===&¾©À ™2GªÝ: WŠlXÛ¨"v†Z]¨n•Œ¤Œ[ŸÉ. ^¯4jü¡óùüå§\~òwOž›mEÉc{|nìsßyÁw6Æçµçá-ÖÓÓ=Äâ¥j€Æ|"ø"ræY`’þ&'j厵sì]ìÑë\ŽÊ@XƒÇ¦y¨oŒ.¨$4M¼x̼-~+Z•ÑÞÎÌ2ökáÄ´p«�苃èÚÝVg3&ɘÍ|~’<4UòZx³ç‹§”Žs¢ë¦\Ti›LQ­~•¨ ´@bO I!'JÊG°eïhUçü@¶3úÊÄá´v¨ƒØº¿˜`Ë8ÓÚrvq¡CbÕ‚¦9»ö92-PN.zÐÁˆn·›“„?U!mÒÊ쎰ýòvp{À¡oXZò ~£ c}#E絚vâB¨c̤·Êiæ|a•۶ב@‚“v¿@«Aáºý`š°yþ±±1B¦6Õ´ia¦dÖåV·feÍÒb5õËþr¹\¥R±QÊíÛ·Íš5Ëz'¦%ÃÁdwÛº2VÓØ»š"¯Ùlöööimí¾km[Õ£z®nUˆeš‡úÄOµí¨´5Ù·DÄ5rP«ödµ@g°§V,¼°ðomžR©Dm~ #§ù›³‰OªUåiͯ¨ 3¬Z¨Æ6ªÅέ¦jÖHcΔÙgÔ4Ð ÈxjÕ’$ÉÉÝîAIÒïû¿œ1²´##e†% 0)ÊrN\Ì3…{F”Hƒ¢»0þ™c"%ÃO:›AQ¥b”8@ÏR(•…κ£+¯¾ Õ»CήŒ7Úê4ˆI€Z¹³”ȨMT# –hK¦sb§ÿ˜þÔO}ß?à€‚ X½zu­V o Û§¶+wThØ‹+Fár=Ç1Õ%îDõ6MðcŠ�¨ £3* i·`ì:!dgÈi¼]æwJ§›j‡»ÅWçÈ€Ö¢·!jm ðì8³f:²˜[·nݾ}»Ù¥Mç$8\ ö1íçÜøø¸½l³Ù´ó¦‹=ßB¡°jÿU­>¨7×kKÈn]£Ñ8lÝa?\ü÷m}›KÑ ”™f¾8ØÏXüSpøEŠ÷Z­V©T츱³Ï̼Õ^“¼Ä>»Êö@lƒ1Ú£¦–TÒКùE5{6DB—ŽS•ÌÌÊ)X�öhtDZê�•iFƒ“‡õövۋ㯋§u:ÝNçWS£Kª÷׎_g¼F§ÖàL«QâÕötÔ-—×Qš<Èù«2ÇìæX¥«ãk0)”§“™rg³¨{†^ëDûQ!ÁÝ!g—…ôÇåP™#í”àüa™Ç“‰¶›ò°¡N¹t2«š5kÖÉ'ŸÜét®¾úêuëÖÅ.¦³MæETqh{G[öƒ+P‡Égµ3©T"bŽnèx©¶|ÉÁ)zÈË:wâ1ŒbíÍmaÁê»cì- Øa:11aó+8@]7ãÔ³ò1ŽãuëÖíØ±cÖ¬YsæÌQq-è×€ŸÖ<3hÂ} ‡xÒËÙþéû~§Ý1€¥X,Λ7olllûöívµq7Í´•šÔ›%-L©Úäò(§´Ær¤ ÀIÚš[Æ‚³_¡t ·£wÏn²}´ ª u-ùµm í»ØÂ°»¡„xeÀ@ѵd‡á°LdV^¥JêˆLš¦ù 8±Ó Óôêb±åÜ×}ÿÜn·•Ï?*3­Ìb …ÞÞ^!Ió‘L…}QGTŸ4·³?¡-3»*ž”’¤Ñ‡WF6 ¶ªöøx0 ©‡HP‚ œ:4ª4"r|nJJ˜ih·[cíCÔцgÆEœ*Ýž*„­ƒ@¯£òJ¾ïû+ýöþíüê|EwÞyg»ÝuÎ%&¹59XdvŠÙk’Ý l¸„jΓ’2_éĤÇzé$ª”;,SóÝÉX0@ØË y„à Ø(Y¸oj8D¤ç|É0#Àg¨í´Ñ¥ÌWôê1ˆãù ôõõõööúoµ'»ÛÙ5K†l£š¡ÀÐÐ¥QÕj5š@C£C;úvì›îtƒ‘‘«JsÏŸê¶»i7µzËM‰6V*ÃîLÊÚ¢L3‹+‘‡±i§Ó3zW4“m½1šCiâÄ 4RA6ê¶Œí˜ÛÙ‰C}*©˜úÔ]£Ó`ÊÐD‡„/ÃrÔ҇͘Ë厫×ç8÷µb±T*•’¤Ñlþ£ï¹ÓI¢è©1˜½öÚkÙ²e>úèÓO?yæš¹¨R ;£Ð¡Ì4UÇP?ÊV{;*V¦’w4óãTUAµw#KPTM'ÄiîfxC»CÎ.ûRæçŠó:ÞΚ©"z†ó¦Óøj—†añ+ÅÖ9-÷>722r÷Ýw`:gvúŽéKÜ´6”Ð@5è¢G+þœ+j|X¤œ/^XôjúkŸ"ݺ=HÌ¡¥¥¬ƒ>ÜI ´;¯Ò¼¯róT GÌÕ¬º2˜AO ö›§>žpä³Yޱ5Émò΂¤¼l½^{Å;®Ø÷þ}{âžjµjV:QݱäŽÃ:|{m{¹\®T*œ,X¸RBÑO²HL{9û¾Ý:ý „hŽ —|Âx„m%4Bo±WS§d  ²Wæ1㮊©*ææ¦¬Þ2b9NŒAu¨K$ÎM5åÅÙ+,uîþ)mŽûG<oY=8Å@³œÀ÷ýñññµk×ŽŽŽr+t²tЍŒšº¨éQ�ƒÎ"½Šk驨ÉJ. Ð!Càf²‚'¨f]ïj^ÇñåB¹;äü±kNdÐTô¦,+[9JÐRW+ ­Á˜< 6ú᪰qe#üxèÖ¹4M»ïêF¯Œ Ÿ˜¶ãÅOÌ.’æÊ$1쬨óÂŽçy¹›sÁµÁ4d7•0Ò7ÒÖ{’X†o­sp,Sp3ùäP†2ŽÒ‰Ö‚Ê+Õ”L혔$ ªç‡𰡬,À¤Ç °|>o‘Æ^Ê ©™.†W0îžQ 0d샞™ñµŒ lÑ(Š¢çßôü›½yþ†ùGÞ{d.—-ÞðÒöÞ{Öð¬­ã[ëÜh4 Æîh$›JÓÔ&xì.)Ž62g“…v öÑÀRÔ@î¾Ò@xŽŠs*iXu´sc¡Ë„÷yè. VÑ–ÓJ‘wä$U!¾L£”ýµR[ßêti©tj«Õ©×ïœBêNïv»Î]^*ùSd‘‘‘jµÊÌ´Ç´´¥ˆÑ<S­^uèp"7¥vÀ¶xLÌ›pTg2jh§f Ä {M72�F£çpb!±;äìúiP|ÌŒ­á(£œ®™%° +iÏ\•:!ä$IâF]î²\ð£ ýñv}ÿºs.¸<(~¼<øÁ´Ä‹[ô6\íy^ûÅíîg»¹¯æ ÿXðýºvëÎVåÌŠ¿rZÛ\‡Ÿ9îŸÃÍÀ&Ï:´DdŸ˜Pû[ˆñ‡ÒîÖGuhtsjlVV’ý–ÔvOŒbÀ¼†+û>cÞ~¬pá”MD aâÐôW즣̃á$V�¹)ñ!´ …Âì³—íX¶yñæËÞ{™çy~qBo·×oûµnmdd$‚9sæáÂÄ¼Íø²Ýn›`ÝIPa=¥ºÙ±kÙŽMpÊyjp¨à(ãjç©}ä|>O9•9•¶@I#Ú8qf‚Ž¡¯ u^ó˜gÍÿÀŽ2-z}döPFÒôÛ¹Ü9ív3Ž[,þU·ÛMÓïJñ¡Ì Ö§NX+ÙRé‚5qP)Š3î‰òд4‡e ³}:FJY;ÇJïÌ|~XY©*Þs]³·?xó'rTµLÅWTôÉ’YhÍ*iâaDÆ69G¤›’ŸaÆÛÕœ_óK§—×öƒNN“xý¥$:?êyE$ÿµ|ÆòËËF#æµ Sz·2­UšÓ2(³Z 8Ñ&0*a^Á0)Wö'Âö¦ˆ¯-2Ä5Ñퟜª:2ÂgdÂ^bbÂŽ “öEÔÌ8`òyõƒØe›º³Qzx´IcÚoõŒôxÿK\šËå‚þ`xÉð°ç…{<¶G£ÖX¿~ýÈÈÈ{ì1{öl»’;v0ßƒŽœaw¸™™´‚7v߬YE†¤B¦ube¦ ‡é ÁÓÉM™=J‰ÈÖýbl…® Ç7¶uü¢è¬]šžS“®ñà2ZM< {ÖÝn·Q(|¦Rù|£±¸ÝîI’¯ü+´1�ÐÓ†“f9DV`I%jfX- ]ª¬¡âñÊ´V´M4íÊX ¿ÝŒIj»oP‡ˆ(Ј¬œRPànuUØrve°à£<Bãq2<h»ËFÉHuôW‡ãÈPØWh¡ó»†˜©‘ŸB%¶÷¬“œËåFß:Z¼¾¨5þä!þƒ|ôæ(w}çe$+JFÔT?lÀ…•â óY£H5µ´vÑ™æŸIR;ýi¶«ÆZf`ÛR{Õ¿±àË6!BGVïÔ =ÄNvK~5ø™B3à;sŒèÚz �µ&¿M\öÄO4÷lƹ8çÜʯìù]Ï^íEQ__Ÿi Äq\­V•  MÙ½ôŸM:ÁNpSð„6iç»Å*xÚ ïREpTŸaI1´ÅÄ»Šƒ©N¹z´ ÿ¬&Fng‰L·³¼¡J©å8*é ó‘bñ=Ýî7‹E/MµOõCa=¥ ¨ø…ò9Uˆ–¥« 1Öî—Š¨·º ¦i›Í~’´’ÎkÆ;N-t~<MM/H ÞÐéˆÝ!gÓÈÜYCŒˆã­¢C”;)àv5*�N\Í¡“rÄ«ë¤#Ô‘‰XÑiQßÑ}±‹s¹ÜÐÐP­V³Ã«pM¡ö­Zþ†¼z�èQ³Ó‡+W+OœÕ“΂†¥Ì¸�på‘‘©_@¦”„áÆ¤ß«ãGºñxwÛù­V‹„]µˆløƒ4"µ]ƒy}êÝÖámë¸0²g®'ˆ¸ö_PÎP=) ë^±. ÓU¬=ÀúËX>º÷èÆhãþOîoV:Ê¿`]jËaù>F>¦Ä£ø$s6Gp Šê ÏQWJöSI f3$(¨HY«ºïÓ*ñ‚4§ÚºÃ¹ÊœÈngyM*ËI磿µ³¶˜-�By^_k>„Á*X¥h¹ÒÜÒ£&¤›jß Suµ·L…@®šjÞᦴ¨µ“Šo/à62¸¤ä^8w‡œ]\åX5ŠÀ8Ç"šÑØyÄÏëÌe»›šÌ'¤Qš0kÉdÐ¥rqšO®øx›5kÖž{î¹zõêI�:M ¢!¢6<ºÉM¹«ÙlR×ë`ž2ÊºÖøšÑŸæà@õR±;XŠeã) ú ðX4‚.L“©P(ØwÈUwRš/M²{“ðé`0šÝ´F£a} žžË9êõºEwƒL¹Z⥅±(Œ6 nZøÈÂÒ¥í…íår¹X,îóÐ>eæ>ÍÒæR§ÓÙ¶m›aeœ\LcWMgúìÅMM«[HÕÈ’T4+RíðC6S¥“’©}^'Ö‚öO¤'Q‡ CF¥Rªì}9UT)£ÚÉé¬:ÿýªdaoÍà 7“@¥©ca,Bê`ÜT3fƒ†"jnûÑ:Æ3Ô¼ v€N@q2ÿoÑ(”úA!`­Š41¥Á©ÔfËtP/C’Ê4v‡œ]ÀX›®!dÐÍ0Ù„€«0·¦r*®lù ÕiÔR‹CN´+lw™?J¦keÇÁAë°Vþáüøø¸ÙºLî¨çÇÞovjóªä¾M¥¡~¡ºÈª.…N",�¬�ÕÐS¦.p± yÏóªÕ*i£žþê; þÖHD«¦=L…Îí ³zb¦E<<Q 3Fm"R]D#8ñÆˆãØ”xìÕ¨ä8æ ´¾õ¨­=õž¡UCqw»]³±)—ËÿöàÛO¼}ÃÜ 6/°óÂØº…B¡\.s› ^3@Ï0= ~{.¦:j¼uÓDžRÓ  ×93=Ã/Z…Íx:Í豞ßQ"€‚´ÔÜJ§v;[]?ÀÀ`íé§Sè™6ó˜U bSÁÕU¯EU£ ž b¡ƒÅÙ××W.—ý¡|‚ [Õ¬ S(J¥0õ"1¥OÃŒ‹yõŒ0dU´2øtwÈù_r Üdh² 4a•¡«œP„Bp¦èÖè•¡¯X¿1OCiQÐâM Ê•>YšøÞDþ¸¼ Ãs¼6Ïo^Rèú]ÆttΉ†ãdg:̬BôÏÊ™aÇÚñª>Ù3•t-ü˜ÆåØØ˜ÑÌìðRP^IÒÔR y‹k«@©ØÞð}_ÈÜí]ŒŽŒè!2 X* ¤ôhÕ\tm¯Õj;M¶NM}öõõYlãç :Ý…W¦MÛŒƒéÙíµêÇ(Ôvëõz½^7éû_‚‡õù3Ëܺ™)%%˜1ˆ£úIåof ¡E s¦"™ö!4×f×(iÌî Ú4r3ô.íóR*ûN×6aÆM‰9éþR¨–ê\Å–Ôÿ"Š¢jµ »Õ‰T=/e¥[…¤ƒeC¨°xC¨Pú+øÒÔ%K=J,åBõ\¥Á!S0Ù³;äìâ/ƒJ2Ú6PVÔvÐV€Ú3$ϲ݈>¼Ò½@ÃðgT̆­ËËÞÔE®ôƒRýšzá+…ü}ù Z¯oµßÚ.}¥äÓ*™J3å}9ˆY‚$Ë8tûÑ^Rka"JÆŠC¤ ­8°-§2Š<P–©œç‹VlšG+”o)ª¦†~XLBÁ,sª²™áTI÷982_ÌÖX|îíNê[×j5žãÈÈH§ÓI“iAIæ@±`°c?nJ¦Åî’Ú4 ¬,u°üSK»ª™³É*¦ÚðSÝbb50Ì ¯àIó3œ«Ìïª|0röŒ˜a†Ê¬4E[*t¡XÜÕáSUÄPžÿK<V¶€Ù2 £ÑkÕábòKÆT®  H#Vig ÌL:¹¦Š=ªø©ŽaAÇÛw‡œßçkÇ÷þ÷»K/ux/‡„¦3ø€Z²ëP•æðAuJY"’Ą̀p/™ªºlº9/ç×ÏÝšk¾¯ÙüLÓy.¼),žS w„‰ŸàLŒ–°&‰ªÊ®aÀ ŸÌÜØü¼í¥�(‚.}æ¾Ù—¥oZêh7縎°-ØYÏ„MF(e¦Ô4So¶ñ¬áOö­2ûykÞÒ{×i>„‡­ŒàÙKYÉ*ïhûžÛz6ýí¦íl\5hЙçy}}}kŽXS\_,¯*ODXX®cÇÅ„–g¼¦Ý)c1(Â.ÆQÚ{§àS “œÃÞ×^V�=9»H+ í'5ûQA Ú-Aµt�P…ãŸõ£e=Eí~gÜÐ3Ò ìu Êø*tÁØ�ï«Jq™äO‹?`Xš¦óOƒŠ`€ub�v}L5mÕ™ªaæF'=µ; ‘›Ôê¦& »CÎÿ¿¯'žp_ì.¼ÐýÓ?¹|À-Zôk¨tû¨‰ X€Q2•˼‹ŽÑᢆ:йºXn­æIf]×Ë·ó¥ JÊêQo$¤8ß3Ô8'FÅÔäF·»—ÈÁ˜'º;Êp£Õ,Pû l$ *X¤i8&YCå«ÑFTe_tt WÑ~zZ;Òï±QeFû8FI¥¸ìX0(3zž$Aù™òؾci1xxÀnÂÚ¥kÛ=í¡-CI+IÜN½ivåXøX+„R©d9FÃò,ôékËG=7I‡X­¨ÇºÐâÜêÄõY¹�dKÚª„O¡ó§Dú àÃH�!´ŠMåyXr¶Â-Œi5£þ#úaíèWKÓLÿÆjJã;èÖ½l G¦òFÇôaÉÆì2R :T€ “V]zìd¦z57Õ×Ïh?rZ±a™£r$»k¿Ï×òåîúëݹ纅 Ýé§»«®r§æöÛï,t˜1WÑ€djŒê3È()0Œ"üÖ•Fˆâ¼`tÎë$iâR|+Èä£6" ÒÈDG]Ùn,2u'ÔúIé­ZlÁxardïâ`³¥Ux^ÝSEM± i D蹯`—v’2·=›à¡8€¯"Áˆ›Á8 ÐC¢AéŒóã9[_·uýÂõ[—l,|ý ïw}³›Õò¦aFndÄ´ÃÎJ :v�Ù@q >èVîµ5À©Hh稼žæIJ5V@U“•7<ÓƒípÕ/ЃUÑÞEG2Ö/ÔJq¤Ýb‡¸cÊ)%Ú9Ñã€~’12çncu*€µ©.iíÓØKÙ'SýF ÄW5j !¼1ó 4¢­Nk(CG6¥¸w‡œÿîkëV÷Íoº³Ïv :çÜsŸë‚À}ö³îË_vÅâÿ¸ÊÑ©4:ÈLeX<xÊ™q¡OvÛ•¿ØêQmJç\óÝÍÎ1ÊUÓn\ØèîèÎ+舃…:Ȳ„ZÚy¶£V:yà@(¡U?âü:O�43ö¡¬îÌD·bq°lU„˜Qs«ô}¿^¯A=æyž·ÙëÿH¿= êeq7Ò±K2#N !¿ñQ¥¢2lÍR çÜ õX‚ ÁΟõ“Yq)nÙ²Îl~àÝb_2:4<G”¸(’$©×ëæ6Í«}Ó±ŽŽu³ì#«èªž,xN;™×N�Ý2hˆyê§²J0ÉØˆjtA8(µb�TTú¯Î—ð¾Pˆ=ª0Ƽ ŸóÝ €ÛðÅí›æåã¦ä'”“\�Eç´;«wƒÕ¢s?T{ZrÁiI§YifàOé‚ngý{ÇYšéƒÛrþ»¯³ÏvŸûÜNHÚÒ¥îïÿÞýÍ߸ÿ÷ÿq‰Ÿìƒ­H´ÀO‰å²S*©ô¨R§¶-D£ýär¹è-QêÒÒJ=žþþþ‰‰ w¯ëÒí|²SüT1Žã`AÐ8ºÑ}g×¥ÎÂ/~¦ædœPCÌŒ6¥î|:mTرK«Ñ\²*ÓÆ‡±ªóÞìg5´Wì… ­Sî*˜o¹¹Z–©:j.— ç†cßóó‹g“4ñçû#·ŽT®«”¯)§­él\gCŸ¸�Dh˜�ÅïË.LApF 9 Ë!g´œ:‰ŽÚ-öYlºk²m½wõ—d|Ïñ06Ãf¥VÁïê2© {vm¦7aI†Ý±z½ž¦éÄÄtôê ÔaDzò=w8û´D; kýì¥ÜÉØ€RóÙq¼ªètÆfÉTT&Ê…Îíí’S’î±Ý¶k÷ůƒÑÀµ¬<òB=p)\@º4®PÍh¸%N@¡T‘“üÁˆÈªð16†OÚŠ™é:¶�ÿEÏ’øj @Gq3e†^4kµ ‡ïgkɉ¦p.—3#ò¥r�� �IDAT´8Qð?Ëó›ß¸ƒvåòïñ+_þ²»è"÷¾÷¹Å‹'¿óøãî’KÜ·¿ý‡ôr˜G!±`›™c‘`ƒp›œ$‘Á 8ZLmóiT¡'nÍjåžÈ•ª¥C8tñâÅO?ýô£>:üôpxtX^RÝc´uF+wk®ôÒRš¦ñ’¸þ¹zþÞ¼÷mÏëxêAöÅô‰ïgÚ0ʂͩµ>ÓÊ”Ÿ¡ðý5lƒáX7›QFÔ>NÇô4ÿM’d||Ü÷ýÚ µÊ;*þ˜Ÿ¦iè‡ñp<ôÚ¡‰ONäŽÈåWÍ+UiS’’âT˜!ò¡Í ჲV«áK¶©ŽÈ™ È ÉH@ùöAítaºí5Û\àÂ0ÜóÁ=Ë›Êýõ—ËekÏà VC–  $m1¹9ãךl¶zŠ Î,åI¤TÑΉ擶Ùl&Is‹”ƪÈL°³ƒ”¯ôz`àÏ"0×µßÔ.~¯X|e±Ó鸗ºÖZ¹;rÅïsiNC²©)YËÍP$Sx\—à¤LŒ-Ð�ÕNŠ8¨ ÁýôPí½(­ò™WA*rãX*¬¢l=l² Õ" „j«%§Œ<ÄŸ«¬ç¯~å~ñ wÛmîcû=~kÏ=Ýg¸«¯v§žê-r=æ~øCwÞyÿcTv‡£òq²¥cŒ|Ú)f+É’ÐÌùËH¶%”;�O!Ý/uºÁ+>üàÓO?}ñâÅ6l¸æškî¸ãŽúæúøgÇ»Ïíæ>+^]Œ¼(MSÿ ¿xJ±{e·´oÉ[3ÝQäd0Q½5Áe>FA6-P˜mT~†Ü\H 蜬ñšˆ!* IÉlÓ@Ð+¢üoò®9­û0évõó°õ’VáÁ‚×õ4XÍ�¹¶a™Õw;ûki?I‡´SEW‰'Èo)«›þPf²¶müeã ýì¡Q+* ëY_Ý¿Ú.¶çÝ7ϸé ï¶œÒ45ùj;©,ü‰Û¡c½»0ˆÂSp¨\”t­·ü’Ÿº4UÞÆ×Ÿ°Ååcjv¥¡%3¢nVÙ»)Õ%­®4c ­Ÿ]/¼¤àù^Êårt_”[¾ö“ZîÚ\ÚN©Ø,à±z‰4P¹QÚõ¤F§ù¤yµ»®R•QWCnmÚ4…›nIªŽý[!HÝžÔYJuqô­3dÝ}*ŠªÙ§~@Lf‘æú¿r~–÷#¸[ougœá?Üþï÷»K—ºSNq]äžzÊ]~¹{ç;ݾûþÜ÷W®sc§qC£}aÛö=@xMªñÇJ²D8ãu¨àÚ–ÇíC¹ v@çóùþþþC=tÙ²e .<äC^ô’U¯­6ßÕ¬]ŸséœÀµëjåcËsæÌ±1û¿ÚjëÀ9{à”Ü6;|îܹ½½½j[¢©ù|ÉgÎqôO3 ^ôZLĉ=¢BcJÅ=¦ /‹sæÂnX,,X°dÉ»àܹ֑­4—ª3÷ÌÞ¬ŽÑÑѱ´=£ §ŽÇm€S DZ�ìeµdTG�{#»ýnÔõ^ÜÛ®·­"ºihÖ=³6±ÙlršÍfcêË ]ÆÇÇ'&&ÆÇÇùKµZ1OûIÖÂzllŒiSúÌæ»\.— r´öXüθ~}=|" ïÃ{ÃÖ‡[­/·J¥ROOliÜÔäIÙ ö'³´ˆüÏ”!`_Ø”ê©ÜèÆùâ§‹vå .\´hQ¹\N’Ä;×k|²Aîo]+”î "ä@%Ï´ZÑ¡ Áˆ¬‚A.­hîjƉ” 4²¢Ë)‘‘¿£•…± Ñš«¬BeU@°§oG U#"­–‹Øehõ6Ó(èÏ Êyê)wÉ%îâ‹]¥âöÜÓ9ç>÷9÷ÁþÛA¹/|Áy¦ûÆ7\oïréëܺwòîôà´òÞŠçyÉÁIõ¶jâMŨi_ë6U ±a5ÆPx—Ù:•‡aQò´‘vkÝmÍm<ðÀŠ+/^¼qãÆKO¸tîÉs;ÝÙ¾pûÒ‘¥›~±©MÿÖs¶¾åè·ÜzÉ­k×®õëGÏ™6ÊÌCáäÈkVQðP§,U³–ÉVËsU8]'!4]Õn­ ò8ªòn|-õ­õ|/‹Ë–-[ºté•W^i­¯zP7M¹éŒÁ9r[PUØJ•7 «:uO·ƒñO»V‹8ÑáÓΠp 9çZû´jËjó>3Ïó½Ù³gïµ×^›6mÚ¼ys¸2,ü¶ðôËŸÞëç{)" ?êSHFG±—¶™'šRöÙi omeŸå(ÛŽÚæöp=gö$Û“À ºÝná¾BxpØúbkÏOí911a/HÀ‰‰(ª~:….aÊé qf•qjëT™b“çyÝú…K …raéÒ¥§žzj©Tºì²Ë~øa¹_{AUÊjÔÑ'²Ð¶l‰ê¨Ó.1f›ÞUïÁF£aüÅ µúÉÀã�ÔHã±=Ü8ŽMÙˆTF9šÍddUD�wÕœæ1±q2úp8ÿ44=ÏsÿýîÊ+§[/žç^ûZW¯»o}˽ç=¿GÔéïw×\ó‡_úIž¸ê¸¯gyA~$ß{to훵øáØ=5=„¥êÎ335;†Ô!”öo†ƒ _0kÕaúp:qÜÄß{âÒK/]²dÉê¾ÕÛG·ïsÈ>óß0¿5Ü:锓Mõ<o|p<·OnÞ óÖ®]ëyžó&³Q› Tƒ† hV{¨$I†‡‡mçXŸÜ‚jÊ’Y-ÔF+hÚÎ:ËFe¸SÃM‰‹[„(¬.´÷m›>Û=÷ܳbÅŠjµZ*•rGäò«óQ;rÉäg7ý+J bj¡PÀ‡‘é}B†«™Ã¤èèh7hLÆ~D½”:Nê¥i˜&õ¤R©qÄGyä­·ÞºqãÆöx;nÇ‘?Y'ÁC³‚’¨ Q…ƒ.¯™¿Ó ,ôêÍÕò[ñ‚8|2 FƒE‹ nÚ´iëÖ­Þ6¯[ëÖæÖâ±X*tLÆgŸÍ0!zMtTÂ7ßÑ¡z£N�©SŸs.N&gxñ®FŠ=.xD †VȱP‡lkeò:Bß<z³àÓ§O§“yÆŒl¢Sá¨ÍêÛ†µ]ª†ÜÀqŒ”ªžPfJ–?Ä}õ$e;w»ÝR©”1ÿS9›7»¹s³ßrË—»?:Âx½»þMîMÆ1…Qæœó¯ó[ÕÊ>¯3_¬32¾ ¢…I0ˆu - UQ—âo‹c;#Yùõ•ããã«Ï]ÝivzNé9uàT/ïÝ;xïñÇ?øàƒKî]òÙ7~vÖ¦YišvNì”o,kYM0ÈL®(n†‰A ¨ XÐRc>²› ãŠøSìS4°îir¨È®žÚš›´¼ü¡×¾¶íßäG#‘6¶³-ÿÃ|ÒH�3iÒèp ð[‘¸™G D…>`Ž01J°aeÚpoê(™¹Mchf<òHµZ}òÉ'‘UMÝä• -ÁýÉH5 Œˆ:öˆ€`צ¤�~רխVËÍsÉQIùŒò^ó÷zÛÛÞ¶ß~ûýêW¿úá8þÌx÷7Ý‘ô¬èé"îêä¬7j)͹¬x2ÎLU®8mcñ\÷í]ÿ+þòå˯¼òÊ8ŽW­ZEQ÷´n᪂]ØNT£ØqN$;qVe⛈vÅ€ á§)5Ya ˜#<n@ ¦…,JÙF cC0‰»”Ñ¾Ò h="2%5`Ôñ Œs¨ò­5ñu_¿O/ç„Ü_ü…;÷Üéï<ø »ã÷·ëúúþÈ×}³»ùXw¬íÕb±888h¤pK!~Ãä¡l òkZ1ØydËK…Ë8ªl|'ÍšSÁ`Û�áò0¼>,ügaÃåùçG†_0¼ßð~''¾¢óŠ¿Lþò¶ümsçΘ˜øñ<6:¶mÛ¶\.——V´<[`+û‚v¥œNl3L·oçc•¼2ÀŽ}.ŽfJT¥ˆiÒ¨&®ú¨ž4»7Óêv»ùOæë_©·>ܲ„º3§3|õp²=ɯÌÛÁ N•ÌË€L_Qû,ú°ì¼6 C…>uVÆ~Ѹà:¢®¯R…­…ÂòÂÄ«&¢(zâ‰'î¼óÎgžy¦Óé´æ·Z [å_”5r#ÇiŠ«vIœ,F°ïÛƒ3±5³ŸP‘òUÿ‚R©´páÂùóç÷ôô¨i±½ð—­(ëê–¡&Öû@vÆÈR´>b›>qÛùæ»oêFQ422òè£>òÈ#£££Î¹î[ºùëò<#íÒiŸ™NhTèÀò[”dÖàáòt/PËfBvŸÁe†`Š¡]ÆŒ¯š‚fäaöúìÍ™~¾™6ª­^\±>Ôÿì9šýùŸå\Î+_éœs^èÎ9Ç­[ç.¾Øx »ãwÒI.Ü5 ¡…BáÈ#,‹wÞy§í½Ô¥D2\ËY�RÕè&4è-||Ã^m¹mQÛwÓJY+=·Ò)AÐùPgÇ;ž^ùôšSÖ,X°àõo¼fð5ÑÞQð‹ íÚÉK“ÎyÜrñ“q»Ó¶n{ÒÖ†Fÿ… /@[”“§C%u³]êÒ0 Ýz§ì™AÑ4M[i+Ø?hÖê¾´ëœ oÃï„ÞÏuwB«xq' QäeNô£ úLnÝåï ϽÜUo«¦iêoñûßÓïµ¼¸ë)iµjÖ±¥u~ÛÒ:#B¤ÜWšŸídL©¡`Tpî ¦m¬#âû~\à a²(q‹\㩆½ikVËß×÷»~i{©·2G¹Ííší,jó…BÁœx,Þ+J 1šÒGñ(£Yóâ~ÃïVº[¶l¹âŠ+ûÛßÖjµ$HâBLz% ³gj:Dô>çRÏ«O v£J¥ºÅ`_í=ÛC;s;.u^Ýëý»ÞdGŽ…ª¯6E>d›¥ÿ¬þñ»ÇƒïîEQ|TÜ>«ûX®[íúžÏV5‘q`û²ë‡f©~N¶ûÐ ¤ ûTc³j²™(VtÈŸ†?2šè¨Æ(—]£Ü4o0B¸êÒ t°NáPí㨥ìà²E«­è?³ãyîè£]­æ¾ñ ÷ä“nÙ27gŽÛ¸Ñ]½;ùä?æu¿Ð½ð~wÿR·4Žãµk×2×½ ⤤õ©¶gÉ©clé° 9¯icª¹ZÄÃò«~’&á¹á†_n¸ý´Û;΋^ô¢•+W.¼}áÊE+G¾7’[ó–y=¯èñ}ßó=¥¾‘e\ëí´R÷»Ó4ÓýRw¤sÎEõ(½5Í=žë®îꔜUB“!䯻íW¶ WÂóCç\úš´óÉNp[P¾¶Ìè€fÖ*F MWeRdš+“a¸ê…? K?+MÆ—:Ïy¾§vÈ™ßUa±4M‹ea¸V«Yâl™»•tІf¬?d7Ó�Šôaب�Àq¢÷Zùy¥vRmË·”n)y©aã¨FP†.Šò Z8ÆIÓšØÒX;¤p;…ËdÉ`^ H;OÛxoÌQ Î ÿÒ¸ûî»íNÓ4^Ç/Ž+ï­ ¼DÑžJ»}z’¤žwYTeZ öù´ÑÃÝΩ_yy%MÓ¤’L|u"x*(\U6NÖLò-ÞÛüét3|•×wL_óÍæ'š¾ç{¿öÊ//ÇqìÓb´è¡eêx–-oÚ`ª³‡ðŒj-+A–¦Î«¹Õ6U®”œFͪy4üXF‰‘P¤½"k‰Ï$#Ì•m&W/š^¯“8Š*nfJéÏrôøãÝM7¹;ÜܹîÍovι¯}Í]~¹{÷»ÿh×}¦;s™[v‰Iš¦6lÃÐDVâ³âܧsŠH(bëDlX!Wl”TgŸÑúT}HVœ\ιü7òkÏ\oˆ·ÿxûªU«Öë›G6 ß)./x#^â&¤­B¯PEÌ‚ ° ÝF:H¸ˆ‹öÖÓ:nÐUÖUf_7;‚z±¾ã„çtü+}oÝ4óÔÅ9½+ê=º7Iç;ÏóÜí.ÿ‹üÄñÕ± ¢(ÇI3DõÅzVi[N4õEVkH²BÆàA)UdL‘ýžžž4M·oß>sòFéyö…æ¼ÖRdçØ–6Ö"ñFÚívùûåÊu•‘ÓFb/޼hð’Á`kº”H½®pK-·fðš•2jÄ¢Ñ@âÿÖo-i¥Oà èyž×}w7š•n,1å®ãúÖÚl6›¢_çóI½¿ÕúL©Dã=#Ù’¦ió=ÍÒE%oµ—¤IÇi5-¾³Øùp'><öžñ¨,Ñ8Wõ³éçwýµ;‚P  5PÇ×€}äÄu—¢P!A#2óË Çñ[l `µÂ㈧Œ`Éa!¯hv;l0=àG~…e•¥WQdI-€ÌÂMVTóÏU}à‘GÜQG¹ãŽ›üçßü»â wÅî´Óþh—~±»øýKßß=£›ûf.ŽãôдqQ£xK1Ý©W6-(U3|\º‘˜‹ ½>wî\çÜÖ­[3[:#Ы²²Åï;;ëZ¿éÜMF#y&É]“Ë=•‹¶F0´FÉ õ¢˜} Ĉ%MÓø¤¸òŽÊœÒœEû/êíí]¿~}zYºý‚íñÜ8÷LNË5ûøí/µ W Ï"¨ä>œk^ÔÌ$¯Öœ@öðªuÓ*ªÀÆV®}:Š3pN¬93™)£Ôëׯ§�µƒ^9£Ü1¦s°h´“¾:ø;ÚÏè ÐßæÜç@¬|£2YSú© ¾|´ÜT;¦ìgµ#²Š“£^´™%å׆«ÃàûA²wRÿN=-¤Î¹ðÚ°ø³¢wŸ—z©Ö00=ÏûR»}m©ôÛb±ÛíNÁ¿´ZžR?S®p¡Ph¼¡áßçû›ý8‰uˆ'ü~Ø=§[¼·Œ0`gél<£Ž¸Ì)ˆ]C­©~u•V¹3œèÔèšÌ Þ¦IS½Ts]‰ÀqçH¡(©Á¤ÐµÙiýeóÓ’ÑadMRUÙ“˜ªúyV3@ì æ½ºïü9…œ«®rsçº×¼fú;ù¼{ë[ÝÅ»»îr/{ÙçÒ_ì^|Ѫ‹Ž­;ñ‹ Ïyþoýâ)E¿í{‘—¸d¦2¼_¥<!( ¢–üp†ããã›5Ó`ÇrºEÅÁAîÁ\éš’ßòãvœL$Iš ¦Å{V �FS†ŸIñÚçµó_Ηº¥}Úwÿý÷/—Ë…BaëÖ­ùçë߯‡o ÓnÊB·ÏÕzA+ÿÓžÙ˜ŒùûÝOwYÜ:¹Í9Øl6‰ÇZçÈ£úŒ8˜©"Ð<ç°Ø`ä›yu"0¬ßØ·¼‹Å³ãTù)n”ª9™™^· ãƒÌœ“’›a„«‰M;*‡H(ô'œ ¨½” M ­_™LÖó<sJžL¢Qîžœïûa.L&’´›ÆIŒ… Ä ÊÝîßw:ß-òý0I|ß0 “4ýx»ý¯…Bu*‹ÇS<šy›½x"îïïîsŸÛn·—/_^­V½ßyñì8-¤ÆŠ´Œç$îa€¡Q\*°OTºŠ$qÄ[»hA‰Ñ„%>)›£¶9Zªn ”0e ¨¦8‹Ÿ¦Ž “Ù-ÒXNß… õä¶ïB8¹U§jY'"#´‘È0trÃ:mvქ¢f!çÔSÝÅ»ë®soûäwZ-wÅî9Ïù£ÅûªÄ•üÕùð;a=ÓÑkL?•‘‰w ”|fèÔk¶Ýn?õÔSsà F¬šÄÔ"­V+nÆvÃ9ç§‚Ç™£\¹žFJÁí‘l,ÆpÇi>MšI!_˜?þ‚ Úíö¦M›<Ï £Ð\.Ú©ÎÓë×9ê8޽ÀsÞNúZpmùS)›pµù&<+HkÜäÌý·I=¸UXPsÏõ‚U K)ã ñù_ŠE:v è UlUÐWG>ƒ•Ü”y+B`†ÆÕ­T¡0¬‚›i|©Rc„pç\PŸ® ½0 FÔ£ç{^- ŸÉå˜iAðtš6’ä°4ýE#ÓiŸ:Ißù¾ï÷ôô<ïyÏk·Û«W¯¶}y‘²T¬:íçǬBõ<ÏäHøt´EA*Fg <�t“j;G@ÕDÊ kÊÐ 8L2¤ƒ®Ô¶é˜£‹Cùb!Ö~ÝÂ'CtdÕ OçuZ“qê¦Ùb*CDÄ>ÑLâûŸ4IZ¿>øA×h¸o~sòŸÿïÿ¹}÷u'ôG¾zUŠe¯*©Q“;t ;MjO1JµúqâHhê& ‡éÖbå¹:‘°49gÕ‰Ç6-LªÌø‹má@#›È¤Z&ΛL'GFF¶lÙR­VGGGa›p²d¾ï¿^lþmÓîÏøø83óÑ{£Â· :v£­u D³5Š;ÑûR_)bÀ3#yB‡C¥nì'˜P-E'*úÜm{:ÌjéΓYB¼ @Ÿî€c(uBöµóZȇÖLVg3{—f³É‰¦P…”¬c§S5ãããpê´ÿLoƒ»D}O¡ðç½J04Žcß¹´Ûår÷LY°«msîžœ;Ø¥³Ójµú³Ÿýì–[ni4¾ï§G§ÞÞ?¾“ßL[Lõ™F/ŽSo·Ì$£rØ80Í” •FQ)«u…g-Û§ÊQ†˜úÿ±÷¥q–UÕõûœs‡7Tuu624c£"HJ‚# AAFã< â€§‰Š à5¨$# 6SËÔ4t7ôô\Ã{ïŽçü?ìW«VÝâÃ?jdH×~m[ýÞÎ9{ïµ×^kf‘xÓ¦Á懸-S³ÔÜiQò¢Âfë<®kõÃ1�ÄÕâËa|âÿØ\Nãçõ¯çäâ‹åƒ’OüÓ_=‹Ú‚~£›ƒq✴a¥{^—“—ÐÕ€&‚‡F/nlBŽ)Œç`ÃA™çÀÕy œãŒt£Ä¦N—Äå+Êñz|éÒ¥·ÞzëÒ¥K7mÚT×uö†¬}YÛy×ívuÅ{rEâ_éñiø¢úeuò½¤!b†€î4_*FäPþë>kë"Åc­dj<¦À°!�L!Ð7‹Ñ6܉ùQB&@ƒÃšmçÓ‘(O‘›ã+¤ —)¸x`e,Šæ«›7¨´LÁ@Rö<‚ÑÛc< kŒù®µŸíõôiÿÃÔÔ¿ÅñO§ÛZF mÞ–úE^æË`0X¹råºuë†TŽg†øž8Œ”€váX¨{!,} ìæécݬݢòhXoØkº£Ù®­éqý!³Õ˜ �3‹aÖÕjéÔ±eö¹À~8Ì©°S–9g)O¦ƒ‹9[ï°Ð»VũÐ7¾ÌW‚\ÐÃÒØþoÐD$Žåu¯“‹/–׿þëGäꑇ*åŸYÔ RÈäœYu]«G zźš¡Ú„¾˜6º rî22\t¹S­˜¹òÀ& É´´3ÄÁ«q;ºßcO¬ß²>»'kµZ™Ï²'eåÎet]TÕn»í¶ÓN;­\¹ríÚµ¸ö9íñÿO.Kâ_ÇFLõìjË+¶¤g¤ÚKg2ÈJ2Æ© ÈùÆ ¨0%ŽŽR6ý}ÁÙW Pú¥ˆÙ8VX7Z?—§='vEœÐ‰ÔUȃs ·Ì ܗfE>öïÑ¿DÓ À0[Áše³Ù¿UW çPIƒ"_Æš‰k‰s—ˆ|8ˬÈWZ­Û¬õEÁê,ܯNNOz_ï™ “~&;ÏN}f*þ׸{M×'ž1L a ù¡ Ó¥‚QH* 6:¬8|y€L¦ý§ñôXT©ÁæÂœ.‰U@VÐ sņZŒÀâØ 8$ð.>÷ÙEÏç f–9,i‘Éâ ¡ãÂ�#Ã¥áññ/䈈srÆì �²o·ÛH�¡×„dY¦ªƒ Bn40ÏàyÖÐ%ušFi{ ax…©ò¹Cï¬J‚òœؾ“GÐú¥2„Ð~s;ÿÇ<ϷܹEDB'Ï,âïÄöV[Úr||\»J,8è–¸yÇÌëŸÜï¿­oÄÄÿ3*"¹Éqžr¥ÈYXƒŽÑàŽ7\å™SÀ£µ(4aJÄ9nÉ0)ä=ݓ裨E…H7çጠ&lú GAÖ…QЈ!€nòhžCDŽ‹:ß°ƒä*$Pß°fç4ÀáeÉ'>1þ!×ur«só¼¯En®kC^A ÕA1…I_ž†'‡ò¥±=;rôHA;FlFHùSÃã£áNËÉJæH¦%Úk°af ¾KƒYC/y 6ùQu±×"O<X( â‘â2N±ã*v1×µ` ð,6¨w�1ó QP¶NP0i…AšÇ°=¦¯€ ™vZÄ»G¢Ä8k¾" õ­™à”†99 ZäD ‘WàÐ¥å<þF¹^ÌÎÂpâðúþjŸÝ®÷®Ëç”!³Õ¨¨v°ADTQŸ2ÜirYb¿1M•™˜Š68n‡Çi…ä®Y/€¹vp¸‚p�£ŒMÉ!m :hbÈ_Ê]"p¬ÙµO²3èë¼Ð{_O'N¢G¾ïqÍh_±Ë=îQïˆçÀÞ4d²K²p@ðTy®¶r€ep¸/ë'´”…«¸â�� �IDAT-}z×išB+׌"î>É=IzFÚØbh!0}� 3‰`¦LK[rwÅÇ0¯b3 T�Œyòz€êb<®Ü™Ç\C¾<NÄ:èˆF"RU…ÝCÁ}×¹†Ì =¢(RT@Ÿ?¾TfKΣ”ç \™Ö@ˆB€D$ÎuiÛréN”µÚSA´@ õÇå“ ïu4NOXŠ1ÐðèÄöúÄb €×p1ÌÅ9Ëû€/¬AX0T7V<›iÝå“eÞ¹‰ ÇZP­p¨åy±5¤oÐGaòX#Åã‹­v¹yŽx‰ñϹ^85ø‘¦Ó‡ÏÜ9”;8øíâ(Á?Ãƒí½¿W>¹l®­¿Ðÿzß-qu0µÃ2ò@Tði8‘Ûí6"c½«Ž‹4cñ´Z-dëø·<«ÄqG0ÌÐt=,X° „011àú\TÆl凨~Xݨø!³÷Ë=Áy€‘EhæÊì7&¬¹½ÑÐÑÕ¨+ÛÆ¤ Ï6äè«”'Zªˆ£K ¯YaUg—¥—¤­Û[!„섬øhÑùëËi³º6JLzÇã, ð/Ø­È_qJ`Ö[7…nX$ºs·…œGò‡gàÑ¢ÇÞ(ŠB'ï¸FFM-¤!j!û/¼@žöO;ƒ³Àb¬¸®§U=VçÛç¾ö¾òÑš&ll8éߣ+�vtPÎó9Â<QÌvhzB”’ý1ûÍVuÌCã> [ø°•Ÿƒœƒ£“¬ÿ…;/ªLdÖ€2´…3—(Œ#³ßàP¨Rï[PÁÒÿöÏé»]ë¼–ä$´Z­Ö©­ìجV?ù\‚Ëž{~é’ÐzK •*ÀÏrÌ}�¹KõÖ ›ÆzKºŠXO ê èhx`˜N)²åP_ðŒãÀ%ˆãBçzËbDÈQM¶¹n웉{g‚Ã\@¯…aü…ĨdÚ0—©Æ(yQç!ÁÂL>DK"¤uô‰iä¶ þÜæÇç#/1…‘ $º.J’¤ÿ³þèóFAKa\<[©(b°¤Yêp®”; 8ü¨@‰>=ðïÿ¯ Þ<ʰ5}s˜ †Ü,"‚zÐVaY!“ú qÏC°"ÆÁÍíD™©§ìnÖïåCùx^.)ÓëSs¿ë‘>>¼¨4ºàÕÈlë-ÄNî ùϜֶ‚盨´P˳±n#~k` ¥ÁÜÓ£|!Œªð9ޝÀ,+ÁÀ)U™ë Óq§zÈE|b%±D«#çIŒr&! +‚ÙÛD»Eõêš1@œÂ€hpn¢¢b™öY@²ÌÉ ° Zœ1†ƒŽ³„q2"‡©´åð6QR`å0ȃTFïNq!ð¶O±ã8Óùx´ç€,²ÉÆ—¸)ôŠ8:"ôb@ †¥qxýà(çDüûFÁÊà±bS½E¤>¼¶¿µ¡Œ5bDD|îMeÜWT¸ÅO©cb³0¯¯FØ4I•iUY½Y69d)Æ'„ëðÚcûê9A�ã H”6ÀQÅë¢Éx=Ýa�Sêïa·þ!„#‘Éæ›».þMœž‘¶Ïl^4:ºËhxC;0ÓxÇ=·7�bàÂ@XÀºÄ?ä¹}´[øÓÐ9‚gÐXU_„á5¥óáÏaB¤çòbޝëA%—»÷@ظ[Îé|¯×E˜JF¼ûtkœ‰ïˆu1Ì›7o˜ÉÞb%•|Ÿu£7<°É¾yó¬[ÁýM¥¹Îfp©a5Æ#|Ûá¿Å÷ò²o´Ç‰™ ϼ,H#HèÈ?: TLÄ�x…y�^Ql.…·†‚ž¥+¸UÆ« ‹Ä9722òÄ'>|6™ö"B8äöjÀ ö ÃÂ(»Y! ñipò úZÄÍžáYq¹-O)97åç£i@ÿð0'CLÞCaÛ$,!ðqìüßžËyt�k<)Æí=Îx"yÒØÉœàè;\«ã¬¦Ë”½¿¸Á–›r^˜·/n‡_ Ž;…Ž»ç¸'<ó õh•Ç—ìÆÈø�W!è@‚ñ‰[À0#+`j,”ÙîÂ8¿4ÉE/áÕê î0 Ê¯œþAÉÒÐðÒjµ0S¹*ÄcdOÏDÆñ´#¢SGlê#¤~­Ÿ£*œ"2::ºï¾û.X°€¡=&²,ƒÎ¸ˆ bž(ÎÆõ;Nê}a2ŸIöPÖá¹?=Vð]Â@áËʰ{Àˆ*๡ISX¬š Ñ3dÐØS*¡¤Ã+ˆp€¬Á E…ÍnfúZTADƒQYà{èÒñÅGQ´×^{}ôÑ###�ðÀƒ,lêÌ-^N¼ }‡‚‰õÐ)¦’2ƒ\m·Ýv ,`£ÌiÛ÷ŽgÎG65Èèš:è.` .Lb9Õ6ˆÐÈx¬·s¢ÇAØD§Éc,˜ˆmÆ™øÓ •â£Pa(€)<,n Žð8&yž »0}Û¨.&Ý<ƘM›6ŧÆÙ׳ÑcGYëŠìÂÉÛÌÞ2¾ÅaÄ@FL`9Å`”~ð0E¡é$b!‹) ò`µ7Œìáw46@þüúäU§kÑ¢EƵÚÔ¯€¿5¼Å@oƒÂ#Ã2*ÑÁ`hj¡ÛQE½¥>ÔÝÚNÙÉÉÉeË–i· oåâÅögFßÑHàÛèä!óàñr}¼ê”ƒJš]™VÎ ®!øß¢Ñȉ`Rä4üÊ ÙƒodšÞ ¢&�.-ÎTÔ4n˜a™UXô+tއ¨t1ë© f¿žÝ<#ähÎ#kÖÚÕ«WoذaãÆ€%feÞ†$‡[–Ðe]�Ôdú±ú™ÃëYcÍn&YŸE199‰×ävw~çélÆZTEMhîI‡döÂá9S½’,Ët°Œ)0úí˜ü㜘6ȹçÊK_*dz-äü>¤5dÓìµÌZ­L1b>ð±€ÖÃ@u¬§+Ÿ£1Î|¶ÄÙ‰xQ>Ø^{íEÑÒ¥K×­[—e™73ì&æ5¾”NY©ÁÞá/m 3˜%b:rCZ‘ê1P&˜&¿ 5!;‹ 5#hÈaáܬëú€$<|&ì ’$Á ·*x¢ºR|¯Ýn+Ë€Ûª3¸Í ¦:²*ÿ¢Œ~¡sDZyޱ¹~ ŠA§ÓÑOF±… çÆ ÿ’é!yPŒx¶Á€EB™m(¤éЀg¹-ÏNNˆ ¿/ÃúT°UfK·ácðÞûN§ƒ¸ÂØ&O§q« B8ŽÁî{&bÂW!VP¼„”lx­â®7mÚÄt V=¬ð€pcœ–· Cpx†ØYéÇÒü}yüÖ!æ†ÉââEç¨NUW¬ÝÉÜHFá‘ $j|ÍPjàÿBêŸ(÷á‰ð‡ž˜>(_,¯yüèGRrÜqÛBÎÿŒ;€´ˆk—¹’! gr&ï³>kC¶TBâ.°DÄÉËõ>2¦á0 ±Á†ÂÔÔð¦qMņº(.µR1âÑh„p“¢\Á’Îô! ‘!b(I¡1ÐÀÇj&Pà˜-]ÅæÍ›Ù„I¥,j‰�§¼K2'\ÎÔgÿnŠ—ÅAE÷c]-S¦>0e‚±ßÉ‘5Þp³Í-ž¹Á}5ºMÈ£Ñ5Á?Gy„SIMzx\' c2¼by6Vh,”“h=°ò¡äÄ1 º™ ‚ñÈh ¶wõ1É„RsƒA ¡)@ð€=îNó�·Èº°Ë@ˆ‡æÐ¡Ž¦ð„„Vj4x‰È¢ØíÍ<hìrÛûTÏ}ÖE«#É_’ËâþÁñcgñ'^rØ8VYÔ{_[úçùÒ•ò;±_¶š%pka‰-Bp¾ýA?E!\ 'ž(‡*(Ÿÿ¼d™œp¶ó?ëåð!Ë>4º¥q$±O-û€/Às38ò€M#ÍdñV~Õ±aìØº®»t{êµ_ÛV9µò÷çí·Qn£Þ‡ô™ÂË88WfÜW‘ Ç_£h«ªª>¾î¿µoŒ±wÚöYmœ2¸�ü>+ú4<c Kʱ_hÌ›£ Ž0>1‚Ž æLXN˜õØZl%½}pÇ“ß%6·å.åÄÏ'ôâÓ§²Z¢û"È: È ®…C‹˜ydí¬†ñ YÆ1ž³ P�xꆾDm›3 †±J¦Hà°Ë(q_3èÆ7Äèô(ךk Ä9PuY†`Æpvš÷ÜдդM[ ÚåÆ;ÒhÉ´äÕ™Ø0,ot(qÍÜán(�OæÎ (cd³Ä—Ʋ§dÍŠÝ ‰®ŒìeÖÞhëP³ gÐ㤒l,äœ3Û›©+¦ÜÏœû†‹¢¨zr•ýW–¾'­oªãåN¬†x˜ï÷ÿ9í4yï{åÉOI9ã ¹ðB•ç<g[Èùÿ¾Ò!fô@ÿ,ÎqxD‹ÿ/þLFØ$ƒ-s p®«0MSìÆ!µ÷~ÊP?­6Œ_ã˲ŒæGƒ=õvutGÉw="q¾¨!Ü$e¶È&Ç?îX²ä¹yc­­÷®_DWEícÚÎ9¿¿Ÿºvªû¯Ý?XçSSS:(ªÿ…¥‚Þ¸FS=ãpr*ÝjµØÄ^fdÔb*sU¡D‡!ÿ¡¼B» ˜ÇtkÐ绲,Uyx- áÎÐúE+ø`Œ‰£8øÀE­8±^¹ŽˆBhCNL+Ÿ[—0ñ‰MK¡å£…3eŽ‘t#üÈlü~¿ßn·‹¢xR–}´ª>2oÞªé(Èms6öFãC…èT1Z€U$F›ù¦µE«ÕB[Ÿ†Õ†PidȨq‚ëÒ±Á÷a� y'2¦á@Nw+„Ú«1feŒ‰'âpK°§ a âkïÅÛ‘ÉúÈ&y0¨ÑoN’dòÊÉÎ1àƒ‰â(¾5N¿ö¾ÕógùðP`zë'A”'(~ŸŸ~P^ùÊa¼ÑŸyóäÔSåC’?û3Ùe—m!çÿ—$ š<RNLJ"ùšÜÖÓ„ÕgÓÁ=ät�"˜Å?7Âñ$&‹na‰'oH²Ïff½‰ÖEÁ‡r´ û…ö×Ûfí ZOXdÙBÂq 6p…Á£‹¨Ã0 Úf òôÔÅS£G†ªºª}-KdôèÑÁå­¥¿ÕÃF—™ ¸ `ª-„t‘9_æf@Ñ^ßW ÝEîÖ:Œ5ñ ì6Íݾ4I½÷Á„‚cìŒ'·Á@b渂Î0ÒPZq ³‚Ä­•+ÈælÊ#PX`¨Ë¹ÀÅ᫽½ªªžQU'…ðþVë´~ÿ;Qtµñ”óÂ<@Üœ¤¹ÇÃ\c  h§†+îU�IæóÑZëŸá‹§Q™åÆ^kQaàeaŽGõñ”K Y lgn( õ ¦É°{¡L«»Ø@~€n«JhFÈ!Š ,¼Ó;üFüC´ý 3Â[s‹ÈüˆÜ]ëL˜‰¬uU[k“k“ò9¥ûfs¯¢‚TàÖ>òùð‡Å{yá ‡³n\|±œ~úŸ,Þ<HÒ�- 3¶ß@„Ù“Ò Fܘõ˜Fð‚sçœÓŸa££6s:ñ¿Åb$˜`î5ÉY‰»Éá<ÕËÀÙĦ–z=ÊRÅl9TàÀT„‚u¯¬0œÅÃïËŠè_†´uÂߊ7½h¤_�÷1XêQãá³x»fÁ q€Ê’\8æ 3„ÙU”ið 6Õü7‡L‚‹V*<– öׯÆ#÷'õ h!ÄàAP¼à8ÀÒÔúûzê5&{xf1�46]ÕO/Šç†pQ·{¿1ßH’ò|iR¾~)Š›F#Cˆ$¸Tö¨E&Ô fáÓðºh‡ÄëíBö¹¬zn%Qå«êà*û|–ï–ãIâðVÂ>e^µ¯xeØ#X“¥ù¸‹-Ùh­!Ð=¢¾«–#q ^�û©só¿”4þq·|cé¾ì´nSEZï}ú¥4?=o´c™2Î$r.IŸŸ÷½Oî¾[®¼RDd0Ï~Vþú¯åàƒ·õrþg…†Î0Ã̢ȊqÍåÉàäB‹[KW]@!ø„ìkƒ;;SO8ëkïÃ̼ýºÓÙ¥ÓªÀa&.b2†á;ôá6 „ÿt€Ô€¤¾!£«DU,ÓúYuû›íº®»Ýî¼yóœs=ôPUUöz»õ£[Ó2�âöÜ$kÄ (P8å$}=>TE˜zËCm¥APVª®ž/b‹IÆÄôíÀ䜬Œj†E¸œjŒj6:XÀëÑCâF`L4~xHh’í¸`ªÐÛQ}-(°v7æµ!œßno"[Uw×õ×’ä£Yvz«åã˜k”¹œZ#CûPkGˆ 0þ ö——( õQ(• ¾ “çO&ŸKš`×Û–mU£•ì.Ù{³î[»2%‘33<7h¥s”…á·ú9�½â¾Øtª1p£y’&=\Z…Ó颯*é\”s&ÁóÚªÔÎÎRˆÖhIÎl1Î9ãŒÚÛONN2• @ÝT8š½ÉyLâ÷ëCÈé§Ë¿(?ý©\v™|èC²ï¾Ûkÿ³>XØúªDÉ8úœ0jÄëd܃u£ÛôŽŽŽ"Ï÷Êí6;' !oâ·ÅÉÖÄ®±ìæÄCmL}™ FkJê$³VX‹e41ˆÊÉ) 0Íý;¶ã"·páƒ>¸×ëMLLŒ³æ‡@=jA¶/ĉ£’38#‘!H+¾ WA!ðôÁË+Š"¨á)§‹Žytƒ(}M,+[bˆÍÈôØ¿5�7´ÁYÏcù\IóéÀ¹Ž"Ÿ¨ó€î¢ÐAgH«UÌéÆ0’íjý½'[ÅßëqåZ¨ÁøÒ{ÿáÁà#íöFkãi@lU‹ã/æùéÓG– x}ÜÚÑ{év»¹Åô.K(é5kH…w+Žãz¯:”Á/öišvæuò<¯·Öf“1&ß+ï.í¢µ:SТÐȧ{ÁL¯D'Û41g3y‹FÔçs€i8²[33ˆk`Ff‹<aì ùŠ>ÀÆØœÆo]Ø "R¸7„=C´.ªëzÍš5È5Ë=J»b|F×S¦Gw°7änÏŸÑQy×»äýï—O~Ržô¤ms9¿°Æsj\Ÿ²Tø£¬‹ÃLýjhç5¬M  5#Ns„Èó¤Z_uŽê„Œ3ýO÷ýߺ²–††¬,°dµØÆên�—¦·X÷ܰå‘Îôhjا¿M‹ÃŠô¦t||üž{î ^^¸ÿv˜/a/wŒ ‚Í 7i™ÆÔ)¦árËÒa�7„̾æÍ›§Ú 8pq²hv¬ÛÞÌLÀåéÚ¹Žà 7-à±X 0Ї:±œÐ›AR‚H ³9z N¹1&´BqJ!;Š_èED&ÄÞoíX³Ö(—¦–Úc{W§óæ<ÿn’Ü>û)Šã½K§Hk AÏÅ^àQ¬( i5îšc'S¼ðÀîÝò[Ú¯oÛÄî¼óÎ|ðøøøM7Ý411a϶ƒÿG8‘îS]ÌøÄë„<ÊxÍ£;ÈÌ1ý³bV�<Y#€å ±rç å‹rjxÒ“wOJ°É,(Eú$ã÷Ń_ ì³gMÞ„òóóö[ÚøFv/ä·ö°•ëïÿsÞyáë±^å°»8Ö.xÏ�÷‘ü6$¤€ÎƒbÀ[\Ò"ùeJL§Ó !ôOì·¾Ñ ‹gÀ‡ößµËÓËê*º;jLq6„,u'k…Ž*бxdèÐ1DŽÆ;³*ì¡ ÓäÊdò“#_™˜˜X¶l>¿xeÑþb›ûɈèý"< ×kˆóóqÌ3wºë|`µvdî`bŸN§£õ\´ßÕÐ!F«€•Çp4ð”óÓ T[F™6‘dpò$Ê!Ń}Í¢¶f˜EfmñCž|פ½ÏÚ·É­‰ˆø'ùúè:{cÖútËf.µds]nÌ+²¬çÜýizh‡VÕgã8›žÒ•iM@Í8FCW˜zæÔ‹Ì!Æ}a;�ÂÒØ/2Té~ÚÓžöÒ—¾ô¡‡ºï¾ûƒAE™dHQj ð0Ô$ª nÕèÝáˆ×˜� xw<OÊãÆ,ÈÆ¸.çT}0€ó3™£)%¤+*"É?'ƒÄWÇÑ#©ŸR—g”é¯S™{jÈ^<,½ö±Ç1~Ìå ãFóÍR^BÆ<—£øøoœC19‡gõ¹LÉž—™eÆÜiâ$Þn»íT'£ªªöÛù»sû[[ß]£Û¼Rƒ"˜EPˆa=`$_Ú°Áé£ r+ÝHP\ff*;çºoìnºzStU}&²Ö†ýCï ½ø±,Oé€Oh…aD”eA|b§EÈXqõ€âð@s½^oeQT \¶òo6òhÖƒ‚™š-‘C@ÅÖ¤�ždžN6úÌ8˜4¸"íe.u·Û]¸ÓÂ»Ž½+92©ëÚ8cŒ «B|YÜÿN_º"[f*P²1Æ,ùŠsçåùEíö‰““O’Wb�YENûC�n–¶RÒ¿Ro°*€ êùŽªw0$IâK_ÖeQ«V­úÍo~³~ýú‰‰‰B-µxAö£jÊÚ•Ñ6OÛ4„3€;é/ƒÞ z³ÿMd¢…ÑÔ¿N FLü’Øn²Î:.×�µi[‘ñ=�ÐÖcìzË ]@¡•÷ g†|aº¨ILA®s»©žWï,DÄüÎÄ_Ší*[MV(ŽžÉGÆð‡ör¶…œ?üÇõš“*ƒì´.ÎA × »<üȧ¤! ´ý‘Íí“xò‹_üâ7þèG?Z¿~½l•¬›µ´{¦×0ƒAÜBÅ m§Æ‘Á— ºA[lOðS !Ø{mûÈvõ¢ª÷Óž1ÆÝåFž=2 œ!cä‡ÛȰWÑ è9"JƒK¦Œ^ž f)e6A¶ )n˜¨è“Ôy‘QxË#žÇ3›ÖD°ùÑ$›ŽãÖXš“³Nr!U Z—&ã`1 _¸ô£K““HóYk{½^UU­—µ¦~9¥á~ú ×´öôn÷ŸÆÇß:2R×µÑj;„ µE]×Z4#–c_*xNœAÁ€J ·AÇ9‹£ÖKZý_öÝî®»îºï¾ûô.D¤ÿ“~ç…îA·Sôr°! ¶ؤ|%è½ù|ùÞ2ìºÏîêK™ú—)·Á¹O8Y;cÄ •Þ2»640X(%°Uº§2 ÕW.Óe¶êóÌyR…èö(¹3©Î¯˜°Ç³Ì„ n£Ñ¶óü°'9jX`S,¿ÁijíJf;]âíbCí#…T.ô÷Áº'I’$J4†¨ ¬´³,v?C&åFQÅÙ%ìIF'°«qøòHž˜ým¿Ù!ge½Y%l‚"û»ÿ“ÝN¹âÁÌ BZ GÛ–™²ºá5ïFJ Ohýj­x0¨Ïê(AÀªB²ÏžåÀÙ¹…Àá-d]áQv–ìõz<üÏo«Eÿ\Wµ©Md¢N§sàÖu½xñbÖ¾CVÔ{Ô«:#IÌ4ˆVûqÔÇCFóŸM'áà‚Öû·rýÊú®£k¢â…_ì‹ßu]˾ž¢›#[[†;…i) —#$F€€^ò ó˜±ë×Ôîg.º*2nˆI´_Ö–KýÚ:ùäPʳz¼œ ¯Žê–K2[¹ŽÑ3ÔCTRÓ\™­U Æ8ܘ¯‚ò) ñ0¯¦¹)lÀó°BvÛBΟ4ä€Û:wYÌf‰YÆŽÙ KŸ;ðÇÀ5¬®sÅ+‹ÁŽƒ+V|ík_˲lãÆ"RQÊ2)W–*ŸŒJ'‚c½K¦sB 4{ Zë°"3Œsa\IH¥4>"¥ ©GøšÜ5’¤dw œz`%éC@xCr‡Z„e‘°³Õ&¨z‡¸fÓ±HeÃÆ…,|¹ÖAq†çŒìž½…ðŽãœür”Òþàû$Iƒ+t±¥1gN<ÌC¯\è3@ÊÿSHj@&‰9—¤€1.Êçœ\ ÕñUõªzS%"²^ܽ.úB$Ŭi”°s½|°°AêÓèËuø¨p@ð±77TÕÃprséŸê«ý+w‡ãJ7 öžGsi KÖAÕO€¨ ð—9²¿ª…40¸>+À‰Ê/Ç}m 9¢ZÜ\†;P,sœÀÒd1G–h›k î)=“¯å.Ì ~¡ßrç–M›6 §ô»q¹wéWûzÓŒI-sl–µM¬Ô*  82†VíÄÌi�ôœ³3®Í¸ ›Ò7l†ÁDh覰òÓÇAÖbá¤ßsë“€Hðq ڦʱ!T 2·>íI�)–k5„Ç‚…³˜ÉÈE3ÚQš¢¢eÍ•"‚´ÞÓ꪿:îõz7ß|³R¢E$» k½½Å!´„Y%&x ý±"Æ`ROÜèæ'‰¬¹çÌöD¥^ô‹py;†xçXDd«Èj1ÆDñåS0¢…\¾3Y ¨8¬•0ê?cx³sí­w÷;›n·ÛjµxàcŒYc‚„°K0wýÒá<â÷Ÿ�� �IDATR¾!`Ö5›˜4Tع‹É<ŽcøŽãñ²<w” Ïcæ=g9ºüÒ4UòËm 9ƒ�Ç¥–±xyœtë9ÈzMü_ÞBÀ[ppkýÛjµÔm^YXLºoÿ}»øbÑïöÓNUÈ«ÿ‘~tUÔº¢¥òXÊL~ƒú½æÔ Ö3?ÈyBE¦†X ÍêÁú°DgÍà”„$™”:8¢áYJåí0‰ŽÁ1|$3&p2êþïõzl`UìW”­ÒãîwnƒYV¿š¡-*ŠBßµ~…63XÕ5cT¢J?Âá,P•—Ò´–ïªÎŠl܇a{7XúÆëº®î¯Lß”Ï,ýZ_®-EÄÏ÷a¿PGµ»gøûXŠH‰x…£ CˆÕçÃ|bÖµÔOÐÁ!®‹YyÀà%"©âÁM±¡nÊMDտ邨 ÚœÇ è4è-@üX| cªJ…Ùþá?7>Š¢V»Bè÷û³†…M‰ž«~5ëçê>B"Å:☽…f6SŠ‚šóécD +6SÀ¤[IåJuQu:V~cù Ö”ãâm!çžËæÀäT€ ‹eö"䦱LOøIã2èp ×äabxv\ïRÞ<°ÖúÊwþªc­z§O9䛚¼ózB§”oJƒ ièÿ¥´cPéx®¥¡+Ó¨?&³q ΆMÀY`Qg²‡¢ú[ wƬXtØ$Û3?f<쪨 !¸-ÎM¹ÑKGYíè2 -¶xÊ„á5ö7â›F†ˆ\#ºúkgd/ 6eÁ»@ÿ ׉Zvøk;Õù rq•‹¾:#*ƒÒ-}[Z|¨¨·Ôv«‘Ð ~¡¿Ëñγv*ß;·ô1쉱ñ"P7Š3ôDõ+´…Æ�ËÄéÄ´ ±ãX°µ²F@ƒRŒÉ3®¤™ªçì`0ÐFº†Ÿ§Œ5¶.ëzÚ®´°VªªÊîmM0nµ{Ø>"”…”¤iØAF+&˰£c¹ì!qÂsiØ5Zà2Ï…µ—ØYª=z9€q4e]^%èâ ‘ù¡ød¡Ú3í¿oûžçö,@XÒÀ³’ÍÇgYV–e´:j½«5\sVx6“Õ´#³¤?ð ÆñY6ƒÇ¶ž1û€%àxÚ”U5yÜL«uöñE…[cB¹. ¶(O!`a§¡±]Yždí%iÊcL¹c9ø›ArO2òƒ‘ú¡Ú9W?£.•ãoo}²…žf×9r³66wª£¾xk–€óð"'ÝÌ;çvtùô(Q ò(ЦÞ?åSïnqƘÚÔƒD?‹Ü•î=Yö‰Vkx0 \÷½Ýl߬zJ•ĉ¹Ë¸_:cŒ‰gøxü¥ÌŽCù…†Dƒ¯È@™ÖþÒšQªøpQìR„Ú—¶Íõ†1OînB m®³AîÒ8ÀCÆ繟ÆúA kmçÀp• PÓáC¸ÇUyUPÛ•–iëùÞ¹ Fîv K·Æ’h¤°¨`{ñ²Æ®ÇÈ _60mVkämÅäX‡ˆXÌhmÀ3ÛBÎ#r@1Ä1‡dgVYbç “CûÝm©Êjðí»ÍuÎíH9 ÂRb+äm½‡8Žƒn?t†p¸£�†;ÿšEj²çMžA`@ž«ê2œB¢›Âc­B>Çí¤4…tX¾yP2Ç´›ù©�ÍpR@#‹mfx¤IDÒ>•e×8÷ ï¯ìtêét8„àwðf;3öñBª8Žã%qtS4õý©îç»!ªŒèó9BCÛá°*žp ž å9>>U¡–Ä>ÖP`ÃNå>6·�«ªšxïD|mÝÙUVDŒ˜Ö’VuLöáÃû‹Ó½`0xw»][;œÛ¸+vwhMåj©yù]è*AÀ†ƒ˪²é5Z‰úÏuˆ•ÁKå™eú¡4ÚYkóSóâE÷¥Ý¨ŠÐTPY#4íôÕS’†ÌRA-«'&D¸‹V$ÆÒ�ŠÑ´P" O×5v²Ln†¯…ìýYqZ1òª "^ߘ5¦û±.NyVÜÁèö]Ãu¤¼yGƒJÇ3œ4Jjp²yŽ/%ðOs4>g[/çÖ¸NgÜy.¹`¸…Þ™»k}‡5‘ñÞo:/ìä/È‹sŠøÓ1¦[Ô!Šé^à„`†o”°ÏKHt®†j»T/cĨ_0S6yKs>Îù aMsÎ…¿ßˆÇ G�®ù´-Äù>v òY™vyÁŸõg‘È;úý³Úí,ŠÎ¨ª“òü»í6”£Æ?5¾ýqÛ‡4¨2’ÜíÎÝn⼉ùïž” xËl=é~¨‘2‘Jz ýi÷âZÐ2©§…™Ù¯q©Ÿ  9…ò!~í…v0÷³ÊˆcŒõvÁ]æõ7…köO®k›}üÎ<¿(I¶L“Ú™ ÖÞ2t ÁœDÕ‹ŒK½ª*uâwª¯²~f #G á,ñî×]Ð\1=q6SÓÇÕjµæÍ›×ï÷ûý>úˆ˜C)£„G¸¬×…ó§™´Éc:Jˆo|&Ò2Ù(éÙ©ÝÞN]15Dwÿ&j÷ÛßÁ@J„†£<ËKÐfa#»b Ö$sD2ATH> ¤í *«B3BôÕ“x^G_4«š>FÛæ2“»5è=²sh¹kYûÚ®´À‘‡eì WÛÚ?ià’Ù³è<Ù®'h±h'–…ñ¹b�Ák?1—GHô‰ó­Š4ÍäÞ‰jа,ºQ“ýÐý ÛAÝxÊ‚N*<ŽŽ8qfˆãÎYk÷öþeýþùÎM‰ˆÈW[­Q‘“z=d—0D !l¿ýö ,ÐÇ^”…5–³ø²,{½F+ |©ž?šü°WiˆàøWžÙw€Î¹ÖvÇ> ¸xkm»ÝÆù5<£_ê“%‰_é5”î¸ãŽ;ŒŽ¾v0¸Ý¹k>XÛ]ìÍÎ]çÜiUÕ¦Ž1huð:CÙ§)1ƒ$� æ§q�ݰWŸØòÐ2¾n(f:66Öétâ8¶¥µ7Úò°Rc°»¨³Ñ†„õ-:ÿ =2âiÜ04¶[E°×ŠJHë]ý5Pzê²aÖ8dDD¶ÈÈ FÆ^<6úÂÑx"f]5Ð;‘¥¡C‰È‡–$ç|�äõ‹´ãÒPLGñ‡¢’<:bÌP-â.èùxÁ&Åbc¹Cr[Èy$ tz±î‡ïiD²¯fƒ¯ z_êå#yø³àwK]E ,Øm·ÝFGG½÷~‰¯]]ï]C£‚ÇËYR×·Ú]ˆˆ¦X7ºg0IÇb(Y@Ödî zÔ´¸Í‹þ?H;¸Mpùqî ­cfO¹òèÄ9¸GÊf\ȾyÚ‰eÊPã!l_ׯ+Š«ÚíûâxþüùcccÞû/E‘¯ª× €Œ8(BL^‚;C}Ö±•F½AiV•3»]H›ä:DYøËa9!æzORç0Ø�[X‡»N±ì¼óÎGuÔ¹!ÜhÌÏÓÔ3:o4MÓÿNÓß8÷Þ<‡±PÏD¯Žõ&ðöÙŽÇõ0Õ”YOI>:‡Œ åq¥ùñÞï¹çž'žxâþûïŸ$‰dbÿÓæÇæXQ {½²,·nݪâ09eC3°PŽ0 )ã�Pë4–*v�'ÜföCßAo?B~EÐAÀ¾P¶³C„@€äÉ-è¢â¸€µ>j=¸ý†OÃÕP?]!‹¼mÀÚ#6§s:À)!„ÚÕŹ…?м}$H‘Þ¥=¿È»ï8%}vØa;î¸ãO~ò“^¯g­ÍL†± îû¡CËUÂÖ­[Í`Ÿy­Xf˜™BL—íÀùÂjŒ%cƒýìPÀtä¡z`’À«†›ç ØÎµ.”Ì¡¥A+`g3¤l c`ì‡É(º½,É󻦋‰Ëò¹Þ0I4ûžþüÉ÷NŽ|lÄ{ÿÐCé#MÓtÓ;7m÷÷Ûé6ƒÐ�®Yië܃e%`dÓ„IgöŸ• 8âvПG Щ‹F`€>ÛP-X'¥ÊÚ;oœñ¥_ºtéê(zy]/ŽC¯’bPxïS‘–åw’8Þ.>øàÃäŒSRœ%¤J¬($­E‰Ï˜'¨wιàfjÓvØaŸ}öyðÁ‡íg½ñð†ú§æ:¬¡§Ð1Ò¼ÕNÆü“¶÷8¢Xkuƒ°DÕЬª þ°ˆyœI°4uÃ\¿+¥ Œ�6 ccq<þ@xz2›T:d¶~5@úFc‰Üì'Æ?Bz"ÛBÎ#Yâ0CIÿR+ŒòoKw£‹ßWf(ןš˜ü„¼ú˪Ȋn¸add¤ß]hm°²e¦ÜøpÏWqInÃðÆfD®‘c:N–eLÁ‡°Ùðeîã83Š»8Ð3U ˜ÍÄð_rD{œ °$Јfá²ûœ¥$Z$§SUõí8~]Q¼*„oMLD­ÖžÞ¿-ËÎìtÊiÈ.½7 Ïå_”Õ-U’%­V«XT ¢"·Ñ)¡`ëÖ­ØÀ,‘ÂCZ 0"¯¸ðÑaµVšJ`Ó´�g®ÌֿѬ ÍÓq8ÉÜIyqß›»Ì¦M›¶lÙ’çy/MÏ>vâ+—¶7ßÍ«ë7UÕžæ~»{Èß2n¬1Ƹ/¸tmê–:ölX‡Ôî) NòzÃZR*WÃ#Õ‹Yiüž>,·ÜrËÊ•+'''ó<.T;WfåŒ~;:U,) œ³sÝCPZÉìR¶„Ш€õ†É3V(`56½!—)ÎéÕj³„ý¨`Ä£šXT2[…¨Qšp•©"¬­§—´@á5¸‘è° ¨Ò™MF–å¿-ä<? 1ó8Š¢z—ÚtŒ»×Yguðª®ëüµ¹<AÂ^¡<³t+܃LoL£"cLqXAK0an Ø…~„¹´`N‹b£aˆ³žg9Á@Û éæÆ@^…GÐáÀ)<+¹q¼ä@ª+ˆa°†Ó2¢¡ô®c¡ÜÅ Å⻜¦]Öj½6ËNñþFçN,ŠO·Û™1nú¡¹U.¹2鿸o´Y•EQ$ó¤Nê±w7s’6\qÀÉlƒ>Th_³Îžž>Kä32ôŸ´Ûmôçqâ4hÁ|Aötæ¼øy<ø«A´d¾gœs¦en8£è,NNûe}Y½ºªn<L~ù¢à ß~A[ß~õžJR)Tšëgq²‡F^e©RÐJy€ ãWè·ËìqBÆT˲ eH.M²7dé»Ò^¯ o«WTuÄJ–eÈ`°ÒpÎ6ÎJ0¬@¥S˜T0ò$–‹FHß nAOjðÊxÚA´ÁÓCb7/Y¨ ^ø|tÅ€,±Ãt2öEäÅÀ׉‡bEæ„3ņv°ÌVxÃÁÂ’] ¹Åm!ç€Ô˜2ö ¡ÜÎ?66–¦éºW¬3Mt}dœ)Ž*Âdp¿sƒ#ÑdTžVJO’Ëh(A›º&@9¸ÒÇ j5w¤y¢‚EÚYF ÝxxððLébŠ'õ¼Fq%ˆUø}èAaòü °26Òd ž3üq¹¹¢Ï‚=hì½Õú›,;¹ß¿<MW9¦k¬!ó»4Y’øc¼ì UUÅ?‰ãûceyá4"1°½™2Î{öH¬èŠ'ÃóxŒÈßACà„cföpv»ˆOöhI¿—†£Cñ¤¢újåœó…O¯Io("Û ïÍó1æGûx‰uÿæÄ S“=.ß#9)¹ãè;:7u„?µŒÉÞ¬x2P©hˆMp4R¢ÝpÅÞëêõàÒA÷ƒÝ°&cª3«ê *úD4£%3=Éâ¬Ï=wbAf 852$fW2ÄÄ­ !ÉjD5ä1qŒŒ(‘„ÅP7`vŽL¯ã¦a<pU¦ýIÙššÇûøÌA®ƒдí÷û@Î1)…î]ÃÒIÈ«qû,g¾-ä<Â?Pî� ¾Rfó<÷‰¯ªÂÛƒ¬ÿ,Ÿ\‘„›Böù,Ìå«Êy¯ŸV‡ð@0ΰñ Éxx ý–Æäy£M‚_ÐRƒ™Q¬À¯S è:¨Ê, ÇòIÇŽ–PIàqW`DjØûö…vpÖ@D¢ÑÈ;Gln«~…áSrNACÖEÖ3B(ÑW`G8vºCéùÝ$ùEë­õ¤†9k`â¿bImê½w‘CÓ dÿƒ– ÛTsœˆ„eIï€çÆ<N“¡\‚~/[Élû%=€TÎGÿ>ýÏÔEÎüR%(ÄÞoÅÊo£è~ï—<0-c¯±ÖYtѧ¦¦Ü÷œ{•+/õC6#`Yì ÿ Ž–ß¾*£ µÖÖëô«©›ïúŸîû¼ˆ¤_Nãóbw¿Ó)f´C uÃ2wZ¾èÍ¢Èf…Ùã˜×]�_ƒ{BùúgôÏõ“ûý¾Ô <À3=Lca]xXÕ<ìÌtMÞË<%ÚÖ,Ü�=x¤hÌLQh¦¢@LíÃq©\´mÖ-t5°Sf$è×W¦6ngm‰²,Ûúæ­ñ÷bY/ÉNɂ̻ރw=88bàœëýkoþä|Ée«Ýªg%§ÀàŠ à €Ó=Ý¢8|áqŽ™®°^¯§à€ÖÝhé‰À¹ÌúGþ…<Ž•IYx‘i9C!µ?ÏýG¼üLFŽñÞ˾2~ÉxrMâ¾êü„g…A°ææŠjŽŽfY655ÅŠA˜Ì�h£"]8õ0ÝRó€÷aúä‚¡FíðôÀ|eëL®ÿW©©T*.|Ë×¾vw8³aøáCûvµ)«‰ ²"g{>,pÎÂnÓ”£ 46Ì:çÚ¦-kfælôîîÁÍsIœÇ6¶Î9í±OMM›‹²*ãv¬eÎe´ÙY2’ƒHÀh·�dé9¾6™x<ŽO‰YëÓ8Z3/òƉŒÕˆ$¸8÷ÑE¡Ãó4ÊÅ@M¦Øzþš,òø-ÌåBÀ‘á<ŒwˆÔ(øå€(j/ æ`„S{6¬Û º±¢Ûg@Ø{ŸúN7  ð½†äÁã <x ‡œKä’›wº¹ÿÖ¾ý‰îŽxô/¾=.Ž-Êg•ö‡F„qˆÍaæCyêš§^6v™*³ê©ÚéLNNbþ_h¦sI('ò h]šìÚ‹$pûØ éË2Ì °g+cèB²ÐÃRXà! ).(æ½`ž/¦a¢å®{|·ÿ…~¼oln™àiÌù˜ššÂ·@dsî”5+`²5 ë9 â¶-&Q8©Wþ’(Ð.BhÌóÜìÃÑ¡ì”QÊg–2!­/·ˆ6Uëb£OÌ–r±Ââ•2Ûœ§â™YÐÀX†í™éÎ8É0õ5N½¡‡&Õ¯‘DÜ0²Ç”$(¼V9p6j#…lB¡/T«v,eZ­€­kXPÝxH¢.áñ&,cBC $‘ÙÖ·ðµCÄJq@ÛØ ´3àj "i¨Ý™¥ ”OcdDXs÷OBrf¡ÓƒûB*ÀO[H —!€Ü¢Ãuòfl„ºms9¢Ÿ«åê—ÉË‚„³Ã½¡8¥|yÀP{ÇퟶÃa¡a_Ógç\þ¹¼>¶ž¸xbéÒ¥ Ýè&Ÿœ˜Ü°ak"¡=ËÀŽ®iÃdLÌ|hkÝAœb£E‘CLÃ@^šý„FS!XeY¿ß‡>13zyhÙ{_½¶Š¾‰—V«¥ãýú-É%Iöº â@ ¼˜OF傘§d0î¯"ýlX°à!@”½P  !…h)ô­¹yßîáГCùüR–KüqëÜVëÜVúßi4åïÈqRÀV‘Ÿ=öØcáÂ…PäÃãëXçFÇn˜Ì–z¨5ùŸ€šÌþsë­µñ±-lq`¡Ý2hyùƒ|¨‚¹Õ0#b— „)‡�Àx švš•óñ‡ÎA£áÁ¤2ö­Áwiê ï‹A-]„ 5 ീI<ìÌ,G<^f±³æPC` ûŽin¬b’w®º ÈGú?•C¨ YÎÜÙO!Õp<[ .XrÜÁÂ.ã¾#{—ð$/z< =תq[•ó'ú¹Uný©üôSò©]d—›7Ýü©~J~#åXY|½hŸÚži¤ßëâ/ÇõNõÔ/¦ÂX–¤oIë5õíënW€KDʳÊä;‰ßàýúü–;Ìì  ë†5ÍXc+»5-æø°Ã\¬Ï¤ ìŵîLåÄÑ9sIOóÉw’4N÷Øc]vÙåöÛoß´iSQþ·¾üL™†û Y$ð(pðôàMÒhÃÎDC¨¡bÀÐRZ6Ód ýn·«Å º¸<+:„A¬©w­M0ɉ“¸( ·ØÙ{lùÅÒ:™œù:ȯY³h$3ÄH¶ª„š�÷¥ðkl{ʉ)LPoH„cÌ#SRïV‡•Áoœ¶RÝÁ•{–Òûe›mð}°ÅŒ+Br·¯ç@2d:%ƒ„,´£/Ef;›éª3¥Iá™..A†äíÀV1lsט´k„jíq"6ð”b-Ÿãt“9f<, ¯E¤9ñf!ˆÜÛŸmaîÉ#_ŒøiªÄ€ùÜ=‚HÙPTc^ ‹ô<îBŽ÷rãòÌg>Ú.7HX"Kö–½É¢¶ÒFk¶;°~/wOÃô»ûâÍEØqèˆ>øûÁàÛƒòβ:µ’{ER©þ¢ óB|Sl¼TÅjnô1g®ø¿Z£#»dfŽ®æ†Ì(šÛºúÙWMf‹É³´‰2÷õ\ÆBD%s½È*S©¶vbò<×›$Ia ÿd¯œ­:Ä®I.@’†Í(Ž*ø‘ðŒ*0Ž  YcvAYš2kôR*LÒqç\:’Ÿ“¾hÔ¿ýöÛrÈ!“““wÜqÇ–M[Ú—¶{çô’'qÔÄ9×ï÷1<¡á_£‚¾ÚÐÇØëõ”NÍo´ 'lò ÿf}#I’¨ Y«ÕBc øþЙøó¶|w9xÙ õµVÁ?xÝÀÝéZoùàDåŠ1^–*àÒ„G‰5 ml¦›"</,är„Ö5(A`bQÅfSecH˜B¡O†xÜ?¼/N¬±rƒ„É!Ü„#ÛJû”¬•§K…Íy&i4èx®,ì©xƒóÊg7)„Uö¶gcCø$‹²4#ó,ÏÊQŠ™¹#‹|+¢©êÇ]ÈùêWeõj—c}T]n-õErÑõr=V‰ú9J&Éw’ìµYòžá�sqBý:J˜–¾ôÞ»¹¸ËÁ2øÜÀþºÈIGâkãèæ¨5ö-²W•0çG¡Æ+Pa0”ßðÐeÕE00ýqÀ56oZðAy^ƒo;`žø?ãüÙ¹YlV­ZµnÝ:£«ªÊŸ“G?‹XG}®,? Jdy8›0ƒ k 3p]ÈÚûƒ™6¦¶@¹ëÆt-;"GQd"#F´«üÜç>÷”SNY³fÍ%—\rë­·–¾T,€'ë‹?ì0Ï'‚ ÐÑ`eLƒ7èé b¬�’Læ¶Ö¶>Ýrc®vhôwfÛLÍò̈g­év»7nDÇ‘í�0e…ܼa’Ú”Q;}‰@ÛØÿGª÷^EÓ!… 'ãŒÇrEXUUïð^öŒL:"F¼x9XÂÚ\žð ‹N_]$*a0lÇÆñp¿Ï€é@HA¿š©˜lTCHûŽyÏ,27èr¹ Bù ÌgaVРÁ*D/ ׯ\;v±zœª\x¡ŒŽÊÙgË—¿,I"Gõ¨½ún·»Ûn»­\¹ÒZ[HadÚ\à@'#â~ëÄWÅ”è³Qk÷Vÿãý0/¸ë]rM‚ƒ4ŒÙdhžùz7|>�²qßïØÌ»Ç•è¢ÔÄ’´2[¾^÷!ÿ+68àoŒ¯Žo˜ÏšºªõdQ5R¼O¾’0ΨžA@�8­CãWÑn~ð”s½†$õÙð4+ð¸kp”ApG™gË¥#Cš–nΩ©©Á` ".rµÔlSÖ°Oæ–5K˜p*ÀÀŒÞèï+G|næÁà÷¹í1< ï}Ø’'°H©dˆ½hÅ/—[ ª±†y8Y°§³“Y)²Þ·Î>1’Kúú÷È^ ˆŽS•h$zs‘"}wyžç‡åÕÓ«ôž4úqd‚±Öž9¨ö¨Ê7”ÉW––àÊÔdÈ@ rkz‡¦Qc0ˆ-ŸA½CRÈó•,‹§õ®2îØ$Ë�3Œlsfƒ9q>(@ÐPNæŒæÐtˆâ¶Yc¹ò,÷™_s9e)—_.££ròÉÇrÖYrî¹2:*ôhaE‹•ÑI™•QÅ76oÞ\×u`FŒ Ûþ~{oR?{ãw=h×ÑÑÑ{î¹gbåD½®6w™øö8º&â. ¨ý( ¸Øg¯CF'¸…8Ë cÌ—”å'K1"…´_ٖȤ@yEÿ�åDýƒþèÇàà ؇yýø·¬ƒl®®ëS?›Š®’‹’ªªŠýŠÁ'ÉW’øžXì,½jì%48ûôÌ…¢%ÐjÞüúˆ¸ÛÌ*<FLo .Á—¼8Íg8¾™ë~©[¼³H>—\wÝu«W¯Þ°aÃÊ•+ËnYœRŒœ3RúÙ1øm£†1½6E1t ©V4ÐÞ€1öHQ|.ÏÏ6fj¶< òVˆ€!”2Êi„Ðp;÷ÄJñ�� �IDAT6ôÛAðÞONN6X�Â7I»ð¤AÕ®²‹2W¸îûºÞ{Ÿøþ/ûéÓöEmß÷ìÍ wåsf*X6æQ†:͉­Õacß ! Iš„’ß$~ƒ¯ßTûÔ›lfgÁåÏ\] š[�‡�ªÛí¢æÂot¨:¡öY¤]ÃúN•¶�ž*¿2Œ%ñ‚aJ‘,,+ðòÒR_.µÐf»RFéõóõ7G½œäß<—3ÏþÍè¨\pœu–”¥zè£ár¸óä¼÷È{.” 5älذÁ9gGlï­½î ºQYkKW¾È÷Ïýîþö×ÜnŒ1b¢oFÕÊÊZ[ÕUbÔLøa°x®©3²$¸û1Uføç?—ò­¥ÝbGŽqΕRö¿Ýw·»öÅíh}¾“s®ÓéLLL°;!„œ4üFèl¬Âp~‹¢Èmv Ž[08r0øâ@ŒØå¶sd§¡Ã\ˆŽ`ëçàá@¾l8+~Du£Ò”îVmŽÞ-ÜzŇ`ü‚#7g‘ìÅq¦a}+6]›ù1ùº_¯Ût˦^¯×߯Ÿì›˜»MØ:뢂Ér ê—êJà‰ !—†^õSDÎòþ­Ö»Ëò¢(Z;Í åà «ž4ä«a«Ì‡ Ü\þ2»ÑQc5# ½C‘ìJcLõ™*úX”.K]äê¢öµoÑ.ÿ¶ÌŽËì¿ÎxO`Šk¢ã¸GIF=n°ª*³©ÿ²ž÷–y¦evÛm·C9dýúõ‹/.ï*Íã_íÓKS0ÙF%,Å"fÅáEç!„y÷ÎÛ½½ûªU«²,c¡O|«ºÍ}zÈŠˆZ­â…Ÿ�h˜‘ÝŒ˜’§k >ª {Œ~#ohp@ m§Ñqûí·Ÿœœ|k!È}÷ɳžÕü•;îx”„ÙEvÙAvø¨|ô 9Cÿ&^îðî›nFB…—gHñüÂä¦û²®.‚ì-™ÙßøÚÇËc$Ñ�I‘]b¶™q-P`µ‹«N윶ƒe;8süS2¶rlÁ® ªªÚ´i“‰/Î,Ê#Êø{1ç_ -^„.œ8lŒì²Q–=,É•ä‡ý§kÜÈŽ c[2㌓…YÂ< ÝiI’ø¿ôõ_Ö.u6¶eYæOÍã~ýÓŒÎ#nüò¡ŒLŸ{ ÐÄò²Ô'1”B|w'qñÜ¢xZÑ«{U]ÙØYÑýX×Fts ^�‚0l‹ C‹+Ë2”\D‚EÑþyþâÎëtÖ‰üÀ˜×Å×[­‡¦,eëçCçRiŒû4†BRx|P¢uÏìvÌ3!ÑÆ:ÖO¯ä~q›œˆt:4M•æn þh/Œëõ5gZ Ýi·ÛÌFù‹Â”ì(ŠjS‹* ,Z´èØc]¶lÙÒ¥K'''u@ƒK=´ú…¼¯d¶óx8Ì÷î×vxS‡M­¶««ó+\êp IÔA‘S(ˆ#ð4ÀU™í«Äòk˜:oØ_aú•=ã™ÈŠÇÄ»¸(Š-[¶46fNÕ¬ëzbb‚½û!ÇZ9çùÒ—$Žå9Ïþåg?+ Ê)§<z®xWÙõµòÚÛä¶wÊ;Wì·¢ÿí~ò›$¾-–‹uÓ)ÌJc3kî3ñ÷ã9¯ SœÏž–ÙeÖ8ú­ c+VªÐÇÉ;~Ð<×ÿktttpä@–I´:Úo¿ýžÿü燮ºêªÛn»ÍüÌ”§—åu¥<4̃fdsÛ!h˜7æÚ€°si­Î–0 ,YV¼G| ‡—Uð€=À è›…ƒB8:´ïhÛkl⓺®³§gõîuñwEç .› ¢ˆàÔ[µ±1]‹ÌP¸¦Õ@¦f/ŽãÅqþ—¹16ØÖm­zu­F zpÓ<(†OU(SoJoS ·€Ô$Š¢=BxiQ\Òj­ ADn4fàÜ{z½¿ítìƒÐÜèˆ�{Aݦ£Õ›Þ#,Ux–MvÅFHãwÍÆK\Ä˸ƒK»Êºî Ÿðìg?;˲뮻nãÆæ×¦zcEfƒasXö[B¨c„J¿K‹IsOñuùòåßÿþ÷×­[·yófÐLiS}&†•Xt¦§òç¡<¦Œn‰âkcÓ7ÞûðŒ°eÑŽ>ñ/³•�ÌyÙj<4ü´x¶FÛ0` òl86&‹ÌVuCÆÀ°&mêbp•TQ¨–³{9 È[ß*ùˆŒŒÈÊ×¾& ÊË_þh»èE²h‘,:L»aå ¯xÛ+âÉØæ¶2ÕLóí°:Ìáð0xã`ôM£ÞûàCÿ¾YeÌ:S?§v×:†Jq”ã0¬Ñívy�¢ßï³f"σl§,é%OHžp 'sÌ1!„U«V-_¾<_›W;V¾ãuÜû[š3Jìgn>§?øµÆ‰ºDƒ¿€Š ‡)"GP¨ùŽ»e/¾Ü£ SÁ\eFç.X°`bb¢¾©–ÕR|´0#ÆLÎ\'7–ze8 t?çyÞjµô(épðéÇ\Mô_Ç©*àÌŽé€á h—ažâ†v*pŠ}hjê}­Ö}!$Ó½®ßóÅ$ùâ`pV·«gS·ÛÕnÚÅ q ÁX¿JÜ×Q]Uù»ópPâ‰ë«ãMq¨fÐåWC8¹!ˆ*DkŽ ÁZ»Ç{yä‘·Þz«€a.†vÐ[˜AӨȵJÓÝÁ¼påëºNV%åueõÚ*|-¬ZµjÆ Y–EáŸìÃÓCü¡¸ª+¦ÆÁ�ÚÃo|½]]ž]VQù}ò/‰¹ÑH6m3‹ «Bv|fçÙz¼fô¢é\»s íb®5êE`bÌÀmj6£ O5K#-`xÃILAjÅÖ|š·ý¸£ˆH·+çŸ/gŸ-·Ý&Æ<ªê›ÆÏBYø„â ÑC‘j#2ÍLºâcßzoKFeòK“º’ºgvýC>WDšRÉ´æ#ö*3>R!´CÑÚeMIýŸyž—eª0 î½÷Þ=÷Ü3˲5kÖäy®£ì±Ä\ãiŠB³˜v»B˜ššDé_VMfEèOÉgÔ 5 ó¦ã†)dôë¨ÞRCÉ)›H–aˆ Ûó%õöuqr1úŠÑÎHçðÃ?üðÃ×®]ûóŸÿ|ÅŠþ¾ÿÆ~ô©€€¾•›ƒ%6pø¨â^ØÉÛ^Ÿ‰Æ'°€p `ΩÁfFŽÉ¨}CC#P¥qB½'ŠNÏó‹ÓtÍôß<͘3òüÍŽ›¶Ç´)ê*™6#‹’“ªÆ˜:®‹×åÑeûÓí葵¶xy‘}>«¿Z§ÿ‘¢uÇ©)œ~ævyÄÜoÌŸ7ß­X±âòË/ïõz›7o6Æø=¼YoLßèÚÓ÷%"ý~Ÿ¹‘`ÌéårÌiÐÎ9SY.þ0_[ùùa9Ü›}Œ,•z¢æá'æ¯ã@™òä²<®lÿS;=?í£ÝåæÉ·“Ý~»[¯×Ûºu«ÙdâoÆÙßfÉy h“¬ýÌ€3CyúÕ˜¼á*+PÊàù<XÕA•‡åDa¹ËY¸ÐjXÉF#Ÿê¥r8„ÅâãWIú‚ ä²ËäÔSåWÏ3_, ïÆ{/ãÒþ›6wË­±u]û³‚×ò<ðˆw µ~Ž’š°±ëÂâàŸç{£½«¯¾Zeuî¹çž²,ëCj»ÂÚÍ6Hh°zX[Õô\kd‘ íBV$deûFÃÜZ^ЧÎ+†òi¥Yk’o' µl -Ú²Bž„j˜ £"{î¹çI't衇>ðÀ[·nݲeËædsiJ ì(œy·<£Ï–‡g‘F0ôÇ ÐÏx1pš¬™!€G0ÉÄÜ R4ô¬Bkâø»ÖžR–—x¿!Žòþ¯Êò#i Jël6Ô�Ü´šÔŒgè¨Ñt¬®Ž©FOU)ô‚û–ë|³3õ‹©äšdæ×¦Ûuh!€¬ÏxxöÃL(„4MãŸÅƒaÇ`–›ßýîwPv¨_TÛÅÖ¯ñ>ö�ºÝ®Fô†&ï;ÖUãàÍL˺®ã_ÅeZºÃ\ù´Òo­ >Ø 6þçØEŽa»XñÁãºnòe“#/?â˜øªØýÀå¿Êwý»]zè!•—k,£Ó\aÒ“'4ÙÁ“Ëñ†–ˆ— ýP\6è VF°ÙsK£‘Ráy¤ƒ<3¤ŸÓn·¡“ýx 9Qôè7\“²…”ˆ˜%F‘úYut}qþ¢(êko¼»Áñq€µŽ<—»)ÀaŸ�fP¬›myZYn_®¿}ýøøxA•uü!Þ®´v³UònC*TiK€ì8“Eæ5FÈ™—bqƒkÀ3ÏÕ1•;À%Kó“iNÑQFö–ê •N¿#7‡ÐS#g “K\!EQJ£ÐÆûÐÑ 7-ô"çÀ‰0ÏgƒTœtš¿ƒzÔPiã¹9¤ØèóJä°ÌààÞø\‡Ø+`0þŽ(ª«êÜ,ûl¿8Ï¿Új=4-ć … L3_@ˆh£BEŒ´Ö–ï.»t{ÑÞú|+[Þþ|[—dzÊrAW·Z@}‘Gs»KïWAK¤öUU¹tÅÙ…ßä“÷'!Ó2ƒo ìm6º"òâñl§¦¦Ƭá„|‹‰PøÇ›Å»N‘º_:¤w±ùµÄSqefd Põ2jR#û`–~(Õ�™¸$ÈЈÏ}Ä-9i‰;w(íDZ·Š 8õÓ”>®†ªØD ô2ÐOˆ5ã™+/Óê‚ìæŽá->x¶l#°ô[xºO¦…ìph<¾HÒͼuî¬Ø ë·úlç,}BªÔd©Öõîµ™2õºÚD™WÑ<Q4ÐHÙsŸ˜ô=i~ažWyùÒZëvr½K{ÑO¢äk ·¸IÃe8js>‹™tÛ`7ñŠRS> ¥#é`ÏA½º6?2­vKÓ«p}È'óâU…‰Œôf|.bç7Ä 1aCH¿•N¾irõWVó›ß¼å–[V¯^}óÍ7OMe/ÌÚç´qúã”׃OgG†eÖ´¼40wœ•ÜzAJÈÖœhDñ±‚¥Óé(þÆš‰�Íp¸ ßËŽAHxq:4:ºEQÜáÜÚíO÷ûoÁ±k ¹ ‹— AˆbH+½€êé•y»Á8­¾Ak­_ì뇂­‹¼ ª6“ů“$L ±Y\ýÄÚ%.˜P¯«~†ð“»’øqµÕ»¶'"’ËÈëFÂT¨·Ö°àÞ!S³Pó\ ×UHÃQýcd8„_ ¹6`a úL�{sÕ!UúŽÔïœÛ!ÙaìʱuïX}227˜ÍoÚÜžjcªUõò*}Sª5 k“삾Ò2 üëKo·Ûûì³OQË–-Ã]£Ë{P•“ô–a ÎSz¼Âõ65ËáºMzmÜ{Ó¦,$|X1k[È™óóàƒ2>.ûí÷¿}õpdá’exc_‰üÙ>ÿd®.îê„Ê.³é§ÓÒ–¬3Ï0ÝÜ �n&@×Å +`AQÉ@ìëlµW•ýCf­•BÚG¶‡We…O@œ>ìoóT;IX²˜ÓDÂ…ÀrpùÕÔõÓëö[Ûy#Ž8blllÅŠ÷Þ{ïä“ùм<¡L¾•p×Tfkò ÉT’ªà—{¿¯Ÿ8zâú_^×]w ƒ©§L…=ƒ»ÃÙ¾ fVr§7 ý|íë‘Ä’ØLZåáPÔ8ž²,ctQµ¹ä"¶1Ç™»†g ± Z0ÚB˜ä¾ÑÖ$9µÝvTBaœ oغ`ø b\¸rD‹(ŠzÒCëžM‰œsµÔ!„CŠâoDÞÛí†Þ7˜^ïIÂ%Q}@m÷²Õ)•}íëò{e{mÛýʱýOA6Iõóªó_CïQëfñò…¬çð(´8`× Ð·˜ßÏÚ,™Ê¤ú–˜¿F/E}§Û-Øn°yðà“4'˜pÓôÈö3|´Wäo÷¦gÄÊÜÁN_X‘h,’|0Ë2$(‡ÄyúdÌpa±TÀ$`µ`‰ê!�¯,Ý úijσµŠZêq*xóþLNÊE‰1ròɲï¾ÿÛ½Î%¹%`Œi_Ø®“º>§öÁ{ïÛooû­>˜ ÇŸú�+&¡+ˆù�04´àØBþ+$8\wKë- ŸBÌy ŒœºÑŸÀl9® : ;FóÔžL+AáªêºVy˜±±±ç=ïyûí·ß’%K.½ôÒ~¿oŒQ×gM¢!Q ß*D;ô?†wq« íàð“OŸDñ¹·6º ’H¸d ^H›€z 1Pl8ÿUF;¬« – h$@¦ÿ±°J"l~f%4 `´LD‹‹lðž±ø“,Y&�²H«žÒ¿I®HÂÉÁ\a@¯ÎÞ¾¤pWº£òüYÆœÛnë'8Žß^–ºþf„’úyu]×;½e§í·Û¾ßï¯=nmvhæºÎ\ePÀñKS÷¬r¢ 7ÀôÂæ*Ã÷V¦ /–Yc5qfos^¯p“u…—eé.uù«òÖ7[u]ßwß}rŸDEÕQUýÌÚïéË–¦2õd26Ö4ø 8rØòŒ§ä-[¶ ËaxóÂ<-Ä[õ1ë¶ yžê‚PëO<"< ˜dcQ5Œí·…œÙ?ïx‡œq†ŒŽÊg>#Ÿø„ÌŸÿ¿Šª lc¢j†WÓóÑ'#t¿{uoQ³l®l„‚I‚<KQfÎdÕQ†%‡£àA΋OÕÆ¸~ÃØC7(qÀú°Æ”Lá6´WÚÂ`0X·nÝ¢E‹(ƒc)ø] –bVG.à‘Å“óî×.¹!ÉÏ¥%ÚÇJ'ÒÒ—�å@èÀÃÄmi @°8)ܦñ¢“$Q™/@ hÈs m(ʰ[Œ¢+L€Æ‰ƒ‡Y–¥<‚�†^–>@è!á7Qìâ¤`P'æj9â¶ØžøÔDôˆ½­µÙñÙsŽLžá«¯´ÛïwÚi'kí<pqÜë=_äßUYü©Þn±ó.›·ËÞ»|ðÁ6lHþ3¹wþ½ù«ó䪰Œ.`¶Ò© 7øBeë Äi„"lpÚBMq$~âzW}§àéÎúÖì‹3ì]áWì·íL·õ·.½9ÿåxûmï}|{ì6:og:O hžAæ O)€�îk}\<……agžÜäà@ LW\`IÀ\:圞6ÒÇÿ­FÎ䤜¾œwÞŸ ä¸wÞù´ÓN+ËrÙ²eO}êSÿ —·½MÞþvyÊSdûíåˆ#äMo’£Ž’n÷ãÒîÞx÷÷ñ}©DŠac… ;"Ïm>cÝp¯žEnXê‘0ÆJ¨”®X¼Ñud;5œ>ìFÅsBÌéÄßèwa’C¦… ‡Ùzb®ÁÏó~ÄGýs»ÙÖ ërŸ²º±Z³fÍâÅ‹õ«_­]»6; «Ž¨¢ #œž¤PAÖ3ZeH²s»kÆöã>ãVºtuj3ËœQž[j4óÙ•§aû F<B¡WQ8ôÌщ=ÁÃnNn×!eÍé¹®É,ŸÊ£EÌtâyF6Âëãw ÀÄ9Wn-]ßõ¾Ò‹·Æ6·f¾)ÞPdŸÈF^7²aÒ=#„Td…µ{í½÷ØØØÔÔÔSòü º¾<Ijk£?òãóùÿ4]÷xÍk^sÒI'tÐA!„å×/Ïæaïàîp >Œe±jµ,êW ³KDA>ÔŒ6â :HkXk™•Í3@úô4& _YmâuñÔ¥Sa*ȸÔ#uýêzðéAûŒvzSÝIo8nµóÎ;k«qKÈ߬áù&ÓþlyŽûå"Œ]Y—¥Ñ­ÑPÊ9±º²\PÃX à±ÚÁû’2rνúÕ¯Þu×]ÿ˜'é† ræ™rüñrÅrðÁBÚÛÄÚ (ŠåË—_}õÕ¼*çÁåK_’SO•}öþÍØ˜\x¡œwžœyæ·¯³\–/‘%?–¯Ü}eöñÌÝàì [ÿ¤æ¨Àh ,àZBšö<#|†Í`àh€T𠘯œ7i.¬:XÀë°Ê. y‘±Ø0rg.}�s±¬ˆ1¦þ‹ºÚ£*ÿª|ò½ÄÞoÝ-Î#µ¸Nž.ŋеÿ¾vÍš5!„âˆÂ/òÑÒÈä&¸YÊí¬+Œ-„ìÍ>Î!%ËL¥E�# iš²¹¯Ð¨öÿkï»ã¬¬®µ÷[O™¤ƒˆˆbEìc¯` QoÔD1I¼_®ob¼1š\‰ã{ôšÄ‚%ÖD – *¢¢"‚Š €Ò{›rÊÛ÷÷Ç:óÌ3ïx“ûý.f€¼û8 ç¼eïUžõ¬g1Ù‰ kis$ËSõ�»qp :¶²C¢Ã½V)¾,+1³RV:H,¾gÀ iÏ– ÃÐP†;ÙUÏ©êåÕøŒØ²­üÓùº‘uQùJÝY,^^.'IòÖ¢E†aáy#}ÿuu†aXJ®a孞އrȨQ£úöíëûþqÇ7}út¯èU㪓sØþ")}N\8Z¦¤!L£¤DÌä¦+�nÜEÀjr˜‹¯HB*[ઠ· Ùdí÷_³ê§Öÿ7†aä&åòÃóZkÓ©…zÕj5—Ë ¡àPs¼!UªdéhìRðSäEvîÁ;$X˜Rêºðßò¨å¦$íãQU|4».+ºÄ8ãßjkáBu×]êŽ;T¿~ªTRãÆ©óÏWÅâö�¬•ËJ)U_Ÿ&[wë¦6mÚŠW¼B­xX=œWùÔ Ÿ.ütÔ˜QÉi‰q€ô rçÐá…â§jÓ­ár}JYy«Œhq>Î)7~s/•//WÊ,ëòä%ùW}˜BoÙ¬sÛ|82 ­VþÜ|­ýó’ Ú'R¶R3•mÛù7óûÕÆj­Í·Œå†ógG›ÃÊPëÆõÈÑÅøH>lm™eÀá?*0"˜“j2àé’ 9þÀó<¼ d±(!°´0g*©h“Kp†Å·á˜ (máL[`¶$ÆÁ¡ÈÄX¼<áðÀr|~mÜòom<¥X·w›_ï8—„a÷ÖÖ&­Žã_µÉ™¦©C$IssóÊ•+W­ZU,›šš,X°iÓ¦j¥DZ Û‡4ËÓàW†hI¼‹ôçr©¢qà)ZGJü.&2-]úÜ—ƒ›Ep7E‘û×þ]M"6NÚ[ddV*•eË–É+à i7|ª° 4×”,ÚŠm,›Ë`2h|R@ËFúˆZ–€â r¬nÀŠãHz@jMOý_ÇW^¨úõSJ©³ÎRO?­î¸C]qÅçr¶^1jÈ5v¬ºóÎæ²ËÔYg©cŽÙŠW¼Z­Þ¤6]¡®è£úÔ¸FÏ)÷n7<'æƒñõ¨ñÈÂRh r°kR,y[@„˜Ö·è<®œµÎPŸ`U.A´ap€pJ\ ±Xx|èLw¬,\ƒ{‡k®4ãƒc¸gŠãÞꪩÊ|ÝÌOÏçïÍÛÛª­­ªþІ¤!Úb”€9 Iÿ£ùÒ‡(ÿe­ÖuÇcï  5�ǥ΄žpCD¹O �ƒf(f¤ö€$»©záç s„³T‚…pl=0Ó>ìn{@ðPýç8=ÂpXÞcÛ¥ U‹8Ž£EQô~Ô|Róüùó~øá'žxâüã„ Vׯ®ì\Q“ÍFÓ€ñbzf k‚e‡5ÏårˆäØg°hF§§šš1€€)…¬ñ D—qTù¨Œ‚@H_¸50#X;Gðg–ºa¯ÓVãš+_?;TûÜá‚‘ AX!µ÷ðr¹'§HÆÉb"2ªj«¹œrYÝpƒ3Fí»oû¿þuuè¡êª«¶úÀ{¨›nR矯~û[•Ë©ŸýL]u•<x+~C¬â+ÔÏ«çñVvÚi§ tIÛ·ØÞ•žûkW2P.øs€#c(¹G]´X¸{ HˆLd€1¦ÿÊæHBWIMä[äyª.ô˜a@9”N‰î¤FËÀ„qBÞiž±Öpg¹®+kR+O9Þuž>L«™íz0Îk@!Ãi.ú�‰«Y)Å*®²8˜ý¬æ€Ë–QÓÌ d³Ë£®€¼aR$Â&¡ª£¿G~’Ëår¹ô.aY¤@,‚<mI¤`aá×Å–‰¦5ŒLN㢠üÒˆÄÀ”ËÍŠ‡»Y³SF’ J¢$Jt’,é0l› Ø]UÃx¨PH¢¨Ü6¦¨F|(Ö*+Ù-Ù¼`ó˯¼<wîÜ–––¹å=ÊÊWÆêÚ°QùXÑ1b¾> Xv–`_ÈÅp®…Hâ -yÂõõõ¦iJ0ùàÀRÕ2ì@ð€°Uðé‹s—Œ4N pf‚ÙÁ yÜŸË4"Q”' Å!®µÈ-#ƒÀÀ–=ÀI9gj<VGw:uJðµŠEõ­o©?ÿY]zi{¹}Ý:õàƒjܸ퇱V_¯þðuíµª{wuÑE[×ß(¥´ÒU)ªb[µh§aÆ}ðÁAž¡‹šÇ–!ºÅr™@ d‹ƒIÉŒh®�–é<º˜›Ù©ˆàÜYì +)±`­ÛÖ`‘M ÀmxÚ mÛfÞTZ%AR__?dÈ7®_¿Þ4M#4”»Rñj�� �IDAT¥‚$pTûÓHÍVþÂíâ "ÖE‡Ï™k98$òˆÀÃäJ@ÒLÅ9Ä p”ˆ|߇•ävwpÊyÚB]U€ç´7 ›¦ óáañ+Ž…a˜¸½ƒƒ¹B.ü"ŒP¤?,¬µŽŽˆâÁqtJd(C+mM²Ô e½c!š\ð.yþå0”¹^ØuµÑs“ïÛ^ùåðÙ°”+…aèç©ÍÊú¹e¸íÑ©ãýСq§­¸ÅD›Tg+·ˆ›$s-«JÓÊå|544‹Å¥K—b‘i¤©I6gfú‰ LHK15¸ÌÆJƒWSG°�ºÅ—ÍǽŸÈf8¨Å9ªõ†SÔª Àîä ä•0NX£˜VÇÍà[±ÅD¡Z[Õ½÷ª .PuujÁuï½µ©ÐÛIºGõêõëÕ!‡|Ñ|» Ö¯__Àl˜QÒÎ&d G8)"�#õLã ŽÍ@ÙÐ/€uã!ƒ|~ð©I\< ØhFŠ`ƒjiç!Œª3LGä[îà‘\¨B•õJÆÖ²o˜YRIÀóSb5°�¸.5J0#ÏÜÅ( ÜÏf °4—ËåóyÖ`ö O]OŒŸû'N¡€o ½TZkï«^p` µvgºæ_;Ðâq…0…ÞÑžy‚il1ò×çñ¡ÖÚ¿ÆÇÅŽí8o8¬#û\\5è-h †s¢È}Ôuqü‹}Ïñ´Ö… j­’ÆgîôDІ!ÔÞu„â¸ê(®!p>ŸÇÔ ­õI¾H™$wärŠfg˜¦¹yóæM›6ñˆ±·@ƒ®Lè„‚éÇI*Ëpð)FÅç‘[¶Ñ‡Á/ȼ¡˜‡'È܈ÿ£H4�$EäÄs ÿ2,,5Ê=EsÝúêgœ¡&NT·Ý¦¾ñ õÄꢋTïÞ_¨Ñþb‹öÜsëÖoÚS{eý@ýàNugY^¹re’$:§ƒoÖ8 e÷ÕNdñ\Õg&.÷èñ˜q«%;ilÓä@;9fH¤ uų;SçA%LAj\=>Ž&>­µõº÷ˆý}üæææ?üpÕªUâuª'TÕre,è`ya0+ °H\6pjW\6nŸËW89àŽüdù�X¸>–\Ë(œ‰ÿÁçÞ&¡Ý«W/¹}ÆŽx?@gþž±M”—! `ŠRˆv¡6E‘ÞW—&–’“Ük¹Ük95TUž­»È›A+�¬gg™óÍèÈÈûwÏxɰ_µ~Ö-ŽŠéÀ "ÇSüÑÅRèy»ÿ¯|þ¿òj­âi:ðâaÛÂü=`§œkªŽÚågÚXXqÇI2βæÅñåÕªlÍ<Ïæ ÌË€må^¸ FÅYÁ6•ñhAlfA5±“åLat ÷6 «€CÊ8,r#èÄJ ùf ¿œ\l•Ô 9)L€­*E))B3cÞô i=ã uÌ1êæ›ÕØ±_tó¾Úî4Ö e¨|H=´H-ÚMíV;{ý•ÕÏ2r†»Üµl‹ Ð$G†ÁSå¯hc«‰e, О 7‡f^Ž(Š7ø"æ½(RÉÌÍåG&8p WMp`êËõ^Õ ‡ºIëUZz¢Á‘¹—i¬3ÌR{'i>ÚDRŠ>ÈîáíÄΊà’$ðÚ[s CÐÎ’›4ƒ¿ P ·‹vns ý Š:ÜÃ[£ôTfosÍ k6ÜÜÒÚâÜéèéÚ\Ú.¹'&ïT ?€òñÊÄåËÇÊùgö*wBÈpŒÒM¥º1uFÕP¡2 #|+ÌÝk~ª¹Û¿tKÑÞdsúÇú‰›$g&ùòæ Ó\Ó4µ¡­iVé‚’¢o¿j3ë{×_(@)”ÍÉÑ€¼&Çq„ã—RI@Û&Ü�´X^9à:Ë_ù¾¸R§zÞÕ¹\dYS'§õƒà~Çñ|Ÿ‘(¦•³Áe@õ†ò®Äqf€‹YŽâD厄q‡2*>Á Àn@àÐcÄŒè¡!:‘ó Œ´³t“ì¹,׿E*ÏÔAù·(XÂÉ}Q²ž#F¨£Žú‚(·o—£”:Hôõ•_ª_WÃ×õZž&%~/?ÿoya”ò›fšP*½HY.Üñ¾TÏh>(8Àh7CG$h;áÑîQcÖoM‘2ŸºÚ¸Å. ‚‘AüFlFb%þ(ß~Ûvþìˆ >ÄMÆBô-(92< cíóÐH2Dv¿ïûP*Dԉ딇ƒ‰ô @ãL‚ËDZ-ô%YpØ&šÛåó‡Á«ðÜ0wHnì+crÔĉß:ò­ÍÃ7[[êÍö¡2œ*‰Ñä²ý=‚Pñ¸ÈŽíé¶U²„Çq%f`Z3¬ð„Мjrù½fõ Nuߪ±ÔÐëµ¹}úô‘™åÚ×ÊPñ‰qafÁ‰dHXˆkËpÀ(Vc $P FAQíOÊ‘ ÄØ±²'‹ãS¢èÊB Ð$Ãøzý«Ö÷FH=@ØÃ,ÎÏ,Ño6MSF9p<ßçþblcîfô ]nÈž¡ç„†eCOŠ#KPb™­ʃØ}8r&!`£HGŽý™ì†ñ1Þmï4¤PrƒL8ÚÚ±¼ññ7j;U’¥FR£Rmp6D}£Âãó3Ò5á ‘Ó@q•s‹š*%©gÂp‹°˜¢éà’J7œYtáNRœf.ô¥&òrí©úÌÜg–÷c#³Nñ©ði¦iænÌ%Ý“ø;±iš‰J ß/èP³b#°ü¯è‘Èn–p˜›(AéfNsŠDâ8©yнc)œF¦‡œÆCt„ò¼¬jµ ïŽÐÕqœ3J¥ÞÕj¯“ úýËøùêW¿ºûî»—ËåèÅhîš¹K~¹¤áͼšvÍ’a:øV ”R›UýÕ³€\,ÙÔ`cؼ/ïJ/|>4Ɔ†Þ½{—Ëå 6h­ïi¯îµ:ÎÿjL'#Žþ%*Ž-ÚM¶r”Lã®)†éÿØ/<Rp›\îÇõBÖ…ú'ë%w¶§ÜXƒÿ2E &žµ—R³ð@Ðwécš[HáP>ªY©AQdX–ê(¼$ŽBé)éEiµð!…v°ë˜{ͯŒk$ò6!ÀÊ“àŸ0 Š#QÖT„¢9€;f‘ð‰æÞ(bvpª%€Yy<wÄ2 o§k;¾ïªïî½zïûn¿/¶bmÖÚ¯$NKgAÂV"TDð‹#ÈÍŠÔ[cçAñ—k?\‚†o+±6Ï5‘è©R© ¢ ^e¬ÈéyÊ(HyÓØb¸wÖÚ-ã$†ÑaA'@)…GE#&r�ªNÑd Ü#'`ºá�ûpû'ÆJ2,‰ê?pN+—»)õÈ€Ž<cùo^:²×7O?ðÀëêêFŒÇñ–g¶4¿Þ\ýNÕ}ÔOL)Uz¤dm°Ü§Ý$I’’æ ÍõÕçžÉ )OIÞ*ÉbåwÒÒ21á°Ã5jÔ;ï¼3yòdLï†<+”Rj–rrP¢+ Ý»w_¿~}tD¤eÍ´ªÕjP äXÂ\6ŠXPr»É/ è™<)‰ä ´Tòù<>F£31!Bk=ѲNŽãŸûþMõõòkÇEÑAZß—ÏÇ–e¶¹ˆárZƒ)5ˆBªÕ*êùØŸàž¥ÏP—Ÿ §AãJqÈÎåù ‚¢ Ƨ¢SÄnD·“çÖÀ È_ jÍ}Lj Ä¯Æöf$ž¼l¹ÒŸKº¨•RÖeVá“«™ËéÊ…÷ À¡÷ñqs€œ[1”˜©¥”’9iÀ¬Ñ8‚v¤<Dg!s»;òbµUmú7ˆŒ0¤€Ñ™–Á ÂØen/ÏýD®ÈÖ6Åç'E3ÃUÆ‘ï^X[8½b¤ ψ X,‚ ·ÇO�Í@ ½Š‹ýÜPN:$ä)år9Ç_ªTörÝgÞcpÙ§u»ìƒa{}úiÜØhšf¿~ý¾ò•¯Ô××¯ŽŸeÏêûV_a›¦¹ö÷k{]ÓËÚ`)O)¥*ÕJnZλÌ31Ý7]t Þ„¦æÅÁF@€ÄZaE»Dj‹Ú¼yó‡~¸lÙ²Œ¹›¡–+Œ×c¿nG¶=ÇŽŠ‘µ»e¯°W®\¹zõêhp޵֯£ZªåÚœ7a‹pÕZžÔ©YBê×pŠ µãUr·r’$­­­²1 o h0”-š$É+¶­¢èßK¥ûr¹âxT]—ÏûZ«6ê“ôÄ\‚æÇ„rf?2»O,u/ßßlšºcSbÖxMÆ {ðä:E@°"! �-V›—sŽÅrò¬óËÐsÐvÆ”K”‘<Ïs{¹ÁÅAå+•ºsêTY)¥¼¼JŸJÝOêÂåaærº”M@Êø¡«ÔÑq<•ˆ¡ `¡_ 1TÖøC—%UÂa©vŽ€R…PĘ©¢K\ÃÄ3â à‚Õ<!£¢:*¦$¥`§:Êls•Й|‘´§0Û%ÈéíÞ½{†µ£õ’õ1SÁfHƒµ@àwóà�|gžk­³ÕqÀ%éyƒ«ÕûvÙ¥—|‹R›¾þõo¼Q÷—¿ÄcưÒ~lÄbµ•RÁ~¹Â´[lå+Ã4¤i4©&ö<ÛÛ×Ë¿g6*#~ *¦œ±Rªø¯ÅÒ‹¥Ê—* .\µjÚiKw•Š'ùõÄãØ}Э<Z)©½UͪÖ::>2?6m×ÖOêB¥ úܬ¹bô¥äÌSs`AÓJE©éA<s>Œ!Sè%‹º6bˆ8޵R¯8NC}7úk}U.§;~v•Q,²�͸3†E÷N’1Að©eý©-?€íCšçßp³0N(*²-„éàñƒH…‘ŸÁ]èÏÀCª<Ì?‘4T^´DKòP¢Ä6®E_ŠLϬ;±½¸’ÿa>Ù'i½ª5w~n{Ÿ jnï.mÀ/‚Ã’ävåê+·° “"¡$–3â™»Öè× Øä.zŽËØâKPÉcâ$’ãSÌ¥dTB£—Z~A>AÑH¦‡ñµá`K¬ ûÅ ©þ„Ãò ù|~=öèÑ£Gªyð#få2 Õd¶Ô\ÝIÉ Åz „fß÷忞ç‰Û+—ËN¥Ò¤u¹\Þ¸qãÒK«ÏVkylƒïG›7Ëå¹sç>ýòÓïØïƒ 6”Ë妦¦'l´¦Zñ–X)µë®»rÈ!õõõ¾ï[OYÁ—ƒÐ `¢(ªJ\ECõ»öô 37)Wý¿Uï@¯¥¥¥T*GÞo<÷IllE:ÿ�RrçŒ-FõÒjØ=Lz%u7ÖÅâ(ŒÌO:$ ¬îÌ5–ÂDbÊ@â¦üq1Øn€šÙÓCT 91ÐE¦N(¥ž±í•–uS]® E¯ ëÃä†ÜÚŒÇÇñnI2: uœHëÿS©�n…p8H¤<q£[ò›ËáMÞ¹e<9רùãw.wÁ˜tž‡’jà åU ¼¿ëöw“û [>„VõZm.2lu×k£É¶øiµ:Këws¹ó}¿Eo¹.Ð'40²x%O^bðm=™AôÍx.‹kq"Â�4÷-#9` ^.9¢€þ1×á;wþ3ŒOÍÅ^ÇK˜Ï3Êäd‚`§¸nݺææf†5PT�P‹#¿#%˜B8ÞèµæÉÖ©™,¯À¸|Û„úúÓššÎmn~8ITIÅoÆæQúø½ãÊW_Ý}ãÆ3f¼ôÒK‹W-nÜÜcFXÇ�7Àp:tèa‡¶|ùò7ær¹ªUµmÛÉ;ÒÁòV¨EƒpÏ5-Ã0t¬Ýû\û�;T¯«j¥wçYǘm(³Ãø÷š|ÑIV'ÆûF864 #ånËY+-sµé'>^OP$‹+aZâKÁJÐ(Ju“ W†uƒHÇqYt{©]îp‚e¹$É H*¥ÌÏc¿Y¿Ãa:ZÿÂón¬«[bKâø›IrAÞŸÏ«¶ùÖè¤Æ–N+_„’l9y†l1PÓE3:Æ0 »!}äPRPPÎÝ¡³�dž)s\Yº>IÝM'Cg®c:f÷îÝû÷ïïûþÒ¥K“-‰µÊ ‡eÀZ—.X®$I,ë<ߟmY“´¶•º³XüeµšDÑ4*AóOèV¦€’.cÐü‚¹ùƒLyDèB‘T†8g�Æ—‘LŽ’ 'òâ´ËBw:ü)À©øÐÂr]]ôŒqœ*•J©TB9;‡xö3P 0âx¾§ŒÜËÉÓBM€bU:Ó4ƒ8~¶¡áìjutkë3ùüÈgË …ê·nymì¼Á{6íùÊÌWf6«µOkÏ1=ÝŽæY›¬¤{’˜Iï¼óÎüùóW­ZeFÜ;66q›±Éš= @âõ1Ÿ•‡Ò­†5ÝÊÍÌ9†£µ¶•­B•$‰i™\'C3ܪùžéÎv­g,¥”N´˜¨fC×úrq›®j~ð=L*Aø6®üÁ}¢< IY Ÿ áB‰�¡ËHƒéÀÝZÐÃV¤êÄ´E=¿<ó­ÿÆóþ-—‹´6 CYÖS¶=:ŽÇÁ®kv¢œÈ±åJ$Àª(Ÿ@fðÓË möÀú‡ˆ½@£g} –+AœŸÌƒ×”k®uË©v;P©Tš››Á-’yä™Ëéb`­ƒhýÝ0\gÛ/Z–-?¥®Êå~Y­:Žóz[peó9Ú’þ�¡GC<_$XdBÍ‹•ˆ :`Lcã&8œ ®Ð`¿²0 ØúØú3à BΊ$¨áqkrÍhýcê*GʃÞ>Àh s°˜,ýÂ2ø¨ð 5Q-ÖÆPÚ€1r ‰&ˆ¹ ! î8Î_êë¿[©|³\®7Í»' Øõºç®~Î)8›ŽÝT¼¯Øo^??ðqÙ†aÔý±nË£[œ×½QoܸqíÚµò]­ç·æÊ[ }]<Å‹óËÏ­¨µ+HFZ&ŠZ–êP2jLL!˜Z\rsm7ªÔhQÒ¡¿½ó|î÷„™†YÇÈ;àTb×°yp%x’Õj¯ÉQ ùÜš ”ìSEM–(宥§‹äs¦iŽŠã×,+4MÛ²„ŸâûþL¥ÆÄqC­o;kõ Ø>y½-òƒL™çyâœRý=ð1ðoœTˆyZ¼"©F18§ÔpR¸F´Z× Áªe¯´Ã½Cc¾áyžîÃ0ôó~Ò?±çÚY-§ëk9J©Kã8§uHú¾‚DW”*¶…-0…Lá—Ÿƒ‡&è3ªÇ©iÊò·¬÷ÎD,nV´EH‹šGçb‰³SàOj였œÞ!.ƒê~ŠÎ�÷�ñžu†b�t;‚ _ ² ÐmþL âp– —jfÐ�Ï„‡+šÇÊ4X=àEü±¾ïAðhCÃÛþC}½üd×;vÝïÆý\1ÀšÓ®#€–—(ŠÜ]ï?<oL 9Ô=µ³oVM½PCü Í\®W'ËmBY‹ÛG L�3Äü’ørÊÏ„Ë )ÁJÁX&•‹Ç¤­É[=™<„x¢P(5¥è0R•á.T–#•³æ)œ<€#¡ÅS�PÊ[{$—ólû‡Q¤Ú&'íÇ£“äÑ\nS›Î¡"q6$gg8AH0ŸÏçÛp9¸g̦âÁÛh@–„: Çp²[lÛ.‹Rˆå6;pÿøh°Ô!sê°[jžl£áÌq‚‘Ëei­u­†)÷u7ëËéÊ%¦äŠ0œŸ$§Çê£ûÓÿ\o¯±ã8þ…ï¿e𝻮AZŸ�Ðø0s»¥¤·ù§H£eDv¬gà 7leüJ$ÜX,!Ä♢QP£‘ËZú¥Yà}E"Â?dù^©…Xk+pEšÓ5˲ªÕª¢Yœ)åM8oùX´5°r6áº4Çž©ÆEsTŸ-TÛG555AÎ.5³ †JMrt¬[ßZýVU+ml1Š¿-ªåÊXmDVÄÜ*EÒ(KtfÖr£¾"{Õ¦Å)… rÜ䈷ÆsYx{‹„6 RŒvEL7�% -̸`°xyTÑ8jAçŠìÕ”¼:“ßPþ‘(‰—(Ä—È1‘Ì#IY£Öu]�Ñ6Œ³’äûžww>ïÆñ•ax}>¿Ü4ݶV–á�›¹<2/CZ¼‘ç¥ HÜ1ÊM?P;d’‹"‘i9õ¾ïW«Uà®< eæ&¤‚N ™e»aY–ñ†a~ß,¿\®ûZ®h˲J7–â~qáê‚Úþ×öírê”úÑNá»W/j®•?}A|ŽÒác-³7:?úñ¶e½îº ×àe`ª(ÊBp 6Îdæ_¤b\`bÜÚ"Ÿ‰#0šÀµ%Djhhp]·µµµµµ-÷ˆÅÄ@à`ƒÓå8Žt�°J)Oƒó†ò;œ¬l“´àˆÕ@ÆÆŽYêÌ<½‘‰g©xÜØ©r¹ÌòŽ<¨[Ñ|b¶ªbŒàxà†Áû�ÜÜ8xJ¦i&}’–+Z’>I¿ƒû‰g*O,ûßðó¿Éåɔˆ†ó”äš„²=jãòÚº&á,ËÚK©4ÍA. ¥udØÈ‚yBÓ~ Nq®Ð7&ÔJì^dóR7c'ìç”Ì ËβԿ"5hŒÏÁ,2nB;0`7ž¥Äª¸„/†a$†ñL.wvŒ­TNŒã‹B¥¬ŽŒsq*r…BwJÈLm‡w‡'–( U4žw¹ìyÀÚ˜o3…?�6÷ñd–†C¤ ü¹–Ь׹ësE·Øò—–¤˜Ê(\VÈW¡2ÌŒ±Ö…+Žû?÷ÜòoD/P(^i¿gªî‘>Pës¾á9Ð\|X<õ#W)¥ÉX YAjp6%©É 9à2n<ð-5%Õ™ÍÅáΠʪݻwïիך5kä´ ŒÄ/Œ‰¥ðLÊBnÄ´Zv$ès§R©päæw’$¢ÉÁ67DËÙÀiaRYJŽ˜@šàq€=±K�ªOjz ó ŤÊÓÛ*ºú¹\MG�À"ôòyåüóùü«ù8ŽÄ0"£Ç=¼¯z•s*¹;r §¢&-y8Ü“X•ãñW) æhß?-¦¸îËm0ìž™XÏ’€PÎçóÜIÆqFg±HÔ~DØBÆ£úÇÏ<xõ\7Býƒ¤T® Ž R Ý‘Ó!¤”7RÊÿåøÃqݧ ã;A🎴,jc?€-É^ ¸©œ•¹hwâŽð(Ç�yãþ!Ù‡àaÊ3A¬†R~'Ï“­}rbÆÕ¸î´ºvM[ÓP†ÚÞ¹۹˹ñÆEƒ'[¬ü´ZB=Ŷã0ì­Ô"O<UYF``sãBj|�Ø_Ðìb—v€ìXµ)¼Â‘°›‚´Q<7Áp^s˹qaZJÆML�˜°_)al!Ø&hrvÂÌQöˆ îs ›- 7<êJšrDk%®¾ItE”ûYÎLÚõÜ0âx,÷+¿&Ä|r>Œ. ³…²“¦U¬ÌµÞïB¡P©T Ã0ç˜ÆÞ†±Ï‹Ùã:Aª®h“iš‚mJuš‰¶BO:>µ¾%Ÿ?7ŠòJ½ÐÖ•Â[&°R‹| |2;$H6@c qT™ŒÚ;´‰¤ô÷˜ëȲ`¬1)&Åìg­6¤h²…ÇME\‡çôN‘ì˜eY¾•!ÞÛ $0#�Î[2Q¸Î YLãfÌ ¥ÈÁX”’jC‘{†Ç"0Ð2u rP-á±:)Ž\Fè¢uÊ)zö_“ú$œj­ëêêºuëv‚RS ãÅ 9Ã7’ÝP)Ñc’&ŠÃ|´@EK…œ©ª;ÈoHä±Õ0ûR0%–5ã~IöaÂZ½zõòåË[ZZ<ÏÝ‹Ï$BBæ(ÙUûÛÙvà(BÔs¯1OžInðGÀï3êÂõaP*Rf^P ªÊmïÏzÔÊ=‘+<U¨üµR½¬Ê<‹Ô| àñR„–ÝYi Q'®$õÁz`h*Ó^e†±÷Þ{>|È!q[K-£`˜»™Œ¼£ 9cl‚ÌÂ*A°}3Žã¬õHÃxÈu7[ÖCùü¾Ir|ðÀS¦¢M²=Ô¥â?g•w ‚+•ÒwH¥‰øF@‚bãÀ`D?©««Œ‹DgqŠUŒg(׆ؿªÞ+`ldÒ&®Æ4¤eȳшÿå Œi/ù|*V@#XÆ�‰l P®‘g#ÏÃYf%u�³xÔøRäëÌ•g(ƒà8oFI2%𑤻nrÈAÝ}ý™'Þ¡϶‡4¶Ð:qЦ®‰“>¡î«í»lã ÃþÄfÖ÷"På!f©t;5”‚ð‚ÿ¦fëb4KŠÍ6]úùåT##ð]BZ•ªísõ>e›x©ðsTG ¾q Æ.£[€7â¡A):Sê¿x|³¸ìò5åüļ~]ëH¦á8Ný)õј(<?tþè@ E1[rìJ‘g°¨ Kª¤’$F,Ë “0 úººÝwß}ĈI’,[¶Lkí[~Å)x9Êx°,À žG�ŠʇÁyQô…B¢µ¥Ô–8¾Åq®ñ}ešoF ÉQ«“�� �IDATØc²IRЙ" 2LJ[»ÎB,¬ ©H}ïE ”TæðàÙ*2´Buã–ê»ÎÆÓ¾1Ï‚Óz`˜ÜÀùfÓ`Ó‚JƒiÀ$RÕägúÀ‘ËsásI%Y“Á Âòc¡„@騔g‹qºòr$qšjšâB¤¤4 =«ƒÃË~QSÚ2—ó?\ìbMù¾ù¯.7ŽÞøá‹çz϶ê/®7]³üÍr4$ ‡z’v^i¯[,Æ!2 (†ÅE0 $×ÔÌ1 (:O1¦ÚU)Ûêψæ Ãîn(À\&ÖÀUITˆÒ= slÁqHéÊ@4“™01r–*• gE¨Á¦š^9-À Š¥Úô+†'»'º¢Í5¦mÛvÞnhh‚ ¥¥%X# £Ÿ¡Wj”d¡‰‰U ½‰D@*šÄ6¡ ã8N´"2ö7ô@oŒßÿý¥K—nܸ1Žãx·Øð µ¦½È$NŽaF÷˜´‹aMyãòÎÐú¯¶­ÛܘX×gDNUJ*ÞbqPËAÉö—#ž¯:¥k 'ö6 = ìÑyJ,—Rà2¡A H‡›Rj¡Ì$LuöpŸ?DN!ã„®H# EDn×—¿‚¦»Ü¨wŒz±ä.6*�7®œ)’µõ�ópå'ÆÜ´³æ“×åHC®Ÿ1l!Ù�"$ÏS£ðTÙ£z·½×r¶o‡i~f¾Ñì¼{”º, çžéã4ü¤¡¯êÛÿ¤þºN~Tp¯sƒooKDA…£ öHcÁéJ©L"ƒfÔ15‹ó#Šd"n ”<Œƒ8ʆybÖÏ|d³î_+Û—¥$p³m»®®®{÷îf‘K©ŽcWP§II N’$<$4[Ms±™ËåŽ=öØoûÛûÖÚ~×{‡jwÕÐÐ�ñlEZù½¤¤MÒÄÜ*t¡†ñͦ¦¢ï+ÒÎ}œ3-SÓI’lÙ²å“O>Y³fMÇÑAQҚ؋lÄ¿,è€NC.M¡�ÂF\0“W|k¡°Rg¶Iž$I2<‰ãÛëêqRm‚ ØøFÁQÛ¤4&ðú¤è�< 6å\å>EBPLèç³€ü>^4£ l1S?á¹æBœc{ çÍ¢ï¼Y™²¬*‚(¸­6C–Ä ™' gÀªKÜQÀß三?P4D o“!¿b¹Ç\.wøá‡ï½÷Þ…B«z¬e®<OgÈj9]¦=e¿~Œõ‡éásß7Š÷ ´ñÞñwã/-øR>Ÿ7Z û ÛÿžÏ.G‘˜+âAEØî í ´�ÅæÝ#¢i´E n˜Y @œ…¹{1&ŽŠœp–x�»ÄwPS•càS ]>,Ð Åšr¹¼eËdB¸)#ñ8“W -M�C˜Û.ÙG¹\îÀ<ôÐC{÷î-!¤T\ Ô»wo²v-ÃG/¨HµEž†¤V@9Înm •º~óæB>ŸÏçL’¤îÑ:ÿtË#[‚0ð}?Š£æ§›ýã|çOv,5²:ü/àY~þŠTòä^ÚéãøAÇ¢õˆ0L’äà0<* tœ–¶^®I`æ·@X öl˜ Ê×¹ƒ‡þáD1YeBŒð@9½X,¢ßE +l½˜H„q)õ&¶ûÌ3 ¥HÒÒ¼ä¯øDÀ…¤¾ù:ËïÖ!InsÙIj¥˜RÊ`#X�h¬‘=U\+e±jœ¦TKµ©lÈ*BÁ† Z[[9¡ç’×´�KòöÈ€µ.X"œUüiqM]1ú¸¹´WiÅN+žŠŸÚUïúÂ~/¬ÚeÕºuë¼f¯²w»Ä$Kw�zâÑL©î–Ô À&ì½ÀNA{³Øhî”Þ7AøI]¨€š £�¿ˆ>±³È$`ÙGÈQ#ˆ<€Gû�¿Â&¶,K µÎ%àÑ<à+ê[ÈøxD{DÉIxq˜ì’„ç…úbýØÛ=ÿüó+W®Œã8Ú)RU6…òQÒ$ˆTLµMÊš!xŽ4—0ù»TÆñÃpâø±nݦtëö×®½©[·5¦)T7k­Õó'=£ÞѦI›äÖº}½›jVhx/ YjÈ x\ b£ý–g-‹Ij ÃÛóù_x^!NÖúgݺEQµI ‰qß#”*ì+)– ¬Á“—»N½lfiN”Mˆ†´4 ½ö ±ŽÜ;k$ x•¼î\.'ìy&p^(ÿ+5Ð)•zÆ Oœã¹�€©¹®†β„|% •ÈÛ¶}¤ï; ¯/ÖSJĸ%¤êä<rc) )ˆžÝVÁáùМ-qš—2¯%Gž?>꾊ôñ¬Ì7/› ºMxÃ0,Û²æZÝ¿Öýè£^û͵­u­}ôQKK‹ïûaò, ÷:7ë(RNÕÞ. J ó-' @Œz/` ¥BËtX\7ÙaO3~Ú˜Ía¥T˘l#·†N@E-ÐòÁeþ8Õ# ™–ÔˆUHᢓ#´ê#tð/ª¨úáõÞ¯½üËùòWËK½¥¹§sºU›¦~%4—›áìp™³Œ{  B ÔNõÿC!3“ΪVëmûþúzCëÍJÝß½û·[[Çwë¶’¨\j­ê1ª\x¨joª¡¡Áqœr¹œÕ…ÖEØÊ”*êÆ¾ï‹E¦{ÉuþºP¸¤R¹4Ÿ·ÛÜ“ËÓ"’ëbÃŽ_þÁ†­O5 Eè1¶†]ФóÖi ä:âÃX!s#� <=¥²p¦Ãà€`«£>äø””F’$_Š¢#âx\±ø½0|̲–µ}>Oç‘£§ òng¬ Í7|ºQ²b¼±sW“H¹œëOú'/°\jŠVš¹œ®Y8ua9t&9åSËs_›[.—]×]ºté–-[¢|žÚ±QiDí„m1²TGR.¯UPV—ÁIãx‡Ψ�¸A€ !<ƃrËg'\CFh™²J<Ë�t8(?2•í–¸£”6ð XI´ÝpÍ£,b¨µ®žRu_qiŽíÚúYíÍ7[L{©äæåª·U&#÷T¸¤}X2Y.¦¾¾˜%¢Ç|F¹ëó</±¬q…ÊnóÇ(Æ45ý¡G°-— œ"®½oB3[LÎb9pNðñR̶ìÊ4ÍÛ Ýà C$î…ºl “Ä`è¹—Y<xkxøòÒ±á¡ó³Îú°üù)v ܧÔÕ¡ÅžAÇC�ÑKR4ŸDLââ85̈ጧÑpbÁ r=üç/‡á0¼Õu¥)é|Ï»Ñu›ÛÎ8ÏRc©7øi><iµ}ÕQ·ùeŠè° E¸`­#Èä@Œ•ð?¹tŠa ™ËÙ|O ¹Nudu˳[>øðÇvÊår¤#•SÉ~I~^>´?g, ¢‰”|B>„_éáò¬F€Ôò·²e4�ùMAKÄL`– ó³±q™¬ŒƒÇbÏÃÅ8BÚ’Kß)™�ÀÜ\$Oñ›ÁœÆb�&èF”²îWk­OÖVɲ߷»uë6lذR©ôñc·ômñnó´£Ão†¹KrÆ#Y‘89Ò>p<| 2™ì aýñD»$I^±¬««ÕG'Aº¦õ°ju¾a´úö*:1ñÒŸÁ/=eé DÒêÆÞ@îÓ&ŸÉ59­$i¨Ã± bzº˜'óyfœÆÀð¼W±R5söC)G,#&ÜbD$\BW$ ¦hö9,ܑØsJS#¬¸í|Ë$9V©ƒ¢èNÇ©(•Sj®em0ÍßV*ßohHÚ¤EùŽÀ“7ÂÅBnåHeNJç† <[ž¡•3"ëãñb= È|¤râÌåt1°f†õ¶åôwÊ/•ÕmJ·h[ÛÞh/Î(F;j Æ}*Ë~ j>lÌ~áM†PÑms#(Å`áèL˜‘„1Q#E"bØ!¥qÂQ0®3Ň­ó<㔸�î¦_‘P?g4&þ0á' CÝ]'A’´$û½ïرc׬YóðÃûS}û@Û¿Ñ·ž±Ì÷ÍT؈üƒI¹øææfES„ÙË÷.·¬ÿìÙóŽ-[níÑcãľÿµr9Œ¢Çòy—æÌC1tÁ¡âÃ[ææ¥†sž’Umz˜zÇ-™˜¿‡JWÀXãF`nsaׂ½Ê3)0o ¨”ü+¹_'KCàPžë¡Ú4™ÀvÊ„*¦"ÄõRSA»D?Mþ!˜àsBW¬9„kåÊ…–’’HW¤/°»Ößô¼›êë«Z[m0ìÚbñøªR¹&Ÿï¬ò€POį ®ÚTT§äPEð�?`I*ŽPyw ª†C*±¯[ ½ü‹Ìåt¥¿á¾ûIÛý‹\„½Ã8Žíûl÷W«Z!„)ü ƒÊ«T7%þÊ ö|9úFÛ : jCPÚÆ¹‹éGÕ©„fëŠNJG™ÉÐ\SáLœ}!ë–¦$pxL!7ý±JnªDޏ“C‚ –·ò÷ϯX±âÙgŸ-•J2üÃuÝÀ,³}�z|‘h©–ÀRRf·!îêÖm¬çMÈåö}'Ž,-óÊÃY$Û²¬Ê·+±'Vb?g«Õš6ðÌåx²æDá~¼)fÛ£xÀA47g Wº<>•Ôb7 ‰ø£ÆMoû"”ðOx–ÏÙ”›EC  ®œE:¹ÜÝ“r4ã '�  у}l‰Îr®©m¬”j±íÿRê[åòŸr¹%maÖÈ 84ŽÅß0Ù˜çdyCé“ñRtPŽün¢»–-gá²g``<•~a¿¹®‹Ì¶�‘Úî§‚¢o Ñýۮ¤#Æ@Yý… D¡P`î?ËÌ`¨-‹ˆpXÊÚPb’`ƒÉ�s΄k�3Š;®‘ƒ3W(–|šûXcQ ;Øq¨€`,:ü‘ZqµYþƒ>å:…l#ß‹”ÒRl;`\àM­ÙV<46†ë?[?mÚ4†¨”  ŒM†³Ô1L!aµZ•Øœ¥!SǘEˆSCNT~bš,kô¦M ã‰nÝÌ6„ð%rQÐ0 ÿtß?Ù·gØFÕˆuü PUøu9Š„D4I3³æÿLIØ!ñe`ÔóTÅ‘2yȈ͑“ñÃÔ *CÐÅA›‡§¥º=äz$š¸‡j B’ñ %®S2¨H´‚ “íc¼)‰n‰Áà>(š ˆ)‚%“/ýĶ'YÖAps.×l§Áà8¾-Ÿçvi´` ‘Œgó(Ù¦g9¶K €Žû=á½ðÌe{KpÀcCñTU›nº<OÌ~åN ¬–Óõ  ²Y%K•sQF¶+vS¶/gÖ¨|Àª ‡“@2$?G‰•y¶Å¼›qrªw6 ,€A˱6wkƒ.,iºô1cJ¤SÄÍð$GD£¸SA*˜ Æ-C^)�šA)HH!Á^m‡v¨êxi\­VåÛ­‚í©&¯‰¹ :¨±±Æç(\ð‡÷@k=Ï4·8Îj­ ’(Ú‰¬¢&æ¢ï×Ý[gÌ7ŒÄ0 #šùƒüÊU•ܵ9ÅBEDz¬ºº:i—ä�r Çd`;¡xÆö+Žc7ﮡ•VZÅ•b6\Ù ÈÚxP +êèdµYè£s°Ï¾AîKÈi¸r.B0xˆ‰S<µ›Éx¸*·Á¥ääñbpªìvôбó–F}&&tžcmYÖ‚\nœaÜV­>äºûÆñÝŽSm+[âTr;z’à?Àñ“z!z?ÿ»6L–l�לψ|#”m3g‚ó8L0ËŽÉ{™Ëé²%m’`ô2qY6“ôy€0Ãg†…4Ð]!©TÅZ 9rg5£ÛFÀâ~ ˜0&¤±´»|8¼gELìÆg9‡b† wåky\*I’éƒm ÓÏliÊåðŠF[2xßãû~þº|冊÷=/G^)øAr]bO³ó7åµÒh°åº¾]òW9írƒ< [ÑÀ=nN’®d¢Íõr)XŠZ"§ƒ]kµ¥çjÇuìœúLÙ¡~94j­B•Õ&@ór¢xs\4 Ci¨äøç·*¥’Cÿ?þn¬”JšózÓXië:›™�T–2`OÀÊ"媭û•œD*(MNDýFÚƒÂh"ÀªHMôàòOò–_Àø>¹ EDsŒˆb0êXKL}}¦‡Åq¼T©+êë/*•~Ẏ㨶⨛𻒭bk!áÎYÌWå&6fßð±å4¤Öb±(ÄE`­\/éŽÏù¹6\@&ëÙÅ)ÛNiS(—˜ìÈ´Kñ^rÆY+š:¥¨OfôGÎÊù åoAë‚q”Ï<>¬»ÅHËð·r. HŽab̺æOæ±ðФn0½ i>SÆAÒ娭Fк<—ôJ‚ŸŽãÔ»õê•TñIÈGkbÏÝØO_”RJ+ëþv >CÚô$J߯xˆ|�OP¤X£º¦ÞÖ'ªUí~Aw»`ï¿ÿþ={öœ={öºuëÔRå¼ï„_ swçP$çìDØŒêð„.®š�(ã–ÛÚ#úJ’œ”–z}£—Rjs¼¹ü³²Þ¬£Ç¢Üš²Tá-µÇX- R<‹2|F8±f± ìX˜"›á ÃM]<�‰92È;Yk»æ•yz€ÔÍ{Ÿ“o¦h§ œŽãlTêšBAµ¹mŽP™Z†’lRᔺžU;5¦MFØ2$0!å9Ë.MÝlê± Ã$¼áw µ>� �zD2H¢0å©ÑŠ©œ†ÃÜrÁ'ýœu V Ûá'¶‚ô”@CÛŠÆ£!V…® &B!UÒ ‡¢QQ Ï�²cª ¯1î 2@á3Êð7µ§S[Lóg¦ã8…BÁ‹¼XÇHjøÚ"8Ó4½ÿô’‰ùžišfœÄ¥ß—ì×íÜ9Fäá<øÏ\ a+Åæ|×ð.]4PWWwÄGôîÝ{É’%›6mÒZ:àÀ…åLR¡ Š h§‡‡Þ7=Ã0âEqþ·yø!.P†|'(\Qèã÷Ùwè¾¶mðÁáåapU ÷Óî&—•¡Y™B¬âq‰ÐYóÑbWþ³RCo.¬ÁzH ð p*èÀGÎ rŒ#çÄýÉá’Ü ïTãÞ)ÏçfLt ÔÃáŒHž*"²uŸ`”8å›SÅNÞ܉%›§¥±ø&N%ƒá©ÙWÈb™7Á]º¸Yv!,ö "?)Öra)s9]“å K\‘ö8° ¤ùl¾ñRQ/A½G :+ï‚\ÏSi9¸C²ÿ¹ ¡0Ê8ù°Rê—„®®Á"sý×$T8`’ÔžÆÎ¿(ç „"4œ8HàŒv.æËc‘KÊårìY�Ûó<þŒþ•2©ã8埔­÷-5O¹+]Ó4£82æñÈØ?Åw^pR­<¯š éM�~¬Ó4sN®””"#ªT*o¾ùf>Ÿ_³fMŽë(SéPãÊy21K‰'FÙ)È•ç+îënýïëµÒþ`¿eJ‹{ƒk½h¹¶‹Q:azßñê§Ö÷U}¿zÆWÏ<óLÃ0Æ?a„ò£å–kZœEN²&aÝX©ðP•j f&IõÎOüð®ÐÚÉ*\_\y½b>oænË)­UžŸ”R G†¦(‘1«è(3Ó\×•Ø ¡RÉZX%î ïÕ¹T³¸oÉê@ OÉéï˜ ï8ý•dN°/îUâi[<MXÊ<8ï¬â†qd·Ð@E™ëÊI¹2,)(.Ê{ª“$Jærº`q=_Þ.·ïÉN•ƒÌšk ñs> Ð†’5j†Ð6æä@u¦‚ Ç›•áS…"®¥²1ùÛJ¥"îŠÛ,@ÁdûT°Éº ”2�ds#ƒ´˜óežÐŸ-Mü ·@¡{N.�•Ä•^wO7hãSÃXbÄfl†ÒÊúÄÒûèx·Xµé™ŒV±¤ÐvÎöd{€ð Ξ°»Ì-L*”/(×ý¾nñâÅò|r¹œÞW'#’~¸“r:¿â¥GÔèà ¶ÕWª #jþOî<×}Þ-+åæƒÅÛqÕ[KŒ~=ûyä‘{íµ—ã8GuÔŒ3–/_®{èJP1’Zü.µ"Ö:JÁ°í9÷­Iîþœó¾#/Ë2­î#»W¿[Uç)çÑ[šÉî<1G¾èÅ£€°C Î‚Û/ "n›rü\�3[ª•‘àÁŠN"„ú'Wmqý1Å2k?¥*Ë?øü­|`±XÄȵÔÌ'Äšòùìɘ8.ÎO|jª£V, 7íAo‚-cÚ ®puû]æöžåà` �zÀ}רÂÁàðƒ>Ûy8—…™®ÊmØ=,¥“Úµ\Z”€¥¾¾¾ÿþõõõ,–„Z¼˜—<ÿ¢¹)M0YAÛ…t)¨–žçIiˆá[€Þ0r;T¿qž¹¥€[ €õ«Ž²oò´ákñ]µnö/GÎRÇ^l …!C† 2¤P($IbN0£ý£d·=(9 ƒû-p¼åçè-gieÇÆ"Ã(• *F®æJÃ3Co¤—-'Ì5- ºgÝþmáäØ~ÕæSPô’ŠYO®! ÃÕ«W¿÷Þ{ ,˜3gÎ믿¾|ùòr¹œšƒÉ F¦ó2Á×4ÍdßÄØbX,l³1÷c7é›D="›!®ÄE„#ò¥˜òÂ>­u¯^½z÷î M Õ&™ÌåRÍ•ãg˜>ö Sá¹uÈ“â„wÊ=Ø“(ÚCxa*ŒƒËÒþ 'åàYà—¡Z‚ &ÎDgÕqž,Ú  ÄÀ ÏCbÍÐLIz›hÍá¦*`JŒ³£Yö5Ut¨¤xŠC ¬Á$$ï¼™$Ž–ä�øƒ"AF»wï¾Ûn»-^¼´T´IT(±-LsŠ„ÆGxPö@ aÜÑDМÛ]1£…+%ø ê%@繓¿Ã<¹Ï]0+,xj˜µbRÏž=GŒÑ£G§žzêÓO?µ,KЧ£òüžUÊ46êP²æ’l;Î3ÏÊY¹h¯hÓo6Ž¡µvg»öBÛ™ìÄFŒÝ]x›ÆA;öÏö;ž]Ã~2Wz­ÔpO}Î$'l˜¶áÅ_\²dI†óæÍkmmÎŒÌ)¦Uê00 ¥oÆmp1òÞÁž¹Á´VZ¦SES.—=Ïs¦;ñ7ã°oXl*r܃¢WÂ�3Û…G"ÁÍðœ\$¯(¡ãÉ+Ò c_"~ã‚À©°v5ž^Á•!SyP/Óù‡,kÄ´T°p¿@™…ŸT¡ &àõ â “c–{àZRÿ”ÜsR2—Ó•<ilºÂ]5 §°jøTp”¡:ÊÏ0œV7Æã¸âbxÒ¢8–––E‹µ´´�O€Ö!¦òÈÆÈ XpXYWQQ_*nSJGìQp~¸RÅí~ÜkÍÇ[®DQ»> }b7j°íÏ c€ø¨%Ibk;HC•Jå£>Êår---¶m+G©XéX›Fû °$ `-g-¥<Eµ©œ1‹×šgÕ-¬ ? µ¡£82VNèÄvZP 1|Í©V¶¢ëºýû÷oiiY¿~}n®Û{Bk:ß ¬¤_t –®[Z*•‚ (WËFƒ·ŒÊ–Š4ÊÀ}¢r&h3Vj—a™Ê¨íÞÁƒï²Ë.3fÌØ´i“ïû‰NP¹ÁpÏ2Z}Q¬Â¾ƒ´ë ”ÔÔÔ„£Á>q ËÜä%Àñ8Çâ–,ù^aH#dÄ!•w‡HH&¸ŠyóÀ0¤Å•/‰;%åÇY©Tä»e`OÍsâÑYM SêqH¬È?”ÝËÍlLpB¥]=óf.§k°5±2ÐBÞ7úc�——+É Ï£¥-í–)MDgˆ:!Õ%• äX\ÕçÒQÇ­­­›7o†‘BŽÂlµZE]‘5nѾ 5*¡ q!Z ,Ö$S΀–Èõ#bå¤m·Ü”|T R…zÒ¸j TJ jfL^€Ö™û'7¸%03*s*³f͂˿ÚïØÆ#Q +¢â þæyž v€¼p�Öy Ê{µM²ÄŽãØÑŽiš–]›Yù/ìn.†Ï®Y“…¦ÚWéºT*­Zµªlª¬…K›È¬;¿®ü@9iMšžk2 #p‚êEUç1Ç}Í ™+³™ÑœR ’9{ƒôMìž¶Y6W¯^ÝÔÔT©T,ËŠúFªY©’b¾%,Ø(Èø)µ`Œ¼©Î£e¸3T7°™‘y0Í1Aг.®à6¼â¦û£@u±Á§O�|<�ÚYB†×¶4.Á.gº¸xÄšØiÐârŠäAñ*åðâp/Ø™Ëéb’tªÄ9<æ„H9T„ªæ [u”¤ì|Bx= ëàJÊãòÀ™aëÃRs±1,²¸a‚¹È!yËÂ?¡-Ÿ›Þ1ÂdÍ2‰ î ¦‡ æ‰1<­HºüF¡��,IDATža´?˜›¹á¼]Úë5'8!ö¬?Y¶m›–þ ÔEmOµñuHñùò4D(oDœ1pŒm„FN+¹ç‰&W¤ÑñMe€KÅ;‹-SZòO景o†÷S¯xC‘—7ܱ®±ŸQ>¯¬ ¥ZTñ´¢eYÚÐ\=N áð›âPÝ~Å®Œªø{øÖ,+‚¦¦¦üuZb-´ŒOkâO,¡„‰ÈŒ©r}¿–‚¿ø…‚Á…«h¦B{ÙÜ9€©H(A÷HÍÑ�„Ss$UL>F ÉjªÌÀÄv Ï †VÚyÓQï)€o)Å ØâN�¦ñÙÄð¨_ü+ âÄñÐ<0/€åò}eê]}¤‹7ƒ‚Ï™H)m¤z,€ I8Ï]Zà.§$ëY\Y¬ OzgqL†þj÷ JÃÍŠT^¼â>,a‚‡4Ï EHõF@t=EŒf)%ú‰0ó¾ä{;O#A°ßiîùœ}²н‡¼Ð mصņù Çý1ðÐbu¥yLª KuE  ;qEÕqVžRʽÞõôÜ)®ñ#ŽãpÏ0º2rf;ñªØ6m�¹Çq–9úšš¹‰TÄ„4\ -§&cÚEǹÇsþ¹¾qš‘»&'ÿ¼rÅ\næɇI˜birPÏ ¤p ªãP¼q$[¬x”r9x†f6ÀjÐ Sl`d3 «po�Þ£"-Fº0®©óà"tbò€Ó4£#"ï|ÏéÚl­utz]™š*lçæ¡./Õ  ׈®Váä3‹˜ÎW +ÍAºácµpv—ƒ¸IÈÊ\à…ò1’tì™ ‡¤h@ˆ´²†±O’|Û÷ËÅmCS• àé܇…óÀÕ‘¥2•hàÂ<+4‘ ¸c63ê(Þù'\ÕçÑs) 8ô�1ê‚©·ÌEfþ"bEM¦,Ì`â8 ãsËgIkmM±L×4§Ö¢Kw¹DZ2jM0ªHÉO1­�„l‘>â1$¨a ²N! !±sº;¡ Ó°|+®ÆÂ‹E@ãÒ.7Ùt>qô)ºéå&­´±Àp®uŒõ†ã9Úhß–¬ —jRFC ;cö͈uä݉‚C­º0ÛÈ­Ë…CÂÒÔ’aZikŒUŒŠz}Í›B.AX^œÄcä ¢±Œrkè€ÃÁh<‘–«;,{H5B'?aÀ�Hµ\*ðR4¸àuõu]ó�vI ö6j†Æ`#87Èý:§V);±µÖFÃíá–ÿX.Ž)Êwá¾8à.cTkØÁp³w;È r•[ @ àOÞ9˜AÙ êmbAìq-ÕiÊ€œa œ`áqø�`ba6šæÿ ‚gr¹Kâø>ÇÙÔ–$É xÄV©~IÕ6ñŒÕ£q¹åž£K´� 1(˜H誡Ù%å9:›n%eÇ“ú‡dTb O gCÊH¸N¾Gy’œQà„LÌ]DÍ©|´vJ#e-±´Ö*QÚÒà8ñÉgnBlw]»£:‡ÀªMC,5ù[RÐ3HöK*gUâã$IÜ×Üdf’;ŸŠNL´+¥”Væg¦u·åÜí0Fg9k!'æQ:°\Õj•AW†�å’‡ÉJå¯öuË {…íwQS4 #Ñ4$¥`z=žª€“) E,sÇì2D9üg(ÃB7AøÌÊ–9þ‰°ïÚiõ¨ ž†ÏI13e£eh|uÿªµÌ2?3ã8ŽØ0 µQ™[LÕª’}sa;Ÿ'=y¨¹vƘÄÛt‰Øö,‰+úOŒéA’Ú¾;€ôÀvïrvÞyçýèGêký}ÔJÆ`.r ž{ÁÌ%N)þ5Š·¬ƒMsD 0Ím¼I™:ÅQ6`žÀÕ”† 7)ŠÔ!ùcSr[|#)Áúÿ,ݪSŠSÄ3žHq$™cqnnÂGÝ‹EMpUÇ‘<ª£PXªÕ.$~îPðÎãS‹Ù  ƒ3—ÊoB™@½¼ý¼ÊW+õÖ;Óœ8Ž«_©†W…õ××Ê€ÇåK‚N%2÷EñhŒÍk„ŠÌTGÉCC¥ñ}NIÑŠ³ËÝc�‚xÿs`²Xû {¤ÆË2w4…Úáç<ìY® <(“ÍRZ!ÐÏVóØ…p,Å7…Ÿ³œÖÚ;ßËËëK5F÷Ö[7Åñݱ3ÁÁÇ2þ ¬/5€Juœ4ˆ§¨Å[Q»+÷9pf„Fu”+äÖ¨d.§ËÖ Aƒ®¹æš/èÃÞö‡cT¶þY×¹ÿÍžÈÖ°®þïÿêìé|a¥ìd+[ÙÊV¶þÑYŽÖú¥—^ÊžH¶²•­lek+®#F|ŽË‰ãøË_þ2ÿ^JVòòW[÷×¶‘Ëø¿ö|ÛÂel•·³c¼‘¿} ÛÂeüÃ^ǽa2«Ò%Çy+~þðáÃ?Çå|îG0ïëoÿWuRxݺÿð‹þüìÂþ7Ÿ¿Í^ÿÕ6{aÙÎ.lǾ0î(Êj9ÙÊV¶²•­ÐÊ\N¶²•­le+s9ÙÊV¶²•­Ìåd+[ÙÊV¶²•¹œle+[ÙÊVær²•­le+[™ËÉA¶²•­le+s9ÙÊV¶²•­Ìåd+[ÙÊV¶²•¹œle+[ÙÊVær²•­le+[™ËÉV¶²•­le+s9ÙÊV¶²•­Ìåd+[ÙÊV¶²õÿ½>x†ŠcB;þ,ëŸj²…êºá%*›þòÙ êŸx–ÉñF¾Ð)>Ùé’7ò¿±Ì×^{íç¸˲&OžÜ%~oÊ”)­­­gžyæŽáÆ/¾øâ;ï¼sǸ—9sæ¼÷Þ{ßûÞ÷v˜ kGz;ÙÁٖדO>¹óÎ;üñÙÛadóOGÕ%7S©TšššºêÛ·úÚwß}w˜{©¯¯×Zï0·³ƒ½ìàlËkÉ’%»îºköv”Rq·;𯯯·Þz«R©<ÿüóçž{®ÊV¶²•­lekë­8Ž[[['Ožüÿñ} [ÙÊV¶²õZ™ËÉV¶²•­le.'[ÙÊV¶²µc-ûöMåryΜ9Ç{¬Rªµµõ…^PJ1¢oß¾J©÷ßáÂ…;í´Ó)§œ"¿ÿÄOh­÷ÜsÏmê‘577Oš4I)5räÈ^½z)¥fÍšµxñâž={JyMkýÄO(¥Ž<òÈÝwß])µpáÂ÷ßß¶í³Ï>{Ü“&MjnnÞ{ï½=ôP¥Ôúõë_}õU¥Ôi§ÖÐР”zë­·V¬XÑ¿ÿ“N:I)åyÞ„ ”RÇü.»ì²íÜÈK/½„ gç‹üðÃ?úè£b±xúé§Ëï<ýôÓAtÐAûí·ŸRjÙ²eÓ§OWJ}öÙ¶mwí½¬\¹²¥¥eèСò¿sçÎ]°`ACCÃi§&?ùË_þEÑ¡‡º÷Þ{+¥–,Y2cÆ ¥Ô7¾ñ !½ôÒK›7oÞsÏ=·µ·#kÖ¬Y{ì±GÏž=•Rï¾ûîgŸ}Ö«W¯‘#G*¥â8~ê©§”RGuÔàÁƒ•Rüñœ9sÇ9묳ºü^-ZdÛ¶œn¥Ô;ï¼³téÒ¾}ûŽ1B)†áøñã•RÇ{쮻š?þ|ÏçA/œ8qbµZ=à€ößÿ.¿ Þ~ûm9ÝJ©Õ«W¿ñÆJ©3Î8£P((¥^ýõ5kÖ 8ð¸ãŽcþÜsÏ)¥†Þ¯_?¥ÔìÙ³?ùä“nݺzê©û»¬bÏ»ûí¹Ÿm(­_vÄaqwuùå—¿òÊ+£GVJýæ7¿ñ}¿µµuêÔ©Çüœ9s^xáÏóV¯^½jÕªaÆÝyç›7onmm}÷Ýw÷Úk¯nݺm;víúë¯ðµµuÊ”)Ç÷Ýw'OžìyÞªU«Ö­[7tèÐÛo¿½¥¥¥µµuúôéC‡ݸqãÃ?ASSÓܹs?üðmÊß<ñÄüq¹\þè£êëë{÷î}à 7DQÔÚÚúÚk¯tÒIS§N6mZµZ]ºti©TÚk¯½n¾ùæJ¥ÒÚÚ:mÚ´ÆÆÆ\.×åw1uêÔßÿþ÷·ÜrË%—\"?I]äâÅ‹Çïûþ† /^|ðÁ7nÍš5¥Réý÷ß8p`’$wÝu—¼ÙwÞyç˜cŽéÂÛ¹æškxàÖÖV¡ØÎ;w„ ¾ï¯]»vÙ²exà]wݵaÆÖÖÖY³fí¾ûîžçÝ{ï½rñ3fÌ8úè£ÇÿÑG•Ëå äóùváíLœ8ñ¾ûî»÷Þ{¿ÿýïã‡3fÌ¸à‚ Ž?þøLŸ>ýå—_ö<oÅŠ7nÜo¿ý~ûÛß¶¶¶Ê!6lغuë}ôÑ 6oÞ<oÞ¼.t¢I’\~ùå÷ßÿN;ítðÁ+¥¦M›6uêÔjµº|ùò¦¦¦}öÙçÖ[o-•J­­­o¾ùæÁ¼bÅŠ?ÿùϾïoÚ´éã?>ôÐC|ðÁåË——J¥Ù³g÷ëׯOŸ>]øvyä‘x`âĉcÇŽUJ•J¥Ûn»M,À´iÓN8á„É“'Ϙ1£R©|úé§aî±Ç7Üpƒçyb"Ž=öØ?üð¹çžó<oíÚµ+V¬8à€R_ÑT'ÌZ3å¥I³gLSý÷n¼ô¯þ%šo¾ëý…­Ë.»ìþûï=z´üocc£üáÄO,•J<òÈí·ß®µþðÃÏ;ï<­õ‘G†¡Öú /œ9s¦Þ–.þ½÷ÞK’dܸqwß}·ÖzæÌ™^x!ÿÂyç÷ᇾùæ›—\r‰ÖºT*xâ‰z‘ZëÛo¿ý‘Gá‹”¹ñÆŸ|òI­õäÉ“¯¼òJ¾ÁÓO?}ÕªUÛÂ],[¶lêÔ©ûï¿ç×$9qâÄk¯½V~ók_ûš0¿7mÚ¤µþéOúÊ+¯,\¸ð[ßúVêßvÕzë­·~õ«_]ýõò¿ëׯ_¶l™Ö)Gk}É%—¼ùæ›88¸xœ»ï¾{ܸq]{;‹-š:uꡇÊ?¹ôÒKO?ýôÔE¾óÎ;?øÁøœ{î¹óçÏíµ×~ò“Ÿh­›ššN>ùä.¼—$I¦NzÉ%—<øàƒò98Zë-[¶,^¼˜/~ôèÑŸ}öκuëN=õT>8¿üå/_xá…®};}ôÑĉG%ÿ‹‹Äà"Ÿ~úiÙ“¸Á“O>¹©©éñÇ¿å–[´ÖóçÏ?÷Üs;ÅÊ¦è’ ÍçÜør·¾ƒL¥”e»n±›aZ_ݰaÃÊ•+9ä‹ô}ܸq‡~øš5kv€Û¹úê«þóŸ~øá«W¯ª¹Ý­AƒtÒIì�ë˜cŽ6lþ·OŸ>ƒ Z±bÅÕW_ýÀlw·³çž{žtÒI¦Ù^9^¼xq±XÜyç·»{1 㤓NÚk¯½ø‡«W¯>ãŒ3.¾øb¢·¯5tèPËdõìÙsôèч~øá‡~ë­·n‡fZn±[÷‡8ùº/œ>°bÅŠßýîwW^ye÷îÝw s°~ýzÉi®»î:nqÚN×µ×^{ýõ×Ïœ9sÀ€R£ÊÖ6¸fÏž}Ë-·Üÿýù|~{¿—É“'¿ùæ›×]wÝóv&Nœx×]wýÛ¿ýÛM7Ý´½ßËæÍ›Ÿzê©™3gΜ9ó'?ùÉVÿü/¼F:kÖ¬)S¦´´´´´´Ì™3çÕW_• Ûö»vÝu× .¸ 3‚Ùú‡­9sæ<÷Üs—]vÙŽ‘Æ]}õÕGuÔüãéÓ§·´´<þøãÛû]tÑE X´hQ¶W»Þåœp ½{÷VJ­Y³fÉ’%®ÉV¶²õ?_‹-ÊçóÂ}ÚÖ=÷ÜÓÒÒ¢”Z²dÉö€fëÿ{õß»ñò—ôå/é[îyü -R­X±âÇ?þ±üyáÂ…o¿ý¶Ö:Š¢n¸¡±±qôèѾïk­=Ï;âˆ#ÿô§?Åq¼MÕÛ…0ÓØØ8kÖ,­u†¿úկnjֺ\.Ë/Œ?>Žã8Žzè¡ÆÆÆãŽ;Îó¼m>àûþèÑ£…¨¦µ~ûí·åú.\(7xÙe—566^tÑErƒ«W¯–_xùå—“$ÙvîåœsÎÁŸSEÑwÞÙØØxê©§b1¢±±ñ¾ûî‹ã8I’gŸ}VþÉ–-[ºü^^~ùå{î¹Gþüâ‹/tÐArmRˆö<ï¸ãŽkll|衇d?^~¡\.k­ƒ 3fLccã¯~õ+aâlSoGÖµ×^;oÞ<Ùc×\sMccãw¾óÙc---r;&LH’$Žã|°±±ñÄOÜÑã?þÌ3ÏÈŸÃ0¼òÊ+¿÷½ïÉÅoܸQ.þ…^‹¿çž{GŽ){Ï÷ý/ùËøÃäÐuíjjj:ÿüóÁxõÕWåúW¬X!{é‡?üacc㥗^*{éÓO?•_˜6mš®›o¾¹±±ñ¬³Î’L­U-úò—ôÖkÐ~Fÿ½Çþn¦Rªß’?ýä‚oe>8[ÙÊV¶²µ×êVuû;ªyí’ñW–©d+[ÙÊV¶þA+s9ÙÊV¶²•­Ìåd+[ÙÊV¶v¬ÕÎX«Öïþþg›‡ ¬ÏJ¶²•­lek«¬y+K›tÏÏq9-½|fÆ{ôÜ-{FÙÊV¶²•­­²ž™±ÂïÕCµÍ¢¦¾èÞ2iÙßýˆbeE}ù³ìQf+[ÙÊÖ?íÒn6z^éoÿZµ0Ðjó7J)cÆŒw/üõƒ#/þ>çoÿû$IŽß%<u+{âÙÊV¶²õO»&f½±Üü».C)C)UiÞðò=rëOí~ýúî·kϵ guë·[q§>ò×c…^¹iýºòÀ>ÙÏV¶²•­Ú†¥r×eˆ¿Ù¸dÞ{èׯŸ!ŠÓ¿¸é®yŸ­9éü›ÿî?Ž£``²l¿ú-ÙÏV¶²•­Úµ²pàgÕQPý»¿ùڸˇí±óu?½hèС†ÖZ)µlÙ²µk×vÎwÿ'ßdƾW³'ž­le+[ÿ¼+·SdØ:ùûjú/<ùPÿþývÛm7¥ÔÿK‰Ç}sŽ•L����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/2masssrc.png�������������������������������������������������������������0000644�0001750�0001750�00000611527�11332127303�016675� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��_���ÄŠ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ ~Ýò�� �IDATxÚìw˜UºÿOåÐ9LOwON0C¢¬aÇËUWEtw®UÁQLq”•Õ5 †‹zWTqEQE$ 3ÃäÐÓ=¡s®~¶¸:¸¬wýÝþ<óÌS]ýÖ9ß:ç­óVsº¤ªj0ôx<=ö˜Ïç?HGoÄ™cY²dÉ’å—€ Ô`8Vâ² Ñ>8Ž!ƒA›ÍÃð›åçç?ðÀEEE999h0\µjU[[Ûc=VPP�A�àýÿý£¿ùúßfk1K–,Y~H²üö¦wÿûžË8Žûáæ]ûÿÒK/Í›7a˜¡¿öÚksæÌ‘$IÛ£í¼­ýïíí}òÉ' n¹åÔãñ´··?úè£E"è[`>y[”¤/4ýË}X±³»/$R~®%Í ÑDÚbÔé(Üçâ8Zì¶·v��FWä×·ù��#ÊÜ-ݲ¬¹mÑ“H±v‹Eá`œ&qW޹ÃlŸÙ(-p „b +8í&YQ‚‘¤AGÚÌúîÞ C•%ƒí+Šœ=ý!^òr-,'Dâi³‘ÖÓ¤o ‚cHI¾£¥«°}U©»­g@’”B—-ždâ)ÖfÖãÚŒQ$–ç°¶÷øÛªÈol÷©*(ÉÏ Di†ÏµU" =MæXô]½!†F”ºÛO–ëˆp¼èv˜yA ÇR&mÔ“Þþ†"eŽæã…U–¸:¼Q’ \ÖDŠ‹'›YOàh_ FXÓÚæ9NØÈò¼£}ª¢–äÙƒÑTŠáV#8¡£ ‡ÕØå BYžßp| —æö",'ºrÌ‚(…c)“ž2èžþ0ŠÂ…ΦξÁöÃK\]¾€ ÊùNkŠáb ÆjÒQ$Þë8Zè²·yN¨ú¼æ®>EQ‹óìáX*™ær¬†BqšÂvsç?¨ú²G0Æp‚3Ç$IJ(š4ê)‹‘öô…^ì<Úqœ°¬Of}ògðIŸ?�`Y6nÌ¿·…‡ HQAB¡ÐØd¶E‘eY3þ{‹Åòì³Ï.X°Àãñ ¡Pèá‡Æ0ìGS‡ èÝ/[abÒ©_ЛN¹,d:•ôõИªÃÕö.Ÿ$0¥¹ú†ÖîD">¶Ä~¸©3‹,²6wxÃáHA Gûúýf FU±³§ÈBž…ljëI&ãc¾µ[f?ÒÜDKœ†>`À´0Y`=Þ~ H6=ÚÒéM§’# -uM]‰D|\©½®©3 Ë3u{ûÁÓL°é¤·w€ÂµuûDŽ)wZº‰øØR{ÝÑŽX,6¢ÈÒÚé …"ùv:ööL$„CR‡§O•¸|}´Ý“LÄÇ–ØëŽvÆc±1¥ö†–îH$Zœ«ðû‚6=ªŠ\··UÅ#ÞÜÑ“J&G[ëš;ãñøøRûᣱh¬Âmôô¡\3Á2©ß�‰*&jíò lºÂmÔ„Óìc±ªBK[·/ çÙ¨x,îëó@"rGw¯"²…9ôÑ6O"Sj«kêŒÇb£Kl­Ý‘H´È¡ Ãý+YèêéCT1ׄ7wô$“‰1Åš}|\YÎᣱh¬ÌmôöùýÄólÚãë'ÙB#m>–I Ï7Õ+±œÃM±h¬²ÀÜÑÝ …ÝV2™ˆ{ûüzШÒÞÝ+ l±CרêѪ^6ªØÚÔÞG st¡P¸o `¡X:=}°"¸ÌdS»'™LŒ)±×5uÄcñqåZFÑR—¡·ßï÷‡rŒ˜È3ݾ’m4ÒÚéeÒ©ª|ó‘æcU¯ žoêìé ÃYŸÌúäÏã“o¿È³ÿyf9˲?ÚÈÃ0|äÈ‘ &¤Óim§ �€ �Á€�‚a8cߨØ8fÌ–eµcUUûÊ Á0ÃÚ·“&MzàP¯×[PP‰D�µöƬÒiÕg²ï¤S¬XYhÓ’��È��)Ü¢Ç!J²B4-@�¸­´¢‚`œ$!i\QÕhŠO±Š@.+Nði^<Ï.$†Ød(Áq¢œÙiÑfgE9œàDY±›h@mްìs;ÌZúŒ4>ºÌùe}M`gŒ(Ú×èª:¢ÌÕÖ‰&¹Ò<;ÃË]ýQ·Íh6êt ˜hbDiîÞ†‰MUüy]7Ž £+òê;)V,/tD’œ7/t˜I’hìXôdyAÎWG½z Ÿ\YðÙán GÇ /8ÐÚÏ ÒðâÜÞpj ’*vZŒ4{C9&]¾ÃòMK¯ÂÇ”;¿8ÒCØÄªÂ¯ŽúEQêêè‹ElIž•ξ¨Ëj°™ ‡ÛûM41ò[a“Gï®ó 4ºÂÝØL¦…²‚œXZèñÇ rÌ4M6tÌ:bX‘c_£WOâSFì:ÔEâè¸aù[8AV”Ûeúé"§FæžÝH:­û›3Â<4N¬,üúh¯¬(U¥Î®X(Æ”¸m‚¬vôFœ½Ãj<ÔÖo¤ñQ¥Î½ =:›<²èË#^£ÊÝMžP<-”ä$XÑ3ËÏ1éõTC§ß¤#††MýVØØaù‡ÛX^ª(r¢L_(Y”kA1¬É´èb·­¶Ég ð åÎÝu G'Tìoê•d¥²Äéñ'‚1¦Äm“T¨ÝεèvÓÁÖ>MØž†šÀ&(ÚÓà…!0²ÜÝâÄR|Y¾=ÅIݱ<»Éh ë;ü&QYâØ×àÕ“Ø™£ >;ÜM È˜ayuíþ4'V:Bq®7˜,̵à8~Ô´ÈÒ|û×G5a®Ïëº)?¼à›–~A’‡—8½Ád š.vY³>™õÉŸÇ'4É$��àGŸo2|fûPGðW÷žÐêÞyùÄ+¦ ýÁÔk>[’s÷¬3lFê³:ï£o|uÍyU7V¦ILÑñz½ˆÛí¾á†8ŽÛ]ßûÐkû:úã#Šìf= Ãpgüñ _¯ÿ¤±Ôe)vš!ÚüE i°’8öŸ“ '—ê ˼7Äèõú%W›Pf«oë‰ópÃxåÔâ T™K8­ž@’¦È».ÑéñöEy%T�Ÿ–¿b§qιE mž8¨0ªØ@×L+-·Ã# ͱLÉ)^%8§E—cÑlZ TQ®é`GÀ±—©­/ƉJ™ÛJð1¶Äi’U¨£?á¶éÍúHWÈf¤ sMûÛ:/qšz#ª •ºÍýQ&”àËÝfVTºÉ|»AGžHމÎw˜j[ý&Yœk:ÒF¤Ôeê ¦âŒXî¶$XÑJ: †5û¢N‹.ת?аèÉ"§ùPGÀ°—©£?Á r¹ÛNñýQ¶ØiTÔÞw[õV#}¸ó˜°oÚ4‰—8ÍÍÞˆ¬‚2·y Ê\¹ÛÌKj—?™o7tDCw$ÇD8Lµ-~#M9M ÝaAJ]&o0e„r·%ÅIÞPªÐa p¬É͵èœ6ö€YO9Íu! CKœæÎDš—ËÜæhJè‹°%N#!m}q—Uo3ч;CVU˜k:Ø ¬ØejñÅDE-s›16çÊ\&QV;’yv½QGÖw‡í&ºÐaÚßê7ÐD‘ÓÜà CRê2õ†Ó‘”PžgIórO0U£' ühO4׬sÙ ß´Ì:²Èiªë aRâ2wû)N.s›ci±7Â;Œ´öÆ\Vݬ;ÔÔ„j’Vâ2µõÆI-s›ƒqÖãJ]&Q:y6½IOé Ûta®ñ›V¿ž&Šæ£žˆ A¥.so˜ 'ùŠ<sZ=T~Žž"‰£=‡™vç÷·L:²(×t¤+„ H©ËÜH&X©<ÏO‹½a¦(×€ hKo,ë“YŸü|2Ïnð/9³\ËùѺºº‰'jc9‹_ú‚¤BNmsÿ¬s«(ƒ ¨¡¡a̘1Zʽµ¿?œî §1&žžzçUÝ¡i£ r­zUUa^·nšíÙôE�àHWèéÍœ=U”¿nÚßÜ�lÜÝ|Þ¸"‚�€¦I¢ÔilinüüPg$%¤rÌðBH ÏXA´²O,ÏùèKom5;Kî¼úÜ£­rgŒSdINúÏ^b¶;Ì4Þeq6ÑØ¶ƒ}…vúŒrÀÁÎh½'6¢À8¾ÔŒó ÝÓ̵PãŠÍ±´¸·%ˆqšÚÑEæ±Åf^T$. ¥ƒÕã&ºoˆáD¹4W÷Ð_ߺ沋ªìêQOZÁŒ.+i ñOÌ@¹fºÙ—PT¸4×à 2±”4¦Øì þ;Ìmä$µ'Ê·ë(kðÄÌzÒn${â(‚9ôþt‚‘Ç•˜z#|0ÎW囬ÜfŠzE<±e1õžEày6][ŠáÕ±Å&o˜ '„Q…æpJê0¥N�p“7î´Ð¯ïŽé)Âi¡›{’ wz‚l4%Ž)2ù¢?Êsy xÉ|›Ž&±zO̬#íFòhOFÐ"‡¾+Ž'Œ«Ê7%9ÅJåè ­÷Är ”Å@4xbçÛuý©4¯Œ+1÷„¸pBYhЦ¤¾Sš«‡`ähOÜi¡Œ4Ñà‰é)Üeѵö&D Ï3xBl4)Ž.2â@”­pDêîOäÙh‰7xb&á0SM¾!ʆî�OKc‹Mý1>ã*óŒi^õ†Ò…9:Ç<q›´ÈOŒÀ°|»¾c •d•ñ¥foˆ %ø‘¦(#õ…™’\=#=ñ\3eÔõž˜ŽÄ]6]koŠ—Àè"cOˆ Vî2È ÔÞŸp[i‰×{âFšp˜é&_B…à’\ƒ'ÀÄŽ 1nxž‘Ôž`ªÀ®# ¬Þ³êI›‘lì‰cV˜£ïH'Xy|‰ÉáCq~D)ÆÈ}a¦Ø¡ÇP¤Ñs˜(³ŽhèŽÑ$î¶éÚúS¬Æ&Œ*4iU_æ4(�jö%\V:ë“YŸü|²ÞË4òC=9nüúþî%øûŒ¯9wx³7"JÊîzßîúc“Ÿ/:£$/Ç08q4sÀý¿›r˳;eY©ï -zá3EQûÂ)�€ŽÄ˜}væ� á”t¤;|ÎØªq#+¿j í8˜TîhîìéíóO¬*nÚçÏ5Óž¶V?‹ÉÀÎ+(¥$�àZUh¥Q¡/ªS±ïHçØÂÒÆÆh4>ÛÝ\šC^zæ”p ÷âñUžÎ6%;yŒß—œ>©ôݾ^`;»X÷~ë˜ÛL]<!¯­¥I8È^:¬Ä}æðœ×6¼—L1®¢aªìÐQ„ÎhÅUŽ‹ 8JrLÖÚÏ 0\–K×{AR'—ë½ #È㊌žM‰å¹º4¯ø"¼ÃDR8Ú6ÀZ`£{QSÊ u^†ä3JL­~.ÁHÃ]úhZî‹òyV á¶Æ@ã¹&¢©•0®H¸'͋ʤRSc/“æå‘ù†¸ˆ EvZV€'Ęõ„E‡µô30W8uG¼iAR'—ë} #Èc =!’Ë:FP½a.ÇDÒÚ6ÀàZh§zQR3Â&–˜Úý\œ‘†¹ô1Fîòn …"pÛ�£'q§™hêcELùN˜¹±—Isòˆ<C !ùcB¡VT¨ÛϘô„UG´ 0@…+\úzošÕÉ¥¦ú^†áå1…F_D'ÅR‡ŽAO˜µI=µ 0ŠåоãJxB±©#ÈÅÓÒ0§>Á*¾(ï2SŠ´õ34¹,dS/+Ê`J™¡®‡aEer™éh/“âäª<C0) Ä„­¸ÝÏšt„Í@´ô3ª wëxÓ¼¨L.55ô2i^]`è ¡„X’Cóè ±6i °¶…‘Ýp¼°ñÅÆ® K‹N]’S|Þi& i`(ͳRGû¾­ú†åI¥¦æ~.ÉJ•n}8%÷Gù|+ApÛ�k¤ñ#ÑÜÏ( 4Ö­¯óWõ£ ýq1ŠshQžk5YŸÌúäÏã“¢ àoùï儨“‰0 ›uÄã7s‚ý“k¿7>M©tý×µSzuO&2M¿àÊIf=9ØøØ|j† ÆLwYu��_0©Å›üãÿ,¹,ÏnІŒ�d�Ë�ùôhlÉšvןO–™ør'Õ7æDuüè*˜ñ‡“‚ÝjÎuZÍ&…¢Ñ¨$JßNûÖ}ÕЋ„?Úõe<ž°âÂH':çÒ_{ÖB5*3|þÅ—­TUd»³èñg*ÎwBl˜ vÊ�ÖQ¸EïøøÓÆ���t÷†ZzB×Íü9¿»*À‘:Â󯻼ҭ „"ËRÊ‘^Cá‘yÔWŒ  1ô7Ý 'aN²+$„Ór¡`%µ+,Úô˜Y‡6öq† s’û»‚ÆÑû:AU.ªi€Opjqc垨˜kÆInà))É!ö° /Ò}Ùž–hDUçc”9HBêKn AP[@0P¨Û‚×ù8 …GåSû:Ó €FÐ< 'Š\ÒB)¹ÀFð²Ú¬z̪Cú8C†»ÈÚn@иBú«NFA¥‹jñó1N-Î!œâ‰ˆ#FpÓ�OâH©ƒ8ÐÃB04¡ø;aG|lZ�¥2˜’úb’Û‚#Ôô$šoÁûXGÐû:Ò² ʧö°¬*rIoD¦ä|.*jGH°è0»­ïãp©t“µ]Œ  ±…tmÃK`¸‹l ð1V)²I^鎈¦§¦~žÄ‘²\â€GFïéH‹ á¦ê{¹”�JD(%õÆ$—ǨÕÏë¤À†ö²-¤÷Fò²ŒÊsÉÞ˜HÊùV\VAGP0ë0‡­ïå0®Ê#¿î:Võû»NÃdGPˆ2r¡H jwXÌ1`F =ÚÏRžK~ãa _Dïí`T¹©Æ>.É«%9D„‘½QÑiÆq nñó4Ù‰C^áqEº=iI…FæQuš0Ù“RžWÔL4ê4áYŸÌúäÏ㓊t™F‚ V›z"M=‘£ž°ö×Ðe%3)`°1‚ÀenKæ¯<ÏZžg¥ ‚¡Áö™mAT? ɲ*+ê Eß=å@Tâ2/ùí™O½³ßãO��*ò¬÷þnªË¦Ï„A� À& ûõ(»a’ËL!]>O¡‚U…"P=‹¢0ºÈºçhßÌI¹WŸg¢ ¦–öκ6Ÿ®È�¤��P58T ” ÆAfÊëë D“çL¬ Å™¶ÞÈo.>%ª Ú|Á|o°©¡>ʼnÞÃH�ð@BìH^Z}.b-@" ÜáRÑ@ISNôöEíBbÀb6íÞ_/b6 À ä™^Àà| Ü*³ÁÁ”H«%DTAwDv`…ém4ì2"û½…Ãù¤¡OT`{ãr„UËm0+‚ž˜’g„I >: åè`§ýÚ# 8ߌò  Xà@… ŽsJoB)4Áµ¥\=l×£¼‚™„óÌÇ„XàÖ€È)P¹ ¥J-± ² º"²Ë�›h¤®O´R°Û„|Ó#P8\`FD‚Š-p_B3j™ f%ЕóŒ0#’†]F´Ö#8ߌö ( X`ODNð Â'yÕW L0Š@ÍÉ¡ƒs è7š0rÐ'à\`ÛC"+2f””ZlAT�u„d§6ÓÈáÞï„‘8œo†ˆ² Ùà„bÔ2+ÂËÀ•ÝF˜&‘†~Ñ®•p Ó„õŠ Xàž˜ã@…N ÀWòM0†BMÉ¡ƒt`"á|rÐ+à(\`;BRZå68Ê(ýI¥ÈŒ�j ÉN=lÕ!‡zE kUObp¾nˆ¢ •Ù`J ¦ÕR+"* ;"» °žDêû¿­úo…é!*´À¾˜å@… N‹ÀSò0ÁM~)GçÐÚŒ°o«¾3"§4a¬Ò—TŠÌ0A­A)WÛtèAŸ–õɬOþ«}2󔣨à• ïîi;¡£lÞe®¯;øÇ4™ÿd��Ÿü”óeCïão}=8Ù}G{Ÿy§vѬ3íf]Æ| AcË÷\sæÃÿó%‰¡÷þnêˆ"û Ý| €ã¬ZÛЧÚÅt¤«7l-}´óýà Í:×ðám¬¿µm�fS¼h•úø¸¿³?QsTÈôòŽÆ†úV¿`hë�¹ôúOöúÃöõvÖ¢<¼Û�§¢þÆÖ®–îº1hƒcùÖKç·yz„'$ò‰p_˜U‰"À¡´¼©vÀ.Dµ » h Æ#ú¾¸gמý¾bÌc}þæþP¼'¦EzÊѶ°*©p¹Eñ&@œƒFæ¨ ¦Õr àdÈ—P݈Ġæ b"!+ZC* Á&ÅS“4Ú¡ö¥@˜ì )@ýIµÀ0n*6 2‘ ) ì6ªQ5-Bcª7 ¢,¨²ƒûSj± �n ©¤ÇAS@ÑáP®t„UQ…+,J&Ì®X8˜VË,@P o\ué! ƒšŠ‘„l:ÐR˜”ž¸šà¡Q9j 3ê0+H P_RÍÿV˜•‚Ìh *8»JwTM‰Ð‡êK‚ *m ÊÁþ”Zd ·„T HÐPhMXDdhDŽêM€°«A¦ÕR3ÈU]zˆÆ æ b û·ÂŠLJOhÂÒPˆQ+¬€‘ Þ„šo€j* ²P 9¤bœgTºcjJ8NXŒƒRj¡ 0ÜTshÈ@‚¦ Bá°S¯vFUN†Fæ¨Þ$ˆ±Ð»bá@Z-1Y…ºÂªSÑ8ÔT2U¯¨p‘YéI€ÌQý J«åÀJPoBÍ3@53 Y)ÐRQÎ7~Wõ½)aÀpˆ ð@R-4›ƒŠ†Lš0 véÕΨÊJШÕ÷mÕ‡98RKÌ@p[XÍÕA:4–õɬOþ«}’‘`ý·¼$)'Ç�ÀŸ4Þpñ¸ãƒÊ‰1gP �ßc Aïîie�pÑÄ’I•îoí“dåÓCžÙŽÎ±è¿g,'“âè’œUw^„ °Ûf8¹›OVY­!Uæªl9Ó¢N‘ÌpYÓGª¬?ƨî8Ö!8TÉ åÀ$N3 ^Û'(޳ZS”b? Fèú¤¬:͇ûUÉ~6¬R}1IUŒ‡@…¥…y¹¿*)$éÃ/¿ñ’$z‡*[€Bp¬"@ž¨ÒÅ[Y 2ÁÑ®¥€°‘8ÔË\  �f¤�N&¨=¢Š ïà›"'6Á›Àb<\lÓ"Ô—Bì”D"jg%Å­—š#¸¤€ ¾1Lð2cç;£DR„ÊMBŒGÒˆ“–`tÆ&çÐJ[“0ÊÎׇAã|s„`$0Ü"ÒHó ¢¤@¾$b"d3®´G1¥&¾1BˆòqÂ|I,ÊÁEF‘¡¾b#%U;¢«ùz©9‚‹ƒ„¶óÝq"!@e&!Î#ýiÄIK(:c)Zjâ’&Øù†!È`œƒo‰Œ†Yă8Ï **ä"F\6“J{�”™ù£ác'¢ «² }),ÂÂ…F‘“ Þb%eU:¢«…F©)|œ°Qv¡;Ž%¸Ô$$x¤?äÒ«Q”D'-µhÂrùÆÁË`\ß%Ò"¨0‹añ§a·^*èŠ"\¶’J[SU0ÒÆ7ÆJ Ê*ô§°0 EA†|IÄBÊz\éŒb¤}+,s"#mBO‹óp‰QH pÉ¡$üÛªw饖ã«~lß%R"(7‹ñ§a—^�tF=.ÛI¥5Š) eãÂÇU}¥Eð§±DQ†¼IÄLÈF\éˆb0ŠÂÑã…e}2ë“ÿ"Ÿ›Ãv¤Í øþßOýëÆÚBÎò?üzp#Ÿ™kp×Ì3n}fDZ�h³ ®>ÆH'Gû~7õ–§?_á\0s’YOšôÄCë>ŸsјŠ|ÛqDgœqÆîÝ»S©ÔP¦l_ù_›@îèŸáeéŽ/…X/J[¨üñ¨!çŸLB” Û§U¸‡Å4_Ç©�ö¦ðR°‘rsŒ2`R™‘?Öш<ÌÌ5Dt¤”¹~†H‰H¡žãd¤ŸÁ\¯ÃÕö8iĤ#_ÖéPy¸™=Ò“ˆRf亓$/CE.)¢AË£y ]I‚‹yz±!BëQ¹ÂÌ é(D)7±mqZVA±‹ðX”Gói@pO Ï!;)7/¬ÂÌ5Fi¨¥ß +Ðq‚ ÷¥q'%p¥í$a‡BzQÊŒ\OŠä$¨HÏ¥$4Àbnš'PЙ ̸X ë #¥ÜÄvÄ)I…Šõ\TÀ"š§ã`ò¤;!æÐRS”2 R™‰?ÖQˆ<ÌÌÒ�%ÖÏI)Ðq¢ ÷¦ñ\J0áJëñ†™¹º°ƒ”R#çK¬ê9FFÌMóªv$H3&„#ZÊÃÌÜAM˜‘ëL’¢鹘€…94_ÇÃ0ð$ !æÒÒÑ(e@¥r3¯•­/³Í�� �IDATp…‰mŽÑ�€à°¸€è8Y…}iÜA Rn‰QFL*ÕJ•‡™¸úˆ…”R#×›&Ò\¨çµªwÓ<ªí Ò„IEFáH˜>¡ê»’¤ CÅ..b!ÍÓñ( º“„]:±1z\Õg}2ë“?ƒOv&p2Ññâ¢ÿüáF>³ñ /Üzë­ñx|(áÕW_={¶6£úGíQ2e ¾ÿÑéû·µk?ÃYv®qâïéªÿ€ Î2)Q]4Û‘¤xÉ£™0yÂE±² u§(;Á0¹1¦7b’“âG $¢¸h®9N+�rÓì�KD<bXö1¤ƒäDi‰ë̸˜Kñ‡ÂFU\×Õ£0pS¬7M$%,Ÿf’"ÚÏ’¹Ãj{’¶â‚ë"=&;)îHD#ª‹b;“« yá±�G¸HVP×1aR÷Âê"Q]4×§eΣY?‹GÜM1¼{Ó”ƒäIDnþN˜B'Å5Dõ0 ò(Ö—&â"–O3I ícÉ\’C`µ-A[p!‡G :TvR\}DÁÀM±ÝIŠQÐ<Љ ¨Ÿ#œ«¨3EÛÁ„‹ Q½“œ4_ՈꦹÖ8-©pÍ8<ÌÖ“¦ržF妸΄‹¹8rLØÑ˜‚ 7Íö1DLÄóh&-!½ ™Kr¬¶&t\Ì¡øCaQ&Ì“"ÓšG1qõs„‹b�IÚFf\¬ê ˜”KóuMÛž¤Σ™ ‡…xÂM1¢yÒTÁë0ùhLoÂ$M‰*.ŠkŽÓ*¹i¶Ÿ%¢"žG³¬û2—äpXmI|WÂ4*»(®þÛªïI“) ͧ™¸ˆ°„“b! v$i+!XIñHôøªÏúdÖ'ŸLJØàÑ“ÔÈï$´åãý‘éw3Ö†8…@@ð/ëOR‘~V‰R*ÈŽ*$ã‚‚t§õœ!`¹-e0 ‚ã:RydÒÇê’^JGƒ<äÉ*–’1/£s)RÛRFÆQ¡-eÄaÅI¤<Œ>-c%Tl€§ÃYJG£"ÙËÒyd�Б2X1N‡ŠmI#…HvŒéfô‚Š’ñ~ŽŽ‰Dˆš°„ "Ýi}Î1aF=*jÂT�òÈ„Õ%$¼ŒŽy*ÀSÅTŒ‘±Fç$Ò(¤´§Œ&”7¢|{ʈÁª‹Hy}ZÆJ©˜Ÿ§ÃYFGcÑËÒn" A #e°`œ[“F ‘8ÓÍèy)¦bý<ýVX?G I…»Òz;ÎR°Ô–2êPц±iƒ¢Âùd¢—Õ%$¼”Ž…MX\–K¤qXiK¨`Bùö”T‘ò²º”„•RÑ�O…²”ŽÆ%ÂÇêÜD †Ôöc„¶”‘Dd‘ö0zVÆŠ©Ø�OGDB+á>ŽÎ'² w¦õ6œ¥©-eÔ!’ c»ÒY… ÈD/«‹‹x ”Ÿ§Š¨8§ FïÀVÚS*˜1®#e€!G¤ŽU=u¬êK©XR½¬ÎE¤HmKÌo@…Ö”‘€å\"íaôÌ·Uˆ2:É>–Î'“Š w¦ 6Œ¥©-i¤U½AT‘B2‘õɬOþL>IE4Þü£ßå Ñ2��¨°°pÑ¢EŠ¢��$IÂ0ì„^©Œ�@o(©"ä/ôª"²2� a‰WU…pX–UHVaR H‚T’y=Þ^ä�‡%Y…eF!@TR±“ì3,‰*¢¨˪ I*Œ@ )‚‚B@%`‰S°†@ ©‚‚@J@2w’0^AÕã„;‘¡ ƒd�IE2Â�PÉ“„°$¨ˆz≠E؉%|ªÂ`HA z «‚‚@@%à“…I¼‚üa8,I*¬ü³UŸöãUŸõɬOžŸ„EQVr-:UUOnÒOÞ‹ÅÌf³¾×~ðÇx<n43)¯±(Š8Ž«ª*ËòSO=…:ŽÛn»a†wîÜyÑEe_÷%K–,YN }ôÑe—]–J¥vìØ!IšùB§Ó]yå•ÙÊ’%K–,§‹+¯¼²±±1//ï¸ßå€c?ÒT8ŽË–Q–,Y²d9-<x°««ëûCŽªª‚ dË(K–,Y²œ<ÏàÁ8["Y²dÉ’åç!r²dÉ’%K6ädÉ’%K–lÈÉ’%K–,Y²!'K–,Y²üû‚ÅÈçó½ýöÛ'ìœ={öúõë§L™röÙgÿ´¼?ÿüód>þö·¿u»ÝÚö›o¾)Ëò¸qã>úè£Ù³g�Ö¯_ÑE5j()÷ôôlÚ´é’K.6l� ¶¶öË/¿�”””\qŧ½wîÜyäÈ‘ÌÇ9sæäääülU˜L&ý~æ£Ýn7›Íz½>77÷'$xrugJò_JCCÃG}¤m3æÂ /üÑC¶mÛÖÕÕuûí·ÿ3ù~ñÅû÷ï�TVVΘ1ã„oW®\9|øðêêêþ÷ïßÿÅ_d>^vÙeååå?zÔš5k .¹ä’ÓRÈ;vìhii™?þ¡C‡víÚuà 70 óöÛoϘ1£²²R»p��EÍ›7�ðþûï·µ{Ýýo~ó›²²²SÊî¹çž«¨¨¸øâ‹‡büúë¯#ò»ßýnˆ%yÓM7™L¦l#~Úéêêz÷Ýwµêîèèxï½÷®¸âŠ’’’Á6­­­|ðÁUW]UXXxúŸr<OMMM8®„$I555Ÿ~úéO>±?þ¸¦¦¦°°PK$¿{•κuë^|ñE£ÑXQQADMMÍÁƒ‡˜rwwwMMÍÑ£Gµ_~ùeMMÕjÍ„´Ó˶mÛjjj2%CÄÏéÉd²¹¹YUU½^Ïóü‘#GR©”N§\ž§EQ™sEqpIþëðx<wÜq‡×ë­¨¨@Qôî»ïþüóÏô¨Í›7ÿå/ùgò­­­]¸p¡(ŠF£ñž{îÙ¾}û Ë—/ß²eËi9ǽ{÷ÖÔÔ˜ÍæŠŠŠæææyóæ…Ãá=ª´´Ôår®rÞ²eËòåË�_ýuMMM(Ò®îÆÆF–eo»í¶ƒVTT<ÿüóO<ñÄ–-[î½÷^«ÕZQQÑØØøÇ?þ1‹ =¯åË—/[¶lñâÅ™;‰æÅ_\·nÝP,-KEEÅÉoçÊrZhoo¯©©immÕBKMMM{{û 6G­©©éîîþ—<åhL˜0áÒK/ÕâÁ3Ï<³~ýúL“wå•WJ’IJìý÷ßÉ%—d] 3fÌ iZÛþæ›oæÍ›·`ÁI’´?üð›o¾yÛm·�ž|òɳÎ:k(7†S¦LùÓŸþt÷ÝwOš4Éãñ¬\¹òé§ŸþÛßþVYY9zôè… 655I’4sæÌ;î¸ã¢‹.?~üÓO?}Ûm·y<žíÛ·?ýôÓ¯¼òÊÞ½{õzýÐOD+�À¬Y³`ž>}úÊ•+×®]{Çw˜L¦T*õâ‹/ʲ¼}ûvA¾øâ‹¢¢¢sÎ9çõ×_—eùƒ>À0lÑ¢E²,_~ùåóçÏÇq|è¹[­V›Í&IRWW— MMM¹¹¹>Ÿo„ GŽ)...,,<ùõJ'c³Ù´sñù|K–,¹ãŽ;¦NzñÅó<ϲì½÷Þ{é¥—îØ±ã‘G¡i†áwß}÷oû[qqñK/½ ¯¾úê®®®C‡3æ/ù EQCÑÏ0LGGÇÌ™3§NZRRòÜsÏùýþp8<}út­ôÖ¬Y3vìØuëÖ½öÚkAäçç¯]»V;VÅ^xáÍ7ßÄ0¬´´tÕªUúaz{{ÿûß_wÝuwÝu‚ ÕÕՆ͙3Ççóñ<ýõ×Ï;W³L§ÓsçÎ <Ïß|óÍsæÌÑ.Y–wìØqèС¡×Ô\PTTÔÖÖ¶qãF†a¾úê«Á%‰¢è‚ "‘ȵ×^»téÒµk×>úè£S¦L©¬¬üãÿèñxA˜3gÎþð‡iÓ¦M›6Íår½ñÆ~ø¡ÃáJîz½A“o2‚˜9s¦¢(Ï?ÿ¼Éd:ãŒ3PÝ´iS8ž8qbQQ‘ÇãÙ½{÷з—N§?ÿüó½{÷~òÉ'õõõçŸþÔ©SÏ?ÿ|»Ý¾aÆ?þX§ÓÕÔÔìÞ½�pÎ9ç<ôÐCÚo½õÖòåËßy犊ŠõëׯX±âïÿ{WW×}÷ݧÓéAضmÛîÝ»Ÿyæ™qãÆíÞ½{éÒ¥4M«ªºeˣј ÿ"𛛝½öZƒÁH$6oÞœÙÖYgMž<¹°°ðõ×_ߺuëÞBl¨¯¯ß¹sçÁƒ“ɤ×ë•eYÛ¯] »víºòÊ+¯¿þú@ pJgòé§ŸîܹsçαXì’K.™<y2Ïó]]]�€T*åõzEQÔ—»ï¾{(ñ�@„Éd ‡Ã’$qÇív{ ƒ«V­Ú°aÆ |ðÁšššÏ?ÿ<??ÿèÑ£]]]Á`°¿¿ßï÷×ÕÕåääœRàÔº×vîÜÙÛÛë÷û?úè#­Cæé§ŸþÏÿüÏ]»vMœ8ñ’K.áyþ©§ž7nÜ–-[¶lÙâõzwíÚ•H$n¼ñÆ5kÖ¼ùæ›ëׯ_ºtéc=öÉ'ŸœRî±X,$“I½^a˲¢(Š¢È²loooIII}}}"‘8¥n®3f\sÍ5555K–,immݵk×ÕW_=wî܆††k¯½öòË/ßµkW__ßm·Ý–H$®½öÚ—^zé¾ûî{øá‡/»ì²ÿùŸÿyýõ×_|ñÅ!fWUUõꫯîÞ½{âĉï¿ÿþÕW_}ÅWØl¶]»vÝxãO=õTGGÇÎ;üñ­[·~ðÁþóŸµc÷íÛ÷ÐC-^¼øÝwß}÷Ýwÿú׿1SI’Âá°Éd"EÑ‚‚‚U«V}ðÁ[·n]°`Á’%K2Ö?üðG}´sçÎÛn»máÂ… ^¯wõêÕ»wï>|ø)ÕÔž={vîÜÙÞÞ>f̘T*uBI>ûì³›6mzôÑGŸyæ¯×Ëq\ooo8Öž9¶lÙ²hÑ¢ûï¿¿¶¶Öçómß¾}Ĉ‡cèÝÅ+V¬¨¨¨øæ›o´²,8p`îܹ—\rI Ð.�€ËåÊÉÉ™7oÞâÅ‹|ðÁ+®¸¢²²rïÞ½C l�€?ÿùϵµµùùùV«õÑG=xð ÏçÛ¶mÛØ±cm6ÛW\±gÏžÖÖÖW_}õ¹çž[½zu¦/×l6˲¼gÏžX,vàÀ£Ñ(IÒUW]UYYùæ›oNœ8ñÙgŸÕš p8ü»ßýnÔ¨Q6l¨ªªzþùç³á4RWW·sçκººL?pUUÕ®]»Š‹‹ó›ß ¾oÛ±cGEE…Ûí¾üòËOOÇšFGGGmmmSSÓ÷Þ¢>ñÄ{öìù 'öÍ7ßÔÖÖÖÖÖ¦R)mÏM7ÝTQQñO–×äÉ“3mÁ™gžyB‚kÖ¬y÷ÝwµíǼ¶¶6óqß¾}ï½÷žvëtª]4µµµÁ`P»bŸxâ‰7¾õÖ[F£ñ‰'žhllJ"/¼ðÂ;ï¼óӺעÑh:¦iE{x9räOHð™gž‰Çãÿõ_ÿõ³¹ø\°qãÆ¥K—Κ5ëöÛo<<öÇ?þñ7Þ¨¬¬\²dÉ×_ýÌ3Ïœ|øûï¿¿jÕªŸóš;vìêÕ«ßzë­S:êðáÃ6lxóÍ7/^l·Ûµ·'žx"ãÿ��»Ý¾xñâMêœsÎ9yðéGEñÁÔ¶yž_ºtéß}÷Ýo¼ñFIIɬY³xàÁ"‡èEÛ¶mË|<ï¼ó2ã:\pÁ-·Ü²yóæ¿ýíoƒ¹øâ‹Ï;ï¼%K–´´´¼òÊ+wÞygIIÉâÅ‹“Éä}÷ÝW^^žñI’$/^ ï¿ÿþÑ£Gßwß}Ù8qimm­­­Õº×4ÚÚÚžx≓;ÓÎ>ûìLÏéìX»üòËgΜ �xöÙgOø A‘#GŽ9òÖ[o5›Í§tb÷ÜsÏ©6îCaêÔ©UUUwÝuÃ0Ó¦M;áVtذaS¦L¹üòËÇÇóüiÉñþûïÏlçååiÎ÷Ýwß矾téR­áG6lØÔ©S/»ì² &œRî6›Íçó>|˜eÙò\¶mÛ¶oß¾šššŸÍ¿=Ïý÷ß?wîܹsç2 óÐC>|øäk`þüùçž{î¤I“NN!??âĉëׯ?Õ!îŸÌ„ ÆwªGÝ~ûí:†á§Ÿ~Z»1ÏÉÉ9rä /¼àp8>þøãµìššš?üáÁ`pýúõ«W¯®ªªÒfèœÌ{ï½÷öÛo¯\¹òÏþ3A7n|ä‘G†ÒÛ¼oß¾mÛ¶=øàƒUUUãÆaÙ²e¢(¶Ùµk×Ýwß}óÍ7Ÿ0. �¸õÖ[÷ìÙ³lÙ²‹/¾xÚ´i†ÝÿýÚ<‘ššm¨Rë¼ÿþû;::æÍ›÷þûï§Óé¡Äé,CdÖ¬Yÿñÿ±}ûöÌí¸Ñh9rdMM MÓ§4ª÷Ÿrþf³™ ˆ‰'666>úè£étú”~¿ßï÷‹¢hµZ9Ž{üñÇOx–BQÔ`0$“É?üáCOù©§žjooÇ0ì®»îÊìÔétAŒ3†çù‡~¸³³Óår=ûì³Ï<óÌ 7ܰnݺ… .\¸pÊ”)§¥ÚšššôzýĉKJJ‰F£ÿÈR6zôhI’~øáŽŽŽS½uåy^’$EOµKðöïß?oÞ¼¹sç^xá…ZÕðßïO¥R&“ EQ³ÙœN§µ™r§eÖÃ0_~ùecc£ßﯪª¢(Š¢(«Õ*Š¢ßï_´hÑ\ u´–””L˜0Áb±0 £½…Çq½^_ZZ:lذx@›8òóóW¯^½víÚ?üðàÁƒ'Nܾ};Žã@ ‘H †Ì�µÑhÄ0Ìï÷'“IƒÁpÂsä©b·Û‡~ðàAžçÍf³Ûíž8qâ_þò—wß}Wsƒæææž/õz=ŽãÁ`0kÛ?9÷³Ï>;2 3cÆŒºº:«ÕZUU�ظqcKKKMMßïŸ>}ú=÷Ü300ðÉ'Ÿx½^EQÜn·Ùl¢kõõõuuuyæ™3f̘1cFqqñ¾}û/Á�…BÁ`°ªªj̘1ÚÕ­à�ÆŒSPP°oß¾âââ¼¼<Žã¦M›öÚk¯=ýôÓ.—+sßH$Î>ûì 6¬\¹ÒjµffÖeùW`µZÍfóĉ7lØð / þêÓO?]·n V«õô<åX­Öêêê̸PIIIuuµÑh¬®®®¨¨x衇n¿ýö ��ž{î9›Í6ÄsÐæž.Y²Dû¸lÙ²;v,^¼xüøñ7Þx£(ŠùùùZF¥¥¥ëÖ­{ùå—üñ¡—‘Åb9ÿüóN§Á`Ðz! o¿ýv†a{ì1�À½÷Þ«…–ÊÊʳÎ:«¨¨ÈétNž<yìØ±§4ëlĈƒ'ÑžuÖY™¦jóæÍsæÌY°`Áí·ßŽaØë¯¿®•$Š¢ÕÕÕÚÌãsÎ9ÇétÞzë­étZ;ÁÅ‹ŸuÖYCÌ ˆÜÜ\¯×ëõz�ãÇ7›Í‡Ãh4Â0¬Í“¦(*77wˆ ¥^¯Ÿ:uêþýûµ©Ã�€»îº Çq­Šß~ûíQ£FmÞ¼yÅŠ ,8ï¼óÖ¬Y³qãÆêêjÇGuuµÝn§(ªººúäØDUUÕ+¯¼òâ‹/îÝ»�ðÈ#Ìš5kæÌ™¿ÿýïµ|_}õÕ‚‚‚^xáµ×^ûòË/·nݺlÙ2­æÌ3Ï|þùçßxãíÛ·Ïš5릛nb¦Ú”\UU_}õU�Àõ×_?þüeË–i>ù /L˜0aúôé£Fš7ož  .�¬[·nÔ¨QÕÕÕ#FŒ8¥‹V»p´ù¥¥¥ÕÕÕùùù™’¬ªªÒÜ’eÙ·Þzë‘G™3g�à׿þõ¨Q£îºë.Žãxà�ÀÚµk'Mštá…Ž=�0eʆaNá6†«««+++�Ó¦MË ¹—””hÃH ,(**Ò¦f|�°iÓ¦!Žå¸\®êêêLTYY©] ÚÎ<óLQgÍšÇ_zé¥ÌÕ­M^ÍäUYY©‰$Iò¥—^Z¶lÙÒ¥KÏ8ãŒuëÖmÙ²¥ºº:77wÍš5Ë—/?räÈ9çœsB;˜åŸ¹%ª®®Öê:sEoݺ5ÓοüòË ™*þõ¯a˜Õj}íµ×~4qèŒ3ÎØ³gÃ0Z»œL&³%ž%Ëÿ_|ñÅÞ½{ï¼óÎO?ýtΜ9ï¼óίýëÿƒåðâ‹/nÞ¼ùÃ?̺Ŀ9EEEÓ§Oùå—ÿ‘ÁÖ­[eY¾ì²ËvìØq×]w¡Ù"Ë’åß—˵cÇŽ¯¿þ:‹]sÍ5cÆŒù?XkÖ¬yâ‰'Þ|óͬ?üÿG6ädÉòoDyyùæÍ›µ)-z½^'ÿ¿ÆìÙ³gΜ9ô ÙYþÙ¿ÿ) CdCN–,ÿ^œêœÏÿÿ0ÙuþR8Õ;ƒìk=³dÉ’%ËÏD6ädÉ’%K–lÈÉ’%K–,Ù“%K–,Y²üŽ›>N§‡¾@@–,Y²dÉòäÓéÁ ©|rTUݶmÛÀÀ@¶Œ²dÉ’%ËéâûCÎ;3J¥Ni…˜,Y²dÉ’å‡V¾ 9‚ \uÕUÙÒÉ’%K–,§íµ­'†œ,|>ŸöŽä,Y~qL˜0a(k¿fÉò¿B6ä|~¿_{s¶(²üâÈÆ›,ÙóËÃáp˜L&UU³E‘å—Â7ß|£­%K6äüòPU5r²ü‚Eñåy¾¯¯/[2?ÌjO}}}§kíàÿkØl¶^—÷CNOOÏK/½tÂÎÛn»míÚµ¿úÕ¯.ºè¢liþ#V¯^¢è-·Ü�$I[I �0þüœœœ={öh«€”––Þx㙣vïÞýñÇß}÷Ý~¿?³|eeåìÙ³ÿö·¿i+!NŸ>ýœsÎÉòÊ+¯ÄãñÌš§Á`påÊ•3fÌhllôx<³eË–:tèïÿ»öqÒ¤I—]vÙêÕ«ûûû�W^yåøñã3ÕãøC=�ظqã‘#G��Zu³,»|ùr-…»ï¾Ûd2}öÙgŸ|òIF$� ?ùä“'ˆÔ¨¯¯ûí·µíqãÆÍœ9óå—_æ8îŽ;îÈ:Ì¿ŽT*ÕÚÚZ^^ž-ŠŸvÓ©õR8pàT—ãË’)á>åô÷÷¯ZµjáÂ…çŸþwÖ(ºjÕ*A²!ç{Ù¾}ûêÕ«:TUU¥…œùóç×ÕÕ­X±â©§žºá†V¬Xqçw^uÕUgœqÆ­·Þ AÐ 7Ü��8tèÐüùó=Ï­·ÞêñxV­ZõÐCMž<Ùjµ®_¿~éÒ¥+W®ljjš?þ+¯¼2~üx�À«¯¾úÈ#Øl¶Lȹá†öîÝ›——wÖYgiË)®]»vëÖ­?üpccãªU«ž~úéòòr§ÓùÜsÏ=ùä“ëׯߺuë­·ÞúÆoÜtÓMÅÅÅ7ß|ówÜÁ0Ì”)SxàG}4 .Z´hÍš5/¿ürOOÏ#<²|ùò›o¾ùž{îY°`Áõ×__^^þ§?ý A–––={öìß¿ßb±œrúúún¾ùæiÓ¦]~ùåàÛWÏnÚ´)™LfCο»Ý¾wïÞ?ü$IUUEQ”$ AUUQ¼8´¢(0 C¤µ³ÚWZ“¡­? ð,Ë��A4cI’2m A0 kû3f–E HKSQmÙ\m§$IAh ²,k鈢¨‰Ôò‚ H–e£Ñ(Š¢ ²,#¢IÒ¾<yòÁƒ%I’$ †aíÔ4µ†i;5KQ ‚ÐÒÏÄ‚´µ½Y–=ï¼óÎ=÷ÜòòòÁ£bf³yÑ¢EZ‚ßÛÿ¡�@–åLÑe AËë{Éøà=?°à7ÏóZú™aþôE9A-‚ ™:ÒÿþÞO>p°ÂXb˜¢(‚ ´ÍÇ ˆ?Ò±6lذiÓ¦�^|ñÅššš>ø@Û?00pùå—SFçÏŸÝu×ý“«Áÿ{vSü÷ÿ÷ÚµkÍf³$I›6m‚aøºë®cY6•J]sÍ5wÞyçgŸ}¶hÑ"‡ÃáõzwíÚuá…þêW¿ºøâ‹3‰<ùä“ñ<O’d<ïêê>|øôéÓëëë5/Åb+V¬øío»bÅŠp8|Ýu×]wÝu3fÌ ¢¤¤¤¼¼ü7¿ù Aýýý©TJ«¿>ø ‹92óÓÝY³f=øàƒ3fÌ��hëz½ýöÛ}ôÑ–-[š››ï¹çž?ýéOS§N¥iº  à–[n™;w.‚ »wïN$‚ 9r䬳Κ6mAõõõ£Fâ8În·K’”N§yž?|øpYYÙ´iÓ6oÞ,ËòÞ½{{zzªªªÆ‰Dzzzî½÷Þžžmaï¸þúë[ZZR©Ôœ9s®¾úê‹/¾¸¢¢¢¡¡A–å+VÌ;wöìÙ¢(&‰Ù³gß~ûí™å7ººº.ºè¢9sæôôôìÚµë½÷Þ»óÎ;�gâĉ7nÌF”¡ÐÑÑñõ×_koæúÏÜÂkÍ(AZ„㸢(Š¢¡5:3ÍFkÍ%IÒ.ym§,ËÚ‚èn·ûСCZƒ¥5ô™F&á;�� �IDATAQµÜµ=ªªjq A-YM ÃZØÐD-A´–NkÓµWÛ@QtïÞ½Zâ(ŠŠ¢¨å+˲–…&RKap DQ”ã¸ÌYÀ0¬ªªÓé=z´ ƒÀ˜J¥öìÙ£éQUup¨Î´ãZ²’$RÈÉĪÁ úØswrÈÉŒ“'|oÈÑÒ×ê(³ó”BŽvÓð½9Ò4M’$˲‘Hä{Î÷‡µ¶¶vãÆŸ}ö™(Š©T*£à¾ûî »víºîºë-Zôÿå; zzz–,Y2iÒ¤·ß~{ܸq[·nýôÓO vîܹpáÂåË—744\{íµ^xá®]» ®»î: Ãôzýàûš¦Óéô’%KÂáðæÍ›µ_}õÕ¦M›8 …œÏ?ÿüÌ3ÏÔ¶q¿ôÒKY–}ê©§f̘±gÏÇõzýúõëŸ}öÙ•+Wþ?ö®<.êr{¿³/ì›" Œ²‰¢à‚ ¥©¹å†KÞ\Ð{]P3QÊ45--5ÑH-×,½”¹€¦B¥ä.Šû†"ûΠ̾ýþ8Íù½Í #îÊóéÓg˜ùîΜç=ç<ç9QQQR©ôÁƒø-¹|ù²Ýo%‹O:ìååeoo?pàÀÂÂÂU«V 0àÂ… <O(&''ÿòË/[¶lñ÷÷‰‰¹sçÎÞ½{>ß±cÇÀÀÀM›6íÙ³§S§NmÚ´uÆÞ½{8À`0ÜÝ݃‚‚²³³8�gäóùB¡Ðì“ܰa!dÊ”)aaa€šÓ§Oöññ™7oÞ—_~yîܹ¤¤¤äää›7oÒߥ÷ß_$EGG_¸pA*•gee­X±ÂÆÆÆ,¶YÍBrC«ÕÖ××Óàθ-.— ø›Ë†%0‡Ã0èX!æÐjµ�¾ë€Ïe2™~~~¶¶¶J¥~àËàÛ ûB¬Ãd2y<†/ˆ\.Wåjµ® ΰ¤R©�· ˆÁSÓ~ÙßߟÅb!fÀôz=Ü2b†)–<±ÁCãp8p/`OXø¡ …BLJ»†øõÅ»8&¦R©ÄbqCpõˆÐ¤®®®¢¢6¹\>þü .4áŒÄ²eË222æÎ6aˆH>ýôÓ›7o6ò fîܹeeeëÖ­kÑ¢E^^<ÕÂÂÂ%K–|õÕW555uuu³fÍZ½z5!ÄÎÎî»ï¾ƒ}SRRºvíºmÛ¶/¿ürõêÕ?­[·®}ûö½{÷þöÛo !¹¹¹GŽ™9s&8°¢¢¢­[·~õÕWPÅc:99íÚµ«C‡ëÖ­ÛµkWJJJ—.] þôóÏ?WTTÀ·öèÑ£gÏž=þ|QQÑ AƒFŽ a_EEÅ?ü““óù矯Y³æìÙ³f2elݺõŒ3† ïíím´ALLL—.]ÒÒÒàÏ-[¶Œ5jΜ9V,i¤'ç‚éÀÌhñx<¥R‰ :2À@”N§lÀhƒÉdÞ½{÷Þ½{ô¾°Žf±XàÙÙl6œ ®01��¼ ×F§ìèLb ŽV«7)8Üór øî»ï”J%‘Z­–Ífã}ajÑúy~öÈyóÍ7ãââ!)))¦àÖ¿ÿþýûBÜÜÜšÞ£qpp˜:uê;ï¼3vìØ#GŽh4;;»eË–íܹ“Çãeff6æ Ó§O¿uëÖ®]»D"¾Ù«W¯^½z-Y²äôéÓùùù>Ü·o_QQÔc¸\îèÑ£ß{ï=Øxç΋/Þ´iSll,¼³}ûö?ÿüsÍš5ׯ_W*•ñññ*•ê÷ß—Ëå„7•Ròòò¦OŸ>}útH»B’““W­ZuèСxÇÝÝ}êÔ©„mÛ¶5t/-[¶œ:uê©S§þûßÿ~þù祥¥Ë—/šçíàà0}úôÇÿøã~~~ mü믿fffb‚×j\÷p86› ü5–pK5ªR(€àÜ! Â|@8wtú�36�z½þÚµkP,Á ƒ®áft]Ž& ¡<x�Ç@ n B4ÄB•J¯ÙlvÏž=OŸ>-•Jõz}ZZ„Yp6›  O�pH­Vs¹\+ä<W{Âá<ÏÉÉ)==}ÆŒb±¸é=šÂˆˆˆíÛ·óÍ7\.W*•Êd2Fãäääáááä䔟Ÿïíí][[{óæM…BAƒ Ú•+Wà×{óæÍÛ·o …ÂfÍšß¹sG(º¹¹mܸñàÁƒiii£G&„,_¾¼   '')OOÏ‚‚‚šš@póæÍ›7o‚ÚwZZZZZZHHH‹-þøãS§N¥¥¥­]»–2a„€€€¾}ûÆÅÅ7A£ÑÜ¿?77÷æÍ›|>¿yóæyyy2™ŒÃáÀ1ëë룢¢nÞ¼©ÑhZµjåäädooÿþý‡:;;ÛÛÛ‹D"©T {{{Ÿ9s&44tË–-wïÞµµµuuu5½÷xxxœ<yÒìãõööV©T[·n‰‰ñññ ›3gŽL&Ójµ—/_öððøá‡D"‘\.߸q#püÎ;7iÒ¤I“&iµÚ‡Z½]W²ÙjµK÷�Ð× $¼‚XG¥RÁö’€Á²ÖäU*À8}̧A…J8jµ>…Í09¦P(ðO¸Zú8€� xF€4@>ä5@¾yòäI¹\·PZZ ¼�$¹\®P( µˆ7…AXC‰2.—Ëår9ËÄèúÑf€ ð„-ì± —ËÅŒÞx´Á¿"=}"ãÀ  Ä§Êb±8ŽÀĸ³€¸ðpŒLn0¼•J²Ç‹r\]]Gމn´M›6#GŽtrr9rdXXØ»ï¾Ëd2“““ !ßÿ}“lÔ÷òòZ¿~ý–-[Ö¯_?~üøO?ý~ß~ûmçÎ?ÿüócÇŽýüóÏË—/ONNn×®ÝúõëaÇ·ß~S‘}úô)..†ÅãñÖ¬Y“’’’––výúõÄÄÄiÓ¦áéÂÂÂFŽéãã³{÷î”””äääAƒ-_¾üÀ#GŽÜ¾};l–€|Í7ß|Ðþtss9rdPP“É8p`ÇŽágéïï¿iÓ¦;w&''Ïœ9sÞ¼y;wîT©TpU„ ìÚµkåÊ•ÉÉÉÑÑÑkÖ¬Ä)ä²V®\9gΜäädww÷eË–9;;õ;wîã?†¬£P(9r$^ž§§ç AƒÜÜÜìììFŽ ¡áÇ·k×¢±„„&“™••õå—_BýÝwßäçç4ÈÛÛ{ëÖ­Ó¦MsppèÓ§OZZš³³óСCóòòÖ®]ëçç7{öl+œ4Æ´:·ߪ0äÄ0‚ªÒéØ,–b&S­×3 Ñ3™[Ûúúz “I u{µÁ¿«u:“©!Dc€€ƒðwÀÁbéôz™VËf³5jµšÁ€˜‰AˆV£!†‹ÀŒÁ`±X½^­Ñè98F'2ŽÅfë !±ˆ…Q“É„ %†œ!!DÇ`è8�$­áÆY,–žÁPS…¥¿CÀö홨|Y¹¦æˆˆÈÎΖÉd0`€õ÷I¹pá‚¿¿¿½½½µôåZrr2›Íž6mÚ´iÓÒÒÒ¬“5,ÛéÓ§ÛµkG󬪪ª<xVS³õüyLv1Ñéõ,,™^ 3e¢×뙆,W`_­NÇ„* D,ÖßÎÝàåÙ,lÃ0äÇþŸ 1ƒÁ`0˜ †N¯ÿûSBà—Æ öâr8z½ðèõp :Câîï‹4ܦN§c2L‹èõ &S­Ré á°Ù:½îEGf0L¦N«ÕéõL&S§Õ²9W—’ÒRL2™ÌáÁÁ#]\è'yàÀÐÐPì Ápª‘8¡�lÓņü“H†N\¼Âo@G"©Pj"@ ¥khØPlÊXà }at©³Z­ªÑÑÑJ¥d=92kÖ,«ú€Õ^]ëÙ³gÿþý÷ïߟ——·nÝ:ëy2ãœ8!عÒ5à!È�×i7,×ÓD2HŽ©Õj!H÷B6À ‡Ã>ô’vü]2$ÙðM–N‡5(Ü# .®3NH¶fjµÚb±XJ¥8ÖX—‚íáz  n„Íf¿óÎ;wîܹsçŽF£aøÓ.W­VË[xnlƒÍf»üë_¤W¯gP´0´Ë ƒ6ë©•J%<ˆçŒ\üã"McL§ÓdšÅNSÈš²š¦¡RH,²«‰UðÆ‚ÕÖÖ>CƤ՞ÀZµjuþüy\CÕÔÔXŸ‰kH”…Á`( $@#� ³ »dÐëÁÆÈ6ÆJ;äÊàˆ @†ÚÔùy<žV«ÅÒ íž ž TcznÀý 3L&¦Ô0Ë娀„4¸x¨›õè�püC‡ÁíÀýbw‘^¯‡‡€ Ÿ>+ª1MÐÀ Ò4ÂìÝaJã:Þé3OәŠ×c´>0 æpG §¶BNƒ–——÷RxîV³Ú“™P(¦?x­VËçó0Q†ù.\Waý±P}æ€RH@²5‡Ãßd6 ,©*„ ø?’Pk� E€:ˆj¸�®àUÑ,jt‚p°1Õuà6!˜C¤©ÄÐâ£Õje2™õ»ôüÌ 9æíÒ¥K¶¶¶MORÁjMÛ.^¼Ø®];£¥4 íÙ]]]kjjÀÃ;�-F`€9+ìÓÄîQbh’Çö\çðfóà P‰ôø¸š†ë¤±΋„™7¼AlÜAª‹®aN·DÔDÍÀZ¬¦˜ PL‘ï‘ù+È1R= S: ˆ�½#}4x¤2TÖ¡ã*\(Ða¥ÑÙiõ¼¼³ÁÑ‹†x}¦·i…œÇHé4oÞÜú¬öÚ™éKXÞ¨¯¯G¶´J¥ú›u¦VƒsÔÊ-t÷(í¡àPÈLƒÃÀCƒ<›‡‡‡L&“H$4`@C+ìÄwì^¼ bèý$† „ íÐAž6Æê—Ë 5¤Eàí`‡rpsç  …q¦ƒG##­Áí4ä‹é¤–iÚÍÔ¡ÓÑ'¼YÝÓwLY�F§¦ßH} E+ä<‰9;;›ÍQXÍj¯¬9s&,,̬»T*• œ¤V« ”C°CûY 0™LDŒAGƒÞ 1‡Ã¡Q‡ÃáTVVBcP(„`E۠иÅáp¤R©H$b³Ùùùù´Ï…k\„³°Ùl'''hí¤ãØÎ=7t@Ã`0 sßÄ  ° þ¤…J­fM¬YÍjVkÐ,øJXAK$U¶TJ°ÅÀ€¸UtS'®Ê±HnsSHuÂN§ãóùX–G†à€ŠR©äñx………XËÁÄ¢rê ‡5o€IÅåre2R Û888H$Ì\©T*¸/¨Bм�—GW³ž>Ü4 ˜èÊÓàiõî';~#¿'¦Ô8:Õfzø©iƯ¡ ð !g×®] ¢Ö³gÏ*Š?þ866tn!ÇŽKOO_¸p¡£££åCUUU-[¶¬ÿþ(Üòê[NNŽ®!„ <øòåË÷ïß'„ 24¶Á¾þúkBÈ|�æçç'''5*<<|îܹð&—Ëm˜;vܸqÇÏXÍjÏÛÐ/�0` ûíW vº í> b Å:1è¡k04åEÒàøôÀzšfºL ]´º³§§ç¥K—š7o~÷î]”·²2¶ðÿ€²ðëC27 Òöf÷¬ž¹©;FFv± –O¯ñóÄrpf+1¦fú©ÙTžiÁ›Ö’0sÙ®,--máÂ…=zô MLLÌÌÌT©T©©©È[%„„„„Œ;ÖBZ}}}jjê•+W^£j^^^jjjhhèØ±cÇŽ{üøq˜2ЬY³)S¦Ü¸qñfåÊ•û÷ïÇ'>bĈÔÔÔ;wîhµÚÔÔT‰D2vìØQ£F]¾|966öÓO?ݵk—ÕZí…E?Îjݺµƒƒ1V±X,X)‚€ 0°cƒnyAñi¬ocF $™6pµŽØ€.U6]Æù»¾¢Õjed IC d3¤� õY§ÓÉd2Xê¹»»{yy Hˆ©T*©T -–}ûö¥Kííímmm!Õ†àw !ðÓpDÂ#—çV{6Hl!/ÿùçŸ4hܸq  5B)//ÿàƒüüüîÝ»·k×®ØØØâââ7ÆÄÄ´mÛöþýû¥¥¥}ûöŽŽnß¾}bbb]]ÝþóBÈwß}wñâÅ×ëùùù…‡‡‡‡‡/^¼¸°°¦Ñà·sÇŽŽŽŽþþþ¸}¯^½P566688xúôé £M›6aaa™™™¯Qœgµ&`‘J¥÷îÝ«¨¨Ðétåååð~mm-.K1­ Vª1å<Ù�¨T*¨ÕËd2Ðdƒ“B Zß¡òÿ÷€œ•̺Õu,.‹¢LVò6ò‡mÔ©ÊårÙl6Žçqss <x°‹‹‹—————‡ÃiÕªUçÎ !J¥òðáÀ|pÍR©T¥RÁî S(PÔÁ”-† ¯A»¬¡Çø¸Ãéõ ›é§4ÿ¢¡Ô¨iˆªE`ôñ:žˆ>&ͤx,3{kO9¦—‹¯¯^½úþûïÛØØ`ʨ¶¶6))é_ÿúWVV–^¯Ÿ?~jjêéÓ§þùçmÛ¶i4šââbš2yòäö’0zÕ,##cëÖ­'Nœ€?×®]›––¶~ýú¶mÛVWWWTT€zXvv6Œ�4hPDDĶmÛâããMÕ¸­fµå��Ò&Èà 4 ]ÿ'†îÌ¡A ….³c¶¦¨ÑZÔR©zBÁÅC †Á`ðù|^¯¾w½ÆWìf2*€ ¨ÉF«h4hÕ„ 1~~~­[·ŽŽŽ†óº¹¹•””œ:u KM�*•Š–CrÞ2Í8 ©(|ÙÄëläc×5lp1´ Çã™íÍÀi4xµx|xJJ¥à¿¡Á< è Õ/8¦ð´yÃáI4Ó[{ö­ ±±± Ìhd‡.--•H$ô›!!!PçÈÏÏ}óà˜6MNNÞ±cdž ºvíJYµjUÿþýaxsæÌ™Ù³gC8HATþÏþ³zõê?üÐê­öâ!›"Q™U‡±½Ešo�œ€P€KZ(æÓ­6øûx€½†R›F*ÔL&“·†§ÎRë·ê9¥n)—°þºà ‘KÆápø|¾‹‹‹¿¿›6m:vìØ¢E‹áÇ;99A*%//¦a¢ 4rÐ :ˆOt“ B)ä­ß™çglË‘ €ôZ ¡è)<<|„ ãÇ···ÿé§Ÿh(¦Cņ˜ï¯¬½ýöÛ�0ëÖ­ûꫯŽ9íڵ믿þ"„ܾ}›#g8� Ì+V¬Ø¸qcHHÈ7ß|cýªYí%®™�è!͸ü'„899Bêêêär9¬|ÁƒCj §y©ž`ÜC„êÎØä•y&“ j4z½ž³œ£î©¬�òx<hm8ŸÏ‡"™L3ïu:]Û¶mKJJ®^½ZPP P(ÊÊÊPeûF !jµÚÖÖô³áe24Q*•J@#ˆêàÀ d_—y9Lñ½jÕ©!'22rÓ¦M‰‰‰<¯¶¶6%%å¿ÿý¯!dÏž="‘H«Õâ(-6›íëë Û÷Þ{oذa¾¾¾¹¹¹W¯^ýþûï·nÝêéééããSTT4uêÔU«VaK×kdÅÅÅR©´®®X|<€bbb!YYYðçùóç{õê5oÞ¼ãÇ_¾|ùÂ… UUUV÷gµ—å�Š@ë% Õ�NTUU!o [,±þ¬Yü›71±ºÅ°Nù�€s!ùï©nÅl@C*ÿ®Ü�Þ`JÆiµÚââb&“YYYÙ©S§Å‹CÅ…Ïç×ÖÖB»C… n †äâüàËôbŠL­V ¸ñ‚åå.P ß¡É~1`|Ðk}L²ÙlTËÆ\´=5„4&Z€åÅ“D9C† Q*•ÙÙÙ„¯¾ú*&&F¡PLœ81&&¦ººúÝwß]²d ŒOvttܾ}ûæÍ›wïÞ=jÔ¨… ­fdd@2*""‚²eË–;vÌ™3çuÁŸ‰'¶hÑþŒŠŠR«ÕÿýïáÏ3fà <˜Þ±Y³f'Nôóó1bDRRÒîÝ»½½½±–ãîînu…V{a.Œ–gÆZª™af ƒ!|aJ‰F 5ìŒQ(8XK;„ê…a€v3•+µ‚Óì¢G0€KB¥NŒB*++ÅbqNNŽX,úYii) ’ÒZ/¾Ð=.Hž†ç�¡æÐ0ãÕ#ëæ¥%Ö!£F5jþÉçóW®\ivËÀÀ@£&Nœh´MXX˜ÙîèWÖ€¨†4hРAf·œ9s&ýg«V­ði˜>±1cÆX¿yV{‘QøeÌt!I Wý„’8Ãy”XàÁ18w�#$‘B¨ž´0„AFI9v ›¹‡ Á¬¯‘,gš ÿÊÊJWW×7n d{0›G¨š Ô®P` PupÕO¨öL XIÒ/r,ÛùóçSSS¿øâ «™Õ¬öÊöK¢ŸÅ8†f�ÅÃz¤4öêC F&c[ |„ºÑ(fq2Ð�«fÏV®íÞÝV§Ó%&*äݼùÿÚˆ…( L}[RR’——W\\ Ÿ¨ ÌÀáxxdKã,d@J{T¯×[h1¤ç�5æ±›q†Q”©ú�~J+¹!—–k3Rlñܠ0D Ô»¿]¼¡b‡ÝTŸ>ZC¸K÷â|¢XX˜¥Ì=ȉˆˆx½Z;Ë*++š‚n5«½‚ÖÐ8/T@Å wŤ6¬€û. 1þ€døzš�:} €�É0[µZÍãñ<<ô iÛVsõ*ÇÃCÏåjÔjDt¸?=:¿ŸB_=†�{9Q0›ÇãÉd2z”Ç£Gnã¼bbÀ ›\.oèWoi̺i³Óhù‘ê €Y¸$,Pá¡è«5Â6Zt_#DY¸MZÚÎìŘJø<cÈiÚVRRbMìZí52'''¡Phê›°»|´J¥âñx´ê%Ä"˜hBÅ‹% e2Ã� �èU3 ½j†5øŒüuë”1Ó9º¶ÿFÅê€J�QDTÄP§XBê6¡†è ÄBŒ‘ŸÏ§ëçp xK;xÍ–KßV{ɉµ&lçÏŸ9uevvv¯WiÍj1pëF�¬Á@˜‚$1:\Àñ9X Q*•¯àäM¬Ð`ꆮùj¶4F!Z­–†^¯ß¶9âëzuG^ÏäNÀ‚?„PJ8F½p¨æI M¬Ø×f´|@‚-G€a™…5>ê—|𘆲L<®Ñÿ—Ë8øÕ 9aþþþM›T?HS÷dµ¦gôä4ðé8–9cà¯Q†Édº»»Éår>Ÿ/“ÉÀáB]S7 • F‹åÀ6Øã‚åðððŽõ?þxéìyîû_×3)Ø@ÿ…ê - *5�™  GÆ3â ÒsEáODMäÚÑóßhŽˆ^7$.€E §Bé«Zålh�Úcß,ãŘeä¶BŽy³··oÚô•ŒŒŒQ£FÕÕÕYÿ­›¼A r\J¥Ü:—ËÅò4jÐÃ(ÙlvYY‹ÅãÇ߸q#Ε¡Ñ £Zé uºó†1ÐÕ«W/\P°ÙÜÓ M[B¾'ä'\?¨s¢j" Š@ P((�;Â�„�hÁÀ„pHì†cB܆ªP"TãŽÕ¬‰5«YÍjObØ–ûlÐ_C—(`ðõb±xãÆ8_€ø]`Пhkk+“É s“l¨¾…t,Ø÷äINI ÑNÔ^%d !E “ÉÂòˆ¡F D‰>Ÿ/‹‰ß¼�üâ€ä΀a@ƒ2¦Na¿]N·°r7•×l(X±ð¦å)œtHj´=@Ðê0ôŽŒBL‰¸Ç:ù'…Áô°…F3mÚ´ØØØ¸¸8BÈíÛ·W­Zß±cGÜF*•Ξ=»oß¾F]V3k[¶l9sæ !¤W¯^Æ [°`¨ùBlllV¯^‘‘±oß>BHpppBBî¸ÿþC‡­\¹ÒÎÎÎú­öĹ5ÀtF`(ú}º'‡Æ€c¢ßd2™ÕÕÕÀ6L 0$š}ûXz½^3X“³ƒw‘©'cT‚FW.Cç…íAÀrþ $P�á j?ØèJ‡nF´oÌ(bV°!gS_oº™ešÑ|UbŽKµFÛà LWb:Ÿˆa°Þcá„Ñì5£Ëh ꘦ ŸDÖS«Õîß¿ßÎÎnèСl6»  à—_~éׯN¶�M¤={öxyyõíÛW«Õ …B¶œ˜×�� �IDATP�’¥õŸ––¶råʵk×VUUÍ;×ÞÞ~âĉ ø:þüÛ·oŸ>}:!!aîܹaaaC‡åñx“'OÖëõYYYóæÍ+--]ºt©r¬öd†ÏP$€¢”1`u3hm-,(͉!æ¸è6�Œ 0ŒÀ´“É´d«‹Ñi™Zö16Æ0ô„J”@u8d.`à…4 I¥Rbè/Á˜ á„.ê€n)H±a!Êú…y¾ßƆ’¿ûöíÛ¼ysZZšL&6lØäÉ“"##ãââºuë¶jÕ*�BH||<Kýõ×^^^ÉÉÉ]ºt‰‹‹ëرãÍ›7­OyèСׯ_wvv®©© …|>_$ùùù=zô÷ßOOOçñx¶¶¶b±¸²²’ËåY®¬¬lÓ¦Mÿú׿¬ÐjOcv8999::‚æ,LÀVHO¡Óÿ RfðèqÑ)/€PcCþ¡Èt)Ž�Á–V«ÕåéÔ5ÑæC&> ”"�[(׆ :8Ò é™Ó�EpIxãˆ7(R€± )4â@tEgÍFŠ–çߘÍ_YcK½¡'ܘΧyñ_¤FÎylÈ1k—/_1bÄÁƒÇ·|ùò²²2³›UWWöÙgcÆŒ9xð Z­^¶l™õ7vòäɳgÏŠD"m+,,ü믿úôécooïâââçç—“““™™éæææëëK9tèÐ;ï¼c}nV{J ²··'„…B(¶cèƒõèvá#˜u&‰Œfš!BÀpd€êmX/A—äîg‹Æd†´DéòF<H=@À †Ñ(P p…/œç†T4ˆ{Ì60n¡NKÛÔÍt/¸YÚÌR‡¡1ˆ6�N�ÁíŸÕÀìÇ‚NÃÖÈ kr|}}GŽ ¯ýýýGŒ1bĹ\º–ì×_7šó?n3f̘8qbvvvnn.!$//ï·ß~‹‹‹srrº{÷î±cÇF””tûöíÌÌÌuëÖ999YÕØ¬öôÖ¶m[€œÂ²²2¬y  ŠÜ@8B —A\RWW‡±  Äô³[ÄЀ‚lòÏ™oz½>’n†³#3Mˆ¡ÑPÖm„V0YÇhôð¹±u”ªÐ5‘liooE «=ÇÄ!ÄÅÅ¥cÇŽŸ}öYtt´··whhèüùówïÞýÑG™£ŒóûÀºwïþÑG9rdÉ’%Ö§¬R©$ ýUÖëõR©”Ëå6Tî»téÒš5kbbb¶oßN1ÞV³ÚXFFFii) ƒ6 *öƒ›1­é NY©T‚8kôïXªA4"I7 >x#�Ã|}Õ ("p™L&d›QïÙt¼–Ä[PÂìJŠrÀ,Lòp¹\>ŸÈ„ƒù4‹åìì, ëëëÕ° õ¬ž|#Ó_L¾5> iä›ÏÐ7ËgéáN˜0¡[·n¥¥¥{öì!„8;;3™Ì¢¢"{{{77·‹/bØÎd2wíÚõóÏ?B¸\nPPD")**Š‹‹ÃYmÿËväÈ‘N:ýøã—/_öòòrss«««=zô”)S uæää$‰®]»vêÔ)gggooïÍ›7ÿùçŸYYYPË1ÞV³Ú˜X,V*•¨~F)ÑXäÀ~@#ZÔü;€¶UâbÌ8aW rÞ G‡Jg L77ýÒ¥Ò€�(›Éd2¢$mèõú;wî�Z@¢Œ¦' 3ÍÆÆ…Ú�ÆbQЮ †Îi4šÚÚZHdÁ›P×iHÍ ÓŒ8PÕ²©T*…B¡P(”J%>=Ó#óù|›šP(är¹FëQ•Áй#Dái©‡d|b˜ÖÃQÓ*€á‰`R5 4†›ô½Ó*|Fn0x’ð5{òVÐÞ½{·lÙ^øá‡'33³k×®K—.½~ýúÌ™3»téòæ›o­®Y³&++«eË–08'33sòäɳg϶þæ  V«!Ÿ¶råÊîÝ»+•Ê™3g°QBHxxøÚµk?~ñâÅ%K–Œ=÷ŠŠš9s¦•øgµ§1Ì›Ñ#;QL¤íb¶Gðpuu­­­E·Žù+Œr óË0xb¨¡XòÈ‘Ë^°XL”bCâ5 ]C‰ˆ¦wC°E‹:#êуs4K("2­D€Ÿ"W óuÖ/Ìó³G@Î!Cè?g̘av3Ä•=zBÚ´i³hÑ"ëÃ5z’ôÃäñxF(:::::Útǘ˜9j5«=™µk×ÎÙÙ¹ººšnÖ£IÃXÁU-VzpZ¨R©Ä¡”üib1í!G‡M¦èâqñÛ¯Ÿfóf6‹EÞ_}ö,ˈ‚o°;ªÝÀ¹x<”ÖðÉ «x”ÌÑétS§NMIIˆ³ zÑI lŠ]>ÖïÌKƒ«YÍj¯»]¿~½¶¶–Ž`ÐûcÓ =- #ž-Z(•Êšš †‰ÅbàUƒt4È<c* Â&ZÈ�‰ »à¨·ìcc•B!÷òåV„ÜÇ3¢ �1Œu!”ð>ºÁ !!!¹¹¹4u ÀoÏž=ÓC°ÁžG ò°Ûaé™<v¥F™KÁ`”X3jBõB‰˜}YAÁ#àDj:ÈÃÃbÉ·ÇyÕx#-´BÎó²’’’&Ì]±0CÉjMÌ@LŒžˆc4L" ã¤#¡òòrt1€80 †ß@ú‰ŠÔ0€° xRð_%%L6›Ý¼¹û•+Õ@b†“œÌû§S©T0€�ld±X×®]Ã0Pþ¬®®Æ†P@PWWnh8"þg[lÇ'iá°¦"˜ø4hPiŒÞY3«¬c4Ô•ü“e@—‹H£áX!çiM,7áy9mÚ´±þÿxjP}6*ÛC3?!D.—cè/GGGTˆhÀUƒõ2½j1RTÃ"ŒEpÕ<”JyX[¢…Îpfr°‰p4SŽ&XùGdI�Ç‹X´Ô ™Ñ´M«Yk/ÎNŸ> ³o›°<yòÌ˹téRMMM“ÿÂxzzúûû¿š×†D#Ð%C±dZ¶ 0‰ô¡a†M}}=¶à�ê8::Ö××ñ ³aØD qî‚0ä:`ÒëU8ß[shå1Gå8x IYˆ:te@±¡‡Ñ¡‡#ÀŒmTÿIJi¬@ç<LÇÒ˜îE¸/*#Ð!fc—Ff´,LôÁü˜{ÂèF踊MÔÐq~Ë¢AVÈ1o¡¡¡M{^Œ†|™Ã²²²·Þz«i—dÁG¿²L'ƒ$ ßO (Ü€ž- Ó¢0! e|>ßÎή¾¾Ã&ìöG< §D#+ ‡ðù|6›…B¥R (¥T* †\.¶4Χ³cÍ_ —‹7جCGWèâñŸ nÍh¤›åên2Ms™þ”p3ú°´^§©´ÿnÒLß1Už6«ôܘë'&¬Òõ1JÜ=3Á›ÿ)R²¾éÚ‘#G^ØØS¡PØ„Ÿ¤N§;~ü8ŸÏe¿ÌX´‡nGD† t ÇÛ Öä¡ ºZ­:t(:2l´Ä JÈàúj0|>ŸÇãµjÕÊÍÍÍÖÖÎÙÙÙÓÓÓÁÁº2Û¶m;~üx'''ŒN0Q†å(ôk¡¡¡t{,k°°D¨Št§ÔA´ÇçóQ’�®ŸÖj³:@kbÍj¯–åååAçïþó[[[ëy• ;1¸l´ÊƼfØp|�² 01e&Môz}jj*–FW´Z­H$*,,D™j(ïÃymmmÝÜÜ¢¢¢ÂÂÎ×××–•µ(***//8yøðá–-[`TB ¦Œ )ûrss!¿G§Ý`/8À 6Ñ”˜�Z¹‘ zj'F-–5 p{ÓpßlÏôp3(§5Î6r bzRLÜáñMã¤È?2ª~’VÐÛ·o/^¼ÿìׯ_mmí¥K—¾ÿþ{BÈÚµk¯]»¶qãÆ_ý´ !C† …OÓ¶‚‚‚¤¤¤qãÆõêÕ‹òûï¿Ã3ñññùì³Ïè-7nÜøçŸBúôé3vìXBÈ7–.]:}úôÎ;Ó[^¹reùò儇o¿ý–²zõê .B† öî»ïÒWTTÌš5kÔ¨Qýû÷'„œ:uê›o¾r—_~IY²dÉ­[·!x‘ÏÖ$Ɇ zöì¹jÕª[·nÁí?Û²eËñãÇwíÚ~üñÇùùù„ÿûßÝ»w7Ý>%%¾“ܽ{7dDçÍ›GoƒO’’˜˜Ø²eKl/Û¸q#—/þI¾È@VúØàñ 瑾ŒÁf{èì¦Ý`fJ´Ø@Åb) š9}âB¡0((ÈÍÍ-000<<Ü×××É©ž§çÀ'Nœ={Øl6»²²’Ãá`Æ {?Ïp´€‡B¡ÀBöÛC!Š˜xkxÙ€:pmt™RŽLÒ©0¬Í ûÀt3zžéÑÌfäL=;.@nõ)¿ ¦©<rL%.Ìì  WØ äÔÔÔ¤§§/_¾|À€°<™={öÑ£GU*Õúõë7lØðÃ?¨TªË—/gggïÛ·¯Y³fÿ ]f̘qîܹ›7oB{æÝ»wçÍ›7a„´k׎Ífúé§Ðswøðá%K–üðÃõõõÿþ÷¿ÓÒÒ®]»v÷î]ì •ÉdõõõçßÿþwŸ>}âãã{÷î=eÊ”ÐÐЯ¾ú*##ãîÝ»Ÿþ¹‡‡Gdd$ì2wîÜìììëׯwêÔ‰’ŸŸ?f̘øøøqãÆ 8ðóÏ?g2™)))gΜIOOŸ4iÒþýûCCCŸíCP«Õååå=zôˆŠŠzVdë»wïNš4©°°°²²ÞY¸pajjê… ~øá‡÷ßÿ·ß~‰D555ööö|>_­VïØ±cÕªUZ­öôéÓÓ¦M[´hQTTTLL ŸÏŸ9sfee%ˆïfggALæììüæ›ozxx$''Ï;7>>þÇ„ÓÑO2**ŠÉdzyyíÝ»÷ÀÏïI¾7 Ná¨uL‚AÐÖþjµzÆ Ý{ï)U*!ŒmÛxÛ·ó ú‚C 1ø¨¬,uqÑÉål¥’!œœœÜÜÜ:uêÔ¹sg{{ûfÍšw*—·ÞzËÉÉéâÅ‹"‘¨¢¢âìÙ³µµµ�„2™ Eá€x¦Õj<†Ž«Ó×ë¡,„˜·Æçóë~¬³aÃd2ë¿­ç&q¹.ì‹· :“ƒ_ì×Ez�ºˆP”D"‘€HÄkŸXsttôðð ¿»ëÖ­ÛµkWjjjxxxffæ×_ýᇂ<-½å+hþù§\.ã7êêê$ %<®­]»öúõë(Tãëë ³>áæééI<x0Ç‹‹‹“Édnnn|>_*•Êd²­[·fggChöý÷ß/Z´èÒ¥KýõW^^Þ•+Wôz½··w]]B¡pwwo׮ݰaÃè øòË/óóóa@ü‹ÔÔÔ888xxxœ?žòÑG©Tª-Z8::ŠÅâ§oÝ25—1cÆÌœ9søðá={ö|&ÇôõõÍÊÊš={vjj*¼ãååÅçó¯\¹RRR¯/^¼Ø§OŸ 6ÄÅÅ={6///66öèÑ£¶¶¶îîî>´···µµmÞ¼9!$&&&000"""33sýúõW®\ñõõåóù>>>;wî¤/€ÇãµlÙ²´´ôÊ•+\.·eË–Ó¦M›>}úÑ£G =<<^_#@¸]Zñ[[�›á5(•A%6.€­­fÉ^FÇð¾ ŒÇãµn­ôöV¹»ëæÎ•ò‰cFS 4kÖ¬cÇŽááá"‘¨Y³fà% ‡£c2™••Õ #((H§ÓUVVº¸¸ÜºuK&“AÃHµýÝ9M´*-'‹C7ZþÍ(`hõZ‰–QÏ`hàé:â+’Ö âñx8ÌrÚÊ´a‡uÒË }9¦í2¦ 7#:]¨×ét_|ñE‡Äb±——׺uë@ÍÒÂpRÓë7¾˜^m#ë[t™Íl¶°QsèС´lÙT¿d2ÙÒ¥KgΜEiݺ5$1²³³ÓÓÓ׬YÓ­[·WóW÷Ë/¿|üñÇÑÑÑ­[·¾råJhhè“AŽY;räȬY³/^<nÜ8BÈøñã¡«î‘;FFFΛ7ÏÁÁRVV–““£ÓéÞxãû÷ïCÖÈÖÖ¶[·nˆp Yfff}}½‹‹K||ü›o¾yðàÁ•+WÞ¸qã9=L™LvñâE__ßO>ùdذaF‰¬ge­Zµâóù999ÞÞÞ|>ßÓÓsÞ¼yÁÁÁjµúäÉ“±±±?üð!ÄÎÎÎÃÃãþýû:ÎÞÞ–>S¦Lqssóðð˜7oÞƒŽ;V^^þõ×_CÒxÅŠ³"ðx<‘HTTT”““Ãáp¼½½áýË—/ççç·lÙò…±-žê Ï…”Ò‹±ý2`€Ãá@V> †^OFŒÐ…†*t:Ý©S¼¿þâ ŒB¦N­çrµÑÑʨ( !äúu–ŸŸ¬m[5›­puåxx\ôô,sq9O[¯×ÛÚ2/3/íUÊ+Ø7 †ƒ‹C]§ºªª*µZ]ê^ZS]5£©_€L&SÛ^«ùPÃ3H2!„Ÿˆ _€›ñò•Ó”„Þzž¾VoDÓÂç€ü.œBM³´Mñ†¦~Ñ&̰0`J2i¸•õ[ŒWhš< ùʸË'Ÿ|rþüyPþ¥y‰4¨ÐÜeSn4½äÂm€‰2³X‚wYJ¸q ÈÍ|äÏ>,, &†B„Bá'Ÿ|²ÿþÓ§Oä$%%%%%%$$Ü»wïĉ¯ìOîçŸ^²dɲe˘LfLLÌ|𬎜™™™˜˜˜�xÓÈQžQQQIIIŽŽŽ„Î;'%%±Ùì½{÷§mÛ¶Õh4³fÍÊÉɱ|°°°åË—§¤¤¼õÖ[›6mêСê±>s“J¥.\HJJ‚bÞÓTÅFÌ4£‘‘QQQ‘””Ô»wïC‡UTTxyy%%%}òÉ'1118D#??ÿ÷ß<xð¬Y³îß¿ÿÇB¦N:|øð®]»ÂWtèС'NœÈË˃‚YXXXzz:­9[]]½ÿþØØØ¤¤$‰DrðàAxΜ9ï¼óÎo¿ýV\\üšâ ΤA‡O‡nÃtµÊÊJ‰Dª3XF'›—Ǹr…Ëbu|ë­CÔt:ÝÜ+W¸‰ÀçaݹcŸ—çTVæ¥T ]y¼.lv¤VÛN« ++óÊÍåØ*ǾQ¢ ñ(ñh¯oï'ñëÊïê”çĽʵ¹eÃ¸È  üǾÌfæ0™9LFƒw•G.F1ƒB´„\$ŒWÆý‡Ï彫žÁd{B  p'K‘Ž.%V{Y‰µ>}úüÿÖlvBB‹Å?~üîÝ»¥Réĉ×­[‡yžWÙ:wîìææÆ`0¼¼¼ÒŸÒnܸ1~üøÙ³gOš4 ßÄjÄ#­¾¾¾®®ÎÕÕµ²²ÒÖÖÖ¨ãèè¸råJè�///·³³3K èÓ§\.¿råŠD"iÕªU§Nª««Ÿ÷#mß¾ýÓ<É-Z¬Y³Æhg9]UUåèèxýúõ³gÏØH¥Ò?üÐtãòòr6›ýã?®]»HhÍ›7ïÓ§Ï÷ßêÔ)BH]]VA"‘H¥Ò&О…'”…†<`†ŽZ”1á#CÛæÚ5þá쬬< D£Ñ@T,ëtºÃ‡z=#;›og'hÕŠ|óM›÷·ß\<==5?Æ[¡ðoÓ¦M}}}nn®TêèììóÆQ½”5÷ î»»»7Ó4»#¾SUUuíð5í)­^ªg(,ÍÿÇÉÁ<iO´÷´Â@¡Z©æTs4 ‹ËBÍ7ƒ¡÷Ð!!‰Ö[˹ÌaP'@=åAwQº=1äõÄÐi1ˉ)Óí-§õÀjkk¿þúkµZ-¾øâ ó°s ¦‚7¦Á™å'ÓÈçöØ$i.—;kÖ,&“7wî\‡S§NUUU¹¹¹ùùù½Ê?¼¿þú+&&F¯×ŠÅâ»wïvèÐá)©Ñh$ÉÇ;FiÙ²eppð!Cx<^bb¢——×É“'e2™H$‚2‘mÞ¼yÑ¢E'Ožüàƒ<<<ââât:]DD„¯¯o³fÍ233óòòüüüÜÜÜJJJBBB,X`4 ÂÆÆ¦]»v7nÜÈÈÈ¡¡¡ûöí[´hÑš5krssƒ‚‚ „zæVQQqçΉDBÏå{ìõ› u³lgg—‘‘qíÚµÐÐP;;»œœ¨å8p�¶‰?zôèÖ­['Nœ˜““£V«]]]AËçÍ7ß 9r¤^¯?vì>É.]ºgddTVVBÆrÕªUÉÉÉgΜy)Oò…eÕh‘P³¡s;à|±œ8R‡ÛµS1™|™¬úþ}nM {ÕªUØFJáp82C¥b‹Åì~ýÜ££Ç“ËåJ¥²uëÖ•••W®\a2™Í›7¯©©áóù-[¶äñx………—.]ÊÍÍ=þ<MAöñ� Z­–s‰Ã8ÏÐè4,&‹Åù[›�Óe:NúÔ¦‡ ƒÁ핱³ÙÎçÚÚZ¼#`Ü¡ƒv$ 2÷d}9ØH«P(Œpü61ÇOCŽ­¥mj˜×…|#“É\²d ÀzˆY§ÏçóáÂâÑÐÑèzPo&L?²¨#—Ë1ÿiaÉòðð˜8q¢Z­¾}û6­»Å`0»uëæææ†.00¨S‘‘‘<ÏÑÑ1..®¸¸X"‘ >ܨÐýªýê>ùäN½gÏžë×¯ÛØØšÝ¸¤¤ÄÅÅ¥¡õ;ƒÁ°³³ëÖ­[‹- ”¬ËËËËËËmllÞxã &“þî»ï¶nݺ  @§Ó7JG ÃÉÉ©k×®ðT™Lf«V­bbbzõêUQQQ^^Þ¥K—>ø 00ÐËË+??ŸÍfOž<¹cÇŽÕìÖ­›——ƒÁ€×žžž¶¶¶‘‘‘pö·ß~{òäÉaaannn÷ïß …Ó§O 2{·oß y2rƒÁ¸páž={~úé§¡C‡Z.5Ý»w¯M›6ʉFGö÷÷‡vèÐÁÉÉéþýûvvv3gÎôóókè;9`À€ÐÐÐ’’’ÚÚÚ¡C‡Ž1>êÔ©ÓСCždlllMMMyy¹¿¿ÿ‚ ÀÅøøø¼ýöÛ]ºty‚' ÷ø *òÉåòÚÚÚ[·n]¾|™ž2 Ñh„B!¸ZöG•ex&ôÀƒÁd²Z´Ðººj<=Y••Œââ¿çCÓ¾µŸ…B¡ƒƒƒ““S³fÍàwy-‰™†ÂÂÂúúúêêêšššãÇ9räöíÛ€ ´d�êÓóAj8Äÿ¯Uèì+l6›­Óè×j™šf"ÐMòèá²áúÃÂÂÜÝÝÑ ß¾}»yóæÛ¶m3ã@©¾œ†<;]û¡{¡ŒÞy„§¦d `c>Ÿ/ø|>ЦüÈ”ôlÖð€¾H 8˜7t¶–Á`Lž<Y,{{{–«Tª{÷î>|˜‘-“É8�|è¦j'Nœ°µµ ¿té’D"1ÛçváÂ{{û&œÕ=xðà¨Q£êêêžl÷ÊÊJ¨0uïÞÝrníÈ‘#|š`èÕO[9räÝwß•Ëå¯ÚµUUU=xðà×_MMM5Rßr3ôÐ`UšWP¸·Ç ¡èâ€KòšpL‹åééÙ¼ys¡Pèáá¡ÑhlllÜÝÝCCCsrrd2™££#â%IaaaqqqMMN§U7h…Å5*Ü`ÍØÛ8Þu A�Üj¦A„¹5ˆBP§�ƒ?¸Gè65jÔ°aÃÚµk‡Š 1;¶Ê´/Çl”ƒß”MÓ,°œñD¸#M7°°ÜÁª¾å(Ç4ꢣìs²Ð£ŠØyîܹüüüèèh¥RiggWWW4«ÿ!õ€öZTž^qsuu}­[#ÿ§ Õ3‘ÖŒÞKëX×ö0Ý-¯×ëa øhœ/�& kÙ”Áe6›­P(¶ø!‰pp5Ä”@å‡: ^ŒT*…”—ŒÍ&­O¸è3EÔ!†y( ^î\' öà …Bšß…L°†"rLçÍÈårZe‡ü“#‡ .SêÙУNÎBpfK&˜¸ƒN)#ˆ¢Aî×H›Î9hìÁr—)äà#¹îyÕrþw¬   ‘é ×ÑžG¿Ž…uˆ4Õ(ç¿Bü#ØÆè¯AýBQ“(¶W¯^5ý'î à `ø#€@�}þ|>ÿÎ;L&Ó××Ú_œAYYYqqquuuqqqmmm]]¸0ìÂÁ‰ðLò�òÑA14HâLb ¡¿†è”Hp†)V>,C¸iM¾‘’ Ïé›ÖíþX—a:”Á�� �IDAT*ÓÙâ±k…KN¹ ÏË y‘N¹ 'Ö!¯¾*.áQ‘ŒîEº0v°ƒÿÅaÏr¹\(B¯ ÆF=H$‹>°/6÷ètºÒÒR;;;à �ÁÚÙÆÆˆ£%%%ööö>„¥I}}=20–¢•ÖPæ §àŠõ€É7¼Gæ¦Óé Lo á .=ªÇêýžŸY!ÇŒùùù ‚Wvüɳ2™LöÎÒ¡CƒÑ¶mÛ&¿@yÅskØ¡3§iUfºû4jûc³$½ìE”BÆ€“ ÝS__/—ËÅb1“ÉÍ›7/**‚¹¢"‘H(º¸¸ÈårŠS[[‹%8öÊ�$`|q¼ÆfÈ&aÜFß#ȵ¡B&¦˜ˆÚ×øD%˜²�T¨júl×^°Jx‚hƒ&(ÅIO!&L¸ VÈ1oyyy>|-‹žÆœœœºtéò¼Ï’››û ÖÕŸ¹‰D" ”¶—Ž7ྡŒˆ4'KCÏ[C.�=É QŠöYL@ùœ/ìËãñàÈ*•ª¾¾û`U*Uaa!ŸÏwrr‚\–Z­¶··÷òò>æ÷ šÁ¹>r¹ŠCØCCð€Î�´4HÁ¡Z%8}¥R‰2k8Ê…±±!´1Ž›¦º5æùÓƒžaäjtÀƦ¦—O 9fržDIúÙ´ZmLLLÓÑV\\ìååõÄŒµÆ›Z­6lXc~™¯©éõú²²²fÍš½²ÈŠI3Ð]F>8¡P5HŽSÆúú&ˆ‰±Wkòˆ@ À.‰´Ô�ÆÄbqqq1—Ëupp,K©Tº¸¸`Øáàà ×ëÝÜÜ FÁ‘9ÈŠ„ËCN¶Æ- !žžž´¸51pè cÄH!ÓšX³&Ö^ZÞ© “¤Oœ81jÔ¨s.Nׄ½^Ÿm4`â•2ðËX¹a³ÙX’Áèý;ПWÀ¹c‘À‰^&ðx<Pµ³³ƒè¤²²*7°MQQ‘F£qqqqvvV*•õõõ555l¡�¦¼PjÀ�ƒ*•J×f„v˜ßÃÑŸ˜E¤ic�·ô¨7œ‰€ŒjS©4³ÿâ¦yTZÈ(†@3Α#ÿät4Ñ›…˜„"UÓ=¤¦á²·’!ñHþ9E”ÞÞ(íF·IÑ¢ÝÂ# žÓ 9V³Z7,ä€rdÉ€t Œ5ºkS@¨)�.=8&¼=Pši¦ÕjPWW‡ó§5 ˆ¸ÛÚÚº¸¸ÔÖÖòx<¡PtØÂš¶ƒ'¥ãpú<B¨‘Àe�=2l‹S*•r¹@IÒ98Å�îâ‘ MË}0FvFïк¡þJ³2šxUØ7C³'LE¨ û®ˆ­NÖH»¡+¤§(=•\�5ôÁùóçE"QÇŽcbb:w˜8a„ǥ9•——ÇÄÄàÄ- ¶xñb‘HôÂj°‘‘‘ñññ˜b‰D)))Ïi ¼ÿ~‘HôË/¿Ü¹s' &&&(((;;[.—þùç:uêѣǰaÃhI´šššÑ£GwïÞ=22rÑ¢E2™ìܹsmÛ¶Aþk×®I¥Ò¤¤¤Î;wëÖm„ b±øe¹³²²2‘H´víZøóÈ‘#"‘ÈHÓìé­¢¢"666&&¦C‡7n”H$1óóó=ztmmíûï¿5þ|©TJ_adddLLL»vívïÞ­T*·oßÓµk×òòòêêêwß}·G:uZ±b…Ü×Ôhâ�®ô¡‘#�º-}Ž8ÃÙ9à­àwŠìd:[%‘HjjjÄb±\.—ÉdJ¥ö’Éd …¢®®®ªªª°°°ººº¤¤¤ºººººZ*•U”¤‘€€kjL‚¡O„¾ˆÛ�6`mކRrJ¥R¯×CI‰8ß8Ì»|p²ƒeá}«=ÇÄšV«‹Å+V¬ˆ‹‹Ã)/ööö'NœˆŒŒtss;xð`›6m‚‚‚”Jå¡C‡Ú¶m›žž?Ú.]ºØÛÛ'$$@YõàÁƒð…ˆŽŽvss+((8wî!ÄÎήW¯^ …B,¿°DVDDÄõë×oÞ¼püøq‘Hô<NtôèÑ-[¶@³Û{ï½çëë{ðàÁøøøÑ£G>|øÞ½{ß~ûío¼áãã“’’²`ÁØëûï¿ÏÈȸqãFNNÎèÑ£»ví:mÚ´ÈÈÈ;v :t̘1‹-gOOψˆˆ:L›6í¥|x<^Û¶msrrJKKíííOœ8áåååââòlÏràÀÿ 6lذ!)))&&&++‹rîܹ &´oß~Û¶mû÷ï¿téR}}ýêÕ«oݺվ}{Ø÷ƒ>H$gΜùâ‹/¦N8sæLP«óññ™7ož··÷ï¿ÿžŸŸôèÑøøøÆL‹xíRàŽÐ…c˜fìììš7o^WW'‹e2¼cCqI‹}”4qࢠx2iuuuvvvZƒÁ§‰D¥RÁ,ÎÂÂB;;;¹\Îår¡*#•Jëëë•J%=ª‡Ú-Qb�Þd‚šæ| c¥R À0ƒ|ÆÆÖ"Â0±f:+Úl cô¢ñIfÑIÃPiW�F͹¤qÌ Qoc¾6¦wg0Y¾ÇÇ‹rÌšB¡Ø°aÃO?ý4gΜ‰'°E‰D2qâÄ_ýu×®]~øaQQÑŽ;æÎ[PP0qâÄC‡mß¾}îܹEEE©©©sçÎ-..NLLÜ»woQQQBBBZZÚ þ~ùå—AAA³fÍZ¸pá_|ñÕW_½óÎ;ÏãD_|ñÅG}dö£ÀÀÀÍ›7GDDlذÁ××÷­·ÞzÝ™££cBB¾}û®\¹R]]’’2dÈgÎÝš0aÂ7ß|³páÂôôô¡C‡¢ÆD<sæÌÁ-ƒ‚‚6oÞŒxc54À(]�] ¼‡Ãqvv;vlŸ>}Àc_$Tz°DO¨B=¸-¬µ@ð#D5MUUdÕT*•\.ntÞH$’6mÚ<xðàöíÛyyyùùù………åååÐÃÏ`0Þxã  9àñQÚ�>:ŽÏç£ÊÎϦóf8¬gá á >BîøH_Œhª1X#—˸=àŸYcQ†oÒÿŽ|>Õhž rLOj6ê02ȱsë±ÀóÕ«WïܹS,<¸ººúüù󃶷·_´hÑgŸ}¶xñâM›6½õÖ[ß~ûmDDÄèÑ£?úè£êêj±X¼fÍš‚‚]øõ×_¹\nBB€ ííí§OŸÞºukOOÏåË—=zÔÉÉéEþülll–,Y2þüuëÖíÙ³ç9i·$''Ïš5Ëò6+V¬HMMýù矃ƒƒ_S_9räÈÅ‹ …ÂÎ;>ü9e‡z÷î­P(þøã©Têää´oß¾?ÿüsõêÕ¸M||<ŸÏ1bÄØ±c­CG¢È<W .œrMMÍõëׇ rêÔ)ðb"ðù|T( ™ÓØŠÙ9ðÔX‚™^¯ü@…1¥R Û³X¬K—.%šz6V±�è0E½È¡aøkA@™\¹C¤õ·ì´¡!Ü%ÊÆƒ\mém[í¹ü-<mÚ´Ý»w§§§oذ(ŒXÎáp8:u’ÉdW¯^ÍÉÉ òööÞ²eËÙ³g÷ìÙÓ­[·˜†o"‘¨[·n<ïÚµkýû÷‰‰y)©sFsðàÁßÿÝ××÷ã?.))yæ§Ø¶m›Z­(,,„Š‚Q¥J&“}öÙg;wîLOO}ñ†âì윜œ ~?ÿüós Çd2»uëæããsûöm ìUTTЊyÉÉÉS¦L™3gÎáÇ­¿m4¹\ŽI*\‡B œ¬R©\ºté… 0|áóù(’ß·o_ PB:}hPÓ v„¾ˆ©T*!“¦Ñh …J¥R(2™¬¶¶öáÇR©´¦¦¦¬¬ þ_\\ i=8iUU1Te0³§Õj§N §ÃÚF]XÙ˜¡ cðh˜ø JY|Z#UaPÊšÖà1»Þod£Ù\¨ÑPTÓ³7 1ȳ|©¹ßg²1û‘ë#³3ÁÀ¢¢¢¦N:wî\777˜µuáÂ…ššš;vL:5!!î´]¹råæÍ›!!!IIIK—.6mšÙA2ÏÛ~üñÇ+V|õÕWýû÷Ÿ2eʘ1cRRRšeðdÖªU«ìììU«VÁĶC‡UWWÓ7{þüùÕ«W§¦¦âÐUØ æR¿vIðA(¾ûlíܹsC† Áw***._¾Iϵ³±±áóù T¤T*÷ïßßäUcÈ<¦}8Y¨£@¥)t.^£ÑüñÇB¡ÐÆÆ¦¬¬ &6àv‘t‹A 1T ‚AÑLaa®Џx…Á„`+àÜBHJJ *Cõ½Cc)†>jÃvºùîžÜŸÏ¢A#[;1…¤ÓA; ³�áþ.0…%$á1p>2+8$l<>¾0íO0[¤±¬ž`4ÅÀèÛeô,Þ–$Ý£G´´´ŠŠ øS,'&&2D(¾ÿþû8Vhܸq‰‰‰óçÏ?uêTxxxÏž=ãââÒÓÓ‹‹‹'M𔑑ñœ\UC¶lÙ²ððpàDÌŸ??$$$##ãÙBð©!gΜÉÊÊš0a‚B¡øòË/çÏŸŸ››;uêT? QôìÙ³W¯^IIIsçÎÝ·oßòåË+**Þzë-ÿ©S§îرcþüùwîÜ™>}zHHH÷îÝ7oÞlkkÚÄÊݦVWW·`Á‚ .äææ>ÜÍÍíúõë{÷îÝ´iS³fÍ!Ý»w^¹r¥X,îÙ³gÛ¶m%ÉäÉ“çÎûÞ{ïåääÌŸ?ÿìÙ³ï¿ÿ¾§§ç˜1c~ûí·ªª*>Ÿ?räH{{ûƒ~öÙgùùù}ûömݺu{z´Î­Õ#AÑCA{ øtPQîapy4Èàï€A€A¼Æi4È=C²2¦ûè¤ð›*h-5zl Ðõ¡P(“ÉfŒ4Ó°ÅÇÈuBHÛ[kÏ÷ÛØÐÀ=£àóæÍ›<y2!dذa:u‚æü:øøøÌŸ?¶éׯ_³fÍÔjuÿþý„Bazzz«V­<==ÝÝÝ5MÿþýÛ¶mëàà°téÒ;wîBBBBÞ~ûm\§¼˜ÛÞ±cFonnnp‘Ïé\ø$]\\@·­ÿþáááJ¥2==7ƒ�hëÖ­B¡000pË–-555„–-[zyyM™2†ãõïß¿cÇŽl6{íÚµÅÅÅ„WW×WaëâÅ‹ŸŸh[llì?ü “Éú÷ïïëëëää’žžŽ7¾yófÈÆxzz¶jÕJ­V§§§{yyµlÙ’þN:99-Y²äÖ­[„¡C‡Ñ`ûöí@4÷öööððhz¿sd|7ß h (;;;™L† ª“‡™l:I¹@m2iÁÀ@àp¹\•J…N_¡P`?&-rh§€ƒÐ”3HßaE ^ƒßÀfU„&„Àéèq;tž–P3 pÄö™ZíECŽ]çÎéwðçíéé þQ*•®X±"77wåÊ•¸YDD½F[¢¹ºººººmóÂŒ¾H÷\/€~’ô‰ø|¾éyq6v@@€Q†ÓhcoooooïWç›ôlcDS £ÿ´··7z F2¬70úN:;;íÛ´óo˜C/q „ $ ] ÃäUÛØØH$ä@+(yà(N§T*ÕгÓÒ¢À5€±i˜=ƒ ‚k�jœÚ‚¹ ä2`Ó"+„ê‚ĤnlÔ„‹D„³ü<é‘kŒÎ€™æÇLM¥Ra¹oÇtŽÅoÌwj:}4ü!%Íp°4UÃ#…BL£á÷e s#O9±üüüŠŠŠmÛ¶Y˜`o5«Yíå�ƒR©Dÿn¼ :\(ç€z ÊûÓÜb‡Ãáp@8i¨ëŒ3¡ÁKžÑT7œ©C§ìà0Ù0_G  €`Ç—Ëå4T:Àƒ ‡Uc‹+R¥Á/cž [[�\iÛ Ëµ¼šfYÉæ9F9L­_¿¾©>úóçÏ7áy9tþó6…BqöìY«ë‰NVhœ \è^K/ˆAilÀCƒƒÀ‚2Q¨Û3@¤†ÎHµÉ E¡p‚W‚óo€D‡Zpp.¹†W…ЂF‹Œ‡ jH...UUUØQ„M©H®Ã  ¦,�«½BÓ´-((èq[‹_#{‘SÅx<Þ‹œ÷âÍ4­ñJjÛ ‡…´öê#å B °rƒ£e� L‰I¸#êxbœ’Õ@ÃA×€‚X""†Ò ô僺%Â!rÞ&!GwÂãÜ9H©) ÌÔÁ z(6ùÓ¬6ZŒ6¼ZòOƦ¶hE²ÆTƒ0c‰Ù?zxé kÓnSLs¡&›Qh‹;ÒÁ.ý)-C`:ú“{CÂÃô)&îè›":»rÏ233_q?òôæèèøbªh¿üòK^�ÖªU«Wv^ ŸÆ ÌÇ„?ÄŽ% Ð!·\¿J¥‚8�å5Á‘¡<3D<666À%ºpp¨1àp ’0Ãjr  ÑS¥R …B¥R ¥)Üp*Cв¥Ø0õGkSÒez¤Y0}mVúÉrY˜ß£!‡þᘎ6E>Ó-è‡Ò;š½kÓ kÌýÒA§rk±±±M»@UPP ‰^À¼BȰaÚp²B¯×{xx¼²°=…Ïç+ >Ÿ¥‘ÚÚZ\ïcæ Ùhôxf£4~„©*ð€8Ðh4í ÛeèÉ`ÈšS«Õ â91Œ„ŒÂL²á˜júÂ`w�!¨Ha1 G!`Ò…ÚE.0µi5kbíü,›êÝ:uê9)™š0—š0äœ9sæUž—ƒ¹):Ý9%zæ ]™§sVL&ÓÕÕU­VWWW#m q‚CW«Õ�|:â¦ÀËÓdl“Äé/HzÆ ÔA•¤$@¤¥P(›@tÁz1°ÃáPˆ©H+ miLÊ5”{$“í‰}pF§‘ú›–͈³÷ÈKE¥TÓàÆ,#YÑû­c5«ý¯®+Ùl½^occ#ª««A÷Gà Ø` f ¸^¾¾¾ç C…€Çã¡v'Ä@p@GGG˜Ê›AîÙÉF}?ðd€ÞN¼]Ø. ¬i±j8&- —Šz£8ÕÔÈÒÛŠÈi†EC9¨'ƒº|Bþ9 íéûRi-êÆp¦œ),2™Å*³jÓ §A=s挫«ëÞ½{›ä088ø½÷Þƒ×EEE®®®_ýõsZïÞ½ždnn®H$Љ‰ñõõýí·ßêëëçÏŸß¾}ûîÝ»÷íÛ·¬¬ ÷*//8p`tttDDDbbb]]ÝüñÆoÄÄÄ´nÝúܹsb±8!!¡S§N]»v‹‹ƒtüK±ÒÒRWWWlÌ:tè«««©ÐÑSZaa!̼ ]½zµX,Æy9žžžC† ©¨¨6lX·nÝ:vì8kÖ,‰D‚ûæççØ¢M›6Éåòo¿ýÞ øðaiiiïÞ½{ôèѾ}û ¼H.ß‹1€ …BQYY)—Ëaî'Öí!¡4hÐ wwwœ=C µk¡PŒT*I�!(ÝÛÛÛ7oÞ:~€;�Äi4b±gtBäì5œ’€j7tŽ 9r8OºU«V þ‹E&dCÀ„7 ˜ð°H·C0Í7€Ftîðüÿ™V{ÂÄ bzzz‡~ûí7BH¿~ý a¾{÷îÞÞÞÅÅÅÇ'„ðù|ÐÎÊʪªªŠŠŠÊÊÊŠutt„é„#Fà�ó—n}úô9sæLnnnhhè¡C‡<==ŸSíwÿþýû÷ï‡'9iÒ¤àà`˜—3iÒ¤£GÖÕÕmÞ¼Y$ùøø|÷Ýw8/gëÖ­'NœÀy9½{÷ž6mZ—.]`^ΤI“-Z´sçNœ—óÓO?½¬y9 {÷î999EEEŽŽŽYYY¡¡¡-Z´x¶gùã?ºvíºzõê 6|ôÑGýû÷T;qâÄ”)S@›àøñã—.]DyðàRò>úè#­V›••õÅ_$&&FDDÌŸ?çå|úé§ÞÞÞçÎÃy9}úôibBØU?UÚá¢MFF¢®–7 =88øÆàµÁ•7oÞ<00ðÏ?ÿ¤©Stï R¢ ¥»ƒÇ§»gPÐEò1þ€|WAAì‘ ¼†±rоƒƒ <Âk9€s÷�ì!ÎѺÔfCzŽC#kfcÓÁϦ5y:£e™§@Ï•hh3£ äŸôš:a¬ÀfðÐàPO?EóщµeË–ÅÆÆúøøìرãäÉ“QQQ™™™¿üòKrrrbb¢V«íׯߧŸ~Z[[ëí혘8vìØŸ~ú騱c{öì9|øð¹sçÆ¿qãÆ;wî,Y²äù.Y²dáÂ…³fÍj×®ÝáÇ¿ùæ›ØØØçq¢5kÖ,_¾Ü¬°±¿¿? Ó\¸pa›6múõë÷:º3‡I“&=zܸq0hÁ‚FÒ OocÆŒ‰‹‹›={öõë×G ºj„mÛ¶ÕÕÕMŸ>=99Þ À¥V£]ÊÑ#¥1€Oéae¨rFO=@o±È½{÷nݺµšº†%�,¢Àû´”ê¼x ó Òh666cÆŒÉÌ̼ÿ>"r 0xÂ!†AÄcggB ØG`#] IØ i¬™0Z [¼¤7ƒ( `6®2%’™%›íhöP¦ìjœ…jùRi`+!³ž6ÑטÔ^NNÎøñã}||><~üøˆˆˆ¬¬,•J5oÞ¼äääñãdzX¬£G^ºtéáÇqqq={ö„}8àíí=~üxOOÏÿcïºãk<Ûÿ}öÈNŒ ÄŽUYµG[ÑPM‹TT$(ª”˜±ƒšA+Í«j·ZZ5kÖ¨• "!±CHÈNÎ>ç9¿?.ù¾wOÂÍâ=×>ñœg\÷ºöعsgÅ9„jµzÖ¬Y¯¼òÊÚµkW­ZUJüféÒ¥S§N}ò=sçÎݼyó¦M›Pêæ…ƒöíÛO›6íƒ>èÔ©Ó AƒJã+‰dðàÁ­[·>yò$ÙͶnÝzøða>yРAÝ»wÿþûïílƆšPâ=yh¨p�²m)@0$ÐÀµƒê5qqqFÏÑ!æ‹rBç $²ãA™ —À»Ã…¶Ä£~qqq÷îÝ#›=N4v<²‚†é$ÕJ«Õâ…4 €J¥â½Üd‡ ÕÇnX+UøW“{îÜ9êHÿàÁ\”ÉduëÖÅ?Þ­[·¬¬¬ UÆÊd2ýðÃôõõ5jÔÍ›7Kü«W¯ÁÓÓ“ª—¦¤¤Øt*((§>c|ùÔQÑY¾|yݺussswîÜYJÁå"‘¨E‹^^^·oߦ™|ðàAvv¶îÙ´iÓÌ™3'Mš´{÷nûÙæA¯×#¸™$$òÃÈFqÐ ‡wª pÈ¿TE؈  "ñ¤µ˜ÍfµZíããC &¸L͈Ä;;;Ã$•J]]]‰©îb6›ccc5M,�q)´Ì@14Ž#Iþà»&“I§Ó¡Û4¾RÎãLgÏÚrFTÄ…À[´ŠBÑKp3ûÅ'ÜÆ÷ÚyÄŠª_%Ãròóó'Ož<hР#GŽÀÐÁÓjµäà!èÔ©Ó‘#G¦M›Æ7;)wX·n]ttô²eËŽ9òÖ[o…„„\¼x±d?ѨQ£ôôôõë×ïÝ»—X/Õ*œ?þ?ÿùÏœ9sxÏÇÖ­[:d'‘6pâĉ7òWÒÒÒbcc»téâìì\¬![¯×¯[·...Î>{|§>v� cøe°n¥†Ú�±.ª·† ÓÄrÈÛÁÇFשSgõêÕ½{÷Æw‰ÃÑËe2Yƒ (¤R¿¼W†ô!øf¬CÓx W*•¤Ù…p§\.çm\£¿è!ý”Qd4dP?¥¦qåÿ·Qô¿ÑzÍE XS!áÃ7Û.:¢¢Ò0÷õç‰Z­þøã<˜™™9tèPj8߬Y³/¿üß›8qbTTÔøñã<^qáW_}Õ¢E‹·Þz‹16a„W^yåСC%[¦cÇŽ;vdŒýõ×_¿ÿþû Aƒ>üðCr ?~âĉ`~GeŒ½ùæ›þþþóæÍkܸñŒ3víÚ5{öìÌÌÌ^½z5iÒ3yåÊ•ððp__ß=z¬\¹ÒÁÁ¡eË–Ô˜çåöF,]ºôܹs‰‰‰~øaÕªUvìØ±zõêÊ•+3Æzôè±}ûöyóæåçç¿ùæ›Í›7ÏÏÏ ›2eÊðáÃ?ùä“ñãÇ_¸paäÈ‘5kÖ:tèîÝ»SRRT*UHHˆ££ãÞ½{ÃÃÃSSSß}÷ÝZã,P‚“q ÿðšØDè2®¦�_óŸ'÷|„1i|h$c2ÆÒÓÓ¿üòËøøxàË…�� �IDATVèÈAŒ2÷ØØX8É­V+ì °z!F3ú‰oAÍ «ï€‰BéEylÞ_K7P`‚½yA©ÂcYN³fÍŽ;V³fM___ZÎÙ³g‡……1Æ‚‚‚ºuëV»víiÓ¦ÑiРA=*W®<`À�½^ûöíÕ«W3ƆJ%U†Z¡ÊlÛ¶M¥RÑßU«V=vìµÿ) ÀLº¸¸_}èС>>>&“騱c¸4Å-[¶(•Ê:uêlܸ‘<U«V­ZµªÍLJ$’¯¿þš:㹺º–^³Ÿ§‡%K–”^Oñ:üúë¯ô~šI__ßcÇŽaàÍš5[·né‘UªT¡æLÇŽ£ÙÛ¶m|êÔ©ãää4{öìÛ·o3ÆFE+²yóæ‚‚ÆXµjÕˆ‡½L@ P™Ÿ¯TÆ3b0r¹ÜÕÕ•fî¾ö—WFDùüˆ&H$fß¾}€^œ°_!Ý ˆÔÐWxüIáë \@03 r£`9Æå£ÛÙE°Âs^l€ʈå888ÔO±ðŒ1ïÊ•+Ó±”ËåÐ š7o¾qãÆY³f­ZµêúõëÕ«Wwvv–ÉdeY>òéoîRÚHb&Ù?‹i*Š¢ßb6¥Š"Y­ZµEþ7PÚÍ4mÚáð³J`Ó=H*•â›^>...6ÏòÞÇ—ÜÜÜjÔ¨qãÆ ˜¤XaM]Ff ¹@ð+ñ!NG%yÍ›†ÈOƒRlÈt!o q OOÏ7n ?)òiÀ«Xa)Iâ Èî„癡¬0Ùˆx'q2˜ìd2½ÙÁÁ,x„<H¡Aªáf±X´Z­R©|œa/þ†ë¨ÄHu¯mTsLuÑÆÕŒ+òfóà“ÝE|ÐyQ…Œ¯¨ åeXÁé‹Ú‹†Ò!^\§Ó¡˜SQç R_T*D“ça9σ6›Í”Á³lÙ2êbi;Ø¡|!##£I“&Är àÃÜ„fpÂCo G= E³Bw ˆ—Õjutt”J¥999ƒ½ %c±XRRRøÒÔÁk¤QAù€wÍu`|ƒv‚°Âòä>a…UXˆKñß â ¶ “C°+:å£å<„††¾4Scï—S" ×ëO:õ²ÎdŧPR©ô?þ€N€j7H¦A _*†zV*•!#©™u¦Ç³³³Qâ ¶/º¹™Ð¨Àf ³ƒ— )>6n´4¥—³áË`ó©BE‹Fã¿àp(hmï—ó"±œ—AhÙ²åK\S¶M›6e6:™LfÓ ú%ƒ'T¼¯ ›™4Ä€‘%Í�lŠ _‡†朣 Ô#ž”C㡯ÀQ„|u±X¬T*‰7P5¼JÄ É9äáá‘––†9¨2|ĸ lh6-sÐ產ÑÀhùòeª&ÉßStm2ð7ìWEƒÊø~6%¸=”J¥MµM³Ù\´?tQ|¨0]±r߈†µ¢¦ÂÇ 4t?Q›å<;v¬â”ç)%pqqi×®]|h÷îÝ/½äX«V-QESt}B-¢HÐ!ƀ—t3Ñt$¯ðao¬0r F08i¤R©L&#ÿ ÝI¯5D©aÅ‚ÆC´^¡PŒ;6""¥ %‰R©$Æ€3bðNNN”úCHµ£Óé@ûh,AC€íÖ9>˜ IKÅÎ!߯¬h˜bŸ‚÷„"Ï <?Æ;‹ò†¢>¹MÑÑ=%ªÅvÓy¯²³œâ¡[·nU«V}‰­º·nݪ_¿~Ùô˩ȅýKRRRjÕªUaûåXºv5¨Õ"7…u dYbL$3«•‘!ÆÂºÎ"ƬŒ ‰U¬‰@e¨â§=b3…Ê âÂ(d™T*‚Áh”I¥F‰D,)•J³Åb6™cÇr‹…‰D‘hfZšqØ0¾˜ÒÉIS˜Ð&‹Í&“D*µ ‚Îj•ˆÅA‰Dbl‚ X­Ìj5‹ÅU¼‹­V«1Áj1f’ý-f³T&Ó›ÍVÆ$b±‘êg“OH"15kf'€vÃZ9ÀËÝ/'66¶ÌP^ú~9çΫqêÆ’“ó"öV+YÉÌf³¨0GG.— ‹ˆ1Ū1F F$YÅbb!V«U,L$’ÓD"‘” ÈÂ&"±X"‹¬V³ Èd2…Å ƘÉbÉå‰D&I¥R­F#-l '+ I0›L„%øV^N+ô6 V«„jÆÄ…ý¨Í‹T"¡{DV«`±ˆ$Áj•I¥–Âð9Ò2ÜÝÜòóóAY­R¨ziáûÍf³H"‘WFŒ/„S¬øŸï,WÔº…+OöUGŠ6)Fð7:d³†>NýB3‚b¿{)žå­‘üKŠ~‘N ¤ÏÌrlІ–x,M:Í»D"yrɼÇM"Hi Y2b¦Åb2™ …ÍfÅ ˆÅbÚRTKŠvZjIR¨Rƒ¦§lÂMär·@bØÌpÑÙƒ9›¶ Us¡›•JåK+Wž9£Ú² Ф"¹Cdr¹¸PÏx±VXôŒz ÔR)±UY!BÕ«Õ*+ ˜–Édh¤†æor‰Dy¡È`0ÐI‰DmÛ¶={öì£Zm…Ú2™L\X2àQéB:Žhô, ÛàìAÔã’~¤…¬‘®Äb‘ɤ”É`‰ A¡TšL&)ixëßÿɦ§'°œ'XÛløÖ:^[×¹(‰æÃ%lnãCºŸ¦…^U¬ °¨ï§è$ Êãq¥Qaø)¸Zµj:u X»vmɃŒŒŒ‘#GöèÑÃÏÏïƒ>HKK{Ö7˜L¦€BèÛ·oµjÕ"""*œ€)1113f̨V­[äææN:µsçÎ}úôéÕ«×;w’““[¶lжmÛ+Vh4š+V´mÛ6  eË–ÉÉÉ¥íµk×Ú´ióÆoP¦äÿ C† ñõõ-ß>yòd£Fš5k¶gÏ~{¬\¹²M›6¾¾¾IIIwîÜéÝ»wïÞ½»té2iÒ¤ÜÜÜ={ö4kÖ,  Q£F'Ož|YYÎ#N#•R.$å{Êårrº!Ñ(œ”_ RÎ%#Ü‹è#¨?ßU¹ˆ�¡q€D"‰‹‹CÓòÙP¼aBÁc|­eÎH†@eO¹\Ž–ä†á£œQ:½´Ñ‚åè_r¡Pÿó‰¿v(ÃÚ¤I“cñññß~ûm¿~ý~ùå—-Zäåå]¿~1Ö²eË×^{í×_mÓ¦ xº‡1æïï_«V­›7oRé~ggg¾ÆpjjjÕªUgΜi2™^{íµíÛ·5ê™P—ÉdT¾Œ1¶aÆ»wï¶oßþСCDÙ[´hÑ®];½^f9xðବ¬ôôôŒŒŒ[·nÕ®]»R¥JgÏžurrB»¶Ò`9;wîLHH(úS||üš5kÖ®]Û¥K—ºuë®[·.99Ùd2íÝ»wéÒ¥sçÎíÚµëܹs§M›6eÊ”† Ο?ߦÎX‰Ã_|Ñ¡CN÷Ýwß}öÙg›7ovttôòòЉ‰4h³³óùóçÿúë/Zb>-66öìÙ³Œ±ºuëöìÙ³,wð¸qã^}õÕ;v„††~úé§½{÷¦ë999³gÏž2eÊ´iÓ7n<wîÜW^y%66699ù¯¿þ<xð;ï¼óé§ŸvéÒeíÚµ}ûö7n áå2) Ô±ç;Ó 'zƒò™1t'UÿDIMÞç=ƒX9ó-M,„´I¹\Nï1›Í¤ÄS”ª–Ñͨ%Š„DHåPM`˜B3ª[Š4Š2�«£›ÑÖÅ PŽïWý|‘œ| ¨‰6ª�ßÍúYÛ}½¿Ø=O²hV!*6Òzoa+Z ‰@ƒ ÖžG˱'NLŸ>ý“O>™>}zXXؤI“¬VkzzzXXX\\Ü¢E‹¢££=<<~þùçéÓ§{xxœ<yr̘1·oß;vì™3g<<<æÍ›·jÕ*¼ðÕW_]¸pá¶mÛæÌ™óÚk¯õèÑã¹OÔš5kæÏŸÿÍ7ßÈd²‰'Z,–‡†……;wnÖ¬Y›6mòððغuë”)S’’’ÆóæM‰D2iҤÇ{xx|öÙgÑÑÑ¥ÅÒ¥Ò… ‚Vd8|øpLLLXXØG}tèÐ¡ØØØ/¿ürÒ¤I{÷îýõ×_'Ožœ˜˜8~üø”””™3gNŸ>åGãããÇÿþ}‘H4qâDÈv¨ €Ž8¼Ý ÖŠXCã>"Ô ¤<Z&pއF¢(Ê?Óõz=q°=ÞÔÃ×U#-´ºbÞø^8`rp?€úPMä$ãDhÜóÏm XÖÅÿŠá—Ôû©A±´H¡PP‘ˆbYð¿šs‰Db0´Z­V«¥øçd9‹-êÖ­Ûøñãé¿qqqýõ×úõëøá‡   ¶mÛ^¾|955Õ`0\»vmÀ€Õ«W?qâÄ€š6mzüøñììì“'Oúøøøûû›L¦Ó§OÛ¼?00044ôòåËçÎ{¾ãôÓO?Í;÷Ûo¿íÖ­[rrrJJJ¯^½ºvízåÊ•;wî<xÐÓÓsÀ€5jÔ ™˜˜X§NwÞyçÞ½{"‘hÀ€‚ ¼ÄF•§‡äääÛ·oët:½^Ÿ”””’’Âóöö1bDÍš5<˜––ö÷ßwèÐaĈüƒ÷îÝKLLlÓ¦M=RSS/_¾lŸÌ $ü¢è2 ¡HAudò„ÁŽüPè °_ñú_Гï'Í_A·P°:B†ˆ#Ÿ æ‚K_„׬jb±X¥RÑGùô*rÌW&ŸHÓ²1 ‚E=¹õ§Jݰ6mÚ42¬­\¹’1¶oß¾zõꥦ¦Nœ8‘hÓSr…'N4iÒ„omBàåå¥Õjóòòrrržû¼¼¼¸¸8OOÏ¢o¶Ã³ÎäÍ›76l8cÆ ÆX:u’’’t:J¥¢zò<µxñb77·:xyyÙç³BX,vttDÐßå“/… *Oìxi*dš£{¨ç eö M^BvRM(Xþ!¾ï5T.”M#ÆÀ7™&¤FÙÙÙäÂAl‘HKÉàˆ!U†p�_!ÖHF?Ø0^Ê‚áëq,‡WGŠæT>¡±ôãÞöL±Å¾óqé8O¾¹Øï ŽÀˆøL gJÁy–S,üòË/'Nœ¸páÂõë×ßÿýÿ÷þààà &¬^½š'FW¯^=pàÀ¿ÉذX,Ÿ}öÙ™3gþóŸÿÔ¬Yó"¸}ûv…b“—/_^µjUtt4$Œ™3g2ÆŠ ¤ÞºukÑ‹¯¿þúúõëëÕ«W¾c9wî\LLÌ ÚØ»4 C‡Ô¿€¯NÕX*r2®v'_Þ†'Ó 4p΃¾óªñE›":ˆ=ãÛ"Ыˆ!ÁádCßÁ#ys<0èÁPeC%QEn(”®¿úê«Eç°R¥JÆ {·à}!6Uº‹¥û|ón+úþ'3­¢Ö¶¢œ£èƒ|<÷{òˆÐx uJŒåøùùíÞ½;<<ÜÛÛ; ***++«Ø;ÝÝÝG½mÛ¶ÄÄÄÓ§O¯Y³?)•Ê?ÿüóàÁƒ …¢]»vo¼ñƳ¢a6›¿ûî»úõëóÍ7t¥N:mÛ¶1c†N§óóókݺõÌ™3gΜ9|øð¸¸8¢¡¶lÙrðàÁØØØ~ýúEGGoÛ¶­iÓ¦ï½÷^^^Þ¹sç†~ùòå1cÆx{{3fÇŽÉÉÉR©tôèÑå‹vÓ¦Mi¹ûôéÃ_÷õõíÓ§ÏòåË×­[—––öoÜrÏ3gΜ:uêðáÃÏž=KK|ìØ±ùóçûùù7n×®]ç2fÌWW×½{÷N˜0!333  iÓ¦3gÎŒŒŒ>|ø•+W–,Yò²²œ† ¾ô¥4JîÝ»gŠéèèHí¯ìð”pá¾}âù5“×jµ»víâI‰^¯OMM­R¥ 5‘ÍÉÉÉÌ̬U«E¦§§¨Õj¥RIüF­VW«V---Í`0x{{geeegg×®][¯×S�´L&³1Èdff’=ÍÉɉï+úôê7nðW\]]Íf35>quuõðð°X,·nÝ¢_½½½Fãýû÷=== ÅíÛ·ÝÝÝÝÜÜnݺ¥T*ù~9çÎkذ¡³³sI¥‚æææfddÔ¬Y“ò]ÒÓÓµZm:uhV1{Œ±Û·o“µÚÓÓÓÁÁA£ÑÐìI¥R›âüÿvïÞ=pà@T(v¹c*•ªzõêééé:ÎËËëÞ½{:ÎÙÙ¹I“&S¦L å—›1æàà`Óyhÿþýï¼óN饂 ‚€¾^´?³³³³²²°ÜüìÝ¿_«Õ’0äææf2™ÈeEòÊóñ­Vëþýû*`õ¬¬¬”””6mÚëO¶ÃÀÉɉ( clß¾}ýúõ+›R/P;£Ñèä䔟Ÿ¿ÿþñãÇ?VËQ*•¼…ÄÕÕÕÕÕÿ¥ÎWô7ê¡„~ãîîN4èq–çH$*öÍ@Œ´Qþ©TŠÿâ›Î4¥......E1´™UV¤éËf¯dáÿ]nÆX\\ÜСCظqcwwwooï¢Ë]ö ‹m¦ÈÍÍö$¿Ü6†d2Y¹›Kh]ȱa§€Ïà7d×)((°Ïá³B±ÛöØ ;<-´hÑbùòåæìÙ³óæÍ ²Ï‰ì`‡g{µÇ‰'žWõ2 qO;wîܹó³>¥ÓéþüóOû޲ƒì`g9Å�EétìØñåîX6££®À]»v}¹7ŒýÔØÁv–óœ@Á*/}?ÚçStžºwïþ—‘&°X,¶sìPAYŽH$z‰‹éÚÁv°ƒ*˱Z­¨še;ØÁv°C‰€££#òœþaXkÑ¢E¹¢Èyù†!¢SE[° ‹˜  "äÿìzÂÌ „LEjT§®‚¯iE>¡6¥"Ê'''”EøËqvvvppx¾BªÏ f³9;;ÛÁÁÁÑÑ‘•Ÿ%//ª-9::–ñ <òóó©ä¢““Ó“; –/dffªT*¹\®R©Êx CAAR©tvv®PkG-•JÓÓÓO:Ul>vùB¥J•Z´h¡V«ù²˜ÒÓÓ+ b6 ÑhŒF£B¡pvv®'4''‡ªÕ•=1/ ¹¹¹"‘ÈÁÁ‰´¶á&“©Œ¡¹¹¹/^ìÔ©++‡v±ïéééååe±X4MÅÙÐñññ•+W®U«–Ùl®PˆÙÀ‰':vìHŸ²ÞkIÁýû÷ïݻתU+«ÕZ§èôéÓ-Z´`ŒÕ®]»U«VMÅqpp s§ÕjŸ¯ULi€ÅbùóÏ?©PžN§«€’ 11Q¡PÔ¯_¿‚ŽØØØFU®\¹ì‰yQ8{öl½zõø¼r{*¨ì`;Ø¡ŒÀÎrì`;ØÁeÏŸ—süøqhmíÚµ‹‰‰©[·n±µî˲³³ccc›7o~íÚ5¥RÙºuëøøø¬¬¬nݺ• ðòòjÒ¤I¹/ê™3grrrªW¯Þ¬Y³Š¹íòóóu:]åÊ•áá|ðà9cìgò9–Ûl6·oß¾" söìY½^_Á‹.¿H– ܼyóêÕ«:uR©TÅÞððáø¸¸–-[í›U¦ZÎŽ;FŒq¾>|Xl•2ƒÄÄÄÀÀÀ“'O^ºtéêÕ«Œ±eË–¡ÅEÀùóçïܹSî{è?þ6lØ™3gnß¾]a7zJJÊ™3gxŸpNNŽ=›òù`öìÙ“'O® ÈÌŸ?M„+,\½zõÒ¥KöÃÛ¹sg``àƒžÀžãââÊSËÙµkWxxxff¦ÕjmܸñÏ?ÿüî»ïâ×Ñ£GSû©S§Úôœ(¸víÚ¬Y³c2™lÆ Œ±•+WÆÆÆ~ôÑGtÕ+W*Uª´k×®˜˜˜‚‚‚E‹M›6­dq8vìXttôüùóëׯäÈ‘U«V-X°€üüŒ±ððp"÷£Fjß¾}ppp¯^½‚ƒƒ'Mšäìì<{ö쯿þúÂ… ßÿ}‰OÎñãÇ'Nœx÷îÝœœGGÇΟ?Μ9]ºt‘H$”wõÆo 6lÆŒ¡¡¡4“ , f £GîÔ©ÓåË—çÍ›ÇS«Õ¥$@§Ó%&&z{{W©R%//O.—ߺuëáÇMš4ILL¬]»6ÍgÉBffæ˜1cèï*Uª,_¾üÇܵkc¬}ûöcÇŽeŒ…„„PÅ„ˆˆµZ½gÏ…BqàÀooïž={®ZµŠ1¶yóæRš–%K–\¸p1øî»ï>xð`ܸqôÓ÷߯V«7mÚ´gÏÆXÇŽ?ùä<¸víÚ0ƺuëfÓ,¼m èÛíââòóÏ?oß¾LÀ“1fƒdDD„V«õ÷÷ÇÁ)YÄÆŒS³fÍ lݺûÙIºtãÆŒŒŒ²G’1váÂ…%K–Lš4©nݺ£Gîß¿ÿ{ï½7räHŸ &,Z´èâÅ‹Œ±   >}ú¤¥¥………уëÖ­+½¦G|÷ÝwsssGE×£¢¢p!Y£FíÛ·÷Ýw`\FZN÷îÝ}}}FuãÆ}ûö!BiôèÑGމŒŒ¬[·î{ï½G=WJ,KÏž==<<"##“’’ ´aÆ  2²ÕñãÇÏœ9Ã#Yâ+”••õçŸ^¿~Ýd2%$$œ>}Z§ÓíÛ·ïÒ¥K³fÍZ¿~}ddd›6m† ’””{öìYNGˆi4š¿þú‹hJ‰CëÖ­»té›0aBjjê¾}ûzöì÷Ÿÿü'**êã?>|øìÙ³ùå—ãÇO™2%22R¥RõîÝ;22²eË–ƒNHHèÝ»wµjÕ"##ãââBCCKå\¾|¹R¥JçÏŸÏÍÍMOOÏËËËÏÏOOOOJJrww?þ|it(quuŒŒœ?~FFÆ¥K—öíÛ7eÊ”ÀÀÀñãÇ/\¸píÚµÁÁÁ ‘‘‘UªTyûí·333çÍ›g0"##ׯ_¿gÏžÈÈÈ»wïöëׯ4æäë¯¿ŽŒŒüøãßÿý… ž={Ößߟ1)‘HFŒqøðáeË–…„„Œ;vÁ‚$u1Æ~ûí·™3g†††Ž92""âçŸ. ôúôéc4###•JåðáÃ<8qâÄ~ýúMœ8qñâÅ«W¯¦ÛöìÙ$cbbÖ®];jÔ¨øøøÒë:vìXddäŒ3âããýüüI­VûÎ;ï�É?þxß¾}7nÜ8sæÌñãÇ‹ErãÆGŽñððèÙ³gi„Éååå<y2))I«ÕîÛ·ïÚµkYYYG½uëÖ²eË–-[ñî»ïΟ?ÿüùóo¿ý¶Ñhüì³Ïc¥$CL˜0ñàÁƒï¼óŽV«ŒŒ4|µ#GެX±"'''??¿oß¾ejXsppP*•"‘ˆï”óˆÁ`ˆ‹‹KKKËÎÎ.˜Ë¬¬,2/êtºÌÌL­V«ÓéjÔ¨±lÙ²§DòßC@@@PPÐ|péÒ¥Ù³gÏ™3§iÓ¦ØRF£1..îÎ;¹¹¹b±ø‡~ظqãÎ;!­ìÙ³gË–-¥±uT*•Z­fŒ¡‘OBB¹sç6lØ Ñh®\¹¢Õj©MY~~¾§§§J¥ÊÊÊòôôtrrÊÍÍ5›ÍYYY< ~\¿×–-[RGz›}B×Ñ£¾dA"‘xzznÞ¼Y$mß¾]¯×k4ww÷J•*éõz­V›••E÷¨Õj¾N§“J¥žžž&“Éd2yzzJ¥Ò§ªU«Ö½{÷?þØÁÁaóæÍ­[·ÎÌ̤‚›6mÚ´iS÷îÝ7mÚ$Bbb¢N§£¥$$µZmRRÒ•+Wøë%®#* OOϵk×nݺÕ`0h477·Ê•+ÓLÒmü¬•J5~üøÄÄÄb;=ÿ{pvvž?~bb¢D"ÉÉɉ‹‹ËËËËÊÊ’¤žŠE²nݺt(JÉÎ;3æ“O>yøð!]5j”\._±bE~~¾Ñh¬R¥J``à™3gZ¶lÙ²eˬ¬¬ÈÈÈàà`¾¥r‰ÃªU«ÜÜÜ4Á`ÈÊÊÊËË‹‹‹CŸF@§NFŽ©P(þÍæ/ù²ž$ø7jÔhúô饴ï\£F¼¼¼r±öìÙó÷ß_»v­¯¯/e]ðP½zõéÓ§W©R¥|› Λ7O,_¸p!,,¬(žƒŒŒŒ„„„¡C‡Ú4r}9 ))éÔ©SáááÏm(=èׯ_¿~ý-ZÔ©S§åË—Ûܘ˜8~üx’-làúõë5jÔ˜>}úÓ¯u™AÍš5GŽYzï÷õõ…ꙟŸŸðöÛoS—ÛV¯^}ùòå°°°   Ï>ûŒ7¢–*Ðìùùù•/ù iGGÇÉ“'{{{ÇÆÆ–R…-ZLž<9==ýòåËtÅ`0DDD{s|||i˜ÝßxãêÕ«oذ¡yóæ6.+‘H4yòäæÍ›ÇÆÆjµZŸo¾ùfÒ¤I ذaøqãlÚSeg�� �IDAT–6\¼xñÂ… ÁÁÁÁÁÁOi ›<yòÝ»w“’’J«rqáfddŒ9²N:¥$kÿKزeË€†:iÒ¤ãÇ£Ç6IãÆ»|ùrllì|Plḣ~Ø¿ÿØØXÑ¥‹-‚S§Býúõ'Ožl6›É5B^A¤ŠÖ­[/Y²dË–-‚ ÄÅÅ-Z´ˆ¿áôéÓ HHH 9pàÀŠ+š4i j@ݺu'OžlµZãããùëgΜùí·ßþåËŸSËqww¯^½:cÌÉÉÉËËK&“yyy9;;GGG¿ûî»ÝºuÓjµ³fÍ*qC"‘ìØ±câĉݺuÓh4P(ÉÉÉ&L˜:ujXX˜J¥ªZµ*¹—/_Þ¿ÿµk×.X° 4fë֭Æ #K+cÌËËËÕÕ5,,,%%¥[·nz½~ôèÑÕ«W—J¥­Zµ:tèP«V­²²²´ZmÛ¶m‹QK\]]½¼¼D"‘Z­öòò’Ë匱\¹reìØ±>>>_~ùå·ß~«×ëkÖ¬Ésss«Q£É ^^^NNN[·n>}úÉ“'Fãï¿ÿ^HR5jüý÷ßÍš5suuU©T2™L$Q°¦T*U©T¥Q$Êd2effž;w®_¿~ÕªU[»ví¤I“¦OŸ.‹ƒƒƒ‡:hÐ ???Ú`Û¶msppðòò"q–˜ý³ÙyÉ‚¿¿ÿM&Óœ9s:vì¸sçÎnÝºåææîØ±£J•*aaaS§N­]»öÊ•+W¬Xa0j×®ýÞ{ï‘DÌkß¾=•ó(qرcÇÀ»uë–——·eË//¯©S§Îž=["‘ 4è£>úûï¿ÍfsïÞ½ I±X:dÈS§N=. ·DÀÓÓQ¼CráÂ…ûöícŒU®\ùÉHÒ!*=‚Þ¨Q£K—.½ùæ›ÉÉÉJ¥’Ü'L˜pãÆ€€�£Ñ8pà@Ÿ°°°aÆmß¾]§ÓíÞ½»4!.‘H”J¥———J¥Ú¾}û€hö6oÞ|ïÞ=///j2àëë{÷îÝ›7oRÀÈó¨uëÖ'OžÔjµ»víz÷Ýwåryy¼qtt,Ç‚7çÏŸ§‚7*•ªBM‰‹‹£‚7 18tèPÇŽœœ$Iy¼qrr*_3f±pìØ±-Zh4B²Bᆂ7jµZ¯×W¨‚7û÷ïûí·ÕjµÁ`ø7žü´´´³gϾöÚkZ­Ö××7""‚¬û÷€‚7(T¾pêÔ)*xS²Ä¼aƯ½öÚÆŸé©˜˜˜zõêÕ­[7??ÿþýãÇ··h³ƒìð2C~~~ttôöíÛÝÜÜ7n\ArfÿgÁÎrì`;¼ÌРAƒåË—SªÜ!C*lIŽ ßÿ=_ÓÎrì`;Ø¡x¨W¯^½zõìóðo ¤¼ƒÒ¢JèÝ»wËr$|AJJJyY“sss===cæÖ­[g¥sss)B«ÕV(Äl�Vãìììôôô²ütNNýa±X*àÁ'‹e2Y…ÂÐHMM¥š x:ššZÆÞÁg‚¬¬, @ÕëõaûÁYöÄü ÈÏr¨ÝHÙ;`k×®Í3ùùùåÅr*UªäììlµZµZm…rA{xx¸¸¸T@ÄŠ.¢T*¥–!eŒ'en2Æ Cœ¢š5k* ±X,•J+`kW£ÑÈ3™Lв7jÔˆËÏϯÈ,ÇÅÅÅÃÃÃjµêtºŠ°ýªW¯®V«Ë‹˜Û€§§§MrÏ?"Öøòv°ƒì`;ü{ PÒb"Ö222Ž=ZzÅãJÐàëëK™@åÛ¡Öb±aÐÑѱâwh/VçU©TRéÿ®KÏd2‘]î{©4åââRqâžK ¬VkBBÂÕ«W_²ý,‹_ýõJ•*9::¾p[T¯×Û°5¬yyyµk×®‚C¡PX­V£Ñ(BùÂgee]¹r¥}ûö"‘¨"[½Š‚Õjýý÷ßýýýE"‘V«­È~Knݺ•ŸŸÿÊ+¯X­ÖkŸ�ÉÉÉV«ÕÇÇG„—fPO2ÒX,–Ö­[SŽóK*•Šê šÍæR*Wz@y9|M�{WP;ØÁv°CY)mö)°ƒì`;Tt–c±X®]»–™™yÿþ}¾ø`……[·nÝ»wϾä/+¤¥¥½ûðYáæÍ›iiieð!AèDãJvvöµk×ÌfsÑ›ïÝ»W‘Cöÿ=ܽ{·"4ù-G¸ÿ~i,ñ󳜼¼¼6mÚDEEmß¾ý›o¾©ø3اOŸŠß"×Ï Ó¦MëÑ£ÇË7®=z”x[Ûb¡   M›6_ý5®œ>}zÉ’%Åö?~üËàºqãÆuëÖý/¨‰'öêÕ«Ä_[¡...•*UJJJÚ°aÃàÁƒwìØQ£F?ü1¶hÑ"r„4hÐ !!úxxxL˜0aïÞ½'Nœ=ztTT”¿¿™Õ>Ú´iu=xã7¨@ïÒ¥Kß|óÍ[·neddLš4©´øù矓““ƒ‚‚Ö¬Y3pàÀfÍš]½z•ö·££ã´iÓŽ9rèСðððÔÔÔ7{zz’]»v]°`y‡êêêúÕW_õêÕëÊ•+eÃS?ÿüsʾ<xp£F®\¹BÅþF}ìØ±Ê•+=ztÆŒ7nÜØ¼y3¤gçÌ™“˜˜¸uëÖ#F¬Y³¦yóær¹<&&†1Öºu뀀�|å·ß~;þüˆ#¢££ßÿý'NP†iÿþý}}}oÞ¼I=(•Jå¬Y³þüóÏ¿ÿþ[§Ó­[·.$$¤ &!55•ÚôŠÅâùóç3Æ~ýõ×óçÏ{{{7kÖL­V=zÔÑÑqøðá´Ü„äþýûc 4 ùñÇoß¾ýÞ{ïáàqöññILLüá‡Êf,6°yóæ7n̘1C­VW©RE"‘ÐéfŒ9;;O:õ?þHNNÎÉÉùñǃ‚‚Ö­[wõêUÆXÏž=;w™ÉïÉ®]»>a¹£¢¢úöíK3I¤€1öþûï·lÙ² FºwïÞFmذÁh4úûû'$$ܾ}»eË–ï¿ÿ¾›››Ùl>{öìo¿ýFˆµmÛ–ï†ù믿¶k׎îß¿ÿÑ£G>|رcÇ^½zéõzÚŒ±I“&edd¬[·nРAµjÕZ´hQ÷îÝË@6ºsçNtt4ýííí=bĈ­[·R3âb‘tss;zôèÁƒc>>>|—“?þøãðáÃŒ±¦M›•›–Ã/ÛÚµkSRR¢¢¢BCCkÕª5gΜ͛7Ï™3gÓ¦Mþþþ™™™!!!W¯^>|¸N§ó÷÷ŠŠZºtéÉ“'£¢¢‚‚‚¢¢¢ø¶¥}œæÌ™CA‡ãÆ‹6lØ… N:5wîÜM›6•\¾|ùW_}¥Óé†~õêÕÌÌLÿM›6Í™3'666**J£Ñܼy3***%%%???**êüùó³fÍúé§Ÿüýý<x0dÈ{÷îEEE;vþüù¥Ñ¨(,X°`õêÕþþþyyy¡¡¡W¯^ ÍËË‹ Ú»woLLLTT”Á`¸víZTTTjjjHHÈ¥K—üýý?þÉ'Ÿ$%%EEE}øá‡ß|óÍôéÓ§L™R¿~ýÆO›6ï•pôèÑ•+W4(**jäÈ‘_}õ•¿¿¿Ùl1bÄÕ«Wƒƒƒïß¿ïïïÿË/¿LŸ>½^½zÕªU“ÉdmÛ¶-›tëÖ-ÿ½{÷N˜0a÷îÝÓ§OoذágŸ}6f̘¤¤¤Í›7S÷ƒ®^½:>>þÓO?uqqéܹóܹsׯ_¿wïÞÈÈÈÐÐP:8ëÖ­ó÷÷ÏÎΦY:t¨F£¡f‘eÉo~ùå­VûÓO?Íš5ëüùóQQQwïÞ ÍÎÎö÷÷_·nݼyó6lX¥J•JÕªU«õë×Ï;·sçÎ...Ÿ~úi||<-÷áÇiO>y¹·nÝ:gÎÿëׯ<ØßßßjµŽ9²l¬v'Ož îÚµ«Z­3fŒ««k³fͦOŸ¾{÷î_ýuË–-‰‰‰D£6l8uêT’><dÈìÉzõêy{{Oš4騱c£G>yò¤¿¿ÿÅ‹CCCïܹuãÆ NuæÌ™2š«««¿¿¿¿¿ÿï¿ÿ¾mÛ¶;v̘1£yóæCòüùóãÆsssëСCDD(á_ý5~üøªU«¶mÛvÖ¬Yÿ¾Áy ‡„‡‡wíÚ5++ëÎ;—/_¶X,*•*11ÑÝÝ}çÎÆ óðð0 ÉÉÉôH•*UîÝ»7|øð²9QwîÜÉÊÊjݺu£Fîܹ“““sñâEww÷É“'—eÏ.µZýÕW_y{{'%%i4šÄÄÄ5j´oß^,Sד·Þz‹×j{õêÕ«W¯±cÇ&&& ‚@³zéÒ% nÖh4?ÿüó±cÇÊ�óüü|ggç/¾øbäÈ‘;wîttt¼råJÍš5wíÚõ8WÙ¦M›æÏŸïáá!•J![äååݸqcÚ´iiii......éééE+åÔ«WjþëõúöíÛשSçêÕ«†ú®¶oß^&“]ºt©F•*U’J¥Mš4)›4 ñññ111kÖ¬Y´hQZZÚƒÚ´i³qãÆb]J¯¼òÊž={z÷îíîîž“““’’¡M›6÷îÝ«U«–ÙlöððP«Õ—/_Öh4IIIµjÕúâ‹/ʸ¯eß¾}CBB$Ibb"]A„#GŽ$%%ýòË/S§N­Y³¦«««B¡ðññIIIÉÉÉiÛ¶mÆ oß¾M½H*Uª4mÚ4tgÇr_¸païÞ½íÚµã—ûúõëíÛ·¯Zµêŋ۷o_·nÝk×®•Y4pBBB›6mêׯóæMooïW_}õÁƒ6γ%K–¼úê«E÷gBBö¤OÓ¦MïÝ»—‘‘ñÍ7߬X±ÂÃÃC¡P\¼x±K—.K—.?~|Ë–-ƒƒƒËÀŽÂsrrjß¾ýÖ­[ ÅŽ;ôz½»»ûìÙ³;uêôûï¿wìØñâÅ‹...íÛ·ÿõ×_7oÞüꫯîÙ³çí·ßvwwÏÎΆ+++ëîÝ»NNNnnnYYY©©©åoXãA.—ó‘ùùù‘‘‘Œ±ÀÀ@‹ÅòÅ_œ9s¦Q£F|)§õë×—j獵™L&‘HÊìs"‘è )·„ _äÃ`0H$ªÐ•››‹Y¥+ãÆ+³lªÅ‹çççøá‡:u=z4d…Bñ¸dØÍ›7ûí·¯¿þzjj*ŠÑ®ZµÊÅÅ…:ÈmÞ¼ÙÃÃ#00Цö¢X,^»v-c¬,—æ)!&&æÏ?ÿ [°`/úQ3«¢ððáÃY³f¥§§óíÝÜÝݩմD"Ñh4XVì²ÏË.zÜÜÜbbböìÙ3uêÔ‚‚‚7>M…G™LÆW÷¡å¾yóæ„ ¤Ri\Ð'ÀãÖô †Ÿ3ftíÚ•k‰DÒ¡C‡š5k^¿~ýý÷ß/³:{W¯^MJJZ³fB¡ œ5kVûöíßxã/¿ü’'ÚŒ±´´´™3gfddPEGؾ}{µjÕ7n\±´pwwŽŽpuuÍÌÌüî»ï¢££+±ýû÷Cñ*ÐëõäŠx-566vñâŧOŸ–J¥ƒ¦Ÿ*UªÝ·oß©%þ¬°iÓ¦åË—ýõ×o¾ùfTTTnn.]_·nŸ–›••õã?Òß‹-jÓ¦Mtttƒ Š}'5m$Áùß3ÞúQzNN OOÏ%K–ÐE‹Åòí·ßò·?~œºù&%%ýöÛo}ôÚypqq!¯•««+˜÷š5kÊ=û¯   <<\.—ñÅV«•à¥K—Ž9RìS{öì¹qã†ÍÅÓ§O=ztêÔ©3fÌ`//,Z´ÈÇÇ'::š:ò]½z5,,¬Y³fãÆ;v,ùKÊÀœ3aÂ///*?xòäÉððð?þxĈ‡ŠÅ?þøã¼yówìØ1jÔ¨¥K—}Û˜1c/^ìêêú¬Ü·LYÎüùóF£ŸŸß„ jÕªU«V­3f|ÿý÷~~~‹/>zôè¶mÛÊ~7 4¨]»vAAAƒnӦ͊+N:uñâÅÒë.\¬ èààðý÷ßϘ1£Aƒ ,øé§ŸüüüŒF#ùôüüücW®\9rdBB‚D"yë­·c;àçç7qâÄ:uê”}eâ×^{móæÍ#FŒ¸|ùrDDDƒ """6nÜ(•J‰a„„„´jÕ*<<n•¯¿þúèÑ£~~~ƒ~øðá矎·½ùæ›IøÁܾ}»N:Å~tâĉ5jÔðóó‹ŽŽž<yrƒ >ÿüómÛ¶ùùùåää,^¼˜16}út‡åË——m­Y³fááá‹-ÊÏÏ_¶lYŸ>}Þ|óÍqãÆuîÜ£þûï¿9B-}}}‡ ¶pá¡C‡ÒrŸ:u o‹ˆˆ E óòòªY³æ¬Y³Ö­[§P(H-_ßËË+,,lÙ²ejµšP¥Ó½zõêE‹µjÕªÿþ .6l˜¯¯/-wrr2:C]î/¿ürüøñ_ý5żd°bÅŠ .øùùuêÔÉÁÁ!88øÌ™3={ö NII9{ölàžž~âĉsçÎMœ8±^½z×®]8pàñãÇßÿý®]»ÉY³fµjÕªU«V!!!óæÍ5jÔüùóøáŠòh׮ݠAƒfÍšõÞ{ï%$$øøøü[_Ö³]»vׯ_zÁ`J¥V«U©Tj2™¨}½Ñh$ÝÙh4RQ Ò²A z;r¹œê×>Ÿé�ož©wµÑh‰D2™Ìd2Qá)B2))I*•Ö®]{À€ׯ_§ Ž§¼y¦ÈÇ?xðàÍ›7iÆø™‰D 1<ÂV«•¿ŽYågû™æož£Ño±Ë*“É5jD­j a›-A÷›ÍfþYƘÙl¦¯K$¾:–Ùl£Æª=ÍŒ=ýXPðæY›XÓä „ãââˆ5’9”1F±X,f³Y$ÑÌE¾ØY5›ÍT…úéqCÁ›g!,•Ji&Åb±Ùl–ËåV«µX„ 1›uåʹ\îííÝ·o߇ž>}ûË-‹é嬰§–›fÉÆDÿÿ¼‰wwwú‚7„ŒB¡Àlã@ш04^þ E˜f‰FJ¾› ÿ|§o ÅÓ«¼ØŸü Û488h¶·?ézÑú”öç’lDmÃ-Š m4±X\ŽFj cC’V®\yñâÅ#FÜ¿Ÿt‹²~6ø¿ÿ_„mfµgòqÈáÿwK*vÛ\´™„'ÏX@Qo\ÑQØÜ ‘H@kþ_ä1À²TÑe"„‹u=>nFFFÞ¸q#44ôÁƒ½zõ²Y)~¹yÊË_,3O)Jš€Ãã–¬(Âü,=n×Ùi-vÚlѧܟ%»"ö® láÂ…?ýô“V«:t(ü%¥ AAA%Õb¯BÁìÙ³Épü¿ µk×þüóÏɈÿ¿ K—.ݺu«V«1bD¹äÙ¡"ƒå0Ê×+Ë/vïÞý¥œIÊÿý‡ªU«–ñvªhàââò?>vx–#‹+~ü¢H$"ó¨ÙlÎÊÊ*GL¯Å+_LžøÆ¹¹¹0ûþ¯|‹åÅZÁ'€V«¥ Ðr? eh ôBP°g%wô‡Ñh|áV³hkó°¥RéééYñ[´ÑYbŒåååQéšò•jc&“©Ü1yV /«Ùl¾~ýzù¶*_ >èæ…[Á'�Y8óóó_¦A=ªU«Æsww/‘PûŠÉP³²²^¸Õ”J¥6qÕÿXÛ½{wÿþýízŸì`;Ø¡dO1k‚ ”K¢Œì`;Øá%ggç:<b?¸*‹øb䯿þêÝ»7›#”^‰DB¾ ‹ÅB9Cô_‰Db±X(vžÒ†$ …¢“ýW¡P˜L&‹ÅBöSAD"¹Ž(nR è…R©4{¶º«Z¡P¸¸¸T¯^=###==]]sh°H5EE¯E÷o˜eÅb1u–EÈ<}ˆò�(kÁXɨûJçäÀ«R¥Ê«¯¾zïÞ½¤¤$³Ùlêk¼Å e8zŒ ܤQ°Â�V>îÑëõV«U©T©TJ¶JA ¥e�+BŒž¥G$‰Éd¶2™LºŽU ¬hö_bµZ)éD"‘ QƒÐ‹ÅÙi0±A¾h¤Ð0QU…2r(ù€¾hµZ±îô7-"ÝLI”-AHÒ·(ë‹ðÇ L°…èN¹\N×i#ab8æ°¦´tÍ�æÓjµZ,ø!軬05„&×)›„–’.Z,©TJÃ1›Í4K´“i}éìyúºÉd¢OnXn&- }Z*•Ò›i€„9þ& ‹¿7‹Åb¹\ޱÐBÐbÑéTšL&ZJú‰ÆBÕžD"”p¦—Ð@D"NáC¿b¿Ñ΋Åâšb¡Š •J­™Vv“Ñ€3½Vÿ©^‘ªíI$777“É”““c6›…š‚a¡Áy¨3aEŽÍ`0ÌŸš•YJ·ýnC† tppˆ‹‹›?~JJJÎ÷9’‰qê£ÍOã¥94›Í4:Ú´.´»hP´d4Qxýõ×_,Bm±XöÂG¬ñôy©t(.ž²´@wèƒÐÖ‰D:Ž®Ð t�d2™T*5 ôN±X,‹‘Y;Y-§-YYYùùùr*ELÜQ,ùë¿D„n¦ÏsB7ÐXàm£OH$’¼¼¼äää¼¼¼G×™U,y”H3@£”Géú—6.C": È:«-°X,ı±@£‘†�zA³Mo#¦E ¢Ÿhª 7K!ðdŽ– < ªô!Zhž“ñŽbÊ}£+`–‚ ÐRâ)Ú'„6ð£gi2‰ÄƒÓ¿8͸ü×Á¨°Rf³™–Ô™xaB3I¡é¥íMÛ˜¨’ûˆÛHѨåryAAÄ)šRªhõi‰œñÜŽ0(FH¯%„1Rbc˜ Hx<°^´=hVÁc¼ì+È LôE“ɤT*ÁÒŠ.60í.f³Yì"6šE^"s%³DÙ"IŠDºWjN}Ä€ L&“,R¦=¢uÞíl0<x@sÎ3M5)>WÐm[±jV«Õ"X FƒF£‰‰‰©S§Ž««ë±cÇ222´Z­Ùb[żÇOÏãiÅM&It‚hØ/°‘íEg9´Hd½žvh$D´€ý ²†–G‘v9Ò¤AÊqƒÕjUlQè†ê$'%Œ1NGhX%Vc€Ññ G‹`¡�æA˜€L€Šñä bµD"‰íf­V{çΞ¿2¡]#/ n8ÃD¿[¢°4XÌX ]·A¯‰ïòç™n�ΠÝüAb…D&“ º&hˆ0!ü‰Ùó¬‹]éЂ A˜Å³ôN> âÍ<y¢7¹¤mC'ºŒACä§§0Õ |üè ã[ÐiÐ!p…v^#ÄФR©Z­¦}Nïô~šRT -A’2aN¨bo@]Ã&Ǫ¡Ò¿”$µÚذÍhøF£‘P¥mI×!ˆ€V‚¯Ðlï¤û1v¤gb_aø$ð4œ2M8ƈãfœl”Ü’ÈvÊde‚ Xj[„®‚aŒAõ™Jlc™h€ò¯äº/tâSbÅ…T*5V3'%7%ÂíG/ÇA ÓAŒpD0õ7iŽhâââ  Åýû÷u:µ—Uô—HÈdÒGUS±ßèôA¬áõBÒAA0Ž5 õA;v–SÎÀË8dbB© ÚŽ$ˆÑîçÅ"¥R‰RÍ @8t…'Ê6&»GÛ:™‰þ)pøÄ%2‰Xb˜d0õ4)G(!#ÓÑ¢O“¶³�¡ÊÇBÀ‹Å,“ÉvËÌ¡fÙ:™Åb!yJ©TZ«[…î‚z±šD!˜Aø±ðÄ‚hˆ8$nÂ.û¼I«Õµ¢CEybdµZõz½ƒƒ äSB¯¨Š*)Ï! ƒ“…ÞÀ t&CkÁE8ø ƒàÄØ¼%“É ƒN§ƒíJ0j~@�JDXéUDåAP0c0Ì’. ÆÀœÂߌñÒŠÓêÓÞ†o2™T*•^¯çuDÞlerq‰DBâ8¤(°CpPZ&ºø"Y#ihÎIá€|FSGØÊd²‚‚Ò¢À±Hå‚u쾋9á͉˜ ð!ÞPÉ;¤aã·1cL&—»•J©LªtPêt:ᆠ¾.ÖïÕ‹±Ø &å ÛR²["Ü,í-ù‡óc¢‘ú+µùºYœ-6ŠŒô pw #N[삳 ËÒ]»vÆ¥3èôô,‘I R©ì‘…3L¯Òét|)GvfÕuÑ™f›d+dÒcRfe–þ–Ðf¡q,NÁv–Sn�òAÿiÀ¢Í“C ÊxkU‡�ížL7D ‰ÕZ«jµJô½¨`eÐP`"¦øBá¸ÔÑjµZE¼PMÄb±^¯'ö�¡‡sEø‘ö`´³§�� �IDATbÒÛR};½¥¹ErQ"gr³Ùl¬c´Ö±Jr$â‡bˆ{téU°’•‰7¾ñ¼t“!„�ØžZ­†èG@nqG'ÊH4×ÁÁ¥™èŒçÀ×aÒétdÈ¢¢@ çÐ`0Ð�y/81}:¡ ؉B¡À:B ¡âZàphñB7´#Þ‹�þ­T*éY¾ð ‘]ú/×‚Ê % B�µ«€DŒ“71“@“Æ«h<Õ¶QãH{€(F‡‡ŒVœßê4“ô-`!a»Ò; [ès´!‰nêt:ðr“6$˜+¸;ÄpwÚ p¹‘äL`€…X@û™”?BŒÖˆ®k·i•ï)U*UÓ¦M}}}/\¸¯×ëû8jŽjº:ÐÂh&‹5ñÕ[ðá­f«ÉlR«Õàg4P¹,‹<TnüÑhÔ­ß[-f‹ ôóôÒRñ.±Òñ‘÷”¤J¯¢Ù#žõ—Õg–A×7]at1G˜×¼¶¦c»Ž±,ÖÎrÊGÅAá9^†¢í2ƒ>¨3Ä^€°ØHñ(>Šlf³Yý±ú¿æ ö_+oâ]ü tÓ†#Ao–ž’JÕRÓ {Y«Ùl6y™¤f©Ãgf‹†xVXQ&Þ\¿:1<y«_™‘ù¡äA¿Æ*mB6ôz=¨ìZ¼íŽŸa]³ÊëD× 6A %o?- k|qO⣼K�Z,½ÐF,€Óžn3 ¼~Æ;1WÐç ñ1 ØoØf¼¦· ÊG²Â ’¼ÞÀ‹À´|ôdº9^_¤+0ÁAߢ³C?Y,¥RIª?-œZ­6¼å +û!(dvž‘fF£€¿ 3 ^ˆˆ b¢x?ö3¦²ï!£ó yˆV€¥OÀ%‚L*S(¾¾¾]ºt1IIIà4<z°ðöjr˜±Âz ¥Èf‹EW VYê[ c Œ1!_pêá$‰¹�¡–>Û)áÅÂ�Í]ÍÊJ77·:uê(ŠÔÔÔ´´4±XÜu;ÌwgÝí,§¬Åø=…ÍJ;;›7‹Óî$’D[Ä&]ç‡$¢:¹Žð_<ȇ6¶‚ Ø8@ /žðFZ­VÉ^‰òÒ2ÀbUZE‘t¥T‘¡ËÅ|”¬…ðFðÞh Bá+¢Îµ€FãÇ;„mìKôb@ïèÌ!À±Dœ ¼ê¿DwàyÆLÂÑ %y¿:ïd¦giÃ8 öÃë4p!€hBpA .,œ6±mø›>Џ5^Â%ŠISñˆ/¿È»!ù8‹Åâàà@l†v€óaðrC_? ;DGGÇû÷ïÃpG£c\½Þ½ßÀ6.n°U°^YÁêãp§cÅ‹üÒ€{ÁˆÇ‡Jò&Mriz½þÔ©SwïÞ½~ýºV«…Ÿ ;ûŸB[É Š  žû‚zÐÜÚXؤ·¤¢É""MR™”W”19<ž<¶pR?4zøy(++[µjåëë{æÌ™cÇŽI$’`ü%ûÒÎrÊGËá=Ïmø0K~-ùÀ'yð1Qðü7JM&£ÓÈ¿†;ÈÔØ…=mÜEd¸€,ÌŸ"„ÆJ$Úô’_%dF7b¹>Xâ¬Ô‘_„—dÁc8ü< ° ¨þÁˆBÙÐ 5¯C Nb o·ù¯ªP§±‰¦0S<Å[ºA¼(nw×ólžŒo¨„ Èõ$JCë¢`qLÏ¿y=†ÌPx #X)>Lºé†ޏs=ÔDŠw· +Àði‘€Ûø"¯–ñE›–g^ÃÖétdm¦© ÉO{à­ÙļÉÔŒ x~EØâH¶2z„fBöi¶ùˆ8zè ŸÙXù¨h>Ƈ~ROTë¾Ò±–œœ|ëÖ-Úi"‘HûµV9F äyÒ¡V«yÁ…P"äùåW&4ÈHâ ÏùÀ]™vÿG ³Æœœœ+W®´lÙ²k×®ÙÙÙ/zm…žå@ú€œ#/ÉJо‘mà ûXÀó ù‚÷vð¡Sdï‚tO%Ë®l¢Mè´)߯…pOô¢à7ºÙ §Ô&:�þ²,á§Ù†ññôNFÃÛy~ÆS:žiÙT¯"ê@¬Ø¥ûá¿–hNh%žMß…Bió9¨†ô+?L˜ûp3¬ ôE´~Ƀ#…S T˜âS5 pXWÀN@»áGäõcú›X ^¯G0vaË«ÈdXãc.lÔJÈ(ôiðØ{yyE¥RQ #\ô„*iW´oÁDi~òóói¶‰Å*•JF‘ˆ·ªAÛÀÌóÛj.Ñ\:$aD … OåcOÀȆ{ø®NØdýƒ*OÒ!/Ì=2rÜ[ÍVc+£ä®Ä|ß,“É,n¡žÀäLr]"ˆÿaÖãƒ×!PÒùPô…“ ¶M‘èˆ*z(ø  &]|Ä×ÄFo£øŽøüùóyyy7¦ÉLfÉõX=;Ë)–C» ÞEÈ€ 9upp -Ácün¦ÃF¿ò¦ l}ºŸ6RsL€`'´câ­C°fð9pWà"Ä;6Y®à(¼ÑKˆ°B6+ÏlÀMmr!¿ƒC@žEàµmŠOzà“¢ˆò†ØCxó/?ÒO|Ž” ÿãóH`ˆC4< Ú|Ⲉõ‚[ðÚ!è#Ý ÝH¡PðQÄ0xû”i¸^±Â“f˜Èlêx«üŽp9ðòÜÌCŸåJ’uÅ›pùÝ Ñ|–.‰A$ã#¬œ˜T+¨¹¤mÐã ²?¡ãÉË=¼óèa­ÁV a–•¼@²N.¯ßc}yEY"‘8„;è¦ê„‡‚([d™™33W6ËË¥&©Id‚A’>Eá£.¡¯`Kóv`ÚEdæEàþ@|ŸnL3ɧ<+) 3 ²á2N—˜˜xûöm“Éôé§Ÿ.` ìáå^íÁ ²¯h#=+!Ž!Ö�¯…ÿƒw)Ãà ƒ8Ÿ'–€½ÈG=ò'„7Ý€xÙp)ärÛ©!Ð1®Ü�c>ÑŒîÁžæÂg û;!ŽÛ×x¨0f`cÈVÂ(¯�’„Ä ›TIž-ý7nµ0¿c$阭ˆL,Ì2tàAe€�TXø]0ÿHl"üyþÍÛv ñ±Ëàš¼[‚ßt(;á�Ɔ7Ðñ¼œW³xÎ Sem"Ëa¦}Îç»äää`íøèp›UÃVăË& ‡¨*¦”4Kœ22™òAØ |` ¯¡òñÄ6Á„ˆ&àɽ8Sì4ÝÉüªÙÒØb±X¬­òr‘H$Rˆ ©ðŽ4>~Á&kG ñ„¿ƒæà+Còüwm\˜b±ØúÀ*Ši£´ÊH%Kbf³Y ‹¨1ƒÍ°ÖÊå`+É׺àÓ°Åb1É}ÏŹe\“cD¯‚´AêgÿÌ?ç¥lVØ8Ÿæù ü“|¼2þF4'oL€E›O9uS©T¼îžáäՆР)((àSÏè°À€&Âéóoè¡!‘P.—ƒ €p€ªòÉÿP;@³1Á»%Se“øÉ£éTO^±ãË¢ðHÖy-b5h¥Mz¼ƒ_ yúÚÃ)H¿Â«‚Å«8Ál1[d™RfµZ™À˜õJ6vÏ_mì6nm°y~°dé…ZS4‘tœ¯¤À·ýæc"ø @ú(ňC釱‹¯œDZ¸MX^BjKb“— •²GŽÂ"—‡ùÉ‹—Êÿ–“îb[°™ùÁÒ)ç‰[áMaPªø &hüPy?(o»æ-u0W �Ç£SŸg‘­‘YkXu“t–±H,Û*tPßÊ}í,§Ü kH§€¡‰D P7îÈöB‚-Ÿ‚ÎÇV²Âb°ì+‚þ «7„/Ú|ôN„£f ¿5qƒÊEä’ÄO˜ø !˜÷HÃd‚þAô‹¨Yó;‹l Fã‚RÏ›¿ Éårrkóš„J¸Qc ŒŠ|ˆÏ¶‰æâkšñƒ”ðV/z£æ•-$âÀÃ%ða²©�f㫃·”6´‚çÃêÀÿ(7“gT|ZH?M/‚ð©—¼ÁP$™˜oÁ2ÉR`-1‘:RÍn1ëe+?WšU2&“(ëõ°¿¡|ÂU°L6ex:K“^¯GJ5ïfãS—x‹oÚ¶ç…0Þ +ì„dÌ„€B+ •JeµZµZ-ö°«¹½‡á#*ù F¨¿ÇK| ©^¯—J¥„ \zØl0{ƒ!–ò¸ù|X>Ü™;x“&o gÿ,†Âës2…óD,—©>RaàuûÔ1‘å”§¢Ã›°°ü< CI:$|ú=¬7|q02× çƒN ïQ„½u¨p°yUAtH}°q«ðEð>Ñ’w-òÆÐ,Re¡Ë¸ê–¤Õñy¦<3Ãð’É×gäí pY#êW&pŠøø%˜DÀ ø¸�ÞDn9Æ—ùâ£àøø%Lˆ:»‚ ·ñ^nѲ¹ÍŽâé36Þ£ùd,^i€g‚bF`8zdñoaz "‹ÈùmçG~‘9&s[³d—Dö·¬h‡ÍÎAý^ GÁ>ï3\´~MlŒØü|63Â…‘0ħˆA€l]á|ØŸµ€�®,žIó5 ùñFÈ” 5Ž·¼¾d­R©D+ã*ÙÀŒ ]ØLÑó/2¿ÓøøR0JóelÂO0±EkYÙ#ÖÊ YØd­óá’6¾Þ­÷ÈÒ¢©gŒI2%Žs!gÁ$‚œa±Ûô@ÛˆÌP\@€p>!$ò®B°=è.|¢ˆmeÒHÀü œ«Ð]ø bù ÎóG·Ù €à‚¡’Ø'ü4*•J£Ñð1©6r.#A³äÉÁð¨"h™žXJž\ò™+¼h KOhøBdÅšOm8=&–BaEä}õ¼Š�¦ËG6ò!¼[›'.–7,Š8…d„’ˆcê…jŸÎÔÝÄþfðVòëEeÐ,y2GH‚çñE^pÑ Cb™ðÁ$H;Ô™ûDÐ Ÿk|ÌMxD>œÏSÁˆ U£~9¢9è={¡ÌVúÃ7ɸ>Ø„ì ÇóõgÙ?kñ< f1¾&)ø=â $ñÅÜÈ.Ç‹&°³ñ,ŠßÒ/.ˆ_t‡Ï}£e3”AÍ XxqñQޤÌRð[1بŠT9.w”ï•çÌÑ Ò1É£[ž»ð9ùˆ±iˆiÁ ŸÊ SØx…÷ CÓG7¬|\,/®›AIlÄy#ôˆO´ñ ‰Lgtµ@¼øº¶8HDƒø·ñ%)ù\<‹ÅâèèØ¨Q#OOOÞ4ˆ \ò¼íŽ&4ŸŒÛïÂ!£‡B¡ $¾v_üŸ÷Ù•d ž �¿^¨jC÷ÂzÛPùH'TÜ¡I#?ù~¬b™XqRAƒBÕ"ëA« t-u|Q"Þ{U(Vã uó•àºàë{’ƒ‡·nÁÖJ&;’¥”J¥MÎŒŠ(¬‡PcšU•J…¥„‡ 1>|Ð&êh ú ýÍ{’d2™B¡�“€ÒLÆCÜ­‚JØ|\ ‚ƒp0$’"è><e&` Æ~†Í “76ò`Ìeê›ÉW·c#´é)½^˜X»–Sž¾Z0^æõ¼Ñb¶©v£Vý‘Zš%5™L‘…1æÜÃY3[#tD‡E¼óD û‰¼r7ÈVŒ«D�Âg£éó °b!2Mø s˜ž@¤WÆW!J‚f4 ×j…WAëyûgÌjnn.Ÿ-DãdÊåòúõëëõú‡ò¡S|Álˆ„6Þ)Æ0† BÒ=¦‚HÝFO|P ƒR©©TŠ–Û6Ùò|¬-ãÊäð}w¨�+4¿¢VY‘HDUé(R?º1ñ•Сá,±0‹1ËH«ïîîN]0¬yV‘XÄo=±Fø1W>žŠ|¡ó…9¨BºÈ ýƒ¯˜ÀÎA{ Jü„0„¥$Ö³X>B””ü%PPXa‡*›,4ÞJÌ׌�'îBÆ7t¬àãQßê;½„"¿ùÏ%Ø„3ðÞÆRbÓ¥‰q¥+ˆÓÀ2oâÁ—!§£A R`Ä*]'Qœ¯~dg9å©åa‡ZƒP 'ñ+ú|`—@6·5‹/ŠÅz1ïö4›Íâ“bKk‹"FÁŒ¶•PØ ’oÚ¦—ð%ŸÑBÁ ER„ÿ³v 7Þ¦v2OîïÄŸ  Ý›²¦q6l¢�P�¢ŒòГÀ5ùŒW›ìTDÐ ><xð F£Aè_û‡q…ºaÅwùÖU|V?ŸþÉû“i¼0H"Y…Báààð¨‚C!„HΓW>ʃ4çS>Žû Áú|PØjlöÒ£ÏY‘ø¿5"! ¾$ûg¡¨Yx™ìøj~E§À–ÀTè\𥵠`3o¼ŠicìB,¿ ùŒ¾8)ŠüóŠ©MÅ&>æ›/_FQ‘PÑè)èë6-EPO; ‰VüDÁ FL—ßZ¨ÄŠÌ'´åkL`ÒhGñ/±)$ȇ°â)˜Íù)Å*ð‰Ò /쟕³í†µò@!$‰¢:IEÃá­V«å ‹è”Èœc¶X,žžž;v¬V­š òrs³H%âM·0ûùùH|ä–óÆž˜Bká-'EÙøÊŒ¼OÒ.Ê×Ú!¯/eÑó WWW¾Ñêc#˜ƒO@Rƒ˜Ï;‡ÀkA2x…L§Ó¡ Aþà±y_&ŽsƒYq¨6QΈ@¡nwwwÊæ}¹X&>µ–§¡ð4ð¦žRóÄÅh4’õ“†9D:¨#"‘H/L‚ñ#Ù„322(JÔVdÕ[åIrdÔ‚-ñÕÇùÚn<Ç²É ³épÁ‘xƒŒH`ù4HN¼ÜÆk¨ ñ|¿^5çÕJ~nù ì[h30öþ{ooiYyßÏ´÷³‡3Ô�U@Q€B ŒV¢ FD1Nm·H+obÖ˜˜Ž¢‰o›Ÿ±µ£1v’Žiûš8ÄmQ‰CÔÖv€ˆ™DôePFA (Šª¢ªNSgØÓ³÷3ô‡µÏÿ\çÞôWð;烿²8µ÷3Ü÷½ÖºÖµ®‹2Ž'oø¹ÆBe9{¢VÊ ÓFšêbxBê•@QZD8ú¯,iEÞ<¥]/ÿðèó°Å™¦©ªM?èîcï»×ë™'»‘d ­- a@pF)£(jµZ\pÁe—]vÎ9çH µV}ë7NêNÚç@wV1úÅèËË,UñB§;é?©† $ܪª&!*e£²dÕ+A›+´|xnÀzjƒ¦¤jý%Œï䢘•[¯êa¯�ü]Ÿ9ãñnÕõ«7ºÿ¹#øê×`¨ŽÙ„+õ€Ðųòèa<Õ vìØqÖYgMMMÁ¶÷f¡”ÚǧEQ”§yÙ.‹vQ†>zS;^«úU¹» ¦Çl¨¢(ªvåç\Ï ª£Ô‹O˜èØ’PjL2 ‚¥2¬ lô oâ:¡µˆŽ¯j– yÏÖÊ k½èãBf‰0F°±Ý‡EG©Tˆ¨Í°bÌYE�³Z&ÚÃQ!»É‰+6²f3ÊDE˜Ñ–(`šíP~ßnJÇHmå*¨R ŠˆPê©d5³†›ÀÚ‡åær,»;‘CF9xLyÀ¹]®ŒKÓ—=pàÀC=”$Ivzætù «v5Õö u†QÓÀ$—×c—c‚Nf»Ý61]xG*ÌãSÇ5PRàQmcq®ªjaaÁóTÖœŽ?¨3®m'»Z; ¬ÖN4K9a�¸{Â^Áçù!’§ÛdYfáÍ¢ÂÔÔÔüü|¯×ƒØG˾Õ�{Ñli ÒÇ·8§ÃóJF÷Ò:ívÙóóóN§ÛíZ ™¡f3öØ‘Ï)O+ËÇ—ùks·Õ¹À…_ ƒáõ¡u†ÆŠ“hfÿ%Ë^‘…_pïõ½øö¸ù§M­É@¼ëp®¢pZú¼Løa|)µfW‘ ˜Óà¤l]ÍO+ÅÎGU7°×çÄ Ý­j2Y¦j¦‚ÊeX3å…©QheSŸñ4ˆpzãÄ$Ö W«fN@vèÛ+¦Ða M¡fÚf4™XÉldŸSy=®¼Ó&-OE7{9ŒªéPõ‡µëôŸzåÆŸŠ_¤_Ióãù±cÇæææÆ'ÝkŠäs‰ëº0U°Ë²lüûX‚!H,Þ¬‰[µ›…àÄð—jÝ)ª¾ÚýÒ¥Pƒ¯ì¥Y~Zaý†züƒµ^‹bql0ð:T°ô´ÂSDu LKâ,Ì�;è`Â@µ¿G‚Þ‰˜ )-ÉI)'•{G°Õûé§žzæ™gfYfhìÖû581kÐ(¢Þc±”BeëH¢M Ó¾ÅJ+HŒž_G¸:­]1r-×øOd)©ª*»,+_T†§†á߇ªÌ]{w-jEÃßVU¸ ù›Í°bò¦è¢'îâ1Å‘` Ê»0åy»õ²FÜOX±,Vš"«W p4– /« �¯F)'ôQXu:QëÄ€‘ €¹7•“÷&tJWeútn‰²‰T6U­pºýN£ÑвCIª:ÇæÖû´ªÐŸ©Ê¡:Ý¥À£''±r6¦ÊÕd™E�ÑSÁŠ¢hüEcð_ÁmAü¾¸ªªøÔ¸÷Þ^ô£(º;Ò¾=@*evN‘ é%y3‰ô�(w(ÆÙ“yž›Œ ÅФµ—‘ÆÅûÏçý×÷“ï%ñÁØ97xÁ x]1õ†©h¸¦ªÀf6êªn9Ï|ZiÍI:^ªD8b@Øì™àÀ¨n^–÷YŸÐòˆ]n&Ô¤Àvé‰'F£Ñòò2¿©‚ÙöcÙ½:'­M_­Vœ©ÞP¢®t ”†kð/‚$]yj•T–åèìQ5U¥oO+W¹š+˲ö¹šÛê:íLyãø÷WÊÆ;k"¤Q¨i H¦Öv fr˜ÚÄ>®3Ú „{Æ2à3É™àLªt:‡/É8«òÈuvJY8Ci¶«ô Șj‡Coa.¸  Âêd’§BM^|õL1Ð.QF(=|'2Áà„˜8ð}Ã`Úo6›†îª¯39q(&¾*`ûØøy,h¬)‰Èþ`<N¥·S̪Èn’$î»®~ ž?-üëÀn47Jß’ÆKqu¢*OfòŽ5ªºNœ¸póè˜l|éa²¡ßï3ÉHδV«•§•Ù«³Ö·¢£‘ë»áp˜_“'[“•¿Y™}Õ¬uª˜Rj:L3¯§[×£Òéy ®Cˆ4œ# •~v¾v ^ŒAÝ]¥Û`|ñx‹¢èt:+++ª$D6JJÈÃgŠBÛéèõjub¿Æ ¯“)]UµqΙ˜¿M(/X”ç¹pmx¥×ë•õrðÛƒÆI-I’dzzzaaa4•óeü‰¸ÿú~í5LÍIPFמ"9¬Fà'ÚþÔú*`áÄ¢Ôé¹½zøJèò&ÆÐ›ÊÝ"YIª<Œã3¡nR—S£xr‚ª¡ÀžÅ€Ü|å5_¾u šlFµ·œåÖ¬qÈ–§L¸6h”X…3/›0í:Jௌ!Ú]ÞèdzR{tÞ>Ý 9ÐËÑ:–ªýÐ~°­µmÛ¶éé鬬¬¸Õ©{wÐ…ÂôK©*¼~¸’>•¢ª²ÿ—©Ø°7ëþˆ3ÌœÅVKéˆ>Õ:û¶xJíÂBŒ‘â Ý _Ìó=yu[€a¤À”¸ æ®U3[á?ÈÀ]X!M…+•ÌÕÀ]Ö9yÕš”å¶nänu´þ’úèx<@jA7á_¹FV\mQ¨ð6€'à§øn½=fKÊvUç7ó})¢¢œ-ƒ… ªGüãŸøÄ'~ç;ßyðÁÃ0 WÂrK©Y­§’ÇÔ‹6&i·¨¬‹—{áÍc/Ëþ¡ºµ2 `S»÷jS­jßžŠÙ†N±ÀôV’½¾bË´tŒÝ¡…‡¾}5$éV«`àA‹“´IbPË]K@1jÓA·‹Q[Ȩ÷i#lI'X¹ën·kÓZÔ7ÚéäÃIVêö&Iz£cæz¦“ À°ì`R®¬¬,..ªÍ-„z‹ON|h”d¥²Q*f, : > 8¬±MT"EÕýTîB¤[uœÓS©(Šþïõë^4£åÐü@³seÇÚ¿ŠŠ( U±f=AÔ=|߉hŠ“¹K=MT_Ç£äª.µŽ€zÅ=©:¢m'p¾ð%.•J#<hà§0UÙoî,¤2<@舚4P"PÚú‡cùÔ8ªÊÊÇŽÛ·oŸ%:I’Dñ§i }þP3È6”¯”n'ŠýŒj.o­!Õ+/–7Ÿ`H y² ”ÜvpèázRc¼GaÑŃ,!ä.]<&xhš:Š«ýT³×aqnfff÷îÝöºY*žó·²tìÌ£�X\·µdÄKe”x+h£‘êG9ëVÁÀ à„ažíM`mƒÔ9‘3‘íÊ{z½N§£‡28õÌð˜I'FÒl_¶ÓŸ æz'–U±ñ¬ÃÙÀ@ÇH(«,[�� �IDAT© ܲßh4X¸£bäÖë<:™Èó”ÿùO}ŽÎ0¸œýõ¼Ñ9×­ŠsɪÒ7LÎW+xåÖ{ð ¸ vÎ¥iª ­Htø'ÝwÈ�à—óBU˜KPêÃñAdâ\xQí“$IÂQXûR-¿<¯çæææçç­±_¶Êü…yãã ŽcÞŠÑ|…~,Í9·^V›%úîh 2¯¦.× œ  "§¸ÍzÞíö¨í¼6h‹e£eŸ‡~O ­z:lj—‡áHTôN!/xßb+!MÓf³¹mÛ¶#GŽÌÏσ©ªè*Xˆêb­Ì@­ž=>§“Idý{Ïj‹ÿÛh4ìp°^Ž×ES/­)ôVçâGý$åc ¥KVgôÔ(Ér%;4U�e@<ÔÎÖ­àr"(`h Ú\šÑ#g‰r”¶ô©É²,3|ÃÚŠ€D’Õ•r+®hŽó,Ë8CËVi4'P>­Z¼Î–N BA¦P§þ[˜Ð&]Ýô—5œhäÖ›[cgb½ ÷H¦×N|6y¤JFò|IlÙ¨¶áU¤Â’Õ"Ú…f8CïEµÚt<ÓãŒÝÂÅwÆÕªpGÕVË”™p´u4Ú:ªî¨ ¸ÓF±‡µ¢Ä¥8¤½´¼&»Ð< #¤0)29°b%>·ÀÉkKNW,¹6­AejÙjK]I   šÙ(/Ñ‚„NÃXD7Á7ƒ©¹#ª¦ÓìïQʰkصk×¥—^zÚi§AKkµZd-‹‹‹‡6p˜-ïÖ+9éƒRé e@èhöpõÇÉT©¾]{:³Ü¢½*œ£´O@àÍ*ç§‚A@Bmç/h;Œ#:ìµí¢¼ð¤Èùp0qÀwÃa5íu¢n« »¦*œ¶ÃÈžŒÍTnKÛZõzݦjoª-ÿË[þã+„éý÷Þôs§]èh(vT9¦f¬ J:‰¹("øíP;àªÒR3 ÚÜaPq¼4M9<…7(d”­ÚP_N{§–§óâ´üõb¿§Ž ÉÛШêûâµÜTðò^ôý(8%è~¨›|&©ª ú/ìW'WÉåIÈÝk'L!P¸&í,S&£ê¢y¸ûØb³ Û‰cI†z5YçÏ‹Oº˜ÕÃB @ÄŽ4c,SQîLUUöxÙ€Zb:Ñr¶· öÀ¦£GHqÿý÷_}õÕóóóÐL·àœëÄKž3ÊX‡± éCã„L¡‰H#²~ú_-³t«N"ÊoÔ 冨[£¬·‹¨Ü 9rÔ?C‘e{͆�hªbxµ3°µm*N"rC5A`ÐL»†ç¢)9Yfa‚ÀÔ:ŒR'ƒl$à0°©á¬‹EQ¹XÆ÷ÆÝ7u“Ï%á°,Ë᳆£½£Æ“ôqñÄ›Ñ]>qâ„79 z›gAMj¦¾Îìms#ØÝÃØˆ¼ö^ðKVl\˜M}E1,QÓ-ÈxNÜN¸«y£²�¨xi_„ラ#Ž~H+ŒX*¦Ä˵Vÿj=ür˜½> žT®JÿgÞZ¼QÓ3ÆBÕ\C_œÎó“z“TÙ“×V<¶œ¤aæççù/çeYƒä3‰R'h\×ëu‹=Þ˜ÊgLâ¢À×ALOOOMM-..®¬¬¨8·ÍK°´KÑ€»¨*YÚÇ1ÍÓ&Õ#gZ^^^^^Öñ2/ÝÑBP),¶$ÇócµTÉó:ÅÅ–W×(ž• nQª ª¾no féf•³ññæ=ÄØ¾&³Ú`€49)ËAÃF™f:‡Hk†>©.zš4<m3H‚“€u[<ŒÀSïÕÃO†£§ŽºoèºÎ9—ÜšDwGµkj¥+™÷ðqt²ÔÏ€öÔ5mY«Õ 0±,^µ MÊãë(ŒUlô�ì±4ápØï÷€(aŸÉV¤kJ]è‘åTËèϰÓv³Vœ‘…¼ý ±tDsUÅV–IR> ¢‘åyž×þªDæB§‰¹ç¥­f—DGŽ3-ð”³ÈíÙÎR6Ù=VAÕûT/øqÝÅa\Tõ?Óo|¤‘|7ñ$Ò) Y{ö‚8©«ÒÊÈO’dïÞ½{÷î½öÚko½õVô<¾¾’k¾Sª=+Â<Nô20)Ò¹.ÆU+hÏCͮ޻: ‘Æ�pë¢X oF>·�Þ ©'|?ed蛎ÍA+å Ø¼ù)èG­â:†B?œt•ÄSß:Œ,,뵉ǻ‡Žb¿`›¾Ç¥n'=ƒTéuaXXNt×¹¼§´ói]ŸÑhä»äpR¿©^Õª¼È£•(êEà~óXUx¤ßïxLžNÇ<ãBÚ!WoB“W�sŒ‡Æ'@ÛÕ“ZÍ P¶_ƒ¨¦ìA%¡áÎ }€ãÞvyÜG<Ì`-ªô,SŒÎˆÔŒb¸õŽ–Ê¿ð 5�ä¼›œ|ò>Ó.GaÁR»Ç”P«,TóX¬cÁÕÚ!dHËW/·þSËu]>—APkÕ’Húo采õ‡êô#µ¹b»ÉœA¨ìIÚ˜'óF2˲<zôè~ô#£†êtšf÷Ä3nM->u*¥…›õŒ>mõÈl#Vš½ée(UÕÂØ¤`‡ xÞ( ¯¦‘wÒ4µ‚Ì0À -GªR7qæ“ÔWžSÂŽ¶ƒÆ¤MÁ›ŸŠ¹øHjƒ‹êÿÐPrjåÄ®ɋ½o%hy–¶I±gªŸ,ËÒ4e¶œ“T‡tyñEvhVU\åÂ"ts‘³ù>±°md9;¡8õ¬»ËºG"ÇnmsÊXnh¨ˆ]¼™ì.´©«?N,Y³,³‘ðÏ ®ù]Ú6ÖrÓÓÆ×À`§ŒÍcÚ“±V$ÎM=2´Õ ´jÑÈ2<VÆ<êÙj·ÌíkôÒþ™“a{½�Kþ 9퓤{e–gÖ@»›btÞ(8„‡C°²rP‡‚èÞ(??î p_n6›0î ;·Tw¥zA4Ïó}ûöíß¿ßý£CŒQ{P:‹ý~ŸŠâ€úÙ$]­ã\oÌÐ u’� E‰>)5„Z»Z:Å(Ý)è…L†B,"›ôܾII Êþg�ÜK†6UjÃfÈÙH®½þLÛâ¾tèÎuEQÿD7D,Mª  0¶ç?ÁZ¦Q³–—Êê`„ÂA ìØ¹¯³¥È±P‰+Õ*- — ˆ.‚÷Ð4/Ò¦7·o‰§:I}9¿ìË4xÁZeª6Í4kí¢0õÎÑ!MÅèÆöh¿ž¹“]UUµ¯ÕÊ;×ÄrÀÖ˜…ùQbmmZÔ^.¥¡Å0«qbÃÅ|Ÿ'J)ã~˜nyêú¼bEÕ / éSb®Ë‰ð>Eè¨ïô!ú¯ë7>Ú°=233ÇññãÇó<Oÿ*]ºn)þBÌøHv²óõÂà•èŒ5jÕÕ?‹yövTÙÈò(‚ öÞšò\@¡uI஦´@…­xžxÙ)O‡àg;ÈhÈ(x6*<á1VxÔãÑ«Õuk/—^£[µ·Q!QÌU'kk cÔýêME÷ð¢~,¤ ÿ³p©¦‹'Ý«»n‡ o ƒå…eïïzÕ–ŠuIÙî úÑòŽÚ˜^÷UI®IJxuâ辆†±@鈪 2ª'˜w©å†4h¸J褡ÍÕoæV-E(ØÊ`†®÷¨.mÚ‡çðRGŸRÞçÝðyÃîÕÝZQ‹ïˆw7Š+ŠÞ'z¤µòœÔè–8[5ÐDUL§U*˜œ�øaC*;píð¥zÖ±>ž¼Ê2Ôeá' e¯VÖÃÈó5°¥¢Ôg¾·Ùl^xá…W\qÅîÝ» ²cIÀÅgÙ@á|C‚¢—ÊÖºø‹F‘•¡aÞ=¼sÝU·Tîn骥þ«ûyžw:°JÞI%)=$¥çèæU‡!O§ò!EÆÔÔ”>jÀ·^T£ŽòH À4WV¬¶™ÙËžj­ž!$»ä žþ‘ûg’6«œ (t<Òɬ‘åoÎë¿SOV’ ‚<(þ¥§ÃÁ'ÉË}y:³ÂT¶ÓÚW“4DˆÙý\Œ§-¯Ý”t4Ì–>x7à¯wÊÐüÐb›ªÛí:ñëõ4•” CZS´ë«‰¶ê‚ XÇa„À»vÑIá5HP•ºõ^¿N”’í˜+Ï/Ëç–75Â…0>9.Š"¾7N]Úýt·õZv0цÅzÒæl<6*NÕ êÂw"dÚ!«)°C:µJéY‘hÄñÇ÷ÒÞGàÕóã"[ª×ë6`¯¹¶ÂkJó:êpgè,†a,åt¹¨(Š£GšG@žçn‹ C‹Ž¶í.ðoVå:ÜAãÒ¢£šÇ¨Gʧ*Ýÿ/ýðº0º5ŠNŒ»•á-áè%£ìeYü¹ØàÙñRÙQä/ÊG¯9çâ{ââÝEµP¹‘ÓuHùeñ̰e ½ö9j9hÙ€ P©O ÌfÈ~Jb´Oö$¬Ð÷ã!³)Úo i½…:TìÀ³ÅHg3äl<cÍ‹4úbÂg†ÁAu¨ŠÑÌ–™ápØétò‡óྠߛ7®;jI[X^í¢‡)Y­ê¯(=_µÜ™<°®ÿégUý¢× ò«ädEÀµlÏ·Z-眵%Àúmx~'ôiìò,vš½Vž·"éjKŒ¾™ÒUµ^za:è'�”¯¥¨aPž_†÷„ÅIEùôrtùª¿Ë7ãòìÒý¬KîZSФD§MµwåÄóM=œ¸¹hY¦RÿÊLa ÅXíMqK“ ¥ðÚß[÷‹\í—h8i¿DC#päË“ÕX¨ TUÕxGcåÛ+ñÅñ`0¸ùæ›o¹åÃÍVþl%}Kª‚:ð‹Ï òtºËPÄèõzÌ`‘Ĩ³'ZAιâÔ¢ ªè¡(:™þižç½#½èh´gMGI'±Cvô¬Ñèu£øñÔÅSeYFO‰:ïíDÿ¥W¥E¯ÐDY.'R§Êõ:æ’è{Ù4·ŽÍ-;‘uP*½'“ȪoâDv»­ û{u*"½£Ñˆ ¡7¢n,›½œ:j2A&bû¶ûönëÙ­Z«¶gÏž /¼ðàÁƒ7ÜpÃÑ£G“?Kï4~µ|¡m›-[¶Ðëõl+¾”¦éÌÌŒépà踖žJiÜPdV׫6¢tâÝ«ç45V÷_-¤,•Ó>§:jÖ«Cª{¯"ŒÚGE2ij Dþ‚öLJÇY DiÍDe�…´Šªþåýô-iþoò°§^9e’½& n ú¿ÚoüAC›pö¨•ç8ê膞)P´I<{fµðÒ^½7Ê£ïÂnÞ;Ñ æ1#Y£øDƒ¶4cP%$2OFoŒ¶}"ÉÞž%·$Á5AY–ÁÁðŠ¡Û碑ÊJÎÎÎnݺµ,Ë……[<öBíQ‘xÒišv»Ý1zù–¼l”ιڧknÿ:1½á…CwÐE÷EAìܹsÏž=÷ßÿ=÷ÜSûv­¼´ŒÏ‰‹›Ç ŒÁ»ÓOEáBE‘»Ãµ^Ñê~´›_“Ǭ˜kŸ=s !Ê{öx•æmCØkvì_Ö­G¢±ÚNã™§ZëÍé ¸zYy©Œm"DäÔpKiA›!gãIÒ^ÁCÆÓi§v饗>ïyÏ{ðÁ—–––––úQ?ŒBC8Ûíöi§–$É‘#G;aíNMMíܹs÷îÝý~ÿàÁƒæÝAËV¿Â \ƒj(䢻“uƒ÷ZV¨_„tª€tÞ3P\Ewv‘"*3êÖ Þè5hcŸ pª÷$ŒZ ê#*‹Ò9Wþ\ŠkŸ©Õµ0 »Ýnò7IøÌ°xqA±b66AH›ùh)j3†¡…ƒ&  •’%h³SÛÿUèLg'íÓ4­×ë+++ª&iÇ¥Âý-áøZEµ¦ª7Ù]sÆ™h‚ò ÆnŸjdgßö½ïœsG\ü¿âÚµúJ½ŠªF£Ñh4¦¦¦¶nÝj+|nnŽ&J­V«Ûív:àJ‰g?¼|8|É0ýdZô‹ †¿7 ª ýŸÛcöõÈÄÌÌÌé§Ÿ~äÈ¢õp8LÂ$‚ìõYãà øÐ–HAP_}ø¦að†urgT 8±*IqÀÈ ‡†ÒÉlŽeC}I‡Ï3ášÙøŒi°·ëWYwêiôu €w7IQy´×…“Š®,t~7ç²é¬Óéœ8qbqq±ÓéŒõÃOrnn-m´s*˲ãÇOOO«ê³Ncõûý‡zh0;vÌ>‡L„´ß\;³Ð,aðM IMr‰2Ž˜‡@ñWk ãæ,6™‘Í÷qsû6N¨"r Ê¢6HÃ@C6®%?ñIÇJ`XËm°C\ìî�©œså©e~VžüARÅÔÔ”e EY³ÁèßâïÅñWc&Ì-ð`—‡£Lcp”«Y�¸"-*±¬£ˆÊœæ§ij¥0bšv¤ÙåñÊàÛwyòŽdÐvÒÀó(ȤÉLs›A”E™~;Í¿“GŸŠ¼p#WïÕëõzkK«^¯·Ûm>mfffvvÖkl(ÇÔ"jµÚìììâââââ"u˜RõÊ—Åö¢ye38„EX–eò½$</\üãÅ©·N·Æ *f‹<Êã"þñlû(‚¢Q”ý2ÎÇ@ñðÜaòþ¤×›Íæž={†Ãám·ÝV–et{T<iÍ„Û6©!{ªåŠÒ¤ºàš!ž †«Ï©Ô:“ êe×<oÈl1ãß8œj`šçy·ÛmµZöo-`«£gÑÆKTuW{ j™ºr6þGµÿÈAœsékÓÞßö.[øâ¿xË-·?~üÁÌó¼ÿ~za:r#¯V=vìX§ÓARAùápxøðaÐ04¡¶€5`‹Ø¹z! hKÆfP£»C¾¦3Þhy„T[^!`XמÌ^p\pD2Õ!5¨©4T´í~¡lkÕkDgâãb§YЧ¼a¯›”AãŠFþ«yR$qŸ{î¹gœqÆ?üÃ?Y9Ò½²[ûËZU_“—· ¨y®….¥lØÅÓFæ ×wJ<&âj‘JŠJ5i_Ü`¦g~¡œ+H  fåDAÀ.ÑWÌu‚ó@ØÃïr­3ù0ã$I¦·MOMM©©åàf^iOÃâ à4MÏ<óÌãÇÏÍÍ õ¨šUqfÞºc.Š£´ž‡ÃáâÐte·œ6ˆöGιúWê½÷ôÊ'—î®Óét»Ý1™íW†ÉI|O\E«Mu·FWá}Ùó7œ‡4’Nºnn½Ý,WƒuÀÙRµÒ°ò©#k D&=ÆÚôT¨Ñf5RÝSõijWCÒ3zá(Nã(Œ‚훽œîå(É]õê‹¢p]ÝußÖ=ðù'~p¢ßïiX<§ˆ®^Ó\ÒÆÝh4ZZZr¢¯:ü ^nîù'2ÿÏå©.Ív;Ë8ƒÚ"$ÐÑhQ¨šUHÇ«oÔ®˜~‰}š÷hÐ1wÍ7‚ÚS=xc"Èy?8@ÕM`Œ™y‰<5¦14ˆ¢¨Šâç‹Á šÓ<räÈ`0XüåÅÞî^ôñ¨<© ]¨ÛÊ^V“Àñê/IÍgÕƒUŒêô¤œX 1¥\ t"ÔMYçsíüòú|Ê:ÓN‰÷¥ªj¡È¯‰ÃZZ@a63===;;Ûét–——q¯i4Ö­l6›(ù¾üð¨9*«rËÿÞÒè5¦§§£(:~ü¸5xÆ�à–bô´Q냭 vïÞýÔ§>õСC?üáW\‰n†ÏÖ?<–Bˆ¿_0,÷–µŽ³Ñ;G.wÑ7ÖéÒ¯§Ã—Ë÷–ý~ÿ®»îbŽ.%_Jð¥…6™€²¯m1ÀïgÎ'«§1£DrGÕ¹Ð,J¹g Ú.S¹BuéVD{?:?†aþ¼<» ‹‡qåªÂi|äFwãÝ7CÎÆÄ¤º±½Š²¨ö±ZùÔ2{M–•eÝ…ÿ†ÿ˜ÐºW8Ëà#£ÛëѯTcb`:R?d0Ø~°“: ƒ2 gM-’ñíб[ãÀR<×F 0Gð:ضÖõoPjB¡¤Ùl–«?^›Ý#ãôÞL¢¬ü_+)Ô~ Æ—e©4c¼ŠÕ%˜jè-ËÒÝíÂòVvßݽõ¤[Ã0tßtñwââᢼ¬L¾œÁ:£k 5Uîá\V—3î´þ0$j\ª V ´n½Ê½gÀ…æ7T7Ï\þ—#L-| Ëƒòë§3IÔ:óÔÛ †^«ÕÚºu+0)nc¨íYöP«ÕŽ]|ìà/<åk§TËUQ —/,lY8ûg[ydüOo$3MÓ‹.ºèÅ/~ñwÜqäÈ‘áp˜™¦Añuq¸ŽÎõ¾ØãJ£‡£ðG!±!üfØK¿xO¡ Aäÿ.oüé˜òcχfžžÔºSÔieLªAñª€<,G M-%é jÇÈŽ Õ1²;Rêà„Z±ydE†Š ‹ðçÂð†°uCk4EqþsÏߺkë{Ý{ßìÞ¼r6&êðž æõAÎÒ…Ô}×Õ¦jeQ–ݲêVjMö¥}xOçŸäW«]Iô?íDSœ`YÛr4~3C!x¨LÜ_/«2ÄdÒVýOŠV¯‡T×öËä‰@º9GÈÔÔ ÔŠ8©<4i´5Š($×?þ'K.º9Ц"÷w.8DQT,åÖ2zZTõªðèØŠFé|ž&7Ì4UáÜáu«'¨ê¶ÅëAm�uRD%Aa+0/ŒL§=R剨„“)·ê¢¢&³¹H•q¢ªIo\)´ß!Y´Ûí;w6Á``/}jjʰ¦Z­f6<ív{Û¶mÇŸt|´gôä÷<9?–»Ò ‡ÃúÍõì¤lßîÛóî=išîܹóСCö« *{eÑ.FýÑþýûoºé¦Ûo¿}nn®‹¢^+ëÆ’›w£‹ÿaœoåGó¨ÅI¬Í•ÙWÌ.þÓbø°þ™zÇŹEï-½ø½q¸?ÔU ’Æø®%ðÈ ·xfOã (§<é&z„žžÍfÓ^·Å!ìíÕ¹Êê�žÁukWžYº£.þV<pû§•OÛæ¶ý…û‹e·<í¦7CÎOúG3tDº°+6"J†a7¬UUV®ZË#X²@±|šêmP þ3£=d÷æ8âÖ«ïxéÒÕ€’Þ£# úk¼A$ÃÐãHAN8ÁdÈòÔXÈsxS•Òµƒc5 ×'àq:( ì£ì’´Z£*­Mª'£Èµ/Ô²ßȲ7gÉ—“0 ]á†ÃÃaú§iVàH¨tlSy öT8Ee]´wE‘lHSMʉs ¹0éDU‘ª.»5“’ÓßWYtË-â86Ó{zX°¸õ£ išÚ£ÜCéßn··oßnÿ–ôÈž‰E£ÓO?ýÌ3Ï,Ëòä]'ßuÎ]';©Õoeµq äA­[[ZXZع0{x¶ÑhlݺÕÜNÃCaýºúè5£èýÑí·ß~ß}÷-..öz½òìÒ=Ó5_×U£u™ ªùªŠªª¨è†ªs¨;⦞3•??ïÿQß9ÿ8n?§çyX_gk†*…,¹ùt ç´ýu0 }Aj]ÊÒbI+ÓDåï<’§}&U²ârXäi›¶gQùiùð¢aúëiQ­VkjjªÓéDQ´Çíù÷ W¹«®tWn†œ `Hkƒ£ÙlNOO/--ᬧrgêÖ [‰ž¼®iõ?צ®ºÂx¶cðXÔ>ÙU»/ÕƒO{${¬R5IMr!Ûpú(ÁI1€à™«:“ù;Õ•–n‹xiÖÏEªT‰ó³!Ul\Ÿ}4‰?Þ0(â¢V¯EïŠÂa˜ŒKÐËâë�ÕæU_6�h‡Ø›µäT±>†øÒ4…ÈD=A‹NÊG~Þ˜*äk¥ACÅútœ(F!_7RåSç­VkffÆœ¢.±kNÓÔ<§Ÿ~úI'ÇñγwÜ{ðâ?»ø`~På †G‡SߟZxÎBò׉M\¥iº´´EQø£pô3£þ;ú ïY˜ŸŸ/ËrøêayzYûRÍò3Èšæk1¡èñ8Ź&j~£9B#ñ"2)Å5 E Ø’:ˆ¦Râì,šR¡^{#$yÞx¦•R#¾"j KˉÌ uf"Xùa0–6˜=óÌ3<¸9 ºñUŽ2èñÑycÍ|=ÕKϯ‰óÔ³?™dU’óOœˆâ¨< LТŠS˜Ö±zb¢Ípô<<G25°b$ˆ(©ŒSIë6¥ÿª±Æ—ÁnHŸUeLð ‹å”5Z$iB‡{€ïÜĸõøM½?°Lee¥¬JO;NU=Nà$k|ræ‰@u=±·À=ªÉ>p@K-ªÔÿ‚.š2MHÃ)—y•ÐI¬ ƒçdN^µ/õÈÖ0Ìb0[BÞîGt×O>ùäÇ=îqÅ“Š×žùÚ fŽ5Ž]ó{× ƒ=´gËhËoÞUAP@LMM ƒ,ËŠ;‹ú°><u¸üñeWwιæÿjß,â›ã",X!lðCoÈ߉ YRÎz“ ,6û·ðë¶Ò抲*XÌü*ÏBó b.¤]ÍJ8”ÀT½>¢òèU Ô}�� �IDAT¸]œV%ÛgAíâââþýûWVV6ýr6òGMÀTñÉðP}aP†3BEYxñN|¦uó3ú§d*ÕŒ¢:æÀUí /æ¡Ö¬EÃxyIî9<ò›ìsæË´­Â,g7+Þ›4$&ÚiŽiíÐz½Þl6 ’6B§zج€(ôØ)7U"E{­xÚ£1`äqÃàû:Q+èv»´Üð6Up·ÞjšƒU+ƒ (N.ÊÝeÿÏúÎ9¸éßÎÊâù^Ÿ=·F£§öOŒ†ßk”wãnh÷ˆ$Ún“e‰¢9¬  T3‰€dÏ Bë ­†ôz=»*Óà± JûØv»íœ³Ù ±6çEÑ)§œ²ëçvýý‹þþœ©s>}üá;n=8ëfOò¤/=éïøFq Øñ?vÔ«úô–éÁì YIàãµZ­Á``¡äþ$½? nÂ(Œ¢È­¸`”nv å9‚£ùy’j³Q ÚäÁ²xlqjËÄÛfŒ /z©¤>äÉÈî°µ„/°‡·Ûþê÷ûF¦PûyU_TÌÓÃ0îÂkÃì7³ø#ñh4š››³{ü‘ûÑõîú¿t¹r6 äxFO:¬§oÔv¼ã .–z‘ݰv•ÁåÖÛ1Q¶“ƒ«Ë2QAÇ”¯©¥AÎÓFSéýKj °&(Š$x�ûD½ÝôX‡õ‹c›JöºõFŠ“î/l~ªd!‡C8éYÂ<£W 2.C“<Ta¦©Kؘ$rîhôê‘s.½0µ÷Þû«^y¼ ?ûƘ›©å[°Ñ“‘sGÍZœH ¥²DqCOʼnû8ÀšQE’$IÓtzzúرcêH­–€ª�«¤s&aíø£ßf©Ø`0ิ�<==½mÛ¶sÎ9ç“Ïþä’ìîy_ú¾ ^ð¡Ñ‡¾ûÒó/=ëγ~ñ~ñÎ3îœåü¶÷o[l.Î=kn÷w—õ1Û­Ýn·Ûí¹¹¹µ4Ñ…qX”…ÒXì$ÕaXŸ¼Í‹ƒ™ÚËÔ¸ ³Ë "©ð¨=aªñ6VZ‘xü7Þ f6:À�Ì«·æŠ|"X§¿PUUUVÁýAùìrté(ùjâ Á·ƒoŸìNÞëöÖ]}3äl$iMu <E£Z­Öjµ–––tÜü ÀWµo)e<¶¿Æ¼-ek ræªÑ@ õ²âÅjã ·Þ@ Ò¹NÀ@°f¶´²º9˜4ƒÓ#Õ2t‚„$èm<4µ¡ãÅpµfšÜšòîÒ4Å×R âúZU¦W¥® }£å\–e£Ñh·Û‹‹‹Í)%] ùËóÚµµøÛqŽ÷yë­Þ%½Ñ Fîž51ÆE™E·£‘µgÌIC¸Ü+'E©nèêÛíõzTÈ[j¨c|6'’ƒJP4 e»ÝÆÛ~ÆôôôãÿøÎÞÎ/ÍþÒ©ñ©ûÝþnÙ}Bþ„0 Ï‹Î{~ùü»áî_ºí—–/ߟÜôÍGGÙhæK3–1´Z-{2SSS6“o{+kø?ÔÀ¬ærÞ\‹ç ªJH(J¨,줛Gú™uÌOšòÑ•ñð½ÂI‹?•%T€Ní‰yqêÈL·Ê (b?þêïEyœO†ïºÀU®:rÆ‘ÓÜi¯u¯ÝÖ6>äб`oCMÑ– '& µö]�y‰ Êã"&©ó± 7…a¸òÞ•üÌ| ëQ¯ýcmÒÑD‹DShZ¢ÜTm D`Y*iší^ÔS±sf<¨´Ê‹ãèQUJ¥?©3.uJ–qUv×ÚÔa““B¥‘=ã)àG»šöŒ—å/µÖÞKš¦{÷îݹsçõ×_?77G⩺«vmýŸë×ÊZã®Ff<>ÿ9¾~èžâÊÛ× *M*oò Ð$Ö¡KÛ¦ñFs›Ö±g”ÇtªrÓHÆ,RË,hërlÞ}C/mÞkëÖ­»víb™5›Ív»½eË–Ý»wŸ}öÙ_zÜ—ÎMÎΧo‰nÉ‚ìgªŸÉ†Ù©Õ©ï+ß÷û¯_ùõl9ëlï<í¶§íÚ·+^Ž{išÚؼaƒý~ß $,Ú<ÜZ¦=mBâÉà„(-í({2�€À¶UÙ2ö:x\„ «‰u ½o`8´ZÄZXUX F¯PƒŽäÖ;ê”4¿¦©¡*+ÒÔi6›Î¹äûItS4¼`XºÒ9÷kÿÚ§\°ÙËÙHÆÆ\v,ª­ºµsx‹ƒÁ€Y„¼ÔRÅ(u²L9N–ÍBU­ê¼¢“¿*oÿ¿íð°,ÊÁïVÞºÒú–;0¦±ióF]¤X‹ü!˲ðì0ªGa†‡nÙ9ч§ÿÝsBê»™b²¡ªrΓ˜$É©W~kÑ‚¶ml˜;|PmÛX¯… Vœ³×ë)èÇÎFÀñÚÐÒ‹¡1æÄñseeÅh©ªºˆD#èø”¸Ê+·0þðV«•eY–eɉ¤hÉI‰‹œÇz°ÔÕ™0¡Ö²EQX3ŒhMÕe¿²¥µ¡emHBØ™h×0 ð×P~<%µwFúPÍfÓþa»ÝÞºuëÌÌL«Õ2‰+SvîÜ9;;»ÖE[…|ì´ÝUìÚVnû“ôOÒnúáâûfw=qÛË–+++?üð‰'Ž=j²l6Wdd‡n·k¯€ÕÎsƒJc±G±qU@'*ƒÛcüQˆØ£ÉÇ…V-'žOJjЙYí)ZcL;ÎÊS{ø,fEű²¶ßQCaÍáÀ ¾SÁ‘øúqö,o2Ö64Þ¨¹gZÅIÄßÀmC!Q™¾ j‘#C˜V g…ïi”O(‹'íg·Çažþ×4òî׺S/𲥉í4­H &J’¤8¯~6ÈŸ“çõ¼ªªÆê*øúK)UĪ6FV¨×nÕ?Ša°)B ¶R-Š3‘®T+Õ�ŵPiݪ3&0wu( ³óÀwLÎâvÀå•xfž’wÝuWš¦ <J ¶6¶V,r—Å­ën± =Ð8ˆ ñ�ú³§mÉÌ¿ýaË–-;vì@wüÖzGhXN3Î9$ ©k¸>LÏ‘ˆ›v×išîرC¦‘é<óÌ3Ï;ï¼æSšþP'èœ\œTÉCÁC§W§‡axwt÷ÌÂÌ=ÿzÏ÷Þqדï:úÝ£÷üøž,Ë:N§Ó1Uo+¡æææÌï�S(眅¢cÇŽ©�.© e*DäÔ\³³pÈôHÄzbW| ËCGhùpÚ`p8ù‡TE�§ý~_[Œª,¥ž2j¨áa†J„SµTX‡Ð9š<møGûÏcÁ”i–Ø ‘êÕsMÙh$¹}@¥P´oAö’,ùrb1czzz8v»Ý° k×ÖÊ—”Ñ×"ŒO舠7c‰°ÑœŠŸ)F—Œânœþç4è£Ñ¨xIQ] ~u|:±Ô^-mi²ß<r6O[ÇÈ {½" ª~íÇxê,ätÊg#yC¬Š€[ª :…Œ¬bÙ¥:ÔqЫթR’Vi^‹¬<ðú=õÑù£òœ²¼§\^^Æ–xôÄQµT•÷®³ûå0BÖÈn@ôW Švµišnß¾ýèÑ£J‹Â&R¹ìé zãÉjÚGÎG`X€¬(ŠVVVh1Zµa_m‚LÃápyyyyyùéÕÓ?¶ýc—4.9¯<¯UµnŠnÚ]쎢è«áWgnŸ9tÛ¡»fîZ\^ÜrÓ–cƒcF©°ƒU7ÑêÀ– A©x x걤کêÁ¬Û[V ÚlT_Ñëÿk¡¬==`öH—±vehM‘Ú*}ŽÑ0÷Œd‹ÍËÿª¿ 1LGÔ=rö£—z �k`µ ƒªz«“T” M”z‘UûY3•o‚»iÞ'c®ÑE£èŸ¢8ŽÏ:ë¬ßú­ßzîsŸ;55UåU|Cœ?3×pz"¡£]£¢*¢÷G®³J)þz­ù•fþorÕ_‚"19`%9éÕ•zš’*€%ÁZú˜‘°÷”õ¤26´µ<áÏŠJ²Qû¿pOMp¦ EåY‘sÐÕ Óî9 3Šo¥Cý¡ºK\¹»dIŒ¥†Î΃^ 81múÏ>S1}=nÈo”Jg¿vìØ±üàÇŽÓSÆŠåÙkkiS+‘D"6+«E»Ðv׺à>x~€Ôs9:t×]w½ôÖ—¾5xë[ëoý5÷kß­}÷EÍ=¿þü}÷m½cëg_þÙýOÝÆ·ÏÀïY)XN„Ïu²Í|ÞæççI�BÙP¤öjY¨€U‡ëXÈ´%l;33÷G}L´€fP”Ûí¨†!ƒ”‡©z¨©8´ÚÉë’±Ù;åµÚÇ¥`:gIîÄêf•³1s9乬3uŸ„YG5T„˜_ ª‹‚€ŽMX¡mKPQ)[úý¾'ãƒÞXÊk@—ž!Ø”¿Y6®hÄq<==½}ûöãÇ/--‡‚úë½+{õ÷×a¼€D«M'":©îQ½€H ¿,N+zÆò5/ó’AäC¸Y¥°ÓGµ×Aä¶4R Õjõ¦£KtªtL‡àÄwNíˆÖÐÿ?tý?¦oKó*/«2{_V»©ÖúãV–˜k1ÇG‹ÛIthÆkkÛ¹fË`º¹TH–ý¨})Tº­çÑï÷ëõ:C] !nYÉbG0\ VܘʘâªòÔjµ7¸7tÏë¾üä—gU¶Ò[ w§w»KܹpîÔÊTÞ]ã‹ãÝ’eY£Ñ`uT¨} égI¨§'Âb*à ƒ\×*D ;ûÞN§cƒA¬[ÔxQ(W²­–ê©\›òœè×é,¥ÓèÎòFH÷O*.L[ =Ñà¦9ªtðͳ‘Q3ù»-{¯ð^8‘á(ÿ‡ScRFŒA&C uN¬ÃÃòiåðÆáƒ>xÕUW™…báŠâ)Eôÿ}‹Éý±õÔ³u|¾×‚ZPKÓô‚ .xÆ3žñ­o}ë{ßûž™Ç¸d=Ó_ùo´^•‰k½}NLcUXænËÝb§=¤µU‡dSÇH5Üj–M£ Z‘ª¶¨@/Ì=U¶VádjÚ{³×dÓ#);é±;çâ*®½¥팺Ô-˲(‹ÆKIžT®çD¢Ôºâf´£~_:÷®¢y:ÓN~JäQµ8Èw"@�0e53®ív»:KÈ(Ÿc§6ÊIvæŒpì„-I’'N<ðÀišž78ïkç-Ïóë®»î‡?üá±cDz,[\\ì—}tl�”Åql ‡£NA™(…/»†TÀÖ’ªái‹!'Š<:À €”ªÚÜé\'uƦUÚurÂ_EÖ¡¶êÔ”Çb÷¦å öh¢æÄcT=‚èÁ«™ré›!g#éѤ6^W_ µ&ÉNŠ•i€ÊÏ81Yá”´ÝNZ䜋¯Šó×äéÍi¿ß‡™]†eñò"ùå$¨&©KŠc]ÕDø›~¿ôèQó’2µ%':o½˜B‡lª¾÷ÚÀ‹EóGü`Ge¯y@™6cõ?Aý䟫ˆ�0Kýh³9™T±¦±2µ”°NI¡oS;+ö.¸)¢ÖëZv`¥ijõ ½(ýLLnì|$œ«´—ú ‘ÁØŠÒ,›§êe-HÞ1„¯Ü-û¢ååe¸¸íq<qœ£ÚúF¦IÃíhaa_´´´´oß¾Á`pòÉ'Eqï½÷î߿߉Қ-ð“hcýÅô ÁO9Ÿž;�兲ȴp×cšÄ…ýbAU½‘d¦oª4Ðlͼœ‰“Ê6jG‡rè¨\+]®™®ª¾q†o´ï¨š‡ÞŽÀNe“>ðSÑÎQ5ÕvDOš¦=([NE·HÁëØ?”*BNÚ5â}ñhߨwm¯ñºFy_YÅè-£ü9yíwjÚàçÕð(·âÒ¯§ƒËåU¥)Àw:¢(Ü—=;Kß›rê© ðdXE¨”ƒÞÖ½ ‡ØÆfä%MÓÝ»w›Ç0g ;ßšw:N#gæDˆ#Xm’ÉßIHuºHÿ¬j˜n½L–Jh'IË&u1ðä°‡ñ¸@ž³8p‡ÚMrkÚ+VšŸ.!oåQDF›Óš8£ÄœòÖAÑ©åµól•”Äaã8Y–¾¢2èÂ0|衇ò<øá‡ çDžYÅÐ2° Õ½Õì.8u›ÎxyÒÝ:8É\5ÊDò¿G¬&)g©°ùX¥É©/‰¶ Ð&°åjïû]E§•„íĉ‘Ö zö ìYUg'…"Ø(¨ ~®ÌÍ^ÎOE­£˜‰þ û¢ˆ¯Öp0ÜI"¬I\pÜ«#– Ç&IÒ]ìï ’&ƒ¿T¯œs­÷µÜ]ÞɃ( ·¬´lþ�‘lÔU÷TåEeq^Ñ o*~Ñã#w–«zUx(,ãÒ†Ã!Fpœ¹”;tqTc[m‰µWšNÞØ| x $‚1ΰ5mÞ3ªfªÊUµ¿ª…?«û*õpb=BkwRhÒ‚„¿�­1íФØS£äÒoÑn°²òhõaX€<“1rÄ$#SQèNd|G'Õ ÚÒ§ê–(q©€…ÖèJÔã¾ÑhØâgRÕÚ9j™Ì…ÙÚ°�“eY¿ßït:…!…gaÕe·9;;›$ÉÒÒ’é ŒDÓȾ:MÓf³iÍ#(*G*¦Eö6Õ}ƒEKHqÚ$*ºÎ/¯ÌÛ&Œš©ƒ‘…yFßx¡r«Ú²ÖæQ1u8>ö4Ì mnD}¿¸f²+SÆÛ$IÿT4r<åWÞœÍB3ônλóóóÄ £u‘À‚PñhOóÚÓvb‰6nŒÊæo4ÕlmŒ ©¦ÑúÔC?øNÍDÙ²ò¦²Ê*ç\ñÄ¢rUò–¤ˆ Ä€¡ôðÜz1…ŒMHض(ì>Ê”<Ï8�:AB ¨H^i¥Œsnxò°zMUœ^´½]¨ò<^9,®,Ê¿/ãÑÄRÓLVÑ$·F²éV=Çè!ó àlМH÷kæú1­¶°Ï± oïÅ–A¯×SˆC;F³V{ï˜À‚­y˜­Š)I˜ O±&–„Î2M¥Ò*“ÌPʶ0wíN{½ž){zÔAj—n·[¯×m*–Ö‹ei£Ñ¨ÑhÀß³<¬Ùl&IÒëõ–––ж0‡œÐ<Ö¯£n½c´‡ªØ„ÆW­Ùª¬gJe¸�$°XáNd‡X-“' Wî]Œ}ŽåTlªæ®ÓÓ¶HZ­©*«Ñö*ºÝz7úͳñ?Š™h®Ä°…Ž +ðz¦\RÊa¸°p¥€›ô»ÔEçF•7E‡YRþRU¶Öjö¯¯7òWæA;ˆã8üë°Ú_UÁ˜#DIifDD¾Â.˜ñ4uìbÌ“V¶Iw»]ÏÖZ•¡kµZö¤Ì…®ñúFéÆ8Iýƒõâ´¢xoQÿnºÒÌ<ÅR'B8Nìâyò:;e…®s6:”‡M=–1šÑâ®×ëguV–e<ð�-b6¼rÊQ"WŠrÊx5qt"ꥲšs°ê¸#z0& 5€@« Juh ‡©¢‘ÖäOÓÔ&r(†IP›„…œn·Ûëõì$µ{7AµÎe8¹¼¼¼²²KKv{ÖkY^^žì†ª*¶–&Þˆ+é‹Î*hWl’FìYµòjÀZ“W‰ÛɧÇÌ;er+yÆ(ºàù}[ L/yÏ7Úæy²UÈqs.gã5ÛÕN<©¼yìn·{øðaU²¬P•!p‹Î^ÂËÒÔ0c¦UêHHb1gSl {µÏÔâÄá‡Ââþ5½aL”Y‚ß¼«UÏ»L‡{�LÇ^UÅôx…HDZÛêŠK‹èo£<ÏO:餽{÷îÞ½;Š¢èx] ~e âÜzÎê öœµ#eÛÛŠõªœFÖŽ<ï”±çl§¶Vxp… v†.-----©Û´;jåy]ÍèB!ÛlUš=I›óÐXåCê!¢™ºMB:„j4A:l+Ùî—Õe¥¿åÚœ¼†@öz=`"CÕXºÆ®ÆNƒu6–¯• '5‹ÜÆ_&c{ Z…°•4ähÉ+°ãÞ- èdLÌèóÑ SÒS•8s&Hµêv°'\«Õ¨VÁr‰²–¤bÉÈ~´“Šìy_uñÑ+±€íÍnV9ù£ÒœŠøk*ä;Å ¥#×0/¡Q)ç̓ïÔ€Ë;”iÛŽ²¥ î¡3óˆÖ òƾB—Œ§£H"´:ŒË6Ð)@$#½xÐ3B-Š¢ÓéxâОôï°V'Wáápjvê’K.¹ôÒKo»í¶|ä#>ø`9_ºs–00Ù`"àÓL—˜ÁÔM.±Š²2Š2ö4ºÝ.ÿÉ«ôÕ{û™RÒ–Á‘#GáJÔ®³ë¬1‹XŒÄêä hªQÅÔ§Ë"õá,©ö—šÑtÁGÙ>„™e’Kl@8†¢ ¾1ž›Í¦¹š*C!¤xÀ.Ûòqû5@N@?›€>q℠Ā ÐäV§5íYVdbe(lk›ÚUÜÖd`Èù³ý'»eRèYhÑ ‰û†F<¡^ª%âŸöíÕ0®K®†¸¸Âwê´VIØ8Q§G½ z¥*l†œŸ‚Û‰*Ψk­<=|5ƒgɶdº[çì8îYv¬+óXé+jâdl ¸ŽË¹õJS^ØSBòìŠJ+ï…µkY?sꢪ·Þ9 ÅÖþ/ȸ¶ÍN/..®¬¬Œ«–0p›žž®×ëGޱ©*Ržƒ‘aöÉÆ`V£®‰~'nžŠ£Ú†‡»®¢Ô>ŠËëU¸ŒNµF\®Ü4žôTÏÍG5æš,޵ܤ¼ AöDBµî¤LTÈEå$¾õßÚþY–íÚµK_®…ƒ¿æççÝêˆ>‡»¶ «ªšžž®ªj~~~yy'6–Ú{Žªphk™ð£çNíDü ¥�õ!T°A5amΟœ‰ •Kè#?CûJ•Ú¹U\¤¢UùAÀmv¨V™=ă"”MàVçXíö B×m3äl$ªF‰ª›Ü{‹ž­§®o aÑ[ Ã,qµC'6ð—¶—(zTÆ‘1 ½æ™×ꀡ²<êmUÆ;€‘×§Žgä›ê¤@³];dc°¹F߉†Ï.\³ðo|ãÎ;ï<zôèÃ?n³§féWÒ©©)sãáO¢í<d áÂj9–Hc†‡ ¤†3è¥Z>+ÖŽñ˜µˆž‘«ZP´’¢Ùlò¦”‰®<¥«^ … %ˆ&¹9´ÂóYçsŒvOfÀTæ½’á#8ç:Îôô4½1Û¬u^'Rþ·U´²²râÄ ”8ĆÀ\ŽªZ¨ “×ýRMwÏôO `ƒå%´ßxÙ섈ådŸÚdͰµõX@%Ë;X Ô¨g¨zXpÍ*q¢•ŠÝÂöchîßæƒ‹ιڭµÚ§jÞØ 9?éŸÏ»Ïÿ¹ûsç\·ì“aíbo¬Ç‡šF3œ¯ïž4öpßÅvU˜ÈMX�h'@{:ب4ÄdNMÓ8]hy²+ÄÖ²”ô™²Lç•……ËŽÁ#ž´†îF ]Š¢Axg8úù‘ûßîÀG+-Wž]º[ÜÜÔœùàqØy‹ÚµbÔïam›y5zhCŒ‰è§€6Õ>ç[œ8Ñ©¤ ù)äÐÌì:Aea¢3BÁÅk]â1ÑY3°úæi+ö‚(8¯C•jI¶øDùE±!‚öáÑ£Gó<o·Ûà?ôf:ŽÝ©vÑíÌXÁ9wüøñÅÅEÆø½_¶C_ç~Èr˜}¡E¡®HvG:Í£ÄLù–IP]w«‹ ®#:ÿ@©Çà”= 5ïàñÒKh´å¡Êªõ®9:ÐC²h‡•zƒF§GÝOu£¯FõOד$Éž”­\·Rÿzý®ºf0›!ç'ôs§»óÕîÕ—¹Ë¾ï¾ïœ»þÉ×_ô݋ܧ\ðÙÀeÎkä¨ì 7,Í2U)Áif'PÎ` yÖ)�µäh`5Ì]Û™hù#»8JãÑö’“‰hPò}ϳ]k&Û 6Q¨ä]�1J‹‘ñ <I;ĩҘôN¾•§ƒëÅÛŠQwäœË;/¶µ—Õʰ4/�<Ç<Ѐh¡µŽ7wÂQW¥¢¢jÑ ë¯4YE8 Éö`áb©>›‚ivBỾj8ýZSžìžÚGšíõ·é]Û™…Ê�<xESUèKå Û°Ó,ŠÖµ¯ÝÑ`0˜››[^^6zH­VËÈ͸’#·jßétæççÍ舡8d¤ípºÈº˜ñT¢`‹göíJ–——ÕÍÌJ K(_”§Àˆ.å‹ql‘3JeßhåµÎZyJþ Ž|^%Ê4¿ ¥<BMº‘uÊMûöÞûŸê·ŸÛ®ª*‰ç\òý$þ›¸÷µ^ò+IÑÙÖ~â?¯v¯¾ÑݸV(Ü5ž×~l8úÎ(ºwM4Â#œ°&ØN,Pf¡½ Ó¾W+È­)âæ#gœ*»ØNÐSu’.¬L$:êð¸øå2©¶ çDn÷kx <´Ç@„E< uÊ–áâÇÍ5³?ʆ3Ã0 Ó¿JûÂ*YC”Ȥì/f¼Ýªx»=’qãíG-gxøÆdâÕ¾Âút¡µòÐÔÄ•$@ë0êT¤MЬÔ|øÔáL�� �IDAT—™²ÂNTß5mdà·:Ó®e+©Ï†‚5ù9òÈ%E° C«½xõ‡¶傩޶Ûív»m ¸+!åbœÏ¥¥%[ü:Ho—¤™ŠŠýÀïÐõ¯E'+ ]PhíŒjC‘¡b¶§dLþGnÁœ�#Ózº³zVL/³åIï<¸[¥`µ»F¹I«X¥ƒñ·â²(ѶÏó<Žâäšdø‚aúåô1`^ðh 9W¹«®pWxYUUðñ »<k½«¥NVÚšS÷r'Ãwª-Í¡ ”0 †v"Q¥C$Ú¡Q¡e•ÞR9Û¥ž‡—¼óÏ•šÔÃÉe_¢è5«=)0ÄèˆR×+AÕ*¡ýÌR1ï\{D*Ž«Ê1t>!J¨™ç‚§J¼ÔOV¥N•ÆÑ¦ÒôªÕY;\JYÚäS+nÞ²¦Éz”­·Ûí0 M6‚RÉt+t*–»Ó+ô¸Îê|¬ý9•.V à-R"]ˆóÛÑ9,,Õjµ©©)«­zËó¼ßﯬ¬åWݵY!Ì9M^¡o  |¤ñ£ÚwFGô\Õõ@Ÿ¥4diOH_ºry&:‰ŒŠ(‘ (ÂÒ&E…^‰R^Jµƒ½{ä¬à:‡¯6³„A£Ñ¸à‚ ¶oßþ­o}kaa!y_Òû—^ýKõÇ€�Á£)äü‹û—+Ý•w Žãà;AÿOúT*:£«h’@{U E« OÎÒ)·¿7š,DòS;µ=j–‚<ÔÊ•T,ð2oãáZÈYƒ/§zØ8™ªC³ Ž!þJŸSYb5ùP©DÛovF«j=% Š2P„y,#5æèô8©žFµê½k­ “ÿVÏ1ŠM‡~`¸y.y4·ˆÓÞ»[/¼èÄN’ Á襧 ]•S•XîWq`­ÀëSdÒ3õ¦&Ùf ꜳÙO»B²Ÿz½nSÀsss5Ò@’Öo¡¿HSV˜ý_;޵¡ ‚ ¯NÒ&DN@3F›7¹Ò9*pKÅ0ŒYê9bhÖ¶meýà¼/åÉ=üAÙzÁ¸¶ƒ6¯M€UŽ:ω÷¼«ÜcãçQ¯$­Ì"[¬è 2¶mg8£Ÿ¬ÍÓ‰­Æ†]É'Àå¶tÎPß@pv'r„:†bW¨3e*ˆ‡M`­3ܪ!›v㎴!D<¯PI|Qñ®Õj\€ý'rgô:íÑáUcÏ܃v‹]-˜ ”kOõÄCÏ1Ud{k‡¦( “â·RoÂ9“xšy&åÕ²,³¡B2�ušpë ¸¬×aWnÍÖE°³iB¾ÇŒPU l2œ(`rñz Ú{WåiÕU²mSA3êà�¬%@hsØQhý[¦Š<)Í’' ¼žºSl:OêH¥Ò8q õÌåÔj£¥_:…Þª†,kØ,¤*¨æ Ü•“™½BþöDÐU¾Z㨎yÒdU2ýú»/Žžÿ\t»Ýn¸!Š"Ó€Hž”„?Õ't3äü$~žížýOîŸÎwçkãœ+ŸS&ÿ’°im,À–&žª’D~ |ÄÁü ô[C8xÀ.;\uPˆ^ªç¯1†8¤qÔ¶4ù¸Ž)ù– EÐ'f²Áó2Ðá⻆*»FóeÎ8m�p³´|-Àx*ªŒë7ˆ3w­p™fÖ“öqpŠt“C/œÄ9ñFšèÉëç{æ@4Û¬âôšç¶*\ T·Jc©›iƒJÝ”æÄ?Tkm’emk[bn+S%Í*´‰H?ߊBFÖ´¬'ä{OÒë–{Í0rüÙ,wbJ:¯õ1 ¶¢L¡@¨5ö -*{õ¶ÞHDTúGDjx: )\¹'ZH™d×̃Rõ#ïœÑŠJ�E ‹¢h¿­}âÚ­g·LšO÷t[—µ&Çõ?&Á›ËÝåŸvŸöþ2Š¢â•Eò™„UÂ9è) 2k™N¦omI–¸R{Á+XÀ¾Ìó+L€ápœøBâTu&5Š6PHwŽv�…Úµu¬‡ßmÔ*¥Ö¸õv�àTÈâòg…hl«+—P±ÑhX&ˆÜƒªÕiÿÃîÝ#›PTµ §~¯&1©Ú$“€¤§G ýasW@މ'gÀƒõàM*ZOqljY­[]öºü°¨´EÁqL* Fä±.uлGisë~•¤K0¶- -.Ö!�ÞŽRB¸#²¸šfãA]‚x×,K¥’£ád{Í2HÔpm·r†#±J%µ¥E!BN6ÉÂç­iTðÄ›õ659Pa{\°QìâM®mf[„ô·Hwÿ³Ñû@/ÿåq¾˜ÿ\>úð(újTöËIòÑf•ó“`<Í=íeîeovovÎ Ÿ4ìüc§vU-Ü¿Fï«}µ¦¡çótª[ãÖO³SyX] †¦ºñª2K¾oÌfìÂìÛ 'tƒ<Gg4hˆ3"ÏsÜv9 èÄbáƒ#*èÉ,þ@m:¦nÀì½wžÒFQ= £Ð…®•e1>MŸ4SgËa#oOÞ }o Ö}»–jcLò;N{?v±h�ðF@@r84µ—ÃwA…@kËDukUQu`SN”]0L è¯z£ž6«ƒçެÚªª�¢¥6<Žã ŠÙbùsËc~àei¼GA¤Ñ×ãàq[ÿo~µü/ì2>g]ª¢‹þßöÝ®rUóO›Á·‚(ŒX$ K!Æl>f“Î>#ÈæŸ†¢êËÎ~M‡öäĆˆÄ£³ËÓZÞ¦}¯Ï¨%ô~â«ãúõìßeÅ;ŠQ0 o k®Uûª$H¼6ífÈùIüœëνÑÝø÷…g¹g9çz·õÏo„aX”é•&}ä¼êð¨ü±  nV”�'7uLQV’~§°¿Ùib9>§˜’ÖôïõCqЙM%Ø(Nˆ½ }Z-"ÙpL8´ó]C¯ÊPà{è¼òöí6©WUU±³ˆvEýßï»)çÿmÞF·®9ÐÃç8)€°=Æ ŽïpL+ Õþ!Œ�RHTõšMÝNK^Ó©UeVoÍFU¤€ ð&êT¯´`Åþ±'éD”ÞŽªÁ` |åÅÚZéP©zš4u <“ (Šeí1k팃è΢û{Ýü”¼ù¬¦=çåO-çGòú«'GFm</"§8Ž›Í¦J’Sz*Fê‘ï×ôy›Åà×½ô¯iÔ×ʲÌÞ–o,â7ÅáÝ!1F¥»ÕG)—Põ¨PË Ÿanß¾½(Šùùyd¨ €ë’Px€?€¬MQåu€L!5[¨°lò^Ý5ïh†jÎÅÎ<…7Õ6àçåîå/w/wÎ}/øÞ £«ñv¯G/S¤ƒ,š ¹õâfttÔÀM§•«t8¹S=VžRlÛ0ö¡tmÚòŠPkÆDËA½½KÒ¼X%Î�¾Q¦Ò]¤å"˜šn»ŠìY1[4_Ý WÂ0 û¯ê翚;ƒèÚñ7Z Á‡À;P†+äuP‡lí¸õ£„ ¦O`Žáû©¦*†í©Ôpx9Ñrbîéi®˜þ?±“aRÆ*'š@è$ o6„ç¶§“öŠö¨}Žrùtfv¢’ÍÇ­·Ûq«jªSÐý•npmÐøJÃcŠðô+§ûÏë^9 ß*muȽÃWŸll.Õ+3°OîŸÓÏOÊÛÏkEáj®V«…ÿ-,§ÊÎ';íKÚ°™UÓ‹ œšc™‡©詼ímšÖ*¾mú9êÛ¤G‡J›k½¨¾‚*ñGLeŸª6wak@ë0õ˜ßìål$cSÃàûI,^7§ÉF)zKÏV1'FX¦x¯-û_ŠZ×a7T~µ‘8éíô§¦è:†ŒC®¹V‹—¥fš4c4—´SXÛ×:" F 4¹õŠŸ¶1†ÃáàñƒÊUµ7ׂåñK?‘ÆgW¬‰¥’!ê©ÂYà0ÊOåÛõ¼à®Q!„¨Š°yGôâ&w)L ˜åNlÆž,•¹z;Mh±Ø¥²–ð9µF}¿ß·šX[èÊœfIð‚’åE™´c̨Öd{À¾ZY,ËîÛÔ†6ç<Ï{ëåQþ`*ì~‡ÃauKU…Uþ„56—êD¸Aw‡åjö­þ¸õRLeT/+j_¨Õëuk ŽŸ–†É7“âßÚ±·×mC Šï)ìl¢ßïe—Àaô­Ó鬬¬l)«PY jÆÒÁôô´¥>šÈZuc^ÓÊPÒJëâ¬P[ØMúÀFþ0JBâoûJí#m^š&-­Xd*v©|$ëìQ÷¨¥<«n„úyТU˵±ÈØê³Øª<(Ï`ت Uxzb7½Ô‰ø ¤r#dÂndY#E #€ËƒEÛ‚òWÊÖ'Zj«ìœ Žñ7ãÑ«Gd�Š˜yö9œ’øÌ+‹O{àôBìÛ5«UÒ÷áž™õ޾b¦’& pÃ#  aÞHUuºP5ît2Ÿ¾‘õótØú‰rLTÜHÃ0e§ËçÖ«°h‡_?(IÔAŽÒDy¸+¬¢*:5g=ëY—]vÙã÷¸(ŠÜCÎ…Îír<dZS†£@§h’®L[ð-‚Ò¦@TÃ' ƒƒ ¦§§Í¿9 øŒë÷ÔË½ë¤ÆÌwŽ^«šÁ^k¿ß·iOÂÃ"±ýâ ä 0šRªm<UÇÎt É~àgS²«¿5)ŽÑ7çr6¾ÊѦ®"¶€<5h+Ã3·òÙr[†óÉÕæ–XbˋŪÎNjê¬-'2eº¥Uª‹ôG…U uic€<kË÷ FçÄáX©; ¸yrÔf쥫„FÒá5êÐU[ªòH‰²úX¨-¨ W†ÅÏôêUØßNRNLƒÝxŒdß*± ¯Ô>Å ØØz2Òªn�Ä;ƒ¶§$ÑËøN {@Ô^jyb¶ød8¾­75ûAÇk)ÁµeœÈº_Z1Ã<ô&íר6¬wBjl‘FÇ›tD”¤›üi\9@]íŒ3Î8묳î¹ç•gõxz`¶6ÂI DMQ5±XEä³ÇÈd•[M…_ŽNÚ¨iø4I€…{_v  Ä¡„·PTÐHÀmž§‡Òó4jµZ§Óév»íMGÊÀÐT· ${Jš‚@Bñ ÖͳñÀšÒ:µg«D~5Ö&3¹Ìä0íPmœ(xâ|‘÷i—¹OåG1†FÞ§ÞºŠ«¯†íZ­¶cÇŽ$Iæææ89p½!YãÒÁR¸I`n &è¾Ò' –-žduéJ&'ìÃm(RÛ]vUœj?¬•ÃtÚ`ƒø€¡‹šq唂äV‡½¿R†OFõ¤Yi&¹­ÄCàÄë[S]ŠªüfçÆšSÃÓP½_ê'".¯"=,'úsºaŠG£¼È˳ÊÁÁ5×\“¦é‰'‚ ˆÎ‰Š²{¾)*ȧÁ塬4’§>%MhWPÔºÂß FÏ¥ßO———×üfÒ xj/VkÕMײYh*Mk°Ñ-lõ¨g4 îD][[ŒæšªóàZm{Øû¤s¹Ê/iPôÌ¥íœG}ÈQQa4ð==;tp«¥%èmNM½éñè‡ëaÏÕSÓ¡âsSFÄ—Àý”äÉi Ų6Ëp•1¬p>¸«0ñ‡HšJR’¸é±¥iy+eÁÕrÿSœ¿$¾º6<EQtr”==Kÿ.¥iAÅ鉷kw‡Û„Ü¡î^FÚæE€žéT&“ŒT�ʆ‚”ÅsCÛÆ´L(=)§TÍS•RiÎ15L똢½=U/eá1?OÁ‹CzkžÜ§=Þ¾[o=îD4]Kj%:êL4òätÈøÍ0 kÔ²,ž;¬öUssskÈÁʪ¨Â{¢,´&öøôú.ì«"œè, .>ÏóZXK¯Mû—ôÝ?¯«ÚÃF8zö¨ñþFá %é©–JöáÊ¡,V8v«Ç å:‘Ps(P¦©€j"¥©0"#ª³àÖÛK«Î……jÅW7IÒ?…ÖË"ƒg¢šZ“ {›·K®¡šz0Ñ2QO ÙvÓ”Ð­Ž¼Ù5]X²´m´Ì²_8~ü8 —¶è�©×º:ÃÃ¥F#hQ_Ïêj|wÃ0º;*/(ƒ \ϹÒÕjµ<Êã“âbGQÝ^…ÉØDµë=k;PD Ó¾ˆ=R¼œiŸ@ïቄV˜êÎQ‹¨ÐßÈT–Mf.@n ¤Ó-(–ÉžZÓ÷‚^E•òwuÐUˆŠ¾h‰ÑìœuHȉº³Jú3—¦-@Û ÆŽ¡žÓ^cíµÁÛÃß¶.oUUU•UÿÓýè`”¾; £5 ̤}²U?ÿ·2 ãc­“†ÑQöälåÛ+õߪ‡…UTe¿ŸO/Zÿ±åE8ÝÅ^Wi�¯ÄQ)k´…¼‘&uòf ÃÑÐ,Í&¬á&@`QלÖu΃ʲ̚²”P@š:l†œ å?kž K•`p˜'éæÁJÄ‹0Ž9dVœ¨£¯_]f'§vT¢CMv1UEjãQºž17µÅu2qIˆµýÆaJžèyTs㣫=—ö“íb ]]W•;ÊÎç:éûÓ°A1¼l8˜´_Ó¢À8ëü¨pˆ7bâ)ßèèƒ[o­Íi<Wh#ÖÁÒ(îUý~ß´>µÍnõÍÚÔÑ9ýh{Te~‰u\‘sí3Ù1×ï÷•õ䘲XÈ“GÎ-«mÕ(•ûËè¡È[*šó²ª)¼<øÈ3A·ˆ©Ï9’HÓÔ®å!š£ö%£gÀk4óAýMõbºè}¾WU• \ûUmwÜ©¢‡=œF£ËÎ#j™[r Ê:ÄœIØ­ 8Q¤Nÿ;ì”§—A4ÿ{3úÃHe¨àX;ÑwW­BuhÕHÀ…Qy(ø©"&3z½;TÖ¶ƒŽ4¨{¹…™Ö¼7k£=H²–ë¦yÁO}@ yõ˜Ñg[¢UÅÉ/úW*3¬².|©"ÑZHiPtEí#UX%U2]é ˆØ™k‚ é­•jƒÜ:ÅgY–e²ÛÁD¢íÄ.SÉÇ:…\$ŸI²·fÕT†aýƒõðž°r•6ä½bB»:T¤òûp Î`g–Úši‚©g½Šø0‡dÿ|Íï`O=/«¶Ue£tΕ'Ê¢W$NÜÈÁjƒá1ž™á…h¤Ér†n·Ëþml Ê´Ì]îVÜhy”^•uN©Ü‘Õ 4œTü›ñu-ãàSi5ì·¬TOåþz:~6�[–e¶’5^Ò H ¢�9>JIØ|‘gÁǽPvÄÐh1²ŒAvMëu­5 ¾*gS+OA'‹"T–Jåq1P ÉÅ­Ê—ð¸ h:¨v"-¨Ü?F©¨”N©QVk}<¡E˜ÊCY6CÎF’¤mÝ E'ÖsâR2’2Üh±(‘‰“ ùd†3´¤x:i#b-*ÃN¨cÔCecÀÕ.”6Zì÷ííVCûY‡Fõ÷õUz ’: )*'’…n½Ñ�´ÝNã=ñÎ ª2(™g$ëTRŸvì©JÁEyìú ,…³PU�£§ŒvÑ­ª*Øô_Õ&ŸOK²,³'dÕžjðöAã] ë$C¤úÔŽ… yƒ¥*C0>dÓjøÆaý–ºûªsœs.ß“ç?›goËÒ·¥úl•• µ5©ž°ª\§£?ˆº‚ GQdým–Š}’*“l‡¾ÅjbUWôL娙P±¶7×¥:ðÈí7qôPWSPnMÚx:øVåXRukð `¥i5©†° ½:ñEgH¡Q6/ŸOì7õzÝH}ÐýTB¦»lƒ <ٷͳU•¯R§ÔAYËý}.€øú: –Õ.´®~ËÓ­Ü6.¦Š1k} »Q1\žv…ƒÁ€Èä#©­þªªºÝîMkK2zÎhùËA„ÃÙ7Íæ<(Öi{ʾž~Œº¶8ÑÝñ(jê_E‘50¼)}Ð0¦=WÌ-*·ÂN†E”6†ˆ‹ª¶0«onÕ(SñyÅjôòo×2ý­…Ûîê_o4»ÎØ5 ŽüèHö캦r 7ì¯õºÔZIÏ#ÕÀ¦ÝB@åøs3®<£¬¿½>+W9çj÷Öj÷ÖV^»ROëÉ(ÑÔ„‹I`Í£èÒ²G: Ä‘Yk)@Í¡D,x\ü½Jzs ÚêÑ~Å\ÑäP³6±L&-˜äB]×â žçæ`ÁR›‘ZF(áX[qö$Uç—¯¶JÈ›Êä«Õw€*DÁ�=@_öME¨ÑWíàPÄ ©š\Ï›!gcBÝ9ú:ʃ3FßÊmšÃ$ –#ƒ¥l‚Oû+*IbÛ�pÙ‰°•Nõ«N°2A9U9YðE¦»Þn·Í˜¢ÌòÉeÿýôæôÔKNÍó|tÊháã ñuqíok®»N-”=oìÛn·Ë·èHÇ=.#Šhw@@àQXððX:®d­;2 © v1:ƒ­•}¬íùIñ^º ŽÐãÄW¹R=5´]ßÿPêâ©f«ùŒg<ãe/{ÙáÇ¿ò•¯ÜyçÁ›‚Þ_ô’×$$br¥ž˜¿5Št“ÙF¯–®^j=»•‡c‚œa˜Î¹ô•iéWL댡=X;n Nd-yõ †â·*<áÙpè“y²`_ý~ß.%ž·8¾•cmÅh£Ñ Eê ZÔG敞ŸÚQ§j §<x¦ªõµžLu«G³}šéU¢¼g=�¿”‡cŸÀô•Šk€ h‹—ù M쨘9 L¢—ik/x3âªl·Í³‘Q‡<Z=rX‘”&žø®bnº½‘oFµF–ž6øµ{¤ÑqµBÁâ¡|:ÛIÁÖâìì,³58rÚ§uþ°³í·¶Õõ0 £(ŠŽEÛÿŸíKïZŠž%7&,qv‚= kŠì °OF"¾,ËN§f÷š#ÆÎ,ûO6Þa(ý*=‰xt6ÓÇ=ò4´3Ò§/*¯�׈CÁëF(“Ê­>à¢(r‹¢hûöí]tÑ/þâ/ÎÍÍÝ}÷Ý÷Þ{o“’1>´yCŒ´ÿªB™Ú§»cz†¦÷̪�¨áQsq0)ˆ¯ä]nÓŽ$»ÈÉqUÈö Y¹úå¨ö½t-+õ<U05ƒAs´Ý8°.uš‰3¥w{­Ý_ZÁ³³4„x²oìJ²=íbê|aI]çU_N™ p_ñ‚Sr„;nUùÍ#yz"ê;î6Í 6|.V±gø¤“N:~ü¸¡@UU v8øÝAáRØþ½¶Nb{F�J뢨}Q2zEíˆÌ“U)÷X‰*ÊK[t�ÐöÛüü¼ýCÓü°Òj8^6H¿™ºžkO·gff²,[^^.Š¢ùùfïò^óŽfÞÏéZ3ª£( ^U¦î#rò(©AF¨Uˆšh:f¸ ni;ürælÔæÎ2ßq~]>ªâ*¸7¨ÿqÝ­—áíP5ªScIJÔã»,Ën·{ß}÷íÛ·ïá‡>tèúÿ:Œeá_)‹*î æÜØ£iyD»Û&võäUŠ&oʤÐyaÆÑ£P'j•ûîÔk.¾C@_Y×òXNçY)0«ÎU*ågúCªdªà„!˱žÛ*sD»úvµ,™3ÓFšõ %‘ëf´ªÈCðX¢ä.,-{/”ÎêÆäé\¨Í<U† 4Œ€Z«ÕºÝn¿ß§X)Q<ÿ1àÏæ3‚7œ‰ný€¡E…Á`P5«î'ºáÃaûÛEYT³ÕÒuKñ§ãô©9m¤ãň§†FlQ´‚ö¢ˆ2ÄtD_aYô”Ð.dƒ“ΤPìCòóòÖõ­ÙÖìÅ_üÌg>óÈ‘#Ÿýìg:T»³¶tÞRéJe1(@AàÚÖ°Á¦R~¸am`þöØ{ó8IËêìÿ~¶ª§ªºgae×$¨¸nj¢1A_£1»ÄME¯&®ÑWA_MLbŒ\¢‰D"PÌ�À™af˜ašžîéÚëÙ~œêo_u7ïïO;òéþÃÎôT=Ë}Ÿûœë\çºúý~–eaºµnôšQ~Aîý J?œg‡iBãöƒ‰Jº» HD‡Fݯw“ë’©LE1<~ع®S»´_W®ªUмÄßcK{ ŠbžEQÔ/®w>ØqowW]uÕwÞÙëõvîÜ9ï´.jUÑ-M¥tø\cœÅ5›=$õ¶[nþ~søwÃæï7¡iØOÿýô¢”Ü\eâÀ‘,2z¬šËkëˆuhåÚ:ˆXàW6Õ´ÜfFmëtãt§+œ¬¨a”‘^oìLm¶qQÒÀm}šÁ`€~ÙßÂ?góŽ·É"™E%�€T°g9V»ž¡ª-ñ¨çøã©7  ‘²,¨ùX·ØÛs¸z"«GΊÍåX½où‚Ò+³,Û»w¯mÝÎg:µ?©%{“¢( tÎÕžUËÿw>:{]¡l®0Œzyé°N‚·P5þžLô`4«Õ ¬œì*û}£*° LkµZ'tÒÉ'Ÿ¼~ýúV«¥­W ñfÊ¢~ ö! ‹0jàõomÛ£¤‰j²…'{bÊâÒ<¼p�� �IDAT­ª*;7^8L¾4Îj”g•ÅÙÅ®…ä/’âò"ª"õæÑm¬†Çj½Ý:§5N3Ë ž‰ƒ¿ †o/†ý0¼5 ok·Ö‚A`»©{yT@äÛÇ@Êa…ù9ù¾Û÷µïjEÑ?ª_UD»#·ßynf`ë¡UÏMj’êE†áîÐ Ýè¬Qò“ÄísÎ¹êØª8¡p3.ÜÚX¥r—¤åŽX~:ɯÅ05_·4¥V«­_¿Þ9733c]/¶˜ŽøXa1ÔjŒµª(+0ïr¡)]-‡36âìêíÀ5µ5�÷]Ûòæ’®bÕˆöjeFÞ®MÉå^Ãf¾…¸G³AQߨ¢ž70ÒføšŒ wØÕ¦•Ðh4¨qIølÎôg½‹ó9rˆéC½þʸæxFÜĽØSˆoŠƒgÁA0•Ò4%Œª³U”rÒ@lht^‘!z’Ï^Hõ„ÚœŒL»E'>fJ0‹¾õNë=rû#7Þxc»Ý~à|ðÁ ²³²ÆM  �L,…xmý$ñã¤ÁܳõÇdóãÆ¨R4ƒ?¤ÏIÝY.¿8×…UQÕ/­g¿ŸU® ?¢#éõó=r×’Ÿæù®þÝ:h{îòꪲUÆ?Š«ÙªùÉfþŒ|ô¢Q~Z^¿¬Î¿2àÑ¢ d*8Š1Z÷«úûjð«÷ ®ŠªªŠZ¦aýmu¬…‰°ªÜc½%#—+W^}]u „0ýX:zýhxæ°UAiPÕ«ô/RÈ~J)Ô¹.èTæ•Îöc¨¡ÚÀªFãÔSOuÎÝ~ûí<òˆ×ÝAÚ™u‹gŒÞ—ª¼¨‡ìraC…¶À÷ØŒÜ$N; 2u™RtÆÑ“ÕYfµà{õ•A{c¬‚¨2 "t¼RÿJXÕ£ÒCWõO™¢#,Ðmõ4È=§DM]=rV¸—£rXz(¹yø¬amK-é&ET˜¸úÜÜ\’$ÕõUï¢^ÚJ«á8B‘ø«5fæ”Ò0´µH­ð !%LÓ4V‹å´(I—žçytMÔ»¨×ÿ‡þ~ô£{ï½·ÛíZÔ{AoúÛÓAho@Ý'u"Oã°¾šŽxZ>D%•Ôµ[¾eXÿH½xjQ{Aí¨G­ÿÚú]Ûwõûýø;qÿsýÊUµËkÞ‹£ !*!-㜽lÔülÓ….MÓc=ö@ïÀÎíœ>º,ËÎuòeðƒ ù~Òÿ~?ù¿ ÿŠËÖ¤Ä-êÜX‰qå]e}K½|v¸Ê%[’dg¢›ß«U\—œÔúê¶0˜M?áaã=쌬ÜX†Qn ãŸÄEQ¸`©wHZC^ùžo!R«v²´J4ÀÇÖÞÎ`0èv»ê}Ž\‹Ð"¸ÎœRßx"uZÚÒH×ù-îõz ÖqÙ*VFždäQS•l‡[¡:: êP¥37zXÚ~WJ**ìANÊ,Ë SŸ-§Õ'D "ŪVìQD¨ï—²d©Û”e¾ÚËùŸÒËq“R»J‡wÎqQ¥fdK[7p.˜pÇ"ûPô¡– ýo½^o6›Ýn—²åÊù sV ¾¶ªÆÁÞ°Ñ 'ö£ÚH`qO¿qzîŸæú?|MùÏåsšk}µý(*ÊBuÌ8±¬³­©Óræ…N¹Zè±DØ6¹1Ç`šá¶›Ÿ™×?WÏŸ•¯Ö¿:~õñ¿uüg?ûÙ{î¹'ùaÒKzù)y½YOª„1ä2="Ö„±BUÖâZ³ÙÜ´iÓµ|íÔë§ÈòÒ4µ¾Èô…Ó½ÏôZohƒ¼p£$7ÝÉZ}6ok.Ù¹qŽ@ªr¸uЄ°×JB¥]=i‰øÖ˜„vÑ:à¢ýp–+€¶Rœs­Vk0Ðòá‡È>ï¾ûnóæ±×m Øš‘6)‚�ߨ…¯a€BŒÖ2 ‹¼8Ž-ªÕjžS¸:%*oESIû"†ñ\ x³àØJÐøN ¿ûé÷ûìYú˜'ûòžaghgÅ3äÖþ–öö¸rû:5׿º$$N<jüºzä¬p•2K{@YLaÆÄ££²V–ƒRÙ2å eø`˜”I^抹¡F£ c\ݘ ÄoØ>‹6ÛœÔ+¶«Õ@ÝÉé _2v®©¥NÕåçS/™rç¸ÙϺÊEE‡˜M½ð@”*ª£|v³Ífsýúõý~vvVçŸЖ/ÈÛÆ.’ª¢z|å.pÑGœõ@¯×k·Ûcz÷Î0¾6îýf/¸dŒJó²,Y²iÜ\ô¸¢ŸD£M£øÎ¸Ûí^wÝu³Ϧ{Ò¼ÊãÓâ©SOzÒ“vìØÑív£G¢rÃÒÉJe¦uh sô¨¼º™hh—§´(58°Gjºd¬@' FŠü(µO׈ã@@^Ý ]Û=ɱa(tÍÏÏ£¦¡Ò/j½ÃAõÎn¢ö-vÔ©¾ƒN2ZÏœàà©lb±…{½ì�e7(:­ÿKT¤RÒ R+ ž§Ý>ö(œ¨ui)Ç­µoWQÁå3=ÞØ¬É¦Ù£ §M2eÐ)âº*x³ò…•2†Ú÷:ç≇ŸWÑžÈÚ¶Vúôã«c7¿„?k´†ÞõHknÑ#Y…èavª•ñb©Q±Á“*ºEý¥'Á—ót ©?â8®ÝRküZc ‹»’SólèÀÖ6ˆS«ÕÒ4=ꨣöïßokÀ»*Õqap„ 8xÌc¤ñ_âì•™sîàÁƒ×]w]£Ñ·L/%_M´Úà U¸OwÔ¸I{y­wC/ü·°×ë…aXVãc¯ó —oØ·oßfX9f £ä¼JZ®Å«½}ì$¹`Mvy¦4«Ç¨àhd}A‚¦çüh_G#ZKaÒd&Z<tý_˜NºH }ðW^fÏXééŠtq#|¬Ú![(75 åó•ªÊ`#»äé6*kyÕ•ZûhA©ͼA#¼qÞn¤* ®¥ýùXKTˆ6¨()A¯ðQ© Z*ì¦=i {“£QeO½zîQy˜«GÎ �kc¡õE£O(X:,–|4üå Ú…sî7¼|Xý¨ªÝQÓu`ûJÉÄl6/x-—Qb‚x€Æ,'Ù¥Ú!äI¤¨Œ•ê9j§ƒ ÞZ$3²Ý­¡tÞŒ¡·}ûv›DQ¼R¦ZmÚ ¸•#ºsÆŒÞ/%ƒ{ÑMQ–eív;Ïsó̽nÔ|]sô‚‘Â)ä›Ô"–×SY¬¯¿»Þþ\;ü°þ¹zôΨ÷…žs.º)êü¤Óiwìí þ|PûÀDàfÔÃ3‰PpÒm9{¶V`†D‹EYËnqºSç<T Î=bìÚ.l+…4uzQñ"ÍÇ=uQ±…3©}{wQf¡ÌUAýÔAkPUË%ã1Ö2k@%ÔtúDG¸¬fR·*Ö”<«‘-‡›£ÜeqÅØW‰9öM¸|LY‹º‘éB*ô­ž{:Ǧ¥µrº2j c¹ÆX®TC SUúÐÉ9±Þ°Ôꑳ¤5TœuÆE‰ñíñô{¦³Ó²Þz®rá|˜þaZÍWU»*‚ÂÓïSæ>4dRêéÉ÷Lår5¦/BTbÊÚ“/Ôü2«2j8V5L#ÈÈÂ/ á<œv»mÞîQ‡6a§¬9²N«Ù½O¿jºý¥v~qî>ïºawá™ ý?é§LƒÃ‚àÜ ñöÆ(@‘)Tµit”ÇÛÔÓÒÁóë;UU…ݰñ®F¸+ {á0FÓQ¸&ÌŸœ7onFµšƒi®py4ä9ûy­*Ô¨µnC†b©¨šª6x4-'#¢*… sÄÚäÓÒœ—«^öäqð†míÀp“×°PcB{›¯r–ŠªÁy3Ó&ÃŽ–[¦²„ÐÜøµ#–Ö rŠà±ã,RSa0QäMVÙ{áCtÊXQnKœz¨èëÇ–õ¨FWW™]Uª¤=s œaÁigI¡å‚Ü<g­cæ/ŸšZ=rVæ¼i¦òJ êLת%{“5W­Ñu¹ÐП'Ö°ŽÉ'öÒØ ÑÓÐUE²ŒŽ§ž^꣓ù”öŒ£š !ؽ®`MǼhšFÓZ'"PöÙI`dtÏkÜá¸#l¼®1ø›Aÿ]ýäú$º!jœÕ¨ž^åO̓mA>—+~å&ª<œz *º°ÚUÅÿ§ÿ”EQ<©è¿·]…ÛüÈËÓËâÌ¢qaÃ-š�Yukõ 1™K´¼Á³ë±ÿ¦EA@!«Õ ±¿8UP&½r&u€ƒyFJ-O5Ìy„+åŒÙ‹ÖHÏ4õ¦Â°$U& Þ£7!Ïî0�V{û^Ž¥µn%OVCe>ôU6&ÏõUN_ãå ÷ãEë\³6Þõ2<z};ê”nÀbP`Ó2BˆfK¯šåäYƒ{ÓâNØÉAmüÈ´½íÍÚÁó³^èüÌÓx¯l9V ”ÆÚ~Ð-­#Šªñ J†v§§@.RJ‰›ÔñTþa2¨êÝzÔ[åø* ×J%×RæÑ§I¦«ä»š$zýI"/>¨`A::JÑ㜠6õ?©Ï.¢ ru—¿#¯‚ªœ-›k†ñúöȇ؉®êA¶«mŸÏO‚ÆâåEùô2rQòäõñVQ.\ÊÖ•§èé…()V£-¡ÖH´©*—�®¢M8Õ'Ö:c¹Ÿ7µßV m; KñÄT­G™W miyíÄ혒¡¦:¸Æ5£_ 4ñå†4°H,>R¦+WXñv +Và¾ïÎæ»u> Jím< yåsª–‡W(zi›'Ì[šÆ§JJ«×bNZÆéä“òË• ÈN‡lBóÿ2Üz 0¤;Àu�@-Vf§½µèÄ\„¡nrŲÕ,^Ë Û®ªã½v<>¨×4k´Ñó’’ß9755e €Ž7#­ü]BôÓå£&S¹bAøË u*à Õˆoˆ“ï%Å‹Š*®Â0Œo‰³½YP †ÕÌcjÊ©l^¥E˜Nc¸ïß“àÊÅ¢!ƒ0ŠûÛ{W{SU…PgÆ¢(lØÛÚÖ@æe1d£d-Â8 Ô:–z¹ž£—ù²ºhxøÀmHº¯Ð³QûTýQC -°t0 ‘5‡%CgãÐhÑCZEðà‚ÛWF#ƒ‰|a_ШÓ6˜[ ô¥ì½t»]´Ï&e™4ºØÔÂJK »^î• &XÚ¡áEWsÍš5µZmÿþýL…CÈVÉD•ƒ²O¶ q?÷LCTÚJk}õvr“®ªV¾zä¬X•£ƒ8$Ζ’hVÈÞ³`äÎxb:„¡Q^K+>ŸΦ2 UÆÔeôÚZ‰¦+OÁ °'’Æ*À¥Ô2ø ÄnwrbÚÍnW>h¡ýŽÑ1¼…æœ(Ê ‚ ¾6æÙºÄåyÞívrWѶ(Óþºñ”…špšÄz¥•si>[«ÕN:餅……|<MA·(ýÂd¸]˜Îó˰ ŽM#´ìÖÙ '¶1$4–Ê(+„' ³ ò†B,jãÀ|¥:(ÎM lë ¥®Iú¤ÛÁQ§0”r…ùj$ÞÕàC«4»Yúó†#AkŽã¸ÙlfYf¬EeùsGh-×n7ú�¯ºTšç)üÁ™gžyøá‡_}õÕû÷ïçyÚN§.dS�uºIUã/hDd�Óó¶˜6«ì?< #GE SÄVw+áUÝy¡ô[¯Òâ8£0„Qº÷8$jȾaN&¸­ËeÖ¼F!ü~tªŽÉvz–×+ÌM¯X³`kêŠ$ZÕ¡…ìDÙŽR`íiÛ_1¤¢ÔU婼+9ùd臭<Q¯Ôî½7ÌÈcwç9þz l(ܽ{7`‹rç`Óê¤c¬#‡<jd,] BzT57iDÆÂñÚ¯¥- Ýššž_­"3”§4Õ9Ïl ؇ë„F«ˆDPܨ†&wÊÔƒ–¦½²6œhXh‡œ®Õh42XØ-ŠßxvAÐ÷9à=r 0LNüîxAJ˾í¶ÛLã™´#mÐÒ-s‹ƒ½LصىK÷W•®€Ê™Ú†«ÈÖëõ”ð¶JXá*GI2D ¯GIA/ÁŽLÓÕ ?'Ôj°HÏS¿Nso … /Š ¤f_Í1C/Çö°Bž2[êíáD~ÉRl újMOG¹£>@š¯W./»È.É›‰ñŽ'3}ž´aΓ±Â®ÑçVðG¿Îcâú³,›››sË4•Õû€æ–òò½IOÚÕ¾=WEOÂ_�äT§^®>E†Õ¤4ÕÎ�jh")§Ž=:íÍxz0F¦R5gyÚœp±4'QÆ?KTK ºMÔ˜0Ù½˜H¹¦ÿª GqãUQh4h­F]屫µåDœ{ffF¡föT³vÅ´=˜Äüçææ–\u†O=928Ñæ–ttwu.gåçr´TgAØ£ü%¶½Š#8CS„Ò8BýDUàOú¿|¨P}qÔÉʉO"Uü¡Žì-— &˜Úæ¯ÕjëÖ­k·Û&ƒ V§PUÇIõ­U£Á6Ôæ'Ü<ýãÓå§ÞÒó‰ÍÌK¡R„¯am�Õ­Ò“I›˜è££©«Vójý‚? X¹èU@O ñvã–"x³SZh¢�äõ‹·CUb¢Æeb5–uÎ5wQ3LÕ˜ÀWz.oG5» A¨x‡Çÿ¤M…Ü2½C�j&§dHµzóÚ„žõƒ¢[I’XóÒ,d SéªÐaUŶTLÀMÓ5+ìì{ °u2¬C*µŽn^’¦5p>a ðdÔIH _˜µZíCét:<ò1籯=Fª– »d7¶^à a~XÞÿdßÎ9×ü£fõPΆž§šë|™í=Ý*Þá§Vª’ þl^ó¸Ã>ÕQ˜ŠjI¶+Ž?üpÒ7Ä+•qgOi0Ø×ÂÕÓ‘þ9Cædå: H.FOE9 †pzVóȰ« ¨ªtk÷ƒn,4iEÓo¶‰þD)y<á~¿o a-QÇQ¶1ç°×£6-Ä/…L9D9¿íè…r¢‰½e» yÌsxø›5±ÁB î*á9N.ggØ-ó &Rê£}‹:¸;Ñ'3£´‡c8¦r>>sXüqQ¹*|(lýy+š’^ÂõÛ—ª1.[@G†Ãá`0 î{dq–¢Ù¶”î¯þ4:NK‡IE­´áï ‹x¨»*Œ, >M&v$» ÒŽÃÑ¢¥x( iqàÀÜáFÔª|õÈYÉBÇö›Í¦(ŸxIâ÷„lø;âUL=oÊVFÿ²¾ëºôÒdG¢É;Jxµ&dª‹´ËÓê0L€ËPµG†•åMP4é©*Œ¦ó:¶Íî»ï>¦O4UÔ^‹E1ûqbÅañBٷ˹œ(jµb›Ö�N)½jG€~>°\ÛT­-=¥Ný‡ª#Â~æ•Aÿ¥m‹I³š¦xÒÝÌNºI³Kzàèó–õ°¤ÕƒÖ³Š@•c[)Žž…Çžò\TZRÊ}GÑÈ x‹\¯Vq¡z½n:¶`Gª€P>³üö ¹=i>¿Y–eõøjøÑauK•|6‰Æ´ñ©PyûZ¾çy¾°° Ãȶ;8áXùJà¯�]ÙwØÿhKOy ª˜&´L†L-¡áÛÙ©i»ÞMZÇêEê^Ö„U¥;t]ö«UÎÊŸ7ên«ÙCTʲ¼t~/lü{£rãØ”^”æ/ɳWdî¯' kIë¬ÝèDOuyÔ/Öqµ _nà¨ú}„iúÆ$€nÒ`A—©…$õÖTÅ\-ÛùsEùA{<b´oZy­r‹l¼‰…%€»ÇV*Bݺ£t}#Èj7ž¡¾cÓ_â¶¾®ÌOȃ ® ÊK%éªèˆ ÑëË"¸¨f0æž zââÊæ§äµô™žBöQO\ˆs|¾Ê)¡I¡x¯698Þ€a©¿I èùéõ»E=4ÈuØtßÚMþWRë×Â(L’$Û›5~³Ñy_§<±t·L¨·Ù=ô¤óL§tI=Ü”­Ã‡{d¢%Ó©E6â«Þ0§²j-*qÚˆ2,´3ʵynCœUü­‹*°­ð‰{LøåüÌ—iÊôPê:ÐDù eÐâ›bòDCÂ[Â*¬²Ó²åkQ÷¶îXŒžàa*¥,¨>žR:X„Æek`ÀOC-S^d̵l×S‡ª\1FÒaÝ¢@|J"RŽç7ì!‡ÊB¦k¢½bÁùCË[áïÙ¶áÿÒ°'iN [sˆÂ\PùQŒ¬ÈÖµ§aÅ¥ŠfO+z_ïU*¹9 ÿ+ÌÏÎûÿÚ¯¦Æe¼G­ZØç*ßË’˜§ÑƒsìgºX±©@ÃCåꑬ0'-Š®³º“içL5ýx¿žœ—}/W®g�‹Jg€l†I'yU(ûõ,ú—(%¨¡ûLå¯ÏËxÂëŒwDÆ£tUbWòíÚl¦ <�Ã@6&³GNôO1D tð ð\àt0À&¢ºÛ´›Õƒ‡?QE(…¯ Ðãò ,âþ©ý]KWÕþGôrœsîñ.®ÇY–EDÉ(¡Qœçy¸!,\‘ìO‚(8âˆ#Ö¯_ÿàƒÎÏÏG¢",ÜaNç=!H ´ ôW+k4NGpUJW^&˜²ú‚“Ù)IÔ<(íIo—›PåÏ{ÏêåoÌsñCñÚ÷¬­Vq<,¢ø¡›”JTr’ô`Cè”�¯-zoÔÉká¦i ¦¡¦÷<UíTiNgmýƒÀ *ÙßÚgªYžçµcjý?ì7ßÐŒºQeYFÿ•õrøåaë—Z<jäÕ*˜Y•ðÎc-„Zæ¨ì™Û¬ ÑÉТ~ˆö\U»n B¥M»hËÕ¦98ó–ËÀ(¥E‡èzìA☠Ãpp ý^–a\;î¸f³¹eË–ápn Ë'–•«\µÄWTd »9Ý•œú]ðÔ•‹H›??3-‚sëׯϲ¬ÓéÐ2ä†ñ¬PºH0Y¡'½uÝ¢FƒæHéÀ,8¡}5\VM|ù+^=rVæÈ)N(‚SƒìÅ™[ãʲLnMªUtezCQEÑ!‡òä'?¹Ûí.,,¨RŽ7Oªª±Ê#qv‹þç h>î±b4kÖÙë£PJkjAˆHÇRì²ùqœzn5øÍA|K¼ö…kƒ ¨Ž®¾÷`zWºþ+ë‹™åyMüAáÔ’øëE_`‘Ù¿Åo[[¦^ˆ°›íF2�%ÿð”8G1€±ÍŒ^€êqG©r 4^ÆÀçŸ6 nª™ªŠÆÆhA/ˆzQ¸5,Ÿ^†·L8ë¨Ð/äoÂ×õ $7òq£NØAË ZB/M§aÔëZ×¥¡rÕTLõQ�¾t8_áAV—J¸ªe®0ê°\æ•‚‰2ni¨ r†"t»]cm°0ʲ,³qþ®V1j ¨µ}8ª–òL>(E…«r¢ã±IU.ÁÄÔ™ìõG¥’z:™`ÛœÙ>–1¶Ù¼G-Ô†/Vª*«à‡Aøp¨þ^XçY# ò·ªñ*J±zä¬Ð‘sLU¾¦Œóxíûׯãn·;:o4:i½>J¿ŽOŽmUqF‘Ÿ˜Û‚]»víß¿ßʑꤪȋtçØã’±|•‡TFðm¼‘ [ʤ{8/)Ë?Q@v ‘…¶³º¸k¢±ƒgÿpáÏZ¯j…ý0ˆ‚8Žƒ}Aí÷j XÈÏ“¹6MXX¢Q¤)bívòËZìÛçè ‰Î`s‘ìsåPèÊ¢ _¤ÞqËI *À cBSÈÑ›Gç6‚0ÃÐØ}ûöí˲¬þÉzÿÝýtsêDËmGOEëûXÅŽ‘ʘ@»ÈÈr;Š&üO¥E¯d¶~ìÌÖ?‡G­Ãƒb|DAZˆyê¯AIçÅG…ãTƒÒ^´½¨aŽð¾[=ŠoŒ«Qµwï^š4£sGɵITEáp Õ�T,zfº)”í öå&U£ø}•S‚ž <7ë.,,Ø6D1 œ¤%(=+Ž@•þ$uÎeÏÉòççåÁ2¨‚0 ‡Oº¾k|¬á©íñ-jö£îgÿçgüÈy|•½.«vT g/Ô·Ö›ïj×ÕæªóOøaû7rÙ Y¼5îõzý~<ñw|æ Wl+ªp<®L±¯1щÀ»ÆqN´@Ø~nÒ”štÆkÆBžáw4eSnR:Û¨ùïä¯6â<v¡›ššJÓÔ çýçCçÞ8wø^OêkÖ¬i·Û&]ev¶-Rx­ÕDXÞLš(7* º2ª%£pŸÏ=*eË3§RS�„ø‡ÚkEôzéÔwãVD³Ù<ÿüó‡Ãá•W^9??¯"˜Zu±·Ó453!EN¨‰iòCͰ„Ã9ò,k=•<O.“yu¥HhEÇBB}QÇ?’]€'¾NE6€òÂrƒgUÍQûAò2¾1¾m˜¤‰11 åƒç ¢¯GU^é´58'e«È‰&4 OI"Š S•òçªê 93ñ£È!†FœÁz̽â¾A¥âÄ,˜»(O+ÝY.¼>¬)F8�� �IDATßT†AÅ)Åèñ£þÛûÍ¿n"@¢^õ�*ž˜÷*}`~v¸/¾¤õõÖé:ý?~ç;O}gõÃ*ÿµ¼ì–õOÖGïÑØO/O‹gotÊãË⸢<¾ìükgxÖ0¾t¼Euõ0â`»z’:JäJÑ›{°O0tÈ·§!lÝC«4Ìé$¶“œÓêŘ鴩*·—ë¦×yä‘OúÓ_øÂŽaèíá踬0+­€h†gRƪÕ@šmÛè+ÀÞ†”“½JÂN°Ãï}{”2�Yvkv„ ÇyžÚ¤ N (•Ž<”Æoç®»îº÷Þ{M¾<¬Œg—RK{›½^*¼µÊ!2`üeOÉøÍN¤}ìf­ÌUKut=) 7…nÊ)¹€[ã2³Ì&/!ϰš[]3PüÔ|¿(¹Ñ]°ÚQ8`='Fj Bê‘j ˜­¡¬Â ¦_7ÝÿrøáavL6:z”=3[øî‚û± ¸”- ¬RužÈJS-+{2J²ðæCutÉKqhmêïkQˆš8/¶³¶fí$°U:u¿¨ud’&åñ¥;èj7Ô¢,2Õ¸äî$º9ªŽ¯Êµ%m6O™I'Õ¨þWoVòçîÃ;‡Oþì“_ö«/{Íù¯i4ÇÞxì»ïÝ3?šÉ‹|Ð07ç ¾# ÖÝK»¶¦§~{*ŸÉƒ â Cv;ÙŸ¢önQ.‰AE׳ZAg`µ)±")´# [ÆSÄÂõ™Ö¨ÎxG•U„ív»,Ëx`ïÞ½Fê/˲rU…¡ {½ΛžÿóCZU(Ÿ•¢‡Þ&ãnÒüÔš½ê÷EM¦ÛªZ¦Œm…ãÕ÷žtXtJI±f*y€Í75»ŸèÖ~µÖétn»í6$Sûî¯}áÚ*¨œ¸¬’Ô«Ja6 ÜjPSЯ|b9<m˜“•­Ò9þ0¬vUõ«ëJÛãÓ(ÔÈßY~Z ©Ç„ª½)�»D§>6¯Î¨dsYøÝP[˜ê—¡ý Ð5ÀÕoW3SE>ã8.:EóüfùÌrø®aåªh_4uÎT–ee8!ª+Änß}¥?¯ùœv2t°ÆÓ}W\Aáåþqïª/ .s:È©´{æF¡$€}APBÇÑaQÿ7úW4\ìÖ­[·iÓ¦ªª¶oß^Ηîk®ó›ôÿ¤ê‘¡ºÔ`˜˜.>¦AVœ¯¸¯¼Ê½ê}ÕûªªZ»vm«Õªªª×ë%_M†¯V7VQ)#(Žãxg¿ž½ëƒJc¨†Q%ÎÛûÆË¶V«MMMõz=í‚hF¦dko"Ï›©¤ÃêD?ƒªœ?$Š)ï–´¨,Ëèê¨xQÑÛÜ+ŠÁ`` l½^ïÛKÿ#­ò*¬…Ö³µøÇq¯×s2uèùˆ(9GÝ?•ßéÉLñ¸4%uõÔñÝÑs”ãe9‹;@s:ÛÄ¥ fOi*e{—ËèÖ(ÿ@ž|>É·çιìYqv‘~!õ¦¡e+«BEÕTc‚ZÐÉP°á‡ãÏ9®]0ªÚUã`>pÎeçgå‰åèðQü1Ò8Ü‚¥ÕFC% o,—ÓVy1shiøÂ;‚AöBçœ;ÆUgWñ×ãø¿c0½»ÊeâáÍÿ3Êy yÜߺ¥ 7/’õƒ‚9G®Y¡'7éäÄœZ6x2J×D³ƒ¶?lR¢?g6ã5Š«¹ òw@¸ªjÁl©7iÇ3äôõø¶e6lØpÎ9çÌÌÌìÙ³g~~^iJ¸×;T©O:Ô­9?ퟫÝÕoroZâúK_iUU³³³›7o¾òÊ+Üz ÷Ÿ½ðˆ°qiƒ6 I]CìaÕ=·õÔøm;rÈ!/~ñ‹ï½÷Þ›o¾Y º : hG 7PãH]Õ™�Ê?§À×ÓÅM–Òà­ýW­ýŽöT:UöKëâX´ûÌîÔ¿MåY¸qE¢Õ*lã±o=?5wX®5Y]þ¹§ ;€É uvÑ‹ v¦ž²ª†ç¼ýcPœsA;ˆþ.ªN©²?ÌFO9çÂÂä;IíæšŠ®j§Äß“¡ ˈ�AÊb8˲|CîZ®ñÁFEa–e+.~PŒþq”|.Ñ J"š^ÝF”¤ÎSupÏ÷Å>­û‘nýëõrwnÃ0 ×…£§Œ²WeÉBRî(é…8ëSQQõÒæ'MS'ã¨ðìÊU†ÃK¶XröjÆeÁEY~~„A|u|:ðæ½Ü¢8‚’´çªíŠúj­iïÈÓ-åtW…º°ä@œÂw·ÇÕh4x&�ŒÁyîéŒF£»îºëá‡>xð`QEY 6íD½Â«D‡ô4 VœŸ~*<­vZyL¹·³÷†Í7|þï?¿cÇŽþÚ~U«Ê Ì·.ÅAí·+1Ìs\·ÿÛï÷mU)fyÜÁƒoºé¦v»mëU)¹ÄYËh¼yþz½Ž]®›ptÎ ƒ4M!Dz’”DOµBñ�çÜô«§ÛÿÒN~œ¤ÿe?>oÿe»õ÷­äŽòL½^çT4C¤‚FºØ÷¦iʽ@éѶ³[&ã­à¡UZʾ£Ç ‚U5ÍïÔHôÈ#ܸqã¶mÛ¬¶Ó wιÚB­¼±¬ý¨fO”GÁ(Pÿ.²K2‰nͯ¹\aJõ¸RÑt4xÛ ùšfUUFcãÆNgff¦˜+j[Ëþ<Kþ:ÑFç½E8Ú¹Eý$ “t=ã#§Ó‘ƒÁ <2,W4nlTUe·vÂè{Qþü¼8®p÷:oÖ{lx"dÖµBŽl¹Ô¬ š¡ÑàY© ÿh4*žWdïÉj—×Z¯kAP¼¤XøîBü¿ãôû©§ª‹G·¿¢pð `zl@»/À dÓèÞ¹Eõ)•7Tžª)K±°Už™0Ó »Åw’àï‚ÁÛ­¶öìÙc†oyž—G”£ÿ5j½¡â‚»¼'¢¹”ªM¯9?ÕŸg¸gÜänzÊ?eæK3yõGŽÛuÜì³;ù…¹»ÕÅ¿‡‹mi[Áô]Tû°ˆ…¨òÉxÏÀSì÷ûÛ¶mÓ–ƒ’¬<Â+îèX©Y‹Òc ?iбœˆtR Ý¢Žº1ÃN8uþTþŒ¼÷¶žs.z(ÚðÒ yž[¸± i¤J�‘Juâ!fn[Yü" P-ôH€6ÍäšòYyÂv̘lQhNϺÉÁ9íi¬[·Ž\Ò{¶H?ðóöb(¬JUÑ×AµO�‹tZ…Á ˜rvüLMMõûýN§3æ›D«»8ÃzxÈ!‡œqÆÛ¶m›u•Ë{yq[ªA-eÁK )L¹H5¶q"DkÄÎÈÁŸ â÷Ž‹ÂuëÖµZ­”e™þUÚ»¡—~'5^kÀ›ìñb:I ”5údÁÀ'fSªèY†Ù{²éçO#H“!o]ÑêÞÐ Ÿ¿¤È§}e�ÒMáwtéjCщó40ƒ~,0¬Ý2 RÁm»S×®oNFn[­–ßUY•;ËòçËÁ/êß®çý¼ªªüYyu\Þ½BåÌU-Iž àkb·zäüT.t>Í=í2wYòŸIôhïë÷Vë«pM4ƒÚ{ka.OŸÝ¤Gýri[shëÂ,à2DnCBª§‚VNxÿ1h‰m—šK˜ÒÙ:È žÃ":nÒåe<ºqS\ÿa}œ6&”¤èFëH Ä‹Å& ­šÇn™)§rç¼) -W¢X!i82í±˜Ç«6V\0ø$qvÿþý333+èPŽ[tH"@�ÄSÔÒ‰O�+Æbt>ßRuäpìÃÕ<´ªªÀø1w:{ï½wïÞ½ä:Eµ´ µ£¦lÄ`¼É ¢¡ÄiÌŒ“’pìœV¯×O=õÔÓO?ý›ßüæý÷ßÏ·Õ¥Äõ°P%ru"вUåæ¼éHE® ^Þ0¨}ºæœkµZëׯŸŸŸ7ÆWtY4¼p˜|*KÔq%ÛT'úF8¥'$3Ðq1•Ò@rFÏ-mVÏÖø›r)Q Êó|jjêÐC™™Û[ÜEµ(Vž¿5ó•åþ2ýdêBÁôôtUUNGÇ5år‹j~žšÉê‘óSý¹Ì]öÆ'¿±ÿ»ýøSqò…¤xJ1øà ù|’<œ$iÂêÄ V‡ÉÙ@L:i¬7Œ€hqMVEnNÏоNàøL¾‚£ æ mdZ8#I Q¯“Á�}ÃÜá_¡í¦ˆŸý! zZ®Ažfs*/K]fa†áMh:ˆãD—ACŒELõ7âYÒmNbÚæeZEA<ýEö¸RxŽ.ã¬Û᪙¬q-ËQz½žb¹nàÒ+Òò÷Ëê3Õp8ܱcǘ¡>]e¯Ìê®Ó~çá3ÈCÚ¯%jŠ¡l+47ƒ Ȭ*«²(­Ó¹mÛ¶v»=n¨¸%"¢r®H#4G+#jÃØÔf¾¶5‚?ªëG~A>uþÔºuëÎ:ë¬g>ó™·Ür˵×^;??ï¾â†ßÆ—ÇÚ™§5¢5¥×·èyã- Ð~ö¨¡l^†¨t´TMnƒé8J= õ±µK5è;I’Á`°oß><°Ã0Œo«Û*w¦s©s•sw¹úBÝÚ{I’¬]»6I’~¿¯NŒišâ¸C§,’Õ#ç§ýs¦;ó’­—¼¤ó’Á÷7ˆ¶DÍ_m–½Ò97,‡N4\תã ÚØP tâ:Œ:l[»\–/I–Šaôµk‚˜ º#ª¿b«Ð´m<Çu6!q°V«YΨR(v³Fc£ÀR“ÅÖ4ú˜v b‚:è �=ÞV 0Ú/؆&¿Î9È…8€*«1S9Tç‘)"W˶g¦Ê|“„à^·Hj(ò$Wc8¯‹Znò𔿋Q)Q#®âd[Òi?|Rع¯c´±âÈ¢ÜPUì ŠrÜH°°Z°F^¢‡7"]ªoM Ç®¿­Þ½²ŸF£{î¹gÛ¶mvdv?Ú­ÿq=˲4M=âµgF§*±Üøub” Z”AØa¨(í’éFÔjµ£>ú…/|ái§V«Õî¸ãŽ^¯”Aæ2¥¢hßÈ>gOZëåa¬)GŠ„jïj^9žap7i?ˆl¶¢è¶[Ó4U<“�»Ó^¯‡g«i0fY6ø¯Á’Ãl¼Ô˜46Rd{§è`²yâÕ#g~e£vE-ùçu¿Ð…a´dUé&ÝeÐÔ)=xœ8¢{JÕ{fÙ2‘Ñè/xÚø©ÇµPår‰¶˜Ù´ØMÇ^ 9àð˜p!ü.!J 6‘gS¦6̪¥<Z¥Ky"=8ZÖëu#d{„.6?ÕzŽÊ»ÕW ž"*‹©­W”„TÍ…š�.2/š”ê¶Äu!éL¾ÖÁûIãYÑÚhðæAðƒ DQ§yš×ÿ ,΀ÚÊ!¼Ú½+ê¥ræ Õ"I@'¹qΣ"º.*_[–;Ëò¶2˲ðˆ°:· n¿óð(B¹MÈÂà21Yr)u:giB÷‹–’áv/¬ºðš°ûÜî7?pã7.,,lÞ¼yÿþýeYVçUá,Q¶l©xÞ€ZÜ¿#Žãééén·‹…–8Ð.T?PÙn4\Õ)ÇMzý©('a­VÛ°aC¯×›u¢ÓªÈ­bŒnÑŠ‰ 8Ÿe™ “*yÚ£0¬9+ü¢­­BO"Lø­V¥Äñä˜ÔÐ*§NÞi~¤ €,)±''Œ´G ×¯öT­,à²i,kXqb/ÆEÒ¼¡€†›jí`‘ 6í-hí]S%è¡ÐøxlxŽ4ûMÏçFùp„ܤ<š wzÝ cUZ»ÊK!lycC^kJѪ0 £Dè8´zv“¦ñwâè?¢âuEuXåWÿ\½¶­&!â4ßÑGÔå¡j4Z_ªš¸¶(—sî½Îý‰+ŸP.8ç‚Qî ãŽkûk.]JÅ´;‹³,þIOzÒî»ï>my*79—ª0¬>Ûªª‚÷ƒÍƒ…,|ç;ßÙ¼yóÜÜœ €öÞÚkžÝ4)<{£fÔÿËþx…(.)=ûÄn·kšð€ îk~Ãj7Ii%¸+”ÚsTnBý~ßþ›í†Z•m ªFÍ)I’4Á`@!HÎDé¯óÈËÅãWœøÑÄDyMJ\f£Z1Õ#ÿxÌ>„• nkmXånÑí\ÞèÓÏ×1CŽIÛ why¤é¼A.Úc†âÀciz”$‹\vÁl?Î (¨èü6aQû̆à!ha"MS”% fñüâ0XÔ,ÒMJ,#ŽÌ¥“j‡Œ>4Ïh‡æ“25È£µ’SqÎx´x±è’PQ"‚¾BQ¹/,¼ã#³ñ¬ØÔ.…®¸òæµ£‡A_iµËkå†rtô(N⤟¸»²,Ã$T—R¤Í9oðÏ>pà€ð&æjÅ] ‘¸—*qíMeÁ{ Ã0ýXÚ¾º}"›»j.˲ꗪá [—µ\0†¬—û÷˳ʩO‡sð‰Aô`Ôx{CYp̉ù…YS#ÚºÕ Fé0Úßb;Hë9à ƒ 6ÌÍÍñ–Ï®ª=ºDöEÝn—} {lM»¤Š!¯9+\âh¹�FäuØt¢ÐÃÖTØc‹:qFÑ)qà5¦T%ÉÖ¢Ú<k/ƒkZܘ²hfÐ1R Ó±V«™š›d#*9Q>æˆj6›¶”{½ž]†ñ’aÐazMÝó Pjƒ6¨ì®™l5K!æŸtf]/;®ì�ã4²‹ÑØD5æ®JkÚfÐm§¬ÍfÓ¨ÚÑç4Í â8d$ã³ÙÌoÐZbpÙ9Ÿxƒ*ß Lv%U±<¬³eí@&H€é8¿U„TyM”æ¤ θ}.~(¶YT“öQ¡¼F£¡Ý,mhåy¾k×.[Øp•Ù¨Šæzâª"‘›œ–ÇW©^¯ß*’o'ý?ì÷ßÒ¯\U¿º¾æWÖTƒj˜ á¤äy^þA<Ô^Q‹Â(Ïó ÒÛÒꬪûŽnüîöÒAЍ[ 2¶3ÕÌpGfm`Hçah3|ÈËbðªv¥vôz=» –¸¡´Zé'qðx&ëËç“Vœ8uH? Àâ@¶‹ômQeCÞUK ‘D"jÏLèVÍ%5xQX(iØ-:SA„AöDè–q”QìH¡gû«F£¡s'žîŽI³˜%ìcõP¡ Fpa¾Á4:u@Ú‚ôd ÁK¦P€ÍŒ§ƒ^¼½pìŸX¬Ä1]NšùÌœªÈ&7¨(7«@i&erjž)2 Ok‡rA«F]ºö$•ǯ 4í;På])$öÌíŒäEè‰Käò<,ì€WÝXûX* Q~¥ù‡�¨ùQÛ_é5§IÝG“ÿL&Ó©ÑhÝ(¸#ˆ‹8/ǃ2qWûª2(£'DÑž¾Œª±JÉ~€V`Ñ_·ÏŸ‚É’×qÛ0`iѲU±{÷nm³ÑgµAýH9îXã(!BYvzêP⬒¤WX[žQR[5TKŸ-MF£tLÍôÝä £'BCJ¢Löɸ¶ðáv%­èh ª9°cɵmxŽÂ|”Gv`„ˆ’Îb0—Nù¨°Îax zdf¨ö8_Õú®,h˜‡Ìðx96¼6šðŠTxG»ýØi¤ÆÕDRKi5sU†ª«=°.3xeÚSÑ‘R»` ²8û�:‘åÇÜA¡T¥ÆjªËª£øƒQÂ൯µ¡%¶)¿tøIß·¨ì…jzÞN”x”ÁL§šœ…vLÚ3©×ë½ã{ÕaUýÖz^äõz}ýúõÃá°ÓéDÛ¢¼—§ñî˜BÝ6jGèÔ©ªÀy³Ü+„^ º¢JU¾‰snnnNZ:ФÓÄ*ø«H%)+ÇV2ä=,'ÔÅqõÈY±S&’-,K܈þž1"íOK„­ ~©:¢[ÀÁÊÜ%ëW¨Âr&º ßÕüE´4~i5æd¦Í+À o¢Ètp ÖÉÔK-•wàͬhÙ¤3tüC¯á°¤¢"}ÖÓEÁF楚ͦ…f½�;¨0 ¢ÙÅÃ*Ö6Å%¾{F–èTjÔ`b k=ɼÅãI|eà; L‚þŠŠõYŠmwÁ7úª3" óêa¬Å«:x\ ‚8FÙ°çšmש] &V)o““ŒÒJUÔ(v,Ó§­… Z~x 1{¡£rdÿÑjµ6mÚ´oß>óóUQNEÇŒÿIûŸÛ®rι֫[ÅL¡ %ëPiÍ^Ίæ:ÛV±M­590¸®‡E˜f³©ÁJÝÿ´sC:å][¼¥ÕQЕ?oò<Ž Ü‘îàGŽGäÞ•D»£bGá±™œPE}Ž|£möPÐz'Ö�g‘Ó „·}Τ£Ý: ž£¬‡±Çâ"5Àª%âÐl°›µ|ß6–e'œpÂÔÔÔÎ;ûý¾Uýê嬢ÚÜ8i@ü%µ @ùe_‹<®ñ+‹G¶3¹#,a£Êã‘JUÒj,TµÝX÷KÉWvïžn yº­ {°½Uš“CK³Q8‡ y<Ä º 0œRˆ`¢$¤Ã[6ú‡þ 傉Köû} /ÂÙúxz±[©^ËpŽmšÇMª[Úwé ³Òøä*éCE»á²ÛcaTS3qO˜Ž4‡NPìjØÙ|Œ‚j]å¸~¿÷Ýw[›pTAQëÕHÑ7ÊÉFï ŽL¿d:‚ÊU W,DF4Ї ¶¿)òy¨†zÄ=YÏœÊ+#Ë1d ¹:¬Œ«@0WŠrpW[ ™ö¦8×qeUÌyõÈY¡ŸŸsùkr·Ö¥ÏI[­V–e½wö†aøå°þ㺛TÇO¯<²¸cò…jzá&çÕu&Ɖl½ ö …ÒŠáûWDIªÔQò‚wÊêõ(HÝh�O 5ØïÜÿý›6m:餓úýþ<ÐívõÉp*óànylÑåÝc횀Pú»IidK�•ÑË^"riÎk›ßˆÝölɸÁ%t“zJ|qRj²·Zx¿F5«e:º—§mJ;Ò„6?Tø@S´£’*úêAŸ´�Rr-ŒloÓB6D ¯G øc…Žæ[J¨ciéCího_çLõ ³ã²á³‡Î9wÀÅWÆú·*æ=æ4ÞgÏÍòóòô«)<õ¢(Â3Ã`]7†»rUþ^™|+i}·e(\»ÝN^𝠆¯&ÿ'ÃÉÒU ›A=EþC‡xdZêÕ«ÝAND¯• £•4׉ œ–ªäbƒ?ÓûgûÀ ‚ |~Þ6ÞÒ Å®ÿU½~m½øåB'ÕÕMV`SϋӢì<Ð.qGçuHµQD·É5ÚSìH'üQ䥵®!˜ 0`MMÛt“_Ãív»Û·oä‘G¦§§=ôPº/´4Çnµ׬qÁž’FsÚªFïñT]Mÿƒ&*€¡UQúÍÏ›×gÇŒò�9eujÇš±nrâÕvµN³*žËËR–ïèãhTU+$WUØØ»�Õ}PªÕ¤­fWé�¹IÝn;©B´ðõLÄÑ·E=–#p8š/ˆ¯æ‘ºÉñOð:”{4X›D÷ÝìµYU«²0+Ž)— ògæ<=ºhI’ÇqíÆZ¾)ソG/6û‹lôüQð€òŒìĬ ªúÖú1Çóò—¿ü¼óÎ;ꨣêõz¼%®’ª<±ô tð‹,AÍñÜ2ÏuJLeè[Sj¥MÞð^€ëÙþªÌ&BfHjþ*°¶ò?å)eðà ùJR–åÆm’ ÏóäŽ$;=<g_[çVIj£ $/ ܃«*c˜^´Š* ¡†’žÕ¼gßd«ß¦¾ñüÞ5áRç]›h_òlâ¨1¸´=ðÀ?ü°~…}QÆö3ãŸ(ÙÀ÷ì hiš¢q§v¬çÆ•Sz³¢ À}ô¥µ›¢²7´ÙÕšÚ²~Ëy½ø¨Tâ,O@it†Oö/ï.ò ynÓMJ+cžZòÑÊ_·Ê‰£‘“¶yùA[ðž¡“¡iõ¬SÕaXû4Vð—d�²†Uá–ùp«rnÃO ƒÏÑL”>”æyîš.?1Ï~5 „Å=Ki\£Ñ¨×ë­Vk4ÍÎΆ? £/DÙáYïúÞ T®j|¨‘oËã{ãÒ•èÃÚýæÇäa®_û‹¿ù‹¯|å+;Nš¦W^yew_·l”îhWm­´ÚÐeÉYb+„ÀC’ݤI ˜$ûÁo=]x­¬jo*ƒ~’"ɚĬÎå¬t/gªªjUp ØpĆ‹.º(‚+®¸bÇŽùÁ<,ÃbÝ’Ö="T¶¤4 O$ÂÚ‚3J>\xÈÄÄ ú¢d `ÊãŒûXWYô>Ô:¾¿Vn+k÷×,Ò1D 4S-hèjRj¨PŠ[ô©µÐfEÚ¸¹E2Ûö·¦¿À¯¹Is6¢Ì» NF«Sýu,8âæ‰·ÄYoÈ  :å°ÜYÇ9×l6Éý¹<ë�i9‚¥:Sx»×^+AGE»ô·=ËTç\yt9xÿ X¦_4íœ êAûúvp]PÿX=˜_¢`ØKa|–§<k8M°‡©€(¯ôû}æ”iÃ耤g{\ �� �IDATÁ¢2”êAgOŒA"ò¡Oɳ@Ì0²áÒЮ(ŒœsÃÇ՚*¹#©u땎Fámað¼ |RÜ=±Þ0°ÅÜßÕ/ï-[ÏoU®ªª* £2+£di¦¸Ûš7N Ó¬Þ‹•.¨uÇQ‚†Î™ÙÒ‚¹Ç›”TÉè¦ü ó²%= 'Î5Näâuj)ÀÇ€KÛc±fëûî»ïÎóüÀê(Ì^"Äâ)Ø­ÛLS{ÛZÚRvˆÕ'‚êä*{U¬ Òç¦vNôþ¬çÎrå7ËòÖR©t�¾4=1( 'E‚ßÌA1ŒsˆÖ±ÊRQ¡+ÚMN³[Œ¶@OE“eÝ6–rê€ ·@|ät¤:!õ# ЪatIñ7xÔŽF:E§çfæqXɸzBJœEŠM=+¹ÁÁ[ñâxKœ¤Éh4*:Eóìf~Q^½¤ ¿ê'sT³õ2œXzÔ&õ/P| „ÍS€åŒ÷ÌåʤfE¨c¿€ÌV@+™˜¾ ’ úkö Cûãˆù–*ýÛ4ÓN8áÔSOݳgÏæÍ›G£Qí#µþ÷úÍo6õ  ´Š‡{ü‚¦¥uqçæù/äók篼òÊ™™™N§sóÍ7·ÛíáÆa9*ë×]à<z•¥ ϱÇYóª6䵦<þŒ;ò�S…ª£Q¬=OØ[W ŽÖ®V9ÿ:Q;Ãð@X<µ˜¿cþª«®*ŠÂÀ‹M…k¹èލ *ÏÎYs£Š¹«h {žÄ_c™RQa1-)-žSÅ÷Åõ+ê£p<Ý~0Íž•å¯Èã[c¯i©sŽ| 6ÏÕíjjj*I’ÙÙY¸•Ö}Ñ+ŽãC=´×ë™`‰Aj8å¸e#±ŒÑs MkÂðlÙx†cÃGù Å(,>B†VœJgn´[ Sh¹;¤f4–&RÅ·8äˆ8€ ‰Î*ñ]ðÜ´4Y’VzváîsÉÃIœŒ«a›3nˆ² ²úãêåCÚ©È18Ñ]õÄÑÄd<H%y€áþÙMáßEŦH,¤AnÊ*läbÉ ”­ »J'»IÉ{ôuìáSËR- Z­Ö™gžùò—¿|ÇŽ[·nÝ·oŸ¾kf ô 6ÀYÁdv.šîVÕeY涸à¥AñsÅöÿؾoß¾²,mñW§Ua6v6ÊziDGýÞªªzêÓ…s.ühì4%%©‚øCí®ðƒ'£¥2ܧCÐC]YézP©eѪyÁJ9ûà¸]ù£rnnn\Te¹±,“2¼?dPX"Ô»I9BOÜL'6Ô3ƒ¿Uu;‚`¸iX]¦—¦ÀYèÕ·ÔGÏ•/*Ý5ÎËR‰ *ª„y’$ÇsŒ%ƒv¾Z»Xu»æN§cò´p윌û5$Iz½ž}/Svö·*ïdv•â†8®™šŽ‹j™¥Ã:êôNR¿|UýÇt˜IaRÅÓÙ´4rù}¨ê4l‘ˆ7±’‚X$*‹Ê}UUÕIU4Õji3=ùä“˲¼ë®»ÚívõßUþGytX<xjßê%ªæ~ž”©†—ñpx{Ó‹d$:”J«†Ö sž™´òD¼#yó[8)\œoŽÕñ%U®¬Êáp¸{÷îmÛ¶mݺu¬N8 © ¯¬o‚Ç:Iý~ß@]aòè‹ÑàƒáoóWåAd£lôï£ð°öþ%…aö.ìå¯Î“7'EVDQÔÿ‹~åªúoÔhQH�Ñ1j=L¨(Š4M ¤@ÑDGu„É”) £BzºpJ­Êz®<ª}2ýÅhøíaã*¨²<½c펚7-hê¦Ç¿òÚøêD æ`z,¡–TH¦ jµZÙ(ËZ9Ú;Ê‚ìçþçO9å”-[¶Ü}÷ÝÅBäAµ®ŠÂFEÏh2¡úEïš³íá‡6zž�bh\Šm¿¿iÓ¦8Ž·lÙâÙŽEQtÄGzè¡÷ÝwŸý>Îí ó£øXû·èÃ/s�ëÑõ!†’ù¢¤â9ÎÙ1ày`š`NV°]u˜Ü>ÍÚTöWœg4f(ë )1jƒ<¶RË É1Y<ØäEQ”EYÅã÷¸óÏ??Ïó={ö,,,8ç¢0†Q¹ä&gÌcC«t>‰…ŠJíÉîp¶‡IUgþ¿L|Ô×Åpˆãy8Ú?A°ð^ð[vU——鳘°Žß¾3_Þ|óÍwÞyçüü|·Û­Õjƒ Ò7¥ZZ)S™KcÉF¸ôÀÓrp4E{¢æ5ËCËÞw{öQÓLG£,Ë W¨´Z­Vþò0J¢ÚY5ÂBó·›Õ)UïS½Ú…5æ¿¡ê,— œ/$–{”E­‘€²Àb7bðÒ·(ÚŸk[=rV†$†aò¾¤þÑzï=W¹(Šš5ãq–gÒ$Ñ2z˜® % WÒàQ]q'Ú_¤Ì¤?ãä® ~{ì±§Ÿ~º±“ƒ ¨ÂÊ#G±R=+½xÐçÁ``W¨ê¢^³ÉgûÀ¹¹9÷,Ërnnn4u»]„p8§ÕñÐóhp¢³@(WQMT=˜5Ò)é<yi·ÌÇžïÕYEU¢ö‚­Ó£ÊPsqEóTûG}'õ“U[“—mÊg–µÇÕÚíö7¾ñ,Ë8Çqùse´7 ÆE›Æ#Wñ„sh°!€OÖ¬íI½;2 oCúâ´'¤Ð®G„Sµ›ô½)¥PÍSË 5¨ëŽ«6øµAqoÑþ^;˲êªAßÍ87ã¼ ®õìtâ˧í+þ*š¦_0mgj.ònƒ È[yvTßë?Ïó<ž‹ãýqð” ¼³Ô·£iŸWå3±K¯ñdlàÌ˧Ül_ƒœk&ëä10‘ó©rÆËh4ßÒdì¿p…‚ãÌ~“ªx–'ªéiÅ»ÂØnªS½W:½8<Þ“äçîÙ.¼%¼ãŽ;~øá}ûö ƒò‰e9]Æ?Œ½[  gmy¾¹cœáåeÿÜ~åªð¶°þÙ:É—Ò(éÓàX3ö¿ÕN‚K»Ý>xð aú (je�:2Pª›¢³Üÿ/•=¥k…> b-U.Ï®‡ÖŽ|¡±ª{’µÔe•³SÇÔTÛ¾ÿO_mŽó_Ë{ÎqåíåÖ­[­£PUUöÜ,ÞG3QVfÐÞÈåy”h”_VÊX×Ì�—²¡Üâ,º½ #e¨¢3jÖÇòìq`#~jKšêŠáVªX%dëp˜R@‡Uñ(‚úeõðµavF–½*+ËÒu]´%Š¿Ç{b>ŠRÔøP_<A$u£1Õà©{xWÅcI2F‡ŒªSªè’¨¨ŠV«•¦é`0èõzŃ…Ûî²ggÉ–DÀö”X–œåöc³D´£<8דaÕÞž".z´Ãã×™5UY=rVò‡Þ5Z¶ØšŒ;í&YÓq Ï7… ĉ§¶ØÔñ”†-öÁ|P<¡p7»Ý»wÏηC»rcéê.ØäeοU3võ…cYGQt¿Ü­]U«ÿm=˲ìÔ,».küY£v[…HA¦äµ6�'$ƒŸ ëAyÉŒ³¨±ŠŽ@z“ЫˆLÞ�Í«@ú=ιÃ;¬ßï<xÐ#¡é´¿²§8ó,DÛfœs,>ÃåÖsd FtÔ¬\uOtK…òô!L]2µí’måyetaTUÐ ºWuãëãè˘ }ÚÝöá*Af˜Ø–nx£ŽqðßZD*‡PUç Ð*„ªÆátïPêDV[ñ^×ÝMÚÀ”eY¿¢­‰òyY–y;Ov%”e`z:©þ¿U!ÆæÜ¤oºº xpÆ ¢ž"ÏyÎs6nÜxíµ×¶Ûm­¥ÔÇ][/š ©k"à(Uk.K·¢ÛP9«œ¦À­€¢É~õÈY¡XìÑÑ„ ˰® É©¨¯°ªîëRÓH¤…­j�CÂA}|&ýC0¸x]Åo;®†áèÍ£`oм¸Y¸Âû@‹20qÈ·Ø/ ¿<lœÕ¨×ëöE£»FÑ—£Î7:Éo$a;Ô^4›TTƒ‚ê5ñkºÁjD}ËŒÜ5}f3x ,a×Y¥Æ©’ؽµ¦þÿ»£J ¶¶Šò�Á5?@ß?Q=1ï—UoQÏ]ª(»/Ä,w•ÑQ±©h«]UU­sZeYfEEQ³Ù<ÔÔž°¾ª=~§^¯«ºšwjêÊÔ…­Ù€¶*µªÖQh SÉ ˆ|ê¢ ê¨FZ—S<Áé à/°.|$ŒÃ8*"ϸO›ªÀkÍ º…ö;Ü©Ýäx¬sÎPbe6û‚Y4:0*,ë³uS ŸŸÃÐ5]ÖÌÂ}!&¼v؃0«”¢KÙ†Šã8MÓ 6<ôÐC–ªZÊk=3‚†"“°×H€”4kh-Lõ [=rVì‡AtKص÷1”‰bm<(þã&=ÕuâÇËà�‘=zO¯×s¢qbK¿yI³üxÙ{_ÏbDýëñì‰0ì�0/QE/çÜðEÃè[QE6l8üðÃgfföìÙS–eôïÑàŃô+)ž• P I«'…ÂÔ:(œ oؽ¨Ê™…xêW‚5p¶Adž«pðFؽ ÆŸæz�L</z…F¹ >Çúà*>©g-qP-ûœh%x9Š',=Öµªôî`͋׌Ãt²„Ú[œ‚7ˆ2‚y7ê?¾‘‘ I„µþ[Ž[zš9!ÂDÀ¥êÂáBe•±°—®(<ºÉÙ^j2þ‰–ïÚc³ø«$IMÿéš(æ ‹/-/W}ÜuE‰\íp8¬î¯Â„ÃWÝenûöí¨•ǔũEü©8J"íÚrm¶„˜ Òf°½ñÑhÔétЪ1 Qü)(á€ÇXƒaK åDÏÞ+ÙWœ Àê´ ‹€d 6§6ÀUÂÏ-ŽOz ?¸¹²«µ‘�óØ£NŽ{§YY¿¸¾ä˜,m Å”âåá~eYf¿›µþ°uä‘GžwÞyO{ÚÓî¸ãޝ}ík³³³égÒîõÝæ¿4¹;,Qîƒçkâµë÷ôlàRkBƒõì.W”�°§"…Ž¡M màNp^›„¢®£ ÀG§ê@áy†¬û˜‡gö–†9v„pÐÖ´µlठ¥hvìõÀYŸv³žkY»}o¿çÞ¤h”*­ X�dàÆ”kL§Ú£Rß)eQ+Ÿÿ¶Ò!3¶?XÍÊȽתó nÒMœ¤ŠË£&«Ý^ËOÉŸÄo'‚ƒ7ªUúÅ´rKi y3LNüˆÕ#Yùùy]-‹©Ë8±Åöy³¾Yšžãê\ÎJæˆÍ‘†~UÙr2?ì?¼ŒLMnRZXi”9cäW £Jeñdµo¯9µÊœ¨›“t)¦¦¦N;ñ´_ú¥_zâŸøøÇ?~ëÖ­·Þzk–e½ §Ñ“¥W/Õât¢`OÁ0 )Ýx·LFg-5'EÃÍMÎujó“ ì!œUýVUP †o_8tÎ%ÿ–Ô?]F¾¹€Î¨È&©Î²hëv8ÜY³k£ Æ?´Ö~_­!àP‰3ì�jèp*ŽI‰ v‡½©Å£åÔÊ!E°³œ@Ïy![çùWv¨×p´ÓŒ!-`¢f¹Wô«•²Öµ^u¨ÄÊ;µD3ÁÔB�‹Ó:ψãÿj_ÅyÇÉÇN~*Œþu¡ªW®rч£æ•Íj[Ô&Hê¸KÄq|ðàA¦Aµdä8‡kàUWTlL/è–g®™òr)vÐj•³ÂŒµ¥¹<Qg5@~_~®@ˆbS¤êv®¸³~)ûMgÍÝM\Û-à…È'@0wiÚɪ»ª…£|ðÁíÛ·'Irçw>ôÐCyž÷ŸÐ¯¶TÝnׂü%J –)áÒæ=•xÃ/«bÝè&ÝÀ Em‰b*«¥2ëmÂIùF Õ롪ª*Š£á/{¿Õk\Úh¾§éœË~9ëü[§õÉVüí±b&Ê»*FÀ)NO^yzÜȸO6‚œhÊ¨B £tpn®×ëö¥nåvódpy0ìWmд»i&sƒybè@DÖ’±5¨dýJðe¨ (H$mtY”z·Ê‰=³ ,ñ i¼û@ƒ­?'ÚTº¯¡°T˜ôBRU°_ÕLš¨g‚j5uÞÔ�[M8|Ûm©z½>==mÛ:( ožxB¦8žŠ"½kþÜ0j¤m ;Ï€œSjµÊYù¹fø-MCÜ…$A_;È/´WL¨æTlKåíè'[e£D&Éé¦2²cñȉã¬VK$SZ–Ù­ÕßYï}¯wßKïûâ¿xÄGìÚµk÷îÝyžþzPM='¬Õt7aìx„ÛÉd²:ÃíU…§ ®êÙÉ7zMl: :Ó€¨ Í|:ÀnZ¥+{¿×k<¯AM–~3 ¾tЭ¾Q)Ȧ¯@/Ue6d¯”Ëâä5öu쟨§ Ná¦Ñ¢GŽ>uŠóf“µì&o`y°Â•t΋³ó@¹ܸ‡«8)!WP=q©¬2À@ Édð[û+sõâuîDZB)lj±,$1äËTbGE ùv]?œêá«´Fu¬ç]xSnÚr³ßo·Û¦Ó¡’Z·Ñ›QtT bh~š¦öð^ïÀ~l¬=€5E‡—óæ®=LV{ JOÒ Ãó `k©Œ¹š°©Š"k ¬_zˆt:¦:Ç:‚ÊÆ¨º~àcî¼úÎßݹ°°ŸžÞ0J¾D£È…KšÖZ18ñ–ב{«fVFÅEè 9ëô(‚ðßè‚>ê‘£fVc“.1¢W H±ZÅdoÏÒ¥�ëô’ttñ¨þѺݤĤgõ­BÑË%´É'<ð“_¦£KßKa%u`1 |§„Î!b±×”BÖ̤!Ý¤ß ñ—EÈÔ¡¢‹nQ¯…Ⱦ%MSKVö¹z·Së„9±f ýâfuué‚Ñ9\Þ5©˜6:8¬ä}hPüUU{¸xKqø_V¯Q]4óÓI#mpÒ<ÓÁ 01ä9œiJÇV¦6wjò%ÝQ­¹åƒjd°z䬨y£Æ…LNX°S¯wbTÍìTQŠh‰êLMÈõÌ#'R/g­ìFdÿ•5§Zžƒ ¿·ý_é·ÿ´]EíŽZëÿ¶ÊûËÄ%ÃjH¸ácQíóJÓ¸ªU£j”„I­¬ñ·¶è5ÜëTš éb¬Ù àÉøHSzÑŒËèÌ„§A cÌ`êIÁàEƒÚ{kAlܸñ„NØ·oߎ;Š¢H®K†o—LšTS"vkê¾¥jlÚê×ÃUeèÍ}““R4«5FÅ�;ªüFÈ9gÜYîÚèmyž§iš$ɺuëN>ùämÛ¶íÙ³`Så…Àx¹6U€|a5 j˜:2bGšÎTzBpœR–Ì)}€(ÞEF‚Ú4Ä}¶¥Ål–rFTI–Ò„“I“ ­õÔ„âaU.˜Œm³ÑHcJ©+:@&¡µ¬e $y\’ý­Á°VU‡IÛuNLUHS<éÇÂ(¨›4{&=· ì¹ÃÒ¨Ð.¥=|$O(Œ8eÓÚNÆ×u« ®h;V' a»Y\0Ö¤O »†ì#b ÇqX†Õ½Uðá úhÔëõ 9,ó²Ÿ÷Ý¢È?Šg 6cÍÊçºáiÃì¥YUUÙÙûœ+·–ÍN3MÓвöj‚&D2 ‡¼Éf)”ƪ½Í×¼o!qS•IMô¬ÕqÄGœ{î¹›7o¾ï¾ûÆCy•ó´™ 1ЏjŸŒ~¾öóP,ÕBéIL{hVAJŒÃžrjjÊÎ-¼¼4™d‚Cía·è`m˲Ûíò0±žc¡.ض¯6!W<RéÁØãµ;‚‡©ýjmÅóµZÍd–”v„Åï] í}±)¥œ©­8ìyò' Sš%ûÀã-RoÙ4M‘ïSW­Š”ÓᕈQÛ¾¶¥K[ë`?5eF—<•R¥÷¦+MÅ3 ¹*¨ÜšU`mEO¯ƒ¢h}ËqøÓ¤ÀÊ„aþ™î®§HáÄFL¥‘™´G;„£H-X hÆPåhF0ÕΧ̸ÉIo'#Ùc”ãUEuFÝM½tª,Ëàè {a7xZþSØŸí{F2vñø¨ò-–£©ù››ôÙdòo+{tŒ¹Ñúâx¦L´ Æt­êøj_« _9 ¿ÞsÏ=½^ovvÖ.oø+Ãø_c�wîÝMêeqžÙC¶0áMw:Ñž!ÇT-JÏ=Ó"©]¹ÝµQ¿E c.©Ð«»õ”vðàÁ-[¶¨µ¥äÆ'„GvŒe€Rfð¿q“Nçœ.h¤ª‘U¯ªÿ¹E?’wÅд ã±I•.O¶A/J‹ij û"+ÎÔ²Þ„z§R(óZÕxF“BíqRfaE¨5Yð5nܬ:îNÛ¥:Ö¦öðD «8Qa›W3þÒ³ƒÁ)ƒòÈÒ.‚+Ö_±Ím{½{ýꑳ2?(zR+YáQ¸�Z¢jPùlª¬î)NêØ)!ì¾ Ò° ²Q-©˜‘y+/¿¶àž¦) <Êœf› 8uÞT9*«¨Š¢¨Ü]NÿåtçÒN¹±Œç–JÚóP ïÒ”þT0óþ{Sï˜JÏäCƒ¡\Ç}TñPC-XŠvJÆ%Χkíoµ_jt»Ý­[·.AóoÈ[ç´L ¸\;yŒïéD§gV¦ôtOõÒ>g¹V©e*ô _ i¯8Z£†¢öÌANäè ñiZÒÒ Æ•“ôoySYzñ,{ïé•=È)«Ú.äªõ cšç)=O1[˜uãlP2ˆæ:Ú†ÑÚEuÀ$•Qâ„{Âhêp£p%nßÌèØW€Úi‰©²N@Aôq¾)í%{j–Ÿ™—ÛËú§êIApøÓïoìÿû› Ý…«GÎ T9Г–3:4X+ �Šˆ%&Ú„P +϶Keõ,ŸeÁQñ½Ànšø¨š‹ «gPÿ¨¼)®MG5ÝP’ÂøÃÿ|4õñ©8ˆË¸4°Î`ëÖ[wj¯­)]ÇâŽ!{p‹“$ Ò`þ­ó£Ÿ­¹x=“¹OÍE;£Ö»ZÁhÂÒ[ ZªêDÊЉ—2”ˆÅÊ ùÑfï{½úÇëÁ•«Ê_,¿7Hß™ºe†.„TÏôÁû|å“X(.¯£…ôÃíÕSÄ0i« lCoh XǤ•£ÂÓâ š®F¿6¼vàœ‹6GÍ5«nUå~ÉXª(¿Nu`•‹¹};ëGe4µ%£"§^ì󶝨cU)Wby'þ§gyG©jžªóUË~HŒ´è÷D€€L‘dåókpÜ=N¥®yÖ‡3V·úØ’©‰ `%¦¥‰mtÂÚ‰…•J§çe>:z”´“äëI­Vk4ÃáðEîEÓnúwÉo¹ßª¹Úê‘óÓþ1 (ÝR*ÛÒV?¯œ‰ ÛW¸µ«Çš:!z›3Ãn4d/géhU{›¤iÚ1R¶(è3Gâ|µ8ÓüÎŽ±ñÉtDÞyQ«Õ¦¦¦;ì°ÙÙÙùùù葨:bBqÙlHHÃÉ|³,\8¨ßQo½»Eö}èk¾`Øs¿ñÁ†eÙ°ìTÆ«½@ü”2¤T=Vm”uzzºøNÑüVsô§£ìЬªªä›IëœV’$.q`enQJÄäF°Œ$–©ðÔ EP=g{{ÎøÓÀÖñ{.mh‘F‘v&,ÌÙµ¡[¡-qø²aæÏÏGo¥W¤k_¶6˲ÁS/t¢/EÁ烰UvÌM t2áäDŸÛ-·£ F³ÝR ",ìüápxÊêY#³fkhzÉM€ßåP6‰šâÁ<sĤI¼¤D«gHÕÒï÷í^l’A­Wµº²Ì€-ÆÁ©„û@†¾•ñ ï�ÊCZö|T·Ér¸f³9{½S\qimžàÜK]ò;I’&'tÒžð„mÛ¶%Ir²;ù9î9ŸqŸ¹È]´zäüT˜,ó<”ÔxÉÀfq­rÂ`TKb„2G©QÈYC$ìàØð:ö¡è„R€T+Ú6�·çŒ©=|R?`hÅ|õßêäPQ®3ÓLï+Ïóª¬lôÕîËŽdö05_uLU$E¶%K‚Ä·z½^EµÝµá©Ãâøb°k àa8lWàuíð¼8¤ˆã¸ÕjmذÁ®<¹4I.+ —ÑÛ0‡S‹:’).¤5¢NÔ+É›G Ξçùp8l6›d Æ+ã¦èöq%Î ƒôû}, ²osÃÿ=œ~þôôôô¦7-,,ì¾}wüòxá« é¿§ÅLAóYun™Ä²Wm+´¥ÞÔ0Ùž4”´ÊÉá´ ‹¡,ËüYyùÔÒ9n £«#5]æ5ytg݉Õ~œš%xȘÊÓòš8_‹¢h4zPé°y!犎à "àYÝ@г·©=0n”úŠŸÚ× ¬*«²,§¦¦^ö²—~úé×\süVµ8r´ãʲvË̯ÕFŒÑ€/*á¢ÕIaa>¸Š °yœÈ)ê<“é<>f‹-Yê0•Î%ˆ`¢Ηz†=¶¸ë_¬^?hÞÞ ªÀŒ«ÇòV¿5J>›,C“snÁ%×�� �IDATE ^EQÇA+H·¥­éÖI'tØa‡Ý}÷Ý333î^”Aqb‘îNÉà4²«1¶ªÿòîtn‘ÚN»;Trúl•¿ í x_NDÆhwiY@çÕUPä …vGªSg‘×â5¿\†æ Ör£ØÕáP}àœ7ÙŸfSŸš:üðßö´§{î¹ívûk_ûÚÖ­[—6†“·' ™C¢Ô›Ò×µ§^d$¬['‚¶ÔéÕ‰-›:µÓ±HÓ4‚ÞT¯ÿ¡~tOßW®ÊŸ˜gÿ˜¥JË»JíD¢ëã–éÆªJž€ž€]rËV¶ZÑ�7ÒV‡s•‚¬-}tá1 €Š8›%Ë`’Œ·­CQeûø¥ òx§ŽýG¿ß¿çž{æçç·nݪ@Èꑳ2ÜhMc•B¦]*tš~T?J3&¥mfÃ'®iš©bÚãu"ËÈ¢Q;Š˜Ë\˜Uúû@6Œ¦E&Ή¢Yªý¤¯ñœùƒÁµ µ¢Sd,Žãa1¬ÖTå©eò·‰'¯ÉII" ìÌÊjÜÊ:ýôÓ?þø¹¹¹™™™²,˪ŒÃØc7ØX\VëFõβ8Ε«è5‚(Šúýþ®]»¬¤CÓƒÎßÁsS†4Öp6jíØwÄq/vÙ†¥ØßÚ)Òh4Œ nÕT Z€Zµsö ¨þØMÍ?wþ¿:äŒ3Îxík_{ú駃v»Ýn·g~<³÷}{ ¸#E€p¯ðôte¦0ÈBï|̉Aw W˜ }K:‘ìl6›'tR’$ßÿ³ï7ÞÚ„ÅlaY/“«’ÁûÍßmƒ@âìŸ+%`ͽ¨£ ”qE\Ùh¥«p8ä îìæ¬Ù€ðEíݱ,A<5’ΈK:ƒ¬<=7©A§3:ܵž@v÷»èúhôë£Îç;×\s¡)Ãáp›Ûv‹»åƒîƒ«GÎ T9^Z¡…*/Õ‚ºñú;¬T‹’¨çzv)j©«Þ-¾åv<xƒÇ^уóŠE%¦ì"Uc>¶)‹ ˵�”û ŠUU¥¿˜Î}c.º;Н«¸ªŽ¨ú¯ê×.«…w….pÈ g¨ª*˜ \æŠÃŠlYQ?333 ÊCÊ ê uBñÓ¤/Ký‰i3xc’ôxÑu&ë´Ã˜æš ¥ij¾2z–XÛ\I«J~ÅßW•²œL’„Èòÿ±÷arUW¶ç†º·êVì¤Ð(!!#&$’%“dÀ<6Ƙgc26ƒÇó†Ái° N'li1A¤2"ÓB åî–:V®ºuÃû±»W/Ýæ½÷o4ö×Í÷é­îª[÷žsöÞk¯½–àcŽãàþ—Ëe&݉®hë2%-ey”b:)× rÆ$‡î¡ãEäg\וE"?Êmˆß¡iÒY/Kn5×ÖÒyqўĬV«²!J‹Ô 4€…!ªÉr¹~"T*X*H&“‰D"ŸÏû›|}³ÞøDÃzÍÂH5ÑýâêŠ#Áhí] ‡°#:̇ŒÌðò“þ Vx7Š|YãN`Cæ:òÉÃ:ô,® º®0¢M§Hà•YEu# ‘†Ò6iá¡¡:A•^(©’ ‚àuÿõVÕ:MM˪ìXÈùïþ‚fW¸±X¬©©)±˜DÅÃãWŒÀDöX$ qÛ@~�³�ˆ%© †›·X‘ÜêúÇçl§X,–L&ëõºdm˜T—VˆðUpÌàa„\$ÛÌ9Ý  ÝS]/ôÌfúŒ4æÉA÷„“ƒ!Õá4wëéyO{¨çêsë†eØoÚžáE˜B¬w±‚†K©"…+Þ´�eIDD}lr�€¤mƒo‚ÛH$ø“BjÍ<ü+Ý ÖŒÅb‰D"'“Iy  u�¬Ãè>S t€vˆtÎ'Nœ8mÚ´µk×vuu172‚ø_ã} û:èxüñÇóùü¶mÛž|òÉ;w–O)£3%³Á¿#F£ð,ÀˆØÿ`Ùp5†â˜gäÀ•lIþµZ­nܸ±øÃb켘aétúðß>}úŠ+Ö¯_¯]¯•_([ÇZ£½3F+$1ˆ‡ŽI`!Ë5C€FÄŽ|d¿ »bÅ$I ~ Ñˆ1µˆ“ªôüqñ¸9ˆ$ìN©ç"Î&¦i¯ZRóxÚÁC Ä“Þ8Xü-õ­1`makK€!X–µß~û•Ë厎¬­Þ!á­«Å2ZT_%}q@B»tĆ’isƒìq¤ßËÒ;ŠÄ‘ÞB-Jdöù<B× ®õCÁºõ·¡^¥§<nx°Vq„*ï•|6Y9·Ò÷é¾ÌåyÁüÍùÐ s÷çä(ŸÛ‰1@D l£aq6ªbJH¤*bM)#€jŠoiDÎ bøÐã_1'€Û¶S©”Œ[&“IÉ`n…ýI±Xô}_ÚcÀjœb €‚¥”rG*�¹lî'kšf/µû—÷›¿4_zé¥Í›7ïÚµkÇŽµZ­þźùÏ&KÐw�íM¾< |K$L À\JIÌü«aÅHë ÛðpÓ% C*©~¦M›¶dÉ’½öÚ«T*mß¾½X,*MaÁ ýŒl(öræ±0”¼È!¹ÎàªX:“Fð@âqÖQ8è�ôfÎJaFË‘óáT“Õ ö±= sDÝ&áÌå¦þŒîâùš¯‡ú×j_;B1ÖËÙ“!‡óÉy×­[”†‰žÈh €­…n¼l`Ù~œqpó_8‘§(|í¡Äz p`”£ÁLÓz½^.—##Üâ©MÓ„Ù,y4'’òF䇸�Ã{†A‘í²ä%Ü×u]×Öi‰Ÿ%‚¶ y¿RJi*sMÆì2Ã7F\àKu2:xƒ:Å$RáÉaÍfV</‚Ä|6&æ¡ DK¾%+µ»rg©•È$ßlnnN&“Râ ÖI§Óro …‚ïûýýýuòå|É,~ iZ¢À¸~2™¬V«•JEVšïû›7o®V«˜ßd”s©3øÌ`íÁZé©R­V+[t¿íÚ?±­š~¼,QVVfX‰;ä¼Á7kµ 4bHH.LÑ´¼ÛòTÀÈ8K!Ôsº_ð{{{W¯^½yóæ÷Þ{¯V«ùI_åGL ˜”*_žl<gâ1ÔðŒ$ÿzDÞ#Pj”ï‡4ü t@8†I*ÀèEµZÅÜÓ Pn*’Wðà%ì80 Ùý%>S?"£²š¦‰xÂ÷}í’1µ=úÅú¬hlô÷÷3%Œ Èž„tÄþ¸Š†#fS`:ñXt8˜Ì .Rjnzs…qýxøûè9$nºðŒ“;#4khâ"0ƒÃ†]hkA½Xðw­W³¬–Å- ï)¥4sD5Y¤D"Q*•äšÿ°ÕÇ6fyAS¨ •3)žÜ=ài6p|Ëå±cNdù3‘HÍÅM,«ÕjŽã$‰d2™ÍfÓé´ã8Ùl¶¹¹¹¹¹Ùqœ\.—ÉdLÓL¥Rº®÷÷÷çóyß÷Wª•e³¼eÿ-žç5ª)™댥ºRf*”ÅV*•dn#N×ëumDdzZ­¦>JY'ZÕ³ª;º3íU-¹09tæê«:Eh÷ì—ÌÕ<0dNÔ4­P( RÁ©-ûÏ‹×*Wùr«ÙÁV)åœç”_('&wîÜùàƒÊö}¿öh-}N:Ж3`ú(,Ãe#"UÀM)¹ihñ¦à2Z^ˆÏÓà5ÙñHò$TB‚€•Ëe øšGT” +®¶ áCŒUbAò7ºA5rö�}�Õ7'nØH²š¹@Á È*ëho²Mª]H ²x³€�ÍÁ.<¯ >±[;ŽEœ¤�×ógŠ+ƒ€;2‹3ÊlƒƒÌ Xï0œÎOÁŽå¦t?ô<¯½½=•J­]»¶¯¯'-¾E$gt]O&“ràÆãñÉ“'g³ÙÁÁÁ9 ¡ª€é¨Ñª!<d.Ù4ßUÝàv®„(‡Ú¶-uL&“Éd2Édr„ ÙlÖ¶íI“&µ·· Åq¡>kš–N§ƒ xÚ|º”,íÝ»÷¢çõööîØ¹ãå^öð›ßiÎuæúûû1(’( •éº.‰,ËäÃIý?‡à2ÝÔÙñ…éżnyñGö'X ` íÁ°QgDÄ ˜mˆ’ 5Sæcfý›õø«ñÆê†ëºþ~~ãä†ñŠ¡54ðÐE‘Äö Iˆà-ð" —ñ ú‘¼fX¤‡y@ QG•#rÀ¬ßÌÕ#Ò?+V°þB&“I§ÓÝÝÝ…B!‚ÐDü2˜ëÏttzÆ”¤÷0ª}ÀÔ´"Kfñ"ß·,K¼;¢b,b\ãƒ:Ì­ÀµBÂí²‚,c¸ÌèÇò…K G×up`{+\-6!º<ûÍ|þP`| I¡µ"½QqÂ.‹lÞAÉ PbÆäÉ“g̘ÑÝÝÝÛÛ+88ðø‘)®×u=NO:UNÃÞÞÞ7ÞxCCERoSA’.…nÆhp$xÁ‘šH$04.HšpÉâñxKK‹4rÆ7~üøx<>qâÄL&Eä ñx\)µ"½âüòù3Ì;fíèìì´,Ë|Ö|똷âGÄǽ4®\.c=àÀm4ŽãH£†õ)LÓÑhÏ ØàèäÒY!x†Š¤û™JŽK“àXˆœŒçIMXsGý?©b%BÁmýÒò÷kÇÕj—Õ|Ï×·êÆ+†þªîUGš@ÔR{1«˜Åª#ºÐäfZ)¸H>A½Ã ‚‚’X7>,`ºÈ|·N_~P²ŒÄCy?Øwß}çλ|ùòR©ÄdkfN#ÿ“‘U®ybúï—úG I3“‹&’È01 67ĦņT»û}E¢xα$²%$Mƒ%-" ¬™¸ A¦Æ„.ñõ‘óB~ R]ì»…7í’5r`ûÈ¡‹E;Ôîø�‰£ø˜P•@†sõêÕ6lèééáY >J�’0[›TW®ëf³Ùb±¨† z!Š¡Ÿˆ”QDf›I« mIP�Gn”P‰„ã8étZŠ›D"‹ÅÆßÚÚšË夬‘?QÝÊy(þÐoÎþáþ¦cî½÷Þ’Éær¹ ]=úQ'ã€'„7 3Á”W�=Œ¼D´0˜c†f!j&“ lô$# ‹±Ôh‘„Ü?6P¤ûÉÎ@(ñQyøE?|$TϪXsL÷uUQªO)]…ZÈç>úXÏh« å.ï9;yRÈ– 8Ë‚4À-x’šûðØæìÓÃÓu(_XJ† ¬èÁÊo<c‡-& ÊòÍõë׋Å]»vÉ/ʾVÃÚ¯ÈPn²+9 Vf 9{,ä°:$“,e !‚e¡R‘ƒ@²]$;¿ˆc1Ö¤m™ Ÿyž¼áZžáiÖlgІZØ!Q6$B|<%bƒBFœ ÷ÂÈ>û‚ÈY™¡Cª×ër:ô÷÷«aWæçÀAD‘œZ¡P¾:&ÝƉdlÝíº®œŒµZmݺuPúb¦õhkHùø²áK¥Òh¾„Ѥ€ãIZ5‰D"•JIÛ@hiét:“É´¶¶:Ž“Éd¤Þjii²€ü ":Ë4”µr,ŒÅ˜¦kòâºZúZÌ´™È$¬´U¯×%†ù¾/®|FHNH×Á‰‰ð§a) ]×mjjš7o^ooïš5käe!axI4ÒLf[ÈÜrj@QAÒÃŽC‡rIŠ®éJ)ÝÜMMæ^#Z lýÎë€4ö$`ó´”cÔîNç’Žðû¢æÀÏ€4ÁTOQ”€Ë`L€™ì&X=´Ž˜¼Ã–ø€Atuuõôô cÊiá•ï EŒl…œ=¬EJ öX(Á?†aÉž¤à@¥‚ÄW?§Ïàt1ˆ |Œg𬣃0†q¬ÔÈ4+ŠwR˜ì´hÄl2ÆY*2JfxÃ3”m§™•Ä@÷„ ¹È”6X…Fø»ršššlÛîêêBݦhXU&À©“®ŒÅ˜ !{Rž‹Ð¡‡)fûH�@E£¦¦¦L&3aÂ)Â0”H#×/åN2™”ÓÙÒ¹´e©a­Aëî÷ nœp8|dÜ#[3[ëõzgSçi“Ok 4Êå²4«¬+•Jýýý…BA¡ˆ’¤R)ú±B¸ñÆ]:Lïvvv–J%4W$_‘ù| ™¡V@ç ‘Hb)¿Å>cÀ©Ø%(BDe šÊÌä5Ã- |œz½qLE²ÿjwS(lTuHDØY‘ÇÝqâƒ;†¢-"¨ƒWÂUfĶ\rvg�’†Ú…”l)Ð,óô^]dŒïpLåm¬ÊÙóUNÄ섉4Rå 5'_tý„%ÓÝ<dÇP2Š HNŠÖ«"_&ŽRÜΕ–ü¢´gxÈ™í³¸ù™H$t]—^¶´d| FÅfl/ªÞh”G¿¥û[«ÕxGqKŒ?5~@¾#צÈC¨—@sP/–„ 2 #·1R¯°ÿ‡%ö'†Ã .Ç‘#OÊ—É“'?~„ Êkmmmoow]·R©ø¾/ØZ<¿lüe“Ô¤#Ý#µP+[åóSçŸ[>÷ÄÆ‰–ãÇß¿g³¾yŠ?åë™ßÛ¿?©vÒ|cþ3ÍÏlt6Þwè}—ô\’Ïç …r—X,–Éd²Ù¬Õä3Öëu™õÑU9jåtS$n/E0n­VÛ°a—Éd°tK¢¡†g‡9¼P»ë³¡®e/(é±ËöÁB±ÂÅ7ò¹ˆÍ%xÞ˜6űxT”=ȶe" >®í"®W.fv O0+Œç–`y')+!ŠCqòKÌJ­ÃËåÐ<buŒ€x£þÔ`¾ÉT%Ž"²Px¤\¶ŠìÌÑ6jw‰L–k“w‰ ˜2Ju^@b¨!€¤mɃ`rL ÆÅ~ ýgökPæÔ4Æó¼0É fÅüAß.Áø]¤–\ÙH%!äÑ ,£Œy Àˆ›œVãF Kñ^Ò°ãð˜dt‰ë3�nP�8#Á&—˵···µµ577Ëk¶µµÉéŸÉdp‡³Ùl*•úZÛ×¾›ÿn³jnRMJ)?ð¸ îpîhõZç¸s¹•«ó-s°y½¾þ9í¹ûnœhL4·[ÿ£ð‡…‡}kñ·._q9ÕD_R(Úìw.”b¤Û(™GY6%’š$¡'uRR#mçy)Œv²13ÏËY,=0ùuæbÉ^ˆT·ÜCE™.KaÅ“VPFpb隈¬'òÈH‰É6BØ}p0ÝùÈoËÇQ$ÔËZje²+xù\ʰ¯6KhËØCdÃ2("ç�$‘¸8c:ÒXÈÙÃôy*bÐ+ù ô¾ *#ñF@ xxç>rCŽ[\@0‰ËE‘ ãW¬h‰9 dOhÿ€ôÅÉ Lç¨Ýu‘¹¼À”‹Øcà©¥®ën Ý#Ü`¿ ªªúZ½ñjÃZi©¢’Ü– &wIMÆúö6 ŽƒgŒx‰º­ÑhÈ”>Fj *zD»HþËs©hê þǧªÐd¦O’÷d2™Ëå’Éd{{ûĉ…%ÿ*¶%ÈWäÝãñøzk}Kز—¶—­†¤ lÝnWí3ý™kâkæxstMçöúÁëoÈÜð»ô»&±¦Cï¸/qߢú¢sÝsë±ú”Ø–¿¯³ï¶mÛº»»åL”CG n9Ô„À&TÏó*•ŠTo’1Z‹X"$Ô$ ¡áN�Š.XÙ-t¸¡¨HŒ™ç¦#ùVÄÕ›e>І”>,ш‡[D‹î øì`Ù0©lh€l¸Ñø‘ F‘•¢íÊûw†ÝÙ±,Y ìÜX#ñØ¢#$|XÖè_¤”U-LNyˆP ä¦õXÈÙc_8Ñмá?²b`½Åv÷Š4»�y3@Ì‹‘b6Õˆt°yq;¹lLYÒt~9m1ÃõÁá?´Œ}à£5¾ÑÐ4ÍzÔ2Þ6<Ï ç…ÞbÏ=Ø5o21TiÕj••BÄô4W“(­p2JåÄEŠ3Îð€>ö3ÜE;&r»lÛZ³žÓétss³ð䤖&Š£òˆeæÆ4ͥɥ ­ñóäÏÃ0<Ñ;ñïyÓójç}&÷™³kgkÆü"]׿—ÿÞrgùÁÞÁïÇÞ· ëÏ¥?‡aè¾¥YŸ÷>ÿ×)½$¸D†ä²%4"·H§ÓP6ªV«¢�W§Hš"ó—p‚ó鉆Rʱ+Ÿ­5Pd—Žùöœf:žÙ<È…%*5ˆ ŽãD²7ÀhjwuQ9pQ¾# òÝ�ÁÒ5èhBH ÷Ÿû²R²Ã› °™Ér˜è‘VZcÓ|º­ŽƒŸ|+± 'Ö…œ=É @z΃c8Lùé";“ãOÓ^™ÏÈaIuÂK ˜&�žpð@Æd†{µëîiJÓÔb÷Å� K&8‰Pz%vÏToIù#S{¾ï75Ç$”¦|冼ØoÛ•+rÀ(�ºm‘Æ pn±HR!¤2¯‰±lNŠÑiム ÀÒIXE�Ù0¦¤¬‘¶¶¸ö¶´´´µµ%‰t:Írj˜•ëÐD"±2¶ò©ÄS_v¿¼¸Ëíå·$où}á÷15D¾87{® Ôùåó*%Gišš®oŒ¿´ÿRÛ¶¡²ƒD[$ÚÚÛÛK¥R±X”;‹ÅÒét†•JE.Ihr2$¹9f>ØáB®Y:ð¼J3 ¹3O;Ê“jjjn!æ0‚ƒ;>p$|40[ƒš‰ùÓXíÜÝÄü²\³¼>Ëá7’Vj¤*=BIÈ—ˆ÷Dð Îo˜¼ÊîÝ—^>C�†—Ë帇É'ERÈùØ­‘ƒ‡Y€Q ô–––0 wìØ‚ë±³'ã R$œV˜Ó„ÿ Æ$ ¨M8ò4‹=ÇØø¶(XÜrnb AV'äÔ„´ªHWq¨&‹™Õ…ÕêwªæOLû÷¶®ëþ™~íåšy™é½í¡ÞH"¿‹²�û0(C#“7­<TI~>釾tbb±X>ŸWJ9g9Õ‡«ö¶6äËrÐð´¿|(ÉK~hxD U²?fdDè:œ•#ƒ$ÏÞã #�4À*¥šššhšã8" :ÇrÐì3g2A±¶Å¶-M.=Ý=}¦7ó¸úqšÒw¯¨Ê™™3Ï,žy{óí5U»£óÇvîqîùaû½ý×mA›aº¦'ÉÎJçÄp¢D†”NÜzoØ›5³±Xlܸq®ënݺÕó<áȰNss3['“ÉÁÁAQ—Ç-¶cl¢Œô6äÒ «àÖḗõ î"Œ04Mðî ²‘¼¬<npI¸1Ú€[G»I1�)nZÙÀ y!ÏcÁh‡É @°}"#èó!zAî�ÓjÙ s†.6¨ÂÙ‚]ÖÄ{�ÄÉà}ÖJhnn>âˆ#¶oßÞÙÙéyžÊ©À 꿯«¸RJuÏìîVÝÔ„±³Çz9üwhhbº ‘† <è–óúˆPY_°�-FÜ1¹ Ïs¨Hñ%a‚Å( ÃPå]îåNÌ Øk*ö«˜ùK³üb9qL‚e䙱ʄ"y_¹�u—#)ÈFÞ0,£¥¥eÞ¼y•JeÕªU•JEõ«°i„ìÇÂø ñ ,÷¨Ç)R–C¥Zzijw+hÖ)Ø…ó‡…Ôy¬ô8C£U ¿N0å$êà˜“:F´„^AÌ1ø²Ú\=Û›ýõê×—ä–U;*­§SA*&íÐ~=ñú1•cάžÙê¶Úš}eíÊo¸ßXÒ¾déGKu]×<íâÚÅ·´Ür}×õµZ m†¾ZßûݹtçROy2dêû>à5&DHHnmmŠ6rdÈNãÔFуJ(2l«hHyôx™|§\.Ëg—D3ªxô¬7Êèö ©n¹÷‰b A [’ub"m{fôo4Ìy=d„<9ÇŒGVžÆfS€¹9ˆàº<Òã™v@©æe66Þ‹_¯¼òÊX=Y¹_uƒýçTGÕ•¦i·.¿õ/‡ÿåuÉ<5o,ä왯?1¢°™ï:`¬r~ñˆÕaõD8£8:q¤Ê_""çjØX+D2Ïó¼s<ã÷†äVÉdgµÔjœÓˆÝ»¢üaYcMÞ"2j‡kД¦B¥”Êd2‡~xOOOGGG½^÷|Oi#­W–¨.8øÌ¨FŸ1M™U#9P‰¶.|6xÊ/⸌b‘uµñ»ð V´Ìö À%ýùu‰72sƒÓxůœ_=3øŒ®ë_ª}é牟ÏUsO®ž¬iÚÞþÞoXoœìžüRú¥gãÏêº~|ùøÙÙÇ}:þô‚Á†a´Ym­NëÏZv|Çñ-^K†¯ïõúú¦õÛŒm7§nÖ”vAႦL“€~]]]˜"”XÇ20R&ÈFdâ\×4ý¸ òÂ7�� �IDATÃÂÒÀcAm¬T*qñ„QDÌ”@mE‘h&Ó—¹Ù†”  E&{ØZ‘P4«¢®âÙaèi‚Ĩ:µÐíŽÀP‘QS죈«4frYÇS‘bVÄ·[hØ2H›x|ô#ÓÓò)ººº†úX 0Æ¿Çm¹IÝ”R©ŸªŸþVýv,äì™F÷WYyP`(EJMðYÁé‰èËÀÊ"&:“÷ ´“ˆyûh‚Ydü>‚Ú™µÄ1 MÓ¦Nºÿþûoذá£> ÃÐzÄ*ß^¶° 2)3âzÂ"72>ÍÙâaåµvùßÊñoÅwîÜù裖ËåR©äyžûS×ú¶…O!1�ù,v—üÆQqâ@†åQZ1¿–¥æy&h†ü¢<€'röE°8°¤¸‹ù2ù±ÂÌÂÛ_yÛ4ÌL9÷‰s…Ÿ&P›”>’+$“IFóÙ€õl÷ìb/¬Ñל“=GÓ´¬xºwyýò–°EùêÉä“?ÉüäŠÞ+h}`A~ïû“µÉ_¨}aUiÕ]ûß•åU¨¶5m+Y¥­ÿQ*•Ò4íû­ßŸXŸøÕ¾¯J°‘yF2—*9‡\$[›£ŽŒ ÏË &÷]"#÷07c°—Å÷d¸’+!™ó 8¼ÝØGôËÈ>OËß%m‡ªkÒ€†ÀÕsÄPºìÂv2`ˆAå- ÿ;ZÖŒÅÓPv;ÃÂ<ˆ‚‚îâl•-' \Ed>Ô°â�›ƒ e†?ÞW‡ªø/âº9 ‹jßT5uŽšó˜zìTuêXÈùïÖ˜¾…AôÈ|8oE.zŽCÅæ#K’ƒ�CSdñÄJƬÍ,P7 àÝs¹Üg>ó™… ._¾¼«««R©°P#ûàj¡dŽ:uä'GhÇ«ôຠ>±ÃŽŽß÷ƒd ÓÕLe¿i‹¬q²Ãì {˜ÏÎã8šÂ´T’kÃpg¯,ùH|:ô“ÙG’§I03ÔÎiSoýË[™BfÁ ÚÚÚôfýöónŸ÷Ѽ3¶Ÿ‘Ëæ0— ØÆFc›»m“±éжC[‚]×UüÕ>}Ψœªp^Û¼õߪ~ë_ÒÿR° ÝzwY+ÿ8ÿãó'ÿÙÚg[[[…c6ÉŸtdáÈæõÍ¡>;ýÙcKÇžT:©%lIi©D"1`þëæë·7ß~ÖγDMšç(³dj•íä‘þ6Š?p£]aPg�ãQ5ì)ÅR{`]²F ?hÎÇ ÿËà0ìj8ãA";gÐâc¬)OƒŽ†8K@äæùb4_#‚I ˜]æ�Œó À1yLòF‰Dd<Ñ_À=1ZH§ø O(˃ƒŒx¬¿‡CÀÈn‹«mÑ2ÙÌ¢E‹Çyê©§t]O©T³jÞª¶ŽU9{ äÈêg{c ›…S§ˆ–»ŽË¯�ÃÙí gI a‰�£`±N ¬áÛ¡ ^ÓèÕ 6Äb±÷Þ{O:ðO6Œ×FÄÓääxå̽zI¸ ý Ž ’A8W9ÕVÝ7ÝÆG +f¹{»þ<ß¹ÊQä/$£õt1. ñR9$Ñ<ÙίŒ›Œß•D^ⱯEÕ,�4áA¹V»kI –בïl¼jãA¿>¨½ÞžH$’ÕdS¥éŠ?]ñü§žß¶ß¶ýëûC:G¼d*…Bámïí»bwÍ.ÎnÕ[oë»-_Úté5áÜò¹ÓüišÒž‰?ÓitîÐw|·òÝçÍç5¥}7ûÝ‚VØblÙ™ØÙn´ËÑu}’3©_ï·,kjij¶‘ ¡*$ÕHkŒÓ-} 9 sÀ…Ça Ð4òù|±XDî ä6‚s2)‘u`±¡ÈOŒñxNç-Ÿ4l6|S$ëÀo¤žƒúó`!s›"o<ŠÀÂÇ�X00³F�Rù'lF Vûض",Þ²‹Ü.ÙDBãăwÓ#ÄQ4@çÃUñþXq#ÉCá\®¯òM)LÇk{ž±†¢H؃— ç†hÀ0í*€28ä /•àfV à/¬›­ÒJáiá믿þÎ;ïT«Õ!=öküäÂd`(;¸´g "r¦3ÎL0Ó4›ÎyŽ¢xÊ‹½KÜšÃ0T! Áù¾ïáyŸð”¦ŒWØ31ù¼!ÆqÏå¦ 6 ‹¨2ËN’>pÖy+ø–ºJŒrá1#܇ß-\ÈlÍÄ«ñ¸Ÿ6mZSS“p½-ºvÜÚcòÇdcY!Oßš¾µ¬•MÓ<Ï;oš7­C︮õºæ|󵚜¦7ÿøKÕ/ýºüë¥ÖÒkÒ×ääižRª5h]â-1BãÒÊ¥ÛÏ­Íý·Ä¿½h¿x]öº^“¿F.8‘Hôgúóv~Ÿ ûTSÕR[éî¶»u]7æ…æ¹u-ëŽn ©.é*Éá( ÀC6[¦†™#Ôgöë”TZ¦J1Ì ÷Lš„¬J vŸäǹ›2 Í´yžÁbSíH`“ï#ÿ-D;—â©/~e6å$,•Îô?¼£"ßÙ"pdP¾óÝÛFxˆ ä²Î‘¹Ê'Eõïy^¸+4×›þ‘þàÊÁ'Ÿ|R)588ÁNµs“Útš:m,äìî�‹ä…N;²EÐQİfñp¢5- ¥�1áŃ]À—¥ b&6!¹©²²²*Ë*›Æ+†eY³î?¹æ¿™#¶WþÚÝ—A6Àü'¾ÐÃÐxÞPÏsöLÅv†Þ~^åWŒåFúoi×u½Oxå‹Ë‰‹j›â†'|: @T¤¶Ë(C‹ð¼aßU¹“�ÐÄ®ÄI–eõÏíoénÉ™©S§{ì±¹\nÍš5µZmïÆÞϤŸñêžišÿ™þÏeéeÖ/ŒûqS™·˜·l‰mÙ™ØyPí %Ú’}à¶ømŸô?y»u{§ÑÙ­uh~¸°¼Pu_ó_´_¼nðº6­íîÄÝŒ }FßÍÅ›¯M_;¥:åàÊÁ7dnøNå;ŽãH‰&ãmsoËä2_P_PJ 4.šzÑŽØŽ³¶%ñRž¯Ð4$­©V«ƒƒƒÒiC€ðŒ#,�±>ü+«§sî ˜UE^0ªàbBAÐ>Ù�eÍÇ.B`¤ˆ–«ƒóÑ– v4|ÊÙØÈ1 9DEbk‘v—}ø“Åx”æŸì/æ"éIL¹¶ã!Yi²FpQìbfx ­&Œմp}Îý—ý]»vÁ‘«GõlU[ç«ùc!gÏôr"fÌ<Cú³¹\ÎuÝ|>¦&ô0˜ú‰þ9 *슆Öz€œ©aát胖£iš¦´øÒ¸ý¸]ýfÕ½Ù­i5ûa;yAÒëóüpHÒCÚ¨¦q"0cB‘@SĦ3r1¼î!I2ÀlUù·Jö«Ù–xKk¦µ««+¿2oÜiTþ\‰/ŽC6ÔHÞ8OSšòT¸5„ˆœQÏE„ã¤àbÜ ¶ÌBn.X¹äòlºÊ½„¨ô‹¶U³²Ùì¤I“ÆoÛv.—ËçóB•ŽÅb/¥^Ú™Øù›ÂoÊfyµ¹úŽøõé0Ý©wç7Å›rTxÔ§ Ÿþ™ó³‡ªC½†wcâÆƒêéJWJÝP¸á®ø]/Ø/4ÍWÕ¯:¾tü«Æ«J©û³÷ŸQ:c³¾9Ë·˜-±X,§ç,ͺýðÛOxÿ„ÏLÿÌ^¹½t]/Ö‹¹M¹ß4ÿ¦T*õõõ577à HîXµZ ðP(H½é¯ðˆâ=@¨]êTÃJwŠÔ‘ürÝ ô ¸3àØž ð–4Ù ð-Äè ú"’¢ ;L#{�ODæv‹Å"´æ8¢pQ$“ƒ©5ìÔ�—ÕX^š1=ù ÌØID¯1X#GQæES“Eä˜1Äö }�›IÂ×`Ëp¨Z …ùe¦w©W¹n_dAxÁWâ_™­fÿNýn XÛcÀt½xLšªìB¡�žn)¡ÐÐrgˆÀj™¾Â Ÿa‘.6 ÃÐ ,ÍÕìël[Ù#h(m7¿�à!œ[a"…‘x™ƒAþÈ'ÕòÑeëMk‚=añ¢Å|ðêÕ«ŸþùÎÎNï/\Z+­0 ½Ež?Ã÷÷4M «¡¹ÜôÞ÷̵¦dš8û 8 W.Üe†Ú a‚.@s€EÌ_BÂçøÍx¸öf»°w!L†»vízï½÷²Ù¬çy™LfGvÇ$wR†[ã[÷mì».¶îÞĽúÞ^ºý¢äEgºgÞèÜxGòŽwâïœS<gmŸÙÞì­±­G—öë¾i™µZ-T¡R*ÖˆÝQ»cQó¢ç Ï…aøœöÜyÙó”RU­ºÂ^qÑ΋niºåú®ë•R3ê3&7O~M½v|çñ¥D©d–‰„¦´¾¶¾÷ǽßVjs{\¯ê¶Ä›|>ßÛÛ[­V%‘ .¡¤—L&‹ÅâhN9²ˆ–”Xü•JE–4Ö‰žå}DY² » (¨Òü¾,OÉœ{¦,cmCÏ‚ËE‚L+ÃÌb��¹3˜n‚Ú]Ò Õž|F0&±!@ù;ûÇsß Tnò€w”ÿ€¢#iÖu]y*qk"øYPýuÕµ\¥Ô{Ýy¤:r¬—³'Cz†(–y@ ËÿAQ1B91YaÄÓøhÄŒO‰OÜ6Œ\*Z&@“ä:-ËJ&“’ïD(×`þ y/û D¨ý²Uxú@ìãÐ8aRÓÐiõ]oòé“[xØ’%Kf̘ÑÞÞÞßß_©T´Ÿiw Ä–Äg7ÂöPÛ¤%/H†áš®ûU7Ü7  µG¤ÑÊV$"ªb¢ò —'AY6Xjw¯0Hcd¡äã‚ËÛ¶Ýþ·ö·Nx«´©T,{zzF.—ó}ÿ¹¦ç8¸\/¿º×«Èÿዹ/þ¢ö‹&·é¦äMfÇÉîÉgÕÏzÐ~p\0î¦ìMzÎ/Ͽپù3åÏtøVÉ2¶'–O||öãO;OŸV=M)õ¦ùæ²Ø²ì”R‡x‡„Zø“¶Ÿ,6;uGs×ukNÍñœçf>—ìKþñÀ?Z–¥Ò*¨ßÞôí&>0wÓܬŸB£d²•J¥X,–J%pÇ…%-eT“lèˆ ÝœŒèos¤çˆ;`òŒ$[Är]àº,ºŠÄŸ?Ì1ÁÉ„ {V¦”¤ž€¸³�gqòÇÐ÷è„O^V˜¸èÂ\�ïËâf‘ <˜ýÈ)º#Ä Ø6E–4b!sXXg³yœ@~lD×ã¡]£?««–¿ãC[ÿ{ïåDL&øTÂ0#<e©1!˜åÎ¤ÄÆ+ ‘?¡°2šmÂMÙ²|AF “ޱ9ü…Í)»Pt\áð‰aò%JSÌ=ås =*æËr.&¤5ieKCeHHQ…¾ï»‹Ýä_“ñÇâCC”uÃú¹ú¡?u„AÙ+å##º8b-”SÐ6¦îmÛ–¾ˆ4äaSëéÖ²¬T*%1û'YyÆÊ—O}Yê†ÎJç5ó¯ñoÆÎ2rŸ}ßâÚ⬟]e­zÈzèû•ï_]½z±»X)õH쑪7<d>ôvìm “ïxï¸=nimiÎÛs”R¯$^ùræËŒ '/¾=qûÕ¥«•R;ô‹ýbã/žl~rEÓŠã/ ¯) ýö~wλ·uËMwÞ‘¼cJ0åO™?ms¶Éq,¨¦mõz½\.‹a<#HŸ!T`…ÈOb=0B~§'² ®Wä(”Ó¼øE$[ˆLˆ4lÀ Ïx7ÏÙsƒ;`K(Å€"«<)æÎ¨aAÔ.ÈT õqÁàR Ô;áGô @ÜÀ†‚Ó¶!v.ë)H/б"‡*ìzù!Á‚ƒÀ¶Ù,„1º_À$UGѱ*gѤjæqkno*’�™Rº8Sˆæ'8�©x,Kæ$d©AŽL–àZ@Ƙ–G )ß$huò¢]/ßÁP'ô’c�…ã¸áª‹‘n„:T?l•-¹äˆáv-ŸÎ¿òÊ+–e͘1㥗^Z¹re>Ÿ÷gùúݽØ5ÿjºëÝ\&wÀd³Ù>ø`Û¶mÖϬÚÝ5û=»±£>…œ#ІÌ1|#Òü¿p‘@Â˾[Œ(ò´)úÛ"’†(•ìJžx+ÿzÊ¿†‘òRß|é›¶²Ûñ¾]·ßßø´÷iÏ÷Þ5ß-kåÛâ·-µ—nÖ7_T¿è ãÿˆýÇÊÆØÆ×c¯ÿÓ^ÿtÀö½½¨X,¶×Ú/xþ‚gŽ|fµæÇƒ?~2ùä~þ~w9wÍlÌü\ås­ÕÖv°wÛÞGo?z“¶éÀðÀL<Ó¬7ßÐýw|tÇl{v&Ìhš–'ž|OöžŽtÇÉ“mDÑ®X,‹Å|>ßßß/y´@@ÄùÔü"ž7¸?㜃õÖp’¢W„ÛÎ3¼Œzñ™Žih†’ä! Hˆf>xkÈÆxú îAê­Y´ñ8R? }Ž Q„ÓBÍÔB=¬o®ëµÝJ. ½ñxÔ† åeñOXh$~‹¥4*• –.+*Ò1‘[Íqx戂L‹Éë1’ôÿˆ/ÐbʹÏKZDFŠevù`ÔÞ³ëÊB—v4VƒìOYyÓǘHÆ�¥WÄÄPY^¦©GDåxÉ3ëpÐ0°†½‚,[Ö#_“s'qA"ÿ—¼~ªþÜsÏ­\¹²³³S†œë¿©§¦Ü+\Ý×-Óš={ö…^8qâÄ¥K—>ú裥R©n×}ß×Ôˆq|€°¯qˉ&·fÒÈû«äQŽVîÁÔ'Ÿ_0ˆHÊnعs—ö_*lžçù¦ïjnk£uaÏ«÷¹zqÿâ’\—¼îúÊõ¯Æ^½¾rýyéóvú;·š[o{ï¶ïíõ½çZŸ›Û;÷öÍ·Wú+Ag*•Òuý”ü)¾uá½3ï½¼õrií|»øíõÖúæ yŠšò_ãþkkfë»Íïzº7gpÎAê ùùӽ铚'÷Ç›¡©)-Çs”­ŽÜyäxk<ü‚ =ˆz½^*•J¥R¹\Æì­„¦Nð€÷óp”ót¸Ë}fÓ&äÝlÀ$&õFD‰Ð±`©'T<xš‘Ž·s¸ º#!€À@P€ñ­À'EwpD!ðÀ°6«V_P×lMiÊø›¡mÕŒ' ¦á`�4/Àû—m‹QqxKã¹�uçÛÐn7ŒR0Ç+ýÀ¬Še üz3Ö@HC} ô?òc‘T…×í°ÿ ž=ÃǘxˆÈ&ªÝ-œaÏY§,b¼£TZì>€ê>bbf,O1 V«TTB+‡#ïbx†¹Ü,|¯ü%Ht$J¥’{„ëŸìÇŒA„jJ)AÞpäA B¥4¦ÖÆÆ> •(×#ðÒÉȉ-Íç ¨˜f‡|=0U0 >•VJºööC¹7qï‹ñ±~ãüfž;ïôÊ髬U[6nINH*¥N}ûÔÍÝ›QaÄgšæÕ…«—5-›×˜çÞœ?|¶þÙõ±õw¿ûÈò‘_êÿÒÛñ·=X6}Ù!‡¬pV8½Î½É{§ÛÓ/ò. ‚ °‚wþ]¯èkÆ­QmÊ.ÛrUµZmppPÜt¤£# ‚qe€£ G<§*Pþ‚…díÔèXêÜÃ@�€Ôëå°Ð*“PÀP@&›,%±¶�ˆ îÕ£ã›Nv Dí…OŠ%äÏò§4ô’žúv*,‡J)÷T·±OÃ?Ç·—ÚÀxCÀ¹g´ö7®Êâó¢FÇRgé&#áíˆ9ä´Ñ †\LÇBΞ§D¦AÁóˆ±5$#¼¼$©„î$àŒm –·Jœ˜�Gšg$Èa¬0E$KeÎ ›§¡ˆˆ–b4+ù&Z¦AT*@pÁJ)ßõcwÆü9~å¬JñÀb„úkºõ”{+æë¾õU¿²n¼c¬]»öž{î±mû­·Þ*—˵³kærSïו64Åͼ)^å˃º®;¿ṡ‡X�étZ)U.—±÷P®ÉîvVðY ‚þô›u]¯Õj˜`•¸^.—›ƒæ«>¼ê¦97UµªRêö¯®^í(çZçÚÕM«»Œ®?üǶ mŸØô w•»%Ü"ÒgjXNrš¿åS•O…zxE劷Œ·^H¾°W¸×ªÄ*?ôgήêÕCÂC.ž}q·Ñ­<uZÏiv³}Zö4ª¸Šÿ¯þÿåô9ëÍõ"ŠQ(äÂ:;;óù<´Bµ`š;@]V;ž†Ú‘ɸ A3G 䮈­-d \Ͱí,{¢Gu€ ãGÚæ9@Ïð/‚P$åGEâW‡H›p—à-xš ”}‡‹ÅzCÓ4çI§6±æÞèjhlÍ}_$gLš�œ…\–ÇÈxÜ•=·"Lˆ(ò*$…8ƒÞ«"Mk–këåü<räaíBy‚ÉQ¨÷‘† ƒÍ=|¬xQ ƒZ—GÀ™¸ldšç�cÈùc«Ruóf&Ë!ma‰‹!TªMÓÇé•VÂ\¨BeÝfoúG:°8ôrYÅ]®Æ9(ª B*?q6n­¨™¯™á›¡¯ùa†Ð ÝÔõ˜^ßVW®ÒfiÝkº»ÿ«Û¶m7p+{WÔÞJUWîHý •0 ªÑ8«á^ä:78濚±X̽Ð-=[jº¬©yWóa‡ÖÛÛûÞ{ïa£âÊýñ¤ÛÒ‘’{žJ¥àûËg¥<F£á8NµZ­×ëMMM¢€)]ýqƸt#=ÝŸ^Ój[­×$¯±•=ÎwÆŽ3ŽÙ|ÌÙG½vÊÚƒ:¸sM§ÛêŠi 4µä”üQåG÷Æï5•9×;QŸ¸EßreåÊ…Õ…ŸM}vš;íÞ‰÷¾¬¿|Pþ ã{Žo±[ž÷Ds¬ùÖâ­­~k£Ñ(t¶–·ª¤êëîëßÑ/A¥R©tuuåóùB¡ åN½^g\- ù&[–±Ë'zLh”ÑÂ`1Hã0VÉ¢p2D^q60bFÛR˜¦ÙH4üñ¾¦kª®Â!:pì ú¢LA��:'¥?ö£|: ÒaŽ:I•Je¤mm¸_pS¦ä×S©T­V«×ëúV=ö×XõkÕØí#í}æh íéŽSFå˜tŽz ¹À–%IBm$ 3LÄœ@@—8šLÓ”)é±³'5~Þ$ÐÆç@p ¼X°Š-`èç«]é.²W|†Þ!^eRE}Ziòß«š¾E=ãÉ>VAý4Â隬7ÎoøÓ|ç|GÏë¾ï7.k¸ ]k©e¼b`Ò¥äs‰¾$X•ìúŽÓúZ‘Ãt誡 •®éØ<ò¹ìk훣CíMÍ5ÝÀ ü£ýø“qk¥å…#*Rò5Ô=šè{‹¼ôqé!”ÌWö­¶s‡ÓÿtüÔøûï¿/­r܇ˆl;#™s%§¢xBÞ¶í|>_;Úñ}Yß²íúö+²W¬­ýlí³G”è.w?Boèí½í†iH(MàZ­ÖÒÒR«Õ¤ãÒd7eì»ñwŸ‹?÷tüé§»Ÿ~Ë~k¹³¼d•6ä6\ÑÅŸrº:¸zÙ„e›ôM?¨ý §ÞsWâ®ï¿ïWýB¡ðpëÃS?œê~äöõõU«U×u«Õj¹\îïï/‹bI Ë ^¯ÚBQÎÀ# N£ÜG].OD -f¬Èv@_½"L“à òšÜ:Vôà?22U[RóÛ}m®ªP•”ñ𡽧뇄'Xc!ŸÈü?×aìM(‹ý<ü˜¦´Ð CwHž®­­­V«uvv†Aب6 ÛeÞ#ŠÔá˜` ±’ÿwÓ¬h€ Š è¸0ew €œ¨/Õ°Æ ¼2'Aù{—Yû»¯r0zMÅþä¬ÍŽ%ÅsûjXÊ"8Úà #É`ˆèÙˆ €¦5m4ŽnhšýU[~²~V=˜xIÏ|Ì­‹× /h þl_ÓµÄE ¥”nêAX·YÚÞZõæjre©+Ÿ>ŒÎqæ%ç5è°è#IŒ¨·1LF€|Å¿÷ ýÓü TEÙÚ–mñ”ŒÚÝÄ;×Óÿ ³‡•¼~â¡Äà)ƒþ2A û!º(r4P$ËÈ’b–¤½„„Q r„Æ&G$òtñ~]¼uñ{ßy|ñøEú¢³µ³7&6^Ñr…L9ù‡#guÏúpÞ‡•‰•d!)ì†þþþ˲*•J>ŸwÎ ©Ò©ôïZ~çéÞ÷²ß{%þÊúØú¯V¾úvâí#G&kÉ{’÷ŒÆ¾þùûâ÷©@%ÉUÞªô®ô-Snq{Ü}×ïÛÛÛ;00 Ú6òÄ‹Åb¡PU4×uÅõ ¶PÙS9ãpO$#Á1ŠÁÜeô Ð?G£ä1ÁyØúˆÑÝÄ[Ô¿R­0¶.fÿʇ@êéUûÏvlûn^|LqÄL ²~;H°<Mò¬1Äݨ؄YŽg†¡ðÀOr®É™+$vx@•Çñ‰ /ïËÖpèþââqó™€4ZŽ5�cFÔ{þ O‰?4G+©Ý]?6€±û�†¼2ÂÊ@oá໌ØocÀ ãÅkókÓÖãR!´¹4É�� �IDAT^8uZvÙ øløq»nˆ#»Ó3ž1ܳ]ãÏCä4Ž‘€°¹ýƒÖC‹¼‹Xe‹÷Ð?ñÊAÿ¶jö¯ì!`ÄÐ#  º8C:'z™›3F̰,«¹¹¹ÑhäóyÏóbÏǪWUÃGGf°¡Ï L$Ô8DûG&Ö”£3›ÍÊ'TMT¢]×¶±T-‘ûÄ–O\;óÚI“jÅÚç Ÿ[“]óiïÓý·ísÛ>ÛÇöíÚ¡µrS¹­Ð&“Ib·#4ž¾¾Z­6¾:þôþÓ—¥—UôÊÑÝGŸ”>ɶmÛ°ëa}jeêD5ñÒ½.½¨zщÁ‰mnÛß*ûå„_>œx8Ï}êÙO¹¹îV·¯ØW«ÕúûûåòªÃ_R¤²§(‹ø¼H›0L6$ 7œÍ°¤ äð„ Ïôð¸%Zl˜öJÄ–^MˆòRS‰/%ô¢î+¿Ñhý†õ «þú>Y¯o¬ƒô¥†µ0=ð<�Àp˜åéT °‡¦sú”öW­ñņþ]ú…Cx@». íŸÙ¨YŸý|V=ä@ˆÓjX”M_Är˜¸s‘‘ )¸½0Œ  Y‘à Ó9c!gwqp<Éã@£a\›ó_"L6r—¥Ôx´ÉG„¢6TÍiøøÎ·OyèÖëuûM[;LóÎòô‡õˆA{¶)L§¬êξ]×M=—ËÙ¶-³ôA=0Ìúôº¡ Ž.R¹Gœ åò7ì'§¼‘xÚNš%hVí³Ï>“'Oîèèèééù¿ÑñÊr|`Sq#⌣ك8Q¬�EŠÂ‚—ŠŸ´x}‚n$n² …ê�9@]×M¥Rr ß÷û×vÝÜísWô­ˆbš7<4í!/ôÞ¸úO>òI7ã&‰z½^¯×ÓéôÌ™3§OŸ.¾×R”ˆšïû__ýõÇ÷}üû}ßojjú õAµZíëëÓú|wþ¿þEjNcNK_ËVo«¾SŸõî¬Þí½[¶lÙµk—çyù|^n†@#/|‡‘�¡ˆñ62DÖ!oYòdŠs i¡HJÉ@‡¥xü9\ä bЪz}Õþ¹­4Ã4dpJ¨ÖõVé±’ù²é_¯a$3RÓÈÚ‰~£<‡+·ËÛìùGùæÓØh µ^¦ëÁä@U•·Å ôOFú>vq"Ü*²`€ˆm2mm´ˆ²;*EÄ!dR‚³îmÄ­ó¹`ÇŒ‘¤÷|/­îj²b;°ñ¨Ýecä‰Ê2âý ’43³e¿ÉF ü ÔBßõ5MknnN$]]]aÖ*µÐ ƒ0PîPŸŸ™'‘Qm?ð jµQ³ù)³9q1Àèå·"sB %³æ#2�—¡ð¶aÆžž¦ŠI‡[nÐÿX,{5Ö8ª¡^Pš¦ Ƚ2M³txÉ\9b$Ê[{9�ë]B»ZþI óJJŽÂR©Ä¨ È=ˆÓó±zÚ{2™ÌÙg?ÐòÀ_¦ýeî¶¹E§øå_žØ7Ñkõ~tÖ6íµiÚ Ó$Øg2™ææfQ™ ‚ ™Lzž'ÕÏÁ;^—Y§—õ¥ñ¥‹ò‹ÂjhŬGÒÄøñµãýº_QMÓÊÉr©^š¸}bߎ¾ÎÎΞžžJ¥"ü49îåDr¹'Y¸”Jd‚EÖ!3Áà™$E’P'x^UÛ¶AcAje„–s3X,Jþ"Pêñ0®išã8³fÍêïï߸q£çyª¡B#4c¦ßð²¾ -¶£f.ÀØD8„®.öHìå˜Ö¤U/©&V'‚z ”rt•¯7$H¤‘ † DfBó–¾ô5˜ §È<+YcÙŽ p¶‡¡fev+k×òüì?�Ûë±Ûi¨S0ç=âÏŒÂïìi� mRÉyATß<¤< ¯¡È*íñ <5â½Á:¸DA?šþbßxÊ€*L†^Úóçù‰'¨ö_B)§ðO˜ûˆz1@<ö³b6l<MÓÄ "d |ÉÀ”ë¡3å7±Ú¿ÖœW‰ò¯±X¬~^=wb.’ȃ +×RÃ.y úˆÞ0úUÙlV޼R©âD½êõzž:ö©œŸ{{Ÿ·O8ÉôÍq¦Rê²õ—uLïè8 £ôr©ymó'õOnÚkS2™œ2e Ï—Èõ—L.ïÌ÷ϼö„k/^uñºöu·æn Ì`}býNwçûÙ÷Ÿ\ûäæÁÍ2ô~òýMÅMí«Ú×m[·sçÎÁÁÁZ­V(äS`ø§zWò€ä˜“ûö±c1<5ŒŽˆ|�–=X'FƧØÇ(V8²´:s‹�  Pj¡&þF’³CÓ4Ó0Õ¨ž8UAVæ ÞÜsâûƒ·†wÏ}[[Æ_ ÷\7tBMÓÌÛM«ÛòC…šú<ÒÄ“ ˆC’âDŠ!°Ë„£!— Ö%{¥c¤)ÒªaŠ9Ãkâa6 9ÿ#z9¨9€J#W‚ƒ�0sæ½°ª?Ÿã8mmmýýýù|ªJ¬´†Ó-ïCO­Sþɾõ”5000»løí¾õ°¥4ÅÄeæÅ“Ô‚ðƒÐ;Ì3ž20E¡ëº–Óü}}ó&3ÔF ŽZ­†ÃÔIÙHàÒ ²¢–ç¾ s‘y@a S¨ag)Œ ¥húĪ[Ù¯ØågÊεŽù¶†aù‚rãsìuY¦¢ 5™ïûŽã€k ¢ôfäd„x<S© Òéôé°Æ¢”Aàïýõ¤¿õöQ³’³vMÙµpãÂj±ºñàr~|èMÍÜiïÔš5«jÍ(ÌøÞòï=qÜ'¼qBÌ‹åóy¾„ð&Ճܢz½¾äÃ%¿žÿë3×9}ûôw 8£øþ>ïôÂ| :Íww¥X™ñÈŒ>ø ···\.‹EVT’ˆˆAwÖ4“(¦ xroÑØ€I '¿Ü‡@ÀUõh{fœûâ1ÁÓ‘б•"+3ðkpÔÚwÙõê±×b…Bá7Þ€Zã ó7¦[vÃ`…‹2YôZ:p b²Ð'{r3Æv8Cô‡?Z#³2¶†ÐQ °ûxÞˆkÑürÓe_‰1)T¨<–Ä&)È §8Ð�Óa[AÖk,äìal ë "Õ,ÜäMœqáÌÚ�s<Ï-œîînYàwJʃÓȶg»]n°WàÍöÌŽ!ãê`f ï«‡½a°kDKCŽnÉ’ZvËõprX|¾h]géE]×õú×êa[è|ÁÁ)€˜íyŠ + cI²C0-q ôê#¡H޹`ÀТñÃóP}‚:ë†y·™½7[þ÷rå§¥Tâ®Dö´l£Úˆ™1 Ùp^Hr¬'“ILä°L*´På"ÓétµZíïï—Š©wµZ ‚ ­­Í4;LŸ²ÕÜÊÜçæ=÷÷+Œ ~ÊŸŸ¾B­Ø˜Ú8­>­ÉoÚÞ¼½¢W•ÞÊ®ù»*µJc°!’ÆýýýrUº®—ËeÄûYïÏÚíþOÌ}âÍ}Þ ‚`ÿŽý¿üÈ—•¥®üâ•r?ÿåñù·ó[û·‹E0ïå %€£I::.K„ÎEN^ SàLdn »pâÕ¤Žáž fÀyÈ(Žã477÷õõ•ËeL« •È[°s ¯Ë+n.jšÚ¡¿N F̈é±!tŽ5œXj•“<q@‹Þ)Äid%3;Ÿ[),¾Îs{¬Èjf8èj!ËL$r°XƒÄP^°U„ð Þ3¢µlU–™h“F§÷ªc!gÏG4ñ¸dØƩУ­îÎÙ0Vñ´gIffE£VÃòæj™jüS£vQÍx}X‘zn ujÎÏ@@qaRƒ¬E´‚•RX¿µÌ»Íêÿ®jMšR*vGÌì¢ÀÁ»ŒG"˜;À`!)šBç+4– „F(BQÄX‰y$3E`Å,]éñ+ã#襡tM‡ø š ü%(ê'˲¤ Iù°'%6àƒƒŒ'wàÉEO~aÅ|ßw=·»³{RyÒ¤I“RÉÔqã¶„[Ýôè»ö»ß™ôÌúÌ.k×ýÇÝ?˜|©é¥OtB­e>¬ƒƒƒ"@gY–ã8‡?}ø¡þ¡µZ­R©ô–{Ã0<õ§ÖëõÁÁÁ…B}Æ*Y-ºÐ`¬ ¥e14Ûj€”€˜LB²éPŽ.b"äf¦q²ÚSðD’Äu'{>1F^!~Y¼qK#(ÚzÍÐ å(Žo<`èïê6Âü„@'0ª^p€.2§+âÙÃ<vÌ‚“¨FêY< _ 8qÿFÖ9MH_sY¦Hè³^¯KM†×áf€ªaã;dºø¼ìÉD,i.ìÆBΞŒ7h½ªa=>Î8p[㇤’…Í™#€üg1j´d²A_7ÿl6¾2zX7Yú€.ËÈHä÷Ã0¬T*jX(%¼ý{ĽQ9HpvÉ5;¶+d@÷¢†m–Á¨=çnìa 耒8òí6K')ö®9¢Ë‹Ð%=©-DžG¾)² 8ŒÚس IC¹\nnnŽÅbI'™4“fÌ´B+N¯K¬[ᬘLTJ­M®}=óºÒÕÙ/ýRú¥Žã:ŽXyDÑ)¾ÈûÇm=†˜¢b ®6…BA‚_>Ÿ¯T*’™  6ü%2âÏ$£Çlñ‡Z •3h²þ±0¤¥Èú]™±*ä•Ñ}d±H˜Çˆ‹a1JÙM2BT­VyÎÂJ)û›¶;Å Ž =Ð{uëë•?ÔUf°‡ègóel:À©Rä6¢R»|n,KùÔ—,Z™m¥” Ñab¡¶JÿP¹N ܰá…f® Èw1â87ÖËùÁ“Æ:€R${@á<â³—#·±ÜYÆ\‘¹›—pŠÇ‚*T±»b€ìIÀhzH‚Œ$˜(mHܘû�  ÄY~Y$bl:±hŒHe3—a´”Ô…r£$‰ƒÚ ÒU0&Â0t'“Ɉ+¶:ºM,À8{ž"´(Rqgš/©Ÿ‡‡Eä²¥w=äw¢k¡ =Ï;­û´û¸~cþf}óœÊœ¬\ÓírºîOÝIç%™)™•‡¯h(Y¥/<ö…7Žy#Ñ“ã@àJ¥"gP¥R‘÷•ùP|R9ÓE š}@—òIÕñX9O‡H6âN%´èØÊ$u”˜lмAV÷D¨½`ú)òúdn¤²bA­ÉKÎ÷}ã#ÃÚb ÙÏ„ž¼#<ßÊšÙ2pÖVÄ%ë$RÏqC{t5ìEÉÕ± zÆõ pKVˆç‰N¦¼ ›ëx54‘I¤ç][$syâ>Üß»ÚÍ?BÈ1M3—˹®Ûßß/GdDySiN¨¹æà£çx°J¤—À"êLmäÊÜS莰ê(öž(³ý(jògÁ(5ðM9)âñx.—s§§§GRìD"!f£r èBÉÆ“.A—9Ð0Î- ñx¿‹7Âhà!SP–™Î'C¦"W…¨"5„¶U“—•ÛëU©ØÐäÀœH$ššš‹“9Ö+þ늜ôƒ»a‚7!¦6:;ãö.Ûh2쬽4³ôï˜ö¾ÁœdŽïß(7¾²ú+ËN]Ö—è{vö³ ÞY€û,&>C¢Ë ½�v†æ@ÎÒý¼üpz2ƒ!îÄÄãq¤º‘W“ðÌ‹ÍèÙàéÈJˆð$†¬Vüij6M3N dÍ ÁL€>(9¡X‰Çãò²ÜC™‹EÎ2ÌÐü–G‰­ÇbÕ¨BPâ#Ø ÓR$ÜŽv&‚n„:Á7IòNö˺Ÿ\£ŒÎ'`›¢†…ã@aEÄ9yeð50Z„É@(—Mcô=ü%ð:Œóx+²Îä½$«ßqPƒPç6 át²ç9hEÈÖ²iå|²ÇÉ&"»µKì‘W¶%§®P€F݆e‡ÂDþt:=kÖ¬éÓ§/[¶ D2ü¼8 9H±Ù<¯†ýÆã>8Z[[{zzð¹$OÄào‘ÂTj,|:È>J^/ÇÌ™D�Þ|±"áz Ö3c³¶ÍZ¾÷òÃc‡_µùª;¦Ý±&¶Æ¨»b»Î¨ñhâÑ^½÷ðÃÇíwÐêƒî;æ¾ ã&ühåžølÑ,Z–%Í�ù€F£R©{[n¾¬¹·rÓ’É$Z€¢pÏÁD=i„ÈÇÄ!Îàã>Ðaq\‘»ŒïûÂ|ÃÓDw Žyü¾8æXЭ>œ¿£e@¹3 Ž›‹ %c�Ò™ç2 46Y*|»x\˜ˆ *`¬OÖž‰ðÇëÃD3ƒÒ,Õƒ÷å˜ ×µ¡A="Î'¡¹Ëc⥠üy!L}Xdz,äì±/IáádEÞ0LUdi5yüÔÃÄ l0ä”GwûNMl‹� $ÍYÄ Ì"D&¾0�k‚ò —Ý_Ðuäê>ò”®ënÙ²%ŸÏ‹E æÂP@fd@‘V&ÈsVŽN¯mÛhÀb.GÄMMMÒ'gê3,Ä`¸ƒÃ*ƒ Œ"J$–M)ö8Øì^ùh"N!œòî)/O}yEnÅ ã_0usúàôÉûnÛ·/¨©êØcÝx¬·Õ{nÊs¦mxdð‘ì¸ì¶Ä¶ºVïlêüæ¦o–óeÇqD…SBå86 CôT¤Ú“2¤‘¢~Å‹ð$1F*€Ÿ(2"|È,’Û%ô6¼š<)dè’S3I$2üˆ4‹ÓsföË©*¹<>)krUÇ«Bb­,-QøRÍ“Î<¿Âv¢¨c8ÂgÆ­ŒêjwÝ­F6º\Ѐ‰€¸E²P K²Åð/ð@DÀ‰Ì—cU7d~P�‚áæôXÈÙ“½(öGÀY,AÅÜìaÉwyAdR5_åÔfÝLàÂ,Š, @-8?à4c±b« ŒìyázBîWrîi4Û¶mÛ±c<t¡÷ÎŒÈô+hf,œÃÍgDLêàÈ“iÿl6kY–ÌðÌzààvcê;r®±5Î/ÙÏ–J6¬•J…Oy}‘v¯Õj@ääpIé©£×Ý­u—3å\SήØÕ™ÕUSW•‚Òçú?W.—³•ìåÇ]Þ﹨rÑkÉ×^ν,îŸ_ª}éÊC®œß3ÿ¼-çÕª59ÇE;§R©@8RʹárŸÇA€ ¤kXB§ãómÁ9 ÿrLFÏÌœ€ra¬S š�w°á¬ÃSDgñaæôã ¥~ŠG1¯¨)æ%%äH‚‚Z Ý#ð,@TCmRÍÜ`Wd½Ã|Έ’/S¨¨ÀÐkÁ²dQ(N8OÅÛIàÄøîì*sC4~øöBŸA G$%c!gÇnÀøuAä$•Ϻë,þ/Ç=�. ®ƒ˜ çyœÈ¼V þ"{C$€}г¥ ÝX´Is‚év <�Cƒcö¿¤f<«HB M ÉëK�“·@½ju¸ÉH?å~Êÿ … r¹œ®ë"AáM t›A®ÃÙÞn/îìæŠÅ¢\s­VK&“ò¾òà$D�”+·,+ŸÏk}Z²+™kËApÒ®“*FeÃä ?mû©jS¿šú«ý*û-V‹Ìskç¶Zß2Þ*êÅééßÝùݳ/Þ=óî= Êéò`ÿ`²7Ù¦Úå@I&“‚à•ËeÛ¶…Ê%.ÁLD&'—Ëe|yX0_aül„|8Ç�PE „»Ãä¼ÚÝ�'/ë³q1!+6Ï £œ 9"¬IpLðÈ"rÑòPàˆQe¬ay)X¹KŠK’'ŽÄˆ#,N™À…Z.+:3'B­0!™>®†‡m­Ÿ‡ˆ�äÉyÊ‚Ù,1Åqùuud€RtÁýdýé±³ÇÒl%À˜8gÙ @E¡819–ùÁˆ\9Óò»\EaCJ_!ÒãeÖ)Ë»±D¿ì 6]ØÂ,5¬Tµ»ZF¤MÍ­ÅÈ5^*"HŠœn´÷ÜO8=óï%X†‘Íf±‘˜t€g© |ãÞ5ÞˆÁk´…¤é-ç¦ Çy ƽzñÄeÑ“–8úÅ׿øZõµímÛ7´l˜èOüäà'7f6>â<ò õà•å+O<ýº¦ëŒ¬ñ»Ìï<ÍSJýiÒŸäJŽÜ|ä~»ö›·jžÔ‘§Ì§L<¯T*`Iv/}Déù!¬²0×.øèh`™à« Ë€Mðèã/&ýC®‚›@|vË@ù ­>ɺ`7Îâ‡ü¬e#Àª'bKƒ^Ëî±ÆO¤pÇß%äì“ix¬e 'ðË‘äaWrØà±6!¦bþÂäB`dùìÒ)ĬPG�ûP·R£T ÆBΞù‚fx„òÁ¤It±Ee ú Kà3’™2XŒÄ‡-˜ŸEªyAL0vÇõ �e†ŒQa oÉ´ÿЇĖFí³Í8ëYàíÖ±£XÔ„¨"†rèQáÓ¡¯>88ØÚÚ:d–CÜnfô‚¨ƒî—”}Üg†÷>mÛjI-%o„YypfPI(r$K$Òòš¯Rêù}ž¿ó­;kýva}a·Ù­‡ú©µS;ÌŽË*—=žzü5çµ×ÔkWU®Za¬°BëÕø«J©,eK5¿öôaOŸøú‰‚°É&7³T*áÝYâ ®Ž°/í›azND‚b%2ÅÉ3aÌ/gÇ?ðâäñáÝѧd¬•ç�…ñâá¼뙹Žòg.—›9sf>Ÿïèè¢ ;Ëc´_€"iW ú@J™õ yÌû»ŒÍ˹4gÄk>L¡q.Ë—Ç\|Žy¸Ã< Æûµ#X¢¯Ê, æšrDìTÿ?㕱óߊ­±¹*kEŠxH² Éߥ%€Eƒ•Çø/0&\ñ¢çá.Y€òã¼À̶¤ÛjxÚT2>9¹˜…É“kH<Î`®i&·["«Ÿ„UÆmx+";Ãl\°ù1޹?•J¥¿¿5†4#cªB¢…^!ßC¼ó&xžÇ…gˆð_¯×¥¥/`… F@Ó„ri®`ÞEPßò÷_{çkò»7¶Ü8£>cqiqÉ.}§ö3sgî2v}£öc/žP;a‡½#ÄÏ*Ÿe…ÖãÞã±0ö©OýdÚON~çä¦XS*•’!P¹!ÒÛ Ä?ÐC¤>ƒÇ¹ƒE­7ìÄD*­Às‘ÙHÕ(ç¯ô&QÓ+²–‰ÈbòJ@½Ž: R°r’×Çð–”D¦iN›6í”SNéèèØ¸q#šÈñPá#<f £ èEÄÆ-Bí·Æ½IÖ‰çHÏ%Õ{±–=9‡P»+£#Ób%=ä¾(ý¡¼‡=ν+¬‡±³çCÎÿMÜ[ö‹œ£‰0v™dVXÄ&�çÎGf²±?4q1 Êµ?êe`»’TBpWí.<ÃXßÇš20úÄãÜ,(á’2:@‰ìRž—tI{å×™mÁH‹ˆHr‡K(³B+ˆÅbò'¦±Í$f‹Eß÷«Õ*7±Ëå²L°‹çy©TJ)U­V%GFƒJ¼D{2=Sº§èº>¾>þâþ‹ô¼¬í²æŽûã÷¯7Ö7MZ6MßÊ~ëáüÃ?·>O›g†æÛ~xþ®óqÀ/®_wýƒ'>øÕÕ_r`>Ÿ—õfôó ,•JÒæÁºªÕjâ Î,c§Â—SÑH Š]Y*PK’£Yº‰B ƒ,·ÐPz²Æ@i6¤á”ù–¼>8f<G"ý˜?üðž{î) ‚¢_ÈDÿÕn´Ë�f<²åç1Ó7x£ž†Ôn̆à»To#eñ ¸—Ô a�›µ{å– '\’<b ðøö¦#îˆäz06—³çCB âmÏ*æƒ(›䕊Fù"â1lÉ¡�Ê3[EO„ýˆ#ÂáFÌ@»Ÿ „0BEåypp¢iš–L&Óét>Ÿ¯V« k#~�(Í;bN'@Eˆ}™D¤g]Qð8kôÁ…‹L‰²T+p6hÏÈÿbJo*÷D6|"‘Öqù¾ìdÛ¶›››ãñ¸×u?ßóù¯Ïüú)ùS–íZvcîÆS‚SÎIŸsœ{\SØtZý´R7<k?;%œr@x€ç{——/o$†id³Ù˜Ëf³BàNb [‹Å¢è Š,r=ÒaiH ÄôPíEhò˜ÀAˆ>?%ž/¾Ü‡�vAoàvÁÈ^p\¿rÈÌçóù|>ò¦2qF¢ýòPx¼´.DSYøN΄ ‡ÈŠŠœq-6àa­H~ðÇá Á3‘¡LÔ!kd“'®¨°qD¯Õ4�0Bn h'ÿ‡»%…œ=VâðY1è^�Åå¨,(V�=)2äì^Ž9´Q»DX•LëD^v¾¤ê<8Íê×\g  qYV‡“„K’Mˆ=ËÇDÏHÀ(ä ‹ÇãÂŒyB§‹G瘄—eÙЈ¶"G î7ðàCêrTAþ�þ¤œý±€r‘x€Pˆ»ÈTf&“Õ�$°§¬=åþI÷_°ñÃ0þy×?ÿ í¹\<ù±Ìc®¼Œ �� �IDAT殊­²C{‰»¤Sï\o¬?§vÎPý„š¦iJ‹Åb¶e755IÕU.—ëõºÈˆ:Ö¡ÐÒäÉÊ‘k; üÀN9݉°Èˆ°×ÄP‡Ú?† Ï„×�¢|’wá¶¢œé¼üÀT/âÖ†cy Ôˆ•Aà ‘Ù&Þ"E?“•e]±¹¨_ ©²“› ¾ˆX€¯Ù’ñìdÄ3¦¼"‡7€Ȇâà˜<Â:C"±!uÒß»ÒÚ?BÈAä`r!ûáÞŠÊgª`Xf1Œ‡ÿ#f…¬•Ä(Kÿ" Ų¬T*åy^¹\æ¦7¼ ¸mƒ×TÃR+¢, ‚“ü+I³½GÙQ¢9˜H$„+%B„«(¾«@±aü…JR4}¡Ï~£ z²BÄÔ �  –ÈïЦ’>M.—“©ŽR©Äl(ùìò+¥RIØÒìv@†©TŠ-5åð±®ëÓz¦Ý7ë¾%¥%®ïÎ׿OѦ¼é¼yMë5]F—ê;ô¡^’ºäß+ÿþlìÙ}ƒ}}åo07Ü’¾%TáË?¼=wû 7 ‚a;µ|>/N§¥9'ӸЧ(•J†a$“Iá³A(‚­±>ŽQ°˜=ÆÝCèE㌠)Ë¥rsí@^l ‹M${ ðj2Yɲ´ÀŸF`CBÆx/ÇEVr (|cÑ^H¢ÉÑLMDY*lÒÃc¶WTò¹X®Ub&iPlEÀy¹¸Ÿr—¸‰‹Ì…#–Œ=2�?õqác!ç¿ïKø¯‘Ayü’<2¯Œ©½Ø¥Ìƒ‰ :"Š\f9 c2KV#!Åh*“t]‡(�K†DJœ!k©á¼FÚÑòw¤örX€‘%—N§á5)Ç4XRy»®+²crd�À}Ãm&à |Ìa#!«…ç ¢üêQKq€Ä!’H$ g"LáÈGÆP§ÍèaH¤‘X¹\N¥Rr£dö²›Ü“x\(¤@,—Ëç?vþ 'ßpè®CöNzɺ_»ñ?þyŸÒ>Ú~ÔüÑÊøÊ|ïÑz^3^«¹µŽFÇÞºÒ{TO‹j™üØ{Ó8KϲÚû~¦=Vu§»C’N !$A‰azE&E}ePˆ¢(‚ ¨àŽ¢ âñà„ pÈ rD=G)ŠÌ!LÒI:Iw:éNwuWÕž÷3¼VÕ¿VÝ•÷«uàWõ©Þµ÷~žç¾ïëºÖµ®µÒûŽ‹1±V^2:ÈÚíö`0Ðwâ?VWWuÖïÙ³G[žçå<Õe²¨ôUyQ£ÑyÒ T¥Lž*9 ŽW©AÞI¦:ë—3N/o=\Vµ×ÔnÜNéìűÒ­I¯h¥ðWn› rÔæYš¬Qð[Ö°ƒ´.¯à5wÀýÝ„ÍÿÛ*(¨#‚¨;n åU_’gJRK̦‘®Hâ²r¶ó‡Ã×u£”ÐãMX—°„"‚† aŒ†?G*s<lfw×p*0‡² †çÜ‘ ü— æìa2š¨‡¯³Ò霣Éd¥¾€nNd_ÆiEØ£6Šôf"j†ŸM8»Â®N:ÎJŸ£�xôöfq:ÔèôêI¡°"×�º>º^ÐŒµ  “NæÇÒ>ÐYд^þ‘—ßpñ 9ï#Y’]±tÅ›¾©ßï’ÑÛ|Wë]Z^Úziáã­‡Ýk+äÑÓGß˜ßø‡Ë8Ëg[Ði ³VkGÁO!G§Œó&¨ÈõJf]›Ù·7òÎ@/™rŠÏŽÁ&‹# Ï œÞæ4Eº.3èiÎ%ñü .%|K÷â¿Jd([,‰°YÖšÊI=!ßÂ.Dâ6ÞZ„”æÁäæÜÊÄ‚Lpí‚–çÃv~8)÷Â"Ö{rlIŸÚ 9Û<šQVˆ1$}ô±ÅF%êÓŒa•CÅ æqëz´ Ûd=%l6ŒñCV Ά¶ÊùÐ¥³$|•}èd9ÚÅ;BÓr’(ŇtÀ^ó¡<À4n‡·aq¥îêaN&Ô[é và‘縸¸¨é}ÒdÚuš¬TDw!»ét*̰ßï‹ ’#1Xë‚0·»ï¾»išËo½üÊ;¯ìõz­Vëdyryy9ÏóýÃý/<öÂ# GÞø 7jô…'^xAyAžçß9ýÎK›KÓ"EH[s!¨:ßu†Ã!º·j·êô¼„©/g¨S#ò4YÒΠÕj¤a@i⎾–À£ÂI47ÑaRÍKs8u®›àªhÛ8M.R[gŒÚÓHVí•à¾û>uf#ñ�ê?7�uê„—ïîV@óR+ð©ÖcrŠ¿£)èì=¯âñ¹u/„÷ä&ñîYÚNÈÙ¶†BÔàÑ"`Ã2õ Ρjj^IÐÄ»òc4d© lú†AVKç zûÔé.ÈæÎíŽ-D2\Œ›8U)˜=ù&Y¶Àzs€4«#­·Wñ7‡(…& —OBMVHKÝlÝF5ÌŸ—‚c_*ãM¡ ˜á= ¾žþW'2iï`0Pæ(ì^ º ¢¨¯DðRFËË˧OŸ>;;û²=—]1º¢·Ð˲ì¾óûöÓþÚ°p6ÇüX´·²,™ñғ祻ßïV‡Ãa¯×ã8Bëi¾kp·”èd\|KUçñÄi-fé58“:5€96¹x} ÅREÞT‘ôŽ“ò©B8ˆ úôhÞ r tŠÛøÂ¨½ äs0hòz]ÂA±•½í ª‹ÅЩž(›x  ¦Kä®(è=Q' yS§Cûm'äl}� /ŸÖ¤%î¬PWp&t4У,•• g†¬J€‰ç5ZÃá†r°:U£Qƒ­_#âùÐêðÝH "#í‚ä^¶ü“[û ûߺמiŽ-�ýéÄWzÎ<¬®,ÅUsPÒ‡:ÒMTÓ­v˸Á`°k×.zÑ‚pÞ¤D£J ¦×¢7 ½^O8ƒÁ ßïkø*­^)¡6Î OØuÓT9?:¿Swʲ–ÃЫ««zCÜ‚ êüEMta>õ,//ã,'=MíŽè¥’Ø—LèÅSKÝE?õìd¤Ö]‹ˆ:*n´Jѧ¼v!ø<YO·)ßYŸ4’$‘›–l–— ˜:ÜçÑ+R¸ñ15{ª*¶:p»)'³Ì¢«)¡TeE—xP'Â1cÙÇiodtz¼ÍÖêJ-ge‡Ô=Ç®AçÂq;!g;«œÈ„Üù£T-nJˆiõxƒ8 u®“J•Ò‚ä¸k“‡ Fjüì¦È`B…‚ ÜÖItø½r§Úà{:žã å9Ǩ.œ€“žÁ @í£u0ß\ð:b†”’Œ«ß@ñ±zÜY‹–/Q*’ ‡üãü]½X Y0&ÝdÅxˆmt›f³™ºúºj½›Êõ~ô¡šÄÔôw›ƒ×‘ªSl¾þ#™QˆFŒ¡Ú"Ò6¡BáGZ[Ì35L£‚›©hç¥ é r™úzÝn÷Ì3ϼûµü¡7‡ˆ®R­&ZØÞèv6O +q´ˆ‚Il8kŽýÛéttòn5gŠ"GDêAÍp8l6éq¢‚4ÀV‘œwkˆj,ZWyàõ Üq¼§ VAüá£]@È%ê£ìs'älç;źä¥SÈ|ñyo†™¶²Œ°p�Q¸Ðâ½|TÞ¿ MH¯NÃg6†Q"oÚ?>ï1< ‚.镇š·Ð‚)žù&ä„õ<iŸ»ñõÜã$˜îV0ÿTbƒq¨q ø¡ûâN‹Ä¾ý|p 6¤t—Ý—*²x0ŽÚ`'Hû˜*aU©%] 1Ü”“Þ¼÷æÏ>ì³Y–9;óY×>K¬ô~¿âǹ «;’݄ܥ_b<RÁI’d8ªÇ <=ž”àóíÅ1V50Ž“»,‡wÝuB^ø†©² ›§úéGBÂvÉ%!§ÌàÂÇZòæ(…/¿g!GEìg]B;ΈsgB—Ša˜Œê©ÜHµ±]7V” omê ™äsaT„$Ž·{’D¼6NôÕ­Ã~×%€·rv\A·Xó5½Õ0ÑéŒ|C9ÐwR¾F;”´N‹¬,ˆòéåè%£öëÚ½ö’$=k4|í°÷C½0 îªJšù,¤/å`ãÊ.]îâná¥õ­Oq^sgÁ"z½õ0½ß¢­f'ÁDÞ8£±PN'ò}î`0p”€Pªx ¤› wvqqQñ^½MybŽ:*g7nrÒ[ã) O©™ÿ¢($Œ¦Ç1™L†Íð=ÏxÏù§ÏêuOmšf¸{øªxÕ“nyÒ÷Üö=+©îqQýf<«],Ö�!|aaAJ<@%4ÄÑ*Šbuu•a´M}P¨ ’ëÁþp9õÖaR OƒôXy±Ç$ÊÄõæ¢ÜøÀ}Eƒ NóOÁ¬ÆptgO¨À>%ãïà áÏI+¹? ½OŸ¡ÃàãÜËÊ'i\‘Ö£…Sxœ‚è2q)¡&yÅCášnÌù\Íd'äl3}� �Èe¾'ÂßeA¸=穎*9±“Îoòè}PSý@µë »Ööd]-¼f!}]zúã§Ïø¾3t(�»)÷q �­3Ê( Xf‘§-°AfÊÒ{g}3ÎÙñxŒBSÝ8Œ\Œ_FS }ø †öíYg5N5°éC¦è¡é­$¾éÀ ™2Gªn•#jb‹*¢3Tu¡»U2’²²²¢>“¾Àp84ªF þЭVëmÏ~Û³Þó¬3‹3U”œuú¬ß=ý»ïüîwÞYݹºo±……è!Š—®E$�ùDð+DääY IɉªÜQ;GŸ¢Gïs9.¡¦y¨oDtš'^¼fފߎVEÚÛÑÜ(c¿ú?œ˜ ·n€¾8ˆ®î¶;›1IÆl¦—¼ oz¾xJù8'бaÝõÇ•¶ÉÝê׉š@ d!zjH SÊp>‚.JŸ¨Çês~ Û‘~„3q8m ú ¶ï/&Ø"çb:C;!g› +¨î ¬0Ïٽϵ@9¹|èÁ#æóyýÄ:ÿçÜÒÖ¬Ì>™O;Í>‘qè rKÄoœaìäè¼WÓÁ\}Œ™ôÖ9Íœ/¬rm{ $8y÷ ´îaØìãЄæùOŸ>MÈô¦š7-dJ¦.·»5;k–«Ô”ýEÑï÷5JyâĉӧOïÛ·O½iÉp0én«+£šFŸ"4EÞx<^\\iíÐù‡.:~Q9,‡ÅPUˆ2͇Üó›Îºé‘ÇÙLÖãJDô€ÔÈA­Ø“ÕAO­Óé x¡ð¯6O·Û% ‚¶@¿ŠŠÈ)"s6Ñà‰ ZWžöü:˜ 2Ã: …nlãZìî‚èëSŠaøËaËiDÞ†^µ¸Ê: J;")3,IQ– æbî‘ (‘Å`v!` 4ü£c"%ÃO>›AQåb”8 §Êe¡#AwtåÝ7¤z'älg¼ñV§ &o�z=æÎ~p"£7QŒ€Xâ-™ÙÓg»Ÿ¸»I›4M/¹ä’,Ë<8 òäÓçNûŸìÓ6Л‹ãp¹Ÿã˜ú¦zA¼Ì�×dtƤ£v FßBvDNã㢿e(nªwÅWŸçˆÀ µè5Díž‚Ž3Å0èÈb;vìĉ²¥Íç$8\ûHû'„°²²¢·Ç:ßiºèù¶Ûí›/¾ù¸X,j éÖF£‡ÞþÐ_úáç{Nh‚hÎL“/ö3Š®¿Èñ^Õjý~_ÇÎ>™y»½&y‰®Ýe{ ¶ÁíqSK*ihÍü!‡š„ƒ(PèÒqª’™©œ‚ Gã;ŽUèL3œ<,]#é±ëýÀµãϯñ©58ÓnTãxµžŽ»åò>Ns ‚9 uæ˜nŽ*]_ƒIá<hBÈÍâ^ì½6˜ö£C‚;!gÛBúcŽr¸Ì‘wJpþP&Å1ÇdbÄvs6ԩЬeUûöí{Ö³ž5›ÍÞõ®wÝ~ûíU¨èl“y]ZŸHbË~ðbê0ù¬w&JDìñÑ /õ–/98Ey™CçÁ<†QL =à¹-,XÿtbŒþUa@‡éêêªæWp(€º nÆ©§ò±ªªÛo¿ýäÉ“ûöí;ãŒ3îsŸû¸¸ôkÀO5ÏMè S8Ä“F,gýgš¦³éL�K§ÓÙ¿ÿéÓ§Oœ8¡o[•Õx4n&¤Þ”@(ZH©Zry”SZ±)p’VsK,8ý ¥½%п{ºÉº´ˆÇÕ…º–üZ[Ãû.ZºNˆw� _Kº†Ã¢Èì¼J—"ô™­ ÐùL+³Øív{qqQ $i>’©°"uD÷I ›ý µÌô­xRN’FwœXH6ඪz|<†ÔC $8ÁÎ]Ñï›ÝS™³ÍQÇž‘‹8ÿét{ª¶" T¼Ë+¥išH§O[[eY^sÍ5ÓéôÔ©S!„úuñ™N1½'Ù ÉÂ%\sž|4ùÊ`&=꥓¨Rî°Lå»Y0@Ø‹Ð<B Œal”,Ü77"Òs¾DÌðj;ot9ó½z âx¾gœqÆ®]»…þ«¶àd›]³\aHU†{÷îUêP–å`0  ´÷ÔÞ“»NžßœŸÍ³¥¥%U¥!„;:wì]Ú;ŸÎ›y£z+¬‹6öû}aw’²V´€i¦¸‚™à8ŒMg³ÙéÓ§%ÃCïŠf²Ö£9”&Á,Ñ@#d£n‹lÇÂf'÷©¤bFèÓwOƒ9#À¼ˆå襛Qý$½§¦Üœ8¡s!„sÏ=÷ª«®ºþúëo»í6<È£ïÌ­ J.v¤ÐáÌ4WÇp?ÊV} +ÓÉ;žùñA®ªà‡‰Û»‘%8ªæâ4w#ÞÐNÈÙ¶§a~î8o°áíHÐÌÑ#ΛOã»]nžç7u&/„_ KKKŸùÌg0³Ìv=qW6|€°¦„êÄ=ZÑðà\QãÃ"å|ô¢wÓ_e|Žtûö 1ë#´´”}Ї;鳺ó.mÀç:7ÏrœÁ¬¨¦êJ0AO öËÓ O8òYEV†cÔ] ‘T“\“wZ’ò¶ÃáðÁŸ{ðÛêíçñü…jayyYV:eY~ò²O>ì+;18Ñëõúý>' ®”Pô“‰iÏ g ßëÖ ôƒâ82\ò ñÛNh„Þ¢ws§d  ²wæ1㮎©:æÖ­Þ"±œ`Æ >Ôåç&‰šóâàåGó ár Ê Ò4]YY9tèЩS§¸>ÙF:ETÆNÍ]ÔüÎ8€AçÆ‘^ǵˆôTl„d'PèÈ!p3YÁt³®È»š÷QÂÁ#þÿs¡Ü 9ÿÑŒµ`2h®FzS–•íœ'h¹«†ÖŽ`¬w¦ùÍùèêQþ›y¸=4M3ÿÏóòñeû·6ìxñÓ—¤¹²F {a9{ø,I’â‹ì½Ùd·ž0Ò7òÖ{’XÄ·ö98–)¸™|r(CGéÄkAç•ú JT;F‚’DA÷üðC6”ÊLz…µZ-E½• ©­.Â+wH û g&¾–ÊŠFeY~×G¾ëŸüç9ïŸDQ§z§>ô˜Ý÷žûî»gß±•câ:F#Á8ÐE‚дPÓ4šàÑ])Ž62g“ŽB}]XЍÀÝwÏÑqN' ».€wnº$¼ÏC§ƒ±Š¶œWŠ|"'© ñERö#ÔJo}»’.GÙ!‘Ò罂æ.---//s'£ö˜—¶1>@ã“g®ÕëÁä¦ÜX‹GbÞÌ€£:©u ˆ{Í72�F£çf!±r¶ùGœfu|l Gçtm-]XÉ{æ®Ô !§®ëp*o-²ÿ•Ms:¼xBÈÞ–u~³“Ý‘¥Ù†Ä‹½†«“$™>z:ý¼ø³¢ýßÚyžOp:¹fÒA?=°¡mîÃÏ÷÷ŠáF°É½-™ð'&ôþb<ä¡´»½Äqßœ›•¤¿ÒI­{"ŠCò®ô{Ƽ~T¸ðœMD !qhú+ºib”)0'QÖŇÐzh·ÛgÞxæU'¯ºëÒ»Þú oM’äŒÑOûÔÓç‹é4ÌKKKY–Ýç>÷áBbÞ2¾œN§¬Ó”ˆ€ ë9ÕMÇ®²›à”óÔàPÁQÆ-Tç©.¹ÕjQNEç¯Óè!yr›ƒ`ÎLÐ1ü=¡Î{s¯ùØQÔ¢÷GI2Ø,*ù„30¯õéÖN¶tº`¤&*EqÆ=qš—æ° |¶ÏÇHiÃzçØéÑåðbg¥ºxÌuÏÞ¾ âÍ·IÈqÕ2_qÑ'%³Ðš]Ò†EÈŒ69GdX—ŸaÆ; B:H»?Ûu\;É :9M6ñú»uùÊráq ’ÖŸ·Š?+F׌zí‰FÌ'zAæôngZ»4§2(³^ Ó&•ˆÎ0ï LFÊý‰„°>ñ²EÆ€øÎDtý'§ªŒpLBèýWWWud(Lꇨ9`r½~!úÚRw&J–#I0¦þjaiá_|Àå×^^E¶;»ç²{î ÷äûó³¾vÖh0:|øðÒÒÒYguæ™gꛜ<y’ùtä„Ýáf&iotßÔ¬"Ã@R!ªGƒY™yÂ!]$ø`:…u³gѨœˆ¬îc+te8¾±­ãá’y«ßuH½Aèš•<¸H«‰g¡g­Hu^½â¡¼#�¸wŽÓÀ\LÖUÛ¨±Z@º\YÃÅãiíh›+h0ÚY ¿Ã–IjÝ7¨CDhD*§\¸Û]vBÎvø'�>Î#“áAí.’‘úè¯Ç‘¡°¯ÐBço…˜¹‘ŸC%Ú{ê$Eqê?ê|°ã5þÚ!þ·­òÇÊâƒÎÎHv”Œ¨é~Ø€ +ÄAçS£È5µ¼vÑQs‹Ëg’T§?Ív×X‹¶•Ú»þ‚,ÛB„ŽìÞ©=D'»’_~Rh|GbŽ]­ P5ù5]$¸ì¦+oŸ=®Š*˳ÂGXøæÂ¹_9·,Ë]»vIk ªªååeç‚CBsv/ýgI'è—‚'´IïŠU4ð¼ÞåŠà 0¨>Ã’b.h‹‰wsr÷hAþÙMŒÂf‰Ì°YÞÐ%‹\‹ò•tРǾõè“CýpXÏi.~á|N¢eé:Ċ½ûåbî­î‚iÞfÓ+I+é¼FÞq¾h¡@ðãizzAZàð†OG서m¦¹³†Ç[Ň(#;)àv5*�Á\Í¡“rÄ»ë¤#Ô‘‰XåÏ”»ž°« UQ{÷î :¼ÚïnþjÐúP˽F�ôœÃC„ðÉ'žp<,EãtÂ#DFæ~Q) ÃH¿×Ç|ãñéÚù“É„„ݵˆ4üAš ‘ZßA^Ÿ~·}x[Föä 8AÄÕ?A9Cõ¤Ýnßþ¸Û›¼9ãæ3.9t‰ú7\réûžº³¼óâ[.–•Žó/A—Z9,¿ÇÈGJ<ŽO2g9‚+(FÔž£7®œìç’Ì$F$(¨HY»ºïÓ.ñ‚4§ÛºÃ¹ŠNä°Y^“…Êròùh§·1“ ”÷áý½æCx¬‚UŠ–+Í-¿w0!Ýtû§˜r8¸«½2¹OhºyGX×¢öN*¾½€ÛdHÈà’v{yàÜ 9Û\å¨E`œã ÏhtñzŸ9 lë“ù„4Jf-yA„8•‹Ó|mÅWk°Ø¾}ûÎ>û샮ÐM  !·áñM.å®ñxL]ïƒ5~Ê8ëÚãk¤?ÍÁê¥cw° ËþÆSX¼ ð(A¦ÉÔn·õrUÇœæK“€ì^>0£é¦F#õ”s ‡CEwA¦|[â¥ÂX™—G÷½ð«voêžhŸèõzNç~_¹ßìªÙø~ãî]ÝÙlvüøqaeœ\Lcˆ«æ3}zs)°yu ©YR‚ŠgE. â~Èf`ªt2P2Õõ³Ô"=‰:hz00*R¥ÏätQ¥Hµ“ÓÙuþ)ú]ÉBÍà 7“@å©caÞÒ⦙ ;EÔ\ûQ?ñ =¯‚àSPE‚Íÿ+"J©ô‡öªÈSœNm`¶Ìõ"’TÔÚ 9ÛÀXÛ¨!l0l1Ù„€ë0·§r.®¬ü…ê´j©âP0í í.ù£Dí\e”UUe_Î&´®k­¬¬ÈÖemG}W•|iS›×%÷5•†ú…ë"»º:‰°�° tC_LY˜ºÀDòI’,//“6úéï¾îo^–kÚÃDpè\(|LõÄV‹xx¢ 3F5é.¢œx±ªª’ÞJŽcNØ vø±G[.ì½yoÕTóù\66½^_ñ‰§âÈ9G.¸ëbë¶Ûí^¯Çq@l¼&@O˜¿ž‹TG™G!Àx"O)ƒiPÄuަgøCUØŒ7‘ñ¸ÓŒëÑøŽ¤¥æv:uØluAü�c�ƒÕÓ=óf³ Tl.㺱îµèj4p#Á3A, t°8wíÚÕëõÄþp¾�Á†…-ò<�� �IDATíjÖ пi·ÛÝn—N˜û�‘˜Ò§aF‚Å€¼z$ÌYÀù‚OwBÎÿ!ÊMD“u  « _å„"‚£¢Û£WD_Q¿1O¡´(hñ¡Á庯oµõ”–†á9^ǯ·¿§=OçŒøè\0ÿ ãdg>ÌìBô÷Ê™aÇêxuŸì­Jº ?Ò¸<}ú´hf:¼”w’4µ”C^ÀâÞ*p*6†7üÅ2w}ŠèȈ"3Šå²@NvÍ@WÐöÁ`°i²u}ês×®]Šm¼ž€áÓ]xejÚfeeLO·WÕ(ÔºÃáp8Jz@ÿJðPŸ?Z~à~ÔÍL)9ÁŒA×OŠ”¿á"3B‹@çVE2ïCx®Í®qÒ< ˜î Þ4 [ô.u½T„ξóµM˜ ëbN¾¿ª¥:w±%÷¿(Ëryyvk0©=/g¥«BòÇÁ²!T(Þ*œþ ~àôwÉr¥\¨ž»48d &{vBÎ6ÿ*‰´m ¬¸í V€Þ3$ÏÒnDÞé^ aø3.fÃVå¥ eèþmwøîaûMíÖZY–MþßÉô?M»oê&Ù†J¦ÓLù\b– É2]à~´—ÜZ˜ˆYqø€4P¡Šm9—Ùpä²Ìå¤8_¼bó<Ú¡|¤¨žý`tHÇOU6³#œŽ#ù>§Bæ‹ÙÅ×5áÞùš¾õ`0à9.--Íf³¦Þ”d -Mü„u™Ý%·9FX9(uP~©¥¾ÕÖÙäˆ …†©7ü\·˜ƒØ £áœ¢4?â\Eë>ðÁÈÙ#1ÈÊì4E-]¨Š»>|êŠÎÓá_‰ÇÎV �0[D!½GP.&¿dlÀåÚ`Ѐ4r±Nˆœ¢™trM{tñS!¡Kðñö³m½:N˜Žð·d矴KY¯ðA}JÙ"’À̸p/™ªºlºER¤ïI‹ã__7IÈ?’w^ÚÉOæuZãLŒ–°'‰®ÊîaÀ…Ofn4?¯ã�çAÐ¥î›~”¾y9è£Ýœã>¶ ³ž ›H(e«Ô4SoÚxjø“}{‡L¯Wó–Þ»Oó!<¬2‚[¤·RÉ*Ÿ¨ŽýÂÇŽþüÑ—œØsóAgI’ìÚµëW~£s¸Ó»¹·Z®by \GÇÅ„å‚×¼;%ƒS!ôeÔˆòÞ;Ÿc˜äú\½­�zrˆÊvŽ»S\ÂUÔK�Uø`0þY?^FÐSôîwä†I'°wÜ%(ò-t肱>וâ¢äÏ‹?`Xš¦óOƒŠ`€ub�vL=mõ Õ0s㓞ÞðÈMjuÓ“†³=À*$ä>.$EâÆ`”Ì%¢Oñ1:üQÜPÇ17Påàj5¯1ëæIkÚ꾪ë¬÷&@BŠó=¢Æ3*VHp“ßrì^"‡Ëè@çP†íf!€„ÞW`#UÁÚ MÃ1Ad —¯FÑ•}]_KAױͧíð°Q€qMéž"¹7 eÆ$I²:ëÝÑ;}þé¦Óœqݺ ‡.?4]˜î½{o=©ë° ²˜¦oŽ…ZÙ˜ t»]äŒF#åXþøÓ÷– Ž,~n’³Zqw¡Å¹5˜ë³sÈ–¼U ŸÂçO‰ôàÃH�!TÅæò<,9­p…1¯fÜÄ/VG¿[šFýÕ”â;øö½¬„#ª¼‘À‘>,Ù˜>(’ñ¡™¼êòc'šêõÜÔß?Ò~ä xņeŽË‘ì0Ö¶¿ÐaÆ\Å’ÔÝgQ8R`*G0øOX7*#Dˆâ¼`Ì^1«›:4!û«¬µÔrŒÚˆ$È#ug»±ÈÜÐë'§·z±ã…MÈq9ÞÄÁ gK»ð 0¼º#SEO± iDø¹ï`—w’¢Œ[B<Ðâ]$q3d~(P4¸"=ƒ±÷ùûûûÁc‡/<|ì²ck…ošíúæ®}_Û7I6`FndļÃN¥@èg⃯aç^«NEB;Çåõ<Orª±ªnœì¼á­”h‡»~¬Ž.ð)>8Y¿Ps8Å‘v‹ñ`Æ”SN´ ¦Çý$22çE·Q AmêKÚû4z+íqò0×oô`@|u£6°Â3¿@#žÑú´†ƒ1td#(%l<Ü 9ÛSå›J£óÌTÄzäÁGz,_ö 8�Ç1�/‚ÍøyãÙgýwô¥ <zÍh~rÞ~EÛGê"Q)Ö7½ó¬£Öçæyà@(áU?âü>O�4ûpVw4ÑíX,[!f”An•iš‡Ã,ËÊG–§ùt’$É]Éî_ß­gAÝ㌠îR:úJ2âTQüÆ?Æ•rˆÊ°!<K%œs+Üc 6;ß?쫺Õäýçy_;/K²ygŽ/š`â`E)꺇r›ÆæU¢1utÔÍÒ%»èªŸ,xN›÷N�Ý2hˆyîç²N0‰ì ‰D5º ”^1�*:ý×çKø\(ÄWcÞ…kÇ|Á7à6|qýR^>a]~Ây1‘à(:äÝY¿¬Ÿû¡Úó’ ÎK:ÏJ£?§ †Íú÷(޳<ó·r¶§Ä€OöÁV$Zà§ÄraÙ¹•@*?ªœÃ©­…(ÚOQå—Mhº¿Ô]-ìÞ½{uu5|>Ì¿c>{õ¬ó;ªª² ²ÑF󟞇&¤7¥×uª“U2^‹nˆiSêpçê¼Q¡c—V¢¹dUÒÆ‡±ºuÞ…i—¤ŽFcÆó•›»e™«£E‘Ÿ“Ÿþ«Óé×ÒÎ ;uS§ç¥K]ê ß{w¯™l\²¸ÎBŸøˆÐ0Šß—¾˜ƒàŒ@r@ –CΨœ:‰ŽÚ-ºMw­Õ£ãlñ_Å%Y9{%oåã|Üôñ{†z€L*Èž¾›ô&”dèŽ ‡Ã¦iVWWñ £WGH #Ò“ßø¹ÃÙG %ÚQX ôÓ[1¸Ù€Róée¯.ºC#±Y2—‰ y÷ õ³ëù“çÓ0Í>›uþ¬“ÊÂ4ÀÊ#/ô—¤Ëã ÕŒ‡[âJ¹‘äFDªZÀÇØt>i+FÓulþ‰ž%ñU ÀGq£² C/šµ^…Ã÷ÓZ ¦)\…ÐZà8DÁwBÎvV9Ì£Îh'h3s,lÎc““$²1G‹)Ò6ß@ªÉ¾IqSÑ]î>äʇ\z饷ÝvÛõ×_Ïm÷äOÈ{—õNujòüIñÑ¢û˜nÓ4ÕeÕðw‡­Ï·’¿N’Yâ$`_LŸó~¦ ã,؈Híõ™oÔ°>å§3¾¿‡m0u³%aDÀíã‚éyþ[×õÊÊJš¦ƒ ú?ÕOO§MÓäi^ÝSíý½«¯^-®,ZŸk¹æ•«´9IÉq*HÌùÐf†ðÆA9 ð%ÛtGä(ÃòB2P~úÀisasüIÇCò<?ûÚ³{G{»¿²»×ë©=ƒ;€[ )@IZ1¹9ñk%›­SÏÔ­¥<‰”+ÚÓ|ò6›f’<‡P¤«"š`g9Þéõ4ÀÀŸD`®¥|J9}æ´ó¾NçñÙl&¿?)>YtÞÙ)šÂC²©9Y+lQ$sx\—àäLŒ-Ð�õNŠ8¨ ÁýôPõY”VyÌ» �¹8–«8[Ï›T¡*¢p!DP­v”œ"yˆYÏíÿq{(ç㊲åcŒ|êÓJR¿ŒÔy[¹ðšû7áaÏÕ{®xØ?û³?{饗9räÝï~÷'?ùÉá]ÕׯÌ</^[tÞÕ)“²išô¦´óìÎüêy÷ünòŽ"' €‰ë…¸ .ó1 ²i´Qy ¹!¸ Ð9Xã=Ct@&’“Ù6€ Ç•­/µÂxC÷aÍíêŸóÉ÷LÚ×¶“yâÁ@4äÞ†eV?lö×ò~’ y§Š®O¿rV7ý¡°yrpñ`å{W²=äõ)'e»Ý>üÄÃË/O;Óý_Ø/n:È»–SÓ4’¯Ö HÝ ðC&®CG½}1ˆÂ‘)8T.JºÉ¯MÒnÚ„¦õŽVzG꯰Åå2=»òІ¸Û…*û°®ºäÕ•g Ô£Ã_¶¿§¤IÖÊz½^ù…²õœÖàÅ{‹fÚP±)à±z‰4P¹QÞõ¤F§ùäyµ»¯R—QwCnmÞ4…›®$ÕÇþ•Br·'w–r]ÿ訑ì»ÏEQ=ûô Ädi®³ÍÀZø‘0{ÞlžÌ³³…ßY*lVq´ÎŒg|Ѩƒþ0©¼™™äI«ÕÚ½{÷Cò«®ºjÏž={öìyÔ÷<êÃÏÿð|ÿ|~éüœß>g5¬>0ØûÖ½ÝÏu5ðœþQ:}É´÷K=/Éù ¨>î»N:yÎ9çœ>}z8:ÎM0 V©óš¥`n¸šœú €Ý>( Ÿ¸•9Aãï·>×Êçy§×9çœsúýþm·Ý6 ŠkŠ•_]Ùõ–]a¶q«7HJ’a›H§Â3ò-Æ…¬«”BKóŠÊ ÄZx“ëÑ.…Sañ‹Ó}SÁ}{?²wzùôè3Žîý—½Þ“Ïó\C<1ë!fñLìk>ŸK™ÍýÙõuE?×FDr6}ú4ÿë<-Ó¦n&¿6ICzæ+ÎTÄR`#_‰üú¸!Ny�’BA2*Ù/‘ƒŽÃ_zv£WŽ:¯í$iÒn·ïÿû§izäÈ‘Á`¼<½zÔY¼“¦ºsvè£�¬ÑjòDö„vz]ü|Àu ãkú+aËÐÃ�çr<@¨p?½!x� §7ð4ò¬—g ·ˆE‚°…kzúõcm;n·?ï;ž×\Ñô¡Ÿ$I}E½üñåâÏŠÎG:å¤ô¾:Öm®¢a7Æpx—eçò0´ÖùM3jæƒùñññ/ùË7Þx㥗^zçw¾ùio>çYçÌ~bvâ—/]~ôSGwc÷±—ûñ'üøGÿô£‡J¿ž–Ú0ÊŒŒ¡prä {VÎF<ô)K׬ ë“­:]8Ý'!<]õ W+ˆý@5@Þ¯¥´N[í™N§sÕUW]~ùåW_}µÃ0JSn#cÜÖT¶råMpNŸº§ÛÁø§n£j‘`:"\à $%Ž¡Âä~“ÁUƒý¯ÛŸ¤É™gžyî¹ç=zô®»îÊäí¯·o{ìmçþ󹎈¤úÁ’ÑQì¥5óDSJ×N�}k…@IäñpVXxÁB}¢Î’l>Ÿ·¿ÐίÈ'oœœý;g¯®®ê )@`Eõ«s覜GÓ0Äojuª¤Ø”$Éü¡óöŸ¶Û½öå—_þÜç>·Ûí¾õ­o½îºëÒÒÁwX¥¬F]& ­5 %*ÔÑ7¦¾bÌšÞuïÁÑh$~Šc†^ýDð8|0(ε¡RÔ’–²tmçz’É6ºˆ�&î®9ÍcbãDúp8¿=4=¿µCΆ}ÇMïxÊŸ=e2™ÌçóÖRkñ ‹ƒ¿T×UáÖ6›�:Pæ.2:†Ü!”öoÄAð˜µù¼¹®Y}ÊêMï»éÍo~óe—]vp×Á§NÜï;îwÞŸ7¹gò£ÏþÑëëë“$YÙ³RܯØÿ¡ý‡J’$$kÙ®fÝà‡¡BanU×õ=÷Ü££>¹‚jÊ-_z$LE�ïx.ŒeŠú^@çÓŸsj„uÑC²9EˆöÁöôü©ôÙ>ûÙÏÞxãËËËÝn·¸²hl•Ó2Ôk×N¶I¶´Ûm|™Þ'Ôy¸Ú:LŠ.€vƒÆDö3À î¥4›Íš¤iò¦Öý~ÿÊ+¯|Ä#ñÑ~ôÎ;L«iU¦k :xh"’•!ªpðÁå•yø€œÙ¨6äŒÀEMÒIuA•ß’g§²‹.ºhÏž=G=vìXr<™æƒsÕéÊ*|LÆgŸÊ&D¯‰ŽNøæ7>T¯ZÈúBU½6Ëw5e"4~\R¿"C+ dŒXèC6Œµ2ùÇ¡o½Œyüé“Ày…­0&ŒÄ§Â)tüã¼$ ¦ÐC¦ÇH©ë yæe(Ä}÷$e;Ïçón·™‚ÿ¸Ÿ†>3<SXŒ²Bútò#“Öïµ|æ‹uFÆçK‡ÓÜÝ|©chi¸ ˆë¸t¾Þ™=y¶ôëKÞr`eeåàËÎÆ³…g/<÷Œç&­äó{>ÿÔÕ§^{íµ—}þ²×?ãõûŽîkšföôYïïzÂv"*v4¹âbÌH4<Ê€‚–“p9Èn:åÆBÈAuÓº§Éá"»~RxG„fòšå凓é{§éGÒr©Tq °qü‰Ç[nÕ£0“&Ç„uR¶"q2ˆ Ý¢æ£&Q6 ÷Ö’‘Û¦‚föÕ¯~uyyù–[nAVµ kßi îO$56P0"êè‹€ ïæ¤�þVìêÉdö‡ú‘uïù½sÏ;÷9ÏyÎýïÿý×ýð‡?¼rÇÊüKó¥G--ܸ�6EÜõÉY/nÜRšsÙEéèøàp4U=NÇãñ†Å;‹ùOÎÓ7¥7ÜpÃÕW_]UÕÍ7ß\–åügæíw´=0øÂ¦ÅŽ &Ù‰³*ß´@¼+Æôü4§&;ŒêÈãvð´wj26“¸K‘ö•O@û”Ü€Ñǃ"çPç[{â¾-~¾UCÎ?†üÕð««õjY–ý~¿×ë<y²išö?µ‡¿1Ìߘ«)̾יò¨«§»Ã¦Ã‚'íH1FÚù y=©“û%GÞväxëøøÂñƒþöAOßÿôÇÍ×Ë{¯m½ö'ÏùÉÕÕÕk®¹æôãOWÇ«¢(¦O™vþ ã³´=)¹àVº¼<²ZH¦kç«Ø¦¡BþÅiKøñÄ?,…Ÿæe„OBDå…‡: ­W·†oæ×å½?èUUUï¯WÞ¼Rü[Ñ:Ð y€r60ê Ü8Ù›†‡¨WÊE 0QYò_·£nð‘Ïè›cèé¹Y–eDzö íÕï[í}´wÓM7ÝqÇŠóóç“ '{®ÞCÀ£+Æ¢ô–ÐèÚ6 3ú¾¿ßyÀ˜ñMµœv»Ý /¼ðÜsÏ]XXpÓb耪šñÎ%S½¬§PVÍʼAÉêü¥üõs<ûp6øô ûÃliiéú믗CQóŸ÷¼Â!¹µ[¨Ñó ¶yÉB«Œr$ª(¸QfŠF”\m»ÇvPHS=-j²ûŸúFˆfÀ]°Ç{û^O{-î96QTë5HUQÙ8°r¶í§Ýn?âèt:×\sö^®r€T7ú„ zK‡\Ø«¹h‹Þ¾Û8M$á@è|µ“eÙì%³“_>yÛÛ¾ñìo\pÁ1ü‹'íyRyß2ûT6 Óú1õì³â÷‹ê–j:›j‡ëÒ‚fÀPô_Ù(s0m4¢úM834¡É›<nÀ Š6M3i&ÙÅÙäg&óÇÌCù'òüyr$ óMhoŽâ$BäeÁô£ ú(øµoh'ÏOÂcÃòÇ—›¦IïNwÿÜîd’TÓʇLI«]³ŽÖ”Ïo‹!í3"ì[À}§ùiócJ  ¤‚ÎD»ÝfÚF‘4M«å*?’×Õá¢0ºu¤웤ç§é<ížèNª‰傪”»ð&’ø”à,G)!FSú8%š5ožŽÒy~÷Ýw¿ýíoß³gÏ׿þõÁ`PguÕ®ª¥5¯tö¤¦C ÍùèÓ‘ÝnÝb‚ýôìéì!³ÙËg¡ É0Y|ñb}²ÎO箯6…¶6Ëîî^ùÌJö¾,üS(˲zd5}á´ø¯Å|yž&)[U"ãÀúÑ÷‡Æâ~NÚ}¾ô/a°P½!äˆ1ÅJIJ€à &X €¼ô­å&vb2„pÔ;>Å»¿¼FŒ3 ¼âÔÁ¥Eë­è³=?ÿbøâåáòªª:Ä\[ùÝeþ¥'%¯O£,ƒ0ã“+,hÎkÚ˜îFîñ¨+¦ËiÝÔùËó#Ÿ>ò‰ŸùÄl6{Ô£uàÀ ?qá‹,½o©8X$W% [HÓ4I7´À@".�cbî>à`wÓ4ÕS«æþMxD!”òùhSü{1?8÷)9UBk!ä'æÓÇOÛooç¯ÌCÍ“šÙ«gÙdzÞ{{N›q§ÅÈ Þ5¬"Ú…Sà’å$ÿßy÷cݵØš„$MÜ9ú[kšfaaAŸÒn·ƒÁ©S§ g«Pð<—0£þn¦�ŠôJØ lHT�àÓ{íÿs𣃻åîî?u“&ɳ|ôÈQ6Ìö¾aoÙ*¡HÐÂ)ËRÑFi¬)ÜNÀR2DI‡ÒÎ6ÞwOu²d£ÿ1úÌg>£#¸išêÒªztÕÿ…~S4N¬p´»Uè$‘S܆ÑÕóÙsgéíiÿ±ý¦iê~½úg«Ù­YûíìÎLgŸB¾â½æO7šá7'»ž¸küŒñø·Æi’&ŸKzíUU•fb´è™'õñ,-oÚ`®³‡ðŒk-;ËÇR'Ý…Íj›.WJNãfÕ<^)1мW¤–Øl6ÓA¯R€„(mNé ¦ö¤ÐylGQŦ”vFA·ççáW…«þ4ýÓ¦iŽ9’ç¹DVªVÅk "JØlBLlØ!Wl”\gi}º¾$+N®Bë/Z‡^p¨:Røû7ß|óáìðøãö;Ûí·µ“¥¤kÒ*¤Ð+t³,Ë”¡k¤ƒ„‹¸¨žýÌ,ì ýÛûg~àÌ,ˆáɧœ=h–^&·'d ÂyÖTMÿs¹ø„ź®C’$ Ÿ­OµV?¹Z½«rAç8y†è¾X÷*mˉæ¾Èn IVà ,sdaa¡iš'Nl¼qzž~М÷ZŠÌ�ámi±‰7nÄ0N{ïïõ?Ð_ú™¥*©Ê¤Üó§{²cYKô¡#®Ÿ-WH“—J7bñè¾´|=\6i~³É_“—“2I’ùóæåye÷ïºL¹û¸¾Z›J5x¬g`@·ˆÿܸû†nr0©›ºªªf¹éütgök³êaUrGBe‰Æ¹«Ÿmô8ß“¶ßÛÖ,B3DÜ@_öQ0×]ŠB„›ç—Á_±eh³¹žCs^û"§ävô½ÿÄ4®ôÜœÝÊÀ²ËÒ»¨ÒYs;Tóì‚ëúlÜNÈùþùãðÇ/ºüEóçÏ‹¿,ªªjÒŒÞ0êüS§9ÒЛñî(U3|\º‘˜‹ ½~Î9焎;méH ×ee;ïïÌîœ~äá£/?:ê;êâÝEqkQ+ `.hMÛ&˜ suB¹2 F,MÓT?ZõªŸî}.ºø¢ÅÅÅÇ7omN¼êDuNUÜQx¹¦ËŸþá´ýâ6yA¥øµbü†që×[^pøè@0gîhÓ:ªÀÆv®®Îƒè 3¶â™)êÑÔ‡¦�ÕAïœQîæZôr|l1 æðé †ƒ^æyÞÿ‹þZM™6!øòéÑDÊxÜ1g?»‘Â� ƽh½ÃL&„̳÷gõ}ëá;‡M» !äïÍ;ë$_Hš¤ñ:�&'µ73ÜFˆ�Ùn·G?<J¿¦w¥U]¹Diþþ|þÒyçóìtÓv–ÏÆ3êˆËœ³lØ5ÔšÞáwWi—;ÉήÉÌàmJššèåšëN”�Žó8Gú ÄI ’BwßUõÿͯZ–¼Ðõ#œqƒ^FdÏËhù˜bW0ïÝ}g'äüGÿ<:<ú 7¿áɃ'¯~j5 Iúõ´óìN:M“2©C½U~ë\ç#[ŽéÅ»wïÎó|eeE° Y3 ö4ú ÛVe•]“×ÝwwÓIZM«zµ®›5-öؽ0š"~v”âM_1mýI«;ïžÿÀó/¾øâ^¯×n·;ÖúÍÖðýÃüy3oX躮ÉwOZ/ÛðÌÆd,½.¿vÎâvÆçàx<&{'Çõq0‹Z*,8ï4¢;ÀÈ7ó îD ¬_ì[>E±Gvœ.?Årõ£`3óÀëª00>ˆæœœÜ #Ü•Hz½ž÷“^!¹†_§»@Oç€Ú£L6I¹Õ·ÔåeñÙ"MÓ¼ÈëÕº™7U]a!±F²“)¼çO§x¹¿LîJªÕj÷îÝ~ðƒ§Óé 7ܰ¼¼œ|3©Î¬šv#V¤2zúóÜ%Â�, ¨ Ø':aÝE’8âÕ®£sb4aÉGzyˆL•QµxÍÌxCŠkгøiêh˜L·Èc9}Ÿ\ö-ƒêã¢ò ¼á“>¹QÂ}°\tc'älÏO¿ê·ÞÕÊß™Gè™ëÖ`úéŒLv&”|fèÜkv:Þzë­‘¹a„»&1µÈd2©ÆÕh: !„:¸àqt”;×S¼Xhid‹`A0†«ªjZM=®Û­öyçwÁL§Ó£G&I’—yh‡,ËB¹©ÎóïïsÔUU%Y’MúZpmù_§lÂÕæ—Ì( áÎMŽî¿&õP Å‚š{î_Ø•ñ�²œ27Œ ä_)é@èð `ª*Ì¥; ïŽ|‚•`<Ò)ѵTœq«#Fw k�„à¶_ºÔ!<„ ׆«ò$¯³Ú§}ÆH²o.–Ã9+´™N]uÝÔiHÓ4]XXøÎïüÎétzðàAí‹2)õàbÕ·ž—©BM’œÀ0[�� �IDATDò?$|>Úâ £3P�ºÉ ½ãî$Žj"¥Âš24‡I†|ЕB›Žù0º8”/ ±ús…O†�0Ý ÏçuZkqý¦é¤˜o·øÒm%¾ï„œÿÐ/u#õŸöàÔF7SkN'{$»â¾³èˆ°u±ÒZwØÃ1˜ãrD Ðæ”Ç[õ�ññáÃDDäyÆd-\ZZºûî»Ó4=uê.#Ng6ŸEj‰·tÆ??î¼¥“$ÉÊÊŠ>«(ŠÑ/ŒÚÕvXÆMM¼}âò3Xž¸SµCêî~íçŽW0|ah?qÊ;§$SÑç#‹S’)xú$ ?>¤É3õ^²Ä>j5H|r+­p3>ÜÃŽ£œ÷Ñ7\YYa¡zý­ðWþb¤g6ÜûYŒÿlQ=¥jþµY^^þØÇ>6G£Qš¦åcËäº$]I“,!`¨+’ãd ;S‹—ù‚wþH8\mȯÅl¡Hwþ|y+AÓ®Küð<·x ïèõ™W¤f!Xû9€œ¹€îLÄ€î9h43ıãUøŽúÀö‡æ9—Åô Š{Nê#¾ BoBF‘ë>› à H³ ¼Oîø>x: ¯ƒ¿¬{&¨=rÎ¥v‹·Ó—M—_¹|àÀáp¨É¤ªª&ÿeÒ}G7«³~¿/ò.@Së­Ù§fù_çXs®mž«ºï‚ãÓeˆ5wÒ½Õ½Â'ѳWHÞJ{#‰ø(\yq@‘`¨ØR_vïÔ`ª”ì|pú"‘€Š<t‚¥‹BòK޹Ý7ô ¤Q…Ëq¾ÐëruþÜb Ywbå6úñä¡z«¹-“«(¥iÚþz{ð˃pFŸ:thcY>¼)n*šå†’Âý]€°Ä~&IŸN§Ø%vhîÕwP0o o¿kS#7�öåD„Ñü¡³ú‰W$Q"UÛ>wL2áÃà”Ť³Ž…êkˆ½YpçÆÝÇÁøÙ�ÈQ(rÉѳ=?¸´jÑû ‹ "ƒ™œ;뱪*y´Ð+Öófœ¾L­�DÎ9PH8¤¼S­\f«<pÔÃô!!²uwÁ«q;º=K’d|¿ññSÇ'·N:ΤžLî7™Ÿ;Ïÿ-/gåù矿ÿþC‡Ýyç\N÷ÅÝåO,·ÞÑ*>[$!)WžzÖ©öÏ·ÕKw2d æ=3刡gËH#TfŸ7âLÔë£c‚!J 6¯6|^‡ÚˆBž='wåÈÓDº™Ê(×¼ùá-4.™dÒYR ˆ´ê—4- 0(�c¶ÁÚe³Ý¿U«Å9B ^Ìš$Lzf¦ÅȰꯅÏo ¯&+IûÚ!„tW:øƒAñþ¢ÿñ~ݪà ƒæÇÇi©0 ƒ¤‚W<ÞaÕÎu;sê¥>£­±¹˜sà+¹êdeâ抑-F* 7ˆ‡ïòsßËî?牶n¢åºðÅÈ•q`‰<>vBÎöü�Ùw»]H”$ËäÈÑ H07jgWEÜ4tiˆ¹ÀåP‘á•V-ÓÚ‘ñª$4ÜÀí;}ô‡Ö7”ʦiº¿Ø¾i:]žžºñT¡é5³‡ÏŠ÷éWÓy:_^^VWɳë³]OØ5ú‰Ñè%£$$Å5ÅâCÓdÊyŠ)`ˆƒZœÂw<r•÷‚ÃGkIf1%r‚œ·dœ yO{’>Š,*‚‰¤ysg™°é G!ëâZãЈ½ˆ!á€ÉFGÁëžÚ~¸u¶I˜Œœc|bÃe¼)Ê}¹:VæÝD„軸$DÉ‚©†’YÒþOíæòfþ²yHB:L¿Ð4:FnFNHþy|Dî´ž¬D6EaÝQ‚ UÁÆ™5|–‚™£y.¼æìüU—{m8&ÉéÖÍèPw&uˆ w\e³k‚<›Å†z§ Ôû(Œ) 2¤ '­øØløÖÿù–·hÓ©DaÖyö$J.nDÐ-eTÜ‘99‚KäD‘È«¿º¤BÆoÄõrvÃ=Ä-&ðõǾêþJ·º¤š?qÞ4Mr:‘¨v“6!„¥¥¥ååeʸÒÖ;Zé߬£[a#¦Òçr|œ6˜Üµë8ׇ+„œ¶@ÍÁvr!mpQ%†þ¡Þ%‚cí½ ?}(d7Ð×]Íð•CMœä¯ÏëQ)Æ{Ïo¨è¥8o ™î’GÖ„»êsØÊA0ã{:›îœh)"‚–O®D°0¯¡è\Ó'½µÕþùv´Å€àœ>@cÒE"œÖ¥-]4šbÈ‹cÌ«øÂ^x³ÇתÄx PÇ¥™Ks;5'rto5•/*› š¦i²eÙÖ˜A:ò<* ûï]dê)å½—ÖâQè |vÄ­.m;!g›ḐVp{W êÇõ“‹gOÍ鉥˜£‘G'ÛôÉÅ@×ø2ÎåœõýÏèŒÖŒB¨n. ¼Ñ4º©nݲ&a™‰ÇÚ¨,|IE=)¡ E@‹R<?°Üj7Øl6ñ’û,N ¿¥Àth£9œŠZPQ£„?f>ƾj8¿|Þý£®^0ºz”]Ÿõ^×cj'jó V�/Nß¿Ûíú˜!+¤;V1Þ(Ò±ÕétÈÖù[ŸUò¸ÂŒšÖÞ={š¦YYYqoÕô®¨ŒÝÊØ¿ V7?2ûkÃiÜT“ÑJóŽZ”ú+½Çæm|­F÷ªñ!°ˆ’ê Lir % 3â¨Ûó`sP–eõ¤jòÒIûmíοwš¦™üÈdöšYïz.§íêÚ”>Lz9q‰ þ…ÝJþÊ)Á¬·6…7‰vîNÈÙfú€[ÈÉeoÌf3À†:â-qLaÝ“FËEƒä)t}ڙ漋¸âºN«jw5Ý7­«º.ëüH ÍDE©qj0Ká,2xNBçÆç.Q»QO›Ùoê?«÷¹3‚ ƒ–f?=WŒ'¯Ç—*“Ì(C-œ­DaŽ<f¿áò©÷ëû–ƒ�,ýïèÅ£ìËYçµ0 Mh:NçyÉ÷OF/µþ¨Å×Þz~iI¨ÞÒa!©Žx—« +'Kзåôt/z?®ŽÃCžÂS#h9»å¨/<c`\‚<þr<ŸÐ%+Ä $äH“͹‚NÜàpÛоK8 MÀ‹ 0Æ_|Q!FÖ sjLÉKG‚ÅLo¢’ˆô®®”<2ýŽtú´éÂ3’Yššÿ[ÞjµF-þÐ"³8.ƒË½¥HuÜ`c¤>0îRîÎË üH DwþýŽàÍÿØ¢¹ šxy“¹V'ZŸžr°êtpR?Ðgñ>ô‡1··“<<}žŸÖ×MÓL—§óëçíÏ·“ÛÄÒèóÃ+B¥™L ë:Œa³õ±Ó;4ÿ³àÚVø°y¾I¥E-Ï>÷3…ÝKXY¶)dýt¡”G @ƒ“ê)À/j³;©Oß_â•.ôL.ü°<§ EÈçY%­5ëÏVÓj¾Ù$—$ùùyu¸r Sˆ†s“ŠÊMà;¹—¥·a mÓWw ‡Ž³{kÅ!Jg PR8•œ‚žTFW'\¨ZÿžrÇq*K§üyÒ@ÙäãÀļîÑ‘ÐË@.ãÒ8¾~œ èT4OÄKô,l,RCg‰†ªGWéÓfÔ$i’B¨§uR&ÙõÙìa³ìKw)‚1Ù,Î+áшæ$ ¢.ÖM]JÇñ‰`Š ßêðÚ·ö·÷ÁYó”ɳ,JH>àõΔe�“‚)²ê»×íÄ"I&;ýåi¶'+>W´¾Ý}AwñÍ‹‹ç-6ÿ¥iÎl`¦Õ|JÃÛ€|1 ¬KŸ-�I ÝâïFç*„Ï ¹»;ÄðšŽý†øû8¡é9‡¼\ôWÆz¨äz÷Þ½8<‡Èÿ€YQ2òhÒïL“,)n(´víÚµ–É^—†v˜^:¥ÎpôÆ6}âÊ͘óðþRi¯³\Š¬Æ¼cĹèø-ŸëË>j‰ÉÁAÆhõ“âÀ?¤+éF/‘¡à•"D´¢Ü\ЧFAïÒÞ*óÕÅ"ɲlaaáœsÎÏÖ½ˆ‡ÞÞ£¦ñ‘)ïzF¢Ú‘%U’$ãŸçoϽٳvV¼3?gߥA€(ÿ°Tœ4ëÜTäàß"7Àoеûöèå|k_ƒ³Ú#†‰Ž3ŸNpž4;Ù=càZ™lº˜–©{y!–Ûrž<íþu·ù—5‚ãþfÿÞúƒ÷yø}ªÅŠ•çÃîÆèø€W!t a|r hØøŒbaØì.Ìù¥$—^á“j‰zÂ{hPùÍ×(Y"Ýx€—N§£“Åñúh$ž‰Žã©#"J¾’%ø>Rá !,..>àسgC7:&&“‰Ïu­ýáfbžó(£ÑÈë!wœÔu1™ï${fúxÖ:¬é¬¸…o4Õ¡;ƒÒ0ðÖÐî¤)–‡«¦"zFÍž’„’Ô‘‰p@ÖðB©°ÝÍLŸ¨¢  GeÁ÷èÒù—Ïóüâ‹/~üã¿°°€(�ÀÁXÔZ“оó!0`v:%k©dØ@®öîÝ»gÏ­1n¦¾†Ú6\;÷Ü&65dt¥Lƒð˜ÄæT=ÐÈøVoçäßa“Nƒ“Ç\0ѵœÐ鯼† �éÐÓSbpÄÇ)˜ýôy‚ÉŸN_²¨Å¤Í“$ÉÉ“'‹ç“«'‹ß¿èZ×È(¸ §KB9{;˜ñ-‡‘MŒ˜`Ùë`J?ܦ(Âú,­³lXá„"š¨}D”„µ7‰\xá…I’ÈjS¿5¶lÐÛPxtXFm£©E·c6›U§ª¦nª~•ÒÕÕÕ[n¹EÝ‚igêŽ6òi$ø:yd ñè2qù£’ö1r§•{„†â5„ÿ-FOD€IÉiü‘¡ÙÃ':ÍŒ'HÔàRqæ ¢Fмa†ä’«°è#4çCTZÌLXë—:»}&˜£¹¬¥izøðá{î¹çĉÀŽ »2o$IçáÖ%t‰âPr0ØÕ{®}Ÿ#ir~Ò:ÞšÍf«««<¦ì‚¬>Z»©c-Lø¢gH’á!Ù½pØ/´~'“‰Ëœ£OwcºúÀö“ÖȦÝk9R:!v>øX 9h@N„^}dJÎî”ëµåž…PñÁ.¾øâ<Ï8pôèÑÉdR'ì&çEꧮαwüC#d†Y"§#GÒŠîT`J~!5‘ÁbðBÍÇ"9,Îͪªîºë®N§C¢MMຜJ“5W¤÷5@¯¾×ív‘<‰èLY–%_HÊï-çÿÏ<ÿß9ƒ¢(’'&é4Í¿˜gã^¯§w¦Ø"Hsßœ¢ñ¯°î-íέPHѨ¼³%=?ˆ(õQ—æ… _= ë&H°5l–nãŸb]õz=—Û`=øtš·š˜â8†Ý»õLdÂW+¯°YÈï•ÞääÉ“NW¡ÈˆXõ>°âÂÑ’o‡à\u{Í#ñuíé+§Å/­anLÏ^6ë=¶WV¥kw:7ÒB<r\#=i×ùF¯ÝÓ‘`꟔û¨서mæyíâ®-¼Ò÷¿“÷]Ÿ5Ò…Å–Jÿ¹&t¸n‰ÈÉëõ>ÓÚ0`’6iÓ4Í`0�pú÷¨i*Fê¢|Õ¤rÄ#j„x“Ñ@/‰°$qj÷²#$Cdˆ¤ 4øñAÍÎÙÒ³ÙliiÉ}AœTꢖ (�œú.õñLއ#š¦IþO2{ælö°Yÿu}•)ƒÿ6Hš$ýÐFެxãÍvš[>sÃuEÝ&òhº&ü9å§’Lz|\”Ð1_±>l,Ô“hG¬|Tò<†¡®uÐõœ¢Rºwõ™d¢Ô�aޤÈ!�áö\ò�·d]ì2ñØh®9ÔÙT÷0Lh5RÙÙ°_Ï¢Üí-¹;I¿‘ÿû0ûÃ,?œ‡¦Ï˜†Ç„ìd~Û]öЗÇê ’Öu=ÿþyýCõ<›‡¯…ô/Se Þš%,¹EˆËmîåø!ë>4ÚÒI. éþð|n†#lš4ÓÅW\ùUcÃìØªªúoìkØýé®|ä kM_5í¾¾K¹M½‚@ ÉŽf¼2ó¾"D2Ž¿¨h+˲zZ5ú¥Q’$éi÷E]N¾�¯wEŸÈÓ£c±íiöõ$Σ [»£·¨EPAP+šdâÀr™ØáëÁo}­•NÓùyó•^Ñ—oÿv;ùm9²9â*Zdæ‘{‚*¹+Åy rÃc¬·\dÖ—™ÃÐCDv @Œ±J§HpCÜåÍ7®‹0C7Þ—Ò,ª)]tÎ%nù<,f…ÔÇ~ñ¨)z‚ØqQãݵûà …C^ÝÙ‰‘ayÔ¡ä;{_Ä»¡�žÎ!(&I–Bñ?‹pQ˜¼f2»`BÈ?˜§ïHÓ/§US‘8\¿•*"Œ‘‡’ìKd˲¿Éò<///'×LÚÿµ]][9Æë¬†|˜o'äl묓,)ZÝ¡–‹ç8‘ØóÖr5´p“ ·ÌAá\«P²µú>kÔÞÛÓfÞT­’{’úH=ŸÏó3òñýÇÕÞ*¿!GTXG$ç‹dhq“¤%’>¸L¤’å5oÒ4­.©Æ5Îÿ>ï>¡›eYý zðéAÿýý=·gº< Õÿb©  W4ÕÇ9è©t§Óqû°Ù PË©DÎUE‰Ž!ÿ5y…n˜‚ã Ý:ð>p7ŸÏ%„¼vÝÒ476OušºI’¤È‹¦n¼¨ f™¥o®Q„ærrZùֺĉOnZŠ–ÞŠ3ˆ2‡c’nÂOØ,€?ºÝ®xƒ~|û˜³Sï¨NT4À‚ñoët`4X ¶èt:´å\=ÚÕÌÜaı_ £è×Ò‚ˆñ}€"ïtËmú²èÂi·"ÔF®æ˜U’$ÅJÑ\פ?»3„&ÔU]‡oF'ê É&}0(ê7·Z­Õ®öžÐkê&4!/òâ«Eû=íệõ‹êæXãô ×OB”Ï'(vBÎv’¤¡É“r2)Iòlr[§ „é³ipœ ÂYü[#œObºèK¼õ_Z“?œ$Ç“ühÞÔÍ|qÞ<°é^ÝMîÜ @ë„%Ë&µÁ+ ]¤sÉwЈ<=øëÁâ㛦)«²ª«p}X|üâøÏÇó¯Îë¯ÖØè:s!Ò °àM €©(Z�F9»— ¡C\ â–”Ù$énÄ|Á¼‹c¥Ýj×uÝ$MÓ4IH’tÃÇÓÛ`˜=®Ð&-€ÒÊî rŠ(ººE“[£ú ŒºÜ \_õöœßE :$΋ó�¹4œ¤½Çã\4PÚ‰‰F”oñÍaŠÖß]Ï<Ëó<ùF’~:¥Âàa1dzæ¯1›Ñ¥öu–9X4êAN“q÷°®î °A~@·UÒÊ=DyÅ3ØáðùCÚ~èŒøÀÖÖ"rú˜iöé,i6"kUViš¶>Ýš?qž½+ÞkPTH¾=€µoy’´�¢Èè˜qºyË„}+4`àÆÆ¨Ç:‚ï¦TÁžþ¬5:ª¤÷â^ñá"$¡Išä`ÒzQ+»6ã<Õ×àlrSK}±T™-G¦2 ë^¬0ÎâµïÍò÷®Ñ~äÙ³?¾»8ù”“H¿�÷9Xõ(ºù¨„A…‚ÄÕ%¹8æÐb6BŠ2Ï0²©ößþ¤ÓS÷GØ÷×cñèý‰¨~¢€öB7¶€ÙÅK•J$M½f$Ñjmìñ™yb�46N•ÂN“²ìœQ#ÇlX.ßà¸h„PyӂТ]#^ïm&4)¿¯Ì[yY—å•åä'Óó§ÜIo%ö©óªƒùÚÁ+c°& ¥ù¼Ë–ŒZk$Ú#ò]UXŠFâ"^€û©{ó?BJ¢_wç?7Ïþ2Sݼ{÷n)ÒÖuÝþ‹öôùÓ¨ë”qO2¼$Ý©r¶­Ð ëCgÌ0»(²0®­<N.ZÜ*]µ&@!üDö5âÎnÔYZWuÝlÌÛ¯!B7féuUàf#.2ãðúxá?¬}‚i8³ˆÓÜ{³Õ£ªî»ºUUõûý]»veYvìØ±²,Óϧ§_sºÝ´ €¸½7É¢xŠ‚Â©'‰ôt|H‡€J&oyÔV"‚²¨º:/r‹IÇÄôt°;ã€ÓàjÁT3.ÊàåT4ªu°Àëƒ9ι‡´‹ö“;wo1/˜Xºék)vR`ÕÈ~\¸Ök”­œZ#£}¨ÚqÇŸa©¸¤(Ô­• ß„Õß[mýQ«9Ò¤ÇÓNÚ)ËpA˜¼bÒÿ¥~‘È™Ï ­t²~«ÐWä�zåºhÜúà*aÞ—V pš.ЦPH÷¢Ü3 Ÿ×–R;QÙhInl™dY–d‰ìíWWW€çÊd‚£ÝÇÇ$vBÎöüø‰à®èC(&§Ï‰õ,Óq×&¶éIƧOÓ+ÒÉ‹'MÓ$uR¼¤hn¥G6šü0¸8õe+­”ꤳV\Ëe4Dõä(L¹/íeyvÖYg]yå•ÃápeeeyyÙ5?‚ ÔS Òâ4DrÆ 4iYÓüït:d¸L±ÿ¶ÕÝ@ Oœ.W8öÑ  ô˜\V[bÄfÂúØ0k�o ´á¬÷±|¯¤ýtð\GÈ'uè.…!U«Ìic-’Ý7­Ï©³…Ó¡>XóÍU¨)ñgU“+UÚZ²TàõykG¯ì÷ûŒÜ2½ëJúÎ`M€T<;P¬¢(ª‹«fÞÔ_ªÛívoWo:V§«äd’¬$Ó‹§ý}Z;бœz@‹B‘O{“`¦o¢É6Å!çì1“ÇX4QßϧáDe·23Ä5‚ ›Ež{"_Ñ ŒÆæ¿µ°#"Rs°i.jò£yUUGŽ!לßž~s|¦ëÖGwØ#¹Û³mÀšÏ©y}êREðG]Ç œúiçEÖ&(hmˆÓ<&„ åñ²÷Ø^Ó4I–Œ~TŸª;ì4šHVl¬–m,w\JoY÷Þ°õ‘Ïôh"C×U·¿Øž=rÖ¾¶½¼¼|ë­·ˆÏ=Ëþ5c¾Ä½Ü„í †7iæÔ©ÈVÕóÓ°® í™»þj×®]ÒVàÀådQv¬mé¦Âз|º6šÉpŸfwÂv’zFEÞÀÜy"m3,¼ð&Þ!Ð9åI’4föœY8;ÔgÕ!„°ÒÛÓôirg".µŽ0zld*È%PI»Ö@DÏe/ø(+Š!­èª=v:Å‹›�»÷Ôÿ8ÕýÏÝ´•ž{î¹W^yåòòòµ×^»²²’þJ:þ×ñì{gœÈ‘ûT´‹Ÿ@¼.˜G™¯yºƒÎÓÿfåVÓ^!u¶(ú¸ <H¦¾€@BŽï8Ÿ”@|D÷JäÝÉâ•Åø3ãôq›&oš¦™þÞ´ûÂ.Ÿèî…þÔîµrÝ 9Ûu\cŸyxú:FI~# )Ðy(>±YÌ2™ÁiÛëõš¦=}Ôù›Nó¥ ð¡ûÒîüùóòª2¿9¦8#!KídUèTQŽÅ“¡£cHŽæ;ͳ*öO° ÓÖ[«ŸZ]øË…•••[n¹…÷Ÿ={Öýó®÷“‰ô~ äz‘8¿ÇÁfî´ë>¸Z;™;L®ñÓëõTéÀÝúY‘1­Wãhð)%ç§¡T†-cX7‘tpyqˆ¡x¸¯9ø!µµÃ,a³Ñ–ßäÕ—¯¦·¥éÿI[_m…êûÕÕã«ÉÏM:¿ßIfÉVj‰C…*›ô•œ”A:¬¢Ÿc4ºbêÙg\¨CÌu±€°ûCXSé~èCúÌg>óرc·ÝvÛx<Îó|&¤ƒ”G#@@ ©6¼Uƒ·bÅ<�d4xv>OêãÆ.Èæ¸™.ˆsDÇ 8<S [4¥‚銆Zoiß4.þ©Èÿ1!T®æ??o¶V‚=E$rЋ{¥×m˜Ë!ãg Yê+#˜1Ïåÿÿæ9”“s|VßË”ÉM’[’䯤h{÷î•NFY–Ýt§¿1M¿˜V7Wt;È+a¡ãzÀ$_jØpú¤"·ÒFBqÙmlœ©œeYÿçú'ÿédþ÷yþyš¦ÍƒšáŸ ‹¿)Â7‚‹§A:ðS­0FD]fœÇ‘±òêñ ühn8ò\EzhÎhð²Õ_åÑ®?†‚™Ì–@äTl‘ x6Ž‘N6}f7âTÏÆõ'ý~ÿ¬ýgÝôý7µ¾·UUU’%I’4w4Å;ŠÑûF¡©† J6ŽÎ&‡åË�d•€¤þ á–°$ØJ¤QoX ‚:ß©zÇãq«Õªçõ¼šÏf³;î¸ãsŸûÜñãÇWVVš¦©Bê@ö#5eueÔÆói›H8ÜI/†Þ ½ÍÙÿIžägåƒ÷šÐ$!)žQ¤'Ó,ͼ\jS[Ññ= �¨µã».Úúx„v*ï Ξ ùbº¨$¦išðü{RþP9{Ù,„|-)þ¢HïHËÕ’â˜ðìH>ÃN/gû8æ®UN*†ì(ÜsôZ\aׇý” fHƒVc½§Îgy:M/¿âò§>õ©'Nœø‡ø‡ãLJÓaÒŸt÷t‡É02ƒ!nQ1hcÐvŠŽ ÿÚÐ85¶‚l†Oø]jš&=›" �� �IDAT˜v¿·[>¥~t˜$IvS¶ð¸…µÀÙLùñ62ö*úÂðg@ω(—LŒ^Ÿ v)e7!ÛEŠ“‰Ž8IÝG½ÅSŽŽxÏŒ6-ÖDØü`4é¦ãÞJ &É1¼ÉŽiPéÄT2‹~á×hýD i¾4M‡ÃaY–ë þe ƒp‚Ÿ^€²_Ab\zdª¶›¦QmQU•Šfb9£øZ<Tðž8CÁ@¥ÆÛ‡Ðß9g0ê<£3ú—Qö˜ì¦›nºí¶Ût!„ÑÿõžÜó^º…tLéå°‘‹…­›Ô¿ ½·z=ż9¯é?®¯‡2xï »'Ë~7 wn9H¥Kv׆ƒE)ÀVt Oe"ÕW/ÓÃfÕçó¤lòÏ[7¶Êß+°ç³ÎÄŽKðh´r¶áÇ=É©aÁ¦\~Égí*lvºäé2„!ûÈ`*z=l±µA÷V«Õj‰h´¢šàJ‹˜e¹û™"ÊQQåÙÈ{ÒÑ v5‡¯pÇÒ¿K»ÿ«ËìH0ge]¬b‰[§PİOØü§»zÅÃÌ çc…Ó¶u¦¬6¼ònRZ<¡õѪxÔwu JXU$ûîYÎî-·´|(È]ñQv—‡>üïOÕ¢ÿ_•UR%y’÷z½ïú®ïªªêK_ú’kß‘Ec‘Š+t ÷r¿"úÜdšÿn:‰ƒ ­ ÷oõúÕ‡UUåÏg?7«¿TϾ6«ª*< 4ß×ä_ÉÓ*­›µâ´”ÈåˆÄhôÒ‡TœÇÌ~¬ž[eËò¿Ï“l “èþX7<5T?]µÞ°&eͬž/'äÕ©n½±6+×9zF=¥’JsÃf­Rwp¸™¯BùC<æÕ”ÛéHqž{²Û 9ÿ¡!nëÖ=ÆÉ6KÌ:vì~h,}ïÀ3ÎàZ¬þ-›={6>{üÍo~óíoûd29qâDaþ˜y¸%ÌÍ%ŸF‡Ò Cp®wé´cO¨Aó¼Ç ZÇÉœa :ì…¹R0•6ÐüˆK!©'È1î@3û&Á$)Ý]‚SV’náäŽZÄeIØÝjªáËq6‹TF66²ø6z­CqÆ}&»wo!nBä8îɯG)õ?€ï[­Öx<v….·4öÌÉG€}èÕ }Hý?ƒIí¡�2%æ^’ÿ2.ê,ËÂCù´²|rYþBBÇCv0Ëÿ$³MÓ”°[½|XØú}}¢ŽðÀ[5W4uQ'_I¨ª×ÂÉWæõCêòAevCæ•(…†…{ÏÓâö’6]BX‡ªw@ÔÇ|ÁÃÙ_éc‘ƒë^'Š_Îu턜ÿ‹j¸¹wP,{œ`iº˜£K´m5І{êcÏkÉ×7²fWSŸUŸºñÔÉ“'צôûÅü’y}¸®Nn˜Ô:Çæ^Ùq¨mº`¥ª'€rd¬Yµ3'è=gw\Ûq7¥l†a"Dº)®¼àôq"è½ZÌN"øÞ[/L’às m©rv B¥¹uÔ“�…뵚&á9P¸QœÅN†$?ˆŠfÚQJQiY{¥èƒ ÿÚý÷QñSÅp8üÊW¾"JtaòÆIçW;^¢%º¿‰˜ÐíœÒÁ›a³½,Y¹ŽçÎö¤RŸfÍ;›æì¦8·!„Ó!I’äÅÊ'˜‘h¡—ïNÖÇZ‰Qÿ Ûs«:­³Û³¤Húý~§Ó¹ë®»’$IŽ$MhšóšäÆD³_Nà–"øFà¬k71‰Tؽ‹é¼( |ǹ½îïe�ò<gÞ{–£å×n·E^pY ³m ŽK•±<<Oºuº^“ÿ¯o!ðnÕ¿NGnóba9é¾ûëÝÙŸÏFýQû-m y~g”ÿ}Þù@Gò,e'¿¡~¯œZ`=ØÎ4~È}B%¬+&¬a56o¨ƒõ^‰ÎÊàDÂ&É%#ÓA©Á…g”âí8‰ÎÁ1Þ‡�éŒ NFíÿápèV³Îæy’$ÙíYvOYVf¨¢…@¡Ùl¦g­P3ÃUÝ\3FUz[„Ã,ÊŽ‹K‚´8­Ãå;AÕ]qÀû¶ç¸aAê‰WUUÞ^&£dþðy}g=¿sB¨Ï¨›6U^e·®½ž¥HJä+œ‚Œ«ûã|b×µÔ;èM8ĵ˜Å†—HRåoÂE¹¡•$I¾’—KëqÒ¨á¤æ<S,> Ñ[@ü\|…1©R1Û¿öçIçy§Ûišf4mNæô\õÑ®Ÿ«}D"å:âÌÞ¢™í”¢HB9Ÿn#.Vl.¦À¤­$¹R-ª^¯çÊo.?ášr>P¼r¶y.ÌÁÉ©€ ‘Ų{zÓ8¬Oøƒ¤yÙÇîÜYd-1ü•¢:¯ÿâ8MÓº¬{Oê¥iºæ¾äÈ7•¼ûz¢Sê¥ çBú'ÑŽ¡Òù\K¤+Õ¤ÉnÜ™ⰠœuÆÐÐ=„ˆRô·" wǬ\t­IvÑtù Ë͹M™—MÓd§²l-þÏEW;=#ÃP±åS&¯¹¿‘ÜD"¹6#ºzâŒî%á¦,<‹h6Ó%Ö^¶¿šþð4„•YþÖ QJ·öKڳߚU§ªôtBhzM}V]üIN…:«];Õ¯Ý[zŽ{r F‚‚8*Îè‰ê#ÔBs�Çeâ41†¶!;Î #¬Õ5"J1“g^I;Uçìx<V#]ágÃ)ãHZÍ«êþUz(ÅZ©,Ëô’4i’ìpv¯}D”ƒ)I;4ÙAA£ÀÅÊÉ2îhçX®{$N|.]£×y.®½äÎr;s9Û©ã(u]_%tqÖ3šÙfÒžéþz·ÖÞž„ÅÏJ7# žL&óù<?œw^ÞY[siðÙLWÓ"GvIð Çñ]6ÃǶAÏœ}àp>mꪚ>n¦jÝ}|©±¸4'”Óea‹ú»ˆFBJ”•¨éÌÏž|ܺµµðw Õ±*˲껫ù…óå—,wÞСgÀìºGn׿!`{§*õå©yXçñ!DOºwîítùt”ˆÂà<ÏóÁ«u»Î®Ë’$©’jü–qþ±<ûà&›Úlœõ_ÑŸ<`R>¸l­ä¦$û—,I’¤Øàãù‡:;Žò‹†DÄWôF`X×þRMC”šýölvÞ¬išîÿì&ŸOóôî&b¸t¶½Î†ÜLã€›Ì ÷¹ŸhýPg0a­v†›T6 ¦k7áÖ¬œ–ÕUz(uÚúô’iÒ$áÆ@aYºEK"Ja©`Ƚ|Ùƒ±ëX€ý2´]­Ñ·•“c=±œÑÁ3;!gÛBCŽ9’5WHÜXe­düÚqsyÓýn¡œ—ã÷Œ³¯g½W÷Â|„%b+ò6Qï¡(Šñx¬íGgˆÃ�Œwþ•E*YÃyÓgA ä¹R—ñ’nеó9޶“h6‚t\¾ÐyPa‹i·óSÍ8)ÐÈr›ib'ËUÛi<9³Nö&»?²»iš²)‹¢(®/òkóÁÿôÿ¸ßL×TFt0Gˆ´ ÿÀªÜp Ÿ õ9>?UQKòŸk(¸áŠ„S½í-À²,W^±R|ºÈæéi! IçúÎä&õ÷×­kZ^î”eYÜTd7¨¦ÊªPùºó»è*!`ãAÈeUÝôšV¢þ\ ¤aüŒñüóöoµó{ò4M§Ï›ÎþÛ¬ÿÌ~^æ4$kDÓN×(O$ ¥B-«naÑB’1–(¦i!"‰O×E»‰,ÓÛ„Íۛɫ&³Ÿ-üäBhB¨ÃøoÆÉ‘¤ÿº>§¼+î0:ƾ‹\' 0@’&xûކJç3žD%5œlŸãáQ‚"̽ÏN/g›5¯ÓwÞJ.XÛB/›fŸÎÒ_K“<©ë:©“Þ“{ÓžÎ^<+~¿`ºEQN÷B‚Á oDØ÷¥R‡ÎÕšÚ®ÕËŒøªùvʦoiÏÇ} ß#Ö´ç\œ¼>ŠÇ‘#€×|j y¾Ïn!Ÿ ë./ü·Ú ëêÔHu)7_þïËû~p_Ónd‡L’»÷Õ{W^»rÆoœÊ焞²[#Ý©IPÒsèOÝ ÄµÐ2¡2sC¼è<’Ÿ М |Äóóó¦Û$·&ÉIHB’$iýÿ±÷æqz–õ¹ø½<Ë»Ìdv„D#²ˆ(ö¨¥"ÅžÖS­µÚjmé9µö¨-ZkëÒÚºQAê‚EWà�Š@–@B²'3ÉdæÝžõ¾|ß¹æš{<þHñ3ï|B2Ëû>Ïý|—ë{}¯Ë˜µF½H¹®º§R™Â›gjxCŸˆ Ð`N¢ëEÅ€£^U•¸ ñ=•[Y¿¼ö§ù‘óF†p–rö}¶½¤=¸q0úÆQØ`MM.W£ÑX´hQ¿ßï÷û˜#Bb­Œ\^]à¶^.fTÌŸfÒ&¯éHÉüL”ejB¥ïMÍRÓ½±;Dwß5ûM¬ï`! -Bà(ÏòÒ�$dXTWLÁÀ™dŽ( B&ˆ*’©D&ˆÂªŠs5ä$Þבͪ¦ )g¿eN6è¾yea6ØQÖ®¶g•χø[Ÿ\ÛX³ev@|&(¬„à„l!Å‹" ~þyùƒÁk/˜y # ¼ øB*G¤ðŒ¥šcéh@äÁc „YȈ £ÍŸaB@—Wµ7LwwØŸ@c­]ºt©Rj|||ô!,„?ðå,�V 8bȯæ‰ üAgEfl¬Âõ žy|1r3êk³B³ûï.Y¸N´_-ZÔëõºÝn|cœ]—™;{fØ+³62 öH“¸¨GGËV¼£Š÷Œ"�j¶ÃT˜üy|ÏPÌ´ÙlÉ¥7šre™þ"ÅØOØkH*Â:“þ•R5`OÌäqݸËäg År¶YmH¤Ò@Úš ú$>Q©I5rɈœ™ªª¼õ<5á…Á=¶š  KÖø -ká`cŒ—ÙÿøìÀPñÚ†"‘{œó�L ’ÏÓ—ù5H9væÅ:öC€hDe_Î_ôþ­—äþEÞig×Ú(Š–,Yrä‘GŽŽŽ:çÜjWÛº~a ^/gH‰bw¡”’RÍH³H>À&‹ eY“¹7ÈlÛÌc^ÌÿAÚÁÇ—Ê:fæð–+¯.Aœƒg¤lÆ…ê›·X¦ =ÇX¼xñØØ˜àòdÄ›C“W^i3K}–µ•`ŠGÒ*°rf·+Ò¦¹Yú18NœÕؼÖm"ßÇäìŠh=Üb9ì°ÃÎ=÷ÜÃ; SëÑE£ÂýCa!ç*À31«c½ Ü}v„ãõF ‘R2K”dåÊa‹l|yQ©¿§sG}ôßøÆN8!I•)s‡É/Èq¢{½²,÷íÛ'â09eC3°ÐŽ0 )ã�8iñÑB,f÷p2Ámát },Kðø 7!ìq¹¡hȸ`Bº’w˪¸}l‚�k+ü¨õàã<«¡üL Yä-t9û;mÎ4(¼÷µ­‹îT7òþ¯¼RªwmÏ­pö›VH_+W®<øàƒøÃöz=cL¦3¬MðÜZïý¾}ûÍ`ŸyéXf˜™BL—T$ÚøÂ“j¬%c1¬—˜éÈCõÀ$W ÏA±o] (™SK@+`g3Tú10cؤciùÈR}/þøâÎ_vF>6âœÛµk—\Ò4M÷|pÏv€<ÆcccÀ{–>€g°¬Œ‰4'!4£À78V‚∃ù<r€l]‰úl¨è«ªªËÚY§­v¥›ššZ»ví¾}ûœs¦aT¥ŠA1[½Z/‰½óÎ;ß™u*B‰PrAªÄ BÐZIu¬.Ák³ÖZé�$£,[¶ìØcݹsçpœ`ÓÞPÿ”Z‡5ô:F9‚!ÚÉØ<€3Š1Fö1‚¨¦€UUÁ9+ –¦LÁåWãÄăñ -Tl,ŽÇ?žžÌÄC*¼5W _ÆF‹RàÑ�#ƒ±Dö€ãEz" )g¶8ÌP’¿”£üãÒ>hã«ãJeøÒ7¤ú_–WgUEVÜÿý###ý~_)e2Æ59;F~8‹ç‹¸$aøÁfD.¨ÇE +Ë2¦`ᇰÙC @*Óº˜åiŸµ`!u}žaðxœ °$0ˆfá²€}ÎÒŠ‰Å)¯qt:™|`h<œ¬Oý«}ùª²z¸J²¤Ñh+ŠÁAƒhGd'¬ $XƒÍÌ 'fhH«åMÎÀG‡ÕZ4…À&™1WÍÕ¿‘ª ©Ó‡dîÏ«òKeüP¬×è={öLNN &S¾»Œ¿gOeC4ìDïwSïžÒFk­íglº-µk-{6¬Ci÷’6ä³$T:î0†!Õ)½Q»£Æ?üðÃ7nìt:yž{ë«Ã*½qV? —“*‰”âì|÷´Vjî)[B`¼§fÌ:¡%Áº>øòf¹Lqm„jLÞ­ KØ †@¼ª‰C¥æ ¢³5Zî2ED€µõäm ,?¸Qè° ¨Ò™g ¸¿Üç}ÊYˆ™ÇQՇ׺¥ízk¬‘Å«º®ó«ru òÇøò]¥Ý`wNìLL£‘ÖºXYøW(¯ýü:B§ü.ÌfZ0—EŒ £.ÃÒ>‹Ê�”ӆ鿯@^%p F—ð¬äÆù’ ¨® †ÁNÚˆ@é]ÖByŠ ŠÅw¹Lã±V`³hŒ±›mòí¤ÿú¾9ÕdUE‘Z¤ê¤û‹1mg#iຈ�§æô¡3Àøšuö$ú`-EÀÈoi6›˜Ï#â´`ŽD=·Åƒ Ñ ‘¾I[kuC÷ÿ ¯c<“ kÛ—Õõŵ+\ó’¦ÜýêêJ¥ªü~©WÍád¼ÊR¤ …ò�Ư0oWs× S•™Mrm’ý~–þyÚëõÀ4‹MuyÕº´¥ŒÊ²  Nâl+Ñ¿‚J'0©$`ÔI, Ê¥Ü|‰Ôà•ñ¶ƒ¼„mˆ!1)?,Ô¯ ü|¨Æ€,±Ãt2öEäÃÀïÄŠÀ¦„+Å@;XÍUxC`aÉ®@nq!åìH)ó8pþï›Þ>awcccišn¿|»žÐѪH[]œ[øŽ·ÚÁ9ƒ¨•¿WªžJ®K ¡m>èš�åàNãDVç ig1ð­áÁÃ0ÒÅ5.êùŒâ Wáë¡…ç÷o€•±ùk€¤páËù>ìq2wH¼œ8ÄaM“Õ‰;ß©eªªªø‡qül,,/Ds XÓÛ›9 ü É]qexÿ—õ;OŒ¹ hÇÈ[Á6Œ‰ô¦ÔŸç‹Õ—+k­+\z{ÝEk#g]QÅÙE¼:¶ß±JK“å×/OÞ”<qÞ­_¶-~J#“½Yqe RˆMp6¢ÝðÄ®·õD=¸vÐþPÛoõZëê]UuZý]4«%3³ÉâLܘ¿± æ 8³+bâQ"Éjd5Ô1qŒŒôz=ö;ÇóȪ¼•ɽ P>Øè±È›R؇»“`¨ÃºŸ(1añ�MÛ~¿ä›R˜Þ–NŠÌ±‚Ïræ )g?¿˜?ã½÷Ê»zH™ÍóÜ%®:­òï÷j·r¯tɉÿ¥Ï>ùž|[¹èwù-ÞïðÚj6>a–=/¯a¾ÂrÂØ<Æ$øi50à©^> 2˱éØÑ* ¼î ŒH8?ý¸o^g4PJE¢‘Ž˜ÜTý ˧(äš‚†¬‹,1B(1W`r;ݱ„ sI‘Ëg&~+¥R“:çld1ôÆPdÿƒ‘ ÛT󈄈Ʋ¤€w Ê<.“¡\‚y/[©¹öK€DÎGþ>½#µ‘Õ? ež5Ê(o}]×ÙË2ÝÐævc¬Á½ÛíÚ›¬}›-Ï,ý]C6#`™UˆÿáÇǃ?¾(£ 5ÆÔuúåÔ.¶ý¿ï»CR*ýB4¶ÏZÙbÆ8R7L|—öE>,šlÌ$@Ëds^°º�¾Ï„˜NEsŒ*ûý¾$ô ¼Àt8ÜÜ@BN5/;3]“ŸeÞ’aMkn€<SX‘)‚š©(S`ûp¼UnÚ€µÿ*t5°Sf%èwWºÖö0MFY–íûÃ}ñM±Ú­’C“%‡.Yôì¢kvÎXk{ßê-î,V¹Úgöa}%0¸"è¸àrOQ_xœ€c&'¬×ë 8 }7EØ"—Yÿ¨¿PDZ2) /2-g(¤ö’Üý§nU#ç8çÔqjê+SÉí‰ý²uÓŽ™WˆjŽŽfYÖívY1›�mdb¨‡íÖ¹xˆ%´¹zðbëLîÿWÁ8Jk]œ^¸†«]mŸ°z|øÃ‡"öÍ&zSæ‹#³2aŒÉKÐŽM®•4XA¨ û†ÖÚ¦nª­Š9ñø¿ÈªHÅylbc­•{·Û-öeUÆÍXÚ<ÄeŒÙY2’“¼…0nÉÒsüÞÔ´Š§âøŠ˜µ>µÕÌÌVðgœF Á5@ÜÇXïÓ=™`k˜ùK±Èë·0—C G†ë0~  ƒ†UT´A-ãƒÁ\�¬pÊ̆µqª+ª±}„ yö)÷xê',¢ß $~ ÚƒçqÊùŠúÊC‡>ÔOßüÐDOE¼ú?å+Ks³aìc½RŸñŠ3NÞzòuc׉2«DÕÖH«Óé`²­h§kI('ò’ ´MvíE‘¸‰}ìéË2Ì °±•1tE²ÐÃP¤°�%c9©Å?‹.Y䊘èÛ~C»ÿ™~|\¬žàjp¹*Á¥Ûíâ·@dsþ–5+`²5 ë9 â±­\\Iˆ IÇÃ-᣻Ó?Ï—­2J"ï|ùòRM«Æ"ĉMÔºØè›1ܬ°x¥šëÎ[ñÌ,0–áxf&…3N2,`]¨7ôФþ5RÌ€ì1å ŸUNœAoÄVÖì´$Ð%,ÕŒZ[×° 8¦ñX¾A_‚††1'¡¡H’¨¹Ö·ðµC ÄJq@ÛØ ´^3àn "ièÝ™¥ ”OrdDXsŸž„HäÌ Â¤Ÿ ¥�_mEb¸ �$àÞ'?ŒAª[ØËyŽ^?V?~³z³Wþ°ì0¿ÞWƒ/ jã¸ù“¦_éûŸëKùl­Íÿ)¯/¨§¿4½víZnä!ïLwÆÇÇY ãYväL‹Ú‹`bçCFëì‚âç#zy&Y1òÒì€ Y¡,Ë,Ëúý>ô‰™ÑËKËιêª*º!RN5 Yï—ß’|%ÉÞžA(À‹92B(Ä<!ƒñ|åg`Á‚‹�QNÌB%p„R¢¥Ð·æá|»‡k@/öåkKõŒŠ?7>Üh|¸‘ÞFSQþ‘¶°‚ü,_¾ü ƒÂ2 >8~ëÜ`…Ì`¶ÔC¯Éßj2/÷Í7®7ÆÄOĦ0Å©…LË ååNs¾òúÍŒ|0�A S €ñ í¤*çð§hW—L*cßü.)° PK¡@C<Tõ€éñHOÍÕzgš{ ¡ÉšCÀž;Ó<X…æÅ|uä…C¨ U–êxí i×VѦ3üñlâ)ã¹#{—àñ�=Ö4šoÕ¸Ðå<G¯GÔ#?Q?ù„úÄáêð‡ö<ô‰›?¡îSåXY|µhþæì }½¿ׇÖÝ;»~Ì«†JßÖ[ëÇ·?.�—Rªü£2ùfâÆÝ ?Àœ?¨ayÂÌÞ‘�ú)  aEœlYGPÿa>^›gRžÁµ÷¦r"tξ¥S\òÍ$ÓåË—~øá?þøž={Š¢p¿på§ÊÔ§x®PEOB�?$DžLÞ{Ÿ/Ê5]`¦Éúív[šLqyWtƒ]Qk¯“›¥TœÄEQجYgÊ)í¨UÙ_Ùà­[·äd†ÉV•P๾ŒmO9!1… *àD˜ÖZkÕUõ‘µßèÝÄŒ•ê2[]ª¾2» ÛlƒïË€-v¼X’§}H üÙq$C¦S2HÈB;rSÔ\g39Õ`¦„ž™ædH~Ø*†mî‚M» UËŒ¹·ÄIEà=@ª@Í3ãaIxiò ͉; 1@ÔŽxüÙÙæž¼òň«Zü¿ždÊ@Qy1,Ò³rž£—W~µZýBõÂjÅ,[iÂèImÆëÔS30ýQ®øÃÂ<tDüÙ`ðõAùdYýJ­W*UÕ«*¿ÈÇ¿ŒµÓ€ªxR̓>&ðÌÿktT—ÌÌ‘ÓÈŒb¸-§Ÿ}ÕÔ\1ù@ÚDP&T¸xÃìÍ^d•®Ä [&1yžË›$I¡ ^ÿd¯ÄVYb—" I`3ŠP?ÞÑCÆ4kì.ËCJæ©©)É^"B¥f6éxr®Z*_>zé¨ónéÒ¥gœqF§Óyâ‰'&÷L6¯möÞ×Kþ&Œ£Dkm¿ßÇò„¤É |e6 —±×ë šïh’NØäþÍrG’$²F£Áðý¡3ñ§Mùåà̓ƿ7¼÷λÁÛöIÛøÛ†óŽñ@t®Xãe©nMx•XÒÐÆff(ÂûŠ\Ž0º@Pƒ6E¦ˆ1U6V@‚„~ ædÈÇý3ûÊ*£º_ù΀l=—�� �IDATnbI!,„Êà‡BºÿùL>†bïu’…=?à|òÙM i•½í™ÇÁŸdR6fdžåY9Kñ"3OdQoáÏ )ç¹{Õªþ¼úü*µ §DüU¦’o&ÙUYrõp¹¸¬ˆîÒ›ÓÒ•Î9û1÷buºüÓÀÜildUKÅwÅÑCQík<·¨^‘Tü¼—@1ŒW Ã`(?ðÐeÕE$00ýà‚‡ZðAy_‹oX;`I´øŽ8u®Л7oÞ¾}»€ÑUUå¿‘G·F¬£>_–%ª<Ä&¬A 0aa‰ÑèlX{_r0ÓÆÄ(Ø»¶kÙ9Š"i¥•L•_óš×\qÅ[·nýÊW¾òÈ#”®,€'ë‹ÿÊeÞOA XÑ`elƒôô@‡ç€$“¹1¿oØ1Ûohô÷®¦îjÍñ̈gŒi·Û˜8²�¶¬P›&Ù,ÙÇíÞs|yOÖ9'¢jƒÂ€„‹qÆc¹#¬ªªwf/{Y¦ZJiå”S§+¿Í'×'a1©Bð•C"ÃqlŸ÷¹ p (ÒAçÔ\k ŠD@ðÜ1ï™åBæ']n—B„¹ã,Ì 4X…¬>Ç묀öÊBÊÙŸ¯v»}ä‘GnܸÑS¨B«sS­QöV@|QL‰þ1jÕèÿmß/òv•MnOpbP‚Qƒ[@óÌpø|�dã¹Þñ42ïï ŒÂØa:WO,†ˆ3Š…jüÆøÇñàOúu]ÕYĻнÁ%_LgTb�.ë0ø´„‡¼åøâH:axšøÜeVAE9‹yVJ«!MKÎn·; ”R6²µªÙ¦,°Oæ‘5K˜p)ÀÀŒÞÈ× G|~åÁàë±ã1\ çœßç“¿I`‘R©!ö"]ß\9TcIóp²`O#f'# ;çêãêì¯2­´ÊUú»)>#{% ;BN T ‘˜mÌGŠäÞåyž¯Ì«—Véº4úA¤½6Æ ^>¨–Wåï—É—––àÎÔdÈ@ sKy‡¡Q°Ä–Ï Þ¡(äýJ–Å“~Wwl’c€F¶¹²Áž8 4„“9«94“¢xlWÞÅá9ÓÂ^ÎsËŠVzTvTgT ¾±wïÞº®½òzDÛÁpìï–:êxWì´;â´#FGG×­[7½qºÞ^ë5:~<ŽnxÊj?nöÙëÑ !ÎqÂså‰eyM©´R…jþvS ”ê((¯È œ(Æón�Á€}˜×ïe Tsu]·ßÖîÞÚÏ'UUǃkÉ“x]¬ÌläEý%¦ÎhDøÐ#F(Z­æ‡_.O›g\jHËÓ ‚/xÍg9¾™mÿ[»ø`‘üSrÏ=÷lÙ²e|||ãÆe»,®(FÞ7RºYÙ1ømc†5yo‚béR­a¼clð¼yÔ­C*e”ËEËí<Ûßúƒs®Óé,€ ñM’Dò.<i Å]5«ìó™-lûµs.qýŸõÓ¤ÍÏ7]ß±73܄̙©t¼bì£È 1‰©WÔ~Âû›¼|’&Þûä¾Ä»úµKÎfŸ,¸¼sÌ…Œ4î (ÅŠ¼ Úí6ú`nìp@·ªz_A*‘3,÷Th à©ò-ÃZ¦)’…e^>ZâË%ÚlWÊ(½ü|ùÊ…YÎsú²Ê~T}ôjuõçÔç$åŒ[k͈齧׾¤¥‘1¦´eáŠü„ÜåÿǵÖZé膨ÚXcªºJL‚~‚ ? Ï7uF•Á|¦Ê ÿüU¾§4“fä¼km©Êþ×ûöqÛüR3Úïd­mµZÓÓÓìN¡C 'øbÆ  ³± Àù-Š"»×.¹hÉàœÁà_J+óŒiÓ tbx Ñ<Àòspq _6Ü?»ŒÚQ©KûˆöFw ^ñC°~Á™›«H,ö"œÁõ`X{*“nK‹S‹üü|û½Û÷<¼§×ëõï'Ç%ú)í÷͹§2ð�£ÅLr5¼Q¡HÄ%ЫF©ËŽ ò1T…y,_ [e.ÜpsûË<ì`¢ÆjFXz‡"'Ø•ZëêSUô±(}:µ‘­‹ÚÕ®yv³üã2»(3ß2¸2X‡âÆšè÷h)0¨Ç¬ªJ«ë³êEï^¤úÈ#<ãŒ3vïÞýÀ”kJ½Z»+]zm f``pÀ³R5WBIfÅ™EçÞûEëÕ<jóæÍY–±Ð'~«ºÍ¿z¨EDéVqCO�4ÌÈnFLÉ“3ÕÀÆ^^Xeêœ%HÛIv\ºti§ÓY�Öžë×áêðejÙGÔGþ@ýüM~qîNtö;+¡¿Á©—©âµ…ÎuûÍm9Ù»3}‚vµ‹Ÿ‰QD$Eu‰ÝfƵ@•)®8±sÙ–íà]ƒäŸ“±cKŽXRUÕž={Üoºâ]Eyvßsýhñ"u!â°52ªË -û•$Wv’Οn·#wŒ s[2ëŒÈÂ,a^÷A_…<iI’¸³\}VmSkbS–e~r÷ãèŸg%xðËA•>Ï ‰§ÈËR®<ÖP¼÷ñSqœÄÅkŠâ”¢W÷ªº2±)²¢ý±¶‰ èæìA#T‘�å ˆu)ÞЉB®ŸñtŽ/ }C¾:oœÀPJcÝ'X ,þIáq ÄèžÙíØgB¡s>ì^Z©g•Ýc•R­V+MS¡9ø½;ÏÅÅõîš+­@÷A)Õl6™+Œö)‡ì(Šj]+=T@X±bÅ\ðôÓO¯]»¶ÓéÈ‚·zõ£¥æ)àÆãJ×?¯_›áûì®ìn1[ªWx«Ãe€$E.¡ ŽÀ{Ð�WÕ\_%–_ÃÖ9�Þ~eÏx&²âr±ÇS\Åääd€°1s¨f]×ÓÓÓìå¸rž£×ꈫÔU©Ç>¨>¸áø ý¯÷“û’ø±Xý@;SÂlÔ&3z“Ž¿ÏÊy}.u¹ì”Ì<m´Õ¬ÛÊ´}VéGoÁÅ;^žË?ŽŽÎ¨§U´%:þøã_ûÚ×zïo¹å–Ç{LߪËÿY–÷”j×° R‘͇``ìµaçÖ:[Â:.8²¬x> ø‚—,Uð‚=À è›ùÓ¼?Ï7ŸhšÛMâ’º®³—fõQuñ§Eë3-n› ¢ˆäÔ[´±±]Ë–zØy’Ð�×2ÖŽˆãâü¬\hãMã±F½¥£ =xh ç"”)J>¦|>J¤|t, Œb„æ`"ì}<Ê ˆKÞ‡e`“]±‘Òø^³ñ7ñÃ6îôÒl6vÂxЯ~õ«³,»çž{&&&ô½ºzGEz\³9,û-!Õ1B%¿K.‹IóL×ê™gžùîw¿»}ûö½{÷¢fJ<Ù‚ÔÅ£µº®ýK|y~=Åwź¯sþe~rŤ{Ÿ‹þ6â/f+vØ äxçãÞ­‘1 ƒ¼Ž—EÍUuCÅÀ°6mêbq•tQè–~ ž—ôjÅ µb¥ZyÿÆû/ÿ“ËãNlrSéjvø¶²ö‹½?ÓÞ1}ç¨sÎ;ßÿ\_oÖz»®£¶wY†JÊŒ�k´Ûm^€è÷û¬™È;ƃÁ ;4KzÉÉ—]vÙùçŸï½ß¼yó3Ï<“oË«ƒ+×r²n‚çsŽ3)Yśо¶AD]"à/ cC0E&àL 5‡0àø°[vÊ•ËKßõú=ºhtÉ’%ÓÓÓõ/kµE)ôˆÖÙ÷Ƀå@¯ ñÉ@žç<φü-lI‡÷?^LQgv,H A» ûŒÚ©P<ЄÆq™QÇv»-ÓŒ‹â‚±~‘¸¯£º«ò¿ÈýiÞ+#®¿SÇ{b_ÿŠEw´_pr ˆ.Dz¯¼1fùòåçœsÎôôô#<" `XËû!…ôfÐ9?Y®k+ò’ÍIyOY]Uù÷›7oϲ¬( ÷bç_ê㿎«ºbj¬ =1üí‘«¨Ë÷–Õ«*w°K¾‘èµÊflæ¶~³ÏÞ™E¦žª½€h:÷îœA»˜¯E~˜3ð1aÕ¯K£,`xËILAiÅÖ|R·½@ØŸ¯ƒÔAF»"ÑFdš™j+»Æ_6Ô¨êü[GNRû]m·ËåžG#‘”TjFóÏ*3>!ŒC1ÚeMIùß<Ï˲ô• ëׯ?ú裳,Ûºukžç²Ê«˜{ü¡ ÍŒ1³øw»]@äþeÕdöX„þ4œØyG¹PɰnºhXBF÷Fõd %7¦l¢X†!‚<Ø/©—ÖÅ[‹ÑËG[#­3Ï<óÌ3ÏܶmÛm·Ý¶aÃ÷=×G?úD@@î‹ÈÍAŒpø¨â³°“){¹&’ŸÀBÀžSÀfVs}¾¥†:*#P¥¡ä#°Í9 y? íJFI œò†©(®‹ß)ÊóÊæß7£DƘⷊìÓYýå:ý¿)Fw\*á’ÂégþÄ‘W@ô³Z¿HÛÅvÆ ×_}¯×Û»w¯ÖÚ-wz·ÖýYf„Tôý~Ÿ¹‘`ÌéåvÌihk­®´zF¹•®º rßwÃr¦ÓÇjµVÕÓ5/?1])¥#]¾µ,/*›ÿÜL?žö¿ÖŽòÏåÉד#qd¯×Û·oŸÞ£ãâì³ä£ h“¬ýÌ€3Cyò«±yÃ3TnV ”Áûy°ªƒ*ˉÂr—%²ð@«a%É|¢—Êé‹ JÒû›ÀF;_, ÷Æ9§¦Tó-Mž–mêºv…c'îåyá÷˜£ ü}qñÔù¼»ØõF{?þñEVgݺueYÖgÔfƒ1{W>`õ°¶4ºéù:Ö¨"íBV$deû``nŒñ—øâäšaÇPžRêm:ùz¨eKj‘‘ê, TÃbÐk)8úè£ßô¦7½â¯Ø±cǾ}û&''÷&{K]y`/8@áÌ»åý¹¶¼<‹2‚¡?l€~ƇË|TÍ<<‚M&ænÀ"гbçž@,`-SÕ‘Q²È®‰ÄtÄèz¬®Î¯Fß:*RèÞ{û¶uC«{g7¹=™ý²™qF ë3žý°ò>MÓøÖxpÙÀìõ3úÑG…²C}im0n«s±“Ðn·%£šLüܱ®'ofZÖuÿ<.ÓÒ®´å)¥ÓÎã7ã&þרF–a»XñAkmÛ¶óæÎÈëF”RnÄi¥ã[bû=›ÿ<?âOصk—ÈK+¥Œ6ŒNs7†MOÞÐdOnÇ-+/ýP¼mÐVF°ÙsK²‘Páy¥ƒ¼3$?§ÙlB'{!åìÏb.Ä‘”RzµVg¨ú•u´*‚8Qõ©µÓÎÞo9ଣÎåi p˜Àâ“À,Šõ)¯,—–»ß=55å½ew†3Ùk„¼H… m W²¨¼†À9ãm€Xp xç¹:¿²'Údu¢8Ã):W«ªê÷+Ù~Gm¡§ g “Ml¡Š¢(„F!ƒ÷¡£W<´ ˆbœ'Ò<~>¤"ÒIýêQ ÒÆ{s(±ƒìóJÔ°ÌààÙø|‡Ø+`1^./”ÑrÒB&•/ DŒˆÑ¡"GcÊ¿(ÛÿÐfìE¾½ñéFþ'yóÓM^…‘Ô%¨/êhwÉçÐ¥}UUö³¶xoáö¸ä'Þ{ÝЃ¯ Ìc&º1rÊáÚv»Ý@Ø5œPo1# ÿ¸³¸×é©ý™uç8[¥”ºWÅݸҳ²ÈåŒZ£ÕÈ>”¥J‚LlâÕЈÏþ»úM«í‡‡Ò>q;ã ˜€è,?Mèãb¨Š‡ˆ3¼ Ì“@#b씹òjF]Ýܱ¼ÅñwkÀ6û@~ o×"á©!;’ô‰”( 5…™6nŸËËÒS¡&+¥êƒêú¨Zwu½½Ö‘Æ=fofÆU¤N”à‚a� jî^1ÞLzuš.Ï«¼ü«Òcµ½k{Ñ£äß&nñ†Ûpôæ‹™t°›8†¢UÇ–@CéH:8zPo©õ÷u£Ùòʯòy'/ÞVèH«Þ¬¯"ÐE<ù¸¡ÖÚûô?ÒÎ;;[¾¸å†nxøá‡·lÙòÐCuǺÙë²æûšˆþˆòødwdØfÍÈKsG¬äÑ JB¶æÄ ŠÃ z”V«%øk&6 Ø‹Âõ‡^sÕ\,áJ‘Ï‚^ŠÅÊP»°x „h†¤S‘7P½´Òï×X§•;hŒq¸ú5kM²¦P)LÅëCj›X¯}½½Önø+°„Ÿ¬I⿊«ªÞ]=¥”ÊÕÈÛG|××ûfT<;djúoÞká¾ e8º¬ {ïãÛcEF®ÁB¹è3ìµÖVgTéR§µvY²lìÛcÛ?°=º&Ò÷ë½ïÜÛì6µÖÕ’ªú­*}g*= k“삾Ê2,üËMo6›Ç{lQO?ý4>5¦,@Añ Šr’|dXƒó–Ÿpù˜RåÀpí²¼7ž½ÉP>¬˜µröÛ Ž,ܲ ?Ø#÷^—_“ûowuYež6éß§¥)Ygžaºù�<L€.‡VÀ‚¢(ReÞnªcªì“™1FªyNsø®ŒâˆèÃþöˆ§2I‘Ş& .ä�žƒëÌ—¨>±®_Z7ßÓl-j}öÙccc6lX¿~}çÉN¾!//+“ÿHxjªæjò+’©.$UÞ=ãÜqnú¼éU?[µfÍšÁ`Ð=©ëöö kúÆë9Ån@1òóe>,!‰%±™´Êˡ螲,ctQ´¹Pä"·1Ç•»¤g ±-c!l òÜÓ5´PX'ö.X~‚Þ9²EE=ÕÃèžM‰¬µµªáU$ uh‰êksŒ©®¨\ìjW—7•ÍmMûsËö?Þ{µGU·U­Ÿ½GÃËWd=‡K!Í»N€¾Åü~Öž`ÉT^ •ËÈ?ð÷ÀÈ⣈ä!÷ô€% öv¾`§¾Lû_άl¿ÌEÇDîq§{Z5ñ€ËV¤‡dçÎY–¡@A: ÔI˜“1Ã…ÅR“€Õ‚#*A�^Yr姉=Î*z©Á›ý?ËáZ’GZëæçšuR×ï«wιæû›nŸóÚKøS¤>ÀŠI˜ b?�LI-[¨ ÏÄSªqyH1Þ!ö<0 FMÌ'°[†k@§aÇhÞÚS3JPxWu]‹<ÌØØØÅ_|üñǯ^½úÚk¯í÷ûZkq}–"Åð­B¶Ã0cø)±¾éÝÙ®óÒÎ (¥\îÌ´‰þ!R‘âF-x!mê-Ä@±EâúWí°®bÃ7$6æéPšÀ„Y Œ´‰hpñ&Þ3Nÿd$K– €lÊj†§†=Ó‰«×7jЫ†,¸ß,ì·-sXböø¦ê‹ëº®}÷¡KXÚï÷·]´-{EfÛVߢÑÀñ3– š'V9Q`òÆæ+Ã÷ˬ±š8³·¹®8‹ÉrÂ˲´×Úümyã†F]×›6mR›T´+ªÎ­ê—×îhW~¨Ô•®;u|M¬ø 8rÚòŒ«äÉÉIT9 Ïb_˜·…øÑC̺mŠ<O%€ Áú—W&Ù8T±ýBÊÙŸ¨š¢…mЇfy5=]aúÝ«{¸‹Resgƒ"LÔ)8jŒ2s%+Ž2,9Œ‚ 9/ŽªÁº~`ì!€”¸@`ý•Æ”Lá´µÚÂ`0ؾ}ûŠ+(ƒc)ø] –bVV.à‘Å›óö^›ÜŸäg檡dŽ•N§¥+ÊЋ‰ &X€`qR¸MãF'I"2_€@1çD(ʰ[Œ +L€FÄÁÅ,ËRA�ìÇF. ð•hv)”G¤Ã^-gÜæÍÍéOLGߌØÐ“½!kž×¬T%ßu衇cvìØqø1OvfÒ,ºnÑá/<üôÓOOîHÖ/^Ÿ_™'·$€eä�³•LexÆ*[W ç!Iždƒh =4Á‘dù‰û]ñ‚§;ë[³/Îp>t£|{`¾nf§­¿°éCéÔϦšh:çâÇc;a™<:ÐÌþà o)€�<×r¹x5  Ëμ¹ÉÉ€˜®\`IÀ\:å\žåã‚’ôþ|íP;v5véåÚïñª3´‚Fù¹Ž©­Š$a‚ûj)°^½d3Eî~’3К0SÍuÔÇ Öq R´k^ù\ò1£(Ò‰ö‡úJUµªãí±©fzù5Ö<loøoúo|ã·ß~ûž={vìØQž\VË«ø¯†„cùE&ÐmH*Å\'0qQJEwGxn«ºâÔe\çÊŸ›Í¦0v˜@Ì׊í¡&}†pƒäúËõJ:s–xrÀòÞA¸+Œ8'å€Sl1 ŽñNÐ!LxÁP¾ÖºØZ¤×§;;£Ÿм÷ù›óòÒräªf:|ðÁQu»]a¦ µVOIz¯è-þÐ⣖õ¶·½íÜsÏít:7ß|ó ߺaüéq÷V§¿©9ˆ³ý6ËüðÀ€uWÅë>7¼£#? t �r¿äk¤PÜ."Su‚õOñ­�ÅFgºõÉVçÎNôÙÈÞk½÷þ2ß¿¼ßüýfòôŒZL]%IrÈ!‡ ƒ½{÷ìpnÈðX)r™cî«´ûœ3`€'‘ d¹ÉCOÏNÍfSžSÞ¬àƒyuœ±Y¿pQ,g!å<w¯gÔ3«Õê¨l<jcö·™½ßš ¦þá¬Ñ,O_ðáx1¸æñs4p4@© øÏ-×MR K…Ö#ð:¤@D=E^d,6ŒÚ™[À\,+¢µ®_UWË«òÂR)å¼KnJ̳Æ>lµÖªVvƒU/UťŶmÛºu«÷¾8»p+\´6Ò¹övŽr{°Z€*0Óø›ß²ÌvZ0‚¡¦)›û*ZÕf²)AÖÒæJ–]õ�»±èˆš»ÊŽp€F‡w­‚Z•˜Y ­ +� ¤ïpC›ÅÞ²eYj¥“Ÿ$ê5ø³Aý†ÚF¶qS£}A»ª*¯<õ×­[‡1�bºN´mØZœzê©^xáA”çùYguß}÷e­lPâ4f²ès±2% ar¥%b6 /]pã-V»÷ÉŇ"I™l¡¦ÁnºÉá×ßeGî)þ°(>^h­Ó¥óÞ{‘‰Á`¦©Ô1ìÑÎ}<ð†`TÉÒÑ8¥à§ÈgÙMy0`;3ÉÐ3a¿UR/[Uñ£ÁØpY±%ÆÿBÊyî^[Ô–ëÔu Õ¸F]óÌÓÏ\xÅ…î§_¢‹‹ôº^~ªÝ×ÊzÌ[eD+ØÆàô€•Ä¥=06Š—wÊ,ë²ó’|¬ô–Ã:¯Í—”åKJ;aok ×?ß[TÇW*RêEQãç")Š‹ÁËÃM´ÜêÍ:þFìÍlχY7Þ<º°äÇ€£-³ xÑ“ødKìn u–C‘¤ò>ƒVC~ K ³ý¸°¸Â@ð8'äÄO`* š*¢Æ­†LŒÅËõ~–ãçí–ÿ1ÂUª}Í‚­`²1jdŒñ¥wÎMMMmݺuÛ¶m­Vkß¾}kÖ¬Ù³gÏ ?¨ëZ•³&ÍÜ™ò6’]d?—»Evà­#P ¿‹ÉL FFÇ–>ïåàâ8C¨ª*ù—$úܰ®Ý슌œÏ~¿ÿì³ÏÊ-@m„¡^l2áqC¿‚aËæ2˜Ì€?) eƒËƒY–€bŒ„Õ Xqx#H­}êBÊy.^ÛÕö=j(I¯÷뫪2·˜äždúëÓëŒäØa¨ áI¶Ö1æ^µ3ß~´Õ­VKtãYÆ‘….é¦HÀâ‚—í:@`”øŒ|˜Q,´Ìº„j®®°Rª<»Œë»g±#õiU^QÖ/­“‡†f—ñÿÕUu^e´I¢Ä>h«½•2ÃØÍVÁ|b ¡V7Þ?Ç‚p*èûBN -ØR XFLÐ�‰YéF£1äÏ4 \½²ËràÎw–—BX½Šÿ†G}L‡e^tÆHeyov”€²ö-æŸpÜ ¦„@8ŽjÈîÖZ·ÎUUS¯žzò¾'¯»îº“N:iÇŽ÷Ýwßö‘íýCû鿦€tÄtƲLh– ËÛE¬°Ì$8yg& tss ³½Ùq ^aA}ƒ©'@NSÀŒÀS _ &Þ¾¸ã…SÚ¸{ã± ÔÛ ÓŠs"¿WFA¸Ú¨x½I‘;j¯€y!Ö…”óœ¾jU_­®þ¾ú>BÃØØXQ¾ë£OFÙ_fÉGé@yàÏŽØPrì-ÞÞÂi’‰ÃýhG+Áˆ0%–ÿeW]è1#€r)ˆîÖ2<ÚA ¡ì’LïÔɃIá âãì#™?Ý«fõ`â»b€B:ž.ú�‰Ù€bÓÏÃÆý†æñ¶Åjš™ +’%:ÕzØ;âɼŽýù›4MÓ4…Þ%*G) !W[)¶½AY*w„ƒE°ûÅE€|2 Db@»’‹!“ôF0 �� �IDATNk­vîHW¹Êyç6Î1ÛfÂN�1öñ«ëZ÷´ÝfÝQnïš½·Ý~ÛêÕ«§§§'Ò‰ÞÑ=•+½}h6*?VtŒ˜¯Æˉ,Á¹ª% J¡…#WxddÄ#;ÂAmÇ*œ¤å‚„£‚˨H_œ·däAãÏ,ðC0;x!÷s™F$©B®€&YGuX” ¥¢-ÉM9?Î(:ÙV0>èÔA¸rþÿ§¨)ßWý–jÉÿŽtÒI>úhQ:Ó¾å¡yŒb¢[,— Ä�|¬ÅÖ«Ÿo]ÌKÈœT$@pï,q•”X°ãJ| D6N�·a·Á(ŠLÃ(¯\áFFFŽ9昉‰‰Ý»wct©•U…+b5{5oà?,Ø. @ `w0úð0à:ó,‰\"pçà\ Hš ²xaŽQžçˆ’¼îN9»½IÏ¢A,¦9»,lŒ óáañ+–}D`âõ.Jäâ_y—B‘þ<r°¼aï}õòª^^WWZi¯¼ý‘U[”]eQÍ€G.x×ìÔGk)›€ßZkãÅÙ[³Þ_õÊ›ËnÚ-Ë2;+S{•ý_V'³Õ›Ôñy˜³¸33Ü kÞlÅÇAÂnåò|ŽŽ¶Z­M›6b‘i®úƒ–E¿hÀó&3žÑZI¶þ²ššk vÓ v?Âàt5<ãLÄGV㪅UAÝÉAÉ+eœTp«SìȵÀXÛ¯¢(vïÞ=4`Ö¦r³lBÖpD©Ç¹‰™ÁÔ2‹¡_€èÆ&ƒüüà7N\ì…ôYb4ƒWˆAö&ËPF ‡&RSš¦Rù8!¤j¡§Âl%&)AH>f ’€@RÌ dƒb˜Ä Ï–å¡ÚeHW‚iš6 Öà¥v][¯ç'n¡@fÅz©|®€—]š'ÞûäÄüp-ï¡0{efÎ1zR7>Ö(¯,½÷ù‡óú‹uÅñÏbÖŒ‘s.© 8uH®UU%_Kâëãü=ygÞûæ5MµSÉâ3oz¢E(ËjoŠŒ¨¡8Põ„ÐØh4àšêgšuƘ½{÷îÙ³‡-^ ÄÙL�aÇBL8 žbtQü<òÊ66c0xñ7Ll1à™õz©�ð iŒó7ÜfŸËNëë�Xãuéçõëy¶Xd•}·z÷gÕgå{½ÞÖ­[s>õÅ[ ûE‹…2Ø=Aµ]<Oõñ3�ÐÛæÌÌáE6hr`‡N‚<fh¤ uŒ‚ù9W3¢–¤†g£fÀ2ÃþS[/©óãó©©©Ç{lÛ¶m’uç Ôf¥×̉¼ð ,o[�@<ØÇƒ‰=Û@€uƒcù�D¤~,y–#P8 PþEV.bG«ÕZºt©||ÆŽø<@gùž±MŒ—! `üL&ÚBm¨ª*ÿ"ßý^×êÒ»Òô®T ú7÷õQ}3h€õìYÖ<iªWTÙfúVÝþùhýƺ^9; C�DŽ;<ž3“³èŸ¢ÆgÏ4ÔNÅn:ÈâåÌ þ{ÀN¹×TsfågfXXl€„yŒ½¥6æ p[y(‚´Á¨8+Øm[ â0 ªÉc$°"¹ÅO–ˆsűŸ.Ë2lb&ßLBỀ'G%pÐ'EŠ \=Q"N9_adÓ…UÐçú¥•>YüUõÕujÝQê¨á³wˆ²[êdsb#‹ŠR͈Ȳ.»Ë?¡ÑÆQ“ÈØl6Q ¡<AoŽ(̼2žu³ýênÞwSs=¾yEu1XF˜šàédƒ¬\^ú}ÞoóJ©,˪å•9Öè]Útg‹8ió±&(ú »G¶“8+‚Wh’0óª&ã<LJ4ƒ¯A ÆÍ_s#€ó †:¼Ã;´8@™efÇ5;ö±wº36ö÷y³iVrWLî© ~�åã–ad">ø ð¶?›…×u­cÝýD·}E[´*•Öº¼§Lÿ5ºqjÑë´79œù«r—8w™k\Ó0[LR%Ư½½Ûvÿg7?7u3ƒ÷ßl6A)”ÃÉՀܦ8Ž…ã¨$`´Ž4À-–W@Ç\gù'É%Ò€é'7K`F& 5rÀ È8 Š�Êc¸s°Ç–ØØ Æƨø N0£½/‡™È¢ƒ=4T'òü#/Ål#Ë͇yÑÊ3ufSÆ‚¬ç~x¢N¹H]ô!õ¡óÔy»–î*ßTºS\¾4oü~C¥|§Ùë3h/‚èσ;¶á ªxFóAyd® Á<ï‘�Íb'lí>5fýf>Q)óS7|�>(Š ŠúgµÖÚY—_˜G÷Fñ7b‘Á‡8 £Éx¡ú”±Y?4’ ‘ÓŸç9” Quâ}ÊÅc h<“`¸qm }I\�¶‰åv\ÛjiU¾­LOM¯¼ýʕǬüÞ÷¾wÏ+îÙ{Þ^{U?Ÿ5•áVI‚&—  óó=ŠPyÃÉÿL­Pž_F÷E¶k…P×µ«œ)Œ½ß–ç”æNÃã÷aÔkƃ ô&íwû¤J<ð@ñ,÷¹WZÕçÖÍšq£ D£Àâ@<[æEW%p1 Ši(16`�™ÿ‹3ɸe�|‚Ó8Ã,ÎÏ,Ño6ƈ•×øz–eÃ1\@ò-èž¡ç„ †eCOJ"—/–bT>µLÎ$}JÜG"‡‰léÈq>““Ã0>X¯£øJ¢…’È„£…”óœ¾.T^¨.üªúêx<^T5ÿ£iž2•¯`“%…9Ô[yDÁO “PEXL‘;¤L¡åo¤Š—FcÄDÖìRsU1P¶ðì©úÌÜg–kê ³øTøiƘôã©[ìêß©1N¹æ;›¾ô¬Ølÿ+Brš¥æ%Ê¡ �¥I^—cw"ž]ÉÌSâ²#³“™r›è e¿¬Á`€ìŽÒUúÎ<Ï݋ݢýî?_w饗®X±¢×ëU?®VïX½ñCG>Ê”âáÝ9É¿](¥Ô^5ò™J@ŠE##îà~e™5În”¦]¶lY¯×÷ÞÇ×ÄÙMYû®6÷C¦“®«×U­+[ѾHÅJܸ‡@Š6ùŸäÍë›É¾DÌýx^Èz£Pÿd½äùñ”ÙÌø/S¤âY{)ØœER¼³-.æá„—$ñ@‡™¥= 4’I%[°ÐN"Q8¾e<#‘» Vvv@~‚AW¢¬©Es�wÌ"á'šww ïà`/Yy싊O„ÅF¢ )g?¼®RW·ý¸/ýÓ—j[{3\¿’:,5ö‚Ts%mx’#ÈÍŠÔ[ÉzèHòlŸ9Ö˜?e‚#ûšHõÔï÷1ѯFŠ2V äö< 2ÞÔ“:ùìpݲv5‚ :¡ YLå�TÐd Þ�„‘'`¶á�û(ZÿÄ¥€­$Ã’˜.àáç@ä>­µÑÕåÕëÝë_ÿú“O>¹ÝnŸþùu]O~grê§Sƒß$_KÀSJu¯ïÚq›Ü”8çܘ›úîÔÈ #éwR!eà*É=Â$Y~|Mˆð(/Ž §Ÿ~ú…^¸jÕªŸüä'pï†<+”RêA5ƈ®Ùl.^¼x÷îÝÕË+å”}Àƒ¢[È` slƒÊΤ‰&ã\ì* ÛŠæ ´L~‚ ¬3AKc%CVì.‡”�1\nkàRƒ*d0`žó îYðp±‡ºü z)0Í Èš!lù`NÍljƒ˜Ã‹¨àv²o ‚ü“ Ö¼wŒ J¼µ†”Ã#"toÖÚî7º¾å•Rö¶ùT„Õ…”³_ù3÷9€KÞããå�yn%PÂSK)%>iÀ¬±8‚u´l¢Î^ȼîÎ;¡ì…†(è(@{DŠA0”?ˆË¼^ ?GôAtº"GØ??Í ï 0ŽšQÙR3òY >Çq,A ò<€Z­BH{|° Ú«¤Ø_YÊɆ„\%™ÁH9à€µxó雯ZrÕ‰'ž(÷ëàƒ¾è¢‹FFFþsðŸFtÏAÂ7ÆìüçK?¼ÔŽ[•)¥TÐOïN³dæL“ü<‘Åd9ÌÆá‡»ÅV‡WjRíÝ»÷±Ç{öÙg‡0æQZmV°×ã¼UQôHTµ*»ÂF[¢­[·nß¾½Z^ÕËkï½Þ¨Ýî }Þ„-ÂSk¹bP§æíH¨_#)íddç\§Ó‘+<Ü) Ál(Ga1X¹eÚ“ô$\‚æÇ„rf?2»O"µ\±`) 5«ð 1 >v®S$áÕ!2ì,K­‰² }9÷X, È:¿ ýëÀ-€¿%K“â=Eÿ¢~û-mÕSJ©ìš¬`¿ýþv¹¹\H9û•M0Ó,3þΫ3xKÃìA‚º,Á'Pĉ ¡¨1ƒ¡†ñŒ8¦ÀïR$£Â46&é³V#g85Wf›§ô€ÎäÉz 3¼Ù(AžÞÅ‹—e)P;V/Yg>(î ° Ö =€K¼Íƒ[�ðy®ÃÍÖ8— Döá�Ü;È¿,VÚ¯u-Q[)U¼¸0[L4©\i£eiÔ \ôx”½(kÜÛ`6*#~ *ÉX)ÕúÝV÷ÇÝþkúO?ýô¶mÛ°NÛý|·uN‹o@üº®“k“þ×ú½×ôª[«x﫳+³ÖDIä¿å›ý¦èsKéˆë�/âÃøÀ‚¦T{Ë( ‡1d ½dQ×F Á¥3Íøw±±¨Œ‘¥È�hÆ›1,êÌP3úE¤ xDqìæUSù{Ld!ZˆÐÁöƒh…ÑŸ!]èÏÀC0æ¿‘6Tn´TKrPPbÄ6žU¯©LfÚç¶q1ÔpÇ»Îÿî¤ïHŸïãó|O9X#`~=¦šÌ0fÅFÌÌ­Âö2˱(…sÙ›u ŠMޢ續#¾•l'•,Ÿ.¥£%ŠGùù ŠÄ™Æï ¶ÔÚˆ_¼Áìÿ£–ŸÐh4Ž>úè%K–ËÛ€í 1²é¸ðÀŒg Òu±„IY–yžË³,“´×ëõD-¸×ëMLLlZ³ipóà†é6lØ µ·Û]½zõM·Ý´*ZU|¯ïõzûöí›8gÂÞiëÉZ)õ‚¼àÔSOÉóÜÞh‹ÿV”q‰š�Ž¢˜*ñ ÓïáÕÓ&ýQ:øÛAvr6==Ýív‹•EöwYò­llE:ÿ�RÒÿHõ¤üé \\º¥®ýñv}X]••yjN AUö°Á‘f‚›àÏÆ”?Þ¤Û P3gújæ…žè"S'À5`‘ ½Š¢`¬r´—© ,² VД.f§QF·ä+áȇ|þ 6Æxò\cæÏzê²`2ß%XÃuÇoc’Cw²‹~ÉŇЪßéÍ:£Ï]P’þ/�¬IÆr˜î²WaY¼’—|ÇZdfP}3ž‹|4" @óÞ2š–àå‘#àó~þæ?SàÀødÙ1œu|p)óÙ£LžLÌwíÚ555ŰKLÊoÁõ—¯ˆL!<ÞØµfgkV{䆒2"‘0ˆò<Ž4ºªþy}÷›î>ä‡$I²dÉ’ûï¿ÿÖ[o]¿mýÔò©%÷/©ý¬é®'œpÂé§Ÿ¾y󿉉‰4MvEQ܈e+Bžs.>äScA’u±|í“/%ÑK¢âÍÅà#¯|ü‹8¾9ÖkeæØÏ ¸ãàc·Ýé‡tye©µ®Î«ÒO¥v«5ÛMîrèpP$‹w´Ô+¬¨ÀJÐ( ¶I°+ÃFÝ ’Ôu-^ ŠÖu92Eß HŠémX9Psxq¶#XwãÙ¸d€¸OpAƒ’9˜• b`¦‹glŒÁf…ŬÏ÷ ó"�`ž‚Þ: Hl‘2Ç•¥ës~‘wǸxulb³xñâC9$ÏóM›6¹Ig·Ùò¤`m¿¾¹XG F´YAVÍÕ­B,&>cÐ|ƒyù›ƒLyDéB‘<˜ q'ÎŒ/£™$nä%i1–…ítä!R€S3ð ƒåv» =c<Ný~¿ÛíbœÎ›Cìý ÔÀûËqËÈ'~“ì h#¨ÒIú”Y×ða¾Cí9|Ï'¯üäøcã/{áíÜþà%vìpÅÎÏ¢yvu‹3®(ŠU«V=ùä“Û¶mÓZ×Ëj=¡ë²6µaÍ qû˜Ïʦôº£í}6} uì½T¤Jåœ3Öðœ ËXH«æ—&y8±ß±J)ï¼) ¦ÙP‡¾œ|9ÃÑ ÷0©åDØxò‡ô‰ñ¤„f¤(Þ Q¤D€ŽÒe¤Átàm-èa+RubZ¢_ž�†IÁþã|ʉ<¶<‰òXãÈÌ@cye*! ÍÀXÿµhô¬¯Á!`%Hò3!dMyÏÃm95úýþÔÔ&—âG¾rö3°6»„O~? G Iˆeó¹Ú’ý�¡GC<¿H`‘ Qä+tÀ à%8<<¡a5EF–Ýpô!gÀãÑ3¡±ã$ï«L]åJY¸sÐÛg'.ø§!0aÁ2ø˜ðCíƒP˜8€ÒŒ‘‡Xh4AÌeG/G ›8º!ZúÝ¥·üõ-q3Þóª=­/µ~üà¼Èñ¶µÖíoO~m2¾+ö~bbbçÎò»:ïè4¾Ú°}‹½.d)EjªL5æFvVA²òâ(j­-})„ ±¿”P¦Ü’(©úCZGåæì·Ï÷Gà}O„i„u‰MÉ@X ‡ïWr0°²2¨ZX‘»R^ˆfœ–©ì«æÏÒƒ‡Eú9Ø´Ëq~Š0î Ñ'ÏJ=èÎ:¯ÏT~)˲L’S°ßÃ_�åñ„†Ñ?f]²[¼"©F<bHN9)"V­‡àÀF[£ò¸R?©³,Â}Y–y#w‡¸hu´�¬íÿYŠk�µè÷ad cž€t 24/.à‰BĬü`¤Œšˆ‰O¬ Â;Ø€ÈÅps�ÜH¥€\ئ%p¤gkNW@¢a"°97|l—ÂÍ êÁàÆuàêžMŽyb|/Û„˳2ni6›È|yž¿àÓ/X²dɆ :NáæH/ ]×&Ùû2»Æ6nh(¥ü>ÿ`nöÿ´Çè˜ë_~3Œ¦BB&0&lŠÇQ|Á‡`}’@´‚KcÖaR$.ÐOXU…'™Æ:+qàox-àèà(þ˜ä¡*B×Å)„‡ðP¦`ùNÞžF–’ó3 $Uè–*/Êp“Á¥�Oe@À²‹üXNKøk•ÖÔX)™Ê%jµZrq¸•‡=#ók˜ È‚¶,…`­Õ:~$Î.ÈkPAôÞûC¼:I%ŸIÔ_,ìåì¿úô*ª&0©•vÞüÞH´#b$A‘Ö'�´€ÛÖ´·°üSs=uP*b¶ ¨ @ o8âì€"THÞ lµZbñLÍHœaŠ Ivgؗ怅½"®FÑáY¾—EjÑ:°¶O¤¹]³ÖE^œò&’·üX¬5°r6‡ožKsÄù¨²Pʾ}û gx Q©žöî ~{à•דºõ-µYéíº²s«I`,1ŸYË‹új®ÑŽ º$à‘ã%Gܵ�æ´*|'¾ÌXáTÄtPÂîñ†Áâe ¨¢1 ›+rVyu&¿aü#ß((„#‰tEQH;ȵb4Ìí6W3Öm ØÌå‘*D&»èó‚oŒòÒÔ™äÔ‘ TiG<ögn‚~(æüÎõÏ´y§éÝÖk¿±íûÞZÛýx·>¸nþuS=ÿ_Ï`í@}0s§¸öÅmm´Ñ¦wmOuTãC »Ãòš47FÀ˜*ŠšT|v†—Q[Û‚]ÆÅ)k`0| ‹MàÚŽŽ&IÒét:VîQ‹I€ÀƒÊ(ŽcÙ�`•R. à…î‰À=ä¤äodG¢+³³®Š†øî€û€8ÕëõXÞ‘ºùsT•`„ă4 ÞøÓà>àƒƒ§dŒqºé«§Ýîà—,™©÷½^þ[yãï_–| :Q´ea°¼7!ßãCakÙH.šô£PÕ/K‹"¨…¨$ëG ½¾÷ó9WØ“Î�§]¦ $!Ø û9™aÙY–úW¤ö^d¼„u`€ì¥Äw|”/Lýb§ƒ€qŽ._)Õl6ñ‰@Éqdwdb¬þ�úc_deTøv<2ìñ`p;ëp‰Jøó°§ÙíÓ¥­¤5ýíi×rZéæšGªTÚ,0Ööw—S¾¥ŒŽ£?”Rµ«v£¿3Zž]fïÌšÓT$É‚¬T�œ $54‡<; 76|cËØ@ý—Ù\\.á9ÁXuñâÅK—.ݱc‡<-#qcÚï[€äÊB[Øàc¦ v0%Éõû}®Ü1³uΉ&ÇÜ ˆ–gO “Ê9^à°:e{4‚³kù3V�-ò.‘\R ©°J„šu0:B…Þ{{¯ñýFãŽF]×Úi]é%oX’]šõßÒO?Ác—I)ÿåâðN€G^ŒÇ?©¹Ò/ÌFÁ&?OhÖ™"™ ùP¼IÆuÆ|±HÌ~DØBìÑ@ý@âg ÜzžaþÇERÐk‚#ÂhwàaŠÔÂo@. äG¹þÀÁ2€ˆA¨A[Œó nq °èÍ8ùœÈE»Ÿ—u 7Þ’s&fQóQµÀpN¼Uä9ãL=¨Û—´g5mVZý˜<Ïk+œ[â’;6»­ëÚ­qêeª8©ˆxq!°�û š]ã³&)HAŠDÂi@b ÚjTñ¼Ã}=ž[6däÅ”iŒ›„�0 ¿al<B³ÕDÐäî„™£œy,Ì+x¶€Þ°Õ €{L´Öî W]=‰¥ž7«çsˆã±Ü¯|ÜÄn�ªH“�°)-’Wµ2k†»ßÍf³ßïk­Í#F§õñº~|Ž 1 dópE>LÆÁ6e:ÍD[™—E ´0Å– ¬Ô"?P~2'$H6@c uäg˜Ì†Ó¬# ùøÏ|PëÑóYbf?kµ¡E“(Ô8^*â9<·wŠdÇØá›D@ÀáÅO¶ `õqXÑ€&Ä0#:~0PHj\L€E)­6‰pfØö¡—ê ˆTKØV'àÈ-¤œý×åì݈+/ã8n·ÛÖÚN§SU•Þ®u®Ý W?\Cf<Žcáç ÞÔ&€Pñþ&wÓP*D!ƒ KP¶i`$P!dš,~ï`0ؾ}{·Û-Š"Ë29¸¼ôß6´lÌÃbÌÃa,Ž7Ñ8•¯‡6'f 朢ðC‚xÁ*\,ÃbSªûÉn}P~2µ‘ÕZwØnÒO¤œe{ža€–ÍÌ@~Ï(¥AP”hÇqQ&Ú)­Ž;î¸+V¬]»vݺuv“ÕMmŽ2ÑÚˆ„Ò<q1 d‰q} þ`Eo€2 ‚ų#â„ßË^m8‡BßÂ"h¸Üdc(Âm"øÐê2Ì´Œ¸é,BÑn·e=-/V÷™þÀ鉺ŒÍ + ¹æì¾X…bÔÏÒ´`ßñÂNš )’ „’ÊÉ[¤ÐE‹'œ]E2/A¶à‡‚eOYoj7j®>”Š¥GͤHÌ~!åìÿWíêXÅQuÔQöP»¶³¶ÿÁ¾;Ðùƒ|ôùHŸ¢£§"ˆÿ㈃ƒË8kîò›;_ þxëš% Fƒ_ GzeèH|—’–Í£‚Ù>OïÑLpÖD “_1ßk@¹´bÀåôñ$†b¤~•ÍIð_\ þ°xÛ½÷ßkøŸz_ymtÇ#TWTå;Êøßc~êÔÌ2 ZFî3XÔ„ù‡A“$Àˆµ¶teY–ív{Ŋ矾sîÙgŸõÞç6¯«:€×™£Œ ËY< T�¼‚÷ÆÎfó'‘óýŠÐm@¼‡¯$ê¦ÀÁÄn¾ +H*RßÀ=Å(J‚/�3Üä¨H¤VsmÜ‚½+T<,Å? nëaS¬š1Æ¡•n(¤‚iú3)}P:Èu–d#­$k²181mêZ(!PºöÀfƒrma§+¿QI<MCMñº–AVÕ</m€Ÿ¿.mÏsúÀnõ#ÿBŸoÈ×u×U¯ªúKû#ï1‰é]Þ«Ž©Êå¥ÿ‘oŸ[2¼.9Y”,.[$Ô/çŠYŒ Œ)Ôw˜?ƒ€ µ–ín1`.ëà]É£{4ÌøDçÁ�D3™é€#ÏR¿ßgËT^ç¥W&äà Š¥fô+!âV8ß÷f‡‰¢(jD£££EQLOOk }¾Ök¿Õc$ è µ­„H8Vö&qŦhƒ8Ž«-•>Qû#|=Q?ôÐC›6mš˜˜¨ëº>ªÖ¹V;f‡L’äfDùŒ3 ñt±rÇ‘)¹´gî‰\±f³)Ý0 dŽ¿\ñð¾W0Lâ _dz6‡n�� �IDATÀØc¾K,R2¡A HCx@š£)3Øìá=ˆœBÆ \‘F†ˆ¼®/ÿ„5ù\ ÞqoÁ’»8¨h4yr¦HÖPüpW€ôŒ”hް7ÜûÁûgº3Ž�’g×(\UNƘÞ-ÌröçËl0vÒú—{ÿŒïÖU 5úþÑ<0zu´¾½¾ùÇM€Ï¾’E·EÁ†?òlŸÃØ}ÀSâÒu9YdÍ‹FCƒ6ØâÕ0ž%â÷Çc9çù;Ô�ѱ ‡ 6›aºÐ–Úív«Õ’MØùW,@Ny{”g?üL–§–¦cÌz“6Ó•+WžtÒI«V­ºÿþû£_DÙ[2µBN s',±ÃB“R²¨ /÷ U¤+œ®MóKr’ww¸ÉÉÉññqõ«S*×qéºT.K�|!ÿ!–±w 1Ë–ß,¸Ç^^à8¾pèèˆAe Z±ùt�ùvàTs\gIZLXgSvþzÆÀBä3Ã:Fj®¯9;ýð‹¿…·)Ê1¡ÃB&Ñqoš�ýï6±Æ ˆjxóœÎ¹‹ÅÅ6d™¯™[}òÍfóŒ3ÎØ»wïSO=%Ýoeq˜# ^<z~íç}μ1ò¯ðÙÝ™{‡ký[ëÈ#œøÂD}Uýš5¯i4zZGߌòßË™Ígõ "‰2väë1œx÷¨h<‚òx€ÍB„xAÐB¡Sg‰ Ø¥¾ƒ˜š«ƒ.a>˜#a”:¡XÓëõ&''Ñ á`¼Ä’…¸¡Ð«�†0 vV²³®Ò4=ùä“O;í´eË–I ))äÈ#\¶l†³Z2ZË¥CQ¯HµE®†´V@9F£Ñ@.i­¿>Ÿ¼~²(‹<Ï«ºšºi*?+¿ã$ ¢«Ãÿžåë¯H%O> ×L=à;Ž}L¶ xnjFφ3,² Q¾ù<¼ð$ gUÌ*`áqz«ÕˆEÈcÈ Íf“±è@½‰¡é`«Tn"ICHðq’â'‚%Dù7¢_gùÝ€{§U~‹ÌJáRÊ`#X�X¬©ìTñT‰Åªñ4!UÈ R3*r† b¼:>>Þét¸¡Ç²Ïy}‡ÇB—³örìÛú`KµÕÔÚ©î±Ý-c[n¬o|Á^üƒm‡oÛµkW6•õ›•˜äÂE[3Û-‘`Î^h ®…â wÊî› a¼¤©f¶1�5Ayƒ‰³ØbAd!ŠAø×²µêw¶qHmþH�x4Â%° Wì¦ÅGutåŽvå{Jw¸+ß^ú÷øî½áûßÿþÖ­[뺮Æ*5På¾R~”, Ê]‹íwè‹HvÁƺIùø###Aq*ß•ç¹ÝixÿÕ²jÏöÈG[ô›‹Ô”£„xÍ':p¹@ÅÆú-{-CE2“ pòæÑJp”Ü#Ãsœ+– ¬Á•—OÜfYN”Cˆ…¬4 É…Ëmþ2ëRdÖǶÜî4M…=Ïm7«BÈÿÊŒtJA¥€ž1¨ÅŽsì �˜šçjøvî)¹Óm6›"7ŽßÂÃTžfa¼ŠÄ‹¥ò’ì(\9™¢»Ã*8ì ‘�3Ц(Ò” O>ù$澊ôñ`ܼWÐÿYGkm#kWÛÅo\üÊW¾rçå;;íÎO<1==çyY•ì¥ljþ²Ž"-Š`ö(CPZ„oy¢€x è`÷ÑP&´L‡Å[â%;œiC0�}Õ2`#x\± ¨hZ¾LP¼O4sj®kdZ“a ì[.Ì‚�/÷Åë ÕW#çdÍ·5z—ö6e›Ò›RßñƘò¢Òl6åÃå³ñ³ w@Èfzµ™C…|x&q^ÞÔZ«jÉ…KÂK5¼S£££q÷z½Àª ,�æ&ܧV«¥HD•OóÔ™\¢ú'y?Rš0%M'Û`#ÖKB±á8Ê%³Îæ[°N³L ×‘Æò6ÜH`»`żötáŒUâÁQD‰r| ¥8FæI¬2Ç#úÀ]O;cn�Eùé„Îrïó·ú˜§ÎÜEž? ý*^îa ÒBÊÙ$é™§®ì•ñâÞk{«ïZÝëõ’$Ù´iÓäädÕ¨ÊW—Ñ·#Ls,F—€³ åàöc Êê2xÒ¸Þa`;*�n¬%ìAye‡»ž!£´ ¢{€åG¦Ò1apëa¯@”ÄÚ ×Ñ,<Ê"†ÞûÁŃäö$¾;Ž’Èßìó7æfÚD›¢â¬"}<|j ÷éôƸ¤}X2YÞÌÈÈ ˜¥¢Í+Jæ`Ç›…!¤h�§9^n1{°Ê`ÜÅrá ð™E-Ýx_òæ…!’oÊ8Ö0I žw™±2Éó3h3Çg'(9êáððgóp†Îx͈eÔ¥EÃÖ½ì @\7…1\± 7,‘�ò=þÌB´ìÓÁêÎAŠbã(~Yöã"5W·—÷˜è² \°ÖdrX¿‘÷¨ h HÆ—sRÎ~Í=…Wǃ “7O>úØ£q÷z½ÊW*UîÅ®ñx£Œ~…- ª‰@¾B‘z Bˆ¯Ì¯p8H-ÿ ![F¤*Gõ$h‰„ x™0?—ÉÊxðxãe¸G¸3°œb �˜›÷7~3˜Óð!`‚9°Œ ðy½÷þ7¼íÚè¡hÑ¢E'tR·Û]{ÃÚ郦³Oe>öååeúÞTk·ÅÅi ^�š+ÛŠÍ xL°£›t)²ƒCwôìU uò¯²ìÂ7=ˆtP"´ºq6Ð;"´aFÑ®®\¢`Ç[œjFr Y3,ƒ=Ïe>{F y@•ý^AÄâwä¡€…Åo˜ ·ñ->†Uðy5-ˆTió§âXíDÄç=Plt2¡NÎ a ÈA—?8`rGxXÈK \©`ÌÉBé¼Pk ö´²F@äc}<~±žd>‚žx!åìg`Mkmïµñ!qïÖžú”òÓ>òQöæ¬:²j¾¡YèYÔ!Œ÷T� õ–¡€ù 1|ÈP*ÊwaÂÏmÈ œ$ÄÔ¯n0?õT qÂUËÜb>+@KÏù~Ƹ�>#B¿"¡~¶g4&�˜ÅT–¥_ì]áÜ´{Ñ+_tå•WîØ±ãºë®ËïÌ£“£üã¹ýŽ5™ lDÿÁ…¤¼ù©©)E.œ€"eÁPÆ?ǃ¹ÎwP¢�è‚BŇ)¶ŠÜ óoî³ÉQ5£¡×;^É„P7&y<iÀ</çóš §œUö¤€ßP)ù.ù¼ò`Œ!p(ûz¨M&°]€2aŠ©HEù^f*2ÓLöåÁDà” Á]¢9„kå -%`B[fi�,Ɇá5E+–L¶D©‡« C É놫•5σªH%²ð–¤â •O— jxH¥öa I½2¨[�Öö¾á½è[Qòí¤¸º(—•u]G_Š’G¯†¥.SømYƒÕˆ¿BÎ+x¹úÆÚ 6 †&(3vîð7d¥aÞUdò%ˆÜ”(˜ Vñ³QÎ…¬[Hà°M!?«¬’,‚ÈãÈ·`‰¡�H³9Ж-[n¾ùæn·+æI’º°Æb¯…�_`a;XY`ûWÁ¸ã„V�[#æã¢9à• ^7鿵_Gµ³.º%RÛç,màšËoDáÉ9˜†ûq§X:Ã.¢y9»2P…`ûT¶áÀi’éÔÈj¬¢Ï2•ÁÅä1'Jø·à‚3¢H'—·[Ø)‡A3>ð¸�šP=HÐg‹@Î58Æàà ÃÀwAƒ€É&8ÀìÁä Í1œñ:(W~h7±]Ë-wáÔù;ö&æö ç5@`û5@¤ž÷® ØÛÂALþ.™Uaòc @cØ#Ý9'¶+ü7¬uÁ¤š ÈåÅcðjƒÉ�sÏ„÷�fo\£g®0P,ù¨ÝXcQ ;Äqy'¨©‘wÕŒÜ/ó\ñ¿0ú”÷)dù½hé°ÙñÁÙÔ>lëj}‚Þ½a÷Ýwß-fˆJ©âôBïÑñ¦X’p0HmÎÒÁcÌ"ÄÉ)ŠJ‰¤<•‘fØR9rÊ_Ÿç¿‘G÷Gz k_ï.T_5?ÚdÎ/µˆh&šffÍ1þHرì ¹l\:€Èë#¨ÍÑ“ñÅ6&CÐÅÁ›ÍÓx!ïGªi€{¬B„©¼Ô˜·ÉPdÀdCÄ Ðn"[¸iC‘7 (%c5cÌ àí.ù³Àž\ (RÉCƒÂm7×v¼Þ�€Ž÷=‘½pÍåxCS<ÐÛÆ}”â 6gÍ_¹ù°ržkŠ9¬‚’ã\ t»7åørg6Qe2’š!ù{Œ¸1™çX<\ƒßÌT€0h¹ÖÃãmmÐ…¥í�%W>fY–"†.oQ°Ó»wH›ÈCÆ-C^�Í ‡ $dmʨôGøzS= ä·Û¦­VTjŸªwÔ<…†¡fl¬qÀ= ü‘}A�˜ÆÛQøh€¡˜ósózEÝþB[?©µÓZëêþêÿkïÛ£«ª®õ×ÞgïsNBx…7òP•‡¹¡" 8Ð+Œ¢ý)ööŠÖ1¬XGk©¼÷Òþ èe”*¶ÜA- ?‹ 4 E.„`Ã+ †@„gç¹ÏÙgïõûcÆ/3;^íLˆëûƒNNÎY{ïµÖœkÎo~3Õ+•øU"436³`¥à@ U«VT4N‡È%4n“é„äß¿\× †ƒZP“B )Ü„ 1žÙFKhãFñP0¦ß.QjÊiü8‹DNÃÈyÂWb‰¸¨üçÅd¼¹ªhX2ÉÙt{Ñ8*d¾ä%9…ˆ‚~hØÇšÏðijƚŔFMì8~”/„¹lís¶èþƒkÎ×}#ï›Ç‰- øqœ βãä=erš TîÇË•A\¦ÉDu Ìð5ë²Q]A)_¨Šôñâ¤^xtÎXCœRÅ[b#ÞÅ¥ÝéÃaEø©ˆ»yãBâ­ÂtQ’“/r0ÓÈÊòü'-Q:éƒmŒ­Ÿ³¥I(—7„‡;‰†ç~êjD^ 'f'ì§ìð„…éTÚ{Õ3 ðka)$ ly^ ßNçWZít¼¶`Ú¦¼8‰sazy*Ê›B’éžé@U@î—fÐ4BF:Ç…áÎýŽÖ]g²È6!4Oà Å{l÷ˆ‹:ŽC•>•ÆôÛ½Ôí)÷G®«õôYºvJÓÎ6 7sj�¢²|SFØ“7å"åâ‹êKD¨huÀSAjáDäo¨<ˆ‡†ÐšˆÀªðuôD ¸ˆö}t!hŠˆâ˜P(æZª““‚>§‡†ö}Hnº »K§UL-Gxå,ô:ygßðeËA µfggq±Vž/鎯8ô-46 @Éz6ñ‡ï;üHë‹bñô';rÚ%Y/Zcð¬ë:%X0¶uÐù©œ~ Z6ÇÆ nù±ŒWóˆ0üAÜ#Ÿý}Ù$ÉÑLŒ³®ù'ó¶ð‚IÝ {èEü$]îµÕ´¦†¼^úå´iš9Áñ¨ð’Ù$œGé”Sߺ±‹HÿŸ´BHX\‚Í 2=òRɶñx}ž HAβ^½­S&9<Ùnr;#Ë8p`nnî¾}ûΞ=+Ns¯é|ß -!IÎO'ÄþàQÞ¡‹gM(ã%·u·è=o”—u2«Ã:!jÜšø¿ÄeÌüg&TÂÌ—xóÍ1®–©Þ‹2|ðƒµï8gŸfN3|Âð¢.Þ�‰sdpîäZ«˜½Ø^}rM({¢O¦8!ñ ùá›S´} N_¢Ž?8Þå–+°'à(ìS7À½ª§Æ|!£€ØNH`BÒ}¦Yê»Xß"âõC<LÂ'|ËXk ô®,‚�m+T�†(¶r_kEß™†/.ðiLa¢žƒŸº(V@Óî'¦WÜòI–ùúØóŠQðqQ¯à§ ¤h® &g€“ò hEÌ; Àó¸?$x G›Q^àÅCõÇ©Kºþ/ºišYYYvÆve½’í>ðàt]·ÿÕöÚ{ú]×u×scoÆŒOŒÐŠ0…ñà?ó\ßÅ|]�@µò<Ï“mŽ­ZµºãŽ;:vìX^^~ñâE)eZ¦¹ãÂåL|® ¢7(§wF;ö?Ùš¦¹GÝðïÃ>Uiì˜é'ÒYÿ–Õ)Õé–·†ñé§Ÿ:Sô¯Ò²¿ ^ reh®L|Þ¿€k>7‰MÔm»ÏÔ…õp€À'À¨ gnÓ°9ò31…þhqÑÙ o_áž)ï΋1}í!èÎûê‚UL,Dšº<>Á£Ä>ÛìKvò É+±@­FíßĪäÁp_ï+œb9o‚Wéâb¹ £Àƒ%ˆý‚ÄÏÏ×¾D™œ&;å J\0íqÄ.|jW¾&È— ßC:WÞ¹žw¥åÎå+ŦŒ•ýÄ*ì&à¿ÁMy™ONúD®1 xÖ|Ncf“]D1„È¿”ʉ…Îhãd>zÛÊ7\�›C9ñšî9¥IMÓŒ¿ì ˆƒ"x*¨ëzÆÍhû5w¬›z e®3—b@w„78@ÑßðN°Bt]™¡˜Ëh™D"±uëÖp8\]]N§Í )t!éëCÃ-:"Z¼Ã^:œN|˜~Ìy3G ™º>Ù Î> :#çì'윂œÎ¢ó÷üÞC=¤iZ^^ÞêÕ«ãïÆ#3"æQÓ«®OŸÿ„„ �ª)²jFÊK9ó@Û@Ö¬,Ú‚Ÿ$ôõÐïBB6P³% Uë0«y$¹gµ :Ê™iÁ`|/¸>8ÊЩ…«$À\áù"»C#A6‹×Íà0Á»ÑpU\j܇žJáJØ¡Pˆb_¼V *Í:\&¥y°Þ!XÅ Æk¼Äwˆ‡réî¹ò°$Eq‘Þ$Q”Éið|>Z<ñÆ(ƒÙ@šŽG۸ώT6r†XhP}“r†èˆÅ¢a3,�ZÞ\Þ—(âY"ßiŒ~›H$È\ñ2 P0¹Ž½ÏÙäº ¤4�oÈHÛ µä‚cÎ;(ó=°ÙtÓÈÞð(TÏ‘aÃ�ù€_i·³ek©Ó´rÍÕ]MÓ„Ïòféöve¶ÔmG«¸¤¢íü´GÓ„Wpöp‡ƒÁ¬õYñÉñVo¶*++£û …ä-ÒãµýY[a6~ÅCÇâ7RÊäÇÉÖcZ×Ù?¡ƒc‹báÒpº,Í÷qÑQhåZ—Ü.Æ ëׯŸišÃ‡/**:yò¤l/鄿Õùï”+âZG¾0lý™û /´8dî5éaô@»±í’?JŠ'…ùnƒ)ÍÉî¼|¢œˆ†­€0C Î‚ËÏÊÊ"q[ŸáçÙ0³)[É=ÜXÚ£ù1…V%rE¢¡� × [ÈYû>UYNðƒ=Àoé³³³ÑîÈ×ó ¾&}>·dœ8NÆlª¯¢–v^´½ nhyL›WxõÚ…~­Ÿr°0p@ô€×]sÙs®2ê3º øÊ§}ÒÅØe|nëk€À+o¬Ä¿W×õœœœ®]»æääÀGæºU¼!/sáý? šëÓà`ê ¥E7ʶmJí€#@À²ÄѦ…g¿±žyI/5@¬_4”}£» [‹ïª«f¿?cž02#++ëÆo¼ñÆ©¥‚¾ZÏ Ìx½ëÛG"å€^oåM¯£¶œu+]×ÕŽjZ––˜œÐBu¦ÔyȱÇÚá-aÜažÓB£{ø õ´…{]c³ÁgN]ƒ¢ †{ŸËÅñh ŽãTUUíÙ³çðáÃ%%%Ÿ|òÉÉ“'ãñ8Ï„‘“Óy9ÁW×uïO»¤Î0ÍꈹG‚^g/Ó>ÃÅfˆ@ˆ‘ƒ¸w„¾]^x†OJÙ¡C‡Ž;B`F|!™ÌÓ¥\ôŒ2Á­Ã ö §ÂóÒDÆ8)Žx§¼²sI{o#Bèsã`r t‡?á‡rð,ðf¨–`‚ÑmñÑ™/ ˆ*ÁñÙË…sxê—G­Õ)§)KsxQbJ<ÎŽbì×È©¢BÅÇSä>…58I‡w>™ÈF¿^Ÿ"=Ï÷J)Ûµk×»wï²²2ÐRQZD^!ù¶Øš}$4¾TïBT„[D ±¹£ˆAs^îJûrõ<IËó%ˆÎóJr¼‡wðäu樂ĶÂO5½.™”››;f̘öíÛ¯Zµêرc@@h‚wGåm`x¯RNc¡)kž’­ó „¡L¿ÌÅß\ÔLMJÜ4J 3ßt5:ª»ð4ጃvœz$eÎ3‘_©Ã^Šm‰µ^ØšúÌõfú±ôùÂó}ôQyy¹ã8ŒF£™‡2ú&=kÐ0 ©o·Á`èíÁ¶~^œ è¦N™x<nÛ¶¹ÃtÿÉu:;ÙµÙÜïAR„g æl¯¸ôï“‹Ã+ï[Ã=-þ€`fÎ…×Ååd¸v5Þ½‚g†@Låz9M‘¿Èe8m,\/…F LƒÄ/ÑðzpâN!?s¹~†¦‚£¿OnŽsR”ÉiJž4¦Ž/ºÂ«j@ öÅ"¸SÃW÷2DCùN«Æc¹b0¼Ó"H$rôèÑH$‚x´Ñ•tOÞpŒ¦>\8 û.­Ì0¿±~x¦Š—ûñZk¾¼i$‚•ës¡Ozoík1B–2ÆâsÍMCi/­I-‘H:t( E"Ã0„)„+¤+u­¾Xäð šÖ6JJywñ…ÊgñZ•¶r9R“7£Uj¦cº†_P1|̾#,MÅ`0صk×H$rîܹ:º¹¬¯ ­Óù>ðºxé6égOÄb±t:OƵ֚;ÀÕ¶i‰K *”ùD挢Uœ±R7Œ€.´ºÙ{ýõ×_wÝuEEE/^L¥Ržô¹Á�xÍ2J}‘¬âº×ðœ’É$…’jkk±4x† ÂrnÎ%ˆãñ3/ÉB_2¤L@Ž ?Õñï…â¼yÄ0¨Ä•‰WJð(ÎD"Aß/v_?'þ «I¡K=)œúC𽼨ƒo&X¡T®î ó*“Ó4±5Ú ¨¡=oÔÇð�(¸¼<“Œò¼c4•Å ÜÒ'£ ï ^'¤º(“3ÏêóÔ‘ëºÑh´¦¦›ÎàHÌ&“I乯-Ê(GE”!žH‡Vk¢.gˆ–Ðøá±òC!ß»é¢è‹ JàKÔ#‘Ƴ¦àAù$Ñ fÆÉ Ð: ¾LÏIkÿ %JÅÅÅ0ùÎc§¡Ö<áqET,rŠ¿Ù¶MQ;„¼p¬ó+HïÕM’rÃu]Sšº®ŒºžuÿÂ|àÅŰÙu»I©.nò°ŒÅb§OŸ®6Ò�—6¡ØêéVñ%q/êÕ®­Õ4-m¦“Ï&Íÿ4ƒ[‚ŽæàäÊÙÌ(N©‡9ã¼áuöŒ\CëUUUµµµ‰D"d:gÄe!b‚ó-±£‚¿`J-èCOªqk^™ªØÌ8ypš ï”ê;ðr‡nÃZÀ¿át�ˆ†-6øªÄ�mîYB†c[š÷‡t¬`ââ< sB3eR¾ '4‘ÿ„˜¿®Š­LNS’¤})ÈáqN¥CIX‡ª¹Ó-JR6^!¼= ×Á%”·àÍžECAìÔ<ÙY¼`‚s‘áBò) û„2l^ôNS–Ì�¯âš `pQ[.Ô†ÉXÞˆDó\¶c?˜'ò‚ózi¯-fúîtºO:ð^À0 = ;?ud¶4 |‹ø|º$”€'BÆq´mE8ŒüXÉk>pÐäiTüpm|ºŠìyÙ‘M‘ðÊ0çëkšf¿lgÏΆçÁÓÁǃZ-þd\hBDDöøì@ 5ɳÇ>!þ¤¸«n|l$îK¤ú¤Åt:][[[þïJÚ±:ñ'.¡Dˆºc´ ó)æqý!îÔãOx¡>&?v  ’WÀ¥CE*Wh…Ú7˜„Íq¨âäc8š\M•301œ‡­‡&…4·šb@ðͧ‚(æ™ÓøÚÄ…ðV¿xWÄŠãMóÀ¼@,—_—Rhê `ºè03Hð>>¥ _"HäÎó*-p—}’õ\\™vD¸Ò”`¢O|ÞóÎHä€ÒÆÃÍ‚©¼ðàoáÃ%LðááýB°#øj# ‰è#Fsë‹3“Oôn ú}Ñ÷6îF ‚8ÂbüJC†Œ{ ·—k¿c;º£IÍø/C+ÓôOuìq¼Þ‚<Þ´KIi_w^… K4…£$f+І½ò„ÁYA{©ÜÔþ¢¹®ëôu2Ó2æ>Ó=íº@.œÓ4Í SΨÛn2"à i Zöu,F· ×uCËC©I)m¼š¢?O,Nè'õð²°ã9>–&wê¹) ƒhØO‡-®xä39x†f6‚Õ úØÀ8Í€®ÂkðÓ’á‘.´kjܸ•˜¼Á‡®ë™;2öÓvpwÐ8oH)32™ç2ú3ºpê¹yÈK!ˆç+ІiDUWáäk> Œ F +ÍAºá˪i×õœ��ÄIDATpZ‚ÉßDdežà…ò1é˜1ÔI°!TÊî#(ÓÚöe2OçpXQX<;â£TúÚp¡ŸŠHàÜq63ò(pÞù+<«Ïe`|p¨âQt½å\dÎ_‚G,X‘)æÁøqhÆ×-_KRÊÀ¦€Ôõ‚:ï2x2躮ÐêŠ`ˆUᓟâ´²Iúˆ·!Ažµ/‚jvf;ӑަkTÀMºÄ‹…CƒÍ¥^ ._7?7å²vc­R;¬™3MíœfÚ¦Ôê§%×…ó)£ „cn›áëг#‡ºìÂ>-t6äÜèÄ bš¦I!²3Ùò\5…\±¼ø!-áåÐÎH—† Ú¸Ñw¤åÙ.{O5BDŽ^áDªi¨ˆ—¢ÀQß`0ˆþv‘ ö&ªã8ÚõZzR:ôï!qZž!¥ÔÚkÁöÁøÿ‹g?–Mß…ëâ~�¯2F¶†^lÀ«èy•—@À?™xç`©FÔÍûãq-ѨË�­a4œàÂã°ˆ‰Ñ,÷õ*¯§Ù6|+_½¤ø¢ãWÆ ä%÷Ü»DÙBa$…-ºj(vñYŽÆÛ/ÁNÊ ï!LÉÈÄ@ž€î¥‘0N~t'ù‰ 'œ„ÀÜ…×ì;Ö­ÒŒ”¤”Â2 Áqâ+Ÿ ð"ÄzÓÕ°:ª± ,¾Ðóuþ¦gÎM{ý½Äà ·›ëy^pKÐÛí…·‡aSQ‰‰r`!„B?®Ì&ÑÌ�×(™˜·ÒÁΕL&yЕ C€rÉ›ÉRæ¯îë*4£ÒŽ"§¨iš'h4Б‚ÓëqW)8é£QáÀWŒËÜqv¼þ3”a¡›‡…@|ÎÊ–9þ„Øwõ´À†zTOÃçø˜™4Q²ƒh|r`2PÐë®ëº¦«iš¸ ôKºˆ ïO/­‚ÁæQMr®cœÄ„½ÑiìÀ¶ç’¸¤ÿÄczä¶o ¸æMN·nÝ~þóŸÃ©¯«ïc¥d<˜‹3ï{Á™KüHÑXÉŠ“[Яɷ…ñÞš¼?ÏúÄ0(zã£xA’¬On‹_ˆoàúÿÜp‚jÁ)Å>âOqè0ÇŹy>ò^\ÔëP4lÉ# …ùJí|Nâ—6oÜ1Þ·aq¶èàœ Ž¡ò'¡LD½ìþvâ{‰œwsÌBÓuÝä?&_99³r4¡Áâò!A§’2¯‹â­1|4wž#LÁL4”lábhÈ´ñø>?’¢Û.¯óµjö=ÁTþÀÚÝÃ×^–sG}Q;¼Î›=Ó¨p€€åd3ŸVô³ECÅ<nB¸/Å/ ¯s9)¥ý´^–/H´î­l½èº \sµ‰åñgÄú| ¨DÃNƒ˜x‚•x VîÊëœpæÑP®—FuïÞ]™œ&C¯^½f̘!®&5üï/ÕiA˜þßÿêvuw®Z*DÝ…oú”#¥Ü°aƒº# WcÆŒù“ãºîý÷ßÏßçcmý=¿º²ok&ÃøŠ·}“·¢9 ãŠ<–ñD¾z Íaߨã¸ÚFí*M²œ¯àç=úKLΗ~ç}}õ¿¢‘Âë•ýëýùj`ÿ›Ïo¶ã¿j¶SsX ¬eŒW©\Ž‚‚‚‚Â7er”ÉQPPPPP&GAAAAAA™er”ÉQ·@AAAAA™er”ÉQPPPPP&GAAAAA™er”ÉQPPPPPøãË› ©8:´ãg·ª³…hºæ%BuùFf‚ø÷2¹OäªvñQO¤IžÈÿfgž9sæ—˜œ@ ŸŸß$voÓ¦MÑhô¡‡jfü¹çž›7o^˸–’’’={ö<õÔS-ÆÉjIOG-œæŒ•+WvëÖmäÈ‘êép dðWï»ï¾&¹˜D"Q[[ÛTß~ÅqË-·´˜kÉÉÉ‘R¶˜ËiaOG-œæŒòòòž={ª§#„p]·ÞÐX–µmÛ¶D"ñá‡Nš4I((((((\9¸®Fóóóñ‹_(ú€‚‚‚‚Â7er”ÉQPPPPhY0¾±oŠÇã%%%#FŒBD£ÑuëÖ !ƌӹsg!ÄÞ½{KKKÛ¶mûÀÐûW¬X!¥´,«oß¾Íê–]¾|yýúõBˆ±cÇvèÐAQ\\\VV–››Ké5)åŠ+„Æ »á†„¥¥¥{÷î5 ã‘Gi†“`ýúõ—/_¾é¦›† "„8wîÜæÍ›…ãÇoݺµbÛ¶m•••]»v5j”¶íÕ«W !FŽyÝu×5Ÿ Ù°a2œyàÀC‡eggO˜0Þóþûï§ÓéÛn»­ÿþBˆŠŠŠ;v!yäÃ0šöZN:‰D @ÿÝ¿ÿáÇ[·n=~üxzå/ùK&“2dÈM7Ý$„(///**Büà? ‚І jjjúöíkYVs{:„âââ>}úäææ !víÚuüøñ:Œ;VáºîªU«„Ç¿þúë…GŽ)))1Móá‡nòk9zô¨a´º…;wî<qâDçÎÇŒ#„p'//O1bĈž={ !>ûì³O?ý4ƒ^¸fÍšd2yë­·8°É/'Noß¾V·¢ªªêoû›âÁÌÊÊB|òÉ'ÕÕÕ=zô¸ë®»h3_»v­bôèÑ]ºtBìÛ·ïóÏ?oӦ͸qã¾ú»Ù¹Ý{ŽøçýÇÏÇÎUÜñƒ¯ÞUM:õã?ž8q¢â7¿ùM*•ŠF£#GŽ,))Y·nmÛUUU§OŸ4hмyójjj¢Ñè®]»úõëצM›æ³¯Íš5Ëqœh4ºiӦѣGïÚµ+??ß¶íÓ§OŸ={vÀ€sçÎD"ÑhtÇŽ ¸páŸþô§t:][[»ÿþ¡C‡6+{³bÅŠ#GŽÄãñC‡åäätìØqöìÙ™L&nÙ²eÔ¨Q………Édòĉ±X¬_¿~¯¿þz"‘ˆF£………–e…B¡&¿Š‚‚‚7ß|sΜ9S¦L¡W|ƒ,++ËËËK¥RçÏŸ/++<xð¢E‹ª««c±ØÞ½{{ôèáyÞüùóéÉîܹóÎ;ïlÂË™1cÆ’%K¢Ñ(Ql÷ïß¿zõêT*uæÌ™ŠŠŠï|ç;óçÏ?þ|4-..¾á†lÛ~ë­·hðEEEßýîwóòò:Ç>‡{ôèÑ„—³fÍš·ß~û­·ÞúÉO~‚‹ŠŠ&Ož<räÈîÝ»ïØ±cãÆ¶mWVV^¸p¡ÿþ¿ÿýï£Ñ(-¢Aƒ={öÝwßM§Ó555lB#êyÞÔ©S/^ܶmÛÁƒ ! ’ÉäÉ“'kkko¾ùæ7Þx#‹E£Ñ­[·<¸²²òÏþs*•ºxñâ‘#G† ²téÒ“'OÆb±}ûöuéÒ¥S§NMøt–-[¶dÉ’5kÖ<þøãBˆX,ö»ßýŽv€Â»ï¾;??¿¨¨(‘H;vÌqœ>}úÌž=Û¶mÚ"FŒqàÀµk×Ú¶}æÌ™ÊÊÊ[o½Õ÷µqguqõ¦ ë÷Š®7Y/üWjÊê˯Ï_&¯^zé¥Å‹Oœ8‘þkYýpÏ=÷Äb±eË–Í;WJyàÀ'Ÿ|RJ9lØ0Çq¤”Ï<óÌîÝ»es¿gÏÏó-Z´`Á)åîÝ»Ÿyæþ†'Ÿ|òÀ[·n2eŠ”2‹ÝsÏ=²™)¥œ;wî²eËø éB~ûÛß®\¹RJ™ŸŸ?mÚ4~&L8}úts¸ŠŠŠŠ‚‚‚6~L4È5kÖÌœ9“Þùýß/^”R¾üòËüqiiéøCßß6¶mÛöÊ+¯Ìš5‹þ{îÜ¹ŠŠ )%I GJ9eÊ”­[·bá`ðX8 ,X´hQÓ^ÎÑ£G † Â_yá…&L˜àäÎ;úÓŸòG0iÒ¤Ï>ûlË–-/¾ø¢”²¶¶öÞ{ïmÂkñ<¯  `Ê”)K—.¥WháH)/]ºTVVÆ?qâÄãÇcáœ={vܸq|áüú׿^·n]Ó>C‡­Y³æ¾ûî£ÿb¸ òý÷ß§9‰ ¼÷Þ{kkk—/_>gÎ)ågŸ}6iÒ¤Æ_qª63eõåG»±Mç^º"`ƒÙm4=p•¬èùóçO:uûí··ŒXd*•Z´hÑСC«««[ÀåLŸ>ý—¿üåСC«ªªÕ¼æÐ«W¯Q£FQ àÎ;ï4hþÛ©S§^½zUVVNŸ>}É’%×ÜåôíÛwÔ¨Qº^Ÿ9.++ËÎÎîÖ­Û5w-š¦5ª_¿~üŪªª|ð¹çž£@ôµ…P¸Œ››;qâÄ¡C‡:ô7Þ¸27M³Û´ëv£nuÕé•••øÃ¦M›Ö®]»–±œ;wŽÎ4¯¾ú*/qºF1sæÌY³fíÞ½»{÷Rh†Ø·oßœ9s/^‡¯õkÉÏÏߺu뫯¾ÚbžÎš5kæÏŸÿãÿøµ×^»Ö¯¥¦¦fÕªU»wïÞ½{÷‹/¾xÅ?ÿªçH‹‹‹7mÚ‰D"‘HIIÉæÍ›)Ãví¢gÏž“'OV› Â7†’’’µk×¾ôÒK-ã7}úôáÇ?ÿüó;vìˆD"Ë—/¿Ö¯èÙgŸíÞ½ûÑ£GÕ\mz“s÷ÝwwìØQQ]]]^^Nì…¿G ‡ÃÄ}jX¸pa$B”——_ë¨Âÿ]o²¦nS7È9 —_Õ$UeeåóÏ?O?—––Z–eYÖöíÛ¥”™LföìÙ–eMœ81•JI)mÛ¾ãŽ;,Ëzï½÷\×mVùv"ÌX–U\\,¥tç•W^±,ë±ÇK§ÓRÊx<NoÈËËs]×uÝwÞyDz¬»îºË¶íæFH¥R'N´,‹ˆjRÊíÛ·ÓøKKKé_zé%˲ž}öYºÀªª*zÃÆ=Ïk>×òè£âgß 3™Ì¼yó,Ë7næØ˜1c,Ëzûí·]×õ<ï¯ý+ýÉ¥K—šüZ6nܸpáBúù£>ºí¶Ûhl”ˆ¶mû®»î²,ëwÞ¡9–——GoˆÇãRÊt:ýØcY–õÊ+¯§Y=ÂÌ™3<HslÆŒ–e=ñÄ4Ç"‘]ÎêÕ«=Ïs]wéÒ¥–eÝsÏ=Ía-_¾üƒ> ŸÇ™6mšeYO=õ þÂ… 4øuëÖÑà.\hYÖØ±ciî¥R©ûï¿ß²¬?þñ´èšµµµO?ý4ø›7o¦ñWVVÒ\úÙÏ~fYÖ /¼@s騱cô†ÂÂBZ\¯¿þºeY?ü0] §#rê9ùOÇ;ôê¯u½Ézü»…]Êß{qò• VPPPP¸‚¨ŠŠ¹;Åå3åy¿¯Ô¾!(“£     LŽ‚‚‚‚BËB=c-™sÃÞã5ƒz䨛¢    pEpðTì¢Ìý“é8샢OûäöV÷HAAAAáŠàƒ¢ÊT‡öâ‹^Ô¬.GÓY=欯øÚÈNTæÄ«[©   ð­…ìñÝËZnÚŽ}õÛ’Y=_Ø!„VT´ë™_:ö¹?âs¾úï=Ïy3îæ€ºã ßZäüí¤þµ&CM‘¸|~ã<»ì—.]:÷ï™{¦´¸M—ÞÙm;ѯ¿Ž¯=w6Þ£“ºã ßZ8N–¡¯5do.”¼µo÷.]ºh¤8ý_›ðxõ¨§_ÿÚ?v3é^EÿœKêŽ+(((|kq*ë;Ç“í3éä×¾sË¢©ƒút{õåg  I)…gΜÿèþžoÒÝTÀMª;®   ðíE¨mF3¤÷õjúëV¾Óµk—Þ½{ !þ?éIëÞîzÝ����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/catalogs/2masscat.png�������������������������������������������������������������0000644�0001750�0001750�00000446053�11332127303�016655� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��&��Ê���‰* è���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ5zëÖ|�� �IDATxÚìÝw$×}'øgó¥+ï«Ú›ñƒ˜@IˆE*tÒ‘º¥¸:‰¡?$ O!1(®„B« ÆéB!¥»Ø ]PîtZR$@ <0~zzÚ{請ªËûª¬t÷GVvW¥]Ýõ7&&ª²óÕ'_v×ûÅËÌÊ‚¦i�šÍf2™Ã0M�‚à0‡9Ìaó_/†aB|Ï£±®ëã÷ÚÊ*ð½pKKKáp˜ã8���$“Ép8\¯×­5~äËýõK#«Yýg?úØáïû0‡9Ìaþ+æ;¯\?Ó!þÒ³g­bð€c¸iš_ýêWÿäOþÄ0Œöå?²áÛo¿mÆG>ò‘çŽ=šL&Ãá0i6› ø�AÕjõí¹µ¥þ›þU! ÆMM³cŒTM�`„„ª®�B�M7��#Óºa��(Ɔaè¦ �àÖtkâ8JTU7 �`”4UÍ�ÀQ¢¨ÚO�5 ݸ %DÕÞ …�RrO"ˆþuP‚Qó.#J Öÿ%Q`í_…¡AÍV¯¢š®[ïƒJISýÿ�ºÿGµ‡ZL!�þ¥Ð;Þ³Bmïíó“@„&Êú�²Ùl©T‚{†d¬­­=`„„°^¯3Æòù|¡PxÀ†sssc§Ó™ÉdH2™ ‡Ã¾¡– !Hm¯OÕ»õBèwËgu¿14Œ<=1ÿÕÑEŒPo,àvŠc3k££½�àÌrœ|úHg±\[ÙJq_8Ù·±“ÙNå9Jž<wdba3W¬0Ž<óè‰K µ†Â3úñ§Î|ÿÚ¨aš‘ÿУÇpu BèsËçŽu¿ÞBÝ=±àÕÑŒPOÌïqJ-´'!œ¶ÐÁÎbµ¾²¹K ¾pªo3‘ÝÞÍq”<ynprq+[¨0Ž|øÑW&ªu…gôãOžùþõ1Ã0d‘æ±ß¿: !ô¹¤s'z,4âw÷u¯Œ´P¯K›^%é‰ §—â„àÓƒ•jcÙBOön%sñÝGÉ N-ų…2ãȇÙGêÉÓ/^× CÙ3´P¯K:¢÷µ¡) íï ^YÀuGý>w 쌧—¶,´ZS–6’”àó'{㻹x²…N/Ç3ù2ãȇ9~mj©RkðŒþÔ§_¼1®ë†$°>~ò uJNõ¾:4… \]áË·ç1BÝQŸßã›ZÁéS‚§·Á§:ªu=ѳ*l%³%ÏÌ®l§ï@9úì“§_¾1¡éº$°^<õÂÕ¡Ç)>rª¯…ú]ƒÝáK·çBÝ_ÐÛB»Â%Ó‹›„àS±Z£¹¸ž¤?|¢'‘.l&ltu'+1Ž|ðÂñSKåjƒçè³OœúáÍIUÓEž{ö‰ÓÏ[¨C|ôLÿ+C“Âßu¤'rix!Ôñ†|®±I 1ŽN/l‚OöÇꊺ¸ž ?|¼'‘i¡Ÿ˜_ÝIµÐc7¦VÊÕ:ÏÑ=qê•›Sª¦‰<÷SOžùÞÕÛB·C|ìLÿ+C“°Ïy´7úŽ…†½a¿{lrc4Ðâ-㓱†¢.¬'(ÁçŽwïfK;Ž’ÇÏôϯ'SÙ"ãÈÓç M¯”*už£½x굡©¦ª Œ~ü©³6*<~vð‡CÂÏy¼/úö­9„PgØ ¸Ç&–1F!ç¦ç7Æ'ú£MU›_KP‚ÏëÞ͵ÐÇÎô/®'wmôÖôj±Rã9úÑ‹'_š¶ÐO|àìw¯Þºeቇ_š€½Îý±·oÍ"„:ÞhÀc¡ýA‰gm¨>¿¶C ~èXw:_^ßNs”<vºi3™Ì%8txf­X®ñýÈÅ“oÜšQšê>  Ë!<ynuœèxkh!ÔòÄBÞ±ñ%ŒQGPùé¹u‚ññ¾¨¦ëé-pü„5¦½×’óà­ì‘¿íƒ[…BÁëõ†B¡d2IëõúƒÏolš��ýÛ­7^—xz°ãµ³áÏÙö^]Ƙt†=NY¸5³A0íïò›&˜^Ù¡„ï Jµåx†£ÜÙ£±õl<Uä9îÑ“Ýã‹[ÙbM`쩇úÞYª6T‘gÏ\8òÂ;º "ÿó/¼3!öºÄ3ƒ¯î¡ßåÑ% u9D íëô›�L-ïPBõ… •úòVš£ÜÙ#±l<U`÷ÈÉî‰ÅíL¡&0öäپˣK•º*òìÃŽ|ÿÒ¤f�Y>x~ðù·Ç!ħxöhÇ«×gÂAŸ³'ê¿4²„é{Üqhz`Ò×€N.íPB÷†K•Æ’n&ó[»ÆqœèžZÞNªcOží½2¶\¶Ðóƒ/^žR ü/±Qá¡£]¯\ŸA½Žž˜ÿêö8[ho‡!4±´M =Ö*UK›iŽrg£[6záD×Ôòv:_å{âLïÕñ•r­)2ö¡ ƒ/^™Ru ü‡9ò½·Ç!Än‡pîx×¯Í „^G_,ðÎíEŒH,äöºä›Sk“¾?Æh|q›z¬'T©)‹›) § ›É<㸠ǻfV)½6¾Rª5Æ>taðå«ÓMÝ”xþÃýÞ[cú°…Bð9ú:ƒoß^Ĉt„Ü>·|cjÍê)!x|1N =ÚªÔ›‹)ŽÒÓƒ±íTÑBÏïšYM¤rž±‹gz¯O®”ªM±ž|ùÚLS3EžÿÈ£G¿ûÖ€ØãΟì~ùê4‚Øïu tß^°zð8nL®Lzc>JÈØ‚…kæ‚…Dw2Å„…vέ&vsžcÏôܘ\+V±žxåúŒ¢"Ïä±£ÿüæ(€Ø#óœì±Ð€Wì½e¡AWÐë¼>¹J0é‰ùm¡GºƒuE_ßå(=5MfJë‰㸇uίï&³ežcŸé¹9µV¬(cO?<ðêYE5Džÿ¨…ì–ùGNö¼te BðÈGºÃoÞZÀˆDƒ®Ïy}b•`Òõ1ŽŽÎoYh£©µÐþh2W^ßi¡ -”{ütïÐôZ¡Ò°Ð×nÎ5TÃÚ½ßyc�ì–øÇN÷¼h£ÇzÃoÞšGˆD®°Ïumb•`Òõ Œ™ß¢„v•¦6·¾ËQz²?šÊ•×v²ŒrçŽw.nî&2ežã;Ý;<³‘/7Æ>ðpÿ7çêM]äù<zäŸß3rÉüã§û^¼<!ö{¤c½‘7†æ"‘€3p__Á˜tG½ÏÌmRB»MMŸ[Kš�¾×zsÏ’c˜ WªC÷!ñ8„w©7åZ³¡n™±–ä+Šª—HÉ^É�KKKŒ1ÒÞÞ0Án¾ÊòHí¯ØPõ\¹!óœÏ%î¹{%!(r„ç0BPÕŒr]µ¦·í#<%È0Z‡,îøÏa‡@ Õ¦5m|È<•xÒ¾¤Pm*êhÎ쑹|¥ÙÔtžÒSý‘×n-!„ƒ^¹3ì¹<±Ž1‰.Y¸5§„ôF½� É•]ŽÒ#]þb­¹Ï1Ž;ÙÜJ•â©’À¸‡£Ók©L¡.2öȉŽëS›åº*ñì‰3Ý?¼¹¨êÀ!òOžíùþ•9±ÇÉŸêî¡]aïåñuŒI,àt9Ä[³qJHOăvú˵ær<k¡ñt)ž* ÷БÈìZ*]¨‰Œ]8Ñqcz³\k¡¯-6uSø§Îö¾pe@ìsðg£¯-!„¹;â½4¾f¡§84'6:±œäìòWêÍ¥x–QîD_p;SÚÚ-òº‘Jç[èÍ™x©Ö”xvñt÷«·–›š) üê}áò,€ØëàÏF_ZD<ROÔwil c 8=Nih6N0éŽzÁ6ê«6Ô¥­,£Ü‰ÞàN¶b¡g#ó™T¾&2öÈñØÐl¼Tm¡¯ßZV4Sø§Ïõ>o£¾rsAìwK½1ß;ck‘hÀásË7g¶&Ý!d|)É:Ðé«)ÚâV†Qz¢7˜ÈV6÷ЭL*_»p<vk.^l¡]¯/+ªa£3�`¯ÌŸ;k¡©/ægt#iC»"Žñ¥%t ÓWoj‹›FéñÞàn®²‘,ðwf0¼¸•ÙÍUÆ.‹ ÏÅ‹•¦Ä³‹§ºÞ¼½Ü°Ð‡z¾wy�ì‘ÙÃG;~xcBìóHþ·m4à‘oL[¨›ãèØR‚Úßák4õ í îæ«-t ¼¸•³ÐóÇb·v ¥…ެ6š-ôù˳&@™?¼ãe u‹·FV1"a¿#èu\ŸÞ$˜t…Ý<GG-Ô«¨ÆÂfšQz¬'˜.ÔÖžãN„—·sÉlE`Üùc±}üT×Û£«õ¦. ülÔ-ól4àtßYÁˆ„ýrÈç¼>µI0é »yž]Ü¡„öux›š1¿a¡t±¶žÈ[èÊv.‘­Œ{øhltq'_VDž=~²óí±Õº¢Ëÿ³=ß¿:k�ä–ùGNv¾t}Bìw‹GºƒoÞ^Aˆ„ýrØï¼f£"Ï,ìPBûb^U7æ7Ò¥G»ÙbmÍBûë;¹D¦…Ž/íäÊ ‘gì¼4¶^StYàŸ:Ûýý«ó† ]2ÿèÉ®—®ÏCˆý.ñØê“#~×µÉ ‚IgÈ% lÕ sn=ÍQÊQò^§w—ë™ÿð7×ï9Ÿ8ûýÏ<êsŠ÷¬:…jó›ß¿>›øÍO?ôñ =£™bý?|ëêòNá?}჋XUÇ0 ëR…ým5L0¹–ùÊ·®Ç|òŸþêSQŸÜª7MýåáÕ¿|aì©SÿóÿhÐ-Ù³¤!ŒzÅŠô‡dh»Eå{7×ã¡ý !(Áõû¶3•x¶j佌N÷ú?ûdÏ7ž]I«“)9ODž>æuœÀ³R¥Z«7¾õÆÂbZG˜¾K«¾¨û‹Ÿ>ùõZHªzS}d!p‹]!ו©8Á$ê—ݲpk!I é 9‚“kiFi_Ô]i¨ËÛžãŽvy¹êVº,2îd¯!žKêÏ/$K5Õ!°GŽ…ßÛP4Ó)òOFpc@ìs°Ó½×GÖÂ~·Ør]žÚ˜D|’Ç)ÜšOPB:CNŒñÄjš£´/ê®*êÒvçèÑNo2_ÝL•Æìõ/Æó{èÈb²XSe=r4üÖø¦¢î¡K�`Ÿƒî¾v»…ö„]—'÷Ñ¡ù%¤+è$duÕmi;ÏsôH§w7_k¡=þ¥íün¾.ñìì@`d1Y¬6e]8~gb³¡N‘¿x"úý›Ë�`ŸÌÎö_½½† ö¹…žˆçÒäF$ì“|6ÚtR‚ÇWÒ¥½W½©/Æ[hªPÛH•,ty§°›¯I<;Û]Þ-ÜüàÆ² °×B‡[h_Ôsib #öK>·tsn‡bÒrp¯¤,´¡Úh‡7U¬oìZ¨oe§Ì×$ž;Ó[N*MY`ç„/OnÕ›†Sä?yñƲ×Á ½2¼º‡¾3±iõ4`£!ãÈØJŠ#´7êRT}!žç)ìôfŠõõÝ’À¸ݾÕD1™«I<w¶?8¾’Ê·ÐÐå©x =yihÅ�Ð#³sƒ¡W†W!ÄA·0ó¼=¾‰ ùÄ€[º1»C0é:xŽŽ-·PU7æ·rŒÒÁNO¦T_ß- w¢Ç·–,&rU‘qgûƒ«©|Y‘öð‘Е©xMÑ"ÿØñÈËC«º =2ÿð‘ðo­Bˆƒ.a c y¥ë{(OG—S¡=—ª›:ÐéÉ•kÉ¢ÀqÇ{|ë»ÅD¶*2îL`r5++2Ï>º:¯)ºC`ˆþphU7¡[æÏm¡?Øé{k|#ôJ!¯ãúÌ6Á$tˆ<]Úåí‰8uÜÛÌ1J:<¹²²‡nì–vltj½…ž?º6³]mè=v<úÊðªf@·Ä_8~yhÅBtúÞÛÀ‡¼RÄç¸f¡‡Äs#{¨ÙB;<…ª²š( w¬Û»‘j¡§ûÓë™l©ÕÓ³Û•†æØ£Ç#¯¯ipIü#Ç"-ÔÉíò½9ÖêiÄßB£YÙíÅ]ŽÐî°Ó0ÁìFÖê©¡Tßÿ,'S¬ß³Þ��®ÏlÿŸ/M~ùß]¼ç,çïÞ˜»>›��üå÷Ç‚gû‚ÿË^Þ)��¾ü×—þá?ÝtB+•ŠÓél•«e©ª|å[×�ÛÙÊýÍõ?þ÷Otõ¦þÊðÚ_¾0�¸:÷:…/ýâÅöYŽ“§9ë÷s/¾u}za- $âYWxÐíu›�Ô-_iv¿ø¾›3›7´í’pñ#Ã0ËuµÒÐL�µf}wñ–ʺ¢]‡ Ã,×µR]ey%!0LÓ*§5E�ÜXÌÞûÐéè#§|ûÅ×'6wR¹ðñ‹¡`'F°ÑÔs•¦¦›n‰: !¨+z¶¬�š†‘œ»^C¢7Š ¸øÎ ãÊL’ ö n™ /¥)! c<¹žg”ö„äzS_N”ŽD©Bc+Sw¬Ó½’(§Š ™çNõxÇײŚêØÙ>ß•™Ý†jºDva0ðòí-`ŸÌêö¾>¾ ¸øî ãÊL#ñ ^‡pk1M éðKãÉõ£´7$7T}i§Äst êL—”Í´…ºV“åÝBCæ¹SÝÞ‰µl¡ª:öPŸïêìn½i¸Dv~0ðÊí-`Ÿƒžêö½>Gû]|wÐqÙB=‚×)ÜZLSL:ü¥xb-gõ´¡{h¦¤l¦+"ãŽu¸Öv[èÉnÏäZ¾PU{¨Ï{­Ý2Lèsp§{}¯µPÖr]žN`„Ã^Ñï†l”Y(!=!GS3wŠ<Gû#ÎlIÙ°ÑõÝr²P·Ð©|¾¢:v¶Ï{}n·f¡þWG·uzeîL¯ïµ±8´Ð°ëR üNah!E1‰$FéøZŽ#¤'èhêæâ¶V”TEdôh‡{=UMæëÏìöLoäó•¦CàÎöúnÌïÖÃ%²‡ü¯µPv¶×ÿêhBìs±¾È>p 7-Ô/ _Ír„t‡šn.lyJû£Î|EY·ÑÍt5‘¯K<w¢Ë3³‘ÏÙèÍùtUÑ-ôõñmÍ€™=ÔßB.Öq½3•À‡<BÐ-í£ŒŽµPù ª¶Ð˜{3SMäêÏìòÌlåså¦CàÎôú†Zèù~ÿãÛš<®ßÿÊÈ„ØïdÑ}4ä–ņ&1¿(2:¶’åé ɆiÎÇ‹<¥ýG±ª®í–ŽépÅ3Õ\«§s[Ŭ…öøn-¦+ Ý)²‡ûýoŽo«pKìáþÀ:s¿=¹ƒz„°Wº1¿k¡OG-4(&œß*ð”öEÅÚhMb܉.÷zútr[Õ[bç?´Ñ#1÷Û“;á Gˆx¥ës»“¨O”:²’±PÓ„³6Zª©«»e£ƒ1×N®¾m¡ ñb¦¤8ît÷öRº\×";×ï{2ÑÔ[b?¼½!ö9¹#ž·,Ô-DÛP‡ÈF–3!A@8½™g”ö…庺œ(=u"üþ¬½ë©pw[ëqÐ#:E®Tk�þ·çÇÚõ„\Œâ;ZíÏr(ÁQ·U6S¥çþþÆïýÂ#ó[¹o¾0j­ã–ù˜ß±.Ç„†‰"^9ê•nŽÜzýêm…' ç¿ÐÓDF2uü¿³ôá“!‘‘ó¾>ýϯ-}ö‰#œQ•Dq5«ÿÝ›óÖ¼#Ôvÿâ‡úœTW5c)­¾>¶=ó|ü\°R©bL$‘ÿΕåÑõ:¦,[VÕ†³†=ª¶S…„ê 8õé§ŽŸètbS­Üwo¬g+úÏ]ìêt 7k&ÿ7o,�Ó¾H@�pÀÉuúÅksŒqØÃ{$îöržóò£©"£¤Ë/*š±œ¨ í ‰Ùrs+S—ŒÈéênAqðܱ˜<³Y,T5—Èèr-eëŠá‘¸3=î7'wuúôD§ëÍÉ]-Tº:—Á‡ÝÌ+³á圅rOî£ær¢"p´/(æÊêf¦&1:‘7Óu =“g¶J-´Óyk)WS ·Äéq½5™Ò èkCýN®;І:ØðRŽóñÅ“ë*¨š¹”¨í Š¹Šº™®IŒ„å­L=i£sñr¾¢:îd§óÖRÞBOw»ÞžJi:ôÉÜÉN×6”®Ì¦-Ôï`·–r“¨—gO¬%h¡ªnDež9öÐÎÛËùjÃF§Óš¼2;ÕÝB®ÇFCnæwò{(OñÄzÁê©f˜‹;P‘Ñþ°ÏÖ“ù†ÌÓ£QÇ|¼œÛCWòÕ†á¹ÓÝ®KÓiU^™îv½>‘„´7$_ži¡'?´ØBFÆ× ŒN¿ æâN…çhOP,ÖÔõT ÝÎÖ6º°SΕU§ÀèpŒ¬ä+ Ý-r§º]—fÒª¼2;Óíz}¼…öí¡.tñC‹YŠIÄËDFÆ× !~Á0ÀÂN™çHOP*µ£¹z$êXÜ)g˪SàŽw8F÷Ð.×¥Ù´ª¯ÄÎô¸^OBˆýÚ–/ͤ1ÂA ¹ù›‹Y‚IÔÃ$FÆlÔ4Ál¼ÌSÒËumÍFùÆN®….í”³å¦…Ž­åËuÝ-r§»\WfÓM x%v¶ ˆ8.M§ÂA »…› 6ÊÓ±ÕGH‡O��În•xJºƒb¥¡¯íVmTÙC—“ÕL©…ޝ,ôT—ëÊ\¦©ÄÎö¸^Ûe:q¼3B‡\,ìn,d &st´ ±Ð€Xmè«»U‘£ýai· lçê2O£²…:îXÌ1±V,Õu—Èêr]›Ë(ª¹pÐ#6tr¯…∇wtt%o¡™ÍOIO@¬*úêîþ¡£÷Wr�Gñ@Ľÿbv±)V•»+ÓÞÓÏ=s�ø½ëË¥ªÒ^oú£î?ý‡Â^ù¾%Ç%±ÿø+O}õo¯/lå��kÉâÿôÍ7öÚ{dþ³>ñù¾ã\!cT­Ö°#,y y‘NÅk×nÞ:ÞåûÔGŸôê‰ço€“Ýî—Þ¸ú›C˜°w¾­Ù›Ï<~æÃO\øö÷×u#�xúÓ]¦ãoÐ þÜÇž(eQw—³˜KÿÓ‹—?wâÔ`Gq{¾V R �€yf2„BDD÷Ùƒ‹¼øú¥™¥ßùåŸ}$ šãBŸ÷û|2ûO¿÷ËÅŒ…|Ý.9cÜá®/1ÂaõHtd­L1Žz8Žà©­*£¤ÓÇTÝ\Þ­ éð…ª¾™U$FzCB<§ìUOÂÂB¢ž¯ê.‘‰ˆ£kåšbz$z,&]™/hôËôXLz{&!:I‡_¸¾XÀ‡ÝÔ+s·WKÊžÚª0J:|Ü´¦of#½Aa'§$‹MOûÃÂb¢ž¯j:¶^®*†G¢ÇcÒÕù¢j�ŸÌoC»üµ…F8ä¦>GJñÔf…QÒáå4,%kGºü|±®ofl´ $ -t)YÏU4—@Dű}ôÚBQÕOæŽwHoÝ^-QŒ#Nàðäf…Òáåô}”•êúF¦!1Ò%QhZ»·Ø(W†G¢Ç¢ÒµÅz¢Czk:!8IO@¸j¡.êwpÃ+w¢1/g˜`1q'Ú’…溲[ÏZhÄFEz,&]_,6uà“¹“Ò›ê =Aáê| 8Ù-žØ¨0Bb>Îpa§&PÒígE_O[(Ÿ,¨Ú:€NnVË6zc±ØÔZ=}s: 9poP¼2_@]4àb·VJ㈇“™Ø¨p„tø8�àÜN§¤« ð»Eu'ßB×RõLYs t0"Nmí£7—‹Š|2=Ñ!¿9“�‡¸¯ ¹ØÐ²òdÜB½�pn»…Vc-Ýé ð©’º“oÊ<íñêè`DœÞª–ê†[¤GmÔ+Ñò[3yà ÷‡ÄËsy„pÈECn6´\$Gܜ̓ñõ2GHÌË!g·«Z³PŽôøtIÝÎ+2OúBÂZºž)«m¨îéѨtk¹ØPÍ6¸?,]žË#ˆƒNnCÛCQ íô³ºj®¦ê"Gz‚|º¬nçZèFFI—T§@ÃÂìvµX×Ý"=•n-—öзgò@A K—l4âáo. Æa7çl¡8æeÁ™ø¨@ÑOäò[üÆo>s÷õi¯¬,&ï7Ë~þ£'6Óå·Ç7ÛKΗÿÝ{S”{—¡×Á?÷ù'þønÌndÛ{üg>tüß?{º­14�ÐÊUõRMíŽEºS0QB.ö±s!tÊ-pXàyÜ,+¼®†n@g×¹Gýù§·û¤× €‰•œÚ¨·®A¸z­¶´ºîí8 !aëµb±¸º“;uN�˜�˜�êöerVm74ä9B0\_]NÖå¦ADÍ ÆâÜ´ê=¥ê@æÌjv€‡¬YNM×W*á° »%r{£ÆaqŽ ©í:OpÌCTÃ\N5Ewzi±®oæTÃÝ>.QP“%ÍÅ“Þ�]N+¹ªîH_€›Œ×+Šé“È@ˆÝ\©6u”É`˜{¾ !Š8p‡—»¾\!“+¢�� �IDAT‡ ˜#hÒBÝD3ÀrJ¹ZR“EÍÅ“ž�]¹'d7W«MdrÄFÃÜáå®-W0Â!öJdx½…2Š&ã-T7ÁÒ®"r¸ÃKË }#§Ê wù¸dIMX¨Ÿ®¦•¬…¹éíz¹aúD2dC«UE™ †Ù;óe�¢Nì•÷QžCñ:OpÔc£wxiY16²-t·¤&ŠšÓB3J¶r'Úd·ÖªŠ2 ±wZh—»j£>^¯QŒÃn,´¡&�sIE¤¸ÃC+бÞBiª¤î5'Oºýt-£d*ºG ½Anf§^²Ð^¯6öÑŠi¡~îêR#tbŸƒÜZ«RŒÃ.,04¾Ug{h¢aõ´…r¸ÓGSem§ÐB׳J¦¢»Ò°PÃFk $2b—*&€!wû¹+K qȉ6qaÑFc�˜µÑZÓX˨2‡;½4]Ѷmt#«¤mt.Ñ(Ö ¯HúCìöz­®‚€DBìòBE7aØqu’!•özê&�‚ÙDC°Pµ…vyiÆF{üt#§¦Ëw¡A6²^««À/‘Á0»¼ÔB{ÜåÅ ‚(äÄA'Zmí^‰Gc6 ˜9ˆJîòÑLEß.¨NFº}tóÞ(7²¹^Yªè& µÐ2‚(èÄ!½¹Z¥‡]XÐØfÍB3; âi¨æj¦)q¸ÓG³U=žWŒtûèVNM•5 ]H*ݬÕTÓ/‘»ºTÑ,4È]:ˆZ£“CÀ£û(´Ð˜‡44s5ÝBÅ;/XM Ue¤·—?4b”Ü»ä€ýKÕÚë=Þƒw¹bmc·”/7î87·‘é ¹Ež¾[ÉÜâ}î‰?ýÇ›SkéýzóÁã¿üì™;6Âýãye|£p±§óãÌ•ªaQ`J£î“Ðk·f „¯ BPo4J5u°¿ûQM½÷¼yýôÑÞO?óÀÐU�@CÕç7s±Ó¡Ï|ò™Pï`2SYTÑCáŸ}ö©ÁÞ¨iÖL�ô¶’c�`ÚÊ6²x¦úä#!~ŽqÓ‹«»óô‘îO~ä¦w@ÑŒÑéÝ÷¬é�BNèÐÈV“Ã(ì‚S •'(êFº–2šDQÌÊŠ¹‘× uxðnEO” :½x-«ek¦W@]>2›TË ð‹¨ÇGno*ŠC2ìñÓ++  ˆ "nr}MÁ…Ð#Ú¨2‚,4âBº –ÒšDQ̵ÆÜm¨¯ç´lÕô ¨ËKæ’jÉB½ddKih0(Á^ß>³PØBoï¡Mî@EŠb.TUÌõ¼îàP‡§+úŽnäµÌº«–À/¢nßôêŠbqD%t{³I1 ;!߆š�,¤4‘¢¨û]P=S5=êò’ù]µh£cq¥n£×VÃDaèðk«-Ô+¡a(šhCçvmT5×sºÌ¡7ÎTŒí’áb¨Óƒ·òzºjzÔé% w * J°ÇG¯­)º #ØŽúd4¼Ù¤…PàÐÄv mhM5×rºÌ¡˜g«ÆvñN´ËKRj±|"êö‘ñ¸RSAPB=~z}MÑLqÀN/¹ºª`ˆ‚Nè—ñ-ßV™ÎÚh½­ÛEÃÉP§Ç zªÒBÓj¡nÚhs½±¦h& ˰ËK®®*¢ øe|kã(DûhC5Wm4W3âEÃÉPG 5<<êò’¥6tb§YSA@B½~zsMQ –a—\YQD!ðËdh£I 9 l¡Eœ!0›ÔŠ¢.ÔÐÌÕlëwÚŽn[h§‡,§Õ¼…zÉäŽZm‚€„z|ôæz íiCƒN2´Ñ$…œPfh,®2ŒÂNˆ˜ÙCu°šÕdÅܸP7¶ ­Ý»SÔw+†»îD‡6Õ€¡64؆†PæÑX¼i¡™¤*u¡¦V²šÄ¡˜êÆV^k×w ßx~ôŽiƒ•¯|îÉŸz¤Ÿ£èž•ÃzvW½�Àƒ§r´]Kÿ÷LŒ¯¤î°þ×oß~òñA‘¨:èn8앾ü?<þÐ@h¿ÞüÔ™»7Â:°V×À;s¹Œl×kµ�ʶo ¿=² EÉ9:·¶“Ê–jê[3²ãaþêðÄ;[Ÿ=Ò4ȵÑù\±œ*6n/î&3…+³;Wr¡€·²»üÝ×o\\^«Ä ZÀ-Q­ÒTU¥©Z¨õ/žSFæ·²…’ÐÒný¥Ñm¹½¸òæÕ[¯]›^«¼0wø"#óÝW¯¾54UAžs‰|±d! ËÀÅÃу`q@Ãé]ƒ#0ꄺ2¦@aÔ +M°–7%Æœ0]5·KÀÉ`‡ nÌt ºØáB‹i£¨@Ÿ:Üh|Ǩk( º¹¡k& ;@ĉnnêˆ \Ù6‚dNÙ¨öѪÚB£N˜©µÐ˜nÍtºys¡ÅŒQ°Ñ‰„QÓP@ntsK×L’Aĉnlê°¸8²m`ÃÈ(œJ4XȘ¼®Z¨ fkf¼ MÙèRÆ(4Zèdrºê[hÄ…“IƒÃ-t>ÝBkw¡cN/š©*pó°Ã…–²F¾½"èp¡©¤QU÷QÕD!Ä\èú† ²ÐÛ6*Ü­«`5×úfkæ–…ºàvÉܵÑe îDoméªq'êáí¸… ¥F0·‡j`%gŠŒ9a¾nnïDc.´r­¨( 7ÞÒ›w¡>Û¨HáD FB0—6y#NذÑèAt§d&+ÀÅØ­d\½…Î$Š ý"èp£áx íp£kû(ŽÁ°ˆ\ XhÊä Œ8 ¢e-ÔÍMMì¡.´ÚŽî•&ô‹ ÓnÇuÅ@!tºÑµu@–_FÃqÝB%Ç-Ô ‚³)“u@EËYS¤0ê„…†¹Y²…–÷ѵ¼‘­C…¦Œ²…ºÐȶ®è÷@oméÁˆÈm(nC›mh±an€Ì`Ì “3Q.v´£n4k£6”Z¨ PXÁ;P{t"ÎX¨6 °”5E cNXRÀFÜñ¹œÿçù{Ö�Àü‡k•Fóž•Ã:wsw½±zßYÎó×—G—w­…§z<Óå–Y«êü—¡L±þ#f9V•ë8ÿà3ý_¯LöG=w×+{ŸË)*àÊJýõ[Ͷ©«Dô,Vv•|ܨ—'ê CŒJ/Mæ«ñIµ˜„„mÖäÚÖ0 Äd½!Êôær½.H*ÿ½±|-1¯U²p|ø”.E6RÕf~‹§(W(î¤r@ôî}þôêRéõäB³HĨ¬™èö–zulMÉnšB¥.1päʆùÚФ’›†Î…No«¾¯??W© Ž  !r2c,‰(2#’A1œI#›ÙÐ ´R@1"²YUÑf 9¨‘Íl %ªÈÍôˆÃÜ.¡Lùx="›Ë9Tj€ Ed0“‚u †E-"ƒ‘¨™0&iA m#͈l8´Ð°lpNÛ¨aÀå‰>ˆæöPÙÜ)£Lyy=â0W󨨴ÐÙ¬í¡ ¨0*iaì¡.¾…Fdƒa8B<6#’a¸E"1"²YWцæëh§‚Üœ¾7ª‡¢£ ¨¶£À ˆ›‡£‰Êc8B ›ùG .NÈf¢ŒÒ6º–G="ƒÙ4¬i0tz3Ž0#²~:•B ›aÙ�mhCCëE$S#,›ùFZAéòòzDn¡~A8À\VÕ:–€MF%-Ò†zx8’@šÙài È�pÞB¥}4"›…Ú¶Ñd¥jÈËô°l®·¡ó6–Áx:G�€ˆ¬í¡aÙ(œ´Qà| ĈȦ҆ÛÐÝ JÕ‡éÙÜ( ü]hÄÑB#í¨¤yÛz*R8¹‹2#²` ËfSGk{¨‚¶ËÈÅéá;Ð"Ê7 Ÿ×#2XÈÀŠN$¡¢·Ð›6êáí(g£svO÷Q‡YRP¼Œœœ‘ÍTíÞ Zèn Ë`(ŽL�bQ‰Â‰]Ä!3,øž¨|­î£›E”³ÑÅ ,«0(h˜´ÑˆÜÚF&�1Yó‰pxahF$CâZhD60‚³$`#"›ªV H¢FX6Ë Ú*#'gÔ©Ù>ŒŸê ̬gÓÅÚÝ%çgºîw`Mdôtoà­ñ »¼€½:“-ÕOöî˜åì=>Öå]ÚM䪧û¿ûß=r´Ó÷­W§¾}i®XU.žìîG”œ½*×r=÷?>ý.'ŸL� Ó¾û�•øð >|bÿ7®Ž÷:@è</t¶ž:Ž}ôÀ½Î�pxº¬Çb÷£ûË1 ùDȼK‰›“‹É*½ž}�:ÎBÇ�† �@œó¶£,|’…OÚç~�v„]'�ÐÐÁx SdFD• 8›¡<6¢¦hµHD¢‡$½ª¢­2qP=,éùNT‰›ÓB¢‘¨Lûx5(êëE®¨ € Ec>ËÕ4›јH1Õ€1Iñ‹æp‚GÐŒŠªÌñg¡†3ʰ5À+E*=,êum–‰ƒê!q ŠF¢J2uìejHÔ׋´¨àwA¢yËFßåÈÝ(€+¹û¢.N ŠFÒFƒ{(¯E}1ÇUÕ:™bMNð�˜QYur`¬ ÎP†È>j„E½®¡Í‘©õBïT‰‹ÓB¢±[%é:ö2-(èEZPp€Ww iÖÔaTjDc8Á�"²Ò޲6�¸`£ m”ˆLõ°¨¼S¹Zj¡A¡…†„¨_4†“<0ADV\Ýå4#’Ê0˜Nsí¨`¡úýPœ®/Ó‚¢¾Y¢ûy5(èK9®b¡‚1fŠ… Æí$3MØ!+.¶òL¥9aQ�Îç¨@Œˆ¨+:Z·Ñ’‚·m4Uéñ0-$[%’TlÚP7Fw9 ͈¤ ÄF% 8Ÿmõ´i£!urZH4Òíh™äØÏ«AQ_ÊßI2Ý„²âæÁHòN4"iÂù,ð>*݉êíh¼Lr6ºRàÊMšAÁ˜I³†#b3 £6ê9ˆNÚ(‚pÎFU­Ùh¹‰ã6š©áÝñ0-؆l4(4ƒ¢1“a í�Ú!)^ÞIòšQI)˜LµP á\–òØKºj µ"‘ˆõJÅ+ÄÉé!Q¯Òcø/<}!¸ÏïßmÓª�üî/<æÙ=KŽ×)|ágþóKíë[«î þüÓÇïwÝÁ§@N­e~áécG;}Â_ýÄY„`<]þõŸ½àw‰ïVrî7«º×Õÿ7¼YI7çW·‰YÓÐ0ïd‘(¸ ð“ùƈ¨`çò<CzXlê&Z+1‘èaQ­i8^aª…f^¡ÉçæÔ€ &k\¶A}¬éãµÍ2+6IW|¼¶TàkŽ /¯OgÕ@bÝ͌є�ˆ‰5‘‚ÉŒH ÁÙÏ›:@kE^ÄzHPë:Þ²ÑBsÝ­qÙõ²¦_h¡64,4<¼>“šŠYhZ4ìkC3*6†³9žÛC ¼Ð†ÊduQ5(¨©:—±Ñ­=TЖ |ÕB™>“»í’jwoÔ�hµ…6÷ÐÐ,6i¢Æ¹¨ØC¹¦_PãV°Ñ•"_U[èlNhê(&Ö=ÌK‹€]RMæÌ‰Œd¡ÙÏ!#,6 €–m´¡ã͉VYA!¦xm¥ÔB½¼>—O‹† »¤šƒ3Ç-TjpÌäDaa ßM7¸týNÔ'h«%¾¢â0ßðòú\^PtêfŒgÚÐôhDl€¢Ñ‚‚ZRÉN•s¶¡®°Q?S|| µ¡Q¡î扌¨›°Sª98s,-!hƤÃ`:+Ò  <õ°Ðlx£ÜBË6<ˆnWYþ^è|^hÜŠ5§FŃ(„ yžÇzXl6 d¡¡ƒh¶Á¥êÔÃ5ýѵ_¾ õÜ%û(´ÑÐA´¢âí»Q^ÝiC×mÔwÌŠš ;Åš‹™£6Ê0Õ†ÎÛ=U ´n¡¢…2'UƒB3Û Éê3‡_xúØqÅšß%~åsO<àÕníO?uqðÓOi_ò«Ÿxè~âþ¶>x½±šmgòÿoö숈ŽÈþ<ü„^–@#*Ô„óE‰!=,44­UDk!¾^ÓÈVMp5À•KÖy7U|LI5XFa>®áášñªPTiÕÝœºZ«‰ðU'§ÏdÅ@BE¦údÞi�Ø-–ybNåšQ¡Š!œ+JÒÃB]3ÑZY°êuýG ^®¹] MduOêâôuP}*ïÔMØ-–bNæš1¡Š!˜+ÈÒ#B]7ÑjY°²Q™¨A¾QT¹DwQÅÏ·Pï]èZY¬h$Â×\œ¶P’ýNT$ædÎFу£M?¯d,m¡¬…ÚÐ0_sqÚbIjè8Æ·¡Â” 0k£ÆÊ×Ù¬ 2Q÷Gwj|¾ÉXÝÍÔu e÷F»„²H̉œA3ÚB2"BÝh¹t´¤Ò=TaéóÒ6”«»™ºQËw¢U§Mçš »„²tJ[(\,‰|*5È7ÊJš^É*,Õ`^ªøÚPS7ªbY%aVs·¡NN›±Q™9‚fL¨Rf ŠŒh •x¤…ùºbª á}ÔÙ†z¨âcÍDÏ59ÿAÔÅiK%©¾‡š‰º„²Ìã6Êa0SpPhD„º ábQâ‘n£¢…VTº]ç¤é?ˆ& BY¥¡64ÊWœ6[p¨&ê*2§ç\Øh¾…l´ÙŽjt»&8IÓÏ”œÂíî¡u mx˜ºYJ÷@õÙ‚¬¨S¨ÈTŸÈ¹�0;…*‡ÁtÞAîBU¯ßåßÿ=ÖÞãà÷¾2çÇ[%ç½’ÿÖoëi�!X(;9¤GXE3ÉzÕ! 5Ī5Æë²Œ•�W+ª,©ˆnÒðq´"d›¼Ö<TÙiHE• rU׫rU§Vvm©ìT ÜÉŠ6fKnÝ„=|ž!0]ô`hvðEÑ|ÙÉA=Ú††YµÞB›{¨‹4|\#£M4Ăʂ\ÕEš5¹¢@;XQÜG ›ÓEÚG]6ŠïFƒm¨ßF½´æ½'Ê•e¢-— +¹4uó›S6Š š/¹(Ô£¬¢›x힨ƒ ­g>ÓÚÑ�Wu·¡Ž6T"m(1§Š,ΕÜí(´0«6 ºe£e%l4«ðé¦à¥õ}”V]¤¹Y“+ seÕ–+ކN:XI"ú*Øh'_Äh-ßJ-”K4$iøiÊ)Ɇ˜·PÚܪÉe]©:ê:‰±’Dôù’KµÑÉ¢³“/µP'´H²Q§ÕÓ&ŸV/­{¸ÆAT*kÜýÐ.»§ÀFgKn+&^µP¾ªtÓBY­¢q; ÉI”€zHÝÛ†º÷ÑŠƒª«íhÙ¥6Z¸ åË&ÀKe'CZ„¯(¹õsõ|“OÙènCÌ©ÌO«nڌפ’Æ…¸Š³ •ÛP‘˜S7�°SÈß.Z(k¡"Vƒw jª¹&ï§57UÚѵª£¦“(+ÉD_(»š6:]t›�öyj£|�´‡6 ²Qw´£|�5‰ò~JÎ{üÁÁí7¤”¾öÚkµZ­}º´wïžÿC‡ç·o¯W™Ã÷oýÛx¤…¸ÊFà �pÓMÛŠ�à" i»M�à£5@F�!®¢¤ ñ�€+5¾¢s�€n¾°Û”�ô ¹†[3�àˆ˜Y¬ù�=|a¥î�0¤…ÛPiÄmT@ZòÑ.¾²Ñ>!·y/´—Ï/×}áÊë ÖãŠËFÕdÓa£fF•��A®Ò4pA��QV*i¬¢3•µÐ­†K5±….Õ|&€‚:IC´Q/­¡û e•m4Ý”ê½Bn¹æ�pH²ÒzÝ�±ê¥µxÃB7“J ÅÐL7[¨jâ¼j£:+k6ªJu�z…\\q©� Š™åºÏ4!‚fß}P­mÙ¨„›‰ZÇаѪj" °rEç,´“/fTÑFóqÅi£Ù•º×0!‚f¿[²Ñ+­½+ê¡ub£®ªÝͪbÍF·góÁP«~uE¾ª›(g£U+½+: fWë^Äš6J‘ÞqÔ›;6J¡‘zW´ƒ/æl´GÈïÜs@Ì.Õü�� õN¾¸Z÷�¤¸êfà �p`ÅA”Å �ð:Ezª)�ü´j�˜SE�@˜•k:-i¼ 5³Ð„âP b¡kun"ÌA1»ø®¨Œ§ºIkCë¥ìўȩ¿¦iï2hß±�ðÆo<ûì³ïuð_]]5M³»»û=qÖÂgŸ}RJ_|ñEEQ��Š¢ÌÌÌ<üðÇ_´w˜Ãæ0‡yŸ}øá‡­cq7oÞüú׿N „ûØÇŠÅ¢U‹b±Ø¹sç÷Ôas˜Ãæ}Æï÷Ÿ;w®Ùl†1<<¼.Çšø8΋/î¦Ãæ0‡9ÌûÏÅ‹‡‡‡{{{ iÕš;¿ŸÆ4ÍF£q¸§s˜Ãæ0ï3“““###±XìÝJŽu^ç0‡9Ìas˜÷“™™™f³Ù¾î”Ãæ0‡9Ì¿NKÎas˜Ãæ°äæ0‡9ÌaKÎas˜Ãæ0‡%ç0‡9ÌasXrs˜Ãæ0‡%çpæ0‡9ÌaþuBÞÓÚ/½ôÒŸÿùŸß½üw÷wçææ^}õÕ¯~õ«O?ýôû߬¡¡¡¯|å+íK~þçþ×ý×÷žþÕ_ýÕw¿ûÝßû½ß›˜˜xã7ž{î¹'Ÿ|ò÷ÿ÷ÇÆÆ¾ùÍo;vìÇs¯_¿þÕ¯~Õzü©O}êw~çwî¹Ú׿þõ×_ýk_ûÚSO=uÏ>ó™Ïär¹üà‚ üx[òÿøý×½÷ô‹_üâ'?ùÉÿÖþz>ÿùÏ'‰ï|ç;n·�ðì³ÏRJ_zé¥9ñ _øÂÆÆÆÞÓ_|‘çùÿßW###_úÒ—¬ÇÏ>ûìüÁ¼ÿ×üéŸþi]×_xá…Ÿù™Ÿñx<ßþö·¼íßÿýßë[ßúµ_ûµÏ~ö³?©>.,,üæoþæÞÓ~ðƒôGôÊ+¯üÙŸýÙÏýÜϵÿè'›™™™ö7æ3Ï<ó‡ø‡?ö«ýÒ/ýR2™üçþg—Ëõ.«ÍÍÍýÖoýÖùóç¿þõ¯¿WâË_þ²u¯—½üÝßý]$y¶SSS_üâ�O>ùäsÏ=÷ÿ»’“ÉdFFF>ûÙÏÞñ÷‹Å^yå•‘‘‘|>ÿÙ¬R©422òÌ3Ï|ík_³–øýþö¶¶¶FFF²Ùìç>÷¹O~ò“ÝÝÝ�€¥¥¥‘‘‘jµúc׹߸ßèëë{î¹ç^~ùåo|ãÂßþíß¾{Íõõõ‘‘‘B¡p¿—šœœÜÝÝ5 ãÇÛ’ú§úã?þãO|â¿ò+¿�ø‹¿ø‹/}éKèÿeïÍbìþÿÿ3MÍ´ïû>*u·P"ƒ¦(!J!ÙR¡De )Ê.IÒ&!B‘ˆ¸Ý’î[Q -SѾ—öMMû23ß?Îï}}æ—å–å¾»9¿®9×¹®sÍëœë<ÏysÃÆfjj:¡JOAAAMMÍâÅ‹“’’xyy©T*@ø¡z“påÊYYY�À’%KæÏŸÿüùs<?¡Ì’——çèè(%%åëëûôéSXöîÝû·ÍÍÍ%gϞžåþBšššrrr–.]ú½þcEE… ×¹sç��/^¼8uê‡sqq9{ö¬ˆÈZc¾´´ÔÎÎŽŸŸ?((�ðüùó3gÎàp8OOϯ.õµµpQäÏÐÛÛ›““ÃÇÇ÷u¶ÊÉÉ9w–l¨-[¶ìáÇbbbŸ¿°¸¸ØÞÞ^HHèìÙ³üüü?G/çkk¢¢¢ZÿãÙ³gŽŽŽÏŸ?Óé!ÿŠŠŠ¯~8,!Ø(¸rå ™LŽŽŽÆâ\¾|ÙÑÑ1//ÏÍÍ 6%6mÚTVV6Þ´²³³BCCµ´´¶lÙ’°zõê7n`ÿ%&&�pòäÉ„„�€‡‡Gzz:�`ëÖ­XœwïÞ±Þ–Édb§ÌÍÍa`ee%™LÞ¼y3•J%“É{öìó0mmmÍÍÍâââ𿋈ˆ444@9÷ôôÄnøöí[ØL#“ÉæææØ)¸‡F#“É–––�€ªª*ì,ÔÑgÏž‘Éä£G>xð€L&Ãwø+(..#®XZ¶¶¶�€üüümÛ¶½|ù>|øáÇð844^uîÜ9ìªÇôÕTUU…fÁãñ………L&sxx»pùòå0&´pNNvêСCð>·oß&“Éááá°»ŒE€Ù - Ûd2¹¤¤d\Öxûö­­­­¸¸ø… ´´´6nÜøøñãõë×ÇÅÅa ]½zë.ciii��2™\\\<&[±†ÔÐУ£ãž={ZZZÈdòš5kÊÊÊÈdò–-[`„çÏŸc÷<}ú4lS_¼x� �8qâçåË—_‘郃ƒ<<<0/º»»ß½{÷âÅ GGÇØØXÖ‡L&ÇÅÅ�Ž=Š…dff~Eº•••Xºòòò]]]õõõ÷ïß'“ÉÁÁÁ0ÚùóçE|Ð…�� �IDATÉdò;w|}}=ztðàA˜(–­d2¹²²’õÎÆÆÆc^ÈÚµk¿KU;iÒ$øÌD"±´´ÔÔÔ”L&÷ööΙ3gppKÑÊÊ �PVV¶fÍšªªªâââÈÈH…§OŸbq ·)22’L&GEE’ÉäßÿýÈ‘#X¬>$“ÉÕÕÕ+W®$“Éðyôõõa´E‹ÁÚÚZìZ¬S‘œœŒ|Cƒñþýûîîn&“I§ÓßšÀÀ@øV`!®®®�€€€€uëÖ�®^½jooÏÅÅuáÂ*•ª®®.##“››û~œÜ¾}�°lÙ2ÖÀ³gÏ 9;;ïÚµ ö‚CBB¬­­¡ß ¸¸XOO�pýúõ–––ñ¦øàÁè»` Þ´i•Jµ··¹páByy¹™™�Àßß¿¡¡aÍš5œœœW¯^¥R©JJJ²²²EEE�€úúúÉ“'*•šœœŒÇãõõõóòòdddÔÕÕcbb Ž.Z´hÌÃÔÔÔ¸ºº ‘H¤àààŠŠ *•ZWWçììÌÃÃH¥R§OŸ.--žž®®®�““cmìwvv¾ÿ¾ªª žÊÏÏ—••USS£R©—.]âââ²µµŠŠ�ðòò¤³³óx¦¨¨�øë¯¿455›››ñx<W]]¼¼¼„„•J‹‹#æææ \\\+V¬ R©¾¾¾¼¼¼T*uÏž='Nœðññؽ{7•Jµ´´‹“\AAÁ¤I“äääH$REEE^^•JíèèPTT„}¬ÄÄDvvöyóæ½xñ�ÀÉÉÉê¾X¹r%¼¯¯/�ÀÍÍíäÉ“‚‚‚nnnT*uùòåbbb·nÝ‚-IIIè²{öìÙ¸l’””�˜7okàåË—EDDlll¨Tê–-[„„„‚ƒƒ÷ïßÏÇÇwøða*•:þ| ‰GQ(�€´´4ì/ÊÉɱ³³?}úTCC‡Ã±³³744��ÄÅÅaƒƒ@ ]»v““sõêÕ>”X°`•Jõööæçç÷òòª©©Né;vÔÔÔ¸»»óññ;vŒJ¥Î;WRRòÉ“'ãÍú–––¨¨(NNN‰dccÓÐÐ@¥RËÊÊBBB��NNN555T*¾8�€Ó§O»¹¹ñòòž<y’J¥R(IIɧOŸŽ7ÝæææÈÈH˜®]}}=LVÁ®®®0š››Tt{{{11±   *•j`` ))yýúu¬jÊË˃…ôôt0yò䯯FQQQ*•zÿþ}`jj ³uîܹïÇÏüùó�?†?'OžŒ•I¸„¿¢¢"•JMHHààà066nii¹~ý:�@OO¯¸¸8>>^\\|ñâÅT*ÕÓÓS@@àðáÃpôAXXÖ‡¢¢¢¼¼¼¾¾¾T*U__Zxúôé��YYÙGIJJÊËË×ÖÖª««³±±Q©ÔÔÔT<?sæÌ‚‚YYY*•zåÊ..®uëÖÝ¿_\\ÜÔÔ”J¥8p€ŸŸÿСCãúï—/_>{ö,l1{{{ãñø¯éå\»vMSSSSSóÒ¥Kžmii’’"‘HD"±¡¡addäëä011Qóœ:uª»»ûýû÷BBB;vìÀz ’’’pà{]¿ssóÔÔÔƒ’H$AAÁŽŽó� !!ÁÍÍ}ôèÑììlSSS‰D êëëY;éÕÕÕ8ŽD"ÉËËÓéôwïÞŒŒ444ÀšâĉŸêÞ¹»»§¥¥ÍŸ?ßÛÛÛÐÐ0;;›¯µµµ¯¯OBB‚D"qrr666bë½{÷îÏ?ÿ,((((( Ó¦MëïïŸ3gލ¨hRRÒÈÈH}}=‘H$‘HÒÒÒÍÍ͘ÇÀÐа  à«Çêêê`ó�ÀÃÓðìÙ3‰$++;<<ÜØØÛ§4D"‰‹‹÷öö’H$˜­°Ñ#""B"‘øøøÚÚÚ>tÊÈÈ$$$<~üxppB¡,Y²DRRú9ÙØØ ‘GGGëëë±–¸œœ´I@@À£G¼½½oß¾íëëkoo¿cÇŽ®®®®®.aaa,ÑÞÞ^xmssóùóç  ¢#===° Á?ÛÑÑÑÓÓ#**J"‘xxxà‹ã766ÆÄÄ0™ÌÑÑQ…Û·o´TËÉÉ?^ZZzpp°¹¹yúôéOŸ>=þ<‰D£Ñh0]!!!¬njooïéé‡é677c鎫©º`Á‚ììl//¯¸¸8==½ÐÐPVOü³ wïÞuww_³fM{{{oo/L—‹‹«¹¹ù+V&‰‹/ÎÎÎöððˆ9sfxx¸˜˜ØÊ•+÷ïßõêÕ   °°°K—.íÙ³vPÚÚÚ¸¹¹I$77wss3lÉÖª)::ú·ß~ÃápÕÕÕ £¶¶Ç)À߈­­-¬Êªªª?~ [¥µµµYYYùùù¬e¾­AZZ�ÀÅÅ%))Ù×××ÚÚÊËËK"‘DEE»»»±þJggç–-[ ?eáÐÐP===vvöºº:ƒQSS� ‘Hùùù‘‘‘ðÅ!¬UDkkëóçϯ\¹²uëÖŒŒ èêÿçÆr°Ö¢‡‡l Ÿ<yòSö%˜Q¾Žyóæa³¸¹¹±átXéÿhxyycccýüü`Õü)7£ ìÃŽëÿ„Ï8sùøøøøø:D§Ó¯\¹²{÷n¬³eË"‘8fØ,99yêÔ©lll��×ÐÐÀd2›šš$$$$%%¡¡°°PUUuÌ*{–––gÏžý:'5ëhùŒ3èt:�€““söìÙ�€¿u‘ÁÇÇ'00F£}*|QÓÒÒÈdr{{ûÔ©S `®ªª �cÚ´i±±±pjƒ°°pÿû÷ïûúúºººxyy1縯¯opppOOëµW®\Y²d Ç¿âï¾{÷®;;;–éÒÒÒ¬›cpppˆ‹‹×ÕÕÁŸœœœEEEÐ÷ðy!Ù»w¯··www÷·8HdddÌÌ̘L¦ƒƒÃ7p8œ¶¶ö˜AY''§;vpssÃ]»vyzz~fô Óµ´´d2™[¶l¹~ý:‡óõõèíí¥Ñh¡§§g\µ„””ÔGÍû Æv¿9›=iÒ$è—¦Ñh–á1üþûïÏž=“³{öìÙ±c4òÎ;=<<ÆXXBBâ£ãlll222PüàP™ªª*¦ÄFFF¥¥¥>ôòòº}ûöúõë½¼¼þÉáææÿ|œ°°0lë¯ø"‰›Ð%22ÒÛÛ{Ó¦M»wïöóó;þü‡qÖ¯_ÿäɓ۷oëèè,\¸ð+†‘>äÒ¥K>>>;vìØ¹sçñãÇétúµk×°Ë™3gŒ1e‚ÂÂÂPo`¹íAAAV¹ššÚDZª*%%VRߨ7PwÛÛÛ±ZfÚ´i<<<&&&_~Ÿ]»vmܸë-9»dÉ’¢¢¢””EEÅœœœ)S¦´µµaƒ×¯_Ãc<«`¨7Ðeèîî~ïÞ={{{Ö9N;wîÜ´i–(t± þ[z�ïHJJʆ æÍ› ›†åÈ‘#pZï+ð/^<}úô;wîXXX0ŒÍ›7‘íÐÐÐààà}ûöaz‡‘ _úëÒ}ûöíÒ¥KáÀêòåË †³³3L×ÎÎŽF£ùûûÃÉŽŽŽjØ\PPðÃÚLLL “:>>>Ö2üÑ›˜ššb*œœœp”———ufì·XXYYFåàà€5ðúõë™LæÞ½{CCCÙØØ¾e~ øqßåðòò ®]»VCCŽ(|GŽ?ñ™ ,(//×=çÌ™ýäÉ'''�À­[·ddd<<<ˆD¢   ‘HühgîñãÇ£££ðÿŽkêTvv6'ü¡¡¡®®.¨1\\\c’æáátttÔÐÐ(,,ü¨_��wzeÕ{</((XRR¢¡¡Á:ãü»PUU5ÉdÒh4666AAÁñŠ—  àñãÇ544>œAÐÛÛÛÕÕ›„üüü¬ÍR'((888¨¡¡½oczÜÜÜÃÃÃ0CY_QNNNAAA oŸá­««—ššjgg�¸ÿ¾ŒŒÌ·O’VSSû7Ôèèh__ÔZÖŠãСCp„€››Žcihh¼zõj¼ÏC§Ó»ºº`ןýÃöÁùóç=êêê:fv+LwûöíÙÙÙß’.kºD"‘““shhhpp““ó£/ì§ÐÒÒú”ã–áþþ~ °b,((øûï¿khhøûû4¬¶mÛ¦¡¡‘““ó·._]]]Ö*¢¼¼\CCcóæÍIII222nnnööö§Nú ì7õrp8ë«ÎÆÆC°SQQQ«V­Z±b‡£ÓéÉÉÉJJJ_#†ll¿ÿþ;t¤��6oÞ|äÈ‘¡¡¡S§Ny{{;88ÀI8Ø@w„¹¹¹©©éŸþ©¬¬<®äðxüâÅ‹áô‡û÷ï3Œõë×ûùù;wîøñã!!!û÷ïߺu«§§'''ç¹s熇‡7nÜuåÊKKË%K–àp¸ääd{{{]]]:ë߆†IIIø/¤¥¥srrØØØRSSçÍ›wèÐ¡ØØX¬¥Éг³óÐЯ¯/ô+2Œ€€€5kÖ¬ZµjxxØÖÖÚöáÇZZZ¬ÀhhhPUUź\“&MJKK›;w®„„“ÉÔ×׌Œ|üøñ‡Ž7°®ü) PTT¤©©)!!¡¢¢’’’2þ| ,-XT0 ÷ðð:xðàáÇétzHHȇo]rr2…B!“Éð>£££µµµpü NX`2™²²²ÉÉÉ%%%¬Ï±²²ÊÉÉñññ!îîîCCC‡>zô(ƒÁ ´°°ˆsáxmbddtëÖ­Õ«WÃG²²² ¾råÊ.]ºÄ`08àìì Û;wîtss£ÓéÑÑÑFFFÁÁÁ¬©çääL:U]]60×%Œ3Ƥ8nþüùׯ_ß°aƒ„„Äš5küüüöïßÏÅÅuàÀ¡¡¡cÇŽ;v¬©©i×®]...Û¶m£Óé7nܘ3gÎxÿ¦††FRR’©©),ÛL&ÓÒÒ2,,ìÖ­[ðñèt:N „³ÈNž<yöìÙááá-[¶lݺ•N§Ã‘˜ñ¦;uêÔ„„sss,]+++8g¾8ƒƒƒ>>>X©f­²àñ˜¢ óòò¦N:22ÒÜÜÌÁÁQ^^®ªª ³O]]ýéÓ§¹¹¹–¨¯®6Ǽ;°_®¨¨S”““{úôé˜ /^|ùòåÍ›7ÃÚÉÁÁaÿþýgÏže½s``àðð°““Ó–-[ètúíÛ·õôô>ú¯kkkedd  ^¿~Çã_¾|©¯¯ŸL&_¿~-44ÔÑÑñÎ;°#ûíßáÂàà`ww7???ƒÁøŒ'ñíÀMðØØØ‹/ÌÍÍ-Z§_#ˆoatt4 €Édbßá"þ]îÝ»G£Ñ¬­­¹¹¹|||Ђ7ÿ4ÕÕÕÊÊÊ&&&4­¿¿Ÿý£1.†‡‡ƒ‚‚~è÷ȈÔ±†øv&MšôôéS333è?533c]Ø@|±±±ááá{÷î…+Ä ä þ?TUUÇ;»@|žõëׯ_¿Ùa‚ƒk@’ƒ@ $9@ ÉA ’@ ÉA&@ Ä?ÃØIÒ£££pC@ ¾…×’gsº¤¤$99Y @ ß6V½)**Bzƒ@ ˆÄÿõrSSS'Mš„Œ‚@ ˆïëæOÿ?Ç''§²@ ¾ üüü½½½p›+€f¬!âI@ ä I@ Hr1qA[´ýp¨T*2øù““C’3±(((Ð××Gv@ ?õr&8nÚ´iÈâçàÝ»w\\\¢¢¢CCCHr&L&s¼ƒ@ Yr„„„DEEÇ{!š>€@ ˆˆqôr222"##ᱩ©éòåË?-444??÷îÝjjjàììÌ`0ÂÃÃ5[wuuíÝ»+**8p��PXX¨««»eË,fRRÒ;w–.]jnnC¢¢¢RSSõôô°h¾¾¾•••ØÏÓ§O ÂãÍ›73™Lx,""âëë;æaÞ¼yÂbbbbmmýác_¾|ùÕ«W...ÚÚÚý_nnn===aaacN555<xû©¥¥µ}ûvôÖ!¿,_ÚËyõê•——W{{»¹¹9‡¯¯o||ü§”)..®­­íS·Š¿{÷î¯fèžž''§çÏŸ›››kkkGDD?~�ÐÒÒ÷òåKÖÈeeeqqq………ðgttô™3gâââöïߟéÍ¥K—455ÍÍÍÍÍÍŸ?îääÔÓÓ�pppˆ‡á åúõëûöíó<ÍÍÍqqqïÞ½ƒÑ¸¸¸üüüîܹóá“ëè蘛›KJJ~ê¯=|ø0..ŽN§ ommuuuÍÌÌ„ILš4),,,((½uêå|ŽÌÌLcÇŽijjN™2¥¤¤DYY966öþýû0Ζ-[ srr��Ç ™<y²‡‡Gmm-ŒsáÂ~~~ì¶}}}ðXVVöôéÓ�€’’’#GŽèèèÌ›7/ €B¡8;;ÿ†&‰6lpvv644,**òòòJKKcµphh¨««+�àÉ“'7nÜ��àp8xöíÛ·&&&ÆÆÆ!!!00==½³³ÓÐÐv><˜””4<< �øã?p8ÜÒ¥K¡¤íرãéÓ§}*­µµ5**ª¨¨èÞ½{˜ðlÚ´iþüù/_¾|ñâ…ŒŒÌµk×òòò>UYYéïï/##ãêêJ£Ñ��vvv111lll¬ù›œœ¬¥¥“ðóóËÊÊ�¼xñâܹs0š¹¹ùÚµkïܹsïÞ=[[[SSÓ‹/¦¤¤lß¾ýåË—YYY¸wï^qqñÉ“'Ï;W__/Œˆˆàááa2™k×®…!ÂÂÂð¶uuu˜ÊN:ÕÃýêĦ—ÓÒÒ’ŸŸ/##£©© B‹-¢R©¾¾¾âââ ÃÓÓ3--ÍØØXAA�°xñb ‰}ûöݸqÃÔÔÔÁÁ!33ÓÆÆ¦¿¿ÞshhhíÚµ¯^½rpp033‹‰‰Ù»woyy¹««kcc£˜˜Øž={ß¼yósš@ ,Z´ÈÐа±±ÑÍÍMIIÉÇLJµÏ‘ŸŸkkkKJJ°S×®]KHHÐÐÐX´h‘´´´¿¿?ìè9rDUUÕÝÝÝÊʪ±±1,,,..*zLL N·²²²··Š‹‹ãCûLôĉBBBx<ÞËË+99ùÍ›7‰‰‰---ÙÙÙ‰‰‰...%%%---kÖ¬áââ�ØÛÛc ‘”” ¬©©±²²òööž2eJ\\œ»»{FF†‡‡ÇÈȈƒƒƒ”””ŸŸ_LLLyyybbbMM �    11±¹¹™J¥&&&nß¾=22211ÑÉÉ)&&ÆÌÌÌÁÁáÕ«Wk×®ZµjUrr²ƒƒƒµµõÝ»w6oÞ\^^îàà@&“#"">ô+"ˆ‰ÛËù(d2988˜D"ÉÊÊ>zô())©¹¹™B¡À9 Ó¦MX³f™™ÙôéÓ¹¸¸ˆDbZZ¶/)NOMM766®ªªêëëËÌÌ\µjUNNÎܹs-,,ÚÛÛ½ao[[ÛŽŽŽÈÈÈ1C#ÏŸ? RSS»xñ" ƒ1X»öxÚÛÛ¡…/\¸@£Ñ¶oßnkkËÍÍ}õêU8š2oÞ¼û÷ï®]»ÖÊÊJLLìòåË}ž´´4Øill´°°¼víÚÚµkÿüóÏGa* kkk33³°°°W¯^ Ì™3KtŒäpqq­\¹rÒ¤IeeeGÍÏÏ×ÕÕ=tèP|||aa¡ŽŽŽ±±qyyydddUUÕ˜kYÉÍÍ=yò¤††ÆÎ;ûúúfÍš5iÒ¤[·n ³³³§¤¤°³³wtt eddô÷÷¿~ýš——7))ÉÓÓsÚ´i"""èUG þÛ’#//Ÿœœ|âÄ �@uuõGãhkkoݺÆéèèøò› «««ÿd¶îèèX½zu{{ûÍ›7µ´´XOéëëÏ™3§¬¬L@@@CCÃÈÈèÒ¥K¬µpppð­[·***X¯š:u*�àúõëk×®­¯¯·²²ºÿ>ìèP(:³råJ"‘¸iÓ¦ªŽººº§§'Ö)ùÔø+S¦Láããû¿ÌÍÍM¡Pttt��{öìyûö-¼Ã¸ìvòäÉuëÖññññòòb3gÎÄŽ‡‡‡-Z422ÊÊÊ&&&–••8p�ê,â?,9ׯ_÷õõ]¶l™µµõÙ³g>|øaœ­[·>xðàüùóòòòÖÖÖ°yþkÒÝÝmiiÙÞÞ~÷îÝÕTXXXYYùÒ¥Kiii¦¦¦rrr0<""âöíÛÛ¶m[¶l 9|øðDDDbbbòòòÂÃõ´´bccW¬X‘›› «Ý… 2™Ì¤¤¤yóæÅÅÅYYYa^»1ˆˆˆ°ÖÝß—ÆÆFeeå‹/®Zµ ªNyyùx%GMMíó"ÇÎÎ~òäIxL ¸¸¸fΜ E}ûöíÅÅÅ8NÖ@ ÿÉ144<|øp`` ŸŸŸ»»û­[·BCCÛÚÚZ[[eddttt>úAÔ›uuu•gÐ~†—/_b­ïŸƒÑÑÑ‚‚…OõÞLLLª«« vî܉Íèkjjjmm•••…�€  `jjjOOOyyynn.SWW'‰Ø­òóóá|x<¿ý3Ì›7/%%û944”›› ]©¼¼¼ÊÊÊ_r“3gÎüñÇméÒ¥ýõ�€MGG§««ËÌÌLZZúôéÓëÖ­SSS †ªSUU…^uâ?#9üüü7nd2™qqq]]]‹/vqq9þ|PPÐõë×7nÜhnn~ðàAaaaÿ®®.ggg___77·µk×®\¹’@ DFF®^½ÚÈÈhhhÇsrrþõ×_ .ÔÓÓ™4iRTT”¸¸ø… víÚ¹mÛ6ww÷ŸÌÜØ‡5S¦L‰ˆˆÀN ÈÈÈ466JII}ɭΟ?¿nÝ:;;;(6=‚ßå¼xñbæÌ™0!:.))÷%÷´³³kjj:þ|lll[[Û¾}û–.]Ê:³î£<yòÄÐÐB¡À‰v²²²±±±¶¶¶ðIúûûgÏžíççÇÇÇwäÈ‘3gμ~ýº««kýúõ𛤖––³gÏîÚµËÀÀàÁƒ&µlÙ²+VpppTUU=yò„@ ¤§§“Éd===:ÞÓÓ-%%µÿþM›6½yóf```Ö¬YþþþèUG &8088ØÝÝÝßߟ`eeõ©¨½½½Øx ??¿PWWWww7ô ÷ööЉ‰qss·´´ JJJ‰ÄÆÆFèí‘••mllÄvÀVPP`0ïÞ½ƒ?988¤¥¥�ƒƒƒ---\\\YYY666«V­ú¯4åêêúþý{ìÏBˆD¢¤¤äÀÀ@kk+77·˜˜XooïÐЈˆF{ÿþ½€€�ôÈ cž¥¶¶¶þþ~qqq..®ææfÖutdeeñx<<Æ&¦Ã¾Ž¬¬ì˜§bMwŒ°«« s÷ñññµ··÷õõÁÇ`ÍVvvv�À»wï œ¬ÈÊÈÈë...qqq�@__æe…e �ðþý{†•%QQÑþþþþþ~ NNNL³±19998'û³Ø?njj‚œœœèUG ¾#999BBB¿ýöÛß.åÅÏÏßÛÛË`0|||Æ1–ÃËËË:~ <Øçî��l^ë…«#X/gccSI½yófõêÕ³fÍúÔ «ÿ.þY¬ÆÂ1 óóóc0±Z�ÀªŸù<ó£i}*]V ÔaˆŠŠBÇ)77÷G³õÜÅàààøh*<<<<<<c…„„ ö`eéÃ8cÒýÔŸ%k1Akÿêêê¶¶¶***CCCK–,A.@’ócž†ÝÄÄ› ÌÁÁ?3D ’œïg]çç`dd$** •6ñsÀ`0(ÊÏ 9?lll®Ÿ†@ ? ƒƒƒHr&ëÖ­Ãæ€!Ä/ÝG&@ ’@ ÉA mlžI�� �IDATI@ &,húÀÍ@ ?%p#4$9‹|t¥møO£¡¡¡¨¨ˆ$gbÁÆÆ¶nÝ::ŽL@ ~úúúðx<Ûß.ë‰$ç_€Édöôô ; ˆŸl%éq7Á‘íñÏðE½œÖÖÖüü|iii ,°ªªª²²ròäÉãZ%>%%ettÔÄÄ„N§'''‰DØMËÈÈÀ¢‰ŠŠbû`~ ùùù­­­ºººÂ™™™ÝÝݳgÏþpéû—¡¡¡ÔÔTžÙ³gÓh´×¯_ ëêê²ZXPP°¨¨ÆWRRš4ië ššš´µµÅÄÄrrr:;;aøœ9s°0 áS555ÈÉÉ©©©¡÷@üû’óúõk[[Û5kÖ„……awîÜñõõ=vìØ¸V³··§Ñh£££W¯^400èëë»qãÆ‰'ôõõa4mmíqIÎéÓ§=ztÿþ}CCÃ?þø£²²R]]}¢INgg§µµµ²²rVVVUU•µµµ¾¾þÇ�¯^½²³³300PQQyúô©ººzee¥††Æþýû•””àåoÞ¼ñôôÌÈȈ‰‰Þ¹s§  `ZZÚÁƒ×®] UÇÎή§§§³³‡Ã}ÉS=þ|ëÖ­§OŸFïø÷%‡•ªªª7oÞLž<™50//¯¦¦“ÉdIIÉ/^´··æææÒh4ž„„¸¥ãï¿ÿnnn¾råJ"‘800íáá!//¿yófMMÍ´´4¸É[CCCVVÖä×ÒÒ�—––Â@…¬¬,¸dzzº¦¦¦±±ñ´iÓàrÔOž<€‘-,, ÆÃ‡‰DâܹsŸ<yÂËË;þü ’²²²ÂÂÂ{öìY·n]@@À±cÇ444ÜÜÜ …ãããëêê`äS§N?yòDOOÏÛÛ;==ÝÒÒëè,]º”Édb{9sqq-\¸F£%'' ¶¶¶fddHIIÉÈÈäääÀl}ûö-´0@LÉ©ªª:}útnn®……Eqq1 ÌÍÍ=|øðÀÀ�‰DÊÈÈXºté¶mÛüüüÒÒÒ<==[ZZîܹãáá±aÆäääÑÑQ¨ ,ذaƒ¸¸øË—/SSS�===/_¾äààØ°aƒ‰‰‰¼¼|PPPRRÒÌ™3+**„„„<ÈÎÎ~âĉúúz55µœœœ9s渹¹åååµ´´��²²²¬­­;–““óêÕ«ÊÊJWWW"‘x÷îÝ¡¡! ‹ 6ðññ?~<)))'''((hÁ‚ÿn466fddÉäK—.ÁÒÒÒ·oßjhh`£s×®]›1c™LŽ‹‹sù±cǰ㌌Œ\¼x166vûöíË—/|ñâEHH‰DÚ°aÃŒ3 ‹ŠŠ6lØ`ff¶}ûö7oÞ��êêêJJJä ˆÊø¦¤¥¥ÝºukþüùÓ§OÇ6œMMMµ³³»pá‚®®nXXXaa!Öûqss“””<pà@WW—¿¿?ÜríܹsØ=………a¥)''çááÁÚsºté™L¾páÂáÇ¥¤¤ª««ëêê„……½½½/\¸`hhxýúõׯ_;::jkk�vîÜ©¬¬ŒÝÁËËëýû÷§OŸ¾pá@pqqá###åååÇonnf­¯ÿ-Þ¼ysáÂìgiié©S§***8`jj ¥TXXó°a<yò$:::::šF£ÁÝ»wÃåÄ]\\ˆDâ… üüü:;;<øÑ¤g̘±aÃ�ÀܹsW®\‰Þ1±k*• È/^ aî5ÈÞ½{edd¾ý)) ¶¸¸x^^Þ•+WJJJ¾în¼¼¼ÇŽó¨ÿ.ŠŠŠ†††˜Þ”——{zzB½ÉÌÌüóÏ?çÏŸ?sæÌˆˆÖ«ÊÊʺººâããœùøø��ëׯÇãñ¨d#ˆŸGr>¤¹¹¹¼¼|Ö¬Y³fÍ’““ûA›““ãããÓß߯­­ÝÝÝýÓdÔ)SlllXõfñâÅðÔÇëêêDDDòóóËËË�?~÷î�`Û¶mzzz¯^½òõõ]½z5”œ'N°³£Ï­ÄDä+¿ËÉÎÎ~ýú5kˆ••ÕÉ“')Š””Ôß®ºÃ`0Ο?ÿåɽyó&888===99999ÙÔÔôäÉ“3gÎü0f\\×ù¯PWW'­AAŸ={6¦7��}}}EEŦ¦¦¦¦&è4{ÿþýG¿ø½rå 6Wâ3444ÄÇÇž››Ë:O@ þå^Δ)SŒ³³³ùøø°ZÏÈÈèÕ«WOž<ijjºwªê’%K>u‡mÛ¶:uêìÙ³}}}ŸOKYYÙÌ̬¨¨Èßß?''§­­MSSsÖ¬Yd2955uxxXLLLKK+!!aêÔ©EEEwîÜ‘––Æ––qppðõõ ãááݹsçÌ€ŠŠŠ›7o.]º”µê÷÷÷‡Ç eáÂ… .„?KKK×®] E÷æÍ›©©©ííí7nð÷÷ïïï‡1wíÚêïïß××ÇÏÏ¿iÓ&QQÑõë×'''ß¼y‹�PWW_°`A^^ž¨¨èŒ3Ð+@ ~x<ïåå544ÕÕÕÕ?Œ„ÃáÄÄÄôõõ ”••™Læ¬Y³æÎ«  �¥¥¥ “ÉTSSsrrRVVÆápS¦LÑ××çååeccÓÕÕ3g‘Hœ={6;;;‡Û»w/;;;…BÑÓÓ�pssS(mmm'((oÔÕÕ™L&“É”’’Zµj•‘‘‘¼¼¼¢¢"LkáÂ…::: CUUÕÐÐPDD„Á`ØØØÈÊÊjkkëëërqqÁȳgÏÞ·o‡ûh¢?ÔÄoÞ¼ÑÓÓÂápœœœ eÚ´i��~~~ …¢©©),,L¡PÔÔÔp8œ¤¤ä¤I“˜ÿCAAAVVöÿú¤lljjjÐæBBBð¯M›6 ~£ÃÆÆ¦§§§¯¯ÇãáNL&“ƒƒÃÄÄdË–-<<<0]99¹µk×b‰JHH¨ªª2™L===###ôJ ˆ¿¥©©‰‹‹KLLìoW$‰ÃÃÃL&óåË—iii8088ØÝÝÝßߟ`ee…¬ù}‰ŠŠruuý™FžÄ/¶ÆÚß.ëÉÏÏßÛÛË`0|||Ðkø‡@’ƒ@ ˆ4›öŸ€N§£É`â§¡½½]HHIÎDíK²±‘H$dñs@"‘àJ˜Hr& eppp\[< ÄÄ.ÓŒ$gb¡¨¨8<<Œì€@ hú�@ ä I@ Hr1qAÓ~8pOøÉï¤5$9ÿ7oÞDF@ ?Ó§OWTTD½œ‰Hww7ëöñŸ†H$ 2 $9ÇÏÏì€@ ~899‰Dâ—ì 94}�@ ÿãœ{÷î)ýÓ§OÃÀ“'O*))ÅÄİÆÜ°aƒ’’RNNΗ߼¼¼\IIiÅŠ(KâW—œ8;;/Z´(??ßÕÕÕßß? ��ÐßßßÙÙ988ÈùüùóùùùãÚm“N§wvvÒh4”%ñKKΣG,--ƒ‚‚xyy·oß¾wï^ŸÀÀ@,ÎŽ;$$$>|�°··Çz9óæÍ“ø0²”” ÑÔÔ�TWW��rrr,,,P® į+9 ctt”�€Çãñx<NǦ+¸»»Ïš5ËÂÂÂÖÖöñãÇ£££p³k##£¼¼¼/^´´´ˆˆˆ(++Óh4))©ÑÑÑ–––ÒÒÒ¶¶¶iÓ¦‘H¤ÔÔT�€®®îƒP® į+9‹ŸŸßêÕ«?u¶¿¿¿··—ÉdŽ lii¡R©(âWàŸ˜$maaÇã�ÂÂÂ8@ ä|"‘( 000@£Ñøùùûúúz{{yyyyxxÞ¿� ÑhŸ™ ý矪¨¨´µµÑét^^^,œÁ`´¶¶âñx111,pxx¸¯¯ïë¶8E ÄDæ‹k ,8þ|jjª››Û»wï#""<==œœ`„ààà˜˜˜¾¾>QQQ...ìB ަ¦¦wïÞéëëÏŸ?¿¯¯OVV�ðîÝ»¢¢"MMM��‡¤¤äÐÐÐÓ§O÷íÛ‡2@ ~QÉ�˜ššååå-[¶,>>~ïÞ½ÎÎÎ��QQQø™N}}}iiixxøÜ¹s±«bbbŒÝÜÜ–-[ÆÇÇ—––ÆËË›••E"‘–-[foo¯««ûäÉ�€’’Òýû÷ûûûïÝ»wñâE”1ñó1ޱ33333³1;vìØ±c�`ùòåüðª1_‰B233? TUUÍÎÎFY‚@ ¿z/çË©®®îééQRRâááAöE Ä”œ«W¯2™Ìˆˆø™'@ ï?IúÈ‘#Ȭ14;Z´@ü,¶¯ì® zð‡ƒÃáäååYg‡#êå ~t:}Ñ¢EãÝ®@ &8h‹¶‰H__2@�´E@ ä I@ Hr1‘AÓ~8D"áË¥ÓéÈ_‡#È_ÎÈÈÈWLµB ÉùoÀÉÉ ÷äFü-rrrüüüHrƃÁ(..F¦øTUU¡Å)äüœ0Œ—/_¢åþ¾,²³£ŠàëèééÉÍÍUVVF¦ø<Éd¢"‘äüüíPd‡ÏÃÅÅE$?³×â3ðòò¢2ö%VbggïííE¦@’ƒ@|ÚÛÛCBB��òòò›6mBA þ{’“ŸŸëÖ-ìçܹs.\È!..ŽuÄÂÁÁAII Ù÷CÚÚÚnÞ¼ 7‚_¿~� ««kee5&~BBBZZ�ÀÊÊJWW ¿téÒ‚ ÆÄ?|øðÐÐÖo€›µ··Ÿ9sÖÂ[·neO¥Rïܹƒý422211�<|ø0##�°jÕ*mmmx6""¢²²�°}ûv))© hÞÎÎÎàà`iiéúúzƒáèèø‹¹çÏŸÃl…ܽ{îMµ~ýzuuuÖÈgÏžmmmÅ~=z”ƒƒcdd$1÷/++‹ŒŒ�hkk¯Zµ ¦¦¦>~ü�°hÑ"CCÃ1—\»v­¤¤�°uëVyyyÖSGõðð@"¾?ÿü399ÙÌÌlΜ9ã½vttÔÛÛ›‡‡ÇËËë{à/š$ýæÍ›Ã‡çä䨨¨´¶¶†‡‡¿~ýzLœgÏž…‡‡ ¨¨¨¨¨¨pss£Ò0†îîîÝ»w{zzÞ¾} ,--…F«««c­ý¡Þ³ T*�pùòåÝ»wŸ={¶¥¥åÃT®\¹B"‘à%Põß¿æÌÂ`0Î;7¦¾ÈËËSù"""PoJJJ`Èï¿ÿžŸŸEËßÐÐЦþ¯ÓÓÓ“˜˜¸eË–;wîÝ»îzþË’žž¾{÷îãÇgee±êMMM ÌÇÛ·o™w+,,Œ•Ç`0<==áO!!!Öøååå7nÜ€gccc�iiiééé00##ãùó笗\½zµ«« ž½xñb}}=kƒ),, -Høåˆˆˆ¨¨¨ ~ŵ£££áááW¯^X½œ‚‚ooïÔÔÔI“&qqq‘Éä{÷îÁS>LJJ²²²jjjzõê•››Û˜6 ƒ@ èèè´¶¶²¾äüüüsçÎ…»wß¼y3##cåÊ•ØÙœœ!!¡7�\\\ªªª¦M›¦¤¤D$a×ç£ØÙÙ±ÎÌ&d2ÙÂÂ�••uøðaÖø“'O†I`deeÉÈÈÀ@''§êêê©S§*))©««KJJ�(Š„„Ä|}}}=<<Æü©_111ŽŽÖÀŒŒ �€M}}ýo¿ýÆÁÊÊŠD"a?™L¦®®îš5k��K–,Ù¿?v¶©©©¨¨nYrûöí´´´U«V‰‰‰-\¸pÚ´i�€#G޲vtH$’²²²ŒŒ �`Á‚+W®„-ƒC‡)**âñø nÕüüüˆˆxl``�_ØÄÄÄGÁÀU«Véëë_¿~=++kóæÍZZZ!!!eee{öìQPP8qâDss3ŒéççÇÅÅÅ`0vìØÁÅÅåíí½ÿ~QQÑC‡Õ×ן:u FSWW‡Î‰¬¬,è�ÌŸ?ߢ©©)77—D"ÊÉÉUTTÀ=—·lÙ’’’RZZ �Ø·o´ðÁƒß¿/ üW¬÷÷½aaaX"%$$TTT°ð?þøãäÉ“ÒÒÒ™™™•••¥¥¥'Nœprr*,,üYßᘘ'''''§¬¬¬ððp''§/ŸœÊÅÅecc³téRÖ@)))¨7™™™eeeëÖ­ƒåû÷ïê>sçε±±SÝ8p «« »ºº:99mß¾þäááz{Q{öìsÃ/^À?CV¬XÑÖÖ544 CÏÈÈêÍÉ“'7lØ�'¼¼¼sçνpá‚“““ŸŸß/.9“'O¶±±3­`íÚµ•••0sgÍšçRúûûWWWÃ^^^ðl?��‡ÃA½ééé9uêÔñãÇ�õõõ'OžüTºjjjÓ¦MKHHprrâææž?>ëYCCC™ÀÀ@''§•+WbÔøøøÅ‹OðïØÞ¾}{àÀÒÒR …‚Ãáüüüîܹ“˜˜xâĉžž …ÒØØxøðáôôôôôôèèèwïÞ�þúë¯èè莎ŽcÇŽ]¼xQMMB¡<xðÀÅÅeddÄÙÙùöíÛÚÚÚÛ¶m‹ŽŽ~ðàASSÓîÝ»ÓÓÓ)Š˜˜XHHÈùóçsrr¼½½«««)Êð𰯯ïƒòóó£££KJJ233:ÔÙÙI¡P <==ÙÙÙ) ìé655y{{_¾|yêÔ© åÎ;ÎÎÎTr¤¥¥¡—PQQqúôé0ðÑ£G'NœPWW÷ððPQQ±µµŒŒtrr255-++swwÿ)¿¸uë–¿¿?77wCCûwïÒÓÓ¥¥¥¡'êÉÎÎ~øðáÒ¥K¡…I$ÒäÉ“ÇuCCCNNN�@XXØ’%KLMM ¶mÛ†Ehhh8{öì’%KæÍ›ÇzáìÙ³½½½MMMMMM+** Ô•––rssÃÀ¶¶6¬Q�ðññ‘””\±b??ÿÌ£¶¶¶³gϪ©©]¼x©Î‡ ÂÌmhhhkk�Ìœ9:gNœ8±råJxvçÎÃÃÃðªþþþ½{÷.^¼xÉ’%��>>¾Y³f}>!%%%SSÓ‘‘‘šššÏΘ1ÃÔÔ´¤¤„F£�<<<<<<&¸õšššÒÓÓ›ššh4š››ÛÔÔÔJJJ ´´´¬­­UTTrrrª««g̘²aÆâââýû÷“H¤9sæÙÛÛ[[[‰Äøøx:‡ÇãW®\iddS¡ÑhIIIÂÂÂÖÖÖ†††0Ѻºº×¯_××× ¹»»ïÛ·oL-‘••%))imm-##“––¦¦¦fmm-""’””ÔÝÝm``pîܹõë×[[[ãñø¸¸¸Å€_9c­¬¬ �°råJø)€¶¶66Â|ûöíÇ···ÿ|ïêÛ·o ÜÜÜ:;;cccõõõ—-[&..þ·¥R©wïÞe¥ÿŠ,,X�ÌÌÌàA__Ÿ»»;œ»ÕÜÜìãã³fÍ}}ý1ÊËËcÍÌÀÀÀââbKKË‚‚KKK�ÀãÇf̘õFZZÚÒÒrÂV ýýý¯^½ îîîÆápÉÉÉîî–`= …²eË–FËËËÓÑÑ™Çä( <kllŒÅܹs'ü,wxxØÅÅeݺuXE@@�öÎ?ƒªªªªªj~~~EEV>1`C6,,¬««+,,LGGÇÂÂ6›&2ÚÚÚ7nÜxùòe```JJЉ‰‰––ÖÓ§O�wîÜ¡R©EEE0æôéÓ}}}ÝÝÝïß¿¿ÿ~!!!###www8d µƒƒƒÃÔÔ”ubQeeåºuë0¿(™L¾qãÆ³gÏΜ9“˜˜hfföÛo¿až‰¿ÅÄÄdÇŽ0il†ÑFr,-- BLLŒŠŠŠ¹¹ùÅ‹ÿúë¯íÛ·X£ýdhhhÈÉÉÉÉÉÏž=ûÛõ&??ÿæÍ›¶¶¶S¦Lù.OhggÁÁÁÁÚð÷òòÚ´iÓG›¥ÏŸ?/))qrrúÛ;ûøøÈÈÈXXX|ÝXå?Œ€€À¬Y³’““î‹´´´½½=æ°ýº›ìÚµkß¾}¬^Sƒaggçääô·ƒ‘ÐÙÙ ‡‹>ÄßßßÈÈŽô@ÒÒÒ á qooïúõëoß¾=1÷n_¼x1|øÐÐзoßb–êèè,_¾«(��Ïž=«««�<yòÄÜÜ\HHhïÞ½111¾¾¾éééX'ò£ˆŠŠb*...%%%%%5uêT&“QTT4®oZ·oß~çΧOŸþ[s4¾2SI$’ÝñãÇ>ŒÃáJJJþüóOÖqoÄÒÑÑÑÐÐð½ô�’’2æþÁÁÁ¼¼¼O¹Aàðï—Ü977W__ÿ?¡7¿&¬3¡¿Ž—/_Žù—Éd>{ö,&&æËoòîÝ»†††Ï4³Æøàà`l'ÃW¯^999MØIÙÙÙÇ×××wuue2™çÎ+++ƒÎ “ˆˆˆ?þøÃÕÕ5666<<ÜÑÑQOOïàÁƒ[·n½xñâ«W¯úúúôõõYÛ…Ð-agg7¦ÙdbbòæÍ›ƒΜ9³··÷ôéÓóçÏßµk“ɼ|ùreeå—«Nzzúàà ¸¸8ÿI�@AAÁÛÛûèÑ£ÞÞÞ&&&§OŸŽŒŒ,))9vìØw¬C'aaa²²²………°-..þàÁƒÕ«Wkii}õ=_¿~½xñbxljjºmÛ¶{÷îÑh4{{{;;»«W¯Â³K—.ýL3sÆ þþþ"""qqqVVVt:@ À«�€††, MMM??¿ÌÌ̤¤$///ccãÎÎNxvöìÙ°ÐoÚ´)22ZZZb^OOOÌ¥váÂ99¹ ˜Gõõõ...;wîܳg’¢1¸ºº^ºt f®µµ5t™îÝ»×ÁÁAUU5<<ÜËË ÎkŠŒŒ$‰L&sxx+?’’’W®\©ªª  œ:uª……<«¥¥µsçNXVcbb` ±±ñ²eË ®hhh{yy………ÁS›7oVVVæááù¿*‰]__®I£¤¤D¡PÂÃÓ““[ZZÌÌÌ988*++¯]»öôéÓššš+VL™2åÎ;mmm†††‚‚‚©©©===çγ±±Ù¸q#''gxx¸¥¥e||¼¥¥åúõë·mÛöòåK�€¼¼|hh¨‡‡ÇâÅ‹»»»¹¹¹—/_.** ‡ššš¬¬¬lmm£¢¢¾ðÉ#""V­ZµnÝ:Ž˜˜˜+V@çê? Ž@ vww÷÷÷'$$|ø)"� «««²²RDDDQQ±­­­®®NRRÎq¬¯¯oii‘——ïëëÃ|Ž***slùÛë2//¯¼¼<ggg++«;v”””ìÞ½ÛÌÌŒ——÷SWñññ…‡‡Ã©h°ÏQUU…}G£ÑÊËËY»Ò ---£££¬�(**²NU(++“––ÆÒ-((PUU…í¦ÜÜ\ƒ­²3<<üöí[Öç™<yrwww{{;üp§½½½¶¶Ö&0QØP…Ÿ’H$aaa�@EEEww7«ñûzÞ±o¾ÅÑ<44ôøñcggg<åÊ•ñNÄøÏÇãûúúRRRLMM?¡¹¹™Á`HKKc!µµµp´UII v[KKKeeeaÕ_PP�³@[[Ç3™LøA„H$jjj ÔÖÖª©©±–aaaalvuKK üàFFFºéjkkyyyaÆÊ’šš«ÞÀ>––ÛÙW[ðfttô«oëCx,&&‡B›šša ¼¼¼˜˜Xuuugg'´pYYYOOü³………ƒƒƒ�€©S§ÐéôiÓ¦Q©T</##3yòd‰D¥Rûûû±IXp|·³³›XßÖÆÆÆ¦¦&99¹ÁÁÁ¶¶6XKTVVÂ/ŸøùùKJJúúúàÛúöí[èÊÓÑÑÉËËc2™Pã§NúãÊ'??oo/ƒÁðññù"ÉA`466vttÈÊÊ ÕÖÖÒh4‰ô½ùPr?Tr êÀé-ÜÜÜ¿Â+9ˆï+9ß¹s焤¤¤¶¶6Lr~›‘´ÆÚø––ÆZ‹.6ƒ˜‰Äoñs"ÿ0aaa …L&Óét ‰kúò?’ø7QWW¹:d€�� �IDAT‡KÞÁ>ëϽ€ ’œ÷Sn}w+!#|ý›ÌÎŽÊØ·Œ±®0ô“TT 4x<ÞÞÞþ ‡"��qqqsssTÆHr�ÎÌaë…ø p âË¡Óé===à_ý¤•1’T¾¨Œ! ÔG ’@ ÉA I@ &.húÀWu4uu<0™L4ŽÊØeÌRë$9?üüüh†ôÂÅÅE§ÓÑdßqÇã¹¹¹{{{‘)¾žÁÁÁ µÆ’Ä÷„N§_½z}þ·àp8==½_ç3ìïH[[[\\ܘ%™í.\¸ðóëð"äü÷­Ìη A|¾‹W’F¦ø DDDÐJÒ ¶’42Å¿¦úȘ(½œ®®®ÒÒReeåÖÖÖêêj)))yyù††¸�€D"‰‹‹c—”––vuu©««óññ½}û¶¿¿_[[›H$R©Ô‘‘‘3füÊ£ƒƒƒåååØêúÝÝÝ%%%ØYqqñ1ž¥ººº¦¦&�À¤I“à~·�€’’8>¤©© Ý)yyy¬C 3g΄###………ÚÚÚØ©žž¸ó´°°°ŠŠ ��f+ANNŽu;¯ÿCCCyyyÜÜÜÐÂ4­¸¸XHH裵Õ××744ÈËËKII}x¶¸¸˜F£aÆÈÎΦÓ阅' ]]]Ø^AMMMuuuØYEEE ‰1—ÉË˳zœàÛ �ÐÓÓÃVÃ...³£WWWWkkë 755ÑétYYY,¤ººnú§¢¢7ýC`0Œ¬¬,ŽiÓ¦ýê’óúõëÕ«W¯X±"""âñãÇ;wîtqq9~üxtt´¯¯/‰D’••uvv^´hvÉž>}š˜˜8sæÌ­[·æåå)((X[[wtt455}ßÝ$ÿ+ ¿~ýº¡¡!$$$==æää8::jhhÀŸ .tqqÁ.©©©‰ŠŠÊÊÊ�˜ššZYY‰‰‰…‡‡×ÔÔ��lmmMMMyxxìíí%$$ˆD"¼ðÁƒ ###ãýû÷^^^oÞ¼Áôæ?þ€ûØ«¨¨8::ª©©%&&úúúÂm�666ÖÖÖÿQ#777/Z´HCCãÅ‹�€üüü¥K—šššÞ¼yóÃÈ©©©·nÝÚ¸qãGwäÝ»wozzú³gÏÆÔ°Ë–-ëíí…[5O4:;; _¼xQ[[oß¾}åÊl{§­[·²ºà ;;;=<<‚ƒƒuuua`fff@@@?�`Ïž=£££/_¾ìèè8räHnn.ŒF£Ñòóó©Tjffæ70±©¨¨ˆöòò‚•••‘‘‘°ZZZZZZ"Õaeddäĉ‚‚‚ׯ_ÿÕ%çóP(”¥K—Âýh ›››YßϬ¬,è6ÍÈÈ€›ÑB’““ÙØØæÎûK•ªÞÞÞ   ¾¾¾1ázzzP>$**JHHè÷ß�¸¸¸ˆ‰‰YYY;vÌÑÑÑÈÈ�0oÞ<uuu¸­õÕ«WY[ë###AAAcf•””DGG?zô�ðÇœ>}úòåË�€%K–œ>}úç¶sssaa!<VPPPVV&“ɰ«WRRÒÐР©©ÙÚÚÚÚÚ ÷ðÆZ]½½½sæÌáääLMM¥Óé�€”””yóæM´ÿXSSÔÒÒ‚5b «V­Ú¿ÿG/¹ÿ~nn.¶‰2dãÆ)))°W-!!ÑÒÒ2<<wPÆhll êèè`í¿}ûöâÅ‹µµµX`xx¸––ÖñãÇ�ëׯ—••]°`Á´ µµµam8YYYUUÕÚÚÚŠŠ %%¥ÑÑQ¸?7FÃLª­­-""’““£¢¢RRR×`Õ××ÏÌÌ„ÛB±³³ïرîÑœžžÎÃã¡¡‘™™)((ˆµ~Éc}ýX™<yrZZÚõëצOŸîééÙßß¿f͸­:lkwvv�bcc.\“’’bbbRRR¢££çÏŸÿëHް°p\\\EE…kxkkkbb"�@FFæK¶³ÔÕÕ­©©—hhh`Δ”Ør\°`''g\\\KK‹‰‰ÉßÞ³®®ÞPII VÁ?ŸÞ„††>xð@SS³¶¶VIIÉÛÛûÞ½{§N:~üø¼yó¼½½ÛÚÚÖ¬Ysÿþÿcï½¢:ºÇïÙ]v—ÞÛRDz‘.EPDET@ÅÄ'DM,yì55‰b¢¢b/‰&ë‚bAŠ4)¢tDzA:,Ëöòþ1¿ç¾û¥(6DœÏ_»³s÷Þ9÷Ìœ™3gfî<{ö,** ^˜‘‘Q\\|÷îݰ°°ààà+W®@wÓÅ‹Ǡɱµµ¥R©·oߎ‹‹M¯ªª‚ï×ÄÄdâĉ¢?ýôÓO��??¿×ÿ³¤¤$•Jmnnž5k–hbbB¥R=ztñâE,qúôéÓ§O?~ü¸èÚ�33³ÞÞ^ø ˜‹øs´7§OŸ¾~ýºµµuSS“††ÆÞ½{ccc÷îÝÌ`0îß¿¿lÙ²êêêîîn …’——ºbÅŠ;wΞ=»¤¤¤««ëñãÇüñÇ£GX,VBBÂåË—=<< #99900PSSsÇŽW®\éîˆ°··ÿ‚LŽ­­í† N:…¦�•••ååå .ìîî>qâ�àìÙ³—.]ª­­…s�€ß~û-%%åÅ‹ÇŽÃÆÑ·nÝúçŸTUUW¬X!:…ðe¢ªªª¥¥G9:::`€gÈ‘edddjj*ìÉËË�¼½½±V†Éd §¨¨hbb‡MØA„:::âââðLMMçÏŸ?äÌÇgFƒe,--ÅF*'Ož\²dɉ'Ξ=»mÛ6###"‘½téRRRÒ©S§zzzEÿ*>>þĉÙÙÙk×®õññ9wîÜÇétúgä�100ÈË˃ï×ÚÚzþüù¬Î(`ggUÎÑÑñó,lnn®®®þïÿ»jÕªþùgݺuЂ޼yÓÜÜÜßß?11±®®îìÙ³ÁÁÁÇŽËËËkmm�ìܹ3--ÍÂÂÂÆÆæ‡~¨¬¬TVV¦P(_ýõ�­£Ñheee¿þú«··÷¾}ûîܹóÅ9Ö²²²ÎŸ?M™Þ¿ÿöíÛƒs®_¿>===11q¸¿:þ<:ÿÃÂÂâï¿ÿ†Ÿ¯^½zéÒ¥#G޼þ’£GŠ:ÖìííÍÌÌ:„ePWWRÈúúúßÿ=ô¡½|ù:âÜÝÝÝÝÝa†?þøãÞ½{›6múÜMν{÷`Ÿt€ß‰J¥ wáªU«ž<y¯…ìÝ»WtüsdÖ¬YØÐdûöíIIIß~ûí(?ÃåË—---÷ìÙkúúúŸ©cÍÚÚzÿþýOž<¡R©¹¹¹êòÎ;g̘±qãFlØ·nݺw¸‹††Æ/¿ü2àÿÇ#ŠÓÖÖvqq©©©éêê ‘(,,´´´à/F¼---p¼òžDGGpE‹‘‘ÑùóçÏŸ?¿zõj˜R]]xÆZZZ°ŒlgKKKrr2 yãhrÜPRR‚Í= Þ“—/_;vì·ß~KNN.//ý) �›>@¼—É™4iRhhèÓ§OëëëOž<)//íçç7¤|_¾|98ýæÍ›h#“Á”––b‘EïÃîÝ»{zzÞ˜­½½ýáÇ322nܸñ%HÛÉÉéäÉ“?üðƒ½½ýc—ÔÔÔúúú‘ü•@ Àb´Æ8 ÷ïßGuíƒðâÅ‹óçÏÛÙÙ<y2$$äù“’’.]º„Í5 >ØîîîîOŸ>}ôè‘ŠŠŠhPV``àË—/¯]»Ö×ׇö5²?nbbrîÜ9�@__Ÿ››� ¨¨ˆÍfÛÛÛÛÛÛÁ_) Œcž1cFQQQUU�ÀÍÍ N’-Z´èÎ;�ðÍ7ß çºd2™YYYÐqÜßß?mÚ4�€‰‰ISS¼‹P(.Zä³FOOÏËË«¼¼üܹsuuu¢\...iii)))ZZZ0 è5„††ž:uêüùóCv­Æ¦/(++ ¾_ߘœœ¬£££§§7ä%!!!T*ªÓñ¹¸¸TUUÁg044œ0aÂgªH&Lðññ©®®>wîFsqqyþüù€tÜÜÜ233“““{zzþþûoX¯��@عs'›Íær¹•••PÃãñ¤¥¥]\\LLL¸\®¢¢¢«««®®.‡Ã¡P(nnn>>> ½½½‹/†¨îîîrrrŽŽŽ8®··wëÖ­x<ÞÆÆÆËË Ç3 ‡/áMÉ䜜+++¬w 7ƒ_•””ÔÕÕÓÓÓi4œº�TUUõõõéëëôõõÓh´¹sçBc0iÒ¤òòòºº:¶råJ8ëêêšœœÜÞÞN£Ñ~ùål±­P(äóùÎÎÎ𫜜œ®®nJJ FÓÕÕ…Ý4MMM‰”““C£Ñœ¡}ˆD¢˜˜ǃQÈï,¯££#”0ŸÏ'‘HÎÎÎÞÞÞ0t•F£ÉÉÉ…„„øúúr8UUUWWW•ÞÞÞùóçWUUUTT,\¸P]]ÝÈÈÈÝÝ]FF†Á`XZZzzz’ÉdOOOƒA§Ó÷îÝ;&<x<—Ë­««ÃB y<ž¼¼<V—'NœÈãñ h4ÚôéÓœœ��¹¹¹rrrØ n&“9iÒ$l'@77·ÄÄÄŽŽö믿b=(^ø|>_RRÓp—ËUWWÇLš‰‰I[[[YYF[¸p¡©©é'‘‰DÂãñç7“VVV677‡Šdaa1kÖ,¦¨¨8eÊWWW—ajjª¤¤ÔÛÛ kÙúõë ˜L¦±±±‡‡‡´´4ƒÁ°²²òôô$‘HýýýöööL&ÓÁÁÁÅÅ…Çã9:::88àääôY÷Éd2‡Ã …Ož<IKKÃÁHðÞÞ^ƒˆìð‡EFFæÌ™3K–,A¢x=Øk£ï€MJJ*((ðõõ533[ºté½{÷¢¢¢Æ` ôpÝÆþþþääd´ÇÚÁöXC—QCVV–N§ ‚ðððýû÷£m=ÀçóïÞ½›——giiYQQ8úaÄÄ—�29ðññÁáp0¬+888 �¡€@ “ó¹‚Ãá$$$Þ ‹bŸR½½½?ë½0ðx<Ò±‘H ™œñ¯ånnn؆›ÄGVVÖÎÎé™`2™úúúpS^ÄyŸpµ/פ¡¡t é29�7‹E >B¡éâsy6L@ ÉA ™@ “ƒ@ ˆ/±†@ o†@ Œ©Å¶\.÷s<™x38îÓn!JyyyOO±±1291náñx#<~÷ãQWW—••õ™nˆLÎG;ƒ@¼€N§‘‡'}Úg`0¢Ç`"“ƒ¨£ÿüó’ñÉäE‹!9ŒÉ¥^ɼyóˆ·‡Ã!'29ˆwARR x[“#%%õ·F#Æ h]@ Æ’Éyðàe(Ž;öË/¿P(”Ë—/�Ö¬YC¡Pâãã‘XÄË?þ8 ©LOOÍàèèH¡P:::Œ)Š@ `2™ ÅÒÒrÜ gDŽ5@Àb±-ZtòäI,žÒ±gÏ‹Åãñ›Íf±XG(âp8>Ÿ/ a~€Ãáx<�@LL û€´@Œ3¸\.‹Å:sæLPPLÁáp��Ø$ØT�ž?�Àãñ<Åb±Ùl>ŸO ¾ôQ&5üÿ8~ü¸ššÚ±cǰ_7oÞ|çÎ�ÀòåËSSSÙlöÌ™3µµµuttÔÔÔÊËË…B¡‰‰‰ŠŠJww·šššŽŽRM1^m0q8‹ÅòööÖÖÖ...Æúↆ†jjj.êìèèpttßby “Ãápzzzzzz†\ >þ|�ÀÅ‹=<<‚‚‚²³³cbb^¾|©¯¯ïääôêÕ+˜SOOOVVVNN)%¯0ŒžÿÁãñæÍ›WPP°aÃ†ÆÆFÑœ¡ºº� ¬¬œ=¾Åò®­¤¥¥�BCCGxÊzwww[[Û€•S***eeex<Š\@ ã–Ý»w‡……ÁÏÿý7–þèÑ#›ººº/S,oaræÍ›wêÔ)øùÈ‘##¹dÕªUD"� ©©‰Ù˜¢¢"doÄøæàÁƒÁÁÁHïnrFΫW¯àäØõë×mllššš¸\®’’7øÂijj‚ñSCÂãñZZZ´µµ‘Éy3 EFFæåË—QQQ4MBB¢¾¾^RRráÂ…!66iøBhii)//‡Ÿµµµ'L˜PPPPWW÷×_µ¶¶ÈŒÃá ;;;³³³>L¥R¿h“#++kii©¥¥…¥¨ªªZZZª¨¨ˆ‹‹[ZZÂÌÞ½{á~b‡š2eÊš5kÂÃÃáå7nÜPQQ133ëééA^51ŽÑÔÔ´´´ŒŒŒŒŒŒ„)G={ö,�à?þ¸|ùò?þØÜÜL ÌÍÍét:‡OJJòóóßö�€#‘H,«··—Á`ÄÄÄ"ù°ÈÈÈœ9sfÉ’%HÄÛ5O8œœœœ@  ÑhŸ¾{.&&--Íår?ù.ÎåååOž<±°°˜<yò؉²²²t:] „‡‡ïß¿ 81J “ƒ@ ˆÑ,"Œ0X@ ÉA|Dp8œžžž””@&ñqáóùÞÞÞ\.‰x°ÉÈä ÞÌç{J9�ƒÁ€û¡}BÚÛÛ‘ÉA ˆqN/((ÈÏÏG¢@&@ >"€Á`0 xÐÀ'GEE™·&G\\ÜÉÉ ‰â}@ërL@ ÉA ™@ “ƒ@ ˆ/±öÑ‘@BxØl¶@ @r@ ÉA¼2™Œ„ðžäääP(´OLâÍ…B&“‰äðn<þ¼°°ÐÓÓ™™Ĉàp8HïF}}=ƒÁ@r@ Æ(|�@ Èä ™@ ÉA þ]]]±±±yyy_fñ‰D¢´´4‰DBš€#Œ4| 999,, ûºhÑ¢o¿ýv„×.[¶¬±±ñêÕ«ÊÊÊHâˆQ£»»;ëv¬XÜ‹6mÅ<�lmmßxIXXXrrò¯¿þêàà0옘‹Å#‘H# `Yµj•èùcQQQÒÒÒH‘£mr?~¼aÓíÛ·�nÞ¼ùûï¿ãp¸ÐÐБ\þüùóÊÊJt3b4éééÉŒzH¾[D¤±½ì¶“Gbuª««³³³{zzƇ½ëgù|>™L‰ÕyñâÅóçÏÿý÷_MMÍyóæÍœ9óÑ£Ghaâ2"ÇZooo}}½¢¢¢µµµµµµ††F[[[kk+�àĉÎÿ#>>�°uëVggçÜÜÜ•+WÂôúúz�ÀܹsÇAMF|Ðh´´ÈâÑ…D�€çðÉÏ[ZÿMùyŽëׯwvv... uvvnll„é3g΄Zíî³³ó‚ CCC‹‹‹±±cÇxUtt4–xá˜xäÈ,199&þ÷¿ÿÅaÅyO{� …l6ÇÐÃfjjjmmW__ïááÁçóÙl6öTAAA0[ii)–øã?�âââœ<xóæMggçsçÎ]¸pËs÷î]xáöíÛ±Äââb˜¸páB,.bãp8XÊ‚ VA£//¯}ûö8pàÙ³gÁÁÁß}÷¯¯¯‚‚©S§>¼|ùòE‹íÝ»wíÚµ'Ožljj*--]ºtiWW‹ÅºvíÚöíÛëêêŽ;&##ƒ$ŽøØôõõ%ߺ+}û¹Xÿÿß©ÇsùâÏ›_]IÊÀÆÆæÒÐÐPZZºhÑ¢#GŽlß¾}öìÙ±±±¡¡¡999ÉÉÉ’’’öööS§N½sçNiiieeåìÙ³jjj²³³ÕÕÕÏž=›––¶sçNçää´eËOOÏ­[·^ºt),, Ç÷õõ;vlõêÕ ,عsçêÕ«Ïž={ëÖ­ÈÈÈ'NX[[/^¼Øßß?&&FSSóíª´˜‘Hd2™B¡K„Vg„cˆ¡¡!/++ãóùÎÎÎmmm)))­­­AAAûöí VVV¾páBffæöíÛq8œ­­miiéË—/I$RGGÇ��K–,ùæ›o~ÿý÷Í›7„ŒŒŒË—/ïÛ·ÏÕÕõ»ï¾[¼xñ­[·vïÞœœE¡P¼¼¼\]]³²²œœœZ[[SSSÛÛÛýýý,X‰Ôû‹09RRRß|óÍœ9s¨Tjxxø•+W–-[¶nݺÎÎΞžeee}}}YYÙÖÖV:/innþûï¿mllÔÕÕ‰D"�`âĉIñQéïïO¸-UD` täâ¹ñ¢æ–+‰8nÒ¤I#ù·¸»»“Éäêêj.—[__Ïçóuuu¥¥¥ q8ÌÆãñp8\QQQIIÉ¢E‹&Nœ¨¯¯_UUÕßßßÚÚêé陘˜(--­   ¨¨ØÕÕÕÓÓÓÝÝÝÛÛ{öìY##£'N0 ee刈&“©©©©¯¯O"‘*++y<ÞÛÚ‰4ÀÞˆZqqñ‘[ŒššYYY}}} .—ÛÐÐÀápššš´´´ôõõ555=<<$$$’’’àsÉ’%?þøãùóç?®¤¤¤¯¯/''×ÞÞÞ××·iÓ¦U«V)++KHHˆ‹‹755±ÙìÆÆF.—ûý÷ß§¦¦fff 11±šš}}}IIIxS¤Þ_ŠÉ�HJJJJJ®\¹R(þúë¯Äã_ç”»téÒÌ™3¡±A F</ˆòÔBkè–ÏHµÈ絈;:²X¬7þ¡ššÚpÎ(mmm�@WW�@SSóÑ£GÊÊÊðkvv¶©©)›ÍÆzl<ؽ{7��ë“mݺuÍš5{öìY¿~½„„ÄÑ£Gg̘ £„·-~kkkEEÅÔ©SÛÌê°X¬ÜÜ\]]Ý·;šššòùüÁ?‰‹‹Ci@-Z&###''�?{ö,Fƒ¿*))íÙ³çÑ£G˜ô��wïÞåñxÓ¦Msvv&¹¹¹0N§wSÄx69qqq«W¯ž?þÁƒ׬YÃçó÷ïßßßßÿšK‘½AŒ2�H‹{žÛöxéoÃåÑñs6Z6³ iccsõêUø™D"EEEmܸqþüù{öì9sæÌÁƒ�222222‡æóùT*uùòå/^„—œ9sÆÎÎ~–——ùc¨¨¨°X¬Ç»¹¹ —'77WBBb„ o[Fii錌 ¬¼ØäÖ`$$$D]è«V­úþûï1ë»nݺ›7ož:uÊÓÓsñâÅÏž=�@éeddL™2åÕ«Weee0¿èM‘†‡~áH2q8œ®®.hcÈd²¤¤ä»ÝÌÚÚº¯¯ ñ­ŽP ¦£2õïCMf9™nYÄò‡Œmmm“á¼[ŠŠŠyyyÖÖÖÛ¶mc³ÙýýýâââŠŠŠØI¿ýö›¶¶öíÛ·Oœ81oÞ<:Ž…tÊÊÊ***.Z´ÈÚÚº©©é­y&LÐÖÖNOO2C~~¾¸¸¸±±ñHšoVQQ3ãp8EEE6›mmm š3%%E[[{ÕªUÃY EEÅððpkkë{÷îÑét‡###£¨¨(&öÿº¼Ó¦MÓÖÖîïïÏÏÏ———ïîî†éð¦\.×ÚÚÚßß©÷—2Ê™5kÖ™3gV¯^ §ïø|þÚµk·lÙ�`±X?ýôÓÏ?ÿÌãñN:5gΜ7n ¸<##ÃÞÞÞÚÚº¨¨E >6|@l¢ªÛ¥ŸÒ¾Ù'š®éë`þÓR&›õÎÿ\TTdll¬¯¯¿VWWcŽ2ˆ••ÕƒfÏž­¦¦&f̘qôèQ<Ïd2·lÙò÷߯Y³fË–-û÷ïß½{÷¢E‹6lذiÓ&wáÂ…3føøøÌ›7oΜ98ŽË妧§‹:¬F‡ÓÑÑ …...¢?‰DSSSl j8à”——«¨¨��êëëuttÔÔÔ„B¡††F||¼˜˜XllìÌ™3aI½½½?%ú?ëׯg2™¿ýö[XXÇ;xðàüùóX,Ö’%Kðx<•JÝ»w¯Obbâ7ß|cccƒÃá8NMM ‰DjllÔÖÖ†7¥P(ЇøÜÁ‘H$‹ÕÛÛË`0bbb‘P>,òòòB¡°··‰â݈onnž5klþFîìâÖ´¦/? äñqxœÆô)V{¿ýrv¤®©©yõê•““‡ …EEEx<ÞÒÒ©b”‘••¥Óé <<|ÿþýhÃÄ8ëðù$}uç3[Ä$Å¢:(�� �IDAT5¼í¿({�ÐÓÓSUU}öì—Ë…k_½AŒÐy9ˆq Ç7ÖôK?Åår¿Àw „B!•J555aP8Lñ^VçKvi"5@Œc @ Èä b|k£P(Ä– Þ´9Lâ-ìMKKKtt4@&ñÑ;é)))oµ¦1´LâÍ0ŒY³f!9  @ 29@&@ dr1vAá᎕D ÇH#‡Íf¿Õ±:MMMqqq$drÆ'/^¼@r  ERRòÃÙ9îéïïÏÍÍÕÓÓC¢!jjjHÈäŒ[ARR’‘‘ÅtQLLNNîÏœý’‘••õòòBÛ4¼‘ÆÆFuuu8˜FÒ@&gÜB ‘Þ8$“ÉL&‰âÝz6Hto$??ßÉÉI^^‰âSÂ1–F9wîܱ°°ðóóÃ333ÓÓÓ===íííßáÆ\.÷È‘#¢)jjjÿùÏƱ¬étú©S§°¯šššK–,�TWWGFF�,--gΜ ÍÊÊzüø1�@TÂ÷ïß/))�éêê"õLooïÙ³gEStuuƒ‚‚>ÈŸŸ:uŠN§¯_¿~,‡„TVVÞ¾}ÛÜÜÛóâéÓ§©©©ðó´iÓììì��<À¦.\¨££ƒ”g$Ðh´ÚÚÚ×dÐÔÔTVVî×K—.µµµ}÷Ýwp¤Áb±6mÚtøðaqqñµk׊fnii¹|ù²hŠèkÏ&§¼¼<,,lñâÅ¢&'--íÀ’’’ïlr¤¤¤Ö¯_�èèèøóÏ?AhhèxUÖ¾¾¾Ó§O¯Y³æÿ 0ñx�@MMÍÍ›7ábEEEB¡ÐÏÏ/+++%%ELL �˜˜�°··¿wï^ii)¼êúõë!!!¨™LOOOXX˜ªªêŠ+DåüA8~üø«W¯V¯^=6MNmmíÕ«W+++£££.\Û¦gÏžíß¿_ ¸»»'%%eeeýôÓO---aaa&&&¦¦¦×¯_¯ªªÚµk—¶¶6ÒŸ‘˜œâä'Òµ=CþªêlA˜0a¸kÿú믴·····ïÚµKVVöðáÃ4mýúõaaarrrLNsssXXØÄ‰aß´´´4::Z(Ξ={œ›HAAÁÝ»wýýý¡½INNÆ~ºwï^NNübll|éÒ¥ÚÚÚï¾ûNSSóøñã›6m’••ðŸRRR›7o�”••={öêÕ«¡¡¡555ÿý7Ì`mm=þügÏž=xðÀÕÕÕÇÇ')))55uæÌ™ŽŽŽÑÑÑyyyAAAW®\©¬¬„W­Zµ NŽ5äää`y1êêêŠŠŠ®]»�¸zõjBB‚ŸŸ_NN—Ëݶm�`×®]ùùùööö±±±žžž�€ ¸¹¹!“3***¢r.//¿zõ*ü<yòä9sædddÄÇÇ{zzzxxÄÆÆ>yòÄßß¿¡¡¡  `áÂ…ùùù¡¡¡'N�œ<y²­­mÆ c½2‹‰ÉÈÈHHHˆ&æææ>~üxË–-›7oîë니ˆ˜={v~~~IIÉæÍ›çÍ›÷ìÙ³[·n…††"“3BH4¶|Që?z¹«««rùï¿ÿª««=ztÆ ƒÛÃ!ÑÑÑÊ|ûöí¨¨¨¸¸¸Ù³ggee=|øfðññquu½ÿ~vvöüùó­­­¯_¿^ZZúŸÿüGOOïüùóMMMkÖ¬QUU ÇÉݽ{÷윷¸eiiiRRüœ““óôéSÌÞ8p ¹¹™B¡$''ïÙ³§¢¢"***""¢­­ �pùò刈ˆþþþöÔvïÞG¡PÚÛÛÿý÷¨¨¨çÏŸGDDddd��ž<yQPP��xôèQDDDeeååË—<È`0(ÊíÛ·wíÚo=ÖèêêÚ¾}ûöíÛOœ8ªîèPQQ±gÏžääd …ÒÜÜ|àÀ{÷îåççGDD@NOOˆˆ(..NHHˆˆˆØ»wo[[ÛÇwïÞÝÐÐpâĉððp"‘;¤c¹¤ÚÚÚk×®ý¬»Àã˜3gÎ455…„„¬]»VNN.,,ŒN§¿Û_eeeýöÛo ¥¸¸xß¾})))eee�€û÷ïGDD444��nÞ¼ÑÕÕuèС#GŽÈÈÈP(”3gÎìØ±c¬r`Q£¢¢”””bbbD{”Ë–-sss344ÌÊÊŠŽŽ^¾|ùªU«šššŽ=ª¬¬ÜÖÖöÓO?ÉÉÉ ékÚ´iô‡hjj®]»¶¥¥åþýû>>>+W®¼}ûöµk×RRRV­Z5wîÜäädѸ¯ÈÈÈgÏž…„„Lš4i×®] MMM«V­ÒÔÔlooƒ®99¹={öÀÏL&óøñãÿýïQUü´´´@½200022Š;wîÊ•+ÿý÷_*•š‘‘¡¥¥5ܵiiiwïÞýᇨTjWW×¢E‹òòò «óóbêÔ©³gÏNHHèììÌÎΆ‰ .,--½|ùrzzzii)R˜Q ::Z´|åʕݻwäÂÊÊJ¨Ìµµµvvv .,))ÉÈÈX»víÊ•+»ºº<XTT´`Á‚âââ«W¯cמ<y²¾¾~ãÆêêê×®]£Óé555‡’””äóùcÝä888èééeeeéèè(((øùùAÃãèèXWW�ÈÏχ™gΜ‰Çã·nÝÚÐаsçÎï¿ÿ~ÈõD"ÑÆÆ¦½½ý¯¿þ²²²š3gNffæàl¦¦¦І%fffVTTlÚ´IWWwÅŠ¾¾¾'NœØ¾}»ªªê?þ8ã %%%¿ýö[ÌKùã?"“ó‘°±±ï´èÏËËkHSppðîÝ»Çø@g0æææÛ¶mƒ³¡¡áùóç��WW×½{÷Âið¬¬,¤0£Æ:::F~‰ŒŒŒMQQQrrrpp°««kEEÅàlNNNFFF—/_nˆ‰‰iooŸ;w®¼¼üÏ?ÿÜ××÷ÓO?ñù|‰tôèѱnrôôôNœ8!--íééI&“¡É¹qãÆ¡C‡\]]KJJàh�PXXG޹¹¹,KZZzðŠ‹‹õÕWt:‡ÃEDD8p`êÔ©ïP www�€––Ö–-[âããÛÚÚŽ=J¡PÆ”¶õôô<xpß¾}¨â}läåå¿úê+øÆ_|ɘ›››››Ãþò£G`¢‹‹‹‹‹ �àîÝ»0 ññ8räHUUÕöíÛáì ››Û¶mÛ6oÞ<’¥Têêê_}õÕË—/�ñññÿüóÏ»=Ãܹs�²²²«V­b0g@lçèðvÓGîîŽjjjp’ŸŸ_]]mooŒuÿøãsçÎýðÃ/^,((X³fMww÷p+--íëëÛÝÝýšÖaúôéAAAwïÞ%‰/^looONN urr�?~<44ÎéééÅÇÇÁÞ(“É|ðàª~c *•7’œ[¶léééùì zûömÑÄ‹/†††b~6ÄÇ&%%¥££ÃÛÛ;øHHHDGG|ÃMMM''§úúú×¼µÐÐPggçÓ§O»¸¸\¼x1&&¦¼¼|çÎ0ÎhÛ¶m¡¡¡îîîçÎ#“ÉT*u¬r��'N´²²ª¯¯733»wïLüú믫ªªÎ;ãææÖØØøÇTWWwvvzxxØØØìß¿?>>žÅbä&&&Û·oÿóÏ?—,YÒÒÒâêê £]õõõÍÍÍoݺ…Çãž>}Z[[»qãFhäœ###7nܨ¤¤ÔÕÕµÿ~MMͱ¦v ;vì€ñŽJJJГkiiééé õôô çÍÏÏ/22&ÚÚÚNŸ>�ðý÷ß߸q¶~~~¦¦¦¨&++«7^»vmÉ’%MMMÓ¦Mûúë¯%$$ž?dddTUU5Üå¿ýöÛêÕ«7oÞB¥RG¨ÆcCCCqqñýû÷S©Ô²²²¯¿þzÚ´i½½½QQQ?þø#…B)((ؾ}»è�bŒuøþýûUUU‹-òõõ�ØØØhkk߸qcݺu³fÍúûï¿;;;ÝÝÝá<º¯¯ïòåË—/_N"‘x<Þ¥K—>ÉÃãH$‹Åêííe0111¢ÃŒ¶¶¶ÂÂB ssóÆÆF&“iddTSSS]]mdd¤££SZZ ÷²µ²²jiiioo‡:88ÈÊÊfffö÷÷O:•L&cÿÉçó“’’Èd2ô¤õ÷÷gffÊÉÉM™2¥««+77f£P(ðs]]]ee¥®®nyyyCCƒ™™fZòóó1©£££ŒŒÌÑ™3gÎ@ûÁd2ÓÓÓáðÖÁÁfhoo‡xPÂ0±¶¶¶ƒPÂ0±¸¸¸¥¥Ú!%%¥qV‘° oÞg[O(aÑHLÂ��---h­¡„ 9ìEõôô477[[[«ªªæååuvvN™2ENNîÉ“'t:ÝÕÕ5;;›Íf{yy„±#·®®®gÏžB?6¬­ƒ+ülll<aÂQ]�ØÙÙ)**~ uBBÜðæ÷XkjjzòW¤jrÝ¿š¯Ö ö¬À¹¹¹]]]°=„)iiiX÷eÚ´i‰‰‰D"ÑÃÃCôªÞÞÞgÏž)**ÂÕ»­­­EEEšššfff åååX¯úë°×:X‡ßÔÛۇÂÌeeeétº@ ß¿ÿˆLâC™ÄÇ69_ Lâc›œò¼¢©&“†üUZ[ È£­Ð_grжž1RTTTd=\%†ò ý¼_ 291RÈd2™LFg “3¦ÁápcgniÌòI¶ß7tvvŽ0ôîK¦¯¯ ™œñß’.^¼xLM8#ÆJJJh«›‘ ##ƒæZÉç+ðÙ­ZÿT…B$„·BNNnêÔ© ãsÜgôa2™HÇÉÏ$Äǃ@ HJJ"5C| ï9@ ÉA Äø9Ö>:CžÚ€x[ètú§Ún}ŒC †Ü3ñ¶`Ç—!ÉùŒ]%Æ1B¡022rÒ¤I¯9RéÂ{êØÙ³gƒ‚‚Pd)29ãD¡Qꉇ[Ÿ!Q¼‡6¼yg®]»†"§G4—ƒ@ drL@ Èä bì2¢ð:ŽæQPP jkkëííUWWG›W~êêêœhkhhˆ}æñxµµµ$ ;ê £¯¯ïÕ«W²²²jjj===ØÙzÊÊÊ �€ÖÖVl« )))�@cc#vГ®®.Üg¥ªª î#‚Çãõõõ?•(¸\n]]öUBBBKKK´°¢™•””°£É ()" ENÕ%ƒñòåKÑÌrrrªªªØ×ŽŽŽîînyyyQuÒÔÔ”””�444`S÷ƒÕ‰@ èéé�àIzƒ_ë(ƒÃá^( _³¡,ìĉ‰D"� ººZ TUU WqD%,##£®®>8O{{{OOªªêØ_’1"““œœ¼téRyyyxggg§··÷®]» bµ´´lß¾=::úçŸ^¶lvìbÔ ªªª266†Õµ¤¤$-- 0ÊãñRSSuuuoݺ5@§–-[¶téÒÝ»w=zôÚµkjjjmmmAAA7nd³Ù[·n-,,”““khhؽ{÷¢E‹ÚÚÚ–,YÂápÄÅÅ+++¯_¿îææVYYéééi`` ššš>ÕÁÆÍÍÍS¦L×××g0 ýõlccc¿ûî; ˜yÙ²e¡¡¡P‡·mÛ–››+//ßØØ¸sçÎÅ‹£Å.l6{Ê”)bbbÆÆÆ‡ÃáDFFB]ÊÉÉ™;w®ŒŒ <l�°yófìÚ“'O=zôàÁƒ~~~›6m*..†êôË/¿µ¶¶.^¼X É䊊 *•êââRQQ1uêTccc@ÐÜܧ««›˜˜øí·ßÂ×*//ñâÅÁ]¨Ñh1ÅÄ^³½“Éäp8Ãí‰^SS³p᪪ª›7ozxx‰D///ÖÚÚ Ïîí-aöæÖ­[;wîÔÑÑ¡Ñhfffááá˜c9räôéÓ_ýõøq¬Íœ93=====ý‡~¸råÊ_ýÓ;–——gccsüøñäädT??·o߆/ˆD"yzzÂÄÎÎÎqqñeË– wíãÇÓÓÓ·nÝšžž¾téÒS§NQ©ÔC‡=xð`×®]ééénnn›7oÎÍÍ]½zuiié¥K—ÒÓÓ544æÏŸßÓÓãëëËf³SSSûúúæÌ™óiE¡¯¯ŸžžþÏ?ÿÐh´+VÔÔÔ`?¤ÿho^¾|¹cÇŽ‚‚‚ǧ§§óÍ7×®]+++C5�yyùôôô;wîHJJ.\¸;�àææ†IUÔÞˆríÚµÖÖÖˆˆˆôôt''§ 6®\¹²¢¢âŸþIOOWWWŸ;w.Fóññáóùéééqqq½½½óæÍkii ÑÓÓKOO?sæL~~þÆ?•x<^ß0dee½FsV¬X!&&fccóõ×_c…×À`0¨Tê®]»¾úê«ôôôˆˆˆ¶¶¶ÿý·££#ÿ ¸×××çççÃñzUUU~~~YY‹Å*))—ðùüÂÂÂüüüÂÂBXœüüü/^°X¬üü|ìµÒh4ì. £:Êy ¯^½Ú°aChhèwß}WYYÙÝÝ }2ˆOT&55µ¤¤¤ÒÒÒ¥K—¾xñŽ~�Ûßæææ &¨©©‰¶)Ÿ#áááþþþ;wî¼zõêpÙNŸ>}çΣGΘ1�°wï^¤9¯ACCãÒ¥K«W¯NLLù…›6mÚ´i� ²²²§§ÇÄÄä‹ò×””ô÷÷_¸pÁÂÂÂÆÆ&??_EEåõ—”––®[·ÎÝÝ=,, �àáááááÑÞÞ~ìØ1*•ª££óòåK//¯mÛ¶a—„……ݸqãÊ•+³fÍÚ²eKJJJBB¦M›Ö¬Ysçή®®¼¼¼k×®=z”Ãá<xð@WW×ËËK]]ýСC¿ÿþ;›Í¾xñ¢––Ö•+W:dddÔÑÑ¡¯¯àÀ]]ÝQå´¶¶¦¥¥¥¥¥ÕÖÖjkkÃqôùó磣£±<ûöíËÊÊBÕò“ðìÙ3ø‚‹‹ � ¯¯oñâÅX†ªªª 6¼æšššöïߟ™™¹{÷nhÆ---iÿãöݾp:;;1©ŠÎú ¦¬¬lݺuýýý§OŸ¶´´ürD´iÓ&Ñ>ÜW_}õnËÃãââNœ8ûŸÿüçŸþ¹yóæ¯úþûïûí·ØØX…ÀÀÀ7n<|øÃá,X°�fèééyðàÁéÓ§+**6nÜXXXøÓO?9räðáÃL&óáÇ£=Ê)--=vìXcccEEņ BBB°ŸÊËË ñ£Ì… Èdrjj*Ç‹ŠŠÂÒY,Vbbbccã¬|òäÉ®]»æÏŸ?^¥ôüùócÇŽÁÏÁÁÁØ â}¨©©Á¤:}útƒázú[·n¥ÓéÇŽ›4iÒ—Ù/lmme2™cíÁÔÔÔN:õâÅ øUAAaÚ´iíííplúûï¿›ššŽ¶Éñðð8uêT||üîÝ»kjjªªªA]]©©i}}ý… ¤¤¤ÔÕÕóòòìííÑvX£Ï¹sç(Ê·ß~çã㓘˜H&“íìì.\¸��pvvnoo�¨¨¨ØÙÙ‰Ú›C‡effîØ±ëøŒK¦OŸŽ´åÃbooÿï¿ÿb_ëëëKKKõôôŒŒŒ°Äâââ;vô÷÷>|XT÷¾KÓÝÝíää”��°±±IIIILLäñxcó-,,¨Tjnnî–-[ÝÝÝ÷íÛ7¤Oþ#š¬ÆVVVîܹÓÄÄ„ËåÞ¿ÿÀßÿ=üõ›o¾9t裣ã´iÓP=ü$üõ×_êêêK—.­­­]±b…ššÚµk×àO………ÐÕ6}úô7n`WÅÇÇ_¾|yýúõãF]]]™™™ªªªS¦LyM6sss]]ÝÂÂÂÆÆFmmíììì––''§7ºÚ¿Lúûû“’’dee§N:\žØØØmÛ¶mÚ´içÎXâùóçÓÒÒþüóO{{û/Mhûö탮 [[[LëV®\ùú«\]]ÛÛÛ³²²›››srr FrǬ¬¬‘D( GGGGff¦ººúï¿ÿ¾}ûöÔÔÔ?ÿüóƒôÕжž_***¦¦¦¯^½¢R©ÙÙÙ:::vvv�PVVF¥Ra¶I“&ÙÚÚ&''?{ö Ç777»ººªªªzxxTTT$$$”••õ÷÷Ïš5‹L&üûï¿‘‘‘<H$~òˆµÞÞ^*•ZUUuñâÅÕ«W¯[·NÔ„•ÑÌÌÌÌÌ ÚàƒÂàéÓ§%$$ É�›Í¦R©íííaaaË—/ÿù矱Ÿš››1©êééXYYAu*++³¶¶Ö××þü9�àéÓ§X„±»»»§§geee||ü‹/ ÆìÙ³I$R@@ÀµkרT*‹Å"“ɳfÍ’’’š1cFqq1•J­®®VQQqss÷×ÓÓ ß¼yó–-[Ö­[—““óðáÃ)S¦ØÚÚVUUQ©T dllÜÚÚ /™2eJfffff¦P(|O“sáÂöÃ?ØØØtvvbÆò=!„;w²Ùl.—[YYiff68“Éär¹NNNp7ß¾¾>111Ø�IJJN:uâĉ؃ª¨¨xyy¡êŠ!..«ëǻūW¯ôôô|}}á½-,,|}}›››'Mšäíí ³q¹ÜÞÞ^__ßU«VÕÕÕÕÕÕq8œ   ¥K—Òét</!!Q÷?´µµýýý¥¥¥kkkëêêTTTvìØajjêêêÊf³a¢¾¾þáÇåääfΜÙÜÜ\SSÓØØhooèСXºêêê¾¾>##£‘,Ïäñx:::uuu4Í×׳7 ƒÏçËÊÊbeTUU…kf---edd`¡”••·oßþA|£'“É�ö>B¡ðåË—ÆÆÆuuummmîîa±X CEE“ª´´´¿¿¿¶¶6”§„„ĪU«¼¼¼º»»ååå9–ÓÆÆfîܹ, æ400—‘‘ñóó{ùòeMMMSSÓ”)SþøãIII77·úúúºººÞÞÞ™3g®_¿þ°¸¸˜Ïç[[[·¤æÿ´˜€•×¢¦—H$nýÚÛÛ544|||äå屜†††––––––°¼“&Mš>}ú€ •””lmm±Ú¸k×.===(1"‘¸|ùò™3göôôHKK»»»ûûû“ÉäÚÚÚeË–©¨¨P(6›­££3cÆ ))©ææf###???ÐØØhmmíííÝÚÚjkkëééÉår{zz&Ožìïïomm ïËårƒƒƒ¿úê«w“-™Læp8B¡ðÉ“'iii8‰Äb±z{{ FLLÌxò«ŒäååÑáï<¼`Ö¬Y¨3\#(##ƒ/xàá_ýõÏË!‰§¢¢bÈ_ëëëµ´´†ì¸±ÈÊÊÒét@¾ÿ~äXûœHJJˆíÚ‚@¼'·nÝêîîMÁáp+V¬@’ƒÑÓÓ3ä¯rrr¨2¾dr>':;;Ç:7ÆG Þ–––s�èÈQQø|¾”””ƒƒ29㟠     $ÄÇcíÚµHˆ:¼�@ Èä b|k£ŸÏÏÎÎFrx7°V¯¡¯¯/''Éáݳ»� “ƒxkAjj*¶yñ1¬rFFÆë÷ÓD Éù"`2™ÒÒÒNNNHï:pö5}§¢¢‚Ö-½'o\Š@&ç3€Ëå~ª#2_B¡@ C|v‰�@ Èä ™@ Þžÿ3—ƒÃᤥ¥‘PñA°aÒÿ19L&óÎ;HFøP¸¹¹‘Éä!L@ÐÖÖFB „(d2YRRò.”’’"‘HCrðx¼‚‚.@ D‘èèèxÛ%ížžž ž—3„ɰX,´Œ@ ��999èýb±XòòòƒÌÍËËSUUÕÒÒ<¾!‰‡09B¡Á` A#BBBû,..>À&...-----=ØC&##Óßß? I#âÁãñöööÍÍÍ/_¾I~´á @ Þqqq"‘(..>yòd1±Y“·39zzz¶¶¶Ø×âââ²²2Ñ NNNõõõÍÍÍC^îïïÿðáC.—‹Ãá,X��`³Ù÷î݃¿ÊËË{{{�ÕŠL�� �IDATÚÚÚ?~ uttìíí�•••………0ÑÊÊÊÈÈ�››[[[û>"Ãn innÎÌ̲°�€ÂÂÂÊÊJÑWW×ÊÊÊÖÖV�€···¼¼<� &&óL.X°�‡Ãñx<,ú\FFfÆŒ�€ÎÎÎääd˜¨¥¥åèè�¨­­ÍÍÍùóO›6Mt<{ïÞ=6›}%‘HÓ§O¿ÿþ×jjjjii=}ú� ¯¯occ�(--Åfmmmõôô��YYYMMM0ÑÓÓSII �×××çÎK$…Baddä{*±¾¾>ö5##£¥¥~Æ$ŒqçÎÑmç%$$<<<>|�PPP˜6m� µµ5-- f˜8qâäÉ“�EEE0ÑÚÚÚÐÐ�]__ÝÜÜÔÔÔ��‰‰‰ÝÝÝïY(L—ÊËËŸ?u˜Á` ž4uww/..îììÄRfÍšõèÑ£¯Õßß~¦Ñhñññ𳪪êÔ©Sá熆†gÏžB££ªªjdd”žžþ6¸ºººòòòùùùcóñ¦NZRRÒÑÑ!ªK‰‰‰,ëC݇ñX,‡C&“ÓÓÓõôô444>¤É!yyy𫹹¹±±qyy9üêèèØÒÒb`` ^½z5ør,T.006ÁâââsæÌ¹w¬¬ƒƒCtt4Vs?~<a ˜h```eeUTTdiiÉçóa¢­­­@ Àš‰wƒÁHHH€_)г³3´:bbb ¢úÄçó\N$áî³ÞÞÞ………===��__ß„„‹µ`Á‚û÷ï "‘pçÎ)))777øðJJJžžžÉÉÉ'N„‰ººº¶¶¶˜„߉DJMM…÷…*õàÁ.— Ÿ¶V³gÏÒêàñx8¹§§§§¨¨ÀÄÄÄÌ̬¤¤ÄÆÆ†N§ÃD¡PøòåKÒÒRØ úøø<~ü˜N§Ï;7!!ëI¼§Õ!‰ÏŸ?¯©©_4ê$)%%¥··Ë<à˜Ãÿåååíííáë©©¹ºº¦§§ëè訫«ÃDCCCKKËçÏŸ[YYq¹\˜hgg' ÜÜÜjkk³²²��^^^YYY¢7}[&Nœ¨¬¬ oalllaaQ\\,&&foo/ «««EÛ--­’’Ñ6"--mæÌ™^+ü7�€¬¬ìôéÓãããUTTÌÍͱô &ØÛÛÂ)Mx<^4ö‹‚@ ž;H¤{cØ7%..N&“±îµ££ãH¶â~kÇš@ €ª ]ô³@ Àãño¼qTTl¾ Žáp8�ÿ™ÏçÿÅáp8&Âír¡Šóù|˜ˆÃáÞ¿q¡Pˆ•¨±±Ç;99=yòdpa_CRR’P( …°Q€ n‰D"—Ë…ÑP5q8œ˜˜VLXv(±Å9\.{È@LLŒÇã½±VÔÖÖÖÕÕaQŒP¤ð109ɉ‰a2Áž“H$òx<hr>H ÄÞ/� --ÍÃÃC ´··(ìkèíí}ôè,‘@ À䌩öüPë`"¦ºbbbØ3„˧ߖúúú††ø0¢ï—@ Ð^LsD 0Çಀz?wuu=zôh@ �ÔÔÔ¼§àm™0a‚¦¦fkk«’’Rvv¶©©)‘HĆ’“'O†CÉÌÌL¬8mÚ4UUÕØØX''§´´4lÐü©&<ïÖ­[ou¡™™Ô.—[ZZjooßÙÙ‰u›<<<( � >>¿Î;WRR’J¥Î›7ïÖ­[°é5‚‚‚"##oÞ¼I&“gΜ‰¹a¡¦¥¥%%%åõýu&“Éáp0íMNN611…ý`&g@+IÊÉÉ©¹¹¹¡¡¡±±ÑÓÓ“ÏçÞépm �€L&ûùùݾ}{ìô  ÙÀ 8¸°ÃilPp8ÜìÙ³ããã™Læ¨=³¨ÇÇ/X°àæÍ›B¡0!!ÁßßÿîÝ»¯/5‡333ÃápÐó3F€¬!СÁÌä%�¨««¿¾æŒŽRáp8"‘XPP�Ósrrõõõá@ÇÝݽ¬¬L´Ã1gΜÄÄDƒ Û>ŸÏãñ¢££CBBúûûïÝ»' ¡ÚÚÚŠ‹‹CBBšššÒÓÓ±ôQ‡Ãééé …Â®®®%K–”””p¹\8”´µµ¥Ñhׯ_�¸¸¸‚ÆÆÆiÓ¦·µµÍ˜1CQQñ“kZpppdd$ì ½•ÕÁápVVV………!!!ÙÙÙjjjB¡°¶¶vêÔ©©©©�€3f<}ú´»»{îܹ=b0 ,ø¨cÄá:åaáÂ…·nÝZ²d “ÉŒ;wntt4tÀ7E¡PÜÝÝá“7ÄÐÐyxx|øQŽôïãñø¢¢¢ÒÒRѶ²¼ñÈdò¬Y³¢¢¢ÆòÀÙÐÐPt^!??ó"ùg̘‘’’28.ð£2cÆ ltuëÖ-¬Ÿ »½XïþvËØØXLL ›0›øúúŠZ}*•:ÜÂ8NUUÕÌÌ,))é“?6‡322õÓB«�Gx<~p‡¦®Sl6ûêÕ«’’’ÁÁÁ4-..öá^½zuõêU--­àààúúú§OŸŽ²Õ©««ËÊÊ222*//ÏÏÏ·°°€éyyyx<ÓÆö866vöìÙcáÁ‘ÊÛº ÅÅÅÅÅÅÐ+^YY©¬¬ Ó?~L ”‡ÃÁ×M¥R/^üñ ååå%ªT¢Ãå7nÀi樨(III¨`===ñññ#i7àGtŠ&&&&ZXXÀyÐcr*++¡ƒØÜÜ¾è  …vvvvvvXû Å =êÒgao��ƒÏ“‡Î¥•™H$zzzfddŒ¾sàáÇp.gΜ9D"*‰Dóçχyèt:ôƈzöDí¡¡!™LÆ:àc–˜˜˜ÁÓ*$ Ýcªç6Æ‚½ÁãñRRRƒ§è²³³œœø|¾¶¶vMMMKK ÖLÃ÷]°i&‘H°S ËË`0®_¿.''7cÆŒ˜˜Xy<^SSÓõë×õôô¦L™§£>Fë<X‹^@°µµÕÕÕ…Õg”=~#' �~ Nƒ Ãut†haÅÄ\\\`<ú?‰‰‰mmmØ×yóæ½ñͪ¨¨ÀÁ rJqH$ÒaÓ¦Mãr¹pXÿaLÆ‹/&Mšdll\RRbgg×ÞÞ.ªß>>>\.·½½}úôéiii4MôÚ \½zu êt¯¿¾.Mž<¹­­ sÔb‚~öìÙûL2¿?÷îÝ ºsç—Ë?¾¨„a˜Üýû÷•””lll°p ˆžžžœœÜè8½-$‰Ç㽦·c®]»&š(//oggC×>9'NTPP€‘ƒár¹pzr@WœÅ‹_¿~@ ܼysÀÿ¨¨¨XYYÁy¬¬¬««ëƒF˜Ò¤I½½½ð™]]];<ÆÈ ÐÐu ›ÔáòP(ƒáÜMƒquuÅk3gÎÜv©ê+|S00xpÃápl6{À#--ÍÊÊ ç}0“3BX,–¸¸8|‘¢VQJJ ~L&S(r8˜ˆuÕa=„‰˜%€]u˜O}ÿN(ö0ð�y¬ñ%‰ØO°ïÃårÙl6@€é< cÇ23 ¸‰ƒ¤¤$œ1†q€ÍfÃlX7:è±b¾¦‡õþÀÉx/111LiÄÄ݇‡Åäp8˜œù|>ö1™°Ùl8xe2™D"†ÿ}3ƒ=Œ­­­h §„„„è‡>Lƒó‹:—E_+Çc³ÙÐtÁDå< ˜ðÏóýÝS¢ŠÅ‹ý”““ãââÒØØ8ÜÒ‚…B&“‰ý™L†Z$úf?¶"‰ª1‘H|cÐ-‡ÃÁ^tŠLÈNNNcáÌX[@˜:uêpK ÔÖáš]Ñ{û0˜Ç3 qqqçååõn~¼÷f±va;@‹v†â`Þ<&“9\­y;“ÃápDEÌf³aåa±XF 6R‰‰‰Ó¦Mƒ*åÀ–[ Ãd2ãããi4Zvv6Lloo‡aÊMMM8&VWW�JJJÌÍÍabAAAccã{ŠXLL {˜W¯^a½Q‡£ªª*ºj§¸¸¸ºº:??ßÖÖ¦geeÁq+ƒÁ€ë‡ qqq,ëîÝ»sæÌÃpØ%d0ðÚ®®.¸^¤¥¥+f]]Ý[ͦ0 ÑWK§Ó¡àßÃ61êêêzþü9¼WKK 4®\.WEE+iii)\¶bmm ³³³áâ˜ôôt7778Ù›””[üøùùÁu9¯ RyÅÐÐF7‰JÖÁÁA4óýû÷ù|þýû÷ád�‹ÅŠ‹‹ÃÚµ¯µ±±“sUUŒE~ñâ………LÌË˃˞<yâìì *¥¦¦£¿-\.WII {˜òòò²²2¬îÀÇÆì(Vq¼YøraÑbccýüü`b__tvtt”””`w]ÌðÁéëëÃjkGGGFF,&l†°Všs�� F‡ùsrr455aEpuuµ³³KIIqssûä­í½{÷`m…5\¶W¯^aZT__}Ѿ56› -=Ö$fee999Mš4 �ðøñãI“&õ÷÷ÇÇÇOŸ>]BB"&&&00ðãÑë:úûûaû� •J ÀºÜÛÛ›››‹­¬ªª²²²õè¼qˆyúôé¤I“äää†$A{ÕÛÛË`0îÝ»çééÉd2KJJ÷;8Îhb}p—_ |ò¸LâËDJJ =�³gÏNMMS•‡ÃÉÊÊHäñx$8n>»Ð_:ÊAÒo…’’’¾¾¾„„DSSÇ›<yrOOχwÐ5Çb±¤¥¥áNÒáááû÷ïz”#--=ØåÚÔÔ4ÆÃ™^‹‹Ë€-:>rŸ,ø€XXX¼zõ Ž ±öwì@"‘·ÃÍɽ“'O.--…­6¶Žû³@ TTTŒÐøûûž¥ÚäôööŽ|nðs!&&ÕsbŒðôéSSSS�@zzú(/-x#l6ûãµÉÉÉ0v >>~,qóôôôà:™‘ d¡ãîÍ&@ FÁê|±eÿ´Ë“ßgð'%%5’!iWW×ñxCŸ—3òˆ{@ŒcÄ p8œ‘l £ŠÞlrø|>ƒÁxÍòÑÏ11±úúz ÷Ü,kì@ Z[[edd‡0~¦àñx¸ªIFFf|”öÐéô±°›Ë,TKK‹ººúxjUUUÇT°ò{6ííí’’’dѶ„àƒ |ÈTYYYÑààÏ99¹“'Oz{{“#--}çÎ+++UUÕñQ"qqñœœ<off6>JD$[ZZ^¼xáîî>nì @¸qãÆxjdeeÿúë/qÓ{“’’ŠÕÕÕ|2ô»©±@ Àù�K4lD Ä( +_ÿó«W¯*++EjUUUÁ%fææææææ0177î†ëìì<Ø´>|øFÜÏ;v%•J…}[ì°©îîn¸‹šššhǰ¦¦¦§§;-­¸¸Xô@�@ZZ4ÅÞÞÞ#weôôôäääˆöÚáÉúúúØ–qyyyðX-GGÇ &ÀÄääd¸µþŒ3¬þ¡R©ØR/&“ Ï£ƒûba†çÑM˜0žÒ)--˜„_ÏǧN*:þ…[VH$lÛ¨ÞÞ^¸LREEÅÓÓsÀ?`¯ÕÌÌ Ûæ {­NNNÚÚÚ01)) îàëë+ºp!22rþüùp —Áb?)**b‹OáêW‹:_Orr²••<r÷î]èP ˆÙ××·ºQVVöòò‚‰MMMp}ñà×ZPP --m``�¿fff¡žžž***t8 �Ûú—ÇãÝ¿“ð멪ª¢ÓépI $??žø‡é0� %%.}>}ºèyt·oßö÷÷Çœ?˜„eee}}}abkk+ ú×ÖÖvrr}­+++�@vv6ÜèÌÅÅESSs¸gpÓtuu`Æ*ÄØØØÚÚZ4NN\TˆµXÅÌž=[RRrȺ3:P©T¸6Ûœ£³³311�@¡P°ö°¦¦îÁhòÿ±÷åñP®ïÿÏŒ™±/#kö¬9HQi“%)iCQmŽJëi9¥£NZœrZµ©¨„-"[‰È2';!²¯c†1óýãú}î×óLr:ŽŸ÷_Ü3ó<ÏýÜËuÝ×}Ýï·ŽŽúrFF†¤¤$pÊý눉‰122BBŽhà@¤2ñó!(þÉÈÈ …ú[šœ†††¨¨¨‚‚‚ââbôŠ?~üQVV¯›Ãáèé饥¥½|ùÆImmíòåËñVçùóç¯_¿†3¤d2ùþýû¬B&“ûúúlll€‚ øÄÅÅÙlöœ9sÊËËß½{'((ˆLNxxx\\ ¿¨©©©¨¨¼~ý:&&2Ü›››mmmñZ™¢££ãÉ“'UUUÑÑÑÈäTVV>~ü&‚ÂÂB‡"’¨'EFF‚(CMMÍòåË•””bccccca>jmmµ³³C»AAAîîî0l˜L惀Hx5-ZTWW÷èÑ#PV3f ‡Ã™6mZaaaZZZtt4Þ¨ó06MMM^^^ÑÑÑÈä<xð�©Ìõõõ­X±¢½½=88ÄKDEEÙl6(f¢Ù0<<5+†azzzééé‘‘‘\͇*koo/""ÚÝݽk×®eË–ÁôÔÞÞîááÆ­ŠŠÊüùókkk=zTÜùùùoby›ªªªóçÏ_½z™œÇ'&&B’KOOƒƒ¾Yƒ‚‚PMûúúÌÍÍ+++ÃÂÂP³²ÙlDA£ÑŽ?naa&çíÛ·¯^½jnnÆ0¬±±qÕªUÒÒÒÏž={ýú5 Tƒ±víZ2™Èd2ÿý÷/šœÒÒÒäää7oÞÈÈÈ ““™™ ´‰ÕÕÕË—/WVVŽ‹‹‹…£*---vvvbbbaaa cïÞ½‹-‚×ÛÓÓóàÁ°%‚‚‚l6ÛÒÒ²¾¾>44ß—¦OŸþúõë7n >,))©££óþýû—/_Â\_WW·bÅŠþJŽpÓ}ûöYXX ÂMŸ>}jkk MÿôéÓòòò·oß"““‘‘áíí=cÆ ø—B¡àMÎû÷¢PwZ±b…‚‚BVVÒE Ÿ6m29÷îÝÛ½{÷÷49>LNN‹µzõj¼q µ\ 6›={öìÒÒÒ'Ož€å.))áp8&LÈÌÌÌËË{øð¡­­í¿nrbbbjkk}||îܹƒæÃ½{÷š™™ÛD&“ñ&§­­-88´KÄÄÄØl6jÜïar:;;i4ZUU¾099¹®®îÂ… †:u*::ZOOïÑ£GÚÚÚ¿þú+†aNNNšššx““ŸŸ¿gÏØrÐÐÐX±b™LÞ½{7LÜíííçÏŸ·±±©©©¹ÿ>øh —/_ž3gN§ÑhŸ?ÖÖÖÆ?†µµõöíÛñ%ׯ__¿~½¹¹9†a¾¾¾ ã‹&‡ÉdÒh4˜\²²²h4š¿¿?†aþþþ¡¡¡x“¦¦¦vøða Ã6nܨ®®®¤¤tñâŽ{÷NŸ>Ü·¹sç‚ɹwïÞ_ý…2î;::Ξ= ë³¼¼<77·E‹µ··“ÉdxŸ¡¡¡Ó¦Mkhh ÑhÕÕÕCYâTVVröðð�:>mÚ´+VÔ××ûûûƒJNN>sæ Þä466ª©©íÞ½ðӧOGEEééé…††¢f½{÷nKK‹¢¢â… 8�¦bêÔ©æææ"""ÙÙÙpºÿ T*ê…PXXøæÍX~eddÅä”””äççsÚ8räHll,t*YYY¼Éijjº~ý:ù¤¦¦ž8qÂÜÜ<;;;33óöíÛЬ=“C£Ñ·¸}û¶µµõ’%KÀéž<y²´´t~~þ¾}û`Å£®®¾råJ2™L£Ñ†˜ØÙÔÔD£Ñ*++ñoUUU¦¦¦àÌmÚ´IMMMYYùòåË;vì€Â™3gΙ3GLL,''§µµÿzY,Vyy9¼Þ‚‚‚Í›7[ZZÇÄÄ€úÔãÇïÞ½ }rΜ9¿ÿþ;×Ü:qâÄ#GŽ`æàà ££Óßääææ¶´´àS•º»»<&§»»›F£á(€É“'s5:BHHˆ¾¾>t'GGG…;v BDD1ž|ÿSç{÷îýøñ#??gg§¾¾>ÞäTTT„……û}ãÆÙ³g¿ÿµÂùóç_¼x1a„ªª*†×~þQ\\üñãÇþžN:Å%莚¸­­ j”˜˜èëëû]MŽªªªO||¼ŸŸ*?~|UUÕÕ«Wá_ ¡â={ö`vÿþý¶¶6[[[|PâÆBBBÐ „¡¡¡¡¡aÿþ—’’×133ƒ@àéÓ§UUUöööCÙT3fŒONNê÷PëqãÆAÛÛÛ‘ËÆVVViiiàVÏŸ?Ö~ýõ×ììì»wïòø­††8×¥¥¥åååïš9sæÌ™3ÿøã¡Ð2zxx`¡9WWWh56›½nݺ/^¦þ¬¬¬ääd‡ƒ”`þ ÌÍÍñºA\8vì41×"^£””ÞW-++{ùò¥––L^_„‹‹ L¬øB‡pù7nÜøÅ‹¨ªªª««Ãóttt fŠŠøâöþÞ½{á»wïÚÙÙAÞ§OGGÇPN Nž<yòäÉׯ_Ç+¦ƒUƒ7¬¬¬ÌãlØD„„„<==aµñêÕ+x½òòò†††PGƒ&‹¬¬,(œ2e ¾eyF%^SœB¡¬_¿þ–••õññÉÌÌ<tèþWEEEp/}}ý¡Œ„3gÎ 7ñÀ¥¥¥ÿ¹Š%K–,Y²d×®]?ÂÃlÙ²:�W¹¿¿¿   @ؼy3¾\FFfÏž= =êîî^¼xñ¿°—Ã!!!‰[&‚‚‚Cç­¯¯§Óé222vg³Ù—.]jnn&‰þþþÎÎÎ’’’óæÍûóÏ?Qlg0L›6­§§ž¶FÀêDDDÈÊÊööö:::¢(üWA@@@PP.. Àµ13kÖ¬¬¬,xÈ¢¢"dºª««*ŠJ¥‚ÒÍ›7×­[‡ÏI´µµ…ßré¥~úô),,LUU•+Œ0ìü:999¨@@{0_DgggMM ¾Yãããkjj˜LæãÇ—/_>nÜ8›äädXCÐétýdýúõð õõõÁÁÁà3–••…††¶··777s8üJë« ##ƒ¤¹ToÅÄĬ¬¬à=þüyÀf…-(}266†-.€……Eaa!DK¸–ø·oß.//?tèÐ7LmŠ÷îÝÒ¥Kõõõ¿ö·íííþþþ$éçŸÆ0ŒŸŸ_DDêH¡PÀÕ××ÿüù3¾zõ D­æÌ™“ŸŸ¯öê†Àûà„¦¦¦©©)Ü‹N§s8<aŒ™™Y^^Þ€7 ²°°@~÷µk×\\\~9ÐÑÑ)--…%''ÅÿþàââÒÒÒ{—/_Þ¶m×`v%“ÉÿP`ðëLNFFFccãéÓ§au–˜˜ˆ§Oæ;w‚Sïìì &“yìØ±úúúyóæ9;;ËÈÈlÚ´éæÍ›à£ñ¸Ôܹs‘çîîž••&‡Á`888¨ªªÎŸ?ßÜܼ¿Éùã? Ì%$$ÔÿE£8Unn. ¬½xñÂÔÔ?ÁK€UÞ¹sX[ºtipppCCÃþýûñ³BBB»v킊_ê–••…„„¨««síãýxyyákCY€-Ÿ6mÚéÓ§ß¼yÍÚÕÕµxñâ &8;;ëêêŽ7ÎÉÉéÎ;°»Îu@ aaaXú`–íáá&‡Åb©¨¨¬Zµ*88øÉ“'ýMN||<â%Z²d W@ß”øÀš»»;> çææ†œ}Ô¬999(°),,7cÆŒY³fáMÎÊ•+CCCaà _Á[·nÕÖÖîÞ½¿¿ý7÷þýûÅ‹ãwž‡îøùùá{rYYÙÛ·oQ`-,,lÁ‚S¦L™2e |áĉIIIFFFÀº ‘èÆ!!!hæììŒOÓÀ¢OŸ>ÍåãñÓO?¡F÷óó‹ŽŽÆ›p™w™KpäêÕ«W®\›^¹r¥¹¹ùàÁƒ?þ)CCC‡Ýu(G# %;›ÍVPPè?*((;v kÖÖÖÿ²ÉnÞ¼¹lÙ2®NL$÷íÛ×ß7‡u:ìå vÁ7oÞP(”þÛ�vvvªªª<ž„ÍfƒÉù;‚`xx,Å.^¼¸dÉ’óçÏôuúôi¨¬¨¨(Tör0 +// ÒÒÒêŸ!ƒaØwc^ßÀù�� �IDATú믿êêêP‚¥¥%WÒ†a(ºÂC§ ³³Óßß¼o®@âªU«x< h3ÿÍê3Þ3ìå ø”””„„6›ýöíÛ÷ïßNž<ööÑZå_ݸq£¹¹ÙÍÍíʺÄÅÅ¥¥¥YXXôÃ_Dww÷ŸþI¥R!r™™™ÍÍÍýÑXYYá!ùþ*·Ã@AAAQQJ@íÅ‹ƒáá “âáëë»zõj‡Ãb±|||`‹ñÇÄĉaqsþüùÿ ËþŸþ¹iÓ¦O‰655=yòdˆêkrüýýMMMô›ðhhh ãáC!$&&ŠŠŠeç™ {öìù›GA£¢¢$%%¿¸°Û¹s'^aübƒqõêU® oEEEZZÚ/¿ü2X(ãûô¬¬¬ìììþ&§?îÞ½kff†²ÃT¶¿Éù"æÎû7‚Òéôû÷ïƒE罤C¾6‰D¢P(}ôè‘®®.pMâûð;wÿø;!5EEE|ÎôW™œÛ·oÃRŒ7h4ZII —Éyþüùرcñ !î«}ÑäDFFfr^¼x!''×3éæÍ›K–,A›¯»wïF1��Ér?&>|øðùóg´'÷_Á¥K—Ö­[7 Éinnö÷÷ÿ±LÎäÉ“ëëëÁ……}W++«7oÞ@¡¾¾> ×›7oΟ?_EEÅÝÝ=00†÷Î;¡ªG…ï£å¨B!???r¥ûÃÜÜ<66¾©¢¢ƒvíÚµà·ÂópÅ÷‡ŽñãÇëééÁÅ………Áwxîܹ"""¯^½zòä †aººº09nذáÕ«W°lgg'%%µaÃtÁ“'OÂÌK$Éd2\™L&£9ñãÇhvÒ¤Iß$¼vìØ1H«#‰`Ϥ¤¤ìììàF ž0777''ÇÖÖÖØØ¸®®5+Ä»ðͪ§§Í*!!áïïy k×®ìü“ˆˆÈæÍ›Qe·nÝŠa˜ººº‰‰  ¸°"öíÛwáÂpÌ= ³ðü™¾¾>TS?ãÇ×××Ç7«‘‘:ÓØØ¨¢¢§‘ÄÄÄ=zë¼yóÐNعsçÐfÑ#G¾ÉvγgÏÐn“½½½žžž““S||üË—/1 [µjÕ`R¾†utt n#//ÿóÏ?«ªªšššB¡   ¬&§NÚÔÔ…bbb '**úâÅ ÈG˜4iÒ`ÑK.<xÇôõõ‹‹‹á^""" ºC¡PLMMEDD^¾| ù `¿zøðá™3gKêêêŠÖ¸ÞÞÞƒÀÿ 9rÄËË „Ë`ø´´´Üºuk×®]cÇŽµ´´„ª ¬]»þ(((HIIÁšðññ±ÐÎÎ΋/îß¿_JJjÕªUhvrrú'€ïðáàQXTT¤¦¦ÖÓÓÓÐÐ�}‚B¡(**¢l%iii*•ÚÑÑA¥RAÑÃ0eeeÐ××G¥R/^ ›NµµµÊÊÊ"""zzzMMM‚‚‚T*ÕÉÉ Æª‘‘QYY•J•——‡ WAAAMMÍÚÚZ*•ª££ƒD¡iUUUÑàWPPàççïéé¡R©æææðœšššÝÝÝD"‘J¥ÂY ®Ñ’––f``ÐÝ@"‘äååQÚ<N§R©ÆÆÆŒnii——WVV†œ}*•jii YFÚÚÚ$‰J¥ÚÙÙqeJII;I"‘ôõõ+++©Tªªª*˜2™,))Iý”••Ñ‘@!!!55µÁl'…B)((••…³8T*U__ÍƒÆÆÆŸ>}¢R©²²²`¼´´´jjj¨Tª¶¶6˜RƒÑÓÓ£¦¦†oÖ3f f=S|³jkkCb7•Jµ··Ç;þPSxÃd2YOO*«¦¦ÖELLLQQ±©©‰J¥rG%‘HÕÕÕaÀ¼qqq]]]tðh„ 555"""T*ÕÕÕ•@ °ÙìÊÊJ~~~mmm¨©¦¦&8ݨYŒŒ¸tP„……544P4hYR©ÔåË—Ãû—@Í4qâDØi€§l'†¯£££¡¡⽂‚‚ªªªèü€°°0mmm*•ª¥¥…ïKx‹>fÌCCCØT'øn#++;~üxQQQee寯F*•j``�3 ŒŒŒ¸¸xgg'•J5ktE4`­¬¬P—ëIIItS>>¾‰'‰ÄÜÜ\p¶`ì ã!)))##ÓÚÚJ¥R§L™gQétºœœÜÝÅÀÅÅÅõôôúï„1cÆ|‡=y~~~¦­­=eÊ”òòrqqqiiiggg ÃX,V}}ýO?ý$,,<nܸúúz*•ª«« ¡u)))))©¶¶6*•:mÚ4´gWKKë‹¡ ¥¸¸˜J¥BšŒ„„ÄO?ý„Þ°¡¡aUU•¨¨¨¤¤$xà³Ñ××ÔÒÒ‚IX[[¢ |||§££ƒL&·µµÁ×nÜ€(**ÒÔÔäãã£P(===çÝ»w‰‰‰¨‚¶··çååýçŒ<�kk×®åXûa1ʱöãq¬}ÃT—À±¶dÉ’Q޵Áº1Ø$¤ :yò䡤K<}ú˜¤¹TAG9ÖF1ŠQŒbß £&g£Å(Fñ0pú�‘Hü¶ ÿz@�Ã0!!¡ÿ|Ù{ ‚‚‚#¦™ i@sp$õ:‰4’†“Éüæ*?ÈäðMÔe~œÉA@@à›4‘Hä}PòÛ˜œ¶¶6t"od ¯¯F ß½{7bІ577“H$®3ÿÿitvvvvvޤ¡Äb± Æ›ººº^½z5b$Ú0 «««ëèè�Ò¿qqñþ,|ߨäðóókjjŽ˜þüù³††ÆˆIèèèPTTžï¿ …RTTD x$PýÇ$RSSSyyùˆJH$666ޤÉAHH¨¦¦F]]½¿dòwr`2™rrr<’쿪“Éd<ƒí§OŸ€mš7ðg¿lrÈdò74kÿ:ÄÅÅ ÂH¢ÉÌÌ”’’IkµµµD"qÄt<2™L$ëëëGL cD"¤ÉALLŒD"ÉÉɤŒµÜÜ\IIÉoÒL\ª ===C¤há"¹Ç¾ûÀ(F1ŠQŒbd€Ãá ‘‚D"õ79_ØNOOO?pà�¾äñãÇffffffÀ} øã? o¸°nÝ:øèK1 ›3gŽÙÿ€8†Íp€3óñññøB¼Œ†açÎC1åÇ㿉tŸ¾ˆ’’.¢ª„„¸ÈüÑÿûçÏŸ‡OãââPáŽ; ˆK—.533Ãxlll„¯áé ÒÒÒ ÐËË JÂÂÂðuÞpttä'‡7Œgùôé\/Ö€ðäÉ®f½páþ1’’’0 Ûµk¾°ººðeË–¡¤P (//õ Ã233ñ¿rØ!bûöíx)X Ö/_×éÏ.úùógøϸóúõëþÍêïï…À† 8rä%zÃPˆÂøºØÙÙ}± ?æbüóÏ?áç111¨ÐÃà ¹è–/^Œ³hnn†¯¡#âYYYøGB9¡¡¡P€¿à‰'âããy?³••Uÿ)¡  �O¨Š�Iœ œ={>eXÀ¶mÛ ¸bÑÀà„˜›››™™oòòòà‘Ð|…¯oÿÇÿ:¶mÛâ„\ÇÌÌlÁ‚@Ìo‚AW9999›6mêììÄóM…‡‡gdd\¹rðˆˆˆ;wî¬_¿þܹsBBBPxåÊ>>>üéîuëÖ999Á)n[[Û°°0X÷!ã!Tyyy¸ÌÂÏž=Ã0¬¥¥E^^ôB0 ßæ=þü… ~ûí7øwË–-ÀBa˜‹‹ËP(öªªªV­ZÅd2ñÛ!‰‰‰aaað$ çÏŸl4GÉdøÔÏÏoöìÙ;vì˜;w.Ø­}ûöýñÇJJJK–,9zô¨°°0‡Ã133KHHhmm]·nü¶²²rÆ ·nÝÊÌ̼víå¡C‡ÌÌÌÐ;¿zõ*^@¬?6lØPPPPRRrüøqThffvùòeÐÙÙ¹dÉ’§OŸVTTìÛ·nTTT´cÇ___ôýˆˆˆôôtøôéӧЬUUU ,°±±ïÀ±²;w" ¬5kÖÀ$˜››{ÿþ} ¼Ä‡.«ªª–/_ŽÒf´µµQ¿|ù’·Dž={’““ËËËñÂ?666û÷ïîƒ9sæà傪««=<<àFÅÅÅîîî.\xûöí£G ðõë×çÎóðð¸sçN}}=Þ»wH$Z[[=zTKKËÞÞðӧOïÞ½[OOÏÑÑqãÆ@Ý¿råÊ'Ož žo6¹/^?~œN§ãOP^¼x‘H$ÂE®_¿ÎÇÇ7gΜ]»v™ššnÚ´ ðœ9sFEEÅÚÚº¡¡ÄLá·ííík×®…ßVWW;99ݾ}»££ƒB¡ f…—– ß|üøñ½{÷Ö®]{öìÙ°°°êêj§nmllêêꊊŠÐM;::ììì §¬¬lÍš5ÝÝÝx9ƒ––999àâ­†ùøøˆŠŠÂ“\ºt‰oúôénnn–––`·ÜÝݯ\¹"''—““ ~ô÷L1577÷ññ!“ÉL&ÓŸmTXXxòäIxø¬¬¬œ<yÒÄÄõ€€�x½téLƒ¨Yÿ •³!bÇŽiiieeex¯:777 �d$¹6äääP222€Ùëû™ €€€””ФA½ª§§&Ĉˆˆ¦¦& Ãêêê´µµ¡°­­ TŠñΔ¬¬,Ðø—””€OJ ¸˜ùùù¡„F£ÅÇÇãG×7aêçããÓ¡s¶®®®GŽÑÒÒúbÍeddŠŠŠÎž=‹ ÛÛÛÛÛÛáŽ)))xM-¨©šš| ß×@ZZ «ªª`¾pá‚’’pE�o.‹Å*++ƒ¯q8X1Œææf(ÌÍÍ…Eƒ¤¤$0\»vMYY/yÙ¿ýö“Éä: ^PP0~üx/�§§§§ªª nD§Óµ2QÓ¦MÆ—§OŸ"MCyyy®—=׬Yãëë«  €Ì °kàßÕæÍ›O:…Üaaa¸Ú«W¯>þÌCšÝ»woݺQoŠ‹‹ÇûX\ì–½½½¨7B ¶···µµ¡fÉí¥K—r8xÕ===°¯ªª266†o644€ïRZZª¨¨bz%%%0 ÃwZ[[·oß΃TðY³fãE+ìííI$†ŽŽX<}þüYJJ ®\]] }É××·¯¯/D/,,|åÊàŒ!hmÞ0Nïíí…°°0°ëׯ·±±AžÜ€8þ<‹Å¯ÑÙl6r–ÇŽ››‹f(£P[[‹[[[;::Àt[†ahZ[[ûûçajkkƒ*(RÃtww×ÕÕ¡ç„™¸¸84ßýû÷’ØÎÎ5kggç`[èßû÷ïïêêêO•¦¥¥5`Ú…B:~øðáÕ«Wƒ ¼þM êD¨««sm@­X±BMMÍÀÀÀÀÀ€Ãá ˜ ())Q(KKKƒ'Ož€/Ìb±à"ý]€®®.XÜÀ¿Ïž=ƒož9s}§©©‰L&sÍqȳ–’’ÊN ™L%i®xÔ‚ àŽ………û÷ïÞkUUUåãã311144)°a€N§Þ9iÀ€Ç•l“––fhhh```eeûʼn‰‰IKKôõõ¡ùÝËË ^HðâQQQ!''‡î;cÆ <#‹Åª®®P ®££ƒÁ` 1ñA^^^]]+vµjÕ*x¶ÔÔÔá½^*•*))éëëk`` ¦¦6<—¾¾¾ÊÊJÞYv¢¢¢êêê\éCcÆŒ‰éÈ‘#³fÍ õÁú’ºº:Þß'‰`o>þ¼gÏž‡ByJJ ¼±µµ•——‡B …³´´´ºº:o!®›Šˆˆ @…BQWWïϧòüùs¸×©S§¸>:xð`vv6|jee£ƒÁÄÄÄÀÀ�¯ÿ#£¥¥…Ífƒï‚šõèÑ£3fÌàŠ\}gŒ;V]]½ÿy£™3gð`1ïîî¦ÓéÃ&Gæ*g°AEEL@wîÜyðàÁPä0 »{÷.‹ÅZ¶lYLLŒˆˆH^^¨¡Ðéô¹sç¢}‘>øúúÞºu þ]´hQzz: Iƒx†¯¯/•J]·n]7ÙÙÙÙÃÃc‚WïÞ½{óæ T0""âÊ•+xöÜ_~ùå÷ßG ¥¥‚N·nÝÚ²e 0sižGDD°Ùì… &ä>eÊ'''¸ è¡¡®]»Æáp†øzû‡àAv¬½½ÝÎÎ:ç+V˜››ß½{÷þýû[¶l9tè *;vŒD"!ÿ`õêÕÞÞÞH;9)) 6›=qâDÖÔÔdoo n5±±±ÑÑÑ_µ‘ÓW¯^Ýbsss|ʦ¢¢â¥K—à•öôôüôÓO†Í;­r ÄÍ�7nµÖ/^àåî¹ÚÑÎÎ|[´ nì¢E‹¸TÀ¿ žžžãÆ[µjÕ0Î!ÖÔÔlذ!((Œ™±±1Fƒâãã÷ïßêÔ©§OŸÖ××C¾uëVHHȰ©é;;;W¯^ ÄÉÂÂÂÖG9s©A QGGÄoŽ9"''7{ö쀀�WWWØ¥khh@†ºSoo¯±±1ºæ‰û÷ï×ÖÖâk ͪªªºzõêðxéÛ·o!ÔÄáp&L˜ÐjÊÉÉ9{ö,èþû&§««‹ÅbÉÉÉ¡^8Ĩhll„΄BÀD"u5èdÀgŒVZè^|||ííí/^ìééqww°-étºˆˆÈ`ùõššš`ç$%%[ytwwwwwÃM9•Ë]ýõ×_¡{¡Mx*•zãÆ ˆ pm<ÊÈÈp8.Ùi®•¬……¨Ä?}úžÑR`ØÇ¼ëêêdee ???þõò†ÐÍB³ŠŠŠBÀ½ü*S\\f šÈ寫«kkk³°°xõê•„„D“ÓÝÝÍd2Óž9~ü8Zµüù矃©¯744Œ3î˵×ÅÇÇ7iÒ$HvÈÈÈ€à�??¿ ¬$<xPQQwÞEDDX,ý¿1cÆ„††Â@E’0h‡'yAQEEE{{ûa¤ç666®X±"22½I …‚‹€€@kk+Ø×¾¾>(çp8ƒ XGGÇääd´‚„"8ト­$‰+ÀÞÖÖ¦¢¢_èêꂬIII %FqrÔ˜L&ïÌð†ÑHfUPPX³fÍ™uº+›Íðõööö¶··¦Kò½MÎ0°`Á‚+W® ùÀ¸qㆲ{üôéÓØØX×D6ïìÙ³ çÌd2ïÝ»7tåÛeçtš—ñ"ӨáÌFFF±±±C9§ úˆÿ·záƒrssñ ÐÐÐpttüâÏ ß¼yƒâœ§¤¤D__ºuww7¤0 åIöîÝ‹ŽÛCäããƒWнR((D,î.\`±XC¹&šÙ¿Õ†öñãÇeddÖ¯_?Œˆ­­­æææIIIxÎÿÔÔÔóçÏ?xð`síÚ5”ø7l¥ígÏžEGGÃØ:P¡±£¯¯Ÿššú ¿¿'Nœ8!--íääôÃ,4iR||ü·Õü*üã ! £¿Æí€ÞVvvöáÇÃÃÃQ ‹ÅâbÉÞµkWEEEIIIIIÉÚµk½½½—-[­Y³fûöí<ÔBEþ‡aOîGŽAA?„Õ«W#Åb|‡¢£œ””4  ã•+W:;;÷ìÙó}:Aoooÿ\X&“9 *Æ’%K¼½½!`5`kŠ‹‹×ÖÖBEEEéêꆅ…¡¨Úǯ]»6Ø“ðóó£fB«¨¯Byy9¬ñˆŠŠê¿ïØÛÛ‹O;æÙ³gs¥,CÔÎÀÀ€‡¦2o�YÙð&&‡Ã`0¸&å¾¾¾¡PÊAAAôÚ‡mSY,Œê±lÙ²ŒŒŒáEEE(AšÄØgæýzóòòöïß?Dñ19?òׯ_¯££#+++++K$AVÙÛÛ;// W¬XÁ¥åË—C˜èíÛ·NNNðijj*85UUUP2wî\| žëv666óæÍƒoVWW{zz‚àøB&“¿vÃ5ì---mllàŽùùùÞÞÞ†?ÞÇÇ–ÌEEEðé’%K@è,88øÔ©SPxëÖ-XϘ˜˜ÈÊÊÊËËCöä˜1câââàkÛ¶mƒØ3flݺ ccc!Ã9}C'}âªxmm­¼¼¼¬¬¬‰‰ ̉êêê·nÝ‚>}Ž¡¼xñöŠÖ­[7~üxøÃ0¸{{{çççC¡ þ„‰DÂßîãÇFFF²²²JJJtÇÕFø7L$‡aKH$¾¡³³³çÎ Ïœlíííò«¢¢rçÎøèøñãK¶páBkkk(ÌË˃fݵk‘H„Bв»qãÆãÇ¡ðàÁƒ :þúõkGGG(LOOÇo¼}rájP‰täÈÙÿyhhè¹sç äÚµkx^®&niiA¿ééÓ§{xx@Idd$‹Ù¸q£ŠŠ  mß¾}°W:Xà¿áÊãâ­Ë–-[°`Ü«¢¢&âÓ§OClóÌ™3>|€Oííía_ýÉ“'¿þú+C²Iii©¾¾¾¬¬¬††Wjå? àÄ’••Õ×ׇLee%ÍM˜0áäÉ“ðœwîÜÁŸp"‰<š•w*ã÷×h-,,œ:uª¬¬¬‚‚ækjj§ Ûê”;*Ñö_ĨDÛQ‰¶ÿF%Ú¾ØñmCÏ$íìì•hÅ(F1ŠQü;59£Å(F1Šï„A£ê#FÍ _£XC51Í„’ Gkôƒ×hDN#©™¾mˆDbÿü¯ÄäôgKüïŽïõõõ“ÓÞÞÎb±Ølöˆi&ƒÑÝÝ-((8bjÔ××ÙA#i(@äHªQkk+›ÍIC©£££··÷[u¼¾¾¾¯MDŽÉiiiùr-¾áj ¯¯/""bĘ"‘ØÖÖ–˜˜8¼LâÓ)ƒÃ˜CgÿñyÃ#i(aÖÙÙ9Â&‡îîîÈÈÈ‘´íèèhnnþV‰g222\+¿½É‘ykÖÖÖ£k?,F3Öþsd¬Y[[˜É2Ö,--G3ÖëÆx‰¶o`ã±QŒb£Å(¾ ¾–iii©©©Á’×ÔÔÀ9)%%%De_RRutt¸t20 ËÌÌ„˜É”)Sðk=‹E£Ñà´,ØAKBB·766â©é²·¬¬ �ÂÑ-ø4//N§cf``€§<úb” ¤¤ÏŠn*''×9YZZ _[[ˆãrssñT“&MÂÓ¿{÷N“aÖÓÓÜnÂÂÂèìUKKKnn.†aÒÒÒHs¡ººéUTT†âªdffêêêâb€dŒD"M:J Ð>Š‹‹ëééq]aÀfIJJ""äììl žC5}ÿþ=¢þl ØL&2â+K§ÓÃ_Ù¡ ;;[UU߬iiiÀ0}út®ÅkWWWff&8°À»ÓÜÜœŸŸ¾ //8I1 ûôé“€€�âÍ-((�j8===Ä ‚úðÔ©S!˜Éáp€—ŒB¡ >Ì555ÝÝÝjjjýû’––b¾ÊÉÉz4CCC<MFjjêäÉ“Qð§··ŽZ á ¼étz]]ŽŽü 4èSUUU¤7aXaa¡´´46-®›r¡££ãÓ§Oð† p\tìØ±øšâ+ ÐÕÕ*Ŭ¬,`cCÝ)55Ñ^ îô}ðîÝ;6›=ØMÛÚÚ***ïF}}=^ú šš�h–ø‘••¥®®ÎÕ—X,@˜>}úPšõ;™œ¶¶¶ŒŒŒ>¤¤¤¡©0$$ÔÕ¦L™boo¯¢¢òñãÇ€€€œœ Ã-ZdccƒËiiiW¯^càââ²`Á±}}}/_¾Ü½{7ÌïÏŸ?‡)))mܸÑÀÀ 11ñàÁƒÈàÙØØ8::~úôéÞ½{0§Ì›7oåÊ•²²²9997oÞq”Õ«W[YYñæf‡‰ ¤SÃccããÇ###aÆqttÄŸ�/.. ÌÊÊÂ0ÌÂÂÂÆÆFZZúðáí­­ˆNíÒ¥KÈä¼yófåÊ•À×ÛÛ |9cƌټy³±±qKKKxx8pühii999éèèTVV¿}ûðiÓ¦ÙÙÙ (�HOOooowwwþü9¢Ðýú5ñóó»»»OŸ>½««+22òÞ½{0¸ººN˜0?s5+š÷ïßïìì ÄBýõ×õë×aîpppX´h‘  àÚµkÇÍJ¡P‚‚‚zzz¢££A'QJJjóæÍFFFt:=<<¶ÙáCh�� �IDAT´µµÉb(¦©©éðáþ¾¾è Ú»wï.]º[ÙL&/qùÀÀ@0-®®®†††©©©;vì@†ÖÒÒ™œÒÒÒcÇŽÍœ9$òòòüýýaš^¾|ùÒ¥KÅÄÄÒÒÒ®\¹Ž…««ë‚ øøøâââ€-BXXxÛ¶mȱèÚÚÚüüüÈÈH …‚ˆìJJJÇwÁ‚+V¬––þðáÃÍ›7²zÍš5–––BBBÉÉÉL&ÓÁÁ¡¤¤¼ ‹}óæM Ã$%%·lÙ}‰F£effÒh4¨>´¢*--ݰa" ÈÏÏß»wïÖ­[äN}÷î]ww·££ãÇ¡?³X¬÷ïß›šš‚û’ššZ\\ƒ¦à°°0`­ž0a‚ƒƒÞc‹EßÌÉɹxñâ‚ h4Úõë×Á[utt\´h‘€€€½½½¾¾>éün&'11ñÏ?ÿìëë#“ÉîîîxÉöööôôô¼¼¼˜˜$ ›——‡åÊËËW®\yàÀ[·n½|ù¹‰{öìùM·š››ùå—ëׯ#¯:))éâÅ‹°cÇ|Ô5ë£Gð ußÉäÔÖÖúùù566â_Ù«W¯ªªª€2ëÔ©S=Úµk×Í›7µµµßÂÉÉIQQO¨âååº;™™™bbbçåË—x)늊ŠK—.Á¬—püøq`ž={6—¢íýû÷ÅÄÄàÜÝÝ_¿~ \úëׯªàùóçÿôÓO_´Òmmm~~~\|·ïß¿ONN†‹ûûûß¼yÈQ�þþþjjjžžž†mܸqìØ±ÀysüøñþþB\\Ü­[·PÒH[[Û¾}ûÀÇÏËËsss‹ÏÉɉˆˆ€Û%%%ÅÇÇëèè¼xñ‚N§C¡——Wxx8Ñɰ°°ÒÒRü2 Ã0[[Ûššh›6mZAAAuuµxåÉÉÉžžžxéåüü|QQQ¸ãéÓ§CCCó&//ïÁƒxWîèÑ£€Y`êÔ©“&Má–ÀÀ@<‡fkkëÀ ÉÎÎöððˆ‰‰ÉÊÊzñâÜ%88øÒ¥KCÑ€ŠŒŒ¤Ñh\¡äM›6ÅÆÆÂ>–¬¬,ž«»®®ÎÛÛV�©©©GŽ#7}úôþ|ìÅÅÅÁÁÁYYYh~ùã?¬­­AœÉÊÊJ[[{òäÉ;wî¼sçð+»¸¸Ì™3‡oÍš5pßÚÚZú°˜ðóóûüù3Þ4¾{÷nêÔ© ¡¹iÓ&yyykkk//¯;v€–ÌÌ™3'L˜ ©©@§Óñtp’�o²  `óæÍ¯_¿®©©ñóókhhÀËœXXX€4xIIIpp04ö?!×þÄqMMMø›2 gggø N÷óóƒÕBrr2Fƒ§ŠŒŒLIIÁ›WWW0êYYY÷î݃Y%""ÂÃü:ccccccð®îß¿ÿýYn×®]ûñãGhCœ7ÈõóóknnÆ?¨5ƒ½ A^ÚÆ‡§9òÍñôéÓœœ.&û 6¤¦¦JHHp8œuëÖáMNKKKÿfý~&GKK+(((>>ÞÏÏ*++———ƒJ4˜/Þ�”Qâââ †™™Öúúú6mÚ”››‹Â>ƒ¡²²n§¦¦†§’üû•• ÊÉÉA2L“——‡;¶¶¶ö@ ˆäääææf0(øãââ’à †ººº´´´±cÇnݺõkk÷\KKËgÏž&“ÉCû ¦ÂÒÒRÐ1B »7nLš4‰·šàåË—BBBa0¹aTò¸.;oÞ¼7oÞ€Ë? Rý€q-hVeeeäñàñŸ966¶««ëòåËx污`öìÙ³gϾ~ý:^d‰½~øðAFF†‡(oâUà„……aTvvvfddÀÊcüøñAAA¯^½ºsç΀® ™L^ºt)ü{õêÕY³fñ؆2Q¤E‚c AAA™™™‡âúaEEŇÔÔÔk___›I“&Á€¶¶¶)S¦ ð@dd¤€€�‘HÄ3ûý‹PSS JNNÆ E"<þ¼³³sÕªUh =mâĉø0æ÷ÇáÇ1 pˆŒŒìëëÓÅAü#((ˆF£8pà_ÛËႪª*FYSSS[[{ˆ?ŒŽŽnhh077‡ðKxxøP’^eeeávjjjGOOOWWVôà_À„hbbRRRK˜ý‡yyy¸£ŠŠ ^ˆv‰ª««áÖýÀ0lÖ¬Y¹¹¹°UÐÔÔ´bÅ ‘/^,\¸ŸÁÌÏÏ?gή߂½ KOO;v,‡Ã122RWWohh@>,ˆÍ`Xºtixx8‡Ã¡P(CÏ<,))yüø±¦¦&ì²|øðABBBUUõ‹ oHŽ@ °X,kkk~~~333¨bf„TK(¶R*`áÂ…OŸ>…à�W…„„¦M›wAùÖòòòŠŠŠÐ¬ÊÊÊ N]mmm$qÅŠŠ ø9^p/:::??ŸÁ`ttt¬\¹’D"-]º¾ÆµÄü*Ðh´ððp++«)S¦|ío FXXXQQ‘——ïo±Ùlä±ýõ×_cÆŒá­d2ù‹ÖýóçÏaaaYYYªªªl6»¤ú9—ÖpBBByy¹™™pc[YYAŽH$²X,d&L”––vuu!ßT__ÿåË—ÐÓ>}ú´|ùò×ê ¶úILLd³Ù ›ùïþu&çÍ›7µµµD>uêÔóçχhu <¥¡¡aiiùäɓׯ__¾|ù‹cuòäÉÈ¿råJhh¨žžžÍãÇ!dŒvê~þùç‹/¾zõ BX^ éõ‚`×`S@zz:Düüýý<x€ßó°µµGÂ)PtÚ€éÓ§Ïœ93...66öìÙ³ø´K‘'N€û€_ºÂNõÍ›7CCCoݺedd4oÞ<‡óèÑ# ÃÊÊʆar¶lÙ‚¬ ÑU477777?}úôóçÏ»»»Ÿ={fff6sæL.W¨?Î;ôõõ)))Y[[‹‰‰yyy *jåñãÇ;88\¼xê5à933¶Êàer%2 ìÛ·XóLJKK8pàØ±cx›ahh5+??DD„¾¾¾¥¥%ÞälÚ´éÚµkÐ݉²¾¾¾cÆŒQWW‡Â+W®¸»»Ã¦àðÆ^ffæ³gÏ.\8ŒíŠîîîÒÒÒ/ÚäÒB833óùóç ,˜6mÚõë×á ñññ(übii9 Ä{WW—‡‡oP[[+))yóæM??¿þ&çæÍ›æææ°ÄA8räÖÀê  &“©©©ùƒ›œ¸¸¸ææfDc¶jÕ*´ÜÙ¼y³’’Òhr®\¹B"‘~t“3<‹jjjŠWÚ¾}»··÷Ý»w FWW×£G#¦-++«¬¬ÄïãlllÀfÀ˜GVþ�.÷þHII¡‘ÁLÎaggggg[´¿e``€ç`=»iÓ&°l6ûÞ½{k×®Å0LBB‚$°—_ÖÕÕíO›?>Ôb(ÊßÇÇ›››ñAΰ°°ªª*ÈÀ)--}óæ‘‘Ñ`~qppð²e˸ÂMT** {9PøÓO?Aappð€‹§òòr¤T¨­­=˜Éá 999¸Kjjê‰' ÚSZZŠ[ÇÄĤ§§ËÉÉݽ{7//¯®®ÎÌÌ "Š›6mB«7ô}OOO®TL‰w½œ¯}ÈŒŒŒ—/_Λ7o.EOOϽ{÷***À²~BBBšššŠ‹‹‹‹‹ËÊÊ óòò0™™Ù€&g(˜2eÊP4ý¢¢¢&MšÄ%« LÕÿÑ3ÎBBBøß>>> åÛÒØü@&çÔ©S:::x“ãääË ÆCäŠF£EEEq™œŒŒ 2™ŒOk†y_GG‡w¬àܹsó(hJJŠ˜˜×YÅË—/ïÝ»orìììPÔžÍfCe»»»ÃÂÂÖ¬YóŻ俿vtt|q—ëâÝ»wÙÙÙø;N:5!!¤ŒZZZ>þ<ØÚðC‡YXXàMNWWד'Oìííñ_«®®ÎÎÎæ=;ÛØØüÍ£ íííQQQ+W®Äæää<|øorôõõËËË¡‚L&â±ñññjjjø=ŒÁàïïïìì<ìç|ò䉢¢b5¹!†ÔNŸ>??À999L&égO›6-11*ÞÚÚZ^^ÞÞÞŽ ‰‰‰cÇŽÅïnþù矞žž\&çÀVVVÿ “SXXØÒÒ‚_¤†‡‡+((üà&çßÅ×µ«®®nUUÕåË—á_X Ïœ93?? 544`¸†‡‡O:UNNÎÖÖ622"ööö åäÉ“ðó–––¨¨(Ø”””œ3g\„Éd‚ƒ©¡¡‘——…àÒéôÌÌLÈ!–““ƒ‡ºººììlØOž5kÖ°ÕÔÔÔÕÕáŽ`í2228ޱ±qsssbbbBB|N,]ºôýû÷p¢ÈÜÜ\BBJ€»wïB}ÙlvAA\¹··VßcÇŽ0avuuÁ6~[[[BB¨%’Éd¼zÒ±yófpÀÙl¶““,°ÌÍÍáF===¬(---))177×ÕÕ­¬¬„Oa?ÉÌÌ mªoÞ¼yÑ¢E°°téÒ””ÈP·°°�wØÙÙ9 �Ì9,úúúP—èíí…UlWW×û÷ï!å‰Á`pí“}ƒƒƒá¼äAãïììÌb±²³³a©ÔÓÓ[†ªªªøf…-}´*UQQ‹[__Ÿ™™ ûØS¦LOÂÖÖöÅ‹0 ®Y³R`Š‹‹á‚}}}(à«ðöí[”иpáBÙ¥§§ƒ=˜?>!sƒ†¡””ÔêÕ«yLô Yú¥K—¢PÕ† V¬X1”Tu Ã( ô¥Á ¡¡¡¬¬ŒF+äp¾ÿžD"ÁD:mÚ4|^¶lYRRlì-^¼Ro6lØpûömÀápúk¹þspqq¹qãÜwÆ à¾<}ú”‡›˜ššZWW‡Wï>}zVV¼eeå¡$X}g899ÂØÑÚÕÕ …ß||||‡f2™½½½EEEjjj=== °IÃf³EEEQLVAAŸŸÿÇ cÆŒ#¨¥¥E§Ó‹‹‹ ÆÊ•+ÁKMMMUQQŸ:ujzzzcc#ƒÁØ¿?þ˜$ÏA×ÖÑÑyóæ ƒÁPPPX·n„éÅÅÅ333 †±±1 ›qãÆ1ŒÂÂBƒaeeçà JKK+++ †‹‹ ×þ¤€€@ZZšAÿU‡Ã!“ÉÈ”–––’’JKKc0&L�ËWRRÒÓÓ£ªªª©©ÙÚÚúñãGƒ±|ùrØ3œ8q"d!3ŒmÛ¶q¹lL&ŠÈd²±±qll,ƒÁÛ¶mDŸSRR †––LÍJJJ$);;›Á`Ìž={À„1 …RPP ++ Y›===S¦LAGAçÌ™óâÅ 8¶_BBB?ýôÓëׯ †œœ¸çµµµºººcÇŽ€f>}:—1èííÕÖÖ†zMš4)//¯¦¦†Á`üüóÏkš5kV\\\[[[WWä Q(###¨¬„„Ä–-[À«;vljj*ƒÁ?~üòå˹âTÕÕÕë¢PÒ„ PÀgÆŒoÞ¼iiia0žžž¶?cÆ AAA}}ý„„ƒ!##ñO|³à#f†±X,tFROO¯²²²¼¼œÁ`¬_¿òĦNš––}ø—_~÷lfföòåKƒÁÇÇ7 d8_GGGCC8a}}}²²²(o˜Åb1p€7lhhXTT}iëÖ­x6#&“9sæL˜)8NWWú-‰DB'–Øl¶˜˜>Ó²¯¯ONNnÀÌÉÞÞ^þ“Éœ1c‘!‘H¦¦¦D"177Æ8›ÍæççGQedd$$$222 †‘‘$gCæHY,–†††œœº¾‘‘Qnnnmm-ƒÁpww‡C©¦¦¦±±±íííL&ó×_ý§g@~~~¦­­=oÞ¼èè莎‹~pwwwJJ Zý³Ùl!!!üæn__Ÿ´´4þ螆†F{{{QQƒÁ°¶¶þçTòvŠ‹‹©T*Œ—žžž‰'¢sгfÍŠ‡Ñ ç=z{{Q€—Ãáà›•ÃátttÉä¶¶¶ÞÞ^®Ù•÷»ííí¥P(===çÝ»w‰‰‰£ª ÿIŒr¬ýøUýO`Tô‹ÝxTt£Å(FñŸÄ¨ÉÅ(F1ŠQ|' œ>@$ñ›.# €a˜  àHÒËÁ0ŒŸŸÄ4lΓÉäS#h#‰4bjD zzzÂÈ›ð¬¸ÿiÀÞÛ·š@Oè79@E<bÀf³“’’F’uKKKVVš¬ÿjjjÈd2ëÝ­­­­­­#i(õöövww°ÉÉd¦¦¦ŽµC ÃØlvEEÅ7¹šºñocrøøø†ÎÿÿãÖ7¢¢¢#ÆäðóóWTT ˜f‚|h¦ãlƒ1bjD §OŸFØäPXX(""ò­44„É¡¶¶VPPð›4ß·]Ô’{h|æßâââ ššš#)c­¨¨HQQq$e¬utt‰ÄÓñ c­­­mÄÔ2Öþú믑49ˆ‰‰éõHÊX+//;vì¨*è(F1ŠQŒâÿk|!|™…?éöêÕ+ÐY¾|9JÏ¿u먜íر£?'îÞ½{«««1 »zõ*¬õÔ”艕••Á ,===Äžýöí[8H¿hÑ"tÆûÁƒ@îêê ÇQÏ;”€ßÿOöΟ?¾qãˆý�RSSXpþüùýMnß¾ L ?ÿü3žòöö†ãâ�999777DgI&“áÑét ‚SVVF YYY§NÂ0lúôéˆwäÅ‹ §fkk;Zý{÷îÛ·ˆÒÁÁÃለˆ í‰ÊÊJ8:~üx`5Ç£³àešvíÚfûí7 Z9sæ :æêê ‡"ïÞ½ %MMM ¦¢¢ ¹¹¹ðÀÌÌ ˆ†///{{{üYnô†ïÞ½ û¥ÕÕÕ{÷îÅ0LKK ަfffúøø /,\¸pݺuááá É�! Ã|}}AnçðáȹdÏž=àèùùùÁ©:‹¶©T*p•òÆ«W¯êëëmp÷î]`àvssCzK'Nœ�Q¥“'Oâ)æ\]]/_¾Œ‚?­­­pšXQQú†a999ЯLLLýàË—/˜uÕªUˆÃñúõë@¢šu@lÚ´éâÅ‹ƒ‰5”––)'~à�¬¬¬ðŒGhà  4žžž È>ݸqcww78ß NNN½½½ˆ¡¸¸úÒĉÑ|ãÆ Ã–,YÔ‹�ÿqãÆý 籎=êììÜŸÃÉÉɉëõ¢˜0a¾}û¾ŸÉ)**:|øpSS~"‹‰‰INNÞ‹ÌḬ̀°°åË—ûûûwtt@á£GˆD"þ¬Ðž={LLL€cÍÍÍíêÕ«BBBëׯ†ÍÖÖV &¬¬¬<uê\¤ªªêäÉ“HNNŽŒŒ„œœàÇ ªªª‚ÂØØX"‘hjj:wî\tâúàÁƒ<ÁêêêÜÝÝÛÛÛñ:Tiii?†‹çççsñhݹs§µµ>ˆˆàãã›2eÊ‚ Рݽ{wgg'<ØÉ“'an‚Ì¥öövø-Hõy{{çææÞ¾} KJJ._¾¼mÛ¶ÈÈÈŒŒ (LKK#<ŽåþòË/¥¥¥IIIx·5kÖÀc3™L F®©©ñòò‚kÖÖÖzyyáÏuÇÆÆ&%%q5ë”)SÐpîÜ9`þí·ßƶÖÓÓÓËËKVVÖÅÅÅÆÆ†B¡p8‡ÀÀÀÖÖÖ={öÀ›šš<øûï¿ËËË#Æ”ÄÄDÄÍ'Ožzo<sþ¶mÛ,,, ÄìààðàÁôQ}}ýÑ£GáFuuuÇŽ;zô¨’’ºuLL Ìé%%%"""ˆ ˜“|}}…„„àËW¯^ussÓÒÒÚ½{÷´iÓ oݺõúõë@mÀ`0ÜÜÜ@`f@¼~ýúÒ¥KóæÍC…ÍÍÍp£gÏž‰D“'N(**‚Óöûï¿ÿúë¯ [¶linnŽ¿pᘜÎÎÎíÛ·Ãoétú¾}ûNŸ>ŸŸóæM(,--½xñâÏ?ÿõþý{(LOO'ÖÖÖ7nÜ`2™PD$ñRÖ€­[·655ÅÇǃ;Õܱc¬WUUyxx´¶¶â5ªkjj@ þåšãrss•””Ѐ˜ÏÑ£Gµ´´€hîðáÃ'Ož”––Þ°aêU«H$›Í^¿~ý€ò?ÿÖ¯_¿fÍPLذaø>}útþüyxcŸ?>{öìž={^¿~…>|^½zu```DDD~~>¸wÿ.¼¼¼²³³ß¿ßÿ讣£#iEGÃ$77HžŸÉWý¯¿þz÷î*¬ªªêììÍŸÌÌ̲²2 à µµµ¡ðÞ½{ øëØÛÛ?”0¶nÝ ªæ@“ÜÑѱiÓ&p$%%]\\`îNHHxñâ†ašššŽŽŽÀU\\ Þ‰‰ 0xFDD€ˆ�b¡8xðàž={¸tׄ¸¸¸››[YYrÌ1 khh¨««ƒºTVVr1'!|D^ˆ‰}×®]žžžÈñ733uw€€€À–-[€0//¤Nétzyy9\°µµ5>>Ã0mmm`(IIIÁëzõÇêÕ«-_wïÞ=/�ŒÁ`dggÊÉž"èêꪨ¨À‚F£}úô Ã0mmm =:wîœ Ð~,[¶ xŒ`Ž�Þþ7Nž<™D"õõõA—ܼy3T6;;51Ô4))©··ÏÎK–,™>}:—Xbb¢§§'ìcqñ›uuu}øðhùSSSa#-- ·Žåçç:% ÃÆÇ%`µ`Á`Çó2)))[·n…÷³eËèÃnnnÀET[[‹<ý¡££ãææ]aÆŒüüüÀ²F£™ššÂe;”ENNNL&Ÿ$ÆÏÏ¿eË0ü`íètzYYTçñãǰ~ª¬¬ìîî†BMMMXæççOœ8 ïܹƒ—ÂÏ¿L&/ëÀb±Þ¼yS©T77·?]:‚¼¼<I@]]]®OÓÓÓ­¬¬@ äÀŒëââ2uêT>>>&“9ôuðßG||üµk×@”‹ç´­­­¨¨>::ˆ555­­­P¨££tyÓ§OWRRâ2þ·`mmmjjÚqppprr‚µ ÕÉÏψˆ€UÝ÷39bbb³gÏf³Ùx“caaÑÚÚ ú+¦¦¦¶¶¶_¼X‘ 6€²5^É•ÅbeddÀ\&$$dddTXXèáᡦ¦‘.iiiii騨(__ß©S§×xO~~~áááK–,á"û믿@$í‹& 0{öì1cÆàMމ‰IMM TÐÈÈÈÁ†ˆÌÌLWWW”Ýakk i—0×Éd“ºº:ggg|‚ H`ãÞ½{‚‚‚\\d\�ƒÇ•R¤œ‚‚‚ ã ¤|üøñõë×MMMñÁ˜Ô-Ztj@à½sçNXÃ2æ¾eË–±X,§¢P(ð&7nÜ(++‹uÐB¤¹¹V_,^ñLä0Qº¹¹Á‚’Ë|òFmmmGG ÐÝ»w´Ï·nÝ KIˆ¤yzz¾ÿ~ݺu<(/Á0´µµmß¾/©Þ²²²²²²EEEøÁHÏÎ;7yòäþ ø>‰ýïÜÒÿ´$¼óêêê“'O~QÏ;$$ÄßßßÑÑ‘‹Û›úßTXXøþýûð·àr™œ¸¸8;ÖÖÖýŘ}}}ƒ‚‚ÀYé/ÜŽ�q8œ•+W†††þà;Ïž=»|ùòªU« ®0nܸqãÆ…‡‡ÿÏ£µ¿ERRÒµk×xäRµµµ•——ÿCq_—Š âóúõë¡°ñà €ÉdþöÛo&&&`uº»»CBBð_STTôòò*..�¥˜ú½¼¼Þ¾}…¼KKKccãÐÐÐ> œ½{÷nذaˆÌ¸¢   77*˜’’òüùs¼¿³uëV???¸Ý§OŸð¢;îîî»víBÁ„àààÞÞ^ø{Ñ¢Eh +!!áååU[[{åÊÄ< <xPQQáää„§A"<==?‹›S§Náw,x�$ÑbbbÕ9{öìäÉ“¹¢Ò[¶léììôññ166F ÊGe±XžžžÏŸ?‡III//¯êêj???´Û‘”””˜˜øË/¿ü^{öìY777Ø<tè~ÏINNî·ß~CËh|F_lllvvöÎ;QøÕ+<<œH$"òl!RÎA�� �IDAT‡%K–øùùðà|ëêêrpp8~ü8—”ÆÐqþüy!!¡+V ãÜC}}½‡‡ÇÑ£Gá ììì ât:i>zôHHHÈËË+::úáÇCqDww···7¸böìÙ`QФ†”‡`€ ÝŽ€€�>>¾©S§ž;wÎÛÛ6nñR¹0jNž<Ù?â÷CáÅ‹ F˜pçÎïFÆüw°jÕª€€�ç^ ¯_¿~öìÙè¾Îä466vwwÃÂ%&&)cÑWÍÍÍElí $Ã5V………ŒŒÚÛÛ!†’’’’’zÿþ=Ò�Å0LIIIIIéöíÛxÙé?._¾¿ÂÃÌÌ 6¨Tê`nHKK N‡ feeqÖ·nÝ Dñ\êX………...hµêÅáph4>$bdd”——ÂÕƒááÇ¥¥¥...xž¡ƒF£Mš4 kCÜ2AÎxll,¾YËËË•••ñB#À^HA&NœØ××׿²@zÃ---ƒE>/\¸››‹ '¨9ôGvv¶®®.˜ü±ÿ ~ÃJ1;;M‚°…ÖÑÑöäåää9øð!>¾Ë êêjXH ˆÞÞÞ¥K—úúú›‡Ô××—ŸŸõêÕ\¯w(hnnvuu=}ú4’åY¼x1<L\\ê`³gÏvqq‘““{ùò%’þ䂇‡ˆe`v÷îÝå‚úúúx÷%*•Š65ÓÓÓ¹Lˆ²²2zóçÏŸ‡ˆ¥––Ö¡C‡ ~ˆw^.\xêÔ©aÈv|g˜˜˜lݺuìØ±‰‰‰!õãÛ›;wš˜˜à7á¸À`0*++‡„øÇMÎ0àààpâĉ/æ}úôéèÑ£øXµ¤¤$®"D熡PâççkI®§¯Rnç õpañâÅ<À/i[ZZŸ>}úÅ[„„„ô×AøçþñãÇø¹ðóÏ?»ººâùÛÁ! Á3›››‡^°µµE˦¡s¤sŸŸb0— †Û·o÷õõ!uWÀ‘#GæÎ i¼1gÎÿaŸP¹p៽½=QœÁÐÞÞnooùòe$…€¬T¼¸¸™))©/.”wíÚ…ÞÕ°_{ll,ì± ¶0ÕÔÔù"<Pб˜ œ9sfØ Çï ÐãÀþ;(((عs'L€½½½³gφÀò÷Ä?nrÊÊÊð)a�‹5þ|Ø…0™ÌþÛ\íííý †cÿ¹»»;;;óX‰kkkÿÍ£ >>>JJJýå°\]]wïÞ—,))Aë9ä$‘œ†N§³X¬ïfo0 kmmÐÿýý÷ß !:¨¨¨€”<Š‹‹¹Dm«lRRÒÓ§O½½½{ä¶UUUîîîý7xbbbÞ¾}‹w_š››Q𡺺zˆŒ;?~ü;'"ëëë‡aoàõ–••qÙ›ÌÌÌëׯÉ‚¯o9Ý¡Bëêêú[vuuݾ};מAqq±††ÆHâ¦ú¡"ü‚aØÔ©Sûg~üøñäÉ“øl½Ùä¬\¹’Á`@”ÌÁÁvV~ùå—“'OBááÇa?Æ îîî'N [¿~=°ýDDD _¸¼¼¿ôQWWÿí·ßèŒ ‹¶¶6(´±±7ÜÝÝýܹsPèááä¶êêê$$$þ&7ßܹs[[[áâVVV°åpíÚ56›½eËoooHm8pà�Êø¬®®–””Ä_ˆ·´´loo'² R©AAApe55µ‡b6yòäõë×Cáœ9s`p4ß»wïׯˆ322 8ލ¨(dÁ©¨¨œ9sn¤¯¯ ]11ÿÇÞ—ÇŸ¾ÿ?SÚ7m"%%J«8;)K"EÇV‘plÙ²t8Ö:²²¦E©-Z„HhmTTÚ÷šö©™f¦™ùþqý>÷ëy=“‘ìýzÿÅýLÏýÜû}_÷u½ßÏž<yâææfee…šÕÆÆfëÖ­hu5jþørãÆíÛ·ƒ´¶¸º&&&Ο?¿³³“ŸŸ¢£deeoݺ/3f ºv¦R©„û•þ!..ÎÊʪµµÃ0Дììì433KLLTPPprr‚¬µµµÑàéêê¢Ñhø…üï¿ÿ¾zõ*üÒÁÁ¼¥Ïž=ûï¿ÿÂí‚››œç ƒ¥(&&,·L&ùå9’Ûÿç³8}ú4ºù?þüüùó¯_¿¾k×.¨OOOŽ—ÍÍÍ(÷ñãLJ††jkk/Z´gÏž :«V­ò÷÷‡D;;;¸â>räȉ'`á?vìX¯€Üç½#^°`…B¼,--!ÂãêÕ«ÂÂÂ6l8tè««+<=zô(èž<yrÛ¶mp óóóC'†?ÿü–qqñW¯^ý˜éøÕ«WS§Ne0"""àX[[û÷ß?|øPKK uªÉ“'{xx`¶dÉ’ÎÎNH\¹rå®]»~ý%¿· ‘H`Ammmý믿 °’Á`455}×£Ûg$Ú FÑh4lÅÄÄЭ …Bͯ””ÛÚÚÄÄÄ Œ ¥¥–V999dC$“É„|OO\Ì ¢Ý_ww7ÙˆŠŠ¢¹¯³³ì�’’’hiooé5l‡D[OO…BÁÓét:šI•Jåp8PXî’ ‹?±Ùl¼Ì%›Í† ƒ!C† ëbƒ!ÂÂÂ`ˆC5Œ†:¸˜Æ?^¢­¥¥EJJ o0$“ɇi>rW/N§Óé„L Í* @XÅ[[[áp ++‹räQXT½ÜÝ ·Dw CŽp0Â0ŒÃá477CaY,Vss3!k|aºººà¶FBBÝõ··Ã1ZZZåÈ݇ÁEÀÏÏ}x$Úh4‹Åâîè‹¢V¼ÃXSS“¬¬,t`‡ƒE@ÅäîKø–Åw¤^»17ð™b\mL&³³³?v¸GkWW‰D‚|{Í”»;¡–Å0 ß¿ðm0jP7f±Xííí0T™L&lq„„„PFåÅšO œ‚D[kk«„„7i)šÙlvkk+t`îùð›K´}æ”#((H˜ÄEDD¸YÞ$$$rx‹A¯Þ8܆£!C†pï{%çvƒæ}¹òÉSÞ!„Ë[!!!Âgàg|î’ ‹À=Tøøø¸ (((HH쵆?kSîGõ ¡‘ÿ©fåΫ׻î¾öS¡ì¼Á]ÄI$JáçççÎ_Xüàäv6éµ#q×ð—žÕÕÛkþT_"”—D"õš;w_êû€ýl¦ÜÀ¯èŸ­øêí5Sîîô½× Œ~~~Ôî}œ>5p~>圂 ËÇLJ6LÜóá7Ç ÇÚ 1ˆA âapÉÄ 1ˆAü |R/§/ü¿ ÀyL\\| ¹Áp8üýÖ��›Í`O@@` •&X¯ƒ›Ú£ “Ã7Jß}É!“ÉÞÞÞiiíééáÍñð;–(22’GH×oº3HOOHÓ›Í*Â&“9À&&“0À&‡ÊÊÊo59 >¹G~¯%GFF†{ñoðX³¶¶Hmxµ�Þk¿#k�µ¼ÇÚÀ(Ácíë»ñ DÛ 1ˆA â·Ägœ¤Á©¿•¦P(Þ!%%…:›››ÁÞ'//ÏDR[[ ®÷JJJàzÏáp*++1 ãç燥˜ÉdâIŠDDD Ó®®.ï@‹­­­à/++K°WÖ××KKK÷}ÃÂ`0š››É †aT*‚ÄÅŹƒ-ZZZ ÊANNŽà_[WW'''‡"9ªªª ¼�E¼²X,'@ÁV4 "<ÄÄÄî¡mmm$©/Îß555 x×{ ràããCÁ_¨†…„„¸Púج À09r$dÊ]ØžžàÄÄW/ö¿¨Ì/ò…ånÖêêj0Ä5ŠpxåQÒÎÎN:Žšµ­­ b°dddc+™L†ˆd߯©©¸eee¼½‚Íf×ÖÖöe;I¡Pzzzð¨½ö%TÃ#FŒÀ;”WVV*++£’öÚ—º»»EBTT¹Àvtt@@ÉСCQ_â=`ªªª”””>e Óé­­­øîu´"ôši}}=DA)**¢±SYY ñ1x‘º�ÞùBü"ö°ÍúQWW'++‹ú8pl%””Á`ÀFXX¸ý_rº»»«ªªÒÓÓcbb7b{{û­[·€&aÙ²e›6m’‘‘!“ÉçÏŸGª –––øŠ®¬¬Ü¹s'Lžžž|||……… Y"%%åíí­ªªZUU…ˆf©Tª––VHH…B Cª ;vì““knn¾zõ*R]µjš,jjjlmmÝÝÝyâ'¦òòò?ž;w>ÆLDD( ˜˜˜ìÙ³ïªO&“=<<*è²eËЂWUUµ|ùr ½RÎÎÎN‰tûömuuu‹•™™ BjÊÊÊ.\5jF{ôèR=xð jæ–––Ó§O>|Ïž=¼ N_¾|yTTšî‹‹‹mll@Ô××WMMÉd&''ƒl”¦¦æ©S§D4ëíÛ·A"péÒ¥›7o&4ëÎ;—.]*&&æììŒÔW+**ÒÓÓG]ZZº~ýzP ‚Âfdd UÐóçÏ£•¯³³3(((''É•òpknÞ¼ùìÙ³(­¬¬lÓ¦M°Zâ¹Ã™Lfjj*R=}ú4Z(ŠOuuõùó硆½½½ÇÎÎÎÖÖVJJ ôë€ÑàðáÃóçÏ®¨¨Ø¹s'RÕ×ׇU‡Ífgee­Y³†7IkGGGCCChh(•JEMMM/^΂mÛ¶ýõ×_âââ555‡Bª 3gÎ,++ëéé™3gNqq1,@ŸŠTA=<< /ÅÆÆ"UÐÿýwøðáííí·nÝÂ0lùòå7n”––nlltwwº)GGÇ%K–pÏŒ©‰‰Iaa!„õ°Ù슊 àøa0 û„XÒ;;;À}Á‚»víÂï*Ï;\»wï¶°°«®®vrr*..Æ0ìܹsS§N2dHII‰½½=¨‚x}¾JJJÖ®] ª þþþø|étzeeeVVÖÝ»w-jÖ®®.D{ßk³þ¬Å¦¦¦†J¥®_¿þêÕ«ˆ³ÎÄÄDBB:°PRR~½IJJê ---WWWü,ñÝ—œâââ-[¶tvvâÇsdddEEÈôž9sææÍ›{öì9w†ôõuëÖÉÈÈà=zñâE˜ ÕÕÕ³²²@‰¶c&&&¹¹¹jjjðZ*•úèÑ#¸C~öìYzz:¤‡„„„††nݺõþýûêêê¸cÇ))) =«¨¨øï¿ÿŠŠŠúXr2™ =ŒHHHˆ‡—ûûûŸ;wOæáᡪª O7lØ ##t;ÀIŠçˆsttŒŒŒ”””äp8#FŒ¨¯¯okk[·nÌ&ïß¿·³³{ñâEAAAJJ ¼0,,ÌÅÅä¶š››ýýý£¢¢¸EGpqq)(( PzϘ1£®®˜¤§NZPPPYYyèÐ!È(55uûöíxúÄÄÄîînxzöìYÿ½{÷â›ÕÞÞ^FFÆÌÌ .”””üóÏ?°uZ°`Aff¦¤¤$‹ÅZ°`Á³gÏ:::Ξ= /ÌÍ͵··öìÌJQQQžžž ÷Ò\¸p!-- Tã–,Yç`<AˆéBÖéééÛ¶m‹ŽŽ† "<<ÜÏÏoþüùð˘˜ø¥““Sdd¤ÝáÇ-,, /^<bÄCCÃ#GŽ\¹rVÍ1cƼ}ûV\\8Âû"4—’’âêêÚÒÒ‚—>ºwïž¾¾>ÈdlÚ´IZZÚÂÂb×®]»víš3f�mèž={Èd2žÚŽJ¥º¸¸À—¬Y³&!!¡¨¨(!!#""Ž?~ýúõ°°°úúzHtuu Ú¹sgPPЬY³Îž=‹a˜­­­œœ·®ÚÞ½{ñü¦¦¦@WWWgooO£ÑðögÏž¥¥¥A^¡¡¡!!!°(nݺ5cÆ Ø]­Y³FNNnþüù§OŸ>tè¶¶6†aüñGDD„²²òŽ;ž<y"""B§ÓÇŽ æ€9sæ|üø$ÚtuuKKKñ6ØTá9ºRSSOœ8ÑÒÒ‚1¹té’’’T‚‹‹Ë›7o‚^?nnnø‚ –ê5⸢¢âرcðñYYYçÏŸÇË·÷%GGG'99ùÅ‹øÝ¨œœœ¢‹ïËÉ öÎùùù cüøñ`XÓ×ׇ—P(èp999·o߯OˆÍÍÍ•••Ó§O‡%ˆÝª««Éd²˜˜:Òîß¿ßÁÁ¡ï⊊ŠÉÉÉyyyxr$0+Á·Ñh´>Þ¿mß¾ýøñãø±H”ß¾}Kà]ÆÃÀÀ�xHÛÚÚ:::Ð!788˜F£á5°?ÜDâ(�}}ýœœ˜›úâj®"` ƒfURR¢ÑhPx› `ݺu7nÜÀs1½}û–ÃáÀÒ"--}ÿþ}:þþýûÚÚZD„ž––öøñcggg¼ÂÍg‡ †aHÉ ­­]PP�_Ë£zñxñâEZZÚÁƒK?Ò­©©âaèCçyyy¨3™LKKË·oß‚Ž2,\¸páÂ…>>>øM Òaª¬¬”””äÁï c?ÙIHHDGG3Œüüü†† BÕ××÷ððèèè())ikkãÁݾwï^˜_ZZZddd¸%¼°ÿ ßáU øùùÿ¦ŠŠJrrrVVA­Ö©S§Æ:¬———£LAE©°°J¥ª©©Á$ srr˜Læ/Â'=nܸäääÔÔTè�SSSSSS___Â~lMMMÛ·oï‡ Ò7pÁqï'Þ½{–¡^I©Tjaa¡¤¤ä÷Xo°/¥õ444,--…“—‘‘Qßp77·úúúþù,ÎÎÎðqqñÇãwRÕÕÕøsUSSSHHHTTÔÔ©Sׯ_ì3111‘‘‘PkEEE ýã¼ÁCKKKWW¾ÍÐÐpãÆø§`¾€°xÁ6SII©WŠ‹ŒŒŒcÇŽ}–ð±µµ522²±±XD˜L¦’’žÅë‹pâÄ (‚ˆˆÈ‘#GúøWÉÉÉÞÞÞFFF Rcnnîëë ïY±bÞ‘,??̘1x•ŒŒŒóçϳÙlggg´þµ´´<xpøðá`æCÄ×°/#8pàĉp1@.7n´ÒçnmmmiiéÕDSUUåïïohhHXÕ¸‘““ãêêzçÎ(xFFFßɦ>…²²2ooïE‹õë­­­íàÁƒòòò`/E½ñèÑ£:::ˆ›õS¸wïÞóçÏW¯^ÝGênaaa¦¦¦ÐÐÐÈÈÈ)S¦¬_¿žûF¤¤¤ÄÓÓsÅŠ : ¸|ùrqqñÎ;ñë.L Ÿ’Bø•Q^^îííýæÍ++«þ‰ï}WLœ8ñäÉ“p‘ãââBØ­R©Ô'Ožxyy©ªªîÞ½û+iÝ{Å—y¬=~ü¸ªª*66666–D"áõ¯>{Ö‰ýûï¿EÑÒÒ^ríÚµ5kÖàL@@�s�¹¹¹===±±±Ã† »qãJß²eKllìû÷ïŸ?^PPpýúõuëÖñÖtJNNNJJJJJâÁM›–––””ߦ¦¦F ‚ß¼y³€€€«««««+LgùùùW¯^ݱc·é«W¯N:õY͘ÖÖÖ¨¨¨††XoêëëïÞ½+%%Õ—#SËãÇcccýüüú(Û —s±±±|||ÁÁÁpñ¦¦¦U‘””„×#ß¹sç¾}ûð¬´îîî÷ïßðà^eĈ±±±{÷îݵkWGGGtttII oAõÒÒÒ¤ÿÏ\IÀš5k®]»ßfii‰4|øðÓ§OCÁ¥#ZÑñS3²$êéé-Y²„wåddd¸»»{yyÁö<%%ÅÝ݇Df/üüüLLLúg{6lXllì¡C‡ðµþùgllìôéÓñûñ^áää÷æÍ›ÜÜ\TíŸêêêB·­ŸB^^ƒÁˆ1bœ¿ñøøñ£¯¯¯……á\xåÊ•ØØØ£Gâ÷X111ááá¼UØM<}útÚ´i±±±‰‰‰¿ÚçÃÀyøð!w·oll„ ÐÚÚú³;Œ±äôéé鼕²>k`%˜ËKKK Ê:gÏž6lX[[[|||[[[FFF¯’'—.]ºxñâÅ‹¿&mË–-ÑÑÑÑÑÑ`pwqqQSSkhhˆ§P(¨°ÉÉÉ—/_¾}û67+÷zS__„™cccÓÓÓUTTâããKKKKJJ~€-»¶¶– ú¥¸{÷.Þ½ŠÁ`�ý;þ`äíí=cÆŒøøø¼¼¼úúú^¯Ü.þ}¿–#@II Ún²²²‚ƒƒÿøãøøø>ÔÔÔÀ›ËË˃ƒƒµ´´‹V¯}ØÓÓóÂ… hǺlÙ2%£Óé©©©_ú‘ÅÅÅ·nÝš9s&’Qï;zzz’““¹=ÔO¡°°`¾ÿ>ªv¼Ìî—ÂÈÈ|FzÍ400pÁ‚x­„¬¬,ðÁ#11‘ 5õ{aÓ¦MøËì_ ÉÉÉH2‡£Gçšï‡ï.ѶwïÞ>Š'vtt|øðaòäÉŸ]¥%$$ð={„ iiioß¾…SBTT”©©)·¥+$$ä+CA DEEñæ‚I“&½~ý.ÜšššÂÃÃMMMEEE7nܘ––öY üüü„‡‡£eee‡;Äââb>>¾ÜÜÜïí*úìÙ³ÜÜÜÏî‹ÑéMKK‹7Wn{{ûæÍ›AV --=räH(W}}=l¦ð¢v�{{û¯ ¥R©™™™øyMNNNVV²®©©ikkKKK7nÜýû÷I$þî÷SسgO@@�ÞwqÁ‚ðB&“I¥RïÞ½;mÚ´/ú΀€�%%%äËðEèììܰaa—ðþý{77·¾¼¼½½ 𺺼žß¾¾¾ººº¹Õ#GŽ?~œ`ÛY·n]nnî¯à^< ±aÆôôôþiþ„%GEE¥¢¢\€0 ƒ…DGG§©© ÁO?55USSSFFÆÈÈèõë×°¥566×ûE‹Áï»»»ÑíVyyy`` ¸ åååá—à9a˜¦¦fYY$ÊÈÈ())­X±­@fffÿý÷ßgu¯?…áÇ+**ÂËÛÛÛá¾´¨¨ˆÃáhhhdgg×××ÕÀˆ#FŒâ`‹wöìY¦ðøñcðäãã[¼x±  à¬Y³Ð›‘í¾±±Õ§²²²‰‰ R~;s挀€Àg︱xñâèèh‰Ä`0,X€a˜¸¸ø¤I“ £¦¦&˜ëêêjkk'M𤢢R^^O9Üöëêê’ÉdB³bæììLP755‹‹ƒ(e¨!!¡™3gÂß¶µµÍš5KSSìu†EDDÄÆÆnÚ´©ß½vÞ¼y/_¾„ê§§§çÙ³g¦¦¦]]]÷î݃H”æææiÓ¦éë룬oß¾™™‰$ï Qåëë뫨¨Lš4©ºº555‘sÊóçÏÑÍ™™r(hii™>}:xÕ)òòòPîüñ‡¢¢â”)SŠŠŠàã'Nœø)ÿZ###ä‰}IVVV]]ëêê&Nœ›Öºº:HäããSWWÇ0LOO¯¥¥•••û~1dÈèKŸ‚¢¢â°aÃàµ]]]àTPPÀÏÏENNšé&Ož¬  0cÆŒüü|ð>Ÿ<y2ë,\¸ðÉ“'C† a±XxEÚï 33³Gñóó÷ôôÀ1…F£¥¦¦¢ñØhkk×ÔÔ@% 6씩ŸRAAA‡c‡Á`¼|ùrþüùâââ'N„'“Éøû¶·ä(((à ¯FFFDÍÍÍÁÓÉÖÖöÖ­[<�»Üç§¥¥ 6LFFæÄ‰GŽ/ÞóçÏÃÕ«Ï–-[0 “’’B縡C‡ÂÅ5ÂäÉ“Ùl6;Î;œ¡­¬¬ÂÃÃ!;;;;ÂîÒÈÈè‹î뤤¤ð]jâĉl6œôfÏžmcc6hXrV¯^}çÎÈzÓ¦M„èä¿°xñbA€ bñâŧOŸ†‹t%%%¸•——×ÔÔ„b6mÚ4¼‰––^uLMMñ»B__ßM›6YáÅ‹¡<›ÙqãÆÁgÔ××gffNš4iöìÙl6›Ð¬666¨Y7oÞ SX¯5|ùòå]»vQ©T>>>0ZJJJºººÂ݉²²òÑ£Gñ¿WVVþóÏ?¿ÔbƒË=þü¾}ûÀ& §L&óéÓ§¦¦¦òòò‡§ uuud±Dv‡ÿÖÔÔüðáª|iii•­[·zzzBâþýûaŽž7oDê�æÏŸì¥‚‚‚øm¨««ãÝ[ôôôž>}Šr9r¤¢¢â¾}ûÎ;wÇŽÇÐZXX Î &&æææŽgŠŠŠ S«¡¡±~ýX FŒ�� �IDATzM†††°¢›˜˜p8 µ´´„ÜÎÎ. �²vppàá†ÏTTTi˜`C‰þû矢º‰‰ÉÊ•+a»&((8vìXƒ/^ òŽ=úä©S§À{âÄ hâ«W¯nß¾N§ \¿~ý‡ÍÅׯ_ß¶m“É/y*•úâÅ 4?ÈÉɘ)cÆŒÁ»ü­\¹òîÝ»PÌ7~i?ÿ066ÆŸi.]º´{÷n΃ƢÓéÏž=›?þˆ#œœœÀGSST˜¿9>£ :0ÀCô7Å ÇÚ¯A޵߃kŸíÆßVtcmƒÄ ñƒ0¸ä bƒÄ ~†|ê=`Ž™BBBưI‚‚‚¦™àvdÈ!¦Dp ÂÏÏ?`JD"‘zzzØä�sÂ@J09|“ñóóïê÷]rº»»ñ®�l6;//o ©0Q(”’’ñ’¿êêêR577·µµ ¤¡D§Ó Æ�› Ƈõ�@[[[EEÐí=xЛ%‡ÍfMÀ€9ß`N£DàãØÝÝÝG—¶ßâ”Ãáp Æ€éx|||l6›Åb ˜‘H$‰4 '*•Ê;jû7‚€€�Lߤ™øùù¿í$Ó{-‹ˆˆð&ù½ %%•™™9a„ä±V[[;vìØAµ_yä×ÕÕ1™Ì3”ÀcíãÇir””ÌÏÏ×ÕÕHk---ƒª ƒÄ 1ˆÿßñ™³äÇSRRÖ­[‡RRSSªrîܹˆ8àþýûÀÝkkk‹Î puuݽ{7D,²Ùl (–@LÒµµµ·¨®® †eeeA ÛŒ3P¨Ð£G0 û믿[†ŸŸP€lß¾Ï8Éuuuááá œx÷îÝíÛ·1 ›2e 7Jdd$\Z[[hó/]º´råJËíìì |kÀô…aXGGH9 >ÜÑÑýá‡233ñ$‰‰‰>Ä0ÌÔÔ´/œîîîëׯÇGhB¦¨¨(â2ihh€8AUUUˆÃåÆË—/ ba‰ˆˆ€°D0èééY^^ŽaØÞ½{ÑëØ±cÝÝÝ|||ˆ’µ­­ þ­¨¨ˆä! !°×ÀÀ೑x\¿~ÝÌÌ OüsâÄ `Ò;uê^¦Ã02™ìîîŽa˜ŠŠ ^²ðŒŒŒÊÊJDj (¦8((î*6oÞ¬¦¦†þöôéÓÛ¶mCq,ëßÿ%ôaHMMmiiÁÇFGGCäªU«P°··7hÒìÞ½ zìØ±#GŽŒ?ÍÍÍ¿üüü·oßkZZZdd$zdffABaaaܺvíZ‚zÇ?tèЧ.9ªªªbbbð”ÕÙÙÙ@õ;}útnÊÈððp †Z³f ^Sƒ0p0 ;räƒÁ2d’>û18tèPOO   èáQYY ñ¡šššˆr÷õë×ÀVedd„xÕzmÖŸˆ«W¯.]ºσpüøqF"‘ðb`h>Ƀ1cÆ| ?HN9åååŽŽŽ‡ÆK›¤¥¥½xñbüøñãÇÏÊÊ‚ázÿþý²²2H ïõjñĉ×®]CÆû÷ï‡ß>b§ëëë¯\¹‰t:Bʳ³³cbb ±  �bz=z²%ãǺVXoººº ñúõë ¤ÂÍÍÍŽŽŽÀÓRåååEDDÀ{JKK ŒU‘‘‘ÅÅÅð422òÝ»w葇‡Ç¥K—%â±cÇ”””à—êßÕÕuâÄ HÙ¿¸¸ØÑÑñÈ‘#xšŸ¤¤¤äädøå«W¯@½ñS8þ¼££ã•+WðL¦¨z•””`É=SHd±X½u'$$œ8qÉÉDDD”––ŸDDD@³^»vÍfCâùóçAÁáÈ‘#£F?~ü¸qã`©£P('Ož„Ÿ ^¸p𢢢۷oCb]]]iÈ}||=<<ð4Ã...ÇÇW/¾YÏ;8Ò”Ã0,33ÓÙÙb>{ö,++ ~ j:°Þ´´´@¢¿¿?,®gÏžutt¼zõ*ž U²‚‚÷ …Ç›7o]\\ðæÑÑÑEEEð†�C ——ÈJ?þÒ¥KPäãÇ;::zzzØ[[[œœBCCñ‰ïß¿?zô( L 䥥ÇÿeeeKXXXee%$†††öʯêììLÈ”F£!‰††GGÇÿýö`–““óàÁxmQQþ¬7ð4,, ؃®\¹âèèˆ80﫪ªŽ?^]]6¦?TWW?~¼ªª*D¹ººÚËË >žB¡øûûC³>yòsssA•Ь [õ³àéééèèxñâEP=zTYYyüøñšššNNNøß766^ºt >žÁ`ôQ·÷›rÄÅÅ ?|øðñãG”XTTÔÞÞíqæÌ™wïÞÍ;÷õë×pZ·n]UUAÌÅÅEII Ï4lhh›\P=zôh[[[JJ 9Ô××`&##3oÞ<PôôôÌÌÌ477ÏÎΖ€ìvìØQZZúÇ<þÜÎÎN]sçÎ]µjÕg%T…„„ «««ACíeÊËËašö÷÷OOOÇtÞ¼y£ªª Yoذ¡²²öþ"""x§Ž{÷¥CÌ­ÝÝÝ111 Åøþý{‡={öHHH ã™}?|ø@£Ñ —·oßâëZZZÇGbÀhŸŽWuvvîèèHHH€c(M:‰‰‰ÉÉÉxãï¨Q£ttt€ËÞÞ¾²²RGGçÉ“'ò¥˜˜0˜›› °X,eeå3gÎtww?zô ›››ëèèèèèXWWWPP�;Œ¤¤¤¾tÆŽ+&&F N Å«‚ⵤ:;;Ÿ?Û·ôôtWWW8èdgg?xð�¯9;¨çŒŒ IHH°°°€óôâÅ‹ÉdòèÑ£utt€ÿ ·o߆}F{úô)"ÈÊÊøÔ•••544@dÓ¦MåååúúúqqqxUÐõë×6L__ŸF£V莎ŽÿþûOOO1¿aVPPpçÎuuuäǨ©© ²?ž4i°V«¨¨�U ­­muu57¿ª¾¾>•J A)L&óîÝ»pì144¬¨¨À“ó———×ÔÔÀ²äåå•‘‘?è¼zõJWWdñÖ¬YS]]­¥¥4ŒH ´ž  Š—2ù®¸}û6^Àjnn~óæ ¤<}ú4((ÈÞÞ„M†ØÃÃ#''gáÂ…#GŽ„N•ššúsÅr444¤¤¤{Ö{÷î­'›Í9r$ R€°°ðÌ™3)))éâÅ‹ŸU%þ–KŽœœœµµõ‹/ðKάY³š››Áê5f̘>’îÅÄÄ„††‚­°jÕ*:¾}ûv!!!dwÂ0¬¬¬ vÇ`+PQQýÁ€€�4Û¶m{ðàŒÕ«W÷Ű&..nmm——‡—P›0aBii)PYY¹ÆŸ¸¸¸ãÇsw¯íÛ·3 Z ÖÖÖ±±±ˆwáÑ£GK—.å]ɦ¦¦†Á1áÚµkp(ÀW;Q©Ô & Ác` HNNž4iþÆøäÉ“eee...À; v*&“ Ƈ^1~üxccc¨[EEEÄ­ÉÀâ¦N„3gθ¸¸@¸�(K~•••µµµ³gÏFÇ8d~üø±µµ5h|GtwwïØ±cèС¼I¸ÕÔÔÔÔÔºººð¢ÈäróæM]]]_°é!ì÷»»»ãâ⢢¢ðKQ}}}QQ‘ž›ßùùùÁ5lÑ7nÜxõêÕ´iÓzµ„ƒ X"""hi—””´¶¶ÎÊÊúJ=X ÄÃÃcïÞ½,‹¯|©?ªªªªªª0ü©T*^)êÖ­[ 7nüÞ𼔕p&ë $%%¡«ÇÄÄàå’„a­WTTTtvvó#‰D¯FŸÂáÇwíÚ…'~ÿkÝ!æææ³fÍBF€ŠŠŠK—.™››KJJâ5”••ÍÍÍEDDÀ`eeE¡PììììììP‡ó|X^^^¿Òëëëëêêà=àÊ‚ºzõêÚÚZÈî®0 sss³²²þG<Œ-ZDí ?~œ““cnnž““ÓwÍfürµxñbsssccc¼ÉîSHHH¨­­]½z5÷#}}}ssóºº: f…;9EEEsssWWW¼±káÂ…fffpÞ’””<|ø0T²Æ455•••AÝÊË˃‘§xöìÙ¬Y³àU„ž¼¼ü®]» ë'N ;†ôôtî-[DDDII‰¹¹yRRo&7zzzÌÍÍÿøã`ØìnÞ¼ÙÑѱtéÒ/r.êêê:räAפ°°ðáÇ„{ÀÇY,árΦUUU}ŸâÔ~7Ùš5kJKK¡]«>Ož<™?¾¹¹¹©©i?:ÿF|||zzº¥¥%º»uëVSS“¹¹yLL Ü]ý^(++»víš……^äGœrx,9Ðw 6·O­7ÚÚÚK–,áŽ$âçç_²dIcc#²ƒKKK¯X±bêÔ©/_¾Ä›àá¬ãéé 6MMÍ¿þú ôÆÑÒòæÍdX»té·î†a666À",%%õ)†ÚúúúÚÚZ( ¿¿nn.þ©ŽŽh¦íâìÙ³rrr–––ˆåaÙ²e|||ý8œBÇ÷öíÛâââ/ýó˜˜0¬}öf;)))>>~ÕªUZZZhùÇû&L˜–œ¹sç.]ºTJJÊÕÕo,Z¼x1‹Å+–¥¥%˜ªÊËËàÆÊÊÊà¬�†5î DG;w‚Mµ×cåÀ°†<M�¢¢¢–––ÀI\XXÿöíÛàààÕ«W€ÁAWW×ÊÊJMM-99™ û÷ùÍߪU«æÍ›W__á/E@@@GGDze˾h½¡Óék×®566.--…ÄââbOOOCCCp<Á£¸¸˜Ífƒ&Âĉ'NœÒÐÐàêꊮ`ÝÝÝ{5J÷ôô|VRôôôøøøÀˆÍÛãöñãÇgÏžÃÚwÚh+<þ<99yåÊ•xQà‰'.[¶lÔ¨Q>$Háýú¨¬¬<þ¼ÍwR.À¾·D[jjjFFó[ZZìííïÞ½+**ºjÕ*îÛcIII“’’’••EP%Á¹GlذþÁûv„7´´´À:×¶™™™d2ùÑ£G†•––:::úûûƒ£‘‰‰ ???¢ÊÿÒ3;a‚ø~¨©© ‡å¼¼¼æ&+++??¿^5Ä&OžŒ'áÇ0lýúõW®\!ì*„……Áè—›› KN_0eÊä‰÷û"ˆ‰‰AÖÒÒÒñññMMMà aXmmmGG‡ŸŸßúõë1 SWWïw.|||èSûÀÀÀÖÖÖåË—öÒ‘�‹õðáÃÎÎÎk×®Q©Ôªªªýû÷¯\¹2** &t2™ÜÐÐpùòeîðññQSSÃkv˜™™¡)æû‰wéèèÀ-/ÁLú›âåË—/^¼°µµ…¹?Eü\{Ú×L®®®7n$ˆæýNKÎùóç‘'UNNÎæÍ›áÂiÉðFcc#Á´çVQQÑ~ˆ¢e(è7†Ž×L;zô(r¶qtt\³fÍO”Ûë·ÁÍzááát:D>ŠŠŠúX]IIIgª¶¶¶={ö€?ôaܸq_ ÚÐÐàììŒ?%Oœ8}I|||aaᯠ&ðñãG%%¥/]oàyÿþ}øw]]«««µµµºº:R{õêURRÚ+DGGS(”5kÖ 7€lÞÈö½Ë{ýúu55µþ© þš¨¯¯ïèè ¬7¿5¨Tj~~þw]o¾xÉY¸paGGl!ŒŒàv}ëÖ­>>>¸råJØ.ýóÏ?vvvø;gAAÁ)S¦�wBdd$ü^\\<((¬gŽŽŽ¨¦¦Ö¶Y³f‘ÉdHœ:u*SŒŒŒüýýáÊÑ®Ȏ=zùòe¸ÞܶmxãôS§N­¯¯‡ !æ 88˜ÍfÛØØÌ;÷Æ Tµ|ùòiÓ¦á]@Só;wÖ¯_WñàÛ-%%uéÒ%x³‚‚Aí  ‹;wîÀ/çÎÛm’@”€ˆˆ¯9òàÁƒðNðJIIILL<xð ¯ÉÌ̤Ñhà|±uëV___ø0xbvúôé .€¾ÜÑ£Gá<wïÞ½µk×B\Äl‰‰‰­Zµ þvøðáne``°dÉHÔ××ÇG&})‚‚‚¶mÛÖÙÙ } F‹½½ý½{÷†ºhÑ"ÈeÔ¨QgΜ‘––FVéÊÊÊŽŽè«V­ „_.Z´jìÀ×®]'{{{nW.„ˆˆø[ ‰€€€~”ÂÓÓyá:thæÌ™®®®àåääÔ«ÁŸŸ§´´TTT ”‚îh*¬©©éééÁ«¸îرÃÛÛ>~õêÕ}œbÄÄÄxûµãGë”)Sà 3((HHHhÅŠ¦¦¦>>>pÿ´jÕ*Úe¡¡¡«W¯†¸´¸þ�Ü¿ßÊÊ ârÀ†ÑØØxðàÁ7n¨««oÞ¼Š6nÜ8t= ‰†ÙØØ¬Y³fãÆ~~~heeÅ-éöÓlooq9H¤xÛ¶mpô,++C%š4iÒ÷ˆ‹úŒD…B!“Éxã™L†óûðáÃQ¨ZUU¸~«ªªÂ6¿¸¸xĈx©Ê¼¼<MMMˆeãp8à±. €<ªi4˜Ú%$$Ðm|KK Ù‡ †¶„µµµ 0§ ±È’’¸ÚÑÐÐ yxH´Ñh´ÊÊJüV¥­­ .Šäää`ò…k Pb®®®†[œÑ£Gîo UTT@ðwïÞ±X,ü’Éd‚Å\DDoümoo‚ üñB‹{Õ &H´½ÿ^]]o0ÌÎÎ†é …pvwwƒÿ…¸¸8¸>·µµµµµáý†Øl6f…Óp7?žPX‰„6 N¨øÂvtt@œ£ŒŒ A,œ7áÍÇ ݉Édb<F,ëýû÷à|…J*&&F°O677S©TäЈÜ"”””‡KYYY[[†acÇŽÅKAççç7ÅEöÚ‡ñ H´‘ÉdƒúpMM þÞ?pÀ0 ©©‰?‹¼{÷®ñYÐétˆÂ'¶···¶¶¢fmllìéé!("WVVBL•ššÁLŠ!S‚D•J­®®Æ×0­òòò°^ÖÕÕñññAF™â»÷ÀÁ0ìíÛ·l6ß¾ðm999‡¢¼ Fqq1tÈ®®®¢¢"ø=lYPah>DS„ŠŠÊOq’&H´)++ú~jêéé)((ÐÑÑAÕ̘1c¾¹DÛ *èo‰AUÐ_ƒª ¿UA?ÛUA1ˆA b¿%—œA bƒÄBïîüüüˆ¾p`à=ÀTAÅÄÄL3AÓ °  ¤¡D¥RùøøR‰`(IHHà/“@Çý&ÍD"‘ÀOçû.9MMM@¬9`ÐÓÓãëë;JD§Ó£££ ÷É¿5˜L&‰D†ã‹Åb±ÒPâp8ˆuwÀ »»;00p ÉÑ2Œêêêo59(((|ÃÖÞ—œ¡C‡"W¹�)))KKËÓ«ÄÄÄ=z¤­­-''70J$,,œÍÇÇ7`>|ø0}úôs àãã»ÿ>·0Áï IIÉ   SSÓã> **¯¢¢BpSìw7æp8x.êï²äH¤¯ ÑÿÕ�e0KމD2dÈ€i&AAA~~~>>¾S"!C† ¤ÇÚÀ› D¦PBBB|||ßjr�µoøyC>{Žf³Ùxík6› _�[B"ôHnóð¾à¦P¼:Jäp8à-=›ˆ²Cy9mß—îrçˆwIQéßÃ]À^sä.5¡€½~w JÝÇêíG³¢òâ¹³Ãórä®óÏ¢/änA”/J!Ti¯¥î5Gî>Ì£€½eÄ£/}ªz!;BIáz,øDî2òA„,¸«÷Ž^ËK`²àñß_Ô©ú7þx|ÑØéßðü²³2B¥RŸ<ybccƒÿV___àÙ<{ö,Äâ1Œýû÷CbDD~lcÖÝÝmddO«««¡{utt@ʤI“ DŸÍfgffB"H@eCâ‘#G »S§N)**ªüøød:nff–••ÕÇņJ¥fffâI8X,Öýû÷áÍNNN ÿ'L&óàÁƒð4,, Jjkk‹>FAA¸¼h4šžžžŠŠÊèÑ£ñÜ—'//Å$³Ù츸8ø[ÈîæÍ›è…ŠŠŠxîntwwS©ÔÉ“'Ù(€J¥Ž=ZEEEOOª—Ãá¼{÷ÞieeÕÛk³ž9s5«““ªd(,N_ºt)$æååAkÒh4555ÈŽL&6 •ÏëÎb±BBBb<@§Ó©Tê¢E‹ðôÃ4mÒ¤Iðrk8‡ÃÉÏχG–––PRTÉ***#GŽN~&“yöìYHôõõÅÏtt:ÝÊÊ*55Uò¬Y³à—ˆ¨½pÔ¨Q'Nä=‘Q©TOOOµ¹:tÞpïÞ=T½+V¬€Äœœ˜¹h4•JUSSC ‡§²²~fll él6Ì)***[¶l¾ÔÓÓsýúuH<þ<´ìþýûGމ¾¿Wö)ÈT]]‰Yp8ôo˜ÒÒÒð"§,ëÞ½{ðÎÇC^ cïÞ½ð4** •wÉ’%øáÃèNúúúèÛúÍ€×Ðh´±cǪ¨¨Œ?••7-- >iíڵЩzzz!ñ¿ÿþƒò2™ÌÇšõgÆÎüùóñôÄø©‰»˜T*õÕ«WxN¯·äääähkkˆ÷oß¾]\\\SSSSSC"‘€µåèÑ£:::M`8_ºtéÍ›7á©‘‘DV;Râââ£×Þ½{!q÷îÝÀ4˜˜‰JJJˆ}áðáÃ5ÿŠJëêêZ»vm× ꪪ´µµ \mOž<‰‰‰7kkkãç ÃŽ?޾<66h󃃃!¥  ÀÀÀ�v)))555UUUhذÙì>à›óõë×·nÝ‚?Ÿ;w.pÀ¬_¿RJJJvìØÁÛļbÅ mmm K@PSS«ªªª©©III�ãÒÒÒ­[·Âkœœ:@aaaÕÕÕ𔟟DJŽ=ª­­ ‰111À"¼bÅŠÿý«ªª0 ÓÓÓ{ýúuMMMYY¢RTTDmƒæÙôJ°ÿ)lݺU[[›@wÿçŸÆÅÅÁËI¡²²UàáÇ—/_ŽaØüùó!¥¬¬ÌÕÕ|“._¾L"‘ ½¸¸qMvuumÚ´ ´„¨™fΜ <ðßêêêÄÄD EˆŠŠÒÖÖ&p‡¸¹¹ihhÀKž?Udcc³{÷nHܱc05Ì™3G[[ï5ÔÑÑaee?óòòZ°`†ah ™™™íܹð€€�Ô²$ qÍ;wµPF`bb¢­­_Î) R^/--ÕÖÖ^¹r%a줧§Ã;aÆ?=tè< Y¶eË–?~×®] ´&ùùù’̓á›CCC£   ¦¦¦>ü£ÜÜ\ôvvv0+FGGB¢””Sý÷ß***˜žžþ5ÜÛ_ 6hkkTBfÍš•––VSSSYYIXÑËÊÊ´µµW¬Xñ]¿ê“‡Ö‰'–••½xñ/G*""ÂÏψ:¸% ¸órss3‹Å’••…ã§¼¼<¼¤¥¥1ÖÀ”ÔÚÚª­­Í›²³³þ\RR¹6ÚÛÛ;88àõ˜ycÔ¨Qeeeyyyx‚t!!!!!!xyOOï©„�sssOOO ‘••miibRihh°¶¶SH™2eÊ”)S F[[ƒÁ dçáá!&&F ç'�X’4Yòòò@¹A¡PðÕû)À D¥Ra^ƒf•èé骀jA¿omme2™Ož<áqúf³Ùð·ˆèåË—aaaW®\é» ô¶ ª¶ïmúþý{`úmoo‡äççGŒ [·nµ±±Áw$˜8 ËÈÈàm­­­æææ½j9#XYYYYYùøøàùQú…Bä±±�ùj<?””Ô›7oX,VsssGGTïŸþyëÖ-ØÛÒét¼ƒ,´ìÖ­[Ñ€íè耂KIIõš5œððdH$ õ%uuõ²²²¬¬,¼`³™™™™™YwwwGG‹ÅÂsAwb2™©°°0\3HKK£±,%%E°Ñééé!ÉŒ_Ë–-ƒ +•Jåp8x6& …B£In¨“�� �IDATÑN:õs¯¡?øÎÁ#”L&³Ùl‚óј1cÊÊʲ³³¿«þ÷—yÑ-Z´hÔ¨QÆÆÆÆÆÆosã cccèô=‚—üý÷߈+Éd&&&ïØ±¸˜z…¤¤ä;wàÏoß¾ f«ææf11±¯÷9™>}úìÙ³áå%%%ø§RRR===°…!œIÉdòСCWXX˜­­­±±±‰‰ L¯l6›L&÷J˜–ššjllœ––öÏ?ÿà{-‰Dú¢5!66ÖÄÄÄØØØÖÖ¶ïÂaaaÆÆÆ,ËÖÖÃ0‡’’¨ŠÙ³g#·+2™¼qãFccãׯ_Ìî„ËøÛuëÖÁœB§Ó»ºº¾ ëÔÝ»wÿþûox?(Gào&dee¡3šy b÷ý$xɨQ£`Ukiiíu¦°¶¶666 D7‡Ãihh�ò½þ¡­­íرc .쇃hcc£±±±³³3^U³»»;***## wvvzyy_½zÖÑ¡C‡^»v ìu¼!&&Ö’ÍÇ×ÖÖd¢vîÜYPP�™Î›7È/\¸€¾äÔ©SøÑQ[[ûM®¾7ºººnܸDmêêêjllJ˜%~˜™™Í›7ï§(à}Ù’'ƒ¼¼<‰Ôw÷üØØØ¼¼¼%K–À>ÚÐÐ^Žá’’’ÀÀÀ¼¼¼ 6€a­WìØ±#ïÈÉɉ‰‰ill<tèÐÆyË •ýøkž?þôéSx¹††ÆéÓ§ñOœœÚÚÚ@Œ’ ÁkccãììŒØHçÌ™óèÑ£¼¼¼wïÞMš4‰Ífçææîß¿¿×ƒ¶‘‘Q^^ÞìÙ³ñrjP·¼8ŸÂ¤I“Þ½{———÷èÑ£9sæôñ¯Ö®] rÅ0…>}ZCCªâéÓ§ÏŸ?‡Ÿ8pÀÅÅ%//o÷îÝ` ᆬ¬,j£'NX[[wwwÇÆÆÆÇÇó–nnnFÍ䡽bÞ¼yáááð~ OIIÉÓÓÚ¿„cöðáÃÌÌLd,;xIYYYXX™L>~üøŠ+zeE{òäI^^Þâŋчuuu-^¼¸J½öôéÓFFFý31"//ïܹs`<3ýÇÓÓÓñêãÑÑÑüüüyyy 4‰9‚Z'***))©®®U;áoZè YÜÒ¥Kóòò”••‘j5ÀÕÕUWW2}ðà ŸuëÖ999Aâ¶mÛð‚f'N컑ügB¡2 <-ºÏü‘———œœüs k<ðæÍ›œœœ¾³¥ýÃÚ·Byy¹¢¢b_Üõ455ûBßÔÔÄÇLJß,8p`Ê”)rrr………T*µ¢¢BGG‡ûÄckk ÷±ÒÒÒõâ¾ãÀÀp‚o}Ü YZZÆÆÆVTTÐéôŠŠ *•ÚÒÒòMØ÷¾íííÝÝݽžÀ¸qãÆ ‚¥›,«¼¼/!‘}åÊ•+W®ÖÕÕuttÔ××sŸ‚‚‚Þ½{ÿ>qâÄܹsûQœÑ£GÃl•žžþEìëÇŽ?~üÈ‘#¡#UVV‚EßûpßA&“/]º4yòä~ĸ°X¬²²2‚ö9F{üøqJJ A ÚÚÚmÀ‘WXXMròäIŒ'5ÿ¢ù·³³Ñxtttܽ{·««kß¾}øôýû÷ÿõ×_¿ìg«ªª~?‡´Ÿ¿äØÚÚúûûîx¿^^^øQ¤¬¬|ëÖ-0\–––ž<yROO0 1 KIIùJŸÅºº:AAAîÛ‘ÒÒÒ#Fd¯Öeee8²Ðéôššš'Nøøødee]¸pTS Ë*›Íþa,ÑQQQ¹¹¹nnnßê…---HÛÌ2t:j ½½½££# €p Á0l÷îÝ_çÌ`0ÊË˹5UÛÛÛ) ïÕ]II)44´RÊÊÊÜÝÝõôô´µµmll=ŠÃáðÔáK—.)))-]º´“û¢E‹ ñ‰ÙÙÙAAAH€‡Ξ=k``�æS�õ¦¾#>>þñãÇø«ß~#??ÿ³ÛšŸŽGåççƒÔo„E‹¥§§ÿD%É/[räää„……‘ûìR•••i4$JKKCaŠŠŠÅÅŵ´´’¶¶6rè‚ßS(Ð8QQQƆX¢¤¥¥%%%!i(**¶¶¶B¢¸¸¸ŒŒŒ³³³³³3²Qþ÷ßÜëM1tèPiiix9V©ö#FDFF²X,+:t(j¶;v?~?ÍéééåååÑßÀÀ@TT⊋‹íììÀn&!!¡  �Ùµ··£ÛÚ»wïÒh4{{ûþ•ÂÀÀ�¶ùT*ôr„……UUU!£ÚÚZøÔ¶¶¶ÖÖVUUU|³r8Ô¬àDŽoÖqãÆÕÔÔ@â˜1cà(©¯¯Ÿ››+,,Ìf³ÁAnÈ!(;MMM===T±±±ÜëMß¡««ûþý{ð—ƒY,V^^ž¾¾~ssó±cÇ`ã‰Wsyùòå«W¯ð×ǯªª‚–““³³³C·úË–-Û»w/L|ЇÛÛÛñ}˜Éd.]º¾¡@¹c¦¦¦&--=vìØºº:HTUUýÔå3??¿––,hÙëèè@/”••=z´¼¼<ÊéÖŒ5ª³³eeeûè†×^êøÑJ§Óau¯­­åãã>|ø¨Q£ººº™jhh ^¼àÓ‚ N˜?�&LÈÉÉ2dƒÁ@z9EEE:::¢¢¢JJJðñd2ß›ššP…1BQQQII©»»%%% ’Z¿`jáp8H/çýû÷¼÷Ç-9RRRx1±E‹±Ùì#GŽÀÝÚÚÃ0‡Ë—/Câ¿ÿþ 3²ŸŸßÚµkµ´´¼½½7mÚFÿàà`ðëxøð!èñHKKƒl¥ŠŠÊ±cÇ@­}„ 'OžÄ0ÌÈȈÅbÁ›---alooïç牻wï&Ø^´µµ ®2¼!** k`Ú´i(G33³íÛ·c–Àf³­­­·nÝzíÚ5xúÏ?ÿ̘1eJ¸ç Y¹r%ÜÖŒxÂÂÂÈÙT__ãÆp…cddäääé°ZуŸž?~lffKZHH†a#GŽ<yò$ÜéèèÀÝòû÷ï8`ff†oVð qpp¸rå $<xpÚ´i†¹¹¹íÛ·îK½¼¼Àж|ùò®®.>>¾‡B³^¿~óÔÔÔ®\¹Bظ|é©—PÃwîܱ±±imm…¾sÜéÓ§ƒƒƒGŒáææ¶iÓ&X*Э†¬¬,a#bmm}ëÖ-(àÖ­[ *ZZZÈéËÇÇçï¿ÿѼ»wïÂq–D"ñ¶äÁŠ8zôèððpt]ñï¿ÿΘ1ãÔ©S¸yó&†aW¯^ERr†¢`C ???h¦Q£F]¿~&8!!!(†aÆÆÆûöí[²d jÙ5kÖ€[ó®]»<<< ñÈ‘#<JÏTLLŒàŠ"..Ž?‹Ìž=åeaaMðüùs!!¡åË—ïØ±ãÒ¥KðôðáÓ'OÆ0ìüùó{öìaF___dÚýóÏ?|ett´……“ɆÃb[[›‡‡‡¯¯ïرcœœÀ¹ßÐÐ6¸òòò­­­¨Â­­­mmm7mÚäåå‰û÷ïÿ¤’tttðÞt¡¡¡+V¬èìì$‘HàzÓÕÕåææêÌЬ½J~+ J´ý–”hûõ1(Ñö[`P¢í³ÝxP¢mƒÄ ñ[bpÉÄ 1ˆAü |’IE5 ÃdÈ!¦™àNžŸŸÀ”8ùøøL‰H$›Í`“ÃÀJß¶DàOñÝ—ƒñ5®8¿ 8NUUÕ@Ra¢R© ß¶7ü\477 ¤ŽW__O¥RR‰º»»{zzØäÀd2kjj’"Cgg'zã+ñ ¥ {_rèt:P   r8œ’’’³ä 2„N§×ÖÖ"ª±pÊXŸK¾ûmG)› ˜¡ÇÉd¤ÉA@@�"—btä7Ÿh4\“n,%%õ ¥ {_rÄÅÅŒ”!†aRRR………Ó§O`kºººƒk¿ò\kf(ÇZ]]Ý@š$%%+++'Ož<è±ö©n kßl+† bƒÄ ñca¼WVV¾}û£óîÝ»—/_b6yòdˆçÂ0ìÅ‹ dffö©È??¿Õ«WC›Í†ð@QQQ$ÉC&“ƒƒƒ1 SVVFD  Àc``0sæLHLIIøÞ¹sç¢Mqtttyy9†a+W®ì#]†aMMMñññxå?B𦮮.7'æË—/ÌÔÔ"Û###ñ<¡k×®…@}ooïîîn‰ñ­ŽtVNN¢h¡†###1 ÓÐÐ�á“·oß&$$ Μ9‚„y ((ÈÂÂÏWùòe‡#,, y†577ƒ$ÌÈ‘#?W‘™™Éd2;*jÖ… ¢àͰ°0 _´µµELw^^^t:‚g1 ëììÝyyùÕ«WCbyy9¨-hjjâ•ñ>‹ðððéÓ§ã£)}}}D|ûöíCskk+ĵ)**ÛUYYÙƒÐôõõ!V&=====Ã0###}ýèÑ£ââb 쬬€ðj"O7mÚQ·x~RIIÉuëÖñ.»wïÚÛÛQÆ0,!!´L,X ¡¡‰÷ï߇¸ikkk¼5ÃËËkÆ Ƕ¶¶‡ÝKJJ>~üˆ¨©srr€÷aêÔ©ˆ5>>>??ðŋóAë5S„†††¤¤$<ŸXaa!YN˜0é" L-Züááá` °··—€)‚‚‚[¶lùa³áÕ«WY,–€€�7­p}}=DU«ªª¢ù0??„þøãˆ•Æ0,111''‡Ð¬?!!!sæÌAhà€ /–ˆ€ ®øÝO9µµµîîîgΜAÒU0l?~L¡P(Ê‹/`¸>þ<==ï߿߫×××÷øñ㨨.\€ß744�IssóÍ›7!±  �hÒ £££!1%%FNJJJRR$>xðàýû÷0ïçççCb`` Rôá¶¶6ww÷³gÏâIPŠ‹‹#""à=éééˆ>­7¯^½‚§‘‘‘?~Ä0ŒJ¥Rþ‡Ë—/ƒì‚§§'™L¦P(†Ñh4OOOøYyy90ÂUUUݽ{³²²€K<==ýÁƒèOnݺåîîîìì "ÀÃ㣣ƒB¡ÉdOOOèL~~~ðÂÂÂÂ^ 233Ož<‰x‘ñͳpHHHQQ$Þ¸q£­­ ðk×®555Q(”ööv œ¢R©×¯_‡Ÿ•••Aª¬¬ ÄÌÌÌ>’ìÞ¿ßÝÝÝÅÅÏZíííÝÐÐ�¯ºpáþ÷ííí¾¾¾ð¨¨¨¦ &“‰ê399¶ééé/^¼€ÄÇÃNâáÇoß¾…ÄÛ·oÃâPUU‰W®\— ôN¼~7òóóÝÝÝOž<‰/rBBBZZüyTTTQQLÁ………èïïu^^^îîîÇŽ#HEttt¸¹¹˜JKKOŸ> ¥†õæÉ“'ðÂçÏŸwç³gÏÞ¼y‰À ÏýÍÞÞÞîîîÇGÄÒt:ú†a---0v` …Ö›¨¨(xmjj*~Ûë Ê4<<ÄsñcÇÃúÓéÓ§›››Qú›š/_¾ÜÖÖF¡PZZZ®^½JX\ƒ‚‚à{€~š5&&AÓ/!!!555+ï#44ÆÞ,æææSwõ655]¹r=ÂËÿ SA#ðìììææf K9sæLJJÊäÉ“Ÿ>}ª¡¡„`ëÖ­ÓÕÕÅSØ~*<@Ü©±±ÑÄÄdÓ¦Md29&&ºiEEEFF†aG[[˜H<==Ÿ?>kÖ,Ð8–2ÐÒÒ ³³³„¹sçšššöå’ƒ»€EEE>|�Žwÿ§OŸâ5ãââTUUáX¶aÆÂ±cÇ¢óŠŸŸßßÿ ÿ‹/¦¥¥IKKs8œ#FìÞ½›J¥úùùÁùþý{[[ÛŠŠŠôôt õ {ðàlN§L™‚¿ú¢"À ­««#‘H­­­S§NݺukKKKDDèn¥¦¦º¹¹Èn333ãââ@ ÀápLMM'L˜�ÛÏ¢¢"uuõÛ·o<xŽAhºa³Ùûöíb±XÊÊÊ y'..Dg¹¹¹ŽŽŽ666eee0†„„ÄÄÄÀ©Ž7@‰ÿa0;ÄÇÇC+((ìÝ»¿“ }ýú5ö?&é+VŒ7êóÝ»wüüü°ÙšWHwrrÊÎÎÖÓÓ‹ˆˆ°°°€mìâÅ‹çÌ™£¨¨èííh=ÇŒ³eËAAA~~þ>¶Q¯Eàp8óçÏëM›6}øðaܸqÁÁÁ»ví‚“ÐŒ3,--eddzmâ®®®«W¯ÒËËËCBBðeff¶··}Trr2<züø1¢õ´µµ500঎æÎ”N§_¸pN±P"Â>|øPRR´ž™™™„é,66VWWwíÚµ†­Y³f„ jjjkÖ¬§>>>[¶lAloNNNxŽ–77·? uuuéêêâµ²êëëãââÀÜòôéS0*äææÖÖÖÂËÃÃ#11qúôégÞ¼y“&MÂ0lóæÍ>|ø‰^;†a{÷îý­ç°aÃúØ«¿ý’£¨¨èääDP4iRCCP á­<pãÆÐÐP`ŽBef2™'Ož$‘H»wïFéÕÕÕ7nÜ@}QSSÞÞ¼yÓÞÞtjÀl›žž®¬¬Üo6º¡C‡‚VGvv6JÔÔÔÔÒÒ‚ .\¸°ï/ ôôôü&D~©©©ð ÆÆÆ¼+Æ0#>|ØÅÅÃ0‰„ŸŽy ;;›B¡Ìš5 ‰J™˜˜`•““£¥¥…§Úóññ©­­upp€Ž‹Œi®®®Ð_EEE·lÙÒÒÒrùòe~~~‚œùl€„-óîÝ»¯_¿c qö¹¹¹°Ëùú6b±XÐFâââ¼+YGGGGG‡  jddÿˆŠŠ;v,§ 0òöÝ]]]wîÜ‰ŠŠ+7Zr²²²ìììÜä)))Ïž=›3gNßIáÀœuíÚ5”"$$„Xúeeeœœª ¨#EGGOž<ù‹Dçüýýƒ‚‚eøÔ©Süüüx©_ úúú•••h2„Å7«ººúÏåÃI鸸8Bú™3g„……I$ҎŸç D£GFâÅ?ô.‡�ÖÓÓfA …ÂCD ¿!µµµíu"–——g³ÙH�´¶¶öÆòòòMMM0™b–‘‘‡¦„q´z}Ô4ì#@Ä ØÕÕEØ©™™™%$$ ý2žyþúõëK—.åq‡$&&¶uëVø[š§`sG&؉#þÐ>Éâ«—222ÍÌÌh þ–B^^¾¥¥Ù÷¼½½õôôäåå/_¾¼k×.tsüøq¼œŸŸ_^^ÄÅ¿m¯mnn–‘‘+¼®†aÒÒÒ¶¶¶PÏ7›·oß–——ó6O¯\¹2==´Ÿy“âk››ÛþýûûQ¨¨¨?ZXX|Ï)F»|ù2"EëMbb"÷4‘šš ˜ššJ"‘fΜiaa‘””UÇî>n™›ššxÿ&''çÑ£Gòòòè¾³7(«V­BW‡†AÍáp\\\¸§Å_¢ÔëdØ¿fý18x𠲘;v qðc&''‡´æZZZnÞ¼ùÙÊï¾ä¼ÿ¾­­ ö•gΜÉÊÊB«z¯¸té??¿ þf °mÛ6ØrÂà200X²dÉË—/¯]»KNfffll¬±±1º̘1cÆŒ;vì(**ãÏgñÏ?ÿÀ¾X\\üرc½þ¦¬¬¬¤¤öVþþþÉÉÉ‹/FOÁÍF)éùþýûnnn<T–………7lØ�´ÙÂÂÂ<Œ¼ºººˆÜú¿ÿþËÉÉùÒ%ÇËË oXM¹O_ÃÜKΜ9sæÌ™coo_VV$ùŠŠŠ666òòò“'O¶··‡"9rdÔ¨Q„ÓŒ””Ô¶mÛÀ°ÆCæèèh°j‚ÍQn„7¬8q¿F®]».«H$~–,**ª««ãM²9oÞ<‰~(<0 C÷®õõõ ,èÇ’Ó’%K¸Õ}x€Á`8;;ëêêÚØØÀÜ“ùùùM:uáÂ…@­¯CCCWW×ììì™3gΚ5‹D"A} ///¸«Ã0lß¾}½îœ ÆÍ›7qr¯‡÷{yy¥¦¦öqÉ õôôDVµõë×£ýߨ±cÙ%§°°°¡¡&C7oÞ€æÿØûΰ(’ïëžDž$ 9#"` è0!*ÌŠŠÓºb\s@wM¨fÄ�F$JEAD@P Š€$ÉCfÂûáþõôÓ#bæó jzº§ºªî­ºu뜞5ëò"<O]]ïräååQ¯NHHðððøù.çKq÷î] Ø­¯¯ß¹s§‡‡‡„„ÄæÍ› :µ°Z'($fddDDDLš4 �=ˆ Fî®dHºƒQ£FóKJJúÒï¢ô¼œœBbñññ555¶¶¶?¦ æåå…††~úôéÎ;YYYgèС“'O b2™‚'0lllPö `×®]‹/FÇžØl6$5|éÑä±z2…÷œ’’‚4F»$‡™„]¡Ó>ü½ý †açêÕ«óæÍ{öì›Í.//?vìØøñãýüüêë룢¢ŠŠŠ ?vkLMM Z݆3¶—ÓÓÓCþõkF‡`¢Z¦á...¿é)™_ÜßÀ"rçÎ0ÕŒªy{{ÕÏw9Û·oGÇãCCC‡G|oܸÑáZXXXZZŠ÷7°x§Óé=p9‹-úÊ£ JJJ‚Ód77·Ù³gkii ùnccãÁƒ>üÙ§¼y󦸸ø‡¹ Á0¬¡¡Iá={öÌÈȨ;‡þüüüÒÒÒð‡·[[[{àr†þ•GA«ªªÎž=+¸ŠMOOÏÊÊBûÕ]áÊ•+ƒþlVz÷û°`¦††F “˜˜R¢¬¬¬LNN0`€®®®‹‹ JJJ²Ùl!*…·oßÖÖÖÆ‡ ïæ§ÀÕÕuáÂ…hžaØ;wvïÞý›ºœ´´4uuõ_ÖßÀšrË–-ºœ†††°°°_ËåŒ;¶ººzùòå†B.™ƒƒÃÝ»w¡pøðáæ:vì˜þìÅììì€iîܹsp½¸¸8ä¿©©©9::B¡¢¢"Ê)HJJ‚B æM›6{öl;;;ô¸@öÔÚµkCCC}}}1 ›?¾pë/ƒ~ÿþ=Ü\[[”„‡‡óùü3fôíÛ÷îÝ»×®]ƒ+!Ýð˜˜ü~•››ÛÎ;ÛÛÛI$(h‰‰‰™™™Áét:(ŒŒŒ&Ož …jjjR˜8qbpp0¢Ã:_„ .¬X±‚Ï狉‰¹¹¹AôiÕªUpÏ>}úÀvwzzzjjêªU«PÂRyyyKK ìy:88„„„ÀW† VxË–- iºvíZ´Üùûï¿¡eÅÄÄΟ?Ï`0vìØße0°m`ll<aÂ(TWWï±æ)Ø)Ø^‚-î–––;v¸»»KJJêêêÂSäååQ¼«¸¸¸¬¬ $Ã0lúôéè=›˜˜ÀôÜÔÔ4 �2gÍš¹—û÷ï?uêë<뀳gÏÂw%$$Ž=ÚƒZܾ}2ë0 [³fͰaÃ6n܉6NNNU·ÿ±Tê¼yóàïwïÞݾ}z*¤Óé•••0.Æ_WW‡úDºŒïÞ½ ‡£FÂK ¤¤$!]pºP\\ ÏÒÑѱ··‡Y?¤á,X°�u§‘#G¢¬Ÿ‡;v ¿¢=uêÔ¦M›8™L&¤€Wœ9sæï¿ÿæñxT*]UWWŸ8qâСCÚÚÚsçÎ…¯¬¬ Él£F*//‡B}}}4GlÖ_Ê帹¹mß¾½££ƒD"AÖ;›ÍÞ¿ÿñãÇUTTœœœ F h_燺SSS4Æ0LWW—ÅbïÛ·/ü1pà@‰Ç!‡ J‘–––„S§N!aG‹³qqq˜a1 ‹&LQQŒ……ÅÁƒÑ`ü÷ïߟD"Á韀w9r$…Bã8–––ÝÉhiiá'㪪ª,K[[\ŒF###Ø0`�™L†@ÿ!CÐÔ "KøÛZ[[S(8Ó�»Abbb, ö´èt:,•”””X,ئ¯¯Ïb±`Ǩ_¿~ÝÕvuuÅ»lmmáøF{$##Ãb±ÀåÀ WMMr±±±Ag$“Éd…šu̘1d2Òˆ9Ô �� �IDATÆ™¬gÏžE좰Ög±XÐ ¬¹²²2‹Åuuõî¬$ð±;|æý´iÓ€e<Ô„P¥¥¥Y,ô=yyy´J377'LDŒŒŒX,D}MMMAÜÜÜœL&———C§‚ûXYYQ(p9“'O†wËb±À÷ >,“&MÂtpppÀû?è£G&“Éñ1vìX¼ª§§§ ï$“É\7£Æ‚ˆ™äéÁnö AƒH$Ps6¬Sdžæ.è¡4 œª§§‡Ï(SWWg±X0}ÑÕÕ…‰K¿~ý K 4ˆL&ƒ•À?tïÞ½HuB …ÂårÉd2´éÁÌ™3©T*Ç£P(ª*%%-+''Çb±`‹KYYÿ´´´X,J‡N|Z :Jü±oß>0hh¦E¥Rñ¦I\\æ"t:ÅbA‡‚‚!¼ô­ Rý-!Rýõ!Rý- Rýl7©‚Š ‚"ˆð[BärDADøAè|/‡B¡Îüî ÃdddzM` âãRRR½¦™à\§¸¸x/«Fë55"‘H---d2¹7h&iié¯Éÿƒ¤¤ä7i&2™Ü#ÿ_ërjjj3`ï�—Ë%°Âü«‹‰‰éM’Àd2ùç2!~[�™EoJ<¯±±±—‡æææ»wï~CáËŸŽúúúêêj ]þzôéÓGÝø·q9222ß)]á§€N§ûúúŽ1¢×¬r¤¤¤bccûöí+„ïà÷‚¸¸xvv6™Lþ†û'¨Ôªªª‚‚ yì 2™Õ›ŒƒŒŒLppððáÃ{µ¤¤dbb¢ººz÷5\„€F£‘Édá\éßÀåP(”oBOù‹�²uååå{SÆF£Ó齦™$$$$%%Édr¯©Fkkk£Ñh½¦F±Ö›ÚÃ0ƒA&“åääzSÆš˜˜˜ŒŒÌ7i&ÈXû†.G”> ‚"ˆ ÂZ+ ÿ811‘@ÈxóæMcccccãÓ§O£B(¢»õÇ ò‡× V>þñú!ܾ}äíøñãðuIûÒ¥KA-´ûxóæ P|#DEEÁ̓ÿþû/|‰ -Z… Ú1b¿µµµÆ8€\ͳgÏð…ˆ‡ÿêÕ«P‚—‚iÓ¦áÌ0 ƒ¯#}O Ãòòò Pé‹——W§Í ÚqxØÚÚ"NI¼Dyy9|Ï·aXLLLN5/\¸4,--áþá2 ÃÞ½{!)# Ãîß¿/ج§OŸ†B¤C¸yóf|‹€¼ãÌ™3ñ…°›ÚÑÑÿv“UìæÍ›’‚ƒÂÂÃÃQ¡££#ö´†Ž뫪ª‚ËíìóçÏñ?Ñ–øøø@ XÃ0l÷îÝP¢–]ÁÜÜ\Sû«W¯‚¤�___Pè!`Ïž=ðP<þ¼yó ¯ì0dÈccã®H]¿hllŒXEðÈÌ̄߉W)õ÷÷‡B<õÑ¡C‡ /Dû1wîÜׯ_ –w*ûòöí[øñ߃Ðó3.'##C__ßÁÁÏ<ïë뛕••˜˜˜˜˜ØÜÜ \#ÐÐЀÂÀÀÀ‡ ÞmܸqYYYH,ÈÔÔ®÷ööÆëÁ¼xñ‚Åb¸îýüü¶lÙ‚tÜÜܨT*|ýÉ“'À½¸zõj}}ýˆˆt þ³(**Ò×ן2e žÞÿáÇÁÁÁpsuuuDPl„²²2|þuñâÅŽŽŽPø×_7Áˆ#|}}¡¼h%%þ ÒÜÞÞnhhˆ æÚµkïß¿‡’ŠŠŠK—. ©²¤¦¦"Ö�ð7ðuØÁÂ0¬°°ð¯¿þ‚BGGG$ Ç•+WöíÛ‡VÐPWW‡¯ã›ÕÎÎîÉ“'[ß¿$PUUÅb±à»Û¶mc±X†=}úT__ßÑÑQP¯O–/_®¯¯ÿþ}$O‰aؘ1c¼½½áþˆ­P\\ìää­X±lâÇ¡PCCšõܹsÍÍÍP˜••lIõõõ{÷îE-7¯®®¾qã*~*333ø÷Ò¥K½NPP¾¾þÖ­[ñZ‡îÓ§ÜáÞ½{ TºtéÒùóçC¡³³3PlŒ5J__¿  � ŸúúúiÓ¦Áe...pj{РAèîܹ^ò7òòò °¶¶f0{÷î500€Â›7oâwð]__???=”Íf£sõúúú666h‰·Â›7onhh ”ïÛ·OWWzçΟupp@ÝrÉ’% J=dȰ°°ÄÄÄôX «0`Àƒ`h¼Nvv6êÖÖÖ0  JNN†B2™ â¿GŽ‘““ƒÂû÷ïã'¦?‹/Ö××Ådñà¨YáÇÏŸ?ÿk(©„€*¤233ãããR ÐÖÖÆårÑ–5Ì€š››) ¶·· Voܸq 'ƒJjkkáz‡ê³†eeeíÚµëêÕ«xb¥ÀÀÀ¤¤¤]»v¡YüßÿM"‘ S‹Ãá€qwwçp8@‰ÖMhhhdffæääìØ±¶·····Ão£R©)ÖNk L$˜ØÔÔ¦¿®®NVVTA‘%“É‚»ý4PØÚÚÊçó /¹+øúúr¹\‚„Dmm-l\‘H$x½\.·©© î ´„ûøøø¼{÷nÆ Èu577S©TTYäËY,ÖÖ­[ Rßýû÷OHH@Ä >Ó,-- ÈÂÂ"33óþýûv}á8{ö,‡Ã!h˜ÖÕÕ1 øm„ Äá#)))¨é¸qã,--! –B¡@³Â‹…+¹\.ZCÈÈÈ6“¬¬,¡õáööváNtæÌ™“'Oööö´œBݸ££^/›Í–””„Û655ì&¨µâI F\\° UVVÂëE•�«Õ¶¶6å|>ªÜÔÔ„.>wî\§I<àñxxwÎçóÑPÕÕÕÍÌÌÌÌÌÄËF`üäÉ“={öÀÄ‹0vÐCÏœ9mhh@õŒŒ6뺺:999iié¶¶6ôÄ�x.¨‚žËápZZZàwJHHÀ´læÌ™Ó§O‡ H‡jÊËËÕ¨Y<==¹\.žüÍ£Gs5;­Ä÷]åÀÑ‚dÈ¢E‹ ˜L&“Éäóù 9üY477KJJ~vëžÇãµ··žÈáp¸\.~gOLLŒF£íÙ³‡Éd>Œ‘„„„ŒŒ žÌøó5'“eddŒªS§N1cT0;;ÏðÖ$%%)еµ5“Éôôô’pU^^wÆ{ˆ¸¸8(즢ŒàÓÏ©ªª2™Ì#F¼zõª;÷éèè�ÐÏ^ÙÒÒ"..NÈ(mjjÂ+“H$))©ÂÂB&“¹~ýz˜ÂCúÒÓ¶lzzú„ འRû¿‰•*!!Èd2³²²„7ë²eËàÎ Û 5jö@nŽJ¥ÊÈÈv§¡c¶~ýz+++!üRÒÒÒ„&&‘HÒÒÒ?~d2™+V¬ ĸ\.‡ÃùìføÚµk™Læ£G:5‚G¾ Fvv6~ìê uttðx<!^·n“ÉŒÅ?ÔÊÊŠÉd–——ÿ^Ù=T*U\\üÊ•+L&³¾¾ž ˜÷+�Œƒ`ûF믵—CÀõë×óóó+*****H$"QbÈÆwëÖ-<¯œ ø|~VVÖ¦M›ðA^˜�¬®‚{*©©© ÆÕ´ÿ‚ë0üFNXXTÐÄÄ„ ³{ðàÁüü|0=1•ÈÈÈŠŠŠU«VÁÇ›7oFŒÁd2}¡‚‚BMM ÜùܹsãLJðEuu5Nœ8/·þ5ÐÒÒ*++«¨¨HNNþ,O0ÇóññÉÏÏÿ¬åp8,ËÅÅvèèèèß¿ÿ«W¯}‰ŽŽNEE…‡‡G÷õ¼aÙ €9~§2dHll,¼7Dƒ ÐÖÖ¾uë´ÁŽÿù矦¦¦Ð¬›6m"“Ép%Ð*cvéÒ¥OŸ>Á:šu‰‰‰•••P8lذo•½Ãår7oÞ<räÈ9sæôàPˆººzEE…——ø%ÑíÛ·!l+7n?~|EEÅÍ›7£££ñ¯EÒhhh"«Ìãñ‚‚‚âââð{lÞ¼y̘1·oß~ðàNŸ>ýäÉ“sæÌ¦Ñß Ë–-«¨¨••FüC§ê¾iúaèèè055ÍÈÈèT¼àWt9_Š)S¦;vLEE¥±±‘Ïç755uÚ¡A/àîÝ» uÝÚÚzïÞ½#GŽ466¶µµ¡UªpŸ!}ûöÕ×××××T¬ê>Ž9¦q•·´´à÷Qðq(–Õ4:°ÿ‰ðóóKIIÙ½{wcc#²;^éàà°jÕ* éknnæñxƒ ºwïÊ܇:òù|BL²›øï¿ÿôÿ‡/Š¿áa``�m„öo¡G ^ùÏ?ÿÀ•H Ô…—éBü_ÏÐÞÞ¾{÷îÁƒ#Ñî£Ó¾ôE8yò$>V¹páBôÚ‘<è!***88ØÕÕ•0Zñ8qâ!Uðˆˆˆnª'üjàp8ø„|†NEˆÿ €}2*•Š­?zuø]ïÎ`0Јª««ûã?^¾|‰§dGA¼ªª*HPéèèhmm]»víܹs¡°µµ•Çã)**nÛ¶íØ±ct:ÝÙÙùKLaaáW®Üa/‡7˜?þ?ÿüCÐɆ½üãjjjÆŒCšOJJ:yò$!ïîCLLìþýû þOQQ±Óõ–ŒŒ Ò©­¯¯·µµ—““›0a2£æææÙÙÙUUUãÇÏÊÊúÒãââò•LÒ<ÍfÔ+¢££ïܹ:4°gFˆýý÷ß³fÍ",&MšäããÓ‰îãßÿÕÑÑáÎ/E}}½……… MŒМ@êÄWö¢§OŸâG«’’’pôßIII„HOss3™Lþe¹säääК¸½½}øðá‹ô˹III*•Šfî¤Óé %$$À"×ÔÔÐét|ô v˜Áß(++ÃõµµµJJJÚÚÚœƒaØÓ§O;Txùòå‚‚Èû”‘‘áñxðu11±oÛºpóŽŽ·Å™ŒŒÌ©S§äää`}ƒjÚ§OŸÆÆFøŠ¬¬,ˆ©Ì˜1ãÊ•+PY8 ¹pY]]H׈‰‰IKKCa[[J)))$ÙQû/­“ɬ¨¨À0ŒÍfƒŽ•J•••…{¢ÝõÖÖÖ¶¶6‹e†¹»»·´´€¿a0¨Y%$$®^½Š1f̘˗/kii%&&⟠á~|eëëë¿9E‚’’Ruu5¬<@¾ÏçúôIYY¹´´tÙ²eóÂf³áÑâââ¨Y9´‹O]]Ý’%Kàý€ï‘••mmm…+á¼-Eëêê PQQf¨WWWƒÄÈ—d¤‘-——Ç÷¥®ö&I$’‚‚¡/A�ðúõëx6))) …BèK £½½0`? ‰D ÇÃÊÊ Ö«W¯¾}ûüMcc#<ß$%%ÑØA/ANNꫬ¬üéÓ'6›ÝÑÑñ#µ9”••+++i4Zkk+<—ËåÖÖÖ***±køÍÍÍrrrP …`0 ;{ö¬””ˆ;|sëôõHHHÀVð7<¯ººZII‰B¡à­Äw:ðKý¬ Æ÷³9sæðx<Ðú\½zõªU«0 Ûµk׿ÿþ …'Nœ€9ïÖ­[ÿþûoPE¡g°ÎÈÈ€ý�EEÅØØXüÅÅÅ{6þ$íúõëOž< Û¿?>CIIéKÓh4<-Ä„ 8Ü|Μ9 @uëÖ-·jÕªíÛ·:t>uuuù¦Ë—//[¶lË–-†Á®UBB˜1cêëëI$(‘—— ‚)Fß¾}!Îknn¾zõj¸¡µµõ‘#G ÊqíÚ5(tvvîNª¢ªª*¸:@ffæÀù|¾¬¬,t2mmíÓ§OÃ=‡ ±~Èã„4Z•¢ ‚;wþ÷ßð•ãÇ£¥ @EEE0ÓISSþPPPðóóƒïöë×`‘‰ü"s€oÙØØØ &TUUA_‚i½½ýãÇ544<==áуöññfår¹Phoo’¬«V­:wîîܹb>'NœØ´iÓ¿ÿþ‹aØ•+W ‡††Îœ9²°âããÁp§§§“’’’ðÓ-�:¦ //ïííÒAOœ81iÒ$///'''˜ZàSQÔÕÕÑ¢YVV¤­0 Ó××ît´B,ôÆPÇ¿ÿþâ‡ûöíÛ·ozxxÉðÖÐÐ@¥Óéøé˜ÔN]~´^»vMBBbÙ²e{öìÙ¿?<ôäÉ“ !týúõ… ¾|ùðððpÐ<LNN1bDss³˜˜ØóçϘ9~þüù°aÃÚÛÛ¥¤¤’““1 «¬¬\¹reXXXÿþýÑ;v,E¶bùòåëÖ­ƒPíÑ£G¡ððáà }ösÁd2;M B£µ¾¾~þüùÑÑÑzzzÈ´š›› ?žÑcˆ$Ú~Kˆ$Ú~}ˆ$Ú~ ˆ$Ú>ÛEm"ˆ ‚"ü–¹DA~¨]­ ñ{½@‚Û;êB …Òkš š†L&‹jô+÷:8äÐ+Coj¦oX# …òmOtþ›¸\øÞ¨««ãóù°™ßkjÔÖÖÖØØØkІ±Ùl ‰ÞÔñª««ÛÛÛ{SZZZx<^/3\.·¡¡A8³Ôï…ÖÖVAÚž£Ós‡ßØå466âÙ>~û¥•Êãñ’’’zÓ¤ŒÍf¿zõª×èJ‘É䆆‰ôéÓ§^3ÙlooïeC‰D"µ¶¶ö2ãÐÞÞþìÙ³^¡P(µµµ---‚\ï=kq…o’‰ Ìå0 H•뀌µI“&‰2Ö~Yˆ2Ö~ k½É8@ÆÚøñãEk]ucÈXûf“KLDA~̲RøÇ•••ùùùx6—‚‚8Ûˆ×ËÈÈ�B_ uuõNo9qâD˜Jðù|8¿&..>}út¸ ®®Ž…*++#é¶¢¢"8f``€Ä3²²²rss1 2dˆŽŽþ)?633ëþq÷úúúôôt8UøøñcJJ †aºººƒ&\ÿâÅ X®š››&±±±Ã†  ÃÂÃÃf Îö···ã•¸OLEEœ°ÓÔÔDäoyyyÀ�mbbbddôÙZ<xð`ôèÑxž‚   ÃÄÄÄ„WCCP+**vuúïíÛ·\.­3:mÖǃÂФI“wQXXXGG‰DB---@ -++;qâDüSJJJÊÊʾˆé.>>ÞÔÔ߬ÀpeggGX¼²Ùlà‡UPP ¬0>|øPSSƒšõõë× ^5pà@}}} Þ={†»7n<ôÁƒ@KeccÁLäÖÖÖŸ­BAAASS^�&33Nì>ËKHH€Ðâĉñ´=¡¡¡Ó§O'ð466&%%Á‘d­Ož<Á0LCCiÛäççÃYËþýû÷ë×}755UUUUøD8,,ÌÚÚº+„ÚÚÚ—/_¢7ŒÀÐÐOž†`Ô¨QÀx¢;“'OFT=¡¡¡‡L&#&ûwïòx<*•*Hø_SSÂB***Ȧ§§cÖ·o_¤Ði³þDÄÅÅ 4CFð®ÞpuuuNN^ÉìG¸œªªª‡¾~ýúíÛ·èܽ{ˆÿrssAÆ#===<<V^?~d±X‚^',,ÌÙÙùùóçàr|}}ãããÁ&‚¢C}}}@@�hzÊËËs¹Ü?þø£¨¨(88øÍ›7`ø|þÀ_½z¤³EEE¶¶¶Èë<zôhëÖ­.\èŽËill /))¹wïr9?~ 555>ŸgMÎÈÈ/--»Éb±ÐˆŽŽÞ¼yó;wÀåܽ{)#q8œ9sæ°Ùlàï‚ëµµµ'L˜PYYAYY™ÇãYXXäææ†††B¯ÍÏÏŸ9s&ÞR:›šš—û÷ï#—ãççX4ÃáØÚÚ²ÙlpÞ²²²< ±þæÈ‘#}ûö—“žž•EÍúèÑ£û÷ïƒ<L]]Ýœ9sddd‚ƒƒccc9‰Dâp8ööö­­­~~~p„ŠY,))ñððhhhè¦ËyüøqYYÙ‰'Ο?š5444&&<z[[^'©±±Ñßß eee¹\.âMøðმ›…B—“““ b”ïß¿·µµÕ×׿xñbEEjÖAƒõéÓçÞ½{ÑÑÑ@@×ÔÔäàà@¥R}}}Ùú°£Óïß¿OII‰‹‹STTD.çÅ‹ááá “URRbgg§©©ùøñ㨨(Øõ­­­µ··g0!!!---›6mz÷îÞú777_¹råöíÛðn?}ú}III‰Çã1"///$$úR^^ŸÏ766~þüy~~¾··÷ªU«ºr9¡¡¡ÍÍÍ›7oÎÏÏ* ŽŽŽÈÈH8ÚÐÐYXXøøñcärRSSÿý÷_¼-Þå¼yóæñãÇð÷“'ONœ8¡¢¢óàÁÐû©¯¯Ÿ3gŽ´´tPPPll,—Ë%“É\.÷‡; Œåñx HÓñÎ5 �x.x<ž¥¥åû÷ïïÞ½ sß7oÞðù|333|³³X¬Ÿèu=zTQQáêêêíí\ΦM›,--aÚD£Ñ]NMMÍ… RRR~´Ë Tii)¾—?yò¤¢¢m=Õ¿???##£½{÷bæèèh``@p9!!!‰‰‰xfÙçÏŸÃM*++'Nœ8sæÌ²²²ëׯC§Œ‹‹;{öìü‘––öúõë .`vþüùààà†††Òétøúºuëž={.'&&æÑ£G‚r„]¡µµ5))‰ ’™™™žždbW¯^õóóûœ€€�]]] KY¾|¹žžŒØû÷ï?~üO˺}ûö¤¤$hSUU2999¼0¸m¬„›_»vÍÂÂ"..®¾¾®ü÷ß>|(Äå¼|ù²¸¸˜@Gíìì\VVF"‘jkkGŽikk[YYyùòeØõ;‚ËyûömhhhQQQß¾}Ñ n„ £GÆ0léÒ¥úúúêêêîîî;vì�³baa1a™­[·¦¥¥1 .—«©©iooÏf³;´ž¯^½Ú¸q#˜Eðè¹¹¹HÓá³xóæMNNA-j×®]111°Åd2ñ.§ººúÂ… Ïž=Ã0,%%åàÁƒàr>|øœŸŸVQQQ$ ÞóÖ­[Ÿ<y •+WüÇÿý‡h=õõõíììddd6nÜDvåååS¦Lâr>}ú”””ôþý{<ۇƎ ËÍ•+Wjkkkjjž>}zýúõ0Ô---ÇŽË`0ÒÒÒêëë üÖ---·nÝl´ŠåóùPàà`ooï#FÄÇÇ×ÔÔ@áÁƒ£££ß¿Ÿ””$<M#--­®®ÿЖ––­[·‚hiiIJJÂ!<ÌÍÍ =aÞ¼yÀ𯬬 &ÂÍÍÍÅÅ&ÿý÷_{{»´´ô–-[^½zm†††?Ìålܸ1//$ÚÌÌÌð.§¨¨( �<xàééiii™’’RXXõ}øðaqq±™™YPPºº:e­Zµ šõg¹X0*­8qϽDX¹Þ¹s§„¼ßÀåèèèxxx<zôÈÓÓöëׯ¤¤qïtSœüàÁƒþþþø°H…·µµAG”——3f ܹ¹¹yÊ”)†ééé©««Cacc#Št OOϵk×Â:·;PTTôððÈÊÊ ÍikkëêêÂëêêFŽÙ[:uÊÅÅå³i<MMMpç>}úà;ô×�¸Ý^ºt)ð¢r¹Üùóçwç> uuu3fÌ@Þ ý¸¸8]]]àŽ³¶¶NMM…ieeµ… úúúBÂpÉôœœœgÏž9::FEEu³‚À㇢¯È~Á±ƒnŠ´¿xñ"''gþüù°’‚‡‚/™>}ºªªê×·‘¹¹¹¹¹¹——¬¨�h½¯©©IPýÁd³ úLl6ÛÃÃ#$$”¶ÁÏwaaaaa¡à*ÁÞÞÞÞÞ^lWØ¿?LQ‰˜˜z“ÉôððHOO'JåççC711éjìøøøØÙÙá¥wîÞ½[UUµnÝ:ÿ÷oœœ ÐþI”ïè‚\Ñׯ_ÍL¤ÙPZZêïïøðáî¨S~—½ètº˜˜Ä÷ 4…]áÎ;Ó¦MC;^^^l6z-FSRR‚;‹‹‹Ã|SZZZRR ñ\‚¸wïž™™Ù×ghHIIIKKÃ¥¥¥ ”£GÎÎÎ>wîŒ.3477ÿì´]RRráÂ…pç’’7{öl55µg¿ÍÐ�� �IDAT 333Á†š™™UWWCaZZ^€«›ÐÑÑ‘Édx“Ÿ6µµµ£G†(amþôéS‹6BUU5##¬L&˜=µ´´ à ak°…óêÕ«oBt¨¥¥•›› 'Ôê cÚ´iðöŠŠŠÐŠ-??ßÊÊê³JK“&Mzùò%¼=___•¹sçFFFBë ÓNNNð”¯Ñë}üøñ“'OfΜ‰ßãù,ÚÚÚüüü-Z$øÑ‡‚‚‚ÔÔÔ`&gjjZYY‰ú’?ôYÉdáB‹#FŒ€WK(A¯£««‹÷¯AAAâââ>>>K—.¥ÓéË–-óöö† í¯ïo"""êêꪪªø|¾¹¹ù¨Q£^¾| /<77·ûâ„? ŽŽŽˆ¿üâÅ‹+W®Ä/q>|ø½e~¾Ì夦¦~úô ¸‡=úøñc Óí ·oßÎÏÏ_·nÁ[ðx¼³g϶µµíرí|¡ÀÚ¹sç¦OŸþêÕ«üü|X»ÿ~§S§ÈÈÈ/^Ì›7O¸y=uê˜E)))ü‹&,E³²²P`-<<%2À^2=!!!YYYŽŽŽŸ]>KII¡‰CNNÎÚµkgÏž­§§·`Á‚7n@`ö* Ž°Šï™ÐÙ¾}ûð5áë€×¯_‡‡‡›ššZ[[\NlllJJÊŒ3ÐÖèåË—ñµ™3g2ŒC‡ák¾Û?úúúªªª.X°�1wj‚‘^¤µµ5Šòàêꊬ!X.¯[·îìÙ³0„À hkkÛÛÛß¼ySø«›;wîܹsáoKKKggç3g΀E'±8ðßÿa_¡s—””4}úônF Ð\íܹs\.wëÖ­„ƒEEEþþþššš¨ |>Ä„üΠ  äž/^ÜéVhkkë¡C‡çŦ¦¦¨‡{zzÞ»wOp´Lš4 ¿Ä©­­Ý·oŸªªê°aÃìììètúîÝ»>ÜÞÞþ뻜ÖÖVkkkww÷˜˜sss˜QAůy¶™\§®®ŽFk}}ýÕ«W¥¤¤V¯^OùÉ.çKáåå5dÈ Êoll<sæÌöíÛÅÅÅOœ8A"‘€¤ýë@¡PÀ•””ܸqCSSSðÀ 2ß_s:ÇÚÚ Ñ[·n)((ܹsÃ°ŠŠŠ«W¯îر£ÓÕXKK‹··÷š5kåúúúûöíƒZÀž?x®À¢ÿ]‘™™ ©eYYYÉÉÉIII#GŽŒ‰‰IMMµ¶¶þ¢ xW(**ºy󦃃ƒ««ë›7oòòò¢¢¢W<(²×ã3ÏŠŠŠðJa/'??ßÏÏoöìÙ®®®/_¾,--‰‰!$Ñ!„…… ºº¿ÿþþ@r žR^^6ýKýMrròÔ©SñÝt9®®®7ntuu­­­­ªªòññY²dIIIÉíÛ·uuu Ê›#FŒ€)‚PIkk+zí=f7yûöm~~>!úY,_¾\0z f±­­ ´'~Y 2D0Yqêԩб!õæWÃÙ³g—/_.(äSWWwîܹ•+Wººº–””ÀôÅÞÞþ7s9Ë–-C‹8¼­?~ü8„Ë¿ ìììð ‰]y”íÛ·åQÐèèhyyy<w÷ܹsñ3M!÷onn>}ú4Áå|øðáéÓ§øÝoXEÕ××÷ žÖ3˜™™!3Aú ²FFF_4 C;ø§`eeõ•GAëêê|}}W¯^wêÈ “Éä®  ™5kÁå\¼xqöìÙ„¹ÿ‘#G¾Fõ2&&FCCC0 ÿ³ Ñh›7oÆWvÑŠŠŠ’““ Ó¸´´´šš”.غ¹á'¯_¿¾wïž—¡««ûÙö=qâĺuë~SZ˜˜ƒñ îëàƒ= ,t9rrrhÔàûÕOv9C‡­¨¨€É¤¤$¤ÖL›6íéÓ§Phjj éUÞÞÞ&LÀëì^¹reíÚµ$Íãñàz Ãdee7mÚ¤¬¬lkk …4 ¾hjjšŸŸ…0r&Nœ…ZZZ èׯÊŠ]°`AÏä÷ë×ÏÄÄ=¦0ñññU,!!†ýïX>”îèèKœþùÇÃÃâxáÑ<¸3…BÍ[ …RZZ …âââp¨ELL,-- p¥¤¤ gì‹°gÏ0îÿüó†a öööð *• R˜E´··GPEy®aaa K†a˜ƒƒC¿~ý£££aU4oÞ<¨ì¶mÛÜÜÜð••––vrrB•]¹r¥ºº:d:`"=æM›ÎŸ?óqÈjkkswwß¶m™LniiA5uttÔÑÑA¾yófZZä°3&&&®TTT„ñìÙ³ÓÒÒ ›|üøñ°;(--}æÌXu9;;C–’’‚ï’Éä7ö ÷îÝCá9s昘˜,Z´èñãÇp|êÏ?ÿìTl”F£¡ê¼{÷.66mê a5pà@‹E£Ñ222à°NÏú‚¸¸øÖ­[…\`bb’——‡Æ0ÄÆÆÒh40<9r$>ýrÙ²eQQQX´`ÁئÓ釂î´sçÎf‹wîÜyèÐ!50™¨««»víš³³³ššÚÔ©S‘u‚}²Aƒ#c-ÄÅÅ>|5200À‡üóÏ?îîîøÑÚÔÔtþüù-[¶ ~•’’òîÝ»ï”+H¡P(»wïnkkëèèÈÍÍÕÕÕmooÿôéä’Òh4UUUCCC¸ZYYYVV¶¶¶–N§[ZZ‚3×ÑÑáóù­­­t:ÝÆÆ¤ ‹‹‹µ´´ð2ì cРA°++++##C§Óétº¼¼ü€$%% ‹‹‹étzß¾}Á…(((())UUUÑét 0T*µ©©‰N§O™2…@,##cbbBo–HMM0`€àô–B¡(++£3­òòòL&³²²’N§6 rX«««ÅÄÄÔÔÔ´µµI$RKK N·¶¶†¬Yü£ÍÌÌàÃ!C %%% ¬lh4š™™Ù»wïètº––DÛ †¦¦fYYN0`�¬lTTTètz]]Nÿã?:‹‰‰½yó†Éd"iá"ÆssóÜÜ\EEÅeË–Á022***¢Ó醆†.ÕØØØÒÒ‚—ž×ÑÑVIII:ýúõ“““366®­­%‘Ht:}áÂ…`#† òîÝ;)))YYY˜(Ñh4SSÓ÷ïßÓétØD!üx BŽ•J---íJíXFFÆÔÔ5ëàÁƒ‹ŠŠ$$$ètúš5kH$Ç+,,4h¸¸¸±±ñ‡èt:$4즦¦&lƒ«««KHH°Ùl:>qâDد200hmm±jÈïÀ0lÀ€eee Fìääïyذa¹¹¹t:]YY\¸`×jllüôé¤Tˆ‹‹ãSf_¯¼¼|¿~ýêëëù|>NŸ?>~]%++;dÈÂÄ“L&+**Â/§R© ÝP]]]WW—Éd¢¾4vìXüΫ´´´‘‘‘ðl²²²ƒ†‡R©Ô¡C‡’ÉäììlX©P(&“‰ ‚‚hHÓétsssØ­ªª’€Ð™””Tß¾}ñ)9ýû÷¯©©î´xñbH2:thAA”””œœœð´ºoqqñŒŒ ##£#FäççKKKËË˯X±b˜?~433“––ÖÓÓ+))¡Ó鯯Æ0UTTìÓ§Ouu5N9r$LÔ´´´Èdrss3˜d9$ÄÄÄòóóåååá}ÒétSSS))) |ÿþ=Þ4ñx¼>àãT*UEE\�…Báóù4­¡¡¡££E7ßmGG‡˜˜X{{;ŸÏOJJJHH©‚þ–q¬ýú©‚þ©‚~¶‹TAEADø-!r9"ˆ ‚"ü tž>@&“ Û!¿{@�Ã0))©Þ$‰a˜„„D¯i&h11±^S#èuT*µ7 ¥¶¶6‰ÔûŒƒ¤¤$슌ƒàû!ði}—ÓÐÐÐ}J’ß\.÷þýû½f/ðêêê””ÁdÇߺFT*õ*süt455566ö¦¡ÄápZZZz™qhmmíŠ0ûwDyyyss3°¤= Æ7a~ærÄÅÅ…>ýv––.,,ÔÕÕí5.GRR²¾¾^MMíw¤¥êbbbyyy$IKK«—¨Ôššš¢¢¢^3”à¬Feeeo2RRR?~ÔÖÖö¦^� ‰ææf_W»±˜˜Ø7d‚èÜåÐh´o¨<úÓ!++K"‘444zSÆZFF†’’RoÊX«¬¬$“ɽ¦ãÑh4*•úéÓ§^S#ÈX£R©½É80 *•ª¦¦Ö›2Ö^¿~ý­Ô£Eª "ˆ ‚"ü®øŒËIKKƒÓÝ!!!VVVVVVxú#www(á5–.] Ÿ‚´†a\.Jð‡ë×ÊÊ rŽ‹‹³ÂÁËË Ê½¼¼ ŽÁc¶oß>ü• IÕ¬]»_òøñc¸‰‡‡‡àõ§OŸ†Oš5kÐY} Ãìì쬬¬ð\#ÕÕÕð]8h†””\ñþþþpåíÛ·»S‹¥K—≅0 ›4i’••þ daa!ÜsÓ¦M‚wè´Y=<< ‰ka¶aÃ(DD³gÏFoñ|úô JÐi¾ŒŒ |€E7±qãFB`ÚÞÞî#HÅV\\ áe)�÷ïßwwwGÿúøøÀ•x–þýû÷C!¨ß",X°�äPpâÐŽ ¨E8{ö,Ü!&&nÙ² ”³fÍÂ+NÕÖÖÂexžÍôôt(¾Q ÃBCCñïÈ�1 ;q─"mW°µµE ’‚xûöí† ð%111p[ U%ÀÍÍ >6Àºuë dÍ�3f̰²²úñ4ÌÓ¦M³²²êêHâË—/ñ|BÑÑÑøwK8¿Îv׺uëí}W¦‰Ð¬‚ç¢K›ììì5kÖ466âù¦Âž?~òäI Ã"##¯_¿¾hÑ"qqq(¼té…BÁój,]ºtÁ‚L&Ã0iiéI“&Aohh°··÷÷÷/,,Ü·oÜäÍ›7[·nÖBEEE¤ÉçÒ/]ºÄf³áÊ›7oR(”É“'/[¶ qn¯Zµª;Ì¥¥¥óæÍÒTøäÉ“àà`¸yBB©S§œÑ§gΜ!“Éðé•+W( Rt^³fMHHºØÎÎnÛ¶mÒÒÒ|>ßÊÊêáÇõõõŽŽŽðÝÒÒÒ+Vxyyedd¬_¿¾¡¡ô7000''® ½s玣¶bÅŠ·oßæææà ÀÊÊÊÍÍD"555ÙÙÙ—””lÛ¶ Ÿ¿iÓ&777t}xxxjj*|zïÞ½k×®-^¼øÔ©S4 /_¾L¡P,--7lØ0nÜ80s[¶lqwwWSSËÌ̼ví0M@âYmm­““|·¤¤dÕªUžžž†††P‚a؃ðîY¶nÝšœœüîÝ;DÑþfÆ p¸zÒ¤I _(++Û´i<èÝ»w6l@>&::zË–-h¤]¿~½¼¼®ôóó#“É3fÌØ¿¿žžh¹»»oÚ´ÉÄÄÄÑÑñÝ»woß¾ÅkL™2ú0ÈYúùùuU…¨¨¨C‡UWWãg�çÎãñxðtooo …2nܸ-[¶Œ9¸ víÚuôèQ--­?ÿüóÓ§O999ˆp“Íf/Z´¾[VV¶|ùòË—/gff^¸p ÓÒÒ<¸k׮ѣG£}—K—.±¡›››ŒŒ \yñâE …‚—òDÓˆÊÊJüC.\T.>|X´hQKK ž’çÑ£G‘‘‘pÛ¸¸¸óçÏãOž<)%%ŸzyyQ(”‘#G:;;Oš4 Ȍׯ_öìY&“iccãââ"..Îáp¦NúÃl÷Ô©S>L¥RÛÚÚlllðú^¹¹¹NNNMMMøÆêêjUUU4?†÷ùóçoß¾ýñãGÂ$ò§`Ó¦MÏŸ?/((ÀÏqmmmwìØ!%%…Lú¨¨¨háÂ…---ßdè‹]Žžžž——WJJJdd$*¬©©ikk}ÙÈÈH s/++322‚Âúúz‚.ç¾}ûÔÔÔ€¤/77æ¤ÙÙÙp}ee%èL·¶¶–””@auu5²Grrrx9[ Ã***èt:655j/RòX½zõž={º"½ÇCIIÉËË+//ÙApõõõpóçÏŸãÙB¡¦ºººðiCCªéš5kf̘:µ€ãÇëèè�Wšq8œ‚‚ønß¾}&ÄÈÈÈËËëÉ“'øÕá„ ÆŒ=øîÝ»ÂÕwïÞÝÚÚJ ÎÊÊ233ñX´µµj!,5A3fÌðáÃaZpïÞ=xbii©`³¾ÿ~Þ¼yPøáÃ4ï611ÁK"á+ KIì„@0þøñ#AÝ«+8;;/_¾OÓ “CCCxEÙÙÙøÚÛÛ?|ø�jnnFk…ØØØÈÈHGGG4›Ú]ׯ_¯©©Ò!Càë...`R]\\ÚÚÚÜ9.\€nV^^Nè'Œ9ÒËËËßßÏfoooO¥R¤ŽÍfC� °°pÖ¬YðôââbXa¸ººr8<õµ”””»»;ð-Ñh4˜ÃöíÛwÏž=@¨“ŸŸ*à PÁ+W®hhh�u!°:BâImmm§z?Gåp8ø‰0ÇC MUUU//¯œœœ‹/¢ êëëáÇkhh6œKKKÍÌÌàÓmÛ¶ÁÓ -Z…………ÐrrrŒaºvúôéf srrú÷猪Y3---˜ ¢e" OŸ>ë4{öì &=zôWXßlܸ±¹¹™ 7ñúõk### ª]///$Äü£]ޤ¤¤‘‘›Åb5556óœ9s€¿K8€`jÆŒ?~ ij®uð¸  ]!(**RVVîÎN F322"hv7®¶¶ž8eÊàÄìÎC•””ðùÊ@÷iiiÙÒÒƒ <CCCè»RRRFFF�fèÊ•+gΜY°`A§J\àk ´»ÉÉÉÆ ª.$?#²²²²²²7oÞ<qℽ½}WbBB0vìX2™L¡P@LH8šššº©E [ ˆ! 9oÞ<˜m !°Ùlx(r9`‹OŸ>}õêU'''¼Në† âãã½¼¼À‚C&d4õíÛ·¹¹ÙÒÒR^^?#îêõ2™L¼*(¢’sqq±´´B} ŸÂK¡P ÊËË­­­555oݺVSSóÉ“'ÎÎΣG&È^TWW“H$`Tƒ¹†aÛ·oŸ1cF§\ŸðPü964#322êT€'$$dÿþý޽{÷†‡‡?~˜U/]º´qãFPi:sæ >ׂD"áÇÎOPâê€àà` ß]ºtéºuë Y•””º£]ù�½·ÓóF£GnkkúZhÖžit}³½ÁPxIIIXXXXX‰Dò÷÷ïæ½¼¼ÂÂÂþúë/¨Ojjª©©©©©©p™Â©S§&''ÃãPìNœœœÖ¯_O˜w|RRRá‰:::h÷y à—£m¤+V¬[·®S’??¿dË*++/^¶nݺÏn�ØÛÛ‡……µ´´ˆ»‹æééÙ)ãd§˜5kVXX…BÑöíÛß¾} •®øYÚöØØØèèèÇM¯]¶lÙ©S§ ™œ¡êêê§N‚Ÿ¼õ£G¢¢¢Ž9"x«%K–„……•”” :nܸqìØ±aaa'Nœ lçNËÂÂÂNž<éääÔ³Š8p@[[{öìÙ=8µ§¤¤¶mÛ6ü†Ê°aÃÂÂÂFމ,W®\áp8ŠÌ;v 8pæÌ™wÞššš„Ï~ B&%%%¸Wçâ⢯¯vçÎXÖïØ±ÃÉÉ Úqÿþý•••p¥¹¹¹ŸŸßíÛ·#~¿fΜ™””?¾£££Óí«_£G¾víZpp°pͽÊéªÛq8`ƾD‚¦´ÖÒÒ‚ø{UU•ã+))‰žE¡Pªªª„?¥ªªŠÁ`t¥´all ”Ý}úôIJJêôš–––––x¨˜˜Ì£ñÓÕ;wS=l¯ZµÊÎÎnâĉ&õ«©©ñù|´R17…úúz4ººðóùüè—––ª««C`­ûÙ222°…'ÊÉÉíÚµ ª)|;MN¹\.~¸«7ÜÚÚÚñ¡C‡Ð:éäÉ“‚úW€òòreee¬âT*uøðáлÒÓÓÏ;—pýúuwwwA5t à ƒÁàp8hÎîââbcc#&&ÖÐЀ߱‰DRWW§P(„Ünâ¿ÿþSUUuppèÙy^ …¢®®Îf³ñ}IBBB]]]RRâ„hœÂ’•ìÚµËÄÄ„ÅbA<ÀÑшÈÈÈNÕuù|þgû’•••‹‹ N§R©(WaóæÍsçÎ…S#cüô铬¬, ·êêj” ¡­­ÝÖÖökªœ¡ð&òÖd2™°¡ð+#$$DOOoš~]—ÓL›6íÌ™3‚¸;JÂÃÃcccñÝ_ƒ¤¤$8—ó5´7à 0 ƒ±ZWW·råJð7l6{Ê”)ñññ:::æææ< ¬¯)Jwöå|||JJJº¹ÕñMàë뛓“sàÀ®*+Ü&6ìÑ£Gx‹ö5ÑgÔUzLׂ(DÙÞÞ† oÌ`0\\\Ξ=Ëáp½©¬¬lwôÁúöíKÐíþ":tHAAaÉ’%=Ð"?B óÙ³g§NQsáØ³g¡¡áœ9sУϜ9ƒ¶^¾¦ANBÈØé¦síTÀâWCPPPjjêW®× I$Ì¿{¡Ëa³Ù‚Ò¶:::ÝIXêèèè~`qÑ¢EëÖ­³°°èê99¹¯< êâ⢣£ãèèˆJ®]»†¦fS§Nõðð€Í•†††·h[[ÛVMooo¤QÚ»w¯¡¡ágc)`»YÙØØX???B¸’°®ýÊ8xQQ¡’qãÆ¡ÎvçÎŒŒ þ¨?HpÿE€¼ ži_òù|Á95~¡†‡——W]]^묹¹Ž”㸘_>j¾÷¶G¯Äççûø5Á¢E‹ ™L&ì@BùСCÙÙÙPhkk ºß,ëÙ³g†=~üØÑÑ>MLL„àÈ‹1™Ì &¼xñÃ0###(<sæ œG±µµ7n~üøqïÞ½†íر£¶¶ ÍÍÍQ(¿½½F£õ`ƒÿÊ´iÓfÍš7ÏÎΕ@wwwLïÝ»÷õë×𩵵õôéÓÅÅÅ¥þ …")) ^-++kĈL&SUUµ¤¤¢jÑÑÑðÝ¿þú Ÿ›HFvrrRQQ+eddþúë¯îT‡’’UUU&“9bÄÈ—ƒüC¸çÑ£G „ñý… Á§<"‡...™™™P8kÖ,8$tðàA(ôññÿúúõë¡C‡2™LMMM8¬£¤¤ —­_¿m“ðx<×;KxE/^¼˜0aÜöäÙl6íhjjzzzÂGÿþûopp0…BAm$..N£Ñà@ï…+‘sõôô ‚ÂmÛ¶á¥Aó•÷ïßÃe“'ONOOÿÒ*ÉäÝ»w3ÿš½s玛›”œ?¯ˆÿ®œœ\\\\¶bÅ ˆ"BÎ1FFF¢d$˜á¿$iãÆèÑøSAB†ƒÁäìÂÿªY³fMœ85 dí»ººBÖÙÑ£G322àÓ9sæ@.\hhèÞ½{¡ðöíÛ°Ý››kjjÊd2 ‡“¾+Þ½{g``Àd2MMMaýZRR2räÈ®^Èܹs¡Û3™Ì††ü‘Âxü¹ t¼ììlsss&“©®®^\\ !ÍAƒuUÍoÿ{Dm¿#Dm¿>Dm¿DmŸíÆ"‰6DAzi`MDA¾ ºLè5jfø°@/«™Lî55‚˜goj£ÞZ#‘qøÿªFß|3¢K—ó³Rè¾PzO¯©TSS—Ëåóù½¦F­­­mmm@ýÔ;j„ò-{Mø|~/«†K©í5•jnn†”÷oR£ŽŽŽo›@۹˩«« êM«.—Ü›jÄf³?~Ük¤ I$ôlàÜë5âp8mmm½i(Wl/3­­­ááá½&·ˆL&755UUUQ©ÔoÒâJJJ†††ß×åÈÉÉõ¾Œ5[[[QÆÚ/ QÆÚoáo cÀpú[2ÖàÀCï¨ÑwÊXûfADA„‚Ϭ¼êëëËËËŒŒPIEEœåVWWG^ôýû÷@ôdhhØ}VFF†™™¬õø|>¥Ñh@ÛŒaXSSœ[”••nÿêêj¼¸ššš¦¦fII žÈK__æß¾} ”h&&&ÝRùù�� �IDAT?MÝÜÜüþý{TRSS“——‡a“É a< AtÄÀÀ�ØkÞ¼yƒ?ˆ>pà@`õHKKƒˆ*"Dhoo)))÷hMMMMM þè_ii)ŸÏGsÂñòåK###ü4-%%Ã0*•Š˜ûZZZ^¾| Ó:ccãNïSZZÊãñP³¢Êâ›5''HØ �$µéééè?™L>|xGGþt¤ŒŒ ¼áºº:àùWTTì”È«+ääähiiá›=ÔÜÜœ°xE5¥Óé°fª­­Å“Ó¨¨¨À!VÔ—ttt¿r^^”hÙð}Ã0.—ûâÅ‹nr#VTT´µµáW>|ø�äl¨/aöúõkØz433Ãn>þ|È!°!ÌápÒÒÒð³ZSSS8N‡ Ñ.//‡Ó²øîTPP //ßÕh¤¥¥ <¸«]覦¦>àW¥UUU TÞ°àÀ�>ª,`РA¨§¦¦~–"ö›#55•ÇãQ(”Nž°Ùì?‚iTVV <˜& ÃŠŠŠð !öð‡!;;[GGÑG ŽV‚=|õê•p+ñ½\NCCCffæ‹/}}}¡°¼¼ÜÏÏNÎ5jÁ‚šššÞÞÞÀ¹;kÖ,[[[A&±ÔÔT‡””ø(!!áøñã0Z6nÜhnnÞÜÜÊzÚÚÚ«W¯611‰ß¾};rxþùç’%KâââVnnîæÌ™“““ãéé Í¿páÂéÓ§–¡«µµ555õýû÷>>>è�vuuuppphh( �GGG===ô•wïÞùøø€Û˜1c‹ÅRPPرcGMM è`váÂ55µ”””'NÀæÄ¶mÛFÝÑÑsþüy Ô””Ö­[‡NüÖÔÔxyyåççLiiiAAA@@€ššþHs§xñâ›Í^³f 0!Babb"(vHHHlÞ¼Ù¢¥¥%**êêÕ«`zþúë/SSS­>~üxìØ1&“¹cǨ¬··7pCÌœ9ÓÎÎNAAáÕ«WçÎ3½|ùò)S¦HHHÌ;×ÐÐ ±¸¸¸¿¿SSÓÁƒá¶d2ùáÇuuu¡¡¡@|пÿåË—w'@œ]SS³cÇwwwdž={vòäIàwÙ²e ʃf}ðàÁåË—aVô×_™™™%'';;;£!dcc³råÊâââ›7o>}úÃ0++«9s樨¨¼yóæÒ¥KàŸæÍ›gccƒ¼Njjê¼yóRSSÁˆ$$$´´´¬Y³æ³´¹¹¹T*éuBÇÇlccÃb±³²².\¸� ŽŽŽÓ¦M“””|öìY[[Û¼yó `6ÓØØ8sæL4•ÑÓÓswwõêÕ‚ ÐTfüøñ7n,++»sçÐXZZΟ?_CC#??¿¬¬ÌÍÍmñâÅ]…Èà¡yyy0±àp8ééé£FÔ–––——çïï(Õ«ªª#""0 :tèâÅ‹‘:†aQQQHy+''çܹs“'OÞ²eKSSz×/_VRRJNNîèèøóÏ??K}ûm‘””äêêÊåri4Ú?ÿüƒ'±nllÌÈÈÈÎξÿ>Ú®¬¬ô÷÷f ‹… jkkÇÄÄ  Þ¾}{ôèQ[[ÛŸål^½zUWW÷Ï?ÿ\¼xqÀ€Pèàà ¯¯£•F£âçjQQQÞÞÞ†iii­^½ZÐJ|G—SVVæááQ]]fØÿÄ À"=zÔßßÓ¦M^^^FFF Ïáè訦¦FPMNNöôôlllD%ööö0婬¬œ8qâ«W¯ª««“““áÎqqqû÷ï¿2~üx‚^ÐÂ… Aiêí۷ׯ_ŽêC‡-Y²X4¬¬¬Œ?+aP__ïááAàiñøW¯^½xñ"žñþòå˺ºº ÷·|ùrUUU Ã> CÁËËëÊ•+222|>_UUµ¼¼¼¡¡aóæÍ0ÍÉÉY»v-MÖÔÔܽ{7""yÖÌÌÌË—/"S!¸uëÖ»wïjkkñ…þùgYY0I9òÍ›7¥¥¥ÇŽóúôéÓ={ö’)JJJüýýŸ<y‚–_¼xÑÈȸ>—.]ª¦¦fmm¸~ýz˜èYXX 8‚¾¾¾øœœ¼Ã¦¦¦ˆˆ0¬™™™áááPîççwêÔ©îp…„„¤§§ª—/_ûXL&?}®¨¨8x𠬡SRRvíÚO=z4Œ%¼UÕÓÓÛ¾};†a[·n½ÿþ’%KŽ?>kÖ,˜²L“’’.^¼ˆ'1óðð ¨u…ׯ_Ÿ9s¦¸¸¯x–`nn¬0+W®V!—õë×3<„™™™¡¡á¥K—jjjœÖè ã1hÐ B³FFFVVV• rvv~ôèÑýû÷…§i\¾|¹ºº¯BÝÜܼhÑ"ð¯555 øì•'Ož¤§§Ã³"""ð.gõêÕ ³—••åããƒf¥ÇŽ#L´/\¸ÐØØ(¨/þ½1wîܼ¼<h333ÃsíTVVzxxÔÖÖâ;yNN™L†úº»»ßºukÇŽK—.]ºt)4úµk×ðÆóÇ#((èÕ«W‚Û0·nÝê”ɰ¤¤ÄÍÍ dÂ\\\`‚øƒ\Ž‘‘Q@@À£G<==Q¡¦¦faa!’†Å¯�„ÀÙÙÙßßB=€I“&ÁMZZZ@2GSSóرcyÿþ=šÏ–––•ÚÚÚ„…ÞÅ‹ŒŸá~˜Lf@@@VVžK˜Édª¨¨Àº¹•’’ñKKKþ\ºt ðèèh‡3yòdáËH–- æM›6mÚ477·îNºººbF´“'OŽŠŠ"‘HmmmãÇïN¢¢¢ªªª@†Jú÷ï_[[ ¯8ß0 Cr׉‰‰ƒF‘Ÿèèhiii‰4eÊB'>sæ ^óôK|”Ó§OÇŽ7.11fß]I¸P^^uÑÔÔ„(8×ÜÜÜwïÞIKKC`DH Ä+†466vª“DÀ¸qãÆçåå…—h[¼x1šŠ*)) ¬åMBœª­­ ª###cii‰Ö¨½` ­¥¥…F™L°bÅŠ+Väs€Q,S©TÐUƒ…r@@@zzº ßyIIIVV–žž¡ÉNž<igg‡¢‘ÉÉÉ }6f̈LÀÌàçkôôôž>} 6 ߬EEE999‡°d?wîܘ1cm?ûöíët€<|øÌðaþZ{9èëëgff禱±qw,r\\œ¹¹9AÊÞÞn"!!ŸË×ÖÖWUU¢¸ššš¼¼<\ihhÈb±Ð³²² >2þM ®®®©© OÔÓÓëÿbfjjZ^^ó4ï5jÔ‹/ �UUUegg‡bzmmm -&&6vìXø.°é¡ØwWì×=N«Ÿ3gÎ;wø|¾˜˜Xw–J>|`³Ù¦¦¦øåÂ!CáUXXXà·âãã÷îÝ ëŒ©S§B½Èd2‡ÃA¶¦©©)55U¸ _Ï0sæÌ€€�ˆ[$Ú¤¤¤ÌÍÍá÷Àžr™¨Yy<ZÃÚkРA°ó1tèP´ŽG*=²°°è¦”Ù!333((ÈÆÆFº h4ÚüÕa0\.÷?þPPPÐÓÓƒB 7dȃ—/_B¡‰‰É×Dçi4ÚgÕJJJ‚‚‚ÒÒÒ X,~‹m†©ªª"%KKËçÏŸƒ6eMM]§–¿2òòònß¾mdd„A½|ù²OŸ>ß$aì›cÊ”)0»…$~ˆÓ =×!C†@ç¤pý9.'..®¬¬ v\Ž=^]!&&&""b÷îÝŒ•+WkØÿÕÔÔ€¿K‡†âùóçýüüÐ,ûæÍ›†††_´ÄAQKqqñ®RÀÓÓÓSSS¡‚W¯^½qã>°æààpëÖ-h0¤n„Ü5jÔÈ‘#ÑÆ¸§§' ¬Ñéô#GŽÀÅnP]]ÔÜܼaÃÁ É×ÀÉɉXîo‚ƒƒ™L¦ƒƒƒ»»;*¿q㆑‘L”–.]ª££‚i=ŠˆˆØ²e‹šš\‰âc\.WSS½™ÊÊÊ3gÎ|‘–pff&Ú·°°èjå±iÓ&|`mÖ¬Yè#%%¥Ý»wïÙ³ï3 m ÍzóæMÔ¬öööööö[ÿ{_Wãö†ý4Ï#M%*ÔA¨ˆ2סÌCƒ#cœLQ¡C2O¢Pf•¤D¥A¢A”æa7ï]»ö¼ß÷û_¿ç}vm!޳ß}}ªµŸi÷Z÷º×uíØ‘œœìêêº~ýú3gÎ@Ã퉉‰?öóóƒ(•>Ä»wï<x0}úôo ËÉÉ¡ì|üøqíÚµ)))FFF(166öüùógÏžMJJjnn†ôÀÀÀ'Ožüý÷ß¼|ùò%Ú8™>}z·Zv]]]›6mêI4™%%¥«W¯ž;w.**ŠWéüùóÓ¦MCKØ5Œ3ÆÚÚšÿZó7„­­­­­íñãÇcccQv®\¹bnnNp¶ÿ&8qâüÁápˆw»iiiíØ±6ûäX/~nt`` ––VRRRdddWW×Ý»w{r‘ÉäÛ·o·´´àGðŠŠŠžä;¿ÉÉÉ/^¼xñâÅëׯ¿û!Ë–-»páÂ… /+))‰wŸ366–WPRYYîÃYZZzñâEuuõÈÈÈÔÔÔòòrÂèükN¥§§C<Hddä»wï>|øPPPÀg‘°iÓ&üÐó#Â3„9ã‹ÿá»w555¡œQðEMM x¨ñ(((€¹ëׯ‡Û 1 8pàóçÏQîåäææ>zôhêÔ©–––ßz/ƒÁà=ŒÙÐÐ�aßgüP±ÿˆÌøñã{/|æü«R¿¿-ÊÊÊð›ÿÄÄÄðѺÕÖֆƿmÛ¶ßb•ó­°··¯ªª‚i/„»¸¸t«Ù\WWwýúu¼²¬9âããyç€ÙÙÙòòòøÐíÞ ,,ìñ¬¬,|”$<ÖËË‹p$ÓÇÇÇÆÆ/ C§Óïß¿N6€ººº¥¥%h;VTT´´´”••áãd~ ‡¾¾¾|Fuu5‹Åª­­åu‰ )’a_açÎvvv„j¥R©Ïž=ûÖp üàQÐöööÄÄD‚ èýû÷QQQhÏÏd2 a&)))ºººø :88 Xj&“ møÇ'€111ÚÚÚ„Oê%:;;}||œœœð‰%%%aaah»å›ÐíÒ§Ï‘––¦¥¥…)8v옿¿Ÿ/ Þ¼y“žžÎëÍÌÌTUUíÃãú} Ÿ©S§v«YE&““““ñ>ƒßä >¼¦¦ö31 ƒ-ʉ'~úô ‡ ÝõÑ£GcÇŽÅ»Ýâãã ÊsåÊ•p=›Í^¶l\ÐÔÔ„ž<hР™3g2D[[;::Pí>|øPKK ?=œ>}zAAIOœ8±7zÏÝBWWwÈ!ðF …KãÜÜ\.—knnN"‘’““a3\WW6WçÌ™“ 'Šlmm!ZzÅŠQQQp aÕªU†±X¬wïÞÁÉ!ƒáä䤫«{ìØ1xïƒ>|¸téÒ>©ÔU«VA¼5‡Ãè>%%%[[[ÈFƒí–²²²/_¾ØÚÚ¢ÛñãÇ»ºº`¿‘P­h'ùÁƒpêð%K–(**º¸¸DFFBfÿúë/ø©­­íìÙ³øÓ9466†¶··ÿÈ™üe˖ݽ{Â¥ @ˆÁ`ܺuËÅÅ…Édæää466BNÁU=xð`Þj=ztVV$*++Ã>GmmíÛ·oa7n̘1êêêøé^\\\@@@_SOKKCs ;;»!C†Ìš5ëíÛ·àFŸ2eJO©RRRóçχ/‡¶^‘Q£F¡Îa##FŒ ‘H(&&Ö›`‡ž ))É_"ß[) Lž²³³ÅÅÅa ˆŠŠš0a‚™™Þœ§§§Ã©ƒ™3gþ»â¤nnnW®\…fX«utt<~üxñâÅÝ^o``PZZŠjy cbbŒŒŒ¾isîWÂÙÙùÖ­[øÞJ£ÑîÞ½»|ùrƒ‘ []]]„À㾂˜˜˜˜¯¯/ˆò~úôIOOÁ`466‚ÍfËÊÊ¢˜îJJJfggS(KKK˜R555Á©®E‹ÁùÕ«WƒF§U`j6a°®S§N½ÿ>¨5C”*‡Ãioo§ü222£FÒÔÔTTTÌÈÈ P(æææÈÌ`0Œ÷íŒ5êÓ§Oeee eíÚµ„”ÒÒÒYYY#GŽä]åN~©©©õë×/--B¡Œ9òÏ?ÿÄ0ìÓ§O4MOOÏÐаµµµ°°B¡ÌŸ?&Èæææùùù••• eÓ¦M°k5iÒ¤„„„ææf …G1$%%Ç÷ôéS …"//¿iÓ&üg°X,EEEüÚ‚Éd¦„„þʪ08vuu7m½ÚÚÚÞ»wB¡°X,ˆ)’••511yöì…BQWWwww‡•eEEᥚššˆˆ¯Ö Àe æ‡ªÉÂÂBFFfòäÉñññ---+K4‡ƒ_¡ªªª0 55•B¡âÄÅÅkkkЩۄѣG£=kk뤤¤¦¦&(^ØMHH°¶¶–‘‘9rdBB…Béß¿ÿš5k Zû÷ïO¨Vhêyyy eæÌ™0F˜šš–———––R(ØÁ",/&NœˆÖs\.—N§CLs·]«£££±±Âb±ð\U ƒ‚ðaÃÔÕÕÍÍÍ +**(Ї‡>j‹J¥Nš4 F ‹'OžP(999X£¨¨¨èèè¼|ù’B¡ :J11±œœ …2iÒ$|(N722âO˜D¥R­­­Á´‹‹‹Ož<YTT´  �V¢ÖXCCCYY™Ð[‹ŠŠØl6LCétúСCñ±ycÆŒÉËË«ªª¢P([¶lÁŸš¤R©?#ð¤[û››kdd4mÚ´GµµµÑh4 îìì|õêr<°ÙliiitœnÀ€²²²™™™ÐP`*ƒÁÐÕÕíå!îŸIIÉ’’è/]]]æææ ð+šÚÛÛah¢ÓéIII–––rrr#FŒHLL¤P(0Wãr¹ …Éd¢MÜÞ”-“É”””d0\.7===55U¨ úŸ„cí÷‡Pô?¡*èW›±PT!„Bˆÿ$„&G!„Bˆ_„îÃDEEÿsg²ø;0 “––á?Ȉ”””ÀTlHHHLŽ ŽÄÄÄ©+1™L ²I`º’¤¤dŸTè ýt“ÓÑÑчb~p8œŒŒ ÙËÁ0¬­­-??‚ôµµµx3¨#2™,H]‰Á`Ðh4ètzVVÖO:ùø¯ ©©‰Ëå¢CÙ?á*çÛŠLDDäg–ü[’’’¤UŽ„„Dkk« Í ÅÄÄØlvGG‡ÀäHDDD^^^ðÈ‘À˜)))IIɾÄÅÅûvý×})KKKëAËßJJJ/_¾444¤ˆµ’’’Aƒ RÄZgg§¨¨¨À4<ˆXëèè˜AÄZ^^ž ŠŠŠ™™™C‡¤ˆµªª*¼žÙ6c¡*¨B!„ÿI|e-™ŸŸÿìÙ³-[¶ ”ÄÄÄk×®a6oÞ<D+råÊPÙ¸qcOZ~›7o>pà�œHb³ÙpðUII ÑÌaVZZ|õ€×¯_ÃùÞ3f ž‚¨¨({Zµj0{†††âº8p —$Ó•••ááá@^ ÈÌÌ<uê†aS§Nå%Œºví0’mذ†„„�õ�àðáÃp‚ÏÃ㣣CDDÈØÛÛÛ7n܈.ÓÓÓC¥ïÞ½{õêú•0`éÒ¥_å÷ööÞ¶mþ¥››—Ë•——‡¼`VSS;lØ0<"?f0¨Z¯^½ ´]ãÆC—íÛ·oåÊ•ø^¿~}gg§˜˜ØåË—!¥¥¥šÍàÁƒÞ±°°„ã�“&M‚³f½ÁÁƒ/^Œýûï¿õòåËxÕ Ãêêêà|±¯¯/†a¹¹¹xÆÒiÓ¦)Cllì½{÷0 svv¶³³Ã0ìÌ™3x¦;???$ÕºmÛ6???Ä€oýû÷?räÿ,$&&666â &®_¿þìÙ3 ÃÖ­[‡ÎÌû@@@�þ°óºuëÂÂÂà*•Jݰaú J¸¸¸øàÁƒ(ÑÒÒŽÁÆÇÇGFFb6þ|8‹aØ¥K—€DÃÓÓÉòòbÆ Çï–ð/_¾Ü¼y¯_––ªÓ§O_¾|9áúðððääd¨;t€ôÀ ü‹:€Ëå®^½D@~ÜÝÝ™L¦´´4^± MÐŒGÆÃ””hðöööÀhކ&�¡ãüz<xtx<H8ÊårÝÜÜ0 SPP8yò$¾ã�LMM·oßþëLÎçÏŸ÷ìÙÓÜÜŒ?œ””ôúõkè6yyy÷îÝ›7oÞÕ«W) $Þ½{WTT”Wš×ÓÓ3::ø}¡»BŸzÚ°°°êêj///2™Œ÷}¥§§?}úž\XXxóæÍ¥K—FGGWUUAbbb¢¨¨¨•••µµ5Zìûúúâ•¡{BCCƒ§§g{{;RˆÁ0,'''66^\\tMÀÞ477ï÷ïß×´´´I“&!Zx íX¿~ýÌ™3¥¤¤¸\®‹‹KDDƒÁHMM=}ú4ZÎC¦8ÐØØˆo h`ºuë^Š›»wïþòåKjjêúõëQ¢‹‹ËÒ¥KA/¨‘ëëëà±$éàÁƒx»xòäÉÃRDDD[[Ü+&&öÇæçç§§§ã®[·nöìÙ’’’XCÈdòŽ;àÞ––??¿�Y5Ü’šš r_ÅáÇsssß¼yƒ—Ú´iÓÔ©SÁUíêêzýúu|µîÛ·^ÔÐÐàëë[__O"‘6oÞŒÆh ÃîÝ»÷éÓ'¸òõë×¢¢¢S§NÍÉÉÑ××GÃÐíØ±£ªª*%%Ï9‹òÒÚÚŠ§çÅË—/Ïœ9SYY‰×.ºqã²@=µ°°FR7AAA¾¾¾ ðððhiiILL<~ü8˜&“™’’‚¤ a§®®Ž>)==f`Ïž=ËÌÌ„ôÜÜ\‡Ë—/wvvB"Ð2¡õ7nlnn~þü92¥Û¶m"¥šššíÛ·“Éd< `FFÆãÇá±EEE‘‘‘hŽö¦££~ŽŽ533Û¿¿žžLR÷ìÙˆøÖ\\\Àÿ2üõ×_óçÏc2™«W¯†œÊËËCCCáã«««;¶eË–ÔÔÔçÏŸCb~~þ;w,X0zôhD¹rêÔ©¾ÚÀÿn{3pà@˜RìÝ»OýàââÓæááqêÔ)EEEÔ„ ~RH&hQòòò@`PUUE¥RaÒ——ÂyEEEFFFxëÖ-^`OOÏ)S¦<zô¥<{ö †‰††à–PQQqwwÿüù3R*Ã0lÈ!Ë–-ƒãèeee`®?þ¬  �¯{üø1T*š©ùùùmÛ¶ÀSÒ-ÜÝÝ+**nܸI$R}}=<¼®®/&aØÇõôôà×Û·o#u QùòåË-,,$$$¸\.€a&--MX¯hii¹»»gggã_4xð`£££ÑÌ´[Ì›7B¡ Ò3@BBÂÕ«WA¼�Ø”©Tj^^È`§¥¥ÁÔ¸¸¸ììlü µ°°UkTTdvöìÙãÇ'XÁåË—O˜0A\\œÍf•ƒÁÈÈÈ€)ê‡`&د_?xZZZ—ËÅÏÓù`ÆŒüñh3#$''ûùùÁ>a%ÚÕÕõöí[Žß¼yƒd 555 …?zôèQ£F¥PRR1233#\9þüŽŽŽœœ|"\ÓÞÞîááÛ ÜÝÝ‘°!j3RRR°Ž‰‰‰©¯¯Ç0,;;©‚@ðÞÒ¥Két:AæNJJŠð‘***ÒÀ‚SYYÙÕÕé999ßXPP€òxýúuà£#`éÒ¥4-55¥°X,ÄT­¬¬ìîî^RR‚oHõõõMMMðØŠŠ ‚dÆÄ‰€+Ì-TЬY³ Õùúú¢Éߊ+\]]±ÉILL<sæ ¨‚âe1 #“É?~LBB8!†ª¦¦$¿?~q&###˜ûž>}zΜ9ÿ®~¨UÁ7ìÛ·ÀŽ2ÒÜÜ P999¨¾?>}ú<¿Îä�¤¨¨(Þä̘1ƒL&à 8qâD‚:VOHOOߺu+ÿÝ9999àÄÄ› XkƒžnoxÑsrræÍ›‡…ø@FFÆÖÖ6??or,,,jkk!ƒ£G×Ä+½žâ�� �IDATWáããS›“'O‚» 1ÏŸ?éô477Ó 3***¶¶¶L&“`Û�eeeü=„Ð] ÁxwïÞ…ÅŠ´´4ÒPáêêj:®¯¯_óñ8 z*ˆdlÁ‚½Q®%‘HÍÍͽ” &Ê£Gâ/]ºäéé #òíÛ·{óœ×¯_CáÏœ9¬š—\ºtI[[é™Á ÷àÁƒ »Ônã˜LfVVVDDŸWƒ(Ù—/_ðª È_:fÌ>ЖñTmmmä;466644ÀDmöìÙQQQp¥••€®_¿><<»å/ïÁ¿TVVù{¡·ª¨¨ðÎ]zrB„„„L™2^túôiàåCŠ0¥@ÚßHkîþýûT*Ü6EEEÖÖÖÿÑè2™\VVÆ»öý{9äææ655÷699ùõë×K–,áËúõë :ði€9íÎJ\\\zzº»»;3¿Û- 77· §ùôéSQQd0+++!!ÛkÖ¬¹té|yII ìy!?ž¯¯oPPò’Í›7oçÎà¦WRRB:l$ ܉|¾äÖ­[\.÷«ÅÛ-‚ƒƒa†ÒÕÕuüøq…ä_•••kÖ¬‰ÅWÜÅ‹!³Ÿ?þêôâÏ?ÿܽ{÷W tÓÓÓ_½z…Tø¾aaaîîîàÃÜ¿?^©OSSsïÞ½h œâãÇGηììì3gÎ ?dxx8…BY¶lLn¼½½‘°ÛÉ“'===ù˜Æ®®®U«VÁNÉ÷áĉ@ ýMÜçòòò¨-566‚WíD&&&"¯iNN™L†öœ”””žž¾pḸ8mmm097oÞ411éiÿ:~ìØ±œ¶ÿóÏ?ªªªóæÍwýµkצM›U'Nœ?~¼ºº:HÿWB–>|øîÝ»¿þú ¿ñfllü}B}ˆ   cÇŽÁ~ºxðàA·ƒð§OŸ.]º„ßvý7MNCCFƒa%99ù«žÊõë×;88L:•°Ä?~|PPøÁ kXž={–’’²aÆÞÈ~üøqîܹ=Q ÛÙÙëYYY™Wá ùå[ZZ ƒ………àÊû¼Ö¬Y–Q&ãås¶lÙ‚NêÎ;w×®]hW@\\ Ç………H¶ '@Ùöž´•° 7n8Ö€žRRR<<<!•Y˜ƒP 888øùùõfäjiiimmÅàqêÔ)¤€ëçç‡ßüÀãÝ»w¦¦¦0…c¼ÇÉÖÖÊ-??Ö@***øÂGÕzåÊ•––ggg4:t(Z8p ££ƒO^Ølöû÷ïñlüß„“'OŠ‹‹/\¸ð[µ6ðméãÇøè2™ÜØØˆ²@"‘èt:\œ˜˜¡®eeefffÖÖÖ¶}ûv}ÞíÜŽÍfã#t¾GŽQRRrrrBç -Zͦ¸¸˜N§/X°`Ë–-&LøOœgxüøqffæºuë;óeeeæææÿºаaöoßm©Šà=:0“Éd¼—›J¥VVVþˆfy_šœoEqqqVVÒ455ÙÛÛ'&&ÊÉɉˆˆ@Gå¯üøüùóøøø­[·~ßÈK@hh(´ã™@ikkÃÐŒºÍ–-[\]] ‹Ð¹sçîÞ½{̘1¨çÉdWW×Þ;"°_¥ ÚÒÒ^û¦¦&§…  °ôüÏ;88ìÝ»×ÜÜüÇ?xþüù(lé»OHKKCëBꇯ^½ŠG³@DD‰DZµj~hð÷÷Ÿ2eÊ/à~>uê—Ë]ºtéwœënoo_¾|yŠ—oܸ‘>}…£GÊËË/\¸°' @~~þöíÛ!‘Á`̘1#>>þ÷´7qqq©©©žžžà^û=Ä2º=Î Ý-ë ~®É¹rå N‡¿çÌ™ qKKËÞ¨AS(”ŽŽŽ^ڛ͛7»¹¹ññ?ÿà˜xüøqmmm‚ÐKyy9¯voqq±žÒÅb}úô©—/ºqãFgg'>íçaöìÙ(ÂðêÕ«HÖìèÑ£ºººéÉž—†††½á¯KKK{üøq```Ohjjþ xAmmíæÍ›£££ c4Š@� dÂT´ººšB¡ôæEL&söìÙß½Å]__¯­­ý}<"l6›°þF^µÛ·o‡„„|ë{n󃨫«355åoo0 {òä ›ÍÆ0ŒËåZ[[£Ïßmmm]]]¼öæèÑ£†††ü£~~ 6nܸjÕªžVáÝÂ%%%‡ÂGëýË&gþüùT*†õ%K–À¹Š;v>|wîÜ 3ÄÕ«W{xxà €¸¸¸¾¾> L×®]ƒŸTTTž>}Êç=BY¹r¥§§§‡‡Ç‰' qÓ¦M p cŠŠÊr<ØØØ´µµÁÃgΜ [/^äp8kÖ¬quu ]£íÛ·ƒ¯öìÙ³[·n…•iXXÚí=+ Ã$%%333UTTnܸOÖÕÕå¿ÐÚÚÊår¿[Û433ÓÜÜœËå*((À)¢Aƒ:tÞnll ]III ÁÁÁ( ÿþ]]]àgwss;|ø08‚wìØÁ_/ËÊÊ 2+--‘‘¡ªªzõêUxžžÚv¦R© åÇg…OŸ>]¼xqkk+†aÊÙÑÑáààðâÅ uuuOOOxõðááóLž<™·Z¡îÐFמ={œœœ‚ƒƒýüü š?00‰ò‚Ëå–••œÝ÷áðáÃ(ÔíŸþ±³³;uêÔöíÛA¾/44´'K ¨¨Ù4hЭ[· ½³³³­­ _¼‹-ºrå \¹|ùr8‡±{÷îƒþóÏ?†íÚµ«—bØòòò(b­[LŸ>B¡À»@øÌ™3ÒÒÒ´¹ÿ~fmm a `>Ïœ9£¥¥…<\.WDD¤'ìÏÀ«W¯¬¬¬à\NJJ ˜ÉuëÖÝ¿øðáÛ·o‡¬3å"&&®Ä0líÚµ0Glhh022"„Øü+ðóóÛºukAA~h²µµUTTDÑ’’RBBÜB§Óz³‹ñÝøŠDN§R©µ>˜ÊËË£À0¸L¬àš››ð‡ÈH$’ššš ƒ[YTTþ‹Á` -_ úºº@¹ ''I¡PÀ ¤¤„‚µZZZää事ã#ÑÆd2Éd2~ªK£Ñ`,“••…8´ŽŽ¾ñ9UVVFæ­¹¹|8jjjÐgH$‡ÃAÏ„Q€Ífƒ#Q\\l“F£uuuá'¼T*•Ãáð‰»#H´544ôë×"ŠWDDùIX,D¦JJJB ó¾ŸÓn«­”””8&>³èÝf–·9á½a|$ÚºmNðR([.—ÛÐÐ�m åTBBÕl·ÕÚÞÞŽo$ЖZ[[aC®_¿~ø7 ™Ëå’H$>n(‚D•Je³Ùh$Bm€ï8Жú÷ïJVE¨s8[ÿjñ¢«  €¶9a†Î[³¼K1üK m¼}uXÔUÛÛÛ™ µ%€ªª*tÕ¦¦&ؾF}߆Ï /ÑFè5l6»¹¹ºƒÁ�””””0atBã!…BÿñmÝMhæ„yë´Ï%Ú¾²Ê‘’’" ârrr ~LÓñšÓÐ] ×àM )@£!@FF¦ÛU‹¢¢"ï$¢Ûì«ÀJhì#|>7§½É,@LL¬Û\ó§ó–0ðÆbò¾H\\œÈû^BäE·™åuFõ>³¼Í©—øj ‹ˆˆ ÞœöT­ÝFšôäì"2Þœ÷r øjî6§Ýn±ˆŠŠö²x»í°ÊÊÊ_õqa_Û×áí;¼M_zÙ–¾:DüTÞ(&&†*]RR’ð+ŸÑé÷ñþñï8¼%Ì[§}!ÇšB!„¿B“#„B!Ä/B÷Ž511±ßjyøƒ€ã8 £ @s©&iiiË‘„„„ 娣£CTTTrÕ$///H"@†ÉÊÊöU5á·<–Éillüÿ""", Ñ ØlvLLŒ éœB8@ZZš e¨©á ØàÀd2ÃÃìŽÊËËûjpÐÒÒ255ý¹&GUU"Ö|"Öþ£ D¬ �øG¬ýAˆXŒÑ±&ÀG¬ FŽðk}ÒŒ…mB!„Bü'ñ• i:ÞÑÑ´ëèè�Kä+lkkƒCªªª=¹Dëêê444`7¥¦¦¥‹‰‰A,&“É„“RRR(P¯³³ŽSÈËËC%…BÁûUTT ¾©© ˜ÔÔÔz•â“ÉlmmůºººZZZ`²ÀHÊ›Sô^€††:^P[[«¥¥…–Vl68êÅÅÅQ¨"FƒxBœ7…Bé +6‰DêׯþX”0>”¯¤¤$þTííí\.ªåЯ_?ˆ¨nll„HBNaà ȦÓ" (a>™åÆÆF%%%|µÖÕÕ#Ž@o…a‹Å‚3+(§è½hˆj–B¡ˆŠŠâ£¥›››á\NÿþýÑÌ—D"±X,p2àwá|LoÂy;::Øl6>P•0jÃøæ¤®®Ž?—ChK(§ÍÍͨ-Ñét T@ÅK¥RñgG¡9µ¶¶Â)>¶§—"0 2™ÌÛ–¨T*“Éäí;ݾ´Ûæ ˜·f…ø466*++ãÛRO%Œ:�?÷!Dù›²²²˜˜üáàààààpúôihÍÍÍÍÁÁÁËËþ‚aXUU•  ÃFŽéð?�ß(˜AÊöíÛah¦R©ÑÑÑxäȰׯ_G÷N˜0dxH$’··7$&''#r->`±XeeeIIIx¡ÆÎÎΘ˜xΡC‡ìCÍÍ͇†_ïܹãÅêÕ«§M›†> è8+++ËÊÊÆŒãØ›wïÞÁ5ëÖ­“@£Ñž>} ‰ûöíÃ+—´µµ<xð«Ì555eee3fÌÀ[ñòòò?ÿüÓÁÁaÉ’% 4Ãd2ÓÒÒàE[¶lâ%€L&‡„„ Nâàà`”¯7oÞÀ@¿yófHIOO‡ÜUVV.^¼ØÁÁaÞ¼yåååðñèF$çÚÕÕõøñcH<pà� Ž_E}}}YYÙ’%Kðš@UUUË—/‡GÄ{X,VFFüäéé –ïŋ蓠TÛÚÚÊÊÊüýýñú ~~~pÙ³gÏ`ô¯®®^µj$æçç£s¯'//ï«„Áeee'OžÄSÑ´´´üóÏ?„¶T__¿uëVH|ýú5œ‘„¶daaŸÙ@NÓÒÒæÍ›‡æ.qqqpïÞ½{¡-=yòåÚÊÊ v,ššš<‰<è¶ÃÂKÇhj9R-b2™eee xC4Dœ>}šW³®¹¹9((^zÿþ}xi]]ݦM› 133šSEE ­ÅúŽ““¢Êż% l¤¨Á Ùâ_´ÊùôéÓêÕ«©Tª±±1JŒ‰‰)//BÙC‡]¾|yëÖ­!!!FFFÐÈÜÜÜTTTfÍšEÈÉßÿ ãÿ¾U\œÀJ[SSsåÊHLNNþûï¿£££222 ñÌ™3'Nœð÷÷ß°a°ËH¤#GŽÀ”|Û¶m®®®  fgg×›ý.‰âWøévrrrbb"¼1<<<$$ßyŽ=:dÈøuÕªU***@GvñâE©ûúõë›››ñcD[[›³³3èâ®X±âÅ‹………ÉÉÉðÀ;wîøûûÈßÒÒrùòå»wï~•fÍ××·¨¨ˆài?~|]]0IO˜0áãÇ•••>>>𢴴´õë×ãu àó"""nݺ…å0 Ûµkþ_ ÃwìØ6QQQººº¶¶¶999ŠŠŠl6[GG§¶¶VUUÞÅ`0RRR€‘%333** Ò£££÷íÛÇ_¾pøðá´´4‚DÛìÙ³Ÿ?+' üÔ¬¦¦fëÖ­ð–7oÞ¬]»è/íìì@áÞ½{gÏžmllj”å¹sçÂö¸½½½††ÆØ±cwîÜyúôià Ñ××ÏËË“——çr¹>|è¢ÒË—/÷ïßßÖÖ†gç»qãÆÈ‘#<iÍš5JJJsçÎݸq#’h a``àááÑØØH0 ,+33sË–-hå÷öí[ÔƒbccýüüΞ=»páBPhnn>wî4õË—/Oš4 ìߊ+TUU§M›FøæM›6‘H$üK;::ìììJKK¡Að¼£P(QQQ—.]B†!88ØÔÔôðáÆ9;;«ªªNŸ>ÝÝÝÝßߘ¤ÇŒ«££³zõj …LkBü³²²xe >þìîîÞm ¼zõêßq¬™ššfdd¼xñ/4>|€{òϰxñâÛ·oãítW°=À’­§§ÑÙÙYZZÚØØØžÁÇó 8öÌÈÈÈÏÏÇ«'(***))Á·uuuõ’Q´´´üà}züø1öÿr!Å<¹¶¶èåÍÍÍÍÍÍ)JEEE{{;º>22²«« 6ùæ­Õ�“>ˆˆˆP©Ô^’ß¹s‡D"mذ/ÑVSS<hÐ ¤A‡aXIIIWW×àÁƒ¿êÀ,++;pà�AÑò›�|VˆI0lذϟ?ƒ¥ÁO‰ø€L&C^TUUÁŸàæææææ$r:::mmmp¥††ø»@Ꮟ˜Á` S&“iooŸ——ÇG] ÈÙ³g_¸pßùH –P ݞ̀h!AP ¥¥eíÚµ÷ïß-a𪩩Á—“ÉdMÖåË—%%%AF (檪ªÚÚÚTTTºõÜÞ¿ûé>EEEQ[ÒÕÕ…¹ (ñ ÄÅŽÿ~ç쬣 èìì„Ïëé¥�àûê–ÒBˆoLéxçÓ§O/((�=\h4Ô‘œœÜð~ÿ^&L(//ß²e Ly3ËÂÂB}}}ÂØ4jÔ(xˆ‚‚ÂþýûÑŠ¤¢¢bË–-C‡ݾ};ÿÇVUUÉÈÈ M&}}ýÆÆF Æï@|+LLL>þ ß6~üøµk×âÕÖÖ¦Ñhðä$444¼zõ*8g¶nÝjkkÛm苜œÜÖ­[áÉšššø¾ZPPàçç7zôè7‚o‡Éd0 […àÞ $$fî²²²0榦&¦­­_–éèèÄÆÆ&''c¶|ùrGGGä?vìXqqñ¶mÛøÒéô/_¾ qJQQQMM J‘¿{öìÙ³glé´¤$%%õõõá-hàSVVnoo‡Â·°°X·n]OÄ…...¡¡¡P›k׮Źû÷ï'‘H{÷î…ú}÷îÝË&VVVž>}zöìÙüYS `³Ù………„u¼¾¾¾­­-äqÔ¨QȤƒ…ËåæO7nÜHLLtqqéå¤DFF† þÀ»UC¡PzÒQœ?þÙ³gA4ÖÙÙ⌌ª««Á„#ž?ïß¿711éö„¢´´´²²24!}}ýíÛ·#íƒÍä<~ü¸ªª ȉ:‰wJðâÇGŽ !,Àå{CCƒ­­-Z6 ><11199y×®]þyNŸ>m``€VNûöíÛ³g(?VWWw{KFFü!!!Ñ3]ZZÚË—/!ƒááá§NÂ;ÖÖ¯_úôi ©sÂ7qâD##£néoÉd²‡‡r¬mذáÅ‹È'&&Þ¹s'$$dÏž=QQQ «V­âuˆ÷³fÍ"8Öø\ÜØØxûömQQÑõë×?~¥{xx m¼•+WjhhÌž=þ…ÅðáÃù¬Gkkk÷íÛ‡ŠÝÌÌlåÊ•PzãÇç½¥¼¼I¬ödÒ–-[Ö“cMKK+$$ü]ííí@˜%ŒÖ…„j%ø"æÎ å`oo¯««‹V°ÖÇZAAA``àÇñîâoEyyùÅ‹mmmmmm{‡ÃyùòåÅ‹###ñ'~Þ¿ëÖ-Èflllpp0:ˆÅb±Ðzàííííí½bÅ --­¢b=zt·T*uÁ‚àXãEKKKlllkk«——W·g\ÂÂÂLMMA:ËÙÙYKKkúôéGݺu+´Ï_¬Úòÿ'Þ¾}tóæÍn¹\uttP7IMMõññé®üÏ59ß OOOWW×ÒÒÒÒÒRƒ‘––6kÖ,qqñÔÔTpX#tvv!á–ï�òØÙÙõ䈃¨*%%%üŽñ7í$ptõÁƒóqŒðA[[[UU~ºúôéÓÌÌÌÕ«W§¤¤TTTHHHTWW÷I|}Oxþüyrr²‡‡GJJJYYN¯¬¬4hPII‰¬¬,ajü#™ý“'O0 ‹ŽŽQ8ÞAƒÚöíÛ{É«O€¶¶6¼åÍ›7 ÍÓÜÜL"‘¾ûÄOvv¶±±1~ þóÏ?£££SRRÚÛÛ Æ›7o¾ªÀMÀ—/_"""¬­­{ã* ¸>\\\®_¿ž’’RWWG¥Rsrr¾©ã|þüYAAOÙyëÖ-öÜõ±±±^^^)))Ÿ>}ª©©ùòåKo<3H ÷üÄB|7\]]ÀÀápãðÂÿ¾É±°°€] Ã:::.]ºdkk+..¾`ÁüÌ< [·nEâ_í3222ø8//oàÀüCú~ü¬þ§OŸdddrïÞ½^^^ß§ ŸŸŸìر»wïâ‡KƒˈÒÒRQQÑÜÜÜŸjr` o,++ãp8ÙÙÙƒ ºxñ¢‘‘!|ÀÏÏÏÇǧÛ ïÈøöíÛ &à'Âü#‘V­ZõƒGA»ººrss Õ‘ „ðoš9]½z©;cfkk %Æ`0¨TjDDÄ·šœððpmmí3f|ëLj‰‰M˜0ÞÞÙÙ ¢®|†‰ÊÊJ&“‰_yŸ={ÖÌÌ öuÓµï†ššš¬¬,|Pܧ¥¥}Õädgg|÷ Fˆo…µµ5,ÖÁäœ={orjjj<==ÿµðn1hРòòr˜B‚“ð#F´¶¶B¢––ìû½yóÆÐдµ#FŒ¸téìÇΘ1®ïêê‚S…‘#GBb}}=x3´´´ú÷ï®6l<êúõë°0GOJJRPP€)¹±±ñw“ ihhhjjÂ) lM—””p¹\ƒÌÌ̦¦&CCC¸rjaañéÓ'ˆ733ëIw@RRÒÒÒžÜÖÖó÷~ýúéééAbCCÃÈ‘#íììÐ*-88XRRò;h fΜùäÉ:N999333ô"ëëëëêê&OžŒŽÇ?~¼«« ”@[ZZàMMM”Ù?‚7é?þ€Ú´³³KJJ’””äp8(𣹹900—XWW Áu|ÔÏ¾Š©S§¦¦¦Â²Fm‹•œœlgg×ÞÞ~ýúu¨ŽÆÆFÈ©†††––ªV>VÍÌ̬¦¦®444„í+kkëììlu<y²¸¸8RØkii±´´D‘åß„ÂÂBÔ•ÌÌÌ´´´ÆWRR{T£Gî¶-III!Ÿó—/_–/_a`ªªªC† A=í3=~ü¸££cñâÅè &&&¨Ãjkk÷’ÀB\\¼'ÿ†acÇŽE_^\\ &íÓ§ObbbúúúÆÆÆmmmðÒÂKãââ a¦8vìXc9û g*ÒÐÐ�óTlmmåääF uD"‘Æ÷/˜uuuüDuÊ”)¶LæÎ;wî\ Ã\\\®^½zûöm Ã<<<ÌÍÍ1 KIIQUUÅKÌœ9„‡‡C8–’’Rhh(´B//¯½{÷Â`çåå…aØøñã9œ¢˜>}ú’%Kàvccc‚¨É–-[Ž;ßàçç×Ó&/”””ð;·üñ‡ÃŠ™2eг³3†aEEE`rV¬Xqýúux˺uëÀ.z{{Ãú, �ï¯ppp@Ût !!!°5§­­ ;±Ã‡wss;räÖ]´Âðáà ¢U=aÚ´iøáéÊ•+ýõÂh¨©©¹k×.___ ÃŒŒŒ¼½½aR“••…_v¢#MÎÎÎÙ 6À<z×®]„Ì<xŽ3gÎxxxtvvЉ‰]¾|n—‘‘!¸ŒŒ;†aØÄ‰W¯^ýM³3|,{hhèæÍ›aûv˜LæƒìììÔÕÕýüüvíÚ…a˜„i˜››s8( üi’#Fࣧ<<<N:¹ööö†íÓàà`8̆÷ƒKJJö2frÈ!ø™˜˜ÄÅÅÁ‹ £iiiÀ.øíß¿ïÕœ3g^‚ ''‡ö† ¶jÕ*}7nܺuëм°ú_¹rexx8¼zÓ¦MòÞ-ð/•••%P«©¨¨Üã�]]]ASXXnnnW®\—nܸ,¢¯¯o@@�ljã¿ówr Lž<¹[m$TÂt:ýñãǶ¶¶ عsçž={`ðAâ‹Ã‹c�� �IDAT¹}‹¯¨‚ „k¿?„k¿?„kÿ ü$޵¾Rr¬ !„Bñ‹ 49B!„Bü"ˆ÷´‚˜e&‚¤¤¤ÀH´‡PRRR`ª v­ÄÅÅ&G° "&&&09Ý)¯+Á('!!Ñ'9#ûý“C£ÑàТÀ€Ãá ’ Y{{{YY™  «¯¯—””äÝ$ÿ©‰L& RW¢Óé CÀƒQ\\Ì˵üßE[[[eeeGGG_Mû0˜°{“Ãf³Ñid�„Q(AZ±q¹\*• ‡[c•Ãf³!’E`V9,‹Éd LŽDDDDDD8Ž °hoo˜¹W€Ò>iÆxiŸerdee!ÖY0 ¤¤ôöí[333AŠX«¯¯744F¬ý¶€ˆ5‹%0] "ÖJKKipPTT,**9r¤ E¬µ¶¶ UA…B!„øÿ_9iXRR’––†?:—‘‘lêS§NEÇÐîß¿Ÿ™™‰aØÒ¥KMLLº}Ô¡C‡6nÜ'}}}‘GHII ÎÕÖÖÂa=}}}ÐmCxóæMSS0Ø'&&"BL Ã.\ÇÊ®^½ çÃׯ_ß{ó^WWwïÞ=¼,M~~þÍ›71 7nœuÅãáÇÀS¹xñb8?ŽW Ûºu+Q€�Ð|aF¡P€TCCãï¿ÿ†ÄÏŸ?˨Q£-Z‰¯^½zúô)†aÓ§OïÍ©ŽcÇŽRJ#222püÃ0‰tâÄ Ãtuu{:†ùòåKƒ‡Ì=z”žžŽ~Z±bPŸ?Hø7oÞLP¯Ø³gP§tttà‰'´µµ¡„?}úìv£G—^âÂ… 3gÎÄS «úÀ„¨ÆÆFàå4hœ®-**‚óË€ &€ÐÑóçÏ“’’0 spp@,>‘‘‘†¹»»#‚÷cÇŽ¦ÜîÝ»sÍfá98ZË---ˆ_‹-Bç1/]ºd›6mÂ+Þ¿ÿ®]»Gƒ›››¯_¿ŽÔ7JKKá(®©©):7ýúõk8Ongg7eÊHŒ‰‰¢­åË—óYV8pÀÛÛ»§MŽêêê'Ož Å Ôq�ÖÖÖ¼‡dïܹchhÈK<ºbÅ Äâºoß>ƒ!..¾oß>áýƒ8{öìŸþ‰Ž£Žƒao ××׃äÁ!CdߢÇUNEE…——מ={' ýÏŸ?×ÓÓÓÓÓËÎÎ~þü9؛ϟ?CbLLL·[‹AAAaaaˆŸüܹszÿ(_‘H¤Ó§OC °±¡{333÷ïßÿúõkô èvð3^¹r¥­­ RÎ;ÒœüÑÜÜìååµ{÷n<[jAAALL <çóçÏ ‚·7ÅÅÅðë½{÷òóó1 {ðà—ËE߃ÂþýûÕÔÔ ÅÇÇÃ0*•)bbbÀ¹PZZzãÆ H¬®®ŽŠŠ‚1"55ÓÓÓùóÎ…††zyy…††âwª|||àv555°MMMaaaH£ÑΟ?ß­½ ÈÊÊBf¯¾¾å ÆÙsçÎÑétH9~ü8>xa×®]gΜ¿»ºº"##ѽÐÜKJJPbUU:xÏ—.]òòò:zô(ž”/00PEE_¼---LJŸ °)———¿zõ } mÏŸ?ÏÎΆ”çÏŸƒìé7H$$^¹rŒë‘#G¤¤¤ qÿþýÀƒ YYY’{Bvv¶——×ÒÒÒðö¦¨¨žðàÁ`Õ¼xñ"•J…Ä“'O‚px@@€——שS§Â, ­­m×®] ‡ý'î­««ƒô´´´””H|óæ HQÄÄÄ”••AâíÛ·»% ôòò:yò$z)FCÃSCCƒ———¯¯/^诤¤$##2AhH?>LPqÅ0ìøñã¡¡¡H0{ïÞ½ZZZàB&!¾çÏŸ÷òòB³%À•+W455¡Ž4ð 'Ož„Ÿ¨T*(^þºUެ¬¬©©©„„ž ýãÇd2fЇÊË˳µµMOOGünnn„yÓÁƒÕÔÔð4QQQ‚þ˜””Ôøñãaœ|úôi°±YYYñññîqãÆn<x°¡¡!\fgg·hÑ¢¯ª«IJJšššÖÔÔà…³@f¯áááéééø…ô(xõªU«ÊËËaIgooOà‘ŒŒŒLOOWQQár¹ZZZAAA4íþýûH¼ÀÃÃÃÓÓSNNÎÊÊ VwîÜyñâÅâÅ‹ :;;á-øðៅÎСCUTT@ø!<</^°gÏ2™œ””C^ZZ¢÷GHMM}õê~Za˜••ÖSOOoôèѰdaa±zõj¾½½½‡ †ß*“““#Ô‘œœœµµ5¬Œ£££_¾|Ù›…Ž®®®„„~]‹aØ­[·ðâxýˆööögÏžÁš˜¤úUB^^,e0 Û±cÇÇ-,,^¼x1wî\ Þ°·····<x° ÷éëëûúúJII]½z¬`}}ýŒ3€b§[¨¨¨˜šš¢! ¥¥5tèP  \³fMYYÙÈ‘#ãââ𪠮®®êêêÆ ëìì$¬äÚÛÛ t}}ýû÷ïÁ*ÄÆÆÆÇÇ/Y²¤¨¨¨££¾-00ðýû÷6669r$°”®X±¢ªª ±" 6ŒJ¥â÷Ÿ Æ7`#%%ejjZYYI ç:thOº‚ 055…2',ÐeddðB×®]ûðნœN700èà“ÝBOOOZZ)Å 8;;wK#%%zí0 „††öF%²ÏLŽššš‹‹ AÔÊʪ©© œ$ƒî%»Ô½{÷nß¾ äZ�6› QTT„ñBYYÙÞÞ¾¬¬ìðáÃ***H©åË—/@Έêˆ5ogggë‘ÇàÈ‘#‹/îcMAAÁÅÅ%??ID€w«´´¾mÀ€ÈÓÅG½ví†a~~~=™:yyù;w“åää`n®©©©©©ùáÇӧO«««ƒÓÆÆæÁƒp¥žž.Eìr™Eç'N€Â‚„„D/EwŠ‹‹©Tª¹¹9^422ÆîÕ«WÃŽ1P©:t¨¼¼|íÚµˆëæÍ›ÅÅÅ;wîD÷¶¶¶Bttt`ÈÓÒÒÖꜜœÂÂBà¯û*ÀDÁú? :8¼Æ¼}û¾ÇÚÚzÙ²e=]ö×_=}úVööööàX6*__ßææf;”””ä?,êëëëëëÓétüäq?GDD˜˜˜ðÙùjÐBèêꊋ‹»ÿ>Z£LŸ>>IMMÍÍÍ Ã°I“&¡ŠÐÕÕÖ;Dz}ñâÅñãÇwë J˜{ddd€?œá...oß¾E¾ä€wM™2…Ðw,,,,,,ð®ZÀÓ§OCBB"""„¢ÏÕ CÛ¶m“””!æ)))½)--}òä ^åï×íåPSSÓÙÙ 9ùüùsYYÙWã‹üýý7nÜH DŽ:T†(ÏÓ¦Mkjjz÷îÝäÉ“³²² ÜÜÜrssÑ½ŽŽŽHÇ0!!ADDþóÏ?ÊÊÊNNNÒÏÞ£±±‘D"A+**Š‹‹ñcÁâÅ‹ïÝ»˯ÌÌLGGG¨?p€`vøðaŸn5t™Lfff&<¹½½ýÍ›7ˆ »ÿþÓ¦M«­­-((°°°¨ªª¢ÓépeqqqEEï$”?’’’¦M›&""Â`0^¾|É+DÏëR«­­]¼x1ll�–.]ЍdcbbDEE9ñ¸qã RRRäåå·lÙrøða¼Ç_QQYA …ˆTPssscccçÎKÏþ&¼zõjüøñb·téRôSÿþý7nÜu„ü~£Gö÷÷‡¿+++oÞ¼‰¿üü|--- :ÍÈÈ “ɨéZYYuvv>{öláÂ…âââ/^¼�…@öêÕ«ïã$¼víZkk«““Ó7IÔP©TÔk///‡fmiüøñÕÕÕ4 ß–Pß¹xñ"Nwrr"È'ö‹•’’‡]mìØ±È.–——ß¾}û««ØÃ‡/^¼¸÷$¼Bü8Ž= ža.—»nÝ:¤ã‡P^^~æÌ™¹sçvËÙú÷rºEYYY{{»““ðÛó*œ°wïÞ¡C‡:99hØþ[[[Ø'¨ªª:99¾~ý:''çÞ½{NNN„ àˆ#ÐíÍÍÍUUUÈÞ¨¨¨899œÈ®®®ÎÎÎÎÎÎh Å‹ÚÚÚššx¸²²2Á0räH'''GGGGGG´²²²Bß“™™ÙÓñ+:þâÅ ¸lìØ±øÁ]KKËÉÉISSvtKKKi4\Éb±ühïåæää„D"øßÏŸ?wrr"lêŽ5 嫦¦¿=6eÊ''§ŒŒ *•êééiiiéää„wÂHII¡{ÿøãäËËË‹ŠŠrttìÉÞܸqÃù€Í•nñôéS[[[x>a¿MNNÕѤI“ð% PRRâuïàçé:::peaa!^ôsæÌ™NNN °½ñàÁ¸lêÔ©qqqßgoZZZ¾ÕÞÐéô¿ÿþÛÑÑIâššš>}úŸ4pà@Ø“ûòåKgg'$r8ˆ¯{C£ÑaQŒŠ½¦¦¦Û÷2™L¤}Õ-ˆ YNNIýö„C‡©©©AGZ‚_†9sæ@9::ú†aUUUÇŽsttüIöûÙm©©©ÙÙÙ=‚YØêÕ«¯_¿.++ *�ø+«««Ož<‰÷Õ××ÇÄÄ€?­²²²³³ÓÄÄdÙ²eQQQ222ns°7óæÍëÉÞ`†„x‘†ÂwÀÄÄhã400ÐÉÉ©—òÞ»wÏ6À/@uuuLL ÌÊÊÊØlö°aï\¹2pà@‚�Á-Zddd„R«ªªÀ½Ãb±\\\"""Èdò®]»*2ùùù×®][¾|9•¶?þøÙ‰ïžüÊËËæ Ú0ÏÉÉyùò%(G|¼¼¼¶nÝÚËÕ@/qýúõ¦¦¦ |«'›Í~øð!•J½téRggguu5Ègôþ —.]‚9 rÛÙÙ¡JùnÁ´ŒŒŒììì7öþz*•#ÝæÍ›ÃÃÃù«, ñãX»víÑ£G»•bª­­=xð ««ko4S“‚"©²³³]]]a¸çÝÑêèè øy-,,«1..®®®|Ð%%%xÝÀ»wï\]]Qe·˜>}ú ×ÔÔ$Ì.³³³ÑNÒ·¢¥¥V6ÿ"lll'066–N§Ã²òãǼÔÙÙÙ#táÂDÁôüùsØod0¼vÍÍÍ•••üUA‡ öƒGAI$R@@�as«¡¡ÏÊæ«HKK#Hý8Š‹‹µµµ¿CòYJJ ílÕ××———ÃfÏ7MtÌÌÌð›Ž}"]__ÿÕ• þþþhYTT´téÒ¾=å.D·HNNf2™=9l?|øðSíÍ7›œ™3g’Éd˜BZYYÁáš5kÂÃÃ!ÑÑÑ î]»V¬X×Ç•””´²²‚¸µ;wîÀõrrr ±5hÐ OOOHÔÕÕõ÷÷ïß¿?Ê¿|ùÚ‚Øÿ¤ÃàÊÙ³g£küýý!òð'NôFwãǯ««ƒ‡›™™Á@Åáp–.]jccsåʘ¼Ï;öNž< a²;w|íÚµÕ«WCP8¬‡;OVSSƒMoSSSGGGH1bÄæÍ›1 spp¸uë$ÚØØ€ó› [ ÒÒÒ°yâKðLØîNKK{õêÕŽ;P Z^^^WW,/Ö®]{ùòeT­ÐOž< ·ïÞ½[SSg)** keeå¸WCCéÛgggC"†aÓ¦MCJ¾ÃöoÚ´‰J¥B[Â0 bü"##a;Þ¢­­ õbaaQ[[‹ª¢õ-ZtýúuHœ>}:ÄÂìØ±ãܹs2³|ùrØE;yòäþýûa|<wîðMݾ}î•——GÂtß„óçÏÃ7 Ã|||,--÷ïßêÔ)¨Ù¶m[·Q0bbbø~!''ÃÄÄdÁ‚ðIÇß¶mxQP[š4iÚ‰ EÑÕþþþ½19²²²Hø[XYY544À»ÆŒGënܸ!%%Õ­QÄKÃÉÉÉYXX@\ÆÍ›7W¬XÁd2ÅÄÄÒ¨}¸¼vww§Ñh"""111†‘Éä¿ÿþÌ•——£jnnþã å¼øŠD…B!‘H ˆ&Œx3`À�»\^^ÞØØˆý/f&qÄO[òòòŒÁäp¹Üììl Ã$$$Цtgg'ÁSTTÄ»nà¥4 NðÀ2$õôô`%^RRÒÚÚŠ®766†s$ÈWГD[gggyy9~fÝÒÒÞ<uuu|alIEE èëë#'ÞÇA<ØÄÄñßåææ‚Óí[0™ÌwïÞa&##ƒÂ„Èd2xØûõë‡Ìd}}=ìQikkwëÏ!H´}øðÁÐÐÏØ®|qqq´ªèêꂃD 0’¶¶¶¶´´€!ÔÕÕq8T­ÝfânÁ^âc[Á¢ Á‹Á`ÀÂBVVô¼) ~óOMM o®øÞ|üøQGGï x÷îLÖÆŒ#""Âf³ß¿™¥Ñh0Ý–——GÏÖÖV8‚/Ú£<x0¢Bmiذah=ýáØ@˜™™ñiÃx$Úèt:ZÖ 6 Àwp ÚðÛ·oGM•¦Ñh%%%¨-¡VUUEÕJ"‘*++1 8p ¡  {r¦^Jh£R©•••x—rss3œ©ÐÐЀÞZSS#**ŠÚpYY™’’¯÷;??èС¨9½}û–Íf‹ŠŠâç¬? /ÑVTT4xð`|[" M,«  `Ô¨Q¨ã aÓÐаÏ%Ú„ª ÿIUAUAÿª‚~µ UA…B!„øOBhr„B!„øEè>|@LL è=Æ!�«<S•““˜j‚IKK XŽ$$$©+õŽ åÆyyù>T!ûž¬¬lŸT“ˆˆH_I½ñ39MMMxbM�‹Å‚Ð8F{ôè‘ÀQ à †ˆˆÈ¿5Þ·­ŽÍf RWâr¹]]]68tvvÞ¸qC$ƒi4ZMMM_‰Î©««ß¹Ão09ÊÊÊ3f̘ PTT¼té’ƒƒƒÀ´*99¹'Ož ÌÑ9))©wïÞ‰ŠŠ‚ÿÃqq‰T\\L |ýOOŸEEEïÝ»'H±E 7nܘ1c†À„ÈÊÊ&%% 4è«Ôƽ„„—ËíCÁ{ñžÚ–ÀT�ö?!j)))19ÒÒÒ¢¢¢SMÒÒÒââ⢢¢“# IIIAÊD¬ Þà�9¤®Ô‡ƒD¬õáç ÄB!„øEèÑäp¹\ƒ‘€ä1 ãp8çÏŸ×ÐÐÐÐÐf³Ù†±ÙìmÛ¶Ablll·&‘ÉdŽ1­Îúõë§ñ?�½ —ËÍÍÍ…”ùóçÃI%‡sóæMHܽ{7z¿¿?$FDDÀëX,Ö’%K 133“—©¥§ æææ"mSxcLL <gûöíðF6›½cÇøõÎ;èÕþù'$~øð^Íd2ŒŒ444455cðªª*¸lòäÉpŒ‘Ëå>{ö ×®] ¹f³Ù'Ož„Ä£G¾·` ÆØ±cñÄø CSSSCCÃÈȽèÇðÌ?ÿü“ ö…rwäȤæéííÝ¿TMÀ\Éb±ìíí!¥°°eÖÀÀ@CCcÀ€Y.—[^^—M:¾ÃáÄÇÇCâúõë»ý^°X,ƒ1kÖ,8w‰rmbbêìì$TkQQü4gÎÔbcc!qÛ¶m¨!CâùóçQmº¹¹AâË—/Q'L˜�‰H!¦££RLMM{bA Äâð‚cl6ÛÛÛžÞîèè‰yyyèí cРAHáå´¸¸Ѩs¹Ü¤¤$¸×ÝÝ2Žj°ÿþ Ëf³===!ñáÇ=uXƒ¡««‹³@Ù„¾óæÍ<ù‡Ã‰ŠŠ‚ÇúøøðöÍ›7ï<@ù5k$£üêééihhèèè ¾ó À`0ttt444ôôôÊår322à;—-[†ÕÕ«W!qß¾}ßýû÷£ïׯ߽{÷þÅÁúŽ­­-U‚â544$ M€ÏŸ?«ªª¢ïÇü¿Âä¼}ûV__T7®]»VRRB"‘H$’ˆˆÌìÞ½ÛÄÄïß¿<}xtvvNš4 ÖÜÜ€·oßBn}|| eÓ¦M hòøñã7oÞ@¢¶¶ö0 VUU…Ĭ¬,à;Y·nÝÚµk!q×®]pÌž?*++õõõ» ..îáÇðcccD¹سg¡¡!üŠTU.\èíí ‰›7o.//Ç0ÌÔÔ4##ƒD"ÕÕÕÁ1ìæææ3fÀegΜå‚ׯ_Ÿ={gÍš‚Ü—.]B…Ãd2ùoÕΛ7O__/£‡aØ AƒêêêH$RFF†©©)†a_¾|AåãííÍË*Ïd2Ïž=Kàà A_|0+V¬Ø»w/¤¬\¹ìÜØ±csrrH$RUUìojj²··‡ËBCCa`JKKÍM‰4eÊ”^’l®ZµJ__i•ÌÍÍ“’’àQH+U«««+ü´gÏ  Š¿ÿ>$š™™ŽYhh¨ˆˆ$–””�3кuëæÏŸ‰‡;gccsíÚ5Hœ6míèëëCJbb"¢"íwïÞÕ××Gê €   Ô–ùfÉ’%[·n…D K˜8q¢¾¾>!jˆËå–””L:¥¤§§‡……Á½sæÌzÍ•+WBJUUÕ–-[@`bÇŽcÇŽ…ô¨¨(Ðö%ÀÊÊJ__/5K¡P€EðÒÒR}}}ï@xòäÉëׯᱺºº…cooosssøõöíÛ R5wîÜýû÷CâòåË«««1 322ÊÏχJ¹_ƒ¡C‡Âà–ŸŸOØP|ÿþýž={à;ÝÜÜ@·0&&¦  �•”” ï Ë*++/^LÿÅpvvÖ××'° ZXXdee‘H¤ÚÚZ^æÜ#F .(‘ð””Têäååeee» nê±Dþøãªª*‚D›”””˜˜"ã#ðô›Û·oØ0á!¢¢¢@]nhhÇb±( F¢ب¤Óé¢edd8Ü...<¡H3µ½½]VV¶7¡ƒ®ªªÊÏÏÇ3}IJJJJJÂÃY,ž%‚?( ‹ÅJHH€W+++“Éd˜µ}U¼‡Éd¶··O›6 /lC£Ñ:;;===ù2ðÉ´�TTT€²…B¡ô’þêÕ«µµµ>>>øY-•J…¢——‡r†V™•——‡&,>†µ¶¶BfEDDá^*• ÁšVVVVVV0d2™ÝrÙvûaØÿ”蔕•) ôçÞk#1ŒŽŽGGGxµ´´4“É„ûªã›L&³Ùì¼¼<´#Èår[[[¥¤¤x•ÇðX¸páÂ… /\¸€_‰¢•J…]ŸžnsKœœRSS?º„„„´´4d‡Á`Š744TJJ )²X,¸RRR/t„�ÊxF"Ô–†ZUUõöí[üœ DTét:•Je³Ù½ï;ÿQ,X°�¸ãh4—Ë%ÄXoß¾ÝÆÆ†0£ýŸyó&ö?¡6üZ‚Ð[ ‹Qh¼ìÉд`"Âß“ôøñc2™¼dÉ^£ûm{9sçÎ4h¥¥¥¥¥%—Ëuuuýê-ÍÍÍÊÊÊЯ_?xÈìÙ³œ PPP`iiyýúõþù%vuu]¹r…B¡€èäš5kÈd2ÜnjjЬkmm]µjU@@Àw“¦X[[O™2^RRB˜‰+((°X¬úúúúúz¼—£¥¥eåÊ•–––YYY°¾~øðá¢E‹à9ÀŸ/**ªªª ÷â¥È Æ£G,--wîÜI&“Ñ0têÔ)KKËS§NÁœú›œœ ¯^´h"Žäƒ®®.‹EhaŠŠŠð –––111ˆ.Ã0wwwKKË   ¼@8‰Dš:u*°ä©ªªž;wî ¼pẌN§ÇÄÄäåå}ß>111...ð|Â$]LLLYYʯvC£Ñ¢££---÷íÛ„x®®®\.2hÐ PWRR¢Ñhp;ÞíÐÔÔ4wî\KKËÏŸ?Cgç¡¥¥¥½½=¾ (Н¯ï¬Y³2þàp8ÍÍÍjjjøÄQ£F­X±²“’’‚ô„&„ŒÐöíÛ?|ø�WΙ3¹æøC^^ž¿^�smm-U*ABggç… 8pò¢j•øúH$›ÂÂBBßikkƒ†±víZ<k%a¡Ã_ÿV3fÌè–»ïÛLNtttYYYQQQQQ‘ˆˆ~ÔSÆþúë¯sçÎØ~ á.Ýå�� �IDAT!÷îÝÃ;FUTTäîâ©Tê7ššš@¹æk***p{nn.R===½½½ RcUÿCO"T†=þ<>>>lذÀÀ@‚s ¥¥eúôéÓ§OCضmÛÞ½{‹ŠŠ¶nÝ Ž5kkkxNaa!0檨¨ÄÄÄÀ½x&üììì/^ÙØØ áœ;wîHHHuvv~Çq¢Q£FA ÇÇÇUj J¸¥¥ÅÛÛŸ¾k×®¢ÿ!>>?²GGGmÚ´ éãUWWÛÛÛ£åNssóÒ¥KáÞƒ.^¼û÷ïßÏÉÉ!xðð“TM„MšÿÓÞ™Ç5um}ÿdS™d(2ÉP+(*V¡jëuzZ­ôzµ[­V[ë|«­^ÛªX;ÜŠ tð±-ZÅY±Ú:ê€Ê$ó,BH óp’óü±ß{Þ\DJâúþ•œœ!{8û·÷ÚkïeʤI“rrrÐý»EðóððHKKCùlÚc¸víZiiiYYYPP*Ö´´4 …‚nRWW‡6-Þ³gO~~>ºÜÔ¾xñâÇ—••%%%¡Çñ×^{­¬¬ìèÑ£} ï ©TºcÇŽ &<V_˜ ˆòòòåË—›FùC)##%gÊ”)¦AÁ322ôz=â`¶mÛ¶ˆˆtæñãǯ^½*‰Èlïm^J.—7î‘oöìÙeeežžž»ví²x½Q(ß}÷F£Aûv“lݺ522rغ’777Ϙ1Ã4Ô2Â××—|åßzë­¥K—ö¦(h ]o÷ÿí·ßÐ’á\S㫯¾úÁÆššƒÁPWWçàà@¥Rkkk»Ðétmmm݇(Š#GŽ…BÓy× …[¶lyçwúŽ!&-y<^nnî“¥hãÆHP¨cDVVVo:gг³3jÅîß¿Oö_xá4©kJJJÊÊ•+‡¦þ:uê?þؼysMMMGG‡F£A#n±XÌd2»-`niiáñxÝl}õõõ‹-º~ýzßëRÕjõ™3gnÞ¼i:„íFVV©[;wîìfè'>>>(ŸoܸAv¦L™BzFô jÁT Nž<Ùm•ƒÁèÛžöÈÑÿçŸûÈ0ágcRRÒåË—kjjšššt:]SSÓÄÝéÖDÞ¼y}>räH·é±þ·¿J¥²Ç(ì‰\.ÿñÇår9š‚5êëëßxã+W®<lòê±îm ƒ\Hzöá8>iÒ¤Þ,Þƒ+9>>>dĉD‚ºf666cÇŽ%=h~»[\¯‹/Þ¸qãáèÜóþû理¤ôÞ˜4O?府¶¶6&“ÙÿɃnFÒÚÚZÓ0Ã{{ûŠŠŠ×_µƒF£1$$$%%e÷îÝ£FB3¥$o½õÖ† ºqš2eJAAÁ#çBnÞ¼™Ýw”5kÖ<åNÒz½9†<qÃáôhÅX>ÿüs'†D¥RGމÊK§Ó577oÙ²åÛo¿íí|‰Db0ºYáºAÆB|~ýõ×sçÎ=Òòa1œ9s¦´´”ŒÑeÚJ°Ùìa]{êÔ©7nÜèÑè×ÐÐð÷¿ÿýúõ뼉V«¥P( åáëׯk4š>fÓOrY,évÎwwwW«Õè —ËEýâššWWWSo+@pöìYdP=z4:_.—£­Øl¶§§':(‰È1T*5}œ›››««kWW:hccC @]]yf@@À“R‘»ºZ­FsH‘c4AÈT…ÎÄ0ÌÏÏO(¢K¼½½QË+ÊËË­­­ ‚@>c …âý÷ßGÜÒÒ€a˜­­íˆ#е2™ õ/œœœZ[[ÑA*•úá PöR(•J…Zp‹åííî) Q‹ÜÕÕÕÙÙi:‘ðù矫Õj4E7räH²XMKþ·çž{Ž4飨HT*uôèÑt:Ïç£Óš››I¡•Éddñx¼'î›UVV¶¶¶¢Ä"E///‹ÅäH´µµ¥”Ãáp¹\²XÑxÅÙÙ¹¹¹d±X(¤lff¦··7²…ººº¢9ð€€€ºº:dO Dƒ9²Ëd²'Û¤¥¥…Ì ooo.—ëëëÛÖÖ†zyyõ¨âl6;//ì¨-X°�é­­­³³3º¶««‹ .õóÏ?Ëd²5kÖ˜Ú•J%:ÓÁÁ¡Ÿ;qQ©TÒc­G¸\®º­V«E™, Q9r¤J¥"ŠDÏç“™àãリSHHHii)‹ÅÂqœ 4„„„”””Ðét­V‹ž«Óéjkk­­­ÝÝÝÑÿ‹Å¤W…D"!K¹c¶wïÞQ£FýµŽ}SRR‚òŸB¡„††â8^YY)X,–——JQ[[[ßQ.{èÈår½^÷pH¤þJ‡Ã1í˜OŸ>Ý`0¬]»ð… .\¸ð•+WîÛ·ܲe 2øîß¿ÿ7Þ0­£áááäPîÂ… ¨™spp@Ý^ ôí·ßÆ0,""FäñxR©Ýðyóæ-Y²äÿøGFF:¸fÍd{áóùGEÓ†}óÍ7ýìçZ[[›v«ÇG&púôéȺuéÒ%£Ñ¸páÂåË—õÕWè×7"íÙ½{÷{g†b@³VÇŽ›={¶\.§P((ê¶½½}ff櫯¾ŠÞ.Ô _ºt)ºáĉÑ|Õßþö7£Ñˆ.^¼…^}¤Æ˜6O/^œ:u*Avvv(🇇ÇÎ;Q4ÌÑ£GïÙ³Õ¼+W®H†¹¹¹‘nï¼óÎ_|þÆæÍ›Q±¦¦¦®^½ú›o¾A3¨Y!ÝŽQÛ}êÔ)‡ôôtäLåçç‡Îçp8dº0 ›6mši;Ø7¦áþ²³³çÏŸ¦7‘S¾F£Ùºuë‘#GÜÜÜvïÞÌžÁÁÁ{÷îEÅJ>ú¥—^B>Š .üþûïÑÁåË—£6bË–-}ôÑ¡C‡PÉ¢ œ••µxñbäÂ{ôèQ¤CçÎC~t<¯Gw҇ͪ¦+`<===Jšæ¶lÙÿÙgŸ­]»öÀè "eeòÃvK6›M6Ê¡¡¡Ë–-CÉ™0aéKæââÒÍ'mõêÕ©©©èÌ­[·¢0¾=I>ÔÖÖÅ·%±±±A±þ ä»óÊ+¯,[¶ ðÜÜ\‹5þüwß}wïÞ½è×?üù,ìÛ·oÕªUeeeØ–!æÌ™35 ƒÁ@놆³gϾôÒKz½žÍfŸ<yðÎÎÎO?ý4++Ëßßݺu¨ÚÄÆÆ¢ÕŽŽŽmmmd}^¸pá¢E‹P_¡ï1ådê=NZž˜LæéÓ§•JåöíÛ>ìååµ}ûvTpaaa}ÏÆiµZ*•Úm sóæMN×£$ „h3K DÛðB´™¢í‘Õ¸·m,Ëh4’þ&yyyáááä¬'„h���ä MŽƒQ|ëG*7H���ð$ ­x1 “H$jµ:""͉öuIo#è¾íqæƒÁ°ÃJN·˜bB..4ÍÂR„öôµ˜Zg4-¬q°¼Wi`SD§ÓûØéN«ÕÒh4*•ж—ìÏ–=KŽ^¯G“¥A<°¤(L*•ª½½½ï %Í ‰DÂb±,©âµµµ©ÕjKJ‘F£ÁqÜÂÇ[[[-IG …X,¨æ®ïûÐh´¶¶6¥RòÈ!N¯’£ÕjÑ*zK’Ó®,ãåommíìì´˜uuuýµÛ 8r¹\¡PXÒ«„ã8ŽãÖ8à8ÞØØ8P14‡IÉÀ€Ü ­åèíWNWZZJ¡Pú¹kbo8ƒÁðó󋉉±¤Z¥V«ccc-i”Ã`0ø|~»™)ÕÕÕL&ÓÔ3ØÜ‰D"‘h(— 6h `·µÀæŽ^¯‰‰±¤QNQQ‘»»û@… F.Íè3•J}xƒ5///.—ûðãzlo{6›íííÝmw�sG ˆD"KJ‘‡‡‡F£éCŬAËÓ,¬â1ÂÂRÄçó-,E¦;ÀZ�...ƒaÀ‹ÉÁÁÁÞÞþáá`oÁãõzýÃÛл‰’Åo9���<.d8Óø&OÀIò®©¬¬„ü���ÈñÍ€,,Å6¬iµÚÒÒÒÞJÝ/¦Ó±ÿ¬I†R†­VÛŸˆã��< Ú¾?–y6€-|s9VVV:ÞÒÒB„‡‡•Jíê�•ââ �èë�À“öºF’Ó·ð0™L:ÞGüª§•œGŠ ƒÁ ‚ ˆ¦¦&æáá¡×ëûX.�Î;w¼½½Ar�à‰Q«Õ …Åb¡Ý9‡Æé1$‡F£¡ «F£Á`ÀqÜ`0À;��`Ž mã ‚ …Çh4š†œÿË$ça±Ò��° áA£ …Âf³©Tê  ý‘bÃb±‚0 F£Ä��À  ÚšÍfÓh4ƒÁ0ÂÓ«ä ã8ˆ ��€Å N§#…‡Åb!áX¿Ð$G©Tþþûï\.7::I��À3%<ƒ¡£££¨¨ÈÍÍ …{,Éa0¾¾¾æÂ… </<<Š��àÙA"‘ܽ{¹´…††î(m­¨Ó鬭­•J寿þêìì<°O���†!2™ìæÍ›(âgDD„µµõ@mÚ«äÂãáá¡Õj9NWW×… FŽiI{â���$J¥òúõëz½ÇñØØX‹Åãñü)ðXc±Xnnn<ÏÁÁ¡££ãܹsÞÞÞ�Š��À2Ðh4¿ýöŽã:...ŽÁ` †ØôKrHáqqq±··wvv …§OŸæóùPT���æ ŽãçÏŸ7fÒ¤I4ÍÁÁaPŸø»°Ùl6›mkkëîîþàÁƒ“'OªÕêàà`(6���ó‚ ˆ“'O¡T*§M›F¥RÑ®kƒÍcﱆ„ÇÆÆÆËËëþýûè`aaaEE”"0”¦�È�xºººf̘A¥R9Î=´Ééÿ?pqq¡P(L&3<<<((ŠJììì,)²8� % eÑ¢E(êÚ#ÏÔëõƒ%9¶¶¶‰‰‰ …¢ÿ·@{HS©T(E`(Q*• �ð4ªÓϦ~�7 èt°çŽ���€gJØz•¹\¾ÿ~È#���` xå•W¬¬¬zkkëY³fA���‡ÃQ«Õ¤iŽÞmD§Ó!���€N§£x<è+Ìù���CH����’���€ä�����H����’���€ä@���� 9����H����€ä����Ö¾¶·‘J¥wîÜ!¿º¹¹  몪||||}}{»öÎ;R©4::ú)ƒÿ…ÂÒÒRòkß���ÌRr:;;³²²¾ù曨¨( ÃZ[[íííwìØrêÔ©Í›7¯[·nýúõ½]¾uëÖk×®]¾|9""âiþß•+W–-[æåå%êêêÁ¦M›üüü ä���,Grªªª>þøã‰'þøã†ýòË/K–,ÉÈÈXµjvTTTTVV×ÕÕ¡«¢¢¢ÜÝÝÿüóO±XŒaØÕ«Wýüünß¾­P(^|ñE6›}öìYÇg̘a4Ïœ9ƒ®²±±™<yrÿrÊ”)»wï>sæÌöíÛwîܹ~ýz>Ÿ_TTT__Nˆ‰‰quuÍËË‹Åñññ………2™lòäÉ666†;wEµ£R©Ó§O‡R��øK Ñh´Í›7kµZ½^_UU…Lg†i4šŠŠ ‘HdooßÕÕÅår5ÍØ±cFãÑ£GÛÚÚ¨TjHHˆZ­Þ¶mÛ•+WÚÛÛ:$•JAnnîÕ«W•J%F›8qâÒ¥K<øüÃÎÎ.11ñçŸ^»víO?ý´bÅ …rïÞ½ôôôQ£Fõ8v)--=}útddä‹/¾ •J8àááÁf³·nÝzýúu‘Hôý÷ßwuuoذáóÏ?·±±)((سg­­mppðùóçß|óMÇ+++?ûì³€€€ÀÀ@(x��€!€Åbét:‚ òóó¯]»Ö«û€ŸŸß®]»ÂÃÃ:´qãÆêêêÅ‹¿þúë'Nœ;w.†a3fÌHNN®©©quuݶm[zzzllìþýû W­Z5jÔ( Ã6mÚäááñðÍ Ê+ètzRRÒW_}•˜˜xóæÍÇJÆO?ýôûï¿§¤¤¤§§GGGÿûßÿ...F?¬Y³ÆÍÍmÓ¦MR©ô½÷ÞS©T_ýuZZš^¯_¹r%T��€¿„¾Üüýý¿þúëÒÒÒ-[¶,_¾<::zëÖ­/¼ð‚é9³fÍrww/++«®®®­­íçS©Têo¼¡ÓéÞ}÷Ý>úhòäÉûÛß*Ik×®}Xç~øá��0L%§­­íĉÉÉÉ}ôч~xùòåìììn’óçŸnß¾J¥uuuõ_röîÝ«V«©TêêÕ« < t:ýÍ7ßd³ÙPê��� ½Ö×­[—‘‘aXHHÈk¯½öð9þùçŽ;þøãY³f}úé§=:§ýôÓOR©}>xð V«Å0Ìh4~õÕWÿû¿ÿ»sçΔ””ŽŽŽÔÔÔGþ×;wîܸq#66ö ¼à¶oßþÉ'Ÿxzzöhè���þÊQŽ››Ûܹs ”–– ‚ÄÄD ÃÆŒ—ŸŸaXLLŒR©¼té’T*õñññ÷÷?qâDPPÐܹskjj>Ìår-ZtðàÁÐh42©H$JOO—Éd\.—Ë妤¤ôñ/ SSSóòò”Jå¦M›âããU*U~~~nn®H$ª¨¨˜9s¦O×.[¶ì³Ï>ûâ‹/ètú'Ÿ|²víZ(u��€¿„^=Ö8NXX˜Ñh4 ƒÁÑÑqΜ9ÈÃØÃÃÃ×××`0L˜0aÁ‚#GŽÄqÜ`0¼üòË�Çñààà &ØÛÛã8¾dÉ’ääd6›ãø»ï¾keeõüóÏÇÇÇÇÇÇ£›Óéô)S¦,[¶¬·¿èììŒçîî¾`Á‚øøx Ãø|¾»»;zî¨Q£–-[æïïdñññvvv†EFFÆÅÅ%$$ÐétÇFã„ @r���†Œnk&“©ÑhºººT*ÕÙ³gçÌ™y��� G¡PÆÔÔÔýë_°Ç���0D€ä���� 9����H����€ä���� 9����Hd����’���€ä�����H����’���€ä����Àð_Á ¨T*‡ÃL���fXC¥ö*9 …â»ï¾ƒ<���Ф¤$2óIŽ••ÕÔ©S!ƒ���€ÁÖÖÖh4ö<Ê¡P(ÖÖÖG���À@IŠ—ƒ¾‚û����0D€ä���� 9���€eAâ+Ùl6é„0<Áq\©T1àw¶¶¶f2™–Z'ŒF£Z­Öëõ~gƒaccc¦Ùò,W'½^¯T*ãζ¶¶t:ÝŒªAZ­V£Ñ ø)н½½Y´F§Ó µä0l_’C‡M:uðÚ¸a›ö§Á`0äååQ©ÔA}oÍ+[ôzý?ü””4xþ5Ã6O´Zmzzú믿õÁh4ÖÔÔ”––Nœ8ñÙÌ ƒÁpëÖ-­Vþ×HŽF£ÑjµÃ0krrrd2Ù >B¥R ÆP௥°°ðîÝ»QQQæØe<Ž;&—ËŸÍêôÝwßu[Í7à( ƒÁ0ü«AKKKnn®··÷ ªÚ`7\OCIIÉíÛ·ŸXo0˜Ë���† ����$����É���€'`(ÜKKKö)¤R©¡¡¡÷îÝc2™£GÖh4¥¥¥666–”¿wîÜ1õ?a±X}x‚uttÔ××;;;{zzvû©¡¡A,ûøøðx¼g§v*•JrF}0¼i5F£±²²b±Xæ’'F£ñîÝ»duâóùùâô˜pÓyu:nkkK~Õét*•ŠÅbYYY¡#jµZ«Õvs@W(8Ž£º$—Ë»ù,p¹\3ʶ¶¶ Ïžžž¦½½ý¹çžstt|Ö%çïÿ{UUÕ˜1cLËžÍfgff&&&zxx×××'&&FEE]¼xÑ’Þ“iÓ¦ †ØØXôV<xðà§Ÿ~êÍßãÂ… Ë—/óÍ7?ýôÓn?<yòܹs|ðABBÂ3¢7 …¢¨¨H¯×3 ™LäááA£Ñð•••À×××,ò„ ˆ+W®Ì›7/::Z«Õ …ÂþóŸË–-³¼ça½imm-**B+Wp§R©aaavvv†iµÚÚÚÚššww÷   ¤:uuuµµµ¡¡¡^^^¦ÝßöööqãÆ988ܹsG.—s¹\ä'•JcccœœÌ"CZ[[wïÞ››ëééÙÐÐ0}úô–––Ó§Oïß¿þüùϺä ~øá777ôùêÕ«¦n—jµúöíÛ†Éd²{÷î…‡‡K$’ââbô«››[@@Àƒjjj{bCCŸÏ9r¤YTƒqöìYTKÁÒ¥Koݺ%—ËïܹƒNptt ‰D†577×ÖÖÒéôºº:Ç›ššBCCCCCƒ‚‚0 +))éèè@×FFFÚÙÙݺuK¥R;‰úµk×0 ‹Çqü?þ@gÚØØ ªëóÀ"—ËKJJp ãr¹¥¥¥­­­NNN:Žì™:::R(±XL¡Px<^GG•JE£@Ç;;;ÑiL&EÒjµ¤£³•••9.Jýý÷ßçÎ;mÚ´C‡µ··/]º4##ƒüU*•¡Ï...h܃^tÐ×××ÓÓ³ªªª¥¥%00°£££½½}ôèÑÃè¬ÑhîÞ½kgg÷ / {@~~~yyytt4†a"‘¨¹¹ÙÉÉ©«««¡¡ÁtÀ§P(´Z-ÅÊd²‡ÝÐ###ÑZ«óçÏÿùçŸÓ§OþÕ ¥¥%55õâÅ‹ëׯ_°`Á÷ßìØ±ªª*Se‹ÅèsDDªÿ7oÞT«Õè`\\F3¨­@oDLLŒEIŽ)³fÍb³Ù¥¥¥èkWW×áÇÑPñøñã^^^ kmmuvvÞ±cÇo¿ý¶qãÆÙ³gcöË/¿ìܹsÙ²eæÛ?|øð'Ÿ|ÝÑÑA¡PRSSe2Ù¥K—0 +**º~ýºX,þøã_}õU…BqêÔ)tazzz@@Àš5k‚ptt¼uëªso¿ývuuõýû÷‘¨Ï;õ O:õÖ[o?^¥R566¦§§£ñÖ𧦦¦££#** Ù:‚ƒƒ1 “H$wïÞµ¶¶¦Ñhb±8""ÂÕÕõÆ %22²¾¾^&“3†Ëå>xð ¼¼œÇãét:‚ BCCÙlvmmmss3‡ÃQ©Tvvvæh‰š3g›Í>tè†a#FŒÈÉÉ)//;v,Ò›¬¬¬o¾ù&""B(:88ìܹ“ÃáìÞ½ûÊ•+þþþÕÕÕãÆ[»víþýû333ßyçÛ·oçççgggO™2e˜'œF£ñx<F#‰ ƒÁpvvF#F#—ËCCCkkk;;;•J%ÙŸ¨­­µ³³C–ꊊ ²#bÖœ?þàÁƒ+W®\°`†a‹-Z´hÑûï¿ðàA Ê‹‹ßÿ}½^ïäätûöíµk×.\¸°¤¤dñâÅþþþl6û÷ßÏÌÌLNN>þ|JJÊĉ5MEEEVVRôAeèÜ.]ºtöìÙ³gÏšÆN@¸ºº¦¦¦bæïï¿mÛ¶¢¢¢;wFGGggg¯X±âòåËdWî—_~)..NNN~î¹çÌÈ&€~ùòekkë„„„ÆÆÆõë×dggoÚ´©  `Ïž=qqqo¿ý6†aIII‹-B×þøãÕÕÕÉÉɤq`Ïž=›6mÊÎÎX¿~}cccBB‚µµõåË—u:]nn®ÑhLJJÒh4‹/ær¹ÙÙÙûöíkjjZ·nY¿iB¡ÐÞÞ>222&&†Á` ºDDkkkdd¤N§+,,T«Õ%%%¶¶¶111aaaVVVíí퉤¦¦fĈ111ÞÞÞ­­­MMM–dz*++ûøã#""²³³W¯^}õêÕýû÷———···¯[·.;;{öìÙ‡Bn þüòKF“œœììì<üSÇb±"##9NMMMaa¡J¥ò÷÷@#žÚÚZÓ@ss³éµ2™L£Ñtvvö¸h], …B¡PH„‹‹‹Ô„½{÷Þ¼ysÆ ÙÙÙAAA7n¬««[³fP(œ3gÎ?ü0kÖ¬üÑ`0,X°ÀÚÚ:;;;--M$½ûî»5Ê9sæ Ú“­Ÿ]ªÖÖÖœœœ‚‚Óƒ£FÚ´iÓŒ3̨ †#GŽètº³gÏz{{ïÚµëþýû¨Ïž““SRRÒǵàŸÿüçÔ©SW¯^ýí·ß’Çóòòd2™D"A_wíÚuñâÅ+VL›6mÉ’%z½þÛo¿U©T¨˜““�±T�� àIDATÓÖÖfï’@ hooGFEÓŽ …B‰ˆˆèqÓ';;;dNlmmÅ0L¥Rµ´´ çÕÝOI[[[NNέ[·Ð×ÄÄDŸââ✜d¶%3f êØ™KÒØlvTT”J¥***º}û6‡Ã !M‚½•¬½½}[[—Ë …T*•Åbu¡PˆÜR\\\""",µbLž<900pýúõA$%%͘1ƒB¡`¦×ësrr¤Réý“¡“œÔÔTr.§Ÿ/Ϲsç0 ›7oÞ˜1cЈxæÌ™æ¥7†1Œ¬¬,…BñöÛoçççŸ;wÍHuvv’ ŒŒŒìñÚÙ³g÷§õÖ­[MMM‘‘‘‘‘‘ȼðÒK/eee8qB¯×Ï™3‡<S«Õ’O1G5GD"QQQ—ËEfè'¸ƒZ­Fê;räH{{ûÁÞÃfèioo'‹;::ºººz×®]EEE¡¡¡äŒâÍ7ß4#½1 H\\\F]RRÒÞÞ^SScee%•J­­­Y,*Y‡#“ÉÈ’õöö–J¥R©T­Vûûû×××···›Þ9$$äYˆK¹}ûv Ã6lذ~ýzFóÅ_¼öÚk†á8NVWWW‹’œþ7+hJ#<<<--­¶¶6//ÏÏϯÛpÇì°µµýôÓOѨå»ï¾Ã0Ì××7--­µµõÒ¥KÝÄ ¬¬ìÞ½{}ÜmÕªU“&MºpáB{{;2[ïØ±ãøñãï½÷†a_}õê ^^ZZš\.?qâ„9Xóx<‰D"‹ííí­¬¬D"‘V«­¬¬Ôh4AAA666/^ìÏ®\Z­V$‘Ž³ŽŽŽaaar¹¼³³ÓÚÚÚì$çÕW_=räHvvö¼yó”JåñãÇÑèÍ´MKKkhh¸víŸÏ¿råJvvöªU«¶nݺcÇ4¼6G´Z-rpqq±±±áóùH9:;;ëëë===ÃÂÂЙÕÕÕååå¦îÎ<¯ªªÊÚÚš¬æN@@@TTÔýû÷ ÃÂÂîÞ½[ZZZYYÙÇ%§NêêêÚ¼y3•JÍÈÈX¹r%rl³²²JKKS©TÇŽC^ÏŠäp¹Ü—_~ùÞ½{ÙÙÙ*•jÊ”)™™™·oßþàƒ,©Çáàà0sæÌ¢¢¢ÌÌÌŠŠŠóçϯY³füøñþþþãÆ»ÿþéÓ§[ZZz¼vÒ¤I÷îÝ»páB}}ý—_~:yòdô‚ÍŸ?ÿþýsçÎEžÄt:}Á‚§NÊÌÌ‹Åû÷ï_±bErr²YdÒàêêjdC“ÀÎÎÎÈRÏb±ÜÜÜ{Vº»»K¥Ò††…B! ù|>—ËurrR(  …bÔ¨QfWsöíÛG£ÑV¯^­P(:;;÷íÛ—˜˜ˆ~ruu6mZCCCffæ½{÷òóó×®][\\œ™™I£ÑF}ãÆ ‘Hdv §Óéîî¡¡Ã0¥RieeÕÏY(OOO±Xìêê:4Mê·eË–íÛ·ïØ±cÚ´igΜQ*•¤QqâĉwîÜÉÍÍmjj …3fÌptt<þü×_-‰üüüètúÿüÏÿP©Ô”””Ÿþ933³««kï޽˗/Ÿ9sæ`ÿyFÛ¼y³V«ÕëõUUU ÿ•€N§ã8þÈΦ\.“&M"ÜuuuEGG'$$(•ʘ˜˜¸¸84Ù+‘H7nÜ*‘H$ ‹Åš7oÞìÙ³u:‡Ã‰‹‹óóóëÏß+//×h4ÁÁÁƒ‰„Á`Ðh4½^ÿHóNWWט1c&Mš„aA&&&æÅ_D‰•H$ eæÌ™)))ÈÚÃçó%ITTÔäÉ“âãã‘£„Z­vss›0a ÇÐÑÑ!‘Hø|þ† ÜÝÝѳÔjõ¶mÛP’étzBB‚T*•H$fòäÉ«W¯î=S(º»»Ƭ2Fc2™F£±?[&ÛÛÛÓétN§ÓélllF…ÜâÑ‘ÀÀ@‚ t:—Ëupp1bAƒÇã9;;;88èõz4»ãêêêííÍf³íììеt:ÝËËËÅÅÅ`00™L''§GšVÊÊÊ´Zmpp0ƒÁø «•J<y2*S•J•°fÍÇccc_|ñE´º@"‘0™ÌÙ³g#Sªª-ãÇ;vlGG‡‹‹KTTÔøñãûiè.,,¤P(ä0b`a2™T*9ö]sx<*SÓb%yÆ“rb4 †““‹Åb±XNNNVVVƒÁÎÎŽÅb '''ƒ:;;÷±—\.¯©©ár¹>>>ž …Íf£x<<ÙÛÛÛÛÛ•¬££ãÒ¥K###]]]ÇoÚDøùù­_¿ÞÃÃcܸqƒA,K$’°°°ýë_ #11Õ%¥R™ÐŸž½H$jiiquuí¿ŽÅb¡òÍÏÏ¿ví…Ádæ–«;Zê z¬:Ït oPˆ6´Äwvrrr:;;çÎ;Ë/Ð’fÓµñ¼`0âå mf¼@&“Í›7o0ìþü:¡àƒ/§·�†'dð‚Áˆ—ƒB´™Kð‚þÇ/àp8ç š4:×ÿz1—n$°3U…˜I7Â0����H®=`t©imto­Ë¡P(v#<lÝ!k���€Ë:ºÛðMZB¡Ò`'i���`ˆ�É���@r����Ëâi×åÔ×××ÕÕ Ã„¡í^•òòrËØHÆrêÁC,“_Ì…‡> 8eeeæ¸bf@¸{÷®B¡þÿsZN———7lsàé·Æy*É©ªªº}ûö4R⢢{÷îYÞŽ)ƒH$º~ýz·ÂÂÂÂÂÂg³:åçç—––ϵCŒN§»té’iåüôz=“ÉŒÕÈ E{DÑ{Ûͤ­q A|>ŸÏç›c¶ RuBk]‡su"÷OŒá£½½ýóÏ?oFÕ`ödCKÅÝÝÝÉÅÝÇ¿@r ƒ½½=ÚSòYÃ`0899™K�ÁáƒÑhd±Xƒ±rÛ¬Áqü™­N8Žÿv(_‹;À}�����É���@r����à ø¯¹ …bkk ™��� ̰†JíYrŒ4«Z§ä/ÏW/™0² ���xJ2®4c~J£É!(T ƒ÷ ]h»ˆ���ÜjŒj¤1zå`F£3q¿OÔôÿ޶òJUä,��€ÅC¸G)9AJ©°¿ç;øÑéÿ$“RYU56ñåÅé¥ÿ9…0àºþÿƒDoýóîz( ���‹çFûRÓhÀûy>ÎÄ( ÃÄõÅÇ>|åÖÕ to//¹¨ÉDƒ(4F—X+:Z4rœFãBI���X< …B¥Ñ¨´Ç½Ð ×©$Bo//:“ɬ*/ õ}y˃éôÜèÇd F#þÈ€í���€%@{…¸¾Ø ×ß:«º²ŒÉdR‚ ¢©©‰dÃs±éçÇy¼ÑA~ß^] ��`ñàãºìCåâÇØ–÷ÔŽùJ‰°º²ÌÓÓ“B¡Pˆÿ¨–N§khh?Þ8‹ 0Œ€’���°|( £Óæ—ß/õööf2ÿŸÁÿk¶ÃªéO����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/index.html������������������������������������������������������������������������0000644�0001750�0001750�00000003203�11332126233�014615� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Users Manual</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h2><img alt="" src="../sun.gif" align="middle" height="98" width="100">SAOImage DS9 Users Manual</h2> <p> The DS9 Users Manual leads the user step-by-step through many features of ds9, such as data binning and contours. For an in-depth description of all of ds9's capabilities, refer to the <a href="../ref/index.html">Reference Manual</a> </p> <ul type="none"> <li> <p> <strong><a href="gui/index.html">Introduction to the ds9 Interface</a></strong> </p> </li> <li> <p> <strong><a href="binning/index.html">Binning and Filtering FITS Event Files</a></strong> </p> </li> <li> <p> <strong><a href="contour/index.html">Contours</a></strong> </p> </li> <li> <p> <strong><a href="rgb/index.html">Create a True Color Image in an RGB frame</a></strong> </p> </li> <li> <p> <strong><a href="scripts/index.html">Scripting ds9</a></strong> </p> </li> <li> <p> <strong><a href="catalogs/index.html">Catalogs</a></strong> </p> </li> </ul> <p> If there are topics that you would like to see covered in the Users Manual, please email: saord @ cfa.harvard.edu. </p> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/scripts/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12132057632�014316� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/scripts/index.html����������������������������������������������������������������0000644�0001750�0001750�00000030271�11555611701�016317� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Scripting ds9 - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Scripting ds9</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> Scripting with ds9 can be done in several ways: by invoking the GUI with a number of command-line options or via the <a href="http://hea-www.harvard.edu/RD/xpa/index.html">XPA messaging system</a>. A third option, Simple Application Messaging Protocol (SAMP), is introduced but not included in the examples. </p> <p> To illustrate how to script ds9, we repeat the <a href="../contour/index.html">contours example</a> with both methods,. The examples use Chandra data from an observation of the galaxy cluster Abell 2142 (ObsID 5005). </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li><strong><a href="index.html#commandline">Command-line Scripting</a></strong></li> <li><strong><a href="index.html#xpa">XPA Scripting</a></strong></li> <li><strong><a href="index.html#samp">SAMP: Simple Application Messaging Protocol</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#clcontour">Figure 1: Command line: x-ray data with contours</a></li> <li><a href="#clcontourdss">Figure 2: Command line: x-ray and optical data with contours</a></li> <li><a href="#xpacontour">Figure 3: XPA: x-ray data with contours</a></li> <li><a href="#xpacontourdss">Figure 4: XPA: x-ray and optical data with contours</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="commandline">Command-line Scripting</a></h2> <p> The ds9 Reference Manual has <a href="../../ref/command.html">an extensive list of the available command line options</a>. The most important thing to note is that the commands are executed one at a time in the order they are listed. </p> <p> To create contours on a data image: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 acisf05005N002_evt2.fits -bin about 3800 3800 -bin factor 2 \ -scale log -cmap b \ -contour yes -contour limits 1 100 \ -contour smooth 5 -contour nlevels 6 -contour save ds9.con &amp; </pre></div> <p> This command line produces <a href="#clcontour">Figure 1</a>. </p> <div class="figure"> <div class="caption"><h3><a name="clcontour">Figure 1: Command line: x-ray data with contours</a></h3></div> <div><img alt="[Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.]" src="contour.png"></div> </div> <p> The options direct ds9 to: </p> <ol type="1"> <li> <tt>-bin about 3800 3800</tt> : center the image display at (x,y)=(3800,3800)</li> <li> <tt>-bin factor 2</tt> : bin the data by a factor of 2</li> <li> <tt>-scale log</tt> : set the display to log scale</li> <li> <tt>-cmap b</tt> : use the "b" colormap</li> <li> <tt>-contour yes</tt> : display contours</li> <li> <tt>-contour limits 1 100</tt> : set the minimum and maximum contour limits</li> <li> <tt>-contour smooth 5</tt> : set contour smoothness to "5"</li> <li> <tt>-contour nlevels 6</tt> : create six contour levels</li> <li> <tt>-contour save ds9.com</tt> : save the contours to the file "ds9.con"</li> </ol> <p> If you wish to add options to the command line after it has been processed, the whole command must be run again from the beginning. It is, however, possible to interact with the ds9 GUI that has been created. For instance, instead of including the "<tt>-bin about 3800 3800</tt>" modifier, the image could be recentered in ds9 interactively. </p> <p> The following command line builds on the previous example by retrieving a DSS image and copying the contours to the new frame: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 acisf05005N002_evt2.fits -bin about 3800 3800 -bin factor 2 \ -scale log -cmap b \ -contour yes -contour limits 1 100 \ -contour smooth 5 -contour nlevels 6 -contour copy \ -dsssao A2142 -cmap grey -contour paste \ -frame first -match frames wcs &amp; </pre></div> <p> The resulting image is shown in <a href="#clcontourdss">Figure 2</a>. </p> <div class="figure"> <div class="caption"><h3><a name="clcontourdss">Figure 2: Command line: x-ray and optical data with contours</a></h3></div> <div><img alt="[The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.]" src="contourdss.png"></div> </div> <p> The options which have been added from the previous command line are: </p> <ol type="1"> <li> <tt>-contour copy</tt> : copy the x-ray contours</li> <li> <tt>-dsssao A2142</tt> : retrieve a DSS image of A2142 from the DSS-SAO server (there are also a "dsseso" and "dssstsci" options)</li> <li> <tt>-cmap grey</tt> : use the "grey" colormap in the DSS frame</li> <li> <tt>-contour paste</tt> : paste the x-ray contours onto the optical data</li> <li> <tt>-frame first</tt> : select the first ds9 frame</li> <li> <tt>-match frames wcs</tt> : match the WCS of the DSS frame to the current (x-ray) frame</li> </ol> <p> At this point, we can end the ds9 session or modify the display interactively via the ds9 GUI. </p> <hr> </div> <div class="section"> <h2><a name="xpa">XPA Scripting</a></h2> <p> X Public Access (XPA) is a messaging system which provides communication between Unix programs through a set of access points. The two most common actions are retrieving information (<tt>xpaget</tt>) and issuing commands (<tt>xpaset</tt>). For more information, see the <a href="http://hea-www.harvard.edu/RD/xpa/">XPA Messaging System</a> page and the <a href="../../ref/xpa.html">XPA Access Points</a> section of the ds9 manual. </p> <p> XPA commands may be issued one at a time from the terminal or collected in a script to run in batch mode. Unlike the command line syntax, there is no predetermined stopping point - commands may be sent to ds9 as long as the GUI is open. </p> <p> First, open ds9 with the data file: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 acisf05005N002_evt2.fits &amp; </pre></div> <p> The <a href="http://hea-www.harvard.edu/RD/xpa/xpans.html">xpans name server</a> is used to manage the names and ports of XPA access points. Use "<tt>xpaget xpans</tt>" to see the list of available access points: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% xpaget xpans DS9 ds9 gs /tmp/.xpa/DS9_ds9.22972 username </pre></div> <p> Now that ds9 is running and linked to an XPA server, we can use xpaset to modify the display and add contours. (Refer to the <a href="http://hea-www.harvard.edu/RD/xpa/programs.html#xpaset">XPA documentation</a> for details on <tt>xpaset</tt> syntax.) </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% xpaset -p ds9 bin about 3800 3800 unix% xpaset -p ds9 bin factor 2 unix% xpaset -p ds9 scale log unix% xpaset -p ds9 cmap b unix% xpaset -p ds9 contour yes unix% xpaset -p ds9 contour limits 1 100 unix% xpaset -p ds9 contour smooth 5 unix% xpaset -p ds9 contour nlevels 6 unix% xpaset -p ds9 contour save xpa.con </pre></div> <p> This command line produces <a href="#xpacontour">Figure 3</a>. </p> <div class="figure"> <div class="caption"><h3><a name="xpacontour">Figure 3: XPA: x-ray data with contours</a></h3></div> <div><img alt="[Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.]" src="contour.png"></div> </div> <p> The options direct ds9 to: </p> <ol type="1"> <li> <tt>xpaset -p bin about 3800 3800</tt> : center the image display at (x,y)=(3800,3800)</li> <li> <tt>xpaset -p bin factor 2</tt> : bin the data by a factor of 2</li> <li> <tt>xpaset -p scale log</tt> : set the display to log scale</li> <li> <tt>xpaset -p cmap b</tt> : use the "b" colormap</li> <li> <tt>xpaset -p contour yes</tt> : display contours</li> <li> <tt>xpaset -p contour limits 1 100</tt> : set the minimum and maximum contour limits</li> <li> <tt>xpaset -p contour smooth 5</tt> : set contour smoothness to "5"</li> <li> <tt>xpaset -p contour nlevels 6</tt> : create six contour levels</li> <li> <tt>xpaset -p contour save xpa.com</tt> : save the contours to the file "xpa.con"</li> </ol> <p> As long as the ds9 GUI remains open, we can continue to modify the display. Here we build on the previous example by retrieving a DSS image and copying the contours to the new frame: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% xpaset -p ds9 contour copy unix% xpaset -p ds9 dsssao A2142 unix% xpaset -p ds9 cmap grey unix% xpaset -p ds9 contour paste unix% xpaset -p ds9 frame first unix% xpaset -p ds9 match frames wcs </pre></div> <p> The resulting image is shown in <a href="#clcontourdss">Figure 2</a>. </p> <div class="figure"> <div class="caption"><h3><a name="xpacontourdss">Figure 4: XPA: x-ray and optical data with contours</a></h3></div> <div><img alt="[The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.]" src="contourdss.png"></div> </div> <p> The options which have been added from the previous command line are: </p> <ol type="1"> <li> <tt>xpaset -p contour copy</tt> : copy the x-ray contours</li> <li> <tt>xpaset -p dsssao A2142</tt> : retrieve a DSS image of A2142 from the DSS-SAO server (there are also a "dsseso" and "dssstsci" options)</li> <li> <tt>xpaset -p cmap grey</tt> : use the "grey" colormap in the DSS frame</li> <li> <tt>xpaset -p contour paste</tt> : paste the x-ray contours onto the optical data</li> <li> <tt>xpaset -p frame first</tt> : select the first ds9 frame</li> <li> <tt>xpaset -p match frames wcs</tt> : match the WCS of the DSS frame to the current (x-ray) frame</li> </ol> <p> At this point, we can end the ds9 session, issue further XPA commands, or modify the display interactively via the ds9 GUI. </p> <hr> </div> <div class="section"> <h2><a name="samp">SAMP: Simple Application Messaging Protocol</a></h2> <p> A third method of scripting ds9 is via <a href="http://www.ivoa.net/Documents/latest/SAMP.html">SAMP</a>, a messaging protocol that enables astronomy software tools to interoperate and communicate. SAMP is also used by such applications as <a href="http://www.star.bris.ac.uk/~mbt/topcat/">TOPCAT</a>, an interactive graphical viewer and editor for tabular data and <a href="http://aladin.u-strasbg.fr/">Aladin</a>, an interactive software sky atlas. </p> <p> Information on the ds9 SAMP implementation is available in the <a href="../../ref/samp.html">ds9 Reference Manual</a>. </p> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">21 Sep 2009</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/scripts/contour.png���������������������������������������������������������������0000644�0001750�0001750�00001363727�11332353406�016537� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��:��r���B!ý–���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ)¤¹,q�� �IDATxÚìwX××Ç¿3Û ,K,€Xì1šØK,X¢HóSHôMl±$%‰Ýh,± –5v1Ñ(±‹Q¤©KÙ]¶ïûÇ0ëRT0͘ù<<º»sÛœ¹sÏœsϽC¨Õš'~Û¼ç^="Æ þNOö¿Å_{Ôå­¡ŒD^Aþ–¨×ëˆ^#§÷\V!g$ÂÀÀÀÀð RQV’‘t… @¯×«”JF" ÿeTÕrMµâ…ÉXžPlI¤^¯U)ªô:íóÓÉй<�µJ¡VÊQW ²$IõU¯× Ô•N­ªQWZ•B]˜ÒL*àp8¹U,;Aæ¥èÔJ¢<³´¢ÊÞ§su^´Z¶Zîîæú”EEE•å¥<¾@¥THÄ+Ûç§×iµ¹ùZ¡ŒFµ²ª…»Û «(..©ª(å Ä”ú1èõ5ê Œt"6Ok—æ.ÂÀV>W¯ßL.)âYÚƒÖXF½V¨—i jI3o#sy^4*¥‡»‡ÃyaJ—ÇééOÀcÛÛÛ¿0=—ËmæèPX"3ôîn®\.÷…Yœ222`4Íì%6� ’6ÛÀÙÜÍÈQÊ+­,„‚¼lu5+²¦””%U™ŠgÇ[=ÍòÁa“¾nŽ|'%«°J¡bz0Ã’¨¡1‰ ‚ ’@£Ó“¦â›’…$‚RL´uE$ùT÷$OkÑìaö#^[¯­*Î`qø¾XSUÊ­.’ù©›Ý°zäsÙm¼œ[8Û’Q©P%§çç<‘ŒF�¾nm}›³Y¬ŸÏÝ–W«©ôNv’@Ÿæ–"¾F«ËÈ/½›–§×¼\ìÚ·t»Ÿ^ô8Ïø÷q|÷ÍN~R1¿àIa•ÂhòœR°X¤‡“m+f|'·¨üzr¦Z«cz9Ãë�A‚ 4D£A &=‹$ßéÒª~ª;©yÙ…e5ê$ £‘ «xÃÍÑ»¹Ý™ë)Jµ†Jܺ……ˆúê³*HZ·´ºP[Ýqb£­gÖ£ l½Ro$ô$WèàÁ®ÌªRkyÍ|8|á³N¡s]ý Ê+å–"­J™SP ‚-àqÚ·t{«sK’ î§f$>* Yl¯æv£û´ofkY^Q%ð»¶õ>u))þêCgé›üÊËJoiT,®àï½`@ô:ªÚh4Ö‹«£õÄÁºTVѱU •˜wìâ=€dú9ÿ_[Q–O£43ëŠÀf±ºxÖOö å‘V­æò]:è*ÜšÙt ðt°•l9| @çÖî}:ùiµÚ݇NÛ9»QU€ú£aÓU×m"O,»·—=8Ç‚®:ÿ‘QYÊelGžHRc˜ÕƒËa{¸ØI-…3¾Z_Z©är¹jµJÏñE{kKWÇüÂ[©¤kÏ•{-­lÞnÕÂÉf}ì‘ó‰Én.Í¢Æìêýî#�Nc%â~=}ô£¬B½Áèêhý뵇lÙµ­g‘L¾óø•²Êê7Üum#µ‚@rzÁÉK÷K+ž.¶aoµg±Èì'eîÍlÒóJ¶»,òCü=;·vò9)YÅÇ/Þ+’=N±µ ií×Â1=¯D$àz�,kÒ€.¾nvF#*Õ±'¯ùµhf+ý°ïÜÅÛ©Ëf…·£ù•;)%rC#m[†WW]$å²kBbcMz‚$Ò³ò–¬Ýiî‘êÚN£ª6ô5º ÒHÒUœ¿•f#µòh6yP—äô‚·»´Ôh4ó¾Ù ÓÖŒ¨„™uEý˦,Š5ªÐÊAiã¦,L3F¡Qp]쥎Ï9½ÞPXZ¥Rk#ßò¸ <-§8%ëIEU5‹d5w°v±—l?ß)ÐÏÍÉÎÝQJòDvR N÷ëåÛ+‡b%+ëI¹½•»£•VS3iD„¥ˆïê ¹yÿ±‡“tTŸ¶I)ÙùOJÞpp·9{+ËhDrjfnA¡¯»ó[¡AUUUgSÃú¶·³þ=ÑÕÉÁÙÞ*#+»ºª¬w‡.C{ø_½ý 3¯pD¿®$aØ}*Q¥3—à ð ô¼xã^y¥¢­oûÜ‚b�^.v¡×ï>Jz”ik-‘çW:J ’ðórc ,­$ÕÊj©ˆW(«àðøÏRá ÿuÕhg`Í\í $–Þ`�GhïæeJ#¶iV&«�IR³PAÄSg VoØwæÖHÀßËÉÓÅ6¿°då{*ÕO?S{H‚@n"Ì­«F[]u¥NYf` Ä|‹©©ÒkÕl.ÿY'`.ßË”Ë+[8J=›Ùv ôº’”~èÜ]#ÁjãåT)W<Î.�›?a K€ÛÝÇ…Aè F#Áâò…,6W�I@§Õ˜{ûÁãí•Xˆ}[8þõ"›Ësw±·‘Tʪ² åŽQ"Ukõ6KÌ#›Iù±àqVÞ¶¿vïÒÞÓÍ �ÃjádCP©5\.W¥Ö:Z‹%²ºRG’¤HÀw²“VÉ•{Sؾ^îl�äÕjY¥ÂÚÊÂÙÑîIi¹FoLzœwæÚ}7{k{k‰¼JÁb‘½Î`п–Q' ÿ=ëŠ@£­+$@Ö¤'逳ìÔǧ>=’$ŒFÔ®"³ ÌßË @N~!8'wÓQ‚$@’”³0 µ@}ªÓ¨*³ï@Z{j‹Ó+*Ê ¨ªÊ—HÜÚ°Xœgœ�Ølöåäìßï{¹:Ž~»‹§“5¡Sˆ¬ìZµp$`Ò§ _(âq9Þ®Ž7SräJ•“Ek÷¼J£T"t²•†ìü¢nÍÍ‹UV«Œ,®`ëtúªjµ…@’$Áa¡K@‹®É2*«ä”5f4ŒF#Aˆ/´0Y¦FÀø\^uõùk·eåUee¥:BÈe³A `0’%IA°�€'¥•;Ž]²’>îN¡í‚ÙlöÙ[Y‡Ïß:†©aï°XDQi¹$ëÂÀÀÀðŠª+’ ’$=wE¤±&LÏQ;{$IÊh$jUÑ©¥ë›| Kʤfö’ÚÚï?{Ç¿F4jA€¨£®Œ}uá#R&õ Û8)x"yÆ5´„<_Sn+´skÐ÷Åb݃¼Þp³Ë+’ ¸ÜfvÒiYU•Aþ-Å^a‰L$àè—UÈ]m¬-…—î¤z8Ûþ/¬FA™µ¥‡³ÍµÛR³ò½½jOÙÁ"éF$‹ªœÃ&m,¹l2-3ÏÖΆ:«¼¢²² …·»óÔÑýœì%b�•Z—ž[ÒÑÏ•ÇåV©ôÖ±µ à<!õ$AÕm~qE[o§þ=:(õìN69ù…�œí­ü}\só Õ:pÙl> "¶aP¯ŽUr;‰³ƒÍÉó×òŠeb©#u™™îÎÀÀð/wÖ eÁ­ÝZ{Ôú©R¨÷ž¹]K—€¤Ò×ü‹ZóJ5š†Ö:A’¤‘Ê ÃÍ{·ó"`üzíN#›oëàÔÚÃqLŸ¶;NÞ0³öhueš»ªk ºŠ<¾ÜÐ<@âàÀÒ±…Ñ µG±HÀ«Òʪ–l±u}e4i¹%–|¸Ú[³HòÚíO_,Whßpµ¿—šwølJÖ‹Ý¥íaºY‹yn§•”½Õ¹•›ƒDQ­Ú}äÌ‘_¯°x"­‘UTZ!WTë †Â²Ê ¹Âh4V*ÕE¥åZ­N«Õ—Ȫ*ªr¥:áfª˜ËêÖ±MâýÌœ‚’òJy•BµëÄÕw{ù;Û[åç?±“µ:½Þ`¸z?K£©îÜÚ½WÇV¥åò 7’å %WlM’¤No¼p'Mè[y¹eæßH~L Õé ÖÙIÄÞ.6páFòѳWÄR;±€ãçê¦Öh㎜9ræ*W,esyuâÝþêªÆ¹Çå°¹¤Ñh0Ôá5Šœ´äæÞ­iDÂ@˜\~R©tÁÔQæêŠ$‰wÕÁAP!òF£ÑäoäpXU 墕›ZÂÅÛã`B²²ôÙ)w]ß0)¦šP ª…½FNíÔ{PQY¥Iç«Ë¸òl™ Bç6$‹mú™”=jÓ\3‹«ËÙŽ$·pv£ÑXYúD¥¬2èµ�Éáòk›WV˜E’,‘ÄšÍåFe¥L%¯[ÛóbEU™Z)7èõ$‹ÍZ-¬Ø\^eée•LleÇbsÊ‹òD kû¢ìT›maã¨SUË+ŠR‘¥µ²J¦¬”$Éæò4Õ ØÊÏ×»Z.“WȺ¶k5¨wç݇ÏÄ_{$±sÒkÕòŠRJ ƒ‘d³ù"‰ÈRÊæÔ, «–WTÉŠô:-›Ë3è´$‹ciã ×i+KŸ ‡'°ÚëõÚª²"½NËb±ø"‰@,asù4Ÿ^Y”•å-Ü]L»Z夫”UuÒÄ;gw�§³,ƒÖÅʼn:¤Q)Ÿd¥Ö/ÖÑÍ›ËVUÉ Kd½Þ­y3G*ÎËT)«š{·1%ÎKKæðöÍ=�ddd²–”ºRT–eÝ»Zc]™f· :®²P£ßÞ‹dsÌÍ:ƒ¥[¡¢BÂ'9Ш+žì=thŠ¥vBK©)|ƒ Y$‹eíèF$Éb±Ø�lOleK²Xl6—Åáê-uI @€Åâ$)²²Il¨%Ív.ž$‹M²X6ÍܨҸ\>OdA²Ø,[le'´i„FA°Zz8µõjg0è-EüÛ_º™Ìå[R{,²8\ƒÁ@ÿƒ XÔÄ�€/¶dqyÔ¢�£Ñ�‚`‘,OÀáòM+«I‹C8\¾Iï“l6ãd``x¨Ù¤¢fHtpõ|®-FÖÙ¢‚'¹½ølÓ¨¿«…½K‹:É\¼[×ÊCæn¼šÈÀ§ö›KX:±X\6_LµÜ}F®°PK”Tiõ,[L<ˤ ¹<€WçG–Plþ•Ë{^H²XnÝô<ó•Ètb–ÈÂô›I‘²À®S]RzQFFºA£®V©r ˪´¤H,d±Ù$IR[?ëZ±ìú¿šÌ¯§¿°9LÇf``xÍàpùEÅ%Í]œ_˜²´´Œ`±I[«UWÉ––ÏO¯ÓédålÏÈ6—ººº¼°Š²2™‘`Ë´€úë®Xl’ei÷ õðÄ�XÀ«<WSV¥Ê./ר«I’$ØB—/³Xl¦;2000< ž@¤®V¤¥¥7Âcób’Å6rE%eEEÅ/HO,ŸÃãШ”«‚Åå‹MFaf]T8^“mÖ…ë:k£éŽ Ï+ÂF&6 $›Íc[62=¥_8|ø‚ÆWA®›-6 b‰ˆÇ\0†W„ …:½Pn¶#; ×iúvòmëÛœ‘ë€J¥:x*!5¯fŸ£º3: …‚‘Ã?Î/¿ü’ššØ5 ®ŒF£V«edÄÀÀÀÀð“››kÈάb````øÀ¨+F]1000000êŠQW ¯ ÝšèæÍ›•••濈D"77·û÷ï·nÝÚÖÖöåª×ëõ¿ÿþ»é+‡Ã 1}MHHJ¥–––:t�pýúõ-Z¸¹¹5²üû÷ïõèуúš””TZZ  Y³f¾¾¾…@©M_ÿˆp^š+W®¨T*Ó×.]º(Š;wîøúú6kÖìåʬßLRý«ÉÊÊÊÈÈ >ÛÛÛ·lÙò…YT*Õ•+W\]]=<<þHÕ …âúõëÔçÎ;óùµ^¥-“Éþ Tëpýúuó•$õklL'ÿ㤤¤ˆD¢K—.¹¸¸xyyݼyS£ÑtîÜÙ¼“›.‡y— J¥/Wc#3&%%Éd²nݺ5Rª�¨„á/Åü:>çî8wî\#oä:°Z´êèâé'WVwôkîhc©V«L7a„-[¶ˆÅât™L&“ÉÆŽìííýr§§R©:vìx÷î]ƒÁžž^PPеkWóq6''ÇÓÓó—_~iÛ¶mAAÁ[o½eggÜÈòçÌ™³páÂÙ³gS_§OŸþÍ7ßXYYq8??¿¿â‚Q5ÚØØPRòööþûÕÕ€~þùg—žž¾jÕ*‚ \\\8àìììääôre>|øÖ­[ÔImܸñûï¿7Iõ/%33sæÌ™×¯_///OLLܾ}»¿¿ÿ Ï"//¯gÏžb±¸{÷î¤öÅ‹¯_¿ÀÚµk EhhhqpÈ!>>>ÊÉŽ9r÷îÝB¡0==½ÁäìÙ³—/_îÝ»÷Ÿ%óC‡Mœ8±W¯^¡¡¡,ëÍ7ßœ0aÂ?þ8eÊ”7nDEE%''S—ãöíÛS¦Láóùééé;wîLKKëÖ­›é=/¤°°pîܹ_|ñEUUU#3NŸ>}ùòåÿ÷ÿטò8››Û©S'FüÕ˜zŽ››ÛsmÛVTT 4è…Þ½{·ZGTD:­º¼0· ¿J¥ÒÅ‹SŸ—,Y"—ËM‡4ÍŒ3¨ÏQQQ>>>M:É:˜J¦tïO?ýôé§ŸR_ÕjuEE…^¯‰‰pôèÑ>}ú´iÓ¦1%Oœ8ñòåËK–,™;wîÑ£G“’’æÌ™óøñãêêj�ß}÷]JJ €ž={>|ùòåUUU_|ñE||üÑ£GçÎKéÀûöíÛÔaŽú°qãÆ~ø!22rÙ²e#FŒHJJªSã˜1c–,Y`Ò¤IñññùùùíÛ·Ÿ8q"€/¾ø¢¤¤Àˆ#šúìܼysª ÷îÝ[³fÍ[o½UQQ¡Ñh¨s>|øÆ'MšÔ®]»F8eÊêC||ü‰'æÎ›ŸŸOµÀ—_~iccséҥݻw°°°ˆ‰‰9wî—˽|ùrFFF›6mÜÝÝ=J ý?‘üòË/›7o>|øýû÷CBBΟ?ß®]»:©ªªš3g•åÓO?5Ýè’%Kòóó4õ:.Y²ä§Ÿ~Ú¸qchhhŸ>} 333—-[F¥z£‰ÿû¿ÿ£õ(©N›6­}ûö666ñññ”pY©££#uá222Ö¬Y3kÖ¬:R°{÷îK—.Í;wÉ’%}ûö­®®®¨¨�pãÆmÛ¶àñxË—/§2FEEmÛ¶ÍÉÉ)22òGIIIŸ~úiPPÐÂ… ?~œÇãÅÆÆÊårªÙsæÌÙ°aÃìÙ³‚Æî —““SXX¸víÚ5kÖÈåòœœœ5kÖ„……]¾|™ºlß¾=11€éî e¨ÛÊÔL·eŽ÷íÛwàÀ¦‘êèÑ£ñññ�Z´hÑHUÇð§Pçî0¿T7îÒ¥KXXØ Ëyɹ«ãÇ?~Üôõ½÷Þ»yófxxxuuõ¸qãÊËË_úÄnݺéèèøå—_Rî…ää丸¸òòò!C†�h×®««k#K µ²²¢šzûöíÜÜܾ}ûÆÅÅ]½zuݺuK—.6lXÛ¶mçÎ{âĉS§NýüóÏæ5–——ÇÅÅ%''¿ôéœ?~ûöí£GŽ‹‹‹ŒŒ¬_cdddxx8ŸÏˆˆ ìÙ³ç¢E‹vïÞ=oÞ¼íÛ·‡‡‡;::FFFÞºuët—'OžÄÅÅ¥¥¥:ujýúõ›6m¢j49ÙÉ¥K—f̘1vìØiÓ¦1¢   <<<##côèÑ<øè£¬¬¬ÂÃÃ8ðé§Ÿ>|øð£>òôô|çwbbbÃÃÃ/]ºÑø»té2yò䯾úªwïÞ-Z´8sæLXXX}áŒ7îþýûááá2™lôèÑ&ÇÔâŋ׮]îîî>cÆŒK—.5©“[YYQöM=<zôh™L~ÿþýqãÆ™RN›6->>Þt322âââ-Z4sæÌ¸¸8ó»¦R_ª\°`Appð¸qãââânß¾}áÂ…¸¸¸ŒŒŒˆˆ>Ÿ?mÚ´´´´¸¸¸qãÆ/]ºtݺu¬´ÿþÆ «ÿûæÍ›sssoß¾MÝVVVVcÇŽmݺutt´T*íÝ»÷òå˧NzæÌ™Æ;U*Õ´iÓ¼¼¼ÆŽëèèAõUªçlß¾}Þ¼y»wï^´hQÏž=Mw•·¤¤$..îáÇT9qqq‰‰‰Ë—/_¹reXX˜ŸŸßÌ™3Ïž=K VgÏž9s¦ŸŸ_XXØÊ•+—/_Îh‘¿‡úwõûíÛ·MýsÁ‚ü3ÕU~~~HHHHHÈ/¿üRÿ¦b³ÙR©”Ç㥦¦6ukŒ#GŽP%0 ªª*77×ÕÕuãÆu÷”ûÎÉÉI"‘4¾pg积oqpp0¹rss«ªª$‰X,.***))9~üxIIÉ{ï½gJß«W¯!C†DEE5õ Q§³sçN�F£ÑÛÛ»  àúõëçÏŸwww7ÕàñãÇAAANNN™™™îîî~~~2™ìÉ“'éééF*• …Bª©Mj@rr2Õ†7nìÚµ«ÎóûòåË©)+³‘dgg:tĈÓ§O<J¥AAA‰äþýû …";;ÛÅÅ%((@jj*•ÅÅÅ¥U«Vƒ!((ˆÊØøJ%É×_}ùòekkkU«VQN'­V4gΜëׯìÙ³gýúõR©”Ë妤¤èõz*{FFFuuµT*‰Dùùù”òr †””[[Û   ó³HIIa³Ù¦ëHIU«Õ~òÉ'º¢úCHHˆŸŸ_||üo¿ýFIU H¥R½^ŸššZTTTZZêëë»aÃóŒÕÕÕ™™™NNNAAAl6›2â)188˜º­Ù{{ûwß}—ꢔÁzóæÍgM6xzzÞ¸qãÛo¿Ý¼ys‡?~lnÝ6Fª•••*•Ê$Õ¨¨¨AƒiµÚôôô‘#Gž;w.00ÐÒÒ’º;¨4AAAË–-[°`Á… zõêºhÑ"¥RiooÕ·oß3gΘ¼ÁF ,[¶Ì`0$$$¼ÄMÍÐH¢¢¢BBBL¦º¢T*åóùõÇœ 6øúú–––šOù?‹&8œœ.^¼H}¦,ô:ýüùó©G3ӻɠAƒV¯^M}NHH >p¹Ü?Ev?þø£¿¿ÿñãÇÓÒÒV®\i®½�|óÍ7\.·ÿþ®®®\.·Î6TjµšÅb±ÙM~W–IP§N”¸ÿþ|àääT'fáYh4“HïM¢hÕªõT1xðàñãÇoÞ¼Ùtˆ ˆ—“íùóç¥Ri«V­X¬¿ï}g………‰‰‰mÛ¶Ý¿ÿàÁƒ=øô¥,‹jÌÉ“'gϞݩS§»wïÖ/Ä$F‡¿­å}ûöýðÛšËÓÓóâÅ‹?þøã‚ ®^½J=¢8qâÁƒÁÁÁ­Zµ2¥lä]ör׺eË––––W®\éß¿¿P(¼yófppð³®{bbbIII¿~ýÖ¯_?cÆŒ>ø Gvvv©(!!ÁÊÊJ«ÕΟ?ßÎÎ.##ãÊ•+�8Žé]G™™™QQQõç´H’ôôôtqq¹té’Z­îÒ¥ ‡Ã™?þüùónjӡC‡Aƒ™|¶ýúõëׯߊ+Fåää´eËFµü¬Y³¦[·n ƒ¦~‘Éd¦{Тֻ›¤,þ´@v//¯ØØØððð€€€—ßë÷,+íСCMzLîÝ»÷¸qãd2™——WCëÖ­[²dI@@€µµ5åZMKKÓjµŸ}öÙ±cÇlmm ðg‰h×®]ÉÉÉëÖ­£fÅ^5+0sæÌ€€€:×øï'...:::::zäÈ‘g½7oÞ7nÜåË—QoºÀÝ»w—.]š=gΜ–-[ÆÆÆöìÙ³~!±±±Ÿþy@@€¥¥e㫞8qbqqñ±cǨ.·jÕª¿í¬GŽd f?~|lllpp°§çÓ÷‘SÓTãÇoÙ²eLLLll¬Ý¹sç¾øâ çååÕµk×cÇŽ•”””””,]ºôÊ•++V¬˜<y2å2mê,ïìÙ³©¡ƒ¢Á«|äȑ˗/ÇÄÄÔ?DÕHýNM^ÆÇÇ/]ºtÍš5C‡¥2š<@K—.4hÐÌ™3ÓÒÒ¶lÙÂè•¿ ;;»ØØØiÓ¦Ô™ÔlR7þsÞ±ýÉ'Ÿ„‡‡ß½{wذaM}úNHH`aa1oÞ¼1cÆlß¾}ܸq¦Ç+ —?üðÀãÇo’F|ÿý÷·oßÞ£Gooo¥RIý8f̘óçÏòÉ'•••àÝwߥR®[·Ž2kBBBìíí© ³?SÎÎÎÔ9fee=KEEEݺu+<<<33ó7ÞhüÄ5Ezz:%ÒDGGÿñÆoß¾]©Tž<yòäÉ“¦‹¾qãÆðððÛ·oGGG{xxLœ8qÏž=×®]ðÙgŸÝ»wï×H†?~¼²²²S§Nýû÷ïÒ¥KáDGGÏŸ?ŸzZòððX°`•ýÃ?¼zõjxx8åa‰DMê6jµzΜ9¼råÊôéÓçÍ›G=“Õ‘ê¼yó&Mšž’’òᇺ¸¸üY}Æ\ª.\غuk»víNž<ùÕW_ÕQ ¦»ãÞ½{•••«W¯ÎÊÊúÓÇooï¥K—~üñÇTè\.4h}ìè3�� �IDAT©¯RŸ}öY“ ^HÿþýOŸ>½`Ágggêe2YÛÊä·´··ß»woRRRqqñ€LwïÞ={ö¬%UF‹ü=˜ß]»v­cî;88|õÕWݺuëÓ§Ï ‹"zœÚ¹ÏÐ'Å¥Ó†ú¸<ËjÉÊÊÒëõ¦U,™™™�¬­­ œ…B!5W yóæBa£ßGi0˜2R¾///™LVTTäææ–““# ù|~II‰»»;Ç«¬¬¤j‹Å——Z­ÎÌÌ´µµµ±±¡j”H$ŽŽŽ999”ö’J¥ööö�(_¹­­-uŽîîîMº6•••¦E]yyyJ¥ÒèOÕ( ©é+ÊéáááQZZJ#%[ª©Ô u6i!‹)£ÉðU«Õ999ŽŽŽåååÔu4ÕØHc<++Ë|-%JDÔ¨Êáp***¨y…:בÅbý©RM¥>[ZZRË8êG¯×§¥¥ Î‘jª©F**‰’j“®&ÕsLç¨×ëM:À\ª‰$55Õ`0�hÖ¬™¥¥eJJŠ©©Ç\8¦žSGªF£‘êc</((hÆŒT—£îÊKfÊØ¼ys—––fêä$''G­V›_GÓ\2Õ€/GSG€ôôt‹eZI™––FÍ;š¤* M§L9¦s`4‡ 2oÞ<ÓÊ*S_­ÓåJJJ¨e—|>¿ñk7©Ë …B¥Rùü»cóæÍ+V¬ ÖóQrƒ~‘Òj"[gW­¨Ì¼{¹±êŠáU`ÿþý³fÍŠ‰‰‘J¥óæÍûàƒþ³ÒÉd³fÍJLLlR8"ë@ttôŠ+nß¾ýœG‡:êŠÍHá_ĻᆱR©Îž= `Ö¬Yÿe] 99™ ˆÝ»w3ºê_G›6mFŽÙ$ÿ<£®þeŒ?~üøñŒ�„††6fã†W!C†452€Ùâ–á_�£®uÅÀÀÀÀÀÀ¨+F]100000¼*ÔŠ Ôëõ§Nb„ÂÀÀÀÀð£×ëÍ•ÔÓO*•zïÞ½¦í^Eëêôéxë—~Û,ßA\%²óuÕ€ÐÐÐ|ço�$I>.¨¸qðrꊡJ¥òæÍ›Œ^'ø|~ûöí90üë`ÔÕóP«ÕZ­¶K—.Œ(^ÿª_F]ýËE%Iwg00üK9uêÔСCë¼€œQW ¯ÔÛ¤ÌÑjµùùùŒdþèHÊf;;;SŸ 4 #“?ˆ££c×Ò>O]­]»Öôî] ///''§„„„I“&ÙÙÙ15QQQ±qãÆÎ;wëÖ­þÑüü|êÅÞ£F:zô(%Õ~ýúùûûSM)gΜùàÁƒ£Gàp8Ó§OpæÌ™7n�pss5j€ØØXÓ3pà@??¿o¿ýÖÏÏoàÀ�6nÜ(‰Æ÷œŒ¦¦~ûí·T9Æ óòòz¹Ó×jµ+W®ô÷÷ïׯŸyϡαNbS�>üðC…BÛ»wïvíÚÕ/9--íàÁƒ�&Mšdþžl‡3jÔ(óŒYYYûöíëׯßÝ»wÍÇßI“&ضm[·nÝ:wîlj*‡Ã¡„cÎôéÓ³²²¨ØÙÙMš4)!!áÊ•+¦Ëñš!—ËïÞ½ûÒ—žÂü%¹×®]óññadò¡ÞèØXuµfÍ;;»™3gš«»‹/ÆÄÄ 0€QWæp8__ße¢V«?úè#�ááák×®=|øðÒ¥KOŸ>ýñÇoÞ¼™ÍfSò1b€ÜÜܨ¨(77·Ξ=[.—wïÞ}Ö¬YÇwqq™?¾^¯ Û±cGVVÖÒ¥KPÁœ111...A 0`ýúõvvv®®®u2ªÕêèè诿þúþýûŸ}öÙš5kŽ=zøð᯾úê§Ÿ~:{öì®]»^î²jµÚ˜˜˜ &ôë×ïÛo¿Ý¼y³ù9zzzšRΛ7ªÑ$·üüü˜˜KKËÕUjjjLLÌ”)Sx<^LLL§N(a²X¬:³²²bbbwíÚe�—››óóÏ?¯[·Î××—jjDDõÞ¨¨¨>}úŒ;@iié´iÓììì¨Ë¥V«»wï~êÔ©”””×R] ^¹{èÐ!à]`?ðÀîýIÅŽº%ë´ª@k@<Â< þÔÞ¸”Ñ_û—€*ºÆ, ï¹Ù)Ôg�p¨ZOš4^,Îmß¾½B¡0vvvþôÓ @oêþ�¶šet®]T%°§‰'5¡ž“Œg'{�$Ôým1àM^Ýë<¦ì®ÎDàg”zØtxv½«€�@kºæì§/Ç àm�@ðôÖÏÏ/,,ŒzåºÑhl‚3ÐÖÖvðàÁÔç=z´oßÞ´0ëÑ£G&L`±Xz½~ÿþýÍ›7½](#FŒ(**2 ‘‘‘cÆŒ)))8p uú7n´³³[²dÉĉ}}}ÇŽ›m0ÞÿýI“&………%$$XYY©ÕêG<xpAAÁîÝ»e2ÙǺtéR[[[‹õàÁƒÄÄÄ·ß~{ðàÁ .LHHpss{üøqHHˆŸŸ_TTTRRÒ’%KîÝ»wúôi???’$I²f'­¼¼¼G™.pfffŒJ¥R&“ 0ÀÂÂbõêÕ¹¹¹ï¿ÿþûï¿ïêêzûöí“'OÖ1¦Æ={ö|÷Ýw$IÚÛÛÿôÓO»víZ¿~ýîÝ»===OŸ>=þüeË–­Zµ À‘#GBBB†îáá‘——·wïÞòòrSi .ܼy3€›7o:::nß¾½uëÖÔ W¯^Ý¡CWWWs©PÛ·ooii ÀÅÅÅÔ!U*ÕܹsW¬XѾ}{OOÏ©S§Ž5jðàÁ»ví …¦d&RRR L½mÚ´iÓ¦Mqq1�OOO*}VVVbbbdddÿþýY,VDDÄ­[·¦L™âè蘒’ò÷ð{÷îíß¿¸¼,@avœŠÎ˜l ¿~¬7KðQí¯&¥ÀA@ýìÊ©Âã1 Š€€P €(† @� ¤ à�Wkz{_÷ÌTί@%±8ÔñÚ™Ÿ ü”4tè P€¡¡N66‚Ž;ÖRA••û÷ŸZP¬Àúˆ›YÔ­Zbvf‡Œõ~dѲê��dfêJoÖl�Èë ÷€5pŽ>îH¢ÝQ(ù@.ò+P™^»Šc5ç›`„ÔH_}T�ÀêP÷ƒñY1;ç€KtóšÕ¾Ê�N”ó£­ÌrÌ.Ù­[·¾}ûjµZ++«&XW� ERRu?§¦¦:99™ÔU§N†¾yóæ°°°Î;çå彯7ó¼yó”JåÅ‹wîÜ9uêT—ˆˆ??¿Ã‡ûí·‘‘‘›6mzôèQIIÉ|pêÔ©«W¯æää|ùå—¾¾¾»vírvv4hÐÈ‘#ãââê”,‹+**FŽ™““³jÕ*ooïÆxɽ½½§NZUUÕµk×E‹Q×uذa …¢IÛh¹¹¹©TªU«VíÝ»÷ðáÃõßBýûï¿O:uõêÕ&Lpvv?~üÛo¿]TTtïÞ=ggçäääÊÊJ’$ÍÏ€N§Û±cÇÊ•+wìØan3}ùå—¿þú+õ!::úÑ£Gl6{Ó¦M}úôùøãÛµkçãããêêºsçÎØØØÈÈÈÓ§O×iOyy9Õ!I’lÕª•ƒƒCqq±R©Ôét¹¹¹R©T"‘�Ðh4T2�&‘~þùç±±±îîîÏÈáÇçÌ™³}ûöU«V]¼xñ¿äձУ€zÀa4øøx€U½và�šýÂÀQ °òK@(ëÕë´ŽÀ1 ÈLS€-08Hë*!T /j‰=Pj6^o½Ôc6`p�K Ñe+à(@,À†.ÜØhÖ°÷k5×Ç&sM(ÁsË£Õ<8èC€u¸N‹}C½,?'êýx°¥ž.h‹ÓèKu­ùßc!,;ÀP)&KQ, ø=R‡g™”üzUÔ¸=P¸…ghÔdü½(±ˆY¤â˜ÿ3Îw0¡ö/ »™[3-�xÔË»ð|æÐ÷üþ›››»nÝ:�³fͪ4;;{ß¾}¯·¢¢ˆ‰‰9vìØ¾}ûëš9sæÌ™3³²²¨¯ÁÁÁl6{èС ,ذaCË–-ë›,æÄÇ×8:"""&NœxñâÅ6†ªÀÉ“'úwï>|øpê¿¿zzºB¡h¼OoýúõÛ·o_±bEHHȳÒ$&&òx<j–~üøñçÏŸ§šºhÑ¢ùó燄„Ô9Ç={ö|ýõ׋/0`@“ä<xðà´´´ÈÈÈ‘#G:tˆÏç×÷ R’Çã­^½ÚÓÓÓ¤NÚ¶mkz¶¥’X°`){hhè… žß†„„„-[¶|üñÇ"‘hóæÍÁÁÁÿ]Õ˜l:�G ‡~ ÈN€�øµ^^_ è\Hà jé;—€A@°hTéf5:à>p�p˜L6+98DÞ€è¤Àà®Y² @VÛÆ¢2R®«C€hœ|L@¤Óç(‚€Û€|ofý\6kªœVuupìÍ4å?Š;Иþ%2ûA.”˜<ñ­€*àÿÎ2ð.Žú7¹¢9C‘t^&ïàêÊ××wÆ Ï:ªR© ‡Îf¿æ†{öìY°`AdddEEÅóSNž<yòäÉŸþù”)Sºté²bÅŠç»I/^ìáá1f̘Æ7æÈ‘#7nÜøüóÏîÃÂÂJJJžoC˜øþûï7lذzõj*DâYTTTÎ;·E‹�FŒñûï¿ÿý÷mÚ´éÚµkÄ;vìX¼xñ×_=lذ¦ÊyéÒ¥999³fÍš2eÊÈ‘#¿ûî»: :tè`Þ!CBBzõêµcÇ___ʶ£œØæÉLÉÿýïÏi€L&[µjU·nÝ&OžÌçó§M›¶eË–ÿ†ºâ× à"TϽFéø¶€¼¡¼B@\Æ÷hu•T>À*�@3@g¦«¨ßn)´u¢�8õæILç$`m¦,™%;UoŽäP œ£›Jz@ ܺ׀S@o@ ¬Þ4«Â‚þÚÈx†ºâ\àXð  äÀÞw±q!*,ÜL@†]ƒ[)BSq§9vwlZu+ÞÄÖíøxt“3þuêêùøøøDEE}ûí·IIIÿûßÿ^ã[™ 狊ŠÚ¹sç‘#Gj9A6l8{öltt4õuõêÕ/^ܺu+‡ÃY½zuzzúóÕÕ÷ßß½{÷&©«3gÎìܹ³A{—²½ê¼=‹¸¸8[[Ûçë*�½{÷ž0aÂøñãU*ÕÀûõëgkk7|øðj͸nß¾=::šÅb™ëª¢¢¢iÓ¦ :ôù§¹hÑ¢{÷îµnÝú믿Öh4?þøãÊ•+_x 'NŒˆˆÈÉÉ9pà@cNyùòåTEƒTVV®Y³†Íf÷îÝ{ìØ±Ó¦MûÏxSiÿÝ€ �hdàÐ63;(œÇ€ 8˜ýN™,r³Ï¦·€p\`-°øH�F`�Ú–úÑ,ûXÀܵ~h´h ¸ ·Ì|ŒQÀ-Ú025UD×Ë€;p6³Lþƒî�0¹©³€\À¦¡ºR€5´JÛDý¤ÃR!¨g_ ð^ã®Q$@Åv¬ë1ûþsBp›jR$� ð.eY�QôˆßŸ€#�èŸôvû±ÖãR±T=‰}í6t¿ÑEW¦ñäCZ\ͱM¾K÷³ô^ä¾€Z‹Qt²Y@KêÖ§»P±Ù9Ž¥ÅJÇk(€‡fÏ%/¥®,,,D"‘é«¥¥¥P(äñx‰„Åb9räƒ> )--¥¢´_c¾ûî»RÏò3fÌØ¶m[xxxHHõ<.$ ŸÏ?~üáÇûöí«T*?û쳞={ ê€-[¶ôíÛ7$$D.—ÇÄÄøûû>|xܸq!!!eeeGŽñöö^¹råŠ+8 ÓévïÞ- “’’f̘Áf³{õê5{ölƒÁššÚ»woµZùÎ;ï�H$B¡@`` ½½½H$>|ø 3nÚ´‰ Ç Nsÿþýuö8îÔ©Ó‚ V¬X±qãF£ÑH…T�8tèÐèÑ£M!é`ß¾}Ÿ|òIëÖ­oݺe*sÓ¦M–––×®]£›X,®y´æó% I’þþþ111ëׯÿæ›o† 6|øðøøx™L¶oß¾:«.$ÉÅ‹©’ù|þ™3g(@óæÍ•J¥i’L$¥§§›°k×.‹%‘Hx<å­5]�A˜uvvÞ°aCtt45ضm[ó°ûÿz Z€�ø€- �"€}€ ð€ÚLýœ €x‰ÀQ ¨¢ãø@gN¿p <¡£~´µÓl@­g•”gØY/†Â%p¸Èì6ÓgYtÞ£ô‡Bº pè ´�ú=#ºä©W‚VHB Æ9oÄ#ê8üm}i.š9'=Aa¡À„íø ÿ[ŒßMÓiç;”ƒœ®W´®éðp#IkÃÛñïXQe6;Bÿ&¾ù rNv…AT[mh€bú³_­æl…žEx©HŽ=´3KŽM×kÒñ*3ý×î9>ôÜUy# '¢×È©û }R\êÊ.=ˆÙâ¶ŽkèáÇ={ödvµø§ æç6oÞlšŸûG ;þük0M{üøñ#F˜ïjAuò .,Y²à�£€#� ”B`FÔM~(»y«YÈ€�+à. Ò€^À6 ? ~&Û^Ô´Þ@P¼¬��Œ Úbs²Ž€/pȪ­Ì&—�`_EÂG@ ”ù€Ð ø.v›Y瀮ÀNóü«W¯¶±±1—êáÇ۵kצM3g©ÉzƒÔÕ’z­j0ÔÂÄ ÃobÓ^Ì™Ma´G”b­®FÓâàl& p&ܪ ]®³-tXHÇ à냸4YÍq§%ð|ÿ0ãYí áN~ðF‚Ü5D£2èï¡}³YÀ�@ 0—>ºå7WWWLevëfcgiiéææf4T¬=x¹ZQ™y÷2³«ÃSt:ÝεnE''§º ÿÎ;׫W/©TúÔ~ãÆìììÿFб€ÀÊ%ð-0蜢î½@  �\ø@6p0BŠ€ãô×úºÊžÎøÔÉM[0wèŒX` n@ (¼N@1àA;÷€XÚ?æ<¡Í,"À•:XŽÀ#��x8øÐi@òGÀθ °¥W½‘YÆç£ÎÓŸÛ¢g§ìR3·×½~çцÀ¼iØÔ•v¸™ )}fÝé¶Í%~Åš-Ä10@ª¦ÂÍgO­ü:Â°Š‹IYžçPGÕ`•Ñ%[ae)Q®A5�#ôئÿècøv|_¿¾\ºU:³È@ÑK÷NF]1Ô¢ÎJòú ËÿfZµjeZðûOa4'NœÈápþ3½À4X¿Ü�Ä€°¥Í) €wè¥T@(0‚¶ºhŸS]œ[ú©ÿ ‘NÃz§v€/�à‰Yö}€-`QãH€L “¶ŠˆÚ57Ì Õ!�°§GO 3­®L%@|CË™ �(ò€’Ú6ås�!SWr³I8¯çŽæÃ ôLÁÚÝ81ŸÌ‚¶ŒåG홼† 2nœÿ:È%t‡�Ø2Ô<*æs Ù9kKF:ÿ6@9n–a:ýˆ1ƒ„�@>Rhu¥ÓAŽõcôöâS`Y*SèV5hA2êê/àÑ£GÉÉÉÿ‘“5í{fîŽ{štåÊ•¼ ÿ¸(þ8æ«¶_ÄH ¨âÒ,&0 Èë€ÎÀ%@jæìí}ºS§f³•ÂÉô:'�zLÏ*ÐËä¹¢Ç}' Hl΀ $@_Úý(�"EÏ8—w£� œ ÌvÊÐÒz«¾Ù4Ø3nα†Öý•Høy.{â£ù¸ÕÚ¦ŒÞAÙøa'á«ÉÏ˨¾‘ÿÉI…¿øf£Æ ¨™˜i¾=ÅŸ£®^ìsuue^²ÌðÚðŒÝWùÀGÀf®¤#€šÞ]‚‚ô"§o5ð ä] `3½&7xBÏñP ³Å¿ÕÀpz¡±iwŒb T`ô(à P ‡.À/�AǧÒøzÀ�,�Œ.šíõ0ø8”½€Ç´ÿM�- ž�:Ý lDÀO�€T ÐfÑ"G�60¡Î<–¹cÐV´lŸ˜)òŸ ÕxãÓåÕU@9=2;Ò ¤@ ì‹A¡#…Bé È9PJ§7GD¯àÕ,ôn•…øUØŠƒ VR1Bo�I5TWg£'°]ôvÆ÷ûÔÁ)î!SØ%5ƒ!Hj…xÒkÉõ<´Â  Äj Ô*Ú¦$ n¨rzºy‡äÑ¡‰Œºj:Ož<ùí·ß90¼6‚Î;×ü~ÜÌÔ•Šû,èÑ6p®’§¦-!Ê4‘3À7ô¬€Íõê*2Ûc}½!l`è5 ÝT ð¨måjtÀ à^@=¨ uX,ÝÔ À è¤O€¾@í't”@+ °›¹±µ…³ó9#ð€¶5Ô´~ ÙXÀˆLÍÓˆ»ô‡™ÀZ�À-¸ ÆT -0 åÀ¼]á‰@�ýù:dbÎIl ÅlÊ[;‰ÒåÕø Ÿ�PC™Q¯“œ«”câHìý!cÉï®+¶pz�x‘á© ×t)iCùæ·˜˜Œ ± c¥6à@K ˜Y¯CÚ—0Ðþ^F]5—>}úÔíÿ‘ôôtooo¹¼þjßKÀj Ù/í»€p¤Õ• px ¸kf.˜cÜ�n�.fêªIt.Ö€ˆÖ7@&­ý!ph <ªg€d\àM ØÌÌ|]ÌÔ € ÀH§õ“�Çè£èÝoëH)¶žpþâ·„ptøøg€Àœ—*¡çC¼ùÂ!ç5x¼bâÏüío=3ûè÷õ^•ãOU"˸(xQ”Ä©VøxÖìŶýùA挺j”? dgx=¸y󦇇dzÿböY k=>ã@ T:`ðsýñ¸47‹R ™-Üü �€¸[¯í£6´�üè A�§èèj`°Ð�mºÞDPEO¹iiõ&€8�GJ ¡Êõ‚X@ºYƒ¹5ðsmáüÅD/ÅK¤ÒÆ6•îÐ%k{>KW•OÙk$Å_­Æ¼®ÏÔ˜in–{ßx²~‘²çUã°­Ps_Péá@Ts1ëþï]F]100üEŒN›Í1Ü7;Ô¸M/¦¶´¸ÚP ù�”š­ˆzÈ€M@P È€€8 ”V-æ¤ÑÛUP;)ØÒQæ&%‘J; pó@u:.�e€�Èd´e–EïüÄÎÐsH•�Ï,6D 1ÓX›€ò†V4×9åû/¦àMïË©ïÁ3ÀNSè_Ô@î©;~³Þ¯·èg+�¾6€Ú[ÇÙPÕ@ë<›¡©®KÆ£ÈBVRÍL|°D9€’ðkùÈboë¡~³Œ\|•ýù"�ÞrQ  �-Ëà@Yþƒ»Ú÷Fé­Ä÷0 €ìE �«õtái \¬ÃGcÍÌn“6Ò/çz& 7@Ø LÉçÈ[¯×ïÛ·ÏÇÇ'$$ÄÕÕõáÇ�V­ZåààðàÁÓ�ÍY³fõîÝ»±ú¾{÷îÝ»ÿoeƒÁpøða‡%K–TWW׎B¡HKK;v¬ƒƒCƒøá‡¼¼¼V­Z…„„´jÕjåÊ•ŒÑÆð*q€ÖUAÀ›�øˆ>tÒl»Û®@k €ÞJG L怪€B@| �Ð` ­{�Ì~@p ^¨·ðiÌž+@Ž6ÔÔèN5†O‡zo�TÀI`4àWŽ'€„Zºm€˜H@>í!T¥€A+?Ó™�Õ@ u½­•†�.À@�ÀÀ‘>džÍ@�dÙ@.àZçÏeF”ëÇ Œ$üÎøF  õG @[m‰§ Ô-ÙÖ>•HûsOr>-.²ƒ/°¤þX®B]/yRéŒB‰\´•úúçØ½ÕøÞIº…FÝâ¾zÒÝŠO%Å”&…k“ÞB‡tƒO¡Ê籞WÑïã»öPÃÚ  -b>ÄX˜J6ûcã’¶Åòýfv¸|©¨�� �IDAT‘©‘&û¬œ–ù_Eí7×4Úº:xðà¼yó¾øâ‹±cÇ.Z´hèС;vì0 Æh49rÄÙÙ¹]»vǧ4PvvöíÛ·ðx¼¾}û¸sçµU¹££cÇŽoܸQVVàÆ ¾‹ïUF¥RMŸ>½_¿~ <qâÄÂ… ÇŽÛ§OŸÑ£GoÛ¶mÕªUwîÜ©yõË/¿lÙ²E£ÑèõúØØØ^½z}÷Ýw6l˜3gN×®]Û·oÏ “ ¯¦ Ú›@`ga¾üîwúCoàG %pÈZ˜íøàMïfÛ0Ò;äj€¶€èAïþgªÑ "à ¬&šã#àâs~GGàÃ{˜ À°n‘ÀC n¤� Ò;áv~<jàÜÑ(²o ðÒ�5=ßFA­í¥Î‘zG‰à"`+ r�;Aí{ÿ<ò�ß'°Q @Ò´ŒÍeXµŽ¸ê±“ëZ#^™xÿV<ǦÔeéœ ÌÜ»­ò‰­o‘•¾†>gˆ‡>V¨à–Š¥§;”À®VÚcÈßÛÕ²ÿŽú£Ç#Õ¢8ñÂid¥ø™-1O$P±á^‚LÛ?K0ÏSWŸþyË–-©·¬.X°`ãÆ«V­¢†×­[·Æ+W®,[¶ì»ï¾;þüõë×gÏž­ÑhÚ·o¿uëÖE‹yyy}úé§þþþ"‘è×_]¾|yyy¹Z­——÷¯SW[¶lñôôܱcÇœ9söîÝÛ¾}û;v�8yòd~~þ”)SÚ¶m»cÇŽˆˆˆ:{­.Z´hõêÕ}úôý–¬¬¬3gμýöÛL|<ëÊÅF¤ùpdtW¹ÙZ+K:€ð<J¯ç= œz�ç�g ¸FoÇ÷ÀÎÐÚ�æ�I8ÖX‡OLËLÓ€7€À% I¯M%€b P…´:´<c€àMïWË|�>pXµ—¾¬gð )P�HWú4«ëí[hee¤--¯z nÑ›Ä×[¼uxû: Â/ú”M.5JùS%ð&Qó ½ýb„ç!é&æ~…”.�äàgC@/RáÓ•Ö;¼è‰¬ÜfjßÌÜu1Mk·¾cr!ï "«ph1ì½Ö„B$qL€t`X?¨Àhñt›ü˜w a¡kjÙ÷»\-kj´ºaÿœ E’z•àÍ}Øì é+ÿeêê9xxxôèÑcëÖ­—/×ìÍœŸŸòäIê=å[·nݳgÏÛo¿}çÎeË–µlÙ288ØÎή[·nß|ó €Aƒýënß-[¶˜^"µgÏž/¿üR(ž>}zΜ9ÏÚ~ÕªU\ËcPYYù¿ÿýO,ÇÄÄ0êŠáU%È|Ñ‹á©!Ûd!É�‘ˆÛ�:Ú´òZ�‡éCÕ@žÙë¡€3P¼ùT |]…Y§jÖç�°‚€û@Œ²6@ rêy(à�dE@��”ѯÿè8{[ h¤�“€$ZC›¿ê~?àô£™”Rt õ¦Üž¥®"hY_]%<OÛíŒ÷Óqåý?{çÅõµñïî²ô*U@°‚"(¢bÁ^£?[°EKì±×˜Äž¨¨±·h,1&¶ØbÅnTP± "H“Þû¶yÿÑÄÔ7…ç³ìN¹3sgöž9çžó<z|z $ËQ_ŒˆÊp5rÖµ °Q´È•ÅÉ•YÌ[©¬Ù䀇y¤§ÕªÑ¸d;$l]XØ<Ôe³Ö·sìý ͨÉi×lϤG+¾P<s¨:óƒŸÚH-ïúuléyîˆÃ@Î÷~ ››ùí|Š3iîËξ”jÀîÀ°ûÿ4WmÚ´yéò   ;wæææê+`™ššþí“>4 ðèÑ£€€€ÔÔT™L¦Ñh®^½:nܸ>ø`Ô¨Q ÅK¨_Ö®]kooßµk×»wïZ­V­V÷ìÙÓÐÐpÍš5¯¯ X üå¸û2¹úî+CsÈ„°J²¥;VƒZp\*~ÕÀ‚4/«Gœžƒ!š€îp¥˜åOPÀȇ¡ÃEAxI•¿*¸¦ € Œ‡½ … H…J’¾í …"ˆ…¦Pƒ¥žØ£~ÅX ±Ðà Ø€5˜ADCõIÊÿ(Üó¤Ê]¬rIy žL­úÛL,[­¤TóöIæ1¢|WW—ȾvÁ@wvhq' ×6i=¯QŽQݯý®>IiñØccëâÐfÙ^ñ!aC…¶Ö“-®{Y}W_ï¡è†\IÏPre´ù–°ŽÈ`òl´¯ÈÐIŒ]PåÏ™+¼¼¼gÏž9;;?~üØÀÀ Tô/""⥢àãÇ9räýû÷MLLJ•ËU*ÕÇœJ²S²²²T*•ƒƒÃ?å¿;hРÔÔÔRBîîÝ»{yy#GŽœ4é•tņ††›6mÚ´i“(¶»víÚÅ‹›˜˜DDDT ‡ø{£|jœS9ön’Œ“ÈÕ$NðdH–,Z¢–øÔ ‚C�,ƒÇ°Ñk Ūç†K� £e؃N`Ñ_³MMøÆ6ƒ„éMž)  Àl ì 2J(Æ €,HcØYn0H¢ÍéÛ_ 2#)ë$ªTª ÀÛÒ. �{ðùÙÑÕRòÉÊË$– ƒBéX)yœÉôGØ`¹Ï*×%jJx(t’K«œ¢5ó>UL™¬{z¸$ç‹Qkfloês0AU]vˆq#êÈ$¡Vl‹uŽïç¬} yÅÅFu·4 ÿðlÔàKšÐ¦5¨]ó‡/"'Œ Z¡È5µ™ÔY–bO¼ Àc/P²È‹…”2ßÓœê/(ÕÌšJ¶ùKž™ÕJ6™sלë•ôèŒÕ?ûàŃE©Þʯ0W{öì<xðرcßyç¥K—0`áÂ…Ë—/öíÛרQ#www///QÞÖÖÖßß?$$dïÞ½sçÎýðÃ}||jÔ¨qêÔ©k×®­_¿~Á‚Ý»wã7öîÝ»cÇ¿Õ÷ïDDDÄÞ½{33³nݺ½°vøðáÇnÞ¼Ù±cDZcÇ?~<44TÜèØ±£­­mÅÐX¿1¬$f(,‡b¨ ù§7Ž×‡ë` R²{©D©!Ô…ÝzóCÎ0ìÈ%4X¨Mà6$Âh°’3 îkËð¸×…»PKJdm•³TÞëþ° ÚCd%œ„§¢«'g¹Ž£p Tà[–!^ bºÓH#è*éü¿Ö;èm0Gx~pbá xE×ÙCs�  ö«{ØQO+¤£Tý•8gÄwöèù �Iä‹¶TW%\µü¾o ‹ /qhƒÀìOÓð˜3©~ܬdÙË §>¬Í¨Õäø0~3+ÜÌ2Ìȵ2±9H‡/½špõæé‰Mµò9Våáçõb>鈴,¼¾úkyÜ{²ˆZòceiRÒÄÌ·4 æÉeôߦÞ8š—3g"yW^Ö¾Ð,ôD~+ ,úÕæÊÂÂbÕªUHMM:tèÈ‘#V­Z}òÉ' ؽ{÷’%K:wî,JNT«VmùòågÏžMMM:uª8L/]ºôþýû‚ ,^¼¸k×®Àœ9s¬­­=<<ÄÔÁ  ЪU«ÒŸC† éСƒø=55SH€wÞy§~ýú/ìîêêúÉ'Ÿ4kÖÌÑѱC‡â.€Z­®+ðwÂû°©ìX€!œ…¶pL$ÛÓQ*+>-9d©Pzå´æpŒÀ_*výRyž&½qH‰æ†PWtÜz>9t¿2™¶Rݱ ˜Am‡¶’­ª!’ÚÓE˜7` œ”˜ÔÓdœ‡Æ¡²(“1" }EKxµ¬¾­Œ% $@"$¾Ú\ýɨ”OÐ^¬ u+ñ~߃ p`O:¾°md Ƭ$¸%c¶²ìÓ—·ç¿²™•:Çæ‹ýÆ53Ý_0È1ñ<#³¡¡®íyí¤U²\ Å¢)%–cÖ|íôÏuæö|øëg ,fL«?ûŠaîÊÕÕuìØ±úK5j$&¾°¨[·nݺuõ—´k×®]»v/lV~Ç¿?D[[Š·ß~ûU[vîܹ¼%vrr¯º¼%«@þN¸]nI†$ô5¡:˜HKï—eÁ@Š’åK!A$3c $su¥ÄC( 'ƒ’¥Ùø¯  ùpû¶ÇüùÞpoÝ:F:] :„ë‘Ø¦èUêdÂx�÷ :4Ó´l–ª¾ÊSC©àG¸m%º©Raûh‰†µ1Ü€]zÁ±z9&ÿOؽ«B%ÂàsXVŽ€,+|ÅFŒ_ÃÇA(_ý’Üz}™RµoÅ5_—ÍA÷{~«âV]Óë¸Å©w—ï}GñU  ør¤ðÞ6tqx(ê$&–«YêÀG?r§3D‰éïeµØ°aChhè‘#G*þè¨À??Ÿð JH#úÙ°¥Y¶Æ”ŸúJê½ ± ¦ l8'‰tÜ�C8 =zVÚ·G£¹fbbVX¸°E‹U?HÉܑҖ*y{ È…0€à ·á¶t2ñ df ápr¡3ì€cz€-¡XŠË=-{D¤…¿ˆ%f[ýLƒ$ÉË”0S¼£`(ô/bUäsþÙ�±ÆVgªcÿ*œ³hÛ…ôå˜Áø÷Û/DÓ0[ ëŸ{OË3¡ùb]J-ÆD²À³•%þ¡eQŽyAàZ_ënÉ¥)¾ÖnÓ~eP4kýÖêE.6'ý…¢¢¯|Û7h¯¸fõ=‘Ñ{¶p >¹ra“ O’÷”Öã¹¾¹Ž©½•Åme8�:"5÷ N" ýº½‰Ù|)b%Ÿ˜#Éžý æjĈ#FŒøwÿƒóòòÒÓÓ+F² ü ðKñçþ/Sþµ¤ÏkÆÐ ¾‘¦Rl¡’D»n ÷ ¡\;¥ƒÑw`™ÀMˆg` [a�d‚l„ŽúÁº˜vî,ž=ûجYrÉ&‰ÅÒÀl@)ùºB PÂ[02àÁ$˜ÐîC$COh7`&,kp‡'` 1p>…*Ð*•åóµGHx ±«Bž'’ µ‘›? pÍs!.ÈpIbý*gã?“¢TÉdX`”\’ž ÇX†06PeUKï;™ÔªŒ‰dÅm0»s%/ÒÉ u�ùZªŸ;ÕŒ[Ë3Õ{>«=`®óñz¦Ò•*4Èâí¾¬šûE—ÙßXЉE ­¦pp-À¼Ö²,SéiÛUðÓ+ä³”zà¹ûWöa3ÿ³ÌÕ999¥9¨À?nnnrùKÓŽ«AØ–PYr,Ä ˜#Ô€KÖ`'M™Ac°sH5ØCc¨®GÁ'¦§‹¦Îò`L‡DH…jðŒ+2ÆéX1ðjë×{EGãçG­Z¥Gt‡P ¼@¡§²Ä€Vrž  )¨ nPIOÕÞ $ºÛÙð>…ŽÞ•á2S¨!™+±7šC�| ¨óòèÛŸ×$VÌÇ<ž·GQ¤¤*^V(ôЕ÷Gs«:cϰ"ã×ÇyU/w ¶/2~ŒËáª/®þ¤+³¶Ó÷ß4˜ñ6ÁHÃ!¬Û¥›¿V>ýS %{<2°±?—Aù—ÿõHNN622ú\¬B¡ð÷÷¯¸éÿUK€·ÊNG‰Q,}™]xC6<eíZhÑ -ô¶©ïHnÐ æ*ž‚ „h°„†` µ%ž§FpzI£æga£fwó;Ñ(Àç¬]nÍ ¸e÷†sÐB"t[°”¦¸Þ*w±•ÁîB>Ô‘Êxg0ñÅÀ}(O€ºp_êHx IÐCoþ쥨 �h¤ô÷—"fIßIiŠÏ`$Ãzð•k3Áóž`›Ç覺§'±ƒµéÈêò¡ïsBGhÉE Ó«åžøtŸÎ›ñÁ,:&c´$çaî‡%€F†V .ÆñIÉZûhŠÔ@ÛsçÝöWt,˜·vMU£ŽÍ¾unÐXTtTPÓ`Á'ÂÄú÷Â[,ðÓŒ[‚±šÑ´[v Ó2îS3ðX7ž‘‡Y?€+R©x)r+ÌÕKKKOOÏÿÈÅÊd²ÒÇ üÇ Áà9’uAòKÄ‘7r ~‚tJç Y Öp ”ÐGrªÄD 7¨ pWª1Ú£w81xø6t&�´“Âtâf¡ ˆÝ³sTÜ4Œª‘ÍžƒÐTòíöKGl á˲Ñ9+h7! ÂÁ†ÂE½S]^®:³~4«Ë•G§C}(–zÃTZ"Ú½ºK@¤ó.þYs•;¥ïó$JˆƒRvûñRs%·)ÒÜo0|6jó=Èk8Œ§eŠa¼xàh³øÀa]ýôqÁ|| c5Jc>ÒÔ‘Lš“ËÅ] ZÖˆE«|²Ã|¢ÃÔßâyÛô›êR»Æ7ü¡²\¢Ž”QYGk‡ì`àMÅΨ5š-~ •ï¬ÔžƒNÍ„yàp¼;+C%sµ£ì P…wõÇÁÄÄÄÖÖö¿0ˆ·iÓF§ÓUÜôÿ*Ì!\¡C1¼'%Pœ“¦Žò¥"¤£LââVƒ оb0ƒšRõŒFå˨*-P]G ´†«p‚á;¨ ž _%E9ðÀ%Ž‹@f²%}á6\s(„‡P®Â X“¥‘ýL…; ™r8 ]  äÂG HæÍ&B.ü@n'ˆOèߨµNŠ ÊA§G{Qâ%Oîχ}®fËûÊ{È3/1…ZxÓŒü 7óìŠ7Ÿ?˜R+{äI£¥'‹Dհߥ†&7•y‡k}ûñe‘B8S6k$ßT±i˜vÂj]ïòƒo’kÌ—m˜~‚Â<p¡ ÓgoJŒ ;{1gŸŽ«þéá_jµú¿p™x5ÚB0ÄC<¼ ¡° ªÂS)²'NÞˆ+{Ĺ¢7àkðk¨·!¿lªECp֣ȫ ‘ZÖ*°‘ÑV ŒÀÚA\- ²uüß¦ÍÆÀ˜Ýà[)|0|ƒá<+ à x@,Ð;º¨º$z~û œ .<€—á� $I,·÷¤ ¡ZA0äèÕ;’zà×z±b /eµˆ—¸¬J-•`OÇL¼ 4L—w¼ã™T7M)r{¡õB¸M;åÕή½ºã›› ÚÐÉôd;̤\IV*ÿùá”)( ª¦Ó(0L,®2i†Ýö·óøÉâ´?`KºÙ@Ê(céí¼ù~TðÉaÑL÷é2”ÝKX àã6d)‰3 ^•#I,í1Ç—±W<–èB~¹:pà@zzºXí ìÛ·¯°°pðàÁúÛDDDœ8q¢[·nÕªU«ø¯ÿ!HOOßµ«dšzÈ!–––}R¿ úå(âChn €âa4 ÕÛà3¨w!´`ßC]¨yPOŠž5©ñzPšÂF0ùßÛ·ƒÏVËÈ^#ÅÖj ¸ î œæònU.:]D·CÜë F` ™w@ 1"ý-l†¦p§3o4\ÊV`îpêƒ à€tÄòxæC-¸®#ÜÆàú² ÀWެå–XB©Ï1¿ÜÉ›QÏ”^ÏX:UÕÒhÝëòñUz¡¡‚:1OÖ¬ÌmòÀyMO»‰ãÃkÿð?Õ�• JµH\À�W+«TÏ©¤ÌKŠØzœ¥ý-Àúrv‹“—©;éšÕiOÀƒ r(œ‚ñaþݤÍF”È«gØ“Æð|�ÿÛŠåV²ì¸¾3KÏ‘XÚWÍ K¹Þø@ã—öÝ+å·oß¾tés*­M›6­X±â…mÂÂÂæÍ›'Ê6VàÁ˜1c~øá‡ï¾ûîgØ+P¿ÅpT’wõTZÞl@+ Ó ‚s ‚lèFz3Iù’ "Pí šƒwVÖ$¶ØË™!Ǿƒ•ðÔ„@0%UàƒbNä³»{:8 5¡+<ŽP h�ïAHp 2`ªd«KEÄjè�€äƒ¨!E"àPAã—½ÔC(*ÇtW�ju~‰ïwÃÿÖDV}~de!Ê—×|ßHƒ KóÐZj»ì?ãD4¶9¯\g›Yö§�v„OÁÄR)ŸÛU~Ï ¼Ò\‰ÆiâĉÀ²eË<x°}ûöË—/·– ¿q¿~ýF¬^½ºuëÖ™™™!!!¥[Vhæ¾>f̘±yóæ~ýú¹¸¸?~¼¢C*ð7@iþÿì‚¶yPΰÞ¨ ýᜃ@x�þÐ�îILb¨§�.Ãy>w.9'ïè%°_(É�ý¡ì†Ëä½Ï¹D¸9R�y°¾…"¸ž ÁpnÁlð‘´¿—< ;¸Ðrà¤Ã=p€Á0[¶H„`)ÒøBlª&ÄA&(%ç²ÀUøŸ,t 3.IøK„#Á.Šc«0yÑLÚœð7 ws^Ý+' ìÑW ÿسüßuz…µ˜ÏÙæÏ®‡£�Ôh�îYìß@ƒ¸ßy¯ V¯^ˆŠŠâãã ÌÍÍG8bĈV­ZµjÕªTÉ)<<\”ÃxöìÙÝ»w“’’:uê4lذ ¼ñÆ-Z´ip+ð‹¨W¯Þ©S§ú÷ï·sçΊ©À_ C! „ë0 N€­ÄÈwƒÞ‘‡ì\È…l) #6ACpƒc° žÁ+ÜÔPú@$¤Á?†©°–BH0“á2„hz}ƒ7t„p@âθ!’À là 8A:DZÑԒϸ¯c%4KÐ ¬á)„C܉ }‡$ \úÃ>È„{0F/Ë\&垈…8èZ®îp†÷^ÖÃ_K¼·Û@$ïKƒQÒÚRŸi2Œ†7e6L·ÓfU–UÍÑÜÒ âú‘ì §ZZ¥µ¼$ciO*™ä§Ë-5é|g¾õÉ5ã³ £M¬3e2[Át¤”—_åÆ"U]‰@ÄB¯Á£dϺV�u“3‡žß‹ 9|7NM2p”·á –¹ŠÅså';ËϾUL*Ö¹¬˜/ke8+Fh{W=;¹@·í\ÂþÎÌùäð…t¬C/SüÒþï hÛ¶mé÷V­ZU©RåÀ®®®GÍÍÍÕj_Ù® Z­öéÓ§GÍÊÊÅ¢*ðšèرãåË—[´h1pàÀŠÞ¨À_ l†¸À:ˆ†ãRB˜�@#Àª‚IBS¥c‚<¡�ºÂiˆƒ·ÁZB𜃹ÐZÁèµAZh Ca•Œý®Îýêy#'JÎØO¡ Œ„2ÈPÀxšÃh ËĹ™lãØ c>tµpæÁq�kþ •lp …‹’äGèÀ¬@»À\ô˜ì¡Ò¯]`� (;FkËŽÔrÑ—a�(NÕ~°Y°•j}µrú|À¸3²€'2dâG\Sse×'½CUV…;MºPÃeú2uª€¡äƒ�:ÐIWn¨LJm—>2y±LØoº®ÝBið9‚ A†�èë¬òÔŸ|¦kyY–à‚ è}ß{ÝöËò¬tm®²«ßw¡õuv÷fÔBt IWéqÒ–ûü¦` ðÙgŸÅÄÄ,^¼øöíÛsæÌ),,œ5kÖÆÃÃÃ_'±;###<<üwÞㄨ@þöhóŠŸõË:!àJi¡8ŒþOî¯~„È€<øÖA(¤ƒ%¼ ’+¶‚$ÂuPC†"Ø-РÑýûÓ»·“£Ã(¨ÃA€(ÁIÙà"Œ2Ë‘¦M6€¬Ô;ó –X£ \-{É[$WR„è�YJDì†`– RØA)¿îOÀ—ƒ~níôžngµ¿õb`lO“¨×,;ö{¿Ý£:º™Ÿ«óÍ~ãñqšQXÃhÚß{ÉZÍâÙºvç FÉnú¸&âšÈÈE„Õ¬rt»åÇ;,\ÂÌ©Hü\"»¥¥eÿþý/^<lذ5jdggÿý÷“&Mš6mÚáÃ/!g >yò9'J£F¦M›6þü 5Â×Ç Aƒš6m:zô芮¨Àÿ’ËþÌnp2õè_EsU(ñÉŠá¬>Pµ,¡{¤Á}ð„w`¯´£(œ(æ¿}ßB<ÔV0\Ç,)0_*íD�ïÙóø¼yþ‰)~pª@w­À@?É1Ô½¡�4pR —$fŸèûÀü )œC0‡4èF/‹Ju€È€š` áð.J³b"Š!b¥Ô‚×Á É™³„‘�äêqV•â ÓÃðA·>QÍ@˜?Ž0º'P’Ñ—eZêùåJáS,/Õ‹/É÷£ÙÞšß„íë³ –a¨eøu¯=ãïé,„½¥ÊšoÝÁÎÀ1'qd6Ñ£6®,…g¶ŽÇûsêµL¿[Ò¶ä9‘ôhÅzƒ.‡íß™ûì'–`ŒÕÌYȆ8Bµ¤°â8ÑÖÂÉhz_`–”÷/¾Ö¼@c‘R¶W“¹222jÞ¼¹¡¡aƒ lllÌÍÍW®\¹hÑ¢'N,\¸000pþüù†††r¹ü›o¾éÔ©ÓÉ“'é|�� �IDATlmmׯ_?wîÜ .ÄÇÇ—Ê Wà8zôè]»v%&&~óÍ7R¿Ëþ¼-•@•JÁŠ!#Þ–¢0ü1”6ð…´å8Xžàg¤e`�&0¶€¯…€ š�дà_Íõ­/¿¨Ñ(@¦TÖ‡90La‰ŽvpI ¦ÀV0„}pTFe|ȇ“ R’}̇ŸÀBÄ#œ†]° D… W°ƒî ƒB„½’Ôd?¸&Ð Ôð¢¡PO»ä5QJ¯Þ^ÊòH{ÙÀA“‚€:‘fãb#‚,QÖGý<Šh}ÆÏüpz‘{²åe!G()z1¦hTŸÖßîû¶OŸÞÕô o°í»nO™±u Z¨—RR]f¦¥„ÀÈçL>`¤E·€++yxŠj,õn¾èºä(ZŸóiµ*'ÆTG,J-߯`Dq@¼Néß:NdPwâ¹C©¬R­rWýxW@Ë–-““K^¸”JåàÁƒKK¯ââʤyÄÄĈ_V¯^ ôíÛ·oß¾ÿþ_‹N:EFFVôCþÐIU«¥¨ .e9ßÎJ_–`û ª‚ü7  ¼·!: H�ch »öC t—äzßU2Y%|÷í·½ÓÓ*ÅDW™>m[ß~2b帪±“ábÁá"Žk¸$c½‚l¦´É`#Á(Ø c@K¡�BÀ‚¤ÚRJµÿt¬lè ?€ XC°”én y‡âØ*ƒ\0ƒ þÛI#~óa[9j½7Æs<ˆÏë[ù&Õ¦Žzº`Sz·+îQº¼R¬yR¬t÷<“—^­Ç~nÍÎŽ‘«Va÷KGÎGµ˜¿âÒ):4.Ii)ƒ<§¼ðy_Öyg¾QŒäà’ÅîM˜äSjŽ‘äI¼ 6\bx«E*P×(!ƒÄ—ÛÀ Üc¸-ÕiÝ’Ø"®CehÏ €;0nI2¾¾ ªã“Ï-ðСJJh<eÒ»3f®Òñl@¿/a%±Uh™Ê’ ЬˆWÓÜ€U†˜r?Ãb  ÔJ‡;”8[oµ”=á …`«$n O ~‚ÇPõ¡¾”o*x Eà ð�òaxÁp(/0T�]…BÊÔG)µ‚¹‚’¤*-q ¢ZCâêHRZ8lFàbI‘ @‰"™l“Y}ž|¶ÅAfn{¨PˆIަ’2¦òÑÙ¡íß÷ºw²oÉžÎ9ÆÅ, Á^¼u…¤‰ŽH©þ”Æ´h‰QÖ7º[r«5.Άlže—2üå›êÍpËÕn¯™ý$,›°<e£oË4.²·Fjéà•‘·] ÃFǵõŠÊ#Uï{·RŽÄ sU Tàçß_[é9Lú0®Òd•‘˜¥%£¾ŒJ:Îyàm𸠵@& fi9—¡| át€\0Wh•ጩrÎÂu9îV¨sðСÓQ,£¦[+Ü Õ€d925B•‹05ÅÁ„ø$òÁP†ÀOP�ç Ô…|¸ÛË^H±4ôëÉk]†TI†J ÖÒZ´däÄXXø‚ƒTàõ�"^6w•$se�C^Õã2ì Ø(9³G§VïàÊ›„Ž‘Ú¹&ù5Í8ۙ‡üœÈÒÉ{ ³Ùo%¥N15ë°«c6V»ùÚùþð’,³Åìª,[¿­{v±–m30Tƒw¾Y�–ж$½`Au¾R²©Ž‰Ñ¤G„!ÞÞUÃ87ãŠaŠ•ÓY¯”ë—"ØÈx*TïÈ?˜%Ku,Éê€ââpƒ¼¶`ª%TC�\„ö¯Õëø•Ž¯R¿¬0W¿ŒÇÿ˜;*$(+�:(‚ _ØÕà=Ø&±‹(™Oð†ê¥' _   „á’€±Ä“ô-$Ch »¡>|ÁÃ% · ñ‡ÆYjL´\1ÆÔ µ3)µ‰(¢–é|Uƒ*ì2IÒb˜r5\ƒGà߇ð|!6ƒ?ˆu÷5à;)¸× @œ¶8H‰‚Ñ’• „¯²Y$I¿~Êêµa—‡™Š½/c!*0ázºâ_ù•g¼uÕa—ÈåˆM¸ƒM¸ã“a5ú�N±†“Ç»ªŒ„Ý]sä:v¾,SïcGV™p¼€&eóɾÁúAô?Hõ u.xw¹PÙGyÐ�YTµ’yz Ö‹SÁ÷ŽÖéÊLÖµ¦HY ü+ ÕjÝÝÝ+W®ü_¸X¥R©R©þŠAQ§û%YÛär¹R©üÛŸ¦1Ãu0AŠé½ŸItyÝ!Äê5 Gô¤­Ã!¸.©>3 t\ñLd(è©¡|&§· 3µLÖ2 ÞpË#Ì”FDå’W1ÆõËÃ6 Õ(“É—‘¾ H¹ÇO:ˈע€] Ö° A-8�†`'e…‚bÉô®5|%…ïDß+:B‚Óe3Dºú#¯sÏÁ\*+ôø2Œ¥Š+µÔor½ö øq9?Ô"ÊêåžØ%ê?Ô 8¢ÙÝ00ê·œ¶¾%W)Ÿý®êê†ZÙæF)ÖÙÕ2ÕJ Ô…˜XǘÌéo>ù@TŸ£éƒç­=TdR(€¦X·Âžz©Ü/ ² @C‘™ º½¥èR`¸föéÜI¨©Bc%gtw—eV«ºäæ:Ï<ùVÙ¥BÈlc“4ÌŠ ¯ŒVþÚaŽeW…¹ú•xöì™~vþ¿ …¢]»vÁbbbBCC-,,þ#keeõOн|ÎB6(AY €ÏÅ€¨ ª‚7˜Â)0„ÊPdpºA0D) 48!íX àÔ„N[4øA¼ _ƒ‡Žýà•dlx"ÇÚ„bðªLv:ö ÜœyV¨|LÕàBv:ç2ÙÜ„iw1²çN$9NÔˆ&BÀfWGˆà+tˆ‡ISÊŠÀêÁIÈ„!eC…}áK°€c`"•ˆÝ‚g'ÑÕ¿jé5[�µ¥ï“¤ïD,»bIGŠFó9™Ë!pZo—RIVl¬ÕZƘšÆãX“Õ¬¤ ÔÅ:ä4¿ÿض’2½*ÀÎzÑ+Wg·*iø”ªbdѳ-£÷¬°?çýAÝSÖhlSjkÕ)U‚K.=A9¦„ú°fÝnÑŠ]½¾§§hÏCi EdÕÑp4‚`]fŸbÒ�9B•†›¦s;+³xiAI�³ý¯Û@+Iz¦Â\ýJT©R¥cÇŽ?Cáñ¯A||¼««kaaá_s8ooï üäµ¢££kÕª•››û·?ÓR²p;0€,hõá(h öB3p…&P .B+0€0È7ð‚{ÙÐ,àKðƒïà#8îp� À žÉ™$°KÎQ~J®šaïNÍœ¼‰õ$þ\H£ö]ªU'˘9Ö†bïJx4ÉæÔR`Ïà<ô“Së 4ÔgÐ,!là48ÃI¨iemÒO± ¨ ¬ƒVЪÃù?2Ëí¥ØÆ/ŠÄËîøWÇdY²ã «¬Ï4Ìj’f{XT1ÆòR½¼†¬¯ÔѧŒ÷3<bÊáÔÂÊû†=è¿Ñòà{ùÕ <°³7ɶ<u£R‚ród³š/§ù›ó׫1tHéA©Ííý£ù­-öwÊ|žEù£Â\ý24Í¥÷öíÛvvv¿§…k×®íÛ·øä“OÌÍÍq{•Jõ_ ^¿~½V­Zÿ¨S~¢çœ.«ýZÒLx6<o¸�FÐöÃ-°7á.„KM‰B$Þð$ÃM˜k Àh硉 XØÒ1ët \x…V@fMf nñ®ÃCCd âpÕŸK¡):C¢2i`‚à@ëtÅD 78YP,Ñé ò¡4…T «^U²>Zèy„éòšÏsþX »Ä–¬_2žo¥yw¯P5¦¼¹*»ý­ÃNO¬¼½“¾¹2L·¨¾¾“fÐ.™ÀšÙ™Moɇ^çPN´¤ÎjÄ0yù¹†…Š—¶™ùÆõ¼»vl쪿P0Tåö:Uy¨$3foÀ·?“bRa®*ðÿ‡ððð#GŽôíÛwúôéC† Ù¿EŸüó!JOµ—ÒŠàCºÄßš&Íʨa%ÄC{x á¸%™«s5À >ƒ÷á‘Ä7x*à JõŒ©–ÄâBF T®B¤… 2°%Íz%jÙ÷´¯ÃŠÌqM#7‹(s¢m×Õ<Ôávà !ð à-˜­`lƒfðÌ@w_qí¥” 1±í¾äZE½^×ÀvÙ •R²¥†åBɲ–iÐU}O»’ Ær¬8 K¥hŸ‰ @Xâ­ûd¡lذ¬B§‡ÔÑo¦hã´ŒY ãoZòÌJŽ«u‹'¬»4ïQÿ/¤ßB†OQl­Ÿ4}zÁ¹·Òï(wìd|´µÑ—ÍÝïÆ ApKëA@…Yv‰,é§ú &ÅÅgk¯nE†8Ô^B/¹c6%358(æ1&Ð�¦”š++IÒEt!SÛãøs3`~~~"""ÜÝÝ—-[$''׬YsÞ¼yÀ°aêV­*n#¾\ÿ Óéâãã—/_îîî*.\³f»»»¿¿@@€Ø9¥Ø»w¯»»{Æ Æ———7f̘Æ7iÒäÝwßÍÉy.$SPP0gÎ??¿fÍšuéÒ%333++«gÏžM›6mذá”)Sòó_’•táÂww÷5kÖ¤§§7oÞ< À××wùòåÅÅÅ<—×É“'ÿ$É`•J¥R©êÖ­{ôèÑmÛ¶ý-çææ>Üßßßßßøðá¹¹¹Ó¦MŸ7___ww÷Ë—/?õËÌŒ÷ôô6l˜¸dàÀâÆÞÞÞîîîúåí©©©~~~õë×_·nJ¥ºy󦧧g@@@:u.\¸ ½{÷Û©[·®»»{ZZÚåË—ÝÝÝ}}}z÷îý¯x®7ê}·�9ÄÁ0ƒJ` ùæRf]d‚9Œ‚$h¹xqqDDvXØü°°ÕÓ¦‰;€: ÃHOÀ>5ä¨9G !\vàf>2‚jU"߉¤"Ì3¨.G‡«1EáÔÎÁr ȺGo¬M)(F¦ ùI( Ñèø¢eœ„\è Àlð†Nð#Èa웄“DØQ©Tq×ÚA2L…Q Òãb/’ò×Zˆ…›pîÈi&~däA¤DE¯Ë"æw#Ò¡$â‡BŽRŽR†FÚ>R EGŠŽ!ÒB0MÒU~¬&/ ý:¦f¡BÈqMÈ¡0! ݽz¹…éªt,ÒÑf'~Šã ¦NKtôÚßVm¿Æeá�ÇË5òªG©«E©«…éê\Ç÷:¾wŒkÄ»éb>_Ö=Û4+ç­áÅ ;’Z;QA&öqTŠÖuÈ/$¤¹8@*X¡2@¥�%Ô”>†Šw•——W§NC‡JêbbbrrrŠŠŠÂÂÂ{ôè1þüÈÈÈØØØÆûí·ÿˆ¿£V«={ö,àéé™ššš——÷‚v×ë¡“&MŠÍÉÉg¶RSS<xàîîþõ×_»¹¹•FØ2226lxûöíÊ•+oÞ¼ÙÛÛX¿~ý®]»N:eooïëë4gΜ«W¯Š†ðÑ£G7nôòòrqqùøãMMMÏ;ñðáÃîÝ»ûøø T†ûòêÕ«‹/ÎÉÉQ©TcÇŽ‰‰IHH8{öìúõë;uêÔ³gOñ>Ž?¾_¿~ ¦¦<)g½zõ|||æÌ™Ó¥K—ßÖ¥¯ÂéÓ§srröïߟ——'Ý%K–�ÙÙÙ‹-:þ¼•••J¥ vss;þü™3gÒÓÓK'áD–¤¤¤™3gFGGeggÿôÓOžžžcÇŽÍËË Y¿~ýŒ37nܽ{÷Ö­[ïÞ½{øðáÝ»wÏÌ|Îé ú‹ S§NMNNáúõëÖÖÖË—/ÿkòSþ|�€ È¡œ”(É[A7(€Åàõ†ŽÐv‚Ÿ5jÒ™3›$^¸Vp_TŒ‡&`$ä7lxÆÅ.)ödõ0ª[1& # –èêò8 ë;ÔoÆÕLl*‘QhòK4®…ª6UˆË&ó)md>$Gc’M -Z³[AÇ|³HÍrð à‰¹i[!&¨ -á,§Âñ1 –$Ò�0„"©òì0†–_ŽžêÆš¶L=É;9¼¦jPÙ¶5•¸U>¨8ˆ ‹1Ðq¥¦¸@Ùk¯jÉG ãÁ¦ÆÍc­­­KG'‡îëlp1,+C•0è;M÷sŠU£ &/*f”“×ðLfìú'ORZiïÃÎá@BÝþß‚7nÜ8uêT«V­>ÿüs`Ïž=7oÞ?~|PPPݺu;tèð7ÿ;nÙ²eÅŠÞÞÞíÛ·?~ü¸ŸŸßo[­¬¬öíÛ'sâ’›7oîÙ³§W¯^°µµ –.]|èС 6¼ñÆgΜ¹zõêûï¿ïëë[·nÝo¾ùÆÌ̬zõêÍ›7&Ož \¾|9 �ظq£““SûöíE3ö3˜<yò¦M›Ä½JÑ®]»¿rMJJJJJ²²²úè£Þ{ï½ &üNuÿþýÑ£G+•Ê·ß~ûí·ßfÍšåééÙ¸qIIÊãÇ7lذhÑ"ooïÔÔÔ>}úŒ9rÑ¢E#FŒpqqy¡ÁË—/8p`÷îÝ7oÞìÓ§Ï¢E‹~É9sæØ±câ;ܧŸ~Ú´iÓ°°°°°0ñTÿ-FË ¤Ì [h ÷@ÖÐŒ J”Á²A E"Cnß¾76T·nqæL2A8˜È©- °²·?=thÜ<øÑ™3&œnÄ©š‘`‡³ 9JÔîÄdc%C0¥ G9ºTì-I/@Y—5æupzFš •YæØæc¦!&Ÿ s´æ|˜Ï*µe¤éê„ÑÅ ã9bÏàŒ‡ öB?S;ð,‘g€|ÁP"Œo éð[äúdÔ–ó‘äj•Äâ^-Q¸´3¼wŒ­-t% aäÂ¥O±ôÅ\ùèaâEC³*&ÙÏåí;“yûu–w´'êò,×eýóîËúîáòå®_i¨VÓ¤©|íúÀÛ{Š@&æ ‚ŒKÒëÓéBÕdÒóåo}&€–û <KbKÄ b¸N"}w³¶I·JγýCÚÆ0FÂ]NÆA˜B«r\ jHqÑk€¹zôèш#€éÓ§ËåràâÅ‹¢sPbã{ôðôô¢¢¢¦M›¶lÙ²¿ù›æ–-[V¯^]½zõÝ»w¿ùæ›C† ù£Z®_¿þ† ÄïS§N-**>|øèÑ£{õêU­ZµÒU³gÏÎËË«_¿~aa¡­­­¥¥eQQ‘˜66wîÜÒÖÖ®]ûÅ_lذ¡C‡UªT9þü”)S²³_¢i½yóæÒÀWi\N¼k}ûöm×®Ýܹs?ûì³#Fü©"™ñññ AAAmÚ´ùè£~§¹:räÈŽ;ÞÿýRðÉ'Ÿ:thóæÍM›6Š‹‹—,YÒ¢E ñy³°°Ø°aë26oÞÜ£Gúõëâíðõõ-¯×<wîÜU«V1âÆåÛ‰ŽŽþúë¯ûôéãéé)Q\¾xñâÄÄÄÅ‹ÿ[ÌÕSéËÛp²$m{#¨   XKÛÜ‹4¤Ã ÒÓ/>{8gg»´ƒ;`%à2zôOM›³¶¦k×´m;'(É‘á§"à r +‘Y„q%2ò1½à½/O–Öå¡9yw°Ñ"—a G›ŠƒE…(ÌÐÈái!K AN˜ÀYŽvO×gXðT¢gš4ˆÔëa _Àˆ¼SØ.²°æÃ=9+ÿצc(o®êð!�ùż^ÓŠŒT2ZЭÓ!>]Õ`†´ú#Ég5W2ÌŒ6½wÂDcrÕWÏ\9£²cÅaø^pŒ“­•h«EZìi©¹ÌŸ£ÉÏgÚLÀ„ÐÞ”hg½‰*1WGXvˆY=„­š*Œè/š 5ùÙ¸f2t';"y�ÁjÚDÐÔ˜5jf<ã(œØâ;MysUºˆ¬?Æ\¹ººŽ3pttLMMg‡ òÓO?>>>>>>¢o±dÉ’ˆˆˆ¿¹¹200]ÀüüüV­ZÿQ-;;;÷é#þ!1bĵk׆Þ¢E‰LgéªÙ³gŸ?ÞÄÄ$**ªC‡ööö³fÍ ëÑ£GçÎ%¤Å›6mZ²dÉ–-[ÄSmРÁîݻŰÕùóçõºsçN…BÑ¿Q÷¹ôÇŒóÃ?Œ3fçÎýúõ‡é¥K—êoö'¡M›6¿§Woݺ5qâÄ„„ S§N-[¶\´hÑüùóׯ_áÂ…Rƒ¤ÕjOŸ>=hÐ ÀØØ¸´‡Ë#;;ûÚµksæÌqvvlmm_µñСCEO7###66ö…µééé7nÜèÙ³§£££þ=Ý´iÓ‰'þEæªdÖ®@¶ÞP$i^„Á˜XúZ«e+L�38uúôý3gÌ  ÄAœƒ$h,ÐóúÑ¡W>u®¹³k× ÒËÖ„ä„Z:ŠA¦cb5Ö#A…Òˆb'’L)¬N”#6¦téÈ#[ÒÑC‹¼ qWñ¨Ob4NÖ˜$a(ð¾—4ä:&À‘P ´4-ÀÂEwåc²íà0+™¹7…&ªŸAž©Gì»á¯îõíÍ|•a—Øò£Y¼£õ†zió×(R+Y­Ìº´JlêÏ´u,^Dû]d`îf"‰Œü Ò}ÜñuÞî&¼9Ž{Î?·éº]Œ©GŒDÉí“ÀÛ¡|Ö…ÏÂÙþŒ«Âèýó«ÍÌÌDkT {{û•+Wúûû:thëÖ­+V¬¸uëÖ?å/¨Óébcc­¬¬”Jezzzqqqjjª««ëïoùĉ7nìÙ³§þ{}AAANNNçÎ,X :=¯|§}ú ™>}úŽ;J#«)))jµÚËËK*åñãǦ¦¦Z­vÓ¦M›7oSí7lØPXX(—Ë}||BCCóóócbblll\]]+Uªô§ömVVVfff~~þïÑöóó;wîÜ„ ¾þúëãÇ›™™­X±"((HßV‰}ell,š Ñz=yòÄÚÚÚÁÁ¡|›111¥—_TTkooÿÒ-+UªäââbeeU:I™˜˜èììljj*>9666âTe:uFŒ±`ÁþØEiù*V` "‹]KIÞ†A4´P@ì77êÔɇ­Br20 ƒ;¼{3¦71Þ²;ÆÖtZ1oÞò�ÿc: ¼H7aíìBÈkÉ= ó&\·$»:Úq¤‡÷¢y€—!¦®Bu9©äl×᪠N @Ç@ø V‚†%ÁtmOäu„F较¥ºPru5äY“TŒ« U܃ dAay>ò׆bDò¶—Ö2šQ¢Ìa!IJŠO'l¬Å¸v <Å^{ÔUôܵZõ†X2Ì ’mFÏIøn‚ð‘Qn€ ¹L¤ºH·cúlì's¯cqÓµF±Žb„ øš% “1ujÙhM•Ä4Û¸c;×8`ûy§pA¼ûªRò-ì“á’ÊÆÕüïC´RÀ¦n13¶2fÓö³ýQ9[¥Õ»ÆÒÚ•\iaÚŸ5wÈåòÝ»w÷êÕkèС­[·¶··ÿñÇsrrÜÝÝkÔ¨ñ7ÿ 6kÖ¬gÏžlÙ²åš5kÒÒÒ²²²¦L™òû[vrròôô¼qã†\.·´´lÔ¨0eÊ”ààà .Ô«WïîÝ»Z´hQ£F ww÷àà`KKK'''///àÝwß&Mš¤Óénܸ!Ö$¹»»?|øðã?ž={v|||5ªV­*:1bR€Ï|ðàA@@Àˆ# EPPÐÁƒoß¾íããcoo¿lÙ²»wïN:õéÓ§­[·V(FÇÚØØÄÅÅÍž=;44´Aƒ¿¹™L¦P(üüüòòòD55AA8þ¼(­âåååáá1`À�ooï™3gŠ{edd4iÒDœ»*ßæ€zõêUø½wï^ÇŽ-ZÔ¢E‹‡<x0,,Lu›?~\\ÜøñããããÅ8Á?þ8|øðÝ»w·nÝzذaƒ •qŒŒŒš6múøñãƒfffþ‹²-ž¿Ú釺ám˜ Ž©Gd ǤÕ àöí*]º4zóÍÛ 9vŒíÛ‡àÁ¢ JtÚù¶(>]3s3ÖÔPS©ñ¬ŒêÞ–äT&1Ëg8 ÈÒ°k˹\äèdÜ=M½b¶˜2³ˆ ÐZÒNÉôDB$Èy¢£9<†+L› ³áC‡)°Üá´€gÆV#|šC ›ÔÔƒZ  œ•Y¿ ):†ÿ,¡YS‰«0 f–Y#@ÐT¦Ö¡Ÿ#;Û•z·JÎÈ0.;|@2:¹ËÛ«Â7}Ê–~\k ÄÊ TÓDC·iv »tšÇÀYæ·=÷ß«a?Ήƶ ¦aÕ«c^òjéÎÖÉÇb«)}BbAà Jlm,/™e Q'‘a—ùîsj¥�»NXU�� �IDAT„±q ÿ˜`^æWeJ²œú8#H¼.ÿÇÞyÆEqµmü¿K•^ATDE; bAc öÞbŒAMÔØ0FóhŒØò[ì)j^[ÔhD;vlDlØÞpÙewßãlV@¢è^¿ý0;í”9sî9÷¹Ïu¹ÔoQ­¶{NÞSKi^“õŒŒŒ´ÍRË–-…H6¡111ñõõuvv:v옕•Õ®]»-Z$$$¨ÕêaÆuîܹ‚¿‚:tÈÉÉ©_¿~çÎ¥Ré“'OJ˜e‘Éd©©©.../.H$’jÕªùúúš››;88Ô¯_?%%%==½[·n}ô‘pBƒ ºuëÖ¤I“´´´ôôô6mÚLž<¹víÚ...‰‰‰2™¬_¿~}ûö*ÜËË«I“&UªT144LOOOOO733ëÝ»·½½}||¼žžÞÈ‘#ýüü�==½Ö­[»»»krbnnîëëÛ¯_¿J•*ÅÇÇ›››7ÎÓÓ³C‡Ož<IOO¯Q£Æ¬Y³4qAE'fjÕªõÚkcc#”ÑÝÝ}Μ9%ÇdffªT*{{û±Z4iÒ¤W¯^úúúBÑœ „ ±··¯V­šT*mÞ¼¹§§§¦øÆÆÆ¾¾¾...E+GOO¯M›6‚ÛP8ÙÒÒR¨+©Tš””deeõÉ'Ÿ¸»»wèÐ!;;;==½V­ZsæÌ111‘H$UªTñññ±±±100ðõõ­S§Ž`®|||233ÓÓÓ4h0gΜ}ܺuËÓÓ³|È_B#ôè‘0-ý<„h ÁŒ!ŽñãYs:ƒ-øÂà|åÊÐíÛM¶o¿³}{³+W„°‚ è·¡ Œ‚†,¡«> zØX‘÷¹„jUÈ5!?#)ªÚÄØ‘R ™Š8œnâfGÊa:ÅS5ë;äå‘­b Ò|nBJF•¹‰¬c)½Ô¤ƒ~ƒ{ {á<d8 ¦ ×ÁU=.ýf¨å´íϪP•`/¤¿dvíÚÕÄÄÄÃÃCÓKܺu«jÕªkÖ¬)ñºZ t­yÅõÚ>œž@»³4¾Ì¥g«•õ¨/y~€a€ÂL$ÛM=׊A¿Ññ´^B IêsžýCÌŸJ}ÀñrOY %ƒ¤ŽÞÆžÖLïR)¹š½„†ñô9ÀÍ:_,È**âÕÏ=©Ùk?f…S?­-Řû8:EâKáS¸ ûÿiƒtvvîÔ©“‘‘‘ÐSeääŸ~\ ÈÏLz,é0`B+ÿÞ‰)i5ôSFzÿÝ¡q{dddܼy³}ûöï«Å‘#G:uêTF«²ŠšF…BQ¿~ýwÕbÏž=Æ «°$LB#?uêTppðßÛž@.È¡3×ChøÔ�S8 ž` Þp VÁ Ø §ásxÚA7 ?@ 'ÐÁ w%êê¤`ŸIåÚÄHQ©¦P©w«’œ‹i–¹²›^ 8ªP«ÉËäzRÚÁS%wU| gôÙ§â ÜQQ–€X‰òÄÚ–c @Ö> épì@ÅÙýt\Oî¯TË—/·µµíׯŸfíÄž={š6mZh¥:¾pt0>A_É?cÍj?Àþ…FW&äUá™|îM̨–À²yR§TÔ4¼IÛª5°;ú`Ñúœ&·Uƒ¶)o»ÖõÎé}¼ÚiY¿Û˾Ë|àʺaܪeˆàH,à‚òÙèêæ³ÑÕ"¨Ú‚]M¹åÀ ‘ò»Íyü6²fÁ¯p¼dÛ¶m.\haaáìì¬V«c²Ví<ó47ûÁµ3:V tÐá%q$ %cð épš3€!Ìà+°sPü Ú€ƒ+¸æb¬bò}–ª±P 6Ç08S¼’1ÐCï15íI6$ÿ ­ïa™‹’@V™:iœ+`�4VóÄa)\SrKM,(`Lƒ[°¼Á–=¬“ÕàC8 '@q,%y&îTÊ0†Câög<[*uFäv²€¯‹:×á°EÅ»u˜Í(T!dQŸ&Rœ<ôî¡YCÙ–Çðq†ÔúkåïËåQ^ì“3ä(T¦WS¦Líªø.Uþ> É$íÖ`Õ’é©§Ê'/4Ì©J¢ Aã!¨ öåÓBÊj#€ ÜÈâ–o¦~<ƒw0þ?rFØüCîkĘ~X‰hb_:sõ÷ÈÍÍÕŽqx[QþÞªìììb:Þ2¼]4¾uÀ ŽÁ8PÀQ8(vôµÁþ#.²ùŒà&¸ÂN¸3 ¤BWØmD/%‰ Ba…>-È—Qó>_I 1CY“L[Òþ¤¹qJ¡–i]N&-Å-…G* X­à8Ø'’�¿J°–�ëÕäCs8 Má1œ4`ª‚!` &`YZáép,À�!�–•v¥I6ñ×ð(OŒ›P}qWå ¾ZÖ<eÊS† ËF¡Ôb´‚ ‰â/f¢�iHÒ ë^W7øSñc_õ¨‡ÌC}Æüé9™† ýPýÃB~‰a"Š;™$VQöøY‚¾ä/vD�µ]ªÚù&ÈX¼[µixG<Ê¿lÕìýLèËg ƒ3­Rå­ÐÓ:úúFGg®^Ê[rÿþý·¾˜•+W.7½+IIIÂꈷÂ\ïÛ‚;âúÙ+§ ˜ƒ˜ÁhÕà†fàN°‚! "!Ìá¾9‘2æð•³<ªW'Ç–;&ÌI!6 «T¬ïc'å^*ú‰HõÑS°=ƒÊ&dqNEØ�½à@ˆ—’«ÆÔ$Áp‚pp†!ŠgÁ.½àz%®IÐËãüí@ Ї ±ÖC`: ¾Ìæ¶/y…$ª¾^ó ‚Áãñ‡¹ fžæFUι0ì`„R #†~røV’ԮѠ¤÷F²‹ãªnw›~—?”vrN”S5èÌÕß 99ÙÔÔT;å-Fdd¤&²¦¬ñàÁ‡w¤b/_¾,h¼EØ_ƒ>€T‚Mà^°A_Ê{¨" òÁÄ”†JšËØ!'•®p *CŽ ¢i ¦À™G†´2"AEª’Üâ“©ªâJU`‰ÕL–’�÷à#%iRzÂw*l¥40'=“#÷á6œhÖ0\! ba ¥–=h–"m©£†8sf FÙ} Pi>hì:ólµïuñ1Ö|)ŒÏ$ð8kÛ©ÈW“óÈòÂ+)ÍybD:GnÖ/ð Êh±‰Okp´žÞŠÁ’‡–¬E5,C¥Šâr= lHÏív"·ãÔje|¢äb}6‡høöù{?5 ¥+ó¦´Ž•ù]8T U wqÛçU˜_ïC#¹zM˜šš ã:”.¬­­ßŠ-£ÅoðK8/öJNÐŽC8,VR}>.à*xË©§~6Z'e.XJ±VRÅ”¨*¸Ü¥À›ÇÜ3ÆR†¾ yMbîóy¬”Rɹ1_ÆqÌ€Õù˜C(LQñXÂpêj¾”QôÁÒ 5 {ËþlvçO-"p‡\j”¢Uh¢µ¨´à�þÏyê�:€íó§Å"r®ƒ·h®b ¼ðý6¶aÄŸŒ;®ZÓ@\Ë•©uçg0!ÏŒ,@ÍÓg¶n-Ø@ÓG|öHµ-Sz³®þÈl¾¥š¼œ Kd¯Ÿ^édS˃”wùŸ¿ ¬p¼ârž‘¿Ÿ…Õï³àg~řǢ6˜R+à Jé«›«v"3“Î\½–¹²··¯°QÈ¥ˆ“'O¶iÓ¦Ü&Z,--+W®üOÿ[ðÇôéÓçß ÏøJØ3à˜‚(@®ÂxÈ0Pã”ô5`’T êʘYÀØ¢"Ó€ºj2Õ˜çÒ:3dv¤æÒTMÊB­‡¸(é¢&Úššù\É`¹Š/òùúÁp=Ö)™¬f't�µšž2Là<4€Ž ƒë9 Sá�ƒà�›¡ ü)ú6o€º¢W¹\ŸÍ­sЧØÚ‚Wé½Ó!ΣoòyAÄgò[žêÐî¬ü€Õ³õ $Ž#J”RTzò©œ¤ çó|¢0.%ÌZÈOßq¦éKk+ëœåˆwAôV&“•O»jµú]¨Ø¼¼¼·±X9�(à=ȃ[`5à08B.Ä 褦†³”ÌÌd’j¾Ss®™aY€KQj”rl³°IÇVA×zl¸N>ÜVðÌÈ5$,*0r$,P³ÛóßBCpzéS œ p†Ÿ :)(´† ¡P ÀSØ Hhªæ’ÖÂçR„!D*ªg¢P�‘ÌBƒ DêXH+6MÜc š¹O=äú¬öcÚiñK�Ê-ñÌg7‘c-ÃPPYÜYðŒA? u–Dßå¸ÚûLÁ‚O \ÆÌoÔ÷«ÉëÝÏìp<»M„”ÊRô�5OÔCê Öy4Š}.…66ü6š3r8IZ™× MÌ•FlE¡•Ï’«ú.Ý+›«-[¶hK¡÷ë×ï×_mÒ¤‰†û%ñã?V­ZUCˆWrŠ666Ý»w/·w®PŠ/ŸÕ—Á… )¬*Uª�û÷ïØð€¶mÛº¹ Cf._¾|áÂA3I#l8xð`íepOŸ>´0Œ=:..î?„)bÆŽ[lŠoBV6lغukàÉ“'¿üòËk´œ’‘œœ¼{÷nooï JñÇÔ^Ñ5vìØ˜˜˜#GŽ�|ðö}âãã÷í{¦'kaa1hÐ áq�666ÂCùã?>|¸¹¹µmÛþB(´/H…H°‡îð+Xƒ=DÂ�Sôe\Ô5 ­œ,°Ë"I‚5Ü•2@MF&ÉÖØÐò:rx¶R.©ð{‚<‡÷ ŽKè)åJÚÉIi­b'xAG¨ç ùHÍÂìÀ ÃmÈãçå?êƒ BÈÆRÞSRFr¶ÐBøbéu‹EeЬx›qÏuÔ ñÍÇLýá;øÉ ‘ë]£U–Aó,%mÄþ‰æ&œ‡" ½/£vÓtšÂËô-ØÛˆ/§êôP} ¨x¤öNÂLäT~ÚõP}þwH ¾oQLöÑš«¥•Ï’±ÚBñ´8%É3Ο?ãÆ††††††«W¯ž2eJPPÐÁƒ_õ¡ô‹ùóç¯_¿¾<_µB)Ξ={Ó¦M¥rçÈÈÈiӦݹs˜>}zXX°~ýúùóç U*0ÜQQQÓ¦M JLLœ2eJXX˜¡¡á–-[fΜùÜ×lNNPPÐþýû…ËÓÒÒ¦Nnhh¸lÙ²%K–›â›ùðÎÉ úí·g3Øééé¯×rJò‹ÈåBƒ<uꔦqjR400j),,,(((!!aêÔ©'Nœ044\¼xñ²eÏE*ß½{7(((22ÒÐÐÐÀÀ@xQQQ†††3fÌØ²eËþýû§OŸ.NŸ>½l£p~ËÐ$pZÃï`.|ÔKÈ% ¡L‚¡b‘šå ƒ§*©ˆÈ UÅh Û¥8ƒ#ô„ïÔd¨8�?Ã/n)Q@eGŽÐ"á‚ižrÂõ˜vpj@¥¿Â¯öÂeh%Œ{”Íý«ðß±ËX·™^ÿà&?Á§ð©Ÿæã)WÌBnˆÜ𙬢\Ž|:ø¹ß^Ï7UhiɇG5jÔ(;;;NãÂ… …ñDZcǺtéröìYàæÍ›]ºt8ñØ¥K—.]º=ÔöíÛ…7\¸°K—.b·‘#G {„ Ëk×®½r加‡2iÒ$++«¹sç–ÊååY³f 6,%%%""BHkÓ¦MB• œ@‰‰‰6lÐ ?~ýúõ£Fª^½z¡: lܸñŠ+„Ëe2Ù‘#G<==Gemm½gÏžû÷ï_»v­C‡šßT«²²²Z¼xñîÝ»…ðñÇ·jժИæb„ Ư:‚X 6lÔ¨QÆÆÆ>\·n••Õ¬Y³–,Y"ìÜ¿ÿ/¢˜ÌÌÌ   ^½zÍŸ?Ô¨Q}ûöŒŒl׮ݨQ£222Ž?Û¯_¿îݻ߾}ûÆ:UÌ¡-Œ€,ˆ€“PÁæ'8A-�ÃUôª°,UTÑg¨[¨.**Á<57Õ¸‚½ ‹ªŒ€|ø¬ª²"žeÐndñ¥’ƒ*~c±oÀ,&Nû£â#‘8µ Â#xÚB0€Þ¢¼ä51fä_ˆŸ°É‡pjýã»}|‚ù{¤‡ÞÓ[ÿ¡Þú%ëßg}[Ö·eŸgÅ)ñß zòóó±p¹\îàà˜˜¸yóæ={öøûûO™2åæÍ›wîÜiÚ´iLLÌŸþ™››;xðà‹/†‡‡;vìË/¿¬^½úÅ‹MMMW­ZràÀÁãääôçŸÞºu+<<<44400°X†ì²Fûöí7mÚôñÇ›™™8q¢råÊ¥rg[[[[[Û   'NÔ¯__ Y·´´œ={v~~¾ŸŸßW_}ejj§V««WƻܢE‹ððð#FÄÆÆj»þ€´´´¬¬¬!C†¤§§ûí·Gb„A£Fd2Ù­[·êׯãÆ^½z• í½€ÔÔÔäädXpÐÙÚÚuHFGGMš4©T©R‹-Ö­[·yóæŒŒŒ]»viNS©T¹¹¹×®]ëÕ«WRRÒ¡C‡tfçuñ& ÎWp�o8K$˜çóÂA º0¶€nÈL(°F‘F%OàÌRó?ءϧ‰4€ëzœU3;‘9*¡tÍã ƒa£SÕ QÑ®‚zÂe5Gáô‚?! à�T9Œ‡*0Â9ø¿²© G¨ BÕžþAØi ÍrŽÿ¾¸V 3¤È ¢ oàÌÞ£tK#׈T3ÃáO@!F,ÔÈäh8<W‰ŽP1Ê©S<[f²`5/(r{ÃG�ô‚6�܆UE2P4ŠRÓ´¶ß„¹ºsçŽÀVîèè¸aÆ–-[Ž1¢gÏž‹-ÊËËëÚµë˜1c&NœØ´iÓaÆ1bèС÷ïß—Éd#GŽœ={öÎ;5”\./((¸ ##Ÿé}<y2""âîÝ»ùùù‚„|9C"‘xzzvíÚuÓ¦MAAA‚6D)bñâÅyyyNNN‹-Z¾|yPPpâĉ€€€FÕ«W/,,lÅŠ!!!šKüýýýýý‡ 2|øpÍD—0–6&Mš4xðàÓ§OW䮫eË–«W¯ž1cÆÜ¹s‡ ²bÅŠÒºó;wÖ¯_¿aÆ¢zTÚ8vìØŠ+6nܨ‘ùøã?þøãÆ;6<üYЭ͵k×45ß§OŸ×SÖT {•°zAM=Vp¾¸ ö 0Â܈ ± N™R+™ÓûÀN‚‘”h%Mm0Iá  $ê€%T0€ð„­PMÉ/` €èÁq‘QɪA ˆ†8P@3H„å…¾É˨k‰7¡JZÚ¯T«Å¢�¹ã‚öõàŽ‡Ý!IàÈW£â°h?n‹—d¾á8SBY%8?òD~}ùËe@õËV–ÎÀ „Š(vE§O­Zµ~þùgAŸiöìÙ?ÿüs½zõ 4kÖ¬ÄÄ ÆüöÛo~øáÙ³gËA3ðEÈËË›7oÞµk×&Ož¼jÕª7–]ZÇ_¶l™vœØìÙ³–-[&ØžŸþ¹„Ëׯ_¿cÇŽQïÕµkWAVcéÒ¥¥xÛÐÐМœœ­[·††† µ*8�^»,[¶ìøñãèPj8CÀV´€dH„h0RóÙö>á€gáHúà éP꨹®äTJ&MÍA°‚h2XƒÁ"ÁŒÁ †A¨¡:( �zA;¸à”Ö²Ó3ðöÒÓôø„Ÿ|ð½‹o.¾à‹Ú7Iå¡òPùžÅ÷®ø“ Gÿúõpbià¿¢ˆÿ4½C‡õêÕ[³fM³fÍzöì „„„ÄÇÇëë뇅…MœXx$7oÞ¼^½z…††æææþç?ÿÙ¼yóáÇßHùg̘qéÒ¥5kÖ4nÜØ××wìØ±&L(…Wöüù7N˜0AóuðàÁµk× ¢VfΜ™žžXXX�öööcÇŽmѢŘ1c4çœ:ujóæÍS¦Lùæ›oÜÝÝ©‘w½{÷¼|ùùù€¥¥eÑ©ÔÔÔï¾û®[·nB,¢¦ÉuëÖMsNXXØ‘#GfΜ9oÞ¼ÀÀÀvíÚéìL)áä‰ëXsAÔ ‡«p ºAÈk=l!]M¦ ™nç’Á2àxH%E©ä$Ôƒá.° Þ‡¡à—àWȆ#0n@*ôCøNƒ ‰[ ÌájyU‚v�º>Œ·w¶çÏ´ÑÒ‚ê#;ˆ${5rS0T¤<%Æ…GÁ$ñh<W…òi<užj%¿,­)º¢+epMÜþ\¼üÏôŒ³‹+]{qº,K<­XßX}Ñóù¤H©_„¡ÚºÎ¥l®€E‹]¹ò×Òå>}útîÜùܹsiiiAAAõë×ö>üÌ™3#GŽjÖ¬Ù¼ysAªM›6>>>ýû÷Ÿ4iRù3É:tÈÝݽqãÆ@ÇŽe2ÙéÓ§KÅ\Õ«WÏØØxĈfffAAA‰äÂ… ï¿ÿ¾L&ë߿Ϟ=5¾ÇØØØÝ»wwîܹV­Z'NÜ´iÓÇ7oÞ Ü»woûöíÆ Û´iSÿþýÛ´i·nݺZµj-Z´è¿ÿýï¡C‡îÝ»wòäI;;»áÇϜ9S“â[Ù6hÐ@`Šºxñâ¢E‹7nloo_ˆ{077÷ôéÓS¦L©Q£`kkëáá1eÊ”… fddìܹ¸råÊöíÛçÍ›·lÙ²ùóçŸ:u*&&æàÁƒ...cÇŽ;wî²eËjÕª5wî\ƒsçÎ 0    Gýû÷×Y¤¿C¤¸!ð!õ…ÉÐÝŽ/²‘³¶À½'´W1JÍÞ|’Á\ .Ã9øꨩ¦b)‚Ì>ð'|° Þƒo!zÃà ë!ÁrÈ£-„5L‰Ðžj¹ÅÊ !/×Ù˜(.È»º–¹ò}quE{pYË\y‰RÈ·Ds•�»^ìžSªŸ¹:s´~çQ$^Üî•�¸Zâ%µÅýóðë‹Os žúÒæÊë5Y-nÞ¼)‘H4ÓÒÒ„=ÚJnR©ÔÔÔT3G]³fÍ›7Ÿ=‰D"‘Hbcc…mÛ¶ Q…¿€0m lk•ç[U¨ŒBVKåΖ––Ë—//TÞðððB{|öÙg“'O–J¥=zôÐT¬`æ‡ &lkfk„¿cÇŽD 5{Цøf±lÙ²o¿ýV²_ºhÖ¬™¦AÚÙÙi¶ µUÀØØxÒ¤Iš¾Ÿààà H¥Ò‘#G>\ûТE‹43Xž½{÷V¨ŠýWAЕhŠz9±+Ž6`­G%ÛÕô‚p%Ã!úÃtø 2á>˜Àh «¤È$Ø)IQ£„` ౸äÖ~5ü m!$.à ÿÀÆÁÿÊËVéPîÎÀ¢½ŒffãÆ&LðððÐ~‡ ]¨ù[ôU×>óô/Êj© hy_ÔÙiï/”‡—<TòýßÊ:?ÚRò£,¹®þuû¯‚ FàG.´–J L‡•ðÄB5p% …ñ0òT€µÐì`5´…xˆ€áPÌ Ô`�]De©§à ‘Z‘vZŠ!å%\·ÅP‹d1BO âQ+ñ¨éËÝÙ 4kx/9úT¼sÉ^«§Z׿Šò&ÐSiÔì»ñL+_¼$š ÒRk$ž–ýÒuu ^‡Õâe––Ö½{wÍ7¾:èð®ÀÞžùó_úì*àçÁfC"øÂh®ðDÃè 7À�La<ZB*máÔKð½ç/4‚Np€Ô†?ÀJtšµ})•‹ýû)vÐ å„ýëÑ\ɵfÔ|DwßKÂƾØ\¥‰w.™¯2]+{Ì…�œÖ2W!"_ð§ ,³i!f ¿8sQ¯XW[ -ø–‰¹jÓ¦M›6mÞî·2&&æÖ­[o}瓚šZÎ)^»v-!!á­¯X™LövlìØW¼ ²áŒçuZÀÏð�>†jpB Ô¸@"Á  \� ¸P ´ce…¥íA÷¡¬„ÎPGkú§Dœ8B:ŠÛ¿sd¨ÕÎÎÎUªTy kll¬ÍY¦P©Tš°É·‰äí$žin^‚m>$À`H„FP€zÃq )z,,`$èA�Ü œƒ• ¡jȃñ0ž€ôA …ã`Ѓx°Õ²Ùrî9@¥¥¬ÒêrõÄ Áíf ýZˆ!vJñ’—_¦IK!ÞD%.Ÿ*vȨ%èÚ(ÅuT -u`™¸öIùü}(ñV:sU^xô葆ÿô­‡žžž¿¿ù¤õàÁƒw¤b---îÝwš‡‚qdÂp)| =ÕXð4„›ðÈ¡:xÀtøîC'Ìä¨}`. �;ØMANBøÃvøñ ö¶VdÇ_ZPøKq�”xPtí„Æí¶Q÷ðURð¡˜\”ÀÄÖ…’ÃD¬›«EË"æÓQÔô*Ù¹ú8;;wîÜù0n”3Þ�� �IDATâãã«V­Znjžžž^^^ȣG\\\Þ:½«h ‘ W 9ØÀ:‡ÿ@äA�üéÐ îßÐ΋¶ÊF@É[Å;WÒ ËÞ®«è· :sõ÷P(oíôƒ.]ºTêT%#??_ñLœ>}ÚÅÅE÷i!Ý_°€†Rn‚¯ŠSðèA%Ø%Jiü P €%¸C.TƒC)Ðâ  \c¸ €)4SººÖ™+tÐA‡އ 7ÔÈadÀ X· Q4W‚Mê‰Ð €îC> ‚Pˆ‡\¸¹â¸jXÁþ7Z4[°‚!b7+lPÀ% F€šS èÝXÂhñª-âÒæöâñ®¸p­XÄÀ·âöfqC£Ð@ËS·NÜ9¸'^[Y‹óâÈ  |€R$(ÑF7Q•1],Úk¸IˆÞÈ’ËøJZfäíí=jÔ¨·ûu)TÆ&MšŒ7®ÔS)((øñǽ¼¼|||¼½½³³³e2Ù´iÓZ´hѪU«?üPã‚S*•¡¡¡õêÕûßÿþ§¹<77wèС­[·nѢŜ9sd2YVV–p·&Mš„††*•ÊóçÏ{zzúøø4lØ0**êÍÖjZZZ½zõ,X ü}üøq½zõ¾ýöÛROH&“Í™3§E‹­[·:thnnnNNNŸ>}¼½½›7o¾`Á‚üüüÌÌLŸÆïÞ½[Û¯›ííííãããååõã?DEE5lØÐÇÇÇÓÓóüùóÂãhÒ¤‰pNVV–Δ*b! Ô4U³nÃ8X ßWÆßˆÆZtéG!~ƒ8H(€½à5!îA.$pþbßhÑŒÀ�NÁ)­)Ô¤«HP‘ æDC4ÜպꞸÓLdôkTb*9âùÑbZ§D†_À ÜÁêj]â"jS¶ÞwZ‰hP\ºUÅ›hÊørE5_®Œ/7ºJMMµ³³‹‹‹ÓÓÓKLL|ò䉅……0C.į?xð@ 577¨Œ®_¿ž››ëæævýúuWWW‡Ó§O SnnnoD%¤Ô¨Qãþýû111µk×¾råJff¦““S©§³k×®yóæõìÙ³nݺÇïÚµë÷ßngg׸qãš5kΙ3øí·ß–/_žœœ,â øúë¯ÿý÷Û·oGGG¸ººnÙ²E¥R>}:$$dܸqžžž]ºtéÛ·ïÆ‡ Ò¥Km*÷70f×ׯR¥Ê­[·„~¿´”Y´±mÛ¶U«VíÙ³§Q£FÇߺukTTÔÑ£GãââŽ?>dÈ77·kkëÓ§OÏŸ?ÿƒ>¸r劳ó32·áǧ¦¦Þ¾}{íÚµS¦Liذa@@@»ví¶nÝ:f̘.]ºœ>}zܸqsæÌ™2eJãÆûõë§¡rסôð‹Ûy0~Jåè®ÅH+|àw…]`�i …ZR¨ñZájþº‰«wÔ¸wïÞ‹/:99¥¤¤\¹r% ##cûöí‹-jҤɌ3ŒŒŒªV­zøðá+VLš4©M›6úúú6lX¾|¹……Å´iÓúõëwùòåÚµkýõ×666§ü7n7nܤI“zöì¹zõê1cÆ|ñÅ¥žJ½zõ~ûí·ˆˆˆuëÖ=zôðððpssÛ½{·©©©³³s‹ß|óÍ´iÓ´)nÿ°´´üúë¯:uê4bĈO?ý´]»v¢£2JQž4i’î­þ7c%Töp¶Boð„lx IpÜ 2ü­Åy,}è› †8qµµ‚J¢Ew›$ˆ{ÀÏF\h\)õE'[Mqt·Ï‰þ°øâRéPdO#1ÝÌâÎoÖE2ðT+-Æ%W\Î øŠ%©â%K,xuVªÈŠ~]ã6kíô…&¯o®€;vhÆ]»v]´hÑÉ“'—-[öóÏ?tèÐÁÖÖö‡~عs§‰‰ÉÝ»wwîÜ)ôËÀwß}gff¶hÑ¢ùóçòÉ'Ê\™™™-Y²döìÙ3gÎüì³ÏÊ”ÖÀÀÀØØQúK©T«T*a]ÎâÅ‹ƒ‚‚ÞŽèWW×>}ú„……EFFš››—©þî»ïvîÜéêê:a„?~|úôéåš   I“&Mž<Y£²¦CÅFÄBØ 'a ü>` Þ-’ºvÔâU ‡NZs6 Rp×rß æª•h®bÁG<ú¼;÷- ·§–ÈO1¨ÈžjbºÅ2�´S¹%Nqiã�(îcBP?Øç_¢àua ˜¢æê)²³w ·ÿˆ"ÏÅÅE¥R}øá‡ï¿ÿ¾ö~ccc09˜˜Ø¹sçü±b6¥ÄÄÄ‹/,ÓåœÍ›7é:}çÎnݺõéÓGP[_¸paýúõ Õä¿ŽŽŽÁÁÁ–––›6mÚ¼y³ |UFèØ±c÷îÝ—,Y²fÍooï_~ùeÔ¨QA÷ßÛ¶mC‡xÜuø7àè9dˆ¸ Y°jAQ·èÙà×u÷vãEîÙ³'((hݺu¾¾¾uëþ5›§R©’’’4«T©²k×®¬¬¬ÌÌÌÚµkW¨ò_¿~½OŸ>cÆŒ™<yòG}Ô®]»}ûö•ú[~~~RR’µµµ¹ù Á²²²,X°páBa>?((ÈÓÓS©Tš™™ýKÛV•*U„š,k;áæææîîžýèÑ£ôôtSSS777 §TBBBµjÕ<XèqèÞÿŠŠdx` ïÃzØÁ— ‡XP>Œ8èaŒ€[ (޼®ü¡Ô"ØUk9ÙôE…Ž|1¤X2…–`XªÖ}J@Ñ!”XÏSÜfŠgšŠ9IƒêâÑ„â±4H98òˬÞÒÁ®L(níììªW¯~ãÆ ƒV­ZÅÆÆ6nÜØÖÖöàÁƒÿ÷ÏBzZµjµcÇŽ“'OîÞ½ûæÍ›[¶l©^½zÅy-úöíëéé)ÌWmݺÕÉÉiÒ¤I[·–²ï;66öƒ>ðòòêÚµ«0Ìrvv®V­ÚÙ³g-,,ìííëÖ­;p 0jfÇŽcÆŒY¼x±µµµ““Óˆ#š6mjkk{ôèÑØØXggçêÕ« µzðàÁÛ·o7jÔÈÜÜÜÇÇ'!!áàÁƒÉÉɾ¾¾ïH¯V½zuggç .$&&ÚÚÚº»»ÿúë¯ .\¶lYTTT­Zµ¿ýöÛƒ.Y²äÞ½{^^^•*Uº~ýº¿¿ÿÂ… ›7o}ðàÁèèè XYYùúú&''<x0!!ÁÇÇÇÜܼQ£F·oß>xð \.oÕª•Î’”vŠ+!BÇ~�9X!$ƒíï«Pµ"¹+’ Tó¹êæ` À0÷Å—ßÃLî×KqÖ˶¦Èžz"Ý"àSbDåʾÞ@ÛYÏ¥~‹jµÝsòžZJóš4¨§-Ì*—ËE{{û¶mÛš››ëééùúúº¸¸(ŠFõîÝ»nݺ>LKK›3gNbbb—.]6l˜’’2xðàÐÐЮ]»~öÙgOž<‰µ°°˜:ujEãˆÊبѳHJ…BѪU+Íh@&“¥¦¦º¸¸üC'¡M“&M?~ߺuë™3gººº A‰YYYýúõÓØ*aljmmݦM[[[¥R)hWZ[[ÇÄÄ(ŠQ£FuêÔ©C‡…jµS§NIIIñññ5kÖœ?¾0IöJ¸ÿ~­ZµJù S©tqqi×®žÞs”b™™™*•ÊÞÞþ²Z¸¸¸¸¸¸<xð --­W¯^‚i·°°¸{÷®Z­3fLÛ¶mýýýSSSããã­­­ƒ‚‚jÔ¨¡V«}}}‡ "—Ë>|hbb2iÒ¤úõëûûû ÕX­ZµùóçW­ZµY³fqqqñññ^^^_~ùåkdòÖ­[žžžò2¡ú.üÑ£GÚ"vÍ ¢¡.dB>T QqñY+€ÚóAÛ2G×®]MLL<<<4½Ä­[·ªV­ºfÍ­QFÆÚI$5¿ ÇŠÜÌ,žß“Yö‹+Ãqû‡Wûø[Ôãà󊛦*ÎÎÎ:u222²²²2ròÏG?.Päg&=–t0¡•ïÄ”´ú)£½_‚·êezäȑ˗/,_¾|ĈÿÞ¼ŒŒŒ›7o¶oßþ]`µ8räH§N²Æýû÷ EýúõßV‹={ö 6¬Â’0 üÔ©SÁÁÁ»"û Þ‡Š–­åË—ÛÚÚöë×OC½gÏž¦M›6l¨q7‚•/7ºÒ„Zh³–q êi( ÿntõªè¨jñ’ƒ?Ú¶m»páB gggµZ“µjç™§¹Ù®)eV ??¿7úûûËd²ôìÙSçÔÐAJ'ÿ¥ù– ­)g'òõÓgôðšù$-7f|öt'-Ü7ûât4§…Š*_˜Â4qû{1p¼ûžšÈ¸¢>äA8'^5CŽ…E²×@üŒgVÏ ,_:ßR6W‡~#2öe‡§OŸ¾ tå?ÐÉÉÉ)7½’7ˆwÆ·\üü_û"{*¬¹ÂHT–'öàˆ‚@Z{`¨5Þ*9[sZщ�©ÖQ^‰¹ÖNM–Fˆ“…fZCC'­¢‚‰x´Øà‹­x“Šg®ž•éí’ OII‰‰‰yë;KKKƒòœbyüøqrrò[_±eÁ“ò®¢Táe÷FõìuxÐQÜþ RSS------ß…Â^»vÍÍÍ­|ÒzôèQÕªUߊՑ²—R%L®·]U•!5†)¢Â¡¢˜JÜ·‰G·æ/Y¬®EÆ^‰pVÜÞ­µ³òµŽjœ·Ä%Ϫ¦h][4âì±xTÛÝç#F¢Ç¼úb¸ à¡3W¯ ccc‡w¤°å9,677w*V__÷¢• žÀ�’*Æâª` ÀU@^Ú_‚¼Ez q¼yè5pÑ2WŠ\{UË\• ç(/îhŒVº% ­Ä;ÇÇÕRtoyusõ!T:sõ:033srrÒ&œ}[áããSnB”ÖÖÖo§*üó8|øp@@€Nž±TqÆ·„H‡·|p­Ãß@­V¿ ³å¹¹¹å\Ìw¤bu†ªlPÁm•’Å¥¾R‘{0Á-œýüê1N<‡eˆ¼´ùZ´ôE!Ó"„½üºYÕŽæxm‹ Ñ¢å­Tœ¡Ñ°CÄqiAUq;ž¼(%enûöíÚë\>ÔÔÔ4kÖÌÝÝýõî®á3-Ó¬– d2ÙöíÛÝÜÜš7o^èÐÞ½{333Æ7lذ  à—_~ùûû;88$&&j,Ê­ŒÑÑÑ/^ìÚµëK*€„‡‡gfföïßÿWõõëׯ\¹XYYZSqçγgÏÆÆÆBVÏœ9s÷î] ZµjíÛ·/ú8töA‡WAìy7´1EŒü>aEŽj˜ w‹.¸ø×]ùÃq»ÆëfÕ>ÿÇå5,ñ&VZGçqxVÕ:M^Tä’"#¿øâ‹åË—çŠ(‹¤K—.1cÆÄ‰?þO €&“[¶l™8qb…eظqãÌ™3'Nœ¸sçÎB‡BCC'Ožœ››1mÚ´èèè%K–,]º4777,,lÆŒIII3fÌ ËÍÍ]ºté’%KÊ!Ã111Ó§OŸ8qâŒ3^²VW­ZU",¯ae§M›‘››;yòäÐP #±±±Ó§O?tèPnnî_|±qãÆÓ§OO:õæÍ›±±±S¦L9tèPÑÇ¡ë€uÐáÍâoÙœœE 6lÁ‚¿þúk@@ÀÇDœ?^&“͘1#<<\Ø£9* ’’’4'?|øœ>J»víZ·nýËгgO!‡NNN±±±K–,ÉÌÌ,”âÉ“'…¿ÝQxxøÞ½{çÌ™0gΜ½{÷ GËš½¢E‹/â&?|øpzzz```§NΟ?ÿàÁƒmÛ¶U©R%00°aÆ{÷îMKKÛ»woÆ «T©²mÛ¶rhqqq666{öìùóÏ? Ο?pòäɉ'Nœ8Q8gÁ‚¼}ûv@@ÀÞ½{µ‹B­Ž;¶ü[öƒΟ?ß©S§ÀÀÀôôôÇk%%%?~ÜÇÇ'00PÈçõë×£££{÷î=tèМ;w®èãÐu:èðfñ7Þ$…B‘’’"¸SN:uìØ1!òxÀ€ÖÖÖ[¶l éß¿ÿ¡C‡~úé'¥R¹qãÆ‘#Göë×ï÷ßß´iÓ‡~¸wïÞaÆխ[Wlmß¾ý½{÷´»o©TúÏ‹¡R©:4uêÔ™3g>ÜËËK;Ń6l̘1;vì߿Ϟ=¿øâ‹ 6 :´mÛ¶jµzãÆýû÷ïÚµëÑ£GË®º===ÿ-#--mĈƒnÛ¶­……E÷îÝg̘qâĉ˜˜˜Ÿ~ú©k×®úúúÕªU[±bÅîÝ» tÿþ}ÃWð­?þóÏ?ïß¿¿——W``àÚµkuï›ï áü€|- ¢µ ðg¶fÀTñètx¥pÙT-eÅÿŠ?ðŒ8C³âÖ¨9ƒÀúTëü`qFíUƒËäZ¥øË€ˆéZG5ÄŸÀh�nÀ8qgÎ뛫èèhAXoéÒ¥€¹¹ù—_~9lØ0àĉÑÑÑ©©©ÙÙÙJ¥R¡PØÙÙdeeÙÙÙ™™™=yòD¡P¤§§çääDGGgeeedd”QÇ:xðàÀÀÀÑ£GéééFFFvvvFFFÙÙÙ¦¦¦vvvR©T˜ÈÉÉ111±µµU(J¥Rȹ`›uÐ|deeÅÅÅ8q";;[9oÞ¼fÍš µš››+—Ë«V­º~ýz휜œøøøèèháL]}êðN½=P ®3ÔÚŸ§u‚¹h4Á8ÊWOEã¢7q¯.Ñ:ª•H`¡ ”ów˰^u‰ªŠ;j"fÀü%ÕÿÛÑÀž={´C‚­Ú¶mÛçŸ>`À�í¡R HNN>pà@ýúõëׯ_McÛ¶mNNN>>>º·¤ÔkÕÉÉéÀ:tعs§F2ê%¥T*GõÚq4:è ƒ/e®^„åË—;88,\¸pþüù/£)îîî¾páÂM›6]ºt©Ô˰jÕª+V|÷ÝwÚ_÷ÿ¤¥¥Í›7O[|¹â`ùòåƒþnÞ¼yóæâ%…òóóCBBŠîïӧψ#¦OŸ^A®mذáöíÛÚr-:èP6°‚6Zݬ†%öÈ:-2ÛjÏ—ïåElÄKRŠ¡o ®âihÞÍ¢”ê²âÄÀ,D±$i®4á3A‹¯½Tð>X3„^°lÍ•àùñ÷÷ïܹsëÖ­KžKß°aÄ üýýïÝ»·xñâRoáááK–,ÑË­\¹rêÔ©BŠ6lpqq™5kÖ?üpàÀÌÌÌÐÐÐóçÏWF““³eË;;»Y³fEFFúûû§§§=ºuëÖ6lèÝ»·¿¿ÿ£G–,Yâââ²dÉ’o¾ùæâÅ‹ÑÑÑ»víªù=z´0M5jÔ¨þz¯š4i2~üø-[¶$$$|üñÇ圱֭[=:88xíÚµB�Ž=züøñ¹sçN™2eõêÕ;vì�–.]jeeuâĉO?ýÔÀÀ@¸0??¿Ðãx»;×Ñ£G áû:¼*jÖ¬yîܹ";íÃÃÇkíÐ|ŽÕR.6bŸ.ƒ)EŽÚçÜ+]–/[Q‰øé ôŽ_ÕDïhº¸¶ ÑnXXX¼ˆ= $½«§OŸJ¥R`c^^žžžžö_ÀÀÀ@¥R Túúú†††ùùù*•ªR¥Jr¹ÜØØX"‘hˆ· ÅV¨T*™LfhhøÚ«ˆòóó q1kbü„…Ì{LLL„¿FFFR©ôéÓ§BÎe2™Z­®Té¯5ne¡w¥V«5)jþÈd2aÙ¬ðWSÉ€‘‘‘žžžR©Ô SLLLJ÷­+ªwU´ÂÃÚÃÓ§O“’’oß¾-Hô~ðÁÚ �H$ÚµJyé]) áþR©TЫšŠ¦hçM.— /‰¦‘}¯‡…Þ•ƒƒCTT”Îö¼”Jå!C4/Èž={ EÉêðJP©T­[·vtt|½«B]L¡þñEÝ¥¦wÓ×××X úV©Tú{^mäeO;3/ÊÛk(ð¾$‰vÞ´ÿÍ@¡Rèé镺•ú‡ `÷îÝ_~ùå¬Y³²³³«W¯^³fÍbÀAQ3SBÞ …ížw¡k000°¶¶nРFD[‡×û Õl;88˜šš4HW-ÿEÕ…t$L:ü# 8P"‘ܾ}~ï½÷tuòï‚™™™››[nn®®*J -[¶ÔÕg© +Ng®þ÷ïߺã·iii¯wá€^﨨¨BìYo%Êzí¹:¼#Й«¿‡³³³½½ý;ò¡]nS,‰ÄÝݽN:o}­J$’² 0ÓA¹Òá/X[[·nÝZ.—ëéé½ å-7[%h*•Êw¤bsrrto“:”¦¹200(4Û¬ƒ:è ƒo…cŸ3W7nÜ(6ÊNtÐAÊSr‹7Wfff…b—uÐAtÐá@*•f+4«‰Ÿ3WöööGŽySke|||ìììÌÍÍßì¼´Z­ÎÏÏW(fff…†¢ªj¥R©½ »ÂB©T qqfffoä±¾ñ ¼ òóóåry¥J•*¬¦h¯F¥RùôéSaUâ¿"ª¥>q¡cQ©To¼.ÔêäúYp¯s¥V«»wï^þ9«T©’ÀŒ®R©Þì¼tlllJJŠ———D"©€L7nÜÐ×ׯ[·.ÿUõˆˆWW×*Uª(•Ê7²åøñãžžž•+W.((ÐT(<yòäüùó;v”H$yyy…øYtÏñeðÇ´k×ÎÌÌL¡P][ZÑ “ÉŽ?Þ¥K— õÄ###íììjÔ¨¡V«+HDzÿ~ ѳÁ–n¼©ƒ:è CŇÎ\é ƒ:è 3W:è ƒ:èðfÍÕÙ³g4hàãããããÓ±cÇ+W®¸ººnÚ´é©_¿~íÛ·?uê”Oxx8àêêúÙgŸ•g|||þóŸÿTg|çΟŠOݪU«#4Ê@ÄÇÇûøø¬[·N÷¢þ¤¥¥¹ºº~ýõ×'Kûöísuu=räHů½ððpŸS§Né’6ºwï^r”Ù3g\]]·mÛVЉ¾f\Ê… ºvíÚ¦M›U«Vegg ó©©©Â<gDD„ ÎP¯^=GGDz¨,¥RyòäIa»Q£FÖÖÖW¯^­W¯^VVVFF†»»û‚ <<<.\¸ššóèÑ£5j”zNnݺ•ЦM==½GÝ»w¯yóæ ,x›¢¢¢RSSGGÇzõê]½z577×ÛÛûñãÇwïÞõòò244<{ö¬³³³@ôPê¸zõj@@€³³ó÷߯T*;Ö¼yó .8;;?}ú499°··÷ððˆŠŠrqq¹páP§N´´´ŒŒ kkëF‘‘‘‚€}ÙeHOOÏÊÊÒTŽÍ‚ œoܸ‘œœ,ä¼V­Zeñœ<yR3õݼys¡©kL©±±qBB­[·�CCCá9êéé%$$dggW®\ÙÂÂBÐ×öóó+»žBhr@åÊ•õ .Båz;T*UjjªpBù<G¹\!l{yyYXX¤¥¥]¿~]Øãçç—ŸŸŸšš*—Ë eÕÔÔ4""¢ZµjJ¥RóZ•E×áè訧§÷øñc¡Qͪ‡‡ÇÇ…\-X°ÀÝݽü³*@hrÚ)Ö©S'22R¡P´lÙRès�SSS¡ÅêsÊègffÉÉÉ7nÜhذ¡­­mvv¶Fª×ÛÛ[¡P¤¦¦Êd2!«uêÔjõŸÚ½¦¹:sæ ˜˜xïÞ½õë×?~|Ïž=¡ß~ûmÚ´iýúõ»~ýºÝÂ… «T©RꕵyóæÅ‹÷éÓçôéÓÍ›7Ÿ5kVppð… zöì™””$•JÏŸ??dÈ7ÆÅÅi²ZÝÜêÕ«7oÞgbbò믿Ο?ÿôéÓ½{÷îÛ·ïG}ôÙgŸ5mÚ4//ïÑ£Gÿýï¿üòËèèèÛ·oïÛ·ïóÏ?·³³ëÝ»÷”)SæÌ™S­êâÅ‹r¹<--íæÍ›ááá›7ož8qâŠ+üüü222ÜÜÜ€›7o†„„|óÍ7yyyÑÑÑfff®®®'Ož\¶lYAAÁĉß{ï½Ç?}útÉ’%®®®eôÄÅÅmݺu÷îÝ~~~£G*çáÇ;vì˜7oÞ©S§$ÉâÅ‹kÖ¬Y©9rD.—GFFž;wîôéÓaaaèÔ©Ó<räÈ/¾ø"%%¥aÆ¿þúë7ß|þüù5j¤¥¥]ºt) +++,,,88¸Œ4‹¯]»6uêÔ5e&d�� �IDATj˜˜˜\ºtéÛo¿ÍÎÎþôÓOûôés÷î]¡rŽ=ªývLœ8Q¸öرcåóׯ_¿víÚ÷ßÿرc~~~Ó¦M›7oÞŸþÙ²eK¡r4Ü…^ä‰'öîÝÛÛÛ[.—_¼xQx­J7oùùù½{÷nÖ¬™¡¡aDDÄĉwìØQ4«ÝºuÛ°aƒ­­í”)SÆŒ³uëÖÄÄÄb³êíí½eË–   >ø Œ†w“&MÚ³g»»{ïÞ½.\”’’²{÷î   µZ]§N;w®\¹Ò¢PŸãééYv£ö-[¶üþûïõëן;wî7ß|#Ôáo¿ý¨I7(((&&æ“O>9tèPÍš5ƒƒƒmllÊÕ(¼�žžžE¿"¿ÿþ{ 88¸{÷î»víŠ-‹šZ¾|yõêÕƒƒƒ½½½¿ÿþûÄÄÄï¿ÿÞÛÛÛ××·Ð7N Y- <Xxׯ_ß»wï¨Q£ªV­*:tèPttô´iÓÆwñâňˆˆO?ýX¹r¥æòààà† öìÙ³ŒšÔ‡~hffV»ví=z{þïÿþoåÊ•}ûö3fÌ¢E‹&NœxõêÕcÇŽkÖ¬ îÝ»÷¾}ûüüüfÍš³ÿ~á9Î;wøðáÇŽ»víZÙ ôôô:tèмyó5kÖh5ÔªUkàÀB­–QêsçÎ<xp~~¾ðW¬Xáééìîî¾|ùòØØØ]»vuïÞ=88XÓÔwíÚÕ£GiÓ¦EGGËåòàà`‡+V”Q#"".^¼˜——7oÞ¼ñãÇ………%%%/Y²¤gÏžúúúÖÖÖË–-Ó¼š•!åöW¬XQ»víàààŒŒŒ-[¶øùù­œB/²U!n~åÊ•eÇ wñâEGGÇ•+WþøãBV…&—˜˜(dµeË–…z’b³jhh8pàÀêÕ«/_¾¼Œ²êíííçç·råJM|ù/¿üòàÁƒY³fEGG:thàÀÁÁÁ³gÏ®T©’ðvÈåòÅ‹9²LIõôôôZ¶léçç·eË–ÄÄÄ5kÖ4oÞ<88¸víÚ…Ú¿T*õòòêܹsXXØ?a(“Ej;vLII)SçitttÇŽ?~¬½³U«V•+W.뤋¦¸oß>Ÿ+W®|òÉ'VVVÚ' 6L£™Û©S'àðáÚõûöík×®]ãÆË-á¡¡Íš5,Xзoß——·èÞ½{9,ÈppphÖ¬Ù–-[ŠêÑ£‡ W_¦xüø±‡‡Çœ9s =Ç ‚>}ú´hÑâ“O>éÛ·¯¯¯ï°aÃ4‡jÖ¬) :+W®Ü½{÷¥K—z;Êó9jÞŽV­Z ^µW*ãW_}U¹rå²ËX·nÝ‚ƒƒííí¿úê«Ë—/wìØñÑ£GÚ'øúú¾Lpss+kU:u긹¹­]»Vóªž={655µGÇ×îg„OºîÝ»1bàÀݺuÜ'e+++__ߣGjöüþûïQQQwîÜ)$mjffæçç§qV,seeeµoßÿ³wßq^WÇþøŸÛØ¥maY–¾t^–®€VìX°DD7‰×(71&—DÍM1&~o¢&7jŠQ ˆº‚ ]z]Ê–ºlaaËïwÞûû�jð^^ðØÝï÷gÎÌœ™93sΙZTT´{÷î//?Þ±cÇ©S§ÕŽšÕå®]»j®‡?Ö‰ÆÇÇ·ñN:µmÛ¶'N¼ï¾û.½ôÒ£>}î¹çÒÓÓsss7nŒfÍš<x°¢¢¢uëÖ{ö쉉‰ù2’¥ŸÎ;ñïSO=´¢Œ1âxüË_þ‚‚‚‚æÍ›yä<xð„oÞúâ˜7oÞ]wÝõÀœp¾âËFBBBJJÊ›o¾yþùç?óÌ3uëÖ­ù¨¤¤dçÎéééǯW¯ÞÔ©S¿÷½ï=÷Üs§EŽ5óñ\c£F¾T_xôš"J÷îÝ_yå•€ÔšSè :t†ùÝ AƒÚµkççç·nÝ:66öÀM›6=êÌÍ›7§è¥¤¤Ì™3gذaO<ñDRRÒm·ÝvÊè5jÔO~ò“üüüÇG®¢*** ¾øûO~#{¿~ý¢¢¢æÌ™óøãßyçAéè¤cÈ!EEEsæÌyðÁï¿ÿþ ê¸eË–ŸÿüçǦœ››ûë_ÿzÍš5_1ñññƒNIIéÒ¥Kd¡cÇŽéééóæÍ{á…®¹æš à•W^Y°`ÁŽ;/^<eÊ” <õÔS§~ddd¤§§/X°`õêÕ=zôX»vígèS×®]“““çÎû«_ýꦛnZ¹rå—GØÆõ«_mݺuàÀ§þˆš+®¸¢M›6mÚ´™>}úÍ™>}zAAÁ!C’““»víºjÕªéÓ§ª~ê÷Á\rÉ%¿ÿýïïºë®† ¶iÓ¦Gõëן>}úO<qíµ×®Y³¦_¿~ÁìHLLLMM­i8er<xðîÝ»§OŸþµ¯}íž{î‰íÝ»÷Æk¸9‘÷íÛ7}úô-[¶ôë×ïÔ±=xðà½{÷Ι3ç¾ûîûÖ·¾UCêÓO?}ÔŒ8¤~ë[ßêÓ§ÏwÞ¹xñâfÍš½úê«Ï?ÿ|íÚµÓÓÓ;vì¸dÉ’éÓ§:ô•W^yë­·ÆŒ3mÚ´;iÓ¦§ "ùçº'6vàÀ¹¹¹sæÌ¹á†~üãµTxòÉ'×®]èꉧ[wéÛ¼m§âÒ²¤èÒîÛoÛ¶-8àç_¢²²rРA™™™•••™™™¬S§ÎàÁƒ¯¹æšÊÊÊ­[·Ö«WoÒ¤IA,ÿ/WUUU]]]«V­£*ŸˆóÏ?÷îÝùùù5úîw¿›‘‘1hР‚‚‚‹/¾833³k×®}úôIJJ4hP£FÎ?ÿü¡C‡})***--mÒ¤I||üñPRCOË–-kîÕ ˜3~üøFmÙ²åСC×_ý…^øÏ!::++«mÛ¶UUU]»víÛ·ïñ ¬°°0:::55õøÉ«¬¬ìÛ·o·nݪªªÚ´i3dȘ˜˜ÌÌÌfÍšåääÄÅÅÝqÇyyy­[·8p`VVVuuuZZÚàÁƒ“““R¯¼òÊäääM›6EEEÝzë­‘ææ³±mÛ¶ÔÔÔzõêÅÅÅÕdD?›Ô±cÇöëׯ¬¬ì‘GIII‰‹‹4hPË–-Û·o?dÈêêê  <855õxÈÉÉIOO¯S§Nllìq‘‘‘ŸŸŸŸŸß½{÷K.¹¤°°0ˆj'OžÜ´iÓ=zäæææççgee}ë[ߪ®®NOO<xpýúõR[µjUYYyî¹çöêÕëx(<tèÐŽ;Ú´iWYYù/kk×®]Ë–-·nÝzàÀ+®¸âª«®êÛ·oݺu7n܈²_¿~5³côèÑݺuËÍÍ ${ÊäXC@Ó¦Myä‘æÍ›0 àê9çœóÿñ5r¼úê«#'rzzzÍìø\!N«V­jÕªSQQñ/ÿuuuVVV`è>Ô+¯¼òÝwßÅÍ7ßü/Iý\¹¢¢"''§]»vÇ)ñ�UUU]ºtéß¿Ê%&&6iÒ¤S§N;vìÈÏÏ3fÌ׿þõ.]º|¢Íù—ÈËË«[·nRRÒqZà%¯®®nÑ¢ÅðáÃ/¸à‚;wæçç·oß~òäÉqqqõë×<xpÂùÑ~´}ûöûï¿ÿøs§ëׯoß¾ýþÒà Vo¯8\¾¯`{Ôˆ«îî?ò²üÂÝ-c o¼âÂ>øàôžX·nÝ3äÌÀúõëŸÉgž™ä»Κ«]»öé=30>>þ ?3°N:ååågø™§KŽŸš3ãââ¾à™………ÿöoÿ6nܸË/¿<++ ÙÙÙ'=ÝœxFI¼æÌÀ“~¥øÈ‘# —.]úy Î Ì),ùÅßæ••mY>ïì©gqgqÿDrròÀ¿ýíogeemÞ¼ùøÃYž|ADEEEGŸG{–›gqgqââân»í¶SÙžð¿3gÎ<Y¯:»º:‹³8‹³8‹¯�Ž^]EGGÕ2Šè+áøâíù_EEEIIIÁÏ‹-:Ó¶k×®`oÀ¡C‡Î@òŽ¥687aÿþýË–-;õìÝ»·æ‡?þø dQdY{ÕªU§·p{ÆÊñ³QSkÙ¹sçºuëÎðIÙ ²víÚýû÷Ÿ T¤¥¥¡¸¸ø 1,ÇVIpW111½{÷>-¥¿ÊÊÊ I¦²²òïC: éééA«eYYÙé¥äÓÈKIIAyyùHÞ±Ô&%%UWWíL§…€zõêUUU?Ÿ™\ ÄòòòäääÈ}TgåxüäÕªU«²²òÔïb<1´iÓ&xRRÒiY|"SSS««««ªªÎ¦§§u°HìQK«FO'è—„¨¨¨¸¸¸-ZœØãÕÕÕ'ñºúÊÊʦäsÑ üž=ä,ÔªUësQûEØòi.á³ë󡪪*ØH~&#..®yóæ'Q.'uëÖ=Åþþ‹(jUUÕ9ïõK";&&æÌ1,GQxt2011ñÌl¥ý—‚­¨]»vLLÌqne8íØ»wo\\\\\\íÚµƒÀYëÚòòòØØØ¯¨6b×®] qqq_mü—ؽ{w|||BBB­ZµÎª+>\\\W¯^½pVŽ'Ñ<µ;öX»ffÏ?5[PZZúU±q3gÎ=zt\\Ü¡C‡Žÿì¾ÿõ¨Ù[öÕF̘1ã’K. 4óxöÕ~%ðæ›oÖ êøwÐÿ/F^^Þ¶mÛ‚ÝÁÅÅÅ_wõU‘ãÌ™3kÎV p¶3ð,Îâ,Îâ,¾8ë®Îâ,Îâ,Îâÿª»*,,¬i >~ìÝ»÷T^üqGaß¾}ÁåÂgqzqðàÁ‚‚‚O»Xà¬%%%§±wìKšEEEglî±Æ’—––œÄdø—⮲²²&NœøyŸš8qbpH×Yœ<óÌ3ßøÆ7Îòá´cÚ´i™™™³gÏ>±Çïºë®=zœe#ž}öÙÌÌÌ3'Öç<òHffæ<ñËÃÓO?ýÐCá…^ÈÌÌ<‰õNÎ!L/¾øbQQ\sçñòåËß{ï½+®¸"==}Ë–-Ó¦M þ~÷Ýw¯_¿~æÌ™cÇŽmÖ¬Ùo~ó›Î;ÇÅÅíØ±£¬¬ìµ×^ Ê€§©HLL¼á†-Z4þük®¹æ¥—^jß¾ý¨Q£Žãï~÷» ´nݺfŒ§˜æ¢¢¢š; ¯¹æšÔÔÔ€«ˆ‹‹»ýöÛW­Z5gΜK.¹¤yóæÛ·oíµ×†Þ¹sçßüæ7A¼3jԨȻϻwïžššZPP°jÕª¸¸¸eË–Õ©SgäÈ‘¯½ö>QŽ˜?þ¢E‹^uîÜyøð᯽öZp+`÷îÝ tZ&Ì–-[‚–§FÕ«WïСC5¶lÙ²²²²¨¨(::zÿþý1115ÊËËC³fÍbbb¶nÝšœœ\QQQ\\ì9]xñÅëÔ©3~üxËÕ£ä¸{÷î—^z©ÿþ5 €:uêÜ|óÍ5óñµ×^kÞ¼ùñŸÕ}²$2mÚ´Q£F[P¯¹æLŸ>}óæÍ4GM«Úµk¥ä5/<|øðo~ó›àçH%þrûí·ïرcþüùx饗&Mš0§W¯^W;uêÌŽ·Þz«Aƒ§Þæ`Μ9«V­ æN¯^½ú÷ïÿÒK/¡W¯^3gÎLLL6lXAAÁ_þò—ÁƒoÞ¼yÏž=W­ZŒë–[n9õdæ©©©×\sM`n¸á†²²²€Ôž={¶jÕjûöíï¿ÿ>þú׿vïÞ=..î‹õˆôìšY¿~ýÏÛ+òì³Ï>þøãcÆŒY¼xñÿüÏÿôë×ïOúÓÞ½{fÏž={öìÞ{ï½¹¹¹Ý»wòÉ'÷ïß_YYùo|cèС-Z´7n\|||ïÞ½ß|óÍâââ«®ºêlĉÉ`íÚµ“&Mª®®nß¾ý£>š°~ýúÇ{lãÆ©©©O=õTëÖ­gÍšuÔïºë®Ù³g׌ñâ‹/>jGÛñ`ýúõÍÑÑÑŸ7eqï½÷Î;wРA/½ôÒ{ï½×¿ÿ{î¹gÏž=çœsÎüãƒîß¿ÿ¡‡ºà‚ 222–.]zûí·wïÞý­·Þúå/9zôè¹sçþýï6lXÍõ3>úèóÏ?á…~ãßHNNNKKûÁ~PZZÚ¢E‹¿ýíoŸ(ÇÚµkßÿýÉÉɳfÍzê©§âããKJJ~øá<óÌ3;w>='pIÊQ\Ý´iSzzúîÝ»óòòÒÒÒV¬X±wïÞ lݺuß¾}uëÖ]¾|y\\\||üÚµk+++k×®››»k×®”””… îß¿?>>~óæÍ‡>±{×®]›™™ì»ü\Ï®^½úõ×_ßµkWË–-¿ÿýï7lØpíÚµGqõå—_>JŽ<ðÀ¢E‹ªªªfÍšUVV6~üø{ï½·¬¬,33ó?øAuuunnîÃ?¼~ýúçž{®¤¤$ð‚'<¨ÏÛ|;oÞ¼»ï¾{ÕªU­[·~ì±Ç’’’¶oßþï|§GEEE?ÿùÏ;tèðúë¯?ùä“]ºtyúé§ÿøÇ?^rÉ%O<ñD¤’_~ùå5/üÞ÷¾÷òË/1bêÔ©3gÎ4hФI“6nÜØ³gÏ_üâ;vìèׯßܹs×­[wþùç7mÚôúë¯ÏÈÈ0`ÀM7Ý´zõê´´´‡zhݺuM›6}â‰'7n|œWE¢¸¸¸¨¨¨Y³f'¦¨O?ýôSO=µoß¾ÒÒÒçž{®[·n“'Oþûßÿ¾xñâçŸ~öìÙ|ðÁ…^xóÍ7¯X±¢yóæ?ùÉOª««;vìøöÛooÛ¶íŠ+®èÒ¥ËTÎÏ+Ç+V|ãßHHHhÓ¦ÍÃ?œ””´téÒÇ|âĉyyy7ß|sÇŽÿüç?¿úê«·Þzë{ï½·jÕªaÆ 4èN¹=ö‘“ 9räßþö· &ôë×oÑ¢EÁfM›6½é¦›Úµk7cÆŒ}ûöÍ;·K—.&LHNN® Ï#Ñ«W¯ôôô„„„óÎ;ï ‹-êׯ߄ ‚†øàï—_~ùرc·lÙ²råʹsç<xð3ÆxêóãÓ¦MÛºuëÁƒûÛß>ðÀ)))ßÿþ÷ÿó?ÿs„ 3fÌ;vìøñãxàÍ›7?ðÀãÇ;vìŒ3&L˜pî¹çfggïÛ·ïØ7oذ¡^½z&LÀÇ<a„`Œµk×~ôÑGŸ|òÉ9æää¬\¹rèС7ÞxcM䕟Ÿ?~üøóÎ;oíÚµ6l8õÑßÎ;>|àÀsÎ9§S§NqqqíÚµëÙ³g‹-‚+YQRR¸Ò¢¢¢-ZÔ«W¯¦””Ô²e˸¸¸ÈQO1FŽyÍ5×ìÚµëÃ?<–«_|ñ_ÿú×H9N›6-##㦛njÙ²%‚{õêÈqÖ¬YÁkg̘ñúë¯ÿà?8-ƒ>|øõ×_¿oß¾ììì^½z½ð wÞyçèÑ£7lذfÍš€Èn¸¡f8mÚ´æÍ›O˜0!##ã(»1mڴ¼¼¼Ÿÿüç?üpTTÔ¬Y³233'L˜Ð°aÃàÁsÏ=Ÿq#Ò˜1c®¸âŠüüüÓxìÐ7Þ8tèЕ+Wæää`ß¾}ñññAtXóú÷ïà 7rìØ±cpeÔi¹éiûöíË–-ËÊÊš0aB Ç[o½uàÀ&L¸ûî»/¼ðš0¨qãÆÁ•o£G>Y÷¬ž„·Ô©S窫®Šl¯¨W¯Þ)»ÈòKBfffä¯ÌÊʪ¬¬lÓ¦MpCöéã¦M›Þ{ï½»îºëßÿýß_|ñŘ˜˜ üìg?KIIÉÍÍMKKKMMÍÌÌœ>}úúõëwìØqõÕW¹”ÜÜܬ¬¬ŠŠŠ6mÚ|®»½£££W¬XqÝu×5hÐ`ãÆ‘èuêÔ)òŽ7.::ºM›6‰‰‰§ž3 (++›7oÞ–-[:uꔘ˜xèС ÄÇÇgº?>>þ¤ä.¾Ú´isÔÉH®Ö­[wøðáiii»víŠü?M›6­9ñ?ûÙÏ^|ñÅÄÄĦM›ÖXùœ®AµjÕªævù„„„þð‡999G…zõëלVï¿ÿ~VVÖáÇJº|øá‡+W®œ0aÂOúÓŸýìgMš4Á+¯¼òî»ï:t(ðÙÿíÛ·?õ7V…N:E¶Tdff¾ôÒKqqq‘rlÞ¼ù¹„÷¤#[Û´iÓ¨Q£¦M›þú׿¾à‚ RRR~ò“Ÿ~I8 ««ûï¿?///;;ûÛßþvÍwïÞ}<Wk×,ej°k×®/õnõãGp—h ²³³_yå•É“'‡Ìž^Ì™3'))é'?ùIƒ ®¼òÊ 6|ûÛß¾í¶Û²³³klÓƒ>اOŸ«¯¾ºOŸ>>ø`EËÎÎþãÿ8yòäÏUrÛ±cǤI“®»îºììì£.{=JŽS§N}ã7&OžÜ³gÏSÏ™½{÷–––öîÝ»nݺ+W®,))Y°`AÆ ‡zœw—””œ»¶#¹:qâÄ:uêdggßqÇGåy"¯lŸ4iRvvöO<qÓM7ù\ÊIÇ’%KjŽ£ýå/ùöÛoÿùÏ®)A}¢4hPvvö³Ï>;yòäÈÿ–]VVöÌ3Ï4iÒäŽ;îØ³g®ºêªììì§Ÿ~ú¨&…š¹¼páÂÈ[:çÏŸÚ÷É5w¢££3T*--]¸pái¡yòäÉÙÙÙ“'O¾òÊ+×®];qâÄÌÌÌäää»îº+(FþK;ÚÜÕe—]V·nÝ)S¦äååõêÕëå—_.---..~ã7–/_~ýõ×§¥¥]~ùåóçÏŸ2eJaaáĉ;uêÔ¿ÿW_}5’ÝW_}5þû¿ÿ;77÷T²¾eË–#FŒ˜1cÆ”)SêÖ­{Ùe—_·nÝïÿû€Ôš1~ç;ßùÝï~w&µðþûïß}÷Ýk×®MNN¾ùæ›ÓÒÒÆ÷î»ïN™2åòË/ÏÍÍ1cFÀÕ† ¼Åõ×__ZZ:eÊ”|ðå—_þ\F999¹FŽãÆ+,,ܰaÃQr1bDFFÆ/ùËG}ôé§ŸŒÈ)FIIÉÒ¥K ããã7n\«V­ŒŒŒ¬_¿>)))66vÛ¶mŸý†òòò­[·:t(##ãLpTÇrµFއîÔ©Óïÿû›o¾yõêÕ¯¾újÐÔ´iÓÑ£GÏž={Ê”)wß}÷¦M›Î„äää<óÌ3 6¼è¢‹† Ò®]»ßüæ7³gÏH r€‘àæ›oÞ°aÔ)Sî¹çž£Z%W¬Xqûí·/\¸0Pï´´´«¯¾zÑ¢ES¦L¹ýöÛW¬XäÐæìÙ³'˜³fÍŠôO›6múío›‘‘1bĈÓÅ“… ¾úê«©ÇùÈèÑ£›4iòì³ÏnÙ²åSÛ®]»Áƒ¿ñÆS¦Lùæ7¿¹uëÖW^yeñâÅO>ùäc=öÎ;ïf'@¯^½ºuëö‡?üád­@¢F\uwÿ‘—åîn[xëµ—4iÒän>ž9sfiiiFFFllìÆ‘––Ö¸qã+V :4%%%???h&Á¥—^ŠU«V­[·nĈ³gÏÎÈÈZoÿñ$&&ž@;û¼OzãÆ~שSgÔ¨QO>ùä÷¿ÿýìììuëÖ5oÞ¼wïÞ5cD×®]Û¶m[Cê’%Krrr.ºè¢hµ˜6mÚèÑ£ƒs?o8_ZZZsïÙˆ#·oßþÑG¿FruöìÙ‘³ñ7ÞøÓ»wïȬËüùó  4wîÜOcaaa Çà+š7o^§NuëÖeeeuèÐáÆoüÙÏ~–ìºhÛ¶m×®]O@)kaª_¿þ‰ÝߟT¡’““k×®]QQ”’’RTT ?H©ÄÆÆ¦¦¦îÛ·¯¬¬,11qΜ9íÚµKOO?xð`b: ® •••ŸwßI Çþýû§¥¥½ñÆåj Ç:”––nß¾=HçÎ÷ìÙSXXxÑEåää,Y²$ÈmŽ3&Pò`>~ÁAUUU}ÞEÉ?þñë®»î¹çž ¾=PÈùóççç秤¤´jÕjÉ’%YYY}ôQbbâŠ+¾óï¼õÖ[;w>JÉk^XYYùÆo?gee¥¥¥Ö\T_3?úè£íÛ·_zé¥5\]¾|y|||NNΤI“^{íµ’’’³9"aª_¿þ Â4iÒ¤^xaݺuÙÙÙ:tèܹsà’k˜óió1X¯”——M˧RŽA´&&&&Ž1"°ä£F*//HÍÏÏ/** ÎOú‚æq̘19…%¿øÛ¼²’¢-ËçwuÚñÝÕQ¨qW'Ð,tÊÜÕ™€·Þzë{ßûÞ~ô£ž={fddÜxãO?ýôíwW'ŒÒ_èl�� �IDATÒÒÙ³g·k×î¨Êå©tWg,NŠ»úŒŽÄûî»oýúõS§N}öÙgyä‘™3gµú//¼ðBஆ rÂ/9)îjÇŽuêÔùªÈñTâXwë,ŽAZZZ×®]Ï{hÎdŒ9rË–-<ò®ºêª“â«N/¢££ÏŠþ¤#11±k×®‘íÇâ¿þë¿.¹ä’`ÖóÏ?ÿåù*4hРk×®§÷v±fÍšuíÚõ:¼ÿÏ⬻úÜpà AÛèYüK|ík_ûÚ×¾ö¿f8 _$Ü>‹OCVVÖQ½KŸøŸzÆ7nܸÓË“‡z(8ýá,Ž7š<Ë‚³8‹³8‹³øê­®öï߇•FD«.\xZÒN�û÷ï~زeËÇ|VUò²²·ß~û+=–¥K—'<ý/@Í,[±bÅ¿ì®ü¿€òòòšmFsæÌùªœ¥ûU‘cyüTw¹›ú+„˜˜˜¨¨¨ƒvéÒå+tmlllEEEZZÚW”í_âã㣢¢*++¿¢l‰ŽŽŽŠŠ:tèPûöíÏ„]z'QQQÁ Z·n}æÜ~zURR\ÒxVŽ'Ý<~ª»*++ûêÖý*++KJJ¾rdGnZ<‹È¸õ„oÐ8PUUõUÔÆÏFuuõÿ¾A}A>|ø+×ùù’cqqqdªìwõÿ1³¼¼6oFü-™T6‚Þ|ñQ]Z²:üµ>M8ž³ú‡PÈAŠØ}̧Égº/á¨&æOûÆó9Èû4£’Ï{Î[0ÆòèÎ^j6µCnMûèF1ì8ò =Øþ{¼êÂF"›ÔƒjH­GoÞù$…£>Ä^D|ãVØJ ÝXº±šº¡/àm*h>øièF]æ…¤žKI²†à›£¨mL ©¬&˜ÃèΫT|’eÎ'"’ÔFákЖÝt¢„Ýô¡˜ñ`[°ˆ^ä©«ÇŠ£i¼~cýRÛҌì5§;û¢EU™ùIº:޹¡®vc3ýx›äq˜¶GÊ1’«’WÒ ìc7•áÛZ±’Nl¥S„®¶§˨d7í"ÞÙƒåé‡àÁ^Ÿ9æ´=f>ÖÐy.é¼OËâÀŽÐt CÈÕ­¶2 u?çóf(Ç}GŠãÑ:‚Ô@å:ñ!­Yþ¯t© ), ¹º›AL=’9MhÈR02Zƒ*óB•«ñ` Xʱ#}Š®Æ3ÆH»ZÜ@Uò#„u”2ÔüÚŸ ì"•D6‡ÏN=’9",Àá®&Ð6ÂÊ…úô`ã1VîIŸ}ph¤±B\ÈU¨_¿þà .ÿdwõ¼¹{wÓéÅv Ȥ;»¨ä݈ ™Á*†°˜hš°$0O«õá/ bïùQcùH寃¬b$aUHù¥d³–ýd-ý‰¢6ícð`äA®÷ð'F±˜f|@+º³”<6°—*ºñöQÂa6ó1ëÉ¥/ó ŽºéH›èÀ|ö3Ÿ\2m ë9H[bYËҜ޼G99!¯‚"‘J[|Ò§¤“ÈôæmêQI]ªy‡T³žUÔ¥!)tä^JÉ 's"˜3„åŒ mϳŒþ,`# ÜÀ¢¨Ï'•Á|DCFð$9‡w#Äq”æÔ0ç(\ÝþšA;¹…4¤˜Å‡tî¢3%ìbõÈ¥!q¼Ç¶°“2²˜Ž,ac¨®hN%yÔ Åñïógú2‚ù¼Ï@6RʇDÓ‘Í, H6¶êŸBÆ8„d0ƒ©áìTh0±,á}jq5SÃ1¤Ö#•åœO6UÜH:)ÔáU>`$eñ.;hªô22XB»h!©M¬ç\Þ¥39äPº«¾Lu5xÕAšÓžE…¿8B7Є¹œOÑ'É£kB7ß‹?Ó™.”06a¸Ÿé¡÷Fˆ£+³#4çð Úp.3)¦ }ÙM þúÔ‹rc”œ*{ÉàOdP5¤°‰,à ø0ÚuÌ«²‰öìŒW-½Ú¢EI­’MSŠc%tf)éÊÛ”SBÞb ¦69Ä9Æ2Æò뺖٠dy4d9+ÙÆI}™M>qÌfë)¤!‰G–”ózÈÕ@ŽZðNŒK+­ œ÷¹<Ôœ!s"ø¿@â›H§9Çyp/j1/üµá0Z!tæƒÐ]­x­«}ÙØºuâ==öÞ†¾ðˆ Dd¿XV¸µ Š9L);V#ù0"Â:LaèÕײ7Â¥Ws(TnLŒP#¬cç1˜÷i@Vh›nb.ËÙÂ%¼¾³‚ìpÔ?峑^,`l(È=ì¦:âÁîb YÄJÙ¾³„lå fGîa¶ x Yìà2¢X2•”²™,&/äÉ`f0˜=ìãZ–Òr¸ŒyáÚè¿ØÊ0êHFœ<F£û˜DBLåG30Štã-ö1’iªNýXß­ò2Ìc<™ÏDÖP‰|Èa.çÍ|HEh;²)¤k(âM–‘I;ú°‹K™MCø˜íœË~^&™§ØÇV&²0äRÛhÀ”‡î2–SJM2p?ÃCNn#"ʘD}ê1–aü?ŠhÉÜÊk$²›äREnf®c=%\ÌPR:¿ÚÜÀ%dó&x—Vta)c™K{Æó"ù¬f+×Uí¿#¦À$³ˆ<ð iœÃvFðãÂ0ÿV‘ÄêІc)E\Î\6±'Öתü*JiŒöÕþÈ@„Ú2žE, CûÀ~­o”¦Õ–yªÙF’Ja'•TÖqˆýTQÂs)óØŠ£-™¬bs—¼Ëz~JSYÉ Zñ-©ÍVö„KÛJúñMÂo¬ ÍÙ¹<À\ÒiÏ ³Ÿ6œÃV®á5 8‡ÑtäŠÙÃ2Æñ<Íe,ˆÒˆ$š0( ÝzÑ—·CŬ"Ÿo1•íôeiè ÓYÅ’j‡Ic;‡ØN]ê°‰;èC³ÂWd ;ØÅøݸŠ|ޱ„KÙLj8‘7‡?Tð%aØ]ÁǤ҉%Œ`%±-´ÉMh®ü‚Øk/¥\GÍ1}ÛØC1k(à ºñRø»\Ц` »ØC9Õ”…_—ĽÄ™Þ8¢&Ã~ŠÃ‰<—=჆V.0kåጋe(+ÀUl`[éNI©õõ7×\ r”»z§¬¬ŒZ"–ÃD1„T¶³:Œ}jqIŒ +Y¼}¤‘-%žZT±† ˆÇ8Ø÷x˜—Øf'ÖDrYÈe”ñM6š­g-­©Ï!:1bVSD —1ˆÌ¬ ’jvóW6†BŠ¢ˆÛÉç6„k ù€å¢˜RÖQÌR6q±áêê 1ÜÇJ© ‚TÚ0|öR%!ÖuU~Ç~nãCz³>¤](`ø.uÙL¹»ÙÅF–²…xªhÁpvq˜×ÙÇǦœwéÍ^â·Vù9QŒd;³Iç‚Ðt® ‹Ù`;ØÆr¶“ÌOYH4;˜ÈlRéª~I˜NÙF.ChÍp¦q€í¬¡xš\ÊÉ¥.°š›YLKC,ªŠCA<D6 ÜÁê‘Mu¨`8 YLp…º"1e × Ñ"…û˜F5q¬e4K‰&– êÒ”ŸÓ›ýäq[¹”7x‡brÉduyœ‘Ts˜ b#·ó< ©ÏB¾Æ3,e¹ô Š'YÌÞ0‡³‡ÂH3–SÌ êq+«Ì b‚j‹ù˜Ñ4e‰4g3—±’ld7Í«µ©6 êóõÐ/¡¿æ|’™CûÈ£ŠýÄÅŠH`Ô¡*´¡iIJ3´Î•\Ã?XÎVöó.K¨¦¾TCgf2’ÜÍ9ìäF3–´â÷Ds1¹¡nì§ -Èâ|Šù˜4å¹0tÂU<Ëx’(a.¨G³˜N ý˜Æ¥,`1;Èá‡(§ï°6²†yì§š}t&† ÙÃN~Ä |È"*ØO%BCG7ê3;Ì<¥1ŠwÙÃP6qç°‘"Îá;lb?W“Mt˜8­E >d™ÚØÛø˜F´`Sh?k° bUZÅ}´`.åä³œëøˆÑ\êŸì¢X>¸?œƒ‡éM.`={¸˜ÇÔ¾ÎGt¤#BµÉ ]Ô!6K4u(¥8üƯñ'ºÑ’w#r-%T¤¤¤|†»ÚVV¶ƒN¤Ó›í ç<°3FÃ0=Úˆ‡XÈ 4f=ÂLT'Mg ØG}FPáÉדÇë$Ð Ô¼`æìeùäÓˆÕ,¢-{ÙÂëaÈü6kXCsJiG Åìe&Õle.%ÜÎ~Þ YŸƤ‡y34ô{iHÕl¦#»ˆ¦»¨  T’N?–‡ ¬¡4¤{iO5ÿÆ[T“LeäVy7ôš{ÂÄT7Jx“Rö2€5T²•óBÝmÀ߉¦E2½(a8oËVŠ©¦çq#E\Ç~ÒÂÄEà 7Ñ•©¤˜ia”ô×P(ãI¥/yáòô\Þ ·=¬!‘…ôd-Y´£šK™E–ÑŠáÌ …ZŒá4b;ż°¨³ŽBZ°“ª0x/<²J±™D±“_€¾\Èj²‹þ”2,¬¹Lî–ÐV2–ÜB 7RÈ|:q[Èà6jS/4¾ìd8ÝYÆë4àeâ©Ã>ú“B uØÊ‡¾œ>ìæMp=k(g{Iay¨·KId…´¤]éÀ0òGúCpD^–Ñ””s.‰ñ-¸›Z4ç·$3+T¹ƒ¹µ²x‹½œÏï8DgÍ^êS‡†´ 'ÍÂüÒµì Ó'»Ž—CSUZɹˆá¼C[s€ ¢þtçÑ‘$Úó$•,cz´›ª½ÇŸÈãaV„IŽÝ”s–4æ{ì  ü""ͳv°“6sAXÌËc +ÌËázn;I\K=òhÁzöSAÃ0|©¤’64`7ØÍU¬§!ûYÏ^†‘KI çpy!ÊÆ( ØÉ•¼O4 Éã#ZðÓB…¯K6qÿE"™O%Ã(c$‹ÃìY ¿K9…¡ìjìj#¢Ã|Œ0ûõ}ÃÊËEl¡G8 …AÒ8Ú²–a ÅT‘ÂAÞärf0û“jÞ{ÙK,bñ4 óÌm9º€,'‰ó(gfèYD,‡R®¦¤ô¹úúK>Í](+û˜a–#ŠN¼ÑÝÔ½Ï “,à\Þ£6-¨&pcéH5«(§!åG¾GDju8Ëèź†±üv‡¹¯=ô‰(fྈÕî-4  ‡ÈçÛVZÓ‡¶lfNøŸÈßÁ9°+Ì•ŸË妄¦, Œ\Ë\FÓšºì y©ÎMTó&1Tr«èz j¶Eim|µ½ìç>ÖróÈc�e4äºÐ’x沞†tšë§š„9õ ¥…!18@iü„ÒI#“]d0‡•ôcÛèJgK"1Äs!sèI…au³‡èÊFâiÍÛ4àb Bn,ãC’hÊ Ö0üƒ*bé̾ˆð0Á:‡ÉÇH¹!mÉ 3“5É Kyn˜¼jÄXÒƒ& æ÷¬¡5 Tó�9,ãY¢Ø.­¶Ñ…Vðú²öÄÒŠ?†%±ƒaDýðw3\6Q‹þ$„Q]kvÒŠW(á&j³9ô] ¡FÉ3øò&ùaÉaܶÇ-¬ç2öòïSÅ^r9È«¤s?Ë2RÃiT563šáƒAÀ[H'6Òˆ>4£1­Y A;L5)¬ #ßOÜ©³$l¸žbòÂåì|ȇlb 8ÀË,vMµR곿²š–Œ$‡s(£3³B§57¢âÙMÅûÔ§?ÓØÃ:rù26Ñ‘ºt& )£œÎìáæ°Ë`jÈŸ@Dz–4ö±œDZG7¶’Ë@°zÜL–ñºF¥Iµ-¡?ìj¯­XÉ2Y͹lgô§˜]DÑŠd²ƒ"Î%š®l#¸¼-—Ý  ÛiMçp ô…«Ã\å ʙLjòÒòˆ>†&äDÌÇnä†Ý 9td­z�ÛìHØæ²XöÕbChN«YN=†°ºì§.£9Lc0”VA›’2øêë‡|š»úáýu}ÉJ¶…ßWƒ]¡*[GƳ‰¾Ì%ŸÂ`!­(dB‡|ihGZ†ù´Jö°—kYAmք߸ƒŽa†¡kDê3X«Ö4QÎ[ä“ökµg'u8̨ß¶…|:p=+•Vcư€Böf,ËÙÊn³ Œ’¹‰¥Ôœ9™™ÄC!¥ü)LaçR%!J£j½èÏ{|LýèO>¥$’fz„Ëó*ÊΛ!¯J"F=>dT_ãŠÂ^ƒ5a­k«h ºäãhG‹ÙÍ0ÖQεü‰¥”RH £y•Ä0Ýt¯4d5iL)‹Éa èÎËlŒqOµ9aUÐQ›÷"t 'yìŒðUŽôUÎ'–1œ{da¯Šb°•8–„ñ.¦c©¢‡hÉ¿±[(a3u¨¦˜6$†®âFÞgsØR±Žt&ƒõlˆx0ŽéĆFµH¥+MX–ª©b*YaG·pÁ·™¨ kÇFºQ‡òiÍ¥ #• ØÂʰ+¡ Ï„³ãRJH¦=YÀv6PHåì¡=#¹’ašº˜á”ÐÚ²Ÿ[Éã}>b% ìe4=˜FÐã­0£PtdL,7†6·1¹ô&›,RJ£IfWèØ‚.ƒÕj³—¶0ŠfäÑ•õŒg*ˆæNð=‰ B´hƒ¢´¯ö‰æ"ŠÙÄ(ÖÐ-,SiÞÚ¬ãA¦2”î|¶h%É8ŸÚ…4|H. WùÛIg™äM1›™Ä<q¥ eÕ:SëÈ„A††ÅŽ},¥ Ø.ï>$>Œ†Ñ‹9TSÀ!¾ÉXúªÈÀ®‚ü°$ß=rÜA4ÉóÑ1rlÎ:òðÓâ8x2Â%J n0ª‘37•˨ϲ°Þ¼*XºßXA :Q²q/s-mÉc»)NIéwõõ>£vÕ€!,cDØ9Ö´ÏìïËÇ䇥³Ýì¡CxÝÔçbV†5Æ‚0]PÎ}\Öý6qEȬ±”²òBŸt©¡-ΧCXÏ(Þ£w“ÏÔ ½×6¶±>"up1ùôãU6‡8Èj–²²ÐWµ“ ¢¶-œu]:ª"80—bö‡9ñŸZFWT[K 0ŠT0Ÿ\®b�SC¥I¤=‹¹ŠŒãØÉ6q˜¾¡8ªéæ—†%ÍODàÆv°›2òCþïà0‰ÑîŠv]µ¥¼Ç-t¦šËø˜ëiÄÛ!£ÚÓ˜é”rØ?;©‚o…­•;Éa¥ 1ãÈ ×‚=éμ#;qû‘=Hc™ÁÁ°^E #Ž=aM>èÙ–ÙWÑi¬ ã­ ïè�Ã(f>êKHмÜzÖ±<œl¨Ãýü9ÔÒ?Óˆ6ôe©ÜÂ.–róhÍHf‘Ã5lâï\Ë2ºÐ– c½IäeÊèÁpˆ(‘ư°íð—¼Ézús’Îÿ‰Ì£¬c ßã7ì ß¡°êžÇZ–°„¾Ëߨêp±a;Àò0;†)#úb Ïû4âëlec„þýÇãø;kÉeØÄ4œ1¼OS¾NK†Æ¹­êŸ•ÿmàë¼v?K¢üpѰ›),§!ÁmÂoQÆnaH`=9Ä:Ö„i¥ôânÚÒœ™áƒkbýºÊ*fq>cH&–XÎåý«¹š$f…AÀøp´ŒbŠ) Å4&”Ò’X6r€.\~Æ AõkÛC+4à}àŸáì´¥ ÙÆ&ó£ÙL‡°7{"ciö£çi¢óCAj®dS„1 jª¢ŒÖ»Ú{ì!1,BW²7l‹Ïá VÒ–nla=?bz8¯ Ÿ!¼Ç‡äÐ èîc"ËÂåJ°hÞC*IÌä`Hê¨X÷Vù5‹Â’С””˜«¯¿¢Æ]qÕÝßýíÛ·üðåÇþó©©©D… 6§¹$âÂjm×7:²çâ®cÊnÑÄ„%Át&P—ºD…Éô‹èHmî$‹á¡±~”ËÃÿC2uI'6lJÁ£¤„¤^ɳü˜xRˆ¦ß û/äñˆž¨ŽÄP‹d. 5_§5K§ð(#Â0¡)7R—dîçqn¿å‡áÏ‘vc çD4å×ø9‰$ÒiL&†-ãÁ<Ì£<Jzø©áx³ø1í"Öà“éÊsÄ„AS:éd1†›.4êI?R¨’šrr ߤ¸‹8jqMCÞ&Q‡(âÈ¢' C9?,w=FÑD1¿qQØ7™éÇj‘ÂuĆÒTZÜvdí çGt¥¯r1xÎá§¼Æ/¨ÅX.W6QÄ’åG4æ¶(©|—ç‚¿M /rÑDs#ÍøÏˆÈ÷Uê2†'iJkÎe87ðzqÑL¢7†=©áÁÜy”†ájû.3˜o’ªhLXEhÎ]á&­úa7Ä-\Åâ î$…‡éÆ·Ïß™ªD27шfŒÿr­ù?3Á´Jç^j“Ì`²ˆ¥;Ï2–x¡1M©’êH%O+²G!PžÄpÕ<x#CC%‰ãgÝy”~ÜC-êR?J-näW!sz1‘Db‰a ß ¦4 ÂQÿ'uHçNZ0„K˜H3Q/ÜWÐ$äy°œ %u)´ -Àx¾O“®~‹ÛH檫sS8ûÚq õ©šÊ@!Sˆ¥%·3!œ\ß"=´r©!·c¸—¯S;Â"EQ—ËišÄ�iÄq.×2!4È56çë4ç£ÐÊ5¡þ‘²«±äÑŒä)†v5Yyœê[ƒH¥v„¸‡\ÊCô#•xšP›;¨–BχủµÑ¤‡Û’¨OƒÖ­Û,^³õ–¾|íÿpÑ-Ç®®JÃû­lb4/r5ûÂ<@ã°ðèe2XH2íB¤ûƒÎ…Å”°‚‘Ô ó‡AŠæã°w³^¸·® 3hÑVDOç³¹$S;Ü%̪W‘G>íÙÊh^ã †0Œ„{G ØŠ‚}iÑbª5¦‰¤‘Ã;azê"ö“C32yÅÔ¢‚j>ûd2j‘ÉR–„;Lë…iAT3Š8†ÒŽÚDñeaúhSÃÆšÑ‘i´ çÕBZ±‹Ç'OR¥}”¯ÑvwºlyDq>«Â%Ë�“A—pu$%ª¨¤!9t¡;)aè]Å6⨠ y9ÜQQ@mbè@·‡o³ø ÙÁà°�»""ÿ(ìîfä‚}¾AÖ2ê³„Ž”2—ôàUš†»èþJû0«6‚J2YNbõ­²:JA”qÕþ_˜UÉnîàGÌ XFóˆ}'cXÏn¢ÙJ=.ãeQÆsŒa»¨K^Ó}Áƒ᠆ш(ªÂ¦²¯‡­4ײœ¦¡óÞÎG äÒ°U­Y”Õ.äC~ËUì¡íèG3žáûÜË\†‡EÊ•a¶öþ‡VT3µŒ#›xúó×à|2ÂÖä<–ÐŽhΡ#Åay¦6ç„«À ŠmùIH2’8¶0’\2ØC —†ý‡Aþö¼OséÆtš‡Ûfk³¤±ˆ­¼G<W“Fe˜º?ŸKh6éT†í»›hÄ(V2Š>¼OÑô¤}) 7¡|:²“jÖ°Ÿ{™ÌfV3'">œW™Go±ˆáüáôduØ@Šýÿ»Å«N£éÆÚO2þ?Æî;Ìêò\ûþgÍ0Ì }�é¤7EštA,¨Q±`Ib4MbzÙéûMv²“<IvªÙ1Û$ÖØbGEéEz/Òa( 0”™õþqsͻмÏ:<<gÍú­_¹Ëuç÷¤¸Œ†Œ§ŒC¼ÃHŠ£ª„¡œ‹G¸6R+U‰/¦-s£ºÐ)Æœ¥Ñ7ªæ$gè`ÜÊ䆸¬Y¶‘G1{rÏôÆ‹8IýF•ÇðØ‘Q™8 ‘cìbí¸ÝlçYÖ†„çZörÉ…~•¶ŒåIÎ1’Aô()i2mú”-dO¯EgQŽ)õt¬MÄv² âèKèG38¤ ­¨â4-iRœ*Ês.FÚJ—åôÞk ܟC,£†ÉläŠpÈi¼/e…Ô‰ÖâM<Æ,Ö³‹<ÚÇ]»^±¡î‘gpÖvös#™ú¨C¬£O¸©¶„„dXEòsšWr,ü¼}hoLƒ×ê¨%æÓ”=l óà`zPEÎC™½…,Ÿ`^tÚ³#di3ÒèŸçZŠØÄ“qòs‚ºSȪUÈ–ò­ŒÝyª³ÎÒŸ ô +³£T88œÑIê–T¹ïMÞç<×SÎNÞ£'7QÌ"ºÇuÙC5i”Ó¢ÿ__yôd}8eØ2Ú°Š)âOrœa4`)Gɰ—Böe =6;j¼ÂPúgÏWÆ.f1 ‚)ЖMt )=i™SvßÀŽRÊ6º²#Ö+Ÿ ûm[Úц§BšÞXÄ€OÇðý© +#ù&ëy'd]—’eëCÇ8'jq£³Ög gû¢Ñ½‹iB9´Á&±ÕŒ‰ÞÒ&QBïŒYy&eµã,·²—Ç…ôÁ¬aõXÇ\Ë_™CYhùv3†ôb §ãä|ôÕ‹çbÔ4úÖ!²ßÃ_WúÓ=†‚t“ãñí’â.ð4ù%×Dư6á-e9£’} §ËXJG^‹Q«šv¼@GêÑ——é³i§ o�L ËMç O¶„2{Õ\M³ó08h�� �IDATØMsZñ8÷²ˆUŒŽŽ@O¶Ó’§XEfÑšçXÊZð4Ã8ÔŽ£LeYHÞwÆx²B.1§e4Ž>ÖñÐîÖŽ«É˜u¦ ^ eYíá âDNGj ÇELìŒôÆ¡¡-£cÜ�ëø ¿ÈѾ%ÿÉz³œÏò(ëéÅXVr1ÃcmÔŒž”1˜Š VM˜È %%—L›>öÿfºJ–ÉORÈÒœ§<§ôÙ’†Q3MÎáÔÄR:=ÃÉlX'Ê»“B­”ÛNŸN·óG)c4“y…|:1Ky—¼À`vQEOZÇT×›q,äÆi_X+ö•ãuã²íÉjSÔ!šÇ4–å87S?&ÎÚCÂN±õBaÌøUìJ‡•R\×;9Á~>ÇbÞ¡ùв{’Gn§(¶ØiÅVVp,n£“LbxÚeí§!C’~ˆÔáÆ0Þâ‡SHS±!£ŒÛ@'êÆ£XN¦ð eåÚŒ¢|#²ç[ÓI³Û#ãÒìyŒÐAZ3%ˆD_a Ë4ˆ”ó-vÒ#nô¦ÜE ûÉg`ìk[†}¹õl¡eÔñoæý@¨ˆQ,µÖ0•-¡˜Jãl#V³&1å$±ûUÌŽýâռǷéPŒä¸Ø³{ZQvaM£¶©Ì‰mzúÄi1ÔŽmw3–rÍy6žŽµ|‘—I!+£A›å–ðKn‹EØ9öq57…KæéÐ Ëa.c Ã9ú±’6K¹‚›©ÇS@~¸&N³œ~¬fõé˸â}ˆÞRŽÇ÷ãòhó&³8çy<Á‚БÄ'CC*¢·„îA¨æzz8ßJL&åD™¹?´¾I¿Þž¡¬äí¨s$íÒ.Ê7.£~Fû¬ÙÜIÇ�L`-Ó¸Œ÷Ù”ñõ|WeÏ÷ª7peδt8Ü„É5ÿÝèÈþ 椵uØÜE x›:³)ÊwM¸”š$cãXú…<fP—a,¤}('ăܘáœ!CwöP'*[w0 wq€Rn¦ŠŽ à~^Wb–÷ƒ2šãLC* á¦R˜£¿E=ÞÏqŽfpzÝLÝø=“YÍZÚ³3nËz±äZUâ>ìå�7°ˆÆœŽÙahô/of=EIzVR2vÚôËþÙt5¿²òVVD}³&´•grÖÂYnææ0”K.ìWp=BÎPÄÄøÉ>²‡SQpØÒ—ØÏý,`*«9ÊØœ¶ç :ðz²ör‚¶\Ê"ÎF·¶7-XÀf.f`LZ©ˆœjMg)Ï35ÏଵÜÈúp†7âYJÖ–µÁ¿ÈU£u ¥á¦ÌæøòZó«Ã>uE”>ÍK´¤/°œN|2ê–‡ø,e'G ü{_2(æ¹át ô]èË 6W}/“x?ç¬þ9ä ©nS–9?»ÜË 4çòoq7g)¤ˆòZñ±Ê?Éz.g"OÒžöYÏó>wÑœE,`&¥q U|’ö¼ÍÞíQ‰Må²s”ÆJ".´r0q©e½• |ÀF*ùïðwpopÔ01‹#ôà®(VöNò9ÂÊÆ<z2·˜è$V®LNªøÏˆ©ñýX £/1¹å4÷ÒçÅT:3# Ô;3ÞjãÛÇÍ BjInç,¥|šp‚Yl#?tØ»9KC~ÅžðN%fÒ9q9 8ÊQálBïò>ûhÆk¼Áͱ\XíÜÍ\ná8ÿ`~|÷Ý9’¨Æô§ G¸›YìaÊ…³#!³J®Ç¤˜Hce{9£ü•¬¥‚á¡nO3Ùï˜$‹´&ÛÇuLä{”°žg8@SÞá,Ó˜ËR•ö©Y-²ç I7ð§P—Ldøk¹›ÿfk¬ùîå6:LJ&m× Æ1“‡ƒœYÅClçi*y›ƒüÔŠw8É¥!ИÍ1úЈñôa;ÿA]º°™1g«Éã2ª©áJæÇÇä6vq€c¡ÔßÂÌc¥e/e”SÎf°?*:‡© "Á)Ö‡ôW芅ä`NÁ Ƴ€¡´ ÖLBö¤á1-Ü3”ÇýÜ>~²&d/{¹‡×8Énvq6ú>Éñ²“Ñ×Oæ¹SAÀ©.)ùÄ´é]þÙtµ®²riOiôÎÄFª[ØNG^à‹!áßKªÚmæn 3êf â­àrnçzÎ… sWüÚÁy{ºÌç2ñ,-¨¦€ÃlйäúhVU°7:óÈ],ä~ÅãÑZLFÅ'ÃpöpsÖÓYÃ9dzq[ â'ÌæHp½ ÝpEü…õ¼G >}!R³‚S,aÕQ“lI hæëîl¦™lf9°’ ¬ñxRË©Ï^fSJ NӂޱKþ§&ð*ÝØÈ..âæ²/Mrùîi¡Á‰ó žìe'}y˜¹Œä?)çV~ÉÞ n¿d}“¯3Ÿe c=S9­é¬b“膠a­Ê+VPM•óUÄb>OËYZp„¥ì§åÁªIvæ³TÒŒ™ü2L$r”¼F—Ð#Žqaï…‹ <·{x‚›B,›¶,³¨KcÎqm£z”›¨¤†¹¡¥ÜÒÔĬëÎ9“Ñ0ß„¬E”¸µÆÛ'xŽnuVÅaÊê*8ª W_£_e%#˜Æ¯òdòôÊ:ËNêóyFq޽üœ¯ÅL?˜Ž, Õ3$ZSïs-/²…ö|žghLS*8Â+QQÊÂè#nŒšÁŸ˜Ä׸‚Å9ë÷Ó4e$ÛØÀg£Ù¼!¼ µÆÇÄ0[Bî`-SÙΧ8ÝóMþ ÜÂANŽd ÅQhÈi¦ó®gëxˆ÷h´Ì¾üœMœb»YÉÚ¯zÑŒ/°—bf²„cœe åìf¢þù.×r”[hD?æQ¬3}C‹ôñEvð Ë)à©åÿ -x=6”·3—Ÿ1bžecP°o`  ‚‡BkÓ‘ 18Å}Ì ëñ–G“©O„~}” 0–Õ,庰H§pqF·|d½Å„hW‹æNb&¥ÕF*Î×Pɪ0&§Kƒ¨Ô¥áñX<ec©¦Sy)ÖйA¨¢nˆ¼Êãº_ÌÙ˜MwÄOåèžî*)ùÛ´éwý³éªNeåŠ�)fs6Ué˜ê°Žö¡JªbNì '²‘¤3»é”ç˳³ç'ƒl<ÃC.Q•â!,¢?UÜÇì€Áœd"Ǣ镸‚8'+1ZGâ‡(á§+¢¯øI>Ïh6„`½E8iÒ+ÉÖÒŠõô¤.Crœ^=¸”_F-å~åZç˜ÒÚp9‡sÎø˜(ŸÞÀ¶X84çRZRš”uqrNæøg“>¾ö�Fq9×õtìÍÓwü¯@ç�u•ÖéYóO˜E1˘Ç)ne1¿¥#¢9£•8ccžñY5Ýj<ű‘þ,§c8…¿Ê™KÈ¿ÅÄÓ—ùŒ¦ä#1§ï8Œ™œ¡ Gù^€Œk¿E)m8Épބӹ¿‰%TNÞÏçèÈiŽq„Qt%K…ñØ?® †ÁR9† к‰QÉFîev,uküò+­?goÐ'{Þ.=ªÆÿ“Ñ#£_Ö9*šštê¼1yGS?e]@hzЕ´fç¸.ëÙó”Ίx5´¡ %ì qÀUÓ“[iÄ–àœme?‹sؘÅq#OÒ—i¼7À‹9CÕTzód"ʳ´a^ˆ¡¾È‹Ëñ—Œ÷sl7㬦߹$€–WÆ<—¡[øFÇ®º€Æ´b5—qŽL‹Æpi{:sE”³(ª·ðSªù [™ÃgY;­“ld`ˆ’ž +R ÇHw†DÓë$÷¡­K™¥¹#,â(aUª|{Œ`·q#Åìå^þÄÙè &×i§™CÇ7hƪظ§IâïÌaÃ)¤Ù…«ýñ ù8¹‡bvÓ%ç&?ÃEæÒ†Òh†§²žg?+ãhK!0;vEM¨âÁ€sæ¾…—£&†ÇäÚ>À3.$K¢c÷&ÝìQtã�=ØD{*£cÒ€vqoˆÃûï””Tý Óï£w•ÄrÛ²2˜æŒa1¤kÓøØˆVÁ\x›|¦fmÈzÎì£[¨õ7Ò›ÓÑ“_jŽÒàÆîYp=Éç}Ú±ˆ+sÖVå4Œ‹ÅÜÆ{´ øüI®`¨ˆîe¬£Û(¡€«ÃÌtB–±)ˆX›ÆUûp^Í‹Œ§ˆÑÈim°T›îʨ@ï$ÐT ­ §£üý"•ñkIû£)¥þ, žïèhYmáJÎæpö®ª¤ihª(¦7Çr² SJ wÒˆ9äÓ¬QûfVee\—Õ&ë Ú°ˆsŒå”³‚}9;ªåÑã,c²Ž%ÿ<5`"MC¶- f¥9]«ÙqÀå\{¯:1@7¦ˆOОáy<ÎE”3˜I¼Î FRCGúМ7èD>ãYƸ aµ§†iÑONVåÌçÓ¬ »e>9ÈZ²%p>ÃXÀÚg½E;šŸòlt§.:åM&†|UÌ‹uYÇfй‚”ä»?{žH¹“Bn¢/%ŒcÜ|}´á­¨²ž;¡78š ®,_ÚÁTOk&›n$}y–ö§ˆy´¢%ûc ´û#Ö³ôŒdíã�ªãžïG½XA1×Å“Q2¹ï—n&]©%q}G ¶1%,Sï0:òPÖ°4¨BýÉD*¢ŽZAAuKù ã–<—gÑ—zö?Ëtf³œbЙ^Ìcy,¾ëÒ±³IA ýWkèż½á9!zL­ÄÝœáI)—*7ÍÖ)¡»¹Œ%|œùÁÐJ+¤z! (d0/s€úìa㨸PÿÒ!ä*«É§2¨¸z%B[9ÇèÀr:0•åüpúŽ;iuíð˜Ú‰ s3b˜ÄEœá£É²™êâЊ½«Ã‰¨´qMuŒSïêŠÿ_©Å¡X«ÖDËê$+(LÑnîŒn¢R¾mê„fhN!ë(¥!“XÍîàÅ]_š‡F“iwŒûµúA, G÷96†Ôðtìu–PÆ®ãóÙCIÑ�œa7™Xœ¥<xQ#ã„b;_ÿ$y±€Æ=üœÞÌf0ëãt·Ë1 •óA3:ßåEYcXCš…ÏM|Ç[¢·œ ´ÄÔǤŠPûœŒ•ê¸c>žlˆ¬&ó:5qÞî¡#§Œ¢^\6Þ¬euéÆlZq5¯&TOÖ“, 4ÑÇ(b3c3&åûxÖÁôœ´rñ OQ,à ›Y÷Ãríw¬mν†py¬R‡æð;&r€ùœ ‰íº:~^c%´ã~ žãf|˜NÚ€7i[«Cf~}Þ£yÈ ïMÞÒªÌù cÛÓȧ”òe^‰~Š­j¤µ$VÌrŒôˆOŸ MtΓɨŸ5ïóW2„¾üƒ¦åõŒÙó ÜíÒ£üMlåzžN[ûè`÷d»iÇf_ÏIp«êx*Ã’|ŽƒÁ-Ë£+¯³,¶¶iN/f0€fo_‰b½Y›s¢vç¨|'³“³|Àòh…!d kÂݱ! £ò|6cXÖ6q-kÀ+uü¨ÆFž ðÃÛ5ò¥ÒuŠ!Tñ7.¥2 MØÊ8ֱ͌çUV׸/‹hIŸ�Ÿ^ÍÓál´”TÀ¸3v~Û7µ:('céÇ2Ú0aïÇ¢ÐßÏN2¼Äƒ¼¨~TК½\G#fSÅ©(« u[Mtª2˜µ”r0–}íø>‡YFUL`©yEÜ�¹}½y?½4tìsKoÚ²Ÿz\ËÂÌœ‹ß9ŠÕæS cgÌI½¹’7âÒì ò}e'¶æÀÐÓ´r3KèE}^ÊaõîbII£iÓ¯ûgÓU¿ÊÊn1?¯ íMÚ—MfW±4†žÁ>ÍŠÈÇZÆIŠù ‡™U—ÑgÚÁ9úøÏуá‹Jp¹ÚÏMĪûR€£Ô„áü Ë·aßJ?fQÂlÎò ~΂(;r’²ÐÐׂRJgzDp@#®d)7°3°žGyƒŒ ôòJ˜Ú#|Š¥ æjæoÉÚ‘5ŠYOÝÈ:~õG©ÉeQ±]ÅQ>à(¬g9‹rd¦å9”ÂëcõPÎ8Þç«Ô‰œ‚ë™Åtdk˜ÌÛ!ï,c7›9Ì*îÉøkFv³5V*™ÀëTr#˜Î7)ã>NÒâ´Öœ?¤š‹:M%ŸŠ(ŠÔ¡]Üú+ix¡Ò2éPž§]d ÝÊTòyƒ*¾FòÙÀ½YùÑC^Ê»ÁTÜÌ]ü[ÌOÏ0§iÂuÎv«èÃ\ޱ‚›y™CÜÁ«L ÆÿñŒæu<U£'£ØÍÚ³œöLVkÙ^àÝü¿±1A ¹–`á³(c]¸Ÿ—ؘ•—=0ŸÏq9½y’Ñ"kÇcÄÓÁoœx¤$“«b.¿(ÜFŠø¿ŒŽÂ,çbªØÍ­Œd}XÇ ÚóUƄ豜7©¢> äÍ ¿üm!-;ÃoÃy¹ˆ&]¸‘S)Iq¦‰.vw°Í¼Év¶BlgíÎú-»B ¹¶ìÈNg®a+e¬Ž3–CkKõîü×SÄÚh¹5 ÝYÆÝáe*™ÊrÆr —°!"uí:­Ô“À¡)? Æ(ÞŒDÍOx¨F93Ch°žñÓ¸2‚–ñYžà%6DA¢ ©æ×ñ\ LæÑ—™‘†ñ]Þæc¼O õ¨Ïåìb"ïÓÖ-=ÉÒ`š|è•0T1”0šWbl©ÃHVPHyè¨Ï²–ªx§­sÒ¤üœ¥ôäè ãJFOºŠÔúPgš²œjŠ8ÇI21×î ÆÇ¾@Ū’’êQ üqeåüÚ=ߌÊÌVnæi*kŸd ¹’«èüàÔE\ÏŒ‚º5¤D¥Œ ÿàVês:vNiÈ9‡“‚W‡j^1½YΤ,UuòÝÇžg_�†«C:u„)4àlÌÁý¦"^U‘~û—EháÔh§¥xªTËeü,B#K¹•?ÇÄss(áoórã™A%õByWc¥6CTDè@ª®d9“gLžË²–Py!¤«öu&ú±gClÚ€‡˜ ºæl¥OÇ93DÌi-rŽ6ŒN‰\õå›ræ<&ê Z4°ƒŽ{t¼CǺ:6Ô±ƒ#©J›Ý$•`/°“ÿäPà ›R®là"6°–§ cØS;M¯e´jªëŽ`&•|R~ÊQaqÔr×ÓŒã´f~œdéH³~ªúNg7E%3©‡îfmXgš†&%}4fãküžü…oñ|Öþ¬ƒ|Š, ý£î±46ú5<n?ñ Óˆ#,áГ©\Å ºóßÔcmØ9KùÅyæi—=?2¶¡;›8ÈD iIî’Ûkð%~BW®eS4Ÿ>G+â&ÃÁð„<K‹ø+ø -h×Ìï*ýõÜLK6Rλ±koÍoYMâ$ÙOp¿N¡S®Òlè?ÓZÃ*v–,Ù¹’…ã:DôA]~ÎV†ýk;¿å()ÛhËYÈJ Âõ1œ—øMx—1 g?o²“-ü€%lwžO˜æ³Þˆè€úÜÅF®¤š ãÒ(´yѧéÀè6?re|@汃þü†š´Ì0š“Œã]¡7giI3ždG…'G’ñýÉð žb ˜ÉIòYBͤï8Ïø± GŒ ˆ}áé ‘§w²’í| LfM£ ¶'Šóm8J=QÌs<Hçà÷¥”!¬V}Ê K"‹aÚ©ÎùD¡ÇIq¯­ØÍXåPd—”´˜6ý†6]Í©¬ìy¡Ñìƒèü—Q7"mäˆ .âŽçDÀµagê³€S”Ó*L_§ ÍhDðÔgmp5àDØúvFðó6Ó9v«i=ïը̈́Ê�ÚQ[ÔA4§5ûs¢¶ºéàc9Ò¯a¼Jú §„—©ÇËTå0 WRºòZ‘ÛFà þ‡v£ËÙÊ% Õ*êTƒÙ‹ÓQ©øž•Ÿ=_ÐOÍ’9¯ÔœÛË0çw�ÙÈHæó*“Â_( ]ÊÞœâ&ÚQ—#<’Ñ!ϧ³¶°Ž—ΪsÆ�®qÇ #—ñ;÷ùæ|wè¹QßõúÎ×¥¿¥©IƒÑhŠ9j«4‹$RR¤ËšrXÓÕ,àPN€Kmxè—èFIÊEÍ(Ëó@ö<Çïu²1 géÏ£ÚßÏ7y|‹B–PD=NЉÍðWºó'ðº›*Zs9‡¸›² X—Õ±C-äZe|.£=—ñ‹ð÷èm£Xl b/+r²SDÄè,`]èÌ!Þem m)á,#¸ˆFOdô«ñÛB-éD=ÞäÖSÅ`g=«¸–¶c+ׄ®5óx,22fsŽb#‡èÏŽëÄ¿3¥»ØÆå,e;ñh0ȯârÒ•¾t¥:Ç… ¤3 "ä°õ…Ez³aõ+g<MiÃ0N°“ýܨ¤:´à�K¨ÃšÐ ƒ˜çsYUtfað‹Ø'¼Š™\y`E1 a>m¸! ³ “Ÿz y3Z‰C"8C‹H‹Ï~¾Bö0Ÿi9 ”Ôp¥Áx¬“â;C!~Ž»x”s±"o@cöe{A˜“`AœÕ:tä0½c”;æ¹´B°&tæHlÿ××ÊØýœ¡0$3i°ú./Ƹzc´îZÑŠ£Ì‹Z/^ä`œ«TâJ,®šö\˜Â±9üõgb@NÛ’•4£=sùrIIƒiÓ‡ÖNW¢6]Ms†Æg2,š}[úçüüŽP e>’a?þ¿ÙÃ9:ÆO¦¡§Sr<h-?rGç¨2\ý‘èÊí´ºð/3<“óÆ×ø&Ï0€¶ÔapŽn<O|$Úy;…—^³C¶Û5 ÿEŒc[¸Ÿy‚'ØÁÕñÆUtÍ!.£7MrNNÒ†õäóÜNš0"Ç`ÿ¡«ÓŠÁynÍœO¼,Íñ\§®Ø*žà4½XMfæX¼ÓÉ_°“Ôí@ÆuoûÍ4?*³Þü/y·‡_&(öôàn~Î÷¾ÉR&²€4ævÎÑ•ùqV—±Ÿ39A!3(btÎ1ÜÎíôf47²Œælb&SB«ö¡‘Šèù§ÖúVŽðû8-³y–­ü,ä£y쉓óz¾ÿÃ-¹yÒ嘟s9’–g4FÐ$ wÐîÂs˜n€ÛíåÜ™s¥ÒÓñ.ƒøNt"{ä<‰$"PLiÈø+ñâP¼ñLŽÐf;‡ùk¼ý…¸ÊBÄ8)盾+åC¹Á,r{Ã;l\åÕœï˜TEûYÆPšó£YÇN^£ íbèšóq3/×>È™øç(k(¥4Ìõ[iÀºH ÝHsšå<}«ã¬î¤ e<õüÔÍr:ÔÏÆ{G0Ÿ_qŒƒÌfô…gu<3ãä ˜ÜÊ:Ž1¯q…öçû43â+äŽ�[c¦IwÎ|îä({è·ÇŸx1žŽL]iYv÷ÿÈ v'ÓãÜžà‰0BÕþ؉ ™èWç¼÷µ «´Ò'çC£Š {É“þ·)mqÜ9{âßGã3ü5jW™ÍynÍüÃþ?{ºÐž¼?ä*l~hwõFe岜´õl@¯¹|Cd½ç’/úFH³œÎÊÙp¶žÈQŠ×ffœeôg3ÝXMŸXzßË¥És½#ZæG<eZiÃîHÔí,óåTÑÞôc* pet¤*âPo¹ð’ŸŠÕ±H¿ÝÍ@êFë(ëÂÙ‡Ö,æT`¢>ÏvNE.øá%ßèXôRú\ãÐh5fMd© ôFkp;¯$¦dÖ:ÎÑ$rkRúó—© c$/§Uj¢œ=+¸D…¸<ë?¢’3Óø£Ýdf¿Ùla}®ÔC—GompºWůÿ¬r³Åck–«þõ_5ilfRè5çZNG¦ûBšóeö³/gÿt˜›™Â‹Ñ.NùL¹::z°*¤®»˜”µ•íÙ-¶G»ygÃ|z&¶¹U¡žŸÈBs”Ya«<ÉÞ˜x»pŠÏ±’~ à)åb–òuê3½!x9͆|]3Þ˞׌0œNü9º 7ðv¶Šœ‡y–ž¬ P‹Ø1¿É'©¤ݙɤ𤟳çƒVÓFdèO!7òãÈéÏótæ¦àâïàþÎÜq6šöéÉM9#«8Ì>ŽFçé‡äï\Ë4Þ¥-+FVF¾eZJŸæ8™Î´æ=ÊÙP+sŸtaÚKUX¤Õì3ä0b{ô6Î1ˆWYM/†E¼}kÆ„èc:—°FY%A39Í[ÉeÏÅ\M_êðÂI¥3o³„Ð!ÒËÖ²2*Q3¹ŒU¡¬ÛÇj&°,k{µ…5–³?ŒY)Ü.1)Š8À™ˆŠÍcÿ²…Ä_ß7ÿ &±œJ.ge U‡ÒhîöåxŠ/Š[ònwg2ïåèŠñsò\ ÿ‹Ô0/T¦Ÿ¥†•Ï©ÅÕ^š4–&ßdú°1v½#b@Ï! ´iÂjTÑ<gç”v #ØÌæRšµUÑò¸†ò ï½>žó·””ý‹bà?*+Ó#hYöFç)9ä¿Á±ˆ½‘Ó4b%„fOÌs•ÆÜ˜”¸/ÅÞp=§XËtë6¶FŠù²0š½K9¥Q.›d­ÚKR—½‘yúKÖÓ6d¬7ðV0 ŽÒ‡¼l•å<¦ {¿˜çëG{'¹õÕ�� �IDAT®g=éÈ9Èœ‡¶æ#À“°6TLOãXÉ |ž5ÜxaDa2ä§ÏC»—þŒàMÖ²]°Z‡®wNèõ± ÇÔa¿ào!Ë©ú¥ëÙÊRnä·ù>•Q”mùgõ‡÷ý!ãç{4=z]«ÖüyOÅc±{ví|¿8}¦â2o\Róò�×­÷v_gVò8í(‰WZÚÏ&Ÿ]Ô¼ŒñÑt¼…ytã™@îŽgm˜²—²“VlâW,£!E\Ì>Þd8CèBÓÙÀ(F†ë¶€½\Ë(6‘a*‡£Ö¿‘<Ç—"6z#w0›kEü$h7¿`!ã²¶eíæý ñÖg4/PÅYþÀÞû»d2—ñ{ö³y¼Íl:q)ÿE1ghîÔ:4åy>A)-ƒ&W¥¡DXoÄP6Ñ›ËØÁN}™Ç®àãßÚÉpº1•|Ž¥,â?8ÆÇxŽ2ú±–ü—Còz1íiǯYÏÎñùÀ¤®Crt‹ŽT!W²•jƲˆB¾9 ׳6*lóXà 싢РÀ̉P·ùÌ¥0”弯’|c2¶fÏÈ ¨Ç^¶0–ã9ЃЕ–¬ ÖpÂaÌa£XÈne“ØÆÁGiÕ¬à>^¨q${¢–xÿdÅä[O¶ë´f•ѱþËø>o0™jvpUˆÈwó)*)ŽHÃlÐãîb1×ñ&#©Š¥Øqá¢ýÙÎH~DAÔ–ÏO6åFž }àžÈÃ;—c¿©}'ŸÏS*ó•ì ŸsŒân¾"íÝg³êòqÞfKTYkÑnù&ÝiAÌy‘Dˆ¯²“ÑQ’Oû0ð4))ùÄ´é}þ…=m 6Æ–èp ×ʸ›c<Å\&ðXdë%çæˆœµU*Ê÷޶S;fQÃøä`MЬ;±†ÙÁ)ØÆÛ±XªÉé¥ COZ ž^#^žP;‚üIeg"»¥:g®êħÃùцC¼FJøû£—ö.Å´ ßò(àb'{èÀ†ˆ”®C²!Þr²dÈÄs’NÒ ÏPrGá1™:ë3ˆ îñSÄGWч¢8}ZìŠês 5\i=ïR"«ïeÉzÓ¢®Y—×ûݼù­³êùÑÖz÷ìj¾¥óñ'_Ïv«jÑ·ìäCåêÈ^5·yy·S¯ÝãLÓþìÝ©¬à9öÐ?’ >ЮÔV)ÏŲ¦oÅÒlS¡õ_ld3ß 㡈y|8hF½È04žð·8I)ƒhMMùIŒ× ãý0ûy‹^,?¾O M£ú´'¹›ßó*oÓ=&Èÿà;F–[Â;í&ŸÝÌco0F¤^2íã>nçûXÏýäÖ‹q¼À.¦ò ]Š>§%ÿM]®§*ù¥òÉh–õZøðRXó­¼G7Z‡ .ÑŦQÄÕ½2†GLÁ[!ZúÌz‘ãð{ò¸˜Éô¤Y¯k‚·]Ÿ!ôâ'ìåÕQ¥ø ¸vôcUÌ^ß`-Gíµ”´gë9?¶&ì•Õ1&ß^u™Rë jò´Ïž§mµË׃f¦}Öììy\Ó1ÖÒ/Š–“ÙJoþÆãŒ ˜¿ñ©<…YEa-šÈ|æ± DäõØÄ泋ÙÉ©H7¾šö™ó®€ƒ±=º››yœù´¦/g3s‚Ÿ0™Môdù¼B'G ío‘%=•mŒå¸“ýa*­á]އü²Œõ|ŒᎨäk<©6Tå“1-{þ»”ÄLv ûéËo¢ ‘ÍNÁ‘©}u˜·-ŒdGLéQÝÃNRÌÇéPƒØrj¸žæì¦h$”©“šÇMsFò.aÅÁñIb¢L/)Y;múø1]åff?Ìšœtç¼äŽÛ.WÂß- †s¸;;ƒ¶Ò$*l[¨¤cȆõ²$£”Eˆ¸ °ì¸P#[™c>ͧCô3úq;ûØIwNð)^ŒFåàHh‚“Ý9™Ù})§€;)a5%44‡‚0Z§ÐØhK{ÚÐ$GⱎÉñk;p/Pa’½(dK$ʧ-QG®í~_šq+õh‘’U¡ÝßN0 ßÀìy½åJÆ1CIž1!8LýÞžD›Û–ûOVð6MËXÐôwWuììc¶ìpþ¼ºÕ5'»í¿úÙúùKí|´É².§:—œ<OY˹d¦ýÛJ•Ò¼¨ôȱT×¾:†Z¬("% £ÌÛ*’ÌZ{é`ìVëÓ‰/“‰gcû‚kP‹½ÎÞŒ~­y2V²Ããò3ç.ås¼ÄÆåé•5‚ï³Õd,céÅF*ØÈ�¶p–>\Êz‡•çv:†Õ±Vætåte&{y“)”‡‚¿€ÌfqÀþÓvj!ÛºüŒR`)ÒʬYP—㌧uPB*èB¯®ŒãÍøöfÌÈÈd­âùˆ´x¦\œ§:ëÏ,ŽT£îÁ–Pl'§ÝWXÄ—‚ï¼té:.ä‹ñP²V±¹É§††Q??F£¨Ëž o¿~œüˆÞµQà`Џ?.åš<×emOÒ­¬%TЗ«9I'öÆ6w9õ¸˜£ÌábÖ2š[ÙÇ>晚5;꫉¼“Ç>¾Æ­œäi>IGöðêðéI!›ò ÌjÊbÎR—F¼F&˜;)¢6Tø˜¾¬d³.,ÒCx/îœÞÔ¥E¸eŽÓ)̵B¤Ûø)õCQ¹ëÆC—Ü]òvd=ãj¯08n 2ø¥µm×î1^=̲å&Ó6§¢¸³Á›_®å‘œ9æÂ6J‚›tc&­9Â*x„m”²™³´Ž*ý‰ �lr^c¼(2’†²“n¼PR2yÚô~ÿbºªˆ,à+sâJwÄX0žü ³?’Ðn9%ÀùÐ+U·kgëÙÂàÖ°Á\Ä&6³“!4Œ©;7¤¹8Z…ɺ쌅sí\=€9‘`½-Çh•PT5 dw 0*8Io^ç –FÖên"Ÿúá!MÞlઘ'R¼÷z¾¹ä¿ë‚´þìgSh:÷Fc D$…!ÒmyTèÛÊõf­¡+mYKs ™j¾mâ.ÜC eÜÉq.ã½ÃŸp”w©Ã­®Ë{ð\m«~ÿ«ê>;;=ÿ™S³§ä YrcƒÃ?Y\§iM¯·/ìðÊÀ’?ÝXÑogÍõ32»Zæå]’-zÞÚ«èÆÎäþÐkHGö2’jœ˜ŒâEÎ6âfQ/ž¢Æ˜ôf¯²ˆntˆŽÂ gá}ºE8}bÊ(:Ê~ŠiÉ?’Š:㶬jþ‘s‰˜ÀE'ù&EL¦˜Rš„C«I Ò‡²‚׸–y&d4ÎjE%c#ý«3ç ړ欅íXÎñtBjö>k¨Ë‡íf •œf4g‚Šý»¸–r2%²£Ö³‘5ô§uÖYæqÕaËëE«B'êÆÁßd½È€žOï»’ǬÀZ¦ÖÑÚ2ŒwÙO?:…¹xY¤Ê½øàd M>¼Æ¡¼ÝÚˆ ¦Ó8–³_IÉsÔÇ šQšµ4T ÉÓvœ·XCËxLݦä|hTZá¥uzš“úg=Aº¥uFý|³çŸŸaÙO%ƒ˜<šO°„÷8”µšM/r)sx‡Žäó"sÃoÐóAàÒ ±:–ì)¾%½£m‘&þÆ‘.¿‘ú´ç�׳00'i÷Ò>O1ÍØgu¥ ¦€JnÏ! Ô†¼”„f{w ’f'QñZ0Ÿ&1<ÖâKRòžË“S’@—œCÝòN*ÃîÙ8|)é–+Ž4ó"Gó¾èW%/ïzp‚²’’ÿÂw5«²2m6WRʦœtç$C¸‡²(Öæ” ÏPŸB®zðÞéÝ1næÙØ—iG¸S³wp,7†2ù‘ˆóUÎEhz[®ˆO<ÁW)¢WQÀ›Ñ*Ç¿ÅFç–Ó8¬¿NC^t>Š;¥B»P²²™Ádùo²›£ÜÌ‚1'cör6‡¬ëöRÁPþv<x5´£¿ãʰ»^Ì{\Æ3œâ—³Š­¦gÜ#y–åüO·¾yDS'BÒÂ` wöO#E%¥½Là0yŽk²®;³¶Iõƒo{ä–.ݸûÑO°ó×uƵëseÿÕ-l{²ßÞâ篮´9óµWÿüÇl6æ„׎)/¥5­XÎm, q]uN"x’í&uIŽp5ËèL1oq óSô5_áyvÑ‹‰Ìæ&þœûXÀÀ0w¯b$‡Ñ2ùHºPÍÒX´`.ë¸=@² ¯AÍ9†Ó›­ìc0x:€=)q2Cx‚åtåc,ãáˆ{ßÍî¦,"—P7�B½cǰ—©d8Ãê†ïÉ ôálĆã6q˜Û8É·y<\[ø2¿Îù"7±!ŠÕŒ ÐæÖX|NÛ“¹œ<µô ‰AF`—ò›˜Ä˜Ô-g'¥iÞXƒ:Nµ.ð‡Ÿ,D×±‹[XÀNRÁíTЈ¶ÇP¦óNèö26*̵Oî—"ÀhÛù*}(åÉ >Ggá,¡#ÙÀC¼LcºÒ“?ÒŒÌf.çèAS>ˆù qåÓ]W›Ô¾™/°ƒî ã»´Lü‘HÓØL«x¬ŽE£½<‚m‹ ÂÎlåsaxª =p gù$[hÀj¾Ác ã’¶5›ÒÀL´ekjöë(a™áë8܈ç1ìßÀÚbUSèD½aLb6]¸(V–­é¬¢Úë80È)g¨à ?%“£\M Þ¡ü:gÓc\#Àõlf?e  ŸaB××xƒá-)ÉÏ®Œ»å3ßøã;Ÿøá3ßýɯ›5û7Ú15‚á“ÿ;‘gÑOFr‰œf9¡È_å74d7Ç꩘Œ£%uùN„Ã…!Í©=‘!¡}ìÉõ‘îÜ*p‚·ò Úq[NJw7n éÛCôcy|‹ CšãŠø_¿Ñ9Ç™ e—È·NzÐqŒà¾H­L¹æµRÑ ô¦8'ß½„§¸›aŒ¡ˆ|ZÓ(8xÍòLÍ÷pœœ®b|d`ßKÔ‡¢1š~à1~ÂôÂ`ß{sª34å»4 9£µmí•çùö¸º~›·©U¿Ýö¼Ø({î3ÙìŠlvaÍéûü¶è[%Ÿ¿®ëÏ Š¶Õéós}hö L;¾ÃMq9š]x®r_Mãoò¸)NT1©ƒA ã4bOs Oðåp¤}‡Ö9ÙMhIW~ÇïXÆB”<’{y„¢8«mø>7“ǯh›lªÍü±ø|™¥ ßçÒTÌɸ˜F´¤˜®L` Ó ÎûRÇ0Œ/Ò+$0ߥ-—9_¦­i Í®üš‰|š¯ÑGÄ_~œ¥†<@k:ñq.åq®ÚК?ð&2ˆ{YÂiO«¸“§p­ø"÷娊“þð*n` Eè{Zò;>ÁM ¦(æF¾Ok¾Ã×ñ¾Ç/JŠ˜öoÇäÇ¿;39Lõã!­½=ú0:¾{*®Ö‹ö~I É“½éŽˆiÿíù,­ù<-(¢7ÑïPBn§?Ÿe·P’у’¡I¤üdb ’É1H¤ eØßÆØè }—ïý¿„Ýg˜UçyöýßžÑ:Co¢ƒ�è @ ɨ‚ ²ªÕ\£ÇŽíرã'qIâʼn“¸(²-KV„„½÷Þ™¡÷6LŸYï‡5ÇVòXï>ôSö¬½Öuß÷uçÿdT|XÍi-²ô76ä úñ]nÊ2¦þ¤4q;ÖÍd–I±}!nìftärhEd}Ž_¦[|åíYΊôÉz–z´dr–x=}¬ZÄ•Ïþ3›G Fzwe\F'¾É¿0ŒQüS€þ,¿MX,Æó%òã)N]qO2”(àóšœÞ�í©OÓ¬ põVy&þ9¿§½øGÆ‘éÖíŸ6ì*~ì¯Üÿ­ÿuûcÿãtõÏee%\ nf--YÆJ™œÅç¾Ã\H/Îe%¿‚û9Lv…(#4mÐ$ftÍɉ-y[Å1'd-i`Ýô`=ÛXº‰V ¢9å9d´NêGšÒ’Vtg/Û(&‰>ì±æÖ½*K"x5£½_ä› ceœe81~lÌÞá@ªûÿòHõ~7æÉü$H3×цSÜCKjØÍ&uZäÆÐ‹]œ¤Wl‚F²„K4ã2ûèG!_™â¦0Œüp^%q}…†e óÜ|Ú–o;zJŸ•…ý›eJZÝ»¹sÅèógZä×Èí}:¯Õ¯{¬=½=ÿ£Ÿ¼QÒ qõ›_ó,›fØZòÈXÚ‡ýV4¢2ºÅ÷+ðIس«®<B#1(Ô.)úïæÈÐJàM"O(Nƒ†ob•Ð9G×Ä~öDâóVÑŸ¡Aw½Ì|ºGB’2ÏW×ÅrŸeÇèqMŽ_&¶ñYêóOÔc5ûjëè—XF+n‹c@ÈvÛäè–1 Q™ö*) £tšbuŠ5¥šRFQN1M¹›ldèÍ>¢”;™L'šgTfÔg kB—ÿ ="Á(á,O³‡•œ¡# SXÄ<vñ(X’“/Ã>Z¦–Äÿ8Oi8…E'êzŠiÀ 2Lg³è˜ØIz†‘n]Â72’½Yùp§(жæNJH;¦G½.¸_:GYL£¸“Ö|Ähže] ÞZG`l[^á¦t8šç‡µv³•qYTè4ìq?l§ ½¹È^aÍ£·¿%º^Et¦[¤÷=L5™À^L±IZšÓ®RšMÕ!µÀG‰ÛÄuQŽe´-Ó›¥€{ÎÆÀ§C‡”ÀЕå1Å<OÓÙèd. q#2lcrPCÓN5×Ñ‹}ú;*˜›ëI^à5Žs„CŒàP€CSNÒ‘À!¾OS>õ#¬ýËÃü.Ís"!3½gÞÉÒ7´|¥t…[΢ÈIHƒÍš,Ÿ5û‘Oiæ0œöÆêAÇÕ^½¯3ŸT�v t¬( ÕA¯J3#j³N`iâõ€O²3†GØ®КýŽ^f;­Ã‹3˜3\ÇQVÓŸv‰â¤.ßsIØã›ò` 6&Ò;ÈÁè~ïAÕ)þEzE@_GÆršµ�?Dcúp:.N{º~íêÅiFŠéĵtb&Õäñx„š÷ UËQú±‡qÜÂQÞ  7Ð(ZùiLøH.0<«­q(öi•ÜÃZ¾È5‘§ÐŠS àírLöæV;Ыù¨’Ë#vvþÒWË>³°jyÏ5]÷ŒÙ±'?oÙ/òÖÖm-Ê·mØÙò{Ã4ýúÛš’Ç5ôà(Ÿe3­ˆÒ»8³«Ô•uWBÚ t¡×™b3YÀnc ¯PÅý §!‡è¹À½yV,%ɱ7©ƒªQÿDÊ)àDžm莌K5u9dKÃ9{>Öõ±Ìࣤγ/v<[ÙOÞ‹oL]) AkzЀ7©N¼˜Ô™Nó[šÑš·8ÍšÑæ]sôLì'¿¨9ãÍ÷#0â“O YÈ{¥7'JÔ 4^HÝ‘¨û)ÕéñPâ]ýás¡þG}Ž2 4f y“#TÒ5ǡĎ&µæ|d щáœâßc\”Ð(~Boò¹Ë!DêJ§ ívÊ*hGψ—[œï'ù¥ qHt¥Rˆ×ÁUhÊ8†–x=AGgo.jm¤8ŸŠ|Þe‘s…‹Œ¤)Gé{Í'ØÏZЛ呒¼>fy#æÊciÅ㽘¦å-Š/»‡3´ 2\½zno YU]75ƒqæ˜C%-h‡Î4Û(›ž>žs ¤yÌï»Ó͈ 0<~ãIZrŒºó¥CDæ~ÀåÄK¼óÉ-{o>¢!Ã9N1]"ÇrMXjXÂ>*‚òs!¦çÓ$)J¢<Swë¦ùijOUÄ’ekµNј¯¬˜5{ö§,Wi Â{œ¦&«û|ŠÏÑùY7ܬ¨/©cWVCoZ–pn&Û’Ù”c{!KO’.ŽG-ñÏå¡ ßÏ_³žk)ˆ¿çtxi¯°Ÿàk8F+Zι.º%cèÃZêSAE8vÒ/¨²_7ÄAp7³ù}Ü1"N~‡|žÂÈ;G<nOnŠ!D‹�¡¦”÷µì zÊÁˆ8É´x<Zqs¤]OÂqVq-7Å™B¦/ñoEâ@>ÁË9úåùa¢5K™šcVƈDwú°™|_Ù˜ÜqÈÝ?˹Xš×úšvKú\ºcQ›—&å×V¬l:ägÿqlñŸ›¹féµGßºíØ„}ÕßÿŠ©‹áõã¶í ûáJ¨¥8øªE±“XǨ¶O»O§c&Ñ78á"=éÄÊ8æôŽ‘Óq8ÎŽc#}cÕÌM,‹nL%ûÓ<ºˆÌºó¼cjm®5–›9³žo³ŠËLdýù0RW) Qkšƒu#OÄ1½;Çò<T[—¸±6º1sy˜<Ž1‰‘ñ9^OMÆ|Zs†Å<N?>d/«9EªÙ7ùŠ«ˆ\OÕúcz§åùj­×8Lç¸mfGÚÎGˆd“Óü&ä3™ A9ÁÙ<“k}Àð˜!=”øA£>ÁíTÄHÿ0õœ†J̦ˆyž­õý(‰XÔ4еŠå1O²ðZÌ諯±ü!ºÜååz,±7xmY:ÆrÖ³"ü:ӢРÏb%·1 øñóC†¾)6¦iã$‡;(åp\ÇÎûM¹‹]±²>Ü+±(¦ÒèLœ®~Mq~p.hÍXN7q0c7mktäKHèJ_±ŽË‘”x#+hË­ß•†1Îäkã q<«ØæG8Ñá®7ÏCiTº»YæCY¾Ã A÷( XiVyL7”W ÷ÇðéjñR|c~,'ã‘¿ÂANð:µ¨^‰ÀÉ5Y£–Ï³Š“Œ*(Ø8köCŸ²\5ÚØÕו0‚]¢w Eîfräw¤\íyô¥3“8ÊxÖÄaÿN–PÂ!a%#Š;'.ß®HoK‰k˜ÂèØµ] ÑAú ¥»Ug\Àžof—ÈXŽÓ‘<ÇË!èHeT屸= fj`²óìs¹—Åä0‹¶|ÈuqgÔð~ÇÝœJùÁÔk²ß寲…)ÔgWÌ«gÝÐ-yˆíÜJ=~Ū0p¼Ív°Ÿ‰å œæ-ƤJ0Ö°&´C(d5EÜ—ø0±!Ñ”~ MNü˜!Ìsk­Ÿzv·VÔÛõÙšK¿ªº©¤|×ä‹÷¿séÅgÆ^¬úòÏ?³~s· ÃÆ}ïÃFÎ|ùÕ²o}&¹÷ ÏŸW4Î/ŸP¹#²qq‘#<CþãT°“³d×”[ø0Âa?ä Ûù›xމ ám®g!GØOÕ…”ÿfqs®Ÿd J¼•‘Ÿgzm]S~1ëiL>Çcò_î&Öx­ÖD†ñmX`Ùg˜Á|fr#¿¦”oñ1x›KÜh•I4ÒèxÞfhâýˆqz—‰¬âW‘tc ™7ò6ë™Ê<RĬ¤O¬ÇÉp4ZñWø&óC±RÉvZð ¿cHøñ/ü0Ú¼O’Ã;<ÀýŒáï9È~n¤--ØÇ’Äfîæ ÍÉçݰ?ÖgóíǼ[¥µü_fñ!¿aD¢o†o4Ñ¡…|?‚âVs7gø,K)á<Ïd•*Yå‹Ì¤?SÀîÐâóÜÅghÁ}T²ŠÃì¤>—˜ÃÈå4÷3‘-, „3îd9µ±w<Æ!vPÁÓ,ç¶ò,Ó˜§Æ[Äb9¬ ý¥@ þ–•TÆ0åTÌ™Žqžiœ§ùlbI¶\áZ6SK û™Á(—)f=ûiÇ%ó6Ãm9„ Œbß ˜?<ÀÀÐhl‰advpOÛˆL(æ�Eœæn¦óûØD6âo¨¥€[Cðys !–Ò;K"_›uyŠy”ÇÌ,7ì¹åÁF8Édêq‰g" ãú²š~ôeyAÁc³f÷û”åêhˆnÿÇëá=»›-Ñlɰ2¢9SŠ]ÚÙÍ«%ÑOkÀ»tŽŽÍ ¦°'@ÂeäÒ&tý«XÍX¦ÒžrŽ…þX¬ ©—+užn`7ù8déßòr–þ.Öqo�j7“ÃC‘hМ²DŒß¡ ‡Î{¼K𷥂áí?D}þžùTD¡y‹Uq6½‰Nq7?Mýââ”°(¤A¿ªTN ÜÅ2žc'¹ÉãcºqˆÛùˆ6©î3´ÎûèI9wðÇ�Õ¬£1-ë™^íQ˜s·ï¯ÝñšÓ7e5Í<¹*çw_¬ú×­™¼,Q¿ë×>bÕø} ¿R½³AÍ?|=yö}Øèç¼\lYó(µi²NMðfJ²ÚUñä¤÷ú*F³‰†ÜÉ.2Œõ å$ÎÈc¹‰Ìmzʇý˜á…Äsõü¶Æµ.±>ô&ó#ܯÏòpÆã¼@SPËTr…™’•Ű”·‚S×”…|9T{x”]tã/§d}fÆ-”&,ïæyÁR;@W^á¶Ó5ØW)c «#\õ­ )g8D{^¤-×ò9úòkÎs Ìâ�½9Ë\fòKŠ™Å#‘é7ˆjð;~DG~Hiê#f%ãù¹Âmlb%‹b‰ÚOýL]~MÓh«¦tà“úMhÂÇ\z‘Ïç¨ &u=ŽFöÂEò2S"nm]Va¹î“Äβ,˜çbæÄ\­/‡Ê©+E|‹6ìàiŠØIºæÀaúÅ|)WøUè8:÷qË·ò:7Ç­ûsjBAšÎ÷œ±�� �IDATá¶³”m4æ^Þ$Ÿæt¦-5ÜÇn^ kXÇßq=Sνlc4c9ø´ëy7b(RÉô¾Ø‹b(E<Ísq3‚BÒãÝF4å½µd_PnS^Æ»lˆ‚Ü6 …M²ð¡'¬>ƒe4Êõ×5‰_³%ô¢³™ÁÌeNßrq°Ig4fñ“ÖÆïšÎfý/.kÚÝHm¤_6g»ÆB63­  õ¬Ùýÿãÿ÷«9ǘI¦©®=õÀŠÅ¿S–fñÂ')¥´ /ð­Œ`scDÙ–$"}G-»aÀÈÓIø(êGŠÄ¨¯’dêjéã”Ò?Z7"¿£†ùœem"Ô—Cw7W³&m1áïB!'™Bçã.üˆwãèÓ8:{©‚ódlmrÍ«1Y=!1 þ_Áð½Â*Ø8´Žï…õ¡ gy˜Ý´¡oDa:Ë訶éÂPÊ&NPÌù ±a!ókÍiP®×ù»69%ƒë=Óôý©¥ÍÎl¹7™°,½ª^nÅ• ;j²®2}‰U­ýøïu÷ü™ˆ0_õI2æø¬ŽÄp”ýô Š/fìϨ,Ÿ‰4a‹éI }¸.×͉b[zŒ‹LÍq$Ñ‘º°:Ç…ŒüÄÞÚº0ˆ#¬¥‚·AgZ§zŠŒ•‡ÇÃ`”z´Kù/úų}…;(¤-Û£MÔ2ˆm¨Ç‘a½—…œb~°´_̸1c/E”³ÌfMcøú;‚O?#˜Ù•t ûàI–„µñÿðÍØÜÔãyf°šŒàל¡TsmHTNEæ\ ±³54Í{XÇ`ŽFNÇyŽÐ÷( ŒÖÅ”–’qSއç)ä¬ SãYFðz’8L=ï2;cð>›\ 9Ë|ý8瘘5¨Xÿ Î^.SŸ^l¤+Ž”ßÄM^û4ãDªÄI¼L;^g7ý&rÕ.¶ÿŒã¬ ^eaDuœ§$phÒ†‹L¦5ãi¾[éÆIæs2â‡VEÏ-MÚFwšÒ8š®)ýò&vÆ–®íiÉvц†r=!üK3"ÆÇ[=õ<Q;UïYÌÒ”t^JmäUÖb•ή‚‡ê3"‚C×§�ÏDóÄz:2’¶ÜËIÎ2’RÚÄŠ˜ >1˜–i=\ý>Ç®¼ŸÕµØÃñfžLŸöAåîÎ5¬)(Øþ)¾«ee×Ò/"wësg|äyl‰;›Ÿ‰;¯c³Ð;mè•ÕÖlBZüævRÜþ$ÀŽ7²)Ò]ë“a+͘ȇtˆ¿ðà'ת)¢-Ç8ÌHúp™‚X®Ò`Öúœb B ¹3 og#l´œ.Aƒ)ˆµœæ -8M•Y¢óQ;Rò%®£2âÛW°‰¡¡~7)Å`˜Èílä1jè®õn1èNíÖFàÞÞ\%uКÎ2ž3a1®¢[˜Tú³Še çt (ç&k¶'wÏOêu*=Ø(Yü§fCš—_ܪ¿Kc¶f–ŒJŽ0¹Èöž]àÿV{~(õ¡NL 8æžØ,ײ›é’¡I 3:%zħÐ%,ñ=cq:–ø]ÌSèÀýü8cpb=iReâhR×:ïEÿJŠƒùnl`p¥}Ñç9’èÂÃL¥/oq 0˜Š}ˆ\`{�ßš‡*}^®;;hEí¢iÓ•û(¦˜s™º«}êªJ6§®’¡˜mlã‹ì¢9eÁ*LSws3åLå2gèÊZ°› ,¡3i€Œ4ÝnÝx>ÌæuzÐ< _E ƒÓ)ËH YŸÆ„æjÕÔŒ ‹ÙIoú2JšÓ‰…l àѼ@!%YOw­ÍžÖ!,§­ºä— ãØA.õyŠ·F}vÄn ÞY÷jëà?Í qÁ òƒ{RÄü@K ¶³t`/Wh—n܈¹a9¿Dgòy-+#´ òå‚ÍF#zQ"¯±ç8›Ñݹ¾šÔ•û31ëê¡Ïiï± ¿æ4}˜7¹™4#Ÿ öq)BšŠ¹“öÑë{/«Ņ&«k)c]¼ÕQtà¹Lb?Cò³Ÿj:Ó726ÓÒ[8ÀWiÄË‘§³‰-ô`ç#¯îHV1¿š¡ñ_q´ÚGÉ«±ìW·X°û­xGVå<K>ÍD+JØ‘Ö% >e¹êXV6?„•e1È9ÿUÄ|(ÛkUKn]ØÌ]œb[beNžò#¶3_çL4¸+²¤9d™:d‹ʸܺÖÿ¦ ïÔË:ÆMˆí¦Le ncgÖrUØCáæ»ÌÉøç>é`hNvñséÌêx«"Ôø\ÖuXKÂpš0“ƒeYJ÷xçéNóNú¶õ$·r‰BºóQP¥SAÇô¸†ÃØÀÁ,Òù1¾ÊûÔçtlZ/RL†{"Vãhe^æ"—¹ÌßòƒŠ.Uº×Þ’{6ûúgÜœ·àË•+÷ZÐÉ€Úä–er×ï1z§¿­ðoOJRþÖÁMl86»ŽìãÏRŸ¥!Ú›ÔÑzR»ÌüxÈOrŽ‹Í’:º|'^ÁâDAÌ{¯î“FGáþB€‹NQ’çž¯ÔØÍ7x™¯ÒœþÀ�êSN;°›ÉT2˜îü9à^÷q KS‡@ÆáÄ(ÞgWôSKòKìc"mÅtšgiÇ Hì&¡a„”¦íŽ$,ä~¶s;ÇÎÍ?;‡ôk+ø«8ƒäŽçŸ11ñÛ#æz:²§¹÷Û•ê<Á±à­}zÿjop’¡Lâ8s) :xk2y¾W«¯Òf|™¨‰›ü\ÜŸ£9Ëå<_¯õnˆ)R[ñ>ZÓÆ¼¨Üˈ|oàžÓ®lJŠIÉ…±W«Îª’©Ov?ý˜ÄÇñ)¤DÿÔ4’V€±ÑžMASYAKªxƒ+´c$8Æ6ÎQHÂ&¦3/´ —#4¹œÎôfíÕùMÆÁÄn:Ś݌É,à�ùò➧óÏôˆÒqU¿^a7©z»Š£¬g#§óü²Ö£Êíâ›qzNeMƒC󙉽NîeµºÀœ_õ<¥=]Ï�^ç| XVp"”½YÓ¬ÓÌd Eñ±¦7yºìÈJ9/å!>¦ÍÀØ,4k*|ŠÕ”q íÙ•óB¤H§²ÃkYÇ¯Š‚‚/Κ=ì/-W?)++¦}Xšk#s/Ã6p ƒ8A m™J#òC_°›*nc8¯p*(±é ñ$ ëË¢Ò8k÷#FD££­º6N[$þ3 Á·³.r@R~vªŠ© x]%çÙÁá¸Ýñ ØÁ—1ðeY‰ò7Љé,æt|ã.Gÿ!ŸRzó8o0ƒm|›zsœ§ÙÂyγ‡s”ÇnJàšç+æ]Úó6wEwþhD86¡oS<ÖÎü9Ë9Û9ËR¶RHiÀ('³ƒóŠ1õGé:Ç%òù,ß¡o3‰×8¯d»õ»L/òÕÝUO¿jöSi}Ñ™|ÓÚùéP?Ýgñ5ª'ò"W‚RšêMöÄ5¼‘÷9DÕìb7<NŸ°ïl§˜Í´åû\L±1‰—»™É>.°B&óß4Èõ팢Äþ“·Ľ¬a'¯ïÙZWSgüJSfvDWa#KsÌÎQœ˜ÃI*i@¿å#Ú1“Õ<ÎëÜË:eLLü’ Šj{'¿ yUúa=G'ÆÒßq…ÍÌd ÃØÆ#ü9¡§x0Ø(]¸‹¶”ðÛÐ…ž{›ˆ%[Éã‘øÕ‘âD·ÄËì­çký&Rµ¶ñ4;ùÝÙÎCq‰¼ a·òïU×u–F3š#Ñ\ȉf|&ñçH;Ãpzñ=éÆÝ”ÑŠ;x<1”ë9J1O±“§)f1‹¸Ñæiwä(kù“´çŽ`n=CcÞŠ ¢PK7äL4”z°„GiÍâFV‡:…MŸ¡ =iÄrö…wb ³XAZ1‰|—r ùžgJ(¶òrXÐ÷J:ñ0K[èHW¦r7ýy!P c7ö:%”†Sêx„'$Ô#—k¨äŽˆ'½‘uÔ¤-ÊÄk<GÓØÞ­‹8ãòÀÂödÝØRئ¡ÙÞwZÕW²‹T3&VÓ¬êtžšŽ&˜x?%Œã‡ìgiŒxîå4oPÿg[àùö³‚j’ðX˜e/µõŨÓ(Žmô6²8;,­ àâ¬Ùü¥åjQYÙ3¼úÉÓ\š`½j.Ñé‘Û:€Ù9\&ÍÉ|̽ìä"µ‘[Y?b39ÎßД„B^¤3pœ<Jù>˜ùâWhžñƒŒíl¦S}jiÈt6Ò–>Lá;ªèÉòx‡Ñ,¦ ²G¹‰EÄ[-å^–±9R÷QAnì}’hÍ ûçЀ§ÙÆÝ±¿H…¼-Iøë(jËzÊ‚aØ— Õ ¤–áË;Êß°Ÿ£4 ä„÷jÉ%æGƒ¨ý\f=«hòÄ}Cø€{#OëG´eVÝ𶢯?_ñË‹þ½“Ø¿/ô“ZÏ?ëò—ç¹ÜBÍݼÃÉh]ž IE§˜‹¤±†Ž1åN¿"X+¥PÞŽ‚¦‡ùˆátb%SÄ78GƒÄ֤λ€Ö¦)»3®ÍU/q˜‰üŠ'ØÇ Ê2:×ó«Zo««¡[Gg˜ÊhºpÁ”ÆÎgx„÷)£k;½J¼EÂZU+'˜­éªüG™ÇÇ=3 áÿO“8êó1«Ò™_ž?×Ö18:s–Ã\as¸Â?dì‰VØûüm¤Ðþ”1¼B}úÑ4ñFž7j þëQq:Ï3µþ2¶ðÆõäq=s8ÏLÄ09¹!‡BšrÖìä:Qc˜”ZÙ„¹—®ìã_y%€ô›8Î:*É0ˆé1pJYUÑ÷+O#”2>Ïï©¥†l¢5Ó9EwQÆwØÅ•àU°”õ<L1;‚14ðH÷ñ!Ó‰}¤hÖ2‡ÞÏåÊOÌc5Ið·R\EoN‡Ré,ó©¢ø"]èOÂ2f6s)sÁPvÒ‘o‘ÏÛŒâÙ@Í êc½"åüÞe3ÕèMa›)Ž …=TG‹û1VÒ6¦é©™l¨¡†Ñš¾ÄžPB ä0¹>>“›ƒäp‡C¸¸:º¦õ¸ŸZNò ýx‰^l§9})¦ˆüû#2æ ›"–!õuü5¼C9åÜÂÐŒÁ,b{ض‡KÜiŸWÕ :Κ}Ç_Z®JËÊŽ|R"ñ?^mâMµ ©>-Í z8¸#erWhmN!%Nãud>[ã!¹Í¢Z®O¯oxHSaá1ÊsêÚhk"[¤ƒ(b }Ë“ü½S=wضҟY*©Ü¬ax)¥L¢˜“ž”ŽIú³€Ï±$¶i—)ç>ŽÒ šUìe-¹]\ŒT§q1ÚµâÑ­ˆ´å"R:͘èJW.Óˆ­At.g,x749GbåH-5×K÷;l£)ÝEK6°,½d4Ê1%©;/¾ á(ú±>Ðgƒ¹Èq-óøïdýÆ” x$fû#âÎI» SÉe-Åü"²ûÒ¨õ¿ íõªcéMGcÞ¶!Ž)øcHX÷ÇÑ1N½y‰z\à4Ó9ÀQ’‘K‡¤.£ï]îæF*ø=¨  hËl†0M]ÚÅRV•ÔáÌG±!tâ”2’Ó9îHäS€i½3š$u¦õNœŠiùŸ˜H 9¾[cçØÈ%¤ž°Ð}]Éøzމ±ü¿™2Us4¤6G“Ä)áA^M Íq!©“¥<ÊêÓ¹Ö/ùãÙÅþš3Ñ©«\2¶äh”Ô©œsA}ñ:7„\°1ÇxŒ×éE)óÀB4”¡=GyÁŒå$]™ÏEª9Ë ¡pû,WÈe/rå$Þä8×sŒ&|ŽÃ¬øYÏ@Â'an9ô¯ÓŒ J©¨äÒ, ÷&ZPÀ½¹ü1©ÛôtŒŽÈª ¤³sü)Æg¨Ç^Zð›@� ?8¿ÓhÎ<í¨ 1zoÄh.fK³*×}‰­¼GM¸#&p6Ð}É¥KôRPÎiÅýnz³1Žã©•{`Ô«\údïYÌØÄ»ì¡)ƒYÃÅÈGN‘f'éÃ1ÒÖŠXB&¨4=ÉÚÐ?|l…ú5#œjgcœ_Ë)®PK_.0,טÄ/³†JãéB %ÜÀ:ªèH#úôŸ5{ô_Z®v–•-àzºfyûFAŒ|R’|I˜¥S"Ño¸HK1/à%-L%¯Å7ò1ã@Y¾&´d@Ä9Ÿe+¥\›eI+L‘šI]žaªNi„ã{‰b X:ˆT3oRf½ûy+Ö*ab8Luìnº† ø@ÌW®a6sXG J)ilJ¸›Ê0äÆßXŸZŽ2A1è:º =ôf(+h‡¿Áã.ŠèG1[#¿î §²‚TÒqeªzØrÞ‘le-g¹‰r^Œ+ÙŠ–77ëšÚ` M9D ÚÑš©f‹éö¸«¯/eij³v9ƒìùÏ\NÆ}Y¡3—XEÇ…¶£3#ð õÏ861•zÜË@> ©à¡ ,b!£x'@D±;©{¶0‘·9Ë©\wp#ȧ*Øqÿ‚ÒÍc%hÈêqMšÁÁáúÂõ929Z'u®²]´æ‰‹T…&E™ÜK*st˘ɮÄóp2¬¯èË.n`ëGéYé¶&£OâùŒ¯$®Äá~MF?^ެŠwʇ´`ùü4ÄiÓõIV†Ï÷Oá‘J2šæùJ­uôåtØhÎEíÞÏXÊYÄžˆ9øóÕ f2·27¦×2‰t¤#Í©dmÄ´]6#Æl Eqótçpl·F¼\^@xS%^>ë£UþË8žn (dcØŸ‰Tâéì9bNX†KB÷Ó‘[ãÄ0/ò.d=Ȣʥ ú´÷8ƒÜ\%^¡q„¬6£KÐúS¢B+vðVä›·a*koÓš1˜è©Ó¢iô{B…1…ëYNÓ+”…w(…}\¤(*ä` 9”µ\=ÎGlyz®ÝfátXÓ…½!•<˜Áµ<a çhKiœÞÒ®{*É ½t9Îöºb5GhέÌcERGA«âQ.²š¾œ`ËbÊЄ„ͧ>EjñRYYUa¡½ƒIœ§ãy2+ˆ=õö¥%{y B‹’§Ëq‰Ûø8¾ñk¡&?ÀÄðT–D&ýSYÔŒt!ÏO§Ý!à(û™Åް…il™Öµ¬¤†‘LaÛ¹ÈЍâ`‚YŒ0ïô=ÌfoŠš¥{¬^©Ù~G8×PΣ ´Á š0’w#Χ £x‹sÅäïcÙLгÌà ÿÈ!q™MÒ…]Œâ%ŽÑ…Òè&w%1ŒŒX}Ád;GkD¢ÌLÖq; "RZ&ð³ƒÖÕ–'ØÉÇ3–ÛéB-ð¯‘VÐ,"a$M&Ò’Ç8ÉŒH”8¼ûèʬˆ©½‡e‘±“Ötb-ÓyƒFLæ]±{èÅËŒe.‡ØÈòàû¥i2­y/¶ÛGXG}ÆÓˆ©¼M ëy ,ƒEœI¬ ªHÎÓ…u´c I=ofŒLtd8KÃT>!$‚ÅÔ²š¹&s9£y¢ ¹…-‘ Þ7B2p sØCûDS–q„[é™Ú¥Œ•“¼Î>Ï\IÙE‰Zú&æ3&Åó¸L^€ÖÒ‘;âmr0>Ž42{+׆(|+÷±‚wØ›ÔA÷„X·#Ïr˜Cy¾W[§¬ÙË, Cpߟ_EüæYNåùQm]—¾86)g͸-¨]¸%šáé×d û¸“½qGma6[9ÁH*8FKFE=Éz+yˆváNØW©àd¬‘“Â{ŠçâÊÏó`­or(öé^¡K¸$ÿ:Ú!#f!%(ÞÌk¬c7w°,T …<M#þ!¦ª[C-2Qêw¬Ëi¬ wy¨“„Õér²êêÉ0Ëj5ùCEˆ&ŽÅÇ‘ŽÞ  }Cé—bàÇr+ý?Y:ÊãšÎ0ÆÐ74½x*ÆÐ/ÕàÄqv]Øg«ãšßGfÒ›!,⧨ Š"Є-‘»Ý"2áEÑ« mðeÆRZP÷é"©7å ûXÃF2ñ÷É ùEžaÇ™ÅúÜå[ÖVz õã·Ÿm5;BZ?Ä~KBó,·E˜Jz_Þ°¾…Ygü>ôb'K£Ár:² Ê#Õ´$vI7‘Oe¤tÅç|M¹4ClËYÅwè>°cUËq5;Éð³0£4¡5Gxÿ¢Œ þyÜÏzòq¸"ÒŒ€™læ¥Àœ ´×D>⛼ÁNj¨$‡¢f¬ lDŠú½‹&ü·ã4ÃÏØÂ2rrMN,c^\‡ÿ¥åD«vß ïmjzOqý”~Šó¬ç,;"ƒ|G|L{:ršºò£"î~ª˜ÃŒ¸éODãû!þ“x‡³¬ãå$™:š~ÊëÛÆÎÈÙÇt6q€Æ<ɯ¹‡ær'3‚ë“6vr-Ö—S¼J5õy”‰×ê–ø*#YÈQ¦óe^àOÜà ôd:o׺+Q•(àu¾Ë/™L[Þg 94 ÞÏyaÿjHœS2gFÒŠ†ÏZÆO8h†t5JKjUØÒ÷ó8ý¹>$Ý©ýqØ󒲨p\Ñõ©K:MJ›Í6qŽ%´æÎ|Vñ­Ú:Ì]|_D'p-/PÅP°Žãµ #¾õÎp¹}ƒEq6L«ˆ}Ÿ†´`R,]s"Ž6»vˆÌ‚PåÍdó¸&Fn)p¨†¦œgC”5íÿ0Œ˜Fo~ÏYÎsšåìd+k½ÉôèOæ)Þ!ŸÇù_£Œ–´ ËãW ”7˜À`†1‚ŹnËX—(å=Ð’¡ /Æ„‹ƒèQ)çÝ"Jb6;Ég+ý˜ÍˑԉI|&ίÅ\"¡7ݳDzéÁ«*Ì$-B2ö=c1[ÄjÎÒF±ç¾•Õ)ò/XÃm¬£sÙÌr†²–ÍFŽr#ƒ¹–ÛäÿÊ£Œ^`ËÕ«Ãæ˜O5M˜ÄrÎe´ úA𥒦u Šm$tc…ø”åjIYYßP ׄG2aþ:òâÎS/VׄÖì %çèCc¶ý¯¤¾1XÃgX¦šõ±] £b}Êã§|Īh¤×§èÂÆø éÊt3 MÁ,ö„C6¡W8[S{ºkH£E7†e¤5äñyš„0Õ±ñ¦Ò)ò«öЕ'¢¾¼ÈT~O †³—c1¨Ëá´Œ<ûw© âQîáǬ‰ÃÜÍl¤Õ|†~ÁЀñlæþØKNe7½8N':Ó™î¬ãôàã€{ÃLæ÷|Àuyºè\ê;|› .3„K”1 AÔÈ <Ì”è“ð4£ù<frЉLŽaÏò˜öc YË1‡tâëô¡$ÔÃ͸…K±:¤Úçò<Që ÙÏ=Ìà¯XÁEòCÞ¡„ß1‚ß°Ÿ¦¬ÍZ«Ò×›¼ÎøŒF]9žñ[ÞJ²|‰·iÆ‹Là _âÇѨ\ÃØ°ÝÍü ’æ%úò×±‚ž´ã‘b?£ûztâ%Y#]æ‡Ó–Ÿq…a4¡(S3®ËèÍרB)XÌxšp%òÚ[ðKSåXÆ´\w%vÄVúr÷mæDŽ‚_H®[èJ_•Cc4UÊÏÙÐÕ6 b# hÇÐ$ã4+cRuŠ&ÜÊ©†ÚWÙÇSÁ3Ý­Ô‹ü ½ù9ûÊyŠ×Ùô™?3€œà VÓ-‚[{ñ/¤ôõ¹žZöPŸoÑœçØÍI:fµïÒ±Âbrƒï~Œ!”N¥3û¨!‡Élb8ÙÁSü7¹|]µ>aI+ÞãIuvãž8-£}ÆD&^fâ7¦¶”È׎Žl`m)æ~êqÅœç×!È\Ì-lå8YÏ[l¦e0¦Þ˜ƒY½¨ö!y­ ÀØU:â"ŽÒ ¬¡:æÄç"%.í V0’ET‡b}œÌª"ì ÉFÉ6¶É]ê¡MÚªlhðH[÷«II⟉Cp#(Ëójý’(ãÖø€òvðpÏÑ€žl.(¨÷)ËÕ²²²Ñl¦I ;N°:˜@x–Ê0á§cž^לÓt #B6¶²"k°¶õ“µcGh@×Dfv–Ò¥á¦.¤=ØØ’÷XE:†gþt@1r"a}PxÓÜ—’(…oÑ“ctŒºóº0$ºùKb·2”¬¤ª˜Ä›>h U¹îO4 5×|Êø"‹9¨Ð7‹ ²1”2%¼Sejâ{‡z´ŽÒç9ÆAzÄ;I �©Ò$]z/0‰/ò͸A{ò§ø»E—ùO帙¯Ö:\Z‡LlÆQ^ ¨îP憷ì»Gkæ„1n÷¦-®Ï-aôNái© àcNÒ.<NB $?Üfç"›fG´X‹C9Y*º„^.eˆõgk­•ÜÅ$z„å:r=mb¤qC”ïúñVwe¥Œ¡gœósä³.×ôŒ‰Lð*ÊvF3/Ð k¸5r˜ c"»•Ÿe! ‡*$ͤîE9‹É¦Ü›,‹o îBYø¯ã÷ôˆÚ·¸@.S#—>¢Ã"=à§‘µ‚÷ÂNŽò;éŸÔ¡,KiËÏÊôÉM´KF6õ™l¾]I³0M¯e ÇYH!?àíxðDzÁ¹Ú'JølÔßN´¡K_*3—ld<SxƒÜÂ5|‹îa»I­‡ÝÉåL8o&Pí¬¹´>ü‘$¨l)ž¦GÈ‹gÚAZÇåâHØ©””@�� �IDATLú}ä10(<MʈÐR§@–kÙÃ!ΑÏ8Îg} ·Pà¥9YÏão© uX’rMbN¢’+ü[ùyl¾¶ü9Ä)¹A.möÿ™±ÀrîRùåbœóFEŽIOšfµ²Úò(}"ç7û5” ±˜ÕŒ iB*¸ˆwy ¾±EœéS¬{;nç|x¦ÛÄ¡ .ð$õy¾§õÍ ýÐΌʡl`58Ï„TBUë2»YÓ¯Fì¡ åtâ8Í©Ï<J >e¹ú°¬le„zŒÏò-‰Û軜g1—¸“]a…råQúGÖrú•ƒiÄùøç°à^ `NÈÅ1j»16zibJþ'?ƒ|ž`NVŠL>õâ„Tš‹4ÃfGHþ/q‚}¡ÍÇSäq”ÃŒŠ”îô­®ç¸Ì¶h»g÷ñsJ(áöŒ[) ÁnÚ)îÔÎPÃçl<0+8ÊV¦QJsj8\¥4Ùd*»*Ëwu<ÂÑ+£(/¡F÷5ý¯¡!·Ðƒ÷éŸñ(oRZöóŒa;ÙÉmô`×2#¶/gé�SŽòîø-_ãý˜çgü8W^R—gsµ4a)‹¸å4 DÍÎp^ Ù¡ Ò>Â^懟3‰|–9ÑDjÆEÖ0šBV²›ÑIOUg=¨¡)à>šq#?ç,Ç{¹?ãl­·™›ëùÁ†HeÓB^QåƒežË“ÜÏ…”IŸñ÷9®$uºµW©bO\wÆ…ºÀ l¦=ÛƒÍzó9Ìc¼H3 |‰z‰ÿbnŒ`oI© Œæ¯³?pˆí)dǹ?@V¹¬`jŽ¡7&uÌ™šï3l©µ_résiÏ&nŒD·v¹†äøç¾WVÇ¿“ß$6ÒÐ/Ûˬ„U÷07(A[ÙÈ ŽñCÙÂDš…?ì6Þc#70…-k±†rÆeácÒ)ÎÜåä³:†ùù‘á46òRËqãå½ÜD¯ál7ƒ™N/öFY‹øŸaCÄË£!¶Š<>K e|™•T°šÛ¹žÿæcÎ09&ßi iêŒ|–©âH :Fï#iIK†Ó3ëé¨ ?ÁyÑ9j‹›#€â@–E'}àêG M•>é1£(ÏjÍå (åãVòlˆ>Òì«ãÜM}þÄOÂTÏ =Ú:ǬŒ^Ɇ}þ®Æ‡wª3þ7ç(›¸6 &d4•ô–`YÈwP•ü>}¹ºÊ ¼sšÔ—w[XÛú±‰/Ǿ$ðòÙÆ1Ns {© bw*ÜHS·ð="8n@”È cëéÏØÌ£,ç&Vp'㳄ø7ÞgPœÛšó´üîiö†ûr–ÿ*ôýlprÇÿŒÝwœÕå¹ïý÷šzzïU:*UDT°aÅ.±—ĘÄìlÓË9‰;õdgŸä•mb,±DA@Pzï½#ÌÀÀ ÌÌú?î¹xÆ'Oòþ²0kÖú­ßᆵûº¾ßÏ—i1i,™ay¼óê^g£ Öñ>{38/ó~G··!·XÆõµ!‡- pÑnD¦íÎ@B”FÀÕ{áÄ"n „ÿOŠãl敀͌¡}Ð\›ù 2-5÷2/2„Q¡¶J†ÛX„8] špÒ_dŒŒî_u9p7oÆá¦p¹1“S\Ï‹Á58Í~ZóvqK¸ r°îèuI,ëu¸›ñ<ÄO9TèÆ6&T*«ö­ù-o37Rê1Ÿ£ÜD7±…ûéÆ8¶±ŠŠ�³.ãlïìÏ\ÃëœSèN§”)lg:•bEˆõ÷p'x‹hËna.‹hä‚ÁÄ;‡öÔå'<ßÚ¥ÜŬ¸¥W†›~L\ŽÒ’[8‹y|ÄôãÖHl¬ë1¼Oý`ÿŒeAPì&ò\ï !@»âºµvðZ›Ö:ØNUO~KÕWù1»XÄ™IU¦U»0Âá:±(Ø€3>2–6ÆH£.À_B¶°9ît6=ÍWøV$Ò¥&UYXõ7±•ãèšò0Ç×j“$ßý~*(âr>ŠÏÂ[ÆøH)åGF{}^`ëéÁTvqóéd²—ƒh¾.ºúɉ|1çZJ™ÊxîæñÂ-»ØLâ¢ÈLŸÀÕ¼8#ØÁ¥¼Í*¶S ÷Ÿ0œ]Ü‘ÛØ§&{,=0Ÿ>ÔáÓÐ4 ›íþàŽ^ÏF~ .IN/ÚGšèÝ|óÑáìÊl ?3káÒ“q~aÌ­—0”• ‹ÐÎ-Üɇ4ä£"?ôàú ûöo½WêüM6û¯ÛyLùf0±Ç¢—ú–«jå~Œ ¦û)úІýÅÅß¾iê ¶]Í)/o]Ñ)á·(Ü䉰ü™Ã<B>¦ŠBŽÇ®¦ŠbúQ£š#Á¼ůc;YÉ<у#ü>fø‡Èó2§éÃ*Îã¬Z,Lÿ<Ĭ‚7XÂ!*) fR½HÁ9ùùµþ*²’õŒ JÅ—XD/úÅ.Ø‚U±(·"ÏxZ²œ{üü)‡Ê¼¡ˆÛø¢_W{#"!¥ére¤B´¤˜/RÉ,fÅnZ7�”˜Í¥qj<ÉHǹ‡\̨Ãsa”IªÖñ´H<=ÆjœÓ9SŸ'XNÊ)aW3›·Âm–°~Y%Z3*Æ`Éü›F)Oý>.ç–§Aq‘ç3ÏñŠ9DC*ØMãp\~–2…·j!¸RÆc‚ONÌY™#'̬öGй”‹BíVh»ÆÔg}YÅF¶2/PÅñN†Fy˜ÔÿÍ™Íòý ¬v-{éA'ös{ù-h½û5áîšÎ†ª¬`ßàÕWý;M‚q#Åó¯Ë2Æó4 XÀm|LwFq€f²+btô'¹ŠY¼Q`x)™îL¡’F¼š<.u\“÷60ž‹9Áü E­åP î¿@–p“’žªå)†Ñš1ü…ϨÏûäj} Ì™–9’3–óÃXš’‚Ÿ¤'“béœH_^à^ZÇQ£[iB>‚Ò‹ï‹h{Ò+<È£¬¢Sؼ. ÉRâX¯ñežŸQ—õä"꩜¥Üó¡ÿÉNêsŠ9Êmñ{ÏbÓ‘uÕÏüwæ7†·úþœâ ·çzð‹éHc¶F2ò~:?¤1€WXÍA€ÜÅå¼Y+û­9›©Šžçv&Ñ'Ê‹C Ù‚Å1q( –<ÆQÄ~êGÚÜjn枤„UÌa'™Ê˜ð{àXPÄÎeq¸HSûc”Äþ1’= âÙÂ>Å.Æ'MCÞŒì/U~ð»ÎO½IÏ3VdSÊ”y®ïåO‘æÜ0ºY ˜Þ šRåÑ'+ ˜-©€+.Þö/Ò„såå¢UøÚÀÃlå6ö11èûVˆ»R™SŸñÌf—¨¡ŽžËŸAófA]<‹O8qÎiHv/sƒ¶Wazµá~Ç[§“4¡mCû– æ(~^<#Ö⃡8zŽ †Ø¶ˆH•>Œ¥;ƒB=8‹V|‘R5Œ¸Ãñƒmy†nÞÊQFQÈ-,­U-þ˜FÌe·³3æ]ÏveZBÿ{¨öç0šê€ê¦`Æ}œ éÒ(¸Þg+?äw™S™|ÀùsÇéVY£éIç o¦ÏE‘”š ƒ{c<$^3"ölyHiw0 óNÒ–ös#£Â4ŽÔã}u´/Òºº&tæL“sõøcHÝ:‡4¿¯ÒšüŠ%LŽjz e<̤hËì§’ïQºT𷰛٩ĉ]¶‹[2³³š-³’«©d= LGÅ¡çÁ�È^Ç à»q“§ Òñìà`è%Büp6Q@]ZÑÙGߨyç©óü!äü% gEŒqÔE™²8pìé,5ŽÑy÷Ó‰†´â—Ñ8:È,~À²œÁ9øuŒQ—²"<IØT yæ:6ò]Ñ6<’™ÙÍì"_Íû3oSB9õé@3Þ+ð£Ì±8æv8±ÝlŒII2õ²eu˜[ŽmID>&ôbÿ…™ :Æ/ê¯Ñkœ)RK£x"ÖœáT›ɶ¿å=†Ü®3‚û7›C•СþUòUVÄ›KÏ"gåíä\^bs€t[†Ç¼(°ý­ùŒI1ÍêIcVñ_|ŸEña3ú0<BFr4„< æ´ŠÖì¤_Ľ&¿|ãèŽ PY¤”‰Ä%±Êç†Ò£\É.ŽÎpe¨'Rw´ ûÆVs”6ÌUzÍX`£ºa íÎE,þó EMßµuÖEÛ,ÎîÜîÕó8³äžä`LÒÙôpdc‰¬§s;Î|ýŠ‹óÿb»ª,/&~GïZªü³/YA)¹Z³ªVØv¢æôàÕŠ=“.¿–%Ñ¿QRgs€qÕ¶ýCC,Q t¨‚=4ÖùÁøûS­ƒöª=Ÿ÷ÙÅÊâ4™RºÏb6#hîTø7¡„kXÍ¢ÒÐ4¥KÈåÌçlŽGMu ESïâ<628K÷°8ÈÐ{‘r’£1×½ˆ÷™Ã°Ý#Š&‘ã—0“11mNñMt¤!å>i–œ ª¨9K¥ü‚OÃ(–4ý}âŸwĹ>MM¶©zOÜè´åPrOgR¼ùyl <¸þéPÇ©Bͪ\ËÊZ)Y 7<öà XL­ØIç°ý% gÊš™Êvކ°cÌ~“‡¡oÜrJöÒNMpÞÙ™¥…ZgVQ‡ gFö™™t§aóú“ñ§øŸ‘§uIž¾ì'Ÿtw”°šFt¡˜ß1ˆ9äá¨oÒµ=9£²ûZæE^ÌPÊ ¼‘14ÈkJW–ƒ£.Ÿp#ø÷(ɰžaô [ðeúóL~Œ•Ý#QÀc9Ûè˜sN¦e¼Oqà”vp!- «öANqYMËn\=Y=7T*+0,ó×Fų3ØÊ(d3ù5OÐ.XS÷êó¬¤%Ÿøzæç±µ7‰Tûáu½€í´âlŽsèLÜÚ@ê°Ÿ®œˆ„>±ÈÖ£o$ÊŸ¤)Ue–VùU”¼Œ5y{ØÈIJ¸œz±=ä/;8}y/Ð\_åSfÓŸ²8jДJ±•6 £}xžN¼1]•¼UkUiE=ƒW­ç±Y ­Jb„™âOæóNd¨îŽ^Î<®-?±è³Fs„î슈¸á?iZ«ô/g<ïÑ;¾—,Öþ„æô8©z§9kU&ß÷8® Dž=‹4¥Œ‘EyCiÖÛ!t/.>rÓÔ;þÙvõÛZyW»ã™LwFJ"èF_šG¾û™%fYhÇr¸AÔ à^RL$vÖM»"VÃóèÑÈ)×µ"ê‹.ܹl­õÓ¼$yžJYG!oЕú1q9¸ Z0–Ýœ ˜æ˜à1Ÿ¦#ƒÙÅ.¶Qaãi”+9ȇ4ÕÖz6þÃ^uæÇRFÒñ6²›/0:ø’/PÍâð®oa o²›ñla<c_Ìjî¦4˜ñ©XÌ0ÖЋnì£wóýbÈß‹®¼Ëî 3¥¬¯¨ÉCÚDZ`DÕþ“¾Á´à0?ŠÔÚÕF>ˆæ]"ðtc´aûðXD£Þ)׳éX­U•ùôgeNÇB×gêG硜sÙͬ ®b=£(á&Þ£ªÈÔ¼·™Ã¦Pë­âE¨±@øœ×ç"&ð\N½t s®ÍjŽ|×szd5c•k©G >,t'ëÃ|:3üˆ©£XÈf°/âÒmœf-ÉBô·ÇÛø„<Eì¤'#3MèÌÂdŠ/0.g\¦ƒ“L´@ãj½2½øoºGÒ²œŸ(.Њ¿«Q6d"Cx—‘jT$¯383CœÏ§Áé_L 7МřÅá¢]K)_àõ̙ࣟPG½Ž•z…ž\ÂŒœË 4­Ö6¯”Ž4§#çp,z$Õì`8ï°!\.—p2Z&GÙËJ«úd:×fÞã­ÂW7›ÆAº÷IJw{€¥µü3‰ÒÛ6 yǘH!ÓÙÁ%Œe% älp(Êßtÿìe+ïùUÞ£ãwÅ‚>™Í\Z°Õ´ŽöCK>euDP&å-Ôc9–²Ë(gûbg]È^°ŒJ¸,<¶¥¡&Ûñë̉謜Ž|•ÏK!¬ØÍ÷y—ötdCL͇³/0m¹ÕŒŽÝ"©×s€cŒæ›¢U–ÀƒûíBžUmM¥Ã&<©$í÷©¡ò!{) ÏHJ¢+–¸á ÂùY¨+/‰¦Q=úýDöËËOÇæv6F‚mQ ÛOow,m9ÁQîMÙȳÔá]J8Ì짃Âß“/±?F…)¤î_£ŠOúdr\ÏÍ,¦ V¤t’Øm ³zw:2‹;Yª ¾&ÊÔf<s.L\ŒÍ´¢Wø-ÎcN¯å%–±ËBz»€¸–fìcL¼"z3$Nœ÷ò—øu£ :ƒ\ÏÇATÚ%p=ø%k¢Tü¿£MØÊ”°›$lÝ vE$Ä.ŠCõS&³ŸÎ\ÊÐø¥ôšßòëÙE5ÓÅœKV LU;wñx(î6Å•™Âá·O<Æ/3®Ü¬ýQü>˜,‚?’¥×3“MÞNÖј»YÁ[\ÍåÔØÌA>£Ãè™A¥)iíh™ \Äk”3%ŽŒ“xŠ é‘sI¡¾yÕì˼p,m¸23©œEqrغ 3?³ž[鯦ð·B¾ÂEl`r%3èÈëÌc"í˜ªŠ„¯|Œ½ô¥dv‘2‹(ËÜiñŒ«éRí•L?^¶ä!öp<Å]fZdn¡0ÃIsÛç£Ä¹ˆ/DHM㜥E¾š¯1{ôæ…ÈØÁ¡œcä Ý—3"ówN3†ïd~Ÿ77çx½+´åNzå¨öl¦/甹;ï8OЗ_5#Lj9cø [Ø&Ècôf”òËBålÌtgC4[s¯Ò‡¬àÓåXؼr\Cw¶QÉ0æPʽ¼ÆÎØw¿í-¶±=òD¶5üêˆÈªÊÌ×Zò!¥YÀ®¥>5ê.çyúsXÇ¥,æZ^ Þ÷òÔãBf#c ›8‹&l¤·2/$æ‹N.b3•±fó- CâøE¦QñÏ>Ÿ…xE¡®9UY ¬òšð,¦ ú¹é óˆäbº- mƒ¢Ò* s¤¤in[îf?7*ßmu7Kš;’fIIÖ{„Åd@¿€ïò±>Š·š$Í+âXRÊ®ââ£7M½éŸmWóË˧ĸhE öPÆ¿Óða>dl �»„_jN¨-®ægA*lÆTžä í£Ýô§ÙÆn*©G®¤ŠEìâB^ç ‚œÝ†7èÌÎ ‹ÉApW$±1BÄÅQ·shæ‰SA@ïÏàÈßú,º…“x­–Óp.Šû{UÔ\u˜I»hÃÏ{XHF•©ö¤99¿¡;‹hÏ)šù1us;Ûy•Yt¦-ßgNsB@åµÈý[�˜OPE97óçhŸþ’­‘Gõ2"Ýu?oÓ3v—«ƒÑ°4¼gþ´ £ß§yM{Ú`ú­‹”~=m´jŽr.³hIžŸEúe¢ ¥p£ˆÐ\”« ð.æÉA¾)°7‹9ÀÔÝASÞâð%ö†Ë8©õ²BCÙÁªYË:¾Îy<ŵ,ç^É×`ÖÓ…ûXÃb¦1š… eZDÏý0³ Ó³Žïç}“Ýäx†;rÊÀ|þJWÖ±–.4£k˜€79—Iá…¿™o3ž·I3Úämà¶PTö¡>“ƒ2Þœ-Œ)иÈEyç1žÑ9·e5ÛLO~ÎR±ž¶¼ÃƒÌânþÀÅ1^ý=•yK¸‚Îü”û9HŽçœjçefe>Îtä† –¾Ï}ô®Ð¤Âanà.®áEÞ£?ò×|àûQ~Á¸ µ¤Ðz–v0á¸9<Às…Ì`.²å™\f(/ð¿8H '˜Â¹Y,æ4Í¢“|%¸§ÙÌ å1ÆÐ$’µOÕ�ž QPþnçì\Û/Åæ­ ·1™å?™óø]Âù+](¤œq4Ž0 dO>¼×µÁº½™Î|‡w™C®àhT–YÊíÌ‹NUJ÷hÇ&öÔZ/Lć0ö¥”êÏâAklzŠEKiI¦Sæ¾ÍÜxµ*îáT1vláÖdƒÉ¹ŒÅœbOйã0´¡ŠÌ WÖh§žS±™Ë‚4´ýó³¤1”ð¿Ès½ÿaÒÔ–R:ÇU­(.®÷ã»:C¦J’ªañ‡9ÀѰøoÝ…l`×ñ—Z¹… mp<NèóB¡×?ÁiÈ4Žáq)ó;ˆTåì(—ҟΦ•lÂÛéÂîÈhÄ­cé>žÁ¬ M-çÖþÀÑÖœŒ çáë\ˇœ¸É´ êëPGiÓƒùá¥XA7*ØÀM ,Ò<oQ@ë›Ñ;�ðÝÅræ°>ôåWüšA‘`–bŸÞ „Ö4§/]"´©­#R땨ÌbhΩœë8É_"Ž!…°¤ÎIž¹ô‰Ð™O@{Ó”h³´±A¢ëÃhv2!ƒ0CTq.ÈÇ ãÕ¼NŽRÂÅÜ©.ç䔸>ó]Ã>u#ÓXPó 6òçÓ“'ÉÎßèF3ZÓ‡>ÌÍ<FoócúÓkø âCf0©À LA”~p„¡l‹‹³’ºìã-Ös-_à­¼yôfõȨ[èÖ¬&‰õÌååzíåuzq[�\ng>£iÁz.¢ „=nw$fý6‹ÓŠ7èÈü˜Šÿ¹ŽóhxʼœÓ¬@ßÌsg1ß`søbœEr73Yȧ<É^†r5kiÍûaHoE!Ýi_fU0 šRZ`¦A'éÏ«¼J[ž¤uÜ6YÇÛàÊXÄí´¤·Ðš&\p܆kp.[xš­Œ£4ÐyG˜Ç4> Ì z…î¦[ì*ø&;hÎ Nsv}–³Š^Ae»0Ì‚é&Í' 0ù[9#rÎÎj¦nâöN±ŠC#éx.%aLN•ÓL¥-4äwô¨eR¼ƒ³hYÀm"uóWq¦éÉÞÐ~ º3jÛ“lâzÇ[-« :^kCMÈiµ–²ô1Ï¡/ÛYǸž4ŒÖ´e>•t¡ÍÙÀâ¤*TœYÂiÚ3˜Þcx-ŽF+&9螣3GCžž 3-©*pIVãAìÆ¹¬á»¢Öl?x^X¡R@ש½]Í//¿‘eµÔ]éDcæSJ‡ÔŠaõÊž0|TR‡µ!0KBÉSlaR±Ê⫪ËvÎaSX£zRÊrÒ0Î+ãòÐ=WDO €¹œ>ñRó9WM§;Ýöq ìñŽ¥/çDçtÏç÷ªd8hE>áÚ˜ý¦£÷:ñ{8‡[ 5ÏŒ`(»™HÛFYÈÑŽ˜LYÞo(e s¨&Œ¦,[ö*0QÍ!ã­ðÿ&qvcŒß›"rôŽØÌ)±_vbK©œ—n9ÃØÂé ÷lãc50Ó4¬êLëé·® .N18H'pœ>T„ÊkÇ¢†˜ÌVĹê‡ÊÇìbs­ØE)·ñ_‘ ´˜q™Æd¼½¾×XI7Çø¶Ò-Æ“—F;¨ic·¯Ö€i´¥ŠY…nÍjêÁsXÄ^:PÈg Íi›éóö•¬à±‘)¬f@„ЋsR¾’³«ÀÅY?æšÌ³ì£=U”²‰þ<À ìehÁqVDGw#ØJCF¦vyxB•îºP0Nä/FÕ9€¦³†»É2g8+-Âw¿ŽÞ¬§ÇÊG\E5÷PÀ<öDÐß!nΙW (³Ÿ)ÿíÃB6äü!³·À¦ñÊ©f?·…UvUÌ_b@ˆf›†m/ Áó4QŒR”Ò8¸ˆ)|,+k R˜À}ì¤5¯ó=ž§==b“[”²Yc‹: KÆ™½jÝ™I%Í)b)çófNƒœú™²‡'^åö†ÿ²;_§w”\Ç8,†Vt ßUŽd «8Ì62’V|ÍÃÔ ëÎØØ?D_ç¿Yɬh«ÌŠ·:4ÖÕC‘´p„[#¼mr,Sgì}ETì-E ÷ŽáYSi´³´î•2=.~5G³ÿç_[Ð>¿Û¢ L.Õ$TkzšD¶—G»o4‡ ôΦ+ŸÐŸ=±wtâ³�; Þñ.2žþÅÅÛþ…ÔbvyùÉ@9䣞JÉ•YE7z†½éNp5ƒº”4T×07>çˆÈX»9`‹ÉµWÌj¶r$pU‰®82 ž)ñý€9¦ô°“±¦œ €_RK‚q´ÖR›ªïqÌæ2°2f$ÛkU@ßaH-Yùn ‡ãÁÀ;õ¥#›"½ôcJYšsYfkÔ†›™Âæp'‹øÖž…aFYJ{6M² 73ƒãq vf:‹hC=f…²îPxZÏa-÷:‡+˜Fß�ïˆ,ã#ÁbHÖýD;- Ù’€j¿B•Tg% ÞÉPN¯ ñçŽÈ³¯dP'•– 8Êz¦ilK»8žó… ²ÇÛ, PV2w >o)­™@+6ü&c·ð§p%`/kØÄ!–ðÕ.ÉiZåÝÌ¢8®ã’œ™YM×ôh€ˆ*ÁFögð"[ø Ïp$ˆS{$Ìλ+´0)‚¡¯µvÃ)2C(ãSV<{gQÍ+QÎrJ¹Š×éÉÄРO¢Û¹†ƒ‘מš °ylåjÞŒƒêÀÝŽâd‘ÉyÿÏÏ�� �IDATÉúPúÕ§m JÇ35ž7ã”P!°oq]¢ž]˜3Å];Ô?ÏîghÎ;\Ï~Æeæ¥xVÓ¥?ÌßN‘´Qc’.çç…Zg5!®—2½À¹9e™•áÆm=˜ma¿»5`"÷³“Ä„ï[ RÍj6òQlñ ›bÓ­þÑ'ï“™Z+Æ¡@Bg(y¾Ã³t¦oSĹ á@�N/a+çó2sh•äšÜÀÇl¡oX¦® á&ñû€¤€Ýu|B9 ù2õèÍžäâØSSÇìw1Žº€•1[MíÁþþ¿™…sŒwØÊµ”PwÒ8ØçÇ¢:€ãÜÃZFð7¶ÅB}”󩮌ãŸW]•²5_¢·Xg j%oTó)]È38óvì ç3?bQÖ’´¥#û¸’åÁß_\|óMS‡ÿ³íjayùÆð!§ à´W ¯À¡@.~giD%R‡"SŸ—¢ûWί¬c1'hÀ¥<Ç.Gp¾m‹Ò£$ð‘éÈŸ tɆ݅¾ì¤, ájî¨Ö:µX…GÂI°‰é‘sº1óizÙ5ô¬k©®ãÏyÆöß qùf6ñ …ÜL!¥™—ÕX4RÀÄǬeG¸“§9ÅZÆ9òm†ómr|ÀQVs}ð™s)«#7+Åú]Ï@–RÆf¶Ñ€«2oò(‰ ùN@VöÅmw„~½7;ù#èħtÃú˜ÌßÈÍFê¾+uBž˜­_Šzp™DÓùfT»˜–iDŽùqhèF®ç§,gOôâú±#ìç<IÀߦ!ÒvüŒ§ãè–’Ñ 2{ª ÈìϹ¡ÈÕyf"£3¦ ¿àú3:(¢»YbŸ®¼ÌI®ãVr# hËBŽ3žk#©¹7KÅn?åj/Fù©xd¾ËažàM¾ËU,¢;«¸†+iÊö°–±Á=º˜¡‘Oö­™I=Fóï,f ¨®ã¹êšiD=ºe†2“{Ã/y‡·¸˜y–9ÄTºµÐ œ~™ å4Ïwwá)gUùÐ5ƒüï_ºü¯?âø1>ji$« ¥o¡+™”Õ´ãæÑ7Fׇ©ËY¬c+3LÉy®È/ªmÏ|­Žó |C'D5™à[oÅwšÆÒC"¿*yä?æC¶pߌ!Ü—iËkñ,Ws;ÛÂà˜Úeyr!ä9Ö—äyˆAèSÊž¢+kYÅ1V3b¿á(k©ÂÂ4¦ÝÀq YRÇåý8„ßàk´¤]ð0¿ÁµLf(÷ðh„ §Øª"¾À'´äçÑ o>¤Rê…8ë4Ëù&ÝØH Ö±„±Œf5+9?B–[²1¸…G"Ba)ƒÂ:ùiœeOñY-¬ÁíLdãhÉjš§´þ7%¬ãtbq‘eõÍ|ÊQ¶³2¶QÆ.ng(³by/¤ˆ.¹·%0•'8P\\qÓÔÿÙvÕ©¼|whŽÕÚ]7ò>´‰¢o³ÉsgPý·Ö’*$¿wŠþ;ŸÕôæºÈªO o-5R/ˆüã*®¦g³žJnVáθG÷F‚íøˆR‹½[…ÃiÚÒ'àI¹ž^³G˜‘~0ïMZÇûŸÇsŒ¢³‡Ó±—ÑìåáÈ7Ì֤š#Īpð¥cÄzþ*¦ê€ÉñËh$mH½ø&ï³(Êœ¶|•Ó¬áNð2³8άˆëSŒùA7zç>eV\DðëWrq-£nÊ2O%ËuÑÒ,æ$ãaþÀj°“=·èW ^Î×’õ’ÛÙEn£.óxS4¦)MéÌ\zÓ/b,’Q½9ÃéíÞ¬boNœiÁVºp=Ïp%Çò5(ݱU°I m}uÈ? ¥Y ¾Í8þIÚþÛ Ïåõœ¿úQæmfPÎÁ”p‘y8§‚{8D•ÜÃØ°¨¯a_Ž4ÝÒ9ÄS¼Å1RmÃÏØF7î!1e¦Øt/ðõ¤ÑÊûOvrgÎgtà1ºòK–±—gØÊ `6öŠ$ø $óV&Ï3Ìe*J<YåÝœ+Ö8;½Ï<dÓ·TÍg|¹þU.àUÞÊ<•9À‹œÊù.]x%žµô“SfM¡ \‘y"_cܹ'ï sG uåT(ESVdâÔãzðe,¥-Wr{^äqŽ„–a,&_¡N0ÏäØÕålGÎÙ#\!œ†$!‘ë&F‚Ïê2†…œv•¬‹&ùjŠéÀÖÐΕÐ9]òÞ¤8ÊЗ¸™å¬¡#ßg:ÝyƒÃÀׄö\Ì ÞæMÙI@ÓØM?6Õê'MU3LJòGlgýøŒ6ì Oz9—|ùU¦˜&ñº’À-a9? Fkr¤Yl žæ]zqnìO{èÇ”€„½R—±Ìc =©dN°­[E¦I?F°ŠÅ¬Š,®«8—þ¬ ‰_–3€ö´à`qñý7Mö϶«ß•—‰™ÐnF°§Ö¦Õ‘o» †ÃM(d!h ú$¿IS–¾ÁmlÇp¦GPfÒV ágá7êÌJÞäãS´g#)¯å¬Â2¶Ð›ú¬~ɰ-‰³8Yk¸×=M/â¿”)­µÉaS HNPÁãÔ‹hà–\„ëYF§8Ö¤‹“^á ØÀp&±!Á±=³ý¢”î œäÃdfSÊ߸˜K˜‰òy®â­ø'"¯½2$a×°Ÿ7Íåµ4Dš0(²ïr f•Ïü@Þè®Ðâ§®`ê&Í}›øàÉ “jüƬ.Ô1óWÑ€~TQ‡ŸFvPÉxÞŠ!móÆ:UZG3Ó:èÑp”uLãÁœý97fªYóØcAÔîÌð8Šm eÍô$ ¡fGzs~œ{Ö…¹ðü0¬¼ÇhFPA3>ÊjJ„‰ìf\Øá‡ê©_Ϧ"߬VŸç)åõ�˶‰ùÄ0. @Æ>ú„j±ålà»T±Þ,¢o†NúHh‹ëDjhËXÁx6Çé¶Y<K 4Íüšjzd»ùGYÌ`NÆ`i�s³zÝÜ÷¬!;¼ÝYy ½"{~ bØÖ=ç;e5%ÔßcB6’c8,“QNŽç¢êíË }™y‡s¹ž¿Ñ‰Ô ‹è©Èvº<ç@Î}¼CŽ^å5Ÿ´a8«È¢Ä™Í.‹›| ÃØUìÀ˜�%ÁáZ2±Ò˜ÜËQ¦ð zÔ.%ä=N Ê|”$šqP+¦;ÛéA%÷ÇV‘òûÄaâôUã è’®œÍÛЃ½\ÂŽZý41CÙ&™whÊ$ò¡_ŠX“T‘·‹ ‰D×+6³×ɱ pºåq<h‘Tã ˜rÆ»0ŸDÄy: yE ¯&±{XþwiÝÙxô)¡$˜¼â$×(¾Í$íІ…®Ì¼•ÖœââÿBj1«¼|Sp²Ñ.VÆQÑòÚ︔§€&T‡ùëÍÏ'Ê_œÜ_—ö)«-×Ç.Ú0Ò äÒ`òϧ#¢KÖ<"ˆRɤà­áR:Dkâ8ãÃ'»î›4¢ˆìa½FO6~ž:¿)ÌÎu¹>||ÍM%•\Éj®‰ˆ³}ñƒ“xŸf æ#ªÙD[ZÑ“i4&¸Ø“œ õD1ïq€óX˜Î5!÷ªšœy—Kˆz½¨âx¼&ðg…a®% h4ÕW8‡k™~ø}´à+a'ZÅýQpµ‰°†3ÃÛºXÊ ¬¢€†Ì¤ElÃèœiÁzÑšWhFßH×Ìc-§ ݔՀ¥Õu¸ÒpÐ×89=lŸ§ óZp¯ˆ;jWSªf[.õéœÃ¥ŒÅy´aA¤ªÄe¡ÐëÇ!V¦²Žb~ÕÉ Tr!MBز6³Ÿ¹EŠ2[«k¦Œ(g$;¹™³8H#Þ`) èM爭KŠÙ˘C Ò.g99H}η\]&s€~<ÕȾOОtˆ`ªÃ´È9ž¹!Ü 乡îÛEëÀót«Q$íiy/ߕ۷³¥aåf±Ÿ ü ®£U|i_àlfÓ»y:èJ“h™N`¬ ‰Ý\ò4f ûXAgfÒ˜N£'mBÄ” °{ ýG¦‚¥¬kåW'5¡Gx©ÈѦ¾U¡.ïs}ˆ²§¢ ”±>¦÷­‚—@bm8ü|Éû¥QÏåhZèüÌ\š`¯9í3íc4p4º]˜Kå©p L`U´XFÐ32HëämÇbñ "LdççaêŸ&Ò+ÅÑ™@ªØLCº0—fd‘w8žÙrZ1•2Ú°„~1<KÓ©>%§O¡+3s©©#¬`o€6‡ˆ£1EÐÒÐö¹4f§9\×Ä1´<¦SÇc•;(d6=F]êÅÛ¾*Ó€öéLùÿKd/©µåì«Å(ÜÍÏ)b‡V݆预ýŒ ™™ˆLíàŽ‘jx<ÆKûÃlâ�»ƒ <…SÄQP#×FA”x€§kQØS¨U'C»!ï©-0š‡É²!±–'ÄõJÍܬÖýq7ǹ–u®ñ•XÇ“cñ\Þ¦/ƒYÄ9´ HÉ YJÛìÃz&0‡2ŽSÁÚ >¬úüE>ãñÃ…îɹ-³Œ% “ù(‚DK8Ȇì?c÷°µÈÔ¼Ÿ²„½Á€¿‰Î¬f›i]¸Ê¨ÔÒœojøÅ—">ãް‡„£ '¯…ú¨€¼4ôŽì¤ﳎýt`? ÝÂø®a“Ù~Z[†óGvs>?¤8ÀN. šYb¬¬ãXc½ë)>mcxšv’ÚA§{$€tŒ(Õ¥Ñ_šÃЃôáAšpœ?ó-úr6…¼È}ü&èÔÃéÊûÕn«¶œ™E^Î;N%Å6…aùa®LõG‘¯ç½Ä\Bžâ8³#¶“_°Š.¼A)íø–Ò22Ï›` MÃ~TEkþÊaJ2½XšŽqHíÖ?Ò¯Èòže o²‡/1+ìéªt§óFW¿ñ¤»[±Ã¾D xîÌbË8Î^ÆRi¿8Ä8z°‘ùz4V1‘tãc¾ Ý$Ñú˜ÍœÃ¬Bų_–™˜ yƒ«<ãíª¶±º¦¨½Ó,d¸‡ÐѺœ¦ãæQG¦êDx~óŸß«ÊØYˆ»Ã»%,d+ýØ—Y1¸‘gJÎÉB#3²Ÿ_±”A¸HÏõmŒcZDmufù@ËŸÍÞÈïþǽ*Í’÷ÇLz×2“jÆGÿ 3£á™:.C¨ÃOM{¶0›m!U;T%!.ÛÁº0¼®ëðbø,ÏÈ.å$9FÙ=‰-¿Ïr¦‡³>©<v³ý!¸?ÅÝ,cJ8 7D?3Ñë·1<ÎH9FDnçÿm€È¥áB½Ÿ•Ñ]y-RØÏð?> ÉÃ,¨ÍN]©QßMŠÏ8S¼'Üía¾Ï«\±ªmùÓ#`­¢–èVÑ„íñEnßXÂqNQÄ=|…¿Æyÿ%NðL$;¼êþÅÌɳ—£|•°›Ù4d=ÙÀ1~Ï»¬gI?ÌËñ~ÀËë%06­#1=1oª™ ·†òjW­k•†4«yŒù\œ¹"ó8—ðg.¡:BèаPŽïE7¼ÃùŒeÜHcæäý…\±¡Ÿ±$@º_ˆ‡0½ïQÍ2®ç]¶3<”Z%¡N³·æ¡ÿÜÎü–n,áºø Iõ;×YThPÎÁÌ~̳´£1Oñ6uiÂü€Ó¯e Ôq_^{f°™ù˜óyœÑÁ[Í›‘øu¤ÒÆÓ> zÞË'<SÇsyø)ýøo^䣈<?Ê Ô£çЇƒ|ƒ^Œç[|€®™,§~è_`[› ܘ9ÆPÁß)ÏûŸ°‡™æþP“v¦nt_»æý”¯q"‘sëx ï|ª¡aÝÉ1þÄfndW±“ky‡hÇašñ)çpÃø+ÏÒ‚óÆŽ`,5e√œ”~™+Â*Þ‡ë9‘ó 3xŸz>Y½ê•Ü;·ÚÜÏw×Ôùðéü¡ÿdOÎ`®çlêÕ LH!àC¢+¸Œ+B”´$ØÈ(àMÎæ)ÆDIÔ˜ŽŒHÔLk–ä<W¨]Þm¬ªãÓ hËElÊ´¯v5O²‡y ãÃÀ¦€ùúœEOPÊ >Êõt¼òµÄVEu~Šäøoúsš1qÉ\ÊV–G"ÔUtà¯Y gk/ó8Á5vïQ»dLËéÇÃQ¼¦ û¹„GxŠÉµ¼·m¸4ìzµ1ÇÃ<Úƒ'(åwü&Î[·F¾ÒQ x‡!·»šKx‰“ü YC†²Œý4áfæÄ¬½4ùßY͵=ãŒ$It¥k˜ÍŒáž` %ôäë¼È¡h_ÎKAóú¨–²<­¥1îÍE}A^›7úˆÛ=åå»#‚³$€ª©Ç… 9ÍU1[M>ÔMg:#›£,r³òq¼UK QÅÚP?bã{ñó� ðAYlæ3kÍ™²ZURʨí̽á¿YCû8ø7¥=Os+óYAžîôã`4…¯`W4‚RúY²ŽÏdv´’G lEÞïãu²ðü†&T’ãlÒ!vÓ+!"Ú–G�AzF”ÉQÞâ¬çWÔcMÔ˜4/àÎæ§Í¯6­Úmãô9‡WxÃdÜÎÉZìê*ªè‚à+¢½s‚9¬ •üî8ð͉ó~úÇ5ÿC’¤J÷ÄÀ¦‚Öܪ߮lϬÈsorà ÝÖÐJ¦ÑG’÷0¯,vèOyˆmü%¢Š›³) ¦d+ä†B3ŽŽI@ݼi|‘u¾lš39næÖÌÊ©›SÊùˆvìa¿‚íoÙÄ–à“®¦”/³=“eöX–y“÷㤵6,ƒ/±^4äIî¦+Ë(f '9÷D4*?cOEÑ¥¬§5+éÂÿd{9)´Wð(Ëxš}Tñ»8ÌÌðl,á}®å‹9§szSY¤Y^ý ¬Ë¼ÀÛEžÌ+¦)íLX+»¾àwd³6ùý¥ùYzì!r…nå�ÿ#}gSÍ#P{CäÕæÈ©Ï—ø/±Ž1DoI)£˜L)#y•ü„ƒÌe2ýó>àC®Ï[N_ª˜È@pn ýäwah‚2/f´«˜Á»ì‰Áð™`øc±VTP8Í¢¨ËÅü³ØÆ:æp"^ó)fûiÀ>Þ‰'èú�ÞÆYÔ£??¨Ò>öy ïG4åS6SÁ ^§»Buæ†UI Ð?ö-ÙeÖžØ5Óÿ½íK_â$[¹€›ø }) 2ê÷…šò± YRþJFø,g\µÿd>#k"ù@Ús.k™Aƒóé®›Üú¿ŽËž2{çq$8¼>¿ WG m+ŽÓ㵦éÿV\즩Wü³íª¤¼|M­×ªb=õéÞ£´=ôãèç7žKxþó?xˆn‘jóÿ:á¶à†xs)K­ShQv†é§7e]nRÔíôÿ‡\çDßHa©‡°"„×qF¾˜“,åXX©wÒ‘Ól` ×Ó9´IÓ‚æcÚ‡sÙO?¶³£–lò þ5i]raÁû ÷°žçcýJ÷ܨBå™*pC~WÒ‘>”0ˆ'C$r˜걞¹ b7[*Ì®vyDW|‡ÁŒäS ÙÃpŽ„ÝòL¶S‚h4§ŒÔï=/LgˆÆ%n-äi*Y'Èlu9ßþ99û \žy.’­“Rf Ýxí 1ŒB2›!ôáY6²Š1œÍNÚð:}x‚" £X.ަy¿PF´§ -Ø›È7™5Ô£”7CN–ìÕÕ4åbšäÈéœYò‡sêæ´Ê4c7_eE@ŒŒ$ßÅaà]ÿ%¥¡×eL™«XÁóÁ@Iª§s¹ŸÙœ¤Í{QÏ&~èßy“Ætf9…t‹œÃóYOÿpÍ?ÈZþNÖÅØró“4¹À—³š Ø!”Ò;ÆÝyœ+š;\`t¥r>Ëi—Ù—·‹™µ™æîþ?|Ýwœ–å™þÿ÷ýÌ ½ HG)ÒAŠ€€€V°!TbM¬ÑT³É&_7Éfc’]³1Éw£YÝ4½ 6@QšôÞ{g¨Lîß÷œ¾Æo~›ç_ÀËgæ)÷}]×yžÇñ9h·˜£µkè{Mz¢žÍEšV[©e_«¬™j.Ÿî`7sˆ%4HÉKø8§SÄŠP‡V²:ÆSÙSà†´öä׉¢Ý’ãáX¸6�€¿æJ±Jmýz-‹sîO­¦ hGYOcšS?¦Ú—×YÚre‡q>Ýã0·œ t ˆùÔg� ÎA†‘PÁj2ƒ!t¤1ǹœRÚÓ˜­œfu ÈZ²‚}f7¯=¥,ä$ß0˜£´¥sŒQFÅpñ<Z±‡hEÓ¨NVRÍ`q.ËÂZþB?¶QÀ~nå/Ôäôä9N2‚Š0ÛeLêlªt>-ØC5W±‘%©mi­Å¸?³ê|8ùÀÀvç`lÌ¿'\üEUy¦_èÃ!D¬ûÄNŒe%ç…°p�ÍÈO½ñ–ÎÿÛvõtYÙø¨ßóaŸjH}ÕÙuörÕËÕeñ‡\؈!EÛðÅfqQH²CÓɸ"Ô1 žËhþ,äÏq« èF!§¹“ÆtàŸù=ÕALÏöÈ)·|"Fn™…¶†~A1Ï…ÿdèòà ­ã=~‰Æ¬¡×Ó¿²Ùce"™–d}ÜÏ{cV·ÖL`3ƒkÃÁzšy¬‰ÌŽì»œ ‹%\O¿p fg·7Ãb5”·Î\z…#dC)Ž0”ýñuì¦âʘÌgáÛͧYu•}¼7²ÆY:_$·f/ ôdfN”¤vSJk®`1¸†óc‡Ë®æs6"°¸”¾®QÂ’HæÎ"e?¡!-éÀ̸² ÉO"rŸÐœÃq>A»ØlÞ «_ Žd“ÅÔ!f°Ž) çÕÔŽTm¡Ù=9ˆe´c Á¡° OæCÖµÔ±ÂGim`tr‰–Æ¥µœ´kÂÈp¬oeWì”0Šõ$xµì§!Íq!WДéŒá0ÝØQèGyÛYàB^æ¢Äg©ALd/0„b$ð<e…úÕèYí,Mk=“Í^×nKÞœNÞíõ°Y¾“˜ó@²¢y=R¯Uû³_õÈs¹§G$’ÔB¾Â&.áË28oήg]6HOmdÃx:úx“øÇs†'&¤&º¤~GÕÉJ®§%ýx'’‘w1#r 3'ÀpÖpŠn‰a©¦㻜BX†OÌ¢G/`)Ë"þT,/¿˜kio›}'=)Ž¥`«8‡×òSlP¤,lðîh!¾C¬L4xw &ÖÑsíâ(Õ¬f3Í¢±QÌ(Ñ8ñUtå8ïPƒñÄl®QþŠ,ë<3¹1‡zŒ-Ðíi­Iù`À|w0(^Ï6¶ÅÝ·‡C´äfv³ƒâøÇc›¹•&á}Ìòå›ü] 1!>Õ,m£Œzlý»•ühüù ŽPŸ%ÜÆÂàÁ¯...»ñ–‰ÿÛvÕ«¬ì­È!>#÷Sá:º/*ªÉlf2åôdEÜÄ ÝázÉ$[{¸¥ÎÄQ®4°è‡4©mŠJ°4æ^ê<±Ã"¢*â±KXÀ$ö†«à+‘0{/‹¸< ÙKM9ÆéÀ)e¡´Çâû˜níÌ3˜!„¿LóCêìX]éÁ˜ø¬Î¡+ƒYG ~ÀÖX³2i\%óSos(Tøe_´ÜWpŠËy…IŒâCº‡éaCx¼2òæIÎgۘ͵,á4Ã#¯äbZ3†g½ \™jíõŽ<ðòÂà6•r53Â>™á'že_a(Ÿ°—mœ¤ŠŠÔ&†q+ïóYÜr[ø€EœËæRB+ºó‡8‹ èó?‰,†sx æç'¹†<Dƒy׸ˆ9,ˆàÇ»h³ÏLàðY Ü/¦³YBžŸqŒ~ âQšñ빆ßï`5—23’;0‹Á‰ÿwZp½«uÎ{šÑ¬âvîæv±• 1t,R›µ1›Æy>ŸÛhÇü¸­j¢g2œ—­ =ž×•—èÆgü–³Y”ÚÊ¥t¡ijÇRߤ9sy#9]r:¥>`41¿Ò…Õžb?“ØÃp~¥ãÿ˜·¸àTÿ3&–÷UÜ¥Y‹Ùwúç¥þ0ÆñÁÕæÕØÈÃ*Ž«xÅßV»o¶û–¸o¡û–)Ü`ñF®,ò@^CžM-ánÚå¬O4L5àE¾Ç9ìç]ñ]JRËé‘zœ4bð}~ü³ßÓŠ[ŸãŒgƒùZæšH½pôóø ¸£Ðùyÿ2¿J…ÂöQ^ÅñƬEÉ YZ·Õé8[dg¸šWÙ+L¶âµ¢çñ8b´‡2>ó3d`ò•ÑÎò¨ªø hRº ٌՑupš‰\ÁKlåޱ…›bpp($é{ÙÞLÙ¸7øAÛÒZ¼K%]Î vq,”bUÏÒXN2™ÝÜDïpj×}´á6ž óVûòwa™ž¥KüÆL›“mMÿ–Ö†Ô­S½Làe¦q†8t’ÊââÊ µøÏ²²”3™¯È‹y¯|q=ý KYÎx´p7“MgGIl¦?SéÍnfÇOø|ÁÍ0'«B2Õmý"WBœÍ‹hGi<ñ1Þ¥?à ´‚&\Î8–sI¸U2åXf×ÝÌù|F{¾Å þ‰{£4ÞÀ]qи‹Ç#™;cu¦3¿¦ Ôæã}.à9eûB:òÆÐ–‹iÎÃtËKž}"’ ÏÔ‘\®$ÉÎìã.v±ŒÉü&FwãhÓœÒ 9ÝÄ.–°‘;™HA0Ù¶±“͉Åù�� �IDAT.NýwÀJN†4£$JÒ AYR‡eÕŠ¥üŽG™Ï ˜JBÃ)ÿϰ† ~ÇE¤L¤/KXÇÑØÎr4çIÖG#¢„y½¬¢͈Ø~V1šûø¿ã‘�½ËfZð—r)+y”#4åñ¸>âE~Æ&&…{ô)Š[FEµÕü³‘3ÌÉŽS‰E N\S¨_Þ ò>33/gÎÐTGÞæ4¢¢ÈwjTD^ð þÌ{lg;%4 :Ãôá‘ìYAkÈ™ÉÌÛSàÕÄK©Ôð;ÊÕ–#or†Ÿr(<7 êûRjfªwêîœ/'ú§¹ê²4wü_s§^§B+´Ù'G ¹&ýpJzàßìkÁYåWm<ýjêæÅÞ›ž_Rä&¥þ¯ü$k‡{ª‹'/òäMž\æÉ‡ ¬oÖëå7þ éa¦:¤^g¿g-M¢ÏyÿÆYL¦‚©ä4s8Ä=<�ûŒ¿8‚ÃiÁ÷ØNwöð7f1žg¹=èéæÜ¼µt“q m¹––ü…[YKkú°‰ÆÁÊ;C#n¦'ÙH9íêЛÇlx=å<#€vü1d™¦fNtíFÑ xZSé‘@Mõ]Íâx éÁå¡¥jqSôåC…:ó¼^K+ºq˜¶üç0(¶«:r”&P˜O# +Çš(tšRM÷Б›ØÎ.â5Ê¢öÊì@2’I §3.æÙÿ‡Ùìç(w×M rÖþ.K2^Þ\nâL ¹'‡ßt& 8X‡ãz ¿,.þøÆ[nýß¶«yeeÙœ£%ÇóÞ¤{m³” `cØÜ²#CwÆÈ\Dr”Ò0Î ]¨Šóõ©°Ù¶á_æU†Ó…×õÅ�À–\Ï^Š(ckhÁZ¦ñçòUfð×AÝƇèK=Fð_æÃˆÆ™‡â¼WjŸ€�•Ðqôb8/rsHä/ I½ðx«% _ÉA^å)ñ4i,UGˆm&ŸŸ›°ãdÀÖìg —’ãEú²-¦Mø X”’Ôº4æñUNò&oÐ*Ì=?æ¹Ð^f蔕aù<3{ tˆ ½#ô nSfåÛTâۘ´c%[™/ #ciǨaU(©ÄŠ0–rðUž`å%ÜJëD÷¤6÷�›èAß@—£ŒßÓ‹aÌåJG¾jkJÕf,õf>s(‹”Òf”ÐŒÙÎ[A xƒe>«¶{y“*þ‡{9M/^)0•E©?æ]Àºò/tg1kóÎc:;¿<0ï{´£5çr6sø0ñ“Ä4>â'œM úä|jI«D›D·*<ÅÖð'Îmê íª5çªý7Šý¯$¼ðÏ'&f·q°Â95®£~êP:ú—ɨݧõ©lü^Z¹ÏÑnÜ–Xžs¡-ŒÞ£º8÷î‹©YÁUêýH¿¹Ý—iÐTËíõVÝÚHó2KsîK½À)éÇÒs¥õŠÓ‹ËÓK(+vÕ¥ƒmí"©²@@ÃpV²™EÌãHô?ótøà¬_ò##}03¨Ž#EÇMå ^ÈÕ*÷ŒnK¤œOO¨ sþ‡Ìͳ›z¤\ºÍ몕M¦gSÍ1:SÉä�¿}þ¸Œ$RHÎå83žc,çNÞg¿ÚˆÑ,D)Kºê7r“/w­böœÝhË¿[”bÙý˜íßëØO0­Á‘9ÉÕ‘ð9ŸÜλá0{Œõá”í°›Má=ŸÆQÞý‘—bŒ’rbF¢Ý‚žÚŠEtaëhJ¾ÌR C(XÀ{9W¥µ“‘•\Zg•k]G4ž•CÃ9C§àò ŽjçÿŽ/-.>ó·–•e¤†Œ‰~W¸2™Ç8vr†ÖÕy5ݨ!Ù¬¬K䨮â(]h@?ês,‹Îõöð½oäx¼™sã7ÖËé”ÖJÝJéÃι) €JÖGò²ðâõ£'éÇq¢9·r8c î¦ï2‚Ûž¸,ei V1„el¤"¼ YbáÄè+f ¦‚øpDß¶ˆ¾,¤U¤ol ýB–_Õ[Yž[FÏÛqS?ãCneÇ(Ï.ë\-¿ò٠˵Çn&1ØÊžÿ¿àQ_ÌÌ>ñnìˆÛ kˆ*³‹,óddó¢µ}!Ë­ù4çrž ™âÛÜ"»ÄQFí =ØÌrnf Ï$µŒÇVLaUd‘¬/pwêù¬+ðÝÔZ6RŸ¿ø¼ed+·à EÌJK>‰°íq!nìÆÅ¼×À”"ë³;Q“Ó+õA ®ZR–:Æ£¥ Ý™Nû^¹I Üžj“Aå 4„ÓànÎÆÊ"tf=s&¦f² çîå±³f"Æm´©p¸Zž‰|ÈNúDâøŠÈÚhÉE‰Þ‰µ'½[ã;‰ÿÈ™œ^:Û/HŽnø«;*.=lÐ^—ô°øPröÔÜw¶¤ÝKµlí'W$ùÊÔ²ÚýdVËÒ‘ø÷†ž=ZóD×r X‘Ó25Ÿ=\‘s[5Í->¥”y]á•kÌÿ‘ý­;βiªIh²–ð?gM ï²Y}g6s1U!&<ÊOXNŽ…<ì½È*|Œil£ ›é™ó­ÔGlg$Ã8H ÂãQ싸™ìâÖ3€¹aÿéu℆pyp²-‚?gÅ®ˆ”ÂKhM.¦‰Ÿx"Õ„Õa¹9ò¢¬P~5FòKÃjý?aUv ÖÑŽ³iÂ|Ð?kMâºíjÆA‹ˆá®TñTÀáZ†6»XÇnZqV°ºÑ,jµ™áè*¡‚ÞœË\'ö$&¦>e1E\@}°„3±t,¦;¯Çt.ûsÆ¥öǧº.Žn‡þN»Ð‡yœÅV†°ƒ¹p;+Ϲ4 CqñѰ]e¾«ÃñN2“óçš‹E­›»1œÃœˆØ‘¢/d"‹%gmG13¸–-t @í:&s’J²³Nö<nNlJ­¦”l•UZ›‚\Á/¾Ï<r¬ …aaX’Ç…[â§¹‘ngŸp=©bŸq”Æô :û;Ñ|ÛÉaNÓ’i´æ)šQ?ÁÓè0ÇÃIsQ ûïäHPÏŠèBãc–…Âû[C|#Cy‘nq¡d·¤ÖñvôÚÇHéL|k™àemì—ßbþßÙø»Ó“³Y>üLL‘Þ‡1‚î¢M¨b&§"춈oØÇ¥ìc bÉÆèÄÚ#R¯Q?ôŸ c˜Èo™@žÕ”óešò._ 4Iöb>NŒI=ÏŽìSM,H]ÆzŠâîAþj¢Æ\Á"qëø!¯0œañVb{Þey‡8”xˆƒ¹…ÁÏá˜Þ¿&Âõœd /ePóÄÁ´ö¤|/Ó‚zt`3(OÍá1Ÿm´c`ú—ÿ0xoî£ïÓ5õ"Ÿq„vóÏcô¥o o®f»M'^æb°‚÷ÓÚ>ö`¯ÏvÓ…xö|º¦æèàüÇ]9¡üe?ÜäüÍé'/yo é—ÊwKÍiª¼PyU–ät^‰bÆì3½ÚšV.-Ò÷@º©)ýÍÁç¦f–šQà¡TkVÒ³°²_þ²_{u-õßL½Fgssum´}^g=—1ž¿ä´LLK½ëTlœ“‰¯¸,u˜–t¡-à0iZ»ñ|̵¼È'$ãjªhÆIºñ}§myK¨ŒùM©é_‡u´+˜j nÓ×ÖÆ1ï˜ÀqfÇ€ygW¦µ…owVÄ/‹“w7†²Š<WçìMtH]Üjax?MApp~QG™Îðvvs ³9C!m9Cãˆ0}’‰‘$þ<=¸‰•¬b9…T±)̲…ÜH)[¢§R?ŽÝEÁ¤èËÂT}곆z ¦(tjÙ^rKH(¡—2™Ù©U|9XÒ7F==$ÞcÝCs†éjæÎšx©g"¬«?G™_\ÜüÛ„Ë)Šç줊Óîžù®ÒŒC$ ¢5«ë(C²¢'“ó5‰Xúb.å=®a9MGŽQA�##š:gP“i­HwSèIc–FÕqÖÒŽÓ æ½€3¥¼T[`æ¾¼ƒ}<D¶D£`bÂt D"‡cŠØŒ«b`{ðÜŽòÇbuˆ©Y›Žsê¸{QÄBŽð5ìgoP$ºp ‹¸•Ã|…uq8Èä-ƒù}¼Î&ì¥0ì_¹3O²†×ÂSu9í©ÇzNs>Mh?vT„ÖfÁÒìá‡@ï±µ£ ë˜ÏVö†X+cX´f[8|ûbøKüšKÌü‘…Òi[iÃXþH%÷RÉL¥9[ø)íøonæÉ Õš ̦ŒN%ü.ld 3iÏ‹œ¦˜ÿ`ïrÅ·ß‹Ëc7:ÅÐL£˜WšWEúð*Ã8Ƶ çCцe‰» Ýœ¯ éÅ{ÁLªbKêb–k|pøygs5OÓftetÆ-,ðËÄñt÷ÓnéáÙþ©5LåržcL8üO1$ŽºYØàäÄy‰Þ’4<WÑIE‡]§¨±¢ŠÆúåIÿù±¯65ëW掰âcUo§Þ¦Æ¡ûmXiÙ­æLõÙ�'Vó*C¹¨F½j R×7µùŽëš.?õÍí~L¯í^\åÚ­–.Nv./tmÞ¢Ô'ùZ4è‡-´+pA•~–W4îžþUÛ§[»Ò™ü•%Tðu*ØÄŸèI!¸ƒ£<‘j—Öƒž¥/šáºà>NWúò×Ðè§‚ñ\ÉHþÄ÷xš[¸­ÈÀ¼Ò„‘²œVtd“ÂË37PIg³—vЙ¦ l‡ÏWSN¯H3Ȉˆ'˜È¶T+~ê åÃÕÁþ¸'ravr<Õ6õaô¥Ê¸ëXFæßʲ)fÇî’I^§’BîçÚq3,²pDz‚„±Á]€…ŠøQ¹‹shÁ\®bM´CïeNT6ûiÅ×Ù v»˜ À:Ÿèp¸Ä¶1+$Ä›#›0kõeÑ1"uìeG©Z‡�|ObV]\üÃoéÿ¶«¶ü£L¥Šz e·²— Ìç(Utäb^¢u^P;~É›QWÒ„)\€ê”ûè˪è/¢cä4f‘Ø]9I·°3Âva}�HöÑžãlàÛüŠr†rk(îÎaBìLY†Þ>æ5®àMÖqkhÎø€—d•ÓvÚ‡¶2«™î§)Ÿ°›MÜÃjʨd<sy+XÅ-ØBK®¢ @®ÿ3̶!‘_C·EzBšˆ þܯð ËéÃй…ÌèE^Ìׯ¤foía~öÓXÆþˆMÊòÝ;GÎï aKȾµ^¡Â¿šÝŒã™H–ûaÄ¡ÞÈË,ã×ìç5îàÑø Þæ÷´ ×ó8›)älFÑ0Bë§ss¹‚§4ÞŒ‹Ê¸c8;B8ç3°ÀE‰ÒTžM|ƒá1ûvœË`F'^£?ò71ž;©*24ïÄy‰{ù4ê›@}š3Ÿi|%úue!)®fTÞRÌlÆqs³Û¬žGkL¡}yœ¯ñ|&‰²BWåíL<È~ÞdãY–j˜úOû¿ž<{~ÎÐÔ³ìã—4ËÐÀúïÐùÇÎulI¡s*mrÜÀU;öO;>]Ùë>ÏþÌ ÜYêÎOÝù¦;$w®Ižúç¢ïþ,ô¹ä趤ürÖ&¾Và{yKùW.rü)¥›é]`·ò ×¥Šx'ñLw÷TæÊç^èÑo¤½Úšý©Ç:™ÛÆ%‹* ·ßVã5^f<ã9R®m•Cõ5¨®y(¿â y¾ÝÜž6ŠŸÉuœ–tüJÚñS‡ëË÷¤)ó¹˜GèÀí<Â)ðS:ó7þo1™´æ?çm–smâ…îÏû ­¹.<Æšp%š2›'òþ˜èÊ&Æp†¾ìËíPa5›˜Ëüˆ¬ŠÄ êĪè(”‡EäPœÂ+c&Òƒ\¨Zð[ærsÙÅL¾)0Íùˆ“|‡Ftâx¶ã§W…в5¿S›wC¸Eq{œ×{qŠ‘ÖýY»ÃS˜Ooæ±’VÑ šJgÆGrt¦V½ŠWâ=þ ÿEÇa—q’Ù\é`ãUÓ‚Ÿ3Œ–l¥IlW5œæ$yòt‹ÖTi°â²ŸÙ1^ϵá ¢ÉTF££A:˜& ÎNÅÅÿquUÅA1’¼nƒ•¡ìIÇJ ;ÃOWY‡êý$Õt£G#2ê÷Œâr^g«)f8ƒ‚«˜íd=™EcÚ°)Üs‡êX»RŽSUç~B‰}‘Õ(€Ù¡l|X53[îÙÁÕ^Íx–ªdmÈßXé×ÙÒÿ¹*ïuêsNLbÖTþ3ºÒ&!‹絬‡;/^êyÜÁjî£>›–ã÷3”} 3Ò,†¨m™Ä <Ì:ºp:_ëQ+æÛ¬âì8Œ×µÁe1¼&˜l€Ô£—ú¸°Êi ZÑ@ßÇüì°“3¢‘zUÞà<fÒ)¤¡Éìa¾§¢i^¨OqΞT[–²!,_órîM}™©a à3º±˜s~ê©ÔæTÇ|!B2deC–fÈÚS²‹9SSÃx‘—òÖQóŸ9MR/’çE0/rG³4‡Ý¤95ò/U6ÐþAÈnЬy҃ʼn iž] tK•¤Nç—¸'§:uŒBD°áÉH4ž‘jÄ>dR¢o2°±«¹z«‘ÅúpNßüà“ƒGçGtqÕòÒ¡‹+‡Ö5ï†1ÉSßKžºÒSwxj¿§î+xjlnë„js <@ÇTý"I3KÊü™Ÿp€ö´à¬ÔF3?'Ú¸*gÊ!æ|#µ8é³^|6yìêÜ˦Û&åöŸüzq³5Ee[²‹ph`3rÅú1‚Ö¤žšìîÍ.Z™]’]mh=Mû$+çœjàHIÉ ÙÁ9ì ¤Âù¼Èn.ä›Ìam3çb^×(î§tÿCÄõ9S;¹˜~›Ö¶²—óSÖЀÞqÞEg (ã�ïp•œ¢y’²˜˜¾‘ÜxS(¿®$G çmn5gXM{Îâ#†Gâ ÆÒ…Ñ¼É’àæÔg[( b΀&^Gƒh!îà:ÆÐ5®Ï™ógò|DÂ[œ›Ú•ÚI ë) òV&\êÏqÆòй’¥aÐlqˆ™7q {9ÉZ‡Ô`i¿:Ð…­¼M_^«ã ú|H„*Ð*>U±tâ¶h¶oŒŽ_'Z^uc�ÞJY˨À­ ).nuã-—ÿƒíª>—ªõUZÑ£ÎP$Û9ŽG•i?åHxö±5,%t£‚ÌUQØf=ÐÖ´àÝøv³ëlS¸Ð›2(ìýûê@²SߘճsCþ˜t .­8Œd¾«Œƒ¾;®ÈA àÓˆ{ÏTC%Áîüü‘}µçpŸRÁ.d-Gø ci¦¥¬Gú‡ÙJ>¶Õ½‰¨É¦¡1ß`E¬çÏ|+Ñ5§[Z+›¾–zô¢³¨G3Z1–9+šŸ«êp\>¿tÔI±Ê›+"2¸M€ðGð>7±‘,µALãÙØt{qYbX=ë*3‚  ’l%=e’ÝH™kªšâ Õ“¸0­¥ Hœ.pmJâžTŽ¿ÑšÊÈ6ý,ŽºÿšsAêå,q‘=¼ÈÙÌbqĵ4 \aû´6Æ©5ër†¥Ž³™FÜÄg´NýAÌe$-èLB #ø€7˜x«ž²J9ÚòÛDA¯¦FðKHÙÆ¶ä H4LUÓ)K;ä·ÑˆjÞOòQ+XË lÎ ôôc+œ)pWjxÒïéä†a©J¿;í…ÉvŸp^S Zæltà?ÿvî­‹¼u±÷.¥{R+rkB?ÞçåÄYT%:¥vçµ(p0ïD3cN9«©KiQãÂÄÅ9å©M.n))³/Ñ&5=¯1Ϧ§yü™ÜŸFŸûôåíï|½ÿæüÁ׊*K»—ÕüÕº!ÍÜ›×<o}4Ô¨ÒŽ3j¸ŒátdE2ûòŽo5+}«­·Fxër£v&7ŸLV¤¶Ò…鑞ºŸû˜É8.âc†~¥24å»is-£ç|’… ¡=7s€%ôçÔBrÜAóœÎimÄÔÍчÞqˆ<ÁÝÔ +q¶£Ì‰U5‹+ê™1‚ÉÓ‘â Ý÷Kÿ˜ZÕ}ìâ,v…1´4~Nc¦‡q3kç”F¾öœM/Ö…@·ÙÈj]e…¡%Îb ²°Ê;Ù°¸—Û°ŠF´`Y >Úñ·þeù–ã8L÷H9¿"º/bܾ“!œ¢=—ð&ûé¹ÏCx/‚8úÖ‰_ÿüÑ;L„Ù*÷¹¸¡$âHz1‡>l¤Ní•&R–•ìe Í‹‹ÇÿªÅGeeg°½-z¸•Ñf]¿lêxTmï~¼Ðª/ª0„¢ïûô¤€%Tr+\ÍÂØcÊižÁ ˽ÜÅiÞüâÜ_§2¨âúˆ8ÿCÆ�®q„«¶ JE;FÆ0sed•rSP!>‰'ÞÊ*F1™|D Oö}šskiºÏ ažÅðTÔ±Xõ§cÌ?³ä´Ly¸ŒOÂ[^É™D_Þ`EÜÉÖȪÙÎNEÖßi&1Ÿµœà—ÑòN# ºî‡¶¯Ž!¡:ZާcÀ³&6ÔƒQëdù­oG¸õ.¾z´²v�žg$]Cùy)󸜧1Y]¶Äü.­VnàKœÃb¸*­-åû1Ÿ‰¸Æ´L= ÌÓ¼Âuu.†l x SØJŸ úq{êýÃzr;åm¶’N!pÏ<|¯fˆ¯TÿJ§˜I¶ðPÀR§3?wkù6o¤VSjÝ$ýiÊtâ·ld3“Rø˜ØA¾A3Šø”‰ÚýÆ÷jÒÿ¾Å;“ ÏôË{Ò‘Éö±°—…Ÿ®ùq^Bƒ´–fYÊ|vRÄÓLfaêe¦èZ£†³ijtÚ+ÜCÓû ôÌ×™›ðLêâjsöº*õ_§JzŽËWk_ÒÿÝI×Oûù±]­lxçä÷÷k\eÖuFT;™z;ç6U{™~ít=ewþ‰Ù|’úi¥6 ¥ÊʳTåÓ«ýè=·®ðr¹êîÔpç3&²¤;Ð@Ÿzž{Ñ­‡­)s Ë1x‚©;xƒk!)ƒ©¤](dQI· Ä¾˜5{ méê3fð)ø>#™ÃŠ€ng¶Š~Èô°Ìgâ3e;¥œÅ=B}5ÏÔ¹­n»ãP(·q”+¹–ÿKŸXX–ǤãD4Ð2“ò&„È{�W³…S4ã¶s”k™ÃáåÏT¦#¢M70Ò+bÜË"¦Ð‰w ÜC5×҅죜[ØMßP‘Ü &YL×îà´•EžÑ¾øï¼Ë8Z2.Þ>¶†ƒhdtãšñPT)ûb›ÌÖœŠ¿Ûí*‚®yC*¿O‹‹Kn¼eÒÿ¶]}ZV6™}tbO ³þïªèég›Y£l+ûâß«ëìUߥ;Ýø9 ˜A)-ÙO 'v™Éü³ƒY‘@ø.ǃÛÑ%6óF‘ýUMB>~ã6SF}Æ0‰5ÜÌ»œæ†™õgZ¡;Ss‰4ƒGXS‡²<ä[‹ƒ�{yàšºðѼÀ¿$ö¥>`3%lâë<R§½ž7b¯º)Ìð§" ³:Ƽ™‡º”ïÅŒí!ú²•BncMàA_ÉZU¬aC¹9sµUËýÄŒ¤<Ž-‚¡õÛ „n‰³!Shl½,x©éÉî þŒ£(P˜KÆQ†q-ÿÇ‚¯³ž÷c”šÕ޶oRa27EÎÈ‘ækix;GOösœ;x›ö4-09õ=X´ñì áëôäE>f,m)³Ã²S»û ÆpùPtÒ?`n ‰‡R‹Ù^)38Á5(Ð;Ñ7õ1íx°ÀÔÄôÔ×8‡òfÝø=ƒ˜Ï$>æ ã˜ÁeTkÜQó½÷ß¹ï,K¾¶8ùÚñôkK\Vàþ‡ìËñ‡Ôï÷º4¯ˆŠSùD‡ÄÇ¥3š‹\•WŸÓŒçBJ(o¦WÊý*­C{%çd^˼]4hæH=Ý+4iëœR}S}S%i­I£¾£ Û¾6®üþ­®}þ¯Tè8÷±ý'úíqçÿiVÖ+ñ|¹òÄ7õkÔOŒê£x·9kk,.ðRÓ+}µPÓ|[s²é¶ñm—÷:ùίÃÌw =la+6T>—æßªR7ëgÞ?üJîž±¹×ÿ)ýÑR?]mDY¿SµŸîü­tâ}Å+Ïbw^ g1€>%Çiž‹˜æ©ê ÍS39Á<I;Ö±êë)¡œ5\GйŒËYH%Á³ŠíAë«°ÝÍ¥Ftc`�[çsS°ùFä(â« 5 Ð£©·¹‹Qü•Õ|™\Èsì#a"G)å­xͧYâ¯7)+ôHjEìYGñfP‘ZÏ î‹äÛXÌÃkå<’¬¥&¶€Ï·¥ÒØG7ðG6ñ_ã%J8Ì%/µŠr® U³ÐE›‘u&ÙÞ1†4á9±3ëÒùDöÊÊ–Òˆ.ARÏRÔªël‰CÙÚ‡atù¢‡ {dÑ…‹x†Ú°ŽÍÜ +»8›=̦g|Ç;¨dyl_Š4„Œ@8-b‚o®SŒÍ½ÜFGžgKœ’º²2è,ÏûJÉbr·Ð3Ɖ¥¡È¿‚©”òJÈÜß(Ò½©Rú|íPªÏѺÎKêR…ž2Døra´&Ú³ƒ-ÜÈÖðS÷ä7ì£oSÂ\Î¥7SéÎ6¦ñ/15õRj[œÓÓ†Õ!Ç9‘i;) ¯-ñ©–Ó‘†¬¤Š^t§ ?` [èT¤MbþM­¤µ--èÀ_‚ùÔ½Ð/óµ’‡”0›ŽŒ¤€ŠŒÊýœb%ßBù}:±3P¹¸sÝG/�� �IDATö1…®ÌÛ•Q}Û{Êqþ™Y²€)ñ:{y‰<K­ø!‡YË?s2˜ ûxÛ£Êl–µã Í»…ÂÔâØªûrŒml%åN~Z•ÖÛvñaª"µ' \’ö:mÀÕ…í®Ëïi•h‘˜Î}¼È79‹…·äÇÎÓõß}e‹o,¸>iýë'<qªÁƒËž¸±ð™ŸäË›NôpY =PíÔž,¸¸Øø¼žÕ¦%þ­ÀþTaÎXN¦f²»¾šúæÕsa+ÉAóê•÷3F77&Õ´ÚžDE…†•žå‚RÙ9ºVy®çܼ%§Ë§½bßÝ+žëØþ£Á•{º®mpÑÐêcT¨©TcÔÏ[žZ”{ØŸò¥6&vä%…þ%ï¼5Ì,Ô?ï÷•–ž®º!95,=u$yjIáÑoçŸXèKÛÛ¾ÿT£YɾáI·^}Xy#W7OOý(=u¸ðõ‰é“ K{åï¼à½;XX“•úô«×íÜkߟYÂv†RÆO¢¹}2P^ëøv¡¯×XÈx>ŒÁçÙÌÎ\DKÎ GsMÌ“šÑ:FeY^çÐV3‚6”SþÅ­«3_ç=ް“79®–Ü’j&Ñ’ ©f-UìÍ×¾‘÷™C ágú,¬ÄÙÜqfÈçúD¾h†1kœÒó†'º M‚5óB¤¢\Ãωù*G"E¥š;8À#xú�³é¾±v!†ôŨŒUv€fœ˜ž:›èªØ;Šƒ¡Ó™†”r­(©³Bváxí¶aa ó‹]\¼åÆ[nûT‹t¥Œ-äH MB×!¸Y`ÏP Ínqäz d½687Ž!ûCVÞ©K¢•n¢LY͂ث2­ÇJÚÑ–zuJ¢ì±Šú±Ê”2’¢ÀA 1-YÎ�Nr,Y—á�S© šCæ[ÌÔÄêœÞ©D×,ä‚tÊ›ÇfªhÃ.~^Âì¥JôHj‡F™-·K¸‹FÎ’}a›Ý׌(3!ô™çôŽøF²ÙÉkQ¬ä,.älöQ/¶³½9ÓsöŠ”È½ñÖV3œíTD`ö¦±& ¢y3§ë›Y¡ Õ"1>§Mj3¨Ç¹tå ¯ç5‹ Ò¹ìe<¯Ò…><ÅÍ|Æin iò&«‚=uÌRf±ƒ¬ÊË,VòµSÊø8F¾÷„‡/³ÐUr5[£ìÎL$GhËvZs9›XÉa¶0–¡ÜM)·3Ÿ>yÇ~OÎìä¯aYÍÖ²‘Ñ…oÅd8“Í”tà»ùeƒÞÊÿôÛlBEZkfͱœ/ÕÜõmÿµV~”·¦ùé¾´üd¹ïv¸Â•lnB…,áî*0·¾^å>nbpµ$ñýj¯Tê^íÍD›–zžv”¶y ‹nèúJ…MŒllÔ1Ow µ€&y™þ³R·j»hUà‚Ôq »hyRóœ©hnG wÓªÚ¨Ô¹êÉÌ©¥7Ì.mZâ¶AÝ÷þ¨DY⼤6˱œ+Cv;’ÇýƒkW£uÞ£,ïtÎuô E^eNëÔŠüîÅþúcívêÚ_vCÒ«E2ò@z<ïQÊ6d'˼ßpq¾hº^ûÒC3~ŸŸ°ÐÐ ¦V4ûé´ŠÉk|2Ž3Ld {ê›VhwM-—¤&HOåbq6wr"Žkõ"I| •LðñËxŽ>Ô¬²$zwa.â+‘ß‘e´ŠÅêNÒ>æîÇ¢QöÊ¥‘CŸ[Ù*wÇLó:‡Ý)ÑtÎ&Ñ!«þB…¯³€2Æ1†Maé=9ÒÚ1G9Ë9Ã%”qM`ÝÓØ~:±•§YÀ1êÑ„shÀæ:ËìPÚ±"úOµùD©6©V¼Æp^f5CèD)#Âà14N{›YK_7 _Mvì®â&Jø„ÅÅÍê* ÿnÔ”¹“RΜˆPkÊó´ã¬ˆ¹z&ô¾·òz<7uèzÓ¼ÛNì`ÿZ§ |!þ|)‹¾¸ 5 ýá©ÐödæŒøŒÆ�¿' ³iÔã ØÃ¾HnÄJÑ–MœÅ—9 ºƒñ‡ Ì¢Wð!3Ri¢ŠAlçu†œ•¼ƒŸþQ&×Ä0vGt¨?7pù»ÑQ–ŵªŸ ‰DW^c ¹>$� )ä%zñÃɾ¯Õ4àj΄t*û³èÎÒé‹Ïz7ŽÙ—x[¹ŠÏXÃÆ£&PÃü˜_2"+¡Ísn¬ñò\Ã…{c/#Â}¼wÕÊ1¶²ˆw©¢'5<Ç'ŒH|#Ñ"ï-Æòºs=¥œ“‘/ ü8oeZQ¸‘Þ¼E ºD¤P£0Ÿõ =¸…Þ áŠ@ÓöæT»j<Â:šG‹x \—Ùy¢ÕÞ–qT°™\ÌjNðfô .ˆ˜óaÆ2f‘ œuÌÝÏçg´¥„/Õj:&-5a§Õ§Ü–7n ÝìÁÛ[¨ÊkxÒ±œ‚bíŽYš}‰Õ*O8HQê®Ì{¹Ày¯¤v'¾Ÿ:ÎÁæÚœñv·rÞ`Í ïœp1#x‰,aG�f>gG =*µ­¶7oe5µð—&G·Óü”’{SklÊí¸´á÷6=µ©²DsNätbLÏnÖ“2ŸëS;èŸz,Ñ=g@MíácJª&u€¹\PèûÕ~^«ŠüÅ7µì•Ny'ysL²¼(Õ˜¯P™Ó%ç¡jõmZçÈp#ˬW›'WS"WæòêUÅXôo\À¨Ô'‰*.aàEŽÆEÞŒü2¢ßd-}ÙÂóÑOãæ=þ¤ ì‰Eé¦Ó9PKø1Ý)¬“!—=fEÐÒçLY×äsªêçaöƒëµß ^ÔÍäb]ý=]È…wðÖP]±Mh\éÌ b{~C—ȧîÊnÆFø<­ØAÓæeËgø:£ù¤Nž}f{³Ž’¢:¦0Y5’-VÏÔÑ[�æ0$6éůš«ÜÆ0=Âß’ýõ4ÿîyü?ÕÕœ²²3œÏGLbUá…ÚÁ®°³•ñUÞ`‡Ãõíh¹¬ã.®df°GE¶Åv0¶ð«Yî@D–Ur?]brÞŒqÌg<éÿ¾›3ƒÓ‘#|{¸’î,c3R²‘ÝÑhÞn¾½ ˆ6TgºÑœ}죚ö±o¦JY ºw8ÑmÕqâ¸„ÏØ@o“p%{G†R¾cÉŒ¤„Aa”žZG&pƒ”0 kåújÞRNs9ÓëI·²>tó%|²Nuøeªùnð7×3,üsëÂ8V3šEô§”%,¢-ýiÄ60"­ýÐv±ƒ•ÔgË9ÍUAý¸•Ê,¹œ nOl(Ð'UÃÅÎåÃ,];1e¬dCÚ¾5Ž“2)­]˜ÞE¡ûSŸè3c2ý3O0ž<G¶ñ0ç03b„žç ‡©Ï¿0‹Ÿr‚{ø˜ùX×Î<Ç4ÚъƼÀ¦qmºè&õ¦9ïÙ5Ñe›L;è²ïx½­’„QÔð¶Ëê;¿gúúÈäí¥íÖþ┥µ±­Å…ίöz•=yÅþZãüƒÙ¬Š;iZ¥&UAeNz¦š§~U¦kkõë)8õÿvŸñu•wÖ÷¿ûË’‹Ü$KîÝ7Œm ØÆ:R ¤AÂ$“f&™I&™”I#mIj ôL1Æ`Ü;î½WÙêÒ9gïûÅÖÅGyîçÉsÞñ1¶ŽN¹Êú¯µ~~ûh»Qï㬜GbggLË8•ø=»¸˜³3F'(ò¡œªœ’‚GêŒed‘Q±E¦$¦¶kÎûa¢O‘Y‰ï&:‘/+-x±Y¯ cªhM æàÆ>Fp^Î`Vg5·{µà~¾È,N™XPÍ¡¾º”ÖìLŠÆÎ(Zâ¢Uã#?KTó‰È9Yû°>1–ûª]»Ö9>™rGNùÄ›í+Ïrï«~ýuªYÍY<XPQpyØQÒÆPö…tm3¹?„|„èÌkLd‹©ã²`UßæåßçñàL>͇Íêð!?ÐiHü6tš^‚El_ÉÏ0–õL kà‘p>nf;³D>”XE3£¸‰¡v½œF&0…&ÐÄæòzX™ë9*'nH<ÞpÑ©çL`ا*N.e-Ajª„„Zši÷Ë\ 9\ÆÛ!¯}4LËÒFžÕ¬êÄνœ5ŒæÚ åÌ µ/麞Ó\ŲœV>ÖC¨¬¬üǹ«좕ma^Õ…­¡Ú®‚²áÇ\Bß %/¥ž.¬gU0×]ÌÞaW0*ç¬ FûõáE™Ï ޱ‚­aØ–Å-le3Ã)éUbÚ(„÷yü„l¡‘²(´ØÕg\’1-±œ>Âkôe>Û¸›_…¿õsž Ü©“!y–vm¼Ç, ÒSe ‹ø²““ìg-ßåh(è,æS,äfÚyÙü…ýÜÀÃÌàJz1Ÿü;¨æOq‡ãn3x+ŒÁ® ÓÁ÷›¹¦S#rIЯ[ùߤ”a¡ã£ž¾tc33Âáà"®åMYÊþpؙ̒ éßÃÛŒa—†úùyœeLæöñ9¾™X]äîÄ·øvïì'¹Ÿ>ÔºèV0ë¨æe&³…G"Ÿ-ra¬ÛξÈ`¶òAþ# Ä$^æ–³ƒYžû7nâNž @²Ôñq>ËvNF>S䫱-,a,¿á-ºG"æ)ag¸Šm\†g³4æ<u•®·mµ)Ua�g™ýCWÉþÛìh0¶Ùc‰›}‹ìŽ ˆÝWðï±ç™Ïœ‚VÆG^£8²&�”Ë™ÁEÆG"FœgØA#ÛmP“Ìe‡3.kÖT🋈ÌKLgG±b&Fðp±19{2þwŒŠ<Ybu…‘95±E±Oe”'.ˆý _‹ŒÊèÖÃA>™W³§AuÜÁ`¼º«Ë*ÔÕÉäý'½˜[˜HÔìÒpYÖ¨1¢‚~->Ï•-êZä8‘¶$=¶%E½å~ÆŸb|Ÿ—Ó D>Qlhl4õg›³Íé_ØYÎb†zá÷½êò#r+CùEŸÈÞ¢Š›âŸ}­¨âÚdËÉ|ŠÕ|›Z¾nN¯ómVPË'¹4ò8]yŽ#|– ±' ˜ç3““ÜðQõa»1”!}”&î X¬-”ÿ=ðýúÚ±‘"êÙM7*Bùjz¥;”¨H:@Ãý¸•E¬¦ˆ»¨ãM¶q¥üŽ Å~ûEø×nb.OpŠ1ŒAøÔâ{"4Ed#}ƒ}7õÇo Qßô©ž¢–Ržå#!z‘¶NÜÁcab×Äͬ¤4�ÊÓÙØ7©ç —3Š·‚Ÿ6%Æ¥ñá´8éRÎã ›) Ô‚vf±ƒiôç+••kÿA#ûâ––ó87Ôo¤E“BÛio>Dº“PÃ*òá›2ŒS1·%\>¶…hdjBKÛ‘ßf8ׄLYĬc £È0šA!ÐS’_f 7°›e|‘ º_C:ÍË³Ž£A$¼(´áIìL:6íÔç}*ØKxˆ^”ð¾î³Môa1óƒ!þŠP^|"e|0ðÀÞc4· õì0>M]CÏ3š³˜Eî§sCêYÈ›ÔF.`)›zèÓf7›hEƒ¨ ƒŸQv¬«x€žt§‰<˘Û¼üÅ\pjýÏ¥†4a ›¹‘&†2/[17±+xµŸä"¶1‰&š¨æô¢‘µŒ‰\‘tÀëb¾ ãªZ) 䟹“Û˜QjhÆÀØóTRÅÅÌâG±=dBÑp곪 ÍÐG˜ÍãKá~™ò-£¤CìŸX@ÌòÇð¢ à‘XC°meYäò¬‰^E>œ1-ö<93›ÊÈ%ìvÞ}&MÕëªåj_ÆoéÁ»‘³’¹ñ’äîQÝ UE.ÈÉfMˆÕÑØ[[«o&~ι#øûJ-qUÁ¬?Pˆ:”ÉÉtO|¿LSÖ%û4•8^nj«Ã<K %‘Þ±Vf¤y󸃸 £k,ÇÔ2û8§Õ¢^nmvvbF_Ϩou”¡‰'‹|¢»É-þj†ÆFä5Ç^Ϊ)V\pªÌÐØoÚ·z˜¸7ã•$-‡ú¯îô̼HãIÛebU|;ÁýÜG««Ñ=gïg8Æu‘öÈDÚøò&Ò³Á;±'iöêPÿû®GöÊe2¾å3É£ãå.ávð\ šI>ÚßMÛãAO{a©Ö”ªšcב¿œ5a†}œ©Ž-âVfòezs6‡žÜWؼRF=Íaq8•Aˆ« +þµl ÙÐKª˜n'iâj³ØÏWÁ6>ʹÜ*þ²´18 æGÎå0ï„4ÒÅ<ÈŠtæw¬Ï§˜Æ~ ‹ÛNv2‹uÌe&[Ȱ€,=Š|:¶6|Í7„pMè¡hg&OÓŸÝ ·¨Õ°×âàž¿%@õn¢ŽÍAT|‹ã\˜–+R�åפíÖr1û¸1Àb¶²‚­¸¿­¬ìönW‹[ZÎ% £°©”p€3Œe‡ŽPÞ©�@* í|a°kpÙMá sháFº3†>l§-ô½žænNò× °Nb=ƒÙ}ÃBµâE¼Ä›¡™¸‰çÙK)g±•AaKíÿƒy—¶N°´}¹™/PÌÅ!*Û˜’—‹CNkHø¸§ØªÁR¸ŒÏ±š^ü)TÐæ¸†c§™k˜ÆØ WÐ#¨—é +Y÷ Aã´óxRä`$N¼Âé>~Ùà¥P{:ˆ \D«ÀÏÙËa&²ŒvúÐ=ìaÅ¡÷ý"úÒÕ,g9WRF5£h`+ÅpºSIMøï&a·ó‹C—s*p_ÀqæògÊBÿx.e7C¨¦†)ákv!7±?2(²;ñ‡XΠ2çp&¯=¤èÛÂÌï�À ä6q"ëç‰?0,£’ÕôçBgÌáç_H: æ%äØÅ"¶P>Ì“ÈÒ“å¡ì|@H¶õOü¾± ±“Leýx<r,òdþ#¬3d›sMïêÂ.<j|+ßaJæêKÌŒz}ù;m6¶ªj·„‰-óÝ›½žèV¬wW' ffT'NÐZêÂnÎmÓ­`tÖàHuäóü¦‡óÜË nz«©÷x›âHW&ñµ2×”‹Ú &éÝCm¹·Z,¢2R‘XHy…«Žè×ntƒ×ºidz£e3†%3¿àh«SQäú2u]t)ØQáDÁ„íí W8ã¼Ø‘2²Ú e L¼G}f~Ÿ¤eƒwÎã8CbàÃC¸jNÖÀDÞ¦2{{pe±•ö·vxϺЗ£êå zññȨÈ6w¼­d¤eKï%qˆ+èÎN2;R³=Ù0ÅÝ ><Òš[B[—ë~=øqÎ J@+;c3™ÅüyÌ 1Þ}Ÿw„šO†Ú@è~?\Ï6ÎegX»ÒúùÚÐ~ÒÖ©€üDèz–ú0{ëOž¢½©&¬»)fDÖM‰w¸˜á´àÖÅìÃÖP ±¾Ó7гuœ±ºQÍ.ΰ%Æc¯-±6¬±—ÄIŽqasêÅ»DŒagÓÎlŽbí¿9£1üãþ>#[Ìù¨¥•ÛI‚ß*tŽ"ñR(¨§ˆ)Ié0ÿX |½¥e}ˆv¿iNI»)z§Ë;ÍHJCánÓ‚ z)啜¤/¥,þûw1}¤}äÇ;åÑh?##9ÄEŒ¤G`äÔ†=u›‚üº…sYÄ¥äÙÙéÙ¦àsXBK(®/p¦SžXvÍ3€“'‚1²5AþÚÆ¬�iN÷›y5™†Iâh˜üä<Ö…ïñБÎ*ðå0…š›8ÈÙ\Ù`kÃ.}ÚcØÃèð¬Ž0*ö§/å¡„ÐÄkŒgoSÅÕ¡ð¦†õø,SKS賘ÀnÞÎi¡†‘,ídžìA¯Ñ•\Ä»L _§ìçZ6ó/s†2æò°&é˜%¬+òß±^íÞÎûc‘OGŠ˜Á_©e ¸˜¥T0"²‘>IÇø÷BúRO%í‘-ŒŽ;fc)¡®‘O°…•ŒeqZ«˜í ›¼M3Ô2²Èq‡¿^@¦îe4Û¸–“9Íè“ýígú>s~ÓæmzrfTÑ™{âì_Úéú­Iû+~Ùžm½9§èÍßH""“§Ò°Œ£Y%c÷÷QÜâÝ‚ë N”Ô+ËûA¬8R(ү،¼a9ã î‹Mk•â]XŸµ€Ÿæü­È”XiÆ7y.oddÈ`ýN±¾Šý4Q]iH™ªf#c}çÇöFÚ³†ÅNFf2±—~9×÷¶§Õ vçeŠ\7%çXâéØ-fe4EŠ]‘øïŒ[#{­[™ôœhû’H_z%æ4C8H·H×įÄÇ©Êè••kí¨N˜ÈÑÂD·¬’Úë½Æû×úÙ; ƒ,-c=“ûÑìÚ9B%ƒ’s(`Ùx~Ô¯w±Œ’ðIžBë˜ÍÓ Êú4õL - ùJaŽ3ŸM¼Ëñ@áJƯÑÈulf4Õ'C g‡à}ÐÁëû9‰Ðü”uV0—&Žr€±dØÍ:®àu*¸<騔‹Ùp‘Yndh m¥S8íÁa¸#,zÃt(ûØ.æ g!Mç&þÊš@P* ž©ÆPq+hw2 ìd4ûèÊò`ù[ý÷qÏ;‹Ÿfñ:í`]Ærabrº“ú•fÿfWo·´|NG—èGÂ×uz¨úH_Ü4üÛ�í=ÄÊ®¡A5…ŒÌ£Œ_ä¨e|¸ ¿ÿ¸™iü•É¡‡ñ×ñ\Pf†0˜-)þtÈZï [ÈÁ Ï…”Ü7BŸl†å~Ü´€¬ÝF?® ³:O>òõáL!ûÂÈ1ÝT6ÑÒBãƒìØÇE |á*^à‡Äì¦ù#háb®f!?£†Kx˜›ƒQø�ýYÎeÜÌ£\ËD~Oä‰`/\Þ”6N|õÞf [Ì_Ò!ǧñ4;kÝÒ ‡éÊ3œÏóÜÉþ›m42Žó©å]¾ÄlNvT!tÄV°7€m–ð&«¹’bžä‘O0†„f2;|~“ø9+AkbMb}Æ„ÈmYÓc§ù Ǹ†WYÇ^&S›ø§¨äw¬ãKÜÏí‰EnŒõf£ù%[Øì‚ghãZ~Ǩ¤c}éÇ)Îç²Ä7è.‚•¡qOñ-ã ™e£ŸôOŽ=‘³«Ðx£ ûm¸+Ùð¨7ÛúËìÛ7DoTþBÁÈ‚¿²ó\‘oTSSdtÖ°¼=yU±öÄOóLíáDÖÜfÃZÅô%Ÿ8Sdn‹;òjòþØâá6‹8§»ef·9»Øí^n·£¯›r&d•v³¯Nÿ"ßʪiöXÞ YW¶;žSÇ“c›µäíMÔ%º¦zib÷X-'½±;10ïP»ï·¹*í™lWšøUb0Q«~Å®Œ”¶[ëÁ˜ÈYçÅ^Hä¢íj|»Á¡¬&Vs[€Ä73"ñNƪbÿš8Y¤*Ò£E#•<Skdƒ?ñÏÌO%²6+b"»’C¼xÊéþô´½WØñå¼\D37qƒñ¿Ê\vnôË«’Ÿ=ìß®wàjуe:¦ÔiÅþ‹œÏ.ºóhb3ÓxÙ|˜GXÀNÊ›æj6¦àôb*ý)f{(‚IIÄ1‡8@Õ|Š?ÿý‰|Zð¿ÿ¨#f¯3›:v²™}\ÇöùêÆs¯‡Ïmž Áb¾-8˜&p+XÀz°­Ø#±'Ø¡)ìÓ¹‘×ÙÍ.pW‘äª3,ÐZ˜Â‡9—¥¡q ut£+ïq*ÀtÒ™_áï×öO³†‰¬c·ñ(Ç,)Ï)¹œåtcb¨ßûÏ0†~ùÇÛÕú––çB…Ï*zY/®ù°2âr²™Ï²#&® ÙºÕiŽ*ö³ªS.¬–Qà™ t¦ßCd°x(]¹ŽçCôª)€bçRàߢ{}k¹*üˆ¨QE9s[ùQŠ~Žle±Žž‚ë™C){ø(cÃtj_ oµ’㓡ȼ5øîÎgcޝ9päNBÁFÚy˜•¡øf.äçl§”§™™ñ/Y¯Æî <øûYÇ Îç"þȫԱ„, %¹ÐÀ›n«ý˜§£3­ÀUA•MKâ/¦;K)ás!åÓÜà;ìæLf#µ¡¦Ž|•U¦<Hop& º¯ :Æz†"Ä“ñJ@›ÇŒâ^ œâ‘È™"çÆ~M-O„J‚´û†Ä_û‡cqä©"ÅjøOóµ¬>ÿ™Ï8žb·q3ƒÈò�;c÷²8àÁòl ‰ü‚©ì¡”îçRb^b Þä|N²€?÷¼~×ê7P¿YÞå+Iò©‹“æ^ÅîÍššŠ\Y䆸ð¢£ßíyt_Qkq‹ÁýJŒíj\^—Äñá,êmmìhâK­ÝÝTâ7í¶uõP»¿$.o×ÐlS¤_ÆörÃ(/Ö;ç>Þ`e±»ÿž8Ùæù*«‡©=bm‘w#ßj6° ¼Úú#Vò±Øæ‚Ò¼5Y-œÛ®O$*swb|A&‘á¿Îš[lPlÉ ³ŠU'öµëž¸7ã·åêÊŒhï(.ùW¹,QË–ËÖ™ø@» ]Í©t¢Eïij‘ú¯óáÄÂ"KT±…×JÜ’8M[‘»sÉÊœ)H"/°–I ¦s+MY5‘âÍu2‰÷²¦&6ûr¼¶Þoó>ùšŸ¼/þQQé฾šWyÐÐL2}mòØÛîÞ\ü?wÆMŸ¥,ç[üž…<82iÙæU¡tt›«<øA·°‡ff0Žl˜ûî j‡þVî`(íTBEžUšt½§…° Ü�� �IDAT=8æ{p‡'v# ň=޹7ó %ôäy¾Á}¡Èí£äÈpë8~D¯r*êØ;÷ñ­Øñzó§©0°7ܹ ¤ÙÈPF‡B–´¡ê@�†]œu]dsb9w²4”0ÜÂ}´Ð=°vß×]Òbõ'y> ¶G±˜™ü Kû¹‡gÃ^•¾b_g$Û¸¢²òà?ˆ wiiÙªãñe631ðK®¦;ÃúMšèO¿pÛLýS8Μá.á½€bJ½‹B£šà€Ê2‰qs<ŒÐ‡üýð©uÁ«ó~j wóóNbqÃ8DUƤ5²•¹´0±kùZùk¨_ìš11±‰Ild8e|‚ã<ßéi¤cÌmEâȱÐÂ>Ÿ á¤v'=BPžéÜÍZ^8Ý­ÜÄJ}¸‹µuÔ¦#дu0Ý&[˜Ï¼I Ûù`Phß§9§JãæN¯ÀË&CK y¥s »éÊ«,¦&À×s+x‘sN#—0“D –Öylç)>KK"_ŠÌ!b,W‡ÉÜ7ÊETdœM†YÁç˜{’:¾KžÉ!Mr¢ÈgcïqcÀìØmœ]fp¬„׺º«Äøvϲ‘,!Ãw躾Réõãìˆ\ÙÆñ"oPÌA6pŠü+uá•V]Œæ~feä’Kǹ{µÙ™½Óì'M™ùè¿$þ‡Š¬1±¾c•±Ö‚73þ©àp‘÷bÈYØ`iÞ mrwÓ…–.öŒÉØVé‡.n³¤Ý!®©µ¯Þ U–eEmfô‘M”ŒÐµàH‰u­îaT¥8of¢6ÑxÆÆ£†öV]ìÊfºx12þ´u‘n]Œgtl%¹HÊËtåÍ¡Ææ¼û]W‹Û -2±\ßœ—ï–˜ÚGÜl,ØÝÛØ3Öµ;–ñ^Ƶ‘öÄöD;*­©·í´Z•𓌳6´Ø–1#ë;‰e‘z¦Äù[:«î«1ïwœ×M{‹ææNlÊ™˜š±&1Ž“üobu"Š=“s'cÝù\Ü‘Mîna‘_ËŸï‰o}CSo§o1»Â˜±t·ê'­Œ»ÿÖ¦+i°’,¥Da³;ðÚËYÄQªHXËИžÿ.­Z¯òY6ó!¦ÑÂ^#O] Ûìç¡»¹™o‘ãd§å{f'`Å9ž¾1:äbÏ2=­<f�Ó“÷ØÈ+ÜÎô­|‡ß±ˆÒÐGsŒ³(¡®È¿Ç*Â_8ÈFúsŠÌe £8M_*yQ\ÇJ.dûØÈ|ú‡kåBNÓ˜¨K¼È`ÞæÚÐáû gsŒËCY� Ì¢_à¤Tu¢@¤3¿ö@äH·SßÉÒ<š* ¿ã²ÊÊ.ÿàvõÛ––1<ò1Çè4·wƒ™ØwS8ñ-TÒ‡úóNs†qŒáª˜Êq¦†ðÓ6N‘åf°·XO½kyùNÈ×0#hŒiùà0îŠ;UF14T'¬Î˜žÀkœEþ—7ÌÆð*óÙÈKÔòj¤-ñ+9ÆhÖ†RÝéœf }¹‘—ø2ƒ2*ÙÉÝ,ŒêÔœ’¡Gеs’bY~| /qMÞ„6‚ä=¼HB/¾Î›84ñ á—=Ê|*9ÈàÐö?€jN2ZÇü3K-71ŒûÃß*t×Ò@wn`z¨©Ã»3–f~I7ÚYÆ®°]UPÏ%,ÉtôâÉ:™ø#ç„£å8*x*cxâ/ôe*¥ìå z‡z”„Gid(·ÇþFGC"â5ް§Ì¤¼’XI» í>ܧ«Âq'Ï8F³—©TUÙêÁŒúðÒ-âbV“„FÅKS8Ç3® G׊´«)ú`“ßÿÂôÏ{"ñÄOÌòôŒŒå‰j.bOgÌÈ:‘8›{2N'Îj—/t”E]ŸØ•t44~¤HÏ2_-1-ãüÝ ~Ý]K±\»>gÚ\ÕhL³7zVdõio´+kvì´e±Ñü–á-ŽœY™8ÍG{]ìøq™®jËnÖ³ÈöÞòcc/ÔP‘˜”X^æ­6™V‡KµÔ–¸¢ÅŠè­{A&çãÕÖÕ{7ol¢G¢¶U}ì@¹–È™Œ2†%Z"%´ôTÕ¬!‰ÑÔwu Zí)•‘c±BÖµÔ'^ï¡wN—Œù‰íÞÉ™Ólϵ:™Õ«àeêŠ\Oßj›JÌ`]¹¼ÛÕÔvÚ³Š2v$t(H¯Ôé^é¦E.Ü.ó„So¸¿™þñÜbõ-Ö¢½YÄ—YA5£™ÈDÖrˆËéÅCÔá½·s5÷Ó•zf†l{×±–é¡%².Ì{qœ˜Õ0%g:U4í 7°1¬¤*x†10 C_e¸S<E/²á¤›š˜†…ïàûqp0òæDìyŽ…Iÿ9l¤75ÌäYÊjd}7±…ˆ³XÅö¿ŸÑl¦o§ßñ áô|0x¯R@üÙbûHX@+›éPsWñ}Évr‹ÿÜ Ÿç)Îa/ãù-Œ¾¼ƒ••eÿ8wÕ›ááuß’›ÂÛ“ æì’¿Ïý¤”Æ`×ÁðœÀ*<Hɇ‹ü"î°_Ìñ*w5YRËëxÀ/e½€3$ì§’Ýœf{èÏQö¥`xÒùGByA¢Ë YAçQÄ´£œ óõIÇÕ8áTØO2; ?Ò=/íwÙÆöÄRfòBdõº@êÜÇHÐÆ€ Sìd*;hãžôŠÆÞ`IPÓ à¡`éÙIc˜Ò¥/Ni¸c w–)Ìc!½‚n¾µÈm±ŸÑ'Ð^Ž2)\mof­¬`0 èÏFÖrŒ ôá’@¿Œ!¯þ&×јxŽ%œˆM:þôBºQÄy‰§¸ˆ'2΋D‰“,a2/0‚·èÉhr€ 60çCÜ;ävû=9J ÿËBnbÍŒ (“ó˜Ä¹,Ì™“ »ÅË|‹ÕÁ")#,x۸ᶥTÃXA=%Uª›”ºa_òÓ}ï –_Xd`±n‘=±éƒµœ6˜æÄ¡Œçú¸«UïØÏ‹Ì/øk•¸€agè“5?ÒÐWÿ:¶*©ÒVo}ìב} GîiïÐ÷'ЫÎÛ}<ÓËÜ:ƒ³.ÄiãéK?êJÔõ7¤Ÿâ¼Ê£vfÕÒÖâ‘‚!‘ÚŒÞM’Dv˜ê:-,bf›ß'¾”s°Õµmú´(ç¯×ëÞêPÆïóÆ•Ú^¡­]ï›ûÙÖhpì‚‚î¥=•¼×h0…zg$9ÝòÖ7z&çLâù*Sšü9vvÖ9‘Å9û9¿\¡X6ç±Ä€Äø<™ÈC‰ËR‡tVÿÈŸ þ=QøE« "?¥kA)OG®TdwàØ›ÏòÖˆì²y塾ъº¬{Y692ÆO–©;fõ0ª9‡)¼Ã .c;y*ìX£„w7²)Ć6„ŽófÝÊC‘$k~âGlç87°4%'tZ¬æ°}á0w$¬�ÿ÷ò˜žw‡»WúE. =~i;Á¥WF>XÏáPŠQÌV¶„Un0Û˜À{dÏ!À>=ÕÕÙ fiº²;"’þhpë”íMÕû3áw<À2ʙī40„qŒb[øÓàóz®¢ž²àz<мþïG §ÉóNÝi~·(âëþñìjIKKÚZÝÞ©@öói¦> ŠK¹·QÆwy–ôf&‡ø2£YÎÚÐÞ˜†Hž¦œO±³Ú,ŽÝÎc~“¡œ<õÁª—ö0}2¸*×s'Ï3ˆ³=Ô�îá<N³,¸“¯½>óxå|Œ7ÙËZ¶‘PÅ<V†0–ždåì¢_ 7¶Ç:i†¨ÝqrAR;ÉFò¡f¾‰öKOÂvx˜Í£>d±SòJy›yDÜ*êç‘e “™Ã“\ÎÐ&^ÎÄp¿L»£^a+õtg ¹"q’?U°‰+yNG­Üzþ+cWÆ D°#˜æÓpô¯YFQ u]Î^¡7XÏDN±±Èïc­¼À{âCç·!Ô|AbwÒá\È®t_¡¯0ž:&ðûÙF]BlÃ×DÂ|€ëÈRÍ[|Ž…ü˜ 9¿MóÂäBTüò�wèbÚ×îÕ?’ëg_ ]ʳ<Üfxœý±«wxíK~wsKaS›–v‹ þ;«Ù˜‚7RâhÆmmžÏ{‡&®ÌØTìÛ‰ûŠÜØÈ¨¢ˆµ]ô)7¸Î÷r&u·²/Ôy=Q›ë(ËèÇ#õ:®g»QY‡ *c£¬íj|™3mjKÜ;Þ5»œU*ªv昡‰\Þoc#JÌËËçÔņVéYgwÞä¬ñ‘êHUWS†èyR3ÛèËÓ‘ù9™6gŠMmò‡‚Ù±†65yµeôÔí¸êØ/jŒ>ãÝnšKôlW±*Q”3*柳i‰¦¼£éšØî‚‘ì䆼 ‰ÿHìÎËæý41+27£¬Ø'ÕÓÚ/[®o¹å-*JŒk²2ñDâ­‘Îkõõ¡ÓvñKî*26oyÒ‘C¿ˆ¯‘uâ#ÉÖár“¨çÙò„ýÇMnòÖY Ë$·r3ù*?b =Y­¬ÓîS¹œg{aƒy™Í<˜Åkôä ’cS œGÁ–5 Û¹3p„~Åô¬ŸÚ‹Òä¯à…{ߘpGPPNs”û#ÏfÍ-¸—}|2e)ÎXÆøŒÏ'že3G© MãùI�¯ aö‡YÇLn`Sy&±œJæ±øï·¹\Ê’à§kÎí4>›š¿J¹’—YO=¿ Åo§ƒ 6 ÆóGˆBoÓûºè§yËy›®cæ”v„<G‚|rÇ?ž]½ÖÒ²<ðÄâ´Éôh§—ø{aNùiB6(Å|,MœÐÉñÁ *îãwSű™á±£ü™nt ïôé°WáÛá’”Ö$¯ãíàÀN±(Ç`-1çQÇFþ#¸�~B5%¡ù4|7PE+-Ü΋l£„¯³˜|«u9»¨åÇèG Ë wõÔgŸf=Ÿf:¯ðz1’­|%øyÒÖÔãa8‡Ó…ü‚Q”ñÞäûä蚇³4¥¿áP8(­fwØ«„å;­Ol¡)˜š~M)EÜAÄü˜®Tp†=Å®,X–t(§XÞÀS¨áQÞeàbþ[Gn7õq ìà–Ƭ¯&&ðÅbŸ‰íç(]™Ã``›xš;y= œâ‹Ãñp†Æ©bÅþiŽìç‘à]ÃIÞâ÷|•fºr'¿bVÀÊ,äÛÁë1Ž×•ÿÞ£{Ýx¾×ªüóß4N°÷APmŒÏáÒ&¹Ñ}ŸQØëû¯Ä-]\™x6ïÊ0 ÍMWÖæœŒ Ši7”‰¡]}‹è§¼ÁqÎç»Ôlj÷l‹y·d}¿Ò¯z4QQäž¬ŠØ–Ðÿ¸ù%Š"£KÌ(6¼ÉÁ‚oäßn±ò¼;Ž(Ë8uÚ?18«Wo'šŒ§¦Ê¦‚3ƒ•×)´ûMln_-òX¬f¸²}FkÊkä'<ØWÿ’zzÙ’¸7gPÖÄ‚5‰Æ^ª÷Y]le©ËO;•øßvg·;Q¤÷Hå'Tfˆ O¼›1#kbl)gg]ɉ"› TØêÙĽ‰ºÄy¬ªUÝ®K¢<£Ë~'…¼’¼Ù†{·É¹}\Ûâ’“Z¿,3·ÉkYŸ¤>ctlOÔApþý2îÍØ“8P,Û—±½Ø­±n’!ö2f´¬Ž–vwì]nd9V²KBGsŠ@|žéLáÛla!{CAÏX®Š:"G«B»=T–\O†ð×Pç–†5?ÄÓáËØFÈ#ØO¡“É»Û:ýçêNëêíŒãDZg˜D†¿‚yÌ@š-‰_±“j¾F-ýË÷B•Æfs¿æ|n#Ç¿r}¥øH(ÏìKžA³‰¿Ñ+8®kCãÆ=Á‚t’ï3Œ ÂPã«¡66ø#ûCU[ê¿-eL ¡ fcÙÊ«Le6?ã$5\”³–NÛÛêÿGÅíÿ+MxdHæÎa+ÃÂÖdÓQtc+ã‚\¶’%´§ U*×®G¸Œ˜ˆ3ôà‘ðlÞcF讎;AÓÇÄ`Û¿ˆñ a"—³…zÖPÁ˼r×1]Âò÷ê8|Û׎I&°ÞJDyhcúDøX!a ¥!.>Œ³H‚çgfÐg§R`K9LÄÓôc<Ï,Ʋîý|tÆíÁ´RE?–r ëBÉ÷–PR)¸NÓFÁô|w‚Éä†yWRÙibw5_c?Ó9J9£t¨WðO¼Æ4~ÍDf2ˆO³$ö$Yö²•OftMÔ2RGkj1­ô¦’6Æ¥3yºði>DžÑDI|}ìu*ƒfKš¥ˆ `;YÉùŒg"Àtjv/g4Æ^¢{Ƈø"ãŸ2.Lìc›XÊp®8˜7ØË&Ö„ét Õs’žLeŸ’ƒ>Vínç=/–ºë]EGíØïÂ: .põÝQÝéèWý2º18£œ#‘™}mÏ+J:†Ø“èÙdO›=íoúç‹Õ”¸8ï©Jý ú¶J8©àÅ~qqbQÆÄ¬½™œ8›îeý3&dÔÄþ3oI«ne´Ù“(N|½‹5‰«ŠìâLƉĦ‚ê&§JÕ~Úã5.<åX»¢î®n±¶ÉXêJÕ²¬Å¸Äëå6GºÄF%†·*:¬.§½ÁïzšÛ¤±«ý‘õy+²fDZKe{˜TlRθ2#ò–œ9e{Iâd75yßΚRì윅T—{-rM¹íº6w¨jiS{‹ Ý lô@AÿbÓb3†%ö&*NøSFC‘¹­ŽÅ^ŒÜÖ(ÇéÈtÞ)8é‰ËôæÒØ”Ä+‰«coFF–ªã½Øº¤lË•öؽáëŽÝ™˜Ä㔳‚nÝôh·-pÙ‡SÁ>.`/å¡—vg êƒY_¡Š‡C};Í\MÏsïÐJ ©ë´W½ÿ8Þ‰0!¸æÂ^•„›èÂ(ŽSÎïÃV·7Ül*™OCÈû_²°)âò÷ì¥"L:9».£9Qà¶òVøŸw†ý»ˆ³"Ã#B½dQXIæû†³…7ÙÅ ÔÑÀï9H@ï—ùf;Õ™ âG: ¯¦‘k¸•j ~ÎæD§VrQè_M3©=¨«¬œwÓ­—þ€ÈÜ@aHX‘1&ñ8Í”3AD<Âet#fLpô$ 3­c¼\:O08;¶þý;:„® Èc:qîG³‚³ÇÙÆ"¶¢ü0úRÆq ô¢ÀV±?ĉ*;•O„êÆÔ'Òã¡Ìi=•¦?·rš×)e0ý³S˜³Í4?tÚq—:_kÂýiBÀK§c§•©üéÂÁ –s)qy2 6tšI¦nø a#�ÂzHè&?C÷`Úœøi)¬zQ˜ ¥â*2.¤g0Ôö᪑$0‚uœf3ç0ƒ>¡O%­éjc.c*g³’, , ¥Ë_â²pQ;H3{x1D–ó7¾HÂi16kz¢:úð½øTb#±-²(Ò#Ñ'À3GrŠëÎØÙÓå­vSÌŽHYÖçPG†w¸›!ûÊ&/^kSên½ÎÛ»\½Öõ‡T•‹ZýëìhisäÞX+û2ÊJ +µé¤ïå2nˆ4U˜IUÁMSFöDÎ/vs¤$o]³7»™Ó¬6²=kVÆä‚ûhMÌ MœŽíJlëkXâP•eõº—Ë)-èXª_‰Æzêž÷^…ymz uÅiƒƒZ¬-UVÐù ÝKÔp¨`àI£“‰£M†ÆºDúÑ·TÿØ©2C,m1¨RkÎÆœ)‰¶HsqÞš6ŒEíŠ j²nìbs¢g“C^«6¶Q”õFÎôŒÉ<]æÜ¼^Eö¶P©)§*ç`Ö´RûZ} Õñ ùžúµ[íX‹¾,N”Ä>Ù¦!Ñ•itMD‘|ì0c˜¹ªU]¹\F!vN¢ž3‘™ùQÖ§¯[^ÐȆLGQÅü"³vR\0/ùÁ]u¢ø‡·Û{ çp–Ƶ:ÞÃÅ÷—˜ÜîÆŒi‰&fòç ±Œà!¦S‡ nû Ôò=B¼!%FBƒèA LãÃ!·3=,ú—„/ãûƒ«T‡ÈÒÎŒDú'M+ýÂ�¾•›è. §ã«øëÇ2¶'p/Ö†“údZžQœ8Ì!.¦‰©”B ¤$2™M¼ò?5œ`Hxæ[ƒåä|J(ãB¦ŒZfor(æ>žp_¦S&[ý©c"X íFr8@–?ÆJÑŸÕb_n%••“nºuÁÿ×võFKKc˜¬¤ÑÎÁa¨ó>™bOàÃ,ìDa?R·ÿÔÉ$s",»®bFàuF`¤;Si ;÷çvf¬{’�f­ 7‹¹8ŒpRÝ;áBîê h°Í줂9ŒfOðŒ ¦køOñ â.ªYZ„oæiª¹0ñ*Sxƒ4P¸¿ó¹šC¥ÓxÞá$ëƒÿû#¬a@Ɖ±làs”§K‘Ɔ‹sØÑi»z¿ù}žôÿ+dr[šiã?ù e:«MR^å uhæÚ¾N«mÕ‡õ\ËqðBboÆ­‘㉗¸…—ƒÇ·•Ñ<ÄYlf{µ{=›’YŠ }3xå/ éïc¡n¿ƦŒÛϰ |‹ò|”ˆÒà,‘xŽ ³Ž–²8$ØÊB9áº0ÃK[<ÞITæ-çÖpŒ“Ã#ûŽ Í:/s¾ûþꮃȺár¿ñÞ]™†^ÑÂO$ ˆ{Ð-±Š^œ›èéŸ1 `IbA伌‘±‡ ÊCÉvs~™ªvgñ`ä²6‡ÓE“|¢4‘Kœ]dfÁžÄéJ§3¦æœæ\Ê™6%Y“Û<RåúAÚNÙ’¨Iä™VãT‹=T5Ê„6}s6÷–dXÜjÞ¨êæ“O5ÿÑ¿ß_hÞŸ0:')87V:©ËC?ýqùKd$Ío3.ñ8ƒ*ôk3'ßÁ x6£¢qõ~’˜ãö§zwiwÀgrîíiB¢{«BÊÝ»x¸ÕèX÷œ³Û=ת-vml?¯W¸½MK‹L*Ò-ñ»Ï0»ËríÿŸßZÓg2%3™Iï½i„@(¡‹‚a ŠØûÞîíß¾UTÔ­¨X�Ñ- Ò‘j*!!!!•$Lz¦dz[å÷¼XsóÄcÿ·Ïz•Iެµf­ë¾¯ë:ÏïÙ˜öÓ>µY‡ÓZhˆ]žo^Bm…1 ¿Ìš”4>²+Ò™Ii­žvÏÇ^ȸ,ã+ôñFl(3‹<:ÉÕM¦÷j̘Àì`>ÇóÍ êµ9vaÒÌìÏéƒÕéµd<»ÅÇZ2æðdÆÔDFÑËS ¦Šs8P\sP›õ|‘*:x…]Mó`íãS´²–YœÉÆ2=XhÓœÃÀÐ�åFô´ñW.ˆ„O0…ãœàó(£)ÔÕöü²ˆ4§RI‚ \Ìš`jŒÂ‘3Ž<vÄ^VуLäyn¦—ª@ökeèe"Cš&ŠBÍ9B–¡Œ¡ƒAðµO¿æ6"/–ÐìÕ9að:²œ4_O2Š?‡†dÏq"`Ë8ûy›kCF]¬ªzãŸì®^ìî®vô ØÀpž¥ˆ‡ò‘Û[d°ç .b ÿÊÏsl˜Ðÿ¦Nz»saŒÓÙòÐ&Ñ@ŸT«I¼–O›‚Ù¶+¬7ktçòwN !&…aÇØÍt^æá`}è Ž·x„cA“s"4dóx•%Œ¡)DäFX·²”‡8ö[{OzQÇ)¢ƒ£A6Z˜“ÂxÉY¢?X¨ƒ¾Ø:.áT:Âçµ&¶‹-Ì pŠOñ:ô‡õ£(ÒÿcÎp3¯p«éåÖ€áX΋œÁa&QÈv~Bhr4_a`Ÿôz.î'- cÃK¸4öd¬)°œ?Ò61?ìŸÖÑÞmYlømÜŸ+¶:8 ^c¥\FU춸ÿJ‘ %ú6ÛYÃãAqû›c/qÜÔùóØPÂ_b Y>Ì@*¹…eœ`XÚ/¨çòòc|…/suì{ Uñ}Ëøí¿q&=±Û#×äu_iߤ¨}Z kÞècù:ûìNêK«Š•GFeMŠí‰e³ê²º§ªkPÖ˜6(ë%žŒLÎúhdË’º#É÷±Ø·3NDºòlëuþh]]êÒþÊ•‘QYbåY-í š í³7kx¬›l»d·¡]ºÒ~ÈêQÚZœÑ«0åm–dÜպ凙=C’ëçvFC{·Õ$²Gë”6ªˆý{Ó ?ÍûÔ—ú÷¤ú9#cW¾V[¥¢íÏ<]“—žÎØÉ² :{T'.|aø¤ÕOœ·»÷›)×W]ä”föy§š6=&D&f}¦Ô”RµågíïqzÂi½Z2 7»ÓÓÿ–ñLÚMYsòM¬6¡ÇÙY_â´V+¶:v]ư´Õ 3+ ‹õ¦lì6,–—‘È:ÂÝÁÍ™ ‘qm³k³ÎÝhó]5…{y0öHF-u±Îøžoûú»/ÐóSfò: ßáïÅÎg¿#/$˜o¥Œ,Ïæûk¶_a‘ã‘>Æ+¹lIêù{YÁÚ|¿Ê:ÀÛ,bCCÏ}4ð%æÐÀjÞO=Ëx)P~ö±‹sù¯nÎNÚù%O"ß‘`YÉ#Ci(8ãiåÉÀ¢{?öä„^(q›Ãz¬YʾÉ,ÞǫĜÃëA.ð/<ÀÎâ¶œWYÊ ÖSÈð�’ÍQØ—1óG‚zà5ÚO*9w '¨ÞÝá cÏI…´9ìÕ:õç M`>Óy³ª*½âºÿÉî*gd©g0Ÿã« är^¤‰1\C!‡i Ýh ‡x<TÕÜ.qØ?²ªJ8“Z6†4Øzn!Ía]¹'ð9zÃwK€À Þät =4Ó�� �IDATè[»x”,5\N.*»-\Oö1„¹´1ŒŸÓÅg6©8LÃÚ>Ìvñ$ÍtÑÄJ²œM;'ÅÛädú_á�å¼É2ŽFNúÁE†ÞÄÕ‘eI7ÆFðcž¦†íDŒáO줚KXÎnòÅú`†Oÿÿ)A›h¡6 W›XÍ%l`3‹É Çü <´\*ñ£}26_ò~Þa�ó#oPÄTv“Ç/øvÂ÷"«c‹‚|#ÍËý•ŒæîáóŒäƒœÍÓ3”RÖp˜6°ŒeüLãz²¬fAØý~(p‡ïä"p6EŒà>.η7¡5ë0÷†/Æ·ƒàEæ‡F¹€ÝICõ;»Ê7ÖøÄõ:jÙ™tÃbuY±Í±'øy¤§ÀÛÝ]nHŸç™Ñé¤ Ã íò_Y³¢<¥± RÜžoZìݬ{øxžšRWf{°Va§+²ŽÇå™X¨m´K{­9l_ÚˆBÓò¼XnzÚæšyÛ  ï JuŸ¶XY‘º 33ëóÚfÒƒJο4øï¬1EÒƒu—Hµº:¾ù7Åç,Xÿ¾üå)|û®–¸Ù·"ã"S²g¯I”X\X¶¦ú4ïU”QÛí`r_T–Ð¥¯BkƒÂs³Tì™bÂáÎD_ßoI' 8¤¡Ì”„™v¶ë‹gí,pZAGõuÚ]kz§I_NéIº¬ÍÎAÎéö±ÈÒ}RŒ-×Ðäw˜tz·Ý}RûËÍ)£Ñ†´} YåIqd^ìMIŸËwiF9¿+tS± …nLʤ•1´DyÚ¤°õüv¿»ÿ±ùî<èSXY¢y/·°Š‰\"¿sf ÚYè0‹žõ­:| Qbç3³ù·<ó“ögMɪä£b b"ÿÅN¥<BÕ£:L}²! áMöPÉl6P¥_Bò;FóV±ƒÕLÔcÿNXmÁ†9êJºBÅßx¹LðÅÌáå@Üþ¿åBv±h |™œ^¬az×±:ðä~F]8®VÒ̆2,d–n ”&²!W¥&€€K¸(ç=|œ–�"hvï=2l!«GÈcïÒÀöªªÊÿ§ïê:öò*Í434h·º9Ásâ$4ÖõTÏ{Qôya?ßš) 3½ B$`YHOXºœvãsxœ†0ý|ï1.ä¾$æ›xŠëYÃ.d /ÑË’Ü –£Tä"ލ`Aæ¿'שåLÈå"RÃÌ ÛJ3ÂXÒŒãZæ #ËãLO˜C'{¸"°£r€±fQbÓŽPMšsy‘C¬!Ö/|2¶Kû"”œTtr€†åÞœ3ØÂ¦…ÅoÝ´QZØ­ŒgŒÿ‹ùØÅK즖¶¤¯Ån¥â„OÄ6ÑÛëál¾OëØÅS\ÌFfÐÁý˜¾=¬g0}œË*>œ.ƒØB}p_vÓCE;nåŸe¯ògNáO‘¹ “bs‚}­¹Ä²„ißâÞá¡rö$#YOŸÍ}€cçÓLœëº~?ÛÞÖ„ÄÚb÷³šÏò çqyÒ‡Kíë±!åÜRW59–4¶Øy‘Úngfí‹ý6«y€î%)ç6˜KÕÔ)éðxÊ»b0•ù†§mKù{“A©~[[kA%Îk[º)ué­móßí.J%vMéQž!_o…¢®›{ÞÿRù¤ÆÌº‘uõ9žr^BSµæÃÚ»])ŒF4V”Lk?wué[“Ë_-;¡/6¸Ô2ò<YúޝVÞt{ÊÐaZê H©ŒeKuÕHÔh9¬™M5ºº¼–ј•Moº¤íÀk‘ñi¯1x€!Õúš=Öáu&'Lã„— 4uªü¡Ë¸„l©™}Dz±á]j¨/±ŠÕ×w:ܨ#29érÆemNº$RÃ#e†õˆ í©18ã,²Å’½ês¤ì|ë uõiàò¤u2 Fõy#¡9i@•¾.[b}$9FEÂ|*=ÁøR“N1£Ñ»•:ð$õl¢—‹ˆ(a$Ûx‚¡œH #¹†í\ÐÆÃCÌ-0#_gÊnΊt$Ý$©=,ãÝ7椻f.bOIÏåê VÈ£Ô‡ Ègy-ljs~È?:Æ9$)c0õ¼†o¥Œe§ñ6§0/„›çð€k© :Àʰ,\Ishc2 fs0TõC¬æqΣ3 ôƳ:G†p¨ÉaG¨Ê-#·!'˜<nóÏ倊ISbg˜È{1ñ‹ˆÉô ^ë#¢·Cy<¥ªªmÅu7ü“ãª}ìNúLì±pP¦›2Îd(—oogNjr’�½„åì ñ"9IÌ!R%Ÿ¡dYÅf.¥—6žz¹Ê5ˆ¥ ã3hãz&=Å>Î ÊŸ¤™ãŒ¢1”¡ál¦š†@ÅÝKž~„Á04ËMlq<,±Ž1Lc�=R~09ÄäkÌe$#ÙÁŠØ+¬§‹1dÁ4©áÒÅUa£3uÜÈ1p+9×Ù–« „qdé`0s9ÈJXÊ¡ ý¿žS˜” mâZjÃkœv˜uŒâ:9ÀD†³”µTr^ìqv0ˆm‘±Ÿ„h•œk.7âÏô29rI˜¸_öºZ6³y„*.ÉÍ!ì˜%<A3û¹œ45ì§›Ž¤ÉñÒ;ýû6Û¾éD2ÒÆcIã8–§§Üém6¥¬d#y! ÿ/g5§†ñ•,¥Ž É ÎŸ§üu]ÈáH^ì›ñÙtfdAdH¬+ÖÕ£3¡‚ yúz‰m鳿Ã~N/’Wj\¯iò"…½Æõ:”v$ixÒÒ>ÍÝîÈêH»<ß¿fµÇZ‡Šº4ee‰cÅI“†d&¿Þû½»ËJG-Æ¿šQy~ko]_vÇØ¤DFw§ÚôÇþl]M×—þ¹ëK)ÝYGÓNª®®Ï¬&:иwBߟ?mÔûÔ¹'N I˜š¯ ÔK=ÚâxlÍÑ’ÔΑm*º>Oû‡(žpxâš iO5tÈôŒ#yŽy¤ËÀ¬!ùF$Diû²º3þÒkr‘žfõé*݆D^KêLkêP‰(O˜Mi—{b‹"QlFB~B:iJÂØ”ÊÈ÷K-)2"í­XM…m=vDFfu¥L £Ü´”Ç:ÈÚðn±¾X2£<cv_?akMÆøVÆZb™ØÝ—uz5Ö’óÐÌ'#[xGß.?¡¡Ô—Ž8÷y§ŒöÂYTSCOžÓ³ÚC¹ÏåGŸ€±ý\>«9`ÜcÙC"mJ‚,‹#c#ÉXw-d£(çyb„Ù×{Åp8Gr›×IÛÇ¡@æ<À¹œœËÔ'~n29‹Ùî¬E!­)——Ë"ÈÍÆ2šÅìf%5,à�íTó<GY�µ%,á¹DÜåÒ0^g ¥)ÌŽ e ½b(§—²/@­š‚÷0sC¸h. r~ìå˜ñ^òÆû©¤Œæ°ºîH¸’š:ÅUUg¯¸nþÿv\ëî~1¼€\šÙt.e#?à倂O²Òôšõtž´̵À9+~I>E èã ±W1›º Êø—Þ›Ó@·QÃDÖÓÎÇèàqŽs§ÓÉfºéãZŠØÎ›´ñqÚx)´]œ ä¹³áÝ0’[y—%¼ŒÉ9­c’jò9ƒM좊ðFQŽå8Óx4A¥º'Ð;ØO'èä%¾y3iiì‘`Ï­j\ã½wõê™¶_i2Á›œÃ5ð\xÏ;ˆýz> ¿Çx§q‚JêXÃ;|$Œ×žÏÅGÑÇdÎ ®€M±éÌàÑðëØÅù!ì²|_ÎZ—ÓìñnäƒIƒbdxƒ6Ʋ˜?ó“ùd@e¿Ÿ_1•ÖóGqE¾ÏEsÙËî0JÞÆfýšnÎf^¬_f¤3Zƒóç1-HuŸadÒרÌrþÀûXÃk“ŸvÇBígŒ0.éj¶2•û¨(²¼×qÚNO‘UžujÖ¶„Q oÆ~»8'£HÛ5µÛÀBùå »ÝË8GÚÒ¥œu–Š>:Ï{+»hSjóô”(ö-š’Î9ÑʪÃG¾{gü«s3/œæÕˆöØ>1Ó˜NµÕeÕ¨~Þ³íuéš¿žÛ»jAö›ß)|lJÒÈ º ï—Ø_'jºç?º®z>zpE_éï*þ:«Æ¸";Û|´×3i«ó ßîþaÍËÿÜO}ý·ñ/f¯z¡à¾…]âÚ¾_ãÌVí^ÉØÀÖŒI)GbEC owJ™‘±ÿî4’á%.,UÖ­:ë´Ü÷"©™%Mˆ´YYâ_zÔå«fµ¤t÷8–46mhƦØq§½+íËz“+b{ú4w*h5v¼Î·¦$².Ï8Yd÷0“3²}Fó½‹K êÑÎkLä°™K˜PÀÈXf½ã3½ü5›Öør½;ÏLªˆÜ»;¶•Ìâ Ö”~÷™�G>N‚ZJ¹QœÅvÑÊx–ñk‹=Ít¦²†©A2°›R.a-çÒL)粓wéc(§òõAó='xIsAˆÃç‘Þ±“,§óGf†éß%<ÂQ–°’›¨g%ʉ˒æDΈ­ã.&¼a+ ˆåÁŽ90(þñ¸êâ»8Ä¿ó*éÿtì$GTîoæóaÚ9@>×ÇÕ¥¼DŠ9”³;r @CÐ%”°šú�Œ-Œû}®9pÒ ¶WUõ¬¸nùÿv\¥»»_b3ÙÀ—øo‘áUn Yõ¸••ÿÕø@Ðø"æ0ïÒd0¯s˜ ée ?g çóÑNšOñ{:)æz>ÀŒ@6šËéú3#&†$õåo¯Sʱ°òÉA4^e+ÙPý§SÊA²\ÀÝAè‘3„½ÊÙLgrø4ßHçð(CØË¹¬§‘î°œÇs¡M|‰Ü„8‡a<J~äù<Q¶ß#ütäâlÿªé0§ó«048Ìñ¶y5Ïäò“þ=Ò;öXy¤9£AØ2˜ëyŒ¬ ‹Ã¯p…ÜE7¥<Êd2o2 t·'˜L5wr9ƒCv×)¼Æ™ÄÔ°ŠQ”äà¿Yos/c¸žEìŽÝÉ.a#Õ|:/Ðòs—ðk Ççx…§Èp7d ÏŽþ»iÕ Ë®=æÐ[ ¿H¨ÊÚÌ”EîȪeNäÐPw¶;Âs|/ˆ»®Šý‰]¬ç}*ÿݾÒm,^éé™N4Ñ“ïҬà §G&eÍMêjy£{}#öê"Ù„Îjå5ŠJuv’gI¾9±ïqy‡ œoý1½Êú¼1ÈÜZÕ]>_í’]T3¶[Oqýþxë½ÙÓb¯çûBd"t`liéåÏ—ÿíŒÂ¶‰©¾ŠÖ¼TÛŠµ½K¶$^¾0axï’»;.^}óƒ]££–QÅ_úqÍ=K›Ut6̱D±£ÿÙ‰{nëœppôÅ¿*xiNǤÂî©ÛÚ¶ÏiËâc\pz݈¦ûÿ³ã®M'¾u¼ãG_ÊNØ–ÿʵù^Ï{øÂ*ŽôXÑ¥™‚¤yÃ\ÑnZÒiYI~Qi~»ýŒÊªL8-iè-Fd,Óa¿`NÒyE¢nkÓ¦VŠ"=Þ)0&¥“ú"3"éy¶ì·®RwÒÄ^_ÏZÈ⬹këõ¹ŒÖ<µØ3õ-=ŽÇfÄzÓ>Óîì¾~SÄõ§¦ŒÌêånçW¼É…d¸?vYl?ã#|ÑN|+ÿà7²oôù7ã§GÆžåb~Omjÿ”"J¸”ã¹Ä îgsy‚‹ÃÝzŸb3o3.àO#&„Ìû poñm~L–½tð]޲oÅ>Î�‹œ/å2޳-ÌÿŸd%é�×h °‰\ Ò‡XÈ_9Á'CÊðSÁ:¶™ NuÅ^d[(Mg³«x, ?þL+Cyžc|$xXs5çhH÷X�usÃ&åH¨l‹øt.ò˜—8@L6ÜõsI)Ê©g¸÷àgs»˜‚›èel¤„[BÒÅ‘ªªŽ²»º­»»›œÆAsE ]ªù†Ä& ð²0‘ld ×3‹u æ#á>rXÌzç�©lã9FSÎƱŠX™0*Ò{6ÈÒ Ë!F† È`q€Á'é22Ô„QrSH©Xè^ç»xKØF5ñBHÔ-a6ó!Ǻ nHðãy›(dX<\ÙÙÀ¤ ’Ø•ËËÚ‚¿’gp¶ÿ›3¿e“Ù û|‡­ §‘e±É±'ù; x餘®/‡Í`Úϸ–§öÆý>ëܵãežb;e<ÂżÃJQG7—ño1/‡y Tÿ&ŽRÍH6²mÜ“Ld?ä*Þá ÎaSPcžB)ÐÀ^VñÝÈÅ‘wøzеŸÊ_x•AT›²Ûy»üᨦ]±ßòFä5®å¥¬‘IãùY±[ÝV輬E<Ð÷GWw1ŠÓ nðã’+oöñRM2Í<QdtÚ±Xyl`짬Žt˜×©™«ŸðõÁ¶•XÒlP‹â6?K9Ð_†Ñá˽êJôô:ò®³®Ê“W©°[ÁqÛ“¾Þ%ËŸb[ÓÖ”zúÌì\ÙsZäÅþ»Ô¬”4©ŒYGºØQÚóÃ×îOUw§3{ þðåNîÞÒÑ·d›å[Š>ûÕÚì *™tA[û ¶ßsu¤"ccká-=_¬È{:¾ü??»¹¯{TG\SüúôÄy¯Çc;‹6O©ð|ÍäAÛ¿¸®÷‹ŸòSöáê¼ýºë##ZZ¢´AuÆ¯ÒÕ,]¦ºÇó\Öªˆ_Æ^¨ÑœV›6ºG¢R{—Ž6©XwÒ­Å–Fú†i8¡.ÏŒZ-e}fUjïôJ¡†*­]·;Ñêo37Zš±-¶ŠAŠÆ9|Ì•ÈJ4)î°;²$vG… }ö¹`�ùFõÙ‹c7NÈ:=mhÄ•tyU²˜ËØÎ ¬ÌšâñŸ¸l"±=P¹Ç‡˜ÚM<Aoó4 ùS°Õç’²gò2CÂJi»ăôr1 øKˆƒ… O"ƒçì½ÿÍà ·Êô=TÓNV?öe>o±/ð—ßc æjTCÈeÍU¹GXÈNÖ0ŠÅ4øaS×ÊÊàz”¬Ô?;Ïó$ÃÇù—Ó¦;‹ØÈV. >Ú\ÉvP�uo02 ös‘’™“Z®,)¥ŽgÓ”9}Ö6ó0çógÞ Sđ̠!¤P.È1ÉhûçÌÀÕ¢’½´1‘!|ÞtR}2ûü쓜á¹t“œ)øÞЛÃÅæ¦O¹˜öÁTÓù]BYÜ!˜C> !£è�q¬6VIO…]zÎIúibQÉŸÂÁ~<,Ïrî9²Æ>F°€Ghf>ﰎጡ¢9Šë\Ú9Ÿ­t2ƒ'̳Œa6Kxz.¦˜á daP|¬ ïÀç©doÓÍ©¢1´g=ÈD^'H-›ØÉ"vœd0<%�Œ×ñ.‹¨Ï%XïB=sXȽlçj®æ-¦0‘ƒä'ü[BCÜïÛͰ;áò2{ûÜG³¹—©làufpy ²¼ËÓav*™Î9<ÁNÆ0˜Ã oQ ç0ž ¬Ïw}± RýÜýSÉ ÎþIÅÞd+ùŒ%ÅPÐ(9Üßyk�û™‘p>‹˜ÌS ŒÝÍ[e†¦,(26­6¾fmâœ3âu9»w®îqΗÖÇ¿Û\yla¯1 ™X\ª5esl ï00«ír £G[ÒŠB¥ ÞaP¤9rE¡Ò”îÃR)/f­íÕ•µ;rE¨byEöœè—eîJkˆõ%\È»‘[;lì0«×¶¬¹hWÊÐØ0Õ›[ö§ÑɺúüyGz&)ùkgÝýo¿üw©…ë‡|é;­tª«v¼¼ ·ó†'kî¹¢ÕC Õ‰êªÌ÷¸ã?òwÏÌ(#àpäDÞê™g}±lfoÔs(Z±¹ã÷7'ö—iQ¼aqâ¦ßlWü‹[;UŽ”Œ%éKŠ“0«ËžŒiÕ’)C+T¥¤èêó±<×´ëèÓ“Õ[l`‘žÏÄêÙpQ‘m % êâÿJ¼èÍžEk»­I-z3=¶±xóÔ¤]ö%œ=PIFE1íNïð»2CŠ Kh+7hÞB•š2eÌ‹­NØ—URnI¹§z|¤B]‘æ|UþÈœ¤qIƒ#mU6ENôöpŸÊ3k 8òNŸT%ÔÆ9Oä ½v±æ£›4Ëø+E´$ Šm"?÷[ª(fR¸±e*‡ùY¶ðJ`ñÝ eì奰”ú+áÛ:'ا¶24HÛ;‚HjaÕä0•¹ìàcÿC÷;4ðqrN©޳“n9›fóh�Ô2œ±AÅ«*§¤Í>›ÿ¿^ÀßÎVºúËÃA%—S à)¶08@ï*9̆ÁéiÁ <›!~¥ËÙÈ–k9‚!lÈ·ñ?ø¿QÈ|˜8R¹«s[UÕe+®;ç;®Vww"èñ»x‹õ~´á‘ÂÞ/æ–òRèïv³Q!è6x¸Åäq”/ódØiÍì AD–M`6e¼JKØÂæ ð)ÎåKÙÃ%á<¨ç †3‹ƒäÓCoS•p]$÷ç¯ä¶Wð:™p•ÒÁµ¡­\ƹùg7{¸•clä,¦°ëy” ã~Ne›9@CÈ›9Dì=|˜9lá VðÃp•³ˆ¾~áu?°5,óêI}=T25|ÖRÀP^d$çÄøE±õ‘Ób·‘ärÆGžLš›Òʾ܅ á_#—Ä&’ÇßXE £˜Äfëß[,çk¬ùX§ò&‹ÂœÎƒüýüGºÈþtäæ(†²·ÊâŒ-Yߢ-ÖâZXœ4…­¬ˆ| y`X|¸€žÜ48ö÷ës6ÓØÇ;=ÞÊšÒ{vGö»?Òôþ¸­Á—WÚf󩜮ö%×w–}çÊä–fÆõy}€Í}ªc§'ÍL(gë“&•x>_mJGˆöþàŸöŒ–:c:íˆmΘ@2a`ÚæXUžók´ækJÛGkJ]¬€Ê„ òLH˜Ÿµ._o«ò>ƒn1¾&µ|ÃôÅ}†u‹ó%33;&Xyeº´¯û¡±M—÷”N(Ìܱ¸°wV¬¤XÔ ¶« 7}ýU÷,ŒÔô*ˆ¾»µøŸÿì+tå))°¹ØÀ>£{Ö(ÓÛ°ôP瘰}P‡Á ‹ʾ1µëꧺWÍÐû`lv»?¤ÌatböÑìí?‰—ï´üåö‡6G¦V¨L)Œê•Î:Èä<EeÝ¢´ä(Ú-Ê:Z¦°B¢ã¶Tï˜1°%3®Åñ–²tw­Û¿•<1¸`ã´Œ‘ ÞfT¹‚<³š5W;³gvaæö{¹ðÄ¿p^¡„Á§Œ”m1š¡RIÏ7H•:»\ê –GcÌ¡)ÖDsBM»&S’çü´ò´æØš´ü!20ÖÉt¿¼Ï§¿#õg=kYÁ® %r(v‚q*㸛4ƒ¨ç"*Øš¡§)dY˜æbs§1†¾|-ó9…gXÌ@œ‚^7…jYH!Â�`fÐÎÌD_ÎÔ FØ@¹“õx0º”ÐÈÚU”««]\Á>ŽÑ®ûï2ŸìI4ÛEäs€Â€xûY9‚‹«1¡„³àÂÀ6›À¦…æ,wF^÷Wk.‚¤5ÄMd—k=ç‡+¨%ç‡Î|6pMUU5+®»è;®&uwßË~®¡‹£AÙr<dÔžüÈ­¯rÝ軬Ú409PJ>[ˆ™ÄX^#Í׸Ÿ¶Üv;ØÆlZ¸14­‡Iq Ïã{/,÷_|—ÛØÂö“å, "ò׉üñ*^ˆ½Ëför;÷ûmSv Û¿íA»a‚4P+¥låldS n£“Yì =õC¼Å4žåu6pJzç|Er¯òš™2°sMOÎ[}2 37AžÉFÚƒu '¸œµ!N¥‰ñ$yŠ·Ù›ÆË4äv{±Å)I‹#gÄçO±&~Âf.b2÷p„%¬âžFÞàf±“—©d ¯²ŽYü!œ¬ß˪H‹x™Ëyš\”±4m4i~™tðI¦çDZe\Ês|›jfò$çpȼ¿PÜbböœsk%_ô³Å6Þ¨¼Â~ïú­Vö³?ûZufוie½ ,¥:ezÚꤥíŠ5…µù°Œ1ÇòÌÌø@BKÂg²å›ÙKV”U™ëŠÕò$ÓcÇjU“é–¨23rzŸ~—°<–ÎX“5"­$mLRÍP#›&Tvüþ_Û®[Õ±qnæP[ŸQ}Ò] *kÛÓ›nùƒUõ2–w˜ÑÖR#9,sìpcgÇ_~šmŸ“ùôߢ{ÇÕ½vÑ=­vO“·Ã¸VSÛ<ÓîhÚk{/m¹x»oêRx®uÔ Öuâȸø w&nx¨î·7÷Èf¼0ZE“#Ù¹ë+F·&ô‘Ôç~3ÿç72¥ÃGèjÖ’v‚³6Ϙ¤iY­½öÒ×ë)“NÉÒyÛS/•øÛ¿”l­>´µ {k]Þ–+ÒR V<~MŸC ºô¥Œ*¥UwùR¶óS©-³+÷Ô¤zÇeʚѫ#ëP&æf”f é1*¡¤ZY£Î¬LÒÈ¡Æ´ÙÆÑXež =ÞaMü"V¹‡º>÷0‡b{“®ŠŒŒoþ»ûÖJ-`r`O7ñ7&³?¶‚BþÀ*®e 7qŒÕl±±-ìàêpÓˆ·9Àø3›¹˜oêM~„ù\Ëkñj ©çíï}‘_ã½|‘:åè?žU©à@ m¦8ÊžPô®âÙÀ3»9\õn` gP|]»ø4å¡P\2ÇOHÞ¨i�� �IDAT§ˆÉœOkB]½õ¤åNFuˆk©çƒ¡QYÊÆ@šoáv²þ$«ï['eÆ6†‰¨“  £¢_%qRe{Ò½‡oó cy•öªªî2 üQw÷¾ÄsÁv#mã U|½Áquòúê/¼È.%Íq&êZ(§((XríÂÚ�Õ¿†{é ׄFvr$h1o`£Cå{'ª°Lº4ˆâ¦²‰ ¤©æÃ¼ÄɆ†é“AòwÏr-{ÎghçÌeÿÉqføP'½ú;’CÜ‘oaÖo# x?K‚ ?G¸øõ GÒ±Ky+Ð@Þb£XKÂ|neÛ餔VvÒÄWùÉIv«ŽpäÔ…T´ ™Äãlà3‘ƒLe!¿g;gð|δ˜3dä²Þ¿{"öTІ<Ì@zx†'#cˆxZ–òdä0gó¯ŒæJÖòâeÚyˆ¯0™RYô»c¦•YÏð«)¦”Oó ÐËùSäQºÂÕ²NÁhS~%úŠÎ¥üŒ›xŽÛ8Ì%5æ P?Ù†Á²§ÙÔüÁ ¨nXüÕ»œªÆ¯Åž‹Èw}ÚÞ„±íÏÈÄîŒÌ‹µ vM·ê„I[bÃb'’V׸­Lº@}§w²2 w'\•õ] \2À¹…ž› ô y)ïæYØag¯ÕånŸèü£^d#û¬ÎÊäÉ$” Nô˜ûPôî¢hãìô=Ÿ_YRtàû•Vd 锟ö…¨|D|Æ]ûv×î™]­½B²Ùãm^ë‰O´ãüáwEG.ü]Þß/\÷Áa÷(ì1~¿ÑEZ‡xm¢QsEÓ ÊÿÍ-ÑeO¥_=s¿)Óì<¤º’ô}7¥?ww×]_KɦÛè”dA23÷Dy[ñèǧ¶þüã‡ßºuø]7õ˜Ô¬;í‡CœÙ¥)áËÕEâÞþ¬Æ´™¥ÎK—ŸÈþàöô•Oúé×G6÷5jê6.2aRÜÚPRž˜õfæñ‘}†¤-ÌÚŸÕÙæÆØxnJ÷¦«ŽêîÍ+0"åhÒ˜XKìØ³#5Y¿ÍúÎé¦ì0©Ø±|#º÷¨Ëx éX7SŽ3€§#?*ò¾Œ¿ÄÎÈúyL'ùFÒ´Hsöæ§ÜwŽÔú0û¹—å '´ÆþÄ3ÜÃ<Îå[œÏm æ?YE+—°‹¾^•;±.â:nç…lfwÐMÏsƒ‚?õå“pº+XΡÁêcsP;û§E'¤YʧCÒ|Š>>²¬rÅj=/Ò2 } …<Ôz V‘¡š#œÆóÌâ¡ËÁ33TÏGù½þ<èœÞ$—èôG¹•µÌã ˃óõ½g^À¢@éÅ|šÍáO÷r!M ú2Ô†¹]îË4†ÓÀ² ’×Ý=‚WYÍd³‰âp`ô3‹!ö8gngDè©§nÎd!ƒI°ž#àÿI&„ ïHö„Èä,¡|Fò«)9i—3ý$®Dn*}„V ¸‚gi?‰´XDos*e ŒÝTåîȼF-¼Ú¬ÂȨH7“9Ä«dhãTjßHú²ÖFºæÆ~´m•!íðvùJ–¾þöt Èñïä¡@ûß$F9ûó„à0Ë5I5'åÙßÀ6*)ŽˆóØ›»°D&|=†ßp‡¯\]|Š®€ìÌc?SÃÔû¼<ó# ‰ d�_æG4&]É,f<kÃÑ^̬È#ä] iáÊò|4«‡ ƒBw+s÷)åBN¡œçx“×XÆ>:óܜՙ‰¿Å²#Ñ]»£¼Cqà`¢÷_ŠT§½ÉQþì‘.|ÑãA!V¿´Ý]“ÊÒÿ•U”¯;c`ÖqnÌ*Š­MË36vJÂ;¼ÑiRÖ)4ÆŽ³1OYÚ)]§µ¥ÌˆMMx©DE‰º^—ÒœÑÞëXÚ²BQ»£èŒe"ùƒ¬(%,hÓÚãHRU…ÓJäem8TR—üÕÏ ¯û¯ŠUÙL"®>wUKûŒž}Céë±+vVtÁ*£OôË;zT¥ìëT_hÔ"Šu0¸qÕ·'rÂúcf§­ÎZ›qpªÒ>“j)äø…¿•¯›X:þÍäž™}í%íÊ åy½Kovò‰d_y´oh¤0–—ùùès¯•|îÆN™œº¯¬9/y +ßø”sR&å‘ç­”ÚŽ& îµ*R1L׉ ~í£/–Ýp§ÍÇ魖ßãµnG›Í2|CrÖ_G<>5£*Oi½Œì­²¸DÔáá¬QiEƒ½ÝmVýÉX*ߨ~°_ K‹]ÿ®ßåy·¾>k§¼Ì;=Òåf¤-bDlGž›×¥3k\dJdC8=)9@ª@}ÏÍ+Ý×+õ>æ°’-|"öÅX•œXì±—ׂÞú/ì §ÀÑZ7fJO–bÎãΡ.ä¨Õñ>ªŠâ<æòIÆñí £Î-ž‡‡Sª’EẟO2« ætÚJ\nz¶™†ÑD ï«ó8À™”† ÛW¯™–2…™l n­ˆv± œ4×ñ¾P¾ÚhgÕL ¬ÞÓˆY{Òp+÷BraØ1$(&rˆ‰ôIS¾¼M3•ü˜f¡“mŒ “˜e¡ÊÍ¢gx›z6ÿ?Dºº»ïOt,u³ú¡«9�ÒêOÚR>tK¬ž7h'Qd8›?q= å8Cy ¤ð1^ä̰ïÉq÷ÓAmtæ„=IŸˆµR’ùA¥ÖNÓ‰t0œ^®á%6†¼ùT`«äпÏRÍŽœ4f<^²‘Ù‘qûŽðs·Œú“Ë�[;œ Z®Ÿ¡wˆò´²>ÛYÀox-‡Îd+{G9­ Mg®mzŒ!\L#«¨b G“)7Ì-êrЩ*ÊèàÌØvŽ04$½Ë2>K†A4QÂø@—8Ê8æ±þxºx=é™~AÑuôÐÅ%±WZ4‡Ë* ƒSáx“8•3³¾OkÙ‘48öjPHîá!³Ÿ ÓÆl^¦”ó²ÞL;êŠz¿zÊöQÑý7G›Ä§eu"ñâÌÇûúe÷û ßiÖ›_d5½òñ†¦¼‘gFÊ\ŽðL䬄ºØ¬}IgdKøWhr¯±‘¢X:«>ijÖý…FÅöfÕfÜÛkT¯ºXS¥‚ŒD©=޶‹Rú²²šùIcNHw:Q©¾ÏäF–èàéf§÷]ÿ¸+“£öÜs~‘wz_Rõü¥Ù{.X×¾tuv÷9UmÕ“îJ;a娬’HcF]­®"5Gµ7V*.ðv“í±S+Uš\aÍ^'<Ò*ï„ÝûjôÒÂÌ®ª¼)ÛS;ʓ͓Š4å;Ò­i€dzã%}_™ØsªÝS³~3´jYfÙÉÿžÐcP•¼Þuš|°}gQç“Î+ôëN¥ƒcÃz5ç{´Ðôaj»Ý—®šœ]¾rÈ/nε¾Ý;C Ù¤£[GdÚ G›âyù-CÒ»ÏèR˜ï7½†%-H¸¸SO‡fZ ŒäùF ÖUššÕɘ<¿Ù)®´·Ä¾¤Ú> "ó 8H_¤µTusºaTdglÂ¥­âŒoñµÈÄàß%vG¼O¹y‹û&Iíçõ„‰œÍF†p+é{çlæQÈXZ¥³GG¯gøVØM䔽áÑA%?g.½¹�Ò¤©q?!"§{ú=©âg`2íŒcbX5œD1”1>°³7sÒ Ä¿ Äô|ÊB’ø9bz0ØEÖ1‰Í”úž>0—Ê´?hùrۜτ‰TsˆAtȵL z±ZÆ@N}ÖGy8/;9HSƒ}ê½±Ðb6²‹bæp”ÁaÙ”K’Ì5Eí\ÈR¹çPUõ×õ¿W?ïî~¯|â(—Ñ•Cä¹'k mìR5œ Ÿ/Dž‹ÿoK{Ï06l;öÒÅ@^Ag»ƒkï²ÜÌxöÐÃD^ã8_`}w.ˆôÆýø¬$ÿ‡¯ûŽ·»,Óýÿ^e÷¾³³wzï-ÔÐkiT댎eÔãO=:£#ã(ŠÁA¤‰ô ”H!…ôÞvvvok¯úýý±òÌ+çu^Çü]ÖÚßõÜÏ}ß×õ¹ù*nÑT{;û˜ŠÇÁ ÙÅÓô1=äb´p ›OÈ6ÔïÓI…bVŒ)zö#îü˜á‘~·ðìþK‘·”ôý‚kb‹ÑÄbö‡cé0Iè«©a~Ý„q΢…ÝTpåA {˜fna!ãÙËØàÎ{—8¾|>‡ùc^D%gPÇã,#Á$–Æ\ùo&…8ãæ3…%Ìä([æcÑñžo/iæ$\Ìó, ™?2&æ²ÈßË%¼Ë²\HžóØÈå<ÍNbqÌŒÈZ_ºÏS—ûálŠE­œï?_ñ6õœ¯œo¾fûb_}ÓæÛ}€gŠ’¤e)Ãr¶eUòÞ‹9Q —pa´‚þÈÓtÆœ•µ£ÚËå–e4´˜Òœ1>¯½ ¥Ê²e½ÚFO‘l“Š™œ×É}‘¥¼ÌöÈYqeŸÈêé•«Ò™6ø·[{o|ΫÜþLò‘ç\šÝ_·pо]Ù ÑÙØhW¿»á9KÖzàæïêûò¯ûÞº(ÕÓœO©êWÞáÛµ¦²2aCƒÞv×GÊGˆnb¡v•)ÕCjmID¿þßÎz?¶i~á‰ey%T5ê­21¥>•ÛÞX‘ìÿÚÏ ¬H¬û—‡2ÿñ­©‡ÆÕIí2qpø;ÑY;ëÞº¼‰~ÿ>è-nd€Ê„I©Hº 2õo¿¼amìþsjÞ\Zf°Ï´~_IÛÚl\“áiJFÅ»OY1øNU£Òne"«"÷FþÆl®È©¢d¾(¯¦ÏÜœÊzñ›"g”Z“ës_ÜuÝ11Ã"Uk=Sm~¼œê‚ù ÒÈÃLà%沆‰,©9Ém_.|ñ/ž^Ì6J£ãÂà˘È}Lá»D\ÎDöð1ö3·xÐçTvù}ÚÚ‚"`L8ôî(2_xƒ3y–NΠƒ^®ã^†s§²Š©œñqò<BŽ^Þú?ý¹Ý!Ügû Âÿ44mÜHþÿJÌž°z/ ƒ¢¢Dâ߉_íªðÞÌ&v²óè³wRL¸/°ñ\Åz® —ée¬ ÏzšécËy:„Œ£$D{7qÐñáJ9¹à±iev8‚‡›èar€Ê—±ŸõàC =7Ü|Ùß²§9q|–·édR‘-¹“ïŠp±Š.ã–ñ\d= >Åø wÐÇSÛä’wr L‡Ï ¼¬™ü< b1Ÿâ¥ ›àXä º†!Þ •z&p€;yޱáÜ?À‡x»xƒ£”„PÌÜÇQnâ:Î !.PƧù °³Ôøan8>Z½™Õ‘cÑq‚Ë tòýPFp?gYä­RK†™6àVÛrºøkI3À=<Dóƒ®<Øôƒ§˜ƒ•¡@iæ^§wYÉçIs? ƒ×äv‡é-¾Ã9EìP©‰YðKšÉ/ÙÇvsnt\Iqð'žÍF>ÂC<Ažñ¬åÎâ=®§·ù4Ãh‰<Ê’"v+æ`ä¾·²•³C>B0÷XÇl&°’Û#/*éuÉDÏuð¬ØñÇ=ë®WÜ3‹Ø”,¿*zñOÎ9bÿXµ¾ú`ìñKkz?_«7kaÂe9æ³<­l¯h¢è͸F6ð³ÈˆÈè„BÂ’‚dzй&¯2cbÂèŒÒUÆd͋ٚ´¯ÉŽ‚}ÔÓ˜u(2)¦Ši¥&Wš\kaJm$Uípþ/£Çפïz!{ןҷý¦ô¹;<wvá·3’¯]‘ßÛ›4/ëèL‡#uÇ—lŸYöÜ­ùg*3;~ýcWôã¥_~­ð_??>«.76R)K;)mR™3厘3¨v¾µ»Ä‡L/Uhs¨ÑY)Sbâɽ?Yöç/ôþåÖÞ•c’C#òÞ-÷íÒÜgk.¤úݱ£›ÓqÚªØ?¿4ÿÎÛ3“c%vùó€©Ñcßò¯_Ìtj)X2ÃÙÝö³3áŒBl¨ªª¼á–§þñ‡#~õÅú¯²eΩv³•O7®ÊY³ë$˜”žÝ-]fQNK΄HeL—.5¦ÓÙ{âÆÔU«9¬=-U0˜S•“)Uh1-kJ½Ùi#³2µ”(Éøvqd’ófΓÿÎ%T68PâæŒ¥/ajÌèH[ìø,úúhÿÅñödôõß{õˆÒkäß­ç@ ÔunŸçQžå.XÍoÙÌ—…x‡Ëx80k–³–Å; 9–±”^á:Þ¤>(§•8­`7ϳƒó§`õéà%AŒð 6‘g(p½¯ª`;ƒW¸„,Çz %œÁGYÉAùò[frŒqEÑ?IJI²Ž€¨( çÒ$ \ÀjzÙIŠVŽq ›8ƒ¦ó1Fñ|h¡Jȇ8Êý|ÙñxÌŽŸÞÁX®ªdÐ’l û¹“x:T²Ã ý‡È¾3•Šs;¸/(ý‡Öäñp5.Öü±,¤™áj<—x‹OòÏTRÏQ’ŰÇ¡;'f`x*ÊxšaâRj¹˜+N‚Rn+úmYÊ�GÈQÇGCžæFð2³©ì9œ‹Ÿ°=´)khà?؈±7òr40”7yÀ‚0:˜ Ri¾Å2ü ÀÁ®å;dÙÂÅy÷8)ì?Çââ` Þ.lŽal`°…2¾Í³4#K ¹p)áÃì¹ÝEái\@I‡à<ÈTª8—ÙÂÙš÷µ‚íœÌ4ðær—ñWr¯ðÝðã"Ú)~àgRÉVÞãŸ9È9”Ó[$$´²› |õÃÜZ°» žôÍ‚õt–¸² ”¸œy¬à3E(WÒO >ËŸ}ÕÞ“O-‹ÛÓä­¿cœ»ÞwÏ:®á@áÑ'T·ºå .oõå?Xçׯg7¯­m¿³D<¥³àMÎ4úy=`í¢ò¶Â(Wöha.?,sscîϹ±àãUʇ©È9“Èx<gZÊÃ{§™Øê¿2¾™ž2#ok¹D‰úh·ÇÏØU1¦ÿؘՃc’ñ1#ÆìîÿßeeÉknËÝÓ¼üžsöu/Ët¨êN–tWf µÍÆÔÉÔ³Ûø6‡+9MûôÁcíÝ%±ƒ?®ë-ÏßôtôÚ%#~ûéž¿|*½æÔªÎÞ!åYµ1/%TìòN^i̬z…2µ9 âMêÛ4fçØYƽÜ}k¦»ÊЈ“µv™3¡Bc•ØŠ¤iC¹EÝ»¢¿®žú³ïnï¼.o|«ßw™Ÿœ7ºpÒ3ÉûûG:=r$¥¶Oë(#&™50ó¯õó÷wüá;™]ÓJoýÕàÎÉÙÞ±åâ‘}GìŠ|·Û’”iãu3j ª2óÀM£®ýbƒG;ý(ò—¸‰ÍίԸÓÂó¼=d|d0§¡Ã–¸ ÕŒ+WšÕ‘uIÙ8 ]p¨ÚÁ^+2Ö%}Šj.Hh¤&ò՘ݼ5dnÚcU¹5ëýÈE‘©´¨ÑØ#ØÎ÷Fºª¯·ÌýnÝ ãó%õ7Êkt¾Ê±køLk½4æ¿ šáücPœf§ð6ßä >sy¢Ȇ Kj ñ¾Å<§% ‘¥¢àëÔ0Ÿ¸˜S˜ÎÇYG†kÙÄp‡)ýuŽÇ·¾8ëEðgù9U¬ 1³Âí9Îùlæ%º¸7ªf1šçï„YÈ>Þ£:¨ >Æ7YÅ•ôaÈ*.g3Tò îg Ïðavp!kÙÅÝÜÌÆp‡ø8e´ñ"¯æ,šÃh±$™€½oã$Jî|WHêxùßqcCCÉß)WQ*µ2È1#fQŇØË7ÈœÀŒÀ§øãTp Ïr%—󿸈½A¶XÉIäYÂÁ˜óâ#÷QG*d6¾Nëèá�!ΰ‹í!yºˆYJFñ•¿NAúRdµÏre€Ç+ü,þÂÑãvTÓx‘é$9‰®€†Êp2Gø4‡¿Ä} 2"ôZI†…áº0¨-ã &óXÀ*.¥"#’\ÍŸƒE'@ñÄ¿;dØDÁ{¸Ÿ‘¤éâÕxVx$ÜKÃèàeÎ`vý2ް9öæía¾Èݬeˆ»˜ÃNf Sx„îÐË~&°2‹¿d#ùó‹àãèxxqq<=5eQÞ+tŒg1·<ÌãÜÄä`ìÛÂ|o(2ËOk•WXûr£WŽy‰Ï²Ô]uÏ*œrªM>3[~œ_?jõÏtÃþ·[R&|Ïñ ÏnpÇÑø=·fÛnëñjQ°SYoN—t¿dž´çÒ&õITž‘‰¼ÝhxÊ‹Uf´[”w gÞ¶&ýy c /™¾-úÕ_¢3öµM° ½tÁºÄ‚M¹37Þ]öì%ÃÍ«©1‘DL¦NC©šœ–Ù6’N:\g°ß©ö—;¶ßˆ.ëtØ?8XQ—¾äù¾ÆYóó’í.ôºÉ¥ CÔÌ+ÙåÕFñƒÚóÆôè¯%'–±±K>M¿u-ºj M×Ú©¡GK¥•Õ*;¤ê¬`f•áwt›2Nk»ÚA] ò/Ýûó- †lXÐoÁs¹zü¹mÁ°Š‹ÖuO=<ñú‹­ššðb©ÔT}GTÅ2½à’©„änMiµ¹Ò­nûÝÀo&Tº¶ ¤Öy))·,wÖkƒË^ß¾avO¡|È{åÒF÷ÚŸ2Ð%Ñ«®F&¡,§)alܱ¤…£%:-ˆ[̈¸xLr„¦¯ ª/u^™¡œwb®®µºÑé=Òü u.h×7)’âÜ>ß°rì·ßŠýö|þïÂÒÕJŸ¶¶'n~dÕìätÚ)KˆGV3ŸÛãFE¾ÇãŒe^Ày_À ÜÏÅ‘zNa 팡2twò Rìæ0wÐÍDÚ™Ãxšø·õ´)p�nçUšX ÔEØæÿ,ž ½H:ØOŒb“³i ”ôÑ1WÇ<A–Ûxò„ÿÜpég`îdÙÊÊPT°‡Ý\F?ŸdO°$@ÚÞfY”ÌqΤ]A¶== 6ê9“v1'Üø™Âv†ÁËSìç,z™sB¼ßTNmh8úwˆì¿J¥*™C–ÁðŠñ_«‹BáÅ_J÷N^â,Þ *‰gI1—Öð¦gÈr2«è`M$ÇôÀ@|ˆƒA‚RLXØÙ‹Ìže!©¬XþƆ g¯ Œýb|û£ÕÁAë²6>ˆUÅÊWü›x—zNbNЉe5¡•ƒ|ÄqÛV.4‘EÑiaÂÖÅÅì ´øþ‰ˆN&Ζd*»é=at{â®å® ÚØDœÉãÛÏ]'hú‡x'—pÇX«\ÏNꨠ7ŒžŸáÞç].cDq–°,r4$=ò2ç2š^g]ìå沖΢¸€3Ø£7ØÀ4ât³Œ1œD& $÷p ÷2ƒkÙYî`™žìñ}@%o°ç4mÈiíž›îØPµ éM§7ïÒ½RÛ\~Èïf%}=êzÌ;7XÔåÐRý'™³Û»_ w— ôª·©"þÖ…QêOǵԛŸ1eÀ¾Èe)¿ŒTsvò!Ï÷«Žk­pá  JÍ)8•›[êh%²•j^óNês¿›qçç:îþ|é“SŸ\Tòäy%O~h0ŸÌ—,¨©UÚfü¨ ¯Oõø ¶Yz·ÇH¢Óí챟"ãOÒÖ+–Û1n°&æ¶?ÇNêþúÕh瘘Љ>=^c^•l©i3RöU©ÏËÇÔæl)w´ÔYÕJ Þ-W2IÍ“ú®ÔœVV)>drŸ}I“Z¤*R2×¶. iS Æöæê¶”—l(Ù/•ª,Q2£§¤­òócr®g7Ù_%?^O¿Q5qñ9…f²êRjÊ ¥‡Ü¶"ö›»bzÒ6WØ40­qè_W” ?R()\ÿtl\!¹vf©#eês~4Jc|Aí -•楌©+x©`^»šJ%ÚrjbÙ·1cvÆ'\’-¸šÆ)N:ª1í}j©¬Ð’òxܲ˜©qc#£©‹y–¤Wç{o†kß’_Û=<2È»43ŸžŒiî£â®ŽÄy‰ýt‡ìºbÒn7þBpOâlê8‰½|˜w©dŸä¯<SdÙ s]Ê!žg,휾ü 1C ŸˆŽ êãdPÁA®¡’wéŒÚ9aZS¼,n ŒêY÷­ŒæeÊY¶YýŒ£™2ޱØq;|?eÌcfÐñ_Å~ÖRÜGe<Öð}lde ÐNa= ÙÎÉM¦œ[¨a³I&H{³]_ %g0\ë¬;!Þ¯…u WßpóYgwU´:ïcˆ..âIæ³™+NÚ„Ä iœÛ(å†È±1\(Ú‚¤pIX»ÝÊ:úÙA:8Ë–²ŒU$™Â»l,¶Õ´°!ˆ,÷r&%üK` 3ì‹ñ»Å¬¿X\\g±‡Tqqˆˆ|#€Ï籑“x“õE¿bOÀ;­ç`ˆA/›C(ζàt>?4¶«ƒ‡ (hâ"VÅ`;èü?=äÕœzÂf9T‘·ð×ö«ÙPä>ÉɼAš™|ˆ™¼Åi¬âíÁŒÜÃË|”ˆ8‰‹y3TÄÇXʽ\O'Ãx’>jXÉi>2…ñ KƒQ¬ƒOr”§yŽSéNº»àEV±„ø†óxð]uRÍ &q[ Z V…äïn®£_ýZÿ«Á/γu$ XÄ‚âÓm¼Ü˜WþÅ/§Ús{ÌÝ wŽu8XðÕõ6Œð¥'ü±˜­¼ž‰ wx£ÕD©•%¢ÅŽ�� �IDAT>Ù 7å×‘Õ WΥƆ,Oº°à×Ì¡?ïô”o§\é®Qž¶)ïw{óÎî1,¯fÈ3¹ÖŸ›ØÑûî¾Ôž+ Òý)gLÈÛ—Ð6Ìã1‹*[ìÙo‘yµkÆ)Û£.¦#íè0e9Uš§È¥M+㨑µ²ÑÎñ¹žù-LN¼¶©Æ¼±ŽµùVÒ¹“$zäºíiJÞpZ*ejUw‹MÒQ%×næt{ö9oÐÁ´-mõVªª\i¦¬ºy2{mËG*ûmg`ÁÃÇkKm<shõâêÕµ5«¯¾záÀê…M«gõ­ž™_}m﯆›»×PÎâÈš!Ós&dĦÙ_£¼£ûLÉihÑŸ¶5wïO&|çÓ•‡kÚ¤ò Ô·yò騊¾Iþ¥+ #£³¶srýºÅm”Ê7›pLÃ#Õi›#鸉‘‡©IÈæý1¯*f\Á÷#cRžÏ¸ éäœïdÌŠäù÷”Ê>I^ã4þÈ‚ÈY«Xy’ÓââN)˜Ê=&üÍm{üþì¨{Ëî÷ht¯ç{Ì Óš×"Ëy7à…|Ûu´)"3üŠ=|™õ¡„‹y›3™ö@ïy^ñÜØ³‹sé`z°� çÞ¡Ðñ,n§bÜF’T´±öó ÖÓ0l»¹…÷9•sÃøî´È#,åö„ Í9œÏ’ 4»<˜2ãÔÐÎgŠr$³”Ù¦SO‘áóØIçÿ‰Œb o²‹KcÞO¸!ÒRzYÍÆŸa?KCòÔ‡x',öfÐOM¨Ê² xÐ54l¼áæ+þN¹ê¥Ÿ;Ésf–ó]¬&F97ð:ožàèádîãòdƒ¸(Î!ªC oRη±€VZ™Ë<Ì»ŠÈ/»Ã¯8Á+Š;ba¡U„Õ¾ÄÇC¶tš¥Üöjkƒ|n§±–ïðKÞ ’GéaA`#ÃÃt‡=g=>Èl¢3YP-ÜIŠ7ø×ðGf±& ªšXϽÜË.vó2Ëø3mô† ä¢ó®xúŽçO�\µ2©ìa/Ÿd5åÜÊJ’dC¢U—ñ-%n+( aé0#>Â"2¼Ì lãšy™»ø))ž'ŵìæ×¤ùg¾Æ6‡è“^þ²Ež ³øuŒå²ϲålfSÜÅq3"‹)p#?¥3¸’n>Ê®È릞‹xFÑØÇ&ïüiáð»Å¡e‰Ïå%ÙH.æÛ>ieÆÑ·©duÁ"öé<æõ…±{þ˜¼ñÂÐcònÉÎO¾sJdndÿŸENÏù|Üôc¾ÞåÖ‚©Jº §&n^¯é>—w¨Þ`Ì„¬Iy+ì­rÅ]%†5>Ø·¼0·7óý7ÇüáÖÔà`ƹ¡`d…ê™ }6޲ë Ì ù“µ×è&›5£Ly;Ié±j» Ûï~ÝÝfdí>fsÎC%.&Ý{häèC#XÐ ?Ρîné’Ÿ-ê0±Qf³a1emÆÔéà!}5¦Ì±u»YÉW²ÃãÉê9ÙêÌIÕwV?¯~LtÚ@ör•Y÷”:­Jç‰!=ZšõwiP=ÌP¿11m¶çÕ 7¼ËèÉöæ>_ëgÇôæµä,L©O)5С®TÍa©2ÉaR•õ™žoÝÝûõm)§Çj¦¢Ø?µV&nùJ}Çœ)tm9½ü÷——Ÿò^û¯¿›»ëÙìcuTOçÑ’lU¤m¤–>; ‘FñX¢~FíÐì2Ž“ìôdoV9%¥¢ œ˜Ñ1¹È3Y¡<ÂÕy\É<>Ê'Lä1Gv0Ìã+ãWüGüè5‘Æ”»#Ÿãª@Šñ ¥as|§R²á_ðß nŠËfà n¥$¤œ/yÓxŸ×8/¬À¿Äì/¶_9Û¸†µ‚&0Í©|",qÅfÞ£‹±€bj§=|¢g³6ŽîÑ ²{Ÿ0{9›ÖPŠÝávNå·!¿øZÆñ_æޱš cg ò¬ Û¦ÊÃ:ü0qnd·‡"ºŠ‘ä͘’¸y?$’…?2½†¡»Ø]µh_‚·ØZŒž("OPGÏkhx÷†›où;å*œk¥AV>—ñì¬ÒÓèa¯3•8J-Ï’c'ÝAQÝO;C|GÙAž¯QÁ‚âZxœ9 2;oðóÜÈ døGÙ̺ÐüŽ QÓ^¡9ؘ†ø)Þ&Ã)ü˜%lÒþñl!Ç(0—$CË\ü3\ÊîÀ>Î_æI^ã|ƒRÿmòÿq3/°‡Ažd$W'Ï‹L&Î\.åýðdÆòk‚8C>DY6²'(Ïd Í\@k¨Ð¥*ÝVÐÌXÈ®bÏRóÑ�E|:&Æ$crI“ öòµ0i|…YL ŽE1§ñH² HðDz„ÇÉ:Îç·ÔÑÌ>Ƈ»¥–D¤¼ÿ Õ¨H­¾ì£9¦ÀùÑü1æ¼aRI×$&ë‹»w~!×}/Ë–pkÞ ~ιü)é+ ]Qz,3x+éÇ÷³–Oz݃©ÂÐ1>Þ¢1åîœ "G"s#檤¹yç$œ—ªÐ”2˜tz¹ÙÇ<×WgLƒDt“äþ‚»Ó.È(«óVJÖÍ){#“ò6GZ+½X¹¢2ÛR×—ѰsfÌéÃ5ÔI4ꑬSÓfa¿Ä£åöA§†±b­ê'KåØeä9Ù¥¹ÒôR›§·h´–¬’:鼚ÇÒªó¢”ê6G’F¦5—(-¨ßjdÆ"5#µVÈšuÀð=êúÕ®ÿ£ï=7´üõìòç;–¿•]¾9½<“Þ¥ì׃cNiÙKΰ¼Æƒ:Ú MÒÛ§7fø0Gz4ôJT«Mš]çsÌ-“íQÙ©ñ¨š´5Ãe§¨mÐÓ®¢^G¯þ#ªåùFÂéö÷<ôõ¾ôîÒ'>Yræ} ·mÈ|öþÊ«ï/ùÃÔ±™}}Ö0=ÕÖ TT¯ª+¿ç¦ô=7•<ñƒÜòu©%ñg´¥íNX—·\ÉE#·=0âÅSZTîR“uAÁÔ!å~TæþŒÎJ³Ê­KûPR¬`{LCÌQþšôó‚ Ôðù>[&æ­‰¤H;ígƶF<9Ì‘‹ù%³™Æ…ÜÍBv±> {îc£SDª©Ì*¡™Hp©q7GÒ¼Cœkx„ý ãfó*9öp*Gi‰KÅ|*rÍ!4nqÚ¹–±! µ¸ Z�7f1‚¿qs0 !GM¡h½4‡{hå}¾ÂŠÔþ ÍÔò6ÓhåªÃ"£ØÃ]A,@àŠ‚ƒséæÿã)š9ÌhJÃÔj;wñ2ë™ÇVt²…/²˜e¼ÍKAý0™vΣ•2ì Œ¡,š¿£Š:zy»¡¡æïÙS!¤yhâW¬ [¾âº~«Âƨ˜±ô!³8¹*F`u]\±ÐEžÃ2ŸiL ŸÓÙÂD® ±ÇyfRUÔFÓÎ!Î  óhe£ÙÊulc ùð(<LQâx8¹Læb2‡!n¦‡ûx“½!¥¦øï*¦ñ&ßd1޲õœT…åaVç0ë¹&0ÄŠÓÑ–@û-²eÇóD˜• ;Á0±Œÿ¦™áts2ï³*à‹Ëª½¡#|“S}¹1ŒCò{¦ó«8ú"k9.IžKbFÆ\™ÌQ®-ø W²žsè!Ë®`iÌgcš"kÈð1Nå£L˜Ùeçs?qç2 Ìâ9ºy€¯<Í`\’-ò ±b qäÇ‘)®¸×¯vê4íÙhÚS~z´px%ÿÄ ‘’ìˆ;5’¢!¦)邼Cü« dz݆˜À5ÜD-ïçÕ ™’´·Þ)d؉%Ì-x=¦ºJMÊêJõMÒ—gìH{³_eÁÆýUòM1ƒ‡'Ýn=k Å®|3ÁáïžÒ «ÚÕƒ/ž™~ü ÷ܘÑÚ¯>¦¦[S­ÁVÓÓò¦” §Ò„.Ûã’3ÓiÇrê¶:RfbÆajRâ; ÖÉ•ª`çNêV•44FkdÒaåÕö7KÓ=(3Ìë•æF²†¥••*”K×ÚÝ£=ºõkNoŸfû¤Úí£SÛkl_àŠ—|s]¾«.óÂìzU9M*úMz¯_<£ê°O£D!gsJÉl 7·_l@i£Ýc Ø5Âô.õjª””Š÷Ù2ÊÞ4u.ª´¹Ó¾Þ?(¼w¨vþüÞµµOž™ûîçÆ t+nnÒÉq]M•¶ÕÚÔ¡<í@ÍÓ·Ú?%züÌ”¨ >î¡ ÿ’62n\tóË5k§%¶Œì³¥Ëc‘lAÍ*³¼_!¦¦ <gbÁ½l‰ËÅœ¹ à¦Ç$cöñ¿c–GÎeÏ®]Rwv¤™+‰’ž¯P“ÕÇôó;ò|ž#L\ïÛ¨O˜P©&+ËuÜH#Ëã²ÑqOÎ&†Q >¶9v…´ßZòd¤‰Ñîesܨ¥„nr$ËšpX¥�óǸ»ˆ<7ËJ¶1!�2ÓŽ‘<+ÂÑ19Hßf&1¢‘ ~3”SÅ䯄ĕ!FîŽÇùld*eC!Ȫh™Ý„`+y7à6‡÷ç“ìb?Ç8-‚æAÙa¦1‹ñÁHZ ÛÐPñwÊÕ©Tq–ZÇj–:îÌÅ¥ì¡À\ªè&dÓÅNó(I¸9:Þô5%á@°pŸÅÁ½Ô‰½!þ|€}œÁ#lÚŠ÷HÑLyèZöbÞ•t…UÐB>à3T‡iéÆ2‘Nf„¸ákØÆ|jØÀ²‚u0P}ËYÇ2R¬`WxŘö¹l 좋xŒžàJ®¤—:HÐËå<²¨‹é‹C'ØÔߣ6ráÑÜÄ¥,¢’ƒ,ãu*¹$§°•ƒÔ°„mÜÀ~®d+Bº¢ã¹_g²*:N<<çÏ1žÍ\M{ÉñxÌ©q¥‘2JEþáâÔ4æ¥H§'œB9ƒdÝëYÎ ùÖÀMß”°œ²ÈCŒes‚“q[­ûø~oð»<?)Ñycdu°ƒ”'Låí¸™1±:sb–dm‰ÛÙÉŒg(®3¦,:ŽŽü ÙœËó‡YŸµrÈ!²´Ä,N[°³ 2)攼Ҽ’4yµI'ÓSWê7IÛjLΘÓcFÁ‹‰ÅÉï< jŒ›úîúMgCwÏû·Œ*ÜuOìž‹â*âbeêF;T"}ÔðœDÁ¦¼’ŒÖœ¦2‡GKõ—!ãRÚGëooÒ‰%å¦ÙÕ«q˜Ø¦F}»(5~’«×Ó¥f”Ì!Ã⺌NûÙH'}`Û Y“ôUIOikQ; :óÞÜØäÞÑ™d¦¼+Ӛ̜R™I–¼?%û·‹’w´»—ó”'ôõÑäð(]ÇŒL;ZeNƒ½û=P®¶Ýi½vÖØ0dÏ(3 J{dFªÏ84¨¥ÌÚ™vî‘¡&¯l¿éY#cÖÔt” }gïÀæ&þóãýûUÉæÕ¦U$´všÀˆŒXA_Öˆ.+âæL~¿ñ3÷Õ>:&®,§¦Ö”^Ãê_}zvôŠÄÎQÝZò&0H_ä‚AoõiŒùa‰/EžÌkMº5áPµÓ‡<°ˆ’„Y‘’¢¬7fu¤Ý ³Üµ:ºç#17E"*IǬˆ™ó ½TÒÉ-¡T3Ÿ]Ì屸lÂâ¬rŽñ\ÄnæGþ‹¦¸y13¢ãKý±lñWÅ%΄)T0•cì+ë13yš c3qÖ0Œ+y™Í4ñ'ŒÔÓäfíæ´‹ÙŒgW†¨ŽEÜÀp„öżL eã úƒ²ŽClda´#Œ/ ¥åzž)QCTÅÀ\Ngó4]A8]Î8¶ß—i¦ÀYÁ}u”VÊ) ÐÔˆ³ÿ¾2pE*UŒ½Àn>NS87Û¸„>¦Dö÷u1õù(}!ù¢ƒ~ÎåC<ÞñKYA«ãD¥}Tp.p “xšfp÷ùf';ø2?v±rÌ#F+×s2¿bjHq<“ÃÅgŽËx‘]¼Á £˜Ã_ÙÁõA?ò †ßóïq‹øGâ>C7ó ïð%²<Çå,ilCa÷6ÈU”­õL ÀʽTrJ¸‰œø¯Ÿ.>ÒÛú©â^e€h 1qï‡6® ¾:fUÒ÷ Ç5“O±•TpiRl¢]Žq7y‡«˜ÄI<•œ0+¦>²˜ñœOO)®©D F^ Ëá“Î- š‘Ç(0›ÝœÂ‡ø+™9y%(þG3Š×yºãÈÝ÷npï*±V+w±ˆ)ÜÏdò'ŽÅVð‚g²ŠûTÞü®Ù´ŸÄÝÊ蘭 3 ~Ä„Ze%f¦λpÈÌáÆT87ç„Fâ”G~ÇÉ%FSñ 5‘ºj?h²`ÀøHç0S{\ec ö®þ¸–I¿=ü¥ózÞ¾ 3l¥=[Ø?<¿y\t×oâ÷,­7µTå ÚÉv§$ÚÕ%”µèm(­±ÌR“\­rÀ®ÉV7˜•T7ÊÆíÊ*ÔïUW"yÌè.Ou[=ÁŒ 5zÓª *ká3SÌï5’’á¢c« Œ3ŠŠFí­ê—Ø‘”<Å®½C3g¯«>¼îâüºÓ'¯kî]wê„u££u3ûוÌÕv›1*o×}ͺDyÃ:T'œÓ®´Û¸”ºÈô´1TdÕŒ¬VÑiTÆì.å …”æ´†Fù¤tZË¥U•Ê”U±{QÍ‹K»W.®Ö6Bul›–¼ª”†ì×~^וìož–Ô7Ü謾¯~SøÚú; iå #Ç{·Ýs1;†Êçf4ì¬éTÈHÑsuÒ„˜tÒœ‚c‘ÉåN.õzÚPäô"Û"ç}Îü”¿D¥‰Y’Î/GÝõ”{¶G^æ-š8;ò‹Üq´éŬãLžâ Nã­ z8ƒ—#ïg­e=x›Sx”­¼Ï×°•IL¤…†+ï¿°€y¼ÃJ:ƒ?õ Îåiú#Íl UœÉQXÎ 7±,Ÿ!}‚>k‰àÆú­O°–n3Døži6²;ˆºñ)êx“:°¾ø '\s,²! 'ÓìàvêNÈ)p„Ý,ã%zÏ ¤¸&»÷mÝT19œrEÁùKáÍÙ4çÅ„°×Šqä!—r?]Ŭ¡á#7Ü<ïÿU®f¤Rï3›÷(ðjð¢1äè`—ÓÁ@ðÓeÙH!Ði/e!os îw|³ò*Ýì£5�€Oç‡YEŠm.\,{¯3’;I!øI|‹<—r˜ü–=ôðjø«¼Ç Næ·ìäåpiú%,àÿD‚ÜÊTgGùtðD·†Ç"漨Û.ŠÔŸRÜßz™ÝÄ_ä5r Ì>ʽ¦’V¶ÒIŽ8©gFPpNg>é4À?3Z¥a_µ.Øu¿A7·0“&–SÅ3ϱ€+y¢df"-¸·ÇH ¿¢ƒ±-\Ë$~Ckäç‘YÎ9ÄlÖ0k¹?,¥>DÄO™iŒ‘4«à–óA¸”4?ᣜCêâx!î̸úH†M|/f^Â91‰7Ù»ÄÉ›<YË…,«µp¸szg",(xˆi1×ì(x´ÄÕ¥¾= 'ç¿ ^œ´%r_äŸcF圔Ui¡+¥>-pïUòÚùY¹åqS³2º«M©£AéQ•CN‹V0"ç&ï¯íÇßíýá÷ËÏ|eÒ³gWìŸÑ5ôÃþèÌÚ÷—4nLÿëäLÎø ÿÀìŒiyU1¯÷šÕ]âPÜ¿§-('²u´–ñº;ßÑ9¢Ag0á°’*ýò9c©*3pÌ{ÃŒhtæA£»TV5¤vÀð”\™K¥JEµºw˜ÙáË ÎϹo˜Ü6g÷Ší6öˆ£ÛÍÉ;¤¶TºÉ¦jÉ-•Rͺèì7¬]YÂŽ2ÓSF–ˆršÕÇ å(‘¥¿^ M}*¬å@̳s”µ'k\$ׯ¬QïIvö«è5:¯bHu·xNgÊPڤ궒QÊÚ ëv¬×ˆBb ºêåôÃ7žœÐǃÑ–¾pS¢ZNCfÌ{±kvE?»&cGBG³êÝ2/”ºeÀ/² MÆÑŸò“˜ #«*”Ty%-‘0'aJÖ;9;¹9©%çhÁ°¸}‘ö˜Í‘ë¸4v\÷ô@A’þ¤QÑÏøÓ?Ä|Y”ðU~Ä\3–çÂ&»¨)]΋´09fû™TtÇ42%dûv)yëxš3øs¸Ç³#fpŒÐpœLå¬ ÌÏM¥·8NN¦ÞŸÐ¢¼{uHÚýŸ§È¤xÝ”žpgƒ 㳬 •1ËY|&sJ0ŸÍ\y*r00Vé%¾Tp7ŸávãH0;nŹ…VÞä£ì¥6é+Ññ=ŸÐhÞν¡ÏÛËç¨äyó`)òÖ“ÁpICÃ37Üü‘ÿW¹ú·Tê([YDŽ)\ÉÛ25´ïÄÙÇéœL*PvŠ[«5ì¡!V£,DÎä˼F–nVÊ{!”î) q-_ãNåuj—¨4ÚÁ«|†ŸPr¾Jþôðîñ™µˆ<ÓÙÃþ„OÑÅ›¬æ§b#üœÂæâämÁRþ+Š WÞ ŽóH±€[ÙAœó¸3:З;YÊãùO¬¯q2ÙâtŽ£aP™b]`Ò>átæñ<|%xàkˆ3±Ü²Œ÷ñ›µ—r&y>ö™G£ãß¶<<ЯS²Îå)>Æ,¶ð¬b7±*�¯ ãõǘ@KÒä‚?tð‰¸ÖÈzjNIFÚ⮋ü•‘ °ŸòȆÈI4±"fvÒ•9D§~ÕéÓüâ+Ìx·HjÌèö j8‡Å1å WÕiɹ"îâbVF9õÜÂÎfñ*?tGÂGòþ™7Ðã—µ†Õ+í1¡LÍ€[9?éì:ÓjΫîKÉuøs‰Æ~¯¢=nxÚ?v¸5þÅßß0:q×÷û³Ùd>]jÏK;íŸ%Ê6ÌhüùÕÿõ£æ›ÿwÿÀc•òq%#¨á€±¥šêÌ™¬¿_e—ª.mšdzU0ªOcµ:­‰œZêHNc‡Ê:uSDš“ Ú5^å)6ŒÔšTVçÛö˜¹Ï°¼ÊRsG©cÜFg-°%§&¥ržÁ!»‡LŒéÊ9zÔC­NmfHb»ÑUÒåúëõ ÓÓ ½Ç°¬cÖ$=ØbBNMJY¥BViFòt1S&šQ&™0¶_~¦£q{(´štHIÒÁa*Ž]©;©¬D]ƒ==Ž´[Xª:g `GSí›ÙOÿ-ö•kK^99ÿ蜆ççžñûhïØ‘ã7ǾúxöúãJ”0¶]iREÖ´áFäMI›ÛåÝ”WéMZRðHέƒ‘ª¼DV,jr^Ìö´öÈ"?‹¤“>š8î¡\?¾$>'fMLKÁ7ÞÛ[×y˜!ê˜BŒ#Is r§SÆÖj6éã[ØÂâIÿ?a÷eçYž{ü·ËôÞG3ÒH£Þ›%K¶qïÜMK¡Å„„ÀIÉ„„ p‚9@б‰1`cÜ›lË–dY²d«Lï}öÌìòž[—²²Ây?hͬ5šýλ×~îç¹ïëú_¿Ÿó.d9‡¸‘qº‹5DÞYXÞƒ´rßæ :ó�\ž }š_³šÕ”ˆö’½QÁf¦ø]q^0¡öÆÏs²´†VÄv:´SÇô²'銜† ¤Èò•a»œbŠ^ÎcŠñÔÛ‘ö9÷SÉÏÂx;ÙÍÓŒðaÊø2CÇØƒœŒò©Ôµ˜ßÐÊ¡˜5Éjy€ù”q÷ón²…¦ü}ÖÔþ–ÙU6•Ê·˜N²Š[y,<…³i`„­LÆÙIYräCYòðݼ{ô¡Ó°¾çÑI' ØPÅi½Äü­rlãa^g} ½B’WÅ-‹N…ç6ŸöͲÿ@çC©‡#™Ï›œwÙ(Ã$g“¦Ÿßãi–Ò~Õ¶àCº‹_’åî`o)Ôð}2®8ô~uŽþz¸™ÕtÐIelà]§ä´WÌûóUüû”“¢˜Û‚¼uˆÿd„Šà¯w*f>ˆdSÜ·<‹¸€†ø,mÜBaÞÆHOø?ʼn˜ÂØ©¨·<=ä—ì ŠÃaßPšó5.£L\6r æZ&sî‰ûXLa¤’ð(«**|8íxäﮌ GVD º,aÞ<vw#d;i²‘ç©eÜiL‰rî«´dDñ¬×s6F^䚘Š)] E¥Ê§l¦­\Y•ùÓº 5X:aá|†t/´xLÉ„ñrÓi/W¹hZIƒ‹SÖ—Ê¥í«”Ì,{¢`cñÜ3ç÷ÍÏ­ÖÝgªØ¼>Ï º¬Øì€êÙD4¹§3–¾½Rg–s#ÇÄgÅjΪ˜RW 6£qJãŒÚU¥µÑ@Bj‹¥êrŽÎª+—Hê.R^fjBÁ<¥Í:'”ôk48§pTO™’Y#¥Šf-ë›VÖ(Sg8&>­ ÈLª~%:Ç,n·jFsV¦ß$S}2‘Ár™Aã¦*U¶Ž›,5ÌYmJ6Ú{HE¿Öº N˜‰©,7vLs—Ù™jÓÙÈL¡ú)»ÊLX:­·^ÁYÓ’¥ÚŒÄ&åbZKfŸm›Y3zû~Ôeü¦q*/8cîªûƯzªàë ú·e'=?àWõ•Ægü(åÆY3 à $'¼saNÄÚ¸šœÿéࢸ+"oL›•ŒÛi¥€÷° g$¡ŸÇs¾Ì'›íš²1¦+Rì¡“îþlt*~¡YÁÕÞûa{qOÎQhçŸÍyyG}:§”ò¢ö¸ó³þ3¬âRö±“å¤KlÉ8sNän:ˆÑÂ…JV;�� �IDAT`Ç8AOTÊGÁ-áóˆÑQF™áŽÐP)eW¨Uçž¶¨¾Pœ_.a-4q%±ˆ,b6wÊ&ôöÿ½<hµ§"Ÿ¿Ã Rÿü}ŧ-³ß¤%€£ÞÍ7y5P–³’bJ‚L¯•o±˜Eœd16ÐÆr:©¢-p{9+akä8ϳ˜ 55ko½ó‚ÿ©\-J¥^å Z(a/raP= ê¸ÙèT7sN§Ú| t‡N[y¯§‹×¸‚Š —k h¬Û8‹6s.qœCARx+_ ϵ1 “ã¡Læ¯ÞÌ}¨à}œÁØi™•Ô„àzæÂMæóв I0E—^Ëjža’KYð$ßeœC\Î:Vpϱœnn¢3l¬„COþZd~l J˵A…ÑE-gqŒ²°Í© ¬ÉƒNñg˜ ˜wsˆ_0ÃÊãÖ1˜Š!èz 溄Dt*´þ§á¼ÿr°¯àæ {|8vêÉ<ËuEæ•Û4{ ‹ÙÌ–s/òõ$"_MúLÎßF¦™S«z˧ž÷LÞbu~Ìò¸ýi5<óþÈKÑÙcñ G}{Öƒ·xu-çPÊâF3Ó¢è”è¶š·Â ¡‚»nLû߬‰™ÏI™È³›1w$-Ë· ¬Ž[1ãñœ…Ešr:j'ÕØݺ+]üµÂž›ëu-t~FG£¦2#sú Íf,)uqÕ;YXüñ¦ ‹5Lê+×ÑcûŒ3–yæ-Œ+í¹haú­QëŠ7š›Ô<']äèéa…ÝjÓ‘õ‘ÂŒé9¥3T(M(j1P`U·šBuÓJÓ’mã†tŽ©M˜®5½ÇæY‡ÇUÄ|'ã÷–/6;¦¶P¢Z:¦<#Û¡vÂt¿ºÅRÊÓæ¥•˜j6Ql.’¨’nÑW²ÚlFјö¥†G|©Ì55FŽÙ<çH’7,ÌêZãp)G%f̦4*ŠLE¾ÓçÚa55ÊúuDjKÔV*J)È*ÞæD‰tƒÊRÙI‰¬“IÉÑ*ÍÓ+ÆWt—Ì«=ÖÞå;Ó“<·~Ÿ«*žZ¶l6qÂLZ%'¨žõuÊ㮌¤b⥖M‹r§ºg1…‘“ Ëy"g;#‘br‘>îÏjcŒü<çáȺYTâS¾ÉúX—çßg׃,:uŒø§û¯¶ùi¯ ôý¬©íù¾ÎQÖ“äMÖò`Laä÷)åEFéâr~Mëœ9Õ1×G~É)v…QMŠõ¡Uþ*¯q;ÿÖ·“\ÀϹJ–ñ&wÒÒ~ßÁ†Ó–µÊÿ¶/`YžßæÇÞC¬áMú™¦„PÄâ°¬- ‘îùŒ‹ºHq€FÎàD˜9½Ž)¶‡ÞÝ8ulá JHqª`ýÌK*b9»&Ió ^JCàÆë\gÅ‹NÅEnc[MÍ‘[ï¼ü*WßJ¥~— ÏqŒ= †ŒÝw†oߎ¢oäJp;Ÿe7Ûù·³—›B«mˆ+y–a:•wGÏð×<Þp€˜Ï¯BÄâlæ×á™â÷ùVãÞCw˜þ:Ìñ¾ÊÜLsïÊcg9ÀHp/å2”qpœiz¹‹-lã@øÍ[Ðs.ß hù·ø þÉÔË(s rì´€Î|�Á'˜a/“Ámž'e½È¾Ï ¾Ä#ùÐËÛXÈ(—†g8Îyü5?ã�{éãzvPË‘¸‡ÞÁ׃ÔçÓ§r7”²™‡¨âi2|×IRî éÏû¸"rvÆ9¿á=t„<žw°™ŸÓÌg#?ä(Í\ù¶'þÓ »åzþ[#±´/ñ<Ñ—,¿ þážØ?Þ–ëýiÌ«-Ÿ3›%ÆÔ§OE=Î&²ƒ«ò™UI[X4*ù¿œéŠ4ñÛ3~’ôG9s‰=‘û²6{’³ÕZþþìSOdº3®<Ô²óüþ‰úŒ9ßɘ·XáámsüÁÌGÙøÂ9ƒ…IÝ5}þé©tVÍ´ši‹§Ì_¡gžÉÃÚf­®×œóéiï®S<®¡HÁã f*ëM4zž7ŽÈX»Ô[âæ)hVPej›»œÙcQ£™z3åÒ*›M6éÚgÙåvìP’öí šÇµŒ©oQ·Qל¢1 6y=c¼ÛhJk£á å'•Ï7Z¢¸Ó¢³¼2®ºÙàrÇR*zµÉŽiXfì˜ùÃ*«5™>éx\{·ŸŒùÀ´/–[6¦­Àá ²où·“ά˜‹Es±Â¬XÂÛTFêûΩ›ôÏš?­¨‘qÕ3’³êzÓ9lÞ¬‰œµm†g”ŒMµÖnzr¼¼xá®mýÎ7‘.xãúhç/gÇš,°œÆH¬ÀÆœÍU.)p¬FrÊ_L¸0&›t^NÇju“æ•[²&:%ÝÆ9A <œ°!ò³¸{ãf"9§|‘;ØìqÏ‹úGù„X¯Ýëgçøåg&,?dïµü9õü{Îý4>6ñzYÀîÈ9¬â»áÓb†?äÌ<b&?úM()޼ÐGèã:jè‰ /å…ãIWD6²„ÒÁm<Èa63În60M³žÓy®DO°cN‘b2ðZ;Ãz˜ç»þ<ôo&8ÁáJ9@†‘�1@:U‘÷ÒF7Ï0»y!ŒÞsœ–p'Û8ŸÒP5ó4‰KVÇünäÉÀaXË»¹ƒ þ“Àk/&Ÿör(²û´åñ…šš›o½sÍÿT®~žJý‚½Ì¦ý3Ì+TðYfÃi±óÖÅ|Oó8û Ôó|rã+Øé”h,¸áÊùUà8ãÏÒJ ÛØOö¿†+ãw¹€7x‘Müs˜“5s‚ y‹^ä=¼Êö†˜ãað˜'Ì~‹4ïá�C|2(oæ_) ³Ä†|¼aÌRþ)\ÖÑÍ-äx†$£¤¹†W¹“L•‹ ß£.°‹Ér Ûò1fx€'˜ã–àûC¶±Ž×øÎæéàk|ÊðŠ‹xš~žãÇŒ Ä—³9¤.ßh±qÒ`x/>ŵÜA;9ÌMTž†§z,ò󜛘â8_ä1&éá<nb†nJh£v^ç Y}ƒ7c&–† ë»(æC–¿èþÑÕMϲ¶Ðߎz”ðÍI¿ÉØÈ ¾ÌÖR7füqÒgcfb#{3®uAL"éìÈgøý˜)&(+wxÖY…n#Šk|«ÐÇ‹,I*›ñJÅ÷_žýèŠä3ë<ÿg­}Ñhö‰ŒÝI×±¢õ ãuÕ_¸²ì¿ôµÜŸžÈ&¦ã\X4™LúÌb‹²Fûµ5HõZV#] Öàœ1¥ÃŽDªÌ (+ì2Û+JØÔ«êGrŽÕª:)¶\פ\ÙŒÄK¶çŒ®ðækêZ˜S^¤dFq»× L?ç¬óí´:£¹ÁÀ|ãÝæÇ•œ0¾Å«/H.V¾XzÜÉ“º›Ä漑QM©;bÙ¬ñFƒ‘â9ãUÞ(RzT]‘ñŒcõÇÕ–šW¯¦Ô3’Å6ŒÙ0«z\GcU>>­-¶îîèÑO$LJs¯¯9ßäç[“½À“'¬.V]ääŒÎ¤Ú*sC¢)_ÊšZjUÊ_VJ§ý²OѰc“Þ;þRSæÚCñÚhÒßÄÿ"=NΞ_àK]îHÛÍ8ÙœsíŒ]åê&tglL¯U_(>mlÐüHÙ´ød«÷n”Ki*2÷7i÷ñâ ërj“>–õRäUî*”Îy0éæœÙÚçO;¼Ðïýßtß=>Ÿˆ=ý™¬—`ðJÑ<s=1S<Å{y-tøÿ•ù\3ô9øߣœå,äÞÿÑL?ûyƒ‘§"ý|Vºúùg¼ÌG8À×™åÑœc|'ÂŒçÒ€-ý$Õ!»n!»é`'/0J+è"¼.ßgŠ&Ö°! á†OƒÛ>ªÑ Y>ȳœ¤ŸÈxŠ?àM‘¥‘ïñvóa^äUnã¹ Eþ!r¯›ÿàéÐÇjâNöòJd_d:ïªæœ0»‡cœB,ó$J‘"Á|§Ö¨±šš o½síÿ—j±0TšUìá}t±ˆc £<é‰NÝÍ`��¿‡Ï³“.æ³ Þì Ã_ËŽrùiùî+ùßbŠ’Ó¶XJŠ 8A?‡y…ùáÆ®à¾É¹dÙÈwƒ"å¿_9vûÞ0ƒ1ɘ¥tÆ-N)|Š(f/mŒ²;áƒì掘’˜G¸…¯s)´3Boˆa|é4¢ÒéW^ƒžæ"ê@ ûh§Œß¡3(Kƒßû¶ «}†?¡‰¤žZ:{‰ cÙÌ-!¨æÚ@ƺ—O³—?£Âwâ Ê8ƒƒ¡ößÀþž¯Ü[9‹8mŒp‚{iᬢ‡ª˜CqE<È|›Ê©´âhlQWlÞÆ’½çFš¢[·áRëY÷ºïwx í±Yæ˜S’Sæ|”/ÑsV̹U^JiËùÍÜ÷±È’¸ª˜\Ö×¹¨À,Ó‘*žßäC§¬š¥Yß%WèHL¼Äà¬Ì†g§SŸHµ7Gç?4òÊ%󦙭4›»x"ýÐgRSmÏ^1i&ñÀ­ÑTq|SGî’Gwl){WNALC³xµÌ˜’©S¼íL¤ ÄH­ÊbÉÓ%:‹”(+'­t³CG-ªU<¢¡Ð‘r…Ëõ´´SyÚð%öíµ8ebXq¿Æ*¹&ýƒ^¡;më|#Ì(9)•SßlºWs‰’ñ MÓJ'TV)µ©Àt±án;¦ìT¨[¥§@æ˜öJŸ]`ó<Øî`¯3 tŽªU7O÷¤Ê”Áùú«Dgxõ¨ËˬHÈNK4ö§æ¾q}ËëWΩœ’,78i^ò"—Γi7[ä¸DBQ£mÅ6×TeUF_‹ËãÎÓ2îò:WdŸÎŒÝ¾Óå ³ƒEñLM_C£UvÄý,æ¬HuÜù‘þ˜DÚê´áE–ô̬#s§ÚqçL¨>)J)›±3버k|+eIÎHܯ³§Vç"^®Ñ”r(òRÌ;=öG¾ñ°/¯Ö´Ú?ÔùõßÚ’õz¡Í‰Ï÷g§~íØ@²H õ”ÓÊ`˜ì¤&ç߈ó&3ác•ÏrüE ä¼Äü-îàrþ–»!ŠWsØÂ<Ϲ\Å‘àÏ 6ÐW8ƹ‹œÉuŒ¯jEXdæqX/âX@ó í[žÌÐбíd‚ …³y˜}Ò[Í ŠYà &Y ùd¥aZhã'õÚÂf—…FåŒQHOôò~¾ñ_áÃì  óCD{ɯØÊTMMîÖ;¯úÿ–«Z8ÌA¶QÉNÞÍw‚½k2ØióA Bô¸ƒ.H6vQ\/ç†àÁŠHRyÚdo1{9F=qÆ)c eÜÉtóó™`†óñ:´¦-€ôs§y&©ä’@¾ØÌ›ÔRH-}1Õ1kt‡›, š«¨‹Lp‰Ø©õ/ó<“Nuóå 3ŽÕ«I2I-+y… <—»ØÊB.e?¼—¸”_=ëÞä"^àyšÈñ>–rSÐÜÆ/¹$@@ò'³ËXÏÎgåü&ë#<M/—ÓK%s¬£”‹-ß?¿âQ¶r'ƒfš­1ÓqŸˆ´³‚I:YI¡]/Çþ|}ì“Û ox(ûÞ¹²cªbªúUµÛyÀç¶0O´Ëù9›©¢ŠW¹–/Æ,¦}ZËbb —ÖŸ˜«öH¥e“¶P]à¡*‰i=LL霵*®¤ÌYçfι3§iNrn¼/ùÀ²‰'7êxqD†=s×dÿïßûú{ã_øãHg™ã bÿñw~1ºþ—M<¹²y*™3•59m|@ÅbÊj°8æ‡}æm2“±;mä¤FšR*bfÇTËNI jÈ2£¾@ÁˆºQ••ÆKôegÕÌ—ÊɤÍ[çP$>mÝ!•eJV;>¢&+¢9)Ö­§ß‘9cÃ6Ådû•+^k_ŒHvÌÊ”í TšVÕc¤Ëët¬·½Ë¼NóûæÏ(¯2žÒT%W 1+¶Ä‘¸Â …ÿºUl—ÕÕ¦*8ºÄ±ãÖ–K”ŠøÊ°µÒµÚf&l«4rBmÜôŒX3½r­¦ËLô¨Ì˜®sf§'sJsªfåjUÏÚ›y*Óúìïf.~¾víkc£­é¾BÖTÛ7%ž°>¦52VjAº¬¢:¯ ªl2=k0#ÖªuÂp\ÏÕu¦F<]­´ÒÌ´(®ªQWÖ5sö%¼3:5ú]Ã’i3,Љ™‰ò‘ð\{`QüÍ呈LäÉ­Gã r™'.3¶:òEªâ×ìçº�?»„IîÚ]´RÄ(«hˆ™W9ÄúÐ…ê ô™&žãajáŒ@¬ØÉßð8éͳ§Âºš_G1õLòsXLmláWLQ@M°å£°òûæEläÐihóüP|)L2Ã<¶ÐÀQ6…&^þ|ö]²–xœ`Cº˜=L?ȼYY>¤™ W8åEYÀ�¿a—xw\ÞJW~AÞÂ0gò"]ùsMMË­w^øÛËÕyÔRÂ8å_Éž`Î9 V´2À€÷’8íø™¯dy ô4 .aìaŽå!í>b¨ne'¯1ŸëÂÄ(O{œ ƒsyžìfšÈ,û¸”&žgeœäóg%½\ÍkD,¦„þ01åݼFa$Æ+‘…ôr%?álޱŸ3‚Ñê*6ñ {¨d'h=­ã7ÅÉÀéÈÏ0/ Á]ã¡s˜ ª›9v³ˆï±‘žçjFèæV~B‚^MÚ<c°„6ÚYÌC¼‡ßð‹9˜ð¾È;ØÆ<rœÍÑ&ïŸ2ÁaVñF�ÝE ÒÈáp“oò­ÜœgÏÇlN(ŒÔ&}2ç¨óú£m;í_Å*ø>/S*³Éhó¢ôW¾—{r½/áÙ Ï5$ž»Ús×Ǽ+aUtj(]Ó”0ù{>ÀcÞ·5ç-Ú’¶F¦#I fuä4±;kǬ¦¤m‘ÖÈ\ÚjÒ3$Ý5H®ÎSÇ©õrdUJ]ÂÚœÉÔ‰gë‡Û«”OZš¸¬3¶q:úî~°Q¶›‰èŸþeæŒ^ž_ñâ‚ä­ÏgŸjëî¯NªI©KÎ*lRÒ=’ikRZæé,ÏY“,4Ù©2'3åÍ3 M)¨5ÙaQ¡\ƒžnuÕ²s¾žuf›ÑõMºJ$:”Nûf³Õ3Êç™i0:¡"#›Q¸Þ¾Q• íé³°LS‘™U…ʇÔåÄZR`nZ?o&­Ì*+ÓWî'IýÎ\¥ã¸¦‰ µ%&¦JjìSvŽc*‡õ¨,©Õ?a]¡99‰qÕ•N,P1ª~B¬ÚX½¶´â"™ig/s¢SIÎପ´¯tF‹¢˜ò.#“*KퟧfH[©ªÍsŽY’µ2®&šiÉ>wE¦kqêƒ?p×}u?¾zR²MyBý¤xR¼ÄHdJ_Ÿñr«ëć<±F|Üö‰˜(®rÖhJmÌkY³jrúǼéÌØ© /©)g”§X˹¨\,©>m!?yWšHmÎA¾Ÿ½ª=“{Â¯ß A©ïdûÂÖ0â›°vúØÊ™ù°`vÓÓÆùüŠ¡`Å©g»¹ XÄ÷™#Cñ@‰ÝÌküpv˜?š‡]§Q'¶²4SÈ�ïf_ ¸Ï¶ööÑ@þJ2ˇHòd0f-¡–{y'b;7ñN~Í*v“ä¬ÇzÂ3á•äjÖñ4£ÜÎ\K/M<B7gó<½\ÁA?À»x'¯ÒN7·³q62Îði±dM͉ßÏøT*U—·³„Vé›gOÐæ¯Ñ&yá3Ûƒ•õòð:)ã1A5= ðÊ1Ébnäù�¬+d Wñ(ǃ voȬæ-Ò,壠/”· Žsy\*îÏ#/ÒÁa*¹ƒC¼Èx€òµp†|Ô¬œšÅŒ2À�c´ð+C@žùŸ§CeI…AåŸÖÌÄ…Á:þ6¥âDà9ækÕœäv^cˆcü ÿÀLòy•n ‚8'?½‘«ÙÆ ö_×Ã<ÊÓ´òsR\ãRþÌ)HàO9ÌÙ<Á¾Y¿a~Ü÷"¿ä) ¹˜jºy>.–°5çî�ùüñKz#ƒü"rŸe·ùð_úΫ¦óû©ãà Ñ({–¶u®xÒG›=±5–~RAÎ4"…þ¹Ö5U$4Ìø1khˆ9+æÇœÅªÈÚ¤‘ÏÇÝ“³×ç4fuEþ:íOg•19™3Wlq±{³ÎM¸1k¤Át¡ãæGª²~2çάƘ]sZ³j¶Î”ôW×6Žî½S&;ÿ‹×æ^¯iÉ.Y"–T5aéìŸ}'÷µ•¦'2“¹è‰N®™È4Í(¯7<ëósÎr<®®@aÎòV“ †ªÄö[[cªXºMG‹‘å:‡­^îĬòr3£¦¶ëœTÙ¦#iå˜%Åær —é)`µ·ÆWR ´JjŸµ‘ظº*“»´©K[^£¤\ªLjTUµ™˜XN¢AçŽJ‹Zħ5dݱÆ¥65híq¼YÉ[²Ìf|zÌö¤êJ‡»UÇÕ÷ܰ§Gmï“vé!'†,mÒ·P÷ ý&'­¥ÆÜ¸‘*'-R´PÏIí“*JD[tW[6jK¹]õf&tN)˜³ ¦VK³I:›ÕÖÊd-Þàp\,=ÜÛµ|ê± 2÷ÞUöƒõytNQ¤w™¹^é)™Œ#9[æÄG<F˘öqÕ‘ÚJµi_öŽH"rq­Eqÿ>{Êç´!g"ò)Z"¥AÌö-¸2ã2êWÙ2(ó›œ- ‹#Vàs¹Í_Vx›—ú Ü™ó0üˆ^¾J_°Ž!âZår7{Ÿâ:~L+·ðBàæ °…—X¤¹%>zTבe_ åN˃›WûýÓfÛ‡ø{içåÀŸÍÇVäó±z¹ªÿjšàXËFøž ¼ü^y„c\ÇYüŒñ?§8äIŽòG™e;Kø!1Î!âe6‡Óá#ì~’6&¸˜û‚¨û>À½Ô_ ÉqfØLŽ=ÜÌël§™ý55U¿q;Æ+ì㺠˜!Åm ŸT‡¹‡‡y‚)ÞºIF© ù’cŒÒÊ],åz~B 3<ÊŸ°ˆGyŽÝ,ç.à}|$ïc'×ÐÍçø ?ç\¸ŒWx?“”GGzVQÂAÅ0M…äx×B GG²}>ëx‹y“Ƕåˆßf;Û8É=œæ� äÂqj^ #.‚Æüï§’«h%ÃAàþ<_ ›W(¦š ¥I?Ž<Ç7B`)ßM:'g×òM†i}È-!¸”{(eo°³¹Žg©e‚õ9/G #ûƒÜèz¦©æ÷x&ᾌ_…]Ò-!<íU^à³ì 2éŠÈ¨áv³í6¯ðÚ |:¤<Ï3 >âüãÒÉÄ#_]ÉcIÏf]Ã6”fûîŸrhBeÆ|ÎÎ7 jL&Ü9ç,Ž)Ïy‘›¶xÇ€ö¬%ˆY_ìG91™„ÖÈ1êÒ>=§"g$§œ¿KëšQ^cÁ”£Å.ÏúaÎð2+KKc[¾5±à‘Ü÷>úz¡´þ®³3³«G¤“Vt«.Õʵ~ï‚¡—>U|ÏGæ¾ôã¢ÿý•ñßÕ6òVêY÷ÌyGΙ­J'äæ;8ßð´Š´¨GS}Úâr=êæ$z´¯pð µI¹ÕÞSÝïÍ6ñYƒuŽ”©]ìøa‹I4˜TqÌ‚Z©”ø2'ËLš‹ÌÆÍöiÞdò¸öOèî5¥Ž:ƒÆÛLÖPÓ§¥Ød…‚”²*WDâÅbc -Ié«T¿Ö`NkÊâõ††Ô6›ØèÐ2åÇ}(££Žµz‹Í¯73¢äUK×ë)×°ØÉ„¢Hl­É~#EÊÇU7-S:ÃI {,_ç¥jFåúmØ(3anÔËiÝ ,j4R%6§¨XºÏ›',6PìDzº)3Ú”ùÓoÍÝ}gšŒ 6Úy&«¥Ýü …9ŸÌÊY™±%î†rï7I[Ö—#Ûs¾=¡{V–ëò!1ñÈn^‹¹"(i×%ýCNUd"R0àÂbËç[3î;YŸ'›sŽÍK¾ê¥÷å|Žãl纜J+ÍÏ_Æ»¨KøpÌêÈòr|œü" âv ô_ñPL*®6ò�EÔ‡Œ’¯˜EðWû­áPux@W’äR~Êpo˧&ý ?!ÃÅ!Ùg õÅþöÕÌ4„ü¿¼÷ôù4ƒÃÄh#Ã.ÞàRx8Á(M4ÑÆaÜpˆû)çJö0ÂÍûicŽfÊ‚4±‡Â@¤+ùøi¹‹ ý}1ÿÈ#]°Ÿfvñ· QËpMMò·”«ñTj˜+˜Ï“áxÔRása˜9VI§7oæÌ|#!S²‘ìg00÷þ‰Z¸3¨Jfi°(í:È|¡Î“¦v[W8çàbz)â1ÖòKšYy‰ëøç×5Þ¿«ƒp%ɶÓнùmÅ[áÇz¹„YªI±7¹”:æó40Á†²žÉ >xûÏçP€%oå âAÞRò'ßR6ÒÇ®ö‹m9Û¸7Ìl³ù¶j΃,æ^j¸†;ØÏ<²4±”û(#ÇÃAkþ×ÇÜ'ò`\E¤ƒÕtQÊOy_¡‚oЛSÖÄMEޓй=fOsˆïÈÙÉìôVÂk+x!®9r’wĽ‹„úçüõ£>zG¤“£ +\7³é›®û•˾¡í*UMŽMäM¸6ælÏX:ëÜœ0ÀÒ©œÞ‡* ÌX^ª©RY©Ûg]Vfs$›qOÌš¸Ûy-f0n=WUÙ”0oHªÐòFéRgE½Ú{鉑m¿L\:X¹13;-Kɱ�� �IDAT°0öÜ{S‘óÒ^›±y©©¤é”cE^>ª$±$S»âµ‰ºTã_üQëþù“~4á’RKª˜U’–.²cÖä1W9>©bN|ÚÑŽ&3ªã*'TŽ*,‘7©Ê(˜²¶Âè€Ö%æz4œ4[ª(&·HÇë·ÔÒ«fÊà¬y½ŠgÍU™i2Ô¥¡XG›ʦ”Ï©é³ò¨yi¥Ë›R<g:§$¦c½Î>uFOJ¥”øÁŒ%5Ëe{ͯ16*S {Èæ˜hžZ#r‘òI ¹ åÅíÞ|IÛ´L±xFzLE§³VÅ §•ˆF©ôL›Âq«)3™Ê¨¯•["R]-Ó«;匆M'4§µf=Q­ºDé°Â ¹~+v÷G#­5fsšröÆÒ<¢9¦!¦!ÒÙL'eZ4óp‘yiו™LÛ”°"n,2Uè‚Bûæ<ÉBþ"!yŽs(a.2‚ÂësFì‰ÜË_r›)|ÙKõÜNN/p w³”¸œ“4ñxä§‘ÝÜÉ!–yÂzhÊØþ<¼<áú¸+sžåvú‰è¢„ˆ ¹>¨ë˜ ‰òŸà0#¼+¨6²ɶ˜çˆ1Â*„¼Ù<ãkì¼¥·¯-ô‡Rü¹çg41Ì,—…¯?È7©dÏi¿a:ÄçSdC Ø>ÎûÙΞ€›Êcæ¿Äy±•ƒ¬¥&ÚŽs44äÞ^`/û¸3ä?,äº8QSSó[ÊÕÑTj/3ydÝ\ÌÀJõÿ·Zun(Ȳ? ›‚~ýí:—‡‘÷'üe¤—$êÝ:i½dcw3«ØEíœàBã.R5'¦†ýA§~5ÐÄûØÄ®�‹$S\Lk _ =üa ëçÏgñ$­ÜâŒçØX–A{ÓÉ9A›ðöµ™Êà¨(c„sƒ<ÿNÌ‘ã&Þ¢•oSÎIžçN4KÌz<§›CÔSÈù¼ÌVú¹‚~JšeäXÏ÷(àwi!Å8gSÎá˜á˜žÈÃ1ë"ýœÃCT²!éƒ1ó"‡‚:6Íã´ÅÜùgnˆ¹‡ —D®ç^¶p Ëx%hF*b‘Õì‹9ŸùþæKšR¾¿6îB*s^™Y{Ò7~¬ôLŸYgSÊ’!7wèˆrý‘’ÈžÈÿávÆ\LThqÖpÖ‹ YƒqÅ#~³=a¶BqÆ™9cq¹¬¢¤ODæ15'—’ª•™1>caì²gfÏìÎeKsƒÅ¥·¸æŸûÅ™é’é4 »¯Y2£­ÃT•‚¶—õ•=Xõ實»—–xyÚ†aó'ÔŒ);ßsi²–f¬jÕSmªÝÉiåµ&jĦ$W$9OÏû–zs¯¶¬òbãYEcªjõ7˜R¹ÀÉIÉ„²Q5+™R—KëïUUfdÚðbêdéÞcYV²ÕÑ”¦%ÞÐXi¤ß\F.«pRѸÖ1U-ºdGµ$¥(˜3/­¦ÜÆzEqñ Ó)É2ýoI'—‰«’™Ó5T(Q&QPe:&‘‘2X£0R:ßPVE•ãF+Œ/01l^½þcª2Ž•Û>"›ÐP¬,)6¨fZoƒÉ9É ©BG'$Ò·3;Yl4³±XQÆHZþGüî›"có”OˆÕy1¦iÎ6Ò1ý4D§â6欞ӚÔ3j6g¨È3sJc"¶SSlºÒø¤.~Zç¼)?¤…>¶'=[¢aÎQ¦bž‹¬£+á åj›‡îöÒó\FIÀ+Ôò0Û¨ À%1 q×ä7^ÜAw0 þ>9ÆÉñNš(#ùuN;­õ^ÃOCþQCO,O$šssBS$b˜ûù&x•ªj=)渔ǂ8 #˜Yóí¾añ9ÊáÙôRÎuÜÍ.fƒõj/3‰SÉRöÙIn¡‰l¯±(E)ͱ ³_O'o²—QžÎ;µÉ±_ŒMáß·8Ä•¼–ú·HPCWøú Êß^®’©Ô†h jæ*j‚䯊»8›‘0'\ÉN0Êï3ªR®gS•¯X™yþtÂCc!·³–Ë‚.%B¯çÝ\Î+¬â™¤Ê™à×Aèq„m!Óe=ï ¡ï)žârv±†aöŸ–Q’W£Žq'=ô„2°‹sXÁ¯â–Å}&²ƒ?ä'ùó~Òç"3J'Ç8všN4ç[™` ëaŒA2BŠfø{vq9/p-¯p5S!À~R&#±9ë#ße%lä\îŽÛSyˆëø�áƒ,‰ÌÇ9ÁI–qœ&J#'ÙŸð¡œMYÂa^‹Tñ�ãá;ŠN©çWò:U|˜&èâ Õ¼›sÙ ‘û¸’¢ÈÌøÊÉþs®÷9ú#g˜÷ÿkÌWøÑQƒ½^¾Ý›M†ÊýÎ^½.9Yšó1–²‚¶H'ÓFs&¸Š5¥Æ}.ã¸lZjÎ_e”å$#MÔGzãê"] ËãjãšÎõÒ[g§¦.úxË7Κ}r×úׯﰪL2kn•ᣚÚL$,Ó׬dΪiíõˆÌVÕjÒ6çð ‡­Xg ÆtZñ°ƒÚ{ͯ0QeºGË1ícjÛ,qrμ~-cªÆ!Yk²XÑqK5M™›Ë©)—ÊH.ÔÑgE£¡jƒê ¿nݘšR±6sN®fBe½Á}Ö-Ò×`l¿# vjJ˜™'5¤t›ýYEí:#‡{¥k55-‘\ëÐ~Í3Ê&”¶;Ñ£úB/i›Ô:¦°ÁdJY¨Ï¿ç¬j7>­tHI—Švƒí†ŠUÖB¼]GŒQµ“šWê9¢¾RYÖ¢å%V/Ö5£ºß¯"™6™“þ¥Æ¶œªY׺%#>xããéù‰èÝ$þ½ÙL²P¶ÎܤCÙWj¢îÊÈ£ÓŽf|§Á‡†•,å|5u*÷LŠš4§µgDS# ø×9»ãnËz+¡=Ò˜u(ãœÌ©^ÅK\žÓÅ• çôDbó•k™µ2¦>§•Zî<s]bóXTØå¥«øYÌm K#£¬àg,fŠŽ¼Œ;f„9Jú_9oòcæñQ°—ż#lÝʸ:˜NŽp¼ÉMôÐE‚kbïc­qþ–~þ†e—SȨlHÀÈsŽs F§ÈyðR~þ*òúûØM 1vwžCtcXW’‰< ¼‡Ãj6ÇQ^ Àñ}L3?„¿_ÉÓ,£iVPB;;9ȱ09I/9¦8‹½Tr3Ç$Ã(k• mUüÿö6â·—«o¦Rù´ã“\êç®hú½¼zšÖ~–N® ƒrnäGù:÷ó>ð:õ¡wySÊ}¹S–Þgy‘çèä‚PT"f8@üÌ0G™ÎyŽa¢ø‘ò'dxŒg¹!8®dçq€‡™á.–p$(&ˆ¸†#¼‹UAìÞÌý‘Zb,¡ˆ<GAÎþ!òöõÑÀºíâ÷¨äáÔx2¶ëÙÏþ’7é {‡=|_1HC`aœÏ_{ÓE~N%ïç$Õyëq¤:ò8W³’Û  üÛ8Ä AÀSøÇG¸œï&}:§!òwì£G#—ñí¼“ ¨a\Ï$èb3Ÿ¦œÆ-ÉkXcþ<銜Qž¥ŸÇhd:Y»5ºæ¹Üß÷ñ©¸2þPªCìRw?áÿñußQvÞå¹÷?»Mï½I3êÝ*®²l¹WllpƒƒÄ‡“ä@8IH²²!$¤¼œ„Л ƒcᎋÀ¶,ËVïm¤é}OÙ³ëóþ±õx)ç}Ã^ó‡Öš­Ùefß÷ó»ïëú^}ö(¼iöY§Z=:íùm…É x¨Ë%ÖŒúГ‘åﺼwFkŽy.ŸÒSáp%Õ6Íì°|Vª[#'S"_₼‘ŒOžõ\vÕÚhOEê¹KÓ¹«Õ·ê;î̼þ5Ò½–Rµf’Zg-Îik5¸ÑÎR™=Ú&dõ4(?cQ‰XAy‰Ù-v±åŒS´N9Q:¬f‰££"e‚ݾÐ`sT,¦Ðd:jþu&:Š™Ò‘²»Js½ÉÇ,Êz1éù•š&Õ«i6Ñ£¿Î쌪œ2§õœ°xZþ »ŽYQo¦ÙhJénãe³e=N ëlf©à€îq­³bÝú÷Hhí2?¡iZÉa‹jL·IöÛ§³\üBï¤\Q¦ú¡UÒmg4ŸÒ×z\<ctJ㨣yËŒ 2fÁ%vïÒ1¥/¯rBi™Dôœ R¦Fô4Ú4¢kÞ‚F« Ÿõ½Ü©?ðž_$ž¿»ð—ŸO<}{z~´¤n,õâÿÞð™ß®QSjõ”u \Ø+SHj⚼ḛ$ÊuŽùL»«g)øM6ðLÄW£Ö<Wp ኜDÄ@̳ W{OµÂعlš5|"°:inVmÄ¢œgøK¹2bw lú¼’ÞXÍSÔ^¤)~›M ÐÉjÞ ãOï(ø.Ï0ÈÝ<Ç×Ã1W±¶ÛR ñȹìõbìÑ:n+f&pŠ^Öò5îâ~@”ïÑÍÖðS"\FŒ#<ÂÅ\ÍÕì`2°0°–f¾E/ýäy•iz¹‘:^¡Å¼Êƒì$ :Ì3Š“a„ÃáQ¯7Ü-aöÓlËW Š:Î4å!xédHç)ò¢~f5uj}|‚ÕaÔÔU,ãI^á&âñÐÚÔ¢ë?À«<Æ×œCÂÆÈÿêvõ\*UÍÅá)g-¿ +QÑfÜÌ(ídÂŒöÃìc>4—!Ëazá|”E|š^Ž®âU²!ç±—Njd)´r-CÌ„¡Èù7òþ¢Æ1î×Wñ8JÙÀ"þ–;¨à Þf‡)cŒ—ÙǵüaD$|ûò6 çÂsßdš Q÷D¬ <ÑV°šKØq^»ÚÏe<É5\Á3È1äs|5|æEšT]¤xl§œjžñíáŠë;|ð ªB]å^âMî ÑßN-vÑÍf–Æm ÎQ6~—WÂXÒgù‚Wß§À#|3æãÜK„¯ÑÎ+ìâ6s=‹ØÑÓø)“<IYµ›+|0ããÁ  K¾&xÑä½ÜÅËEXáÉ'Ü·Ù ¯5Z—Õ—ò_ixõÉdT¿×Ù,óIOÿšÉÙž´!c ${žˆ mZ}‰ oYÂ㥖ædç¼\b˼iÿVfm`~ÞLƒšœ‰¼›sFˆ²µ`uüøõ¹Ë^ªm;”Ý×2kaJ]Κr‹[<_«¾ÆÄ Ñ´ÖÙÇŽ©:$~ÄR•xß¼ ¡|“ý ¢ÓúZhÝhD[Dm…HÖ±„ŸÍjmsíˆEe’•f«¤NXc&*Úm FvVõ„æy35rñ.Îxy•ûG4×Hî3Ó¤bVUB®Õp£©!­mkM•ˆOª_èP™‰Ó–,2Ó§kÈÐ #ŠcÚŽÉëZáL“ɄԀö*Ö9òŽªf½ëŒ”Ëv:uÒ™i3•:âJzœ<£ã¨ü¶.-1…C‘%ŽNk«jIš¿“y±iuþu¹É£VGLWÊ·ªÊ98£3¯dDC£X¹º¤ÒFS•¦KÄ´v¸z.×[þ¼øÿØüì®È¯}>8Ü9û…¯eë¶GÿíSýNÎ(É;U®fÚŸÆÜÈÏ:%çl-‘š21Ÿ÷ÞY±Àx …žÃY{ .(·8¢:ëå-«Å§UynÜGb6"‘si„Û%ü ¯‚¬Œéˆh¬ò¿2þAk©®~$UÆ>.ãß™åhÄã1ÖñE>M†}‘s5½¸†¸Ž79ÍòÐ!sKÃ%–¸Ähábvp„eÜK’[é¡2þ‰ùk΄†M¬fc8[‹ÒÌ㡪~‚vj˜¦ÀU<–Ç,9Z¸‡açXòE‰Y–Nò{ØC>z-ª™#Jw(°¼SႪÈhO…“¤}á.ª*09—¢þ Ý<‘ù`à~Ê©Æ[¼J~=ü™Å'PI»é;ÜÕ´Ñ[_á}Þùßµ«ùTêmÒ\ÌKár¨ƒA.&Ãûx“5¡2äX(;)F¶Lò"Bð9v…¼ÅâIó>~Æt¨›(cœõ4Rʲ0‹³èÐ*ª3›è—g'XÁpáœ-©Ÿ²¬õ õ, '¹a�cÑ|p=kYεüCÌæÀBbE2ŒÈ¼9teýzàéà3i+Ó! ë…ÿº±»çÂgõäy³Á…*—æ0Ñø•и„yÏEÝ=âÏæt8¸»Š¯ð!šiæzJ9@„GÙA¯²5Œùúx̱Ž×ég©$Æç4‡¬ÏÙàœ"ÿƒÊ2Ãð$qVñÝb‚bàKQ÷°4¤/©-½w ·ùÂ…÷XÖcåg6˜ØuA`ÂÕ‹”]äÅQ™kÊÔ¤íK»Š ù²}1ߊÕÞ²5ýÅo)PØlë”§÷›|N³9&Hr[Ôûy-îžJ3Y™ =ºª<•².ídFKë'œÌÚŸÑ8¡­ZGJ_ B‡ê5ÇéÒŸ¦Ö}§úàÃMs•6;Q!}ÐîR[úT•IdL¨–¬•-Ñ‘5ס¼Ô⸊RÇZ¤éJ›¯wö¬ŸÏ»´I¤Öl\$.¿Ä Ú«­ì6ЦENL(-‘˨ÈiŸÐ<ªºL>£ô¸¥­z©¡"¯2áê–L©­‘pqÌPÄø¸¦gß±¡Mo¥LFI•Ù³Œ‹îÕ>©;ë̼eR)ûF•ä,Y¡·Úô´’) Qs êÍökžÔ8­>ãg%ÞÊÙr@cÁȬ­kD#t:»Ï¢9•qõu¢]ú§Ô51¯©ßܼé9%U²NNzå€ÍÝÆ*LìskÑJÕS–Ì+ëk•LjÈÛ3e°Y ±)©YC:Êd¦ü²Ñ|DýÏœ¼ÿ¹²±ÆÈÆÞÈTMå'ÖLÌ,JØSmYVIRsDGÌh`ý¸Ò„E¥Ž¤¨1”5Ÿ×÷åR¿Ÿk65ã·o·YxjÞgX1’µ+­À}|?pІ„%¿¨Ò·*î÷óVs/§ãÅZ'ÝåØZwo—Œ:ù�?æu†)g{Äý•QšxLÌ#”ÒÇu,c;£ÜI[èx-ã&^ç;?t.(uˆõá†f£üˆ‡ÂóPq—ÓrÞÚ»Œoó:íEÂ@ÔÅúÙÀh˜a¿ž§ø)kΓ°W±‚ÌÑþ_ 6EÜë¼ÎÌyƦu̱‰,uŒc#i*Ùöªóo±PÜP„·q cÌÇ\x•z>ÆN†¨©D¨àÇ¡Kì¢"i‰X¸-KÓÇVÊ‹Äáúú›î{ðÊÿ®]J¥VPA}|Œy~‚§Ãö>ñ_Çb L§š.Nòí¡ü¬)\0ÇB{ì\^z¬ ÉdiUÅáå WqœJÆè ùó-¼Éú˜bhÿ8Ûhç6p¹–£¼8Êf¦"Áoršcl#qWÔ@àÝÌ… ÆB æ†ðo«ù¿¾ U¡Çû,KÃ]4Ì©z¯sÙ‰ÐË&–åâð4³'ĨßF~ì¡%"6…¹œ×…깈HÜ7™ÕP‘pH[”·e™ïã8ýQÿ;âT `˜g¹œëù÷ód8;ž =X_ç^‹¸1êΆԒ[}øPzÉDáÄ%>Wé™ëÍ÷ðëÞ?yê½ÁÖ7üŸþOÌá±-o]^:ÐÄ“¬e!ñ’_>–x:¶þÞàÑ7-ðõ?5™ möù7ÍY×øqàÒ)%Òyƒ)#uù„ÓYýOÆY0ïñ„¦G™«°a¡‰²³S±Þ’Û–ÎfbFfäç\?íñ¬ÚÓ9=­ÒÆç-#‘Q(ñîɉԉ'•Æ}¾S0idÞ½1ßhã¬Ê:S§,šWžŸUU*P¹ÄØŒºã'-¨2Ü£oLÍ)Ý Ô*)‘ÔT.‰ë-HëÞh×K99¯n¡Œ²¼HDlDóBg9uÆâ3‹ V«ßbG©LÜ`Ví”UeÒQ%uÅDL°8Ç´’UŽNh^*Òc®Ú|•š˜Ì¤ºíQÙ~µfçÔED¦ÔÆäëLÖšŠi®s|Zͼ٬®ˆ¡]Žõ›KúÏwÏ(ŸS–’[çpŸšF³ƒÓ6)¯1—WÛ"=­fÞçWHD\›Ñ3¦,õæ’ÔÆOgKÛr_¿hÙ™÷ ªÊ[’7µº^nN+"*¢%eªæ5Íú{VÇ\økÞÉ™Ó]iÁbûl˜÷ÿf c<í½¬«+x®RUÂÅYßlvwÚXàæœSõÊæÌV»¦JSÊl^4ãt›ØéØef:ÂÏõÒâÅ@'ï§8M¬å4í<ÆÃÏr”5Ä9Ny(.â=—ÍÅ1+C½\5iºÙÉåt†G“ ® …yÇÃzR ¬º>b,ÐO+ œ¥šaÖ³Ž=TÑN%“Ä©¤›~ÚÂû·w ²ózUGŠï“·8Ö*^ñs#}ç Ћ¥þ=ôÓÁõ¼ÅGèä"Þ `3g˜àÍ´2ÃfJé)n¸:„Ï»u1b>Êz–ð«(¥Àµõõ¯Ü÷à‡ÿ»vµ%•ú: ÜÂ1v0nÀnf7C¤™æ#œá†pà{7W„‚“¢…­(nIqsˆ(šxÞæž æ‡CXV¨ÓÏ1À:6ò*Äyqb|ˆ+ä4,áâÌyBÉbjÉwI³™]<ÏÚx+áóe<ÃaÒèØŠl«¢&õ Nq”Eü$$tå™ a†rk()¢D¦YO5'CËW2t§ PEœ—x›1öÑJ?b;»Ã9ê|%æîˆ¡à\Â}‘ãWÀ·†Hÿ7) 4òuÖó {8ÊØÈ7YÁÇùI̺ÌÚI†Sa"À0«xŒ³ÔÐÇ~Nó(ãlâ÷ÙR¹V°ˆw*ü]Õ•ƒ¹w® ¾õFÂc?7PáT¿÷?üðä´ï^Þ‘¾tÚW¸šò 7ÆÝÌþ@!£ÒÛ5~yÖú‚«øû­&»icG«¶i3uVtøÎ˜×öEUÇlȩʋ÷Ø\êºnµQÆu>õ±ˆe1K”DŒ˜çª´Ê´ŽÙ‡ß)Ì]–ÞÅœ–˜D©EãfhX¨žõóê§UTÊŒ˜[,òÇãÈYY&—’/—OhŠXX¦¾Ctĺjs*fU&ÕŒÙÛ%‘/‘m0ÑgáB}#ZòbWùeŒCÖÏ«¨—Œ)4ëµ¼ÉlZůhi6Y*Ö§§Íp©Ø¤†Cu•‹,w¢WC©t³û­=®«Z:­t¹Á~úN»rÂ"-FNëÉ*YæÄ€“’GÔ¥Õçd—ªU’ÓyÄò:³5f*d: ê¸ÌŽJ/ÎØ~™É´²¨ÂQËÑç“I$4’OêhÐE°ÜÀ¤KÕëÉ©h2÷W)O«HYZPQ'PH‰šH‹Ç¬œ‘3Z.Ö&;ž©ilÊÏ.ÌÇô‘ym‰zfµij29‰@o «àwrnÍyŠ1~Qp}©¦V×ÖY—v}^í¬£³žˆx8°‚Û©e#Ù@]ÄÓÏš‰ZFs·hÊ«³>›÷DA!⺴×óVfŠø;¦bÍM^ß‚ˆ>Í[<Jm‹!v/°‚eˆý|”ï1ÃÅaø$ßb/—ÐC«ùOr!ÿÁ*Æ;8Ã\ÄÛ¼Ä޲c̰%<œ/Àž&œCQ Y¶²—>N…ŠbAÎòIêHó;¼Êo…êGyƒ•TŸw‘c(òÜÀaç€Ñ…óªhQÊQd!~˜3\Æ‹œb7“œ¡‘Óì'à CœâáÐö3ÎMlã½aÝ.>ácŒ0ÃIÞfW(V(>Ðñúúé_Aµø£Tª˜ü[Œ¨€ŸQNœ²“ߣ‚ãìä!¾ÇR¦yž7ég"ìÆ¹0g¤H­/Î0Ç Tñ7s¯ ƒÒsT„¶­\ÆOBýe±Gþ+o…xΰøž @­dÉñ2UdÙÅi Éo¼Åiþ€ò"~˜­t†(þÝ\ÃBö²™§ØËôy À9ãcüÏ…3ÀGB�G?&Îû•ßÏÙÐ^=Wô~E”‡f¯ŸóD¨Zìæ C|50XÌ~+´y]ŸpQAÇÙE?óáÌýržåÇ\ÁBV2òˆwðLàö9éÀ>ÌOø}:8Éj#"|1¤5’ϳ‹^Ò$xžÊ0dòY_I¯í/|a›§þ¢0²ŸžˆãÆ·ê}<ñí,|é9Ï|LêøŒêâ9¸Û•9Éy3ŠèŠYˆvº"™â’!KúÙ2gžlñ»Õ6ûç¬Ò”oWù`5UÊKœm×:f¨à¹„õ3ÚÊô6>ï'|=ð[Ƙ-Qå¬l•˜ñvD3$®NýÚg2ùÒ§î/*U¿ÈtFUVÑò1‹sò¦ÇŒ,ÐÖ­wÈÝózâtÛS>¤³K®Rj\[›‘)½£ä›õvX"?£ò’9¹QKËÓÖåàf»NYX![cºÝPN"'~Z÷bÇc‚«lÿ¾†‹Lìµ±OcFi‡“­&*dsÊçÕÕJ¾å¨x™¼x¥ÙVcœ,U²B߯a% Ù˼2¤«V2!“‰‹LZ_¢¼E!+h¤”WKµ Êl¥Ù£êÆLå,ˆÉŸÖ3e]Áª_(Y`r‡1óM†—:Ôï7¦ëPÖl~†¤XÜìaÑ%òõÒzÖ:%o} Vá„Em†fµ¼Ê|³W9:eyÒÒyõÕº³ÚU¬62°"•íÚ^x±{Þ¡uªf5UÙ—ôR»¶”5Ï2Õfq5Z"*š¬Î»+b&ë»ÓnðÅ¥âîNfCÁ¿°ŠÁ¨Ñ„Çïð“‚³oÅ\”“Hª°}Úò¼;Ù”³–÷G|#°Þ%­~ð{Á í‘ÝS ï-x†ü˜JJ¹‘mœå~êhæm2ü'QwF- ¼ÊŸQÆ4ËÙÎ�b7_f;×á.áR‡w�� �IDAT~ÌycdYHgÜ£‡Ãø’w1Æ,kÙÄfùSÆÙËß²›~.að ʸ€2¯ÐÅ8ßæ ^æijCöùiúi Eš,ñ gH„赕T…‰¯EÈS”Ý$™`cè+šÃör8Œ \ÉBúÂYhŠ÷ñ3ŽÑÌ:N‡ö¢ýëÏ •úEpT9ðRT_ßx߃÷ÿwíêç©ÔÚÙÅ!:ØÏjjø]üˆÅT…@û€ŒR ‹ÙÍÒÐ÷S¬³·0À½\É}¼ÎUç8ÅËhf=õ¬bž•œäœçúš¦‹ÛÂÊþ 1µÄ¹1D5€¦$ºÙQ¿ËpH=9ÍGy•9Âÿd'Ùˆ‰È9Zp­´…_5Œ±“%ç9ÀŠ+º|¸´,rSá·ö‘ár"¡›¯!î¯ Fibu(:†ñ3eôó~Îuü€­¢¼àSׇB*ó'ɱƒIvóŸ\ÌÓ¤ØN†qœ¯ÑȳÚY¶r/Ç­¡=â“·¹†<ná§4ðvØØ)ýóíÔÙùy+9î=\÷`¹Wª\5››•û°ÂQ‡×JO9šwiàŸw”òƬ‘R¯å®ë÷Ïm¾ø¬ŠÑ“5±Š3·Ni™Ò;­~ƒÂÃUR1{ .ȉÏx<ðóÿ+ks™5Q½e‚Õ3¢I'§#î,w$è¾ ðù½ûÚt[ÔÜ Á¼ò3Ì;¼Îø¬S%â%¦Ë̶z!im^kŸÎJoÄôÔ™ m²]P!Ó$yVÝ…fËÌ žUS%WµÛ‚.‘I=+í)ø‹¬…gõïv×€Ú5NŽiŠ)Ô™ìÖ»Ëú2-&ãòýV$ ´­Ô·ÁÞCf«Õ-p¶ÚÌ>ë¶øe«á%NÄäOZ4¥jPÝÙņ{œzÓÒ9Ó%šš[hhŸBRøhJÍ Gfe"*78|Ð’‹õ—Jg•¼ceì&CíÏjNÈw8“UG÷AK)¥¦hËh\B™Ñ:[L/7Ô¯qJyNÇ!ó ̤¦<}ÆTÚ%¤“ªâªç•Ž‹(™Q6)1#RðVÊLFG§Ù´Éöï w½yqk˜HZ“R–óƒ¤ETGD(3=#ŸSµ}V_ ¤IzN^=÷ÍÊåÝXjMÞስ,£Ÿ»¨ L3ÍÖ¨"6fßMiöYš¹”o°€ ±t˼Rï+q¿—ó(W3Ï <ÂãŒÒC"¬o70R1û‡Kˆ¥¿aï£.öð—¡ñô—Lsû¹‚ 8ÌR2dØÈŽÂ9Hék¡¶ð ³¬ Á“4ñ¡3,Y㤜:z¹™·)0Êål;¯ —„ðˆ9B?•¡Æá½ì T1&·‡.XÍr:¹•+x2®$Â0+9* ßM_Î\8+Šõ—2B:9òT‹ÿñ4æ%ðsþ'ùÃP»0K#‡9D[}ý÷=xÑ×®^I¥šy#¾D=åaûYÎÇŠq“ƒ¬9ïh Œ?>ïæP RÌ|ùÿêQÌ~>bµ^ç~þ…빘‹y‹C=É,rŒ‹øIø¸oÑHá_â k8K– æØBÇ·²<´Mü ÙÀû¹€yêÙµ˜Ã!‰¤î¼¯xÈñ+¾¢wCÒ¶ÐN#‹ÓØ­avg˜ÁQÌuUü’·hà'!B.üÓÿAøê9À+”‡Ză¤Øs[pN´ù×Òñ|ÔØÚ›y„|Û9ïH"¤„ÜËOX@¤à»÷¾GuÌÃ1G+ÌfΡ_g¡KÜ>kßVÉ'ÙÂvÑ|îµØþ>ðå–VÙ•„eä9@/#ÅÅuÜÕ+Bho/Ó1gJÝ™¹n›¾åŽ-Šì˜ÉiËbKL¹¸k(ÎdÏûµ¨ÎÀîà\NRݼCµ®È«J™ÓžSÑÑPp´Ã “¿ùÝà‡ ¢ßÙ±²IC¿äœ…5’5U"1‹Ë”5ËkzªFUB¦A®[¾VrRiµ²˜d—#U5¡¡Bþ¸e%¢«ŒÆUfÕe•µš•VBl5›t,u¦Qª^ÿ!Õã‘*s9åR1…„©7}§Ó-DJe¢:«ÌÑS"Ólì¨å½º3J†µ«*U˜W²ÐÀŒê2éV-7\ªÐ"ñ†ŽZ¯•éXãä´ºÃ01`Y^iÞÏ/V›Ï*2P£$§"'Þ§q•cG,ЉÄJEK혨¶kÆêåNÖ›œ›«Í¨¤,§¦ÞTÆÒ$ñres®Íy¢Ëª˜ŠR…&ûÊU¶93Ó0&S£>¢¹ÊŽ9ó«ÍN™Œ´gÇVŸøPÎÞi»bZªæœÉ bÚ#:ÙQ[eeÜ©yOG]uùŒC17P¨ªò|—‹XuqVY ;â/#ÞSðBÌ’@Äžˆ+9wa`2° üè/ù/ŽÚÉNÿó°ü ¾¼…þ‚d˜uPÔaUSC‚ Úù(‡˜eŠŸ±ŠöðƒÙÀ¶ð"µ�å, \÷°’ï2Äý¤8ÎV3F%9ä×ùBXIŠ“ž"uw?hç =ìfg˜q? ý¯õ¡Çù=|+ü9à«¡_¶xôIžã~·Wm ‰¦egC48à g¸‹XØ]ÖqŠÆÙJ73¬fAXrßEŸq1]ážï]öî8ãçœfEˆß-ãK¼Ìj8ÞM}ý¿bwõb*uˆ hfˆ ¢\@G8†4ßÇF¶‘àJÞË^¦Â";F7o0F&§¨dü¼©Z0<ÄÛ<ÂæPÜñ3¡C­èú G‹É·õ½aç¸Ö9?é2vä4·s„‡æ¾N‚-\ÍËçif~‡'f«Ã4áÁ9wÛ.‡_=¼ê/çtÈ‹zWgQÂn á¨÷‡—±(”3DØÌ"¸™7È3ÆCü{h¤˜à¦ÿkö\ªtÑ-p“\q*°–4Ëb>Æh`yD,ðmÖ’gšu!Id?×2¾![Hå4Û¸mÅOiD õ™œÞaŠ9w¯w÷—ìöd¹üÓüÒ>{E-{v´Ì\ÒPÒšˆ1•~ÚÙ^±6ðJLu– •e.Ik*Xžñ%#ºk¯/'£³ˆºª`;¸)PȲ/nADªÎÙ”ÿŒXVÐ\0A3§µ´¤|.m.ckÖÿ‰~áÇíÏn©T‰Ì¨ÿ§?õØg£–EÕUJ˨,“N;=©qRUŠ´ŠŒØêN[R!×cø¨åS‚¼Ä¸Ú¬Î¸–VÛ­6CtJûÇçT”™*•«1Ùk¶Tõ•~±Ñ‰˜|™\ Ò`¢ÊlZIZ¼ÕLµé–,vrP{¹T­©³z:”¯6Wg2ªpÄŠ6CÓª[4šØáÒ˜ÂgúÔôé¯W›Ë*6_ÐzÆâ…bòG¬È«[£„ê)c]f ·h+ˆ×I6ô¹.7i«1½Úþ- è8¨»Çà1+ËͲ£ªªÍE¥;;­t̺¼Ò¸|\É„†*™SšZÌ”ÄæU6ˉÕ8Ú¢,©±Â¢´·’žT±¤ÚDÊd‰¥ã–” –l23!•5šjiÏÜû|ù·ïˆûe’ã+UÆôÖe•Í™Ž¹<¯/od½ãýê#î+È•8ºÈá1gym^U óöÌ9’óJq bÊXøRÄ]Qk:´fô¦íŒXUX·º űÀ,‡µÝkõN/ö…®Ä´óAê©æZÚØÌ6ž WW…ÛšJ¦Â€õëØG)¢ÜÆÉð#Ö÷‚Is7?d;û¸'”þFèÀ­bO…•ä#¤ÂÅÕ §¨ 3ÜçȲŸ9f ñyîUÐÅÐÔ %–Çwo| ´-¿ÈWA’;9J-¼V¹"y½0:Äí\ÇÏ[sT…×ú ›w±<cè'Ïë‘ïÞŠ0‡V°œWYÊ¥ì 7AíáSmª¯¿øWœ®Š"£ôq#Ãü>ßч¿Î3Œ†Û¿⛼—^¶°ƒhØ®f¸ƒ2îámFéO9ÃçMö’|…&êxCl% \Çi>Èö™›ån¶s q„Ï2Ä­¬á v†0'Œ°œûùy˜s¿4üÖå¼þ»¸jú3êH²‹aî !îçKb&C[\‘18ó_©Å^ _Ô£|ƒ&‚À lå�wòWðOĹF–ñÑ3?ÁeâÆŒïìcÀÞÎ~xçˆ2—ž`M`Ÿ …oqÃŒ±ŸÏ³ˆï³’÷Æ]Qð ¸CìÛ"'8¸5°+g[Øq,îû…£]ñ¶ÿè°w‡`H<û‡àè%Á_.Ե枻)ДpWTIÞ ¯ÄmŽ»'bCD}ÂÝy©@iδµjÒþ$o%½†³ößbôù paà). ,kÏ¥?Ð8Òd¾Ë¦aë­vå˜ê¨Æ@ Gy¦Þ§J”¥¾úÁÃ?›_rzîÉM© ‘µ }çÌ'رíª&ÓÑqõ3%ú×J¯tú”¡bG¦´¬Ò×*YP3¢¹ Z)s¹] ô—K7Ùiq§é‹3ê/ôÎJ‡“j u’åÒÇmÔNšÖ<hñ›zút&5Ô:lÉ2æj$µìÑ6¡$!ßj¢ÉT½ÚœÄ¼²i5{´ jZíT”iÕ³ªj$O™½ÀžKól0Ó«'ªz¡á6C=N%Õ¦”OÚ½„6CæóªºÍÖÈDDKe[3çŠRÈrGßtý^¢í†—:yÄò›<¿P¿ºdY‘Ð1£¦Íp«á*³†kÏÊ_àä!=%æ\âÄ>‹*•§5ÍÚPffXk¹%kèõÇã>2íñ'.‘;eѤÊa ÛTOD—O~ÿ“™¿ú­|²-kuÒeiJ­ˆxaÚ\àš¬Ö¼™ÀÀdAfÒ•yk"ª,µº 1¢>pIÒÞ”—2¦Ã•ð–¨ÒˆŽ¼O³1ª+ª;å`Úuøí¤2~ÀH „¿ˆº.êª@<rôÚDeWყ¼ÜÐfKʦÀ‹ìMøÞãžú¹ôóý<Æ`;~‚²0v`Ò’Oó:ãáh!œ3ü„Ý|2L…á(ò5.å7yžçéf›øÁ‰0-þ7ù·òIöñ�;Óµg¡Ñ9ý0tø ns³®fq¸aÊÒ®£ ¬b=‹Â¦X,ÚÅ(ú‡xÕ1rô“d˜ÃD¹#¤ÞÓ¡.ñYæéâ÷æ@¸SXÍ#\Í5´±/*é9×1˜ð§Kxe_ C_1z¢¾þä}Þû«ÛU Þd–·Ã—Z,ÊU¬ /ÿŽh×ò4òGÔp‚Z°g( U4 B›t1Ul2dF}–é0Üe[˜óc¼CÒ&¯%Á·˜ã Œ‡yïÝZB8cQçó4Òò�·ÓC–Rn!K8Ë %E›EøÜŠ2ÓVçÄÜ÷Qô¥}€ëÏ…þó r¡õa˜~r4‡ÇÓ ¼Ã.£¶Dœ Œp)Óü¸#¤ÿÉëwpË‹«µˆ>¦©fˆºˆŠ„…sùw2Óá§âBÊÙÈiöRG-wS÷Çý…s¢ÿ§¬¸Ësû¬¿Ñ™@jy$ÝÀ_Qs+ß)øI$ñïµNb¯µ[<r¶ðÄ_:¶È÷. Ö Þ¼ÈlUAYáÜ«ŽLåýU !b]γq‹ ÌG½Ýd|Χ#òÞä$sÑ­ÖçXgYÁдC<¦&KˆÍøL\}—es+®]Ðõv[SB²u¶,íŸ#þµÂ©žÎ™ßz²ä–¯þàKe‹¦¢O÷¤üîLnqìæoNîØœiÓx¸Âê˜îr'w¹ GÍA-3–b vžµ´R¾T¦DfPk•wŽIÍë\áx·¡7¬+QZkê”Eu¦Š÷Ù.R¯´OK‡rU,ë1Üaz‰Ó³ªºÆ¥“êútN©=£òöUVSg*&_*=¦1¥â´î›mϪÎJ¤”·®1]g²FÙå3º—ɽmc¥Ô…öĪœ:Î"sUf¦­“ˆ*yËšZs;l,µ³\CZéU^ît¬ZI«ã–^æ å&:ô½ä¤·3V´hcoYz›—ÊБ²çû’:ÇÕ³,«®ÍÔýóQÁY5ÓjħµÖ›(ˆŽiЉFäO« <HwÚ0fCFe\¶ËK}JÇ ÌõáU¸+5ö£ ¹Yg›U'M[=gKÜ5üvA†5¸²Ú7RÞ“6F϶ç¼7Pˆ[x¬ÃMSþ‘ 4Ëb £Äò„[å“’é:9Ý“>Ÿð`^cÜŤé:ó%Ö6G“‡ÿ¡¤~cþ¶Ìì¹<ÈtqgÄÇ"ÿò¢Í;"?,1x]Áß32ô~‹¿e-éˆD¸¤ù *„‡(ð±p¤”sñŽ;x“.6p‚¦¸OÎ 3.d:l Ÿ¥œWÃ4Á¿ã~öñ-DB¦Ñ£, ± -äy€“<Οæ?y5Œe¦‚ Ó´r;{µÖþÓ<æå{i>Ì¿üÿ…¡—PÂpØ«ŠÆÓü‡Èò›Î9jŠ›”I6„°ÝŸÒ~# @)a/û ^3ïçéf–MÜÁßsS}ýÑû|èW´«rn%MSh8Æb²<Ì+ÌpäÙDÀë̇҃åôw[ÌcL……»‰.ÑÎUó\Þ! Í$QªhcWñýlâ$Ãáé2ÁCìqš6å£ìe*[9‚î{Ãwù.âDèãVÐÉË<@ ©Ð\|YÀõœáH¸–,zÈφxøwÝsEkÛR–ÑÈëÀò\_y‚Ë9¨Œ‡q½[Ø^ð%þ *(ã×p:TáßÀ⸫ ~À,Ÿâö˜;jÄRžà¶QuY�7òךòÞß&s™Ñ÷ñjö‹‚Eá]£+&ýú·Üþic ¿ó¢ö\¼§§°/N.°«HµøÇ¨¦ È1{hqäŸF~)úÆ’àú=ø ‘wo£ãÍ’ÅðÉ(ƒäSüY Ÿï||Ô½ÕV&•dœŒX—?§j‰»´Ú/SZüëœË˜äÖ ‹bšóºÛü]¹/ÖVÝødꛟÈtÌ>øDâÊ}ó¯]œKÞ‘s FßÜg¾1Z[²åßÖ¥·eGW f{×WŒ8:½¹æÌ¦Ô†øâK´Ìº;Дr"åé2ËtúËU·š;îñ¥–M«îv2¥2)svRr™ºr™~]¥" œMË”õ8=­zHmÁ’*ÙyeqûKå&t¯u¨W÷„D½ýëœØeE‘ˈ´˜ÙcMJ´Î\¿Ž)u8ca£ñ¤š…zÛ f”N«Î(ÑÜ«ãå ¦"t;]”KÔ™êÔ‹iË(Í‹e•®Ð;¨lVíR} kML)O)¯2ù¶×fÜvHO³Ñ´Šy%§Ä› 4ˆZ9§tVeA¤^n^yN¤ÜÌréjç,ˆÉ–˜3%U2m® [ªvÐx‡üBÇ{œÌ ""Q©KŽ;;¡=§,mš`ÜÒ‹<ó¦®Zy]úÑ'ƒÏ—Œ ŸÍ{4åë“&bº"F#ÇcZQOéYfó„œG Q—Wº£ZKÊ~Vµ™Ëè™ÐÎúpË;‘p¶ÔÚÇrÊ&|1ie9ÏF=H”ø1Xøwö¦íËØô\™OÕjœY•ú×èÈ=±èʧ"Ë#Á'n}èåšÖ¥´‡t¢ߎœs_·¹`=G)á0•q‚ ¸:-±{Ï„fЕôr€%ßâ!Æù7^f!Kùë0õU>Åv²Ÿ4ÂËÜËrþŒ…,¦‰ 8Æém 1xÃê4JžAúx‡ØÉ­œ¡“|†NÊÎ+bÅbõÁ.mÈqéy¼ò¢Fcçy÷ܶ€½añgé¡—WC4vo„Ò•ÖÑ0Ë Lò�{èæ(gy»¾¾æW@˜b©ÔÊIó ïá³áܳër “ 3Hg2œu6ÐÂ660É=!¸p’J.g9ʹ‚oœ·”+ç:˜g Ól¢…*"æ&¸„3ÜO%gˆ„ª¿"–ø=,!ÁXA„»±+Ø@5u\® ‹ìÔ[ù:­Œðtx0º=d sÌÞæކ—!xˆÍ¡ç7í\6n7W†oàúCò“ˆ+¢f¯qn6ñÍtñ|1é™w¢ªÇ)cƒ ó-l/ø0otŠ=KSfù%•ˆx""œ›­7ªûˆ_âGÞ(¶ÿ¯ÑɇHs ¸Øç^$ýô—¥g·–þøêlgð7ÿVÿÅ‹ç­g%¯q—~Àrnsý"û¢ß½+òæ=º_µ)îïdÜ{4¶û}R'£jU|•»Š—#QÒ¯±:éÛ9½_äfÕ*ÙÕ;çX`QÔµ1=/õB„¼l½®q%yfzËqOÞ¼ö÷›|ýúä=Û²§' ‡ÓoÍiOÞÜç«×ÍZ×?²3X7tf+v5•5dÒW¾ÝõÝ÷Ô jM ©j ´—ÚX¡&*žÑR&²ÄñQwÆå'4̪×¼Ðà)kk,šWÕ§®_O¥¹róÝ; Œiê0Ð(¬r°Ó‰1õIËF $4f”UšËHEU¶˜©4ÙadDUƒd³‰Vó‚VÃCj–:4˜ˆ*4Ï‹õkª3>®".ºÐéR©fˆË/p&/Wn>/q\w…lÜñ¼²Væfæ•j¾Ü[û­=`ŬªUŽ—»t¥Ãåfë NjSÚMܾ„–Jùz?-5Þ(qÂ’9¥'õT™i­4™VÑ`<Ȉ.0ìÿåë>ÃìºËsÿv™Þ‹¦ÚH£Þ-ÉroàŽ Œ˜ N i@„B8”äo tÝ€  n²%[XVïÒŒ4šÞëž]×ÿÅhù眰^éÅ\Z³ö–~Ïzžç¾¿·òFN›ÎJ.7Ù!>¢üŒ%>ª}‚ˆÄ˜±¸ym†çÉ©Œ0Ô–MÜý­ÜO›ªÿ]Úš¬ßE½#¦}3ýê äéNé£y¾¬á”º©ˆ5Y™¨;=Ebú¦ F]•3”2˜åᨫxŠå…î‰JL‘õ(YžàÂrYŸ \“Õ™¯$êÒœÅQ7Z£æÅ”æÜ™Õ>kÄ‚Aïñèè›MÁª`Éq8ÌŸMìüCle9?ŠhŒh P‘óaÒœdœvºXÍëy˜]¡a Q«;¨æŒðAò)áÛ ³çïc3¿˜[ʲ*LÄ}”qÞÅ�ÌòSÖòlÔ[™Ï·¸Õc1ǹ‚,Ý,`CX3°‹âs{h )­®yŒ¿ “ «ki¥“µäh iO‡Äó¯;œ›î̵¡—ñrHvǨ¤Ÿ®"Ÿq~þÀhˆ œ –ƒÄy–ËçÈÂàŠªªmçS-¢|û3”²ˆA~ÀçÏScQÉ¡ß6Ÿ;Æã&Ê©`u¨ñ¿g›9N}H¿‚'øÁyw¼†Ÿ…ˆ"^õç8OóMa£SGê¼€’{ØÆcÜJû襂Ü~Þ-N³™Þ°^6QÊÅ\GMÜTò °“ëy4¼cÿñúOá²ð-ìáìõ×ü24ýmã~Êy‚ï^�ïå½Lðz6‡ÂËSÕ6ä99ë››P_HšûÃŒ•{yÁ5ç_Èql ¹s^·Õtëù¢¿îððy„û¹M<Î~¾Á×|ö"W×ðѬþŒ?;n<™4ƒ/ñNÎò7±z ((]‘{ëTîƒOÿÒã/Š\^¬áYŸûH $ÐÁÇæ¹-ª“ÖÞhÏšqgN{àŽ<'[4dm |›\Ä=1ó+”䙊[Jç”oOÛõ™Ó¥ôù¥G®ñ™ûŽêŸ8¼´þÏÿ¡ìµ§4,ˆY\ûÓ†þºŠ=kDôá.™^$*¦Óox¼\rÔ×O˜ÎÉM Š¥¦äu9/3ØîX—ò‰ ©*Ó ôL;pVÑ*+hw¬Þȸƒ Ñ~e…fKMv+=¤|ÚpL6OzBS·õ ñ¨ÒÓ®rðR/f5·¢ÖH± Q/ñj£…fÏjД/Ó¥ï U•ÆÆTVé´p¯u“*‡Ôi¬5'­4+Ve4¡hRYÌ!«ÓògUH*ÚœI‰=iýIk—œU>¦r•ƒ«»ÀžWlX¨³Y÷ˆ’ƒ–õ«O©¬M(ê³²Ôtƒ>æÏj-7±HGÖØ¤ñˆ`HÞ<ÝÆj®Ó=éHN´ÚÈi ¦T¬VS"wÖâYG+!¡,OyTEÆHŸéÓÅžé¶ ²ðÂâŠÈÚ½ëŠå,dKÎK•öÊÏù7®Ë¯ÕufLIJE¥Ñ¥fêͰ!â×5ê úD¸-R‘õ“BËZ\Èò;ú’’) £vS÷ >NÌùpÖ)’ Ëf-hŒP3/ë�]æ®=¬þ±á¬=|Ðz5eýð ‡^au¹ªb›çÖç#9'x–¯DÔÅ\A„³\H |Ó!Êv®#Ù( ,äß ¥ÂŸâp¨Ãº5œ¾<Ê'CEñ<FXÅm\ÀMlå<Í\À×¾Ç!>ɱ9+3|2â51ã‚ІôªÔð~òy‚ó4O‡-àèy ”vîµß]áú?Áó¡xíÿÈÓj%'Îã$œŸ ´Ÿa‡µccxø¯=ï\=˶ÐUv€Ãaîî«×Jñ¼ÖwW%ÿÀr½¡î|+õô†hÂTˆºx/«8Ì­ì"ÊL°‘>>B!`_¨Í› “ä:æ“ÏÓ¡Le .à%ê©aœ7óKR\‹aÖçdè3¸š\˜ýØ~¾ãDè Nü†B|Æ:¸Z>E×Nó9úøÆø£á>p"œù`KØ›„ôûXèês›÷‡÷ÓÃÝáêõ$Çù9£¼HƒÜÂXÆ ¬å'äR^Ÿu88‡f†X�� �IDATýßò.+8IŠ yƒìãgtåÏxœ'ÂUÔÑÇ&¾g¢ÙX!¿Éóܳ1#õop3ƒÔêkt{·;:s½5ë‰xö¶à¾ýé/oä0ï{Sà,d€7òCéÓÔ»*¢¯Í‡n\ä¾b5&ž zô=)sÏ·ù§œ­19ö4ªœ2›òùœfgeNCÊȬYíŒè®ôʘΌm9ñþ¨ÛØÚjˤƒk>Ö¸t}þ7îI¤KÚe‡ªÞ™{ëÙE»VŒŒ\”»ê¹…ÉÒªg/×\jmÙØØÔëÎ|-ý¿ŸÏ½õî‘™¿©²eÄ%mÆÛôŒ˜WobÖü´Â´È˜m³dLñ/º BÑ5&FT3^¬ Çúañ¨X“Êã4вЙ'¬ÐS§¼\¢R´ÔL«³ EÅRQÑVŸWZ//":¥¨Ôô|]Ë?«µUjDC¥ñEÝæWš\âDŸ¦y†{Ì?nñIu-†FU«ŒwJ,ÝhOF¼WÃ~KÆÍÒòŠ‘¨eÅ2…Rõ†R JÌdäí÷õjÍqyO¸t\kRq±Ä|]e¦êŒÖH¾`–Å8•UyÆüÉfƒer–ލÏ*^¦»TŠ¢^-3Š¢ºÒ•*KŒ÷ªëÕ˜ÒÑnlŸKòec’Cz2êÕ iT9íô¢Ú¡þ"ó7wŒÍ.ŸP3[æsuÞ9¬mTSàÂŒ¡Œ‘¤lÎLIJrÏëŸpÙ¬òŒ.6ÍêÉúPž;³¾Ï¾¨§¿ÈÚšÐ=wøÞ^ìàRÙZu%üe<q]Ìæœˆ{gÎcã¿ÊF]+þ¢j¿Üøl¡±9zB-žó–iŸz·ôš´ÅvÒA”Q^ËÎyÛÙË“Œ†äÖ3œ ¥['y ϱ‡+x;—åanr.õÇ r†£ü'1°†—8ÄS pI‘à]ìä5줉n¥,¢0jpŽ{÷Ëú~GxYŠy–cLÍAÃ4Ålˆ¦cŸ…9´¸ŽÝ\B" ‚¿—±pl¸ŒÅ¼f5L†µê½áóVös+{{÷}€q.e†S¡fm”g8ÆQÍux§8@–†ªª2bød"ñSfC‚íœ4îÕ ß{èçâ°ÜÊwø-E#Î3LÐ"å/åe:ØN–t胛æ0ÍŒŸW+Ȳ“m<Ä1&ØÇRÒìäƒü&\Gåxæ¯ÜÃb^Œº)¢)°™!R\¦:0Á1x.¤"màëìâÞÿ!Íu,`QÉ<'ÜXî±ÞÎþp'9gœ*bWr”kÂP’>^!͵œŽ{CîGrnõZêÌu„-\(à†d²8î¶@†¥%åôòßä(‹ù"ǹ‡.Ž“Œûçœ# ±†Cl¦!¢‹[¹=g” 0ø…Ü’õWùÆUÞýßîÚ§aM.ûx¤-ÏOÄýMÔw2NòW<úÒ®å2óÂ"ûž3^¿¢]ádô_ÚƒwõF?ªïøÀԵɼí[µä”x{ .brÜ¢˜u9°=â~jÑœê˜M9=¥² ß™Õ8S•SX(Ö¬9#Ýj`ÚÏÊV¿3hÊ<qUF<ª(«"¡±ðÁ·ö|î‹™îÉ’›NOôÓ)…S›(02ô«MÙ?XûÖ½%n˜ñº,Ißß 0'Ú§iŠF# êdîØæH%Z¢‚ ùå2ÅF‡o44ÏÔ”’ŒÂ*Ùµö÷hjv¤ÏôìÜnÍÓKbrÅuë8dU¾T·Öý…2ÃטîÕØáL¯…9ÑN‹–éˆË¤ÅªMµêkw<©à´õõöišg|Zn‰“¥fcò—OË/1󤫳¦W93¢¨Æh£²½-º³b‹šR6®2­²-¦¤P:©<_:.;*›th¿]­æ(¶èŒ¦^-}’"5Æ:W0«©È`»ÎbÑ@Q¿‚ œÖQµÐËݪŽùJÆ5 Í*»}~Fm‰¡|¥U*"VŽ;T 4êX¹Š3[óšFs¿x_ÖÞ@g­²Qg’nЉdD+%¡(PS²D4k:ꂌhL~¾Sµ’ã^Žø‹¬·3Sàæ:oIz%ë²@m¡jNÇ]?ëù!û&\3ã‘ÀÚ9FZÎæ¸HÎâ¬^úùIÄ3Š¿lùmtþ‰Èßõ‚–uî»Ô~’³¼ƒœÄˆoµKÿ€ºÀ“A®'É_’Ï34±#<ŽæÌoç±PÙ4Ì»ˆÐÎÜACè5þ='Éñ[.â;LQÏ s›P¿°—*þçXÍ�ߤ›…|ƒŠ¸æüœ á³TVè¬òÕ)‡¸€ ‰r0¼Õ‡¿íÕ¬ç%®£• Ù’Ønà&Úø ö†ž¹@Á1Z)$fB cé ¹³¼— gù%a@Ä^nãÛ¡ðíQn ÏÃóV*sC¬®P½ò*)q–ÜÁ©ªªøŸ(WÛ‰BQ\Š)*Ù2çïáYje5½4†1‡Ép!Ì£‰Å °½œ¡eÜåÍÍèF¸‘ã¡Ña(Ä/ÍÙig)ã?ä+Ȱ62/…g©[ß‚àœùSì"Ë.cETM “Ë™äýtE]E ¥<ËÒP2SŸ2¶²3$ðb0ÔfBgC‚YÌf¾J-YâdxmÐ;çö=ă¬a„íTæfþŒ^NóE°–dÎO§-êPÄ–ÀfÖ0ÆšÀo™õÜ€ô¶œðoìg;oæ÷ÓQ—çB–G9‚ƒßÈ~Ê"VDœ¥Í7#¾ùQUg¼ñw±¿½#˜Ù^h}žDJ!/†ÏÑUœ#`ÕzSWnåŽàŸEðä]Á[Ÿœ*Úë3·”(”v—[8u0#ɺÀæÇ,a–³4ê`à@ƒ‹&¬‹[LmÖãQÙ¬K'•ÍÚ; ´Ô“™`yÇIJž\GWAbA»Þ EÝ×ñ•û‚yC©û2\—'7áÅ!«ªLgm‰ÖLe>ð·™ìýiS—WJÇ=Qa}J$#6Ïôˆ Õñi±rÇ-«62!Õät'¬ÏUÓ¥ñŒÅ}ª¶:\i,¥ +>®>©éŒ– ™y†ÎhŽHJOНq¤Üd —iÒsÆ¢y&{4›i“«jÖ“'Óª+*ȉ&E³¢µÆ~çâSÚŠLÍ×}Äò厜V–5[ ¤ÔT¯ÆÉ9$ÇjèV“Ó3¬¹ÃòE:ç;“'=¤v¡ÎuW=«&"^ uTe•±½ùeóT>¡±Y&)Jþ„©c¢£–›ª2¹ÄÙ3ªGU1Ñ Û§6_nÌ e*'4·hŠˆÒ›ô¶fuqóŠMŸVP"Ù¨|@¼BzÒ¯rï9Tv|ÁLA2èúy«5 žðw…žÍ:‘³ AjB~à±Ë£.Ï:=îàŒK3†Ë<:c]R_ÆŽJ[Ónl,Ö—¶>a9/D¼\¬1gsN¤D]ÚÅ…:¿ÎjŽØRäâ¨Ú2™”ÚÜ9…Û 1wó>éK¯ >Òýôg‚GºèŽZAmÜûŠ}7¥ž­œ …±¹•GTM Êca y7›¹„<ÏV”Xš§ ­€½<G@g8Þ§œf¶0ÊY„BëÃ9Jò¼Sñ2~Âü‚›9A8p{}NRL{Ø™¶:!›ó^áùóöUïãKlæ: Ѧs‘¾'øUØßãù?¶Î] TÌB8E6dÚ%Ã!ÞP<ûüyö¡ÉðW½zNüÅÚéãyj¸‘ùáb¬7D‡œ9Ï2´5„êöð<“:ïêÙD¢&ÂéçÜfe˜òðå}*LË}Ž´0Èua.ûIvqŠ‹Ã6b=Ïqõ(OÖÏÁgéáõ4‘ÏÚpŸYB]_äÝ<C {è S)‡XÏ*vP:¨oæ¡ÅøXÄTÄÍQ–q˜bEd˜áÔRîu.ç8ì;ÁQÇ “a­:êòç¬Çkù}LÐG Û¹.lR_ÏELc”+Bšd>K8úøïæPˆÛÊð¦¹Æ90¨äa0Ænæñ]┆Á)ÞNšßPÀÚÀ'YÂÓ<Æ›ÙÅNN³„íh§þ%óè5ÝÌ<Ä;2nN{…íüž³$Xņˆ7ž£Ô½j|Ê¿.¤%PÎv¿_èùzòS¦²žŽú،޴Og rcÄHàÇôJcV.b6çWÌL¹z½Ó=EÝõƘ×ä Gç<±)i~~ÿ¼Èd~êcÿa뒟ݘ1ØóÉäÚƒÙ?¬1¯+²q òÈ­…&ÕX 9¡2úüʼnìlŒ"âš L»2¡Dްº‹¤S*K刧,óH—A‹Ä:-ˆ)­0S&Ynjþ"‰QUhZÞ¸ø|=¥¦òe§•Ô韕߬ÿö Ós’~õYñQÕã›Nd×NŸœŸPV$9¢¦ÌT™Éj#q™œü¬‚¤ÂA•qA±é}¥¦ŽX^§{…#%$™-1“RÐæÔŒâ¨ Èl•HJY©éýñnÍUF_²à”ø£EUÇTw¨iud­Eê[MŒjK˯éмÞÉ@¤ZçkýáA×ç±TgVü¬‘ õv«Í *dedûef-‹kä@ÚÆÀô€ÞfEY™I¥iÓ&‹D£N¶*Î7<a"ûÂÛóïüÅì}ß¬kÕ¬ gíÉØ±zÚüÀ@ ¡ØÆ¤ ¥.j í¥Àú„g ¼1âXÚšzó§4Gµfô§ìº ðPTÛ¬ÝY‹]ªSv%-ÏÚŶˆÉ¸åQy“ºrFÙUH}NÚd·ôKú«cÞq&°ŒÍ9þ;§-ßõ)›øC¿j? IñNó/òœëÛîæ÷ùÆMËg#×'Í:öSMϳƒg9ËF®`)£¼žky–F-¥’Ž2É [8Îý$CvöWÉ&J/ylbG`—ꈑ`–y…ý žFv…qY[ÿ¯ÔùWÑp"5góš#ê%iž#͇?ùj ø?pE§É£‰½áÉ_B;YŽQO÷9ß§föÒF]È›¿øÕ•UUÕ]·ß}ÉÿT®Z‰9üðxbŸ 'ž¢—ûÂ(åÓá BŽMdÂýáúp9PÁVº8Ú­þŸ×½˜wÐŇ™fΪ|$¬ºeá'~š1¶‘ ¹·CadçÑÐ3ûêŽî¢óö3jÞîœì{ ³„ƒt1F7Í“¡ŠÝgÛÏ¡J’çY»Ãx‘½œâÎ0àZ®d5­aœÇÃaòXWñõðŽËéã-a¯ÖÇÝÌ›ƒAĽ)ðCvÑÀ\À7¸$¨¿)4á×ñ¼^†B“üѹÀ^æ_Î)×mç*.¥~ÌèàJç\Ã`1Ã:Ö²‡k(óFŸúYpï#î}ŽcNlôõ>é×Íqãn ¼–òRë ,Ni‹©Ëëª×Ê8ÍiV6Z0ëÓÕ®HZ±d©\¿¯Oû‹¨ª˜2Ò9‡" +[${5”˜è­ˆ<w8øÐoë†&¦Úò7ï ¾º5[iIg7¾yäºzãõrE‚2§³fK$Å·(Í×U4.˜t4fѰº„¼•õ&iP³Õ® Ó}ê êé·ºH|#ªO[X,Qm¤@rXm—Ö”‚5œ¯{ZÉ$ 4ÕéÓPe*OfDu\&+6£øøÓïI7 EëúìÁ…¿nšê[$»G~½Á§ª.>ý©¯5ÿzõRÇ{5Ê5é‹“–רo»K魔ΈﳶA_áóŠ%^¶¥E÷Ú–¬t8)¯Su‰lBñ<ƒ/w:¥²HrPS‹³¥fJÅ'ÌÛêÅ^Mè º¨Ø¨šmvª°ä„å*Íöh**5³Ëú¨Â´ôbݧô-01a¼ZÙ¨¢6Õå&M%g|z¹…'IŠT«J9\-Ò/=bUÊVµ;Ö”¾2¿äõ»{þñç¹{$ï}Ľ/ëÚt¬ | p%y)ý9ޏ!m„1Mŧ½Èü¤/¤­(òÿkÑ·6ë¿h‹‰D\¨ËªË Q —ðõœs¾žói‹JE½=8ìûßѕы–ç’Ûr]ßá™ DxŠ;Rþž8ù6Û¹‘^ là®àE^à>~ ¾çà;{ÒÚÓ®äEF¸ÅÜÛ›+ù-ý´ñ^îW\¬fù4ÐÃ*¶‡Ìîƹ‘®pCÑÉM<Æz¹˜ang?]¼hpŽ‘=ÌM¼Èzò¸—}¡˜k›ÂȤ\Åk¨ õϯ*´ÛØÂµ¼ÈÔyŠÁWII*¸6ì«^UXÌœ‡H}Õ’uœÉ°vuíƒc<l*FÃöqι¼5D¼Ï¾z÷ªªÒÛï~ýÿT®¾šHL‡.hç5hïâ$/á­$è# EG˜-ò<¿=Âs#ÝÃ!E óÙJçÜö…W…Æ©nV1ÎK,ç3!ÿj.Np$¤QUÑÚ„òAÚÙÍuŒrŒÑ3mÉ› Â*ýAż6bOà ÆÃ™ß1V幯vn·TBâ_ýJÒ,â|+'YÌ‚Ðò|,Dnd>ÿÚ;Ãż–TÄÓqŸÏù9kèá9Þjß爖S\”;‡1~' ö„“ñïñžðû¿ÙM^G=¿ãÎÐißÀÍtðKò¨¤‹Ã<æi‡LɹÈÇwG|‡ÑÂ%\ÄÍ ¾ë= ŒøÄa?éó“~ò6;o–ر‰MÞñÓYI~™öÚ¨ò¸M8Ó«8gßð@Ü ó¼iZ;›¦ntÀ¢œ©@߸$ý#?޹&p?K›Õ‘Ïi™p*jYƒÙôЕ©ïìpòpôM¥™ßX5QhN´ˆm<}ä5efªÌ87{FK¹¢!¯ô¨)t¼ÝT·S*±¿ÌS­–Žk˜–m70£ú¨¦¥Î¤TÈßmy­‚É(Ef‘´¼IeæåÉæI¯·‡Ø ºQUû¬­P²Ò±1•'¥•UI¶;^VÚwâß¿ºÿß¾÷ w^øëŠüç¶_qøÌû™ùùß-™(Ö$vìøÛX¢`ÉO×·t\e…‰QUå&—8ù¨¢¥rƧ•æIo²;+¾Ý%Íú‰7é Dú5´9Uj*­`™ŽQ5Y± &Õ¥Vmw¬X¢P&¡ä¸öÚKyÒI]JzÉæ ½ùƇ´MŠæyi¾`VÑŒy#èÊ*îW_¨ªKcêAMÓ–*:ª7©=nyÒ¶V¹|ÍeJš W)žÖÚo_ƉfMµ³“gOoL<iîçÍ™Ÿ¼3øÉëc‰¼ÿõü_¿1;òÓjo-O¨ŽÙ–ñRÄTùY9ÕQõqͬϨ®Ô¿ÚâN5©¬ÊˆÉ<Ç÷ç|’dN1ýlâ鸪ծH;1ã!.áýE¢M RjÓF( ¦;ƒ­1Á„¡¦VqQ®agù&Û¹¾È VòöQÊ•ÛB—ëè!ÁŒ³Ú9¦{GÌ". ¬ „繂¡6øçAzÃÌÆ(Û9ÁD1ÆUt1Ã.2¬ Üs–¦Zná&. ”Ï‘á}ì ýLs”¿1¯øky„«ø/"\Ä·xi®ˆ¨%I’ANñòÿ+’qnÌ0ª æ®?ÿž,JÃÜÅ“á¹ú*®)N ”E”3C!7±Ä9D… Q@ŒÏWU½ü'¨¿M$ê¸>TtÄiå`¨¡HÓÏ3¬e˜(môGDè£VÆùR̶°+úDˆÞšƒ(ßÉ@Ø”T1Ä1ú¸žbÏq‚|.äµ ‡¯6Ls=_ W‚s~ìõņ"ó$´ÐÂUŒþ;8‡ˆÝLÏ…~²\hS‚7RÌ0m丆y¡3Z¸s5ϳ› þ…hÆÝÅíáƒ9IágCœþ~Ò9›È£Œª°—óh^ÁM<AeÈÊÄ×ø!yœä ¡5bS˜Õ¶Ÿ·ÓÅÿ"ÍE\Ïò:’¬%Á[(ŒØ_(ȘÏ:ŽùJ ‡eñK¯Ë-/P¸Ü`9»\ñW>!Úì·E‰ ñ®hâµÑD~4;Í–¸¦Àu“Æ2. ÎMG-‘uæˆßF|¡PsF– |hÚ'"vF(T7â F´Šgü*æÚb£)}5n:Ñc¸ZuM½NÌS?dd\.m¤|v]¦ç“ÅO\ŸÊ|7!¨›jy:²q¢ê‘«+œ™Ð6kɰ½%ÆëU Šä™®µ£ÓÆ ­ •Y‹ó-/1Ód ÕÐQKÚœ®1>¨¡ÜÔ å…âfº•ˆÎ*œË]¼Ä3gUÏ3Q ™'“PÔ ¿Üd™©:#£ª¦”–*o0¾Ì±~õ»ßÐ9šl¨úËWç§VK·¯ûùŠK¿»øä—(<ÞZ78ùì?=S>›«¼ý«Q3ǵ h.4;£dTõ¨ªÅ ¨WYcxfÃÑøxiA&7%Rq­ÁYÅ#Ê dÊM¦TëÖ0_w¥ñ)e9јܴҘl¦zý³Š $«Œh)7žl°·Ùè<ýCŠÖ+©4¾ÖáAí1ñi¥-ºô7êQ6.N^ ÈdÆñ .tfP6co…YófħUVÖ˜s:®8°¬Ü줪ag ¼œKT&–ÌOÎ&ê*·/i}vE~Wílê¶J#IÅ)‡ë䦌«i‘—ÔœÖYlI‘gf½sù2;vùmÎC5nI;gI½È¸#®#Îp-1ç¬ì×›ñ¥¸»¹ ðPÆîQϦÅYË3ùÛyÓöà»G¼ò …› 6ók*ØÎjÞÂõQ? ,â>Î„Š­%|…ëù&_fwÓZq‹ÙF›ö~G;£ƒQ^æ!ÍvN½µˆËù!»C£Õù¯Â;HÐÏ¥ °‘<–ÐÎqâ\ƒ|‰+ùuØÑA1s”ײ‡wò{’40Æ·¸œ~ªW5nq?Ë9Ê2*h!/4¼‡=S 5\À4S!íaŽîñ–r}ä¸%„çfþ¸Ô½þŸñÍqwç<ÎMåA‡=eŽ[9ÉåäñªªwÞ~÷Æ?Aµ˜ 7]B€w²—úÂÝ Ü@Gb®£‰5,e/“4QB'Õ!}¤ˆÔ1"šR´Ðš«+ˆòUÊYÀ)&)¤ŽŸ2Ìï(år†;§9lüÜwÐÍZvs ÎPÃÅ, ‘Vâ,¥ˆ…-QSŽ0OzÛ<½šÑ5n,‡[«%¡_áUö`«Bk÷…ü‹Â€œ0D?/°‚¥¼Ìjxÿ›CÜL#Kùhšó vPÇ+¬b ÑÂá˜ÛƒsfíwraÄÕQCƒìã6†ø=E´ñ ÂAðÜHp.+2Áª˜žŸÔÇ^3¯H,£Ò­¹«ÿAû+Úã6tÙösv¿¶ð+§c6”ù³¤ïΦc1G²þ3êÒÀsžªpaÊtÔÉ„ÆJëÇíÊ7¿Ô= ‰@OT{ .bmÔ@™K~Zè¯óuiLª*rQ¥îI[¦ü¨Ö…Sªg6ö&ïØaÛ‹SÛž³í`tÛptôhÛÐêa¿/Ò“&>î—Ñ–¹'£\›4š¯4+W:_e¡\ŸµTZÙ!/"NiL¤TrZl™SJûÕtkìT‹ õ®pê ¶¥úŠçJË‹Ë hœo`ž¡^MÇ,[å`¹É1UYñJcå&KL'›‰ËdÅ ,~ÿ7¶ìODj§Ulp ÚèéÌ’E½³Ç¾ü…ìîù“ß{÷æWÖäÏ3VfrTÕ2Çê dä *Ö8ß™¾KN Þ²#¶n÷ä‚Ñ®ý¯[ïàI-–šhÓUjºÜĬ‚ÃGÅKM«,”˜”_k|XIŒùŽîWOy¿²EΫJ‰ÅE:,Êé(U>¨.O¦ÚH¯ÆaÕ³òsŠ ŒvÓaA¥lZÐ+š±¯Ðþ&ñ>‹R]æ÷CZFRYZìÍ*0Ð`wFQß›æ:› ÓGÊe2ŠL'U¤¥·îxý냩q½I#9ŽiËèJ[1"ÈÊD,ËH%-(6œq´_w Ÿ†¤™¬ü¬š){Ë-ŒZœV̈ڈ:v2Ìd¡Ë#ú²*Ùµ:°œZNÓq¶ØÇ‚§û²±ýÖ\®½Ï†Œî¥Æ¿É œf#E½30ŠË.çs �ŒÓ¦`äègš»ˆ„Ù¸ƒ\ÎU1WQóî@„&ÙI1U¡ª«‰‡¸6d£†¦0’£š÷çQRÄ ñ‹ØÇQz kXñp¶¶„×±5l¥pÎ3œ YB·3K…9 áÆçen¢ž 9Aéy!¼pÞXoQV†'s)YãçÞ71|ÞËýœxmu(&Ø—ó8 4r‚Õìc7KXÍo¸,ôѪª:ó'¤5‰D½!è!Ëi. Œ)iá ¬×tO#°—RŠ)d/§éâZ~A9ùL2Å;Γ¼ 5—G©cœ2òè )±s뢹ò Œ3ÆgX²&¯f>}\Æ‹í ÃÄ:¸“60ŸÆ0 `ÎL°>¢'¢/p–Óðס3÷ìÿÕ‡±Ð]”‡÷^C‚M!e. 9uÜÌ/˜å6ÐE”Z¾YnS`Ö$¯c9įˆ…ÏØÂ÷iæu`3…äæþ¨µQ÷ò¸€5|#0AW³“ Ô…$‘ ahÛêP{K”ˆŸ\™”á·¤y1jỈôï‹¿ñ——ûñ{t¯QÛ#±Ôl²óµ1ÓåšrR³ŽÒÀ®ó–Yk"êȞͳ1í¡ˆÖ¤–¬…)%iÍcÞõ!ât –PDK„¨ÜŒ¶ÀŽz ݆#¶23Ö+ößþRMwyi¢¦8Ñ<›X,QyÍðÌ]¿k{¸º×åQû+ÔÎ* ZÒÁÆ3 lŽ«/10è?âš²rqñZ}³úW«—Œˆ)i6Ü¥v±³'4Q”Pži6²Ü±2“ Å9³G5ls`LU¿ŠbSíNž°¤ÒØóçêÕS ¦X"&ÛÿïuüÙïŽÝz¤óÖ}C·íxæ·�� �IDAT¾P} %9Ú0¥,-*8þ¶_œTPg %¿@r Õš\x¬ iüÅóÃjKÌL(oÐ7hÞJ{†•·êRÕ§uÞÖGw}å›-ß»r(Ù²û ßkoÜÓ/jÓU yL{¾tÑ´’N¨Ï‰´$ö|ñ[“·>sâÖ}y·>tôÖƒAõà†=%IyëèV6&¹Àd·–ýµóu%£Â8AÜHD<£lL9¹Á"] ÆZœ2oÆ[õGô{,­>"¨IÈ-Ó›02%è±.+?-5vç™\Ó§r·t¿¹'°¦DE·üaýISÁÛ‰ßR»såŒ@ „Š&[Bg ?Йˆ‘œ1©*ëRîÊZËúÀiòi ǵdLfõY[¢0)UmyÒÙÀ—Óz36Dµäd_f]£9ËEgS¦3 =·ØoÖêžPÛè–߸!å‰70ÈtÆùËÙÀC†gà^ &úÙÂ#ÌP&ûÔÒ¸'â+j*BÑ߆ˆƒê𘞄¾‡§ˆcœ[èà"ÖÒÀi®áaº¹ƒ‘0J*rÞŠ}.º~îhZÄJ^àdÈqõ+ “ó°‡RfI±…ﲚ.ã‡tq4¬Uw±>$'%f …ÐWð[ÂNtîx¬ ÷>+©b˜8+¹4<ɱ’"v‡É½s ä×q‚+BnÃûªª:ÿ3ðáD"Á] ò.vÓÀí,e/„/Ã\Æ#á|„§8Àé°;Ér’iFéâ&^ › ÓÃ"ÞBCs=y¡$o]<3CŒ÷1Ì.Ò¤XC‹yš“¡/ºäñ°ã¤s(£9²ošÿ¢ƒü˜½Á¹¯í®°åQÍØGœ8/Íëü?'èa?{ÙÇZ:¸Ÿ‡9Ë.úø;{_£+'=Äër¢YƒM¤èb—ño´ðFV°Š‹iã³tp#Oñ¹2p-ÿÄQjù!wò#:âÞhå c‡é`+{¹€®å®$ ™Ÿñë mqCiOö¤qw§®ñûͲå†_±§Åž­y™×ä|&뎴ʄ¦¸krâ1˜‘Èz$jEÎãþ*éÒÀ‚ˆùMU23þŠL̪•FÔÌS=©%æÚˆªàœ(¨,⪜Θ)Ó9׿DSóÖ¬Û=¼¦/÷¯JìY]³§}zÏeö”eO ¦\œ|ø ³ »K~y« ÈÊ‚–©'g¹®ÞX­Éyý¶ÖŠ´j4¼×Ú‹FÔm¶ç –‘e½>? /°1œ§?©¼Þ@F<*7¬nHiŸE§”×,—T_m4_*-¿EwZy¡Há­?zê{ß^ñÛ–ã¿ú«+vÍTìZÖ¸«åäǾüîgf´¦TUûéÔîÏü¤âËw5è«0‘O)(œ‰¥æü‡G×m¯ZÓ3ò²µ³‚™õ7zü¸e“*‹$«M’}é²áŒÒ¥ßº¤ùå†êø¾Ï~ÿt×%¤gwXœ–žTÔd°@*.Ó§¡WÓñ}¬ó–ÝÍÿ~KÝ®å«v•7NÔœúì÷;ß¼«xϪ¶žÙiåãçë;a鈊ÅúJÌ›é2ÿU eq…ù¢YñFƒãªô6ÊŠWH+´à´Ê…“–´È›Ñ´Ò±ƒÎŒ)³¤Hé´ØGºÔfßù”箋üåã%_~‰Ù<ªÄ޵^vbô_¿>ï·UX8dTSTM`ɬ©uÉ4eª¨Ísù”žŒ¥i©:¥ªbj"Vç åGSþ=kcž«2NgädÕfÏ>#ô±>nu­mÓVeü(å+9·^â.Úùg¢Ãì9t<£gÖO+/³£G9Èí<À ¬ã%Ò¡(®‹ò#zy-Wrs˜a?É7éáס5ðo!¾o.ù÷¡Ð¢3È¥ÜÅ$¿&Â}L…/ëC¡Kõ)†ÃI+ x4—]ÊÅ|…^ÚÂð÷œ ÙÖ¯&wÜöF‹¸SŒR¢½¯àIú˜ä�Ã\–¥9,SÀa É«YN³ôQÎRv3Ò„É^s¥+ÉDH ï Yì÷²;T·ÍE$6sÇÃlɹ8Ç骪»ýî{ÿ§rõËD">äSDB0Ä0…Œ[à缇TÓ̦XRïcëBÆõ|ŠËY–ýa^`˜¦Š¯qˆ8A7{Buâßñ¼>|1^¡}¼z~Ê>jFßÎJæñ¦…‹ù&qîâI®ã0ù¬ =Õ;Ãáòùןÿ1ÃQ8Økrç&¹—pÏò»×þ&näã¼Äšœ†)_e-/çd—QÍ ¿Œx†¯3KÀŽˆyÞ”óqnä­œæ›DÃYö\BÁÍŽ{}à-Ρhò/¶SÃy˜«¸’µQQŸ ,ã+\ÍK!Àp7©Œ‹Ó>x³ü7û‹—"‘güû‚Hæq–Ôj,uÙ´Êù$é ¥1GSm1rö\ðqKV*Ï=UÊ“²9³åŒG,(žòñœ¹8jý¬ÂZÓ}2y~èÍ™fYždÖY“9¹´-D¡f¼.=û¹Ï·Þû©DnG‹D§æ©mò`Þè¦êž¥‹¾»e¤ðÔÔSžX52Y1•¬ô›Ëó'ëêMq¬Rs¿t“ø)mHB¦XnPÝ!}…þnÈ›k4Y;iEžé N.Ô]læóKµ†z´$Ô^hW¡h™L§ÅE9‘ÓZ7{ùeÔEÇßðÀC[j6ÝûžÂ½«çuçWö·ôäÊzÊ—?¼¼nÇòŸûåøö%§*J¶>Þv|ðâÍvÕ<ku©¡½WÏ.ê‹u,¨é¨ˆ{qʯÚ4ö™ˆ+Kˆ kZêø©¥‘Ì¿ùKÍ£‰tªlɾ’Ñ/~tæÆ§=ð@×}%ïûö™û~3tßC•g*ÓÍóÇ&_²ùôgpå3׿û «û'g­;ÐóÚ5=íûª.ýâ†Þ•cÛwÕÆ‹eŸ·&.˜¶¿HS‘Ae'´7ê¯p`Öè€Ê ޲ò*ÏGÄŸuÁ^{ç‹Î(ÊJ÷©ž²+¦uVí! ZU5 Êäº,™)zÃÃcþr|Ç[‚OlK~ù5Ï-Ë› z|8™÷¶™‹ŒMý…AtÒļ7ßü¨Ï¤\0c}T"nã5ŽtY6!³(§?ëô”TL^N_LY Þ,6åÓÜÁÊœä{K%)C9&óÝFÇÿOØ}ÇÉu×÷þNÙ2»³½k‹¤Uï’-÷Þ ¸ànÀ¦—KI ÉM„{ \ \‡b_pƒ±qä*7Y’%[½·ÝÕö¾;;³3sî£Ãu’_ø?÷¡ÇcFšó9ß÷çý~½U%Èš3ã⨩YExÆTET—Xñ±À‰ˆ[ƒ¡»"Ç.ö³OÙÓ™üwPÉN>à þÏ猱‡}\˼ð­q'¿$Æl¸°ÿ#ÎÍh«ø-7ñ¸‰o°«èâ"泆BÖÌ!ŠIñ £4‡ØõÃü‚SÄè#ÇWù{YÊdèÁ¾‰c ½Í­·›ÿ΋aܳó-t¥ÖóY.çlžåŸ¹uìå6qŒíL“heðm6ŠIÞän¿…qõûÝU:|t&wAòÙÀÇx#ì¨Ì‘fካÀ9ZÁîššÈ{S©ôs’>ζÐw Gz9›˜f §ñn~Þ“¡Cq'ó,G¨ç8'ø4Or»¨¦2ŒvßGž dîåÈs#ÔS"tq3‡8Æ œËë! #I=ÜÌ><ÉØx2?>²ˆyü‚>Ä+áZ®Àרcâ?ͪØðZ–p+¯aWð,ƒ´sõ<C-ÅlãY.æ1!,ò7\@sÌY”ÐÇ­Üó•Ü©\]ðâGÍ, ‚[hú8«b>Øø$Çù"m17RÏE|ŸÏðÛØZfq‘ÆŒf*ø¹‹Çø2Õ½ïò[ËŽE¾órì'_vOÇ|>ïG3§¬gIþlÖù³æÆ4ö¨ÎŸúâÕpZÎHʱ dÖSdy-ï•Âýž(27";©8j`®+gÕdTFç|‹[ GärÍÚˆªŠ´çËŸÈÞºköÇç%ülÆú”»æ¨mÔ9¥~Pg[î—É}W÷õVç®ÿmðõÿåý?ˆöŒ.ؼ,!˜4[£ú¤¹CЦÅòƦü(fQTQÚ¢ëÔÆ$êL,q0¯²B®Dæ˜y3g{kF¢Q§Ãy±#•&bòMúf×—)‘;çÈàÙ‡^;Û5_¸¤-7ôJpÞ¥žëÖ!&WœË•”4ö—ÞýËŠK^xî¦ÞsšŸV:¤®ÎÐ"ÝMúZ‚¾¡«¶Fö/Ž™_'Qme©™½Z3*Œ&Í^âù­Ç†×õ.=üW¨©_²«¨)3’ËEælœwƽgWÜûÞKï]²àÞ+Ûî½îµívý¯ÕDK×=°ôº{:õÝßì]‘++*+ÎOVuGFsõ{®:Û¿0{dñ¸ªAõú»4Ï5S^op›Ä\CqÑQmiUÅtY9nÓ´ubÞœ4TÃŒxF¦ÃØ L‰_N8/§,í͘¹Ç4‰™(72nÿž\t°4yýÖÌÐ’ÈksÆ¿ö@Ý+«+Go»ã·ÉŽWâw~&˜;n_ÜŸ*•.siÚk W—‰ÄŒ×Kw[=ëéJ+­›ñ`­[KÅg”T»ÖCcnˆº%ÐJ5—ç¼™³µÆ@F6kK\¬Ü;ÓÎlsɸñˆHΈ%|£�È ´v˜?dàѨky+V2“¿k£ù_m»›—IßÃÞärvp"4PB5¯ñ·ÓD/ë9ÀA~•ô’àw\ÎQZœJo`9;¸fFèÁK…§ÜEb’?áñœ›'uV`>×3¿a–&öóÁ°ûâ™°Z/ †·°I2—†„ï¦"L‹æ$‡ˆ¦ò'ifQ!æ÷©ü)3Ú﯂ûú…oüÿ¼ª˜ é[˜Ç;ée”V…òXœN†ÙËxMÍu·¿÷²ÿj\¤Róé`Œ&a>C,¡Ga‰‚žÃJžã0—²‚Ò0>£2¤Çw„e¸=a/T¡8y‚¼ôï+“{ß¶ +øþ{Fý wÊ!]h) ‘«ÂÒè7iÑú?á¿ñópàof ³,ãc!kcöm,¨2.aš&¹’$'9ƒQF ¤W9ª¢Ö°‰ >ªØ×g-}”s>×ÒÃ1®`/Pà9ÝäCçëôE}3ð×,á&¢âi:òîa;çûl ô1Èùl&ÆùœÇ²Y‡2æ„‘ÆÅtùP`;¯rˆ¼ÛÿøzdàŠÈWþ$Ð’×Ã=•»XÏõ¼”kÉ:5ÅïBæX%{/Ïx>k'F,ŽX¸0ïÉ"×ål*¶$¢#ckÌ™1’­³¢å:fìfa¥¥%jó~Ze<m&¢(_þÃÈÍ3ñûÖ—™W¬mÜ`~qjbÍáø‘â”ºn¿Œ»0·£5ÿÐæOOŒ<Õ|wiÌ‚rñ­¥ò WÓ«ºFg“d­©bS'ÍÉ'M"'µŒKö«Nš™ëø¨êñQ³C:÷ZÖ¯±I_•ñµ¶¢#ê+_9üñÇ›mŸ©)ÿ1ÏÑ!u‡ÅŒD^´ÜÔ´²:"=-©\ré«5Éÿ}g‡¾„T¹©˜|„YE]Úú#Å缘ÝrNÓìHZ´Ýñ¨Dð¹¿o›hØÙTl¶Ws±ÙòãuÑõ…ûƒ FÍÑ¿ÌÁBiHT0GO…ɪ gv>?wÏŸ?´÷­}¶1*_òÐý=ëF¿òÍž³N´?»8:SrdÝHz^oã ËÊGŠ™Û¨?&_fä˜Ò˜º5Åj2*â²1™JSsýšb^ ÄrzŠ,.¦No^q•ôq ò)ñž˜HB¤FIÔ÷Ç-.s¢IP¬«Ôª„e Û®*{躥×ÝÛ½`,?÷£3ëÇÖU»)þ+gMÇÌÍω¦œ–Ê;’×–ò|LkʆI s^¨ÐV¡hÂÚ•ý¶æÍÔÚ–òî¬C ³åšŸq,iaÄ9³L{ŠŸå,ÏØK0* ôÑu s£.,fhÄ ?áDpÕIïy5þ?,ñãeeô±.bŠeÌã‹ÄÈÅ|:ptì.|y׆[œ!¶4ËjŠhà Îà¥ð{ýÓpõÐäðz9 ¼ÍiLò÷üˆ ÆNÐÁ ù¨s;ØÎò4…{£ 6:e#fOX‚1ËÒÐg°%,/.€xöó[æ’ã ËÙçð} 0M5u<ÆèšU˜CS¸èzûuÑŠ!×Pý¶Üê0[Bøê¹ì§³¡“…Öˆšš5·¿wí5®~œJÍ Ý[C¹¶˜»y–>æò†!Ü9dé%IŠ&Êè'B)Cô±Œ×ùŒ‘ Áñ.ö3ÍRZØΪUdè⋌òßèb˜[9@û¹‘4OPÊ^v°7ä?³Ÿ¢oü¯‡ØÃ«éå�c\NI8Ø~}˜jNr;oRË2Þ ŒQráÑóDx«‰Â¡5Ì;ײÂ)dr–Ôs¿áMVÓÄÖÓÉFÞàJx/GÙÍéa¹IEpÊëy›™ <Á¦@+œ—ò0[)Žù4kù:uaGçÃa»fux8+ÔDÔ¦x*ü _qïA6ëî$ø&×"ðÞICL{àKQûs6ÖY¿Ý·Ñ“v¢•2–WZÑšuE±EI3ÐH&²º³N'Q®®S÷Œ-)_Ÿ‹8mÖqæEµMªˆ[H%´GÔåkó7ÿ¶ö¾÷7(›QVÚØ=ù'÷Œ5ïÈ–¦N¬˜ñ`Ô5AN¼èµ'óo|9©)«lÜÿµ®Xu±|BI›þíeRŽôê™#²ßò%Qñ.mãòåÒQSçÚv@Kµ©A•)Ñ%zˤŠÌh$rRËÁo~÷ð‡ŸMuާ·_¾èÑKžXXaâˆùsOH•šiÖ“k0Ø` Øl‹“íÇb3ýsKD÷YR*¡Úèa †ÔO\ÛýÅ­{ü¼üTeá=߸ïϽïðµ£_þÖôÙ;¦{:qÚ|'—ØW&Õp"±é¯Nþúöv9ñŒ’éénm*æ;Ÿ)êõÆ¡5=©lÅȉ5sô”÷Om>7û¡F.y«å¡ 7½s°)7XñôùÃêÑau]j2*³Z;ŸV•oÖwT´Üw“ÖL¨(“îqшš¼²²Sî­qa^ô¤ª¼â6;S–U›j70¥¨OUÔ‚ˆ§Ë%Ê45›UˆF¶¬ï[z(9Yk*ÇcUß½)È·ÎX—·w…ê^eQirQ¥\·#P³©Úวk\2hç„+kU÷«Î'3áÇ9/2w[D>PžÒ\b"*2.Ê(ó#Å­¼øWE<ueÞ¦˜Ñ„¯’Jü‹[ûE#ö]¢«ÕÃ[Iòúè¤i†¸’§Âê‰".ü‚„!œ•´†`„ÍÜBµl ­ëbŒkh¦ú¹‰ß°ŠZ:è 1uC\Åcì ·SÄCXÑÅì 4Pε,çMb ÑÍÑpõU˜wàƒ¼ƒûBQ®Ð{w‚­ ‡¤BÁñrŽáÎp5U`#C9ΧŸ‹þý¢¨€jüOãª<D]\j˜“o›UBSF<„’ï O aÚl9WÔÔŒÜþÞÓÿ«qõ\*µ—ôr'Ã[ÙF³Ì¥˜Ã求Ÿ2rîd y7¿!ະþžö„3àì>?J$ìpÊRÆ{x™1få}¤™›x8\¥øFŸåÎ%å”÷t9%<ËØPíÖ˜ÞYoðEê9›iÐÂ%¼Xàþ:ÿž +[ ƒäçaäíj®e#BMà{a'Íy,ã£Ls”mì$à}Tó*x7‹ÙÆþ‚¿§œ[ØÂAºx‘m\Ê<ÍföòIž¦ƒ).g+5œÃ†YOç Ï$íZg -\SÐ 8Ê -<õ×Qg~XÁ½ÜFOøÅ‰F_úX¼˜,ò©2—VÚ3m#ï¡“Á¨÷dmÉÇ6ØôŠyÝþvÆ¡H·³³s:ò¾Ä޼䉻(¯>®8ïó…ÜtÎì¨ãcjÓÎ͉gì™çÙV­=dVUÎü¼¦ŒX$û™æg¾:2Ö:¡ªÕH×Ï?2ó—©Ø+ŸÿÓ'2{WÏ真UÒÎŒ©>KO¥H‘ÎJe&»ÔŽ(ëµ?oQJbÌÜI£ZËÍœcs\¾IßµU‚"±¹NÔÒX*X ¿ÒDÒT½¡…‘ƒ‹â{wýÝýÛ>¾é†;ï¨}~õĦ=“5Iõ«ìØgɇš7¬î°Î3lÐ8¦zFiÁ¹0¤nDÍ »æ:~T}L¶ÅÀn+æ9Vmtø=O5=vöèTÛèÝO¦J£Ktîà†;Îy¬áÀÂè‘ÿyÿ%¿®J·í·xRreÏèè®kÚGÒµF[u'ÌÔ.•NšÂúƒž1±wøœý"‹Nî<m¾¾!éllþS®Ø\þìs_ÍMU®ÿ§óƒTÙM×۰DzÉùŽ5?/Úª' 3Z‹µNiéó·K”d47›©žPq–Ù7œÑ`ºD¾ÑP•ºãjRª'4•Ê—iÊ‘Ð1hlÊWæºdPCÚ¡IÕC¹æÜî‘ÜÊÁÜH>ÿ¯ŸJg:§DfõÌU6hxF>ª?ï©@u ¹Dm-ãF¦ÝÍŠ´Ç|)¯.£(¢4o?YvñébגּmÔ£—ä$g})ﲜqWÖR5Ù"7&bÎË;Á}<±+¦9ïgyôï}¾Äs—za½­ëì¿Û ‹ÛˆÓËa†¨¦¤pã¦àTÕQ 9®àw|„òÈw3Çiyž»B¬à:ÞÃP½ ™ål¥—«ÙÈ5á›z9#ü{x!¬m AŸâߨl2¬¥’~þ'“§+äGfŠ}ĸ 9“ía‚‘ð'<ž¨ÖñXX‹ü]6Ó„v‰¢áö¤0Š"áON í ásräm.ŒÿpMð§Ê†‚Ÿ[`2 ±Wjjÿ@LøùTªŠÓèáM¢ÜÆ[Lq;9I%ŸfaÝb#Æ[$ø£|Š2Þ x/ðk~ê"û%Ô0À]¼Î%ÜVu¼*„iÎ…¥Ú >ÆIº¨å0]ŒðA¶†hýËøŸŸ1:ë5¦ØÍfŽpˆy’&¶s;‡˜ ©óo„¦—Bô½0¤iÜê³WQË9Ï“áø>šØÁåà¯ð9ÖFle”1¹‚âAÆig~ÎïØÃ þ˜Ã|+ÙZˆùÓ¼g –¡¼p¯ÓÁ.æ¨fwˆVnä§œøDà_bw‡ý¤Ç<TlÃ'"_}5ØüS—åeLÌXV¬%°3pñÀCAûüà-××ûÝÞ_)ö/VóÞEM`Càü0ë7ÔäõGDâþ1â qWæí 4ee¢Îˆ¨Îë¢|ÔG-ãÚ¸HÞîE" lëÏmÿaÙ×:ÇÜŸsUÔ‘±Ï=û»'ò©Ôì¿,~um¶ÿ‚¤¾³-&S>3wLù~USÖ¤eV;Ò®·_[«D«¾jã%¦Ï¶{#Kì?¬½W]Ÿ¶ ³ŠŠd+M©_ì@Zé ..•>Q\Òs÷+¿ûáCÑïøªÞÖ28[5‘¯´<ª£Ìô1¹Jå¦k '¤öYRn*›ÖÎ ºÕ•—]eÇK.¨5¹[G·ùë W+ù?·¹ÿKuÑÁDˑ˾½*5ØÏ)¬¾è·¥Cg©zuÕ`ÿŠ”De˾W¿ýPÅïÎ)™H´é>¡£Çœq•‡unµ~C ©IÉ‹=Ÿ}éâÑ¿¼7)‰í^’ÑxTyb<ºoâⱿùÆ’ßÍk{zE¿Æ+¼<)ˆ¶ë^ã­>Íã’TWV¤t#cb³®?ní*o˜nq¼L¤ÂìŒú"ãØÜ¥=*?ªªTq‹Þ~‰1µåÆ£â3&2$•ÑËÒˆòŒ'f?™9ãõºé–üë—åì/ñµÀYcꧤç¨s(月sãú2¾;mO‰Od%²Šr.É Ì4JÛõLÔ;Ë8žs|ÆsÅ’Yqó²Òyÿwm‰ö";Yšóç|+殼/q$*Á¹\[buVSÄéq-Áçý›–ØàÍÑTŠúÀϨæIÞ`†!¾Ï;ˆó>¶ÑîŸH#œKž§9ÉÙÜÈ^6r[H¤û$[é {èo!ëwá4ó$ÜÁýaÛß{yGéçWÙý¼Ä ìàŠBòE”ëÃ<å�/ðǹ‹ÙÍ…ì§‚Z~ÌTÈ�ú,/„4ŸIîäŸ9(ìc†R>ÉÉñqv³»È÷ ¨On¤˜bŠ8‹\ŠXÝá4šBòÿÅ6ëöçS†º®b3in­©9ðŒìϧR}ìg g±‡m,¤’çÈSCŠ~ºÂg÷J>ÀÞ"º'ñ;š) mÿáªgŒ›ÙYñ"9æ0Egø?c[(åF&™ ¡´cfY†xž*ò”³‘°$YÌ^® ïðõ]üÖÛΤoçNG) ¡±òݼΠVÐOŽ•œà<§L»8“Ú:¼›³y1ü4ª#^j N‘TžaW2Á(ŸcNÄ–ˆm|Š—¹šÏE-´‘$Êo©Ê{ ‹ ª˜âËTåQâÄYÃßóF™ µÍÎg 7P–Ù¼Á;"ÃÙèà¹Áíßv¨Ùø“¼˜,wM`gÎmì`•o>îž„ÁÛ|ä^‡ã»œ-ô~`{à9ÊK]Zæµ´&£&ªÝÕ•˜Õ[¬ºB6£¿Y²Vï„T©þ@”úzA ¬ÏX—g¯x"ˆ.Iýf¥yy?›]–/šé­9º2wóöå[‡úW9^¤¢KÃ|çE5•Ø™6Z¡ªV¶[Û¸óàÏ1�� �IDATÒi â ÇH› ÔNINªH:^îd…X‚é@4i¤Gë ÆYÅ¥Òíº&¯ÙøúE[’•‘Kß÷܃EqÙ­NQ;¡rµ·j¬²3'FäˆÎiåQA» Šd§” æë™VžV’VÒ§©Úh‹‘uMúŠe¦•µé^ÿTæË'ÿþý“’Múæ9a@Ãá›··mœ—ëoNÎÛÞ÷‘'¯¾¯ihÿ9u†º´«*53¢¶Âä"‡ÕžÔˆ ©+“Ê5 ïùö÷Jv/8mÿT³ü=¥ÑTCt`õ—o<j^©tÖœx·¶¨|TpPqZ “sMÎÓŸª4K©h4PbxŸÇÕO(ßk(®:P3*[á@Jm`w­ñ £EÕ´Ž‹$4e$“úë4Ì÷|ÖPƧ^MU?2½ Ø»ºfzªÕ’œESF%Æ8ØÕ¸?0ÀŸ–« K8šñ8;¢âÓ’yu†@‚ÅQ/Ψ¶ºÙuSæg<Ç“%Î,’MÈÌ3§Ï‘À.ˆú›œ\ ,& SëÂŒ|'çGæD.,WS¥:åWe®Š[žõ/±"dyêŽq'+˜Ã<&BÙ|±vr$h –χù“‚ô<Iâ¼É5ü3Ç餛ma-û&þ™3ÞF:E”›¸”á±,ñΈf61Î.Ž3ŸN‡ƒ,O‡h:\z¡¯b$ÿýo)àŠŽRÏb‘¡– Kèçå8*ï‡Üj?ç²"ì,¼4,A~û5Ê+C>j††ï¾^Ê(+x™+ÀBÞÅ·Ã?°­¦¦ò87¦Rgr”n:éá æSÃA>¦ ¯! \†^äRh$à.^à,ª¹$¤³ÿ—H)§¶2Ì£ž ÐÁ(u s9Õì Ååìb•N=FgYÉ:XMOèÒ>+æ]ÁÿK ßÂ?†i°Ea<W„bÚR¦äºÈs˜vš “ H1Ÿ.®¢’-l¡˜µ`EX@õÛßG²Ã«“«ÇCEø2Ê8Æutò=bQçÇ|,p_Î8±6ä\¾’D>Ãê¨|Xã²”(¿a,$4¯%É›¼Yh]‹žšv±QëGYB–g™7‚]Cò£n¼ù°Ô<Ri}¼/jQ`—óGÔ¾åùt4¶oeðH(xY¾Æ–*we1R">csL_ÞÓŽ¦ýcVœxLu¥á¼±´XÒФUE&2îPBË“Ófg¾÷tì³Ô1uF¹ÖÀ3Q·eö–×~é©Öoºù…†Kúû×”ˆ%šT:­¬ÚȄ٩bÕU¦“¦fL¥EKýËQ ׯßcÙ ûÛ´©hs¢Hi­á2©¤É–ÇçØ”VZjæÐ-Û߸÷W¿Z¾âŸ.ŸPѬoZy^´Ñ@\nJy^´Øì˜ê!õQÁ¬â2Óq¹˜\FÉ<Ç4–›T_k8iªÖÈ€†A ;¬nÕ}\G©™v]Òï˜}é’yŽEõ§”´0.{òæW6.Œ–íþèóóžZ=¾å쌲A+íª0—=iN¹ééCŒª^l±Ù¬øœÍ­µýñ]õX۽וšéÓTœËÏ¡#/:¦ú°ÎR3StêšQzHSÔ`«ÉI‰j¹)å-z»µFÃjç:zÜœbË'T,–ÖNP+?">¤8©rPÇI‰s*•NKDE"‚1¥ÍII*ޝÐ×çw)×E]¼ï…ÄÑ%CÝ¥EâQåã^Ž© ¬ˆXµ0ïxÔp KiÚ ËbgôG]·Žæ¼ <Ešö"·å ÅŒLùÉô©w¸÷Ç%£Î˜¶$å‡)KIV¸.çKÙSf¨©À?±hJ}à¯xå"?z:øA"­²Ìœ”§sK¬Œ8Vœ%,‰£•q®f7]œK_åznã/i% —lXº¸7æ e«8–ÞEŽ_1Æ *YÇ0­ü*ìç};7g”%áÿ{ØÆéU\K ;ƒËûÂâˆùaÛxB»†áIn%L†0îß_ÁÝtPÅÓ 1@KÈŠ+TûÉ‘¢š›B/Þ ƒÎÿ4±êh£‡ö0m6–ÈSÃyF¸ˆ×‰†{¸Ðžñ Dæ¤R› mï‡ÂÒKÌp7¼-í¼ƒôáÓÌPÖ*6s6—‚ÿ�Œ(´\ÏV®$BÇcŠƒ 'B±u+»x[Ekô+H‚'h£Ž¡ˆÏ^dA˜n>zQ.g_øYhô˜â§ÑÆ FBµ�ÝÈѺ3ÞÍS¬àJvÐÍ;H“g7½\H gr F]ñÇ¥¡oå›H‘ä<~Å:>Â#´Næ¦ÙÍû NY./c–vnà×¥M|„Ÿ²€3¢§V1Í2–‡�ª`GÄb;7ñͨѨ¹xèe:Çñbãþöuç–øÍ:æ0‡¯îð® W»á Ï\˜xâʤs3†#‰˜ {"ÎÈY]äP…â Û8Ìj³%°„x± ªWhžp´ßpàéSå“ÿ–’˜0‘V”ûØá†]벯µåò½f3š¦ÍQSœ½zóxHN=ß^•©*µ³DY¿¶vÃe‚Yí–Ì×=¢¡Á@ÍÃÒc¯0ü–t½þåúÉŽ[•ïÑUÔ­*®¨[k‹õ¶¥•4ëë¹aËÔ‚¾¥?<oåC+g‚²C–HÏ*jqrJrP}‘¨|±L—¶QÕÅ ÆTgíÑ^k,F­‘s†ÔÕYn÷¸ª •SÊÏ´¹Öp³Þauû,ãdÖb™¨ü”ä¤d­á7-ê¾ùÕ%çìýë‡þè²Õ[JÊM7¬5Ro¨I_µÑ:Ã3 3e¦kŒ¾êœJãÇÌV[¶}Ir缺ãÉéqU‡õEµªo0xØ‚µÞ Dæê®78¢¦^t}•‚zƒÛ­T? ±×D ?ª<¦¨Úð í3¾]çœÆ5ê´´è«4‘S“ž!ÌJNé¯×7i".hèW“7oÄžJ+Znxj<hIÿ®1˜ÉFÌNx)«„ IË mNÆ´LÛÃF.çáˆÎI߉¸>fyÎsG$bÖ4/Ìš›ö óˆSŸó謚@µŠgר.58%XöB\Üìì)uQ»óÉ+^ë}{ýà~8íªÀ¯Ù‘±Öã.Z²ž2Šy˜‡‚UyÎ Û ÆÙÉN¦ùh!äq$p:2JïäYöðav°€«XÉ`]Éîð¹Šs¸…W ÙÖ˜?áÞ$`/Õäœðµø(‹ù gq+Ï„¶ƒ¡O¤àqXVÔÿþ·žäO‡ÊМàS$9BŒ['Ö ßÎo‰0Í-ô¼Íyq!;™CëÛˆ c -{So3ƨ§†-¤9I/á“_Xš•ª©yÿ°Zü8•:ú=.¥—»ùS|ïÑÎzN÷X…þ®$£¼Ê.q¯RIÛ見åœÅ¡pÄœjÿëçý¬å$·„’`áúW®d?oÐO’jîg;ÛØË¶p<”òÞA k‚ÿgJœ`=ϱ’%Ôø”ÛÊ·µ™ †ÙÇ™æ4vòaÞâP˜»†>N£Ž\Í“Ôs¥ž§Ã“ŸD4ùY`Sà_C·Ï(×2Ë>&ùçóöBq 9ëiÊéå5V1§àˆª‹9-oœ`kÌ]ï l¡š‹ØÇ>Nã¡Ô»‡Or)ϰ‰[y00¨âlæó:X?yCðr§±U>¼ÛKgÊýEyÅ¥g8í-­üzŸgNæ¬É8ÕãÜ@-§gÅ-JúëyŠºµs°Ø§¢çÕPs†ªGSNŽ{iÖü¼ÿUê´Ë)O«L+‰‰7[8~×óí¯µ ¼lÔpÊæX·@¾h²u4S1ûõÿåçkÓÛ[Ó¾™rۈɨÖUÍÑ›”*3¾Ëêf=¦Ì-¶å Œ”«,RuPóbÙ“Zã"-Æ{tµÉí·j™=%Ò,*‘éQÿò%c}éñÓ~¶L®"£¤ÁÀ †Ç»µ®²ó –>Åò»¬<©¥ÑÀµžÌ*ŠÉ¥•–ËŒªëÖ¶ÞÖ¤©~/YV*Z 7"µFjŒ«¬7X&U$»ÈÁrÓk¼Õ¤oLõ°Ú¥-y¾më=ÿVþé¯5¬hÓUnfRET~¡ƒèŒÄ¨ê¬`‡MFÛu]æÙV5Xä@N|².ýÆg7Æ6\ÚéÈl¤¹298žiXoëÍy‰:ã妇Ôm×9«²póê’&ãrÓÊú4,Ò}Ò¢µ^< ’Ô2âáË•vY2)Y$[iøˆýî™¶¾JY•Ù1‡f}«Ñú”L«í”>êSÓågäZ¿Þøã‰‰ñšoÝ›XÝitØd™3+-Nû“œ[+pxFk༤›*½9í!nmsá¸ò¼‹ˆòí2W´Y™uϬVÅ\›×º@ã´Ú¨Æ¼ ì‹YÉéH{rÚü]TqT} z†¼€_qcÌcAѵnûAôáeÑì',b<æ«]•äx…;y$ì ¹‚…<F/'¨ „_…Ñ‘ÕÔq’òï ìçuŽ„BÎgx÷„5¢žŸ°Ý)Ñ¥@C/Ð�þ†³Éð:hdApêA7JEèÓÛÇ.f¸„\H§›Ë÷8@–eœÎÉÐ1p+/p·††ò³XË™¼ÀJ^'C”ÛçbúÙÀ´s:{C”ë4G§',­-Ķ–Pñû¶*PL@@œ"ndŠ#L°?$Á·@ oƒ3Ĺ‹£55oïÿÕ¸úM*UÈBJ¡.âkáÎãÆÃ Vkânà|®a]¸^{‰Q(¦.LbUq!C RÌ |€·tª‰ª*l‚¿“Wi¤…‡IðrÜÅ1ž%Ù ˆoÓǪt{=Sñ3ZȰ߄gØÂGÜ„îö®’>Þdq(3>Íÿ“q~ÃW‘Y¹›ûØB [y™õôÓ—³+8¥Žþœbn{\&Içéð}í<Ÿ·—Cì§š |Ý40Ì%<\�Žù£ˆ×ò¾ÎÇi ôÙ¸%p:_f†•qç­¡ŽN}D¼q9£ÜÅ2Åž Ö=´,ÖûÇÔç4YíðãU®ßaWÚ¹û#wï‰?ym]ä醈dÜuY“÷$+‹¬‰š,WÄñÀœ¬Û¦´¤ôq(ꎈâ¨hÞ¢~«²~’óbà£QóYhõJ­ÓŠE2Ö–kRž½ú™Ôþ%é#‹*U,¶¾Ëº.Ý“ù“m»V}ûöÜ0ka©ËbµmÔ·Ó9‡´ä%úý*i¶UpؼGòr­¦Î²ùe—¶9Ù¡?§è˜Ö ½L¤BM½‰µ3Mc‰u¯ÕŽgëg¦&Ô¬ÚRyòã›WôN?×}wN<#•©0“Ê5§ÛQ®o±£ é­•&j ªÝjq‹Á@ô€%ëmmÑÛ¯q\U¥l‡ãÛtG}šR¿rõ¤’ùºvY¹ÒÎYÅÏ»dZY±LÒd·¶í©Uó¸`Åä‰R锥Є™Fý½ZÆT'M¥•.p4ivLu¯úÝV h,7=­lVÑ+¿ûòÙ7ýùfgôij/?ôÚ3_<í§5¯\>%1¬jVéˆÚ¥ŽÔ¹À3“òoª^áxFºJ*«/ŸU{LK™Ê*ÎO«oÑ «°§Zû˜Vç”u«X戵͚qÖ|cù¦wU­ëúâÝþ¥gÇR³ÍíÒ-Jš¶yÒœœ·Z-èñx^P›ÓŸ¶iÚ-¥>”טM©ÜŸPsKBÕ”Cšãnk49.Ÿ7Ì×G,˹(¯/â}ì[ yÔçDŒå¬i¶nÊÕ’@‘@/F\1Ó¡95[’Ûû³à ‹ƒÇgø*oñ@`"°Ÿ•üŠ;y<$æ/C¸Q [Å:n kºYÅWòSæÒÇ?ò£Ðž>—ÓyˆjêC`Aá¬ä9È·˜ !pcEèÿ*çµÐk÷^ö±I®`55̰%T†Æè¢‰€ï3Í= ñ~Ë»yÃòF6|ÔÜI„nö 5üŒ­”r”¿ _¯¯ U5“|œ}Ôe–JÆC¡òŠÑt:çóp8¼sd¹â!¯à?eSl«©‰ý1ðùT*ÅB¦H²‘å%bVåN‘? œùiž˾ ÄßMa~û�gÒϲÐþ¾.¤Œ¼Ì ë™à^âÐÎørh^ÿ<¥tqïäuÎóøg…„‹3©INsy’ lå)~Ãe q”s©ã0s8‡6’¡ïm³ª ýM±ˆIZx‘ý,1…ŒB$äB°3H³›YJÅôÐÇü² XGÝx…8gr„Ó9ÂE¡ï³“ÝôÓÏ•´†øËe¼Âqîmñ« ièQUY‘‚½%bU…kgUäOÕçœÍ¯òîçóá‘´QâNGׯ‰¬38±ßÔVžwZ[ò†ÕÙïîËÇ3æòÕNaŸŒìïÌ9áÒRëOÆ}4rô Ö4zï´ÅœXÏEü2/–÷:•LÌL˜3ª—Ÿ²>ª©ÓLJñV^š=Ÿ 2gS“EㆿL[’ÐY&¿Jϰú™«ŸïÜ_?~dq©DF./6«½ÌÆtÎ(M©î4Pæp»Éó’jûd&m‹HV8?mþ<GzTT‹­ÔsP뀖:ÃMú'TNIö˜+ݧ餖‰DSw釾³ÿ/Ÿ;º·©¦òÍÎFý‡ª_]Vsó–ãù©ãš»ÔV›Þoi›®¥Ý2 %)sœ,’=f^‹¾„`@õ¬øBG‘jc*òf×z+¥¬ÐbUe,­1:_×”š'¯ñÔ˜ªZÃ5Fsâ-NŽ©šVÖ¡ÿ¸yçy¹_SL.+Þh LªWK Re|@cNlREÒäDFrí%25FÞöÆtß‚‰ß9,¹ÄþÙ;~Õ;Û1™Ž•+¯7=×±£šÆÕª9® Ûþ]Zª¬Ë¨è2>hN›`HqR¾CWÆð¸9Y‘}VF¥rJk.U1®©Üù”G¤ÒY¯ÍØš0S‘/Z|ä£ÿ2~ÞÁÑó&¿ñÙü=—æm4"ÃZ¢F÷†úëJ4¥Ô°?iÕ¬_Ç<ZáÊ„®œÒ;‰r‰Y‘&Õ£ %-ñ½¼%|‹^ÞE4baÔL 6f=««í˜ö$¥qg¦áUb´Æ,ŽØÆY'Gü-­AqÔ’jEúË#Ú“æfN5󮥋 ÇXÅ6Êy€e¦Žÿùw†´¡(üÉE,â 6³•µüOn¦Š=œ /ìÍÚ¾%œ„M 9þwh XD–F–ò4k8ÂÇd ø!8Ÿ!Îe§ÓÁ&v‘`¸˜ ìc‚~I§‡Ra7õtq ½lf +ØË<ÚÙÇË|‚^*8:Ë ±ÔÖñ å!$áh¸tŸk.v„õW¿í!ée¬ ©§'YÎHMMôÿw\Õ#Æ0µq}¥9)V1DƒaµÐµ|!£œÇhX`ÜCMx®š¶a®V³9üËĹ#Ì1M-,£„ 4ÒÉBö²•Õ,åt ÉÖ°}¸°!œ 3Þ{8#d±ÇÂ|Øv„{Èÿ  ¨C+(#É�ÕaÞíz³…§˜d.³$”³Ÿä 4‘aKé¡-by Œ8ƒ ®`e;%|”¦˜Eôó󈆨O¶…^Äs©ùPàM¦gËšËìŽX™veÞOiŽXõf Ïù1— ËõºmØðž "xïs.œãÑ÷Y^ä»?I¿šhÊw~ž\•+ï^5sò Þà—%vLà ¯ÛvúÅÙy×&”M;–·—û˜ qSS“fÒŠ"’Å"Y/Æ\ߢ¥\.êg}§È1z,°G“NŽXQ>-Vì8Í'%ƒ«Ÿ­ß?'~d^Zù í3¾±¤ÂùKå¦Ô”m7p\Õ*]êj™0Y"Y&1®5%ŒhêÕXg¬ØtL´Êx‘,ÆU–ëoÔÐ¥m²8’þâ·ëŸ[ÝøøY%ñ©cŸ{¨éŸnï×kùÈ·¾Z<oÿ’gÚ†4Ušm04¢¶M÷ŒÒ"ÕU¦râíº¦$cò9ñ½–µéíÕZk¸Ú舚5ãÊŽX˜QZm,­$¥ìÆyzKd†ÕV/6Û­5­d@Ã^Ë*M3ï4Û†Ôw:Œ2©„™q•E²Mú&TÄåVٱˊcæNJ«]gwVQ­á¥;­Úüà?,¾ãËHL¦ÁÐÖŸüãy»{²q¤ähËQùV©Œª½–™ëдº•yË‘!E¥Ê¦ÔW˜š69­i±ãVMk]êXFqÔl©é.åͦgÔ‰Œ{­B_F{±²iM å“þ/c÷&ç]Þ}ÿ3m{ï»Ò®z·ª%Ù²±å† ظ�6. ´$@B „$$w!¹C  â0 Æ`pÁ½ÉVo«¾EÛëìîìN»ž£‹Ãy¸žg^J‡fg¯Ññ/çù;¿ß‡Óû¤Ô¢è®s‚o\^42›÷hƒEq׿\äMÆ”jcZèOi¡?ïÙ”ÕëT—‰¥ÕLy°F¬IÛŸ3<é-\µ.«-+^"2ÏØÄY%Ò¨,±§Äi?Š»¢X}Ê é„gÒ:8uA+Ó&«C‡èL?ßâGüÍÃ^ªˆŒT©Hû*k‰³ŸJ8M’ë8È3Ęd“³ŽïbºÉ²‚¥¬äc#ß%I†ãaŒp„RÊÃI!*Ui*â<Ò<Ã{ù1ËBØù i ûy¶…%Ê%Ü¢›Ž2{¦9\— jÄÕ<M£´q%”“g˘!B)Ëx‘kå*~J- ¬âê8ƶ ©$Cœf–ãáuêy"aòw_Gß´wÜêƒ ;EŸQxª}œúýQ‹ëR© ]M¦,繜좇NVñŽÐB›bŠ “TrCXBä|pÇ™töH^@cÍ$ÞÄ.e:ÌûÍ#®ä.ö„Ò÷òx×3K%ײ IóFø¥<¯„²²ß¾n gÞü*Ôè.£—«ØÏ4Û9ºd Ì®‹™¥…q]r¬âBÚ³:¢*8{÷?ÕÁY¦Æ¥a„rYÂCŒð.º¸ƒnaUäìݱ†µ<FB§˜æ?£ÖD\¸‡Oã ^æ%öEÎr-³•C|—1©wûçûYâðÅnÆÖ>w_äSÏñäþÖïþŸ©TiPUž]ôõÜÞ_ñ:ÑÏb{Ê»û|ôÜ™ñ£ˆqù¼çØÌff¸$<!~-m'ëØ—“[£t¯Ç>ÓøWgmƒš ã9‹¢D<Ö 9ei©Sã~æê©ÙÎå'«F5–ùY‰ä"kOûÆ´³ŽGTùÒ Û¥&QLõYTed•c½JÏuø´%DŠQÓÇ%k•5šQ¶ÈD—މ…zkêO\«¿÷ÊñÛ^××ö•[Úukœ·³e÷7þ+S=SùäÖ¥b¹£I•š_·y»çNjï4±ÞIÕšg”U›L+^àôS.ks¦ÊdZÙQËçë­4Un&/Vcò”%5ÆW:2£üu›Ûô›Ûcq»ÞqõE2eR †‹¤ëŽª?c^‰¹*ɽ֕š­4— DG4Œ«Í‰Åeó¢ ™1µ³J–¼ÖpèïYöàš6ƒãêrû6¦?ù˾±)P+£[G r¡»Ôå•%Uµé[èÔ==:ªŒVÉ•I¬v¬H¼VI^b@K•d‰Ü¬ÒqÍ)ûÏ1rR5Esêë™±o­è¸uys¹.¾¢¢î]d"埦uT¹©Ñì°Á&EÓþ!ð6p8îü ãJ¾¿\Ý 3Ö¦%³zãÞ–WUÃò˜u9‰¨Ò¸Æ:É´ŠœÀU³¦™¦ºXu•®)ûsJã2‹r4bÛœ"QíQësDœ“=+è™âB^ä gÅö|Ý'ž >°;sßí1ñÀÑIJR5šg=ÅN²\à r¯ÒË$Åõ¼ÁJè ‡;G9õO‡°‰£ü±³ósÙÊoHñ>†x©ðmO…MúXÁ÷裂&êùC~A’¥ìáiŽ æ¯CÐo­‡^¦8ÌͼLÀ"NÒÇ4‡½ PÊmìä�ÅS¬áYŽ2vRÐM‡há§ òo~ 2ü;&¿C,ì³Lðnö‘e”7°·æ¨­íÿ=sW_J¥n ktlãÄXÉ(iþ‚I~L’u|¥ah²“WÙÉ)>ÁÝáµ&ËgCmsôMßÊÃDxý¼3T¿•Ÿñ:<Ï0 ÙÇÁ0Ð1ÃßPɹ*,tføZx¦èŸZ=M<û&*°ßZŸÿûë<…DóN¦ø Ëx•?"}£œÃèäun}Ïü€ÊÀ?žä×d£.Šª üœwQukÔÛ÷²€ê‹üãI.á~Þf«¹Ÿ?å|Jø G"¾¯wINKÎ×Ùss\eÜçsþ“6r4QÃ÷ÙF­Ý‰»þ+?Ýí_¿åï+¼ÿ^ýŽU§ìÙciñÌØ† â ù_ýÒk·E^‹ÍÇÕ|ÕÍIwÿëû]ZoìË,iОsMVSÞxÌŸÇ%Õ;ùËšåÓž‹ùvN,°4cETÑ„VÒVªYó@`û¬Æœ¿Œx{Œ¼á”ùôæ*¬œ¹ú —übÎõs^jUWj͘Òæ'/6Ùå/ÖúØrC’£QǨÈK,ÒuÀX‹’ˆøB§ã¦óâKt•¨œV=­¢Rò„¶J³S*[ Öœ“Ø;vénÛ^=qËëk¯øŠm¯L¿ïçomxAwÐþØê}°«ý›ÖÎÝakµÉ„̬’ÅN”™YíPDb\í¸š{¾U_›¾ãIUåfâr-æé&U7,1["“V<ª¾Cw³"“Ö4l7P,{Èêr3Yñ1µ³{?Ø�� �IDAT%f{´G+t.q¼ÜÌRÇOZ\,=­<­hL]‘t„¤ÊuöFxÅùóõ\Õ·ïD÷öñ¿þVÛ ‹›ÒµÝ•óž[Z2<é¼ez‡µÎ*-7Md­£‘ùzÊ%5v83¬­ÊÜF»+Í·,¦8+ž‘«63DÙ˜î´ú ±F§fÈk›QݬxTtDXÓ6|EôcwWýꓳé´Ú-ê÷¥1×åumvtÜ)y‘âÀ]Kœ×mmÔ`ÌcVP•ugÆŽ„-¶Nê 乘…m^Oº‹ÍÓ>—Õ˜w|Ö#Œ±ŒóÊçœXX38âœrU §ÝÍÖÀ¢¼öœ¯ä̸”ùBÜÆÀ¿GüïøÔ{r§ê©·FþâPpÕýÁ}9SÀâäÌΉpnÄMüœ«™åǹžC¼ƒG¸:þ„•!u¢…si‰¸ˆ;Èò7¡6öYÆCvè7idsœOSE9ÿÆRžç8Õ\És\̳,çuÖÓ4Nñ’¬<Ê}\^×’¼—çȆbŽÂàJ1cdœÍ.ÞH òvnã︔ï1Î!v`mˆÈùSªCäЧy•8A†5l¦šSÿ7Åÿëõ[zE:̆Ì0Rý „?ª­=ð{¨©T¡þ–äZî wà+C'}+3´q5ûø2å\Ë.2l!Ížd-•\À"~ÈNqó)çr…é³°RW°ë>FŸekH6ê+Úî# Š7ã°F!ï? yZà µìÿíÙ0KÿÁeá÷÷HÄ–˜ ¥ü’ÞÊi,�¢"²1k¢š(¦+Ôn®#Îÿ |1°ƒ·ò ŽÊ9—tÓOmü9Ť©ç�Ëø$¢n <Ã.†¸‚%qóŽÎøjÎù4¿ ŒÔºtÎýDÌW‡ÙÌÞÍB^åüüìn'^ñõ’Ø7Ùð¤kæÜv‡Ï¾à{yÇ™ ³ÑÁ¥ÁCÍÁ–þú7ÿZ÷ëþ ÔW/ŠŒ½¯Ò\ZtF4§‹ýìœW+(u2íʼZF¦}6ï[Q‘¨©˜…yGÇýW‰måR¥†Ø¨©ó–/D¥J\ðͬ-~Öbíb¥Ç•F®>élÉŸ¼£Ê‰ùöι½Áø„xÜÁ.Gj .ïQÜoí”æm¬W™72%švNZÕ-Qé.³3êŠ9¢#¢¨ÎØkNÛÓ¬~‘“C§d[úŠOçç¯iûØÿŽ×œþò7"»7ô¯˜L¾±ý 5Ù}°EÍSç¦]è¥) ™z#múŽZ^o´ÒTaôªÇüeµÆŽZÖ®çE&dŠÍƄӊ¢òDÒŠªM,r²KG·ŽÇUÕ+¯4õªó#,tºÙÀ ¦23M °ŒníC5³5&"‚]6uèJ+*ô«Zôh‰ 6Ù•éíÛÒ–šxõ–S‘ëL—OÌ¥{µd5Ä)Ì{•›N+*ôÞžtÙ ²a¥q±Y‰„ �dŠŠO«JWIVÜç—C®lͪšr¼BûE‚ #b“¢Ešò^Ie–]|tâµÏý0ÿÐ’œÞJ+ê\8æ‡y/rÎ&3C¦ëŒþ”§Lk䉬x^<a°Êü”âoïÓSn0í»Äó¦“,ñ9å<ÁÛ¨¨Z(*öé ÿ>ã^–º,/6ê¡´‰³TϦÀ[v˜yÙÔ¢¸æÀS%yû£2º¼¿¦Mz_üg_ËüAÏ^fx˜SÎ&ž^X·4¯Ÿåd9Á$c¬¡‰^ªi™mrYˆ|8îÝùBÛØ…ѳÖÐö{-o)Ì;ònÆxŒv:àÛ|–.2ÎÎ~}›í! |sÄñˆ¡'ì„äVÎp?-ƒÂz3ÍÜÄ–SžïÂ÷¿<?ç;ù>5$CŸûE쥘ÜÁÙÍ8I?1Í<¶…íw2bvÓ&ÀÖ^Ƕ7±ß¼&o‰×óoµµ7ÿž {2•*`¯ ‰”>rÑÎã¼Ì"Ú(cw†Ã¿ç„«m/§YÎ9<E?M$ÂÑë#Ô‘å×,ç9ÊàHˆÏjáGle­¼5 ®£‘Šp­ßÆÅTr/s¼B„5œfMh' èæX8ê´8¤ƒ\ð&þúæP†V0Ù¿FŠU¬ Ƕ‹?*�ÔYL 'ÙÂ`Av œf24+ÞWẜ 0–±„x™.úøQè+y/W“fšOq&|ž…ßñÕ¨yû¹š&ðlÞ˼J”t­¸2%’¡,𺷤%Ž+(Ô –³â\8á§ý|SÑK‹nÊvm‹ÞÕ\ùS}Òm/XyØçNø/zeyA¬3\ëò)op4jUp6ƒ;‘r°ÞîqÇ(ÚCqÌ51ã5*‰gˆyWÆÏgåSŠ3ó’s^ "5¶¹hÊÁÀƒTÊù³–D$ÒW?ÑÖ™9Ù\oQŠ)‘nëKÍÌz­Ñ TuˆW›0™0‘U³PwF.#¾NW•Éq• œHHGõ5Šl±¯WcZ|¥£å&ãêkLœÑ¶Õ¾1սǶÄ/>mI÷žjßW×°·-yfe´·µ|Ê‚šâ“Õ•ÇZæëUwК¥Ž×k×3¡¦0JÕ¡{£Ýóõ›KªLÈŒhXíP•ÉaE2h‰)•-ú5µëÔÜ`x©ãy ÇÔU›ìÐ]k¬]wT°Ðé Ó#ê´”™YáȬÒY%¦+% 5À5¤”æÅf•´é+$à;tåħ•°¦öTuMù™Ñk_nß[{x®dNY½|•$‘"éÇT7˜žRÙ§¹CO»ÉÝJç™èÓš4±ØpŸyg46™\ãT«áC.+‘™‘SѦꔦnÍÃJêŒÉçt.ËÊΨ¨eû–Ç"ó¢}§gK¨Ÿôh­ê ×t *T´Zž”™õhµuq-åR2ô³ ¥7+ËI­²¢ÏmÍÜó÷åÒ3Š¢–³E¶”8…y]åjjœ7.Cåˆå3fJ4%TåäU—ú£Ç|°ËÖ£±çþ&7óˆíå x#p.»iÌGNêÈ›9Ç‘K¸‰,fuT÷—\Æë”…nßKÃØÛµ³”ûXO R…Ê^Þ 6Ò˹ƒ.þ˜>êçS,aû™¥ŠƒaIiŽjƒÍYVó—¼ÊºˆmýŒ½ c‘`„ NAã[Ék!au;+YÂ], Áµ…É6Î¥ŠŠ#p˜Zfèg§Ã˜ÆýäYDIˆµsÖ±‘1ǶP¹2Ü>Æß„e*üÃÔ›öª ÂXõ6ÆBòCè«­íþ=½«‘Tê%*i&ÃE¤Œvzˆñzy0Ìx,]È…tG ï *g¸.âiPÅ.!Lè�oórMûzÉÑLžû9MM8üô‹¹!Låý€I¦H°”ãT‘àä›dš…gÚû¦½¹!ÌV\Ê~ö†sã'éu4E‰xG`†_1H [ØÃµ,â4y<EŒº¸ÎœGÛx6êÆø¸•ÅldSÜåù³nÍqvs€qâ\C%¿æ<ê‰g Ü¥!ÍåÜ2ÕÅö0o¹šíŒ³”;}ô ?:葯ÄfŽþ•$XKÅÔ9ÓiiMtä’ÈGdwÏzþU÷|ô?ý¸Á=o—ªgghfsàÔ”®¨K"æ()Ê»—aÖOžMþ´ÇœÇjZ"¦sæÏz¦VUÎ⬱r^ËHÅ5æÜUáSE6ÕKe Oû!cÔ7ºzÄ@Â˹«g—v¶4ž\t̼±2±¬úie¥DŒ­0Ø¥~ʡ洌iÌ Ê¥«L7Ë *‹‹®v¤HÐe¬ÊÔiçÅ$E ¹"ÙÕ1¹)• ÙUEâëtN©¬š·üÙ™Æ™Š‘Ò "qz^²q®ï†W®½§¡Ùà+—8‘QD$"˜TuÜÒ9ÅõFŒLªÎŠO¨îÖžVÜ¥£H¦ÞhD+7=©:­h‰*LGÈŠ·é{Âkls&/–•ÈHpNL>.[mbBù¯]Úl|Bõ´ŠŒD¡*X&•¯’L+ÖtèÔÔª¯C×ëέ1QnºùXU¢¡ëÝôè¦:A?­<+1®ô%綘8c~FÉˆš”’…º›Œöi¯05ßìIM¥"£ê96ª<PÙèô S¡¬ô|шH›‘QŒüý½uO?­r¡éQµã æ–¼,‰¼úá¬?žrUÔ9Å-³Nd]<¨lÖ]¬‹›àé˜DÚ²À½Å..S?ga±±Œö9?¶…;bv”º0%]«!«3PšP”÷p`EàU(>#ÇòzWÌ98Xi0î}³^‘Øjòè™ù‘×£îØ]tÁ¾æ§þjÊë²@)K"D<µ$Hgõ^mÁ~ûæx• ãÀ8ÇXNÀ†ÜjàAóãp¸u=ëèñ}™0Í{9ìá}<Ì›8Àn>^t_pØ·ç¶SÁF:)gs€[ùZpÖÄx*„ï,egxô/4AnæYšî1_¬â T°]!c¢–,ƒ‰ÚQXþ RpMX׸8<Ç'ØÂ—…„ß.ÞF7å\ú‹[ØÏµ¬ã`˜4™yÓÊ|9yº(å2ÖóŽSF–éßµøE*5‹/a'U¬æ•þÛMEa‡-ÚšOq%¯ÒÏ¡° ×ÏÁ¸ç}•FÖ²€~&énŠkø©³µ¦÷ó=le. Í oð^f;ø%⦸cT²†¼•ý¿ÃU\Ãrº¹>œG›û“tPÆ~ÞÅ L„°ý[„p°ÜÎö³–טc;éáÏ PŒþ@gØ�› ,á)zx'õ|3°šŸÐÏz.ày®ç+Ô°‚Ÿ3ÉZ®g3§¸™~ãñG]pȯñ.þ˜ ëÑ/r€Ó\àòÃvÿOüÐ}7ÐÌ4ëºî#Žžä#ùý ûõJj§{füýŽ\·-°)®6V:w)1–ñc.Í•ØÍ’yÎM:ÿ21—:›””:V­nÒê9‘À¼ªœæsÖ6Wk(šQ>+–°9îíi§2R9ÏÔøÈÈñe“éÊy¦×èöWÓ.)“]d¼Fú¨¦•Æ'´6™Š90ß\Éå­ÆÇÕÇXg߈†‹jU¾Õ3qÁz{µÇe2ýZW82¦.£¤ÒÌ´ŠŽU˜^|°toG]ä‚—®}0Ñ5³òȾ°ìoï[›Q”•˜S|F[±tDPjvRu‰ÅNtkËuëX¡³ÒTZñ;ÆÕ¬t¸ÜÌœ’¸ìy^»Øó?wS ºÀé¨üˆú³•¦Šd†4Æä*L—I·´Áðr­úkǵ&*MM¨ŽÊP¶mÎŒ©MªZäTRUƒa"•’Cç©k1Ðk~…©®“Û黩;?=_OBöuKê;eñKÖ8¹JçFÕ•È4êÔØn¢Æø¸Ú¸l©A­kêÕQÑ«¾Xu^ÍÅËÌÖ;#—Ò>k0õã›{ÿÓ±2 OmuzBó¬Á¦ÏÇŠ.οzoÌͶÌX•–šqœu¥¢ód3æØ’Oû9+#V.W5èkY›òÚf}1çS.©òt«m)™¬‹³šsÍz-«¼ÖÛ69™³dNuÆtÖM9 žÈY’ó ®ÈœóZ^›ô 7Ùü|Ð9/xâ©`f(}ïÓÙîrxGpúáÀV1/æÝAÝWýŸGüדo°›[9Î�ŸdexÊŒð�ïf+å¬âN2ÈVæB7úßsšƒ|„Z¾C]!¢•iH²‚»8Êíá´o’‹x•ëÃŽÎå¼B_Î>ÊÕá1÷ö06’ä“¡Nþ·*©aÆXJM|/´žÇ \Å�d—óR “c¬æ�µ|ˆáP»ÑŽ_®ƒájŒ¡°ÉRHV¯á¤YI%ò›pªlæwðFÇBƒð‚pÂdÙÿ„é¡Tª…+YÄ^>Ëa%*Þ+/æv6r€?¥$Ü ÷íÜÄNÒLpqÞ¹•²Pu›xîM”Ž}Ìp9s<²Oñ·œÇýlá*vò¾ˆ…ÜÃ~îæƒäÃÚá|ÀöQÉ{h¥$ z³œ/ò/a=MóiäEF¹–U”r'Wñ/|™ƒ,ç•‚„&â4?1Ì`Œ[#ð=:a–Ü1Ÿ¼Æ{æ®c˜—ÃiŒïpß%͹|‹¿$oaœšø#ó>öÉžG<ˆ¼fâÛÆ >O†ÝŒDüKÜÊüåOÇ÷|å‰àGÇ={[bºµÕ”¯òoQó‚B¨òd·_AïOâ5?>⦱ÈÈ- äUs:ï _dWÜ%¯qA•êbkRþ'¿,s]…-Y’>Yêò!o_àÜI¯¥ìœ–™³¤Íᤨ‘)‘÷¶¨Æ)GS>]/’±p¢>¥Qç(ª”+¯üóÏ#¦zo©V\f¦[õ¬[V9•ÒpÌÂNÓ)Ç“.m5Ù©eFýu^>`m»‘IÕÇ .2ó¢ —91n¨Ó¹Ã:Æ4Œª¯1qЙ˜…å•§Ÿüëçû¾þ¯ë÷ÛmÓ¼‰©×m.’9’_]u cí“M»+–ußýùw¿ÿÚ±þÕÛ¼\*U€$cÿ¨ºe½æo°gNÉ<½',î² ÆD£¡¤Ê7œ;¦vLÝ„ê¸l½Ñiå9ñ)eRóõN©˜Q–RVnzPãÃ.h7R%Yoô˜eµÆ–81ª®ÔìŒòeŽ×˜è² Ôì¹^?iÑa«º,H+N+W“‹ÉçÅæ”Ô˜¨1Þk^¿–õöôk9Ï«Í?¼bç¾ÚüìÊÉéªSñÅN4L)Æ¥ãrëMêËÉ,ЙÒÖ£60U"ÓéœUö>çdÔCÍ®0t\c»tJ}§ù5Z²æIf[Kg?w_⊟Í~ù†Å‹_Ü<nß|«jwÿAî–_fÓ—çO3RGr¢m:Òê2¢)±vµSÆçüŸˆ›kE]Ч>o&ª>¡!P×î†RÅ#ΙPŸugÄ=7ç ç=IÛœ5g ¼ToeRGÖÜžœJœŸµ9P8—MìŽÌm VŸpç]¾›^| ûÝýçþüUÿtÒG-?éäž|êó–õÙ¸{%Ÿfˆû¹†wòmîç~ó¾°gñÝpëª)ÃÃ×ðzèU/q6ˆøX¸:NÿwòÿÈ¾ÇæbYĈ„zô8;ÇòFÈÅ(âV^bOÈZOχéÜçX̵e’¯s/L…ƒB_|/§yœ"Nð§ø¿aš7ø<Ï1Jœw²ŸkBóÆ/¹ÎÐa‚웵E|¨€L ¡Û¦Vp„¿æ•ÿžzû@xµúí Öi>úæŒÆïß®žK¥–0ɼÁQŽÒÉ£$‡Â³Ÿ²ŠËØÃ,燷¿ZV:{Ég˜§ÃtÿùPcíœd‚J.&àn°š¾‚÷%âmQóIªhS›æÿ(I¢t³œ3Œe×›\–£œ&~€ù¼ã¬ù‰¨í^ÞÂ!Ž1ŽÂ=º�–Ðsñ@ƒLÅ} ÔX k\u]ĪÀ/9ȳ$dG­âHÄM¡´æV긌¨g{³H³ÇÂü+ßú£ä‰«u_¹óªÈæ"®6}¾Î4²„©¼)- jO½%}r(¿«ÅŸ<Ûxªhrô+9ïÛYfjÎ"Nñ~ù_[™Êâ[{kÜ%y0É>H —äÏ_žžÓ•sï ,Șœµ'¯)°,Ð2æÑŒ«ÓžÏÉs¸Ê奚#&Çü›Æ#Šr6ÆÌËÚG´Òò1?ˆ¹5g&)÷HƒºÃ¾6ñÞ\õÜ[çýì&§5´¨6NJÆÔ§¤˜S_*1¦.á;ÕNŸ±mÒL…}mä-:£±Vÿ|C³çU4,•*1Wgl¾¢‰*{>¼ë¢#c >ù™}Ÿûõôö‡–wW®Þ±td¬bz®<x|xIű?yý?¯H÷-ÔÜ¡+*_k¼KG•d•d±¹uö«­3Vn:&7ª~¾Þ#V4Ž Š¤K¥–8>¡¦Ä\B¦Üô¤ª4½ÒTV¼ÁH™T™Ô¸ÖJS†´,stLÝI‹§TÖyÚeÇ-M)ËM¨î×Zb¶ œ¯'&•Df”åÅŠ¥kŒG†YaTÝÆÒ¹`t×e¥oÿÉ­#"IM“jÑR³­úÓªg$¶èŠª|ÙÕ6ŸÔ2càŒŠ¹fýý.]aé&‡,YéôËÚô¬2< ªZ¤L_ú;ŸNfë+þekék+g—íËw^23U<®ivÁhdÝáú×Öƒ&¬¨—Ÿò`Ò\“sbJJ¼1e2åÞ^£=íüiƒÕÏz¼Ié<•I‰¤ty[V1µ¹Ji`uÎy¯ÄIšÔ˜ŒY‘7Eµ mõ}^âB~ñDTm°³Ù\³=o7ñ^¹rÇ<œqçbwþ›ì1Ÿû•ê¼/W¸¼ ¯äjŽðMŒE(MGyšrŠx–§¹–µ,£Ž1ºx„Os”,feÔ ñú°–s¯òáPôZ8L·³0,ÒìáÜPöb;‹Hð8çrGˆÿ9/‡>­Nâlã$+‰sW(¾¸#d U°…R–s ì¾'øx¨z/„,.¡ˆ'é¡ ×§Ã˜÷2ž ?viXW,�ÄŸ Ðm¤…QgÍû9ÊÂ75e qŒžÐ娾ÏN*i*l„ÿŸÛUá ÈÓÉ&V“`ˆ†Ð,¼‚} ò'<Ëa^$Ë…tQÍBÒ… àMˆ£Sá-µƒµÿÝ(Ÿ¡Õ!/²Š¡œ~+oÐÆû‰ÕhOù6eÔrOhV,h¡³/ÌP¬¢‡ZªÃ?© oxGíkÅlä "$Qg‘µ¥”ñ�…ö³f~Ì‚ÀSl"NchÛz2o€_ �þ% ôå8_ yÆ…äH.jiLx•÷†ŸüYÞõb †4[¹3nSÙâêôÒWì`üJ^Š*²³ÈOnó®¿ÌÛÝ¿%p”Åšîô™ìYz%–·Úè]FcÓïúYæ’±üÎGr™þ9×3Ó¨ ÓGŽU\˜{ñö@E̲@E`Žªb‰Z·Íj ¤)çé®°0§7b^¥ú˜#Q©œx^} ,°?pOųNÏ9‘ÖSjEÚU»«T&ÄgÍË;‘ˆ:Y©¢Þ¶a'E 5Êy"7ÿâÙí§Ÿ½n¬§²CgN嬑! ”&¤šLÌJ7JÏš¨¤Tiª—œÓXïô€CQ­IÕqÙŽÇäúÕÖ˜Ì*šQTm¤L:+q¦º¢ã-÷å÷¯¯îª™Yz¦«y´ç棙ñÆÜæ]½[Nuõ¥_ÿæÎŠšÎ¢®×ÂvÝ1ù-sJ‘)EÒ³JÇÔN¨™PSk|©ãU’è´Š@4+1_V9<«tJe›¾9ÅQA¡q5£ŒÈœâ„lFbµƒõF«M)ÛôÕ=¤}¥9±54.33¤±]w«¾"éZc¯;·Öø"§vXS*Wc¼ÜÌ+ÇÕ,tªÔl\¶C×K7–½¾ï¢Ñ“³+F{[k¨2>©¤Ùhº. N«SÛª¯Û{%sb¥R-‚q¿²½X>&:nø¤%QGF$âbyµY‘1ÉÁw¾ùüÿ¨ŒuÈÆwÖßxdêÐUÁgþ=ñÁï_>õË-%®œõ,“ oÉ[;­%£;é@JkÞDÂ\Ô¢i™˜ÅÕÆ“ñ«I]³.do‘O×é¡5'u]ÌkUgÌ˘Ù_jÛœdDUÄê¼½QWšùÉ„¿b´�bçÚÀ_°Õ+pÛƒvv†ÖÄ÷paÄãÑ“ÍÁOž·êެöÒ5š©¼ƒ3ôqeÂ9YMWr_˜/HÒÎ=à|jé`QZy•û£ ÎFYÉO(¦ gÊR– ¯b¢låÁðs^./—pˆK‰†¡ !—n>[¹Œ/SF5Ë8®«%Ô3È­¼Ê0;¹œáÅ(ɯ©§‚%<ð&úm=µaq8l»ü'Ë( ¡òó~g%?—_‡AîYv„ч"¢!AcûÌšÏv²Ì„·‘Áÿ?ÛÕJN2Ç8çq2ävDç N±ž‹y„!¶r]8|‚ ¼ÊËÌ Û7ò$ùð´5¬ŸŽSʹ°Ðyëy94ÇOÐC‡‹½{ο³½aëKHNÚº8o¢‰ÝÄÉ3ÂÍ&ö“ €Ýhh?»‚<—QxŒ—èg†¡=³À݈1åì‰ï5Ž…ö³çYÃQ^b)Wð"—2ÅËà&‰°Œ'i`–%žÀ^£Sôdà³( í‰øÃH_Ov|‘Oœöâ2s3Q2ä½±=rQÊ’_ØWÅ/ý<eÅ÷-2\Z@1é›oü<Ùœ¿¶vγ‡øUÄ\`+\4V4~Cv]Þg­«ê-˘ ,ˆøAÚZ64Û>+<‘ÏY˜‰3hÉËQEi`œ c6fÙ@Ù¬T`&¦2«2-žWºN׌¦ùrursÖNØYjC©Šœæþâþc±ûþg°cÕ<ýiíÓꊤ1«&kÇœµj²ËÍÕÔbªV²ZùˆSCIûȸySŠÎÓ—Kª<bù–6gzÔJúUW™ž7=Yu¼ñè»öýøã‹öVÕe‹çfknùôÖŠ µ/ºqú ÕÎf6}sKýxÑb]U&OY”‘(33¦öŒy[½VûªÛhw™™>m³J‹d2DÚôU›Œ ÆÕ–˜íÖŒ©m60¢¡ÂTœ4Ï™ýG¬¨7:¥²×¼ÃÅÒyѶ4.1Saö¸¥…”`«¾íóõ”˜Ë‰í°e…#3ÊÑ"s Æòb‰¶ÆäÆÕŒª›Q>®¶Eßܪ®¡<ºéþÕ£MIÕåfú´öXpPÛ…ö$Õ×Q;ª¡Æà¸Ñ*M3ÎŒª™ÕQavJy—ê´Êœ™i™F }ê¦DîµhöODž¿<5g†zh�� �IDAT‹‘?ù¾ÉÌʹÏ9Í3‰ýPþù ¦G¿¸¢IrÀΈí9ósvELF,¨ÕžõzιsF¨ Ü´4®mÖæ ,Ⲉ±¬'£.Îø÷@YV0¥7o+¥1畚H‰FuDUçtñ ç78'e<ð8óe=-D5v¯Ô¬]Û(â Þ΃ìeöüMü¥Ëòg·ŸãqåÏj¢"<ØH°•fžgEH@d'7r€Å¡˜âB*˜ 7p;ߦžDèÛ‹†Mñ[ØËaÞK’+™cÝ …î½»™`'u, ô“”g˜s?“ô±˜§‰ÓE’XÆ4YºÉ‡qó1"$ÙO2¼H4sEHÚË[XJ?»ã!®�ƒ#E:*åJö2Bž XðÃa ãƒ!0^§~;_|3»C5Ät¸òno7ÖÖŽüž1á§S©ÂXõ6nç× Ù‹'BLøµìá%ÞG¯p‚#án¹aÞÉ Œ‘æ:ºøtìç8ë8Ää›÷ÉÈ5<ÍÕ4s’—Âvß;x&íiî —}ü kÃoô†0ËPHÚ&òê *šdØáü­Žl ì õÇ÷ÅÝœ ­~‚q"tò¬åUâ0üÎF>±.•S9Z‰ñh8è·;XÎÅD8‡y.áóy8@¬ÍíSÒÜK?¸+ ísu &ë°'ì»Ö]w¹¿[>·4ðc™ó¸Ä•GÕþÊ?%‹-ª¿îMŸz…Ê„+_£=6ðÙÈ¡µÁÞÝâé¦I/|(~q$î“ùƒñ̇~ž?Raä ~hÉúÇœÍiW´lg"æMe=( ÌeÍåÄòò —Æ}ªÑûS^|=㺄✟qCDŽ/DݨÏ9ÌÀ"­³ê=5!RnÁ¤µ¥ª±‘¢x4õ“ÇKþæï–ªÖ˜R:­l™Áfɬ*V7eiVoÔâ é%N§U ‰¶j3vÜÖ ¥J™ìÕ—ÐÐjh¯%¹ é-úçë±×†s(ŸŒ'÷_°äå¦Ê+vÿéó-þÙøTIïé Ê.ìx±}ñÏ+éí8`}©Ô¦TD5Æ×Û“«3º×ú¤ªå:‘c–%Uô󵯗:–‘¨3ö¬íº+L÷iVÞc~B6­hBÍ|=S*‹¥3¥f[9¨¹Ñp½Ñ¨üÆ SYñgÆÕ¶ªLjJ唊U%UfÅûµÔÍ‹®v("˜S¾Ážq5­úš 4©3V$½@W‘ôÊÒ}ß}ú;¶4Þý¶IÕ7øÅæ„|§–·Ø5®©Z²ßü¨H‹‘Yå㉤5æ¬]¬;%žLê™§4ieTKRϬ؅NM+>­6ûÒæàÎÏåîyqÖ»òJrÝ™`w,ñýÏç^Þ˜ÈYÖª|HqV}ÖÊ�ŠãQ›êdS¾ñöœûŽY·=«&ª²Á–˜Öœ?kÒ>¡3c~³†¤2î,„ã¶g} ­!ï ¶ÄÔåÎÞTve\›÷q&yWQ(’wDc"ÿqpïㆲ‹X—ðμ¯±€Î¾ÈËœÃïs~èe ü€çùq6óãD‰ò>6q,ìäzÖ0Ëzy‚Ólæz¦˜õ,æ}<Á{(åùpY¿“~Aš¡Ðê÷>.áVð<×ðN„aà'™eo£šù<žª£!�¨à]̽ƒ“¼ŸUÄÙÈxDsÜ·ò^æñ§” Qîåu¢¡Þ~ˆɰ² ÿêªPF!¤ôeB]ÈõÜJw3ÄÍŒqUø¶7ñLþ÷ÎFjk·Üñþß³]²4?âæÝÐÎ~æÓÆ(¿aŠg9MŒ¦)¦š×BèQ:Di}O‡Ÿ 2¦JùKŽP^‡¯ ¡[QÆù G͹=oWñ%vð²<6ÒÊzÃ$áTx…Zc§Bßü›Õg}äiâßÙÁLÞã4ò‡<Çì"É…ìŠxi¦øB\Œó½¼…ܳ•kØÅ_q”ÝÜRäÏrÎçjø.2L)oÉû®/<¤r§Ãûò‚„Îûz˜ ý>Ïðï6yÇðœ×Þ‘ŸÜÀëLDÓ¿ˆ¾ðÞàýIÿ|4ú÷¿JN}…•ÜøZ‹ïLÙ¨¬5zµŠrŸ¹ÇÀËç‰æÕH•Úö¸7ž3ú zâJ²‚¼Q?Š»4ïpĺœCEî¬Rž¶–[ùŸ!€ri̲¬ø”Å4ñ'š˜óc-ÚØYëö)5+•f,>¡%G…êµc6›ªI}ý›Ó_úfðîûg»ë‡dcYÿÔ¢}ÀDÆŽ9Ëg]Q_ªhž¾¨ÌQÍÛX¥{XK•dVE¥¢2AÞìV}9O»,£N¾Zçy޾èâ S+uæÄã²/ÛZ4SÔ:’I­99¸¾»ùžmWz¦Xº&ß;²iñôä˜ÚqµEÒ«¬5¶Ò‘f…|yT¾ÅÀ”Êq5¥RH¿ÖÍ«, ü²{­ßî¹QuHZÑ|½ËuÖ/3Ãrâ¦vÙ8Oï]…›V£¡-‹H+Ð2©z}¥f9Ùlà´…Ñ“Ï*)’IªÌ‹vYðS—¶šØec ²Ë¦v=sŠ{´O¨9².k=ó¶][cxDó>kOk;®%.3ªl‘þYÑ„¡5:Ïhý»Ïè:ï:ÝûŸ{ï­Þ›%˲dËrï%ÄéqB€B(L(3g€aJ8À”g8 ÓÎÚ�C Cè„Ð é½9‰Û‰{•%[²z—öÞÚå>/vîY™õ¬™çñ+YkI{mIëÿ»ÿ¿ëº¾W¯Ú&‡%/uzNeƒ‘rÝ ã1•˜é5öä5U öK º+îò`æEo~¹øÞïÆÅò2yU‰ñó‚Écyß µÎ:ÓhÁ¬û*„¥þ•·©›ôDÌî¬ûh¬s])tJ’N§ýeÌMMŒ:™°pÚ|¥é¬{gÝA bªòºsF÷Æ]ÄâÎÏ»—ʘŠÀõ¡ååþwF{ø—W„/íðxÀ®£‚ÿWJo 3ÐÄçù2÷r6î¼PŒ‚½…ç^w’ž lc·ry4º®fž²œ èác\¼PQøàqJ¹Š{¥•çx„”RGüŒJ)ç½låÛÔÒÁäx;ØÎ4¤¹‘çXÅ·8À[xK„E_ÌAªø{¸ÙÈýÍìæ£Ü›·‡¢jÄͼ'Zî=Ë ®¤ƒr€?å)þ„~:¸ˆŽòdtð¾•ÎEäÃE¼Ì£°ð›¸”åjp&²ÝUF´”REŠ[ëêúÿ›ÛÕx2YH,±—£Èñ�­|:j~Ì‘Š~" Œœ—«8ë|ˆ<OÑÊy âÊk[KјYÅ]dø0ótpœÇ£‚« ÷±©Ä­%Òó>Ê¢/ÜÁ ÑŠò÷œ¤•‰×9××G¸âÿhúšfÕª×å…¯aG8?ê’‚|+úªüžTÌ[¹„}Ñžzyô׳o‡æ*dôr û9ÎËõþ6å¥ð5_Ðn–³‚²‰­ÜÇbŠ(£;ê#^Ïò¼’"sE–å<Ãy¼ pk WrÌ‘aw,r&ûP臡òPÒü…6<›ßXdãÓ6.0öÆØÔ¢ieìg >!¿Ãp•=+ccw„.á‹Ö× µN}˜Çh­°!æpÖê„íå*ÓšãN„ʲ¤êÐNš¹4ðlàvšò^N(Î{S…Ò˜³È„e|FIë‡ÕÆÆÄSæâö¥uÄT%õÆ%¦4‡7Ýþý×Ëïø?Á VWZZ[çl\{»ªqëãrIé#¦g”7sÄÚ µe&NZ–V^"=­:¡û)›ÎYݪ/T}µ½ÝX¡qZõ †Ù•Ž•HÒ¹R÷¤ÚgþûwíøÀˆ¦Qµek¥ÞŽ©O)K)ј=nyJY½ñ@8§|ZU…¹ ¼xά¢Yûl^îx¥™=%ÒǬh0:¢±]o½ñ…ÆÕÓ:¯¤[g‹J³­Î•IîL3*§Ô [PifVň¦*3E2jfTU˜SqÄêF£%ÒO»4!w¾]ãê'ÔUšYçÔ˜††–êNÈΩ¨0Û«uNùÞ‡ÿê;î8¢áœê¥Æš Ëf ·0h¤RuVÙœä´ò!M9• F§çÕÕÛ­{Ê•3‚*™&3ç˘Ë8ZâöRCe‘¾ ôè`‘•.âð¼Z-,*qQÖ’¼\Jkh®AEƒó'-nTŸu<íñFŸLù‹Àõ)¯ÎûïKç5‡vƼ§VEŸ…ü¤JONm—5CfËœ-z­ê÷/C±P’. -t8æ­µ&Sfù»BÐ±ÈÆ {l?kâÎgÌ-¡çY,į[]v¼>÷Z®tM¡¥!tš‹8ÈÛi§Œ£œ , üS̾Gš¾ÂOpÇy$’ÒY·y†W°˜V>Æ/â}ìŠ"´ÃÜÂmÌò m´±•71KÈ"ŽÒDÛå—òÓÑMneÔÀ—¤‰Åìå]ÜÅv:¸‰^ù'ùþ•$¸$êÆ¦…ɈËúô±3Ô²™‡HEžŽÆh5µž_sšQîäåèý72Êë8ÏCœ%Íz^%±ó¹,Úá5E§ô¾ººêÿF»êM&ý¿€…8êÒˆ5RPØ òÒx¤!-‹ZRYÇ=ö"gØÇuQ@º0$NEzÕÕÑ®/þ:©ir-­ÌeUÎ[ÃÉh×¹ˆ>žÌ …¡ÒN÷ëJ—rŽ–D;Ð&vp„Å4Òí _"`uA›¥—YÎ6QËrjC¤9ÄÌ3ÂI‚¨ÎxW…ϧ^+.ävû’’þÐãðâÖ±m<E’Gy…§ÙÄQJˆsŒGŽÄ-Îj)4#ó71 øgn1¼Âú}ì™ØÓ«ÂÉ+¬éó‰WµÌ*iUñ •Þ>¨§!vô“¡éÀlÌ©Ðn†]P»s§‡ëbƒ½¡k.rËcŽÜ¼häüi'X0ïX^Q ¥ÍÂ95óæB¿år^d‹XÉxÂ-T„¦¨ =suÚ·ò6ñ­„Æ\3_#W!?£š“UâÄsöWkË™ ÍýÅÏÒ;/—M„k^.}qñüѹJW4f*4Sï—3ί0? ¼V²X¼ÔT™¢6A¦EF;Ó¥')Xíx¥©£Ê$ĦÕw8™T›_`MRUñi•$::aE»œxÿ<\}tQÙÎMúšL4 ÅF5Ì+9jU¥Ù+SÑd¤Òl¿Ef1¡¶ÆÔæ µ Ù¤ò½«=dͬÊA-Ë(’M*k1RzRW©)5M†ZèÜ„ºzc¡`RM¹dL—«5qÎÂzc9ñjS9ñb™*3õÆÇÕÕ˜ª6U*—›S±Åž9å#šŠÍ—Jjn1xÚÒsZÛœM+M)}Õ²˜üè‡UþõÛc*ªÄJ¤é:jIƒê9ÕÂa÷d]Z)‘Q»Ðx·Dh¾FCRbDYÊžœŠj™YecN*µeFiVr¹²ÞP­"Ôžüùÿ¬øú?WZVíô¸‡2dô”ºxNgLUÞÙÆÑi÷ŽZY¯}HI\®Åº1Æm­75­..mÝÍ‘JãåªfðlÚtª>*u{qÊ�·231Û‹[úgCæ¤Bï´â¡<=¡Ž}¶™8îÀ=«c¡åTøDy¼%•h9š9Tµ#¾‰Ílæk¼ãÄ9Ä›x$ÐØš­ö·Ðü©Ó'(Ž7[)åC줄³œÇN.äÃôqAM½•d£¾’—©aˆQü¶‚Ÿq;#déˆE3ÿÙ\Wˆ‡î#E EìeEm cŠ'y[¤¦gØÒ7Fo‘d"‚*lŒÚ NPÄ»y«hô‹#¯#SlàYê9ÇóÔð}ú¢Ðôë\ ¼Â«,`ž‹9Ež èh´Ïÿÿ1²g’oÍ{ÜÌ%î¶Ð†r ¢25(¿›¹œû HGÝüó9Ò,à]ärvFFó¨¿DÂuy¹„_±ˆƒ,âIJ¸8Òfè$ÃøëªªŽE#z ì%$ %Ær,g4zGÿQÒœ%Ééái¶F ÆVžˆâ\/soŽž’ ¡ùB-ô¼¡û ‡~âþÐM,`„+©àQ®c_b?òç¼Ê–ñ�³l湜?ÌÚÌ~˵´Ç4…b$8l Á› _Þ㫯Z]æÁ <Ðááƒçÿ>þüuáÊ^|6üm‡™úÀùµV„ÍÕ^áÏúëNäÕjù¡Ÿq×£Cui5åö–O9Wpu¦}<§‚·ð¿ÙNçÀ#¡,?Iø«¼R–­R4íò¬x(ªnÒ6ã\R{LK 9£:îÂ@<#ÌO~ëóá› K7Ü7ÿÁƒñßþc8S_dªÈ¹zeÝÆbY2©¶AªX<T¶ÖÙ ³ ¹“S¾žÐY©¸Tê ¹%r²›OÈe”´ëŸS5©fÀ‚˜™E&zµW™^¤oá3ûÌò_ú‹ë&^<lõ Ë+Ìͩȋc\]‰ôJÇÆÕÏ+„s*é+’ ¨6µÁþºêϨœQ¹Ò±rsKô›/TŠÉ.v¶ÆdFñf'ÕöêX¤¯Êt±LRYŸ¶2©%zâr³* ׯ„\™dB6'1§"¥´ÅÀ€–P°DOJ霊€ç­]ïD‰t™d»ÞQ {mÙd_Ry§S¥ÒG¬ÑÜÿé»7ýlÅÀá« 䤲³ÚgÕUHuè­3["Y¥®Ù`‰ù}%j㎭’;§zÚ‚&ísJ; ×Pk´ß#õž¸Df\mÖõ9Ù2áÀ'ïî¿9¹MZÙ„ e} ¨ÎúmÎg‹½±Mm™–9¶äìšw†’¼ÆÕNë(79òZ´£+aÓ1_v#ÙJo*Ò›ñŽŒÏÞz9 Ë»œóKzy”«âòÆ* õd4³;tšxÂòÎwái«ôóÍf® ¼!f&”òécŽ\–eCæß¿v_êÈF&ùóœHxgÞ¿“¦.*íÛÎÏBE\Í¿1=%ŠõìfŠ ôD•öu &ܳ1ï'qçÞú,‡#]§Ÿ÷RÄN†£Ò1Î'Î�Ïñ ƒQi_3Oqˆddy¿ƒ 鉖o¸ŽqÞÄ£Œ1ÇföÐÉ.NF5’ÑIþw|…ɨw·'úüû9Ÿçø�ól Ÿ ÜÇ-³cG#fÂ~Vp#<ÇY†YõßE©f©æ“,à .Œœq«"ÈÅ•L‘f? nŒ&ëÿǸúÎ\ò Vñ‡<Çó‘¤VÌ8ý÷mŒb ÿ#ïgä9rÌpŸä!Ú¸“S\·YÊ/8ÀIf¸‚n†™g5;H…ös„£,â4ò;ÞËWÙ=A˜WI²”°¶s5Ï3ÎXtÍšµð�“ÑB¶‚Íì"A–Ç9Ê,mläûìæ8×SNWÂ-¡&¾Ì4×ñE¾Ã¼ú=Å,a€ÜË» HJö°¶Â{Z Mæ>éà/yŒ§Šü,ï·|„Ól°õÝþloüÑÛãÞ×Xp4çìf›L&ÜßêŸF}ò„Þn½™Åüšß„zí¾Â=¸ÊD?»26e=gÑF7¿ê«ïW¾Îî ÞS’øÈ7óg¯a(ïּʜ/Ìëmä§)¡Ëc.ý]‘;÷Y‘³“F>ÚÓ¨­ ñïSfçµÆ­‹Iç¼”Ò1«†}Åó^É{)¦¥Õl ˜ûê×ZÿÏ¥ž¿6ÿ/_?þ‘ 5{ðŠìÄ¡¬Ž25Ífˬ_lþ„á˜Ãuf{|#íºA‹Ï¨î4Ümu½ŽAg_ué¼Þ"«&5U™yÅ&‚œ¢9 ¹UŽž²jNåZ‡âò³*2Š^ùäÃËŸmî|¡¥!?Žvgá ]fW9Re¦Ó©iU9ñÅÎÔ_îÄ2'G5Þïi¥Eæz@µéÍö k*–Y¤?­¤X¦Ý™¼ø¤šcV”š± !סç”ÎeNÐÕht\}ÉJ3hÓ"ýõÆš ΪœR}ÎÂ=¶.Õ]b~FåjGfTÍ+žSѪF} h4Òhd@ˈÆåŽ7)•xÑ›í²ðì_übÑwwtMŒöX2¢ñ±bŠê +=hmºÅzŽZ~Úp‡|·M¡Ú 5“ꥳ’yåÓZ¦-•¯¶¼RÃQ+Ó–Í™+µ»ÜøøG~ü|In¨$ôZ×b ”M͈Û@{ÎìŒ?™5ßબW’ºâÚS)ó£¶N:;ê{Ü‘ÐÚj %j¬¥-k-gÉšÉXKMV[NW ýyÊ-/Ä}’+óN…Bv§È¸(á’¼Öó`è÷ÜjKÚâÇýfœ½‹¯v狎.‹ýfi8øó—+û±Ý{¹Œ_tëðµÎ§ßиÀeÈù—çIŽÑÆíTò!~À[ÈÓÏ)¾ÆÙÉÚзC¿¦6Tà<žæF>Çnö°.:‘¿ÅïXÎ[y'MÜMžy®à}ü›XÁ¹Èn·Ÿ±×Éo ‡kxŠëx ßf0rFä)åz^¡˜þ„Fée'Å‘åm3OGî…ÔìPä°€nŽìûYÞÈfvò*Û£î«ë¹LÓÏzšçŽh™¤‡4W°<r©ŒÑÇJf˜fψXuuŸ¾õ¶UÿÕ¸zp.Y¨^|‰^Òž¼À º9rÙ¦‘óò>O Œñ7ìbžï3MU$ =LMÔ”x#QiÊ;¢¥\1ϲ”õœàï9ÈnŽŠ`ðùè1¤ ¥ÝÀ(æ^ºØ%s4FµÊ"ÔÕ(/ÐÄvâ G@ÉF2X3²’Q~Ä¿òu>ÁBnÍËp7o‰0$Í\Ì8½èmÅ¥Þz‘ëIñeþ„®ŒÄ¤CüŠ4·gaÌ›7ÇNÚˆóŒ/ÿÖ. Gîm09ïy—æýÓüó椮qïŒ=,9MŸâ8+ý¬5¥R×Ç®.v]h2æ‚üÓÿì²yÀ×öøÚU•ÿôîT²–1–åÍJC ÝÆ ´ó“ÐÛBçX–«ñ5&¦íJX–÷GBe|¯Òc®Ì*§&§=°¬]"KÚ•W8[áwm.LúyÖÝ¡usFf|Êm»§þ/u”ü`{ÑÑ+Ãæ¬iž(»ÌÁâæÏX1'›vªFEµÖÕκ5¡<”¯0ßjvÚÚ)e‹ÏhXg Ïò¸Ü«¶ÙsVK›î9%‹ <亸p…c»œÚÒ%zrkŽÕžljë‰÷[4¥¦T:«6O*›T[æl¹|ZÙ>›ÂP—è©0;¬©ÆäœŠv½õÆY[ifTìŠZ“Õ¦^¶m^ñ´ª¸Üc¶¶˜\`x‘þ¼ø§:—¯2Ý©»TzPKñI51ሦ³/s2V™™P—ër²WGÁX±ÌÉqu9E1ùfƒYEƒZæwèјk6”6=cAë’ó›¶?ºrf¦e‘Þ”|½êUN×WÒbbJPf÷°’~§èœuzÚTVÛ¼ îà¼X¥å$Êdç<X>l¤Z¾Hͬ×Ù²^lâm»>sÅèPgL]©ºy§Æ})îÝ¥FsCKb>šU[f&-:²ÀX¹GJL§­kP4méB±¼\ÚYÆcžÌØ^k:nqÚdh0|Ížði^ =㺬XÜõ9³¡fúùÛÀм«B¥¡_—x)tU‰Ûò¶„ÞceC¼miðøÇB'y_pùî`éN÷®i™½p.·»¨çÚÜñÓ¦o¥šÃ‘Øñ-SÃE³Nç”ò=ÎÆ]Øêd%ia€òžâ)ÞÁ7¸‚ý¼Â Vð~~Ç÷h#mSR´DUŠë¸…ö²œßÒÃ[¸jz˜ŒÊ Ïç(;ÈG™âŽ(ÿô 3¬bŠ…Q±ä0çñ~Ž{-켄+¸¦`šLÞÁúÆg7ŸäažÛ8L[T`Ké#AÌßÅ~–rg9΃ô*gy˜s¼“ïÑɦhƒ…Óô²„?b/ýœå6PËשׂ«½õ¶ ÿ}›pÕŒFI±‹˜¥—ã¼=¢†_B7ý¬à½àL°Œ~f¢}`¡Pùcâ¡Ç8¡GúIÐÆY>ÅFùm¤‡aŸb,êÞYˆ,º—ótÛ:±0^Iž%ÆÅœŽ^q%UQoXš?â4«¸'z|hȼõÌEeÊ…¤÷©èã*ªä2Æi䱨 å}|—Õ¡ãy;©©v$­‚‹"œÒOh&Îй,²(!ü ³1·‡Ïu»¼ß¾‹ç<”/:ì¦R‡73ÏÏù°‡sÌÅÜz‚û"$ó_°U[ìŸ÷õ•¡1æs>¡­Oe»’*KòžYÞ2±`òµZ1;ãR¡_Æd¸žCqWØZb®Äs3)UÓbleoÌûY³1æêfçV¦ô…ÎÆ\ÁõiöäTäÕ§l@‘5ié˜+*t—»3ñ¶W矹°bhÑ¢·<»ìImg3Þ–žøfÊ¥ƒ:YÜfxHS£Ñ¬X£Ô^«ª¤LÆÌ%Å ¤Òªñj•všíÔ3»Ä™WµoÒÝî\¿Ö…έqhVEŸ¶‹ì<Qß0|Çý-»Ûò/^4©v™“ T˜K)«6Ýd¸Úô+~ou•²2é^Ëœ }Ë̪(̳Q ¡XN|^q‹¸\µéfC/¹ U|^c²ÎÄÏdÇå"˜VU&•¯5Yl~FÕ˜úŒâP+È]ýZ7zeVE«sóJŠÍ'ä ·º>‹¦UêƒçT„‚iÕÕ¦ÓJgTeÂç,Xgd×ÿ|ªè‰íµ//ÒxNCÊt«ái¥½bKÍ&Ì.4uÆã¥Ú»ìÉëꔪÓ4j¶ÝåÍR‹T )Zê4s9C)S)Ë*Äæm,±nH}êm¿ï{f½¡š/æ´Ïi*öÞ„¾Z ³ÆBE:ËÌ¥eRòåÚr‚J̓:’ZgôçýhZQZSLyhF¿�� �IDAT0´™É÷T¨NÚE7×rM‘ K•äcuèŽP+e…:ÓÀ†ÀÒÐ/øiL®Ê‡’î.לó©|õÖàúl°¯<<z¤† ºƒàÚ²ð†s3Ïô§?QúÎ#éM?lx1›6*#EYº¢å“Lrœ…¡†Ðq¾ÏI®£‰³Ÿ—¨ày¶’Žò©4ÁjŠ9L7D'þjêy0:¯¶s‚fØÇßð3:h$Ëݼ‹INñ�Ëx$:FZYÏv±†9G™âΨ¼£ˆ’h@6p »è/àñb6’g¿â}<‰H³XéRû¢“|MåQT`’¸–£ÜÇÔ³˜jŠ2jx•< æ#¯Ã唳…Kùk"Å>¢VWëên½mÇ?®ê‰1Ê ìe–:H2M좕~ä~Åžäôr3Sä3ü:оv=jåžb!‡!ä%–r}·]Ng¢&±½¦AÕE$ÿËÙÅMÌG“õ?4¶9êy{ô hå*žáôr{9égãUsÇÈó 8?ÊÿÖq%¿`«×|®›eEµemÑÖx9÷•¸-í¾J lËy•1:9·>t{ù=­<Ä¢èÉ"¸1œî öec. Íù‡ýÞ3ë®`ˆzÖóq6àxè ¬å® ˆÜkͤ3otí+áó—…& hõ/O™Ïðø¦É׊Z WÌ„Þ(Ži ¯rÕ˜%ÅŠ•4åeB1+B©„ëC5ÅzʬN97é+Iµ§k[Õ¦ü8¦’ª2OÍújF³iûKm'5¯1å'-F“çÍ¼ã¡Øþb7îœûmqù‘ÅÉ[^j}äý•̨˩\¨ÿœ²‚¸n¿ÉÙ\k_³X…L…ü¤š)ÕYc1™zé:ÅMFŽY¼Ñ‘C6̪*57¢¾ÖL­‰³ÆôtI¤”îþî¿^ùjÉïv4Ÿ‹i(8ôæ”w[Z.™V’Q\fæB=eçÙ]$;®¾TzJuÉjÓmúzu¬spNùJÇÆ4Ô™¨7ÞmiVQ\nLý‡bò%Òy±b™€˜pZUñƒq¹~‹ÆÕÕÖ¦¯X¦]o©tJi‰ù‚‚U$; ¥LªÂl‡ž¸ü¸ºM%æ‡4wè-“W—W“?©+öjïÐjíßvîì²Lìákª&b»­^¯»F,¯|Hcµª s)™a¿lwË™bKóJc2ýgÝW5¦ºLi¿åIe¡Ø¤3Yóã+3ᕆ‡ö§t4KÖ3bnr²Ú;~å¡Ësú³kÌÏÈÈÍH˜lÊ9—ÍÊóP‘á”ÊÝÓlËKŠC *-IX˜3ÊÄœ ¤B)ËjM§<ÌYº,H»;î nÉû »WÆÄjoÌûM(³‰Í¡‘´wÇ4¤<”·¡¡õ¦ä‡¾|¦+ÔB= L…³?÷áއû?˜ºò_ýþlù`{ÊË¡?çòFBÖÒ–#/Xá°Nq˜8!MÜÃyT³šZ>F-½Lð †H°02Ž7ð‹`ê…VØmôFvë.çß¹‚5ÜË›¹›v®ŠýT³$¿‹€³L2Í~†y•¬¥6bR¤"– ê GV¨–2…¥p#g_—;z-ÿÄþˆg2üŸoi†™åd·º‘£ ÿƒW™xÛ¡ƒYúæià…Èž•ç"íjí?®ê¸W#¡¨Þ*l ´ù,W0ðºÂ’~ª+z“7²–ÇdŽ“¼¾ÆDï¥?º-'ÅHô}.e’?ã{4ÐÉr~±ª’Ñks˜$iÆ™aˆOrŒ¢ûuá'˜¡ƒà cŒq!‡Ø®$ÏÍÄ™âBže€&V±«¸‹ 4Fƒ6~ÉIú8É_q/°*þŒô°1 ¿ åü>TÁ½d£ëvôs ëy€;øï ý]•|Å?¶ó¯í½×õ“ž•§XR( U1Ã%qSÆ»ø W:¹Á?ÿÄ]p_ ùù6aÎÒ"ß¿ÙL9ål <n_f,ðG¡šP,k*éËíó*ÒFB‰Ðw¨¡?T—÷lè߈åÕ„þ-á£9Y®Ì òZ’vf=°-k[V®Rq§Ö9õs–‡^-ÓSœZ•þÜ—Ò÷_¼q_ÅW?’9Q1ÿ…o¬ýúÛ[Qc2坯•/ÒÔhjÔ‚µ†Be£~XäÚ@¸Tw™¹> õÒËô5™˜P[Ôbx¿-e’Ý– KÍçÅ*Ì7Ê—+~ú{ßuÑ ×¾íCª æ½S£¦T7Q¹Ø™ µ3j»œšR]ãÐÃq¹óSjNè:¡«WÇ{Šd Ô¥:g´W˜­2S*}Fû°Ún­ËœÒ\cjRMÁûW,3 %£¨ÂlB¶CoRùZ¦T—Hi¨5Ñ¡·Â\™ÔŒª2Ég]2­ºà)85ŽZU°ÿͪµ&›Œ,sjCE²¿÷¦Ê˘«ÎmüÝâ^í-†öÙÚb€ ZrHóZG¤ÒZ:d^±©[gµé¥Î>ç²Õfh+ÕxÆpƪb™P®Käïÿ¸›w:Ö?¶#cpÚŠ”Þü©ŒÏý¸ôë-¶yÊ¢¼/ä¬îT9*—U³4'YìÄ*ñ¼¥¦CŸgY詘æP¶Èl›%Åsþ5k–µL-ÔܤeÒlÎÖœq³.ïÀ¼|ÆsyBßæ†ÀØWÆ OûlTË÷lÜûãÎËy’oò ½á7Îÿ?ÁpCÞï£.ˆSúöxúS>Õ>t±KrW[Ò‹¡X!÷VâNÆø}Ž®Pr1õbŒriÂßä}‰ãlb€ãlç+¼‡ÓôEGM;¸zÞÇ3¼Ä[)¥†Ç¸‰6rüšÇˆs_à]lŽ`{èçrö±›I°‡-f„Û ÇZÜûï­f'+øí>3'å_ÇYèÓ3~úº\lŽ[#ÎìGèŒÎÕÂȼ.²x]p(Ë4w‚½ô2Æ–ÓÍ70ÍZ6F;³&¢ƒ½™-Q›|HŠ41XWwë­·mú¯ÆÕêdòYD†ºâ×ñÞ«ø7$Ï*z#_Ê•¼‡˜Œš;^`w4« >øÙÄ(ƒ”G´Ù>εb-? \ÅoéæA¾È£·ôÇ\Å<9Á»£ôUŠ5c¥Eý•4F¢ßxôXñ nç8×òY>Ì8ïàöÒÀvîç~J1·ð4-<ÁS,cŒ»£W?ô³š5´¹"/—w.ÔK'¿ak¹¬ÀÕIªBK9Ÿ³ô°‹7ó]öúX·¾?óëë[çø…¦ ŒVF¨å.þ–R’ Äíõ’§šG8%û€“7øóÇ<¸#®+ÌÿUPyLÇ:÷mã®À³ —çííe#ƒ|„_9—y¨ÖÍsŠølHxeË3þ4ï B×7ª™wOÌy,®Ñ·4¥±ÚúuÎÛ0£3ÐÞ¡zÞü€Ãy'Û2evÆýYWdn~:¼tWøNg~œjì/û÷/¥ÎÖhˆËqwÒcž\ªtÀX¯+ªµY¹ÀÄiuÓê,,«•œRû¢®9ábc³Êd‹dW;|¡½ƒZ ^ѶÔôœÖgïúþô7?¾ã³ç·ôÇW9:ª¡ÆT(V$“Q\"=¨yJõq+ n½IÕca•éﺣݙiÕM†—:= e‘¾”Ò2©€aMSª+̦”žÓú;3J̱j¡s§,ÛbÏœŠ2ÉrszŠÍËìµ%&¬4[mºÁh¿ÖYë˜S^&9­*&ÜcË=i¥kÕPi¶Øü´ê‡í¸Ü“¦”M«j4ú´K+ͳòi—-]sÿ p$øë˜ÎÖ¥”½Ùïûµ¶:[,›g줭Ý:æ´î·d‰jÓǬ˜UÙ§¢Ê‚󜠼S.o~Òl—šgªã¥7>P·ýשw½ûÒgW?ri¢<•¿óžÔ]_ôž?λvFÃBI~1¯nœÐïéÉ;¸Èš1Í#šfU†N>Xìr:Ú9K“%eÓfr¶ioN«NùÅ„Ïç½…â¼ nyèö¬cþ1PÁ^.â)Þ2­eFu¨(p! 8/ïónª²¢I÷”kØžýÈOÜÝ̽1ô ב L²(1|{xO£¿û\ì?Ë\ÚK Û8ZKŸ#ˆ»;x„n62!Æ/á­y#â}ìaGð4'î5`Í•0ánæ~Z¹…½ ï=ÆQBÞÅE|†çyŽ€ÏñsždÇùV´Ž»ŠÿE†Ýãw<Ë4'#gÙ‘‚`j íä|–q„-¶$½¾a8ÎG™æ£<P0¦Í9Ê‘áb Š!Õrß^b{ÔÁ˜£‚<M|œ³lãÚ(ÎU°¡‚­ŠJÞ/ç©hPÍFöQ?V†ò¨£¹PÌ»†§É×Õ ÜzÛ{ÿ«qõÅdòªh縄?åÑh\½•㪣ö –ÓÃÓ…²v*¢üÓ’ˆÀQø×EŽ3F=בÞÿç žûykÂyC¼‡n&ØOE<ËÕœ¢+êÙü ÕnÞÌ^® ™Mc)î ›Ž¨©$Çÿä!nç_¨b'ýÑ5k†Oq×F»à–ÈÍXE7],as‘îUJÀ Lrˆ'9M<ï"vm«(âã|ßkÐèÚ = Ë3晉ÙóÐ\ͯx—ýÝÓŠF]|Ì;õ»…lãk¼˜uGmÍéîþ€¦¼ßDÖK™â]$5÷z{³—æ'>Á‡gnÌ?¹‹—¸“®Ðd E+]\³$°2æÒœɺ#TR,ŸÑÅÅŽ˲~>ë¢Å {>©"çØJ·äsªRGVUÒÌ„±ŒÒJùŒæaų…2¥²S¦3-Âò| ûÓÍ2ÆVÜœûÔ#Ï5ÍÍlk2Ñ£þjõ3Êç<4èæjeóB3ëôkj6Yo¨GãR§-K©‰ùL JÌ'äFT*?£}HÍ´ú*á"gª–í™Þ|ºí±Uˆf¦U·¼ÆT™Ô€–N§æTlôjFÑœò­^®1™{κ=:£rØ‚…ΜÒÙ`¬\rJÍZSÊæ—H›o06­jBí¸ú˜pJÍëêLl¶¯CόʴÒfCg-Æ”š´’S–uëÌIÔ/0/¢†¢úç]<ª±Uÿ{Ïi­0;§¼M_É sCša›³{mI*_ãp!V.Y"½ÐÀPsØwùÑM÷,/•™T‹„ì~ËV8¾OSÚ]]:RNŸ3Z£5g¾VrLý¸º2“µfÇ'•œS³Øó'š08£´¶¢zú¦‡2ߺÖcK¾~Sß]_Ÿ¸éùÔ¢3>ñž²nɪHHL›*ÓRcÓ´þPc >-ÇÉ@Wà\o¦µ…^É9<!¾Øþ1Ë8YéL(ŸöÅi!ÿ«Æ5yÛ²¾Ÿwˆ‹ò¾3Dg…[Êg-/µ?ãMü*tWè '| ´+p;{éÉX1åYjØë¡ƒeŸn,;‘Hžå¹ÀbV‡–åýµÙûùh˜y1ô1þϲ‰=<Î;¹—8籑SÁk¤×[Ø™Ÿ·òY.¥Ž-|?á3yy¥•—#¦CgDO-|«ÿż_1Øwgh€ß0Éû9Âô³œ‰Nóý"¾Í0à5phH.: û­±ˆtº˜*öÎx04Âcœˆnl "Ò¡ÿÁ6¦ØE£œÇn๠Ž]¼ºWE­ZOÑM+¿æ££‡žå¹¨£ {¸ŽeQ®«šetÒÅF¶eOd”_YáÕÕm¹õ¶7ÿWã*•L>N ¬ãÛ¯ )gET.YÈ…­¥švÎ2áë Õ˧¢/¼‰NDòZAE<ÈFž‰ö‡Ãlåj¾›7À"¦y–—XÀ…Œ3E1OÓu$f"ó~ž—¨rà;©ä æ)â0Ÿc?}lfŽ.æs,f’·°…N~šÝÏ�Ûid†jøs:YÍ6ÑEßa†¸…jªù]ÔZÖÈ/¸"îákœ’B‹Ê­ó^É8F7©Ðy¡v±ž>š™PºÎ—~éüW|µÇ¡~fã¶„?ñ‡ ¶´Æ—7‡KsÁË—Ç$C¯°®Æ•ik¸€U¬O»ñ7â ½ØÇ*Xh§‹S1Åuä%écmhWèdè8W2SnoBzÞJæbâ¡Þ¬­YµqÛ&‰‘„.מ§8¥:+sBc`v\*t¨>€êjËR~•Wž”¬ÓÓ]I|íªtÞàËk3J¦5ú§UÎiZl}Fù¬™„à|‡Ò{4Ï ÎZÌPÊ¢¼X½C-’«,Ë‹Í+NÈædÚLM«ŸS²ÁÁ@¬ÝéþøäÒµ ž]±Ø™3çÄ;ô¾l[\.+APcò”ÎÂ]ªÚô¬Ê-”KÖ˜:¡kFe¹¹Eú,\¤¯Ç’rs-眲,­¤ÙЌʼxÉ*3­ú멯4[$3¥¦Êt\.©¬WG³ÁVç6ÛÛîLFјú¤ò¤òZºcÂjS­ÍJä$RÊÒJO[2`a•éUŽŽ«o0ºÜ‰aM Æ$•ÇåÛô}ï™â]]5û—T›K˜$^fr…³¡¢•úG]0­£Tͼ% -Ó7¥d\í '‡ôé7>hÑ”²^[óZ«m -®©οíwmß¿yFPf]é=[R?ŠûÑf=W/V–æIxbÒ 3.hTx¨H+ygŠt”ªš—iuÞ„ ðB "ôê˜=µÞ˜q.ðTV\­-ckÚʬž¸? e9%1WžLëW—ww­¿­R5kYZ¸3¯%PÈ…NóÓ¸‹B'x–·›y.{zeúIƒ×¹š{B¹…EÜ™-©zcÑÉ÷g]ÇÖ�tÑO턲…¡Gø9çGyͧÈñ#æÙ–÷2g˜àzÆiá­¼Ì:ùmÄÓ+c9Ô†î%I}܉/gùn¤ˆˆ—ru<ÍѳucÔw&:Wû¸ŒâH*hû)c==ÔÐÔG¹žXt®VGòÛVFæ²åü4jˆíøÏL¢ÂeæÜë4šcq·†z9÷Ÿ;›.`–ÕLPÁC¬âžãs\Î1¾O’rƸ”µ¢åd]ÝU·Þvé5®%“WsaTê•ãjNp1)Ƙ©ô¡¸ó²ÞO–ï1Ì WÓÎ1*™c#mSG1OD¼ÁW)å6†¢+šˆïw[yˆeÄØ]H‹‹z@NED¥=¯«+¼bŸ%Á>fIPGž¥å}´“ä�³È‚:“žˆ~g8wYø‰£°®œdO´f]@?|—u\Åhca´äìæO‘æý¬§í< ­£›qf¹†GxˆÕQEÖ7ÙEÀvJìqzÕü*}òpð‡uáÿåëÎãäªË´ÿ¿OUõ¾Tw§÷îìûJ;„ :0‚Џ¨³ú8úè,ÎÏÑÑqœQg·Q7pa$@d„ìI'é}ß«»¶óüQ9¾˜ç÷Ìœ¿º“WW'§êõ½Ï}ß×õ¹Öïu¬!þèÿr_gxΙ`Ën/VÐEPäïÓž XȰ±.¥åÞû²Kº=u{0û±“Ÿ¤)Ô\k}Öž¼ª*ɤª”QØTku¢))â¥êŠÄ«Ìdi3;ª/ïµñœÍiŸ«vN™`Zmà+u’iÉj+òÊZÕÊžÎhÎi•Ä´Ч-L;R~õË Æþà†©ñYÙŒÒ2ÓZC±´òqƒy9åÓŠG4OK¤T'I=åŠÑëÌENVI÷i*1;¨a¡îPPixX}›v]#NŸ^3ÓþÈú¢ÑÊ~Õ&’Æšô·¸Ô̘d¥ÉQ5í:'TO¨JȦ”M¨žQzÚ¼”²P°È‰f½U&_taÁ/œQ\g¸PíÆ%[õTš Å*MVšS3ß©^- ²eRE²…\¸|©Ùb™Â"jØœi啦²Š&TL¨NÉŸ´°_c¥©PlJÅ^ëW:Xc¬HÒaÁ”Šã–ÔkÔÿªu9‰:ûïþÞEw½§„Qµ{¬KQo"}6rx§ø…†ªM ª=¦5§bH]Òø˜x±ñQ e6Õ¨X$3 ’3%Ú+LöVÄæÜtoÛ½ËNúÉŒ’„ui?¬3Òà²){fLg펹"´´H_haÎÑÕŠbN™O>ëøˆ†ùfÆm ½·Žw&”Ϊ‰»:G\kL>£.o€%’Kù1BSkCûBõ<3ãÆ6UCg÷Ä,!àç¡}ü$áorV1—k` ³r¨=~GWö`ñ_ñ)ްÄW·»µ4Þ³4üàÁÜ‘‰;óbÄÙÃvú£ˆ÷kVä¥Â³t¥¸žb.ÝQb oáÁ(†q%§œ%¨}‹·rgDž]Æ­ ³ŒßPN)/2E/óØ%•—³:b=Ìr.?ŽTsñ(2q Â,ž¿¯áw”Ec­Õ<OE ‘ˆFšqº8J9oåH¤^.èÝ0Äd”ù¤8‡®æ5òœSH" ƽ+ô m¡‡"@ûïÑwíÑ›ÕÅ0vQäó¢»ý* ¢ÝU¥X ª­ÝòŽÛ.øïÊÕOS©ã¼Íî 0ü©H‚™#וs8ô$;èXñƒQÌL¡×»…},Ždo…|ÎÚT e)æó<Ê,‡ø-·QÁÐÅB·±à ô¿Âgbæ ß~cÁ˜µ#R þ9y^¦›aޱ”fæq OdLL›Èêç�³œp6¥þ(`í‡w+-ôÑC'5|”sø w%â_£HìßkiöRÉqž ­áß8ÎÇØC;?b£ÜÉ·YÍž‹Œ„ÃôúE¶ms?õÛ›ÃGv&¶ÿ$ÿôzÃÛã6ä4YÖçâG¼ô&ÎO»‡2‚Ð3ÜŸðÉü©{<·6ñâ—ó?üûð‚ßz$ÁaÒE® Ôåý$çžœ·“¥=ëÜŒõ¬)²¨Ù@•°ß?†6æ}%kì¯g}oƲ´elË8Ú’ug½ÉZ[‡õ…&rÞ™Ñ6íÛY§fmɺ;æm9UMŠ·ÚqHcÌŠ@cŽÜ’®’w=µð“w ÷Ìo36d^ÎÉS dÛ½~Зf50ÿ\=Cš3ÊæY¦³Ã‰5ŠF”Ñ´YWÙi•;\Rc´Yo–P0WW±Ükæ¦ÔžÚÜ_1ïàÜ_œ—+“Zåõ¤±Óæ1w®Î¥óJïÑ2¥r±ã)廜ÿŠsè(—QWohJåB'Ç$O›×¤ï"Ï·éî°`—ÍKmÓµÔÑV=}šÊ¤²+ª3Ò`pTM©™n­S*ËMWÆýç9=¥²Áà)󻵯„…]Z\þ”ù#êJÍ,Ô1£4+‘U4£´XzD](¶Û¦¸ÜB'OX¼Ô±.8de³Þ¸üëVßõÓËï^Û¯±]gƒÑ¥:bâ%Ò¥fŸp^‘öiµYEíz9ñ¢9qýÕʻ͛•lV3Ï`JrDÝz¯¦Õ®ÐÓ§cª¢tæ¦_Þ{]ÎÛŠlJÙŸ´4i9Õë<*™ó@ÜŸ%¬Éÿü®ù÷_™4:`Ù”$]6¬.Tê¢:¯}Æ÷ù:—¯0wT[ì¤ÊÐɘƔ¡Gù2%y-Y÷å|¨ð€_äè|‹Ft°.tá„?ݳ4<ûฉ¸-¼–ð©œ_ó5ö·Ø:åç\“ïïÍݼYör^á]4ûO»ò×_—ÛþPî`ƒO=Þõs÷Vòsºy70Àr~:À2¾Ñcàj&èçïàyöÐÉ{¨׳“N> ›_fšYæñ GY§yÓäèŒ|TOr&²ÜvÿÓ‘^ã‹\Ìr.ãu6óÆu\*¶°Œ3Ĺ,Ò” DeoÓ¼B?˜e˜ y–9Ĉê;uNï 3bvFýT¤Îÿ(^ä–Ð3ÿõXe¸÷ÒIÈ2Ö½A¹…u±°“q.%Ç0=¿?äkkƒwÜööÿÈÞË¥…^˜) Z²iþšLÞ¼ðì,®'’`ÜÉ{¨¤ƒ÷ç~NGÀ’™ˆº·pgãOy…w1—ëø7ƹ‹x0¢Ttø\Å|.êØða~û†ûõ>¾ôÔßÓHM‡C\’Ë*e7ÕÄIÑÏŸòo¥˜û裚óù5w1ưƒ]sóx2´ŸÏq‡XÆ»¸Žžä$W±…a6îo/„g·ð>ÎWÙÄQ†"ÈSayp™¡“±#7Çêûüì¡á’§’š§Mäå‹rWåçíVžðÔ%ü„îÈ ¾ÐâWò—¬ö¸ádþ†Ç]ÿqÜ,üo/òîŒßäýŽäýe‘[ò*CCyûB_ |k‘i³–ríJÓ.oSÜlÓ¤ uê§ ¤rRMêÆýÙ„KGý4ôç¡×rÖÄ´±*GÖX¹…b¡LJåëR¥šk̦å<{ê3±·}kh¢~LY©DRê§j Sßk]ÜÅqÅs4¶é;iÉCcŠÒƒ¦êÔ.r&«´X²SÛžËÊd L)oÓ™4Y*(3Óp¤öÔù}«[X9®zTíK6—š™ïôûóâ5ÆB± ÓÕ&V:8ÇÐ<g6ÛU˜ø%O©XàT‘lV¢Þàr‡·¹|VIZq£-¶ª9jéŒÒ&}kíŸVQc¬ÂtZÉ´Š.ísuV¯61ß©VÝ{m(5[È.—*7=¡*£h®3 ÙZ£S*ç9Sf¦U÷ †Â†lŽ9†á«Ö•H—›^¨c…CU&ú5m_X6sÁ‘ÁŸ~0”i4Zj6#Þ¢o@cÖ ¹ê‹Í®pr\r—µ—:¶ÌPZéGg|aÖg|7e&¥uPwLÅQ§g[RZ5óé»Óçˆo»&˜YPìñuêûtôë>&È‹%ÜÊääüç[‹óéNÙyÊ«½)«tÔ“Uj‹õ>›q a‘O…~^jÉdÊl ‡ \IØ·5/È»«Z¼XMZ6gÁ¨ðpàÁ˜ÇCoð(ËxsÜ/XšUÍ1Jø»)ó˜(Ò­?³æ�� �IDAT›skþžoØó-ý÷r<03í?ó™ôùs¥Zõ~ÜC+|â‡î~’iòlì)ñv…öÒÍ«QÜÔï#?É9qsÖÒÌ-üˆÃ‘äý\îc–b~Ç5Œ±—A&g;«™âÝQ³X`±^MëØOÀ>J‚€1—ïÓSÈ‘`?¿`']ÄHs-etr}Ô¡†‡äA&¹“ÿ ‡#¼ÀŸ±‹§Èò4·p!ë©%Îݼ)ª"ÝõõLòK^g†^ncWD„*HÞ°×ù¤¹Tï§Ûø»£¤õ16òVVó)Jh U[ûÑwܶæ¿+Wý©Ôig÷¥…,Ë|4mì`![#Bkg°šOÀ3\ÍL!B†û"%EC”GÜÀ[y„ß2Ä1·1?f_hš«y‚³’f¾Ã¶HÚŸd3íêñ÷WŽýGÀ«Bdrµdy ’#“âWðjÞß³ˆsˆ'汄ø�?fš[˜C ùhš—æeVñḨº‡Œ±Ÿƒ,ãeÞÎù)»™Ù„÷ÑÅ ¡sC8ÊŸp€Zèe’q†û¸›x‚“|ŸÏ•…+‹Ÿ]•þæaŸÌN6§N}´Í“7¨êÙØÒ7Çׇã½l¦ÌšZ—µøà65{û…îžr÷m¦Z…U¹dN/A -°œ•yåü¦ÔþR›Ò„nöÃ11KTd|g”!Så øbÞU·N9ÍH©¡¤ C­ÐR¤²XgÖÒ˜öz{陵³Ê‰ç…~Y²â™Üåû²«Ž”gšÖÿ¶½Üð”ê)çØÌ¢c›6¹áÀ+õ榋åê¤І4Ç,,5KþˆÆ~u)ùnÝõÖÕ˜¨2=¨ìa *¥ÓJ ô“ aøÐ¼ŠÚ×[*g³ƒ’ÆëŒÄåæêW=£4.?¥’`H}ƒÁ‚u7/^erReµñPЭ-i|P}x»ÊÁY%yñuÚYšV¼ÊëE2qùB0UB¶L*­$._c¬OS^lVɸä¬Ò UÍúÒJ&UÍ(›c¨GkA¿^˜4æÅCÁ”Š S‡-ßhwV"&?ª6«(`ZE£Y%£jRÊN<÷±äeך8׫E²Úž¶&PTe:M\°Àà¤dá*ÓÇ wk=e΄ÚR н­Ì“Y«-)’«ÖÒ£±YKÆÎŠÔ«3O¾­äê#ù–L¶ådñ‘Ç:ò‰˜;âv§åX—w°Ø“ì òë'U¶ê™ñà„e#²î˜U›Ö4×¥£^9Y£;Ô6fch*¡;ë¯B›òæ%ŒVùv¹)ãÄâ–θ'm¿¥ÊY ÞÍõþvÒD軌»)´š0P_­&/Ìù ¢.áñ¸Wjlù³‡ÂM'ýèJc½1߇B+š¤_ur!Üdõ˜É3N]ÆyÜøóУ9ÿÂmÔ²c ð sÐYèvak¾“YžàSÌð$OÓÏ�e¤¹Š –sˆ•äI±ž÷ñ"¼Be¤J_Î÷Èò‹Éð¿ÙXœu;àXB›9Ê»éa-ç0È!Öð�QáØ_zƒ6­`/+aˆg8Àµ$èçbš â»ì¦3£Íç½ìa#'ÙÂä©xóÝ$#¿l#‡Þ@‘=)øZ¸ƒ¼Lûùy¤H¸˜·r°¶vßÿÀ |k*Õ…9–²’ãôó Ésˆ3ô°Š[#«ZŽl¢‡æG̤Qv²‘Zš˜di=Êó`Ì_‡~Ã\Ž‘ç6þ“EFV ©*@þßP®.çÀMP^ÄyL°An§šÍ,âu‘=íþˆ|u-Ó<Â&^ š3\@‚¾C=ÿ›}l"¯†ZC{ɲ•1‡Vnçeþsy7Opzx‘ \Í9œæ0û)ã-ÌåUnçgTUyKÞŽ¼9<ĹܯN®ÈØ•ö3ú½¼Ù×gÜ»ÜH·î ¼¨/¬~ÜþZrÖNÕÜt4h˜Î~®Ñ£¥î,²%ke¡`ÇÔUY•ól^m`<f%sãjB?˺&ã5^¯µuFÀ…=U†Z²ãPèPS>ƪ@¼ÑìŒ÷‡šK\Qš7'ëÂrµ“ž.6³&-3éLÖ ×&Í›úÌ·W×Ô'êóaCuâ35UÛ]'5á‰JË'e‡­Oš“R³³Ìꀸ€é:cT·éŠ)I+I˜M)S»ÁñqSõžˆYˆ¨-• •Äå[ô¼ne‘éeK'[&Gß¶-xæò:Poð5k{5wkM?Ç«Ó*æ*l­5ÌwºO3âòý 4(dØ'×mÓ Út/tr…ÃK6§ÜtB¶D:'žVRÐb¤—KåÅ+LªÍ‹5¨0]"RÖ¬¯ÄlN|Pý¤ªiåÓ*Šeʤ:,(`Ÿú4åÅ[õtš›V2®ºÌLN"”šRyÄò“oß,Z²­½Úx­Ñ>Íg´ *3»Àᔪbùzý}ª’¦:}Ä¥N—ÉËIä%bõÊg,:íhÌÓÓV)ËØ7¦«¸ÿÒªûon«;˜Z÷7Å[.Š·,Nì¹EÍ„4e%&C{26%Œ†y­RlŒ¼3ÌaÙ¨¢ÐdÂù¡ §ÎkŒ«+¶5#FO^嬩Y]1+“ê¦Ï.¶g¸Œ<‡ë­O˜-Õ6iÆ|)o6ôÇ,Lɪ`˜m.ˆù཮Ø^Ñ8}Å7Ãøªø£üÑG“Þ“ íŽùlø\·{_õÝ%\´5óò¹áןpï"fXľÐNVq†¹‡6V±™f¶SÙoãd4Ä+D~$¢ûªh•°‚'©c'oçÖhÏr-û©bg¢eØÆˆ£±™‹iŒ6Lócgm˳Qí4¼¯ ~mì‹JÚ¬¤’Þã¬e¥ó¿¨z£EWU$Õ>ÌÅ\Ãox”UÌãhœtšr6p.•œ Ç, zÃá¼1¢,Š~c¡V5ÓN†“Ѥ±¢ÊàÎüz~ÁÔÿŒ¸}0•*ÌWGÿ½õ”0‡IFØNq„òë¡?šft ÒÊ3Œ3­= v°wGtkøvDÄx9ôŞ‚ Σ2zG¿¯+˜´ßÆ¥ÔP_Ð_þÿÄ*³ôs4⯿…ÿä<:#‹ßo,ºCŒqçN0IŒ§Xq:ÞòïQN°‰~gi¼4ÓBõœ¦(ú(¿Î›˜e/y;i£™-üŠ‹ibG9ŸŸÇÍ:êŒi¼'”È„{ÏêG²ïsl^ìôºÀ¢P%ûø–Kâ£×Øßd^»?ÚûáÇr.ÉÍìå£îP>g7%ßUygÂý3ÒìŽY•÷HÜÅt…þ•5¡C¼;®)ãŘ ï§­/7§Î¢)‡flÊ[Ê™ŽÙ;ëꜿŽK$œ;íœÐñõ FªŒ¨})pnh{`ùä¿ãÀýzÞ“~¶"öÀ Á¶ëçÚ×£xXSÞò¤±¸–“ÚãŠ[ ®PÒ+Z ìµ®Å@\fV2%Yk´GûR§'—Ë•)­ÓÛáüVµFæžVÑ¢ç|»^²|±þ^Í-k÷}ã{«ïÞRnºI_Á¥´Ô± Õ¿pÁ,“ïÔÞ¬oBõ˜š9†²ËI)[àTL8¢¶PÊdêŒd%ªMÌ*ÙomƒÁFýý ŒW“oÓŠÕM)o0V™ „Y‰>M3ÊbÂŒ¢b™iåÅU&ÊÌìµa¹#¡X^ü •5ƦUÔm4pIJ9†Ûu5è°°ÚøÓ®ì¿iGÇ?}Égïœê_8«d©£]Ú:µ×925mqŸ†>óGÕË [^$l–]h¤Ûâ3þù2åErƒZú5Ïè 4¶_u¤û¿QsðÚdÿ›&ÕdôÆœS¾måH²-ßuzNgq(••™±ŠÁŒI®çžœMieÅÞ2lN^]Þ…Ô‘'ø17Îú~Ü ~Äuq r†›4Í:?ïp(àh±ógÝíœÃÒEÊGÔÆudµX—Pš— •ð�ûÙ³ŒöÐtÌ™9kWLßôs{ô}X_Bß•žmˆØ™ÕóŒ§x,°$,žñùm&F¼|i\e&û]ÇŠÞÈ ¸•å„ü.áãy?ˆ†`bÞŠ(´p$"¢a%—ó0K"öÒ>>ÉvâlŠ 9…íW<¢?<Í‚èÙ7‰EÑE¿b„ã4…úø)\ISüœb®¤šñˆæº.²÷䌺ŸÃÌçv.XÞ XƵ|8 ;.Ðynç 3ÆAn̦ý¤x'‡ rb¶GÒëîÿd˜d!'é`m„Dœ áâÈw<|ßxÝÁµ´Àÿs¹úa*u&êŠ:¸*ñŽÒËÛy™ÉˆF‘}C­*Øi_c»¢Öjœ÷ñ‡,â[š·•«¹†$GÙõ:G#ÂÅgL>ÀþH˜_eU[Ùû†�‘Û¹šS¼7"ð6ŠìçöÓÊsŒóNð5óg¸–•ÜÆ6®¤›5<Çêx„ulã¯x†­,"dvp*òî¥ÈDíóÉ(”òfþ á¼¼û)-rSÞWÈÐx8¢ /É õðŽÐ@h#i¡œµo«¹aâ—_+úÃr‚5Œ¸ôù†É›3¯-ÏÍ|GëÆÌâïå^.lk¿œ—¬‘ä—Y;¸+ë×3ÖĽ;¯4î’œTÜŠœú -NX¿Bã°Ì´c|µÒt‰«¦äòÚs~7ëëyóâþ¨•q‹HÌš Uò¼ßÍû+þ ¦%¯|LVc`]BcNQÜ9‰#kóùhÕ>_6žŸ¨VtÚú¤d’^Ë4œÔœq4Ð8ë•Z%µ&âRꛌ4>ea¯L [ª¸ÖèŒÒ˜|­‰:£åLYžSÒ£µ×þ„yc’5F›õ‘U\êùÇéxÓ‰«¿¸iLÍ~k°Ì‘¤±Ô‹Ë¥•$5é?m^»®2©©Á`‹Þn­³J;.s4Î*YàÔ\S*ªLÆåZô©o×UazJå/;o@CÒx«ž”òY%1ùéç\Zgx©cCêcÂÂ8q³—òâ…æJ‡2Š&UN+_áðˆÚBÉû îšóú5Íu¦8Hu]}øÄ·¾´é+W”?vYi.Ó¯©[2,ÐÕ,=hþI+úžV½FgZÙI »´¯µ@cŸ¦qaµyóHQ‘‘ “å¹}w•©’¸|ø³wgþä§k~z®D__¢zú?¾}ׯr•ñ™ß|<´bÒ'¹/&˱Ðc¡'ŠüEÎάڅâ•âc:š<:×¥3.©[êÏK³>g,른³:sž ˆ»‹Å³vó0yþµÈ-Sz³‚´ç³î¥>tšgã®l -dUhU¨LQ¥í_H¯y!ÿ·^¹ÙÁ+\ë`ÖÀ‰¬ÆPwÆÄÉÆ­ s×ûÏf‹ßÿYæµF?~PÛ°_b+Wñ 72À®Ðvj¹‹_GúïÐÁÆù;ò'‘ðÜÇZ¦ØÊOháYÆOy‰‡ÙÁqîà!6ÓÂþ(ò±——¹œÞË+‘R®ÀR˜Žz”å<Ì4Yêhgäç±›89öÑÏ)ó!æ{ùC^e’aN°‹DÄŒs1°ˆq9¥ ³•í‘ á\žãL´ûWRiܺ9acC&çŽ(|ª‹I®ã¯˜Çâ|‹‡ßP®ÆXÅw Xmíß¼ã¶Uÿ33ÑÚÿífbÑÝü¿® Ê©f†¾hXy%Ÿ …gyŽÇè"Ã>6ð ^e[4•îäuÚ™ š·òoÑ‹ï&Ç4ÌDjˆ=¤¹!ò?×D¡\{9Ã6Òü-ÓÜ‘ßÉOØC3ã<îæDä¬LÇã4qŠQ.˼D {9ÆÛø;jhå1޳—ÒÀ|ŠèV\ïãÿÀ<Éu<™×ÇN.Ì›åšÀ|¾Õâ¶)ƒlàyb|‚:n ƒ'Æ_SÉxàòñó?ký¬_ÍÅ‘Úþ”¥§¦¾úpþÑ=ÍÅ k‚¥“ùWßdæoO³3¥!k=¯Î Ü’÷¼vNåt&C­gtŒêé4•õ�WÑ”14kc“Ò”‰¸«². œ dÇœâÇKJÈ»;t9è ÜÓ䚤F\ʉ˜þ53jrÆsãgâÏÝêñ'Ú o- ²G‹”·8’Ôª˜X(O˜s²Tk©\•ÙáëVwi+“ZnhHýˆø:'¦UT˜nÕ»Í%½Z[t7êŸV¹Fj\u³ÞY%y±3æ§jÒ#_ùâôÎ+6¾û/vXU"FУuR¶H" `xêÑ“?aq‡…íR¿É+ ¹~óœ™ïô°9° ¸Xéà°º”²“™“RVm<«¨ÌLVÑqKÆ%Ѧ«IB6ˆ,À;Í-’™cx·«(’éÒ6¥¢ÚÄ”Š"™˜|—öŒâ^-%f4äÅN™¿É+£j;,˜V±ÜéPPcôˆe÷]ýZ͵/ÞyÍ­Ó;¯LçÊ–:֮󘹳Êê|ÚI§2Z«Í‰ÛU«fPØ|•éa £j‹eVèè´î­]^çÐ%KŽí|¿ç.Šäý£C£ù/÷«?é|憉÷o ßÿëØ_| ÿ¹?Nü朼SµÊÒ¶–zä ·•˜7d}àò&õÓz›=5dóÃóÄŠ]ݧtRЬwÔ§óªBqO‘ÏP˜É‰³|‰Îa§CEáYUاé*òZÎUãÌaI E6ðë@M ÑPMÂê¼—ÍòRôZþ†kLo§Œ/1—_±02}NPŸ÷Ká)C#±—kƒ»ï ?ý3•S‰›÷å½-J,:ÎNF‡¿¦† B{…Ûù¾Îõü6ÒN?Cëà?£x£/ñKnaÏñ‡‘Ѹ߰*ºia9è¤7²ôþþª#x=¾ Kš2.§_SJ=‡¸9 #.€Us\ʹ<Æ/GA$éHË}+?7ó ãþˆ4ÿ$£ôpkÝ÷ÃHO1ÀóÔE€ö©(÷d–¢2•ºIæ0ÊÜÏ·£á|%r4ÕFÛŸÂn¬˜|mí×Þq[ü¿+WϦR‹ßÒ|"0h =ù†{×þ8S;ç²”NÞL?/RÍ7)~CäÇuð¢àÌý:7FÑa+ˆóIö³œ‡¨`St+ ë¸öH…¸>jª°ŠM¼‰'Hò>^a«i¤»©e œä<n%ÆgXFõìàNîå6ó.%‘cŒCÌã:""û^æGø[ân"I «™¤‘JäS̲ŽñOŒ²”·R8˜z}ÒæF^ú tòs°“1¡#Ì!wI¸m›ŸÝlÇ%ã5VpÊžs¬?‘¨kÊ?÷XññLñ5'Ó[ÿÃö ãéXxÖj>^p‰‡–’£Š¿-“¬rÙŒ#yËY:w;gèŠyo\SÂg<Ä…Lç<“𼑘 PZk1×%}.­­ÈGCçÌQvB˜ÎkÌËNùeܹy¡ºò‰Ì‚oo¬Èw>œoÚ{é]’)MMƫȨK«J3ÂQ%YõætiŸ¯³UO¹T¥©VCs¼nUÑ‚µ¶[u dJa¾žc–.w$/V$;¤>.?wë¿?{çɵ÷nØÔÕ×l´Øä›íÚ£¸Ru›îœxa×­µÖh(˜QVb6+ѯqŽjƒêÛtW›¨29.Y¨+eRƒê Ô „mºRÊ4Îs:«¨ÒÔiócòý[õ`VI‘eåR ¹Z##êf• ™3ª¦I·¶R³s 5ž]é%Ò­z*LÉtX0&yŽW tkPõÊ[ûÚ.¾þý嘚 U•&w¸ð€eREòÝæÖ{å°35–l²;´ˆT²¼Ä°dÌl±§'œ3¢|RuLºNßž|ïŽôé¥Á¾9«¿Ü+¡ùTIþÛçÇ¿ýÎø·ÿ¨´ÿçi•¡=¡0.ž68k㘠¥’ÓVgœšÐˬ֜¹yÁ°ŸÍX*Êž0?æbÒqËBOç]—ËúUL{Ìkƒ*b¶28/ôJ¯rMÎpÞTÌoBSqãwqwæä|3p.‹Ê^Kßòm[ïóÍøê6ê9?Ú']G·pŠfvó,![8ĶХ¡ímðóÆy˜N¶pŠ}\%ƒV/aœ±‚Ç‘uÜÃ&–ò]zù;¶ÑÀRgÇø+y=ê92‚½‚~BîwVuµ‘jöGúç?'CYôƒëé TÚi¤™)Z#rÂÃ<G-©è°*[XF’“L²?ÚЋ^6ÍR,£‹"Zéc„+9¹Q‹¸Ž÷2ÅNž‹^¡p’'¹‚¹¬â(%Ìe„×"UáïƒKR¼‰IsŒ€¦(…²—2æÒNšæýÄé«­÷ŽÛ–ýwåjG*u Û)¡‡ Ci’Ñܯ•‘˜­03,,è I_UÑÆ¯#Z9þ 2úúC¬à_Ù•¨ïî Žs—ÑH6²•¿Ázöa¶E_„ãÑýý(Ûèf> î‹|óx™¹,&d¿åªˆ\p§Þòs¢„­sØL/—1/2.`Ì·qQÁã·‘åq—‡…:x„vs.;)á"Ê¢ÄÈËæÇLr¦žÍ÷|/§¹Ž,?fWS3COÌWCIf( ?¼ß ký˵ü Op«7óRþóZ²Ïÿ"^è‹=” G»X³™ƒ1¿Múç§9M[܆"›‹<ŸrŒå Í¡ªÐ—óQÎ{Cµy3Õ.)³,í¥b³^ãú¼¾©R6mMÂOš];¤:¯.Ð8ª+/CŽÁ¸¢P¦ÞŠr¦Iœ°göHyâ¡Ï«FKöýv®±N?vδãq3ÕFËTΚ_®3T—’eã¦ËdO©›P5¦¬ÞHVq† AVI•\A2^i¦Ù@Ÿ¦1E¢jã¥föÖ¾ýµ _¿¬ù…EÕÆÇU½b5aBP¯8£¨ÎHÁ“Ti²\ªÃ‚"™åµ¬S{»Î23q¹~9‰´’ƒi%3Êf•Lª,5›QTj¦Òä ‹ÚuU˜šTIKÈ5,Ä9N©H+N¯1ú²sËM—KÅå–9Ò§y®Î„ܬ’´’Y%YE#j{5wi¯0 +®v]gÌ›Uºïæ£óWü®ñïoÚ“?VmqNbL²ÔdÖÌZ§b‚vX8nYF.£®ÊÄQíyã LT™hwjLohQJlVÇJ#2£‹‡sOŸçÞ[búã6ÎèÎø!k“¥U‡,sm……i˘¨TZÑêp·‡‡¤ÒÒT‰ÛZbqÎÏ2îOøBÂ8SY#1-¡ÞœÇ©MX÷H¨*P–÷t­E3~—Wx>´”c–¤í¬6šv*ážPm^ŽÍy„ªØ”pcX¼§ä?9«Çor^=Å2*é"ÉbÜÄ}”ÐÄVR„Ìò1*ɲ€)깊æOyð ^¢šaÚ™äËÔp—y=Â5²‰Ç#ˆh=qÖDô€Í,¡¦Ñ¡Ç7Óȳ̃âò ÞH‚Û +¹„SÄ q}UÊB+ó^§9:ô ±X[£Šu„Î0?BTQI³43ʼøÙ½ÌjŠ%Á¹e7Ȧ#µÞœ(³bW°šcÌã5ž‰Z½ZÚȳ”›9A’?~ç2Á|–0Dïà(!µìe2Š9L±—Uµµ¿{Çmwü¾\Åþëp/Ñ/Šøý_ ¿aG5ÁNnâSÑŸ4FIŒIV#2¾®«hæ6gwmŸ ñ<Î�ÐéoäRŽÓýàÿuýè íÚ/y¼ÂL•¥Œ³‡÷Ž@±…Ú¹ŠOó"k9Í^–q»Xʼ‡“|˜û¸€Ï°ŸçqÊèæO¸–FnåWQèY]ÞÂÐykœ­åÿÌnª8Ÿ^àœmMfxŽoE¶³zž¬¹—‹#GÅ.emÌÆ@-ƒ9Áù$Yæ•Ùԭ宎Jà6özôÓnú”;Žp­íŽQ˜ÛŠñÁ¸ïÏÈ1UàŒ„v¥TzKÞ›Cçæ=E>æË\ÀwnäKqGåKr^Ië,ÄÛ$”×ûẋš]Ù.6kÓiM¬Äò¦ó>S(ætÜÊÐµÅÆFò*'Œ 9‘÷D³=Å>;sÏOOªÈz[ÊÂFËsæÍhžëL¹éíåÒY¥3*:Œ$&ÍÔ˜œR3¤á°ÿ¯ÓhNÅÆµëŒ‹µéËu+O«˜PuÐÊ#—%OM®=Ùº}Qµñ”²P¼ÎÌ*GÕ'Õ<håq‹;,8dEN¼Òdƒ×¬Ýf˘d“¾´â.m妋dZuçÅbòiÅ…ÍV‘L»ÎB›µÇ†Z#£jBA(ÈD%3 h“ÜoM™T–>Msé×X,]nºÆh–f½…©à¬’^Í ö[3­¼ÒäÇ^µ®°÷ª4yÔÒΟxÛ“§¿úµÔÓoËÌMZXbv‚&ÝsŒÎ5Z$Ó¬wBUœbU#jcfû4ÍJ2§B.¥xJmÖ¢fKô$Ñ6zù‘éöùã÷†¶eÍæ¬qù\ïiQ5ãëåJ+]8®©ÕD¨!°`HÛ´Ú!½%^¨'Ád(žs߄̬e¡]yñ”Ö”šÐ_„¡qÖ&üUÞg󾆼GBKfuÞÜhs¨ŒD`}Ì…¡Õ3Ž…®Ìú÷Ð3qí»ÙÅ}e:,úþø÷Çþiml÷‡8ÄÔż9æ|‡½Ì­¶¾Üªˆ?ô5Ê9˜°™7ó<l¦«¹”ítr/·0–ðèd»ž"nà_*¤ªÌ‰òÊ_¡‹^z#ùÀvçߢðØvE¬¿wò ¾ÉGùh$˺î GÜã¼F?—8F¡'CÿD/QAsÚÂÜÙËYÂkLRÊ5œne/³‹)Ò<KKaTÃbx</z€ï±=QÁ( ›6²€Û9DsK$%dWSIÃZ‘±ˆ;Åã<Á{hcŒè®ng-¯Gy("6Uë¾f€ZN¾!1þŸ6árú"¯Ölg†p Õ즋ócÖPÇáhØÂF #ök!o~˜XÚÊ÷çz¶ó.ï´�� �IDATÎ0Á„³ô£måUv0}.¥šþ¨?-å2.ቜŒÎÐ ||$ éŠ6¯³#Úm¡…cÔð"m ErÝô³‚mѧ6`7Œó Ú¹–ïq˜v^d ?dËh¥”¤ø­ì‹Ü]Ílàœ"ïÏkâ©„kCwä;´ùHÞH´¯šÇ=Ô„~ZÉ»øÑA½î-Ž~É·Æ=üç2ÕY“÷�w:Sï®gÝý—\â±ý~újÑ~š=Ë‹ú›Ð-YŸj´±Ò–i_=šeèc]è›|‚GÖóh³s¦œãÚ)õ^ÌÛ˜óy^eyèܸö* }ÊF}¸Ùícöç<Zz_‘/æäC‡Yš7]å@¹d·ÐgŠ,[[<Õ“LÏ|qgöí¿.½åÙŠ©9µj›ÍÖ›Xät·šIµCŽ´Š/¶+ãH•Ø”•)µefŽyºÎÁЊ…Z™¿Êñ íÜf¶YE(’Ì‹Å-ÕQktTm½‰¥µ¯¾øæÉ©Ÿ½Hýà ò‡ÍM+*–oÕ=¢¦U"Ý®sZE!cþ.w× ŒƦ•Ï(-x°Š¥ÇU§•L©H/5K×K)—,ÌôŠebœx‘ì †ÖTš¬1–“H‹Ë÷kZ cRUB®K{ÏtÊü­¡ØŒÒFmºf•ŒIÖP“¯3‚“ŽKN\óBËKs3Ýt~îÕRµuF*ÍÉ hª”J)K)ï° ![mª\,r訑ÀÒ^•¥ÒÝŽ«Ì+V>áïÚâëO^úXsc>öâ‡êÍŸT™q0íüv}]þ.k:mY\ã˜ê´Ç •¦•ϘÈh¯ÔÙì‚i½ÔŸj`OÂÊÀcy[é®WŸs(çíE«T%LÍj ý}Ì–˜ëB³E®K;5k:¥7t~Ü—šl÷CÖg=Tä£9f^èV~›ðž¼¥e/.:}{îö…oåùÀS ·æü&´‹<·ð¯MY¿Íc3» q…¡&ÞI1³Ìå'g)ÏÓÉ$ÉKÜžUTMÐeƾ+çLÆ#¡ ŸŒÀ§SQbaî—æÃ죅r^âý|‡óÙÂØE+;XÈ‹ PÁ9ôùFÞ#d¹<rõ^E†V:"rÐ…9[BÿÆ2¾‰5Dþ×Ò|¹ÜHš x/ÒHŽ+y‰+9Ì>Žrc4&ÝÏñ'ÙAÏó!汞8Û˜fš}<Ö3|€?dû#•™rvD/x0%ŒŽÖ+9ÆIêYIKʉGUc¦¶¶ü·Ýùß ·¥Rk¸éÿvßaržõÙ÷?S¶wmßU]­šU-Y²l¹7Œ1Ûà¦`!„ÀÄTCB0`06˜Ž{·%[–\du«kµÚÞëÌîÌÜ÷ûÇèæ5Çñ&ïþ©Cš™=´{ýîëwžç÷dœséŒ&PÞø°…ÿdŸä ÏF$’s>³Ÿ„$x+…|„C‘!ð~¦£&˜§8Ÿƒ‘ ²ŠÆ™¡•åd„œzƒ%?¯îãmü.4?TIFcl‚«ØK†4U¢éÖò;*hçdþ')é¡@2BÂçñ€—²š6>Äü4¡=¦&ô ØÌž"Í $óݾÑná¿8ÈMù·ˆù@Ì÷8+p)ê3ü¿æî£"îp\m\DŽ’xšÖ˜ðÃüƒl“Ow[ü+,¦>°,f]B:f6´Ä?w×fž‘Zï²Éàä½»£ÉåÔLòB¾Þ4¡-i"PÁobæxÏÇ”®œð/-¾›41(ˆùF¡OgJRÚÊèÍ8x>çÝãN^d*¦.aí9’§•ªa<æßÞ:b2iQpö’p™ÌƒÓ÷Hë]WóñÊLMMëoR\ wÀàá1[“zÚ-íRÕ«¼Ç‹“JC ¯ó›ÝªgÍË(¯“+SœU4¤nVQ•½Uê2–R1«:%]&Xe¿¦çjÆ+¯Þ±ñ¾öÅŽï³z®ÓæŸcÏ<=ÝZSJN69QU¹z¢ûˆ¥ÕFóp£i¥)%K)6s\[ŒvÇj ©cdVá>«ç^àTçš‘™¶®äéæP|BE\Po '‘‡Î(>nqZñ:¯âå&jO+ÉJVWÙ§±Á@ 1ª¦Âd•3F›Ì;mn–ÝÖ­±çQoSUj:£pJyB®¤ºóØæáàÀê±×—·>dù ú´Ò2Ó­ºã²d:T—›-3}\bL¼R²×ÜÕÆ›õ˜ìÒW¨¥HiJaZe¡kzV‡øÅÔ_~>49ª¾T²Y8cq•\Ÿú¤-ôÛœO Ž[ó›„Tƒ³&<š²{ÔPào†'  =ØìŸRJÓŽ~S ®ÕÁœÊœ©P{Îzö…‚˜ßå4'mÌŽ[”P—38é§”ó6zµ4GÛÏ$½%류¯z6îaQ,8çÇöµ™XĦУÔq6÷²›;C…qkyˆ*~ͳlæ!²óx‚ã”ò8òçü$âhg9îLyq´"»7´?T;]Kœ¢(}•ãrb<Â÷£dË<^Š =Ù¿EŒ2ÁÞøo.ã7²ž#QU^Þ}ç uòS.å8Ÿb:šÿÈ0×ÐKûùG^g1¿åƒÜÇrF8‹su4žˆ(…<@H)qjèæIöqe´=z(šÊéˆ ;É•|7ÊäcEt£*ˆ‚Û5 išwF"Ë}ÌPÂh\}‹ELRÅGkjü/"éTª€'˜&Á}óî† ¬àiNó@^CŠi¹žIîå|ŠXÆì'ˆh½d¨# ƒh꜊nKyËF%ó¦ˆÊ#ÍmMÑßÜH7Ó4p‚&ǽ“F–²‰oå�£›Ù-Qåñþh9û;v‘àr>˜æ)ZâÊh§ˆ¸€6Æó\ȘÆÐƒæJÖQÅ~Þ›—1ãg¢$/³ŠWYwEè>fâ&8Ê1.` ã–…Ö2¦¨£r*´6ô¯¡Ó|5ìäT°*¡4´ŸHÿ·§s–uëÛg ›ËbvrOà9·ÒÕaëYô1æÁ+Ýú¸~ËÙ|&nÎaJ++øÏJo]W¨kVc¥¿˜±!ðsJrF+08岘™Ðʸc1—°œª˜OÅÝZäõ˜®¬Š¸•¡XpYèµiçÌØ[ëXN[¥Ëõå4¸ôžÌOÿº¼tv¬·ÂŸ¾/qbí°ÆUz,žP•K˜W£oغBmµ2TÔ9•SµÔ¼´ºãšWè+Ö°D:¥zF®[Ó°†¹N‡bõ†Z0jùrÝ£*& ]èP‡æ¸°¥&5zõŽªû®hÒ“V:­,O+®5Ü­%Ý8öÒ×5S•­Ú±âÏÌ1rT{¹©=14,pjRy­á1U1aŒ.s§•.s¨ÚhŸ¦;ïÙ}ߟ \rçÆ¬dL˜UP “U0£¸Ó¼ËJ)MÈ5ê;hE›CjñõùqJI‰ô„ÊÅOY0«£RsFa•ñ¬äBµ†ÊMVšU3©|\Õˆêm[f›6<¾ô?.­3U.U(“§iL)Ÿ«kŸ–]ZFXlxŸ5}ZªW;ЧiŽáAõ§=“ÖP«ªNÇ”¡Œ—æ*œ¸m[éþµ%¯­(V7k¸Tý¤Ò Þª²¸Xmê:©"Õ)e¡c•´š´‰q3ôÆ­"¨âü„Êi¯—UÚšð¦R ½>ÌÜÀšR¥³:ÊÔeÍykÊã¡ÅÁŸú…¡v–ðs†ØÀ ¾ÅüЪ¸l•¤ìÌ <l∆ œ<p^LG²“?a?ý¡Wiá[‘N¼”Ëø'æÇͧ…ƒüð#®ˆà~96ðAJcVÅÎP´G¥ SÇ:XÀSàstSË·ò4%,¢ò ͱyoZ1/PC†7°€—¸–gXÀ­<IÆ•s” óNŠ™àý|–YåiæÄ`!m<©þQãp–\UXÒÌ"Dö´cÑ¢kn´ l¢Šzìf+iÎeQ^á^ºB&#{Ý[©ä$=¼À2Úá\FþÐÌUĘO/]¬£…2vr§jj*Þ˜»Jþ±84Ëc\Àvq$Ö²<ðÿî}.çIrÄ(àV¶q7WF—Á4}YÒ÷ÇdŠ×ØÙfÖPQ:B£˜‹£,ÞµÑàÌ¿xòœ"ã+ü;C¼û ëÎU\ÀSÎ\ÿŒ^'hz™¶0ÀiþœCü˜&bÜÏμÕ2ç]¼Ä)îŒÊD `;I®ŠžÝVÒÅOx‘÷ö1ÁŒQÛO:»HÍ„€Ç8ŸNV²·ð2çruü4ç/"±·rh$~ÿµÞýBð½Çœx=4^Ýåº×ÜôB¢öïrî9SôùW¾òÆYF¿ }€WiãêPjVaÆ5t‡Ò+’IXVs,Pø)—ÅÄC™œÃI†fC‰Ðµ9SŠnHZ9Çl¿¿£;'5ßX§\Lɸ•ñûuÓ±`i,¬()]ñ·wJ‡gËóÊËjUvšl74+ÛkYB"¯7Y,ÅšMž0•±­À¹CjG5·êŸÏIâI3U†*7¹@÷ŒÊÍ'5,×™1•R2 ~JEFIÁRÓ%RGµ7ëyÕÜÖ­msŸ¯)‘JÊvkYìX­¡"3,r"'‘›R–Ÿ8iábÇ*LÄfスNç5ªq•3Š*L ©c¸ÐlL¸ÐÉü|Š '•§gÔšUجç¨öi¥ ú»µœc&¡}Leƒþ#qA±ô„Š2S³ kŒšÍ(˜Pq¾=Ç”›“`$­xFQ(Ö§dÂʘp…Þ@ìÊÕ ©œUxRmJæ5OŒúL ­Õø€É)_ž´¥Qåøÿ}({Ó+ÁêÉz`Ü å¤RNLy¸FjH<çt†q5ÍfbĨÈû«œOQ4LJӪӊâšjl/PÓ'›TФ­_jÌ’œÒP/OÙ·6©>¦)¦6pOx†Ýoý.¤0îÍUf†ÏÈ6ý1ïŠ[* =zK^dFÄmÝ£-ô“ß3 §¸—¥œÃ/)¢ˆ«¹³Î­ƒ¶E°Ëy7ÍÑ1rO°…ãœ$Gȳ4ó]b¤‚,'¹šj ¹†Ñ³øf޲–0âÏåùïäIž‹î ùYu oËy?`CLUÌüàÌAwÍMÚ%|ŽÜËyчÏÇEF³% ÒÙ ^CÀƒo8ó×µ'‘ܾ ¤u¬ˆm ɾAO:qºWD§Üöèó‡oxåQžg+Éò$í¼˜× ¢r(<ÇÙ¼ÆJ¹'zÇKÙÏPä„ ¸Ó™oa3‹£ òÿ­]¥R/0Ÿ÷ó'è#›ß\Ež“?x.Np Ú3g†U$ÙÀjøb46QÏ=ÜJwÌs(Æ™Š}äà£.–¡¨=$•.ÒÁ­ùÜ_h3»ØÅüžÅì Ç[XB[©ä“Œó3|˜OrS4,ÛB)~ÇÛy™–ȸ2ÃA’¼Â¹ìãÓSù4}lMsÏ3—Õ<ÚÀ‹d>3yá‡N>Ê’}?°7°7Jv°PI1m”qWó}ÞËíüž­œïoˆÝZºE¸ÐÃ'»È¯“îÔ§‘ü­ÿ¼Ï]i`™PAJ]ܱ˜ŽÐ£³.d=IkfÔÆT¸0çɬ’¤·3x“ZÒ m9?ˆ;;Tœ`ÓÂ÷X–u4°8î÷¡LNSö }Sj)Õ:+ÈÒqvòé+3ã n¿'þÄÄý9+Vz¾Ã#å.Lª •Îèh‘:G÷!ý­j“š§”µ9Þ£e“½¥Š,éÓXdh±Î ƒóôí³ ÇâjÓqS‡5.Õ9 á„¶”Êb™Ý5 +¯¾ã}K—8^g()·Þ«ÄFÕL+[>uzÞËGûׯ„)G-©6Šg%K¤õ×9¦½Ú脊EÓJ+ÇYÃj[ôœûjæ’_Ô t]g¨ÒÄ) ‰õe¦§•&å&T›éרi~©ÔbÇK¤šõæÕµP<£ oR[o°@f@ìÂ=Ö¤•L)ëÕTelVQ…‰*cG,m®9¸÷³lþ§ KFËw›JioÒ_iü¤…Õ& d3E:çé5÷°eªW;0£ä¸¯ÎxG(³u³æO9Yi ÞÍýÿygö½ÌôNÍÚÚ*Oû|`-CkBÍ^i¶}ÀkRv„ªi¨ËØ“3ú +rîJ+ M'¬Éiœµ`½©Óî*rÑ”_ \Ȱ8T4£;0>«*Ôè<ƹŒ²™òÀ½9-|?ï®ô` '=ZZCE–„аäÏ=±GA¥ß§Øž‰»~œõ¼Àvz"£òÀɬâ¼{0éí ]¡ãlâ×Å&*,M y‰¨àCœf![™Ë<j9Eï‹â¤\ÍV.£—œŠŠ€?Ë—yžÃôó¯¬bK„ˆ;L†,Gèæ!è8Oqškxž_ÑÃ$ C·³†£áý潌0É,Ÿe §y𫩉ðßQÍüÈð<¸ç)^ŠÝ‘ü¶”›yŒôN9ê¹*jBÉü.f³™ ö2Ä4SÜÌv.Šî”ù–ùIºáZΡ*š,?eŠ5Ìe[ØI‹¸¨¦fÇÿ² ü^*õYÀ=QSÙ»8ÆgÚ‘Ë8—ÊHOÊ¿ëS|Žߊ,ì“‘:w¿¡–»è¥#o¨¹š$÷ÞR-qÞΡèæ[Éåì‹l' .äéæ×lâ7Ñy/×0qõ8Æa^eš `?|ˆÇ¹š÷ñs¾Ï•ô6Î!ÒÑð§¹…r†á.ä¾HC|•U¼'ꇼŒ{(൨ ì^¤Ÿ›ÙÁ‹”Óz0ð>ÆÙÊ_±Nm¿úÿãècÞ»Õ'Ýñ{wü<~Y[bÇ‚ ø˜Ù¹•¡ÐPøÄÿxŸ[žwýÇ<ó'úuæ¾óXáÞ»b6ëGR.ðz̵Ô„’¡….Íy’…¼¨jeüŒ©¤/§9pGÂeÑÓÚ"½5Æš ¬ÉŠë+÷|Jc(×hѸâ¤kêTå”(H©žt$ëóu®+_¢w¢o÷LêÎÔ7_K•&“ÏuÖ¥lJ[>íÕYU1…‹ :kÀòƒæ-PxÐYý&9ep±à%˺•¨ª3ج;£*¥*­d™Ž“ÚÊLkL‰÷[Ø`0!7O×9ïîœ]ØõŽéçÞTfêUë÷YH”Jõji00Oß㋜8iQÁ%Ž®²¯Ã‚Åi%ÕFK¤*M$y7D›¡Ø³ ïwsWb‘ùÄU­¡œDFᘪP|‰#)%¯YŠ×î°°ÖÐióBñcW˜˜c8£`JY¿ÆGlºÊ¶ÝÖ%Ãj7yiLõˆš£ÚóŽöœä) ñCíÉÉK_nüÞÛ2 Ú̼dÉ€…mNŒ«,5Ó¦s\}LÍ+Ž8™Õפ4'9©|™³ª²²IfÌm00iSÎúï1³jì›'“·¬ ~õƒd×ÙŇ[×­ÝŽ&Är*)¬ÕÒmy†jÙ´òŒ¾¸éjcSæ¯ÒÙç¡Y}M9C³zs¦B_éθ#­:nMÒº¬Í ›b†içúÈ Üó³VžöRèVR1ŸÌz¥PeÜ .ðÅ”ŠIñÀJbùXgàõðåß8=ßí)û:Ÿçi.àk<阻XÇVÚ¹4ë5Ö°ŒwnŠ­’<Èçs–¦½Äƒ¼ƒc|–×(dY43s1ƒìŽ´œ¼?"Ÿ¶ÌÓ’ç Ë¢™ÇèH7Ï©qÖ´Ÿ³›YÊ ˜ 9ws‚[YÅËÔñ4¾œgç³+=lá0_c)ã:fØÏÕh=$H3A9~âö¯yìçF6òin¡‹i^Šxâe¼—­tq2ÞÎct³› ˜¤‚§£¤l–^Â^ði~ãLéîf–ókÎå;áÑèü¤Ï™ÆÚ®á~]S“ø_¬O§RKù2iv1Bš¿¡‡u”³™—Éòe^àôDAÚç( ’râk¼ghç0#Ô2³"ÆÞøõI^#I 'h£—½œî¾’Ÿ³“EŽJ7vrœÝTñÆXM= ¬§˜6òv.bšr~ÆÝ$£ ²>®áûpx&î·ˆ*î–™Ÿ£–Ÿó^ƨ�_¿`~„ñ½ž—)Ž[SZÍvN3AŒ2ÞU“ü€CqëB-¾Û=¿tã1Ï,Š_{vì®ï…wU»ëåÄž¯gÿãÏ Ïwèl8u?Ke¿î·úÉGÌœ’=Ÿyü3ëyIJ-VŸH>ò“Í93ìHZúBÜ©Ð9\¸@˘$K9EwNYÆWæx[µéq•ö³,ІLg «)´`ÈÞ9F ¥-`[©¦´ÎŒç¸©Yi¿¢2ýƪô´¨µ|ÚY)ý:sž*¿·bÛ’ÄòîÚCïÏL¬^á褲:õ…:ÆÝ_bËY:†µÌÊfTÍš®RêkZj ¦¢´\B츾R]jkMæQk âf¯÷x»“¥Rg{-.|Å‚épÎ%©Ñ…™Š§6eV+‘î\–jMžJL½dÙ´Úœd­á@¼EÏ º6·9Þ£¹ÖP—Ö~&^²qŽá„ ÈìÃÅf¦•M¨¸ÌSiÅ•Æóÿü¸Å1aæˆ÷k<e~“¾Fý&bÂQ5uã‚>MùÊ1Õå&Û?Û¡.­{­R×îè¸ÊãW˜\k÷y¶¿dc¡Ì¤òYE»žüì—ÿmL‹žu—Ú1«h¾Se¦ZÑ¥µK˸ŠB4Ö)j2Z"uPÃaŽ.U^­«Øô)‡ÊV.þUv]OðãáƒO‡%±;?,ß¾ü`ÝžÉyEæf%C5¡ßM+ÍøFJñˆ…9>&V®²Xᘊ:#ýê\CYZw~ S˜pmÎ}qkÇCd=بgÊ÷C›BIãíü:náúƒslšu$ð¤ 4Õ()´>eàBNYà Æ<_¶Ñ¹sÃ9nn•ý+YLŠ…<F†õIçþk©æ|„nùRLYx¦x) €Gi%M)ÕLEœò#Q�+OË û¸œ],âFÖò@”ßÚȧ¸Ÿ£\Èæ7„D39}Ó†¨:Í?wVLQè8%|6¢ÜöSįØÍæ¾ËR.ânN’e ø5 Gu€£‘_q\Çü¨Û7ÿ] ÐÎ$ÍŒr<ú\Ñ>6r‡#»Ä).`/ 饃‹È°I°,Š©åÙë8͵¼ùøŸg2*žÝÇÚ¢Èl–% SM ¼—sø*¸²¦¦øæÛ®ýŸÆU&•:ÊI3C†y<í(—ÓÏm„„<ųø�rs襂\D1?aA¤N-gQLŏÐ,›èzC-Èó´FÙéutþ±ï~=Ï“e$‚á–0—}ÑFñ€ö/³˜³ŒöQÎ êx•ÜÆ<ZÙOç’f' ¡§CeüЇyŒ“lç–ˆUŸb”+8Éù‘‘t5•Lñ(§. T‡ŽÒH<*#øw³–u¤©aC\[è<ëv»é ï¿9ñƒ¿ ÇÌ }3aK®h—ª^»?êâŸÙòƒXÂø¾+Ã3X°:þ†u¼•ÇÕ¿Å'ž²>凗'ž»"ÔÁŸn‹‹‡ŽÇÕ¨ }.¡54L]…®Y ¦¼œµ fs`oƒé)Ç7?4NUÊØ¬¬Ü„¶„Wb…ÖVÙ°}Ö»ZcFg ”(šRv„Ú*¿ÓGŒ‰¤? Lt ̘ûSeLÇ—êÉ™)6Ìþ&K3bÓ¶U;\¢aHiƒÑŦ3êG jŒ ¨ë6o©ÑÐl½S5r*‹ÍŠˤ•–H°¨Ccì¹^O”׭ع¢oøÂÁׇêÃþOÜìS”œ®«:Ô|–㵆3 dò€óJíŽåá¶9É)åýÇU®´ŸX‘ŒÂ • œJ)™TÞ§qH]N".èÑ<W× º*ãå&‹ÌÈÈ4êW™RšRRd¶OÓ”ò|EȘê^Mµ†“²…I¹¼0'A¬Á@¹©)e£ª+Ÿ°hÄœe¼ã¹Ò»Þׯq\U žVØ¡)d»uç۹ǚ±”âVƒqEkNI*Ó<ß«šR²ÝFë5o¦ýhî¶–O¯™iŠ«öÇî»,¶wi˜ÍÞ˜™™)µ cA¥Á¬ÇæØÔ¢²Âœim1U…fOëÑ(ʨž±~RKV²QÙ”ûâ–Æ÷ÒH2ðãÐê*Ùfûû••hŽ+¼z:ßN·$t,¦¡H“ \–ócæÏX>c_xfÇ>?ɮޙŸÔ–ýôGë~ågIµp3}â=Q7U;g:)§‘zŠégQ¨44÷Ðß²–ïFUU»hŒ*ŠøitXÍ6~¯r˜‡©a §"_Ø ÜD!ݬ¥42nŒŒìÇ£:ŒNŠ"¤úz¦CÇB½¬çuöÒÇ%ÜÀßÓLï%É*¨£”ëéæÝ,ÌØ¥kVq„.³œ»£ôÒDœÙ³85öæH䌘ïL~îóüžù\F‚®¥œT„ù®ŽÚtÈ/YDжq.»(c†W¹’"ç4%¼™Bv1Î1ERÙ¹¬¡Œ+8Î+Ô²Ml­©ÙpómÿOãjW*õt$#]D7ÅŽt¼µŒó2|ÿ»#ƒH»z€ç¸-¢7p#\ÄñèF9ÚO…Qmó0øoãQVòV¶qå f5ÔFLûõÄéb§"C˾ÎçG qˆ·ÐÀV¶±˜Ûx€·’b–›˜%Í$F] ÓË #´åô³›wó4{9ÁyÑJ3Ÿ'ÛÃ1®é íŠÈ`Ã<ÁËìKxsè!VE¿*aèßœ<ßî c~"ÿ›°Úׇßíõ†>÷š†±s.³$mÏ(™¨ÌåÊüÃCÞÜë@ÖSˆµÿO�� �IDAT-ö×°7ô[R W%l ü4”àž˜2^YhãÈí[Sºb&Š][fYÊÝ¡µ…v¥Õ‹Yúæs,iåR•CÒeWÚWhtŠIGãšBÏÍZH*5Ú1£-é”žÈø4üÃ7Ã'[¼ØG)صFÿ‰65ýZºü,ge»ÂcZ‡L”YT¢8¥¼\zLQŸ²*©Qõ¡ø¨ø"]UqÅÅ f°2'ѤwL¢YÿkRJOjêU{¶#YEeUñó·Ut¿ûÙ}o>9°nf׿ìæW*wµoœ>0¥lØœ!µÅÒÅÒu†fO)˃Ûû5¤”,s(!Sݪ{Äœf½û­ÊIÎ*,”)2›QЫiDM¹©œDìLÒ°ªÂD©éaµ%RÅÒ#æL¨(–.2»Êþ”’PlP]R.È[ÇU…â¡x½ÁZCýŽ[œ›’,5^(8pdzíw]5©<Æ uFФf•tš;¦0!6"WXcº[פæ¬ð¤Ú@]¡Â´šù¦2²Sæfê‚?ÿB<=œ¾}O6&ö¯ñU˃~{Ωåc/ŸŸ›­˜Õ*KèÔ5h1>kþŒæ1#ž °¡ÞìD±év“ߨ×^ªfBGÌÙ¡o%]w61kvØØdé”lhEàÅÐSsvBSè@à™”Cu–§Ý¡=<ÓDZ‹Cu‘ÆÜÀÝáåäµsù�÷£˜˜[æº×f|ƒ"ÚYAGyŽÅù¦½Pÿ¡ðN19ÉVæEt×~.&KŒ7G´eìâ�äë–ö2È*#[Ùnžf Iú¸œOãŒÊÝç1ʹìd€qqš"Ή°F}´Dî³ü0â6ä£8¯°–[ØÃ*&#˜Óñȼö¶ˆ¿7Åa’âï(ŽÂOøG©ä dm‘»“BG÷ŒGæ½ý¼NuŒGù°¹¼Äqæp,ºBä×’Xý]ã Øï vRÁ,òõôû"BÕDMÍ%7ß¶ùW?‹·e(Ò ßX3ŠçÙÇ0—°9zõªò\Böò~:ø=ÜΓfðž½&^ Ãè0ò£ñ½;²‹¬â{œÎë+Œp:ªm>MWT!ÿÞ¨·w‚^.à—Ñk~‰o0É¥œæ÷QññS<Ï¥üŒzøÅ\Ú¹B.e¼À¿`ˆƒ\Æ 'ÎFæ²’6&Yϱ¤/*ÙËÅl㫬eñó¹ŸNþ”ûy%auìÔµáÑ»Ão¿äþó}â;¾óóà®—<ú5#¾ôà’¿ùàøsW{¹ôuõ^…]¤}ð€ÿÞêGoóÐO¿W¾÷ëLp)ÛB߉Ùô_y¡³š­Q›qSÂõ1g…²¡o‡šftfí .m–y-aq¹;âål˜Ò2ëKÜž6X2«±Â+µO«ùɬsS [©µ|Ô·Rª¨‰ÛZïÍ™»¿ØøÈ¥?ûJ¢ ºà[Oý‹Ù{Ïʨ6þÐü³5¨R–›P0â;—9|Üê9™9f5…âi%sŒ$åVx½E÷€úŽUHª™ëô£•ÒE22³ —öâû½øäÇÎyhAÙÓç¶î©ÛÿñgšŸZq|tõ×jÐßiþ1‹Ïr`ŽŒÂas&T´êN+Þmm™érS¶èÎg{ç™ëô°9 ¹"³ ¹P|XíRGY>¬¶_cŸÆ…:ÒŠGÔäÉL-zæêWÙaa…‰m.À<¹j©#I¹¤l·Öj£¬Üoåˆ9ÕFQfzBÍþïügÓW>´úôh±™AõÇÔUÊÍ*K—;Þ¯eRõ2‡SJë÷û« ï3–¶¨ÖD¯#9ó&L¦Õ­6ÙyïgsÏ^¤®2øâ»Â;~æÃÿß¾<þL*|ê’ìÄÿ÷Î@.£8thÒ]cÞ4-–³?PW¢ªÜü&¹U: ¥ûM¤<š±l“ªŠ4›œQÅü¤ ÔÊgÍjgžñí¸s.ÏYNu 5×ßÉZJaÖ%9Õ˜çD™ã~ÈL0É*..0/ç7._ªëv‡Vñ¤ùϳ‰µÁ»>Ÿ»û¡ð£'Ü}ìb¶ñ{.âZ.äâü$æOnð:£ÜH'¿âÏØ5Í^Xàd„ÔË?ª¾‰ýü9læyNs)SÜD/k˜Ïãôä ¬çIzéæÜÎ ÑÁ¥¼‹ŸrY^YœôWx–ë¢ÅZþŒ:ðáÿv–°“ œd ÑUI‰¬}yÅd‚ODzaÞýcz#Éæi^¡àÑè£naG¡xŸ¹ØRŒói`só™¦XGCQsÓÚtó´ñ?‰P £Xq>n{O1çig×2US3qómïüÿ%²·³™¿%¹0?ĵ\Ã}Œ3‡i:¸"Ôù¿†æ¤Wø O¼aªÕñ>Ò´²—Eõ\0_äýôãäx¿Š^ê"zÕþ,š¼ÊS,åEâœâÖ³Ÿ÷p7ã\ÍÃ$ÿ,ÐÉv^à­ÄYÈz6ÄÍ$üEàËŒä/1£‰0«y€AÎ;Co*ØjY­ÏÿÞw{}p6¸ëI¶²‹½¸%poB‚͡ה½â“qëßb20Ü/üB¨:ô˜¡ÍöTxæÛO&?öÍðèV©—]Ræ-#?¸$þ5>;ß¾8¼õ;†>fÕË^ÍYYä 7{pkñàg‹ã® ÅâW¸iƒg?í=»Ü‘±k(ˆßel’W'ÅyS¨'ðtÞ·©Ñ[KuMjb~‰4êlšò\èæÐÛCÕ³:Xê ½œX2íó½’çd-X¢z؉iËG m.p~\ƒ9•©øqæ® n]Ô}äM³ÿ÷ÎÜkwûê?ûå×þìýf“Z²Oª •4HthXdì"[«…%6ïV°´Â‰a‹pˆµŽf%óÇúaK™Slv\ývç_í‘N-->aA±q•óêšZÖöÐò¦ÃM™ÁæQÕõú–ý|ÝsOéòo/­3جwLuV²Ó¼óm¯4ž“<®­ÊØ„Šœä§6xµÔt‹žå^T_"Õ¯±ÊxN"­˜XBÐ¥µOãŒâ~5FèÈ·œôkÈItiPY*5¦*)×i^¯æ@¼EWN¢@n¡Ž@bXí ‹æëœPÙ¨žÎÙjc¥¦Ë¤*MúÔÃë¿·!9U´Ïên5µfªMtšTó´’nó²&ZÜßé`ƦE.*/0gƒ×º”e–”g{2ï{"þÝ¿í½ã÷³_ÛäÖ=‰}GÏY®Øá¦'Ã} ºwsÝLC•²¬Æj% ¡tÒ¦Œ q¹B±BÿÀu3ÌøUʺc>2æ3YÇgµ°pÆ#©YíY bÚCƒY3Ÿp€§‹œ=×ê*”ºʆœ2PäÐÕ#eM³7å|3æÙ¤/Œªšp)7Æt'-¥™xà�/[3âÔ*'³œG;Ûx“sþÁ£ÏÄOݾ^øÝ5¶=à“w+8ËŽB®âïùë8Á6zCµQ7o¥;SÆÃ$ÙÎI |Ÿl£›“Oï*îç#`ëmŒóò p1p/r<væ‰| e\Oo¡.:—ÿ ZîÝÈEV²‹_SÊMQ5îûéŠ6IyRO<ÅQ¾Ë/£¥WŒ xÏqCÌ{ù ¥Ôñþ•8IŽp+¯2Æ åJH’â%ªhäýѵa8¢–ðC yr*袚Iz˜¡€2®b:¢¢¯åö±6v¦©äm„üßà&r<È$çò0ã 5¿zÇmåÿ ‘}>ƒTò8]Üû†:IE–ü·p‚µdy=,þ5㡆 šCõ´F(Â6.çûœ`/í<KŽ:Êÿ¸ªkY^ˆ‚VxÇùô¨'«¢Çœ÷ÐÙ%ÙÏ-ä"W^ƒÄ¹”u\Î)ž Ÿ j€œÏÏ9›WI…ºùë˜Æ¸¯±ÜGCLwÌ¦Ž“1o‰å«ëJã÷Œ…7uúá?ÙlÞûâÇÎ =ÀE¬ |ŠÁÐH˜S\tƒ…ú§üäÛº¯Wѧó[Üw:úiü®«ÃWVárµhƒKvúmObhQÌ{5á’ÿ³ç"_Ó™vÑǾ’ ç+ÖSL:QØ|í¶×zó¹ñ»>¾ò¬óZÝ} W1S³.T—°™­I;â²¾•‹yÏ"Uµi%“ÊC?ŠØÏ'âÖ„ŠC[C æ+3Yìœbs\^íøÚ¤†¬™¸ßä¼”°¹úÒ—r%ÓÙg[§ëS3%“ÇWÆv]ŽöÇF×ÏkP3®&ã•z'ŠÔÈÚ[¬l»ú!KÒ UWÉ ¦ÍR[&™”Ë‹I-zªÍ18e¸Li\jT͈¢*¹¹ú&•Wë­7’“è çæd—:Þ¥µGEkØ}ò㯼ë¢rS“Êw˜¿Ì郧Í=¡­ÖpNr@È9óu.Ô‘“èÑ\ sT{þó#§Èì!ËkŒNª(–žRHëҺđŒÂn­Ef dg–™ÊJÆ…§,¨7ð¬‹õ±`\Y£á´’Aõ“*VÙ¿Ýy‹œWÕ£ùÔ–Î㛪W¾0¼²÷ôÊñ‰òDÙc›§f²) ³NM›³Üþ1‡—É (èW˜UšÛ ¦SóD³œ\·W.>|êÞø•; ö,iúÈŸ–nÿèoc­Ó‰‘úØdUüd[ÕßoH‹Ïˆ*ó‹g z"Tx9Œ©…õª–;¿Çp¡UIW6{%e2§Œ¡—Çâö‡„ B]I# Îb7çthÕ”pѬÁÀåü´Ùûú­œ8ãcêà{ü%g³-<ó{ý}^ŒS`]Îv®gOÌ7cSí:Ó&æþ¸ócZ‹Çüh¯³¾n›†£ÂWý×—ã¿=öíŠ÷·†¶óöFõð•1oŽÙEÓ‘ïM WRÍ"öEÔ×!®¡‡‹˜d’M|›NÎî:ùÈð¦˜)ø)Œc_Ò§‚3—°<Nag´^:ICU˜e„­‘)ñçì#ÆjNFzǾq%®Š<ÌiŠØÌ)Š9A{¤¦ïÍΤåGYÎéæ473M]lŠv›×ÑÊZ.%NeäEÜÏ+Qmï@ž”Í$5¼™]\Ì;ÙÅNq)'¹’1'c¸Œ‘€"æ q½áÊùÅܱú'K)³LWÖ<ñ¿Ô3>ŸJ}š\DÊÚ]­òrè (aUħ˜¤š‹£-ç{¢+^?¯sœõÑðŠYE‹Ì;y¸*Úçñ¸×1ô´.éå2Úy’[Øs~܆P3߉¬Ÿƒx*OCg>£,¦’çy–çéŒ<‡Wç45‘¦ÚºˆRVpN(ú%Çf}ÌÕ¤YÁwy{LKBqhÈÔ ±m×ÅŠ\ûºO<ÛÖ{eG(ÎI’1™¸/…®äª¸¯l[=³ì·¾ÚmpµÕþò¿¼~‘㩸·°#æ—¡I~A«ázCýÞYž‹œok ÿóqgµzì†Ä“W„W?¿ïb6Žè +tšâ wÜ¡‡­_/{Eü½½áŽcOÏïùd¨8aˆúœ õñï ýeyEÎçã9•ÃúR¢2›·²‡Å¤ãžiV4©!®(ðPÜÅ3Ö9kBP,œP0«¢À‘rÇb®Êè+SÓ|dñdMÇì _]wpÕλ7vùöø“—-êqä7ßÏÞµªØ‘˜æœßoRßC‘v¤­jTXîx£‰#²ÔÏ(Ì85­ñlûËLuš7!Ùc<f^£þœt¯Ú^©KKÈÍÓ9£è+‹cªë vhª’Q‘k5ôúÏÞõ¡ZÕÆO)œÑ˜V6+Vbj§óò¢ÑEf³ z5ת5´ËÙmŽK¨™TQ(Ó``TuBV4èÏIÔÅú5&e ”™B¿Æ¤\¡Ù-1VÚŸ”m4Tm2« YϨšœdý> ~FñÁ+º3—¼pº¶äp]퉺™×êJæ|çöºÞxÚÄ€eª‡´ŽKdítv—SUqå¡â”§SY³£T¨Îé™ùþ¿ÙTôÃOV¼¶pÄñ¡{¿â}YRúPÉ {¦/ݶ0yÒ³“S®IžñAìI9¯PYRm©‚@iÌü¸Ø¤XÆPÆ9#ã¶—{ß”ûتas­›¦Å4Å „²ì®´0ã(}Lsœ†Rc³*fÍåUžW<«-ô" ‹e‹¼=kõq[Â3›˜åŒ']ž4”1“pqèç±Õb7ü:<üC ( ý?„Ýgxg™îýß³Šz—¬bÉ–å^âžî8…@HB é”H ” eSØ0 °ghû¥ 5B=¤‘BŠCœf'1Ž{/r“Õ»Ö’VyÞ+Ïž½ß™WŸ\$û°$?׺ïë<ÿÿ+CüüOõìÍìçŠÔÖÿ0ö6$;Ôµ…bV`F`{è(7ó$gÐÚDO³‚Wéà r̈žrã‘—½ çHFϨCÔòWöÐÌAzèáÓ1ïb[ÞÝ\J5Ç¢WºËbOq‡£`Zá6oS„DˆEÜ9Ìæ�I9Ìîˆ}>Ê"žŽŒÀ-¼‡:ž¢ŒcÌÈûYôÚ½—Ù´RÊC °ˆÇ"³â…ü2ÂÕ¨rÓÎߣçê¢hµ‚îH@øµâžã2^#Å'¸?¦>Ê8ÌüˆÇ1ú‹HPÎpÄ\&Ç)/´Áþ{›ð3©ÔÔ)]⊨¢[Êû#x«H|‹éä�yÞÈ=å*~5·G¢“i‚AN2ÅÛØIè3Q|I´—º”=,çCÌbÇ)‰ZgGDÚçEQã!äšSzÔ…íèYÌn�˜É…13ÚIV1=ÒD1Ÿàw<Áj Má6w6wFœã÷ð|èЋœûϳþr¯nöØr¿>j庨g7Dš¿l÷ÁXMvÁt%Eî =ÿQ‡~eõˆ°)<ò+C/r1æ±ÕÉ%¦ùè¡p[ypÏ‚‰¦àcï .2ƒaõ óž¶m|!&XjáN©CÚÇM/·?æ—o 6„³ÓóöÑÓx"Ô‘ðâ„ 2ê²¾š]âÀ4Uq%ÔäÌ໬«Ë+)¶2å(uq—Ui±3kN“`Jë¤d¬IÛ^«¦EYÒYCÒÃþZ²·.îøäÑÙž×}÷yu;Vûî£#ÿö‘²C³ËW—7^gÚ!Í#f¦$ãÚªLôjLÊœT6$Œ)Ë*)¼ÖK wÈSÄdK%Ç”u8Ò£c˜Imõúób;ML—hÖ“VzÔŒyŽ”/‘îלU2«3ØÿÞgÛžZ”+VQm´Î`—–¬dƒÁrãͺ›u£ÆÐ¤’U=)Ó­iRq‰tL¾H¦Äd^Œ  ÊÈn GUN)®3Ч!`JÑíE¦fé,“êÓ”IÈNÓ›”=jæš=Ö¬6œ‘,”±ÒJŽ­=¼ùÇ?9ëžùÓvEÏú:Ö·U­?½khN—Ù­&ûÕÉ ª ”Ì–Ø¡uRSBÃJ&”Ž)Ïk }?§¥^uÕmOMÛ;gpê ×ÒdOâŽGF¯ß”hšªÿÔÇ'^>3Óõ@â·éŸl!ˆ©ÄÉ-ÒÛ«7ÐÊë,õ©¼AjÒ¦e|)­&«‡søþ"—vk£“½q™ùb½ò<Õ ßê¼AC%ö%­šÒP€Gþœ÷ë¼²„Uy x50-ÔÊw*Ì(rKÊ]œ¾¾u—°*oGΫ'h <Á‡coËWõÀU\@3I·ýÅ;÷¹í¶ÄøÅù×K?û·½á×{~^hOè^.á>rˆ—ÙJÐÈã‘äâBæó0o‰ü½Lq}\F;Ûhâ*¦¨ä‡ r&›Ù5D8›¡ÈÓq0’Çìãbv²�<Bg³œuÌã\n`#çEY‰«ØÀ4>J=Ù(ÐGœ­$鿣ˆÂ}Ñ­ÝS,ä$ïá ò8oçQkø?ÒÔg±–§£ÐÀq^cê¹Éµ<Eµ÷“â¦SàR…9ÔÑSäȇòôPæõò@š«IñF¶F›¶Â1´àÄ:Á;Ù\Xý÷ãê¹Tj;˜â],¢—³y‰íìa’>Eê³?F$òÂÅàÙ¼Â.þ™c4s‚<c乎þˆH/úzäI±“½Lr2:ä^ÃVÆ£‘û6.¥”ûéf +`#HåÛi¦… Þs2æ#¡»y›âÞØz™’g+!·QÆ«Lð±¨çÛ–piøúkoqNDFy wǽ?0ú2»™"ÉÖ¨‹÷y'¶Ù]›]ϳ´²™2ÞÊlf²5;qÕÝÊÿæïŸNfÚó»ŸwöüDî2;–…~é>·¨ið‹g<Ôïš¼¶3üñßÂýsø‡éá‰G 3ËL;nÙÓþv.SÌ Õ…¾EYÌ-aêtÛçÚ”öÚ?É]suÜÚ¼¦Ðv„¶‡:y÷„s8R«(æÌŒ#Ia‰ªQÓ²²­ª&¼!/l0=«oÌñ@uÒùq3&¤ã>3Ó[Ò*‡%¦ŒÕ8£QI—uã:F[¶g7þ£iõÙç{3‡nœÜ|}ñÆsK§þ÷W?²òØÓm9íiMízÇôNø~Å¡¡¬i 2UÆ&˜°»Mó4£•ÒbSÊ–ÙY+ŸSq\M™Ò‡ZX€ä4ñsm¬4¶ÞŠ>ó¯ö䈪=̳o·EmŽÿ͹í´ê=zâÌ“_úÉŒ»/®ÍTÝeñ GÔä%e^°f¹-êö™ß Hm!ï^e´Ý‘a5¥R úKL–JçÅ3’µÕsÙ=¥h\y L+I)-ø±õì7¯ÖP^ü¸ÖˆÊJT^fÛß\xºM'´«éÓð\°¦î¼‡†æÖýòªt¦ªLj®#­ªMì÷É”wJœf_L¾Òh·úI¥ÓeÚ3§AbRiÞ¼5ò½ñÌÑ[îz¾cê@[^>iéäûMwMxˆÔ?í¯Ší~çääÒ¼…cGκУžÎØ“wYÞi^,òÌ\ï õkŠ›œ¦}\Í· §&&Je|cÔÖŒóãff,ñö´?çlÈz2ô&’,Ï)Í+ççü!”çÚÐÏ’®Ïkš²2+Ê…-û¼ôYYgpE¸£H˜å—œ×èÆ)AóüŠ‘›¿âkÇ¤ÏæÏôq½woòË´½|ñpøEÎI$/ ï]ŸüÚ·ó[Îæ\þÌÿd”ß°˜›Ùέ§uUt͵Ûë£÷‹ÑÏ'hç¸ç –ó<—SÇQ£ö=ts‚™|˜=¼™ç‰1Ư§ßÎv–1'òf¼…Šn¡cú2}41›5\Á+œÁ«¬ç ä8J’#|G#§×ûˆ±…6´X\ÅKر ÒóítE§ˆð”˜Ûsô3“FY¶±‰s™ÆfRÄNù®hÞ¼×èf5$Ç!8Á(=tÑÏ'x…,Œ²Ÿûã%Ã|aêÿw\ÍI¥ÖSD /³·Gw»{ˆóŽ�ü‘hàÃüšÇÉàõOwšJ¦8Bc}!Å~Jv¥Ð-8AD ´®tĹZϼ‡5ñMæ³€4m¼™8ÒÄ×ÙÆ÷Ù˯…FÂ×q÷§sO‡¾úBK¬”ãÌåGÜÊÿâ ¤ù4æ}•¿°”¿³„ûØLè¼ÐçxoäDžÍ${ÙÈÚ xKdÀšÃMN³ž‡©¥Jǵ#r•ù“?…Ëc§åöhI-ÕÁeLç^ù²}Ðg7…}Çîm~Ñe`£‰sØA†¯Øw³=7'‹ÊÂÔKùzà] ,P˜¬Òç“âá ?«wÙ¨}\‘¶{ÿ é´r7ÛèÈê ]7XjdHC^>ç#~‘·‘…NÄÝúP‰ÆR;Ò²q{&ÍŸ2ªJ9”P´Ðá½F™3©;ÿÒ7Šn½;ññ+Y•Íeò‡—®xÂ{^ ×Ïêyjq‰ºŒïÌQ—ò“1ÕçhÜl÷„æ%zK÷«jÑ—ỦbbI£'ÌŒ‰ÅŒlU×Ôh´Qß«–÷+:©c¶®"¹½æ5s±ƒ³t÷i@NbTe©T¿Øl½1‰ùömI´Ž~ä'.ÞU÷ÌŠôxà [z4u8\0ƒœmCAÿ‘ïÕ8]×t]£ªFTÇåçÙŸŸ®«Gã°šZƒ“г»ôMžÊ‹5èÅ 7{G´·;Ò­©Gc¿†¤LF²_ÃZÏКïW‡:Íjs¼[sÁ'®Ng–o?ýs×wgfŒ«H)RsỖ¦ÚPå²GÔõiì2\¦&T×d".[¤=/ž2žW–QÓUÞ6úÁDz{*c¹9¯#¬Ú0¶tvÑ`óW.Û‘?0VŒΊ©mP6*:úvÒSFâÒ–¬â¼¯d÷»&e0Ô˜4oØaÖÍ`ԯƴp"ô06Ä´æÌ erú³^â‹1ÿZïÍY½y¿›W7#ðáVs&­‰;Ÿ…Y7ónÏÛý~ùª<¬d܇ŸòT‡žÙ¬dú¸ä\1Ú²ÓÅ÷»·ÐfÙ €_¹ô Ñ‘ÔÔéÁÉ•šžu_øÍÙù-ßfßä*¾Ï£‘èö-…ÿ†1í†Ð}|‘'¨f#Uü¯±Ÿûx’Ç#$ù¿ó.*)¢•Ó"´k6~’ærœˆnÉæsˆgÙÏ&ž"Íq:£çá<Б}:od;/q6àcÜÌ#5bŠí<ÃTSÉ£ìc'G˜ÅÛYÏNæó W“Žùx`*´—;˜Ck„KÏR%´\Å«”rˆW#ÐínÆ©àFŽDOéÚ(÷±7óXÔ¦šN ËØE7FA„Â_÷)¶D%¥/ÐÉ\!¦ £$SµµKnºùúÿj\}+•JÑN-Ìf}Ì¡›ùEѸ;©csÉÑs]`(4ƒd6Gh‹Bœ}§¨—OFÇÏ'9“}t°$BóÖn}Ñ`ç º9‹·‚Ûù:ãôà\Ê£ ÛLf’æþ¥¦ñqvqqTü¶�� �IDAT4üÓTÑÂ_c.õfŠ!.b”Ç)åÞÊ~*¨ ÔF&ìI*HÐ^ðoÆ”nÝÀøTs°ÒEY£¡GÈq) ôÛß,uý5|$¬…W<¬þŒÑíëÙÃN:™íއ|ùÏ&BwökYä¹VÙvv°Ÿ~úÌhôÞ§ªãÙãgÄLå1żuÀ¦¸•eާ^íl›Ò2jù¸ÕY/ ‚×;˜ïŒ¹=´ŸÒœlàß縶OÂu”“*ˆ¡k|˜¶"ÝCÒy¥5¶¦ÍŸ’ŸÔ˼˜ÅÇ6±9¼ôD,_^ñËÛ*vuÑ¢=éë÷ÄZ†óW=¼°<ñ—Ûj´Î•éu]“þ«GÔ ™žó¦)GŠUö›—’P?ªô :Sªb&BãIÕ펴Œ«¯×=CW¡rý)­&&v›]a²QO©Ôˆª.-E2ÆóâíŽl“­–J(Ynk­¬}ììàŒ—OÎNmŸSvÁîžÙ¥}jŠL‚ýÌiÒS ùÕÊ(êW :Úmáˆ*Œ«¨4Ö­yLåkVf%Úω¨î×0®<«2ºß¼”²QUIÙ cCj³º<ÔV³×üZCÕF[Ö6qùú¡•‡K—¼ÿÂÿ¬4YitRwùqùj#múOz_ñ¸t§tB~Ì=ÅΨ7SÖ¥¸\Pe4mlšÁ¢Dnè÷„#%±_ Ú@º$¿øƒâO?ZýÍkû_9+·îb?þÑä¥?ܘ­\Ú+ >°¸Lé”òbW×X•÷ÇŒï ì[[¥1g¼ZgÚ³¡Æ sJ\6fu !07ÔˆÕ¸#¥çø%c2Ð5áñ¼óãª’Ž—ˆMÚ‘pÚ˜[Ê—r8fzhdÌ¢˜™1ŸÊ?¾Ú~­TìKçxåt¸‡Œ0GãkïqßZrìçíÜ«vÂÚuùUƒùiÝáG–î}ÅàrfRC-¯PÁ‡XÂ1^¤8” s:ÿƹ\GÈûée‚ ˜b˜2Îd&ý$9Ê0I¶ðëèa5— VFÑåãÑ\áíìûÿâøša…gc–5™8Óbæ³3ºkˆ°pÕü˜½4QÃ^N0É>Vp:Sôs ‡¹€‹x†}lç¬ÐïC $ܨ‰ô&¨bIt+˜ç5Š#ñÅxôØ_-Þ8‹~æ³øk|>Ò‚t²†¤(g5‰’ ïàmœä>ꡆnÚy5Z¸TscÌZJjjÏøozWe©ÔRlá"úä|깄gÙÉåQ(<áõüÏJž ­ ÍaÃQ·y/íôÑxʯ#Z!ÈTm¢)úª¢sXÉnVð)*¢ûâPë¯Ì¦ ¼™­ü®¨¤;’ÜÇYÁké!ËÂèx~»w†NÐÅ<WÚ¢ÚØÀ…ìç©À§"Z똪Ô:—dzh t„…ŒEÌ(uÚŸb’\Ï·èõZ΃3¬6»OQ¿§ÆõG™í¶ÎøÎK :ß`ç •yC‡g¿E)/SAŸ óÚ×¥5?ïxèDÜYy›¸?¦%«sÒRxr¦O*Òö³$t7Ý1óâ:âZâêÊeÒ&¨­éw¤Ø†b+L´z¨Ï/9#æý) dJ<:i-é »cfQóJèyå’À‚r9?¾û´O¾3?>½Keêµv^nអÿõ¦ò]W×Ê §ïW•Wœ×Ñ.5¬–ñéQÕµ†S†¨Ë(UÙh¬FzBY“¾-Zè)S™VÚ­9›e_‰üf§Íqp†½Yýq•‡ÍšíФx—ú*©iú¦´Vêj1‘ßk~ã`¶ùÁ³ÇceñÙû{®ÚÐ9'Sòê⤩#¦u8±ÝÒRézsíßjù”¢“Km«6’•¬06¦b\y¥±>Ó&”׬0V*}М6Çcò¹pŸ†BGxµMCj»5©-8!còê¶Ü¸wçm¾y÷ø›_ž3‰%úKË«¿úî¹Â;¼¦*§-ÐsRù4éãJMœT=$“ÒWìÚcÃJf;Þ«<i¸Hg«ânM>ûƒôñÅ~}ÝSò¹Ïße Sôó·W=»jBq|¢|Æ ³GŠOsnwjWCnìP( k©²`R˜slÜRJëUOZš3Z®4co3#Þ:<¦iDEƒñq„¦3ƒ=©×ç3˜Å9 -¡|Þî6sGü&ë@ÆE¡Š¼ò^K;-ä=X¸O =ؘ×h²/þà²Ò$;çd¬ ü&nih˜J.ò‰ßzø2ûöD/^ç’³ý„¬;ÍÚ»Øã{WØÓGcdxÄëV‘æ†hå<NPź'ÇóÔ07êßH_ÈmQÉ袄“\M§s5 ²*¢lO*YEì$8…w^É쯠œN®bh)ÐyB»¹˜é%ÇKla?çñ*[˜Æ9Ì Ÿ:Øuu·QËUü˜ÑeÕó¬&© 6²‘),_–Fùõ‹x•^na3©â5æE8EžwFp÷ÿã­)R×°y›¸Œ±`Y”Ñ(+9É…¼Ì–ºÉ×Ô>ÓÍïþo¢Çèa5ÇxŽ<ÃtÓËÆè?ÁqÞÙ ]!¶‘ä6ÆèŒÎ(ËO™ÃÇ¢ÏÑD”S¢?ºñtJ'Ïyü‰9¬c G#þúWÉSmKùZä¸|7›¹œ9åp7 !ðôh¤McVè.:YÄ‹tq#c,f9?'`±œ§¢oñEÜÃ}-Y'BÍ<Ê,.d2¾ÌÖIÓ9ÁÇYú;¹…³ Ñàå‰ÝÛÛìmo²dÌO N_z(øÞÅáÐì˜ÅÁá¶ð¥iÊþäöž:Éj^Ð<â½í~tÝœA ]$x,´ˆ—Ê}°DjJÈY“*òâgâÚóîãÖÐæ¸Š˜é9S¹×I*óBO²/oå"'»=6fu½|©7M(Îk*ÖZm"­,T×]gyF{è—qWÅäxƇR3¶.Þ8½/×X¢«X}µ©ª-‹ÆÔÇÔM™œò™roW(éÒ5¡º\¼Q¹â!íÜθ3õÅ…µa¡ŒâCºZ%jŸ0'/Þáp£ÁŒúaÕmzk¤²’,è1ó4;šu”KÕ]`ï.˪)7¾Ñ¢ÙŽÆ mSZxî´—æÆ¦’ýµÉ£_ÿÉ̾̂ýá”Ò¬ä¸r‚1³šîD¹‰Au‡ÍÚfY™‰F=ÉÃƒêª WÞiñ ÚŒdÁNíuwYÔ ¿ÖP\~³• Ùé}õú7þá;ý·ßð–{\õBÿÐþÓ7í¿©~ý’…Ìé/Ê&<©aTk™Ø\ûG•ô˜1fÛ”¡¼¦˜Ÿe ”ÈÏKHŒøY\{€¢´Ú‡ûø²;ЦY5ü¡ß„_ýYâ¾Ëß³ÖáCʨiIvÅ_ºdò}ç?ðëU?ë˜y%ŠG•†çÌK;WNk(ÈHð@ÚzK¦Ìs"¦‹¢Ð’¼×²zøóp´„Ø×aјÞP<æxÞHhÅ”‡BŸ ÕÑD%m1×–Ä5‡z¨æÞ˜7Ç]ê-¶¸Êeãþ8+ï§\ÏF¦ñ€ï<çç’â`³Ž9É3,aLf«—þÁKÅzVpf³cöÓ@oä]t’âRVó'¢lzW´ÃÞ@{$ª¿›Anæ4Šø½¼J y%R}(²â‰`€å8]Q’K”�Ìq6#8ΛI“çInb35LDÂ?€ð[j¢äºò;ÌYÍ+öÚhç1.%ËL~1–®ã0Ìàjvq”ÎŒøÝX@ûø'oæΦ3ªýœÁFÆ8öŸï·±€íôŸ²îŽn ߯ï#oâ«àBžà*Îà~ê(bŒ°;TÊæÚÚ÷Ütóªÿj\=–J`Œwp0R¡:Ìc\‡ 'Ѐ"Õ"N籈¢?ÉÛ¸“,ï‹Dò™(bža2šU¥§K)¦³9Ê “ìaNzs€Jx_ækÈq w±’÷SÍQ8§’m áš¼ýœÃŸyÌç·làlžcÇøÃgñu®¥‚"îâC,`gq9^È ½“G8I5 Uå˜ñ˜µ¡fÎJú‡œWyÓÙÎM,¾œßÎOì †BÓS~¡YÙQWîŸXjø[¡‡B3¹Iì\·Û¯ÖpiÒíù9÷ÆÞ°4vçgCÍ2œÃ‚9nš°&gvN<£8ôtÞª)7‡ú93TØ÷Ù*ÓŠÌšT³¾F~Ü¢Íó’¼¶œ»z|wDw uÊ—SJC Ħì+Vœò¯ygl ­ ÝÄç§»~Èâðš¿î^R½çôѰ®Be›^É1¯æ¨0jʹ¨R+wlTû[¼“ߥ£IzX¬F¦Ý耩IÙ…z¶YÖ­y@À†FA§ÆReC~ѧü­¶¬wA‰ô„ŠZ©¡¤O]NÙ ­­Žn5c¥]ý¦ ¨[f[JÉsòÊ4ÌqlМ8Æm•ÛÛ‡ÿºjûÛ_Üýí?ï¹uÃêßÏš¬TÛ®3&d³YÉ”Òv#ªÆTV}Ü¥KììW?®¼Wc±Éb“å&Žš±ÀÞ'\’;©ù|ë“2ǵí/oyæÎ{Vu–\ó»Ó˜×ôü¼ž=ç¬L\hW^br¾Á=fµÊh·%¥iRý”dŸ}Ûaå¤xÜé kÎ÷Â&Œzû¢1½£jûÜ5deú—Ÿ®³'®}WмrÞ×Þ9¼96®H¨Î{ ^û„éi³J .{ºmèÃ9ùïûÓ.žÒ*iÖ8.ÌÛÞ&×9®±Þäl-åH(£š¹9õÜžseBSwp Í«!Ë·R®ÌZ•—ÉË2cÊ?|q Å¡ŠBoý8ïO‚ ]ÔæÃGÃ'ÞšE[ÞáI[2ú⮘nöˆ{(a»#îG·²Žƒ)«CQÁvŽò1^­ò"US~š²!´˜rúy€)c&¿åó$‹ûj`Qè~zy“¬åöÇÝødhŒQ¾ÃU\Êã\H?¦‹APÉCœKÏEÜwð2eôRÂÄé$Ëå\ÌÎf9ž"ÅBä"êhäÎäïúîãœGš€õ‘_¸<ÅúÙÏ�ã.ŠÈq!ë™âDdâzžçöèšq‚yLò/|’ÅÌäH„ð®ãEÆxɈì>Èi …"6²Ÿ³"*^9ÿ›wp„®(µ€sØÀnv1ÉA^ŠVNG9H*Ú >ÇMµµ‹oºyÎ5®¦§R/¾#§ˆF\Áüˆ2n IÇÉñWþÂ]Ì¢›Ÿr!;¹?Ú@þ§Ì¤w0|J¡ª (ick¸…ù;3Î()¥÷GÕ¼$´çµÒAu<ÈÙËÝ”s"ð1Jy)¾÷œõÝã(ßb 1ú¹‹e…ï•@m`f`•Tò'¶q/½t±ÂÈgS:_É nà×Lðo¡úPª@ëÊû2ÝæN$Â5ùôLz~Ó™÷þ5}~/$ð=öùÒ#‰Ç>¾œ ¼;¡&¦5¿|g>æÉÕž¸‚úüªu>>¾ë3 w%%só>ó¾˜ÎÃY?gV蟒þwkÆ÷¸žxܪPšÖ˜Ò {Òúã2v{$ð‰Àŵ&ÓNL¸1k<ôÝ ·–:ž–‹éª°wJu™Åy'BŸªvm½59µ9 q×%ým\²}ÝÚø~ÈÇ›ƳFOª÷Ä9Ú[ÕÇ”uy6¡¦I~PY—§«¼tÀEÕç8ØY'_ix½Ì„ñ 퇭^hO…±‚®~RÅG²%ÊjT=êM•²÷©)Ó_'8ÍÎYŽf׈ýåÊ;ïQ{¦ƒCjû5 (ïҰľ¬ä„òýÚ“F›U.•Ï•Œ5µ<y^Ó®í{Ç“{ßr`úïÎ_ᵇûÕÖqÀÜ欰eèuÇÌ2åÆÇU$ecòŠà<û†Uwk>`î<û§ëª58¬¦ÜøÓ.®kÙù÷O¯ËÝuÓìúà¹cÛGǪ÷eæW›èö/Óœ—«×_*uTs¿áPë¨ü •£ÆÙCeÖ‚#RÅj82Óá¸æ¤ê2粕ZrfŽy.4Rí ·>4ëþëRC”ïj_õ§þ¶†äŽ+fæúÓm'r«Ú³ÒG‹Òa.á‡GÒM©n~ôݼ‡ÒÍ͹¯Öå}úÓª©Ë…&N˜øZF  L°8éÃ5nT›¥L~Êk”°¿Þ™Y+B¹(¾´Ò§§ô†‚Ða*"Â@Œ)å³ìù„9ϧ#AΗóRq‹sr£îa),dÔ»ýèóÑP[¸x†¯p s'mœòÍ@sÞ^Zy;I>ÍoyŽYLò,™Ðºðõ¡R8ÖÜÎÏ(á_CBËx˜¿ò9ç1ú#Ŭf:EÙBSj7ÏÒÃ|úø Ûyké “U¤èáeްµ`O¥9\Í/ÿ3’¡ÿ€Q6²„ñÈŸ÷;êIr1[Y"{ý~ć(åMÑ9o[¦9J™Ý=ŠWÑÆËÜÏ4(á^àDd·8› §p\7ÐGW4˜k"ƒIA3ö{6FX÷‚™¥Š Œ‘¤š1ÞÌ9Û©ž©Ë·¿ðY­­Ýöß$¿›J%9/:ÍærŽÓÍ}¬è½lá_™Œ ­gŒç£qæ?ßfžÃþèÇ[þ¯Ÿ,‚…ˆAyT(;™TÖòÓ¹˜î¨ô°(ï‹´ÒL'O2Á™bO1—†ã ‹I2ÄU,ä…ˆª^ÍÞÓ¥˜Έ)Š\87‘cVT èãZÞmÑòJàòÀd”í&ÍóäfuT&û=ïåˆNä/ÞäoËÞXâxLEÖ^Ò1ìæªØÐ|ýÓc®çßeIoþÅxГltiVmB"sïW=}©O¬ ¬œçþo¸éŸdR¥Ú½S>ÉâЫ•v$¬ÈºE,-³,gSÎ{bV…Ö6ðb@ÞXÌT™¦¬]Z¡¸ÒÆ”ò™è÷†˜¡¿® OÛQi$°¦Ãx¯ãš3žÍÚ¾TM×ü}‰ŽúåÃÒcî‰)Îj.zâ‚“·þ¬wÉÁÒ3O$ÆòéÞãµæ¥ ôž>œ¹öëågö{ùºIe1«Î7•P¶Si—ª}^©Ö0¬mÜ’ ¦d*ÔeÜ?Sõ„òQ/užíä˜Ê*E !ååú»5V3l´Fr¿ŽN5S*y9iE«Ì”ªãj‡56ëÉ)®0Ù¥®Lú„¶i†JLÌvx¯…½¦é噎,µ-¿þ‚Ýú[Ík³ë•N(ïÓФ'![kði·èW1Mo@Ji…ñƒæ$ej ¨ë4«Ëô!µUFCÁ„²#f0·ó]ë¯=:xΞ¹Ï´7¼47­d¿ì€lL²Â¡R7ôjSÙ£±QÏ!³ÊŒUËN¨H ¦›I;–• <QcY(ß%^¢"­zR</Œ á¸MIgçÏ9™ªzfeqªtÄÌú—×Î<奄³v¥N?”8gãàwŽ.~5?'ox©x_Ǥž©;ž ~ôžÀC‡ÉW ó65›6a_‰á¼yiûÇ „*«]ž2ÅÁ˜ ðïÀó¼aRgh IÿˆÝ,eŸÍ9‹âNò×Ðú+•Oj í¦šO²ˆzª¼ó cËôÏÕ߬»(﬊™ÚZWͱ˜³B]\Üñ@ìGáëÊ7ñ,£¤)¥„/È×qŸ­ããô² ãÆB 8ÂYô0‹®æ]ô‚˜«Ã×£tgSG'u\Éy•Å|0¿Èæð3Îã� ™b ÍÄd #¤£hÕOØM= ±ŒZ>ÎŽ¨®³0RJNÄ$Ã@”ƒ˜ËQF(¦‹,¯ðñÆ¢’Ö?y}Ÿ#IŒCTÒÎ�D1ÅÕÌáEÿ¹PÔJ7“|€>ÖpýÔÒÁaÖs{´¯ZÂiô2Ÿb–sˆYÜý™çÐÏ¥LÑ-Ûšèæj†¸œ¿GèÞãÑ…ä"fÒA²�|úïƒì©Ô.2Ñní9Š)áo\ÊÍ‘ j=‹9âèl{„ÚSÂ"l~¡wµÿ?ÿúÿñÓ"Š£…ÖîSî| ¿UHí<Â1Îd‡YÄŽa²‡dÔ9øLøzÒ¿pã<AlëØÌy”Gȯ§—…¾C;ù{¨4´Ž“¼/¢¿,”sg]ÌùæIš‚×o¥?B â R¬¡ƒLA!X?¯$hlðÖ×â¿yO8þBÎ9c¡[4TúØãúþ\TÞø\ø—7¸dBUÞ}·%½/éñû37nöÎunù¬ñ’@‡[¶9xq®ük3ršBåŒÎ-qÉ”\Ê !£Sb9[YSWWm^ÎÁ˜Oç•r"ᑜíõÞ— ¤Ó*‡Ô2;¦;/x!nm ¨I(Í«“Ÿôç)£Y³ê ÕµVõÝùÿ„×þ%~ú«cÎ+ž¸¾\LjÎq¥± •-§õuå2k·7 t_ùÚÉ+ŸMµf³CçMæZroù£gÛ+•–K¥”¨‰éɹ°]˜–Œ«˜GÂÌPbÀ_+Í;)Öl÷ }Fç-•êS;âP¨©XnJ~RcÖXÒÏrÖŽ©©³xŽÎ=ηÿÙ¦ºü|ºyf(Ëš¬3‘•(•Q 1á•IÅ;-nÊ Ì˜œÙ]¾îìbSÓu×úš-ºÆUU+l¶rÆGUæÅ[œì3 …<E‰ÉEv÷´æÖóáíWvî¿r÷øÈôÌTÅê¿ó쪖ڹYG5S¦ŠwšQc°Ôá´X³Ñ^ÉzõòETO˜’ µdU®4sDyVy›î1÷Žx®XOŸñr3f8Tg{Ö™“úSvÃʯ%Sþ0iy¹`éËÍóR±ã“b?]>vAé'‡¿ô»Ì᥉ÝuÙ;^ˆÿè »Ë,›R–ò“zŸV4FÒ,f„v†Ò–QW§jR2o›ù·˜t\YÆ~ŠFÌa5Äâêy О··Úª¼=cÚëÊœW”µ'pwÜC•ìrÏï]y¦Ù9óŸ·±/nY¨6Ôz‘WB£1KbªóSâŽÁþ%TMÇy’j9‹¸••ô†îç¦H«8À3¡_E/Û^‡8Ïg:õ|=0( agð+Žñ,›Hñnš©¡‹%<O˘Çržæò(•WEÝ)‡B$ápD¶=N-´±†²ƒ1–ñÄÀgCÇø3SL’b:o¢ˆaþ• ª àf¾D—°ŒuÝüUJÈF6‰Ã”p3išÉòg°†NY2möL#ŒF–ó+8ÂD4êÆ¢it5Y¶r”v3ÂÍщ¥ðŸÅ4ž<E@ßå!wGטRÆ¥¼±62„Œ Kµµ×Ýtóšÿj\µ¤RÒϹ\Ì"þÌÜh©x'â¡(ãþÏœ$ÁzÆ9ÉrfD®Â‚jð?ƒØO};?¡j_áÝ>ÂE”päx+qörë)§œ•lŠ “SŒ2Åå y=©ÙéÚ^ŒÆûD”Æ9“\É¡„÷å=êâJþÎjNg}DÚ=a3{ÙÉ1±ºÐZ²àM,ä .ç7ÌçBÞœpQÞWˆñ6Úø®Kv[Ön÷}ÂøÖW|·_îôËãéèû[ö½iôwŸQ´Ý¿/52/ô• ;¹ÊíÏyxŸçÏ•?ÎvÙîÁÍŽÞ^ª­B{J5IÆG'ÍÉšžó¹¼—ãÎ/0™øAhÓ³~ž5-çÎÐ̸mY׿=s$å–´*ÒIoÉɶ¾¡ÁPQhˆþ¼™ŠG4ç4Æ5Ú²ŠúÚŒ^²)óÙÏ”l9'Õ9X±Ô®‰ ¥ÍÙxצ¶Ü¦k‚βüþÙñ-gTl‰5<{Yéº5Ë6•œ^?9‹ò~Óúå'í(1³XÉi]¾sS¡ÀTi¬×êzñbr–t;’±´HbXM‰l‘XV]¯¦"A¹ìI•9³J”¨˜?©<-O«SÕãÄ”órY¥õªi4zRsL˜í1T ¦M'&޵sÖÍ*Äó˜; !­¼ÊX‘LV"­tHíÓV¯°gRÉíuârmŽM*.؇ÿ´þûGŠšW~¶L.xdÞéÍÅš¶[V¤ªXržÔö©s8eVš³GÄËTùM­®CÎïR<n’êÀÜœd±É!•ºœ>nîÙ1mÃ|wÔ9“ïi<^_½ç´Qí†{ÕtžØZlZ]Ó:-·iÙä‹ SgÌ·7þú†üÉö& éÎ+d” y*ïÚIe1Éœm¡: Õæäò~Së$ÍòHÞ»3jYN2aiþu8çZNmãI. %rjB? ͽSwaþuÝç|ã9oñ–í.=âå!·&ânÍ;T$\úMà’˜Õ¡'^úXîä?SÁ¹Tpwr”'>š÷=޳‚‡áz’‘–/C'ü%á}y‹ÙÏbFxœþðõNë1ównä([yòÓx¸œ“¼é)FYΙü‘WOa¢ßÆ ÑCÿ]¬h0:ríŽöÜàÔEøÓoáÙHW/EmªQÎäw`-Wð£Žg"ì7ÙÏ^ŽÿçÃCåpÔ‰¾•§©˜ÿñ@~Û" äX4/{äÒÈö÷vE¤ÁelfŠK8ÄÎSDN…!ÔGùÿ•à_µ¡ $Øu‘ªi-{ÙÑe;¸¤¶vÓM7¿õ¿WßL¥þUÜÏóôóÜÅ0ϱƒÍ‘-÷q&(ç ºà=Q;j7IÞÏ3ÑŠEIôB¡ªp‹xœB²§Œ´-lädA!-3Ûù ,ŽÔ/ ;9ÂÍ /ÂÃ^¼ùìæ�9>O@%3yš=´Ïû&÷\¼\ ²GÕ¼Óùkô=] ¯|Qvqg“å·lâUö²ž+¸‹ùaÞ½œE3}QnÛó.>â¢ã~Ú&5{9À!;Ç|DB­�� �IDAT±ÇŸ®ƒ_Œ§Ãð“÷û…&7±*pUÜçÂKw{¡ÒþXëC{/ó—1aeÎÇ'ýŠŸðßᬸŽÀšÜ:âÂPŽ#<ÆgbÎ ¬ÎÊ'¬ˆY›÷\èÎÐxÿšŽ¹·Ö¹1-yñ&ý£~–L¸&fv^YL@רñ¬gbêb'LϨÍÔ&㟾7wͳ©KÖåþ<7=ÚByŸ%ƒ†ûãÿ«ºñºÖñ]Cƒ Ž6ýJæè׆‡‹'¼|Bw¶n»oü6÷àÑVûg)=nF(U];:.qfvf‰0íð€Ø }Êv)žikNí¤íËô *›P×mÿ™Ž¾fᘩr!uUJO÷Ú<{Ê8inƒž"1“ íO;»F•‰“Jæ:S\il¥ÍåÆÔM3Öa´Kk\nTåäÅ• 7=ñàOn¹lÁÁÌ®òÆâé{»¿õýM_¹óþ_Æî3J®òJûþïTU眓rÎBBE0`¢Á`Œcl°Çã8öØã0žqœq¶Çã6&c²È!$ÊYjÅιªº+œ÷CëÌbÞg=ó¾õ©W¯Õét÷½ï½÷uý¯îéƒñ3:ª‹§WììœVa¸A÷€ê^u]k~­~Æë÷~oÑ%ßh»çìéûÃÜ¡)ÙÌ}šŽYx\õD]-ŽcXE“Î]Ž&µäôÆ´MÓY&“SYnÇAS2(ÌiJhÕ†^)—<ì‹1åôÄ\V®µÛ¾œ§÷«&ÿˬËâý™‰É?.èÏW§ìòDΫi ­& ú5§7Èe5„Ùê²C•¯ÍOÞþHúÕ Ò½tYܪ¼Ö¸“ÇT•šY,(P•ÒêŠY8¥EEÒ¤ŒÉi‡ÆdÞOq¡«ª4’c>‘ð%ºb¶çmLX“w3…y¡ß.)tshaÎïó:¸q¼6Ä_¹Ý÷޹ëBé—}'i÷õáŽ/äà dÔݧ±(ÿÌ—Âíù·îÉgÒ°=ÿív÷^Â[ü•[XÏ Þœ“÷Ç(ª#iNå÷QÆ-¼A)7å-çþÂ#Lg3ù,YÆ,ä6q5¿`Ó)c'üý„”q6Õôó+:ɼCWÁßñ_ão|7F̪P;ëÙC+«ù ûÈFhžo3À ¬Ž‚¦~Y¸°âi÷s1ù-ÝQäÕH´¹o *‚¸ŽË°òÜq¯rUtqcTh×s#ëYÍLvPòŽ­Õ�àO”’æ~ïž$!÷DÖØßs„2T1…Åt±™[#û£Œp>[ÙÇqB†èb;/ÕÔ䮽á¦ÿ[¹z*•zœ]4“áþ¥jžÁFŽÐQ*¦°ŽÝ¬`7/’'GœFº)¦éQUWElÙü;`Þ‹’e.·ò vq6û¨ä8âþ¨’¡6p0Ò;œK/빈Sù)ªY@1“ahŽ4w³ æòÐ?'Ë<~Â6fãBže"å<E-¿ã\å1–QN¤ŒÑèºÔÁa*U‘Lñ)ù3½x¦’ú+¥1ÿ˜Ê‹-³|G, nÌ¿£«zÜFy—î©ôžbïOOêUwv°¥°¤fmvÕK¶ Ûóö’ \(ä'Í^¶>´5ôä°d‰uYÓy€[ømÜÊœmÜ•÷ç¼-œ6Ž?)uñ~OðÞ´ÒŒ‡êMëÔL[̼¬Ÿåt&$ªÕúIÊïbb®¨ÐŸ0’s8èé¯^Yjí »­l¨¤Üüa› •”ûUæÒóGn{hhÿ̰k]—“Uö*æ­2Ogœ^øl®/zõ£W´»zâ'cÿ°ohJºsËÅ…¹ä51ÅY ºÄK47Ë÷9Öª·SÁݡי7ÏØ3*+ŒJ©oµ%'wTïVõ‡ÌÏ‹zûå›ÅG•mWVg[½x¾&kSXdì )¨0´ÁICªGí63/+{}~El ç}Ϙß~þ¾®¿hÆ÷/þÅ[NþÙ)1ák_{bäÝ/<wßX²fbá¾LW[þþÒ¢â í™Õ›¹éž¥_¾rVg÷P6–W>¦p£åCfç½Ú䕸™ûLÏ‹íV3ÅΔ“û¬0i¶ýÕ2‡M,”ÕX«ó˜®:úÙ´°F՘µ*Z*¨“éÐ×\bYê¤íé“×}eÓhOsÙ®Mækë½1lz(OIÌÙšŒËK…ƒ©U;£;FÛËr-ñ'¯ {+—9Pè­bSÇìn4|Ìæ´ù9›ó63R._ ¬G*0œ÷+Þ×Hh­4#)‘75gv½úa'‡žŽ™Tïs#vqS­Ós.Ìy¾ÌÂ=I3Bµ|4á= ýÕÙôØØUù±‡T§]æCkm^ëìÎy.¸a,üÀŸ\t²#Wûö5gûå+oãç¼Å9ü2ÒËåfäOøLƱ¥/G¸êÉìãC¥^˨f)é|¾Œ£¬(õwSHPÍË|†¾É1Vó*Ó ÆT‡žå Žsï㾈ã·Yd¨a˜Y|›ÛÀsã¡Mቓj³åIGúÜÈóœF;ûˆqÿN1Zh¥Ÿ7Yé†äò(VqrÂGóþB&B¡Ž1…Ó#ÄßkLb{8Êfqœ,‘¼p|¤ùO<E?Ñ¥-+àÇQããh…Á¨£jŠÞ^O޹TÒÅU<Ï~Ρ‹™HŒ×ø{~ΙFaȜĮšš²ÿewõßyW“â9 XÏëäi¤†3yžÿ ‡£$˜ 7O'O/]¬d€I”óV„äÚLsé`)ýQí}x{Ô®U3or˜©Ñæi á¸ö!pRàŠð&ù)>N‡£±épK¾Œ·ùK”úøWf“gÿSH‡Ú¢y[™å°mdܺÛHÀK$)bÓ‹*î¸7pÜ‹0’h?÷ZÙK< •ü}èç¡û¸ÉHÚþsÂK»Â»r¾ÿÞ``Vl°1¼|ײAïÜ3ú<iÃß¾+öØee‹NM/}&öÓ;b. }…ù1gpS³DÃÃâRyÍ Wú~J/Çœ:”÷GÆÇÜÍ.ö Îãò V ØwA`04;mv̱@e¨&´‚»ó†Sf§¥X×–Ñ4b[RûsæžnÈ”{¾Hë°íÅ‚Ê벃³×üâ£å×?”í{¬¢ce‡=9M¡­mæ¥,ÌÞý/¥7|¹F¢@~H"Öz¬ûƒ ?yk¾nGþ´éu+Ê%šdÊõ´z£Jq(ˆkH):"(4/£¡Ì®@CâÀ`Ú´¼'F•ö(´=cLBåBªFĪ$;ÔMÄ„[T*.,¤Xz†=G´u¨O*Jº”µêš¬}»¹§¼ZPyÏ%í·<[¿·ºõ WixËI~з÷ƒ îY4ùžUÙÇ/¹á‘msâN]×}úÎí+ÌÌŸ”9å®YËv?¥eTaNðŠnõ9cS”ŒY4¦p²ö-æ&tfĆ µi¨3×—/—ëQ=b¸ÊhÆôA5óé‘(s¼_YTL²S¬×Œ"Yúëg<ÞÛ“‹^2õXüƒŸ _žµ=£3as‘¶1Ù@IÌœZ»F³5ÑPø»Že'ë®L{Ú® Ýc¶WÈõ›Z蜦¼DÚ¾ZÍ¬ËØÎä¬dÖ@¥|F>/Æ SXúEÚ……ÆbêK•öœ°ãT&\8äQFë,K ³Náù¬l^]¨ŽSv HU:/퀽 {Û¬Ú/ùblÞ‚üŒuáý¯ûñìOÃ#ûÜsº)¯ëjöì8éî(|` —å­g L!Ëtz#×JÖ¤,Šø¿¥‰‡Ço±ޤ¼Í..$ά‹"ô*;c&‡Ç-‹™™?x¸”1öFýôsvÌi¡r†¸‰Í‘ãx0ZÛÌ¡ˆûù'š(Œ ~Å´F¤Ý®(ÝøBD™ÂÜÄ^£6n|aqSy“ñï좑 y÷PÇ'ô™ãråfF¢rÒ1ïF>83ÙÏN‹èá«ÉÒMå0k8 d˜…uŒ7”mT’¢ŽÙb~Ž8:D|¾z:HE#¨Mï(qÎfoMÿÏrµ’FÖG[ r>›™Æj*háUVR•Ä‹)c0RñŒÛ³YÄZæGŒöqJ1½TÐÏD.ŠÂ'p9%œÁ ìâ|.dnd®d*)R\º—ʸ3ÀÁ€WHFcÖSÙÃb²/J9ÛÌêè±¾z8°:ô@”!§/ÒñÐJgE“m|’#œÎÞ ƒ2>˳ã®æ÷ÜD5?à žãâ\ÂIìä\žx—Wéþ©gÓ:–r&‚á Âó:¼*±ó’^äÌpd0ì|.ý¡vwÎû „fpF¨„{ eÛ--7¡HSÚjóËô§5ži0/íäÐ[,¦¸ÐŒ”b*â¦fÜ=ª,°8ç—gò&Þ¢&ô#qiL.P;IŰX^¬Rs­²¤Í%.©³»ÈñZ£Ý¾–òêÑ÷¿4X÷Ó‚Ÿ|·¦«e䨔ÔhK¬w^Ö„˜¡I£&æÔ&îøMëÏ>6ê- ;ÿí«±gk/7® §õÅ/ÝÑôò´œ|RmBCL‘£Š‹T4ˆÍ²#¥%¯0®t’Ão›SP¥=g~)ÊJic…ªÆÔŒ*©5°WKNUŸšB©ŒÚ&äj;fR™dRq©¡ǵéÕ CãÁöè|öúi[J‹u «Y`w»â=.œèð^M}cZž]kÊ—§J óG&MýéEåÏ®ê˜9¨²[Õ<©IÚ;5åÅg9Q°ÓÄfÛu„îizŸšFGÚ ïÒ6¨j@q± &ì‘®p¸BÕˆÆ>•bª ·«VS [lhT}QÑþ»¾Þ]Ÿ©ùæÍsX>`I…±”'ò&yÌ¡bõi3òŽùq¡SÊ%SŸ»¯î…ÓÊwÎLï¼.”£#©$0!k±\£ŽB ½få Å…9jœ”ô­PGà䄹ÕrYÏ•¨SÆóü]hKF2gZ\6£*®#ô$•¡åh`å33ú9x4T™5aB(— ÍK˜>&M±]µ6øãiaî>¿\ìhŒUÉ¡™`Kγ²€Öh#~.ÇØA3ËH27fqà‰Ð~ú•1óB[hKiäNšß{´süš2™{t"Àw#±~ë‹Ce¡Góž¢2RGwq¿Ïd“¡CœÏ+¼ÌíÌe;”PÁ6FéaÈq€Ë9H†=Ìg¯Ëiü‰å<ƹQDÖS\φ]ôòiâÒáâqð<œE§°L´y™DmÄax™Ñˆo¬Œ¤ÎZ£né|^e=‹)ãçñTdFwèŽg(‹XÀ§±œ)<ËJªWó ²ëhbFŸäf^ —vºþÿtWÃìæÒHM>îLn''ð#6r%OÓIWóWFc”.å]ãËÌw,¨>)az¢lÆ9цírþÂá¸ë˜ý)ÜO³ØÄÇXÉ\Æï˜F=á2¦‘w3™D¯³Š&q:OИî'‘„&s?GXA÷³‹ XÃ&Z¹ŒÍü^ö0“uLgŒ+(ávòU„ªÐKìe1ÕL‰Ìðx8BZTÑË8¾ó‹ ò!&ŒßÂÂþŸyþ";¾qNáЙÞ„ºÏý—Û·]ÕQKæÅ^¹$n~ί¹‘GMyŒ¥ªB=ßÌkÎ+ ­ÏûYÆáœ•,O K˜yã£.¦0PS2MõˆÓ²FËÍ)Óœ6™ï¶¸.ô›´áŒ óv„ÚFe,mïUtWR17g})tÚ¬îþü-o}øåêí“{îüŒÍ‹·×vèŽiÌÛU=ÛàÔö`×ý_ÌÞÛ¿16|ßÏòÿú•êͺgÔB;žÏ¶­¾øåêWô*®2ÖêØo¤ôÏ•XfSÒpÆà˜ÿ ,Ø+ݤm–C}NOûXÚá ¥µ‹ï7q²îЦmfÄÅ—Ø“·ã€–”ÝÅ&*iÒ3¢¼ÈXB®H¶Òpƒ¾¦ô˜˜UpÈĉíU}—sªsÊõtY™÷Ș-œ4Ù¡•]=“'nnÞ¿ù²E;džTLҾÜ Ãfn3Ñ#j&:^¯c¿ÆRC k›ª²Û¤¬ÂE:^6HPèX£âC>[âÝ}’I†ôúdÚU%mŽŒª)—ω§¦lNggõ­¯UTg2¥é=+‡íʸ'ëö˜Yi›.³{ØgXÁ}¡Õä/ëÊþùõÜ퇫ÿ\9ì7¡jf¶êpwÞå­ftjOû^Ì2’¡úœŠz Ã*B³Ç|yLmSK”'%y€/“aQ¨xÌÛå–TêKj ÝÃ<Îbæ&, %cæ–ÙÛìâ¤ïÄüCÎÑñT¤1Áxí³ÃÚ8öì»l«¡”æ†þÀÕÌc+u®Íkd›Æû˜?šC?g)/qnè\Šx,‚Úç-Îä^æ°—O’¢œ±&JåbNa<@î(SÙÌù¡?E§ß‡y›ÜËzvs !EÜŸCÕ”ÓËŒŒ×¿„O„6ÑK”‹t%¿£žóx‹^®¥?¢¾î‹ft¯sO2‹8÷³’Rî¬#Kë{xˆ€X¤‡y‡êo^:ßq;içúH4¸‹°–#ìáŽp*£QTã‹\Êë ±‹ÍQÂÔ;_|×9À[‘…yÏsœ¹¢Û)¤Ÿµ ³8Z³Í Qÿ7ö¿ Ùç¥Rû¦œ |ža>Áé,dµ ñ:=¬'Å(«"]êÿøÖw³žA’œAeô€þûQÞ•®IœË©ã“¡.~Ìk•<Ë Îåô2‘“#­ç¸0´eLæ)Nå,x>ŠéœÅ‰ \:†È—ãÓ¬`0š>ÇÚYχ¸‡½\ɵÌgϰ¼ÄŽ*7¤œÇ\êù: yG‹Ð3©§€ÙͲ$$™“ö}~þŠ;ÞÖ} Q³2l6ÒL ¿æVÃ{¹6üÃÇc©YÙýÿ(òøUò¶þÅ´íù3ŸÉmƒì™¼øó9o…–%=1;ð‘ C29 ÎÎ9‹öñ ¬åÇ3Üœ‘‰iÎùI¨µOA\*'>¦2åüW?zW¹ßgô³v¹Gœ×U+VhÚ1wfý8g_Öñgd\híšQõàʪÇ.>ü¹_\ò›UÛë Ú çM+4#˜ð…Ž?~½ûν5+ý¥?f†×$7ýäöâš¾Šy<Y»$¶ýóJF,ªûÅcéò¹-æ,œªâ°ê7-è×7bAŸUÝö¦­L*=®±É±A¥Óœ3ż.Å]ÊÊ d}³ÕÔ^S‹%²[$²æeH+ž.3É‘€Z} lÍ*H)ëÔ4¬d²î”¢Yöl5¡Qo^åA_vz§æ}}m–Ø1õ,©4ð–Iu²µútm7¯Ý„„±éö?kp±EYG›R)(+1´Õ¡ªó —뛨çs¦,w¼]G¯¦¼ÛO¶©N∊Z=y¯†n(5ئ¯×öã¾Xd^‘Ùqñ¸©ÉÜSES[^Z]ö¡ŸwŃøž“ÇT‡Bñ@s£Ö>©‹»³ÈOŠuµº®å¯üù/#±’ô§æ½ÙhqVw¿O¸''ìK õ²i‚¥9_18âÇ”0«sþaÌ_’¦s2·1Ƴ<Èïy[R>œ7“¦Wç-åñ¼/ó\Þ¿¥•÷Û“ózÂ䜗ãJ·†ãˆœšÜàÏ1¶z¯_œ%5ÀQ>nê¹»ØK ~“ÙÜw2—Ò`âQéoɽ}™ÏG²¬½lå>5õ ¤¹$ð7.௜KßJà’l¤Ÿ§ÙÆÕ|‚ìàpÔ‘ŒQË<Âþ(í¢E/û^®¡—û˜9;ä½É~na/+9?“â /PÃrþJ6bñ”²€;ø1…‘[t7x™¹ÔpŒ&ò1®£ˆ&ú)a79¾Çã\Õìæ(e‘?÷V XÅfÞË_9›GxRM@œ#\ÍÏ#åÞó ³•Q.ã‹€„…\Ã4ñ $c×󲌱™þ²”ó6qV°¼øÎúñ¿—«¦R×ÓDk±^þÄ穦0r×D…½–™úMäxìaœÏò´ÓÉ|Î`8Ò¨¼å¦á-æÑ¹’N¹#4@‚'™eϤ™Ê" 8ÆùÖ;¡/ÿ 8•"æòw²=ôzh(2ë-e‹æYžwBÎ~ ^âTr ²}ô¦—g¢¾jbÖc)ý´S³!<2™f{ø {#ÑJ ³˜ÃínøFpׯà‘À‡Ïô³÷Æ¿õbÙ¹›F§Ù÷–'b>z„æ¼ýÌ_÷´÷þÀ[ x‚iô{{À’uNH4Í wײ¡£ìе,ãøy—Eä‘U¤é L¬áÔÀ{±aaÎ=yõ17‡º™Ú`ö°­æãy‡òÚ’š&™Qî¼=NÑ$5ªªÒC–99îåœãÖ·êíÕêÉ»¿/yNþ/õùðÍAó:Ô¤í)™×Yzû®‚/Ýœ}ôcµŸ¼`è?]PY÷/ÿv¼8H~è'mëNŠ-|»¿ñõ¢§®*w<}Ýkà ©TLU¥tæzÉŒ¢&ÝòÐw“‰òøêÞª}%‚5y¥)UýºRJ«Ï{ûx{O.E§Ps޹ÐÏÓN®R?êWý. zäÔí3{«(2: Hô)N)Ï*Q=¨(¥¨@j¢ãû´–º¢AC§³Ž˜Pep@IB..^c˘ÂÀ±mí²pˆÅúFU i+²~Ds‰ìL2¿OÏdû‰ï#¦bHÑ1­¡â¬)»ƒ 76ÍX¿nÏÅT•ùm¹Ï Heµ÷›P¬©Î¹ ÓK%«m¬32(Öª2§ºþéù±ßÙ/ŒíYÌá¸Ê¼—†TWª.öR±Õröe\,LmþÈ7ó¹îR“SÏ©È C½n¶wÌüœ¾<`ϨÓËUæœÚFQÌÊÐ-^Æb COÇÜœ^&›ó¹2×¥Íæ7 çT«M:2D(SšYàîœ|Ìmõ&{&´5”¦œ7ìsÉË®ùˆƒãÛšrË;}¬ÂçVùÔÓŽ~PgŽBö™TçÂí±÷„M½ê§Û7›vóŸ"ŒrÓ§°–¿ÆÍafÜò¼vfå7¬øoö9si‹°Ôçð-*©ûŸ:·6Îas粓³mìà|îe" ža §1=;íâ¡„;ù 8à N¢…5¼Ÿ}´2‹6vFÉã†ÔS™Â,¶p$J»ŸmLÆÅå´@"ÐM_”\ét{ ³£¯x”p¹—Å F. 7ȽtŒ9%T- çÓ ¶G=ö3§ÇéqW’¢Ÿ™Ñ²„ ½~\fùGþFÌøØföP­`fFË055g\{ûÿoåjb*õkêyŒ&ÚÙÈb–²—eÑ5¤œK 2ÊtÉ0óaçÑsÏ1ÆÒȺ<7Z²ãÑS}Ö‰±øRæ"tˆ<­ÐvW”@ó‡9“µˆÎåñ\çmd©b0ævÞ¤ 40‹»XÊ>à„^è)n¥—MôEïóâFÃu<´f3³¤œ) çcùÙ3=´†!9‡ƒœÆ%ÌcF”A0èæ>çÞÜyVè$âÇÊïË”ÆÞ[˜Û~[läõÐ�xJn¶5çÓÎN®f ‡cvÚ·0ŸÿÚÉŸ\Z¨ácÚjMLj\q?¢”J^™QoY̳Y£\Á+qÅÅÄLá½ü>æÌ2›yfØâп±™¬aI‘Ç‹MN,28¤8ç·CŠ“úlfAÜÛnÎ:“ªÐਠab™33îÌÛ8/íP‘ò:½sîO\{¤îîw×ìYÜQÿŸC͵¶žõ¦áLPù˜ùfÍÈßÔ¾¸2»ªshü±ðhø¡?yí´®# É:sªûÕ•ë‘OiJš‘ÿÄ_æmZu4­'ëx“¢2›k tßóíÜÝ-¹Ly¡‰…ŽÖª/V^f^҄ɺê-TSmpT²ÚèˆÚQEM:ÓÂFC5C†ìè´¤ÎИ`‘Ý-º« •·:ž¡ToJU±±@Ød¤ÈØ.•ƒ;V  š4ÑñœÌˆŠ>»,ÖšVLZ›ÑX¥¾FvPU…±*Ç ´ˆ\óTfÑsím„çù‚Ï8ª1ãgT—jÒÑ(sÈ ©„‡B §Kî–*0é°Š¢§[FVÿslÃûåêÐï‹,‹‹õkIªô»IªG,Ë Ö´ å2äKü™óGmÔÆM½kÀ•–ÆŒylTw©Í)íã.ƘªÐ`‘š+ǔĜ·1f4æýq‹ÊÔ ùѨwÇT†x“I1ƒŒ•º-ëhB_Æ”˜ó‹ $­áä¸óBI9{½ïŸçÍñ1ÑIV>ê­ñüsxø…`ÿ9±æÍá!š4uøð1ÕåÁï?Î JÇ6Õ†öò$gÐË™<É&ޝXBO³'ï7ÔSÆ6q ¿`1îcå4ó é(Bh*ñ0"„Ñ 07a-Ë8›ç"úqºhã½üeÌfE”ñCæp˜'˜ìÇW »©b"c<ϹÄHÒ Ù>ÄO£ ©Ë˜ÁŸ¸vŽKbRÑÅ“IFï±ÈM´ŽY‘¢ï¯,£‚bæD,ž'‹¼ÆÝ1KCk˜Àh´XšE ƒœQ>Bý¸ä;ô6]”ñ>ÖrðµJÄé`!#4RNKô¨û)`ÊÓëkjV^{Ãêÿ.W±ÿ9»ÛE5ײˆuLåLäQN§’3èæ1~Eý;H€¹w¤ÇYúg‘m OÄ—•±"jËvÑÉÊÿŽ÷pÎÿü6*""ä©üž¶ñ@”ßó¢Ðî�� �IDATr*5|=L¥‰¸’Y\Ïm\ÍœÐ]¡Nîà4'âmþÆU©ýh¤™ù*Ãl ƒrÞ`ŒCׂ+YÌ>]všÉçm ÌYBsÎýÜÁ§¹‰³(Œë÷f#“ìzÄá]ïãʘE¼'ë7]^˾rAnfRñÀ©QåÅÌ£™?ð*ãXÅP§v»ü¸X6/š:?´8î£9‹c.äiÖ'|ˆoó!nl4'eMFwvƒÂÀŸ9+ïzRª*·§Ú™y“E 7sÏ$TP\¨¡ÎÑa¿+’«—Êå­„êÀrŠGuz#²ŒùqµØ€Š˜%Έ© MP5bY|ÖYÙ‚#][3EzŠ~xC[[XyuºUS[®~¬ýîŽ)é½fîјš¿‰¯çjn½´ðÖ“­‘›àh³ã#qó Ò_x,ì-î™óòˆ{Ê… ϰgØÊ UÿøÑ²ôGO•›f¨DyJQ•‚„)åÆU%5,±%exDå!É>Ý…þ©È½½Sï6MµòS™é0f;ÜnR—ÒcšT‡­6–—ª4Э¥KÃ1-ý ;X®ª^q±M]š³Š2^áéaßh02¤j²sjMTÜ«ªXX&l‘.S1 1¼b«‡NòÛ”¤ÃŸ}~ïòÁ$åNž¦1Ô×¼_Ë)Gm=*×®)P=fzâFÉBUáü|^¢^®Ô¦Ð¾˜Þ}5úÈ›>äÚ1O¤¼rÌoCëŒ(HÚÆ­Å>_mahyýc’…* N˜Ð/Áz^£*çÇM ò¦eMáÕœ[\–5˜ugÖµ½>Ê(]¡f¾’sÛ˜sQÂûý`ÌŒ¤KY‘ófÒQVÄå™KBk¿¶W½^Å6–$ÌÔY¡¬<ü鿚<×wþ¶½È!fJ]¢¹eÇóU›-ÜÎÙSj \-Ÿ¦‡ù&%4Ñï9Î)láÝt2Çø8pˆ;ÙÀå¼M=Ïqz4›G_ä»,a_g wPÂÏéæÃ³4RŸÇ×ÙÉilá?8ʤxd9Ï ŠüæD…j<u}ü+>ËÌ$ËëQîÒ×ðÐ;v(Ïñãh¢2™ÉŒÑ•÷Bh™Ê#Ñšf*7ÒÄüž3ŸQ¶sAdRîâ’¨¹YAa΋¸–êwÄtµF…óÁo"­Ü¸´o\1·;¸ƒ&þ%â?]Ç&*Xå?Îñè@ÿœëÞQ þÇlðÿÕ]=J]ÆJYÍ5|† ¤x…#d¢Èà¥ìü?ìSŸæ%^b7séæ:þF£á=<IÚy™ùÌg;x‹i Ÿ =ÃótG*ö”q c)ÛYÈÛ`䜠žŸÎSÔð�;ã&&ÐA 7ñ/lãì(Oëû”p€õüŠR¤‡/„'¢Øžlz#œ`³Cý¡§C],b!÷òO3)ðb—òöòûˆØ3“zÌ6ÅN©Œ=úî\~|tû_åìðÒçÃ7~{£¬dcOÇÍÌ«ä…JÞç´µþú˜u)?ò»{‚\Ì`Þ9=窴-qQœpjNi °œiÒNÎYÊ訚¸Gêœè(Ð*ÉêÈY;â…:jÏ:2qï }&ð©uY õ¦õÎÌy ´«Õ¬Qss3ÆMJë,6¹Y¾_EN† EêêŒúM©É‰#¥ÿpgé—¯/JÕL—J.蚸etÖö±WÏLæ>eðWß™ÐYþôFγà?ôþíÍՙѻöÿöû½·+7}ª=‡• +¯Š?W÷É_uu¤Ý¸6ùùŸ”ͯVÔ¯.0aTiÜï: œ(œÚ­®F0Áp»º:£­Ž…2GT «í2Zeg¹–Œ–Fc½ÎHy»Íá´KR6MWøšÓÊ¥ª¥ Å<–öF((Wدx‰Ž£ê›X Û©`ȱ*C&L— æ›lä¨Ý=fÌБtp®Ã;œ1dJ‘úåêºÅšÔ9¬æˆ²SJdËoÿ~מ9ÏÝ&3 ¯^]1ó;¾úpÇ`¬øì‘«_Nýñã™­‰l{¦ß»ò–5ZšQÔ­jŠÑFý=…»øJÁ—Æ&.ï°sLCÂ¥O z8­9¯­ØE¥ÖØ”±0oI‰Ó,¨tVÂ=µW(ï5–5˜×¦¬Gg¡?ð®*“SNçL®ª·<ï¾1Wú`Ο8‡snÏHòZ¨ t2gDýAœ¹œJ{èÕ¼ïñLà‰˜²©æ¥}6åIjùcÞ=Ì5mš¹ö·&>Ekèi}Ã6„/\ãÇ¿öÉÙ6?/µš'nˆm¹9öÊÙá'ïôÛ9žz8;´9cvx‚ÐÚÄÓœÊS¼îDÍs¨ÐêäGü'»¹pE×ó·s&;œàìâ…ˆ˜3ÎË>•íÔðq (Šà³/ñvó8§qˆ1Îb}šv=á5F“¤ëh§Žµdù8k"hÜAêYÂ},‹N³ñhõvrç0‹x‘c DÒëKy– òQsÐ);¾D¼›Çéf-‡¹:Â^´pOÒÅÙ<Í:ÙŒÆMZÇèdÙw”«^éæŒP[b€™‘Tr=¼—cQô‡wä¤Ä¹‚‘ššØÿ²»š‘J ²‰,ãëLàó D¿¤ñ|­ÉŒFúõåQCåÜË7Xiù±‘’å`Ä y– W±w>wM„¸¿…޼"&òB„› IFÖ¨óC¼qæ/Š„üÇ)f+ù&eÄ™ÆãòÆÀÉ­œÏìd2G£6ÿzvñW0ÿb%k#3Vå¸d¶Vk輬£¬ Ô±š¾HcÂß‚Pžy_çÎåe¦Ó@† þð™ðŸÿNÛ<1›ü®Àʬ_…ÏöÔ[~vU>9%ïy5Ì4©Íì?øõÏ5w—LN¼ñ]}I ÌŽ«&™wÿÁ‡]1§‡ÆòÊù|™y… ³J²ÖpŒš¸¦¼ w x<í¾´Ä ™³*œRÀ€ÚF£I±À‘˜º¬]®Íº‚м޼Ã9 Â"BAÚ=cNÎÛ7£^KJCÊF\˜u¸Pu‹£¡¿¦¼R.6¢!¶òꚦ¹¡×H»ÅenlÙvUç…™Ò‘Y;oh<Z×·sQÿäÞѦ7 ~üÏ™—®Ì¯këkè¨+kêýEõðwÏo<ÐöoɶÒ|[÷à¥O÷ ­ôžõauGâû+cžìtyÚÐ<›ß"[ ©ÁÒ¶ï31® />IoζA3c⣒9o6©ïW2¤mžÛ-¢¨ÌÔ˜yÅÂ!‹GUVÊØ\-U7­Ý•y“óŠ§Û¾O8Q8Ëþ½Ž6ˆ÷+4+¯šÄA­]Úë=Cúˆù}Jº´ì3³YwÖ·ÊÍL*T™¶¹TI\6Á Š@w²úÓ£g—¥·§ó»¦¾7:vÉФíá¿k_qþߪë,)¾~öð¯{âÝáH]^ÇLÉŒ³$7ëj-L}ã·3¾zMßog)”KKÆi69kù˜í¡¯5:ë¸t`V^{àO….p]§Š´ƒNª•ïv<nn£xŸ¢¬59Ýcf Ž™Ô(6âÑŒ¢z÷{€ÏPÄm9E /åmåâ‹ ”åü&8¡ ~Ÿˆ™Sày¯$\]ïï[Œ¤­ë=ñß4“yjeõîú¹÷|†},ç=Œò‰ 9¦ïÛî9ªo‹Ôø}˜÷‡cŸŠõém1TúLh*ò4¹–‹x›[™É†™žóé…l Låb´’m´ñ>NfYÒ4ð1b˜µÜÃg8Ê‹Lâ îâoÒÍfÆ%|g1‡Ëx” ¼Lˆ°³Ûø8Ç¢EÉ%¬a= dYÂ^b|”Í´ãM.âBޱ„Çha"IŠØ…ƒ ÑÂÇø­ÜB1‡¢ˆ¾Ñœ° •òSzù*ƒ|†jÖr1OD0‡B^¤”RF¹ŽC̉‚Ÿò$èäFvFÍß9*x!ò}–5äȰŽÁè§3•Syõ–«)¬¦€55‰ÿ¥\ý{*µ“;8™‚+dG¸ˆ<Ý\Â1†é¢<¢"ba´ñzœ~ö±;B&sÊÇ3•[ÉPÎf°„êðcq„Bvpײ”V>«\Ä}e5²Cyåœ(Cì4žâäd²”ÓyœÌejBGàòÐ~ŽÐE³¸›%‘üfc<Žðxœ¥ÜÊW’¤%euÖq¾ØXÚÀ~ÖJʬ|0ë´²uæË<ÊÝì‘^iÍòX.ßRžàNM uñº–Ðsûhã<^b uf-ró&çT»¥%xè ¦†nÍ™“/¶{ì„ꔘKB[CkâVVu8ï~^ $cÎÊ c‚‰zûý€3x²ÛhL"íW£ö䕎x9ç¡À!⡪¼ÑåÕZ²vååòBõ΢P®,)S ¨ÀB»‡$+\2A8dn¨ÐÁ!Ï%ÜZª"åé‡μò“†c6äM_­ø og«ë‚;l^:6Öìœ9:©3~4\>Töðy%ß½±à¥%ýWlËNüíswü>·l›e½–í MmZQÒÒ^õÑ÷Å’µ ,Ò?bK ™â˜å¡ê^Ïš(V’W‘m÷ð-cBŽªìVžótʲ2ù"cÅ2ĉeÅ›lîÕ›V_.¿_ÅLÝšêuϰ·Ýìj%ÛMMJ”É–8>lg³–¤l¿xL²P|ªD‚zÝMzRFF”e5UX5&^&9Ó´…YÛ³0)0¡ZoÁ{§ô•ýòʼón¢"ñÆåA²4¶¼·úÊŸæ^ZÝk8l,*hm®xk ØÞ>sCÃ-©6ÄÎ^>°¼wó$úÒnÉ:/᢬¯ÔšZ£´Ë N2ƒžBë ÌŠùÇ ©^­EŽ…fçm)2mÄã¡áa‡³z eX™1!¯3e+ý8 t õ¼;¥6®û÷ðÊ»«vTä úThZ(¸ 0;ë¼+ïÙ«z­ò-–ÇܚȌ¸J…[}à€_]ɨ£šmq-ìŽÜ¬ãsþ9¼@qèÁÐ.‰Ž¹$gSDk4ˆ+àptÇ¿Ÿ‡#!µ¸÷ñåu2ü÷óÕ qœd”55ƒ<»#Gé~ÊYËy<­ðo¢#âPÜÁÚˆ×ðgÖòÏl¡“ÑF¿)Ò ã�‹¢Üóös=GÙÈJ)g[dò©b5ÜÉFf°’³ˆ1 ÙÃjÊ8“J^¥Ž_ò2ý|žc¼ÈPÜ¡·x$Ç;_ûøÏ(Úâ-šXÅlšéd* èc'ÑœÆ5 Üq1þûuÇ#òoŒ Ž2…–é$>ÈÃ<áñzßh9¸§¦¦ô÷]u³ƒF:x˜ÃôD¦¨}Ñû7Gžj‡„æÈ;ÚºÆèø ["?ÚYìàçÒÎUœG–É RÊÿCØ}†×uÖùÞÿ¬]Ô»,WÙ–åÞãljcÒ§‘$¤PBË e sæÀ0”30fÍ¡„�©¤JŠS;‰KŠc;îE¶$«·-í²ÖóB^\9×ó½ôå-ÉÛÒ}¯ûÿ~ßï|^§9>BÞŸ餅í±@z‡ÙN>¡4pEd÷Žî‹ +™Êv–q ~ã ˜z3r”'(‹AýåC|‡ƒå®MjŒ\y-pmÂÔH%·²—"Ö3‘mÑñw¹ËçæLÍù+/f˜Õìc'ÛªWÕ˜—•ˆ:öDuÃá„ï:¼¨NiÆæÄÙíÑg9ë¶OwŒŽv0Ÿ÷±ÀeOÉ'}å#M$"O$̈<ÌY‘İ»cŽF[äÀ«Œ Ì ­M˜ù=½œÈÖDî…Â3¹9¼šÖZ!=b6sÎ|3p5k"í,*2®BCƾ‚ÜS04à„¼gG Fê*,+3­Í¡‚—NÌ1doÁ¶À˜„™Y[²9ûò7É®ýH™C¥Îò‡‚ žÛÞÙ_qpYn¤®KÍÜë›ëW/ÿôg&:Z¥vøÅ÷üñ·é¯ÿsúáꚇӹ‡/O=üÉò¨+³ö›Ew--ÝrfÒ¤´ ¥¿[ÝrÝýÊsÊŠu {Š×+MéÕS%Ù¦!§ª\_Z]“áÑ 9Õd¦;Ú«ú ©i#ÅÚ{L(øuŸÙåZBs÷›x©Ü„„lNéUãô¢c&+ª¶?eF©¦:ÝFêõJÎÓYªpÈ”ŒB— ÃrÕÂH”Ôß¡{ØøaEy•ƒúú­U‘WÙ_ÿZÅU¯<vvá™Ã6'7I{^uná®`íêòLcNaØ[ÖŸ2pÊ߆>¼)*[0vG¢û ¿,¹x]I–—F²¯cù€Î„Vn‘™%¢c6äÓKÀ¤4IËòŠ\Z”´—=ÓíiñC©ãÞŠ <P°"ô«Qj`f c\>tü³ $l‰ü‘ÿI1µî=”Y;;¥Ÿž‚¢Hu±’ ã³ÞN˜9“Tv˜œPy† ÑÇ¿çÛ’›þGÔØo[šõ|Ûx_äa¶SÎuLgÃèÍ?‡ã«þþX¾=–ä}‰G8‡‡XÏIŒp„‹ã^¦ÈtšãÉÕ‚˜ >³éÕV$œ¹/ÖÍç]R¼NDC<ò:·byú¨®ïññâ²ÀΤé‘?"v/ä]†ÉÇB¬5Lï‹Y@cÒŠÈŸâºXžFºHŃÊÜÄ"&ð3Òd˜làbáez™Ì–Ä”¸uÔRˆŽ·cçÄèÑ'濇ÝÒ|”½´ñBÌŒâ´Ç:ÇY±ŸóhgI<ê<üžíj'Ó8;fMá°ã:éa²‹×1‘7ÞóòŽQlwmmé?Þ®jø`Ò¥Ô²Žñ\K+íqbbÞÿW5LüßÿaZâ l%´Ò““Fc3eÌä˜ÏCÅM¯nÊi¤‚KÈñG¦°˜wbå“ìeo<ěžâ�Íœ¹ˆ–°­œ_qEqÍû}ÌIºœg8ÄQ–p5ø,ûx:´?²:òP !ø«XÇ;ñIùýìŽ%ºy™“˜Æ… mOÖ›õ|hpr䕼¥té3ÉÚÛü–çO>ìì?û[w´÷`&»Óy›ñ=KßQ4ÖÆ:~Î.¦ÕšPðHÞË,ŽNg!%IWFÊ#m ¯G¦&UŒ x‚M‘ÔˆGß’&S™YÄIŠÐ¿¾ž´ <Ždî *ëÞaXÁ„SjŒK¸-ïC‘íÔ˜Hérûçö]ÿBøJ=wpFÒ„‚öZ§FÎÎßô§†µŸ E½ ÃÊ:Š4Ù?üág·>S2ÐT§¬ÿÓ÷úÛêâuçŽ-”ô2¬¬ÐÚ^óÓìs‡ZÚcÎ<Ý-§ï/Tì óÑò¡1}Fúô™<¬ºT²ÝØa"%Cî«vVŸé ØßçPÞ]Ó§>%ß®«VÕDÚýêB%5öõ˜*;¤tª®sˆ:ÜšAS‡žA“§9š–KËí0¶Vï;÷›ÜæÝZÇjå•wjL«lt´Í¸Én##~9ÑäÈ.ê³RãuÇTÍÕrÌ”r™A{j¤{Çß<x}Qê{·ŒHeÅúÆž±³í—_Ëï¼7üüó#§î­~|Y™¦¬…7O‘­Ê.z*ÿõ?g7ž[õʲ¢{/ì9´¹ %RʼPOd(¡6T9à@AGd/PÂã¥Ö~W­hÈ„WB+#‘ ¡ÅÕJ†tò6sÙ/FR1êóVr‘ò¤¹IA¹ìˆÇ#¿áffðBÊšè‹/™ÙUx|[^MäÔ¤Ûë-íw àá¤s“Æûa¹¢3;r„ç},é;»üñ»®¿ß•OÙ·ØŽiÜÃU<Á¹¼/–$TS̪yš˜Îžd<WµbØ‘ŸQÄ.f°’ÃìaoÅM•U)ߌÔS·ƒO§„»ÙCûh¤-p=“âúÊ8Îâic©Ç1V2@'iãÍX®ÑÎp|6+öNŒ²ØGÏj»ãŽfZø4O6½G£ã¹¸/±›~ÅG™Ãñ:¶—vú¹Œ~Ö1B–‰<ÃgØÅ.8ž¨:™·ùX\{·tp]¼<ŽRŽ2È.zùWNf|¬‹ìg„"’¬g$ö˜d8%þ“Ñžïè'ϰ‹b¼Ñ"Ú9“çé‰÷‘ëbêüß@“YÊëŒüãÞÕÊLf7+#ÿ+>,¯Iê Œ‰l£†³yšáÐ{ŒÀÞsˆ-TÇíÝ3ÙI³ù;¸4ëj¨vr =ÜC']4q#x,¶j>ôí‰ðsXÅ!ư4áažáçœÊE”ð –ƒÛø¯ñ¯<BAy•ÊÈ Æóv¸læ2JùNhgè}‘?ÑÉDFREžä{´±™ÿf.¿á ÒA޳ØÀÔ´ËCŽäk­È* {޵£?ßyO³È©Ó­| ºmNºbùÈÛ¨ôµev¼‘É~œçb&ïTò–þÙ…Ó|''w_Ú·CߣyÄ[M“ÜÔg=÷¤|(R|'åòÈw'Óï§QÉŠ¨öYå¿3|R>º¼p\¼ýGVÑÈáÈøe±Ÿd Gþ3ò½´ï'Ì)Ø)e7³›¯òðDãk,ëµ-ë`ÎY‘*Cf eín Ö=¬<{éøüªœ9Y½)UyCSõuüËïû–¼›ùË ÕŠG´–Èd¿ü`tó£¥wÞQµ|ë³7F7O^{e˜]°Ð»eŠB‹¥3ƒÑÕÿø¬îÜFL;ròï²w~¿ö³ÓÏ^Ñ#•È*ë—cäˆÊ ÙH>©4cÕ$ã)§(§tH{dA §ÜÓíVjÿëfu¨ÍK—Ó¥¾O~È¡A…ÕÞépb›qÝ* –M”#+5¬®EE¯qÝr“ Ò0ÃîÃæ6)$”¿aZJ²NïJ/·wд•6etç½”·¤Õ¸LPßßI—G»+òE“ôV;F.k^WM6ñ‹{7,Ïÿ¥Ö´¼9Ã'îº÷Ÿ+ï=mæOÿeò˧µþè?M-uÏÜ—wl¡:¿wnåæ…=]0þÕ¹cöWíæåiÌ›VdZ¨10\0¨ˆ´°2å žd^¥kÇJ–›ÝgÎ*;÷úI¤/rZÆ!NÉ(®– ”ät¥ü!oF½^¶æMHXž0P“rNA{ÖYG¢ã„½èb_øÛïúÚˆ«ÆzðNÙY|;òÅŒc9‹ÙùI¨¹ · Ÿ¯F" ?pñ ‘ÿq£ü\o™ß}ÀÄwm˜%ü]\M9'íšÐ>ÆKÌJ™Ä}Ìà05l¢ŽYÃî-¨äî¤Ó"54ò,å<_í, 6ô3šhf s}ôr"ßçaÖñ,ïã[ü"Î[_Ͼ@OÆËñTVóÃñ6PF‚‹Y ´ÑɵÌbåœÊn†Y_™ÿí„døräÇñrzð(XC!^rûàb¶PÅ¢X¿»-þN>H7óhc=/p˜×8@qŒ´À¼J/ÅäYShG¹ ±)†M„±yòäØÒ’ÖxqŽ8‰ËÙƒ Gw¾!˜¿'øêxÇqkÄyÿgp4¾þãíª&“}Fx›O°™·"{#•Œa/oPàÅ÷ìU Ç%ÖÇwì“ÇÙ±%eB|ËÕÉ:R¬ç“äÙÈE|œÇ7|Ofnž¡Ÿùϲ›qàóÜÍbbõÙÎ_´çýŽâMîc:Ç—..瓌ãt.ãj–±™[y6®¤]λÇ<næ-°Y£eçÐVö¦\úALýXÌU<Å8‹Å1£MòP?gò׌î¬{âõ6¶¦\j0óQsØÝÞúyGz}tlŠ%,å(5ÜŸr}d¾)åN|Á]\úwš³89ò‹A7—Y’“Eñ‘U¡½‘¿FÞê7.¨ZèSÿí_Û\Õ©ãµ`ÒÒ0ýK]9ªJ\“·)ž‰ïhpð1‘£‘óX–R)æPJUä¢RóËÕ—h4¯C[àfG2åÔ¥©•xj°| ý`P÷·“êZû¶¯r”¶ ÓgÞoìðCME—nmüÓ9}¢„YimEÚŠÏß<²vuC‰Ö¯Ý–úÇ ?ºh~¡«Cë.ïëRž7©Û‘Dïªdöľ«7 ¶ .X°±õ›÷UüùÔÞïõTæ—k+vhDù€TBC^®A®VOÖ„Fû3*Z Îr Ô¸"“§HÏ0¶MÓ€úÛ=ÀY Q“ƒEÞ l=ÍØ¶90 ªê%x­]>ÐÜ c¢îIÖ9h|µÜNÓæÛ8×ÑŒªˆœ¡©ÚŸ6³×¶Iº·™Õ§«Áe%гúkÎØÜ¿þCW>]9£}è•S÷ /àÕ./ççL)¹õ«®ÿÑ„qíZ† 4¬è+Üú#^3ò­ñ½…úBï‚’G:oØØÕ=¦fûò¤è˜u¹ÜÄÄ€þ°¢]m(Cs™B·4Zh«4&ïW %Å ßI8;åÆP_^K¿l·0/qÀœÐbZéå÷ã]‘Q4蜟%,ŸæÒ.G Þ*8/T¹›±‘· ¾]pWÒf¶¦Ž#‘øèËÁ÷ê¨rÚ#^™ÄQÞ¹‹eU‘SMIEy/GŠ­¨uû ß«5-aî1—~Jm›kï³u“Ö>Vs»C_³b¦–*¨ï}¾Æ§47¥N8YÛ‹Qþ’Ñ,@äƒ<FQ$ÙÍqftøÑDû 9%ëžO?¡%.i‚¦sŒ‡—:â` V­åÖQà*öPÎ.¾9š|Køh`ZänvñRìd#›™çÑ?Ã0iöQàY²ÌãNŒu\CÈÆÄ󛯸T´™:ÞÏlg;(e3Ÿæ^>Ä/ØF[Êã¡»(‹#ÝÔ’àõxŽ·š]la€Í1·a„rœÀ•,ã0ûIó:ÓâÖ쮘u;rGÏ�ôQÇ%¼E~fdzº¹äh‰K>ïý™Oíÿx»z4“I:~m>UÑ“?š¨¤4ŽožDK|!ÙÃg{iæI®æ•Ø Ý‡ÝKzà�� �IDATÄ”ßý4°'¸˜#,ã ^ç’¼DŽ)ñq ãšBÜL3‡œ÷,ÇXÆz޲›IRÅFÖRÄ©ø+{F†eNˆô„.¡<0OÕ×S£(ÞæzfµÃ"‡æü¸¼]Éž@:i.û"- s#‹x=aÍ,gþ(§#ÔÉvÍGÌ>à´£~ÞíG£oc Ù™ð‘Èï8)ÔÌ_46Y:ì‘kØ•´*ðÕÀ´„Õ ûJe‡MeMRi$˜ž4“^Æ&O8×ãÊ•~;ß óà 4û°'jùXµºŒõS’–00lV…]¼œ°2tWÁµ„Ry÷rÞˆÔ oäL"8+iJ$•PHÊ•i.¨.³rbpò±éƒ…íÍcî=3£bØ‹· ´)Ö!YR1£½fþ+}ÝS:Séúou|â·Ùâ Q]40¿¥âú¯LeaN*¡&2»ßP‰“åM¶ÏìîèÒ‡õÕm‹FJ®¾¥î…Åý¦„Œop¤LcŸ AàHàÕ³ze*ew©)r4¯2Ô—Õ;MnHÝA“r”JiqF­t»tVªVùìr¤Z.aü Í5Æ22AÉ ’´Êa‰}R)¦œÙà@NM ¸_{ŸÉG7:Ø&[ИWYmË~ÍySê•¶‹Ft…tüǪŽ7]=0¿gxÖ‹Ñ܃Çʆ?²§då–úï—ì˜Û!Uc¤h͸ꋨ¾ößG^èH8¥B]»žÁŽ×£×êH´Žë35ôF¥°ØâRʼn„—KÔ–(ÏÚ‘pz¿IZ+ÌöùÈû"¯…B¦'„I{Šöxèh(A ú.4%­5e(¯?uiç1š¹(ë#œprà­È¶—ZÃåÜXðe³øð=2c’3òÑõß÷ñÑZäæòfB DªBwN ô»îËÁó剟ÞÙì’?i[‘ظ"*Úäo ¶N‰ij‹yˆ]žØjí—8HÓ)‘=³êµðÂgëÿ;Ê|8Ö´>ÂeTp7¸‰ÿbÕ{‹8ĉ¤¨Œ)0ÏÅWÑSéådfð .¥†³˜XX÷ª8yñaej`0PŸð‘HéH¤À$Êxi4œÅBVÒÂ#ôRMžç˜7pRL`>iÊYA–?ÆK|S¬>%×ìgNL乌‡™O&ÞD{Ù@ ·/†Î¢‡$GYÍiäcêШw×ÿ $Ma,‰ïk¶ðJ¼ oä óYD’çÞ#]\ΡØëø:§3;v*®º)Š™¿û{ø=_ñï£ùÿÓÎLf´o;¿’âýtq$ã×s]´0Ž£LŒÓŠ£»N!NIôŏޱñ^º”ç‰Kģтãú¥Qâá#ñÕßè q$þŒãEÐÆÛ¸”#ÜþÀûâÂ(`ilát^a2­ó¦Ì U„þÌô@"éý‘‡gw˜Àœ8q{ õqNôQN$Íl¾Ë¶sN`$á¢ÐrªEgÙ¤i‘2úYRçŸF̈šËÍÞ­(²ùj-ËcV}=Ÿ <9‡ ÷ð‚ܰæ-ŠÖØ·®Ùí<FOh`D]ÂØÈp½Þ!-¥¦—³J ¹tÔ¼[Q…}už]ãÅÙfW [\4¬4i\d_­9O3±Ô iƒ´”6:4`~Êœ‰ï°(°)tçd«<WdQ©-Y½¡ªÀÑœFÌÐZYPùÄÊŽ·¹;cj`f¨$2éŠd*r»;>³.{Å“ùgÆûé7kO­¨ÞS9ðñG‚ÏÝZßSŸp(²µC¯ ÔV7¢<m¤^¾{öz_½/Xû©à??éUW˜9OG·»˜Ó/1IiAõÈ׿®›‘Q:"VÊõ—‹è)5g¿q¥:{„9uCv5•Ô ú{WÚ3¬®]]äPµúœD=#ö:`uõiIúúÞÊ;/k¤KuLò6 ½ŠûÕLSÈ*/Ó×i‘åÊÓö4Jõ:Võ꼡 ¾q£'®R“Šê¿ž?4¦µ9x¤«}OCÚâ Ùè‚çó‹:Jo»¶#Ó‘PTcb§¢IzSÓš†n¸Ã› E퉜l¨"yÖÓá¤ÃÑÁ¡¬±)é@bÐ㊠* )VIZé«RJ쨖.XT—7%mòxûm4¤œ›Ž´úóÇæ³NŽìV8-²°ÌÍ–f ‡®æòbÍÙmÒ‹~u»‰uz¦EÇ~ç¯+í\ÇEŒ$̫՗ñjd3XJu ‰b/½èùÖ¨ëo6ϱù¼©ÓÇô]ÔÕ™ù²“FoUŽæFf¸iµçà…À¾h” úîOœe¦p;3ËþJ-/s2Ëy“[©a*eüŠZ¦ÆÞ¦)±½~7UäãPûî¸&õ6Õ\(Ð~'rAB%{9›KãØ˜¹•Iñ�ér¶SÌuIåÍ8ÛdI<1]Ü2ñ|¯IüšÝLæ�óIÄÏ(vý|êF½ dXÈ  ž^>ÉzÖ0‡©<N9]qý«-^WG¹O‘‰ –WQ3S|”Þ U´½g%_<êÙD­ã£öØ”û%lç*š8ÊähŇY®b-XB*Þ;FKG1„a4†Ýõ·«»3™Nös€A"úhßÓCq]wl”»çG5ÆÅ7Šå ð?ØIYºã¿ùQžä(_a5ÏÐL?¡—SÂùìdiΠ‰•¼3s*wò"§0ÈÉÜ#ä{¸€‚ãœÓÙÉUÌŽµcßH8Pðá‚GÒþ%tc"¿œ•rÂWÚÏ*×ñ¿Èð7²?neíäi'L 4DždnäñÈTNŽ|‡Í,çhLÓÚ>ŠÒý¥`¾æ^³«ÕÛ¼QËN¥†+¸+²‘ËYÄæ¼Ëì[l\•#ã–‚ç"üòuû¡|*á¤Àþ¼[ Ö–‡žÎ;H•ÁgÌnÔX°q¿ú¿”\ÒUÿjüæK†4Gþy¹à¹‚ÚPsNoÎ>™Ð˜U\pqFmÁ¡¤Ê Cò)WG–NUè0¾ ?°<©9¯¯Lo©)yUƒ&NÑ~LE…²‚D¤¬¦ µÅŠ2ºR~0¹÷2/M»ilß·~ÿ¯ëJï:/µ´{àÅ É¿_PH63§£OßxØß æ˜ÖZÙ~“s³ÛÂlQò矇¶•˜Y­¼Ï±¥UƇÖê6)ãß‚Ÿ<5mí''yã ]»ô.–É“–æhânMU²3é7®LT¦"'(R:,5ß»[Ü•u>CÆG*ëÕ÷™ÐkR¨¦Ru£Î#¦ŸcG«{3®ÑßàHFu›IÕÆçU/´s·Y²Y³ìîõÅצí L­1ÒWh雘xÿ®à¥Ó£]#³·žÐupføäu“ *ÒV„§îî?}_´öæîÎïF®œy\åUÛ_ú/ƒ?~#ú¯ï;§4H-¯¹ëÛ¹ís³›W†^(ø}™Ù C‘÷|±Ìå%JFTFFØÅºÀ †B?/8·`]¨± >¥¬Ze¯ÆÈ¸ÐîHã³r”3•&&æô&¬H:©`[àŒJs$œ9h¨Æ= OËùí#¾Õ¨zŠO?î–l¸‘vž˜î¼~3óÖ„|€cLaÏÑÍ6-½Î[íþTå·mÈN¬´ô^¿h1ðO„±÷¶…}ÁM‰ÔÚóBß`gdÍ1|SR>êˆÁi7Äøæ3y…v&°›–°‡ÐÏŒšzY?à~œýôòjìjꉟñ·³1N‰WÂÈ ÑÄo™YÏṎ“Ì{b"Ô³<y«ù=ƒ¬ak|{òÞaÎb%SSF§³›%<ÏpŒ GG¬Ã=‹d {‡)qiç0ÕœƒÈϦ<ÎCžËßâÛçx‰«‰'rñ4rnÌš:1Vý~Œ-qr/Ç T±‰ éàRþDwx—qÂnÔ?È!¶Çó̿•­qX£Àt"N¯­=úÁk¯ÿ¿mWog2£µÖAªbÓG†‹c·q3sØECäÈ‹±%¯SöðÞàM:ˆád¦óU¾M:NaL`Oñ [ùSøs9‹ Ìã(Gy6ŒžÊ×¹|ƒm¬c K+ø%.g]¬¼¬&`+½¦)òEެ楘¢ÿLh÷Ðq@ûÞ²–…ü”Ó˜Éï9•v>y±Þ û >Í£LÓ°ÇK¸ýf2ÜÏË|(á¾”×C[ ÎáWšw˜½]ÿ^oü‡ÖQ@V]œÆS<È$¦1—‚·j\Õ ¯É¨K–¸©ÇG|ã¿Üóe ۣǧEJ ~ÇCGBãéëo 8óAµkì^&jµùm—½=ØqBÔöo >T°!òq*küvгúq0’LØyº„Ÿ (Ô'”°¥GQ֡СgC-i'…æd•lÎÛ:hæ8µy£àüHvÄ·“NȫϚP¤z¼ê#ý/f7Mxäûª†Îü§Á¯î<ëg§§w­z˘œCãLÉ»³ßÙS= %«>¯©Ï:{V'=³¾?—7>ïúËófVHvê L,ÒÒ¡3÷è¢™Ç ÿusÖ‚VSúÔ6êí2¼Ë»93zÍÏz¥ßÌPa–CÅmÊ'‘*QµÛ¤„ûRÆŽÕ6èãyW–*í×ГwSµ+ò’;Í©3—‰ ÒŠBc3þX)ßnvƆ:Õ‡”Q4"•´¨^j¶#J;¢‰Ò¢ÿøbª»jÜ› ëÃBù±I­Ž%52Ù)Ûr_üAâssƒþþ2Ÿ eÚꮟÍÜùHâÚV7žŒo'?\{Ò+écõÅuÂŽ±QÛ푲^®Q<ìÀt×èiQGé¤8%on¨«Éå}š j 7©)×ÑæçIWGŠ#sRPœvfhW²‡³C-±» Ùí­È…}ýnÈàpCÞ=º:Ô~³ÕûüøL¯oIGŸ ½Ã”>óòþgÁ…\Ìàk¬aˆùf°í¼TaVõû»[^Éeÿ#Ü‘ölNϽåV*ø8'n‰nz8\»„Ö”»#iägq9äÕÐdî$ënïdËcù\’¦X1—Ûx'å‹‘?ÐÊçù ÏðÖÆ.à«ùw±‚Åi¿ ýž.NázÞM»7ôSħ¸›Ùlæ\ÆRÏ ÓÂ5ÜÃÎfC<í“×cîßI|]\JsÀó4qñHŒÃÿ{’âKÜÁ^"ÆrïÐÎ^.ã~VƲ¨ø5çs!O°Œ­ä8…•l¤—$oó0“8…m¤ù&o³†-´ÓBIrq+`5Œðjü’=|ˆÛhŒ3ëqêbÒtÐÇ÷»iˆuÏ9>Éwy‡ÓâîZ’78Ì;µµ¼ö#ÿ·íjE&ó§øËœÏ_h¤;–TŽúg3Ä'Þ3µl¢?=­Œ~oÄûäßM5\Æ· ¸šx‹•<Éfn¢mñ¹ê5ngç1Ä|沘“¹Ù,à0%,ˆ<À�ÿÌÅ<ÆÎø¦jT?s=Cñþ8!aUäEf§|6ôÎ伯×fÎŽœš°½ØØ¼yl¥ˆwø ;¸Ÿ ÙÊŽ!Û ¾@' {ƒ›^Q»ÇÇp!Y*KŒ¯wI¿NÖ3GÕW³ËƒµeÑÎÑ”Înåt&¬ˆ<ÌXçÕÀòDøÙhJkªaYðî´Äua.鯳´|×áómhvd9î£7¡+¥ï3E¸À ]®{\}iPU”H,^ëôî¹Ô'Ý”´„|¤;°*ky»_åŒI[Qk¨ ¬t^èÄ:sý>e¤Ö’ù‹Mp8/Çy «'x&P™’NÉÙ˜5gÈH©¾„ù?Öú÷>Õ#v&¥[aÇê-“+ê÷ëÒÅ'fuwÝtdpo‘Å3凥9«¸x¤û‚/TÌ>ÅðØ‰½‡”Ö„ÉŠÂÞÇhšïäaѰ#ƒj4lž"ÊHdæmKtŽ~p_ÎécõìÞfÑŠZ™Ù‚^5UÆ$ìï—ï0«SC©ö:[M©õÄ}“ŠÕ•Êv:2Á¹Çt¦ŒOØ6I®Ï”)Ê#%=Jº\5âÚ¬l™Î”¡9¶”9}ȹÕÊ{l-QZmLŠ”ÝY¿-2£Qù;Òõ”Ûd‹vìImJwö´·y©ËI=ãì+ÕÜÿßg”]\,)œ;±??±r_÷yŠ®xiø£𸉝u÷¬ÖУwn}õ3CŸZï×+l}øÐ£©áŸ„Zé2¯à¾¼ÆVaJ&ïpÊì2S³ö+§¹Ly‰®¬ ‘µv1¡RCÖ::B™”– ¹ùHEBUhaÂùÜ/F#,âph(R¸,¡6¼ã×¾~D˹®Pq øÕÅ¢kCyæ0=é”P'ÕIõ Ó"ù”'êœ0¤?ПÐE#áŽç†/hÏ÷F;gFÑ chà¿b3܆Sj› Ö–ºB~Â%$C,`I†YÅ^¦òa ü’JF˜K7ÏñXœPXz>¦Í¾Ê:¦ñ,M,g/UœH5l¸žûØÇ:&†~³nÏçbå5®âö‘&9:0ä—¼?޳äÄÀ¦@]ÜG…DôÄ‚ãÑâÊËle&l¡‚vSÃ4ö1È6æÄ`ÙËx7†þôò '0ä˜F3ÝÜÉ%, ͶX—\Åil6:Œ1†Ã4s·XÈù Ÿç.V3–ï¹Ó:•Dœ^¹q÷àcûâß9´7ÒÃ;Œ¶tºé`{üú !N£ìâúxêX¨­­ùÃÀ—3™ ®Œí 8†…tÄmäs9ÊÆs€yT± ¶aކ/ß Þ_È2ÙÏÑž´Œû˜Ç..ä—4q.í4PN5mq˜ÆÄq ǃ4q*ïPJ ÏÞ&,Ž'Ý«ÙB™f3%~|ØDmÒ ¡¦È:zYJÓhäy‹'ˆ" 4ò㤅%fŒ˜G2é‘§™Í3±Êú>®à}<Îo˜“Paý-þØK ÛXN’ûó®í÷:«haº¶™Qæõ¨„#gòm"š)åì„'#‡9-µ‹Ìµù”ð„gµúrÇ¿ñ€6Z²)P’xsAä™8õÑH}RS¤‡Äè´¶êÙër—ü0š·1ZØåHÊ‘mç’þ5çáÈ·9\cUÆ/æ$,©ÐÞ)‘W™´)PÛc?Ÿ+1oDÿ^öº F&eïÍÊKÜÄÂ*½¼5ì'ÉUº4k\ä¢~‘' õ…JóNNëKKµë™äQòÍ¡ë~]´ÕÈΩ)E¥‹ßjÿØÓ¹ÕWž²+1½©|òŽü‚½»ÆÔô7ùq…Mæ–™<ßîn¯÷øNÒÊG³ÊènU=»¬îÁ8£Òàt- Š[ÔÔÈçå‚rÇ’ú"SKdÿÅš²:ŽøW–ì° £0¨.kC•IæŽ×V£¼×ØŒ'Š­èUš“$˜hòdûzÕeŒìTÝafF²GY(5KUFÙ ²Z¥ýÆ×ZQl0%±»FI¸Xÿ?^ó‡¢C >Çö”$ ŒÜ;Éþ ƒ Ÿë]´«ë”ÝÁÊ-=̓ٿ˜¸õË“;™IwB3ƒCÛ«3Kºþû{ÙâqÉ·¿^è•×4$ôsZá¼Öbù¼éïԘ؟”mLšÕ¯4íá™nïT›óf %á‚‚õ¡1#ºC;ê ‚„Í)+L™¨O˜©>î¯ñj¤É]^\ªýënPûpòÅòèø)¼-²!4•,ì‹ì£)íèX-Ýr ×¥œ]ðgÞrÖóÉ–ÿLìì U²ƒ—y—‹þ#r/„ö»ik°¶!ð³#ЙôQ^‰æ¦2‹Ó«LÈÙÙßK9BsÌXÄc3‰1\Á~Æ\>¯Ý£%–ûiàË¡‹¥<È>VƤðnf2›w˜LŽf621–ü¾Î&ZÙû«ÞÏf^Ì TGª9JãØðjmƒÌ ÍßbîíÔ8ÂwuñŽ2ê…º¼Íù1|uM|uP…ÌàÅø¼±œçhãJvQÃ$ösG(¦Fg„Z^b/ûéâ\ê¨e7e6s˜É;l'ŒËd£[À© ÒDIjØÞÞ«E\FC\Ë¡¸d–ç Éþãšð¯2™íñ!)Œë£ÐªMdâç§y’â¸ûv.ÛchDZ÷|7å\ Ú9)ŽðWÓž°†•<›òÑðx¼gmLOØ)â}¬¢Àó¬¦b^d-ŒåìHgÊu¡Û)ç0OñÅÀ΄9‘¸†mqõ:h‹<Í‹ÌæM2!8^›Ì¾ÑÈbàC‘sBÛGlJ¸Œ‡˜â%fp5Kù K8s(&G®Åýñ$eÌ캘ï2‘6^¥Õ¡È‘q¼X4=’`+ÏGÇGÉ/%]£¸Ü×òṲ̈A[ÚÂÊ?¸çdð‰·”Ü|ÿ`rëÕ¡·“f33åìP†êÈ},¦™>ÒIÑ‹W﬈Z+lZÊý\œHËØ—ÒœõI%-Íl+ØŸWj-öx‘®ÿÉâÐc¡‹"rúŠÍª×ØêGCj†MH¹(ôݼ‰CóŠ#ɤŠP*©™&5íº2JŒ©T7à–ζWMïN|èðägVûù­½S†r;K=Ó3m}U?¹¨þ™ 9:òÙMž9'*”'-í4c,Uv¼io`yhò€cãÔ猯q,2!o_hZÎHŸú>©R‰!õ²½J"Å“íÞ¡»Hù ¶bE½úÚ5ô«œ¨*§fPeAw…ÚPw±ICŽælê’ 5÷;¡ß¶O k*rN£Î‚d«†¤Iy“úËÖ<‘ùßß ®X®Þà‰5½Š:Õçü P›• eÓÚÚø»ÌÒ£‰o}©hþ‚É‘IÓõÑ]¤²WIÁúÚŽó2ÏœVÈ¥Cogö¯Š~¾*Ü_=QϰÊ~?â*2õJ2V I,۾ϟH'ô…ö°2cÚˆ©ÃîˆT…¦gÝh’ ý$éŒaÇrfæ$ž4¾ cȱБ¥Ö´ ";B#üЇC³#[9¹%°„Ýlå9Þ ¼ÂØäïä_<SñZ—v'þü‘èXIÊiÑqžl³h`jä!²)—Öª>ì®H˜Ùy’n_‰.Ýnù©ÁJ†)âX`RÊšÐæF7=hmwdÛÉP¹Ú¸[Æ\v&µçœÀO™ÊEô³•1¼JŸãa‡Óx•×8Æiqz{ôºë’<ÉÎØº;™‹bG{%ý¼ÅNŠ/ºZËær>sx,X=ÏEìãŸ9•ûFÑ9Ññ÷†h‹É/sEìg[ &¿˜cŒgYú8L) ˜À0å\Ϋü…‹hc > ¶±Ÿ ìå²—m` Ý\ÊÓâóÌd(Füdhö;b|TŽ260–á˜sX«kûÿ_WqÕ1ŒãÞ¦‰Af¾':÷wùÆæ8ô8zä‰Ckh¯­õÞí*õáSlg˜¯Æ0ÄQ´û»¬¦›ÿÍÿämîù8;)f÷ÇI÷·1‰[ÙÏRÖòïl‰¼)á}·³7þºKø~dEä2~Ë^¾g; ó~kQ†ø2{éçãckxh•Y·¯Ö’Ž¥o‡ÂÀw“:ó~Ìp ›tvÞó”ó )f’ ÜA7Žü12#ÒÇÓL¦˜;ù ׃/²'ùs|¦ù‡ù$·rbÚýyI÷çý‚Õü_e)9ÞŒ¬ =Oó+’ÌæµP6zè«÷¿~cMäu ²Ç‡ë•.šxÇå­ùtÁO"ƒ¡q‘¤Õ›Ùá‚ù gÍÔ¶ËÂÀ!GÅÚ´•ò4mÔ‡¾ÅǘˢjUn‰ü"2fÀ- _NZÊ’qr]d=RðŸeEä¼ÀÅE.t°Õ¾jó|¾Ã³¡ö‚…iŸ-‘ ì’J)™¨½×†^9©Õ¦ :rÄ‘”9-ž«uRÙ|ô”ïyôf×~¶ªë¬°¥¥Ì˜nïïòL¯-E¯.î\üésã.»½UÙGfÚ{ÀŒ‚ÞÀ˜”Æ‚Î. ÓFJÕg$H|®Æ­Íöö©8¬aXP!©È¨z×$ªY¨{¯ÎÈòHºÑȰ‰%šÆªªg¿¢f³vÚ›²¢^Ø#Ùîc‹}½ÏøRËKt÷J¾«…¦›2îR·&xþÇ…'ºÜzmèüö±Á›Žz}"{+ý3¹²ÏýbÿëÒÿtÛ¬ý…={Þ×+* ž¿øð®ÒàWåuåGïõå¼¶hýï­ß8Þç‹:D‘t‘¯…¶æ½Ô딤³ mÇ’_úî”pOJv·Þj¿*wM‹“Tñfd˜e‘ßО÷™È<ú)°/P>EºÓ¸>O•y¢Ö”nOQ¹%çNå×,‰\›P¸:¼VâÑ2ìTŸ–¡¬–P ª/1éŽhÛi‘è8§` ó™Àçª|¬Þä£nêq·“MÈf\L}òÆhúãaùm¼Ä¦ÑË­È›yû¸/Äw9Õœ÷mÙÌc<JýT“òîˆÍëw³‘kÙã§Ç2P.—öËžã?ù_f©ãüÀ ÜÎjc`ÍŠ!q÷3ðÿvŸaV•÷÷?kï=½7˜zïˆ€Š bMìÆ–˜˜SOº'9©æœ˜rÒOô$&Q’Ø[lØ Š (½w†é{ÏÌÞ{­çŰrqžó<9ëoölæ‚ë¾×ý¿¿ï÷v±‘Rñ)ÆÄ¼ãxŠ¿'Ëylc?Ÿ`UÿÆÏ'âìô+œÍÔøÌ”âzs"do‘a¹€ÑüŒ. ¸”¯pScЀ¯dàyû˜g@ÉQÏ"^ã/\ï顓ó ¼I%n\¯ä#Éò*©¸ð»„nÞ>湙ۙŅàg bBÜW{ÎcÚºƒ¸™—x-þàÛÿkz"V6ÿÿ D^Éd21 °?þéýd¹%V3”]<ý?ç«â7ŽÉéÀ¦2oóß ŸiY�� �IDATü…§Ï9ÜDÀ%ü‘A,å NæÊØÊš™Í½Üëè»ÿÀ9oW`B2ˆâXÏä¸ûµŒóÈr[)àSñä÷ 4†6%=X9?ô ?­71o~þhšetÊ'"Kù)û8™&"N`r€7¹‘9qPg ž´µÌ§€ |“†Ð:²¡G¹™m|ƒ<ëù´QuvþLÙF+Wë;˜ÈHæ’÷¯8ç[Þ¸AWë)wÆ…ÁSßÿaovRΗK(‡•ëÿx>7½ÇÑÑzÝw;]IA¨”Ã|›é-4-²`ˆÓÒ††î¢˜Ö.Ïñ8•ô%œ>Ì”N¥*•íU”÷I‹G¨î—ËiN:¿ßCyû¨hw\¿šœTʼÈgJ|´Dk»_„¾ŸSÑæ·•.*6µG>al¤d°CC›†"³Š,êë.ËÜ=a¢íàütׯ>éÖ•0¤Àˆ>‰~õaÛOSïœÝöðÃgNmïiØ:¶ûHs>U49ìLͲ·]udp·LÆíÃejõŽTºÛ݇œÕ¨¿ÒáRoÐ]+1ö=¦ŒT2D×vÿU¯MtæV}¡}3õ¯Uµ__ZºÇÖ~;ÊM+•ì2üdÃVŸWÖ­{б:TŒ´ogÓðâ?¼XxãËåón­}þ+-'5·TôlïLÞqCpÇiÍwÜÔ·ð¶û}÷g–½1»òS¿êØÖÜÖ64«‡ÇŠîüAîä}ÑgîìO¾›ëNGž\ùe­é ;úíír&ÿÎÄF¥Ý>žsYÊ ÉéˆlN™KïjÏTf :ÞûLHÊç4§ Õ¤t†/rmäå”_ç<x“KcïòV‡9ý®/p}ŸW{]ÄîÀ\ªy› —¸&ôéH:rRhg¹ï¥­ìµŠ7è+pK虼Úpîóîü“g†«{ÙóR®l–ì<z“”ãÏåþÞï³}uW¶ßöpî§ä/{ÈÊ× z/ìûj¾o`à_IGo.±ïiùÍœPçBÎÈy"¦Æ4ð wü–+˜ÈÕqÆ*Í\ÄWy4ÐD¯ÓBÝÌŠÓË“âžSß˺¯×X¶Ç äò˜^ñ –¾Îzfqw0‡¹‘¡l¥‚÷ãJÓ8þ³Û—°Œ­\È]\Ê(þëÿ›µ´’ã c§É ¶�/ó 9æRÉSÔó, œÇßâæò@í#¼Ï~†±…I<ÄÅ á/´°™JÒDz3gs)5¤iå5ž'Ã7y4^çWÒGip&«âxÝÀ¬ràdP ³¸9ÖÁ×ò&!ûYó ÷RO)½ä9?>vïàz~G ý¬á6PO2ÿ•Ì×ÔL¸òÚ+þÿ†¯f2#9@}êØB/Ä%êÿ-°…EL Gš‹8žõ,&ä\dÙ4ЫåUv𮣯Ëcêb"¶ËŒd;gq%d)L¸šI¤¹€MäøÏÒÎ+ìdW°.Ök%8³xŸ÷x‹¸*²>²›÷x—Ó¶å­ão4ÓÆP¢›µ¼ÎHþÈûÌä Yêi§#ŽK ø«ö±•|ƒ Þãæ°< ›˜XO)PxòÑzŠtÙî)÷… S²~v§ÝY+2—…FïNL¨ˆž™A{èÍÈ Ñä5oµìl-Ådcœ¤aYÿŸ42òÞg:+äŒ>âÁPQ`V žrÞad`T 8aHR&c]†äììNŠuiC¯2¹JM§,-urî›Cm‘d^SßѦú,NIº6PU¢8iKŸªH«.WI6iªTÑ£¸×ð6ÃCÛÖ®-7»ß/ë¤øIVY†Ô´_µ$qæÛ© dÐ5(8ûùô¤—ŠöŽÉš›vW™¨Äü!’‡ü±ÅÊŸR]¢·Ö–½ÞͨNêì5ù°þP¦[y‘“\dB—A}FNeµ†*kz TŒ–»?éÄ^UJv*dU©®È¨±º²i•=J{~øËA÷•6|÷¶^ãªìTÙ@²LP¨×ý³³·_^zûÕ­+›GékWØo{BSÒü¦ÇO'ÿƒ$¶-H¬®¤¹À%N/PÕíC‘æBsËÌïó~!ýä=Äþ@y½|èHÞS•Â6ôem)QŸ–ˆÜúk‘K&šÒa}±3r2Lˆ4§ Iš™è-u°OÛÙ›Nª¦-°00#¯5p~Âö²e¼‹ØUì¼Ù¥Îê³—º"‰ç…UÝFµ_¿"Ð:Ü©‚{x—_sÕxŸk¼Ç'ŸöÂ¾Þæ™vÿÑêÔ”¦b\¦ï1~ÆJ‹7Zök탙›ñdhBäS9ÈA†ð\`}`%ËháœØüô ŒHøzäbÖÑÊ |8&;Ç1ghã¹=0¯‰{8ÿ@²NKÈê#‰_L·³œ†ò}B汊3cÈÐ6ng3ÿÊHðïÓÄ7x†hãÐKs ôµ „õã¿C–›¸‹xša¼O‚y¼÷y³¬æT>ËrB^¯±‡ò¸ õ]Öĺ©qôüË<'ìk ýG±ÃYƒcÀ™ìã@ܵí¢}Àº ¨Zi`o|OVÁØx”5”ÓâvÓ?žE¬gûc…ã ¼‡DzÂ$6“g%sãÕ¾ˆ¹ÿÀÒÖÔ\}åµsÿÉvÕL"žožÁö¸„¼<&ÿŸ·SâDÃ.Ò죞VFÇƒË ôpGxï%”Fvħ΂ø½à º©` ÍŒ …¡ñ ö§¬Ž:ÓRô1ˆ?°;þàBêc†Ó&Úi¥ž±äªib8㦕r&RͬûÎe Oò{6æ'ŒŒ<F'·°5~yi£€7heO%}/:Êóÿ4ÐH»kï´{¶Þ|ˆï%|,¡›åÑ@ð½§GÑ…F4»û“´…Æ1†Nê<¼ûãxާ_ôl4a[Ô32Üw˜1&îõ»—Ò¦ Å#Èr(Ð÷…À˜”ÉÁ¡±´8RjÄÉœ&¶Ú“ÎO©gN  á”È»‘=¢È“‘w’TDw‘饞ÉèÍ›šÓÙ/ŸUÌ›Yãº,Kº"¡¼Éê´“²ž|ˆ ‰À¡J{*´…F¥ÕôjHèikF{¤¡OXîH§ŽPôZàº@e‘|¯M¡ÓKœÜç¸À+aÏŒìë'„Õï„5ë~¶Ðâ›Òõ}…ßY\¸|vÝá…)¹~GÚ…Ct—;9”mÑÓ ¥WCÎ_Ë|ô°YãªL«HØÞ¥¦Áý½&Ž–Û!“TšTÖ£ga}¶æìí7f¼Éy¥­* uõ{³ÁŒ"5‘|- ‡Ô§f¯M ÛÛòrm[û¢o³1Ò8JG§åEò SØYlL¿ÂB¿îW™V—58PÇŽ@¢Ê®ç§î*­úë¥Nf{NaNeZ6Ò¹ˆIy=;{­ˆ ¬*2ºPgÖw#ÊzjˆÆ„’ÃF7h.Wq@cJ]΃‘»¸³ÖäÈ£sÛC›y:4ƒ]¡§"#JMê;êר(L q°Ö΄ÑY–&E2ImmI[ ¿ÏêRóû¤½Pe…|ÿó»Ã翨l‰üœ]3fNl)ãK?ôf£Ï¢TÏ ¾Ðçv8}}ò‰‘g—H¶XºEïJNåÄ@kä"jya<”t_Âú"c;x•ÉD\D6ò8{Y˧¹œßð.©‰w‚÷bƒy-¼}Œ¨bWóóÈÒÈ«\Ì!ŽãFq9ƒ8Â|æà‹$Î+ÌHšÙÏò8U1“=Ô‘ã‹<O-;8¯r ˜Óž:™ÂÁ8×þaúI±=>ètÐÀӜ̦Ðg­[9)ñv5›étÅ·>­ì‰O*—ÓÏ_à"ÓZ([`aŸ:öó(ûxyqÐü:öÒÊ!&²ŒÉ\k«0‚F63”™,ã5LŠi§®ìãþ§ƒq ~¹>ÞeÚ™÷”²÷ÑeMÍþµx)“ÙÄ4êÙN!­$é#Ã.äAç:†Æ(žNî¥?ÞZ·ð^bYü.³‹³yJ>ÄLVüÏo<BÄl61œB>ÂßYë†72ƒÕys\Ìþ0¯2ƒýLÛÝÌd:8H5¯s&O³) áa*8Â(–Æ%ÕG~È ìâ{ÁQ<ÉÁÀªA®ëñ�ƒ™ÇGÇÞØLLcªL:‰JþÄv×¾ï§{Ì-uïP^æ=&E Øz–™K¹Ž6Ÿêð³ñ<z•Ìîõ^ž€x„eÚo5c—ºÅVŽeª“4ö€oò¹]~9—7’®Œ bz™#ìhq¤Þ”>$ÝPjXBGV;ãu‘žHAd¿ œÙ)Ž4rIc&ðpBsúN»ºìË;“Ûòù9w¦\94,Ô3Lº×¼¼X/Uk|…\hèAµ]J"ÿÙ\ifÞ–v?da«ºé*½ý~ΙŪ ÜÝeGJÛXCwÉE2¡9§—)¬z­~ÂkMÒ'Uêëh«È²-¿·.ÚØ5Hñ.•zÉ$…%ò¬ŸäÕCfHï2"gCRMâ~©%]J†ÚÕfLZiZeBQ¿Tßâïu|쉰¼5·r×`ƒw],È0ܾnuy•”µ*;¤pŒîMuŸ÷ZoX”öÓ¡ ¡0!_kÿÑåŒH]tùºÑõûÚvNMª*RœqB¿ÂÈÖÈÎPW•Ú©ºvgë ÖÎ.SÕewî'Oæ?÷ç`LkòµÓCùÈÔbÛŠ5t« FShÏ{µÖ½&‡ªËÌ4öèèt¨WAhä0-ý*ú IZØ/×A½¦^?«û 4/¥\™· 4õU?L`CB=‹RF6óç&Ã{<œWÉó|`c¤9ÔÐo3g÷ùÇ–‡óÍy5ÒÉÔH=gPÎ|"^b”ß,öðKO¢‰7ØM5—Ù1È7—¿¼:°'ø„hÅ»VŸÄJª)à¡xò‡ï‡6GF³™#Œfm¬æ® A%飉UTÐÆ¥,åø8>à„ìaŸ¦”uŠ N¢…¯0‘–Í~×p {™_–¯b©d)ç6D:x—MD$bFÁSŒä Ʊ…‹yŸ$a^ßM’SÙIÈ™¬d%POä Ètp2³Œ³XÎfvò>qÏrop [ÙÌTm'°ž<g“dçäüWŸÍ¬ŒINßXÂN2æ› ›rgòf<Öëð‡‘ˆÂWÅÉÀY±ilàÏeìú_¾à4WÐÀaÒ1$hg²þ1ñÿaz%“é[f¹Xû8Ú8Ñ‘%M’è˜Áå±O!×óï\ÌHvò|à[) =p÷ÒÆF¶ðQžŠmʇ÷,%Ý fp'óie>¯0›Óid#x/Nô_ă´pnÌŸ˜z?¸&¥2t³™Äñ”0„)Œeÿ“|À%ñTìÙ:‡r&ðÙ>ËB{8›Sù5U,á�ý\ÏŸYÅ+‘s™@…+—yôJ<Åá¦Xˆ¼1ðJÒ­¡nîäU6éN:|/ð$çÇàËßòc/[ã�}-›­Ké}1òDòs;¢o\™Z÷ûèñW´^@ ¯FžäÃ9£Ò&f¥{­ ɛԫ7ç¸ñJÛ4FF$ a[¤nˆ±6p ü9anRG 32¾£{”Õ;9§!of¥Ò*K»¤#õ)'äŽ<–Më'jSXÖkxÚÒF÷HMu¤W²ÞØNY#»ÔçÔmM™–*ÆæŒo2¼SqŸžÈïšÝ¼WKÞß"§Rٖן5½U:íߺ]võ/^Öÿù?Ô®›‘92f´ßîrà‡÷[pXCžƒEÍݽ­ëå)ý™‰õêë-–-V›“+Q—Ö\šèèºêÅèÞÏf?³Ø¸ ÑÕŸ7µ8½«{Ý‚lôÅ"óŽX[¤,mÿÙvíÓWeWBý»úOlÉ/|-ÿóOô5R¡ë/Uªn÷Fà†:%û º÷ÎéïßÔ¨¥Õ“‘³Å…† ÓŸ’ìVjhwKè².od¿÷§ð_õ çoNÜ—Í;”ÔÛíHÆ+9{ÆDör|D`|èTêBu½Ú»¼êà·y7JºlË;n°¨ÓóN IÛ]cÆïä bQdSÂ÷#í<Ëïx›ÙÌåÐð”º¼Þ —÷›Ù#ù >7Øé¡(ÐÀØå8áÜÀäȼÐäBÏLvU…‘=N‹dšäº,ã2wÞå·'x·ˆÛyžR>Óàž‚^ñÀöhÙ+Ñdúʃ›m>È%G‘c^`--ÜÀ NŽÔòÓYXM†…4³…ÇÙÈ),ãj*ù 'SÆjÎaH|ßã<ž¤;îý€#¼ËU<Â>J9ÀF³Qü”Å<Ë2V±,æ3½JÈv&E^fïR@- XÃtò#3‘KÃû̉O!ÿÂøÀ4‡ ØÃAÎá5–³ƒƒ´ÇÚnÓR:ÙM²›ëbü`ïPÁÕdØ_àÑÐ1±p;ÝœËãŒa%+8“—ó*-Läevà'ü%>“ÔóIiL¤êcpÆ€G÷i:ÙÁa>äøDÿs›ÈÄëv -t³9œÌ«äâ­ýÿØ®^Ídæ0&ÎP|<–êN§‡.Ær23¨áÿ;P˜ôöp+³ŠsØKsx4³8€?ÿ÷SN/}|ƒ¿r*9n#ËFþ5ÌçqFÑÃ'y‚…l`5q2‹¹3˜C7ÑE+kA1'³,ô(W³–óø>Õ”ò#Žc6ß`&_'ÅC<ÍB*XE1ibIh£xœ»ŠÜœ÷CÁoã¬Ñ€pòwGÛÍã“òÏúÔ>ìaEÌaXh ´r ÿ1p¥—òýÈi´syÒ%5ɧ9´…ÖðY•oùÔcÊ¦ÛøÕÒ®=ǵž»ï·Ã[ï5¸cAÒÂÈBŠCçäY—¡˜/GšR:ˇ>ÅY {x:’î÷£PGà'Ìå#Iƒ«T–ÚgFdXÂÆf‰Ý~7²H.mb§WgÎJéÎéaTè¾Í-ª“F‡æåõf4±Çð÷ØYeA‰ú2/u©¦9Ò“QŸÖœ—êÔZ“0¬ÒqŽ+‘­wb¯Œ´§ìªñ7.IšÒeVFŸÞ¹ôs=·¼W[+}¬[qèõ\ãâÜâGR?½5wÛÃ÷ž×:%©l§Ý ‡Ú_#ßæj»ç|*¸t_pýÆê_]Ý×66¹|\â‹od2Ñêsz£ÔP¥OÐñ¸)Yw sj·Â!e…‡W_,’zaz½Ònk™2Ø×²~Ÿqk³Ú¤âÞÞÒ°¿*TÝå_ª4ÖšR¦(%lõ•.Ç…¢#ÂRÍXÙPòÊ ÑèltÉÕ«æŽþÜœÑStVÒ/ÉΑf¦Ý‘WY¡¼ZºÇ¿gM«´¹Ds¯ç"eÍ®î´#²4/•÷‹.IM8y?¯°Ó«‘’„"é”{Fú÷6c‹m‰|!2ŒS¸c€™Ø`\Ò‡|&rg¥\ž2­Ó­¡‘Å^¯t]F)ß`P䗑á¯R—÷ÃkÚ¬Ïk‰„]îäRmn´éiáEäh⃰hKÏì?¹þu“.ñÖo<YéóË«Ÿ;+ñ`]ÖjÚ¹ÂÑÄüwYÁž`7§’ç~2ÍþÖ¥,ð“ÀVvÒÀÙÉ<Í ÔóQf1†gø6ݱlèiÊ)¥ƒR~—jVÓC= ØÂú¸!ZÂaæp='²‹~H’»ieid—G]õëxÍñàn!o18&KÁeüŽ2>Í©tñ¥8ì°ž›YB!”óu‹¥Ž•\Å^’¼G9Ãx‚Õ±aë:þÊ. ýœ»ÙÄ©ìæž§Ÿ·9‹¥¬‰ç;8/òäØÀGØH×ò'rÒIŠcîGyƒ›)æï<}Ì%Ü@wxﳚ’X5ò§™šã«¬ÐQ ß ¢šãââÿ|»z3“ù<?è?¸î[â‹»#²3鋱bó…ÈÛŒdYGïãpLžÝÅñÔ0C¤9•w¨d7ûbçÈ ú9ÄEü•³¨iöÇ3-¦•œÄ^¦†VN¡„¸‡Mìg¿¤‚ÇÃ*XŸýDΧÄüÙ¼ÎÌ8̺ ØÏyœÁz¶pƒj,ê;: 覩BEÿÑÐàXÎ<úoðîaßëð•«í߈<È&±žÿfHÂÞa.ûé m"Ãü"Fö¤®:'¼ðÒEvÝÀ©Üoþ½f÷«ÃìÌúÖ¾])wjkH}ïwQ×¶ÀƼûIQ¨Nø2/E†ÓÈ“”W’÷d¨žñ‘ÆÔ¸<c‰rö…oDwi Õ$½™1¿ã(åzÁLU•F$Ÿ«R6ˆÖ¤êjCÓîŠ <]ny—S›l)3·C¢Ï„”—;<—pF¨3¥*tˆL^Q • 3òŒTÒ.(ô«v»’25šû\SéC= û¥óŽ$µ×h¼ž× Í¥Fï^¤v> ê›oõózƒö÷\žzøùÏ/?Ü6¼zßBµ­ö$å›% Í S].m,۔ʮ>¥Ka‘I›B/$jgoûyêÀI…k&D2]ÖUÚ{Èq½êŠ "±çª·£‘{’ý,mݪ¹žœÆ>o”™Ýadþ~ïeìˆä’¾Ò+z:ã`*.ÌX›PDw¥ý½ˆÔ–™œ{¼Í{êž¿=c_‹¶=^l²¨HgFÔnPÞÂÝUË…‘E}êËÔ¶;¡ˆ'»TPÁYìåʤwÊó^IêŠtÚ ‘Õåõùx·5¥¶V¸ ëPÎKœ¨ ìªpmÞ¬¤Î#&E‘å’ùÆ7¢C'òÝœÿÎXûy¯N8퇮b­¼Ä¦±ŸZóžpÏÝg<Yå¢#œï¼±– uî &ôx´ÕŸë}oVV …|‘:F°0Î:mæ¾È¦¯úqN]—ýDk#¥ 5µµ´0’Tp(²PÉ–3›±Ôs†“£‹¢x­üב£€<'²‡Ÿr'+·bÛc‚Ï�K¡™zžH™º#.º ¼:ç¨ Šm´âXÄÔ8Ïœg8ÿ~LНРa6cN‰<F3\Á~ö1Ÿ%q[ëÞÅ3ºCñ°j%ÙÄWâ®&Œ—Ó-ñêcÖ1xøqjå ¥¡”a쥚] f||üÇùi4µÌc''qo1†bŠ˜È6Æ`?qµ«‡ÃœÎÛÿ¨6ýóíêåLf Åñ»ÿÿçÓB;o2AÔŠc‹“âç0ºiflÌleYfÒï|;覑\ÅíœÉp¶&[^QHÿEH£céõÀl°+¡2°=2š|„Eñyv0§r"^â 'QÊV¾ÅÎqÕ^7îðÒ;òc˜Ä8Bž‹ tYæ3¨Ä´BÛ³v¦o]›øÐ>‹RÑ¢^‹öŸë{ucÁ2æPÏf={­9èûRdeLg8!Bÿ§ÓÅÏùKiçÔðÞ»Ýô%—ô ºí ULòч=Ùhçl. <œô…H•õa׸¤Ò¼CÌàF¶:CP›rq¦ꬴ0mAR:˜4„ÒŒÊ’Þ M Iº»À¸œa‘Á¡»KÅ‘SˆªÝY­¹Me¥†~+{E*³Ê"?ê5Éeæ¥$²N(ñ~ÒürÊv÷罓u^Âæ¤¡ÔätÐÙCO½Ú‰è(¾lx¯»K\–U˜QhSÆ3Eþ%gTäWM†õš[ftÞØ¼ñÑk'æ¯~ìðì_8dÛüžÖ¢hΉóÓ•Ÿ¹%·)!©Ü:£÷²×R]Ú_7-Ò[¤¬À¶ž’'zú|Áç?”Ž¢ñ ®BóÒ«çÕìnNûùÿúT¡tïõ¿[ÃÊÂEïå½™^´.»èõ¾¯þ&úÎe>81Ò êŸvRÁT% ­Tѧ8gtŸrCý‘µv ³s‡!†f$#‰uíîâK‘ö"59¿ŽœÄ´Hc­ª´÷ræy¹×ÍÔGÚJ4–(o!­'§¢OK`[è9æ$UVÙ¯žŸRXà³yýa5†öÎ/u¤W®ÈجΤ†"3x*{ôÆ÷`উ2zõ' LŠ4±8¼ãèÂe–ÍÐúfÒç#ÛY‘t>;Ê]]®:c2[âéP”ÔLŽ•D¾ºÄ®Qžª‘ï´-¾ô¬":fûÁ6ŒÐ“të_ýçjÚHÅîùže7˘Ï=ÌäO±:iOÒ¨œù3UŒŒŽ–/_çÃlb+SèçÀ@–Æp7ð­|ž×Î9Œå8²Ít²–ÉìâH<ž:!žß œ·ãŽði´p=#8Ÿ ý•ùœF]TSÌÖÄ†Ž…ŽŠÅ÷rˆÁ¼xLôcÀ?à¹ÌÖ„ÖÈûŒf2KMí¯¥Šw(á<ºãTöðx²÷e6py ºk×íšZWq)ØIÃé 9–¤¤YÍ0Nc3%Œ`mô³#fìýãÿÏt²(Þürðï‘&ÃnvrˆzúÉóm~L…ÇäÏ«ãüáÆcâ}55Eÿ<j±5¾eéõ<½œÿçØÃ•±×ãÐÀ&™Py$v Ü¡ Թ氅´°‡.¶Ç̪xœ·ã|Èh^¡… óiçJ–pÛN6ÞíÊøK¼Ù¼Äú¤kx„µT0Œdø||:‰z~žø†Ï¬õã[dCv$fOÒH†™,æe†…Ÿþh‰Gûà ‰MÕ5›šò›f¦7õØ=ÀÃÄPÎànB›6éë,ç]šYÉ#¤ ²œ>zØÇÅ ãµFŸI›¢[ßô·[¼[oË:zuö©þ…/¹u ŠóBçíf›ÉfÊ;’†G’‘lä6¶²7åʼ»#c"…9crª"Oh \Ú[฼3³ušúý$oV¨¬Ò¾È½‘éC©Ô”ö;ÔåĬþŒÚÈÎÀÔ©FýGô$ÍŒL mŒ´„’¡ò^ïf½žQÖîù ÷™÷b»èY3�� �IDATÎyÕ)£ó¾ZjöqŠsª»íav¨ I”WУ$mJµÚE‡ý´ÀΉ.èÓÞczhFΨ.K½šðD6œ[üæékFdÎz/üä}Ñs—•|öµº[®/Ø0®ß¾©z»ÛFÙYyèæÇ«7Ìékï¬44¡„Ôßÿ,ûýôîÛߤ#ç™#žÌ;-Мõ›AÌíüÞ=Ñ9Ë¢ëÿíX”cxߦû£MWç6 ­Ü4¸ÿ+žZ–mâžÈ¬¬%¡÷B‡rÆå”÷«ÊÙ™ñNãPÂÉyu) íŽÌLhŽ”çìKšC#s ]P$_å#>]×çúPg±I}6Г75£¾L6gd¢ûEÏhŽ´FäéFWöȆzBrþz3´0oV¿ÎÈÆ¼ÇúÌ«•Ì{(ï}$l ¼’3=ô}fFº£jçÄ.ó_öãin^éÕ¹zG 9I òj³ÑEa¼„­ ÌdjœE»ýý’ÞMË£™%îþ“ ×øÏó‚å¤Ü*¶¥Ôë£ìʦ°¢Ñ9ÝŽc Ï0žåñ`p<3¹=Ô–³*¶JøI 9RÄLrÜÍÎ{T[c€Î©<@1£hcg£†ìâ±¶Ÿ ¨¤ŽG8—çÙÅiæMóXhCU±f·…bpâŽ×€­c/Çó*[YŸŸ2ú¸’N^¢•«cÂêy\3–&ÒyL!b]:#v¬_Ìröp:‡¹)¶[¼Ã>ª¹ˆãâðúþXXÜKy|gßËözØNšëYÍ4šØÈŲ‚´ÅZs¨àpŒjÏöp"eœÓ;éâ4f²„vzØÉ¸Å5ð4ñIÚŽ‰õL»kjÊÿyÔbà÷éåz¶“0¹‘6ű2¾D{ dü GHPÊjÊ™y021æÉ‡^>³¢Oe çð>·pZÈßf"øy†]1‘~€añUfEÜ6˜ËY,âInd÷ðMPÛ²¯§%†…|œ~ng ëø<ÓX`éGýò4}ü† ‘ç \ZÎ9´¥\I° 4+Üôø§ýê¿¥_ì{²$¿ñYUK|+eÉpîâMf†Xħ#ù3Ȱô(£tžš¤²¿*[¦l®²ÿ”/’kÉhÝ冴O=åwŸtõFÿÒÊñÊ^wi•ÅßNi¢)Ôù “y‰¦È ÈC‘Û®ˆ”% Št%ÜÅÈ„iyöÖèì55g9M‘ý‘½CŒOklʘ˜Q•7™ÿ ]Ò¯$§xŽÂîKûp•QY‡B§öø Ú ¼Þ'=ؽÔi‰T§i¤Ž[R>›Ó™Õ7·ÕñyÝ‘ ¡-´´j œvÐÁ¥ýÚ#M AŸ’Sä’Ö·Y’vBBiÞIÝNI*-è´¡FÐa]·éi§…nLô}6¿}¼%C{ï%ºýÑÄÍÕɽ7õ9Ðç¸CV¥eÛ²M¹KÖÖ¾ubûá‰9kÛÝÕíô컣ÜúˆgÏíî[úpTUT^œ+Ûç;k»~qGòú_æç/É]ûÑü›ƒ£Í%Û¿:qûàÜöiíÛ³ãS: z»ÉœŒI£u‘*2—–>C›SEIÝ}R=$lí3œw"Û²* L˹žÓsöF†\cR‹úLÎ+H9·ßÐ~’†¥ tWy«Àý=&'Lï±6”¤ˆT`GÎâÐf±$mzÞFžÈ;¥ÀeIãûí`q“!¿ üº@S¯C9O®ãåÈ´HmdêPó:ÒÃùܦñ-£Ï÷§F/.÷ø¾‰Š¤¡‘¯EÞÎÜï.öÒTæc5ÆdœM 9«+zé ;Øû÷ùü+Æ vÓR»Ò›×r|h5¥©ÊÉÑ/ïpï.®£–wDêø€1¼Â,æy^d0grÉ8ÛöÉÈW#)>ÌTn‰aáo³Š]ô²yÌc7gò[b1c50ŸQ¬9I<Â.¦€ÜÂúøÞ!LúM`Ndr >¿ƒ<—²Ž"^`«he¬£@µ~vs„óØM".ü Ęoe]LÚJ’GXO¦‹sx/å죟¹“Ét³‡o³›·ÙÃwø™Ÿ÷°ŒqD`à€q6i0˜{ØÏMÇ$æJbšù€[ù ëù€á,ˆ UåL¢—üÃbÕòÒ Þã—<j7³î˜VÖÿuòÉðÛ¸æ˜M'G¶¦¦êÿÜ®SÅë„ ‹oÉVr‹¿à#1)d‰£ÛÕÌŽç&³˜ùq–¦–ùlc ¼Ë0žf ƒXÃT^ŒÝ‰a˸·q´!ëÖ²–½Ü­ÀñŒŠ1CX’pjàÁÈÁxoHÌgxŒµ´#¡>`¢£—1<¥ïAÏMŒ¤Š› Cß⬄w×佯/Žª<ûŸÓs¯?Åí·¨mŠn{Qþ8¿zÏõLb&­T—j(²´×[L¤'0Ÿ'Îk>ðÙþö¢K«]ZêÒ×]Z¤ìu_‹¶g«ã<:ÅM+E‡}ë ©õ ¢‚³ƒ¹9†ŒiÝ:1kjèL¶ÑK‚eÓB…ޝ£Ç¾j©ÈÓýÆq+¦䵓‰Ý˜Û»tå­í1+°‡TäïtfðFäÑ=¦DÎ Lí¶6'G[B2çÍ^íÌìt8²6­:’Îû~ÂG"aR˜ŸT_®£ÜUV):äéÈ׊ Ë(Ì«¯TÛeid'¤ç=›÷CZlÌ9©Òñ»TguÕ;²Ow^Ãq2kHx)2'´¾ÄÎÀÉÕÚôçúzN(½÷üS{çÒÓ¦:Røôúñ½_¸©áÉ›;Þ9!kK ý “Z »N,xZù—HçÏ FåôãüUsé ÷]}ù‡c“­íg¿^þÇ›¹i¡þ¬†d<šTæ†V»ÇªÉ:³ß˜¬â.)wÝ«ª ïðócÊ4Þã[¥ºG˜×gøxÝuJÙ_à$ÆDÖGŠjl,÷áÐC9 Vj]¨»×z¶†Ú•ÔX—²±Ïci7ä5æ-Ì L&Ao¥óòƇ2<‘Ð[ä†ÜÑ>Fe¢mÜ)ŸÔÐ¥ž=¡š¼µ¡ç87erh<%ì¡!cr yŒ"ªíÏijpýN/Á¼×ƒ—&lj´'ç@ÖÉt“âîÎZÕãžJӂ黢™Uù¯ßæo]…¿ùn”.Rl×Az¨1U©·N 뜶ÕèÂð3ßôÝ/h?ÅàŸk¨ÑÞYΩt§|ŸÃ‘©K8ÈlþLg3†€Ê¸]t€{x‘…tÄÆ†:>#ïjy³ØÀ ì éœÇ£±ˆî>>à¢XV>•Õ¬ä5š™‡å ÙYYÏ;t3}|‚ßÇ÷Ή̈́rÈÕTq-›x‡<—Ä7FkY³šÓpɇǪÀ¤àèl©“o±—ð³óùkâ•}-ÙB+×1ŠÌá¼Ø‘8�¢ë$Ã*ò„ÇìU \ÀfÅ/Ã9B?{y‘O²‘ØÊž¸ôb\´:B1Õ´Ó7GÄóÕÁ䨊yób¶_&–l Ì Ws@Z@OMMêÿÜ®&PÃ`ú¸:îKwÅ'Vq¢æÖ1ž'YÁ ô$\ÎÓü1Ìçm&p"¯³ŸQü‘nÓÃ!æñv_o¾ÎZº¨`*Aä›MHj��ŸôµÈpÖ³„F¶Fr‘Uü¿b"OQËÇâùB"jØJM…å<¹‹Át%¹—­±4!Á“‘¢à(;ñ8:YÆ2:(b—õµ‰Å:skrÓôèÕƒ1ž«žÂ¬}"†1?p009²’9J÷úlhãÙ¾y¥Åƒ-®³¸Óâ‹Ç9ý.¢`^"αïAƒ‡ù—¾|Bz÷%{Ê¢kWy&Õ+ú€×0ÜåÚ’™ÂúÊ-èÓ›V¹·×–Е‘Õ&—85TÁxÖ±~†²/p0é¼Ðoû¹.áP ÅÄ"• ŽäôeÕ% *4¬ÀÛ9Ó8108aJ¤%´ŒËÉH.´«Ôê<Qkvδ­–w^¥©Ò´RVkn3.iï§JªÀÎ>«8’Py9oR¿‚PI·ŒèP_&•×±Qi ¹ÈrÅyÕå. í.ÕÕª1at“ßowÊ!O$M *[ ?}¸è½…™çÆ7RFNy• D‡Ó“;£–KßÊMØQø¹Ÿ•Þyb¸øKÕ›#‡jö—,Z1ô¾÷:œ5.Ô:àS(×P"ÙiÒ!…ƒì(ÖÖcTÞü^=i[êºÍJx¾ÒØ.u9ƒ-Yƒ Ý_#¿QQþÿ!í>Ãë*ï´íÿÖ.ê²dɶ,[rïØØØ ˜Þ;Ð$™dR&É$y2“LH&3¤‘„ ½…nŠÓmÜmllÜpo²lÉêÚÚe­÷ƒ¼æ`žyfžòîÏ{o{íCǺ×}ÿ¯ë<=AY¤-òRÒžW²7£>¥® W§c¯(bcRò•–hèög¶GªHÓT¤¼T2kå` ’>쳾ظ¼! ]i^ŸÓ#Õ ‰œ=;½¨ 5°(é›<Ipsº‚ÕŒ¦™÷“&å"Op cy;ƒ¢êàŽ÷Œÿ“n_=TÜ©#çÊ„½.)¸Œ4õÌ7±©ïsmù»ž ËuÕç->¶Ì”PqÁØ@MP2=úê aã~“zÌÞlâÃ\kÃYjs÷Ÿ]lI¹Ã»ãb{ä*Ú’FžˆÕEGSÃjÙÜÔ0£¹†G8šib:µü›¨f-ÉÕŒmñ…Xh¾˜QýẤÊÈi”±J™Æ"J¸€_QÊ{”0&NouÒÈŠØ?ƒv¶SK+MŒ ™“ã=S»)§ŒIüSÙÏ6&ŦàÌg>W "W±ˆ‘læ#f2…1Œä0ïÇŒ£(fj<:ËLÚ‰bWíkäȈxŽU7”?ýËÇœ_æf0˜4ößÞÙDË™ÊĘ™[D;=ý“E*ãÔjéâøÀÜ„ Ñ‘øÞ 3”Vú˜¯>wßF×ÿ¶wÕ+ík˜Êâ?ÕjÙÈXÆs÷“e$=´±žõ‘õì!k#.d3¯s}ÏJz8!ÞrfÏELçN¶Ç„Í”ð^£’Q<GÍœiŽ+ûÙBìåÄ8 9Ž<§0œn–ÓÉ6¦²—õE&d°û8>RÍ“\ÉýŒˆ·íqˆýÜÌÞ·ƒ§ø0°Ö’¹Þ›IRNo29Îç¤(gEä)¶$ý<úñBËn0o-&5F¶KøV°æ’pþhÓ¹çÌîv¸ËÓgÓzÏ|‘UœEK4f»‰[ÌŸÍ(Lßè¾ß) õFLuà é”ê¼I¤#¤C"¿J¸3é‚Ý‘! ¦† à™A¾ßmOÒPQdGŽŠl§|YYCËUg¼Ÿ³7ôDèì>‹’&‡VDzÆp2O%Ìî'`¦½P§n›Íݶ&[¤;0¬ƒ–xÄ;3Êl)±#£1m~¨n€- ï±>RX”t)E5šJ³Â¤ŠHMŸ ‘†¤•)Í9µ]FêÚìÔ¦T—H·«¢4p~–à' Rï˜NŸ¾È"EÕ¶i,U\­½ÕähψÎùTÍŸ[‘ ûÔä­Hù¤`L¶p0Ú·-½-›óI¹=jH% N6Ü¡µ”T´ùלù4òI+’ê{LNéJ«ì5:ï×IßM[Ðêý&£"ë™ÚÄY‘Þ65-^îóIÂѽ:[-Š\À–”Qœ0 ôBÞ°nõ5ªzíe.00¡.­&Ô^âÌÛJ-+wRâHMN[µÆ*/wëJšY’05² 4!ðA`j`0ƒ#ƒbïßÞÀå”%å" æ1ê`O‹5áßÌ{è|#×Z7”+sÓ–æý[¤œ ?Ñý/ºÞ#~ù Ù}ìÎê*|£Ëú*}[¢½>Ú#*wèu?¿ÚüûsœàgOË”˜D»¯¶i(ëYib½‘»˜Ëêy’5Law³œ6F$]J9O²©ŸrË:9Ž€ûmî[¨`6ãÙÈkl£Žm죊Ú@!:â‚8ÄfÐM†­|B/§3„z^¡3þà4Veçq˜ ,§™a\ fqœg¾„½,#I/_ŠûÂÙ‡vq ±,’gcy*Nå]K3eä8ƒ±tq-¼K5WQAwÌžè_:¹„Ç ¡G1à?žË çjÎõޤÃúu'ø€b.`9{âµJ?n”^ÊopÏà5ær|¾?0€OâØÝÖ3%¾™Š×—ÿ™ìþ²\ád6³,þÆ"O·ðyîÎúËÌŸÏ,`žeÅ\¯þŽÅ2ŽêoDq9+8†í,L¹)<¢YÏ´ÅÙž™|†‰ñîr7qRL"™Á.†r4Ã)åϬdu<ü[v²›4·ÒÈ Y¯q=9že#9_0œýi7%úûé`]\Æú„ â˜Ðû‘ÝÌŠ<ÈŠifCÚÏBëc°áëGR¦|>Ê\öAò•+"o0sYÀ¹‘ƒi'„«ÆYµßÙïè:dž 6‰ÁóíΖA&ðó-~ÛSï¿Æw8:ãÛþSà"…††F’JÚ”P’t~hbèk9m —D:'êkñg"^¢i¦9Õ:ºÍð˜¡õójÂ}vöÕg/9*"Y>Lš47a�ÙÀä„òH:òû„K}~5ÈY‡š qJšaj ^l“~ó§Ô½$ý!pJ…!Fd´ENÌ™Òç¾ÙÅŒ¬.x¢Ý¸‚é9¹>Û#c‡É¶9œ1mòZÚŽî¤ò‘tŸ\Fs 2H”–žýRÅ#RJºŒj÷t·ïöXmL³õ5ev´%ogF]VPfÇL¹A ûþüÓ¿œÖ«¾Ò˜jŠ¥:8Ð è2ªÇ΂ŸŒÏ{(ôVà‚Àä>Íݺ#uYovÚ›7#RÙXPUp9#£’ Þ$ÉILL¨•å=:3itA†‰<”òå¼ÿQæ³¥jzuj ¨0)òvŸF•;¦È¬‘=Dæ„}‚Гä#¯äÍê³#2}¨T‡˜“ÔÈiÃ:ŽL5º#?Š ÷ÓSf‡Z#I¾GKÓ>¹'aX¸'iÕùn~×_59s·ŸwY|¶ƒu¡³“3=ôK?lðÄ­Þ= {:’§×?¾à…úÏfœ]ç[5ÍúÑ11a7øçÇ‚Ûö;j«½gØô“X?_ÎM™ù{[̨à)Nc+ø çRùs©¢›[¹Žfr,ÏÆ4¸g™FŽÇâÌ÷¿×o³1r)žçzöóõxÐuoðžç`ÜFjb.Ë9@/_ç8Vò íñæ`7ë9×@w±‡ÖØ#ØCÃ?öŢ©ÆøÉ{ _Š3ÌÛ9Ä,¾Ê«¬Ž‚Í4ÅÒÞíL§‰®x8•\D»)åZNfW°™QL¤•rÎ¦šƒŽ Fû)S™ø·êŒ%&eLeù§ ®ŒASýÀ£½dˆø&C)ÄWÑÛèw…üûjÚÿkô«Oþ³…äÿt¹ÚDŽýl$¤‚[ø>Or-kØÏrú²’¼E†µlàîc \ÌZ¾G3gðg2|ÄJò,çºx‡ C?[åÿÈ/¹<Π¿ÁS¬$Iß,QTkP·bu¼ÈN¶1…G™I1Wq2àYÆQO>îÖ½ÈÁ¸?Ÿå1㤒7ØZJ=;ø ç2…ÍðÀ™)燂“qcM-»RfÔšÔ­ªßøJÂÙ/|7ØõJ²û¦ÂŸ·½ËÀr¯ßã+ûÜù¸;_ 7ÜN\^²A¦ÅãWÿSOï ¼“ÛíþdßÃe'yôjw/rÓß{ãT·´Zu‰÷ëEs[BO§T(þr4²5 [þ¶ÀtO:‡¡ö.gqj¯ÞÈ`îÙ§+ëKí ¡nºÎKš¸/0±ÏÝ‘SC«QP LX—ÔšW›00ç£À’ÀšÁÆôùQÂíyÿÜ .R?ÜàýG¤e k˜™» Ì:©ÎȾÆÏÉûÄœù^ƒì4*48ë`ÿiÊÈ‚m“pMÚTvå­¥ºOcwÑà’‘}¢Ò¢LåAkB¿N8!Ô:PlTAyV{(*ûÖôüêÝ#d^Ö—Í…ÚùA¨w°æ\0£mÌËG§Â£ò}¿Ÿª1õ*ÞgîþaAîÚ?{dPèݬ!uºv+*ø37´ÛÙmÇ;{´Ev&¹ Ò?Äè¼o„FT;Ô™]ö††•^/Ý&›2<ePÎ; gGÒi-ãlÖFCÂï’ÒKEy¨Ðà¦6+2VG†D6¶¯ÃÖ>+8±Ø#UŽ=èã‚lÚÏ ÎŒ¼H¤}§^M‡ó æí îÔÃ#ÖÐB6t«ˆ¤ÏGŽc0%¤“ê"ã"ß \™œt}ÊGyA¤1²5Y[üquê¦ÃC#,;#9þ°ßþ2ùܹµ½cÒ“’?~?ÿ³÷õÄŽËÛ"#8Ÿ×ù5kݸÖ3iÝýéÜUi—‡ºx–o)“|v™ùÌÉÛ[fÓÊø^<Ëß ‹[+?榰‰×¹’ÇbzÞ½ü Ž7qu¬>ÿ1gò.‡S8 ¼ÎE̦—ó¹,ðenâ.çnä0Žßð>[XofRÁÕ¼ÍØÀQ¬'Å,å(n‰Ï~Î¥šMüŠ>îf!”pqÊ€Ðå|ÀâØ+»¨¡’¹ñ”}ð>%ìbˆ#½Ìƒ±¨¯ëie¯ÐM-ûøˆÍdû£ð4ðU>¤;^‡ú7�UÔÆÅt<²ÚÅ>">3}Êã~ÿ_š‘T1€sXÊšúå¿ñhêFvñb¼Ví‹ñß}1è¼ß`Ò¶üŸèHÿþ/þ_,W!ç²3Ž”œÄû4ÄaÇwYÌFÇ ¨×YÃÉÌó‹¨íWÂó Ã9^VÆðÀˆ›b^Æxªù„5|—V^g=œÉj™Eš;i¤’»ê’ ñ‡©d·rbŒ¯mà~Jø(n_Áß°©$8‰äéæÛŸêŸ nà"^%Í޳';‹àŒÐÒÐ= _ 4GGz`›ãMî_|Òí ñ})…ë‹ä³>fb¸³EÙlß]î¼·\ð¿áÞ÷~Á×Këtp¼{î1û_|«<hîNì5mc~dPh½p‡ÜÏœ¡÷g¿èoögíSA/ (œõ/Nëî…¦·xÿ€žs³® 縄á‘T‡ýÌ Œ! e#‡"ƒx‘¢¤±ëª\”pNÁHž*vqVµ"éÄr¥Ìîöâ`mÝN/UYbt›-ësv$œšÕ‘µd¬ÚýÖ”;6£™ãºôF–Ò'[œ¯ë0°Ww=ªS®4,¥’Õ5Úº=OCÂÐ@kÊïCÇe ïSžÿÜ£¹»¿—ž½!S¨Îï.©Ì}¥ÖŸT:£J&RZ¬¬XŸŽ£ƒ…AâÏd›$×e ˜œ?÷hâƒí{ǵºéÛO'Ïû YÀÆ[ž¢PÃp[»µv¾q› ¿]”«)–(×¶Ïû9ãR椕j êðZÂíŒ+øYÒ˜ÐKI=ZòV§}-R—P 6­(+×êM¦‡62¡Ï”i+rU^?‹\’32éÁS‡:¯ÝÀ”µH¹¦M2<Ò]-¢4²€B‘%_ãºf­‘<5¶ÚîÈù¸K{`T¤…Ôó—À£ 3h ,IšÙœp[dÏõ"E¶D2=ex(É T‘SzËHÑ_ÿ6ºï+á'ƒh.ª~ãøBí¾ÜE »7eîüEîg§¾su˜_ÙÙ˜ÅrzYÀ 7ö”=ó³|÷ÖÀV…N§=0/ð&Yuº»’ÚæØû€MYN§‘R‚”ëC/‘vä´—;¨åGQI‡ú¹v £#ƒYË% æ!v†'üStó6“1¬a)õ|˜rKh)/0“C¼’62ixèîˆù„ý‘+y‹]쎧/³”ó8&=ôwLPˆ0ƒ™Í'41ˆ L ¢ÖIG¾ÉÚb3H–Ã,áîã>VÄ=â Èr*]ÍÛdã0AivÆ»º¯1—õqiyRïß#Ng Îà½ØÖq6‰¸ |1G±Rêx'î›®‰—€îË×ÇnÎã~H7›™ø©ªîþ†±¬äL0-œFklboÝ>ÝñÍ}:$ñß/W…ÞÞ&Æ;2ÊÊùØJŽÕŸ¢îw¤ÐïvÛHšéàvs+]±e«”±TR`.šXÆ Îe4»ÙÏ,Ö²ˆi|/vþ¾Éxžf(‹)çc¶¼›Q‘0=R_ê4¦<~ÌI²‹Æ#`ƒ™N%Ãxž< Ìà�/PÇšxø¹.ŽW„lá$>dt©îPC )DÂÈŒ¤¦HšØÄ2.â%šŸpmäW¡—s Y븂 L°y†'ÒžX-?(ÞïñêOGN[âœ%þþ{v¶G_z51ïoÙÂm<Ã4ʘ®z»KG¸obâíÛ)N:)qÚúäueѸ­º7»o˜oØðù²ÃÅ}¢P>²<a�½‘Å )F%åH& Oiˆ ½ˆúôf½—Ð@{©ºÐò c{ÁIYSÒ>Îx#oIΠÐÓ# h³µDÈÐb#›ìȘÌYIéj $×åà`é}Ú#Ï3©ZE^”õŒs*$"c"Yï”8/§-PÙZ¦sR¹ÚÜm†_»gÀçoMîÝöoý!¼¿<ÑV‘ÐÙ«¡ÄÞ6J¥z¼Y¢£L}ûì­ª^wAçÌ-áIŸœSbÔÛ¥ Í ݃D_úAÕת:3—<Ð3seÑ’SvÏ~ª÷¦çíœécª 55ŽÛosà‹ S‹TW:X¡¢Ófn´„ú"MClí2,2)°žÓ Úv†ªz•ÛÕíšVÃ�� �IDATÁ@&azäåPk™5¢C†$¤¸¬Ko±IÅíþµÓMU‡ F„GÌÝýCø¹IÓ™ØRâüÀ]²òÈ"ÒmFF~Â¥|©JؘrlAÄ)s ùb½Efæ }Â_EVr˜KªUg5EÖW:µàµ‚7ûн>èÔÞá 7?l~;¨èÏdgl)¼1ÔÛ×ñGß½ÌÎý¡}¬ã®H*‹|ȉ\F¹·V<sV¦ûáÀå‘V6ó\ÒmtF°ÜÓœü‘çCÛ'8Ôšt[¤†n†3‰C¤˜OgˆH@Ž• ä**–DFG>¦ƒ‘±i!Ç.Š"é¸ÈüZ|$3Œ>ÊBo’d(Ië¼™WŸ442‚åŒgv¿q›éLf7'r YJmÌA%oS`?­LIßÝœÃ*J{¼iŠs~Š tB|p—fBL:…6VÅžV¶1ŽbðMºè‰¿çCұȢŸÈÞÈ¥´ò.Û8È+Ã*F²<¾ÌwbLÔrò̉ÕêãØI5£YN7Å˱tóƒ8‘WâaÍ$Jb‰ÉÛq¡*ÍbƳ†SY¿áß_ÓÿcÝêÿâ0peoï^RLŽ7°ÿ./iŽM1ˆöÆòYÊØÏš82Æó0ïq.íœÏG|Èë|ŸnVq­OOÒÃí`KüëÙÆœXžtEtݹ™ ® 1ÐIó2åL$Ÿlb—sådØÂq1ä߸š§˜ÌŽþL[ØÅåLd‹ù ›ÙB ŸcrÖúФÀÆH9Þ œ™¸5¡(RÆh²–ú@]ä=¾ÄnfÅgôûÙÉ£OY÷RKŠZrnûsrù­Ö¼¡¡ÝÌCæ5QÏÙÌK¸(ðQä)õoº¥Ô]×E†Ñ¨ , 4†ßy@*ïÛgÛ·_C½CË3ÍcýnòHM "òåHš)i“CË# °!e|J¶Òö^ËjÊêhX§aOG.J¹*a\(S§¦à¸±65;)RÄ ãÆ«ìpì�5=>ì4;§¬Ü‚´y5 …ª( ïô«ÈÛχ {')jRÌÔ^oT†îŠ, \žWÌ Ðÿès é2Ù°Nþ–G“C;Œjé{ðZ/#Ê%»¥“j2ÊI·HOVWŸQ]î–òS;³uQ4¯bûõ÷Mé|ë”ð­+ƒw‡ä%ó¢[*Âäêâ’Öïü!üüÛÉžé~rn²«u€üak*œSÐR0¤@^[Zz¨D»Æˆ@gÂÌ´a£“š#eÌå{Å9Oõx åÂg•èÉ›Êà §¤íëu T’6¾`i^6rNÒìÀ˜‚žÏfGqFÛ¦A]FuÞºRÔöiJ™š·¤\c‰«4ôús1¥Æç ý}äôÀÓ“#Óx ÈgB[#ƒ#<Ë(öR‘Ò–³0"é½¼²È«D¼@KBm¾èåäô3¢KWøì ë›H/È\kíbÊx˜›˜Ìº".ãGN/óÓEŽoÎÜ{‚îS"ÃcÿÜêÀ Ð4®æC}V¡«ÔÂ2ÆÞŽ,ä}3‹ƒ,f'¾“2;ô<÷ÓÂÏé¡‹ 9ı4V¹‰— þ¬¥À.þ™ÙÇxv²œCŒàÆ8é¾ñ¢7/‘÷6•Šèˆë½W9ÀkdXN‚3y”èàªy“n>f#˜À$úÉ8ý«T?|§ɽœ® =F1eè&_izÒܼM¬û[é”»Bó8Çö ñ-be<„{á”Ç6UqwªÅ”1#$&h§•ŽxóPÎ*s c˜c,vÐDÀ-lçhÖs)ù8†ØöRÅ0æTQG ÇÒÂé,ãh2œÄÕdá_Çôšþ›µê»\=ÕÛ[ÉÍÌd] ï!÷OÒ&&ý:p^äÆŒO8eÌd ¸˜yñ˜®•R~Ès¿ŒO¯åM>—¾ÊŸÙÂy)wG‰‚ëâ¢\+Å\ÊBÎ¥…c¹'rkø »x–Sx,Þº¶³Œ¿âgÌóSXÁñèïxþDkÚ]¡û8ØÈYÌg¸œU1cÏEæ3„<™Âœ˜0+0-’ç÷4qväN¢”Ç8'å†Èî˜äø}/;ýb—üɲýì Ÿ8ópjïyá¦î7s¬y=Là7D\ƳjÚ×â‰Þ£4’œ:pmrþ áêF¯ÿŇlm÷ÆÙAÖÐ,âÕÈ•ŒKº2Ð^ŒÜ˜Ð85¡.RYgèaSBƒó/¸>41çpä"Œ,6¶DS‡dªn[³~9Ðð„aY[ «°5­½Íô¬µCÝ3Þô}F”du…þ:‘šÐ¾"Öš”11¯¯Kà S;…<éM¹&oxÞD6w|‡vEÎÌ~Ò½tYîýÑ}OÁ‹ éÂÈÂê«¢;çGw¾ÝùRîêw¯OQP‘TQí˜fÝÙ={RënÍ}朜5¾VÐacÞÁ¼dÖðÚÃÛ×ß“ÛðÍÏO®}nPsë4ögt •Néí6y‚æfK ž ’1!'I% UôØÞ­NšH5rUäõ)Nh6­Ô}i£ëåºE}ê1„¿Ð˜tB‘â* {ümhAhlNë#—R ½Fu•Ù-†faChhÞèPuRPðýÐù9ó³nÊTî”´†>"c"ù #ˆNЬÈù›Hu $å„ð,í`ÖßÊn› ´Û¸¬éÍX–æ¼¥÷G>Nøp’÷wy|ƒ¯ítçÇîÌZtiºù”0ø‰ Þ?ûÅ+î\âεò“¬Þ¦¬Äªç7úU™‡¦ûõsïÿ<Ã8*‹¿Æ}WY?˾·ô”ñÅÈXJÙÏ™Ìè·â1Œ­<y”$—±Uq%fç1O ìŠÌcCù*kÙÈéœÆë8”rgèQsorǪ§+YKÇE^ç2ZË?òÓÇ×/Úx–*^çPÜš:‹]¼ËP~—tjÚB÷÷cMx-GL¹Zâ$ᥬâZÞ)ø$ï“H U|YlŠ Çðcöîð8A~+YÊ%9OkˆI¾O*v6µÆ–ºxEoáíäɰ€nÎæ-®‹éõsy¾{‹ã¾TëbþQÄ>öÇM¸Uì©€ìe9Kb’E -±ØÖÿórõNoïÞå5}j–‰³-‘g#+Éò(E¼Ë…Ìaõ丂?3¯ÒÉVþ†ŸpVL+9žÊXʲ/²™y¼AØúU¬´YÅ l¤œJvRÏ!Ò4Qª_[`ÏPʺ¸Í÷Unb‹âe)k³«9@;]ts=£B#© ¼Î±|‹Ÿ’¤ƒ"–s×ðUúØRî Uð|Ú‹¡k"¹ÈûüŽŠ@)=Ë$*8“Bècû8Ñð_5ÙK Ë*6Vì¹$óæ [þɆznwæòÄÞ ¢MÙ;5¨»ÌÉÝ–~™·OXõ÷ßkN¹†ëgó{R‘÷BS‚öâhÿl÷íÀ<™¿ Vž¹=4“ùïRÅi )u¡#íü%49²ªÏwJ4–Óki$÷‡Àé¬ëÏdæìè3!¯g’¶}ª Ys³$?ÎáÝŠ:•‡’ y½».(¤UFþ.éOdhI™5Cs¯-Ôv™ÜkSÖð¼«ÓŽN˜ØZî˜Ððvu)G§œÑ“6(l¾¥¨ùÛ3Ù1½S„ãV–œýBpo[pïÅ'¿8gÇÒ[ƒÑï‡Mƒ®ö1¹™»ì %¨1¤EKFjÊ«jp…l—W«C›òá—‹š{ö4/êÈÜ1B²ÛØ•{õôy"oôaÓCA`jÎÏû|)r\¹Ò"Ýä &-Kù(g“‹tD¾Y®´ÄY‡Ý—scʬ@¦Y2¯¯ÒöJãû\0ÌõZòzú •±µÒq5FuÉéäÙÒë§]: "ÖóóÀ•áu¶VÙÓîÆÈ¼ÈƤW¹pˆŠVïTX:ÄÜvKÒÎ)¨ä–ó@H¤2ðQÊô †ÔZbP$,wGŸ wl|­/;-ÈßœV™›2c5OÔ<Ç¿mtï­î=н—~¾ û÷»£Ólòõ«Ý¹÷ns?òÇ·\ÿ‚™cÍ?4¬yŸkú,¨mËåt°‡g8Ÿ½ŒÔ÷9=ýÔ¾ãÈp\GÈ3—[XÀW9—?Ä×~µÄ—8>ð/)sò>ŠœÃ4p'¿ã>ä÷DœÌã\ÚÌFšx+öðî¦&Þæ�;XÅÏYF1[)ãÝOÝ<wÒÅXÖsÿÊÂøx¦‡Ë¹+ò—‚Ç8Ìf¦ó*|1š¡«è Ld6òåH6:V/‰÷7çÑÎFªÈÅñú *ø„c81¾<Y®!ÃzŽ‹ùೂ½ñ⋼Ïñ”ÒÌÎá_éäNÄà¨ýñW*>†]3‰öSC=”Æ«NߢÇhˆßŸá&f±ôSÔ¥îø¿êÿçrÕû©7`;u”ÑôøØñ ŽæYÚØÏxúGpýçË»É"62…Ù1+¯ÿö±¸ß°uf-5äb|m›ýX¶ÆÈ¬müCLE|Ž2¾’rB¨‰˜Í31Bx¶#e‹ˆÅ¼Ä†X¶‡Í ["K8Ì—ã`}¿ê»ŸÖ$üM¤œâ!äH®fm’ÀÑuI‘­¡ýôõƒS¤]Qp˜²À gD^æ}&°“ ,¢‡ß'}!šø¤/æ\´Å¥¿Ë½´,³j˜îñÎï™êÀYÁ™MáÞb›>˜™˜Ùµ[:™úÈ_¢#EñLpgsâÞG–'¢‹?'\Pð]Nb‘ )NꌜÊùÛ¯ÄNÈRž4!0:o>¥I3#ºNê¶±`cäÊȈ@”pz¤£\"¯‹ƒ$½¶_5‰È¤ÈÛ ³"õm’‘mýš´„õ*ºŒŠü˜ºrd¬-·&aiŸ—‡8¡I~¯uCmÌ5Ö¾ƒÞT wB—Û9¿ÓÞÁ‚¬®PiÚ’b…„ä@z<ZåÊûKlïZp[éÙ?mgNyÖ‡[{/+¹÷öÁÉBøW¿(]ñ¹ÒÖâÃz’¦ujlÓ˜˜PHW8|HIòÀ”J3ǘÐë·iÇô*TبïT\P–7¶ÎQ}ºóJ# ™A>Ÿt C÷Pí]ž.vT•¹=¦R^£¾Gj˜¶zÝåf·ù8”.•ót¥útÚÕi[Á‘Ç"õ··LrT«î"ËB}¡z„S#ú¥ÕiuÅÎɉºÜÓn9e¬fy­»z´fÍ+óåÃ^`@ä=ÞLhM¹”ñI·F Â^ó*éñR”–»-ñ¯»ó뇥›TX™‘¦‘(! ãFNÿƒüð)<{£{ïto§{o÷I¡BSÖ™K§»÷3þTÂ- ß.U™¾Rç Û¼¿š£8ĺ8ô”pD_²™c¸œ—ÙϽ~ÃA.f5<Â…<Åt–ô“Ÿ¸™IœÇml í¤géæ,Žc/Os*Ë".HXY“ESÜÌFÓÇ¡ÀÑói!Ïu¼Åd*iáCJ 籞£¨âyŽåB³™2›bNe<U¼ï¢Þ¡š|ÀiÌ —ˆìd ×r/+øÛb¼j?q>—°…uœË®ºhg5O°Žaœ#ûFÆ$øþ¸ùnªú'îñ­»ÿ‘h%³âSÓþIØ; ¤“>Ž#92Ì¥šËyL§Žã :b‡}‚‰ñi;ç³'û®Ž[@íÿI|õé×H¢8Ü÷ÿ²\owú§me±‡t 8Š6ªI‘‘º;ØB1·²FF°A¤c¼Çu<ãÈàç�71?¶7ÓN#ŒâÞ¤”ƒœÍãæÄ(ö…GÖðÒœ·µób9šÙÌÏzZØ™ðבg©åd¦q4Tq+Ùy=œÏQgq<K©¬ háfñO'죊”Ã)ó«õDþ.çƒè\ëГ½U¬`<Û"‡|îƒÄïøÞ9 £)aeÓ<s­¯þS°ô”àÌ­ÑÞcmÚš¨Ðç˜5v¯ux ÿBš>þÍѽYD"V3*’ˆt%Y89¡1Òù9Ÿåž¡…TÂ" *hÈy$25eDàP¨#RÔ£!­>åè‚ ò3>Œ\–Pr”d³\äp‰ºHM…tƤ9q¨Q;sZŠmJ©Í©¬éS\,‘¥\W¢¦O{Þ´‚iÜÓ®tˆú6a‰C½æeTöy7áÆÈÂÐäñê;ŒÏXÓ+›6)¯ ‘nW[°3é˜.oViëþêâ¨P­¨Î¨M¸9R ƒ!«ƒ!+'-·¡c`¨&Ôé ô¤ýq¤ÞVz¤uy[JôDª› bú>[He¼ÕiE`x±êœty¹AJ2v‡ªøMà¶ /¥Mé5¼Í€Àþ¬†UÔ³·GgJ}¤;#µOE…åy3vänÄ>¯¥5BOŸw †qRÊyc#+›Ðkt ;ç…‚·ÇFGö¥MN{/kKÒñ‘k9D-£36pY΀Œ¢HCÒñ¡âÈ¿rSRmà´¼ßDÖqu$Éö:L}FsAÏ!•‘'³Òù+Özÿ”°ùr¯ñjÊgC¿e;ûYËyŒ¦œ!„ c/5e.Éi‹|&¡7rØ73¦ÿÒŠºb³ šÂ/=ìî/1‡Wùó8—}±Úûܘý /3‰:’È‘ãu.¤”÷ãðñlc,³h#Átq›™Ã¼GšÁÌ£Ž‹LmBoä-jHÅ2ø‘¬îŸhŠa$ïHÄ1ÍÂø<.áøw{.lf*C˜ÀA0Ži´°‚U dg³ŠkØB!6@ößÁGF¶g ef�½Ô³£é¡;Ž^ÆÔ1‰ýTÇcš3Ép,Kc¾{}j$O3„“9H††ø‘½ß’1™2ò¹¸ø<†Z®'Ÿ»v’¢&ž™­d"¬e9«bhCY¼\M£'žœ áõO-%ý6¨ÊÿZôÑ/ÁÊÄÇŒÿëå*ñ_|òdx‘ëYÃÇìåì¸[×ßî7qL`_à‚øƒ—Ź‘iÅ2Náî~ ³ŸWIðC~MCŒÌú€­Ì!Ã#<Ïlš¹â?^ÆJjã­ñ@¦±‡Ë¹†«ù˜—ù§ƒÇã&Z+§´òYvó+ÒLá‰x\ù5¾É/9?&Þ÷ï½’\Ǭ¤ÛC+CS"{hãÛ¼z-2ŠÊ¬Ù=ŽïuY^–CœÈA¶s"kâDb@1—{ñähâýÑÄbCØNÎoöaKäÕðÈÞ?Á9Ö”ª~ßÃϪ~ŠËxAüž>¶0#iÄPwÒËçGQ$ŠL s°Û‹$&šTíĤ›'ˆŒå2r¡“RFUé-Rë˜á†¥¤r:û U¦|.pERGdÇne cJLÚ¡>‡Ç%Íeh—-?\ž÷1˹©àüœÝI§%Œh³…ÒÈò¤ƒ”¤ÍNËè^ NmWÁå¡?¶ÛZp]ŸDŸ-}ŠÜEsè…HI»’œîìðlè×ÅRÁׯÍÜõ˦ÿÔuÉÁ^ÝÓªW^¼þðEkÚÿ`G׬2Ã& i ý4´&oL«öAê+UE¾Bû¬ŠtPàñ„1 IÚ†å•z žŒ¬,ØÞèì„4=IGµ8}¿Ú‚VÖ§\:Ň5 EÊùçС>O·zƒÆ>×÷YÓk UØéíµù êœ3#·'Mý1”LÞe÷A-æ÷y¦Î¬Èý$&QÏã}¾Ñé…*é"O÷ûŸXÇÖ‚ú‚C¼œP5Èð” Lg C# ª8‘,OÆã„þ¢äa^ $YI›»»íü1fô8VleÓy‡×I‘ ž?©[|ÿí¤YIg¶kŒŒ*ÜðAôâ¯ík=àÅ»»/YŸ³Ó­9FñYVp2½\È‚Ø.q2irq{¤Š$¿e#h$G%áy.L˜‘pGÊ]1ïç·ü–hc(?dKœ® 8H ÜÌnæ§Ì(™¯´ÒTó\K)";CoñëcÞ`—æ³´1#²;A¬çUv°wbO<Ç!…9qSøÚÿä¯8ø©{÷»bUü›#¡Í…L'K×qsLÿy)ÖØ7s-ƒâï¹€ÓXÎ4j9‡×YÂÓ\Ê~+-,¤“ãíR^¥™ °Í¬ˆÅèëùèS‘ºe4óm,¤Žëÿ?ˆ¯ò*üçü¯ÌS›ÿÛ“¿ ÿíbÿÕËXÇÒ¸¿ÝÅ_ó83)¢™<íñ–ho2œ c¥f*ötMe$¢‡Sy#~Ôƒ,_d×°€ÝŒcÐK6.^ìçj8‡†Xj¹ˆ‰”ñ8›ãK}ˆVRTð�Í|† ÌI¹*’!ËJæÄH®Æx#x/çRľÈcEškÝÖíþĹ‘V6ÒGQ`OÊ×C¿å6ÆPÇw˜õQ(÷< ÏÉ“Ré‹Ã²E ¥¿/÷“dÛI.-Mí¼!ÜÕŸá9 äI?Xá{9Æ™ï¦öÞmzš[–u¸l·×º´ÿmà‚@Ž?Xý}ÿ±y7°7ã{¡=|a4ñ°d¥¿ã„c²«×棒Nfœ˜y$ídèó Åãòôy=´3gF4©‚5‘  #04atho¦HmÁ¼^;8«Ë÷ Fòc³*S.‰`LÊ_út%M­`,Õ‰rC%ÚªÉСŒBÖ[“ÚmÖ@£ªÎh<lCVgè\.Iª-èL.øç‚êèH1î˜Á†µ20ÿä)^­tÉ/‚_?ÚvùÿÇÛ†×Užgßÿ­µ·$K²dÉ–mÉól<cŒ±Mlf „y BšJBfB’¶I›´Mi›¤iHš$„0¦ a6£Álƒ1ðlƒçy¶¬Y{X÷ûAZ}ܷχ÷xžö]_ulikº¯ûº®óüŸó{Ü~SÛW5¯^ëŸw CÿrYou:«Á„õ}õî§ã¸IEÍUFe”vü¸¿èëòfÏû¸%¶¹ÔýeÎn3ˆÎªwøSðÇ‚s‚‚ßSšXÚ¢_ð±?+êO}¥¡¥µ:~†Š=êO p<¶ñ¨ *²&´)ÜŒ þ6˜Æ@Šúg‰MIL錃îvÕšùuÞ©|<ÖZrᣮlÖØ­Ôr€ÚØÊ¼éùn§í0Ji .`ÈijŽÚTô3éOÿ``lslH´?+÷1Îã¸û?ú® ‘g*_ïqBY§§ŸóÉæýÄ'ÞÚP˜æºµîù­;äß7Y××â¿uÅû~öïnºË¡®Žd£y™¿f:ãÈ}©4ü-ž¢Œ^OOÒÞ)âa<ƒy<X ~ËùÛéË:6qãtr-R›‚=;ÙÊì Fò´Ð™²rf§¹‚_ærp—ò _¦™ý,e3ï§¶ÜÜÉËé­=ŸÆº_M›ÙÇaòé–¡ØL;7ÓÆh.d/—³˜­´ïêá˜Âü=÷²*%SŒJå¯Isû¥¦¥­\IcÊ[8= g;Ó‹¹iÃz o‘K]Yߦ‰±¼ÂòœIKºÆ›Âö¦D½–´'ûÏÐÎ2Šº! ÒÖ­+¤ªŠÊOJ¤<¹ êó_X…ÿ »«.‹U†‹ØM)×ó›lõÂùZ*9ÁhÎâO¤<à låyÖ°I4swðÍ“^þwò;žá“´0ŒvPd(}ØD3óE'â�‹¸3M‰¼‹K(OC¯a#“Ì_°˜Z"›x”zVp;’ãmæ²?ë6Þawð!ÇùTbJ«û8Äp®Žü$²;’g>7&úSIž‡x–±|Š%<”ÆQnæ¼õüJô½Çï~éêþîìKwo /u$ý²ù«ÎàR튾™q¨/cœ¿.»wP²ùD™Á½”u´Ÿé¡F¿Ìzzdµ%çl—¼ëÔFó;Ù\Ìúe,Œ, þÒÇÜÿ¬!›’n´¯)QžØÌ—•ôé”=ò Á–ØÌXyo‡óú'ª’nùÉOœßlrä…XsÖE_ ¾_°ªYkÒ —jÌéS®OF¦—%F&iF­q•ŽWÓ_U£o59§hiPŇ\$#œ(1{·Ž‰Z·z®Ñû9ânT&Rl)ÚTjq?sFÛ$›×ÌPâ6µĄ́±GhŒâÿ<ü×oþÃmõMí{ÙT§¶ d¸ì^ãò&d j´ ï‘ã&’/8LÒá~ÖâÕœ¶¨ãìÈvzž§v“Šõ<^êÒ£š 78·Ä§;ì Gž $òhÞèÄêà ZKRoÑ~EÎ9lXä¶¢S›íë´‰+‹š#ã"÷d\ÄgF†–É$š2þm ëƒÎN“N8Z°<2®Ãœ¢mAˆŒ j˜œ¹¡+¤{cyÃò~•qv¬,ï­È7J|2éÆuðÝÈ¢ŒK‚'÷‹Š~ÎU|”qwóFÐ7H†èÕaPÁqjëiè´‡ßÇ~y3¨ŠL(qnÒ°Þ÷³ÇÅ‘:£_Orãæèow:ú/îZó`É QñúLc]Xð¨_Ïr¨}Å2^|ŸwYÀB²lï²Ïs-;èÏ\òÜÆ£lHÛÁg˜Ë$"Nµ—¿gëø.S9Ì ö²“ã)i?¸ž 8Á#©z­7ïÑ›§YJÆc YÂY<õýàãT³$u ~‚'›²ÆG~žqGГÞ#Oešì¾ƒãÝ’«} æŠîüËÒ6ë›ìç#¶3“õü1ÅCTs‡øÏ0‚ËÆkt™5óÛ™Ë/¸•>œËռé\ÊKH+è×ÒËØTû0!MŸGÄÜÂiéDM%8†:ò6¤èÂzÎâÙ“êK_r¼Ã<©>»¸Œƒÿ[ÞÒÿ½Ô"Ϻtkõ¦®`qšXØu)Bo§ÍìD>Æ£,d£¹©,u ™ß5PflŠßß’Mùñ­�� �IDATâØ¯`�ÿÈŸ33x“p?ge;SiÊ»DüMšŒ¹‘2 ‘w"³ÙÊ2¶ó9ú3œ=\”Òû³•ù‘’ØÈÄ„ŒfŠA†­ü>ã®ÐÝN-æXÆwX¹=ØÔå—*SñBÑVîä Z˜Ê†tÝz˜8v[¸-|í×65xºÓyG’ƒ½;œx–MJ*{Èŵ+Œ9+ êecƒêÚê1Õ¹µwåsO·[œu›KO„½UÖ\Ñ©5ç>cî@?ÿtW0q­‹r&uÁ‘ÈÔà˜A÷›vÀƒ­¼LóÖŒ¯ë»�—‘ÑYËŽT9š×4GªKÛ,-ªeEPÁâÞ¦‘*ƒ¶`Ab—GJ#U†E&Ux=çÉà´ µš67UЖ³ï ©m²9ùNQ“siâÅH!21¶46+X|Üþï–š½ÃÐXmÐÀÖŒ£±ò¹¼çÀéú³ö¸^jj ë™1ò^,ÈÇNdL;*›ˆJT”ڜ׷LU›E‡Í*Ú<™8Ê8Êb½býƒ’ØËA¿ÞæVûT«#Á ÌÉ8µÁм§È—¸>˜«‹ÜS§æ¦6µ¬|,v 3»$¸72:RŒ,8Òj\£ Új´”É·YÎǸ,‘¼ÙDc¢Gðrâ¡ÈÇ+õ*x6qw£|‡JÔõ2´Ý˜Œ;b™H&ؘ1”²Äö—º¦è{l²¶¨gð©R•©ÎùUÆeKé @ÓÙlŽ}“Êd¢àýž*w'fÓ÷„ Öwé°[ï4¥Ô“çÍž†lgG˜ñ’ÚKFÅ+n®HFÔÆ ÏŠ[rßþŒÕ¯±‡ ÕÁSäYÂ^ Ã|ÆgœÜC3Çy“ß²í)Rhnz=ír"ÎJç„빊{Ès€[XËL†ÒJ '"å‘ ìâÏx‹}äT¾Ä ”¥"d\”z~x°Ž YŸ¢ÓÇÑ/ñ2{y‘ô$C޳8êÈߤޱç)eç3‰ S¢[{JhÀjÞ¡‚5]¢¸Øl²4PK̶0šýLaVJÄ ^§“?qU MïŠM9ؕ º Â[˜A'M4¤ÙI{iâsX΢T˜ýVúB,ç—³W7]åB¶¥I¹Ì¥ D²/MÞuRÉ8HgœD™Íö¦Õ«2íØþûË•ÔsÐϼ¡ â±,âìà:³O±”^ŒMÃ…‡ó³3¾žI5~ð¹tÀøð<‹RõNµÌg'¥Ô3ˆyôI{ð1D42Š•´s‚Y¼Ë·#oE. ÞbC×Öšáéh{oºŒ]Åí슜¬ ÞIđϻ»ìÁ<^âóƒ£ÁA%ãÉó@VßH¯¢­\ò¸¶0‚§ÓX„=‘›Bão-;_I_%gyu­_Žá}ŸÜiij޻D’ÏšV®£Æ†Á÷½ÛãÓ:znzÏûÌZí[[BùSòK¢•Q유‚þžø£_ÿóI*L-(K<ëǘ Cq²3ç»Ïk[4Õ•èUaN_>Ⱥ0K:lK´ð|0,6—§bãÙ,‰QaH»'‚Áhì­.of°4ÒÙÔœP¡¤Ý{\R£ï ‡©¯T^áh‡úDiÁßçõŠ„R'rFd”(2¦V¡Ýñž† pjÁ ÁZ611±2kb¬WÞt:©.ȵÉwè &ôrª‚|Ai¹ m®¬ÕÐS®Õ#‘’X¿Œy}*ïp-íÁ1¶Ò‡>´FF$rcì;æÌà*u6©Î{“²^&ôv¤Ì[½ûIÑñŒ(±³Ä¬2÷¶™@Ï.6O°<¨ÊèQ#×®<‚—"‚LÆkÇ ž*7ò¨-\B)#x-8uÿ.£wâÃ%Z#‚ž±ƒ½”Ÿp4öxO³ÛÍKüŸ ^‹ô .ȸ<¨ŒUËÙͦàúÅ®õ z°±^NãÃÙYÃǹ‘]°ƒ2G:»97õTñ0×r »¨ŽÜßÛ„›Qï‚fÛŠZm¿QiÖ‰z-}óH§ ‘©‰voÅÔ’0„ÝÆ’/PÉ­ìc7‡¨ Ý™¶Íô¦™<_d'TQLJ¬Ê¸(È¢ØÄHK°‰ï²œ÷˜Åk\DŽ©Là)ND¾™»ÙŒO ´QIÂ4Þ¡”wm2æ¤iõ)ýá«!ÃQVñ—œÇ:^âÖp£RPÀÊ8‡6æñ1–sŒ ÙÇúó.ëÃSbèG¦¥|=Ò—gXÍPš8ÀAêéÍy¼’1!(gu´3œ*㽴ë䦤֨®{Ébޱ†5a M'½Õ® ½#í1&m¤¥qoêá¹,M–I''XÃ:»H(¼ó_êÅÔ%ÖU®úQÃδ\íúÿ^«þÊÕNK¿·®€Äþ)Dë9¦ð1Þf'87S*2žVÞ£’™Ù<É¡“’óiªØ1òJÖg¯3Žwt§{ã ëS/^o>âV¦³‘¥ìáú³ˆ)ìb›‚Ìf5·r‚g™ÅM¬ã1†s-§“I]#™ºƒ§&¸SÒ,çóy’I”2Š™d‹Ïú~âáT*¹‹3³>ŸØJ5{ƒ7ìðKÞÛï½V¾Vá™Ûíz†ž»ùRví犫ï5s¢Ñ <uª|_X¢wmxþ¸7{çöؤØ9‰Q~q¿_lçœØ˜H¯vÿ¹ Ò?±‹?h9»ç»W•½zznO=• J*ÚËy,ÓTeH§ç‚§ø"A#¯ bÿ[lm³0èÏ[\qEð,×Í ÖäÌNôèp+2®áþ¼‘Áauxš)I·)²7ÙN##û3Æ©«g°\§>µ¨9Að"븘ú1Æ3¤Ó4õ71opâHlXPôÎùÎ@gGªšõ.hÍÛìÍùcÞ± 'ckäêåùIÞy±ÞY#y4cn©Î¦µì ê8zÌÆ2Ãò†tdLÜL>¬"ñ3#YúôÓÚhs›ÁY—×ÉwŠ3&D’XEÖà‚|VÜKŸ}cã[¥y“<\°—gLíòNö7;2¼Tm§ÑûÛNPK>Ï–ÁV–¨m3¤hw¢W0*R<ÂuAߌ!ô*ÊÑ@_j‚Û«‹ÍãúX襄©múQ[bVÐ~Æ(Ž3>§@XMìhðó¬ïõwJK7¶¼È°`mÁ&LÎÙÁhúÙÞ]|y±­!÷©g-¨†ðW2‡=œÎ»œÃ¥,fOphæꩦ÷hŸ<æôT•×Áí<H-¯§jÞs™ÈR>Ë~Ãù|‹x€r.c1gò.5ÌIS÷†p«Ò3áF¶²‚»Sûæsl æ22µ´ð îe{:¡jå Vr‚<m\Í@ÖpË(e/p<£¨K³²"ÎJIlÅ“lF]Ìš®êzÎfMAi:3쳬Hï¸ Ò•¶+EQ\Î>ÎHcoãÕÔØº#S¯îQ>ŸuKb/·¤Uê?Þê!¾JCŠ/?#µWd/·q 金ó»ØžfHÉ„“Þª“è짤ñ¹©Àû¶ô\ݘ¦sáÏþstâO¹ú4[Ò igš¹Ù­šÍy¼Ï æWœ ‘KèþÂPžO™L)¥u‘éê«Lw`WÛ»¨«ÉMü„3(KMy[™Îa¶¦éǨâsE+;XÂ?þ.òJ…»{êìÐÁ<ÂT2Lg/U´3å©ïEN°™³øˆ·Èr”¿¥–}œÍ«ÜÈAfÄÎŒ HÌçd+gó\âµôZ1šù ú3‚É,¢ÛGeœ^z9JŽeýM¢$cBÑ7B>±ú.:ªn¾7æ˜7Öë9›¿­ãküC(ݘܾÑþ%úñ\‹æÑ78Hüƒ¹‡*6Dç›æš±€/¿(º’ó3~ž^°·Óã‰Ù%îÌÕSÿr5½œÙéÑÞàKMÖf\–u]äÊÄ‚ØWòîHºý›{XI˜»#q¤`ßÍørѪŒšÄ…Áö*§Rì§¢Õþœo'FSù×Z£v9T¡G“æZÙœ/$îŒÍÊôh3°§ö!^<¡gÞY#½vÈo‚u„Ó îi1¼ÖQ:&j:¨ºÆŸJßêBŽ':¼ÓêhÞÄ`H¤-Ò£¨2±»T®É=j3¹IU¥¡uÎkñëÈmý¤C¯ô÷CµבˆÚmÏ:ÞÛyͶçTDƼR©¶Lg›oçýŒ9¾6ذœ¨¿iÍÚø vY¡»}¹81?è,1¹Sg‡gòf‡éÙæ.îˆÜ”q ¥-Ž5y$rÖ@£y:x'˜ÀÍ‘%±w“ƒK .ÚÛFùNdLä¡¢+ƒꃼ“ó³œÓ[#÷FÎ-ª#—^³º$ ¿ÏZSç3ÍJ™ž8µÝ»¡[œ6˜É—u˜ò>ŠôPZT‘•›—ìì£HÏBæšAÑò-¡p _âYoq+÷2…Óè$Ç<æðvä|ù°Ùº¤¿¹ Íc_á þ’»y9•h­ç…4›-ËXª¸ ¼ÍXÀ0ú±œ+XÀ7¸™g9H[˜ÆÊGmº³ù=çPÆÓ ä[´¦LØý)”ö�Ï^äýôÌmcYºÔ?Äxvð à=vsïs1ÛˆÒWmHgT¹ŠgøO°.… ^–ž9å¬àz–‘åìtN¸•³¸/%PtI:ÏáÓ\ÏŸHˆ8;ñ8cx’c©ƒøXª_[§[FßÌFÓÊQrlçsqÊS/OkÕ¼ÍbjNj•þㅈ褙5LçŽ06Å~tRdð[¹êÊ!Àø´»Ê“Pd#oñEò¼BcÚèµ°‹/óKÖ3œµÌaûÃmYç'¦š é¤ïÓÆ%ü†çéK–é\ÅYìæ³¼Ï™ü‚ͬb¿Šœ’±'ˆø8«¸”¬¢Öu>ì0)ã<ÖÓ¹Œ—hà§]4¦³še„T ÚÈxžåî ƒé íIÆÑÈ{dxŠEÁ­Ála ­\˹)Æÿ<Úy…Þ|‚'‰¹Q´é=Þìúdó ›tÕÝØ›E_‹ü.¸Zq©Å}ü°Ã»«¢½Ó2¹¹ÁaÞWºÀ-»e{ûÜϳ;'†°”M#èÇÔd\y5øaV¿Äª³¾]¦)øtì…`Mw¶*? N¡.Ñ”ñ¹ ç·¥Õ•¢—4zƒ’D±è`pƸ^&Mì!WjRÑÈÈ®Œé%Ê{io·’#å}]ô+‘ÉéK:•öP‹]y#ˬ/:›“5³Ñ‰¼•-«i³¦ÆÕÊ"«kµŒloÕ¿Q±`w¹–ýž >Ëa~žØ¹;ÒÑ®­ÃwO\ª22³Ñ¨È€ ‰±‘¡E¥‰ ^IL(Óšs´èé2ß æ›²FthmÑ;ëÒXYÁhz3?MŒÉz³Ó¿ç&žÏ¹,8Q°²æœÛéH7[ûº¥Ó× ÍÙ™RbXÑ„Z…¼¯ÿq"ø%~™Z®:v´hhFCb}¢wðcùY>bRг‡-êÍHv–z£Ú_µ[)–i _…ýÕ&õΪ쥶Ýý‘•_àÉØ3f­ vf|¶à5úGJÓž?v•ŸoUd>U´eL ÆG® Šñ¬d7-tdϪN®]ïÊg¼2‰yÂ(› g-õ­+ Îå]z°„1ÜËSœÁ‹4ðò†'òCòœûFboGþ>vCð2W’ð}3“aŒ¡†ó&9Ê4ÞäÍŒ¯EæKSo†×SqÚsâ§<Ì—9›‡©e×ò•43-5ÆÖwëµ±ƒÁ]C°È œÖ•ÍÍk¼ÏidÈå<Nç-ÎÒÍLZµìf3åôb‹RóO×)÷/º¯&‡¸(u v9v»4÷^¥5ՂΦ4¶c[8ÌMlá}ŽQO:>bßc£ÆŸ8ÀÆT XÁuôá;Ò‚10ÍrÉTö§Þ¯ulIõ“§žDO_Í…Œb5Üžš&r(•k⛬ëÂòNªÙ>šâóÿsÃÀ¦4滋™t¦‹;,¥é$ÏZ/.f$ËœºSq{ØÌ¦¤›¨˜§9uϽÍA63˜£ÜÄ3,%ÏÚÔ«ø^š]–~ª6V…îõæ.VSJÌpF&ÝVóº ÈÝ‘Y±³ƒê4«¦Ž!`@ÚYÀ@:i¥“fq Òƒ <ÏnnMw›“ÙÌóŒc.ƒ#ëbïÒà’.Îï<zðEz3‰­*úD_o® /且÷ƒ†` bÓ³¶×Ü.ãÆw¼r£Æ{‚r&²ÊíÈô÷뛩O<ÛR©*gO°†’Œsƒgƒ­A_6$þ†b¬%±°ÚEÍgp»Þ‘8RLïÚÌ'Z‹Æ•]0¹¯+šecF†0"ãšÄ/‚b»EÁ©5²Úm¢DEÆôOV[9»àæV½òÞÊy)c`ÖéE÷Ò§FMÑþJßáêŒ(ïm6ó+2ö4·ØQkC¥1MJ«’w¸—áEúÖ&NL§go½ EýzzºNI»Ê>ÆŒoTd"G‚¸Äñ2G ÷õ~‡£•®ÌYØÓ¨œ¦È“C\UaM“ª*ƒšrQÖ›Uª²šsNI©‘áã‰%úPŒ]Áá`Jâà”XUKÃežì¥»KÚ5Å¢=±Š©¶5¯CM»LÑvî >»”ÑL)USeT^M^H´fL¶q#2²AKì¢Øy±uMr.½x‰×‹nh·ŸfdªÔ·+vØUi§¨ÓÆ6C2>Í-TÅšø àÖà VpNðZ¬.ãx°/vY0.M1‹Ç˜ËâÄüJýÊ5å ž"Ç}ÎYàªû“éÛõzUÓG:º™ RÖhÒ¾ÌÆ‰QÛuÁ#|‰¡Lç_MïØ)äceA5+÷1› 4Жxˆ·97Vëd"ûbçïñ%†1ŸfÊéÃônè³½ ‰l´$v0ˆ÷YÍ.f·n´tU:YÂõ)}_*þÞÍ`Þ °,e&ìc*;#3ccƒý)Ro&«YÊeô§7«ÓÝÌ»©Ä|«RâxBo1‡á)ÉéÏ0„ˆ¥¬8©�Lçx¬2ü/Ù÷JÄÇ陚צ:²«èÊ_žÆé¬O¡Œ¡ž­ ;© a*ýYJ̦4þâbª˜Ã>ÝÌÕéįGÚ]þ*¥&J9 ø%Lä^0—»˜Oea Ÿdïù¿xþ¤•i¥/Ç»9é‡zŸDŒ/¥/<ŸnS·² Y?O¼ÃíLg2ËØœ¹,_f|ª§ØÆ1úPK?Îa§ÓB ­©%í<Žs1}ˆØÄçø %<É)ä¹’—XÈd&†nÍú¾O/þ™J®ãmÎdsú kÐdÚŸ÷ÁF">â(WPF/–ëVÎá@Ƭàþȵéeç%:ÈÇA±£_ ~ëîyÑÒÖè…냧BÏuµóÁžØˆ¬òö:2×§zõ\Îsãw®´å û>Ç žcC¤.+ΛéöŒ/žˆ®|=\9ß•Ûíjq .qM•9½øC›O;9Ì à‘Øyô ~Xoh^U­s"ùrÃÛìlÒ'òp¤&±ˆÕ‘3ƒá±Ög$Æ4iíÐÊ îge0<Ø^bGÑ¢"å<CY­¡I bB›š¼Ú,˘[X0 ˆÂzærIámêbµll§*Ãë›´5ªŠì.‘TèdsNSìØ _+ÞdV‰ø¨G‚–`wÐ/+â‘ØYAe™w;\˜UÈû°ÓÊDKlD0ù¨û«Tùe‘íJZ5Ô×+žP,W,¨Êkêð8Õ‘ùÁ¸¬úHEd|¤3kd­övK8Üi\Ö mžBÖlÒVâüXi0±Nï65UÆEö|TP×®® 6– Ö„îËu;Ã"ã¹6²£F[ÎÚħè ˦fœÉEÆ'jÚb£"ÓÚ-)Î^1¸FÏ¢myK‚ävÅÄn£<±2øYdw…–ÃòЬ/sm…ñyù Ës?`UÁK¡¬è·‹\Ù¬ZæÈ­áçšw¡)EýWZ9‡ý ±m®;ÖE«*’CK˜ÉnòLçQ°7’K¢îx­¡œš*â®çTÖ27Ò'2±h?Šd#õl „?xš»ê\ÞfOj…\ÁœàO决¾ì âÀWp)LJµm]Ë ½ÙÉ(¦±Š/¥¡Ycy5%šÊáàqÖ3…ÜœÆme))ò ­\Aצ¡S]>¤õì¡“/ð›èÍÖ§†®œÆóØÊõô`Gä´ >)Š~<å¼¥²ˆcÌLC¶óY^äHšNr÷RÍ ¶Ò‹Si¢9>¤–a,äúȧbåÁËÌä 8Ds òh`,- üÏÔÄ2&Ó@Ë©á 6±:E5¥jŽbJ©?ÎÇÓí×$*OZéý”«ætHz iÞy’Ò½%_v‘#vñítQÙÕ„ Ö¥Ó,L7´Iš‰µšÙºÙ_] ˆ´pŒ•ìe7Í|+2*ëöÄh¦1žçXÍJNK/?c?[™M]ÆôÈÁT®dk̓¼Ê1fs Ën&g\ÏPža 91‹"O0‰&.`>ﳉôðmþÄNæ¦ ¢#Üéó<•á ZÙÇiü‚ª`Døå“ž¹Ñ½ƒ_"CMlpì‚ _‰áë;­¢9lÛé_^³h¿Úû¦§Ö™ÿ€¤lidZðdОwŽÏ<ê‡Küry˜¿ÎŠ£Î8ä®mžjšÿ•myÁùœKgjì‘5;8kÌ«Ï;«à@§¾6ÆFU¥Ž÷ÒÐîENÆtÅlý¬ 48ʃÌîkVžØ™‰ý95‘¹Áq~Ç—ÙÞ×à&÷צÁµ3h(u¸Ì’ž:ò'~IÇ‹r‘É9å Nd >h:5ÍìØà¼]= ¯3©Âà5«.jˆ4äºÝèÆKÍëéævûªÕVxT%íYSY×wjΙ™Öé´‚ ‰Ñ‘aAUF¿oç½ØicÁ} b=×9½Ÿgì­öòVýa +z[ÚìcEuyWáòý:•žPŸ1¶`mbðãØÝ9ﳡèÅzÓÛõHüˆ±Á=<ÕÃùÕNo7ŠcAe”ÝW0Ÿ!<Ælfv-ácoG. N¡š?g3ðsÇó‰óîåô؆ØÁL¥*².Jü1ä . ¶S½Ïe¹–i¯äïøeøåûn>ýcifÅ?† O,)LKüΎȵ/Ù³Ò¡1üˆþ>¸#üðWû;4gìïô<ß�_ æñ‰àxZ;ßä=NÑ­ª?æn7çItÅËM ŽÑ—Xϱ4ÆwFÑŠÝNÛi\^âÆÄCœÊyÌc'“©f!G#7dô мÏVÞe'R>á[´¥éPs€‹˜ÎÛTs khIÉ ×SÁz®a'ÄÖ22ãïÙ•îòGpË9H-Ÿç‡¹ƒ…Œfé)ÚÌMœËëiÜûz><~ÒAŠFFs£LéÊý¢•ÏPÆæR¢‘3ɰÍ4s*Í|œÑ,NW9ëÓ#z"ßäa©[ø€ñŒfw*Öè \È‹iù‘ÆöÖQÍûäù\j˜É>f¤~§„F:ÓðÁö¹´“ù,W'?é·ô]ÖÑ”þˆk©cšR$Ö’ã6Þ$I釟£Šç©H£¯'›®Þâ3<AŽn p ­TóDb8?å%Vñ+vóyjø^&¡WFúeeŠþ=ÉX>àE:˜Êj¾BÄ\*¸€§˜ æ]ëÐŒ›"Ÿ~ÉwI/nä'dù-Ü¡³¶›ïÐY⻉µÔûá¿xþ˶|=õ}{hŽ>³=<¯\oÑ»\£;Î-ÁöàNŽ%N¨½¹ç|ƒ¯ôÈÓ¾rÀ_ võ²K¾h÷ÁœÏoûúrOµ¹PÉ*Ã'8ó€—®¶x·¶ãö>%ï>þmS8ôµ`mÁfpvÔ­£-¥ªÜ9#‚LȘœ³:X9Ü?Єã’·™ÙU⢢AECƒl •Ií$æfèk`ΙuªÚõMôLîcl»)3¡—L¥~¾Å¢¼ë:ÒÓÈG·ÆÆŽqa¬¦ÉÀÄÔ%:³ ²fTê;Éñ¯w8·è3‘¡Nm4²Å]Y%Ëc¡Ó×cÿ”1±Ö¬Ó;XÑùÓ;¢þ  K+ý¸áY%Eåy§C•e|ØSÏ‘\­b‹‘¼ÊòÈL$“7²Q[âÎÄœN ¿ .º Ií ¹¢~ÍfL¤!¢è½Ú•è30owÖÅÅ w«»"/$ÖÐ;ë/ƒEÕ†Ò+ë@PûNÖ´¢…Á¥ ‰],â”#ËRª½SOÖ’e+=ø6㻂‹®,1?1$x©Æ9NíÐÈ}ÌÎ8=( jx4ñNp€úHï¬o$N zPJÎõùÌä~%wü:¹YØùÛ°·\ë;ü(cabªÖûœÕSÓ÷l­jÕnP>Ê£_×y'}Z=ÝÙÍì?ù÷²‹)ü”jv°‘ï“çݸ€Ñ5¼Ïʽ–ONÉߟg"Û8ÂÏXÄ7VTÁ§ñLât®¢È(ò—äù—¥ ±{¸Ž…ôà«ÌKƒBº¯_¦•=,góSNDýùˆd6£9Ê~.eßd›¹…¥ì Ê9‡å©ÿ÷q§´ˆÕÌåšÈÙÍ®aÓI¥hc—,ôe'k)ûÏ=G—qê1“ÓÔ5ôâ‡L¦/s„ÒtàÙÕ!]ÆTžaYª{<ʘÀ!Îäi§&­U¬'b Ÿd7;øOs7ò,ßæUÊS€êŸó{R)ÊÚtBö!–wå­ói6œ\o9‰D•ÿŸžü„TU1Qéb פ¡j[ØÉ±‹•d˜ÍÙL Þæo§º»#<Éý˜’Òò?ÏŸb·O0œ§8BõlêæéÙEo^¤›–H&�� �IDATJ÷Žç+<µ¿—Êv¯1:Å w¹óvq+¿áŸÒ+êË4±=$l''‚ú4г+¬eo§óñÍ"—Ñ\ª¡h�÷$¶ósª½Þ·â+‹ò¯8‡´3;r]|ú©aùOôc$Gb=#‡3 ‰M”3œA¬h®>æû¿÷ýew¤Ó5¶ÖDÉÁ‘åFÚÌŽ>»Å#?±z»†EnhtQÁE!¹`~XÛû;6°‘Ú²Ž&6EŽEžªUÓf%Ç"W5Eï3 rv°-²µÃ-µVvx.RÁ²`_™ª2;ó~ÇBÞãבc4dTä-jñVbE‹AÉ(–+=áÃÄàDoç-«u´èìÄ´à]–·È•95X¼vÌ9­~뻹LeÁÉÆÈ“¥Öç< ¥Ýg‚g¸"¨ŠŒ.×3cÜx§ç]^£¡ÍÄHIìp^]»NÉ{m¿¹Ç}*ãü>Æå**r}#«= *:•ª3¬QI“êXEFtÂW9ÆÅÌ-uI°§ÄîHEA?±Ž8ãZ®åw%Bì+eÚO¸— µ>VªØjIÐ)m—kñ¯é½õx$ȼAž9a U‰‘ ÍŠOQ_§WÑØ2³ûÊæí*º&XÕÃe¦ç½Ë½–SóL¤U]”„ÈŸ1‚e©íé¾¾Ôj1+; «P›s81žUAYÆG‰Rnî¦Öž•³g`6«iÓÕ÷9¾ùÃâ¦ßZÿSþ=r_W¶z_ÖÚeYyããnÛ.Û¡e–Ÿ®ó…¼0ÉÓx‹*fR[,åBÖПmœÇ©é6åÂn<ͱã_Nµ¼žé¼O]dC¤”a¬`hì+‘ùÁ&^âªz¨J¬®‰ý:’mœÇ³Ü@=kxœ½±ÏEž:˜ÀÝ™KY›© ¶s6åLJñ ]a‰EÆñ0˘á”|ñÕœM?>¤žþº¯“)ç«iÒÂ)©¹­?e}5ñ!ÓbMám’¤÷®Vã:ö¦Ôóþw'm1=Nw¤+´¡¬eõâciþV×�¬&uõîK¿ÊU乇®“çç§{Äaìæ›dùEª§‹iæ6ž §¤lÜ… ŠÜu뱫™Ëúé6'ô¡"8)ЗòÿµöÿÏrÕõLå½ô4ïz6pfÉ<ž‡YJoúp˜Ú4'm- Re†‹éI)ÒanžÏ0œQl`|ln°™Û¨åbÞê"‹§i•c)PIÌ[Ô28‘k·†‰å%Þ`?çRÃÕ©³ý7TÒ—]ÄáJ–1‘sùÏPË<ª™G·QHêgdm-52çizòØÁ˜ž¯\Ña9%<N+Eš{D32“CaçK—ñùpÆÁðÙÉÖFÍ›ÙÂLƹý—ÎU¸Ð¿]燣<±Ö–+n6Ð{¹Â¬NdoüÙ aø‡–W;sŸùë›3}'<6%zlNØ7›„™lâjf$æ±3ö1Z•f\Œ½ÌÀ®?ÐÈ«‘S#7eô¯óB“¿Š\ì碬»Êå3jãý9«RUVYÎ b¦Å&ð\ììÈÎRÙœêHM¢•cÁÎfûú:»É+”öò‰Øëe–¶ifVdxpJlrä_ËÔçæHììJý²ÆE^¨4¼Ã«±æÈŽÈ¸‘Â~%ÇÕå½”—É›ØXîHÆè¢‰½k×Relä@^ßg–)õ**ìËHÊÕ´y6öõf»+,kÕ#öNlJ¢>ãu ˆäcƒKd³ææ ®±®Ã™lF2>Y¢6#[ªµàæDu»áíŽx±‡ù&e /øq0…M‘ ‰§XLYG÷Àà²ÁÁØê ØªWðtN¦Ùöœm±=±úº1Vh3"¶.ØÃ¸ƒ}¨Di¹9å4Q͉rË3Î<aQª Ðnb ½˜AHücéA£KKœUëÌuQ}I´¾$bÏG»êâ†Ê°·Þæ3"¿ŽÌ z²£U E]~¯×?寷œ¾Fó3þézNrû;þîî3Ê®òÌÛüoŸsªTAUªRÎ9GŒ�!!!!’Ƀm‚i»mÜã€Û6v;bcc‚MÎ9Š  BBB9”c©‚*Ÿ³Ÿùpj{ä·gÍš5Ó½fÞwª¢¤ZªçÞÏ}ßÿëú´utæq> mzÙ÷øuÚÔ`>=Ø“O¤¢”±‘éiC¹6¨ – #3#}‚Ý,¦wp8´1dèL(Ö>gS¬&h¬á m�ÏnœB ë˜ 6¦ý8ø1i²lÉó‚ÁX†ód¢Ã(â0}8ƒÀ@Ö1*6q›©¦3ÝiGÉTl<QÎÙ‰‚|r¾¿M bó™@*eDø?†´ÁÝst§++9ôŸjÕÑO}RHòövÉ5(/çPBÓX’Ä{«ÄöR|Tļdd�ËÈÅé<ÏbzÒª£ŒN5ŒbøˆmIE¬Ni Šý ™!ÿÍy…VºRÄÇIF¸û?ï:üS®J’iÍÑï-LN$#ÕÉI5”ä,dØE3»É‹3^Ï÷—èËlæ²·¨åCÙÉ`vp!•tH»’åÉ®go²Œäc¾Áz&ð×r Ã85²,íÏÁ:ö³,ãŠØ·éÎlmÁo²†n|ÂÀÀc8-¥Wd_ð)—1;é}WÑ/Ö¿Åo˜Å <IŠQ¬k’æ–p˜Mœy)µ§o˜ó—†ª!üP×%Ö¶¸ŠÓvy½Òy~ü@fËõñÚÅî=ÅçøÎ.3÷_rUg¥G db°²Ù'Ψõ³¹ag±;ŽÕþC£ú¹ç\5_4]ƒwÙÁéJ—$T1†Î‘Ž‘·ƒÃïwtV£tЉ'èȲ@pLlE£?v4©VsZ× &kJ£þ)Õ‘±qiÍ<=PŸ®ŠÈÒ/8Bûàþذ•iE±ÒŒâÈà/i_O‹Z-¬0¦Ù'”1°«9 *x§£LΠV‹[ôí GZçœçJ;lq‹u)ÇÅzTšØ +]³67êÛÚbs©žÍ:Ç>lõ~«™ü-¥¼ÕŽF5z=2}°°×+ÍúǺŞ(ЫÌ1µ–fý=eE…ÙUÊ"]"qð`Ê´àsfd %+hQtL)ìkõZb¹ÝùyÖž¬]…:ÙbÃÛk×*«`rV§Vã Ljõ`pqd |˜uIlYÒ„S#]bÛax!´¬ouI}lLëëëä…áϸp…·f¦šÿ©l5?óÛÒNmŒ5eü{l4ïwÔµÅØ †éÝ¥ÓlÛYã»Ï{²XE?ÿkØÝ3ZuN0žã#åœáü]–õUÿVpetHά©a‘O÷GMu©¿öuòë·\þ¸¿”Ñ“= !¿9¶‡‘-A–þÔð ‹i$qQ쇱%¡-ç´†‘4ó8=Iï~Ìdso¶¨Š ȇ։˜ÍǬ¦ƒ<¡íFÕŽù‘Á–D ”GEÜLK¢AYDÃxŸ³˜M?ga²\0Í,âDv2ŠU ¢œ'vÔŽäO¸&óä!=O/¶s ƒùä"ΧŽÏ‰é•l'–1ƒÍœÌ©‰ØþxòÖóxLc'UœÌÊÄMUÅñ¬H’²¥dP2÷jÑF÷Ή©Ú8’ÉK|T×.¿y°ZÛ U:&Ëqý‚ãªj~u<?ÛyÔ'þã9üÿ¦Vý߈ü_?[˜ûŸþã.^¢åD ~£3×Q¨­Çù³È 0†KØÜð#6QȶҎ,áP¾åZàN–p6e±?ð¤X“lfôm=·PÇ<Ç/ƒƒ±£:ææqu¾‘­ü‚ÕÜÇÍ é«ˆÅl-®ãÜÄ"~Ƀ<–´­û3Œ½t`S’¤’—iSau ®l–jùe·xÑ1žïg«üéBOžï7˼p‚•›ø7?{øs/àÞ´‘©S®¼>vE•™GŠ¡&?mÆ{~6ÆCÇëÑjNÆ×.·ýò^Jb?Iòj# ô'˘ʉÔ1,x<Ö¾‘+k, ¢Œ>…þ8‘ñl꡼Ù}­•kŠÛb‡Ù”u}gD¢XE³¶ªkÕ‘[9ŸëØÈ5”òT¬{°.çë±;x ÔˆÃ¦|©Î ;Ð슠W‹n]4ÃJ éé�ËéZ©¢¯ã#?¨11èÀ´zÛrv×ø{Ð3ö“º6ÎËi_ª34vCA.ÈÅ>h1,Ò?í¶Œ?Ç6èÕjJ³ ÁðÈ—³î®RYâ´åL©¶;6)hŠ…ÎÍÙÛìÎy;§0v˜³f5¯Á䌯¦ LùIÎÁ©i}S*x3§´É§µÞ¥1²6òÍ´Š¬Gë|?gk/=‚ÃÁ]<Ãå9ûÙ•¬ô2.«!§€1=5Fm…ÙEeì«yíÿžó+ã6yp¥-7ê?^»²¬ÃMöЇM\ͤfZõã¸î²ùÛ@αc˜Ë®HYlBᢌ+‹-¬îþÍN}ËàÎñ™W˜”vFXÙlàçJÆOù¿Ë¿ÇðPb–Ú§~EX¶²Ë¬÷Å¥œÇœÂ÷¸,¥OÚY\˘ØV¾Ç`Vò5Žn Æç,e$K¸#é—ŒIé“–a! Å$î¥/SÎÍÔ3‘ ¸‡4çÝääA'¾ÅxÖÑ'ö.ßeïÒ[ùË’3¡ŽM”$¸Ûß²‹ãø1½YȽt¥„¹ÔÒÊ@Þb×%‚«k)¥–O9Èjx‚jÞç\ö±‘ XàC¶“åÔä<ÜšqUd4 –“YÆ«tã‚ä½A[®t‡¸ë¨e÷¼cöeö²$)„Y®£qBù[ËYT2™m ¨3™™H­nà0#¸Ê>Õ¯c=[Ùžü‘öñ »“M ë“_¦’ûoyþŸÝ®$Ī’dK2¿¹˜7.äz–PÃAFó ŒýˆˆRnbïq¯±C\Î\>ø+'ñwVrCìf%:«j>dßgG"Çúœõ\ÊØÈ2¾{“·µ-­Íf —ÒƒC,ç9æ³5Q_ÈWháMNa"s™ÊF6fô¾Å$zq|²Çyñ,yÝ0Yr~ÒQ,á k£¼$ìg¯EõŸº»ÁKûtùÔ¾\t{Q4mWæÄgãA;<þ¦u›­ÝÊ‚}áøOüôýÜ/;çLceFEs»ŽÓu½ßµØUîÖ¿¹l†ú}t¨ó½ÈCKbs™»¾<E-qߤ’‚§EjcOfLiµ;­{ÎßÒ¤Œî¬ó÷´››|+dF~ÛYk¡™‘ºH‡¬»j-qw…³[|-2)YßßBŒ¡±ç‹Í*ô|µy„œ¦"ÝÛ[Ѫ¤ÀÄzóëÕСÖ=õFÇþNŸjÙCúÇ>Œý0rv¤CzWí„H§ŒËs">¨ôåJ¹¥=œrDHÛ›ñ…È…±­NèâÙZ¿ˆªÕ®“â&ƒ¿L­höÕVÛ—‘MËF*ê ÊÙ¹”)+tKΦ ßK»t—í4TêQï‘ {¬°KÒvÒÔl; >.sQÚžuÁœà¾`bNÁ±µFПé‘c8@†³2R ­•ám:Zë§Aû”öiǤŒ R„ŒI'çL,.ý ûôr£¾d^K¶xvEº~a±Ù9›‚gò Š´Ã‘>Áýµ>L»8¥2ë9©ÛŒ¹BÁ[GjÿµEaœY¹6û£Ÿ|Gö(w­ÚYÅ´xu}”½;¥2ö¡K›ûUÕûµåŽWpcdj¡ß¤ÍŒjo‹Ÿð2 î~*¾ûþƒjæ²$åò”þ¹6}ÝsÔ2S™À ‘# ÁaçFJ’µ©—‚ÅÁ…t¡'#øœ[I±å¨•„;XÊD®c+9Àv'¯ªãÙÈjá·ÌOÖ•óN¢jÊcÓÉ|J_Îa¿g8“XÌAºP’pùòKn‡Áü*ÊéÀ[‰>q4#x#I:Wó4‘¦†%”p ó9‘&þJW*9[Ê^^J¸Õ\ÎØ„Ôƒ¹\ÅîüL!9u%FùåtM¼!ÙÆpîæ}¸Œr.â…¤§5•ÏXk§WÞsKC›¼m<_Ô9¿$Ù_¯LÚ-I;­5±XmLZÃÕûrrÿ%õ鿤ø§Ýé ­Çý?ü%‡ÐžÝtç0C8ȵ¼Æ!PHÌNâ0‡ÙH ÝH]ʃVºp×±‰Fz1”}›ä 1‘ }ïÄ>J†µ´gíy—»Ræo$ ás9–©b&UÑÈlçv21öN{ZlHÒó™I ûÙÉ2¦ò=JY’üËXEfqRÆ—ãÁY‘þø7¶OHÝ]R½ÜØ”ùÁ­ñŸF‡¢¥ Žtõû­VUG×Dz™{¶«Ûô‰Íã(ŒÅÓdnX96u÷ý¾ø¦[>“ëω”3žyÁÐÈ;ü«xŽ Bm-WE–FžˆÔVè΀Ro6ø¸£½¶–øEo;²ŽoQ«(¶7mk‹vŽLH© ÖðDÆéåJtV3«ÕÖFŸ–‘r$öIÚÐv&e|[œP¨µEsJ·œrF·úM³Ž)WTØYo$íØÍùÔMGÞHDyPŸö•£ƒO뵋­H)ŽTÚ˜õr‰÷û0kc­±úbe¬kòHg×’3¸ÀM­~•srl^‰ÑMºÑ…†ê’ó\ä½RÓ‹4¶£Á¿Ä¥ä"«SfñXGßm4¦ÅîÛɦ lp™”›RëŠÕ·ÓܤoÊ÷ÙÓjR“ýNš2FÄîênJ‹y9MÜEyZ?`7»ËŒö;Ôb.óÛ[ŸsKdTÝíìhñjä ´÷V©õÖô:gPuÝ!;sÎ(T¸Ú[767ilTÀ&Pä‚ÇùWÙRèÓƒÌYêº*Ã"Ý#z(úcüÔ]mÅG,͸ Ö+ZZ}ûc«ÛÙ?%¶—×õlÔm”Ϻ32XDJ¸5gGΫ¬êŠýÖò93ã¶å´K8H³Æo<¾›æZoÑ‹>´£ˆù}ŸÈ×#ÕA/SœR™4²‰3©åYº°” ŽýfŽç…ä–÷ƒôäêèžXO§1†o±˜·™FÊRz ŒäM©¤Ù5™ÏXÁ.*x*Évb3ûâ/üã1ˆÍŒç„æ4‘JNám>¡Ž!<ÄgÉguàL#ëé‘,ÎÝÆD<Ÿ¯ ³ÀaÞÉ;Wy—áteØMgNHfíy£|~k#¿›ö2õìOö§ðÉÎz;¦±=iÙýCç1*&jƒFJbXà å=UyrÐ^&ä›·IÓ¯Sòǰ†ßtÝÿËÕáD#}()°G?y­çuTñELÈ_VØC==yƒê(`;¹%FKì¦%-!EGާ3 á0§PK˜Âï¸.íê €­T1žaÉJå’”¼Ê)œ@5¯&Íßõùy�_¥„cy“eL`‰Ò&û8Àµ á1.c4s5/°”\‘TÇR*Y+uþûZÛ‡—7°6Ò=lîì¹qUGŽDEv†Åƒ<Þ ÷¢3{Dñ‘°­Tzµ›sî+b§)i2&¸?í æ ¹¼6m }›‘ÂÈiAS9…ÃDiç…6ƒTc»Ä-¶6x&å{ ~|­EMwërrGü–ÏZ=×ê´ã#ovЭÙ\Þ¤%gD³&eDü<ò^ÖØű' ÔWèZ¬G£‚ [±ÕÁÙÁ€œ š2Î ês:´ÓÔ(˼<ÿ­·ÊZƒ”2½\qW=jŒ¡}[c™]J-.°³Üäc;ji¶ºUYdO¥­uvµÚĽE&éQbÅaõÁóiê_dyƒùôëè@ÖøÈ'­^IùÝ@»<ÚdL…Î-f±?öBd ë•D†EÞÔ³$gðz05Ò;r Ð‚r{h¤OJvPì´ Ö]‚)AA‹5=\ïü S°šÁ´œ™•Ê %Æ7Gk“s–Æzd­jñqÆ-‘…±gšÅ ÖðZõ oÛ8Þ5‡ŒªMÿpNØ¿,68­,­CV'±ÑÄí6âXRYóZ<ÃÓžŠúWãÔÄž¦¼ê„jŸéÑ^TÒ+RlHà‚-&®òR~¡ ÁG—yø.Éï ¤YÎk|;!½º_=‡9–Z¦²•œÓ6¹®‹Ê#©1Ùôâ™ Úq?Ý’¾Yž;:ŽûC›—v«‚ƒ4%®ô›éΔç)Ô‘K^mwQÃ6*“nØ´ÄdßB>¡Kò «È‚|ÊåÌd; ¨Ñ¦û9”ŒÜNbEhÝÉ”£jÕLÑ%‘nœÃvÖs QŠä)?«~ÄvŽç Ös ϲnôe;ùœÈ©HÇ“x–B&&é—mÉÌ%Ï騙0í†&¾ùò$85ƒ¥s„+ØB ‡é™à*ò3­Bú%¾ÄéL ‚Ò$¼6±×°‘«ÂGœÈ>r d ­Lðíÿ ¸W0‰:z°=¡Ú×ýWuÿþkËUþÙsT­Êçkúݽ,#$Z³EÉbPK)‡sñg¬‰TÅÞ¦…zZÁhJÌ4û“({?š¸†Ïòôkº'víEÌOVù5¡ñt Ó™‘|ÆÆ$¹®ˆ×èšXÚ&s„Q¬áÙfÕ›ÇàüvO&kôim@ûÀżJk¡çXþ`ÂA…•U`Z¤O¬ŒºŒ“b»M^þú¼ËvøÓLïõ7=—êÒ;ú`jzÉìxÍ`;ò/˜#u-áœ`|Ú€ØÓ\ÊIÒHe^o‘6“b63Ÿþ‘tБýÚj̉ÜAg:f\{˜³y¶ÖØz/Æ&dœÛ9@ç”+ý˜ê¬c}c¯š. î mä‘qü‘ÙA_2¼Ó%gp³Âf#™2{kÜ‘ó*ïç9úAOÒ†6»•3H±­»¢Cv–ê[¨0Ö›â]b;‚ÚŒþC„HtÄ–œ¢"ªý¹Ñ€Øª^†7êëÑjõœÐ¤„®±g›4pNä©V§—*L+möRä’&wgÕrjÆeMJšu¢s¤WÖ!†8>èœÖ;v$jÌŸÚ ª­ÜÜ62¨KÑâ¸`@Z»à�£( îdQП_¶x-8-­KÖ€ØšÎÆÆÎÎ*ŠÚwµMîJ"ä§ó`ƪŽÎl0?x=VÌ~ìªUn_n\“žÕ~ÖÕC;¢m7wp0åxúFºÄ‚tÐÄ¡YÜÍÉDœí‡k<7Ãêµöõ³à]—Ù=Æ‹Ãiád¿]½¿6d_ ŠmÙï[à÷ߢ8mväİú1ŸïN¹62,èÄ&~Ý^ºÀ§Á—ã¶3îoTÑ—Ÿš¶?=eR´èÓôÓ·´úׯÁÎ`IšÏ; b™Á(*9ÄhÞ§škÙË;Ì"ÅG\î‡ýh®çΓ]ÂBª8…)T²•šI³ &Ó¡Ä=øJ°Ÿ®œÍ¿ð-j¸4Ù“*áDÞç<¾M­¶=¬&®:ŠãPüÈ,ç^çMR4³Œl>J6xbŒkd7'Âß">çjš9Äšd†”N>7_;'³ý¨³þ,%g]¾œ ãR4%‰uùí3N`5ë’KOAïÍ›%²ÉxédZØ›|£ÒÿLUÏ?Í,¡– ÍœÉâ¤éצVÔI® ÿ;†UÿåêèçP‚tÔw-N"Æ»ÿÓ%ì›<Ëa°Ÿ4×p ûƒiäßI'Iþ<àëg¼Ï* ’ˆxWþ7š8·xÙ\ËzrøQìEîâ5N¢œXÃ-¼Îfö²šS¹÷Ò.Š|ÜËA¦ç‰“ÍÄöÒ…-ÜI#[éJŽé¼Ê÷˜HÏq/²•åŒ`® uN;,ŒŸO®ç –{ ë^÷çÜ:Ðkýéeß^nÜö°hZX8(hÒs·ë~“žÿ¥Èi-n-svWk ⌱iƒ#Á6¾@¢Œcc•ü>厔òX·°“ìâ@ËcÕi'5±'RnÊ™œ6ƒãƒ¡iãzê]¯s½YX`ó—íŸ-w§³Œ«¨Î·/ÒS3NM›Þ¬¾UHy ˜Òì±à«\ÄãÜt¬Jû]½ƒýÍ®6<­[¤CµT°5öF‹Ÿ¶Ðj`ηƒzvirq½†&/0²A=UYÏåœÐ ÎjÌù<XÁU<_à1¦Ä:×èK.Ü—uU‹\Ú´ŒÁ•:ÔM¿`k¬ol³jòÈíàž "Ö3ÓL¦—AuþD3b÷µ:/gíÙ·å\Í*apâ {…ÃÌhòç SÚÎi¦±'øyÉ!ªP²Xë]ŒgsO·Ð+¨d6=é_ª¼ôâuÙ.£W™^aÙ-Quµ‘ofLiµ9Wô‡P¼ß‚»}í- ã,\É€|Ì6ÒݸÔeùS"Dßù¼-8·ýÇ'Þ}'ý§Ú.Oÿµ>;ÆÞqžZê¹5ž™²¡x‡ßÎóÄ‚ºàç\ÀGŒËz(«.6¾ !ʘ<B¡ƒ÷„ãW…]¶Güf›'‹8‰ç ü"nË¢a5k™”ÜÌr<ÄXÎg0Sx€7ЃSiÏ"›{{{”ª|À0Þb ‡O19.ämŽe�+dÁ$ÎN„¼w³ž·xŽ+8Žõ¬¢9¥weyBǘŀ$'ÚBšïñ³y„*Ör6³’4ÂU m'ÏÍÏ8ZnŠ c9ëØÀžI\Hõ\Á&¦1‡WÍ1Ë 9›UÌb]2¯ÊóÑW$ÀÜSXÏÕ”³­|—ßÿséÉ“…õï3€åìçs.áú&æåÛèœx3r죖þcx.ÙŠÜsÔÿÿ%Ì#4SÈ5ÿœnúŸ \u wTMšE=MtåÝ’9VG*hÏ ¶òm*¶õËŒ Šf&³€Ï8Ÿ›SŽMy0xŸ2ˆùt$ÇË‘Niíƒçhæyº¥}%2.8'ös¶SF+(c ³iÏYlà·ä"#XIUÐ1XœÙVäØb¿`l‚6ÙÄ=‘±ìeEd|/ÈE²ƒ+8Ñ…Zcëø“–qÞ™î[Ë5í´m|þ›“3¶4†�� �IDATæûßtõÙéš~QÍœðx‰¿üØ…®æs¥<~»+N &ïsE‹_×Îc‘s'‰¹—Þaèw°j;~ÈhÊcó˜1'8HA0?ï4aM$ÇB½röÅþáH#ëTòË gw{k­Õï×½ÁïÄc‘3£Æ…rK¹ˆ½Ô3!ãØà‡¬)4–±i«[l-Íx«“iJK\_bK“Ul¡­ÍîÊ '³Kÿضà—þ^¨OWãë}5ãÄØÊ^ÕØÆÁȤÛs~’vFY•Cć쌜+ èfR½albGÊí‡ý½Ð5 þÔ:9­¼Å¦”¡9WµèR¯;¯SE»Ø]iÓ"÷XŸrrÆý±vEšÒ&¦„Èúà‘:'q*ÚK³ƒÂȸ*]bý2ÖÆ>Št`Nä—íü™ÙÁõFÎ ~ŸÒ+¶¶»“êDü´ÈÒöÎ7£¼ò?Î.Ÿ®ž•óÅ‚ý)…鶉÷-Onš¼"^ô½úYv­ýOUº883ëÆØÓzìw[Stërg|Eú[¢wNgóèTa@ôÌ”ì /ù Öþöfw±NMNÚåÝ+â9›ê¯œoÞ>5ÃÕ]ä[O;w™w+ýýÿr ªþAÇ{“FzA_Ža=Û#ïo›©õˆ÷—ùÊAEãõ\çåãØÉ±Þ¼ÆúðuV1–wèÃËüˆýÜIÆ3¡<EkY¯±FÍ+I5z›™|é•q~¬'‡yšnIV÷L.c+_â~Nc9ÃØÆ4ÎãwT²9Òì Š¯QÃ÷y’u\ÀAú0™{©æZèÈu<Àël Ÿ%GöuÔòz¢…¼Š"¾Á#‰Õ©%Žçj6r€˜;YÀß‘Põö³‰@wÖÓ—Í4QÎNR¦ˆ >KF-ÛʖĈû¶ÖWèÎÉåidä#ÒJÆÐWØÃHža-¹‘õÄTr,s™Ç¼‘Ôª‚ä$_ûÏùU»¥ÿÓÝ®FÒrÔþþ¦D!z‹ÏV0”>tæmF²ƒC a�Ý™É 8Ž5ìa8»ùEðXh#TП‰,x½C›÷:W½$ÓžLc*ã™y/e|Ћ\ÈZ¶ð•´¡ÁË á0ƒùŒÛèšœÑ ì¤G8À‹iÓ‚v ¤¤_lOJ†)´ð–°®\ÿ¬_Å®ä\R^ïãkˆŠÇ¦6”…iwÄ—V»¹£œàpЙ©ä?˜F±Ë7Lª/»ïªfþÎðÈá´ ƒA){”µ·­~ü¯Ã~»PuµŠÕ¶æå›â®Ùpùâ¨ùûWÑ>Ò’R—RÜÞY¥J›ì žáS¾Yçç)C#)=j½N—ävßÈ_¸5%¹>øUBÛ<‰ªXÇ´k‚Nu }©Å ÞooK¡±‡¬ç”XMƒei)N£»Rzf\ë½Í\Ž¤ì †Vúr­?âÂE¶·Ó-X››˜V;’ò­”)%êZ=|ÀÀHÇHÏŒ>±ÕÍú—[Ùä!.+U˜rYêz["£‚Ö2¹f-A¯ 6åø Æ^V°TMsäÌVSÄÊbý+œQo0Ë*Œ/P–Q›²­Uš…t%.7§Åž W¤¤@ûX ¿)ÖØ¢.݆bÙlËy:ßñ.tZÎ6p\]žàñJ7w<{ûàœðüø5W­-;¥E:çýàÃ`[죧³?ҾƣioÜì™;¢û®nò~ÖVÅE¾ÜËÔí^Xðã{ãçùs7;5½n*äÍñMrY]ôkòî럼~Ä®íg×o´K½ôpÎ={z§½ÒÏùËÌ|Ñú1Þn8üš½ÜLÌRö±•_Sĉ)““øÕü€Ï½=ÐEoû×s™A!;ÍjNç�¿d2¥ŒNÆQãYÉpÖQD+¡?s©¢û˜Äé|•÷hJ„Oýc÷Q™ÐZ?NÚk[Ù@o°–öÚà­Ï*m©ö-_Y‚;HSÄ&ú0”¹ŒgkÒ1ûÇ3ŒbVÑŽã8}¼C ²)—%\Çù<Giž_&²‡BV²9Y_l-ŽH¦GËè›ÌVÚ•mêCæ°’2ŽO"½ñZBp– ÿþ„ÍgX‘v~ð ˜B-Ï3ŠRÎJ–±O£=‹)a0ÐÃÉ}k(£¨bÌQ±åÿöç¿»\í>ªV+Î3»¶'áâüúûbÎ`z"i^J_á )ä,îׯC:ÿ¨žò4>M».xž {ØÂIL¡ë™N óØŸ¸×Ž$×ð ‘v)ߌ, >bbÒØä8—u|À$¦å¯I𢔿ÒL{ú±*XI=© ŠwC›>n KéÀ¤&XT&ƒëñ¾½.º¤)tšàO½ÕÔpˆ—µ!þžf «˜êñ‡2??ÒnMÇ‚vl¦kdud{Ρ ¡iÌ*söyø2Ÿ 5l±“«=Ûá~ü¢“>wdY´ãFûêSTº©IØövʪµ¹”qA/6EΈˆíˆ½À9<—\òúÑ‹ÁË `§²&ÿ"t`K“†ÝšÕÝš½Ñ¤8­2hdx'íÌ sojõ ‚ö´³§½Â&39Рs¤&2¥BéPGËöûrW¤to±6XI 6z7¶ñ4˨é­S½Òû LMTèùb£ëÈêÄ1±‚f÷¥M >fx¤Ÿ§nZ²s¬¯åÅàÒÈà´+b3;6£Å'œP¤)¶ Þ€¬J )M™Õ¨1ØÈãi3Rº·ú3'µsV‹I[óaÚ$ry¿bÊÉ”tÒ­IkJ§ú W Û?î×W¶4”¯ÜSmÏÆêbŽ¥cƒÖØncÊUîñÁA…‹|)•¾ï‘ÊàWn{WÓ>‹Ê,èʪP¹Ðø2?n(WžÕ9+¨awZ?ïápïÔšk"Ë‚G9ÇÐŽközO²QÃÕáÃQv±s'Duuég…Ùó<{e—·3ƒƒôç!zå-wÜä,zOÒÌ¥ð cÙé½*:òfS­b;-äØL%o’ážeëYÏ ž¢1A`�ML£ž2ÞgzÄËwìóLôÇÎ1ôJ*AG¾H3«ÙD>£–Þ4²’.ì ¯SÉ.fðrbhlN@æ=´ž²#»Wð21g3Šž¼Ÿ\/†QÁáÈ÷C›“(ÃxQš÷ƒpIÜI5øé�.äqz%`JБQÄùB˜L 'ó>UÔÓ™=ÿÌJßpT­Âðƒ¸<q Ç²Š¾¬g&j’½‰á|Æ.&•¬2æi/ù!H9ÿygòúrõŸŸËXÉçÿ¼.“÷E\•ø›{³‡ãø8Bo`sx”z>O`'2‡!ÜŸdå6q'SÉ|2•algo0¼ÉŽãaR¼Ìé,äXZxuÜH'R|ÈU‘ûÓÎ ª™Å[ä’ÅÅ> j=x‰©|Dƒx;Q|.eOÚe±yœÆŽ“}Òšv¡êKÞžfï�þ”ä—ÇgÌŽ}ý a„ëßÉ}ýªf™L*cBl‹Cþ‡¤Ç0ßYäÏ—Ø\iÕ<×ë<ÃuVÊ4}/nÝïòåaSkçqz¬,k '¶è΢¨íWOÇŒ/õ)3ƒÉ=t;Ò–~ŽM–<ÁY øªOÚx~‘¿/´’áž”[2NÆÇJ‚Â2%/å Ï)+³¶›ÊÞ –i±§²–rg2)(lQP«à°M±9=cÍ9Orb{_(öR“άf:¿åí KPÞäáVÝ" œrD®Õ‚&kl+0&Ò-g~óDÐ7ÒÇÖq6¥4¾Ë·IÙ´®Á½9¹Vcifp“_´¸$ˆ‚mtLNk¦1cp°<¸¡Õ†à‘Œšìæ½´¯24´¥€Ç±>ÁÛüKÐÂÀ kÖFh-3gÉÞË—§>´÷ Ï´~Rëœ',¤õ‹ˆ•Óݘóëó1§™5¿bá¬àØìï¸æ4Û—²9ø@å¥Nßå‰3è—ÓLç¾ÌÃ!þ «}i¯…ùãu‰x±Okhã Á½FŽ1ê=g­·ãMÕç:ÔÓ‡ûlš¯q,C9…A¼Âq!3ƒ¥YŸ0‡N\̽_Š•%²ž)œÄPêÎ2fòµ œËx†%4‘ãv†ÓÅÌ¢™Q •.ËÌ$ô˜É`&1”ƒ”°1i—åÃLèÀ#G5©vуž”0‰—iNÞYóë]U\ÎÂä`ÉçjOg"oQÃØd—!¿;V—D[Ȳ”Vm=ÒÕ4£˜O̪h K9ÀÆäK4ÐÄ  …vIÒ+·˜Î*~È£d Ó_TŽuœÁ²D²ÕüŸNÚ/%v‹‚ä69™wØAcrxÎä`�YH}ò[9À¥|Âp.å=Îb-X¶û¿l¹*f#…ÜLÑQÛ#- Ï"_o±„\–ž@);ØÃj¦ò5–sXȼ¤YŸâxšX–\Ãðóhæ‹yE,+YÁÉG#ƒØÅ•‘Ùô£–j®gQd^ʸTû%éôÔTG6¥\üš¯%¨‹ƒ”D©óTž ±•§¸„¸—~4§bGÆ¥±2n‹}Ÿ“øC’gÜ éAÛÆ:r˜NÉ w*ãc·'¤Ý*»˜ýºVóOñBÜmžò+¥6kn¤«Õß¶3ãQò¢Á ©‹GöþÍ]Q¶CãÎÝÖüÕ˳3«o•}=ãÚ¿çØŒA¾Ëi¬Êô ~^êªb5¹½Õ¥9¿IûnÊW‚:&Gºó< œÚ2gwÛ"߈¬ÉèKsg'Òî¢}rrÚ•º±Ò¥Mulµ.«WÆ´iÍFPVæ„RcÍd ÿšÒ-Ò¥ÑÞXš‹Õ½SŠcC*ü¤£³«T¤ †G†tò/‘§ZÕÍôz£rÞnU„\[´œÐK‡zoæü½«­¾žó>?Qý¦Æ|Ê{Uü5m@ð´/Ä^ce‚¯|6mZ¤$ØÂwcØGs,y!ö8¸>(*Г²XC°ºÀ¹±U,Θ\É„d$ð\Ö)5igÇU÷xwt¼ðê½ßýY¸½¿ÖvtˆüEAAhÓ_ÝP°qrÜ{‰ÖµÑŠHßjf}óü±Ù'ë+SU­d"[ø^å“ëþýíŽÉ}°<´Ýé70–×E'_bÜNon˨ æeš¾ØèÎW½{¾nãÜô¨–N6Œöëu^z[ƒtõQãÈJ8ÀOµE»nẳ*ëEʘÅcüŠíiߎ-áý)ŽtËhŽ=œñ½àJzqZ‚OÛš»ùÖßõ|Äf_äϬåô´†à*">ãé¨MϱŒM¼Â¼Â�~Ã:Fð‡Ä0>‹ÏÅç”2˜ÛYMydÏПqìàß {€Æ$›Ÿ¯73‡;i¢çF=9sx…ƒ §†*Ž0™A¬a='ð"ßáXb;ÕGÕƒQteUy˜'{˜ÄŠäEç}mIê<•{›ÂN¾s)Ó¸†(YúÏûÛÓÊafò.-TSÍ碉¯$ê¬ýIj­–ÍœÉfnd! œÏNâI±ŸõTp!‡ÙC%çE6ÿ_­\MOx‹Û(`ÇÿÙÇLåiŽ#ËyÌL²ry4ý$Ê8È:ÑÌ q˜QƳTÓ¹ aH¢>‘7yUÚx—g°+™Wq[FXJÆÉ¾‚â»ËgT•}wQÝÄ¿XtOªå±ÝÁ'¼ÏÓ´ç&.|!}zu|ó»6Œw(Ã*Ö²‡kx¹›ò#zÆz'ÓÑ}cf²+õ;šYÎ]ÔFÆE°8ÿcœòHcxò—®ïªú«Ôq–‰»-Øàø{ úXª‹AÏ+éËxŒÁ¬0ëÙ.5ïŽk¶šÛ â3ʾ–Ë®Ëz&㆜ž‘òž:g­jõiZ}¯´z€âÈ-9ëZÒ/ëcö§\ü(x–~ÙØÒȵ9e+c¯ä³)Ç´³´Å#i}#úòAFΡ ÌÞ&›í¯Õ' v”æÜÑSAÊÎZ-ì)r¨Pßœc'òa‰lr·÷£f¥5WšØÓÐÃÖql•±‘Ý ©·©Be;jíÌz¾Þ¬ NJLYÆ…ÁÜÈI {Uë‹ ÒAßà/œš66rZÐ\¬2ëE*b…i²®J4¬%Å. NJ«Í*Ï[(ÙJ†á ˸2Ö)2Šx Ð¨RŸ6YMX1ŠtöÇðÃÈÐÈM‘‘”g:œ¦==n_Ÿx×Ûá…}ZË8ßfÜÈâ|H¶Ä þ¹ñ‡z¦üjgfפøÍ“õh _Z¤y½vjºœN|‘Ÿ×ÕÚ0Ú€ïâ!¶E~YEG¥½=ð´‹B÷~ú±%ë7–VÊ5({ÔU[¢F‡‡x´Ø±ûü`»¿ÌÖM‡Ì ºp O1‘žœÍ&&æ%þL!]¹8¶/e@dmð,é{™É±õ<Éîf £èÍ>¾ÉQÂJø=x“‘y o7×ñ8åiƒù<í{±WÙC{ø"=8H37ñ;ö“£ý8•=Ìábÿ;{÷]Wy§ÿ³÷9’,ٲ܋ܻ±qcŠmz7½R „&eȤg2IH¯@ )ÔÐ;6qã^pï½w[V—ÎÙ÷ÿÅÑæqfÞ>kžYÿyö;{--éHçì{ß¿ûº¾_wpK¡ •uZâC60’þä¿æ6ó ×§'Ý97­sýƒ~<>øeQªI¼2Eüí¥œ‹ L©Xï`-ã–Öªú2‚¬©éº4øð�0’ÞÌ¡œ˜}d¨åZvPÎ ®c¿–ÃÂ1ö%ªÉp8=v¹‚ÒœÞ\:r9÷ójêÞÏ�ŽÐž˜Ìrä9Á1ú¤¿ÕtdƒSWF¡¶5#Z4üw®UÿýËÕÖôwz줵ꬓÊÕIúúwp"5(v‹u£> Gv`1{y•‹XCkâòiü¦0#¾*v_ì²à/”3–V)èûlf­ø EœH¼ÀQš¨äã’o>ÑðПj—w‘`逸¦wðóT1ÜȽ…–bæÆòc–zd¢a/[+­‰ØÂklä/¬'Ã1¾Ì|&“ã,Fð.軃űÓ+´Àž×y¯Èe¹[÷›ÚÃñáLtÞj}×óçûÄMƒâÉ} ,÷•Q~^ìÒàUzFÏlˆoû\ðŽ1¶ï.©öd³÷éŒŠí«šáºbmŠ½ß¤š£Œ¤_l@¢½‘QT%Vr=%‰é­´.’Í[šøBJ²šÈ·µ¶Þ¤`]Ðí¨òŒƒ²D¾ƒ¶uZgÆvG›²2íÅ»}/Q—7!XÓ¨sƒ²ÖäõgB£µMú&NtvVµyl®•$F4¹«µ M6gô­S›1"ãHÞº&§QÖÞÈ&í"ÝṴ̂ kdR¬Kκ¶ÄÆÝbo9†ù _¤ª#2‘kbmòÞ-r]+7;L»¶ŠGŠuoRM/*¹•A´es05Ö5²€+87gFƒ6DŒå;bS ùé‘òȶ¬î¡hjþG…ß/rëôúX¼äâ`?ccÚXßdp¬¬µ8oY“=Gœ°|°#Ç’Ÿ=*_®Ã~¿è—½­À24›Bc¶Î‰¾6­b"Gcè¢x¶;·š’ðÕãºGú#ߎŒwG*3'Fúsedµ7ûdÚœæ f1WÄʃ £:~ÇbÆr*»‰Rªw\8Ë ^ vñ5"³ˆ3ÓÊÎbyƒ‘)ý2þÀD>àD¤¶³»ë<@[–Õ´@1VM¬M¼š>ê'XÅ Z1“+ÙÇ!Fójy?“ˆ Þ 3s/2ŽZ&Ò†t¡>-Ï|„êšnž ¥Å g7£tÒd¨Sª‹\ÏñWvÇn–Ѓݬ⦧Œ‚ÝéO51ìe 3˜ûVgi`­i¢=™CH)ÞU¬$Ë™la[HØÀzPÆú³–Ö,-¸UÁzNgGX}RÑèö²œ!i»k\ŠöØïÀõßvõ_¯N”Ò;=Hü躔ƒT²8r>»9HWÎb>l¡:v'XCûtri'gÖiKEdkDh9Ò<> 4q>¿àVjxfŠK’rN «w{ë‹õ>æoÍÖ_ü‘.œ“"÷±‡=¡÷¯ -·b®^­>Â_³~œ˜ÂZ:¥°ƒc)Ò¾á6щ™cddhP©H¼Jw[bÃ?´Ö‹mºÊÏ¿ïž]Þ8ª¢›ë‹®~>Ñ»cä—GZs#3ý ãé+Âú¼“qÏÉÕ(®×¥Am‚·‚æpaÞ”&›\@ÅDƒÆv6[Ÿˆƒ‹ M—¬«Ç3v$æåå6†¥%„ãõªcû#—ÅúÑ#Ò™—‚ƒ5N æñFä[‹œŸñvƒ«²®Ìë|ÈY‰= þ”%žàH¡ÌxÂÛ÷'fvվƜ¼ EîÍiÝVûD>g[³Íõ ¢XygíŽYiM×ĚغØÙÁ³‰]<ÝʲRã5ïñ"×S—Q4×;YACäô`v¬w,ΙK‡f§'Ž5Z@”5´Ø•mÔ5éÈ‹”FvÅ:u6(2,14±…µ“˜]áFΗøBì�GC<O×*¯Ýäµf{©Y­ž¼Ã¸ÈEf7ÙC·¬LÞ†ÐR[üЇÝmÛ.9 ¬¯±k½ÓÁ¶•|:¥¦ÞQlCÓ¡‰†×~º=g}%ñWÐSè¯Õ ÷.U×ÓÖñÁO8΄®2lDtÎ’$óa´.ÕÑåì™Ã€`‡8DÌdæq* 2`«YË1&БJŠÙ”ξúÒ‰õÜ“|œ~›ÒÊG1™@ IŸÌ)ѪÞ|ö±:*XOHÑnãC?V§TÙƒœÊ DÜJ5ïs#ý j+úÓÄû”g\™ì ‘Ù©i0žPSy!&ö>$ÏHÊRnÅh–q‚kØ@#‡ÙK5çñë¬/XÀ Ô’ÕHÇÓÖs!T\ÊYD¼NW†±'rYðË4=Qˆ2ÖËÃÜÀFÚqA 4@1!õt¬MžÝ âíâWÍ .?i‰½Žcé„Ð?׳RJƒ4¸ØrCÎú|òŸÿóÝrµŸæ‚ÿϤiý‹©b'Ølä�Ÿà9"Ž2–eg}ð!ëù99NclÞô¼kØì+]Wm ¯e}*˜›ªßñ,Ó£€ùÊúvÆ5‰½¬g�y+ÿjm£-·Û²¶¨þÖ¤ úÖÌdÖs9^³ùëžó¥Mñ_ÆDUg³ƒ³)¦]Ö‚çŠ<™8óXÁ\ÍJÞ` ¯s4vyäâÄO¹$È3…m,0`mò`E~æhÛ†82Æ R7ÀW>á¢užÚæƒF¿~µÐ=óܳÃÐ-Þ-á"¿ù‡/^Àn¤6Ø,̙Ũ¬+E¼&³8öÝØ ÁèÔøõdÆÁ¼9/fÝ“x(cýƒ_´ÒÜÚ55†fÝÙÍàj2úDFžëÈv“ØOeÆðÄúÄ CF%]ŠôHì+7¤H¿&í5ùZì²DßDE‘1‰ ÔÒ*ˆ¸ ) ú5øÓ©hçòFI“[›ef^sÞ°¼E±n(6¾Æ“Í®k¶!´¨.~dƒÌç´J=O˜—3!i±WüŠŽüÆàiösG2†&¦$îÊià…î&Õšž÷U&EA·œúÄÖ +dôsrªçå¬ z‘çƒ`,gøaÆ%‰?—p ƒ¿H®¶ü.Ë#ËßÈ.ÿi²ú³AelXäÃD&=y˜UÍæŸJá¤cécíu–/³ákfõöÙeÞûd¶~bâ»tàš`d¢Þï‰z[½=Iߌk9’ïX½Êö®ª÷+½T¯þF¦RBkÞ }Ûúᬰj® ˜áÐpƱ„ëXÌ]¼ÈY‘ŸO´Nçw|‚+èÀc,¤5½x’¾ÆÜT8˜Àï9ƒ±õ(×Q™jN/œ² ¾å©´ª^ÁÙôã!æs5¯³žMYØÓÕ >ÉB6s;븚Nôb}™le@.Ý^T²kXÆùôã~fsœ/ÓÌ*v¥‚òòT wˆÚ´ÊÒÄ–®ucrÚ"­æŽq8ÊQ¶¥î_ÓƒƒÁ;éôE&¥ÆÂ1Ê^¾ž~lçòï,£=W±•wÿÙÌ[ýÏY¶¾™Ú ^ˆüŠ4ØõÕ¡™æU|t]ôá)jÿË~ÔîZöýr¥`ýá¦RLCŠa>œþùëOjqwˆ´æ-~È*¨¥#‹iʨŒ¼œóA:§ªã5a-m2Ž[¹•nÔ0“ºÂ›/Ñ:ñ›éÃ~nä #íýƒú‰‰‰¼ÊíœÎóLâ)JèÉv}Ë›·;ú» Œ[ø7EÆ$:ðV¢`õ^Ë•<Éæ}Îg#‡ƒ}¡±1…Íiz¯õËVÞ?ìòs?fo7Foö¥Õ®\æ{?±å“Þ鯟õçü¹^îr¯¾æþi%û—øÐM‰#‘¦àt¾Ël¤Kbwäå¬{3³¾ôgQps°Ž, ½ Ôüœg#ßNTÆÆEÎKìà”œÍ .É’øLµÎ±ÚH» ë.;CËú ËO‹\”x+ºÄA*š|Ðh 5Eîm¥¼Òî&ßmRTgMKZ2WYΥ옗´á>>`lï°4±+2FÄºåµæDð§cN¯µ$–×1 ’DVïpC…3KÝÓ¨Oç×›x±d¹™ê"_Ht¢=ËŸå³Le:™ZM_Ìùq°nÍÎà•XC°%h]­<Ñ''Î;ÈÞ"g&í¶D?Z-ÙòáÊ‹ƒÑm\=\æ¨÷Šœ›qa±ÊœâŽnH¼œwUÖ¼™ÁßèMŽ›8/ëóÅšój¸?ÒuIð#VEuóí}?ûÖ/Ã3&ïÿQõ•4p<‘såL¦ûÝç…/Dê³äÝ´c“æ‡ìýWïÝ—ýË áéÅw—Y©nwÊw´p±ß}ÃgúÍk ñîj^æ,¥ž±|@7–gЉâçÞ�� �IDAT¯2’‡)e._§/íèÊi)ü�»ù«yÀú¼YÇKÌa(d*çÒ‡…ìd+½™Å¯ÒÚ&²—ÇSãßݬ,8ÙLwò`šü÷ÐÀÌ£'§°å©Þþ~žá÷1‹}Z”%ßg6ù Ûh`(I‹·\Í,¾Ì*n`C™ýŸî®4¦Çg°‰iZnu”rÌÃÌ .m"oçhJ9º‹%¥šW©¢+˜CÌý,çÝÿ‚j˯™Å9³?mï#ðñ;>œ‡ž¼ H‡Çx#¥ý#ñ$g3˜Ggò.÷²øŸQæ+Oš+þß¼\õ£Gú t5ÇS™!Êé s„ÀŽŒÉìà߸€JZó=3#hÌf÷QÉÓìâTJÓüå&Zó!ÅñMz¤yÅwø ¯§ð®‘Ô²¶t%f {x¶ð&Ž};˜C'N¥W”ß * U‘Í‘’àŠSÜÎt+ù'jC_å n£wz®{˜QÆuõÕà¶Ë¢v‹š:Z·…g¢ÜƸ÷7Âè—ük¹íW² N¶G¹¢ë'lÙãWøã®>‡®>¢ŽÃ±˜|ì¬àï\ÇœXeÆgrŽ38±‹÷¸5<éXÀGÅ6EN Æf]žøbðn°—ǘÈul‰µµ¾Ñ5¥·%ÚåLãÒ%#—õÅfë#§RÃŠŠ¬håÜf¿' ªòŠz¸IGúµ3«Ô—tˆ´‰-ˆ_âHN?²l¦½»Td:ÿa6 lãxûë…Äž;9·ð'ŽlÏ›ü•;#µyg×;,æ‚àÙ ûc¥A=%cP¢3y¶xBÝ[ã=ÆÓ“¸>V4s?¿Éº?ï@Ч"{:ú—F=‚i§¯D'÷þ>óÞÎ?bÎd¹Ñµ²6‘k´¢ÎÑ2J ¨÷A…ÒzQ½þÍÆQYÙF6¸2QÅ bFoÛª}"Q·¹FG¢ØýA¶$_–{»µÏï4;°©Ì%y¥á”ïëy¾éC¨§gb;J•¸8XÅI}’{ÔÛ_õüŸ <ÕÔßsœ( •Qî1ïŒeƒ èÁô–ú„g¹—Æ® V“¡=[R±E.õÕNl×Â?|…÷b? "Ú‘ÐŽq”Ñ%·q6½ù!‰Bæc'ËúÓ‰8ƒútgv§Ðžç¸œ‹øGºyE§1Œ+¹6EŒOa(çv^KÏ>òEœA_¶ð.e ý9@Ú1– ,IÛ1ϧäÒBŠê:3„êTÔÀ^f?³ tLs烨b1³¹‘„38N#gQM–/ð3p9³ŠûÓõì4*ø;ÇÒÂÀG»«¾|Žï0ŽTPKÝR;Ò‘´°¼ž¿§ª°»ÙNþ|RÁ¨‰5´¡‘}\Ë^¶QB[¶Ñë$cò¿a(ÍùŒa‰Ùþ´ÿ›akÆnºÐ3x›œÅr¾çÿ¡¸>ÃTsodyìŽ`-t§K!­Ä—2þÑÆeY7F¢| c¿ g „ý­0¸©åPw1}ØÂ•t‹MäÇʃ½\Å;d}°„˙»YÈ'3Z#YÄ5Ô3/*¢'ïÓŸ®÷ "ccŸç<¥¨½÷ª£¶C£ü¢°sm¡•”°#³øþp¼#? ÆFzÐ-%vaø1mØÄYÁ&Þˆ\È 6Æòye‘±SƒÀÍü•n í¡‚Ï݃Ö,NŒÌ8#x7ä™9Ô·sq¹„¦D&ç«Ýµ©1'V¬hg`“2¦ë3†ÇK¬.Õ¹ÞzéZ" ýøI©Ÿ·*2‰©±K[ùG½«L§ï0Ê­JÊö ‹-ê(>æ•rÌË»§Ä bqÎ9,ÈÚUjB“Y4Ç&·µ·^vñbW[)еž`LzˆxϤݸá½Ä‡F«X‹—ÙÝè Z·SV×’ ÈFZ×j J#Íy9ú$gýÖØ}áͦ·÷©µ–V²¨Tç kÞOÕÖéÓ 2ïPŠŒål6ñ|‘šrW6ëÚÚ†& )>`ñ1¿K4q¨“ö‘Ò& <ÎÍýœ^ÕøÍdÇAãwµÙrw©\£S“!Çõ|ËÌfÆgÔs[fS³mźVˆê 5£Ï}hwgïÙ\Ð8-‹´‰\4Ç?£„Q±O»iÏüØÐؤ¤…ŽÚtb,kËxútP\-ÆA±oÏÓDwú²vÔ¥jÇí”±vlço”ñ§Ôs8: ö¥-Ó‰ÒLé¹¼J]Á7é›ìâInegÊý[ÈÞ` •,çôHqìúÐÙ=•Á$©wxššÛ’˜ö3’ 6QA{²„Ž|Dc4ÝÀµÌ¤n b“¹Œ§S¶ìGô‡Íé·èÊ(§ØE`ZÔí‘&m§’s™F¿Û}€s¸”åÜF/ÖÒÞN?Ç_RZÂ>Ár:¤b¦Ñ”SE?¥_±™ ÿ…R±&;4§‰ëJzrŒÑRZý¿ˆ]ÿŸ¿\I—úFNJ¡ÜÅ»t#Ã2EŒIßggò—ÔŒµ†jÆó.c)‹Z¼8/‘£'3ÓZÜÔÈòŒ/y'^e'|†óyO:í[r.eO¡ù˜5,ÑDNáM&‡–ãÖa9}¸"coцE.ˆÒ#Öa;ºp.IZÊ[”*àÆG:“¢B]íYÙV’ûÉçÂèß™s1Ïsо½®kŠ>»+¼Ò]c;z±…‘¥·‡–A‡È£#‚Üâ5ìsÊѰ©5#ÛÙ’QÁ öEÞ‹]’ø#8—™,åTÚD¶DDN -Ç ‘«ØPcPÐ>2$¯¡YÏùTƒòŒ¡ ŠÈ)Žô zGÞÎË]oS³>ž¨`73çTO™LòÍŠòzðBÁÕb÷köM Þîê–zK›ÝQ¬g®Åƒ·/Ö3/O»q[ÙÏq ÝbËsÎ$átžŠÝ) ¦íK\ÞUßHy'ãëT³9ãëÁZú–ãm&Îð‚n‘kr–°*cS³q<“N– "ð…Án¦vqMmÿFC–™Úß¿¿cýN>Á{M*3>×Q¨µ|О¦H}¤mâu^gMâ¢:›rVdLÊYÇß8ÌHd]O¾Øþ&›sîâ×ô⎼ÃB8íCWŽˆ§Þ]«]^‰!oèÙÕÌî¼™ìå¥FÓ‚¹‘‰‘›î:ê¡ù>\eedz/ŠMƒƒ6Ì š^0ÃEfïð Ëä© v0Œ—Ó3EÕ-w®#ì¶Ó™Zz¥RÝUŒÌ¸œíl¡ˆ6\Ão9‘>#nÐy‡Ñ$üƒ›È0‹|£•Š2I£e´a~dO0Q¬b:ÛÉqœ3‚C\Ä®¨¥¶ƒ¹YÏ&Úr;¹œeìa¸†FúPÄ<j¨I?ÈU)Ñæ³i$ÏͼÃ|v‘ç]9Fºó~z+ûO¤¢.|óÀŒ4&ÝŠ‹XGªӵê6f§è©é±?‹ÈÒŸ}ì>騬†Ý©8q"YF i‹eDD'AkÒýVá瘈|„&ÏQK)+Ò_/šÙC iqöÑrõÑ5–Þìa'—1•ãÜ©%sµ*r,gw¨*E¾“˜O Ãx–-Ì笔@x.YÆóJp°ÙÁ¼ñ‰þÌM“ÇÅ ¦#Ó› ¦r9o]˜Â™<OO—ÏjÞàR^e[ÆH;¹4­Y<,e;˜ÍÛì¡kÆ9‘É:?iyZ¼JþÚµy O ›‹D?wÙZŸ­n_gsì‰øÃƒÉmoyåB5ý†<ÞŒ|3£*1ƒ1L)òyÎø|¤,´ù¶gÇECâžï_ô Ꞧ‰?ϰ‰OQYðzÐn\RhLÃe!>à‰>xG})§]8DudNb.Ë󾙘¬¦5klå'§2-¨(•´UWï­àÉbßÈF}°’w8…õ·EÒ½›qG¼Ì#Áü"ÿšXDã¹´Is“3ÛèÕ ÉÙ’w8ïXЗQAhÒ'o—óǼ‡2âXYp”Úà.§?™à‡ ^o4§Þ¤ØØÄO‚bŽ2˜ŸÆ2±ö‰] È:¿Ñb¦ò\sf…W7zþc™01Ò”RÅ2²>Þè‘üÁ i­g·îñ½QsÁ-Û9øJ£«y”®”ò-ª [¨46vs›[ŠÿJ1%¼ŸõÛœ]~“·¥È}‰±¤ÑÙ¡ãß^î›ßÉÕ><§çU>ÿc߯U7‚ñAkZñ8׳?‰†5ÝüW¿ÚáóÌVÛ ¶Àèĵ±â8^~ú‚{©çF6³¸‹_°‘,àöT›;Á)‰§ YÎ#Ôq;XBÂ¥,Ö‚Šþ}Áɼ˗ ‹ ó¸–uŒaßçvr7góÒøÃJb¦'šÝætFkùkÒ¦ÚhFdý$xŠÏSÏ|ö²=µÿä¹(x˜½ŒŽ,c6·1ˆ­lg?y*ùÇ?ïŽQͧøKanÌðLê3š“Š Îd ÕT1Å'Ùß 1¢§áŸñ&œI)K©%b夂¼žî–9‘ö¶QE›Lî¤YÜÁt­*à<ÖÓLÆÒŸËXD-'ˆù{SèûG×�ºžd±ªc"y6ÒôÏB¨ÂR÷ß´LüÏ\®ö¥O 70“‰la!£XÊ”¥Ëö¬a ‰9¬`2}èEƒèÈÅ ¥–+87rsÖ)‰ÏpWp)´l³jÈqoj}îYk#˧ðoPF5¦Œ:®ä-9#±-¸š[Ó!g-+éη¨Ìº78›¿rK°98¼Äk\Áxæëw‹™Sô9m_6ÿ5ÚÒ?ûæ’º®áo±‡2ÏÕ^=‘÷ä KN-969ãš¼JN¼©gW'º²$Øœé7><5Ϧ¦poE˜þ”Q%îYœýÛOÙéZ ª­R`vaÚ^ÀµÍ+v]ók¬÷Ëc>»ÌÏ¿¯¶mìíÈœ`{“NT¬IN)ÒØZÃÄÄj.¢C#W˜Øì¼#Á2î ­*Æuwç UyoÇ»Ôì­ØÏ¹`N‰›K´;jh[g•èÛè3‰ëbùŒo%:ñ@^qðÛàD­~y#ŠJü(Ò'òØðn:UÙ]˜A•ˆÛ(­õ'v0.=+þF±‰û‹4ðÛœ±²Þ®É8¥NEVçÄ&þëì(%8%ëêÈ„°r¶òí­û—ÎèVï ‰ô˸%蜛×CóãJ=þ+7]Q²íS}t<n7õñzd}1£S0žç¹ ¨ÊúLb-oGd OùxÝ)+2&èšoÉR÷ï’*g4z“ЬÉ å[Üñ?v‰Œa‹ŽG]»ÆãWg})¨äîlËÅ]wµoÎ÷­Oî•ü;íùG™Æ#¡âéðð,‹ôÛþøi^¢Œ±¼––ožd¿çk鬲3ƒRªú†4D7„f–Ñ‘zÑ“¹41‹*ÞàŽÈ2Ρ3‹Æ|†0’ßÒÄOXÌ¿p0²“))tõ—¼Ô{¸ž ïp ÛØG ËX’xœÀetæãlOwE…ãêi40õýÝVkvÞžd/Ÿe),¦5Íü =XC W0ýÜÊoùÝX›~ÛÑ}4ÓšI)ué›ZgóÔsVáЕüˆEìK+%maqÅ)ì¡mŠC+Xó©Âªö¤ÔÃOÙF5=h¤–{˜E?Zñ(Íôã &3“KyžîäèH {éIEib~óI©÷rŠþ9ˆèórEËMgvZVh†,°“ƒÜCDWÚ¤dÉ{YN#/¥ÄCdYÉ ´ã­ ¬¤l|„ݱþÁ+´ân`:G˜ÁUô¤±Ì9±;sÓA¼Ì}ÜÎÎe+­8l¢-SxŒœÍ8šÙÆqB¢w²%t&Éúqb!Í´gf›ö›N™ê¼ 3Ý>åÄÂÐpjbYÁè"Ë[«lÐ1>¼sžoÜשÓÒâºÑuGÿÀ/¸0vCli0”ßñJ$„»7…åg›ûºÍÇ¡aŒÕC“µƒ™Á.nâ>ºR;56:x9ÕçL,Õ|Ô¸J§}ê:z=«q@°2Ⱦjƒ _鉿8ð7«Ç1%vs0Œã±¤‹íÇ­b$}b­"ŠeröÕÈð‡JœÑ¤w“£yå¬ã“]íì ì¸²œ.õæQÍ‚b¿,Õ¶Q ±\}ÞcAO^‹š÷¹ØÌHeÖ•‘Ήâ`@p4¨æÇ9ë­¥˜m±O–êÚl›:¸*'j¯¶Ê´ Wªê 59!cE³gø2¯Ó*ò· ÃTž*Ó7V™»ÿ5£:5o¹±¡çC¶åZŠBKᦻb„v‹iôö¢äX·* nèCúг½¸­ÏÕ™ØÆè&óhÏàÄÛôŒœœ·›.±·KmmöV…æf‹“©Š”ì1¼ÁlnæÌ6†”ZÔØº—ÏÿÍ¢™½½¹Àu?³ÿJ .Lìg ×EúFÎa½âyÑ ™øÖsêzÎLD÷`%%Ãó¥_¨lŠ^7ê¸_žG×ÈàÈjvó ÓiàUJy<¯20=jÇM,eÅlàã\–lK­u»Rwâ‡YïEÆÒÄ\ÍaÞLCÂc8DG†fÝ’èÉ6ÊØ@5wPU(ÓYÅùlçê8Æ)ôeWêÀH> —Ê!·²Ž3Žy7_à7KŽJÖpå±OQÎ"fÐ#—Gê#—ÒWK)b='Íš)çv³›Ù”q^:²{Ÿ)F®@ÆÙù)`·pè°),†r#Oêü®ãx÷ØCM/I;&±ƒ4Ñ9Ýxs'­ˆ™M)ÝØ”¢�6°…tcø•­œÎúKxœ‰é??š IÕÃGþÿåê£k÷I;ñŠô o`:ä-ÈWp‚% ãc|À~z³Ÿ:ÊèÆ|.b#çðÛ™vŽQÏ Ø’ào)¹² ))èB³„MZå4ðsæÑ¶ d3—RC[Öóq!Mª¹‰j6q¯SÆM¬çÎJ“ %‰õôc Ë()m?¬ñ²7<7>üx¾ãü,{˜Á¼š·¸Á Š‚?h¼Òº’Ú¯N¯›¼Ñœ=ª.bqe^"á¼X ®pοoG{{{ä[—ù`daÿžQtà­XŸÈ^òík0>¶*h.µª±ðó¯ìç•æLc7–Ç®hãâ 'êu°¯ÖÊbÛ‹>–uwpj°…cAY•²ÈîØ„à@¬<v kV³íŠ)ÉéÇ_¹ò:‡;ÂTÎ ·Ó§ÉÓ9W6Z[îhpV©ëêlbÅAuÐXæh¡±TbSƒ‰âv*š ^ãÖ22ò^‰ÕMr4שÌ;Rã?\ÚJÉÚÒC{u*vaFßfÛH]°<Ø:Rþ°ë‚~Möå,wÿ2¼Üå‰3»›Ó›<›ˆc–gT1#lÙ¿ò]Ç:5Á¤àX¤˜a‘YÁõ ¢&ÓK-i4‰E±óéË´2<kMΞÈgJ´k2¯Á°D=¯òÍØ8Vñç"å­ ®v¢Ø¨æP†ïvJm˜šõ¹µâÓýîž”à0€/F2‘m±Iá÷£12:x—·M'.`§Ó¦xßÞ¢•75VœjÑ6sÏäªXDwÆPÌ:JéËÅ”¦‘°QæÒžäÙŸšv ¹D\@'z°ŽÃœŸèéy)8šîÉÞ:ibVÑ•0-QË:9½0/¥œµl¦ iðo(‹—Â>ËUhÕ`6ÕìI)Ui@±ŠQt+8¢"‡c¥Á>šèOŽl¤‰:vЙìbeäŒHy0+RžÍaú¥y¹©§ª!5ƒÄWo¤/ðFÞãÌ“’}ÓÛÚjƦ˜Ð³¹{xž$]¡¦<„"ªÈÒ›š5ã´) ¨i`+=¹‚UL¢ '8À¨”ÅŽþìMßÌ[NZœ Ó¥iÔ°GÓ︼@Cýo›þÏ_®N¾"¸šé|öò¬¿` 9ÀjÞ盹Œm¬b ‡ ³~®d÷N\Ã’B`=x‹sšööÒŠó9;Ý8Üä…]ón®gϲVK3ôe.b KÉp'gòJÆùLcrìÚHcðc¾ÉÙ<Éš@7¾W`Y6¶__Ö?§…ª`ö~MxŽkØÉy Iì]é§ê ó7Û¶Øý ¦—H—ŒÁ‰}ŒŠÍúXK—Y;ÌàùºoöÄeÙ§¿•äÇ1˜v‘Á.fc°9ñRdbÎÛ àFSùqúh>ÛE»›LIÌjv¿±;éxø39£—"%ÁQj"/·õé"¡ÉÞ ›x°Y1G»ÚÖ-5âœlÞ ƒ«˜›qƒTG–DN'Ÿ#kDâpÖéyõþ=rQdV„ÇëO# ye±ÑÝ,=êÇd#³rv¶öƒÖ¶7èE¿`[“§(ç&ªô9æ™…ÑÎßÕ¸l–šò:çìb?mø€ TÇÖVû4ýb§E…Õ ü±Ji쉎Ž=˨b/·5¼ÁA^cw‘íå~Ú`UÐŽÙ±|lxƘ.ÚW[—×»Ù~•÷ñDeš?¨Ý./=ݾ(ܾ6¹ýP¸pNÓ뻸›^Ôq.ó‚ 3zðµÁ7òší Í¿R·ß×¶»¤ÆŠ›ü¹§ðX¬cäüÐ~[œáÛÏyp­‡¯ ÞâlÖ3¶Ìd òzÎöÆÝ{Í=#;÷ÓÁûÊ-ˆ|˜3–ß’å®àw‘Nƒƒvý]T¥[Ð?v^ä”Ðò˜†1#rK¦¥È±–aL¡?=³>Ÿ8ÊëÁ(ú°ŽÅ æ¶´u{3sXÍY\ÌÑX§HÇ`*¨¡µéÓê'éÊ"Ö¦qó&–3<²2ç�qÊ9;Ä êÙD;'rIðèÎX- ÖB: d£¨a2YG=Gƒ­œÂ�þÁ1úq˸‹ÿL˜“†!?Lÿ™åb–SIö³‹^Œf™Â雩Õ25ÏБ^Vqgñfz{üÓŸNocó©âT†2‡cdÙÏDV§IŠÝÜʺ¤0¼‚4ãèIÙˆÆô¾º#}Q5ÿýóÀÿ´\eýO¼Ž¤‘‡\šuÙ˜7•»yœ õ<Æ=évu¾ÃRf°—a3糎¹ÜÏß¹’û L&ÏnjXÏÙ|,}ëÜÇtf1[˜Æ]d™[š¨a$ ñ89@†Ý áË›ƒ{ˆ/PÁ—éÈWF ù7æË¼ÍrîM¬1 gÛªÁWÁŒÂedFÆ9K¹—¯óeÛ¯µ½ÆÒ±ž}Áu+¹;§}PYdbÎÊHëÄBþÖ¢·ol~r&Þµ:*R¼Ã³<Í—ò~¬W¤wÞ†¢6Ÿ®Ë\©¹^]nâªH»ŒN9í°L.ñBO/·7y£ÉÁCü$£Í ȹ¥ÒÖ}rQËÃi¿àýj·ñ:å½\¼ËVöðõ£®ç®ØwÚë×`u{çpW³/åUÓ/{.ñBÞóÍn(r_³£ ©÷óà}~ËŠô3œáTz49‡Ö‘Ù»uâkü©Þõ‘IÍÆ58Á‹<Zfr”©Úô3ía–ùu©Gc%ŸäãAŸ-x¢Ëì-uÖïîs>;ç±ÇœŸzûu­ì®éêÞ£6ûý ;è[gZ½/5é›Ó5èÁ N$&Qš86@Õa—ç=ÙÑ—ëœ_ï›|…ZýÍ# ØêönÍ âßÌßáñ"ŸêǹEîjnYT~Ÿèùb7R–13¯ˆ Ì}Ãc—EõåÑÓ—%ù+©N¬¡œ)<J«L«¡aäßÃÕ…¤@o­Fø[7ݾgRUém‘'š}JöæUO¼[í¢`ûÙK†‡)§>–·…æÝV$Cƒû<PJ–ïÒŸáLÍ•7;¨ÏëÅ@ñ3^¡$ïpZPYHGJùr˜Oó›4ôThÂΡ(i)ÛÞʃܕrlSÄÖô‘ô/ld;;¨ ^¨W•f :²–~  =s8œ˜Æ{TphÁãLd;pYÇ5Ìe¢;T_áwé9ÅJncJª7:Ÿ™L=ëø[9ÀQ.å 2D¬OÑì%i ã>¦œ=Ê0ŸjÑ@'°œ÷ñ(™4ÜQ”ÖqJŠ,(âjkyùÃy—Ý\Å“§„„«˜šn˜ÖÐ5å_¬á!~ôÏ1éL8&“žÕý|ýÏÜ]®„.;¹˜b^¡=ÇéÎKtOûtÙ–9àZžàCÚÈ‘VY%*³F·§¾ãÕ)o÷rü’y©8¸)2”—(ìu¦RÞͽ5Æð"ÏE&r9ߣ5Ý™uKâH¤+õœÏŸΧx‘ãlæn&0œß"•ôçeYãöªn´a¤­ï€ï¥J·] Iü9RÉöp‹ùPívoŠ÷÷Ž]Ô34v¤Ô‹­}³ÑiÁ”ijšNM;«©ñ ¾–Ñ#K"´ veMÌOùÏ.Ó¿ÔK¹…Ky$ñ•Y}sÖ/Tyð€G:©¬UÁÎàõÄE®ö 7âÏ­\š³.¼Ëmäë}š’ÈljÆ`x½7söž0.±™ÙÎsŒÌkÎ:/cHÎwc#?‹]’56ØÂtÚG¢H¥d8%«?øA;÷Õ·$t08ïÈ ÈÎ`Y±™õyû ývšI¿ñÒ@çX;Wç7ìûydl±Ëøv{¿<Ô¢…-°æ.¢Æ©†þÝô_»õuÖ×›º!Ée‚ÎõžÎÙÆzFjcƒ•iSçT–îôx¢2hS¯G³v4RIw?{Ë Ý}ëzUëãªË²UcU­ Ïe»ÏÑ…º%u±ç‹}-Ñ+x)x¦Þ°f_ 2˜7ýöî3Ê®òÊ×ýoí½K¥\*åÊ %HDÎ  ÆØ`ãÔ8Ûí€1¶1ÁÆÆ$“D B¡œs(¥R•Ó^ïý°kõ oßOwô9Ý}Ž×7 •T%½Ö\ïœÿù<uwYøh«O/k“=½Ô†´7RúGþÓX›÷<X^|ßâçëÇ¥÷þ…—�� �IDATÎ÷Åy¾š±ãW4¡1ߌ}Â,Ú2Ÿs’ÁM  v$=(â|.â ú’Íjcî/}¡‰¶ÝœšÆ¯™AW>ŠÍä|Þ¦sò ßÁZ2‰—’fÆÎŒÆ†°“*þN9ë¸ntg¯eKx‹&t¤’ËÙM ¤ &I¹œ>w\ŽI³ŽMt'ð5jéÃÍr!VЙ”ñðZ’~ LaK©áë¼O ŽÓš3)`'ëYDÊy"aæŽdd¤I¤’÷ïå‰þT²qœë£ÜÈj.fuĦ1cØÎÅLd›èÍß“}€.‰…ùæDºÔ”}IxäʘAï$°~ ¿¥1™ä”ö ÏßçÏO5º&†åÿK™ÿ?®ÆL`%ýébÚSM pZä´”SAǘÂQÒ†JúÄþJ‹ØÊ¤‘}#»éÁ3ìe»8—ßÐ… i×’a­r”°2•)ýŒJkž²!ÔOMO±+ÖÕ)FòwÓžOiÄ+)—ÍéÈÆf®¯•ŠôrúÒqŠŽ©YšzÿêàR-÷™Ûy‘Êfë­á³“Öó@—77±q˜;)X“–af,[ëT•‘ ’ÀžFz³'VF¯Å~ECZÇ>óæÅÚï±èt«¦4Ñ-kq°< ‰lI©v0™e>c‹¸šþ”µv´J~ÊW‚±-ÔTèšh •z;vvðY—V¼Ïî†6gôÏZÆ£²‰áYÏWç  ³ÎÌZŸrqì×±ÇÌ-ÌK¹œÁ¹œq+ó4¯Õ82´³Çt£/½Y™òAìÇ‘ó8š2¶©¨jØv7îIÿøë¡tßc‹gëWåíŸ#›kXeP™=¹Af3½²zFZ†aÍýuï2~QôôEQÁi¾u$μbQÎ6¾¥‰Õî¶ßOI±‰Ã‘/¥ëhù´áÙ”Ò¦:ÖYÌ¢ÌmaW³HÛ´B¶ÇÎRz¢ýßmP G¦+«›\íPp2Ò I»-57/1b‘o0Öš†Ä•ž²$hëßH:RWg¢–­ÜùDjYÇð—Zzšªõ†ô÷a ‡x/%¶'Ñ€rö3*é,äJ>¤’ XÊ8šqf}*á´úž%¯Ú–9I8b4ù ¢ˆ‚TÊéÉ3´¤1óYM:ö c8¥ÞDóo­§ zr€îìd(“;=Ë8Ž1—óéÅþÄÑdE·31ÊiIÛ*[È‹~Ë ì¢’cg*ý©ex‚Ôé˘œœvt Jv0:-2C4O––ro99{r{¶/ù-¥ 3~IKþ¿žlc(ö^^H4W§'ÉY¬`;=“Õ·|b`3}i“hs'¼~4bk©¤ cÙì}n¦8¡­£ˆ¡ 1^ ÿ!³žû7îú¯zîÿ*W9ßZœ°æQ•l«u«èÄ~Ñ6²(2*8¢^SÄE4d@òŽV˜ð××’õìN¼ÀfÎämð|ÊyAQ°%<Â&J虹:r,¶(ϲÑ#U/ážËÑ „éI¸Ž#¾ô‘ÝâÊÁ >äxCÓª­Š#Ý©a¹CŸÙEÐÉÃË.Ñä<;òFÊ¡´ö5N1ˆV§ÜÝPº‹~u}:îì ~´;ƒ?¶Ô*­¨V§´û#Sèšu*Ò?ôYlâ\G1$Ò3mXp„¿0ÏÌŸZQ˜o{­)ß š¦œAYl#‡™œÒ?p‡XFcú4±¦ÂР '+l,MÄ `sŒLð—³±«c%užäû¼Am¾Á=5?bbLÃYãTÐŽOSºÓ›WÔgC2l£.íŽÖ©¡oPWé$•ÌäãHç Od(A‡ÊAÏzr»w†„%M™ÍŸîÖMî¸ÙÉÍ´‰UZ2.øÇ›ë”ge3S+­OþĨÍð‡ª¨oO·O´m¾f“L(·¸,åúÆfTY”r{¤?Kƒ½\i‘v<ÆÓ/hÒ@ËZÓ‚Æî×¾ÚœaJÑ5öblGiàÐV«vÉ4wéáø’—«¦íÓ>2í£hZóg6¬)!ÕVjˆÆÝ¼Á´ÈÉövä¯ÔêYg K<\ba“0û(Ç48èí7á Ÿöñá^ç^w"ýƒ örv²þu””ËéÀŒÄàwÝYÅJøŒ6¶ÏsWÊî`gÚ¡`q‚}LS¯~?\ÁÉîóÛÌg9ÃiÄ^ ™Â>Zr)æ<DË”séÄ à ‡KK¶±›Etç$ ˜Íõ´d çauUÚ—`^s,ݳ¹œOF»Þ"gäöœ&ïµg'‘Š#lNh~¹Z2-YÂmÍXÞ¥%;X-’ñXIl{0—AIK-÷û0…´¡'mY0×[$S«­´bPs(Kz¡[À^ILʹYFk–±0ÉDç�ƒH3ƒW±•KYÇž¤Vå¸%ÿÝŽ)ÿƒÊU-§þƒn9GÄÙÅfêèE`íù8to?¢×ЂO)¦ -XŸ€‘vq‘ú®ÈJŽrˆKxŽWP­žÅpŠ*Ú2;ø˜]ìaiì=¶Ñ‹EÁ›‰æ`/çÒgœû©¿í·n”{·…é¹ÜÔU{•´þƪs¸ô`kãËyÑýW»êE5ì½0¶°Ö‰Wåuj¹ÌW?ñÖ{V’Ϧ1”3ƒ’FVú,6ˆL­§bï*ìlæÏ\±ß–A¶mb7§Ó÷8Ì4«q8XHÛ¦¶å»¾Ú[Ü£Þ \ê¹Ôã©éª[µg*\ûF4ãw É®3†s¨DÏÖN+S™˜qf™ô®ÏE4ÓÕêU+ª²ŠyÁȰ” _˘ûQÊ )“‚—˜F㬓u:ЀVÁŽ: r7|Æå±i b[YÌ7zœ <yžògØïÜ«=õ'OßèÃ1™ºq±8HñÍy‚Á„ Ï×Íz»¶Ï6ÓeŸ>⃎~ôƒy¦·¡Ø/O5ýËóUp8¨J̳}ÚVîïÁà`{èGs~D“Í‚G#w§Ï/ á€'Ñ"² ígAž£ ´l§ãm»¿ñƾ6¶­Þ¸ÞƵ5Ë+¼s§egX6ÈʾJÏÒï°oüÃÇÇ3G~ÀG)MS3Ç#Û=xýÙé+ÝNö¤Å ¹‚>¼’{ù%¬I˜ÓiÆ@ž£‚»éÈ< #»ÒÆ)V¨ºÞê+Î1ôrY¸¡ü•žÌc%mÒn˸1ö3¶s-m¹œ…ÜC1Ÿp9ó×XÁXvБ·XŸ°lZ0/Kºñ>C9/ù©J“ Cn˜½£Œæ©\•Í#f0éÏ­rµ7Ј"šÓ…é_‹=ËNæ>ÒŒg"ï±…K ‰ë|]Bî$ºÑ„uœ"NüÂiÉõT“Çz½(¤˜/Ò’µŒ¡ˆshËn6ó–}•”ǵê?TU|9 £Œ5IZ}eª““åçqw¥|–œœÊ8KýÒÈ1ÿí¯ÿAåê?Öª\«·9k¹‘¼J)“y)Ǧã(Ÿ¥–wYŸðÊÚ’—@YrvÇ7Ô“]¦'@­A I©L{‚%T±/ñI^Èdþ•µü<±ü–Î\Â#Ìd;}é¤Wk/.7»¯×nð7=>Ž=4ʸ9hJ)§SÀ@ÞæÛœdKÅÂw2“ÄÇ{øô ]U¾‘ ¿H9{’Ž,¢ÔMï(™žu"Ô^A Zg Î »‚ŸWèPçΤ½è«ù^W—¸æ—6ž¡ê“<d­Lëi¬à\æÑ'øþ¥N~uý"KšŸ77¡7jü/ð;²eºÖœ16’ëoû‚Èui+b?LëÈO«M*×-x“®ü46†}A1¯EîÌ8’µ/eF¥^ü–Ëy³Ó*ÛëSf 'b-2®k­°ÌߘÎúóçÓ‡ëÓn,´ºÂßY›ÁÈ [Ãê4­évqêÁSw §Ös¶~—{÷¿¯öÛþªŸ †Ðž\N;–sCV&¼¸¢nÄa¯Þà‘ýâV¯|ìè5öè~ÊŽSQé¯}43{â¼ wð7ú¤-bp…‘ÁSLOô€¿¤gS;Te_¢< ›¥Áû–~È»ì*êûºõéÓy\ãÀ0E¿¨+USDÑVEw:x*å+)Kƒâ7 5÷§¥œÊZDåø}\ØÂkÇ\ÔPucŠü¾ØGŒêœþè·©Ú¯Ûy’)É+Ú*x››8ˆK9üŒÑÁBžH93Ò x—eL6r#ÔýÙáþtd3«ØI%×0Ÿu´mæö|3*ìd`ätž`Xroöà8—ð,7°‹¡tcz¢¼–svø f1‚Nü€ Hxµ]ø UÜÏÞ㵉a$'.?’ usæbªhÄòéÃCìfu3[“,?•$.ˆ+™Í;‰(dÅÜÇ æp8Á&Å´e !7óæû¹‰Ë’_NKö^¶Ð„ëyŒuõ¼1kYËb¶å@2» Éįá´ÏAJA?¦1˜iC†+ÙÉød„1€Il äsÒ\ ±”ñÿ›½ÀÿWÍ®|îÄZžHϺ°ŽËÁl†“eQ²ª} óù.;¹”clJˆý_gvâ^;?!ƒäC.Zop«hÆ=¼ÆšÁŸ) ;=r1úH§¨>³îy.J9/ö7ÇKüñ‡ºnkøÙÙCy^¾2W9bëYy(e/Mi™L8ÓŸ†ø¥&|WÝ»^\-)msò’RsYòxgí wþ½íþ*öÓšmÁ«A`7éÚモHQžÑ‘†!ï·Æî|ÖêŒíƒòu ~•¶°NŠoFz¥õ²¬glÚ…‘“±ULä!ÚUK×Ô‡²N§[Jc‚nY_ ¦æ;Ÿ%‘ùAYžäùf­%YçF:‘ϸ$zÔ‘¶i7¦]šõHp˜©­Œ©ñ³ ,ãÎ`ƒÆå–f\¼Ï㱎åJRúD. î§/]Ó:Föó³þ^áîá¶FFD¢Hyµ%u-7„‹–‡ç»ð)íëtúÐ×/m˜­ÍZÅåi[‚×hÊaÚçé™ÂSÂÙ«£AEþXî¥iµB^´nªžó<4?Swv|Åî0kuÖ{Á5¼+f"ÕÁ&4%œOAÖÕ†O’§à;ÆæÛ5ÔæÖä'ñœ¥0·0;9m [8A_Þ£#ØÜô`W±PÝW¼?Ä}Ë¢ÇÞl2÷Û 7¬ùÎb?øUêP.¹ÞÊûô-O :ÃŒjƒ§¹™öLcGÊÊ ?2 ª74eù×X¦ð“ƶåkUcRB~iJe²éøt$DÚ5rKLeAòÜj̬¶ƒ¹4ȸ"ö!ﱋØN/~Í)Öq:íhžLñ.ET2m €ügŒ¡Š­Éñ«+‹’ÀBº±Šî‰1ë81=(¡)×°9·Ï¥ ä"Ëaú2‰V¬ã&r …¤)c/Ÿ&k'1È^ŽwÞÊd㪌óøï%˜‰‰Ì¢ïÏÓ”ñ ›ØÊ¼D_Qžì×&ör–äæ|ìg2++l.Zò:'(b(d‡YNûäæßŽeEìLÂô]9Iã8‘Lã:SttÿY®þó¯öœÉ1N%ðà¼$z7€]KÔ�‡“ §n¼Æ­déĚў4g:k"×Gõ; ')Jöã¶sŠŒMé™òåØ ®¥?æ&¥4œìât¦4t*RQg*my:µzd“¾Vûò´¨‘mµÖð ã#ÝÓR,æ¯ì¡G_õ‹{>ÅåÆÕü˜O–Wîç Ö'‹ïr¦†ç”[¬ï»Vö¦$íœà1†PÒDï¬NYJ)‰´JW½à“{­(3³% š+ÌÊÏs]­&¼C›Óõ—F)­²e,é‘[süÍá|„à�íYÕȉ`NpW0¿‰‰ù&V9›w"ÝÒ4Ö-v¸™QÕ>bM°!Ö(²(eZШÂ˱+xššhb“på\kJÕ~HQ$ÜØN^…#Å9þiž²ºUhüƒ3éA1kXÃý‘ÙRádÐ!Üö'«Û[½§þñ×öFgmLMÒÄÄZ‹cgyìãÉÜ«hC½S^ ôòÐÔ ×†Õ9\ÐàÈ=)ÍÃêÕ^èŸÿŠü9áÝucr¾³òµ¬•Ïb$m¢Ü*ÞÁ¡žšÓ-uF:LYé×iLKJÉcýYM3jƒ¿ºõÝhÍó)-‚-Ìåešñ»r¾±MÍ;CÙ&ÏuÔº ¦ßúê;ó^ùrØR»È6óì[‹¢YõþD~—p†&¤Ü‘².(Šô¶±‚u¬¡;]rHïZ…5Ö0Š÷™”„¡wp7Ϧ´åkÍ´©¬¿Sr¶Ã/˜Dsš0*¶šd×g--H'K©MéMCö±•tc ƒ™E7î`3Ã!Z3%q|ô¦Rò«žS;ÚÑ…žtM†CýX@_ãÍR&[¸Š'(dpµÉ5÷:Ò– –%œ‘”2R½ôk’º8ŽÞôã8kØ–b¶«ÖTq6»DûÏeÁóÀR'ã=I›1W#ÛRJê>sÎ@V3–RN²Œ­Ÿ{6Žüœö7fiR«p6=Èé̤_ò•ý8É ÿB_ðÿÙåª!GÙÏeÉGÿ`òŒ¨ã 6Ð’ˆöt%c´a+·s‚ål ’ Ôp}"ûX þDSHu7ø¤9úgäXÖ‡L¡1/qˆŽl º-Íkµ†Õ™Íùõ ¡NUk{*Ò8%]W/¿©fnlzМF‘¡i§‡‹>å“Qª62Ú—æú¬Ðê‹x‘V‘‡Hë”Ñac•‚¾ g¹·D&6m$DV¤]̬–Í:ÁsÁ¹±(¨ êjË(‡+ÕeͯUÀë|”ñ#Ú¦í̵õ‚?RL›´sƒÃ¬áv§ Îb?»¨eZC=›ÚTG.¬q”s3ŽÆzÔÔß{‡‚¥-ë¼›qMÖÔ ¦.·í¼ž€‰ê93ü¶44 n™aL‘ÓŽ†E3ƒÓ¸²‰ùÚT]¨}-ÁªÍé¤c•ƒ[Ó†­8šSåû8üÚŸ›ºëN–q5Ûµ=+uVe4}r•¿Ç.a!—ÓƒyÜÙŸ5*Ö?VÔ§˜I/EZFŽ5…ª]œ>&ÍFÆñTZ!ëëL €^ ín¤U5¼ÉASÓ®ÿxôxi(ëbÆ8‘1<rMPD†u\È)Ú¹{“†ç¸ô@ôq÷`-½LÊoæÐ•íT®3¾·›æšwž×+l»Ú¾­jÌ Ö0šû괋峌é\B3VñEÚÅ‘3‚½Áß(HBÏeD¹ædZÏ`?sYÉ:RFSÞàržÏÁ×+Íà¤cÜš~ÌàFÖ'^·7¸ŒÑl'׸®a,Eœä•‰Š¾gП~|Jsú$‘›8L Åa³8'‘˜|€d5ƒ½´Hƒ7䤣 aï‹Ù) ¦$e ŒŒK"éùêÉÔS©¦1'ÙA ýiM–uœL6«RËÚÍ>6iÄÉñº’HWq‚0oÁÅâ>“O!˜bp {)¥„®´¦ìsE®%;8JYRÚqÖçêY®ä ã|Š87I‚䨆e\Î+³Cý†\Î4óŸÍÀÿEWE_)ù´)Çü?¡,äpòòõ«“gÖ¬a#×rVâèü*…,fB›EŠ<]ã¾ZOSÀ¤ /çÑ)eu¤cp³(âLŠy•¡ü ä¼<=b+“`Ep NûdMo GèÀ‚î,× Øáª®Šò-›J!pný½lù€?1€¶¬ðòF¯·d43mëfÝl»3ÆjôŠ+;ùM‰Ú´¡‘Á÷"w¦/k^x4¬z˳"¥]”òçq9qFð§`{pf}ª=œrMûjX]¿ìÊïèÇX޳—*.åDðhûbƒëtÌj‘QYç;u*ƒ†LçfÕj\kÕÚÑr§h•¨ òÈÐC£”ÇwûícævõöR;׺µ£ç~Æ:UØ™õASƒi[éDZ±Õ¶¤ek]Z«$ø—Ñ/O¿XyÊäÈÜ´;ã‡ßÕ~½ÙÛ)â'JDŸuŠN¶ŒÅÌbAbRï™8pW]‚ÓØÒØ‡M5©Ò˜©<COjc‡ëº_kþLG¦Ò-ë:u¬àoyî¨ó~öößÄmÛqS_Žôˆ=KÃÐð¯áÁî>âT>˃QA–GèÃ2º³ÆíùÒK<{̾…áHŽ~Ò/¸ÏôØx‹Yýe«×X8Îâ&™Ýß‹kK”T<+8/ϱïRKU­×ƒq’U àrý(á÷ANc,KYÍWùG¹…Ytäq°—<†ðgð-¾“4èÎ%0”JrˆuœÇStfË9H1§sïhʧ\É2õéÄJNðJri&¾K6“ÇAÆQNš/°„[èÃfæ1‚Q4OŒ<9Lø^öRÃqêˆËëN*–Tâ]  ãùŒ¯³ŸÏ(¥2Oqa%:Èi¬e*«™’°b÷џƬåæ%O¤ösˆí”&ññjq”S\M9«™ÌbÆq’ ,c�]˜÷9 É]³’êÏ‘gd8Uÿ^VRI1Ç’Öndq¢ºÍÙšîâSJ©¢„†Lù÷¨À–«ÿä+W«ÆqzО°”ú$ðÜXë>ã\Ò\=“­(.¢ï±”Ê8Ìm,àÓZ/'±ŽÙ¼Î;|)X aÛ˜Êq²‡B–s3c¸3ö4séÀ6.Éw Ðmv3"ÏOcgpÇËý#èG7‹÷úÖKªFämë7[llw[{Úõï‘O{'F_ÞáÆ|3/T1’RÙŠ Œo«zšõË ~4 +uoí£GCɾpÄEß:˜^xU6ue›ŠQ±›"gÇJÙq_èVö>ç†ã¾üzÅ—Ÿ‰oâY½kJºVkÍa2tŠüta³ÓîŒ î ˆýš ‚ˆiqk‚v‘¾‘[c €&±NjygèïüÈÖHu¤SXúp4õ}ûÞV¾L£b3ŽZ[ê­õ‘£y:Äd-«UY— %r$¸¯Ö¦àib®IûuäpʘØmÁsÁi±ñ^Ÿå‡{ý ÙÉ~ðžK OÍ ZåÅ‘²ÈÅ´£ØÃ×)áç|µÎU–ÒüÈ  “²~_¬sИVÌcBž¶±U‘«"“¸+>ç̰bI<±Üüòhý/³¾kEG²jϲöÝÔwÏO}4)T5ûœ+o:G#'2n‹×.÷µ&6\éùÍž¾…îõ¼¢#”÷\æøƒá´ÍÞâÖ5V ‰×&âƒ\<öšsײ“y•Œæ1 "þHÃyˆetÎøvð븇•Ìà›|r¾ÅϹŒ]¤ˆHñS¾KwÚÓ˜´çR¶ðsF²…œ K¤„ÎIéçs/r ç›,ã)>â5FÓž¶œà5ŽókÙÆ»ÜË ¤y›“ôãqzð@¢ ™Gc¾•«^‘²„¸¶\ÀlŽ'¼ŒF'†óv’¥eRÁG\Ä"Æ$c¡\Ö¿)‹™LpŠ£Ô²KXÏ•‰—d }˜–¸„îå v²‘E‘bN°.ÙÞO+¸;YûŒˆÛÌÄ ó#º°•/078IšZ¸89Œ–ÑŒFìâ&±CVS“@KNUøg¹ú_qu$•0/šRUß3©Õä6kèÊÞ£œXO5[©ä$-ø%_å(Í9?ªgÝ.¢%%I{úš3˜uÄ ž +‹9‡}I*ôæ1‘Žü‘FL ­ÙNMVy…·(¦kl?O³1"¸ŽŸr@h¦Û&|+^ÞÊÐBMw{î®`_a¸7~˜¹í—ñ¥o™ºÀâ9N¾À7u¨ˆFöŒÖ,´g?d¸/úÚǦì7ù,s›É¶ôÎÓ§ÄxÖéQõÎ6N^SëbÆj,|Øô¡.}ÐužXç¥W-ºÍâOÏ¥Œ‘)Ùà_7yip8ÔSE†S„&Z¥´ªñC²ÔdTÅžˆ½Å€H·”nA)+èÁeŒ‰«óBÐ;Œùv]2o‹ýÙààþ{z¹­7·f|£Ñ5š4¶ˆY×P¡yÆöoàg²ŽÅÍMάєƜGŠ7¸ÁãE©è¢*÷Ýäé4§Ó™BZçù›‚z“¦#+# x€£‘ÊHãpæcFuÉtjïÌ™jìc2ÜU¸;j}sjO*²Þ9«M_à×<?ZçÙ §ÇÕ5¼ÎÀú÷ªFË|IͰtxš¾ 'Ÿb'„ŽºÔú”ª¦f7£˜ x¹6äëz|ÏBƒö»`˜'n²)0›^Ìb'¸ž,™Å0~Êü+ï²€MwÆ^§ŠiÈ£‹MgÃx•>lMÆø¹¥…ßó—H÷È78“ úD®‰tæ€z¬~'ºð:Wò2‘!MŸÈORz+ØOWÚ1ŒR&0'™‡åöa;0’¦ì§/ódxY’èO´áCúQÁ|Z1Š<.fssZ¦ÈRîš3Ÿãte>H%'×ÞôàIúq( ~‘¹Ic?í(á:Þç.žgk¢ìšÁ›É&o[q‚(q|ìOÜóE `™ÇaŽSé•2!XCoN’jXN!ç&Û•Ôp"Aöå6®NQÄ(ÖrNòô»†žôãûiÈ%  ÿHäéÿö]rWwª©ýïY«þÏ(WÈ&çÜ£f+w±&¼O9…\ö¹yéEŒ¡7›©dÍ™Àl:³œTʈ伵‡NœÃ&60‚]td +™Àgæºð+R”s3ײE<Ù—òí Ÿ2”j*èMw–Ò‹{RÚð);iÇ^ŸŽURì÷ëìl`Þ1{z²§~êvþ"!ÏfÎ/RÕ1½òš`›ImSÝNzö&æ3ÊÀ_¹ºÂß¾åéJZПsˆT¯óê$ƒ¶….ûã•cy‡.lrÅ ×{4E–�� �IDAT®Š&?™Ò:hÈfуÞ1b`“×Ò-VÀ Sbæ^E!]ym]ÑHË 5 -ŒL f7±3×ù2lO9#åœH³à^RÀœXk2&½àÜ´‡ï[}Ûíõ¯ð佩g›5wZµû)¬Ô1ölŸÔ)«UÆ¿]ྗRëšÚ³—?§½LªÖˆ>)ÍSÖÝSõªÏ¹ŒµiRêÕÉN}ÊõÔQB[âz÷QºðgŽ22¥³´hâ[o…³÷èÝEûÝñ/ž·³¹Mï77¨©õ•žæ°ó·šðwíKôÈv‡³?Ô£$ýÁá7i›z¹¯<^›uø¾ÉEa~tlBO o´¸›“£)¦S&û4eÌ{¾3YŽ©â}®¡Úª^½ÑÛó"—¤ õôõ4çºÄÈþy•óiÂkœA60>Ö‘t£gQ’Ë’Ð.ùöâߡޮ¬£#‘¯GŽ„z€Ð ‘‘ Án¶RK)ó9Â1õèävdr'È`!Ÿ0”9Ád¶šÛYF«uš˜/QÆj2’I·öýèÊVå<#IH¡ËéÞM@®9²Ì?‚ìe ø.GI1,ÉRÍ>vñ¸<gåæCŽÑ˜F|JË$žØ™Ä"rܯ"²DœàZÖ3€®Jö׳•ñ¹J¹&exÐ’=tõ£þ ¢€ cx’žXÆÆÏ…,Îc 30žM J–«Žr~ØÌu#¶Ó‚ÕIà¥ã2aîêɉϩÿY®þó¯£ÿ~nlBUÏ5èr“­,í¹Ž}çvæ$HÀ(Ùl-'¼Ì†à}>¥ß`³Ø’Ì`ûSΑÄ^³‹ÀDš25yÓl“cŒ2œEìŠ zÓ‘*Ú¥E"òyŽA3–p>XMdÙ]↿íÑs4a'›Ý7߇lëD#K;8¯$*º5d^wËÉð\ÖáŽWÅ]zþǧߺ,f'C’)ÅÏÏØq½“Cˆš:Uà@Å÷?0ú˜ì NÑF¶µ…Ýìh•*îV¨k¥aA‹\$crìÇŒeYÚYwEŠëÌ©1°ÚžØ?x+ø$¥[ÊW³ÒdwP+Hy%å›A/ZäÆuNðçÉJ^ô‹-–òá$;®â)MjÝÆžä³j·TÕ/¸´óÄšjÌe]žryʶ`Yd1)x“Niýbßâ�ƒZžâ ìã/l=Íé'òŸñÓ8ACvùÝk–¾îÈ3ʽµ{˜}ì¿<¥mðYÎÝod O•šy®ë4nèÈ—¼|F4wKЛã®<dÁ×I[Þme`Õ-M-?±Â´*›gÙ•¥Òõ¾›‘™ASúZÖ›ˆgiÉ\z±ŽBꘘ1>(çI1–v¬¦–™¼Ÿì墭¹¹ãtúse2ó_G#¶áõSœtc,Ë9# Bc.áÌ`QB9ÊcS°”ý,á>%)önsÛ“æ\þÆMdƒ{q…,â¨z÷³œ 9óèC+>#ÅXº«OF f yÉJVY‚@ìECÞån6°†Ixá8­iÊqŽq‚–LS¯«Îp=M ’ÏÃ)ÎaO’ÈÙ‡±³xŸ¾¤9D%SXšô÷²™ãìánš3#IjçP¤I’Ì‘8Ž%¼ž&‰Þ¨!YŠ)åø¿Øä GlnIRØb$?jnV—f9ûîbI²:&9Ñú°ø¿s­ú?ivõùmâ—�ÇP—ô¬%ŸÝœ—:•ç­X53øŒõLg=G2îËøuÖóÔR–È‚;ñ=Zp.oóÃÙË9œF+6äùJì�O±VýNå[¡ž¯ñËÇ^ÒÌͤãðpžg5ÇøBž»â•Xøc¥ÇI3&Ïu I]Ð$l]˜Þ5¾neǸꭰ½Gçûîõ¶±ž·óªÎiÕ¸wù¯YÝ8ìÎY%§RJƒEƒ\x@«j›†Ó*ëñjãã%[L;fòÖðÆZÖ·ðWýV¸|£¹ãª-‹\kËé­¥ëd뼜¸ÄFÅÚW»¬F9ȧWç”:ž²?äŽÄC6-m@‡Ë¼ž1%ˆxÔø…ÞÛ¤áÑ·´øúk ޝ¬v”ûkknP•5Fq]¨ßH]C¡ —:{Ǧúþ’hÕÊ'•¸‡fÁØ 8x›ky6¨b]Ê÷óLþ’qˆÍä Ž¿úº?¨¼mgݳïK÷’þWéÉyñÄØF©J¿ê÷ïûæ~ ¿iÃ$%Cø(¯öWñ-‹|0¥Îé5žà*'z9w»#×;8Ë ‘~³À9kÍý0œ”2(epzÉ”ðû_º~‰Wë„gkÍÉWãøäUé9_Œ¾¿,,8©ü;œà·Á™ý 8ìm.á=®e0¬MÜ9H'Þ Z¿gƒYÔÉ¥žJÒ=cYÇÄCŒ(ñVRd+/1Ž ã)LfEKØÃüÁÙ,b3kØ@ Ær˜³©aM‚×;Î:îc%Wò8•4§;Ëòü0ömV' ³«“±ÿ½‘2n•sg5;McôµÖ°—¢äÓÛ‹ôä(Or„jŽ¥Ý¹=Ñ�½Ã¦Ò/ÉžâBÖ‘å ¹,±¯äÆÄë¸—Ñ f0?b û¨åDò½wò6{ðMW®bvRš2$Ájü[?ídÂw?Ä4.eirª;Ɖû£²œ ´ $[¹=߈ÜÆB6'¨‹ÎôKf`(y¦ŽQDm¸…©¡ 7²(ûÜ·øçšðÿÖ«šlÝÎ…”SJw®çbn"ð<¸:Ö—Í,SO—ȧå±õY|‰6œÁî` Ÿ¤ JYžñp\ÏàšNŸrcd;ÙX!orU"«¾‡«éÌûŒfլϙaùˆŽÜO3ÆD6r'YûŠlJigªòL²Y3ƒ‡ ÖÛúó°ëH™Ÿsw¯óÚT¤=¹™ï°»£{Nf•Zì‘}¾úÚNv5ŠìŠ<Â'•:÷Úïó̦ܳ)ø V©´GÞão†§û`³Ö#•ÎT½ÁºóG›?"ëæØÇ<Mó uv¦ŒÏ—­s€>y¢`yÆ÷c«x‘ JãjzÓ32¡‡²*ùbO•Is*eDð5Ê:»ðT~jÕÚÛݺ±ú/3jœ ož ‚-uæTÙÈlúPLÏ<#ƒÇ£›¤{¸x•‚éGtøåÉç†p£s_ÌcÜŒÈ:ÌŽûýʨâ—¾kÁCîjU÷Â…–¬‰î¬ŠîœãÎéñæ“ZntÓ]~"sÓÏâvç{èa{NªÞ£ª,[ê˜J}tfFƒ`;›U5j8çªê‡žó£CZ—¹p¦'ÎöËUö|÷Hy¿®t¶—nôÍ™†Ô8pM\9Tõ )߈=¦|D˜¼Èo‹üv-Åt¦Ïah™Z?0€ÇYÌ\ÎfEd[—D4o.µ‹©4 Ÿ?“Oj9Xg=)Æ0î,àŠ‡"2ŠkÇRîf"‡øuÎöºȭiÁ›T0€ûiϨŒÞ±IdðÛóÜû A+½LAlHd chš8ç:RÊBöÅf²Ù –)´b'cønr¦ËBFDzò;Þg5ùò©¡Žª`Y0“ öЕ¶ÌàíÄ)•;Ìu¢ ÛßÎZže/§³ˆ%´äÌáv$6ÅÓÀ=¤9ƒãÌ£Ž‘¤ø./ÑŒ›¸-Ù†<D:'‚ˆ\ iÂaPÀu,å‹4K}Ë“lE.ì׈¼ÎX~«4fZ2·›û¹§Ü e;hNsê’ƒä5½–6Ôp˜u\DUŒ÷ÿfìæøÅGþY®þ ¯­Ihðó“FÜ/ÕŸu¶ð×%™£¥¦íÜL^à=Ž3„ýÜÁ9AQÊ%Yo&NúÀò#R> 9#íŃmíËU|•×ùéâ™»óKI³‰ô§9{(ϸ+öÛ¸¹”0„¦-œ¬±)xa.ÈÚú–]el©‡óv\è«¿Keã !5¥õ¯]'™Ðxv~öî-!omjû×#Ἆޚnãѯ/ŽŒI¹+ØÒ!è@^¬UæxðÔ¡íÆÆ·¶È¶ØV7óÓ‚´®ô¢Cõû¶ik 9•Ù0¤M|¨Ô:Æ~ªÅ×âk¾gH/Ç)ù"·°-rfZw^*poe}¾vW§t šÆÖó±¾íÜ´³ê{ck­Òà\·®HýåÁÈ­Á–”!öTô[hÚ3ö_èÿaï>ì*ïöïÖÞ30ÀÐ{/Ò«"EPDE[ì1v5&ÆÄ;Q“Üi&šcb5AEEAE)Ò›ôÎÐëP¦îu=/ö¬äÿÜÇóæyóÏ\¯88fïÙ{öÚ×o]¿ßy~Ï3ëS:ëê*«0 ¥s¼m—&%ʶ…ýk˜Ÿê“ }êëS Ï"M6ÙQLMV0•cÔ2¤zê®¶¡ÑoÜ0Æªšœ£²‘W.L½Ò7ýÊÍá•Á¾õ´¡Ë}ÙÑC_‹ÏÞˆSùïðèV­êëØÝÞ ×u –Ôs¨R§Ø“åÖ—Y`êå^y$šúad4ù&·öÝ#ÕK»Uß¹©\†¿yåGWzx… µ;­›Ÿ§O¬ÔÔ­k:Xµ%ö%ePPȾ2yÚS]¹:檗±žxŸâÈ¥icSÆÇþÊ-|ÆV&f7WªÊ­ßD†«ÙHC^g/å<ËDê›vY¨ÚûÆÐ—IÌ£M®à¬`/×suù‚Ëø<öSŠ™Ç9 Ma/íhÂVž‰ü(å‰`9ùd4wr(±ˆÄt¥Ç©K:ЉŸóeVy6åT¨ªj]ØÎŽdÔ׃I£¬?×&Áìt 1&Šát`%ù„˜Åf²¾ûE”'¹'y‰ŽÔIò®>O~ÿˆ+ÜÉQ¦Ñ†«ø;Hrâ;R‹'¹cÔ¡” ]xOÖÓ‹ÕI§îXRÆš'’ô4yUmïЇj4J\ç¹IpóyLæs¶ÓÈãp”Ág™‚s„N´£U"֨ŶäªÓ‘Uÿ—ת‡rõ¬Ìfd2&-£ò¹fÉÛYs_uÕ3NÄê38å\j³züžIÁj>çöH£”mÁF27ØAGZšôk/ßÈÞã ú±‚\¢ÄvÛ̆´…*ˆÔ–ØjSF_¦0œ#ü¹Ä¼ )ùCyífÛ»—]A¿”ÞA‰^‹­8eî 6²&mtp(2-åLuWÌ®=šN7ê[ßÌ^é›Ö…êL‰Ü´IéIȵ3_ÍÒ é¶“o.îU‘ùMSZÝ™Ä×xù6)E‹ã k/è•Ò)Xí÷\ý….«ìîaó¸,ù-åâH&¶¼DÛ¤ 2šD†éªÑz“[ ùÀ¤å Um…ÛƒWŸŽÌ 6¥ó[×üñÄ3]׺¹PÿŦ=eN•z!Ö<å—ùî,Ûp•fK¼þ¬‹Þ ùäו_šnÖ4|ÿ;Jm¾˜Žôâ”KŽ’I=÷•0u=ø-]ø’yÁ§±ÚtJÜ:LÞem;×-Ò³‡oö “ïÑ jÙ®èTŸ ^îII‰¢ÈùÁ)²'mXi‘Ò©L±ðáÐmvé¦ ´eãì-0ù ͆h_'=nwîȾe#g+gÊx÷¼¯[73Ú¦ô æ’¡/¥¦UŽï§åTú eìດ¦±Æð­hÀ4ƒhÃnê0†4Ntæ$CiJ._Ò€Y|–xêkóïК5âzz°:làV±†¬I¦ÂÍiÅ ê0–R6$.«½A)YAudó“pÛá䲇“ɬ÷3Úò ¥gå»dw¨ OØCcæÒ•\6ó$¹¬LdÛ8“<5©“H§%–©”±‹• é2kTà0CØËPŽ05!e­¾GÉIî\1’mìNDÙˬ1ûØœÆÚ$”¸Ép¨(\\°qûsºI¢|%Œ¢;û¸ƒÉRÌà.U’÷¶td3¸Šƒ¼Ë *’[õg¡Ó“|Ž'ðmgíŠÕhžè/þS®þ¯[©Äµ¾Çè‘àÌ/Ͷ*tŠÍ§ ³XÏŽr Ëy…ÙîÈu¬b3÷Ó”…”Ñ%gímñî¥,gCYÇn¶'(Ïl–OÄçiom©©|™ãÉØ>¢iò=Ç!öS3Ç‹ñ¨µjEÑ’ ˽\å›yd™âUž^:7÷ZEê"Ÿ1¬Rÿ¿­-O_Ò54îšÛ™ü”®ÔÍØÈžP5ÆŸä6Óý¤ïgä–›Söå­A&‰{¨ç͉úò—;Õ¬óþòhGVÖ?'¸-§y›xÌÇjIÏü/›³i–—©à\L7Vó÷ãƒA)"G"×Õ5ifÈïM:Îñ5*'G?Y¥¸Â×Äßšr¦ç<ÏöõQ+»o÷ÜBçýæf+ÐÀŽêõ£ö„UMÍêdaG ÷[¸*Zx:lè¥×æt­a¶¯êØlè±w^Rí€?î ‡³NÌû)`(µhLmÚ±0rmð)zl½I7åì¾$ãû¤lÙ-¼¾líìnÊà r„ØÄØJ­+å$ªåjêhÌ.sÛÃùÌäj¾´i¾ÅÆé†;ÛÚÙÛÝ+Üý±»ííjF§ a5çRHmZdì¯ô6û¹.‹9vÓ—V4c+½›¸îŒzÌgkùýxCce3-ˆ“tÄÎ\Ès¬M¦ çPL;ºòDu.f G¹ššü™ (¢»x€Á²œ=ÜΗôgýËdöp5;ØÌböó,S’œâ#\—ãžØú±›|‡‰ji I6Ó­\IsêQHABTi”ˆ 3tKèì5ùiNgÓî¹=“ðߎÜϺ¤uV˜ôëÒìg?|%Ñ/Hb>r¹+Q‡×Ç „%'ƒÀbq˜ëÙÎ-Iß/‡óx›OÒú².‘§Gª‚úŽPÌ=ôOT]YïÍåÌáxr8+L¼Sûú³¶»±lbÇY•„‰œ½*ÿ%jÕ¿I¹Êã,J7!z¡2I#ÀbF0‡úüœ#œGs6Q—µÜN^Q¤ø’›–`vï(g‡èíÎB•s5r—s{އ‚_q!Õè,’²5-*}‘U¨ì%Œãþ¤ï\»D]ÂàÆ<ç¯ýËËgD ©ÞÈmSÍåíËT/5ñ5G…ͱ ‘uå{)˜¯ôþ°úeCugïÝ‚ÿæ¼(5<§f¯¸¢’ó9YboÆð”ñe>urÔ8êºM8èëÛ=ú éÍ]ø†ãÝýò&«s*m<+ƒfaõ(oôZ{ë® •Û¸œ¦Ô¦¦=rÜÛ~EzåkUb[ðC†´ßŒ?©\.|bÃûl±±•îœï¶_ûc—N×hŸ6ç+ªç¹ò[ÖÏRÑ®$ +5K^Ÿpÿ|ŸUôŸ²:Ç÷âÌdÛ†øòL¸s§ÓŠ'ü>s´IôNQaÓHµ¢ÇëEõ"Û» 'x“åÙ@™ÅÕ5j¿íÃþ7ù:ÝTæ€ÝÃhÏèI)y àòÒü#•5"e?JIJPû-K6*;fÒ FQ‡WÉ©šð‡¿Û¶É¶¥¶õ¶¸·'§Þù 5ëx(ÝJ#x?;Èd}y޽<M“„f´…í  +/1·Ì²`lŽ bSÂBÞ¤^ÚS,Êñ`ìà–rŒz¼uµôÒ)K¹‰‰Ìåq‘›ãÁiÎð!iO¾¤ })L@à®çÇäqÛ™›®G%,Ä—´dÙò`€*µaÖϔLJlä(ë9Ånör;Íy“œ>+ZðåÔáv&3‚[’ÀßlÜÆFHz¡YïIäUVv±ŽÞtäL>«¸;ygS?ŽÒ€:œ¤Œ‘Éøç÷ò“$”r9Ô໌NTæ“—}ˆš\Ÿp˜NSx@%J±rºPÊ1ö(f6÷q)תŠËZœ%²“…ÚI…. {XÎ%`77ŸEÙÈ*2®NÊç¿Ìúw(W7XÁ�:&9Ö™Ä=~[é@gæq){˜N=v°žŽ‘5Q•IåIÎMXÎóèÅ ªâ60žáeQ3/ÛIJR½ÕôcY\¥*ž¨ÙõžüÈ»8¡ÆWjîëºÈS•vñ+F0‚çèÊ"–ëN¯r7OôÈ#éò& j¦¨X¹‡>°ëbSë;õwÚzy´ëßÐðo9®8í·ÅåøZ°‰‹U4Prôàõ`/_DncŸ+nŒ™ïÄ%¯Dg. ~—㕦ät¿8üîÇîÜéÀP·6óò&‡O¸Æó!=áJËÇEnàÕ`EÐ;Ç­©¸f|Rúä•Ù–²HÛÈžÃè [úüpoçóËò_*92Ÿtw¤\iÑÓ£ù2½,õyc¿*‰½[}àðÌE+tŠ¼ÆÆu6LÖ¡£©[^±zC®ûrž]˜™¾ÄÒ¶L§7Çæ¸Py#Ÿ\é©—2×_gÂèºeÝÓºWئÖwÍ­wôÖèü‚ÊêMmý9Û¹4ö©‡¶Úue4uoP‹+’üÙN£7ãy‹!tI«—êPœ™ömãf+¸<伎ßeÞB[KÝ0Š4g[_Öÿ÷QãÌ1'w„“׆ÒeiýhnðµG:r<­ É¡×pŠ·9Á@z0’è•…ˆ§¼{56ŒñT&7ÔÝ‚VAÍX ;)£åÜÇêò,+OUq‰š°˜ù§YûŸ06raä({YÊ0‹õéÂqRL"Åùœa4›éOÖò:{¨Ë8 ÉðÝYÌð�eEÃÑ7‘w×g¹Œç8'üò U¯Ý©Ï^îf3ˆ™Æir˜Þl§%k¨Á·Lý¸*ª $¼Ù4Ï¢&“4Åjœ¢ •Œ 2 Çú428r{YIƒD‰^H%ÝhÅ,¡ÿÅa:ð<3ØÍ8.áÖRžø”¯`e¢_¯¤Vbоr–Ò€3+‰’˜þÏÉô7r”T¥%|›_‚nf=ó©C¤�ü—«Uÿ&åjMÒ¶Îzœ•˜©Êá¤3;YÇFRÁ|¾JÌÒ”'iÃT£-£I—Èc‘täbÞI’u®-¶”&ü–td´¦-+4­ݽ5š3ÚÓ#ÜS¡ÏËÏ|Z¾§}]­Ê}¢%\ÄA¦8ÆR=JÒ5ÉSQ/¶YË^.˜aY {¶p)5÷*¿ˆ_ž¹9­v¬fÐ/ò~J›`e¬<åæ â©´6®yÊùÅ©×Ç„;jëØ>½aD(ÙJ* œßø3O–ûÝ䤴§–ß2/ “WP=­o1/¥n¬E¬&eÁ–ÈÊ´±Í)Ý"µ3òR6í¨mØ›ÞZ¡å>÷ÏN­Úw1/ó¼z©¢¶ÝžÐñs²#ëTµÇ5)][dϹ6•9±…SÖìut˜_ÊŸX­üXNòŠE7:T/É;Ïæ:Öb'ݨ4õŒÊw©^æ£ …¼ç¡UŠ//}}d<{D¸ácóöòx¢<^˜cMõ FTVlH¯üVmW–y‘-<Fs>£ArŸMH§…t¡»»F¤:· ]W(Ž<¸Yf—0„«˜Äµœb--i—8™fÑ•cL.gŸ?Ða··sƒ|†³<‰ÌèÊeYVw £x“G‚e‘K"Çc•Œæ ·RŸŠ¤÷•an¤¨¶Ë}ÄLjñWF.ŒÌe73œ/“àÝÓ  9í³<³”C‘þÁëô¤6'©FäðéÄ0Û4!å%«=´§;KØ@cNÑšATГ1´fi¿ÈF ßÍ.1‡1ü*Õ^ÆÚ$ÍÒå iQ›º\Å*Š#½RÎ ^à9Ô£¥¼E>]XŸ®rææ±Ÿ/(â"¶Ò–s9Dr�GavÞœ²—Þ<G?j²õ ¤€l`'¤ØZ³Ž‰0»·äё˙—Œßzª:Î6¥ (çIÖ²â,ëÕ!$ø’ÌY»Ü`¶r9Tž´ý"‰dÓþënåÿG¹Jù_¾0áŸÿg<O‘f!,M1ç0“Ùܪ®§1É£æ2ŒÚ¼Évò!‡XÎ@V0áì£wÚ“Ôa/8ÍQ–¤UÌñã2]¸KŽùEpY¤^J«¬U>­!¥Z$ÇrèG!]¸+íÆ]Ë5,¶ %ü¿3×/kq"GµºPÉ>ºp5-ÃÎLÕõº(sË·Bû]^fpäë=õÚ—ùýwƒó2ý~ht ø±oÔö»7ݲ¤Ê“ñ_/VÛÜ®ö»ý9Î2¾“íȧ=Èv×0—¨Ò™«ˆ•󗌑7RV²\Äc‘WÄ£? ýj¤ýT‹zígE »>å|;zÜßR̦‚FþR×ׯð{¥¿[º¼†5Ùsl§ˆÅL£ÓhAM.N}&rˆ1B6qfªpšÎ0’õD\–dÌc'mj¹(O=Þ÷T- iy‘ŠÈß9ÿホÝ:Á»G•=LKrx“‘»Ó†&…Ë9HsVp0©|›ùeºê£9ÅaZÒ1‘œ”9l¢m6±žél'‡¶l¦+x/R7Ço"%LàM>f6çðI’Òõœ`vrñßEc&Ó$¹Zû111âŒbflQòKùÏÓ‹ LIéÛq³lÅ5 ,ç‚ä9§'ÿXB!™J7Šy“•g%3MáU~™ˆ²ï± 7ÓðŸBc˜À^z¤Ýy&b,L¾ª‡’/rö!µiÂBNp‚—S¶ÇÞ –p4ùZIx䛢ù4öRI»ä97ÆN…ª0Õîd1=x“í´çÌ?7ßÎþárÞ¥Qò1aÄYœìõj.¤¿M8”¯Ðˆ›“—z #è’¼Çi‰òvgò‹ÚªJT¯ÚíiÈòþwìæÿ&R‹¬«ÙÉ j$t‰Jð4;@ÆlÖPÁuL¤ »ÙÍ6>¡'èÌÇdØNW–g/÷´¥YÖ²�� �IDAT'h,àNSÙçô½º4­7„º•_üÞìbÇç3(˜9Ì.š2’ÇØg_OZ„Ÿ¿¿wu…uŒËÙâ*ºÌ1c;Ë9Âõn;$?ÇoÙýpÆ• ù3o³6èÑBÝ ²\Y“¾®^øõïýâzÏ;.ð‹é¿êºù¦öñÞt«º\hÙzˆè4/üb™;Özí*3ze4е¡1+©ìÍ1<ö8—q&ø”§è@ òy5Ç£±'ɱ³´ÙÜûO?ý©ï]æÂ¹á™%áㇽÿ€z_š´ŸUteõÉp…ÊOÕ(3r´Îlél_¹¡;o;ôˆswúak'_e9ŸQ‡ ¸<i ÞÎjFÍ14®’#ß¡¸£¿Ot°I¸ésÎó‹?QÉerMùõ.¨wª¢¡•}Ëô¥=!ã“ðÚ‡mu]޹7Ñ#(Kù<eH¼u;¸|Ÿß-_ô6¥ï,4ýG*_£-{O¾O ®&Ÿ¦)›"c‚õl¤;íÍœhnqδÇã#GéFWVDþÊ–ó)ûØW©k¬(TíSO%s¬E‘!¼N70‘–I°ÅÖrëØÊ®àÂ$ðwÛYðøò( ²±óÊ­‰«Ú¡q3²q\4cPQ¸-ÜÏ.ÞçB®¢9ïp Ç·âª(lÚz9ße2•œ¢3¯PÄ J¸ƒÝ\Îvò“$ÁîS†S‡±“bŠè’Å#…*ÇH="F³’±Á„ºŸ&äó9?§ÞåbÖ³;Ñœµ dƒû¹8­v¤ð èDc¦p$I$ÈÞñdºû(æ O2ã,;M]z±4Q:dsÉO'Á‡èLcõö³–퉾¼"¡[eÑÛ»’f¿h»ÿyg+'—a‰;[ò E‰X?ü+î×ÿžÊÀ¬,Hi+Î:Vç$ÙÕ¨CO¾Í@ÖqQâóÅ ¶Q“‹(d?HÜ—íÅ)¾É¼Wf çhZNä‡9=m}3#&™}Èoo·eŽãÃi—ë‰X'¹™ö<Ëv†räm_šº35幜ÒÞÁ”à™Š=]u¡Ók¾ÎZ£çxy“ wE³®fìa- è©ÚdÍ'—ÕiW^ç“PçUuÖ†Á+-¾*ºi§‡RÝ¥aÃð½5?â¶EæW*ÞmÑ-§ýäÔ®K­Ê7©Wôöm|#x8V¾\ã‚·ùÍéËã79¾—–kÄÛl¡}–yšÖ.6Ÿ»zæàÒ›~/zÑÁ~N4°µÜÐy¾ÙÖm¢—w[ð¥åL`+ïRiÏT-·ælŸfÍˉKR¾›KeK_;µîgÞ»GaËÈ¥œ“ëkq•%Ÿg¨F-fÓ•‚ØO¹€öŒ©vô¥†{o?Ýî5‹ÜUæpVË‘û*48ýei¸ë¿j*ò“`|ü§/Œ.ôË´—6-ªàDM ›¹ªèøVo>ìÝm¹/}|Ht¬KøÚ_ä91‡á9þ|[îT-®Sç2uR&=ã¿Þ ç. Ÿ T~ˆü˜:|ȹö<y,¡½ý„'kiWÓE¥ºp/ ¹™Y‘Î9òcï1„‹˜Ÿr"òH¬%P=å;)[‚<~—xû²˜Ôs)áeVG†Ò™-ULd¯3“ =KϘF-¾ihÿÆF沆-ÜB –SÉJÓ‹}ÌLŽ’5bóØÃãŒ%ðMN3…%$²ÉtHzŒ—QÁ$2Ìb5ˆ®ÇO‰ØJ' ±>Ôb4¥¬â=ö&èê54¤œ¾ÜÁ&Þc-XÌ ¹”çx1˜Ëøäæu óØl fó½d*¶‡£Ôá†d°trâDžwDUåÙbñl�÷1jRÌijð k‘äi2Ù¹/yD<’8;Gqšã Ã)J j¶Lp'ëèH†°•B¶0à,ÂSWZýó^÷Ÿrõ¯´.e?¥Iæi ]éKŸäËvçñZŸúÙÆvF$QžÙhÑóø&ó9Î^Zs&íéŒòEJcòbßÕ!È´57_A;eï«2TµŒmæ÷±4­2šÌâ¿Užp×ÂÐg{êEUúXümÍ Ò'o´­·y.YjzkÏÏ14öWbFé{TŸ ç»ûâ±[ÃØcO;5DÝ9Ï‹w÷Š4RÄêTzŸ‚Ë½ßæT89QfsTZœ.»™ãIG(•6>VÆtJ™G<=ë™YîóØ3ìJp8c‘a‘DÁò&…7/‹]óžyWûŽ©—ùëlÒéG^wçÎÔ´½ÁVòù-SÄu­¼ªùša•ñ¼úî;iË)9e¥©¨‘–ŸÖ*ø[Æ®¡‚E.,¶gc™CK𚦮áÒ°üôÚÖ:ô7í+÷ñLTu>ønŽþ±!“qNk;+,Ê×´N‡èLßåî½Ë¶vV4šZ·„z ‹Ôg òšÊvðEðxPì­ú©Ÿî Ó2œŠCž{süý >5vÛ˜ÜÔõÇ;E›jrŠIÉo]6p8eDdEЛü ûJýœu4å—4¢f¤"XW x>¡£‚“Á~Bׂ̓¥Ä g# x€±¼Í*>'ÊqGlÇ"ŽäKºf=§Á“ÜÃú”+r4æÐU 诈rêr†>”qmƒRΜæ!±ž y?ÁŒ¥É¥)Û¹”I kcøŒÌ£=—°=aOHÌa7%ÖÖÉä; ¢1+y‘Âäôp$é(>Á:ÆâK 8ÁéÄ£Öž/¨ÆÌØìO¤ðÂ"ÊèEšùtä z%]Üe\̉‰ø†æûµL`¸–Åg_c&õ¹”º´g%1qšÑ¬å<®¤ µ8C†<Î|šÐ+a4·¤¬Ì p‚:ìI•MTOÑž ‰rääÊÕ¿âÚ’$ô£UbĹNs’:¬æ ùlIl:uøÛÙÌ.>c:yt¢#‘HyJ÷Øg”ñÕ`R0ƒºLã—”¦ÑŽ^\ø $èës‚…,ã0ŸÓ3éÊ;º3úî/ý¨8üŒ¯©U?-uhˆ:/¸¬›å—¦v#ökNéºÖ×ûá;ò;:¾Î#·¦&\bBÓô„þa=ç;ÏÊe)[Òj¦ô ZøõrÇ;zv4“9JEdodHMµ+Þ ŒÅ)—d,K�¬Ymî-6UÓ2hQáÏ3€&)祑‘>AšyÅn©¶7ª>aOÅ#úiO×OW›o_Ó¸8õå/CUz -ù;§OÙëyÊ V±müW–g|{™s¹‡{iê+=ëÊFÖïO€âWq„öÁÄÚî,ñ>ç[]iï\öGE†3kë]ncœ¿ßöºÖ°7òYæ¼F -ÜêÌdy-”6´7Ð<2(ew°ÄWÞTpTE%}Ùî–Ö©Âae3ÖЄ?{°…½G\SׄnÚ§w64­kZý` ŸÑ’ëˆy™TžT$/£ˆC4#CµÄès %i̓º\ÀLjSšr$ßmåV²’ëÁfó½´ÚÁGäQ?Ó†ºÔ¦O¬ÏÑ3¥3+( ;Ñ‹£cs°$®åµá1'éÄ�ј4_e}¤<¥zP|š„æ,b)'Y’0¦ i•ð):МJiÊ1ºÓû˜Ä1„²¤;z8aï¶`mhF)l£”¾ ¢E´¥)³(¡ ,L¬W)&M7v‘¢!_#}Vô{¶\eØÏÑ$ö÷M–pœ†ÜMµ¤Ä–&ƵÃIÈagréÏ!V$>„…\À\šs„ya[Îp,qOï§„"Þá(ûé‘t/SIg'“P’rÊhH#þ¿ÌUiúPÀ®ÝZõo(µøÿ¨[Ykú‡¼ÁiÚÃì¥' žd—•1ƒA´å^ 39ÉZV1%«Ä UçýÚüŠÆte05ø‚__ò·'T•Àúñ[ž#—ü)I=x3(´ýjÛk¥.k«Èñ=bµ0 ”ÒèXÜW^L ¯í‚Ç‚f^?æÎ-øùhßü—na?Ý( Fr±YœSêœÛ"qZ·X*¶#(´·¾—o¦wÓ6h+Œ5öÑ€Ï8“ñ+öEê¥<Ÿö\$_³ã¸—Îø ŵÜÝÖyI²N^Ð=Vb¶ÄÚÇ¡#=ö€E·ùýÌôyÇ¢Çgf<ÎúæbšPÎâ Û“(¼¾¼@Ì)ʸ4©a8íÞÙ™ ç»÷“ä-àÏ<ÍOyû˜g¹’5ü¶=|›B«ØíAu†ºè²VÓ÷ËÜtú³¦ºÐl?c·Å%oRÈGô¤‰[–h1ÞoúNuF4ukÞó¢â¬Vø›´†Ç®¶ªƒ×7yýÝœÔ㹇ÇÔ=y =3Z0³ºûëhǯ¸„¸=v"K>Ók¨Ìw)]¨MÎO›Ë´á<ÊùŒþ/$ZŒ‘eiwЙéÁAªÓœ£ôauI±)­gÖ‰›¬æ >Ihâ#h¹5­'«9œxZó(ehŽ8Ê¥,åÕ,<œб‰T¢‚kÎ@Jù„êT²‰aÔa&[ØDMç3¶ðWúИgèN9g8˜$ù6g)µéÍ)æ29Älj±2CÚa\$/¥„Tã[ɹ’ϹœRJ“^ßhºsA¾C_ðÉY™4u˜Àºì¯`|‡¶œf!]iœ÷P+ Üy”\†py4IT‹™³POXJ}†f5«³—Stÿçíë|@Õ¬Îÿdþìß®ýïvºúÇ:cŽP˜4£ÇèÊçÜÀß9F{yˆ¥<È4–PBDG>e$ Ç‹\—ë¾ØfÞ¡;ØÍm¼Êþ?ý.Ñöl¤9YO[Nr±liqŒ›‚ÚÎè:M‹VaÉÔ`±\°Ç«%JÑ)œüÍÂ#ëýp¹§7¯Qzî­ÑêÕ¡<?Ó€Á_‚™tV¸ÈÇmêlßtÆM‚8×%ñŒVÌf5XPÍ3N)-÷a0’ºôI»ŠË9À,F-CÕÜn4MYô©pY¹ZÁ5hê…Y¦fÓ.­æ­Õ?âW®=`þƒvWX¸Áü</ ¿<íˆÒ~ôæs.‹tJ–rQ0)×#±Ã,¦ïÐ.euÊ£Á¶gå˾uȼ§Ê6TÚר·,lN}žçÛÅy¹®‹}žµÜUº/£„èÝÐÅ%~¬pÁP¯ŽS2™~B3+šøåËF¹i³_ߨx-wF¤Æ…—Þôò>Ÿ–·ÖkK*ï[ZÙý@¸§<]16¶Ÿ5,QÚÇÆl¾Þ’Ÿ†YÃÊsjìÝVÃø2øm°­ÒšØ5\B.2>‹½ÏjÊ‚6—Ʀçz,6››x#TePI¨7—TÈËŠ†rý0cƒ©N&ˆiÅ&ó ýsô½œr²:ò¶ìäPÒË:È­´fc8̾D¬‘M<Ø,¢d;C©Ã—±ŒRnãsÖ±ƒ¯p€¯²)ñýŽ«H1ÚôK©n!°€½ 9"CƒØÂAnà@BD¼™WØB)“Ue¥Ã~ÚPƒÃìd9ÃÂäêýz2»*¤;w&#·"Žr€ÅF3‹½¬9+«è[XNmê$|Š ÙÈèÄCýÐ-J8É8úpšyPÎåLå<Nœ%@ï› (N&Ï8LYb%þGU+cý¿îDê?ÍÀÿŸ«œrîæoäPž�%kò-bó.xˆŽ\Çjóx‡œD]Ú-vCø”ÖDü’g¸•V±%<ÊóÞg7wr ƒr\”åVw¼C£NÊ6+Á bWìË9ysØ×O׺ïöA£\WÄ.àwŠ[›™ïÏcì{݉˂T3¡º'2uÛh·EÉV1 hbúó~þžéE*·¦õ‹ÌË8Oá3ŒM—ëó´Ÿ”{‹•Açк¦ÓG„žü9øK´Œ‘Út¤,íû)ƒ‘<Qn¡&OøÓ÷|ê…üԲ˕uȘvž1øˆ¥?kyôÞS¥õÒ.4í’°}(_9,cX6œ"ØÔe`ì1îHëùzðÕƒ)A+žà~j¨[Ãj-¼¦rgµnѱÌü«©äPÊÓ)Õ‚L nÊqW¬‹3ÞâΔriqë5ñôí:z´Ói®â3ºr“µ}o»emµÝ~ÿ®\Åö„¼T6ÃÇÛ}ðm‡®¶®¿”dZ/O<e×%)¹qqu;]•;0ÞÓ2ó‚Í¥Î-Uö¼4§e‚ãË6…ð+Þ Šc-#wfÜi@mXL.÷°)|‘cec_9c·ÆòyˆF|D1ùtb-è@{‡î\Î,ºSÀ a%9ÔJpÏÙÖ÷ÏèD†S4¦?cçñ}i˜ g±ˆ{s]ÛDw.å*¦3žìæ=Zr «ØÍã4êŸó<›¸„l¦œíI±9@)'‰™C >§=pëYx{³–†l:É9 Œãlb÷òsvñ1…¼Â{tb=«¨ÅW™Gù²†R*HS‘ =«Q›ú b*ë¯Æe`2yÜǨ÷‹Hȧ„%|”8 ²g²£ô¦cèÃPÀ,¢]LàëIÒ,)ÉEguù®åèY§4gÕ¿6 ðð?åêÛZIg6²ƒÓ–÷ØM ýx˜Aì$TÁâ¤I§ª8ÙÛ´lÓãX27®‘r(XGíìÞÁš¹Öƒ—iGÇØdž»51sŽ®¥ôÒj§îÝ\EËö„Ï?Œ ù/ë’£à'6ºÒTÜU¼‡y–},Oåômuuõ#øêêvÔt¼-“u¬mØ|¿àÔ5‘þÁâàJÚ±‰5z.+Õ$öEÊ•‘OÃû¿Q¹2µv ûSžB)LK!rYMV³ Ü,Χ.§ü÷oßíÕìùŽêë]^ic¥’5ïhÔ\“–+hrÊ6vÔÖY\£RŽDU[@êøk*ù˜Ã´ OÐ6X”R3ø+ƒˆÙJL;ÑpqóÙ­OŸ>—oq ‰Cù5­ªôýêŽÔPV¦K™ëÈKä3žŠàt0Ñcùè?«&|HÇ”Á—ŒÓµÜÐmj´Óc…Ïׇ°5SXGÎ w<+ôójçÏú¢¸µÙ¥t£z°(rq’¿~D¶ÍX•D“áÇì¦ ŸÒ”¦´á›ª ͸”¸Š×¨‘6ˆÒîŽ}L5î¥G•1ÜNľuÚ[)"«‚CÔIÒcg³ß²™m¤éÍ(±ˆ6”EÚGŽò=†ó ƒöD—¤ß¸Ž4•<Çs¿¦)j%<Ö›i–ÔÅF*ª¬«|c›y™Áì¢& é‘d2Ífe²ÿ¦I%G(á\†%É>œÃ,ð S©žhóöax¤eTÕ´ÏNÚ–q’«ØKwš³ý„¤G÷mÏb‘¦ ¹4çÖDcÕ+aeqˆ;¸‹›hË_8A œfœÏ&§\ 4öS¶sÕBU¨AæRÁ1¶±™ɵtœ‹’Ön³$¢h5Ïò¨]ÍA–°ùŸ'Rÿ§Z•mîûÏéê뺈zœ¡5… £]èBc¦'Þø\Ê>*èÏ^ê¤<¼À¹ ÇeýiÌ:z¦Ü`bÒošÒ51Át ”ˉ5Y]½mnõîÉ´oºçjòWkפ¦ÞL÷”Ñáð ½ÆjõajåÁ*ŽS•œJÌ¡-¸4<þƉ§?Š^oŸúñu¡ÛÝK ÏÑ{¾&»­k“>Yœˆ\låÓèë3RËÆE”h^WÍR…Ár_=¡¸zjî6F:QÂÇ‘æiÕ3ͨ]îƒrŸð•È„fZ+a› ëY6PÅJ[GhqõTjøõ2#'˜}ÌáŸ1Š¨Ì¼Ê›þâ:QÇfÑÊvÁ"°‘JÌã[ºLpîI§RÕ9H)ûèÌr‡][\4vG¼°‹çvêzÜŒ6µ4*Ó¾ÒÁ2§èÈ%Ž™ü!íÆõlÍ=àŠ"?µzDJ~t÷º0öˆasõ\¡I#?¿'=»Sþ˜få½¶vÌ–"?-wÿå`$1»ù*_òÃ"û#ý¢*_$öés#Ÿ¤\ÌN†ùWr'óiEKÊØÉ~6r#‡Á¬U£õXÈÚ$l¢CÚ€ »ƒlb1×'âé W1—6\›lgirR¢´Þ±#‘Q‘L°ž<¶QBSVRJ[R4ã4Û8D+í£9ûéB.·Ò„·ÙJ1©È†È‚ þĉ ¤”%\ÇeÔæpàÛ†–‰6¡Mh”0ñF28•ªÇš”›(cCà[ŸsÊd¦\NM6°—þ”Ò‹rŽÑ-yñ-/퀄{”íõ b?{CK6rE4cE [}@bÈ͆'œ¡S,ÏZ}S.^dNÒ\]Ÿ óvp ͸†ºg©%aß»iÍ~vPB zÓ’.LOÜîÿ˜¸Ÿ“œóŠþväÿ”«ÿqeQl§YÁ9tb5èÈ6NÑœí4૬æSЀê¼O V‚EÙÁP~Ÿ †Ò&hœ0H»8ø$‰3ج§˜+9HKkR/5da˜Ô1Z÷µ0w¦¹ÝmiÜÎ’`0Ý=läÄô®kãc­9A~ÒEÉ:KÆzršïlsS›hæêX½Ëâ'Õ+·ðtzâ“NÞ™kFs9EÖÓØó/ºá¸— éÁ–”IÁœŠÜ 6›X2ç_“YFƒÈ®Èý4Ùá‹v¤úÕ°ñ<æW÷j‰j¶mñ_Ó|´5:}"×¶œ¢Z¾ù¦)½ž±¾ççh›éæ2¿´m½Z]Âwßô•ù6nqø&ª±„s¸H“/Ô¨™‡—†ÅµÒ2ÎçÓHAÚSáÀR_ŸoÆ­òƒ¾5)UÂjÆ2ŸºpÁÿÃÞ}ÆYYÞm¿ÿ^kÍÐÊP©ÒA¥#(MÅÞðöI3j4‰wŠ·‰1‰‰‰Æ»b‚ VªiÒ{ÊЇÊôYëÚ/Öœyð³ïý|îçÙûÙ/îx¾ÖZ× ë¼ÎëÿÿÇï b C¹*’Œk8x£}}¯Á'<0×5ûÓÛæåŸYrp›/+½÷s%/F%룹WVÚ#ý‘;j{ü ùmù‚¹\ÌKÁ±+2>ahÚÛ¬Žíå«LiHÚó=‰XœçÎ{˜ÂŒ—Î!uÙÀô€rø‚ ²)$#àl¹3ö;Š8³¸ŠdÂÞHýX-–Q@6Y2‡ƒ´d3÷Äðt\3 Ïtú3›Cô ¹{ù”$R‘ð5Ë„î¦/SÆu2GbU´§Y0#¶g¥LäDWZЃ|Áˆ`±ßÌAJCŽÁ¾Ø|®f>CHmNe»hÅRú³<¶ˆ¡¬ ôŠJ.g�MCqÙžžjüU9læM¸Šbvr‚¬åŽRÖØÇP¶s„å ã«8D’Ó†u\{7To™Õ„>,c,QÈV‡Œ«ÌÊ´ÆS}RÀGe¸Â˜"¥œ6Œc5;Ȧ’ó3‘=ÿRÇU–oWMã;¦Œ\Ƴ(<“¤$ùÜÀs<™I+Žü<©Sµ·éË\5ùUC‚ ãOôáU’<AI¬š!iç±”«x.–â÷<Î.^ÏÒ/¥vìÌ*HEŠõ¢kC§EÞ;f2?b£­Ïj”•Ê} à6^`&¿åa¾ë‡¿·{t4øÇ­¶ÄûE‘¬”kUtò~gj¥=KWúò€+%K<:ËLJ}òlü§ÇÝÛ†á%VDfŦ¹y)~Ë@ÚfiÛBñ^¿ˆ]Ÿö\ì{Ôã>oTÅuÄÅóÍz¬È±†’‘ÆÇn*õ÷]ñ¥#ª½;jöd;ŽÉ?È0^ˆIE»\T[»6ž<áÄê´5gˆf˜òz;²›ú2P£ñÚ´òÐQ³3âgž.vñ˜Çd®}žV`UmÞè¹Ï]ø°=uˆy‹ý\Ecž ɾb¦…’öÝAù^ùÂŒ®±»ìzº¨|.Å]T¥¬ÄíiË·n”ugùúyùgr7ý9ÁéÌ÷ÃpjÚTŽÅö°Ž§ù[©âÇœˆí¥u–Ë‹<G>Gù1sýØÀ©ü…ø ¿¤˜!$èCÝ,¤Ôý…ÛˆÓnãçÁ¨[ÀFªÒúE®âÑ0ݹ)|½/"¢nlUìÊPy £OQ‡ö\Æ›´ç)FQ7Ës)ÆÖó0›xœ5Ôbe<H¯›¯!“Põ _‘¤GÀç<L)æñ=ž xÃq´£//œ¤À.cu,Å­¼ÇE±çh�þÁ &ó×1—¡Lç ²¸MTñõ¨¢ŒDðÎ_I¢ÆñeÁÝ%¤×§hÏô¡)3Àâ!bžb9]™Gš†$ÝjnxŸþ¥\º4„}ùÏfK+˜Ïh'=½Èe!u( Ƶ©TnÓ—áϦ(4oÿ›‹/¾­®2«*üß—žÛ?…=¸˜)4§w²‘ei hšiGþ¥SÂû‘ú±6ìä¡\.©2šÜÈ¨ÈÆØ>†Ó€¶ìg2Ò”;ZÆ&ÊÉÓ÷}G”ÖWq +½]!‹®$[Þ•¶´·¡ª?ñÝhÇïÔm£O{‹úøª¡#/–—öÇØi´ ?Ò•IÃ9=vJʹnžáØ?Lûw©n†´¯]Vé©qEýØ€Hq¦ÓUÛY)¿`PÚ»Çýš þ-øß0«\×ï*[ þ¡ÈÇ-÷_SèxEÛòDO–ÔJ—§¤8‹ŠÿÄ)¾b·Ý7ºË½{¥âË£ŠÇkUÏI¶ON=Ï'ùô”~-ì½'½ÔÁOî³wkóœzÕ_ÍH :àÕ‘\vÓƒŸñ§8¶Ï›×9–ËjŽs1gókVp/WäZÚòKF‘àôŽªÎNžþEõ‚´Ïé]î™*ðb¶ÕiXÁ0ŧ²‚­ìÍòÓ´¬‰ìlç·L滑-4äŠÈ¤¤¡I÷¤íã2îLè¹.å©´,eE¬d €¿PÆ–,‹³”¦kB§%´J–ò$Í9‡ù,§„?±ŠYþ›ÍAêD¶O?~Ã\6r;·“àvЀë(æv'Ÿ˜å�� �IDAT±›4æs‚Ì:VÈjñçž¾“Ò¤3#ƒbsù3m9r}O õ.o+7чy z¬å,–qÕ<Oã°×îáFΡš(§+)¡„ù¬àJYÉ6êr ¿ ¡-]~ÊTF>I¿·ž/¸—w9—©ì ;}�gòŸ“bQè‘þGP„¯å|šSÈ)ì Åæ�L*£U6ã&FSŸ\Ì&Šh@ío’/:q>QD¯Ð®läÄÁGäò·³†V|8Œ¯v…à®ÛÃùm3ð_tÕ£=³2ÆLÎâ(U¬dX�ûŸGÇÓÞ¯gpÂÍÕ5f¬îåvW™Ï_YšÐ/’Œ-f*ëèDG:PáïÒÞ¤aâÈyqáç¾×Z›y:¶&·–ÙI­S¾§ÎV¹Ñ…oX¾'Q4-Ö–÷ÁzôôèóÑêcÑæ…ü”Ö‘võLKé•P[kLˆM­ˆÜ³ÁºÚ6îUXåÅGÒíwšy²ò½ÈþØjÞj"¯´Æö8ŠbZ°“ëxÝ%¹N´0븥ý oéÅ‚k°Þ³…ÎÝž˜rg£Šze*B“Œ¤Ì9‡O~ÞÒÆŽó½?i³$»Ë¥Ni_ºåx<pŽ[–[p½ŠF¤X›pF<ó7î~L«%嬯½Ûuç%ü<éüذVZAŽpy,£hOQ¶«kÉ­vˆ®Tð½„Ñ,£22*¡\ót<G«mq§^lcHF9–Ö:Ri˯™)M¸?V+íNgc ȵ±4ÌŠ4ŒMæh–‰µœYË–ÊšÎX;Ëç,VqíÈ¥$<2·ãÔ7ª®^•5²Ò[bK¢õ¤óœèÁ Zð>YÁmÌLkÅéOÈŠ´¬++eNìjÖSăÌg%ýØJ® © ÷žbs‚%ù&‡aí‘@ZÊ—ü”TlcìKúRз‹ÂfÉx{¹v½‰x;Ô^í™,ÙÇlÎñ?Aæs.Û("û½œC%¸š<:´ôFö³‹ÑL¥I.S“…ÑVd+ÂŽîF_QEîIéïi†²'áìØæ“î�—„ÁX#v³’[BpbmŸd1>7Þ`FÈЊ)æP¨Ûr¿™7Ÿf&1HQNiÈh>0]YMQPÏg ñ[‚Ò7íÿ³îÛãê_eÕ&ît {#‡|ð µ.àB5eÖi•ªª­ä­¤_Ç5ÁÕ¥læ¼XƒXSú1€fÔOÈáB0…UtaBBÃxÏS:h¹K»¦._Ÿ5¦*1æPõ˜ÅFLb›%ýü¥\Q2áüØtÚPß½_»{³»ÎH|46C;ŒK;5ö|çVY”6‹$Í8ÌU줱ò®.z×Ì!ö²&-§–QÑìÑi³ÉK:ç„'èAfÒ!鮨'”³Ö?fºúW,¬¯WbñU©¢V:¾¡_ {ô‚ø`2»ip„óÈNÞnX¡ç¹g¾ë™R¢åÂt›OJ[/qi?Xï©m6^Ê\FîŠKkÛV¨_aôî/ JŸ¶"m#Åukõ¯˜ø7KÚ²‹Æ,f1C˜Cgd9š=½zb˜¦Æ¬2æ³xÌz)‡ÆÑ#–9œŠÉ3h¹¿.³²½‚Lù¸9xïVSi©ûŠã‘‘±äÓ„tl\,Å|Æ3/VFL›WíÅJQÒÐØVvÓŒÙC.ÝøTІ6taŒ«ô^….±§ã¥ÃÐø'³\ý™OïPùHÂ("¾ ÓŽ…4¡+cÕ±þu ©²4vnÀ§^Á_#­®ˆEäñ2•¬M¸*ö)-iEœÔ/†I¬¦˜K?ª(¦>™J:ñ&ÇÙDOúEJN‹ý•Ùìä–p hÜE-9ƒ2 Ñt^sös.Ѐ¯9Dù$E}‘Ëln žÅa“¶ ¨°LÖÚ©) q&[BéÖ‹ûþ¼0ä÷a3ƒØCó„V±•áÏc%ÓB°d#NІ9œÎž“Ú0ÂY…”Ó#“‰C9ýØD¾yœ´aħQ;D ÷cM©Ë&¶Ó„Clûf¿q»¿9»Êܬ|{\ýË®J0”m!É&Ãø)å»L¥íl¤’˜˜O¹(rz¬7óø€Ë9Bˤ<Ú1„…œÁg±¥ ›‰X[Å(ÖØØÍ⟕Ú~$Þ~¿í³m:áÍä—%µá¢´- _%®?öª…{<­™¥±2šÇÝžðÆ×®[RyÝÚø£ÎÊ;0–Úüu ©oSÅ–Yþ²Ï3÷'\íê/%q8~æ9ͶYÔ›¡¼Ë:61ŸË³uOYOC?ÝäãïYs€—"ýR–ÆË—X{®[}x¶£i*"Û³ÝK›´}´2x›óžmúü¥>ÿaõÇæ×µq¯…u²Ö>›®\læ"˯PÖ“²†öekXé®J5H,l˜>ü2…‘Sc“M^Å+wgŠ^ÍrNºFPPP“™ÔrHꮾ~£uWš5Îö lïhûn×ϲ|—ýÈ«iU5ãÇ«íé }®åg3š¶2kéÈòX/Öq@Í3G]nâ²à}YÏ%ÌàaR,¥od]Ò=±ÚôfrÈâz–Uô ·•–´cçñu�Ç §¥n«=¢A'ÃÓÞY¯ägA 0‚úlcu˜‘›r¨Ò’¸&At<;é˸Ȩ ‘ûšÎ”r‚âšØÉ¯ÙÌàÈÎØçdS›ü`Ÿ*ä,ް“^,å�+ù5ÏsuØD58-”si –Í£.ý×üR^!—¶¬ bë^\Á'lôŠÚ\Ï<šPÄP–0!X‰w‡ýØ“Ú|Æž@?YÍòùGùô›ê†í eƒÙD€- *bs‰@CްŠ!ôe9Û‚æ%SŠå3‘ù`<üsÎIÄ©3XÃ>"ʃ8e58D×2™m¡—8ž·‚—ù9t êē׵,þæ°ªò¿ÙYõ­ÔâuÝÅ3-ð%PÊÄvq:o3ƒ'©Ë¬Oû 7&}?m ;XšªÉü ŸðIl½ù;†(‡M|Ÿ­ôbºÔ >{˜DÊÇܤFvµ;¥)/8u}zn±"·þÖÁ<U’ëš +J?ýšSÝziR¿03½à-éLFNP\îá Õ”ÉËâ»iY ¢À¬Km¼ÇØ»m}5þþK½ 8#3y‡¬*7q ÿ®SÚœ 9Ž ª4’}ÌP\ªø$9y+éôj¿3!§ü-~ûgÞ]\>6NÞhàCä0•‘œ¼â{?»’4]’~ÛÜ­=Ë•ìbqÚIW%ü1í´÷1‡­:mqÖ©öÝÉÖ”ç9?ajdVÊÓ\gÞ/­îcä[Ž<®¬%¿à†YVâýûŒ¸Ÿ$Ù*ûWZŸfAö' M»ˆ<®åþÄ0 ù‚k)æAryœÈ«I·T×d¦XÃ|Ÿ~<Û™¶ž±f¬‰´OUí."æ÷T0šÖü™ Æq)¥l"û2ðån׿YÑ ×œëHonUf0WÜÂF (ãÎ oÈ(F%[šßÅRÉUœC\ÍîäŽ1Õ/íÏrµèÃÓ4 Å ªy/8Ÿ2ލ,j1‡cÔã•Ø^–PÄø9ݸY ‘‘AO8“®Üšáë˜Ï9\Ï„0gúšg¹“jÖg{±Ê­Tñ]0‘§ý/3=zŽdþ–-|N|’Š¡<ÎÊü¹uyƒ"®ä5:МÎÌä>¾ $¤Z\Ï[Œe'xÔâÓÿ,¡£-e¼R€‹¨ËD>ç^™@µ®º¼H?Š9H‚Ky=üË $©äo߃ýK¬o«ÿùz&è/22ž3ùˆKYÆêQŸiäð.Uôcu–{ªua|ÊHÆðYCs˜ù VÁ»t Y Ï¡¤¹ ­«<ÂC¼Æi¼Ì5,¢sRÇŸË“Ï[ýtôÛ5¬U2”{‹|™í¢èÊýñ’GÔO¦6W¹ Ó@Œ*âL&V×ð{ޱ=’æ²ã8R°1ñâêmLÿìI%÷z4'QðT´­0åÉØMlçl·ßã•_9{•q7Û8‡ ¼OÝö7·y ÷Ç¡Dæ1áLNm¼0ëþGÓ#榛ήØÍ{m§!£#禼ºßóÔ¢" ï.Kù+QÐ,K\é+jâñvÑ]‹Yû¤Íw#çÆf)“WŽLXZekøÌÉ*üqªiƒX>û¹ƒk*÷ËåŸácót8`tìò8Á<›ð½È¢´bÅã/™øÚت}‡k"wÇ5…/xœk2 ´(ï¾D·S»¶Ð1Ö"¥e¤Kì Jy0a7ÛÓ¡QäÖX9O0šéÁRsû8Ëþ´_¿]»%)*ÜÀ¦¸æ³®ä‚Èç±Ò >?—)\ĉÈÀ¤¦)Æ®eRÀ)å°A í8…löóKZ18À—Ôãg ùYãÆpŒF C#½R^â‡\J²¹±lãÝ“lCkSÊLÒ™§2oEÏP·aOà<&Ó¸ÊwèIÇ–08ƒ¨ÍjöQŸþ̤’-¼T‘‹‚š.#šø…ª(£â;“:¬c.ÝYuR—/"7Ä„V2³ øÜÎà^@]²kqm�úÝ.æ´`o8«p%UÛà0+àÕ@Á¿„8•Óyç?›]ý÷_ß6ÿ‹«7cx›Ž|ÄAjqg“ÏBúQI[Ò¦q=¹L§uYœ Šå–E*"‰Øé4&‹Åä1€BŠj«Ê6¢ÊpÇ‚÷~?7€9 ÊsŸ6¶Iâí`§1¹®‹ìJE†ê»Ò´Ý4¥] „É6>æy®ŠlŽ|J~¤vÂ0NK˜ñǶÄK*½ÒÓÔfîžwYuïa@o+kK«¡mNé¬kmÝÖêú–E†vú{º9œçÀp/Ŭ£3i»7yå…KÒV¹c+ ù”¦¼G ØÔ,v ÷ИuŒà@¼®O^RN= *lãÕ£LïÐ0²3®!žOQBšÇ´oS«ÖöZ[ÚT:Dn¤oB÷X›´&¾á™A´ä8»©kßL¯<dóÛ'4Iäì4úhbË„X ¿Ìt{"g&œ›Á*?¬!üDMÿjȯ¡‰7‘}ûkYý‹ªwÊ)¾¢Âž„8R«E}cy±ÕìôK¨«¦;ø!ٜΠÚqÜfv%’Oõ‹÷äGê'ü(rœ-$¹”ª¤Œdñ÷$èM {x/¡wlF d^ÂòÙ¾Ø+¹8„Üà&^€1Ç™ÍÎb23ÉcORM£Ø‚ØzÒ5`‡Ž°–}Ó[OòiÊÀ€¢ï¦N|!CƒÜ¼;MÙ‚á+øŠGZÒc‘즻ØÁú†zš: aré- ü½ŒùTú†¹Wgú‘Ëfn 5]ØJ‹ÐB\èÊ‹Áv”ÏÉe0ëÙG†4KûçÊ´y3L©O8í$EâWò„Ób-(ç+PB[F±Šu U;‘Ûî·³«ÿ½•ǧ; j’ 7l’¡Ô¢ ûéæÏ»(b?WЊYJO^åDliP ½’™“s¥U;^¥eܨšcJٜŠ2/˽ ›½}ulm8ÏÙê§ÔK¥bs¯Óa¥ì#v<L‹Èþ„.±—¨¦˜Û"ÙŒ!;ËøØ¯Ò bM˜B%»˜CžÊÅ>¾ÛáúqÛbñ!7ÎѮвOé}|u¼³¹ýÄ{=™mr¥ŽMui`q/Þøu|ÝÌ¥ò…•ŸùøÑp®ã&–ðƒÌïKðo¬e>ÙÆy|N—¶ Âjîá�ÄöÆsQRulKl¹¶U¦þ=Yùöìã"mbŸ“oâ¢ä3¿‰kZC»Éeµ2ÑÑ3Ù¾·G~¥MûÙÁˆÈþÈ¡´cƒ“¢iªžØdêp;×pŒVäë4%yÕ9Ñ÷VßðYí•#+J?Š-ŠMIÂu$tɲ ZKÆÆ>åSúóÛišc¿b3)ë÷Ç……äDús*8‹<±9ö& r{™ÊR†ÆÖÅ57ÍOØÃ¥´¦œJÆ„$õÌ_;ƒÌ8H)£9Î0¶Òžƒ eC3ÆùÈ„„ݱö(ò'XLÛ¦|5o‘Í(J‰YÁi,g5Íé@‚«ƒMøKPÀÙ4euù‚&‘ÝiE´d9L ‚‚L2-id·ÝÙEmŠÇê“¥fš¸ŠÞô k(á::ó ŸP7¼ð¾Æ±‹!ð7‹öœ`)£O×fúx¿`û(ávæ†Ï R‘îq fédõ`qˆ[PŠþ5«o›ÿÅõ§ôWôKr0Ô1µ¸–gî Áëìãæâ~žãC©Lh¹.åMp7ÃhÍ›¡c>Ÿ¶œËslㆤ»ÒÇzsSl)³ ¯Ö"a{¥œ”2žv`ºƒ­ô®eÖ>JcS8ÈX¦²Ûb½©b[Ê´XNç#æòI’ËJ>±æ¸5¸Î6z2ïÑ2Ùé›em1µõ}[¯Íòç”;cÉ'—õYž¨6‘áôáßNÔ�¦?P‹[ØÂöðÀØŠÍtæ6RÔãcs"á‘È”˜×(åryŸ±ŽáôâIîJ›Çvn¡-¯²$©y즴_dkÒȧ‡ïxÌõüôê´CÁ:3¥YÞ©ö)«9–ÖÈõ£í.à(¿¢~¬VÊß¹‚Ý\B>ÙÄÓÓæs®dÓ¼¦rãKFyð豆nÎD?üÐÕ_ÇE‹J/©N9›9•[)¤ƒh@#§'òsÆ%ässÚS¬‰Ž}Æëü˜­ÜP³Ý©•Á]fùcʃ<’°+eÅ,ä(k© ÆäêÓÆ¤Â4®¦Wle¼ÉF&ßou–ÛsåªÑ`ÛbÅ\ÇË,&‡4s.£q�aÔe8o2–¶ü%Ù3ÔÚ `wcù÷€ö˜Éº,oT{”:\ÌWiËJfµ¹(¤×gZ¸T|Ê©†»|¦‡šø êŒE†ìw'/òØÇͼ^˜éãñðÇ9žiL1sKÄo˜ÍÒP3¡;hÍ‚ÐÍÖ0EÆØ'– Œ®LËaÙ7ï3ÇN®9é…«O*Ѿm~»þ««~`9f;¹œqŒä|fÓœ]ÜCçÈòHW%­â5¾ÛKzñIQ‹7²Ý”ö2Ãxƒ;˜Äq¦’;¶WU]7¯ÏZpYªê¸ìÝñ)ã¾ë©ÇM<jâ‡êúS¥TÌëìe-kØÎk|Á%yWé’ò,­8J·ðú=²Œ5 ;Q–á±ÞÑž3¬™ä½‡RoŽˆŸ›‘šð¸ùk5*I7šæýÍîß8g]Ö¬‹­¸*åç¼FSöR¿Z%ïðJ8‡^õ-¬ïŠråüﲯ3Ô¸„ß%ŸÖšÁ䯿ÆÊ8ÌÍôäCNc?ã7Lf Sy2à Ê›ìØ…ñøõñ²‘šf§Ï¼©|úŒxU™þͺÉâYa$]9?vM¹ŠË|ÑÞMk½ý�ÖpWÈh_Á®`½™Ê šrFÈñû‚íÜíë>îÞàö…~ßϲMâÔZöÎÒèƒlÿ^maÚ8îã{|¦Ö<¨&ŸÕld~¬Wì(³¨¤—šÈÊnœÊo25Vdy‰Íi³)¤Klùtd¥4¦ˆbʹ‚‡™ÍåŒ&;$t$Bàá©Ý” cÆ_˜–(÷X\c7ÞHÇ8®_S‡ èÅgü‚÷ÊQ.ä³›ù|‡Íäǹ,£„,#É;!°0m)pнRsÎcdkÈœËf#µ9øI¥$¸€\r˜v’| ˜Mš£Œ 'ÙÆPÄ6ÊB@×L¢ÍÆzŠ9Î@ʸ0Ø¿2Ð᯹Œ:læ0œÅ|60†yâNP‡vÒˆûhÍf]ÆeÔæ�m’Gø®<Ø-¾­®¾]ÿ «)#™Ï~Þ¦yP´W¢×ªÙOí¤›#gTù3‡s /Ñ£Òë\Š­Bîä3¦ñ?«ò5½ƒù>á7”±Fú»«üVõò}ö Ó®ÚwVy5©wVF @P¸\E¾d<¿c{9pÐZ:q)=)`c#Ÿ'<˜òyµ·y”ó8³Ú$údÙ‘®ê]œÒÔ¥Wk?ÛsE,æë³í^WYdà ±ƒä0Š/®LËçmªiL§¿æûÈ}lg “HÄÄVR|çðænri—T[Ÿ¶?�ŠêDŽÅ5Ï +ÙK=éJÓ‡h0Óíë¿ÑñDºwUñõìà'ìIk™tvʳÜoã³~8€môd6eÔãCžcOð$çöz†”ªÇ»Ì2³ƒP»›eÖéQö0“ó9—\eÊJcªk¼J+ØÎtþÈOiÁKx„iå줒Áà)fó@P¨fêž¼Œ| é¯Õòk^ % Eb>o‘éGaì8—ÓŒÍTq«XË¿ór¯±ƒ­ÙÇhÎâ Ž°$­Bã±ÇB2ýqq> žà|ÒŠåü€_Ñšã,gÏÐ(@]ð{Þg=·ñ7ä|.c5gò˰­Òäkþ@=.`7ëÈf%W1 ¡ˆÏè)ÑŠ0o~´¤'ë9Ĉà`ËÈÊŸàZA`6o™ÆòéÀVvV¦q׉¼ÁØÎöâ36r‚#´a`ˆC7ªB,ò÷CÍT'hRN ­=' ô‰ÿŠëÛêêÿå:å›ß§ æYêQÎqŠéNuäÔÈô”Åiõ8@V¹U) ™ÏÖ„žl(÷Ìèx0[8•fÜÍ*ΡgQÀ‹ŒQp–õ-q†îøÒ~m]+ZRHÇÃv²žô`› õ¹^È8Èl¹Ã|ëÈLZ‘CÄ^†³<mU¬Gl5ÍxIñù&e™Ôä£Nô"U%Q©8ä 6{Ùͨ„Sc«@'úñTH Ê8O«ùc(e'+cí‚›­"Ò#áòØQfs&bÉHA¬3Kˆ)MúN,'ô�7ÔЪ<i]}f%Ÿ¿?~g[YOÿ@™kB?ê& K«gª¬e'ŒñŸ†¢3HR@'V7´ªÌWdÓ–C¡Û¢&»ë|ž¡3=9Ê34à êPE6ð>møóÈá<ò8Û×c;s ÷2…l†»üå|ä°”>iï3÷ØC#ÚÒ‰éÿ©‹iÃþ]–E+¾f=³34÷¤ÆŠ(á26Ò-R©Å4Τ!XÁ¸“eÔå8ÊÃÌ¢kÈÁjç;9ƒÙ'u´2Áð-ØÏv²ÃVz²œÏc¤8•D艆Öëq&Q›³8tã[З¡|ve_ÓÓÂH)Ó G’7ƒM¥YGyèéåÐŒ2ò( W~ˆý`(»ÃGü,¤ŠRÚ3=ü¨'‡¨b'Û¸…IÁX– ;û¹†R–„ºv7¥œ‰þWˆdüVjñn #Ù†œ“ɾb«CF9}ý±Ö4¤uÙASn °ÎFc�¯Óƒ¦laù,f k™HW6rœk¹Ž´MÅkLž`Nû°{Ïc5#93CœÄ4–°ð s)%WM£é6R' Ø2 ¢­¬am8FOfq!»XÄrèÊ9ôd¹šøÁv¿¹vœûÛƒ‡©1¯ðÒà\ц¦ôb3¿ÎÕº¶*ìàÎÈùLç}Φ Íx"2,v=ÿ‘á¬ÇÖ0ƒ Ô#‹Y~›ö5 kn‰N,ŠI#š’âìZZ4¬0ŠØlžä@ÈdêFLm¾ ƒî[•t siÌ@ði™–!éuM(#òhì ïÅíÔg ;(a³©CŽS@Цü#¬gwó*ùlÑ'˜ú,î¤ÇhÆ—4g)×0š%Œd!‡Bèߊ“f«—ðv\ó\ŸÃ%Ô¡ˆetã�ÝiAsêD b=ØÀöE†“Í&VeìqÔe~CÀ 9Â'ثҕô¢ êœ$èLËp‡ú,¥}X Ê…tg§P͈@Ž(a9õIñ�¥¬ Š™ü”,ös~ØGÛÙÎ)AÇ;ê¤÷ÉgGQ›NbéÈrùŠ:ô£ì›™cIÓ=TfeŒb[Àð Úwì&f\hè a9q¸Ô5¤èÏ:q4È÷}ó¬B£0èúö¸úö¸úßYJ“Œ€gÝØM =CdC&Ÿû~ne*—D>Lê;L.§3:© csø>}hFSnáº023Æ ‹ø¬•ÛJü”-TÙõ¥òÅãçäó4+©âlð¹t rZo`)õ³tŠ5b{p&õæb¦s#ÃCùéÔLÇ”Æ)iŽgrÐÙNS`g–¾™L öq*ÝiSÇö÷—YNc.¥-͘É?x‰fsƒÃìçkf‘âÚ”©UÊÓvRÁ(ÚsQ¶[Óþ”9c[x‰[]ÇÈ ó9HŠv|Äb%´fÓc=™N‡YÏ ±_¥ÌN×(¡3O ‹(g8“ø’ÕœP=YB¿Ø«Ð.¢/³'éGìÈvWÚi2Ô¥+ø#“c¢+_2˜×iÆEÌe72•ÛYÌj.a?ëÉâ*zr·ñWvÓ–,–1ˆ&LâþFûÙÃZbú…ÿ÷œ` yôàcÎæ )&—kƒKý`l{éÁ9ÜN+øBÊ)¤€~Ìçût#k˜ÂÞ�4ÚÆXòéAWf²8t/ÿÉî+¥…äs½”q sC'`%2rú•é FЃel§’4 Ñ!3”¡¼’‘»p„ë˜Á)Œe&͘ÀgŒ`‡) i–Uìá %àNæ…ngõ7[(½»|Îá öñi¼HU8¿O›àô¼.µˆù ¤Âþ? ÿÿ·„Ø~{\ýÿ¶ÊØJ˜“¬�� �IDATv`š¶tScºº˜/Bç¡’«ù%/SÊ$ÄŽÒ—i|IJXÃXWæ‘EcFð#f;8“ìJú}¤ä¸_swR½È#±.Ù&¤½©ÅjÊ(IÈMØkË\—Ô.Ç.å<Þ¡EÚq&ó=’DmŽÆ­‹4Ë3þ•¬—v˜¸5^ú’½µø¤Ô)_0šmÉò³ØÅ\”P–ðRʤÈrŠÈβŸN±«Å•îŒlŠ5ä™ èÆpþÀp²œËYË|‡ŠLðnÚçiW±™;YÈ_I¥¥Éâm.d G®p¢ÂaÆq9ÍJ:òN¬o¢AïDÇ=q³OXêtÖÓ;RI’U)½¹~ÜDs:Ñ•²Ûh}®cµI¨3/QÂNVP@¾Ëjž-VÄpaZQ˜±ŸÎa> šç(¢¤¾÷ZÛ}´æIb j±;´.'qœÙJkÈŸÙÌp„Ît ÉSì ›¹œ-ÜÇJV²•;žô£HAl8_‡Â•ü•J1—£ÜÆV3ž•d³”Jn¢. 8…†|ŸOÉHÜ\. ¹Muy‡c”óÙÄ Iº4’ˆý’@ºêÉ™Ì;åys?[˜M*)§빜 QFc~N+°“âàÀÍϸw#ÙO~¬†f‰-Ì£*t×d{8]•oÃlFòK8Ÿ ¬¢9WÓ€R&pœÞÁ)<˜¥!ñ>¶áCmêÓ„Qìá'|Î`6‘E5¯’E¿ œ…­$¨`1 4ä›)gu�z\<]KAø¥rˆYö¯ ¯øö¸ú?´ZrÚIýëÇhÊ|:†Çð#D‘Ó"(`tè½L§'cÃ|þ5:²†©bV›),f$)ÈdrǶÇM~ÂŽ37Ö&msB^ä@ìbš1"Ö+¶•rZ±0öJì�C8À¾K>7%4ˆÚÞÔàüb×nO_R\iû°†·>?óUêçÛ”¤ìÜÉE´¯3:m3i²êh^[—J‰ZžKyË«›2>²#Ò$m-©ËkŒ¥èÀÅ4åiŠèÈ©dÑœEl4Ô¦ ï3ˆ!.ù2zÔ•Ÿ60é’´WhÆëÄ,ä,dî?+þ³¢ŸUK7ñÕÛdÑ3é:žNz1íïLçd/y•Ýþ±?ì÷Õ0óŬ§]ÎM fP—!\ÈqJúÆvò ®dM¸£Í ‘’*ûŽz—¦4£‚óã8BÈE‘DÂÀ”ŸsVHbÜð@ì]–1…3èACšÐšƒ¤ ëèÎ~Á±Øú¸Æ·þ—�ÇëKrŸqš7c-¯ÃPÞ }H!yy7ÿ >•¡vmiL>kBï×LèÛ;è’p"öV¬Ol|(S걘å,¦1Mé|�bõ9—TÑŒ+xëB2ÈÙ4ç}n¥›©Ç¹ô£gf¹3­ËøE˜çQ—¶!¦MÒž“ÑrÖ¥xÌVÞe"lg&­ùœÚÄÁa¹–Ó¹€4ᡃéæs 2`F~AOnãB¦r€\N Ùc}C·ð‡¤˜Í>ºÔâË ÿYí=Ékœ¡ ûW»Ã~{\ý¸ŽŸtV äé¡ÓUΆ¾‘]‘âš[ÞE¼GDŽﲈ:¬æ1$Ò>ad,¨ÏÛèËÆÀÙìD #ØÎÊH³´õñUu¾(·ä³2GbõYνüƒ)cIÂW9úUhÈZ3‡&ó#•:ó£òf¯~ù†Ä³-ã÷öEËšUêVmй·ü¬Õ}ÙÁ',äZŽq¿¥¼Zy¥¤’µÆ¤~ùª‘y#?Lœd`±c?¥ Õ|þµwßaV•çÞÇ?{O¥0¥é *XQl6L”Ä–hŒFž“¾9¾)&±ÆcŒI4VìQñPA)Òa†iLÛëýcÏC†c4ÖDß<ß‹‹kÖÚk­gïÕç¾?΢˜WøkÙÊÙ!çøˆà°ð4ƒx‰ƒÓZ“¦(Øòž,Ï—²ª¥–õ¦7ZÍbÓsLJÜìøÙ™1ëuìbuQúGݬ*Õý~Ó~GK:&þÈâŒBÆ’G)CÉÐÀ‘ŒõÐ[þt‚²Z+2ƒé|‰ böÅl%E=éഴ.‰Bô^L§1h°ö£$°‘—cBbÝØ‡9 NÙÒ‰Š HØ=9&mp¢37òZð�¸—vœÄKÔ2‡vŒ`._§<ø²W’O>s¿§=9LáÑ`_Û…Á¬ådZRÈv¾Ìˤy%°¦XÉ—x‰Fv#!ŸÃéÇz2Ô¦]˜R”hŶ°†ìC>EìMÿÏ݉éô ¹|›³&[,¡6m$]y˜FæÓ!Ò†Í4Ѓ©© #¬Õáe¨=-8œyl¤å¡¡=û³&$‹J†ç9Ÿ [˜ÌÌfžUÞ5Ÿf}8mºòóC¯æ,*)â6Ó“ìHÕ:&²„õAÈ8+î>›ÃÙZÌ&PôeÔ®*ïš €ý;ª.ÅDöOì=hUÈ@]B5lJ4&ÞÝëÙ$´Ã×ç8±Áv^â z°:qB°0^AKd6XÌï8‹^ÈÚe¼Ä~Nü‹Å‹ëJ. Iù,e+Ç1”ÿ¦&ãh®g̸ÿ—§·Þë2.aéýV溾Vi•e¨*õúxgWº£Žcə˾œJwÚgS2—¨>ÔÕÀÇæ.<ºÁ/Àˆ¬m £x†7XËX#7GnƆÄü ÑWžÙÈ‘æO†¼¬¬‹k[FQ»]5svÐO+áªDGfY“çè­:V¹"3y\’TÏö«ÁbZÓ›ÿa,ݸ†})æ8å÷x¢—›¨àiÚò6w±‘ÓCæqOV1–rºs[cSK[JXƃΊYœÊLrXΉ‰>¼F¿c5w&º'Vp85œÀ4òYÜ(E_ðS( [HHûs™ÌšÂtç!o¥c0f¼•4—ò2ð«Ö¬C);ÀÙŠ„žT²ŒûLV‘Ong wùlrÁÝL`ÅY«ŽF R3˜g91<Ò,_`³¨åg{1‹«‚,}ViéY^KšF"»©×xžs¹7¤&>ÁþLg6µ½—iËK”qjhwn³+4+å¾óõeGñvpËÆ‰ÉARvódX<˜§¸«Îj“¡ ÷†,Ä1 âUö¢‚·¨å n¡+ï°Ž6A“þþ°W³_uçÛÂ6ÃÆH1\}‚¤XÆ`ÚPðð>‘-¨üU42– þœ(o´4å¡-|Ÿ³x¹‰^´cÏ\À³|…Žäj.ä~êë·;ªÂÏ÷¬ò&·µwZ­%Õî 5ý¸Ÿ¯%†ïPAš½hE9Ñëùo7{lºÓÛ»bºã/h\ñç ×±˜ŸK•Ú½ƒ!—r gómŽåøPÎuiò8,Óð„ß\ã ­›ÞXýc~Ë†Ž +\Uk1…7BiÔ”§˜ñ6µœÊSÍîÔRÊ üÿ6ä7q1w¥ý<%§ÑUì o( ÚƒtÆ­œdnÚ•U ÷âºq„7°‡ià b2 ã—´!¿©šíë_tÑ.9…ý‚•åÍTb¬ Ý©ãb¶ó%Nf«i‘RœxŽQ´æU^âB–p0¯æ88c#Õ“›çÀz7Óƒ£ù9o5³Dz'µ¼0øÿ+ª8”39“‡9‰z~Å:Þ¡ˆçy›x„ ÷p*·³–cy’ßrvfÿ?ìÆ¨²6×±(ÃÈçZ¶…’êÙÁA#›ñ$iZS›çºzÓ/2“ZÊÈ¡ý¸‚ÿd‡2Žñ6_&«ß}öå |B†%.b%·RÇkl#C#o…jÂïp#ó8€bð U¼^æ†ò#¦3 ¹!´o–-‰ëȧžÎHŠF^$EŠûø ù¨OPÁZö§Çs9¥<È!, O‡SYK‹p¦Õs2ðMÖÓ†ÚàópI³ø„“˜†¾qÛØo¬;‰Ÿ ýÉö •‡’Æ>\Äl*ÌXÅCÌa(—RÎöŒu¼BWMÂEÏщ®Ò#Œ®•ßQy¶ÖäW´æÌ§5“ÒíZ¤YŸ\wŠ›îsÓt~²Ãòzíy“²žîÌxŽar_¤’[ɧHã4[j½¸ÞMܼ¬`áÖ¶›÷«Ò•uþƒkî6å ¶r%›C:ÖRävç<:±"·á”Ì–_Ø2Wý ¬äNW»ºÑÙÉ¢+œM>޹·p>óx‘r6ðKª8qü”cx‡ýÂ}dqb^âµvo08eiÊݹ®Î¸‡JÛÿÇ–“mIlù“-Å«™Ã3Làf~ËEÜÎtúæ9+c&øýò3§4î9=õP²šï0SÓ`áéÜH[&‘¢2å@ÚåÆŸ}hÁ¯éÓÕ…•*rMÎxÉ”±Œ"J”ñ ^ G{gü”ò”á<Çb:“G[vãh^Ðä$¹„„kÎp ž5s˜B1ñ2Çð‹ù.»³‰Œgk9‚Í´ÉÕ/eabcÊÕ¹dÔQÌö¥Ïðæ0žÜÃY´á÷L úû0ˆÅ­C_eYJ7ÖÍ“øSðXÙBÿl¹q¨ú:›ù+ƒC?ðé äqêiäŠ80\we+õ¼ÞÛ¶†t§zpmYËïYÁ;œÎQa¨,?ôÞÐ*ʨ¦”©Ì‚³EutáiNáw…2ÊEÌ ð cBIÀtÒ2Dô8!h$>Rëh ƒgõá=/W“sô<ª8‡¹Ô1WÜGâØÕ§Ç–`4¼Sù;€  =ËÀëta×™ºr+¿a‡9e‹çµÕÔMºæº1šêl¯Trd}rÜÕîî¥Å[^Øz#;’Ë$~Ãʸ$maâe¦LÌæ*:1€4‡3’ôóÈyß»¥±bcîššF'jUé¤uîÚ“ete ?¢šŽ|™™ a8*£%sƒÃétŽ *Ñ–:zÒ‡£¹…ô§?[éCŠ|…ר3¥>åa^ µ\ ¤}ØÁ:ŽáU*éÃ>9.ÍX”i°É¦V×SžrPÊü·²†w˜EŸP‹=*í˜Æ&U§ÅΘTżä骔‰‡¨fýYÊp–s0»ñ4דŸã«‰WÛ˜ÐhIÆcTdc…?òõŒŒ¥#­AVùi }F7Îg(ƒS†§ä&M:g²iÆòGŽb4­9‚7XÍ 2¤øA’g:/‡0¶„­a`u,_ ÃSô¡3…ÜϾ-µKëÛ`12~L†A¼Ì}¬çúq_PQšz«)e>£ƒ½äò 8œÏZÎÈqQâòÃÏHú“â2þÂniUŒ¾ÀóhÁ@úñ»Ð'Ö‹>ñ2äQÎøw íìKÏ ˜¯©û´}ðÜZ\©^¡”5 î”_cr#³e¿i‡Ó“<B?þ‹ßPÆvZ…²ýSo°ƒ¡J:ë ÜbòØ‹¥a,à%N £}[C°<0 m¢© )ìsã4†««v}&ZÉxêYÇVÒ¬cOF±»8„mô¢€û8”i,e™ýóíž«¾ÆÔ‰¬¤#ø-Û¹Šé–8ºÀÖ¹üx•{2“<z±7+ø33øIé–hËÚ”·ÝSÖ§”–úÙö h¬NÍß'ÿ¤’ІÕ\vƒ'äÍBV±;$Œb‡ð*ý©%E1PGïàWt!ý©`û0˜í<fΡ7)àÚ5„ùä¥Ì¡/X§©FõÉ`ÍPÉ>0N|‡Ù‰'iÁé,Ö”¸¿>i=XÉCœÁ£lÖ¤;U™-dN©ILJé¶(±š73ªš¸!¾”§}ƒóù/ÊÙDêÎMÜÅ’Z ™¦ ã Œd›¦×åbÆÑÀZÚñ0¥ô¤€C ¹•›’¦Šã1<IwQº³ãöG1‚R^åu^ ‘®ìO;êèÊóA¯èF¦ K©K¼ÆT:pÝBjOn{¤(%Å(:†úñZÚ³/{ò=éLMÍv2÷äi¾GclòsxBÚRÆ·¸1¼U/£8­8i3Ü;¨f-ø ¡^j#ù<ÂnAˆO3Çü oÑÈÖrZ‡*«†SV/mVïÕ¶!5qQö<Éf¦´ä92ÔÐé,f{¡–ÆÖ{²™î­È·6h§C'¶Q ªy” uÁ‹²Kx¨Íg`3Éö:^W¹Õ0rÿ=Ó+b¸úr‡qBEö1ªN“Z6zÒ3$¶¡uSgÂüѶ·õL…ÒÙ‡_1å”rÛZàÕ#¼=Ôò¹ê&PLgf«ÓŸPE‹\G66I“­OŒáÞ”T$Kì‘gF{טIOº©üJãòÚ†Ó_WöPηw¼ð´j?w„‡ÒRiíñ ù ø(e.ÃèÏ ö“Ç<Îco³Ÿ ÜÇÉœÂhÊè“ë’Œ‰¬Í1˜Ëãôa#¸*­GJÿÄo)gwzhz«ëÇâñxx®ÉÛ•Ìá| $TªNÈuyÆ ÞL´ kªIIáAF±0ÈF¬ÙÍ•žf1£yо)_ÈÑ2iR˜ÏzÎf‹¸‘>´b¿Ð;——ÛÀZ1ˆ±Ìf,]XL¿ºò]:3‹SèÈâà[ý³‚ml`5Ï3Šïò6[Ø‹ôâq&2-T3…(e=³ÙA`„}0CèÀ¬ pø0ý¨§³ØJ1Oñ2ëYG››=„e‰VRÊH†2–ƒäÝó¡Øël*ƒüÒŒPã‘â ‰ëÀî¼Áò`Ýû,G²Ší”1‚­¬%aé]£E9_ }ïÇÑÀ:á>*XLU8”)¶7Ó.ÊúÂìÆ�Rœ:%MÅÔhÏ^â°¬K}FuÆ>¬aoFUÃŽ ¤3’MndûÑ›y$¬`s(_û"÷ÿ½{Åll–­^õoèÃÕ¿Ša äU¦7{¸ú=¤_b*¹Œ£” l`mSÊlò'˯TZÆ÷Ù‡g8€7ó\­èI]†•o¶|«º8˜> e¡’BÒLα[Ư˜ÈÎsC£z:pw'N¯uy¢=ߤMž³Ì*rå†ä›§Ö–Õ$¶2CøNbZboñ·ð8Kƒšø. ²f'r/ç:%ñ-æñær2{²–™¡gæÕðd½Š©‰ù$lÈ1%qµ& ®5M>ƒÏ'æs<«Bùˆ1ƒ£Ârþ'1œŸ„ìäWó—1o±†a‰R©Ifð&îäMòø!÷sÃÙ^£OböäÿÒ›9tNL§†½YËí¼@~ÈÚxëÍX~C55Lc}©ä›¼Êkì˽tb1'rs9*䡵ã[<Åy,æ6óWÑ6kO•ç7Ñž îàdrXÄÒLá6V³žÎå)æ°'§Ó—?s>Ky%H5® š³XCŠ·ù&¯±#HH8–Æ ‡t=x‡Ûhà`æsb¨YÞƒ»Èe$³Ée�<^AV±è0_Fi(r˜Äg³rb)Vs0%üƒPÖ«Àl6†‘¡·Ù‹–¡OµMˆXùA oùLæyÚqS³¦ÍÃV:’0“eœ“ñRFc8”—ÂKϱLç[40‡Ù,ä ¡*túm¿.Ÿ³x• 5¥eù*ëù"sC™y&ƪ®þù”°šzj)¤8èµLá%–U·F6ñLŽŸPG¥4p ³¨g5«ø#“˜ÅÑí jüÙÔÆÇW¤ŽO+KÜF‡„ã7CNWVÀtcÆ7µ›hÌ£zÏÓ{Hf·bë–qtcLÒ4ê3„eßg«ÚŽ쮬*ñåÙÛn®É²P“´ÒO©dd6™sxƒ¸1×…äeÔs-YÅÖ™ÄtNбóRM#Þ½(᫼Â䌹¬eƒù•ü!å\Σ{Ë;“߬c‚å Ž¥ϰ‘ê\W6˜’2†–ŒáZ"ÃE<Æ|zsgÓÈ:†d{;SSÞdm˜É¥, ²x%|—Ö1ƒk¹ ŒÀ½ÌLÚ¦¤iÇø Ö˜ãÊjZ³†\ÊkœÍF+TÝ`|ÞxŽFjéȰ”³ø*åÄêŒËÆÃÔRÂ6® uëmÃ[Tq"÷†÷w(§˜N¬c[‚P†‘â#ïpqÈš[ÄR¾ÀBZ1Ž9™;ù+oñUöÏudÆ4e+Ïó<r4÷Ë—ù (¦ ²–j®c ËéÁ Ìá0vçizq* Ì£œ5,OY“j?\Á¸àfr ³XÇnçV^ WâÆÑWH˜NmXÄ<†sV³ŒÁlžKorXÒ"öcSéAw.ãa³œBz±•Ö¬cS³;@õt£ª™‹Õ‰,&öT…Ç»±¡Ê­ç°…Œá*†«O—"ú„:ù×éÀ~lg`ðuÜ-QE{Z¦$)½ùk¨ÃϧoòS8©æ¨…UÓÓ3þ+“¹°@}ZËF©¥yü–ëideÌmë€Úž-5Ó*C^Õ­Æ‹XÅ7¸œG©c" ¬=6å<ÎþÌ P`TØÅÌçÐ`:·ƒÞôe,•,i-·¶)T'|!üŒA¬J¼Ìqœ¼í«ÈÍqZb.ƒÓÚ$n¢óIÑ›Ãy‹i¶1QÊLªØ#Ôr. ªPTÊ6næÀl±mÆs)G§žx”ß²™\êØ—A¼Àa¡3s>]¹›‡¨ GŽŸ'Þ¦+C¹eìϾÃF–1‚cYF‡`L¾Rz¤Jl :Hý>ÃLº“ÃƲˆÉ …ÛmŠœQãMrx–%,äH2¬Ê1*ñQÅál`%Œ¡†áu¹Ž¯†~¼ ëXD‡Qœ 7rÕŒb%#˜Ï:s•ìÎHnæIý™E^(k-L;*iòxœÀ®ÏèÆ d0»Ñ–a\K%irXÅžœA•ìÍ1,¢E(ZjRrb³YÍh~Ïjöd+ÿIcÚ^”1Œ¯³œ§ÂØçοìë×bzQÈ+š2n2¡¿Ž’0\4šûƒÆÑTò}–³˜mi“‹‚3x>çq?)6°•m¼Ãr²ãy¶ÙUß…Žô -î ‡›(¢;EŒb.ÓÁF…‘H Wÿ2jB¬B!û°€}Ée%…ä‡!ôÒ”#ØÔY²f¯GÑ›ù”ÐÚź,Ì]’e5بkt uÈtf°…¹¬fò ت¬KÍ]<Qé‰!^<NÖàÑ>”±4Øç0”°Gðå´É[¤dÏRGþÊ©´¥–– áæ0:_Rï6ö †ç™ÁH*CÍãN£ #xŠŠD«¬ÛBʱ‰Çy‹¾œ•£e¢¿dkJn¢Gâ[Ávûñr‚zw“Ã><‘rBŽ’¦,Þ”$ö sÈË¥Ï1‡ò?MšÒöÎÑØL›ìóo¢ˆgYÏ)´gÇPzÏ£šüœ“ø=hàÞJtfy¼•ãúÄÆ A;‹ýCŠs7^¤ »ÿk¼H=s) „ ËèMqâ~–Ó– ©í{„ÄëÙÆÙ”iŒ¾š|â³iè»…q©ÝøeÔ9ʬ—|v·”†LÂÕÌädöbOÚñ6•¡ã®*e\â&Žc/s¬¬°z+òh [ŽTPáÖ°9Ç1‰¼ÍfÓƒ=©#ÍNcëØ—gBçØš P´obϲ’SÉe-µ¡ƒac)ã)ŠËh¶rm˜Òöv2ÕŒ"¡+ƒzá¤\–4ÉjdO¼ Z³-èlu>™íxœÕ”6Ûr+öfoæQVÂR¶³ÌoVzÕ‘Ùͪ†#ÿ;\¥ÆO¾`ì'l,-ë™[zÐèÁq}ÊäÒ…ut ¡Í) =ÙÍÔÓ–^Ôó6ù´Ìzÿ¤%yº×6éÁ÷d=(Ûµ®°'å)óµ®UM m)$VáòËe5¹Ò:ôidB~ZVrkÃWmOìÕ14<†w¤:¤–Ïï¾Ô4Ë}EEè ÚNWÖÒ1¨Òe-{¦µLT'4û-«iCn]x;8Òf3ÄV†D€í)=Rr26…ÒuÁ¢þí =‘ý_J^ʈŒJ(Hë”±”BÊèI~¸G·'à :iêå[t³;§3«iOq(îé6¤ìHÙ+cU¸åeO€*2´¥”ì+ֆ߸ó8fãú 3¤Ù™Ó*TVUPN€B¶Ð#H¦îÜ«;é¬mšåž³ƒºRKšMA]7Ûùù¿ëvžr‚¶Åßö*hIË”"J’]3ÜÒöÉXNò-a#›)'¡T†­­ßUõ5[º·• ¤éOÖd äÞã²Ú-œÒÙ‘³µ´eõ®?d5íÈ„ßØ*œ�ÙO·¾ëp¤é òv^ïQ#UL÷¬s[¸WýJÿ}d Ó­;_ÿÀŒšªíï,˜±K¸ºäÜ)EEEqE"‘Hä³À¼%kv†«tÜ‘H$ù\tLý›o¾9I’¸S"‘H$ò/§¨¨hÌ¡Gÿýpõ³Ÿý¬¬¬,(<îü—þ�sÞ=3ýVùhk}"ßçnê#ô§úµS’´$Õì_Z&µËœLê]˼{±¶VJæ#-“Iñ‘¾@æ#ýØ¿ûþñ~ûhk½{™ÙÙ÷A6õé]4ù§}Jw‘÷_æmñŸ¹—?ùϹë~ò7½Ö­Û¼çÛU3²ë¤Ãšé÷žüø |âüwhqçµé_öú^“ÿ„b‹»N&iÍ®¾xq|f[L}"Ç)îÖO«ÅyKþ&OÇ®"‘H$ò9 †«H$‰Äp‰D"‘H W‘H$‰á*‰D"‘®"‘H$‰á*‰D"1\E"‘H$ÃU$‰D"1\E"‘H$†«H$‰Db¸ŠD"‘H W‘H$‰Äp‰D"‘ÈG$÷½?JHÈdí*È„™éw}š¤vÕÿ“ï³ÌÇßø'8ù‘·ð‰|“ôÎýŸÈ$’ŒLZ’ÈddH™ô»>MËdþæpÑd>ò¾“; JL€ \��0IDAT>ìdÖ ª©Ñ÷™l6ócM~B_ûƒþ¨÷ø&IêoÿcŠ„T8V;/—Ì®WXj×O?Õ³ï3u…ýs¶ÿþK¦w‰Oð8}Þwܧô£>Êòòòš¿Sí®Æ_SSóÙ‹©™øXñ'iöDóè-ȉGäý®¤Æ¸#>u¦M›6nܸz15þëZß…ÚÚÚyóæ;öC­õÚk¯5ª  à.9kÖ¬¡C‡¶lÙò½èÒ¥Ëÿù£¿®n½õÖ¢¢¢xªE"‘ÈÇaøðáS§Ný¼·^RRrÚi§}ØM~øáwß}wçÎÿá’Çü¯ýë>}ú¼Ï2ó–¬ÙùwNŸ¡ûvï7¸²º¦(]=vôž………ñT‹D"‘CïÞ½û÷ïÿyo=''§W¯^}ûöýPkuëÖ­ÿþ¹¹¹ÿpÉ®]»î±Çùùùï³ÌƲí3ßZÛP_[¾imn<±"‘Hä“eâĉÿ´^XXxØa‡}ص>ø*¶Ç2fF"‘Häs@ W‘H$‰á*‰D"‘®"‘Häß“‹.º¨ùä¤I“&Mšô׿þ5;¹téÒìœ dçL:5;gÇŽ³é_þò—“&MjþÎ;ï¼I“&Ýpà ÙÉmÛ¶eÛzæ™g²sfΜ™³jÕªæ›ú‡+6'¦ZD"‘Èç‰+®¸âþûﯩ©¹öÚk³s&Nœxýõ×ãŽ;îhß¾ý~ûíw饗f?ýö·¿}óÍ7/Y²dÚ´i×\sM6°=ù䓹õ[o½µ¸¸øšk®Y¹rå%—\òë_ÿúÜsÏ=ãŒ3vß}÷'žxâÎ;ï<óÌ3'Ož|ÓM7ášk®éÔ©Sqqñµ×^›mýœsÎyöÙgwFÜ3Ï<³K—.ïµâÈ‘#c¸ŠD"‘Ïq¸ºâŠ+†¾sΚ5k²éæI’TUU%I²yóæìœòòòÆÆÆššš†††ìœuëÖ}œÖ¿öµ¯eÿX°`A›6m°iÓ¦®]»öéÓ§  `Û¶mX¿~}¶­ÚÚÚÚÚÚ†††ŠŠŠìœM›6íÜÔµ×^›ÉdfÏž]__ߢE‹w¯ø¿šŽ‘H$ùp<ðÀóæÍ»òÊ+?ævêëëo¹å–’’’aÆýÃ…c¸ŠD"‘ȇàøÃòåËüãüMÜvÛm}ûöÝÙCÃU$‰D>î¹çžòòòóÏ?ÿãoêòË/߸qã_>Ž]E"‘Èç›:””” •J¤R©6mÚdç´lÙ2Nççççäädç´oßþã´õÎ;ïWWWWWW¶mÛ¶¨¨¨¼¼¼¤¤¤¡¡!;Õ®]»l[¹¹¹¹¹¹999………Ù9m۶ݹ©U«Vmذ!N¿×Š1\E"‘Èçž1cÆìü{Ú´iYé£sÎ9稣ŽÂµ×^û¥/} ¿øÅ/:vìxÐA•––fç<ýôÓ§ÝÞ½{ß~ûí÷Þ{/Æÿƒüà®»îš2eʆ &NœxÙe—aêÔ©'t.»ì²Ñ£Gãâ‹/ζ~÷ÝwïÜÔY±9©ñ“/{Ä KËzæ–^rȉD"‘Ï󖬹þ5UÛßY0#Ž]E"‘Häs@ W‘H$‰á*‰D"‘O‚¦T‹T:§:“¿pÅÆ–-·Ç‰D"‘Ï+ÖoI¥sv W¹yùeõîxr~Ü;‘H$ùŒJçäæåÿ-\Õ×íØ¾eSÜ/‘H$ù ÒP»©i3æü×/n­««‹{$‰D"ŸM~ú½oü?ÏI‰ÔÝtao����IEND®B`‚�����������������������������������������./saods9/doc/user/scripts/thread.xml����������������������������������������������������������������0000644�0001750�0001750�00000024151�11343564747�016327� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="us-ascii" ?> <!DOCTYPE thread> <thread> <info> <name>scripts</name> <version>Sept 2009</version> <title> <long>Scripting ds9</long> </title> <history> <entry day="21" month="September" year="9" who="liz"> Original version <!-- scripted version of contours thread //--> </entry> </history> </info> <text> <overview> <synopsis> <p> Scripting with ds9 can be done in several ways: by invoking the GUI with a number of command-line options or via the <a href="http://hea-www.harvard.edu/RD/xpa/index.html">XPA messaging system</a>. A third option, Simple Application Messaging Protocol (SAMP), is introduced but not included in the examples. </p> <p> To illustrate how to script ds9, we repeat the <a href="../contour/index.html">contours example</a> with both methods,. The examples use Chandra data from an observation of the galaxy cluster Abell 2142 (ObsID 5005). </p> </synopsis> </overview> <sectionlist> <section id="commandline"> <title>Command-line Scripting</title> <p> The ds9 Reference Manual has <a href="../../ref/command.html">an extensive list of the available command line options</a>. The most important thing to note is that the commands are executed one at a time in the order they are listed. </p> <p> To create contours on a data image: </p> <screen> unix% ds9 acisf05005N002_evt2.fits -bin about 3800 3800 -bin factor 2 \ -scale log -cmap b \ -contour yes -contour limits 1 100 \ -contour smooth 5 -contour nlevels 6 -contour save ds9.con &amp; </screen> <p> This command line produces <figlink id="clcontour"/>. </p> <figure id="clcontour"> <title>Command line: x-ray data with contours</title> <description>Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.</description> <bitmap format="png">contour.png</bitmap> </figure> <p> The options direct ds9 to: </p> <list type="1"> <li><tt>-bin about 3800 3800</tt> : center the image display at (x,y)=(3800,3800)</li> <li><tt>-bin factor 2</tt> : bin the data by a factor of 2</li> <li><tt>-scale log</tt> : set the display to log scale</li> <li><tt>-cmap b</tt> : use the "b" colormap</li> <li><tt>-contour yes</tt> : display contours</li> <li><tt>-contour limits 1 100</tt> : set the minimum and maximum contour limits</li> <li><tt>-contour smooth 5</tt> : set contour smoothness to "5"</li> <li><tt>-contour nlevels 6</tt> : create six contour levels</li> <li><tt>-contour save ds9.com</tt> : save the contours to the file "ds9.con"</li> </list> <p> If you wish to add options to the command line after it has been processed, the whole command must be run again from the beginning. It is, however, possible to interact with the ds9 GUI that has been created. For instance, instead of including the "<tt>-bin about 3800 3800</tt>" modifier, the image could be recentered in ds9 interactively. </p> <p> The following command line builds on the previous example by retrieving a DSS image and copying the contours to the new frame: </p> <screen> unix% ds9 acisf05005N002_evt2.fits -bin about 3800 3800 -bin factor 2 \ -scale log -cmap b \ -contour yes -contour limits 1 100 \ -contour smooth 5 -contour nlevels 6 -contour copy \ -dsssao A2142 -cmap grey -contour paste \ -frame first -match frames wcs &amp; </screen> <p> The resulting image is shown in <figlink id="clcontourdss"/>. </p> <figure id="clcontourdss"> <title>Command line: x-ray and optical data with contours</title> <description>The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.</description> <bitmap format="png">contourdss.png</bitmap> </figure> <p> The options which have been added from the previous command line are: </p> <list type="1"> <li><tt>-contour copy</tt> : copy the x-ray contours</li> <li><tt>-dsssao A2142</tt> : retrieve a DSS image of A2142 from the DSS-SAO server (there are also a "dsseso" and "dssstsci" options)</li> <li><tt>-cmap grey</tt> : use the "grey" colormap in the DSS frame</li> <li><tt>-contour paste</tt> : paste the x-ray contours onto the optical data</li> <li><tt>-frame first</tt> : select the first ds9 frame</li> <li><tt>-match frames wcs</tt> : match the WCS of the DSS frame to the current (x-ray) frame</li> </list> <p> At this point, we can end the ds9 session or modify the display interactively via the ds9 GUI. </p> </section> <section id="xpa"> <title>XPA Scripting</title> <p> X Public Access (XPA) is a messaging system which provides communication between Unix programs through a set of access points. The two most common actions are retrieving information (<tt>xpaget</tt>) and issuing commands (<tt>xpaset</tt>). For more information, see the <a href="http://hea-www.harvard.edu/RD/xpa/">XPA Messaging System</a> page and the <a href="../../ref/xpa.html">XPA Access Points</a> section of the ds9 manual. </p> <p> XPA commands may be issued one at a time from the terminal or collected in a script to run in batch mode. Unlike the command line syntax, there is no predetermined stopping point - commands may be sent to ds9 as long as the GUI is open. </p> <p> First, open ds9 with the data file: </p> <screen> unix% ds9 acisf05005N002_evt2.fits &amp; </screen> <p> The <a href="http://hea-www.harvard.edu/RD/xpa/xpans.html">xpans name server</a> is used to manage the names and ports of XPA access points. Use "<tt>xpaget xpans</tt>" to see the list of available access points: </p> <screen> unix% xpaget xpans DS9 ds9 gs /tmp/.xpa/DS9_ds9.22972 username </screen> <p> Now that ds9 is running and linked to an XPA server, we can use xpaset to modify the display and add contours. (Refer to the <a href="http://hea-www.harvard.edu/RD/xpa/programs.html#xpaset">XPA documentation</a> for details on <tt>xpaset</tt> syntax.) </p> <screen> unix% xpaset -p ds9 bin about 3800 3800 unix% xpaset -p ds9 bin factor 2 unix% xpaset -p ds9 scale log unix% xpaset -p ds9 cmap b unix% xpaset -p ds9 contour yes unix% xpaset -p ds9 contour limits 1 100 unix% xpaset -p ds9 contour smooth 5 unix% xpaset -p ds9 contour nlevels 6 unix% xpaset -p ds9 contour save xpa.con </screen> <p> This command line produces <figlink id="xpacontour"/>. </p> <figure id="xpacontour"> <title>XPA: x-ray data with contours</title> <description>Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.</description> <bitmap format="png">contour.png</bitmap> </figure> <p> The options direct ds9 to: </p> <list type="1"> <li><tt>xpaset -p bin about 3800 3800</tt> : center the image display at (x,y)=(3800,3800)</li> <li><tt>xpaset -p bin factor 2</tt> : bin the data by a factor of 2</li> <li><tt>xpaset -p scale log</tt> : set the display to log scale</li> <li><tt>xpaset -p cmap b</tt> : use the "b" colormap</li> <li><tt>xpaset -p contour yes</tt> : display contours</li> <li><tt>xpaset -p contour limits 1 100</tt> : set the minimum and maximum contour limits</li> <li><tt>xpaset -p contour smooth 5</tt> : set contour smoothness to "5"</li> <li><tt>xpaset -p contour nlevels 6</tt> : create six contour levels</li> <li><tt>xpaset -p contour save xpa.com</tt> : save the contours to the file "xpa.con"</li> </list> <p> As long as the ds9 GUI remains open, we can continue to modify the display. Here we build on the previous example by retrieving a DSS image and copying the contours to the new frame: </p> <screen> unix% xpaset -p ds9 contour copy unix% xpaset -p ds9 dsssao A2142 unix% xpaset -p ds9 cmap grey unix% xpaset -p ds9 contour paste unix% xpaset -p ds9 frame first unix% xpaset -p ds9 match frames wcs </screen> <p> The resulting image is shown in <figlink id="clcontourdss"/>. </p> <figure id="xpacontourdss"> <title>XPA: x-ray and optical data with contours</title> <description>The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.</description> <bitmap format="png">contourdss.png</bitmap> </figure> <p> The options which have been added from the previous command line are: </p> <list type="1"> <li><tt>xpaset -p contour copy</tt> : copy the x-ray contours</li> <li><tt>xpaset -p dsssao A2142</tt> : retrieve a DSS image of A2142 from the DSS-SAO server (there are also a "dsseso" and "dssstsci" options)</li> <li><tt>xpaset -p cmap grey</tt> : use the "grey" colormap in the DSS frame</li> <li><tt>xpaset -p contour paste</tt> : paste the x-ray contours onto the optical data</li> <li><tt>xpaset -p frame first</tt> : select the first ds9 frame</li> <li><tt>xpaset -p match frames wcs</tt> : match the WCS of the DSS frame to the current (x-ray) frame</li> </list> <p> At this point, we can end the ds9 session, issue further XPA commands, or modify the display interactively via the ds9 GUI. </p> </section> <section id="samp"> <title>SAMP: Simple Application Messaging Protocol</title> <p> A third method of scripting ds9 is via <a href="http://www.ivoa.net/Documents/latest/SAMP.html">SAMP</a>, a messaging protocol that enables astronomy software tools to interoperate and communicate. SAMP is also used by such applications as <a href="http://www.star.bris.ac.uk/~mbt/topcat/">TOPCAT</a>, an interactive graphical viewer and editor for tabular data and <a href="http://aladin.u-strasbg.fr/">Aladin</a>, an interactive software sky atlas. </p> <p> Information on the ds9 SAMP implementation is available in the <a href="../../ref/samp.html">ds9 Reference Manual</a>. </p> </section> </sectionlist> </text> </thread> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/scripts/contourdss.png������������������������������������������������������������0000644�0001750�0001750�00001316104�11332353406�017234� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��:��r���B!ý–���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ3YÛÕ �� �IDATxÚìwX××Ç¿3ÛwiKl(jÁ£‰½Ä‚%JˆÑŸ‚‰IlQ“H"Æ®ÑXb,I4±‹‰F‰]l *Ez‘º´]¶ïûÇ0ã¨`ò&ÆÌçññYfnŸ;÷Ì9÷Ü{ F{ðÄï[÷ÇËGØØÁ#ÞîÅ?xâ÷Øk)]ßƵÇKÈ¡ßã =Ñ{ÔôÀ¾CÊ*ª¹áààààx ©(+ÉH¼Â`0Ô*×"ÿeÔ5ÕÚåsƒñ"©™AƒN­¬2èuÏO¤Hj&I�hÔJªºY%2 ’äQ z�”¸ÒkÔµâJ§Vj “›É% ·Š'±s'‚Š^£"Ê3K+ªì}:sO—ƒƒƒãÕ@§ÓêjªÝÝ\Ÿ²¨¨¨²¼T$–¨UJK3‰•ƒí³ÃëuºÜüÔ&“FUÕÂÝí¹Y—TU”Š$f”ø1 µâ Lt ¾H k—æ.Òv­|®^¿™TR$²°-±LÔ Ð5–ͼMÜãåàààxUЪUînà¹!]\\¦§"‰ˆoooÿÜðB¡°™£Ca‰Âh4¸»¹ …ÂçFqvvÊÈÈ€ÉdbéK|�@$­¶'³IÈÈQUWZ™K%yÙš‘PfM +¨JŒê2µÈN`fõ8Ê+„€Oúº9ŠE‚ä¬Â*¥šëÁÿH¢–Æ&‚ HO2É7% I%˜híŠ Hò±ì!I‘μكìQß «*Îà ı™¶ªTXSTm ä|~ÃâQ,ä·ñrnálKD¥R”žŸóHa4™�øº9´÷mÎçñ~9w»ºFC…w²³lçÓÜB&Öêôù¥ iyƒÑËÅ®cK·{é‰óL¯' ßèì'7<*¬RšË)Gz8Ù¶òh& r‹Ê¯'ejtz®—spp¼ $JB4*0AjÃóHòí®­ê‡º“š—]XV+ÞH’0™:‹×ܽ›Û¹ž¬Òh©À­[˜Ëħ¯ÞgeAÒ² Å€'Å@bf²õÌJ¹À7¨ &Â@ ¥üʬ*NÔÌG –>­ ]Úx êÖ–€±¼²ÚÂ\¦S«r ŠAð%"AÇ–noviIĽԌø”’Ç÷jn7¦oÇf¶åUR‰¸[{ïS—c¯>pv¿ÑÙ¯¼¬ô–VÍJþÞF�„ѠתkL&Sfqu´ž4(P«Õ”**^oÕÎÊLtìâ]€äú9Ç¿_ZQšO£4–vEàóx]ý=뻟œ¢Óh„b A§: ·f6]ý=l-·¾ Kk÷¾ýt:ÝÞŸOÛ9»QY€úGç³®[D‘™Ü̽£âþ9ô5ù)&U©OðÛŠd–µŠY=„¾‡‹ÜB:ë«¥•*¡P¨Ñ¨ |™Xfiomáãê˜_Xb+·ìàsåîC +›·[µp²Ù}ä||’›K³ˆ ƒ·½žB€� ×k­dÂ¥IÉ*4M®ŽÖ¿]{Àç‘ÝÚ{)ªw¿RVYóš»ÃànmäæRHJ/8yé^i…ÒÓÅ6äÍŽ<™ý¨Ì½™Mz^ÉŽc—ͤ⠶ž]Z»IÅ‚ä¬âãï){§ØZɵökᘞW"“�7y`W_7;“ Êšè“×üZ4³µ”}àÜÅÛ©+æ„v|­ù•;É%ÕÆFê¶/¯¸"HÊdׄÀ¦ÚðI¤gå-Y¿›m‘êÜA«®1 µ² ÒDÒYœ¿•fc)kåÑì½Á]“Ò ÞêÚR«Õ.øf“^W;¢,íŠúŸOi JT©•ƒÊÆMU˜f$MB«ºØËŸQƒÁXXZ¥ÖèÂßú° <-§89ëQEU ä5w°v±·Üy0¶s;?7';wG9)’ÙÉÍõzýo—oK¬ŠU¼¬Gåö6VîŽV:mí¤I2±«ƒåÍ{=œä£û¶OLÎÎTâÿš»¿»ÍÙ[Y&’R3s }Ýß ¨ªª:ŸÒ¯£•ìôñ®NÎöVYÙ5Ue}:uÖ³íÕÛ÷3ó GöïFƽ§âÕz@¼`ÏàvžoÜ-¯T¶÷í˜[P ÀËÅ.¸Çõ„”Ä”L[kKEq~¥£œ ?/7žÄÂÊÒ¼FU#—‰ ‘øi"œƒƒƒã_#®m ¬‹¢Á3Híݼ˜0f6ÍÊ IjŠ H‚xl ÔŒÎÜ´õròt±Í/,Yýý¾JÑÅÓ)I¨•M[»j`´Õ×TêUeF¾ÄLÌã‘ µU†/?­&àòÝÌêêÊŽrÏf¶ÝÚy]ILÿù\‚‰àµñrª¬V>Ì.�_<q‹¿[ÂÃB‚ F“‰à ÅR_h�€$ ×iÙÉÞ¾ÿpç¡ß,ÍÍ|[8þí"_(rw±·±”¨UUeªG“¥™¬Fgðyf"²™\li&y˜•·ãào=ºvôts ðZ8ÙÔ­P(TktŽÖf–²¦RO’¤L"v²“WU«ö;§6ò}½Üù�T×h•Jk+sgG»G¥åZƒ)ñaÞ™k÷Üì­í­-««”<i4èFÃ+éuÂÁÁñßÓ®4Z»Admx’vˆ`E§~>¶é‘$a2áÉ,2 ÊÚz9ÈÉ/„@âäáÎÜ%H$IÛ–«êKT½V]™}ÇÒÚ£®8½¢¢Ìˆªª|KK·6<žà)�ŸÏ¿œ”ýGü=/WÇ1ouõt²&ôJ™•]«ŽLCûvKe"¡ÀÛÕñfrNµJídcÞÚÇ=¯Ò$·”:ÙZšLÆìü¢nÍÙɪjÔ&žÐHðõzCUÆÎÜ I’ðÐÕ¿E7¤”ŒÊªjJ3&“‰ HD&–š3š© 0±PTSsþÚmEyUYY©ž ù|F‚äIdr<@àQiå®c—l¤¤»Sp‡@>ŸöVÖáó ROÂ8=äm(*-7D£}]8888^RqEA’d£ç®H‚4Õºé1OF¯µã‘$IÙ�MÄYtnéúF'ŸÂ’²û©™=ä¶ö?ž½Ãø¯ ºZ êˆ+“ÑPS˜¢W)äžf6NJ‘¬:ãš:¢:_[n+µskÐöÅã=¼^s³Ë+RH„ÂfvòûiYU•m[šID…% ™D “AQQíâhcm!½t'ÕÃÙö!2 Êì¬-<œm®Ý¾Ÿš•ïíõä”ÉD<’.4Aò¨Ì|ÒÑÆBÈ'Ó2ólíl¨Zå••U(½Ý§éïìdoi& ÖèÓsK^÷s …Ujƒµ¥™µˆ<" $A5Z]~qE{o§=;© üN69ù…�œí­Úú¸ææjôòùbd|ãàÞ¯WTU»ØY:;Øœ<-¯Xa&w¤3×Ý988þåÆÀÚ¡,°µ[kºS?UJÍþ3·Ÿ% ©ðµÿã‰y¥ZICK‚ IÒDEÐ鵿}:x0-]¿ÛÄÛ:8µöpÛ·ý®“7XÚ-®˜¹«ºÊɨ¯È“ÊÍý-Ü�X8¶0uö(–IDU:EÒ‚of]_b™LDZn‰…®öÖ<’¼vûþ¡ÓË•º×\íï¦fÆ>›œõˆÇãwmÿZÈÀîÖf¢ ·S‹JÊÞìÒÊÍÁRY£Þ{ä̑߮ðD2‰WTZQ­¬1…e•ÕJ“ÉT©Ò•–ëtzÎP¢¨ª¨RV«4q7SÍ„¼î¯·‰¿—™SPR^Y]¥Tï9qõÞmí­òóÙYJuzƒÁh¼z/K«­éÒÚ½÷ë­JË«/ÜHªVª„fÖ$Iê ¦ wÒù„¡•—[f~ñ¤‡$Œ:½½¥™·‹ \¸‘tôì3¹™Dàçê¦ÑêbŽœ9ræªÐLÎŠêø»spppü;ÅU­qO(à I“Éh|b„×*sÒ’š{·¦e #Á˜üärù¢é£ÙâŠ$‰û ‚‚ (y“ÉÄØ^•RµxõV¥Žpñö8—d¤<Cvr‚ëkþŒ`ªuµ JØ{ÔôÎ}•U22ÇTS&¬ÎV¨!unCòøÌeR‘Ò¦¹%`Ê,®)ç;’ÂÜÙM&Seé#µªÊhФ@(’XZ ø¢²Â,’äÉ,­ùB±ÉdRU*ÔÕfÖöb‰™²ªL£ª6 $/–šKÍ­øBQeé#U•ÂÌÊŽÇ”åÉ,m̭틲Sy|¾¹£^]S]Q,1—Ë,¬UU U¥‚ I¾P¤­QJ̬ü|½kªÕŠnZ îÓeïá3±×R,íœ :MuE©V­‚ÑDòùb™¥ÌBÎÔ. «©®¨Rô:¾PdÔëHžÀÂÆÁ ×U–>2 Hb.·7tUeE½ŽÇã‰e–3K¾PÜHõ™ƒƒƒã¥EUYÞÂÝ…ÙÕ¢(']­ªªFbfiçìàáÃt¾ÄœgÔ¹¸8Q·´jÕ£¬ÔúÉ:ºy ÅÒªªêÂ…Ñ`pkÞL$Q·Šó2ÕªªæÞm˜ÀyiI‘ľ¹€ŒŒL¾Ä‚WÊʲ¬»Wkµ+fv˨×ê+ µzˆí½H¾€­Ö-Ü •–bR�­¦â‘ÄÞ³Aƒ¦™ÜNj!gÜ7’GòxÖŽnA’</�ÀˆÌ¬lIÏòBƒ…ž ðx‚$eV¶2KjI³‹'Éã“<žM37*5¡P,’™“<>Ç7³²“šË ‚4Á“‘ x-=œÚ{u0 2ñíû/ÝLŠ-¨=y¡Ñh¤œÿA<jâ � 6³à EÔ¢�“É‚à‘<H"Š™•Õ$' $¡˜‘û$ŸÏ™988^j7©¨\=Ÿ©‹‘u¶¨Idn¯µ{ºêFÔßÕÂÞ¥E`.Þ­ŸˆCl3^­gàcý€/$,œx<!_lFO˜ûLBi¡Ž(©Òx"¾ñ4•‚Š�Q‹<©ûO¡è±{!Éã „uËØ+‘éÀ<™9s¤<ðëd—˜^”‘‘nÔjjÔêܲ*)3“òø|’$©-Ÿö¬x~ý«Œúõø _ÀulŽW P\T\ÒÜÅù¹!KKËŸäñu:MUµÒÂÂüÙáõz½¢¼‚/™øÆ¢âRWW—çfQV¦0<‚à1N ¨¿îŠÇ'yvO€È �x™çjʪÔÙååZM I’ß\*Š%f<ŸëŽOC$‘ij”iiéÐÃø"‰É㛄’¢’²¢¢âç„'ž@,‰hÕªÆeÁŠÍ¥ˆ`iW�åŽWd›u©¥u‰5£ÉÈuGŽg ”Hi#MF’Ïñ-ž’/±bIã³ ×YË„MF£‡ƒ™¥LÄ=0Ž—„ ¥&½°šµ#;`ÐkûuömïÛœkŽ—µZ}èT\j^í>Gugt”J%×Fÿ8¿þúkjj`×€¸2™L:Žk#ŽœÜÜ\¶#;·fˆƒƒƒƒã_�'®888888qÅÁÁÁÁÁÁ‰+N\qppppp¼,4vk¢›7oVVV²¯Èd277·{÷îµnÝÚÖÖöŲ7 üñó§@  bþŒ‹‹“Ëå:upýúõ-Z¸¹¹52ý{÷îõìÙ“ú311±´´@³fÍ|}}ÿ?”Ê‘ùóÏ4Î såʵZÍüÙµkW¥RyçÎ__ßfÍš½Xšõ;�ÓªÿßdeeeddP¿ííí[¶lùÜ(jµúÊ•+®®®&k¥Ryýúuêw—.]Äâ'ŽÒV(²UëpýúuöJ’ú96¦“ÿy ’““ýýýe2Ù¥K—\\\¼¼¼nÞ¼©Õj»téÂîäÌã`w9¹\þb962bbb¢B¡èÞ½{#[�5€pü¿Â~ŽÏx;Î;×ȹ¼­^wñô«VÕ¼î×ÜÑÆB£Ñ4nâĉ۶m333K§Q( …bܸqÞÞÞ/V=µZýúë¯'$$Æôôô‚‚‚nݺ±ÇÙœœOOÏ_ýµ}ûöo¾ù¦]```#ÓŸ7oÞçŸ>wî\êÏ>úè›o¾±²²~~~ÿŒÊÑÆÆ†j%ooï¿_\ 8ð—_~‰DééékÖ¬!ÂÅÅåàÁƒÎÎÎNNN/–æáÇoݺEUjóæÍß}÷Óªÿ¯dffΞ=ûúõëåååñññ;wîlÛ¶ísk‘——׫W/33³=zü™Ü¿þúë7X¿~½R© ®3:ÔÇÇÇßßÿ/©ì¨Q£öîÝ+•JÓÓÓ̱AΞ={ùòå>}úüUmþóÏ?Oš4©wïÞæææÁÁÁ<ï7Þ˜8qâ?ü0uêÔ7nDDD%%%QãöíÛS§N‹Åééé»wïNKKëÞ½;sÅs),,œ?þ_|QUUÕȈ}ôÑÊ•+?þøãƤðàÁÜÜÜÎ;sâäÿ¦ç¸¹¹=ãíhß¾}EEÅàÁƒŸ›`BBBž¨0Êô:Myan6~•Ëå_ý5õ{É’%ÕÕÕÌ-­V;kÖ,êwDD„O“*Ù©S'&eJöþôÓOŸ|ò õ§F£©¨¨0 QQQ�Ž=Ú·oß6mÚ4&åI“&]¾|yÉ’%óçÏ?zôhbbâ¼yó>|XSSàÛo¿MNNЫW¯#F¬\¹²ªªê‹/¾ˆ=zôèüùó©š4¨_¿~M樛7oþþûïÃÃÃW¬X1räÈÄÄÄ:9Ž;vÉ’%�&Ož›ŸŸß±cÇI“&øâ‹/JJJ�Œ9²©ßÎÍ›7§Êp÷îÝuëÖ½ùæ›Z­–ªãˆ#6oÞ<yòä:42Á©S§R?bccOœ81þüüü|ªä�¾üòK›K—.íÝ»€¹¹yTTÔ¹sç„BáåË—322Ú´iãîî~ôèQjèo|Eîß¿ÿ믿nݺuĈ÷îÝ :þ|‡ê4NUUÕ¼yó¨(Ÿ|ò û¸Ñ%K–äççhês\²dÉO?ý´yóæààà¾}ûfff®X±‚ºKõF†?þ˜úÔ£ZuÆŒ;v´±±‰¥§‘™:::R.##cݺusæÌ©Óª�öîÝ{éÒ¥ùóç/Y²¤_¿~555�nܸ±cÇ�"‘håÊ•TĈˆˆ;v899…‡‡ÿùñ(11ñ“O> øüóÏ?~\$EGGWWWSÅž7oÞ¦M›æÎ+‘4v_¸œœœÂÂÂõëׯ[·®ºº:''gݺu!!!—/_¦ÞG�;wîŒÀ¼Ô§ õZ1€y­(u¼_¿~ƒ bFª£GÆÆÆhÑ¢E#EÇ_B·ƒý8¨nܵk×ç¦ó‚sWÇ?~ü8óç»ï¾{óæÍÐÐКššñãÇ———¿pÅnݺîèèøå—_Ræ…¤¤¤˜˜˜òòò¡C‡èСƒ««k#S ¶²²¢ŠzûöíÜÜÜ~ýúÅÄÄ\½zuÆ Ë—/>|xûöíçÏŸâĉS§NýòË/ìËËËcbb’’’^¸:çÏŸß¹sç˜1cbbbÂÃÃëç*‹ÃÂÂÚµk׫W¯Å‹ïÝ»wÁ‚;wî utt ¿uëÖŸé.=Љ‰IKK;uêÔÆ·lÙBåÈÙÉ¥K—fÍš5nܸ3fŒ9²   444##c̘1÷ïߟ6mš••UhhèÁƒ?ùä“L›6ÍÓÓóí·ßŽŠŠŠ ½téRXXXãsìÚµë{ï½÷ÕW_õéÓ§E‹gΜ ©ß8ãÇ¿wï^hh¨B¡3f c˜úúë¯×¯_êîî>kÖ¬K—.5©“[YYQúMÏž=‡ 2fÌ…BzïÞ½ñãÇ3!g̘Ë<ÇŒŒŒ˜˜˜Å‹Ïž=;&&†ýa×Tê·ê¡C‡-Z8~üø˜˜˜Û·o_¸p!&&&###,,L,‡††ÆÆÆÎ˜1#---&&füøñË—/ß°aC#30`ÀðáÃë_ߺuknnîíÛ·©×ÊÊÊjܸq­[·ŽŒŒ”Ëå}úôY¹råôéÓÏœ9Óxc Z­ž1c†——׸qãè¾Jõœ;w.X°`ïÞ½‹/îÕ«óvPqKJJbbb<x@¥¿råÊÕ«W‡„„øùùÍž=ûìÙ³Ô`uöìÙÙ³gûùù…„„¬^½zåÊ•œù{¨ÿvP×oß¾ÍôÏE‹:tè¯WùùùAAAAAA¿þúký—ŠÏçËår‘H”ššÚÔ­1Ž9B¥<pàÀªªªÜÜ\WW×Í›7×1ÜSæ;'''KKËÆ'îìüøøÆÔ››[UUeiiiffVTTTRRrüøñ’’’wß}— ß»wï¡C‡FDD4õ QÕÙ½{7�“Éäíí]PPpýúõóçÏ»»»39xøða@@€““Sff¦»»»ŸŸŸB¡xôèQzzºV«•ËåR©”*j“ ””D•áÆ{öì©óý¾råJ*GJËl$ÙÙÙÆ 9räG}$‘Hîß¿/—Ë,--ïÝ»§T*³³³]\\�¤¦¦RQ\\\ZµjUQQa4¨ˆÏÔÒÒréÒ¥—/_¶¶¶öððX³f etÒétóæÍ»~ýº¿¿ÿ¾}û6nÜ(—Ë…Barr²Á` ¢gddÔÔÔÈår™L–ŸŸOi!/†ÑhLNN¶µµ 077g×"99™Ïç3Ï‘jUN÷á‡4þëŠêAAA~~~±±±¿ÿþ;Õª‰D.— †ÔÔÔ¢¢¢ÒÒR__ßM›6±#ÖÔÔdff:99ðù|J‰§tÄÀÀ@êµjdlllìííßy窋R ëÍ›7Ÿ6ÙàééyãÆeË–mݺµS§N>dk·iÕÊÊÊŒŒ µZÍ´jDDÄàÁƒu:]zzú¨Q£Î;×®]; êí Â¬X±bÑ¢E.\èÝ»wppðâÅ‹U*•½½}DDD¿~ýΜ9ÃXƒµZ­D"Y±b…ÑhŒ‹‹{—š£‘DDD1-LuE¹\.‹ë9›6mòõõ---eOù?&œœ.^¼Hý¦4ô:ýÂ… ©O3ælãF2xðàµk×R¿ãââ¨B¡ð/i»~ø¡mÛ¶ÇOKK[½z5[zøæ›o„Bá€\]]…Bam¨4 Çãó›|VÓP§N’H$”À¸wïÞ”)Sœœœêø,< ­VË4iã­I­Zµ¢¾*† 2a„­[·2·‚x±¶=þ¼\.oÕª÷÷wVXXß¾}ûüqÈ!Gm×îñ‰¥<*ÌÉ“'çÎÛ¹sç„„„ú‰0Íèààð·•¼_¿~|ðAScyzz^¼xñ‡~X´hÑÕ«W©O´'NÜ¿?00°U«VLÈF¾e/ö¬[¶liaaqåÊ•H¥Ò›7o>í¹ÇÇÇ—””ôïßãÆ³fÍš2eJÏž=íìì“Q\\œ•••N§[¸p¡]FFÆ•+W�欣ÌÌ̈ˆˆúsZ$Izzzº¸¸\ºtI£ÑtíÚU ,\¸páÂ…cÇŽíÔ©ÓàÁƒ›mÿþýû÷ï¿jժѣG;99mÛ¶­mÛ¶œhùÿ`ݺuÝ»w‹‹2duE¡P0ï ¹ùg96IXüeŽì^^^ÑÑÑ¡¡¡þþþ/0¾×'&&æiZÚÏ?ÿܤÏä>}úŒ?^¡PxyyÕ¹µaÆ%K–øûû[[[S¦Õ´´4N÷é§Ÿ;vÌÖÖvàÀUíÙ³'))iÆ Ô¬Øs¡ffÏžíïï_çÿýÄÄÄDFFFFFŽ5êïÌ÷æÍ›ãÇ¿|ù2êMHHHX¾|yvvö¼yóZ¶lÝ«W¯ú‰DGGöÙgþþþÏzÒ¤IÅÅÅÇŽ£ºÜš5kþ¶Z5* €qf™0aBttt`` §çãóÈ©iªÿ'&L˜Ð²e˨¨¨èèh;;»sçÎ}ñÅ"‘ÈËË«[·nÇŽ+)))))Y¾|ù•+WV­ZõÞ{ïQ&Ó¦ÎòÎ;—:(|ÊG޹|ùrTTTý[TŽÔujò266vùòåëÖ­6l‘±�-_¾|ðàÁ³gÏNKKÛ¶m'Wþ6ìì좣£g̘áïï_gR³IÝø¯9c722òÃ? MHH>|xS¿¾ãââBCC˜››/X°`ìØ±;wî?~<óyEáââòÁ<xp„ M’ˆï¿ÿþÎ;{öìéíí­R©¨‹cÇŽ=þü‡~XYY)‘HÞyç*ä† (µ&((ÈÞÞžš0ûK`rtvv¦ê˜••õ49qëÖ­ÐÐÐÌÌÌ×^{­ñ×éééT“Þ¿?22òÏ~çÎ*•êäÉ“'OždúæÍ›CCCoß¾éáá1iÒ¤}ûö]»v À§Ÿ~z÷îÝ?Ÿo»ví(ÇãÇWVVvîÜyÀ€]»v­Ó8‘‘‘ .¤¾–<<<-ZDEÿàƒ®^½JY˜e2Y“ºF£™7oÞ¡C‡®\¹òÑG-X°€ú&«Óª ,˜<yrhhhrrò|àââòWõv«^¸paûöí:t8yòäW_}UG00oÇÝ»w+++×®]›••õ—;ÞÞÞËß|U�� �IDAT—/Ÿ9s&åzS]]=xð`¦¯RŸ~úi“> žË€NŸ>½hÑ"gggªŽ …¢ÎkÅØ-ííí÷ïߟ˜˜X\\<pà@Æ!ÐÜÜ<!!áìÙ³vvvT«rRäïývtëÖ­ŽºïààðÕW_uïÞ½oß¾ÏMŠè=jz—¾Ã—ÎØÎÇåiZKVV–Á``V±dff°¶¶.((pvv–J¥Ô\€æÍ›K¥>Òhd"R¶///…BQTTäææ–““#•JÅbqII‰»»»H$ª¬¬¤r433k|{i4šÌÌL[[[*GKKKGGÇœœJzÉår{{{�”­ÜÆÆÆÖÖ–ª£»»{“žMAAAee%³¨+//O¥R1ŽþTŽR©”š¾¢Œ¥¥¥T©¶¥ŠJÍÐPo`“²0ÅW£Ñäää8::–——Sϑɱ‘ÊxVV{-Õ2TQ£ª@ ¨¨¨ æê<G÷gZ•**õÛ‚ZÆQ§q CZZ�ªŽTQ™)¯$ªU›ô4©žÃÔÑ`002€Ýª–––©©©F£@³fÍ,,,’““™¢6vã0=§N«šL&ª‰D¢€€€Y³f………Q]Žz;(+±yóæ"‘(--éä$''G£Ñ°Ÿ#3—L ÁÇÑÔ ==Çã1+)ÓÒÒ¨yG¦U¥R©³³3SejÌaêÀd2 :tÁ‚ÌÊ*¦¯Öér%%%Ô²K±XÜøµ›‡érR©T¥R=ûíØºuëªU«¨õ|Ԁܠ]¤´†ÈÖÛÕ(+3.7V\qpp¼ üøãsæÌ‰ŠŠ’Ëåaaa ,˜2eʶ5 Åœ9sâãã›äŽÈñ2¹jÕªÛ·o?ãӡޏâs­ÆÁñ/âwÞQ«ÕgÏž0gΜÿ²¬””DÄÞ½{9Yõ¯£M›6£Fj’}žWÿ2&L˜0a®�7f㎗¡C‡6Õ3€Ûâ–ƒƒƒƒã_�'®888888qÅÁÁÁÁÁÁ‰+N\qppppp¼,<áh0N:Å5 Ç?ŽÁ`` ©Ç¿ÔjÍþýû™í888888^FíêôéXë>m–ƒƒƒƒƒã/„ ¡ Ùù¦ºâ @ppð?¾ó7�’$TÜ8t¹qÅQ•JuóæM®8^%ÄbqÇŽ¹vàø×Á‰«g¡Ñht:]×®]¹¦àxehüQ¿œ¸ú—}ŠZZZÖ9;ƒƒã_Ê©S§† Vç�rN\qpp¼\P§I±Ñétùùù\ËüÙ‘”Ïwvv¦~hµZ®Mþ$ŽŽŽuŽ¥}–¸Z¿~=sö.…———““S\\ÜäÉ“íìì¸e¨¨¨Ø¼ys—.]ºwï^ÿn~~>u°÷èÑ£=JµjÿþýÛ¶mKEdBΞ=ûþýûG >úè#�gΜ¹qã�77·Ñ£GˆŽŽf†˜Aƒùùù-[¶ÌÏÏoРA�6oÞ,“ÉÆÿŒˆLQ—-[F¥3|øp//¯«¾N§[½zuÛ¶mû÷ïÏî9TëfrðÁ(•Êèèè>}útèС~Êiii‡0yòdö9Ù`ôèÑìˆYYYèß¿BB{ü<y2€;vtïÞ½K—.LQÕ8l>ú裬¬,*G�vvv“'OŽ‹‹»rå ó8^1ª««^øÑsP°ɽvíš×&êDÇÆŠ«uëÖÙÙÙÍž=›-î.^¼5pà@N\±¾¾¾ ¶‰F£™6m€ÐÐÐõë×>|xùòå§OŸž9sæÖ­[ù|>Õž#GŽ››áææ6hР¹sçVWW÷èÑcΜ9#FŒpqqY¸p¡Á` ÙµkWVVÖòåËPΜQQQ...A 8pãÆvvv®®®u"j4šÈÈÈ¥K—Þ»wïÓO?]·nÝÑ£G>üÕW_ýôÓOgϞݳgÏ‹=VN5qâÄþýû/[¶lëÖ­ì:zzz2!,X@åÈ´[~~~TT”……Eƒâ*555**jêÔ©"‘(**ªsçÎTcòx¼:³²²¢¢¢÷ìÙÃ4�‘H”››õË/¿lذÁ××—*jXXuoDDDß¾}Ç ´´tÆŒvvvÔ㈈ˆÐh4=zô8uêTrrò+)®�PGîþüóÏÀ;ÀÀk�¸û%?8蟬+Шv­=ð�ò€Ø?‘{àPFÿÙ¸TÑ9fyÏŒN5H}g€ õäÉÌÌr;vì¨T*™ÛÎÎΟ|ò k˜}þ}¬^Ž6ÀWôïH Iš®пÞÅS@Ö“W$ÀDú÷Ï@� ?0¤^Ü@é“Wœôï¶ôFHÛ€xJ…úPc�°ý/é.~~~!!!Ô‘ë&“© Æ@[[Û!Cj«Ô³gÏŽ;2 ³RRR&NœÈãñ Ã?þؼyóWÛ„2räÈ¢¢"£Ñ>vìØ’’’AƒQÕß¼y³Ý’%K&Mšäëë;nܸììl£ÑøþûïOž<9$$$..ÎÊÊJ£Ñ¤¤¤�2dHAAÁÞ½{ ÅÌ™3ƒƒƒ—/_nkkËãñîß¿ÿÖ[o 2äóÏ?‹‹sss{øðaPPŸŸ_DDDbbâ’%KîÞ½{úôi???’$I²v'­¼¼¼””ægffÖ‰¨R© ÅÀÍÍÍ×®]›››ûþûï¿ÿþû®®®·oß>yòde€ÉdÚ·oß·ß~K’¤½½ýO?ý´gÏž7îÝ»×ÓÓóôéÓ .\±bÅš5k�9r$((($$dĈyyyû÷ï///gRûüóÏ·nÝ àæÍ›ŽŽŽ;wîlݺ5uÀàÚµk;uêäêêÊnU*bÇŽ-,,�¸¸¸0R­VÏŸ?ÕªU;vôôôœ>}úèÑ£‡ ²gÏ©TÊcHNN.((`>{Û´iÓ¦M›ââb�žžžTø¬¬¬øøøððððx¼°°°[·nM:ÕÑÑ199ùîáwïÞýñÇ‹ÀÛÀJ€�”¬û”wÆT`ýçÀFV€iOþÉ0(š§gN% ˜z 8˜�è€r`8G³½< 0€�¸úd‚aÀ 7°ø x—%r~*éˆåÀy ŽÕŽ]ø(ièÖ 0'‚ƒll$¯¿þ:;•ÊÊÊ<Hÿ%z±dɪÖDíÐßÜ„y¬»Éõ‡h¨Å¨‹m€újÜ ‘z}j4°�‚YYdPÚЗƘˆ9Ofá ¼Æ’Ž<�À%à(õjÔYÀ€©/“/“»únÃtïÞ½_¿~:ÎÊʪ Ú�¥R™˜˜H½Ï©©©NNNŒ¸êܹóˆ#¶nÝÒ¥K—¼¼¼Wøe^°`J¥ºxñâîÝ»§OŸîââæççwøðáeË–…‡‡oÙ²%%%¥¤¤dÊ”)§NºzõjNNΗ_~éëë»gÏggçÁƒ5*&&¦NÊfff£FÊÉÉY³f··wc¬äÞÞÞÓ§O¯ªªêÖ­ÛâÅ‹©ç:|øp¥RÙ¤m´ÜÜÜÔjõš5köïßøðáú§PÿñÇÓ§O_»víĉ'L˜ðÖ[oݽ{×ÙÙ9))©²²’$Ivèõú]»v­^½z×®]léË/¿üí·ß¨‘‘‘)))|>Ë–-}ûö9sf‡|||\]]wïÞ~úôé:å)//§:$I’­Zµrpp(..V©Tz½>77W.—[ZZÐjµT0�L“~öÙgÑÑÑîîîÏnÇÏ›7oçÎkÖ¬¹xñâɪc G  �ãa4øøD€kl¢Ø8�…¬+b@’� °�ô€ª^¾N@{àŠX’’�léÀ!ZVIx øø Ö™Ø¥¬1w+àì§>³s@�X�¥€�ÐhH€ØÐ‰{�›Y{ÿÉ?Ùò˜Q×”€ 4T©MÏhk9Æ;`�Ô«Õõºã±0ch ¸��Šè`ó=`�ÈmHEžCÿð ¤Ðr‹Í(Zmz�L­w7Œ®Ý5ú®ˆUßU´Hî Œ¦Õ»ôݾõDrcyη¹¹¹6lذaCaaaý»ÙÙÙxµETTTxxøâããëÜš={v\\3%8zôèaÆ•””lÚ´)((èÙ)ÇÆÆÆÅÅÅÅÅõéÓgÒ¤I) •c\\Ü’%KöìÙsæÌæVÛ¶mÓÓÓÙF‰ç²qãÆ;w®ZµêE?pà�5K?aª¨ééé‹/~ÿý÷ëGÜ·oßÒ¥K¿þúë6©‡ bnnîææöóÏ?‹Åâú¶AªCnÙ²…úŠbĉƒƒCûöí™oÛ 4eeÌÈ‚ààà .<» AAAqqq ,˜9sæ°aÃ._¾üßUÍ©€ @i >€5ën:P t¤Àï,ƒèpð:`8Ò­€=0èF Ç'sì¼T�÷��÷Xƒiíû¤�‘€o�Ž@ �@+X�б^DÆö ˜m袊€j ®£�颲¿à/³Š*J»9Ò²ãÿçhW¾¾¾›6=õA­VŽ1‚ÏÅ= ÷íÛ·hÑ¢ðððŠŠŠg‡|ï½÷Þ{ï½Ï>ûlêÔ©]»v]µjճͤ_ýµ‡‡Çرc_˜#GŽÜ¸qã³Ï>kp¸ )))y¶ÁðÝwßmÚ´iíÚµ”‹ÄÓ¨¨¨(,,œ?~‹-�Œ9ò?þøî»ïÚ´iÓ­[·:wíÚõõ×_/]ºtøðáMmçåË—çääÌ™3gêÔ©£FúöÛoëèÔ©»CõîÝ{×®]666¾¾¾”nG±ÙÁƒäÿþ÷¿víÚ=£� …bÍš5Ý»wï½÷ÄbñŒ3¶mÛø ÄÀu ¸Ô3¯Q2¾}CŸÿ”Æc�.€»À#�@>Pø�k��Í�=þdŽo7dZ;Q‚'Sþ™5ûBÖÀoõnQ® §D¬}°À9º¨$`�TÀM p 8ô4Àà VæôŸ€ Z3«ƒÜ€—@\=ŸˆˆˆeË–%&&þïÿ{…›‰r狈ˆØ½{÷‘#Gž0‚lÚtöìÙÈÈHêϵk×^¼xqûöí`íÚµéééÏWß}÷]=š$®Îœ9³{÷î9sæ<M÷ªïðö4bbblmmŸ-«�ôéÓgâĉ&LP«Õƒ êß¿¿­­mLL̈#:uêĹsçÎÈÈHÇ–UEEE3fÌ6lس«¹xñâ»wï¶nÝzéÒ¥Z­ö‡~X½zõs«0iÒ¤°°°œœœƒ6¦Ê+W®¤Ü(¤²²rݺu|>¿OŸ>ãÆ›1cÆf(H¥= èdÐÓí�œº,µƒÂx¨3@ëúmÀÈ2sëå¸(�´€ ÐÈÖë€8` v±t©XÑÇlÓúE 9Ј{f5o±lŒÀ-Ú„ÈUD�×Ë€;pV³f@0fê, °©—Q)°®A‹ÝguÈ`„5°ùÜÊŸ Ï63n¥‹aP†‡VÀdú.óÖ§ÑîðËÓ›B Èj “µÌ¦])öS›FO4oÈPǘý-X ÎÂŒ¾XÃÒ€©ÑãëɆ­^D\™››Ëd2æO ©T*‰,--y<Þ‘#G¦L™TZZJyi¿Â|ûí·ƒ ¢¾åÃÂÂfÍšµcÇŽÐÐР  ê{\"‘XZZŠÅâ &>|¸_¿~*•êÓO?íÕ«—Ñh¤nضm[¿~ý‚‚‚ª««£¢¢Ú¶m{øðáñãÇ•••9rÄÛÛ{õêÕ«V­:xð ^¯ß»w¯T*MLLœ5kŸÏïÝ»÷ܹsFcjjjŸ>}4MxxøÛo¿ ÀÒÒR*•h×®½½½L&1bÄs#nÙ²…rÇ ªùã?ÖÙã¸sç΋-ZµjÕæÍ›M&åRàçŸ3f ã’.‘H8ðᇶnݺ]»v·nÝbÒܲe‹……ŵk×(ÁffVÛk©õ×$I¶mÛ6**jãÆß|óÍðáÃGŒ«P(8PgÕ…¥¥åÅ‹©”Åb1eõõõmÞ¼¹J¥b&Éd2Yzz:S€={öðx<KKK‘HDYk™Ç€ öŸÎÎΛ6mŠŒŒ¤¦�Û·oÏv»ÿo`�ò� @ ØJ 8�(�@hXÙ9À˜€ÀLŽ¥@=©.ªh<6Y´ÿB ”@6ðˆönøÐ=~° �==ÕÏÖÕŠ€JzÈÛ]χ‚ 8\ªìeɳ,:îQúG!…¸ôZ�ýŸâ]B¡y¶k¥yºZÁæ�ãŽë×P+1ܯ{W�HE´h˜‡ê:Æse­ð#€û@ØÓŒ'¾´Ü –¬ß-ÑS‚¬ZX2›ò3¤¦E™Vk¿ZS¯,+?ÚØÛP½GMïÒwØ£âRW~qè˜ÁÜ·uLC<èÕ«·«Å?ÅÉ“'CBB¶nÝ:bĈ°!!!çÏŸ¦i?>räHö®T'¿páÂ’%K�08@9 f�i´CÝdà€Ò›·³\æ�L¬€@¤½À�@üLv<¯h}€4  xX�Ä´Ææ d¯¾Àe ëIa6¸ øšØ$<Àpt@x�Í€?èdw°²8tv³ã¯]»ÖÆÆ†Ýª‡îСC›6mW€æÀE–Žø qõqí]/z0˜Þ Y.�ÎÇ»“ë™pw×ê6Gžžj„/nýúôÛÆ(òm=qu ØJëjè‹cY5-®–п¿¤]ù‡o�2€(Æüѽ»gT”………›››ÉdzXP±þÐåeefÂenW ŽÇèõúÝ»Ÿxœœžk*ü8wî\ïÞ½årù?’û7²³³ÿ]@D^�(TÀ2`(Ð8EÜû@ 0¸ˆlà&½‡"ðŽÓÖ—UötÄÇFnZƒ¹8F  è€[@ÐÈŠ�o 3P xÐÆ=  –÷ù�h5‹A¸÷YÖ*G …V^Î�>@ ð3¤Ñ!�üèˆ;�ÛF{µÉX¾pzòÍk´{ˆm»`XÑf´»ô@O¿€ïòjMƒãBÊÙÅáSpøM�@R½,kˠСÛ%úbÀ�p¸ �«Ëa‹ßZ>½Kô`‰v¦œRÚT¨¦ŒíËJìE›ñγt>ÐRŠºÈþî¹(i§Ä¦9þƒÔYI^aùßL«V­˜¿ÿ&“iÒ¤Ià?Ó ˜Áúmà`˜¶ô°B­¡y›^JÕFÒZcªƒ3` Ü¡“§ÃðÞÀi àKvLô€-@™|(»b&IÄ“97XCjü{z|´ºÐâ ¬EB± -g&� ÈJž[ñLÚ8–a°¾¸ê |�¨a åAte×Î̹ÛâSÚÅc$ðe�콊ƒQÀpnHPQxÑÒ¢ `ÄÕ4€r ]_+®"5øàxwû´I£qõ®¸�ͨ”ÖT¬åYl‘<šHóëݽC÷6bN\½8)))IIIÿ‘Ê2ûž±Íq/C‘®\¹ò—áoŠ?{Õöó$U@,@²|³€,às`иÈY† m½‘¨œµR8‰åo¤u—l ½³OŽûN@Ø]�s ˆ €~´ùQ„‹ŸR—w€£€œ X;eèh¹U_mšìL€ K„3s¬¡5d)ûßäæaùT�ˆvÃåæt[=l |ŸûhVè.MË¥L†LlŠÁø÷pÑóe¸z¾}ÌÕÕ•;d™ã•á)»¯ŠiÀ¬=xŽ�zw Ð �(€e€øò€n@�°•^“<¢çx(Ç%Ë TŒ 3»cÅ€½ðk4p¨ÀÈHàW€ §ë ßik›XI[Ê.Ò7�üœ�JÞô(¯Ô€Ðzà ¡=Öl€aÀV@ü�HÒ�`ΚX:ð‰u汚‚Š6šÕ{5f0Æ c€|ohA)¡CR7§m†D­Q¦ Û‡KäÀЙ¸îðh¯í“_jzð·ªMí`�| ñ˼A\o À„ úy Y+ðÔ¬‚¾+¥“udeAYe$ Uܜրլ’0~ƒœ¸zq=zôûï¿síÀñÊ ‘Hºt©ÿ�ü ¸±Ä5”È�sz`m8?é’§¡5!J5‘³À7ô¬è©x6E¬M1ê8×U[�À�h�pè¤ɀǓZŽñÉX�x"À È¢G̃´ ‹¦‹:¸�¤¯éÀ# PE[äÜ�Ð èìªYæÁ!¬éªqvÿ‰ç°ŸÞwƒí†�ô;߇x(DÊ%5ƒ5ut“žv²† á"@/�Ơ˺ ãk÷—º"v ÞŽÀ•î´ëÛ€y“^@æ,{,_¾8ñЮ�€Ÿ°¶Oî£ãþJËË…´‹ÿë´Ç!¾àz½ÙÌ(Î/À �@sÖÎsâêÅqqqéÛ·oýc88þ¤§§{{{WW×_í{ Xûäf<@8Òâʸ¼ $°¦ÓÙX7€€ K\5‰®À%ÀÑòÆȤÅa[@ $�í@ à ð€l@¼TÛ€y@ËöØ•%f(à¤ÓòIXÇ軃€ïéÝoë´Rt½ÆùKO �¿T8TâvKì~rIõ³08i ¾ôx§¤/A“Áw`a‹Ó­›P€/ñÔ-ãö“1c8cà¿ØÈ9²s¼ܼyÓÃÃãé÷}ÒZeŠXóL¿r  ÐCZ‚*�îÍŸôHa­¹™�ü�€P/%m£64üh§A�§èó`0p�Ð�]�ºÝDPEO¹éhñV (90p�Ž•@>D;[+Ÿ\nL) é íÅÇ.ªêÙû´6™A X»Û&ãSj·š”ÆD2µ¿£Ÿ¹—¸çÇÿæcV<¾õìªñÞM„\Á²i¸×X—ZÞŠÓö&ï~þºN\qppüsŒN³vU¸ÇþònÓˇ©--®6”B>@�¥¬Q€j` °Š0ˆJiÑÂ&Þ®âmõz%®T@*ìhÀhœjÒq($@.  5³,zç'pÓ>î"–oˆ Ê’X[€ò§,~bWùÞó³ø™2Ù=…×7À¹ G¾Â‰·0rî«h¾S´éòé œs¹éÇU†ó½‰­C å¦öøžº\:X Õ[KKÖ}_nð»Øµ)«½›‚JÄ�°Ä9ÆÐAG·†N¯Äö!‹ÁØ›�³ŒžáëV[xzæìyX èßö uæ•ïéÝ{àY[Ü †øøø¹ºº>xð�Àš5kîßgV0`Μ9}úôiä Ñ£G=zü_e£Ñxøða‡%K–ÔÔÔÔo¥R™––6nÜ8‡#~ÿý÷yyy­Zµ jÕªÕêÕ«9¥ãeâ -«€7�!0¾u’uS7 5P@oÒcL怪€B@ ̤@Àl£e€¹À/€¨�²ÖBþhŸ=W€lªÍÑ*Œ˜Þa Nc�¿r<,A@0 £ËFù ,�ä@' Ÿ¶j€RÀœžwyÀªiP´Z×ÛZi(à �Lé:6ˆî™ó7�Ìá`F|7|17Û FT•@MïñÑ®e¸³gºcÊRS™¹ z3øPÿ$°ÃL 3~‰€ÖÄÎ9u—D9•2J*˜%rL0˜”BÓ·ïšZ Àˆú‹rèRI�WÀ•~¦Ñ‹\éõ„hèd³Ÿgìjñ,quèС |þùç/^ 6lصk׌F£V«5™LÔF«�FŒññÇÈÎÎ>räÈ‘#Gbck;Ü;w¨+×®]pãÆ²²²²²²Æoj÷ò V«?úè£þýû<xðúõëJ¥òĉTãøúúŽ3&%%%22òÎ;u<¯~ýõ×mÛ¶iµZƒÁÝ»wï‹/†‡‡S[äqc$ÇK3A{¨ìX~F–íëz+õ‘Ú8,\€¡tozê¥=HÇÕí9г^޶ôG÷Û7SŸ¼½ pþÀëw±*Œ ½<+x p6·h'uÊPiM—ÍpRh玖@3€¤Sh ¤à«¦~¬:R;FÊGÀØäÒž&»ŠÆO/5€Wb¶aS4‚>ÇQ0ðš7 ¿­ÆÁöø`Âs"�- jræE—Œ8¯v/hÜ·9‰%$¦/ÙÖ³ŒŸ}öYË–-©SV-Z´yóæ5kÖtìØÀöíÛM&Ó•+WV¬Xñí·ßž?þúõësçÎÕjµ;vܾ}VPË[�� �IDATûâÅ‹½¼¼>ùä“¶mÛÊd²ß~ûmåÊ•ååå@^^^ƒGǾÌlÛ¶ÍÓÓs×®]óæÍÛ¿ÇŽwíÚàäÉ“ùùùS§Nmß¾ý®]»ÂÂÂê쵺xñâµk×öíÛ—ÒDdee9sæ­·Þâüã9^V.6"Ì€3  ×í–³ÖZYÐÃúy ˜vz> œzç�g �¸FoÇ÷ Î<±×ê< ÑÇúð!ã=—¼ .À(ÔÎÙ@1P h€BzËTÀ8˜Þ´ëðÄÀE à=¹4xðe=…O È@¸ÒÕ¬©·oaòè�$ÀœCýd9ø@".�[ƒ¡9Ê: %›¶þ¥ÒW䬓órtÎÀwëqÞá!,‡¨BýP ¬Z�júP.¢Bj\ñÆýï6ÚL´’Lï!ʥΊ|½B�†'ö²Ê¤µì„U§Á«ÁnƳ?mæ-¬WwK+R±l€¶´®™õô†b×q'àÅÚ-·ÑâêxxxôìÙsûöíÌi@ùùù'Ož¤Î)ß¾}û¾}ûÞzë­;wî¬X±¢eË–vvvÝ»wÿæ›o� <ø_÷únÛ¶9~ß¾}_~ù¥T*=}úô¼yóž¶!ýš5kfÎ|ÂbPYYù¿ÿýÏÌÌ,**ŠW/+A@æó†§†lFCR� :â9�@@OoèÐh¦oÕ�y¬u<€`À(Þx<.­ÂœSµk‚s�XÀ= HFÙ@ йôòa€ þ@PF{o÷œý€-´’É@"-¡ÙGÝÿ8ýic&%c½)·§‰«<Zà1Se×°,g4Jê]x^"V´ù@>Úäaðu, Æï¾Ðò€‡¨u7‡ïÓ!«ºVP•Ñ*–±0Cˆð±¥þ¹Ò¹ÍgFa)„ÅÒ¶8F¨¸`· öXõx»°#ˆn=Š­,·u ë.ƒ%½­FÍ3Å»ŽíÿbqÕ³gϯ¯]»vÏž=UUUì°¤Ré¿Q>±Ñëõ�’““ƒ‚‚Š‹‹ ‚Ðëõ—/_Žˆˆ˜2eÊ´iÓx¼Tòï¾ûÎÎÎnàÀ � ƒN§>|¸P(\¿~=#ü88^>:®¾Î ÷Í€®€ø�XGË&b À8I/~´�Z÷{ ë“ç—�¾@ð. ::à.i°ê!¨a¹bph€?�¸ ´¤Wþj«€0`&°0�kbÀ˜�8ÜÔ@6ÐðŽ�,ý†íCqX d½<à! ¬�P d�´ñ°FÌù!·0‰uÖG“p¨Ä¼“øp4ŠÚˆœ0U<¯w.Ä–Öhpë´4{¤ÙËãûe]'ŽoÍŸ¾Ï]ž³¿xF´Ïi‚‘x©>>>ÕÕÕùùùNNN©©©|>Ÿ9ô/%%¥ÁCÁgΜ9uêÔ¤¤$‰Dœ\®Õjïß¿ïàààèX»ì¹¼¼\«ÕÚÛÿkNáœ8qbqq1³!÷!CZ¶l `êÔ©³fÍzZ,¡Pøý÷ßÿý÷*•Š’^K—.•H$)))ÜpÈñrSß5αÞi-�轚D€Œþ¢odÐ[Kt€8 �X¤[¤°ÒC£}|úÑ7�€wÿ°Œ&LDF4vèÐ8` lìDz¯tʬW ¨�{@d¶@P|Nëˆå@ v�å@%à L¤·Í¥¶o¯sFŒÑ^'étA{úQQì`GRü<AÕî.º]@¦%Ú ¦fþ´ë€ÖôXF6«ç‰@oá]$ûæ1|� ø:�ø°£v®x¶<ð2?ϾúÝcDL?h…|8‰àÀ™ŠÞ™Â˜eg;ä›ÜóÿÇÞy‡Eqooü³…Þ»²‚¥©ˆXÀ.¶hb¯X¢£ÑX»Æ˜{í±¥Ù±—õ[£±ŠTŠ ½·…m¿?†ÁµES~¹Þ„÷ááÙ>ß™3çœ÷¼ç]ÖÁÇ“É5“ 4E%Ê>EÏ×À–ö¨Î0þ‚)®”c·71î'Ô kŸ,`,èsÊRňb¥€E¹ÞºÚßi®vîÜ9lذñãÇ÷íÛwÉ’%ƒ Z°`ÁòåË={ö( ///¡¼]```ddä®]»>ùä“>øÀ××·V­Z'Nœ¸xñâš5kæÏŸÿÎ;ïtîÜy×®][¶l©[·î› õý»k×.ÀÌ̬{÷îÏÌ ®^½2~üø£GFEE «�!!!vvvUÆ*¼Á°=˜wa9”A=(†GzÏñp Œ¡®Hvo*–(5oØ¡—r†)`ïHP!QÙ$-4…hH…±`%eÜÒ<Uûã 7 Ž^RGÎby¯?Âzhi–pWOÊr-‡á”Cçâ DeôFÐÊÅãߦ·Óh0'x�þp’à4bÒè¥è]N·Q—A0M J1‘cèH(⢽'>ßõP'ƒæh”ä;|Žæ@öiX�V4ô¢m~ËJ÷ÔXÏ£¬¦eOËlë‘é`£=}�-²ò¤w<%WÒ9ªMÉ¢ïh&†¶„tKÃ-íkâOŘªžåße³³„çqžÕmPKÅpkÏŠØf…j‰JŒ^‰öO*ëž 2§¼hÝßh®,,,¾øâ‹ýû÷gff¾ûî»ï¿ÿ>ЪU«Ï>ûlРA;vìX¼xq§N„–îîîË—/?uêTffæÔ©S…Çô’%Knݺ¥Óé-ZÔ­[7`Μ9ÖÖÖuëÖíÔ©ÓÿÐ-;hРV­ZU~>|x‡„Ï™™™€@!úöíÛ AƒgVwuuýì³Ïš7oîääÔ¡Ca@¥RU=«ð&abùŽžU°�C8mᘈ¶'D,+>):d™Pdzå´æp Œ P¬(r-òbÄwj¹H47%ü¢åÚ“äЭêäÚ‰„0ƒzpÚŠ¶ªDÂ1�~†Ép†ÀqQI=K¸-Êa|&ˆ&1d!6úŠOðÂÓÂw2±¯P&œ ©¯6WŸàûîïù5 ÕÌ?€o erƤàY ¾b¯„øw7çt»`s¤KÛ²~+ÝnÈ6QÏ\ŠmŽàfV_÷¶a\ 0ÑÖLÔõûAG|"Âç©—†½–åþ¯8’MA\\Ȧ ÔFoh0PxÎŽ?^J@@€@|f:àííííý”}»víÚµk÷ÌbϯøæC°µ•èÙó¥Õ:uzÞW«VM8ëç-Yªð&!ú¹)9b£÷d¨ `" ,zZ1JV\™äÍŒ=4Í•ð?M 'F€ÒÁÚÃwÐF'V¨îßOttÝyó|àæêÕŒsº‚ÜÕ±ÍÐÏÍ…-pn‚4X6ˆµç¥¡Êá'¸mE¹©ÊÆöñPJhW`;ä‹!¬$xma¶‰*VìaR¿ßüklØB“&õçN5’lŸ»”ÁckëCÖá-Ïû¦GÐ}¾k¡-)F¢3èrЊüj¤gõŠÈoMKœN‘(ý)„c¾Oš…×T{6dØÙ-{ÕYôgÅÞòæš«WbíÚµQQQ‡ªºÑ«P…ÿ}ü:áí>@*Aè³a+YvÆOGú‹ õÞÐÄÓÖ œ›t\C8 2xòJ×¾=jõE³ÒÒÁÁ_@ü(¦|î‹O°LÑÛ“A!D‚®€DC´x0É`�ZÑÌÂÛ …Ð ¶À= ‰–P& &<½Gĉ¯ :faÚ”¸#rh€­˜·Ã€Þl�É2ÍŠÕ¬Êç‘/s#‘Kä,ŠuS¿0èÞ¶çÄò\§Œìú:³Ò?Ž‘4{à½ÃÏ"ÎL’l]mÕ”Ãû>6ú±™Å’þf×kéd ¡¤ ûÓ—î©Hm f}{@ûö˜ì=›ruF¬©Q=_‰+ÖÉ]lÃú¯Ä’»âÁÿt†¶¢íÿú¯0W£G=zôßû.**ÊÎήz’Uáo€WÅŸ¾¨ó¯5hÅWrC0†æ°[̱ۭ˜À°„›òÜv*FûÀ2…«Á6Á ÈX!úÁºÄD¶n-›=ûȬYRÑ& ŲÀ lÀ@dÚ¹B-0€·`&äÀi0‚É0, Ü‚û` ½ 1\™°¬AÀáü j@°}ZZœ å74»*1aÆ V-dÔP‹†¼ò‡‚—4“`ªsÈd|[s¹&Ì5®p›ERï#vû/é\sÆ" ‹²éißÎ.nsÕﻆoïü´ðLA¶ù ßé ÝnEœé´©«ñyž¹YŒG)ïO‰*˜CÎsð.À¤‘Ú_i¿ý©–•a(Ÿ ÷=9�ЊüÏ?EÛ×X<ñ×íÁV¥øjTr«P…ÿi¸¹¹I¥/Ô²q‡6°,¡ºèXA0'¨ç @,ü’FfÐ,Á\¤{9@ðГàèé‚©ó…"ø¦C*d‚;ì–ð‹„µ¬€D¸õôSñññøûS§Nåpê€Èôº,‰ '94ƒrˆ«¢SÙÕÞJD¹ÛÙ0 Cä€$Bu8GÀj‰æJ_ƒ꿨î‹nOº~wžæ_mŽ6l³öü§ µƒ¯àw‡z¸¯ Õ÷/¨«j¦¤¯ÚZÜþ‚åî.o¯Pi<£÷…OkÔ¶ûÚúýøÎã¿Oq¤ ùM—/úXnôDôjk3¶ö�XþŽdÜ¿X5 ,üà¥wºÀ¯Gi•¹zÕe–žnddô9Y™LXõ£ÿS,¼õt:J`5ë·Ù•€ä‹Ñ0Dë±À˜ ¿<ýþ#Þ%ÀÌ`ă%4K¨'2˜à*ô®XÏùß1cfw÷?dó1¾Yn¢Ì °ä;OŸ‚+h ÞáÆcÖl{[ƒ«žTG\¢‚Þ ¶¨ŽáÀ-½Žò)à ·ÄѸ =ôògÏà ú‹¬÷rÖpŸ¶mnL0¢ Á\B6 ¡$]\GM ³÷èŽ8sÒ¢0‚`©NdÙøL •—@BOÙ‘&’è,;>ú&£¨KÔˆ]´›‰M…ô0×i`8?8æÃ3Q߬÷ÚëÝô‹å&Îg‡»BQîà#JÛTù¤¥”‚¢B‡âß>ºÑÇuQ^Ò±_h6Ñ©e,}Òô"Ötaå%޶†ñ$ãW¯µ{Ï©ÝëûR×E_­°Ê\ý9°´´ôôôü‡œ¬D"©¤8Vá†xˆ�7QbUÀUñCM(„È…Ë ï·ÎÐ_ìµJ@!†æ ÅlÍM:ÌäØ1âãÅàaOè¦c¤ ¦xÀN%$íÜ:æÑ4ŒÜÉgçh&úvßC?Øí 1|ýTt®zufÍI0†;`½@õUЋ„<°†Nó¢ì]64€2q4LÅÒ¨í^2žÖ,š+5l¦ZPnJõÊÀ  BYi®´ßÍÅ?‰És+öµêÛðþ;<PðØIA”* ™äjYx«}¤1ä{ÍÇAyô¡¨”‚K‰Ê4`]#åìˆK64è×¾æ5çäÕ€¢:©yÕäY)¹ Ÿñ^Å^sÐm¨¡ÿäxýÖpxKÚ¼¨Žª1܇Ö/Rµx!’!ùW/¹ø*ïêÏ„‰‰‰Ý?á!ѦM­V[õ£ÿSaÉà Ê`„H 8-¦ŽŠÅ"¤Ã�Ä‚Te?Ca7¤€´߬ÕâÆ‹�"#¹y1V‡‡–Ph àDÀ>¨žߥ=tä¶Ë#~rÓ-ù¹!DÃÏ`¥pjÁX+àc1ÿ÷ù L@ –P s +,„BX¦¢yÓÀ'PÇ! ´à `´`µ”‚VOö¢$WxrÂ{±’5ÛhK½Ï�¬àsø™SølÀ#׆Ö?p¡)¡{Y7 ãõu0,4ê:§Ù9máªãÇÆ·é)0$ÌãªÄ55èµKüKyL€lñGÒ3­$É.’L{ù‚©êSt{Òí[vEÇŠv”=m 4Rа*ýÕõUÁÀÿ6t:ÝßþU*Õ?á4«ðr´…ñx0DÁz¨ bdOHÞíb®¨3l/°†ú ÅOS-ƒ³ž(jm¸¯á6Úê(#°v*_ºCޞϴYÀ8ס;ìyäÃà!¬`<L„P²`5¬„Ó� ¦ÂUö@To¸ ð!œ‡ýO‡°æU¸ƒ’w*hP Wï<T´v¯„ ZB*hJ‘ë*"`B jd8²ä{¼R êMá}ªc2ÆÈxCSn£¡nQ…²¾1fÒÒDGÆ/ÍNfÈ ¶|)v·Óô }×¢d#U`R l<»z Yòáÿ èÞÐâr}ÀŽlÓ|7Pþ©hÚ×Úuß–/˜Å¹Ú(‘Ž™®]7N÷íH†Ï`Í|а<DRn&»„h“$ìjÂÔã̪<5+¨ñ"·I(-°£Â•,×k8Y[än¤ëõíücæjÿþýÙÙÙBµ/°gÏžÒÒÒaÆé/{ìØ±îÝ»»»»WÝë ²³³·o¯ˆö>ÜÒÒ²jLªðWA¿E¸À t d ïê-`p’AFðxƒ-Ÿ=k 6z‚j°LÞîqÊ='ÿ+1¶V†ÂP€\¨ö ƒkò³#ùJºäf'0KÈ…b¸(ÈßÂh×!¬ž~zþÕ!¬À @%°ÿɹú´ ó \Ò‹‘`ס ¸òDJê…0‚-° J21³bŠŠR0«ïÃ3áÃIØ„} ŸãtkTK"Ìo‹ç2©ÉªR×ÌÃHoBh"â`ˆ*ÙÕr+è‹]n«è´uŽÑùSle|±ý‹Ú£?¶>å߀ëÆ(…˜aÒâP‡¦.X’omÎ~�ãÞfî&ÎÖeÂ�¾Ø‰N"Y<Ü@ x–½ c£§Ø3LËEI߆Ѐ,˜©7¤‚rÇ8ò›.Зö»Ú¼yó’%O¤´Ö¯_¿bÅŠg–‰‰‰™;w®Ð¶±  Æ÷ã?:::îÛ·ïWÔ«P…¿epÊEï*AœÞlàmñ1]åpÊ!BÀH/“T,6T¬tË" øäåMVkºƒƒ”R`¬„ÎPBÁ”Lï•q¬˜¥ÜÔÂ)¨ Ýà„€dÐFÀ@È€+pr`ªh=Ä7}t€÷À Š¡.¨ Cà(‡&¢B®>"  (á~J ¨`(ÔnÖoÄš¹4Hfì`¢k�lw&)0eÔXþÓ„ñ¬¸Žák‡í§üÛÌ~_ë_­Ìoý|8¶KFP?•î×Ê嬡QJF eò ¦{jéH7Êä4{ø_¹_j®ã4iÒ$`éÒ¥·oßÞ¼yóùóç[‹Ð_xÀ€cÆŒ¾üòËÖ­[çææFFFV.YÕ3÷õqìØ177·¸¸¸=z´j@ªð †ø:|¶C[ˆ"8 ΰú‚ ÔƒpNC(܆@h7E%‹Jœ‡3qútzAÑgÐ[Ç÷º Føm`œ§h§SáÄq¨Š`3ì%\Oˆ€8 ×`6øŠ\µ�p{¸ŽÐ à dÃMp„a0[lä˜ pþ9‰Õ8¨  Dç²#”Àøî<qp~¾›DÐ9úŒ&ªFE¨²> |q¹öÛ38Ñ€A?³äö¿%™.UÖ˜?Äöpó{[û>giòLÙÐ’ÀZÇd™³¾%îoJ¿ÑÚY[4ë9*É6¨¥¸gýW.Ä—=<<€‡ÉÉÉ%%%æææcÆŒ =zt«V­ZµjUÙÉéîÝ»B;ŒÇ߸q#--­cÇŽ#GŽœ?~ç΃ƒƒÜ*¼ …¢°°0..®¨¨¨j4ªð—ÆB$À%ÇÀNTä»Ã@#R¤Á9°BÈY°ƒíð–A!˜€Tàýà>dÁuþSa5,¦ Ž`&Áe)ñôÞ„À Ø/jg\}µ4pøªA6Ü·¢™%5R¸¥e%4…sЬ!îB$\‡Q } AØAì\±¡pe¢F"rO‚t [e¯îÁ6‘¨Râ*“„^Æ2LdÕ4jk¥ÜûXyasì`øØà¹5boej’ðë KWï;Û0sØe6~¬¿%ÍL�$5¡Û³¾G«¨ŠœPi*…±€M^nDŸîlÑεÒnßµxBß ×Ûgi•„ ÁÊ(wsÃÔ_|$Õ¸Kϵ õ ͺY¬nC×ñê½+Õ†y¬Ei{€E!lÕ3–›žð#ŒyîÜÝïû—Ø®³»8>ñωâÿFï hÛ¶måçV­ZÕ¨Qcÿþý®®®‡.,,Ôh^šcÔét&!!áðáÃyyyB³¨*¼~üñG“ùóçÇÅÅUFþr”È„K�¬†x8*†Èt H`4˜@MÐ@€F«|&€'”@78  'Ô°/Àiøš@+¸ï@=‚šÁ»ð…„ï]øù 塔밠 ¼ÁIÁ8è -`-´…¥à ä“öˆµZæAWønÀ\8 A` Ã!4¢­A2ÀaøYT*-8ƒ”ÃvP€‹Øp�Û—=A2$94 ­ 6êê<ÐLúRþñ" -@Ãh NÚ~€ZXåIs©\÷¼­ßžŽ~<0’ÍÛ Ã/´‘HHÅ?YÅŸTŠT‚T‚L‚ä C.QËuÚù_°©I“£ÆÆé»G¢•ÉÇ­Ôö= mw¤h¤ŒÆðóH-¹„°LÜ€\ ´2.ûÓ4ä é6ú¿ÎØÒêUsËÄ¿? þýï'&&.Z´(::zΜ9¥¥¥³fÍZ·nÝÝ»w_‡Ø““s÷îݾ}û qÂ*¼\]]7oÞ¼yóæFUFþr´yÉ×O;‘à/*©#Ö“¾­'÷W ?A"ä@| «! îƒ)ô…ÑÛ w .¤Â%PAü”°CGJ£€eÒ§O5'Ç1àa ƒ‡2>‚ãò! &ÂÏ0Zd– H€µ`+õŽü¨DÁ‡Ð±ºVÄFÑ•¬t�K‘ÌfV` ‚t€=4Óß<ÌY >+ÛÕWWÀ !ì•N¹®Å»V]ˆéú¨ùwu¾Úöç¹O÷½Ñ!#¦ý *|å/Ôµ<¯}ûÇŠïÓzÓ6” ó»…I¢Zÿª‘LÜøKKË.Z´häÈ‘µjÕÊÏÏÿá‡&Ož<mÚ´ÿüç?Ï/qüøM”€€€iӦ͛7¯ªáëcèС͚5;vlÕPTá¿ô§¿@w8¹O«TDB©¨' dA?¨ù´ {dÁ-ð„¾°Kœþ¹¨+|�{!êÉÓ2Kǘ' v"ŽöêutîÜÀÔ øjÀ;:4:†H¸,ÅPË]è% †pȀʶÙ †~°ÁšÁq0sÈ‚Þ`ô"nCˆ„¨-v¯ ¥bVL@DA’ÐÂêiØ‚Blh©ˆªU->:¤[룾±À©˜±5Y×™[<ã¨iËol]‘ß&ÉiSW‡é=%]?¤�@kgØNp%½¾Æî$Fƒ$,o�•1«Âûιéyß°ñ:å²QÛÓËÜ,ÏùÉÐxP‘к ª¯úr°.l»Lãnp¸5Åè¾±Pú„ËõRʾÈ¢Xt`ÒÛ¬˜Á¤êzþôÈ]NkĪD?ñ4“ŹÅ‚¹222jÑ¢…¡¡a£FlllÌÍÍW®\¹páÂcÇŽ-X° 44tÞ¼y†††R©t÷îÝ;v<~üxPPPJJŠÝš5k>ù䓳gÏ&''W¶®Â+:vìØíÛ·§¦¦îÞ½»j@ªð×âÎÓ_£Å¨$½À‘´zK á@¨¸ØPp„eâ’Âð7¸ƒ ŒƒÐP‹L‡šÐ4èîúÖ×_Q«e 10h�s`˜Âb-íàœŽÚ:6!ìêë(†b8 A Iö10.ƒ,€xNp¶ÃR1”«¡ H Ba—Øjr�\è*¸ñPúòG­1X‰æ\6ìú£ë’êRâF>˜Jâ Ú´Þ<2µ (Æþ‡VîSßÏͶÒhd†O'Ý»J»Ô¬|rW•Ì ™@VB»´È\Ri¹ºù½r9e†”ר¨à mŽëû#5•â h3²6m¹ÐJ"µ gg ôuÏ7Í ÑÔ™;I/šû{ÍвeËôôŠ.ƒaÆU–^=zôHÉÄÄDá×_~ ôïß¿ÿþUwÿoEÇŽïß¿_5Ux3P©À­çàgô¦œ?,­x³”PêÂOp2 ZAgØ÷ †B C[Ø¡ã{H„wÄv½ƒ ø¸\·oïÞ>ÙY¶‰ñ5¦Oû¶ÿ�‰œ$)®*ì%¸Xð%GÕœ“°FF¾„PSÚä°Œ` Ô†ePK "ÁV‰tK‘jÿ6t­lmè ? XC„Èt—ëy‡ñ B0ƒ‰p,~Û –˜`ªG–ŸË–M EŠõ3 d[Õ4çáç«“7°�� �IDATglw›7üOü]ó¬‰}¡ðJk›ãÏi„š•0t v�°€‘ àgÈ=°!‹ŸP{¾ž¹úo«P…*TA„/@$ÄA]H~®ƒ†8B�\cˆë´®‰T±Kp¡`?\‡épMlãÛPF c|‹¹uµ”§¥4™2yðŒ™_hy<hÀ×°Ó’¤´ÌdqJ+’U´ó…!¦†ÜÊÀ° 9]« œC*œ­·ÀZdO4„Rp€/Dm à(¸@”Bh ’à- @ Î ‡ÛP óÁ ÂàùC%brNxÌö„xPKqeÌ2ÝŽÑtèTAH(2F-cìfõ°Ã\Ž °BfŒÒoø¤Èð©M†Ž»¹ú›$´ü¸F­‘Ò´Ri@ži¥ì^]=ÇNH§é*48$E˜yTÌtM)R–mìCFj«úÇÝ Mü!s5r#Ɉ­Ò{v¾­A‰q™nö ‰Q=é’&Ú·ŽêJ²X㌥-;p³#¸èE/5Ï•+ðIÀë(«ÌUªP…ßÿþÚJÏaÒ‡ t£7FKKB ¶Ú ­#)A4xA DCPƒ‰ŒYÂá<<„ÐÎB(Cp…öPnK˜*å\’¢°BU@]-Z-ej˰³Â 2å¤K‘¨ÐQ]‰©)Ž&$§Q †ìu\†87Ã9Øüô‰”‰>c½öZçE÷0�k1…/9­ ÁQ,𺠱/Ê]剔CX&¨ZÈh -RiNuоsB'ì9Óœ÷†z‘FQ-Í0Ì(6¥P[®©qÀßÀ)¥Ù¸Á¿¬ýn‘¤ôßS £©_€¹ÓJ©Ù:â‡�pL“@šGZˆ­¨Fßàøâáeã 8}’{@öGèZasfÍ—tùIÞ,BM‘†b>[ éqB>úk)­UsZëvõ¢U<—q¿ç‚-TVq©Ÿä_Á*ïêÿqqqÿ厪”U�-(¡¨ !¬wߊBì*«XÓuø€<Ôk _·¡ ŸàœcQ'I@ h; |wÀšÀ95×J „&:òT˜høÅS+TÎdÔ#VI#Ô,²ù®=ʱÏ%MƒaH U󋎸^°Þ‚ÐBaŠšjÁ>1¸×RD¡ p¸)+ÅÂCE™y}IÚë³^ 4•\ ÔvŸûÄP>p`ks&„“ëE“¢c©JfwÚ/%ìHШá­Þpx™T«úlºÁïÞóJî–?uín>±¥•Púo͇ßtÑ3'ïü$´Zzµ•fâ—Úz÷›Oø�®{1eY¶ÿ•—©*ü4B¡¨^½ú?ád ÊËËÿЇ¢Vûª¶¶+H¥Rƒ7þ0¡ .èĘÞ(ø·(—÷¬«‚T Õ‘‡DÒ ' ƒƒpIìjx[h3¡å¬¾s#A.£—š:°‚ KJ fjøXìíˆS,xXHJ^eûS„]òr«0H§XB4lDÆM.ki"!Yƒ ¶Ë™¤&b¡ìC°Y!¡L4½k@߉á;@ „@X'ÁHØ&ÈÕú«CžÇ±Ö”ê ä¨dhM0ÒR&¯Ü=´çÓî1çt_.Ï7Ó"Õ l£jª"kÜy¦ÞÆà=ííz^}¤“ð/5rÁ\Jµ¨ÄÖ T/Y©;%ÌU©Ð®&n·¶P·½+ƒU^Ÿ†¥å3—1öÃNû$W@¦E|3†w>ç®;ÆÅ:ÿhƒÐµª5ŽÙÈŠIµ¥§$O+l P¾žòo•¹ú³ñøñc}vþß2™¬]»vÁŽ£¢¢,,,þ!keeõ¿Ð÷² œ‚|0� ä >zP9P|ÀN€-BmÀUèðLa8dÁ1qÅÚPè¯c£X=aÔÕò½‘°QÇ)Ö&”Wuò³qáæÌccªò³9ˆ¦L»‘×ïSPZñDB$¸Âl\b+ˆgÙbšMè8å Jp?8¹0\/Š5r`-XÀ0KÄ®Ác(zU§—¡”Æ~€ñ¨¾ß Aœ­G£i yȆà'Kåš=p¾qnœ¿ï·YØ—` T/OõOÊJñÉõ¶–NyÏâÞêSËw1{6–%P'•¾"±>¤ÒuÙö]PEÙWÄ.ãη4ïlCÝ,xR³`B©¢÷Ê„¡›<{þûÞ•D%÷©–ÏÄ]|q»Ç´Ô+Ý€¦g4‹<ñ^ÀMÄ^ebœsÅsç[)q[e®þZÔ¨Q#$$äW$<þ6HNNvuu---ýkvçããÓ¨Q£B{­øøø:uê¾ñGZÙDÃäm 5äÃ.h®p² ághrˆBp/¸ 1w!Z€| Àf GAûAVðXÊdÛ¥–àoÀ3ÔΠšIž$_#À…”êÝÀ݃<cæXS…ƒ+wãI7§Ž Cx g`€”:°‡hõá1ƒ%dƒ œg8u 빌‹ðU°]a5´‚ÆàgàwÉŸ@Kø¾×›xÝ• hœ HÒu¡î»ÓÓ—mÈíxÅð§6•}»ÝIIjœeî×¥ßðð »–x¨“°`=¯é°Ã…åÜYIÀ[¸</G¨¶+PÖL­=f²åyxˆSËörùZEšÒ5—àû,íÄíêì†Yb­ÁUæêÕP«Õÿ•Þèèh{{û?²…‹/îÙ³øì³ÏÌÍÍ_¹|yyù?!$xéÒ¥:uêüOò½°ÒI¸§7«:ÈDÊßNÑÙ: FßÃ5°.p‘øˆµAWa |îk!Î@SbK°°#$ëlJ\xð‰5¹‰¸ÝÁ§>w ‘¨‘?ÂUMq!¥¦h y˜K#tŽ´Î@[F¼ŽmÐ nA”Vü‹€b°…f :è¦W•¬`=!=C^.þ¶á4„>Ðìé‰g<¼™šÙúæ p›?$õ½C©‰Ñ±¶úÓON¸|¹¥Í=Ƕcûž^½çóþñ2-‹N¿zç+9½£ìþ¤ ø)ü<;ÂâðÛÖ'©Y½ÇBÕ«ð<Ó±µá|í7Ậ2WUøsp÷îÝC‡õïßúôéÇÿþûï«ÆäBë©ö€‚1dÃØY"½B+!ÚC„À{pM4W§áÔ‚lX Ýឨ7xªÃP 2üŒqOcQ)cuT¯Á}52R$`G0–5¨tH~ }}®G¢4Ç5‹Â<BL5ÚæqIÅ-`6PîA ¼“ Œ„o¡9$€¨á†ÞùnÕë'R*~†öpKt­^«w†w9ÛÕ‚ÌüÚïxoµ8G#ê1Zƒ#xâU¿‚dHÙå9jÕF_õøð:ErËs¾¨âá¾Ê!fï¶rµ¼»˜ê“†û­>ºª·‹*CqÅÂm¯‡ØÊ�L V9}jº»°¬S­Š>[Çò…ßD•npêÓŸu¸ç=>ä—¨oùÐÊ¿”ÔUÊ{ìÒÜÿFË]l`%Òð²;Ã�¶ÐRáþÓµwÏ Eüð–(u‘þ"%ÜÁЀX˜þ:£úkšþþþuëÖ «P(–.] ¤§§×®]{îܹÀÈ‘#kÖ¬),#¼\ÿ Õj“““—/_®P(¢¢¢„‰_}õ•B¡ §»víR(7 úðÃ‹ŠŠÆפI“¦M›<¸ àIç·’’’9sæøûû7oÞ¼k×®¹¹¹yyy½zõjÖ¬YãÆ§L™R\ü„•TXX˜œœÜ¶mÛŽ; S²³³[´hÔ°aÃåË——••ݾ}[ø½¼¼Ž?þÿÔ2¸¼¼¼¼¼ÜÛÛûðáÃß~ûퟸå°°°ÀÀÀÀÀÀ°°°ÂÂÂiÓ¦ ×[Æ  Åùóç+ÎÍÍMNNöôô9²BfÈ!ÂÂ>>> …B¿¼=333&&F¡PÌ›7¯â>KI~©çeÆúôé#lÇÛÛ[¡Pddd<xÐÛÛ;((¨N:ñññ‹ëzÞg Â#8 f` ÖP Ù`.2ëŠ Ìa ¤AËE‹ÊbcócbæÅÄ|9mš°¢´Ð$P³`$<�Cø—!‡Í9á¼#WSð•°JG[Š«‘¦Ä<)šG¸£¼K½,¿¥‰œ¼›Ô÷ÁÚ”’2$PSœ†¬µ– ^B8˜Á;Pt0| #üRX ;á*¤QMì°ÃdЂ'´ƒt˜ c \O‹])ò×_ S þP›§ ”q#�„?)äB.hùp‹¾–šZb"ü•R^@ii¦‘®Hw`ªVñHжSÓx'ë8‡RÇŠ. 5îmiæiÿÈhy/¦ô¡$£¢Š¿¼lJ2ÊK3VJRÊî).íX®¥ “‚Ìœä̤Gª¤¶(èq<BcÖù­ÑvQöÄSà£Úù¡a³Ÿ¥÷½%˜�¸!Íni0}™G‰dÙ`fK¾3”Àý—ÿU&œÄ³ö{ѹˆsëÿ ÞUQQQýúõ¬ [&&&(•ʘ˜˜ÐÐÐ=zÌ›7ïþýûIIIMš4Ù»wïÿÄí¨ÑhN:xzzfff=Ó»ëõŸ¡“'ONJJ*((2[™™™·oßV(Û¶msss«Œ°åää4nÜ8::ºzõê6lðññÖ¬Y³}ûö'N8884lØpÕªUsæÌ¹pá‚`ïÝ»·nÝ:///—O?ýÔÔÔôôéÓ±±±wîÜyçw|}}‡Z"8yrçÎ÷ï߯ÜãøñãSRR¶lÙ2a„€€€°°0áwœ0a€RRRLMMÿôõóóóõõ3gN×®]ß¾ 'Ož,((øþûŠ£»xñb ??áÂ…gΜ±²²*//ˆˆpss;sæLxxxvvvenëÖ­@ZZÚÌ™3ãã㌌òóó/_¾ìééùÝwß]»vM¸ª……g̘ñèÑ£‚‚‚磔‚¿˜’’2uêÔôôt¥R¹}ûö)S¦ ><$$¤gÏžÑÑÑÿûæê=�l@ ­à¸(IÞ ºC ,t‚b®Ë ÚÃV°Ccãð1c&‡‡¯!W× n‰ “AΰÞ‡âÆÃ]ìÓ’Ž{ÄàaŸ<ŒÔÈ-Ñz—‡õu4çB.6¶ä¸¯EzŽ&u(¯‡¼òÉM ‰/éñ˜äSKÃÖìRÌ‚2V©(„ñ@NaäÁ&(€I0êAK8ʼn»øšƒ‹SÙ�— A)Vž½ÆÐ’Ÿ“§z=x¦ãžE§ /ž[jL”7A×8Qó™9®KêŒ- ïÚ&6¦t8t{ÌâÁ¾Ó„¯&EÒMÁu&üøp‡×4Fì{JZC#a»5'¬X[JG½~ÓVs[ÖÂ:ÀšrZO#:ú²[¾§x¨0ƒ÷vS¤Çô;Ûd(õÁ¾„õeþÞù@d[¼ñÁÀ+W®œ8q¢U«VŸþ9°sçΫW¯N˜0aÕªUÞÞÞ:txÃoÇ7®X±ÂÇǧ}ûöGõ÷÷ÿ}ÏV++«={ö¬Y³fÆŒ”«W¯îܹ³wïÞû÷ï·³³ –,YqðàÁµk×vîÜ9<<üÂ… £Fjذ¡··÷îÝ»ÍÌÌ<<<Z´h|üñÇÀùó烂‚€uëÖU«V­}ûö‚{!zöìÙ³gOaùÿ.ÒÒÒÒÒÒ¬¬¬>úè£#FLœ8ñš¨[·n;ÖÀÀ@8G`Ö¬YžžžMšTÜÀqqqk×®]¸p¡Offf¿~ýÞÿý… Ž=ÚÅÅå™ ž?~ÿþý;vìptt¼zõj¿~ý.\8gΜÌÌ̺u+å�زeËÑ£G ô² ?räÈÁƒÝÜÜ„XÂÉ“'ÓÒÒ*ÅÉþ°¹hì  Ü-XCK0‚‡à®—ÎÉ(¶YÿþW7.®]#<<”pL¤ÔÓ!Õ¡pp÷݇pkذ{áá&Ÿnĉš+I±ÇÙ„T ó±’ 3¥$')ÚL,É.ÁÀ›Hæõ©ö˜, åFä™cWŒ™šÄbV™£1çƒb¾–0J‚ƒ¶~ ]­QÛp'™C&ðNÀX¨ w!‡]0À”8G§’ @C05)ÚB6üæv}:”®0t)ñ䟇ÏE ¤˜2y‘&&(Õ·‚oG¡ JÀëφEƼ뼷EzEÍ/6»:ÞpËaW»›ødaO]†>~ñ˜iêÀØé'*zŽ˜e—l|O¥ù‡óÀ Ä˜¯º\7åËYË5¿è4*mf®3×LÏÞiæÔoÀ××Yé¯I“H(L(à¬QåZÌô)f {"uÿúˆÑëøÕYœx7ñ’Ø:äñŸc®îÝ»7zôh`úôéR©øùçŸç@X GžžžÀǧM›¶téÒ¿† ýGÌÕ—_~éáá±cÇŽ.]º >üÏÚrƒ Ö®]+|ž:uªR© ;vlïÞ½ÝÝÝ+gÍž=»¨¨¨Aƒ¥¥¥vvv–––J¥R }òÉ'•[ûæ›o–-[¶víÚ:Ô¨QãÌ™3S¦LÉÏÏc6999%%eÕªUmÚ´ùè£þ ¹:tèЖ-[FUY®ôÙgŸ<xpÆ Íš5ÊÊÊ/^,\ok×®}£!%%eÆ =zôhР ü 6ü­G¿mÛ¶~ýú ×<pêÔ©iÓ¦ <øžï†„Ê×!8ybo{#¨ ÷  T Üݵœ…j²á è²³~üpÎÏwƒºÐ®ƒ•—±ìo¶p³5ݺUЯcc³¾Ý:Ñ€ þåäX`!AjB©-¹JŒmÉ)Æô¬Oþž"IV×;æ]ÇFƒT‚\Š&G9ÊRdf¨uH!¡”%¥ %Fg~Y⟥ÛzŠéöëDy¦ÉCɼ$Êf° Fgà“ÁfA¡·Îêµ³ „y¿k KµÍÏRv sòEi¹3 ù#j}É3yIÃíÓá÷çî(Õí×÷ŒÜñ™ï®ÐB,Œ…DÚm ¶ø$ H{àŸßvÏ”6ÀWMT.[Tïh<×<‰)‘MXhbx­ Ÿs¦¼XÕzf0®¦¬+&µ1‘ý4H„š-3‚µanöóÇà’ψß{!]+â;Í=&˜«^P¬üÌ•««ë¸qã�''§ÌÌL!šš:|øðË—/¾¾¾¾¾¾‚o±xñâØØØ7Ü\ÉårÁ,..nÕª•±±ñŸµeggç~ý„‚Ñ£G_¼x1,,,8¸¢®¢rÖìٳϜ9cbbòðáÃ:888Ìš5+&&¦G:u–Y¿~ýâÅ‹7nÜ(j£FvìØQTTyæÌ™7üQצM›?2ª×®]›4iRJJ бcÇ–-[.\¸pÞ¼ykÖ¬9{öl¥AÒh4'Ož:t¨àWŽðóÈÏÏ¿xñâœ9sœ;;»_YøW}åÊ•^½z999 ‡:nܸ!C†|øá‡rùßµ4~|="Ü*x_|â<€Ñ ¼„ÝÓ° &‚œ8yòVx¸t…G§! šèèõ#^—¾ë^“ݺU¼½mØ01=¥Ž–2h™äÎ?RÊ10¢¬i¦”zðÐ Sº†pÏŽ¬ƒôÐ ­Á£ Ôm@j<Õ¬1IÃPÇ(9çÔZ&â²Ugó€e‰ ¡Y Öp–Ÿ’o?‚YEæÞšBøB…¸t®ž°ïÚß?~5Aýê2-ù„ÏÕ+?–OüüùY6Çš&OÙU)n+ϱ¬¶ñ­ä);ë/­ì ŒåM7¯;Gµ!`­ÑÒ…¹N)2·råàÃ�û»ðÙLýŠNáu’…ûÙ/¼ˆˆk]B‘1ãês³§lÒ6½á2hioPŸØWÜcfff‚5ª„ƒƒÃÊ•+CCC<¸iÓ¦+V\»víåÔjµIIIVVVÙÙÙeee™™™®®®|ËÇŽ ]·n]¯^½ôßëKJJ :uê4þ|ÁU}é;mB9}úô-[¶TFV322T*•——Wnîy츸8SSÓç£^ÿEäåååææÿ‘þÑþþþ§OŸž8qâ¶mÛŽ=jff¶bÅŠU«VéÛ*a¬Œ³!X¯X[[;::>¿ÍÄÄD [Û Ù¥R™””äàà`ccóÊã),,LMMuvv655®a­ÌÌÌŽ;Ž5júô鉄¿!¶ëu1·S@K¡1¼„Ö:Ô-uÈ ¾¹›õëæœ]z:0þ œÈöÄ»ù×nËåÖr:¬ú2gîÜåAG´”x‘mÂ7×±¤¨%7"Ì›rÉ’|4q€VÜjŒú6^†˜ºB$Rr ×€Ó°Y‹«ŒG:J´ !*ùû‰V³8‚ní¹ ]�Ú}°D,¡ÕUœ]-)JkÒÊpÕaRB)` 6¥ö;Ïû1Ý62¤2ô'ƒ„9bI{@ªŒuÔÙ¤è’É´P>]I¥ÕJuiÕJªg’jHÔºxÿ„"ë2Už‰°a RÍ}{üké¡q½¥a÷ÎnÖÎé8¿Z¯#ºÛédZ´ZYBŽs,ä“ßëbw@"‘äOÍWz¤Þù×^ÞV¸†K@ƒu©Ú÷^µ^34y*áh×Â$}å)k„~J!ï5†C£×6óy“i�•%4éfî J¥;vìèÝ»÷»ï¾Ûºuk‡Ÿ~ú©  @¡PÔªUë ¿›7oÞ«W¯!C†´lÙò«¯¾ÊÊÊÊËË›2eÊßrµjÕ<==¯\¹"•J---€)S¦DDDœ={ÖÏÏïÆ�‚ƒƒkÕª¥P(""",--«U«æåå <˜<y²V«½råŠíW(wîÜùôÓOgÏžœœ\«V­š5k NLëÖ­wìØñÌa4mÚôâÅ‹ˆŽŽöõõupph×®°ë„„„Ö­[Ëd²ÿµ±±yôèÑìÙ³£¢¢þH+d‰D"“Éüýý‹ŠŠ„nj:N§Ó9sFh­âååU·nÝAƒùøøÌœ9SX+''§iÓ¦Bîêùm4¨wïÞ•ß›7o†„„,\¸ðý÷ßåñüôÓOaaa;vìhݺõÈ‘#‡ZÙG«Õ>|øPà"™ššV’3ÿ.Яàn�=áp‚û‚(‘ µ;8"²*®�ÑÑ5ºv èÒ%ÔGްy3pþ`tºB­fž²OÇÖÎÀ\G¸5µTغ‡guÊoâcIAuR °|Œ³Iöm9‚‹­„'ñ+c£)3•䀯’vLOe@Š”ZZÀ=ØÎ´©0>€»0vŽ@0<†6áÛY¯Âï.—Œ jÁ©Joë÷ À„ËîhÖ»ÄPT.W±]Ë@C{ Y�ɰϥ|âfõˆ¥»½6"¥hνöÙ,F  é+¹Ø@Ó4ûlŸl�H14ÀJ0®£×¯™°Õä’ß±!gå¶éoû†IP-A ”`´·„WÃ÷`ö¶ë1€›|˜AÏ1O‡ï Ï9|HKýA?vùÔå@èÀå×£]äÂÜ_‰âÁ ñóG¿²™»w k­úE%¥VÒ’F>žFFFúf©iÓ¦“MxŽ˜šš+  }ûöùùù­[· LMMÕét¡¡¡oþÛ®]»¢¢"ooïŽ;J¥ÒÂÂÂ_É:(•ʬ¬,ww÷—¹ ‰ÄÕÕ588ØÂ¢ZµjÞÞÞ™™™999]»v5j”°€O×®]5j”““Ó²eˉ'ÖªUËÝÝ=--M©TöéÓ§wïÞ€ûûû7jÔÈÉÉÉÐÐ0'''''ÇÜܼgÏžŽŽŽ?–ÉdÆ kÓ¦ “Éš7o^¿~}ýfÍš™˜˜<~üØÂÂb̘1~~~íÚµ+,,ÌÉÉqss›9s¦µµõË3¿{`mmm…s¬_¿þœ9s~]"///O«Õ:::¾LÕ¢Q£F=zô"l‰D¡P¨Õja@]]]¥Ri“&Müüü*ccãàà`ww÷gGøÚ²eËJJ…D"±²² vvv~fEa®ƒƒCPPƒƒƒðÕÉÉ)((ÈÖÖÖÀÀ 88¸víÚ•{tqqŽJ©T6nÜø…çrïÞ=??¿¿FŒñw@¸È“’’„´ôKE�¾` Æ¢å$Ô…Ž`ÁpÑу÷î5Ý»7nïÞ€èh¡f`tƒXhDïÎülGF²„.rReØZSRH¹W'ŠM)+ÃHжÈ4Ai€*—»Ôs ó$㜉M%%h`Š´Œ»Y‚‘=±yTƒ¯ÀXJM ÙµB xÃ!¸…çÁ d-Ðzr혣+'ÖÂL°€CóšØ¥KSSS//¯Ê§Ä½{÷œÝ=Vï>ÀmÁ93”3U|Ø®«H z@Å£¯TrÌež ¤ë(ÑÖþ…2’mdxKKtmã(î»Q`!A&—·+PË;–´Œl´¹¡÷†€ ­5 BYÑ^ÄOú^©¤‹¥Ì¶-öõtñÁlkóœíÈ¥M,+ÔD‰±œfàg`¨)õ¹¥ÑIù­-_ø® -+ߊê:t022žT¹Ee—ï$«UeyéÉ’vý>hÒ3-3ÛMž9bÀÛÿ2d[·�� �IDAT·×AnnîÝ»wÛ¶mûOPµïСÃÿSUÖó¦Q¥Ry{{ÿT-<úÆŠ0 ù¹sç,Xðªe@!C9t„ÐÜÀ N‚ØA ¸_ÁTøÎÃ è ­¡+;¾`Á nþƒ ÚYS_ƒ®Yjó°¯Å)Z-ÒLL|¸ïLF1fùX5$ú�=R©®E§£$5RZC©†ûZVÀ9?j9qÿÇÞy‡Eu´mü· K/"]T XÀŠ…bGcÔ`ï-Æ(64Xc‹Æˆ5DÑX1‰’7±ÄÑÏŽkĆD©R¤lùþ8ìf„ Ýûòº\æ”)gÎ<gfžç¾åÔÆá¬^ŽÏ"%eеZ A§[~×Áä`Íáç—jÀ5kÖ˜››÷ë×O;qàÀæ¼]V"6Œ=€¡®0‘‚ºÉ l;)™àpJdÜ)ÕkD±ŽŸá¦Ôú‘±§ù¹¥Îõ©‚1“6½ ¿¿Eâ\ãÂÙ8(Å¥œ¹eF ¡@¯ÈìjÂví‚*¢Göâ£eÜr¹heô ÚÁ†v\>_îƒa3øÂé‰nü÷ "ÊéÝA}vÕ¶mÓ¥K—š˜˜ØÛÛ+Š˜§ëöž‘ùðÚy «…hPF\ˆA'@<àDÁ3¸-ÀŽÀ8H#øªÂàíAí¡èA]¨›žœ©X©À¤�…1:ψ7¤Y-´SËŠ$òÎÓæ>¦ÙÈ r-¨“ÊR@Ïm–Ì5·ÄAì‚ñ †»à `5XÁ8aP>spä RÎ¥ž•m'¦,‹z÷Ä_ÆsÂêæ+)gK(Å‹¯À<åÜb·­Yñ4øÓZ}·ˆòt21É,Tµ7æao¾éÌêùÓðÔ°¿lnñeß›;?µë¿:6¿Ð\UUN#©ó .=EJQ>mƒÙø#A^²äfÁ~1µtè(È,âÌtdì\ÃÄ<¾ má+l3˜ý Ó¤L„Óº „øÚÅ"u@åØü]¹?”x¬l JWfј«Gvv¶ºÃ»ŠÊ_­ÊÌÌTgèxWñnÑøÖ;8 ãa?œ€Pa jƒ9|о]¸ua/܆™PþšÁ~]zÉH(`ióÈ„¼\j=àK1FÈj‘nNêŸ4’ý»dEˆëqæ)™bœ“‰•“ a}§À*§ð‹3Oa³‚<h:ÐÃ Ó f`�V¡æžî —Á$p>„-åÓTÏõX4ˆ¯wƒ©â¨Š†Qo -%A†²{$˜Ø÷JÚ?ÙÚ–ø¾ÊˆÁ€d†nVüâ˲ñ$YJbuô[¸ŒŸ|}ÃRÅ‚%¢x;@K©Ù‘‹N& Í)é¹]Ëc‹<ä+UE¢B¯€]_þÊøû<‘Bhá¤`ÉqFûáÈE8 $«–‹ÕV¤¬…Ñ^/‚2r…hÌU™VKÞŠÒ`aaQizW…èˆwÂ^ﻂ»ÊøÙ+P ÎBu0†`wÁ ªC,ƒ`v° jÂ|xŒ‰Êe`_Š1Ê¡F ²Ì¹kÀüdâ2¨’‚Ù,ÅÜOA;±6ZìNÃÂ�Iȱ†-Ð ŽƒÁ1Ù ŒÁGA"Ü�#¸ö0¤€@å¢S2ô‚ëú\¡•ÃCøÚJ$hK97Ø´þ,Ý…Î?ðèƒÍÄùi~?Êþ§ËµbÌç£W±s<Zr&MᎥÎ ‡µ=nýNkÛ0Ñ}‡ï–Ðêѱï2;S·9¥åê˜ÂÈpÖväÉm„uËV˜Ê„¡|r”85Éå7 ¹ú$%%ª{ ¼ÃˆŠŠRyÖT4>|hccóž4ìåË—w  hƒtA¶4ƒß ´Å|� rR! q‘Ñ8è�Y)tƒK`Yrˆ¦‘©=±:´Ö婜ÙRž$QMÎ)Ö°B‹. ¦Š8ò>•‘*¦'|+Ç\L#cž¥sbàÀ@@0ƒPn@,Ä8ŠÐ‚v` ¿VÄÚrÝ h1m4—ÙÕ,•“&O1Í�ЇÊŠ®v¼é÷}’ý*•Iø³ˆ´U1Ë™FŒ['_3'eÝ2³Ogê>²_qÕÒ±—Þ¦õ­oQÒ ûø¿u©æ™ÁþÕ6¶ä¯ð©ãÂʧœ§Ra^e›Äè³üÚ˜+…ÑÊ´‚®¬nÎø_ùó%°Uÿƒ¨L‘þUß²Ò*ª`ªhÝ_5æêÕahh(8ŽkP¾033{¶‚‚Þ(„ bS0…¥6¼´SË„ƒX›qR®‚{>N Ò l³LŘɰ6ä†5÷ZQõ1÷õ0ÍE;—üZÄ<à9¬£oN¾ â9)a}ưüå<ñ †‚¹Ômh�©Pjƒ„Êõò§ÚZ–M6ŽP�2¥`S(@Øé)dA˜r­Ë€ ‘Œù™Þ5Øg.‹h¬…[±«â!_ç–ƒîfùoäË©â„jÚê®í±uÄS¾ÎØ8)z×®í‚ÈEá¦õB_ºj6C'üuš^»Æ§¥Ziû~¥[ã¹jæ*� $2!vjU0˺q]éïç ý!&^â$)±v׋éfÉþªïKü•¿C5æêµÌ•••Õ[ë…\Ž8s挗—W¥m´˜ššZXX¼N@ñ¿ÿþ{Ÿ>}þ òŒ/…}0 €\…  Qà Gdô•p@FŠ õrÑ•r¾“.¡ž‚tÆÙ´‰ÃÈ\KR²i® ù9Àñ2º*ˆ6£VWÒX#gn?C?®Å&Sì…Ž PÐ3ˆ€FÐ t Vé�Óà&�ƒàÿÀ¶+±„qü&T¤Ol†1†3{=YÚ¯§ŒÉýgÜ«ÅÜ™ì¯é*†me <³€(¶†ãà%)ûÆ^=3©F§ÈDt½‘öÔU7 r6O$Ë Òøn½‚E9f¢Œj%ß_Lò™·“N·è8dåξ„É0Nª-‘¾И«2á}½ÍÍÍ­/v Åûа999ïbµÚ·ø�rà6Tšp l!â :+¨©Å³ÓÙ$£©ˆy "àš¦R²¸¡@–yUŸa^@7'¶\'îðlŒÈÖag*Ö0²D,Q° [ñõS‚ BM¸ ½´Ñ{)öpªƒ6B âp„#ðö"š+¸$>—+t@IvŽ.<#|Ì×c!‡0zr-±’Ó!±- €Ç¤%Òs¬âÈÄ‚³ÅaÄ{z^è$‘Ÿ¡¨Ù1àÆ‰ÏnùLkØ"@2æSgÜ øA'Í(Ýë¶xÈ·<µýåò B§L3mLÀÉŒA),îÈT5gúFñÌ)` ŒëV8_r ®Xíl)t\ÌäU¨o‹Ž=j ²W4W!!!êRèýúõûå—_š6mª¢Ä.#¾ÿþûjÕª©ñJϱjժݻw¯´w®HŽe/jY)HaY[[ûøø�¿ýö›À†´mÛÖÙÙùûï¿WÅõë×¥P0xð`õ0¸/^ZFÿûï…ß?cÇŽ-1Ç7¡¨...mÚ´ž?þóÏ?¿BÏ)IIIû÷ïwwwoÔ¨Q‘Õ[UÕuUiœ'Ož:T¸nbb2hР˗/GFFU«VÊï¿ÿþèÑ#ÀÙÙ¹mÛ¶š85쀶РR ¬ ;üf`Q0Àí\.AXKh“O,Xf( î‰  -$3ªJiu|ˆs1—ä´N~À 8%¢§˜ÿ“ÑN?娘6röB3èNð‡Ÿ*X*ѤAèý]þ£!ä t¶ÐDÌ2*‚CÎâï …ÿOËdñ ‘ïï$'a¤CoáàSô…cò/°Ž\ÄZjµY.²K2Z±>žhØO,#bñ¤ßX¶ý ߨ•Ép‡;bùA‚yšdA ¸¨ožZÒø&^Ô숾×éÐîüuJ›û|tÿ|Æ D �·(tTQGwh©¬×ëÇ]=øÿ¥É3.^¼888XGGGGGgýúõþþþ³fÍ }Ù²H$’2€.^¼xóæÍ•ùªÉqÞ¼yÛ¶m+—;GEEMŸ>ýîÝ»ÀŒ3vîÜ lÞ¼yñâÅB“ ÷óæÍ RD"‘¿¿ÿÎ;uttBBBfÏþ›ÂfVVÖ¬Y³~ûí7áäÔÔÔiÓ¦………éèè¬^½zÅŠ%æøf>¼³²fÍš¥R8|öìÙ«õœRŸŸ/tȳgϪ:§*G‰D"´ÒÎ;gÍš%‰t”X±bźuëþ¶îrïÞ¬Y³¢¢¢ttt$É7¦OŸ~ãÆ ™3g†„„üöÛo3fÌÈg̘qúôiú;NÃÏpÚ€ŽA8 Æ‚š°ˆ,XQ �{ \Î2k ^ȉ•žFŠœÑ"v‹±[è ß*H“s~„ŸÑ•Q�¶ –¶Ð¢àø‚a±/¸aZøÃ-85Aÿïßìá²R‹^.cEe·V�ÔVÒ×eŒ>ßZ{r öøµ³6À›jÄD/öÀÇ l<]ráh ßR²•sØô9ý“/aÕ8&Éæ¿Kä¸=Äû&Û1Ñ»/']y—~ØÖÖvÔ¨Q£F²´´Té4.]ºT˜œ<y²k×®.\�nݺյkWoàÀ]»víÚµ«0BíÞ½[xÃ… »víª"v9r¤"\Xùظqã•+W=”)S¦T©ReáÂ…årgAyyΜ9Æ KNNòÚ¶m›Ð¤õêÕrܺu«bff6a„͛75ªFEÚÄ××·I“&AAAÂɹ¹¹Çwuu.<pàÀƒ®]»Ö±cGUŽoªWU©Reùòåû÷ï:À¸qãZ·nýñÇ—c'NT1~uìØQÄRaذa£FÒÓÓ{ôèѦM›ÌÌÌ„F{ðàT*]³fêÌôôôY³fõêÕkñâÅ£FêÛ·o\\\TTT»víF•––vêÔ©¨¨¨¸¸¸~ýúuïÞýÎ;7oÞÔ¨’` mad@8œ h ÛŸcŽ0�,ä´ƒjpLåXk3TŒ98‚ƒ}X¤à–‚º`%Ǥ# ¾…*ÕzÂjh 73X #TÎNŒnÂ…4wrT~ÖÊ}¬ -Ô ôì(\CEC[y‹ µ.ÒóêKŒÔ‡º‰Öè1�^ÀG8·ýÁfø‚J¾J6e]Á¹â°NlëÇwÙ<”$‹¢'9&3*œï<˜p’óì{{Ø¿Lzòòò±ðüü|›„„„íÛ·8pÀÛÛÛßßÿÖ­[wïÞmÞ¼yLLÌŸþ™=xðà‹/†……<yrÁ‚5jÔ¸xñ¢¡¡áºuë9"‘H>þøc;;»?ÿüóöíÛaaa;vìðõõ(Ú*:tضmÛ¸q㌌ŒNŸ>maaQ.w677777Ÿ5kÖéÓ§6l(¬›ššÎ›7///¯}ûö_~ùejjªÐ™™™Ÿ}öÙðáÃ[¶l6bĈ¸¸8õ¥? 555##cÈ!Ïž=ûæ›oœßÚ^%‘H7nœ››{ûöí† Þ¼y³W¯^åB{/ %%%))IàèÌÍÍ‹/HFGG*¾ÝŒŒŒk×®™››«.äryvvöµk×zõꕘ˜xôèQÙyU<?aelÀN Æy¼€Gð5؃TDW c¥Êq–’k€ÔŒ‚TšÊxaŽ‚ÿƒ=ÚLN \×â‚‚y Ì—ã ¡[“`4 †`-¦)"§ \ô„Ë ®‚ô‚?á)HáèC>L�k˜�¡ðü¯bZã)lA´3¦«Ö�2`u¾¸OžDÖ<O‘¢<z^¹)Xè©C^ÍB—qb ä²p¸ó“ù_2QÓÄw<µý.o!awp0MJÕªV·ôÍžÅÿ2UŽL¶Ú“†È³ ˜û·Ò郕¼0B9°cB¿“ƒùýO¥äÉ^e°U5c8]b\F´ƒ¾Å—¾òv׿˜«»wï lå¶¶¶[¶liÕªÕˆ#zöì¹lÙ²œœœnݺ3ÆÏϯyóæÃ† 1bÄСC<x››;räÈyóæíÝ»W5HåççK¥R 2*ªñÌ™3ááá÷îÝËËË$ä+"‘ÈÕÕµ[·nÛ¶m›5kVY%^ Ë—/ÏÉɱ³³[¶lÙš5kfÍšœ>}ÚÇǧqãÆ?þø£pZ``à´iÓZ·nÝ Aoooooï!C† >\µÑ%Ìe…S¦L<xð¹sçÞæ¡«U«VëׯŸ9sæÂ… ‡ T^w¾{÷îæÍ›·lÙ[Êi'Ož VÉŽ<y²ˆD}ÕªU¯]»&üöööîÓ§O‰œî”r%Ù6ìõÐ ji$å|6à—!Uc]fWÀYC“8ip,E芉–Ѽ*Éœd<ƒ:` úÐ�$®ðT—ñ3zííA NÁ3p�;¨5!â¡�Z@¬)òM^1­¡PSÊP”@‘¯ÍÜÞ|½ô9ª4—Ty r^ýÝI`¥ø¬s[¯ü>Dükwñ)/&-fîZŽyft;žc“TÛe_:‰ ‚ߣîs:gýí&µ ›ò÷àt>ÙÏízé*—Åeù¥üźû²B9Ú ÷²Kz¯n®5j´cÇŽÂo§GŠŸàáá±ÿþüÑÆÆFÐgš7o^vvö”)S Ô³gÏ+þqiø×_>}úСCïß¿ÿ¦Þ°œœœE‹]¿~}êÔ©ëÖ­ÓÖÖ.]’êupêÔ©Ë—/ >vìØ‘““3zt™Ä:7oÞlnn.p·ÿ'Э[·ÐÐÐíÛ·¯\¹²o»cÇŽ¬¬¬Ÿ~úéñãÇB«vïÞý•!srr6oÞÜ´iÓvíÚi N9!†ÀX¤$ÁNX ð LŒxÎ4š’U@L*õÀb 6)¸.ã*tL"Ba<8 «a\…(¨ g¡8ÃSP@ x>Uà†Ðâ•s—· ÓúóE(ƇÙóáK_›ˆ¨‡›V‡Éò.Ǥß%p Ϫàiñí`Ã{5RgoÉ%KˆñÂ(aߑЕÄãœî[²«ÇÛß±^ב½cÇŽNNN6lhÑ¢EÏž=…‰Â“'O´µµwîÜéççWä’øøøE‹õêÕkÇŽÙÙÙ_|ñÅöíÛ;öFê?sæÌK—.mذ¡I“&žžžcÇŽ•J¥'N,‡W6""88xâĉª¯ûÐÐÐ7 ¢V¶nÝšœœ¬n®ÆŽÛ²eË1cƨRΞ=»}ûvÿU«VÕ¯_ÿ?d®*½{÷Vùòòò�SSÓâÔ)))ß~ûí‡~¨òEŒˆˆ8räÈĉU‹½;wî<~üøìÙ³-Zäëë«1W凳C¡ˆ{6hòá*…>} Ì´0‡g Ò Hq'›Txö× ˆQbd2΀|ÿyà�ûà# Îp ~L8Cà&¤(× ^À9bÁ®VV#˜AMتœ3ýõ§,MaÂ×]ù4ž‡ØÕö*]­á €šÉJ" ÔK…gÏoÏd'´8ÑUqVN£eŒ®Î9·gs7eÊ™G­ÄØHpH?±ÖYx:IÔ�•ÖÓÏñÛñBþu:›ýd+kÚ|ñ¤2L8µÔFøSy­q©¾%VÐSùû§ 4WÀ²eËÔXúôéÓ¥K—?þø#55uÖ¬Y 6Ò‡~þüù‘#GµjÕrss„ ¼¼¼<<<ú÷ï?eÊ”Êg’=zôhýúõ›4itêÔ)77÷ܹsåb®œœœôôôFŒaddÔ AÁ?-22ò£>ÊÍÍí߿Ϟ====;tèàå啜œüÅ_8::öèÑÃÏÏoÛ¶m=Ú¾};pÿþýÝ»w6lÛ¶mýû÷÷òòŠß´i“££ã²e˾þúë£GÞ¿ÿÌ™3–––ÇŸ={¶*Çwr,lÔ¨‘ÀuñâÅeË–5iÒÄÊʪ÷`vvö¹sçüýýkÖB[ˆ‹‹‹ŽŽž?¾¡¡°pÄ•+WvïÞ½hÑ¢Õ«W/^¼øìÙ³111¡¡¡cÇŽ]¸páêÕ«.\(‘HþøãH¥Ò=zôïß_c‘þ * ¤púÂTè®0æCÜN9£Ì# ê‚Àeø~‡: ªËY ¾ ùÐþ„ÏÁ¶Áð $@oø<a3¤Á ØÓà‰Úš�.ðâoÞÛ}¨B üEõáï»ÎYlˆß÷t;É‘kʤ^‚ô‰‹,% “‚æÊEÅÛJs•£v¹~sæ8y s„܉v"ê(fž— Ýråb`Q_öþÝKàšHð7@MØWÀ-ØQ¬÷ʦ]™ di²(Õ\*u^€]¯h®nݺ¥®êmooŸšš*¤¨+¹‰ÅbCCCÕu­ZµnݺU¸Ò)‰D¢¸¸8áÇ®]»„@TáO@Ø6~«Uæ[U¤ŽBQËåΦ¦¦kÖ¬)Rß°°0õ333y®òÑGõèÑCÕ°‚™6l˜ð[µ[#ü9vìXAR•R<Ç7‹Õ«WóÍ7BÙÊ-Z´PuHKKKÕï"}UõÕ»woõ”€€€%K–ˆÅâ‘#G>\½—-[¦ÚÁR<øV5ì ‚®Dk(€“v|OC0Ó¢ŒÝ zA˜Œáýa| éð� `´ˆubrEXÊHV ƒ½`‘ðD`æð#(àGh ) ‚Dp‚ŽÒXÁxø¿Ê²U/‰Lc–LfùRV<d d*Ý^ ¹P¸ kޏƒ"eëfk¶R§é¹ù*ÃY¡Fü¥'•f®Š2ªÕ›7oNœ8±Aƒêïp‘ UÕÕÏ|#£À?µ\P¼¾¥·@‰)ê—”rèŸRÞ,*º<ê Rú£,½­þs ûŸ‚à5 ºP-žð‚V2v‚#Ì€µð-ÄAup� … 0räÐ,a=´…'ÃÁ Œ  ® GáxB¢W‚¥Ú¢r e»o+ôTÐL0Ó…™}8ò㓌-$RðL®´4b¬ˆ.ŠÂi–)\,šƒç=jæóQ‚xÎpQˆŽœ½ j^ÑÅ4¥JÔMŽU2Õ–‹1ËS+ç‹ 1WeAjjj÷îÝUßøh %AìÀÉZ$̓ð„Hhuá;ˆ†+Ðn*©'(—’ÐNC=0WÐúû…ºÐ@#ð@áÈÿ¾ÓMÁ–¥SûT ô Dá˜ßJ½*Œ‘Œý’Ñ:@ ·"-±€¥J³+¢-Cϸ ßþíáÛßÙ7AßÊÙ!/Œ*3V£Ø¯ò’/J5áòÁs(þ‡×5W^^^^^^ïö{sûöíw~8III©ä¯]»öôéÓw¾asss5Æ á_c—”3–ð#<„qPB!ªƒ#ÀMè Ú®°¼ LàH :ìQËBíè�äÜ$L¡àx@3e@ØIæ|åGýSÔ;OÐŒÿšúHºÂ”K9CÊ(zù%˜9‰°ÉïdÒPÜþÛB†Baooommý>TVOOO%²B!—Ë4h r›|‡!‰Þâù2 š‹7¸˜Oa0$@c¨K@½á”ˆd-–J Zà÷AÀZH lÞTx  "‚Nˆ@KÁð„Mo¨¾b5]]Õjs¾R>X¬~Õ#´ò )¢«Ý€Ë6HbUûmZÌQrIQ¨.»èTé¤5Hö¤§Þ[œÆZ’¿lbá™%ÎG%ÊEE)ÈËÖÅ먺‰L™‹¢ŒÑÇsõ/ˆUñŸ¾óÐÒÒòöö®œ¼nܸñðáÃ÷¤aMMMîÝ÷*fú+ icÀÄð ôT`&åKp[ðäC h�3àgx�•l  :ô…0�,á�4m89à »áû7Wß°®ÐÐü¥ç4Xm(°¡§€Jê÷ïÁOƒ/ÀHɃ~¤$o=ÔšW°I •¦.…B)ÈQ ¾PþžS¨&\2…éÿEÚ[J¬ã%Åá~8 ÀC˜¤1Wå�{{û.]º¼ÆJÆ“'OªU«Vij®®®Íš5{DbccÞ9½«×´…(H‡+àUa„Á9à¿Â3èàOhJ[UF@ ɪ`}*ý×wkúƒÆ\ý; Þ‡í‡K—.•;UéÈËËS—ùxWqîÜ9Í{¤†tt<Á\ÄÜO9gáwÐ}اôIûL@‚)Ô‡l¨G!’¡)ÄCS¸ zp�Ch g5m­1Wh ¯G7äÃ(Hƒ›°nC‚Ò\ 6éCH€^pòáäÁ ØO îB¶r^5ªü›^Eã¤S(o_öˆáÊ(Ýs%­¶]S Ôõ:àWe´™ž’MQ_mº@áë£\©K‚o”Gû>�'•†_ë”›peôn¿¬|"ê_¥!ÊEUh¿- Rþ.m£±´0#ww÷Q£F½Û¯K‘:´¶yk�� �IDAT6mÚtüøñåž‹T*ýþûï›5kæáááîîž™™™››;}úô–-[¶nÝú“O>ÉÉÉyþüy·nÝ<<<Z´h˜Ÿÿ×ÞcvvöСCÛ´iÓ²eËùóççææfddwkÚ´éŽ;d2YDD„«««‡‡‡‹‹Ë7Þl«¦¦¦:99-Y²DøóñãÇNNNß|óM¹gtðàA6mÚ9feeõéÓÇÝÝÝÍÍmÉ’%yyyéééNNN‚LŒ:233ÝÝÝ=<<š5köý÷ßK¥Ò7n¸¸¸xxx¸ººFDDÈd²;v4mÚT8'##CcaÊqRÍÁËa«Þº4Q£K?ÏàWˆ‡dÈ)„fP ²á>dC"�Çá%iàV&Ÿs0ÿKÉ÷ßáõ¡~1j i ©%æmÕhˆ†ËpÎÂeðTþS)¾ÖP¦4Tž 5•(±Ì·•§e–­:Ï”ç«S`ÜW&ªŒ®ž2Óú õг«””KKËøøx--­„„„çÏŸW­ZÕÄÄDØ!ü×>|((Œ TFׯ_ÏÎÎvvv¾~ýzݺumllÎ;'lQ8;;¿•RP³fÍÄÄÄÔ®]ûÊ•+ééévvvåžKLL̾}û-ZÔ³gÏzõê >¼[·n[·n ³´´lÒ¤I­Zµ=ztáÂ…´´´={öŒ3¦~ýúݺr&õÕW‡¾sçNtt´OݺuCBBärù¹sçÇïêêÚµk×¾}û2¤k×®êTîo`ή­mmm}ûöí„„aÜ//euôìÙS`ªüý÷ß}}}­¬¬æÎ{âĉøøøS§N 2ÄÙÙùäÉ“ÑÑÑIIIŷ冞’’rçÎ7úûû»¸¸øøø´k×î§Ÿ~3fL×®]Ï;7~üøùóçûûû7iÒ¤_¿~aaa#SÞx¬Æâcᇾƒîjno‚Ãj7ØH18B ˆ¡<QsfóÖl\½§‹¼xñ¢]rrò•+W|||ÒÒÒvïÞ½lÙ²¦M›Îœ9SWW·ZµjÇŽ ’H$S¦LñòòÒÖÖÞ²eËš5kLLL¦OŸÞ¯_¿Ë—/×®]û«¯¾ªZµêÛSÿàààñãÇO™2¥gÏžëׯ3fÌܹsË=''§_ý5<<|Ó¦M@=4hàìì¼ÿ~CCC{{û–-[–Hxÿ…©©éW_}åããÓ¹sç#FLž<¹]»v*¢£ŠÀäÉ“]]]?ýôÓ)S¦9´víÚ›7ozxxhÞöÿÖ‚5t€ø zƒ+d‹ÂÈ-œÁCå>–6ô€mPS¹~õÓÛQ—l ¥ªdpJ™XÆ@Ãf`­\1Sy&ŸQ:¦?)é’Žÿ|75I{¶¨³”‰‰jgÚ)¹w+±¡2•«—E– _Þ\{öìQͺuë¶lÙ²3gά^½úÇôññ騱£¹¹ùwß}·wï^ƒ{÷îíÝ»W—o¿ýÖÈÈhÙ²e‹/ž4iÒ[e®ŒŒŒV¬X1oÞ¼Ù³göÙgJ +‘H AúK&“éèèèééÉår©T:bĈððð©S§ªXÿÓ¨[·nŸ>}vîÜell¬Î1_îøöÛor!&Öà-@"ÄAø ÎÀ@ø<ÀÜ!öÐIW) :Ò½EÈT.šå©yŠ—Á€Ëjæªt¡ßAÿ|è9LSþþÇŸÃ%•ªÔ�^fóõ‘Zª_þ_x-Š<¹\þÉ'Ÿ|ôÑGêézzz*ar !!¡K—.ßÿýÛùr$$$\¼x ­ÐpN777þèÑ£ÑÑÑwïÞýðÃûôé#¨­·mÛv×®]C‡}7æ¶¶¶¦¦¦Û¶mÛ¾}{ÇŽ+./^Y½ËiðÇ]ÐcH‡=UádÀAp„:jª!œ•’¼³x-ÏÀÌš5kÓ¦MžžžõêÕS¥ËåòÄÄ¿&˜ÖÖÖûöíËÈÈHOO¯]»ö[Uÿëׯ÷éÓg̘1S§NýôÓOÛµkwèСrß`ËËËKLL43336þÇ)vJJЉ‰I£FT´ë …"..ÎÈÈè?Ú·¬­­…–ô>*iii¹¹¹¶¶¶¯ð84ïÿÛŠ$xR0…`3lƒOaäCÈAÆ@<ôƒÇ°FÀm(P“/y³È!ØNªœ²U+E¿8]é5g¬dšP_©«ªœ`d)½-t”èy.˜(Ù4r•tº/Ô  S,S-åò zvY/YYT/[ß¹²´´¬Q£ÆÍ›7%IëÖ­ãââš4ibnnú¿ÿºô´nÝzÏž=gΜٿÿ­[·BBBjÔ¨ñö¼}ûöuuuö«~úé';;»)S¦üôS9¯}ÇÅÅ}üñÇÍš5¼'ÜÜÜìíí«W¯~áÂ++«zõêýüóÏ+W®Ü¼yóÕ«WëÕ«geeõâÅ‹Æ1¢yóææææ'Nœˆ‹‹³··¯Q£†Ðª¡¡¡wîÜiܸ±±±±‡‡ÇÓ§OCCC“’’<==ߟmÅŠwîÕ4lذJ•*aaa7nÜptt,ÑŒ]¿~ÝÛÛ{éÒ¥nnnÑÑÑ¡¡¡ÑÑÑ5ªR¥Š§§gRRRhhèÓ§O=<<Œ7n|çÎÐÐÐüüüÖ­[k,Iea/�^J9[øò¡ è@äC0�WÁ`û[V…«ÊÀ-e¢ŠÕ¢D¬)õ†s•[JÛ•!eõAµ®’)Ÿ¸¨l 5~Òÿ~[µUÁ±ÿæ%ÿOÐW«Wéu¬s5nÜ8a$õ÷÷·µµ544ô÷÷†BaÛÜÝÝ}ÕªUgÏž½qãFppðwß}×¥K‡¤¤¤yóæùøø�‹/644ŒŒŒ´³³›4iÒ[e«TuTý9yò䊈è¬S§NPPСC‡"##Ç7mÚ4@&“]¾|9--íË/¿8p ‘H"##%É×_ݼyó‚‚ÿ¦M›öèÑC$ 4»Ë—/ïСC‡Š´êwß}·iÓ¦ÈÈÈvíÚMžü¶\z{{[XXH$’ŠË¢}ûö…oÛØ±ÚÚÚ‚ŽÚªU«ÜÝÝ ÿ–-[ çØÚÚ ÛªU+}}ýÈÈH ‹   :uêlÚ´iíÚµ‘‘‘­[·úƺuëöíÛ9bĈٳgkÌHåÂR)b é F`¨Ô¶@9׆۠!f|Ç!ê8`bkïÞ É©5µ“Gú¨”Õª²`ÇŽÇ ¼|ù²Ïš5kFŒñßm´´´[·nuèÐá}`µ8~üxçΊƃ 6lø>°Z8p`ذao- “ÐÉÏž=ðv7¤ g¿çm+Öš5kÌÍÍûõë§¢‡>pà@óæ=]\f•:»êTŸ^éøºØìªq©³«³¥Î®+}7ìÊÌX Ê>ƒü´mÛvéÒ¥&&&ööö …"æiƺ½ç_dg>¼v¾œY-Ú·oìíí››;`À�!&F 4Ðàµqæ?UÚ$¸£4êÃìè À ¥gc‰|¤¡¸0SåÎÖï%]rTù#Hi‡T†i rDÊQæØDY¼gj>–é¥VêsåÖ×(ÂE«–…Šš·|Pì&”“cU«9Δ†r6W666ÇŽ{#2ö‡/^¼t•?ÑÉÊʪ4½’7ˆ÷Æ·² €:¬Š¥¼UB®’z\©ÁBÉÉt«T*#åµEkQâ꺳òG^±;ËÔ¦>*4VË¢Œ¬Õ”öÒ x7/) £’j!)VÇü2¶i…p¾c2áÉÉÉ111ïü``jj*‘HÔÉŸ*?NJJzç¶"xRÞWèC5^Æñ•®g¯Á††âö_’’bjjjjjú>TöÚµkÎÎΕ“WlllµjÕÞŸ†Õ²—Óx%lÞ´†?þ;ÅVÀ]åï0åZÙÃR/‰.iÎqE9Q»¦LIP‹V…¹BeJè?gq[ymÅíªÆ”ÚœY¬ŽésU>ÐÓÓ³±±yO*[™Óbccã÷§aµµ5/Z¹à9\ ñ­ ®* äÊ!p²¤E³mÉí2œ–¨T8TÇV¥äŽRÍUŒZ©*KµÊe¬£Æ\•FFFvvvyyyï|MÃÃÃ=<<*MˆÒÌÌÌÆÆæ}P…?vì˜Fž±\ñ�ÆÃMC¼o“k þm&¯P¼»åÙÙÙ•\Í÷¤a5†ªbð–Û*=°/)ÝVÉø ©¥|ÎA�òJ"´µP.Šæ¨ñP¨V›”T¿iÊD™š·žÊ]"Ҋݹ†Ò(¤–¤òPéë‘U®m¥ Õ”¿c_Ñ\íÞ½[=ÞhðàÁ±¦‘’’räÈ‘-ZÔ¯_ÿÕî– žRAE-äææîÞ½ÛÙÙÙÍÍ­È¡ƒ¦§§Mš4qqq‘J¥?ÿü³pÈÛÛÛÆÆ&!!A%`QiuŒŽŽ¾xñb·nÝʨ�–žžÞ¿ÿ7ÞÔׯ_¿rå P¥J•"1wïÞ½pá §§'õüùó÷îݪW¯Þ¡C‡âCc4xØÃt¸Z,}°òÇqØùÏ—·ƒ•óȥŎ~sÍUøV™ø¹òÇ· ÈJx*Õ)nGªQÜßX¯¤Ù Ç‹ýºbÚªšZá§•r^i·sçÎ]³fM¶@ºråÊ™3gúùù:uêu €ª!!!~~~•éÞöRž={¶ŸŸßÞ½{‹Ú±cÇÔ©S³³³ÃÃçOŸ½bÅŠ•+WfggïܹsæÌ™‰‰‰3gÎܹsgvvöÊ•+W¬XQ މ‰™1c†ŸŸßÌ™3ËØªëÖ­«–W°²Ó§OÏÎΞ:uêŽQ>ÇÅÅ͘1ãèÑ£ÙÙÙsçÎ >wîÜ´iÓnݺçïïôèÑâC3�k Á›Å¿0²ÛÙÙù*1lذ%K–üòË/>>>=òQ""""77wæÌ™aaaBŠê¨0HLLT\DÕ©]»vmÚ´yÍ:ôìÙS(¡]\\ÜŠ+ÒÓÓ‹äxæÌáOî(,,ìàÁƒóçÏ÷ññ™?þÁƒ…£Í^ѲeËâ&?vìØ³gÏ|}};wîñðáÃ]»vY[[ûúúº¸¸<x055õàÁƒ...¾¾¾ÖÖÖ»víª„þ_µjÕüùçŸR©4""ÂÇÇçÌ™3~~~~~~Â9K–,8pà;w|||<¨>YZuìØ±•ß³>|ѹsg__ßgÏž;vLu(11ñÔ©S¾¾¾B9¯_¿Ý»wï¡C‡>|øð?þ(þ84ƒ…¼YüËjRAAArr²°œröìÙ“'O žÇ 033 ìß¿ÿÑ£Gøá™L<räÈ~ýú>|xÛ¶mŸ|òÉÁƒ‡ V¯^=A°µC‡÷ïßW¾ÅbñëWC.—=ztÚ´i³gÏ>|x³fÍÔs 6lؘ1c|}};uêÔ¿ÿž={Î;wË–-C‡mÛ¶­B¡îß¿·nÝNœ8QqÍíêêúRÜáo©©©#FŒ<xpÛ¶mMLLºwï>sæÌÓ§OÇÄÄüðÃݺuÓÖÖ®^½zPPÐþýû ôàÁ•òùóç'L˜ðùçŸ÷ïß¿Y³f¾¾¾Åµç5ÐàÝE6ü?K÷…º�xAËâëM ìkQ®Å•èú´K)ú¥î©¤ZF+=ô~Ò¾ÄÅ’�e³Ê¹¬.ø*^ö^�†Àtá»Ja8ŠU+ü ¨óŠæ*::ZÖ[¹r%`ll¼`Á‚aƧOŸŽŽŽNIIÉÌÌ”ÉdR©ÔÒÒR"‘dddXZZ=þ¼  àÙ³gYYYÑÑÑiii4°<Ø××wôèÑÀ³gÏtuu---uuuÓÒÒ¤Riff¦¡¡¡¥¥¥X,6$²²² ÌÍÍ d2™PrÁ6k úÈÈȈ?}útff¦Ê=rÑ¢E-Z´Z5;;;??¿Zµj›7oöööVÿÐÉÊÊzòäItt´p¦¦=5x¯ÞxQRH“Êüèüƒ–JkQŠ7r®R@DeôèÉ)õhVIERɾl ‹žr'¬t *S+¼aI”e3W®®®PŸ ¶j×®]Ÿþù€Ô§J¥ ))éÈ‘# 6lذaEt]»vÙÙÙiÎ+¢UíììŽ9Ò±cǽ{÷†††¾Ônܸ!“ÉFõÊ~4h e2Wÿ8Ÿ\³ÆÆÆféÒ¥‹/ŽŠú÷x½úõë/]ºtÛ¶m—.]*÷:¬[·.((èÛo¿Uÿºÿ¯ 55uÑ¢Eo§îš5k„'ü¹}ûöíÛK–ÊËË ,žÞ§OŸ#F̘1ã- \Û²eË;w„ýK 4¨`8€ G!•„ÞQˆøçK>VÊ-†Âÿ½j¾”bŒÖ¯Qx7>1«”tÔKé^ø $êao°UÎgý&Í•°òãííÝ¥K—6mÚ”¾—¾eË–‰'z{{ß¿ùòååÞ)ÂÂÂÒÒÒV¬X¡r–[»ví´iÓ„·lÙâàà0gΜï¾ûîÈ‘#ééé;v숈ˆxKztVVVHHˆ¥¥åœ9s¢¢¢¼½½Ÿ={6zôè6mÚlÙ²¥wïÞÞÞÞ±±±+V¬pppX±bŪU«.^¼½oß¾·¡ü£G¶©FuäÈUzÓ¦M'L˜òôéÓqãÆUrÁÚ´i3zô耀€7 �8qâÄ©S§.\èïï¿~ýú={ö�+W®¬R¥ÊéÓ§'Ož,‘H„ óòòŠ<Žw{d=z´à¾¯ÁË¢V­ZüñG±D£°°AÊ¿äðqÙnVô�è¦ÜÄzXƒáßSdàú’71‡âi‡A”´Aå<«$¢a[Ð C-¶Ì¯lùÚ›˜èJ¥K<VšÞÕ‹/Äb±®®SFNNŽ–––úŸ€D"‘Ëå‚¶¶¶ŽŽN^^ž\.×××—J¥ùùùzzz"‘HE¼­§§WÄ·B.—çææêèè¼rQ^^^.===•Ÿ£P!ÅÀÀ@øSWWW,¿xñB(ynn®B¡Ð××Wݧ"ô® …*GÕŸ‰D"‘äææ a³ÂŸªFtuuµ´´d2™jš¢$,/×»*Þ„ÂÃúË/mmmïܹ#Hô~üñÇê�‰Dê­Jeé]÷‹Åzzzª®¢ê�êeËÏÏ(6T¼øãx5ü'ô®lllnܸ¡±=¯™L6dÈÕ ràÀ"^²¼äry›6mlmm_BïªÈSd|ü§áR5ºikk«,P)c«X,~Í‘W•c)ÅS/Ì?•MÑ*"‘H½lê/@‘Zhii•»•zͰÿþ Ì™3'33³FµjÕ*±¼73¥”MGGGø€Pÿèy†‰DbffÖ¨Q£FiÊ×ù Uý¶±±1444h¦Y^ÅÕ…4$L¼(‰îܹ|ðÁš6ùoÁÈÈÈÙÙ9;;[Óå…V­ZiÚ³\Pd)Nc®þ<†ãw©©©¯vá€^íÂ7naÏz'Qѱçhðž@c®þöööVVVïɇv¥m±ˆD¢úõëשSçoU‘HTfh 1Wü33³6mÚäççkii½õ­4[%hÊd²÷¤a³²²4o“”§¹’H$Ev›5Ð@ 4Ðà ˆ`ìßÌÕÍ›7Kô²Ó@ 4Ð@ƒÊÇ£äì’Í•‘‘Qße 4Ð@ 4x#‹Å™2]H/Á\YYY?~üMÅÊxxxXZZ¿Ù}i…B‘——WPP`ddTd*ú6@ˆª–ÉdêÝo-d2™àgddôFë/@Y———ŸŸ¯¯¯ÿÖjоåÍ(“É^¼x!D%þ'¼ZÞÂ'. ,r¹üÀEz]¾vÜ/Á\) ==½îÝ»W~Éôõõft¹\þf÷¥ãââ’““›5k&‰ÞB&‚›7ojkk׫Wÿ‚ªzxxxݺu­­­e2Ù‰D9uꔫ««………T*U‘¼UxþüyDDD§ND"QNNN~Ís, ~ÿý÷víÚ-}Û››{êÔ©®]»¾UO<**ÊÒÒ²fÍš …â-X~ûí7• QádK3ßÔ@ 4Ðàí‡Æ\i h 1Wh hðfÍÕ… 5jäáááááÑ©S§+W®Ô­[wÛ¶mo¼JýúõëСÃÙ³g=<<€ºuë~öÙg•Y/¾øâ-yÆwïÞmР‡‡ÇÛOݺuë#F¨þ|ò䉇‡Ç¦M›4/êë 55µnݺ_}õÕÛS¤C‡Õ­[÷øñãoë………yxxœ={VÓ‘Ôѽ{÷Ò½Ο?_·nÝ]»v•c¦¯è—Ù­[7//¯uëÖeff ó)))Â>gxx¸ Îàäädkk[%“ÉΜ)”kܸ±™™YZZÚÕ«Wœœ222ÒÒÒêׯ¿dÉ’ DFF¦¤¤ÄÄÄÄÆÆÖ¬Y³ÜKrûöí§OŸzyyiiiÅÆÆÞ¿ßÍÍmÉ’%oÓ7RRR�[[[''§«W¯fgg»»»?~üøÞ½{Íš5ÓÑѹpႽ½½@ôPî¸zõª½½ýÖ­[e2ÙÉ“'ÝÜÜ"##ííí_¼x‘””XYY5hÐàÆ‘‘‘@:uRSSÓÒÒÌÌÌ7n DEE öWTàÙ³gªÆ©Zµê’%KìííoÞ¼™””$”ÜÑѱ"ž£€3gΨ¶¾ÝÜÜ„®®2¥zzzOŸ>½}û6 ££#<G--­§OŸfffZXX˜˜˜úÚíÛ·¯¸‘Bèr€………@£)x@SäíËå))) •óóóóÃÃÃ…ßÍš5311IMM½~ýºÒ¾}û¼¼¼”””üüü"E544 ¯^½ºL&S½V1tØÚÚjii=~üXèTŋڠAƒG ¥Z²dIýúõ+¿¨„.§žc:u¢¢¢ Zµj%Œ9€¡¡¡Ðc‹Œ9ôˆÓÓÓ¤¤¤›7oº¸¸˜››gffª¤zÝÝÝ RRRrss…¢Ö©SGhÕ×!´{Esuþüy !!áþýû›7o>uêÔ„C¿þúëôéÓûõëwýúuKKË¥K—Z[[—{cmß¾}ùòå}úô9w›Ûœ9s"##{ö왘˜(‹#""† ¯*jE sëׯ߾}{||¼Á/¿ü²xñâsçÎõîÝ»oß¾Ÿ~úégŸ}Ö¼yóœœœØØØ¯¿þzÁ‚ÑÑÑwîÜ9tèÐçŸfiiÙ»woÿùóçWD¯ºxñb~~~jjê­[·Â¶oßîççÔ¾}û´´4gggàÖ­[«V­jРANNNtt´‘‘QݺuÓÒÒΜ9³zõj©Têçç÷Á<~üøÅ‹+V¬¨[·n½ñññ?ýôÓþýûÛ·o?zôh¡q=z´gÏžE‹={V$-_¾¼V­Z‘ûñãÇóóó£¢¢þøãsçÎíܹóÈ‘#;w>räÈàÁƒGŽ9wîÜääd—_~ùeÕªUOž<‰ˆˆ¨Y³fjjê¥K—|||222vîÜPAšÅ×®]›6mZÍš5 .]ºôÍ7ßdffNž<¹OŸ>÷îÝçĉêo‡Ÿ_¡2ÞÉ“'+ç9nÞ¼yãÆ}ôÑÉ“'Û·o?}úôE‹ýù短ZµGåÀ]äEöóóëÝ»·»»{~~þÅ‹…ת|Ë–——×»wï-Zèè脇‡ûùùíÙ³§xQ?üðÃ-[¶˜››ûûû3æ§Ÿ~JHH(±¨îîî!!!³fÍúøã+¢1æL™ràÀúõë÷îÝÛ××wéÒ¥³fÍJNNÞ¿ÿ¬Y³ E:uöîÝ»víZ“"cŽ««k½ª©©©!!!‡nذáÂ… W­Z%´á¯¿þêëë«ÊwÖ¬Y111“&M:zôh­ZµªV­Z©‹Â àêêZü+rëÖ­@@@@÷îÝ÷íÛW-µfÍš5j¸»»oݺ5!!aëÖ­îîîžžžE¾qJ)j¹`ðàÁÂ3¸~ýúÁƒGU­Z5áÐÑ£G£££§OŸ>~üø‹/†‡‡Ož<X»v­êò€€�—ž={VP—úä“OŒŒŒj׮ݣG!åÿûßÚµkûöí;f̘eË–ùùù]½zõäÉ“À† z÷î}èСöíÛÏ™3'&&æ·ß~žãÂ… ‡~òäÉk×®UÜÔAKK«cÇŽnnn6lP)j ptt8p Ðª”ûÂ… œ——'<Ç   WW×€€€úõë¯Y³&..nß¾}Ý»wPuõ}ûöõèÑcúôéÑÑÑùùù666AAATÂððð‹/æää,Z´h„ ººº;wîLLL X±bEÏž=µµµÍÌÌV¯^­z;T‘!•öƒ‚‚j׮ؠAƒ´´´öíÛoœ"/²PTÁo~íÚµÇ wñâE[[Ûµk×~ÿý÷BQ….— µU«VEF’‹ª££3pàÀ5j¬Y³¦‚Šêî¬þ Ä�� �IDATîÞ¾}ûµkתüËþùç‡Ι3'::úèÑ£ ˜7ož¾¾¾ðväçç/_¾|äÈ‘Jª§¥¥ÕªU«öíÛ‡„„$$$lذÁÍÍ-  víÚEú¿X,nÖ¬Y—.]vîÜù:" ¤–––Ö©S§äää ]<ŽŽîÔ©ÓãÇ“Inݺµ……EEg]<ÇC‡yxx\¹reÒ¤IUªTQ?aذa*ÍÜÎ;ÇŽSÅ:t¨]»vMš4©´ïر£E‹À’%Kúöí[vy‹îÝ»WB@†M‹-BBBŠêÑ£‡ W_¡xüøqƒ æÏŸ_ä9¾%èÓ§OË–-'MšÔ·o_OOÏaƩժUK˜tZXXtïÞ}åÊ•EÞŽÊ|Žª·£uëÖªÚKÕñË/¿´°°¨¸‚}øá‡VVV_~ùååË—;uê«~‚§§gY:€³³sE« Ô©SÇÙÙyãÆªWõÂ… )))=zô8uê”ú8#|ÒuïÞ}ĈüðÃ…å“ B•*U<==Oœ8¡J9|øð7îÞ½[DÚÔÈȨ}ûöª¥Â·Ë\U©RåСC™™™©©©·>îäätèÐ!a·C5»LIIQÉÃ7¢ººº¡Æ{èСڵk5ÊÏϯW¯^EŽ[[[?yòÄÆÆ°³³ËÍÍ•J¥Ïž=ÓÒÒªˆÅÒRРAáû÷›o¾\Q:vìX– ùå 11±zõêW¼ÜÜÜWVÞz}œ?~„ Ó¦M{åõŠŠ†žžž™™YhhhçÎ7lØ`hh¨:”””dmmÝ¡C##£C‡-X° 88ø<GÕûø ¦ÑÊʪBm•`ÑU›(7Þµk—PT ]rrr~~þ[Bù]µjU}}ý„„mmíçÏŸW«V­ç΃=33³'N´oß~éÒ¥¦¦¦cÆŒ©´rvéÒeÕªU ê³(©Tš˜˜øú÷/GöV­Z‰D¢'N,Y²Ä××WØ:*w´mÛ633óĉÓ§O÷÷÷v>|¸víÚâË^^^Ož<Ù¸qã­[·*¢0ººº^^^fff 6T_@prr²¶¶>þüöíÛ ìÚµ+""">>>**jåÊ•U«Výæ›o*ÿ°···¶¶ŽˆˆˆŽŽnÚ´éíÛ·KéO...UªT9uêÔúõëGŽùçŸV\ÁbbbÖ¯_ëîî^ù5ýúõsttttt<|øðóçÏ…žsøðáÄÄĶmÛV©RÅÅÅåæÍ›‡ºzå?¸ððpŸ~øa„ ŽŽŽM›6566>|øðÒ¥K|ëÖ­V­Z o‡‰‰‰¹¹¹ÊA Òž£——WjjêáÇ?ýôÓI“&ikk·hÑ"&&FÕªê/rzzúáÇ>|تU«Ê§ØöòòJKK;q℟ŸßŒ3TE]½zu‘7â uÆŒnnn¾¾¾QQQvvvûöíÛ¶m›¾¾¾µµµ““ÓåË—>Ü®]»]»v………uëÖí·ß~7n\µjÕ*ዤpÞ£­íîîþäÉ“'N >|ùòåE¦ ·oßúê«/?:4lY½vý¬œ¦âœÆ êÆÅÅ ?ÿ ™Læéééìì,“ÉœÝÝÝ ¼¼¼ $“ÉbccŒŒ¦L™"|Ëÿ+$‰\.W(:::Ev,JDçÎSSS¬¬¬æÌ™cooïé陘˜øÑG9;;»¸¸¸¹¹™ššzzzZYYuîÜ999¹]»ve_233srrlmmuuuËRUyjÖ¬©ÒÕ§oß¾VVV>ÌÏÏ6l؇~Xø {xxÔ®][.—»¸¸´lÙ²ì,99Y,›››—½x2™¬eË–®®®r¹ÜÑѱmÛ¶ZZZÎÎÎvvv=’H$ãÆ{úô©ƒƒƒ»»»‡‡‡B¡°üöÎ3¾ª*kãÿÛK’›N „„H@z' M:ˆT# æUTu}EFgtqÆAQÄX‘ `„@(¡C¤’ÞîMn}?ì9ûw¼IèRæÍú.÷œ»ÏÚû¬g¯µžµvdäÀCBBÄP§NròäIFóÀ¨ÍÍùåìÙ³áááƒAFDÏ?Ô±cÇöéÓÇáp¼ð ¡¡¡ƒaÀ€±±±ñññ·Þz«Ïç 8p`xxøÅ +++**Êjµêõú‹@\\\~~~~~~—.]&L˜PXX(vµóæÍ‹ŽŽîÖ­[nnn~~~RRÒoû[ŸÏ5pàÀ   1Ô–-[z<ž®]»öèÑãbFèt:srrZ·nm0<ÏÛµµmÛ666öÌ™3•••S¦L™6mZïÞ½Nœ8!¦²OŸ>òí9rdçÎsssÅÌ^³y”ˆŽŽ~á…bbbúõë'´zË-·üáóxçwª_䨨(ùv\Ò§eË–F£Q§Ó¹Ýî ~ßçó%%% C×ÐP§Núã?3gμàP/éEv»ÝYYYmÛ¶½Èâõz;vìØ·o_¹äl6[³fÍsrròóóGýðÃwìØ±^›sAÉËË ¾H ,¹ÏçkÑ¢Å!CFuîܹüüüøøøyóæ †   ŠÎk¯½–ýä“O^|ìôرcñññåv׎#ÙnWmYA¶fè´Ù}‡OÌ/,ŽÕÞ;eÌÖ­[¯oÏÀ€€€¤g`PPÐÜ3ðÆ^]W@ôš³X,×·g ÉdºÁ{Z­ÖÚÚÚ¼gàõšÇó‹ìh0®°g`aaáï~÷»qãÆMš4))) HKK»êánÑ3ð†šqÙ3ðª)>|øð½{÷^ê…¢g`Vaõß¿Üæ¨®8½[cW‹Fi”Fi”ÿHHHHÿþýŸ}öÙ¤¤¤S§N}ôÑG:¹BÑh4ZíÕ}£6¥Q¥Q„ †|ðZÒþë%%%åjݪѻj”Fi”Fi”›@ü½+­VëG™¿FãP2á•••WNÏ¿©¨¨gddÜhVTT$jœNç 8¼º£}ÊËË÷íÛwíPZZ*ÿ8xðà ¨"uZûðáÃ×7q{ÃÎãùEæZÎ;wôèÑü¥P“A233ËËËo„QDFFUUU7ˆa©›%ý\étºž={^—ÔŸÇã$Çsëü$**JP-ÇõICà jkkoÀáÕmpp°Ïçt¦ë2€ÀÀ@¯×+þ¾1µ$6ˆµµµ!!!ê:ªÆy¼øáFÇsí«/OZ·n-f<88øº¸õê0<<Üçóy½ÞD‡QQQ~Eô~®U“&M.† ú ‰F£1 -Z´¸¼Ë}>ßU<®Þãñ\öH.iÌâÁ/ãÚk0¼«%F£ñ’F{%ji®±º.õ¼^¯($¿‘Å`0ÄÄÄ\Åy¹ºpñþJª×ë½’~¯¿Ð°u:ÝcXüFè ´Ùl7&•ö‚/šVX,Nw‘¥ ×]JKK ƒÁ`°X,Âhá×ÖÖÖêõú›t5EEEf³Ùl6 †›e5^PŠ‹‹M&“Ùl6Ëp¹\UUUƒ!00Pb@ã<^EóèW‹­¯k÷oÌèùùE–2�v»ýf±q)))#GŽ4 N§óâ{÷ý׋¬-»IW#°nݺ &ˆ•y1uµ7…|÷Ýwò¡.¾‚þ¿XòòòΞ=+ªƒ«ªªn¸ºYæ1%%EöVÒÈ l”Fi”Fi”›@áªQ¥Q¥Qþ¿ÂUaa¡$_¼”––^˃?ÅOÊÊÊÄáÂr}¥¦¦¦   ¡ƒçñ⥺ºº  à:rÇ~¡÷±¢¢¢  à†=JKn·Û ®b0ü«¤¤¤3f\êU3fÌMºåºÈÛo¿ýÄO4êáºËš5k6nÜxy—?òÈ#ݺukT#°xñâ„„„¿ëRßÇ^x!!!á »#þr²páÂgžyøðîb¡ÞÕi´téÒŠŠ `àÀòÌãýû÷oÞ¼yÊ”)QQQ§OŸ^³fø|öìÙÇŽKII;vlóæÍßyç: †œœ‡Ã±jÕ*‘¼–"† Øl¶éÓ§gdd¤§§ßu×]Ë–-‹1bDÝg|ÿý÷ÃÂÂZµj%Ÿñ¹¢¢Bžax×]w…‡‡ ­ƒaÖ¬Y‡Þ´iÓ„ bbb²³³W­Z5dÈ:¼óÎ;b¿3bÄõÙç]ºt /((8|ø°Á`Ø·oŸÕj>|øªU«€zçHOOÏÈȺêСÃ!CV­Z%Nìҥˀ®Ë súôiAyjÒ¤I`` Óé”ÆÆÆz<žŠŠ ­V[^^®Óéš4i’——4oÞ\§Ó9s&$$ÄívWUU‰ú˜ë%K—.µZ­“'OêjÕo‹‹‹—-[Ö·o_y¹X�€Õj9s¦|W­Zsñ½º¯ÖŒ¬Y³fĈ¢õ®»î¾ýöÛS§Nbå�~¯•Åbñ[äò†.—ëwÞ«¹ødÖ¬Y999éééÀ²eËæÌ™#”Ó£G¡ÕÄÄDñv¬_¿>,,ìÚÛ`Ó¦M‡ïN=úöí»lÙ2 G)))6›mðàÁŸþùÀO:URR"æñðáÃâ¹î¿ÿþk?laððð»îºKX€éÓ§;1ÔîÝ»·lÙ2;;{Ë–-À_|Ñ¥KƒÁpå?ý³DºwJ ºT®ÈâÅ‹ÿøÇ?Ž=z÷îÝŸ|òIŸ>}>ýôÓÒÒR³Ù¼qãÆ7öïßÿ±ÇËÍÍíҥ˂ ÊËË=ÏO<1hР-ZŒ7Îd2õìÙó»ï¾«ªªš6mÚe؈ËëÉ/$33sΜ9>Ÿ/>>~îܹf³ùرc/½ôÒ‰'ÂÃÃßxãV­ZmذÁïyä‘7Êg¼ýöÛý*Ú.FŽ;&ƬÕj/5dñØc¥¦¦0`Ù²e›7oîÛ·ï£>ZRRrË-·üùÏ®©©)//æ™gF·wïÞY³fuéÒeýúõ‹-9rdjjêW_}5xð`yüÌܹs—,Y2f̘'žx"$$$22ò•W^±Ûí-Z´øòË/ëG‹Åòä“O†„„lذá7Þ0™LÕÕÕÏ?ÿ|¿~ý Þ~ûí:\F Çe’â§Õ“'OFEEçååEFF8p ´´4,,ìÌ™3eeeû÷ï7 &“)33ÓãñX,–ÜÜÜ¢¢¢ÐÐÐ;w–——›L¦S§N¹\®Ë;'0333!!A¯×‹ºËKºöÈ‘#_ýuQQQllìË/¿‘™™é§ÕåË—ûÍãSO=•‘‘áõz7lØàp8&OžüØc9Ž„„„W^yÅçóåææ>ÿüóÇŽ{ï½÷ª«« ^öC]*ùvÛ¶m³gÏ>|øp«V­^zé¥àààìììçž{®[·no½õV»ví¾þúë tìØqáÂ…üñ„ ^}õUõ"Ÿ4i’¼á‹/¾¸|ùò¡C‡~óÍ7))) ˜3gΉ'ºwïþ÷¿ÿ=''§OŸ>©©©G½í¶Û¢££ï¹çž¸¸¸~ýúÝwß}GމŒŒ|æ™gŽ=ýꫯ6mÚô":RKUUUEEEóæÍ/o¡.\¸ð7Þ(++³Ûíï½÷^çÎçÍ›÷ÕW_íÞ½{É’%7nܺuë˜1cfΜyàÀ˜˜˜×_Ýçóµoßþûï¿?{öì”)S:vìx…‹óRçñÀO<ñ„ÙlnݺõóÏ?¼wïÞ?þñ3fÌÈËË›9sfûöí?û쳕+W>ðÀ›7o>|øðàÁƒ p]në r‚ÇÿòË/“““ûôé“‘‘!Î4‹ŽŽ¾ï¾ûÚ¶m»nݺ²²²ÔÔÔŽ;&''‡„„Èí¹Zzôèe6›‡ v7 }úôINN„xñù¤I“ÆŽ{úôéC‡¥¦¦ÖÔÔœç¯}||Íš5gΜ©©©y÷ÝwŸzê©ÐÐЗ_~ù/ùKrr²Ùl^·nÝØ±c'OžüÔSO:uê©§žš<yòرc×­[g6›“““»víš––VVVV÷ÎÇ LNN<˜œœ,žÑb±Ì;wÁ‚r³²²:4hР{ï½Wî¼òóó'Ož<lذÌÌÌãÇ_ûÝß¹sç\.Weeå-·Ü’˜˜h0Ú¶mÛ½{÷-Zˆ#Yêêj½^/ ´¢¢¢E‹2k0Ô'¢^c>|ø]wÝUTT´}ûöºZ½ýöÛ¿øâ õ<®Y³&..î¾ûî‹Ä…=zôó¸aÃqÛuëÖ}ýõׯ¼òÊuy¨!C†ÜsÏ=eeeiii=zôøðÃÿçþgäÈ‘Çÿé§ŸÄ §OŸ.}Ä5kÖÄÄÄ$''ÇÅÅùÙ5kÖæåå½õÖ[Ï?ÿ¼F£Ù°aCBBBrrrDD„¸°k×®ÀyND=zô”)Sòóó¯cÛ¡{ï½wРA‡ÊÊÊÊÊÊL&“ØÊïôíÛwúôébÛ·o/ŽŒº.'=eggïÛ·/)))99YÌã<пÿäääÙ³g3Fnƒš6m*Ž|9räÕ:gõ*ÜÅjµN›6Íd2©é×ì Ë_HÔÿ¬©©IJJòx<­[·'d_ßg<yòäæÍ›yä‘ßÿþ÷K—.Õét;vìxóÍ7CCCsss###ÃÃþýöÛcÇŽåääÜyç"–’›››””äv»[·n}Ig{kµÚÜ}÷Ýaaa'NœP —˜˜¨þæ¸qã´ZmëÖ­m6Ûµ×L¿~ýǶmÛNŸ>˜˜h³ÙœNçŽ;L&ÓE†ûM&ÓU‰]\‰´nÝÚ¯FR­Õ€€€!C†DFF©¿-;^o¾ùæÒ¥Km6[tt´´òýúõ»^Õ²eKyº¼ÙlþÓŸþ”••å·Õ R¿V[¶lIJJr¹\~A—íÛ·:t(99ù¯ýë›o¾Ù¬Y3`ÅŠ?þø£Óé˜}A‰¿ö'VûIbb¢šR‘°lÙ2ƒÁ žÇ˜˜˜+9„÷ª‹Ø¶¶nݺI“&ÑÑÑÿüç?Gúú믋ƃ¿\ïêÉ'ŸÌËËKKK{öÙgå‡ÅÅÅs´¶te¤ý¢g«_¼ˆ³D¥˜Íæ´´´+VÌ›7O4™½¾²iÓ¦ààà×_=,,lêÔ©ÇöÙg|ðÁ´´4i›ž~úé^½zÝyç½zõzúé§¥EKKKûøãçÍ›wI)·œœœ9sæÜ}÷Ýiii~‡½úÍã7ß|³zõêyóæuïÞýÚk¦´´Ôn·÷ìÙ3 àСCÕÕÕ;v숈ˆ4hÐEžA\]]}Vm«µ:cÆ «Õš––öë_ÿÚ/Σ>²}Μ9iii¯¾úê}÷Ý'>¹¤ ÊU—={öÈv´‹-úþûï?ûì3™‚ª× 0 --mñâÅóæÍS---Íáp¼ýöÛÍš5ûõ¯]RRL›6---máÂ…~$ù.ïܹS}Jgzzúu¯“õ{w´ZíEn•ìvûÎ;¯Ë˜çÍ›—––6oÞ¼©S§fffΘ1#!!!$$ä‘GÉÈ ÚùëW'N ˜?~^^^=–/_n·Û«ªªV¯^½ÿþ{î¹'22rÒ¤IéééóçÏ/,,œ1cFbbbß¾}W®\©V÷wÞ üûßÿÎÍͽ–ª:tèºuëæÏŸ0qâDñùÑ£G?øà1TùŒÏ=÷Üûï¿#´ZزeËìÙ³333CBBfΜ9nܸüqþüù“&MÊÍÍ]·nÐjDD„Ð-pÏ=÷Øíöùóç?ýôÓË—/¿$£"çqܸq………Ç÷›Ç¡C‡ÆÅÅ-Z´hîܹ .FäKuuõÞ½{ M&SÓ¦MFc\\\eeå±cÇ‚ƒƒõzýÙ³gχÚÚÚ3gÎ8θ¸¸¨êjUΣËåJLLüàƒfΜyäÈ‘•+W BPttôÈ‘#7nÜ8þüÙ³gŸ<yòFx¬¬¬·ß~;""büøñ·ÞzkÛ¶mßyç7СРÚÌœ9óøñãóçÏôÑGý¨’˜5kÖÎ;ÅòŽŒŒ¼óÎ;322æÏŸ?kÖ¬ˆšPNII‰x;6lؠƧ“'O¾ûî»qqqC‡½^:Ù¹sçÊ•+ÅP/ò’‘#G6kÖlñâŧOŸ¾Æ£mÛ¶íÀW¯^=þüßüæ7gΜY±bÅîÝ»,XðÒK/ýðÃÂìéÑ£GçÎ?ú裫åh†N›ÝwøÄüÂâX}ῚЬY³Ë8ù8%%Ån·ÇÅÅéõú'N�‘‘‘M›6=pàÀ AƒBCCóóó™¸ãŽ;€Ã‡=ztèС7nŒ‹‹ÔÛµk×Úl¶Ë ³_áyÒ'NœëÛjµŽ1bÁ‚/¿ürZZÚÑ£Gcbbzöì)ŸèÔ©S›6mäP÷ìÙ“••5~üøË Z¬Y³fäÈ‘¢Ïá¥nçív»<÷lèС6›-;;{×®]âŸj­nܸQý6®^½Zè§gÏžê¨Kzzzaaá€RSSzÆÂÂB1â'bbb¬VëÑ£G“’’Úµkwï½÷¾ùæ›iii¢ê¢M›6:uºŒE)›0]Þ9Üùùù" b±XÜn·RhhhEE…x|R+((Ðëõáááeee‡Ãf³mÚ´©mÛ¶QQQ555"Ät"®f³Ùãñ\j݉˜Ç¾}ûFFF®^½ZÌc]­Šyl×®ÝnÏÎÎ3Ò¡C‡’’’ÂÂÂñãÇgeeíÙ³GÄ6G-¹x¯ð¡¼^ï¥:%k×®½ûî»ß{ï=ñëbA¦§§çç燆†¶lÙrÏž=III»ví²Ùlxî¹çÖ¯_ß¡C¿E.oèñxV¯^-þNJJŠŒŒ,,,”ÕË÷q×®]ÙÙÙwÜq‡ÔêþýûM&SVVÖœ9sV­ZU]]}y6U¦   ËhÂ4gΜ?üðèÑ£iiiíÚµëСƒ€d©œ†ÞGá¯ÔÖÖ ÒòµœG±ÔD›Í6tèPaÉGŒQ[[+†šŸŸ_QQ!ú']¡y=ztVaõß¿Üæ¨®8½ÛÕ«ë.WW~"áê2ÈB× ®nY¿~ý‹/¾øÚk¯uïÞ=..îÞ{ï]¸pá•ßöÊáê²Ån·oܸ±mÛ¶~™Ëk W7¬\¸:#ññÇ?vìØ7ß|³xñâ^x!%%Eäê ùðÃ\Ýzë­—}“«W999V«õf™Çk)uáJO£Ô‘ÈÈÈN:Ý çÐÜÈ2|øðÓ§O¿ð À´iÓ® V]_Ñjµ6›­q꯺Øl¶N:©éuåoûÛ„ DÖ’%K~9¬ÂÂÂ:uêt}OkÞ¼y§N.ƒáýÿV᪙>}º 6Ê塇z衇þkÇl6_Év»Q’¤¤$?îRCÿk3žqãÆ7îúêä™gžÝåbw“*h”Fi”Fi”›Ï»*//¿ìfe×QÔɪ;w^BÚeHyy¹øãôéÓl\ŽBªªªDÖÐáp|ÿý÷7õ³ìÝ»Wtxú/ù–8pà‚ìÊÿR[[+ËŒ6mÚt³ôÒ½YæQšÇáJ«Õª«©o"Ñét¦¦¦¦cÇŽ7Ñ´z½ÞívGFFÞ¤jÿ…Äd2i4Çs“ªE«Õj4§Ó#Té]Ñh4â¡Zµjuãœ~}Å`0h4šêêjqHcã<^uóØ \9Ž›7ïçñxª««oºa«‹E½o½ì4nñz½7ãj<¿ø|¾ÿ¾‡ºBq¹\7óó&šÇªª*u¨ìgpõ‡?œ¨­56.ÁFi”Ë–aÃmîsrrDÙJ/‰ºDgŸÏ'>”pëîý>‘—¨?‘¹u›hy­øŽ×ëÔ½§:J¡þDLD/ÄmESfyI@@@DD„ð†ív{ii©Ûív»Ýu‡*î jÝHC½æÕïŸn·»¡ÆÁ¢s«|Lñ‹—n.H]Í«µ*þƒ‘ÿ%NÞ¤î'uN\+ŸK ^­CѼ[}9ÑbiµZuׯ×+W(V:ýFLT‘\’Ú®×ëÅ�äê¹z¨çH©"q1T­V[[[ëw¡|4^¯oÓ¹oýpµvm¿ââàF‹Ó(rÙ2q"¢&;55õ“O>¯¨(¬o`½vN§Sx“¢O V«ÆK¼±j›åõzý,µ´b²Ç 0:N¶óQ[aî‚Aâ—¿"KsÌf³’^¯ ÔëõÒýŒŒ ‰ŽŽv8‡£  ÀápTUUÕªF‘z{AY­VŸÏg0Ün·Ëå’¦ÖãñÈ U¸ÝnÇ#:@êt:10ñ¹^¯vö áJÞÖOÏr.4M`` J I´&X§Ó T“.A¢^”/ù¤bOàóù¤÷&n+׆ÏçS v!!!f³ÙjµÊu»ÝµµµB“¢�E§Ó)‡Z®d¼GþŠÜ¯øª¹}iháóù„Šä¦G«ÕF»ÝîõzåZ•‹S ÆjµNº§óæãÛê+�Ã#âdDä�� �IDAT�L…M0N€ @0 ¯`,l‡"-ƒ54óð)�Í 6Ânxž†1Pë^¨üÖ° Ê¡  ¬¡¬p�FÂfh[�˜üü¡0Þ‚" Ÿ)wßìá(‚†íužWÞSJ˜ß@_hð¦òÍ4 ‹aªj¨õÊÓpÔ=¤;ÁCP¯A´M Vب<ã ¸žV.1ÁÛ° R”Oba¬ƒÊPgÃ0^ƒ>P}Á+ ¸à„¢œºó(VÀ;nfé˜é㈗ ˜+?÷º21ÿ¡ èxÎ˧>N«W,Ì”`U¦ãgª¤îtˆ•v€îÊP›À+ð¡²�¤VýVÎ8x4ð‹R« NüüÕ+'šÁq©ˆ€>Ê<>vøX¹pX!C5‡àO~&ÏoªÓé¤]P¿½ò(i ŵҾ»\.õ&TÔxŠOJÉ„„Ëå¶£®Áßñsz.ãˆ8Ž’’a+++/ãn&“) ,,Ìd2…„„8΢¢¢ŠŠ yb€Äéâèt:aפ_",Ûí&»^ëi6›Å\°Ù±^¯×étõB»_Híâ±°!ïäòD«Õ ¼š×étAAA‹Åëõ–””x½^1~© Ç£öÏêªHí£«×‰z Õó¤~R«Õ*¦ÃÏÏ“ ÞápÔÖÖ:NŸÏg2™Ä>IŽ­^º.\ÙÁ nØ)°<à3è î…Ýð5„z‰†?ƒfÂRX ‚¾…8ØH¤A5ì†jðÂhhû` X!\°†Ç¡ öás�è ga'Øa;8¡€EP.Ø mÀ»áAH…­°à…4ЀxÁâ /,‡@˜ ã`| …-°ja%Ã0ýw@4è ¶Ã°\à#4‡ð/°‚~£a <à€LØÂÛ0 ¬p ºÁÐŽÀc cá~8«`„Ái8­á~˜�§¡ZÀ`¨…N= BX ¾<†(‡Ã`‡�%°ÛMohá!Ò`7Ü6øL°J 9ìÎð%8a ‡—`'x 'D@¤ÀK_À#ð>l‚Hˆeg/8A§¬ A%a7L]P [Ánx FA9ˆøõ.pƒ2àQø'˜ÀÂLø&‚¶Ã_ Àð$tU4™¤€J0œ_AX`+t‡Ó°�„ô0ha9„ASø8¡šÀ1Xè•0Þ…CuÃ;~¯œ0µÒËQÛk:çÉØ© £ÑX[[+n%1On–…YQoœå$ªÇ)·ðÕ{m”t·ÚZ +#oR^^žŸŸ_XX(þËn·»\.‡Ã¡Óé„k¨†™z¸^¯7›Í‹%$$ÄårÕÔÔ¸\®²²2µ7£V‚ð'„]»xÀÐjµz½þJ�FmëýÌëõŠéü 1óü‚±õ:sbÈ{ЉS#fAn_Ôž·Ûí ¡F«Õêõz«ªªäPϾD÷ËCÐz/ñ»›Ð³• Ö½ÄãñPôsÄ�× Œ×…«H°ÀA¨ÝEÃè�iÐb!Ê`/Øà6øFÁrH‡|xÚC1ˆã‚a$á0à (ƒæðT‚Ò!&Áoa¤ÂÈ…r˜; ?|oÃÝð4"èËa¸¾Tžâ%ÅdŸSÜ”HÈVþ·Š¡) ‡Up¾`,Xás°@5Œ€Á¢\å€j0C"ì…÷a²b.]Ð D³AÐ>‚6ð8áPÇ@ UÐ n‡õ6x ÎÁȆ¾ ƒ· ]1 ñp+d ˜ýa4…ÁZø=äÃÿ*Ømð-À¯”Ožƒå°î„ÕFeö#ଅYð"l†Õ0î€lˆ‡Th k œ€#àâTa+Ô@[X&‚: W 6J¡%˜!öA&„Àm°ŠàI˜½ÁïËåªüñ!<‡á3è »ßúÀ}Êׯ€ÆC>ìüYƒžðñC�ÜÁ·ÐS¹j ‡ð‚©°Ôt½ màô‡4‚.pHÙ7ô†µP »¡̃D¿IPP°Ýjë&BöƒAà|ŸÕ›Yu¬¿îK{žBHHˆÉdŸÇ¥R«}>Ÿ`_ð?ÿ¬¦¦FìÊN§t¥ 3™L.—Ën·ëõza@ÕÁÉ€€€ÀÀÀààุ¸¦M›VWW ‹ÅrîÜ9áÁèt:£ÑèóùÔÝ¥M&“P”ÕÃóƒ:é[¨ñÛO$’I÷Ëï— *P‚ŠÀ*5ÂÕMð¨ƒcuG"´$.q¹\‚.+÷ R«b[`±XÄqQQQ6›Íív‹X¢p¸å ôx<6›MFçŒF£Ÿ*ÎÖ«Wä—¥gn4-KqqqEE…_xÖo“!¨“ë¡nÖ³!¸Ê‡#Šù8®ÀU3øÊ¡ž> -À>8ÅðtP‘!µÍá0 l€ûaœ‚‚[ šA.dÁ-ð% ƒpðÀ¿àØ ;¡ìT‚`ãa9,W<~Pa•ˆ’9 L+34WÁ•4ÐÖ)_²\Áæ0ˆ‚¯`ÄÃ4¨…°(Á &H‚ð>|íȆÍ`„|è  zC!è¡%„uʯ|è�G”_½!ÂÁ ý R¡ zÁØ¡^@1TÃ=§ÀѰ`ˆ>FèÊ3އ¡DÌîÏa l‚BE ©àl‚‰Ð2 ¼½¡v�° zÁ�X¥\¤€ bá44ƒ.�A QHQ [!b`/�9 4X)ylÄ£0€ãP¢Â¶ö°:ò”.…—5Ø| …Ó°L‰Uv…p š+€½n…<øW}è-aŒ„@Õ3î•ØÍ¡„BG?P1 œêâÕj Öét"qUYY)’"U#^f±K½È=¯ðQ¬V«Ýn/**`)E"Àât:ý¢”âZaå.þ’pN€œÈ̉0Ú¥&ŠL&SPPÍf.áA^äSKS(í¦0v"&¶2ý#ýÈzo(^†R¥U­ËOº’û ‘“Áƺ(0Ò`0È,ŽÏçýBë‰ÃáqÝ‹l äñxBCCKKKM&SÝ]‹Ì]ÕÕƒÌY^| D±®$<‹ÛFDDX,–€€�ÁÁ©®®ìÙ~®ú±ÍªÅëõ®zC:tL†*–n¥òí°B¡3œ‚ip\P ½á,”Â&­  –ÀYX¥ì÷= M D õ ‚Jþ¬¤@9œîЊ`¾–Þ0ÆË›¬®ÕÐ ZÀ ëÀ ¹*«§N“x¡B7hy°Nõ¿¹Íàœ‚S`'xàh ZØ ·ƒ¶8­ç÷ð¹âºyÁÕ°²@ÃàU�ž„w¡ÎÁ½à€SJâ¤x! VÁÈ‚‡!:fÀ— ƒ®°úÁÇp"! Ra¬Uv Zp+©µ‘Š÷$A<ôQlk¶2#FH‡ï•Ð\p æ€Â^T2:û¡Ðlð<(жÙ½`/¤€b”ÝÏ 8©�fˆ„hHS<§¯~¾ [€8`ú¸örUßtÂ,ØgTá¸úèé#ª¡#„ÂØ 5aÐ>„isàŸ°WµrÐñ—o}¬…1P­(' FB(,SBØ ¬k‚E¬FâûGáRDDD§¡¼¼\¯×Ûívñæ_†c¤ÑhÌfshhhÛ¶m­VkIIIxxx~~~qq±_Óšš¿^yꑄɆ~ÅϼªÃ8ꤽÁ`¬ºœ‹†Øe6›Íãñèõz«Õz©µZ­8ûÑ/éRו¹$‘fT࢜M«Õ*£j’¡g6›M&“ ™øeÂDøÔh4ÖÔÔ'I\Ø*È`Z½14½‚¤ \ÌÀÀÀ°°°ðððˆˆˆ   ·Ûd6›ëRíå©Z"uäç(«c¿çɆ÷ 9ªAð)BCC‹ŠŠ„ÃWï7Õ+D,W±~ÎWw¥Xv‘é;~nÇý¤ A|Uà„J(‡*'ÿ¬½)°žƒeÐzÃ^¸ŠU(2Ò”hO¼SàßP•P$Ü /Ç4œ|˜¥à„È¿¥PÃ>%T¥Æà$•´A(l/äÃ_Á)0>Ä@Øa+�ƒ! ÞƒãJÄï,„A‰*œ+Áƒ#éZΗNÎÀ¿Aå ÷a$˜ác°Cx * -À"H‚ÁðäÀc¡-|]á>X©dwDî$ž‚° þÞ…w!FTB/˜�m`+‚Þ`†8¨„×Á ga�+ G îM‚ÏÁ ø;t€!*U£8©;À&pÀ9°Ã\˜«\肽Ð:+šúC¤Â& ý'p(¿8z©Ü)aàƒ "Uy¬^@<L€P ]µy˜{aL‚ðL…*ØePË!\ðwX Ó  !6‚`8¬ðèC§ltšÂ„ ø €Ž0ÚÀNH (…Eð7µ™«­­À£æU[­V›ÍÖ´iÓ–-[ ä(..>~üxqq±ÈÖ¨QAD¥$Óìü~†ÕjmÚ´©ØÒj4šªªªªª*»Ý~ñ;eqj­Ëåª/ëP¿,º¤rèt:Éè»`®H€zMM×ëµÛíÕÕÕÅÅÅ~½i„Í>Édi5cBø.j¸RÓêÎC"¿TôöÔëõªQ_þºŸØl6Áÿk0„i–aɆ¦Æ-D>L†•Lqµx<‚‚¡×ëÅQÚ‹ERHèÖåÝX­V?ôù|b!©‰~tVñ‡ð)ëÝF½^ŸŸŸUØ%uáª5t…7 ÂÀQ0ŽÀ@ø�“a3x )$ÂfˆPìÔýpR L&𠬆m°Ž@1xa:L…³ð< áp‚á+ø¬€÷ )¬„ƒ°�ÎÀß ØÇF¬D»ÃYøÜÐ ÚÃ?nH{h¢¡Tœ‚КÀ"ÐÀ'0jàSøÆCO˜ßÀÇŠësàGØQô>‚4DûÈ¿B:¼ X ðGx§ˆ¿ûðÀÃð4å?´ÉöUlÜËð{è{à!ø3d(¹œ—`ÄÃð!Áj…ð‘ð9TÂvxÂDH‡3;A^xVƒ6ÁÅÍÒi0ù(ƒoáqh KDÐ z@(´Á _@)4ƒ;àкÃnh½  n‡b˜}à6ørà ØAÓàȇ�(ƒ ˆ„»á3ðª XYoYðx`;l©C¶ …îð”*î»,otÃ�¾‡Mð´]Ò!&À ÐÃx€ß+k üjà]pÀV°ÂBð€æÂð“@&9P«D¶›ÂZÐÀLX Ó`3ø`1 JÁ e~浬¬¬ººÚëõ U;â5ñ@aŸ­ªªJXy5³@]†äõzéY½/¾HLLL«V­Úµk'BL:®´´TmC…Å1òX³Ù,†$ }½±¬†²VLªÕÍíûIee¥�Aß8vì˜ ,TVVÖÔÔTUUù‘D„ ƒÁ`ðsÔ5=òËõšÑºgH¹Ùly 5“Þï›Â‡“ôt1ÉÎWSïï\dìHÈÈetlwkHÿ¹¹¹Z­öܹs§N *//////((¨¨¨¬§Ó)Xì‚YZï´ªë½êejȧS‡þünâñxJJJªªªŠŠŠÊËË‹‹‹kkk«ªªå=$$Dp…jkk…êÔµ —W?Á_-I^¦@¦’ɸ(ßù¡¬P>©ìµ‹ lQÂhBŽB9´†q`%J:ýè›`&lƒ“;Á-!L°)÷)Ve2æÂ<Ø­¹úENK¼“` ìSH+`,¤B�hàNX�Ѱ ° &A<ÄÂK°�,ð=xa˜Ž�7EZ:yác †6 [à×0 P–Ò›%'ÂF¸ÖÂ`VXíᨆQP fÈ£—ÓÂ`øRaÖ 7q(dA&Xà6V·Ãï`.˜À [!0ÀKP Û´¼âe¿7á1ˆRbkm  ¦CŒ†¥p,…žJ˜˜/À@Ø+À¦è­t‚B¢’œ% @[‚Z¸]ñä†Á ˆ†¦p„á¸N׫jÈ‚ ð=‡a°LÇ¯Ú ^ø Ž(W­‚i°"¡ìVœø°4 ÙÏ€rá¤ÂýP ŽCs(€½`‚~ÐÁÓŠ¿•½Áƒa@¿ºÌ@£Ñ(³Ù²Èh4Š›Í$ eHHHMM  ‹—Y}7‹Åb0DºººZo ƒ"£p"Tuþm{½LEuªü<VÎsBRÝ8¡ÜË’Y$½1T1ìòòrá`¹ÝnW¢ŽJ F£Qõz}ee¥pDü°.ÊJ¾åÿ®[άÓéD*±!ÊIÝâeŸ.—K€Ÿð¢Ä®Ân· ¤Ó*9„ jݹs¹\b¿"̺pÙÅåröˆz†ÊÊJ±N„£,¾,è"Úìg»x¿Óh4Êê@éfù)_P'Ä2>¿s/wr‘Ô[ÉÞ\É ò¯` œ†t…?&Ð/^q¹V¨¾þ1$ÂÃZ4>–ø˜‡ nƒƒÊ7w@¬Ò¾9X!"a9´€ý€Žû<ü�'áü ÁåsJ‚v^H«°A.´Vªv€µ0¶À½à†}0" háK°ÂN¨„-JÄ/G²Ôܬ†1B¡t`„Ð šÀaeTÝá˜â¦œV€ùŸª‰À—hhÛ€°à6¨V°J\ø%Ä‚NAâØ·À)‚hø_¨€ÈT’ˆ­ �öA�¸áU¨„ˆòð<Ðò`ÔÀïaœ€uPEàq°ì .pÁAˆ„©P¤%ßÇ G! †Ã"8à èa ,‚¹P¨xQ£àÅ!ÁæÐzC+øP¢ßú¬Ri¯�¬`…PúóÝI,´Qb¡g`tpúÃÊ œ c ÊÀ©=`%œ„ïÀ®D{+06�~‚µ ƒþðtmÐ*`ôŒ‚ïàa¿èÚØ ©U‰0£F£±ªªª¶¶VØwAáA¼º2 _"­- Ÿˆ‰y<žòòòììlÁï(++«¨¨¨¨¨¸Ž}Wu::ÿ$"iif\.—„(iC+++EO8õÑ…&“Éb±ŒÔA‘ös:"C£Þ¤«áSÚ>iUýŒu=œi½^`áÅÕ„ùÀÀ@‚“QIë—?çgñ¢Ö5îb<âZÁ\ˆåv»Ï;g·ÛËÊÊŒF£ˆB ´w“õ×b#¥öMÕŒÉ_U`É€ö#ºrú*++eL.ÚóT¹ÉHšL]ï¶A¸òð7è«ä €ÍJÅR"l ƒipþêc4< AдP $ùã@+àƒþZ¢}äùXa3ô‡,ý!T¡]Õ@€¯)F§7ÁhIp²Péýa%œ“’óÿPõX£`8¼kaªBvï«Øå3 ƒ08i`†Ý0ôP�YP ?BgH»Šj8>…I°S‰ u‡|x ਄0À¨… DÙ`ì…4h ÃRè­übè¥(<|pJUll`*|OA´T¼±3àƒZø„ÍpAXÀ“a0ü`?LP†j‡<¨UêgÇC-ÄÃYe=äø˜wÀ7° KÉöm‡L‹™Ð€nyà�ì„ÃÊÓ`¿’’" x‡Á0À£°J¾ŒÐj¤*¿b‡‰`5Pª¸tòÜÈï šÀ@8Í¡B­ô»P1 ¡°ÜZlÐAÃí^–úÈ„‰ÐÚÇp7TAkxþè*B1bÛ^QQQPPàõz…A/***((¨¬¬¦A¯×«=QLc4CBBd7E±m—LB—Ë%,»0‹ÂS©¬¬lho+Y‹êº+i­ê-1öËTÇ9ð³A<)Ûív �“4¿†PV8¬EDy©HŠ«¥^Í#¯ W’ y~rv½›˜Åò‹žÉŸó¢Æ9‹Å"f_Í!^ˆp1/’ÿyA.©Ïçh¡×ëÅVæbh–~p%Ç/´ê×yëüpÕ[&�Ì`0ˆê·‹áà\®z€¶C- ‚£0ö€Þ„÷al†bH‡f°à Øåã…ÇܦÂR˜ßÃ#ð ‡.p‚}|êÃÎ@_(óòˆ‡Yðü ¼°’á3ø5ì€P«0úÅ\ ^8%J !_±­ï(„`'ô…jÈ€,¨=ÄÃ{à…· K©Vþ :À×ð9x`DÁŸà,œUA…¾3øÀè aô³p ©°-�&ÁRÐB;xšAÕ°ÕÇ;0RÀ F˜Ga/0*<ˆYð+LÜWÊG° Â!ì°†C,Ì„õ0>…( †¾°H  ià'8£ÄââÀ•° îƒ/`,®ðè¼TÂIx šÃ8‡à¨“çà5Ø÷ÁVØ ?ŽÂÕdݹЊ 'l‚*xÞV-ÅTÐ($ˆ*ØÇ¡*A°€r`¼ý ¤šÂ9xQa 9FxÊáhk¡ú€J!úÁjØ÷Âß¼|­a”Ý>J2Ë?”’s+DÂ8åðÛ fé¥'!3Z­688Øét––– ¢n]NhhhHHHlllPP &›Íæââb™RïîkjjÊÊÊD2@”^5DsP·h.*4¤R»E DZ ÌÈ'øèêÒ¥º÷”]ê:+Âÿ¨Ki>“°z"´(ñãjYü òEâ°.ÏPÂñË3‰L›Ô•T…´×~ÍýdÕ°ÜI´P7ôÏë7ñ§Ó)¸à‚ÜIpuÁ”¤,ä’èe±XD¤±¡0r`` ¸‰P‚V% •XÕ¿h[uìÓ&±ÊîÖÚw¤uv8ŠàÐÀ`Ø G 2 ‚à=È„#P á$[ɯýOןöp Šà6¸~3|90 –@{øÚù‹‡Oá6Ø Ûa8!�â¡�"¡l‡jH†På×wÀ XÇ«*¸ÚµàY]a xÀ Õ°ÌÐ*`<lTº@‰þáP£!>‡u`…8m 3¤n‡A€*Õ/Ò-oƒvÃoàkè Fø\ÐNA®Òi:è \ñ�) %pö4çåJb¡RÇ ^§5 #NÁ^ø^Kw­¼X!DÃ.ˆ®¦#L„í •ð dA2´†·tŒ…]ж@o˜á$BX ¥`A`‡#Ъ R(=öA<| 0’ tÐŽB.¬…Ö0Zªª‘öBB < A4ìU´7ò!ÃZ0Àƒp²`Dª”ü4äBgø ¢àNȇ. oÂpƒ Ð 2 ~“a”Á0Á4È=A«¬íO =ü�…0A9˜ î‚{`+DC_8»à4x!�šÀxÇÁ «à”)|È_MžL§N�gΜٶm›_KÒ¥–TUUÛíöòòrQ›b³ÙD•®Ø„ŠîD 111N§S|³¢¢B¦¤3!°PR¤Ë¢ƒ´§ƒA ¢*HJ]³@S·Û­vYL&SÝ*]ùñ ªÙbõvªUgï…Ï!‡¡ÓéÇÁår‰8gUU•èRXSS# ¥ bÊbdy7ýÏE’#¤öÔ, P ²nBN|S]¤nh$n%2L¢œNw W~M¶êÙ%³F€äÚ¨UAö UIB©Ø‘ˆª@wñ€ê6`;…ä‡wF£xIGŸKÝŠï×Û“ElkdE¼Åb/´!”&êEä ¦¦F6]´Ùl=úÜq$Ûíª-+È®®^Ø.èc•ôÕpø šÃ@(€)µ`øŽCS�+`„ÀwÐÂ-°DC€†.P«¡—?C„ž¸öB<| C`¼?ÁÈSê´â¡l‚±à€‚::É€&`ýÁ·*Ìø8x�6Á!ç Làƒ!ßJ ò :ƒ>‡–�›!úA4TC,”A¥oS1 v òÁF¥‡ zÁŸ 'Ô‚&C*A 8!†CY%™pNøÀG†p¹|ü[÷Ÿ§Ž6‚…¶µ”ÁZ&ãd@>X 3T(.ÔÐ b}¬@ ÀAØ =,p âá$†8ˆ…'áT€à{I’3ü ¾€{ vC0|öóʶGÈ·)ô¿¡P ?AÐÀýð=|a |¥„sÞfŠV§à¯P6è?B¶RøUn(Ph"-j†“ «•ro§RªQ'`(L†2(†T°ÂŸ Þ…ã¡:@¡BP ‚í0N‰1¶h`, WÃUzzz½ Ù]Tì|Àˆ|µàYøEíD ­°eeeÅÅÅÕÕÕ¢†T�O@@€Èa�VFÜM4FRsš…Ý—e=ÒäÉ ¯ús±‘M Õ´1QX&­§:Ô&\7ñ€òÂ|;N»`}»ä�� �IDATÝ. ÔÏÔÖ‹ 2Ì%Ü‹ššyÔ‘lá*œ áS Gä<ýdÕ�/Ù‚ÿ"¶”×ëbŠm‡D,³Ù¬nc(D¦‚¤B.®$NH=KÈ9CôzkÅüÜ#9¿jP½ÿºŸÈ q]]v&DÀŒŸˆµz7#€ShI,QÉI‘ܱr"""ºõN’pU¯ûÜ tJ7š“ÐZÁ)¥LXì@å…!|Ð ÆÀQð€F)M€‰œ“†�£ ÛÍbè k ?ŒQÞù£�|Óa<l…­pÄCsh åÿnÀM4Á0%ç$*š›(- D쌪\Ì�¡¶‚¬ 5CÏÃ&°À§0´JeUw…‰þ $ÂO�1pA70Àm ŽJ7;ô€f Øç  VB8:eðMÀÊ×tJçÖyÐÊÃ.8CjÉ«åÜ ?yh[Âr˜ßÂhx&Ããðìƒ%0B{8¬cއLX§¸Îw€40&Akè°ZÀ9È€Ã`Túb>wäÀqH€É°Z+Tr)] -¼ÃáØßÀ*jL�xás…«¹òçóX«@Ú>…ã— ü×z¥jXTþº•Új B%Ï·‚•ú9°í­ Õ½ œP*š¿P7]À §aTˆ0áô‚p*,!—â‡m€&Z&û°û¨�² åKOBôð–YéxÕ±q»ÝÕÕÕÕÕÕááá‚W7Ø"¬Oii©Ø8_*'B&ðÕöBÆ÷ä?%KBrJã%»©ÊÞí]ä÷ÕÐ(˜âjò´Úª£dêvÀ²± û p%;^á‰}“Í/.OêÖÞ ·O"Çy~¢í…úÉÙ“è÷ë~íÇ´t:û/¾yŠŸ†¥Ëuñ1=YŒ|IW5”»*-L„áVøQÉIØ`ìT¶ÛÉð1A&Ô(Q <¦P¹ò”Æn#¡µ¼ … NxöÃ)x\K4è¼ü ÊL”X°•‘5°"À' ÐoZa¢Šèmü¬Gx Òø\äÒe½sX«@ %©ÁªåA§ œ ïCróÁ°î„Lø ºÁYx¶A*œ…¦Ð Š•Ú#уΠéP£x?ã4'±„Ñ>ûàßpR!g‹E£•ÚÕ2ÅP¶…"†˜ óA »uŒó’ê£ $Á¥É^l„!°2¼ÂPðÀHÈ'ì€`„C+XVQ°n…SpvÁ¨…,HUVBwÈD J§²DâÊNÈ„LGá_VíÀJ­›pk:ÂeÉ…ÃEIÕß[!¾ø—RŠ~C…Òe£&Áq„¯ãA/+¡Ú ˆ†¯µüÁûJåVox^…rèJ1ø)ðÂðÀ:åË ºÁ·0ÆÇÿÑvßqV•×þøßgf˜a H/Rl`AD,Øcï%‰W£&Ñc¢ÆÜä¦hÊMbc®‰£±÷cA%Š„¦ˆ"Òé}€˜Æ0sÎùýñðì윈7÷÷ÝøÂ™³ÏÙçÙ{ÖzÖZŸ2›Õ”riùGr*HWé¿Ì¤9j¬“C–àÊËËkkkƒa]ccc˜íŠUYYYqqqÈíuuNÕ.æ1áswé:û¥'ûñ]prƒŠ`ß‘` Òâ‰P2�+¨EB}êÈ�` ïœTWiP‡ß7½Îá‚"Zbõ’F¬µÇï"]¥s@èq…Òme_ú–…¢$—ËýK Jò¼%OÑ.ntÁG‡M@Aû—é*<o”†ö¾0á!onnNt“û’œ[P5î:7wx‰µqËFåßå ÞŽ­ÿîŒf}9˜Šˆ[Û›6KØÎ4,rwÞ‘y™¨W»¯Ó•çèO7QŸsCôùöv3ÚÜG=ed"´:ßâ·à"&òrÀ›p9ýs®êí$Îg"Y®¤ˆû¹•‘\Ìv 6ïò¬ùQëýë´q ½ø_‘ãžâ=ãŽâPÞàFÑy¬‹Êè!ž~…—ø,ëù:·9/㬬ÅÔsýÖËeý-Ê+¬£”6æq#¿d!yŠháXÓ“'Èñ!¿ç§|–9}ò–±‘Ò@wFæs\Ä{yS)æTæD¾E–kèÅu¼J'F»–;XÉmdËÜ¥NâiÊXsêäèʳ´1Н2—,żΠŠÈ²µ<Ë•,á>n£&ºñGê™G€ƒy;E8 Ç lM=�Û9Œ Êø5ã±6Jp—ó×üŽVöjÖ³…åy¹ìŽ{tßgÏÒƒßó,q$M¼G–7™Á¯¹;fÖ°é™L·¼ ®äü† ÿÇ1~0ày(”Aç&àßB7©©©)1X /A$†LíƒT‚(ÐÁû7€ @#™·'›úC^‡Æ};3™üôìŸD¨=F#íUP×”éuH¦e¡7Œiøu(‚Óö‰ޒȇ'ôᤩ•FÚð«$…–®T’ËK ?ÍbîÌÆ¬ ÁÆBAì{듞^¨qCe–~ÿö…WÒ'loð˜ü#ž)-ÙÁ„®uAÛþñêLoò4rg²;ÛØ="¼;SÅüž½˜éJžnœLïvwVƒÆCÄ1öî¦÷²ü÷ŽYW¶Î´Û9•5|+óžÌ:ƒ5ÜÀÙT²6ºG‰„£ˆÔs]ÚŵZž¦‚WÙL_^adTóû2‘ÜÄïÆ> +[Y|¯s.gò$²Ìn¼ËÍÌb2ÝéÌ·SæAÜÅx>æhZ雳…»ã4ë›ü®MŽ­ü–)<ÃIÀön„z£tÅïÄ(ʸȾyqmœÊáÚs¹0vÞ‚Þî¯x¸Ø²œ­y-4p c wM¬àŽ¢:*å‹ L°†xŒSOO>Ã=Q1äBnåï<À¡üŽnÑÓkŸb»uqAo€[XÄFžda5Íæi°CèÙc«ÂæÈßêÓÕcq©§R”’“èÆù|À;lå»y¿ˆÐ›}£Ê-Qžÿ V³V¶1·ã¶‡°œ ¼Ç/XËF¾þÆO£Êþ¹¼FUû?¥¤5Ÿîê¤ÇBC…° ¾‚¿ü–––ššš$3íÁ¥¹M{l á ¶km¦(ÓTÝÔiu§ŠÆŠFNÁíñ~»(­Â¹–É”«�ö–„é‚ú —ËIÜ4³'œŠ›1Ðÿøâ±I˜¾Ú4<‰ža1P@úÖ¤Ý+Òù¬¢¢"à­̲}[µ Gׯ’^« ‡ ®¼�êž™$ާ“AÐø/`='-åP…aމŠD9%4ŠÃ¿Ü`‡uprO ¬““”™¨Ú'½ßM¬ ŠY\\t^Ú¯g’;¼ªö骒Æã,£œ›ù€ï²ˆg˜À@*i¥ßf2+XÅEºç Ì{uÌÙd§êúcŸ–Gì>G·C\¸Àㇰ”ar÷è{“gäEc_V³ŠeÜ¡Þã¸â ŽbµÊîÑÛðo”¦bëlƒùöåÅ"#òÎÏïv r#ĉläb ›Ù'ªäÝÀt6ÑŸq¬ +µ4suìÿŒ¥*V–¢ÞÇT†ñ«øXÆ"F±–›8®ÈؼÕy]x†ýÈr!³XŸ"í=«^¥‰:S ÜÊbÊèA?eC¦—D¬f#ØÄÔŒ 9ç½I1{³œAT2„µŒc‹9œ»XJ·¨s8ˆ÷ùväœñ=–Åv\h¢f™Ìb†ÓH–å,g¿.ñ~_OÖÄP~ÀÉŒåeºÓÂç¨a)#IŸ(XŒñ ë‡Q™R¯@/JL7êØ•,†Ó•çy|yq(x“{)áF®¥7/ùvÞyß(Rž³543—Lf ü‘~,âÜUç÷âÄ8[Õae“l;Ô™NW!N%ÎRÉ+Ã&¤« ûl¨XŸ)Ëlí·uóÍ¥-¥]×wÍËç²¹Î{v<ypņ )Qíÿy§$&ñ4Q.Oã÷ RW¢èú/Ää7©6:l¦¯0)&vQ]%øÃñg“Š!”¡ À¡µµ5ª™é©O�+¦ñýR6¸ v£ý„w YØ„9bb|ü¿Ò§O/’:,{…Žè®q6' \@·nÝJö–––ÒjÑÜÜœô÷’§7¬UZp$]<¥+¼äF'˜Õ‚ò·=w8- Õþ«í¬_9;¢ïÖEdóDæ0€Z†Ó—8 uJˆYe<©,Û‘<¾}§½}´ŠnîýŠ >öS†gü%câÑ*‡úä¿”äáSéÏß8ŽÊ}Œç}z²ŒeT²œùqX5‘#•¢úÆFÍ«M&WSÇT>G–‡SRî1¸ˆIŒ'q U¥v5?‰´°yÎPæó.=Ø–±2ãW9ËRµÃô"§²š}™G'NLÉ Âs,âÔ(~!²‹Â1„Ãy€œÄ<Š#ÿX1“Y|Ž“b›«†PDÏTÚ~—nlçÏœÇ ÞäT1qñÄåt¥$r×fÅÌ:/&ÇÄAÎ@†D—:>¤G1‰£®ÄŸcø“¡?¶Øs¡7¿f¸€p‘g²’Ø›IŒáC¾1ödwVÅ_dpj¡zÒ“™mž„&¦°ÏÓ•©œÊTöc.ïòÅÈ7—šå8æ0“óxŽÔÄ2î‡ü’‡ÙSYÈiü22—ïb$GQüþå@"­é°‹éN‡Vª¨ï_¿ä´%å›Ë;5vêÜÐy¯I{­»2_’ß^±}ÜãZ[[ç\0gÖ峎¸ëˆN[:%˜‹¯œŒÄÑëÄ© j„D’ng%PÃDC22é0ò¦sv‹!'^”áÝ!¾ÓätÀM׬ÿ/U!±Õ××‡Ï ªêIã.q)k¯7öaÚ_^‡šUÉŠUVV†÷ €Æ0€,HiLèÿÜáOÿâ0›Ü™¬Æ¿œl¥ÓU✤ÛP'…~‡½ÜöMÝü¶}O˜u¬‰˜Ý… äÇÔs u)ºë{¬‰ÿœÁªœ¹y/ýCÀû†é~ðªgÊÝþ±Û÷÷ÙœEgíw×Í=7îãÎåÆßÕoÛé~t†_¿é¼ÆèdQÌÙôãbÆQÇ¡Ñ0¾1æªÀ칎ýcZÝÎÞa7¾ÂÔ°Š5”p! 9{åu"K«cYÍtAð!ZÙÕ}Þd(›âogð ϰŠ94潚÷LT¬å;FžŸð ÝÎpÞç+Œ‹ °«r~Y,ÇœÍ\Ѝ`$ϰž/q'w°ŽœÀ—ÙÝ4ðæ³7cÙ/5¨3|žN”q0 ™Çò^Ï[Ee´‘JŸgòf0•zq,'ò {3eÜJ=«¹€}ÀL泊Œ‰äbjM'~O#DíŒ~¬§‘NtãsÂh^¦&ÞÇyÅ;,b+“ãriDoò†8°œÃPêø6 YNÏÔ}ü¾ÜÃTŽ¥SþŒæ"fð휱yÓØ'·Ã,æ³ôসÙ“c¸ Zvmà Pu°Ž?2ŸsÛïÛƒ-¢ К:þ;d¤ÖÊÖ™×ÍÜÖuÛÐ7†uxßy}°hø”áç _½ßê)WLÁð7†g+³S¾5¥½"CÐkGp0ÙEÜ/-- ¾Y 8;IWáÂ’¨XûaXòú„Ê“.Éσ}_yyyçxà,vÆSîðH.µµµ5ðdw:±ßùohhزeËÖ­[›››ÿ·…õõõ í?·ý­ ß:”kÉøª °+èâ&’N;»ªž¾k­£´\…(n’,Hyyyx“pÙ»¶èüz´´´466ðŽÛß¶m©½g6¨÷ Ç›|‡ò`´5z†ñŒä%æ1’K<š-º:ßš3¯wå#NßhÚóv/¾pm~]Uî[¾‘É]8N?^Y³þ¸\ñ=ÇeÛ* úXÙ8-ˆýèÂF$[Idævg ­ÜÌhd ßd‹˜Åj.¡Ýø-òÖF—úÎÜÂõT1Ÿóø‹ù>Ïqc¯sJT<:œOØÈùÌcõ|‰Wòz3›Å‘×u)÷ÓF-ûó6—DpÄj'GnæiZÛ¼ÂR>Ž@í½M=kxœÍ#œÂRÞ¦7_ä~K)‹S:ŠWÓʯ8…·¸„y–ãx§9š’Œþy ¼¤šæXêØLWN'Ã^ü•!Q¨÷R*y…9†ZN‰§p-C9™ ³¹ƒÝ™Ã>´rZ<;D9Äl|l.àfRÌ^á8FÕ¾#§$¹ª¸•/²C˜I7Vñ¶s ?ŠËr. bRÁK:Ÿ£)?Í»?œ;¹³Õ·h`<÷q97RʵŒåç|™fÊÙÆVªèÆ6>¦„Ÿñ§Uí'UiÐZøUè·´G´V¶¶un{ûÚ·+×T޾uty¦<Û#ûΕï÷âq NXPZSzÌoŽyá¿_È—äàð“~{Òëß|}{·í]²]Ï)ô¦B:L†Øvü ÀŽXÒÚ i"Ñ.  "á“&3•¤Û $é½ö.jˆýªÀ‹9qÁHîBët~X™4ú.ä¹`ÒúiÁŽ«à%+À vý-’1[eeeè/¥ÙŸäŒ5?;l;‡uN wq[“CAaÀJ“ßþ¯€BI%š<Ïi¨d¨#ý³ÂoºØ~_R¸åêès»°WJ˜®%±êúa$Ç„–ÎÃqtÔ‰Qä¹£Í=›¬œáwCK†½›ó­Ü¹|ïÁÝ>°½ï'[þ¸$Sß¹Û³“7‚üäÏõ<æ ÷|ß­7:bŠI_â;\Ï%ÁïÙ-"�ÅrºœÏúñëÔÏÄ-t\«wyž¯ñƒ8ˆ_q¯Åˆ3†ž,dcT�êÊúE%ÙïG¬öoù¾ËmÜÃH²\Ä,îá0>¢.®Øsì﨧/2˜=¸œ éJ†?òeÊyU<iѯÄñÛݑȵ_a7`&Ìÿp:Æ œÂa<Ä%å¦5ëÂ'ÔòCnc;ÍÅnks- Ž´bÎdGƒÇ f?¡žf”æ•ŶðJù?fÏö;œ—¸…£8³YGbV±ë™Ç¬æQLcy*¦“,-Ç›ÔÒ“/r/ÒuQgý°ˆ.I$ùd4ìž‘šl½ÎŸ¸Œ}ØÄq¼\䤜R^ãøbÚœÁò­®Œ—à;s:Ã#¬q—ðUºóæòaƲ&¿Ê�‡vˆN g›úÀÞ ÆŒÕ‚cÁ… ŸºøÔËO-­+ÍåruÃë¦_7}ô£ïýνé—-9lIQ¶hÌ“cN¸õ„—¯{ù¤OêŠzÒ¹'T„!²'Á:Ô ñ+éñ‚”œ–½Hć¤CûVäΆ»ÎUÉÅ$’|>@Úß‚4b" Žß…kbzo!Ú_…%q)ø¾;Ó‡ +–4Ø6†Z*!¤ï]B^N¸nÁñ+’ìÂP1>C¨«« Ô·€Wl·ü7:íq?Ov'°Àà}\P•†›U€Œo¯j€W°<%Ž7¨Øñy³éÁ�6ÇðôM$-\Â\”™`øüΠê_·ýóKr·Þmj®óðNÙžuÛ{Öþ·}j¶,®ë’i+ÙÞ{Kã‰Ó-èk%=éÝmZ—Ä<º™¥ O]FrÈÚèG =£Ž8öe ƒ)‹ ± yЇVNåK|B+ÇqQ¹¢«(gj‹~éÒFÞÏÙÜF%‡pfT?ªØÞyÕÜÆ&&QűœBW>ŒÆ€#yƒ=£¿mkä,WrÕt¥’%©‚é}º2—¼Åç˜ÅÖÒ“IÑÙùPvã$òqÆü*Çn³žãèͨ˜ Jr3•Jz°OÊ8¸'¥t‰½ £XÅBÞ-²’5¼Ï Îå}f1(cŸ"sóža6£XÊr²Œ`FÔ¤ŸÎéœD–/PÁßɳš#ê’×Få”zöf=Ýi¦!âÔ{Gq¥‘)œÐéÚ?'ƒÍ`<+˜Ï–"§åwèÛNÎYAÇ3œNôc{0†GGæ°œ‘¼KºF–e|>£[Þ B!Òªo¿ývà�%sãdüžtÕg(ñžOZ[!^ìî%¹Í{o4qPIKIÃ^ ³¾<kËà-ʬì±rÄ–åÙò­¥[Ñ}}÷\ynÓÀM}õm®nÎåÊW—œEA8kÞ™¨A2[*pÎ-ˆ¿!ê%3˜Å 4,IáA81ä옔}‰D ø$p€O銲³7¬¢µšx¦›u‰ìlÁZ%t±ð†¡o–°â’¤Û¶Ð¾Öi‹GÈE‡0œðÝCyÛ¶mÙl6£TWW‡h<t’ƒÜFžLÊÊÁˆP…6`úî'$ +<<œ¡`JdˆeŠ‚eO�‡á=,Oâ#Ó¹sçð¡é§(½ªi²ªªjÌáG'ªí³q–ü*v¨úqýóÆRL[,­¾FwŽæ`õüŽ×iÑðewÉÉm¿üþÜ­÷t*®øÆOó/Ÿ’+kýÙ:?o­=i¯mUÛFÞ>a÷/ß Õn»±h[¯Ì±{ªšÂeŒ¥3“9&úù‡SÍitâH.¤,Õ̬çp¦Ñ#ZSia?f3ØÎVþÂìFŸXB]Ä~lÊ»ƒ³RŸ0i÷ÒAz+y‡?poÞ š@Ìg6ä¢gà¾JYã¿Õ‹÷™ªœb_ϘÉÉQ¬¶§³’ísÃ9>õ‰'°$àòN­u3˜ÂãÜß3xŸ±%ÜÃSÔ0”Z&q+"Îð6^c`Nu~ÇéŸa»3‹ÙVåˆÎ®¦<V$¡Äy†e¼ÃzQG1%ÜK-O1“ƒéɹŒåazPÍ™dù¥ËÉ<Eý"Wa%s¢Äíiÿ\j‡g5è²÷à Ò·i¢$î`¶gýŒÑí%ˆYÜÎŒæ&® …ƒ¸”‰ìÆž4Çîå{L§™¼r;p›‡SÕά«p€ÑíñhmmM¢ptÙ´/Œ~ïô«\WÙ–m«ë_÷þUï¨pòc'o+Ù¶gÞ×,¼æšy×ôÜÖ³ª®jŸû ø`ÀæA›g|vF¯i½Vº"hÄ%ñ®,u¤QõíB‰xR8÷ÿnÂûÿËÑ!Á6|Ç¡ òViKŸ¹^™†À-¨`ÌQ@ŸJ£B‰Â4¸ 9ÿ²ˆ)XùÀîJF_ÙâS¾gQQQUUU§Nð’<št5À¤¢¢"8ª„^hb©Ü¾Ó˜Þœ% ¾³¹cH„¹ÔQÔîØu3°!Ζÿ››©¦˜\ί£öyml¸õäng?ž§œ¾T±…ë¹x»µÛÇM׳¶Ó˜«+º¯þù~Ö¿é›Û..ÿFÙÏZÞhéºäɯ6ô9å?2s÷-zîŒÜ=7ç«·z¢Õ„0:5ÑÃ)¨K¤ÝŽY40‰~Tr&1‚÷yôŸO<™çÀ å!Æp?ÍÑs¶&*èLdU¹¯O ‰|q4P~—·hâDF21笔CnÙÓéþÉm|È hœxI×]Æ�>âQ^æl°– s^Ê[ñg3I¼gbß(€tÏÓÄV3†ýx¹8ÚÏOæp&ò~ÂVJ¸™Ÿq)÷PÃ6^a|J©::{½G+©¢;ü1oC“¢œË¹. Ԟƾ|ÄÇ<ÄdÙ;’“‚òÈ÷™Ç̧;9úÒ­¯ 5îÏÚÂNeb, —±?×F6Û³¬°ƒ{~*­|ÄX`›¹ŒîÑFë¹è ò'êãfk�—ñ*³ÙÄî\'[S¸”%ÜÍ7ù5×SÂgÊVöc«ø[˜ ´&ÿ3P¶ƒX™�’#B#(¡°tœðªZgý׬^Ë{M˜8á­3ߪTóôæ§û÷íŸÏçû-èwé~—nî¶¹tké^÷šsΜš¯Õ´vmísDŸ!Ó‡¤·É³ &Pš·›nŽ%¦D¨x$„¹4*¬` JœpÊÿ1àxšôÂwQÜ´‡¤» ã’¦Û£û’а}Íš°’–](v“ á§¥­‹¯`UUPņt‚;ð¿øýßÎ;<8ä¤`SR�8 Y0i‡¶_¤½œB ‹“üdg"÷»²c1­DZÁO#ç²Ôr!gÆ=ožáôàe¹Tã.¬ÛèÜ/Ú\1ú7¾8=ûÕ }ËGÒùìîκ«þ÷ßÿå¤ÿZ±nÀÙ_ÿû択X–õ¨ÅÿÍŸø/²Œ«¢mîI][ ¶Ó@¿àª¨ü4•î, Y'^p9‡‹¸ŽG¸…Z.¡7·üÃØvÞe\bM ·‡¹,_â=ÞdßãaNá¯,âiÎ m½N_m2wÐ@–{hb*óYCïtü˸²Ø©m^äHžæë<ņ¼Ïp!ff Ì[Íw¹×y‚jær:Gq/¯òåÜÊ],Š_*­>Ë+ÌåËü‚/òCª£;奊—8ý8Ÿ©´Ù¡º{c4— ÖÌ!ÏzÎks&?æx&ÒÄÏÉáPîà!ŽçªÙF5çQÇ'\Cw~F–9|f½¶¼+ømÔ ü®|“»y” 9žÎ¥ÞÈ=dYÁéLb5Y*)!Ïcl¥˜jЏ˜‰”°ë©a&Y׹Р*ÙÈ]\Æ}Lâ?(cyÔN|(cTÞ<ÊTsQ‡“çöóƒðót]™Ç£|cùßoý{ÿ9ý~äàWÏyõãÑßóþ={ôß#SžÁàÕƒ¿ý«ooÎoÞR³%ט뱨GS[S×\×òÍåAc4Èô…h’Íf×®]Û¡>B‡1¢ÃPؾ˜´ï¥ó‚s H6i)ô´oaÁ+ÿå˜-¦“qp« q¿=Û·€>tÈ�� �IDAT½›ž%Ë’ö;Þõ*}Ê$‘~Ÿ4å6tJ“ÞoúÛ¿sèÝ%ªöŸ¦A’b!Iòe¢Dœˆ÷T“áÜD7ªäN:eØ4¤×p×¹'ŒÊ’¼õiPˆ*²ßÍ@f³CYÍOØÈ6VF¹„ƒx›õÑ穌°‚ÝÙ]Ùãê“‹L_á†7‡¬ÕÜ«iæë¶•5ŒÛº±sU5#æ—m¿}ôû]ÿÒãñÌì±:ûçû}•Û¾¢qòz³bÌJ3{‘¥šʸ:Úçy'¾r,—PË0ªyA,¥2"PÃs ¤Œ'(§[Ù;JE„Y× "ý󿲄²è·»ˆ³h¡„ÿ —í¨êŽfN½»h¢†%¼ÔꊞqIÞ;ÜJŽÿd33X›SÃ�æ°"êÁ¼ÃY›ßѱC–r]âwß›»)擨½»™ ärÊYË™ð SÆìÍò{f¼A1SèCoþƒN¼KžËù-O²€­òw0O2—9ÜLy"Àeldƒiθ<ã4ÊXÀ|>Œ˜ÆUqO°ŽET3š œa™#hc#Ù2Þc##—¹G|Ãñ[âÿî>NaXäz/¡‚I‘’1-:/ŸÌ©lç.àbn§‰}hádæÑ/îf²^ìêüèÿ± §£“ÙÕòå˧M›Ö~k¹ë.MûÍfkÕ–7”—´•T®­üä„OºÔu©ë_7eà”±Ù±r°víÚg*ŸYÙcåê½V¯ºâ½/¼·ø¬Å-¥-}fö ÛùD¼ Ĭ }W`)²‹TÔþâ“ް‰N¿ ¢¢"ÌuÚÓiÛ«£† +˜Ü|z8\µŽä⽨ÿ–a|’ ºC?6´­iù¤VVV–|Ùô‘tÓyº=¹5Lt p+É‘ ºÒW˜ÖïH/{QQQ¯^½‚X_Ї xÅ%ÔdÛOC*JP‚é)WR2&ÌèP—ï¶Ûn#GŽìÝ»wŸ>}JKKËÊÊ 1ôH+++Æ2V„µMŽôuL@ �/ÉΣªªêqGíB‘½[T§>0þd~ ÓéÌzVó6Oð fs&Sø;ƒ˜Ã¸âê½³¿zÂWwwîþ}'Zuí“n¸¦ùú­vojéöÞí3ùáˆOÛÐ}ݦ©W¾“ßsqvÏÅñ³îb�-ŒäCš˜Àótg?â嬸8ž²Cy5öyêx#ʱðóÁM”p=s3ƒø<E”ò6Õ¬¢m¼I÷à˜1èÂæ(5(~î*èM§nÝbj^gGhF/PAw0"ça¶Ñ¿ãj&³'eñ3[ÀžìÃâè«R’u'eœÉÞä–E.*ëÈÁyÛòVÒ+Fÿ÷ø"“y˜6&Ó™/ð6 bwQÆWòƳ€ѪqsT­å"å"~C_0Ÿ;AŸ” Òxæp&Óib¿åHVg¬Í{›¾œõ÷63>vb‹¹ŠŸR¹eƒ9„;£*/ÎàáȦêC+ÈÆGBìß®`o2;&þI|‘G">èYQ7"1"nà. [Ô'¬çŠèžÐ– ¬†7³–±”£™Âf~Ó!нàõßÀ\­:aU¶kvä#§Þ4µëÚ®»mÚ­Û†n{Öïy;×üpݬ=ð/þRŸ«Ï¶e×ï±~ý^ëwV…ìLiéßh"%`ŠmÛ¶˜õ%]Ç­’yO’®’¢3‰›éñFh!\RÒ,°ÞH‡tÓ©¢¢¢ ×úì4þˤ¥¤ÚC±ÓXÁq’ÛÒ†#AK)äÂÒÒÒ„x”ˆ˜0]wî &“$ì4î1ÁÜ‹¢_; ¶Ÿöïß?KÔÕÕ­[·.@Ò…9ký{­Ý¤¾ KZí»¸íÓUðT]Áv~ÎeQ¼†+XÁ Å®.rx«-ôàªb—æìŸ7‚†0=ËvKv÷Êèâ Õ-W¾°ûÍ57µËëcû4ÝÍ+_úYÃUModÄËG®_t¸k¼~„¯<^Mñ—?ÃÓq <›fªÑMœÁ31?­Ž°À­j¨N9V<ÁUÏ|‰_¹‰^ãB^ŠÁn<³¾‹×¹=k�?â ¦D¡ñZ¦²… y“• Úî�žãr*XË,æs<HŽsx‰¡¼G Óù5sYH>fP¤ÍYLe ûñH‰{Û¼Ît–pQÄÑ]Å|š¸*~ǹÏ ySËj–ñ_LgaЦ!šKÕñl$ƒÿ9œLÞÌËQd¯¬wx€Óx‚cÆ;”ð ªéÁë ˆnU”¸=‹iÄkÅNÊZ@j™™·ÞËdéà  'C™G +çX!Ù÷`QF¾ÈõYq$“8'‚Å{3,="*59jÙÞ‘#Úê¸Å¹€ÉEn SÎÙÊy1•ß3‡qq.àu§Ó¨àHþÄ‘œËÁ”SÁ›l¢‘¿ÄØ?ím¼ ª(€ÛŒLÒú{›Ú¼ăn? d}ÉЧ‡¶önÝÐmÃþ³ö¯Y?èÝA—=>)?é©O ­Úë^vë4ü©á+_ÙÒ­¥=Ö#ñ°HǦÿ•ë§?‚Zà€ÊÊÊZZZ–.]Ú~˜âuÁ m×.ÆIdÕ[ccc:aˆS‰¾oʉñq�å—––VTT´µµÃå$¤Eâ?eºJPÿR1¯}{pgÁ½¤¤$8i%ò€!ë×ÖÖ¦µÌ;|“¤L¼@{J0¢i¨^IIIà$°Æô02Í @QQiÆ A}*¹›Áˆ$höH ÿÛÙë_¦«Ý¸‚‰Lç›ÔÇÙþ{¼À`ŽÏy&·ÃÏþ$öÏù}Þt®*²$#—51w@¶èÌñïåfR»Ï­w|½ùôëj6*®—ŸpÙ¯Œ-ž´å÷®~õúg³§<ã;§8æ ñú%6õãf2Ìeu ²Çò·¨×™b£«ÞAtbò:÷ñÍ<Íû|ž,yîf c-E³‰h¦’Kxˆë:¹ºÕd®*Ö+oTΉü™ŸçxÞ£Ž2ä)çrÐÖäF¾A±1êþËSÏŸ¸“7˜L wñ�}ØÄF¾Î=lᇼy÷æ\–u9è«UÜHwÊhd+åÜÂLê94ïuÖÓÄøÐŽ‚/O†&±-zƟĽü™LμŒ8‘³ò6äL–’S9„ø-ñ,ãl¥‚·(¡‚¯QÌÁÜÏ‚œ6Îf_æAþ@+gEtÃÁ<ÏP>C×Äl5ÏÄYÔŒ¼¯çÔSÃߨç¿Á¡läJ†ògŠYËWx…½#em]ÊÓ$ÀVŸŒÿžÆÕ9ói¥š­¬ã®.µ,`·²•WÉs.§ßd \N3·Fzß2ö˺ UP(t¨£šTBM=šúMéW½ Z‹Ê•5j²¥ÙžËzÎ=fîÕ_=í€iOü䉟ؼ¥ùísÞ8màÖ>[ÇÿyüìsgzrTRå„¡}²¹Nì3§ì #láÃÖ>LJþWq§¼¼¼{÷î;óDßÅF>±~ç&0QJœýÚg”€^Kàé‰cšúš�4‡Ìtoß•m/‹•Ä÷4F¿¹¹9X_VTTd³Ù­[·¦eMB²�7ßa™›ŒÓ v0iÉ«]«î"}Ťó™<“im­Þ’.k²°¡X I.Ý®LæD\±½¼azh×ÜÜœ.Ó†–É-+¸¹íÓUŽ·9Š,³èÃúhÿóeÞ¤sÞ¡ìËoø5ëòrrFQF÷¬ŸÓÇ„srÿs‡ïvʬì“9òk­Ïý$óü—Ú~zSkÿg:]د×è—fëeoðý3;ýñ뮽‚gñ?È~™Áì•Ô±"µSîõXCæÞ›ø<×ð .ç1ZYEŽ2;*†Š¼?3V¡•lˆ2¬9$cx«c2‹½Õ¦™=ø>¿áužåE8ˆ“3ŽÈ[ʹ’-ÎßéÆ<Vs›Ë ÜH müºs¿àCŽã ^a;ð{>äómÔј·„®”Æ¢$‹}ø*ÓèÌÕ‘oh–ŸÆüËÿ^Éq\Á3ìKOfÇ{æL{äÕ²œn¼œw$/2“©å¯œÁVDÉ×ǘÏ͜ȥ,å ¶ò8ÿA·ä}“©ez³<£OÞÛ,c 9Š6ó#Že)éË‹l „õÔç ákÚ¼˜ßætîãJú0/ð�±OÆ™éˆÐÅ“pJä}‹Ök·QΆhmóý)çÇ\ÂÚe;ù^«ïЕ~ÀÕœÌLöfe©Ì@{-ÙyàH ½â íÓUM‚È€W¬8źÃÖõŸÒ¿çÜž­=Zõ6ã°zl¸óä;Oºï¤Ó^<íåk_î¾¶ûw±dÔ’s{L¿dú€Ezf{ªÚ1i‘4Ù‡èÜ¡´¹¶F,­HÂzHK™P6› °ò0béÞ½{uuõ²eËòûÓ!—¤·Ø ‚#É7!žvè–ÒÞ¡¸}à˜orñδêwQƒ&ø‘d®lB¼.xτϔ6 IºvÍÍÍí‘eeeÁA±ý%¾WR\&h…ä üS’ÔžŒÇv±zãžV«««[°`A�.†¡ã¿ÁCh¯Òá]ÛÂ¥=Ôb)߉ßÃ' £5j“/c![XG?z³žÇx9o5½©yµ…\VU¼òü’ÍçVOÚ«ñìŸdê÷Ïï³0wþ3ekzm=sz~a•Òn¹ñ-ê¢:Wu5¥!BÑÒŠ±ýSÔ`~Ä<Ö3ŠRŽÏè”1‡Zª9šõ¬àu†QÆîœTbxΛQ<ûe†g Ϩcï=ß*¶ËóÖ笣ˆ˜E–wéÏé,ã`&©áyúÑ@ò a¯1„­ôc{(=©aMäÌI=|È@_æñKy“E¼ÄXÞ+rlÞólg«ù/` }ùˆ!|Ÿrrlà:ê#�a!Ç1u¼EUœÌ=\ùÅO1’¹Žžcg°˜tŽø‘µláG!ü _ÃæGÀrz°wTg?žŸr2ÅtæmƳ¾ÈyçåÍâ|Že o²&ZbÎ`G²‚E¬‹"诱‰å,å<Æ1ˆZ:EVòi4QD{Fìû6æíä¯æÝØNìʴȤދÝy„WãC¾ß3>"V–æ<À`î§ŒjŽa[9Œò¬Eµ*›¦ Ïœ93 cÂT¿¬¬,lÒ“Ê)é´qÒ}ž’’’žõÜt覦ÞMÝVt«^Q]¿{}÷mÝWX½¥Ç–Úžµ[wÛº~Ïõ#Þ±dô’Ò†ÒVô^Ùûè»N†ä™L&7„ÀŒç“0Ô>f…P …%ºMEEE‰vQHEá5éá|2¢O„***ºvíÚÚÚºiÓ¦v;t­LÞ$8З——WWW‡ÕU’œ’%J8jðpz’ÛÂOq„ã2GZŠ>A$¦CgzÔ”¤Ìtº ®qö!…tX½IÎHÄ »té’÷KKÂ'Å_zsxÉ *Ñ ¨‘\jÚ%ýï`ãYAÞÒÒ’$°ÊÊÊðšä›†ç3H3‡;^\\ÜÔÔ\­ê²À„%©“ N¢¾‘4 ÃR$¬íPét‰Ãõ4öˆjÑ20cN‘CòäºQÊÞ¬â¨(¸0–^¬eOSËÁq¸uÒ¾dÍÑê&ç/ü{þ“ñk——}òZY—âÖÞ+ôµeì¢ÌÓGç÷\¬¢LM‰‹^ö•n^=„Zþ#Æf|Ô4Zi° ™ÏŒ§›™P¤’ÝF=UÔñ¥Qh+‹rîŽ7wLiÍx„A¼F÷ ‘˜ß‘óJÁlcG±²ÒgŠ ËšJ?¶äÕ2‚k9< æVð¨äŠ9YǶs2ÝÙ—.<^ì³yu,åd;Æõás¯æ1šÈeŒÌ[§2£)+Ö)o6(æ=æSí¯6QBË9–û¨`úpŸPIÍ´ðoð1c9—¦(zqFØýQœÆCL‡Ó@#ÆÚè}N¡s\ÆÕåÆt2¸m‡ÙÇ8öáh>d#òºç½Å¢¸hˆ6+‹R‚Ó‡Y±X<€ ¶²õ,`(»±†NìÁ!Ìâ8Ö²‰^ô¦…#RÏj-ìË^Œcutˆ.a +9…Id9’aŒdË9’—èÊf–SÄŒ¦š'9 ¶(72žÅ¬á³IºZµjÕìÙ³Ó:L¡ûÈIÉF8ŒU €j¸Œ’’’^õÚ¼ßæº¡uU «z®êY׫®j}ÕÆëúÔ•4” ž:xîés{~Ôsý~ë«WVl|i®4á©§¤•Æ5$TÐöL¦4P"ANwضJhÈiñޤ6*++  ç¦¦¦p;ë|†ojÁ@î 'v¸=a´½=G²€i\\ _§©©)¡c§É@ á7É i„}RÀöÒˆ‰‚ª+俇’Ò*Ù—„M@rz@“‡Ü¤ÒÐ 1=¬pA#±¬¬¬¢¢"‘ãKæ’• ŒàäâÓ]è‚t•Èý¥Ýg aÔ¯­­Ý°aCð û´XFÒîNº—i}Âä’š››C.Â@ E[z…+**v ÆÉy¯Ðƒ6VPÏ4¶°‰1Ÿé¼ÏU,Šúâõ `7½¸ÛìnZŽÎÝôc™šÜ®Íþz€×6è;&ÿÊCù+×\j…¶qL_3Îã#SÆ�¼*}£ËTˆ;×0‡ÉóTÎ:.e&‡°$î›ÙȰbãsnÏÿC™â†±6/ÏB&ÄQG8.ä–òyFñ³‹ôÏ*mÛÁ)>‹›ù6ϳŒ—8‘Ãy›óx•>œÊ †p�wSC˜Â³\F>g#]y“[ù6•ô¢ˆ[( Z9ÈG±Áx<ïfieu,>äΈ²Š'3ŸÑ<ÏÅ1/ ™ÉœG+Ã#@|Ó£~ñ£(qjVKÞ¯Æh¡š láb^â~K_¶³/ÛxŸ½è¥[e3†0™<="Éz3ÙÂj8«Ä¹mÞ¦‘=É ÑÙò^#ÏÑLæB^(rJÆ¡YŽö§È Îe ›˜ÆVÑN çÆòc¨bó*õPV'm!ža+8–Á‘á÷Õˆ‰]Çùtg.}"„§‘ ­,àx^á­VÙø‡³FŠô&M 5Q€-8†¾6tÙÑËfÞ4s¯—öÚý­Ýóó½æ÷ZqøŠe–m¯ØÞÒ¥eái ‡N:ú‘ÑÚ:)¶kÞë®áÉè( øÚû%A<™ç¸â†ðÍf›šš¤-}%!7'á,ºBlhhÙ%œB×®]ƒÒ]øa¸ÎOß• •PÒFK$w“¤AØ~ß4=(á ¥»[‰Šy"áòn²ÒR}øRáç™îdžlè‰ K2Ýioé^ßÚÚ ûaWT^^’Sòd†ô¤¨]/]Ò ø”ðHc¢Ø[�ãlöIײ;û t3°`úÕ>]­Ê»ƒŽ ,UQMã}ʸ†¬â~Z‹}3oQΈ¨HýyN§’G©3o­jÍjk»¤upyÚ"ËúÎ>‘_dM5µüLª ¸‘ßDOî‘™‹¥ÜO#å|‹Ù,áÏQŒ£‰ã¹˜+hc{Ö/ØÌW¸#¾øúˆÇ;³ÄµY“óöæ0î ×ñ†p%“¸$§a›ßEi¢kÙÎwØÀ¼Ak‰d=ž7“ZjÃ&Îa2wéÉf>ÇC\“±>ïn¾ÂËüˆÁTòW(æ~>Ë!B‡ÅÉù)ç²:úÿ,ª6Ìe_çQ¶r)ÿú§) ‚<O ßäqƱ5JÁ6së²þž÷AFÿbcÛ¼Åô2Œ³yŒiìCO‰\«Ë¹ƒ¥´ðŸ4´¹‹*öà<úómôŠJZŸp!£²®c39¶3,ÞÙϰ2"6÷çóÌáñœta¾GŽ#©åbà5£ì…høû¥<L1½8–yÌà+üÿI=ù!ß”ÇÓ±…øæ9ÎçMFGÚ@–giæØ¨Âõjl-,á»ÑRD‡˜õdî’ü­†:  ¡v¦ø´ ÃVý_ïßRÑ2çËsæmßÑêl+o+m,ýäè.뺠¤¹¤"[‘)ɤå>%ö¯@5­Feˆ&é9Ê.æùᨯ¯¯¯¯/))©¯¯/¨“ÒP‚´.C:«¥!µ'rsI•ä€@‚ÞÅõ$ 5±tJÂÃ…òegoRÀhÞÛ©à'áÂÒÁpCÑÓ½{÷Ð, *G§ÿ­¦¦¦ÊÊʪªªP&>‡È¿¤«–6}”Ö=J3 Ú Î†„T—"vûaa{t_AÁ]pVš€µ jv‡ÈÀƒ˜È*¶ò�sQ$~À×£üZ5›³Z£túLä#ÎäyžaKÔL18LÏfu$N]ϦGFË_iáþ…׎áÎæIÖŨ”¸4õb¿¤š«y“ù Ûhås\Ä}|Ày™—èB'Îe×°F› Ù‘ªyš(-Ö7ïžœñQgïî Ðb—1$ë—ôä<¦¶y”Znba”±?›çèBIŠkµ ,Ö§‡† ªy‡®&»Ó%bçyú2›êŒ}óÎäV¦3ŒέË…ŸñQ‘_d]Î+ËDZÍ5‡;‘q2äwè•”G†Nüœsx$ïlöÏÛ˜ó^‘‡s–s§òG–óÝŒ7Š}¾Íý”ó²ìɉ̌ú¼Û™ÆÝ¼gH›"ä¡’r:ñ›¼xšcwl_ôe(¯p-+¹˜ý¨‰ŠQ|u´±‘§éÉ�Ng /FaÆ^ÔPI Mœ•1ŸÝòÞ¤ÖXÀíÅ1ü‘}èÏ'üгèF/;*Ú°Ÿ*ˆ¥LäØHj>,Vä¿ãk|I¿çÖcòÜ¡ïxÑ{ò÷\ÔZ4ìéaÞ–î}…í|§ÎwúÝ'ü·@_£½olÐNM^öïUUU%%%ݺuKôÜ\ ¼n…¥'ü¡ó­érb‘F¤“Ö¿1Éÿ4¨Å7çÝ]dßD¨)Y¥ ÌÚ!˪­­-Q$JÒm}}}{²²²²`#²eË–€»Kúfÿ´SIU-IzÞ“¯½™K¯^½ú÷ïJÃ7¶´´lÞ¼¹¶¶¶ýʈ$¥?"©{:´•iO’+À˜lÙ²%©YÃYaÓ¶ ‰ig’ “Ĺëtµ–‰EÌe$SÙŸ|Ì<Ž ˆN<È&Þax‘±yýó>fwÞ¦'¸š—˜|÷ã†q<CxÏrküÄp„k¸/t6ÆÉSoÊYΣ á2¦±œ&fp-‹¨â>z²}8ƒåÌ£*ê/ÄZ>¢{PË6†QÁJÎÉZÎþ‡¡œÆsTЙmy èÆ‘|ƒî\ÊpÖñØzªã/|ŽÁѲk,#éÅk¬ÈúÒG+5QþWìáõgå̤GÿLÆÀØÀCŸð0cXÃáÌ`pÆÕY/1˜gi‰|؃Ì:gœCç¼#æs72´Èy˜·…ÿdE΃Eš3>Îï?‹ßñn^·6p#ù%\Ê ªøÓ¢_× &²1£•åù£ÇnÑü·Or‹¹ŠN\-zùðp,µ7²”IÑ£2MÕð,g²•Aô¤+ÅŒàaºð,—d,É{1bß—3”¢ NPõ }"¶þ$zò—è&ZJÅ(Ñ=Øš¸›ÃÙÌ,æY)¥ã$~%ºíÃJÂx- +%½¸@»)P7(h°¬yÀ&$í»OOtÝY30Lqþ?âî;ÎΪêý÷LÉ´dÒ&½B%ôÞB—Þ”* EDEDy-¯Ø@¥ Ò¥‡¦téBh$ZB !d’L¦%3çœûÇÎÞïã™0 zï}þð‡S÷³ÏZ{­õ+%mÉ£(±’êZo%6Õœ9sº–bYåÓ¬ŠOòàHâß¡s‚Zo¤‘X¶ L“ª’ )µéBèO™5½]ºSÝ�ÞÚÛÛ»qè(Qdø\CúРܯ^½zµ··WTT´··'gá$Ö!è'>@‰"bÉÞH ¾dYÙ£G¾}ûúm>ŸokkknnN�ÑÔ LŠøagfK½0T cŤòY{24~ÓVùw9 Ùìø¹ÕUöÚ/jð¼È£‚׃—cxŠ[âë|ÄÖå]š¡'¾ÎCaÛc?*ØEìÌo¢Û}vx¶žÕQ&ÌÒ˜á6ö`(·q=y‘W"Ò}·2ƒÃ#(.DÁùìÈ4F1–L¦ŠMXwcpŒ Œáeæ°ŒË9>Š×õà„‚©‘ËUÅxne”ûM^³©æ ªéd+¨ä¶ˆèÛ)Q)¸“½È!\RQÑwË´”V°2¶aß/˜Èî´sëE…¡#xåŽ/X‡ë˜L}‚oÅ^Y'‡QVp1ë2à_oñßÙ‡‰Å4.­W¸•ï³€¥lÉcÉÎ<Í,¢Ž[ÇQü’½9„»8Ÿ*Še&°WÞÏØ†¿3—^Qÿb=Á\®cpÔž§™Ûø€½½]ÂuïÅAÝ~°þ*gqãÆQ<ÏzEK‹ÿç|¶â-‘ !:ynð2‹¹•M¢ÊÃìÇ[ä˜Èû akfrÍQ”ë}ö¦.†•H³èƒ’_fhˆ%âg˜f'eØôëMdÌR†K!é³~ÃAq kD¯tš($Ypø-ì‡ùG ‘9¤¬I*÷K\YqØ0ÔI¸”ŒkkkÃô(%§Ž(v‡ÖV6‹-ðêêê�«KƒÆp;‚¾Q‚¦e,IW%ñ4€>èîs ÁÊÊÊU«Vµ´´,]º4 JºjvÅÿÜ5L6ó½{÷5jTmmmÏž=çÌ™ÓÔÔ´xñ⤰ö[prI˜‘�Í6cð!­jjí† eXÒì§-éi××ׇí.%¿”´'KÐ@Ÿ›®†°7¼Ï›±ƒIè¼�� �IDATé×@3¯D„XOž£w”ì;4*0½W°{ñŽf4—1ŸFNeCî`Kòk*˜ÂÁ<¥+ŽäA>¥ƒ½Ù˜ë™À=Àú\Àk¼Å¡ìΦ²)s9x†½™ÁvæžØ?ümÃ:¹µxŒw©¡æñc®d/ЛS¸”ëcoíhFpÛGfè&QMUAkÔªYÕ[d¢2;–»ºÓ¼¢­ùG)ÐÎÁ”1:ŠSÌ(:)'Wa\Þ-E{óFô°¯ä»¼ÃúíìÁuïTTÏ"ð?ÜÄ3,¢ŒeGp#W²I”ÃXÊ‹È;Qëo ¤’«©d{²ý™Du¬/à1¸žqŒb_ÎdyÁsÍéM`ž[fHΆy5<JOæIÖá^á.ð•Ù6çļ Ày4ÓÁƼÃq ãXäg/^‰¢‹2œU¼a8Dc˜˜Ùr¢ôWÐzßÿå¹ùœÈ‹w·À+xŽ–1†iàƬq^òÅMkkkÏž=»’j“‡^ÖT)Ä£�;®¨¨˜?þgÍ®KòJ ¦i ÀÄ!�­Zµ*»€øÜU×·ûr‡ëÏ;H*Èþ;›ž³C²D+)I ³¦¦fôèÑ¡Y±bÅܹsV;LȲqHfÙtU’ZB+/ #KºaYÊ�® j¡d •P–œ5\þ¬^ë¿U.†@Ïž=kjj>W58ù"vtt|.Å;@³{,îÓ§ã°žI’8e²�÷Èb:>+mwMW yŠ"y Q/õž8ؘïr)gÐD¾Ãa¼È%e¶§²àJ–PÃ<çI7FŽÎ³1\þŽeÜÌ*êh¡ž2š¢ÐÀ3¬ä1«ƒÚTêif;f².õ äINâq~C%÷0•Ÿp3}¹ƒ~,f-þÂcäèÁë¬bƒsÖ.:ˆVn ×¸¿1„Ó¸…»9‚ýø_Nç)fð?Ñ"+ò_ Ã<êbsìMÊØ—ƒYP°¢ànnå*þL?¥–sØ’uøÇR_ð8G0“}¹½¸†Ó¸›Ëé¤.~…St3‹cß²¤GDÿïͼÈCêÇ>\Q…Õ\G?¡†FŽåÉè�²=»ó WRà)Žä<ZèM“ùSd-aˆÕ¾˜E¿*®f›½Çl&p=ø5C ¾ÊÃôç)çvª©ç¬˜õ¿Æ[L/¨$ÏÛÔs4ÓÄÎ<Êe¬Ç�öæz¾Â±ë³11üž.ç8îâ=ä7ìýoãØ(ôž{2,ò;ÆñÇ äÜØÞ ÒM÷0Ÿ¶¸æk–X“,[²�/¡‘v5Ïzÿ¤(@ȃ'¼r{{{%Ê¢6�/‘v»?×××§Á{hH°À°ò¢Ûúx!+”d‘”>³ðl¹™žh][¬kpL¯¨ÈÖŽY2reeeÑ577çr¹ºººøaºóâîÇc% ­ðjÙ3GøŽa¬à i(ÕéöCâWµ´´$ö^èܦ½”Èàªj‹-Z¾|yccãÇÜØØ˜ì•³tº„P Ÿ0+Ø‘5]Ìηº[*®íæ1_ðZ£ªEÊ™cÁÚlÂsÜÄÍÁfÜÎÞ¬EG³íjl’sG³É<lý8€·˜ÃÖ<ÄÞLe4³e<K=ò6·ÇáÖfm `#žáTÞg* iŠ Æ¡ɽÌg £™Áftr#/pПÅÏ ¼ÇY\CÜTny§—xœÇ»|3Ödcø!—qwp¿dµQ(]CùÿÃnefì—ÓÊVE·ñ7†q ³©çdö¢š^œÇp±ˆ“¸_3œÇxícëõHÖçL~NÛ1„(0œS™È¨‹üèmy¥Lã›Ñzj§ØË XÿÝX\æø‚çØ‘«y™ùÜÛŒ{qK,þÆpƒXP滼Zð*_åqÙšx©ÜÏ ÆwÊ™\Ïܼ.9‹7YE¿èÆ»€‡X‹ s6bAÑÖ£†¯Ì¹=h×—ÝéÉïÀp*X—ßq/¿c[3™Ýxž XÂŽ¼Æ6L‹P¶lä^^bhô=éO?ÂÙy}¶¥Žm8œôäÓøëöÍø&h`=¶à¶®§ÎîK«®?ã=zÞkbeÍ…šššªªª0mFŒ1|øðºæÌ™ÓÜܼpáÂ,4 ¹¹9³³Gõ,0 ÄÊR^Ò\$…ªä"Ÿ a_Î%ýK7 ³dØ5ÆÁÄüÍöýH«æFLF½i}RâL¡|5S÷MöüQbé”fÓ ‡ÃDmmm×ñX{C{GUG¯%½Öß»I¨)çÆ[¨™šššÞÿý¬—ñ«ØpžH+yª¥Â'/“$la’‚ ¯ð„ Ìrd­%9¨®¿_@„)Œ7âaN¥ƒk£'ï L¢ylI5Õ\îÔ¼ÝZV7¸úóF —›0Žã9@ªîçkÌ‹)'øËôg £˜ÀC4ñë3ÜÊ:£'Ó|ÄÙŠeÔ²ÞŒçOÌd+¢Føk g<3™Åäy?ujàëe)ÞÕ1Ôóat„zŠ¿2œ£x >Ll:UYMV{>çœÛÊœ\4·h#ÈEqÞMiã^vç-ÚøF ½Ø!r×î³Ù6ö~ÏpŽ¡E<Äæ´’ãVæDR¾Î´¨1Tî`ÜÛ\˦9Ÿ2”§Çf\Ê@dm4ñ(Û2…6~ÍÏ ZXÈ”h¿˜eÉÄ2¯Ñ‘“í4y$s£¾T33™É$Nd_.£ÀfÔPÍ&9åE9.z6PÌùv•Qí&ÓÌb¾Å þB;Çñwî¦/÷²C\Þ b“¶?›33ƒ,Ã*XMäº7Ó¥¼›ÁÌb.sØ’é >ËÙ¦À+çfŽd$ãx3&«½ôõ_ è%“¡¾}û804;::ªªªššš:;;ÃH<EÆtº¶Å¡>ý=éú„Øš9‰+–‚N¸Âüÿs;Kkìו€Üä!Ü5­$Š%ëÂæææìjü[ˆ’”½ÚÚÚ–-[pöAì< O”<¥ºº:Ûà*i v½ª««CY“È^%<<Q?)t&®¤„žÜRß2gÏ9ƒÞÒUVê7ËçÍÞ—$ÿ‘rí¢E‹²#Æ ÇÕÚÚš€ûÿV?6ŒÙ¤å߅† >@XÕ’"XÆm+ÝînÒÕëŒã¸8wéãi(bæ3–å|‹o°GÑî\Åúö`;qIÜÌ"ž`—X«ÍóÕÀže~T£Ø3X†Á{™S¹¦à^ú²}t eÖ¶¼F3íÑ=ÑÇZ¬ 7;pgÚOb8yŽçTÎçAÖg‹¨¾ ƒÙ„ ÆL:ãZ•&á^&0œ Éñ“²ÿÈùE/hç úñ'Þf:XÀPzÑ3žè—óoП+øŸ00Žj¶-÷‚_-çufR ‘'èËì( ñt”ö˜Är^f]VÄ#ÂzÜÆöŇ]™šw MCx=h‹ÄÞÐ3ÜŸFöawÒßj"p/> ™ ÊU0°è=Þc]7è—g$EÍò`ãÛ/ðm+ä+5•;½Ù<ÄqE—W—5r}¸3¯°Ü$f³’¡lÌùlA?á `_†r#Øœv^f{®ä]Îa÷²!cxšfÖ¥2#ÔTEÍQlðuÞŸÊÈ,>˜Oif>ac¸‘áœM£ºQ»9Œwm[uu‚i£ªªªºº:$¡$•]^^Þ¿ÿ¡C‡Qƒ®.\ØÖÖV__ŸËåZZZÒÌãÿ«ªª*±¿H{0;ý =ÉT™¥>gWÏâ´>)ef!þr™ä„&dÐìÄ%ü1«QªÞPwÂSkkk’ºÈÖ£_éTõ‚æVHZÍÍÍ!Êw¯lfn“ ¹Î\Y¾,_/©™²ëP‚£ û*àeÒ¥©©)"Ìa*ý»jѦFeÚ)TEhDg»…ÿáH2Á:ºè?7]mÆÖÜÏ_#fa36‹ @Ìä,¾C+»ÒZp'Ò3:«õ£½x”™Á„oò/Dšm]-,ŠÉéŽážøOå¶¢GŠšxƒaôåo¬¢&³[s _ $\^§žÝ¸—å,ލÍ92ñ3ö¬p —ÎõoðATèhc‡ñ ­ô`G†q09‘>ü–G8À›Œú×^Щ<Y°#bJ[u8ƒÍØœ?ó.Õ<ó4s)#Ù•>µ¬OŽé|­àù¢é9„•t°?sb¤|GçÙšÑ|¹ÌgåLd=ù.e<]t¿Î@«_|"‹µçr,ÓÂÛ¬d –ðæ1›sù‹ 6,z‚ù«Uš?Ù'çñ>½¹–¥ô§—Ñ‹Ž¼QEcr^dWV2Šýyˆw¸€1 1”ëͺlÍôa&½ãmºx“u8•_GâÄrîŒ+ÓÀMñ˜ò*-L,ø”®fSˆEXð*›”ÁVÅTöàzúÒýD^`O2“=øJW {7¥RWÄ—‚BFÀòÕÖÖÖÖÖ†óx(JBe~Þ :„ÄÔKfEÙ¿„³v°Õø¬Àúÿ×U žÚ˜ÙPÔ¹Øì¼'ÛóLríííóçÏp’ ¥‘ôj¼0Dü2ÌJÔ‡*!1}ûö­ªªêÝ»w¿~ý ,›Cýºa_B^=šzŒxdDy£v ’‰%œ0ÔÌ*@fëÑn6jZ‡T'p|8p$ÕÄ$$–Øa…|F•á”TÆ2œâî[]ÓÕ¦É)òöár^â�Fñ~”èÁ¡¼EU…Ãó®/ZÀm¨!ÏT¶e×(ŽP '-,¡%”“ãcˆi …VÒÎé es®)úSPx«t[‡óø=÷òfŒ/±!åñ»\N‘ÓâtJ3ÜÀ4žŠò9yÖîtü<›ñ&p¸:+¿ˆHóødµ¬”\O­#œ¬@edÅâ$^æmÞ)wZÑÍŽ£’Q<Á>̳Ç-¬ÏmTF9ר`mÆòŒ¦wÑ\.â‡ÜÝCîà²X,ö¡™«ù:÷3™zÎá÷Á,Ž »æXžžÆíÑ$÷PªË}§h­‚-èO3˜Åà2órFæ]FG‡÷9ž÷èA¾èSNaw2Ÿ}½{ûS˾LáÎe%u,,ê—·9õ6È;ªèÔœ#Š&ÐÂEÌá>žçh¾ÃíÑŠþl~Ÿ‡ÉœÎ,‰ÊúT±•\Á*êã^=‡I|Àß™Î@Nç“„W,³UÎò¦ss˜É`nã'Ì¢7RN>€g8†˜Âö<Àkô ™ŸÕ¾ë ®+ùK×ê$ˆè 0 Ì®Ây6È455µ´´L›6mîܹýû÷Ov©ýÈ)øv…o$óܪo²+ùÁ\ê‹ÔŸëb¾ÆÚ¿ÕíJúéÕ«WeeeMMM]]]±X¬««KŸ6èÚ­ñP_(æÌ™N YJ g+ ÌK¢æé[„ÇTUUÕÔÔôìÙ³¾¾¾oß¾èÙ³gPÆ«¬¬\¶lY¨™D"aÇ» �–ܦêêêêUÕVuW¶foV¨‡ÂpHÆo%­|RÎÍ‚&Ö¸]? 4 éY‰Â°’¡êꪹžöX‰:pzp Xr¢*Í]$n›™ã`kôí ~ ;òtÔÝÉ@väŸr7± £øzΫµ¶íÐÊú²³Øjù*MÑ÷hPTfÛv6=«uxƒÌ¢‘3èUГÙ˜@-ÓèO€_¯¶AÑÊ¢²Œ²NhinΕ”E5ôŬOET$jã2fsÓõù”ëDO^ /5œQí\Æ�ƳÒN*8’ר»èå¢Y ¡È^|Ì îãÀ8´f¸ß‰ªg1v.a푉¼6o³‚°+eìÉ«´³KÙˆ§YÊÎOsΜœ1ôf=>`'îeb«8ì™Ã{Q´¨ègKž¦’µØ£¨¥h"5ŒŒöNµ¬d op,­ez-äb†2wy‰¹Œc=Êô)ÚŠÞœD+[3‡s ^磜¹eö(ú#¯³8j#Ä´–ùAÑ{L¥ƒõÁó4òOöŒ¥ó'ìÀ˜ÆѶíÝ(ì4—uid*»—YXTM_êZÔTt/gÎó éd-†X­ÓÈsAÒðZ^ámÚCs³·³gÏ~á…BVH}•¬{8ÂWÄ+§Ÿq(z÷îˆÃ¡– ‘ðƒ¹!œsƒ"\ˆD---íííK—. Ê{á\’„ºbê’˜zW$qøcR«K‘4ûȬ¶l÷ÍÀ`ø’DøßÔz*‰’%ÍÀT’†ï•}Ù°J!’†Lt4’¬mVR¶ë «ä+gK“,s.ÀßÓhP¤TWUU <¸¡¡aìØ±k­µÖºë®;lذ!C†ôïß¿_¿~áè²xj¯}ˆñßåW…RWW îúúú @ŸªŸ0)L@ùššš@ð %fªÎ8l•’IRvÒ­ 5}Â1&ùd‘•]½Ä»HŒ·”›ƒäGøœ³œöjmmmV‘½k*›ÅdÖ.·}^#×Ä¿?C-²­ÜF‘—Ì`^fQ#_ÓYi­ø—££_û?ãKÝËØhM”LóÂ?ÞOQÁLaý8c¨áÊÙ5:Ü/g6ã)£ô¨Ðйøl—¯öx„Cø-3HmÎПYŸ­#&ðq>¡íÙ”ßqùA¼•{RÎ(†3³Lï¢ :s–VÏlÆÐ?ç9•O±WüšmÅ%üOä'Mc Ã9!üøóƒ˜ËãŒgþÉs Ž4¬“øÑÈ£,¥ONyÑœÉ2.$϶4°”Œê«ÏR{ÒÀú²™OžÒƒ‰Ùâ³ ëPÎ>‘ý2‡³œq,äT.a$ÛG©ÀrÖ¦ŠÙüŠ“¹$òáfQ™Ýón*³cѲ¢©a@OCÛØ¹Úk¸“-™O=9~Ãý±·?à×üƒÎ(Ûß—Å<ÃOxœÛXÅ·X*îϹœo²a¤»UÒÁxžc%ãy™¾lÄqþ¨Äë0–<+Ù%òÇËÂ6ë/sec}ˆÅ)¬WWW×ÖÖ†þ^ 4Ë–- á¯P( 4(tòù|`ž¶¶¶¶µµe™@ ÑâQŠÚY]×ðø@N³·”\³X笈TbÀœñ„W éç –V¡Zcó* Ï³3ªàp²Kv Ôõ‰Ý·mÓP-‘ɲGŠÙûöíÛ§OŸ††††††>}ú„{t}}}PlêÑ£G{{{kkkpÈ · {vÁçc»+*B2‹dY±bÅgù„wü,™Á¤æ—=„!eâe…'R NZ²ßµÅ^-¸VÉ¥ |‘Xɾ$ý ÂÛ}‘ÙU3ŠöâGÀƒìÂ;,¥½™Ä!ÜD_Žd!D1r<P°lùjäîÎüàõ‚×À>L¡?;qó¿>f]f½Ù‰wã‹ôž÷ÐÆŽŒa-.;6›-¯”9˜E…ÕMª™¼Ìvñ#­Ï<5Xwg%Ïåì\fÏüjÔFcd,u²7¡;0…‡èÅ®<Ç ÊTæÁ¢º¢vjY—ic»ð‹¢™ËRŽd9K¹»Âù.gò.ë1–ì³Î0ža.›0ŒMX‹Iœ3Ä·¸“s£žÐbÞâ¸"ÅÕ<Ù*àÅr'ä‹FÓ—gXµÊGìÏLžä0æÐƒúr§t–kè´2êPìÄÖ±¶îË_9ž'Ù¼àjƱcÐeç@®f ¾ÅÓLɛʆ,då¬8r›O¡h«>ʵ4º‹¯³„ÖN³ÊÜiqø¾Пyƒõ˜D‘Aü!ºtnL?³1wð>—FZqp¥y—oó·H:îîü‚l̪8³œË6¼Dçf¦ƒy&Eí±•,ŒÐOó‹8á?‰;I—(XCN°à¦¦¦4JGæ�1bD–ëÓͨ,0–²N%‰Ë• a –°Î¡ ̦«’VXH™áˆJ±’(\‚A/Á&Ñ©’VÖ¿cLµ’pÒU ƽ«ÌDȬ©Yú%ðiÊXYYÙ§OŸÊÊÊ‘#GVTTôïß¿ÿþ½{÷=·’{÷î쯩+ÀêÂ<,—Ëu•ÉÞ²³* µHuXUUUŸ>}B½’fTÉ‚+¨.%Ð  ž­ÎKV&9]­qMÂmM¼®/¸VÁ'¼]hh‡œh‚Y ›ÐýÎ2Ï>wv…%<Q0…ÆØCþ¯ÒÆGÌ^Œæè UÆ/øU|zâzfB4»û—öuT]ɼŒdÀÙ,âæèL?€½¸Ÿƒ8žÿeÿä1ÚÈñã2á úQÃ;\θ‚rÆò*9Öf. ‘s¨¢Žgø”èä,/Ú´àiän¾É_éäxd+æPŒÚHÇsÌœJßr‹n+Z‹9ÅÕ,Úc¨.:œOø.+YÌrNª4¼Ó™ôc'Ú¸’Ó9“=¸Š#Ø—籂-éˇLã9æG~ô¬ ‘2NäH¾ÅÆLãrÊ*]Õá4Ö.Y\='û-[°¨Å+lÂ-,ânV½†‚ó‹ϫ㖨3TÃ(:˜Ì ÍmœIï˜&——‘3:¿$ù!÷± Í|´œ\‘J¿è0‹ ¬Ïþ'¯kpxµ‘m¶d}–µkÏùpi¹ã‹¶-XÈ%lÇÍ”³‚²ˆu<‡ŽœOŠÎjý§s5etD-Úqü°Â®y“Šv`Ãx˜oðŽ%Çvü)z?ânŒd¬_XíTÐJ­ÌæëqÑð*ã¢\Èšð©tÛ>kªœâK˜Hµ´´O<Q”(¡*B°kkk &!/¾74‘†šÏç.\˜Í7á<žmduGeÝüÖȤI®+è «vbVM<Kû¬xEòP@[dãu6(gÛ¡]{_¤ÎË"°ƒéTïÞ½ Ô§OŸPæ†üÔÜÜ<hРúúú€N¬««[¼xq*eÂÇ릸 ¹!-{:s„|Y[[;`À€ Ï‘ óY…Ü첇‡†[7ª  JêÐñKròY%”ššš’SÈS{‚x$ØK¨ŸJvBZŠ,²ãsÓUý+2¤“Çy†<·²+ÍlÁ•|ŸÝ¹’O9“ãie"‡pvløü¥ vëó &²5¦’zšøC”+-ÐÁ7X<éÍPªYE+C©Š£ø¡ñÅ¥/£˜GEΔ¢•|•þüžëÙ6dor'›q³XÀ ç†âjÐcFr:µ ª´a‡©l«Lå®ã5žãùjóqpœomOîãçŒä5ü“˜ÉzæœP¡_§Ÿ³ ~Â9mE㹊çâ¨O$}Àp¶d&ó™ÊY<Ã?N+q!ð¶ap‡Ë9“Ÿ5°7ý¹˜Fþ±ÜÍîê fÁ9ýò¢÷à Ìa,O1ž>-r:7ñCªYÈ z2’ÍÍMìOe9¬5¸ÊØ¥nïp$×r!wñ121ïÕ…žàPúpgpGÑ?9™‹ò&r?¿áÎeÓia(³XÊÅå8l›WÅuÜÅ+œÂ•|›:Íà§üŠ?q5;1™yŠ=x…Ôd~_a üœJÎáuþÎÑ<ÀƒÂ*ª¥|>õ$›œº7¡UB7§FV^¶££#€/¦N¡šfK]é´A ·Dd6{œ:9kd% ²þ~é縉µè]cé“ò_v.òߺÂè+}ž,'·k’+ÉèéÁ¥’/LDjœ&îT@©|GªJƒ¼z˜P¦ -Áìà0ÝÊ´ªÙŒR¢Ø[K )9UŸ<>bĈþýû744477¿úê«Ë—/Oš]·_7ö2Ž%OézVèj –Ëå²y75Nõ0ˆä†žvèÓ¦©®®®®®î*DYEù¬t5šFÚÅã‘Ìt=C™_fŸ‚r6ã>΢š­xƒ¼Ã@ndÝÌß&}ˆàÑ·˜ÛÄ-ôbG>æm«òŸ0Šç¢ñù�6ç>Nΰµ¶âyîb*ýè 7û² ï2‘rªrúÜÊ\ȶçd¶‰6í3ÍGœÀ|®ˆ¶È¢ÐÆVV»_ÑáoìÆl¦²33˜Ïû\Í·ÉåìÃ’¢NVEJ;p?=XŸ7YJ ç1„X·èìNÛ²6÷±)3Êô¦¢è<¶N]S#`oñ]Náôà`f°ÌgmâGÑàxk–²?eK™Â<Æ8>=Ì›kÚaL»ï!çlþQTËtZ9‹‹¸‘G˜½ÐÎáhæpZ$ÕË*–òjÔTÜŠ˜À°VKZ52’Ù<ŸS¤©h�EþÄzq1šŸ³-õ¼ÂÎÌç-ndë8j -»lÄl’÷é¿b“x“1¼ÎƱEùçHM{:îŸSÆ[lÈ6Ž)ycÙ‰;Ο㛢ƒóÄn¥šM£uÀFÌf£5–Ù�ZUiòŸmÓgÙ²áç†2ÎXAµ½½=kÞÒÒÒÒÒô/¼*DÒkþ‘ à---‰“ÜBTJj¼)ঔ¼Þ“o×uH‡ú·ºj)‹|Vw.Œ|D·F]Loƒ QˆŸ¥¸Ñ=öìKp†’EKkkkò‘Êú'Y‡P‡1dX®ÐÛLdØ48 "X¡o™ZIç7B—Í4]O'!Ó$FpvPW’™²P½ô˜/¡è_rµµµ¥r÷LÄÏߨ]þÒ-xš¬Ír^/wvÞ=Üirî+ªç ÒÑtRA{eôÓjþõõïgOV°**â”ŦM8¢>šAŸ7ðS>¡ƒå<–y¿38<܆°’+ãìazÁŒ‹ªǑ㢀AˆÜÕrÎŒ74ýFF1øö~ÎjôHTèØˆ9ÿÈù~ÁXz²#7Ò‡§8„ë’³NQÓþÑ�� �IDAT =YÅíŒá”¨ Ÿ£ŽµØ—;©dÓø*;—y¥h«¢q\\Ð3ªZT2)öQwæÔ8âzÑìÉ´(íØÈÓìq’e|ʧ,áØèͱAôÊzž}x˜ØŽ—r¾ÒbUÁ½´sFA›”7‹Åôc‹¹’-ø€¹‘3¹Šv`'^æzó1ã©£©L[ÑÂâjíħ؉UÜÈ¡9g-(wjÞ_bòXÁöâ.^æÓ¨pÑq‰°x2þ£™Ñ¶8¬Xeq×u°Ó9(2ÿžŸaª#`gke|t‰¬¤"ó¬]y?r+Ø‚Y÷ê–Qê)¾·Æ6Wª�q'LÝCÜLòt!�eûi hž­·’<RòÖËvØ …B¢¶t=«v­Zµ*—Ë-Y²$™’|ñ«²²2ĸ Ù*㠵Ʈc¶R)uÃWK€ŽÖÖÖ”®R’C( Rîš8?kd•`ŠŸË­Näᆖ——n[[[]]]�׉þÅ!ý‘{N!ÝHð%ïàì¸.XXnòeËB8ì±”“u,ÜÜ´²Të,õ8Ýš’×ꙕ‘ÌRÚ555a´Ö¿¤LÿÒ骾,çMòäº·è ŠœÉGw²Qéçc*ùKy(¶¼>`3:x¬Íà U×@6¡–=¢ò,^`kó UÔr·ñ|dæî]îGEK Æ1“-#Ó3 ÎC¸ƒXAƒ9†Ky’±|À*†Åãvài5r-ƒéÃ!*•ûz»{x“&VÑÀ¬¢cø Kø;c"`ºû±ªè­¢2ž¦ßr YÀ9\mSòlìÏN\Á<Þ.Ú2È ö‹Ê"ol2s؉W¨‰¥, ¿²œ±ŒàVÎd,KXÌŽãnÆÓAÝ¿vbßä5꼊ñÅÕÓ £ræ•—w}A/ÞæNÚ™ËA<Â.´0“­¸Øj‹õµÙœÉ”± Ûð<›òaÑîÅËþìœÓµ_L³¹Š§ŠzMã⦠÷YçîXœɦL)s—lÎ[­Wáì¼? d%§E팯ð!óYα  “í¹9꯯JEO&2žø«ù€Å”G_˜EñYïE¾¼Ø’ÍGBq¸æñCÙ°›è–Lx?küBm‰ÊÃgÍ’OI` ó‰d”õ²¯äÔ.chR,{©äÇÒ0 “C½]¡]ágÿ]yªÖÖÖø°"Õ¯%GÐÝ�(Bíò¹é*Äô|m Ìü …B¯^½2°¥¥%v477V(‰Hï³^¶›eY:jé¼QóF<4"Ûb]ºti{{{Б `“°¶É"9Õa_‚ý&U]iYÅÛìQ©dÌž:!A†ï^Â(ȶ²£²îÓÕªH|y›:î¿Ì‚©\ÎnÜHo&ÓÂqŒær^ä6e<Sø€ÑŒÌôî>a ã™=;ч*†±s$3­ÅùŒa;Žaïч ¹‘³¹!ïXâIfð{2ƒïGA@6®â'Tr7;±’tpsÛqaoŽç»1ˆ˜R™÷›Vðr™óržÉ»žï‘+zž½9‰Z^¦’çy‡V¡œCy…³O_¦2›ïS`nà`þÀbQÞ*úØüS¿¥™ê8™Ë§\̽ÜÀ(~KŽs#÷86&φQ»aƒèÞù+}ø+×óK9Ÿ ¸Ž:*sú—»¼Ó5ÉEßÉû”ÁEÇñz4’næZFñGs+÷ð1uTT8(ovÑ–±ìxzç¾m&ùâEwÔsÆ-·÷Ù\Ç«Ãæj`CFT86o%“x! éîÃTÆrù–V³°{p|™™9Guªç¶JwøÇð ßäR¶e%ä·4ÒÉާ/³”¹Ìˆ˜ ¥<Ëí¼Ç/¢‰ðl®£ªh<}y¡^CG$¹ŸÎ5±>[I#_ûÜŸ}jìtd¢ÿy¦›+ÈÔf]²²r¨]µÀCþ[#|#Û¸ ìÑ£Gˆ•AºtLcü²²²ææænrC˜Ì<Bª¨Ö8 Æ4›IO¹ªk‹,ܲÂtAšý‹·Ãû`äÒ¥K‹ÅâøñãGŽºv+âx`I=«û \“Ö* ÏVöZùô9Oç:r••#¦Ž½­­­a ÃwRa,ž¸¤†F+W® Ïò K–ô³êžn§¤®�O_£qI M>Ë‹Xã]ëš®6àÎg}Žæg f�3éÅ«[aápý;*#à»ŠŠ¨õ0›"³*´hÆ¢*œšoŒÇÒîe&²”oÐÉÓÇEYÌÎ,d!µ9¿/º—MÙ™Ÿ²1›2š+i'ý<#x+’gGF<ú&3ŽÍù˜ó8‘åÌd`Nï¢ïq9ï±'|‹‹ þÆCŒãÚèmøŸòlÎIÜC޵h¤–›x„_ÒÀ÷˜H#1Œ³™Ïee¶e§‚¿q5=Y ’y÷çÜP´!WDeÕ#¨ägE;Dy¡§¬n¾Ëר…­YŒc ÎgG°ËèÏíìÏ|žc¿bhÑ×;mÏÁ ÉS\ý_—p8k1‚ƒù' ÈÇf×ZÇilÊ.æ8~ÆŽœÆÌ·}‘e.Öû¡ÂÏòÚÖF?ë¾Ç_˜Õ©†}¹=çhN,z‰ 90 ?Ì}Ü­´Wزӊ‚{8ˆ?óL‡jög{fU×i=*Yĵ ¡@[ÅüŒ7YL#c9šù¬âÞgJäüÛÉ ¡OdvÊ£4RÉQÌf ëD«ëS(ò,Or_ïf>”ý‰&±ÔôƒLQ;Ù³JBÿÖ•EwãúÚÍÓ³zE¡o™ºm%ýÃpœ0`@ÉL¨›¸–²òé%*qP¨Ë {ûW—ÈŠŠŠž={&ÓËðQSºJÌ¡úúúB¡F}ᥲ'‰òx•ÄîP-%Èur—OWÈ1­­­ï¼óÎG}”JêE‹³ùÎþÜÒ-;ÆË"Y”©ZRµþ_Öï9§g¶ÈNuyšê•χUJŒà„hOÌål^__ ‚%™,M¡ºɲžUYÄMRôOïòYÞ]ÙFhòuë>]Íc"½Ù9j[ŒfSæqvtÍXÁ{lE3ýy†áT3›wÙ”LÉVÿŒÉ˜Ì¼õ°+¨dó(¼¶kÆosjiæ"¶Îùs™=ò*)ЗShâ•8·èËNŒãvæ¾èTR^o¿&¯0„É|‹ÃÖL¢™%욃uŠ6ä=>fãàvO »²1ïÇvÖp~-š^ãrÆ3õø„·#ldÖ¥•D;ÛQMÛ̎Еíx‰-XA[NK™ò>ìiÓV?*8+èAÕí a>[2ŒOXȇÔÑŸ®a"ËØŽí©âv¡q+ÅÙX9ë°kØÕäËìž7=ª˜b7žˆýÃåe ®çX6‹ ¶) àlž£žz^e,Ò¯à¯&µ»äA×}â¥(°Œgic7Þe ®á[9‡ÑQ4a<NC½ÁõìO{§7â¹ç†R¤þIm§ïósVp%0ˆgXÂnÌåM¾Ê‡e–ìÁ/Ù‚})‹uÛí¼Ì7x‡ç(òކ“Ï0„û؉wxha+Ù {cî`ç‘B| òªD(ý¿™KÅMSSSI ¨{×ÄäB›­“÷`ê³¥ïH¸©nHÕXÉ›f¿rh<f{žÝW“¡šKÿ¹˜aÑeyµiAÊÊÊeª¤Å"{ÈYJ\¶ ê²eËR[5,ÂÒ¥KƒÊmÂs'blŠ×éë‡Ðl²Ú\jeYíâÚwN}g£«6ê9³gXÐ} uírA7ò?T:þ·Àœá¸îT@ß$êXúYƒ’’sR:±}®"{-CY›‡y—Átp58'f>¡.Nìvk}Á»µØœ¥ÜÁ§|%b%òѾ=|€­¢™ý,z°kljáa¶f6_cEÑFy-¼ÎþÌâQö£_ßr4;ôœWÊœ’÷8Û3±hGv`8\%0nç¬X7Œ)xŒdxt‚È1™íhæi*x5ŠzœÏ©¬Ëû<HŽƒyŸNæ±4.ÎLæLþA‘—#àâlÃ8ÆógðËØ¿è÷y½Y\Ô—K£)WuìÏ?Ù…±ÜÈò¨z·cxnœ8Îå öàQ^ãC>ày°mØÝ…§yž¾ìÃtó»¼èÁ¦ìÉL6ˆíÄM˜Ê^þÆÓQw^¥­¨Y¾?ïÐè¶Í´õöàaUn©´¼Ù,fs6¿ä`†…[Yp-{—ûvÞAœ®‚‰Ô™Ì{Ì£’ñ¼uÃx)Çvä·ÏÊ©e&Y­vx{Îa9'ó0VVë{Ë-b&q{­Ãоզ–96ÊÞ—ÅÓUßhXº„ãÄ.ìówÙŠ{²â¶]Û_ºf‘Öz¥Íþi"µÆj¦k=”äæ²'ë$û¨£ixVâBÛM, ó+©·B² &‘u²cì=™ –„Îc§ÀÒMÈÉìq!iwsìè w 8£ÛÚÚRŠÑ®°þÄ€Nê\ —Qr”)™ë”µ”m|íÆ­ZûÍèWôàòÀÎʳhX™®g‚¬¡IIÁ2qvêYâ)ó¹+S2” øš¬Íæ ØÈ륵a;ÓÀ&9o”ûJ§_ÓÈ>å}öb0ÐL=»ó>o€÷YÊJz±]ò—ä‘ã)¦³€‡YÎþôæ ¦2Ÿvže;VðÏò*£¸‹3˜Ì\6e+8™4³SÑ•óÂüc…u™ÏDVr:»ÐÉÅïp*3YÄ7¹Ž¥¼ÐàŒå^èð*¹‡ýÊÜOŽå\ÅèÉöÔsUTÒûù”£hÞ œÀ!x 4YEM4OÚ‡+˜Ë¹˜Ïâò“œ~e.Ê»œÆc\O+ÍìÕîïâ… WwúÇ0€¸˜­©aÞ§È& a(÷ÐÀalÃ…ìC'•¬äxú0éLcG–[l,¨ä=öâûœÃ•\Ëüs*ìÚévz1™1γ¬ëÞuY»Ó…ã>tÊ“°ãõ¬O¿ç~F=ÏœF9ãâyšYT³ã¸>òÇr%«Å4z°Œos¯°7O1•uè ×ušÂEŠÖ§&o`›y\Ìר’ÛWy–·9’ʨ�¹˜-Èõ¸_±}’hàŠˆ?lfZ‰ßU ³§+0¬«(u‰Àhr£ï†žU »ž£»âKd[ÿ+Wcccyyy€h‡öàg=²¦¦&kè^(ššš² ’l%š´½Kb}ÇLÊ^]éɉšV5ý#¤Ã ‚~Ê?²råÊÖÖÖ�«K©Ú¿Š&±ü�E |qÀÏ2œüPå’êê%«ƒþó¿z>_™öä°‘ŒD Û…„$’›ðÂÙ¡cI#7éÕvÍm«V­ ¹9`AS=”¶YÂ@¦×ó@dNÂl¼ë6þâéj%ML`{sýØ‘Š¢IžgæDGÚÉÑ «alÇ#1Ïæ8dÇòç¨p3>ªÚÔò(-QâSÚ¹3ê¼ÕƒÀ:šN55ì€~—÷Ë¢MØ“+8˜»Ø…žìÇ“T­ËßyE9ãË}£S‘[¸žûØŽ:®àdþȬïèA ,q^ì¿MçGlÁi9}Êý¸S#3o‡¾ +YÁvü„öe¦ÓŸ“˜ÃPΉ_êSNdç(¾>Óø´Âey=Š:Ø„½¹|ÑŒ¼ch–¸£Ø€VŽ¡‚e<Ï¡ÜÔéÛœÅKÌaJ¥[:4±’ËèÏá¼ÊUÔp2ORF9?ŠÆïZ­Æû�‡²6ÛócÚÙ†~ÄEœúð¿|› ô²&ùÕ2¯y~Ï ñ?¢Šïæ÷9/aï^êä+rö.?áèÎÅç²"§®èbšx¤¸šüp9[ðcžâ$n‰†)=˜ÏU|‡r.1†·iâŽçaFÒȾôa:=:½Ã{9/æ\“w%ƒÊ]´Ê),áþÌ€NûÑÌ…´rƒi¦*:ˆÖÒIoúÆæö=±öA1ŸtMW_d¥§”L†Öè-Û}Î[#sÏÔ›ê*é¤íV®\™´‘Ò´)µqJâKÊý˜fEÙwöœž¤žBªÈJwgu*¤+ DÛ;Û6L]ÐÄQMšOi’v¶DKοٹ]((SìîZ{…Ò-ûÂÈ*‰‡Â4ä­î±ì©›¦\Ýì¢)¿œR¨.l÷‹ífï2ûÉ[žÜæ§ÛT̨Hã®àœY¢ ’¤c?w+m{dµ³]Ê®Û2m³®Ç£dþRrÂÈ:L–œØÒæ,y©®éj?âzò[SÍ%O1„-2œª|„Òe&o³#ͼÄG1-ε‘VuwÆDq“X àÇÜI#3¹a|·brÛ1–Ÿ°6ouú'0šEìÃT°9›0*jÜÁWÿâî3L®º~þgÊö’lʦW$!J„Nh‚Eª*ˆDQ‘¢ØÀ‚Hï%4AzHHÞ{ßÍfûÌœçÅÉ9» ð÷ñzžß•ÙÝ™3çüΙo½¿÷Í(n ÌÈì 8ÉGL|uXèÎ[ÑYȃT¾“6<c/ñ8oÑ)°%ã=v ƒÆ&d8!p£¨áÖ„3¯1•Ž ¦…©ãTJ8ŒÓ©e5ñ0#™È]³()3ŸÞ|…Îüž0ù:¯ÓHŠgù„0‡mtçÛ\Î:&ò#[Çox£XõÑ~ÛéG#ñ.—0™nôc-Gñ[’‘ÈÓàˆº>4åE¬åï â—tO(æã@‡”uû¥ì™óë@cBIÒ³ng¬ÒE–&/ÿ‘Gä ‘ùÃÃÎ<›ORŽÈ¸."8îÁ1Ôð5~É—ù ÇPÇÇIcs꣑¯¥t¡Ž%Ñè^/†p1ôä&&ò¨4zGÎòÀyn«pó95ÊË·³ zFóp؇Ãy0zV'³0zÚËØŠˆýd …mäÛ|cã�¶MÁ'.pµ§ˆÙt>7<ÕÄÿ‹¾WÓ“„˜ž.¶ø»ríÍ_›9¶V!eQUUUx]©T*޵c÷& ùv<ö¬mJRñäY¾CÍwBaN§Æ©jí’°½×X¦M1[Ç®60Äþ…]–0óhŸ[û¿ÐbÅOK›|+®[Öö­-ÝT:þñÉT²òµJ¥jÕv^Ð9®g† Å8Êf³ÑÊ¿}1W}›ÖQø8íô’wå¶óóã6n)t?!¬ÿ –£w¥µwW5<Ê~œIcD©WÉ–ˆÝõ¨QQÁ@©¡ ™CЉÌÈ# |Œ†G´¶áAzЬ£–QÂxV18¡’Í”p0xœ½8‰ý¹…%<Èõt` 8˜–õ°Škx‰b^e3Ëy„ƒ©!ˬˆÝ<DnciôÆ,ÕìËúŒ™Hï3‰¯1™YüLMh v”æŽ&Í K9)Ð@+'rg„ÏH ">ºÐ&îG·²‘‹Vñ%nå2æKÔò=¸’‹ØÂÑÓ‰7©!É 6GñÁ·Y½k¿e?NˆfŠ{Ò‰K¹‰ŒçôàLŽãZ'Œ§$°”yìÆZ&RÌX62º[»QeÖŸ a~F3 Y˘2)ë¶ì™Íwt 9:÷¥±å65“Ýô±E{Ù¿¿wf´PÇÑQ²>Ž“˜Î*£rt÷&\O@ éMo3› ›¹*a^˜œ×xš¯Ñi'ÊëT³€³™ÇqÜÑNàïÆî4¥ÜœuVô`?Âò¨M°#xƒx)rW#CräÈM~þ -N~Ê~ãnyûÈýs±d![`cccØåÞJ0¿mžkã#ãŽKÈ”÷~Ú þß´ÇB~ÂXù‹WÃâvkâ i[Ã.WyyyìÃÐ>ƶ©—†á|8"šÔÐÿ…¶>LvwZ›éð !´=ŸÛ"&“[kŸ[û gÝìLÆ0\ '-ì÷¯~É–ç°Û»½ü»—;?ß¹Í&‡ç÷Û·Ú<1mèZÚO†Åþ²=à%¦«ˆv\�/<æ½ül?ïRøÞÏÍ®B– ­ÜÁ÷¸“u,çøÈ¾‡â_¦„÷"qÛ—èÊž¼5®zÒ—w9žW@Ož£Ž*ÆGÝò02.lç!ödq¤7_A5Óy‰{©f0»1{¨çT¾YóLXO–­|ÈT‘À¡BRkä;EJ‰oÒÀ$&2… ¢=½‡KÍ…Ï2úó ¥9]x‰5<ÀŸé’s“HGȱ°u÷›èÂÏ]ìE&’¿Ê<ÁöN&lôáˆe-¹¤1ä<M/~F½¹"JšXl‡zÓH;»láa02"Àmæ4z0‘JO‚„ÞIggÕÐ?í—WrL”u-"É æ±ž~0ƒ-N làÉœéœMÏÿò˜¯ †Þë“®n8™E¼æû‡¸õ+Ié¤ý¸ÆºsOsÈ[©wŽÏYèÀ~,cÓxB>Lë˜q/3‘¡Ysù„/3ƒrÖsmÈH™ryV å…|L+룎ݪh`2Œä>d÷³O0‰ØÎ¤@ GЋ=XLšóiŒ´Obÿd_æIæDÀ¢zÞù"v6”ùù"Ì!aëÿI½°=e_~Q(ßXÇõ–6¯Ï·k1’-.ÁíTÖ¡MÏ#ß+ït¼4.Ç…Hýòòòò÷_`îÛÇø¡ÏŽs‹/” _±×ÝIèùÚ‹ æÉæ³?Älúù#1Þ=¤Øˆi± ;dá ăVavÕÚÚšH$j»ÖÎ8~F2‘<ypåªÊt:½vÄÚŠõU[ªÂÝnjjÊf³{Þ½çâ ïy÷ža¿-8Ä9SL õ{3ÛþO´¤óã¤æææükÿ ?£NÚD»rWèÊúq-ÛÌrÞã|vg55=Ú)fçìÅ?˜ÃQìËoØÌpFó…Tñ " ûŽ<ÎÏ8Å<ÂjJhF`>ó9²H¶#,\Ca$ʾ/¿ˆZG £jÒ¾¬ârn¢ŸQÆ;ìÏ2| ­âxîãL†ñ>-¼Ì,.a½XY¥—™Ã;y%µ®üƒrNãwœÍiÌœþBš‘<ÈfÞ M鯾d˜ÌwéÀ¹!”îE­VE=­Ë¨ ü<*Íu`³H±˜•,ˆDܯ¥”Éä67°ñ¤x"ét¾•ƒ_2’"®æÀÕ939ŒNYµÔZ¸Œ^dÙ”ãrzfrû³m‹?‰o·2ˆ£ÄO×¥o¼>óüVCW™uUßëŽÜ<ùØú‰vI@:7Žâ0/<í¯æfÍ Ô³iºýÂrÓjnIÚ?«6ëºó^J;,ë‘ÀXžãg¬âOÜ&š9¥Ü˜!/NŽÆ»s'QÈtes £9ž‰¼ÇœÆRªs~Åþ$XÈT‚¤Ë¦dwÀŸfýXÇ'ü: ’pQ”è 6ÏÁär¹0Ÿˆ? ã/d¬O˜?€öBþ ÊðÏm¡ý×þ`§ö®¾¾¾¼¼<? Ž9aw:Ô6äCrÞp¤é‹¤V±€H<3´Ó3ܶm[¼á懊M»Êib,Fœ[üwBõ1¼BDÛŽ1…™0ëŠéHbáŒ0{...®ªªÚ´iS¾ðk—¿¦Éð'†g2™¹'ÏmîØ|د«ëUW´½¨´¡4ðdõ´ê™?ž¹eß-±›ì¸²ãþ·ïŸµˆïE{m—pâ¹éгægÒù…Íÿ/a«q$±+w5€“y—©ãçt¦…·"Iªð;yß`XÖÞb~$4…4’‹`ëáuÞ™^oa-ßàçT“e4…ôæe¾Ë;4q]Â%¬ç>.æ]žâöˆ´IT«æ0¾Î=Ìážä:j(åf¤ˆAéô:sGó{îçRnãêy”_PK–s¹”µÜÉi¼B!7ò5’|ƒ€b^¦±—«W»œ¹ÜFWN!É#tevByàœ”S“s6â{4r1ÿ<Ëûl姬HØ-åÁŒ›ɳ¼í[—ˆRa WQÆM&3+ ”39†ŸrkN_渽Շ,¤˜;¸˜w¿d.“ƒ¼±Gó2#Š}»ÉŸu@3[ýVÅiJ&¤7ü2ëÂÀföàDîã1ûnpL¥½–Én÷Ñu[¶¢ó–„XË©I'§|¿UIàR5׺vxð³-t£†·9Þ_óÔô`ÿÙå³é8Ÿy™iñ>ø s)å"¢šûøÛø:QÀß8ˆ.læÜÍ_x›—ΩäeΡ–¥ÌæßlâG<iÇÏå9 ¢9³wháU~åñwp4ïPºÓȯýÐ~Ü¿‰ùÚK·é„çû€6µ¸˜æü3Úä7±ÄQ<óÛæ˜;í´/…µoÌlÛ¶-¾þ>ìùçCËBDImmmˆÄ‹­|CCCÈ ÿEp%ŸÝÏ ½{¾gÍ}>Í|Œ)©ÍÃú[|V¡˜ayyy{Æ¿|Êó’’’˜Ë#ÎnÃ- ¼a–—cº¼D"Qßµ¾CíŽI¯âââÝvÛ­ºº:‚ÚÚÚÛ¿í€{(ÛPÖXߨÚÚ:öwc_¹õm/j)kÉfS-©‚‚‚_§wÚ§š:}jž½ýÙþoöôÈ Dçrôöìm*oíÕ[Ú<;-âªcYYY2™¬©©‰óìü)í¥ã^]XQÌÛ&µö×{·!Û;$¦½=¢±q¿¦‰óxgø7{°‘¯pT䄞‰â÷°¸?)Ò°ïÃ!Q¹,¤YB=ã(‹º÷Ç0›Í”ñ]3“®LaS#1Æ!!™7=y‹¬ 5Ò’ßN–¾Œb '2–Étä_4óº& v$O¡&ä9Ôq †³š›9 Œg(u, ?‹¨åŸôånVÑ@ ýéÅ<:ñ.ÿf ªx‰ª:Ò‰½ÙÌCÌãR–ˆÜ�� �IDATñ nM;"çoÎL‹páÕÜCINoe=oò »åüŽ® Œfc'³!éþ@oÖrìIǤ·»±=i¿@ˆý÷ÜÀ¬fMg»7jaTt ¥Ñ0ìÖp[™™°{ŸûèUc R’ó‰/ÿ$=±SÁÁ™Öê¬Z¤ùK KhJêÛËž&Öœ’˜þ=~BGúªú›ÒóNË Z£6Q¾âlæµÚ–tVàq– f öMé²`TK°Ì3Cì¹Ý¾ ëö´.¬aÅ\þÍ|È9¼Èjžd)­ô‹’æ/s# 8ŽwXÅx*XÊù\I}éË�ža|—f$ÈØ+’®` _áîeM”Ñ3âëZÀÆHZz<w°;gœ|²áÃaåʕӦMËW¡ ]E(z‡ÛŸ!c+ŽÇ®M³¡=>¾o ÇŒßæ˜aX]·â&P¼B ÆØè„æ&&ÄØ³ØÇá'Æ<ôáåÇ ž 5îäç£ó™Âów&ߢÅû»¢†††0uks---!²1À I‰Â"L€âºYx±í«”ùö:æËÙÃ#„…µªªª=ztèСsçÎ1ì;¼êºîuµûÔ.?py¶$›ì”¬nªîÚµkeeeÿþý»6Îì:³N]÷ÙÝ š và%êûÕ§[Óý>ì·èE¥5¥e[ËòAwIÉ $‚Dø¯hkQÇe×[Û\ÖÜaY‡DîSOEþÝ Ã7=¾;Ÿé¶ÿkIIIr)** ëñƒÏ\^Ë®‚’˜µ9”Ñ ÷p̾¦Í]•im®Y¿ª½»ZÎ5täHZ#AU¬åãH¶ýú$úOo>¦‘q±!ªCkÔ¯êÆLÖ1Ñ ä=FRÏ–²¾±œÝù+¥¼ÂJŽ$C5KØ,»³Œ÷©¤ o³–o1™gòdz;tf]B&iP Éû,MhMšXi‘¼Ê~l¤]XE ÕìMGö Ésld »E8æqôâ“ ßÌéœÓ‰…É”Hó™Å>´Rœ3;Jïö¦€§éa‡Lâ1|˜Ð=é‚À Ö²?OQÀhGõɯ%õ le YÆqwÂwº&³4é¦@?žewzòØL‡†¢Y#yML`»³Q¬f’ªyo«÷85Æ+>ç7‹Ó•ž5¾uï&,1l¬iéäáƒçÖÕëlžøûx法 ™aQ‹s¦ç–ýÓ”Ý]¿¡åá¡›X”Ô50•í|;e|¡Šlh4Ïž¨¥Ú­ù`kßeMRA „}ÈñI¡>"EìH}øcXÏB¾Æ ~ªXJÿè.L`3‰ Tð^ ‡ +ûЇ&ÖFø Æ(2kâtŠxOf=£qÀ .ctì®V¯^=cÆŒxô§¼¼<4Çá|hÌq^âÆãù€ã|—ö�|šê- äCüB›t­=¤-VwŒÃçöäIm²«0gÊ_íÿÔ¾z;žØ‚ÇgžULUš³Æ{è6ö4FQïàwˆ~Ù¨¿-!3F‡çûËð.„¬Na>Zɘ¬(F¾„b†_Ä]…Í¡x몪JJJÊËË«««KJJºuëîRˆà¨ëZ7ýœé[»ovß°µƒÖnë¶mýðõ•-•eÛËžÙç™y%ó6´n5kTrU2¬L†§Q½¢úƒs>ùáÈ¢‚¢µ{®¸f`qaqøéáåä÷œZZZJÖ•ôz§×œ¯Íi¨nèòq—6íÃüïÉN]Qìã§+Ùn…õÌPñ+nþµ©i766† ¹]rãiü‚âââ|wµ+昡Lôæ—æU»Fÿÿ CøY»7Ž`‡ñ|„ì Ù˜eíMnâöãIRtc#ù*¯F2çCy/bÂýèÅê”>9ïêYñgÏä*V3•ãy‚èÂu9ÿd#E\æu¬ ̉›¶Q À;Ë ÂpÏó�»SÉX>ä:‘ãHFð8ñ1'GÄH‹Zý5ç×ü„ÝGGì¨5le ·ÓÀ·øˆ{#±Ý»9˜Jî ˤVNa,{€NLáË,ç>žÍz6œKá=zpDÐwAðû_y [êñïçlä¾ÈX§Øƒa,ç!~ÌFž`7áaFóÖ0‹˜Çó9óXN…k‚릱Êó8ëœÖ)eUzk‡ÎÖï/&÷ÈÍ,1c‰)¿ÒÐ#PÂ]¿Åc9{DÃ\õ†:°Ô÷·y¼,»b_c3kS‚fÿnÖ=é+9iK|tUòãÙÙÑ·˜±Šo2žE<À¹)í&Î¥˜ÜÅstàûTp[Ê·r:š©¥”E f]R¾—Ó#°„“MMl¼(¤ ŸÐƒ›Ã9(póèÇÎâ~űLå1Žç#&2—mQ¥açߨ‘=ß+Äw;ͮڔ\B©‘| `>u^˜µAc·ÁYä×ñâß·ï«·q`¡%Š›á8QØiË—°Úi<wkò‰¾à*..Ž5ÑwÕüó€6,ÚÞ¾Ÿú³ØÅ†V2þˆð2·`óÐÍãoÚñpßòobìeãFTqqq,zÞ¦’’’²²²Ž;öïß¿¢¢"—ËM0ueÕÊ‚M}ŸïÛqiÇÔ†Ô '¥{§›G7¿:ôÕúêúcVÓ¥©KÕâª-[¶¬ÙYnN§º6T7U'ªùhÌ‹cb‚Ä®Á þà; ~pðgc⑯öñJ¾[Ü{Û)ö$ΛÛO˜ÅN(ÚžkªMÅ»-¨µ}½¸ŒïòQ¤ÞĈÔ@NæC†E£¦gð/6’d lˆôˆOâ}Ö’£ R¼±¬¥žË˜Ï¿8‡¿‘æ<ÂuÌæz®á®ä²œtàTzp(÷ñWŽ¢„Ù‹/óK8#RBú3™O_å ž Œ‹ˆ£ž Œæ žàdîŠèáŸæõ¨Îv`6gðwRLa<gD •·ø1Õ47éÁ-œÂâÀ=Lb.ñ1ËYÏQLK¹2P›s —±ŠghâëÜì ØËt†ñåH˜ã..c31³(â-ö+p~뺿{eµ§ä¼Ê <Ë߸²tª=Èrº1"©_Îj©§&Ç=ü‰×Øþu›U÷—çR«>ÖtcàŸ9i.÷Ê ÏôæU6—Ûº‚(å*¾Y£6gtÒ IÇöºzõ¦?_]?x±‹ê]ò«³.-³çóÉæãúeukõ•À0fzwWm4)»±ÜOI^[“›?Ç~Oç¶îÆD&s)5ôæ"žfåKìÉ`öã1Öæ¬ ü“Ÿñ{:0¤ž³,Pθšå$ÈÒĺs8_§3=Ù»¸.áД’Œ«™Ä,¾Ã ¶RÀx>àDžã$úEpü/D?ÑÞ‘|‘’Ëçâ Úó©ït¢s§3m:íMFXðÉ?Λ}Aº¹öí¨ö¾_|g’ÉdeeeþçÆN· 'Ó®Vß7û.;xYlaóeY‚T Hª5•L$ó5Úÿƒ ,ÈåŠrAq DPÅA¶0ûf¯7ïÝ÷Þ S'týW×L]ÆêÿŒ<'Ö':¿Ù¹ËÂ.‰ŠDÇTÇl"»¢aECCCMMMx¶étº´´4%µßŒý¸ò‰s&Žž;úÖoÞº½|{iQéØ×Çf7ïœnŸvžÛyŸ›÷yå¯ô|»çží™ÈþŸ±6­­­!¥Ög$F_ãÓ†pr§¨64ZmÉÛ9«QIfíOwúÐ=¸›™täP‹F}¯ç@ƃs3£x>"¹(§Íd¹šià}Þ§—ò½èÏuLà/Ü`ÇÔÑõôâN¢ Mý!ç!PEg³šñÀa E$ø-Gñ(Ïq0‡3“¡/=¹…n☴q³ø˜Îü0š ÛÀ›\Î|¾š°–Ƀ¹žC©àtú°!­*cJ˜Àµ\ÂXÄF Õ©q¼nÇŒjy4X: ëß4ÐÌsü€JþÁ+ ¿L«jueLäOœÍuif5¤ôϺ€ uÜÀðQ«ç´Üå7¥ ‹92b^Xªàu£öäAËØØ£Àc—=>Ò»x‡Ïó´±§9÷ïô¤Éº‡® EŽ~5µeEÆ… 3ý’r•Yßg½–c-ú—²¾À­Þá5.Èø$ážroUøòŠ åé“oSTì²ßúÁgôwn9&ŽÚ˜X|WVpõôXç΄ó =×Rs«ïoÑ‘R~ú«Ó.Ë*O4»ŠuŒâ!Žæ:.d8Çp(‡Naç<æs$/П¢À`¦…XÇ¤é”æ,ewNe:¿¦;ײÂst \Õ)¡[à1n` “ø Gð ‡r9x¼q*Uª««Û©`M¼6ù1Öù‹ŒOÆ­ìöCWmÄàÛ40Ú;§ÏX!»R˜áµi&}.ñ‹¸«ö(»6°æxgWùVlì‰D8·§wŸ=ê‹:þ§³­äK×~)™NÆÇ †Í•ÍK¾¼dˈ-{Þ½gáÆÂÂ¥…(++Û¾çö „åÄ…§-líÚšH$¡«+((¾dø%w\²uëÖÕkW×ÔÔäVIÏ­ÌAð‘ ***´;´ò¡×/H [8lô²ÑMÝ›þtÆŸ´ 8ä•CþqØ?š²MC_šÊ¥â.Q}¯îë»ð·¦Ÿ3½¤¹¤Ëü.1°¢xuqA]ÁçÊ+çÏ677ÇYvF/S¿ÇQB\ŽoͧhæóViiiyyyŒÿüü1áÀʬÓ“aœÎ¯¢qȰ¢õXÞkËx€:dM4…&°a¸ºŠfæ’ÎÓ߃ìh* Ox y‡hÓƒ á$>¢„c©§+0šÀ+¬å¸„ ‡óC¶³ <Ÿô\Î4~N÷FZ‘çñu ‡%4æü*³ƒ.vƒø‹Íá~ÀF~—pµ_1'¡k¹9)þ̦Œ=’ò»œgs¶óLtOs"ãiæEöç“B- C›m¦#ûð.KèÉ©¬d ÕÇm_%\èÍtå#ŽËxš•IW0;0:‚böaÓØƒÉY@Ïq|RApôæ ßã–2À¢¥Öθ/éülïYúMžg5¦-7îâ¤Ós>¡šçè™vXNUÖ¢”?$”d5pL‘¥IS·[Ç]\Íñôlu'×0ƒ'’Æ&Ý^oÚ6ϧܘq½oouéë‰ï|KË à[ã’w^]øÀ²Ô7ŸÛþáfޢޅôIØZî€-²LuÞGºžå×÷27c]5Œ÷D§ÄkÛi œK†‘Ôò<M¬a=sy¯FôíóÀ ìÏ?YÀ<“¥a æ6†q.=¹ŒŸ%ÜÂmµT'¤8>0™>ü,+ éÿ?Ê«ÏiŠ>³÷_ħíE¤Ú@±wÒ¶Ÿ I’ c®Xp¯}ý04+1¥^øšüè8Ÿk|§qñÿd•––††,fÅý_­°§6ÿÂ#†r$aNYSSÓÚÚZXX¸füš²Ú²Q?õá¹æ2¹â…ÅH¥S5Cj‚dL$“Éä¨;FuØÞ!ÌçzöìYQQѹsçššš-õ[b°x¸{áøp¼{1¦&ÐGôB‹_ZZZXXØ¥K— ]6<qØýƒþ—/º|A÷ßþøÛð×l÷â¸øä×-‰DéœÒï:|ÙÄe‹Xœ vøžÒ•¥…µ…^ð_ï[›"ª<ÎÀ~>;@I¥Rqÿo§ñP{¿º‰i¤iæ%E,•GSNø¶P@* *Ó¤8˜Yôb!ã˜Æ³Bš9Šý¸Ÿ &PÁÉ AB-}˜À4æ2—}HRÄv¦ó.ÃèËþLåXNäÊ™~nR––œŠ„¡«áÊhäö~O-ü”F¤éõ<Ç" ø#O ­!)\n‡Iú>«IQÂ[ìA†#y;ç¡Àý|…gÎî¼E ›ØÛx“f&¤(¢ž›’Näû9-<D!kèÆßåYËè͇|ƒ¹‡ýùOðJN }ùgÊY¿§›x–#NÂW8$娬ÅNœaÈ[–8¿?‡8âAúj²òò�o3å ¬"âüD„íœÈï³ÞNøfØDÈÊr)­\ÚÞI§-ΡORYà™ÀÆbÅ…Š·©$ñëÐ%g½í»®x¹ò›ç”ÕW÷ºÙ]g_8°ñ¬´¢sP'?Úâ-FW8¸Ù-^Ýb§ìÈã7¾WzþùÅßâ(êrªoÞ“8aapg…9ó8Œ¥SA1“ø;Ý¢1†‹XÇ>Q ­;ÃȦ\žu+kC /r8CÉÛ¯Éy”ÙôçÜÀÜ„&Òük¢ˆ­µ²/#X©3ê»—êkÏÞ@õÿ׊G[bÌw›S™Âl/|ALûƒ•ÃD-6^»rWù„廪[æÃI|šÂ*4yqÕ+_U2ÿ?7cØéÈT˜qÆÂ†eeeݺu }LJ6Ôw­ï=­w"‘u÷¨íUÛ^Œ ŒøóˆD6?3¹L8^¶yóæmÛ¶­_¿>ÌBGæa!‘DmÄÑ@&“‰E,ã‚dqqqC¯†ö~`¯ò½~¸ê‡w¸sLvÌØEc›g4Ï f†P‘üoGF cšþ¯õïÿZÿX xͨ5õ½ëgŸ7»rQeÏWzþ×…¾ÿÕŠóé] ¡íô¦îAsy›½Ã}ˆÓâÕÄÊ<+Ñÿ4±Œ:fPýé ZXÈ,޾óÛø^³³9ˆ¥Lä{|ÀkLç¬(z ¼K%ï±™}™ø‡’%ɉ™¼LaBÀÆEM²³¸Eü€¢ÀÁ޲ŽLe#»E‰Q2޳8¯ò1Õ¼ÍW‡ÖrY~È4NÉy‘‹ùud8œ÷™Æ>¼ÍZ8©y‡¦Æ›üI4Û¡¥ÛÌ8JiâºÀÍÌB±’ïí¼M/î¦ëƒØƒõ±;îM†-ÎI˜ôpnðžþzŒ-¥iodL3õlSû±))›pJVM aVšó+Æ1…圖ó V&ÜOS …’@I“Mš9µQ:¡0i`N!ûÑ;ãªÀ7™“4 å”VrÛ¼3Qáƒ-{o?cƦÌ~3{>0íCw˜ÔǺn¦ت;,Ì8"g Ÿ;ºÄ¶­6¦]˜1¡u‡lfFÛÔâÎ ¹á«}çi»-3ï#—V±™ìÅxºñ<'ì�‚žÑàÜirä«4PÀäÀJ.ãföe$£D9Mœ•1€A´rdàAÞäd~[fDRa·™Ëw9”¾M‚a»²¿í}@</Wü2™LM·§™Èd2ñ�Sœ*µÇµÿw+Žyw¥Fbºòg­B`Ågh‚Ämž|•£|¯ðõÀ¦wma)5¿¾úÎt:6¨bÚõöÕÎ6?æŸL,ƒzŠŠŠŠŠŠ.]ºlÛ¶­°°ðõó_ojhÚã©=:¬î†vÅ‹û=ÙoÇÇ%»rÏ¡«Û£c\·Œq‰!ÙG,!–?ÝYçÝZv›—žWÐ¥à`¿ÛôîÀÆ «.ê¹hÄË#BÄM,ö2C7–?vtõûÕÞ·ìˆeŸœûÉŠ‰+F>1²Ó‚NvÍZ2óº™Ù‚l:•Íü??p§Hô]5V[[[?Û#Æ#k»zYûÇ=É)—6çlâÌ}A4&¯A\Í|fAÄ_^Ä¥\Ÿ‡’º„‡É0ýÙ‹~J÷³wèÏz ”"ùóVNã9æSL rTÒ›ZžâP*9˜±5ÐÍdËaŒbwF}©2îçâ„Ò„ós~ËZ¦ÑÀnŒa).e¿·ÐÀ/˜ÃuDè’¦SÅÑìž ø6w³%íÆ¬šÀMŒáñújÙVàˆVßá7 eÿ7·ú7³1ò÷Y–‘à¾Ê;Ä ¤rV²œ¨Qu¡A·$þQ’HhÌÙ¸Ñ Ã\wŠúÅü.#™ò:f%iΓ°1aX•|“:f3š{ <ÜêyncIà ö¬Ö«AÅvßâ6ñ£œk-Yó(ì¦j³ê”² •Í.Ë(JxŸ#èKδÚ^Güeõ ß.}!sé+¹ŠÖ{­ÞÔbÏžÞÍ-Îá¤S[¬HøVûªZªOÒYéOµúCÎIórºó‰uÕ=×íÓðþˆš¢ ¹ÂÇßó§¤'ö“{4¹åÁœ&±ÙÈ1ž9Ó_Ré¯ÿ4«0øøÇ<åï_÷ç)¹–Khe÷2^ò%§ªÝÄìHÃz)ƒ#žÜƒO°‘+øõ*"å³"jø ‡EDûÃÚ|?“ÉdXèÿ"D m$Û4¥ó™îþ¯<!ËQ\ЋñÜa“ iˆñ~ù·Ø …½«ü©|ôs›–I>ÄüsÛZm`èÿ]a*ö ñÑÂ:^{0á.ûXé\Keˬ/Ïznøs‰d"•J¹ õÈÖ ›P°¶ °®0YüŸêh˜ÇÁDKKKX\ eCGBã     Ó|¦ˆŒÝL{>Ùò–òKV\ro§{Oèp ›^Ü0øCÿñb÷O¸÷„ðºb¾ÇøKKKó£Šö×ÞkJ¯®ïvÅ¢sm?oû„&ä²¹TS*Õ‰Ff?¹à“Í£6½flHTXTT4íÇÓÞ¸î ×LøÔ3_êüª¹U]fuiwšššÂ+—ËÕ××·‡ÆN«±±±¤¤¤½Ój﮺1.ëúhúäjªè’³QN1›èÏXÎŒƒENçyæ:ÒÂî”ÒÌS\IJJ‡7¨É*ÜÆép2Û¨` ¯Ñ!ቤ{³nb…jèW²/M´ræ@þF%8‘¥ÜD9ÕÌðÀ,jÙʦòÕ¤a¬Ï©æ÷ö/7r‹+Øt$B±_p=×±o˜‡ñ#Žà,ç»”r«y<Rÿ+`9Ï1˜eŒ`¦íq¿É˜’Ø1¯ƒå´°26pcë)ä^<Ë“­®a&¥|#pBn¿Í‰’?'×gçoIHâbs ãnMu9?3ü¯¼å¢‘¶×”?0mL•Úµ–´øfÒ ¬åÔr)7§½˜tM“oÆ$ü!é¤qÕîZm¤ü!ðóœo2 uå<QâK¼R©oNPïÁ„ Rf<ÌY¯µGÂ"*֫暌;[$™Ô©ÍZEsVŸÕ3Š'^së}¿aŸ•/<|¾¤àü!ÍŠÖÛÈxäD,´Ç-p#Ç%2ŽMûUƃab”ö‹Œ‹Ö::µõ» …ÁºÙÉáã}§oîÑé©úÆÎ¿=sê; û{¯6õ2·÷vÃáýiH¿?§Ø/ŸÈýdú™ŸfL¦2Ëá:ý7t³ðej¹‘ ˜ÅÕнƒyŠŽ IX‘ÕB-ïò"[í*8;¯Ëû©u<µS„^ºüà;<Nqqq¨FñÅ‘m�;5 q=-¿q²Sí†ü‹Êï«Ç}û|6ÞŽzÄŠŠŠ6Ȉ|8~ècìIþÈÎNO ìºå·Ùòùýò{XEìÖ­ÛÚµk·—m¯ëS‡Ê9•¡Ím¿'µƒj3¥™ú^õk^;lò°ñûOÙl¶¡¡a‡œUBìò%£â¸|ü[<ÛÆGæ?aû'†„Ä[×ÒÒrõæO@‡Ô!—̾$·GnRÕ¤O|¼êñ3ž9£ø“âmMÛÂL.«ÃY¨xj-ÿÞŧ”–NoKcï¿î­Ø›W½™J¦ª?¨î¸ c§¹²EÙygÎÛ2bËÞ¿Ø»lcYìq¾òà)™²­÷¶’¥ÿáIZ=quÁö‚Å'/®\R™Úœúl’—]Å1Ÿñ×öcÂËø1»3š.,§/%ÑW±+ÝXÏþ¼±]„}¬ `SÂîÍqŒgV`+ïnK£û#•Éšëóù'ÝÀ�–ðz €€n<@·nÎ1Ô3›=XN ç±…K¸9Ì Ž×ù9ÿfsøwõÝy˜Ú¬ï7šÃîe(§°’µlc ½Ì ºQO%M4Л8(úÍóÑ”î¾À7(¤}Y›ó¶1ŸÚ”Ÿîâ*XÎ(Ó›Ù40†c#WWËö ôŽû“c_pØ£Á×ç{_ÁúKOD<÷ýiNV—ýõ×|=¡|o?¹Üf oqÆVó¹<éÉ"éVϳŽ?qI‘•¬oµ±Ò>-z³wÖ»ÍöÉú}‰1…ª›­gL`S±®)C²zW™Ôa“É ²ÜÎÑ9)²¸ÁÈÀÌ„½ö ,HØOù6鄹-IÙ.eÉÚ7§Oà¹Ôʯš7bãå÷·NëY|öøîΫ!ilàJ:RÉ0r ¡”Ç’¾Æ¶J›­ ÜBÖ%˜°{N6PTžót0­£{~<—©ÿö“ö<:9¬Âs¼ÙËOÐB=ksn ŒJçÛë¹ÜG35/âD6;é˜Ä¾«+n?±eDÒÜB3–·éYf¿œùɤ)¡”ƒùA e¼Ê±=9"Í¡ñ˜ð²eËÞ|óÍ|nžÐ Ç—qÈÃÒbê¼pÅC<a@¢�Ú ǯŒÍb¼â‹Û×ùöùZ´¡å K”!,m§µÁSÞ…?åW,óëññàNüÊ8?Ëæ­Ð…3°ùÓ¬¡ÿ‹w ¾–x”5´ËaY5$@*..®+¬›½ÿìÍ6/8aAKª¥Ã‡ò ‡ÂsÛ<ró¬Ëgå r…› ‡þehéúÒ˜ë/ âJffÈŸ~zaaaYYY(S¾&$Ñȧrz¸˜ï8vWù+,i†W‡—ÓÒÒ2fݘ¹ÁÜ7ªß˜ôü¤>Ÿô É'ÃûØÆaç?a.=Þ™++ éK²Ùl¶9ÛÿµþƒßÜRÕ²ăڮµ›mn-nüøàNË;Å7" ›jö¨Ù¸×Æÿî~PsÇæÍ{msqCq§Å‚æÿ(lÅl)áŒÙ+ÂMˆÉPÚvg~�� �IDATÚÃVKJJ¾È˜pرߋ³˜M…-¨ÕLˆÈ§ó÷wsĺ„7¸ŽÙ‡³¹™u$–MÀL üŽj2Iã(Ìy•"òûðÙHh|PÃÁ¿XÌ tc/psŸrFÎG{È Lˆ�ŠCy‰ÝS¾›õ:}¢Úfu¤U¸åœN‚ §3™HOÆñ{1‘y)§dý&^g*dHšÀÞ ÍJEìò#@þEÇò 5¼Â'ä"âàr&úÆV*`ÿ&&²Ž$9ŸiÌqå[znßËôÙÌñL`ZO£6ZžÓR¢‚ŠKù+ÔPOA`D`MBcÂèŒ_Ò3p>óÝEj“?ª“Îå¥ÞäpJYÊ$¡cèÉŸéUä¥B_OëSgkÎ'9¥l奜¶êP¦ªÉÆœ\ ÖS†t¼øûM³FµZV£€ê”®Y±š—©äŸ™óbÊyzîKšÏ&|=·£@úZÂ×RNϪa³º”K¯6,“;`Fê– ³ng%dSÒ\µÒsIßèå‘£l{„€œ–• ›ƒdN:C@ âë,$Ãq|HæÐ™ÍL‹žÒñ {qD„ª¯mS Œa10/¤S‹KùÿÅpU¾Êg·Û•ÔH¨ÝãB(ZØŽjƒ‰j1Åjx¨Ð7„8‹ÐÊ„.d§*YùápÌûÚ©°áÿÑöö:TûÝi닯¦pujZqØŠ.u ’ÁâSzxP~j¸½÷ö¥'--ÝP:èÑA½§öZƒL6ö Có÷Û0üÆ8ˆxD,nI644äKpåïLAAAeee>=Ç®VHZÞÁá)—ËmÙ²%‚ªªªWŸ¸W×½ºÎéZS[³«œ;ÖõˆBñ@wÜ‹E~C?žRŸé}úLï3wìÜô¶ôîOî¾ÓóôØ %g, ß^PP(L¤ R…) Š ²‰l~Þ™¯�?óot|¶qA"¼;mí»rW!"œØáÓýªžìÁe|Ÿc¨f Ë9û8Ÿé,g=ØÎÞ¢™cØÊÜÉ¢@!¥¼C]à$™ÈÞ<JOFEt{±œ…4Е^)A —s:wRÉSTó])ι9ÐÄVç æ³úHf÷ºœ~è9¼þ 3¾MßáI¶s&‘dße8qÓ¸ƒ|È\¶äLå8ÆòD¤µøUöâ·¬v,d»ØÀÙ”Ð:¦RÀiÈ'4Ó•õÔz¦úÑW½<ÏÖRœeÙ¬œ€ó˜ÃbW®±ì'¹)ËKfî]ä´§]ž18iYBÇ¿Ë::§©ÖÝìÃüŽÁ”3ŠžuæQ¨M™u³šü”#èºÙff7»‘C{ê¶Æ=LJÙ7ç·gÃAì–´GàÊÀoå’ºfܿ­I…$rú¦íѪ¤ÎË9Ʀ•q26¼R›µwÖí5®í¡k‹¦-ƱïpgõÔ}ƒK3²<T·ÍiIø=™žöÝŒVV ÐiµI-ÞH˜Åái#3*©KÎîlö’œ«9‘3S~›ó]8b?ÚÍMÏ8õV)öÏ7‚_ÏÝ>u°ý×{ä Þáj¸¿Á9»Jó1‡Ñ“ž¼H[øõ”°™ÛÛ¨ ‡h0B¾vÔÿŠdýÿ´:tèj½766nÛ¶mW.aââ¡“ÉdÌåÓ ŸíPc;³BÄî*<~èÆBåãPÂØ¼C‡±— 1Ùqð¹‚&±,]WÚûÕÞóÏœ?ôî¡UU}êå­‹O[Ü÷…¾ekË k óÑùᵇ eè§?®RTTTQQÒ”ä>³Ùl8íou¨ÿEêº!ú&>N~ö:-ëTSW³Ÿ„þ/vÃ!ú4öš¡BXÐ]iii¾¦I¬„¨Â\.×ûÕÞAØÅ­.ßPÞ}a÷Õ‡­ðæ€t:]ØX8èõA³šÝae‡¸ïõ¿]Ÿ,ªg c#¤°³5š;éȵ|›ƒéÄÖè5¡,a.*†C¾ã¼E=© •j;ˆãFÆð™Ì"<Åü•K)ˆHÿd¯¬+)+pk«ƒ8›»)'Å!ܘĊx–bê™Àn¼ÅÇ®§,éÖ„æ¬NWѯSHÀ|‡Cy‘ßqb$Ø1…×nMY—ñ ²\Hs#‡ÒŽŒ'ÁYStsByÖjV’b ÷ÒÈ&:óO>äfÒƒáŒd!KØÝ¼¤=þ!8]ÃCl£{(NûÆT+réÇöÌfû4)nò*—e¬IKelduƒ?s2e|@6Z˜ÊÎd7ºg(5åNèoÄ\%+­ÎÂUiÅ9¬ó,iF'"Vû¤Y ˲j3º$,ÉYx0£C`U ©ŽNm0"«8ã×<™pl sÆW¹#%›qOkW»ºõêu±Ìâ¾Î4XºÎ–œßr ßoõ3éq:½lȦUï£ç»ðW¾º\MN‚÷y-Óí ›Ëþ2?â.dϬNN¸¸À{-º³É¼Q:<¦ÇeÖŽ¢8¡88æR?¿ÃE¡†ÀtþÌ3)g]×ä^¼½à¸÷Z×<E†+xŒÉ¬ç{\˳¤82b•¼;’-ý,ò…Ø~.«E>}Q¾]‹cáöè¾|¹ÂØ2¶IMÂfFhCQ¥ždûàgOõþ9b {‹ëŸmªXá_ËÊÊâ*_SSS›’Ñ®UhÖC/:†ì÷d¿TK*¤u3ѦM_üñÈF¦šSí1œ±Þqè´Â ^Ü6ËJ «ŽáœVœoÅuÚ|?C‘y§{Æ !ëUìWâÐ!FvÄÙ|Ü2lO 3ã–Š– 5ÐôŸ†‚‚‚6Úó¹‚\KyKÑö¢ð¹Ê‡ùÄ>8Ì5ëêꬲµÿ֪檊lE"‘H5§†?6<‘Mø´#®îY½pÜÂuÝÖ™<&±eç õ|hÏ.eÆÚõ®x–máWƒÑ<Go2GmXºyœÙü?¬Ýwœu½?þ眲}7›d7»é„„¡÷ÞD”*HD ¶ËÑ« Wl¨((íÚ¥ ‚Ò „ @)$¤×Ýlï§ÍïÉŽçn òõþ>ägÏ™3ó™9Ÿ÷çý~¿Jï°7‡1™ŠÁþS ¢›½¸2ŽfÇpø _-eJ#§ó6‘f)3yÓYÊÖpÓØÈÛ“pHÁb6³WñTÄ&$Ø›hà\XaKÞœÐ#4ÐÀÙÔ„~ZŃ*ëXÄ\aýœÊ$îã|'ÉÙ¤CµLâ8Öð4GQI/sÀàiüo†„6ÐÄó,gkÒÅ4qbÚišÐ’<É1™=Yêw˜:Aá!­se¯‘mä»lãDéFûc=Ù]õuážûT%Œ5‘©÷v\ÆÛlc4?B¹'n*˜Ÿr%³CïDªùßfVŸ¶Y[­”99/ó$áa¡fºBÛC#Ø›ƒah³†[1Üè©”}2ŽKÛ»ÚžmÞÎ) Œ,øG¥/¤¤³~Îz 5„&&th楴IŽP¡B*gA¯'sÚB7¾Xõœy¥FzfZ Ø`bR¢àV„Îd p3Ë]ýG¯î¦ÿ4ªÙ7a t‹x„¹)S&ÑêqþBƒûª<ò¤Û·3>åæBçë<[~"ϳŽßì¨|Þ¾^IUaÚuib_co&ó÷2•×yƒnÞ¢š02{Wëׯ饗Š[Õâ%à½êcñ–yxñb–n´¾ïìô½RZZZ[[[__?yòäÑ£GWUUE •D"Qœ`E¦é± m$³-XÅ:¶‘êv¬x­æ;o,\õ®âÎ\ÜsŠWÒ-¯‘â{}}ýÈ‘#÷Þ{ï©S§6¬¢¢bË–-¹\®8»ÚYA*:f d­ž²ÙD.„ÿœŸî‰ÝËO[>çs=ïaµ>ˆÖ‹g5* EŒÝHÎuôèÑS¦L‰Ä×ëêꪫ«#QãØã8ÊP#+ú¨íHâ[yKÑGÕÈ£½ÝšhÆbÄi ‚Ý=âIŽƒkçÈÎ5Z“ÞNw¤‹[n1@#—Ë¥ÓéÖÝ[—ž²tÂë¢pMftÉñÌG7}`` jSUÓܦBªPÛT»c® A4Éq :‘H˜èÉO<Y‘¨¨j®*ÙR2”üû¿9æñ™'“Éššš}<l½« |‘±–}y`aÑ;¸ylãd–qOòö 'á>È0öç0Þ�G³š‹xFަjšXÉ\ŽáJ& Z–`<¹„2•&e:‡ñ$'QŸ³e«ôÚ£Ý4&po‹«Rjú€ULTâxcUÚÁÓ>HažÆ•”ptÁ7èN*Íï€æʲ¤Ñß ü6ô;b+Ãy’2Öq(Ë9{°3ž'™Ag±Šsò^åM^Êú+ûp2Õ<È-‹C'ûøïìÑ›öÝÏ@$Òí'<º’ÏŸêIuÏ)ûÕ±]þÐ$Áw¨ Êos?*¬*X›õÞΛE{©KS*¶û@ÁÁ ÏqJ ‘tkÊ1 Ç]­½KM‡‡Ρ„#¸·ÚåÙ^3YÑ ­ÍýýBN åyŒQ\¿Ñ�9¾8Ò·ÛV¥|"ï¡.Îï¶1¡;ð…Чi.wHÁ¶*“»Ý[nX(Ÿ•,èš`ØÛN Ý\£¾Û@h~ z”šäô óo½È–P 9×1–F~ǼÀ# NqÍ0Ê9¹Zª ÕoÜ Ø6žÍ)]­ŒS¹,a{ÁkÆ”9©Þ£¿Í)ðw.à(úØHÈaõ¡U®¸Ê¶Ï9íDîÎ&šxgYÆï¸ƒ×™Ì’¬äUŽ/nQ”——Ç>CBNñFrˆÒR ‹¡zïE¼ªCQÊ5ÞKš¨ªª*Ê«jjjªªª***ÚÛÛ#8õΩտ´9Þy_<dŠ:dq.3UcŽX4½8ŒyEEET^+++kll1bDl¾\쌾  cdµÞ¶gÛæ©›ÃBX,;á‘ éžtûÄö­ûoøÇ‰É÷ƒ·ŒTE¢@wªª««ÇŒÓÛÛ;räÈUÞ¢t'Ò¿Ÿ~Q²xN"LDHvÎ&cû¾¾¾èOQů8ÉŽa5½µ½ÉÞdy®<úëZqt¹\®d{ɸ7ÇEhlYYY• cŽ`´‰îÚ–C¶Œ[=®´¿t—6~ËøÓï9ýõ ¯÷W÷§ÛwžŠã÷d߯£ôsò =UÔüÞ9“O³€Vj˜ÍÇDšø“ÙÎî\8¨‡;Ÿðú ÁÕQTq/ÐÂ$>8èž…fVò4%”2‹‡™>ˆË˜MGógZØN?9€óÜàÍÜØ'ðí‚T›[AÚuy.ì0‰ÿÑÃ&ÎàAŽ¥!Ç^ „g›Ø­¡ß…ö }…7Ù—cÙ¹VRÜGš Röʉ<Ó^a 3W$“w'3ž,d#IqYÁîxKö¨²«,÷FÛœuöú ŸO™›ýç÷óËüÃë‚ß›5šiv£\î@KNâÃÈ{1át6¤Ý[­³KI‡ÚK&µÉ‚œ¿Ð›TŸt{°ÿ6ÙßÍû*£YΟ™EMÎÒ¼; _Ï{iÀÝ/¥Ü\®³Ü¬&XS«¼ÍCœ=Ö9½*B{1:o\èE²IµyýCi½ëº_é‘Û6YpphNƸœ…Ü»M_M(Éy0tUhmhIÒ5¿ o*ØwóZNeTÑÅjöb Ïp�gQ’s@hsÞ·¸„/r0ÿ÷õ}i}m2p¦Ûoö“VWèoÏÐ_ª¦ÌÒeA ²;H„ Ç:緬ܴå¨á,á$x‹ƒR>•Û±Eûg¦RYY3l¢-d”¾D?ø!ê5ñGïÜÙÒiHÀ‹[ô“Ž`cïŠe(¶ƒŠ<&¢®U„ˆt˜ŠWŠH‹(NG›îÿk³!•J¥RÇooo6Ú1ÊnȈÅåâɪ®]»¶¥¥eÛ¶m===‚|…Ç—Éd:&wlŸµ½jÓã|÷Ž¥yÙ%Ë e…òæòqOŒ«lªL•¦†lâãÇÚêÙ9²jŒA€#ŠýaÖÖÖVTTA™iµ´´ôöönݺµ¯¯ï½ø×» lï9ò^ÅÞ9†/äƒR¥%¥%Å<„õ…«Òm¥u½u1©®¢¢¢¢¢¢¦¦¦££#WÝÝÝQʘN§Ç=?îµ+_{å²WúáAC®¥8qÏf²Ë÷^¾ûòÝÓíéX©$ö{,ÆëÇë¿ajã1N yPÇKèáSü7²•‹¸•¹lTÌ0•&½Sïò­Nüøõ̦™+¸žµƒ‰Ú\*Ù‹ œ ~Å•üŠîeû sà DKÆîœF+²}¸ŒzÚ8†c’]ÀÏèçôÐm97²-傼ƒ“öÊù/ÑÍ4®åmNeÚ ®a/ü†IœËK\Q°2åôœ[Í|–‘ä,f²‚ç/ÿ;ywq 3yŠqÔ„¦ÜŠAû±”QÎÝlâë.]•ʿ둌×òæxc´7FpjÞuFìcÜ})׿—Þ”ðÅŒ¾Ð $¹)á¯ÿÈËPQbß‚Í:ÉÐÛ¡ßæUkôv»CÚ¤ †‘£» -gdÎÍ/š=èàÄzã:}£_YBS·©ëŒÍªjÌÈ 2®+uNÆš7R—ö±­æÓÉÿ´8bÀ’PtsL¨¬Æê¯nÑz°× w¶{=ç“Qpmw™Ð>Lo7*m|Þ)½þ¡">IchEØ}pÅÓï”úB›;Ò>Ÿµ˜Ÿ‘e-¡ªÐï’&'}$kIÚ‘©¼­\œòÝ‘>ºÍΠ”Ú^ËÿH88Ì}-¼ñZ48ÿeß{ÍQ_ʶÎÌ{jÐÂj<I—þ$õôUùU¥á½+]þUÊø>sø1Îå &QB%3Y–÷É2öE+õÎÛø[óoÛ«/ÍÅËAqÌëîîŽR!ºÑº5uâ´¯£5T¢Ì&Ú×Ç=¤!\±!‰ÑÛøx•‰šOååål! W1ò¾xuޝìÑy¶¶¶FÿF»1xl×£oDßš¬™wï¼tË{Ãx¡o_ß^HÒÝé²íeïª9R®âÎMTüŒª”Ñ+QS-¶©Œr©0 {zz²Ùlggg___l"%ˆ1ôî]Cû GyyyOOOì]'£DLBÿ£vEm2™ü‹ç*ê‡Ådð˜lÞÜÜ7Pc.ù°µÃöÿÞþùù¿ßð÷q ÇÍøÓŒC邳ñ‡#–¸dÔ²QÕÛªíä5ZL´*¾ÿ2\E£Xð�²,âLe,ûp?Ÿ"à&îf1û±;c¹6ïs[ÉœÄ!\Ë4þÊÖÐÀ1üœÇÇT`Ïó!~Ìé<ιüŒ “( ²[zx,Õ”0—sxšîL:?´®`“øZh8mÜÂõl Ý™sŸËéKÏå}›3ø|Ê‹9Ÿ ÝÍ¡<Î…ƒ¥Èjžã¼šsÍ ýîå¼8( ØÇ9˜çy³CWQÂ'XÁQ-4ÜQä,e¢Ê¯™aö¾Äûž¤òØÜª99íÒŒ§xŠ“ÒÆðå|ëƒAë壕mVŸ´±ZwÂÕÖ”e-e·ŽõÉÍ^Lú+—ŒRÝâ§¡#KœÝë±£ú=ª Ô¤d*ìÓ£)%—óth>kKü>k˶ùêLçeM[åoIWlÖ^&“öP‹˜4àñˆu—vpÎÛY§ŒJ;0/É[ôò])_ $;5÷ø@RIèþ«žåÊQÒíFg]úeè£T§šõ\ÎÖ‘FUùás3¯5¬` Ãe¡ïõÉõú-§gýGÚﳺø û”;¼ÏŠ¤Ó˜™ñÙ_˘¨åLË9}›0‡¶´Ýíµª›ÁÏÒ~™ëý^rñ9¹¯÷Õ—ýãŽÂ–yÁu_Nlî,´máfzŒêÏ­¹Qu0!Ÿ\ŸË¹Š ù#UœÀÏ E½ÁÝ¡Ÿq.­¨¨hhhˆ²„˜¼³^by\.ÛÙ&ñ½äŠYºÅYÑ.mGGG1絛¯¯½½½©©©´´´««kˆÿÖŽ–ø¨Q555³fͪ¬¬\·n]ggç–-[úûûcÿˆ¸­õ^úI;W·"Ÿ§˜ú¿Þ××!ýêë뫪ªFŒY~Dñ©§§'ª¤­\¹2Z s¹\$ìïÄ£Ã;²%ÙâÞÕ[ç½uȇ”––æÃ| hŒbFå†Ê×’Þ‹ :¤ÔÙÕÕ EGˆ"GÄ"Š2¿(°EÓu§úúú"EqÁ-Ò¦ŠUEÞ S<½Å9G±ýpJD‹ÊhÝÝÝÙl6š™‘ŸÑ—vuu qÚŒ.-zâ3‰fxgã„aESE²%yì—Ý|ÀæÇn|lú}Ók×ÖVo®Ž+mÃÚú–õµÏjO7¥ƒ ˜+í«²ÙlWW׿ÜÃí¹r¼_é +ª >2Ôn§„Ky–ùÜÅż΋LåPÚy”ý>OŠ=ů9ƒz&ñwsO2<áÔ‚ÝxŒÆñíA-¨$+H&d x“_0Ûò6±ˆJîæ[ìÆ:Ú¯%œ—·–C©eLA†OqZ¥LGª}½ÛÈŒïÓÆ<¦p>糕¥\ÃMÆÊ„™œ@;/ó7²wq)G±”c¨¡•ýh£‰L¢¬µpñE½›EÔ³$xõã¾_îpa. ̦!TõF Ïü²×òÀ—ûÜÜgvÒ[B²?ÔH5Ë Ó•ôD‹®mîg¿r³†)ïw诿£*é°[’æLÓ¶Xs…Ê·‡ºøópm-ŽÈ«¹Äs%¦×9­[¶ÇŠ*íó}Rê Sz%BÏ0¥ „æJu)+GÙs“K,U÷8¸Ì°½]nOHר/´¾Ç ZJP¢©EUÁ“I³ . åBåÕ§íQnq‹ÅÛ=úlàŽœ½òÚKn'(ø ï„Î˺6Ž ¹Ñ†µ~]î3¡M=ö®õl“9•*è§™ë²>–Ðße=²GV 7ä,Žá�G–™yPþžzùPOÕûÛÝNü½Ô ëöçøð…rÝâ…#hf*)zØ6X;íg8/ÒĹï÷^¨è¸û#âHs¡ÞKôºxI*ÇdÕžžžîîºâB_,”{ÂVUU•——ÇyÃ.ŒKþåèîînooO&“QMì]+555'NlllL§Ó+W®ljjŠ’° ¸k¨zÛnm«_Ý_Ó@¥Ü|@!_ˆ¢l<çÑ1‡ÌêÌ!hûâŠk”3Em¤ŠŠŠ(, áhG{‘(lÄ^ïÅ…Êø¶ÆŒQû'™LFzðù|>ŠÊï'½Ža1´äÿ2†ðÇ£d®£££¯¯/:¥Gº3 #zŠŸk÷Ò¸eg,{ýâ×çÞ5·zKuŸ¾ÎúÎQoŒ* e«Ëº»³Ùto:š¢è´‡ôhÿŸÂÕp>Ä›¼Cý` noÖ10hÕËpÆr³Žä 1ù ƒÕ?Lf¦ s=oÒI? y}PZé6e-ïä‡çh Œ ¼PÐÂéÜÉ2Ž¢™»ä>˹lçO 0’4wÓÎmÓ(t~Þ„<Ñ<ÀpSÚ÷¸¯`]«ç9— v´ß÷g=G3™*Ö0#åør]îf"yòt1fž`sØÄS¼Ùø&}.ï^e kY|­×Aÿpìù,æ0ާ.ðVhä}“º¤}–³;Gþ#tx‹û“;P”3ó1‚³'%••›]P8´Ó&ž¥½UuV¾GàœU¶ÜRçà~ÏtX¿ÎÉ}–ôî@š<ÀÛ̸7tTàC#5 XÑ£r˜ I#ºõÖ)MHð`÷¼>–¤-ìPUêÅ„¦´ó 6óý¤Ãëê5¦Ô™åjÕÇ\jú7`UÁ†áò]ZÓ>\ÍÙH¶¥M 4‡;d®Æ×x-gD¿Óx¡à„¤Kó:øÚp7¶« ìV°|ÅózM(¸›7šTæÑW°€LÊ·S6–ÙÚffh¿Àm)§WZ“uZƦ@yRAKÁQ<fÉzŸšã¸^ß¿Û>ͺ~ëžßÀž~|±ßßá3³<½‚3øœÈjFò!Ž C5¯riñ)“ÉtwwG©I ֊ׅH`içýo¤[·£†ô-bž»‘Éd6oÞ\|(ÍŠËkjjFUZZÚÔÔKrÄm†÷ X£i¨bÙ:ׂ"È診º:¡•———••EYB´F…©ylm»·½zé«{ÞµgýâúGüÿÚŠ‹"}Tè‹ .±no †Œþ7Ncø@œQÅ‘,*3Fûƒ(œ$Æ;ç¯Å6fCî( Ç9âÎqå½2˜¨9§Èùº¤¤$B«g2™è•øY2ËbçßâýÄô{§§úS[go]~ÊòÆWå̼g&Æ,³ðó ß¼à͹¿˜[¬’=ðïçÑÚ9\ °vÈþ÷"ÅŠÈÙèžAÆØÀ¢„ÓòžçdÆñ?ÆìAŸªãyž?PÎyÈÛÜE?£Ó ™Æßi`1§ñ›9œñyߣšQ¡M,ç.�Û©â›yÿÍ ~˜rOÎ/‰¨3ý´ÓÍ+ìK'`€JÖp+ÀXŽow;»1Ž…ü‘õœÃ+<ÈEÜC?Çó5F†6fÈ삱dXαƒÞ{pݾúó±Öu²'B?dv‰Í•vk3×·æç/{¶ô÷Ôßfd¥ÉÍî­rH9M*Ù·­Â;¥.벎o$]‘ó_Lçʼ4bº˜œrUZS™·›­fÊn†·{€}Ê Ž <žqCޯ慎l×ÓçùÉ:ú}ˆcjM,ÑÓd8 ìz­Úðµi=ú�� �IDAT•ú7 zHHgúý›3J¨ì³®ÌÜ: <Ípnw?jÑ_ðñP½Œï±{Vš™ñH‡§Ë}¸Ï·G¸b›üHÝY |± ¤€Sò²yÛZ4&M¬W·Ý¦‚yÛ<Í꼤üj¤±-–„öOùþ€ŸqHh·‘éð@Îá}¿)‘ÃuhEÄFÏy-)—•O».+Ÿ· Ëœ/äøhèÖ‚¯'ô†Ö†#°ðƒ†©çäJÚ<ÑžPÆœ‚ë›ýí8?ÉÇz,Œ8sHSÎZЎâmŽ1ÅÈÀÈ-b`` ’Y2¨AøâU#¹ˆeèâìjHç9S Q#Œ[¬ñ³ë|vfhí Zöô¤R©M›6UTTDÝ—âÍþû'WÅWw¹ŠuŠ<Ajjj¢d¥²²2 W±¶i6›íªèZsôšé÷O%.qƒ§w|ïŸ|cØÊaÃÖ+¦f!oÅ9SñÂ+¾ÿ¼$Ê"ˆJ|C3™LT´Œg5ú¢¨kà(ïšèÄŒ´øfE´³]À1b*Û¬éÎ;‰(uÃ"{ñÌŠŸ·kÁI" g1è?fCO{tZ¦&³}ÚöªUUeÛʈì˜LyhÊ‹_zñKÞØû޽‡<!ï§%ù®@ö£íhЬÌx <_/ç†f<ÏúA?ªÑ ãp Ë9/edÞŸC‡òYŽ ¼ÎQœËõœL7mƒæåo j¢wq>w \—÷ß\O)39•_ ÚØ/f\Þ?˜Eϱ7›ø;Ó8—<71•Û}FºIb#Ø“&6ÑÁÞlao‘?äy‡ç]Q›I³iÐôd1gH.÷ɵà§8óBý &$ùqVªÓ!J~oÿ'ý1³hÌ6oäÕ ¸)´ºÇ™}:(å·Ÿemʸ&ïp>·Ë’IGf]”rkÎm¡¿s[^Oh¿¼†:í=Æmt'Ußï’nŸ/øD^e锟Œó­•>²Ñ_´$äú¤ºuŒ2«Ý[cý¬Ò¬×0IÛX+Ìà>ß |1mĀ͡ÝêtnÓ”òÁ‚dR*çK£ì™ÐµÅ¶SMiÂø­¶$’Æ÷¨ë÷rÒI­V2·ÜpJ;Ô”¸²Ö7YÓ`còöàÕ‚=ZÕ|޲^åp&å×îBÙœwrŸ CWê°$ï>¨Mø\ÒôÀÀ^V.2©NI—ße\——èw7[CÏÌðõõ’iŸms5WîNÈå- å¸Ïðu®Ê?s<3 ~h$¥sºoÞ.Õi\hIŸÞ7™Ì¹š‰\ÌÁtÐÇ•ƒ¿—æ1CúCq±¾8M‰W„8 ‘¾-†- ±IŒ‹„C:.‘Ý»þà£VY±GC¼LDÕÂ|>ÿÚk¯AµÜ2™Liii´<í"»z¯×c§¸^‹,Ĺ]ÍÍÍÉd²»»;™Lnذ!‚Õu t¼ü¹—ŸlüÛ÷ÿ6åî)£^U’.‰çÐWÝW½¶z¯;öJ÷¦ß•8<ı·ø•Ó]ÈsD+{ "Uª ¢B\t!Å¥Ýhõ–àf9¤ÆX|Ø8eÙÙzç)ŽP¬«G‹]&ßõ¢Š5 ßµYÜ6‹>„P\üÔÅL»ø˜‰ÖĨF%“ÉDi"&Ô¼]sÔµG=ÿåç e… Djœ‰FÇ·nÅž5ï®Öpw„½šÙLåûƒö}/q2íü tà(~Ç™|‹4cy8P—æ41ÀfBþ@=%L ‰OÐÎ[|f¾Í(d`wæ“-x&iN§ ’yIe9wñÞälZy24’_³û³˜vXÏ?XCý”ÒÌOøM`dÂy_ <îTŸÌžg,3ÙDŽÿa9ßeg º¤Gž~×’l³}‰«9Ñ)Æžìk;/qÿw|ù,«b_>VÝ—Ÿ1ËÏ»æƒÁ¢i¡•YkX]py¥Ö^çœGš® oÏ0âm_(•nµ,gOZòó^ \Y¡1iÏV4…¾‘÷“‚Í’¡2¾Qéî^—´¹žKKœ“·!¯›r>½Ê„[C_Î+«PÝå÷Ië¶›“4"­v›% „V­ô ®Ò™ÐÓ醄5#<žPWh6²Ù•úIÒÊnÃr®.us…¾fãJ´g%C Ü5Ùš¤Â;ÆÔ[Ûâ;Y ù~¿©0¼Kc»K pe³ÇhnRjfF©”’O¸ªàé¤/„(èb_My ôR^å#6›Íq9oóãR7 3ªCM¨· ùšò@}‹–”[KümŒD§OåLèõɥªàxÒi¿Êy!ü§›å¹|“%TðZ •”ÌÉ&mNøpF‰î¬×øæRŸ½?8²"4Ÿ+IÓF’Í|dP zí²ÞÎM¦˜àK|‡-vm/÷©÷ÒJߦ±ó¶³ïxÌvв´T*«0DÈÀV_QOOÏMwLú‰Û<;qÅ Ü¿«ÞÞÞvÑÕÕC²Ïd2/þ÷‹s®š“H]0vå…+ …¤×'E_Ô;®w v ùäæƒ~~Plæ«ùoþ/À¨ K›Çð÷Š‹ÅgR|#¢û[L/+ŽCQA,ªyF,ìˆ^E»h­Áè¹*rù1q»XÕ¢ø=;K>Æâ¿'b¹ë§±ø•Š–Š÷͘ÿù{<¾Ç¤ù“†4‡�P‡&;©ZäÙHÿ ^íÊø1]Å ¦ CesxƒøgRÅEÈ¡ ,¡–W_´r&ëù2c(e;3©#`_ÊXÏî|‰c#…òPkèMÊùkÁRÆÐLËéb.KvØ>)¥’W¹˜=éa؃±ƒ°õáÌ =O]Ò†NaAà†À� Lgk™Æ'x‘µ¼Ä:^ã…AÊ6fªÖsš–3n®§Îà>ÏNpù³š{m[à챯pò5‰¿Œó춤y¡á }jf޶¸ÛÜP7]ü=ë¢Íº,éÑWPËü¤Ü\æ¦Z‡gŒÉx5alèíÀËi7¦ü1á#Y³&†öaf¨¥àUö¡&áÈ„­·æ,è5w=Ö…êBË ¾\%w@…ÎÐÚ ™Œ·3*ä+5äËz¸Ú>ÖŒæÈ+²&4U™7à¡~cË, =Pá„~ ÓÚdZtçµfÜ[æàMÃlðt¨½Äø¼a5Z«Êž 3RÆæý¾_Y¿ÕÕ²-uÆôº¶Ôaýó®N8¯Ü#%>è(8¬S’íÔ°'Oä%)$-ì³%T‘2+TäéËêkwWJûö[Æ+yï·˜yT„ž%ÒTU«Ï9=Tú=ûóƒ‚ÖÀ¤r+²Ö^ wïõÓe•¿ž¿ú; ç…ƒ^'¦Ì,µ%g8kÙƒ)\¬j1þüÈjoH *J"e¼¸©ƒ£u*ZªŠˆ‹%؇¬DïÕ‡ˆ>‹ìœçE/ÆIFyyy¤­Ð××!#òù|dQX^^^^^ÓB£3TÛ‹kDqÐÝùÄbzi\ÆŒO2Šammm[·nÝ´iÓ–-[Z[[»ººÖ·¾áï é0]QQѰ´á•¯¾2cþŒ¶ám[ÞÚ2¯¥{J÷ìŸÎŽ.$^¾ã°£=ZˆãI+FZFÈ·hÂãt¡XȈÔèãˉfã]×÷!¥¿IA`†D²øˆ '#.T<3;3©ã µBbU‹˜{%(1ò>ÞâDÛ ØB::H;*¬Ú™>èceÞèÅØò8Ž£±e16=’xŽ^Ùvð¶%ç,9úKGW­ªŠ>Xl6„wU]]=ï Ãw¡j±—Is$/Ò5ˆJˆš=x“ø5Ø@ϰ‘ë©LŸ·>š^p2«Y˜FõKÐA#ãù<³‚ÝÍFŽd>+ø�×ò’`)÷r,MÜÃÿØ«ÞL†YÁgI’ä—ÜÊB±>0<aj^? úx<2ŠÌ»¬âkìÍXF°‰_r9Ÿ-³0i¯«È"a¾TðKXO’ i4òD.ôð^¢Ï¦sݱ¹¯ù›Þ´¡ÎNe7ÎÊY(edé½îXç÷¯$TP:ÂZlã^f“I*É™ðݤsäÚü®Ü…œÂ)ß =œõÅ„¾Häs`Æ8­ÖTZÕl·áºº…cùx7û¬juh­ Y›óÎê×5ÞÇ–©ìQ“÷p©“oæRH*aC©ãk èÎZÜærŒ¢6-X“ÒÛ¦/4l’ÖvË Ž#—©·Me^%-6$|"©.ayÊä/•¹m„‹Ú­ˆ4ý’j¯%ìè­N;»Rk—§Ôê{Œ-¨¨“/1àC%ÖuÚ7ïšÐå½öccB“óŒ¢9¯ƒýÓûŒ­aT‡YÃØ—?1;ᙄsóMìàQ­¢!iBÞÈÀ™Ik›èFå–‹fK.ä×yÇ–kÌëUéâNŸœ™pFhÏP;ÇIƒþ/äªõÈßÿÑbÆLT„Ù¡µÓßÕŒ8^ª¢pR[[[SSûĹQ¤ÔW#ãì*VÝÞµÓq$óZ,lõÉ¢z```ÝAëF.™È%b’д¦-º`Q¡«PÒY2éÑI[+¼¿¬iȼŜëhNâÂi´R¿—a*•Š“Èhf¢blôþ!M&EƸŎÒŶ,Åq+š‡b p,¶´ë fgÖð»"Nãšäi¾iò^Ùdl{w‡p¢]Ñæc6/ÿäòY¿žmÚ***¢Žl”ÙÇÏ^ôE±Îý?§e§Sjdo±š„ÑOú´¢w^Èj¶RËtP`ø$=)œIçðf„î.Ø”td ”%Ìä9>ÌïÃ0ž¤–—Ê”w.÷ñŸÑ)ižçY^ã Œt©¿…#’öÏRN ›z>Ê 41)’¯ ,è"ÍS<ËÓÜÏõ<5ÛB‰Ðf”–tÊù>›sVevS]†ÐÆÐ-)G±š¯&\˜0–Z5—Ú«Óó÷P“òyJ¬¨qχR_üô,¸œ“ Æ„~Ä¡2ÆΧ&4“9)½naû1¥ÎìRÓ9"°¥O_V3ìÙns(W0»`j¹¡yy÷7è ”±†õÔwx'kJ¿IIËF;|ŠÍ+‰œC öÚÍÚÊMÊ•ò•õRåÞª²¢Îá½î,÷‘1'ý-|âÒÎ'Ο]»¢[ûZe=Ì+•~ÐsùKG!ç¥.m¡W¨¡*òÝ ªà–¼=êŒÌûEA&üÉOÇ—õM¶µÕËý¾ÔèØ¹œ5&N1¼ÔwFeÜ®>ëgMFçÝii¥U¾”³¼Ke¨rPÕ½¾’ÑÚgI tàœ”i)i0+é?’jS&V¦Œ¢¤Üð*]y·öz¢`vÁ·ø}y• ¥u¬évh(xƒ’‚w{¦M¥±[Mà’`dƒ2®˜Ü½:Qð[²þ;«…½~uh¯ûBëC yš¦«vѲXR4Þgm**Áý{�åˆÒñjwÞ{WÝŠx«-¯UUUÇ6lXMMM$ýɹ±¡ŠGœfŠÆÎßeWш´6"&oT ðs¿Î዇¹^û„g&4¼Ü0éÅI{<¼GÅÖŠwÍáþÑ;8þ½½E,zkPb8ÅpŒ—®xiþ5óWœ²"æAÇYÔ«{5_’ ­Å#–œˆ=«úûû·Ù¶üèåQ+1úkñˆ“ž³EâØö%‘cÖ«Æ÷9JÇ¿=óÛ÷Û¾×={Ÿ?þ]ù1% øYÚu滋 ‡±€J>È[œÇ¾ÜÄYËÛœÁSü–_ÓJ‚1\À‚u¾’SÉ ô²„ƒø3ßcCÞôÐL'§p§ñ³ ;`[Æ1Ìæç¡³r>Á‘<F;¿§¨}}³Ø˜÷}>C Ëèâ’ÜK;‡‘åoô‡fÒÀ™¤YÄ $¹‚ðåpöâi˜E–9õü† ‹úÏiÜúnÁ!<Çîӱ'Ÿ¥*¯® Þ©ñN:y5ivƒÏl·!«+0©WyÚĤoæUå½Èõûb¹%¦¬ÑÒª%µÃd¹›{ùSà«Ì <˜P—pjÆ¡K–%4lW>ÍÚ*r’Teš—˘Zô¶|ÊðÐæ¼ªŒÒÀº5öÈøsÁÇûÏö lLY—ð¾¹gn¹skø½O§ŽzuŨ= ík*­/˜Ô£pâêÏMKvïÎÒ'sÇVøJ¿-)_©'UÞãöÏ'>ú­ÀT¾1Ýú…Ƈ’ßüòÔ§fg3ù•îL¸`/£×Û­àæí>ž`»¥9ßHYͯF¸²ÇÉ#•n¶.’Y+“r£Ìlò_9ó³’þ”WQoœÆwέñí~™rhàj¶çlJ:¿AÏ&}ÖöÛ‹cûtð8÷óa¶0°Ùá£%|&¡+ðßyËB׳:ëÙÐéLÏ{Þ ×¸l¦¦n¾Ä…Ü’sGñ£>‹ø6™Ð•\Ìh,Fï‹ÞQE(R—ˆ[cÎf$—W~b£¬˜!o`ã0cÌ¢®¸òS,.þ®ÝâZÖÅ«¬¬¬¢¢b̘1»í¶[ThŠØÍï3kÒÚÙYAª˜~TLZB¾4Ÿ($¹¡kâ¨7G!ä†HÅ{óâlcÈ¥E°øFÄ1µ··7âÄùh<á»°z‰^|‹‡ô ã_üô‹MÓšöÿåþØØ‘éˆöQ•lñE‹Ç¼<&_šOf’¥¥¥QÏ2ŸÏÇlª!pƒþŠþ·?üöŒÛfÄsû®®cÅŠ“Åb¤û6U\M³Hž£²²2~&‡ˆTÅ}¸(›Œ¾¥»»;vq‹‹«Å§·ñ¤#µhTtQ±Çf<!Å”ÄwÝ¥í$ó´ÍW?¿`üi0Ùê§Šß²„Oñß`,I.!Èù$—òöd+£8*ðuÔ2š£9Œö”›÷óQÚÉp0ׇæüœ0=2ÂàC|ƒŸp}L`¹†7˾ÎaÜÏñƒþò'2À8ΧƒÝyˆcÇ=¬g:wsT™{Vð:×óòãHz9Š–A’Ö±ŽVzÍ»Îçz]ø!–Iªçò‚ò¼u9Ï„®æ3)i›}·ÎØR/ÔZøcÒç'Ç-lK–ÒÓgò‹O”Øõ$¯äRîàr¦Rêîa¦…ŽÉZ”pOÒ”:ÇOtIÒ­oY^0§Ìð”¥#t¥jæ7ì¹®Òˆ#$(O©-QYoraÿ×J¬*±…‹Óþ²Ô/ÚSú÷R›Ö¦oþRYzó̉×~2yÍ÷jÝbÉvw–„ٯ핕Ÿìª=¤¦ÚÒƒ­¢&§©Y_¾¯¢æ£¿¨VIu M œÀ¼ÑßüòºcÞê)©äGu&®3¹Ã;5¾\)]î¬ÆP{ÖÖZÐÕgÂ×›ø[Þ'òÞ Ò¡¥ÚSžüx”%)5ÊÓZ³¾š5¶•„OmñlNkÁk#Œ/e£‡+©mO™8g¥}*éGŒ<TæÄ´ïÖùsR{¨2%,5“¯rsh wÐ?s2~ü„ºîâ*ÖÐËMTñØ—zª8ì}îÇ‹ƒÇÎ#Þ\ÿËrÐÎ)K16ÖPÕƒbìrÔÏœDG” Å9S$âõÒŠ1c±ß`lL}o¬}µÊŠ5‡8GËÓëäx³Ÿ­Ê®?m}ý‹õ5«jÞÏLb¸Ú®a&CVÃ_,ö5.--mŸÐžKçâ?âHuvv¶Uµõ ï‹›yܼ««+žÕ²C¯=´jYUùÆòu3ÖEŸÝaæÒZÖWÛ·øÂÅCàÅ–Å#Ù‘Üí»m>ps|¯w;k vtttuu½pDì@õóŠQ”ñ+ñIcY‹£xñ‰¥Óéݞح0²ðÔ­Oæêëëkjj"AÂH1²Xø8N w µØÎw¨¦0h€û/p/Ó³”ÐB†9œÈ›,çPÆ0’µ¬e!/ÐÄn®„‡¾µ¬’.=O{Á+Ô1…_RÉtò2ÓXÏ!,a[¨äG¤ ˜È^<·x‡ƒif5½T0ÍÁ t'ÇçÍ­,f,'œCñ”Ö8#£´à÷œ™01kP´0É Œç8^d àWàÃŽYëƒõ®äG$Ê\IÈ–AŽŸ0¯Ô©)ÏgmÏ8¿Ä>]zæV;$«±ßœÐ¡µO ·[J}Á~•ÆgL õò|ºaÊÛݘó@Æô‚òÀä”ʬôXÚf$†zè©´oÊìŽÝ›=â óZrm¶ŽèÕHO… JºåìÇ‚ã^«(˥ߞ4Re§õ3Ël)µtƒi¡ÂT¦dj¦ªmfÓ7ýä5zÖw C{wÀ@wY>1²bÒ;…_}¢Äè›ßQª+h!Y'[¢­EkÂS †·ù+myµ¹GÎëÌÝž0£àµœÉ£Õ”ÙÚìÞMLOšz íÕ‚BV]èú>'—êL9#çÆÀiY錶T{ §5ç¤VÛºµ&›pRm  4'=•0.MÞ«Õmj©RÚs¶QO]…6žË›ÈÑÕ‚ru­J žMHVKU¸;4›V¶2=ifØ^áżLÛÃìw¼<¼Ä2–0–ÃYʼnl¡œ£c¨ÅÚµkŸ}öÙ×Püc.^©£_i±GvpDe´x Š;ÒC ÅúQ?¿X›'Ò«0ä÷?Äï*Z’¢Ó+//¯««‹ÒÝÝÝÝÝÝMMM‘Ó`”ÃEïŒ7È+¨Øq8^n¢Z”Jf2™H 6 Ì1bp‡ DYaý©ë«¶T5¼Ôà{IÄé15-®t;fû© H±7GÜŠóѸçgW‘|IIIÿ„þGllÖÚ=¦{Øòa½¬²Ùlç°ÎÍÇoîÜ­³f[Mª?m XØñ-•…®ñ]‰\¢i囹÷O›^Éd²fIÍ¢O.:ð&ò‰8ÒǹK¼e‰ð Qâ’Úžª^VCrâŠY¼o¤ãÆØŠØ¨%Þg ‰+ÑlÄÃèŒêÆCØâÑ$Ä®Q·˜?œQq²¤¤¤á톒dIÇ”ŽÖ†Ö’TɈ¾CHÍQÖý¢ oî‡îj)LÄ/$çÖÑÃ. ™µ\@oðÖ Eá ü9tp9›ø ›BÇçÝJž †Nâ”ñAÖðçq+øÔ']P°844‘–/pÒ QæV³œ ”0fP߯™§8šN¶‘¥=ðR`dáŠeöìwÅãÜÊ+ü=åМ¾Js úZ½ÁClà·ƒ¬ â Ž$MïËHBò<Å"áö™Xúϲ=mS'´‡zû,£*éмï„>\Hhisè줽jŸQßos¨ªÊ«i³‘|Ê)Øêϵ~Ocà†„S ^¤o¬Ž5jæ¼I)ûÓÖýáœüæˆ×Ç·.ÿ^ÉŠLòü•ýý»å—$Uô ú +\ugpéåí×ÿ>ñÐGYº9íä‘Êš8 {ںIJuýìÚðϧlëªï7.ajµŽÀ œUúÆÔò͉ÝÝê—ÝöcR#ïÿÐØGælö³f_ëUźP60šl’¬BÞ=3±`Ã&meêSJ» ý iT§Í OXÀåáýš Z8>´‰©L úLhCèÕJ 3Φ¼ÉÂr3žìWF5#§|²ŽÐ§\“wuÒÛ­uFm0§[–edùk« …ÐË¡¹y·vøFÂí¡=XOÈ!œº“‹¶X4àørwfíóK u÷,ºø`` PSØÑñ´ü‡Ć”bvVú¢X\“‰‚Ù.ø¿ñV}g[¦!²âÅ­ø¨Ô“ËåŠc1÷6þ`&“innîè舥Œ"ƒv}†÷>ÎócŽýÚèÿ_4#‰D¶2Û:·uʽS$Ä¡½»»;Êóбmþ·ÿÈU½˜[\ÐËårÅ™b”AF«mql‹z'Q,\|åâÒîÒš¦šñOŒošÒ´æ#k¦Þ;5¶°êÓ©Îô•õµÖ´Žió®5éñIßòxcCã„ùvþëÜ#ªyn»uóþ›1÷Ö¹ÿ?ÊpDªjQ¬Ÿ[¬0;dWncýûbʸ±4DO+ÞD{£âD™Sü0ÿ€ÚÝkŸ:þ©ç{¾aKÃQUÖZ¥ûhþ5;Çð±AmtðÏñSîáržô>ŒCÉs9x”W9Ÿ‰ÌâI7(çb>J =}48|J¶°“©\“tYÁßB÷s/Û’.JèáLš‹¬Ffq3 ™Ä¥¼ÉJjYÈ)<ËSlf)‹ÿ™öñàSúZ¤à¹‚®ÐEy%” ¸#£…ûy‘VÖòE&^ÂZÓ~G5[YÏÁ<cÞ,/<ì­´·ær`hbhNûÏPúIê2³ÉI:Yy'öE60ž7ù¯¼¶ŒÝóz{Ìî1r˜’ £ù^A}A˜pH›+Ó®8ÂÈZ=ÁÕöZÓ¤t°Z»4­æX/Œ;î¡ü^«ó¿Ú³ëö³Êÿrö˜‡5üêÔô–¾”²¼æÿ¶óŽªÎúÿû–é3™LzB ”�!ô"MAźö¶ØWݵ®ºîºêªkõ£¸*VuQP:"½&ž2ÉôrËï ×Ù}Üçy~÷Åa˜Ì½÷;—s¾çœOÉß•Ÿ¹-¯jŸÏÔoxTF(Êã”0-øóÙ]èhlÜx±XV¯ë¯ìü0=.DðòY„+:yV‹Ûcc*Qo]ü›Æi»©³‡F¬Ž‘ Pà Òˆ…˜ÒÀfX¤³$BCŒï%Fd1~“…ç(/•I.ÎòP 3KãL˜EúÀE"–L6.ÑÉ•ñ¤itЂ´Á g(<!"34Á^…iðªJ…ÎêvÜæž�� �IDATzê‚[¹ 7+cÜš$d�t€–Ž¿7ódP KÒI·Q ƒ•/ê´Â;0†Ë:3 ëàK¾Çœ²)È” ´ÈÌët¾ÑyÒ¡Ö¾ÿ4šü‚Ÿú¯ŒïF*ÕíДóƒÔ.œÉx5^ï90Æ'†ŒºQ E"‘Îã‡a†bÖß_ð½µÙÚ^ÔnTÿË{öÞ°wÇ;Ê^.ë–„Œ “yônD"‘`0˜ªxÂf—iiÖµ²,«^uÿMûÍÂÂÈRÆÛþ°­pyañŠâ’U%îw¯õ½zmëe ,i^­uvkÑ’¢Þïö>tæ!Õª+c,²Q�ÕÍ®ûîñïÊ—u ìÈÜ—iB½[°ÙlmÛtIoܶíºmŽ6ÇÑò£Æý!Ûø-Ë/Ã,iöa¤! rBOên‡Ãá0Ô#{LËT«ÉÔj85÷§–ÈÆõd‰Ygo>ûÚí×FŠ#I{ÒÈg†ƒ!3ÿsÜíž« pÎ ÁhÈ…¸Nƒþð{脃ð>ŒÁA¸ö8»ös¸¼P#¡ Z`9\ó!¯ÃhpB XA†a(dƒ¬TyÍ67ÄàU>„•ð[¸Þ„é¸ ž†·!-0–@xáø¨„WuÊ$p7päqÔÞƒR‰»tvi,:gé\"Ш³ÛÉNWúy ‚ð&,3¡<É-…¯a*y× …ôC3¾%¾¥F ^âL…í2sbð›#N:Ê#:Ãhñk„‹é+’àé"de,—yÊÁÕÒE²¦ðÙ*†t!I4ñ•u!Ö œÓ…%{9 ÷Ó‘pr{˜B«À‹ çlâÎÞövôÆÜ–“ª#ŽPëqpï»Âûs„5nÉQÔ6ÿ ©Æ+|4¼EË’[²ÆoOâÜNÿ^ü¾®Ãÿ ã‚–Ã}î½±]·^¹»±u»ÎÔ*ò˜6~몋onohÞäIÞôwá“ˤ¦ÉN[c+]ƒ¿“`ˆSàÚxÖGN+ :žyL¢#H¶ÄÕ0ÀC‹1€W$‘K´‰=«æYñI4%Èë@/!TM­ÎQ‘2ì²sj&ÕNöVp í¤ÅXªp£Îƒ`•$ªbün²py]e¼YËI&AØÔÅê�Ô �®1ÖÂý°Þƒ‡áIXI…2¨„%ð2 €ml¿Çrð‡¤óQ.+VÞy †Â•: w³ÿ õD÷ÆétBs†Jži3qB›¥N¹N8ƒéèèö×ÔÚ®««Ë¸ ›Íæ÷ûÍö—Ûí6Ïk8¹ÇÈ FP3ñ f·Ç(£Ö¨7âUìJ·køet¾ñÇèXD³h §6TŸY]örYzEºáCoª4YÖˆòfÏÓÌÄ'Ô^ú•p>ã²­aëà7'ô„©.aÎf’Þ¤µÓJ#O'ú$v_·{Ò“€¸/¾ë–]e•‰ ˆæDuá'ÝMÓ:†uìüíNMÖÊß,Ïý1×ÑæØ}ÕîA’BÇî.aOì>w÷€ÕÖ<ºfâcükÀá‡5õ'ÍŽÔBÐn·ëºnPªÍ^⯡ô9Ø€“ôl¦¶SÛ�©%iê ²§tH·QVêà°ÛŒÖxüÒÒÒŠ‹‹‡ b³Ù<Ϥ¶I^öàï¾þ]]]!°itž½S=ÜwügœßÁð㌫7a4€÷ENÖ¸šŽ[Ýo„à8 î†;`)¬=N  Qhwáø†Á?À +!u0�b°ÆÁtø&AÂpì‚]0vÁVˆÃÃp&Œ‚· ¾ƒûÒuî‡Âh†�\ÓáRþ>Ïžçp| •*_‰Œ‡Ãp…Ê·0S&Sã#KÂ,µ2Zá&K.ÖÉÌãîV™ ýŠÅû¤™ •£†=ðƒƒ«"ü�% 5ð V)…Q:£àØocA>§ø¹º U¥ö ¨½ˆÊL«ázq+5ÔUì¹ÈBmÎШ!É<¦³WàQ“cìëKöÀøY;éÓL£Ì™3’X`d'ïý×X!}QËs7ç¾ÿ»–úÞ”nñMúZ~q@»­K»²™H‰ç½ó=¸"-ZÐ$z ,©íõ-Ïähï\û²Š¥™ì8RúÕ/t½2ßòæH6†ŠÙÚ6%cÍÅ-Üô|•xæ)Iì×ÌW.ø§ÿïó†“ÓE¤ë¬†C"3Ò‰´ƒŠ(mg' 4S/°8‰Ô—‘U Ph£ÝA@Ah",0AâF¶Á\‚uL-“šZJJ„¼éä<_µQîÂnåª#Ü5†W·2WãÈ™V€(Q^óàORë'§‹z•Q279˜¦“4+iQŠ¢THÁv # w’[á� µâÓøPá+¸úÁnX G“å«ö=ó‹à&xNƒ©„»áiÈ€ë.>v•õ´o0µPÍÈ~B¸pêîÕ˜™Æ†f1íbMš°™ÀÌ]°ñO©Q̼�3ânÊ:fÛP’¤¡¯ Ýô—Me ËþWò¢^}fu¸0|òÍ'ÿ·K÷s¯%æ¯Gü§Âÿ¬+:º r3Õ]§<:eýïv¯÷ wËŸ¶ämÊÓ4-P¨:£jØ“ÃE8ÖŸPEOã·•µí¼vç´[§™«ç«ô%Éê3ª³–f‰¢êS›§4§oL·î°Ú;ì›îÞ4ôïCOZ|B'T4ïÎTÊ?á{ºÕa¢(t1³$5*µmJ›ßr·ÜßízR)b†8¯Éå2±fǰã2µQGii©×ëMOO·X,.—ëéܧoùñ–´´4—Ëe"}R›ݾӞé*Êa7œ¸úÁmà…Û`"¤Ã 8MäZøX£®‚JˆÛˆlqâÐ�õPKÀ wÀ¨8N^u|T: ,õ¸Z„Càp <®Ë·ö8¹I¡%Á[°z§P˜WÁÃ÷‚¬€/¡”B3xàcÂ’Ñ|áIà^ø÷/–Ih6¢INY£@¿Ï!ìí¯v\†ê#Äø­—=ã´È}i¼Ä…:Š’á:x+‚†Á¥à… ¯vðqˆ:›H¶Î…n´z$ ü-€F¨|.ñw!¼ß(ä |¬Ð¦QgKôÑ:è¿ MÁGdΰ‘Œá‡+t¢2]¾·¯·¼mOÜYçÜÜ•¬r_?žkrÇíÚç;߸Ê"s»T1Ò’DºxAâýämZvSVåÃXíxúpô(Át¤È·hwÿÖæž§YŽ&'x„Ûÿ*RËGW¹Å¾áçÿäøÇÉ¿ŒÎãH-yGB‘-¼ag†]&ÝJ§Ÿ|'¶ïˆÈU,ÐiUQ%ÜL²J¡E[×'¤_ò¢ŽZU¥#D‰sÃÛš6¾j'ÛÍiˆÈä܃Xe–JÌvSá§=Iv=7šÊd2­{NÉæ2¨„+H,‘(?ÂEy"ék=´‡x7‰ÏPÿ’¹2[+ùIš€¤1ËffÖ±Ì(¡ž7$ /TÁ‡'b×þ§QÛhFô¢|c$6cKn:$ a¦.E–šíü %½ °¥Ó2äõ!ùëòEY4%õ̳›n³šC’$ÿ`GyGÑ×EÖ.ëOJqµúìên Àÿ‡q1?§ðÛó˜øøD‘¿f|M°$XðmA¿ÅýÚKÚ›Ç7}PD¦-¯!±(Å$£†Ø9gß}‰Dê¦$ggŽ&k g5ä–ßxfcÚ¡´ôÒAùÌÈ7ìh˜Ú0 f�ÇueYþ9^Tj)™Š!4¹z©“KMÓOi fü„ ´Ú¬eËÊÔ˜jöN=Ïÿ¿70/’$y½Þüüü¡C‡feeåä䈢¸^^?šÑƒòIɨæ 꺙Œ{L÷DúaØA ^ƒÕ0Jà�‡4ôÖy áPD* L¥ª zKÜ ³ Úá Øc ¼PçBA<?‚§A <P�Ð�vø>„L¸Xd£F“vL vˆÁSÎax˜f¸CgÃqHáȯ̥ý"ÓØ•IÌ L€¨~ •>Æ@ lÒi‰S›dlò–¯´Û?dóMzŸ-ܲŒšlŽôƒr¦-'#3óñ«ãþïDf(hðviˆ2³$Ãf‰ªH§@›H$WŒ./ W¦ÍMß8*xu2dHSù Îw0 “V…#ŽÄiè�C%¦Èô×)9(ñ“§‘tñ¦ûìˆ+Ó?¬>z„2HHtiHʆ!ìš«tÄ‚›Æ¶ß¿*«~zìíÑ2ƒˆ`o!+^zP/Ü–³jlZ¤ 焽Þ<d¿µ•PI…xØ9±}ÙÖ3G²cÚ‹¿jo£TÂ'î-Iîž¿$±Ò'P—ÄÝÅp9ø„+Öi÷¼ÂyMÊ ¯£k[J³°È·'©qHgœ@¶Œ=Ž#ލ#Ó·“>:ØÓ’ñû_ví./ïì´tf·wŠzIH¼ý5aÇdg½Kbà@ÚëÉMà S4{™½b‹xÏ:eÅoºâïÂ(‘N>CsIñò¢¼ÜIiýœÍTÄèX ÈŒÎ!QÁÃå‰Ó$Ä$ohœ#°(ÂáåÑ5Üù;ØË`;´ÂLX£A°éLJE®]»ÖD|™"¤©Ø9ó0^7á¼FÝsB-ín{çT&M7nÑÉ1€ ÝtnÌÔÒó,ÿmCò'\uLòÔzŒ°bÄe#ÎÊ‚µX,F 1TÚ{Û^[ØÖ1ª£³¼3{g¶ñi®:PòIIÎ9©g1í3 ön*¢ÚÄþ¥V¢=Qõªªš OhèK²ª?§k¾çò=9»r yÀcòµïV¯€».7–kšÑ”¿2ßÑà0KMÓf5¬,0@5gÕäUåõûºŸ±3ø7CÞ#nÑ*ÖÌ­)ÚS”·3ïXO/Šo¿/T’uÙÕá2H`N§SUUER¶Þ¶µiBSÓ„&O£GlI1Éì‰!4U—Œ§.‹UO©ŽÚ£öv»%l1þTžUÊ õÚÙËȈFiÎ;u«¾ñÆ wÂWí3…z~/æ‹Æh-µ"7Ë,C×f³ôdÇãóùJKKÓÓÓÝn·$I‹,‹Æêc‡iÃDQ4Ü8.´Yø>rܤ_@†;W Ëá øªàØ×�Ð×qÌxî‡ýI.†t™?©¬ÔYk¼¯ó Èp/| ‹ n… ˜ïÃÝ›`$ÇÜ>€œ Càa£Wß�gÅ)ƒ×@…Áð2L€S:9<°>†÷ ƒÂk*?ÀÐKçEoàN(€&(€·Á7A Tà ð4L…L ñÑ–öÇ;'Ÿâãiñ0ÿbæ}ÇC ´Û5æÇÐ,ŒT¸²‹~:wÁŽèÔéøámk‰i•é­p–Äí:×ê¸uÒÃH ý%ú© cð¸ KcD©Ÿ¨ÈØ|,-ôIòì™’¤MgoŒâ$ ·ƒÑ\íeËÕþ鲪哎h ÑhÔ)*hÚG¨OûÆýÚ+ ŒàØ–"¬É=<LŒï¾†s?Õž»Ü}ý¶úA»Ø‘ 9—Þ›èogPŒ»t~+·¬³‡ûw…ªí¾V„)l>È�wä«™|r½ƒvË=ÆÈÔYÝŸ½hF­ÌývBë¡RïŸîÏ}ôºƒ¨õÜ8û÷£ëlƒØlák)Á> â-<÷I”·¡hï\š¼íRWõÌ&vu€Aò—CâÖCBïN׆S;Xs�)‚UeP&A°ø×¶M-ˆH L…XŒa1v‰ìi'C¤Ê¬Nä×¹HÆi aÑÉIvµq@C¡C 2á¨ÎSs%„ÕÍP©³N“™«’ÔY¯Ãx(†‘°vA=xa­ÆMÝ &#X›º|æßäWv›˜Àª_�GýšÃ4/7ŒaªÖÖÕüG=´ÿÍËŒ¥W¤—¾]÷Æ×¾¸¶uLkŸÏûúò6äeîÊìÙð4"²¡øg¬U·äÔ3m§VŠFªèV˜Ð€x<þsÕUÍÌš–Q-%«JJ¾(1Ýb±äÈI$qO<áIxš<‚E0jGcI‡?9|Ë“[|û}ž [ŸïûüÜ:dïÎÞuí®Ü×sëOE­½Ý.¨Âö{¶¿o¼ûÈO~öš¤ŠcŸ{pÞÁxz<Û•ZKišfªÌšÁã6À{º®×Ž© 9B½—õ6Ê>ãÈoÈ_w÷:#šØtsU]ýõh±Kì¹90ñ–©«m|HÏ*ÐÄÙ§b5{îDé'qQƒÁ Á‹ï©gñsÈ@ã¸*à(¬8r¡�N…‡ Cáth„Åàv¸æÂZ¸NáWáu¨ÔYó  nøú€†"(„v·! ‹Á ÷ÃÛǽ<Þ‚û!î†UpüjÀšãòéà‡åðP‚óa|y°ž…[�˜¯süQà*˜ µPˆ/ÁÐVÜÏÃð4X`)<í°–ì$A™=·B-]\W"÷yLèðqϳÜz1íg'ù/H)W©„åP¡VX/ÃÉ:ßõâm‘á"Ijt+üèf’›™ýQeö%Ø•d±LƒŠOà÷"I ×äñ€†’׌$+2´‘}*Ïóc!UIVÐ!Q¬Q› ÒF‡D̚戕Úõ¯$*ËôŠ™mô𜇠2ŽÒ¢³”ü÷híªSîêÅÑ~ìó‘Ÿä¶jÖv†–=òHfùäÄ—Ùf/wÕŸžEœ¾Ž2µÃù²77[–8õ¶¾i|µ<þÇ£dd¨‹ …H:vËØïÃEñÓ[ ël<Hì+"ÑÛ±§ÿïr:ûkó³ïP¢sç!ö;xÅGÒÂ0… ]"u!°€œä^;åäo:/‘‘tTÏvQÓEv”¾.&õ h´”Kø[Ø®2=Ê$K”¯ê˜$ÐOå:õˆ#oOŸfÅí¦TÂ)áI$™Mo]6r“üÎÍ#%¨mH^š%Ê#X;ÉwdìnUØAx\à~ê¬QùQc9ˆ À™÷J¤ 2Á‡a¬„Å0Jæ Oa ü¹[ßé²Nªâª‰9þ´m~!͘ºïæÄÛ¬<º1j8…A»ù²Åb‰÷Žwø:RÇFWêr/7Ò0«¡|A¹–]M®ÓÏ9}ТA5skòÖŸ Wu“f0+Åntà_¸ž_¸/CSÊ�˜ô<Âyá̽™Ã_¾Þþг+4Ë¿«â Ä3âöv{7|à<âœtÛ¤¼ yšUËù4G )š¦9N“låõ]?aÁ„u­ë&a5è“Aû3‡`+F6Þ+žV—æ®q~fôs$}ÿ†¹7aŸ&ÜÑѽnrÝŽ›wØ;ír\N½`w‹[Ð~ò0_7Œ1ÝN·¯Ñçô;S·iÇ>„'\íž £Á`<©×lô– Y©Tƒæx<n°ý~yvÅñy’d¯ ð€Ænx~/ÛPpÂØ*,8>I[ásxê l0ZÀ&0T£Za<H\¬ðg¸öÃN0î<z‹Ü ¡B L…zX&0Md¢Š¼Ð¾‚"°Ài0–zð6B.‚5ÓDf¨™¯ÉOsŸiÕÂèonÓÞgi™§Î©IÖƒfþ2ÖHT6À—0f*|ÈC%¦X¸t… Ù /Á§0Qã÷ЏtŠVA¸‘¹¹:I¨Q"+ÈD‰u 8Y¢vdÛEK’·Ö'X”B‘ç:¨lŸNr¬ô²a‰æ’×L³FÒI©N¯l:êYwxjÔæÈ¾š˜÷U}ý»rÚ­Û³ìë*¢¶š¤Äiú=/ ŸÉïå' “Phµðt:Ûǰ/F,ÂÝò¹}JÙ±Ÿdc¬<¥Pê$Þ‡áíŒ@}ÜLÜv’nkôŽÞÒõã¤vÅ%Ïààcש±8¤š}¹ ë4*çÝ*5–i› æ7[a§·ßæÎÃ7§u0J£ØÃæ {aDQ Êz‘"+Ù^6ßóˆvyç½Ál\éè‡x7Êy5”,|?€‡öÑlâEdŸ@i&‰»:éêd’€5“–V2!CÖðÚh,dùA΄ v/ËE.mxGàfXè§=ƒ [™5:ƒežË£¢š‰¹TãA$’þl‚-´&é†Ãp> V…÷! &À¸_™iTUF£†¬A¡5À©jå?v{Ö'¤vý_FoÊfíyú:tì¸|GÞæ¼œƒ9i‡Ò\ ®nX�¹ß·Ç÷oEÆÖìì­Ù'¼;Ó¬¤ÛXżkÓÒ·'¼;UŸ×b±5Û°FÂîÙÎ2}ç];'üi‚M±|yd䆺iu}¾éc${MÓT›ZsQÍI·Ÿ$ˆ'Þ(dìÊÈØ•ñ ‹éïë÷6x-‹·Áëïë÷UÿÛšdÈèÔ‘ÝüÓ²lúݦÓî8-IÈÚÕRÖ’·&xÄ4ÿLH‰-—mùþÈÞ›z›b&±ÚHi‹ÅÀ‚š >¶ÓMç"¦a>iݼRÅ®RÑ€»ÙøîZ[[u]¯«« ‡ÃZDõ¨‰dÂàH´¶¶v Ý̵ÿ[d pö�0vk8a)HpÔÂØçA9¬+dÐï¸KÖ28úÃ\øx $P hÔÁ§ð¬‡Y­ð_`‡�8á} «ÀYeðh ÃéPªS¢ò,Œ4Œ%òU>;NæÝ p.T‚Þ‡<HÀP sªÆ‘ø’»Tnü˜—ç ¯]¢x”!ãÛ ¾±G§&G‚‚ XÓä-"ë­4©Ôª\ Ø‘"™:_i” hœ,1GæÏ. ãV9C§Q¥E$]e©•;¢¼Ó4*š)P¡ÂKfQÇc[-}UÚaƒ…0DÅ]I}-NÚ­Ìôø.HSS´??BYD¬tC—H­xÉiCZ£þ+fyª:Ña{èkº8lÁÕ‡úJrºtz  ¾òíìJà‰áË¥)@…‚,P–ÇØ=¼±¶˜Ú’&ò‡Uú-34«M)kQ…ý†ITZ[‰Ö{Z¶T^¸]¾i¶?ac›³u¾i¡ÑE¦soaèÓ³÷zD¨ñ‰Ÿ°À41ÀhÏ¡·‹¼z^ ™èöf^{U(ð²ÊðNʪø¦9±õ¡­rÍ–ÎSè/P_ŠL¸Qà‚&ê ’Œca¹xuÊm¤Èjæµ ‘B¾o%`㦗@DÀ£³2çÄÜÊGºÆvAWÍ~Ø OK�Ec!¸ €|ÜŸú_7©Ä †Àà…ŒŸ+ƒºÑ\Œ„dèM˜½þc’=v»‘!L«ûž”Ól7µÇÕS—ïTšÌ6ŽÑx1š¦y•ÙE4“„Õj5ɹf¾T%Ø7¸÷¦½éé%Ÿ—¬.¨9¥¦m|[~0?/œ—º³®=¿vÊÍSþ—‰³çàý„…  ª4… MzÏḇÌÂ׈×í¥íÍ£›cÙ1Y–QÈß’Ÿ¿%¿ff;K÷!¿+?cw†Œ, ¤7F"ì)ÞS=˘3ÕM­‹»ãz\—CrÄñ(ΗL&K¾,YýÜjÑ!øj@Ï»+]RZqJ…Iï¶0]BÌ˨<µrÔâQ%kKŒT×­ríÿUlb¦+“AelLgQckÕsÓMiå„Nc&šÃX´H$â÷û¯×k±X¢r4 ¶··ƒA#Qü-sézRO(´†ÂP V°C3Ô€ö€!h†£0ÖÃ28 é Bœà†ip¦ œYð œ_Àj(.„~Ъà0�íÐ •:» öA ¹\cœ M° & Õù¦À(øBPp\švÎq ¢5P ç ”B·xuWßÅâsõ¦ »Ë8XÄ_Ö+oÉ*:4Á­ŒÛÂ$%nnÞÈ{·Ã“ð%dC¥È­1:Ôhä£à†xtÎ’ 3Er5":ÏA ŒHòq&ŠÆ$ W:ýbäÄé§±NÉfŒ`Œˆƒ¾ùD;°CJ ,Ñ™�oëäB‘F;bôîdE6å±aMÁ×îˆ^üpñÎüAúÛ݉ÕEj[†Ä¸¾9ÔZ¢7{•h..bê&2%á“Ûµ«>è¼è›ÀÒ+@L ƒ«…`‚…V’v"I^Êæ¤&KØûÑÔk Ù*jo�‹ªdáØ§ß÷³·OüN©+PqY|Ä ü۔ݱ«>ÐN[iÙU®Í< ¿{ßX0Œ¯–´ÄèÕØ­9‡§»9ìçñš~ìy(ÈIˆ%íîð'÷$r“ÂçeTë$;±Dy4Ig_Jì8TZô“êzm¤VÌÂíGQç-Xª³N…ñqlvÄ¡ˆa "kx}„:h9ÙÊØ(UQ–‹ÌÓ¨’°¬I¾LИE¿cuË!�’ÎÛ 5:¥ð!ü&C¬@;SÖÎÔ&íf‹fÿqeKà 8 2zŠ0 ‚àñxR•³­V«×ëu¹\f 1�ljD"Õè!uûÜÓSª§IÝkϹTª˜››Œ7…ˆ±•6Æ!Fº2q ©`ž.™L¶oO¦%Ëß*ÏÝ‘+GeïnïщGí]ví°fê–î½joÖú¬Ê+*%«”Õ”eÌ3L÷#SºÂ¨–R½ê ¸|*kÕó5ÍæOÈ2ÅLŒbOW#ÎV\^Q=·ºaJCÝ)uŽNG¿/.XÚ7�� �IDATû¥5¦qü.Ó«Ò»ÉTžUÙ:¢5{W¶%j©¼¬Ò¡:2Ú2L¡)¥*bd�»Sãmé¡ôC35lŠfDKß+5Ùʆ*•(ŠÞ&ï×ÿØ>°]Oê ã ·zê<ÆÆEUÕúõY[²R<Íf©¦i~¡fJÍÞßìÍ=”ÛwCßž‰ÓèûÕL«)Ú]ät:SeœL (ã9ŒF£f«ð¯|o4“Éd8nmmmkk«¯¯×µo³¾e]]‰D" uttt›òº\®q“¦þ²ðl7¼ `\ éð\ÃTxDx΀'~ca†Ê³*A1t pA'ôÖ + ?Œ€‰ð"øÁ“a6È0r¡þ [a9ü'Ì�‹Š ê <0Và#¥ ÃnØ·B‚%°nƒƒPÀFxGçx û¹„¬-(‚NAƒVø–J.]¬rßyL]Χ/º%#>$ÆqÞ€ƒ:‹àpŽ2¢q΂gTü:hx­ Hr‹Æå1Zæt’¡á¶02H³^¬ W©¬³à’ø,Ù-TV“$,c¡"ý,{x AFA5ví÷Ô/ÒZY­ï«ßö¾›Be›X?N¥ÖBa;?L&q„`ëÍzàdiÇʨü’:ó5ÆùôG®ïÌ>G\ôñúÛí‰a"q‰Â·wáÎAIóÊrñ»øa?ƒòZñljg0¹“˜÷ç<ÕÒoñÃ;élj·‘ç7Næñ…Ù$6&û_ÿzsë²'Fón¸ÂÒVŸ ë(Õ'ÞÈ)ûyhn'ûtf§1Ì‹·‰×uæJØ9™oË =ùhçØº¾. ÝÎ6›µ‹9vj‹¹=Jž_1½R_qÀ›Š"&@NÀ¹"ÎS8¼\ ¿J¶Âè.jÚiÔiÕi‚P†Ëƒ+Âo}T5£ëx²I´áU¸×@ù±©| 9p-ü+H÷$øöÀžK²KÀ ²NêÙê;Y•ûõk>áIÓŸ&rlƒN(…ÁPýRw ÝàgFÐÉÊʲÛín·Ûeokk‹F£¡P(™Lšj¤Ý y©»àx<nŠSüzø×L§º)íþǸyA×%ÝSí±´[éßlãñ¸qïû¯Ø_wZ³ÞY°¢`ßûlŠ­à‡AíÞLÓD-©%íØÍ›2¢§ /LM·F3د&\Íår>©u§9´3k©°¶¥Û¾è{㣾=°ßwǾ2[Ð&Ge@ç§¥Èÿ!?_þ€€í7oþÔðüýùõ³êŠ#g:'ô¹'­OoH?õ¿N $B¼»À®¡ï©õøð5kÜuå®Ò…¥éÒuë±¼ëî]Åw{*L¾bU}ën\Wü]ñˆE#Òƒé¤O›­B«ÕªÙ´®A]>Ÿ/--Í L%“Iƒݳ 7•SŒŸC¡Q&þT6Œ-ˆ!þk|‚;äÛ>vÑŒE||A8Ž…b²ÔøZíÚË»²A6h0zA;¤Á¹°Î…A° lP—À' @œ¥ó··»?÷ÂóPi‡× NG! sŽËÛŒ„£à °@¾„©PGa.„¼*ãLl……›ÏóM\(2 5VÀ™ß+´Âv¸’P7Ãwp·…áI®ƒ.>XÊ…Ëdlv¶‹, °~ PåКÜx o”ãïKA&“läïÒž¾Îÿ·ù}o­§^ÃØ§41¸†¥«ô‡,Ê4rÚ¹R§FbÈ#47ó˜Î·q’y„Â86uÑWà@2ýú"Vs “ûýÈ"nµr$Ú#Ãæ vÞy„ÚС—OFïÍ·WÉÏæªå–y~W,'Ge¯—þQz‰Ø< éES=ƒV Í`RêíõÊ÷œízõaé÷ÏE§ïPß<ëµõá…–§.O;ÚKAÒ‘dÖu2y9˼ÌÖðY)Ƀ&Œ4²š4ª‡#fDïÜ\}ºÂQ ÃÆóã÷Ì ÒìEȦ3Ê+™5~â¿G<0‡Ó7 ó–å~[ÕÆý–à–¾Œ8Ä¡.2 ªk ‰m>iAæ(š.ÿÂu÷í–›f·HóÑx„Ã!vˆ|ZÁïÓÈDýÆ2çKÕU5ø£ÑM<ßÁ_ Xæ¾"úµ’½â‰ì«"¿…°Jz5 ™Ù…•ñ$&qt"uR!‹"YØna]3Ca±…·UjtFŠ4ØtÎX¨SÜD,ù»Äæ8ö$šÈŸ½¼¦1¤‹¹pƒ5^â~õÂöß·°²‰ÐóŸ‹´©U Ž> Up5Ìü4„1Z0ZRiii^¯×è~h.Ó)ªçL%5{ÝŠý9­#:÷Ô4Ñ¢(š¾G©º‚FÜ4ñÙ© sŸn\¡ ‘>‘¶qm#ž•6‹â¾x 00ñ¯w^µ³ó¤Î3柱ï¢}€»Åí­õþDä²+ûçíW”Ò¯K{Æ83öÔX:ÆÜJ‘uO]ð„+)ŠH’d€×NoH%fÝ9+•ôjšY˜ÉÞX«c-Ö°d Û€i/OÛpû†ñŸ/ù¦dí…k=nOúÎtC¤ÛÐÑðe6Nš:×QUÕÒn±‡íº®Á¤§¬‰£Ùѧ¡OþÒ|£F ‡Ã‚ Dr"‚.dDz­iVSÙ„\F³¢‡Ï;l×í³ï™}ŒKgþmõÌÂzåý+Ï~ölƒ¥ët: QH �1Ÿ739™Æÿi®2«vEQ *žÑpN9xÊ«·¾ªiZŸí}ò*òEðTx8®AÜ ÀÙ3]y ?(° š¿8‚°jà"È„xzƒ rá=˜�ìƒß€ –ÁïàMè%ð¬/œ¯BÚ Þ4ØxÇ 2C¥°ªÁ[a.¬ƒIn‡“!Š`n-€Æ sàR…ù ÀU ÀV¨„Ï¡ :“¼¿ƒá3¨xO¢£ <NH;ä1÷T^Zσ™ Þbi{ŠùçQuøæÃc! îƒ[`!Ï·à“EÎh%ëÁn™1vÒjÙ¤ss‹âX0ƒÉë¢ÞI«@$Bƒ“ªÉÑÑ:ˆj„ p„äC¦­l|»£ã«¥~ò'ñŽPU–0á' /u­\Ó…7›úyn¢!†JèÁK•‹âYØEßMŽˆ×ÇAû3g4üaEâÒ†–7˘´Ä>wdtáÁEš“œ$ª“[³8ÔFc{„þI|-Är°Ø!ÉÚ=Ì-à ÄhaFÓàf@€`«:™)rÀ‰&2.Æ]Qè9m©2CöiÊ}OˆOÝìüm{+¬p¸‹Ã! “>~›²eLî„\n䟹Œ°ÖIšÎ$ UbBm]hégEQ¨صŸéx,À›n¤“x”‹V¶DÕ–Ï'A Ö{™*‘ÕÁžzl‰ìtòBø¢¸-ô×øÚÃH™œ(ŠÈ?4IÓpôÇQÉ…Ùv®Uy_¡nÍd¹ÆœV¾„õ"ãtΈểã‹ó0Ï\,>ó´æY§?ýŒJoÉmùÆŸË©²:½¿   77׋²,·´´´µµI’dЄ{òùÿÏ¿<â2UL8¸‰¶0دV«Õbµ[ïžñ˰ìj˜ÔwÆ…6aäŸGV_PÝTÐÔï­~‡.;ÔQØ1¤ê§µò÷ò˜w ô¥ÒT3xs—ÚûêF 0^Oçÿ$ÍàP]t¨}p{zez*¯¶ø³â‚Ö‚ž€èT¿Ÿ[)!ùdLÕÌ*ç.çÜs_¹ù•sö“:×1GbFâ4jóÔò­ìÛ\=£ÎL¬Õj5d­Vkݹu¶€­~\½€Ð­9όDzcÃ^æ‹úM1÷¦ I·ïT×uMÕT]UŔТ-ˆ*>äÞà¶·ØMEZ³ãjnŒºÙ’ý#Ñ þØ6(¡ÍydN8®›X·÷¤½–¨eLŘ_µhƒ¡Î.ˆBÚàfx*`¼½À~(„$lɵp§D£Êw0FÁ>xfBì�‚Çsá°ª¡áøE°ÂßàX«`8@„³ŽKn‚é0dˆÁ;p%Üÿ•Fg”÷’”ÁE°¶Â>PádæHli—ò%®Ù®Q%…Æ«+¦sî¬9#<ô„H¡ºlÚ \¹™»ÎGÙBR…ÉÐ�3A‡1¼¸—ÌÁƒ=°Rb~:îvŠãììm<·Bvm‡ø N°ÌËE’D <䆩°RªŽ’wtþ ½W[ïù÷6S˜I›DP $Žô�¸t2Ø£ä‡i± ´âHfÈÂö“Q@ëPâ;ø!Bv§æè$Mzz&7|Ís‹Ä®)Á•“$D ‡€µ…F§ÕK4+BCžˆâPù,ÑäÙÉ…ýÙ䤨Ì(;u¹m ð‚vd  !&Ð ièd@ˆôP°à¥Îýq¶hœ ¹Ð–C–J¯~çßè¥ÐÍ{»è_L[&¤‰XœDÂX%Q]ÂÐÖ4\lúwÐ Ð& isB§=žQW“ê8õkñ“kÄï|"U"É,VkŒìb@k'Qð*?ú™©"¥Ó¡J¥TXÖI±Æ©°Hà:I£Eöd0¤/ì†[àuA‘ËT.QU|P OÇü+8e#çï¦n–PëâßÇÚ©:7¦ï”1ò‰Çãáp8 Y,sFeì…»ÙɧFmÁeÎoR‹¶ž§ëfY”ʰùoA¿æ¨ŸV_¼º»ÊxÞ†¼Ö1­îz÷á Ëa¹ì…2g³SQ”¢/Ššf4YdKé{¥•çU¦Æ;ÛÛÐ…C³*²Œ»0Ò†©ëjŠšó¶Tð…‹E1Ó•$Iq_üÐé‡}2hÐÛƒRÓ•¢(qKÜࢥê\¤·L±ãó͵’e9£3#ë@VíɵÕÖêéû§ÛíööööTñ=ãwŽÍ–Z¥&9¿ßo¾?5÷›EaÞÆ¼@߀j;.bîîÜÜù’$éèæâ˜YÓ<éMs,ßhŠB ‡ÃŸOÿ\ j¶N[ÕiU*ê熦2¥Ì»3%»RçaÆ~Å4;î6jM•¨H­ã'?uYâñx¯µ½ ×î½xoÅÌŠ+þzd`p>œ •pŒ„ÿ´Á·Ð6ƒ÷Á¿`%\ X³¡žÒŽ™ƒÌ…oa8< y°p.| 8BÎ`ü�÷ÁÛð ì†KEš®Pùø¡ Á=`ƒW`,¼NðÀp̈‘©bƒ] B;Xà¯pÓ×1j/]A `“ŸÙp<§EÎäÕ;¸îU’ÿäå‹õd/øPâuùëtÌaá[|;ˆ¾_°bœ{ l|ƒ4’îÕYæ¯ }<ÚŸC5lõ3Lå-‘°Êê ú1ðÞ0Ãh ºØ&°2ÌÕ cjÈiMð"®å$vó¬Ê“!:U2w+</Pßgâõ3CÇïe·Ÿ¬.Ò%¬6Å)؃?“.™:½«(‘ÑÆ:ˆ·‹<?¾^Ô~ãûäÖúuÎÊ= ÊY÷#ßesFŽÝ„ú1¸ o1 ’^IÃpJX3qÖsÑ>žÏ&³†±2^$•>-¤{óp`»“¼0’ÄþJ’ô\ܑȑªÔå3ÚϬ<ºê8]¦)Â� .?ó­üå(¥2c;ù0ÉE  ‰¡ì¯¢—›Î 9Ð}ò7:fï,ü¯y­XŽ‚üÓ_៱präÅÑ‚åbñÁÅÚkwd]ôœ´Ý×Èþ"¨8üd=IV’:9 ëlƒ*‘-Q"Ê1µ¤e: Møa¶ŒeÎyÛþVÇ£|£¡Kc}‚ !GåIbmp–D |p3#ü$[ð¿%ðP6¿oýÅønKŒ°[YYÙÞÞnH—677ûý~S„›cªT×]3]™ûñÔz*"5¦BŠ ð•Ñ LÅ ªÛÆè˜º›E€a¹›ÊE5ú3ÛoÞ^òm‰¯Â‡ˆ¡Ét ½'CŽÊûæï+^^loµ»š\Ç€ÍQ#…‘ÚÙµ½¿éýoã¿­ä_%ÿi5)‚±ëO­`Ì*ÖpZ<ÈPIï†d3Á'L!©PxI‘š ƒÊ;˛Ħ¢Ú¢ k…×ë5äRû~f2îã4]ápØ\s£R1ÐÀžPn#sOfæžÌŸ›ÉÙ€˜þ2 ¨8«¢×§½â]qMÔAèììüöâo÷><ë³|M¾¦¬¦Uw®JZ’#_i’ÊÍ/×ÓJmùÌ„¼§*u™÷{B),ó 7>ÜÌ^ '5ŒvüÏÙ“žøäÃ÷eÎÓP¡ Ú $aÜ _‚�™ —ÁQp‚VBÇìƒgÁ—°FB!,‚“`‰aè�u°n„&è‚+a1L†Gat@…N³ÎJhƒ»àÐ%¦ ôÓ™ 2ôƒ÷ ÀpÈ8]ãØM0Ü«8) ž¦øðUz×§ç 쑸QC†O¡±7Øv?4Þ Ù°Sc$|Gc/šmâìfñÑôäú>\ØÉ,8 ÛdÓÉ€2… Vꜯr£JS ›ÂLÕðÆÛJ–„Ogd½šÎÓ¨ÉäŸNŽÆnnS’lqÓ×É€Xë<}Þ®nÎyóªË5*t®Gz Ùõ¼2‚Ìí$2èe'\F}=>½U<t8I+ÀÞˆÔÂÎ0a?ãã¬ëdy’.å^U WtôP>&j;§ÉDT¬ãè:È'±Òâ¸[)*¤E¦6„ÛFþ8~ÜHiÔ¹*ž1ÐéÎL¸Ã¥îMÕî¸ÝÁø@UûF樊 }Id!ÈÔ±go¤·„`CÔ(޳·£V2í‡qŒ¦²“Yý70^`¿Âô$ý£X#ȵ4F)H¶¡y¼DmƒŽvÌy²ë¥¤Æt-3GÞÂë/KoLžº>/V\·u|?+kñ©‘~Up(´ajÈ]"&þ(kgÙ8ìÁ¥NE‚4Ñîl£r“½“<Ö—¢ögq—Æ`]à ‘~P«³!É ‚ë<¨ò­Î`xW`]> ²_"�ù: LQ¯Ê<¯‡Gh$b|«3·'20õ£Q嘚³F·§¹¹¹µµ5µ“ûLèy7´ ó58•&ÌÏŒ¹æÖØ, ô|ªÍ•Ûí6ø¼ÆØÌt8ì Ë6Yƪ]Ýwí¾Â…ÙUÙ†‰”}Œo÷Û³vfy<¶Í¹Prw…»aFCÑ·EéÓ»«¤€ëRmÑ»šfíe¦«TôšÑþ:–ãUQµª/;ènv{=©íY#¯' ƒ9ЭÜ1SB*«:UH×f³¹b.G³#޵µµ…B!Ód²[maÚ•¥^˜ A{Psj’WÒZÜWl 2ÍÒM÷ÁØ:¤¶…SÛžáp8˲lì<Œ Ò0‡4òqÏô¯ÚÔÚÓj3·dz:=Ф$<‰ gn¨R9ï¯ó\í.]×åv¹÷êÞÖ€uý½ëÏ:l©·ˆaQ—u›n3H¾ÆØÌØ %< 9)›µojÓÌg©’‰'T1áÆÕn¼sãè—G{ë½æ0Òår™pò/#ÀˆÎ» ]° ¦ÂP(…ÝðdˆÌÖø¶ Ø! ³ &‹¤¬1ž€[`-‚À …#àN¿Ã<X3a#tArá{Ø IP!~ȇÉ06—Ò8WDÓÙ ñ1\>H‡K –ƒýtêa!Sÿmç&YU­ýß9§rîê®êœ§{zr†fÈ 9ƒˆ\Qô*@P1z ˆ ˆH¸ˆQ/a˜<LÝÓÓÓa:‡Êñ¤ï Dz{Ã÷}瞇éêê}ö©Zï^k½ë}ïBù¸aµB»~ù-Òµ‹u^„ËæhÜ«ñÄáZ¸ÉÆ zî€É§ SbÂm·Ã8–ÏCðõ�v¸Gâ"›Æ8¼*ñ°ÄbƒKm`ÊNy†™D÷q•ÄÅ•Ôå˜JPˆR9Îë½#\å`ÄÇš8gNP{av† &j˜çõ¯‰=õ‡Äü½ž]ç;=(vв‰äášÌV98N<Àsë8öz˜Æ5ŸàšãŒ.ä/›Yi£àam ó3ÌÉ“s‘±Wàp!…È  `SThÐq a·Q±˜Â«>Vfpú·ìcV­‡eF8Îuorjÿ 6P÷R00Fâ¡€4þãäèã‘]'çñ$ÉôÑ]êbÂŽ[¢&ÂÐ S˜ÌGªáë>n¬ÄØA‹Š±à­:"S¥B¦?A… S¦«‚Ý9ÎëüËÕòóå&›·õ—Ákº&Ò5Îö?´ó»«8FÉÛ‚ù€qÕVPÓ¿d·íÉ{UìѾ1¹×™ƒõ6<·J¾«lŸÚaNv7üv®“«»)7ùdœµ¾[DË3?ÄÜ4¯ª<¦°M#%6©‘øÌ:…O™Ì慨ƈáðÓþ8ÐòÁ­ð®Á7WYR<—$)—ËÅãq+ Y…Áú½Ÿt:mµC¬�dÄDžd9äÎ »‡m‰[6z"8 o!Ç#šáÅbQ8•ö‡ÒáôwÈf³‰ñØ©ÙSUëªB]!œWù,ö´ý0cyyî¯æ*Š‚txÚØ‡ ;‹Ÿær¹iƒ±¢odÅDQeµÒÍèÖè‚GèÕº#ìк0ͲPD䈢=Sê>lù3Y”ôÒìv»Å䓈Ý3jÚ& ô-Ý™DK¢ó’NÃe(¶Òϧfm¢(e]e¶¼íÃØ:V©³”Ž8ÓGæÃHž}§÷%ZíjûÐì¡L]ftõèüçÏy`NÞ̫ʙzÚQÛ]ùJ$—ËíýÔÞ„zB¾Ç}¥ÍKY–3Í™ý—í?öÇ–†DŠ?í Sj‰YZŸ,mëŠJV'‡+áú—Æ„ Ã.X µðK¨€Ÿð?SÀ/ñ5!ó}éŠ0'ÀïáZx‚àïÀZ‰ûMj Sðeˆ;G‰N‰ã Æ?0l׫2¼ÛèVß‚!¬°S'5à…_ÃQ0“:o•\þ§Á‹ÏÃóp-:¯ÁiðºF Ñ &Q8t…ã5…÷L¾¤ÑÿAñsü2°ú™%qšÅdVMž48Z!ªó¤‹íLÀ˜.7ê!îÖyx„œÉ“Ùd\”ç(BÁT qöCm„ñ‰Ï¿a¨/{Ñïã<ÅÉ;˲_ÿ%WÜ)…ö Å,n–MF9;…+ÁÆ,59ê†(èÕ©~—š�žJ‚ŠÃØÆ)ÌEW éßÉB£‘Þ09³'ÉÔ1ì@j¥{€A;9Å<ãûh‘Uȶad¢| ÂK§È¸!ç&V@ƒw×t¨É/¿íÜuf�oi²ð†ÉÒ]ã¬]È¢Qª2¼bçŠ0×ï¤2MLÁQÇFò較Ds!ô ÖrJŒh­^í¦ÁÈâ˜LدŠÄBjÛ7%‡çFÉŽòe—Âh ·ƒ™w“œ§lUœ7ßæR}±½!É@VÃ%­²ß+Unr¬?.…}„Ýûa‘FÖäOåü8Î@žƒ2KLÒMæBƒ«Mì:€ˆÌlƒßÀ“'¡#4!ºT“*¸êÖ¯¬yUñí-í ü{Ý#f"§)5Å$Éëõ~=]te¼^¯ßﯩ©q¹\^¯7›ÍŽŒŒ¤ÓéipeFº"Ýù©Î@_Às[+J•“J»k¥É܇¥,V‹?‚øì‡]–I®®ë©ÖÔÔ©Æu®¸ h|·qó›+÷T9ZŒ8”-¹Ë}C¼,—Ë%‰d29>>nõ–+öa¬dÈ ô±ŽXp{P1¡æ.2Útczâ[¢Kî]bÁ•…@Vj^ÚäÕ¤8[:–‹äʆÊNýÁ©@,3 ÃʰK_<çÑ9ƒ' Ö½UÇŒ'–hMgŽOLSpåt:K{‡ÓFÚžÙíöžôÔ¯©·gìÿ\™tŒ‹0öÃ"(‡6ÈÀk�uº! 5{aN„MÐ ]ð2|¶ÃÐóAÞó& p(Q²;Â[p&´Ø¸U#+Àë` ¶Ã¥`‡÷ �ý… oè|6A�ú  :à~þë Î|ž·Oæó!n£Qã1¨'ô)´Œ)ÌÒ‰Wð™U:ƒ2Û –À<ÈÂ[ í¯™Ì‚1¸nHPkCòòç$^è†ÅP!Ó Q)™'3kŠ|CÇ8_B—qé¸Ldƒ‡Ë)ÏÐTdYy™n®Úd¬^kÛpºÖ>2ðнòƒŸ³mlVÈé<"ã4¶asP¬bdOŒ¨AÊd¿Š6€³€RnÞNðægštv Dݨ‡°{ÈU1Z¤ÎFÄ@õì"^ɤÕä ŒÏKÌ�ŸÂЇÍ&r'S2î¹ÄÒøÒŒQKylµþ´WY9ÔF_µ 6øI¥¾y“+—Ÿ‹dبqVž²SY”Ùd ÒÃH9ÊT|nöõsgï¦FÝ<›ã¢“$r$6“²ÓTÎz)F³m„À~#\šæ[ ?¿²ïª— ×ÖØ7_Þ…£Šlšf“ƒ1Ì)".Ê%ÒcrœœáQ™O&¨#ãÚµ0À Údòxl,1‡ËÕG¼vÿ®ABN‡è7‡ÿèãIƒ&™ípžÉ]³e®ss@ÇãI?ÓÑ$š ó þ³ hc¡F5\E@~&ûÎrbùÕþE­d2i™¬ÿÛT«ofÓår …캺‚äéÀ�� �IDATºêêjÃ0‰„0Ç›Éð½ç . sŸ+%Ó4K'“¬j•W3ïeš%D©³â´ÈW¬!e—ËeAh­•Dñ#QÕ<ÚÞÏìuL:Ü£îýïWTeîãs@‹ÿg®i­ Ó4'¢TØ"›Í~X";MÂQÜfëË­«T›ª&U@F‚{ƒeeÑ=Q申toEÊb•û¦ó,µªÒª©È-{(%e ;¬‡õ…ÿ½Ð†Ít¼ïìeÙ3Zé»H7 Ã辸»î­º™wT÷FÝÈ1#ÿpE­RÀ•˜C°LÅþ½üL¸JA÷¹…Ž•±ÃÅ?ƒVµøk`ÜWÆ>gŽòCè «`!Ôà p,¶áÖ‚kL"`‡.ø&Ì‚§àzxÎdÈd> s þ`ã{-à4xÂ"Ø5°.€Û`.Q¹@ N‡AXOB�B°!¿¸„{ß!sˆWTÀø3\«Mt“'“8uVH|Ï@‡Çj8y„g%.”©5xÌŽCåq¨âѯ#ÇøŒJ®•î!NÕqèœ?yPÆ+a›äj;kl¨dW–£3Ì–Ùêáê$zÕË–¿7zßyê#s\0°ùŒ¡`ƼóeãÉ»Šġ,ädr´&qªH~Rã8L ;®:ä'Fš}nÎÉb„ˆÇøÕrfåCØòìÈq\ïFÚ¼8Ò”Or³—󘯡V1²‹…9ÆFèoâå9\>A½˜—£†È- ›Ãc’³“ a?†}Ì9ž}»ŒÝ³Æ¨t⬣3Fm#]5v©› ®H�ÖVr‘J²<CÊdŽÊ‚]eê5>Ÿ&\ÄNó!’FŠÓªbßÌhÉ1"£,j¥'ˆœ!T‰4EÞD·ñ9Ͻ¶è/ëRB y)—Q¦™ÌÎcê¿ý¬çŠ&pŒ£‚«†“†—¿!×0øã+sì+b¸øUžå:OVóýLÏ\Ån(—9zeÂtšœëÆ®a7ð«ä Þ†1¸Û$o’ƒ¯š4HØd–Tè BÜä'`B¾!Œ»;_)àÊ j"@ÚÅÌð­išÛCÄq+îX­{ -´ÞDX²Zj=¥E¢Ge·ÛN§Çã ‡ÃuuuÙlVð•?Ì?¾í™¶ ·mØ|Ëæw¬øÿ!Nh·\Y=Ñi³^3Í9ÐÊêö|nOº.Ýþ›vû¤Ý5æ2:Œ¿ÞõWÉ&-ùí’Òá*Áa›öh¦uY¬#E¡P˜R-cCÑ¿lïU÷¡þú™ÊFÓì:ÿ.»M§K)!3ÇéJÍ;¦¹Žý]j5Xqß wÊmãï„ÒeY]4šçßl,­dn¿vû¢Y¾hVn'ò¡Æ÷Kµ§žY¤J¡õeÉê[¾ VyüoŸ±—Úv]¾+t0äH;þy¸ª…ïÃ˰�"0dðü nƒ0@‚gàzXÇ„Oƒ·B%,…?Ãl¸ vÀÃÕØQø‚ÉÕðŸP ~XŸ€GÁ_‡<¼_0¸Ýd»Â¹&¯dàsð&œ)á3†ïÃí Á“&çÃÃð-……&¿2pÁl¸lv.S 9LQï§< „†Z.L3?ÁL¾nòžÄ0”ë|Sçó2·Úù¢ŸŒð”Á Óù¸‘o× 'ÆR!MA rƒ,Ò¸´šŸ� KüÐÃCEŠj3±QîœÍ_G±J¡U¦²H›‹Í–T{”ߟ?º¿%rÒ_\E¯M;4Égm±§Ã_¼Ï¸û»S/\i|ñ{¶1¯Æø$uFŽõûYšg_¹nOò¨Äîr&]´6Ó½•¥'²w‚³2»h£x1yˆÖYC¶6𠓪n¼:ö^Ü.<MTƒj c*ò> ·j¹0Éu•ܵŸö,êóœlg3¬6ðV0©bÎâí­n¤îåôanÃgrHf¿ƒh¦&‘üè2c øÉÚñ¶qÜ>:Ý.òðŒLK3õƒ”›ÌSñ£¶ÑSÇÐ~ªªÐ†ð{‘MŒIt*G ‘Ê.ÙEÙƒ“äìT™¾!ýÆ_/ýtÅõÃ;—^=Ãþo“Å”Ùø¦’®ÌŽ' t'›l,;„Ãd­;†ø¨—o‡©ÊÒ“å»Ï¼X΢,_Òù¹ƒ�xbÜgãB‰• é]6Αø t@Èä\J<jrµÁÓ�·MoP‡«à[°�^‡1ø <sØ8ò¯Îÿ[n¥ä‚ióÂG&£ ¨›fK/~W°È¬¾‚¾Åb‰D"›Í¦Ói!¿k-Þ3êYòí%ï}ë½\.§ªªÇãDs¡Öc¸R飙=•F_ÃÒ1VIMMMù|^RÒé´5~‹°v<á`ש]sîŸì Êùjnûä£o8zë[]ªËV°ÉÚßjqVÄ/UD,e`N³„Ÿ®Y÷<®¥M,F­K9Ü–„•È-òù¼˜p*eÊÍd´ äSUÕårY»gÉ“ó÷^e‡%/ùc&5ߘO–åÒÞa®"÷έïTn¯tO¹_½ûÕe,‹ˆ�E±PVð÷û§iwY·i¬g=Ž/ÎVwÊÂÔR÷H«f(§dÓ4m[©%Û´sÀL¸„' Êà‚ëaþvÁ*¨;ø o¾_ÓK@ ŒÀï )è‡CàƒÜ`nƒ§ nÍp,xádxF! !°)Ä4ž…åp‡Ì³;.Ò‰›œ 1éƒu:½p&¤ £„Y*ßæìóQÎx”g¡4m˜õ[ –ADF18³œúQžñà0éó²9G|VÃÓu\7N{š{`¥Ê[p¼ÊÖ164rnŒt‘s¼à¿)#£‘ŽSÙ‹]]<ãg•Æ ÁŸdþCa`?;Ye<ñ鯋08Ö0‰£…ýÔ®äó»x»Rm*¿áº}Tï¼8°à{“¼îg4Ãñ͸dÓ,v’«ãŽJzzñRž!žf^Ävæ” ¬wѤ RaG/GM"U¨g|+U~úÓèsÑëH¦:ÀÖ4•=´ Jü´¸œÏ7·Q¿˜®.jc”‹c{ æåÑ tnç%'߬%5A¸‹à ìƒ<˜•ŒIäíDzñyèÒè.ãýÜ9…]B/àqQðà®'“ç*'šN&B•ÊTñnF»hìeaî:•dhô3æ .…£œÍø%ÚœD²l„¾Ð’µq³ÏqÚ×õ‘°±àÛÁÓf>÷ûC×U÷Âà"»zûMvöè̯ÆÀ´s\o5ÅýÜ‘¦*Í«Ðu Ã}qÎ28F¡Oçf8®¬!ÛÇFƒ üFã68ÖÎ&•“£üÏA»ÄÈjúz~é–ÙNƒûàjþ~LØbI|˜­¢Å:l¯þÃÚæ"(üßȸ™¦)TªªnÛ¶m``@ð>âñ¸(MSCÈVe“É=Wí î þÃ’š5òå÷û­W~XÒ6hMéz<žP(äõz[ZZêëës¹œÞݶmÛßuPš±–ØÉ_:ùýeó7.¥oØwògOî½¢·jOUp4˜`JYX{Q«+ñýÃ}¼!åðw ´Gåv»ùÅ"|ÏTøV«<Â8X‰p¨±Dñ¶]çu-~dqÅÎ Ó4[_hÝzÍVxǽݧtÏ~z¶#å@z_R²ŠfÚcŠkšÊÌË"ýV ¤íµ6{Þ®ñ¡uÂÃÙ¿<¬†$ B ¼ÐnÁé sLÆÁ Ç‚çÃ�Ü sàc0C0 LÂã°¶Éœ /ò~Up<óÁ{ …‹j2xVBl—©49Ï`É_~†Iüþ«]ÌvpÆëp¯Ìe7©ã“},”‘žæ—ðf| j!#¡˜< —@¼f2=Úì<¦0?C>Ã…SM¶Á ™Ž/ùY.c+°�æ–‘uÓ”cÔOmžvH%Ûbôø›øcøU’Nº5Æ£L%ù¨B™‡U*‹|ŒéñSN_gHÍÆ›'8T—¤CÔ•“ïäÌüžδ-VÜX QY”aìYêLÌöZF¦¨Ö(—ñ©4qEïç`­{˜I“¡q&:Èu1 ÁML!çFq“Ëám¢à"‘Ã;@uŠ©©"SY á ÕƒH¡jRA’2¶)”Y…H¤Žž£~ ℳ¤S˜04ŒÝŨLhœdw5ö�£>d]>®ËÁ½¨':îž!”24µ‹ê,™J´2RId;º„­È¦�~ªíŒ¸1&™Ð™J¬ <J,;OF¦º¢¿Ïý‘)•ÆBg§ =sÕKH‰©±þÌÙé&ÍvÊTÇF½“—4 Ž2˜P ˱Kás:ƒËL’&wTIœ&1ObS‰)s²‰à  L^2¸ÇÁOƒt(‡)Ê=Üë0?Ë$kàcp,D-"{ÿºuëfBŽ(ŒÒeö3-Ð”Š½ÎÔöþ°À$pQ8K9·tF4$,Ûb‹£•Éd²ÙìÄÄ„¥©aU~2‘ÌÀIùHÞÓëiûu:¢–(øi¢bµIJËP¢{/ÈßÓ’ÃîIéx“`‚¸\®æææH$"âãäääÄÄ„ˆ¶Š¢ÈN¹ïľ²Ýež~OiÔ1–e™P2äËø,ƒ%‡Ó2‹'i,I§R†ý4¨.-ßMC;k8IPHÄŽ•fu3›7¢ì)JµÖ‚0™´2Ý~ûâÒž–5Õ}/ºökk[_iïÚzïËïÙ³v³hVm¬²úO¥™“õá\A‘<‰§/LJ#vÌú`Xcp–uéÇ{Ëõ[*7UJÙ÷Å‘ûOÕ,;jõ‘‰ìÐÀÈAl\ªñ$` ˜\ã•YmrÀÄKàQá¯0:.XoÀBxþd2OÂ×ÔY’_×Ü98¢ð¿ðkø!l48¤p¥Î7à8ˆ˜¼g»‰hšçoƒ»à^“CP�Ì3ØÈu]6e¡ö´» EPíàGÑ�W‚â0>AÑd«Îrxn7™¸Rb ”™¼;Å*'Ýpv›üL'¹8?zžƒYVÊTI,Ñ¿w·t‡Ý]øžƒÝštæÚØSIS†C ª†jãÜ K³gÝ’ûã׋™~ _”š4©F7sL67¿ïÇ©ÒæýÅõ!ÖÑj 7ï¤C£?„шº‡Z¿ƒq)ƒÙò^¨Náª'SÀßHY/õ½xƒD’äd‚YTÞm#5H³ƒxœð 6Öä(8±±z;ŠRHåÄ TA"¢¡VØÆü¥ìHÓ’ÂgÞc´™Ñùq|Qr6òvœÄ·ÍPâ•z[9e9CÔúØj§>Ý`[ãq¤q ݔۻÙ8B|„Kr¤ªÈö1 s!¥8†?J¶™ddÂù)²Rl5˜NÜÿôÑ©O=]ÿÆXº— <ö óêûw|³ 9̾ýÔÃѰ±È–"/I\2xtœçJì0IC C=ømÌÑø­ÉÇÀ:äuþ2pxLî6éÕa1HP0˜gð<ظ-ÏgÁ6pÃ%Dàª6~ô“)Ñ&륦 V¯K„³#‘²ôȧa‰è ø",ær¹?ø§Ó^9MpDƒG8E‰.‘êQ\p áµ†`OPÄ&S2ív»X³¨Œ‰±b·Ûm-U„þ`0ht+ϱÛjÈMóVW¼.>4g(Ò±Ùl>ŸÏï÷ ±ì?Þºuj NxòUW?l+*vW¸\.ì¦ßLÔt:¥%*WÖ¦ÄNSì‹À]Ú;,];²liCÈ:Iˆ.EL°ÎÖ8Åh/½‘i”ÎþšõçYÏ9Øñj rÓÛMéªtý«õÿ7_bÍ+¤TDÜri[W<ÐC'ªZ_eÄÞ§ œ9 ÛåWîü‡ªð_HB\ ÁQ:Q¸>ƒƒ›àè5©7ß·“o€m°ºà ýõê pl†S VÂÅð hÏâ4ø1LÁÁ 10áyø6l€»á“c ¾Ã‚åFÛuü.‡]!^Î[I@å<È<Ì•M6ç2ã¡ÙhßóPî¤5F ˜•h#¸MöC<OÀn0`6ìÒH„±û8‚~ƒ‡á>™¨6(+Яð)`‚-0 ciþf…É¢aöJW~/ýU·yÛ©ö§ÿä» 7F³ÁÐ8wºù…Ôøþ$_û´žUªWþtìâÍCKäõ³3l•i¯óñ$Úq졼—SMüu†ùBŽŸ…±C#î¥ Æð•Oµ±eÚ:j 4­fíFŽ›¤.ŠÇƒaO%c¯rZç"¶§ øˆí§~9»û(Û›^åP#ê*¼Á2™d᥼µ‰£*É.dË>˜ N£a‡ a_B®Û0uíì§!@²†}Ì/RÐ&X¸œÍëhN“ 7ph.ì`§ÊÅE>™æÎ ©vøp¿Á½yž’%)KA3“|c¡Ýh Œ±Ü$Æ0r%Ê(b8 l4ðyJ´DÙ5FÔ·C6š÷f}Þ¦±KÆI([«•Ÿü—vèúŸ)£ÚNJX…¥& #„b¼S‰sç³ü‡‹$íl¬ 1M8ËOòDa!8àtP!ïB¥ÀP¸Æà…{L¾opU‘5*áZ䤯ñÅp"ÒÇ`G~Á箘vÚ¡ÊËVª¥“§âän·ÛK•âDdVJ øu‰t Ø}Õîӕé~v‚8Ñÿk‰Ä–/m™ÿà|ϘgZÅÉò±-%å—:Ä‘ÜÒà±”¿§)K•Æ÷B¡€Äúï¯÷&½‘þÈþûOK666&*Hù|>‘Hüî¿Ãdþ›ó[ßl}ã³o,üÁÂÒ‚Ø4þ¡µT¡$ufÇÈZÉ´tGd�ÖxÀ4?—ï*5e¶RÒRy$ë.,?É™´Æ¿¹#*’„$* N§³ôs"ø÷Vj^Ê+¿kÉšäóùò®òî˺íoÙ;ööµíEoÑwáûÛÐÛ¿Z)ý7®Dk¢rc¥¬ÊH:ñN_o øè‘ŠNpÂ8ôÁ †ÐkáIpÃ\ OÂãðªÄý5œŸ"»àtø¸áG°öÁ$|Æ¡Ø�ÏŒ™œ]‚Katƒ— [HB¢‡ep?5ƒ4Îâ¢:ú¥ƒrØËa¶K¹ú1Wß=ÃÔ’çÕ^†{à©${ ÂÿÂc×yë¼!qºBÈ`Lf8?Çjµs¢Á§ö(´ºØ«sƒóu†"ðŽƒ[\è&µÆÑÏ;O*ªß.Ø7ß(o8'29•àYÅÁiyWEnî[îõsÚ~|vòÉëc›¯Ó/L=AùíU®â€_†91èŠ{‚H&hj #4‹•CäÓÄ%åä”QºIf ›,£ƒÎrÆ4ªÆÉÌb$‡TIb‚²¬ˆÐãgx;µ+X?L« ¥ˆs¯ Ñ8@CéæºðF"e Æ©bÏqtmÀ;Gú;'ÉÉØé¥=Ⱦa Q¦’nap”ʃè&ýõ §ð¢Ìƨ›q'J7µÕ”G˜Ud¹‹¤Á¹IUªFyf’ùQ®HbH×|G~ôùµ€wª­ sÇe)s[ͺ^Žö1%aÙî¥Q)†²Üêdq-cðºÄ+ƒ!ÍK1nÍÿîõ‘Ÿ({û_I^¨Åe‡q¼Æ¯Æ9Qg›‰=™,H³«š¹ƒt*´K8‘ÓørL¦hÎcSù¾Âýsør#Åeô¦ùO˜„ËaÔÎUظJç'&ÇÃQúLF%šLþ›ËL>ÒËþÜÿw<ÃÉˤɯƒÛ* lذÁê[F®¥E3‘+Xœ.‘Cê”ÈBJÅÿŠBœU\mj‹ål‘Z=$ K„“å(ôžÔ»èîE {l %~ƒ@6”]óí5GÝ}”kÒ5MbGÜ‚ÆVµî4øýþºººÚÚÚyóæµ´´„B¡p8,æ|§¦¦²Ùl±XÌçó¥-:Ó4w^¿³æéšÈÚHEw…sÈ©¥´`0(ŒB†íýfoÃ# sÞš3Þ>þöÇߎ7Äë_®·§ì¥�cñÓ,³.£³Ùìa™ÓÊŠý,eZA¡+,u,SÅjÃX¥júÓZâ!ŠÚ¯•“1ÃËÊÆ¬'^ÚœÆ |ó®7 ‰êmÕb,ÁëõVWW‹¤Plµ…pÓ¨öâÙY$=g©ä•ãœ9§3딋²=ÿ¾Ê­ØF‹Â*.«Æk k wkaâ°Uš:‹ô]×uq‚†gú—xM²)¹ós;ýƒþ5w¯ öÛþØf3me”-=z•U œ Wcp7ôÃ"81Pa.ܯAVÂ\?…kÁ×ÀÛ©÷MxwA,‡7`?\ á,è† è°®ƒjh„$¸áuX‹ájBò2Y‰¼Éƒà†ÿ„ˆá¬aîiqH¯ð ¼X1ÎÝ,8OsL‘ïìåq;ºa–„ ü&íPœ ¡JæR¨²3ðÉ0t›l‘¹Í$¢€œÎ=gÛpÂ&“ó¼<ÞÌM£È2Íà7&1?î$[*©Ò'[•ñÔçZ¹G;õYõ•{™å­ Venúƒv÷ƒÚ®“G:;L ùÙ›š$]þ®Q¾£aíùŠvŒŠ/D €-Da_‘>0 O&â#î%P†YFÚÁˆ¿·]ÇÓN_’ª<52’Iw’ŸÂ>ZF±…èŸÇD'>û zІr25 ½Ç;H Îg¨‘BgùA;rŒpY¡*‡;NY® –„(äØc,É+2‹0Cq¼Ãx£ÜÛA‡N¤€{ ›Èfh*ЗaV3L"N�ö5¡W2QÅè(—…pi(&º÷=—ýkj¦æOâ—ÉÈ'dç;{1œ¬h&W…Z¤0‹ý6¾(gé4ŽÑá$icY#QÅåÔk\\Ʋüó“éuÑQnD‡=㡊tÈCMœÇ\`ÀJ™“)™`Ž…6zëé(2<ÊëÐdPg²ÕdN5™;Žo]#”âI‰»=H^6(Ó‰Ë<£#ƒQ‰GË8.ÃëÐ#ñu;ƒ}/rëqh\•Æž°Qa ”ÂÕúõë­P%øÙ¢¢e}E¾U:ï)¢€õ5žÖh–N¥)š¥Édy;•^3 -¼”$)ÌeÊ2C³‡üüš¦ ÎoÕÅbu±½—îuÊΦw›dUŠ"F %S‡Ãa óZf¦iŠ ‡ý~4F£eeeG„Ú‰‰‰|>/hbm"êYy@tCôàG¦:R©º”Ͱ•§Ê§¦¦ÆÆÆv™»=ñÑ}û×4êºÜôõûŠrñÀeB!פ«´cTŠ[ÓÆu�Wø-¸ë)•Ö-m‰@l\Q¹µ4¨E÷%öJ¼Xx' ñ/¢èZ WÖGBüQÖK]-GËɬùõæÊ÷*­Ù,!„(V"Xò¥=E«�k6¬ã‘Ãá(›,ˇòûß_tóþ¼Ìït:E#JhhMc…Xµ>±<Á k¶TšËü,ÕÁ*}4†aw%¤É“5ëkÚŸk¿âñx–­\}¸ÊÂ�œáØ çÃÌ7@ƒ‹ Þ€°*a5l‡ýðEب‚(ÔÂh€>Xÿ qèƒ`#\u À\x�fCP¢Uâ´Ã¤`)É1*vÉþkøý~ÏÍ}ù¶ãÉÜEp®¿ŸâÉ�´Â±ð¸ÉA¨„£ b…5“ã²tB«L¹ÄÉ5,ɳÔä¯õìS™§²â~v(L©tú2à 1RD2i+Ö¹ÜÄž%/w;Õç®ÎÍY«ÜsEÑx-Ã~pæ¿ØeÞükéóß—_8Ëdg©À‚®ô©[øÑ%|í·‰r=ðF[³À¸„}ŠQO›#$üÌ*òÓ"sæ’Žñ¿v¢ûñCµ 9ެás“¦ÜC„Ýx Ü£Tª˜~ò†Š”ypV «T¶ÒLpvc ø#ŒçqlÔ餇˜šdAÍ$m&±Cxç0XˆbBŒ£5Ú8ÙÇ¡Îò#¼ÄÝÌ¢^B‘ñ‚’°ÕÄ æ ÙB.…+ÂÝeÔRí'ëeReoˆâ0³+ÉÉ$Tž·Q/c›EÓÉr:Ò˜ ‘°ùÈ^Éîq“nÂ.ZzxÄÍꪌ=€/©¿á|nAh|¥sùF×q'7Gu6ÖhQè�¯‰¤UÃeCuqPÃ"–!îÀ]F4Ë^w;†‘4;jñkŒë”;É•áU9Jã;_Óy÷‹™²L@XF‚ 3á¹¥òs§0•7©Ó¤b&\‰È. AÖÄÕ´/­e;+ê6BOH˜Ï$ ŠØ:M[ôDôý'«ÍsX¸|{|;¾´céKS-©ÞózóåyÍ­©^Uõª¾IßÂ?.ôe|¥SÀÖ_Íÿ™£¾"fù|>dzxñâùóçG"‘ŠŠ ·Ûít:‡††²Ùl¡P°Uü»Ø±'*<})'Uî®±o¬|ìÕ _uŒ;V?±ZKj¢Ç¶ýÓÛ;~Û¡–©½gõ†úCÞ)¯%3h¹H1­-Mƒ,½p«u$@ÈÊ/‰ wjݬ`Ò ±Ga;b‘2|>ŸØùií–f¼å¡eù†|\•úo í ëb5;KC¿×ëhah¬dÈjt ¶¡µ"  3M3x(زµ%ÖË׿ÕÚ˜m´|C,ù%kdͨ²Š\‰ Ì.õQ³:UbJE‡­OfÙî²Ú µ‘}KèÄår½ê¤#À'/š�� �IDAT•]0 ª?{ƒÕð+pÁ2^‰cLtxÎ/èpƒ>‘§Fa9¼ Ð oÃRx ҀסÖÁ8N†Q8Gálx>iã#Sæ oš‰ “Ðcð?°æ02»¢|~(ÿ•¿pǹü6Èš0k2¶5ß0v­’¹X¢Â$EðË´KüÅäQ¸žSø’‰Y‰Ù í&y“Q;‹³4A¦?Ï“)Ì—†Kg‘É€F‹Ä*ƒ.™ê2²$á½Fô  ꚊŒ©Ûÿ\gœcGÍÓ!Ýüš<±Àx¨…—[M¡\rMj·?]øù§YŽl\œÿÆÃ…{OžÄaǧÞMÆÀã¥q‚9S(£¸Š,3ñ6Ð-S­Së¡FŽã4È;ÙU a&3'‰†H+d”U‹ó³�«¼hcxÛéÎP=ÌN“½õ„&ˆv0)cÚÐG „ÉÔ3ࢠѕåh?1' »°õÒ$c Qk¢é†!‹TÌJF5þËÍEEü^rY\&¾™a™Ñ$´ØÔƒ×Áä•5L*¨PŸÇ"£<‡YËdÀ•yrQ´ •)‚$Ó¬ªf|”´by›dE ê “ôäqWqÐNMš‘)Ì©U2+$lÆèÖœšÏU~ðm×¢>÷Ǥq/Å1Jµ©+£Àœb ޳Š:W†ß,`Ù$ó‹Œ*̆ñ,rŸÄ Tkd Ley× Z§Ò$,“p™äàYXëMfE¨Èã71¡ÎTh1ð™ŒCëL¸U¸t:]üàšfõ+B€8–Ц‚`ü…™XUª�[ W¥§×R,T½jçe‘‹'"ŽÛíŽNDMÃÜ|ÓfEUÚŸk¯ÜZY¾·¼|oyõjWÁ%‚£Õ?ÂÒÉyè1+x<ž–––ÊÊJ‚ýxàÀD"‘Éd¬Ø'0UèÌþí3v÷°[¬Ò¾ôöS¶×¿U?{ÝlOÊ#°¡÷ø^÷¤;º7ÙÉUçL—YÑ]Q:$ðCtKU½- ÿµ4×KÓÙR)[âp`I²N³©œFÒ³&ˆ-t«TVŒ?—&‚G€+kðî°š¿Ö›ˆæ_>Ÿ·’u›Í&æÄœ¯Ø‹¿n5çTUM$âWìv{Õ¡ª¥ö¥ùãòo®|³!ÝàŠ»¬Ñú-1U& zâœQ:ÌnU<•N;Ÿ•ÖÃKíÍTU‰©ÛíËs:¥p5“j1 ÷ ² àX³às ÁYÀ-p?LÀ—`5œ?WéKr‹ÂgM~npôÁ1 àAW¸Þä€Á;ṗ“ÀÙ°MçØïèÌåÊ£àE^‡ïÀ~è‡oÀW¡ƒ¡¹ù¯˜Å’ú—é¸_ç[áD?#§ÕP¶ŸŒÁó­°Z¦Æà.¸H'sìȧ¹&3Å“09Åõà ä(2'έð”®oÅ<ÄΧÊlÖÑ.ãÑÙ”`¾ŒÏÁO'|ËNJ?¾E¾óŒÙOÍÚ¯úš©õ‘>@8§TçZo§k¤Øv›ýÜgCxFñLbk£ó�ß5¹/ÍH96ø9%ÊD-C+wQ;›I½†¬ UGîcN˜C:¶j&ãDr8ª«bBã?³„òuLDpØévâfeW®$ R«£øHHnEê 4ÊUGq`ˆ&Psä5;ª‚YÎöN‰Yôíc‡—æròžœÅð~ÆÂ4¤è²± Ã}Üß¡²1ê½Tò?2m*ŽZ48¤ãZM·‡äZÊöÒ Ñ<F-fŸ“pšðŒYŒöÒT &q:{øÔmv†Ò5}#{Q¡�…"JebE´*2C,œCçZåõ³†oº-¾b{èö'ßýâ.n€ÅAvzÑ'˜e²G"K!<¢ðÕ=$ ¤à˜ Ô1î“ø…B,Ų6¦ös³Ám:gš¸a›ÁeðYp æÂÍpÄbüJá«­,í¦~¯ó1;†Êýpú‡‰ÚYÞ¥*p¥½„iD€Ïž±­<cË·,|xa©0ˆ}N§³î@Ýó_x~õÝ«‰cÏÚ§á¢-eñÒ¾Èc­”èœÏçeYN§Ó‰DBœßÇÇÇ'&&’Éd)VYý!ÒSzZ7mfÑY|ý ¯.cÅ=+ù€Óé´<3ÑL°?(eY•Ûÿ§]Öä#ïÃ.K6×z@âÑXÕNÃ0„±U6<ì$\©ÒÒ´¹ì™ãt¥P$¶Î"(N£w cñþaÇb…X§Áóy§ª·8>gšŽßÌy¬Ò™* \)¿pìÂ3½gÞ{Ö½çéç1I>Ÿ·Ûí¥ò‰âòz½š¦‰EZ»Ýîóù„j¥Ð¼ÿgfÔ¬šA)Çd¦9ÀL¸Ò@‚(<oð@&àqP`?dà›p#¤àðȘ\¨óì…ßÁ—`ZáqX ež‡‹ î€Ðà£ð.Dáfh„Ó`tßÔxŒÿŽòµ ižÃ'@{¨xœ@uGÙúoÑ–yü1í?¤íÍÄž· ÕÉ ; @5™€=Uœ5Æ IÌ1‰«Œx¶µ‹¢FØ¤ÏÆq2·ilM _TY ½ã<orüÊaï0}_+£·H“ƒ‰ïÜ4‡ÊTuçdÓ÷ÓœÁŸ¿—Û[)Ýj||yƒð(uc$<Ø£™‚ùÕ¯ôþâÏÒן¹ÞóÄO¤™ƒP?Å]~j£Ì‹c’©åì‹)à鷺œ”Fº‡f?Si"MŒ¤m!ï ­Š‘cYÛI}†} øÇl¢_e™—îm,ò’&;ðdq43hG${ W0¶EG“ÙÆ¼îMtÚ¨\Ń~;®rr51lõLû©ðÑ0J¢ µ‡ê8¶"©6a:wp½ †i]ÁŽE8o3*ëjÉÕ25N•‡Ñõt¨¸–0ŠBÿålQäqz=ø3ŒøHäp âå”S†v6˜µƒàvìÅ5Ìm _k¤ÛC~œP”þ8þI¶¯¥]¦³M´$ÃÄt®õ %x:aN;í]lÕyÑdÂÀ¯2êäv‰ï “wrMÃ\pvòœ •:[l,5QMd‰wáÓ&uðe‰ɬÔéÕØ ¶ý,ŒP)‘çJ¬<_9 Yµ ‹Üü>;¼d G|±].—ÐXßöÚ ϔ̰˜Ó^¹äž%{?¶wÞó,éBa|^]]kˆ…sáêbõDv¢ôWÒi¿ê·çìG˜_¶8fŠ¢d³Y:¢ŒV(’ÉäÔÔ”È`‰„{ÿ°©gq9Žø¬¸i3‡V 5êˆ;ŽùÆ1ZV+x bÆK¤tÍ7oùÖW—krád÷UÝs˜[ù×ÊRn´ØUQM=òd’5UŠ4*O|ž&“hÕZ-ÎÂ?DG‘4TUU â‰àg X:ìó–Á‚ʨišÐ8…Aq²x:â´a¢Ä'M¸Z ãʺ` y5S6'Æ'C²˜gÎ&—VYÅR­½¨sØ£Xé Š— !Mk¶ïŠ0•×ÀwÃ<è‡3@‡ûa)¼�° –ÁðK‰³á-“˜LÜ  ò‡Nx ކ^xž3hƒgਕ9dpe.4¨‡/Â+°NÑx ΀wøA„áY™eýpžÌ ?ä´[ÈU°&¬ñ&Äì„%ê´³o¦q.-›èú(oO°/­ñ’Â-i c§É}S(ê¸|„“l<HÌA‹FMyNÜ*Êàórv’w`Äu óu~-ã49Öä„cã„FIiq“wóƒþÿ¸w¯»Fw™ìÈÝÿ ×7––Ñá �Ûœ\ÞÌð�9Ciz†Ç:‚cå|ú‰â{ó«¿òe™®=If·ñM‰Ü!ò… Ïàì$ÁŠ牦qélWðõ‘ %ë�µ:ÙÆf–×1gÅC&u}øz(+Kᣢžþ}4ûÑhMA„®Õib½T5Ð h$éÖhM9@«Š»—à^Ìjb$_EÊ㈰%D ]¡8DN¡(±î�8a]ØS8¦’ø^å´ú—Ò5†&–$ a&z1 Sëih!­¡Þ’"VdÔ…g˜2]ã…J"AØc0+Œ:I?,ó˜Eð+dv²±Wy´ã‘pl®¡1‰f Ùðéè³$ê*Ø>…jRkÒ+s~'9…ãL˜´AL'ó*Ø7Ì+~®›¢ÑNº€Kb©ÉL&\,ÐyGc \ §Jtš<wÂV“^èƒk $¡N’6xàmûÿÄñ=ìátZ|´’¶™S\Ä踯ÔM¾E½Nt†ž:ë©Ëïº<+e->w!X>z8W‘óª^wÊ]ÿVý´|«Ô{Ð*gy½Þd2)”„D|\¿~ýÞ½{ív{yyy6›Íd2G J×¥GÚG€dsÒTL`ñ=‹Ã{Â’$9|Û¥#Ï[*ÆVŒeš2‹Ÿ\\»©VsüSz©‡uš¦Â'’ªÒ”ÈNJ£§Ãá°”a­MÓ�œöwKÿÏç …B¢}%Ú`3Ñ®ÔZúßÖì/ ©TJ)¬¡‚iŽ'ÓDULÓL¥R£££@±µ(–'ºnVMãXZ 0k»¬ÊžHø–î¼un˜&r!êÉ–¦å†u¸’a;¬‡9 @Ù²èÜïÀËP÷žÅï%–š¼pÀ,HÃôIœ¯pšÁBƒÃgàyxt8ÎÛ¡~$1)ócxn†à„÷àY¸ th†<ôÁ)T¯âªïðv ( ÿ‡·÷޳¬¬Òý¿{ŸœOX9vuuÎè& HAQÓÀF¯iÆ™Qftè#:¨€:WQ‚£`@‡Lš¦ÎÝÕºr®“sÚáþñžCu€;÷÷ùí?ü4VÕÙ{¿{Ÿõ¼k­çyÖf•á/rí.¾7Âw®á{.ÞµÀ_äð>©~¥Rí‡<�p3TY&ã’ñÃh‰©QR [‘i×hClŒã«ÆˆÎGM\¬0oBš'§ IcÕh¬|òNÉܦ«ÏEÍÏ]dÇ>™¡�öyed™Ôµ²u†î Ó­c~é¾`Ñ\qú§7GKœ]Ä|ŒU¦Ïåù~ºá=³´¯å•Š^²£4¯GÊ‘v·` “.âÜÎÞϲ})‰Œ O‚`;'Tóx»™´IйˆÔØ›;å,ÓIÖ{)IŒ®Â%Q ±ø"=$|¤'iÛÀÁ!–[Èꤠewg™`’êfŽÁçÃ%– Ä’Ãå¦ÝTE’)øIåHÑRx”f›È™ˆ¤8èÃf¥š¢¡Ùô¤0»˜… ŽÔIr‘'ö)އiñPŽÓÖŠ£JZ]¥µÂ¬™å^ DÓ8€0µ8Ö<‹:ûøÒ _¿ 9¢.ä<ã*%ÐaìAZ³dý$2l­á—HÂ4\£p'üK–åVÜ`‹3.sL¢ ¸Tâ}:º¥B¢JÄÌw]x3ŒA$Ü2 .^¬p~•ߘ‡³ášÊsõÅ@ã‹-Hbõš›SFŠÿß±×u}ßÚ}9ONä"¯™©ËÊá.…JëïZ_Œ³‘ì¾›ö…ûí{[B$|õcÑ™ŠÆmšL¦t:-d¹…B¡V« ÃAðŒ]v!\˜<oÒš²k~¾ÆT1¡ÈÐíÖÏG–e¹ëÏ]‹/®¸k…Õj•,’Øþ¿é,ÝSÊ´O¦®íÆSºËŸî°Ûí§»�#X‹,' 666æóy›Í‹ÅD.²äD¢ÄêñxêAúd“õSš0‰_0Ƥ ÿa9!põ&‡âDñŽxÕSíêâñ×òìÒÆR>Ÿ†÷b Ûÿ¬@½Ä›ßÈÆ– ºx%Œ³ˆ¯Ï’²ùÉpåƒÀ룧.ŸCX ÿ*̾îx;çkä!&™÷i ³ð^Ô9¡‘Չü�¨@ÌÇá‹`Ñø[ø°Æ… ‚àøü-̃>¬q®‹Æ§n•-ð«÷hÜ­q„¹òO,[ÍÛÙ½‹j€¼—¾yš3Üý[ùæOK<£r7ü Tu¶@I#‘aša[Y&‰9~$qÌBŽñ*ÿ¦q„a9t*¼$Ñ3ÁîÂÜÍØO>©¾×÷«ÿ½X}8ÄûGi]I" 苸–±PåýEžõ²)Ír…–>L6ªÉcç9 ƒfb®y<çrd52µ~ª þáV¦«øÐSÁ¦`^Ï Âè�+ð«dÇ録ÐJe’Ž,vi¶9zýבBÔð¯c(ƒoœN•azK´D©ØðT˜³Ò^ÅjA)âßÈÐ"î$Þã¬tQ'ØÄ´N:}Œ£u22ȼD»g€ªLщ©ƒéCt8°Ç¨ô0’Á¼‰ñ'Ù^ÁAŠP.âµSá竹=D¼‚m˜p½J'ÅqÚ&ðD(·2½@ÔLw‚Pû§hrp~‰Ø }D<$û‰”¹ÍÆƒì–˜×Ø,á0±/ȧӌgÿùaýðuÒ?”?qGÙK© Ëôþ”4Ù§“Ñùú8;-1q½‚´‘‘W¹Cã †«$64"ÅiO2¥±l?иvª2sžN2KQã:8®ñož– h¬nÃ:Ç*´¬"9Äe5š4’à¿Ôø$„On ˆ˜Xߨ¨Ç³úáô¼q Ñ›b„£1)Š×Ç ‹yýÈà“qºá®á-n14€ƒ?Øõh—=ewϸ}c>ݬgÖf’Ë’sçš42c¥§úè#U¢B$“Ér¹œËåDn±ÄûNµªÇ®?Ö÷›>×”ë¿7̧ê -¯ÜþB»d’êû.õž{ù|¾~�˜Ž§sÕ3.)—Ë Añ™„Ïìþwæ‡(Rù|^XàÏÏÏ¿)ÐÖÏä­§Õ.X°i IœHƒÄž£žôŸçg.ž±•l)Sªq´1›ÍŠ×uË}[²“ÙB¶`,¾àŒo‹ŸÕã¥a%uJÇKAÒ…Á%5®ÞdmO.<ÀÛà.ðA¶C Á'q)¼ 9(ÂŒÀ4̼…_+¼ ߃½ÈIcZ§�ðð9XN8 ›áGp?섢λá8b I˜4qLéõ™ÂÓðmÐaÐâߦ Ó&¦á+²xÿ”‡Î½1º÷Ásðw ~‹gìlŽk|V%Zõša+h:a˜¶ñ“U¢*¾ã-üŽÏǘtÏ;)¨Yh[MÎD\ã9x\¡¿ÆØ4Wâwjdœøö„R­ð©¼Í 0�{”s¸³X£Ì©lsVŠ–µ\Íùil3Xð²ê[œXŽÓÝÃÐ9›dÓ,Éå1âø«”œŒZˆÑ°›yȹɇˆG(ÏÓpŒÕ•·óg i¥È¬•R Gs£4çùA–ý«èÈâXÁÀ¦Z˜ÏÑkcÝ - Dã’¦S´mäH€¤‰Ú*¦:¨Ù¨jXT¬-ÌÇh]Mh=¦9‚ûYžÆf|då.¦­8žeõ-âÂ^FV29AÈMm+û\|§Dvœl 3[9,á>Bo?gM2¯S8ŠãU4À‡žeq”Þ&fQû™×®<®&°òù<ÃS\ òî«FX×ÍÇm¼Pä„þ­»ùÀïÍO¾ŸoÝau™g“W,xú³5Ã;Vcöñ*çùøà<E×!\N¾*Ñ!së2œV.Ëðù ºÄïá ³‰ÏÁ%ð Ê^34U™ïÚøÆj®ˆR„A臠ÎT)c¤Œ,*÷Á»$Öé\þÿqº#ÒŽ|>ŸÍfÅÐÛ·RÚª—Ö¥¢gpJ#Ñúì*£d”‚â>â;hñ£U¿\uðÖƒ'ÞyBµ©€¤H¾ý>­¨å<9Ñ6"/4£Ka40DP3˜âoEuÈ(õ¼®bÕKÞ’#åøI ûZƒºmÐíÄ!½ÙQ/KnÇï÷766 þ‚XpQdt c°¡`â9NQ%>§Ó)tKŠ¢ˆ8. âñ¸X chç){„§T/½u‡ûÓ}ŽèW æ‹+á †œfçÈÛFm‰R©46?öÇ‹þ˜ÖÒéÅ´!ø­W€='ã}«—À×/¬Q–ázŒxëÄ žaýqÊúçÉDöü#ÜçÂ/!Ë`¬4³Zc6Áµp7ÜyHÀmŸ€ã°zà~3Òè…y¸.o ‚› Î…n«$ª:ÿ xÂa®ƒsjé;_Ñ{$±‹Ê¿Br°TíOrå' i#fEŽ£(vÝHã×ÙH8°¬ 1;ùø?úÜ –^xþÆ�™—¶TÀD£JÀÎ.¯²/G9Àò8A‰ÿ”èrbe¬›¶n…¨†tÞ +¤g.WïüÛÐuf î¡]n¢ažà¨RM2ª²ºƒY33'ˆ¥<Ãz½&Ò¶å©EÑZ˜[ÄkANq"@¨…‚Ÿt„`¿½Ì#’“X»¸&FÀMÊAÕA6ÎL+z¥f,Xr„ò˜ŠHÍd¬nU°·³~ŒnSh~l B!QbVÔ‘ *ã4c.á\dz „§hÉ‘wbKãŸd|;…y’x{˜Ìáªâëd®…DÒ´­#ï 0I¶ìZ¦]ä}äŽò”…>'VJÓûزÈxžUœ:Ò^L-¨Q&S´D±¸±BìLÅØ‘áË=ô‘˜õÓ¢˜eR!’ÆUÀ߈¤* w³P@ucN³ª ÅÊ®†‡Wi_ø³4Ú­ŸýKsÿ9Éo”ž VŸ¸ré"‰ƒ’µp‘—:9/O¯‰©$>£>\!¦ãשJœíá© 2ø=\QeR#Ê2’E¬Eä9†JÜ ±I'.Ñ O@JãˆÄ.7$a…™ t;ù«VƒÈ>>>¾{÷nÃSNäÜ`…ÕsÐëë]Æwû”³í ª˜±ÛvJ„ŽtO:ÓšQ\Š=e¯7Õ>~åñÀH ÒyC ËKáÃá™óf*¾ŠjU *©¾”¤Hbz¬(ÑÒNpE„0&¢’azdä[¢w"„A†IUU­¢¹f]Ã×7½ÒtfL:eD®÷n¨OÚêóY–=H2N9äd›ózÙ“Øø‹¨jÌ 1RaƒfYϹ¨§k‹® 0Ô_L¡PH&“³³³étz K^(ŽÙݸA! 0›Í"Y7XsÆ¥¹£«õ´ø“ÍmÅBÌÚŒÄ"ùhÞwov&œ³«fÇÎëy©Ç3-I@ë9÷Ƹ/ãöŊ݉€ƒÂn¼$¢›%üONF%ÄX|·Û}f™ð8Ü Ûaœ·À p@×@�àe˜ƒ£Ð# ÁQØ~˜†¨Æ Hp.–‰ê$ࣰ ¬°¾ ²Î¯u4ñm ƒÞÂ{Òž·§KgͰþrzײ²—×JÚ³2Q3èdd /j°ÁM4ÅŸu>)x•'&åGV¹¿æ¯^ÿ 0ñ^>ð?:qPàr‰n™VØ!óxÜÁÕfr*%ë2Tl,TQ Ô ÝΦ<¯–©¨hiÖ9±”™˜ÍœðÓ¬1¯¸.®þ¯È+_0QJò\7Z‘™ æUΞEo$0G<Ž;Kº ©D‡d˜¨“h {€V|ãD,Ìx(ñˆËý}”%$Å6¦`cG3–~Vwrbš`“'XiÅ3M‹%‡¤IÚÚ8ng.E¼VZ*lb¹†É§OcÖNnžh3ñ1Ú™µ U°YPG±ÑV¦¡BF¥ÙM!ÁÞ,Ýv¼ÝLÙ©Äqñ˜)ÛPÃäÑ]ÂWÅ•âö(á9VO`* Ù¸l-S5¬ÒYî¥T¢»´ƒ’‚%Œ=F F²L±Œ¿„Lÿ,S‹¬èa¾Je”kº™2Ó” MFîF±£•ñÕx4-Š«J9ƒµÀÁÛ`&]Œ…”µÖg—Ï9(›m¶ õC=ŽX›y­EÌE–I”Mø4:“øìe^ª …Ù“# ó°“$|�rB6KHÝ8üXç!°ÉøŠ|_å èйOGÙB‡…£VìN®Pù¬Æ4|²'Ì\‘ÅgÀÕØØØ®]»ŒÈ^o¤$Ht´Y‘Ô§MõâÐSŽú5ˆæF½Hœ¥¬M_>êK¥{ÓéÆt¾%/k²}Þ.ÂM&˜Iu¦ƒ{Ên¤&"ÔZ³Ö¶]mUoõЭ‡4›VñV§"+²Ô¿¤!g„?¡ý\Âh0Ò,PëÃÐîÅD±¥h)Zì)û[‡+í¤£¾ÏQWB¯jxOD5·ê êŠx †çP½sk}£¨&§¼ÞgÄ€+Qì²ÛíÅb±T*¥R©t:ËåÄr-ɆO1êéõRžØëâ‡z|c^¥ñ²Õw€êÁ£P(ÔÏŸÔu=8\lZ´–­‰Î„d“Ö<½&:­×G×'Uõpeø§ˆ¤YlDêSízZc}]q‰¿†øL¯×+*Šâ\o Wq™IßÐÙ À(C�f¡zÁ ]°.‡ç ÛÄGáOЯÀ¸ÚáiØOJxuN@\Ãð¸ È\›á¨Žx±¶òýgJƒŽörç: Òæsÿ%uµ±·‹[†øöó\½ ¶Â1…ã†W`4Su›_x‡ZHK×·è—ŽÉóïÿ‹`†& &WVXa" ñ}¸Q![Áä§”ÇWåÉ*ÿ AWÁ°™Tg5&à%-UvY¸TcNH8½tw³XzU*·7 ¼?Š’e܃o†\žà ƒiÖX0µ“uà ”që XØ#±£‚9мÈtGôgi¯°ÍÅ/ì¬/âlcj/ÛÍ(5,üRq@ P+ã ’¦­…‰©qÂIÛ™ €Š)La€v¥<“nä< MÌLY �� �IDATÜ@ÿË×2˜Å­a’‰®ç°ƒòE&×P¡¬£ßŒbb¢ÀŠa ÙO&Iã ¢òÖc´[©B-Äb•ÆõTÃäÝH>Lô á$¡(Xü”ÓDd´e/Ev™¸Œs†¤“eRXJ,I/ðJ‚Ëó¸+h5Ô>Fx‚dS̨ln¢V/º s’’ƒ6Ñbáâ Át&Tœ™­nx¤œs›¿wu»²)Ngdì˼(e!+Ó*ã”1ÉtV)d¹ÍÂÇ%¿PyA%T¢³‰š -N[•ÏB† „T.•Xo"«³§žËLüÖËYº%ZjL7à*!Gy§Ê¢‚OÁ]£¥>»zþùçOîH‰ˆ³ÄSÕðv3ØÉK¢ÕB—Ñ4aˈP†ã\¾3?þŽñÀp í¹6ï^ç¸sñìÅ™Kf\£.UR|öˆ5imÙÕb„!‘ýAÓ5årN8«¶êІJá’oÄ'²+q Ñ0—ßx,1o5ò0¯Mý8\Y‹VgÊ)é’-k{ëpur²u:¸ª½~Ô zÄ!0ÌX=ƒj/â¬(ô £®ŒJæ)«m"‡3à_<5c:‰áE"®J,Žh7.ñÐ:¹fÐ%Ä)+Ýð÷:®êŸÅÉ, à °> N‹b>”o;ÒÖx¢Ñ�ò3ð&‡Ëå>&V«5ŸÏ¤|cg`¼F‰µ^ °d´›Ëå2ÖªZ­:Ž­çœoÀÕ©vdTîÔé‡>øüž…,tÏÂ6ø<<íâ£>nÖ¸Kç*xN�p´Á ×k„ ôÃZp¿ÃWà&ßê85:a=¬ ði;­–ûo•MšØ»xä2~<£ç{ô—¿Ïí»ùxÑJg˜Ìj$uVIHV¾hå£3:}…¹Šþ³&ý¦n:û±”A…sa'|7еÀ|޾¥s–ŽGcÌ„§Ê…¨‹:ù7?ßÁŒD¬À¼Î¼™%.´ÒÑ4Ò÷ZX­²6Žg’-¥;§ÍÏþdïÑ[S¬Ó‘¼ÂDU6¾Wkøó4hdh8\á®—¤hðSžÆÓ@Pá<›$:6 f¸NÁ¼Hdަ •#r”…án&*xý¤§i5£^Ëc.8Æúž�);å2v‰FW#Ù•Ö·@›r+Ú1Öl䨳¬÷RêabˆP'cÀ0½‹ø¢bX\(Y¼J)>R¢Ï„ª#½Ì6}ûF³Œf°f1+¨Òmôeè|•m´éÒ8¤!ŸÃ_u±ëîï`"D<ƒo›3F¹'É& ‰Æ &.r¢p:¹¦‡5ULeèdJçc "*I \,#Ëhnªi,1R:ž27ŒÃ8‡œšH:‡Îózš8|¾TÞ<K—»‹Ö2m ÕY¸JZeH%]áë%4;á …ÛT–;¸¥•[Û9ÛÄe¶§x"ÇCf†/Á—  .Ò‰iM¬,rFZç]&::+|Oã¯ò|Z&’c¼FP#]àž%A0ž—D £Ï,~zçÿ-µ}Éážuw<Õ!RkÂÚüçæ¶GÚ†?2¼ÿ›ûu‹ÞúÇÖÓqÒ„^ uü©cåC+SËSõ# DMψÝF„]ÒŠ«ß; l.—Ë‚Î.€VQ”׿í.+o·Ú…vJT½ÄgÆBõ[{QìrÔgîå6Ê)#¯È<¬¯.—ët%æ&—J¥Ó…oÑ©r: ÑhTÄ\#3Œ-Ä]ˆѼÒNgöxJ2…Q_5®ß0ß/‡Ãáñx‡Ýn 9ñ KÐãñx½^A©KÔv¸m±{Q`Õ[!•ˆ[ç2h–ÿ/G©TÙçÙÙiˆè¼Gá°B�î†0QÈÁ:X„÷‚¥@»Äs:›a-ü¾ ÿGàvø„ÄaxLÁ…ðÐáðiHêÄaŽÂ;á©/ê³^ú�Ý?W97Jü‡¾ï6ùà“ÒýŸWù•®rGœAY§¶Š®~Uþh&$a6s©™#NÞ›§ð<ÙM3çêåæΟác:çYÇ UVz‰ëتhIv댨|0MƒÆË»é–ù–F·Î»ÌV>¢“urJŠ‚„>¬x¿ûÎ?òö!÷W¾Vä?=l2¥,ç•)fqãºìØÓÌhÖ‘r¡˜ù†S"ÛË+û9?» :œ(Vr*™izJAFΡâÂt^A ã¨Ñ�¹8tpüžyš‹‚¤½“ш.q‘3¡ItqðE:ȳy —ŸŠt©9+¸Ü˜ÒøX ©bÎâí`¬ í0±ºBÄðZN¿—ø1¶º(Ô0ÉTUšÓ¬Ž2¿‚ä 6æE"ŠÙÐÇ` Ç1ð¢Xî&ÿ,zX?‚ý(Ç7’?BçJf+V±8Àß[˜‹€÷ɦÃXì´mcr_‰b'cô6ò)é<¡*–ó³ÌOpv+Ó›_Îè=\ZÅ­SŒ Ì±±ÐJv”¼T¥ÃA"Ä&ëÏW˜rÕ"•¿Õ¹y&•Æ1Á»[hœÅ'ó_YjZL|®ƒ÷ ó-¸ *5þn…çÍ\f¢³Ânã*i8uvÁ}qF¬,X.sK„Ь°T¹ ¾pfQê’\ÁPõRMÛŒ‰§£KûeƒP¾„ -Wå¹Ms®K\=öˆXiMYYÇšo®AFÖe“j’­²±7_2òu‚äõZ Í¢éV]®É§k¤ý_A¬ßï7bS<ßóµ=-¿k©—ÜÖ·—êyõÃ’üCQ”z]—h”Ëe§Óéõz—x³Öëv—,è\‰z¹q…âò꽚¨ÖnØ-ù_Ñ. m<V#ûŸQÅ;#@¨\.׃™ÀKÃl×iãÍy§¸G¥¦èÚkBãSsýÔc·Ûíp8Ün·Ëå*•J ¡P¨\.ŸLñx<‚r²„¹d B«±h»¿·û“³g„+¡Ø…< Nxž>A~~ø0üT' Çá ö€Þ[%~/Ó _ÖhÐù"¬†åà…^ø:|¾ÿÎEçéË ®åƒocèvüŒÝ&x¿™_Ûù8ꕹ’ ÷Á7áC:„^0õ3.Ó§ñ¤ÂÕ˜¯±OA³0[£È-«øñ/¸úНÖ0ëÜ :;¡é…å-øú9"œb¿ÄÍJ:¿€-üb†¸O‰!/3öy¬þïÐ ºØX~ßauû.ÞñæD9‹µô$íiü2/öa¦à¤'K"ˆGåH†C49ÉEy©ÀaR#PaÖJ¹Šµt…ò M15Î@ÿãD.¢<ASs‹D¶ó“FiT9û»|¤‰X„Ä]L43«#½ÀæMÊá±Ó ¦ØÌ\+šÉ~|+ûÊãž cϯ`ÀBmè],~rë‘:è^ %5M›Ä¼ƒÃÃ4PøCT[,ã�çÛ8øo·“QYÁÀÑyÌlc‚ÜV…ˆ¹É•i“Øñ2rµiÚÏâàÃ\ÀÚE|K_/ÓVäã4äh<Žw޹0Ƀ˜½ä&ùÕ,W{é¶S¤%Šmeï ÚʘUfU*:çè³h¦l"%=CLãke>‘b²Ê¦ Ë~2Ï…ªÌû5¦Æ ›qÊŒkœ¡ÑN¯gŠišÆ=Ó³pdUžÒ¸ب²*„•ð÷2;5V(<¡3?Ƀ1¸ƒ¢Ò ëà¸áÿi”(C,á·j),)6Å>a¼£ÞÞ{{Ó+ÒgÁ-¹Å˜`@@Žpµ=á# 6×õEž×>ÓRj}ª5Û-õ•ÃDJ¥Òé$·g@©ú‰ÆO÷ÿãþö?·wþ´Ç #ŒÎÐä·o]ëc„BšßtýÉI˜Ñ ìü“ÜúiÈ"­_"UUóù¼È¤vaò»Ä0ÂÈ#OùÜë×Çø·0Ø5.C¼B¸O$+Æ`¬8t_<ý·Rt­ï’Z­V‘¨‰:§pb<¹`pºW¥ž_ºd'Q.—c+cþA?ž7«)¸FávxDb�.ÐIA�Ü0Ã6¸ž`;Øa,ÀF¸vè,ªÈ`Gá"™Õ6¶j<Z!I¸.ç:™Þaž> j€ñ@\ú§Aéâ›4vk¼jçZ‰'r\�¸8¸à1È™¸JãrˆÃ1ðAÒL¯Ž¯ÆŸH¯ã×™pŠßÉÜ,Ñ(1%“•8§Fsì‰S3ñ (KÕ‰À±aÁÁ;«HVâ\l¢7jìQ9j¹~¢å^n¹Ét¸9KØ ƒhö0±iVid4XÉDŒ`Ž0¤¡†¡Ä»ÈXOˆ•©fÂ4dðÍÓ&ö [{vQpàYÀe¥ÖÍì0Ž2îE¶6Ò׈£ˆ³™lyJ)!–ò[ÎÔmQçh°±w©“ ý¤›h(S9F×fúÛ˜ÚϦ*Ö.ÆF计êX¬¢Ìè&ÂÓÅØ3­É™4ÝLr7ÀA%K—‹\;OÜ‹æ 6 Y‰XŽÈÑ8A3e'¹Á'%™š‰d•ã5Ì֬刄>‰ÓN¾†¤àôcO`uSPØcÊŠ¢aÓù;?ÒS$ÐFÖÎ17&™é"…i–ü^‰åe«rU+ãƒx’ï”Æ:ü8Óü¹BÈîGM€£2› Cg‰µn|þTbÎÄ5ÚSäd6kT$”ŽÛ¸&O¡ÀeEž†¢Ä!- ™ø€ÊÏe<f™ïRxIÇ/xáJÐ%žÁ?ÃÛ<xŠýï™ wB‰bЮê#ÃáßüzßÕÓRÚ|•±‹ÆÂÇ®�ïˆw격\gÎ}Ü}†8þVj8MûšIG}Óå­Ë’ŒàeŒé2:dsç͵ïjﹿ§H±^Qkxgœ|ƒëñ¦2³Ùìr¹Œ_­VËçóÅbÑXí7HÕÇYCãlì!N6úSÅÀ†·¸8Â|ÖèßÔµ/€‘2C&r¨a¯gäsõCÔÊ4 Э_ŸzÊþk甆u?ÛmÓëébÍ-‹Øè+ìóùDºl·ÛÅ)ÞúCPØÅ3]ò¬·-&º;îÙÁgϤ»ŠÀÛÁ Ÿ6s¬Í‡ÿ 6pÀNÈB‚ÐÁ_3œ9¸þ &À¿|}HF%¤qˆ¯î�Äyˆ³FøçïÁ,Ü ¿á_*ünR¿é'~*&î‹1¿ÈY2«d,¯ãb6B6¨ü­“ª¥6.„kK8Ê<Î߆Ïý’_ù$Þ!q­Ît6Á‡TšT$N˜pÙ‘Ýà~¬BQÃï‡kS4W‘c|ºÂì"+”¶:þú®f Í46b·&h±ç2[Ë(5,1\YjšÂð b˜&ñ¥ñÚp7si‚•Q’‡XÄžÃ4AsÍUÖ$p½J÷31z ‡‹‚ Í̺˜šAê v=íàP˜dˆ¸r„E/Ù*îfâA¢¹å%[ÁVÂ!¡kìÜNs+Ó} q¦hЭ¨^r>2‹DTLabÓ˜ÓLë˜,¨Gh?Hå˲D¼”t¤ú¬l£5Hp”tnæM„™×15pX扮 Ì^ÍÞËxfަDšÈNÑ£¢ÙÈÏãpQñSé%;EDÅ;KsOWË,/p›Q#P…N· È\¢àÎqŠG¡iXK”‚¨M¬vQ]M©“ÌйòEãè¾Àh»Ì½+¨¸)hüÎEMb§ ÍɸNÁÌ_W8d£¿•Q×ÂZ•Rˆl„‡aQã›Iz4œ:×ß@‡F‡Îq3]:qÐÙn"ÔÅ /kŒ™8G 7™CŽ«¸¨IÌÜzr1ðMc¢Ýn7,® ʲ`O,1__ko<JžÒøEã#oIt%D›Ä=è^yÇÊù³ç«ŽªÑ½§e+ƒP`yý8ùDþ)¿»è¶V¬ŽÄÿPe·Û].—@ޱ«ÆJáÿŽeÓçM·>ÛºdO]*• <;¹%:‚o%ÝvGÆ´ ÃŒ\`a½±Ð)ÿVÐa Þãé~S”mE{¬P(¤Óéx<¾¸¸X¯Ÿ=3– BùÉX+rFÎPXÛ^?êßétŠ®§?444x<Ѿòz½ÆŠf•xÇê]ŒeY>ðžËž^Vï[_ßQo‘øsƒJZ*•r¹\±XÏN µñSƒjø /º‰’¬¸x«Õ*V²R©˜b¦Š¯¢ñ&½«ÌBRy7×Q �¿„1˜‚ëáAX“ð øü.…™ó$ *_‡·!¥@Ë¡»aHÃ]å�´ÁzÈœøœúÉ<OüŸºÀ‚|¥ö¡ZÿÏyðçùüVõ·”X¸RcPÁ ?·ò{¸FeQâ<™UU~VÁ¦Æ¢X'ù¼ <ebìcð´Æc:>‰u’L@!§3ŠJªÂèZÚgØ#çák~n™£MEÖ èô›…YžÂ©<óÛbð‰ZEçîMèݖáÃûRèï¹7\ÃRÅ*ã«rBÅ~!™{ˆ¬À|ŒE+;šˆI˜4Ìty)„Èô°/‹?ND¢2OƒµÌÊ,œËó>2£t÷2+!+Ø ôˆ=Ï|Ó„æpÉøâæp¶Pìe¸… =}ŒvS„ÀrFW »qÍÐeažà1B‹¸/å…q:kX",ÊhOaºš§Ãê6ö6â™MÍè—1l¥ê!gcAe2ŒaL9ˆ+2‘" !r³‹9'& ½‰Äc\´2ÝËl#óiüç±»€gž³û˜œÃ7ÏÛ$Ì2Z€¤ƒR;“n2/ÓÝLÌE¤ò:ŽjTÆè.3Ÿ§E¦=K²À;Ô·±ÿ¾#ó¡E¾º ¹ÏnväA£o9ÃCʵ«%ýÓgU¼27‰\¡¢’à6TÙPä1ª1µš…€GFSùdšÏKl0±Je¡Ìª^ÒyBe-Ü e8ÇLHc^ãSp­ŒE§6Ã~ ?õðÝI§`…F ™ùŒF³V¨ñÂÖÿ«í-‰a% I“–æ“kÖÕýHw9XvM»„üV“4ψ§ÐZxé¶—v~qg}çF„ #‚ŸÒøõµ�7w?Þ­kÿ= ÃHø–4„–ìŽ&‡ñá#oºqh쪱‹?q±¸‘uw¯;ôW‡¶þãÖz>™SpòÇžŒpÊi¹\|§ÜLˆrÙ’~Þé®1ãµöÏ뫪ªªÓéc;EÕ9‘b�#ϳX,år¹Þ¹Cà¥Qyƒ¬ ë¿%ëc” T“> ¨~óÊ­ÄÞ÷¶½ÔöÖ >RÄ>C\ä’9Æ¿¾Tý—BL&Ë(PMÓ4Ï §+Ýuð¶ƒTÏ$N›Ø-£é|þ¾�Cð,‡‡ábpÂ…ðdAŒC¼âf¾©2¤ ƒAó“\w¿Âú ÊûŒ¤… láj ‹Î=ð(Ùuüûõ¤H°üB¾ûGíÎ{¸ûræíš³Ä‘-Ô$•ªÆÄ!¢r@ån™:…?˜Ù¨rÌ26²*ÉgM h¬€«H)n0#Kø/@£¤±‹Þ§1hf|žŸ´³Ñe³v§q.Ùè°äÒM5¹ÀøHˆL{ßÑÅwußr[펯†¶gËÊíÕ–FÚ¿;,ªÖ4y°:G‹þAÎñà ¢³FbÁĬ‚7M¤‹±4~Ó‡Á2Gôö•±ŽÐmÃâ"3M»—œ“Ò�Ë’¶ÑÑ%ÊM¸ÒµœùNâ­L' ÷2¥AœÈ<<P|7» DÔœíTJ8TÌ‹D˸¶sLœ$ £71ç!ç¦Ä;ÈZ' .\GX×ÍÄ*F,ÔH˜©„¨8`‘>¨%i<Dlåx’î‰<eÁ†µ›Ác¬ÛÈ 6|/¿f³™qvªHË™"z {+¸cDá‰>R¼GX]À["ÔÍŒœŽ¢aÃ/á²âÎlb.ƒ?ׂ¦À(2ïrb sî8=vL.fLň-lH;>÷©æ¿Üh*U«Q ç)XVåVUþ^§_g¢…óe¾Uä½5MD4^Ñù½FEe«†d¥ÓÊ—ÝŠ<C¦ ¡q²ÞÂûüäóÌ‚+B0E¥Â+›uβУœ†ÖDJeG€é­‘ýĉ=ö˜¾p2øÌ½úžPðÞrpô£þQ?&,e‹ñåÿoª*‘*äZséµéý·ï¯4T:~Ó‘[“óúm[½LXôQ–@éÉ=›ÍÖ²µZ®&ž¢‚tÿ…r°\l,V*šCs”Æ*NejçTÇŸ;jžÚÐû†zŸè•eÙV¶Íœ=š 5h "È³á ƒ QŒsQ«÷VËeŒø£nl¼ÑÔ¿lÔÅÿo8¨.aC¼iR÷QÆ¿N§HR—PTŒ¦NýNB@”qÁõ†xÒ—Z?ŒªÞcw ¸sQŸWœN§Íf‰¬˜tåõzÅ©³Ýn7PAX!¿6’Ê«zÇ¡öÃí¾ƒ>ƒ‘QOŽ7f‡Š«»c˜€ ˆ,JêÜfL?“É$²=‘« Á4ˆâf-Kï¾Þ3gô;è±0TãxüJb›„Û! ßgM—z˜¼ŽòZxbð×èûà0trý!:ø‹¿bí$ïß+yrC“>.AYãqø!l”ù6 ÂÏ¥øXMºæ˜ôõ¤ì:K¿á§”G˜QØÒÆ/šiðÂ>°Àf't~û5î‚v3ïñšÅ!1 +5^†y‰ev‚6”2ûGy® Öù8·BÉŠ-ÌQ·—/žš½ô×Õ{¾®6fjŸý±×cMìÞ¡këU†š˜Ýõeë#m¼«';1•ì4kG׺«i8×ÜTJ«cËŠ¬R¸´‚^c²Ìt.N¢AÍÅËtŠgü¬VÑû81M“F­Ä!•Æ•”«Ø’4º¨v3¶ˆËC-B,EÃ<. Ëì¨ %•aÖ áòxŽÒt6ð £KÅfºi?«›˜ËãO¬`®`÷Ïã^Λ|k_[ŒÈ�=“t´0+¡w2^Åj¥$á'îÁ–¢ÓN9ÛM¥…ØŽ¦š)û‘T”~86@9ËÙè]ÉXo ÷å,¨D“´ë˜æhðQ±`ÖsØÛ™ âÜKP%b¢h§ªb*!)¸ªLÔË£ÐF¾¡vf X5ô�ɳH*ÑVÁª1¥ÓXÆÛÌ&™2]ÐR»ñ×Õyrt•ñ¨¼¤q~9™F8®ãè7ñY‰¨†;Gçz6Íñg;4:L\èå Ù*6°¶c‹ÑTb=„Á­#vÜf± ±"·ÁZ +sÄá¸Ä_è$œ<Pák2ëu~¯©²§À$\jÀÕÄÄÄž={ÿê p5³s¦ì.[f,Â!Âh‰ªH©TÊ„3ã7ÿ®¹õ‘Ö¡›‡ÊíåZ¨æÊ¸lêk¡ÐPðˆ#±&1uù”f×zþГZ—¹qäìï=úŽQkÖjxÕÔ·» vµøä%öÛÆ°]£ªSŸ U½Õ¹³ç†®Zܼ˜^ž»j,8t¤^c™/¬_¹`¤uWë²ß/Ëwå­«3îZ^i½lÔ0×îd Ÿˆ­†ˆÇ@ñ›Æt]êÆÆ‹tÇ ¢Ú×®¶ZÍçó†þz‰ïªÈQ„ÈWÁÄŸW*•%.éõnÄU@kŒÒ¨Ÿe,.xÉmÖó¶…¦ê”9ºQŸ©›1¥^Ô ™­�-öŒäOPï„ÕºøÀ¼9xûa÷¨»ñp£Hš _Ñ÷1Ú;"œ‹­Vk©TÊçóÂ(ÒàdŠÃÐ_³Œç+@W¼`"Q˜]?Z8€lÛqÁàJª1U#¿‡-pHâ¤a¼ г™ÛÀ“{X¬Á ü.‡KaÆá½På÷{xl‘ý'<ûoÒ©ï=a¹úqûËkÜ�)÷é„à‡ðüV¶Þ'ÿç Ó¾kyîJýâ)láö ¬¹dØôâ;%†`9$à7p-Ÿ‰Ïé¤ì,·Ëð(Œ©ÜIh~šËôU9\&£Ócâ=2+<íaºBÖ‚ÇŒ¿†'w÷?×Ò=ž{¯lùÚ­éá5Ù¯ü@»«M¯‹³¬úñ§õkoËRLôõ/=!=¿Ý“V´­c¶œ­qß?Õ–�Î*Í^6Ù±ª¸4‚j=,.r ˜3x øÊ¸ÝäSl÷àIš"˜"ê#kB[Í U ÝI©—© ö-¼jc1G[’ŽSf¢ “L܆ßK¾‘?¹9<-ÄIø(äZ˜OcoeÁŒ&®!7ªb'ÒÅÔ$á�ù0³N*aU¬n ]Œ/⌒NÐ0MK”xž ;Þ(‹:’B*K«N¥ù#¬ Û +ÈZé=‡=3DÏ㥡Ì5š{™/3a¥©‰˜Ê}øÀ:GS÷(Ëš‰CÈBEEn"žÁï ï£äÁÙÌ|?µ ùf*0C(NC É!Z«hÙ,ŠÇ:â:Ž0ÇÞ>W=ûÛ|ó/Ê7W¨j¤$>iC^A,NÈͰFUaÄAO„c‚*å|2Í+MlÒ˜ðà„¡*~Ø 1Z¡ý0dâ]:wÊÜdg›Š’Cƒ ‹Ð¤µÈ¿À%Öhl€-Ûu–ÉØd:tÞ®&''÷îÝ{J«Ù7ÀÕ¹3Ó›§ýúÅ—_„cÑÏP¥X,Ξ5ß¼±%mÍ/5»Wÿuý C ¢™t²6¥´º¤X•Õÿ¹Ú>o—U9¶1ÖûXo`40{ά©br$¢U¶ÄðÍÍŠ0j³Ù mÐ’ )þʰ®0Ì8ò]ù¡÷5îoìýuoë®Öl{6Û’m>Ü,n?ל“ŠRû3í€'á¾j¸å¥-5|s�� �IDATàÄ'úî«7D7ÊŒõó# @2zuÆN \Ö;ãKôÅRÔmZRáwj$:bF=\"hƒ5#6(¢i]Å©Åuªª*ÐÂè ž<pËè-Õƒ\=cÞ ù“6}>Ÿèu…ÃáP(ÔÚÚ ËÜ(¸9b¡P0θû¢Ý©@to´~h@}WdrbŒ$¯O^°'ºMFm³¾R]SBfxdˆ[¼qR‘ù >j=\y½Þ-gŸw™ðüšá£ð(\¨£êh…m°‹=¿äC &.‡4LÀ§àX÷Â>¸žà‹×qý*¸¢JNcšŸŽk¤U"2OƒðxÆàF¨1ûkþcµveR[¿Výo±înä¯yùEÆ­Ú—¿£ÓÂw£|C6ëôÁ­:m:+áã*>KˆûéQØ ÿkdÞ)Ó¡Š&šápœ; |?F_†Ç* òƒ› ¼}ŒtùÑ ºoøªü?Êœ-cç‹w-ûÖБƽ¦¯ÝÅWîÍÑ^Y´²e¸…ùAî˜ÃYE-b ŸÁ6Ïl ¢L÷2<HSyz' æ)£­e´‘å 9X¨0¶ˆ3‡ÃM^¦<Fd€ªLVF“Ð3¬§×D­D4‹w;{·sdžõ‹DBdMÈ+9ž%&fF9ÂZ«F¹)IÀN9N¨Ô�+޳RÁ1E{—›¼-IØNÙE¡„#EC˜Ì^¶+8dÌ:’o#3„žeõÛ6qxŽv }-GV3ÖÇàqV®`ÀN9‰í0ëR4h„[HOÑž£3LÌMÞŠ< MÌEX¬2•E6Q-‚…‰äô.ã`’y93Ê0ËXB¸Ìì'è4sØMÈpáÒqT™Å»œ¡bœÇyµàáK7§M !>Ø¢ñ½rœ!xJç/tþ3ÊÛªœÈÒ¢’‹¢÷’òÑó2É(ž¤èÕÙz'<d};tÆÅð¶"²NŸÄÏ%.1q\¥1Y@Ñù¼Æ�ø³t¨¬•péä CŪó*ä—G‘!Mf2DåÄ(¹,ÿÍòÎ{;Og½*Ërh_ÈT2•Â%ñýww¹ÇÜK¤HõGëÞÖæñæc>Û;ú±£=Oõ�£¶?Û>³c&ß’7„¥'×$‡¨)¿ êK†%ŠºÝn“Éä÷õ>ÔëXt˜*¦•¿XiMZcc’$•}å¹õsÏu¾Æ ˆ9Ãés¦ñ‹Æ—|¾Xœzûq"Á#XB6©T*ÅbQ¬°˜é' §ãˆàëv»E^òYŽo‘=ñ¦‡¸\®%ù“ÆàÇ7x¿‘óm,…Q5”‚¹àóù<Ëå¤|k+þD”ïFV´l7(©P¿#àÐn·¥¿l6+vTµZí­Ð_O¶»\rׂ�bPKN§48®Ê A3</Á0ןA‡ ðv’û£Ä„™»!a¦*q2°ú ϳ=lœâ_²¯W5·ðU…P™I î³°€¡ÖÁ4Süëjí ßçkŸáÒor–¥‘Žñ³ ¬â ÿK·ü~Å»Àb¦nm&Te_‰{túáèÎÑãyúu6Ã>/ûüGŒ•šÆ7%þNæ™«ÛøˆÎ=Úmßê»ó–„Ï-LPâ׋fÇÆ™§M·Ëšt˾æf°p^W8^-ê+j;/¬lÈÿ,þ iâjÓ:fz™(ã]EVb…‚%Eà(ó%n•(EÍ£ìcsÞ5Lº(eð½BÆŽ7˲<YÜ“´g5‘ˆâû?´½g˜å•öÿ«ªÎyº{¦'ç Ñ(Žr� !²ÁcÀñbc/‹ý®½`/Æö® ,¶c›œÖ`L @(¡fF3šœSOçÜUõ~(¶Ü;2ÿë¿o]|€¦»§ê©ês?çœûÜ7 Õô=É¢ 3>Ô fêÊáÌa\ÀX¡8ãdfñ70:‰ßC¸ƒñÖMËÉj\Ác”R[Êd)“Vd‘ jÞdÝ»¬jãøVDp“F(!r¯˜ÈNQ²U=lxƒö˜œH9¬ R#!Š,¤ ä÷óჴ<Ã¥9ÊG©´^A‡Ÿpƒ>¢û²˜Ö¡€ù$M&²Kˆ-åä^ÖORo¤¤–D;½ÔEhœÄ9¨—±rÌ"ÙnJ¢´dxßEÑ“N`eÚÆ°÷,µ;h21^|Ùƒrr(¼mU d$ŽU²ÃË·¦ðOrÂeqöåYäXž¸b+Ï„hŠ¡ˆ,“)å„À ”¨ü“Ê‘[á`˜É(õ )0¨ØŠÙÑÀàR®2P¯ð3xºri9*�³B¿ÌÓ*ß1Ð/²XqíÀ6{ZæX¡ðÌ<A¤ŒäêqÖ@æ–‹mØÖñýŽd ™7À°Be^Ófµþ¼gŸÇÀ?½lzí÷×V=Sµç›{œÎ᳇›^hê¼®3lkêZL/<4TЂӚÿjRoì몦Øè¸ºcÉcKþ’¢&cÒ˜ $UQÍ83YGÖ9þÁ!e°ÎYãeñý_ß¿âgˆk±ÿ>t)÷y¥3-àJr,O«G®ÇVí*´¾V›Òj_Ú è£Hš¿{<ײ(]2\C}MB†B6ŠÎÁ;u[ +ƒ|t¶È™ùúÛS{I¨!¢ÆåÓàJÛ<išúÚúd2™'?ÿäÖŸoÕ{i…¬úB)$RØãÔ1OçûÖ�µ]šÎEÔ7§j ‚ q=Ûí®«««¯¯÷—ûm¥6Á-¼ÿïŸY‘Ý €“à5p«Â~ÈÁJØ X:àß¡Fa+üþ5ð)8ëIxs17ý™ë÷‘ü²â¹U°9x£ØÄ¥*ß’i‡VÈÀ>pÂI†?·2õˆ`Ø(m2Š}eÂ’úаõ>{Ó–´Tg鯣F¢LâF‘˜Œ1Î UáðžÀ£0-“¹H +°Òç@ƒÌ€…LÅ%8Säë8˜&a¸¢Òz¬9Ò·@BR°™pÓä{ùâáïݧ¶òíÛ8¼ý Fb"ËèÏ‹>±U9ôŒôÒù¼u¹ÏL²V¡×ÅŽzŒ2†aª!YJ¼†nå*/¥ÿ$mY‘ç0—žÀ`¦ÕC,‚Äю¼’S”Ê y˜½’7åÒv‚“,Z@÷$eË9"@O g_5à üVŒy,x˜e| ç-ôÙHXN¹:&)‹à®dÌN2LqýG©¹„7“ØKPª‰Äp™É¾ÁF73mŒtS²)/ÖFúÝDE”jF‚ø³˜3XÊ9[E° Ä(òNcH’㯣X CV¦!„ç(Ëò™cfp& è+%â'3GI†Ô"‚´4µ²¿ã;3Ôd˜«ÇÒͽ9<~RI\µøb”$™u“IÒSd+ßtRš©åÀ59ž6!9ˆÏâX¥ ‹X¬$sŒƒ[ÁèÄUÁ\œ MQòFr>B#)z®Vø*”Û¹¤„K£ìS9T‹óì2pe”GÃXB¬Ìð¬ƒ)(´˜0åq+a°Sö5eé/¥êåw/ÓdâK %nß}÷]Ý·P …Ϊº4œN1Ÿ'1®3å¼½é@zôòÑh[Ô±$Ë“¾Ÿ¦°§í¦Íf³×ë5›Í4$Tl6ߟ1iŒWÆ#‘Ƨ3îL¸5\±§¢ëê®ò=å§ÝëÝC]3¢Õ}/¬Ë¶~@Ä·Š]gu5½Ú¤OY‰¢L,š"Òž[öœõÏgéÔ ‹Åâ÷L-Ÿš^<ÝôJ“ÆÑmîïÙu7z=†Î{¥„ôÒ«–Chµ&ýúõê¾Bíp­¤©óÖ çTM þ§7q!.ê P!øéY‹¶ŒÚê«Z¨¸XiZlžv†öAݸDC>M]BŠÒX ‡C›6Ëçóáp8‰è@«U›eYžõÎŽÖ6loÐË•ódgõëÒn´.פ‹éº½Ú¾GÇ3ÝWE¿}ڼļg½ ª¥SºÏ5ÎE‹¢'ÛO¾òððÆáóî?oÅŠ¿IÜžJdÁ8Äà"°çù-|^„à÷p¯@«ÊVˆÂ.°ƒ –ÃhY¡ð¶²ñóp.ß{PpšÅïm’ÙeÇÇ®0 fø¾À? )l°®S¿ôyÀÆ_]Ëùê…©;?Ÿz¥”7Z¸ÒŒ J„MôFV8ª² îƒ7Eì2#QÉ DEzÜ\—fÀÀ’çyF¤1FE„˜Âñ㬱P&ìz~dùh®âIõáF--äú&6ô¾÷oùÛ4GÖ€’%dö(þR¶ü"ᮯ%î^¯ð… ÿ&På%—AQÓ¨åL%,DÒ„Í”c±„J°…à™Ú$r"¶|f$•üJ:â8Æ)W 4¡Ô³ ñ,äEä–Vº#¸CÙIˆ(fÓ4îJæê0‰ kUµµìÉ`vÄ/ ¤°>ÇÅ!¼Ë9 DqµÒugÁ^šLd§)±’ â‹ã¸˜·¦),tw²HF*c¢ŽqÊã8ªî¢u”Ê¥î¢¾Ž µÓ"¦§HÚ9o#Ã,8D¾…¨€|q¦‹ãXò,¸·÷ãªal„2+LR帻J>Š+DG9˧XìÇ9Î\–˜ƒ_;ÀÍd±¡9O`’X5ÅžßØ*=Â`I¢¦[z¨r$c\háÉõ6–8ð$‘T^vq›‚oŠÿJ"%)Ønf*º/ {hŠðˆÂ^+áY–ir-"6 ®$ß‘ùbм‡¾G`‘ÀgíxS˜r˜d^ƒ%ðS‘¼Üú#î?šïz‹ÜbæÊÿŒžÓ©ÐBð m}ø´9AóýÍ@²:9zõhÅö ǰá©õ oáž=Ôš\7¹øÞÅ@Å®ŠñsLJ7 ¯¸ïCM²¡Ð)øTÒ¶V¨ÑÚ šÏ…ÅbÁHÍhMßÖ>O§Ç3âÑk¤:R±¯ÂÔoÒý‹ ‡Ž5;ר£vEP ëlºG»6N4¸_éæ!ŠNTÓû(…¾z¥±Ÿ¦çˆ§%²Î8ë:ÂÚë×eX«øip5ϾRUÕx<®­áGñ$<­À±>¬aƒ–Big¨½3‘Hh<ˆd2©¥†ZjUÈÊ«+ï-\5X¹»R{ŠNmµêY‘.Q¨•¥)²ëŒ’yâ“óÔåuW”ÓêdZ,§Óyô¬£û*÷}ì­õû³&''.Ç™‹³ðœ^†~è‡ïBÜ Õ S*¿‚üö€ð<ì€aÈ ø °&¸ûJõŽˆÌKp}„¦<<B'¼7@5\*ÈÜ~7½oòtZd&˜}››®å/¨žå)#9>Ÿ 3Ä/dâP ;áI˜9!q |Vf.Ï®Jg ÃyöJÜbä^‰Ð~ß¼–§%G|ú ¡·–{îæo »qÆn}4o›Ö<Ô%°!Ö`Î`ŠãÌgñîo«8Dnpá7÷áqQ?ö fÃÐÄ ‡tŽºbb€‹¨—?‰äޱ½w«€E@ª&\ÅÄRzâ8ÔEY„<¹zúMdŒäÄ…t$±-¢ã íA|IlÌCÔLPÁÝ}ÝA_íaŠØÓXƨ°’²“¨`ÌM¤ŒXGŠ`#¡"*a:ˆ¯þvŽÚI¨>‚ò@Il"J5à ¸=„«ÉbJc N ÷å½–q`”ŠJF‡ L`]ƾV†Ûj°Œ³HÆT‹#†µ–‰rÆÛèXF×>ºˆªVB1¦0”‘2Jã8 ĺȧ¹%‹É@&ƒ„1fËÉĦñd0ç‰gHØhÁdfH_ËCŸâÊW¹ÿÉ÷Å ™(v…¡ q…WÓXçð‚7p¥P’\ÝyÞÌS!+RŠÀ7Ýdj \b_ŽU"yë,*dÆá„fq€ ¢€SÂ:K·Œ.—hƒ ¼UÂ{p·hÈ|vÌËTt¿>þ—Ǩcñý‹½Þy*úQÁC­¡Ù¥³u/ÔR`Oõ;ÕË»\̤ó1›ÍZÛCg7Ȳ¬û|¾@ PZZêóùŠ‹‹Ë¼eç87¿>ì¦c¹úœÕjÍÔfFת‚šÉdTEM&“:‡B&õîð:ûü?;´Â¦&"¬±ðõj§Î-4‚K½|ôÔš§–÷è×®KÑë©°Ž…º ½þµz ¥:ÍO[Ìl6«Ï*i~Q…ªö§rgÎŒˆZûMÇø\.§ñƒÁàÌÌÌìììÜÜœîa_8]žÍf[Þk±Æ¬»?·»wcïGùs:ð븨qF´ÜKOk"|†ÁµBôºúÄÕå±òu#ëNOOÕ[k²„ð>A%<A'Àƒ?B5œ!˜†,,‡ð*ŒÂ`ð¿ÿ·À&Ø«p-|Þ‡(¸á<qX-{E% عëz¶mƒuð,6pi# û©ˆP›#ý^™;`B¥BEç`Ä\1B‚}*«Òl9ZÌŽqæ.4`0+$!3•\TÅ¡ZFäç/$ûƒücM¨¬™’qŸðd‹„G¡8OÒ€ä#gÄZItœéZraÊœ¸ýœœÄ4JZ%<IS’t«™r'©Q*gp}’7©=ɦµœ4bï'ÐÂX“‡XžÆÒ@Ÿ‰¬ä$¥“”I[q\È6`ÇQÄ*Šª;ÂÒEôi P€)u²}|ð—÷–½°²óήIéå’koT™¶S· ó(>×STÖÑþ¨ÁCx7ë*™1“Éb Qä&rŒÅMHYÜ@?õ‹9f'1„«w' ›8y‚ƒÔžÃöC´Êx2˜m$A´am``„ÆR¦')­c¤‡“À4,àÄ µa<)¬*˜Iû™¦d€­“$1`DÝɆFN„ìbA€Ð(†5íÂdG4aR©KàmB™bL¦<Ã~>݇œgQ)ö=y”9Šãl”pN†Œ7ÝY[}¨ÿÁW‹ž1£ªä@âŠȇöŠVÙÖ¯ Êr£ÊÙ*µ2¹w«Øàø$¯(\à%™À˜aØ@}ž¤ ¬Éc—Y¤Pé…û`Ì*Kñ%…¯ÀQ0K|ΆWa:¥{¾­üðùÈ:5ýopó©êjÚû ö¾ÿ[GpY°ãŠŽŠf¨®^Wýsõ– åÿÔž€t�Ö*6:£Ak¿ Í³­xbÅÛW½½ãë;6ýû¦ŽuÔ?Y/‰‚$h½z-*iÔ¾V+Äý¿^ÝÅX#†F‡ãƒ={ç:ã•ñ²e»º»íå¶òCå…|ÿ¦÷Ûïk/̉ 5µÔYë`Ê*Ôµêõ1/-oÖÒ]EÑBùi-:µüI�]îOŸ5ÖM7+ÑhŠñx\Û¸h“L¹\.F£Q]0B'ª‚д¿IœgËfßúá[`Bå‘ʶWÚN;w?‘yœ=Õ5™ § ó0}< ™LæŽæši~µñÕe“Ë> \MÁ`…k¡ > …káHp5ŒA+„û` H`ƒ{ ¬°!qøW˜„„¯A.Ü /á|›_ìç®uL¼ ¸ V ¡U*'`¼-,ïå.XÌQdc¹ª8Ù²ð4<ìd‹À•QJe*bôX¹$ˆEå¤ÀX;VØ'P/s¹‹»M ÏÂlÀ’fÐC¹äð«ÏÊ—«WýAŠÞ1û”©B®›&›'j ’q\ƒdO07ÅÆF‡ O’]íÌœ ÚD “_´²:ÍêqÊ­ô72>NÙK¬]M_€Ò£ä#\ÝNHAÈbªbd†âîIJ*ÅßLO13Ôb¹‰l ›é*g|†âq:-Ôû™-gÜæyýù;]ýþÏ]u™!n<i9{fß÷ÿ[oYëÎP:uökýO<¹öÎs#¬é¥QÂxª)eðjq<ƒYFr»„—:h;NÛ*ŽÏâo¥+Œ'e-{²˜ª™0¹ŸUõô×0Ç5G¥™œ–x¥±8IŽS~‚Æ£Ô,`BD‘'1û±î`c˜ãU¨ý´ÂÉ•VhÏ`R*a07Ie?‹sˆ)Ä R ŸÈ»ã¸Æ˜‚õF1~PA¼˜2/1 é•“øçø¥Ä—«É&°š*N4päEz?ÃÿùÂ_þ]8ûN…p1!Ä4kêò”l,I°ÚDÎ7`ÏS’%Ù@Æ@Cˆ°H6‡Y"'Ñ”g3\¯ð°A¾·y¹5ÀÊ!þš¢nƒ"‚‹ÞaVÈì†5rÏ密¹U^×s¬yŒd-îh pŽœÍfõ˜¨ýŒuwM; pè'—Ëi =ÁæàȲ‘•ÿºòo^Ži¤´tÚýì<O¼ÂÆLáÖX›•EQËNæ•nl6[mm­¶³Eq`` 2ÙôЦx>¾ûK»×ýǺÌL&•OF 54s¡ÄGW œ‡¦¹\N/$F-ðÍû6-*lù¤äÔȦ‘¾KûZlmzªÉ˜1âäàgJ©¸£•¼5à ¦Oš–^5ÔÉ{|ˆ3½Þ:³Œžvbz5¸Â`·Û5hשö:]ÿ~M½PŸ“Óî”öPi}&-¯ÒÉ‘HD[7­]W3Xc;j+§\»œHMdßMû 3†š÷j Gô § ³%½‡§ßbõªÏKè¬kÃë®]—>õœ'ÜÓî­'bÎX•½ÊïòŸ™jØ%°^…›`?\/ÂO¡6Ã2Â#p;¤Àp Œ”–ÀB¸H¤Mà»*;ë†- JC1‰zâf¯³ù�×¾ÊÓWp°]L‰jê[Rª’*«¬0Ц²u–=_WH¢Z‰<J×Z8.”i‚­9–dù“À+-B”—úÁn…,»m\&ðŽLY€ ºC΍I°<Æ%³LGð öÙS×~`:ÒžS¾žá'Ýɳ¶ ᦒãuf&¢,Pã9/ n2³¸íìôÚ˨ÈbM°©£D¶™ †©YÏžÎ)E‹•´•ü.ùJ@(c¢ŒYÅèg6‡QA¬dLBñt áMaóã®f8Àô(•»ÿy›ôè5þ{>oI ïÉ«Rߺ{W7ÏDzoØSÝe#ž}÷wÏ•<ynÅ/®Ä¡x‚r3Ù4ÖqÊóX*0ŒPe"g&›^È4Rj#5@±ŒH w«´ƒx“ì þåÉ`ÎbÎatë§¾˜Ùq*üÌFð˜’P³¸dÔ�S‹è 3°-ÇjF®`¬ˆŒÓ0õ"¦j6‘c"0Kd¼¤æ8dgA3Ñö‰8}XR¸Ìä (! ¼*ÝV¤1úDZçèPè4¤ç©E¾”-“rU<µ>Ð]¢Œ´ ´ÙÓaHñÒPÁT“*U~Ÿ#ía‰Ý=üFe¬Œ«b÷±ÉÈsiªUZaöÁÙ†U)fyKâ‘_©Äáå]!žQY >ÈC¿õñ«óOý˜KyòÚÂ1á;wžZKÑD¸5!´Ý®ÆìÒƒ‚Þ×ÒÝ8*V‹ÖG3¾ŒeÚ"Ër²1oˆm[óð+V‹bÉÇòBJ˜WôÓù ZJs?Ҏ¡ŸB³ìôé`m³¯}Óé´Z­ååå.—K㾇B¡H$"§e’Tí¬²‚®›0tÉPí˵&“I³œÐ,-xŠ.óâø‡ YéªtZÚªcÞ©úLz÷E'é…ŠCÓ˧Ûþ³ÍÝç–²’ˆXÜ_ÜøJc÷ÅÝjZµLX†W Ï4ϬÿÙz!òA>Th¦k©âTÎ’ã¢vCõØ­­•®(¨[ê84ïç-ê¢æ5„tŸF=÷ÕäÕµÕÈd2‘H$‹i2†‰D"‰hx  äF£Ñt:L&õ„,ŸÎKYIÊJƼÑ>c¯Ú[e ÚŒIãi{óèú‰æLº§‰>w\è{©Û kåe½¨58™€l–Ÿ½îÙ2™¯ÔWcj=ذUÄ(°CÅ /—áì„f0Ãó`ƒ�…Í0Ø Ál¦\â'9Þ®2#‰ØT<ê7v(íÿDã 3¬bíC,Uy£Æ±#*³ÅÍ9ižS9U {Dv«t XTî†);ËóÌBg‚~<a:\¬øTŽ.E Z`˜%åi&œ\¯òº‹‹“8½8EêÒxR<éæ‚ŽðåG¹x~Ý»©u»X7"­1®ÊÕÄ9!Qk%œÂ’d‡x–¤„½Æã‹SLð‰V,a&Fq²…ئYaZÄ+"å±W2>§ÞIüq4Îá0rXǡݴ×´1“ ‡1g½*â8åÓ”,ãH»ŠÃXDHÃ0,¤-dfñ/|£¢óÏ?¼èÚ0ÂZÞÏbJ޶ëv%¯{abÇJÛïn^õžÃ@ÞA®ˆˆ„¬".à„ƒxó>Cáëö$Î>`Xrp\*‹/ßÌ»/rn—™j&¬¤]DÇ) áŽâ­dt–â<Š…”%„ÉK\`z˜2Ë,¶ f¦ñsXú)³1¢PÄï&b&;FEK˜ ›‚¤07ЧŸòj’s˜§™6³³˜Æвl4ºˆ÷±ÄD$‹ÙKÄÇ‘Å:JŽb~ö¸zÄã%ªÒc¡ÝÇ@ŠÐôÕÛgÖ &ßY™¥7J2GÜ&²R&¤xƒˆ5 ›¼!¦GE¢$•¢4™4Ã%¬Hà†b¨±C=<yí|:ÃÓ à„@@åc03°Kdƒ“ËÒ/F0qèCáª0ÎΣYëI˜¦6«w¶M&“^qÒê?Éd2Ò™Ü8™¨J$Ë“ÑÚh¸5o‰'ª«Y“Éæ�� �IDAT^5o®è´3=ºdƒ&#¤½íïVx ‰øÚ+n·ÛUï:¼öðxíx ¿·¤÷˜ãX‚„cÚ¡MéÓÄÀÐÅCõ¯Ök$C­Œ¦¦B«óÔ U} ’OÕF*<1¦×Ðt÷ }k¯¥F4GÍ)*R)ê.*„º’ƒ%;îÜaŸ¶vJß(%ŒÞsšG/Ônª85vÞX´>j ùý‚:?²ë"¹:1D»­…BÍ"Rp* ÷ºz“~ïôý„ž—ëîY…êú_ÔèZIP'ãh©ÞlìbW¬ ë¼?‘ö¤û7÷K1Év¶í:ïÑ:®æ©)j 6}~%UK õªéHÕ¤j*©LÖ%…aQ|õ˜3 /C.„¥ðœ—ÃPàPÀ÷à¯p.8%š–©ü{НÃËÐ^øÊY*ÏpÇŸÝFó7a›NR×Kèî®»Â~?™]‡³ Zä „Eå xNa©Ê.X>Ç´Â X6Ç6À.™ÁZÈåÂdaIž^‘…AŒvfòØ"ø .ÇÊ ^õªmEµaKÐËÒX"Á ÿ[o´÷áâ{>6ÅLÜOí4Ó*{€rÆgh5°}œ#.î!QFªŠcYJ¬Ó0)Ù†x‚Š… î£ÕŠ”Ãæ"VJ¤žþiJL£Ú@¸’ÑŠ{([ÃqÃ>â8Ê8‚c¿€ZD¨ã?ïERƒxý™¸í¦oNP–Ä–ÆÒø³+ö}÷ß=7ZIÉH ¢‰¬ûų]v¤ºÔÑ9[]D&‡±šá>êˆàÎ » !Œ0ÁįußýÈæ%¿>øÏG>÷Û³¿ŸÙÛ´˜ÁÆÅœì£!¡†¡Ræì䊙é¦ÅNbð¼žèu/qg#c³ˆ ³¥noMž\ Ããdæp6<F“—‡¸“X §‰l13.b8lÈsø äÌí ˆVÃÊ1J-|gow0•ÃÄ9D…›°X Ù Ã1*f¨531‚šù—ÔÉGÅ›þ!ø›/9Yb ÕAF`¾ò°éº§dæÈ«LBƒOzX’Ī|B&*1 ȼª²ÌOsˆ«F &óÔ(áŠ,QrNªó%*憞†G"|Z% *lƒ–ZÊF©Qè‡Ñ¿Pç>ÆCÉÿIdžÂÄBkHè]mË\X?ÔÂnª6uükÇk·ÕÖl«‘­òĆ ÀÿŽß>eÇü·i$ÝÊöì7t.øGiE|˜Ô¶ Û%9LíœGoyïÁ–ƒ ^\`è1œ¶‡¤íµO ‚§ éä=ý•ÓæLÆk_«‡Bê&VL ®ø` Y¥†# Þ]^íS••}ëû²Y÷˜»°HUóçš‘­#åï—¸t:€X CÎ’;þÍãî wé®ÒýßÜŸ-ɶ?Ò^x ºž¶{ÐÉu‡n8$Ûd /çE±Æ­_Øø—]Ë·æ%=š]–FÒÓR.ötŸIí=:q4Tš^>-åÖm­Ö9k¡TG¢8÷Å7 6A#›œÖ @Ku×廬嗅§ªm ôÖݼa€yÏÃÚ‘µ‹=‹À êzW%}'<fä¯9~ ¿¶ÀðYs€6¸<°_á•\ A¨”[fø•L&ëp=ÛΧ €wöñΗb™<Û“|J&›e­Ä™<L«"¼¦±‡T^1ðX8 ,“tp2ÌÏ$®RYUF2BÀÌõAJ 4ç9 ^èÌRgà•7ólN`FÙ„¿Žh¸ýhhï¹ù® ;0%ðʼŸ?47»ÈfÚ÷“Ü]yßóçV´².ÂÁôãneÔŠÁÀŠj+ÉT1fÁpœöIŒ&²‹9´—%>r3ðÅ$?*¥A&ÑFÿ 2’‡p_kÏVF7pdš€ˆZÂtO!Ñ�^;Áá»~·ëüÁM7_sˆekØ7J…ß4¾cß7•¿´×ßyõ0Õ^süáñÝE÷ˆ¥L*ˆFr9Œ%GÖþ²#Oþô’Ee;«ÌD äc8—qx7«K˜5“]ʉãÔ÷¬Ÿnû×¢iiåÿ¹´ç®àîÇï•Îå³};ßfs̓xê™QœÄRXG¨ñÚC¯}1ñÖ–Í÷oì¢ý3l›`YúÆÝGÿŽ9÷šU÷:‰9°PÄY6" Š(6’iãñt!ËĬ¤¼ä: ¬ãp gƒ›\K®wYj&iA®Á0¥Ý»£´ÆY\GÎÍX‰~êÔËßäÚŸpû;îßH*©2,YFÄ[ߘYÕ]FXE2+±X!”çÂ(¿tñÙ[eFÀká!ŸŒàŽRçbƒ– bž8¼4Ç{ÏJSD†ŒTGÉ@ Ô@v)\êàK"Á(Ó|]f!Ô©¨°€'ÿw9…f}´Lü9Ç´£b…$IRVªÙ^sêGtíÁSõjõŽ—¢(ñx|�œ*¹¤OžjñEëZYéhÑÑk_¼Öçóißiî6KQ©ÈVtø’Ãñ«ã¼qÞ‰é_þ¿â’n³Ù´LbžAíäCojÇ;üûü5/Öhœ—Ó5µnêÐe‡Öüd=b/š)Rª\,§ZÉN[±Àî@ß§ûú/ì¯{¥N‡+½æ¦C}𺕼+ßòŸ-ΰsó=›_ÿñë‚*,tù©`¬eB’$õ\Ú3´n¨ýÉv)ù·úçöÛ·Ï-«§¾i[Óß5½,tG,¼qZ•XÛè…Jˆ¨‹“%¼ URÞDÆžÑÌ�Ù(ï»y_QgÑ™÷[Z=¹°ø7éÈl¶P°®t>¤¾ 9UsDçj’$Aþ p%œ åùD`+dà¯ðP ¥þ(ós•Ûá18Wå?ár0k´ø KžOûモTßß/Щ²µžÏNP›by;¸JÙ2˃n*g¼“ahWYÅæ¢Äï瘄:(/Èã|n—i2àšÄZJb’ ‰é<ÿ·‰x&dËl€±4K Æ€E`WŽå=Ÿ|¡(¨yqÝ0OÔáíãˆÓÊOYX{¬‘g+úîxzò¯Ï~=— òÜÕÂx©H‘ÌÐIÒ&ìY.Ĭõ1äe"Eõ,î :¼7Ä·Zè“ù·~¼N&‰7Ñ›À~†EŒ8‰ R@i¥;„'‡»Ÿ†Vº¨qo¤÷y.?×þÂô7žîÜ{åÅ?¶Ìeª’/¢¾Dj>µñë]—Ÿ8yËåwɈcõš/Õ¤°¸‰t²°„‰4Ô3çþܯÇ]ÄWÁX ÿªPUKS'-.jƒX‹PO°t+oìûtOÓÑ¢ wï‹°J KË¿uÃAiÑÌ“·ü±q@æWCä3˜gÒFËu_1E-¦©ì!–$ž»40ì¾ä>Û˜3õ½Í­órËá-HgýéÀ}Ó”4qr‡Ž³èVù1ÆSÊd71œôÎ0\Œ¥‡ªÕLÆpleoÏ lQ16ÓÁïefW†¤L¨™²AªFñV‘¬d¤›À0N q#Å®»¿;רmŒ¯Ê=Ù?ûýŸ-½÷ÂÑ„/¿(®ŸJw‹—~klÆSÂ^~WXe.Šòm »‚ÙJû^|‘ ØE–)tE™“°KÈ2¥F$-6vÙ÷©¼Ÿg§‡ïªØRËP+Òlà'yîV¸ÀÄõ îX#r$É  ƒg<œ'mäSÙSˆìZ¹ÐÚ*‹éuüÓÆ#ýé&³Z ‰4Ez®èY×zA>¢“ïÿWt<®æIðéÚç~ûÑÛ½=aLè€T*eŒýÓþ³:+íH¿xÿ‹ÅÅ-Ï·¨ªºþë5ßÂ3Õ¼b±Ø©g2o”§°ów¬ò§Žßt|ë¶æSùl*›Íf‡aƘ4>Õ¸ç–=Ë~¿Ìˆ±ñÍFËŒ¥(!Š¢sÖ¹ú·«gªfþîrüêÁ÷­r’ ®qו7_9½`úå»_øÛ)ÕÞWm3 yadõHß9}‹Ÿ_lŸµÛ&mú{®¸ùбåc¡ºžó?]áµ ŸÍf5k`­b¬Tõ:ž†Uáp¸° ©ç:…éµR¦ì½~oÅÑŠ5¬yïÆ÷Ö<¾Æ<õÁI'œ#ήP¥pmõ?­ãLa‘P—þÓ³«ÂŸÀß­9G£QmÍjµž<y2:ug Z Á¸V8_¡R0߆!è÷°6O^a ôÂïábØ oÂ!¯Ð?‚¾²S87-=ü„|Oä[*?R)ãT9 «áë)*Ôʔ͢¨¼¢±x =ÃDžA/ç&½C**¿—ø•J7Œ˜ó¸“$¸JhJÒª’C Ça5¬ù“…óóô*䡯„Y^òxºÈ-¼k´ð|‚¯ÂŠ Z}Ø&¨Ï©ÔÈdzۯˆzfäÏü…_ýˆ­’ö6´K ì© ãÇ"#©ì r¼G Í«qÙ<ÄÚèIS\DBE<I³‹x+ª—¹6:£¸K™´1‘-e*‡ÑJ$CDÄ8sÙþs§§–|âYKN¶gñ:vSa"«"ÚälqG©ºðDãŠÝs7¾ÔSeXòvIo[ #ÕL—1Y¦LŸ¸ùíâ>¡"øhòâRŽQç$gB¨cd-{;X4qô‚É•ãÝ_Þ1k\r2íW悲}ÝS \XñÀÇ7<°´î K¹ð­ß<cXÐ1ápfƒÎ­÷/^Ð%=ÿ/‡æù€½¦×$(B@™™”+»n~ÇóÀµ)lÓ”$°73ÚKm±â9ŒÇȵMcIQÀb¢{ˆª #c¬®fd–áõS”[™ bkd&H¿!Î’ˆfÌSÝKYЏ…„‘‰ÆbodD‰ó‚w3Û·²ôÀÌÙ³-{êò΋Ò_zĽOÉ¿Ñ$Ó#&òIc*v7k“t¹Ù Ii S­ð‡R*%2¯ù¹ò2~/·DÉð)‹UP Òô›x¶ˆ†*]v¼"7ÊTT²!ŠªrLÁ/"ª< SØeä¼RJ£”뽫‘‘‘={öèöºž©VÒHkçè¯hôþ§5´fƒ¶wÞù‹+J;J µ« iӺɖ'é íBÁmÏ«éÌÓ$Õyz…]tý›ç…Ѿ‹úš^mŠD"sssÚ|O8N¥R², Š`H<‡<“Ë'{>ÞÓõ‰.ŨT¬˜ç+8Ï©O/ é«QX$<utZ»@½C£½!Yž / œ?²ü¾å,ñ*àÑPQ%UªÜ_yüúãQ_´ocŸ£Ïaœ3jR]!"^Oz“ã];£P<W_²CeǾx,Qžp͸Ì)³A0¸f]-oµþ“*Nõ\Ø# rÖ‘­8ZѶ½mpÅààªAQ1(–ˆ!^OySŽÀ©Ù•VâÓU£ kžóø‡Z§«ýjoÐ8óÆ¹Œicàd ¿¥?eM-yvÉ+?~¥´¯Ô²ÎµÌØrbÕ¯W‰ˆš¶“^ ÔŠÕšS°þÍóÕW½»¦ß\?¢?™:ÚÍ3pÑ 6›M–0 ._é¨8¿ƒ!…A0A3¼ «¡Î_Šã ›àm Þ€ [TÞ†Ax®£®Šo>->ò}¶­Pªò.t©dD¦T.…8 àöàNУ2…(8àÊ; Þ…#°Sd!4Ã*Ø¢pÂF{§B‡Èr#ÓYjk°'(2“Î8¼¬ ™÷%(´©t©‹Ÿ‹š ;;Ÿ€LŠT₊bTÉÌÑg &÷ÆZãKŸ,ÍLDhPßi5QnÁ,ãU0[‹è2SÆ_L]�ÙE&‡:G©•´…LÓ峸âØ=Ä*›¡dŽLÇ5ÇX,cðò\Åþ)J-äÇ/}#wÍ+E=©‘æŠÇ79HÌáóIbK`7“1‘ á¢ÔrháLÛÌæ»×¨Û6—3ã&j"g@V3XziJ‰óŠÝêþU¥LŽQt6»'*ÌÊ·MÚê³*H3”É•ï«<µ¹ûÏßµ>pŽŒ ÝeLÅqjçæ ^’Ÿs=u‘oŽÎŸ<VÒQµh %O—+O];S,Dîûá¬ê¯Þ]™ÇxäÊþÒPÖùöŠ,fIEô3“"Ä*ã âsãJb³’N!52æÄ;‹ld<ÏqŸ27q#Y'1Û0fƒgÙ0˜Q‹˜Ì²/ÇÉH)’°‰V7«}¯]àÞÝVzýg• å“ON¿tSò :„Ü_+Íxeö•\ši™ÙaˆæHf1Rã/ ¼*¹zD6§)1“Œ–Ù âã*]E¸ÁVMw‚¸™VΞcDáqè΀Œ¬0ƤR9‚È:›È*h‡E QÐ0®táQ­©PhÁ§·‘ ÛºiPa5O„Éó&ÃKÃ~¾áT¶t¡Ê»ª4=ÀB"µ¶³ÖÅm5ƒ ³Ù¬uzôJà<ÔÕ ôУÌöŸß¿`ûw#w¬ý˜gÀ£k$šÃæš=5ÎY§{ʽôñ¥Á Ež50еSýèp¥‡9ÝËJ±*× ÄëãY_¶á…Süoz¸: 0Q ˆž!bP>³Ð6R->¸5±ª˜-i³ÅmºÉèÆÑ©ÕS“½HeTŒ5{j"U‘lI¶x¤Xw_,ûõŽyëÞ¯m=yáɦwšL&SÑ‘¢âÅ'>vbhÓØoÚSæÔøêñâ®bÇ´£@¨‹9鈮×ÖôµÒnk!eFWUÖ¹º‹‡ÞÿËf³†iCÙ»ei_zlŘ5lkÃâxëxóSÍ.“KãDj*²]´ËÔAhž7[a:®ÏMëÂùZÁ@¿¢Â=vóFž³Ùle]óàj¾ƒ`3pÂ$ü´Áûp3Ü #FpÂJHÃjØ-ÐªÒ ¯À |ž³.¨Þ?nŸ§°^…Ã~•'à6¿@<%r8G4qÃÜþ¯{È”ƒ6Sžb!lq‰æ1@*G3”ªTЏüJI…ù“Ÿâ,pçIA¥HU‚R#Åy >ªÓ ‹-JQ´fÇ¥VÄ,VéÜw’«¶Í]ppÉζñŒAå˜Ê†,QÒéínãÀ­"&âi~b«€³„`–ІG¨®d*ÊXŠñ"ü}T†qÚÉt²@ ¦@%£íÛKKá^J„J ›ÉÈâ8ò†ÜE=Ü5rõ5ˆœ\¿á·m5GŠØc8è<„½Ì ¨UŒºˆÙI–3Q}Ä;›+wâ¤ÖËœæV5E ‡–¢}øeÉŸ0‘³’Ø{ßã'Ïïw”dnúÃô¹êëç gÊ[\À‰ –²Xô ç¤gU31‹ßHÎF2…-DQO©‰†ðþóƯ›c-CÉîËáÖÙ{ïQò;7ûÁóK».>]ŸÀžÃ8Ié$Ö¥vŒv’ à!2Æ‘�GTšRØ ØÇXÅ(è¦ vhœ$G5¢¸ šðH˜Ò=Dq¿H±ÀoÝ,Ë"¨XÍ1)Q”ík­8à{wSöòw/­¶½º>Ë"™•Í´Ì’p) hU¨R„z‰{=XSô[1OaÊrŽ i‹Š!~ GÁmbKŽˆDE›“|‚X?ŒB›H›D³Ê}pŠ$làU˜ÀÂbðÂÕèèètµìB#+½œ¥“Ù =Ôuçí§®5iN|ùÄ‚Wx†=®RjêØ?Ë»ò®“®B곦I¡ÉU”””¸Ýn탩TJwº:­Ñ‰Î×›ŒFcïù½¯7jäãL&óÞæÉÊÉ¢¾"í´åžt:’ðÑQ‹tñx\'4Æ5=øÎëÓæ4…-MRhhËPß§ú‚«‚¾¾¢®¢šÝ5¶¼M‡ŸÂé]ýêŒ)£kÜUŠ…qÓ3Ï6ϪÕ=âEq¦yæÐõ‡L1ÓÉKO›ƒ9GÎ;ð7UkÒ:¹xÒ1ë°¥mƒÁáphÔÝ%$ŸÏ{º=„êC®—ÑhTÒJqOq¼)Þ»¹·¼»<¥¤†¶ µý¥MÏ/õuÐ0Cßsè$ K´GE#qh-ŸÂ,JE($Ðë&,™LÆ5ê’ r¤&âtÇËâõoÔ A¡X?ÏÆ^ƒImÛqª`؇y•éïѶbóž«ÂìJ{Ì´€l6»ãƒËÏU.=30Ã�ôȃ(˜! ×.ƒw ƒOÁ{·©X.UÈÀaø<‚÷ü.È_×1taž¯ |ÎÈ}N ¶Ç Ta\`“ÄÕI>Éò ÞÇâüH ñ ì ÖÂQ¸1à «aØÈU2Q‰Ý2ß„*\4ËDˆ\†)®é–9°†lÎ ?–x2j`Aˆl^²¿ºÏ,þÓ0+檥¯t~üÎü?ŸkpÜ|ìñpÉﲬ—)•As³ÛÚMsçˆÅH Pž&$ÖAššÔ–FL)Ðu˜š22q|^æšâm"^K„fzD“˜ªùÒ_Md6}ñÓÉɆ½áGzùÖB«¢ÆËÜû¬–+[Hç�uFr²„<@‚(¢,¤sÇŸeËìMâ�jªc GV RvVõNþú§eÏ\¶l¨j"Üê+]}øÁÿ˜{õÿ\¶î¶iʶq^#½ÍÿÕ>æ[TBDB®f8‡Ñ@>‡1Š+†³ƒ6á¬Ã3/4;dû'O$[D(ÂXù[eÅëÿݱú­]]78~ù¥ê“æ1 á…Œ½Îù"®2&5™DÑæÃÔ8)Gõ‘å–vnü*‚“ÖÌT,bà$õ „iÄ+âîby1f%É×Ùáf»ƒ»2˜#L²%;’ç¾E~ñŒòŸ#;®QHeHÉt´qö�Ý" *Oª¸el°ØÃ²¿L°e‚Õ2¯ËL›øj5J™D(O/”€~æÂ¦òë þ9¾‘çµ(= k`ÌÈsôª§\å#«e‚`R{ %r£JZå"*Óüãã|íüÂ<)‘HhTìyRâ…Ûy]° 0væUF£±ÿêþhKÔ{¯w^ÆpZ‹…C7šm˜]}ÿj"˜Íæd2©åUš ƒÁ`p:6›M£HhÓ9ÚcÕ-¿Ú¢£ãžÏì©ÛSçë÷_w¼keWåöJ¿ß¯W„t×Ý¿ËBü°7œZ œš›\7Ùù¹ÎÖ‡Z=Û˜ ¬Ò¼õ<õÒ´K>UdáoüxY•U9ŸÏÇ+ãýú—<»Ä´V­š«›Û÷ù}Ƽ±þ½úý³î…Ûšf¦¨ÑX ‡aÏ g`Ë@\£m\,QËÊ'V¦]éý×ìO›ÓëÿcýGï/j-@ ³3™Ì‡I|ɲœL& ç»-‹&¯W˜A(9\¢¢Ž­[ôØ"SÌ””“z’]Øa‡‚g¾‰:nÍc…è0§êλõ²,ï¹dÿ˜¿jO—ŸIÕ¢>¯ƒUåN0Á§ø¬üo¥ör¸nƒ 2ËÀVø,‡¸¹ïÑpp]_ïSÿ/$|Yä !÷™ùf†_BŸŠ§Žå¿àÛ׳ø*>ÇÏîá_aîR³¤TþM9ÚUN@qŽw%¦2&~ggÙ•£AÁ!ðq0tÂE{Y(`̓"ɵ$‚D;Û$õö¹üu¿L³QáŠË„bÝ*ÎýXžëITZ0¥YXÊ ³…î~~kä[¯áIb sŽ—‘µ¤²‹EÍ”ÃÉ(XVr$E@ÝG«u‚rSvÒòÝ´KãhâdÍ´µóþŒ/úÞs3ç©=÷ÁUs}^æ¦É]Äõƒ8‚øBIÈYLMœ´‘œ ìK˘ˆàž¦$MÎO,»Ža/kÖsâY¶63ë!¼„£Q\K?qGèþ;„߆gÊï;ñf‘ËžoxôØÏ¸F¨ò3;Ý>üÓ§WmòÐ;‡w‹h7-òy/…ÕE4ÀÔåÜüh×ÖK3Õ(;LÏ‚îï·(z¾u$žÌ”Ùɬaÿ�uíPëé£"„k ˆ Ô´€;iuò‡^¨¢gu!1¨¶c³’´¹Œ—¶sމ˜“€ZÎxUb€Ù¨Žð`ˆ.3n‘5Иfn̺­]3 žµN³¨‡z‰¬›Ø~(ø$…yZílNþoRë /“<'Q©°PåNØeЈÃÂ{®3°<Ëëa#WYPŒ(Ò2×@‡À›*ßø²ÀxBàøi{ï8ÉÊ*ÿÿ}ï­œsuŽ3Ý“ó 3à iADŒ  ¸²è"®«®»kX®º®Ša °º,†UWD Šä Ì0¹{RçÜ]¡+çº÷~ÿxðZö�òû~÷÷üѯ~UwßÔUç<çœOÀY§²f³©ÖöèùhìB¡ ¾1&ço?ÿâZþÀòÞŸõúØ¡Uß]åœsJbÀ`„Úš«vöê³mûÛ6Ü»afÛLz[ºï¾>£høºŠoDÏMì¾…0„¡^^HØ{ÛÞµ¿Zk­XÅ^»(èSz)UR*JÙQÚ¾‘HD¸.ÍÍÍåóyqƒúÆyØ’yÌù¶ŠÆÚívL´'öݺ¯iÓ«nz• ÷Hi‰-Å ðBáååÕÏW÷è{ oð¦AÓfÓÔeS»þýˆ£yÁ쎹5§VsÖ^Ð×·Õ†ö ù“þ®£]v‡]HÍÒy†î†¦i¾³>»ÿÔͧÖ<°æNUBs¤%OÉ”1YãVÕ¨6 Â!vCËX”;â±5c[`d—%êþfOTlÆ]Ûíu[Ý’³4¦s¡«ò§z´Á쥀BKà£/*ÜÈ][Ÿ1v?™LF×õŒ=˜ HIéåE˜Äº¶Â“xp5�� �IDAT`üt@?ŒÀQøÜWA?Ì@;l/lHP�;ì’~ÜÊ_?¡¿óNþãêA¹Îu~>ç¿àZxVóƒ°öm,ëä¯þ†Ï½‡E' CÌÕù9ŒI¬r«¡•É@ÂBÄÌÍfêYêuV‰‰2æªYÌiÒð„Ϋtä 4µ}ø4ÞËîÅg7Ê$ì5~œM<¥%t÷Ьg^ŸCé#s F®‚s–M½ü‹ u(„DÍ8³Y'¯C‡‡l•L•æI:ªXÜä aQ„b¬™ZÆXSÃ,£ùH_hzêÜ OœmÍoøÃ¦‹þéµf3xO±ÊD]F»”'4d F$Ip’Yiùfu¤E=ÄÍÔª¸„r¸5d ygcDœê˜ 8/>7ý½Õg"ñ§®03Ôǹ^Fâ„ÇéRQd´�1뎧Fn¼íÆK¦^Ã|ŠU!&ê1"ËvP<Ê"Ž<®î‰®½­C½?úŽ÷¬¾}-r€“¦©ZÇû®H>ryЬ„~‚u2Ú0ËVpf‚hä"–6òª»(c³Qn£X@ ‘(‘ŸfŒ[ê OP3SKMPoãÀ<­ÎÔéÇ_㬓î©<î(+âM{ÈÔØ;Ïz™ÖùvõIf/}08¶ÁG·ç+²œ¨(“‰:›Ø­ñ]X7:(—³0Y"§%>¶@ .WÉÚdk¼ª ¿ÄmShu~³N®©ð Ÿ[-DG¹ö@PcJæÇ*ÏÃU&Ž*xìl/â¯sY-ßÊ“/©ÔÈ ¸)nÞȧYò97FÄ×Íߨ|ê­§Úžló ù Ô¯ØÈ‹ÍnžÕ‹zh04³c&Õ’êÿIãvU¸F‰Ù{¡Px­D"ñÿUÌ0Û‘µ&¬¤_Ä@èd(¾&î|Üù¢æXmmm"/Н" ùA£ 5 dçÛNM$!”Pì+z ‰îÄî¿ÛýRâåKžmcX\r¿BgÄ 0‰mÝOÖ Ü8`äª)#ÌêÈE#ŽŒc噕öÀ ¦‚v»½R©Ÿ¸)c¹çÝÃ×Kš´òþ•Jõ…Ð=í½¿—¿TÖ66Q… »ñŽ2ô™UíËå²14j,qÄÝ è¿Aœ²-ö¤=Û‘õLzěИ󟓖HËH"Y–ƒÁ Ø¬�Ñ­}å›3qÙâ:'ómó½éÞ—WdÖC¾‹à; wà  &ðGæ‰G‘)xbPƒG5¾¢ý×!Òy>ôkø-(ðHœC&¾(³¢¼ãß+Ñ¡K7É¿¸ˆS>¸>ø(Üà£:[`Qfü»‚V¢%ËÃIîÐ8šLÕÅœ‰\Š+$’_\Æ”z;vs2·rûÓ®»®måúvZLWF>ÇH¤íÕ#Þ?½M …“uä$Ö*š‚;Å0qYSùßœ¡ºŽb„ÚQúb<TÅRÂÛÆŒt“íL9(>Éî É ó­`=ó‘'>ûÓ7“{]VÁÚļŠ`±i;¥z ¨(‹r¸4dI$!åœ)âð’Y$"e!DbèÝ£ô$ °ÆAQC>|à½üòu]Œgñ¸É% [ê˜æv _>Úÿù7ì­l«`-c]D Y(»›©dmS3s:°óï®[·×=û¶Ç5dq©­G#Áû/ °¸H`Œî4Új³xÎÐf¶“Ù2Î:&‘«¦isR(â°“+Ñéä=:ÉDj,w’*cMàœ j"<ËŠ)Â)¢>:Jس¸5Xä{uJNR¬&Ly°Ìu¦¯~“>£¢Nc« ÈÔ$žVðÂ:™¿•¸¨Î�„Á¿Šs<ÀJ…åÐ¥ð!Ýmð,<% ÿ$ÓRäùy¾¬s fá] K¼mžG5–ÃŽ�·×¹MåË0 ÏÔùp…rš…:?ÕYFÜÊWßüʃ¾h€ˆ%>Õb&$ÐBó[8—‹ž‰Ùl¶Wí½öÆ6ÇÒËÓ/ÂÛ Öóùà‰àØÅcù`ÞÈUbR%dDkN|Íår™LÆ@jýÅ%È¡õz}fóŒ{È-ÍHBX½\.÷<Ô3ôÚ¡ ²â. µŽ—_†©ÒËüN¦;søÖÃó«ç×Ý¿î¥Úe²¼F¬%²„âQkÃO7œ¯sodÐSWrœ+ž_!ì;::ÚÚÚÜn·áD%`F° †6ܳarÛdÙ\j²,÷ÿ¤_®ýïö›–h»5¦ù—Yö¤Ý?æŸÛ:'”ˆ ”fã¼p ÛÁ¨ÞŒ±¨pƒ©´Q´Þ0†>“Z bT`Š¢t?Þ=·g®&×^¾ºš‡‚Ga9 Á‡­ Ãnè† :À¯ OçZ8 p1|ZáJC:×À°*üp;ožçá<÷¥øþ&phŒé<[xãÇùÈUÜñ[¾ú÷Þ“[ªôx,2×ÀF¯•q@‹Å*i(é„.8 f• ™™6'v;æIN.2 #:¯…Ÿ'ùd™wÉè*Íú]ƒM·DeÒL:IXå’,^蜦ZûׯÕ>úšYf\Ô"LÓlB Q¡È5CÔ63š ä"?ÊýUúRìhe~/•33Ͳ,ó³xüh£„¬XU”uŒ¬a …¿•™ßrÓYoÏ[okßï=‡5NØFÙJ¥‰ù3¬°Q–Ñ€yšl”ŸgK/#fj)üuLé{5Ï™©¹È 7¹�‹¬¢®ºŒÇ½dÒø’'èlefž¦¢N çè3Qw‘?H ¥²þLþê¡íwm Ì–eR­dÌÔ<d…]} ’ •Ê ÎÈhØÞËÈ ÖuÇ£}¿;’’LáW©“fÓr†Äew0£ úɶ1f[?+‹u*Ê!¶ºÉq¨²Q;Gs3y…]3|h%ŸöQ8C°J³L1ÂpBn¥‚¢`›££Ì±NÂãï Q+kt#”óŸü^úÓŸÈ0`"çÉ"EÙBÂN Ci ¥AV©< *¬…/øR‘Ÿ+Ü-u> q•ÌJX§‘×Ñêƒý‹ŒèÔ Ý0˜'º³EúÛHf˜„[ UPdî ²,‰žÔy5ü7,ÿ¿ˆ2†üÁ+qa·Çím·_=ž½!»ñ3åªl„ª‚§Ph*ä[òªUí~¤ÛpŠF|K&g¢KÙ(òöRº|ÒA'ÝŸ®›êÁ“Á%L, Ӕɶd{~Û#~¹X,6áb4$ÅŸˆ]¿ˆù¢®N«)Ní™ZóÀšðdØ\4—ù_p£ÒVFb[ÒžÍÏó/ìøõÇg½g{-6‹Óét8ÍÍͲ,§ÓiQî‰ÂÆ¢G×õÐñÐÖ¯m•s²x,¢7{~ñÑ8¼l¬ÅžÆ(ª ýIATh áN"ŠæÆzëåžj¸¸Ø·ØûÛÞÿÇ'©(ŠÇã)•JÕj5“É9~‰ßÛ‹bñæ§1ø|™êªÁ“&ìÐ!˜‡'A…ÇAÑXð Nœ� dTÖi†5ðAø7x'\c~ðcüÍW÷ð&3Š[ã*Ý|˜<È»¹óy>šÐO>‘e¤Äo̬³Î.ÍðÃC&Šû¸¾ sÌÂn…[áµ Î-hENLsï<ã5gÃì !ɬŽseŽ‚‹Ÿ.}÷óág6¤Ø1Ë¡,¿\EÓzbáÿyK!\¬ÞrŸþܲ‡òüò4¾ Š©—É‹ó¬ê�kÔašœÜf&bgO„`'íY:èì!TÁjÂÝÇâ(´4¾œÑ÷±3‹ç)6­,lëØßšÂo¡ºcçè ‘¨`ÝÂóg ÏÐ2F÷ «Ÿa÷Nö]ÎcAÍÌ& ®aây¶Lй’ÓmLK¨?çÒiÚÊØj˜;% Y¡ÞÍX3smL¯ãÄ2†w°9C9ÜA’ëyëõ¯îž }áiª­…Y;Z“r'E*ŠŽ´€ó Ý>ÒðÜÕü&o3‡»se”ô…ƒO¼1•ý‚ñ°Ù§Ø uLÛ9BK’‘,TGéžÆš•%ìs4ç±ö0ê![Çgm7Sàѱ’ðà©3Ðǹ ^ÅÏ¢‰ÙÃÜ7ËݳTš(ø(kÜ[à§½X§ù7ç¹<É“1oEÓ§gN^•:¥6=¸ÆÇÚfR2k¬ô·±§Â$òfÎ2¤Ñ)sgtrÎJôGy§Æ¢ÊCg5ðÓÒÍ ï–˜“Ù!ñq¸b}2k(çTÚSÔt,s|-ˇevÀ·2Ç5V-ÓxHc5Ø õE÷¼Ö?_Æg[xC;£9ÖH‡26ËÍs,¿ùšo¬9öÑcªíè ‡6øŽÁÐ@¨ê­vþ¡ÓTý3ÿß%+ŸÏçr¹ƒø‹H‡Š¯¢ËºuѺdtÁç.8ð±ªIuÄ"ÊìY¡PÞ€~µ@5q‘;ªqk/Ü·ç5s­î®•¤¢išÖ]b¦n\•p¬7¨Ö¶'<v—°¾Œ³œ×Fefü~×s]eO9p&Ðr´Åd2‰Ö®èÑ9aâ.TòŒÞ¯8¯xÅ=å~þžÿS²·¿x¯Lûó%òÐ’Ø-ržáÐ(PMóJP3u¥^´ŸýÇgÜr¤÷G½–I‹q|Ï{Qä‹A„x)ñ$Q5HÂÆ!Ù‹¾¯Ä-ø|>¯×ëñxÜn·(ÇíŸß~ø“‡_^‘ÝX5mœ¬óQ˜€Ç`Bâ&vi´@?Ü ·À<#‘‚×B^›à Í¼·¾ó¦Rß….M;@¶Æ¾,×ýž@ÏK·ŽKî!iMœ¿¿\š×¶ÿ¡ñ”ÄU&\2ÓUòÛÊ\”§­Æq‰¢Ì[ŠRé^ ©În«º$Ö•¨”YlbMUf„2˜´ÛP¼ûÖ –nZ}l§–“R­Ôôø6ß·WŠÁj…uMXd>×Jÿ³¬Iâ-â›çŽv¶(Ô ød†,¸W1â';ÂÊN¦ZH' X(w2å%g¡=@:NXë²­<Þ<iVP=TZ¾kâŸ[{÷î?p¹rŒ@˜ü½gXq*Ö2RÇ4Kk&Ôa:f7+ᚥu;ÏÙ)'åq·¶QÖ‘›™/á(àŒy‚-J óÓ´u3VÁúS®‘°S.c[$t0¾sÇ/zZÊ‹Çè¶Ru‘wPš¢½ŠÕIAFï`ÁCq‚®8þãl²Q‰vR»t²¸ûHð«7d[³ôÚGë7Þ¯<~I—S·„:LŸ›|˜|G;ÍÒ}–ÜFªTƒäSÌ9Ì®áÏÜÈ€…›hg:I°Žg܉£@ë*¢Ó´Ö(uQQé] Y¢ßE¯“ö–þ5¹•“¥{ï"¡výåTGN˵⣭ȩ*£Y:í Ú)¥(¨ìsrY…§Jdj¼ÝÅ_W©Ú0—1Ã.Þ"±ÝB9K"O—‹·yËaÑ9ŸŠó~tH\ Oõ±2Î/–kTáÒ&¶åY¯Òùì„8¤$.ƒÁ>v,â‚¶F‰Û}ûö"­Æj”11HÈi‹ÆQ£b!î— ç2m{Ú®ÖT@©*r^œœ{ç9÷˜»ê¯Þ6ØñdG¡©°ê¡UÙbà)ãXœÅˆé`Íy¾Æ/U]‰kÑ'ßšO¯LOÍUsc§È\0÷ü¦'z$ÚXu•J%á´dHÍ|}>_(jiiEÑjt4³–Z‘ÒÑÍ3`ÍZ±³°y!|&¼„…jÄhq„%F‚¬U¦ùÃf³‰T*ˆh3L8c9N!õ…>–ðɰ/æSdÅ`ΉǛËå’ɤ¨-jµšQ´éGUս߻ù›ÍU³€Þ<þ©Ç;÷uš4“»9IÆpÈxEäfñn1ü3 r˜\ÏçóŽæE›ªYMõ§¦.š:{ÝÙuw­ëúM—˜¥5Z(ŠÒ8ä["nbh‹´ñ£b±(Þo•?®r¹,h¿]VÃÌÅf³õöövttôôôx<CçðžYÕ\ÜQ¼FºþexWIø4Ôeš¼ÜRD+ôA|]c^ ÏA¼,{†ëlÊ–lø.Grð{âš.ßk×ï<%úû™¦ ì’ŸBó~Ö6K-&Y³üýw02á“¢ð*åp üDã¸Æ‰fqÈduœEà ðÕ(Ö3*ÃÐdnÖÈÁ‘�ëóÖ9\d“pˆ|+ÅEÜõÛ°üîk2¸À®/á•Ðd/Êe“ë™PyS3óc䋌»p˜¹NB1¿ˆ=„s§že‹Š­…9…þ ²FÌŽ-ƒw”îºkÓ~馹ó'õl`Èn5ƒ4Òäšx_szLF;Cg»%A8ÊB‚PœEÞ:æ.Æó¸çijgNÂ4EÈE¥ƒi+Ua¯ oâä"vy©‰…fFYv)O®àŒŠâ&&!Æc D-ÔšÉdðõ2RÀ¥¢˜P£Ä€iÚ¼dL¨1"2ÚÑ&†h PXÁY ¹Ù>zìu“•“[3§vf±lö<¿òÈŒ©‰iÙ±èm!æ&#4C—Š<B«Dæ£SlÒžFÆbFòŽSŒ¢ENaRñ§°Ók'Ÿ&4ÏŠ§ÌJ+kL*åRߨ¨VyÄÅ«R]ùØ[6ɉ궴çM߬=%éd5b:ËR8dŽëÜë _f̺ §d<n"e¾édQ¡/ÄD w“ð±ºJÖG5Ï6/?+| ð&¡cqhNq‘ ¿…½ž–èQXYæt›pABf<—ä+2—ëôéj|||ïÞ½ÆÆ\«Œ«AÝŸL §wN'V&2Ë3V³Õ[ôJ’Tö–ÇvºöÔbïbÕY-{Ê®× ð÷’bÙç.Ë.Ïzg½å@yÅOWaÑ(J ï#9¹ê¦«FÅîºRŸ¾|ÚYpú§ý/*pg �³á´´DfWì¦ý~¿˜^‹Et0ÀÄ•SWL-l[¨;êÎy§RU$»”k͹.KÑb0|–š¸ÔF°@£’º@ˆÄi„‹W w£æ3 >1g2ò„‘<2¢X,3™L2™Ìd2"UxË|>¯ªjrE²æ¨µœn1©&MÓb+cªE­¹kM±&#ŽiUdwI’‡;7.ÀášÈ¢œ5îÑ�6ˆÀÌ3‰µ‰Äº„oÐ×o¿)g2’ºq@ƒÕ»$]‰Æ© m5¢+E ÑhÆGÕëua‡v~3PPñÂá°Óéôx<ÕjU↲¢(=Ç{6oßý2¼+ $8 7%0ïà2™:¯óF‰ûà¾õ0™Óu•Ã|&‰/ÌoäÍ?á«?J|Þ{!cŸŒìz"ËÎ2%¸…HŸÙ®ÿýtý°þKE;±þV%®‡{áx ì ÄÏ1í ÀS .‰;Ú hΣTØ ÷Áõ0ªqzáa‰Mà“y•ÆD‚v±yºÊÈ€ ÝK­ˆ+ÎOd&M|2›¼ÔÎA3S*eLXÀ1O—JÆ;MDÂVÀi¢ž!ÇÖÍds6ê6ÊU,6ÊàõS6£Äˆ$WÖX^w`Ó½W•Ž_`Ys$vÑ™‰ÇþÕF9üÅw&F¶Çí{¼?ºº‰¼•Š˜*9)¤ñ…hWIxÈ:)LÑn£<Ck‚PS‡Ù|9U±ˆaUõYv…‰U,óD2Xº§«‰y1ͬa–Õ0 â5 ìgÇZNÖ1EYˆ)a/c ‘ÐÝäÚ˜>ÎúQz<d³aOÓ¥ š¨?êÞ9{å¯{/¯B<U.Î]8¶á_^7"9­”aÞE~ WŸRãšš¸ê­*©YšTÇïâð9‚ Ú<Ž4í)ü—ñÔq<:2T”jœ€„>Ã\:O3\RÀë¡ þ›t›WžlÕïÝ£ÙàˆnÖ縴ŠGgBÇ-sµFYA©2U§t•o´óns6¦c´Ã7! q Ö'øo]1.‘Ù¨cNãƒËÃd5v&¹þ ,+¼ô–Ù\åë A˜‚ŠÊW¡æþÖO0ɼÄ*Â$ìQ9 ¯]’�÷Åb¶lPO áj±M¿tüÄÍ'ÖÜ·f±wqüâñmÿµÍ¿à?ôŽCå@¹íé¶ÈþȺ…ºZoÔ¹ñMúd«<»cVQ”¾Ÿ÷•«åÆJÂpŒýß”$)<Þ|ïfSÑôBBÉjÆ’B6W4?…È…Í5¸»‘7ŽXÓÖ5w¯‰mŽM½j*0°ä-þaÿì¶Ù#·Ùö­mÖœÕàî¹FWã¼K^ŽFfYJ´Ô œ!è 8jF«PH“4fe£—+6 ¥RIÄtq›K63;gš5›K/ N&vOt?Þ]Š–^ù¿@Ø7À¿F‘Ü7€y†Jº¸‘­'vM”ýe[ÚÖOµZ­hþÜöºqZÖøÜÎo–Ý?‘×E°Z­©T´ÄóÉ%OCü­Ûíöz½^¯WÈ;ýAúó^‰Âûa³ÆWà£ðKø’Î:Ø -:?Óð$¯á¯O‘ÝH[;>•7浓ô^Bl­ò]Oä¡Û9áȹÔZð3ð˜‚6Ó:n¤k¥vøbèü.Áge|2#à;ô@¼ÞÅŸ(ñ´†¦ñ›2ysIâf–›yü�¶ƒ"®3}2k%îŠRÌ­ò §€9~J64;¿k¢·‹Dœ£SÔ$_$>Ïïždû"£qÜAÍ„KØ#Ì®`@&½œ e˜ev¤,™s˜�‹AÊAÌ#ô®ç¸ò†Ù¬WÍïëhïøÉΉ+ÏÔ0{È63W/»ûî¸ñwwþnîÍûê˜B$:˜\Éi;¥1º¿ê$½Ctá‘:&ÅE¾Žéy¶�QÀ#b£ì¤`ÑJ5Hþ}НæÑa–e£•Š…ê�­bv¥!—±­å¤ró§Y ¨(Y<‡Ù,ê³îf5äE5Ìs4E9Üþ”¾ê‡›ÒïûïVf¶205wé7WÈ›íRe,íèy\¼ËÞų³ 8U”Vf¶s`%ek8=A÷v²8׋¼†˜Ú�k¼Tl5œ ®<ÇZ.P„ x<Ä"̆©Û¹B*lÓF¿ï®©ž¡‘Éòå «ƒ¬qSÑ9!¡ó°ÎZxDg7Ïél€[ø§¬i6$XW%)Ñ¡ð&è5±Bçr…­5™ˆ™H˜,té/qÔ  Z=øe~Zç9›“£~lbrx¡¨p *T5n†ì‡ëaøÿ. ˆO¸{À­äï~ory2±,‘t%÷ݲ¯õL«oÖ·ìÑeÖ¸µù@sr]Ò XŠUè(L¿zºéd“ÈO"Ú "£Øj\ÊŸ¯ÆIÃËOPD4϶fË‘²èŒ½6DôÜ wG£¸i4â•–è½(( |,œØp,8L%S)ò§˜ÞýXwÕ^Ý÷¡}KÒ’,Ëáp¸µµU8FŠe(2üI1ï2?ïÞØèk,ÔÄ~Bƒ¿Œß¯ýq …b±X­VK¥’艉dV,®`ïý“Oê>Ýf³y<ž ¿ß0rÕHçÑÎW¾]0¸\†2Eñ+•J¥R©\.'›ÆlÒ�šÚl¶¶¹¶lO¶í¹¶WbsÓÈÜjÔ[Rú,ªª c-CºB<=#™o(S*•R©T,›ššŠÅb‰D"™L 8-—ËKØùÍÀIxŒšø¼Ì ™küúà\§` \°]8dúÏok—üŒw>)]ÖÌþ+ùáÙq”ÏNëó—~ç×ßþ‰úÇ™îûŠÿ Ímx>Ë¿>È¿MºÆ ;¨ýDZYã2ŠÎ káÇPZ+¶)™÷iDušj¬Ñ°ç±ê˜%Zt2e‰˜Î²^Ï*¼ÆuüE<:çì4KXª·?T»ûúß©°í`O¿¯›.©v²sܵŽ7ô3£»Ìq7 áVâ.ò§XngºŽ©ƒ³|]Ľ0Ä Ù*Ê"^µ ¾fæ¦KË|ëŸñÚÆ>óÝ<®uýÁ…þO42xÕÙÑæ#ÍRÅšmϺ¬Þ¡zŒË£Ä4ä:¦Õœòëc,M¨Ž9Ah-8ÞÆt„¸@›¨{ÈE‰E‰åp»ÈËh~Òêq"jâÍÌæ°. ïd¾„c‚.7ù,žNmž& µ-<"!"q’u+83D_ Ãã'ǵžãÓ´ŸfÕfíØæÁê©5šeã!ß`{{%æ=ÑÕ5àZ¬GcÓEœ§«€³›±YZwqÈ„ê'$6Bo/“)šd/d_ß `•PóxRÔ|äl¤²„Ë<Weu„¢…³*UìpâN’HÑj©¯Ž"ŽõÇØ¿e¤>oãCAÎNqºÌ:8³ æ¹°ÆIøt:øO—¦X®3 óÎ Í:Å*ŸP‘<âeg) ;d,÷ðÝ2Ó*Þ<·è\\ãç5Êð�|ÖWq×¹P%(±ªN>Ëò þ2_Ð8Ûu:tšë¼Wç]P�|ÔŒ[ã×pÃ’Ù•Ñ´1@½†ÐŽñ~¡•”ši>øùƒ¾S¾íß>tÝP|u<ïÏã]qï¸÷©/?¥”•¦gšTZ÷Öó-ùŸ>__ùƒ•M§›Ðu‰ç3 8þÜ`Þ“ˆÂâe0ç—eus}aã‚­lóÌy%‘ å:ønDs‘¥„•!œ*,ÛÍfs¡P˜››åH£¤¢(ެcøêaSÉtîíçV|o…{Ê}쟎EE­‹ÖŽÃW·ïo#4^-K °Ûí¢\Q²±,8_o „½‘“ër¹<°ùýþ`0(*qm"úçóùr¹,´eÉ ¢ú¯%;µ�� �IDAT™R’$KÁˆ|ßÁö3í.ÙeÉY¢'¢JU1ÚwFÍ ôŠrS$*ñ<E:4T»Œ®¯á­\©TD«S°ŒÉ–®ë¶‚mx×pp0h)Z±ã˨Πò’uþ¾D\mµZ-—Ë‚ÛgXc7‹I´R©IWÜK±X´Ùl¹\.•JU²X^¯wÓ»^fvå„qx^c:ÂõY¾&sµÄëõ ¸ÖÀ·Ðߣ•ÆÞyþ½hJ~\»æ³¤¶óã¾0Äuá§(÷ó—jµ¶_Ê?åÚùÏ*Îðý÷Xj;Ìèuª9œBÇЈF1ÉdëìÔ‰À‘wJüP"aÁ¢ÓVçÑ<Ïz¸Hâù�‘2Ëìô[è¨ò ‰^;²Ìá: &‰{–q¹…ZœVnHºû2[½ü¢—þ¶wË’¯å'­ô¥X5K8Ί"!7%ú3X¬ÌN±ÐŸÅ»@ÐIá(5‘2Ê].*J鈓XCÆA)NP£8¸âø•“7~©cñß?3íAÉ—:}õ¨mÿ¦ÑÅ­1¿eêß·[mk³S^Í`_¤—Œ“â mLÖ1¥ð×0§ñlj,gè$km”O³ÒBÍJ¥ˆ£òGUY­ŽY˜Ê`GÇ~BTÊØö±«™¹nÆ@ª`sRhaÎO¡7oš¶iÚ²xfhó‘QPM¨ÍÌÙ¨ˆ)×å<6¯µXެM^|j|y]9¹ªZ—sõÚYÖD)W°yÈu3^Åj¦ÞÅä<Íϳ~g› =ÍI¥ˆóA+æ2¦ <íÄj O²˜gU7¦E¬5’Q‚$Tl‹¸“ÔËø¸Š<½0¸ý‘ᦉú€’av˜éÏñ•P’p'r•çÜlѸ¥ˆ?ËJAåI•6´YÆQ#ÒÉ¥ Ìšy¾ÎýÐYåx•¢‰·ÕùŠÎVxn„A™wIä`ÁÍ'àË5~gÃÚɶ2ÅEþC£öA•I6?ÏÔ!I½Ta’0®1/á‡K5:d ýÄôB@ń䚈Ѻ®Ûíö"NUêøUGä¹H%R™¾|zç;g¶Íhºf_´g;³º®¯¸kEjmjæU3SWLå:r;îØÑóëτǤ˜Œ>›1-3¦8ÀñÆ�mH½”Áùá)¶9VŒ{ím¼/Qãm”Šh<²81"ßÔj5Ã1Ę|§‹‰$¶%¶|~‹{ܽ÷νkïZ;øöÁè3Q­¬-ö-Ž\5ÒùûNñè‚Á`0ìééñz½C/ô/ B´AÀ%™»Ñ®Wô¯„¬¢ÝnT*«Õ*ªÙ(ž"aˆœaÈè‰oþL6Ìf³Óé´ËöeCËŽßp¼µØê®¸ëÅúùuíù-MÑÓ3v9"©¿èàPü¡x× °b0ôûýG Bzžëyø#÷þ®× !§›Æ·‡Ñ¾6†v…øK Uˆå©1äÀŸFAà Y×uÉ$ͬžYÈ.äGóKüˆE‡³qvu~ºŠÁW —åI€['¯3ÀMvÎC“`ÀÏÁ Ü ­šcŒûÆùÖÇ"d¶hûv*ÇgtI¡ÖÅ«'pîç¶?|ã×A7µã²°²ÌcP’‰è¤à50TbÔÏþ,5˜•™ ÌeVR^5ÊÍ2}eêŒäÙ q´Æ|“:s ²GÅ_&­ñQK ¬ViW©¨·ß×~÷ŠŽ0«f7Ñ;N·Â˜™¯«àiÃÓŠfEM°à¡.ai!Q /ØÎa9u3‡g …œñSô„H÷0bBñ£K"°™Á:”g7ÅÒ]“!þŠýZÝsîôñ‹­%90쎌٭CÝÞE%LbˆåEmL‡HF‰Åˆ¨˜ˆ^Às«ô °8N—­t¨8a;%+U Õ<®& 8)qFYèe:C«—Ì2†}¤C$í”—1¬¢,]$e¡¡š„ƒ¢ŸÔYVØ)÷0–"`qŠŽ~ÎNÒ!£73WÂ'<Fϲ¡òîç«ëÎøGÏbµ` PvR¬anf>Çb _€ìÑ,¶~&=¨géV©9ÐfhÕo£6F[o'ó«3áž`¹Ë9;Q'®1¢Ó4eÑ£dtâfr}dcXMØ‹œ^W•N­Ö‹OÕ¨¨TJüº‰]5¶LSŒ²ÌM0EöÚØà%¤r¶†S"Y'Tå,´™);‘lÍp«NŽÛø€L¼JB§N'L:¹R¢[¦]c,Äh*a¯ãIÒY!ãfƒNZÃÎÚןæûQtyïÛ5“¹î‘x»‰·k(Fºšœœ<pà€±±5>Š‹¥.ÅÚbæi³ñ™oìVI’4þ¦qÍ¢uìíh9Ô"×äöÇÛÓËÓ=÷Œ_1žïÌ·ío[þÀòæçšÙ-±»J¨!,q™2ÒU¡P0š„1]Û‹•P%|2ÜH}ÑtµDñÈHW_XŒÖÖÜ0å[r:®¦3MÀܦ9¥¦„N„dUöŒ{€è¡¨nÖC#!/.¢³ªª™LFÜŽá-b$$÷à+ )Q‹Ep‘ÒA»µµÕï÷G"AÜjC"V¤(Gn¨Á  Á %CýA×u‡ìÆ‚CÛ†,9‹“ŒÇh€Î×нGqdÃgyɧ\. «Õêp8\.W0ìèèˆF£"õ¾@­•æ«öªÁ/B£vß_,¯ÏOW"9‰Y—±[2Ä…wp©T2p"‚Ÿ`Üõèe£S§F/u¹ † çÖéêüÙ• e(ƒö@8ág¼ïg|qŸÄ;dNÁ½pXàr°C…ÊÅ|^ÅÕnjÖw,"/ªÃOQ ²é[|uŸ¿.…åð$\WæIsVá" »„]AÏÀÊŠ9B°v…÷ÁÕP×ð¦ Ô¹?L›B+tú¹^á;&™ÓcAÞie‹‹¼Ì < %AÑOʤÁÞK¨ËÍEzä:rŽ*Ë5¤µ Œbžf4CQÆ7Os…Z¹›z”Ü/™mœ¨á¨pVA /ËGÐñ…±W°Æ {HŸ 'Bf'³×Õ—U§$GAõäJ¶ŽièâySÉráðBÓ3´¶1-²NïËgi)àŒ²`¡:OÓeΛâ„gi‰icÚD]AµQ,é I79+•*;¥4¾nÆZ™©cªa§kœ®Qzœš™›#p?¯+àœ£9‹GGX¤…j€E7¹Eel>Ò2š‡l'3´úIµ0Ûô7—Uçìû¿ sIõ0ñ*–<®!Vd…´  ғǹ‰“Q²¼²Ý8Æ ÚÑ%ä9fŽÒ«£t³¨rBŽÛ¨ô3 §óùÚªGÜ7ýÆcÛFÔ4¾é?\¢®zFo²ê\“å»i «Ð(ËÔgÙ<Dg•¯êì¨ó;g!m¢žp Úx-´¨Xó¨I†!pZâ> ,!"0/Ó OÔù Ä­|?Ë‘E6@w˜à,üÞKEæ= P¾ e›òÕH)‰ïÝá¿Iõ±$¼Ê™%[]Ñ  }㳪iZ6šxÏ@aKAˆ8í2£gÕ´·É1ïP-ê©·žªÛê@×£]Coò yúïé÷žñ¾òÁ˜Õjm¤5NÇ*¯pvbRL쥸J¯dPWoX¦—^ƼÄ^³«µ¦Õª¶ªÈçÞznù#âeW*•\.7==N§QˆÆðÉH“nÉàmI­E1 + Ùív»Ý.0î//^e4E¡&ÐqF×.œ ¯;µî̆3©@Êh|5ú¢ï,ÚhâiœÏŽh‘;ºÝn·{½Þ–––ß®ý­¿ÓßÜÜ X¿ooߨ%c’$ 5 »Ýn�‚^ªé÷ÿß2Ì–¼¥ë·]sÛ玾ÿhÝñr2ç#|ò0À}ðÐ`%l€c<ù)ý+ÿÆßÿ,p58à¥Þʽ­Üê+[Nóõ7Qü [ç¸ü_¼‰Ä3Ý*%‰y•ƒp-ì„ 85~¨s¡Loƒ˜B2ÌóÜ?¨“7q•™ÓV¬-ÌŽsi_ l+ é\ßBÓÛj.,el Be–‹Q¹Ìr T9gÆÜzýWÑí¥%ç`YgçG*_v!ûH›0k˜[ñžÃ!#{9·ŠÀ"¶ &?© Z¬ŒGˆMЩÑÓÊØ:öyÈô0û<[Z™Éàu‘ïfì+-”ꘒ¯ä©X:ÒtÏ…øà‰Õ£õ+²Ï~gÍ¥Ú.ýëq·2£!Ó%t$t35'!ãt‚uvJ6ÊmLI&-c8‹§)p“{?4Sûÿ| OºÈ[© °¦—‘­ÊãJ¬cò’©b™¦­ƒÉnÆLÔÍ”GI–±õ0'<OSÓ—òD ÿ)V9)´2eÁAQd»¡f‘ÏÑeaïãoÏ|íýß{úiVo`ê Û€ ð’  E?ÉAÚ×3™D/àT1{¨ÕIû‰ŸbMóœ2RÕ¬°x‚¤åeÌZ ð_ÍÞj°Ðxpû( UújüRç9¶tòvÍE6'yXgJb¥¬ ë»e6Ö8œäi•.áÁ)¾«q+D\'±[ÇÁlgûW•Ù øBš‹$Z–Ñî¦$:E½ÎUu6Â$<“åjø¼#ÆÏk¤aCùv‹öù{ô¿‹~ø®ü¿tx@g”]ï×JWÀ=KÖù:ªâG¾q_ò¢¤£äp»Œ)…ˆe&“É;â5ÍGÞ}dõý«-Y‹¢(Gß}´ã™ŽÀé�ŽW:ŸÎiD:—Ëeø»¿ŒtÂ+YáÓaÿ¨ÿÿ1B-é)½Œ>“˜«I’>¶æ­Gß{´ï®>UUÏÝv.t(ÔÖExƒ¼µD7Á@©çOÉð‘\].—×ëu»Ý~¿¿±ú4ø³¯Ð!WÔs¢&kä½YÏZsëszP·¥mKÔ_ùîaIº5nJ̺Ç›Ÿx°ÿÁÑÚè÷&¾W(TÏèûèÿ?‰Çÿ±³g8®%—È‚KÞ3F‘d`jÎ×»ªÕjKÑiÚ×$!åÛòvV½Õƒÿ|°f¯µ=ÝÖûà‹¨lœß ÌÀ¼ Fà,DþE¢¦ßzÌüé ´Òw¸ÙÃá7ت®(¶<‡>$Õùµ1õrà5Ì~ݼ៵ÛÄz(솳=:§t~¿‚ß™y³Æ÷ 3ÊŽ*– 7B«ÎúŒðF7ëc]–#+‹œÉòã A-È©ªD«Æ©_x XÒVy——M<n¼êvZVóÓ]kþvê›ßÓ¼¿Æu~*fjgirqU3ó´NÑqš© u3Ëm(ƒø<¸/`pšî.æÎÑŸå°•–iZ»˜#5ΞšêXX»žCÏ`jC™ŠVŽüà¹wÿ¬ã@[\ [ЦgØ%6PÚºñi·zlËðr©úñ/í|ÏÛM9Ç.öpJà!!¶H «†9Àb sÀYVdñzÉ4±0Iç16æðäð, ‘´Sª`-â¬`ó “P1MÒé##ÁVÑâ¦Ò̼ uŠŽ.ÆÃ$âD5L9žÇ#ÚÂÜ2F±5Fd„eJó<ÍNŠ:rSg/#5Ì#,sRô“Jã»2s ï8wóU‡««¶1¢¡ôsÎN)÷Qö¸Xèd>ÉYî(ç²´Ž2ÇŸ%h"5À;˜ï¢ÙK&ƒ»ê,]sD´(8;I%×ÚÙvFùêmùoÜ{òÕëgl‹L¶±+ðлr¿½IþöwÊŒªd5 ÚJKw½€}îYžÕ™‘Q›Ø™§5‰K¥j¦Å„K¡£ƒ=\dM >$‘–èÖñ«Ü{2,[àn;QÞ I¿†ïô·Í,WéVi†íy²[xÝ£|î>|±öÜ×Õ{ßÂõóÌ/XÛÂoÿµ8ÐyàAïƒÁ³A©¶4¬¢…¢¿¸ò¿Vžºõ”gÚP¨3Q ¹kîæ½Íö¤Ý\4Ÿü«“͇›#ƒ‘ÆÉÐêñeØFÚ¬Á®zâ×Ä<\$-ÑÚ؇%Å¢–zAÿ[Ñv.¤zR¾s>ƒxT©Tòù¼1«7vý/Õ ˆ†ÆÜiÄ2»ÝnsÚf·Ï>ûwÏZ¬—æÒu‰ŽfÍZ½¿÷Juiü†ñÀÑ@àh ±d­0MÓK€úã©¢42 3\ÃSQ DV³ÙlápXL€D=—H$b±X¥R)•J†fc ·\.‹ŸŠ3šÍfC/QÇ Û‰}IÇ@ÇÁ7 .Ý· ¨—ºdŒg”\KàKêÚFgH§Ó©”NÜ¡Ýñ„ù‰Gœ\W½N°¦ÇÕ¼:sÑLÓé¦mñ3°F-‘Ï/öž†"É’êÐxÎoW¢Õ5Ŧ Ü:`ÍZÏ"ˆ´þ¶µ-ýÐѱ«ÆJ——^_¹ñ¥gWvX¹À\ ü`ƒn)VzåÐão) (³g¸cÐ<UùšÌëLÁ`7Â1ôËÑÍîíæ/ñ7›ý-2ÇÀóð]0Ã{5ö‡ L˜x‡Ênh/q¢NA#$±²ÌB‘b™-uî×0A½‰55–›8æ l±RTqÂV ³Ê$H^ú“üÚÄ«Kä˨?³ÃY)}g<ü©¯…coIbW°µ0kG*P¡êØËTeú¬Xk$ôÒ9N•™.Rq¶e0w1¦ ›èPQ𙓠DÒK!‚}l™ÿÛ‡®ýâÊúßqú+_7uë šWßpºª0nÑG§v”goûõ ï|õ”Öe¦î&g£l¥' e§ä%ÛÅxk€”™šŽèH1"ÍÌ×°X¨µ3å%“Åë¤`¡j£#ZÀé%c¥ªbêb\G¶ ñyÉIƉt0¹@Ó0Ë@2¡>ÍEãt‹ãljäpÛ)åqq¶1#Œ¦¢ˆlj¡%VÂî!7M›Œ6C[§2Ú™ ¨>÷XϤm[ŽV e‘@*9üNò[À{ЧU.(àd´@w' 3•<oÚŒ¹I1‡;‚5#aÊÌQNÌîÿý»¼_»Š\R‹êõã¦5¥@0¿eÜÑ:æýåöØ$1Rãá2ËÜԪ쭠xÄÂN?[éÓ8ãâX…ÃË :RTSüNÖkŒÃÕB·—– ý:=&†`!MKUÆ!¬° ÌòBî–•õ/ ]Ž~;jõ§üç~»®4ÒÕÈâÈCՇʎ²oÚgÒLfáu[]Có {š÷5ÿÕ°%oq$*æ/pEUȇòéδÿ¬ß’²¼&B@Ô*•ŠÁ¡_ÏgûeÒÁÔt-Ù/1ø(†‹Ãׯ½w­u3ÚzbVoŒˆ T}#™TÜà6žåb«urËd¦#sÍ_“ìJž¼à¤,É…ö2–Œ(H…Ù×Ì:¦M‡›DÕr~X4žV7F,p 1¬/ñ_oLr†p<Ÿ››ü_+•J;Ó˜˜ù­†ö„‘ nÓŸôÎU½ëp×áWn9Ñbð Ì‚PÓÇ>ñ�_´[(°Ô  w.—ë`ßÁÓËO_¹påÍÙ›,²Ùì|f~¦oÆr{'½K$*jã›Í D/ùßÎ™Š·KÑçÞe5r¡ñ3ïôŒ{L%“}ÊŽŠ¤IîQwû¯ÛÛݾùôæÛ.|étå˜à†Ë¥[˜ÉAL\ðnýß~K!5N?GËhêÚ_³*«?ÿHs7àÂ2Ĺ÷)ßß]W.\"Ó,cÕÙg â¥Ç«kx!áXô±ºÄ+Ìàä\ ]GÑY®3y™/¸¹°ÂÑ‹:ƒÞPÆO4.RSiÖ™‘1ÃÁ[lØãL•9®°º…g%ò•Ý…š—Ò“ õVæ+h5ªSôg¨ù(™I›d+ä-Xª8mt‡˜Öˆª‚ú"¶Ñ�ÉLV°Åp†Èª˜bx7p"NTE©ôMú:sðO¹–ìþ?¬½w€de•þÿ¹÷VÎU]ÕÝÕ¹{bÏLOžafÈ Ñ€¨ˆ.ê.FLVpÝ5°â®î¢®(k�Ãb@QDr’a€É9ôtÎ]]9‡~¼ìµìfÑïïþÕSsëÖ­·ªÎóžsžó<3#çôÇ–`Hrõü—&ÂñÃQuà÷E?üÎ5éRš`€Œ“ò�K„b’†(Ó´—pÎÑ(r¬åœTÐ@J´SÕPÂÄC¤ÚO”Ñ}ä@ÒP¬Ôœ”óx”çhô“QÐú8l w3’ÅßDÌMa ‡J8â¸#¤Ht3&®a©akc²…i CÆègiÍÌü‰a²æ ¤¬³SieJÙ±šºÂ‡^Øž/ß+ØÛ©Q|dTOÑ:EÓ0íNôùAÞeCÊáˆ÷Â,;r¬÷P­áˆ3;E´ÆTÃŽKÅWBvRÉQJþý³ò;ï ’S÷ì°­‹ûÎ>–N¯±}ô‡ú­ß|æŸâ±€ƒ%Ç« û¸¹€»J4Ï ¤‰˜w•– YkœŒùœã \ 7)Ñ!á”Xkç9©<­“vò2«Tb2=ð@.Ѹ-Ï•¿<Ë ,?ƒ«ØñF®ý­àƒ~øôÖ» Ç÷ÅÇþc¬ÜRžÛ0×Ôßdö®N^yRuªÏvˆßjÓ@Óø¹ãñ•q{ÎnÏØE=ª^ófxý05"/EÌù'3Þ™$!`Fd®j³špUŸ¨™Z…&ƒY„¡yDµ‘7Œøû§ó(ì"3›‡  ÛZ¯5¤e>n·Û[Þ´wiiiΛ+” GÞv$˜ f[³³Ëg}“¾c׫´U–?°|¡p»©7QÙúw*òñG=çÂ\Ézô2%9ÌYàT*%„*L»g“YO¼—åDq“¢3ÄÎÀ¼mÓk8Ñ•Èú²žaOýÍÏ#¿˜«Y7>­)¢ÈWD£ÔjµNG§»‹Ý}Ã}rMÏ…r<”›Ìl;xlͱdWrÕ/W™>¦ã°9 gšY‹•õÌ…äy»œzøŸ·1WÞü×ç¸îYw±¹¨×tKÞbž)Ëò<fàªÅD7?ý¼qå+ôí�}ð}hþ;Šû¡zÀËoœìüªð�¼m|î0†x„ n‚q[4$ƒîF®ŽÞÏtY¹¼7ÈÈ0Vf,Ò¨hÔj¬1°Npj_©±Ú «TS•ÉÉDX5Šj=qwm¤¤² jz­x²¬ÝøSãâ°õîÿÐcÍí” t[±èä¤sY«øU,H)œ]ŒØ Çy"F%ÆE¬×),c¬‚=‡w˜%ÓD¡œÀ;Jça:|d—¿ìoýúý_xäð7ï^q$Ø3ëÿæü}©I>²"ÞÙ]þîc}-[«H«9ÔÁØ6†Hj(S´T±µ1aNLw3¬ `¹Ž,ˆ E\Ë9ÑHÌFõË[˜£cšè‘(ÓqÂFO+“Í̈Fš5ç$ˉY©q=ÃE­L†I+hsD’„&i “ΆŒ>È¢¥ôÐe -cÐK˜¢¥Ÿ¥)‚,§=Nx”®EŒÆÎ=¹"p`qez)–".ËÝ;Ù6ƒ·—áÅL$°NÒb™i´‹ŽYf⬮"!竊x3hnö4BUBJ±ÜÀªãOQÑ¸ÆøÑ¿Å×ë÷|´¸ú”ûKŸ_TåkVZˆ—”±øU^P$–7ÒÎ"‘sö2ÿg±Ìq®­q™Æ¤Ä5%ž-2©à4¸Ë`²€e‚ŒD/,S8WF‡¥2‰FƒãP…æÓÙ èW`lTøŒDž¯™‘5ðw‚hðؼR.—[ÿÔêó¾ö°xðèÕGû¯ìwÏýÙÊV°õ<Ùãó\8òòg^ž×®?³¨¶9{kÖúþZãÇÓrø‰ Š‘ àÄ '|#¾èsÑú3…jÆk žÖ[| KxA+!õ´½Ÿ³^9Kñ+^÷`µ§º¬¶ÌQtlxxC÷®nÿ¸ÿÈuG’[“Ë]¾PÔçÿQªCÔ`‡B`˜X„X,V(2™L6›]1‘Š›°dâ„ÈPEžašÓëºîp8@SSSsss$ ƒâ‰f¢9pþ€mÚVûËcž!ˆXjAÜ0UQêGwçÉôU«U±Ô‚~2<<\9QYôÒ¢Ý=»ŸØþ„û˜{ɃKþ†Îåë1åZøÑˆûƒwçýÌ­™Ë,Ê(e¥^øxaÌr‹áEÆ·7ñ­ÜöI¾çßbÜre.s«„[Á«2�o±>ùÞš=ÍŽ¼»‘ÜRž2tã_e×jï»1û“ò†l4˜…ïæùwøF‘ÂfhSy!‡M¦MgS;àÓ5*`©R‘pYº¸WæS>¥“©p¯BEã0¼[âqƒ _ª1—ÉiÏâIñpšt€&FÅrÈÕM}¤·ý/¯Å]“XGqº0ºHw1;Å-!îžÄo7èò’k!>G`�ïfN*(ð¦Én&Ó´ 1$ }˜Ö.&òøçh[ɨŸ|˜Ò~Ö]Às–½Ý‘ø¦>åàtW¥8d„9ï�ã‰ß,ïöÍyisN6ÈçsDÚ˜(âcUM̶05MTGÞÃÆ¥ô÷04EKš€ŒžÁo µ2¹ž}³4•qŒÒ¹„SFÛ$­ìn ‚ an„®NFã„C$_á,+µIù^ j#±4Á6fwÓ™Á?M´†ÕJ­ƒ±2Ž þîsNJëØ_ÅÖLª±¾I'% ªmjff†fûEúøómŸøLcÆc ]Às'YVÆ;Hè öÏÐ*#KT11KÔ \ Qc[ÜÌXѦ°Ûö³>Åùv”~^ðâbk0�� �IDATîeªŸÖ6ÞûÒO.È¿÷J‰Ë­8Ô_»å=–gã 5vZù„ÜëÁSÀ ª[#h¡ÃÍñ8$|HüÄ—t:4ìBÍXf™¶ó +–<m:»›¹zŠCpŽj„,´ù™A:4nP(h,ƒß‚7Å:xl�|†AÑYa±´©Û>bÜdü/;éýe…© ⾪ª‘]MÕ½ãRUúßпþÖõŽ~G‰’an·Ûb±xrÏOÓ`“êRw|nǹwœë²¹þÌ Î-ó„Ý^«Ó_ʼnР]WôSï<<lx¥¡žŸmf]ÿ狊:’ØÅ›‰ã¼ª ¨5x.ºÔávøŠ¾;6Ýqãc7fÈx'½–K`(°á± î˜7Â!lw®¡¡AŒ¬žv€ì´âôõé]½ð Ù–K$"ÇT‚R©$^Bü³V« {L§ÓùZ‹àr¹|>ßÚµk@2™Ìår{öì»—o~YR¥àñ p®oDÍËTDRb¾ S+Dô MœÅd]×Ëårû+íÇÞzl¿}ë`«¦iÕbµg §ñöQ;â{%˜)õeUÁƒ¯'°ümÿÓ™º^ø¯ØT´-öŒ]Gÿ«˜eø‘[ª_÷ã×·I‹Vتq z >kc±—¤¯ñ'*ïãd‘™Gù·_pe™É¨N?œbÜ0òGá7p;|ÛÆgŠ< Û,ì68KcœSå{A^¨qW|.‚§ þ]Â’C1¸ÐÆGªlÐÑ®”©êmesž1hLÝ‚íezö!©Øy)CCñ™ŽYþðO“ã-ÒÿgF ¢:ŸP¸%º‹"Ü6K£B°”›“U\ý4oã°“Òóœ})ÏDèòb7ì̾ô–dM½)ººyÚIÇN¶µðÈ2'h¦ã(«VŒžÐmmúùÏ2ÓЙßÊN=™uÍeû™¤YÈF¬æ‡ü6væñT°w06Gäž<Nï ÍT?™¬µSÙÄîNFç²V&«Øº‘ÑÅà”ðNÞqÂeìF€ô0Ý‹pSð“9LŸ`´¯æÐ –§úÉt0VÃÚÊd÷-n À"ÙÊã±SÙÚ¬ZÁÄ ‹Vpì+VpÌNåY.ŒÚFG:›7ÝvYß}V•©ºåŠ):²•êqÚ{H¤Qº8AÛÁFÉÅs¬}+Ïídk'±Q}x±ÚN¾“9ý#lSH=Í$ Zx«6¼K*oµr#¸TŽKµ³-'Ñù‰FÔàÞ*ßÍrÌ'Ã÷|ü“Ê×jÜ&“ÑÉ𨕡£ojæ=3$ ¾ qø&yÜàA7Ùx±Æ€®Yr.z*\mר„.…$×i×P°ø ~*ÑÀ¸…²Æ"ÝÂ+¼X{ì.û&üÄáãð Áý*wB÷BÁ@tšv7Õ¨é6ý¢·_¤ëºù›]W»&y«‘3Ê¡ò·Xùó•fOÂYpÖ*µÓŠ„š @s|õÏZæ ZVB²¯ž7`V_Ÿy•©(k£—ö_ßß÷ݾ¦]Mš¡‰gºÄš®Zó´Ã_g73ܺpµ[cŽ˜l‘ùpNΉ"ª/ás•\B6îµ&dÍvˆY73¥ÿÌ@o²BDùQt˜ÌÂi©Tw"Þ£Yñ{µ{÷¿¼ÿ×z›&%Ýä…‹ò Ûíöx<‚bV) á‚.éÛ?³ÝÌAÅG£ªêi³j]×…lîÂWœu¯V&ó%®” eIªªÚ v¹&WŒJý523ÖuëXê—×üÊ™ßO‡Ãá÷û%IJ¥Rfê/Μ§ŸbÖ«ÓËÒéeéuß]W•«õ—Zø%YWÈjì…%<pµqÃ=/C –ò‹+Êêp;¼­0 ;Ùùfr×’‰É\¥ó |K§¹á8~›|4¦˜Õx»«F­Är…*½)tèïÃá‰|Á £r\b«ÁfÓ)îÓ8G# Îp‡d©IÌí!(qJ¦’de½Ó¼â"šÅ*ýó¿}'¼[ÿ§ÈŸ\,—X›cn±j  qC’Fs2ªøÞÜÏrá ŽÙÈü‰s-h ¢L'IþoŒ [)4=›'žfï. 2{ˆ•½ô¯cÿI:ä‰nõf¯Úó¦·|r/‹“± 6‘éaj)ý'Xî¢8L·†RÆñ—w3ÜĬХ„³ŠmÇÂÄÓg£ZÆ1MtÇ ¸/áIáì œ$´ž}9¼Â¢wš¨(îu1ÒHÌOÆ‚ÚÊd SsD¦‰–pj(iÃtIp§:(OÑÒÎø$­üF³»Ø|…‰—pÓ½–£Âkx)ý‹LÔPT,EäÉV#uÕóç¼åÆgˆ.£ÔÇáö*Ê,«(¢â#ìÃÄ©âÈcó¡Ype) ÑãâØŸPBœ7!ãAu¢žâ`ö!f!ìeUañTþÁË<]NÎIð¬L‡­V¼n«á)Ò*Q•yc“KòáLð²ÄL€'“ØþÍ (q£DME‡müXgh–µðE?ï*±$BËIû Ü[æ;ð_Ã;¡×h샄…;ý<6Çû%®Ó¸É`ÎÊ%~6Íòø¡.—˜…¬AÂ0QÿC*5—ЋЮi׫ªÞÇ-™•™‰‹&D,p¹}'}@KK‹ø}ŠŠÓÒG—Ú¦þÜ•©ø*¶´­ñXãßì˜göfæyý™ÔAs+mÖ¯LNDÑ^<ü‘Ã=÷´¼Ò‚üçØ!žb¶Ð̨çp8Lé‡úØgòÜÌöXýsëKF¦½ìÏWüüœ—ϱªVçfçæµªŽ†aÌÍÍÕ¿¨€R1:-4)æ[&ùÂl±¼N³(“7!¶ æ{y˜˜Êd—Ë%T\½^¯¨(šg}ëÑž{ô‚¾á"y-®|=Ýqá:Ô@{÷y+ÙJ,ÓÐfi÷oζÝn·9c ¾…¥?‘C¿Îú¡øŒ„®•˜J4³öÙ ³Óg–¸í€¿ãʾq/]q£4þ–Æ2·ý»nŸÌÛ%~ OB†«S.”ŒÄÀÆ•g³E~[8a Î1ð»°ðtÀŒÊX ¯À4AV¢Cæz°ƒnà†´DSœïÁy÷Xx“…ë,,“³Si™¬Ÿ¸Œf#ædZ£„§(}àg:>¸„±Ì)Z¯“D+1™¸•—ò8 ÔJ˜dªLµO'ùîvÆ[˜:›C^¦7±;ÈÌ…fBK˜vQtw‘™¢{o/âZƉŽîV´Ñgß÷hä'oÊã9‡ýVôE J*–l3|d×pÐO¦‰0q e‚¶Ve1±ÛÏR „3Dòv¸(¾ÄÖqÚ4ôrð‘•0DçI8ù¶3¾½æ*Ø=äË8D†"© µ3ž&$¸(Z©E˜sQ\ÉÑS,ie²“QYy#{º.àž¥IøF–qøÉaÕVµ0¤ #‹ïKi°`¯a=²$+œ4Ɖ¶Qœä¥4Fš34ö0•$]¢¥ }„Ð ‰‰4ÃÍ$'ñÑ~Œž 7buQkg:.z­¾7ÿø#+×Ä*'T+óKÃU¢+-h¯HDt‡¸{ —i‡“–6Þ›à~eYƒ+V¸tFân…LA-Îsc„#ø‹«1„YèU¸P"¯§`\eï>¸V" WÀÑ2ߥ’ À¿ÃoÀsðB!Þëý‹}_o&uNJ–eÝ¢}ïÑØe1#bÔ‚µj š^‘ž½xV4ä].—˜õƒ×4'%%»4𦊭ò7Ç1£*þª'NmšÊ6f•’Òùxçë¬ÿ ›g&)6ûBîÖ¬2Íó`¬Ÿ„-‹ù|~—m—7åuÅ]…B¡ÞîÄLXEÛÃTP­ïvˆCU˜³À¢ä(± "ÝFÀ¢w%¨fcéÿ¯£R©x<žl6›Éd …Â<,Ÿ7Ÿ$zc¦ë‡Ù2zuàÓª¤‹¬×4½Œ]K·¤Å>À©¿ÈÂæÂŬï$™w"øõ€ Eóìõ›¾æ7ðì©lwvðªÁ3fWËÇùæxþ,žîä™nªÇe~õ¿p×Ýú Xk@½3|– .¦\Ò?W02#‹¹ü׬Pø>zñÞ<Ÿ„ JŸVYW£åe•ßÁ?Âð+X  TX!á‡oÁ»$vÈܪQ„o¬¦z€èd —yHÎ2èP”(ƒ6éÄË身œ½ý¼õ ¾cº”½ënë %(61•#Ó†`3jU’EÅê ¸š£“´4"OòB†¬ ‘O ©Œ5áëcð«tô6¦Gè± ¦p®eÿm³4µ2¹ˆA?™ºâoý·Åÿòƒv^c³›ÙUÀí¤”" m£ =È¢¦’„,¨ÍÌH2úRú›˜-à¶SI´S‰2aÎGVœÃ+,êݬÔ2øC$SK8WsÈ‚j£*2ªvÆÃÄeô)Z’„¬Ô*Ø1˜ AAKБۘ8ª&f#Ìe𧆈í¤ï<ö«XDëyÎOØÈži¢k90Àâ8aßЗ~¾ìË×NÐÖÅˆÈ u$…ÚJަ BŒj(êq*M$ï`±“•~Ú2”»•u†ÆùC+Ö’}”ó „|ddôÙ¯ýB¹õ¶Î2F™ƒC ‹BMãSeŒRáš"1‰h‰r™ÅŒuXÊ$â(Y¾eð2’Ä![† ÷U¸Ö†ùVšï—X¯óÓŸÖ˜Ò°¸Q|&fðŒ—+\®ñÀb<Ët~}°ÃÂÍ*2|‘û’¤WÂ+à§Q¾y€orÞiì±Ċ„¤IÝìV¦ï¨WÔ—’ë’Ç>}¬iSt<ªišPÇ‘ey÷ßï>ï;ç¹÷¿ºÝãþæGšCý!þzb°r0ƒ¯Ø ŠókeB]TlíçVÍͽuÎ=ãî|¢óÀÇ4îklÜ×øÿKøR~õU»…Œüƒ´ÙÊÃ弚ÒæfeOÄzÁ¶0ë`õæ“õÑÓéú® —›ä@³ág¡™ ÔƒÈKŽZ A91ó-Sß¶R©Äãñæææþþþp8lº¥�3[f<“Ï„gÞ¤s=)ôµ“Û"rÙ×:mrÕ¤3ë …Î »±ðµê9œ ?£×JÎDb$ª¦ù|ÞüˆëžÄꉵ:™º®ë6}àâå,7{œªªŽ­+„ m¿k½w”Ñ3ÀÕPŽ÷gIw— vèì‡+¸òïyæ.ÈÀcgÅñ¡4Ðá¢P1bÿ@Ó~žúŽüØ%җߪåpk‰‹a0Ë=:%ØRãöWYø’D|Xá­9Ci P¹ÕÂMeƒ7© ‚ ÿuŒë C¡Yç¸Æ\]&'3®áªñX­œÕ@!ާö«7­ýãìõkß½Ãú_ªß¾Õ`¦ÂôK"(2.Ϋà¥A'9Àx€¡q°²uŒ™¤Ÿ–I6Uˆ$[cc#ÇUVÉLË(#t…HN" ºA#3»9·‰ff„_F÷ÁßÿË›¯¼ÑÁ¸‚ezƒctLÒÚÊd/Ç­Ô´Á0ñff¤{²SÙͦG¹b;Op‡H&hhf&L¼“Ñi¢ARæ’„H4(à§}Š¥Q:#ÌIÒÙÎxœp7Ã#t ¦V7…6&$ŒÞ ö$!¡x)OŒÒÙÌL³‚ô¡¡¬æØ~Ö$hhcÂMáˤ[˜ò‘UІèIа’£CôÌ® ìëö0=Jg ë,‡ºˆeð·1±“e*k9¨Q› ç`ÍY–"=Ž]ÁSÅ(aÓqì¥EGVq´qužÅ-YúCLÁ 6áŠ÷–iˆ²mWöYÆjì°òéÏxz„_«|± ãì5èµá©±'E_žË ~§âRø¼Œ£Æ~Kt…ð–¹EÇw¦¸@'®•9²>#±·Ì]*gATá&¸Æ„³Fù±Ä)TU¶‚†4î‚ÛémáaÕ?@Ug;®+¸çnùˆ<¢Ôÿ¸›_inžlŒ‡Âö„½~¾2p$ÐòX‹­Çf±š„®’\Jt$6žÚ˜µdß48vÁØ–»¶('þ&œ9evàE±ë´ŸzÏY–§ÎŸrÆg=xÖŽ¯ì¶KíO·çü¹K‹ª^ULw¹L-±y7ÛWf•lž´„ $ ÂÄ]Õjµ±Ž±¸3¾õù­Â1K\A¼´ ?æˆU½nÈ™‹¢~¿ßÔ^2¹�¦n¬8ÇìÇÌ«:šÚ² íçM‰?“ó]ëuSØû æzµZM§ÓÕj5ÊYÒKÞ‚ô\aQXßf3ù#&ÜŠº™{4çy¶  ¡‚¥jqš¤½Nîƒx9³s¶p>áõ´$ëAÝ̶ëGë½45´lKÖ7æ30$IB&Ù—L÷¤»ïëVÊÊÆ[6òá3ÀUÕÁDà)„kàEx€˜Ÿ#í¬lVŽ~J¡©Æ“–ÞϪ—ÿëÂðGžzHéûªh ;Œ|\å%‰ó5ÞÀg �Ï«l€—à:ÍQ9¢YþÛÂ{Uîƒ{T–)ü O™OרÁG*8\tFHÆi/ðßU.‘ØÙˆfaÑ4wk(E¢EžÓxˆLOM´Zþý ûƒm3kóFYçd©(s¼eÓ,–9ýQ‚.–‡ðUèŠau“qSqÓ§ùÁ^榑Âưq½À–圪b­Rñ’–ÑwpžêZ¼ÄVAR8‹W‚SÎà´]!’e"×qQìdt–&ù Z—³3‚z„US´¬gß/¹ff®ççBjOÈ5+á<ª(ÓY³ž}­L–pîac„¹,¾ Ò –,aº•Iy ª˜£™–½=Å’åœd‘—\ŒÆ$¡­¼t€µAR{Ù°•—‚¤N²Ì@rSXϾÝl ’±RsR*à.àö‘uQœ¡9HÊC²€^ÄwÉÚo<{ â¤TÄÖËÑýtn$hgpšueK‰Ÿ œ!6MFGm¦k–ƒ¬qºl¨ /h´)ª´—±z™J3cY…­xtŽø±—Ká~k3Ñ!¼2’†¦òbŒýv®Ñ™4°ÀE2ÍŸÔÙ¡R3¨Øx¥•à÷x¹9C¯ƒm,=äIC^‘éšå¢ÂIìE.ѸÞ qøØ®ò8|Zã2ƒÅ2Z "ð´ÄãðއÃOY ÜdåÉ¿„ÝÂUð;Ø(}t‡ñû!Ëx0HÓ\}ˆ¬(}÷öY,–l6[ÔÿBšO®Éž1O¾3ŸÒRzâÕøÌÏl¹{ 0µuJWôíŸÜn³ÙŠ–b½4N}”œ'©0¯ë.*fpî½bîÇ´6¯+õ¸¢ÚUI“œ ç…»0ßš¯ŽÏJ—$Éív‹³ˆ¤"k4ñ´ÒS§Ý›ùB¨^–e»fåBvÕž.¥![Há P4ïV@£)�¸PdOâ‡éìr¹„’)bâÁ¼PnóL} qÍzØ0‹“§}ƒ¦®R­V;zôh}“N§+Ίª¨ö”}›¢¯EK1EåM>Å<0‡y…ˆ†¡"]˜‡™Dóqa&Dͽ~“1OTeÞš2 ¯‡+3/ü³™–®år9qº_Ü6Øõ³.Aj·¥lg*JtK|Zç›plP‚¯@?x¸uߺE{ËM°*jòýŒt²a)iþ¸ÊŠâ%WzõY’Ä3>ƒQ™«t>%qŸÌ¥>´"Q;ÿ“åìIAn5Ø)óÏ1°+ü,̉$ÝY~gÐ"³^e2ŽÛJ&Ê—æÈ\:C¹•¬…/i<n¥&±9ÄõÓ¼QGn"XûÇ üèêAì`aOkR4•p5’ÎÓæxBí½~JmLLáÖP}$Z!Oc‡LnW7ÌʴzHœ`ñ›Ù£qŠ–mì”0FéÌá½gŸ]ݰçœ]+¿øŽ±r§ŸÌrNà¡«‰Y+5å'ضï¥Ì�¨fhž¥©‘Ø,M ZŒF;71%ø{«9d§²‹ÍëØ&n¥ÖÆÄRŠÛØ3EK‡h8MÑÒH,E°“Ñ v-I¨ˆKÌ71kA݈ ì¥i‚6 j¯‹bÛ,M ËNEˆ¶ ZPE ³Œ#M 2µ¹Ÿý÷6mÿZÛ, ´Jœò! âô0nÁæ%¶”ñi†½°’ä!.; ï�ŽÞ@qp#Y ·Jrÿ*N@ϲ§‚'F €ÕàÃ#tä¯ÂL8ç°\lá 7“5z$†sx´ëä‹DbÔ¼ôIÄÓØ |¢„Ub®Ì.ÉS,‚—N¯FÀ`h†_¸¹~ ›!ø¶MíqH£Uçßàv8 ¡_âfƒßà Ücå&…pïø¹¦Äô^.g­ÆÄ)¨Á%ð¢ôõ^©Ž§çîÉÁ²×¹ ¾=¶ùXck£sÄ)~Àáá©S–YK1R Äin·[dõ:7&8Í‹&æ™ü¥]ˆÃá%SbÕT\­<Y–E¨2 Ã0jîÚ‘4ïj®§`ˆ“EqÌn0Ë8 Ez^«ÇnJ(‰p)€gèü!oÕ{þ¡ó‹öb=ãÌz²§mÚ™X,¿ßߨØ(¬4E4ÓÒEÐÓÍBV½²øÂ`ýªšLÂúÄ L¬ªùvTUwƳžìÊÝ+祀"gýoücµZU%Ut Í»ª÷­_x˜ôÑÓŽ!›Is=‚ŠÛ£Ób2ì´zN"Ñ4E.ÌnrËdtgÔÄ09-w½Ðuô棽wö:GœóSóš’Äï ~Ûá=ÐvˆÃsèaš{i¨'—B’œ›FS\uŒu©éÍæà9h†p™Á'VJ$­¸:¹8ƒÇE¤Šf¡EÅXí³òN‚—ªÁ¢*ûÒÜW%S }³<$´Ó`á{6hƒW øC,-Sª¢×¸ ¶d­O=÷iÙ5^õJµgޏ gÕ6Œµïy³AcØÌ&qv@–Á žWY¼œ½Y:–1ZÅ“$�¶±dFÙ2Žq›èßÇ;jg g˜„mŒ]I×01²¬râߊy]ÍO¬qäî0‰�™IZghvS,ã¨a ÜÄ´m=ûrøÊ8t‹ƒJ3³ARi‚Ä<仯WÀ]6j%\6ªmLX©Ù¨éÈvª:ŠZ†@33Ì•qNÓ’"˜Çë!ßÂt„¸ˆ*ŠUG–02dŒ(3Ät”á$¡©Qºz9QÆ©¡äðð”pÎÒl Ó½‚¡<íƒ×¿’[ëܹ¡¤Ûg‰¬`ÐFC[ž° o’Y kšÇ–°½‰°o¿Dm„Ñ$§äšxc´åñڨƪàÎ_yİè³iœÛLÜ<N²V rî ¼Ò©âÕH4à+2Q¢VeÔ«aÈ kФóUm9ô*»@‚õ:) A[ˆf•¨AÁ`H¡Iâ9-Q;Gk“V.öpJç¨Á2Wi|2 o„# ¬/Ñeð[èRh7X¥"i¼ ÊE¶ònÏUSz¤É üÐfð4ÉÃ|û(9{þžñ…^0âê­=ÄVÚcx¦6O……´ª¦ªªç”g÷ûw7ìm˜Ü:¹ô·KͲ’ëmÅVפþ›Éúx` óˆ¹QÁ×2¥Dl^ËG0ž8“K“ö„}ô²Ñ–—ZüÃþôÊ´sÆé¬8Í—6 ˆÅEÌ´°·!/8æi/‰¢“Óé<tÁ¡.yáÂÜ…-¹MÓŠÅ¢i.%T M 6e5^kÚÉd¯…Ïç ƒÁ`0 ù|>AØZ5Í\A„Qñ.^UJÔuífB&¼9LåóÍk^5íQÄ¢å¥üÐC-/·8bŽúE½°ì<ù"S¾Äž0G­ÍîÝÐuCM'›ÌiMÓ¤²”Z’²'ìJJ; •M/´ú—³Z­§µqY˜›*")c^«Î@ݬ-0?øÙƒëþs™VjšfTŒäÊäìy³ácáÄ»o^ýšªeYxX-¼€<O=‹ãvÎ: ÓðC Ÿç©·á°ó‡w3½jÐo‡ …ká˰AçB 5Σw'8\Áš%£3nð#x FjLé<QäóC0.1 Óap¾ÎÒƒ³Kü&ɃçÀuPj¦«o]ç,(Ù>‚ÜðûMÆ›ŸM¯ž+Î.µÎ^›´ÅÅÓV1ÃÄó¼'N¬‹Œ“j•eçáòÔ ÔÁó‘4К°,§?Â\ «Še€Ö"®$YœX«bÍá­am¡i Ùr°´çþ¯wLÕ®ü̹]³%e j×qzË8¢L‹4«€»†¯‰*¶ÖKyb)ý!’ÒctìgÝÓlOŠ0'ü;ÄSÄl²˜ ŠÑøgpêÈ‚F˜Çã#ë#[Ã:Lw k„¹Iñ*CôœdY’P gw˜øj5‹0§ ÷òî)Z‚¤Y1ÊôÖÎÒ”&',ÌDz9¾½oæá ´M^0°hGs[m¦†ÃCõ%¶61[Åá¥f¥¶š¹Nò!6Z©dÍËl ’vB³¶Òž`uÊ�…<­‚:SOwÞÅ/HÔj ÍÁ ž³ü¾™7¿ÆÕ@¯D_ž[=xšpزDe\eªfú˜uñ÷9öÀuTƒÿ–)Lx:逕ÖIB«Ž²˜%QzjÔª|n²ði O™b g•Ûk B?¬Ô™Z˶2/Àç Guî·òI…ó î‚Âϵw—Wü@ºÎnø#8¡àAøÐ\qš=© zÕ›ý˜ŠG™Å3¹r®P( …|>¿ìöe'Þybù¯—Ï›>©W‡øÛý¿ÐÇø3�� �IDAT‡Ýn¯—•[¸e»fó‰&}n!cP×ué„T´Ë åÙͳͻš}#¾J RñŸiËï÷ûC¡ßï7-çë'—ëz{CÓ·BQ”½gï}ñÒ?±ïÛâÛ¢€?­P‚¸Â<å¡Ó²´­V«’ "ÐH8·´´´µµE£Ñ`0èñxÌ2陓6¡tîõzEÞö×:nT*Õª¦{Ò '^ÿÔm½ûŒ)ZXŸúô¡SWŸ:ù®“æhšæsWÕR¨T/€b^m᪠äúmÐÂã´‰—pøTeaUöÌÇÉ÷ž\ö“ù GÜÑûý^¥¤cî¹3Ï]ëá·°F¢)è!Üûem¤¯…·ÿ‰ß¼Sb’¹o“Ï3ò^Ê%¸Mæ>.•ÿ‚7CÁ ~¢óÑ"Ý *Þ<¸Óà˰ÎÒHË8Sø¬Ä…ÐÛ†uлܩfÆÒ,3¶ÒÙBl€u j2SLæ°ãpN‚ïk8<úiÑŒáÏhwmå›”ß,]w—Ĭ… '3yvÛèÖ9r˜lfV!q˜–Ž¡&b\ÇY|Œ¦fÚHºéÎãéfh ýRòƆ†¯£2Mtï?9ïÍ•½M¥ìRö>ÎeMÌêÈB¦VGNÐÐÏRA^OÐPÄq”•+9j =ÈÛ6³ËO&‡·—ã»Ù”&ÐÄl’˜Ð²QuS˜#RÁ¾Œ“íŒÍÐ<£•ÉÙ³õ}žU*å§Ù¾ž}Ê+8VÁ¾Ÿu팷2©¡9Œ8áÎΆACÂðÏâ¥s;OdMT’ŠåK.æ©g¸¨~èžÌž‹²{¯+3å#»žÏqA„™9"6’IZ޳uŠ€Ô0Ê „w±¹™Ñá+ßÊ¡ý¬;Ä úuì}y™Ë‰ì üäÍÚÏÝ÷kv_×ÍŸ) Îüè?Kž9.¿=É ÞeL 2Qd:Ïnh…ïÀ'Y£)Ž]£M ×)Uz–1×Ïš"ŽÃ‚·û0J)Ô~\£ ßÖIA·„]çU®Sø¾ÎÅð9¸F ‚‡ ªØà]àÉÀZã p_ ;3ܯÛªÚ¤dóð.ø´Â$øá³Ößž[{¬ùu¯˜1wË?oyé+/mýôV±÷ô{*ΊwÒûZ|Œê­ëqD 1ÔétŠÁLJÌzšiù*’›ÍV_zòz½¢xe/Ú}ðЖ/oT§Úû³^kÞZOú¨·4‡fD‘P\y¡\áiÉ âRÛnÇÇîøØ¦¾M.·KðLä0{Wâ-˜(kòý꓌ú‰Ù·3»ýÏD`®a="Šî‹°Úª—·Ë.Òµh4êñxfffŠÅb¡P8mJa®ªxfLUÕŸÛyîWÎ}-õ‡ymÂ3ðšGnqîüëÎ/l)<ñŸO¬¸EèT(Ñ’8xÓÁE÷.²¿bÏjÙ…ƒnÿ'=çÌ:o$ü´jõ].³­e~€R=Öv»Ý²,Çb1Ã0|yßYwœµÿcû/þ—‹ù‡3Á•æàl¨q>ä`;„a\Oí~ŒSlêá‰h-÷>™ïñõÇtFáWð;G%VH|ÝàŸ ] -:_RèPùFšKý´X8®òU‰>X¡2Ãíða?Ü5ÃÕ.VµÒ2Å‹SXZˆÆðNQ+#—‰G°Ç '(Ó,±_¡g@c»…|4^Hv¿”å‰lmëG-ï»3òM:Q™£4½‡<Âñ9rÃ,_Âä1,v äûYº•“1<$}Œã#i^^ÌÊ© ¶9\*= |PcQ„9;ùæÍEŽ…{Ó´9"ý,]Ή$!½D‚†-¼¼ƒs\û8œÁ_Ä–C¹„]ж±3M M@€M A²ÐP‘½ŒC¦[FB‚-L­á`û-Q¦eôqÚ½ä ¤Î$¡—ÙÒÍp/Ǥ{9®#§Ú¨ÞÏ;6²§—ãÊ ‹„uV³ÍÌÄhô_Á±$¡îÞ­¼4F‡ÀÎE {í c«úÊ üdH<Àeoá™ßc ±¯‡shi¼^epøÉÔ°Æhnf&A`„™4.•Tûú9¯Äo .ð!§ËGzZº¬O_~Α|<èeéM·Ùó›ª8*'!ʧªDã4@'|®JcŒI°(¬“8ä‘4Í*:–“”Û¥O!íãÉ2­Yî<âÎi~Ÿmð®7ËtBÈÏ÷Kܯr£ÂceúàN•}P–ù{‰•:aƒsàÇOOã7h†Aöïã÷x?Z.ýðÙJ"�ß’¹nÔIÕôs(\×þy¯*ÏmœóœôØ3¯™rþ±•­Õ@5³(ã<î­  ·l0œÆiGA=O=\-”Ç®h¢w-ƉêÏÕ›…„½úçZ­ÖÞûzWüzPõVG/õù÷5šp%˲Çãy†°¬pR,Óét:/tïGUUEÂ'I’»Õ]õWý3~%§TÊ IT/ÍúÛ<¹ QEè¸PlI<b®•«Ìo‘슛˜$F꼞ÉVÌf’*Vu¡{ýiÙƒ¢Ðg†êP-e õªµõt•y)¯Y$4gŸMãສ˜¡'uÏãžó_8ð݃£ÛG ŒÅ¿]ÜöX›®ëñE2aøµÀ¯~TÏ(1ë·&cEhPá01Í Sýr­ÿîúýÞ/='µŽµŠ Øô¸Q*JÏÃ=¶Ü©Dó¬öÈÒà„V®´²ªHl‡VpòòCÜy÷næe‰™Í:1�Ž*(:ŠANA›Æa¥Ê>x¼èÄ(qTáC:q‰l›ÎM2Î<:™A©À̓8à 'g±ëœ0ÌÌP’‡ó * ë]L•yÖ¨ìÄÝA¨ÊÙÆeOë?¸%¸â?Ǩ)8ÜX%Æv²Ú†/Ba {Œ\”xÃ3G©h4ÅñX¨XðÉèíìëd±› Ute )JLÆn Žâ»ˆÝ5¬Y\Oßþ§+¯»N"á%7F‡¬P¡íb$E°•ÉYšrx=䋸¤%üç±/g'¼Éè!’ $FèŠ0'€gÇX¬ §wÇòåñ×Ä�é"®4V&ÇiÏâ ’RЦh�é ¼„SÒ“´Ö°ŠÎY33oæá"®8á9":²àß§ŽÐU¹„SÒ8í›Ù%aL9Y‚†�é|gòˆ¿)úÒâ8¡Ff Xx—s$L³†í|Ôƒ\4‡=B }1NJY,jK9|ˆi…¶ &%BUƒ÷éàç_«ÈNJ.²V¢Slñœ¸X~ƒ¿À�4Ëll¡2 Ï©ä&Ùkç‚"Ysrm†½àv±L§¤rKŠ!™)‰•ßNÒåfc‰ñ2á]¾ª+²5F§DTâ8à 2eG’4*,6¸-‹ §Y!°è¼*251ðÁƒ´Ã×à‹<þÕ´=Çœ|óCó:߀ëaœ3ï—”X•’†"û"]è’s²¦iB[a^hkÚßtòÚ“«>¿Jü¶MH«Gó¶á¢õ*«JÓDÇ]Ø0¨E1\Uߢ˜§§'"²ÈjÖÚñ¿;®T•yCWf÷Ëçó+V‹EMÓr¹œˆJ•Iqº)nN¯yjMšôñãÇEEËŠ~›Uë'xêç‘Ͳ˜ˆwõ“Ifí´Þoɼ¦a™LÆlç˜bµõåÊzh7 ÃápgŠ7ûZòõ$Q‡œ½`¶}gû<QA³fû:%¦üüBb‹ªª½¿îµZ­¢FWÒKóZGõœ{$ó覊£X ¡Tbk›ß(s¡ê“H±˜7¡5Lh&Äâš«°zø†a[Øæé÷d“IäŽ8Ž;ΨjQ«±n—qé+` u.…¢ A…gz8ÐÃíß⫨Tà‘ÿ­Ÿ¼]£Ýàú‹a Í´xh†ïÁ´Ìå^–(¼Ï _Âê%R!ÐNÑŽfFcÀ`¤›ŒŒ®ó@„¼);w»Ijøèrâk¢¦3eà0¸#K\�ºÂu:©IÜ:³ÚÕ×~òζJ§Â2°d±aˆEEœS ôW°eÐŽÒ=À’ŠãtE¨´2§bé`ìµµð’Ëã m$×ʤL&HÕI)L<uý³ÒÃWY³.¡+Ê}b¸ª€;M�¢§›aË0Ýy<iÓDGé<ªÍ̬âˆÐ÷ÛÇú".‘™‰b` k#1 j”é�i/¹�éÁÆFèrSÈàï`Ì‚ê!o£ÚHLŒIH‹Ê^—¸‚Ž'œÃ+dàc4ŽÑ!£ëÈ,¥³…);Ý@š#2B×0Ýb¾x–¦úâ¡®ÐþÞ]MJÃô¼Ì¦¾9"5¬ RèÓ‹èa¨‚u?K'i=Ϊeœ˜ÂïÁU"à¢ä—`•É+Ôª8=äb¸:—9¢rg’˜Žj'Û„–Æ¢s¸ˆ]å) 7k¤4Ktj? Ge:a•ŠÎÈ$áf–Â{`…[ Þ£b\¦ñy I¡‚'áƒn<ž‚›aJ# BP#££åñºQ` ÎÔà ÎÓ·K“¹QçBØWC lâ÷™†]‹äýÄÀ[àA"ïç/§„ƒ'‚«îZ<<ùî“g=+[™_’?ñùÙÙ3ìÐ MØÕ‹í­›\SJà´òó::Bè½ZwT*•…]UU‹J1¾<y""N ÓCÒãñx<mápØï÷{<aœ!zi‚ïpæÈ«Y´ÑsF—ï\.l§¦¦¦¦¦‰D:áû ^çÍ~¯ÝM7!MÔH͵íŸb±˜Ëå´¿<êµ\™ÿU©Tr¹\:N&“ét:—Ë™YàÿY=ý‘KFºŸì®W¦¨ßš§d± …œÇ_Û(:m‚» ¨ëºxü´â˜7o®•�æzÙõy#æ!SQŽÖu]ªI½õÆZcÃK†EóL`Þø%ã­Ï¶Úâgήâ~x®ñ¹_‘ÞÅ®ªäT~#:|Zf£Ä*íó¿"x‰µõ’Ú¾Orgθç­ð%‰¶r‘Ê>gø!Ü ™ÛªDàÇ2=2þ(»ÓDK|n,2­±:Æ?Wñ'ø¤A§Á‹³ôÊ´©|½‰«| ÌóU¶\VC*ñ›R8ö,ÑyC#^ïd³×ÂÙ5*Úu{‡W/¾ûŠa5ÜMv˜°Á~¡.J<w”)ƒµV.ÞÌ¡c¬ “¶à\Çs»¡Ï,jœèe¨B:ö«ÏæÅs´µ2¹œ± ŒgYÓJi|Ó«Ö å'%ùõì;ɲIZ-¨2z”iaÿ1L·“R³4=Ç>²çñ' %ƒ¿™ %DrˆÙ0ñ ìuRz’K ¸Ïçù6&–ÒŸÁ' xÈw1â¤ÔÁ˜§]Å ]ÂùGÞÐÇá(ÓUl>²ûXï¢&î#ë!£q’Ö,¾6&Örà0}E\eNJ6ª»Ù´”þ#¬ZÉQÅ=lìåøï¹ÒG¶‹‘"®Ãljãg$sx×r°ƒ€ŒŠÝM&‹k(8Ç/áÜÎË#DöaoD/♦ÝGäÿ#í¼ãä*¯»ÿ½ezŸÝÙÞµZ­zG‰"Šà‚1„7N°c\cÀŽc;NÜbb¿î•¸aìØ¸Œ©¦ ¨÷²Ò6mÝÙÙéýν÷ýãQ®'»‚Ï{ÿàƒ¤Ù™gž{÷œçœó+mÐÉìºÄúÈË”¤÷3o @Òh´ñ‘©6î*c«£ÐCò† Ü*Ÿ–ZÝêG>Ûu×{§©O°q”÷¸øaI¨âÍPÑù7ø½ÄGºQ稳Q,0™«’ÒØ Á^“oIƒþb&½adÖÌñ4|=Çá¿TøÁ¸É&H@˜6vVù Ì:/Ãn‰jWGÉÀÕÙ?½hN~:á2ø>ü®Õ»cj|½F¾aÖå;çÔ¼zìžcë¾¶N„6¡ì`Å)Ö¿ãk;2™Ì¹çFV\q÷¯_¬£÷«åE³J¨×•XÀ »(‡Ã±ÿï÷¯ý—µî)w•ªÕ×’N"! Ü5Éh1«ƒ$âšHVÖ±ôÅßëN=Þü<PÑ*º®çr9Á”2 CôÄí,oûZN®UÍX¾”–s`í<Æãñˆ¥ŠÐiùnär¹b±(þ(ø¼¢°³TØ­Ç«Xù_Á%j‡OÖ;XêÅuÉõ,èØŠ“„¸_¢`_Ð*ž¬OÑ4mä¯FÚ´ùÇüµ%i¥R©m?Z­ã¶Š¯çuç.ÁbàÏÆXu¦ÚòhKÕ¬ÆR1A”$)ÑŸh}¼µ)ÕTÛ¶XÌ» )óë«ößH>»I�¾ x³Éç°½ÓXòouóöü@ÚÏ–¯£ï†ûà!•Ž ¿ƒ_Ã>GT–U-3¬³þÕÉòNÞu’Æ,^7?j$‘b}ŠŸ¯ 0 nžd>_á+¾åÙ£È*ïƒ?l+Ó£Ò«ñe“#Ýv®Óqh¸NÐè S6©&ɘ;~"]4Ÿ¿ûO É‹¹šsAL‰ƒ/rƒ‡wÛ9k'PGÑÄ¡ãP©Ná®Ç^ÁP©n`ð,fŽÖy¤“Tsœ{™‹6p,HªŒÚIRÅ´SuQtßsÇ‘Ç?~ÍñèáØµE\rC/C›Ùï¦Çã!_Eme*D²‰6&;Ëâ›#â'ÓL´ŒCT?ÀNž°¡íeKTÔ†û8ÅŠ]\ÞÍ膅 È4-a2Fu€~!uá ì¦p?ˆÒ¼‡­ë9œÁ_O¼„S°<äû1¼äЏdŒ‹y%FƒJuœZœúNÆ”‡Y"cØ©xÉ]ßìT*Ø÷+ëNÔ9cÛÇX½‚Q•ª‡BtšPû$]a´AB­¨K>ŲîŒ50²õ~˜¦”ã¶1þÕÅ7Ρù1ÊTÊÌI¼É™y"ÿáIøì?ú2Z¶…éë‡ùþ�~HÊl•ð‚O›®Ø>òÙ1Æ‹ô,c¶À÷óLèœl¤;ANåýe>¥p›Â?Ü‘ã')tH©$á;&?–ðØøGs:Ñ*-w626OK•Ü<[àLÀ‡a‡É×$ð‰ÛM¾wÃ[á“{4NCn4¹q†’L³D¤Òþv~õnÖØ $QobNs#ÜpÁßOï”7ß–_ (‡Êš[Ûu×.Ãn`²þ7ë[~ׂ›4‹úcI i‹È)XDŒì¯ÑžZ¬Èn¡ÄÿìþçÝ¿µÑ™uVœç¢ßï·Ùlõõõ.—«««Ëãñ„B!1ÀH§ÓÉdRÌ®4Ms»ÝÐ!Ü7¬þ’Åû±âš¬É›Üôò_¿¼é‡›D_ÐÏ\ Ù¨µC¬=»Ýn¡(2–%{!DÐ-U±XŒÇã~’ËåæççK¥R2™‚~Åb1‹Õ¶Ýj—dU«Vï±V.¤Ö ò‚ ƒ’¿dÏÙeC*« øz„èdYƒ¹\®Z­zç¼»¿¿{ë§¶Ú3vKMÊDXGœî»6ÇK±'µz]'"ZŽ¢•œ¨¨¬çS”Ú´d±hm˱ö°µà)­(•‘kF¤œÔù‡ÎÅêò¯Å»*s?¦yDi~§ẏž…M�Wv°ÝÃû~Ê+>°œïÍñ«Oa˜˜m2!“zƒaJx$Þd"lK~íXRÅ®±1Îo‹œ’ÈélL1Zä‰J‚Œï<š¼A¢ nÍsÀFF&ÑÂYSø´:/šÁŒÉÅvÔ0{+(÷{©+4xÐsÙ©ÂæÍîtódGßa»mž°êHŒÑr’ﺹ¹‡Êè«ÈŸÃßɼ›bˆÒ +|„”ò؈d&I–ÁAoSj_û0½íLÏSU—YÌuϺ[ÛOù‹¸@²Qm!ªR­c^H˜KPÄUEÒ²œÓgéSÐ ”zâ3451›"TÄ墣ÑA9‹=‡Y$=MË4­ÇYSG¢ASGzHa’ ™È2† (:Ê,MJ¯JÓ´ê¨2¦‚£¡ˆ;LÒEI‚N Lä¾8‘«yz’v#M@ ›‰,¡L䙈mæ ?pßñåŒô2ZÅv‚ÞÃôºÑ½²ØÂë)¥ñu0QA£pŽÎö >Ö:Yçä‡E–]‚SÇ¡4==<âTÍÉ•Ê Ã†Ã4ëh£/MÒíãî7XfÒiòˆ“é*/éæåUÜÝì>Ç3°3Éaƒ¯æi‚ÆVÖ&±óbMy”<K”%ž¨òá&uÿÙÄl•FQ&$Èq§A„6Ø v™wyo!ƒ¯ÊØÞaà‡L¤_ž<ov8 ¹ÐœôW~ÿ †"<Ô _…ý¦}%õýì¾¶–wõòË/‹3`¦'ãL: çù¸1£ë¢ÑK¢ÓOoýüÖžG{ºŸèvŽ;µ²¶xzañ®,±p+òŠ&ÞÅjéà ¢¿h^ÕÖ%¢3#qÙSžÝ4›jIUœ•º}ufÉS7AT²ÙlÁ`0‰øýþ@  ªj¡P¨V«Âi×2¢µf?ü— “Ö->Óù¢ÇIº5펹mYÛù™YÍ%ÒÞâo'ZgäÏÂûY @ ±-z’¢€°ôâÍK¥R&“Òº¢•*Ú}µÖºš¦Y]ÖZz …oÑ¡Äë-Àwí¤GôÐN¾ýdçîÎàtpñ¿±þK±ÞRˆ·2b-ÊÎút‘ùº^éš[9—ïÊW]U[Φ–T«;g¥R]×%SªÕ ²ÀŠüw»¯Z‚”%±heë­Å¾¶– %¼T{f²žÒtoúôm§;^ìÄ–X)\ÒÂZG¢cãEv^LÖá0GºÍ{É£³äÝàâÍGš¶(y3ÊGœpùx¯Á ƒU0 _Í%~ ™’Âå&ªBÙd¬D—É™;Êô‚)1`†fð'79$ãvX"Sl!™â;K,1 WÈì°adøEM%Bòy†uª2o÷·%s÷<àÜQ,vy½C› ¨ÏÐcãA'-^ðÒÃ^â’�Î •”‡†2'š›Tû8å^â|€®áÌã]Éx‰ãuD«´ƒœ!॒Ç$í¦x†Þ6&"»V§¯9³4æ?ÚÝ@ÌDªc~?Åh˜#ÒÆ” ÞúÈæñfñåðE˜›¥ÑE±„+ƒ¿I;¹ Žñ&f½ät½“±Æ×q´‰™NJ2y<NJ9|r§‚î ,‚‘Åo"·1夬`q/aDG)ãÌH*ã(âò“)ᚤ­žù1º„¾F˜äúM¤ þs1½ädŒ$áS¬ˆ~à?;vw4khfFÆœ¦u‰œBb£t6’´“›ÃßF,DéËÂÄ$ ^ì KTmÚ0£ôÇxÆdªÌ¶ »ŠHÎ;}¿y[ÇåÌ/û¹ãÊ+¼¥žüän™;ëˆçÑ ÍÃÑ2ÓëœÒÌ73`Ì’7™„~“Æ”€ñ†½ÇM–HÌxY¥s¹AR&Qƒ˜Ê6Î2/Â$Ì›á D:1 „ÝøóüTeîÕyî¿Dž#Ð/ƒÁ_>Â-GÙñ’¶£RÞñÆæBŸø]ûµ‹w–9 e%ÿEs÷8\f¥«ñññ={ö(Š¢ 8³Îñã-[t]×ìÚØ[ÇŠžbûþöeO.C?/|`…¸� 'Ä)¬€"ÔçjÏί']-–1µ„ò¦.ŸšÙ>“^–Ö‚Z9Pî|¬Ó‘<oÞ!B×ØØØÜܼ|ùòæææÆÆFÇ#Œá'''EúB>pY¼ƒÀ†œD¥R­"»3ïtäc¹çÜö¼ÝZ¼ØZp :/Z—–Ì …žø3Cö¿¼¦«WˆNU*!˜+W˜H$ …‚Õˆ¿L&“µ££×hÍYk¨M`–)‰Ø|‘™EIv' õ…†S ö¼}qefsV‰#¢¼¨ÀÄ2jÕëEÓÕz6LÓl¥Ý•pÅúcÉÞdby"r:R›T,VµX³(zÄÇYB´ABÜ;K¥ÞÚX+Ç[Íÿ1]Y�«ßh³Ùô:ýÌ[ÎÌ­˜›_=?¿z>ßœï|¦³é@Sí‚Cá#wY~hù¦M—YéꂃÐqxÒ*¬2Î ãô¯/~ëZ³ðìÔxÑ`;Ü>_˜‹*Ü >™30g€Â ÂYHéDdÞ¯‘„I…ë![æÓU>ÒÀÍE’Y~ç 8 ÇMNg釛‹|&Ä=Þdps•‘ ½´¥8­£Áã&M&Ç$çê™O}J~ÒUäJ^ìTæ.ñQUyl–x‰+ëi 1>‡?CDÅcéÁëA:A°™¬Œ9ÀŠœž£¹„)€à&îuŒìfe…H±4Ž(‘Í~ù"6JDÓ ¼ô§[_úÅwûتRíg ˆKÂleê0ë“„¢4WQ}d ¸Ïѵ”Á(ÍNJ€›B“*U?'¥!zË8,O8õÊ£t—qz¯h!Nѧ¾—¡ )ÉGv–Æf¢&’‹bo÷,~2%œn *UÅM0‘²øN³|-G3øsx…˜aÜɘ°ºïúq‚U㟾¿ð®‡:;L៥ñJž}…‹eð3Z@~™Ëb„âtÖ1+áΠ¿Žjù öƒ8e¾t×ãN±r ¯N¸ŽzÛ]÷Mmh}Û׊ؒ$¡˜ùæ‡Âá-óW”ø¹6” –P¡N¦hW¹¶Ê¿¸IbK‘+¢Äez`5Œ€ NËD‹,5ø'•;«Ü_ÅPh‚‘ «4¼î’ø¹ÁN…;aÚEo`=Ͼ*ož£^áRQ£ðKp_B6Ù ³.Ö¨oÏeërôZ¸ÎÀ_ðâTòtTÙŸ€q“ÓP·8%X(,I–TU-•JgÞ}¦ùùæ†3 ò ¬ˆ�� �IDAT.—Ëf·‰ßçZ9¥ L%ι¡Gô‚¬øbµhD7LeñéÜU;:ªmp‰×DwD5·æõÛsö¦¦ó5çqÕ"lY(;1$¨ ëŠÅ¢¿¼^¯Õú¡üÕ™ˆƒá±ððöá\CÎó,Ro(†ðb%µXA±u–UÒk$4…²ƒ•ö„·½ÁÀÒê[ÖšÙ[Á·T* žuí±ÀJ'–­°ˆÎ–±a¦1³ÿ=û»^èªý‚¯¶!â.ƈ[°‘êJÒ¾÷íkÚÝÔº«UÜMÇ cÙð²Ä²D%P±¦bTù«µ ÏžUBYG ƒn}S«äÏÀâMÄtÐjZ‡ ñƒšS«Ÿª·d=eOý‰zk0ek€£·}mš°n…A˜l²¯œ$Êî ;I·ÿ#‰*¬ƒkJ¸[i›â?ázŠÓ:[mÜ`0 6!•f?—6²ÉM®DägŠ Àê𤸲À&“|’_ì…›]lw0Çn §Ðàbxc–¬ÎßšàG*uQ–ƒ:™·IÌê,“+aÛ>hl}¶îó·dµCë8;Fï7õ26M}šk§)LBo†WÊ´µ2å$TÀÕÆ´Ží,+ÓœõÒâ¢à¦(âøJÆÃ$4:R4†Hï¥ßÍáÝüUTVp.FÓ&Û+¿ýýwÝ9{„Ø$í'XµžÃ›8a®‰™yê<äK8 ¸…Èú K»8§£ŒÓÑÃH˜„,=¶ó’¥*;Dïv^ª`É/‡W ½üdú8k {Éíã";•Mhc2‹Ï@ö÷Š7\Ê‹v*1ÒYê ¼ŠIBqê™uRyËIi-GãÔŸbÅ=±oˆ¶'¸Ô‡ÑÊÔ†²Š+ÿ±oæ?ô««¯ý‡¦01¹Ÿ7/eÌI¹€zŒž£´çx©™ž ¹ÞÝl“0×pì Ë|d‹ÈK¸ÁN1Ov‚FI’xƒûÚÝ_¾%ûñ‹g_|òâuŸ¼}˜øŒk»¾a`ä¿x{tèo!™æZ‰K% é¼G¦WÆYå•yv®EâŒñÛ% VMò‰Š‰îÖ8ý&ö"ƒpÀÆ%iöš|.VX®qc•?Â|Æt‹3fœ“ðø„Á Ùx«Æ¿Á1Xmà7q²2_þíT(ð­kÉ_ WÁ(L€œg#Ö)ÃßÁ?)¬5xÍH$aÊ&ÐòXËÔÍS g^¯‡Õ\0Kàn1A§W›Ä/ ÎX-¶"‡#'ÿædÓ&gÜ©z- Èòùc§l6+Ü›ÄX(ŸÏ'“Ét:mÙgˆZJTVÇ2›Í¾J۔̱‹ÆF·Œ6ímZ¬Ýn¥=ñãÕjµVÓöõ`D]ðé‚ð+€ÖtpH«&´vÒjÌ. ÉÖšeˆdIJ«ÕjÊL=÷ÑçBC¡®º¬Ž®ÕU{+nY>Ÿ7MSô9…\ä‚d £:ÕýÙ_ñTV~gåÌ%3Ï|ý™5_Xãžv+²2ùæÉñ«Æ•ŠÒv¨í…’HÎZáGQqÖ¾&—Ë)Šâ÷û­º±4p-éB(IþÙ1Ò&Ë.ùÉw?‰É¶¯lK&“ü§¢nñ7~qcCs·½Vº*À8øtNîù ©í1)µÖ6»O[ÚmoÇØ!ñM“S€/ÁïeÞo`3¹]c+쇰Äó&ËxŒ�“x>±9b 6Ó4ƒlðƒ{à®Gr< A‰ ±1¢±«Êm÷KÜ¢ðÙîÎТ±µÂ]xô¦™®³<¶Û.Nî~«öµ÷î;Ñ¡P‡ìÙËæ4¢±¹™š¢XÄ•$´”Ä<u»¸\Âìãl„ЪŸBqAÑ ‘‚kº™[ÂÈ^¶.Ã?k9zŠò½ÍíûúÝWúßøU=V÷ ’Np)ƒÏ°£CB“b9§±F¬cþ.n&ºŠ¶NÆB$O²r ÇôCl‚ šåaO°³ž¸€íÈ6ày®èeH”_Âõq‚öv&æ©›¡Ià®åè�ýÛØm Ÿf¹ƒ²Ju†&•ª›Âín :JóB¬=çZž|†«tú6ŽŒÑÙ@ìžu#ïþÉŽQÛ­áïâò0‰eœÉâ{ŒMm$8MŸ| ³•%vN$é©`OSjA?ÉJ]G¹ŠãOpÕqæà[&ž7<ñøÏ~áþä=Ñ·ÈÚêo&¯-Äv¿KÂ'½òêŸJ„$—‰7R™â m<³–[PŒñ'¦‹º$ûº1r™‡#lÓi›ÀP¨úxržS° ¾-áP¸útæ*ÈA6º82CIã š¬„Kà³ìeÒ C>*ñ“—à€Ä*“a˜•Y'a×ÙÏ 7|Äø}ë‚g  ¦à,8 UÈAÆàn·ÃÝÔün‰0tþ÷¶¬ÆVdž¯îx¨#˜ N«Óf«iΛ"\Šè`¡0jåDÇF€„Eè¤Õ…ºàâÇNg$ñù|BÞbnn®P(,¶Nÿs´ÊØ×~cíþÚ/WåÞßö:ãN[¶ ÑS4Íþ[hG‰i“u0‡h‚EÃÊr˜Çエkå�Õ¡ŽnõÅnúÀMÖp~ÁL^LÚpC|Š5\q¹\"{ 0ä‚)—¨\E·Ðª_­8+2º5²j‘Š,‘Å5„ÀÁ[¤]q’°TðëêêÜnwgg§8%L:'¼üÇþ·ggg3ÅŒ¤H °-â9±H² ð#‹ëõj¸zàýrm¹+?r¥RQ¯øÃнwïÍ7åîǺwܹ(ëeñXN.¯¦>,Jçp8ìv»ãñ¸UÙ\P®wA¡f=‡ �&Ö&[r—ñj|캱ًg¯ùá5î¨;[Ê.ÞU‘¾Ã4MלË-»_[âÖ'ÁË£!Þ?ªœ­3†õ¾Ð¬ÿøwFþeéø¥v“ |VCÅÄfÒy¨À·BôÈl×xÚ$/Q”h„*Ÿ5xZvÊÔ«|²Ä4¬‘!f0*ó—&G6HL¹Ñ¬ò#“m ïsÐVÅ=ƒNÁ'T./š‚žï_—¿î¹ó9³’² _é¢)E¨ùS„«„ʸ=TRÈeüCtd÷s&D*HÚD^͈„3IÈ@)ãHŒá·#Eq)ÈÆ‰,epŽH33£ôt01óÙïE=þ-.Y]öRêal‡R×� ÄJ8 xòx3êH”p(NJ34ÉíL(èEÜ]Œ ÑŠ9"eœ^r Æ‘.ÆTª>²ÍÌÄh®‰eœ~²ãt”qpw2–Ã+cÖ”Œé¡ ¢kØfh®àÈáuQLtPiaÚGNA/ã¬c¾ž¸‡¼‰|Œ5nŠk8&cبÎSŸT}Gßs¼;kküÙµ'Y ]ÀýÛfip“—±gTy~×fŽ—éI£•°gqä Ø8+1“ ?‡š%ä"`}å†g‡nšåWoÒ¿}g•A¢Ö20¿¿Ñöý»åû¯wr_72i±1[Ä–å¢*2My–”9Q$/±©„ +*œM²Gg…NªBµÄf‰ˆLX¦Þà€ÄaÄàI…MveÙªÐ`âYbò+P æö‡%f$ž¯ÊGLQ¸öé<+s½‚]]³¯zݽ¼e77~‚gƒVx üz  |ð&xÚà%8¸R°Íš]MLLìÙ³ç|DH;l%[¼?^?Xïιíû‰¿> ÛsvÈ®m— u;1¹)§£££¥¥% ¹\®B¡ l[­©€€b×òi¼^¯Ûínkkkmmí©Zv°…t¨í4Š·êx¹#0¾i¸ØXtO¹Õ¢Z7…N®ë855Çs¹œÿ”J%!¥#dú¼^o8ka]L­ìBLJl6›fמ½ûÙÞzƒç‚ÿ#{É4²ÚV"%ˆiå«B²¤W+•Ц.nâ_­t%2‡ØyAV?R«ád Ƭ™¥¯!d>Âá°¸e¡Ph80üJÿ+;ŸÛéÔ¢rZ —hén­EÑnw³%aíL)T»fLwêþ}ƒPKWËî–Î';»žê ŒjS‹ØgayÁÁ’Å”'‘Ú–ò‚°RñpZÃ0QL[[gewù3_Í^ø?æ_÷À:GÞañ«¬[YKÇ®¬z½ÞÍ—\þP ÊÐ #8÷™Ÿ;Ìh¹|æa£ð6þù4ß–Læa«B¿ÉN4;·k Á¬Ä:™U^6UøŠN+´*ôšœï¡FLBón5H*ÌÂKUðF“aøšICˆlšægí¬ÌÑfâÖñˆ”%€˜‚‘Üü&'œ¤³<fì¾Y}æí¬ÞSjÄÃþqžÈñ†‡œd|ÈNÔ]^¢Áv…¼¢Ž:E0O ‡Ô@ºŒ£0p)I©>òÓD’xCdUª&…ƒ[Æ=­s«>wS]LñP§í$Ý>J&?N;š“r´Œ m§rË‘:Ê: tP®¢ ísù þæòxtTá¦h£ª ›HõÄÏÐßÈŒY ’Œá¡&á¤$A¿‰ÔÀœ“Òn¶52 øÈ–qöq6ƒ_ˆ<U±qiØ„r owRV©ÚÐ*8üdç©ÏâÛÿ±ç·FÇ+?[3„܈3E¨‚½Ša¦“„ƒòrNÏsQ¥BHF5PÆp9Ñ—0ã!d°Eut™¡e”MR¹ÍyóKo1_¾H¦¤pE–ÇLžup±ˆAν>­ÐØjò§0[ýx}ì™âÙN<ddÎI\桳À' J*ï´3UE1(Kh2ƒÓÏI¬–© €SFU9äB/s̤Mæ)“zˆ*´æy8„V!¢ð“¬A¯˜øà³òQåæcUe”oÔQ8 ËA…!膇a¬‡2ŒA=ôÁåpÀ›/˜®�I—&/L­Južê´Um3«fM Ž-\–5ª=M×ÕÕ577·¶¶ %V—ËǶ¶µ Ð{<ap …ÚÛÛëêêÊå²Õ™©Ëò$ñB@à\.—œ–›ö4¡ æU5ÞÄ*>DÁ$Â�,ˆ~ ëbx#Žê"]ù|>Q4ˆ– °ç8ϸÒuàĵ'Úv·u¿Ø}AãÚåÅk¤+a[µ�þ.^&þµí&f{bͨO4îDÉeÅY‹‡$0ŠbñJB4�-Œ¢Ãáʹ‘H¤¯¯/ÖÛÛ°÷ÖÜ­Á\PUUQàZïS{Ë,%áú!Е‹!Ý6›ÍÍÑ÷XŸœ’Å0o±ñ±U¬ˆL,°‹åNįZ­úý~»Ý ½^¯¸Ë¢ _|z¨Õ°¨UÄ¿`f­½†ß>ìóÖ¿X/08VY).ëìeUo¯–®£†4ˆÂ/Açßæ»W°Ã«øÅ4Ê2Kdì&mŸ3ù"TÀe"™œNÐPä6K ¢óœÌJ‰ûÀ9¬†Ï«Ø Ü:.sUŽBD=tûø¬ÊÕ\ScžÖ—˜„$ƒ¿Ph2ÉB\ærƒU^RO’dŽ£Užî´Ÿ0þöñ÷=e™Ä›K4Dè+°Tƹ”A»A؆¬#g D‰Ö“t µ1=NoŒéHR®àËâ_ËQ?™ ¥fKØ¢øU¤st ÓÇY}XIûZÆU'¥"®2Þ5 …IÎicRÃ6NÇIVŽÓ1F§Ž"躻¸|?›M$aã›$41ã%§£˜H¦J¯h –qäñ<ÇŽÆ… »‰$xÁn B&cŽÈ8À8 Œũ¸¾FfghrQŒÑPÀ- 2!¨a«'î#+ÐÊ6´ýl£sìÓ÷Çîþü/Þ]¥ÃNSÔ,öÆ»™±#7š¼N ƒæy ú‘* àö£§pçi“w3ÕÁL™ÙÉ?¬²éÚ§LF«LÌ6ñŽvnpZ㥠e;·–¨ÖaH`mo†ƒ’6RàÓä¤Á¾$†N'5ðdiÑðÀQ‰ßA*pÂÏ™|¶è|­ÊJÆ®÷²Bð+lÐW"jЩó9¨¨ØáÛðü F ¥-ùNÑö¤ò•÷Hñ+an‚•¿”øÜ#ÐaÂ2h„ |®•xDeóÇÎç5ËÇîÛiÌTÔŠkÎÕx²QLø…D…¥’nI´Y�@ ü/€ˆþ¯Ÿ j·Û}>ŸßïGøÅb¬µ2²^¯×âxæZsÇ?t\óh‹ ¬1F*•ŠÇãçΛ››K§Ó"ú;‘¨<O8®««óûýâä.x¬ ´PG·Žv¼ÔqAa‘B„”¢¸„E…õG·ÛmaÛCøjgNèNœ ,v°v¡«VÁ¯VËü,þDÆòù|¡P([—½+t—ÏéÛÜ(N~¿ßb,ÖÃM&“‰DBŒ‹,s–ÂfÀÞ9Ü<Ð,¾²å˵˜Ï+Òžøš¢a[Ëä0ÔZ•wMÓ2™L2™ŒÇãBòñ‚Î/µˆGKÑøõ<‡±‹c¯4þÿ›xÉ‹æÁ~•4ÁµTè…:ø"¼ƒw"ߟ“ø ƒƒ1¹«Ì Æw—òp+|Ðä':O™< “´IÂ`½ÉlÜæäT€˜Êòfì3d + ó2Ü iq°ÅEëI¤Ÿö³®Â· ë HüBá½:ç &LVjœháø4"{ >Aêt;ÍphâRŒ°çÁ¯ØX½Œ–¢Ë™ëc²Já�ë%žéa&̳øƒ“d™íS´Wpä{1YÑÉ-ËÈ÷1~?Û‡f§â¢x˜• ,#ÚÅÄ Neô’l&{’GY»—-*Õ% (<ÅE6*%œ>². ¶a–ØÐlhÒ´w0þ ¾ÐÏÀ MŒ‹ä§>MÀAyž:ëŒÝ<žFf¤Ý战H³4:) auã,}§Y42« IÙ©p·1™Ã ³$HJè$bƒÐ®­c^à8òx\mh(„£ ¸g×O_÷Æäqmbf-)ÅÕŒ—pVqÈHsDfi¢×@ÞÀ`¦ƒr+{`*MÃ>–¨¨¬š¤+w�û5ç@jÙ©¥Ùο6Ò!ѦsfŽ"Wû˜Ôøl‚˔ʄ§Ð«<IDŠJž[ÒèÜíd<ÚÂM ƒ'ml‘p ™Zq[â6‰H l:e“q•¿“ˆK¼IbC™Âç ‚«<ìõñ¼Î#&=%&Šÿn¢ëð× [eÖÂw5ž’Ÿú’R¸]¿Ño²ædSpêœ0¹:`<à¬ÁsÐ!¸¾nrµNb1ÄËçóY09ß”ÏskN èy¾'ߟOv'-H÷;¨ZȲq ˜µBäóyÁvº A‘Õ­ÊçóÑhTÈ¥Ói!*ŽÕ ÂBû®¢U4Ÿ6yåäÐ-CuØŠ¶Zfîý+è[€ïZܹˆÚ"ÅŠ¡ÏXÂqç­FdIˆ9-Ap¹\G 6Ä%”Ÿ„ ø ÚyÉÙÄ"Šª4(öS\ù|^�,¦Ö_QHxˆ•Ô‚å`ÁétVÕ¥êÒ+½P¡˜uÁ\%*ÝÚŒøjŽ$eo¹ÔQŠD"Á`Pìêk,-x„|œ¸Sµ.S–6UmÛPºÐe‘ Äw*V&³µd�¥¨à¥ölñßþUQĤÓÚ¨ZÇœ×BšU.—˜T(W)A/„)x˜©•=tïgt$ƒ ¼Ãèp7\´3§3­Sÿ¹^Å[%câ*°¡L®Ÿ÷1[eNæ%…¿Õ2¹r&ç)Ú‘4†*Ü“ã�œ†-P­ç¯hƒ¨N6—xÁÎà<o²MÙTÙþUéº[¿Þõ¦ïå’ ¢T;J•â² óþÔÌ;–Ò6€_§šç‡6vÔ1³Œc¯Öøtœƒ]x}ÆE¬OÓ?ŠÖÌÄ s-Ylã„—1u5O¿Âòq½ŒôÐ$u˜õ]œËàÿkþ8Gd‚ö ©ç—{ºÆÕ¥ùÁq:L¤&f¤G虥qg„O°*ÂÜR“„*؃¤ÎÑ5MË N…Iœº<.Å4ÿé Sà í $UEMÈà6Ä­L¥ÚÐæˆ¤®æxÔ4-^rr3ÑšÚ˜,õ2éÀL¥{¥Ü—³ë×üE Ó%œNJqê[™˜ê.K3M“ã1’„Fè1ƒ¤š‰:)‰aM•BœyÅM:IH§þb:‡Ç±ORv@—L›ÆwÆßûS®<x•í äM:rô9HMó—n(cé)’¨ Ix6èÜãæN$cS<ý_ÏQ’ù­ÁR™„ùBœ²ÎèI‰§üØm8Uú$d•Ë5þ^Çaòk‰ŠÁ™%U&UVÉ øàðvXmÒZÅ Û!kò¬D  ê%þÚÉ}ÕÒw±S´ý Ï_ÿ;Ó$k2ÿ�·Â;á½:S*ÿX=O7þ1¤á:“ÿ„k/Ho¨_Ã0¶eû“_~rçGwÊÙ=ëÎwäÃaQÜX.«µ#ñr¹,ÊÁu-—Ëétz¦Ãâ lʹıZȈkDd̳uÙT eªæØ;Æö7\õ®«ÄéåÏÀ¼`0(4~,ª–Ð}¾õB]¼RÌi²Ù¬ªª©TJ¤Ñt:¹\Î*=%$«Å÷jÞ‹Ç-"ÆYÅò¤X¼3ÁL¾!ßï²Ul¢pÿµÆHÖv .Ѽß-3^ `bâU(¦¤©åÅå6ÍV6ʹ\.—Ë]ÐŽk–±¥vÚu­ªÅÓw?}ëçouŠ¢ˆ¶j­öî4©Yl×bu2­BY &­1Òë­udÙçóYt wºøÐ°â +ôðæÏm~ ‡”Å2+^^j1$sÌà_p%¹ñ�G%NÙ�rYÆÖÑ÷8g›\ØØ*,•ûœ¼ËÆ¥/¼ÍËûÊ”LLršDó„u¶CÚ¤NÅa²Jb‹É1™ç$Z|¨e^‚-2“°Lá"k+ü¶º]¶È¨6ª¥w}UùÞWIÎÿa™üéwI¥V w;åYÚJøíÈNÂvŠ9¶¹Õ£©8l ØØƒ9Aou™<]Û˜š¤9‡<Oý ­k9VÁa£rŠ.«99L8ÈÔfξÌú.ê†1§=›ß{É:NŒÓ)cäð*~²QZ¢§Oÿø[캢#VÞÊ^Õ“¬\Ê \‰ÔÄl‚ºñ4A;•*ê=NJ}œ•0ghzß¹§ÆÃž5¿[ZÆiG«à°QÕ°qÒ!ÞÄL‹Rˆäíóƒ7×#EP¥ª`dðÏÒ´›ŠC&,0¼ßÌ~©Ž aŸ¡¹ŒsŒÖý}æÒç\öƒKÛI9)»((BŠ)Lâizâç)·b£?K‡‚k=GgirQŠSŽŸ©\ÖHÅÅh¼ÉÓMmöÜÖÁоíLø}´i$ $ìnÆãì®c¥ƒF3ºNc…´ &-&]v•è…)`Ra½IÜ`9lÈiLÙ JüÈÁ' ¦øŠÌÅUZÜÈ0í`¥NIæsQ“ìA³Á‰¨Ä “«„8< >X OKüv˜d6yc–GÌcO³²Àä•Rv—ÌN˜2ÑÀp <u‚ÎÂ6‚ëa;,±fWúÀ /„Š!1‘]¾©MSjQhš>žß0ß<Ù,çÉ+•JmßFô‰T'Ê—b±(TŽþ, q¡ø"†š¦ÍÍÍMNNNOO‹f]>Ÿ3a².„Õív{©½tô=G3+3„X÷¥uáÓáW£|ZyKØT¨…X­¥\'ÒC:âLB8Õ0 ‚eÍÉËO®Øµ¢–\ë2¸c°,‡çÖµ£…€°&RÖˆ«–`$®Ã—~ìÿ<¶êø*WÖeMMî@|–•¢,Ê­…yn•;‡CØ`ÖÊ2Õ¶Å,–Ø¿­û·¯N}5—ËåóùÉÉÉÑÑÑ™™¡1ÿzòE³tŒ&7N:+ÎæfrãCñ$,n¥z½^1e¬¥ñŠËrD³˜é‡¬VÛ×:ˆ“Íy¾Ô!ïkg‡b­,(˜Ï/LAq(Á¡àâSÈâCI-ÉÝëõnزý5h˜6˜àÃYÖý^jë“®Þiðs˜¡ÞÉö¿â{k@‚�¼ ³Ð§�xy<&ï‡Yè€/Î"Wš,…3:³Ï(\ ¦É¼¢°ÎÀ› €ú$Q•Ûi·Ñ‘¦b2¹0…’°2NÄ$]&®Ñ™C’õðpÝž¥ÍÏ_>IÕ„ž(Ž&çiWñä)*dz1ŠD§Ùê¤ä@óS©sRu!p¨@8Jó$mâ2f'c Â*Õ"J?Ãiš½äúHÊ„£4ÞÈéå$!¡¸,×EÑAÙIi€þ ©9ÓÕòÃë/IÓ]Äe w0"YÂYÂa.I(@ºˆ+œÈARi½ Â/à¢ÔÅ9ÑZœ¤MÂTÐ%ÌsBÓÏMAƈÒ,Q&R‚p+SrGG3ÑiZ¶Ñ䢥ng€Fô,>Ù,¾6&爸)øÈ™HÑW è$m§’Á¯ çqÇQçq»0–3:MÂÌÎf±—ðŸ¦5Éð4ñ+LúšˆÍ„û*¼§Ý7ÿîÏõ‘>ýåAÊ<Ûì¸!ž&¦óz.¥duÓuO…²ŒKÆ«¹Vç^XÖÎÍèaÇâôä)ûh ²$ÊL‰«u .èKò€Êu 2—™ì738ì€ ´ÁœƒÍ á<ý @NæN¨“h×y®$bœF³3Î /Óß4 ™T Âó0 ›àç„£ð.;wpe–Aqćÿf ïŠÏm˜[½gµÝnyb»6îÒuÝ3ãYñÐ ñ‚‰Ë'Zö´ÈÕ?‹8Y['‰9„82 „ÛbÄö[L¢YWKît9J�� �IDATi¦VþGÄkUQeIÖ%}Ùï—Õv vEfÖ¨\ðŸjÃH'étZà/EpŒ\.'"lm8Lã<hí‚•‡dH’ùz™U`"š“µ%…(wD†«KÕvç¬F\-öÚBgX3»#ÆÚwb ép82™ŒH$“““";ÎÎÎŽŒŒ b-†B¼Eù²¤E Xûæc[ÆÝvè-Ÿy‹Å`«Ý®×_ý¯.«þv»ÝµpÿųLkÓÄS·x 5õæ©å¿]þ<ñ×»¤ÅÓYÞ4ÆÇ~Ç®ã¿2Ó³0 ða|vÞÇ÷úàRè†ù"ËaBe¹Î·«Tª\!a3 «¬Ï!É\§6xÉ×m,79¥“0ø€É?Ë´™œ6Ux‡N3l�'˜:Ÿ­ð¯s + >£ó™ Ë‚x+(EÂK©ŽÒ©3aâ3úVùìÊù‹v×ßòŠü›=sÜfk˜_Eé QŸ!\¦S!ct•�Ïí¡nM‚ZÔÇÙ ö%ørDOqIg+©*Ê:N¥ £O'°ž#ÓTŽÐÙÇÜ8Ïp•Ò–!»îgà]>²=Œœ£K¸rl9TÉêÛÅê œ;Æ#Dr†&Q£xÈËCôö2§^ÆpS‘p Qcý|{G1Þ>LÏjŽkØÒJ8……£†­Œ#M@AŽ$]œ«'ž"è'SÄ5K£`eñÉf”„™Á?Do{?ô¯â„J3Qy„×ÕJåe/Eb̽‚¹œæs6´çر”“ <mdÏßÎì¶%o塇éŸçx“DÚäù,·–˜Ó±7QvºvæZäÎ;R<Ø\æŒÉ“•°,Ï[%R]ÌdøA;S„«œƒN£O”ÓðhVqÀ'tîhÌp±AÐÍÍm<gXåð•Ù h®r(‡&·Éíp/¼…lÑØ[å8áGp“ÉK-ø ¼'Å€ÉߘءQ¥O"alÿ÷MòñKØ¿Ò'a5ü†á§0 õ‡k«ÄMž„7CT®ÐU‹¾j9ÕR–ʙՙ7¼(éÒ¶=ÛrÙ' ‚ÄWŃsARÿCÖ±RŽÐ²{=¿Õ…BÁòdA1ÇÞZúm¹\öx<ÁxpÛ϶Åñ#wYwï:+‚‹ÙŒÓ <Ä¢VNèœZ LÙlVÈpT«ÕD"aU"«‡k›vío^¿zwõ†j¼¶w¢øD¯×+tC¬tÕûroã@£{Î-¦M–A¢h|Y3UUëëëE‡­VàÜ’8RU5 |øjbñ–þˆèµŠ^n¡PxèÆ‡nööym^w15´îãýøZ—g«š©íŽÊ²|t¥’Q¬6¬e´±€«W«]"ô…ÿWÊñ‹]µDm'¿ /†!X¯­Ý>p×@jCêÕÒÕÿêZÔ \:ÂuÏð.þ‘1™ØýàõÐÈŸÞÜ­hïxØd©ÄpƒË ÏعAg†Á#1ßH5KTâ'×0ù±Ä­&6¨Ù¤!ˆ×ΖIÒ Ù0%øŽÆmb^"yîµñ.Í!‚26º*JšÇm<ääÚ�j963ñ¤Þõ`æÛ2ö])=¬ñö2[ Pät•N?… F†µãtMÑÂw†þggiK3à¡ñu1:ýTš˜õ‘3ðfI˜M¤R„Mäyš‹˜y‚¤mh=Œ¥ñm:Q>|ó0%w|l“Ê!6a]33Üó„ ¤ ¸ ›s IBAR8ÜÄÌ4­9¼:J„9'%Y1š:ɪ~\”™Íá{|⽫磭LMÐ! €v%JKˆT'ã ê^ಜÎHP© “‘3ô71ë¦PÅ–&x–žIBË<åîF5ìctŽÓYŦ£ŒÑUÀµ¹Î\6Ðs…]×7÷à>ÈÊ þå ÓÛÃxˆ|†°Èó,rÜF¹%G'ÔCk B*—™ø|*\[ 9~øfs0­<î’¾V2¿ôý±›’ÞÚ’üÒÆ-e†Ý4A$ÉE­(vä"Z]ál¯Ac3O§(¸_âK: &¡"'%êÊüŸ8;мQër©LwúTÖ™ŒHÈ&wÀKÐO»Éøñ•é5Y ðÏ/¹¸Þ`ܯpO–æ#&oƒiðCÉäõNƒç~É÷nåûWb†o %\øwx‚ð=ÈÂ4¬1é0!%ñ »Á½p³Õ œžy<þø‹W¾ø7/ÿÍŽéþ˜_Õ ‰‚èDîu%\Ý'»íêŸ},ÿ*OÅ(H„ZQW‰jƪ,“‹­Ë$I²t²ÅȺÖÖâ ¸„-osÅ]go8;yÙdûsí"ä‰õÔ¦«5X˜Å¶ àB46ŸÏçóyA{}HQÖˆâ@ä˜Îƒ/Üó‚�²[k³*ºsVóJ•D¹#ô~„„� ˆ÷×u]É+®¸K5U‹m&ê�¡Åg™‹î™Ëåý·r¹lñD¶øF‹µf•†–"”533 #cËœ¸äÄòÿ\Ç'''ÇÇÇgffAäÕ•H¢6›Mx²X‡�kCÆ.|ã`Ï+=†b<òùG öBh0$ŠòZi‰Ú.h-å|AޱR‹ŽÛ"ºv»=—Ëß½1\ñz‘’­|)öJôB+•Šx8Åæ[+9óÁ3ñmñ-¿Å®Ù/Øý[œçj›§¶¸(]«çå,Æ0¿J\Ò!5M+}È d…Ã*&•P`“ÌåR¨[à×ШsºÊ®.¶jd*Ô›ÄM п†¥/1ÜÈÕE’y&}x”ªôJüÚÁêOé¨pez›ÉT)ÂÁ0›â,)Óžãø,I…*銯Þî?þ~E¶1‘§®›@Ž}yŽvÐVG.M‹F±ŒW¡è¦Y縗¥ÝDËt¬âÜ vÒ rEü)êZˆé¨Yl&TÐþžÝ[™êg {/K2zxüºÃ³CW¶ŽÚ ¸˜ËáM\2°dº4cÖÇá¢õ)à(‰4'¹v+{¢´xÉŸeY§Ž2Â’�ÓM±ž¸„™&XÂõFÂêv*-D³FE %\“´§ ¶2aÎA¹ŒS˜lI Ñ+èSq"Œ/c¨‰Tšà\a.B|’¶4A'¥<×Bô+üd'i«¬šû›Ç:?ö.Æìh¶5œqQ¬cÞŽv”µS´¥ñLÓÞ@Ù¤¥¥“é öC4L’n!†6Æ ç˜m`Vßòµ¥ªí3¿ý$E·[½ûÓ ^6N@f¹Æ<x«ì+pÊà‘ 2‘ÕœKãiÂVÁ_FuK£up[šƒIHCA¢If£Én¿DIçË gü<UbÆÀ ó*ÿ¶ó޳¤¬òþ·ªnÎ}ûvŽÓ=¦''f`2 ˆ¨°((UWŰ*®ÙA@XP1 $ 3À0ÄžÜa:çxs¾Þ?,¯ÝÀºï»oý1ŸžÛÝÕuŸª{ÎsÎù…A/| øl+¥NByºáq™ï(µÔ¦hÕ8¢s²AŸŒÓ`T‰Ã”Íé+TúR|u }'l…2 �Á8WA5ø-ü;¼G ¶ë|@â<8ÃLWCCCýöo=¼Õµdb™H$‰DÞÔ¦óæÃËÂÞ1oÉ\I±‚€ Ó<ÍNB}±yq$2åìDL1c®9_1;"샹ívûÒ7–Î/›„¶¨Í¤‚š0°Ã!]fr~‹+-s¢.p&WL4»Ì]¿"+g4¿Ô,âµÕjM;Ó©ò”3é|»ŠÊT¸0—KË.`›ãLÞ•Y|˜JçBC¥DÍ$ &KLP̺Mì6L$[1£Kܲ]ßµî7ëô©7Eß‹Ë&±)Ö³0›~b¸@FP=ê|Ç|ùpyÏ9=“M“•{+=l0ëžr›wq3ð8yoW ‰š[ÐéÌDbÞÇZì °—âŽð¤¸6›M/Ñ£k¢¹ŠÜÊVz#Þ·óU1uuÍïš°Uáe|Ò©g¼ÃìJ…§áiø,Ü_f})g áŸ2nú¸ÆK×\—ªl–ø´Ä”Á¯%nàE‰ßHœgà“Ð$sxúyÍÏ9˼dCѦð HjLAz„¬Ÿ#y6H(ÌêÔI|ʃ%ÍœÊ*…²‡ÁV°MÓSE{€_…IÂ�tX¸;Ŭú“õÉköÊŸxÀûÃÍ“*'îG÷° ž)`•IÁCõÔÆX;‹{ýšÀ3DU0 áŒ°¤=Åd5£Öö2’Re€¦<6yˆÆY\Ë*'â{±r|Ó3_÷;ÒÊ¡õjá¬ß½ñ…†Ž¯Ö¤æ*™ I É…¬\=],+e^GÖ‘G©Ó‘Ë™ ÍaWÐ"”T0­#Q{ˆÕ ¼ÕLˆ¾_ '&¨v“ò’°RpµRÈâHâ ”0 ¤nÚd…tÓ4ó”¶p"…[A³Rhb@ÀÿܤD´!…õð<¥“Tmã‰ì#Ô§p J$ô½¬¦v#ûŸãŒV Ö Q;î&F§ÉªxÝdn’ƒt‰¥”ÎS?}Ö¼ÛF¬ÝéUŒ—H;6H¨û§qÚÈ´éÈžÉÐ䃦¢´DqDYîàÄ 24ØÂœ–œvœzÃ0hQ醇%N•èÔØ#qEˆ?ÚˆEóaO¢ëN(Yád‰e6Q ®ÕøÔ³BåA¸ ^†q ' Á»d.€‡Õï^ÉSn¾ò^À…p 4Àð lÙ Nc N9X2d Ye¼[æ í?Ìb#I’è2 èùÀyª[-- åmy3òŠb ÿŒãŸ€2‹nÛbÍžbÙÀγf+lA‡G)(«Ÿ\Ý}Zw™^æêr‰Ð£ªªÀ%.Nâ ó»f·¿ÙÏ‹hÎ6D$*6ô’ Rù‘ò©µSõÇê%Iê:«k®zÎR° š½ÁÅ(f�5 M¾ª™½ŠóÓbJ–�}˜YÓ”†2/¯X$WÐ{Eö2q›æœÆ\C¡$˲¨6ÌôcÎL¹a¨§2[ÅÎË©(Ù¤¾óût«^0 9W®|w¹wÄë;dU63G1‰M¬Õˆ¨AÍ0sç‚̱@ŜƉ7õ΢Øg8NSÒ"ŸÏÇ—Ä{.ïYuß*ϸçkœ¶xÿ2 /C$|Ã<6ÆÅ¯2áã{9òƒÝ:7à _³Poð’Îaø•Á»+Ø¢ó[˜Ói2oà ða™üHg•Æ(3ˆxáEˆÁ€Áæe •³ÌÅÓ¥$fèO`ƒýÏÅ)Ó±xdf`|ž*•Ë ­0©6?©_ýpòÀ5Æ5¯«$uÆ*p S7Ë}VX)ôS¯±Ú†äEMàÃE.`›¦bŽA²‰‘,U³”eEOˆ¹’‚v„•ƒ,é¤e–²¥Lj8—þi}Û_ Õ³;{pèâƒó++?Ó‘»~ç"]øU¥Nø4–2ŸÅ!¾<' E )âø|ÄÓ¸€^Zh¬a/‰0ÁêÇ©D+1¬Êâ(e^8Ó;Èúˆ —Å�Ñ)*+˜n`¸’© ¦Ó!À„2ú<%ð#¬µŒyIÄð§ÃJa×FvÓ .,WC9J½—¤ƒ<Èó„z©rî½9ô¢C”R5Œ_¢$Ïr'¾zÜ –yšä3ÆÙô²æ‰†ïø)Óaù¾%¼{¿ñÐgƒ±öRšYUÃé`›\†9’~\s¼ ŠŒìE#ûɯfTâ«UÔ‡°(H‰–I4*l 5Â…%,ÑÈ‚à'Á'K¡Mç»T~¿„×4"nHÁ>دa…-ðŒÎ :;¾'ÃØ�?Mp†Æ 7)ÜBN‚r˜…Axòð'¸VC_ vH§ÓÉdrnn.lÙë~%§û‚µµbØcêa‹a¾è‹ù¼" ,à F1² «&ü2[ë- ­¢—e¾xüÜãYoÖ=ïöE}óËæ‹5ÈM]vÓüðíH²æ›2¹D‹ã )<ït:%UªÞW=²a¤oSß+×¾b¤ŒªU®¤kªmêíü;Ìý¾9Ž*ž™vÆæ\­ø$&’Püº©"‹ÅfffÂá°Ðê-î@ …X,&ä¦Äj›wÁ³,HWâõ|ѱ 1ü“ÑùÈeG¬iëôªéɵ“mOµÙ£ö#W™<yRÉ)oi_)A\¡X=“&µ`³xUM:Ô?Ÿ<Š-Z<Oyyyyy¹PÇ0–PO(4²v»]Üwñ ýOÝŠ?y8�pÿh·sËvfŒ»`LÃn8 ò?ƒQ™Õ_ÒXiÐÂ3‹ .±P®"¡+Å´Æ¥ÏåX•cÐyÍÆ³:*_¶ðÃ…QOE¹#O¬ÒÙÑÄ‹ó„¦ùœÊ=y&–33ÆUQ.ÏóoÐmae¥³}ö[wxwœ2×y«åº¤kïKÝÿùÑëÞo'œ \ãü™ r§räuܤY$ £€ÄÇÏæš}¬.@ Z…qj$ ÿß”“ÞÅs1ü1üñJ p ‘Fi.` è›®ûè/¾ÿý ßY5›mwORuô·–ÞQ6@ÓzöOR%xÝ´k(ïãwQ ¼YQëÙßCÛÕ§³c”ºþ&"”¤pW3á'&|~˘Mãš#$a¸Ha¥ÐÏ-!RÏÈ<¥)Üi\nRµŒY) јÅ!ôpÅ[8AËzö[Pë¤ÊCò/lב…ö®‹´Uöï¿[õÉkZ96È’I*GñW’Îà¬dj{°º”„ƒX‚Âtžßõq3øsøjcÆFs/G%6-]ùôëï7rËr{Î6þ8Îçž1nýŒ²Ãm”Þ’>|<,£\©“OR¯ðË4q¸Q£F ­„÷¦)kc²ŒX7LS2È¿|aˆæÖ –(#ynÐq*œ£ÑiP•¢Ã‚]âPG­<cpNò0&#©ü9Ç$ÌÁû#„à8°‚×Oðl†—áƒð8(à•¸Mæ¯Ë ?€}ð8 ®…ëáfèI|ÿVýt…#N>²‚ðLÁ‡ üð[8�'à?ÿÎä_73ú®QëKVY–³-ÙW¯{µæåš¥Xêñ)†‚õMLÄ‚}®Ù]1s€ÉÿâŸùÉÔj+Ê‹õIÓ}L¨40pÞ€-fÛyÝNGÔ±âÁsÏ%;’%'JÌBª¤¤DÈó˜8fóÏ™m¢âö£Yð-îÎ-(ïü#~ï7áI4=Ùäõ;,Žîs»•‰Ð±Ð;ƒPÌ*Í‘{¯˜C²â©›é±k–ž6›MUUQl �áÛõÓÌjOü®9²­°7Sþ)ǽû½Ê ’Q3&õ»øl‹õÒ鴘ù\®byøÎ«:+Wž1¸þÁõÝïéöú}}Á® =nwÌ;Þ¿xµ%I2¹êBøñ¥Ö1 _ÑÈNbÍ…²e1NÇ|dYNT$vÞ´Ó0ŒÕ¯6ﲘ½óµ-JWNø4\1•3>®Ì>§p•Îr:ç$Ïo¯ü™K®7â:#!ãö'˜}ž¹÷üj‚Ûdª¡ ò‰ –XÙZŠ7R\§Pjåæ<¿ÒùJýãhð+•Г†yº žÊ°ÕŠ4È¡ÙBÔÊ•Uôbë¢\£Wâ+V–iø¨ËŽßûoÁ‹>Ѧ×'<¶üC7gXyäËꇽw/wã Ð>³‡—®zêP6Ð_Êô4 3|ëÆÊqÀÑ~Z×2ÚÖÂl„ý(+T´<¹uô½È¹Ôsxî(Ë»è0ð•3k¥% ÷û¶^t{D+IâÑÉT1ºø¦ÃOÞuÁÅs“ZKgKETǨ°í˜§4HXŒű†ƒké´  1õ)*íäòØ„¬‘\†h"IcÔ®âpÇ$UœBÞiœa %ŒH&¨6ª™ØÆ Jj[Í¡Þ(A–´Ñ¡¤ƒãN2#Ô ˜b SuŒæ'—’xzhSÉ4’Êa¡¾‹Ê:â3”8™óð>îbÙ>9M¨„h»ÿj_kiòäÌ濜:÷(3:+¤ø:é—‘ƒcFÕÆÏ«wßZ=ú˜\–­yf5´4®%ŸSé´àt† ü$̳^¶ån™.p¥5Á#°r†6+§CάÆAø>œ/¸UæŠZ.ëåš,·Á} ¹Ø´šàëœ?”çù€Ì‰›Ž0nð•‰IlÒ˜‡:ƒ! èePB‚¾.ñ²Áï°_Ƈoá¿qË=Üö-VžÍ‘ïà ÿ&{~ eðYˆÃá;°vAçB²H™ÒÌŽ¯î°ä-õûëÛŸn/ä â[oöÊÓ{ïÛë;$¤æ?7»‚¶~[1ÅXŒ4Ì�êñxÌ( J1Q‡‰ra±CÒ;3{ÞÌjV}lÛ˜E·Ô¿T_½«zÇ·vô××ñhÇÁz¦=¶„ÍÜG/°‡XÀS6ç ", âçQS&üM†¯*×ÿ¡^ˆ¤‚Ãëh{®mÏÇö„‡ÃÁ¾àÛåªâ¸\Ì»*«˜?S¬|±¸&j"ý“«gžv íM+à YtY_@"~K¸JqLÒq)÷Çw]² èxºãЇ¶ß¾ÿ¨¿óªÎÍŸÛl*ؾ¥ÓŠx ¹êí¦Y‡C�yLÂÙÔÃâWŠsí‚Ó:Ž@ P^^îñxÖ®]+ËòðððÄÄ„¦i)%åˆ-L«ag¸óúN¹ o½m«Õb=xÕÁΫ;ýÃþ“~pÒ‚¿õÏ¥«Z75ð:?ø:”8Xã!=Ía ev¹}Z;û§ük·Ê+.Ö_ÇçÏàë2üÀàIƒ¥2õ:·(4ª|ÎNó$=0ª°ÊÃGBLOðÑ 'ÆñÃqh‡>ˆÈlÓ9¦ñKØhçhž)n4HЬµsÈJƒF­Æ¤Äæ9ÕÍùÎË~ùõvMËæ~z½z¢UKæéŸ42ëz)Í`Ópʼ䧢€]B2Ø1HË.Viä‚4ûˆÇ¨s¡`E1ùNä±mbw_”è<¾j&fñîc•QMº’I*Zèò“‰ãÔ–V3è!%ð2+/×^?,K"ë„ vRþä°cù•mô(hÝ´[)øˆ‡˜§FGÖP&©r“j¥wžÒ>– Ѧ&¦¨\J_7íAÂT»H/çØ4ylJÓ“T™¬î"¯°ÅGü%6lâˆ`zMR$¼‰Ý/±mޱ¼œ™ï®PÆÎàÙE¨âÙU³¸â8+˜dF£ÕÇÁ“kqü•¥*éAÖñI?–!‚2Af ´]ì1>ܧ½ë5 Éñ­Õüxìã¯Ì^ý3ù¨÷ÿQyîtË w);ìIâS$t$'ûmÈiœ*ƒ¬Ê‰ †ÞH»‡Ûº‘ù„g9 Ñ 2?Õ9¯À÷dÊuja¬�#29|ºáûstê²åü0É ¬ƒKX·‡ ø-¬…gà°Ïà ƒƒJØ ?ÕÁÁU°Oã(\ $¾Èƒ…Yx ùªÎ‹Æ'¬_ÏÊÛUæa-§¤•_eÍÝÆÄƒ2+t^á~¨‡ó ¦ø“äñ…ºB£[F5»vá§. z¡X)˜~ï´-aÛrËÅÒyGgç ï:÷]År¢b6‘BÝjµ¬R äKÁŠWÌt"jÈséútýóõ(¥ýWíîi·dHu/×)e±è¡-Ûñ½ÝaöâŽCþ1F½Éµzûܱ ŸfÎÌŠû¢Å-¸ÂÁv»}AƒN ¥Ä˜§—±À¢^4x‹•^•‰xs\‘ÿb”t_Øgör‹˜o'­$ŽÙÐìÐiC1_Ì2iÙzãÖDCbôÜÑŒ/Ó¿¶¿$RRu°jÉKKä¤l`¼¥ä’ ö+è¿]±%¤ m6[&“I&“æÀIlŒÌ©˜9½+^·äŠgÕ³ èœtVÆ+Í$¤ªj².ÙyCgÇ:¼C^,H²´ö§k ŘY6#­‰C1ñ¨ þâÂ?/h”î¿Bwÿ^Á¦±,EWŠTqCFÛwŒ_grcP*ßË‘wV|È ®P®s\gL©Lº9ìáš)šü´åiK’JÕƒ,< gÁ´À¬Ç\,‰p©Á3þ”àË Uú,=5Ħ(Q°<Uoš«á¨Ÿi×·>½éÛÖkw±ÿúð½?Wޝ´?}EåÊo޾§"rëæ :æh(åX –yªä½ ÉlªÀë!QÇhÛ^‰rƒBŽî M!ærا©Ð‰ÎQ¨&”aÊMz! ñ5ÄÄꤼ“U•ļ$*˜¢¶¹¼5ÌÇð'ñvÓ¾‘½*ƒDm.Ò94;™?ñѬe,ƒsˆÆîÆýÄ^bÛùüYL°rØ… �kˆš›T3ýV a‚‚áë%á!YB$L0HXFŸ¥¬„Èi¼ê"½™#AÂ9ì!榨TЦ©ðd‰ŽüüµC%],í¥>J$†cÓí_(Еƒ9B!¼CÔå©°’:N[–ƒp†„2Î’4ÿað™9Â*¾�n/ŽÌ-ßbåçÝœí 6è>ª]õ;®½ÔÁ«éo¾¨žüîúƒéN—ÙbÁ£1•Å“c¥{’¼—T‹D£FÿåeD¬,Õ”q3âçƒQ^3Ø…Où¨ˆ–‘ † °±“Ï×y \0 !?êK¡ faöÏ+\ p{¹0ÇYyìð^‰¸AXàRV¨Ðphx$Ò…=ÆêŸ³3 Ëád°rÇ׸áLpÃ_a ü¬sA n±psž;À‚9ø|ý‚ˆKÍ{ò­¿oÙ:òvAªíѶ™M3©ÚÔ䙓žqOÇ/;Þ.â/?~›n�� �IDAT:™L¦¸Í"R—VœNç‚ÈhF"3²‹Y”aÞ¨wÉËKƶŒÉ¯È“'Mœ?°ú¾Õ†at {ý·×ÛóvkWŒ‹ÞšÒ[$€+; ¢¼¸Nµ3sðÿJcÊŠPûÎЀXÎ6•,L£s%Ü3SJ’¤7ê['$ýï¥[ðX°ìDÎ`V™Å$®-¶WZ;.{i™`2Mœ>Qz¨Ô5éš]5;Ð>P¹§²þåz«j-6Ý(~ ¦U˜@ä/^™ÿ¯G*•’$illL×õùùùD"‘"uìôc¾c>OÁc>�#ëG”Ež•‹oÓÀyÖŒÕÚc5Yä‚« ž·r!=Ñ qú>i¦Ó˜ÙCð#…•àƒ*ø!3Þf<dþœÆÈaðA 8tú ia‰Î2m0˜ã¼1ï¬(eÖ‚ :…Âp Ê-¬0sÌC…ºHǘ7¨]‚>M©ÁãYZTŽU³"kc„#üWéw‡×<nߪ¸~¹<þÐFcú¦72|¢dÚ vƒÊijf©7ÐTÊó”ºIàÏ¡ƒ_CøæH÷â÷C‡‹LŽ ƒd³]¬È‚F¨á)ÊG˜kÄŽ˜¤z9'J ÏPîF‹*‚þhË\ù‘JɫЩ N#Ly#nÒ »HÛ(xI$ñÎPžÂcA›¡$+ªÕNÞ‚jAÃÊ MJ,h¢“TyI²DÅ"a´p"‰ÇJ!¯Œ¹ á ÎIªc„Ÿ=HN2nRœ9Çox¹çß½äÌ¿p¾²ó4ÿÎåµ;;Ò&PpJǦ´ ÅŠ»r¨.ÁÚÌdG–€ŽÝà'9:–‘Šÿ™¦nŸ\.#-e0rï©§õ»O4;¿scú@>ñ8¿ýv M&¨cQpúH„ˆÄ™ÕV¾ç"”æ‹Í`äx´€%GDá /÷‡Øe üZB)! §ÄàõœíciŒÃ%¸óÔêØ` *eþKå)‰6…å­ð‰tÃïCœšã•¯À)}P�ÅÂ*¿˜×ù+l—Ø!ñnÿµñ›¥Œœ §@�4¾ÿNùæk%V8`­/ñ‘Ã<ÜÅÀ)?7è‚ x ŽÂ �—™@öÙc³Çÿr\QOØ3¸m°®§®XœÆÔ·¶gì“§L{‚e{ÊÊß(ÛyQˆ¯M?*“c$È:ÅâLæç¼º½ ôY0–íÄ7{w1›-jÜ>èðÖ¿X_~¨|äìϸ'رXlœ…+£égïv»‹ ÓDøÍ¢­¨�ˆ1é1½0Š›‡&`Z‚†a8çœýgõW©’õ¿#ãÅab¾…Ä» Ïu Ö/ö Y�º3‘„ÅMÑJð‹•â2Ìo©nuï{mIÛ²G—ùúK—½s^ñ[‚ÔeÂöÌ·i¢´MêH%ë“uûëô¨®iZxy¸ÿÒþøÒxëÏZË:ËÜse®)— ñXìBi^¿‰:1Yáæ³!*“ke*Q™\`0%—”¢Ã,zoPÄÛøŽD"‰D‰DLŽ;÷XËc-&[.Ö;qÙ‰º?×ù»ý¦²T÷ÅÝéÕ&SõJ¼³Ôs»ÝkO:õ€ì6c¨ [¥^º’‚uvü î’ø¶Ñç[¿ ÜLþàT(èø l:#áÇ:Œçø#ÐYMëWêtA‰„%A‹¹ §Í²T£¤û™8} Í2í` óŒ!nš£1ONfc ¥).à‡ô`æ½÷ªßüµåSŸ ?{ŸúØŸæ|6yƫێFŸ¸¾íúÎK1–²Œþ^ºì¶sŽ‹Æ9¼$´FO–ž–•Ñ7DC©Y\­D“¸’”ãî@µ1×ú:vYɶ‘ÙÌž!÷²ÔGa%/÷Ð6@Ó™üõ«ëí§ú|þO•v Ÿl;õå¹_®n×Nä°dÍ(uítR'Ag3ý­ô>Åïç‰,ŽÞ2fË™ñ’Hâq­c4×J!ŽÏEZÂ(!2IU3ý4Ͳ‘Ÿ¢ÒO¬—Ö&R¸38dBÌu²ÖMªŠÉ a¡XÑM{ÇhR1‹§°úÊk¾:œ©‘у„Ûè ´2ÐÅkv>ï¢p 4ùQ* t¹8ÉÅà�Y/ÁZZ‡°”qy=RŸu~~˞حçëdòØ¢lÔN¹Kºî²Ì¹á åÕ‹ ÎŽQ®Ó¯Ö¹MçÒM)×9[GJs£ÎC~‚µÔö2’g¥‡•Þ8ã°Já#Ô*ø5VëDfø¢ÌgZùÜ xOžt‡Ž~ihÊpŒJ\£ã€à6ƒ›-|M¥e¯L©™÷>Ì×~ÎDë/ü¾VC[Ùuå¾ùCû8¤ÀmðC¸¶p–ÓvþãŽÎr/\i Ü­~ãFåú»Ô™¨:OÂàÐ ‡³¡ç-Ñ]Ýv/�›§æõš²ce–Y‹ªª×$@pÑl)F‡›•Ê‚„T¼ñw8 9æ<ßb±± EQtEý3¯kmÓ77yG½­¿mµÇí茟6^pžm ²yÓ´°¸Ã&,9Š…$Ìü$ØK‹Ç!oYîˆÄS,ù ÄêcšCž[‹‘b5ÌÜ)Xef†0M­ÄOš'7Õ4G^¡išÍf§Íf³‚J,Þf±ƒp&˜A£ãw&8Â4š!~1íé-P޲”¦%$WØ•"dCÙŠ½ñ%qÝ¡;¦U»«þù‰š)ô·ÀBÅÄI.pW)ÖÎ(–=,Vò]<ÖÒ-ú¾ÏìKU¥ªŽW­ûù:¡¹%AßuÇ®?Ú(v9oâSÊ´²®²ÚCµŠ]*‚]ïî²OØ+÷Vô‚ní?/q{>ÏsÅþa{|XÓŸ–Èü\âa4ИÀ"%+,Ú:oÀ#ôˬͱOb,È/Ü\ž"�¥ð]p@_–õ25 ó©,mTîJòkƒ(TÆé¶óëØU^Õ)“éKS%#e¨ awr|–JgnÅQ®?®<ñAǧïÉ\oH£Ùt Ýq”¯ÿ\ûÄÇ"3•zU^= {ß ±9Èè08áÍèYœ Ë¢.HOžD%LB‚h/Õ¤R2ÔC4¥±÷²üÅ ôÐ>Cù¼aƒ,ŽJ¦{iõ) .e&Jé:ö½^Q6÷å3)°¯EWíõŒZ)aÀ% 5Ó/£ËèœYœ ;ÉfqÌ*cÖO¼„ˆ—ä ºŠ5Ä\?ÍGY¹™]JÃaJ­"sØ«™ì£E´-¨99+8šÄ;KY»›´‹L#CÇYîó={S÷’Ýõ¿ß0b4üm²U=Ee–,SÍ´pΡŒQ#åÁ“£º™I¯B…mšŒ‹’(esUŽÔ7Ö?ý~9ò. ›Q³#Ò–°vŒ•ýæÃ‰•¯sé²dZË­ðàvb¤‘ vK<&s•JŸ…jŒ†¤swŽSfhV)È4ëx3LÀcÍ´Opož ƒ1ƒ‡ ^b´ëÔèd5F4Âp·ÂW*Yžà Ä+­`œæäÊ–©l²pº†®s”85¾"5wòáýÜ5Á©)>øn‡*رÿ©reæŒgȼÁµP »Á AnØ¥¿PUpl#2£´Ä´—>el9EO=ÓðÜ WÂ0TÁ�\ ÅÕÕèèèo¼(šÒr°%S’ñ¨a:eJïˆ9%k1÷Å.–½À½x<.¢¡VÄ CÌf|æUU;k³±i÷»—ýfÙè–ÑXCÌuØcöTej¾c>Yly²ER%œmòuDÉ"²Á`P”qbß-$ˆ„…6\€n(&›áIìúÍMz1pn®mîпª9PãHÿCö5 ¹­.Ðtæ&@¬­h‚—› ’ú‚tU\½™á¾¸ ÀX‘¨Nú—C[¾±E`ÊÍK2‹]Sïôç0çv&W`"ÂëÃÓ˧[nåNfy&[uÅ\ФxuoÞÈÛãÿÐ8-ÖÐ2=PÌ +V)†Àˆ{$Ò‰IÔ[€7™Æ,(«¥˜¯ô\ÞS±¯"p,Ð{I¯-l+*ç7ûÝv·>ÙZŒFÉÔgõ ÷´Ûš´£ïâ>C1Ÿi”yejÖj~¿ßtÒr¹\ï¨j‘™ƒÇ8¹œ+¿_òÚ»3¹R »Æ%1:Y%ózŽ9�ú“tä(—B{ŠYê  þ,ñ=™5ãå*'|¼äÝ1b2¥:—‚18*QSÂM2ö3 °ûéÊÑžfN#'±:KS˜ƒ’Á·øÀRÛ€Ï~ßõUœ“¾æÏƦy©uØØþŠ|÷å¶Ñ «‘Kh‰²v)3!ΙAÎqZž*i;uÓTåÉÒl!u&ãqJ ¦\¤&Bhy<mô•/g6K²„°Y"ÕOSxs6 ÓT„ zH9Éê(¥ ’s ¸ÐOfofxMIo¹tꮾ*ÏTµ¾¾;õ½$"¸BÄ Ø²8œdBÌϲ“s’9Æ Á…:Îr;ù9B Á5Ä’c¬ð’,c¶€u޲%œ²2Æ!VÛ($ð*heÌuÓÒ œã#aAáïgi#JžÝŽsË ±ÍÇ-×ï¶b™‰’›§ÑGÜF¾}†÷‰«hýÄÝÌÇØWIPÃfCÃ]BÞI6A¸‰d¶n2uõÏßž+97Àpº)Ì=ßs¿û÷ªÛ¦‡V“ñàRUë¯4»ÕÆ0+l÷0‘c¹›‹|Tf¹[çtØ “WX¤,ÏŒ›ƒ9†Ád“Îé9VÉ`-¸íÔØyž&øtÁ•–èŽóœÂG$f<8tº4YƒÇ%<r2!X® Èœ#Gn×ç ®‰òÇ.6Ò+ ¦a ª`9›¢^æÀ°üP TsÖ+Ú²£Î¡ûgtó»×`=TA9Ø`'œçÀ™ðP¤«Ý»w†¡Ëúð¹ÃZ¹V;Wk·ÛÍ.ãŠI¦~’Ùņ]ÿÇÃÔ¤ñó¦{ú[ÂÏÄ·ÄlL–åXC,]–.;^ÖúÇV{Â>pî@¶4;³fF·êm¿i[ìRÙEõàr¹L׌b±S‘È|¢x2uŠaBÉáp˜HksÖR³¯&Qˆ7ÄóeyGÎaMþ=嘧é§8]-öŸ¢Mâ„PÓâ~š€ZâQ1ôÜL¢›óåF6D#k'Ö=¶NÊK J(“‡P¬�R ÿ3u+D8žÛ4^îxäMÕã©MSo|æòÃåK^\R{¼¶k[W÷eÝžmÚf‚5ŠÁñ"#š~`¦½i|,d‘…ßJqÇõìÁÌ>í[‚!Åסá±3ÆR­©º—êjŸ©5·V‚ä—ËåFÎi~®¹™)¹¤Hk$²4’+ÉÍ­š9g¤þÅzÏ„§¸ë`neDç9—ËÙíö“OÛöÍ@@å²'øÓ‰¹x?¨9Oã»Ð*±4É«p>ü†RÉæy*E\÷‚,S«Vø Xíøu–dÈA(ÆqžõИ#ÐÈtž#섇dVÏqŸ‡F™¼Â…]a4 Y¦Þà~¯Æù2kuô>”¹îþö•÷Œ †;¯¢Êm¬xÎûóuÖ†˜ c­#kÇ8Èê fJ¨u-PÁVI"IÒÎä4†Œÿ(+²8–¢LÉcW¡‡L.kŽÕÍL½°÷вšC0ëEŸ§6†]½Ô…läÄWÊ„ Ç ZâøŸZž~jãðGvJm]Ï}§/õLhî…ÒǨog|„z;¹†—Òw‚ÉZÆ–s,‹£–1ù ª…œà•aá$3I•Ž\Ã8`#?Dc[93*–ídí(uÂÝ*†ŒÚþñÏÿ×\P£7H8;×2“³äFV•?q¦›tÛ(ÕÇq•b%«Q¿Š.+QË$•p›Ÿ‹&ɺHW2=Œ+Ít9³6ƃË'·<}‰¶g¥ÄP¤*ÍÇ~ÍKm–?\çœÕ€àÎåòwFÖÍèw¾2ÿåVT€fåÒ�ÕyÆ# ò) «ã4¨„m”[éò±<Ź*÷ ´õ°+N -˾,]`ƒ ‰Õ ŠÆ G5c£ü!ÎÅ•P©qoŠLA)<�AxQc—Â&]Ú”öÜìEOc×Qd&@Ñi1Z áÅ/ÀOa´‚úøÂ!PhŸæ¼Çy ú|b £ÿøÛçeäa?œÿÖp8‹6´yèªû®²ú­b¬"tíDÚ‰§Ø{¢¦ev`L@šnÞr Bç‚麹³.Γë'COÔ#Y¤Ò¾R·ò¤É†ç¤¸¤¢÷ñÄ%Obþ¯3ž.ˆ†"[‹©‹cÃå‰Ñu£ÑS£šM[û³µ¢ó&r¼É°6ñ)¢+Xœ´D-kr×ÞÎýv¨Dq>‹,‰Œ1¦ÈŠª©rAêP­OµJ IÕÔÅ[ŠEí$½iØLm*ÔÚ~þææ`쌱l0»úáÕ ;Ä+ËYf›±Í¯ž7d#x4øß² þ[þ·C·‹GÎ,£ß²)·à–µÿ¼ýÍšÕö¦ß•é'0rÞHÓsMÅ™U’¤’á’ ÷nÐu}äŒl¬úɪÊ•›ÅdX›Ï³9ƒ\<-{«tõîSgÒy>ü ®2è+x`·Ž²¥,‰Ó®AŒ`žv •w)œ¥ò¤F™Á=¾¦1¦Ri€yˆ´ìÉáR 50´;œÔ@dвS”W¡Jte¨S‰xH(lLsU«-Übð4„²÷k¼öö1ä8Ó¥$“”†&µÔäö4°FˆëÜç6–8ÖnÂ~**𬡷“ÕS(‘9OÝ‚«××Éì ó82È],+gf ƒ*– •Î-”0F© 㚦á|þ 4"ÉH>’L÷Òj'¦ÁólØDÏZgðÑó}ž‰ø)Dz[u~æ—ïûÈ{™*Íãt’é¥ÕN΂ºŒ.ñ(nÚ})}K§Æ‚ê!é%á&µ“­"«‰TTÇh_“ ø*§¹IÙÈ/ç˜Ü8þÉö£&ð*?ùØ¥±ç_æ².*·í—„¥Nj¢­Bšg$G3¸=$kˆ¤¦‹Æ ûǨôàÌò •Ëü„­4—>Ê=Õ|ÕM!J­%ìßm¬ø]ùçs4Gïÿ²ìqù¿ùÁº#îQê"|Nâ‡y ¾——Ú^Þžý¡ß• Ýy{”Ú8é9'ÃyšTŽYX©SÈ"Äá§ÓœSÍšÈKÌHXTØ?�;tÃûàUXÑÂò>ŽI´It¬ˆ’V3! uðÎב®T9G _âÓê4Â>.´Ð¢±ÝÂy“p.< PÿIüõ­‡ó,<àö9ž€cp)<H÷8Ý·Âa=¤Âäa�®†4ÁƒÐ›aÅ[…Ϋ:OýÕ©ÂÊn·›²³ÿÌa ö¼³èu±<ö[ΊD/Ë? ·†u›^v´Ì<­ªªUoTY5»`úbf…õض‹îŸ8¹ˆwf¹cÎr„¤˜¨‰g pÕWó¿‹WÆ=ånùSK¬!¦…´—>ûRðP°ññF‘óÄ… PÈĂC¸ŠPhÊ/½óÊ÷¼¯gvÅ,à÷Uï¯~“Úœ¶–•[,–t:­jª‰ãx»<!�bšXÜ»ÈÌèÆhÃó ²&GÚ"Ý—wWì­h|ºÑ¯ø…\’$Y“›ÿÐ<ú®Ñ£7Ýðí ‚teÞsÁßÎRòª¿.–ñŸÝx»còÔÉM?ÜT<, Ö¿\ÿ&²_–L—b®…ù¼-&QXÞ‚ˆÕQ›Œð¹:í l/ü¨ƒèqìŠrTg+|5EÊgá#çkÌË´KÔ—qsw·7¬¨ ¾ ×Aþ-Ç�|áUzrØd®žà=*À*™iF+Y’a|= 2—HÜ÷ØùŠÛæqÒñí‘®;}ØeJl$Z C‘8f •Ó6Oƒ;UlUÌå‰:Yz¯tÑt€•«éÙOc y°vshšŠ&÷²q%¢1|å ã/%æ ÿq#Ïsn;Ý)‚¯áv¡Y1’”è({8¹Š~}9£=,³‘?…×»iËà2𲤞þ]´.áH*<¿qÉnëÏÔãÞg©›©{±åÔÛ/ͶÓ°†ƒŠ�õ )¦ áþ N7©]l^ÁÑÊ-¨’\«Œn'7O©—Ä+li§{’ªsx~ˆÆnÚcãÀ3_/ì=Õwçíë蚘YÝ¥µ¸°•Qyy)}u¤]HcÔ/#ù‰ƒã¬†%Å‘•ø÷Ò  ;øÏR”j¾˜åÓ\–a{’…ã:%Pi<ò]ù¢ï„9¡ß}ºõ÷?hÙ§ôκY$;ÃH-ÉiÊæ)+erÝö/¾þƒÛR´è|Tg@¡ÃOp–˜i¥ë8É,k[Ñ’Ü\B¶»†Ë‚ >£6ø²Î'­|´‚«'°Ê¤UæáøÊ(‡ ô#pL$ø$¬�ÃÂj¤ÁvøÆf5œØîâÓst_¢ýÞ%õ)t; ®pÐâ`ÍÇaVÂX›àëÖy¸àhƒ3!QÁÝóŒ¸7Ê*pÀûáß!6ø0¼‡àÓ‹›'J‰’ªO5=Ûj z¬ð±Ùl&XÎ4¾{Ë-³˜ˆ,@jðþ° @áæ¤A|à«Ý\C2l)›ñ?*˜Ì1•aÂlPh/¯[0¢ «ó'SÃŒ¶ÅÄÕu‰Øo›´ÆÓÓ¯ÞûªêROûÖiþa¿9T+NWÅ©]œS”\&.®x­zÝ¢œ;Ðnÿ¦nòLy”¼bKÛþº“2=k6.æ$Œž;øüÙÒìÐö¡U?^å;”¼"yþá.K’T÷j]¤-¢úUsÑÌ1çy‘âA”YR›8ÌÕ¤XQªºÝn‘®Šßšx8(Ãn·«uÏ¿îÙüùÍ  ’ÿ/™ÒøÇã.ÂÔêÀó1íÛmv¾dð*U¸Kç]„àE¨ÒxØA¥Êí*OÂ…Pª°DE“¨5øëåÐm!ãðIüTÆæ&ç5‰´…»r< sw�g†#-[ˆgi•)ƒQ'û½Œ:Q¦Ð¬œ*Ñ ±–ulùñà¯>çúòUÞãKãLt³ÁÉCkØ"£÷âÈó€‡K}$¨Hñ¥R¶¼ÄúVFʘ(з9Jô:èÔÍÒ¸Œ®i*„DšŠfœdʹÜGêÇ\±– ÅI,À¬[™�ñ4Îãt*zІØp%ÏîâÔ(I|îõš º—åI”Iü,]FW&Q~RÂ2ò®G={þî‹êu=+~P»‘½’#ÔÏRÇleg˜`”@×2ºD…|Ÿ¸x³~bq|T°n`Ÿ œ º—ÖQêc½_ú¥ÙÓMD[8¼“•Y¼ŽgyÍË'-¨N2*–Rm–Üj‡éÊ¡²œu˜^ä8ÜŽsœU>\ƒ+E4À93$2<¯PVÁÊpШ‰lŠpnîÎtê§ßéšûBéìr7ó…Jè.{ü`Ó•Qær|{ïì-k –éÜ`ðLœfC¶vó¬âØÒägi°r­ÆÇUd‰&ƒ1Xëá!ƒ»¦pBÜNF%åP$:C£NÄ@5hWxÐFu†Y• ƒX ›aµÁ=lßÉ7~Ìå-çHD ü^°Дä)ú¡A‚8¡Çà |Ð “° ™æ+0&Ѩs®+a…D‡Á}ƒ­ð|´8dL»¦‡/ÞvÏ6l˜Àâb›Œÿ U\è˜ÿ»àx<nD€6‡ä"Š >¯Çãñz½f %"]ÅÁŠœ/7xö`õ³ÕÝcv]L’ì?ÓV兩9iªÄþ¿èú,è>¿âŒ:^k¨ÝY{ô²£/ñå ¯¾p1¦`A/f2™bÓSÙÖ¼ZsU3FfäŒ9#o¿f»ù§UT3 šB…fÃPÜ ÑÂ2/Àˆ/¶ú}sõš-o³è%¬Ô=S7²m¤éé&%¯ÄÔXdiM…H`†œ•‹E‹;«ïœL‡­b¦â Íb=‹Ô‚b°Ìî»vg¼™ ö+ÿ7bµ{DM!+ñdšÒ·ÔpZµ °Ë q§äxZå~(7x=ÄpžKtÞ 'CÐÏE)~/qƒÄ6h„?A„pú3|ÞWÆ0 Ø*x%Ê»ê5î—ù†Î¾ ^•ß–°B¡µŒqfdlþè#V4yæ‘`Fr&mó äø³DƒŠ¬ì:uüê{"3e'õ§ºƒRnÀOõ,ÖìEodÏþ¦­zÉd÷É:n‰sÞÉ ʆ‘`_ «¦¨–hTØ¥±ÄEØÊ®r<J üf9r€hG)n‚«B~’²Aü:3BÇ©àHâbo +ëÐÆ)MàMSRBT ~‚ê  Lã_Ëñ]l.g¦‚™“ØÛ0›Žf«†ÎhØUc‹;¢òØ|Ädmö²ÑGBGÆö=8M…‡”ƒÜ,e½´eqNPSÎl»Šå k&|žákž:i6µùàI_=WOøXN çˆÊL©\˜À;KyønÒ s„JɸÉfȦ9aµÒé¥9>†ÍG ‹#†ÓO"ƒGf:KÌÉŠÔ¥ûò3þôŽÕ:ö4mu8§ôÓßh·œt(}ê‘Ôš/'ÚcRÛ´œÛåž¾4êþ…qÉ”ôè­p¥Á/eV;qÒï£.É3^j øôÈ”ø97Mö+7Ø ‘Hè,/pÌ‚`(IVÆ/¬Tè5xRfÔåIÃ,`ÆÀ§áà<è^Še-Ç!£ì¯Â‡5þUâÓ³aøø<¢�� �IDAT�<GÓ»¤¶ýÒ_Th€?ÂYð VÀnØ P¡ðaƒ1¸öÁ5^ƒRèƒ÷BÎ4¡###?«úYew¥§Ç#„é’Éd"‘H$ÑhTÈ]›ÑÍÜ ›ðâ·³Ï0÷ÅfÓ¦*V‰D”q:’[_3îŸôÇSÿ°?Q—˜]6;×0WpJÂ%"ìJ ý[úcí1WÔeM[Ík3gWfí"¶ð&5GP;…;—Y-‹šAf1dV?fÄ uñ<ÃÌâ mrľ1ß÷‚:Otêb±X2™L&“¹\Nü+ByñOήœÚ05¿t^VåÆç‹PSšhʲ,ÔoM×D±ò‚Ù&•ÿÀòe¢mÑÊáJoÔ 0Ša5æNš‹/‰Ç;âÑeÑT}*V‹×Å}Ã0fÖÍxÆ=®iWq_PÜ÷bGñ-I5‹u3× HžhÉŠ~l2™4«æª†×„uE÷Œ{ ÅðLxÌtµ€Ûðæî̱Ú=µ–œ¥µhöúÞ²Ö4ïµ¹¶B‡0¬ÞpÊ;@- èK]昗ÂZØ=%”DˆBÇ<S ®`G)×Íò˜Ì5:ƒð'ƒ^.!ƒ*û XGh’±ëôœ!s¿…+tbR™ÈQ9ƒWç‘0”iõ“6ÎìÖîùžÞ]©ï>ÿu«óäæy‰Uއ϶œÙ;@)_û¶b¯>À:y¥÷d=qG¬yNûÀ=–_ÿK�eŒZðh$$‚w¸è²b:Ûs³äçIhÄódš9ʆJâè£6‡’c E˜o¥a^w±=‰½…÷XÉF ¬b`?ëye†×l\4Fm ÃI:H8J œ´Ð«u“ªd*wˆÆ¦WÕÑË^ ·Í5/aPh÷¤ù"^˜ :†¿”ù.–µÒ«#«Xdô ¦ßà$ù(véZÆ:ÏŒœø`çùœ×s´-Äܪ‡×‡'VXQk™9B©Š£¦¾%LeéƒZÝAÄŽµšé0e¢óä@²°Ê†ÔÄ)S�u«Ùy„G<TJ(C¼o ±ÃHóø¢·ýÀrÖ£åìœA18IÆÝöõKÞßF’î³[†¿@¹-ûíçŒËæ¯>¹$Üf\Âæa"Ç­YŽf8ààÊi¼Ú Z,8Tº`­ñx{ÓøÈê2íÿ{–Ú÷T¥²/N'½/é}g‡FÙQAEDGEEG‡ÔÑqGAPСÙEP Yzozß“N:éì•T¥öõ,Ï‹Óˤa˜çÿ|þçà ''çüNÕ}ÿîë¾îëâTŽE~ìIúUzá{ðÌÐy –¸a„Yà‚a¨‘ˆk<®á× „˜>ÎIöA©‚Õqb;E²p•F`’•û¹ì:}š°íY¤"«¤!?Öd>¢±I§NÁ ˜¸ îb°Fá| ð¼ÊÓp¼^xFç€N¦ƒ½0£ü‹o‹ËC²»Ûm$*£d1v‘ Íì™ßyÓoÂØìO•?0ÿÏÔBd9ÍàkØíö]×îê_Ü?´`¨ñÍÆàÑ yfÓßšú–õ]ʼni#«GN‡‰¢ÅÕëÒÑ{.éi¼]Ìœy>éÛ1ç@$jT朲™qÍö•‘fÊu•ʃr±Xl}ºõø×o«/'8˜Ȭ;ÿ4.bd㌠‚pø†ÃŠCÑuÝ9æ´¥m¶¬­þíúÿk\ë½Ï1R>lN !¡þÕzÕ¦ý›ºCucÂX¦&ãw´=ß ÍÚýÅÝ%W©õ­€®MN“ïÓZº\"ËxÙl¶¼j1ÆòL¹ƒxiž`€Éýkú§½>Í–°¸á@ݾºr´Ðx‰å^‹E ÿØ9ýo9 ï_‘Ý ‹ˆ9¼y °vhÄÇg¸ZâÃ:s5JP©ó9• ç&¸_c½Î:%™i)æŠÜœcG’] (r¾B æÂ.—H·NFÇ’§£’Ü« %³P¥g„¬6ï/ùggŸÿl8Ÿ8QE¸‚HŽP M<ÑÚb¾Ì<µãwš}¦H¢ŽÁìáùJÀ7x¨Â/( îc~žSEb•ÔkˆûðÅx8Ë×+ˆ…‰8ã\,Plftœ&è´Ñ~œX›Ÿ p¥p  ‘QЇY\I¦„ àÌàOÑMäi’IZ™^ËP‚F•h‘Rž` K ‹ÂD.+©êcΆƒ~£Ð™ %XÀ6@k7½.2E¬lYœ™þžJÆžç’åìÈàZËÛ[YÕDßÑÅ™×z,óħ>ò|.“¯¨ØSåÆå&}œd„Ö~Ú@ 2æÈQfÆIœB,RCŽ1O'ß@j/ÿ1/í¥£@T§W NÅg Tp÷#É4Ê,³“of¢Ÿ¹I|^ͲNE¨GY Ÿch˜¥ñ˜Î¯ç‰´iÔX)D´Ü×[ŠÓûøÆÓÙ¯ßQõå³uøUž› a¡Mà•™L!Ȥu<:.¸#ÏÆ›D”0×Op¤ÀöW‚®HI ðyø�\¯±îÖqªièü .Èp»Î2KU^ƒá ~€Y[ ­Ä]Ã:¯ƒWbƒJÜ-0 ¢Àq˜-³V}çV±g™Ê}ð¸ :Aƒ‹à $.Wø&\ áßa:¬�Ãlb8ObUydÍTgDUtŽ9uN«þ”VcÇ —ÿÿrÃõwÓ|›Úµš ™ç(Š2<gxåÏVŽA‡‰?mØÞ�½Åtmúô¬n oŸWUÕx]ܪYUáŸÜÓM øÿ‹¤õ‡9½ûþiµ[kû.î3e)&)™ÈR¹v†™·ÌÍþÁÏZ;´ô®¥‚kÔe‹ÛÞû&Í¥6ô;Œ{6² Åb)/&Y.h@Žv»=ãʆÈù|Þ8AUÕÐPè@È<¹rOåòÿ\ž®KŸ¸úDËŸ[LÿÔÃ0㘺³1 ”w{ƒÂcô5Mذ\)Ñ,ŒFÖŽŒ,‰·ÇEEtÄ“j8cV Ïh¾ŒÝ˜‰—Þo“4)s(•J†˜¡qYã%–Ëe1]e`cœç *œßÑÁB�.pï(‚ŸŠTëTæ¹ÈÊyc ¿Tø8üÜbw'¿®åã#à &Ñ7ÁÝþC`±†W¡Ë‚£ÄëÃ4kôÈÌÓðÙY%"&{ÄoþX¹òøHWÛpK7}},Ô¨PÙ"¹^i‘oˆ%þ–Üse Ûz8áK*z‚—úõ£åìšÌÆWòÅ,Žc„S”ªjGãCµ+97Å@?]%Z'è Òz‚Ô…îç¢JæÔ1X$™£*IÈÆ¶´´IXjPÔUÒׯ^B' âøÇÈ.gßvæ¯`ôËê9ž&�±:¢1But·ÑÙCË(U+ÏNa·Q8N{û¿ß°çþ_?üëÞ…«îkMl Ö¬p?ñìÓ¿Rì 0óG—T¼Èà¬Í ÅÆ+¼$±×ð‡T'lëußüÌìùóy{iLÁ=Bz³üØlØgs$…gº6ºè¨Î#ZqÎap„:ÐÓts»Œ+‡&Ñ P¯#뼜c<Â>Ërè>'‘á!™ù9–&íRuÕ©À¿7|ËO³ *=:êœÓÃŒGxUb~-©Aj[9(ì[šúÃ7•+nU¸Sâ: M¡"–"Q Ö™1jŠ @»D½Î½ÕG¹Ha Â!°ÌÃę̀"7ÌËÏI\!0[åz¸ZdLåF-"ÂEn³°Bá|n†‹až•7<«ðŸàå·¯³=MÛÝêÐRØ'àÐën×ç\¤þôwüþ\Ô†*XWg‰üðÃð;ðÂu°0 RxªáQ¸ °6À½P/Og¹Bí?}µ ²œ•Ëb&ö;qÇ3h¦¼Þ»ù>¼¹¼¼ñ ¤Í_ÛlOØÛ:2”sOkÊUìv[Êf;n3À«R©„àô¿~×ëk¾¶¦üúªU-YJ–ÌäÐi0ÅLæp8Ìlaü¡rܲœùmJM­Ÿ¦¶ßM–Çi’^ɲhã¢ï}±é•¦–g[EÈWæ#+"=çõèºn›°Íûù¼9Aì1»]²—'@±+]WwÕl¯™õÈ,9'¿ŸLY~Ÿå@¥9„{Æbk¨˜÷åóÕù¾u}þ¼çiY&³œô°ápp Ø·¢/6+VÿFý¤^¦¹ªS9¦+!§vª¦ÊS½['µfgMÕÞ*I’²áì¦nÚÿ‰ýsŸœ+å%@±)EoñÈUGM‰Å?Xl-Z]輪³ý¾vKÊ2˜úqô¢ËÍqÌã{¨Z$áa˜#2[§ÎÆ·=ü5Ï 75Þ*‘éSi€ïÂ}"ažÆkð¤Ê3qX*aæ(£°,E@â~gOà˜-0­Ä×À*à­Ãžãó ;DZ´kàa(GŸk_“5?­xç—ÅŸ¯ó’¨ÈqÐM“Ýóƒâ‹'ÖÑŽ×3Ér~K’¸H·›çs¡ ¬~Cìì°wß4AƒŸD‚Gš=5ú­ÍÅh{ºo~iI$œ¡5…ÍKU5©~FšIöf“ˆn¥ÑGþ(~‘ñ�¶(ÖN¤™DÞ‡g‚…ŠHß0õ³ï§zˆL-Nä b‡˜¡âЬgp'ËÃDxŽÓžÅÄ{ŠÆ¬â­zn¥¸lÇÈê“=úôÌÇ_:rýÞ 7ÜRÿ‹+—Ü¿´ïÂÎ#Ÿ#ó·zçdÝrŸÔÕŒÏC*Û×¾5Ö·}ò׫>}cEqDÕÄÁÖݬӨŒóøR"ýÌ£2‰¯–q¬‹Õ:cN*Ö²?Ah‚ ‹H„L5vI…B 9ˆ«H£ÈÊy”ÚpYQ£x­,‘©Îœ¿£xöÞäWv»½²øf»@…—£ê@�·È…:Í%W@TSWÕúŸÊò³šÒ‚̶Pma5üÅ‹¬ã¶ÒkáDœR†Fx]£&Bø hI Ã:ßÒi„Ñ8äbšL°ˆ¯D«Z r„á7y¸"ÇÃpG5ÿšÆ§Ófš@‰5:‡ák ?T¬ÎgSÜD³‡u>º_xs…à{E\ÿºªí\~5 +ùjûY|:Ëg;à!‚sàè�Äd.ÒˆA¾†(´Ã0ÔÃ1‰ë­T©€³áx Åì]ŶŎýîXù<Å(Š’ÍfÍé$«*Ùטf5$— »òï³Ùæ™ )3§7£[ãÖFUVWݽÊÑë0ä qÛxKüð‡í»sÌiBU‡Ã+œhŸÈ²5ïÔ˜FŽªMí;·/2?âò!¾<>š,ùrFŸ‘w'Åb³¸1{$åŠ f¨2¼Ù¡QUÕ°W7 <›ÍæšpÙ{ìƒ+‹b1Jw}¨ËÓçYxïÂiÞ>xóÁ±eccKÇQÐ<škÜe�¤‘¹‘tcz|ɸ¯ÏW{ Ö¢[Ê“&Ñ/ß-]Y,cýMnúTY£IG.”‹Í‰uŸ×=:kôüߟïsù\.W.—3¶2“ÞZ¼:®èŠ\Ñpõ¸¼½Þ©x¬9ØtÆ-K9lk ¯¦Þ QwkTWå帩àõ¥ÐQeUF$272¸bP° ¡¡áyÑù‘® »Zžmi}ªuÿWö§ëÓ}çõ5¿Üìîs›3f‡ÒÀçvÍÜ_ž;…u»ÝËVŸõª}p?TŠ|Ydu#E+ƒA£‹e‚6¾TD‚§%®×xYgäÁmå/Å<;`…Ä ÕT$Q$–ÃIó DÆDêUD˜¯óG‚6•aJ2‹¼–Æ.Ò_b‘¾ób=ê’IùØ«ãÍsÀEókG“ýngw›ã’-…på¯ã°FÆ Ó¹ilå G*î»Ê(£g´•»F.ÙSºëGúGÿ«èvÊÇëejfÐ/m䈄×M&ÃÌ,…q–%Ñ«8¡Ðl#™Ç«ÎóDži1¢IÒУã÷S˜M4E…@AFSñ°ºÈnÁ]‹l']ÄYÃp‘S4R! «XXgÒ£#R¿ágòèò±Ë·Íº-û“kƒŠx»Ýlýè’GÛü^¬ŒÔ\|p`^\Zµ¹wÍ`÷’øén©ñäÚÛ7„ŠC[ ƒ#Euû(!!樼$»iðÒ¥Z'Ö€ÏG z5üvJ¸3Œ×a£Õ•d³$|¤Çq‡ÈIDÆiò°0ä>o-Ì|MˆÕŠ_ûÝíÓ©°±O A%MVªÝϱ?Gž/âîïKÇVˆ'>“`Æ6' n1Î|OX 0V"UKešguÒÐR฀ËCº€¬S�f@­Â¾"sP%“Nr�TðJ\˜æ 8*2·ŠÊ~° ¤ól¹\e¬N•hÁÍê"{ÙºŒÜ ç ™.an‹Öò8ߌϵ‰|JßãÑóÙð[vÌbO$!2\¤ñ8ô�à+Ô€Bð0\`!beU‘0 @ì/Wµ8uêÔ¶mÛÞSWN(OWå QWqÄP5ƒË{¤+£¦1®lD%±$†„ŒkñÑjµŽ·/nü}c伈jW=C#]ò¬‚ ¼ù©7—o\.dÿ1ìyâ'¬i«¯×7¼lØ3à±)¶r®Ç¤=²áoð&|šéÊTSjZxÆVÙ$hK×uk¿µîͺl{¶TWšwß<ÿô"äåÆÍ-Û[š¶4M,œˆ7Ä'fLDgE£³¢ÙÆl¡ºà9å©ÝYëp8Œéc­ÌxzÆJËl} 3ªCc arSðÉ�' ûã—O´&RáTë_[go›mü´X,’ÁGÃTlJÔ&ö|zO¬5:‹âÔêÓX‡Ãa¬Þûi›BÀ†™¯!b<Bù®¢ü85Š¢h)XBÇBÉÆdÁR(V³uYç³íá6{Ô.hBý[õ¶¬­è-V¬´çìSÅ¢Î8;hlL"†)óxÆt5 ¬„ë ^eHdc”¬¬Æ®à*°´D§‹)Çm2÷øøpœ·4ª ¥#(Ì‚z8$Rå?`¹N�ìp»Îj‰™ Áoá*h°é\Ј£Ÿ˜€-D­Dõ(GCxUöxó °IæC"ÎØ~-¼½Ùõâ¿9qÇó6Ui/b8K¤Z#x ¯Ä„› —…¬‡‰¾ŽÁÌE•~{ƒ6’Ò<®Þø’rYªù¹Eƒ¸%Üy¼nÒ{tJ UˆQ•@¬A%ÇM®w‘ ¡ŠôЊ RkÅ¥ªšÑ(A¶´Ös´ˆ-Ìhëv–ÊèR Ž&ãTfð¶Ð“Àç'ÞK³£ÛïøÆ·šyõ$Yæqâ‹Ó´´süuû÷O¯ÙßšZ¿'Qo³Q¬<Ñ^½c‰„z_€!7ŽVÆíŒ¾Éú&+¢vÓ×°}Ǽ˜ÁÜwh\ÎÖ4 QÛDz ª‹Ü(Q-Le’ª•‚Œ¥–h/"5:QBÖ³vFî}0ÿÌÕµÿùE_¾bˆ€L*Ãë"_Ò˜áä¤Àü 9^ͱËÃz-÷¹j¾ñ¥|lN‚Å"V1A­ˆÓCÔBWÅô æÃ¾)™Ë¼ôNð€JĹ"v;5*óì*p.<§q<5Á‡d‚>‘¥ð¬Æq…Wàg`ƒœ@„,ì(aÑHiì„4f‘4ªÖ©8àJØÂ=Ÿ¥ëgúá îz™ÃgÁ&ø�ì2~ï]Ë@Y°4X »á ˜ÀAh˜­ñ=¹0.ñ/-:ãEZ‹ ÃSp#l‡ó'mÆêaÒØ“пÛ<ï{té ÑŠ©Nöÿãaî— IMÓ’Ó“ã‹Ç^i'ĶçÚ’ IsœÖp1×4Íp4ÏEOÓ”÷_¹ß{Ò[»½ñȵG–ýv™¡�kÜØT=“ó]nÈ4©Ab&Ó\xÝÑÜq?åêF-X*•_i”eY‘”Ix‘Þf¿2;)&‡;†O7½vÕJ9iÒÊSÌ&åܕãýs\.—Q‰NÒ‰ØrÍ–ÁyƒK¾Ôw̧iZÑS4e Í:ÛÒÒu}¬nLž+÷Tê%ýŒ߯–ÂÁ2Ú~Æ„¸¹V†Ç$f¦©R>ó`îï³kèô.xpiR©9Çæ”J¥ÿ ²û»üþ.¿Íf¢ñÊþßÚ—L­®FàMX?ÕiÏóghÎ3VISŠí:¿SðCƒÆ/TžS@ctÀYµE¬‡Gt‹¬U¤Z'>‹9c´'D4”�îʬSùjU%ZtŽë¬ÊrÂÂj7ÖÎ,·æø8¸T¶éT,?%üêGsAœu<uû}ÒWÌKGÐr:]5KÆ2¶öý÷ÿ$³åñ˜%”ûÆ‹Âî¨XXäëjþ“9\¼:ŸÖl5}¾¼ÍDTä~ª²l%Ý­œì'^Cê?‚uCØf¢TâÜ[ <žåÅ0—úñqS¿”ý] 2ÛK¶ƒ#§è‰2M¥»È ?)Å,.¥’‰5ó9˜Å±ŸVë õi<~"2露âR°{²´Äø‰›P‘ú†ú©Pú¦7¬ì;xIó b¥XÉøN–×2ÖÃÜ#Ô™8L]ÇXdŠXý”Æiª!ÐG½½øv¤ €‰~î‘8'Íx‚p–·ó<\äÂ"ÒNŒÐâ"›E,b+ æ8žJ6æ^^Ãw”6]œÏÕdx¶DBå:‘P–­ì:¿/ðc¸ÞÖ°”èÓÿåâ/Z/Áò殇u\fyØ”¢64PÑË&C2—g9!2ׂێ;OµNC‘›K,÷2§„T"{ácP -E•¡�-"ãE–ëü�:`§ÎÁ&³ ‚*½•ÌИäq‰Ë5R:Ïé4–(€ ¼³X<þý¿ðëO16€}°Xg'¬‚õð”À…çè8áƒðKè…•2wé(ð+h…aX§sþß¹ò#:-ð<ˆà€m°¶ÀÀgVW½½½o¿ý¶±/†Àéã`Žô»]§Óiú8L-5¡|Ó ÖØËØq8§ÓiÊÍ:ÌÐb75XA‹rbF¢óºÎÀîÀ;w¼£ zø@ØPµÛíUUUv»½}¬ýÉ+ži©ÛSwèªCž“žš5àwz†=ïÜôNÕUåzQf d³ÙLÚ´Íf›DV6m™Œ;4ëKN4×Ç”U4¦ÁŒúÃà5˜¬z£÷c¬ªA`)¯Œß²é¶ŠÁ ã‹n1}§Lö¶©ŽaòòÍFãTyr8-×Ñ0ß…9Œlêöúb>û1{lf,x(hÈÏ›íL£úœ$8›lJJŠ”ªKù»ý¶‚ͨ?LLU–媪ª`0X__ïõz èØðn6×¼Üd*D\.êa>—É•05Ý'ù¶˜rïÃK†5‹V½§Úí2ߣñ¡56"¦L¹GÚT¤t*ùÕÕÔtå( < ¯Ã¥P€-Õ)îƒ/;9ßCe†¨N5\¤1 šàAÈ Ï ü¾]Çâ ²H¿Êf¨Œ"YÈh„2DK|E Sæi/­_’9ËÅÍœ7Î| {´büTa“Âv_˜ %–‹4Dg4ÿúÍêŒ9“–ÏþâòäØ�1JÐâ`fiéÒ¡ï÷f~ü}Í)|óueÿkîi \O^Q]¨øØß”Ÿ†¯æQl‡"G×ZÕ‚€¯f8§Ì¦Á§ãdz–åQÆŠÌLÄ×Bo†¶6æÕ°¶›‘õ6ÙØÆ}ŠÅÕ$óRã£)Æ! þvâ!&4¤FN5Ó â5Y\E,^е Ѓ¯‰X–À`Q‘Í"Ï[‰dX• ÅaB´F âQÂn2tn%[‰5H|/ivÅ*¢§¨çVËTˆµDd¶2s£%ƇгØÍ†Åì×™>Î`5¹<}pATãݼ–å·–8iÐD|ÅÜnËèü™Ï¬Ï>ñ¹äÖU$ZüБÔX©ËS§²ò”Ìm•øœ\6ó‘súþ²°}Yé ]£TG˯—ø…Á(ER°SÇ9‹ª>W`¢Ào¡4³4nÊÐY¢ÎË!Âø¥À5 øŽÎuàé¹\§ ~ ñS¼Îmi† ŠìiÒxÐÂÐ PŸßùubU<¾!…ø.ý Ÿ_ÍιálxZg¾+˜~€‰ÿ€Wágð$¼ À¯!OÃM€°F >Øôw²û\3]moÚþWù¯õ½õå]—ËeðÁ&9™ÑÄSŸ„ª•3�Ë›%F80£³!ijÄ,ƒnBpFÔ6øÊ‚ ذ…ކš_n>ò•#+¿¹²úpµÝf·Ùl^¯×áp¸ê]Ï-~Îjµ.|eáæõ›SÁTÁV[ÓÖþuý£kF+û+ÝIwïY½µµ–œe’¸™KŒèfd”r9ƒTm€iæ9f’³Ûíå(å~Sá&?ÞX[#wšÍ3óœò™­òÎ_¹‡–±næòš#Õ“¨†:†©ËLs.ØHÞn·ÛårY–Ý9·~D/zŠ‘¥‘à@P/ž¦W˜p®‰€é=åtDW6½ÖdÍ[Ë_¨ß}>ŸÍfs¹\¬—Éd²Ù¬ôæóyóÓ5uzoªÆ»©{œqòO“µÞ {}ôXÍÎ÷°(Ø ©pªóÆNKÚâsš6ÖÆ"ÝEÕ¢ªéš´s¹\�kÆîÊ$”J§ÍDŒÅôù|‹W¬}×t•wªâÜcÂP  Þ(µ`-Íò{/`ÈZL)ˆÌÖy®–8bI$‡áupJfw–C‚À‡u†ó„J´Î¦9ÃEÃÌÉM‡ì!þ’âJi!•Å.")†urŠþX¢ëzm÷ ]—ƩǣÒ)`óµÃrMQ|l¡*enÇ�� �IDATíSOYn›¿?#}v†ã+·EgïO~î‰Eߺ~ô¶{ ãyïÓþówŠ7c{'Y‰`Cv¡S&夨"בå;zmƒ­¹ä8lØ𫸠¸Gé–åû9ö4æ™5LÁJýÃ9hìʲ¤’BŒ×J¬-`K’§õ8í'˜á"+ %¬E¤~j(cS8òˆ2UDN²ÜÍ¢0 ޱ8ßM:‰Õ†& Tp@GGècæA8‰¶ ”pF˜SÁ3fŒâ£®‰õÃìj!ž#w”ª0Å“T% €¯DsÉþ7×U{ Ö\÷H‡N(ÀÏEîÊÒEI0=ÀZ††%ö‘ðÐpÖüeNæ›÷çGÚ„‘ÈDE-9BÕò<æëvŽ c±Q# EÕ¦æ¾}£Žì£2Ê‹ÌSéŸÎŸ¨H¢_æÂ‡D>äÀ«²BçA¸Fd¶ÎLc€H ¢"W ì•ø´•¿XÙ!²Ja%ÜæäV(r fI8m4Éøá. í\å¤çÆB<ðy…Kn„·A‡1.ÕYæ¥�—Ðùu2;Á–¶°v£xÝ2Ý9XGd ¼ÐW€~ÈöÂ2Ÿ× ‰´ê§ý®ž…¾òÞU÷x÷«}¯æýyûˆ]TNãZn·Ûhê˜[W3f•wåžåÛ[S©Úè=L +Lt:R‹æŽµ\Ð(bN3ôê6× FÍd䌼3ÿNÇ;µýµ¯Î~µaGô§§é’î:éªè¬è_×_ª(ùü£sG}ƒ¾ªÞªíŸÛÞ0Ðà/îjFÕhÄ}Y–ÇŒYG¬"ÿ`7«é¢nÉ[ ·ÓˆdéΡ/÷á-SÌåëfÖgæm”''“hPNH1ÎI§Ó†Æ$®\)*9=9>g<”Ùe»©[1)]y<»ÝîñxŒßJ¥Rþ!º&›óõùDM,Oå‰!›ÍŠ‚¨‡ôæ¿6{=æ#—Ï6\ C%2‘H$ ãeì óÉòýÁÔ$dîfLËGñL‡Yu žç÷~iïÜßÌ­ÚZ¥ëzÉYê¼®óäU'Û7¶¬uÑ3æ9Mm·jËFçNL›È2Î~§  &›Ñ¨,à 0ßõ$% ·Ûý^é*ÛÚÅgŸŸ¥óªÄ:{i¶ É@dáo…™ð¬s+hRx@gN«@œòâ)éÐ9 Ñêc[Ž=yÂ:ß ´ÃË5.ºÀŸ#i¥˜bHåå(ž½:بôðÁk$d…Q•F «›U9~¦ãhÍÐí§ÆÆìÅ/YVF«îø¼µm1Ÿ2üqÓ%Ù™ÝMyÞ÷‡•…öÐŽó²³ãécÕŠ6”~ö¹Õ†’ØíÈqV¢9¼ì©@³çæ'›"Ro]‰žI™x,l®qØz7Þ&<4C£ÁÃÂHjA‘…ysHŠthØœdr$+b­”L¤›‰yÈåØœÃ2BK% ™ÂB:Ýd»©ö@±<„§ÞAÚCÁæ!¹‡šÎR6´áJÆ”áïŒs®Š#ƒµ…>v[hmÀ’Ã!bu“•±‘u#§ÿõ¡tå¶ñYÛôóú¤3g& Ïé4ùpL0êe(ÂH‘]v¶ÙYãbp„û ~÷Ñ¡lãN©{%ÔAþêfa–Bž ÆEžñ2«DSIµZ^dpÃaoæ¸Nåe‘Z‘Y:˜à¨iVZÝDJ< ‚½:Áƒ"µ:#^Vë8TÚEšE¶HLƒk,L·1–ä¯Â·( Ä˜@•õ‚ÆÛ7Xh9^à(lX¬3Îú½¸|ó 2oÃjˆò±AZ^’îø…~r¯è˜Grñ ØX™ä¢=Îü)ý‚N1𦷶ÀÑ¿ ×^�wÀg Â0MãnèÓù 4A –Ãà?¹ ïÛºmëÁO¬ÙQc0¿¡]#Ž˜¼^CsÏüŠº\.SýÁTy(?L&Xyh6‚²9+c†WsïlÚŽ”—kÞe Œ_ÌkùÝçîž 6jÔ½«¦+x,èp؆l'/8©ZÕ/ÎŒòþ¼cÂá“}ñ¹q9$Ï›iD#¥qý‹ûcÓb¾C>Aû'¿+«ÕzøÜÃ"¢oÄgúoMêüwkøBÁÚÈîF÷Åœ©2ÿÝ8Çx:Ó!×Ò5ûC¦éɤ<d\Á€ÑLA“ƒg–P‰‰‘¥#Egq|Þx¦2è ˜U¬Iœ¡ªªÊëõ†B!#¤Ói‹Åâëõ%ªž!¨Šï¦XhÔ—Á€eÌR^#–ëEiɸ[Cɾ\¥¼Š}·te$ã Æ¯˜&/& [®Àdü´çâžú·ê«Þ¨2–ñðM‡£³£sï›ë?îNÌ™ðt{Œhç%YgÖ×å³$,鯴ñ˜4Yh¶!Íç2¾åk2)]‘sYШŸÎGVé\ç ¬†Š_„{à ×ûpæxJcƒFu˜(ìùX‰³$æêXtòUÄD> ’D³Ä0’éÐñø±¹8•àî�a/¢Î!”LæB(Í_³(ð;…f”HýN«ütè¸ufÇð¹\¼@/n©ˆdN9{\àÿH4Üæª¥*O¤ÔW"òæ8¤RË3ãÉxÕM·¸¸±™¼Œ"Ó@¿—h–G‚ þ£¥qW¤î1]*¶¹ Ñ,W åsáûi5—¬ ^ 6Ü%$;•|´!41f$ÇÌ“ ¤y+ÀC~ÞGñÉQ\>¼ó‰Ôu“s¡¦ðtš 2=ALfؤ“°S¢!ƒ«‡–Ñ ézJ:;Ç(µq‚:+³ÖñK§«Hœ¢©ƒsœ„ ÈÈR�¥–’BEŽßÉWòÈå,ß«?ò…Ãöi¶ZVÉéh%‹¸[É'yy€¶Üµi¸§×¼~½¡¤âk$*°lL4³’€B‘uY–ù¯#£ÜÏH$Ç8¨’ø¦—[Xtö€¢0Q¢à$,±]`YŠ$¼ ¡NâÇ U:óá^ ÿíaQ‰¤Âí®Mr/$t’:3tnÖx�²à“øœ•æ¥ 5%¾Ž"› „A’iÑ©X}‚®ýDZa·ÈJ‘jN„™«ê?üç[ôÏ¿ˆ÷U(ÂR"—âjfÉ Õq€%Gõºc8,ØàvØ€oÃ�ì€7¡.A¨ƒ�xà5¸¹ü[í¾¤»ä,ý¯šÉ¹\Î ï½wWß(¤ ~¹‰,ZÝFp/&0 ÈÈ^nMbÌrWE± NµŸò¼å½²œ´ì½|¯C½ƒÞT}ʸB¦*c÷ÛįÜr¥ä’’íI#?u‰IÙX4ªNe‚É*™í"óhßÕî óÿË‘ÍfMá†I¢M&¯Ï¨YÍÔò÷cRÁ‘lIZ2–¶§Ú<§<û®Ý×svYǘFVFj1& ñ'©+‹©š”‚’ÿûaÖ¾æ0iyM9I«^UÕT*•N§‰D*•šZ¾aFãÃcŒ* ‘÷cþ2°j uO«à9N÷)wÉ]깪'Þ?ò/GRõ)ÓÃÌÑï˜hȳ™ÊL¼5®‹ºYÅNšSËŽI�ìûPµØ?[¿í‹"~ðk|¾‘æ6¸Tæ…µ+TºšeêZb *|\Ð#ìF9îÄ',*ãn…¥u\8D¯ÎUp©y(ÆwŠÄ5j»Ø'Ð,ña•ïKÄkY2N³BE–c \=ÈÑ*šŠÔ“Ó±ä8»–¨€}‚Ï <úð#¡þêÌÖÖ ªkˆÇ»×»~FÕ[¶Îuäm%½òø³ÏþÅ‘W¾"¾Ý!;> ÿäåª{Ö!¿ó^ù;ßÊ(þ™¼rˆZètë¾ÂÆße™¿öDéK?!Øp 8Œj|-¡~ÁöV^$˜Á;î"Âla’A¢9jûpKE¢‹‰g©ŸBŒ¹¾²œ£ï°ª’mæ ¦q Zh¿›ÎÒm2sT|ÍŒ¿A•€k‚lŠb†žv<ãÌœAt”Áš±“~M3è£o9©-|Y¼Q„³EmDŠX; )X¬´4Ó;ôûOè×Ý+Ó w5~ì¼È+ŸL¹FÄRlºB¹óví‚MêÒïæCVVYè¨!×"5³I”(Ön+ÝúÓð—×ëì"¦Ò!Ó8ÁCiB%¦ ¬µá…_噓gTà›~¼"Îëzù·:ÍQ# µVf(ŽòÇU:_®&0È¿ÂgtŠõøFx.K¤È-:E¸³Äï5>¡“—‚ X YøÌ‚'JŒÂrð´ÈÛé=ÂçUVA\åk:~¤Û¡åy8j ›3>¨ÍYɆÇõÍ34 p'ÝËäKõvë÷ýœ//Ô'žJÐ¥ò1ðÃ'áuØWÁ7aÜ?‚…pÂËu~–b#ˆðOßù| ïìs¶ÿºÝ—õIöÓ\‰X,f„BÃwÃÜl¶æ4Ïûä –«Öžq@øÖ7ß²yåÝ+³Ù¬±m·gícçŒi’&"V­ÜñÕ’M ö_v¸µ¿5jž\zòÜ=ç¾°ê…æãÍÙþ¬Ù¢Ðtm¬},Ò)9J »,š¥Äds×)PÒK†RªÑ´0¬ù AÅwü5Js´¶üÌI¶UåââåNgœT›Dû6•®Ê/˜˜–HLKÌzdx5ÐVl‹ÌŠT©U‚EÈ…r;¿±³ùoÍ­/¶±XL–åd2™ËåŒdSÒJǯ<îíöŠY±¤–Ê_bù­Nª¥8“¢±/1Y怚1ŽVÞf›$??uðÖ„Iß#Oœ¾;’"•“'ÿÒÞî½´wß­ûüdcÌñÉâ]5¾>ßÈ’¡(Ìùï9þnû³r’ÎMdÞ•˜OÙ­Ù ‰¸FÎLxLà°‰,W‰èŒÂCLË#ˆ +ä,thœÔ¸$ËoÒìKÖ8mÖ)tç™$™cP¦VgPC–°¨Ü¯ÓQ5úUÂ2’…%* <]¤^g@fy{œ¡oäX¤qÄIK ‡ã<èFÔèÌ»öu_õmP÷]4Êhk÷J¹9ùä/…Ç.š[ZfÛº,PFK>¡f›tð¢ÒÆ/èß½2òï¨zî‘ü‰Ü%ƒ…’ÖY÷eµn¡Vwlø«Ï)?¿SýóWÙ<Çö\<uŒ%2CôäÑ9aå¢ì!Ɔ©µ¢«ÈMô”ˆÑZA:BÆIWG7-.äfF޲HG¯am‚ Î$32„Z9Bg=^9Ë†é˜æ##Ó—ÁZO¶Î!Rv2yZƨ²àË`¥¡Ÿš'Wà¤ew†Æ4Õð¦ÀV òxì¨Eº¸eÒ2®8.r/eÏU¯Òò ]Éì¬Â²ÃüèûzBÕñÃÆ/É|m°´÷ñþ©dô…œJÑ&uOtfLÿÑoš¯¹4{©HI#îÄ ¥ÈY%’yÆEG‚i:c:ŠÄvâ*kF©,±¹À¬œJ!ÉÌS#§³¹�%š“¤\4:ÉøU CTÆyÁ§¡¤óQà>zuVìÖèx–‚n—¹UbšÊ~7·Ø¹f‡Ð­²�&ÀW ŒpIŠiy~1rPWÃbø˜8ƉŸórƒ(ÀeP‚f-{«<q¡ö蟘ˆ‘[¡q5Ì€;a Äáf˜'àF˜+á$h-2=ËaÔ™``ô­èñûŽ[Ò»Õnn½MÀÊ€ï'ÍÆšLå¤�³Ç`"N&{ÍœV1y\f eÖ &{ÐdNr1EÑét™2YŸ;>ã¦^‘\½o×…]ÕûªE©{³nlþ˜¤H-G[¶^½5ê‹Nß7}_㾎;Þ¸ì iPÊóù`^©RÒuéþ•ýîqwïªÞ¶×Ú,1‹I©0= ËÈ‹Š¢¹¤||ØŒÅS‹A:£þº™fŒ˜n,š9»fè‹lÒ)Íüd´MXP5<e›<1gB“´ðþ° jIÕ­z÷µÝŠW¸p`|Éøúo¯›;–æƒsÁ ‡­¢µØuN—}Ì^·­ýùÃX6ûïÍ¡/—06E1Ê%f!h¤ör¾å{kNMŠæ —J¥×¾óÚÅ?¹X/èF=§iš  ¶¬­joUË -®˜Ëš·×b±È¢lÏÚC'B¡Þ#ïÌI5¿Ú4åMÂËÿԻʕTº\ iL¨8`¹ÈÅó`3앸š3ä4Nhl„^µ*ãNœ~^I3—'ð texJe@Á›åOO4êlÕY£qÑæd¬@J'«ÜX½\–Cö å98ªpòbœ¶:fÙñ™UâDœyD 9ÐÓ‹ž«¹¨Îöý5Eì%^ s~C] êUa½òvh½ŠSùÛÙÊÇþ¤Ü*ÍòZ~|MðÕs Ï/IÿûÃún‹VáÃ/©K²$Ë’ƒÒc§&î•í·^dzUÆŽ 4h8휟#™`§Ù%ä,.)A–Ãsû©r¨Èô$=*‘ *‰2c"Lˆx­ä,ì,âHàp § ŠtM³9â"“¥AÇ·ŸVY'ºÆ(U㉠çQ'´b“ÐÃŒ…HG‰•¨±0½ÄÌ ¤4‰åDFi²sd˜ÑqY±PòßýcîÉ ÝGêŠìÑ9_bšøç 3†¬‰ÿgîŠw/Ê1 Ì®rä*­½GCH]49±'ÛlÅËö ½¥~õÓ‰‚]ãÏ9~£sD£ÆOꙥ@š5­Yuzœl‡«m\+QJpp²Äj‘ƒà*ð¬FUŠÍV‘jËTªø¢E6‰,ÓiMñŸ"Kt.2üE¼Ö Ã3xî—×½eïÉÉ4 Ü¢cѩؠãU¹®/²«ÀºîQyNà“":çBZ¦QkßB½Ìë` À "ì•Y®±éïßʹð(Â)Hjl„« ŽÞp6� ¡ Þ„ è‚ x6ƒ1|ù¸ÆS“Æ„·oßn*>”÷cŒþüÔBÊà LÕ©;ãØ¬9X:)ИC»åÒæ&‡ÐlKˆ¢èóùü~¿Á}w8oêí5Ϭq—ÜåŽJ%©”ªIY"5¢ªqÕ:bM5¤²Ž¬#íXõÀ*Ë)KLŒª:4í±iWt&Û’™™™d[2ÎÍy~ÎxëøÌ—f{‚F%Tnó1U²¨œ´V¬Ï¸§8M èÆ(•A?›äÑ<©˜˜ªˆo2&ÊWU³k{nܳüþå&ÓwzOy“³“Ïu´¿Þ.Š¢êR3µÿ _Ïžþù|¾saçHÛˆ%ci|«qÒC·4IxþŒ¬‡r}ÞòóÍg1I Æ#—Š›¤üØì˜T’ä‚ü?¦«IGlvlð¬ÁYoÌ¢Dyv4Ûu“Öj’8HyuRº*WS47&á% –§«©÷-ˆØÒŒi¼_€!}°SÂ5:‡ K@×yjàlz/|¿Ä§R4ÀtX oÀ[ÂrŽó¡·Ð�_†nXo!aa< gÁ/’\˜d9¼– ðqy wŠÀ–$W*Œ*œÔèY.²w‚ý’P£Ú‹ÅMÜ qâ: šú½'…ëH!g(’vðYQœ·¶™ù •…`çc·j7Þ/}æCúcJ=Uƒ\í" ~ä™Ü=÷ˆ­Ú™‘Ãm¥×U¡¾‘ñS4H¨~"Q^+1aeEž ¶S,r gÈX±wÀâm)r39`b€úZê8‘…8i Ût¼3ˆ«,<B¾ž½c´L§³Ÿ:‰L ±ž¡Jz+X/aià”L O)·ƒµBy «ÊX=ñ²ÂÐ)*òXºˆpూL=µb—k¡sFˆêû|ø¼ŒQ[ê­q‘ˆM%¯“­ÿî5Ÿý¥x™ƒ‡æ7vêùáÆ`º®"Z™¼GÔ“½~.ŒRù¸F•ˆ]à Ɖ‚:d Rà<‰ª;3ü ¾Û,T×sè$ºHP$¨¿ÆIŠ:lÔ™'°H##¢Xø¬ƒÙ Æ@ ü7ð%ˆê.|±«ðªêBTù‘ÀÍ ¸ «§%ÓUª@€ë`;ˆÐ=ðòƒc‚:[(.Ó:Töxa?¬„?Á…»�hÀÜ ó¡fBdèVÁ¯ ܰ^€Ûa ´ÃŠ¿ßêw¡þ PÈÁšÉ*�ËTË “ XnE?UïçŒÆQå¸ÿ{[L<-¿1‡Ãaô± þ·1êkÙ½E¯ÝnO¥Raj·×j²æ°:t]/I¥±…c³_›]ÿx}^Ͼ×|Çn;¦=¥µÿ¸Ýìjèn}ëg¶ÚÇí¡£!Ìñ˜»“$º–QtNË)—O-'I¾‡î⤰n²('ù-½ÇE¦]wÍøËŒÉ‹©ˆ­o´º#§=5j÷Ö– ¥C—²¥l3ÿ<sxÑðÀ¬KÄb·7liÐùŸÿ–¡¾h*ýƒPðwNÄÿ¨nn>”q¦éh,BïúÞÆMhàŒ©åŒG¦6Ó{qïøÂñÚݵ‡Ï;Üöt[ùÀ»Üþo.š{”÷~º©ô^Ÿëxà$Da)´C«Æ,™OjÔêôI–À 'Mnöê< +2˜a:Øá Ì*³‹,+qÌrP4^y�:~ÈÂ`–tŒÿÒ¸‚Ð"ÑV…&ñ¢ÆùðRŒGj9á¢}RâÚÇÒgïWéÕùƒNX NÃíåC2_Q¼,Ê‘O¢&ié%ëÂ/cSÖmå{^ŽøÉsÝ…ÏÜïa®Š¿›ü0v嘇cræŠkó›K‡¹žLé¼ýÜuN6?SÃgä8^/U ãÔDñѳԉDòÌ_=™8{4þ”æõcÌÂ9L(O*Daù4¡ý4ÚÉûÙ‘@˜KÔ†ØHE#³ÆÐ¾ž1;©žAw€TÛ�öFzæÑ×Oð$GÃÓ‘,زLaµ GE±Ž²k”·0â €êÂF–©Å&㤊iÞ ²;9÷G©D³Ôß1‚ZÝD„¯þ¶¸éJµÿGùMŸžøÔ£ÕÄÜ|17>Ïò›ïðâÊÔÍ?<{7/~ÜñèåÂ=Ÿ.õïÔId9.±JEÒØbç8a…m0 ¿ç`·›+ ÃJ‰Ñ4µ°>ÆÙ^®uÆ8¼ºÈj ƒ,ÕÙß×ySE,á ¶“ƒ×5vÃ(Á1™/±rœOugøƒŠG%éä6†KtÁV™9^³³ëd4vÁþ«ÀÇÃô_§_÷$ïbÚJpÀ˜¯Ã]ð¸þï¦!ó` ´Á1¸ªaŒA~XÍga-<ð]ø \ /@ ¦ÃÓð�×ÈÜ Î˜L±Îònù{ëiij¾1ÁŸ÷hq™Íùâ»»nÚe(~¿? utt,]ºtõêÕsçÌ]°`AKKK]]Óé4u™p&ÊHZ©¾äŒ8ƒƒæõóù|Íý5‘›#ÿtV5JÎØ4ãÿ Q¢|רÌŒþnǤi¶©l·IDmûß©åŽùFúVõÕ½]gòtßÿáí<Ãã(¯¾ÿ›™íE»«²ê²dK²eánc ˜00-8€!@à! „TBB ¡„<@ BxB-„P 84ÇcŒ{·d[–dõ®ímvæ~?Œ3Y$ $ÞùàËÒ5»š½göœûœó/â£;>œ7Øq|Çê[W'9F0|ð¯ñÓÉÚÛÖv—tû7úkþ^S¹±ò ~X“hüYKñ™qäŽ64¿÷ú½YKÖþÏãó•õU·ºã‡;’Ádããiwzï¹{÷\²'wMr•—:ÏT 3!òcöIn·ÛØ-ßÛY­Öx<nL³Lû´ÏƒZØ™èeùOA›•ãT^WÐ ª`iëúiÎæ•`‰¬žýÊ%Ü÷ º5Γi€§4öÁN+/è eÙ~˜�×k|SçWn®äá(bˆ­CX4þ{àô U´¨4í³=ÀDÛÏËÒÒlC,>¥ƒì«ÍFžÿNû–Ù–Ç®.d8E�ÊFIi«Þ”‚i¯í‡é<¹ú-®º¼æã™ 3TEj Í¥áêÞþ<Q³¥Îºt£:K·ÒrãÝÙóß-{ôG´ÒABùƒ( r)éN¼ÒvÔE~[€eˆ…î “%"2K#<dÑ&ÏâÀFJ@/BØpP˜¢S#ÖFøKìßΜ\)¼ªËq`—‘»ÉÛF†'ÈÑ<¤vüÓØoeF-ñn}T“jà@m›8Q œÈ¶]´)¸šð†h°ØdÝgÈ e´©<Ûè %‘* ¸Wš5tÒjk]ƒ~Çæ,¡b.í±Îï½ñYn}®dÅOKÖþ0&v´<xO*›.~á‚Þìæ¢¾Y™¾¥‰m‹Bvµ¶ß%;H·Î•àÍP,S�•:ûUŽ‚¦c—ø¦•R•gdæçSçGòòíÁYdvòøšŠB(LÖ‰” z™)ñ–„¤1XÎñÝ< d– >R¨–¨ÈðvŠ»×@3Ü CL{æJn†ãÎÀ~éøE’»S 3Ü–Áa6*œ'q°®ÄßÇ÷U^]Æ3±ê~žXNC+•½´yá)pAî²r†ÊJøhðSI§^ƒ ¼3A…¤y¦À ßÖ¸Kp.�쀣à<Ø©qüâ‹{#ýëÿ²P½*`IXb±X®ÛÓÜRf Ì=7�…ËêKµkv›Íf·ÛM†P¥àîSï~bí‰D"sfšÙ}Ãî)Oɸ2ëî_W| ø„gN°¦­)þµ§vv‰*á,sÚâ6 aK¬ýÑZW‡K"¦Ö_.ÒÁ°ÌÕûTK”Ï’ ÿ‚ºA_¤~:63 ̼�� �IDATs«YKVR%kújâšCÛóµ=óœg¾•êR×ß½Þ3ài|½Q 6þ`ãê_¬>ñg'†–þf¿ï°¯ho‘CsXR@ã~‰Ft6”8ÆèKE"‘O½l£ 2]¹×§~:“-0BÒyV§ïˆ/Y’TóT³øYÐ!„êVw~wçñw¯¤”C—˜5pâ='6_Ôœµg͗驚å¾ñŽI®¹&cÄ™rñú¦ÇøöÃØÙU4éÈâ·Ð¨Ò HLЙ.xK§]gm‚3¥ =üt%7vqj¿4Ü'jŠDìç$É8¬ÌÒÈ‚ 6ÙѼ,U©ÒÙ ¸ ‚‚$ôX¨œ•G äçSÖË”Jôè�‰ù~;C…”ÃïK-ÞÅ3]ÑÊ•í¡‰:‡$ùx¦ võÖJzÝŽÊÍ5x<”ËtxIgo~™¥·º/_>µôÃÛõ Å3 7#u1eˆb™‚-{.eyd(å{ëNÛþòÇ–[¯ýàq‰ -UÑ¢øu|nN¤2úâT”Ò&¯î… «ÔX(8§Æ„0¥6™gãD5f¸ˆVÑ“áè‹‘^f¦ƒÖ2l2yAR1¶ SàÁã#\C¿‡ÎnDo ™]TžÈ† I— k#$!oÃ9ʡɤ?¤ÌB‰‡©>‚1g«ï/ÅýùÈÍ©*mÝyÒ¥)ž'ä]úâ„ïÝeQË"|°ƒW~¤}ù]ýÖï¤ßÝÒ/²î« WºvÝ躓JCÕi†ÙGjŠˆ÷0aE ÁT/2?ó3ÅO\¥ÄÂÏa¾Î; û%X¸V£S¥K”d_ òáCÛò8'E,Â!ø—oú©ˆ‘UY©ñCè< _Ó¸AãA™…Ó i™³>ÐøÞ^éö÷˜µ :hóÂ(” ZÀ+ñuAµLX5žÅ¶ˆ+Û¥»ÖH/æó¾ŸãSô{ùéêÚ¹æižé„ \uЬçý’š:†ЧpB!"Îj¸‰9IkõRѵ®„ œ ï@žN vCð €à†£à€yðѧήÆƒ(c|{ 6­yà”Õª¦-é´7m¶Q)÷ëšÛ û¬÷á³—+à½ñ—kVÕ ž88áÈÇc·ÛKJJÜnwuuõ¥–KŸw>‹çÃû¸»»[UÕp0œMdË·•7}µÉ1â˜÷È<«8†H4•vu]/\S¸ûþÝ%;JBµ¡CËYÓÖ~s‚‰’ȵ±0•¥ŒO—˓͵]7ÐnÆ*åö¬þ¥›3sŒ1"1ÌŽ¢ÉÍ2À)&e*ZÝðÓ }‹úúNí+Ü[hOÃy¦ýéÖe­Wøû«—Å\~Àš¶.º‘œ••¬RýAuϼžxq¼hoѱ¿%$kÆj¬Õx®±)ïk^R®XâçäÔ\“™gB3 ’¸èóòò\.—±ªF 4Ò8bÕ¬k+Ú–·Õì®1a†À )peá`øà'?8Ùs¤ýépCxÖS³œ#ήº$$›ß¸Ɔ#2!bIX$MÊ{L:’¡)!%«( e¼Hÿ˜Tj»¹²&_D„)dãM™A• `ª‚Eà™!S&è–¨nÜ%öVrKO×Ùĵ/Óæå nqÒ&.S's¢ÊL‰L¿J¿Ä™:çuî-ei„%š5NÉŽrÎÅ`“9YÆ6…Œ‚ÍÄ(Þ2ÎðX§5 Ùþ|aá²Aì‚¿ËDSLéEèŒJvWaÃËÌí±½ ÊÕfuæOF.Ý¥úô:’)kðÛß)k Æq»(J0!A¿¡ ÔªtúY²U4î—꽃ÑÿMW+‡ç¤ñêø¬XKH蔦è·Ä.‰Á’ Xpö¢ RVä$1+áR¤a ;¨¶v3œÁç¤Á޵«Mfz³°¯’`šhŠXÙŽJ”^W¥•˜›N&ˆÇð((!¢1Ê[NàÐ<¥^,Övq¾ »ÿ ÝàIúŠb7ÝÏêRù¥³Gfí×ê·X!k‘®^tÄ3óc×÷kÛ˜ãP)óÕë:K쎛®Jrq…•¡>z2{DÿTÚZI΢öàÌò TF4Ë”yÐtÊœ5Š+CoUq~Óê”HTJô9 –áï:Y˜«Ð¢s] ›“NL'”†Qx½’FPwÂ7²0�>ø‡L‰›Y*ß”˜¤ñGN?ÌyHƒgÈK7‰Ì‡<±AÌ„.hQð ždoÉ|M¸þÊ…ÈÍ”VŸ-x‘¯n–6/rW/‘¬‡Fh„ ð03»¹)7B\ÐÄ+h‚—½$òúK7@'ì†m° ܰÂp ¼ ó ôO GXa*H0Nû·é*·(IÒ¶[·rë)“>œ)‹ N츨£le™ÑÉ5‰0£Àøq—Âè®äNæsE"Ì`g³Ù4—¦¨Ó_™®(Š1µòûýŠ¢«Õ:(÷*{‡ÓÃön{gggÓ‰M‘¢:áêpý›õÕkªÍäg²‹ - ›ÇÖzI«„ššòö”º÷ërC𘹺™_ÇŽR©Ô½1é*W ðóË)£qj4-sÆ n“I¶5h­v»½·±·k^×ìÍN§â•ñXMÌÝëî8«ctòhà` °;`¼I¤2Ò}J÷¤w'Õ¯®ÏEЕl+Ñ%ÝÓã1n–™W>+]hŽ\â×ç§+CÖ6—EkÊšr|FóÖh›ˆ £dŽž}Tø„p‰¦¯6Í¿k¾SqæNÅÌM€ùt Oºðí÷éi=Z…¢à`’Qœ#N³±i,b×»ûÞ„ö¥ŠRGO9j°Ûíf~5d–„†Ž¥±)1á‚c€²_$]E²¼¯áƒ*™.?‘$Iñ,> ¤¨Sœñ.MgÓ“áóØÕÈÙqvÆõÄ<•b‰6(-¤8λvæ(LðJ2èÄê#”džº蕘&xBbc‹#lõ2 ÞÈR.�>NS)ŒÑU4”Þ™1Ò»&Á›i¾¤P¬“”ðjìƒ|©ËŸP †î~RÔµ&[¡?=]i/Ìftõ+ë×<ä"æ!æÍ04(·âŒðs‰-y—o½#_ðgÖÍ…xÓ&±yST)ØK±…ËSúòGÕUò’è$+z)¡®~zdF°ÆV°„ñDè¥Pà ãq°s㔎b‘iÏc¢`ÈOb”U¦·ReŸy˜¡4–az²ÌI"ã®$¡7@q-AE5 YE q¦À!sÄ‚VDo�÷H²Ï¤*Ú¥ß~[¼sÓ[²5¿wÔøGó³eÝT[ˆÛ¾÷×x¼Øõ§%ŒäáµQ:Jvîì9‡ÓÓ[Ùž²'i²:YÛ/¥ÚlR"¬RjEÕÈ‹ó¨`ŽB™B8CQ’´„]f®àh!“b ØiµPæ 4C… :·“Þ+e–X˜#HÈ d‰ v‚dY•f©‚°Ÿ}“X4HJa…Ì5¦Ù¯ÓÊé+ùÃótžˆ3%v}Ⱥ<zšáÛ°ÃÁ‡34 ¦@ A‰‘É Ö‰‡:ÄÞ5t\iÝ2¹øl9trùvv…(š\0ŠbfGxóLè„M#‚ÄÙt6ë Òðœ8ÖAZàB(� üäÁ$èwaA|pFnºÚ°aƒ¡–4&lå¦+á)ἃyöf{àã€nÑã5qïa¯±áõx<¹&ŸÅ1݌̷µ0ÂhÁá‚¢E†.‘¡ïnN¼¼¼…úÂ÷ï=éÒÛíÝW»oÛ9Û öÏë/ÚWT¸·Ð¬„Lñž‰y[iº¦É=àžõ§Y®¤Ë µŸÑnÙ ¯¬\)¸<&ߘÂÿ"]zz¹É/WÓ!whkçg÷‚îò·Ê‹6Ù¶l Û³¨Ç9ìÌ;šW´»èݸ$ÑVí¶Ú@_À˜¢py]×\qÀÓãq÷¹áS¶8Ûub—ïˆïóÓ•1¡£5ib*qä2WÀ,4mYšR»¯ÝÝwr_~W¾Œ\²«ÄwØç°9rÓ•)HoöíΖ«Zbu±ÂÍ…y#yV‹µýŒvo÷à…+?¬Ó|î:©+¸=hšv7˵·ÃÎñ F3³Ù+—¦mL^M¼Ì¿MW>°C…B½Î{4%æªÜ)¨†nú¹6ʶ:â°Oé¹Qºé5Ön( ÝC‡g‰,Ô˜¯Q—e•Ê,™ À›e¢ÆIq\pÄM…“¬Ê…ªØBèY¼Häk æ£hé‚ÇK6Lª€º(Ãntõ¥dãj|äáÃ’®sÒk‹jzü½7¾Á=+|/]üá[ê7/Îï$@ Lq”K�‡~…âöP¡D]²I<¡åÃ4½)+¾(û’Ô»)uQ,cQ”œ°Ì•’÷ʉ'³k2™V†§£‡))#>Ì`1ÁaJª*%2De!ÇyVÒAÞo¦CçxšE6ü<ƒÔ&(”((G• Lõż³—}:g&é¬%vW˜½>56DíG©q£&Ìcu+Ϩ,ô’ ¬ Ù?0S›5¨Ø¢uŠcG¶üàôðžÅÙugÇ2A‰B…ã²ßYž(¿pá°þ['˰„)q^ôÍÔâ ù?ÃN)‚ùëm‰_þŸöôW2!üEew!“ŒÈLÕy#À|AžŠ ¢°2—gX+8¨‘x³„S\( IÊù‚`ɢꔀ Sa¸Ó„m\"áÖ‰È,õSÆàœo”3æ~}nç¿Ï½‹9{ˆSvqõÏèù4ÁÛ“ùÞŠÆ*“a.ôB- ~“y—*7²£ƒÌLµi“zn?7²ö(êð þGíTtɳ§KoÆOCà\… ¶É,‘9S°ZÁ+ ‡a9< >è† l…¹P�%P/Ãå0#7]½˜÷b’¤/ä“®ŒæÌ1*RX9zÞѲõeÇ4j3ÖÞ/õ–m*3osCíx_(£m˜káñùé*¼`ÖÙlÖétf2™ÑáѲÎ2ËVËÖàV©Cª»^‰*±ÒXí[µ†{¬Y™Í@›Íæp8§Ò=·{Öc³lñi)ï€ÃËŽìa»¹¡6/5÷7c$esÓ•q²™$Æ·•r›>óm¾Ê «j0´|;¦¯5o(v…]¶€cÔÜtõ»LüÈÁÎ\=300rƒAHPUu×»*×U(4/uÍ/Ö¨vµlSÙøt%I’ÿK¥R†¤É»Š1·™VÇ æ¦+³#Ø/IÒÖ«¶–n.õ·ùw¨tgiÍ?j$!™J¹’€¹~"º®{›½í—µW®¬´X,¾Ï2`9pù)OM±„-¹,ºÏJWŸÅåÊMW¦$‡álbÜ8³^”$éߥ«ºV…h‘¾'¥ëá4„N̆~˜ÄªNy ¿ ê‚>ñúïŽÿ¥Jp«Ä,‰9YÖÁ=°¾’x>UÃÖÄC‚™˜Î‹I,2ÇIôiާ²RP¦óc¨¶0C¥FEÑx?AØIž…'‡ÐàÜ,ë3¼ogz *€G!otð ­íæà;gÆÚÚÃ÷Þ–™§^òÓ ;Õ¤Ódê¨êãA'çÚ8ÚO§Æ” –ÍòÚel™Yš ÇLóÇ ó2Lð£ö“pP”åÀ(’h»S=8ÙñÊò.æ&ð%ð–袯˜•¡c˜ éÉ´ÇñXÐud™$¥=L“q«¤Üøóy/ÄKæe©Lc…õðv>óÂ8Ž0+ŸI^Ü Ju”IVä0І ¢ÁÊnüAäNœ»…$'qtÒhª’i;¥Ûï´¼·°j$˜Ÿpe£òºJÝ^ ç)]¤¤Çw+Ù…NÎMÑ݃œ(µ%Ž ¥W´)·Ý^EäòÀû ëÒU]‘ºíå/ótÞ|%Áí¥|%Í¡f¤"¸t"Â"8=C‘dsãÌQé•ÈÔPy/L§Âé:ª`ÄB­DT¡Za‘  n�;œ¦ñŠÎåP¦òú0UScüV0<Ê_µióøöC|.±³X¾s¯–‡d–¶Ày!F4þ¤sµÄ<¸ð:Ô@><DúeÍyÒ…GJ­ c­OŠä3úÇ{Øv>é‡àEx ÀR8Uª¸DÌÞ+ÞÌÀT+Ïê¬'Ü CÐ%è‡ L€÷ábÀ›ÐKàXÅ0 oÃVþ¤ó*\j¦«-…[ÞßñþÈÌ‘C_9TðjA:çøÄ #fQ"Jïâ^‹_ÊJ¶ˆMR¨1ä;âËMWfPC›5…\ǰŽrÓ•‰6§ô3™L& #}Æb±¾¾¾®®®Þ£½™ÖLQS‘­Ù¦%µõw®/ÛVVº³Ôœ÷äΙŒ o³Ù,ÂRù~¥#â0O_^v¸åœ–‰ïM´‡íc.õ³�ýfv4D@Œ ÝñÏʈ¹•ÊNtnÅf «çâSœQç¡Ë%«“Å;Š%I²‡þ%S’ö¥7ÿjó ÏœP-:Öè³HñÂxÊ™Úáþªª‡F'H3ªÖV6Žæ·çç¢L >³Â3eˆÍMÀb¸ùå˜;2¶ Æ]ÈšK;pÉòåùûòãÁ¸=b¯ý{­!5kíŒó ¬G®iµ®ë–QKð£àÁo,ÜWh×íÖkpsÐ>j7¯Í„hþGéʘ˜n–æ#j" ³!ñïÒU°½”Ðl8 ¯ÁB%¬–q€z²óùË&Þ‰fUDÊy4Œúe‰ W+Ôê„Á"³$‚s˜ûá7•6ºL±±@á7ZŠwìX‚,hdD§0NH' ×:((bwO�9ŰN{¿ ÂÎF8ÍÎ'7„pfÙªPiÅkãµ8jÇE³‡4Úä ÑÞZ6ºñì~qÔÇqÇ1ÜB™ÊIzùmñ›ÊäF[WqPmIR”¯õ9Ef€CN©¤!I†D’ /6ûJŒ2”]p]ñ eô÷1|„‚ŒçTTå#g9ÃÓÏä®rÚ½(ƒWðl!rÖ,¾BÂh¦†°ØqÉl R ,Á’&0Bw”ŸÇXn¡Ó†ì¢s ]Y.—©r ±ÑC0€[CvòQ‚·‹˜d§`©!7½Zè wgEz߯ÁŒÔËÁ$çÂÚ‰xÒµ}©ëoóõÕË¾Ó Ž–Via{Í~í¤ýÙoüMÌÚ]øõKÃÚÚÙEæx¾¬°)ož“lù³vT“¹AÐ#qÁc!*S8²tBÂÁ,+¶,½.ò5&z±(t¦Ù¨°ÄÍšQæYè„#Yº ébX!‘Å&pKa¾Ìé‚«@ Ã‚¿ë¡XáÁ(ÿø?Îò¢-æÁø]µ|ø<Å7ÔAƒÂLAðZ©C¿›½¦eh“±I4èú&±F‰>ÿ´ôâ ]íGû-z �?‚<°B3Ø-º>{µôf‘Äa ž“8GbüpL„^˜ yÐ ‹àBØ Ï@58 �1xöƒÔy¦ÃÙfºÙ<²ïÉ}òœ×œçèräÆsê#˲„äìvÆÜ±©Ù@Ör Y”l/1NïŸ;&]ç]OW¦ŸV®-¤AuÊf³F™e¢TUM§Ó‰DBMª™T&cÍôÌíi|­±ÜVžŸŸo`Ù×5Å&ÆpHŒ˜Ès ô©âo©‚”f×ʶ”YV³‡iÚˆHŸqŒQXÈýD¹í¹ÍR³Ei¦´ñ°iÓÞ¸†§”Ífsö9ƒ­AWÈ5¦6m]ÖšufõaY’ÃÅápqx¸|xûÛ»¦uUn8VW™eJÓŠ¦êw«}>ר˳å²ÁL|ЉµÉ…‡˜¶g¹Šc†R‘a lŒ²ŒrÓ ç1ŽžtÔ",6MHº“ûVì›û‡¹F®Êu·Ê­YÇ(xI’dMZmI[ÿ²þ’]%š¦IYi¼€Óš® é–\«°ñÍ\‰ÛÏuöô³ðayø—¢m Ê ¢á³e‚0z/³ÿ‡KBßþ†6{ J -$þWf¢àÚ,¿†G¬|Íq^W¸AF“è 㑱ûy>É×ãTÈ<cçh?Ã]lurr»FHfÙ?‰À(”32Â> /`c‚‹‡pgøA’NÁŸegÙf¶Âõ ÷gQc8ŠY>ü÷=é‡ïÎ<ºBÄ ­„z–mMO‘i²[+ÜŽ@‚ä†÷]`ØÁ R”k .gd€G#2OÙhÓ‘»H¤ñZÎÐC]ÝO¨„A¢fRyøÃ(#Ø= zéJãuãͰS'Þ~Š­ì=Äïòxf”`Ò…VÖ ¾dÇ^LwšI„zz™¦’‘)°qAí á!&©t¶R«`´¼u A!ò€f…)°2ÑJo•#¬ò2Ký²9¾«zË÷ŽF½Å:Q6‚ßr°G>ÿ—ê¹Ùì [z¦í Ùi‹„ì#òß¶wV¹i‚|*#”ZÎÚ?|ÿ}zËyýÏ4¶C;œ'ñÂMš-x5Žè\¦³ÍG•N·‰ÞŠòU ¿Ì»Néd«ê8ÿppq–*•wẫ킄‚Ј)H2ŠÄ i|UF(‚©à…£Ï—áoð-X?†¿I4BÌ Á>-ËbpC©Î[¦:Ù'³.Š]æ×Q7à=h—ySð‚ÆØ ¯Äõçê¨pM–ùp@b…`9\ Q‰Ã'él ÃQ8fÂ"?ëCì‚ý0¬0£pà„2Ø�Ó`"TÁÒ1_ÎÑ飃S%!>ŒGñrJÆÉÅœ:=.š¬Ozz=–ËRpnðù@mtg†·Û[Ę`´_Œ¾Qfý1c�(i%¿7¿giÏ´·§9N=Oß¹`g*•Êd2¸A&ªF]Í._·ï‹€ÅË?*/ÿ¨üStK-–Ïz¹b u<Ov¼^nÃós׆øú•-×oi|®Ñ}À=æüÉ/O–$)[š=xÚÁcÕUBZtߢ\Ò·ÄSUuúcÓß~êí‰ïL,j*2|¡Æ|(cµ’"÷†š(ŸÊº3/Û4JþGJU ‡ÆcH‡TJͪ’*§èå&r3KéñšmRãñ0tÇ@?Œb]!!åJ=™žæor%—Œ57z‰ÿMûÓ$n;‘o;E""Ð-§Ñ #kôCÆ}p5âK¶¿ÈzÛÓÚŒ£ú“QîÕ¹ Ú¡~.ت…ƒ‚å‚—u~ cƒ'#éì€íºSìʰÎIñ— u~#8-Í4pGwkÔ(Th¼a~Œ˜ÎT§D©`Â,kýDûЧªäûiâ–ØkMÜŠ~ïOž×ýƒW”sµöQ…Å‘£C¥}Iguá…Éæ;_NþüJ7ËCÄtª½ ±-‰á4ñ0£eÔÆi?À´,mµ#Xw2]aÔ¦$Eä0…%Œ †F²’7J¯—‚^â}Xu|µÜ0€¦Ó¥¬€XœŠ,é,‰NžÓ¸&†¨Jð\šB3½|ÅÏánÊ“8,Ì“.™ï?žšs ƒ2¸všxìú"L‰Î}!$ÈÏЖLt>p'‡g+ß¾7Ýÿ ÛIÕs¸‹ª áýXÝ Øßº(òÖ9â¢×öÖô¡Ål/Ö-Ã2Â�ìƒ+GŠ˜>È\ù¯³Ä“ß·E`ƒEg@£Oçb•‰:£p›Ä2A<Â:£tÉ<‘aI’Ì-å ·ªØt!¬2SÀ'Uø†Ê}¸Kg¢Î¹­à…Û}ðèðäCEñQl:>–ÜAKÐÒòF§Â ¸A€N‚€Æíð}'ó²ì Ñ _Ecì…üüûÙ;¿Ï÷wA�J@”„E¢ â`+áo:/‚R€Ž*QçÃSp4BdIA <'Â9ð:ôÛÀ ‹8f¬óP¡ôŸªí�#SFÛËÞ,³Ùÿ-éÇårUo®¶l· Ì(Þ^l†æ11"wÒ>fûnF¯oŒ“l®‡¬M <¡a>û©}–”eÊÆ)_õqÿÑþމ!W¨¶£6¥SéŠu¶¤-Vk;µÍ޽ ½ DÉdÆ ÿÿ¹Cûda²ùêfã÷5Zâ–Ü$gT¨GN;20u`ÞŸçå¯Ï×…>¾ “eYê“&?3Ùh¾e2™,Ÿh±30;Pýju¤.R÷bŠúY ³ 1nAƒ¤Ïw:†Jò¡ '“ɦ¯6M~uò·ŒÅƒÅ‰H¢grOÞö<_j‚æM¨ª$MW¹eîÃ+@5¾7r¤ywÆœ0þ‘*×™ ñ¸À­á{ø‘Ĥ0·nötS2@¥†#,áew ¤à1p öCàd+s]S<¨ós˲|Kág‚³dªJèêcb‚Gt²ph:¿·2CåÆ mÝô–3ÇÇô¿¬€ Wæ#Âìƒ\¤òíce–éiêFÌ'0 ±‰ƒè1>˜À5¡+® o_šôtË¿º¾°sÎHhg1 {ieÆšôÊG³ì‘~ñlü·FŽ£ÍO´™:aA™•@_Só \M±]b›së9ÒÊ„ùi2A\£xFpHôƒÂ6ç6tA£ÀÚ€ÞÃ$'•%Dm$º©©¢øQ;,ØMÚÁS¹-Á|/)™žä}H*I•Ãqö‰‰{ÿªÿ¦›_=’¦¤çÔ¥=g 4 áØìµ^_“ÏHô¹_EKDÁwïr :ú&÷±€ºýú+×·ü~AêñùQFId¸Fc¯>î ÜÅõÃX@íÁ¢1ÛÆñYÔ)Žpœ…É—S@�� �IDATìÈý¥¾·{„HëË 1)ÁŠ Ã}$`…àBªÜ,ð‚_‡IhÓq40ØDaš?P”à¹$õ°Jçiå‚r¸ –¼&kTZPtþìGN³ AÖÁŰ9.°Â<&ïb8® Ÿ&Ø£S$h<Ë`?ì.æ;NÊ;¹FåX-2v˜¡ó°Yß›§þæx�þ»`<¤Ó$‡çáaóQ‡ù°Žƒ ûáQØ{a¨àˆ±ž ž ÌðeÈÂÑB–FùNš¯ÃŠO˜V%d]΋æe¤Ìço!Í'„0sÕ}ŒÅ1ä”̺Ĝp˜Øå1póLI’Ê»Êk÷Õ®¼dåyï7{hv^o^___<tt× «~uýŽå;æ Í‘"ÿbï»f#®}êT)w§oè6³;gV¢cZf2þ·²­fãt÷í»…M4<Ó`ü~Ç-;2þcÕYÌ  ×ï¾q÷ĵÞhp´8¢Ñ¨Õjm¹¾e`ÎÀ)ß:åß õE£—˜Éd‰D&“QWªª_ýâÖ&ÃlÌaæ¤\+/³3æ¦Ä˜?e–‘TÇд¡™OÍüïôD<q5e „¼ÂkÖ¬Ÿÿªd2i²ëþÓ¿ÇÇ<�ŸŸ®º!!óÁõÚY´, ã‚5p+ìŠñ|’»t:àlø nÕÉÍ:’ùÃ<©ñô&I'Y æa…gˆ"•Í0>¸-ÜVGß~b 7¦hPùœ‘@m§Ð9ËÊŸ¸7ÅÁ ?2œ&2‰k»° |‚²(ö5ä ê“Dü9ÃÄÔ‘kàÉ*Ñx¹ŸfÁïºqÛhÐ)ÑøÑ¨¾Kzí¥DÁÄȯî”îþîît™˜rP¡Xꮣm Ùõ%‰~$+W7p…¼›{xb+7Í %ÀÑ~z{ LFxI¶2­Ša'ƒ;øS>—yY™á'Íô•’*§c+åGÁ“a¯ è#1Êl…Ó¹ácJä÷²Ç†¿‘¡Fb­øŽÔ–;_ko{‹fü."ê#dKˆ÷í=Yzh¡L~e~ºuÝ—S{/Á^ÅO†öž>*´’ÆÄÛŽUÿ›niŒ|î}8] èÌQ¸£”«ú±'ñ¤x:àÒb¢m<¢ð€•{2¬M’9(áTîÇZ‚£ß�Y…üA¼2ÁG:«œÜŸæa‰ùú1á‰û$°*P%q……ë†i…å°FâbA Á:‰çdùN–,\¬ñW'ÿ7Š$QQ‰F…¼,³“<D$æKxu6]o Ê|?Á~Š¡ΗYdçÌ$®þªKxªˆà�kÞã±%p(Ó<Löa°‚W¥™‹à§ ÁùåœØM>Ü!¸�ž„>6ÿ‘ÍïƒRp<�vÂOA’ø½  <@¼7ÀÝ€´Á*¸¾?ÄN˜Ü+Í/RÙú²º¿ÕI–c±;ëÍ ‹°F¬Þi|‡çS%n?µd„*#l™†étÚè.PŽÜ¯ºiÞ˜;ìùTáƒ\½A£K%§½0mÆ_fÈ’#–T’ÆõÜ[@”g=8ëíß¼}ò¯Oö x’þdÆ“ID†îøö‘ùÂOÀ™Wnö-Çp°Œ;>šN£òˆF£ªCm½¸µoqßì»g»{þÕÜ›wÛ<_žh:¿iç;‚–‚3o9Ó ý‡£õôÖ£gùû™ñÒ¸§Ï“›œÆŒÊŒ¯Q\¢c¾bY‹uØ*ÉÒx½ !„ÏçûÔŽŸ)k2¾ Ë…çŒû›<E­û®ÙgM[]ƒ®Ï{¨¬úÑÅG[Ïiê©·…lÖ¨Õñx‡L&|?Ʀñ1¼bÞÇù÷ÌB„“asàd¼6W£ä³º²c?ó¾±f nˆi¬àÔ*þïiê—Aúá#…ó¡?Ã]2ßT ËpA¼WÂum ð8TË”ëÈÿt®k—ù‰Î[:“Ó4ël†I]H @·³~ˆÙ°J*Â;Â7#I¼åc¶Ž¦C¥[¢>DDfžÂE³%f+xF!€a7xfƘáCNc/c¡Œ>‚3#‚­¸«Š¿óàÍðD>Îþå'Ïz¬î»åYóZO,Xò\b»ŠÜïð°ÛÆJ+¸óxÂæVö$ù^1±a$ÀÎæ¥ëÃ\&"æ ÓIY÷õ¡h”e°Ê,˜ÀÞ}XóØ—dÎp=®!>Vh¢$Éwòa’zµUŒ¤‘5ËkWVM»Igi®8.Áî %:…(ðNË®iЩ ¤|‡>¦@"-S!ó\Ééo¶½ô Ï_¦\ûÛW ®—93ŸÁ™·$ÖºY˜%âÏI–Ëœ«±N’™­ñ¦B7Z”&•wàª!ò¬w1öG(†'à ›_N!¼—‰V†Óœ¡Qyjt~ 1vÓãh°Ü2½ºÆñÐ-óc9K@âo«uF팖ñõ.Rp}†-.ìqBr±,yÎiâÑé÷J¯\}I^I’{áØbçé2&™þ$×.ûwp*üä8×¼äû ŠxÕÏ´_Á�tuó‚Ì—uN†zxæÃD¸Wb¬\dx÷@3œ�w€.qžÄ¹:“a1”Ã×!.ðƒ ù÷Ø�Axêá$ˆQ ÷z¼FjI{ÒGVqqT½^e¦+£žøöžföYYͤ0Ê”ñ  c?ž+¬0Þ5шÚétÚãñH’dØEšìcã—ãGEŠÖýhÝ´—§”D #²*W®­,9P2¾h3•‡ø§±é÷‘{Ÿ%†ûÅÑ£š][ø? E!gµ¤þÐðFCí+µÇÆ–OÌÒj×ÖÊ.y×Í»jV×L{vš ¹6‡F¿Õ8ÙëõºÝn‡ÃQTTd²ñx|¼,^.¶3·t0fN&}ÌÂævÇŒ…"‘ˆYˆ˜µÜ¬V¼±XxDÿñýóœ÷9 Õ±¸C³h‹o^ ì¾vwÚ—v8«×Tçõå'ôœÖ“N•ý½ìóë0³˜6/հ麋Å>ul9¾Vûü®’IÄXÚÄÿ}@Iš¾;Ë l2);d¦X8^ ëLƒ#nü SVØ/”X,S#¨†r™É ð®ÆœqÁ Hd²^åNžŽ2IPEN1¤S[XÒD-¬°Ð_H$‰’¥WæRÁa ´–’éҙǛ¥@¢g*ƒ¨i =„3¤S ú-È:³-TÚè‹3bç|‰†, áU½ýÜìÁ|=¸Kgñ-×g^¹,uõZç’MÖ·/È׎“ÉÆéŽàŸBTanŠT?‰Zúú°8iRùR‚32äùQ ú²”ók8ÍC|ˆ…b-ƒä§2É;:yVê&PÇ?ŠÝÍ ÊÁ Ó4|nb‚#Yüaò”Kß°ô;>ðG™›â- ÈÕ „Øê¡,EI„#æj4Iü%Ë´"Ë$º%ÜH×èÇSÿ˜"o>9SÒl'Nf«‹¨O1¢Ò™d/ú½øub?Îr²Ì@ ­aNMWB¾ zÅI0Å€{ËðÇø«…ËuÜ)v à Á‰°J§W"è¤! }Ð"3jx­Œiqâ‚2%¦Ã:ÖazÌÕY£aq23Mt;™ãIïI¾RÈîsdêáiø D ¦C0Ë9£Ó¸ð ž<•Ω`§ÝÉ+Syeon—¢iyç$¯»Øqˆ­M‚ ð5™­‚« Úa‚Ä: ÏJ” ¢ð(L‡Ý°.ƒƒðUÁNÁ^Ø £p7áè…>pA�› F! xêsE˜öJ{7 n(JacÛUÛŽžqT(·ϧDcÈ<F‡ÂH'&TlŒT«ñåS-øL»wsš=¾6~N`ˆBÙᣔ1Ó/„f˜BåväŠ÷«V5íJn.¬~£:ÐØöómÎ.§³ÓiRÌ´”k•k¼‰‰$4C•—veýn;Ç¥"éHö,è ì8û¦Úy¾FsßaŒ)¢ÂwÐgZ§¾15Wæ<7}¯5®ÐPÌòz½ªª& UUÇGgÔghóî+Šb4oK/(eš›ó≄QÈF-iöT`o°f{œ‘Ç€- mbI’ÚÏkª¨y§Æ8¿p[aÉÆ’Tqªõ’Öâ–bGÒ)Š ×v!‡iË’ ÊÈͬ¦ÿ2Ÿt¶/˜ûŽgÐç"œtš‰ ”?­ºró¥Až€od¸|3l€¸…Ó5Ê%î›Èù…<«£ã—ñèœà ƒÅ‚"‚(¼ÿ84¶ NÔ2A™–þ׉äaR”—»©?üAgD÷[¸LFH³l«&?Á¹>…2WP_Ž¿Œ¢0“:¨¥[㻂wòÑ;i–øµ‹tq2Å„áYAQ€„ÄwC.DsѧTc5‰«øýùî{.\ôÀéL±UþpMä„ý1ëˆÆ^)EQ!Q ÅKÔSð\»ÃxFi$$Ø*aMâqàrS¥£(‹!Sªã©oB8¼òö¾•7«ÇÁã Ê!Ê$§Ð«SŸÀ®áî ¸‰N²ýØ;/ø(öú¹‚óUšu$[1R”Çs2äkw=;ÍG‡J…+¡<„Kg³ÆXÉ\ìŸgßxž{ܱC_¹J_ytÞF¯Ž_ãn'>‰¹“tÊ`~†5Y6ó¨L1¾ler†ávÚ"äI”N`ÈÂR™‹d ±õ³ÐNw ”±’ÉÄt|0KÆ 2,6‰)Pk¥AÆ㮉tÃ*ŒF›à)Á>(‰³'ƒK0=ÌÃW¨ŽòV’M𼯣¾ ÷Á48"Єf®yž–pøl°A A ÌáÇ—ry³  0Cºú0OKP !mnø;̆xRТó-×Å1-ݘþOÞ•Ëà~¨S ;¡÷Ÿ³.?L`(°,…¸ ¾•ûE W„³>ŸÏ™çž<<ûŽÙRZŠãFÝcTcb“ËL¦Ü˜nFv³þ0ɤ—Ë`ÎÆb±\y¤ÜÃHKuÉ8Œÿ»ÚÅø»¦‚¬É“_™<ù•É–�`[+Þ«œ9øß½¹‘¨ŒÕ0.þÈG6ß¶yÏu{´OãûЬQu«¡êP`wÀ|C‡Ãáóù¼^¯Óé-=ø¥ƒsÈšs˜¡ÓèïÕ®­5V¸mQÛÖŸnÝñ£㛪ªÆãñp8üo eã= ^‘©àðÅ×Äl6ÆÿyXÊdâñc:>iFlκÆFZm^Ú,Çäªw«r’Š¢w匜)ËX­Öp œr¤üí~s¢i\¼±_1³¸¡¶nqÊìXãžDˆ©Úòø÷JÄ㪫ù¢¯I–ñø½Ö?ÐW¿CèZØ-ˆÂ“ð­$Eiæ¨ìK1¤1%‹+M‰`R=öa&@©…MN¦û¨Hð<üà™SeÞ—Y¨!;(´£¨_Fm„*¨/Á¥ñ‡ s _¦DCü"ƉVŽä#’uNrz‚{”Åñ/æP'(LS¡<ËÄM¥Dtê’ÔX™ä¥<‚¬³ñ¸—ï ñºF;œqA‡J@£~€# žNr<}å¼z¡öÔ¯]î×2~:Èq½ü²—+"¸4´ŽüIÉ'ë$]›\ÃOÚIZí£º(O°X£©ûÐósí«½ºøÁÄw?ÔTDGü2Og)‰Ó䤨JÓ4"½ôÖ¤pHéÎÜüwýàDuíIv-;tî”x=ŸzyÇÇ×-Œ&šë#£u±ßÉG1R‚©2^eXT"IÊtB¼–æ¸$[2«~%*:Y3Qq³ùãáp”Hš?é4ÊÇÄýê44 'g™.Èß(m)ÀAÁv8¤Gìœêf}’n•::åC¼­s1”Ã:‰GÀ÷Á+0�SàÁ£°D"$¨Ëç¬3†7  ~\F}›„ a ÂD…“¡^pªN&ä f¥8)Ët)ÛRÁ\ž˜[–ÒÙÏÂjÈx¹ÕA]Ú‘aÿ‹„:ym ‘ iF¯x¾ÕÅð¬‚M°jàt¨‚#‚rx_¢ àx¨„÷à=Ð`<ÁvxnÕÆ0 R°2P%°F 2°Ì¬®"û"½o÷º%÷›+Þlüu£§ÅãÝîuu»ä¬lÚ/ÁäÊ5åú/s“¥dÆ>CcÔdÂŽá'}*)תÕDv™2w²,³%£Ž1öé¦Í„Á¯2ÂY«™Z´Fü:–i$Kàp VK”$¼^ƒî“K0²8´ôêP=ýžÏi%ÊëïXßzVkÿŒþi/LóuúŽœs¤po¡¤Kãigÿ²x·i;nÙ1çá9<F|4**Ó¬™®—MµåÚïšÞ͹"ªªöÏéßû½Åo-ª{·nÌ”ÅXCCN)›Í†Ãáh4jl>ÔgìTL• ³<2|ÇT™LƬ2=G2™#·o”ÂfW-—ôf¼p̪#À®³»ì{ùå’.Y­V·Ûm°wuIW2Jp[ðàE›–5åïÍO“…;Ipišfx|˜O”y ‡)¨Á'­Dñ"Å@šO`®@W.¢ÄTùr»Ý'œrÆçˆ0E+›úó‹B÷¼¡ß÷”ä\ ýý$ ˇ໰.ËM0KçvÓa-¼ªã¶ë§^ŸB@ç EånÁL¸e.–°UИ@‘85…T D²«e–[!„5Í?©’ é(P#xPgF”‰€Îrö<ä1CÃÕÂ=2%0’fk†Zp‚3DB£XÇ•F$i×ù¼g|\åµîÿ»LoÒ¨wË]îƒ 6ØÛ`z€Bh‡J¤Ÿ@¤@€$ÀÐC7B Íl ØÆɲÜÔ»4IÓgöÞïý°agŽdûææÃÝü³ôÍìòÎzÞµÖ³žg¿ÊñÆR]H‰ÊDƒ‰ù2²àñ*Rý,×É•˜®Ñ#_[OŽ<ùëÁußS؞ĖÏ%C¤ ž4&Ög>¾Çöý¿j?¾ÜØ_µ51¦‡}vt?±j"û¸#‰+õÓˤú¹Òu—W<t£ão§§Ãç[§k›~®o<)Ý7F¢¼š¢""%87Ðœ²^rK×~1ø»‡¤gsìNΧgˆV…³ÇpQ'×:ÙTHT'7Õ Qžâ`’§Ë¨–_€œ¦6Ä Iæë´2ÞÁ‚ƒ‚—¼¯Ý“þ΋Lh.ýhᘽ§Å)˜BoE-`ŸHQˆg$ù”980̽3ré€ê ¶³6À”QÁýNLqs’ 3qÁÖöH¬‚%‚Ú\ÚüÜ#ÏC]†{¡ªáf˜%xVf~ù!>q=\+q²óTйÊrHÈœž!?…„ÁfÁzƒ»àük:Ø™ Ù ”¡!I'ÔÀ,êÂ4öA�΄-П.Üœšö"wn§ÿn>¸•þ7n)¾ú¶XÇ.h~QpÀEÐoB ÃR¨‡wJ x9Æv‰W¡°~�/@<µ0΄éßäRWÀ!¸^…}:Äa¬µàj»{ûëͯ˵rþù[¾µù¼æ®5]ÅõÅÁd0ÛQ){wi®Ð´ò-ë7Ù£UFóÝ #„øÌÿ›5¢ì`du LeØìeö0²¥¯óõ¹é’w¯·ùÌfOÄã {Ìë5Ó‹”’Ú·vŸD¤""«²¯Ç—m7lqQÿÖŸl]þƒåÕïWOxs‚»Ëíîuë~½euKÑ¡"))eW)³U—>ÿýçž”gìÇc³e«ÌDíë×e„šV­k4̢܀×4ÍÓéQ“jçòNGÜ1fØpey˜£NápØDÇÑp•½cÈΫ²) £áÊLÍ °)nuª²7.n·Ûœ¢á¬fæš#(<_«÷+ÎF§æŽÄÜ|ô—÷‡¦„Z—·æ6äNØ<¡cAG:žöä´úXæš´²7k„Ùº:PM¥ « ˜Éd‰D8¶ú—£­ÅÌ»j³ÙÜn·Óé ƒÙn£á*8DÉàÁìÊ‚û` „%–*¬1x.‚v¨=—©qž¹‘È3ˆÚXëbŠFÄ‹#C»Àeç«aš5$E¦1Ìü ">ÖVb %(U™á`ÐAN ´Ûç!šàKÀ§ð€Ì0Õ39âÂý06ÆÁ–ašÄ°„]Ð+!t2‰~˜®³}<ãÙ—âmí¥AZOÛ˜œ`fŠ­͉°!M5GL¹ªÇÕ †ß 3Ëà-1ï+žÛËŽRù±¤ø,ãœM-‡ÖŽDCô£¹pºX˜©Œ9çäªÛÜFÇš]ºuÖÛèIW+üú/ò®3ü­öÿpâècr†"ž˜Oï½êië|ÊL¤Yæ]#7Í?\\žDò#⼞Â.‘§pÕ n¶1TÀÔ43Ó| r¢ÄV-)^‡e~Í¢ÙþDMþÞËÛiŒ QWD X£¶Ÿ•0>gÛ\=œa'W DhQÈÍð·…P�gÃf‰sTÛ!)Ñ HÉx ú:<Ìb¥Ä‡ÞBNb4ÂbI"äáû ù1ä$;%rõ2 ¤“Zµ¡=$§Ã§I®Ìð9¼ÝçHì†k Â0vÂ^¸¼ Cç|Àƒ¯ñÈ*(„¨{¸ÜÃâU,/åxé8ìã ;Oü(Úç‚>˜7B#\ Nø ܰž†𡋠ܢ‡…0Ê@‚A°ÃØc¡‚Pýpú7ÞŒ;  æA tÃB¸ÆýKÕbÛÀ¾—ö麮%´Ê+‡ù_æ냖¾dËr[=ülÉËÁÝd‡[jßæoF™{ö£!–µUÏ–‹ÍV…áì`µÐ;…¹Ù·�&ÛýoÇO×õŒ//‹' þ6¿Íf3xêÖÖ5-mš°iÂøÇ7-kÒœš§Ý3¢šÚvë¶’m%…{ ³ã¬á4OmŒÅr÷æÊÙ¼ÞlU½á™ÃíKÛOûãi^»×Ì<²ùñVjÂX:6ÿ5õ“Lˆì[gvîáÜò÷Ë«?­-Ÿa 'ºÝnLÀÈæ¹X9‡Ç-DñŒF?5—Ëe&Öfû'{7“qfÂ3žnψ®§%®a=šÑp/ˆï¾l7I¼Í^rBÕ¡®Ù]3;44G—£å´–`CpÜúq%»JÌw³êÕ¦¯£µŠÌÒŸ%ooÖº6»m‘2,‘C³Å•½ŠL)&ó#ü~ÿ¬ù ®jA›Ìp•Á[üÊf Jähp<+¡Gçè–èTø¬Òù” w Rè¤ƧiÒØ I‰7à*蔨S©6˜hÖyEæ]8 ¾ásµ…ÌïcR€pˆn&º(JS“ælÇefú©Š  nUØdÃ-#©ØOÅ‚³Ý¼¥¢È:q:u É�åø¡J{@âÌbA1x›Àé~…«‹yh˜ e:¥þšô_ ¢ܾý\ýΪ¶0†³ßV¶-ȹå¼¾toʳ˧'ox6ôÛÎÈ PÚGÊ¢²›Y¯ ÇxãË)úã´:)Ž2;E…ñó¹Š>xÉË¡M?-%yøÎGš|³m8%¤ý¸ü½úü-ÒÕwA±N»Jß¡H¤á&…¨ g®†fA‰Æøs9T@¤‰I6Ja‚F&Ç�ûà<ˆ Òð¥Ä5]8T¸ÉíegœN‰ŒÂí! ŸŠKÃ×@³FDGVˆIlÑh€Õ.|þ.{%ž‡³ ¶HŒÉgAˆNÜ:‘$ŸKœ­2«U\­Üý aa3\ ur d™Ó%¢°É8å~ãÁ:¶á»—K¨ïBJá;‘|®"\Á_`1¼¯ é´@$¸ãMî^iXÌ•cj”fÛªùÝðüð×¼[ph|­ÍØ 0 å°“Ð^‰%ðHpºÎAxN†F(‡x¾ï ¼ Kal`Œ…ãáE˜(¦”­¹<»<ÿñ䬉 –äÁ±Æþÿ·rÏÓL(Û$»ïbŽØ‰1ÕåñÑdy0šÑªì£²ÐŠÐž«ö L¨Ü_YÖ^æp8­8´ò啇 †åáÉë&ï?mba¢dcI6¢éĦü/ò§¼0eħg?1{ÇÕ;ª|Uî¸{°f°cqG¶@Cxn¸hsQ&šA"ÿÏ+©µ´ûF“̰k¶s,—ÅlR†Yã5í3ŽNÖ‹³ À¬ÜÅÂ9³ku§ê®ª ÍÍ|rfÙî2‡ÃáñxÌYm™#ŽáêaÝ¥›‚ñ‰œDÃ… jDU£êØ'Ǫ15:&Ú½¢;VóÔzþã[g•‹-[‹ó2"³Ìv –$ÉÄ2—©|ÔÞU2áUÈ1ø;L‚Ç`”*”Û*gÄá+Á#0(‘T˜f°ªr†é1ø«Ê,Á‰Ð£°È`IŠþbÊ£<h°Â ¡Â(¿w³ª˜ ?E1"ˆ1.…?!膹¹¤íÈ1ºUÖê ºur ô$o ä6¥I.Am&&PṘ…°ÁËAfGº"ƒ° F L€~\ ¼if—@Ï07åË ýtèœfP“$o˜G§‘éå!%|yà‹YrCUæG/‰é ZtZQiZþýªœpµFC.[KupÀÑñë§óß8SfP¢:‡ÔPI:tåkéÿY£…wN ¨‹;ãt –븣`ðÌ¡ÿ~„5_—¼&þ~[fïáÌFãÀEú‘S;Oî|ßöy) Zà%ƒ™ä¼«qv¡áI³ÇÀˆ¶_ý�� �IDAT „Q8#ÅÒ(ÃY y’NJb¢BA¾Æk:§`è<5ŒÏ`\œ[=Té Ñ,aO2Yà ¥ÕMÔ‰ž¢&@�fB¡Á~ÁÓzýœœ¤ßÀa°5Ó‚”Á  Sìƒ)BÅ¢Üoò¼J þ 3Óàe˜&hÜ ³¸°–ƒûxc9¿øPz«ƒå0 I ),ÌàÒé€`ÔH¼ãä<9)<\·¹øÚFÙÄåüþ#¿›'såFIb@fG.»'Ò‚4”«lÉãÒ8°Þ…¾±©0ðJ†NƒÐq˜§p‚ fÀ~xBð_Ð_Â!‚óA@3†Óa3¸à$8 ³ *¬ìª¹¹yÓ¦MV…Ê*z˜%5kwi–׬O§Ói³ÙÌ~µùÅN§Ó#Ç`[™ÜK‡éhd÷lÛson~œ•£X›]}0e2V_m„ÐN6—Ï:½‚ž‚ü¦üL SN}u¤zËò-+>\QÙX9<<‹Å„&|-¾žšždNÒÝê6µ6:t(†RõZñ¯[wVÏCUUwÈÝ3«§mY[ÇÒŽ´7]øe¡§Ããíðúº|¾._ñÎâòOËE\˜L³¯c¶ý¬G`žs6в7<šüˆ,vÄÑh¼«_uDj»yßÌ¡sÁ˜?Zä: Ã¬× !ö^¹wÖó' ªN5?’oJme§nV»È,Ü™xif¢‘’ˆ@”~V*IÒŽßï0ÆÄu‹v‘p 9‚ Ag§SÄE¶¸{"‘Èd2#æGÌÌe¯+s©Ͱ8®,΋ªªÇívûý~§Ó™““3¾fÆQ³+¡óš d*-A¿@Óy 6HüT¢A¢Ààg §läÌ‚uA.ë {à2'n.¢:ŽGÂ?ÌÅ}h°Ü`,îEõ²°šÆ} ¨,-¡ Ã iÜUÌì>þhç.ûR)EÝ4Ù˜«2Äüð™;2ìÌpªÄØL—é‚qCæ³j|¬ŽR³…6 —FH"­ânÆ¥¢OÃßÉ£Lט­ðÃAÆ&ï§¿P#»üxBë©É«pM¢ùq©y²</=<áGêE{†~aNlF æ!šÆËÕ6ŠðÂûð«½ñÁ|k3º¼>ùU}[#~ñüáŽÁçä{¯ÐݵÑÇWHý2Æy…Œ ¢µ³¢ž<îÎãüaª(áw Ô<ftÑíáÇ ÞÕÀl™a‰>…k † °ŸÃ ã$†R�ŸêÅ õÜ¢±~à£8Ie”»Ò$%2DTØq¢s Œá>î¶³.C{’ZAd@ÓyV§XP ÿ“âÎ4û þåI.°³ÈàF½Äó¥ÜØA“Âõ ž>ê!&BTã�œncr€òýP¿€K‰Åé¸lqpÍ…0¤2OãTÁ¢Bð<œ)3'‡ÙÂqòtþ™tt§nÝÈ÷ç»ö>vÀAŠ‚ø¢lk šá3¨±U2ß¿›+k`%¸4–…x*`¬DàXúfÐðV¸ \ð"´Ãˆë| ¾ çÂNø†!®3ôƒÏï  ¦BÄác(ƒ(Èðœ>Ÿ/[qjDЭ«dÙ~[ó쪑U-%­žüˆAKKê[1<<l͸D£QUU].—¹dY¶ö°k#[¢Ô*Zþ¿Gëe7~l6[ ðµ–`a}aÁÁ‚9Ûçì?oÿšŽ5Áh0êŽþKŒ<¥()%íÿô–î)­;¯nãÃO¸ùßO–åŒ+“´%¢wnoý9õS×MÝ{ñÞÅ·/6â†1hŒž86Íæ­}4²ž”ÙM±€üµ,ën›/0sˆX,6º94ÛŽ(F<úõÙš~!Þz+;q„Ã@C îš:÷ [‰(™LÆl=f³-©ˆ¯•>¼™MÜTøUá´§§!$ÊžOŸ‡oÎÎp]'uåoËÏ=›½h³Ÿ~v{̼扙SÒ±XÌÜu9³Æ0bÔ}†ÙKÚ¤«H’dNRÈæGgWn™±‚Åð&L‚/áo0f <^¦:ÑS,¢$Ês.X«# A2° f ÖE‘Ó ¦¨P8,p^!±ÜàŽ4½/± ‚ƒlØ;½Qêt"'$Øa` Vˆé<Ëeœ‘9ÝŽìÁîç… Óg2¨c ñ;Á“NDÑìäËø< 6™©2ªÎÝ•‰^ú¬V(ËÐP@™JÈFO²“üJ’‡¨W°é8%8Hؘ’ÃP*!ŒŽU•ïŸ>%3¡•Þ“4xÕ5q¯úëûr.{&””$“2¤í"¢6œé­ì—JùVËó›µßÜnœ»^œû™¸ä÷ÓNÛ•$íùø !Ê ô¶~JÓ.±Hp’‹°›|çHÐ(Ñ!³fO1Vð¬ƒi%8£Th\WD‰›6ª§Ð£À0’…e‚í*Zv RüN´Sä¥3A§Fƒ Eƒä`§`W†ƒ”Ü’¡Çà Ì“˜Q¯›s4tAÜ®r¼Â|IЉ–¡÷ó©ÂõCÔK$ „N½Á;×+ŒTƒ€6i @üVC/[§ò“-ø'óÕ9·OÙ·J|{,¹4Á‰P'BžàÑï§9TȸIJz唤~ÚSüDu}örš›À-}’æ+„'«uÓÒ-alÒ¸áZ.ÿ;ôP³‰´Bª_Ð c!ßÎÃ:ïJ\)á‚™�<…0B+L‚<Â;ð´}ã•óSøVÂHà 8 Å0Cü0΀ûàr˜meWmmm[¶l±Q–#°ÕHÁª0¿«f&a…$«e¶¬GHõds.,­R«–hLÇ 3:X5KÜšg2‡•ö™/°:d–jƒÙòÁ#—$Éív›<¿ßïõzÍѬ_y]^žÅÑÅùÉ|“8700ÉdPè8±CójÕÿ¨¶”{$]*®-ŽźwÙ‡í©ÒÔZV·t/êfˆ¿›álv¶­i›ðæRÿ⤌f.±s3:»ÊææW=âÇl飃ÌVv;‰Ѣw[‡Iû6s ËöÉŒÑæ2°¼¾FèW™?æ×æoÿéöÂ=…©¼vòºò,rÿ ³˜œÈO Mj<¿Ñ7ä›÷ð<ÕPÍš[é®Ò¶myuy¶˜m`ò@¬,Ö|¿·Ã›¿+_ØD||Üvš§j'¨JlªO™y•¹ÞÌŽšU Á€µd—G´oÍ5iÒUE©™1÷ÙÕÎKÏ9SÈ»“ÇÏ€ñ°J|ŒÐ/=Ý´(ܨó±‹U“5Ò:~xªaü^‘X$áÔ¹Eæ)¨‚evœ!ˆ@•᣶›|ŸB“3’\wèäJ¬!8¤±CâÛ}ºAw�E‘Ëî\¾7Lp _8YšËc`‚ ¥“@€a;s5D€æ$] 4xOaÎöa&J$ Ƈùs.+‡¨(¥£µ™€Är6J#8œ¬tp F±F‰ÞÜÁ¬8ŸJ8lŒ×§–Š È»ûÖŽÁx5öarc(N’>ÆÊ ^œi\²qÿÚE×8÷Šu‚!±¹t†°u@%¹¤–™¦³¦@a€4Ø[9I§qmiÔK#Œ—Që;gQ1ÛL–™ qn›`w.[3œÒB›D»Áa˜OÚY[ȇ"|ÇŽ×EZ§6ɧpŠÄ.‰ñ2s ø™ŸdGŠW Q£ †!é&®1œ¦¶ˆú(ï:“Á‘áû6¦Ø8”ašÀ+ÓÛNC'{aŠFL¢Ká»:,„{%Ðñà ð)–ˆdØ !8xáùýâþ{ÅÏ@¿èV~;ã ÿ„’¹)M±N¬‚çXë™ú¿xÍøù8Vœ n ¾ ª„!ÞäŸkEýø¢ä† \/`³>â‘]l^ÏOÎ&Ó¥ðŽÎ,ø)4KÔ þ ×Âvð€à;Ðj¡ –C�¾‚"x œà€ãá8‚ ¼2,L„¯ M#b¢©_ (J27Ùµ¤«xqNsαËýæw5›Lu {…#îúÍ¿Í.âû0NÿM9k^5ÛiÄš¬h�L¶iSb³ÙzzzLËZ“Ú ËróÉÍw¦æœ_c@2™4ãû¬'fÅœ±ýçï*>ª˜zxê×U;õku sÚÌ ñVCn„7¼¬˜]Y˜d©&Z£¯V‚ûkjü?#¢¹9B7šcž¡™oÙív5®Ú‡íµ×Õï(ÞyñΪÍU–h¤yÉæÐu]·ë-§¶„¦…ÒŽôqW˜(Äý/еGìrF®½¦¶`wA47*¨ämÌ“írãÚÆöÓÚg=<«üp¹5¥`Þóc·QÍΓ91}Œ<ÕrËÞŒ¨Ó{îÊ1.ü'z”MËٮÅk¡ÑÎü4ù`ƒ"–ð ¾P!ƒ‚…à<Øóí¼ïæâ4Ý “utH@» BÅãg>ä8(ŒñWƒ`wš:oÊ\&“2¨ØÆ fJ¼'1SB yyÍI~+ñê3èªB¥J¡L²ÏïŽ^ÿšØ\žGŠm0ÏÆûjc2lè1•“™|: )*H:-AïÉ%)ªèq §B »Ž27Ã|ml§|éWÒKdªH Å~i1.47b˜ mϼÈûË‹?Ÿ¥B† ÆÓòŒXŸÑ¼ÃÝWå=Óx@S˜äÆdxˆ\[ÇßÇÐ!Q&©l……I ôT§ðè¼içRÁC8ziP+ÐIANÊ ‡h¢3Íz•sÙ¥·×UNƒ<•æ, ›H,€ßÀ4…R9u‚¸4ü*uTQOã1I2…Ð 3à=˜*pBÂJ’¨ôC=h–¸X"- ¯Ã‰à”ö4‹C…Tíá„jš§þŒž•p¶B…ÄÛ/ ÆÀzV”òЇ´îå¯9<w)´ÃÞ^~Õ× •Z[‘vôðØÞÏ'ÝIÍT.hV>¹•+xì~2]° Z‡áDØ(x .ýFp´ÂRàvh†,QYnЯB/A3ì…�Œ ÞŠ$N¨°|°Þ€$̇VvÕÔÔôÉ'ŸÈ²Œƒ7í7\º£Ô9ì.³©¬}q¶;ûÑà*»Ab¾I¶«Õ½·xqfˆ±JˆÖœ¯ù+4Ȳܵ´KA±Ù-'CK­À¢Õ%f|4icùùùÇëõ:N“{m¾ÞäàYÆZN=�Œüˆ¢™YGRUÕ®ÙËjËÊjË!‡ÅªÿºÉѯzÛ¼VÍÓÌü,q#ó³Ìk·T‹¬Ãr˜´Ò¬üoËÓÖjî]Y$73=Êžß²:‹#&š­²Ò\ëÓ³böÓ·,fûÍ’0VEͨÁ† šQ[On­ø¬¢wj¯§ß¤{XzÁæó­»º®kQWå†Ê±ŽÍÊÏÉÉQ¥ejKÒ•t ¸”¸â«óÉYÖä²7Ê ¾(p7º5Mk?¿Ýa8ÃŽHe¤dO‰µØL;š …y,õä#êf«]X©¼Ek´:y&»ä˜~WS›xòNþÞÎ9ƒÜRÏ_.„O N|’ä¦P)xFáb(1èNr;œgã,uyìk£ ’ðŽB>40ºY8D>ôC-HpžÁÝ)–fˆE)Õ) u”qËTšV‚dðÁß®1¢|XÀ5 ë¡RPi.!¯‡ çÍÒêõò}ù‚Ùu°¸:E¿Á_à¦ñ¥ 3Ìú×)Lî¦Ù æd’›ž¦Bq%±$±>àÐiÕ¨ 3C¦-ƒ’æ3¹w–Ö[Z0í³ÈÞšB&öA˜' >0øk¶6:ƒŒIФÀ!˜Ÿ¡=ò>0µ}ÿ™ÿLüvf;¹Å,v’Ç�ƒö"l]T Ö z†ø|¬UY#(f ‚œ>ÖCD¡à”$Ÿ .€)‚6¨–9¨ó8\“@– '¨5Ø‘¢Tf¼NÈu7鼑Ç%.I³ÕCMË‚8;ùE†927‡$V‡Øÿ5ÀüJ°R'ÖÏ )‚v*ý|ÑK?ÄmœãìëgªW°[ð$œ Á°qF†ÝMð�\ ±Aa…`‹`ÿìLZÇŸqû ãÞ夫4ò É`<̼S8åw|o5{g}TxN„—8·_Ë ÅËW@/D@‚Í SZ€o¿ñijâÊ>HB7Œ˜™k%R:…ðOàg°þÏ·á \ ªŽ¯ÂB„9Ð?h‡Ýp< S ~]0:ámˆ�°/û›Ô?§¿õäÖä¸ddJdÚ3Ó“ÂCåC¶À¼éþw“V0š>-aga¤É�´ŠNÙUƒ“]Q—»ÅmþÆ2z?ÆNÙ„4—ËåñxJKKM¼‰F£æT“)¦—}Š¢í)ª»¨nìú±æŸ['iµÙ,¢U#2¯n×E»Ê^)ûÿoJbÝI Û,þۈžåˆN•elhq L™’lQ’¾Ö^ÁBPÃ0=ŽÊõ•ý3ûs>ÎIW¦7ü~CÕ»UÁ·ƒ™LÆÚǸñ@é¥ÕoW:6›Íæ¶9Ît:=P9àT¹sw·»²»ÒÜÁ¾~LÝs»Oxà„áªáîùÝ–�Êÿ“=Õ¿Ã=gf‰úÿ·û*Y~¾F^ø=—ýdˆ V‚¤±TågZÎÛ›Œö ¤e§ÊRû4.æì ¶Aº pÂC*ÓÒì€(ä(Ü$Ø%s³Î™ ~ß…åœÒÎn‰ Êë:«5ÞQX¦Ó¦ð–à¢"‚쓘¨q_ KZ¸ÊKú¸ØÁ½.ª÷ãsðhEßPüô+‹»Áòû9XÌÌ>ˆ ÚÀ&Ó&!t<p¬¶“ÖÙ©Ó1…É µ€+?D‡DÊÙÏ 2†`¢ÁXM–¤©N³S0F†¥®¾–ŸVå{£¯gô3~¢ñSewAGñ•Gû)}þ$îé œ`ÚÇR±Võ¾0lKÓÑÏq•´Ó�²àô}ltÑîgÿ0³3üÈÆgµ6Æ–²º‹$n+ç{)fõ³[07HØ@êç%‚Ž  ·4 2Aº u à2‰sefê”@®à{6b9\1Àƒ:Ë!£µ‘"xΠBÂáãU9N'hvJs«Æ?U®·óxánü1n‡Ó56' þ ¾ oÂ÷]‚WàlX >R9^#¿…›Ù˜ïfA>ôÙÊeí®6å‚ Zj3ßV?zNûâ,ÏIâ¿Üá¾gž5~(®ù•šž«s³à`À*¸ ®€ ¤`áeø-¸á.¸…Äa´¸ð™êo އ-Pù‚Û VÀ³p.L„uP ]p)Ü ¯ÀzX%¸^„%/Áà-¯ÃýpøÀgÁÏáYøTÃÿÀ#ˆì…u…j‘Zy°²à‚ži=±ªØ¤§&™õºì®R¼0®GuÓgÝŒDfÐÏŽ€V7ÛÚÀf‘MµÈI¶ÞÖ´4ÕµGÓŸ›.’åÕ”H$Ìð-ùÑü¢yQ_žÏ=äÖuݚϾ¾N_ÊŸúä7Ÿ,»™3ã´ÎÓ|«X –ÊM™ ÛÙZyo&ˆ IQñˆÒ°aÞ’áG«fûÐ[EÂlúî1Âúè"­E£õ F³0²÷ºC?¼öpîú\×aWng®EÝuuU©ª¢õEÉ‚dß }gwLtz~}¾Ïësº¼^oYY™ÍfK$'­§S©T4µ&ÁÍs3ïª?êÏäg²ùôÙ“ßïW:‚1h]à1þ$›ßøoˆ0Å[É\Ë]oPå’Ÿê©\Ø K`ŽìŽë«ßäŒþgÉùÊ—{]\jpžAXá‰d'$q@€]5è…)‚{$fIh‚¡.Kr¼ G"âbR·Á™Ìäh<dLœŠ\Ž× EÉÀ‰:…11¢*ŸàŒ’‚rå šAÎÁ§VÁ›¢E0+N·›Ý ²Ÿ‰ ¦{Ès°%E”Ë)l©LŠR•Î4®y$þà/seÑï¶ËÓ Y.óFd™›!T»Ðl8½5¶p\¿ïþÌÓkÔX¿1Ö­/ùŒIwE'MªXöZÿuïÛWmª$í¹VÅlêó8ÒO}ŸoÿÀÃhÈÁÑÂFƒ¦BÆO<ŽHá”Ë\ªsšÌDÁ.‰iÃì–ˆ¨\“¡ÈIOš)ô‡b´ÂlƒOá€àò\&i,‡¼™áT…JÁ­eüÀż4 l¬Ü¥[àƒ!ȇ‚ýnZà|Ç…4ȼPÁ ƒ¬WYjP“¡!Ž …Ð * A‡ÌƒEý°[Æ'3&C¼S Ý $Ž“ ¼­Œ£Ã!æ¶?» _6ô0DÐÿZðÒݱ5¤'‡SÇ¿ýî;â[ר¯Ì0ô:ƒZè“9Qð)ôÀ?à|]±ã‘«tz%>„~ƒ3`›ÄgÏÀI´¹©)dâ*æôñì[d°T¨”°ËÌÔC#L…&˜�ep4ò5‡°ªà3á Â*h¹°Î þ ™³$NÄa+œyð*¤ÀœM^m[›[÷ÿu¿¿×/Tñɯ>©ü¢2ÿ`~véo¨zhpâ`ýùõ­+Zƒû‚öa»¥—j¦DÙ‚G”®°¾üV0ÍfXs³ÜÌ ,'ëO¬Ž.EV¬º¢Å3ûíÙ›_ëÄ,å½Þq½o÷ö>(“Êlº-ÖK$CCCfÐ404‰ÝBˆŠÏ*Z—´&'''íŸäõz{g÷Æ«ã±òX¤4²ïÄ}³Cå!wÛù«b±ØÞsöæmÏË9˜“MÏîNY?*G:¬WZÌé£íåÍèiêY¦ˆZ˜mMº¶µ·06£¥,ŦlB ycÍjáˆÎ™Uþ5‹¨&ÃÅ,‡êº®Ùµ¶SÚ\1WñÆb]×mªÍ׿s†¡¥!‡ÛÑq~Gî`îü‡ç‡ƒN§Óãñäåå•••M˜0¡¢¢ÂëõÖåÔ¥zRööltÌž$+ÛZ¶é¶MÅ»‹£¥Ñ¢]E#Ì®¬:ꈡ`ëæ›”t‹3b6½,a{³N8BÒм{ææÌ\r'»8ºw•dÖvÆÌàŽB¹ë7Ð(¹t|êñbÌz>|*1þMåãûœ„S$vƒ·¦ öɸ`¼LTÂ)3V¡H§ö É„cØïI”)<t&yÒà=[™fœÁl…Rü-…W§^ç3�Î(Ÿx™«a(õ0¤1V;I»´Óc¬F»Ÿœ^¶º ?H~‚)>Ì0'Ì4ˆÉDeè4A±Â~•\ƒã}#~ÿØZŠ=eøŽgRkÞ0þ\­Ò®s\†Ãˆ‚B4Í›^ lÄ“ü­dç<B³“K7ˆ%÷+³¢êÙ@ùäxùþTû4õç?ô­ûvüÄÏÒ+ž×ò"醉ߺK?­…Í'°}j9:§…ø‡ÂÝ2•.ì^:]ä “”8NB7èWi 0œ`Š Gá+ƒ3 šìDãØ \N>OðŽLÆ äR¤1gª‚’á”!7í:ž0/j,óÒ™Æ'1]'€í `…Ìl Ò^.L² I<‚ǧ Ò›¡RÐ ù*­ã`¸a¥`Ћ[pœŽKଂ7¡Je™‡¼ ïCIåIžÔA#ÌIò¶Ÿï%}š6~#fòH{áPL‹°ná·ò‡E¤j úa´Ádö zá4³É¤\×á|¤2Ã~X u°W¢Iá,Á~øB_L&ÆW‡Ø±FÒ“2+3a3lÿ†(X áa‰€DÄ@ƒ­°òáIsNì8à ̇Ýä À [¡R`‡"ˆB ,ù\µ¶nÞ¼YQ”¦MŵÅã×·JüñÂxÓê¦He$‘Ÿ˜ö´„7a‹ÚrB9n·Û N§SUU+;bàˆ[û#V­&åX‘M>Ì&¬g{‹˜Ã›Ù*G&åýk¦ø7Ív3²X‹öšö/üðНè-è}rÜ“þ6¿g¿'‘H˜ÑÔm§ê,o(—Å»ÇvwŽïdZ‘–.LGÑyŸÎ÷Ñ8_È×4¿©b¿³Ù™VÓku]Ïß›ïŒ:Íèév»-þ¡Í€n²Mì·ýïÃÒáŒìÊT*²Š¨£‹\Yz´b WVG-{Žíˆpe¼i¦íYÓÙMÊ€RöqYvÖ•Û–[ùyexFxú“Ósä˜ö]v»Ýçóåää–””ØíöNOç[oå¶äæuå™4¿l¹?ëOm÷á8[Âf†¤4gP­šgv[4[sĽȽ^ïü…KWíœ~+ú|Þ;QP&†… ÷¾ÃGU<ŸÇÞRV ë›ÒŒÒ€ jáAPb¦Š_Ð&(0P«0Ù‹]æ• j!>ÃIU ¯Á_$î²±ZBÑÈ­ÂトAªLi¸�Á\Ê`†_˜­IÖjì’ÊP!°Kt dA‰†#ÆÏC0Þrãª@„ȃªÂ$ƒkÁ-˜¢S Êð²Ábƒ_ñ&æ4‹3?´ã©IÝúMêÏL‘ÉTP2ä{± ã”HƉe:¯°2³kE:oHD¶—l¾ÄùB¹öñe™O¿ò¸ –9!Væð޾áIqÕ.uý9Æ#“ÜÛ#¸ò˜' 9)èvÌÁ% “gP¯rž„?ÃLx ¾-ˆÁKiZ ÞxRüMáÛæé´IÌ3ø‡2/Íû‚E*²ÁgÿO�� �IDAT®•seÆIT'Èð ÄoÃ8ÞjІ0 sYe@€L®Î “KrˆÅyÕO¡ T¢Dç~Oaªá!È‘Ùï`AŠm ó C«Éb•ðHìÕA³Âö ìƒ}ð¹DL"­û†¥ãâü½,¨g½ ã`|�5tŽ£M†M°~Å0¶‰¯Ç›Þç†fn>l¥9C0 &ÂFX)±[#X Ëaá YÞÌ«'Ó×-Q ×ð!´Á Ø µÐßQøD@ð,¼àF¨ƒÉ02Pk Yã ¸6›þ8P¿€ù°Îw¡Ò0®‚87®¶]»í¸Gû_&O6£cqÇÀä©ë¦ºú]rDNæ%ƒAk$Ö’¾Î®hJ[Ì8æa©Y;èÿ+\Y“›Ù³\Ö¬¨å§•­¬ÞR–hŸÝÞUÞ÷ÄÝmîi§%»’fvb½yvr¹\>Ã7V[:¾4(—ì[2µcêø–ñ%ûJìI{*•²ÛåY“µÆe-ËZ†*‡*^¨ÈéÊ1£žU›2ù æ\ªÙ±¤`­“Ì.6ZI§)Äw´ò”uë¬6FÔ³áÊ¢¥Œ°u WGF WV5ØÊ„$IJ•¥ºçtw/êvº=žlY“¼CyÖÚ0 /~¿? ÖÔÔÝ^y{ƒ­!™Iº[ÝþV¿ É–?Ëÿ"F*¡©¡òÊ­ó·N̤~d 1›©§¥É”Í!´?âZŽW'®ŽVö}*àjÁ%0Ab¡mý¹âÄPfþSÔ¾ ?ŽÂ©ÇI<£ó4x5p=Ü©²H§V¸YáNe*'ÛI;) ñhä9ƒ'tútœ‚§à*?E‚ý]L΀J/üµ”?vÑ:€Æè%lpn‚Çg²oˆ@G#CÄ>•ã@5Xìç?Éä0õ³r‘ÂtÀ‚Õ ?O!A>ÔÙÐ|œâ%•oE’Aãw X7%ŒÂoФú„²lŸþà-C €yo™ü“;‹a„—ó¢TRk¼Tyl�Yf†§„Ævºa�&t“_´nbw`³xÿÇkÙôéÂ!ÊSìMá™Iø�‘�ó<ô¶ódŒ\™ïƒ :(6–¥H”•*ATAƒÁ·U~?–ÛÒì )IÁŠ÷b¤NBl¸�ä25ÅïÜå?l…%n(€Æ*æö3¶¿A´n9 Êì‚w#Ü s[„?«ÇpR¦Xãb(7h|n„¤Äâwé¼&q·L¹„OgÔÙžàA…›ÅÓ‰nÁI7¸;Ž]ª¿Z<pÀ*~Eí&Ø !âªtüMã8ŸOÉ»éë5ø_Rû"ËæóÀ&ü1¿ÙBŹÜó;~섳à范\ÈÀ½�Æò`€ðC°Vp*ìfØ7B/(P‹à9×$Ò°n‚‡á¿¡ì—‚ Þd´ÃµÐÕð|Þ€›à'ð¸D!#H¬‡ƒpçQ4eGÑ|Óžž–ÎK×^R-Žúùkž®1ûCf„2c_,3{?‡cKÛúzÿ›tŒÜhr,jƒ,ËÙÄtÓj$N[K–V‚”³1€H$¢ëºÃá4–þai 4àt9mÃ6Ç€ãï½Ó_Üo5ð—þy©¯Û7"Ž—$JªZ« 5N`xxxÿþýÃÃÃæ ò{ò û ó›óÓrZ GÈ!«#‰é&³Ã¬×Åb1“ã>º±?‚™fÞŠÿ«ƒ³¦Í74¯7Ú–™YH3Ž8`é_ü›\UU+>¯hšÖ¼¶¹öúZó÷Þ›0öŸcM¢×®PU’%VÝn·¢(WlºBÃá÷½ç®w{ºþ%täv»-˜Æí—lOºÝîÑ|ôÑ£WÙS}ÿÎâqÛS©”‡– X,;&Õb,È•þë‚ ‰ÓWC¥N»ÆE¶z/õ¿ä?w?Ç¡7$,\ åp7ôA±„ŠÂ"5þ$Ñ“aÎK)öäqíUi2ðˆD@0Zá ¢Wb¶Bc5ÞƒŒQùï.:Å>Æ{hn¤È n•³÷Ñ›Æ/Ù˜ªsXâZH@_ksØç¥¡ƒã"ÌÓ¢0JÁiÇÔ(ôIÄÝ,&ž"ãàx )NR%Œº­*¿ËÁnû´HÕëòãg9øa‚oåò›êÕïí޳ĸo Û+\{çø©êaP O£¼{QhF(¯Æ9Äë¤unâ2uè6yè•·©ò²ºŠÐ�Ë$wÒçâ8¦VJTE˜ù( l͉-߯~d™SeN‚zøÜàùV~ ÷h$ @•)ÌÅ‘¤+Íú"ŠÛiÆ+X-¨–ù8ˆžaѦ£k lhá}¸ò`7tÀ àö(y}ü4ÃõP#¸ÙÅ/l¨=ÜSÆéi*ûÐ`‚ÎMPO¬„àx,Èäw°ÝÃ)Iìv^Oð€=[' pð …yP§Ó/@¥ —¶Úª©SyïC8e®âŽ=¿Ð0#é–I ¬çòü]Ì8À†L/—xIÐMê}ΊPx2½ŸÂðÔÁËàƒKàmxŽgá×ð6œ‡ái°Á4x€<8¦Ã+‚!WBü›Ñ+;üö ¤4árx.€¹p=\ ëà%x N†÷tÖÀ&‚mð0œ:bîjóO7/þÃâÒ€=bwÆœÇß}|"˜¨_[oÛ aXí¥lHH§Ó–’Þj€):â;4 «ÑÝ/«.g#g¿¹õKÏbD¨!ýît:-›GW˵%3É$ÉÞ`o’ä)ÿ}ŠœúzçþÅ-_è6}Æ‹3¼Q¯'î1s»Ýît: }>ŸI|·,ÿUêöšQL¨GðF2ÏÐl&YöÇ>¬ÍÏ÷5|F£Ñjj+dK((fšvSÖ¤‘õ-)‡_½6¬DÖBÓ´7­94%¡˜Oܲ3F#·#WQ”â§‹ÁÁA»ÝÞqNÇúûÖ››¤¢/Š–^¿Ô¼™ÅÅÅÅÅÅÓ§Ow¹\¡P(F£¶˜m¸x8®Fä¾²!{ú<Hÿ²9Îk3iŠ–¼ú xW³¥ÍGàñxL¶Ñd“cÂȬ…A\!£Q� 2ÇìÊp7¬ƒ~rüSaºÆíP qØ(Q [`‘„Sf¦Æ['q‰B§FØÎ™vJ¢D4^’yÑàS Lƒ^7®í`) ³î Ã\0¼#óë!´eïÊœfð©›a«ú9(¸žs°:Ás9œæÑódÖî£1ÉöjºÂ,óòI;Èœ\нªÜ0L_R í¤3I‘ƒZ„x©Ãt—•íŸóL陿uó~® óÊÀ{?ö¿÷_¾[þÐsËŸ}—×êÔ 22sö£ô(TJØtZ섚±©œ¡0ä‘bê[y"ÍÊ4Ÿzø2ÆÄ$²Äx™©Åä6Ó.è‚…I+ì¸rq%êÊÈiâ‹�sSÜ;L›ŠÇ͘Z5"M<Ê·;ø2ÆxY‚;r¸H£IÓ9ØM-üMg>DeúÝü*ŸÊnöûˆàTHœãK¡^¢ÌÁ4¯†ÑÄ=p<CÄ+¹|ÞËßýxü±•«ád™=p<¼ù >™¹:e/+¬‹Ñ™¤Ö»©‘Ð ‰5r¾ŸÛÂ?KLO9Ù!èŒc‡‰$H7|S!4u$>gÆÓÐ P)ñ‚‹xœ"‰Ç¤‹¯6ÁWð-™jwGNæ™­œðoza&< {`7,N„BØ3!þÀõÿ‡¶û°£.÷Çÿš9g{M¶¥’)$½JQDªÄʵ7•+Ôë½zÅ×+ŠíbE@ªtB(RHÝd³›ÍövÎÌüþÏÝM_¿ßßü•L&s¦œó<ŸçyÞå­¼• æz63ƒ[8¶d™6TóÅ¥’izin·€ëYÂ}lã§ ¸.QK#;&в²² 2ªMÖ¾+u ÊmÏÍÿîü1ciÿ- ‹¥˜ælÊRê/žž$ýU§# –——“‹ÏŒ2ƒù—•ÈKãK–&â&æËôäŸÿø~Ø/Œ“àÅ|ôG5 =õö§f=4kÆòiq3:::88Øßߟ$ÉÈÈÈÖ­[³öWi¶H¡‰{JÉi3°®®î:¦ï¥´)ú²eA&üQ*;TÊ:J§JÿoÑóíG¶äFæÜ4'm~fDÚÝêFîû—}çýy^i=É¥ïÚµkÕªU)»`dd¤··w¿«÷{ø·<Ú2Ž¥›}+²¿¦Ô‚ÒK ÁRK‡MÝK’.åŸeZˆ™2ÈD‰Ûݤ«Øcļºèq*8<²ŠýsÞùkè‰òÄE_âJþÆj*8(ðzneÉde–‡ÎË›{’º¹GÖ ò>yŒoÄNá°r‹æë[¡—ɡ͡sêm걆i\<Ýàfí½õú‡ 3­ß¦D™ü˜SËz2tB·êÐÇû¼¯ÒÔZ#jF­²qÌ 3ïÜåš:'Ô¨í»Ùu×äÍèWÓ6šW¦«Ï®‚Ûræ[´cô”5·ÊšwF¢0`{íŽò\]0Ûʇ•Qy6gÏ´Ø”w˜Ö©)gFÁsfîÒ;è„:Ý:iìð?,©pF p“æ2…*ý}‹6ð7¾\îö‚órm‡Z;Õ„Ê™?æù‚¦œÆucª•U x>t~µ¡vÅZKÛ²Ò}¡ã8<4'Ñøû”y}ìW¿$&ó."Ú‰™“Ó¸;ðlèªH9÷ñ†Du—?^Ók˜µ\œ³Od5÷òÑœg-_ãM¼µheQH/ïêôçÀ’ 6ðàN …A_æ0ÞÆW…/ú.Ӥ¥ã@n'¡‘ƒ¸;ðæ2M¡>Î ÜoRK¶¹ûÒä¶Oç§í7fnrÝÛXÅñüŒÓx‚×s9GrGñKŽ~ɼj&x-ýT±ûùç9v‚cYÇ´²™w°‰Jþ…»x «ib÷°”鼚ÊÀ¤Ä¼Šî‰íš´÷ò²Ri2Ø‹®]6ø)µ^ÌFß)`¬"1000Ny¶T}5€§¬¦‰2Bã@ååå™G6}™(ÒºÛ Æó'?¿ä™%åþA«ÊE¹šÎš /H,R¼ßÎ;«««S$ÞÐÐPÚ|%)§””²3?Ɖó²úëi}³§NE7²ä”Ö^»Õ™¨X˜ñvû~÷4¼g–Ñ2€âË>¥´~M —5KÖtìÓqè͇ƣñÈÈȺÃÖÍþÃì‘‘‘t”©%¥/½´9™A"÷N¢J?eÜ\sO?Ó?Ìn0£aeÁñ8ŽÝçYÚ¨(wl‹3˜Î›iL,¦˜ÄLÚÛ|¶A2ÏaUÌûLbJ¬1Ö”ˆ‡¼ªÆŒ b'M7³E[Îð°02#Ö–óœc#›µä,jÔ<YY`ó¨\è¨Ð‘Ôô¹—†Z‹Î}›2><fÿØê¼ Øšhä§9S“ÊÌ œ@4¨}Ì!CŽcvä =ÚŠN36ìÉ¢+ùibybMb´KŽß3ìÊį+:öwÝþ;¿ûõ¾›nÜ5k¤ÜιÇ_ßô¾­ Õ£_±QÛT“¦JØùx"T5 b¶I¡‘Ø7B­cz ž,»màöœÓO*ŠZ*Ee†WFž«69.Ð(KÙî¨]Êb]‰Ž&ÇLwK`Ýctó›Ø ƒþg—g8¾àø×í }½Ú`¬³ÏúNû&Î\hÝÉš½ÅŽ.ÛvºŽ{ZÌL\ZÀôÄWýû°»ZMO\Ê<Ãj6Fö‰=Á“ymS4'6p2ÛY›X›Î|†øÕtÐÃoiá©ßÇGû¸žfÐϱ‰‡#÷ÓËaüORÉ(sø†Sîɵ9p|èø>û$bÃÑå×øîuœçˆåÉM—õÌ*jyÖÙ8ãù#gÒÂ|ŸÓ(2¥ÜG‡0§ù.,¤œzð]¶s`Þi‹ò>@ñ]~Âj¦òŸaŒ»èeuleÞÂoY›³4~‘™´•=.$óe/.oS…¤q†ëi{g/Zà^2Ù+Ù2q¦%øÿ+6ƒg Ù¼=™g¦Y™Æ|†L ¸9·ÌéYسü Ë×¾emzÎÇßýø“o²yMsõ®êÔ®·¢¢bll¬¿¿¿³³³££££££³³³··whh(“¡Ë¶ô¯™ì^ýHáッƒ===iuõ²Oõ•lé5ìʼnãe·T\¼¾¾¾®®.%ºeNQ°>Cî6Lfúôǧï¶4÷_ŠÅbŠw_ñž™}Z©ôÍîûëGÿÚ=¹»emË_ßó×G_ûh±XÜ~øö±†±´ÎN»Áã°þ£ÿ{{% ˆW¾ …¡’­tÙT,ÓãRÝ„êꉅž¸Ø»+üôà‚{vùw^ÇlæÄþÈýIùߺÓÕ—í\ñƒÄáËϛx(gZ¢¬UíN“òº‡?ÆÞÛi1²È‰‹ ¡é†È¦.Å@c¿¼µÍ¼-þƒXÈÌ>Ççäb:1Ô\ð\Îù‘íim–$ânŸ.(K¼·CebkÎÜ÷µ¤[]¤|†Ög u l.J¸6P—I”1mÐû#çZù(‡ä†ª|õL?~×ÄW½ydVnýs¦^ôα¯Þ9ôþn'‡6‚©¦ì°ºÜ¢r£åÂEzžqV(¬7¥¨q®7º­Q}¯k…Àk¹ª\ó˜óF_§³ÜàŸ ,NT $~KuâíØå±¼Ssº|˜Ë'ËÚ˜·e‰•+”±bÙë¬ßbqNKbt»*~ Ü“8–º¢†Aq^>rqNw³ Ó±ò©ÞºÍGðDÞAÝnˆÝEyÞú|lÜX´Ó¤Ø»8š"-±.fòvbN:Òö‡ÜC‡Ò’xU¬/ç5‰¿¹ç‚øE&ÓÖб'þƒßó$µüа“Xó˜‡îtãH<².ùÊ£Ñi“’®WÜÏW¿ë½›¾Úš î=%™ôaW}™­Þ}5´±‰ëø45lå~ËÉ\ÌåìâXÚyš9L¥™˜e 7DnJ¼;ò=þ•Ù|ù1Ï‘0H 3¹šó¸ƒõTs½„‘;x¬eo™ø›<âê#¸àþó„l†1n"Ý?­õëW/ûÑ2ÑÞÒF___E)Ò½$†aÚLçäiˆNCv.—˨Çÿ§Â¥uÕžþïžö7lh8â³GD¹¨wAï_¾ñ,ºjQ[[UwUÇq‹Å;wŒŒtww§Xù²²²Ìt£T�iÜ3T¢Ÿ¡êÓB0ÕáÍÂ3kàqל‰Q»‹,n¦ÕL6#L *3Þtiͺ—š#-Je®^y@/ T$‰—ÿ¿Q­{ãºm'o;à{Üõí»¦-Ÿ¶ð†…r†š‡nûøm³WÎÞÿÞýËFÊòÏæ»öíúÓešsýœš­5J<|Çe÷ŠŠŠq ý¥j–é?ŒŒ¼¨˜U^žM@Ó*yll,õ2Þ-QúÅ»{©ƒ]^^ž½ˆLÅñåfW£/ØüG•Ø?qSätñó¼ý‹þÊ×|ò»^³ÍÁ_(ý•Àݱ×™Å×##¬ï0˜ ‚œÏ'îiÖÜe6SIÊ|¼Áwv™Ê§Ë|0ÑSô»È}zПMô³)oql¤Üœ:í#ž™åë]8×õ9mñlƒ[=¹Ã}œÛÈQ”Eö m?ÈΕ¾½ËÖFe/øÙ3–QÎñ‰Þ¼†ÈŽÄº¢çjÌšdZ‹/­°6±…ÙÌ]oVÙÐAñ†{cŸ ÎX°¯ŽµöÙfuÎÚ@ÕdB}¡™Û͈]^PØéWvz?]#ÝÛ]ËæufŽº4¥ÖŸä…Ùö[! Œ¾?æ{›=ûľF7yï¨gûó+%¢È£EËØ»’5“Í ühØ%¡gt…~yÝj×šÇ Å’œÅ‰“ónެ ¼!t`Ϊí5þÞäZÇ»Þuy4nÓD =“‹Ö•ù7¦'FiÛÏúÕšùS™S#bæÜÏ`ä†hç_s^xsì+9åìÇH™ã `QäHÂWKh 8ÏëÖéýmyWG.Jü<ô¡À¤hÁWüÌ]ûø×-‰–às%·Üt}1y¦Ûѱc¯²æ³|!×;/éÝŸ±–÷²Y,#ä¡ÀE‰3Ÿ_sñGÎç#ü©¼Ša>À79€,æ6>ʉó•ÄÎéÐÉwø31=<ô’b'ÝTp4‡2•Ï'.{éM§ßðÖq¿§ÊÞÊʞʽT?w}宺öº 'n˜uë¬=“†È¬#7x=Κv­'S#,M“ãôÔw›{RDb8ª««S�aéì*ó�œ¨¦óò¢§:I’šÎš)÷Nyñ´µ±¸thŸÚ¢§¯ôÏiɘN³2M¦‰Ú}/‹¤x%9õeuJƒxÖͺ©ä:ƒ\–ž!;&{òuuuY5…øÃ[–ަ&rǽñðÊ í§´wÙ¹ôª¥“Ÿ™|ÂE'tÕyÏçï™ÇüõÇ®ŸúàÔ~qÀPnq_<iý¤co;öeŸáÄwº[‰ŠRŠBv³ãV{?mšº&~‹²ŽîÒUk]orßa<º¤Þ¬>›cù¢ß…>û3wÌdæNKÜB;ý¡¨‹µ×êQ4Ä6^h·&çÔD?“¸ºÁ‡º¬"dߨw©ãÄPGâœZµc&‡¾2l¬èÀz: 2­¨}IJUÆêÅ#&sÛ€3b“¹)t@,ÈéKŒ$îxÜ‚· ºt—o'¸)pW¹æ‚ŽÄÕ¼1pV§º==bj¥¦öéKÌŸï…þÆ`Þ$ªžÓ”W™ùy䣫z $æÇnâ¾¢“8Œí©IcäYžKÌŸîÂQùQPÁ1y_™l[—ë§åÍ,øNlk‡sÖjIL¦#ð–Ä›C屑Ð~‘Ÿ„Þ»7ôš:ª¼³\KÑC ¢!-÷ñÁD±hEh]ä¦ÀÑ·ð;ZYÔ¨~Ô–!ŸÐɦJ‡U{MÁѼ.²6ç°Èò‚ÛyÓ >ÈGWûaèW±ã«¬Ñ3æZÎÜÃ$vRÏE‘ë8"ôÍØ8šýyºèçuÞ7äC‘«]É$úxx€ƒÙƬؽ‰ž:<ƨW?ëÖ}m>¬ÜQåEÇ8ý� çGÞîèa®¡Ÿg#›y”…/ÉOÜÏlú‡‡:"3Js7sÎb.ϱ˜Ïò†9ïÑÌ& ‡JN`yà)î#UÄ^Í:^ÇÕ\OŽs˜Âo9„xय़Íùü×nðÛØvØOáË~–ùáüì»fOÞ4¹Ôà<k¯•š]e±¬”ì’ÍEö>Zˆ¢(sNÊ໕/Ú gv¢DiÚÍÛûÁ•••)g6UÓHÒ8)©–²¦v[ ¤é*ívì”R†ËËËûûûSxáÞ3\¦è±—ûME§öBÌúçš`Ù}•ÎK%33­‰f(ÙIÒ|íªnžqÛŒêÎêô¾šh>öcן½þÐËÍç‡ í)a¤(‰T@ÒK¶‰àˆlÉ’YØü¿ÕÜ“ŸÀ„Æîœ.篢‰; Ô‡ÚCO*Ù—…n;ÅÁ̽™«}Õ6Uˆ™¸3TIÂÝ]VñpìϱŸ Üžæw9 õqkZŽöi27ÔÀߨ,S›(Ë™ÍT*MÛe04£QRg$ëuiQÀºÀ†PKh1µmeNª±‰E“Ôµº ¯2Öžè⯉WGV“cŸ|i]9¤¬K{`vNY^M ܦ¾Q.ðÖéš+Œ¾ÅÖ@»¡Y¼‘„1Ò§Y •òЮٚ3¹&´¼ËÓ<BnŠÞfí#¾¼ÅG=“#–ä-MÜÚ‡ tÇ®M¬ˆ¬,WQ«™eäW°‘‡?ç÷£úÌåôœC¨dflCbåL |#ôêÈ;=AÄvâœ\½înOTz Òhä¿‹¾™80òKsTÎgb‹C§¼¤Pþ‹Pç€Åcnâ„@]è &óüL­ÍÛy”_qdg³•±ÈïyNNä~ÎæË¬¢¯ÂCµ¶²-pZ³Ù‰žX“«.5Vå¿ Þrë"ßO=×íºY/ùŸJ‘§9‚÷ñ/|Šˆ$‰‘È(‡òÔK–¾=\Hsê3Év¸%çsŒ²:g~ ‚*Ž£—íÇMJ§q¿¤È¿~Fo`$ô ÞB }$Ã^lÞÍç-4å^ú^Ûž?åùѺÑqb3¥á`Îßæ¬?c}yuyeeeÀKÃP&pžF“¬ É2O›Åô”Üš’ŽSªlÚ‘N}Jø™¶B: K[:©ÒOij, šéÕNìó¼ÂÐ^ÄýFþ÷61ÿ÷–eš ßØØ˜öK³éÚ^íkuïӻݶOÓ :N)#ÍC™¶ÓžÎ™ÝÝðððÐÐP–€ÿ/#~ã`ã¾÷îÛyBçÓz:l ³ºdîsóÃù‰„ålKŸC6ÁJ)VÁ¶ì~Ó \ íI÷—–κ2U”Œ½WºS9I—hÙ47uØz9ÍÀ޼••ºçõ`ìÖœ3èmåFíg7Ýfñ¦Eqa2µ‰Ù‘¿'ZXÌ–FahƘ¯ÓÍi\C.ô¾Àµ‰–A?¡žœUæ5±ëb§D~D刃"Ï\ÆŒ¼3cŸ.:ž‰î!ÿ•óÁØ Ëˆc¦…Fm±Šœ†Ù Mrƒ#ûîT6¨—_2™+ÍžnN·¶È•æ˜:¬<ÐÊóŠÖ•¹¥ÍÒ‚†uEÛ‹¶Ä6øfd ±Ù3tÕ Ú]Î9õ9&>—÷Ñɢ̊<_mZ•ÎËkœ9`4Ôhý(òöNÏî¯en�� �IDATÐˬœÖ@åd;m*:1ïàV}C&å- 'gŸœ¦¢Ñ:ù¼}ÆTæ,‰=W0-2›™‰ï•qvÞœØÊ*•µ×8¤ /öª­µöÕ•8€‰%üñ�u]†"ûDÚ#-¡…±˜9ƒª¼#Q"`å4'®¦6§)±:ï_c? ¼1°½Õ¢ûŽjí›·8¶A~Ç4º8yÌjsq=w׺ªÆÖ´QN>6yûFö³•™ìë‰úüco/Ìo¦n·j]âµ\Ç9¼Š[y·sÇómÞÉß9‰c¸/²ƒÃX•wæl§î2—Ù—vNáižc£ŒñZZ·qÜÄ'ù m/©°/ànãÄ22%ðWNå(nå)j9ö%âÚ%ôQÁ_àœR{Æ-[¶\[}mÝŽºæÕÍÅáâžâ×äu“§¬šÒ¶¥-V>¸ôø­¦Ã€L¨;• Ê„½Ó@ :d%Zªc›Ž[’$IËqâ7ž"mf!8=OÎÒuEEEkkë¤I“ÒˆŸ¦Æq[’$é dœºné?m‚e¥ðqBGYR™ˆÛÎâ]UUUš®RniÖa›ˆ¹Ï`‡Y}9±ºšØò—ö [šÕ2¦‰ôáìR3‘½R½ŒÔ$¬ªª*Mé‡f'¥:&uF²*¶j¨ªuMkÓŽ¦Uo\5ë±Y¯‘f¬ìúKivoaœÏuéž”Qª'¦ùR*… ö˜éš#ãld«CŽ<nϪ};õÝÈXQY`,ökÞUôíÀ Î¥‡;w=S—¸7P“8·à·|‚é9Ÿˆ|¬Çϵ”91N2Ø+hö_[}¬EYäŠ.ï-÷[‚H>ò¹ÄÊ!?¬à~“¨¡-p=Zô†À7—\–óù‚€ÊifÖê®Tý”[#÷ð o û÷n=!ƒ*§Ú¾Í/"ŸÍ«Å˜ÂvÕsmíõdܘÆ~°Ñ. \žX9ä¡ý´nV·ŸÉ+=Ö,ÚæŒ‚ÃË‹Voö£¼‹x}b‘Bâ’HŠ=1æ;¼«ÝÂÀ¬VÿUcŸÀ'Bï)êt5k¯nuDàù½‰‘.ëëµ$öïwç.G…:Šm1·Çs#ÎYûä"_ZoÝ$gvùYâèÐÑ#î§ŠÍšcûº>RžXÄêa»†m }0qVâY²Êú¢ÿ©óÇ Cþ“Ã9†³C?KL/ZX“³¸(ʹ=önÜ»7ñ©ÈêÄþܸ£Ë¡›ùY 6vTân`Û¥ÈUuÞ:°×ÛØ>¨!ð$·òÙșыNiÍa®Ú…a£ß/Þõuà3Ïå‡>Ýöå$þ�$Ç™|Žwr3m|ŠMôx±P. ô$n+жl²”7±…ÕTò8æcœ“ø!gñÕD籎Ùŕ̠œñ(ÿÁY<Ï;YÁ"f'óeü†ÕüÓ)'¦ŸGù0 ¹÷üƒ.s`{qmqö­³ã±xbgã°®15ëk‚ôWšzI”þÎK`¥!¸T ¼1œæªqÁ7ŸÏg¨ëbŸ¾jkkg̘1yò䪪ª¾¾¾žžžîîîl¨¶'1ÃÝZ¿g]¸Ì2ÿ§£šá&&ÞW*ùšêÓÜ™¡-ÒVÛÄT”ÉL¼¬ È+áÿ[©"F) ]vd“ÅÝ6åörÍýåýåýåUÛª»ë·Õßÿ±û—}YÔ½›>ç¸PÊuËØâõõõ/ §œØb-]ëìEÞ~·ßÀ(ŠÒ _:¾'´×êj¸†nî¥3oIl&gæ]ûRèg¡y±aŽ*÷2UÍw(oõ±Mìb#¯‹\[ã†1ó†­ôËjîÒ8dm(*ŒÜšXÚâ€!skU&ÎL\Ÿw^(¯£à1~Zå€jÕX:j#s)ôëß鿆5EêË<+Ë{m`Q†­ÕÞjj—{';DoÞ³- ÖçìÜeîçcAÞ“:x5kùZlQàÜÄp¿ÁQïttµÙ=¦GÈÑ:¾`+y2¶#ÑT¥ØoÈUúb—ä,ŽmÈi k,wv 62fÚøYÁÉ•f}§è¦Äa«#GÅ6=ÛÌÚAûDª¼³ÌÖ+úH‡0±3oIhYQk«Îß }>pGâW¼#ö­œ7UxCb¹œêX_¬´ñEò‰‰7†zB#öe*³¹«NEÎy7åÌ+·O¢w’º óŠjjÍ*³¡à÷lÌ;‡59o Wp}hZ`fd=-¡ºÄa<ĜΖ1oUÃ8?°1´€s™Ã,Riÿ.ºƒÚ0w|Mòo¿7²Éê9üU±Ì݉ð[é5Ø8V¢žõôñ~À;¹nn椼}b›ù1ï »•ÆÀÅ¡ãp>âÇ¼Š£8Ÿûù6[¨¦‡ùv Ê{⮦“…låNæV6p;?d_d˜{hås dz’7°,«®zë]ÿëõIa÷Ë󌕒­O3UºôŸâ Rßú´Q–F“t•ŠU§ËØÌÓ/{eá8kÜeKõ´LÙ-æjÜ‚=ckeS®t*–šæ†ežV{ãÔƒJg*{B4Œ3t/}uT³ŽåÄ“¤7U^^žI¦Ô«Ì qâB¡Ôp·lÖôSRY¼ôigEçDõ÷ì­eƒœRÝtI‘q�J582ô¶'3Tô’-ÖnÝIƽ¬þYý}³û–_²|öŸg§O£l¤¬fgÍS§=5å‘)»ó•6î2Âxº J}™3¤ån««¬E<nOV­f”ãZ¯é]Ó]Ìž¥F*éV[[{èQÇïEⶻµe¦Ý 4…öK|;6‡öÄý‰æìdyµG|;ÖH÷ˆ"38˜ÄcŠå L œÐèÐA‹SC'1=4;ö—DÊYk°¨ÔjêØ§¨nÔ¯[löŽ‚SG%î=œsLN»†[¼0¢¥Ê¥eD±ß'žâFuƆÍHÜ7Så˜ê-µÚƒuŒYÒª©_Sbm­rƒ*ƒ-n©¶ï°á¯ê7iÄ´HGh4Q¬Òèìßäw‘Ee&=[ï AWêXàÀ÷F©R[¦)g¨Ú ÕÆÆ4$¢Vñ°Ë<?¦yØPΉ͉$¶“ÖœÆDH95\2É…}5G†›ÕÍöÈNEf÷ÛÉ]‰ço •˜XX­®Ú‘Cúb剚@M¢‹Ó“B…ÄpÎ'BM‘{†ìd |—¾Q'ÜÅ•å¬T6*´¢YÜ£wÔ¦1•ùHìô@‹ý0ò æÄòœ¹g©Ã1”s�¿` Í9ÇÄ~x¾É~±‡ymâ—<ÇíÞùK'Ý”,{Ü`»ÚjO徟V¦ªYgÿáÜcgSH sÓ¨æz^Åöœ3بc¿‹ýY “0¿^?:§X”Øh ´²ü%êUÚœO#{Ñ5´—I¡Áĉùôð Û9„Óx˜),¦‹°…ÓYÁÛxŒ¶°’%¬ã­YºÚ¼yóÃ?œẺµÅnÓUª‘ý¶³P’¦¢tB“_V²YB d(¿¥Ô¨qµÚžÒUši²ÃÒYB©IJÎíììLõÒyÌnÓÕ¸Y]i÷lOé*»ìôöS8b*X,Ó$]ê[Ÿ蔂–²Ž²ÚíÍfù ë1î)]eH‡,M–Úàf%Qz©¥’ðÙ=¦À÷¢½¬tOúʲ·œŽ”˜¿”ºme9;SÇÏårÃS‡7Ÿ´y×~»úgöWnª ʃúŽ%k‡Ç†{ÛzóùŠîŠ £‘å§Ì¿#ýkº‚yåé*K6¥{v ªÜmÁ½ÛÓfþŸ¥[MMÍÇž¸‰Û0òßzRýS<Ì£ŒøHdtq­ó#Gº%rc (2‹ç#—‡>Í­üi– ¶©®´¸Z±ß¼A÷lWØ@Gd2Ûçì˜ìÃ;;ŒPÅÞ”èŠËXdˆ[èa3U“¬ÞénærÀ£Ü3j°Æ[¹:ñþL ÌÈ9»ž]ÊûTñ‹¢·õ®–ú/l55°¶^çˆ$2ĺ­­>»EZÚçñ[à˜XkÎÚDËrª"Õ‰e<ÉH·ÿæÀaëMîwu«×öë‰ÔÅ*vjÍÙZor£²¶¦Q6l[jH‘øvàüœ]±ÚÀž¯vPÎò~¿áˆn›k´…Ö÷»–·G&osψ}ò¦Ä’З+=×§ªÉÌ.O&úû0¤!V•·µèÉîä,öὡ™±ïµ:£CÈk¦Š¦À iÑØ¿*Œé sáVã3üU‘ÖfùžŽlã ,ç\~˜ø`¢{ ð4‹'9½ÏìÈóê:¢¿¨=Už-XûCâ  ¹p•VÄù5ÿUüFD‹¯t-½¶qªï/ðôÅÉ÷Ÿˆ r$æU¤ðî? ñSú9§9‡àÚ˜ÊFΙË%þÎ5/1ÆÎäLa ]Ü\æÞj/ôz–µ)à"6“Gáúxží¬bf²ŠA;M<nãd"v²†fØìÊ$½w-ٵᄠÿY-ŸÜzgk)*C…¥c•”æ©Äî/SýI©­­MÃúË‚úöTZ½râp___:«Hy©ûK¥YZ+¼’+I£gͳy^ÇS4ÊÐÐP–cÒôœÖLi™•5¸vÛ:Kå ³ J¶ («ýÓ[ =˜b|%V/»]@ìiϺ·¬ž:\>PÞÐÞ0åoS aïÌÞ­ïÚ:ã©éÐ(~!®XXѹ¨³nm]šVK¹JkšRטôá—:ã.>[ceÆÊéž‰Š·ÿÏá‚»aêƒ!W]㜕əÅ?ðÇ~›wö´‚/ľ»Šÿdˆ³ÙˆjâÐÁ±ßw™SdXÿ°ÑÈ}eŽ.ØXo¤¨vÐU|3ÖCcì–>?Š}ŠGãýÓ|{›Î@ ó»M-s|Á5 pŸ­•ë´œc¨bŽLl®°6ò·¯i—ð'ó×Xë°i9ûíåOkl[‡Õ±ý#¸<ç3£â¢Ñjo® IÖZ]°Œ†Q°ƒ:ºócOWyýåõÎ Ôï4eÞZ49¡Ï#‘±~“GHô'šÊœ[Ô1"ˆ<¯v8#ñ'Îä6¶N÷©‚É]ö üw›¾íÚÆ\Ëà2ǯñ½sGÜËú't«î— xs «àn¹kÌpÅ7ç]Þä{îŠíLœùÓ}hÌ»‡4'¶&Љ{\H-ùïNl徜}cû³¿%ÎKœ›¤®QÞIûTŸSb7°$gZìS‰cå±c Ë\Tp݃ò±élưOE†bó1žëó?¾Þ’1O7å~xJâðøéöxxV^wÑý>9ìò½iˆy|‹o¸à;ñU_sÁgùÍ|K׺&6wÒFCìJ>Î ¦1›ÿdo⼎‹/ýKrÓ&+_OS¢?ÅMðXJc”8rß1Ê6>˜êŠ<ÂÁ/e£.äj6°Îû¿ŒÍç·Ôóz~GÂt¶ƒ¿Sµ§ŸYïÌÞG?úè´G¦Í¼&vÍÛµò}+.<íÑiãVôê!s¼-ý×qø‹,¦]£tÕœ®ÜÇ ÒnUyyyVpd]Äìàqž¶Y×(#Ò¦ÍÀ´'™¹§A0c(˦xï•ØþîEF(U¡Ý­÷qzG©BmmmV0í a?±K¹Ûòwï )ŽÊ$ ²W“Ù2ÇŒ¸=N@ëŸÛzöëyúƒOcá- §®œZ>TÞÐÑ0<<WÆ•ƒ•Áú`ÓI›fß=;=¸å–çnìß;ií¤LW }}}ãØ]¥_€R¬G¡¶ðÜ;ž[úÃ¥ãÒUzpú²d¿w¢[iµtQ•òùRõ¬¬f;*ãFY¿@‘úíZiëõÆïÙùUäž÷ú± çòúQ·ó/ÌàušD=Eޝ42ìBÞJݘI¡¨à9þZæΘâGÊIØFz!pdä’Q·¼¤å³ˆç¶ 8½VàuCšZ oq*£´N÷õv3ø8³¦ûÍtfàÌnç'®l³(ðÜÉËìZ®nÄ \Ë13Ë4DÖ$Žmfžê¿+FVD¾•÷ƒv…ØX™_‡’ÄÖœÊ!ä|#O5¸CT°dÀ¦V£G+Üejdyè/±¹£ÜÂÔP_ìÒ#u†ªô×x¶Ã‚Ꜿ sÆœŸø&a &ñ þ­Ã’‚Ÿ&:9q›É¼·¨“Ÿ° ÑXf×$Íš–Wh/x¼É´z ¶QHlȹdÐ3;ÃäD'Gç]_p_¯ºÄÊËl)º/geàÝ£:øõyK#U‰C§ž¤·GϘáDL ´q%í|—7jÊ‹‹:#×Osq¯ÖAAâ..3«¨‡“¹fÌ\ÌÜÐ)÷ó8cÒ몑²Û¿ç¢–BñgÑè…ŒpMâJN"²f…ê)¦_hë¶›öW›Ïqñ¥üŽ®µ~û0?äÝ,áÓ©ÿ ¿å­ÜÁþ•;ø5ïáfï¸79ÿOþ¿$Ç>#XÈ*a~à‰¯ÆvÅ–r3 „‰ÿ‰| pkâó\Ç\ÌlàRÂÈÏûsp*çAwñ ®¡)P™¸œ‹Ùm»o¸ex¨e¨í‰¶¹·Ï ¢�mOµM[>­jWUÿÇ ´ÔêŸÐ J’dppp°jÜõŒÓÛÞ¹¸Ô¶ÔNÂK†¥Á«T̰4ÐŒ#öŽùd³´qõÖÄÛÇ.*-VJ•ËÓkN!{‚KìýÙf[&]Qz©™Hé°ª´Ù˜aÇEÿ,ì–bîS¾ZšêÂ0lhhHe¨ÆÇé‘ÿph]õ¾UÇ|똊þŠâ`1‰’0 GÃџ혰=œ38Ð6PÙU9<m¸ãØŽŠîІµ ãt3àLi z"V0‚‡¾ðPåŽÊ:¹îé]”mésw {Z:L˜]U¾r£OÿÄu=Þ|³Ó#¯-O^Û|ƒßMR¼š»ide 9´6±&4ÈO²lн †>y2¶•™7E¾˜Í©þTð÷ÀôÄÑj/Dþƒ§¨ç¼PÄôœa¸&õjuT¨mï±3gnd=· ëša]Ÿó͉¿:úŒT[û ÉVÓc_ ½®Ì«#±oÆêr~èÍ~Agà¼ÄãœëÍ;±\Ådóöqê€WMÕÔkAh´\±OSÑ…¡w&VWˆžµ¤àÍÕέsИ¶Dxw­ÑJ¿N¼±h´Âëí³MmQU >öÔ+ÙÅÇB‡åžX[¥³hj¬†„<›qøw]…}c¯po¯„ª§˜2¢bÄŸ)†wÙ4æ«,Nt…BúræTYSï§C†Y›šX•x$0¯Y͘#êÔh`PGàÜÄïëu'F~ÈÇž4˜øeâÀtÉÅ¡7'*yŠ}y>tý$r;Ïö;j²áAå)¥)¶5oGlÒ%·ÆqõÉÆúØŒ²’r¬9Ëã+¾ëß ü,p9–é¨÷Æa[Ùîú‹|ãf››´å?·ô~×½‰rîMÊ"ZBS¿JDÉZÊØÄ{˜N ,¥Ÿ¥ÁS«Âï.M¶7rtZîžeªx†£s>ÍŒ²9œRíé‚õ9O³ŠY´°‘7RÎüžÆœwñaŽe-ü ÏrkrÎçQê8“C³ÙÕºuëþö·¿õ,èyø?N¤º½zÃI¶¸½ë®í( ÊZ6µ”F±RQ³éEºæ7$/uYÌæÛ¥ã–Ò-3­ÏLÖÆÙÓ¢¸ôÒsöõõŽŽfƒ¥¬‚É.l¢Öm¦¦1îƒ&’ÆJÕ³´šb£3‡ûl„SªçîÏ‚l)’¾TÛ0ËF¥‚RYû«t“Y –"&²"ihhhppp`` X,¦¨“RÄDVïî驦–;)µ.­MK…äöH¤¢Pñ¿Òm>ÙzÂÖ¡–¡)N‰£xbd¯m¯l|þôç ¹Â—>‘ rmO·MÚ1)3ëÊòëÐÐPúçT?iœógJ¸®­­sÏœéOß“%Xúí;iãR]¦9î¦÷[YYY]]áb&ÂåÇÙ3NHW5½ß噢ô8§:øñ¥áoÞüæX¿Yªx<eLfŒ·0-q•¡%±éCZCç&†C&–0ÆúÐV‡>TmK¥žaÿ8*¶1ÑV퉎˜É~,l4£¨¯èi864ƒ_„^Wf}¢6RCc¢“¡Äã=¢)íó‡Ð ­Œø]¥ÕÃ*ÇPÇ1¡¨Ü_©‰t Ì!娑qCƒ¥#n´çìÊ9l¦žMš‡ÅîM,VÇŠZÕ‘)9‹ªl.˜ÞÄ Á¼YÕ«2gÄ@"µºÁÒ¢•+ >”xŒFUæÜ8 4œ˜FC¨Ž Ê¾‰“…*ù‚ZvÄ–êC'Õ˜ZÐScÒ¨³hêÕÙœå§ Š$ÕŽñ ڣ̎]ÁºXuÁ ­Ü–¨ ´óH¢mHoâŽ-}þ«=^¡¦ÅÑ#F ö ­H<Ë#¡y‰¿Ð[mA`n¢.ÑÇ$VÖksü )çµ,q7Ëh¤)öQN È€ jPæ˜ÕáHƒ­M9‰?ñHøèÞÐîÇ*¡Ç9˜úØcÃBBv(ã‰c¼í~ûßlÍS>õIÓ9üiëj¸¥\žØ˜A ~K^ÔCÚB;rÂD%¯í:=q:9ò¼!t: ëyžù‰‡)ãffÐYkêˆG¨JôòäQ¶1›³y2E‘$Fy<çˉ/ÓÈV¶ÑÇìÄ_ø[X_ µØ°aÃÍý7wÚÝðBC\Õ-»bÙôû¦Ï|þì‡fOÞ0ybcdœÏSš-Ò~Ky'q2ßáÌb#,© n)%3YÙ²ºë1n˜EQ†ªPâ͘u~R|AŠELÏYUUµ[hÀ^ÒÕD[ú‰høô#&æ€qbE¥ ½ôšÇXJçùYzËâiÆQG Îê§ì°´Z,S¶@Ê{ËøÈiZ'E1ŽŽVºøH3Vú‰é¤-Ý98{pë1[ûöíë]Ø;yÕä(?óu;ëú§õ7?Ö\:C*}ªu/ÔM»wÚÎv¶.oÝÿ§û×¶×n=akmGm.Εâ-³fJòç…VšŸ²ì²[yŽôý–zUgÏ0ssξu™írö½Í2Y+»4©çr¹†††eG»g¨ÅæI¾°À?æ×§ëÛ7&v$*ù ¯å<IWñ~N%¢<ð{Ž«‡^ßï·4ñ#ÝÆ»‹z{Ü6É3Õöí39ïø¢áï&¸3ï´ØtnUµÔ!š6©¥2±_俇œI’79R(³_ä–Øò¼?¹»Z>06âç¡W¨o0·O _kuéN=C"š[Ûm$t_hê×S1ªºÚÛB[-‰¬Ûa€¦~›ÝebâØ½Fcsò~VtrâáÍJë}¹ÉC´çMKLå—5Î-¨öPâGUFÇŽ¨ŒÄ® ´$æåÕ'úc-½*Ê…¡™‘{y΋VÂ&nèsJìžê5ا |D‡3e§ö2ÇåõRǤD- Gl/šÁÍGw¨'ﬢ‘D{â˜ÄõLWd[N¸Åì‚G½,¥ÙEWEGßhó4—¼6rS죑¥|Ž&ê‹Þ—øZàØÐY‘ÞÛêÜbªY2ÇØfß*j ‡§|ðY'œí²®ø¿pþUÉÊSÙÎÄTŸ?ÌþÞ'FcœÆ¼ž}lç×6—ûEW.lüüÉICâ§ßòäv·Íät/ÒªéàõÜÅ—õlg)ßIMÇö UF¾;‰!/büÄ6ò{.c”»YËtZI…3ÝåïÎS9Eô°–-\Á]LgOÒ•øzÚ·£“]4óV®a„Éôý¯1ÃâžþmýóÌßõ_w-»bYÖôKãÚ¸WZRdÎГz9Nlú¿rðELKå2½ÑqVZ]e8ìqgËHTÜ9ggàÙIÆYÖfúRY(ÇÐú?ÕõÉÂåÿ= Åk”^Ã@ÕÀs<ÁÂÛ¶<ßRZ4£ye(­®R3ø4p§w:¼ßpP&==é©Ï=U¨*,üÕÂôñAд½©g §gYOÛ3m¥kŽì¦Òt8÷s«ªªTYÜú•ïXÙúdk8ŽËIi>(Vd¯;‰¤HÔBbªÔ™ºt@˜©p•>·Ô@§Ôyy"Öf/³+Îé´å`ß?57r\‹Û=Æé¼'Г3¹h.c|˜f6Sû÷Ä;ñ˜¶Øã‰éef'þ£¨“ æå=Ñä5ÝNoV>bMÁ<Àý_ð™6ñVùCš×Ú2I‘O’PÆ9œ¿ÑY˜øCÑó|¸Í™ÝªzPf8rà]±Yµå¦ÔZÙï âК툦ZP®­Ý‘cú‹iôLÎÃ̈u%.t}âš¼Úȇ{t‡~˜)DàC¡úÄiyÕ5Ú"«Ç(s`Á³#nñ¡6çmsˆUÊØ¼Ä}9m ¦túmbÕ²8±‰¯%zf»j³B‹s¦}$狉ÆÄMeÞ³Í7c—õ{8æœÈÏC]\Ay¯¯VÉW[´ÓRà\âí<ÈFËÚh~§õ‰#k§ªl7›¯ò0—pИ ä;‰Íq°Ôû'û÷mÞý?þóK.©µ–<­ìâ:†láUUö­Ö¿Ó&Fw™Åvî`qNE츼Å`›+Ë\·³Íg*L½Ã¿};ùȦ|÷ ‰-‰¡øŽ.ߺ—Çq)Ûø—“'ä8¾g½Ø‰‰‡Uœäø‡=q8ï'f?^ÏßóNŠÌOükâi&óy†àLfÄÐ{ž}øƒÜF#ûä5Gþ;q/;¨æbæ"ÞðR£ïã,änà".aíK¿„ãy‚ϲ’z*bkø"rÒÇ÷é¥ë¥º³DgKã¼ÛæUôW<ôé;UêV�� �IDAT‡ŽùÒ1í¥ÑjOZvé{ä: 1ã¬ÿR1‚ —•F™´ÐùÿX{óÀ¨Ê³ýÿsΙ=™L2ÙHI û¾‹  à†à.î[ÕZlÕºµîVk­ëëR·¢mÕº¯hTdG°$„$=3“YÏ9ÏΛ µï÷wþ a2çÌsÎÜ÷sß×u_×ÿ#ð§h~}zA–ïO%d+£>T·>’Eãîßq꯶gMYYñÔ´.RBPV'*y†Ik‹ZÇ¥¨„ªª===?Gg½O¥‰E6=¾É´§Ö¤ödöd“ýsv ===–ŠÇã‘àY0?Ø:²uÔ;£ìÝö¨º¼jô£EQ\A—=næGíûìÉŒ’þžÅò C¥!iÒ’´�E«öu¹\@@nwd¥F­>¡eæñx\.—µ±°6(ɸãOM…ËWö'‘ʧ·¿|ÿ½T¿t5¦†Q»øCt¬>ÄJ•á>“‰‚LßBŒ‚•0šáyÁÙêàƒ·UƒtvÚHUø‡ ªune¢ÂoÛˆ+œ,h„í C'Åù¡™'Suv*usm€—2øN'éãTCXPngb‚-äñ§AnœT?“"<cò“ÜV6@FìçE°²w0L!_ð*ÎÍÁˆ4¦´¢+¤Úø"ÁPXÀ¨n1fr Ÿ»'ªñ™É¡|FD¹§½ uQ’Âä0“\ W ƒšÙ"xFP5NÜ LAI†`¾ÂpÁe —©üÚàÆ<Þ‚kë| 1âׂ‹M"6ÎÒXÕ .48!‡ß¶ó•“ƒ u‚j¿Œ‰ 7C±B™`¯`2d:ˆÆßB=4Á@3›¸VáJ“LFj”&h†l'£tf Þw,x<Z4ÿép˜?‚.'õ ö«QˆÃéÄ#<á'›ü.Á…¤_Dý­û»6ÂÒ£Ú›ÏëYó<¦t._PÅÐ{ôMKTÐÓ Á×°óφÿÑðjLt˜d9hŽp¬¦e™M«ÐY€Óà58NãrA»`1Ü«`<\�€?+€u‚‹à…K/ÁpCçdxšà ðà ð�HEGx�î„vH…p:dŸ¡ ^…\pÁJ8–€ž‚k¡³—[Œ| ‡!3ù›Ô>¬½öÔÚЀи%ã\m²[p,]€£"ÒGU^ïCCèO¦°hZý Éqö¨`ÙE&K¯Êœ!õ^“#QòRŸ1Þþó­É·äßXˆÔ˳6ì@ZZšŒ³åAv¨¬u°›E¹Lžñ²ZRÉ6r�ÎJÉBˆÖÖVëìiii†aHîÉÆ§7N»mZº=½âÜ =¡Ë‚)yL; ö)¦eÄÅU‡ê?|¤3Ìn¼uã)·Ÿ¢( 6\‡\†Ã¨»¢ÎÕã*û¢ì¿¥9!&¾9qä’‘?ÇÍjÇ%O:[,Á><ˆ£úy»fM+I..…@ ÷²?‹YÜOP-jÛøî˜0|‚?|oÁ|ØÜ«ˆó?³TÖÀ{v¼ÊR™l0XŸNS”â4Î+¢ªƒóL"‡`ŒïM !¦2* –y˜ë #Š ;à¼(ßê$2ÈŠÓ®Pé`’ÂHïDqÙj`ª„ F ÜàŽðà:…i´E aè„«à€ ¨|¯1‚‚B;çÛ(³6Š)¨Ñp›ö±ÉNm”1ÞL ‡Ø"𯄛L¾òpf' '³×éÜg¬‡ZÁtðB³›4•é7Ù0í”d¢Åè‰s½`ŽÂ]eŽS¸3ÁÈ _™¤(î÷jüBažBºÉæl†ÇXep…Ê Ù=˜&;Ç)ä*ÔVrzïB=¼ SlT™< õ€Ÿ1Q*\ÔY _¥ŒðO*1Á*Ý — j³ùVÐ`¦îÍž;,Xut?'énfå•©`²?ATÂXˆšDa |#Ò¨0øÁHĵ«¹ ‹ü|7R^,Îù½¸0Λ×ÑüG§Êe‚õóËÅò[xi8B%ž‘à —P7 L>†‰P-¸ß Íä÷Êr˜ÒÅ6Ãy&ÍpæÃR‡sÜÄœºIvª"¬ƒ!pB†Æmð6,€—Á­1N‡½ `:4ÃK0vÀ`ØðÄatÀ.С š`„Á N€ãàBx:`¸Òr  fÀÛ0�*a(‚K`ª…]µnlýf×79ÛrR¦ôÿ&÷O$Éq<™ù–LFèó>Vd±ˆ2dKw+Y‚ü”Eÿ)Ýþ!£O$²Fb“Õ,- ËËÑJB}R‹d*[ê´R$²ýF£Ö=Yöô§ÌÖ4²Út2DJâ@zzºÛív:’E™ ݹ\.YZYÊ M?Ù•¸Ïf_zA%‰®a]±´Xú®ô¶Ymqo<½&Ýô%gùyû„x!D{iû¾9ûš†4õ¨=ÑxÔÕíúîï•Êß“/?N"‘°wØíQ»i33«2˜G§ÄCÙ!_³Ï·YŸ¢ÿàmJJŠåŒl=?C;m†M‹irlÙ‚š,± ¹5± 8©wœ|_䘄£÷°ZÄýŸðþ÷®ÿవ˱.µÏûx½Þ©ÇÏ>†ª…{¡ê` Øà[…10 œpL‚0Rãd¢ CCtª£¸zXš Zå¡\eËH´ªÏÁº(ëLÞÓ¸ÒÁ×ZMj/Àð8:AqDµžT¨ˆ1G§A𱓔,œ £ÃÄíh§L`(ؘnÒ.ÈwŠRík'3‡¬C¡@å²lyÕÃp â&U‚t?Ù&¯ûÈw0]0ÈKO„ïMJìu±7„i²Bá_NNË 'B}”X¡ò /©«âüè`¨›N…¹ 2‰§ñX:+š8là÷34Êñ {M>RY ³)J‰Â`xJc‚Ég&›¤@¥L°;“ Qèa¿Âñ ÁU­ÐiR+Ó  ¦sn„3A7Ù%0Q¥0F.DÌ“ ùažCà‰ñA£GMžlÑgYðNð¹::Gsû"EÚ3û¥àM)ˆÃnÎüÃOç@8š£¬4x‹‚/¹a"ÞIV‹V:SÌÿ@ž9ž-ùª0¢‚ƒ ÓÅïÓÓÁ¶½ A-·ó‡ûx7ÖÁ<xð Ëlé¢ œ0šà ‹;8#—üÃ6w¶Q=+A^‚“`üÐ ¹oB9G€º¥‚ è‚쀸Ra7D!j`>L…F(²  Z¡òàsè"pÁ&˜ püð5ŒTø†@ TÀP °¢`O¦Z8p`ç;;ÓzÒŽÊ$ã.™£•¬Öcå‰dÅKH6m$EBò¬7—C-r@Jf+[Cðô¨éJ'Zñ²9iÅâþ"°GULN<ò:¥ÏrrŸSžÑzOù]×¥S”œ ¶48, ·Ûm©%Y,™˜Ýn·¾%@ŽËËö©E8Fºê3&ÿ¼êÒ*Ý¡wŽî<8ç`ÉŠ’¬Ê,ÉÈø7¬5œÑà¯ö÷YÊK*­T°¦ cBG 0Ð6©-»!{òç“%ÛP^’B1•®!]žv#äÐuÝÝè®9¡ÆÙì´·ØåC~Âz~"ù‘ª³«¢¹ÑΑþ=þxäHV–Ü<K™Â¢›ZR}t~eº’/°P>{VoP®aŸôÜÿ¹²žI©ô؇îÔtÕ»ŠB*ÌëýNz`¤I|cã1:X ¨¤CÒ ÌìÅœ/ÕÈ4ðB´la¬É¿T+ø ^Ï¢=èo 昜Æ_\üºX°Í º7”¨à0)ƒ8´ {è°1½‡*04Ü*«l†TȳLÆ€!°ëð \õ a'©`øDÄ#0U„Éèeê�bÝ´ø¢D=Ôu³7JĤ°{ÓDM>©9 ¼q^5¸®‚í\THw” ƒU †Åø Çã<¨Ò(©‚z•ùv&éxlœ­,2AäC ÌLîV¹1Â`©0ü !“(d×àf82á_]Øì,Ž‘¦¢ìÀ•­˜Í‡I¾ÉÖ¯Â((…Gà×)\©02ħ:‹M<à‡óyêoRÚÂýÜ©°f—à18ÛDѹIà¶q‚N65ûé–͇Çȧã¹ï×<<öòY\|ö=ó_¤©‰ àºV<r;·m‡]&£¸3Ä õ¼z%¨6ê‡sy¸ª4~k\=pvá.ÜðgZX\X/ð›|[ϵÆ7Ï©»ï¤?— öÁ}ðf/Çá ðÁÉÐ ¿�y €ܰÃtøªàX »`1¯~@÷{Üv ¼`‡_sD ä ˜Ð¢wø÷;¨8„á\@Péà†?Â@ø% ‡“à•ck$[ùý¿ˆ&בÝÿîqÝq¼t[©õ{kðÓbp$ƒI?snW$.׿M&*Õ%CGÿQ@Ö:¤kI•¹äêDÂr–JïÏ?ä†Ýn·K­ked ”aT^@$9ÆÔZòú[²XÁ}Wî #Ù‘iOL+]SšS—cwÚ%"%ÿdçY;[¶ ýlhò©…‡§N=˜šÒ˜bï±ûdXh@(<(œW•FUU­™U“ÖœæÜî4MÓSå‰ ¤õ¹ª…K ­Ù«<*Â䤗t7Ý *ò·å§×¥‡ü!ÅüÿAºW¦¨Ö­»ÏØ=⣮.‹}*«üŸOÓÓlòîX»«Œ;V30±k¸3ì Ø  ޤkÌ2Ù 6î´ °Š  6Ç™¸m¯ó½Â… ¡Da´Ê|Á8…q ¥Ãr€ “ÑÐÅößÌ„õ‡,8 ZeÓÆÆñ‚áÂÄ( &¹*Oê 3¨Üsàm¸Ià€=Âb£2˜ÓCž5ˆ®PçƒgcŒÕÙoò%,ƒB“Ç£\â`‚·—E¨¬OÐ!ÖCL'j²Üp Üê§»„ñA²£ ‘íeAmœó´Ù˜ŸJ™ 3ÎÐMºMRŸ`|#h옂i*…*©&A»›F„—!–Á8ƒ*B“Ú‘4·²\0ÁÃp d[:X&Cã|*H±3+Âe&“¥°Op£ûM{3¶/1^‡Ël÷r_7©‚!‚ ÀYY 4ú@ýãsfÞ§\1žò»Ôør“)*תÄ9 Rom,‚KËY{ KàðA½Š"^üœôÝ|¶FÆRõ,‡²@�_<ÏÛ{½‹G»Vý.fŒ¥²˜À\fcí8aª ÙÅuÍ,¿V^ƒ›atŨ0©Ìœ›ìÜaò{˜Gõ}âÖ¿‰×ŽgÜKbvÊ`¢Â2™|©° € .È¡½B´Â˜ ~xFÁbH“@øáÖe’Û²Ø •8jàØÚ«ÆT=†‹`$<'Á °¾ƒp1Œ†Ð %ÉÕU]]݆ ¤r’Üþ'·õäW±ÏÜU2‹ÚÚ2'{õ§!$ë*íJÊá‡p$„Z!Ûz·Ÿ* –ÂçŒaq²“-!¬ÞN¼ª?°aMŒÉ<zTØÃ޳’«Eǰ*!‹¶.Ë ëD}LI,a_YœÉ“&sÁe'J‹X¼í„#¡jj€Ñ…ŠBá¼°³Ó9úÑùßç»;Ž”w‰D"a$j§Ö®¿u}˰–Ñÿ]½ zІAVãTÑ6¶­ú‚êÜ-¹®.—¦iŽ#íPššPMÓl˜ÐÐÓ}püAwÛÞmB¤W¦W\Z‘^™î޹qPsF£Åaï°[Ñdšƒü§ÛíÎÊÊ*++B„ºBBˆò‹Ê-Žºê27d¦§¤ËÓápD"‘dw±>.!}ª+Y»ËÛÇíÝöÌòÌ”–#zä69{£ŽÿTº²ZûT¦+Çs,"»—”ì¯fŸÉ bÊe„g±û)¸D‚WTÎW ðÂ&XàC…Û\*© 蜷»ð¸±uR§ógÏf±±À\Íp¸N†C g‰¦§a&œÿ?¨6Ê ž„tä 7E1îÀ#‡P}L ³#Bø :ó>üÒ’ í¸lW¸O#-ƒ³cœæd“n7õvÂíœ Oü:Äó _ÙxR£ÞÆ•M(‚ Z]¹˜ÓÅ*A¹Â¬�gÕ³Uá:…𰃹Â,³1-ÎyÜ£à:¸ÍdBÈÆæ@‡“W ¼®r"ŒqbÆù.By„ëaüÁInŒzƒ± ™Pº—¸‚[e™AŽB¡`¸Æ§&¸O B‡‚Oðµ ÜYä´ð#Ü—BÂáqéW…ñe¼øJ´#ç“vÚ26LƒÁš¶ƒš,ö_Ií¤eÒõî�þ§ §)m/†Ïà æmÌÏs/â¾Wá1ë¡0‡‘‡gþI¼±˜B¨oƒíP×Ã?¡«•ú»ƒ _@5y L÷_¨Wyê)´˜øÓ8>|š1sTA\‚tÈ7ø~×ë$ù•‚šàR°‡öGÄùy¼¿F|5Àðÿ :ávPa8`)Üåð ¼mpœ'@<÷A+|Ci||pÄ  ~«äÂÉ&©°Þ…ã æCtÃa OÀµ°öA,‚zX 1ÇÖ¿kdq¨b¾XÏ€oƒ×¶'ç+ÖÈdr3DþFFêp8ÜŸ#nÑrÃîÞx,'n}ç%õ YÌ"Ù±"YîRu²ç–<[#-£’IŒÖ餎œœ¥=6ÝÙ*7%³ã¨ýÒþ#bÖtrò–LhYŸÉK²våV*²P–P(Ô'§Zê–Þ a==•WU–¾SêªëëByDÇ]3£YQ_Ït˜†ÃŠP„be²æãš÷º¯ìý²ÂÕ…íÃÛ£éÿ0”Ÿ¢xyqwiwWY—sŸS.…Œ×†ÓèðtØmš¦­{bÝŒ»f¤Õ¦ÙCvW»kíSkgÞ?³u\«³Éé­ñ•/“, åp8º»»{zzSÉÛ’—¹>³ê¼ªÁÿ¬ÆTÕ¡ÊÚ‹ÿmC%?Zª5m·Û¥1´|nå’Æˆ%o¤ ±ÜXXn¢òÖ5cYãÃÉy±ÏÖÑ««®ˆ¢KeCì̇¹¼Û¾&ÑDOmŸCª BL› ¿VkvˆÈ>ÈPH(Ôác¶ _œO­°Lç’k*UÃÆ »Á :´A=TÁlñp!ÜÇ‘Ö_)´ &+œ)°åSÒC •5Q¶e±?Æù]|£° ÆTšW‚ *5Ú85ˆÞÂ7~øJåW^²ÚY—`¶Ÿƒjš‚H0QaºB¥ ߯&9>Ú»ø,H¾ÆDh·3-F¹ƒå >Õ¸ÛE¦ƒãtÚcìS˜e'l£Ã Ó ]!ª2MPÉÙËØ_ƒ™ª²Àd‚OÐ{2Y�¹qNÑXæã0<è v˜èp�² šÁõa~ÓË@“°ÂAÏØ(ÒYª1W¦Pe²I°L•j‘&ë¡Æ`~:l„¶<nËXüö´hyFvZ›vØYyz”ÁJAlTÛY(ˆˆÇ_áÅùìÚ‹r&gU«ß°º)MáüAœ´š;¯³¿wžyñœ8‰NÕÚN¼�500„[: ’/øÖE~D7ïµJnÏVöåªÛοùœ—SÓLóXÊS¸ík²¿dÏ9ʪT…Í‚¿A‚øÆÁ³ðäÁ ãëálpð“U“»Ž—N˜  Â0vÀk0 <0N‚v(ƒõp<ca¼—Á] ÞÞù­tø5ì‡N˜»=‚µ ë` | ah‚�| ]0�h�?LÐX ipŒ´ª«ÆÆÆ5kÖ„B!MÓ©áºyuûÎÛÉŠÄÒc¾ZŸE¯ªŸ[of™þNŸÐ#³d®’pQŸteQø$yݪádб`«V°ÔŒ,muù3ÿ[(^³’dD9–¬žLgHFÑdõ ²äº*ÙzC&?¹§¶(ò Èú£Á⠳刟¬L!ò³§¥¥Y³J2[Ê„²¡gÉ5%ÄZ×,?NŠÿ²µ{HwÓœ¦²·Ë¶Ý»­xyqF~d#踴b⫳+³\üãÀµU]•¥Uãqyãž—Õ˜¬p}Áš‚´iòäõ+ŠwÇ+¯ª²|ˆ¢+Öêõ ìišÓ4ôŸC³¶gé^½öÌÚ¯ œr¹áýçí÷6y}U>KI~:Kõêc²²²l6[gggGG‡•ƒ3÷fÚ;í’'ât:½^¯¥NÙ_ï㨕·µ©²™ªñh=ÉÚ} nkå-Í‘H$béXJ Ñãñ$ˆôo^G"ìá¼.J‹_æ”U˜›¨˜G¦ÎƒoÑžFÛ�”—àv^;7…øÊ 2AE›Êq ã› ¦ÃÇ»á¸V€'fÂ\ƒvxN‡]0VÁLÁÌ:†Bë!Zàkq&uCa½Æ½vª¼äµ’e°WСЂ„ÂüÒdm'Å A(Ì šƒ»œLÒ9)DA„åÐmò‰ «÷¡ü°B!m�é!#2™$æf³`v숰÷è_©lS¸^‡S¡C%(~¯Š¯oBÖDƒSfkx n30Á$xCáW‚Í‚‚N4…³àGp© nocTÁ“©*Ùq^ѸÜn°Oc¬&|£q•ÉÇ&Ýp* ×hö’`¬ ^×[iµÅß¹¤á¸ÆÎCûÓØ A(ƒ<&ðëì2qC:(Ð)-š4n¼-òs54åeA[ÜàY€÷5*¾Iç´F( 3©Ck›küêO د1ÒäbAndÁ6žH{58X·ÅÔŒ‚¿Â§ê·'pãqækŸ0úJÁÁ04Ø ëÁ (Ø3¸©ƒá Ü ó`l�`m+x1ÖÀ(êu÷ˆ€ Ø :dÃX ›á�¼áQ*,Âxðü*–ÀpØ�Ëá‚+à}hƒsàb�ÊAƒ"˜/@;¬€|0  ÎDïvÃp^r"çi„]ì?{î¹Y{³º‹»+.¬(\](„¨™^Ó>´ÝÝèvknÇ#µúHõ$‡€£šÁ™ñJO·Ûí–ê]ò�ïÏäSüI󳔓¬«•-»>Ôg«“­?™ÿ\.W²À®¢(=jOù åî··ÜkY§[µ”-òdve4µLiív{4•ËbqL’ÿä¨0Uwa÷áé‡~=ÐÕî*y¿ä¿]–ƹñ´xñÅôÂ.ª®ýdh‚DŸÛZðmW5]S슕Ñ+O©,]W*7"#ÞÑ<­Ùzç‘YquEÌËÜ›)ç",°Ðš´•)_Q”žžK)*¹O+×Ùr¸ÿ9Óò,RãQöë~þœµå|ýs¦ÙþãÑŸèfþ.†ÛY2›'߆Rdq°Qi™c ^aªdþ±¢˜®ç¤LqTøRë`‚BžÊ$…Á0ÆÆŒL¼aÜð#¬†+ÀnÈ‚Gá~P`Ùfò œ š : *4î´1Æ`š�pe‘ãX” £ˆZAq„{a‚�&¯Ã:¸ ìÝèZã "&>ƒ¿«œŸA¡És:§ÃÈ‚a`²Ie”ƒ:å³ ††éŒñA‚\!;c Ãà/0þ&(†Ib[ D,„,ÁA; ^Öñ›Œ‡F“œ(ËtNnÁa(Q™¥ ™øÚlø²Œ6hTxnOð9×›¸{À[S`Â,Š6ƒBÌ–øýò®B3âVº¢ßƆ€ |Pbc°É>!Çþk·ðÆÅšÂ„„°ÅÔ**ba=¿+¦«*µLœCcó)‚lTP N†ÛéZƉ[ɶ‹š Ám$œ¹‘ “ e ¶°0LÇaYÎÒ&˜MÍ Ö–Ó¸1†ÀðÂ0¾Æ‚è¨0 ¦Àl…w4Î@<£a,Ì…å0¿·²Ù í½Àj,—®.0~P{a4Àåðì0Þ„"øÊà¤Þl$—«C5œq ÅÐCÄ{û‡ã ÆB ¬‡ˆA# ëƒ]mÚ´Éf³mÿÍöâoŠ3+3=­žŒª ïAïÓäîÈUuÕÝæ®9©Ææ´•ԖȺ$¹ÎH6€?ª¨„Õ‘óûýtI>ú]V¬L–DJ=ápX >›è‘l©•,ÊwTq ó裖$'sGò T<w¶;3Ì´íÒhQz-&óõ%!Þêdöq4 Ãn·»\.›Íær¹d“¯×u]²�Ž {×GêÝeÝugÕeìÌhœ×˜µ>K&` À;’ªúžK÷Ø¢¶Œª o•·â’Šœ 9O<¸÷{‡½=Ìp[ÃË5§Õ ^1X®˜•×eþðÖ{Ëo*ÏÝœkÍ!^£»¸;o_ž¦iqâu§ÖÁâ ·Á«jvU¶¯Ág Ø’5,dµÔÇBì„–HXü=‹oi™RZÈcWW²v:©©©²²^ÐçF[ÏUŸ~²T¯·”´´£Nùo,VQúØ3ö{.'íáoÑÞLg ô@3gì·U]=bßëJt°¾z=Oîà‚;íõ | Îk ÉÎh­êìL6ùÐÏ`'<ØM ~°ñ’Â`ÂqÁõvÊà48Oü¨p“F­Š]!]a±­¿QH3BÂÆ÷ù¼«3.΃1äªF�� �IDAT‚1 dø6†&sr¸ÐÅýp¼ ÷k¬1ptQ=×E©7ؤq¡ÉÞl–zXéçÃh•?°þªqv§©ÜâÞ8Õîi‚ÍÐâ àç0¼ +  wÃjÁ™Ê¶ç1p L€FxR0He¥Ê9‚!!Þ¶1BÁ _˜,6X ë ƒ„É{& R/ vNR˜¬ó4ؘNø«ûá8^‚ ‚óc,R©Up°åmqÁ-Í•CëSv²Õ:TÁíð´Î�ìÖøRûí(D#–Ó>˜î·DáŠ[”¿¾Ì/'C*ŒÃÉ[Yá™Ü½•Y“¢<qÁ&¨… ×…g‰´xÎNžJ‹Vs.Øôö¹FÃ掕¼rËEÚýaß¶Üi\YrDÕWÊË 8ªÁŠRAè—à|…€BÔÃd‰’jŒTÙ-v„Gáv¸®'|KÁiPi½ù) y‡ýðÂo4fÀ4*´Á p¤‚ oÁj +à4øFB9üþ ŸA&Œ…"ŽØB^W‚PpB'œ�à ~Ñ?þpËí#Û}Õÿ¦´U,ªñþÀÛäÍÞ=÷Õ¹“VNr»Ý'%%Eb?}`ž`0 ûc×òÅ‘H¤¡¡¡µµ5XJáýá>#SGµ“%ˆL’ÖØ_7Ý’ûs»Ý²;—L޼þ–íÞÃ" [a+¹©¥jfy¦§É“LµèûLÓ ‡Ã@@ªB5÷dffæææ 2$//Ïï÷ÿTا7¥ªªO÷ ùxÈ„G&ì½aï°¿“)0Y<ðÖpLüËÄîânÃiøª}í#Ú·þnk°(8üŸÃ½ ^YtÊl¡FÕl´8‡C=ìv»ð‹PNH²ø\.—ËåòÖx«N©Ú{ÚÞˆ+²õw[³¶guéêÝÝ6³Íî´‹Na¯³÷Áú«ì[Ã^?ŸŸù³Š›ÿ¤ìeÍY÷9o²t½òÇ4>Zuer¸†«á;˜Œ·2ó4QYÒº¯Dð™ÂGnýšÔðù1ñ \ãJ‡`vðüà nÖ¹ .QYá ø•ÁvƒÝ E*×B½Ê0…‚,•E&Ý;/Á8èd´ÂÛ:U6¼6jò8©›fA®ÊˆTÖE8DÄðB#Ä{ ¶Œ¤æºAPPçCĤñ„Á Ë3(‹Qb#ÅÅG:Ó5Ü9LÉÀ×MwÇE(µ12‹´mdÈŠ³.FCŒ±‚‚ËáV…ñ3T† Þ7¹ÆNÜÍÜ(§)P.÷šx5ìvbÀ\A—J—ÁÝp¼¢r¦ƒ³4¦˜ì6)…?öŠ®Ã•Y*ó~•©‚kå^¦(<ª3œ&õ°R!Õ üð´ÂU0KeœB‘6xœ˜ò¤(ù‘]æîUbó.ŒÓ!_áMG𠜫ò˜àŽ—öŒBy²ÁöíséîüRd(hKù¨ÆÃT˜kpc¸|2uªË¨Y K¡@áVø+œË5 ¶ñâé0¦__˜,ãÓ|F×á{“ѪâŒñʯ¨^ÏânJ+N6Yb0¢‹¥0 œð¸ Áð2ì„qp#¼ÇCX°È¤Mc2, ,Ø-H‡ÉnøVÃWp dÃMp"Ô ð{¨0 Rìló13BTÙ¸RP®±Hô&rðÂiP?Àp˜oB�P  ‚ð[8<ð0´C±B“í° ®‡� ‡‰VuU¬ZÖ¹,œžøÜD{Ì.)Ý¥Ý=zŠ6YS;iö4—â’rAïé#«cQ¿úÏ]Z&V³EŠ…KCzKÕ””+-ØÉ =]]]±ÞCÛK¤]¶Ô’ûHÉ*‚$¹³[c^Ö+!åv»eÏÓšï±ä'$še ñX~»ýE4äõ˾åao]’ÃáÈÌ̔،¢(¡PÈ0 9Ücd%Ö*)ŠÒ:¦520â²»ÒCé9ßähq-9ÈU:rvÓaV-¬ŠdEÒ+Ò~;°fAMwi÷ •ƒ<‡ÿ—/WÁš‚šy5YŸfÅb1)Rl™ ¯{xÝøßw(«/ªv¨Õ¡¼Pã”ÆìÍÙ±1ÿÞqÍŽâUÅôü»ˆ‘k%½‰-+K–¢ÏLÆ&û06ûü—¼¡ÉœÉß÷Ñ[JN6ÉÏUò),fEQ$ Q’0%SýÙûWWýÒUƒÂ¦ÏT€±ð 3 ÕIEÊ_ü‚·Á©pn—§`¹KÐcª†§zHƒÓ=„M¾4ð@TPª0Va€I3•1&:\,Ø/8˜J· ÏàeÁóÐ#!S£ËI8Îd“O N £r¢@5Q²I P)Ø�)ä9Y[ÍßSI1jCä(^ÆÅ˜Ya™ Õ¤10B‹É[!æ)4 ^·“®V)Š’Ð(¶ÓÔÃ.Á;v7e iP Ñi2X¡橈0[b˜ã)*Ÿ rÀoâƒlöéœ %*ŠÁ7W) 5i²Qì$`Gx ÂPcàRpƒ_ð-VhW©ü<1:u*áxÈ„6hѸLð=œ y*…ðÓô’?˜Ï?-ªãr6(·(U.~'m# ì#-ÆÊ šXq!¥ïš¿]ËCtw¾Í óÀ ßH‰q^7á„ËÇþ :¾…TªÒªrƒ ŽakhçÛ¯á©NNQ‰ ì*Oˆ©\àVByÚ×§‹ïjÑvVT狊6èP¸Xå �ð*áYh‡ ½¥Œ€tÒàkÁk wÁAh€½pì€ ˜p5´Ã*8�`/tÂ0X SáY(saz¸9ÆÕ0Y¡Z@3Ù[?öêÒæÂ~èïàX 0A”0ª×¤q2L„8tA Ä`•É6È?L…Ø`Ž•®ö$ö|,>üÕà”Ã)Êòýo¾Ÿ´d’-f³²‘”ô–½2Ë<WnHe!"[1ýu"¬¬µýO¶P²FM-æ…Ô•°¦8-AÙ¥‘ÉÃB’dlJ¶Âêc¯gdÉ®?']ÉÚ"™ !Ï+S‘Å88êL˜Õh²6ïVú± ‚SSS‡œü•Í+™®¬Vj²ŽCŸ솙 ›nßT{bm  K‹¥6¥Úõ#ºÃÖßÊ+—Káêrùê|æg‡žDá§…™•™y»ò’‰G®ÓafìËH&ʵ­›W7bëˆTGªŸd"OiM1œ†á4Œ\cÒ{“TUM¯J·GìéÕéfÔ”H•ìv&çQy÷åvDr÷ª”¼Ú?¥Â%g’wHr¬G±iP6Z“]B¬ž°<$§F¦U+±%çË>ÉUÞS›Íæõz'MŸu U‹ ¼­pd‘¶žëKÅ»'‹Æ|xÍÆ&#ã(:`…`0„Ÿ@l‚ü8+ ÖÂErpX!d¢f±7L½ N… Ë5Î4Ø9ç Aœ ƒ!8Uƒ`„±‚Eð"”H…¥P¥2J°MÁæ ä>ÁfÇÑ¡[Pf²/Âk ˜| •à7Ø¡f¾,bÚ!^Ôð«Ì1(ÊD‰ÐcÒf™ÎRAŽ›xˆ…lG°NCS(<bƒç}¸ Rtì‚@5\ kmLLЧMa G¡T°ÉF™ Íd£`‚ÁÈ8ëuB´1/…q6zLŠC‘“ ±P!C°°1Ëd)D@W™ k5† nV) ÚEêJ¢ù,=¥õDÛ•–u©° ÎTÉVøÊÀ†œÍ kY3žî-D}䯙|ˆÇR¡®" —ªÔ+fó‹uìªTb7«L1yQ‘ïáጩãÊílM0Uð¨U(ÆvnWÆ—‰“¿û)m rCÊ Ýb×§ð=ÌlÖÃl(z0 ÓÆc&n¨†ï!¦CCôÀxƃ;áð9\ »áï°~€“`6t  C>\¥±LE‰ó h° \ ÂnŽº{à,H)°2  :a¼ÃàØõ°Rà (‡ñP Í´qItBš` L‚yVº:¼ãpõKÕÎn§îëgÖ»;ÜY•YŠþoˆÛJW–݆L9É·H~TëèUûèÅb1K(¹Á%Ã4^²Ä&Ž‘«èµæ²ÞÄbJ†^2ÞvÔ†Rë# ²Ùl–‘U²;­7ÿcº’Ä"¡É0*g�$ë,Ù¬ÿ@qgZ§‡ðÎÁé éZBK©KQãj²‡åne½ƒ§Õã«õQ#¡&Í<”Ö––q(Ã’>²€¦â 8[f´dÔfXŒpy…®.WÍY5‘ÜHöl)R,ŸO£GWõ@Y ³¸3£<#‘H´iË©Ï!~ä3Ê$mGúøÂÈ£=¦ux<IM´4gû§+K"9¹ºâh&^}f“åå%I@ÎJò•òe¶Þ£O‡ÐJWv»ÝçóŸ2ã§™£ü½Ò|ª–w¯Åuc¿àÖr˜�·lc½tµ°óa‚Ï€^ãŸÀ¦ñ I· ê¡ÙäI·ùPÅ«Ðmpƒä™Ü™ÁÂ3M¦0ÉEO;Õ6 5ÄDj6RdrP0Qe Î·Y0ÁNžŽMc–ή,|휣³µ‡*w)dFQL•BãÈÎw¼‰ ~úTZ¿'Mp-ÁtY07Îp…àþ``ƒ]ó&R\ÎÄ(¯'¸êLBÐ%øÁ >srY*“08¶€û! Ë Êà)¸ÐäxèÐÐMZ¢Ân…P[ùZÂ{u† t“ý0ÉG‡ÌC¼ÞÊÉ*‰‡aä< ¿?<crût[M † ®¥áqþžK ÇÎw Lh²á6x6Áà ÊàiH â…߃E$ØÊßGC'C&òÁ~ÞY¢^ü? ‡ Þ…«MÆÅI…fNý×/÷¨Œ5y†çXÒMA'/èD¶pñ¨^OúÛh-¯îä¹V>ùÁœ>w(î‘ò_AÄÀe0n„‚¦ÂwðG¼ÿ 68>‚‡`(‚“À€ka| ×@>L‚f8ì„AP ÏBcŒ–­Ð ÇÃu°|p5Œƒ›a,…�¤A7¬à0ád0`Ø¡£W/ãdÈ„Á0x‚€˜ ßCEò7©e|Ëê'VZ\›uϬx<Þ:¸uÀ–fét;¥y’5¾jå'ùµO%² æ-LÈÈ …BGº¾{Èÿáèo#iE+‹&~ Ú¡¤Ú[µ]Ÿ!èäÍ»5Àk¹¦¦¦êº,LÞ’­B¤¤¤ÈŸeëIÆ}ÙÛLÖÚèS÷X=U]×37fjš–‘‘a%xÁ¦ÀeVdºÃðWû»ë>œ8œ»#·Ïkb¾XçˆÎA+õùý€­2c™EË\6îƒqÞ ^ëR3·gº®µ®ÇãjTõ…|DŽÜY‹.ñSÚKÇÆŸ‡Ëå’©±Ʋlhþ+‹©òS§ëÏ L&ûHÉ’Ÿ¥êÒ÷{Lfæ6åO+ç¼×dlVÈäÃc0º 3AX#¦Á;'8 qöÀTpB–Ÿt~£W¸Å$lãY(œÔ…"â`L§‡¹WÃ4Q ¼›i»`&Ø¡²Aa„AZ‚ÕI‡¦ªƒÆj\é£'ýõÜ%øü¨’iò9,EÛÊŸàyÁa4ïç 9:ã·Û¸ÒÄ#°A¥ÎÁmd˜|ã¨dh¤$ø$àô\Fvsu„íqâ*÷@%´ATÁøVÛøXg7 < wÀíP&ð&¨2ؤ òá:Á¯ ÞјoÀ©AZ{ÈœÕC›ÂW .•ÁF^K:¸a)%¸#Á=ðà 9H¯å'ï˜xLbq.(`q#ªüCa¤ÎÕP [¡žLWØç{ÁÍ wÚ˜”à>ˆqàk4Øÿ¸,ñâÜ“ óø«`ŒA„'ßãñnZ¯‡ˆŠ"xMç^X ƒh~”æ,Rí¥û/¾ÀÓ:Í1zÞ€WiýW¸ÐîäÛY´€øÐ ax–À(€Ä!a°Ê  î†Ap#<¯À[°¢p tÁ6¨ x«×$¼ H¾Ùj�gÀ À‹°|° €X ×À×°¢ ƒ^‡§`\ŸÂ-°®‚ɰ . ÆÃø#xà_0Î…Q°_°RaDáŸà…‹’¿IÙ;³g=7K6‚¾}æ[(ù´d`Õ@GªÃëõÊÂÂn·Kž›Åµ³€¨ä¢?`~ \ÚÒdzuå8g,‹F£.—«O.±ô×eÔ@—4‰°8`V‡$çòcðãéúø\Hµr¹ ?ÆæÝ*¹LÓ”­0’l-ú†µ©—\«…•PÕ'Tw»º —ª‘¾=Uù&RXÒØ’mJ’Ó§5è–Ù¥š¢¢(J“’÷i^ù¥åŠ©¤mI³Ä±ŽÄÞköw÷q}œ>äþZ¿¿Á?xãàÏû1§4¥¸[Ðmüûý ®YÐ4¥)ªDnhê¦ßÿÏš^VùrTÞÍ+ •œ~$3§¤¤È½…<Ñ‘±ëÞUíÈUµ¥ÖØC8î³!ë× ƒþkgòRíþ<cN'a(·1Ѥ^%WЃa¥ÆB˜né&û`œKá3• ‚BøDÄ1 ³T²wš”Ã>x~ ð«T{éŽqa9Nìnƒ÷!ŽŸ‡ÊÙ^…pȃ_Áeð8CO”îNn\¡ÑœKašÎ$A‹J½‰  æÂˆA-Ó‹”ΪìÄ;=ØÀîÇíegèˆ/­MðDa˜‚ ¾2h€¿Á%*QJã´@¤ êM`S‰ ƒxÀd2„` \j瀟1a` xå çÁvÁdX ð¦Ê™€/;ÉKáê)‚¿Û8E°œ‘NñÛ'l÷<eÞ¸•gÂi°ÕC0Aw€r±çúP£luA‚ü�™0UPç ÝC§Îý‚�¸†(üµ€¬ g ºmœ§óW˜­R¢°HÐéj-NZíeïjŸ‡Óu~äŒ÷©¸ž:¸©‚=0ÛÃÈSà]ر×l]I`!ï~DõET>[¡@1£Šþ(ïå¨Fªà4ú³zÙÞ%p³Ê£‚µ`‡\Ø `äÀ~ðÙ9ÑÍÖ/ÃP«ò°À/:5Br J Ά;@€†/Áu„(|'A>„{a Ü׫‹q+¬†ÝðKA3x¡ †@Œƒhæ@%Œ‡`\ µp9üöƒ QH$Ù6nû~›&4%¦ ùrÈàƒÓkÓv‡ôHõûý~¿ßçóÉ8 £Ñ¨Ÿû0Å­f Œž2G£ÑþS,2ÉÞ‹•- L–>ɶOG„dÉ"£Œ…~ÉÔeÁKGôÓè)éI ¤Zoh³ÙäÀ²ŽzHÂ}2—liŸL4OFïäkdË4yúÊR ’g´Za‘H$‘H„B!!Då´Ê˜;–Ò•’0®v×±g„ûô-“´e¾´*ë,4KJîŽÜýó÷gmͲøúŠS©ýÿx»ïp¹êr}øŸ53»·”½³÷Nï•„B(¡A¢Ø@ADAzÄrÄ.¢GE•‚JSQ‘"P¡$’@zvzOvo3³ÖûÇJ–sö޼žóþ~ﺸ¸öžÌžYë;kžçûÜÏýÜ÷ M#©À¡8þ8òù|yyy H…©º×ëÖ½nå…+G<4"ôRaª²©²rMe.›K@Èû-„|û ù"Ù^$aÉ]o• /')Ñ ÷4ÿ XxļžŠŠŠúúú$y¡:FH¶Ï©Æ UQQñΊì=,aÅ¡“Zì¡ãB÷²"p^äH^!HiÏëM)¥œ!ͽC&¥5²•_ÇZA¼È…)‘íô2œ½ü5ejdþ�vy%gZ©¢.ûJ|½JªÛki#¯r\¯Þȯ¨KY_%Ú›µ‹ 28RM“3î\ÐAÊaÜ8¡Ö[iµÝ~É<Gƒã·Y_×Ý=ºÂÒ[š=Rg}³\Ti|¨9t.¦œš÷-N,qH‘¶¬êÈrž ÌÅóLOYy‹A¬¡‘¹ÜÀ^––x× •ÍꘔÖÂ¥v¦ÕåÌJ)«vK gsOÎÈneíŒ µFÂès¿òü ð•UÞ®7¯Éª1ÜTéÒ¬e‘ÛÛ Î)í21kWVgÊÎÈclãOeêËÌë1 ÊË=ªȾÐß›Ýé¥u„amöEöDvF–ð© ìÚøC [7ÜóÝŒ5=ÎXkÕ}Ö ÌHYÉ1¬Ò¢n­ÕêÓº³¶¹p­·†y¶Õî¡ü™U)³9œÞ”ÒÈÏ8i7E^£“i'fFvPD·Ð5ÎÙŪÊÔtib#ƒEæ³yDìf›E#»ÉÒÂ@泄õÜA%W1™)̤“bÈKì‹_90.Ø_T=̹”±„bòG²‰)‡2›ùT0‰ì$Åû˜—¤«;w.[¶,DOzûqÈ>|øÐ¡C«ªª*++ã© }ûöÅ<ˆ¤¡]HPŽcJ<[“ì÷c+qOO^?‘µ_'yÍ„Œð/¦«B œøEúŒje˳-cZª7U÷Wëy‡íy‚ãzÌÇ»ò¸“¼KœØƒŒl6›(<%Jaˤ‘Ÿ¸VÆQû¹?7ë'³JW—îž²»hg‘îÐ÷ß=+\½Â¾Krò tÙgUÞhX{êÚkìW‹Ï„æmùøÈƒš±6G>Ÿßtä¦\i®öíÚª·«’“/$°$ï’|4ýI …rþÉÚ&é<¹7‘À„+QøÌ˜¾X˜? Ùƒ…;‰>•z¢‡YSSSUUU___VV6`À€Ï6‘2éƒ6kqÈÊÊÊÿEö”±L=Ë$6¦ì¦)ÔÎå¡'Éúì³þz|~Ó.j"{y%ã«9Y´]¡Qy×s-ïâ1p¯G¶¦]z4ÒÉdj8$tßv#©”ºV+B©¼ÁYg°2eZ^{eÔ>©ÜÍgöA9¿ÎøEÎýôð rYYP’w[#­öåe3Î̹‘3yÐÝM¼/í®JǶˆÒæti+RªÌY•vyÎ"æ–«Íz¶Çnæ…öDZLgózÚ‰yÇEþ˜wÜ U¡E6¥LÞaYʱ\ú`—Ï4y™¹1ëScùy¤1«õö‡ì¯³™WCe¼\¤¤Ò'öYÈ%}í&¿9—Úš5VøNZg ü-ï(Z( ŠüŽR*:¬ìPÎo².å'<ÎYX“2„ÆnwFFs4ßäLÝæ9NvÊS^>½wÕŒŽýM Φ‰›"òé9'ä­w}³š…gÙ{¬XOŠãÙÊ0óÎa.=„‘Ï0‹ ‘M¡ü3›£–§9›;ºMì6—y¬bWèW“&ÃohŒY<GçÜH')1šÏ1Æ~ÄU\lÂû&÷±—WøvònèÑÅ*V0œWy¿;P æÙË|Žd'-œÅ ‘€Nz;S®Ë[ËY|—£ú€ruuuíííÉ4U̸4hPccc‹Wî[ùâ¬GÜ3¢°bè³·Mö¤ÉoVƒ»ø»PŠ“.Bïb¼«Ð6°‡S¦Å�Z¬ ÿÇšä_“hXÚSZùj¥¢©Rù?r$ž¶ÿÊÅ¢>ñÊ„aØÑѱí„mÝUÝ5Ý5rÿ-[ÿ³WKÅBÖI‚Öy‰ÒUr4Õ4ê‘QÅËØÓÓÓ<®yõy«®X¶±lÄK#zÓ½ñæàÿÆz&=Ñ]Öä Þl‰ÛÈAÿ¤ªª*NW1Ä·sçÎdL»XX´Åc Š ûϤß5Î <Ïr)+R¦„vù+œüË~šéxOðëÝ¿@*y5²<ïlÎgohfdŸ#Ã4ÎækTGz"g‡îÒÃÝÿ×’ ä3¤"û"C×óLÞ .ÓX‘ó@èÆN;C·…¾Z¤:t?‹ØZf -‘Ï;»ØI);y^Úi+òV–Ë–ÑãÆ¼o–dL¦ƒ‰Te}l¯ñ½&…zÓ&ä´†vÛÜëmæpJ›É¡‚ú¬ó.dc‘#èˆlÊ»+2™ËØ×êÛí®jvÃ>Ã2j"k#ÿÉY¼Æ-i™”B©À»#½^â‰È;çÞîšç'9ŠZ¦°…V>Þæ6?½ÒuÆ]èД×ÚØÄ÷"ë»|¦Ã%ôò¯±$òåÐ|zYÁ²ÈšÈˆÈüN—PÊ'¨# \jÚáÑÀ‚ÌþÁµ[yhŸ£½ë ]—™I‡«ø³ ›m^oáB¦G‹ÄÛç׸©=?~Ô• }ÿJ÷¦¼CŽ?`,g¤ÍL¥~ï¾}RRÉxzC‹Åoøeè÷ü… y€G¹’ã8Œ9L`¾É>Kއhæ0~ËGÅ9<ï6:ø4ãx‰¯òQ†0„€Ÿr'›¸œ,⢸ô+ùL‡Y7Òȇ""5|‰§YÃx†ò¡"¿¥‚0e<ʆțñ�Cdfèã,¢2ÐÊÝ…_¤ÊÊÊúúúšššÊÊʸÀŠX¶²²²¬¢ì§s~úÇ÷ü1µ#õØÛ~äö%vü·±ÙÀÊWn:tÓÿH9)ÆÖ*…Ûê¸bK&À¥¥BÈ(¡¼'2€…\q²,œ§‰ÙÕ‰¡_2*¯Fƒ¾Â#~£VŠxÓÝW7ˆÞøì½5½ÿÌú$›ÍNºeÒÊ+V¶n/ÛV–îþ?ÏC)„øòùü¯,<ò»G&ÿúò¿¿|ÔO:(r›J¥:ë:_þ—‹Û‹G?1zØ‚aq};fõôôôôöl:jÓöS·—÷9úï¾±¢ðsÖÝÓ�� �IDATHüÏü_>R©T<H>hР>¦À}V P»¤ÏWßê­ß‹lÈ»0ïÏ—º2g2K³ž.:i¸ë+ýzFîÖÛ¢³æ¹9uÝÒ´éŸ<à¿0(r#¯3„2¼ÅŽÀ]Õ&ôdd’7î5vßåõŒ§——XVkTnØSáÌ dzCæ­à“‘|¾È»*\›rSÖ"F§ÌiUÙiXàÇC|»×¢^ 5 7-PŸö ff}§Â½!ͦ qC‘Ë#ßË9!chʧ¨Ž|<ëÞÐg#K¶hcVÊÚÀO#寔\)ÊKs]<pS­©T:ë ¶sf¤Ž«›øTÆ×÷f•–;a´o–ûC‹Œâ½|,ða^‰”ä¼È˜b÷C¾î±.ï}±ö=/¦¼ÉW(J»"å=|£×¤œ‰v=d@¯WÞç˜o×úÔ»2¾;Ö59o–˜ŸÒèdaäJNet‘;85ðs~Uä/ åh*^ì´Ð¤œÃ"M :Á•DŒ`H±Ãø‹š•ÂõÚW®b‹ÏËÐññ"—QÁs\Îi„jÊ\3ÂIåf4X÷¿£—¯°‘ó™—6'|é_¿Ñãƒid1x/w‘ãÞäVðu*èf4yç ª¸•m4òG†PÇRnànåMîä¦ÈœXÄ…L=ÀŒ‹Ó™ÄLã½üŽÙt®çBSÊ÷Ø•óHè¯\Ë&B%Gš2ÞdWd]Dy.å7öÛ†½qƸûÞšì«ìë/]oBs¹\¬LÑÕÕÕÙÙ¹qãÆÅ›È÷WD+ÎûÍy‡.9tÆÓ3V~håÞA{ûˆa÷Ùǃ´ „²íðm‹?¾¸3³_û^)Í£›»j»’‚ì xQ2oTË$øRá„ò;¦²²²x7]Öõ9j1´erÐ)×kŠÍ·âŽÚÒK—çÕ/¼ëÆGyyyyyyÐK÷”6ß”îN7¼ÚЧ—–h &š¼I¾Lf‡ûˆ/$’áÉÛõyNgCgùöòd):ê:Êv”téÚ‡¶¿ú…W‡.:ã×32™Âk¢(nš·iÏ{ZÆ·ì>twÿ7úWˆIG3ù9Ñ×H¸*ÿÓ#þú[«tk•ì‡ ?Ó¤<¿#}DCþÙÕõÇr#U){"…NáG¼žR—=¯ÖO·ìVÆ3ǧ†M£÷9„S�ú) …þÎçøTàw9wµÚÀ!€û> g-s{¼Ñ£Ü‰kýè:3ºíüxྙ³%6—ZÒn8£ù;‹Ôöåä¶YÍo9¤Âø#‡å-'⦡îëtØv½»U†ÖQÊ‘e.Ïêî64mv©ݾÚ¹9ð¡¼uiO…Þ.rWN{I#sžläŽ}.> @÷v±ÒÒëëWj mkñ”Ïçl[/[f@Ú[Y ¸0ïoi _F.ã.†T¹vŸºèeNyÏî9ëÔ>`÷!ŒÊke9rÉGϼd×~¶×5ìI99§hµ C]³Km¯y:m`Wg]ϼ@ŸÎz‰‹ý™Æ^ÏÖøá.Û¸˜E)GÍ×Â2¾Noª.kÛ 1ói÷¦7_™«=]ío¼þÆd=Ì|>˜22òƒÈ×[¬œgÖQ‘Œ£ŽÌá þ‹•'õŽÜÕ{ö'™ÈSjB ˜È±ÜÂtî`(÷0ˆ—ùËÊtþK™Â¶ñ‹ãº=¼Ì)Ìàv‘ <—rUh'ÇEzy”³¹—Uqxg%C™84eFÞ_YË&neænNc=˜‡Ws;3YÀæPÃÔq:_çVÑÊmLáðá·}•Ó ¿H­­­[¶l‰·ÿ€Ú»»{zz6mÚ´mà¶Ü¦Üˈz£\.7påÀI-“JÚJþGQ£lOÙÈçF–ï,O ¯\.WQQQZQºüÃËË÷–}ÛÑq‹"‰,Ië% åñLR» ]õâ=xkkká0ÓAE¸ §ƒûŒˆ ¢ ín㌔ ‘Ìý˜zãÔo Ü3kOãòƃS�Ú3CŸZÙTùÿ^ §‘ËÂÐ{DÅ‚ÂIѸg%W·ãÈõ¯ÖçóùSwzsP¼Ïèóœ ¶ÌÛrÌWIgÓ‘ƒ¨–ÈØv¶°$LåRC_¯d2ôÖgÎ÷ÿ6Û§hK„HþÙJvtt455Źjûöíñ=–Ü]1µ££#vþ,ìž&ÌÀþpeªæÓYRäʼï3–Y) Ñ‹ïö©W\ò–E#| Î·ïõd›UdèMkŒìáÍ´)—‹U–’3ƒ¿&”x¨Wš ž:,xjGJ:€£;§ÔúnåÞbËÛ–N ²=iG*ÙDK¯úN»Rª™h TÙ¹+¯„©ez™Æœ!¡66p[¬n±>°-2‘¹ƒôvy©×Q9 ©É:µØô^{HÓÉE– 4²Ç_Ò&¤¬îÑ©¤´Ë^å#üŒó2þ–²5§#’î2¦Û=îó©Ê`ÉÂ’|k¯‰æd -e©ÈÍi#¦Ëíðnê»,*ÞrÁV¿?Å7×jºØ–í„´°!m&Lëæîhá¸ô_ìŒTGN‰<“vd$Ò‘sH·ª¼[KD½*Ø›vf$ÃÛ‘m5¦ç<iÈxJ{Î+Îà‰¸¸I9!rO”›˜RÒ*UffO>ðÞ56T„ë›ýǯœã±³èb4{ùY žÒƒ>÷|êîÏ0š[y›Y ålçPZÊß•Û2+_=ÛÓ+,;›SvEf3–o1šaœ@ë8†Ý¼È}Ì ˜ ¯³±Eì%Åyêø·èáÌȈ”Nng m¼‘ÜÛ±hYþéå-ª™ÍÑ,!ËJ6QÊ^2Áp–3™õ´ó¹{K´g=OŠŒãeF²›¡ä ã‰>öŒo¦Þ|tãE›‹²Ùl¬�T8ýS¾µ¼;ÓýÂ/t§ºƒÝÁË}¹g`OÝâºâ\q ²%EO‚Ë*ì—¨i«öò°’]%IðŠ¿êEAQÃÛ ÅíÅÕ;«ûÇõaŽ%FÃ}éI@ŒÉc…‚‰gy¬V À(.w iÉ[Ç \ïÄù²˜\o{}ûž){ª¶V%…K &·äÁø×ÝGì®ÞZ]Ò]²â+F<=¢¿"2™úë+6W´þøg4îMnÚqôŽÝ3wÇÿÕo®/‰J’KKL/û ©ljÕûV~xô®Ãv훼oüŸÇ§³éþÀéöc¶7.n ö­'‚ HGéºeuaiX½»ºnE]Qç?¼¦ ´ÿ•#N½1ò–,õ‘YJΡP­±ÓQH=é}öIùC޽½½---±çV,zß3 ß2†vûpne*++ßYÕb+¿¥‘¡i“ò6qdÚ¡›2=ç„/½hÍ ¼fíšà–¯¤ŸøXä(ê¨ <é`NàáP{ä*óÖDFE~Ý«—RÏ]•fNrÌn'3’¯ætçŒæ&˦Ôg?ÑaZäð”"2lceJg­ãzy"›²¾—wXàÉá.N;®[w\ŸvbèïìȘ)‰Œ‰¼œVÊÐ@˜WQä˜.k{=–2'òSŽö‹pÿ:0<+[eV™»ÛÝΨÀÍyc¸<ðTÎûˆòæ<ÂxÞËzç®uÃc–|0ºâŽÞ‡ò\Ôk@h]ô°ŽwñJŠv2#cL˜]£è5ßÙæµ9žX¢û†VÛÖ30òýÈÎjÃS®É¹52•¿§M%,öá¶wÚÕkTèvÊùt$`d =²Ç¼7üòàC òÚ}hk¾öñÜË5ôX«(%™œ1(ô‡À´Ðå¡õ=VØ}›‰»|l­Ó3~{¹§wpwƉ¡ñtFŠüõÖhbIô‡ Ú™ÊÎç-šÇ—YÜmu~Ùn ÞŸY6‹–À›µ‚N3ÿb38š_¤XøèöidTÆBXD–¥ö+½’rQ`CäöQÂ|ˆÍ7„žˆ¬`6x–Mœ3bÍD–ð"W2™ui§ó6 if Çó ‡2”c™Ììf8³YËŽÀȲ¼JÉÓ좇=l&Hû <ÄøÂtÕ´±éîìÝQGT²»$QHeÙlvÀîõês=¹³7Ž{nÜøã3{þ›_’WâlÑ_¶?O,Æ|Â0 Úƒò­åIW ©zX"ú³ò’tU¨v‘Ì$%ÎX +ñåÄ9¬p*+>ŸÂièîKˆqÌMtQ_ýÜ«ûÆï‹2Q¾$_µ³*Y®¸ë—hÉ+Äè_ùîòM§mÚ~ÌöIšT¶§ì é*áX÷ÇBãðŸF|ÄËÛô¾¦ªÎªÛTÚ[µñÄÃß^Ö]Ë;Åõ‰æÖxë’·öNÝF>6²¸­¸O&‚íGm_rÙ’†×Šv½$Ó•©[U7dõâ΃Ûþ‹éª´´4~‹xçTˆ&鶪S(â^XCÇÂʱ¦FÿR8!Æÿ×O{÷„ï—äªB¸Ð-¹ú¤«~`à¡íÎÌ·^âú¬)sƒ"=Tå}>µãÓÁÃÃò/÷µŽžÍuèÜé»<Ë¡ ¬L›IAT÷öø¬®@o _¤2ml¤-ô•N#WÚ–sã S:\ºN ÏòÃŒa{|²Ô/˽բ‘ BÊBïqBèß‹}z Ü«¸=òëÒ¡Ÿ§}±^õn ê|s»#ò–æµDr)wg|7ïÚHu΄”¡9íäÛ|€Tä y‹YB9¨åô.µdZ=8‘ñü´Ó )†æ´ò v“ÚïË48qŸ>àÆ w•øø@¦pA¤Š_ðBàÝ¥ºÛéºm>ÂnÈû°Þç­ü¶“®ñèLm¯óÓ-ŠÚU°ºÑ°-j#?iSGMè*î§1¯’ ‘çÆªÙ+X]ïÊmÎÝÄç¹3¬æ¥ßx¶Ó•³»]ÅZÓ?ïvÚ—¸mN L{γ”ruÞå~^n^«ŠÀÍ‘0͇›¶.õŸçYXúw²yWñ+îå3l,ª<&[ûïšE9y•gYúCú´/çéåæ@cÚ'r^¤‰y["7S´×ç#+9„Vò*U Î{Œ3¸ksú ï^ð`þÎjʹ‰fNåæ"‡gý%ÔÍ<ÉJ>Êø=—æ­ælû1ásÏžç®â)&ñ&]ÜIž|è7‘V®e+7ð$]<Ê ö0ˆ[XÉ“ôðjÎ2âYÅ5œÁRÎ`%çW´äÝF޾±¦hWÑØûÆ.¿tyÙž2í"CÖ ©É×4,k(m/M¥RíÚÃ0ŒÇfãÝëþÝnq>Ì„ùî|º3+y´DHj”¤ŒKlúTW W81ÄK´*bmˆàJ8ÇI`êXöG¢‰»"ý3;‰ƒ³ŠÃÅW,Þ7aßñ_9~ëÑ[{öÄòTq€ŽóîA£sÕ¦ªîÝû&î;ìg‡õ/)âvZœ’fÇAÇ}þAÚ.Nm8sCuGõˆ#Rùýí¢Ak-ü÷…'}÷¤Âdÿ—3ï§óÖœ°fÚ“Ó‚® =Ûwøþ±bA¾µ¶uÌ}cÊV”•””DéhõY«×Ÿ¼þè뎮ØV‘ÀeIg±ôZ¨r ®$¿èêE³¿7»ðÁø¦úß�'¹¤µµ5þ@ã›áŸ55–øç¸ì³àñ=S¨f›hÿ'×Õ_?¥_uµ'cݶôÞÓ©¡’qçÚø^/‘ïFvé* ÃŽf»;,c—©LÉ…*"­‘\fàœÜóŸvÃvZ<€/3(òÈrdŒÍº›ªfíóƒzg´‹x<´.tfÎ]D&F® ¼TìØ¼\¤ƒ—S>\jP·CÒæEŽeBÕ‘L›GB½­,å5¶qGdN^Pæ¢P&tM`pä…ŒcÓf…e = ¦—‘”9#T]ìÞRç÷ºŸãIå-O›Y¨,qO`~èp'µçîuÆg-<^~´·îRµÂîó3~Pê¨>Ûn¯3‹ §ñ‚Ù ›­{¿/Ý£eG»3Û.Ê+‰µùY¶FjÒ:y•öØU=ï•-þÊ´›q`Vi¸Eß3ýR ZJR-S‹ZN˯þ»UFïâ>ÛOÃ{Ó>j亼õÝÖæÜ}À±p‡žþðÄÐÍŸ+×ÖiXà[ÅŽ ]A=«o‹nø»óöi¹™§ Ýú #š}aª=ß`5ó8/ô0r2õ|‡^Þ:š'y/DZ›".¢Šç™ÀÞüìRçÿÞÝDóô§hc-{B÷0‹=¼ÁzYžX¿ä\&ó`Ɖ¡0€'x’´q Ûãam¾Ç&Öò(/QK-=œÇsÌáM>˳|Ÿ“¸Œ7ØÅ`R áQªÙÂv–0‘\ÁœCç«®šš>³°r{eñ®ââtq"–ô“÷Ûüdó©îT¦%µ…¼ƒug¬{é?^Úð® ãî—€QÉQZZZVVkžöùzd}J«Dí©Oÿ#é.$QrÉûöé?u%½±B%õdb©p¾§0­vè^yÞÊ1ÏŒ™~÷ô¢Þ¢êöêÒÒÒÑ€ÁUƒc¦~!ŠXHÁïÐÓ:¦uðÛƒ[G´6ÑT½©:•Keº3…›ýàê?£× ñ‘ô–vµ«}xû„‡&¤ü£ÆÍôdvÌØQÚZš*M·Çù¯¿STr j4òÕ‘Aïþ)‚ýƒÕñ‡’ 7¿9ŸÉy`LEEE{&íYöáe#žQÿz}*Ÿ*¬fâ˜ÿmggg,1ÏÛ%:ô}T6]³hâÍÛ¶§w¥cND:Ž}s¹\¢7˜LX÷Ï:}\Ä’=VOœé“e,dèÄâ‡ñ©öÖJ&úï’îir„aXQQqäÜyÿ ØnîŽèÍbÚÓZBODR]öd-O™ÙG/몼»×ƒT1–Í¡?„nf ì »—›¦Ì^ó'Út~½g;o05òXJ{¤‚Œm÷0/PÁ,Ž(¶©Âæ¼ÃøXÊä*énƒY˜кK#3B÷sDÚ®È3¬©´!rTèÏŒæjÞ®rj¯?sb¥â¬Û¸$´/P–wkèûü;£Ø’vi¤’ÇÙUn%#ò2•ÆTØÖî†0:ðBàŽÐõ)×ò|‰SÓZ³ïn2ogú‹ŸŽüŽÐâ•56NöÚÕ¡ ¥¥F}‹Úûè tW92Kw¿»ÂýO»r³Ô¾Ôƒ§[}gi¸|¾5ûÌœZçuz7O…¾š2'ògƧœ”Ry tñó´iUÚz<Éó”ºê5¿Z@}JmJqdEèb«f¶Ê­»u敱¥ÊŠ ÍÚJGF.sØÊܹÏ;b#p´u(osh»G"“#k ï±5r‘é»]ü«ôõïŠv½I–g9Û}5¦,“™âõ¸#õDJYd{XN);9ŠÉ<ÏfNä56p×q³È2FqΤ fβn¯=#d§ÒA–ˆm æ:Ö³€!´þV2 ôS.`%ÓV@|ÝÁi¼ÆÚ™Ã2Œ¢ž,c3Gs$ÇðYjÂÐK-§ÒÆDV1‚jvSùV¶ÓCU{Æ¿ïþûÖã·\;0Ó›)¥-Dâ"&†M’q“XÔç±oõ toºt[iÃÒ†òòò>pV ”Å5P©‹>éªÐ'" ÿ-9 =ãôÿ?æ¾Ç`c½db´Ðࣿo IõÉıž^ÓÉMuoÕÕ®¬Y;oíšÓÖLÚ0©¡¤!æ_ĶB`*Š¢®ê®å]¾ôò¥OÙxä5Gö4ôl>asóøæA+Å«°1ëÄÁ«°…–,c,CÞ=ª»{pwÝÒºBɨ(ŠF,±ä’%ë箯]_›Þ“Næ„âØ|úæ}ö5onß\±£¢<(OlQÅ¥UüóæS6g˳cî“„éòÝå•[*›Ç5\=0Ó•IJÄñŸX½„aXYYYÌöSj¢Öá­¹±¹Ú•µ}ìWâ_ãlãÀ @ÝçE o°B5ý”N:[ñ¹Þ ¼œÓ“ÝF|$ô˾ ¿æÉãýÓU?0p}mjýq¡ßäݘ8!ôìpGn·5rFàø@>¥(0-¥!ÿî‡5Í·ô<™2†ÐV®³ò|W^ͳŒ Üørèñ´cónËÛc¼iuy7ò)åê£Ù*äC¹}^K©‹ÔEÆ0ˆµ|•ã¹9¯“9¬KûrÞOXÏ)<HO‰YµÚÖ«oW•“Š|›##ãX”vUÞ^ã°¼·A+‡2,¯“½ÝËÛ̪¹Žvf2…œÖåðÂWýä ‡-ïÚ¹ÚÚµ ô«x“ñ{<ž67ï'?XCäùŒKš/ü½ŸÜ¬ªÝJö®°þ¾Zäõ 3æ)ZîÁ£ÒŽ|+p|à£I¡[¨ã 6¤º0Ú2óʨâ+<ïÒ—Ý>—J¦†ö„þ“ÃYA½?z½Ô/^ê´‰ÇèàŽ v§ìšË[œéÈ&ïi&å›ÚSÉM\½WŠ.“îöÞZw˯_J«éϽ̃MœíÊr–ðoSDú� v)dzáiŸÏûw±u`./(’þhý¥Ö¯Qq¸•ç²:íyíÔó<eκù7þDžåä¹ëÀ]{ñ$óôœ>À/8„¹<E#³ù §]“·‰bždi"&²Œq´ó,Óy‰,à›,a £8Ç9œzöq;(Nçø>_¦mGn«[QWÜZìÿ«Ñ¼ñßÓÓã`#C‰Óüÿç)ŒýLJ“þ|)Ò$€&‚¶}R]Ÿt»%%é¡P3"( ^¿üõâ®â©› Ñ6´mËœ-“^š4´ghýˆú¸4I0ÒdâLøæon»uzÖºÃ~}XëèÖ=S÷¬yÏš)wNIåþ7‹Þ[Õ»wòÞÆ—û‹ûApÔoÚpä†õG¬ï=¡7®!’Ú±lCY<}\\\¼ê½«ÒåéÁMƒG<9"oãÆ[.—ÛpΆT65úo£÷'æóÖNybJ*—jx½¡~q}álQÿú#þ âé_Z9`›9ñ©‰]ÿØé_8]Ù?2PE&wËÿüßᇉ4saÎ+Üvô§eÆÂƒÿ²Ä­¦ÈQÌd®ŽTÐĆf]C\¶Í³‘é‘Þ?BxòD¿øVNÛaÛÂhÌÂ%ÜN=³¹Uu`i¤¥Ö˜6“òvòÖ³5TÊ… ç<VLÔµÚC9“BOr(•<¹€nFÔhlÔÜìß;õ´ÚHMÊ)ìjõ£Œ«CëØAiÆéûÔôjà¶œ9‘èáhþÄG#ïÏX›óhÚñ¡q‘oð9š:mgkszCÛÆ÷W¥”2(òëÐÛ<9±enø7û2ÜÌ<_äkw9çW)Uy‹B¸'”åi¦¶;¢wê§3¿|$zdœW¹=ô¾;ñîð‹?÷â©þ+眧͙Sûàì6[vx#òÇÈùÃë•mwg輬ïGæ2‰eü‰ËZE¬H»&:uAø½iŒ¤)­&òÛÐ*®ç8Ýß¡èms?À”Az;¬ìñBÖ£Ùs¬¿€eH±)®û¿Üœp~ÊÙ´„~›v~nøÇTŸì­R£ñYw/UMçžú#÷q'/ïÆp6x‚<Óxƒß††sw1‡ócú i£#Í¡ó˜ï¡H7ÐCOèaŽfOñn!à”ŒË9$ç[4rÔÍÄ8ßÒÅLæs&e<Îyôð:óÁK ãé>J;x‚Ë÷áZùYFÓÀ=’ë îaëÙ 6r*`!b)ÿQøEÚ3sOñÃÅ•K*;;;“8ïâcÌ-îr÷¡,ùÜ’™7Îìîî.”*O˜}$V“¸_({P¢Áÿ‘#.&­HŒÓ £Rÿt•´(ú%EAÛˆ¶ãrü~!»ŠÞ…Ÿ_8p×ÀC7š´ÁbñØ(+f ¬¸dEë¤ÖÑwŒ.ÙR’/É7<ß°ü³Ës·åª›ª«›ªŸûásQ&’ûGvì3`Ô_Ëü‹YžkÞ6õ÷Szù™­™á÷ïhèèÜ%’Ô²½ÙÞª%UA ¼¼¼sJgë¨ÖÅYœíÌ{zXá‹ì8zÇÑ?;:¾–µç¯]}Ñê¶)msn˜sPªEÿâ©Ý_‘=NÏúÙ¬øÃê“* ŸYèmö·}Îáÿ‡ùâwÚ]õ{¤>rEô93+¹—³z|j‡—"ëh¡+ðõÈ Ñ×üíR·Ì´gVྴä¼’qtÞ„ÈTö01z:òY¾µ×Ù¡]\ÌK,®÷=¾‘SJ‹Mëœ87íˆÈ ¡R¶rIÊñ‘ÿˆÜÜå¿ÖøeèË‘½ü–SC_äKìËYx!å[‘r¦§}ºÕ»ØíßSÿ¶BS‘w5ûEhz¨¾Êm)»[}™—é`4Aà]‘ay_ªòí¬_wx;òå¼Q\Ê¥ÓEK•»¸5½!ˆ~±8ÌÎäZŸXåê;·Òso…ž |бÔó÷ÈsœÏ!ÝeY½K†[ä²-Nþšõw[õ!ãþ`x™= Á3Ÿ^¾¿Uб<ø·@UÞêÈܪùOE¾J×rI´º±Çé|<ïm6³}¤ò2|›€oÒÀu´ÙÏFÏîàŽfçE2–3Éfœ’÷ìáÌM vL5/àþÜäQ.®wU1 ™âáÈnÞ}\fëuyU‘»xy¼È‡¨á9ºùÛíw-Yé(rBÖ)|-­6´$²y)ê˜NíónfD–ó6ïãË\O Ç qF³ z}„Ëy‰_ñ_\ÃLV3šCyˆ3ØÈ\Žçç´r>_¤Šn6±<²â€8Ó_iå,*™Ìßx•>ÁFJÙ@Š›èázì·“ØÅc\Æ/(!â*þÔwª·¦'¥2-™l.[È$²i…_þ8]-øÏÓ>=W•Ku¤úO5Å´®>Šp…%iqÇ4‡xCÝ03™ÿÃYŸ�T8–€†h�� �IDATUèõ^˜‡úsù|¾­­­pµ²²²¤¤¤®®.‘†kkk‹?’ ­¶¶¶žžž×¾óÚÜ«ç]Aoº7N?ý½§«7WÏþõì¨$ÚžÙ³Ÿ G\Ã0\ÿîõMg5MûÑ´%×,úÄÐI·NJõ¦RÙÔ«ß~uÖM³Š:Š¿áðTÏÁ…Ỻºº»»cÓäBBIII¬ÿ[T\ÔÆ(^ðXÃe[Ë*¶WÒO¢(ꎺûW{ÀÚ5ëk‚|Ð^×Þ=¨»¤¹$Š¢\qnõ{Wòà!ååa*ÜzâÖµï];ý—Ó‡/Þ?-4XWWW+pi9hšÕ«ªãR5±þjmm%Eúóeú€ýùñ…¿&:Â(ý———¦ÿøÆNúUqMYøç±NqrW'ÅVâP¸}V¦?‘½ƒ—̳<‰ÈpVho©ÃóƳ,™YÕþÚ×x×_ýu\ª}RF{Ú¡‡BGðÉ”É1‘½¬\”v2D*Ê9´Ã¡Qtp Ë2æäTG:ónáŠ2ãòþXZTn·gý8ô^†ÑÁ¥¬: ¹}N‘3£C?cSêMo÷Í”Q)ŒŒglÖæ¬Þ”3#×òt¯Á=º2æ†ÎçãL¢.clh÷u{;ë,®a'–†wº3š½&*Z½8‰[ãØu{Ó_¿\æÉœ®”ó?‹ì¡—F•j s©àñãób0 Ù'÷Yñ r#‚GNòo×µ¥«æ†£_Í¿ñvÞí|+òãÈQìäˆÈ›œÅp^d2GRÙc|Î$®¡ÛØ;MoñÜš72‰ ~s`þì–òÑŒ‰¡EÔDJ¸“™G[èZÞÏÍÌ¥Rï‰þp‚G~:k÷À¾Nx#ü\‹Kï ²í áïî¼;´7‹fEð4bgð@ÊŽÈ À!?q:kÙÈcÜšI?¤#«:t,·3˜e0´?pO`| ¸Ôs0†ÇØÄd6v˜Ÿ·‘gS¦FFrh`/sïÅ¡ ¥’r,æ1ZØÍ|6sË™Ï`†pŪŒ¬¥›åM ›™Ê "ZI1šfø4¿<àË5‘QäáKzWkö­™¿n~Ù†²tw:ÎR ¡p¢(ù—––î¸wéÇ—VÛ†÷÷ ¥kÊòJÊ©XÂ.n3$݈ Uhù˜´¦ çrâ²/¡E$j¹ååå‰+GÜŸHÞ"¾º˜ŒKÎ1"v‘())‰Si¡=JüçÎÛ0þ¡ñ —}ýiëç}c^:Ÿ.äCwvvÆŠõñ‹T¿]…»Ù=hé I·L òŸmÜ~üöõg¯ïÒµkÖ®ú×ëƒ|Ëåb“õ>I¡CuuuœÝ÷Oqº;Ô.«íS²z '$ˆ> ‚ââ⸳¸wòÞöaí•;*s%¹W¾üJÑ΢²]eM§5Õl®©{µ.F½oœÊ¥¶³­á‰†°7,uúgÂç !à8hAVøxÒ&ŒW;¾ÒþUøÈA™ï¬pqЊÿæ‹ûÀ'HrQQQ</EÜl›sÜIÿœj1 ÉÜ»¬]Ëù)ŸŽ<Ê[t0¥ÆÀ½‘{Óò N“ozÙêúm“õ‡g´–¨H›95¯›‡#e)ã"õzÖ‡îålf4u\Æ“ §„í¡µ„L%“ÒVåånëR΋¼9ØÇrê²æ² EJiµÁyíe³^dQ¨)”OÙ8;²­Ý#œ¹)e–,6s•%[#§´R\ìŠj{½ZŸvndS¥t‘1=ÒÜÂ{ÏŸ¨åy>›ÒÃóíêR»£y/x©ÅÆx{ÞlÎÙòÔâê*ïî²02;RÊÛÜD9c+tdý=Ø}Ž;î</Úžçu*R~¢Gzê˜pü2¿½”­œFcàŒ Ó¨ a'SËÑü™€ªh?aT`LêʕѲ¼vhäiㄬc�»Ãòï{O¼õ½À^ör;Ï0…øÈwœÒjn­¹»Ìý“7Û=8<ÛÛ5e]î7‹¾zgØûF "²ˆ‘5íŸë¹ó­à_…Jù çpûXħӎåÕ@ Gó kx’ º˜Í2Ní² 4ˆFûǨǰ剴±|­Bswìz¬„v.—°Œ¹‘Êh?êÛF;ëÁFvƒáÔ0”…´r,ílaq*gð{Ö2™ÍÌfKÀHØI#wà_ÄÊŒb5¬ç,ö±„ÑÃ6§]YɉIºÚ³hÏý]÷cÈÛCJƒÒt: 7ÎÏ& ®·Æ,SYTyèc‡>'¥,Tê#›T¨èZ(�ø/¦«>Á«O I²cñ³#³M'6µ•´•ôf"¶]QQ1zôèŒ9rôèÑÆ K’_¢&•Ïçw³«¤§¤ñíÆ80õôô4Ù4æÑ1‰ÀRGGGgggWWWœ´âj&‚ÚeµÃž6dñL§eÓÃæ«Y_ÓÚØ:îÏã2-™ƒæû8\ÆogÖX0ŒËår‹¿´ø¨ÕÇæ*™HÛèMÝÑÝÑ­¥/ŒÖÙØ¹ù´Í{'ïmÛ¼oò¾ÝÓvO¼cb¦9Ó6º­}t{ùŽò¡ ‡¾æàÕƒG=7*ßs¯ËƒºÇ;‰ä3íÆäÒd·0]%ebŸZª°àŽBå¤ýCÖöXý±å$ƒö9 'â Óaá $EU<œ×_6%<,LWýÒxŽÃWø@ÆŽÌ¿õ$5)¥Ô„~±ÇYD>/M{ÊnŽ÷ȉ”Q’Õ”µ•A,á­@*ðÝ”îeDdqäoäXqDΓ<ÍÓt¤›WÏ*6±+0­RIÞ’”TÆç²¶qZ¯ò¬<[h­LÙúdä)¾ŸrRèjêà>ã1>êlù nõÚ$×Þâ„™þ²1ÿЃ|32ªÄær'vT+·ÃÓ¡‘Óx|´3š<“òyÆ„ª™ÏïCÓ¹%?òa#Ïñ|Û¹šɧ]ÈνîáT^åby‰)A«Ú´/å¼É žg-§‘cOpaÝÞ÷ïºý—<IÄ_8‚߇FÄÞÇôPV-Ó£¸Ç^~ÃáËEQ~Ö¿Etºþ½œ¸#íÔPIè+äØÌo¥ÕwÊm>Ä_twÅ|8¦ùøä|éÙs;©ð™{ʇ¾è f·éï¹ö…‘›#g’ç¼[#GDÞ`>Û™Í3¤y/™¼÷„~Á3F½t’£4pl`H(äþí§•"j¸ ïVŽjöSöÐÀ=›­äJÄ™¼ÀZ®`#r;9”™üÕ„ìã Ž9p±‡QÅã±Hçð"3¨à)¦Óx€1q ¤1ºbE F2œ<ëø<»Ys€¬x)vFò}ìÑøbã¾áûV|tEysùä{'÷q+þÒ–••544¹åȵÕk{zzbVz!–ÒGw§vEœÄ6žßŠ%S“RádÌA”sÿ )cÉUKJ³¥íµí[ØZ±£bÚõÓÞ¡‰RSS3xðà†††¸yÞÜÜÜÜÜ«&&OÛxÊÆÃ~wØæ"±«dÿ¦KÿÓKèñ(tEÕoVW¿YœÜA¥ÄãpÏMǺ‚eee===ÍÍÍù|~ùùËÃâ0¡;&[ŠBe©ÝSw·LnéšÝ5áÎ Aopzkz7žµ±fc F>1M§5휽sÔüQQ:j›ÛÖ°¨A±D/ø µQÂ?èÉ'zZ‰6ãÿNñ¯ðèè舯.^ŠBÉödÅ’b´ÿå ©$}Æ}Í6×—´ÕÚ§YÛ/]íâ–õFæšû}fqéÞã+\¹WGÆÇs"žJû|tÝ#áé_ (㘴E‘é¡u<ŵLMƒ"𙼳#Çe»Û£™ÜâwY'¹¹… ¥ØÆN¥!rg—öȇƒòzSjksmΧi§‰sC¶ÉsYJ®Ê¶ã¨b"ïc½\æø]ŽzŸ_|Ä[;-ü½Ó_tè%šÁY첌l½ Ztü?¼w|Tåöî¿{ÏL&“dÒ{I=@0A н¢xì½a¯‡sô{oˆ½aAQD¤Jè$Ho“2ÉdJ23{¿÷7ÙÎIÄ{~÷ÞÏÍ_8¦ìÙ3³žw­õXéå"øØÌEFÁzÁå‚'aœÂý&ꂸ̜¬ñ’‰÷ƒ<ÌZ•¯ZÀ ¯ðU»¢§ë”@|N0C1\Áo‚ Œ‚¯ã±xié"Âû ’üTŒæü}üÁU$H÷ñ¢táSˆUyÚÇwÚ‚­<Þ¬´=eaBz»4™¿²V·Aœ`·Æåð vA2˜Xp˜Enöþ"b†³áÜC¹þCøŽ–âK„s …Mì3Í\dÅ»Á©“eæŠ OÁÙ°ÈA)ì…!n„A2·Wð‘àZ¸ªàCÈ‚™ð�¹‚! v‚ Í7l†ga ü΀k!.�`/4Ã/ ‰p?œ σ.øFÞaXã¡ Úá*XÇà˜œäÃh¦'RòSpÀpltس`*<—Ë 6Âõð8,…=àèåVTË1,‡ñP×Á{ÐÀµ:_ƒj¨ëzÔ‘¨È²È˜c1]Ù]e—–åý׺º½ûׂ]ã¶‹ÍÈÈˆŠŠòz½ }¢Tÿ§¼,à Bšbb¯ |þz‹¾wÞÞ¬ÕYÖ«êU½qÞ’GJBŸ…åõ™5æ„’ñ%iÐrhf\ÀöyÛO{ô4~&¿5Y5©Ò_®¯Dô?µM}ì ÿKR‰lpÛ3Û+&Vœ¹ãÌèèh™ÆäõzÛÛÛEÎ oLè33Ù@ àÎv×T7è›A"ZX5kèw¼çàˆGÄ´Äfý’¥[tUUdìɬÎP4LB%±‹Òн…r"ä#Æ1î@Ÿ3‡˜ÿÆ}ÑXwEDD„¾.¡¿Óàdþ7ðý'“¡'#VTB”!¥5nîóùkª…•–DZRH­Ãüv¯w³A°,Èßì`ÂPíÑy¼ƒ§tö§©ÛyÍ«×=2À³²ž×U ‚³Å´-0ç_âÅ*š¿€·bÇD*liAp6,…$…¿ æA‹À C¤™35ÁA¦Á?× f8Ž*ŒQhPøB£~‚ÂN€¾„Z•7ÍYcbn ûóÊ•K_Á‡ ˆx�û¶)˜Íìâ„5ñ†à¸öÀAN²Ö¦A§…K‚<<¤+ÜäIoÕyi_tŸð9XAUh$à ݂10Cpž‡œTõêLýP$È…®ž:À=PS`…£&b5.Ò7|Ÿvïí±>æGCŽŸg f ÊYq/ù¯™çÞ¢½«‰îóeP�áhP ]ÚÝ'±½”û/áœ}<0N3äÓSy¾œÉçYª? L™Ã<Éœ56È28±0 –ùÆÀ\°Á\¸ \`ƒh87¼/ÀHxbá% Ì ˜ ‹áV¸Y0tXÒ«[úÂ[à€ ! n…A¦•À½½FVÀxL¦9+¤ªÁ€íð&´Á¿�˜ •ðO¸ö@ºàà‡A  øn„5л!vÂp5Ü à,øbáe¸|°.ïE≀ÏAƒæ?e�Û+íJ”âã럞ʧtEwm»|›ˆW½sÕá¢Ãß<ñÍ#M$G&ïît:-KUU•ì®\V×á BѹÏùÙÈô=é½¢7Úryî÷ûrc2™ìv»Ñ—È!yûW}·íËú%+¾4èŽì.¿¢\¨"&&&-B½·%XÊùGC§Xº®K$>éÙ“¶?µ}Õ›«Ž'D´DÔÖŸöÏÓ°"ÍÂûÏñB³tC{ £ûéSO¥œèèèè¹Ô¤ÀÊ'V¢YžiÈ€d“ªªÓžœ¶æ¹5Sÿ=Õæ´õÉØ•ÅvÜQá˜æpLpŒyyŒ¥ÝbÜç¡ï=6÷ØÐï‡o8èKò%ïJùéÈÿÆ4Ý ¶ôá³ôE¯oèÖ§O7Ê&µÙlòUmkŒüL##Í 8ÈGä#ôe5`O2_ä½2ø/}ˆ9}ž”!-][†^Ûí–Vý†rëÄ L‡¹Œ¨e'ëÝï@„`.ä0ý1nK¥$Qgõè`FMÓ§˜yö7~hüðˆê9+Ȉ†ª@Â^þŽG.壳a¾ÀËysy÷1j€Ëa†‚ î„9UA6Â0pƒ-~Šá/Ǭ+œlbMÅpæ¨ÔÃ):»àÜnAžÆÏ:6LZ¨l¿L ~$(æôn˜ÀÓ‘¼; ø0O;~ _z9Ec2lfð8‚™T.‚t¸VAY;ˆ ¢Ããp�ÂßñÕ|UÂ?ŠÕËkôQwÃ>h‡nP.4“£ñ¬Îé½>­‰ð®Ê<IP«b×9snU¬Ï«åÚ¾Z¸n×{xt7‚S\ôIEêÁù”m0™Ãƒ÷þÆ-~n=‰“,LÝoZÒ¤¾†»áz@)ª½º@üfç@dC äÀ,X«3 ¶˜Â¶EŒhæÐ@(P�ç¡EòÀ^­ |ƒMvF‚›àó^û†µp5üOÁrø–ÂkÐ «`6<u*¡HÇ_Âçp>œ•Às° ‚ õ¿Ùð#| q ·À|C®…Á^BŒ…!ð8ÜwÁhÐa, V˜O C8$@쇸¾€-0 Êa ¤C8TÃz˜IŸ ?Aè GÁÐ…°>‡± A�U02`Ä«Üù:»{uÁuP Ãàè Ϙ&áÊrÅýcªcïª=½¶5§µð›ÂØæXS¢iÆ‘ó“ç”ÿÑæðÍi înôFŽ›f³yô£Í³¤Âoye‹0‰Ôí©¡àÊ Ž×ªªvvv*Š-KsŸ–%4O½¿b´g^”æ1{ÍÖ+Ð×U9³‰M쿟7 @UUUKKKCCƒdg8™˜ü•ZSNùç)žtÏ«$•&|U „ðãïS¾û|…Â’7ÙëÌqƒÁ¤â$S°/cÛ•îòåø€è_£Î›îÚS3õÇ©¥SJk¬51µ1B·Û-§£oÀÖ`ÛsËži¯L3v‡rùo´,Ñ­ÑíCÛ#"”€"§v=bÛ*5eIÊá¿òßÉw„B†¯cŸMØÿ[ÁùÕüh,8 ¸ú‹*ô1FÍ„¤€«/iQ(V ¡ÁT ]bI¢ lòŒ·ß‰¸‘ýáÊ ~®/U¾¿ŽÑð l`öëŒÂÜ»ñ©0¢a›¼lšÎ²úàòTŒ‚Ã^n[ȾÁêG7Ì)k ¦œûÕ v¢¡Nç(œ׳w—Л,\“À7GÜt™xGá•D;cIîÄ oÁ3€Â0…‰ð¹Î~Á'# †æc?K<7PLù”Ó"P›¸øq+e*»}Ü$¹†ÃƳ]ü¬QFÎ Þ8NÀdºý4­n‰B—Âë:Õ&f@™À©3ÃD¼†ûáþ1E¡~‚™Ð+àBÁæ�~°Á1ŸÁd˜©ÐË(¨Íþ "Q§ˆAïkCüÜ ¤"‹,qqFp+¤ýú¨Å%¨<¢¨g+÷ܪÿTËO“Ø8¸äWð ¾UÊ’ûÅÅ«¹­;‚ð\�ÁwpªB“ÂH<˜Ï%»ùôBHƒX¨lÈ,æ…Ã|¸VåzÁQÁ™ð;ì¥Ç€øAØ.Ø PÕk9±D'¼p!tÀ%Gá8œíPfÛà6X |ÓÀ§0I°2 �Æ+,tÃo vÃ1è„oÁ 0 Ü`ÖY G ²÷ ³J¡Â(_ÂD�Gà8¾‡ÅàS  4 �À€^C©r(†!°vÀDX ãÁ¯3¦ÃqðÁp¸�¾„dÈ8áߢWͨšöÈ´ž-t¸VyVeJUJÞyº®Ë4Þ°°°èèè§=OטkžIxæmåíØØX›Í¦iš#ÃÑ9¢3çý³çOkîºÜC; W¡_rZw o§þi对øO=Þoý´úŒM‘õ‘G/9ª›õØý±ÙŸejòEYkdñÒ4mÇ´qþ¸Â…>ŸO^Œ4ý“$½ÐP!Dd}äÄ'ªªªñG~‡1AêCb´Ùlò0~èôC>«OQÕ¤VL­p t ýzhè•»3Ü Sä/iº² ŠÈØ›‘·&/É–TÛP»/sß°ƒÃúTÆ‘ïÜùôÎÆ‘ {þôÞ&îI&‘¾!ÝⵘÃÍ¡CDUDÆs½oÓŸ˜zH0eüO¿BýÎnÆè;ûÛb9�†ˆÍÀyÆþ/ z<¹tü?ÃB“ÉÞ£þþŸXÅW¨kÉŸ*”ûÃU€Ûpdjû¿ƒÇL<¢ÍZÃëÕ\y•Ù?&È X SaBo8úS¼0Çy’[•‚ÛM£çö_Ùo¼czŠW™•;nÁÓ`l2šƒ1° üp›™² ÿ€Fð›¹Xåô.¾€Ø6Tæ \°'Ày&nÖ8c`•F·ÂR•j•Wut—YéÜê@œÍ[#¿™ÇØkn„WWÀzxÓOQ+E# Aƒn>ïO–pÏPºG(ŒPyW'\P¿ ̰M0ÙLv‡!�—j”A1\ _À í)̪¥A,¤Ã%  …!\ñ-;ö,ML<§¨´Ûa¼w+œÆ=¿á¾’ù›`ù~!ÁYêÔöZÛEÀp�€§’¹ÞÅ'a´»^Ïcñ‡ÜQßÛofn—aœ lxÎâÓ8+àjø‰žlå 0Ya€Ê3:ûàK¸ ΆÍÐ ßBTB;ÈÖs0€Wàª^¿óCMP #àT¨„OÀÃ`4¬?Øáx:AƒKtTB*DCç°Áo³ÁïÃ%P‰[` œ8óa‚Lh‡Íð8‡mà‡Ÿ ~„Ep l‚KeŽbo¾¢´l†øFA7üVh€ÁÐ øµ×M£éIM_çB3ÔÁðB"Œë;ê=÷t6NjLÝ’ZvMÙÈE#Ú±÷¶½z²^øc¡¡q‘aóR§ÆÍ Ìu¶;¥’Él6»†¸Ú†¶åšr%üÈŠ“ñsFXC؉„ŸV«UŽþŒƒó‰¶÷²ú÷7Pè)a‘ÁŠ‹*²ÖdÅTÄž{8º2ÚÖb‹Þ-‰ i¢OÇvè’C6·mÃ%tUÏ+γZ­Ÿ$ÙO6+ÆŸ3æWÆ¥J¸2,C¹ò&“)::ZÓ´âS‹­mV›ÓÕ_Ÿr0¥£g‰Ø»Œé®šU•».7º:¨™XØ«ìiiR¢ ƒ»»» w`‰Ñ]Ñ;2F6ĕĿ¿}nKÒ®$ÕõOåØV«5tnùÿª7’Þ†ÒDÊçó¿Ü(놱ˆAö3˜}¨¡¡xöß›VHûcãÏD!ÙšÛl6c/%·˜ÆjM¾¬JЗCEÙ®ý…úº«¡ ÌÙÉ‹‰´¦Âûp<ºåü°B·ÿÎâ“áø“àTÈ….Ðaê0ÚÌÎ\: ¡ÔÏ!?#ÄÆ­<ìF)c{ b<Œò—–~€£wvó¡Âõ:–î¢*@…TA¶FC÷‰ƒaºœ(ÆuQ [ç,ƒ¹°ÆÃô(††³¼›z gêÃvn©TV^IÍ3Œ¯0 ¼>å­çýÝ 4Æé\£Q”ÂànÚt.L| )ðM—‘`Á¥ŠÅãøtqÄ7Á(Qçå#Èü,-vÿ$ÛÄCÆéÌ7s»¢nWÌÍ⋽âåÝy´5k0݈é6EiÖ‡èÃägͳLÝÍüxvÜÄÁÓÐ2UOµ:þL‘$84ÊOjïà<jòyx9ß>†i#W$1o;E;ùøú§*ØÍÅ—êk®'ÞŦÄO~vਨ»Â²ìýó,ÎGÜ ¿ ¾ŒäÊ4\í´(L†a>d@,½çÀV¸(ÁГ­lˆcŒ—Ïà(̆80ŽŸÌ9µ¼ƒáNø�J!YZÀ¯ð�<ë`øà8�ƒáÙ7ƒZ`>,…sÀ «adÁ.Óa“Lé…P §¨´¨ä ^…2ÐèI{ @=ܬҦ’,˜ #á-8Õp Ã0 áh„*h‚S¡CŒƒ•ð=xÀ í>ÐÉ‚ƒ¿Ã¸R¡ Ê¡f÷æ#Ï‚½ Yp ÷ªî€Q‘}OÄž_*©Ÿ^Ÿ¶1-åpŠüd†‡‡Û]öó£t$I×tMÓ|>Ÿäj755 ù!ü‡ˆ-555n·[×õ°Ú°®Ø®Šs*26f˜ƒfEZzºñЀúðÈ,%i9a,9dûÓYS"ëE(žìÚ3j/ ”Î-ñÅˆÈÆHYûä¦!”ã`í#‘GÏ=:ã“Í©ÍíööØúØ._—¬›²JvuuE¼ÏU “hҲ럻*ΪH(O°vZuE×u]JTT”Íf³GÛ÷NßÞ>dÏÈòH[» ˆl‰Ü{õÞôßÓ ‘æÓº"º<9ž˜ò]Ñ‹ï-nÎkw…g4fH’¤µÎÚ0¦¡äº’´Íiª÷ë[³nN8šàÌqv…wEÕG ½ïøÔ¸ÏFÔ‹”ßÊ[%ãÞå]ê3e5ÌÈû“èú<Ø'™L¾X’!áPnz¤CUŸ¾¤Ïï4µ¿’!t3'¯¿±‘`¤lº®Ku±¹ åÂÈ]2ìåˆ[þ¸ÍfëÃt¿MuV�� �IDAT5›ÍÒ/Ñb±Øíö1'M:±î*ÊCæË¬N‡›MlNf~k—Óÿ] o¶°x9Å#qšÖÁkØJµ—Û²¢žý{a;$é´VS÷°å¹·Ä@WÓr1꣜ìâe•Îå)Óy öCS'ñp܇uB˜Ä(œ!ØËœÙEn3Mt™ø^ç|ù~¾îÆ &è\KÒ0ŠÒ¶ñ8ì ;*lö¬Ý Ñ¥pº™l§‡Ç4Ã' Æ`-0_ÙËÅXLÌÚqv|Ä×s:i†Up5A*´B>¼w†kìü\/Ø%®N¯ÿÂýŸòcšç,¾«RnªPnúUÌZ¡—I[Æ¿¾#U5_ô¥~µ`êkø’hY+"-bºÃÔZDi0Œ|XhHêL ~y£¶ónjcãiÜü._ ãËïØæ2uÔ jµ†ÏÙy~GX.þÙº#ErkEûi<ù“ºYòŒ€Ž�Ùl*)> >„ãð\Á‡Ð 3`¡B¼ Áç¼h`KágøÒáLªeÔA2Œq`†V { Iá ¸,PÏA.¬ƒ/ ^‡]&®Qh,…8Â?àbˆ4c×Y Ãák°˜9[§fB9|+ȃ8—C ´C¤@-ììì‚ݰ¦wÊw=ì‡0ˆ…g ¦ÂPØ¡0À—ðX`?|Ñà†�u–ÂVðB-Ì„ZXË RÀû TX™p*$ã°΄#p¾WmÛ–u/k:¹)wYnXw˜1àŠjÊ_‘ï÷6hŠ®ŽVŠT†±Î¯†|uåú+ëêêœN§Ëåòz½îwÆŽŒœsv>±³ulkDc„¢)ÅÏ›ƒæ¿øSùp¸2P¡ÏQÚÈR¥Ïþ�ØúòÖIL’TŸQ¹.S þ‘¿.)>ŸÏpã–…Õâµ$ïJÞyÑNK«¥äÒ’äÃÉ¢VÈI 4•åÜˈz³ÙìOö;ã;çíôÄzF?:zàOÎ=XvIYåé•] ]%ZVÃÔòSÊ-KZyÚÚ«×ÚkíºI·x-îTwc~cúÆ?òv…&ìöŽŒŽ=·ï©˜QqÆCgäþ’ëæìHï¯׺5SÀ¿;Þ9ÀYyVeLe f¬Ý½ËAµ3­sÏM{rKsí>»a ØÇ¸«½Œ]Žt(–Ñ'²LŸh)Ø-ÔÇkØßÉ/É5ˆˆ°Ûí ].—l¡ ±T¨jÊèÅC»«>V)}pÎ�¶P¸2Ô~†c:½*²u“g9õ5î>Ý•±»2Þ-†.ؘsʧløðÊ~®`|щáª2AÙ¢`†nnbÁà 5ê7«ÿ¾4Çš/†Jâù|8Gýe¼à|•³¡^a8a€@5í*ãÒÃQ3Süâ8_ çÇcfnÐ{†þmœúoNq®Ù˳­Ôu±ªuVŠbÖ ç`=ú4‰U*c¬V‡qª_θ¨Q¸@!ê| ÜÔAí ÷ª8ưBtšÖþ¦ ö[eá°ÿÔ_)úŒsê4ÆÓíc¦ŠUlðsi›Zº™îI S Ì¢ •‚­lEwਅø v¢¸2\½ªKìÙÄ—à8gQ•È ¦…Õ…·èM<þ4'×ðÆ$ž¿B¿é ÅcWÚ/㪽ÄåsNü1ñšŠãQ»ð>ð²Z£Š…÷°p¬RR¥0`»’¸ÅU?Z´,ÖJÝ:ÞNÞr®h'æ{WVéRIVÐõeíŒOZ4­Gp=¦’,(³›ÁTh€n#º  NuЪrŸ‰) ‚N?A%,ìàÛÞ¼Œ Ìííœ>ìp|EpÄÄÍ‚ãA2¼û`x`1´ – áb¸ÐEðºÎ×ÐàrHÔùÜ0b¥ …Ê…ïÂDh9pl‡“zsî§B a0¤Á© Ø üÛ Påö^›%¤C)4Ãý° {H¬p „ƒÐ r:‘÷Ã(„S!�U0vÃDØ �3`¢W555nÌù%'¦)&Ô(OÖ²ˆã-)-­¹­1Çb„&œœ«®Xu4îè9žÓÖÖÖÒÒÒÖÖ&§=RT«ªêÀõíµöŠ‹*º’º,>Ëè7FK“ºžÕw¤¿aJCGv‡¥ÓbñYäñVbXÃԆΡÂ""Ú#ŒZ`ÔDcØGÑÙRØ‚BRIR¸ú£Âƈš“kô€n봅•Âä7Ùëìîá„€-àLv¶gµ·gµ;:;²:¢+£ ¸’‹œÎÔΊcG¿8:usª,Ó)[RFn™û[®nÓ«O¯ÄZ3[Íó€Æû&ì¿tüî³w»Ò]žÏ®ëvüÒÉæn³ÒW[›½:;kUVdd¤ÉdJªHjÞОÜ},Z–õ´]ii[Ó_yØ›îõ%úlm¶°`˜ªª U Ön«7Ñë±{¬•Ö¿€+£ô‡† J¥‘l­¼^ï WýÊûtÃÒ ]z$eÔãñðŸ‘]ý'{ò‚å[È8”„îCmÀþ#è$¤i3\'ä·Éªa».¡+ÔÐK×u©[Í_(Ñø£ò˜"Ĩ¨¨¤¤¤ÄÄĸ¸8Ã,JUÕððð¿„+_½ÂZ8 VƒÛÄY‚5*^øÑæ}¥ûx—Ö‰Ž÷™cBDóy+f(L0‘ M‚˜ …&²m‘t™h ü>nðÆ3šã¼|ãtRà ¨ä¬ã,¨¦9–ø5Ý)ÉþC§b"B ÞÆ‚�73·„…8ö@¦Ê‡Ÿ?.¥×;¤CòÁ“‡ØÂîepÃ3`º²v|¦´ŽQÕû~ð'æï.º•âsaÄy™)á¬2s_ð÷1ŒÚÎ’ûÅø%"ÊITšåR§t‰+ßeû@šO‚A04n>Œ=Kyt¬Øßµ°¦ÀJøYPª­¸ Õ¥A±4‰Æ¬§yòiû¯béE¦IÍ)ÙwÐêxéR#pB¬5qÀ§2ÐÄPgqv(ͳáŸbÁnMI7Kç0}0¹zØl!f Ì\À’¨á±ÕTÿ²Z•É‚õ à<(¦Z™§qDçsP nS©Öx^'m2 ¾‡LȆI° &ÀdÈ‚— ,`ƒ3!ÐÛ L„©°¤×ëo�TÃ"Ø 1P^¸T¨dX çÂrà†Ã½ ¡ðÓão;Âá[p@ƒÀ!p@ìƒ|˜[`?Ì„‘0´^µY6ÔA)¤öÍ@;„Ã(AÄB74€€Cp Ôp;ÔB5„A*´ƒ¤ðJ¦ý ßÒ“'P :˜ ê šBDª««×–¯µvZ­.k(\É#g ˆ:åNw7i ó„UŒ¯ˆ®Œ.\^¨úTÉÿ6T8YQ«Ëš¶-M ×Ò·¦Gø{’Dä™zÿmûŠl¶Öá­‘å‘–`Oe©U[zC©©ÛäÎtgÌ4BðŒ<b#NBV[£í¿{ÿÈ÷GZü=6U3«²~Ï’öH&“©ü¼rÇGÇàŽºiuIÇ“"<¡V¼Š¢„w†«jÔ±(ÙÓÙÙeîê2wiáZée¥èÄŠ16üq5§× Ü=pÀOX­Ä�9õ²7Ø3vd´¥·©ššQŸQ>²|äÖ‘±í± Â;ÃmƒÛ²×f«>µ¿ŽUÖGcÀ_ïÌrÆUÆý±Éë&m[Z˜/¬3«Ó‘çp:šF7)feÈ®!;JÎ)ÉZ™õ×p%wrFÃ!{ÙptuuÉ ©?]Ûhgx‡bm¸’¯Ž±”+Ï>mÐ_ ½û;Sô‡·þpÕ'äWÞ£}—Z²µ2Ü¡dß,ÁÏ01 õ¯’³qc*˜žžžœœ#iôiÐb±Œ;ñÄ®Ã;Ä+ Y¨³,Òt| h\è!œò¯Õ/¦qWš¾s#_l†ƒ¯®cÑÙ å°ŠßX¹ÁÆñ6¾‚ók;¾å‡{à+Ø ÈÎçwÙZÄÝOð·¯ð6ñã;‚ ˆìQœ/ªG×j“7™û‚†¦q Á`‡ ÌÌ7:ƒ`½ %Øsðßx›mÓ(øA¬,·çòÎfwúJöÔðÒ½lúŽA+ŸdáM,/D’’€¯žçÌ<œäã^<€•‚JÒ3æ$î(5?gi¬?3³îžoø¡•…:B2Lê¥M×Ã08¹‚¯z717sõ#ʨoTiÜw‹·K= “|-\�@ŽŽ L° .M!¹ ³†Kp2 •´…"¼Ž]ÃvȇÝ=ä¯E“üoÜaè†gY9ºÉj…j=ÞH:\ u0¢=,„ͽvû­ð‹F²Ô&Cü¤ðPì„u°¼ð¬—½‚Á $B!<O€æC ¬†<Øãa DÃ�\ÇázH‡X˜û b ¢ .ƒ4øÜpA\ïÃlh†/Á WÁ xª@ƒ³à1PÀa ¨(å;¡°7d:,$X×A Ø`X`<¼:¼Ã!a5œ½!ÂCáAøfÁ"ȃðœ‹`+œ Â<8³Ï‡©eDKÓœ¦ˆæˆñÏŒ7t²¡íÌß3ëŠê*fUä®Èµ7ØuU÷„yþ·,çä’dÀÙƒ‚G/:Ú8¬1{yvlU¬c¬#uGª)ð/-æx Ð1¨#¾4^ÒóúØaü7l4 à“‚÷íŒ=k¯·WŸZÝ2¼eê3SÃë•çTvÅuMziRŸ‚Þ•Ø%|bÀúŠX,–„# Þ$ïñKç~— ì»w0dù¨º¨ 4”7†[’1‹ôû “ÉT;µ6à Xª->|Š¢ÄÕÄÙ+ì ¼a¨ü©QPŸ¯¶Ám9ësú<w<.©:©uH«ˆ@ë Ö²3ËPþ9_ßÈ6;~ä#pë/ÄÚò·ÉÖª¿D)tWjæÊhèc8Ë ’ÉŒ|€ÿ_rƒ•’’’œœ,‰?mmm.—«¾¾>H-à‰™Ç3¸ùnn)æ_;™ý©¨<cÑBƒ—+@Ñ⩃t~P ÇtN¼o«aS¥VëŽÑ¹®›ã­øžUàR¿&ºꙿ‹ÓƒTz¸y>þ­¼üo^¹•Ê" ëÍ<¡ñ!­ñúW[ 4/ ÀÍ Õ0Àpµ…”Ög2ÊÁ%>Üü$XMw¦û0ŸMð‰¼~¦ø¸“ëHôsîKøß域òF­—°¦ˆ[¾Àý;cº:ÞlbP·b?F \𰜯Xø(Ðð )ìHÖ>zH{n\Ó‚xo²úY¹î/ê‰JŠ(Q?Š×ï>Š#VÃF8.…0•D-rî€`¥F9ÜÃu†w¶VÑú9l€¯à3¨‡Óa*LqÄnÔn<ÛLÌÓ” bêñ‰C ÊáÃc8¶óshðû á ‰ßDëS:“À ׫°fÂRËÀ Ëá(TÀj°C< M°MpmÃUîR°i|^˜ m0ÓÂ}A®6sg]0^WH6G˜•;³[Ð!@2̇åaáÂ�ÀËàH† Ð Ûà9¸¥—|XO@=¼ çÁÝ𬃠Çí¾ ~„àmˆ›Áð¢à¡„uP ÂØÛÁ KÀ ƒ£p&KeQoH£(„LØ ·ð!†ëà9ð9tÂz˜óà#脸>&Lõ'Õ›¾7=W¤…iëß\?`Ï€qËÇ™•¾Ÿ¸ôâôäCÉ6MÉú%O A[ÐÔm •¶ô”!«¦›õޤŽÍwoF.Yðv/Ö×”ÝTðvA˜+Ìäÿ£Ö¤Õ¦ñðšÐpÿGìï‰9Æ?ƾ0v÷û'=1ÉèKƼ7¦mhÛþk÷ø~ĸwÇ9-Κ kF9:¹:9(¾¿xòç“Í~sÀÐu]˜„'ÅcröýC‰¥‰Ú-01Pu^UçÀÎÖÂÖÉ÷N¶¹lšª)Š¢¨Šc”£mDÛ%CÔ`_Ÿ:]Ñ" |¢_C|y< £÷‰ïRÂl˜}fùýšEÛ}ûnGž£ X ë Ñ÷È3Dü‘xYñËÓW§‚5øGáöûý'òùSƒ×Pë¼?me¤Ù‡Ñ¨išù§2mÃ0ɰ—ì/ê¯6X¡b¯þZýÕåçú° CŠÞ×ÀÚþy»ä^Ö¸0ÉÍ1Sƒ*rÒkXÊ0úQû Ý ¸þź‹Y`ç…Ê‘ƒ&G„“_¤˜¹EçâŽ~ÌÂxÁÇP Å ¯cYÜz§˜ì@ý˜† Šž¥Pù:ËͳÎÓß¾—+ý|p5Vó•W âÔ8ó[sô¦K†À»:õ0ÍÂeø=•mvÖùE!bTh±p•ÆBtë¦ÕÝSÞsd ôÿèì¼ ç°³‰[?S‹©³@Ý©¸ù*ÈûÍ&W©ù±x}}ïyk.®ÏYçàž0Þ««‹4G·kõ §[ X`ă:¯ÀPˆw?Œæáwõ™w²© Y›ÚE²à éå<Q’òêkžçßãPÍ?AÌ€ëi‚­|w„›PÚ×@!dÁ°†B \'Á;0"-б¿êûï!)ŒÎnÝ}õv/ä…|^O‡•0~€&8Ñ0 ¼ð2$À»¸bpy…«P7›¹Y·W1±‘à¥t.6s£Îï·B4èðä‚ nlIàƒJ•74¾̆ó¡΃*˜¤ã‡dv¨œp=ì…óá_¼ ?DÃ:˜Cü¦ó±$/(̆e C ¤ÂQø²!†B$ÂÇ †ÑPE_ÀJh˜Ðk¸FÀ{`†0ÞƒÐ@Ð0&B6Ì€=ð3ì v€" ¦@ ¨ð¨PÕ° 4(3Œ†ý½AY:,k/'e´Â�Î0†ež²í[¶'N s‡åmȳØ-µckãëãM“ap(B1ûÍý k€kßõûÂáºE·º­Æ‚º+¡«ôâÒ#çqrÎø÷Œ!¿‰­ŽbÝ{ëRv¥¤§é鯱Úì3[|–0=¬ÏrâX“IÏÔ½ƒ½1]1{ìᣔ¨¦1M ­ Qž(Ùå—ˆ¨Œôã ˜òÕ­?]œ¾1Ý1Þ‘º75Ì]ýÛc¿¹“Ü GT¿êÈs4ç4ùaHh³Ø3~Ô•ˆò× WÒÞ¤üó-Ý£!kÝÜxRcì±Øæ‚æ¸º8+évww·¤´TϨÎû8O.N ¦»1³2HŠ¢¢¯;xxÎa[»M³háÎðC—rä9¦<6ÅÒe1ÜÿÔ Dñ+J§br›d*1ЙÙÙ™Úii´h!_lŒ •]Ó4Çãóùä6KšN»ÝÝÝršçóùäÚFQ”ˆˆ¹è ƒò§þÔÁÖ¨õrÞh$óöï“BgCç–'â†þgtt´ÔB…B”[„ÞçPZ©¡Þ u§íŸªïCùN KOOOLLLNNŽ•c[[›DÄÁ#FÿÅîÊ9Ð Ø8’÷?Ÿ…©ŒV¦! V¡Z¡*‰*SÃáA“¥KÜ~—Ò4\iÉgv&)Ù¦Ý' JÁ*.Z û˜¿äã‹8­’-È`È\òÜüëFýØßÎQ"(‡r•D$è|a¢[¡Kà41¬:&•jA&عîI:uSö›¶Ü£vš…”ÈD×™Joí2’1¢a0tY‡4YòôÀÖ$‚Ylh‡ØËª’ÆP°ïÚˆÜV-\ѽÍQp&¤Cü`8‚‚G`hÞÄñ*7Xy®{÷4u}8û[v&À<Ø )ð4åJU_ÕemÉJx€¯¡>‡CP >ØWÂÏàQ°Š_žaá(¾³¨×¨ä F³5Œ÷@܃`4€k`Eo9Öa$Â8 ~…N.góÔ(loÐ9 @ƒhˆƒ10* 1š‹ý¼ r³ JåbÁZÑ0–Á£0¢`¤Á!Øe!×ʰ {àm_CŠÊe‚y À ÛS`XaŒì-ñÇL=`Œ…k`-ܱ°¶CÄC3dC ì”ÃñÞöÚ›à8 †v£{±¿l°rz3 ó`6l‚ÁP áð)Œ?@-@.xa*ì€D¨rð¹&¥T*WÁQø¶7Ÿº B& ‡oM FBžW-;Z~uÐPÌÄ·ÄWŒ«ë ‹jŽ’?¡{ìPº”ªª­ƒ[§5ÿfxŬ w†ÛÚitG*ŠâŽqWŸ^¾'=I~Æ– £TN¬ŒªŽ¶xØŸæ;ü)Ë9´Z¹ÓÜ»®ßåêZƒ1GbäOY,–ŒƒuëâÄÓÆhÔ¦º)uáÎð„ò„ðîð¨Æ(Àæ¶%V'6g4»“ÝÑõÑ … ÑUÑöj{¸’sª˜ò[³M.0d±kœÐØ6²-ïÓ<{½{@wL0&̪òÇúùδ-i¡"b£èC4hÓR7­®ðÍ–Á-­ƒ[}i>ݪøv„½É.©2³ÏAAÂL½wí-ŸS>èëA¡·®\m„¡vê“LÖ‡¼ t²ÿKJùDŒ÷CŸŽMn4%ÓÁ MÈGä=4VG†‹£9¡Ð ‡}ž¾üNy1ò&•ÁÑJ°ùk¸ ÕùÉÿe0Ô|y=ñññRe,„ðx<§¥¥%X,–P¸ê¿�l鳬å‰N ‚…™]¬éPØw ^Ö8 |¡=¾‰ý½Y·Ï ò!-ÂÅpÕk¤^·?E|<ƒ‘¤7qÝ7QKföÙºñÕz´¢sÌ\çïñýjq:ïÀ5A‡×4l*‚*A•aܧ¢Ýó¶éé{LcµS˨HÔ*>‡;  !vÃO=óo1 ¡ÃŽ^Ã…,63cï,vYVpÝ?é^`lq°&@w/a,,P À(©0Q[z‚íp1|Ye°\ã*$Äqu•ú°µŒ*â»X&"4«4ë4 2�„¿ó`-ÙçBTÃA(ƒkTî‡N+DÁXðBL¯6y�¬‡*xÎD¦Ð‰P¥â¼!xÔ^:Ü›rÁ‰ð;L†/¡@eºJA' 2al„k`!Œ…08§7{^~¨æAÔCd Ó÷Ðv• ¿k _XØãan¯+ÄdˆèÍu<R`¬� fA6ì„zšà'˜ Å Àåð$öZŠŒ7,‚Mí2ØaZ¯Uî¦Ï‹`"Ęx^£ Z`;Ø!ò`/Œ€½½?’ å°€2xÉÄxÃc' Òu½6«¶~X}ÖÞ,cX$WÆÁÜh†ZsZÛ Úò6敞^:öƒ±3*öÞ¼wâûmN[ÙYe™%™Þ4ïî)»U§š¿8¨žQ­Ej#–Œ@ý²+ϰ2ѱ¿åRèjš¦éÚ5CºÂ»ÊÎ+´d„«C³þq´ߟŒ {k©Òû/]×cÄŒ=0ö÷¿ÿîäì¶wO]:5ÈÿF$kè—û”þn¿¹Û,ïžÜÖu³‡ûî÷ËçR>«<ó×L³¯_5hš†@Ñ’ÝÛ_o,@ŒÁ¿v-’/“.ôP]¨WE¨Š¹¿ËpgÞÐÅ•ñ$ºH >‘/­‘ÝüiÂô×EÃÜÄàÏ+TÜ-¹¡äšÈwZ(Q^€ìÌ$ß=8Né$)©’Ÿª|?Á0ÐW‹á\^]Ïê1|ëŽ;4†hTÁ ½Ó˜áC‰jÅN6åÙMâ¶õ¼8‡«rºùû—æçŸÑ¯øo*¯ýÎ çòÏU|¬p ƒ«·‰G62µƒ×.ûÓ5r‰Ç! L„éü ƒ Lð¼Òk@ªð¦‰‹/Â@e_Uªç.÷IGym�o•Q:›Ï‚ÝÒ¡gœ Aˆ„é´­f&xîãžU,¸égÁ(Pp"§€Cù,)Á¿J` äÃP˜ ßÂtïÁ •[òÛÀ‹ën Ûyf¿ Ÿ¿Af,_?�~xrà‡D†qe]÷ª³ôöÜ�ã!B Å½ÄÓÅèåÄåräJH‡*ÑP+ŠGóá hß³úV6”ñ¸`ÅÙð3Œ…í½K—7aL†xp˜z,Vá=Ô ×jõç±Êæ¢3’ –ÃJA-l†Íà€CÝ\›ÀqÁëÐAO ´ ?‰mÖ(€SàKª Gà0¸àfˆ‡bÁ8 ‡ :`%\ŸA„CqW»{ «ôÞì«"XÛkµ7†ÀAØ {Àç@1¬„Û`*´ÃJp›y[ÇGÀA ¶A.tÃ2ðBCï°(‚`‡;!Á&¸Úá4A5tA'̀肙p* Hæ1 &Á¨_¯ÔLº„¼Ã`;ÃYÐ ç†2·nÝÚ3JØy¼èxþ/ùÉõɦÀ%I~ìC7.ÎXç¦y›¢G7å6%5%m¿n{aŠY±×Ûw_³Û﨎ðÄxb‹c­kÉí%•§VÚì9ksÌúØÈ¹ 5jë“4Øsa‰¥‰§Vd­Ëò†{ã ¥ %×””O*üã`ãÈ/«ª¬òQ•Qn;YéèN*M2ª³®ëeÇÎ?–ÿR¾©Õ$ÿ}ä>¡N Ò`B¢BT]TÉ=%¾$_ÐÜwݾ¤íIÖf«¤GK¶?Öß–×–¶%M2¤å³899 *�� �IDAT6ë˜Écª˜]‘¶5í?ž”+Ì=Ð]q~EÚ¦´„ƒ i[ÒZ‡·šusDk„Wým>$Y<,,,**J&,K0 ?žº!5¼9<4c³Ï,Θ²@(ÕHrÐ×glhˆ|å?¤Ù‡q|9‘Ë‘Ñ6IØ6ä}| ÁÖŸvW iFpŸ½Wè«fðKûƒŒal¨,ÚàIwÃÀ6£•”7Y¶¼2Sþ¹ÈÈȬÁ#þ¢»2A%ÏþƒË»ù÷;JËYA’ÀÕ{¸>ˆýbUó-¼š†J¶koSþ¾B\?îå³§ƒoÏ#Êͨ㼿j¾íÉ„¦ÉM˜Ùýa×)Z´p}à*81¦pð['_g'4…qo•:WÂó§ÃH¸UAŒ‡‹ÐNj^ü©éÊ«µê§xònØ-2W³ÊÍÚÓY_¢ŠË? u DC t™üë6^}Ïr™'È“f®Õ¹_ãa×'µ'6>´.RºÇ ŠÂQŰ^„/ „ uÞ‡_à ’¢ß= Ü™ù"º•«JaÔÀ 0®vÐ.®:Æšï)zV¨ös­ØÖHI2-Ý|ô³&ˆÅ@õ~ÎiÛõ6™;ññt™‰ÔJˆ'_"n'Îf8ÅÂ}fˆ¨ÄÞ IÙÌ'`jÿ6ñÉü`‚yPoˆÎ'ÄÆ:xUa¡à·&0µ“únäÁ+0RASéTpiøá\ˆ†*ë…Æ‰f.ÓxZpL‚íðu0®ƒ9p£Â£‚bH€ÛÀ÷@ÄÀEMä‚ Òá:§Ànø^€jØ'ÃíÐ Ç þ N˜Ãÿ"í¼£¨ÓÿÿšÙ¾ÙdÓ{ ¡·„šPD "*öŠgùª§g½³ÜY¸óγœ]O<Å ŠéR¥CB ô¶)›lßùýñÉkÂqÞýæ¯ÌÎÌ~Ø}žÏó<ï‡�è!.Èm0 ––Ã3°~7ô‡‹À › ò!¾‚6(†¥ Â%P oÀ$x^‡“`„«@…Ê4P`6dÁûÐA°‚�ÝÐfÀ½° @U9'#ÝC€úÉõU ª†®ª˜•uO­ËÙ–“x<~Õ¯!Çìv»?É/j÷íŠëŠ9ã×ù'ö;ÙÏâ´l¹k‹ßê¯Uki± úlPW¿®_ ”²¬—Ž'èt:SÐ$e•Þ|Ͼc‰s(¹Y›­¹Ës÷<º' ¤íH+UÚfoó☪qUE7øjDÿíý…†¬³ò^Ϋ›Y—»"·ó4º*zÊ=Sôn}ˆP/—£^ý:¦™*M}rjñ-Å–VKî¹É5ɲQŽäÅtÆŽªVùaˆvª™^sâªcŸëœçÜÿäþüçó#sðÈwG AƒÛ DÄt^;Ñ­žR%å ×Õçõá©KO5ŽiDeö‹³­«Ùl¶Z­Á`P`l§mg&üÊ‚Fà³5¨žØ1f±È+g¥Lý»ÂHk-j¼`mV¤•}ÑÑÑÚ6å¿zfñá|añ„½ ë³NËúVigõ¼h‘_`2ãâ@SSSd¹¦u,ÿ““GGæ NòDãõ¤(¬†hXȬõ ÙÆUÜS£Ì;¡Î«`^ˆyA6ÞÉì¯õ×ÿ] L%.}™Ç˜¯ðy8"�/ݯœö»k¥@Þ&½ïf…qà/<)1[¦@åü 1$Eñ/mðl€((€¿(Œ”'±ò ʆè#wxÝå,\͇0뤑<²‘¶Aú¥+Õ;¿“¶y`œ€ûñÃZ³º9bc›RØ¥ÕÍnBfBŠž~2úo©èáj8Ht9ÃkhJ†ðmÿý�ø Ü`äiW¨Ì¿n&÷ÆsKn«Ä‰4ø‹ÄJ£¾Ç?Ž nÖL‚¦dF*ùGÉn¼—ÂLüfJòhýtãö ÀmxO¨‡þNÀƤ«:Øë¿ÂH$þ\Í㛘þ#º¸ØAc4×F±} ÜáW9 '  ì ‰aŒžQ `6D¹Ùâ hSw@§Œ_a«Šºá'X™*I*+às0Wá]¨ƒ˜«À�wÂHø¶C!Äé¹Q¡ ~’ØuP çÃ#°KåmXcu Uø¦À( Ëe@!,dÁ"ðÀj qwÁ0(„l8V¸ Z!: Óà ˜^8)°¶A dÂ4h‡4X^Àh Ð 6ˆË!�«à{h ‹„0Áo¡1Ü]]P¦B»a&\¢UWee{÷îµ×Ø[F´èú±ŸŒÕöòŠ¢¸“ÝŽÁo¦÷Ø¢cÕã««òªjÆÔÔ¯sf8ãNÅÙZm™û2cTkTôého¬×k÷ÿr¸+Û5ê‹QÉ ×ëUEÕùuú ^–SÕl™àMØghÊ BðMƒV«}) ¥ÿœ^?±^ÈAc0ödìÑ{vÇtçlÎQÌŠÁi0:Z{S’$K»%ùP²ž_Eð¾…½ ð€3Ç©óé4®±Ùl6›Íb˜Ñã~ëÔÙjm>»/{c6 6¬‡×Œìò«!5¦&ð[ý­#ZÓ7¥'JLÛ–æÊr%Nú…Z’ª3 r%ZN)K©ŸTScô°©ÓŽ?íhÉi©_7hß ‚/ šÇ4Ký¥±Î±‰‰‰¢#*j;A�°Ûí¢yÕ7ˆ‹ FӘОY:šIG¤Îˆà*õrÝ<+úã¬Ü†Èöšö Ú#  à ‘®þ#пW½¨){iøM~Iã,÷"м+ÑŽÖÌív»\®@  aî…É–V„‰];ßh4Ž=áÕU#é¥xúÓö˜Žü O\ü)¹FYÏGƒØäO %H¼#‘¨°•oÿÎù`Õ³T¹öÞÐ…Elú;.àD2,ȇî(š;{|umà]ˆ]à„á2ȱíIg1‡ ° ®…t<âg ŸÊXðú‘ýÄ[ß™xçxàè3\™Ç;Û9ÿwGÐý…tä ‰‹T€JØÞ,W—Q«ãâv¾ƒP«áS¡td9áaðÀ°Hwd‰2v[ÊÙÓ ?dƒ bB|Åï¼¼­<Ø^‡D T¢ÁÜNVB&W~Äc7ÂÐî¢_plÂ$øZ81šÎÓÐȨ¼©"qó+,¿Ìp†·¥Ën—ŽÆ©¬jØCÜJ÷çÕ4Þ÷bÃõÀƒ“¨ª–˜+æC0n‚Áffa£‹1 EУa;¤B! €48!1Ba"T ¬1‘#1Ü‹,ð¨bÈ€eö+„@<ÓÁÃÁä ¬‡\™œoBÔÃKp ì€Bh ±1Ä0PÁØ .‡h…V3aƒÌp•r•á�|³ .l_ì‚i à ú……Þõô™sÀ 0 àNd€ÙadJ:1\PC`6l Ê r!5¬cÒƒáYÈ„v¨`´@)ô7dF~‘ÌæhG´^¯ïÔ_† c U^RÙ4¤)de82®úìª'ÔÙÙ)œëZRZJ¯*øêDm•~$=ýHúæÇ7__|é­—þN/<Ϲlýä?•_sqWç „@úúô¬½Y;$§$Ât/r&X "µhUõÚíCÛ›ó›u^Ý •ƒziE~ì•v{¥Ýð‰Á†Æ¼1 ^›×oôgþܳÎk h Æ¶Æ å¤˜²˜ÞwÒ®wë£k{ œZ†µè}úH”¿s€SöÉOèt:ç$ç±¹ÇrNä\X~arf²Édjkkëîîv8½Ro¯Ð`2¢·éõzµ~—@ckI7²ºê+ë'~©á {­L_p¤2E_ˆ¼�nô O#4ÿ7uaL¥‰»[­ÖÿXžõº‘!’Y$Ç\(ùŠDÞ«; ×ZÞ7QVo =øúô:2‡ðè^JQ_À]·ðõX ñI*²$Ð̯Vð€ŸûoùF‡¨…p²aÛ ~ M0Ka;Ì á‡�4C9¸C,ƒ12—© Ö1)ÈÃP ÁzN ¯ñ4–ú°´ñW•ÍPª Ý €ª.RñÃ?(»š{gðÖÞSÿÐâàÍoªßü ptÂø0¨L¯2ráø |ïA¿°Rø,XaÕÁu'•2s+{òà"ˆ†ç!q :è„Q‚h¥ãV;Á66C+Üb0‚‹›OQàèæÞ5pô1þ12Y¸‹ŽJraŸ*èÏϯ¦n)}ÆÊëø~r¶Q9}×ÇÒ WÁÈ7e‰Ü»˜ßä£6Éó¼ë9 ]!ŸÙCVˆ"¨‰æÿ|æå/ð7�- -*wÁãPe§ÀÍ¢�-Ð Ã KÏåA `\MpŠTF©¼å @©L ä+ †¿Áù Á8Ø3`g¸=x¾Žá!|Ðê±™¿ ÞØnX�!™LX¯°ìÐN->‰›eêBTÂ�x:À‹àPØ{Ø×€ VÃxhN( û`m‡'áh‡´A?耎Á|¨†Û`(ÐG` l‚%ð,\ÉP› ’À hø`:4@äËd¨lS™~ȇUà†nØõ‹X™Ýޚךv:m云¥3K+gTÛ5¬øÒâîÔîa-Ã’N&Ù‹í©Ý©A]Ðçó PÀâ°ÄVÆÖŒ©IÞ›¬M D�õÙ¨H¿¨H­ÒÿÖæõ×?dHŠTú›R£ÕèÈsdvdšÚLç~‰¶?kXtŒvDWGŸZ|jðªÁ½T4rOß~¤\“”&ÕN«p|€@©Y[¬–‹c¸#údtȪ¹¤&s×™CGNGÓø¦1ä‹õ{uœN§kЪÑG[£õ²^ô!l` ÿö°$I - ¶N[¿Ô~©©©ýû÷5ŸÁ`¨¬¬ì¾{­¶†‹Ó8¿B ö¿ è½ÌôŸV‘÷õ*ë¥jßkÍ…V¡– Å'§×(K›riž^}ITpØ×ì*’§Õv½„9Ϊ¿þïŠÅ¾le±û9wºÊP‰ íÿ½Ú1Iýn5u3øÛ"NOÐ;¹á[x(D¬QðÄOðê!Ø­R—¨¤ÂPý¾›‚·}Gíq(„«ešô<d‹Ž~Ý< ¿‡4è2pO€&øZå{•;Cøà(ü²a7¼ “;)PÈ„v…Û¸8ŸŒþYÇàÿøTÆÞÂ:Pa %+¸q0‰?…þ²‚tÌVù£ÂhxÕq¾J“ŽÔ Ïêø{ˆÍ°tp/lÐ1]á*•×Âûeørchñ·îÆ.~ÛÍ´µl.ÀÜá…zPbˆŒ'„+léâxŠa‘[7+¸ÇÈê§©¦ïÓaø¹k)oöÑçS<6ÀïeºÕtê‡Ip±§†+ßæ™ÕÍrHmmd·[ƨÿ€%żUOâ˪/Y9ö­—”D†HŒqs vx(Wh‚×Ã�t§‹Çà!(ƒh7¾ã%þ¡ãÖ » 1Äãp'|ÙÐ wÀ@?ÃNÕz~ŠPKRðÁ4øvÁV™Ù¥!6ÂÏ Ã@Ô†Ë àCX «UêT®†*h†ÃzH5*¿S| ^% ?öÂÈ€-PIp%¨°�^‚8h„ŸàøŽCøõ¼äcx*` œê±a£H�ùàn¸T˜ + ôðqXÆ¢œ ‡Nˆƒó êa4ì‡m*ûT.‡M`†Xx™ß÷þ"Í´}`5Zóä8ïÄÏþpÑá‹ò:óÒé.—«+ªËáuˆ¯å?$—Áâ°´g´Çúc#õÑǽ7ÎÚlív÷•ðÑ’„ÆíÕY­6ƒíí"ûÚ7þ/ã#u´‹Æì­Ù)u)­£[í5v{ýÿ'ù9F9BÆPÒ¡¤˜Ê˜Cšô÷I½PÚbÎß^uð¼/ÏÓ’€ô½é¥óK;‡tV,®È{3ïL°Nðxì@æÎÌœµ9[`ëË[%IòÅû¦6=JRg\µ²~Ί©1è )¾”(oÔØ±ccbSRRdY®¯¯×”XÅdE¬¤è†õh?Z­ðíp8"ý/þ«Êã(zþÛšFË£Z×KãøÓ7EêeD¶"EçPÃpj7íK—î[)j… Px;’HÇѳ¦«$• °’S—0+uÁïàÎ {`²Ž­2ËiíjL¥‰�?<ÈyÓYñ°z «õ<bs°k0]Ga®»%RxÙÏcƒ${"U•`ƒwtÀ`Ri‡:�OÀ!=χxDe!<çæQø#Ù_ñ½u…Ôé¹®/ÿH ¹­GÞð#*ç[¸ÏÊ=Žê.CõÌÀ‰àÞÕð”Áp]ˆ8¸J¡f†x¦è™¢Jå.b7ü¾‡vø4°¯µ•LîæcÚÞC£a Ì×q™ÊË v•`¹Ì• µ*+¼£ôL !×Ï:Àˉ¼qmFy–B)|opê·ŒöSÖÅiƒÁµn p ”pœÄ&&èñ¼Â¡SîàŸ»¿®æÊ·UR%¾†£ôà‰ë©žOµ U ƒä6‘¬ÒƒÁä|h„,¨‚“`û#›áž�›`–ÄsAæI\¤rLe>¼¦(샷ÀÍ53»°«¼ä{Ø ‹á5¸mp;W(ƒzȃ¥*ÿ §Ñw?ì‚ œà‡v¬²ž‚›àM°WÀBø£Š[al„Ïa | DË<.Q"ªà~h‚Ÿ!‚Wàm˜6žÏKA ÒÖFŠ›`?ëSØáA�vB4A%¤À7p)Œƒ·`&|qµ@=$ÀV Uêà]°ÀBz…0Õ³¿À˜¹MQ]QÈèt:CÈ0ö籞¼0)>)59Ug× 4`gggMcMG|‡")F§Ql?3vfx/õvŒéˆ.Ö®Ý}ÖˆH!IïÖ÷B÷ ‘œ› 9X~IyÍÔšñ/ß÷Ô¾ÑoŒ6·™5q½K/%P°—Ûc*c�›Å¦‹é!Ó³%-r‰Ÿ…zïY-”\ .}§^î”-–±G÷]z±}}:ÎtØ¢ý%ו´h[òÒ‚•3^$§A5¨Ýýº“U¥½ÜâN>œ<tÅPY•iæ²ç.kÓ`Ì1Žo“£(JuuµÀÐK!I=ÍA·ÁÝØØØÝÝ-Jššš®®.—Ë¥¡+#Õèm6›ÑhŒŽŽÌ_áO&âõÛ(Ó‚5aÏâ¾C&Ýÿ娵UÓ(ùšI¶S@½Àç†áüoXùH†Ù¯˜õ²2Ù[5±ÔÂe=CuÅ„b+¬@Þ¨´ñÑÜWŸ`Á;„n :ƒº-L¨¿ñÂã0OB§R®r ˜à�Ô(XÒE´ë˜ Ïpx•´K•ê¬2yT)¬2t SÉÌ·3"ÄÇ!NÁDñØq„ÜelL`Ï¥\r”¬hŽÚànF«LÝÁóEÁPº‡cÐ’@GqƒYÂ$õhõön#¼i sºáL·Êf¸ >ðÂ`n¯¡°(³0¿t—Q=Aê®·â pc -*¡#á]•6•.x·|ˆUØ[ybO?Á·;Q;!Ef²J5\Í´½Œ•É0à:Fý~¥©IñÄ’ö1w}ÍêyÔÁ þˆ2ÏQf¨TB½Ä•à‡=Ð ` ”Á}°Þ'ÄÂ^0Â4è†Á 0Á>Èœ*=Y*…U6CÜžcuA1¤ú™åã³UžƒtpB3$Á'P ÿ„f8�a&Èàƒ·á"è˜)ñ&¬‚;`i˜ öÌ€‘ ûÀ#a>ì…=p1¼à@xþ”�°ŸÊ7€D<[`?´ÂJøfA 4B))äcp6ÀTPa4Ä…qñ0 ®…ã ±Ð' ž}alz"T@ “¡öhÝ&Aì€$È… „D(¨ @74DJÜ666;vL4”L&SB|Bfzæ„ñÒÓÓSRRÄ úH‘“É'Ëg•{Ó¼¡Ø­Ó¦”Æ ñ'âã+â#aÖA*rî-IRåüÊæüæ„“ ú¾/¥¦—Û¬šÆ6¹R\ùÎ7vJ*®¨°¶XNcH 5Mi²6Y…aÏÞY•$U^|"®EÒhzÙ'žµ°ðÙ|ÓÓv¦;€©ËdwØ#å|Än]‰8D`C æqÍ’*å½—g|>Ÿ¿¹Ýn_”¯q|£/Ú×1¼#}gº£D9¢dYnÝÖ0¥!÷íÜ€¯§Ü‰2G%9’2ê3Œ£À tuu (fdàƒ"²{½^‡Ãáv»=H¨B3I,~BBB^^^FFFVV–Àày½^!;t5ÛH »F—îEpÖŠf ”¡­j¯…¤.ÑœÔTöÏšDkÑb±Øíö˜˜ñAø '’™@‹œ5£ˆGÕJ¨È¡]dR‰ä¼‹5sGzˆ|©©­•Íf›0yÚ9T-ºá3Hb¨}Xî:…¸éþ×^tÏÚ ?ÿHfñG ¶1£‹ëIðJ;†È”JŒ48IÎgò$#e~yº£iôñŽÊI(æq¿´³ŸT’ §%&¨B©Œ]"&D $©àá¥Ý0×ÂG6ÆyÙÉD±? üœÃL¹_€·×øk£¼£¡ÅÍVžø€ Se].•uÐ¥P &¨x(†¹Ìù’Ž*™Á*.ј`7{dþUÖ.yñ¤ðæIN#•ö‹"ÙK²Ó!d�ÛÂü¡©P,qHf€*’ýž“\[…ÒBõdQ•þP¬N¯`úv²b*àë-®~ú)ÉÁI›mÃZIÿÑ,7ÃXuÐÆÁ8Ãe‚P £IÅiàTÂjÄÀVX;áÿà<ø΃4(„Lø¢ BЬ°ÊT’!²àSp€Æ€QÇ…*^ð©=jOͰ(¬´t.ƒý0@”ÂØ®c¶ŒYÅ"3\plPýÃ6Qq Ãpè?”‚ 1Í`Œ�Üm°|Ð ™¸ð4ø`0¤Ài¨…¥`ƒ+áŸ`€|H�&aÔAÄÃ0PÇ•€êX¢Rõ q0 ßÁL™á*À!a4ÀyÐFèæ¡€é`ŠLWÅooÚçŒËb±DGG§§§‹í³×ëݽåã >¶VXÇ,C€ö!ímCÛÚ†¶ùí~c‡ÑÒbQ[|½+§UÚ[ìFéŒo–hëµlseºÒަƇòê›®$¤®Ì.C—ÁÔa2¸ æ6sýÔzs»¹vfí©%§Ž%D7Dk£}h{õìêÖQ­ii’Ú3爴8 …BŠ^©›]_ví ·¤êÕÒ›Kí§ìMç5U\[1pÃÀs;_Dä£k£½ñÞÆ‰‰Å‰Š¢4jªšVÕ2¢¥}h»ßîO92àÛ­ãZ]®ÖÜV½[ôÖ£^› ztƒÄ2jJ"ší–¢(Þ¢9\&¬økGGGss³Ëåë,àš3ˆÍfëׯŸv¯©© ¢è‹#Ps¢1«åBM�"21÷-(Ï`5#lYúR¦DÃV³ô=GºÒ"f³Y¨ùiЇ7ýqŽt%8RÚ™}ùݚκ Ɖ%=«v†ø÷z~‘/Å–$Iÿ1]ÁvF›à\i|þ5ÙMÜ1—c^•ËØ¶Šg1œdõ ýÚ'&ÅQh¦ÜC;|ù Q^ÖÕÃ5ðw_ˆ‘2Ù°˜¢ïY“ ’£ò¥Êv8 ]0\f²Bœ†~³Gßy¡Ò¦Óá’yÒÊ#üs5o•Ëdéùz0q-œНl¼?ŠŽ&‰+uœRéæÅí”4ÐèPLJ¸o%‹òe,µB–‘/1§’«êÔïL`„jvX)3Tb®zj¿/äd9©å,ŸOw³/tÃùáTœ'aÜ$1°öàzˆŠ«XX˽?JWèô[’¢›x›w±*—÷ÀÃrMÙ6S‘ö`ÜÁyƒX>—¬†ŸÁ0(“Ì`SùH¢V唇««Q ƒb˜ÕZbYèa¬§ÇH^ÝaÄö`È„xøÁ °B… ÐÃ�ø¦KLRùtÁtȃP¡c0ì„Q𴃙ëú--x\¥He9Ô„Y·5€ãÐ çÃhõpR`.ì†,°@)Œƒ9p�tð €ÐkU! âÃg ¤RH‚Åp’a …A#áC˜…pš º  NHtª=S®‰+T2îö‡@�5Ë! ŠUÖÁu° Z!.¸/lÄ%˜ýÁÇàQA"ŒLWû¢÷íñìá!lpÅ×8--MìßwÚw¾2à•Q;Fe¯ÌVÕÜlN<–¨êUk«µÿæþ–fKä^»jFÕÑŽß9Üà7h’“§)í`š¹Ý|P²­œ˜"éX’¼Œ]ƶam!](æt `ê4™œ¦ÓsO'´%ôßÚ?n_œØh˲ܑÕÑ2­%¹>ÙÐn8¾àxÕ¤ª AK™E@Ìf³ˆz%w–ƲEez¯>ª.ª/ºÌä3uëÔwé«®¬þÞpk£Uã,k±I¨UõÕ­˯ø‹o,®™\’Cö»¾Mo«±emÎ2;Ì@\Iœ½Þ®•æ±ÍIG“âNÅ¡œºˆŠPÜÂãñˆöÛíîK˘7Çãt:E2…ˆŠÓ`l:ÎívƒÁîîîÎÎNAq ¢h3›Íš'ˆVÀi5± EBz•)½äšzqé"ÏI ÿý fB¸‚Ï Þ…Ð-ÐMz~�� �IDATÂ*añkª+¡¥•û„í©ÄdQ\$²QüïÆuš‹M$Ùãñˆþšt zx²×ü¬øšçn±~øˆ­|d€|'äáœBÉytoQYQùð(ú¾x{6ƒŒ(õx†Ê%NQå•T!¾ù0×Èül]8! ÒÿãÆx¡L½ö8ï”)Á—ý8“Iði蔃¥élÒ+$¨ÊŸ9VDa ûàí²U§ðÇmì¾›oK8¾œ£ýÙ}1÷æ"•/®"#‘ráßâý[¥R >!6‘OÀF(ÉЩ2ŠmœZÌܾ‡–´°Ö‘.€íðUxV¿Š`”Ax¡nÅy”âoØ5Oýi‰²ó¯Á’cJI]ªë.>•þ!) ¢j$Çs)j¢<Þ„™ð5Â\¸ Òá7*••«²Òa|Çá�Œ„uµzžòò¢Òƒ&xVÁRA ·@\‹`Ü õp!ülà…87OåMxNAüÛá�\¤2ÖÂu‚+ FÁ…ÃUVª|{à4\ %Â¥ ¦Â (‚a°®‚#ÞUXSÂTâ÷ ªa|»Áí0VA=~žßÂaȦÂah…P‡ ÆÃ?¡vÀÝå° @=¸ I¥*ìi¥ò%”€%¬Õ[] ø¡J` aPÛÓ°8 GÂBM# :á-]yK½k»×šMæOŠhj‰¸ãt:÷±o­²vîæ¹ÉEÉŠ·‡ã©ÓéôÕzSI|É{,ÕL®ñD{Æ5~ÿmûsvåhÕ•Pv0u™t.ݹF:uç3;ëóëII8ž ý)¦&¦úÂj[ÍØe+ætLJUнÕ.‚²ªªÞXïñ%ÇG~52¥:%±%±_[?½¬?°à@|S|B[‚`σÁ ÁS7óÏ1ñåñ ŽÜq$c{F$^\¯×|†”’”ÚYµý¾î—X”h0„@\$”Y3I°ºÈ¸ Mu&[¹-ñpbRIRlylÔé(K“EƒiX,W]m?m;'\5Õ3bö¡È(n·û¬&ôz.J%­‘¥u;Åʈ‚@hUH’$L­€è ¹pêÒŒá5´›È”ÿqP9UÒb}¯t¥ák ƒÈ}A}‘ê´šã”X õ'êã@øp»Ý¢$ÒZy"£hÊ„Ze&�ZŽÔ.¨I&j3¹ÿ˜®zÍ®„æÖ¯IW•p=¬€G`?¬"9¡ÃX>†Ú¶P×~?~…Ã*vH…‰°ÃÀó :…á ÓyãYÞª§hý!5ž€ÏÐ4YQmUÚ@/QoÀ °†x¾‹÷ æÁˆfæß¹`"ŽbÌêê­¦S¶öiÚB#ÖÐuî³2 »á9‚›qýL°A¯`ÀÀò¶YAZÀ±4Îשè<]ŠC2¼ù{åèg´ €ïa¤3êOÌYÄÛ³i(ÎHLí:ùV‡´+E¢Dv¼K©ø‰5·â±Á70 .¼åÐe°ôC¼,á€Vˆƒç!]çž'9²Ô¶{ Eá[èèæS•å.ï«|” téá°hZxCa ì’ˆU° ê%n†a!$Kì6p5Ü¡ROÂez¦ªÜâ^…P ‹aø ?÷ð¡ÄÄH'œÙzRáâ÷Á ïCÀP 7ø½Â?Á'‘ ŸBœmðN>±áÑÑùв ?ÜLÞÁz¨ d@³‚Ša?¼ ýa(T¤ç…~P Ï$ø¸üá™\.| ›À¿ ŽÃ•aÆ`X60?œ·ôaxȰ  ÖB,ÈP.h„MÐ×ÃN8 ‡a ,€àì…cÙ0 a1B;T@lƒ2xjéªÅÝU•'ç%%%ÅÆÆŠívsss‘Räiñ )¢4+w@hÁ‰½¿¦ §mÝÜÙ?fÇ:ck j£›¢CRÈè1FêŠöйj¨í…w?»{ÚÓ2evì´ùlÖ Õ€¡K×åJveì͈êˆr:âî6Õ¦—{èPîx·ª¨‡~s(çË}Hoò™ìv{L0&¹&9gwŽÍa3)&‘®E)¹½$ëû¬Ø¦XÄ÷${’&ëüº^j­† !ëHV\{œ@3‹p/b“¶CQ¾/Ö@¼£Óhê6ƒÆÈ€.²Ž!Ó{õš&}¯B$rÅDìî›®D3J¤Mñ(À-Еâ¾n·Ûáp´¶¶ºÝnŸÏçt:Å ¢&..’±¢(N§Süˆe  —NÄYÓÕ9`Ú$I$ξ=7mB©“« 0Fâb"¹ºÚFÒìz•t‘Ï™µÄ#."Ú•â&’™¦+¯ÝNûÄŠ%é\dP³Ù<yÚ…ÿ6]y=é2 Uê`\AÚaþfbÉgòF«Ú¾ –© ÓdkƒHT¨4)Xà •5N~<É[FŠFüÄGË•I*ΕùYâg—žWmŒôcáb¨˜àFÌ÷pé,N99:ˆÕqü%'p÷Iï¾*†tñÍQ³ù§Œ4ûл`48•ÛêÚ^ù€ÏÇÇÕÏHq!KÞeF9ÙßxZ™·•9uüt(`†Mróýªg<W®bÀj×Â.5ØÄK·è¸Sf µðc€S æOCÔC$C"èÍÜÅ ) Ùp­ŽKU>€™K$RU²¡ ö«cW«†C8«A©a}¦6hVQe†@<[%ÆKÌ‚x…¿B.œÖq L†-à—i‡zX/‘%±ÐƤ+fÂ60(4B5L‡“0a&8ÃòáÕp̃ØD0A®ÂAxJ¡P7¯¿R*Þ…Œð!<]0+ ƒþФc,œ²1ÐO1L„pËðœ†+á]¸òA6X-óJ;ÄÂ>è‚ëatÂTx²ÂÛíÐK Fáh‡a C|ް¤lÔBT€2`4ÐÃñ: “a(Càs¨ƒ©à¸D(ƒq°Rà4‚ÎW™ùP�n8 c¡N@'̆u0Z`ÔÂVÈ‚0*"‚Ã8H‰Zº:¦?v"tb`h`TT”¦½]˜Tøþ¥ï[<–ÌÓ™G°JµÍ¦t´ÞˆµËêIðtìL©LÉ*ÎÚwË¾Ú µ e ÂRäßa‚µ­nǬ?î@œ¹Þ¬×ë÷ܹ'` ÄŸŽ?zÕÑŠ+*K-m¯×«…qͮԮwèJëùéÈŠ%žL;ÁíÌqæ[òÕtµbFEVtV¢7Q„<ƒÁu,ëôœÓ®XWëÈÖÆñC¿åèQÐ0™L¢aI!‘N˜í ïEÚÉka4Òx©ibSLCŒØàGZèjÀ¹âÚô*›z%û^Dݾ¹DK{¢’£ `0ØÓÙ‘Ðat{åmf Rd['’ÿmº嵸 h5÷Eœ‹[‹ZJ“:ŒLlg©k ¼Ú[ˆ_ [‘„úæÎ×HìOýgŠÃf³+]y<F‰Ý*u cKä­ÕdZ¹Û.xN¥Kâ„Ä�…cð£…E^>S)oØÀéb8  0ögfS¤£¾‘¬DiHˆ¢8…ã#ÑÏÃW0²áC‰›eƪì�ˆßÀãA~wì‰ãjߦiÛÉ-¤Ÿ‰Ÿ³yîÒ ­~,Хâ2S"Af€ºô± ]c^ȲDVW1mG úGn)—%ñôæ C!è Yâêéú Ê•ÿÔŸ­WÊd+¸þ%‘káóO8@™\ ê*=Xa/Œ…#%ÊÒ-Ê5éÌV™½›ÙëÕÙ5l³ºN%¤2>‡¡àã¾BnØÏÆ ðx`Èp®¯@'1êá�(2cÁõP±0Xe(„àLU{ sá:•O|lV@Ç%*›Àµ° œ0š¡ÒÁ IpqØ©ÝQ.ªTâBüºÅ]”•ÿÂÚÌîQ°KÇPl‚&pÂ.A8¬ÒÒ-ÌôqF€áø“ÌlFÈ »9GâB•BðÁ¥P¬cŽJ%¬€z˜A¨ Ôú`4‘0~#4CÌ…™l(ƒ•°Ò!Úá‚ aÅŠ0†Â$Øè†D˜ —‡5–¼ A)äÀ(ˆ‡“`�\�ð)œ YB5¨`‚r¨€ÁP …02àHøÌ™aýT-]Y–¸–¸¸¸¸ØØØ¨¨(ƒÁ°/mß>˜zpê{/btb ª MB (=. !¹sP§¡É`í´&•$… ¡¶m¶&›Ékê…ÅŠtÏ¡ìʲÔý©–*K(²4X¢ë£=FOó˜fƒÃ½>;¶$V˜0‰$Fè®DWå•¶j[õ´êì-Ù÷ 4ûÌî·)ÞT;¾öðÈéæÔ‹ê.jkks qÓÔ©uCëb«b7Øä4i)Ç`0”_RS#)R$ÐQSpPÅ“ä)¿¶Ü1ÎáçhÌklÌmôëüQµQš:ƒàAÆ/î´´[¢*¢\.—F8Ӳ𖴠þYí µÑˆ˜ö‹w­ “"G8ÚX%¿'ò“Ïçs…îînvoÙrhѡ؊Xs‡Y ßQQQ¢{Ö+]‰Þš(Oû†é_“®þc¯ßh€ ì¥êÛë%ZQ(’¶#‘½äz5{MÍ6Ny¦è^ŠjXùhÜÁs§+}Å}§Êw:ú)Ëê弓ÅéQœÐ)¼³U6«×<ÊÍ^hî¬êä®Ià8| žX.ò²ÊûåQ>æ:2”ãUKzËêºÃ,«eëMjO„˜RœøƒL‹B È,³óøý°6x¹Kí|Ž¿ºˆçFÜàNI2·‡8Õ£Þµ–Ð7©¯¬j=ßü`ëšY'ó*2Ò€ëCƒß`SÜ6%2¸ƒ¢ …{u[îP¶¬ ñŽÄU*fØ (©Çº>^N,Ü6‹­ïëy.ÈZر0ÞcÎx÷ï0ÁÁ=¿§#š ¾à6îÀå`ƒ œ`zÞ!¤ù±ßM[)\% À§ð*PzDtTh…nȇŠƒ/ÀÛà.8 /Á“PÕ2#a’Âa•8™P î‘°B—@ð‚œ0²@¯²dÈ„=<ÖÀ²ù<ö +„[¾…|˜+…ô-¸ás˜�ÝÉ«P#a€LøXÅn˜›¡�ŽÀD˜©ð ‚-ð\¡°:Œ§ØzÈ…÷Á‹áC8"øn†0 >§á[hSÉ€[a,,?Œ…]ðÔÁù0Š fÀ0„Ù¾-0 蛯…Ë¡ž†×À�[àQx æÁ&Xxƃ9°vÁP¸úÃà„$xÖÁçß›*xîïÕVеÛíf³ù¤|òaýùŽÜ[÷ÞšU–iɱåþ-ŠA‘diè7Cí…v ^%"…ÛíŽ9S=«º=¦=¶5ÖÜlúýÐάÎâÅÅ’$Mz{R$Ò½×W½y\³¹Ãl¯´kÑ6á`BÂÁ„¶ámñ%ñg:lF£èCƒAŨ[xløÃcjbšÆ6--šöÊ´ÄÓ‰ýúõ‹J2x CtCŒ©Æ††Y–E#1 JA©ÿWý?~±‹}¤²ËÊJ—´ä´LxuÂYcî‘tgv›½æÁ?ŽÁOJaJä™…wŽø|DÃø†´ŸÒþ7J‹55©H‡ªHF­Èjv¿}MÓú…º•ÝS=¼:ª&Ê•åJ¨N�ÑÛm1›Í¦õÓ´ ŠöWdçS<@ä¼-çý¿â ÉZížõÕðY§M½D."³¦Öüyñ¬¯ïNsÕê5>Ô e³Ù,Úƒ½DúRª¸öÓг*.æÕ÷i8 O€%Ç3ÞT6·²r·Õ¸?ph畇 U`‚ŸœìQq#8ÜB…kñ<È?çÛxû˜îSƤà߈« ZᯠÇ6CþÌ0=e.¬*îk<dÁðzxH¨÷ʼ AnW9 £ÕóÜgÜöt«ÕÚûgf=G},4C‹™sŨ¶Š»á°Eñ™øvV(Ü_Ã÷!Véy.ÄP•OàaЧ¾š«o¡n>$‡xnÓ1RåO w%Ë_çå;¹íJByÂùð/»øðynÙKÀHØŽ²„Ž8-PÂöö0^d°Á›ðxnvxÊTK$„è Ûdü6x ŠáI£Ä:˜¯°ªu˜UnSØïÂð5!NÁ�ÜC Ú…ŸÂ»“È[ËŽt< ,Tñ€®QÖ‚oÁ} ¢àÏPQ° ^ƒ•𾊠‚ðLƒ£Ð&Ãp<A!ÌPyt FȃA48áÁß! ô`¬ð´Â4•ùà„ï`� ‡e0²à…°ÄŸzz|ð\χö:è7A¼�? p¼n‰u<äwà†«!òás8¾B%¼ !èÜ›`78cæ$Ô1’#EÙµ]ê¥q—¦)i˪—y=m mnÉÐÀËwäÂ/4 3+öݹOöÊS?(›]V3½F»HÀHÚqF¼Õ^cýÉho²÷‡¿þ¾-=ûûlƒÛ`Ò›zÍ|1>9 Kª¤H ±Nä*ÃI1 z<EQö=½O‰U,íŨL|o¢¦E›œœlµZÇ··ú¬ñññ-–¡’.Pggmš‰Çp%»Æ¾56áX‚üx<žÈêªèþ¢Ö1­S~;Å0˜=gÀö#öc73ušìåvmèÒ‘Õ‘¶9a�‚©{ôë¾q_¯×ÇÄÄüz¬³«-êüÎDçè7G[É©‰ÉÇêÅZ‹ÌF½´—4<‚@ÞGZ@õM<âZè-/z<Q3ië&rC/%ܾ=Õ¾‚„ghÿÿ?"½5,å¹ÓU"Qyc½´f·Ê$(„káözž5Ömô?òg5H 4W“‚ap'èÁáLÁ Ñ ƒzpI”©ü ‘¥z©³èî[©D¿¤®ÞÆ‘øj†þØ£Šc›Â‡°¾„¥\z[oäd ÷ͤñKÌŸRð78ɉ4ƒón”C.çëd\ÇoWß}Iÿèï‚Ñ_ðúLxžvs£Øa‰ÄdXÁ ‰ ÃƒÜ 7ƒAO Tiãô*– fF²ôÞr•€Êø]ˆkà‰FÕðßgþÒOasˆÓ€›áGðêW㟨†§À˪.îØÕ!y£’ÜÈpXž¸\E:æ(TÁÛ*Ø »`)¬T˜…ÿ“øAe;L„2¸>�æÉC) «]wÃà6‰ñ`‡{! –èâE•½³`šÚÃdº¾w)%*,æ„ÄúW¥•³Ô›SÁ ñ°ÊKpjàN"ñ¥J=Ùlø®†N‰›ôؼ 7À¿Àu0j`=| V؃ ,pLxøºà0î‚ ðˆ!ü€‡tÜ¥P¬R#a \Í𠌂#ðñMÖž#¸ ja5L‚‡!0–C4ÄCô‡°Ã`8¨âr¿Ä`hTùfÂ{�\_ƒ§Ã’{ �ë`=�×ÃòðÝ߇D¸¶×^Þçóù|¾.µk]÷ºZwmÀ½Š›²aJÙ 2Oœ'¾<>ÿÇüܯs}>ß–g¶�C·Í:_UÕîîî3¡!"Œ˜œ&]›nÜ㊗·ä¶dÿ×W§É²ùýþ¬­Y—Ul|gcÞ²¼Äý‰@wz·/Χ èâNÅiþI‘vùÏçïûÓ¾õÏ®O?š´Ç}2®ÇeÃãioo¯¬¬´Z­ÝÝÝgu%Ö"~¤oÞyEK‹R÷§ö³õ4£“di³èt:5"£ê¼:E¯¨ú_ÜeÊ#Sv-Û•X”)R×K¤ç?:9I’ÔÕÕõ‹©W:R;¢Ê{À÷QQQÚško­Í¨uºúÂd¿ìIôì|qgÁÛæb³.|œÃ?åH´¿F{B[ç^“9m¢‰·×&¿g}‰è‹^«8A®u˜V‰ŠÆr$‘K£¬iKÚ‘j‘ oéëFÖwvUŸÇ1Òíý“Êvp€Z£Y`·b´póNšc(þæA ÄCl¦G(¨@æ ÊZèHÓ‘§2Næ•bØ¥RÌj;Ësi‘¸þGeàqyô µ_J‚=©Þ¶ä2 o"÷{&˜Vƨodå¸Ïv¸®£Ðcá ûư|‰ë5¯ gÅoa¬‚ƒ„•:®P —@.|óá'ÐC ø ÓŒNfehxŽš1ÊÖûà4(‚sª£N5¼ÍPKT«]ij a ‰áy¨Ä˜ó=Ÿ BÊ …CV–ßD÷“.¦É#öJi4͇}°¦I¹V®ò$ÁP F¨‚Lø^‡¢òX l0 ZÉ«²,Ù®Žú¬Ýw€\e¹?ðÏÌl¯Ùl*)¤‘„@h¡%HQDš Š ˆzñ^+W± T¤( $ôN $HHÒ³Éf³½ÍœßïžãÜIˆxïïü•ÌΜ9mžç}žç[Öxý‚ÊÜÄndT³‰¡ôã9o±6퀔¦Èp6SÃÑŒc 'PÎ&Ïí&µ(sé'#/§œ11¥42—=B—2cx¤…3Ø—.Šx9‡e}SŸ5TŽOr=,ŽÁ=¬çcŒ¤ž É<2ú&v›ùïq?d»r?÷PO&êãªïÊXúÅ’ð³^Z9Ž Ö3޽ù3‡1Õ<Ê$Z¨b/ãÆ’£CXÁ¶qPÊþi? "r'EÔ²)9D_Ûy[9€0ŽˆWãÑz8ˆƒò‘›7o^µjîxßÉkNÞ´iÓ¶mÛB«¤¦¦¦¤¤¤­­­%ÓòÆIoìóâ>!vOxyÂsö²iHh' ý:JTl®ñäˆa³‡m<xcÓ„¦¶!m[Çm-m)-i+ ¿ùþËúu5oêÚ¹m¶­{lmÛÔ2¢%Sœ©ÙX“øHõi/¥sé]ŸÞµßò~-£[öz|¯ªmUÉ"7¬Ä;ã­±±±£££µµ5)ò[‘é¼m—ù»EEùž `¯«¼«}x{ýòúäÅd}½á€ ý–÷+ÛòO˜F*•ñäˆúwú°øë_W½ªú#Då§–�¿ ³œ\.·ò¨•ëÆ¯+ê-ªØ\’S"öš¯å®C° Ld8òKEEõ‹êû/é?ôÍ¡¡õkÁ28A—äS†u‰Pî„+Vù ¾©‘€ ’’+ÿ:'ÃË�¦ä|°x~á•�#ÃG‚¦Tào$ã|§Ç„b‘_Ìm?<K@Ië/мÂõ t쎎Ž|Ò[òUUU…Ò*Ô¦ÕÕÕûxèN ‘}_K—ÍÂb©gU©Cº¬µi¼yÇ:êïNÔòcÓú‘áj†PÇ´”Q‘#SdŒÌº,24Ò/Hçñ*#­k0ë 5ÅQí&W;÷aX±h€É[¦¤g¥‡0ÍÖW\YkÖ _^áÍãljæ!ª‚Ïz±åUÎè 2ÞOn3çç¬`$Gp.ïòiªÄ4ÞäYf²Ýx‰ úqx¿õ*&P¯²Ìެç&¤¥-Ž ˆüVÓtc6tŸsXH-){3„«Õ•¥fnLßó‰ÈÞÓ@Ä“ìÂë©ÑQꦭNÊyé][BМ”²-eyÖ-|ŽJ–p"ËÆ>¼ù;ûò%¦³š½yÔó‹.ή;1:ýoEÏNïqsÔ7šj/ó±R›+ÐãºÈ'##"ð Çq ã¯ts!‹¨ðÂܨï"éamä82lf~äª)a0«¹ª"]¼K?î¢GSEUœÌIÈ?x×y›^ZXÈ6v¡ýèð‡ìF9ÞæÚ(ÊøÇôí}iá§‘Lä,öäaúóqÞ Í¶ 9¯OÃÞÑìÎFÖÆÊ+8…þÁJæ¤ bnμG£8Ž 4ۋɬ£‘ýcŽv0±gãÎOW[¶lYµjUE{ø¸åÇ555µ´´„ÅluuuEMMM— ìlëÜ4rSÿåý[iiiEEEuuuàµ$d—Âÿ§ú/ì?hÕ –-)©M{oڰ߆Áó‡7Ô-««}³¶ytsJjÈëC†?=¼rmå²O/ñ∄șŒÂGÊ7—?´¸¹8‘ÄNâ]€lÞ¼yݺuMMM]]]w¿RN ’- Ùh‹Êw+ßùÆ;㟟ÄÜD:aãëVÔU4V$-µ|§¨•ǯ\xÞÂL:3tùÐD7(XÜ&…×öã“€’o骻»{îWçNºaÒÆƒ7¦r©ŠÍIºZ}ÌêÕ3Wz}PÐ!„R£@s(éø•n+­Z[¨²¬©©8p`yyy@ê'hÆ$:ç‡þ|Q¢üt8Ô4áÍùNQéÿ¹$¡Dð�áÊ 2à ˑ|ŠXþÝ y(Ыì%¤Þ§«|Èö=Û‚*3È[„=ç{wUVVæ§«í›»03r{d*»9¿WGF{«ÖH5ß1ïh߬Öªuo³%r?'ñÙX5çœSx!Ò™52r2Góej8—RÖÒó”Ç:)V}‘É£¸ÀåOµn}1uò´´ýrϽï¹ý‹\×뇜Ï MiMûbÖø²~Û)Ë,–ÐË• æhþÎF:˜ÈýŒgW꘭a%gdÜ”óVd�W2Ž£éb6—Ä#ú±|•šÔ�� �IDATŸD®¢‘ßPË/i.²w¯s¸¯JIä7­7ÜkÈë¾sf¤‡±<Ì‚´ýS~Ÿu[¢A·G-{ûy±5<ÏÕ4ç<Å‹\ÀZŽáV°œA,㜘KôÅœÅUö[àíWÜàotù·Û~°„9ÄŸþ`LcÏ“¯ô^ÞÑëS¹¾YËwb¸æ¡±ÅÔÌ œk¨Ë–sIä&&F²ÌŠ<ÊYÄL®âó±#ð?è_äæ^·f\Y‘3„µ` Ëx ú¬³æñ~Æ~ôðŸáÖø›Ë…<HÇñ£ª|.å¹–¾M7m9¯E¶ð5¾Á[ô²œÿâ]f(oS¬oqpg³Ç9–]8Ž{)㮡•ç8Œõ,OiNûXÖ›¡§¹5ê;°Í,d*ƒâ2ñóÜÊ:C¥NM¬ºTÍdžb)Ø«à‡ÔÙÙ¹jÕª†††®©]Ë—//..îèè4ØÒÒÒà ˜N§‡¿=ü•O¿2þ©ñ ñ3_ž',QËÊÊ>JˆIí¨¨¨²²²££#µ55âÑÈŽÏöì}î'ÏEQ´ëC»}qh&ÊL|nb_¯UDðvÎG %¦õ‰Ø]ooo{{û?¢š›ÃÇÃB>ÑfýßMò·mã¶-¼`áð9ÃkÖÔ$’D[[[¾ û5ì}ÝÞ5jBìwûè¹½È^ÈšáS]]] ¿¸°·ª·º¹º¨£¨exKýâú®®®¦IMïžûnë°Öñ7ŽOv"iüäk™¨…÷‡b¥¢¢¢¦¦¦«««¢¢"ü‡ò‡ù§$SºÐwXdo¿•••p×Âä;s†¼N*?£|˜{èé…HÔ~“24IŸÉ…-^ú°;žT{ùèüä'°ƒ÷oÿ´¸½<ºrO>]üÀy=Ù…ªÛ³ý:\u£Ý׿z?<×»·s>wGšXMi¼ÈËÈa¾¶ÖÓ‘?ñ_üŒ+úÜ=ÁÍÅvëÑD ·»¼§…»½±NÉu˽}yî¡ÛÜãK½Cþì–v~™©Hezúw;7ën «9kº-` pçñÊ�[œÝ¥‹¯r]ÜÇ”d|;²,g3ÛX–õOòY®g6o¥ô\Í8„•œÆÒȱ|‰ýù6g¸½Ë·ÛzO|Ýãòdë)GúR‡/•yû¤¨åJúq<ŸãÝœ¶” ù$ÿmn?yÚ¨r/~6�¹‘áü:ÆÝÝÉq £™4ÒÆ—‹<L=‘¿sÕsþóy_ûœgs7MÔ¹¸Sú½¨çSôï²á\ä¯xÇ(§“rþBEhfíÇl¡‘u, “ÎXUýÓÜ›²wdW^ ½×côËšÏÃL¢_°†`#«HQA#c? *V0º—*Z9¸NªÉRÄgÚ<Ïãs:WÑ/²„". ¨+j9—.*9[ø2/3š§øw1Šƒâ}ŽâSÌb5Ÿ¢’#¹’_°"2;Ûç„r&¿RL'·q!Kc²{©ŒS×EÜÄxF3¿qmÞ§&öùçï¼³³3Š¢¯<ð•Ÿ|ì'ç?|~¦9³mÛ¶ö~ís͹÷à{{èÍårÅ ÅÓ~5­µ³5„þÄ9)A%„yXùær¹3 \ò§5kkŠŠ\vdÓÖ¦•§¬\öûeûürŸ¢TQ*•Z:séú½×G©¨niÝöÓŽ’FY¾—RÒ°JBObЕ|o2ÒØžv˜ï\•ô§~kê«—¾ºï û¦¢Toyï«—¼Z±¾â T’-I€‰G0óÍd2Gýñ¨ç.xnì/ƶt´;ÄíÃ}oooS%6ðeeeåååÉ¡ær¹=ïÞsë^[ŸúÍSÃ_>æñ1áÅþKûOýáÔÞÞÞLG¦@]"_\<áäŸlX=TTTLš4©²²²´´4H4…SèèèÐÿ¤M—_!•——‡@Ÿ_´uww' ù¶± šì-¼˜¯Jõa­¸íPg½€ ¸!öПŽß¾fý—ÈÀtÛþ0§gλ&M6yµÃ7øF¥%%|Œ·h‹ç ó&ƒÙkhdg­u=Óù"ï3ßsPZ §å<Ðc¿áìÝãÇ)¿O›«cj®ãŠhÛwíuªS¹¡•›mh·×h†ôs\³ˆ+I±˜v.`vʸÈ?ø3#À.›ý’ә˽\ÈF^ãj¢‹gËåìkÙã$#›±{¯[i¥š±¬H™ÓJ; h¢RwξàgßׯÁ™ÏD ³W§QÃtNá%Î •2&mz¤.ç÷²¿pç|“¿r¦’WÉñm†3„ Jû^‰±ê¹‰¿ói63–ãØ]o…k‡¸öJ–òq0ÝZöàúœÝXþÜÇ2NâÓ<Ã@å錫r}¶,3‘"Ή+ãoÅc˜Y4QÁmÔf\Ы‹qü–#xœELå:¶P›²'Eq u¼HŽs¹…Z¾ÍgùzüÊk43‚MœI#y3òÇÅÒ39'b_j¦3ƒ ÜÂY,§šçù?âpfÓÆp`[¹3ö½…ˆ3ù ?e‰Èò}F³ Ìaâ}Îäujyì{w]‹çÞΊØ-¤ÙÊeœÌ'ò §[¶l)..®ËÔõF½÷M½ï WÚ\¹yÁÔƒ›ù_nmmíêêjhhÈår=Ñ?;EÉ:7„˜ Äšßf)ÀHz·¶¶ö¦Ncî3î®q ¾µ ªRRŸ0å®)a’ÿñ7¬Gè°%û/0kÿ(ðñü)zøGÈÇååå•ÙÊ’{J–|bI*›Ú6jÛþ?Ú¿¸­8“ɤ3éíÞ?ÃVWÑô«§÷¦zCï´ &}­BBò @EQÑÑÿut!z"›*ê* ¨Ï¢â¢ø#X¶ª€¡cRcAz(Ðeÿ(Îa·ÛgåüB<ü£ è é¹à± i;L’’Ë›Ÿº¸DR~…ë°%ÜüDö“¬É¿†‰×L>*'yzó/cR\~Xºªå“nHËmsöú½è¥W~‡ÇÙ— LˆÉ(¡+²ŽuläXº9‡N§ž2³Sy>§1ÜÏs(oüUäçYCh§Ž·xÚCÇ{hq/ã±Å|jØ•…q”/O9+åÝÈáàLºxÜK?ã ä&^åÕlŸuÈk¡ˆL›™y˜ êÙ³×UYãx;Ô)_à6qÍìFŠÿôÝa¾qUúcß˹,ä:yãéNiO™˜õïñqnc"ciå2Ʊ)ž²EkƒvmÚ%*;­f<¬d*oðG.eižc Ÿá¼Á.ÜÃ1¬g�ñŸd7Þgr°ö`pÖ=ÄfòŸß b Ëù<ûðá)&õº‚KbÿÆÍE·ÅGMÊ~‘FFÑ’‡Ó›Ãp^àáR²)ÿ‘ó2Ïp&·Ð–V’ëPù‰1Ìæ×1Äî J9¦Ø¤ê~ÇžTq:³˜ÈVVƒÀ`:Ø•'™Žæ%jˆ˜Åilâ 0œu1=ðÆVÒÄ+ìÍTçìÆ6vg ‰}† ¼Çd^`ŇÒ²Eg?zö«“^]8iaWªëc÷~¬6SÛ«o¦]QQ‘(¶…ðÔÞÞBOB#Í_ã8¯(L;ÂiÊ/§„Q*•êñÏ )^µ“ÆThîÐÆâÃØ9ÿácNOÁV½¶zøËÃsE¹IžÔÝÝ,PžèAIöÃzŒaÁpùeee;|gP”¨­­ X¢¡·ýÂzتròÎË4áv477‡ëßÑÑÑÖÖL j£*qü»[Ð!ü·š±;a¤%Çæjù #mrÇ·¿bIš ë›(˜¼nPRP&(Áü̼˜ä¼#û1‚ÕæÍTw£kmIhæLb_Þç0¦1žÒXbu.K)£‡ùÃH³–Ù<Æfzy‡leOÐÁtjè‰uÞ>ÇÝAõ\L?FÇSýQT3WŸwû8ÆG~þÀÃÔ°€“XCŠ=bÞÒ1„ýâaJ;Ý–SÍ0ˆGx„ScDÙõ)ß‹úRÝBžÌl SRVf\ùyufÊ‘©´15]e·Œ9½Þec¤‡‹XÆf†0˜:¶0‡2våxÎ,rt®O¦¶ž's^ê2”ºx•1ÌgÖ3…e<Í®|™vf0—]ÙƒûË ºy—±dß»|@†¹•ˆĆCØÆR.bWV2™IÑÆÙìÅ&ò2Yª8”'XhpLŒÜËfV²ûSÅû,b7Jé䓬KõYÝ×é3ìXÆä”ÚÈHféS™:Ÿçi§*žq62™æ‚KéäuÎ`!'“b0[bާQ´sÛxƒ#â^e%ƒy–á|?$Gðhâuj˜È9,‹_¯¤“ŠañqÖ³‰wÙÈd&³”óóE˜Ö­[÷Ö[o]ƒZµµÍµµkk'Ì›z\aÒLXƒçDzDG5£í×˼A°½¢A6› Q>À±ÂÞòIšùé'4è‚ÄFA7)¿¿´CÙïüyUbÐVè‰Dl‚.)ÛRVÞPž�ä’Va­***ÊÊÊêëë×5ßõ#?O$*V]]]áDÝ÷Õ»Ða Ƚàn•¾IÉR[[[^^^WWW___[[[ZZZ ¿½±aøÒ’’’®®®ÖÖÖæææÆÆÆööö0íË_($"‰™YAQ•¯D•ÈFäSµò™¶áÂf2™Dd6¹e;dSåƒ2é" ·yå‚åQ¢BYàG¼Ãg2Á=Ô[©T*ÜÊÐÞÌ÷I)ÀÚ„»V]]/q»}uµœ Ø‹·<¼†ÿà°XàfZÀ‘à×\ÂÙt°”eÅû¬-6­Ç|Þ¡–[XÏN¯¦žÏ0d˜Qkû¤²ßæÝx9<„‹øC±_ôø¯RÏ&rXò.û¶»“ñß¼Owæ~Àlã[Œd‡p›8…[ôd³9‘sHóŸEzzÝÎF~œóUFrö@÷YÞí{Tðe¼¹6×Gý+=9ûÅXµm”1³Ó#kø 7Ä1÷¦SÇ5<JçpkXʃYàYú‘e/fðE±»{Ý”vTÖõœÆ-ìÊ3€ÿö"Œãp¹—4·ñi.æ—œÆ><Èø&Ûø·ÄÅÄ¡q»p9GRG–Çy‰cx‘Ưi¤Å,foöäPn‰KäÐr,áN$ˆ}ÌãX:ø;k"]±ÿÈ/ià?Ù˜û§ß|�/üŠOð?àOÇJnáöd!w0…+9“ÐF$O$‚8•‡iˆ'sÃCôÆJ#U`^eøÓÂ+ ä}>ïsuÌÄjç/|ŽR¾ÄlÆó_åóú°…Ñ3HþT¶Tf:3]Ù®d`âBw'õ„“,N“i>Û´�‰—´ ÿå :¤½êêêÿ_¼ÎähóK±‚Öbþ_ó-v`{ j’ÃB3ª¼¼¼¬¬¬ÿþUUU#FŒhnnð“¶¶¶üVR"ÔÙÙºp t;Lo¯¶P`ý¾ýe Y­ººº¼¼<@Ã}IuÛoÁ€8|i8Á ýñ/ïN`/%ÜÛ|½d¬¸ý…Í1©€šÔ¿$¢e2™ÖÖÖ$-|K~ß8ø¼|˜ÿ俵%Bòÿ.Ë{û/î`/†»°W:¥9emÎÊÈFŠèæE˺1rsr‘«³.Žü„÷y›ÚOr­œUìÚž Ó¥:(󵛋­ìù Ì¯´n%×­ó#8—m4{´Ç †y(kYSê#È»¥ÇWyµÉE>žrSä}žäpnç{¼Í½ô'Í-ü†{yƒ?ñ=Îev§¾Ã5ÊxŽoôöA«—1œŸòõÿÅí<kÊ]É)WE¾˜|xT÷×\vµewQÌ>HÉDžÊÚ¹˜Èjù2ÃéÑï'Òó5àFs8ßàs‘gÁC|™“8ÉœÅý=ærzÖBêyžã¹“6z˜KÄC|½ÛÛ~É&þFšu¼Á Šx)=³zÝÍÕ´q37‘b4Ëâ ÿ ÝÜ̹¼ÇÁÜÉûÔpµÅöëq3x†Fn¢?£ù)áÓ\ËLÆ2ŽuÌdÝ,§.N]ƤòÏÑ/íK1s¸ZÎæD®¦‡"Ê\즧0Ÿ*Nã{\À<ýø.d-i¢„nîa&ÑA'ûq&qͱ0îÍÔQÌ”ŽH#ƒ¹‘ âŸÆu!zp_Oy0ã²Þ¾.åfþÊUÛúƒÅFEEE¬JÖæÕI>/§`ýžÐžÒétouoOmOG{GGuÇ;½ƒÑùüH]Âr>hò¡YÉø$ôâ 4èI(0š•Ûèó¿5²ú— ®æææÄTÔ:¬¥M¥%­%;¤µ¦Óéêêêúúú]vÙ%€Üººº6Un*[_–ÏÀÝ¡Uè?¿‡ÖÚÚšÈy”––&²‰Àkeee}}}¿~ýFŒQWWWRR²~ýú÷Þ{/ì'(¬'¹pgC×4 æÊËËÃOL:’Š'±ŒÉ¯®v~y nÄö[EEÅÿ"m„…Qr$ùXŒ|&\ÂâÚ> &å]2\ìîî®®®Kí×o¶>鯼¶a"[õÓ•”6Få,¼9…ÆŒ=r²‘k¸ƒ£z­e"k©äö^/2š6Þc 'òZÊU)£©%ýFï²ù¦259ïúíwê.ÚÓÈc\úw\íÝ)‘ý(â%Ö²kë9”­Ul7¾Ç“EÎêq1çÖ¶I-—¥,éõL¤%ö†¸‰Ÿñ*ï°‰é|’µ|‘Êxµ~ËØÆ3iGæLd>ÍÄó̈‡oUšÚnrÊQß\ä¦0žþо”95Ûëúì>ËÓ»íeúr§ßå¹0 ûTFeÖ씋"p 3yŠOó2=ú/òSÊ>å[56•s5·ñ ²˜ÁL¤œÏs{Ò.ÞO›š3š»À¸˜[âÅþ¬Øà{ô0’:0˜»¸†Ë¨Jù,¯§Töº€³8„ùsÚ9Or=%œH#],à ^¤ž¿3„ØÂåœÛãê˜Ïïx™ëøë™Ïxæq0³˜Å׉¸=ï™Êo¨d-—±˜,Ã8”Õ4ÆõÍxù:ßçM¶pmÊs¼YØcWðSò4빌 ‰ýø#=Ì£…ý™Ì|ª™Ïi<Æá,e=‡ó&m\ÊÓ<ÊvaO¥œ²!’ѧU¶qáe1Ë"ý{]Æžs›¸§@Ø"Áˆ'Í«`#’ò+ªòòò@ Þáâ½ßà~ïïù~CmCã®(k.;é»'añq‹7»iÌ3cg(‰ž¨ª¤“´† †çùSUUU2HK àƽ-X°ïdõ(®¢ydsËð–(m˜¶¡u`kͪš=oß3”Ù¡´Ê—d }¿ÎÎÎà±~ÌúGOôà®~½: ù¶é}”­³³³­­-\«â2ª««kkk P[[[RRÒÙÙYUUÕÞÞÞÞÞ^àÒ´ý™†B0ѤÏG…\¢¤ðÝ ”.¬$ò#{’á \B @1ÉŸ’{—xL'EgþÈ*ì0À“`ç2ƒát’†êGÌ”Ûã,òÿºÃ »ÃkCÊ¢¬-¾2±øÚ!%iÓÍ><Àçùop *5>cÿv‡1ƒ­le7ÓjÌÁ©Ï®‹r³¢7û×TÏ3¬H+m°ÒÜ:Xý»±çú,öârç¬&Y>H`gV±h“ëáí3s÷¯æ·ÍC|À7b4Äiü™Mü„õ<BïRÆO%cSª ÄøfFó6ƽ¯–bý"—G} ‘Ûx0ecʨœo¸xÏÞšìæï5©9£]úœ‘rO2¦×yìÄü‚.a5#9Ònsíÿ¶¿PñI®¤’Jús #8š5Le=»a&cR}ŽJ+Ù“˜EM|›²ˆ¦Ó˜’I›³Ž“@])¹ÈˆT_}v{òY¦2·y„›¹ƒv°ŠÝ9•»È°œãÒg¯3ÅÜÄÇÀSÏóìÆ `ö~ÃùL‹­Le ÅŒŽÇiÏ2Œ³xœALýÙÄfþƒÌâeú§}'gvdïQG “iˆ'I5ìÃX&ó4o²‰ý˜ÃjŽàYÖИvaÎUÜÊÞâ4vOv0·qnä®Èq4òHÞâ8îg#™Í#LgmL>;Œ½wØÁÀ¶¶¶Í#7çŠr#× Ëö’ÙU’Ev�‹¢è½CÞ[1j…^ýõÿ×ñ}†I%Œlüâ#)úúúPN‹Š|iÑÐ Z>cy×À® çå¢ÝžØ­l[Ùÿ¥«ó/3D~ .˜"¦Óéæ]›×´.“Îd²™ƒ¯:xóˆÍ¦nÈ–e32Ig,ðmƒÅF° ܺukKKKkkë 3_6gXS¿¦’®’žžžÐJ éy')$Qû çך۷ 3™ÌÈ‘#8a„ªªª`HÈÑÿ2ˆôŽÜÿ‘?JkÉ(«€c¯¹V¡î¬¬¬LÀ&¡Ä,--Mp†ùxËüê*ŒóEª’ç-Á ípMÓÙÙYSSæ‹;Iϱºéi'ráïs×nîu,mŒd) cRÎ8þ™”3ˆ~<̤é`ŽŒZ®ÌÝ>|†ž«#ißfdƒµº½Sí¬áºJ½¾K)åϬâ\Îc#Ù¹8ÛÜfl½³AêßL¯©Ìz(fC¹(È¡2‰õEêzû†óãø€2Ng%³Öò7êɱ/æhÆPD}“yÌás ãr†ñíHOY6ØùïSnŸEYkâ×½t²€QœÎóŒ&Cw(1y›Jö`¬ù Ö©Å£¼Ê žå!Ê9Ž^™ÆñNÚ¸<«™‰ld ²šQñ ¦Ã)Þbtd&Y*˜Ï•l࡜4 YgQÂä8µ,Êùzœ³oeq�‹Xà ö¡œóW¾È$Æ’e'r?¿`#?`Ó˜Ç{‚øhR¢;F5Cx“ŽŽçLÃØÂJöƒºX”wÄîŽGòçȱ¹>•È=øKLN˜—'/».žä@*)f0¯ó-}IJé,}Qî ɸ º‡|%.ï¬tO0Žgékj¼ËVÞâØØdë¹¼óÝH1cwòKÛ<rsoiïÈu#“9A¨3‚iz~ Ø›EQÿ­ýŸ=ëÙ‰ÏM²`Hgwg"Fþ:fö˜¹çÏzçÔ|C ÌÚßšÉd6 |üsg‹³£çñˆTg*@6vÁ%¿ ?I®ÿ’¸“ÏE }§l6[ÜZ¥£¦QM)©—¿ùr”‹F>5²bcE—®dbT^^^^^l±‚cHccckkkKKK.›ÿìø¥/dPÁw%…àÎÓUBBJŽm{3ÆDž#œi`¿%îVÉ>âA@&—+¹a·!ïî°¡¦q;t7þÿ¸%Âh-VVV†C-ÈOÉó]€ó—ed¯‚t•ÿ<°OÂCO²]þƒ—ìí_JÜne§úÓeª‹³Åc²=Oðä.~¶Þß"ÂP~ÄÓ½jSþBÇÒ‹ËZnÓðC—Þh`±+ç«\ô =Ë7:¼×ni·Ç2Mp>ûs“>íÚ%q׫Œ,çäÖ¿ã’i.ŸÁ]Ѳ×r®çp 3f­Çøï ùKXÌX®N»’·˜ÆÁüŠÿŒ©T³¹+ù:1Éò"ßÉz/òlìĘã<ÖGæÓÀ—<Vcéþ ç7/» 0›·YÊ8RZ‰ÆÆ Š,XgÁ ý¯óþo˜Ê,楛þLáöæ!N‰Icù ãXÆ]–òV¤-¦c7°…Ó¹—Ϥ\—ñ£^ÝìÏÞ)_ÈÖëçœÈx¶ÄÁ i÷Þa[9Ñ|—c˜ÈÙ\J_£”؃¡¼A–¿0™hŒI»ßäjÎæ a_^àrœÂÝŒb)²N&Æ`ÂÎç:þA†gSê2.éõ[^á]š¹vf²…oê#\@Wp]¼Dš«ÈÒÆï¹ˆ"ÎËÙ‹MÜÅj–Ç–fM±0n×ró™B›x=æiÛc¨çvù·ro°t'éjˈ-sOž;ùñÉQ*ª­­MFÛ–¼b^ÅÌÍܺëÖY?Ÿ5þÞñŸðÞ!>æŠr›&lJš3bߨüô íµókg~sf”ŠJÛKK[J£(Êæ²I|O¼—òÃq~O‚Ëõ'á&¯ÄÃ>Ìç“Ä2P[[[IKÉÄÙ»«ºÌ}isiPÖ¡�<IZd‰c}@„|ûÁÏŸ÷ü7•ý_‡ïÐW,èkÄÇ 6tttd³Ùêêê0ljj %H²“°Ú¨­­ é­ èIÞ™,/¶Çt$Q;¿° sä&†¹WÒ L@;)|“r§¨¨(Ø”„ó -Ê_l?Ýü(p›ëÊÞt>oûoÌ—bÚ ½’\fD½cžwÁUîºÀíÅü¼ÅOù4¯p»1‡–È呼ÍÃÉ<ͳÔÓ¹@c£{7xf„_¿YûFYªe¯n#¸Ð÷ª|Ñ-çq'b+s™À1b{§’IëNwŒ¯ÐØÀÙ<Ì <ÒâF®¥Š^åü ¨ÁÞÌΚÍ9¼Ì£ àYnb(38ŠË8”^¦°‰™›³Ž Õq/²ŽCSþ”ÖžvRäÑ8Ïh<Kã"³mÇ<Fq7S¸5ÊOhN™VdJΔðëtï3»TEíuæÿZÚ8…|&h¿—]8› I©cf©–¬Ç8Wy<ã°ANh·OJKdSì¿ÞN¨Í9ÿÉ3Ì ºã9W§¤9_1,#Ú§¬&–²qCèO?nan§Ãͬá î§ž¯ÓÅ:06î‰ÈJ*±.§ê´o¦,Š@Ÿá¨•WƬætnc‡òq.ãÔÐÆ9Á%2§‘Œ¦#e+èä~Æ7éG9 8Wx™ ôð+ò,'c)çQŸ×Ì瀸XÙ¤;��ÁIDAT}Mäbà†x¨ÖKs:Ìç–²Ÿ0‰m¤XO øLd_»ví¼yóR©Tiyé¶½¶Õ4ÔtÔuTUŽèQ\\¦ÐùKÈsi)NµU¬ªØõÑ]׸¾­ª­rueIqIÈy³>û„ï²W"TšO7Nì£(*i-)i-ÉteHtk²^.˜¦ä> ]SSÓ¿ÿQ£FÕ××TdÁÂYlš\Ô]TÚZZÚZZÒR’ÚšJw§ ô#’(æA¢¡¡¡££#ÕšZ;yí˜gÇ„¤lyCMJŸÄy=4v>„:†çŸxrñÔ1˜T…‹œ·lÙÒÚÚ( ÄÉ´ïÃ$ÛKKKƒdÀ¸Xg5QÛËwJ&sù¹¿àú'ÿM0a(zËA#€È{,¹Tq{{{ƒKg~òe_ò„$¥øx"¶R`ù˜úŸ[¾®qX9%8£–›Éë•••ûtØN€ì-lÈ^:˺74¾éq¼Î_MŸ¦›˜BoÊOøe¤‡%iãsîÈ@ö%Ë©ŒçWÖ~Þ5ÍÛ.øQÅm£3+z²nã›ñઇiÅ Ú9Љ±Di sÎgƒXÁ£”0€e±›ß ÊÙ=ùߥ8&Z5p$Ïqr€„°:m\ηYÏZ Å©,¡“¹ô'q~;ˆÎŒ»{}™?2 &ð ƒÓ~™ó-¦³•[Ù›ÇßC_L©èõ=Œ`x$=¸<¥†ž¨/q`ŸØQ÷ >Îh¾Î¦´¯qdäÑ?mp?§ˆ=³~»Á(¾Ê3üšû9-ö_¿‹‰J1)¾L'ƒR} €글ç™Àz^b&S¸/p+×° »RÅïâkÛÉψ؅Rn/QıTò�ë©g*¯²šiU¦6©¼‘s/³“ø)­tò#näEçišhb- ±þýô8s„÷¯e £ùFÆ®½Ne$­|OêC–Îàû)dz(RÌÈ>‡LØÀd¶ñÓøƒiŽd)Op\̺’íã<¦6ó 3c9¨Ã¸-îåÊ{`v/X¨°VoIïs3Ÿ;á/'l«ÛÖ¯³_h 勯†X #ò›BáÅV’=O¸ÂÂO,ܘÙX3¯&„’pœ¨7%’nIôIæùùÝ¡‚e~¿Nð ¶`ß>W…3 VUUU4VSSæU¡P(ìø·01qÚ5Ó Ž-¹VæD’u'3­ä[òE4R©ÔÖ­[ƒepñÝÝÝ[¶linnnkk ™2IömOz‰É;óeÈw )'±þˆÃÂÿ!¹hA—² ì+¸Vá)*8æü:µàÉÙ“Œ%ɸà[ò4wÞ ÌñЇ"7 â%ÿus˜!ög‚WøuÊÔ¨o*ÞH&í´Èóic²Þâ9Îä`~êÍSÒ¥_Íœ×ãÚ æÛc³G®à¦ÑË"†² +ÇB¦ñ^LL~“ ¾Ä[TðIöã:žæ(úó×r ûð2yŒI4’åWü€,sØÂt6ÅŽåüŠãéG)_áŘ“tßëõ>ÄÚBYnçÓ b|,Þ:™Ì¥ê沂Ù)Y>ž¶>òÓÈÞ‘_eÀÂ8†fYH}ÆeY]|Šþœ¸·9µüŠÁ þsT÷g ?e¿b ý©¢3oˆRÉ:ƲË©âÚœEL§”ñÜÍdîd:GÐË\¶q í<ÁSyÁ>´q4[YÏ" ’ã1:gId¯p$“Èzx©Ñ2Žem|ŠV^à§ÜOšzNá†`Þ3ºÐM9Óy‹ò'8…öø"oíõ—0ˆ!CÓ¸‡ 4ÒA6¥"ÒFmñéœÅïã&søàlŠy™}˜O'ëYÎãzbaŽmñ¤ªœjÞa8xõÿ“ì… Ê¶W7Èd2™lfìâ±³?1û؇Ž´yPÉ >k×€s 2í%%%I&R^ÜŸ=æÏcVžºrÕQ«Æ½0nÍk†?7¼ %Ó‚$i}nV¿Àp(šœp (JUUUUUU H$ïB* Ëð$<%�ÂÎÛòVÅÂw…:)ièk :4¨øtvv&Tb±-S2#ü·¶–––L&ÓÖÖª¢tCVÞþ | "ß3ÿtòW!» šípõòÓüN’\B~H®gA³1y½@i)\¢ä•�x)8DDãÿ{âÌ?ýp´MË*²Ÿé™^gNSUË‹œÄûàz²LãN¾“²!í̬YÔñDÎ ^ŽôgïÈ~¨V™3©Í‹œÍ¨hÎÔÖŽ—£_?ëŠû*ÆN,š³¨Ù<2™¿dì™óbä혤yv¬…z*hˆ¡ÞéÇjNe籒żƧ9†7™Â.,â,º¹6e×´[³zr¾[äW½–³˜YœÉ…tsUÆWsž‰Üó0_ã'œ@†-Ü–òµ´=³–ä,¢œ+hç~š)I;.eJÖ³ü6ëpÚ#ã©áoqswFdlëïÂ7’Ž´ðkÎO›È#9Gs¿g$'q9ãø=tp%Wò †ru,´:<_Ü 1¬c?¤’_ói>΃d¨e*ˆÑð¸’M,ædfòep oð¾ËdÞä50–¿ç¬‹´² ~`¶±‚Ï0…XÆzŽä™øÄgr=õ?B˜Ã€87„2(ËrVó02ÜÂylŒy`8ž¿Óç˜%L¢"2(r'»Ä®fØŸ'YÃÙÜKTÏ ñ7Îäþa(&u}–×x™+øcìÍøcYÇ*6 þQ$ÛÓ1õøÐ}R©T:›>tö¡vÝP×R–íÅÅÅÛIòÃMiiiˆãÉ (­~Ï£½îØuïöþú½×O¸Bøa'؇�ýJF¢eþoEëý‰ zWWׯƒ¢ë1uuuWB¨Z .]¢òžÃÛB(ßžŒü!Ã5Ol¢pvè ø„Á]€õÏß[HxGÔ"ÂRàÿh´ø/¯äÿR˜?>,À‚ŒbX&É—ù£¬ð©¤ã @I;t‡ ¼¤­—3Iã°hmØ|Ûðœ|XÂKp­7hûÙU;·°Îº§­ÄÓLã€Øè:†LZÊŒ´å9 8„=S^)ò½œ"?¤¡W}¯ßFã i™´]sÿâ…ÏøÝ“½_<£§3Y .a¿ÈÚ¶ŒK¸ŽÜÇ« âòXÝ œÿàíbWäLç!®b ß§œE¬`G2—Ãb¤Ü#‘õ,a·Œ£s.¥’y—ÿ¢ÚÈ“¼ËE¼Æ®Lå¯Ïbe*²-ÒËö,­;­,RÏ©¼©üŒQ¬aO¾Ï}l –Kx“8 ²¤Ëa‘ciŠ\ÅtÞŒ¬¤xÓ©äþÈ Ö±;çV. ƒ»¨csyŸ.öçü4Å<Ξ,a_îá=ÎæZÖ³;—q5_`¾Î[ôpM¼ÌÜb7æ<”gy„ÏÑÀZ.d%'ðgV²‘QÌà!s*§ó­œÎ#¼G3KhdUÜ] “Î Nàu6ò%Þao†2ñlähöánf3œ uÁ»|µ¼k€Í%ÃaÌãuzh‰uçÑ "ŸFkÜgÞ̱¼E–¥œËf¾F Ÿçqºèϱ~U˜Ò}*®®Ng+kû$•qkø&{å‹0Í]47S”ÉÈ”)Ø<°Ÿ~¥¥¥555!]%ŠæáÇÆKùt׈ª±ðJ2-ÏD™~«ûm™´¥nEݠŃJ‹ûÀÇ“ƒ|vNd .+ß)lÉà*D– '´½ÀRöA8ø„Z>fH ì0�äB­¾¾¾¬¬,ÙÛö´¢¢¢°Ï$œ¨ž%Ř‹ŠŠÆŽ;lذ .á ä—•!ñ$ ôI§nû-×HXYɹ'fQb£¦|Ùªë…þ¤ì UWqqq{{{26 k”@¿K’A8ŒD±"_d}çR#ÆKÒU2ÒKjñ=øüf‹+ßZ,áVç£oBº OcЛϟcå ü'’c‰S¸>½½½eee;Ÿ]m`EÆé9/E~Ì$^åeåö#G7C"WöZdô�#Ÿá…ÈŽëWY:‡˜ÈèœrŠy†Ósîç5öÓ0×ɧED–PL”ò«´ŸfÅ·ÙƒNÎàXZIq(#XÃ¥)ßI{ ë0Æ÷¸‚mŒ$Mo‘ ½†ð7s+©” ¼içK\Ë^le¿7SÊëœÈ üÅ)ß|…g(bCù_ån¢)ç|^£”›Ÿ¶OÖïR.ˆlä+üŽ‘ ‰å©9“cØ×Ø‹66riÖïRJ£>E«{¹œ;x‘½y‹KbMôçø1ç2ƒÝù>ÛRFóVäÒ±8EÄݱ·dŠWTÛ§³[Ê#%öëRM-ϲ–·Hó—§4EÎŒ‡gí=þÎD³„ wp07ÐÂk¤9‡{iáˆØý}×SÍ@öç1ÇÅǼ͉ÌbÍô‹%Höe7ÅémÃø%Ÿç7¤ØÆµi)ƒ³¾Ï‹lâK àêù ‡RÊõŒ%CSüÁYLá®g±>»ÐÜÎqó^f±‰»Ù˜rK$Ó¾B7rpåüˆ‹Ùʹ,àN†Є»ûu¿}ÂÛ»¯Ü}øÃC<Jü÷’VOKKKòß\ÖŒ[墼? ¥’åvXŸ ¥$RLyf Rå©ÞëKD˜’Ìd°CàØyѰÿ&‘±§§gëÖ­EEE I+/hȆzÿþýËÊÊÆŸN§·nݺåÿµwî±QUyÿÞ;Ó™é8íôA)…¶® UÜFAV%[q‘îúDc³¬VV‰ì²Ù5®5ÆMT¨¤ 1X!XLˆbv›X‚þS7kÝ¢4Û}¥¬`k…>§N[æÕ™ÎÝ?NïáöN§LgZl×ï'M3÷ÜóºçÞ{~÷œó;¿ŸÇ#& „)XÙkË-P&§$&/òF“N¢%eohuÒ8ž˜ÒîÇLvÇÕa³ÙlFe¿x›¯ý˜6öЇAn×§»­xbü~zzz¬®ü80n™úŒû´b]$2”îZäJ FGVV–ÕjMOO—R°»»[ø{^ÜÆmüqWõb[¡xdMÀÝÀÝzàÀM@'ð.p pÿ\ÀÃXv¾ÿo`#ЇÆLœÛ|[w+6„ò¥Àvà#ýC{ð*Ð×àA;p°èŽê`ø°Hz÷4lA°¸ø%ðWÝä€‡ à~ \æ*X¨îÆí�Ü@p`þ´Ÿ·_(xIA±†Ð”�à^à§À{À+z |¬æè™.߉ ^Å«À: €ÿë�� €;€@=°(¼º•z±2ߪà-Y¾ÐwýX,v�—Ÿ>^T�ð`æ«€ ò¨†?`‡¾ñÀ@!p¸£zƒâW)ø¡‘Î�¥Ài`#0¸ø¸S…sç€[p+P¬Öï‘ø Ð |ܯ·ÆRà[ú}¸øèú��?²tûèÂVÅuÀ«À‡À*`!ð–>Sw‡G^c%°NßwønïiÀ`P@¯êE`‡óà!ÀQ/YbÅñ‚¾ÿz¾Lðgà×ÀM@ðc`p(þ¦âG#8< Ç|Øh¸L+P�¼bPÊk!è3cÞÞì!K›Å5èã1¢öREǪiZ^^ÞW_}eìï>»í3MÓ¢ZÀ¼¾yi¾4)®ŒCiôZ:€ýšq-$^GcŒ#ô¡ëLÆÞJúÊK\Ê™=cÝL¾eåÀ(‰±¢’Æ* ù´dÉñ….f™‚Á ©S–PÒâ¢éºä Ãè2Xš7mD3úÑ0«L~È&˜SµÙl‡#¹Eµ‰÷eKñ"ç]…;Ñ2¦¹81œà>q‘ÄdmY8#µÛí999r=L¸Î ‡ÃRwÑ8 (‡Åãhü—mxbåýuõzX{ÿðÒÇ BH²?ŽM›�àìÙ³{ÿ²7;œ=->0…*ó‚ Dÿ%¼È ø|¾H$‡}>ŸXV1õ_B\ù|>¹Æ#‰œØ‰íV„…'ALÄ™²#-1º RÁAôhYYY¢iEWÊ£"µèӥ˜ü.6ÊK1¿'æân¼ñF±Ê ûûû#‘H¿it%ýÒšæÓ†††¤%uc7·hÑ"»Ýît:½^¯ßïïëë“m(§³L ,r·¯\¼u”š ²òñ¶"Å:‘JÛ&5Yœ˜ƒÃá’—)YZnÒB Äå’¤hgÓÚ§I2‰ÛjZ;”âÙ¨Ô#Ä•4)G±r<'’ÈÊ+`ú ‘ÃA¹‘Üår¹Ýîââb—ËUXX(>†‡‡ÛÚÚÄÃ/Ý’?¡åÓ¼yóvì®Ú²1àlki3º:q)øL!„àæ›õAå’%/æ¼(7¾Èw[vÒS¬Wˆq¿‹MޝL³s± ñ}mœáWû†ÝÁ¦!‚qI#vgŒ)·xßò¦›”µ"¹èë¥Ç Ód”i“²´l»r#ÍÊîÏ´]רa 1ÓiMW7 \¬Î…ŒlTcŠ…+1kjÝt½F5?™‰©L9˜L›âÄ><B“ÂèsÄTãƒd4Î4î$žÉ™ãHqVhxÊCSýMkC#q&KKáæàŠ©@¨t³I…æÖ+sì*›ƒBÈÌgÌèêàÁƒÓ·™€BI·Û½â{?_\½üòËGW†–j!±jI’K5%õI0«¤+ Nkµh€¦BS *¢Ê˜¨'6Zr©D“ŠU€¤*MêbÇ­ÀÕÛ-¹T±q¾¶§/‘¬¦ï¥IúÒ¦©™8NB9^ËVžŽ‹¼6½îÔwz.WFÜÑ•‘FÕSªñS0å~J”ëèŸè@ã^ƒ,q졦Âðöñ嘱%*SrŸØ¬ÓUbsk'×®!„Ì&(®!„P\B!W„B(®!„Š+B!„âŠBÅ!„BqE!„P\B¡¸"„B(®!„P\B!W„BH’XãŸÒ� ˆ w@TTcΪúe¬ø$'ˆ“zæSx˜tSRU¶¿†¨-Ѝ MC4Š( iˆª1gUD£W<\Œ:™ðP:(™ì¡ð5Z臆À”§¨Ú‰^TœšhÊ•ÿºc Pô{%_—èØ7L{vZŸ¾õ†]›ü'Ž©Ê;1…÷i¶7Ü4]T29¤¥¥ÇTcÄUYYY ˜y25ÊÏŠŽfø¢™³Þ‘‰Þ¤6Ä´ÓÐаzõêd_¦‘¯¯ô1„B¡æææ•+WN*ÕÇ|ûí·Ûíö«Æ<sæÌÒ¥KNg¼ùùùOüê¹ñÅUmm­Ûíæ£F!©PRRRWW7ÛKïééÙ¼yód³Z³fͱcÇæÎ{Õ˜>øà¾}ûŠŠŠ&ˆÓÜÚ![Š–ÞyÃM·\öܪeé­‡ƒ!„¤BaaáâÅ‹g{é‹eáÂ…ÅÅÅ“J5þüÅ‹[­Ö«Æ,((X´h‘Íf› N—g°é?_FÂ!o÷—V>X„2µ”——ÿ”îp8î»ï¾É¦J<Édg,©H!d@qE!„âŠB¡¸"„o&O>ù¤ñ°¢¢¢¢¢âí·ß‡çÎ!---"¤®®N„ƒÁ‹Þ»woEE…±?þxEEÅÄáÀÀ€(ëý÷ß!MMM"¤½½Ý˜ÕU¡ª!„Ì&ªªªÞyç@ PSS#BÊËË÷ïßàðáÃÙÙÙwÝu×ÓO?-ÎîÞ½ûàÁƒ­­­ ÕÕÕB°:u*éÒkkksss«««?ÿüó;wîÛ·oÛ¶m>úèõ×____ÿæ›oVVVnذáµ×^P]]———››[SS#Jߺuë| %neee~~~¼„Ë—/§¸"„Y,®ªªªJJJdHGG‡P7×4ÍçóišÖ××'B¼^ïÈÈH ˆD""äâÅ‹©”þØc‰---�º»» ŠŠŠìvûÀÀ�€K—.‰²B¡P(ŠD"CCC"¤»»[fUSSF?ùä“p8œžž›ÐT4' !„LŽ“'O677¿ð )æ‡_ýõžžžeË–]52Å!„IpôèÑóçÏ?ÿüó©ge·Ûßxãââb9CHqE!d 8~ü¸×ëݾ}{êY=ûì³]]]‰ÇçÚ!„Ìnrrrzzz�(Šb·ÛEÉÈÈ!N§SUU›Íf±XDHvvv*eµµµåææúý~¿ßïp8233Ýn·×ëíéé‰D"b *++K”eµZ­V«Åbq8"$33SfÕÞÞÞÙÙ©ªj¼„W„2ëY±b…üÝÐÐ LmݺuíÚµ�jjj6mÚ`Ïž=sæÌ¹çž{z{{EÈéÓ§S)·°°ðСC'Nœ�PVVöÌ3Ï9rdË–-ååå»víPWW·~ýz�»ví*--ðÔSO‰Ò;&³J$¡¥lÃ+飼׳ÀÚ»sÛZd'„2ChníØ²1àlkiäÚ!„Y�Å!„Š+B!d*UµPT‹?jûç….§sB!d&páR¿¢Zƈ+kšÍÎ9|êïlB!3EµXÓlWÄUx88ØßÍv!„2‰„‚�”†ÆO·§vxx˜-B!dfòûßüüí Ýqcè����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013365� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/lock.png����������������������������������������������������������������������0000644�0001750�0001750�00000010277�11332353406�015045� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���²���Ò���a e���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ"Ì™å��LIDATxÚí]yp×»:-ÉÒJH¾0p° IÀqH Ó ç¶™6¥ 㤠%MgâN:dš&)¹ÚÒ?Z¦3I’P—tH;Ít’Bsr±À Ø`|I>$[çö9›õ^Ú•vW»Úï7úC^¿÷VûÞï}Ç{ßû#I�Sa¦¾5¬^ Ýa´¾³#3-V¯½ãî ÐYÆAÃêµÌÀH’LsâÒàt–qÐÓuºûx 3¾Q"щqè,�ÐB2F‡‡¢aÉ2Õæt{|ÚiA-bÑ xD'"ÑðH]m­ÔŠÇÛÛB6»C -ˆ,Óí Æ§·ý3sϾicÇ=¡¶¡î/ÙÒŸHðêú¤ëð| ã ÖÕÖeQ±®¶.ÕH ´8iaÌ¢%s¢½¿sÇ“ÉôæÎ]ÃýN¢„Q&\æë ¢²êkÙ-0 Ëú1òÛ‚d%®c±…‰êìøç’ë×Ì«>ûÞ‡I§ÇlµO¹Ù`GÒeŽ8ª|.Ok CYó>=$ZhA*-8ïçô–\<×ßÒÒøçΜ~ðäþÒùߦDÐp÷‘Ú²âÏOUÖ^Uð¶EŽ3å<×ei! is–ÌZpêÈÞ‘‘NÇ=¦hçá’9õ¡ÑþîÙ^´ÿ虪ú›øê-ð†ÿú3¥…ß=°†¯Ê#Ͼ!¾Fa΋éê2( ó—u·¼aGQ„P*5r¸Þ2Oô|{÷@Å‚U8ns§§ï¿½ªlÒGJ$’}Á±Þ½ïµ'Sâ+¾uÉüºÙå>·!40>ÕÝ÷æÇG. ²« ‡[Û»þ³÷p2™RQ‰à¹ˆI-œl;P}õ·D¶ð»Ö<òÜÎÉï?¿]¨Y”Ȥ»b¶–.¸±ÿÐ[Âql ó‹@ $–w\vµÈ)¾oBÁáή‹3ÊK*J§Ýµª¾§··íì BXͬ²‡ÖÞ`µ˜‰ä©s=áñ‰ò€oÙÂ9­mí=}1³Å–®ÞóÕÀ¡öS±øêšÛ—-èëïûðÈ aª°Bpçú_³Ë¿¶õ÷Œ‰Ê×Âožë™ûoK³úN5ËnANir¸}Ι Ñî–H4Išì<Ö—U–VIé„jkïܼõß—ë_Þh³ZÊûÑ›ðoøîR«Å|þb߯Í[û††-V;Žã%¾âT2MÚ,„-]ýDg÷_^Ùiµ;·ÿáAŸÇåsÙÂÁÁbo@b(çGÌ[´”—L"Zxô¯»žÞp+BˆÁ F³Y{"ä[*2”"Q”´Î¸¬V«%‰I2)¨_du8jjë,f3BèÔ¹žhtâòÊ€·ØÚöÚ‡FÆ•sMf™"£ˆL‘ ‹#ÉÉšwyÕ/ï½³¼4àó¸"ãÑ÷>ý"Ÿ IR¤"Ëx^�Ža8o |ÍÒ¯ ¶ðè o?ý³[¦p¢~÷oQ‰ „FzO'†ÎÄ‹JÜÖH,‹F£(60:0½80CRÿ¬X²hÅ’E¡x"ù«oÒz”(™áqM:½/ ¸¼i^÷³ïJ_9Úyñ¯ìÁðÉç™^æŸ^æO“+ry†òK&Êù|ÍŠQ"i<µþfºzlëî=œSL1 ‡F;D’晋Vú®X:26‡ñX¨ããØø&iyÑÛ7¸wÿápdÂb65\yá/·;‹‡#“ëî%~“ÅšHaï·vtõ\BM„Gƒ½gqOWßóÙÁ?þÕšõµ9QUQ²ñ¾ï# ÃM&LŸàëùŒ#BÅ ÊLyjýÍ"o½m‘JÄÃû†U\µÒb+²*“ÕKÇÏì³Ù¬‹eìÌ~Ûü•â¥Sû©®Í/½V[=ûOß{Í‚êU×Õîë8× Ž„½nçºï­zæå±xê•Ý-ko˜ÙôR„PŠL%âQª»Ëã Lÿ*EU–ù‡zœ.BV–ðäOWñ•}ü¥w%x"|½G¿ÎÓõÒœxü¥wÓWž¼ï&îß —m1~¡Íï¶õyºýé+¾Ê+ú#Áªâ¸Åb!Iò|÷ÏÌEâ ‹­¨?Œ}rèäòúy?¸eÙG‡·™,¥/¾¾ÿÁ»–Ϫ,{î‘{Î\L$S3Ë}S*c“¶Å/~t«Ï뫯©B?u.‹%1«Í¡<+$¬[´·ì­[|CÆUÊé¡Dx[ 8‘¾ão_~¬äû òØ‘K§gû-mÝöòº+éüs\h­Ÿ[•L&=##'ºœ™â»Ød±îÚß±ta5áv­¾¶fÏÑÞŽž¡‡6o¿mùU‹êæÌ©ô§Rdß`è£Ïïúà�½bÚ¶ I28þßÑŽ_}Ëjw$™ÛbÓ¶÷Ø#nP¹-[˜Ý öEEÔØèàLgäd÷PiÍrÊè›,l2Åu‘Øð¼9³FGGɳÝg"Ã6'!p§'¶½¾ã`"³»<¡¡±ø~~𫳈D._‰¿bÖiÛúú§±»cáT"‰0Ìd6[íÀ0Œªþ ·Lfk‘‹”c˜I-%¼ËüëoÌqGC¡8.ʵU66p¾c|È>£Þl±±kÚîcƒ‘ Ç&&&â±Øh<lŸS/|3O Òd±à¸)M}—×O¦RV‡!”ŒÇ-¶"ï´òñ"'I’fÂp !!„ãf‹ÍŽaU}Šà1™­v¦yOD¯;¨lÃgÚ冹È[EBV„"næñ—OQ³•(­œâY¬N_duõwErPUiSQ -ÈºÊ píí'êêj¤V<~üKG1a˜Z�ZÈ [‘3Ý¿R+¹<éºZhAæUN�BÈæpÙ.½·´ˆŒaø \º½R¤B‘‘àöMë ã ë6mÏÈ ºÉPزe‹DÛ‚†P(d¨Î""ï¿A…>onnY¤…ž&±j0Ãä]FŠŸÄª¤�h�Z�€� �hЇƒêõr/ƒÁô¿‚A™7VÍR*t;ừVWg´ H ÎO¤Xèõz7Õ]w>-2Î ºPÉqüÒÕÙRŠ~_¶QT¨p>ð#ëHràŠNñ`0È7¢Ù),¾v `ü+Çß òé„Y_ÚÄœûtÑÔ£²™‘—ŸÇ)8u¤ò”µ-äš 2Nt€z¶…Bf){’y½^=R$-ÃØ&³¡×-ÔK†ýȲÛ7º¤Õ ê¨UêvÊÝÈKçÓe|d1Üõp^¡ÿ+÷¸‘˜ÛÉõc8늼¨Ó…–YüÖ©Í´PÃ!TMg'¢3f�@Z�€� �h�Z�ÀÑ4xŒ¤Ež¡µã~Z”F›7MMMMMMFxÌì¥ÌœfࣥoPJ¤±±zLN��h�Z�€�Ù�«œL#\Øú.Ô2 `$I6¬^{ÇÝÎ÷ GF‚‹ˆ!z"™öè^+_1½—å ÂºEÖtZl �Ð�´�€'"ój€´((NäžW¤Er‚.*ÄdÌ!Ii#!<H m©�¢…U}Ý‚m|6ꂾŠ'�†ðDdŸ:|(à]sÍ~FZå,‰¦¦&†ºÉ1•›Ê9h%-(f0œ‘4W¤2cÖßÛ8¯¯9ô7a'(—LYZPm¨DÄ$ëQ³ë¥&v͘nV¹‹ßrr‘žw…±R">±+›Uœuõ®ÁäT…V.:EQf€´PJ…e”ZÎ÷´Í€Ÿíš¡D€@™ÓÑ-tcXdÌáÊp›%± ‰iÁäÌ�öúDv¶¡ðE¾”®|eTP= -x¡ÍÔêª -¸ÑØØ¨Í­TÎe\ �” O�iÁ$ViÁ$ˆi1ÓK™–¡P2åt•í#‰´ƒ´ób‚ Ò„€€o™•Hðk ½EQSœ@IM%"u¢‘!:'�jЂqV‡*§t䈼œ€_™ƒ°ÒÉ/3d”Œ_>c+ 1©û_>«B›vFss³Ôù->Ä—­4Ó’2‹ÑÕ‚ª•aÝ‚MŽ Ú¡Ecc£úKUÔþû‹ø‹Œí1¾ëÚ¢EÆÑŽÉ 3=ÀžEÂQy ñ•™ÂQ'ZŠ2ƒ†#FAw‹¤0Ž<Û’Þ^Œòt@C˜Jø²Ò º'B—°7¦øº…™¡Óå8>¤ 3”*…4ýøµrÌ€x !ˆñÍhrš_Â!ÄW‹€_�‡~_€ž�J�-�@ �Ð�´��-�@ å@œà„l±œHo¹’…ω@ˆoNœÐi„ãœH2ƒÅ‰Û*“Á›¯p_³,œ@‚ÉDEæ+U-»±øøoI!¾œ‡!Œ¨DÄèá“#ì¤ (Ô­ â|ÃMFù‘qnÈfE'.Kpf™Ô`8¼ÊçÉ„³õ ü—]Rd`¹6Wå9 ±–NN>©6HÍÍÍ::cHïUvä¬Àä‘å†Yµ‡TY0p: EöªÓ]> ì]Šçò»¥Îõ¼ËŒ¼ŸQB7)<GFSV…pÔš˜$¦ºfcžè(a¯üJ„ó´HF;ƒï¢jአi7Üðu—È8+†A¯ÈhDëªÆAgFss3_ئ¤,¾"§„0ûÅdôUa Á9Þ5lm†øê{9K/Ìø—‘3æÀÆ:�h�Z�€� �h�Z�€�­Ž&sB|Ù€â«B<#ØA"åD‚À¤â«ë8xÙh!cŠë<r"=êͨY¹]1F’+Æwvgf âE¬ §Jô¹Aß'BqB@$Hí 45°ˆËNÏY›1^—ó"ç&{ï]ΧáÓ‚*ä¢“Ä ‘—3…ƒ* ¯kNkcy"Z˜úá;¨Î¸jv†w¾ºŒ Eå„úrW9äa•3_o …BRc3³3,$Ù’"ãU{ׂ9_¼Î‹+›fÆ ïY^2¸KÊÊ›]Z`MH ÉÁÉë<ÉBf@ˆ¯l~‘øÌÖy„™!¾F]f(gpÔ) fd— hQÈÌ�€€´xiH &¶lÙ�Ò‚idpA¬Û´Ýáöö_èì>ÞÒúÎ�P"� �hÈ‡É K~�3¸jƃ/ZÄU3&Ò*Ø�09@ �ÐoOD³¶’ŽºUï‘ -äGxø:ÛAÕþ,,Œ  � �h�Z�€�ðD²#÷†Ž’z´P–:ÍëÒBYNP¢ñ¿ZXjº;È8‚DüE 28c@‰ùXŒi—�-Ûa¡'ñ1¦äÀ xêSÓ=ãŒÏ˜·IÍÁ-ò Äg¶ÓB¦/P"Š0ƒóOñ™í k{‚'�Z�€� �h�Z�ÀAÍ�H†Ò‚ Ȱ�Ò‚ ã$Ãi�Z�€� À�&'dÚL¡…Ãí=BbRnô ‡Û+"ë� $-ú/tBw�ÒÀH’D5¬^ }a4ð½5âZ��tü²›˜¿Ì&.®����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/grid.png����������������������������������������������������������������������0000644�0001750�0001750�00000020243�11332353406�015034� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��˜�����™+·¡���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚä!{�� �IDATxÚíy”Õ½Çom½ï3=3ÌÃ2 "‹ \#šõ©$1‰YN'19f3¾,&1ñ=N}Q£AŒœ,>1h0*A#"DtF¶`fXf¦gºgé™é­úýÑÐ4µuõ^Õýýœù£§ºêÖ½¿{ë[¿ß­êû£âñ8!ä’+n!�� 7voÝDa*výmwÁ"��ÝqÉ·ìÞº‰ºxõÍ×ßvWïÀ0,�Ð'ŽéÚ¿‹Müš‡E��:B@Å124 f„­»Ó£$„,š@ïP „&ÆBÁáÖ9s2=p{;!Äh²h¡i!#„|qªý_MNÊétF£Ñ£ÃÏdéSŽùO[†÷G¦Ì_‰!€„,8Ò:§5‹[ç´îoo7š¬Z(AZÈ(J(d5-—„Ní¹áú5 Ãl~~KÇP¿ÕU#Ø'›b=á'u3‹K��hŠ¢²¾Z©J[‚Z!ãŒæ kæï7ýaÙ–Ìž5óè?þ³:Yƒé¼Ælì˜e²ÇæÄø�@/JF²v;"¢…¤CK©B­îš“ÇúwíÚíõV·47ì9ôfíÜ'ƒÐ¡®½sêìolœsÆ�â‘‘œý©¼” ç‘Ñ’Çx§^xxï¶áᚦL¨¿ãÝš‹!#ý]ÓÜäÍ÷:'/ºRîØÒb·˜¾çS„ÿzlË‘îþ_ó“N›ù7ÿ÷úmºmr´ —%È\èD„>ûw^ ÷yÜ!ß~è9õ%v–ܘ8\mh™¤~]Ï™HˆÂóC‹Ãâ®s†ºÛ»|õ®¦iF¥ êª×,ŸÛ:m’Ûn‰Dc]½þ—v¾¿kÿ±Â¹Ï |':#!öØ©#?Öq`<´ØÜYøµ[WÎŸÙøò®·¼•Åá5û5Ëæ¶N›äqX!¾¡àᮾͯíí‘Ü_®Â‚vÎ|ó£/~trÝ™‡Ó1>îîÚüÙmï†#Q­]N9ÚäZÒY{60T[¡¶3çPe ÷yÍ·~þÌç/}T©õ¡eš5Ô^ø‘þwþÆ1„¦)_ÇÛ^oM86n™r±ÁlUÙ˜ÙSë¾~ËåŽ G¢ûÇùSÏš´}W›ÙæÊKï° ñJFH,Î?øûWúzŽBl./Oí)84ðryë3:*Ùüh4vøØ‰àøÄ$¯gÅ‚»ÛÚOô…YÎ(n˃O¿Ú×}X¢Âç·KÔw!Äç:rü¤Ûa»`ZÓÕËZ­Fê·ÏïÎè&,4fÁÈΞE«BKõáŸÿ–xÿgý‰ÀO’+á;ÿû·ñÚ„~%?'‹—±GF±8<ÖæKB]»ÆB±8c²Ðá~º®±v²úaw×Ç–8¶ëdßÝ÷ÿfph„3šY–i®¯  š­N§ÝrãÊó[lÓpp|Ïîg^}wl"LqXMr_ýòîO8­¦¿nß;»¹vz£÷‰Ío;éûôu˜Z_Ýïùëö½©uøÕ7nrÚÌýyÛ›{>ôO:m¦vìŸÖP=£Ñ;œØ´õß»ÛB>}íÒy-õ«™¢ÈÀPð¶Îç^{/ßÿ¥6x]„5«–­Yµlt,ôåŸÿÉn1Þ¸rÁü™v‹É?2¶}Ï´¾Çåšß}²ï›?{´opˆ3˜hš®ñØùX43r.ã/ï¾IЖO®Zä´™nªq}F¦]„:¿ï(BikïøÙ£f ÆoÜù±/™·t^Ë?[]7E®u’Æœ9Ù;¯¥Ar燾y“Íl|v[Ûœiu3«Ÿö?òì¿–Ìm^½d6ËÐÿÜsø/½}6–6Q¦öWÏã°\º¨Åã°Æx~`(¸í߇¶î|"U!Sxæ8kárYùSQÂw³åGw]C¨˜ XÉciQà*ýÇ òqŠ&{mƒc¨´‡$ÿf4Õ¸íBÈïžù{ ªnjñLšb¯jðM¬n/ÃP÷ܱúÒ3ÆÆ'^øç[Ñpxå%¬»i!„cY¹¯(ŠN4e͇. …BÛw½w¢ëÈ×n½¼¥©f00üÞû‡o^µPjûN‡Çƒ #¬^<ëPgwÛ£‡åÎë–’È8EÑuUŽwÚ;6þååç_yÓm7ßpÙEËçÔS½cïÑÓ>?!¤£ëä³[_î¯÷ÿž;V_¶°Å7Ø´ù•‰ñ±xþÇ?4›"”\óŸxæïƒÃãÞÆ–ªúfWMSˆu†h'g4Çã” -Ç:8Ÿ¨p<2q÷|D®]BkŸÝΙ-“§Ílª¯#„ŒO„F‡xž—kؘÇ:x]V¹§¸îCsGGƒ#Áñé Õ÷~öŠ/j9rü”ÙÈ]õ9ÓkÌE³ +g¢Œíy~õ¬ôÄ+9fÓó¯nÚüÊ¡Žcv.:ð©“•üG(š$Ÿfü'S¹ 5ív¥:|÷‘.Þ¬E+$ëp®9*CKBÈð©#ÑÁΈ¹Æa ‡Ã¡Pˆ„}#¾»·IŠ;mæÄ‡“½>»Û˲ËEg£Ñ‹Z&7x„¯ÿøa_ øê¬öÿ¹ç3L­÷šÂͲ_ùÂgÊÜþVÛý´ÁdþÀ‚Öj—òŸ<rÊX¾xþ½_ú¤¸2±X$á2=÷òއŸÞÜØØôäO¾j2lLh$füŦm=ûF£Él±Ûí+—ÎkV÷Âm[vP͵öºj÷¾ƒGýãVÎdùàâ…5®Ïÿà—ON„ùã½ï~áÆ+WÌjóv³«.õýâÔæÛÜÞ*·ã¡o~*±å½Ž“<õ EÓ‚¶Ð —ôëæÎ¨¯rZåÛ%áf¯\¶på²sz÷‡¿ý“¢žÉµÎá©W ó‘¿úŒFƒÜÎ[¶½õ« ¹þªË¾rë56‹ùÎoýw×ɾGïÿZsCÍd¯}ßÑÓ\x¡œ‰¶¼AgfÏó«·h‰P_¿¿o8´uÇþᑚayž§>WIBK…ÀNMh™à‡Ÿ¿*5,ýÞ£/ÊÕ!ãÐrbÔ?Ò±s,ÆN[¸j|x`pß?h#„¾f´­1Zìi? ynP[í?1ʰÜÙK—b9CµÛFŸõúüÞ¦–Á‰3WµÇnr)¹¯ºŸßÞwØdu¸j !¡p¤çt¿·iF_'‚©£óéè:iµ»YË™yt–¥ÃcÁ[®^²ä+×¹çfÐ-fãDpÈæ®NÎdq&‹ÝSÛÔÐ@ahzã/îI‰"»Ÿˆ…8Î$ÑüšjÿÉÑ(O½¼û`K½kJCíDpÄ꨷©EЖ8OöH•Ó¦Ô.á€87G‹ñ>ÿÐë»ö¾Ó~ÄQUË0ô'VÎ_,Ó:A(Bn½rÉÒyS¾¤ä·:»Íᬉêí>YÝ8=B8Ž «edOAõŽ„·¿}`Ùü–¯ßy#!$ã_ܱoÓÖÝqÇ‹Ù% -U ™\ ?øÜ•I_,1¹öÃÏ_uïcWSÿ4BÆG#ÁŽ„¢ê/ZÅÍœ·16sùxç£ÑÀqÜhç›Æ¹«Ò¾~ÑyrÀ?t;¬w|lõ{ž§Š¢šž2ÉÝyb`pxœb6k½Šå¦6ž¹ýö (ƒ]î«H$’øŽDf Í0£!žb4pn§ƒa õÞjåZÅb<k01ì¹øÒÖéW.™ŽDxôO'zûoºú²e‹Z !qžó|B|†bYnx<J‰Fcß_¿!=óLcÙÓ>¿µÚÊLÔYñL6ÿö¯þñãχ#üS/îºåò¹Sj !|œFB‚¶p&c²G†FÚEQ}—œ#£(ŠfYϤ)“uéÜéWÈ·NPeµ\µ¬UyçhŒçŒfš¦v (ŠåŒôYï2'¾¡QedOAõ œññÍo­â™:·mvË”¯Þqõ+æýé…×XÕOŸðÔò<¹sµÜ¾÷þö¥ žZÊIAêv™’uHD”÷þö¥Ä–|îJé:È™t Æ{ÚªÆ>çGõ™çJžÆ úÇü“íŽãâñxw×^góÂ4’Á“Çþúæ~ê񾮼‡¿³¶óä�EÑ“k]Gz|<¹uÿÑÞ½ƒ µž¿õ…ÇûçÏšB9ÐѵïÐ±Þ -÷•»nJj»†k?Ö7©rÙ¿÷•[Û:{?²Xö—\TJ‡¦¾>’˜Š‰Çãqžo5kak˹ýâ$02AY~É…4kèíÜßÝÓ;ØXë¹í†Õï9ÁPô”úêãîŸfŽ*iÒdó§6Ö=üíOwžˆÆøæII1Ñ–Ôîh;Øå ŒT˵KðN unŽÌé­§âqB(šfXƒ‘å8…Ö *Ð#ù©äÙ(ŠI™8o„íë8¥`"ÿÈx&ö<¯zÓ¼·¬^ÐÞÙ34:žxh G|½'<œMüsb Ò± Þ#kßµ­uÉåRs²”äJ™l IKœñûÿã¿>»J®¼~1Ö{dZ5×ÖešÔ:/u‡ê–%Ã=»µLŽÅbÎáá¾ãVo³²9žüúÏ6^{éE [g´4y#ÑXg÷éÍ[_ôus¦™?}ê•k—L[<o楋fŒmÙöÖcÜÂL4gü鯗¯]:]ü•àý)BQ‘ÿ‹MÛn[=¿ufs­×³uÇÞ;®[¡¢WÏYdgÛ‘YÍu+^°î3ß{¨k÷¾Ž]<;ùíK»5V[¦6Ô^{ÙÅ{Þ?úâk»ºñå«/i^|Ñ7­jE¢'z·ílõûê¦ÖP4*O©ÍŸÑXÍóñ¾Àö·ÞÝòêN™æ¹c#ÑèÏŸ~õŽ+H·Kþ§,kàR~R¶û@O³÷½å gJ¶NP v¦)©7^!$Êó &zi÷¡¦j«J{ ª7<š…WÌŸa·š#ÑØ¡c'ŸøÓ–p$Êó±´¾@šÝ÷ÄËûv¾¢N†¤g¸òXÂÜ¥+ÅÓ¾~qf…Ø£=}‚/Â# ¤çPWŸã‚KÖ ø646Òêš5£yddäÈÑ®ÎH­Ñšæu°hxb8à „'‚|4FhŠåŒVg•Õé1Íß©‰‘¡ÐDņ1Xìw c0Mù¯¬ÇÛwó|Ìå­·WMbYŽøàéî±44A³¬Éæ ú !žú©vgU÷Áw’;Ÿ8ônò3EQ]ïÿ›R5©Ùh¶ öv…ÇFã$n4Ûã$1˜­ÕõÓŒfëÈ`ÀׄHœ-¶š¦–ÑÀ@hl84ŒÅ¢4E1œÑh±Û«jM¢GØ|ŠbXÖ`²˜ín“Ån0YDm!©[†}§äÚE3lꉺî‰FÂ&›³jR³Áh>¯Oǃ§ËµNPåµïŠó|bç ¿°·‹¢éºæÙ&‹½çл‘ð„ÕåõÔ4°c ÿ”œ‰2²§°zc£}':bÑ0‹QÅpF»»Æh±›­6©Qpޡӭsfgwìþö÷UuZ(!ù¯¿¯çÜ ±b7oÔ×}p|ÐÔ´Hüº&!Äduìëñ훘˜ˆ„Ã#‘ iÆ"åÓsF³»jÒ¸ÙÇ)ŠIÄqE±¬¢hWUݘÉçyŠfÎΛ8£‰¢(¥¯j9“%eîryë &3E³4ÃB™­Ö`Lœ(uçÔÏ ÃºjM!„3™Õõ<£Y–ŠÄãñX”f¹Ä]ÄêôP¡Ï>¬àc1guÝø¨ÕæŠR CQtœš",ÇIþ_Ôü8!„¦Y™¶ó*,ß.Á¹œÞF†ãhšOŸ,V…Ö *vgƒÉšØÓìpW1 g4'êãô6Ð K3 ¡(Š¢L”‘=ÕãLWME3gƒ”8E1“Y›?˜«Éþb– Z »¿jza2»ëC¤ž"Ä@ˆW] hÎ`uJÏÁS muTeú•«¦Q°…áŒvO]ÚzjÏ͸YUrõg8ƒ½JX¸Uj½ÊL›/ÙÁ¹v pVOR˜ThàtÊ;»kνyÃrF£Ù–ü×q¾‰h†–3QFöTfi»»ª”ä}'&éµPB&O-�e†Åîjo?ÐÚšqd·ÿû»‹¢(-”�! ¢1š­ EÈô@³Í™8V %È…–2�*FË,6£Å¦÷d=²±a?ú� Ùáyd„Œ û7Þw;¬�з߷1©exV �Ðëׯ—-S 0�@³lذA°�@÷@È��2��€��„ ��!����@È�� 'ØLp»Ý’Ûý~â+¿?o?ØŸKPxòŒ©§Î¥ ­+U¥V)_Õ´[‡ç·©¢ÕùµyÞ Ò&…¶FÚ‹®Èc£PBVü±¥æ\ùªO²œRõ‡Â°p»Ýn·;¿U*y5X½BÛ\ÖÐøÀÈ›¥Õà‚ÞQnVÉóæwü Î(öh$wȱù‚2• oL[Éì"¶pîMœWP ¤£-Ù@…ϵ¹ÂhÏÑçUéGbÔ©tQ•û¨øê_9²dÛÄC0ïÝ)w')¦W`qš¯òŒ©cKÁnê"°pA[œ•ãÙÕ_×£N¹ cCBæ>Kq†‘äéŠïi FŒŽ4•µ|%8P›§œ¬hÓøz‰þT^àÚ±sçÈò%sº ׋p7.šõT¶"÷Æ \EÉjkĤZº{ѱåÔ‹…”É{T1Ÿ?”\‹Õ„*ù}œZ!# ]éCËL}Ô’Ü|ŠvWžuʺâ Ô¼´(ï³'ùêk•3,©gIš(ÁåWÈæÅ¿•¼ÚE®@A„,õÑu^¢›Ôˆ=uì*Ÿ=ïw'…3¦Ö-Í%Y¸š3fañ+â.Èo_gDåſũ›Üq1M”QÉ…»ú”¡.^}óõ·ÝÕÝ7”\³+Ä*¬â¿£�H%±B잀Çâp÷÷ttíß…Ÿ(i×[�”2´,cƒó€aa‚Œf Ôl�À#����B��2��€��„ ��!��=!ñYâõ��ЫG¶~ýz� c!ƒŠ�Ê!´\»v-Œ�Ð8.—ëöû6ʆ–�� ïÐ�� d���!�€Ì)“õÈ\.úTX¾<…ŒàÝP1¬[·F([!#xwT�>$Á��B��ú -Õd·äs%ÈÖ@QH»ôƒÜ<ŒàºVsÁ ¿«W<*CöB–<1 � 2õÉ6¹¯Ö¼ó;åçžâ$ój$I—YÚ†%uZl‹TÕ‡ MWqòú_¶âk\n9çKA%2‚.¨$¥*ÙqË�ÚDò²\ãY\Úr*Qz �P±\ù„– <�@w~™¯ë’ ¦Æ�(3ŸK<V4Šô™\«S‰�hÖÿ‹Wv—mA½¹Â YR›Sm‘úd®�Ú”0¹é|…ËVüÒ†øƒJ•(Ah)8½Ü¿b-�è(xT/ÉÅ×¾Ü3ÊÜO-(OÖ¼ó»Êi,„ €2díÚµµf~4�€G¦%°T�•IùxdX6�xdúK˜� ��à‘•ÌŽŠ!Hy A%P1`:¸œ…Œ ‹¨�|H‚92��„ ��Ê ´T³ˆE¦ ]`a �rY”²Q1’nŽL[�ÈdQÊ q>±ÖÊ-)n?2’� *%‹’@nÔ¨R( G*.‹RRÅê—P_LPfœŽCK±î bI¹Ø›`:�úe¹ì 9!“ w®VÚ¸7¹OŽ1�@;>WYeQRŽ“á‹ /ÿ Y”dr€Æ%¬R²(ÉÍInÉ4…�­È¢�(6È¢�Ð7È¢��ðÈJ–j 2A%��<2m€%Ì€G��ðÈJ fÇ@E¤<…Œ ‹¨0\ÎBFE T�>$Á��B��eZæ=‹’ò¢þ�€´ ‹R6*FòEI}�€$È¢”…È¢�(9È¢”^¿Ó®‡‹•ÐÈ¢”M%¨�zôàtZæ=‹T �-ûe¹ì 9!+P%¨�:õ¹E � Qÿ Y”d=­œ¹SÀx ø†,J[ÔgQ‚§€6ƒGdQ�dQ�èdQ��xd¥K5P™ ‹��™6Àæ�À#����@È���B�¨\„“ýxƒ� {!Cš[�€NðÈ rÜ�´Ëåºý¾É1G�Ð=2��„ �� d���!�@È���B��2��€�*›¢.¬(HR™—ÌoÅL÷«ò\ꫤ�U`¢³þ)œ´Ìý2ˆš)Yù´YYó>ÎV<²Ô äyLªž,­lç/D–âbf>α d•2ÓÊhœ ydÊ/é)ˆïÂâÃå<޹’õTð}²»KA¬Åz‘0ZÒt©f̨SÄ_¥-¡Ð¹#Ù®,ŠU9z!IZ÷ÈÄ)×},¾å îi’Å#Iòݪ¤¦EʆJ•’Bt‡J›$*š×^e»Äåg×­Å1HZ5DZ¤~¨�­{db-“»Á¦©r;(l/Ä(É4¿¼vü¯"÷xÚ6¦Jd‘ "ç*«š±$(¶@C”,´LŽå[«^îNÕ3ÓF‰ïÕyôyw5R•Åí­8‘¬B ‡«BËäH%™<øÓøÍ*ÓzúSÈeöJƒžWí’õÎŽ¾Â1½ iYñü,¢ü‚¶Heå‹Pg…r¼W©ßY¥/–_ƒä"‚*ç7µ<8!dy:rsd©SwNfÎhܧ–“ÇÛ ;Éz¦mQ¦a—ÊGfùê ŒN‘Q»$w΢„¼D0 UN˦ÝS®XõCduñꛯ¿í®î¾¡±aÿB×`ñ—º.Zb¬�ÍÆ›0E¦$–º¶8Üý=]ûwÑe?Pà·€ÐRßdÐ�ôEéßì/´¸@¼€Æo´���@È��2��€�@®°0—Ë¥Óšt€3¬_¿^wu^·n:@ÈÀyÿG•éE;˜#�@È�� BBKå<Š3À/Š��š²b&�@ÈŠŠ8¡ƒx½§\’�*­Ì‘ ÖŸ+ÒÌ��´.d�� ×Ð2£��t,d˜�è,´”ó¿°n5�@ëB&™¥kU�4Z ”Hî_±–�€žBK��€� d�� +°™,Xá �xdú«­�Lß`å{�à‘��<²RS~Y” €U"å—E y¡`Y%R~Y” (W0G�€�@¥ ™š¥x2]®Ëû�Pá[dã&?(¬i¡~¹ è�€”jŸTE#¢\–âr‡Œ$�ˆoíjò‰/7¹’ªÙXž¡¥@nÔ¨R(…Š¥^)’‘äžâ°IáÀ´ËVÈ”4…`f�¨¹¬²Þ3»k­´×i±CK±Z bÉLe�Åu§RÚ$lÔÂuÊÓŽ©-L4[9Ǹ@é”��r÷ÑTºlZ»NKZ*G×ðÅ�È£ÿ%~'C¥§&ù2Gr£®SM¿‹Ð€,®—´yÈ$÷Tsõ©ßXž¡¥Üü—ä–LS(Aà�Èô"Êè’Ìn#<2�@acÏ2{™ B@å¡e3iƒe|�¨è ´<€ÉR~«Aa}+X \Ah)Mù­Ì‰µFa2™å·J:Ö}‡à‘��<2½,JåçIÁ²JY”´ß"ô)€¥Y”ÊÏ/†ÊÌ‘� d��Pi¡¥šŸDdô³‰’/€©´cèâ—¤[Iýj¹XÔ�@Ê#‹�@ÁC¥‚¸cjœ²L.¬¼�²(•Œ¼dQ‚Š]¤‚,JùñËHÎY” b�dqÝ©”6dQJ#7yÉ¢ ¿>šJ—-£ë´üCKdQ hþ²(•ò6’ÖLî0ˆA…»]È¢TTÏ6/Y”à©ÝE„,J��ÝǞȢ�(“ Y”��å„–2YE } ZêdQBŸxdúY”Ч���@È���B�€�€žNöãù4�@÷B¦Ç$¦�€ŠÄ#+dúÊ` �¨L\.×í÷mLþ‹92�€î� d���!�€)ño-u÷¶GÙÿdO/=‚Ž@wÀ#˼›‚Ž�ÚìM¬~¡‹»ë† *ghj¹GÐèxd�€2B�€��„ �� d�€JGgkög†¯lò÷i³Gøý~ØLmW•Y’d½_<~¿?™ð6AGÀ#K Ÿ’ý—zÿ‘Ü(çšÁƒÈ—w,¾„>‚ÜFåþEë¹ðÈ å9‹ûI²óà&hÍGPpÐM%ï]»uå0Ù/y뻟Hö†{ÑzJÁÚÊß‚BkBË’ùe@wý%׃°âßûÝn·ø^®ÓKŒÕÑõ 0wÖOLÇÀ+¾³,žÊ¥ídh"˜bÓåZJ^¸NŠvWO{kÉå®òØâ‘“-ÝuY™Ì‘‰{Eù)±BG(’_¥n„_¦‘ŽPވв€Šø.”V­ gÅ隌lûk¤#Ê G*ô'Jp�('*QÈ0Í@™ÁêºöÙ¹Ç0�à‘��„ �� d��Š&æÈ**/Ž.@ #à‘erj ô:Yfµk×¢´z �� d���!�@È��@'û].Œ�ЫYî=rû}a�€ö±8ÜÒYê“þqß���$IDAT�� 3¬¿§¶��è*_rÅ-0�@§ìÞºéÿပýŒ´D����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/rgb.png�����������������������������������������������������������������������0000644�0001750�0001750�00000007374�11332353406�014673� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���©���Ð���óšÖq���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚÛ).÷��‰IDATxÚíkpÕÇÏ®v%Y’¥•"ùÇØ!1ñ#@bB I&SBžÚ2-¤%chICé Ó¡¦hx¶é‡6Ó &tB;e:@)žI°Kçaâ8Nb'މ-[²dÉÖsûAF¬µÚÕê½Òžÿ胴Ú{w÷þöœ{w÷ܳ˲�°hõZ@)Fïí��*þ¶»6`‹(G‹V¯íxoqÕª;o»kÃŶˆr4Ðwªÿx;ùᛜÀQš½T¹ÇF}ž¤½£Fo,5YäSCö~ß$Ò‘oÒë󸚓-x¼« �4ZjˆYN~û…ˆù v}A ì›1~Üäìíÿš¿Bäãu\„¾Ïú$´Bq||wScS ››|·Ljà|8vODÌIQ6w‘oðàn[£R©ÞÞ¹«wlXϔŬðy/Ñ8 ¢þj~ Å$‚ R>@‚£üÖßçóÿ 5%¦þ;þ¹äÚÅ óêÏ|ðqHo¢ÔÚi5Žt‡ ”WWc1˜ŠÜé¤|rGÚ]5Äe·R½¹ìÂÙáöö›Í:·væÁ“ûË›¿õcýG+J¿<5ZÝxEÑ÷÷iÚ¤mµ©AÈîɸeluó{Žìu¹zI’4©|ý‡Ëæ´�€{¸¶ö=]ÓrƒPÙâbO¦Ñîä·Ÿi5<sÿ¡"?û–ôbVŽ»0R\ªÏªªyYû[Zð@8<æÔuæ “ï\W¿½jþ*’TI9þ§î»µ¦bê2# 9Æ?=tj÷¾c,ûíðÂRzó’æ¦Ù•£�ìcžžþ¡·?=rqÔÍ/nóttõýgïáP(œCŸO¦ã4’ªádçú+¿'±†gî_óðs;§¾ÿêV±¤ûü©+J]>ÿúáCïÐ* IÂÞû•ÍVæMè.¹J]¢—Þ��`wŒõö]˜UYVU>ãŽU-ƒƒgF�ˆ†ºŠ×^§¦©`0ÔsvÀ31Yi³,[0§£³k`ÈOÑšHño쇺zlfñ• ·.›?4<ôñ‘ó9AŸ}ûúßñ×cëc¬Q¨†ß?ÿÎÓ÷ÝAý­–_CÒv�:£E_»È×ßîõ…X•VGú‡ÉŠêòšd�� ³«wóÖë †ýu£FMW0Ún§‘±nøáR5M»0´qóÖ¡Ñ1Z­%I²ÌR}! Íh"ÅOôöÿíµj­~ûŸ°˜ ƒÆã)5Ûr@?{£ôy — ž1jxäﻞÚp3�Ä€©V|œŸÀ…½£a|¬z¶Í V«é‘T7ݬZ§khl¢) �zÎø|“—VÛÌ¥:�ØöÆG]¶ê¹*JņY°a6HSËNíõ¼Kk~sÏí•å6‹Éàð}ðùWÀ$˲ûôà“iŒ±I‚ kª–»\´†G^x÷©_Þ4 |˲øû¬Ï�×à©àèé@I™Qíõûý>Ÿüv·}f©mVR°bÉÂK@ záõw?ë8Ê”Í2¦®/\´̶fã³ïˆ,9Ú{áϯí!È©žYaYa|·;ÆX J & �²k!{£t¡j¥øüˆž\#·¿xtën‰ã|’ïUbäó8ݽ¼!ªváJËeK]ã'ð;»?õOŒÒ±üÁ¡‘½û{¼“4¥ZtùeŒµR«/óNÝN®*³ªhu0L|ØÑÝ7p�&=nÇà’$#Å÷|qpÅÏ~»fý£GNÔT•m¼÷Ç@¤JE¦„Z>!®¢à£C‡'×ß(qÓ úûp0àéÝQuÅJZSBÛªCõK'NïÓhÔ4MŸÞ¯i^)Ýùwõôm~éÆúÙyèž«æ×¯º¦q_·ýì Óáò˜úu?ZõôË;ýðk»Û×^×|ÉÌr�³á`À­Ak0l3¿qú� ºÂ:fИ\ÜR䱟øÅ*¡u{éý$ÆùB­Ç].PCt"à{éýÈ’'î½!þ>$ÕßOœï´5C¦FkUd‰¥ú²a¯£¦4@Ó4˲çú˜jJïðiMɰ‡øìÐÉå-ó~rÓ²OoSÑå/¾¹ÿ;–×UW<÷ðݧ/ŒCáÚJË´ÂÄTÿëŸÞl1[Zj�àxÏÙ ß úÕ¬®ï»Ú÷6-¾.áÕytH/Áç ÖÙâ^þàñŸ¯Ú‡$ú{ïÅS³­tg¿¶²érî Ö¹‹]ç;ZæÖ„B!“ËuÂÞ§·ÕJoG­Þµ¿{é‚zÆhX}uÞ£ƒÝ£nÞ~Ëò+6Í™Sm ‡Ù¡ç'_ÞõÑnÁHϲ¬ÃåùßÑî_G­Õ±,›—þ~Ó¶Ø#\üÞ:ƒ54_³‚¿0õk<¿{¤Vï=Ù?ZÞ°<:ÚšZY¥ Øš¼þ±ysêÜn7{¦ÿ´wL£gDÚîñmžë> øµ�ŒŽî|èù‘oÎ� K™µªnœÕl}ósÿŽÝþIO8‚PQ”Z«306‚ ¢Å¿;T”ºÄÀØ* B•+Ÿ»•æk¯Oón|–jˆ³0©g9ãösÝ£ÚY-­á×®ÕxÏÛMNNü~wÀ£Ó"¾ÿ&[µŠ¦IR9‰ f+«uz�´¦Ä<£r¢Dϲ,A¨’�`€$)Z£%"Z|š QQj­Žý8_ÖÏñø#Ž—&`Yb®òA °IؼÉZ9 ¥fÊ«§]rÐj½É*±xîïè§Ñ³DÆhr¨!ùûz(])ÓÕu¢©©!Ù‚Ç­+e‚C È>iJô‘FL¶`‰Á)+‡R¹¯‡�ΠÑ ½A»÷ºȸÈ;/£™g÷�^—cû¦uØ:Å­u›¶Gñ“ØÊÑ–-[âõ÷9Nl¦âS[[[Ì´{å Ù#{²G!{²G!{²G¨d ˜Íæ¸ËGä/‡#ÃbªþÌÒæÄ·ž³²rd%›ý‹žjf³9f£²mÓ¢µ{‰g7×=¤ )Rœïo¸Ûå;ƒ¬º‡¸G'~È2ôdöŒÕápaK­ª'sÌ_iîƒÄ£?dy:*M*²:>þ¼ì^\(Ã*‹ý}¦L-ƒ&‹ÊpŸ¥ñ ß\Ìfs!žoÄ«ÿõ}.ÉäÌàrÆÇòe=ÔÜtuÑÍeoCfŽâ]ÂC–!~*µ†Ž»„ûWúD6$es™Ú™¸e%.”ù ‰b¸§[ ã�d_x] Žó別8»G!{²G!{²G!{²G ^ßó'í¡a÷1ÓtQJaàíó[[[±QŠU ì۴Çz(dìQÈ…ìQÈ…ìQÈ…ìQÈUÀ¢Šìx28ï_úæ’ÝPÜ©†¹Üí"´ûLÍûÏ—¢{ŽvŸ– Æäã�áÜÑõ…–ƒ@’‘|0 ÇLí©\üX ùýÊíï…’zˆ8>­,yéÜ80Eõb|lB—›ßÙ?ÏæB)¼ÈÏlâö,âž ûûüœ¹éwr¼d‘ÑâvÛ1]ujl$L¡~‰Ãî>p³L¤Ÿ>Ž,>cåNÆN!%GR3º³”ò#7³Ê‹ÍçKI ’0FRY<2˜ÔCJ® &7Á{ºÊ²Gö(dBö(dBö(dBö(dBö(dBö(d/_1 Ã0Œ’Ù§ò —§ ña¢|rœ3 ãt:¹_ò¨„‰Í²”'õç÷ÜwÊðE@RÀ€Óé”þºW;…þZsè•,í^†c7D^)““ƒOZ&ø »¿a¤fÉ1ŽàÇþ>-ï#ò‹_ܸhý©Û½ÐLy¾¹¨­­-!W§Ó©¨|²éúü¸“Ç¢’Ïq¶¶¶&äÚÖÖ¦¨Ô’Ùº¾ç[Þ8~¥Ï0{ñFÊÁ áW øÇzÉF•go¾jÊø¹¤• ”9‹_&à×zÙçÚùË|kkk^®-•;³Åã3\dBö(dBö(dBö(dBö(dBö…#ŒÏÏL¼È& W:xŒÏ§Ò_ !úŸŸ:{~¼=?_$=ˆ&‡Ïv0?Æçg·¿ÏE/=A}ÀsñcŸz¯Ï÷É"Ìj¯ñù¶û¸±Øü\ôü“ ÇaüŸŸy»OÙšs<0ä‡hÆ=?0>_Ëd­6ïÖñù™ñùÜP|‘«;ñˆýÜÏÏÅøüÌøü¸QúRrÑC’ ê³íü1>_AÂø|岌ÏW2{Àø||†‹ìQÈ…ìQÈ…ìQÈ…ìQÈ…ìQȾÔÖÖ¦¨(¾2™?_Vù²‚„E·AþŸãaþü<€€ºW;å€?/ñùÙŠÑæ†iÇ|Ïo²e.øïð+Òù箿 ËÏ#x%ã'Ó4îBìã…¼®Òð§›??Y#ΗÃgF|¿¢fçäú/_ÙõNg˜¸ìª”È^ÈÄóbýâø•>[ý}Üœùy ËOˆ_à!#ùóã.›3_CÂþ·Ü­pð Ì8].~™€Çøü<89€Çøü<àe Ÿá"{²G!{²G!{²G!{Tá+öÞŽÂSK+šý–-[°QŠZAö˜‰¤ˆÅ0̺MÛ±¿G!{dBö(óe;H) 6-”È�´û «€.’)´§ ª°fö ÝãX…ìQÈ…ìQx}_XŠyk_% @»Ï�øü&ø@»Ï'ø¨Ñﵫ\—ìB´û¢r ɾ´Ùùi>_I QÜcd{9ÀMRÜ>€,V#ŽnBÛM˜&¿É ‘}f|¸ô÷óÊ!;úüÔñÇý)ý…ìE?èÃq¾r…ì‘= Ù£= Ù£ŠW…t§ðW)×îqr¸BíÞétâäpìïQÈ…ìQÈ•öXól)‘½Îh>èn.TñIg4Ç·{î(¥Øýðù^l ¥‰`YvÑêµØJSÇ{;þl×1ºþµ����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/index.html��������������������������������������������������������������������0000644�0001750�0001750�00000032323�11555611701�015402� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Create a True Color Image in an RGB frame - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Create a True Color Image in an RGB frame</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> Most astronomical images map color to intensity level, e.g. lighter tones may correspond to a brighter intensity level in a greyscale image. An alternative way of presenting data is via an image that correllates color and energy. </p> <p> ds9 has the capability to create an RGB image and interactively adjust many of its parameters to achieve optimal display results. </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li> <strong><a href="index.html#frame">Creating an RGB Frame</a></strong><ol type="A"> <li><a href="index.html#frame.cmdline">From the command line</a></li> <li><a href="index.html#frame.gui">From the ds9 GUI</a></li> </ol> </li> <li><strong><a href="index.html#energy">Apply Energy Filters</a></strong></li> <li><strong><a href="index.html#smooth">Smoothing the Data (optional)</a></strong></li> <li><strong><a href="index.html#scale">Adjusting the Scale Parameters</a></strong></li> <li><strong><a href="index.html#coordgrid">Adding a Coordinate Grid</a></strong></li> <li><strong><a href="index.html#output">Saving the Output</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#rgb">Figure 1: RGB window</a></li> <li><a href="#lock">Figure 2: Lock menu in the RGB window</a></li> <li><a href="#ds9">Figure 3: RGB frame with three files loaded</a></li> <li><a href="#efilt">Figure 4: Energy-filtered RGB data</a></li> <li><a href="#smooth">Figure 5: Data smoothed with a Gaussian of radius three</a></li> <li><a href="#scale">Figure 6: The adjusted pixel distribution for scaling</a></li> <li><a href="#grid">Figure 7: Coordinate Grid parameters dialog box</a></li> <li><a href="#color">Figure 8: Final three-color image with coordinate grid overlaid</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="frame">Creating an RGB Frame</a></h2> <p> To use the three-color capabilities of ds9, the data must be loaded into a special RGB frame. This frame will contain all three files, stacked together in separate layers. </p> <p> This thread uses Chandra data from an observation of Cas A (ObsID 198); the level=2 event file is named "casa.fits". The same file is loaded into each layer of the RGB frame; different energy filters will be applied to the layers in a later step. </p> <p> There are two options for creating the RGB frame: </p> <div class="subsectionlist"> <div class="subsection"> <h3><a name="frame.cmdline">A. From the command line</a></h3> <p> The command-line syntax can be used to create the RGB frame and load the three files into the red, green, and blue layers: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 -rgb -red casa.fits \ -green casa.fits \ -blue casa.fits &amp; </pre></div> <p> ds9 will open with the three files in one frame. The <a href="#rgb">RGB window (Figure 1)</a> should open as well. If it doesn't, open it from the "Frame → RGB..." menu. </p> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="frame.gui">B. From the ds9 GUI</a></h3> <p> To load the files from the ds9 GUI: </p> <ol type="1"> <li> <p> Launch ds9 </p> </li> <li> <p> Choose "New Frame RGB" from the "Frame" menu. </p> <p> When the new frame is created, the <a href="#rgb">RGB window (Figure 1)</a> should open as well. If it doesn't, open it from the "Frame → RGB..." menu. </p> </li> <li> <p> Make sure the "Red" band is selected in the "Current" column of the RGB window, then choose "File → Open..." in the main ds9 window and select the red file. </p> </li> <li> <p> Change the current band to "Green" in the RGB window and open the green file. </p> </li> <li> <p> Change the current band to "Blue" in the RGB window and open the blue file. </p> </li> </ol> </div> </div> <div class="figure"> <div class="caption"><h3><a name="rgb">Figure 1: RGB window</a></h3></div> <div><img alt="[The RGB window indicates that all three layers are visible and Blue is selected as the current one.]" src="rgb.png"></div> </div> <p> Each frame of the RGB image may have different binning, scaling, smoothing, and colorbars applied to it. You can "lock" the frames together, so that the setting is applied to all three frames at once. This is done with the <a href="#lock">Lock menu in the RGB window (Figure 2)</a>; all four options are checked in this thread. </p> <div class="figure"> <div class="caption"><h3><a name="lock">Figure 2: Lock menu in the RGB window</a></h3></div> <div><img alt="[The lock menu is expanded and all four options are checked.]" src="lock.png"></div> </div> <p> Use the binning and zoom options in ds9 to adjust the image so that the full region of interest is visible. <a href="#ds9">Figure 3</a> uses binning=2 and zoom=1. The "Scale" is set to "log: minmax" </p> <div class="figure"> <div class="caption"><h3><a name="ds9">Figure 3: RGB frame with three files loaded</a></h3></div> <div><img alt="[The data is loaded into one ds9 frame; the RGB window indicates the current layer is Blue.]" src="ds9.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="energy">Apply Energy Filters</a></h2> <p> The following energy bands are used for the RGB layers: </p> <ul> <li>red (soft band): 200-1500 eV</li> <li>green (medium band): 1500-2500 eV</li> <li>blue (hard band): 2500-8000 eV</li> </ul> <p> The values are just guidelines and may need to be adjusted for your analysis. </p> <p> To filter the data, first select the Red frame from the RGB window. Open the <tt>Bin → Binning Parameters</tt> dialog box and type "<tt>energy=200:1500</tt>" in the Bin Filter field. Choose "Apply" and the ds9 display will be updated to reflect the energy filter. </p> <p> Without closing the Binning Parameters box, select the Green frame. Type "<tt>energy=1500:2500</tt>" in the Bin Filter field and choose "Apply" again. Repeat these two steps for the Blue layer, using the filter "<tt>energy=2500:8000</tt>". </p> <p> The colors in the image, as seen in <a href="#efilt">Figure 4</a>, are correlated to the energy of the data. </p> <div class="figure"> <div class="caption"><h3><a name="efilt">Figure 4: Energy-filtered RGB data</a></h3></div> <div><img alt="[Each layer of data has a different energy filtered applied, correlating color and energy in the image.]" src="filtered.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="smooth">Smoothing the Data (optional)</a></h2> <p> Smoothing can help bring out finer features in the data by removing statistical noise. It is an optional step; experiment with smoothing to see if it improves the appearance of your data. </p> <p> The smoothing capability in ds9 lets you interactively smooth the data. Note that for quantitative data analysis, smoothing should be done with the appropriate data analysis software; ds9 does a nice job for publication purposes. </p> <p> Choose "Smooth" from the "Analysis" menu and the ds9 display is updated with the results of smoothing. The "Smooth" option can be toggled on and off during your ds9 session. </p> <p> Open the "Smoothing Parameters..." dialog box from the same menu to adjust the function and kernel radius of the smoothing. This data were smoothed with a Gaussian function with radius of two. The results are shown in <a href="#smooth">Figure 5</a>. </p> <div class="figure"> <div class="caption"><h3><a name="smooth">Figure 5: Data smoothed with a Gaussian of radius three</a></h3></div> <div><img alt="[The smoothed data are displayed in ds9.]" src="smooth.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="scale">Adjusting the Scale Parameters</a></h2> <p> This data is being displayed with a "log: minmax" scale. That means that ds9 stretches the scale to encompass the range of pixel values in the file. Adjusting the minimum and maximum scale values sets a threshold for the background data and brings out features. </p> <p> To change the minimum and maximum values, open the "Scale → Scale Parameters" dialog box. The pixel distribution shown is for the band selected as "Current" in the RGB window; when the a different band is selected, the histogram of pixel values is updated to match. </p> <p> To adjust the values, use the cursor to grab the red (minimum) or green (maximum) vertical lines on the plot and drag them to the desired location. You can type a value in to the "Low" or "High" field and hit "Apply" to set the limits. </p> <p> A basic guideline for setting the low value is to minimize the contribution of the background. That is, adjust the minimum of each band until the background of the image is flat (i.e. solid black). For the maximum value, bringing it in to the last data point in the pixel distribution is usually sufficient. </p> <p> For ObsID 198 with the smoothing applied, the following limits were chosen (listed as "low:high" pairs): </p> <ul> <li>Red - 0.4 : 20</li> <li>Green - 0.3 : 35</li> <li>Blue - 0.1 : 10</li> </ul> <p> <a href="#scale">Figure 6</a> shows the image with the new pixel value limits set. </p> <div class="figure"> <div class="caption"><h3><a name="scale">Figure 6: The adjusted pixel distribution for scaling</a></h3></div> <div><img alt="[The background of the image is almost completely flat (black) after changing the scaling values.]" src="scale.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="coordgrid">Adding a Coordinate Grid</a></h2> <p> To add a coordinate grid to the image, choose the "Coordinate Grid" option from the "Analysis" menu. Then choose "Coordinate Grid Parameters" from the same menu to open <a href="#grid">the preferences dialog (Figure 7)</a>. </p> <div class="figure"> <div class="caption"><h3><a name="grid">Figure 7: Coordinate Grid parameters dialog box</a></h3></div> <div><img alt="[The parameter box contains fields to set the plot title and axis labels and to change the axis spacing and numbering.]" src="grid.png"></div> </div> <p> From the preferences box, you can change the color, font, line style (solid or dash), and line thickness for all elements of the grid. The font style, size, and color can be edited, and you can add titles. It is also possible to turn off the display of individual items via the "View" menu. </p> <p> In <a href="#color">Figure 8</a>, we have turned off the grid lines and border. The axes have been changed to "Exterior Axes" (from the "Type" menu). </p> <div class="figure"> <div class="caption"><h3><a name="color">Figure 8: Final three-color image with coordinate grid overlaid</a></h3></div> <div><img alt="[The three-color image is displayed in ds9.]" src="color.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="output">Saving the Output</a></h2> <p> Once you are happy with your true color image, there are a number of output options in ds9. </p> <ul> <li> <p> <strong>Image formats:</strong> from the "File → Save Image As..." menu, you can choose JPG, PNG, or TIFF file formats. </p> </li> <li> <p> <strong>Postscript:</strong> to create a postscript file, go to "File → Print..." and select "Print To: File". </p> </li> </ul> <p> Currently it is not possible to save the state of the ds9 imager, meaning that you cannot save the composite RGB frame and reopen later for further analysis. </p> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">04 Jun 2009</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/smooth.png��������������������������������������������������������������������0000644�0001750�0001750�00001160052�11332353406�015424� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR�� ��O���yÐÞ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ�2J‹Â�� �IDATxÚì½ypdÇyàùË|/ó½Wêhú*6Il’ Š—TjA´d[¤([ìõ¬VK–íñ„ÖÞíh½a{v,¯™Ýw;ò1ž¥4¶ÆvX^[²n¥¥ ©Dê„IH”ØÕ,²É> (�u½sÿ(«Ñh4èÎ_t0Š…ÊÌ/¿Ì—_~_æËI’�<ü“ ƒášçÉO}°{†á­ïx·ÑˆÁ`0xø'ŸüÔ‡Äý½ý­ïx÷ËgçŒF ƒÁðÂ÷Ÿ=ñôvﺶшÁ`0zÛ`0 ÛÏ|£Þm^D<ÆIdsÅ+›v Ûàw;Ë¿=9õ…ër"—Ë…aø½9]<rûš™¶f^JÍ}÷û3Áõ¯øAÓ ƒ¡?Ûnu›swŒŒl>ÉÓSS€ã¦®TÚµmB,ÿ¶tË“_{×[ßbYÖG>ú±ãÓ©üЊ”A·}}ªù û>°"¹Á`0\Ó¶¡5Çw\T’;î¸ãé©)ÇK_©´kÛqþà®·•¿åO>ôg¯yõ«n¿íè÷>ó¹(³µ»ü7òì·£Œj¦Ž39Ó ƒa !„¸ø³XÆÎ§]Ï6ÈHö¿øÜ™'žx²T¼å†Ã_ûNuÿ¯‡Åô“#¾ül½<r·é=ÞöÐýo~íèg¾ü­üí—Œ6 †kÛ6È-Ѳÿï ¤Ý”ßУtãßüÜÜÜq)eÎêž>þ¡›ïæOŸ.ð¥8~ä¾7^PŽCƒ¹ŸzÓ«n92¤lkv¾ýüËõÿü‘/Î̵úåò»ïùGƒù ð¿þÞÿûâéÙ¥„÷ÞväG^s瑃EKÊ—ÎÎ}î«Ï|æËßJ€ÿë½o+ ¤~ÿÃá›ÇwQo@�­¹úÜÙ—rƒ×üÍõŠoã+o¹®'ÉSϾøÁW—Ta0®&ãÀªÑv“øi矽e½Ÿÿòÿý7›I{ÞÏÖür¿a½ƒƒwŽ=ÿÄG\º@7fR©Âþ\·6uâô¡»Òº`MßûއJ…ÌK§gj/.ä2wßRNÚ³Q,-K·^¿¿g€»¯Ï8ù²­\à¡ÊíïxäUÀñ'ÛîÈÍGÞñ¦Ê¡}™Ç>þä’ï2sê…v³áeò»Ç8ôH YËÜfRÎ/ÿÌ#iOòó_$¿öþ¡|êWÿà#`™GÉ`¸ºLÃc;\L\è»ß¬}Å«/˜öwþÙ[~å?~¤÷ù·a|½´›)õ°lgÿ]?|úë«,¤gU–†‚¨ºþíe.(ú¾\ºTÈtýà§ßûo!må ¤f³™*¶mxÍÝ7Ï>÷ÂÍ7þ¡c÷üÅg¾œÝw(ã9oûáû€þÕ§?ðWŸ¶µûê{nß/þãzÕÿÜ“§ÛçDMâø¿üú»€Çþ¶úæ×Þåjõ7O~ïų?7þê}¹ô—Ÿ~î?ýÍã8þùÛ^wóuCÙ”ã‡ÑñÚé?ùä“/œšn92ôso~u©™|öŹ…öëï?úwO<óÁ*dßþðý·ß°_ÙÖwŸ?ý'Ÿx¢vjvEo½~ègßüêÁübòå>ÚO>üÀ±Ñ³)·Ý ^8=û{ñ¹£Gö§=ýüÉÓÿÇüW/“»çŽ[Ž*Ý4è? Ìb¾Á`bJkÇ…~âŸþòêÿåþÎòÏšiõýý­ÿñÍ=“°ôy)Ãi/"¦Ô#5PLßð@÷Ä­n”XnJú§åòþ#›©êB«ÛñW«ßü—?ûÝ“ïž8õÌs/¥Ü‚eY ”m=pÇõÀû?ôÑ_ÿ?½°póá}/·“Û®? •$É_~òñL¡”É—¾óRûäéÙƒ¥ü]7úÄ“ÇW¤o}ðÎéNÝ{ûoè¾…V÷;ß©õÆî¾©úÕ§þáD! ™ÇŸœ<]Ÿ}Åm7Þ{Ç-¿øcï}ôÃÙ÷¼ýõÏ™|æ{͹ù×=pÐlœ™=óâÁÃ×ÿÊÏ<\H=þ•§ÏÖgÞòÃÇ~é?ôKÿ燻ѹ²=Gý‹ÿáõiÏyê;Ïu𠝻ïÜö€»n>ôȱ‘ï¿xúßx<r^1rs³~²»?ìËgˇöº1—M7_·ÿ©ç¦ÒÙ‚±ÃÕå7È-¥k¦½íÞ±õÌÉÆiÿÕïì7ßý#À ð<Ë[‹^NÜªÇ ÝD—2Zkm¶ÚA”üþ_~þ§¹ïÑ[xùlãÑ?ûÿNž™CˆWÜZN»zvná›ß:þµo}ÿÁûnûÁÊÝ}ìÉlÊ:]¿Ùêî/Ý ¥m)k¶Ù9X"7î´æWô»ü—_úÆ·ÿŸ÷ÞòÁO|îËôçïÏ¿íá×Þ{ÝÐ@õ©ç2¹ÁßøãO=ü©L&û÷O~û¿}Ó¡¡"³wßw[ÆsÎÌ4þåo½ßÖn&¾÷Ž›zîÈ+Ž–‹©çj/?úÇ¡½Ì‘Ãï»ã¦»Žäž|vFÚj1vK9í9ggçÞó›ÿÑRÎï¼÷gî¹}¸÷'G)`~¡ù©ú˳­}âKÝvË—ßÿn9ràÿûÿôÖN<× º-²…-ô$ƒÁ°[ƒDŠ-¤B®v½Ü–¾_?í¿úÃÿæ?}Óy†áþ×®Qîš¶aƒæN>Ö§oh@·|ßïv»øgæÏΖ®ÛLe¿ñìÉÏþë?8˜sî¸åÈ÷Æíß÷È7þáGŸ°µwì®/}mJHë«ßyáÁûnûWÞýGþì|» ¸ŽN§=aIiYQȦÆ|3Ž"’•¥?ñbnð`'L€ï>Wó²ùP*@)Ûï¶-[üô¼òÞ[<í9KI´%Ò® ÔNžFXŃ׿Ü8*æRÀ åýõþ__úòÀ`~þ«Ï è…€rÙðü‹§rß¡NÖ[÷ô9y¼öÕ©ïÝ{û w½8UŸûwøøK3íßzìS#R‡† 'O=v߯¹ïÎÙ¹ù$Žc˼#b0\U~Ãv®7¬—Û²¸ÐºiãçY‰úßþèk–»Žß°ŽQêÌÏ̯¶"{ø¾7´çÎÖÿá3’˜}æq'û'•ݸªÊ¶î>ø5¢™æÂçŸ~q_éÛ?ù¦×dÒîÌ©®¿åö»o9 <òºW>òºWö~ŸN¹÷=üíï½è¡Vö¿á5ŸùúóÒ‘£7:°/ |eòËZcå6Š"ÛqzJ £H9®ì¯“'IüšÑ_ûŠ›^<Uÿ÷¨Ùjÿû_y·”RQo,�‡”´ë"䑃KÎ̵/¾ü{üë¥/ë³óQ$I,-˜kv€R1o+G ÷ï;÷žGÆ¿ûgŸõ/Ìý÷oú×ÜwÇ+o=øÑ/M[–ó•ï¾>ýýLJÿÂ;Þ |íég…¥ë6Á`¸†bJrí˜Òz¹SZ+í¿ù'/y ½%ŠßøùGþõúÔêr/"¦‡AsúKqè)'¥J©èèkÛÓ_p­”Z8^uîzÃÆõ×ÊþŸþÑk›WÕNÍ& ·”o~ëxGÜzmÉV»óõ©Å}¨7ÞøÀà¿æÞßýÓ¿û‹¿ûêO=òªwýÄï}ÕËòæò ðéÏå[ÇOì;tãÚ¡y!—­èžg{BFQ¤•~ÝrQæo<sb¾Ù)sÿþ—~¶rûû—’|í™çë…#‡öÿÈë_ýÂÙ…Â@úî£Gþèß]xîe’Å ŸúÞKÍv÷ðÁ_üÇ?â 瞣å¥äwÞtè-¯ýÖt­ÝñË÷¹…¹™—û~×ì|«ÙîÞû‘´ç|þÉøöñûÝ(·Ô“ Ãnµ ç­ ÿúÏ=´Þ/í?}~ªµßQ؄߰FÚ¥r{¡¤_ûãO÷¾ù7ÿäáÕå®gÖ(¸]ûÆ`VŸ¸g ¿[¿xÝÑÓ­ú‘l ”J’äùï3wã½(Èâ}ñé›9¸ßÑêììÜßñëöÑϺûŽÞ|ôï«ôçŸèåq×Ñëÿí{ßõÊ»o³ÿËÇþî+Ï>ÿ|íͯ»ïæëY–<ñâ©îËõÉÏ{™œr<Ö[·k~ä‹ßœ¾µ\xàŽáþ®·~ìóßìt×Q@»ëÿ‡ý·ŸùÑn:rð+O}÷3_øÆÃc÷Dq tüð·ûÔÝzÿ]·<èº3óÍoþÙgŸjÀ²UO]ínøþëûéGxhì¾§?ÿ…o<óÚ{oë•8;ß–‚7TîH¹z¾ÕùÄã_ùëOOèLáÔÌÜ·]—öܳ³óúèg?ðáOº©åxÒ²…‰) W‘qØäIBOù³wT~p¹»±:mo¾¿nA¦]2 ½R~í?æ×ö k—»"ãÞý ß«Zñ‡ÖËÏ^ï6¾ybþÐ?°¼°$ŽÃÚ÷Ýv$Š¢ÆÜÜ3tzè† jÇÑËß& ‚0ì&q"-ËËä3Å’VîË'žñ;­tn_¶8Ô»~®Ûnξü¼@ì°Ð8ÓmÎÝnBbÛÚ(¤Š–­µã~êÉ8Žò¥CÙ}ŸÿöWÒuGÓùÚw¾ÝüPy`ß³/L7çê©bñÀ‘( Ξ|Îï´¤´R…æìÙ$‰Ë7íÛ7ôbí{í¹z¿û«¿p÷m7¾ÿO?úñ/üCñÀ[éÙSµvs>è´â8¶,ÛvÜÜà!/íÅ”z«³'¿ßžŸ ÃÀqSBˆNk¡WbèwΜ|. ü$Ž¥´œTf`ðv¼Ó/ï¶’(¶lËMç³…’¥´v<ó4 W 3/ÝqÇyG”>õ¥¿[ïÇw¾ú‡íÄÓßÊ ¸i—~¶æ—½´K9U;wà SãÏŸ½>ÕüΉúþ‘×!Ïó5„eÅ¥;[þìm7ß8??Ÿ|ïÄt³á¬ÿš”v~¨Ç¡@aõæó¶rlí ”Ò’–m+G9. ””–vS¸©ËVÝÔ€RZ²ç híZÚrCeízBH„È•Ýô@¯¹¡Ã¶¥„eÙâo `+„›Êæ#è ënzÀVÄO=r¿à¾çžéæëÜ}Û ­ößñk¶JÒÊ•k¯‘¤°„ ‰ÕËüœgåK‡u*c[JH™$I6 -[ÚËJ‡¥´E_xËV¶Ö¹}ã8²,»—‰ÒÚÖÆ0 W™Û°r&~×±7l&ÕšëÉÛžvÅ—¿ûvÞΜx¦5ã¹ßVÎê|ÝôÀSg[µ3Ou: ð烖›½o}‘Ie×¶Åý+¾QŽ›/Zú_í¦ôª“c{†/}.8÷²Enß9ëg+½<I¦0¸:ŸÏ̽þ7¼jäúv×ò©gÿàOÿfv¾9X>(¤BX¶Êä7nå¸9Ç]óOÙUÒk•n0®Í˜Òj“rÅÒ®SúþÉú5Ûˆ§N<Óœ›£PJi;Þ@qH9ž›ÉK³�`0¶„ßiµ+Â;óôÓßò29í¦®TÚ¥oΞ|î\LéZ^ØwÐMç¤m÷Vê¥e»^FJ³kÈ`0l‘ÞuO?ý­Í'ñ2¹^ª+•v~÷íªÇËæ½lÞôfƒÁ°æ!•qR™½•v ÛÐóZs3¦E ƒáÚ$5PXå7@knæƒï{§ÑŽÁ`0\›¼ó}\2&ªn0 }ôÑåÿk¯þÅìì¬Q“Á`0\;<öØc+¾1~ƒÁ`00¶Á`0 Æ6 ƒÁ؃Á`0Û`0 c ƒÁ`lƒÁ`0Œm0 ÃƾØ…BaÍïgffzš™Ù¶C™V—µ"ó¥—})b¬N»\†m¬Ú¥×ýʲžxÛÛÖìlW\+¤ºXy¶ý1Ù|G½LEoc§½Ü®(bƒqcM}^bÓ_å¶a畲™².·<Wªìòηü™) 333Û+ðšSÝ`VW|÷HuÅEºåì’¿¦>wgÓï:ÛpASY§ÛëÍî—Ú¯÷ÍÊíå°”v¿d½Éòvy0Ôzue——¸üûŸw²iÖTÝöN÷.X¯ÍhãrÏÜ7Öö¶´Å o¹èmo²M*g½Þ²Ã^PŸ×ò²*wuoûè³Þ¼ãr÷›ËQµ‹zÆÖ“dùü}Åç—…•ÝÞ8Àfêµ±6¶<)îM V—xQÚÞ™Çäb‹¾]bcå¬YâÆ^ŠÆ664Ökzã7¬=Bí€vÖ›þ¬×«®ˆ½ÚÁÜ–©ÍšzÞ==ò‚ÓÞmubЗhvx‚²cA¡ËÔ+Ö||v8î´æÓzéMol攲]÷7Àš±šËTµ-Ô} zšæª½nÐO6®øU½Kæ7Ûø¸­7©ßm5½ÜMÚ†]8¦_¾ñî¬Úz‘Ù«¬ivÛm¹<œðn¦®ÖÁeµ3½«<¿5—·±é¯ä<K—I‰—oF¶ÉÞ¼¼j+"Ú{Âå¼|Msµ†Ë§ØKi‹ÕK,»¹YW‹·;=§½¢Ï=æ7,™åm™/¬ˆð,·ùë-G_¾ÇöVm»$Y!Õ•jšñá֬޵ËjUo ÀÆm´2¯™Õ™ïp7ÞX9k>ÈWöAÛLãj_o÷?ôö·¾ãÝÏŸj,Ýmî}3 ÆA¼¦èÝûöµÙbj pºvüÄÓO˜33 Õ±×f¬f¯`lƒÁ`¸\SûA÷"¶QÁ`¸‚æÁ`üƒÁ`0Û`0 c ƒÁ`lƒÁ`0Œm0 ƒ± ƒÁ`0¶Á`0 c ƒÁ`lƒÁ`0Œm0 ƒ± ƒÁ`0¶Á`0 Æ6 ƒÁ؃Á`0Û`0 c ƒÁpÙ†-ßç·µ„æú@ƒÁp-³b ÜxHÜ–SnMÊ.7333æŠ(ƒÁ`Ø1¶x'èÒ]¯ËÄÌÌÌŠ«_—ƒûš¿\‘íŠoÖû«Á`0\Ë.ŇÙ-\Ê-/EŽÿ[(–ßKÒ¬Ó/˜ÿz©¶–§Á`0\ņaã!qÅÈ|yý† œ‰MNê{¦¬'ôj›Öû~½6þ«Á`0\õ.–GæËk.Ê ØB5–ÖRÖ´7ëýÕ`0®bÖ ×sy"(SZî¿\0°³ÂÙÙÀ làs¬™ùÆ5 †kÍf,“¯€mاiŸÀx ƒÁ°ñà¹æ4}Ù†åñŸõ<ŒÕC¼‰) ÆÙõ†Ä­íS²· Çæ¿YïóÆ™l>OƒÁ`¸vlÀ&‡ÄÍ|s%ý†M:A¦Õ ƒa·q%mƒ‰  Ãîľ‚e«`0 »sŒ5ç° ƒÁ؃Á`0Û`0 c ƒÁ`lƒÁ`0Œm0 ƒ± ƒÁ`ØiÖx¿á±Ç3z1 ã7œãÑG5J1 cŒa0 Ãy¬Œ)½ë]ï2J1 †k|>ÿÎ÷}p]ÛÐûÅΈ2;;»“Åí’¢÷„<WVÂ^Y»mÝ«7mÚ…m´ ;ÏîïÏ»JÎÝ FO†ü†õ~·í<öØcK>Ê·KŠÞò\Y ——µ{¼Ø|>¿Tñ]ÕF»°óìþþ¼«äÜ b,—a ³‡Õ`0 Û`0 c ƒÁ`lƒÁ`0.‘‹¾÷mÅ Ï333WêjÏ¥r— pY…¹²—˜.i~Þ—·¦f̯{¨wí•&»6;Õæk½ú±¯‚†Ù1y®`Å÷â#a¬‚ÁtªkÂoXš· …õÜ…å^Å¥·âš¹­.w…±$áv Ä8(Ëe[Ï}¹ôa}=ͯ®øòB—¿âóåh¬Õª[OÎK,kµçºqW¹Xµ\¦{QÊßö¦Ù¶±7Ó‡/Ø….«„ôç5?ïÀõÞдf)—®Š‹XoXÊ}½b–„X­²KÑÂòÜÖìI›—pÛ[h[jº5Í/7k Ó—‰kjr«°d’×Ìmã¿^”6–ÄÞLW¹(µ\¾»yåo{Ól¯ ÛØÛ7îÃ?ìK¸3æÖt»]Ï×fJ¹UìÕµèË:ú¯Ù�•jgbA3ËØý²½BîÚ ÛŠ'vu{­÷×k£K/zåßLV[Ö6êö¢ê§,Wdл”¢íËôlìÎÜvsM/¥Õ·,ÉnVï•\Ê8²»uAÍïÚ¦Ùö‘÷êè[î »v²wù{§WlÚ]26­úÜ‹ÃëU`Ò–b ,zm¦É®ÁE׫¬Ê›é »Yiòò=½Û—\Ó­Û ÃÇrÙVD±÷Êæ¢íj¬ÑùnŽ&m,Ûô¼½ÏÑåÈpzãnpÐ7óP/I¾3ÃfšõRT'/‡·E/kæ¶¼.ØÛR5óÙIŸñ¢µyïárTa'Ía¡Ï»Êމ´y16n²m—| úÙaímáaß%Ïàì{›)åRI{ Ò¬ø¼æ——Ï]Z]îšÝúr°™š^&mlœíÖþz9ÄÛ²q¯ØøËË­Š­É¶±œ;)ØŽIµÉÌ·««ïØÓ·#áÅ ³eIÌ™ƒao— ;‰± ƒa7²«"·× ¶QÁ`ØÍæÁpETgüƒÁ`0Û`0 † ±vLi‡¯q¿‚·Æï¶ ëw›<WVÂÝyý®m£](ØîïÏ»JÎ]¥.qÿCoë;Þýü©FknæÞ|}÷ÜÞn0 †œŠ½ó}L N׎Ÿxú S2 ÃJìíräggg/1pé9\:»AS‘«¸"»?ÆÒ‹ì~…±·ä¼€mXówóØc-£.6ívåpéìLE®úŠìæ°m>Ÿ_ÒónVø^é{QÎ%LLÉ`0 Û`0 c ƒÁ`lƒÁ`0.‘½qžÒÛZq‚ãòSò÷Äe;¬sc⊫Õwy]6®È¥´¯i‘{”®”{BŸ{B«[ÓçÕyÖÞÞ=¸q“÷Ù­¾fÏUd ¿4-²3-²{ÞݬϽշ O{¯ô–Ý�µ±\ñûÕ“»-ô¶ ¼b¬y×òÒW|^QÐï¾Äޏ{*²ºötEöz‹ì69w¿>÷JÞ2rÇÆ÷-wÊׇ-õëõõ Þ·õÍôYm—‹±žlK—Í®þ|±=éµß=¹DvaEöh‹ìZ9>·EÎ-f-z…ª.h÷PÌíÒû'xx‰’ìé•°kVŸ{¢oyİ7ŸûÖ&ÝËÓ^÷7]Aáwà.î¬ÈvÅ‘wC‹lKÇÞ+ÏÅî7 ;#çUзÁ6\Šô{kƒÐCLEÖ“äb¶]R‘KïÛ{k•Øèó*ëÀ—d®¾Þ¹µV¼R¶mûÐî©È%îa5-²çLàU&çžîÀ»È6\º{¸|÷Õò•í‹ÊyE>[zÁ»Õb¬ùå¶kòÒ‹Ø ÙÞ1úŠWä·äï•Ù19>·KÎ-ç°gü†åUº`õ6øñÖ:Áš©6ùåzÂl ÉÆ2_zˆo—TäRj´{*r9Ââ;V‘](çÞÒçžèÀ[S©Ù§d0 c ƒÁ`lƒÁ`0Œm0 ƒ± ƒÁ`ØnÖÞ§t)7ž_úmé»á¾õÝ绩Èe÷_+¿·nä¼Lˆûzû[ßñîçO5Zs3÷æë»ù¢sƒÁ`0\¾YË;ß÷ÁÔ@átíø‰§Ÿ°÷è¤Æ`0 —•¶áÑG5J1 †k’⺶á=ïyQÁ`0lÌL]BÚÃP� >ÌÀ +sƒâ›PMÝgb>~ñƒôùµA‚]˜…Ée?N’äïûຶÁ`0 0 yp`pÕðºI¦`|�|è®af&F  Pµ!€à"­Ñ’à÷ ’P웊1{X ƒá"ÈC P„‹ZžYöyê0u˜]Ç~t©úÐ^×~TÖË|¹KCbp@÷ÿ9«R-Çø ƒÁ°îh>µê›¥áp¨ŒPÊP»Wcrü9ß~°,þ³Œ1(‚‚q¨2±"óè éÃ4á‹�<~jëÙc ƒ‹Í—¦óýpИO±‹š'WGMP‚L¯ëj,äô¬ÂÆ1¢I ÌH­ÿ³s槸<¿™/I® éû=ÃÀ0³9P8%º f§7*ÝØƒÁp5Ïô7õ›U³þüúqùþt¾Ø¥8‹&çS�ÂóŠ _Ê W#C¼ñrE4ä@1Uê©  Ój=…FPMµïÇpŠGÕ ³"f5Äd lF kÉØƒÁpUÍô¯ƒ“댹˽&€áÅ!xù¬Uàè<s2 PAM•5hÒ`+tª# »L¹†À PƒÉóWžmpûëÃkX¦ž<iÐý™¸l¨uªùéqfñ' ©ö3“c”f\P÷™è™žäÃ0¹Å²§Z .3¶Á`0ì½¹ÿšq›ƒàB ©sƒøyÙö¼tNý Ìæ˜\5럂ë6ÞG4\Ê“õ±qý)ŒR͇8™Ú¢4aá<Wƒ4¸à‚¤Ò¡Úf$ÇÔrËt�Š}ëC<à,Ú†¼¢X©§NÑšVÁ$õeËÅYŠy´ß“|¦zúÌAª2âV§z5 !ØÈ0Û`0v‘=X+Ê_êf’€Û· ÀÁe¶¡—í�8ý¡Ù ² 쾃  Ìhƒ A@kî#ÊA¡>Z r»õL=Ã@C�0²låyn`LõW’»¹úTi¢7è÷ˆ‘4S)Ðýµ‚x`ƒÅHL.$Lx92TšT†“ð8ŒP™BEƒí0ߥ"©>å±T[öø`XŸíLL¶ abJƒa/Ä‚!³lwÍòÝ8Ǩ‘‰sè¥í ʽÿŽôgÍù2ÅÚbÆ‚, j8¥~ð=„€Ñ7A$t µ“YN²P˜È{e›sÇ�� �IDATEûÕ¤CÜÆ:ª¡Á ‚¨?sïQ„8mŠº3êǃ ]FÈ—ÙÅžÓÐéËê€d*äÖV„^@”«Ôhö÷ÑNQa| &±@ŒÂ~Sok­(C­Û±ïGÐÝŒµ5¶Á`0\Q_aiÕ7éÚý(q„⺀¯áÇ`>·N4©Øô{/yu  6<<ŒÊá(Ü¢A2Mø`õâE ¦zC� B2ýÁ1„áÕ‹Æ58Ê8MUÇømh’®¡z&§ÿ¶Zí§•àR¨ÝEŸ¶˜pjÑ1Ê'ÑÇð~ú:,,&Cb$!L°Á5€&<p¨RœÅ™DN¡G(@šŠ‹ŠÑaß9rüþ¾Û 1ï¾ †Ë2îoì+<‡áaÈõ}ô-„_®tQS躀.¢ T ëäô“w`ÎÂIp åØW “‡~Ž&œ†YhAÈiø:¼_gdzÑçXÓZýŽ[B¦Bº>I‡¸…ha7ˆú~I¯ !tAÃÁerB5"ˆñ›e?V>DUFº8ôK¤^À9ÍÈ ðÇ&¡ ÝÅSQ—¨‹ˆ,þ+@®ƒ!Â"óy"ˆFá:”CEQ¥$¡ù~ø¾tÃêÔ¨ñ Ã:¬ófÀL-Û³|‡¨X¶ê+ ®È¡ªˆ«²4~¬áëi|M ©6áØÒVý>+Ο¨÷£@C¦LF‡/X€®b®Ìl »l_túYu€þJp´æV¥”µÙâµ-t•dñ")“Ôˆ!œ2ã5žƒîâ2p]@\Ss¥€VŸ˜:Ãà$¬idÊÜPãVÐðc/1ÓæsûGkí#ÏO"¨$TuyC€O5`Ü¡5‚Îã{6UÀ¯ÕÛ%:¡ª·‚®¨ÏöÜ¢{ú«ßëìV2¶Á`0lÅ�#e¦j+7†¦Á[ñ*Ö0NŽAÅl‰É#Óçíí Ñɘ5\Ô7(+3žˆzÜ©~ $Ô°aa­lÅûý5†d2`á ÁtÀT1(A¦Œ¬! y~–²’ýè–^s«Rƒ<¤pìD=«0 9¤B–È ¶…£Ðen:ÅÌ4>h&h*ùFuò '`°¤÷W$è)pz•šîëÑbDÑ È5Æ|Š1 Æmê0¡ ‚êÝ^àˆ MÝ^\ö˜h4˜¦ªêTä!ïüý»Æ6 † P†Úʽ¤£p ‚&Î1 ,U2ªž& vo¸Œ]#ê²ÁË¡ øý}¢½éyÒ_èm:ª\t†ŠnF‹´¯Áá#Ç3åJªV…Åÿy%FLM÷Å+3Y;ÿýa˜f0GgÒH‹8 Œ9Œ›Cõv÷Ÿ¢;}^'—Äì¾Í[ud#Ó €.£û‹ÏaïU„²€°+BTeßÂN£-¬�RDN/Æ\ª¥i<ðÊè>İ�$à€Õßh86ÉaªÌ`E(*´(ûª¶ø›ÞÉK/31 SåÊ`­Ú ‹ÉÞ^§i Êhßkë™åti%4~ƒÁ`¦ü3ÌH[‘/á4œ^Œ Âí0Ð_Âõs$…1m‹¡ œñhºî2á#rˆ4a‰VzÑTh…¶AãÀ1ÅB™Lm1˜ãÃ,ä‡ñrVÊÓ–Ò¨LRAVe¹Þ:sŽ @Éæá ·B8Ì`Ž8ËÄQ™*UhT¬È1[‚4Ž¢!l<5€w±Y"—8¡“"få)£ç›„p¹Ÿ´ôº� Âþ6‹ÿZÐ(c©±´WÔBa'™z"&Ú–ÚC¦Ý»¿°áÖ*Šª!¸A>¤ûo5tÁïEÒÊPc– (gXrÚSØ%5*þtõ œ†‰Þ;nq5.Ó9EvzqÓTnƒ™I®»‡fxþ–¯¥ý»Æ6 ×+×�Ö 1–Éçp dlt¸8µïq ×›#—é*»(²Å0Ô-åSAœBÀ.+’<¡G{š“¯á— ĆBûk‹»’X€œ!tªš²Ç-í'²å'I ìÒ©ñJ0>W®§Õ„k/¾†ì*Â2"Ç@N› ‹“öâÙs”'PL’cŽ"%ѤivM‡ µXúÄÐJÛÐ[ IA €Ç—)0wB»ÌuµÅqÜ» 5Í|¦(¬¢åj)}+!QtH¤EÇ%­±ÊX5ÔâbõXbe1®©'L´¡3}{à,¢ºìåí°Q}|züXΧ€²}? bªí%ÃpäÁf"d<EÐóʨ‡$¢;À¢0éÛ÷c †kÀ!Xñ͹µß󎈨0]]rÈ‘OSôH9‹[ê#ejëïÀ±@•5’#oŒµÂÖhmÙÌ%ʧ’OWuŠHÓ 9ò©2Ô…LÏ!cäýe^œa¢›#q±D]‡$M•´Âz|ª¨§‹ ÝÄ5¬™TH@”Å) =¤,z~q2Ô,ø‹+«eí’'…²I,|E×bò‚œÄŽÉ(Œ™-ÖÎ}”ëoêþ‹mˬ‘ÆÉa)¢qƒD¡HʈSX¹Ê‚Rí$Z l¡TT™—U?¦™Ð…ŒMºý70<Š1E«¬eÍ—e¬ÚbX©¹l½}qí=Fmò! –ë³ ÛVMÔÅËe&j0´¸wÔ¦’‘GHr…,-ž¾'�:D“L.u†À¬7 W·C�£eÖW–Nl>·ö›Ã)0bM…çy† r+àØhé‡È�UÃlo_é0~ŽD…¥¢ïªØÊÚ’Dû±å×ãÀ•ÕHá*M¤8™ÀÍ ™„|ŽC6Nˆn,Üçúï"tsØ)2.–N¨ÖLÅ:]µJ‚-Ð@„JG•ÔLÕUXQ«F÷( ¤eE¢dœz¸-O„ZMÝSAWGá¦6™mZ,@]1›b2‚·B*B'd2t4õe꺵ÿút `3’ÃI“.‘Ρ%Ú†no›Ó Á�sQµ™Œ[Âo'8¡¯d £*>/)^ˆÀÇ ¡LPp¨èaç´Èjÿ(‘P¢óϹt#K¡$ňM^S­ð™ `6¬@Õ éÌöÌa AZ-š±¸ábìKØè°’š©ÂÃÓœ\߉4¶Á`ØNÀ&Ï:/�2ÌhŽÛ%¬íiNÃä²]žv_ѵ™ÒE(Ž(=UöGÀ†ƒib›ŒF@Ü%hã7‘ 2‡,´a&GX íý JDhËOä<28œªÛ ¢ç[XÌ ò£&sŒy*â(Ü�%QÓøàAêebEÞF $ˆQ Ù¨ê Õˆqð]È ûv.Pªª¬L’@4J"BDdë ›nY´dªÁB.,UgÛäšx]° %݈3S€`¬t€–$ ÂVjƒ°ç…áüu‘£–@E¨K´ÐiÚ¸tRÄ’–Ã鉠>’ UŽÀöëdH¡Ç§Û ÎÓ¬@bª27® ~R Ô~Íl5nãÎ.ñ¦Lô–ýkÄ%BpCD�5MHõqÅHÀTƒú;k8h1h“ ÑÅs;Ðtvö¢˜ DzÜ.×½ÚDžuOU2¶Á`Ø]N@©·ÐzþÄjû±�QåȰɆ‹[0ú¿L€¨†(!ÃÊ(ê`¨µ­o-ae•cW´[VD·3ø§i×°a_ÿØ7U¦™e.[ñ=ĺi,?-çMÅ'S1®… èÆ8 PPdP‘Náj,¿"ºUÊX‹g¨‘/áÜ&ÈSÓ°¸[¿®ÁF9¹À)Ô-¤M<C8L£­=bîíŽ Ò®ÆÁ¨ï¬·²5V 7DµˆêÄ] 2Œ(¦¬þá¦6b5ˆª0c•è6ð¦IX”Á*c¥I¡SØGbŸ($nÒqh$HèZø Äa‹V³R%Ä_]öx0@6hC^¢r°\Uª.<WE:8C]j\…¶9Ô>·Ð{ç#i A)ðøô·W•±k<¸ä86Èƒ×Æv¢y¶K ’œ ˜¤Š±Övâ‹)MszÝYˆ± òá©ÈÆlÿu02TòTÏ D²û›^¢2ž"´±zA¡4¢ŒªQ„‡ûÇZÐm¢:¤ÆÀÏxDßÊÊ©ÚaˆèâvÅÅUúa÷ÞÑCâ(¶]ôx„¿1ëûùn0 ?™—Ø:FLj%PËÇo²/K1¢”*f\P§<áÖˆàzè6PpH¡ È-}$L„+Wd¶*³$šÈ& :©JdWç=«’‰”Òlb¬ù ê,‘$- $ãƒ_&·"7(j1mA#œÛ&2 Dý#7bÐp»Ä‹ éÄÐ!îŸU—Ná[¤$ÄÚLµ\¨†“Äe¢l*^¹Z†vÆ$ÅÙ²JÕÆR=N‰®ª.H@I\… ˆÝ2vÞ Ö4’2Z%¡zîJ†Z%©Œ_Ã󉿎.#jøeÂÝaær´q@“J[:í較[P• Õõl€± ÃŽ˜½l8:ïüèŨä¯r¬ªc‚¢‡Ê3R÷ûÛ—Ÿ>TìøìV k|MœÐ.kJÓ‹‡ö[Ðô4H•ëÈCJxÔuËE "IBL<½¸<é÷_`—I…Hd=ˆˆÔ™8˜ c/&ŒHºD]…òH|lPmr-Ú§HIÜtQÛÅ$Ò–ãw@ˆ]Âmûx>Ý<”�a™°Æ ¤! íZÕ>JbÙ1mwLtЉ­’Ô¸+ê2žä¸åû~ˆõƒtÛUË"²B/æ–Ô*)ªi Ð`Êœ®.X IA ò– OQ/³P[´qÔ‡l‚- }‚ZXU¼Þk 9›@¹'©Žd™Ìú4*Ø-Rµ±„b<¬dn\©ºUšð(¶(æ•þd‰)>=ÙŸŒ¥“ ãF¨QH$‰j„e’Úâa¬š1Q+ÆeÔúKD½•¤at…£4Cdÿ€_£ ÏOCÿôªSåqÒþ¨ ¥}mRUu™¼‰) Û»$°¦+0ST ºöf*Š‘ SªÆîÂ=16Ù =“¡÷Ô˜U+ Œ ÒG ¾,C Ž-»@ô·9Æý¢S $Xó2ÅBrýW¨z{F{/C¥j6X¥ŠhWm‚M#bDŒê¿Õéh¨aím–Ÿp!J~tpAî œ…ñ´¬[­‰d?G4ˆ ‘ºƒ˜AN#s*+ÑRèÈÁ**߯D¢* dH"âgpt†D#  ¸`Ò ñCZ’NÞô,tªå �߯‡!Q º“•z×[OØAÇ¢ZQ¢ty\O×É‘dЇP ñ¸Ý­«dBµq{*²IBD@ Â235zGeë—Pmì"$Ä!É<:êy‹V9c‘[Œµ’ŒO©úˆžó4cœ.a¦(_*F¹T\hÅ62¬$(°õHhÍÎ84RN©•ž!m‘òÑðð¡ÅþA2J8 ÓÌ 3CE/ÖªäÛý;ˆ¦`0‡_€,¾Cf; „¹i$ ö\ÌZ?8Y«S"ÔjÀ ëI@R[ys‘± ÃæY<)sdÙ»²×ÁÉQ&­EW`¤AqYsjÅ£(Ÿq‹ú­L„9n(€G`1(˜µ™´Àc4E¹Åà=8b’`˜xˆ$.¥bÔH%ÓALÜÅbX‹R)¿Té6ª_œæáþÅašÅ{zgA©i¬2¢ˆmjrYìQƻ֛þW4Õ¥“éDƒ¤Ø ÒÄI j‹Ñ¤¤¿Ó´÷Y*bM"ˆÀ äþSE=àøNLœÂ‡öiìt%UWƒTP&tªm9.¥/%‰íûqÛÕv‚ë`yÈ6”"²±,D\‰rU§LRÃÆÊ!‰Í\‡f86×>\s®ôìDh°[Jt*:œhøŠMÕ?E:G‰D†é£cÅ�­C?,kbŠ–Ö)|ÕE·ÑM°¤M# 8ƒ¤-ì#è—`5 q¿F2JËû: ŸXdŠm»¸ uWúF”b 7"r+M‘Kâ\;Ö ¶*èH¨SN(Ûw„=ˆ˜ÍÊÙR2ìê‚Pé°¢ã*mZÌÛDiI:Fx´=TÜ”ÌhGh¯CÕ¤2BuªÌ¬Íœ‹´({xÔÍ‹ïô-ù‘2xLÑž© ª­�ÝXçæ"c † 1Å”ÍxžºÃD¡ŒªaçH ‚Ã� øx9Ò9”*R*Ê†Ž§} )ƒ¢kƒ ørñ¬Ñ›¼¨ êj>…Ý"<YÚN¥-rQ'¡»øYü¨ºC¾Jù¾8T3ðàâ-›ªÕß˜Þ þDeT §†:Jbƒ&ŒÁ#,"*%"ÓÊa\S—PìL«€q·\GOÄCø6AÕÀáÜŸô-5ºh0¢'¨Ä]eE:]ÔŽƒÊ©X¼1l/X™b«0÷©‹0$¨º°“ˆºH©’8T½ÝE%HG¢ÂKâb×Q Ž'éº(MØÊEØÄ/ ;S<ËóDÆD ¾œ ä׫Q ¼ZUQIOW÷•ÚD©*A^ÅZÇ讳¢P£´×FÎ(ûtEêª�+Md&$pq%nŸÅéyA•ȪÆ›$$†èëDåÊB |ôsR—Kåd%‰«‘¤™T;ò¶Ó¶%C{ Œb,'¬*ÆT€mÏGaWã2öÓVö«R‘Ú§’•U Bt)©ú™q'í»à[*è–«SµÅ½I´Á…¼MÚ"퀋¢9}îÀs Òø9P4ƒêL‡úäÚÇÛ`0œ ôá<wÖ~¹2R«Úót`سrØ Uª¯e°ÓÜé"©. ¬}ÙU´t‚N@ ’Z…R5Ò_@@ÎâáÔ˜ÒÅ‚¥2bÜuäD’%¶èÚÕnëb¥”-G#™‰Ò/[®²œÀ’õ°ƒ“ GÇÒ“‹ï%DÔa"x”9 Gá—ð"°°-¤@Y„)¢R%¦†E›¢…–ø,F±‹-t„Ö`”¤K×FAÂþ‘¢½í:²wÀÃ$Ö øHpüª/Æã~”#Ì"Ül”ÐñøŽî¼€=CVÝ`Þm¼MÔ^Ð¥ ¿Î:v%Nª‰hD¤v‚°±dLŽð”Ô”/"£5ÂG/T2ÕB‹´ˆÒQW¶­nU·F‰,„“¥¢ÓPñô¸œ®GÓj\8PEŽûÂOAÇöƒÖ| „j…h| ,V «H3E,+IR4ÊÃî™Û¢2~€±.Ť¬5®íº¯'Ø ¯L÷TU¦ÆÛ¶P0¨ü\xaU&4CâJ7ˆâf´/ sÝH«È *‚‰HWthè¢ö”E eÝÖ›$D[cnR$Qã$õ0žˆ,ì6–¨{`K%“ ’õbm±«æÒ!ÅýØ ®ÂމAŒ%š\\®P`åа Bä gè÷yc †¥�Ñ1HÃ ÃØC”m¼žÇQ—iÅäÁ±± (ý¬Sº>ãèlUCÊÁKI%ò§mÛøQ2qNÿ­íàh„[Q5èTcÆ#ßaÙ—µ@•«4ˆÀVtü^†L± ½´v¥/AèsVr\VÂ8šJ¢‡e¨­È)µ•sJº(»J‚'±,ë°…g£»øvÿ%gÇaD ݈ÀªÄÊF©ˆÞ&ÝYÐñ¨NYØ*›”éœÒÁ´î #rʬ„NÕ[C"ðúïB{ ÊX5¬ „ UO²X*Lg[‡ì·lË ¤5E –:¯=›\]×jø!ãa¦D¨V;$‘„i¢�)ÇœèpÒÊ éE‘HbÚ)å&aWƒí“„$AÕš·îñC_ùí€?´»h…‹ï}/ž÷g!†*¶Wµ“záw•åqØs˜Pžjª “ª» Ž&tÆB»è£B1n©ú€5‘ÄÄ‚8¢ @šbBѪiJ~3¤­È†¤4¸ÓÔí›|ådm'©{ILÔFQó‡=k0Le‚–ì4¢Éj0ŒÌPMºÌI2JAW“˜(A H¢ç_'ÂïJ‚6­9â6éü„Œ°âJW­.@F†qrè,n ` ìÄ'ˆð3ÌÁÂ=8 ºÓdÊX eƒÆ‡9uÞ‘éÆ6®ÑµâÞ±šSµ1(¾ŽìMå¡t­î O½¥ÒÌ£­j¦… ]—¼¢_çÅEWètâÛvÊ·±l[‹LlÙ^‡Ñ\MÇIÆSG$YãmYïˆzÚJt î©» 7Àjàf`’ì0ʪÄ)EZ+©°âlØ©UÛ “êh2ôð‚•'•ÞˆT§ªôâÙ;2ÖaÒ9»ìÉšè@€rs]ª:i|‡L)DD¬Ç:ª(-[Y©µJßí’düy›VÖWî|,)¥!•óe)ˆÓÕ´"!}E·LAï³a’2 G!Ì8-ÄÁ ¯€å¼1²ˆå>!];öѶb¯æØXÖ°cçÜD¹n·uý…�iãЄh| )F-Ï^ð"i!#™ñ='èºUK#}"°êÐ (×› PnØq= "&´+–V …Òr”xRI~Ô.H+¥gÜ ë¡ÿY¯„a‰­I\"QÑ©êi›’ މ(Z~tlùÚ ~B§ 5ÒTÒ¨"Z }°Qß +)Uµ hEr‹‰ 1–ÉŽë¡°‹´ÇdgBÆ`뺕E'óVÈ™zAŽfŽÍiÍ,ƒj2G×%‰zÛU+VW%gtâh¿K+­f›•fƒª^)AUE€‚4ÝIØ­HªªC잤“aF1—g"ì_Ä]ƒ 2\À0Û`¸ª¼°ËäkýíÿÃp„rO@X¹ãæëæ;Å}]} Ï”öÉÒuÁPª‘!”·¦óÇ(ôíª´+"I¥=éÚà†RŒUâ«(m ˆ¶Ÿ„‰èàÇÚÒ&Йè8ö£.Aã#þºQe!W( m2»€\ ÒÃÎWƒìxàúq¢ìXIßá(Ó­ 8(ëùSébÎrmB™ÅŠèoc‹b¬<ñdɲuäMûªUMk„K¤ mbˆ",YôE1©H:ÚŠ$RB·»‰ßlÏÄ F²õ› o“²•š ê–Ä;^ìB¡KˆÑ¤ûˆbDHdÌM’Ä ±ƒO"ÆcË·tHâûÝh¾•Þ•í¨fÅ9–d‚…^ÒÁmg…ªÈB5 ± ÄQ‘¾rt‚ˆOEÖ¶–m_×3ia'D1i˜X(ãµ*ŽUµÁ‰ÝŠôª.Uüq„g@ûv%�i©¢´´%|)°Ú°Pu¬ú°‰ÜjÓ³i TXIu¾–¶SvGκâŠ*  ܃óõªSwk¾„.~Dp‹]õQoý\cCÁ/†ÂÓŽfü$@xØ)l‚5 Ž*!ÕDÑå¬â´M¬†rm“tè4PAÕŠÆÅ¤—ñk~³¬ÏÔ†fQíò¸·PÞ„$ŠV SŠÑ̘§‹®R‰O¢zÜ}]m ¢Oó ̪ÅcÌ'{¯O+¦Ö:=ÉØÞ_èÍwFÎíÚþÑ©²«©ÿŸ½÷y‘lKò;?fvι÷º{DdøËÌW¯_Téõëu“3$<„S$¢ÑB݈"„6*¤…ÌŸ6+m›bhÍl„ g6 “‹NFR”ª»^•gFÆw¿ç³YD¾Ò«ni6#F=Ò³…C\÷ð•ßkÇ̾öýèËËÁv«|urÁá—Ì0ýwìŸót|u¢ë©Ÿ°_÷¾ÃN|XÎEsßOK_j•Ûj}¶¿z/‚ ©´,i/‡ì.báÝDMR—¿}kírÜ=‰ªÓðá¶6§gÛEÛ>Y‰›¥mÓb“§m3db^í…ÚÌæ%ŒÝÖÞówüÓŽ¼¾zòw~¼D3¥ù8?,ŽÃ%eG¬še+%%Yœ÷Ä>³vVI Šx¢Ħ{Ö¶œujf9»ÊQbVŸ%ÿ‹½üɋ埽™øB9ÕÍxOÖmopDÀíkbb<'iDžQOˆ%5cA94îîà‚Sߌ÷ÛlPw½SZN­FÝ)M¦¿Ü?û}¿8y8Q?%¢Å‘ã]Ž>Z^ü•”«\èÍ$Ýf¹LOfyO|1y¯öo†¼ ÅnÔÄýKÂX°¶CÚ(I—ë(™v‰ïºízBWÙSÍîòaPŠÌhsîu¯·éÑiî†>áÆ<ð)OÀÛxw9ü ÁŽŸÊ!Ož°Â¸@žÃWHÞñŒèYs•´;fT¸2àNf3¤¬¥Þ=à»,¿³‘´] ]Øb»hHåö5w_¡‰f$KP¡w3íÀðšÅ—;ý rnÏêñfùžõë‹ò‚ùYEöÄ„7æJ¹¦Ã?xwë:®]K=¬5ßR.‡“ÝS»¢sÿ�¿)fÞüìñú¨»û+G«ïrÃwñ7½ø èü·ZCéyy±yrÜðE~Å>7VÆñ…åáÃh$#=J*í9zÊbøòbA½gõR:é8éT‡åx’Š˜­´w‘»ÑîÂ:-‹‹«« E³ô#‡†vï1Áì«&þÐ+|édˆæû$-&º"ý•õµô3Ó?4ëVž[Û•Ô|ÜR®šþ¨J7¤ˆ“OnWeã¤ô»Ÿ/úÙ”&l”C¬Äq˜cíÓ­Û‰tòÉÃÈ<´}Úü BÎÒÙ�� �IDAT(Q„HÃë–ùÒgƤã¤R{ÐXWþù)ýçzù÷M>ÕX¥<¦ª¯äxE#%TˆHè)yBzldÚUb¦Â\‘ôŠgk}ÈY/KÚùÝUJØÃÆn¶ñ”´@Ê9ÇüùaÕúTXŒ«1«®%Ü 8…YQÕÎN²Di]U>÷~Iß½òʱÒó9‹Å«aZš“œ„BææÐÿE¦M·RQ.ífŽwÔinûÚÞm÷ßLÔý-íŒûûÊk‡Î‹=_°{:®­tõVvuýTÀ¨ Ïðvå Þmæºmü€–@a[æKmQt®¯g.j¯[§ÂuåîŽß©Ø zÁ'7Œ™¡’'l„‚Žßsò%ùì*ŸÓÒ¦6Êô9ß;aYÞÀSÍMmÛ‡od©Ó¹ox—Ê¥cýah‹…œ?L#áô{ê;NoþÃ’ Ï^qóÛ‹¼‚ß\ù.7|ãê€ÇcË«—¬Ÿ.¿À ?¹¿Ø<eûþš×éôbÐÏŽ'§ós©’ãœržÒ´˜Rz¨ ÚÖ-…™M>Íåói\ š§ÞÅðnÌSqeh>4&ÉE»©JÃd¹H'Y?¸q‰¦")«ÏÊžª{¼5=Uûä0´CÙïrÏí8èy.Ï‹-Ö,AcͼV_‹¢ÑÃ'íkmé9²ÃU0'«Á %ÕPÔÖž¦¡M©œ^IÙšå‡tÒÒBhkæ•ß.‡Z¦LôÕ¦Õméùã3]@H·nõÀª„{‹CmCŸ³¦ÅþÉBçõlydpÆZ4fÀFÞ  1XÐàhèøJkI9éåÒwWG¥ApYëùZS ™t¤5bÞÆ@U‰veÂ4n>ä­Ô?ɪ>™¤â”Öóâ¸I±ÕDÚŠY¯\huÓúóhëh'ù~Ö†©bèrŠ «u*ktf4Å{ƒð,}CÞjÙJB/;íøCîRçw;¿A!_À5õbó· ÿ²ÁtÞÜóÅ¢õg·¶_pþ=û‹ÜcƒmýHí™ 3hÞîðŽÓLZ™¦úжLÉýþÞqß<7Ú¹Aew3§…õ93UÊ 2×è—ô3ºÑ‡ÛñœéŒéIXÙ±¼üÃÅÌÀkæ÷½rܶ VúÄôC¦%Ê–ûKÿË9½NúR:*ŸE;)–²Î›íØéoyú/Ÿñhëoºã¯_ù.7|ÿeSBáÅsÞøx¦/n2óå›ëåg Ë%Œ_zúÃîµàoñâçðäåJ/ž|þI:[­ºÜ=ÄL£„išòRr®ÙŠ…iߊ¾Ö¹Ÿyùµ³¬9©Š=”èj“ø žC£/>Ì–½t¼š’JÏÒe˜Bt J«©©uª{X&Æ©¦éI¼NÇC¾û¥Ý’å–£®Ó•®Î¤l’=Q?“º–¶ÐHÄ!|áÍz¯ÏÂï4þÒŒ¶p÷®æè§ËáÄõ$ÂÌEfŸ%¾„1ÇÂô.b¯Œz»û’þ̯ȗ>eç²ÅnNWª4¡tr…_ý¤,¬¦MŠtóy˜oÊâ0¬î=–©û÷GHvTic–?Úà[M° x̱.ºÎZ†GFMƒ#¼lÒ2—\B ôLߨ~ë# z¢e´‘'-ãrО%ÑÇYÒl½æ¾ÉÔÀ•£1wJ­¹Êð¾ÔãœuÚˆmM)OI#yØ„er‰¤„J8¸õ¹K…­:tÜèÚÕ!è§akçÈÄt†åWþlm7¹ëå}ÛÁÕ‹Æ燅z²µréãCÝý0^k9n‡â¨ ö‡Š½˜.°gø91a{ïÖy$‹4§~ló‡ÛËáÝ®~}%×<}ÅtÎ41ìIÀϨPßÒ/^ÍËõQr^\.Nvùp¥åãÊ»Âh»Aù¬ä×Z©;ûŠ-™0aW÷LܯO*%?¥Ì³h…-ã†õÉc÷jÃ1sW¸(\þò·ÐÝßå†ïâÿÃø«ëøÈÉžœ¾Êç_Èjuû9ež¿zæÜØðvZü=Î%?YGÒIïúñé‹y|2سáä“T†,Oîã¾7;æâéÉ\mN½iŸ“§ïKœ†.•bÚU‹M5{Ò4DO-è²cGa–”’HN&²"UH!V]â†kìC[&+$Ìi¾ÍcŠñûüå÷ìd©O³œì™$¥¦ÌÚN%&ÕQZ¨.Öúà=Ik‰‚&K­Ê‡û9¹hI«Hç)¥à˜ɳÆ,þn²ÚIô² ŽujMþ^jë>®IEb¶N9Ò3©£9¼Î×RŠŒ5RjÍìh«ïµ<¥4•c£ß>è\gÿ¬cëtJáX8ìøÕ¼s^•rFYÜ£m"¶”­ —©Ì®xŸ™køV ±¢u0º3ö@?E|m¾–¹Ð1™ûòÖÇšt§ ‚€vrC>oÛ|9·Ù ³×:®¶i"Œ 1ß6»|ˆ¡3ÛñVj%vâHHVÜaI¶9$CWë*k=/¹ÍŸÂ? þÀOY Œ¶«`ä&u°Ý$Á50ôx78èK|è‰.xÚäu–cYNÅ‹ÓɃ.ÓC¿C À§ ,× +ÆBNÐðÇ"úõÚŸ­£”³%‰Tâ¯0]iÂçÍ ¶Ÿu¦#e&ÆN ¨WÓ’¸ØÄuʬy—ª§»0Pìœe`ȼ`û†KêÌ50C…?ƒËo*†ïê†ïâ?÷Xø?Ž¡§ÅCôŒá«“Weñû)Ÿ½ K•ÓjQã?79ëù{Ãp¾¦Ñ“8Ÿ,ýóÞN›­5ŸŠÂCeèz ‰ºïó1·q<>˜«Õ¿‡§j§i\2-Sž(fYr’šP“»õÌBrD‚TDAÔÌ’5À4…ôn.IsvMawJMÃNìû-ß§3™–e©2™ˆÐÞè+dá$íšMdÄ“xd—¢Ùín_ïZ–cŸÐU. º%Ó>‹ïL[J)Xçžï[‰ºôø¼-þ™Kx.M ;dÓMômOèLJkѵLÅ-Ü#ü€OYëpN:!¦ætÝמwÞ3cõÁ=6};;<8¿†·ï¶_pYÒì@šåXµmË%ãì²3DÖ^ñ5ÜÁI=18¡ô‚7n¹¶2<;Î:ÝZº?NÖ 5ˆÃ¹!¿ÃUð,ø@–Rɻ݂ÅÄj@e†Fô]všæ&5wZüz ð@ÿ wrÆf¤â…˜G!M/Y¬0”ÔYïs—MbÛNXиšƒ{Ýô¼CA2݉=mOýšþ ý}Iƒ¹áGrÙÎÇËTæû–Ê,÷®Çu_5çëÍÀ6‰ž1,™dEž˜¯9BgÓÉÜ”>”È<ŒÙd±íwÄúšùKÛïÓÎx 7jå01%îgþ7ÀùãÆx½•G®ÏÏ6z±M@† j;oÚŽÎ7 õ;à»7üæÊw¹á»ø¿Å•ümÜî·Æœc?º‚O^²~ºYœnËðy,O>æ!ëY:-|zàöëvþÌ–£ ƒŽj VÖ?;øH'wOH$$ùd/µ¦¦ÇaïÖ<äaeý Q4™l Mbj"†XDÄàÑ;-‚ð¦ÝEšf£XäbÉLC¢[ÃU¢K’… ‚€|º ÞқǙÙI,W6.ò£óƒ&wan.¥?6àQD²‰eK L*ÌC=ÜÔcq$—$M$[ž5 ‚ƸNú§I‰‘8næú|Ÿ¾§2‰»ZÃçs²šû–;\±¼‘œ½”žÊìóa® ™½œ”ö±è‘RC?tÿ¥–§iq"yáö©Ëïýß)Wó”‹?GÿÏœÑ"ûX½ïìˆ6ò‘®D¾’å!ÚÖÄ-nxÁ†HÄŒgˆmï—Úg¹¥<ÌC®¤?³Ìad6š \)ŠfbFY\gÝ7=mÝ6}¢´Ý #û«èÌy[*mÆn�âŒèdhä$CGÜ0ˆÊ±‚n=_tž™©Nm+Kaì …ì8[ \7Ζ `nÌp]“þ6¾f^r_ïÑ#Ÿ ]±a×+ZoëþdHÅq;ÇMU¶å žaªˆâÚh®1¶Âåüv>¼å~3×Z#m¨øk>¼åý[ì‚ Æk Ñ¡ã—L°wyaø~Hÿ ô-Ê6]ãÏàkŒÐ*Ÿ-ø#ã_q…Á—Þn¿1{¿z ïÙ¼þN§ô]üg(Îà´ou~;a¼xËËo��#¯ÄÖ«!§Å‡U)E$udî¶Ïþ—šw¼}šÆ$I 0âÌ"×.Ý{í9…XËv uŵ§¢RNL ŠÎIÇVÌ-Äs‘4 p§7£K"’x’Ž9KJf)%‘ŽÓ”‘CMÇdz&zë®ûš'±Qm°aLYPí½µîW”ºeÉž³¥ŒZdÓ®¢ZŒ¬ž“¥OT3Rˆ4Òœ5ÇâÁ»w~$úQ±”‰if!<Òj_×TeÚåŠÝ“eÛó?ÓÑuÞÏs« ›³§QFí $ïE£XÍi+‡KÏR^ íÞ–è½;eàDP®Æ;$ošm½"ĹßÄy"¯-å^j—W‰«ˆ ÇmL„áb§Ž&ºâLJœYóÙN´Î‚“ֈёQ)Nn)ÚeÓÜär–]ø•;sÇÐæ }ØWh0ÅÇžIƒnDçI ·Œ#j,„Öh{ÚŽºâh»jÌš+5íw=‘öDb¬’îˆÄÀ«}[×UŽ|)ãnîWÇÆþ·7<y‰ ÉÜ) çäÆ@ƒC¿ªˆw›rHÇ×ë¸ÈÔáz7ƒ]P3#¸âP‡}ï C°;Â×äýËúòl÷YfUYÝ|4í¸‡éšÕ7ÞVõyKy˰ᇟòÓ§§Ü+±§ƒA¿ÀnpðL©1Ñ12ß°>¦-o¿…‡¿.`ý.7|7 øšÿuÞÀÇ­‚ü‘)óždN/xzÍû3^ŸÃû¿ò]e;@{¹–¼RÉ‹y5’Æ}³¸s‹üÊ矠0\’P­uñ™¤¨¬hª´­—ù¨Å’KvÐ$2Že¤$SUD—2©$)³9J5¼Ñœ‘.-¤ã©uZ f´‹“ ,Ôt–<šy2Íj)²ˆ7ÕN%@5±4¦4ˆ¨7Z„0%]Y™,%5u‘st4µÖqPU 7GÇ«ª[J")R0Ø4›Õ»ÏÒ´eÍɺ҆&Zó]Dél±'ÑPÔ±î3¿nrÏôgî›æØÿ0ø"‹–-G B>xšVÉil‘k$ÌÞç4‹.þYœ?;u›2Œ~ÛýwæøÑA~•;ǧ[w&a<n‹cؽŠ»Žëœ¿:‰g%:0W]Úp9Œ9ú¥Ö]•«fHÇL=0ËUÉÛ_lihE XçЙÿ¬x†BdFÛXÛj[G]·\Ì©â63rCKÂ= ÆÜˆ‰Ö¨‰}ÆoØ‘ÁI­ì﩯¹ýЛՕ97¾¹óí¤`Lä‹[ò :#×k½X§RêY¤ÒD/ÔN•òä[8çÐ9:Ï2ùq-ñÈJÝÚkÒ—ÈÙæ,oçgÌ7 oás#5T7øö‘8÷ØÿɰçªÁ{6¼Ý¾†×¼ºþèÙþh̨püÖ@ |ó*¬þxÁQØ÷kV/)Fd¢"7ØÌú½ }J1~Xø©À‘ ט€ †ëÞßå†ÿÖã( ÿÁØý?d‹ßÿWy1ò¦Ã‘—_ñä†Ó·<½æý3^7€‹Æy¥ÀÙë^Ÿ|s0i¼¹à‹ëW÷¬,_^ú™—œËªèX&eÌûRnÜ~-,x«íʉ dKR:¥=HŠÞŒA†4g9´tWãîS*‡¬–„.ÙC,4ÑS ÁFMc”JR™]TÄ#zsWõ õÔ»Ä,tÑ,¤„šwK.TÁ$¬«©âbŽ‹ôLXÆÐÒ“ªŠºž¢AOäeΣ™ 4ŒÈ.Ëñz4Ç›K¨ômÚMͽ‹ŠšZ’M–Kô9¨ÙG¨0ˆd…&æÖÏ"ÿOØ, ¢i2•&ݩմ=u»L’Õ/ÝžˆŸXy®6Ž)•Ò§•¤:ÙRt"¨FÑÛ”V‘JäSÒIh<æÚu)íwOµPžü.Ër•ä¶Ñý–ýÚ¯×óÅ"²%Ô¬£¤dšVV%½›CÐÃGýëÑè¾`3í y'H 픩Ȅ¿J²ËÖl”–‹[qÿFŸz¿µ[Ô±ÚZ†Ì¡(ó‡Í¾nQù,m<±—mmLòYb÷”öXæn¡ÎÛ_)¿šx’xü>”kâí£Õù¦]äÌRÞ.35m<N”¦ŸL,=¼ãxÎAG Pèºñ¾½º°ïŒÐÎHçÛHXãøHíä‡Wš×¾Ê­\6ÝÙéU~‰½þÞxí7Çökv$GÞÆK†×ìaÇGÏÔGœÆ�«kÏ8uîàÏ•$ãÉ386Vpò³ÕF@ïÌðÓÇ{Üx_Àã,dÌäg¼¹ù.7ü·‰Ä¿që½€_ÂÛoÍÏxÎ뉗OCæ)¼Ÿ¹o†¬n6¯‡í ç4±œ‡^IœøEâµóÃÄOÙ\óùÓ)‹|öPží–Ô–ç©!mNq“bŸ;÷Z×Ô•ÃOä°5.Uæ1î†ã>dãJU’yÖð|{/‡9ú¬ÉuÑ=K'—Þsö–¥ë"IŠ,¢Å- -.Dt.®IEÞÃï½+¤”,%Mª"šä‘T ]\é&.bF6OF5U“QÑEÜ$§ljê®AÄhš!÷¼·Ú¢ÕÞ‘$$“Kæ!¸‰šj¸6± ÏÒ5$›‰ŒJäYcåwm™, -šP=zÄAe¯-I|YÌ"¡jЛ­l\ §‰!eÓð>ö>‰wÓ¦.hh—Š>HZJž4‘MƒhöæÂíÌ»Fä<4]ŒUîÝ_Ù¼–ý‰êß®-Ú˯µ?Óœ<ß»æH‰$b¹˜¿8iº±Õv^rPPjAã§È´GrÎo¤Šî‘¯‰¶Ñ´¥`±NÃÚÒBxˆFe~0îuÎÔr»-¿€ŠÝϰF NŸë«ÖÖr~_ÿÉ“‡qš†BùÝ1ý;Ú•|MtxýØõDžÑÚGVÁóÎùÀbà°޼¥}‰|o«ËRõCºËºtÏ_—‘®©ŸRßÓ¾f?"°Ê¯,­‘çzùõ¼[]_={Mºx9Ñ̬Nˆ +GŽkŽëž‹•¹-¨ } _o9€^ðæ[mÛ7𾢜3gŽOÙ½ƒŸ}|ë±Öÿ!pÁygØC‚Ägù(Ššx¡¼9òwï8¿@®é´kîÀqàïƒóTyÿ éŒáœž8i¼ü®nø¯uðâ›Ö">.?Ïa<#?§Ô`Xð.Þr傳Ì*ñZx’X‰˜œ –'”Í«\Ö=åWír9ï†r••”P˜ŒÓÆBù=^-–ßÿô‹³wÏ–ÿª?\Ä铜§®å¶]‹ÜkêwŸK:ÍrB;JíéáÒÜMw& õ6µäþ™å1%OÉz••Héú¡Ç¯ñïµXè!K7zKò`CX7ÍÕ²n1„ š$¨žtÈ)9CÖƒ.¦–4e³djVD• BŸõ¢"ªÉ’dÅ\LD3šäqV$“¤®„{xˆ†ªæ†iQê½´9E ú˜dXˆ*®êh$üQJÓݼY7kJ·.⚢Lº8ÏËÑRI õ˜êݱޅ›iQK¦I¥‡f'çå(LYÅsÂè]¼…4EU"š«SªO¦YlHiH©hÊâ)ÄÝ“Öm•…”ŠMÑõ¤ÅymO¢ŒÝðáx,ïŸÎ¶ÀÒ<ÊíЪØRtèš±ÌnÄžw%õŠ’9Qò@RŠÂŠ>ÑDÆ+þõ«ù߯Yçd—Y]í,ü¬×â‘{ºÐÛ÷Óí‡\ÏêÎWÊÏ/ÑÉ´a³Êë]O^F™ ‹¢©t¸¸·„?£gæ õ—ß2ßp`³ÏÛ÷•ß;ã<XAÀQ¸qî/8œ±\“eDËRmÕäš»n4mCÐ%| \IȺv_ßÍåÝ<¿¿å³°¼Æ~€f!š–6©åð±ôSºåV6}µMÏ9ÀñŒ_ü5MÇ{àœÓs¼ðIãÓØPáé—èç™TÉïqAG¼ò"ñ&Aæ ¼0N+¥_Ñ2ó3nöôŸ³þ”’e:§àXB >Ëßå†ÿ Æ¿=õ}ùö‘èð\ÿŠ˜o/ÿmv'\¥ ¦LŒÔGàLoY²)×ÛüŒC㇙³Æ” ƒ5r‚„¦u>_”0$Gƒ&ô¢"O`Jk×ó§§§vò<Mç ÉìMþçðW=~ïö°Û÷¥/‹&)%I§ÏšO#nÅUb'ûÆq«Ã?Q/ÖUޤb½—°ƒ<«®RÕgÍ]ZHKn3š÷Ö5¥04–<ió4$•«äË$I²guÍaÅr&i²l¨†ˆ„hEª¡*Ý A “â.Y$¡I áfa¸D×P%iˆ‚fÏi¶¤áK-FZDšgÚ¡‹ÌÕ½™uK³¨j(š¼)RÉ‹å8-¬äˆ+Gh=Üé=%2=BPQÊäeÒX´¤–uVëá.MT¢ÑŽâ.*(šMŠFI=‡k«áM»«53ÑbÍÔÅZelr&¾ˆ¥„Üi­·«¿hZÍwc´Ü·6¿òiXK£¬Çv³îgDb:‚“ ÉЂ)-1Ï8De†¶çP×ùzÏrþÒN²EXíɽ÷h·ò/nÓæ>oOŸ‘úˆzKûJþþzŒääI2•Ôó2ÆÑ=·ÞÕ[ŽN6±ÞV£)mAãÕÝÛõžü//.x½[|y5}±؆ ´2ƒ-©y#åÎy‚Î<|ž5õ¶U¡8Å*¥±ð̹µ2·Òß³ú:ófÉv… #9)вu.ý0·BÄlÔƒl„æLÏÙ/x2ñrÿí{vÃË-F†‘ÓÆP7l¶}Ëá‘ãt†œ# í@Ûs(hæMðBxc¼pÞOÏ8›È#$îõþ5Ë%˵àz‡?ÂA^¿Ë ÿ?ˆ¿ê{õÚì›Eß– =sXpwßd‘orÉú ë5eÉüÈÅk¸à|€¯÷#OŽ?b£ü2óö’›\½¿ãÓ–I#=ᕃQV³•ržJ¬gbSÛ686ú³=«O7‹rbS9–)¥Å*—Qû(Xmá2Kimu˜Ÿ¢ØÝ"¥”TÅzäÖƒÞŽ¥#ÄŸûQŒøxëToâ‘|¶® é:1(•ÞÅ¥OÔC£å­©kŽœTÑZÐŒ¡:‰¸JJ2•>©2‰¤ÐÒÕ0k"–ÔD œƒõ–BDÂ5戹{×�É„#!Òé-¤p"‹x 3<G´âÞÄ&dtr`ê¢ A îá]¥éØUjJ$ |p-‘Ô†$CÖbš:ݺŠhsס»©¸Õj’S¤Ð”R˜ GÛÑ[JÕ˜éîMks—V-’d Ón¸F—V£Îá"®Šy-ýAˆÄÔûà:5“žƒ“}žïÿx_‚Å~k•WQ7ÕOTMV¥Z©9KÞpØ–GVœn<oÝ9ÌÌp×!=öv6‡á¬]œ­s9_ä8Ñ2QSo´¹wIýnºÍà‰£a™vA¿f€úr]ï¾§'ÓBJ/¹šVOe?ÇGœ©ÁÖ—HF„”6ƒ¯Wo×ò˜¹X–·—F–ç—ÝwÔ+éL ÷´'Û˜/gÝ›SÔÑÛ?o$N»gHXߪ^ºÏùHÞÏÔ×[y‰4tƲ'M3Þv5AË­×½yùóŸ)V˜N°Â”xÝxqñêÍõò“ÝåúéîÔ¯Ô_².–9^VvÂUº }ãÿ:C;åQ8iü£Œ9 ´ÄÓ†Þe…=ü"sã=eÉ`¸òõŠöŽhæP9~7oø›­ý¶ï•ÃO¯þ–Úì[2!àEæô‚rÍÈãº(?€gðlÛ§lœ<P”SÉ™³}ø%ïÜÂûñÕÖÃø,Õñøœúö~~˸ ú÷hŽœlN–ÛhXÚŠ^šÎƒ1i¨Ö¹Ó‡ï½ãùŽÅr[–ÏÓðiŒ9²å…-È¥‹æùŽžšŸ ó¤}°Su¡X*c‹¾¯9ŽgÓþÇCYå4JFýŽ#Ü%•ÓA†d¹kÓ° „ÉÒ“%RvwºèùãšZX‰T0I*ª=¹”“Ž’)‰‚æÀ\éD¨ˆ¡D-4ü›¥X—"è͉F÷˜U’HWzÈìQU{„ "’Ïîµ.RBr„FwÅE\!BˆÞé"da43Å4 £F±¦¡IÍzhë!]¼Z(ñs×YCM-›µÞqqiîÚ+mŽNÝ­E›7w1ïLˆ4'5wh]ƒµ&•<‹í!âÁä`"ŠvyÒ ¦‹”~ï Û¬üþ|þp5Ÿm-žGd–ôOfRõ¼Ím¯¢­±<Ï—­ï¾>\}¸ãpÎÒ6Æ­ÎÛ_”?lØí˜º$¯y×’dqëu°›Ö·Í;ÇÆ†Ìúõ|'¹ÚDY¤®YæÄ\Ä„xÔVeïúój`Øð*bÆ“)þr<]ɰlñû«ôo%®g_ã+d¹>ÝJ‡îÛnßÍ1%ÊϸºwÚƒ’·óFê-öŽ¶Øµ™Ör®õîf×¾äþ Íä'ta~`nÔmOÊôJ ,~”E³ó|ùÅq¿¼*_°HL‰3ç'ö×ë§_®Ççeð8K”#‰ubM/=Ïý‚ý5õšù¥ñPh…¹P†Í\¶g sRЂ.KÛü/ðCx?ó¦AåËkrax……b§|}àá§ä >\oÞ·ßð7%þãëc¾W5ÀáÑ+¶ÉŠ�� �IDATñW÷O†k^<ãÍ㈭ñFùâšÌÇý Æ«3Ö•|äÒØÍÔsÄœ©ÂÖ/èo¹ƒÿõüÝãz=~ºÈ«~’?d¯›úá—ùý¼ys½} vö£Å•œÇáÒ;ÚÕà»Ë¡)KØ÷šœ¥ö¼íêÝÕY¦<¥œ¿×_Æ´N«•L‹”Òˆ -É^#4¥Í>N•„´&.º[%Ú¡µûýñÚÍ|út±:M9 *ÕÚ¯ýö±²4I…ÐdEc‹ŠhèÔˆ–­è`2ÂÐ0AÍLÃsHq1Q1•¬1¨$€­KD„‹=ðHz,"¢‡4uÃ]è51«t3G$HMP¼Iïæ3¡âá5º ¸g\"pZô.t%$™ºFIZð ]Ã=ª÷è]fow·âïq‘X–:f*)iôè­Á±IîGgŸ{]q³fæ~hrÐbÙ¤z3Ÿ=rªFK´Pç8sÜ×z«‡YXkV›[kÞ[Yúz Yôžæ9~-~¤–«w)cϲÕi—£¾ŽyíŠû|H´Byöêt±r~’.ïpè¿xÞ½·Cô“Ò#ù\ŽUí]0Õåêðê¿R'•‡Îúšüßëí\~ÜÍՓϹÝzOxÈÃD¸ç_åJŒf¬X[Zk/>åq¯æ|91VÑUá‡tv<ýq.-¸Ôy'®ôîꮡlšoE8(w›) Ô(g0ïÙÿ ù߯*Ô‹Íâzû{pûòFˆ™ãné7ô·´ n®Y§zkkeŒùxƒÌÌ“FQRcÑ6ýe>}º<¬¦Qúpp{ÿuìÑJm%*×ùc›npc¿x%Óºy¡—%v¥]ÉñU×sÏ‹zÙÙýñý•ïI™—•vÃ=øŒ8’˜‚³D/^åëï|XÿFÅo÷…¾i%=ú^=ö- è‹ot ¿8ù†Ëq‰—…“¯Ðô-4Ä‘u°ž)Ê�»™,ÔöåŽ3æÌþ÷7¼øW›³M>«RNlN<Œ}GütQ¹Ûrñêý×äÜÒø¤ ù¾êè‘ô0ä<é*÷„0ÍÉ>èä™T:ùdmã©L'L£Ù²&Dg¤Ñ; ’¤ 5Âßµ.n©EÜ÷8J¸H`¥G‘–†æ©Wý]ëìc´XHJÙ²YÎVÒ4H^%·x¯ÃQce2Y”Nr¢E§»XS¯„à†i„îîÞ[ï]<Ô»´.ÑDT¤ˆ™„º‡ 0vš†I€w¢«÷Ž›FÒ&äo½‡]¤GHrë.IÌD5¤E@hé{÷8ºt).]$ŒnªÙUÅP$L½»Ó4Bü˜˜‹çô5iaw¤ÃhEURÐ#ºkkM8h iYHÉ‚lfÕÚ<5'æ`/n­¤fb®)DÄéá!ï£tÐ>„™ ©5Z³zp«q6k饄Øûä×çÇgŸgÁ§+ɶ‘¾µ*!BÎH‘}I0‘9Ù¤¼Öq´fK;ÊÍY·u]¬“ßXü¤pù^VSÈ‘a•ÖËFZ`3·{âï >ÂôóðÉgj(ó~>¶±üî¬>äƒî׋˜~Dùɘ6^òŵDŽ6êt˜–·SZft`žfwc˜DK×9 å Ÿé{ÞmGT�´£2RB3­Ñ>ÊO¹ÞŽ ôLùÕ‚wŠ6î•«Ÿ}ÓÚ½æ ¼ì›ÏŽyÈeÔ"²Ìû¯7r»m‰ÅDÙ“o·¾¸Ô§K­(iŒ¯¿î;ðYjj7óžúíì-z-Y”ug]¢HŸ½³ß“Úºõ5”zœ§_a7”·ÌpÍ¿†ï?Ž+@œ{ø NY ëé;ÖÿB¢ÿؾÕ"?þË.µÈ /±'È@~ÊFÙ> œ—°‚Ó·›§lßoxøl¤$ A¸ÂÆ.r\½(r ä–øSØt¶û3âœ9ñ«Æ`›~yiÏç”÷}$Éá§ã×,w/Îÿá›zñúxú’4á{9.¢öÈmÞÈásŸO|X É5ZÑÞlïw§òcí?O­Ét¡ÿ7{oÓ"i–åùýÎ9÷Þç13÷ðËð̪)¯”&¦iõ$R@"†š^© Qø zÑÌFh5ßKK-RQ‹êhœÁЦ 9 4Akðšê®Ì²ð{îË9ZxäTVMw6Í4R›­ üº››Á9÷üßÎ4ë<‘J7ÓDÞCº„ˆ¨˜`Ä`©ãÄô¶ûð9圖žNþ¤æ׿Ú&/*Ñeª)÷XEšV5R²¤iR²ˆ¬F[´† ±(B!Ä‘îuŒ–b‰¸'Ù&S‰Ð‘¥&Bï£UÚƒ QéêÍp±²<’ñˆ‡!ið2uñŽ·B0!bŒÖòèèIÑC$xô1ªƒ»wˆEâNcˆ‰IÈP U‰lÐm u‚DBf›.½ÿZïîÒ탕„ήs8´¡µ…càkÓ¬" –ƒÐ"¹úxhq¤ŽP†¡i¥¹dÕ„ôÇj²¼‹›Üyyå“ÍãŽó"郱ä$ªMä.¸vý½>t×Öû©ÐÓ>U¤¿ª[sØ)–ô¬fjÒ–§§:åBÑQ<‘K^—åÈáÔ>œöVÚAúÎ4×E‘¬y—|Ÿ}0}À¾F.È\Y ã£uM«,ï?ãÃɇ1ùœ©žN¿Ö™yÞ—|©Q£ãVô€ýÊd¯öÊt;<×9u-ÙVnŤ¬}7ËžÜr{Äo9Ù0Ÿ&Êš”)àɈ#½Í ôš¸ o36ïx·ç[eê#ó÷úõþõ——,uU(D]µ›óý7ðò-Ë-Öº¯åVT­:÷s×i®ØuW˜‘ øãåñšt¾›JNsÁËÑùÐóÑ4·¼¦X+Ûñ:vƒ=×LðÅ¿¼f}Mÿœ<q×°ÆÉÝîéuΔFñаþÝ–þ¿%hèwŽŸ;1ô·˜i÷mú•Åü}XQ ­²?À;ø>¬xõ)Û Ÿ]\žø¡¯®\Pvž÷í+p¶÷ÓKÿýúй?¯õ¦å70â~¹à}æ>ák¦{^f¸ ¼9ÈúîÑzöWö¦ýdÿây9{7­Ÿº>Õzâ÷êѽ‘ºfÕä)ǘ}Q!ñ +u½l=~ò]¾GxOÑ0×As,QÄÄ1•Íì"’³Z-‘u:‘TCîF_Fmv‡ˆ‰¦1Ÿï)5ÊÔóºË¼®%G2RÖ•èl–p"IÉ#”$¡‚Š2‚ãviïLnzZwr–”d¤šÅ³vqÑÑk¥7F5]’êêSPÜ%ÀB4D#Â]Ý=|@5|ÑB#ÆhÞ‡»$1ÅL“› bŽ1†÷áK„ïáÇÄ{UO32é"†ºªúÐІ&I†&3E5O‹”`ˆü¥ðëa­þD{džGX£¡$&5‹¨•MÝÕÂß1îBž+CS5‰,}ò}ô‡šnîë¿ÝŽþdÌkŸòPW9JûUD»ñ›³~\ùt2~e‚?zŸ$?Ù̇‰3AÆV}[—MÌ)ÌS^LD¦M*Yå45òm ©‘ZO?Í»T÷vG(2_N¹®•_R%·§º7Å*kAq ÿ%R1AÛU®|XvIöëv9êIýù4ÈõK%§I²æ¥½êAƒù¢…òû½eÔ¯†ð0v#í'»œó<{U©á öaHÀ þ ‹‘N(™´Æ2 £Œ[z#® xàcbGÿòœgýÕÛ´ýcò/Óåëë\ý–ŠäæpÇæá¹M:müÙ«¯Þ^ý§?Ç.ˆkÖ_þ4/ó¤‘äõ—Ò6g;šIJ…pØ|k¨žoö—Ö++j©‹´ž~6Ò¥F=¹«þ¢-oö÷P_°œAæõ9Üðý¿ÄX6lï˜oö3—F˜ÿanø; þv¤è;½ä»Ç·ß¦Þ|¤ _Òžr8Ãÿs4“-]>ÀtÍ÷áø„íÌ6(¥Ôã Ø«E¶GÉ´K½>è—Wùéô‰w=Hí‡ï뿯×Ü~ÎûÂa[X%âšÆÕòÓkJuû¤ü ôÿ~mù^ÓªhîÌ©—Ò”¿:æÃ1í«_2()rDŠžº‰œÄ´®eyâO<–ð{ŽC†ZA¥É¨1šÇ‚&ÕµiI‚ZŽ\¢XŒ(Xàš$‰cóèwž;“›LáIŠK b¹‰‘RjjºÊ6k*a&6Ürru ¢N(Dö¡>F¯Ø:tµdwY"‚aÖ”RÜŠ‹DàM莵Ðp £„‹k8áââ>|Œ  „.!æ#ÆÀ£Ë0Q—0CTTE1 QU#úbÑÜDîMHÉ,ˆÇÚ ŠkŠfª&É4“KÒR¦“1?ï«ÖOÎëÝã/CW¦jBïæ#,F q Ãs"iÉͺùgQ¿Æ-Úe•†‰¢M}Y×å©þ‚åùzYi"…qœâÆÆOŒÍnz~ÞçMI%ÖÆº˜^†Žãj­ÄøQ"ãÅʪvuÚ°’t˜†È© ¤W•q×R:¬=Hu?ä¢ôÕa$Še-íÝ8|2±qlPnë]ý£}>ð-»ñÀÌ>äG)Ngù"¦kÚMÏ<¤4öà ®FÃëßO ’_ÓƒcÙ›¾*óf#ž —eŒC4ܘœœIŸÒœ˜‰7:DƒÆ{Ú¯¸¿!A\p{ýQxVyòÀzÚ>mÛVËY¯\Я?ªHÖ�|òæêöâ2oNNDF™NÒö¿ÍÜ_p{ÍPvç7ûÍtPð“|m ÿ_òô‡å³kJ%/ì2û'v‡7¹ ÎóêûíÙtˆÌÚ«ii•ƒ@‡|ÆÉ3¦ÄóÎ;ø³Ÿó 6l®y …0Èö9¬ÿÁßýµ¥ÿ»g)ÚÁò^òÝãowü|ÿÅ\ó[Ø~AyJÝÂ?1˜^ìøÞ^6aó9wÉüfWÈ%(œ±Éy+?x+Z™nª^`y÷|µOå*è.Vû“[>\ЯÙÀ€x+Xƒ?ÂP߃í^ò¥úâÇ:Ÿp"LJ™(}¥7“ýß"?mÊbˆî ‚"ëY剓í“9¦þ ˜Ç-ÞäxbǰI3UûÄ´Êœ™K^Ed!i£“D0Mj2rctUÜÝqT’¨t™Œ´Dñ©ˆ­lšRÎ!¢Ñ%D’õ”‡† 1Ì#d¨‹º ™P"ŽƒE{&Ì5…ÅÀ\Ä‘hÒfžB#DŒ@ã‘öáá„GD†jðèc‘ƒ}Dèn:©šHVDBÝ$4Áh8;ı&!C#ܽÇò(›êCÒP$™™e±\ò$)‡Ê8‰ãéóû»OŽÎ|éV1—ˆû$Cc!´;ç}t‘˜dóÜÊZËD̑μ/£}2–0™š9–,RòbýW3RÑZÜÓƒÆq˜«¢ùUÌÛ–òˆæñ Ï?²²´²a©SÚ«ÆVÈ%ÊY*:ÒÐe)Ò¥¯U†4Z´ûä|¹cþ™ÞÁØÉØwa¼§}@~E|zE"•Ýóõ~œ’:áÄò*¦­®²M—}ueÄ—ºvJó—k{HÅ$yº^Mj•Û·œþ¢Oô΢h¥×}{K| AÀ…6! N¶³L–ŒånøÕ¨˜a‚%Nœû5îtE½Ñîˆ_ãÿ'íšòÿËôsîoøs¸<Cu·Zr)Å?”“¬®ó-»Âþ)((4v§×yœË\J﹵ݿ¾Þÿ9¯¾`ûù¿{so«ÝOZÛ¥Õ~?l—z]߃SÚšýꑇ„ W3w©ïÏNA¸RÅuìkæî‚žy–>†P­2¯/ÐkV×l>ÑWvÿ Súk/áé ¦3žgÞóúÞü{­â»¥?ÃíÇà7cãw‚†8ƒç�ÜÃþxül_æ|ñòrõú�ý?#/¥L°!v‰ýt¶·-¾f÷ú@c?¸„*/Ñ\7‘žŒ~ˆòç·å‹š·×öÙù©=|*É‹ÿ´³?}à¾ñpÍÂǘßußõº'ïpnw±Ù§“?Mé•:Ï‹ä{g÷wãi«+n2EÿÊô§“ŒH}Ž_y{ÞGÎu6YŸfÖ¹»öIÓìÙÆ+è‘õÁÕî~_d¢¿.Ó(úäbɺ˜ ‹Çêêˆãâ‰4%é„JãÁŽS¥ÛÌÔ"Y”ny”䓉‰J„‡†«…¨tíÕL„„܇7­³¡\#ŽÃW!‘5Ì�¬ ºÒet“®šñ€D,áÞ¥GÄÉAX„8ÞÕ‰è]ê «È¢žÅ ŠâÉŠ«FHÂ"ÆpJZH)TÜU¥»[´æâtq-Ub¨w5TT%%+–gÍyˆæ¹J™(¥ÝÝqlâ7†ÉÒ-Tú ´Óпô_Ø”d5[ÎèÆç‡þàm¬¤Ïj³Î)•¼r4z “þ¸5Žqßâ§’Á¶#o{.-jêOÕ†¥"RŠÓG–úM+õ’gÊ|¯²ŒãœÙôã*(>¹h5¿'šËÏbü؇ªfŸ/»ƧWº†sô-$¦·{yË8¥œ¢J¤m;ݶRjª–phõ|”Ù–œÍgî‡à!¸ôºËçÿZåʌDžÉÁÎÙ ŒŒÒ /»UÊCË%ª-÷ãŽ÷ûñ 1,°¦5~J6Z ã×´·ä3Ê34!ßæ?<ãùf/vYFM §Ú {‡5$8²w.mÔü–u®´¶Üìÿ ¬ÙþŒ-”·T`Y˜Ïö%óÃÂÒ÷/hor£½ã°…§0C< ×LŸïS!;æŒ`Tû¥ó¶á×Ì`çäŽ@êLËkÖßfù=BÚwìßÿßðÑöÛóÁSØžQžQô¿¾U|$  N>ÎÿÎ|ÿNAôT·úª”úhz8¶ÈöéIyF=ý¿ùÉxsy¤6˜/ê¸n•}ºÀ6䌆rÖ¸ÛP/¨åPÏÈ9sÒTŸÕ­öú¼ñî:+óæf^óTí(Ó¥s¨\u¸{I2VùÕªmKÊ£_.÷‡Û~ëWœoã³,§ÿܦϊ=É:ÍÕËvIÿæW㓟åG¢?ke‡“+#^Mi›"gÚi~˜›žžH™DŠºÆ‰` ]BQ“Hf+±‰fnIGšHý¥ŽI)ªEÔ2ê †zCÔ½‹ƒ‡ªJ‰‚šG.a¥‘»¤nyd¡Cp¼‹,0G¼ªTÓ 6­1šÄ¤^¬BïÒômH‹|*"¢ú€1o½…w×côŠgl¸$ôeø²è‘D²éPLðÀ=b¸ˆá1¼Ñ ‰'‘b2²ÒUÌÔì˜K9Q —*Ä›…ˆV×â*A‰8ƒèá!‘Å'CM³™¡:Ý»„]ÂCdt´Y,: ÷Å|œÉDúhš."xO-†´äÕ4[)ÙJ‰ÈFFDì´Z¦>Rmé4b·8a§cZ×Tè§¶ pÑž{=9¦cïÎ:i6{H¹© “[œÛšwÉGqO<“¶º ?>#î|¦­'LùÞN{Ýÿ|MúýÞ®¯rÊ’ŠC±çë‘6Õè:[^‡ÕÖú_Õ‹»ãõ»Â^¡®<Úି"¶B¾;»ÔûgW²f5á²\£fGªÖ–—½ƒBst+lB¶ þ ¶&þ~ÁTX%¬ Ð60±wÆj}A’,½É‹ƒ¾aÀ 䔳ƒe&Íå¾ÉëƒÂ‘ÝŠüå«‹ò¿]ùOØ•Õ~sŠÀ‰^©ovýsHpúˆ»ˆg@{Su¤A¥Í]æ¡‘n� V7D¦4¸ù˜�xù[eÒàÏþÿÜ>^ð_ðüŒwß23óÁtAÉ”|?³ú”²þØ*~ó¸g0}›±{Æßʇæ üëGêñ£=ƒÂÁWO¡Ã_ðÅÙ¿8)繜>eÕ³°«Ê ÆYŽÜ–óC½7¬ÎIÏIÁ“À2âÄ5mwu\#iç²ÏÍí+ilnN·Ì§Ì'oV'(»2D%¯F¦ž³y"±M÷[;–ùmSÞ'ôÉÖ>Ù¶¹lòI±õ$ó*MÓªMöɧ®Øtëéò^2ò§)ýâÉØÚýVK±Ñ&–*i D:E†¸øP nÑTÖ*sÊkI)œHEkˆáQn8Ð ˆtAB¤I(Gg – z "a3¶É&Cd¸¶GS‚ô!ÝUð ‚@Ãу„çð±´bÍÒx¼|‹ø-’gÁ”d!Š`ª%‰ç¨Sø½ 'Zp µˆCFí£ÖˆI 7Iöˆ7¡" 2œ÷æqJÚÀš~Ì5)…¤¡â¤N Sà} wÆã;·l˜ŠO îȈñŽñ˜š×ŠhˆÐÀDUÙ=t81*Èm,]<<¶ß×r–²%Ód‚¨‡F ™&¶yMÊ‚˜§]«ªå w¡Ž„u›°+#eHáø¢#º0ToËÝÁÑ~ÑtMÎÈÚí„tã¢Ú°Gâç_zÇÇÅÝHs=yB:!å>ù(mIù˜v9R[osd;^ªü÷®ä/‰ 1íûêrIõg£n:F,èípíž©åþ~ß[ãúgÓcj©R1ÔaÞN±M©è±Æ†H /ËÇvhƒÓ–{k«¯½àÆÑ¸wVÆd¨ )î?$M¨ÐŽ±Ë²Ï…§™wOX­8™®¤´Kc/ŸÂŒïhÏv|zżËÜîõö†™ý“úgõyæÝyí£½ßì?™HYâ ýbß¡_“!_|¤ÁùŒquZ%¥]Ôýx_3Áê{d¸ ½¡Ãr]tA=@½`\„·oœþ¿Ý~g!Áï¼üxÁ?£þ6gð</Ô0ª ‚+Å) |‘ù¨H«p +xŒµºà‡ΰŒ3ß oà5_|ÉW—ÁSežšñ7Lìøòò—TŠ”*¹q»× üSòzçiß¹ƒNo˜°™¤l”´åîèÌTÙÛ=v‹¯Æk„ÝÄ§ÏølCI/Už–¾Z"¦ŠþÂãJcç5k-ôrú5Ó”mþ‘­²¯‹–U·À¬ÌIÉlZY M—#ž¥>Mœ@3?Óö`‘RŽá5ÅÈbED$é£wÚ{æ!·c–bf¢&91ð# Qs¬U|´4º² !(f•hDŽ’sf-¥HÎì/Ç!Ýs,\‰Œ"hÁ›k’Ø„vÁt}Íâ^µ‹ªiÒ"²F+£DW©h}ăM"©‡xKÑ¢{8<ܼ-]½¢XN"Öž\ò¨<%dâèƒ>DKèJÔÇñ@"ÄMºjG‰l¡C½¹zÍabaê#2¾Q‘#Ü„‡»Ú’K“è½z]¤7ÜÅPK¤5‚c¨úÈx•0Õ¢¨ÉP7D"4c’ÈScŽ4uK É’\WZÄ›±PiûÉiêhhoÑ–:Ææ¸+c•|ezª1û0‰h’CÊÐ’îËdiAñÄ]l{ÛtI2VFQ£ù؇]fÙf-&UÁÈP EÓ!”è9/)§bj.ÝroÚõë£å÷Ún¸9ð‚zÆœI ¬"Ž.+šŠžäª;|ï …ŽW‘¾+÷{»G7�‹‚Sq$”!¤‚T²!§xÆèñjé[—û³Ëöä ùêbf;¡FW¼ï«P¿ø˜Oׯüb»ä3æ?ÐõÜd^ɧW¼y•Ùžž•þŒÏÒýæÏß~Øq§ ²#Jþ=ê=ò9Ò‰ÏQÐÎ|Žßpß^Õ¾Í÷yî—]~}e@Ö\³À>\|´ÇÈ nÎøóÌç|uÃoþÆ€Îô÷¼¾ÿ¿üÉßIâwˆøxÁ/” ‰©ð|•á‚/®yw+&a ¼¡¿¢ž‘:rçycºæ9¼»æõ£öt†àå ß/<=Þàã´;{³ÿcðžŸq²P2%Q}Ë/™_#¯Ÿ}ɽäam OÏð5:ÁÉ^ } gÖPo'˜aFY!F/D¥ {ýø•ïW¼Z½dºu{>ÇéÅtZ‰ÄWÁöýöx)ÔÜPêÊ›æŸQ.õ¨DÎh«6& aäHŸ…l©>-+K$½qA½NGÄVÙf¡ŒÙÈ6¤wÜõ(Ñ’.¹ß®FO#”£¬7¨‡F$Q"ˆHî#¼¹<h,³,}q‡FËî šhV%Yd(žÓê\ªÈÈ4CÀyÜ«ªÒKHÑÅ5 ÇÅïÙH¸ ‰–ÅAH«À܉ wè¾h¯!1\é =’IÊ#{×^BO:eµdBÖ0ñˆHehõÐeubÌ¢]šáÐ$¹ZÊ I:zD‚á⤤˜9jH´P’<‚E¤Âƒ:ÚÐz­†Ðzëõ¡ù‘P3ÓBI®£§M´£Œ{uWO‚0Å0\S‚œ(‚¸¦ÐÉÌFòh$YÕ8+#Wˆ¤Ù½E¿_E;ŦºœÙ‡,©Œ¤ž¼i9j®Yß·é›Õveͯï‡ý¢n™ªÈ¦ÇZ¿–~ÈiW,ç\Œb‚hÓNl/‚TZ»*Æh»±¤ßs —c³VÚ¯ÓÏÿ'¹ØÅõ^!Éü}4¡N@:¢Ë>âÒ¥ÆLÌ5¢YìGE*v$`8ã~ïk\A‰‚baZßà+fêŠu#<A&"qgÜëvýÍv½.ÕªÎWœeR,Æh´²“/÷5£çÛz³­z6”˜ 8òr«‡íœËYªu]ýþ'?Êè=õ=¦8HÇVD‚3TX:=Ù5öst¨7ÛÆvÙ®÷^°/Q�4ç ðeÃóçô¿dœñî¤Ù K±Mï0Ÿß^8ó׎/ÿ½ÒÿÛûí>¦O|÷åGwñõÇ5L |ÕyÙxzÍô’å9^xP´³ºå¤Rn ¦;Ê å‚zý]Xi÷2ïÿiæÉ§˜# ֝ޱ%çõîÒ~u(o®â þß`B)¤Êhœ½~Ü—sÕÃÛ¹�� �IDATohÏ~\'%O]/Ûê «++tGa¾¥<ª§Ãª˜Ñ„®¸’[¡/Ho¨_"Ï®4Ãüã(›^>Yò*˜»ª«¿ò¿}³~8ÌïÉ7Y®ŸBp?ˆÐÉÎIdwíCžÕ†I±Žþ0jŠ˜rM~æžz”^<Ú”&aÆr”ÔUF“ácàiÕ-cÈRT‡H_ «â**}ÈÐ0$‚ã!AÅG4|4ód‘ZèDH´ð‘"²å‘KË¡ÅJVS±Pu³šÂî^›P̆[$º…´ÒCs¤PR€î-õ½ÕÈ2r E]ƈÑ]Ùi„‡Ü"}¢©Šä¤ ± ûF’”-—œm²È6,t¸JfLÃ7•Àª… Ä#¨Þ1L-“” šÆhŠª†‹‰ˆHC‚!A ‰žTpzE–ÐõY¼÷ÑÛCW¹˜­“Z’¤Z"‹I–u}Ñà>º‹àîšôQ&‘bޏР¤$`A™t®êEeÜ;ÍCC$êIø¬>KÄ)õ!$qÒ†¤!’$ lHrbþ}³ËçÄÅ>¶ÄêÕÈ$ý ÞFx9þT‚¦r™§jBhª{QÒ{€)±d‚}/o­hÒn>Ž÷Â/x‰¿ÞŒòC씤àèñ€ "w‡ñz¦6¦C8éïä_#Éá…cù üÒï¨ßÀ„͸ơ¿¤¾Æ¿Dž A…žvr¾;)ß[ÊHdò§c÷DöëF h þî•ÜlËYŽg—ž|!WÖþ«ÒÖ)UšŽœü(‘å¼ä“rRèò!Ê.­÷þ c¡Ý@æX(Ù°@xÕòÖ#+—i¦tUû®³{ÎÈ¥¥Ü-í6쑈ÎÞ­y²fy¢9êôßuÝ~¬¨{ÃÓlÏ(™úmôôß4 œ|›/T¿mßMzÔÿþ&€èÛŽòøK¦x—¡ñô†-l &އ²| /Hà+lEépÎtÃõÕW}ûEÎß×Ë'óáôáJ+Þ9ÆÖÒÖæ¢­ÆÙ·½äk¢ïjÞ×FyKÀDeéšòö˜‹¤j‰<a«Aƒ8¥}‰ÃpÚÄјu—l?¯¸R tÒ gÈzNœÒfˆw.Úܽ±$íä,'*ãĦÍ&¥û_¤³Þ_î;éWâÌcwç{ÉÿÜ9q2‰KMCJ¢Á{Iæ>$GL”ÿCì©Î§f=ØšôÀšÚX¬<hª"÷Î÷ƲÒdDëÞ"’J 55!êw×Ñ”#aá«IJˆG¸«†¤žMG2Ô"P 5TˆŒ' Ô‹;x¢¹ðÀ¼3šF-è(J‘0"rwzÓÅLýÞBE†É@#²0‚YôVÒ;=É’8f}jš=pÕÌÕ4OshÑH„jÒDTEŸª<xZD6D1a&9IJI%"Ô¤wC’8øÇ(FàNóÑMU\ôñÙ ‡´Ð£GŒ1F,#iëè^d•BLQ3sÉÈ,*á}#\=\¿ 0 ón"8Ñ£õá1PGUd²ds2]$†/qÿ0déóRfÆÚJ1cƒæh#zri.2ˆKÉyHÃónLûåœÜ‰ÈW!tý“ˆŸ ,]Èå€1<#MûãÎÚ^öð<“æçü0y.é¹/¯?Êuì rJ9…¼‹¾_ 3"PÇO¯ÆB´M{ÍÌNqGÜ3}†<¡ÝyèwŽ!û§øçø_’_ó˜Òß3=áìKºÔ¹ÊkêèMÚ>e’"ŽVâv»>Ùj.ý´Ó!¼IÜ3Vú?;—““2åÿ¹?½Tj”j©é¾(í ¢À`ôG£S§*mÞÞñ™™œy¨#‰’öÍþ`9·q’ «±¯KdA3$N2›™•£ OHçéïºn¹€gÿÑ{Ãß}Óå%‘:w6à ÊõïŽöÒÏo¯T}ÿì1€èñ/~DÞ|Ô)}qýeš3«Awta 8Cž}l°aÔ¢³@úùöû„r’jv4a×ð鎜u."%­Ëc³«ç©Þlož§ÿêrùßÏ¸Š â½Þ¥ßσ’¥,†¤œd7é>£±œàA–n¦W2oO"¯âÒúAìj)ŒD5J!!ÿ y¡mmÛ%WáSñïYŠôl3o'o9­äÉ[ärÙ¦ËÙi\IìsGŽDº耱jDG·œ5µG³Dš:ÿÄç=/XSyT†êȤòÁÒÛÆÊb²²ÈT…ˆê£ â’Š) ¡Jj¢£Yô )²DQI’†k›ÓÉC'"»€F³JÕ(¸á„ÆÑ=4g„§^S,F˦¡æâÅÉ*½„ö¡A=71-¡Ò°Pí¡¦)™¨'õÛ‰Þ¥j°D. sL\]­Kª!ê!ˆx"‘MæœJä’¤(a#D& IÔHæá›ƒeDÒÀ‚‘ï>Üûè}øqP¥Z¸-Æ0††  Òá*Ý´‰t:"ÚÕ&4 âôÀC"ð‚â#‚!=‰Šbæ8Í£{ïÞAUÔG©\Œ6’7qšH Õ9É$€OclŽÍ¢-÷£jŒ<’J´¹¯ÌSRdE^šþYè³ÑÊRþä-ãÍF�vâñ“ðÔçÚ·ú}\òåÁÇÕø¿vöùþlìëÉ¥j eD%5l_a¼ Ž<#­^ù´)»]v?4®JE”Ñ1ß³¢¤°÷Ψè þ„´B錠÷Æý KÌ…–ñúÓ#u y‚2arØÂTrn­8¸7x†¢s<îrËv[ÒóB¡”Ü|™Ú¡Øj¼áí/9‚}ŠN²dÕ†L˜'BAƒÚá1T¿S"?>êù’ž¾#giS¸ö‹|³ÚŽãjÄÔ cÄ8m»Ú÷¿lœ¯AÈÆIf<¨wovÿòlÿ­ëöcí]}ðù§7¼„§ß÷¿»†¯.xž‘„žò°£8åœtCó›Qà1§:®©ß)ýÊ é‚åÿ¶=<nXý þcgºþˆ2Å5~ŽÝc¾×Èd<‘Oi‰¡Ø wœÜîN^æÒK¡X§÷\û.Ÿìû~ßw—´z’ˆRûÔ>”ý¡\¾[m_Ÿ•WÔÍM‚ÞiçpCªûÖ/{¯]¯ä–ŒädÅ21Q½pÈŒy;éöž’ŽÕ<`"):¡JÌXкócÖû2/žŸVuºg"­f,Éä>—ÛZ[*òÄ´¶Q-7ÕîÒȷý…§¹‡)*¤9ì,lS§<ô>ûdeÌI£gSÒZÓgÒëˆcÔRϪ:pb„á-"Ûc飅 ƒ„˜VÑlªæê¨'m"Ùˆ¤f1p8£‹IÒ†Ulöž‚ä#u.ê0tº€·6CÇ@ª9BÅÂ׈jhB²™aJ–¢ÉP‰ðÒE‘*É#eJ%$¡ ª:,$eO)ĺ¸úp$oHUF[•dš7ª3>=v/·€"ÙF²P‡eˆŽPQä‘›ˆîîŒæÞ›ËQ%º,E”õ!]=RuÍ.`:F´§z΢“‹9Œ¡B„~=Zé#¹˜Œ(ñ˜(×…NTz÷j=$eÂEÔÄ’æl«$ë&㨥jŠljà>ÕaÖ¨·Ã–Ûc ,pÒ`®ÛØ)2ÏFߎ1©/ÍHJö&ñLZü éÍTû<*žîê6¾\vËùß\–O}5bÍa­»7¡îvÂÞ&JÛ¶Gé^»sWÝŠ}QX¿RÝ’£F¾ºòÌ£4:€ 7"3 i…M <(Ö‘¶Yјˮ+wÄv´½Ã?Š©óÔ¶ï7—鬦Ik×¶òŸ:;òér1ÆõêîuÓ/kN»2_I‚i¾×¤,B‡æ˜ãG&%3Åæ÷RžŸ5™ÆœŽš{yöé*Y°>ú}Ynìý¾,œB«‰)3)ɉÊñáÕ‡›íñM†K._\_ýíÌîßeoø®‡àOÏØfÊ9õ¯M›¸æÝ9Ÿt hG)! ëõ¢'ƒÔ3ê†Ûs¦–7KÿëpÆ«Œž³ºAßðúˆÖ~<ë7Ì0g¬Á ìš8G;©S ]Ù hÛûí¥=¯¥¹G“´ç ¾Ã–ƒ-¬6YR[V‡¦;O§¯çòò¤¼€©ä™Ô}ë4ПãçIÄ*G+ž6á?ðq9Êaxo²ï…E)i÷ yf=-†hα›Ù— 61„. ÁtPÞ5éÕ ¢I¦{]ˆü‰¥¤XUòÑ–ºyR{Ù¶QÜsüxðÓ=õÒtî:¹*ÿ*ôŠô§cSbÊ9‰æ˜]s/£§1Äz°éHë*šDüqÁ¦Z ߪ&,ªBÄrº r¨¸‹†û¨µ÷ÅÇðHXZ©¨…QƒaˆÑÍŠªHаê²DJL®Ù\²;Ý=†:ÌÃpk#je„²$EµjN˜i$„¤¨©e!‘ƒ—RŒÔ‘ð¨ajo•[+¨&NŠ—c§ S–U2.ÖDB‚>bh,êÍÃ’Úi*ª))Ì=… aŠ©«¸H„Šâ6‹ÅUFˆt‘¡ÙGºw?¸,""²±!AÒá¡=èƒî2‰‘×1¼Å=ÝÑ‚ä† I˜¢b!CÜ} ¥ œÏ£%¼ktgàU!ª¤”QÅT&S+QUÚZF×eèDÈ£§ÒÌŽbK×ã[ÉËí J«SPnOËzgg{ÖDþ‘ô¢c²T€B ÿ‘ú3¹ÝºL.¤ã°Þtd&_6ñNì}>YËêìÿáím~$Ë®k¿µöÞçÜ™•UÑUÝ™¤¨-¡ ° ă~„a$àÉ#ÞÄÐÈÿÛ>AŽ…ðD@jàÆ{BJ"»¥¨¯ÌŒ¸çœ½·Q¤H}QÏÇ4‹ˆÈ»âì½ÖoM^¿>©õ@}Š*EžéÅŸ´O<Ƨ²=èÅ@–Þkxí òáª.?åi o$~º ÛÆj›Qép¸€ hÂ{Ä<0)¦ ¤¢œà¬ù Àã.i‰­÷Rò¦ñ0Æ­”¨ #ľóÜ÷{øÅ¡h/9:yÈhûÑ?õ»’€¡Uï5ö* ä~t8ÑbÀü„Õ‚ußMu?™»å¢\„®¯3¿ë8.Zz1ßa޽}HöÈíãðCÈ ”�}Áx³}lÛÇëú?£áòûÚïÿ?iÃ?â½¼Âô ÕPÇoí�~ó1Þá~Â*‚¬3JEÈ=ê5–;€é[X¶ˆ²»}º¹Âë¯~‹f!ö[+è?ÿ]—ù%ð#à—_a<½Æ|^ƒÀ˜ÞíbÚ£`e0ƒtø‚îÀÕ! Kë½ÚAžÁ&D‡¼¿ÿ/LßìøG{®^=ÚïotþI–ÏF>_·Ù:|? ýcƒñòÝ­¼ßÍýSYmqºO1Êö„7³¬Ü2Mû%U+…Ž(¾—DMÔ€¢#^éØZ/ö¾Bª^:Ö.ëEVKÕ×"?@^&DäèhS–™‚ìs6Q…âxˆºÕã$CjAæ6°ë6BGJ#TaÚÔ4)ÊN–œD!ä€zh©.¹¸ (¡¤02Eù Œ3œá}´Å*µP-gBbhD.¢Ý$…Q<m!%3D'-°"b“0#ˆÈ‘HŠR&à â\#ƒ(¢0'ªIaqN@5e«Èanð–y’¼·é¨å…”ËÃp?-yìéEÕ>Öþ¨¸JÎK Ia”YDh­d”¦H”L%@$è™ÔsœZ@'P¥PCª’")BdäßÁ§DqEJ‹<ň€?,⪠$räHͳ)m@I›í£o¥f¶L¤Uib0T,B¨FôL ³‘(,©9! ¥ª6™ŒkNÃR„NM_©ÚƼ|°©¿-å}™ãRçO¡¯Ün»ü,åOÄ–H˜-)MÌmŠ÷“Î)÷­Šâ ¹¦O«®3gžd¾"müBô\C¸¹’ª¶FWmkPþTòfô¶tÈcÓÍ·+;UŽF—Ýø´,} HéÀû‚¿ÜÙ·ö±Ïf¡„ʆrñ±â-Èjð|Eß¶V²^ZV iëDSH`ôâUæ–(7èÿòÖˆeìÊØç.ðÈw‡4”úêphŸ¡\‰0´@ïXôý¹\ s{¥Ë¶<+ºº90o7:Þ_ÿë¨óhïÛ}?aŸð~…f»{ÙOOQ+ò ìYQ «�x¿£•ù{õÙ¦®�û^‰_쮾Ú_�_wÀýÿmø×›Jÿþùÿ€;t×Ï ­@+X~°ýM9y}…çGAýí m…“âE"/çµÌ5bój³ÞF-?n7o—®oq÷‘fñriB Ô¾À“/Ç•ÿ›k<»û($o®ñ¶bõCÔ¾xeï¶ùU±¯nrwˆ~›+ ‹<àøíÛûÄä;‘½+VOÌQó§¨{òÕÐT¹¼ÈúÜÆÕêþ"ʃO»<ísœað÷à/ ˜¾,òy•«ºÜk»˜Új½é›’±U®U„*¹j‡�0)ª@2Û…[êטe8Q Õk Ꟁñ´AvÄSæ ¨h:RŠ`Ǻ×2úò!ÇZ2m@Jq�Ò;šK«ŽZŒ8/Û‚Å1)áQ^HW„ SbðbääTWhB‚bÇôG‰+xðôˆS…Ï``U¤9Ò<ÙG2#tQéækP›H*S•çŽ *€ŒLw¼W]eY§iIJHv0‚PB>P.“*R´”:UÐ$MPˆšœ2$âÔd•rI«:­´^‚%úf Ç|g@L„©tUЦ a(šÌ4¡P,”ÎHú¹ÓRSŒiröDŠD=ÀLMˆ 05Á”U šDz<—ËH,ºh|ö]Ç:ã’¨’V¢ <ÄÝÅGAæ9TDvjdœq^’)¡„xˆ—@|ÌщR†`¨{Õ%!žÖ 3DÆ Åסùº@BEÖæYt¯±h¨Åš_‹ö]M8ˆ7‘0«*­ðMÊÏ ]8û½&z‚mÔR§±‘iÊ2mL@ïßâ —Õ1É:r•¨”ø €ø…üÄxpElº¯ò®â®Æ5xWðÃç —<ª/ÂèÿÝí«}�6ïâjÏøL«o0È@¬ ½@ `äö$Û¶]:›¬Õ%�+uޕǽ-('ä¼Üú\Ë}[ÞA®ÑÙöãœÐØÉÕ­~|µöo€Óä„:ŠfèÄCîV¾×¿ Ûéz«ÕæF@y:¬Nxjž¦€ÃÞOïßã~`ÞêþKâG†_¿×‹àú 8Ð e�ö}uS¶M/P£ÙÔå¸?§3Bü¿t¦ô­¢ÿZjÁ[׿¶I/;ÞžO KÇÛ»ZNÞ00]ay‡·ÏðtÂ#Q x… `ž`[e¨§ß$ÊÞ}$›.Ц˜'ýxÙ_üÆdéïùHŸWxVðìÅÇ þŸ <-x’(ckØ jG‹ã V€Àé¾y‡·_¼ÄÀV8P°¬'Ô¨@Îß±Õ3³ùÅÀÌ1?œJ ¬¶%ô¦ñ r›‰¸/1½ÙÛoô]ã_˜_³Wyò­Ü<­ÓªXýwä%ëFYD<tnxÊÄB„� Ðtì€KÌÓŠÃâÂøÀ%0s6>jùWÀpýwÌnú0奎1Äš¤IÝÃÀØ3oÐÁ*½±v-{ÍW©ŸhU!6V €:8&©Ó©úTm–é¿…œÖhEm–’©58q¼ÑOÒFôÁе¬jbMeˆˆ1÷Èž-²Ó¥B' $4 ~î_k1Ľ ëe1ŠNžÚSe ?©0¥5ƒjj¥Ô:MEM@!i%`Ésg<¦L<Ai2Mb…¨NÍNŠ “ü(O €tƒ¢Ð$U¦AÔ‰Ó¹wú£-U$Р †»Rˆ€$0’Èóç ˆˆ’ °ˆ®Éç:ž4_<šç½ç‡‚¯UþXäiÁ¥i¤À]dC= Éóâ¤fgƒ«CId0…ŒˆN‡€’¢`1 tg$ƒB’.ê™ @c [´?"œQÆ(UÔ2S)SÊÕQì­ú–Ô|Rl§Ó‡Ü5ÛÃÿ£©?IüLÀxƒ ØTÎàL#ZxU3‹,j¢aORWƒvLæinñ$ùX½º.lHÙËú¬øüM®{‘¬ d <6i‡Ä+¶-îKYÝ€æ­ ðÈ ŠG"N L(¹ã(³Ô9äXdHXÆ„ôô½µ÷Œ]®ËXW׊i¾ÄØé“}ÖrŸþJÆÖž7‰ƒ|~{ºÂ_ðp\£ R_¥m§©¸ÜÈ·zº)²ªYêL(ˆ]žní„òdç«}±]ȾwtÅCÅÏW?V\9> Œ½ÀÅ=&ÀÞB¿„_ã´?>œ6ÈUÑ욇Øüަ™Iþqhàw˜PÏÏ¿C;Ä ðë Aýè¯ßý9yYðú¸ÇgˆE⢠^ãYÝÍRÌkÏŠ†é¡¼¼Û½Æþ à©cZpQP滆Ýáàø>võóýøÏo_àb̨†i 0¬ þ+Å7uÙ¥úu;|@ie›ýâˆÀíð_�¸ÁåÀ<ÃW…9¦À´B)ÿKÌ¥TÓxi!®âº=i}M)HÃ�ºAâúCÜ]Ö/jꓬ›.µÃ_pTê$"‘ñù*qKC�Aäü ¶›2ÛꢮhY´­XB9¤ Lþ ù]ÇMæ6¨AºñQ&×Pa•õò~+rˆðÙ¥Bþ7«bxœ©UP(ºàÌ­sã0ÕMQ8Ó¢V¤Â"±d~ CVa%`–H ‚Ì€ÀÃ`0ºÊ"²@ S}°¥k“âBŠ¡Ĉ Cà`4®¢PTM/kEq"Q5¤iŒŒpæ1ô3©YÖR¦©–b$3#{È 9KWIB5¼:%iuäH(S™EÜ€ Uˆ�$„a�5Ä¡â©$äpM@T9 MRHI ’z®‚c@Áâ$dP —Àª³I,ð÷#ŠÿÞô‰ÙFmöT¸# ây“:!&0™#‡ƒׂj,PMpäXF€Èž'É¢ª¢R¤Ø)½'Œ‚Pq¥dFÃðôTN-£–&QHµËò6ç¿dÛ¢ÀŽHG¼ 2 3l‚ògH‡Ÿ þ#Áú“\ÿlL7ÁÏ"²q ï2j3u¤š£Ó¢JÌÒ2ó;Éz“Ö{|v!9ÐÆŸN`‡¨«Å>ø±ó› MYÑ T]óÃòbXýT¾ÚâEå±™!¬Cï n>²ö2w}Ùç jû ÞLÞÜñ(HBüï]‚ÉE©ãvˆuÇE -V‹Ôþ9ý¬u¿ÁØ„M˜ªž|Âz­A� X‡*’[ä6¬º5lÀ‹?­¸ÑÚ­uél{Þƒª{ôyï@3¼¯¸/ø±à1wÌŽ¼‡;FÁæêå 8V¼¿Â±Þ¶ ºó±Ÿò€v‡#þËsÑ?:S†îþ>4ð/hþAÈ`^¼þµ`|õÑ_ôçwÿ¢œ�xÝ/âË#`øÑ�:^ÜA¸7ܰ5Äû&¿è¯±y~‘/QˆB(P¤w˜zýêòn;^ìû7qqÞ¶cC#JŲ‚L(犣à“À‚ýè7è­Ý¡]·wÛþçWû—k¼>c«Ž€ã)ðx²@î1câ(Sp–°”ª^ÙBZŸœõëI £¬mW°w €© ñÖül7þ»ç†K»º’ dy _:è43ýüNž3À†P ~‡O¯¨—«YdÆ$u¡oRFêI„kÉ•Çï¦.:„o4?Ð7ÀVÉY X!Ë->ÙyÇè¿oü•?7¢sÚÙ¬0“QÒµ,0&jh™UÄÂT)¦D‰šÍÛ»‡ÎißÌê9i�˜¬8häQÌ2%™La’U˜ÊúZ-ZqL\—ª¢Šd¸L¦Ó²HÊÙö³bN:…¢!ÅÂßÁ3ƒ˜Ò sµu-³™™AÒƒ#!bnʬîB— !ÂÂ5zfcc¤ 3˜I§R#5AA"ÓÒN¤h¢’š$ÚyaOVòl•sðÃ?–D�@ dŠQxn““.q:#?5.”&º–2‰ZFHfqL)YqO*Õ —‰õäðÁ$‹‘‰€‡ŒÞN&‡H–LQQMKjp„z †Å@•™­£S²¤¦©QÁäÇñ—œ[Œ¸õÓ¤R‡[_˜ÑÇq_gX@ Ad"ð„1 3B6°,Að$îrŒ\“JDÞªÍ+r¥#ˆû©?p¾ìk\Mòh’Qm)–;ÐP¶n£§-Ÿý²ln±ù÷ÝJQc¢Ú3ÄTðU•w•0-¬ïønÏ/ e—²{%±Õ((7’Åí*«äU]ô7´e¨¤o k<iœóá4¢©³æœcNCcOɨ!çïò*xÜAöWÀ XLD‰]ÏrÊQåz*:vZÄCqíýêÀ€|‚è À'<€£â­à)ð™â"0 ¨#fä 1C+f–kŒ+<¾À/'L€ôý»þæˆ'Ž÷ÿ IéŸÕ†_SH/ øùå«¿Ñüs“¥\küÚð²ÿZ0vÀ~ºû-ùÑoÊÉ»ä¢×x‡—øÕñ¢àç?~‡Çk” ,âè£Ä}×vø1ð˜€ùö @:ðü¼‚”íúÅv¾ªå¢asfübÓpš«7.�� �IDATáÍ 6}LÒ]vtÇCÇ›~8½Ã‚òþ®¿}yx©x}~“H¼T<˜×°{øŒ l@Öˆg»ÈÒŽ.‹³•Ëü3ÆK«ÃÖÞNÞyÜ[bV â­â´y¥›-/¯¬~"uŧìÇÑßfB–³!‹ä2Äv-ö2¿êõ;,WQž*+Ì‹tÊ=Mµ®½­<<=Гóè¶Ä´&ƒëŒ0Ѿ\IEh(šóÑõ*Eåñ…”§bŸ¨Í:-ƒìÂ$^è0 ‘”Õ\ÊZ±€ H%ÑÙÙ……g¬œ'Σë`ð‰hq!ôär¢¤B�C sЬ‘ 4E'ŸºÌK-R Í0È!‘a„…œ½¨R<JBÉ‚ÕR$5ü—1^D>…=•y.³ØDU2Ifœ+J­Ð@ë”Hž’né-GŽîcÁh‚áBÏÐH$%¡‘çBaål†uœ¡ê’ Bªª(μ?£ˆ0 Gœ7Óg3‘2" R…d&Ùè¢%tTñE "¢g¨¹gö£n(G ‚Gp ÉrJi7f¤{ôˆÑ‘ UÅ[dD�E)’`R"›#žYä%hCóº¢hDªh(ƒÑHC†‘µûEôL79‰¹õ¿6?œCH6C& ¢%zA?íh{ˆG4ìßòf°E�Lêû‰ÿYøà3¤x¤Ÿæ²69×P¯zÔéC-—ÓT›anmb_ŸöÕndÚ¦VY5çÖP<4â—À· ê³})7¹CýZý*.³»WÄ6Ÿ—<ÝdÙ¤Nuî ŠMCÍ[àñ§~\u<Aô™¯;lŽ Â£4™_G^(d¥!'8ÌóX'¤fÔ¶d#û"ûxDm˜WX'fý‚›ðÖÝ›±—±' ¾Þq³· à ÙvrÚEOÜ¿ ~>ð’˜Ê޾Ç™Ãáh—Ð 58 Ùà»±ÓÓÞ§G<þ øå¯Ü:×K­·6üXMCéA3°ý]3¥·¿lðÖ>é–òª]oqWn–ëÃkÜþfçÁ@ í+,Àëk|q÷ñOßý |ùð%Þ~¼€¯0êmxܾŸîPú9ÊPpì˜ßÁÚxø!ìÙncEP-«ÐBÙ1ö²F|ƒeƒQ±žP€Uš£9êý훆ÿôùÎ>Ý?]a"¾ üÍÀ—Ž—¼®øî3 …/`Âïïá_büHÛ÷¸éþ0î»eêÅ/ÕþŒ²ÐÆQëF{„> Ë.®¶¼ÜNÛÕ|©uòÂZ6—ãqý òIaÝ ŽÝOE“m©« ª!¤DÒ;òïÒ·>NcHÞíqð=mn‰q ]æE—÷)Õû6²*¡ ÓävÈÊÊ“r¹.剮6¬“˜ˆ"Á8—Ä2(¤Z©S± ‹B 9\z2rqÂÔtŒŽAfZøÀZh‰y5(ÔP˜°Â,È‘áƒÙ%z‹2K]³X1ÚVÀÈH´ðóT‚¥ŠÖ„@é ´R²ššÎ€ûøÁ«Œg!3mV-ªB#pŽ˜¢L(J-`ä\æC÷ÕæMzÏ‘6„ŽqšÓ˜šù±üQP(a@PÄ Ò%S(ÔJ-4MMj@ÈsƒÐÇA“D R$HžÁ €d-³*f²‘Ñ¡–¢Iæ¹ -“aÔIiùqO`z2€8Cr‡ˆ!È1tq!ˆ! GÉ�# DÐSÈg­ BR˜@“P„ ¢ „dcØ@I¯±t{ñ)_çfϾ“i/ Rõ•ç66%Æãáv1ópҚ΄˜±‰]ä‘R‡Í-r…ÒªVK3-°òFK®X6ÚWr˜bgçä‚ÕÅ ,ü ¤Hc|âh°Óù0Ù¶¯'eñ¹Ê‡-_€ï¶ù¦Â2Jä¬ÐZ JúޱÇq—_uþ?Vý Óo/&µ_:´u¶ðî±×Ž´OUK™á,ö»gSYÊô�-Áyp ´@*lÂ$–CŒZúz�ðòòÉ>7‹W”m”¸É8°ßfàÞþêµnŸ·Òô攌ۘŸ¡ jEd·¨„䫹l})Ž,‡üÛÛOÞa�ÿîsÜ_á¾`zçï~—6ü=°ÚÐ*:P ú¯†Kÿ¤÷ôåo?ÇË+¼^ዊÓ@éÛ†íÃçuùV{{ÎÞ}OíW¨¿†û_‡Ôîðø=`âs¬Ï5§?Ä—+`Æ&äy˜óf¯ïPÏüÛ+ä3ˆA: N×ð‚°½Õ›ÚZr´Së2íÓ y†x‘(‰Ùaè÷P :p‡×?Üÿxë³¢ž\ŸÐÏŸc¹Ä£ ,¨8òc‡Ü qè x[æ°œa óÔw°µUi§Çìo‘'ä—ÈÏ_ñÓ-ʥȼž¯ê\§©5wjúê?»<…¿!7ž£D6éß¡ü´ë¦‡™†5ÈìH\ ðøIÚéþø°s…æp÷2Žóß=VÜëÓÿ0& ÿiÎsN“°@7´Ë¡Õ¸ÑÕZ«ƒV?‡Þ„*J"!NÐ1RTÍR'ÂHãð<`¸N6Á /ô¡AxZÑ HZÂÒ%ASé $"áéÑZª5i) ATd•(™D†$�]�€”¬P‚âÉ¡U£ZU5PÅ(±Î¸TjƒD" *XÈ"0ƒž ÎwËC<ÃÃĨ*"lG±Ž³ ˆ‹’t‘u‘"*�<�0A’T˜‘ P&ê”"Ô8·Ldè“Ç’�%”©‰ó$4¤p¢mPeɶ8"…¤P›1I£,J£0¬Œ˜‚n‰X�[b ;BUHŠI9²Œs]˜:¥çùÿ9 s =’äð³9 T$èðᢠ¡s§ªGv÷eô%E4íR¢~ÖpÓ¬Ü`¢ß6Û…o‡m9WôÆå®>î§ùÖpcóKYÓM¶êux+í¡buÙëÄ!)ê1 4´ 9J~m@‰ý*P’7-…mžû"÷Ù¾uá:-HGóÓ>çÝÉ|ó¼DÕ–+ýäù8,Š*ßÔ,Í'd$ÖAmâ]bcì±¹ñ£a§&¥Ì’ROa§–à è#t>Ô©E¦ 85~Óõ;Lƒ·½ dÂÅçôŒÛxĪì|µ×Y€†,*ŠnE¶nµ× Pž oíÛSEiϰžUˆá°>4bÐi[ÄÖïëxhqr�ï@àê ÏðÎãŸX*Û?1ºC{ñ‘Bú~�Û»“"ùmaø'ŒLWxý ˜ðØ.¨§][•Ã÷ëßÖúú P °ûÑ´ŸŽ¨À 8÷ÀðóßP¦ù@\Ïð{†/$¾ ˜xD~ƒÇ;Tàñ›XQ/Èk”;øäb ãÀ~*§=ÇÁ·0…­ —@žPˆìˆGø{¸b�ºBÿÿSÁ'¶û¤ì«Á–» ûSEÛà0ãk$.Ö`.¡Š^àŽÛ†WÕ¿Ó?Œ¬Û´W—}”Ç"¥ŠjÅeÁØ¿Þ;vò­­o·v¹Ù¬gCÙD­FdŽ‘Ë‚ˆò‹®—êƒíï’]˶ÌÛTÔ"]¥gMzdIïD šŒ^Û8∶tœêj¢Ìrâìòâ¯í—Ào¿âåÕx2•y­³Õ©²Öu)³M+²*(è OÏ$•ªU4éÑ@$£9µ',SºÃ[Äãàc—cœÙr2Ð=½¡/’+“ NƒgrCxŒ ³ i*} ‰ˆŽ€Š0G†8 ¤°ž˜ŠHG ¼EŠªˆ¨P’’‚sQ% ´RMeæƒK&á)@R@s-¨€�ä<GIŠ`ÁyY <›T1Šê,(¢)ˆ¸š«ôs§3D2 ˆUH9ŸhŒ a¡•,––yƾ‚T’)âgÑT&ˆL$…"F3À3KKå?WP‹Ê ¢.I5AWæ1zf¦g|¼11%S¤']…´"]ƒFTa0»bHf‚’!9C`#ÃTCB))#3bøùÝÎ )éìíAOøØÛÉIpQ›<ëQtÑÂ7ÙnÆü (“Î Fš¦_ª}ú¤y¬µT°0]óëô?õ‡]LûīĬRçf3­ÐÊ f\–ü ýã ÆÁ ”2k/yØø6QKôoš\?‰ò3«ÿMYc*8ZÀ?d)ñ}x¶®|€ŠÀHtôŽ¡Ð'‡\oC6ÕCV ÉoNøºÅÞˆÉQ%n¤ì€= Yv6™¶Y ÙKyÜ  ‚>c™`å|ÌD8Òà±/çñl øOðO¡;‘"R¥Wœà(9v3ð"ñåõcýr®p¼Š"«ÝªîŸkÃDÀ0iˆºc+yªu8$ æÝôb¯+;Ø>+Ž¿2”þŽ™’�<SH ¤ãðîc¶ì ïûñoøYÿ¡‘éW­™/©¡QëÞ®nJƒÖ¾`ŠýÔ±Ý`¾†œÛ*€Ÿcìñ^+þ¨ ¾€9² b—¿Úi7Ìx@Ü׈;ðñe`ø�:úÝGÉñÝ®bQn­CÞíðÕ¾ÿä»ÀšÀ ?AÄ@sŒo€#Æ 0Íxv|u/ÛK+³ßL¡)½Ä¸)«ÃÞ>W€pƒØ%”PETÀÅ6×+,õít‚ÄŸêrƒseVmžO ß¾ÉëËñôRÖ:¯6³j¥Mgî|ˆ4PC¾=Éð:šä„<"ªN›R$ ºhG §¦d*„k"¤lUæ{ëYÑVTêÔʪÛêkyºÇ^|GWS¬fÊ\6S½(óÚ¦2™V ËæÑb ¶H/ˆ¨¤ B¤+rxé>GËSºh;y<ŒñÞÕnbP$Iü>x‚0Ó2‚Ñ ¥Ø€”Ì9R˜ƒlI‡’Έ£ã¢÷#]"4J*¨H‚• 2…D†P±"ÓD)-£ŽHBDHJŠºÈy™,ÈD&B#œAb]r$¦Ô€5ªš€ˆ@2E"5ÈAR(ƒ˜‚IP(r>D¤†EDS5TB’yv7%ÍÉ�2=Ù™É &"#À ¥ˆ"Ò%ƒ`‰Ì œI|1‰tšˆ©$ “ûHvð ¡EX‚È=¯ %‹ (¥¦H gvú9²=<…>F`Â4–’ +’¡92Ï?`†F@4ˆ E²FcvÙtýý«Ñ{È<|íÃ�Œåˆ±âô"ÕV"e˜ô1HŸ]•VÖ80W…[¦#µ´½;œ{låV°EÖ‘92Cs³¹r.bp¹õÄnÖ=e‡ZFàÔ|)Ág–ã%™ÿ{“Œ‰®â2…O‡ÒЛû©Ó© ³B ™õð$3 =ãÔ=޾o‚:£x„Ÿ¹;e@6èqßö7y½u©îÍ.QX`„ šÂ‘ ùñö=DÂKÀÀ;à{;Á^Û²P£jħ&%çþ\êíK´mjRö+Ú˜*ˆÄ�N@){Ä W­Ë'm\õ§±×Ó+ùz›½`ÜtDŒ?ký_¡ ØWP ¯1Ý}”{®—ô7FIÏ%ç5ÃË;¼~ ¼žРOÀ'‡ …Å%üÃÓqØjÇü�»C�À+`‹Ï ®nðü€é¶ñƒ4ŒâuÅËGLoP7à ?„ðøó;`.ÈŽÓ;àíîUÇ–­Lq3]Vw·ÄÞ¯! ^`5P © Ñ>àt¿Çe ЊRaº}Û<U®[è©ê‡ÖÕ¤C«sé Bj0… »R [õ'U:–VÞc7õC9a¬KczÀ´¾õ-Ž‹\W™t¥œÀÚD{°…Iº©º>›«Užƒ,ƒY¼N´™µ@PdȨ‘Š“ºx˜6ð”?w±Ùë¸QÑIÎiáüé¯p9‚–«u™­–¢uS뺮6V‹ŠŒÈ̾¸G$È(™Šˆ¤CâìEÊ{—Óä(£ùr£a3u©e‚ æ×™ßIƒ©z’\!˜C´x’ÁaÖƒ0§žŠ6aÉ”`º¸ò(! § (Ö” ±�3 ™`JJ$Á„$*¥°›ÌL© I"¦ÇÙùŽt•˜GH€ˆl¤%«ÙºªŠ %Ï7Î@Šœ_™A"EI3™> žŠ ‘K2ÈD&JòœÐÍðHw#Ó3› “gÃ+RÈ4d0✰QM*„Š)T’Nq(Š"Áð! Ÿ)¬ †Hj¥©é¿âñÅ`dH’6"0ç£@ÉÈÄÀ�)LÍ å”VóâY—ÁêŒ>²“Cðªz”𹼫¥¥XÓUjÏè‚B…˜-'˜¹dŠ+œmWÆ>Ÿ"‰a»…NQƒŒ3D݆«1zAì|þ˜e«}_ªûԛԦł=tŠ“Ä4 ¯^µ­†£µw?sè»<}ß˽¼ yuôRÞïX÷ÓÕNd¿ÖãûÕ3“ß<žþì~ÆØàJw}µGà{¤î8€ã~¼Ù9ŠßU}Qí)Ô‹q‡ØgÇê ª¢+Ë$POÀ„Ç„'êÕ«²ÛêÏKÁ ÿê_ü¿.2w)³mÓ:ÕöY]ÀëQ6ÞŸN‡Ù0+Б qüc \à€À°r_ú7~øƒ@ÇvµÙÆûÍã¼+§û~³øáwhëk¼¸ûhÝYÝáø·ÀÃ5âî·ü©?VÀå9ûü9Ú–‚×/��o€‚·Ÿ\¡NCU<møÑÓ#ªãâùèØvl_^Õ×/6xYЉSƒ^¢_â¾~Ìy½~�$Ѐ\3h¨m‚í±Ê5b ½Â(ßÛ±]Z_4}ûTDAp9]Mp?áÔP ˜9� ëëB¯ÔÚÝp[ºœ€QʪïØ÷çèY8Â1 8ïkÉ=x£«€Òžþ¢/}ï°|h»&{rWíjµzªXŪ@|’¨h€"Îâác”Ur®iˆœ2$b”H[‘SÀ ™° ÍMtVá4y–ôݘöé Œ¨eUdM•®ßEýD²P^¬¦'Ô'bOŠÍVfQCQ78HOÏì>" )==Õµ#G`ZÄãÒùh¡ëàPMt+iz&휺vNs}Q"éKñ`fO-@ H'°!Ù%„1A Ö¥ Ñbˆ‘,Ñ%SP˜… 1“µÊ´A„‘DÐÔÔ B!ÁB+fVL­‚HQ$=˜1Î{”TAÂLw97‚åÐ R*‰l™‘H5-2©%=¼!™‘© ©æÇ:JR™<,’j/ ‰ä0™rÎŒd¤�*¡™#œž92BxVjM|´5eh@xæ¹tÁžÏ.àYLRDD"R™‰´¤®ÎLFA)R” fŽ7ý<S©™î` Q1( J2"˜¤,tUh…*¬„Ih4=޲¤‹µfË’âÃÒ"¦2/(¶ˆtHf(Ç2äÿeìíy%Í’3±ç‰ˆsÞ73ï­[•Ó]55İIQÄ — ‰c ®$G:­uôËhj0Æ@&q!$äh£-n‹KÖp·»g²»ê~d¾çœˆñV¯­´#7D÷qžÏè³ÌÐ, |z‡ñnêÇtÄ› Çá3R%FÎGóo{.Í/½??jE!ªCâ ÂƒŽÚç±Eh©fg˞ɞM€‹Dc?Ñòfä¾eYpý0ã³¹}ºið~3™}s» <·tœ Êû§ï‹•²—©DÞ–q’ úÍõik†qúãöÙ¿�¯ÛpX4†e¥kRœ`.@œo0 Fºá´Á|½¿ûíM•¯2ÿ÷/ý“_!ª˜óG™×ì5 jÞŒ¯JBå8¯¨”ã< :ЋAO„.w¢hq€7Š“.µl®êýãæüNÞ¶:ÞÊîobþåì 0‚Í ÎËwyí5ä-6À `ÐopúÎÒŒo€�^ãj‡'lâ{‹ýÏõáTvÿˆÈ·`�gÊòiE©�~ZËçvø(ð¸A/ÇT|m¸üÕ¯WC�lñ>A¢l‘ -ˆrA�x…ɰÁ!P®µ.ç*DyQ²ÂŽPÄ^ ‰nhÄñ»€'ösGwpAۣ˱_ߊ´…K[ò±½o5?nÛ¹SÓ@tDC>!p‚*Òà$BNUÁM™Ï=?>É¿âò䨔íqS>6}ac¢OQ0ÐFÑ„‡S­ ÛÐKˆR+±^äéͱᶴäÙs×y†T”ù®ðPðC¥rÌ ‹reWõ¦èËFu#R’ßÙ˜ž}`ièž]<ðî)Ò-/ÉÎPqIÈÐs÷o† ò©Ê„º1©ì4M€ˆ&™‰ Q±^35R…’y‡g„Z°7à^ UÕ0-ºêg¡ IAKXjZ¡Â¢¬´‰B‡ щPZU1û0*Eh&Õhk”…"‰F"M¥(T!âéÈ`taÏÕ¢¬¤ª‚èžRtÝ3j‘™>Ô3Œ$?DÕb•Ю¢V’ò!h0õƒóM*!"É ‚™ž‘t™.ð¤Ð?H–"ÜÁdz„'˜ŒpGP¼¨‹{"»ð ¤B(Ib„¢d]K™™0¡QšP$E“j ¨HtfK2œá:†øx’z`T a"«> ‘„µÆdƒˆT‘d&è”<ÏŽ§á_/(¥¸™ˆm¦¤Œ*>–BY¥IŒì9ήgYNyTˆ@ƒ¨¤@*‚-yR¼ÄC÷rZ$6‚’`ˆqFC.½8¶ÕF… ‘ãrNºû|î ò>bŒŽ&ûsî3«7Lµýôê~Ôþ÷ãôײŸm¿íujÍÆIýWœZ-Ê~›å1®ß£î 5èõ~Úîr@ÊŒ¿x¼àAyüÈŒ*qÛ%P~ 2a)ðŠeÆf‹˜Ð ¨‡‘%Æu3ºóu´—¿ðòk#$oùÐ�¤7Œ¾“£ŠC ž£À;¦GÔZ0¶†+àÒ1G&6Ž-ŽO¼ýÖò_^øçOÿA ÆB8ü?wÃôüƒ-€ìõ&Ãyà´ÁÍ ¬àùǘßaólí¤.ÿ·„ŒO?ÅsÅT°¿BYu”­Ô|W§†½-À!p\°o>9–›Û}i7Ïñ_²Q?’?ÞÆöLùÇ ÿå[Ü!ðBð‘b˜ â°à8Ã×3~Ü‘7¸ža[¨`Ë£Æíc¶yÆŒFô>» ¾…ÂðXp¾nØ^�s@6ˆ§Ž¶Áýîð~ÕN×È{¹ðýÈåY)S/ói*‡ Œ'ä×ÐõoeÈcF/(õnL5¤•h/`Ÿ ãPò˜Wàt€Eš0]¡ÉHÍ Ù]>:R1ôUú+fhM)™"Ã#h%²`‰‘qazofV\9–Vn'ÅÝXS@³h¢‚;¯µÔm)›¢“®"!1² O¶‘­kËÚ„’£çšu½´\a4¤"³ÁkbXKU)R•jY”á …Z`%é ¤PtÜ3-3ÆÀÆAO.™ÃÇÎ#HA7i$ ÏLIi‹4H…*RÖδŒ3n@¡# DXd•R E ‰’á ©µ°Q@žêHψ„¨*¡R áé@MME€H&UÈHÉÕ±Mâ»÷c¬iFÁ•vARÖƒþCN+Z‡Lbí|CE@JôH‡;3�Ç€x"ÇÊŒ Ã×–%a*�R<ª¦%ÂÃ=5\‘]$Wé¬(eÝŠ+ò¥JC°†ŽÒ­e\Ô°°¨…$zÂ2ÈUûªN-R“ÉTC˜A–L_šYò¤Ù£eS~O8#¦®³`kÍÐÀAš[ê»À™ñw®y*`= mƒ=Í(=´eÍ_±°Þûç4l =´þÑW©D…6s,KTŽ ®‰úÔØ…Ç'–(—§ê¨mie{ÿÑô8Õßü™6YvQ7Q5aEË!ä¨v+Ø/}; }²i~¨~]³ÖRK­tŒÒóÙ55ZG~¯öÔl–úlÈ¥ë/)¿ÝŽ;ˆ5`RÖ#´`cG‘[+�Å ýÅì.TÇ4Nö ürÛ{ÖfÔ Ì ×¸šÑ ”'<«(Wx± 0œÖZâŽ]  O>ˆOæ?y«·í»÷ÿïݰT<½`~ zA3,wÀOwØ\A0 VÛ[<}Œÿí? ž+ö/P 3aOÇòp[¤ñ+èÍÑ tàà ¦—§«-ðîË‹gãêb»§öùïùˆ'ü7‰Ø^°»‚µ71öÛKy·_—“ánC, Àfl&LKxžf ô¢èÓ¨XK¢48Ð_%߸^0 âúð˜ÇG¼ù×Íc»}_꟨oû¼ïùû°;ú¡ËqcÀ:øûú-øâ5r®8¿Â"o„û+/*úÆëË›ü£}©%žßÆæ4æ»'ùs_b¢[xô‘.�dÚ§üª ýÊ9•4IBVS˜@Áž¾ôþ4²« 7Kù2â{½Z” g- x#ø³ z)ÓeÙ˜Vª@ ²­M2TfZPzA¦J2Ü12<âÌá�[Fª3}Ñ`È6J¥!ÒS$ ’êA&],E¡FI”®Ã%„ ×LJæ%EDõŒt83Æ@©ô2B" ˆ*©º«"™™éŽÚ ªf‘`¤d½’•jXý‚J!D HT¢(Õ”d)Z,E"bŒtb�²¦­ãϤ˜E<ÐVÀçC!q0…¬EI˜d‚�!„D$|Õs!&ùay$ü½m!�� �IDAT°®õ›ÐH®ë!“™ \¬¶<„-Ó9HRƒâª t0ŒTR…š'Â@"FzAh•Q4DÂSF2Ö%†ÌBª¨RÄ9’=Á:zgo9•'ØMèâ˜a3’*1²‹ÂBx¡¸yö¬Km¢eß üi,5½ €)¸܉PQXŠª«jó”³â·g !/Ȥ@íxžn“­&Ffñ¾•#ìæÞ·¥ã¶ŸOçé ®Å1)¤Á<¶gáŽ!éXFù·ËÔ¼ß7މ Å%~ûÎ[ixïmýUü¦ÈãNnËÜ,QÑ] ‡ÎY§”šòýs‰ÂV⾈neéÈÒ&¹·"‚W—ó&K;[ÏlÛ«®ÏÎmóƒÚîø X1™`ÇÔ)\ÂåÒ­ÆN‡âѯ‡«§#ÎèçÏððOÀ �*ôõ6 xº &¸`³F%âºàëÄuÇÐ×;S|Ž_üu—«·å øC|÷ ˜Ö^L Œe@€ÿË\W9â5Ú[<߬¦‰kÀðÓ¦kÔ @ø�\NùÙªêþú´êjw€½†Ôùn»…á|ÜõÜ•ËÕvžvÒÿòñúÛ§ƒÉqZ`X¢êž—}?×DëŽ{âÞMÁ€R¡ ç]MhÔQш¯Å $qåø²ãÏÝôFë¾±<ùíIv¯ûŸÊî'Yž96ýÁž¢?@þý'G¸à HÇô{àú�þ £`\á¼Á}=\Ê~ZöYëÖ‰l`îëÓ+î8këŠÅƒÞÂÕû¦›´® xï²C¶B;D…ëV媠®ÃŽp§‰H¿èã ý?Ä€ ÛltÖ³ê>†²N¾Ýj=ÜKÿ…â#ŒWàV¦–Ù¦¹LXÉ$<]$™9ØF¢‹•Y+1AMÈÌNÅÏÂXÀî^˜‰ «< /Öµ¤« –teØŠ†h! Áq«.±zÄÜÙ‘iZ”!b’#92veFdóÈæ#+W%½‰õ¸Nœ ’Z%¹v®©@J*+QÆÒT )NMSU1[Õæ©ÌḆö ¨©Eõq 92#==2Eåêh ƒ 0€,LÿPN˜k§Ú†aµM¯Ï RVjš †'$�¤Ü "dè=>…(H¡$Òµ+;³'!¢Laˆ$[Ub‘™:˜™)FÛ˜›D"GÏe¬XÖj³‘”„d"‚C<K �)EÔ´R£ìB[¦•MRª)"!H Eš-E3ÝÛš;ÔãÏØw#K§,Ö‹5Ö]‚b·ZS¬vÈ%åßYÓ‘ŠV‘„£„ÂíÔ±ûVÔϰ‹|ce/e/S•h½ãßì7Ž"olÚk^—vMw÷eL£éÓY6—çÐËÕNæH•¥¥¦ªá9O°V¾·ô«ËÉXš§Z@)Œj²Cû‘fϬ)£Ý7mŽû¢]íYv¡.àôdY§ÚIÑËñ>ó[;ÿ˜'•v}?â#²¡$|‚˜ˆ†@áùëÆ[£¨UpÓgœ_æxsyÚöï~Vóz[ …ðàtP=Úª}›1$Ð! 8ak€á@M c�îÿzùu8d•‰âðvÃgOÀ#~úî»ìÒwøøË‚}GÝ`3Ã�ˆŽ§·xþ øl-Qø+�ø\ñ㊠¡¬¢ÒÏî&�ŸÎ7ÇV€ñìê¨oÑ^¯à'T„Üð¾\f)â”®Ò$î7rÜ|¹¯‘óR4*°éWØÙâ—±ŒøÝí»Og¹ Ã̆ H‡]ŽÞÐ .†â1ñqÇ•Cªà‰h(ó=¦WÙé™O‹þå¦>Û}-Ï2·!DªÝúæ˜ùóž¿é ¸‡|ƒò|‰Üâqƒ®ozÙßã:0טÇ \JëÿÃüÍõ„«©«>m{ßißxß-[½Œ:ÔãR–@kxÑ Ñe+VEJI)lCÐCDò4ÕwÝþé|,ã—•›™×ê1PÒ è%¿'í©[p§Zlžt*¢LAzxŒ‹gOƒb¥*×Ë\Lºd€-ñ� dHŒŒFIGƒœ‰^q'žRž¥¹K[z$%BFfW·ìE[2DTAf/pFqNJQ4†d8=4‚A/ n<º‘¥h!ÖäôHñG„$ÖWAj …&jjbÊʬ”DÜc5¼išQšP×|ê„ ¨ÕÏHBEš“Ê„‰u+dD`¤ÉšÒ!�’ëìÏæ1¬Á�d( *T¥|°^È sQ ]#`Ó¡ž©žèD$‚ɬDJ&a ‰if*˜™D$ ¨„ TDL 0é+y-J•d1­’«V5àRèE–µÒÎɦ0VtJiÒU­RÅR«Bdˆ…Dˆ{å(¡ëÆ… ‘’"fŽ,‚ ćf( 0%™Ž_d$Æ9ñûìß³¸*šjy9¦ƒ œwXV¹çŒP8ï.y{Ê«çs^Éô#ËAÙÊ,H\PBtd9Bö¨ß'7ÂÊtá%qNû²&&¼šåjëÅ<ÜêEJC“£ä¸Z~…ÇCùö¸UHØÑCî²BêÁõ¥û¾ð9tMd}Ú•aGOˆb�R«J æ­fs?ÛúWuù#»,u«�$1z=ÈÍQs‚¡&|:N ˆ|<ùl—9÷Ëï7ý8üg»|±)/ÜjDü›o[ßO½¨ÝÒN&wÓwÀ‚–`€9À1 ÆÀå p«Ï0p|Ç?¤aý§©­«Ûùó/ðÓט€úõØ ¤ tð�œçk“ÏK`§3žê.8ŸÑÑÞa¼ÆÍ±}ŒGàùÀõZC”¯€èt(RÀÚg–lMå"xGž qôÀÓŒr}lò7º-ù‘d/Ì‹2êejzÁ¹âë†gWMÌãÀ§#¿ÂÓÇx·Ã#q"6Àu‡ ²!Ϧ¿Hûy…P½?¿¶‹.U­og›ˆ2…ܸÕÞŸ¿Òúoš ñ·zù¦¼ÿRý¨/ïÒŽsA•ýà~ÊÊVº-F;Kç?÷¸úX®J5ˆÇ>çñ¡X´,Û …zÌ-ìK,W˜vÔ?ÞoTEU,ášçì"[-·¢CÊïf=ö<Uí¦`#™Òé=8ºø¥Ê«‚ç¦Ï¡9%U´Pú¡Í$¼{k¡gà‰Ù<k)›µÁœ™ž"žìgÁ%cØ!ðô0YBœv¶QÀo2 ÐÌ"0¤3÷‘éôô{Á‰JD—¤BÓ$ áÀ")ª&Q]cИ�ô‘ê.O5)"ÿ蕤jM­Ôªë¨ ! @’BMa()�’ÌÕïF*ELºDÂÅ šÊÕŠ ý`‚öP€ ¬Ç2RbõAcµ[çZZ(¶ú-”±fë­»A@#UT¨+Ó°Òæ™ðž™Q)¤ ‰‡f®T…'#* &ù!P DC)ºn3Œ1’žkZ·@Vqcm·dæ„nuˈ†)%3j1‘ ¥»EI1²’ÁA�%@O#B@ÐE\éqµé©E„e!Ç&-›œ™¿÷Tôû)•u†t(È7wTˆ!¦pƒ(Ä`qH/¿mõ,›ï/(“‰ˆšŒ©ØôúR^ÞHûe«µNbdËh¡_g¼‘àÔt(š©b\nu)ñt[âTgÌ hh€à„Ü¡óy°\²"ª.:Fе—éÑxçŽ%Q`€è†4¤ƒã„y¸×SçÍæ,›¦×Ï Sœ!=¯Ž#Gk+»‹!0ÁpXƒõ;ƒÈµuµ^ùP§¯î—×Ö ¶³,óì!‹ííqß§j¥QàY ¸Tö¦ÚþŠ…r;úéw§'D &^TØÏðô_|h€úÏí†Oßâ5°�üäS¼U|VðQG«°/ ÇͧÐÏ Úðüô%>ßWx^¯âÈì(ÿ„ó[¬[¿ÿó+ü¯@ð— n ¯!o_�߇íŽ2n9Z—Ú;7ûwˆcÜ�˜·Ä“À+D0ʧ¥27²Eß”÷r9žïùfÏ=´\îoýëÓ¥ÜáÏÏ*®sM?Ý€$à2'Kë(}x*›”ê©&bMvŸ7é!o8 £Kî0 Wÿ?n¹k%o«£ˆ×µ\xY¶±èi\B2í6¶€¸xpà¦ŒÝæ=|ÊI»´… s'Ø’mÅôhZDDÖ®w„1“#µ¸X˜5 0ûóLB6b4ig]ºè×U~Rø\ËidEŠF"Ó2×ÔOv´%ó)yvÙ v.21’ôôpè"é¤(c #dl„ e›xÌåYòÛdG txFZž‡�t‹fë�ÖȦ° £ÊË™äb1RRT‡é$™2èn=˜î¸ˆ“â(ÍÕ²º–RuJ­”5*¡Yf”IÖþ²ŒL_{k<s$=×v Ò‰$ ë»Ä É*ÿL]“üÀµ¦ ø 4x'WB¹¢IA ÀJá¤b"~‚!\¥UNd\= YÁ±²Rê W²¬î‡ ]ò„‚ݳCBáúªÍ¨B¨ N•VŠˆÀÃs%ªC«jŠ\¸Žo£ªz™¨¥ ÙZ>ÅXÃ!C˜¡f Z‚+ê CÂ}ˆ®4ŠRr¤¬Ñ~LHf�N]ts¶ÖŠôÚË8W§h2Q|XkÖstå>úÆ­"#0{pE%¶ÁTAŽcõÛŸ¹m|š æÅØ(Ã$&mWóØOZ'kfÀÒ2î¥E g9»tEæîÓ׬'`/cŸQ©W¨>¾œaåÿxŸ^»€_¾! m—I‹C‹cÐu@ ÃPèw òñÑ›éÙvUºNìå(Þo‰Ë](šÂ°oÁ'È8öúR¯ +ʳƟôÍ?-S¿j¨CÔ ¯ d©}ÔT½nzÈåH` ¸À•{}Ø©¬ \¿CŸ°Ýbž†˜ûwÃó×xñ»O€\>‚Oø øöé€<~R®nn¥œÊÏîtí|þËK|~ÌoÞLûY®ô¶lOwíc\Uà ðÌár¿¬ø6ߎã÷:ê[ÈOÁ4ÁzÒ@öíOýômKàf`7P:ðÏÈ?ÅS?,SË©_ÄÆ¸Ü„N3(¡¥–ú£<îˆ!Xt__Ý,ì»Æ×Ï¿‡»ò�\1øi*1/ó’ŠÁXÒñt©roç_Ã~I{†-‘öµêó1vÛp‘Å삊íô}ð&8_ ì'ö®½%@Z˜_jÿ6P¶ßÖ¾§ö˜ç(†,!צ¿é×Q^&4rëxZЩÊKåL“*»@ ©!žÑ2–TâºÒNù„ø](Fý¹ˆøn9e ã2´þDêèm'Rºž˜ÃGé1‘Ù9šô÷ß‚ÿ\ëµ*')U­P툈d¤¨ÎÕQ†D¢Œä”6ÊØl(Wàì¤DOFÒA˜Š4Á%µ@˜¼!¹ ZA†Éª0ÊIJLC×Ö1œlq%a ”0å¬Z…×$%º˜”‰e’b†ÔD|o„$ €d$0+�$I[ß¹FæQ™L˜AÖ&e V´hQ°&Ï1"ÁL€+�õµæA ÅDL•BI’X¯õc=$�„¢€ÐI¤ÓR %Uá"C-)îšðd ˆ‚Â(0J)E­¬Ê«á©Ë ©"U˜šCáH”Y±©R ÈXÆKŒÇ1édgŽ•ÐÀÊ$À±üÂÝGdëèOÊkGÏŠbN®/B�H—+ Sê=ä1kQãœÅ΢áxA}9l—FqOýùAü¨ªA4(d\!¸H‰";I‰ä€xÉ~5VU+ ¢#àg÷ûBݧÏL=âô„Èxvê6<K—ª¥Ž-°-jG~| î÷üv/Wµmì}êçßëÓu<Vœ[Œ.Ë‘. DqÀ@XX~óo¢ˆ£àn"J¬¡·¨û ª³M]0=àí‚ù=Â_ãüg§e‹Ý\6赜ô›;}w;½ïÖzÜ{`ŽÒ¥4–™•/9½‰¼óKÂõð½(5O•@Fñ~~|¸1hEJÁå5>}û‡vó·¨Àüö óVÞüw¾ÿ¢}ü÷eþéKì·b2òà öÏðéŒÏê^|•õª6c‚~Œ\½r/Q®Pë){xù–·¸9å'wü¡ZAÉ;8z?Œ~¼7œ žŸa(õˆgǧ~û~n<HÓ¬X$ÏzÞ£/ôPû1ë/¼~<äjóâZ·÷—|ú7ð/ñõÿ"×0!RÑ+¬5o=³uÔöõø¿–püÖýì­Œ«^æ}zä…~‰éK})¶1#kEô@)¾ ,BÕiÒrÚÏQÂ1?„{/â“ϼWÕoUo³0åäÞá#ç=m#²-˜fZd!ž)@sz´Dí–@Zw¶ë+çm¢dݤ uˆ¢NsÕç¥07ÏrºJÛ@ Ó.Ñ‘mÉÖ™Mä‚x|м7|9Q k•iR© ¢k¸¦0挘 ÂLÑ-5Jè…a"ÊXUú1:3³Vî�4”éàêºÍÉЄ…šŒ*EQ••°£° /ÉL^„!|FÌ)R†õöUUQƒ Ť-“š$]„ƒĚ—ÿр̒" ƒë”NJˆ€¬¾€LzR P"‘ HE22�A¨À’FR$e=è+ð•+ðôAдªÄⲦݭ•&E5cÊ€FºÂœ©îN/#2ž  @$‹‰5ÑÕµHQ†J53*SÃKæ©¢•me)�» o [²!Ó…©È‘=¥ÄÉÁÉÌžá Ñí‘"ºHªA2s„È`¡p}"Lc®TŠ,æ6¿¯ÅUy:òïˆüÛ„‚eP{z„WïÙÀ1”ù r¤ÃÒ!ËïüþÏ;»Î” ¢÷xÊ~¿Uˆ™KÓ’ôô{‰%ÚCz-b;±ÖBº(Î%J² þ4ø®Û6 -[XOI°3X¢%e'¾Ñ³_ß/¿ÿFÅÿqsÚ_½*ÌÞÛi 4Á<¡&Œ°<‚Èûÿ6Ë‹œv9ÿÏÈeäËÚNuÜ1Ž©ÏÒ½Þ³.5KÕCÄ1–yû �Æq}g3Þo/òø<1½Bñ%[7žJ[3¤õAæ1æ­íg Ä¡]Ž[@¡·½7Y€hO¯ûãÛã?Ï~†Ë@l`ÛqýöÎÿŸÛ ï?ÁÍKø êŒZ±Éý.^=Ç D>À¶ÿåT$×yÔ¿ ÊÏëá§£Üôº•Z`I9 YÀO¡((±g짬?Ñv%ؼ¼@€á¸tÁùéx¿ ì;ò¬AÞâàgh3î;,NÑ0²<Os÷GëtQ\c;/²ÃK\ïRŸ—éÚtS‚þ¬/ÆïÞ!ÿüñâÐê1 `ðŠˆ“. —mï§ø”×w�ÆOöúÙÜBõƒç åÒÔÄ„ÊÌ!µñ·JÑéy”9µVƒM<æÙ‡H‰*"T‘‡ä£bRî̯æúl¶RÜpïmk3ühÝÏšO!O™`lÐ ½úøIÌ#« ¤˜ Z\f¡É\ÇT¢n£nXæD%…éôAšb—Ë“Ú{æ;ÏÇ’³+Ó’&Zušê¤UÎÌ0÷L¤b„ˆ„LH‹D¦Àá´æ€ˆ®5÷KêÂQ3Œ™"5Ù\›Jql„U,sbZg&>ˆøuÍuH�ÅS™šž |fž•!fj…¥ˆH-¹¡lˆIQ bà ÷¨ªV5V‹r]FÏ�#Ö Èz°“ ƒWŠH@I*3é’ék7…)L%$+¯ C˜!™Â“"ãCcóCæ%D~¸Å× {u‘}°Ì‘€ª 5…È´ˆÐϰ ÏáF§¸zaØ S)a&VEìƒ5P³B$AE¨w xZZÕ"emehR± ®ÕšP ‚£¡M‰ÌÈ|H,‚!pSÒÓÙÚê¦,tˆ ©®TX7Ô©Ã.¥?šœ½?DÿÛg»H‚>­†Œ†Ø:Ð ý }o,‰[áÉÇݲŽÝËí>õ zé8»ÿ>/=ÛI€ª€)tn>·ál§_µ<¢`”[QÐjÐxSñ 8»u ÿHì· ¨AO9-«â¬Á.—Gno¹…º\=I™›¯Ûînû_`w}96Ç· ìÖ…öñ%.�߾ȟìùÃg&1ôRûHB\àr¼=G»¾nMFßDZ:Ú#p¯¿Â¯0þu‡¬øR+AÅwã#„ Ç1°]í0pýÔ5KEÙÍ¢v¹žúË›§ÓVî¶rRÅ(åþu¿{ú ø ø‹wø¨Ú1½ÃŒÿ»áÛì·˜f¨ÁÆA—›ºlŸýnúé;|~Ó€íÔcN0G™ ‘ÇXn7ïÀ¦>p¼ l:òü%i¥ôºóúH|ô¢ €c ð„ÞÐü÷ÿ€÷¯À‹·xÌßå÷µ‚ÓŽ«Ç» ôƒâÈö7‹–.É2SmêZ§­fPg·SÝ*5bØ#/ÁÞ~nx€î³â–8-¼»M¢äAÛÑò5ä-ø ÄÛDÀr²Ä‚¢e'Wï¨/D®©’ ‘ƒXöÞ%듨•Âd‘¡-ÎýûKᤓ“—-{º¾ð¸ª}SÊÆ²”4KÀCz&Âáˆ1–Æñmø»Qáé%bö±‘1œ™6Ì.2›un‚“ÙD­!SªQ&[ÇoZ„€jY 4kÊ5cÎ2Ô&™‚¦2›K‘ÄX¾•p2#™`r•,Z®½‰1<e$"íÔùéè ’æEY�ÏU©‰™(HÕÔHd"zB™Ô ®w§¤S<5<=”PÃVjfµšU3-&“š‘…Q”T ³`EòE“Hf"”DRÖ( ¬±L!°î FBæ ©²ÚÑ$Ò¡AÁYN¦@™!ÐLJdÐáždJP b)¥UEHæwšVÁ𤠬#ViŽ’¢Ô\]Ö™G~—Rè:œæ6F823VÖ[…TŠUEMDb…Ë«Y|0ÜIº¬kOªiAfŒ”ÑŃ£'2 æ‘`Qؘ%søú{ —îZ¥\3eì2Œ@ˆ!4ÃBÖ”%É uÑRdʱ¡:ÓF¸‡iŸÐNàïD_ä4›"ÃïÉßõi­ÞÜWß—ÇZz3ÂÛ›|ÚQb<K+AWŒ÷£ýÖ/Ǹ¤kèׄƨ1ª³°€&TNý`7°¡¼¤¨“Â4÷áñ+áÏ‹ÿf äÀåi?—ù7Z€«@½7…E½*íùÁžwó‘ ,¨ Ñß`þÑÙǶßnŸNöî.ŽØàç v|ý¬Ž™#ÅÙó:ó<¤3€Ë©¶VDû·<¡ãæö;较ÝGÐgŠ›u|Ùñ[Á:#þ>pÇ‹ )ÐéˆËËg£¼¬”Éç µwåÀŠÝIâþê°Ôã¿öÿý[Ô/�àòù3àÿoÉzÿ‰†µà3Ã_¯æËïþ¼=iÿ Ÿ#ðéË—QNMpµÉ*Šcì–“ŸŸ•þiO=õ‚Öaï`7gÈÍQp iÕAiiÝõH@Ø7‚ÑqÞÿ ÿ¾à­B¾€®«¬âñ ¿Wü¨ Û 6å@[€ŠyR½â6̤JKÌÎ&Ul*¦šnž _"^x{ÁrQZºtÜ\€ï”3ÊÓ‘ã ýo?¼÷—×p`& øÝÐC�ÃŽº^ÿ’e‹ú¤Rj/2&Œ©ÛÔwžsŠfÝ/ÀÒ2üì? Û5­7¦“ê܇ÄÄ²1¿n\C4cˆG¶AI&#z\åLÿ;Fù]Ú9vê¥,…C&“ÚS7&K­(à4°c˜zI7S*I âÐTLJìݺFäJI­J)Ê¢ZŠ (™£NÍf}°B¤Ckº‰®¦ÝE#\e-C®ç7-R(R V ‚T~Gè@!EáaBWŒPõ"ôÔðAɤQiŠª°ªS±R”&EEDVôBóÿ$ìm~$ËŽìÎsÌìÞ÷Ü="#ÓYU$»’"YM£†�7ƒ�‘ Z´³$´›ý�óGi#hKô‚³k‰†C›jQ‚ ©£NªÅŽüˆwï^3›ÅõìÞ©€r‘Œ{ŸÙ9çw ôAÊËA¯�†Ø‹+ý1�‡â$¸¬xbHâAFf&�šPuPTÉá ?�H ‘‘1(IÈáõg‚9|¦:j'@P‡qUÆ;Šˆ¸H"¢Æaï] £?oÌ2(â"—°uÐÝ‘=‘‘�IUQSˆÀð„Jˆ]~2 1˜P�‘ ÑÝ-ó친ÉÐ*ÞKÄ@¤ë(¢“8"ÓƒI¬y°Ð ê•Ø^\Ê@û‰ ÌiAsŽ™mfŽ7:‰¤27£ŸŒá‘YÓn¼Y&`b¢rÿd_výŒUŠ<U[ªžÀµÐ?·Ü¬Y—¼bVsñ5StûÐî×Ït"ÙŠ%B“l)3h ¼÷þØ&O¥V^ zŸ{þ8ãÇÈí.ò~Y¾ýEªÈÿ }‹ \Ík‰X›Ô†ÝÁ6Èù£+íêÕõú“©]Ï]p>ù؃�Äoÿ—ü!d›Ú“ʼnGs9„!e}íÃíä‡+â·Ä¿z„ÞãÙ§À§˜ŸA¶´sE¸†O�� �IDAT„â °L¸*˜><àa/‚«Àn{¿;ãº\g™«ÌSVÌ‹œníêÄvs8þ3È ^¼øÓ{,ß`}ƒ7¸L­Ó·÷¾Ðñ÷GhÇæx[ðŠõXß}õÔo׉½ìH�ƒû?½ž¿Bâ¶u8ï^bóúµ€œ€r?­0+7ÞÂ�òó„8Þö¯þ3è ¼4(ðì‚úFú ž|I„¡&F›äö¬+ž5+¶«˜3pŠ,ĶyM5FIŒ¬Qµ¬óq÷þ] gi\sãÝëú—¿±ØÃ«Ò÷.EünŽ~ñšŸA Ü`&¥m¯Zbnšÿ‡î²–+L›%Q³4:µ,²EÎd_g_Nï—¶"ºn¦i©S°„˜›öRS,+êDCç&”D$,3¥†ƒ¤³·é±p£×¿Ôé¯&½?Çg‹um’Óš²JN³šK5+ÀÔSÕi*1 ?™âÑÆd¢„Á;&gv^K‘ñ”O˜²™6†%Âê‰ðTcI¤0E6ÊLHÃ+D‰ ösé ˜„19 t§f0ƒâq±…Šs" Ž vÐV³""ìAì0 ½0Ê´P9º–332’%ÒጮÑu¬ï%;£Á9¨ÂŽÁ W0)ÊËR†2©“"TùhëKã‹!…4T‚ÃÅà\C8¦+R(±Q 8™¢UÕC‰Ê-"àÌd2^\¨’”>P”™™žþ1(¢f#3(X�Ä¡‘ácÓ.v±^¥»÷îmí+ýäé],eP ºØèÿI±‰Ù;²AW·š¨¢•]äÒH(B•6¯ItAÁ_KFz[33³eʺ:þ³—C®% ]³oh¾hÀî{6]ÖzBFR SO©yºJ«½×8ÒZ¤ÕÞÿE·ú~·í‚ãìï Y«›�² y¾&qZÝï2‰;’p—žÚ1s&di¹®m¯/t·w›úÆi»œÝlº‚ÔÚó¼æñþ”8^µ`5Ôúù&®ç~¥«È?`ù/E¾¹ÕK”lÉoÎyÅ<zÚc^V»ï;8á‰P Aìðbÿªc¿ÅØî`R L±]ñ#Ç“àQ°(Ê„õ ë ǽÇݳ⦿6Cåí2ÿ0Ä‹ÕéG«ýÀ‚f À+|ò\-˜ŽjjøÀÿ¸§ùŸ3ºñ_|ÕðåûÃðÙºÁV¿è¸±ßÖÏ?韯úã3þNóuâv9ð€­£‚Ãú¤1¿„½AüI4¢Ëë©ÂηYဆÍÕ+mûXŠ¿¼«»ûÛטÐOৈ¯/‚R 3´Â¬HƒëaWïÞ•µ6ŠÒÖ:UNî›ÅÏ¥©4BÆó\Šd-Ê]¸"±Ýh]žÍqdÜi»·ºÏçûlµ]¯ñè&° :ŠÜZìmÞç®rZsÚ–Ò¬ÜÐT:ÐPX¦À«Ž2awž¼ÝŸôþ\?ßnÛnâ–Q] 8SQfÖVç¨5ŠyÊ9£D¬ f¤§¸µ¨ËQe[…õ!æO S †t/±Í¥–2o'1Õ VÁ$4éãPZ‘géÇôžÙ]eªA‡°M‘’Þ=šgIhdbjUOÇÉ[B‚Àp 1Í27ÄŒH8²!ÙÔS;” tÀ)J s2tAS,è­wij‘%Eb(™®Ô",—”‡ˆkIbL¦E„£t‚ÐìHx1¼“šžéÃ&éiž1ŠÊ%þ&б‡¹ìŸ„˜Œ170e´Á]W"%#Òéã©?$Œ  ’Š!¸¸U€Ñõ&"j*¦�˜Of*©j"\¢ÈÄðœfú@em%1š.·’ >¬VCñ†j›¡•™@C$/-Œüè•%˜îÙ[o ­»ƒi…’½8 kÐHÕ uާ…Jj0€â%Œ¡B…Ó �)ž„‡"E;²Sº¤7XéͲ õ ñTÃÙƒ!ŸKì›è:@}kå¶áXzYÚ¬ÖÀIrª57ñhËqå‹=C–Èiw®[ÌnStAS#!±O…¥`‰û�%£ö¨§¾{ +jî±YÀ>ùÓãéôZ6“OS­4>”Yj^— ºä)—žº(Ò°ª`ÞVíÛ©-Þ¹L•WWŽCˆCûâ‡í¦—rmòv:ù¿?N8:at Ÿ0cûâÖþù¡ÎÀ„4kÂ*v‰mà:nÓg…vdÁö~±ÁÍŒçŠMÀÚ«Â}zí ØIæ÷%îÝá@7¬Ø °¢,/±¾¹”ª}|ùò[ï†üøXϸ¯@Ån®Ÿ½¸ù¹Mï:®8?„wŠRäÎq/ókýä=òø¸¹Á\ ŸÂßc¹B •ÄœžÑ‰%QÕ÷¶ÙG¯>­±AÛ¦D&¼¡ùñ)ÄnËt¨32 „Ýàz?B‹Æ3CE±˜¶œ4jOé Z=œdKÅ´šN›Í|þnoG½Þ¤vj%ª-vއ%oSÐWÕ?ÏÅÀklUv›iS¤¨É¨q_ÌhBƒ­™DªH£“èjÎç«Úë*¿ÜÌ3'ónY”Ê)ʦh8)Õ¸º"=\%”ZÄ3¨i¾¨y¹R½¦n Ï$Dñè&Z?`~ÆÅ,vf»Âª¥”É`*ÐŒÀ=Ø/{’8I³MÜ«KƒÔL±e/áš©ºæÚ¶c"%:Ü; £…¦f¦¶”¾ÂÑk6íHšyXƒôDwÕ _á lÈ ¢2HKSŠ"u?¦ƒ€:AL™–¡š5i«ÆÄ0ë©A‘ ­ˆU±*ªšT ‘d’)–"�LÒ$í©ÍfšH*H2UUKQñƒÌLÈ¥oG-©ÅÐòãœGư­ £:SèBP¤a¢bFŠ$Ò„\v\—ÕW^j"Ápú°ÄCëOÀjçb²b ˜#l`Gäh›£‰TÕV˜CÜn9>qPFˆË_ŽÞÑÖÆîtj*Çm£=5á.„8B‘IM%ày‘!X)š‘é>¾F¥J$]ØTà!nˆY3Ó–¤Pš†…YÂ7±T+p¤’1u›Ð»´ìå¸;éU’2O1-Ž%T­Ÿe’ì-ãIúiš®f“jt²À$fCÑTa¢C¤´¼…¨P¾ÎŽ’·.Ÿ­}:·9€Æ®‚ qŽbþ°ùS^}w.".¶šôD„:»£¡µ¾·&D`y(yWОUbŽ÷Ÿ¬óØ~óJ°?ÞÔö¶y7ó=pVüG_ðÿžÓ Cžq­˜åU‘½ÕÂïÜ÷”×]nÍàÄÔnëjõ¸ß°ôÓÝÖï×Ï^÷v»i‡OW æ†Ú€ãž›}ëõT××,¿ŽŠt8pZ‚†« ëýÞàí8ó¿�nðõ·÷¾]?ýæRöy…×òå_nÊ<›LµžŠT´Zn*¯F®OŸbS§aÊo /°3 £¿EÿþëŠç[Ü(  ë+Qê-µ¨V>«¥ÁæâvÛëᘯpràÓñÕêûYJ™î¢ÞK¾¦ƒH}É[ä5ô*9±J@AÉ•k$Š»{WmdªÀR4|jt²ˆ´šúÕD YóÜ®Î×€¥¼ý‰à…¯¥CÔ‚Ek©b[ef®™XÒ"&ê!é̾“6¢¶‹MÇiz,zWy³“Z}1.“ÎUf1•*.Ž”ÌáNgïÚ»u¸dÈÔºŠW‰ÈXòû쑽ÀýTüée~oí¹¡Rw¢³š°5’ȱ@ò>J-»ÆÈJ_ž]»ž“:s2©’*`óðvöSöÖM6’‚è$Ô¨aŒaÿ\‘‘Þz†#‘0°DPR$¢÷ÌZ"ÎÈEü$+‹‰ˆ™ˆ¤!{„¢GúbÒ%*]“íÒfc› …>kИ¢dQ™´-F1jŠ‚ôT÷€wQ˜(a„¡P¡„�Â’‘Á,¢PUÕLÄ.ŠsfDdD$H ÿiÂ}Ü­™1nÜäX%i#›O„Ô„hB"#ó3¤\n¡L$Gî0}¨ˆñ*I¤1äê‘ÍüHä?™H’ƒ2ªHFR(c¢‘F¤§Hê¸f”ÂfDvtGïÙºy–”ĸ Ä‡.±&`ÉÌ`tŠk"Ó„ÂÐuf‡¯*½Gd‹Ðˆæz•DXUꤤÂØ5EürMR=‘\šÌÕ0邺€ÞK[ƒ÷]nŸX:ø^« `JÓ±3·+#¸þÛº¢—³é7š Ôîzʬ E+¥‡Õ€@]1¡Ÿoü|Ã^— ñE Ñ»ˆâ ØtÒv¯ï·è»ùX?ÜhŸ|å‚ã>1s‡Y¬ü*—òZ}ì*=ç§ùütµæg·¶î}¿®ízåf…þš@qlOøÃ‚çïð.Ð øóØlP|OÝÇ\µ¯²îÈ;ѲÈÝ£òQóE–çq­Rõói=¿ØqºkZÔï¦õþêéµ)b½ÍsYçºZ½Oìð°ñ[_ù�7ôŽ:Af�X:Þ;NÀúÇ‚ç|ù_Û·ñ”°nþ©ì“À tüæy»«ý“¹æ™ù$Eâl  ¶)å©Þ;°cù)´`Ú@ ô–Ûå¿®þn¡ì @k8¾‡¾8l¯î²¬Lˆ®œ[θ¢9¶�g,ïö“ï‹TØ AJñiä×n=îÏÅk['ÛNY²– Š’žÁt¬'K¤i³6ЇwˆJ…KËÚÁO$l¦9Cû¾sƒr-¼v{‹Â,]¤«æ&`mõý,ÚTÛpF8Žî© úÄù­Nû+Ù—¸±®š®l¢'›´nR´0DÒ9žñ)²vk¡á¢›NuLÙ6¡ ¯×$ÖžâkF+ÆëIž—g;Ë­M“Ö ô‚ŸÈìg¶Œsz™qD¾S׌£„8ÔO‰Ê=õ% ]NîÑZÅDV«Ê„&GÄ !£O¬œ"“½u­ Ä#UœðÔH¬ÑOsˆSNÚ¦‚4”Á1*‰ÌÔ¬+r!W±…¼È¹Y4¥'+11'ÁDU†K'Õɬªé�gÓOA0C™$’b’#‚BI“Da Ň›)©J1Q». ¨k„»»_:6ÇFÞ‘épOxf|d¥*A^à:W]ø(I ‡ #5§£‰:‘‘ðàXómÔýˆˆŒ ¹Ñÿ€‹Ÿv¼æ°3DdvÀ‰Ph’c'7 !C`Ÿ­ÌüǰØÑ#<ýrç)&d¢#„‘°“žlÁÍ€ÊÌÆJWfGªe ˆ#œ’l!£QÚ’)) %¥ŠÂl S32«³G¯lëD”J ÅhÀ+'Îí!¥7?¸Üd=MÖ„]¡‹QËÆ¨OxºU?¸ýŸžŒŸÌ 9odÝ&k,в’+˽"á8C(ÛƒÉÿžW^?ôxJ–ß§~ǧM¯ïlcîížý÷oqÞï–ŠÝz,ëÓ¿ÇÛ;¼üžõ zøyã__÷·5Ýü\í–éLÁ³]ö(7…¨¹©bP>LzKx¾>àt�^â·oð¯¿À³”õV¬$ëêu@Cµ]‰sÒõÿ­ømâ•m'×-¥WEUmó•*'_gB<£áp|~·\¯TÖµµãzÀ‚rÂæ æ¡�0­ø»Ž¯_oðÓ—x^^M¶ÿ¤~[ÃO½`z‰úX¿�o`a÷zþžjm“ld‰ð¾¬üúgklíà1t@^ ny%ØO¥ãî“—÷:¼þ¯?Ã÷¯€þ~Âôˆ«Í½ ¥©Åtï˜ñ)Á„V”¼Íeƒ-Sj5h[õví‹W}hÙâΚ«Ä² ±XÕ;âÅÀd‡¬‘]°„fJttˆ¹c…ÎTJV²b…×ÈܸÔb“$%“  Õr<áÔ¢©Ï[ݤU>ŒçéX?D[« ½ù|â¶f-išI´J©“éF ,<«xHOËhSTxO×lÒXÖRÕ¡Z0/™-ò‰IQÙya¼1ÛVЍ�x÷d8²7iž)* !@—$¡ªÛ,ìe‚hjŠvšd¦¯¹˜ØS¨1¶-d/Þ=JG;÷†Ñ[¤t¢³fvJéA'3s†NðUñ ¡ÈSbXjÆ›¨Udœk‘‘ŒÌÔ�¶ê…1KN •, s±¤‰h1SU‡å'9®D"d¿JE šI¦ŒÝPœÕ ’` éŽìAˆJІôHðÞ£ÒG‰çGA2$crl¥ˆ!z2  £T"y©ÎáîáŒ0 Õ‚*ƒ¨¤)™Œ¼Ô}"ÇÅÀ÷>ÊÖ€œ.—[$3îIƒ™áC.“ <{¤ãRû@Iƒ`¬³Â#Æ÷ÍÐQˆ†€ÌDˆrñØ-“øx©ªÀU¨‹ƒ�;€dU 刎HtéÍ…T K&ãì™Y5CJ*C´%T¨š&†<P0Ë}NÈ,g6É�¿/(ªUŠÁ•ü,òøšŠß �þ‹†9;!’’M²Ç%xB;B ˜o9¹Á7è!ŽrnͰYÅ R\ç3õ”Ûíé÷e½×û'ýõoNûûþöVÞ–Ý›Mýt;êŠÏ§ÏÛ|©à—NÕjÐ j9H»ÃMF_­¯›Ò&?ЀÍqÞCÿwÄ_ã/¾ÀæG˜nPëAôî+¼¥4‰¹Îa/–Žb÷&/Tží¢2ä1ið)êÔaY4nãêp&ÞÛ}›)æÍûýñ²‚/ ¶¢>@> oa†ÞíÂÍ{þûO÷µï׋>ý?af$~+øä V �åþ«aî}=þN¶²¼ÅiZOËi-þðtjë|¿€ÓŸ¡ß 'hî‰=öu³[Øü=ð÷À*NÀ÷ Þñpzíö ü¼]õÈýV^^1Ú¸ªšâº`²˜!¹B=ã,ŸU*öRžmÛ¶J,iëê±.ÒsM±Â¡P¸2[IŸiÙttF#œ I…\ûô¢^Ó+°†¶.€äB†¡œÀ°^p5?Öþˆø ¼A©š"ý)úC_Zo2Ýp€;VZÔQA«7¦&R 5˜EÜÁ„¸O¾ª¹ö5ºr±iI«•}¬k-Ø4>lMªrR™ÄDêEyÍžéáÙ##º3C S R‘W‘‚B ·’b¡%&rÈŽ¤éi!Œ‘ ή~t•Ìnææ:ÈÏ`iª¬f< &²Í”Aì¶8 ŽOÒ P¤FXdjF£-Ç3—-h …"$½lô‹åE%d°p¦¡P£PÒ5„Ù.D ½ ’HIÐ1r…jŽGøËÛéP$ÈP1PÀcÔ7w¤‹„H’J(†àëù1×6êÜHr„ î58bôì¸Gg¸D%Æ–IdœºŠKßf`¬’Æiþ±<)™š9œcÈÈUÓ½ÿEDÆ ‘¸Ù�t§•Ɖ@^çÒESCjWÏч.ÉQ'Œ¬…>¬¯pfè®æ–Ý¥‘cšªšLÍ®*!ê=á%s Xf/2œe}64Jk°´ð¤;ÖÌÊ–vŽžc’òºÀ/‹šy¥q%¡)Äܹ öûz½Å|P=HÂùÃ3¶™¥®<Lý0Æ(wô ´hŸeªâ™ÌîA^‰OKÔœ›]ÝËÆÒOÏzl~mõׇ•x¸ÆuÿUyú H—‡ëÞûíõK,ǵœ¶¦ÚjYËüKæ.OQžKí÷Fà¶…V”óÏñX+`†L ÜKGH‰h-vÆI²®»À+[_Gýâ\×Ù´7`—çi×¾¶‡,Câõ‰˜ÖÛ²ò  § ì6󊈈··½žâý¨:½¼­ïKEÅõ·Ý Ï_.x�З˜ v†¥âŒÃcÜmúñm¯o°¢¿ÿþÓ¯ã«[ùÙ¡°Qà3¬‚rëQ»W@o÷Çßul7ÈŠsb}Â?œqê{Ȧ÷ʺެØÕ STÛW­U‹ öÑÇîÕãÉ“gÙ?·i'º‰&ö¡-k÷ŽŸ´ uCCID§µ’.bà‡âªá©#y‘Ý$ z†¯À ²0ÄrSÊ&­Z•T‹´`bêQ2ó„ºÊù]ÆšÔ–«ëqÂúôëL,3²Âñо+ô„‚¦œªÔ­hh„wd X„©èažhnì3ƒ‹ÖYJ¦Eò¤±ˆS‚Ù=1Súxô‹«Ý“=ÓÓ£g¬á'zcvš ,‰gÉM¢BH,„®M¨¨bÂH ˆ0ÕÈKPŒáš â„<#ÕSÀ’UcuˆNtvI­Í,Pš–9}CQͰl¢ÉêaBi’©4d„k-ER!5¬äNQ!æµ &•¢Aª|ì1 HFdhF2ŒZ$‹¤‹Ð£ýgÏ£Ò`üÔU¨¤ŠHŽm‘#Ê›)‘â>Zž‘ÁôK#CÊ`ó1%3F¦pxMA‹¼4fiffÀÌHv 'ix°ƒC•¤fHø€q ,„’ÉŒ!XŒ+h¬Ž "L %\}¨ À0ŒŽàaÂ=‰ˆÈ„@q)òÌÙ=½#Ð/4qWq1D]ªÈ®4²S3²I8ñ‹Ï j†XRƒ¬¡“  •,SêEÁ:Í¥§ÁÂÉ.’]ªGh&ÖÈÎŽ9H—¥«g»KÞ#^[!ûð†1³3D:Ÿ‰®ÏBt–ï@>£0#W©«5içw-÷Ñ3w’¯D_3P «¡ û 0fº²ÎQ<Ë}êR>ƒÍÏeҔ΢;òú†j¸ \Ùï¦7{‰„œ^œ6Ûöøüprìïα:±©k¨¥5‰ ªÉõIÞ½ÖçàŠ¾E)˜ -qýgøð£O*�åëÙÐò/mþç«Î½D™zû„œ–|6—£´cÜo£[?Äë쟿‹‡›÷Í?¿÷Ä„04dz36=¢ýË Žü¡àÏ+ 0%Ÿî×(§Ç»ùþ~÷æõ/¾À»,å°¶;¼Ç:é·13ÚE ø9€7°OQ;¬S»Ï÷˜nʾ´¿n÷_½Ç—8|ý¿�tE>ƒN8®ÌÃêwÄÚMÖUZ´Ã+^&"&|0üÁ±¾½}ò²h}w]´¢¢”õr° loÅÒ$lü§œzHkÓ곺ÑR‹¨å’ê(nS‡4'ºôÅãè"\M@T&”B“ý`¡±8,À]ŠÅªôŽGê4q#eËZc#1º4Y4mA.¥gýÃwZh~Z<MÌ6¦ü Ä6O†Î/$Dâ&0¡2§ 볬¢ŒÐAM#ReV$ AœAdIR9ÆàÀ�þ÷ˆ9û Ix17+F çM’ÈÌžÙ#ZôF? 12Pƒuú:¢hI`µ(¡”,Ãê¢Ëè€À€“áÚ#B¢ ‡”"U{"¡‰æJ@ĨÏÈPaæ$éBSéY –Ô&‘fKö qáØM«†V”"UÍPÄ-¡ ŠR%ÁQÍ6ÐÜæ в ª° d†ÚG'i^6KŠæÆò‡Èd@"¥Ç°%.‚oFŽí9™AŒ¹Ÿ0"BÌÄ01?j H0Å.ÿ~#—R¢ñMÃI(!ˆA¥CÆ0©‚B1 Lc}”ƒû¤B0Ž'}¦2/';“—dCx¤'0Ì@æ(ÄNû±žÙÿ¬MP Ihæ sš$˜ˆ&Œ‹¼,ÈHŒšó`´Á ¡m`;êF`„Bh©™ hvj—)ÙC¹¹²»kyŒ<£=X{ŒZéYÁ²n°»GÊw€Ê°\¦Ô0¬&ºb¦âyçÜ.Ñ"Öà–ý¸�]òý™§.{Q䄨pEÜöœë¦¬R`,¬VÝJ‰¸Î3Y7¨¦3æ›þƒ_-þ;Ñ×–([}]o!ñ¹¿Û³V·÷ÏrKî[ ô¦‡Zîz^1g$Ó×üoëmü‡ÿØUP Ýñ™âï;Þ®˜±WE÷7yÝòn•{®¿ÞÎqÐ…`ÜþN玶`=½âqϧ¾{oþÏ~Ú½–Šœ°5PõÓ×È7(?Ãûïbxr eŸ›ýúY}˜×>ãŧX7ÀŒwôûiÚ/6}3#ï~Z|=½Á Lï¡<°mÈ÷¯§o0á/cWõ5€o ÀôåŸ#7Ø�hè+äéþXñaWšµy¿l[À£·ëæðÿ<~>ÝýÍvÅ,ëŸhà¡>Bÿ y<ìŸÝåî8i°›AÔ©ÌVæ2(2½Ë¼`eibÒБ‹8éf%KaQ²RY«ª"µ „,aPli[äYQÁçz=cR¯–L§ŠÔ(–�«œJž“ô¶•MÕjE8]YãÚ“׋þß+§Ä¦ËœÃØ&lRN!TOs÷ô´Z’ˆa‰îÂJÙˆEi’ŠñhsÄ”´Pæfòº!·ô¢acC¤À3{Æ1_™šé-±ÉÔñPLIX*Š@ÅD0û‚Ñ)ÉR©Ã¨þPxa¿B7„#„NÓ®l`k£us†» ENÐ-h‰ ô”ÌRrô ’P@˜$ÊX·)…Z\kQ­‚(�•H¥aä˜%}lØ)¢y±ê›ÀªÒFh€ÂýšIƒ(¬@•Lùa´&½ÎU«Ã:¨|CÚõ110GÿϘ <Ò‘17$%.¥>ä uèѺ·F¤(ÄTDAF üEc’|`\^@™DfŽ'þqÉÉ…ö‘!iph'‹1Å ‘ޱ ëÁD^êçDUÌ“2n½¹ÈïLÐ"4`)I‚¦-bw2C]@IEÔL¤LÔ-ëNÊLZŽë3˜žŒ!è,-(’ÂC+LµD*Ž‘éÙ®Ÿ(/�� �IDATÏ‘ßØxhö®çܼÏkH‡ýa¡º8VÕÛ)U±1Y;bÎexž[QAGdÜv=H×_f—¥}Ú–Y8‹¥⫞[—ÃL¸þª¦LÜ25e]S÷áØ:äík^ó­ÔC5ÞçÍëòË_Ñ7l&(N(×>­ø^;ýÍaøGx€RaŽ&hç¿Ç â9°ýÔ½¢Êúüéî?¢ÚA+¦mX§Ã•à10¿…¾Ýë÷šXŸÊþÁðÂ#/é¨gè ð%´ .Ø<:nÏRZ­gÖ~ƒ¼*õ|‹<LD¯øSíЇ¯uûmÌŒ¾ÿEÃþ ¶@ý¸A¨�ïQ×ñчú?Ç%41x’lˆèè+úж@ί»ãqsû”‡wg€*ØÁü%T„å¦Þýëç÷í|ÿ Ã;”¯Ö†Óý÷? Ë[lÇóýóت'OM˜ôy,”M*Zæj\QVp )®ˆðb.x/4È®kåD5SK3S1ªº„€J@Z Xk´,Ö1GŸ"¹PRʨï’P¸YK¼ Š‚SŠæœQX‹u,“,]vΡ°HVbx0)F¨"S� cwb]çÑo§¸ ÒÑsö8õœƒ’EY'Ô+áÎÚ†½()‰ð$ÑÉèÙ!‰Œh—ßh GA+D«0-U ‰@'ZÀ%AM(Áè À!Ò§K¬™Hu‘–2žßpp•¥Ã{ö&b¨–ú±}<­Ól˜‘ÔP*3Õ²¨¥¢@¦`ŠIŠëÈ‹R™B!b)xG\4VBG›Œâ’vAðHx†@j+Pƒ�éˆ5[xŒÅÿ¥¯ó²ºAÈGy<üKøX4!†-Õ“ž@æ@ œC‡&U¬ÖBaxt%Ì´B­U¬B$"Ó[6aWôž¸„è.h'¹xŠ>.¥ÆŠJøQü§èÄEŸ «âbŒò€'û® ÍäðÉR IeWÙ!U! g” GÓѸl’žé}ÄX2#!D.¸ÄYlV«¡’‘á5¢wx‡tè Q— ˆGd6øÊl–Òã — ½J\ç¶Üp¢L¡ïœ÷n¦ 'êÑ}]¼<¶é¹…”¹(IØ$m¥-uô‰©²&š×CW$^MÜ3>í¾Ë>•BuÓ‘œg%¨þ*m¨$…]-ˆRé%ýVª9~îÁâÕ&öëŽÏ,îÁnKÇRÙkn2§sã¹Õ‡¶»Ïÿ Ó€ý-Ö÷°ÿe+ÔP ^žÁÿr‹ïm±»NX>ûg\Ýš¬Ã¶È'˜a2üçŽÍí¡l^ÖŒ ±^Ö¸}j‡«ÄÆQÎð#ð€þȧ°¨Gði‡´»Êµ<W±–<dCéødÅTËt÷S¿ånøòmÞ—Š[Á!npz>ì¶ðGLŸbyõ›º¾ž}zÀÑ«£�KÁ:c釿Àñ£3¢½Z¹åS×Ù%ž^Í~½v�·è‡¯žðÕ_nñõX|-¯_}ÀË_Nò›gq{ŸˆKøŠ¥”İ‹;r¨ª“ zÖ º£A5USèM(¨Ôb&"®2ZRid"Œ:Ež`[ûíûd)…Zêi˜’;áŽt‰›€†(TÄU¹©2È4e´ŒÕ’jHPÀ CW�Ý#Â"-4´³HžáÍÙ#š»{n€‰TêFuC¹*œ&­B’1@hg.€ [Â3JûŠt‰E4ÀˆIA‘Þå|`zöÙµ&+@fÃøž( †ÓFgN. È4ÊfSPhÎæIbAhFAÊÅMŠ0d$ áIK´Ž½R;……Z’%†®:–)Òĸòc“fÅ7D'òc8  ‚Œ„3�HJJ\$á.ÊðJz¸wŽ 'ÊhéÉ_Å+$zfï™ÙƒÒÈ´ÌBI¸NqSÕÁ;5£Šh�ÁìÌPSŠ” b‚Ìn!’X3­ÅG蓎›aèË2H2h|Dâ_²£™ôÒ0ǿ鑠%9 d.yéÚaÒ™@S(‰2à"©J½T. #Å©DcvɸTYO´`÷ÌHm¨ÕZ†CIÀá=W‹f=Ñ3úšÞÒzF&[�+ÌÙ¡ÁTñiŒš‰ˆY¤J¹jz%Pƒ«›D:[Zs…MðÁýwñx%¨çòÉ–³™Y‰Œ¢F6AÒSTåÉì^ò>:¤íÓ¿‹õ*[©a®½gËh YQºgÛSªW!Øž,k¬kö¦çƒ%ðq5aÈ"?@îcªšÏ™;˧w¹¬íMW”û(èrˆïÁ·À¿ÄÓ[„£6Ø9È?Ÿ"þˆé›Oä›­¿,¾W|å‚‚ŸA^@ äú øß‰?ÕÃé'wÏfºžùž×¿}°Ÿ¦ ű}�Ž8¿‡ ÷ Ið %î%@)ŠÖí^ç3®ÿˆë2±N÷WßÊÌøúo×OÐVð,X·xœ°Ö-¦kÔ$ðöccèX+ýä3¬[” �Øn‡£†°E�8a9ï ßÍÏ®b-VãšÍ³¬ýÖÖÃS¾4|}Løzˆ/;þÆÞç7òìºò<çÞ÷Þ7"ÈLfQU%É*eÍ F#  Ðf@4Æ n/Œ\Žá¿cþªÞ ^ô²ÑÈEìÔB3Àt«Q¹m—ä¨Êb’ßï{÷žY¼ g)ÜdH’Á÷ãžs>§ðíkÜ/½¾¹¼»é§=þÎV ýÊ£¯?¦ß2 ÔYC%«¹¡P›7,±Si9Fö°4ã,N)pC§OçI¦ÁÒUaž è)¶[OaU¨0ˆfReþP*ìNTˆ"ždz 4ùÁ @%šF/† T£Óé ÷šËGÏ!{é'Cšc r7á1ÇS H¢b)Ú´ÊÚÜjÉ•žIaÌT”ù…܈%d„G¯ØÈ'}!¥›uú³á‰–òWY÷áÌ-·Ì^å‹œÎ‘Ü ‘WËc#R°”ÂꀻɢábÇs²ÒFØršfs3Ÿ–¤Ë\î.S¡ d0ªg0E3s:ì:»J£yuΠ€f·BLKL‰LÀ™–p Ï± L¦2ƽGïW@Æ<§Ë®é2»Ö�É`€ R&§ÝÈb®Ë‰IáºËÒœ%çYÿzž'Ì�‘>ï?…¥HR©b ©¤ Š&Ãÿ‰˜—»Æ8#غŽ4šl*Î™ŠŒŒ˜ A×'ušBWŒ4ëS4Š Ó 3djïRÆ4I!¯Ï›…¹²0_�€ÐÈ €šß+Bch ÏŒ‘[Œ'ô‘!ËéëŠùg‚‚’[ÑÔê R¹xiô·*³’ôáèŰ[ÄbÍ=Ši«Ñ?ÍþÍv¹÷>Vro•VM€iiºX¹�ß@G�žUÉqvà}iaÊXÕ/EÞ¬¾Zˆ¬M½•„Ï›žã„’°7ˆö�¹�åA:7Ù[²"/x:Å÷ÈK{ú‰õ膱 ¾Á(¸�õ[äcU :ö�+ð¥é£­w©jþK j©ŸóÕÛm÷ž@? ïpÓ�<ÜþOÇó'ù´lÝ–õÙò¹}©ûrÁrA%ˆÀöð„£€ü- À/‘ߢvxÏDÉ¿Z–(gŒß#ø øìý¿†§túÆò5ÖÏð0*~SÄ—†Ÿè#>ù¯¾Æ§Àíϰ|ŽÃêƒoGÞ{Ô¼[yÚðþ㊯xÄ/úãÃy_qOí6‡¹âèx<ú¯qûÊgÀ-p‹/7À2po÷÷¸ßvxÞ‡pý?°>d[°Fú^”JBamh¿Z¯±0we8Ò{()bdÚ<غ!EƒÂ°É†a%ô*u�˜Ôšeˆ=«²ÔÕ„$Ýœà †c˜æ¹0RhQÌ�“¨’NÕX‹[£ «_µGÈ X€I¢4†Ô…i3­=…®uãsòRβçê¾/ÅY®ÒCžIšR h¸.• JÑÍL¨Æe£ ìlÖÉßcÙ“K’Bëf£39 ù*=¥Ù WfŠD†Mൠ€ºãûäk©f¤eq8Iz½®|1mž�¬þrlÏIºî°0ÃË.@†¹•ÒJõbW•É3FÄ&I AœµŸ™d’p7ÍiQDæL~dÆØ¢÷è›”ÓD9¯ÌŠIKºÚe ¤2JHA™@¤<Í0 â`×äBŽˆ¡Þg¢ ’r`6Åé: ò«É’œüÓL$1ãnœwc¾”=ð%[-¾¸ŸŒÒôðNr—¹AT`îu]³ZSÓæKf—uRI WþŸMᄈP¤0Ñ4<³êH JD­fª`˜¬äÜÙ ‘¡‘¹õdfnÑ/Êu^S3öïˆ&·tK/rwwŠ¹ÊˆêK±fÕT ÀÌ‘#0hÞÌ­ÉçX î÷8 m�Û°Ê$ë¦uäSØÖóÑý K@GÏw›ÙY Û]¬üÛbÔ˳‘õ¶fŬfBÛF~°ç_åã×c½ÃJ`÷å^^eï¸;™ˆÄF à9Àö~Ý!íÁŸà FU”�; ï¡+€D&°C½} êúéȺ†ˆA»¸ûÓ±»{¤a-¸Œ·¼»µÜµÝÏmoÿÔ¸÷BŸý¡¶òPÆq_ÐÇ[ï÷þuÞ}ÄéòÅûï¿F~…Û_âõ@ö¿®çW‰¶Ÿ°þy9ÿïù5Î_Âö¸Õ¿‚Ñ_þê« |†_|Ào¿Xñ›&êÜ øñ5ü ÜÜa9`¿ÃyAà—û…­hÛ â¿ù¿ |úÕqûËwåõvÙŸ+açè—ÊçSù€‡ö³ãoñÕ+üb‡7ÂýŠC>¼²z¨mWZÔk\ðñ8ðæhëçiXI–4# è’Lu7C}„Ò4"¶Èè>6´1¼DoM°$Wª#ªdeh@öPbŒ- ©¦ Eö¤:+农Ph‹Tæ’驌–b/R³ˆŠ¨è%Y¸·"Sbd1UÞq K(·PGt{ZùQø{sü(»)e×j)m‚‰‚è=+h™r 3É`JD„†I` ƒ@eÌÞ²ŽW¼4�kn³"cOŒH1¨`¦)ÒÒjQ‡!S@ ${ʃ2æÀF#ÝéVìl²Ì½e÷¬¥Ê t#Æœê+Æà)Db*&sYd2ád©¥Àç4©8‹×Vš—J�ºõ! ÏìbržÒçÖ£àDÓ™ÑEf¨Ñ{ÏcS”×ô°(Ê$„$"ä³ÂáŠ0zñÅR9µl:iÅ­—3ç@&£ç&jpÌ~ˆ¤`Sîé!Ž„Ñ¨ÈÑGn="“•Å=͓ӌ7½ÙÀ03î<'MW¯*¯ÛšÓðÚè9BÌÂ,ÌgHzî WUûE’¶yb1Z¥™úÚ0Œ¢,žóÛ4W ï@nCb•'‡ŠÌDäŒ^ iþ(‘È.l‚œîóŽbÅP^ÕSžÍ½›tAž=‡‰¥sjb©ó¬~Éónçê{+i~é"ë™?ˆÝh{Û¸»È^er@R|ÿ»ç샧ž˜ÄÜ: ;¹!øèìÆTþâoǸ¿œ±/°(çvè¨*=·“È8â€ø-Æî~­÷Ž–gs$eúóó¶;÷ž}Û=X£o qÜ}„AØ– 3”  CÙ]‘¨CÁc)Ðëãöêô$ áŽÂ7µßÜôý%ÚÃŽÛ@©÷ûûû²Þz"þŒ(*ÍR¬½´z9– J´~î ?ÛìßUüýgÀ¼ý÷ûñYÛ¿©£EÆÍ¶³Ë€þK¬Ÿ"xØmtoøäúXþâ×X~‰O 3,7xã¸Ù¡½ãS|BÃÍ‚JT<<±b×[IlY½=¬vüÍ�^ß<|÷¿ÁÓ(¸ñØ…×aJàøþòÝîßÕåõ»òúô´÷AÔ€wì:Ú«îucAÇvÙº?óˆùbŸF2à?êË®”żl%¡‚ m¡’=¶Y8S³”“dªCÚ*T³“K¢`øK×ãêÀ’+2Kn Sq¨>¿f‚ä-#F¸$±›o¢ºº=ܪ_Ç(@ Óƒ™9ãG ËL]€U™èÒV¥ˆ’A#N¿Ðó­•nv\š—RÜýŬNpBüÑe¶ È‘ùß3ÿÄUk¥¥Á6ú:A« `w°½ÐÌ‘a=-(qæA²NpX$³sÎS̬+5¸Ð_³D2Èé ZÜá Š“6$e¤¶�b•¾Ì¢4ÁpEU(‘gS©T±âÅ‹—jVÍ}–ä¸ 0Íe–²Y$LT¢’×BOÐi…¬ %EŽ1¶Þ{Ž1ÙÓÌ RŠ™[~!T8æ¡üº!\‰g‚DHnp³âæNŸ}r6Çfî“"•Pg‚fŠuhí1")·ÊÒX a×Q¯µ¤6—ôLÍ>:„^˜ªóYÃ˶…œWÎ5L‡K…^ ¯œªöuˆ6ËQ ó<SyóíÍg^Î bAÈÌAÇE ä ËöBW˜FhXÉtÈ0H“¦J¬°UêÒXr¬­Àn•+T5‡i?” ÚÕ=‘Òp‡²¯Ã·³/{,vVX¶¦â!°2b�=JW|›þß$´<&0 ÆŠ2ù°ø{0ŒGr{è¹=¶þý ¤Wë–}pýUÞ> ;n;؆r÷Àçã®@˃î.~×K íœázXãw}<}ùÔ>&/9ÖwëáÔÛû[�7;¨bŠP TTƒ7„cà­é~cûw›N]ïGœÚÀ¢¾“;^GAÂ6ð´=,½Þœ÷ån,._96<|Äòkð‹‡õë:Ð64»ƒ>©kyøÍŒþáþ«ú÷·w7¶Oú'Ïãiëk¾J<|ü“ãÓ-nl <â_ÁSZ€ÄáþK´Øpv (HÃhˆ >lø<`€wD¢Ôþ[۶ҟ옆_èío–{ä+œ>G=¡ÿ øŒ=ž ÿë}üìÐâf« 鈀ø–vV™·àºá1²o8EƒŠ}ƒ ïs}ÿ ÷æZh‹œnc±ÜY³Üç.cßcûîâßEd_58ºúgÄç}¼‰^ †ûæêÀžê–´.­2ExÀ7Ó°|®Á‚<0;hž5y–^QŒ=ièÓ{€gŠ6±  X½L 4sH y¤eL·ƒ™uË5íB q�<UF ûŠ–q0ÛÞ†5LïÎ\ײf‚F`Kö~qsóo2?ÊY ÐFÔžVè –¬ÛtAU°’P&²[^”1íô3F˜iw]HÉX 8ŠhÉL%Ún”¦"Z8@îèfÕ¬¾�èb“ÖÄPZ˜›?ê<µ³˜ H¡S›‡fîÖÜJ™Kíü!lÞÙƒl¦¿§ŠÛ¨Šô LY.P9-ÿ¡1ä`yɈ$5ç]/¹Ù¾@ˆ€ ¦Àœ•¢n¨¦òRG(E)‚⤥ÎÅW«)‘Én#¢Y)VK-¥È̉ÈHÂ&«[)Í%=¡T*cªWž4!zT0BRL™Ê ó+E,fÅÐ5¶}Ýü#‰È9)#œ(f C‰ž!›ƒ±r-*A9 Ëà F2Ò3•³qÉ#¹š­n/H““t¯Ì¬uD¶6bÚyec"¦F8Q/h—|>+÷È’7%JzkÄ(£c5]²—> Òž¼ý¡á¸Ÿá“Iµ²·#ïe5ü]­'Ç{è›Ïã݇þ[ÅÿØý5^•oŠÇóž—·Ü·¨‡ú®ù)ê{ÔŸ·ºH»ÃúëÜ Æû|Æ~ýœ÷úöàÞ0€]…;Ì!¨<–|0?šP ºôûmäv¾ÅóK¿zuþëýÇÚÅ VÏçX\Q>õý;ó}RK‹põöl6°>÷üö~xHË×GàÝÀÆ/`uË}ÿ1ÿ{ÅÚ€ú‹íûšMànô§í›úø&ŽëZ ù¿¦¿Áñ Dz 9PVÄ ?€ O=q.Ø€±!Ÿßæù>[·mmë÷öXk¿ðt.0ÇOâO?õûïöíÍÝ›{Üž–˨jå÷-[ì˱«¥ƒ#Tc}Žår¯íGý²çÈÑ•küÝG +ä¸i8ý ²£üßÔÍqgÕT-[Ýj+KÝUì™Ûšëó¾]¶þqݺ!ø ü.´%Î]¯7Ä«9YæjäHÀºÀp?ÝøÑ²–þ‘ÚËná=x&V©Ÿ¾rA-ÆFš¦qY ZA1±0É-”––JEú€9é˜.þaø(Û« áél¦Êƒ{f©5—DÁõÈ(2Œiˆ‚žìD߸ukgz—I¬ÝkºÌ¿!ÏÌ”~h¸5¹£‰tø0s²Â¤Ò•C³ª¸Èf¤.§¨ )»¸‚[â©àÆÒ1Rf^³4¹“ä<àÃY‚L®©o‘²ÜÌ_Tª\îòâ(s”.‡#Ý‹Ó_¼õWwêdÕ‰¦LЀƒVœrÒP¨‚ð dʆO°L‘Šž !9×ÞëÅaî7³ægFŽ 7¹áÚâ J–i!Òdb˜q3¸ v­ô!ð¢_äLÒ®œíiO�f²š†Ž(€Ìàô—Šg®—%#g³´f€NW9B9b¢èªMç$K¥rHÁÍI!”Šà A˜O_b*+JLœàH!5†zf— ô¤;YŠJD¤’,‘`ÊZ–“¹)¹™¯]–Î.IÎX‡E¶È5•R°G3Áf¢™£L°y1–ÂÎ#Ýa³öˆ5Ó|yV´üè$·ðž:W¾RlìÊóHnÜgÙ›N `\¸t»g»_G7 ‘@ÑËé£ßŸÚrûd¯k+y_/È;ÐPí~´û]6n�‡ÊHC–­¬OmÿûŸQ¶‡xn²»ñ¡µ"nêC½=–×o±ÜoõøùÈPÿ|§“ë=Uç¬nÍ[ë^¶=ÿf]ÇÝ?¼ó7¾Á¿ÞÚ¿µ‹}`ÿÝèÐGà~u²þ8´s!luô¦3Ø·íC¿üöh×–ž“Öêím×’KÁ6ðåáøf{÷ZZpÞ•^3¥>v>'|b€P¶!žÿèÞ°¿1| løÛ\Ð ô.üßÛï6Ü>¢|{oqßoÛæpJÿæi7ÃRÑðÐò°ÅÍ~´¬µébÔìå¿nü-ˆ­}}ºùÖÒ6 Ûv¬ëC©UØ×Ýa«ˆŽÜÎtìp@,èÄeƒ¯à†:>Úë„VôÔíPIcõÒÜ[ ÂLþªÔÖ¨%ÇHO~Þ§þdh]‰a¬yãp¸‰k·'–‹Š»F²0¢"cä ÜÔFÚ½8ó Ç‚q“9k–ôºXq³&`XV¡À,®-+LšeÓgo<’6m<!Ÿ¥, TUZɵʩÝs,.V`™€È4qP‘Ð"Û*·¬‡Òu;ƒ'ä -6 7+4ÆHgÊjÎÃsRá +YÉét4A3Šœ§sÆ íδˆ;:' †tÈ$T]YC$rŠ»FW|Oý?n^,Íè0±Kå ¬uP‹™œ *Jf@6c�Óe9 MÑœ ™M¦*\i3k5Œ¨‰¢)rŒÁ¸ »„2w›îU8'48éÍ”Ùôò.å’™ÉÔ eŠlº‚çê W"•“° Ñ(X†ÄPL°Ý<«ME®9܉¸–<ä¤sψw˜-jšö!1©ÈkPä„Jƒ9ÍøSÓ¼s]­¯×ß+##"s„’’‘ÅX&ö‚%9»|r˜§ˆ5­ Ôda "ÃÕMgÒ5º%›!æÎ><{‰°. ÔA——«×W–YdR¡‚}B2ˆð–Ø'ßÈ?ä2ÔG RÍqŸô•«žºWöjÿ\cp ]€¹<TV•ÖÔ\(ªÆÖãöÁÇ>þ¯ýðq§~Æz[yù+ÏÿØêPemµV ºT»Anq.QùœíŸ²<ă·£½ùùùâ~Wô!v¿öÝ—Çèð“ì{ÓÝ §cà°¢¬�Ž•ïvëëÂE¯5ú·Àøµ@Aà{;?n7£'`ýåûñCàîAíˆñ0¬Œó}Ñóî”ÀØ€‚÷·€ßýõ¾Z”ûwmœ~ ,O7dÖ¼@iLh,zRˆˆúÃÝþ0«8‘'ÃëD/X|’hL¨ü|÷”||xúPí®q× Q£â;x¢T¤Á-á °¶‚²C<á†WŽGí[µG?ñı|ú7¼Íp `¤Q£\j=vÂôÈÆþ¿üµ}}àÃf?´þƒ ?êÃØK% �ÑgÒŠ ±w•‹¯ÿSœÎ‚]ä}ñ0@²•8gI¶ß.Y÷ÃØ/l­¨uT%‹E³~ƒm‡n‰Kæ£|UÙh22”02)ƒe×–±9,iÖa.ŒÒ·Ü¶+´Ð7Y8Q¬‹Êºª=YYä Ö¥Ö¡$ˆô aÚÅåLÿÊëÁƒ,]«Ã©fú¿Œ÷6½—&©Œ9ÅÒAEh* )’„ÓU"3a€*›Êù\T·‰ƒ£˜›µïÀ¸&0ϵ iÚ,¦}±?«%›¹—Õ\tYÝY•8Gè…Hws«`‰Y°†œZJÒˆy…BšÓ4SÆ#s -¤cT¿^f=Ïôj¾„':”4»RÌ \?®@Ù$sã¥g‡b¤¸òˆ�ª4Hé6¿r²ø„HP¤O™<%eŒì‘‘ättfö®¸&Â221}²ÀÄ~Ì;PÌËÂÈ­UŽddÎnŒ90ºI¤˜ÿ2)›s¶j›‰E¢¬ë¢�� �IDATFæ3öG:}F4ŠÁ39B=çUÆhtØ, —hYàÁL¦€Ü¨$Ï4d™c«€sñâÚ1Br€aµÛRØ8=½´Ù>˜¨V’E×PLÈTvŠW}'ãE\G?i½±±ÈŠ.aØïŸý“æm+Ïí¨è@ :è¥ бÃÑÃ@oõÎø|£Fè¯òG(»w§R{-ž/[ÿ|Ô(Þöìfç³:n¾{�kœË0Dù"üô×úìFÏw¹ÝŽÚž®|ÿÃXËwü/G�üúTÿòžË²+õ\ô´/Ÿœ#¶ï¿Áò[6ß6üº÷/ŽOŸaû}°»–c6¬~dDzÃæÇöýK<}uU§ø%ö7æ»{Ô¦ºÍ¶ÅÛ±RŽ0°âÆzÍ#Б väGèÃÝöø²ã ðÙå´Ÿâùö; C øn¾þ€Û¯ðô¿>>ñu+¥mmëøî˜  ~…øâ¸áÏ·¶[?ïßaûñîù‰ÇÛò¶UÜ|ö5 ÿœ¿~ßñ_"OÇü§¨»¿·¶W‡!Ï[ö[QÐèÀŠñ-Êÿ Ü[ûzW¾É°ç íÙåó=±©Zš×Ä»ç4â ‰O˜£(âÞÖ)ÔyŠ´žå@eø9é+oÒwÀHÏR;L® ³mokó†õ³û–ÖÌÍ !ÒÃQ5<„EÈKZ¨$-ŠkÀ0¢«‡Etëhî¡,Ë.ra¶�O…+j æ²™R¥È¬`Ò‹Á Zƒ/hç¡‹v†ÂḻçJÁ5 hÊ”´å°y℆Qé©´IYÉå˜ãX öÆíÀÅ­Òä`$ž5g>Ú 0/•X¼3ËðCZzÝUž›ug§§—â¾Ò÷Ésý³âa—•„…$È<Íæ®—5ƒ #颥ÀTŒì]}ËÑÇ,e@Êi8‡6VD‰¡)(€œªÅd™².T±L¤E Y `¸i~¯…>˜à$@É„¦®ŒLË—Èó¬™ÎÔ˜²‡hn&Ærº˜‘‰TÌ´‚2Sfîîp÷‰„‰ ×0n`b®ß=3B•É!²LÅDƒ©œžÜ‰ÑKeÑ|ŠÀd,æî^‹ÕB·ÀÕù;BBá„W™'i”&HÖÒ,_à†â–Dr 0±(îàFtŒ¬¹É9èb&®#‚âºq¥œV@‘U* :«%?À>æù¬Ë~(ˆQz0WÿäÌòHëÃO"¢"¹½%ïc­]¹–þ˜½‡ŸÆ—‚3@â°<-‰U5Ê«í¶ÕøÝl»ÆSkÖþ±|<ŸÀò=_£¬?a¸í¶;ñPŽUŸwó‡Ü=ó‡ÆmË> ¹k#Þí¹>÷1Žðk8FùøXp€©¸/-·Cž[¿[ödŸ×š=?;E opÙa½ÅaÁVàDI01&7òæ¸�¶CûË/a�ö(¯°¯ÑÚ¹´g⑯D­ ѹ‹ÊVˆa•ñpÉãeÀ…òùG}J_îð3âuÁáŒö[àÆ~÷ðԎφg`ç(~ÍÝÅ×8ÿõ Ÿa?jC¯8yA8jEþãÆo÷á‹';¾zóð˜ýdçq¯~¿ûºµ�À[þì¾êؽ‹Ã)ïÞ÷öž†ÄO†}§Zà nÐ�𧨕Ÿ"—Šoµ±{<ö´§¾ÅØÝJ]�÷!wÔÉÙ÷ù–m?’øÄÐ U‘‰Ûhˆh…¼_°ß¼u—lt²¤ ¯éêP8¸£ažͺ¹È°ÁÈèÜšz²0†çæì}°l]¢˜¶Û¸nµ×Þ\‹Ð„]˜m1c©u9dÙq1͹ôlµ§³P Í/½–æ‹·âÕJkò÷²2@í½ÉEV³Âk[æhyµ Åž(A¦ÏG:l€¹¸àI@î™f!Oœ;ºpx)K«ûº7H¡uK ¥Ëªyµ^xC+VgÒ{6E @ÝaÂô¬ Lgše±iªA$d‚$bBFŽ-úŠè™‘Ä4™0L6†Yæ,oSo6·0Á"xÈ&ñI˜À©ù>qX'†YÌÀ»]ã/5oS<rV×�™†4£MC¨ˆ"RÓ44MÍAe¤2b~†ÿr ¢$faÂ8éÊœ` ŒT1FÆ|¡®Ò‡hšw™È©6Æ9*KèÅóH'f³u)uâ -#9‚™Ls'='œ‰HAÆ †e¤ áŠDzÄyÄHÁÐ T*#QS‘0×@nbÏQ&­—2²çìCÝDWì2Šzä&*Ù7Þ¤>¿øs®fÒÒ¿G?Á¥ÃC_޽`¤ƒßîÇù>Ö¶^¶ª“¶ox9æ!\ C–€÷÷~AnµºýáEÖ�ZuŽ’'ÇO>žÇøõýöå[r ¿÷=ýÕÿ1 Ïð(œª¡,:ôa9lÑÖü;ò)Ên-K8ÿ Ã‰>r;º½³|V¶–€6ÕÇØ÷ OOŸ½/»‡Æc.ÏØ|7 Iì»Õ±ëØ.XÝ *ÀÕ°í Æá7b[¾[·ÎG¬ˆ^ ¨oîHlÚZÄvÞúy;Ñ€m tøÍ7ü›n¼JÔO¿x¸GÖŽwº½ZP˜_1Jüï˼¹{¸Ó‘@¾B} c@{ðîý®ø‹Ïî×ãÍ Ô‡°ºFs´•?û‰ýtÏ7m9l}Aw|ïH½/¾=ìã¸\P&gx@Þà·º9¦½ÛÓeíOÔzÛÿ±àO{ÏÛ–ËÚ/[ÝÝX-ÅTÓ2½Ð,¯¥ïtÑ�‹LÄ`‚aó³fî¡:T<÷ÄV16HaJ"…Ìbv3Ú†'wJ­A¿MÓZ áPP¥ª,´¢˜ÆB3õ¢tte!%-‰N:ÆÀsa(w`¡•AdVóÚ¼-^K–Y vý[O»v²%w¦aÅ|)ËÎ÷Õ—R K&GÇÖ=CÔŽª@a†!˜$|"x #›X!·+s4 ‚‹c�a4åUe!ÈAØp%é"E*m­ÚÌzõV‹-Ën©Ku3DK Š…­X-¶' YÍvTŠð„tM” Óˆa&ô«!Ó2•dJ”R¦zŽuôž1ÀM¦ycàµ;ƒtZqŸÇ»†¡e×fžI¯›ò®`6ÿI¥)ËËü0ç{zˆBÌ+Ë"\¸Z‡$)9+„Ì™~mÇL³ÈŒôk„!2't{r¯ ¼ëm‘ÓR«+™5§ÔJ\`‘#’Ê‚¤êCf¨s;TJsÎUHgªû%AYÜŠ{1sšëÚ“ÊÌJ‚© y2!@¡!á£ä 6å©d1‰ ì9†Æ‰P$<=&ŽÄjYé¹QF8Ͷ‰ð‚£ÔÔNÖJ(a‰èØ6¾–—ì·[ßmç“锉‘ÇÕ°ñÁü8üA^S­oí|Áè5 ÞÀ ú $ûµyÞÔQõ±Ýþhuš:šÞåØßð€õͽ>}Œò·IܶíÕåoo/ﲜÜåå!ëCï²n¨¨·ìLû»ñ ;æ¼s~‚ðj'ŒÞ×~êcl<~ÿ‡‚íxx‡ KÅÒ�‡ìXΨÈÀ¹àû†]… pyƒMØn€'¬8]êiíˆSyþ�ÿ¤"{$éV#û?ò”û÷¯ °þäí ·À­£9lÁøÃ}–ûmk[Ù~oøÏ‰€]E~_ã�ü _Ýõøïpà ¡@înp¹Å;@8¶ßãöÚÿpÌún¼ÚôoÜâ·Å>vÛxÛx ìê…ωu_8ÖÒa'ä+ ËÛ~¸çRQß…qËSd]ÑkòOLDíÑ¿Ûn’·¥Óü¾yÓu_ªœƒhBKÌŠHƒ¹aÌ7±¹–• †Þœ ʆ”%•™Œnamº°t2jéÖ;sƒaÈn€Ålghf`ÀènåžÃ{¦³˜ÅP–@Á°’µ~Ìø¶æÝyj0ÝXšµ†âf4É23*62`†æ|½´›¶¯m×ö­íª3¥¯Ýti[Gf% EiÌ�E¡ÑÜpéahCfHÏ•! KL¶´MÖä6¦ÞÌ`Î~²’à|¨°�îV—ºkmWJ-µ¶b渤2‘ § ÷dU6 HVÀg—ç¼Ô)£#”#G/á,fNùKî�)13È©úveÏÐ o€&m^RWüFñkí¤ Nä*rªÞ™1^w.yך9^¥jFÁ™à˜ýc¶å ¥ÙïF†dTÒrÖ\WŒ>·“×$%ñÂý~‰·An˜3›—‹-&CIYÛç5eKèÚQñÒ 7­°³ôgLe»pÆE“Êܾ y½B½¥^ÿ‡„’”Á+¯ÔóÌrÌm0rDôqíd ³QÔ(ȇe—VOõ4Žê =h>.ÌB…g¸ÈÒ�NÂŽ5UaWpë°ªH|è—K>}³~Ô+ ›õÞ¬ ïö~‚¿—½KßrÀ.¢Ç†çÕ³w`ƒ>‚»ŸhiÞ¬eú¶©Ÿìù!²FoPã[yÝ×ÛÃGç?$†õÿÅë/hè66ç .­À*ÀSx­¹ï6N6€rL!¿AØ ½¾GûCä1žŽ¥àqR€Ä…¨À áÄÀ�7Ô^®¦éÍð!ñ­Ð„' ^‰ÔûÀ)¾[¯Ï8=ÃÝ/J9ºC·´ã ߟ¿GvŸÁ?A/loà€:Ò�<Œ›zynÏhÏñ]­ðÿ0°tØ×ø‡/ðÕ×À~ñÞÜ ëC‹£ LHÀìÝ5¬ Z¢í»[èpÚ€óR×sï_œjÞ÷ªý²¡nkmøùó¨Èw¯ÊÉÚû–°x…gÇvÀ(÷·ºgiÐ6ÆiŒ_áãÃç8â ”ØðpÎ#âm_Ò9¢a«‡°–òÑòû¢Ì¸ }*S:Ì·ÊR¦Ý˜íÁÅXÝ‘žH+â sˆÒ) ²QA3K+ªm3ö¶Ð:„9½Êš™Y’E³Ú¾dÏpÀ%Ó”pdQŠtOã¡;Y¦ ÝÀ •&/æÂ®Q”ð¤1¼@Õè‹cÙ£íj]ÚÒÚRK1(ÓJ-Þ3Ò•Ð@8²P‡5`g¼5ƒa—¾„bȶ :¢YÜŠP§KŸœZö�‘"ᨤsW¬U—ÝR–Z[­¥V+•ÎÙôV3kæH•Œ&Ú¸Þ}ìš)ð+4è¥q'H¨_DÊÔQ&Zðeöޤ%h,iÉ.¦ 7‚>OÁJÒÌáNo†2kÅÅ1}D¼Òì�ˆuh@0¸©I–Bd††8<9ˆB\[klŽwrƒÃ]L¤S fÒ&-Ñf(™6k(@ ¥Ò”cò_É ãe1“`)d¾ÄšA‡¤ ]ï³pÕTLX@CWpŸ+¡È¼*ãWØ+UJ!$Œ0ƒܦ9vö¡ffbÆË¦%¡ˆéˆÑG9ºÒ 30 )‡ŠaU E2ÂbóD.1'{™®1>éPÅ­¤|C>²Â…’pS…ÔE{V&.[ì´?t?ŽD<bë÷‡qƒÆÜtC“Å~g;뱜² úÕ€n[c}8<·Ÿ¨Þ-¾/…Rx$GŽ£ßážm¿J´ÌŸþÀeT=5t/¨Yù� èÕ÷uéÁÆQŽ „$6ò�·� lvœ/æS6”Ä ð˜øøT¸tÜ”)­Àc wX ¾~—øM„_>ÝðYÁm‡¿øŽ¾[o€°øøìXv(·ÿaïï#i–é½ï9÷Þ/"2³²:úÉ™&—œHÆ zÒÒXäJAKžþ/Yº .ä‹‚1(G¢¸d´Ý3“]?23"¾{ÏyeܨÞu´](£jTUdÖw¿{Îû>Ì@?¢¢wäˆ-ôŒlðòÆÚþGΆӷð/‘ †ãiûpùízú¿»]÷Oý¼?¶Šµãüí/Š_ü_'¶xÛTäÃ:yz«'¬›-ê‚{Çp,wà ¸µ·x?lnŽö›7ÖoÖs®/õrv¼Çk»_×¥£^¡ôç ¾óƒ•ê£Y4^ ¨þñ°YƒÙqæ±å›~Þ×Ò¬ÞƒC>5F¿ˆ|õ£†Þ±º– ì™ìÅhf0VšaºÆŒdŽ W4‹Ìùµ†ÀN.3«pÒËâάiµ›¯^ÍÌݨ„C˜oÖD W¬RZd¡É ³’â–æâÆ‚U3ÙB³–Ø% `&c¦gIÏ,æÅuñ²k\/KñÚj­^Ìç$œ¾°¸§ >r•F2 ÉÝáÖé•uFFÐc)==eƒ*¦J1SVh"-LÚ¸šã}S¬”²,mSÛfñe)uiui^ëÌÇ¢FxÞ‡6ÍBÓ9ä|cçD Ža#-Sd 7<À ’2­�4™™›É`uss7¿Ö,æ:ÚÌhͦ½H”`L¦ù§ÅC€]yBv©•pʤÈ̇™ÓxêÞÃÓyJ3s§Ë„º,úˆe–re0™ÑøÉý0÷°È` Ë>9G[0¦}ê'-æóS~-SZfĵÙ0+ÔF8c³C3j¥Y_¤2‰å›å6ö ³Z̪]+%³Y!Í›%à‡ƒlÞp¤TÌ•¹�¦ÑЧ£R ÆÄ›ŸÝëÅQ‹søŒÞN?ª«”Tg È"«ŽšâƒI9(qêEVåyY•åŒÍ’Oo„·£6ß×MmËûV ÃêðmiXGÍâí[ò­ ÒAã8.oÄý%ïß?½ùxô²¶æÛíÅÁ _¨>:pFyÌÿk¿ü¼ßx™AÞFøŠý\êyA÷þ+{¿_]ðD:H�åhÀšX®Ô‘„ ¥a;49ކ ^ÎÀ*”N7üpé¸!Ú,@B+ÎÏ0`N< X¯ß­¨øØ¶1q:›?plF¬äØÀ”„×è±¹Ã÷Ä£Àfì;~ó¶_ .ÀòX>Q—¿ëŸáñX¾ÆÀ—ÀWWöÑg‰›¾ÇeAûpYŸ~‹Ë{䊛o°ýîoà[xAàۃő ïÇÍ3jÛçvÉðÿ8ôÝÈw—ÜýôÒâ jí0x”#nðøàÇŸè±æ ÚX¹éåþ¸kh+è èy¶g»GÝ‘n° 12­ùø_-ÿëïGìL`9ƒÿ\Ê×MK¢UO˜ã¹ ‚µáÈ ©-Å*FY%h°¢ék󭪺ã252‚C6’³õ‹SÁPM&ÓÌ“âuîDP‹Uæué0 tÒd3Úh.3yµRjñmõ]óÖÜ[¡Ws§ 4w§!”=!… sÄCwV³‚ Ô«R2Q•’j½¾ê:w1º››΂L +€ÉÝ‹/uY–Ö–º,^7^7µµjî0¢ÏI~€R‰ž6rÖKæ@Ïh³µÂ*¬à6!«e"ScD-CØtØõY äðél*ÕÌÊÄ0Ñ œí¹94)fŬN·Á«ÊœPB#há6Å|s3¡C¦1®¼ëô$ÅF"¤ðùaO€U33BiÆ!$,glZ8[ÝמAF ƒ’!æÈ@œã,›ÓäìDÎ"à$$1S1ÁèÈ R“'ëèÚMUS D—Ñm*à¤ë·•]ï“h5GAN˜¥øÔÇVþ纈ÿ¬™n& ……é”iDBƒ6`(Тœxcz¹0`SÐ’!C�]rC3ud ^ÈV,f²`@ÑÎ4Šjà#ªW3Ã_É~:xõþasZK-VW]z.¶/ÙŒ«Ûžù†¹îòé+ín"—sÜ?üôŸÿŸ÷æ k×Î*áf]~Ê×}Éq÷qÑ®)lÆÓõõœëé®ý¦áƒ¯}ôÿ7ü±#‰ñšØð“„u Ù@ 0œ(vì+Æ�NˆFbë({W°o¨ø{Б¯p®x~…¼ €w+øÓ?¸YÐ�ëÀÇi¶¨Mh8àö[ÄI`À:WÉ¡½á·[äǃ­uÉóEÿã?À¾Æ«Ü¥½EÁ¦^}ä7X~†vÜ`·ÅÃ-rƒÛÄîrhkÅw­÷ÖüU[À¯pþ%nwh„voTö@EàËãîñíòþ°|UuÛ6ÙL«¯£°¼Ãz9¡>© ç«£ ² 'v†ŸtÜ\rTnúæþ ®Ç VH‡‘}W¬[¶Ê2ë5±ž³¹í¬ZüeÓ©½YŠ–{¿¼lËKÏVº˜ ÕÜU31Vë—Â3ÀD£Vž°Rgߊ&Øš6ÿµ8Ñœó-4¥51¨N“á8Ó:ÒäÁü4ö5Oƒ®‘â\|2D-rNªA‰%d›¬cÃ|DW·æØ¶ÊVç PF"Ÿ*µ˜¯¬éÄ@R !„!3Ó%°dÎÐ,%|d1™#JqÔ &`Ö`«VuòÆQ¤2_7[ñRk]jmµ-^«­¸‰k/y¾á=rÈåf¥¸¹×ZŠYqÎÎôÞƒIK2eeƒ.§¡LÃ%fg¹ÈdÅÌX«Á¯ëzÉy•0»Êl¨€ÒR³=0f›Žf"›çUcÊ'æ‡C1}e×ôÈŒ CSU'hLçp/‘ÚÜ BÆÄ§Út¤bÆ“ÚR«™ žPÄdyeZó²UR$Æàœv³Ù`p€UÚèj&­Ì"qCM!5ˆÎ™»š âkÿ`K½"ºÝ@ZÝŠ™Ìd § ‰ì s… Ûp ›éláì•c¡HEø™Œ‹t—1Íâl̆QŒf½BÎäˆl-¤#lØ0»ÙØø¨¯„âË¿¨iö<¤m…±¢ „Zú¿,vËSSùœ½WðíÕS¹ùçq³¢„ôëªïÄ/—¾Z.ˆÝºú£-Í-³ŽavÉñ¿˜`v`_ 5#.|Sð׎7Ž ” È@dožmSªò¯27æDàO¸þs<½]q$Vâ%N¼6l+–Éc¹ÀVø‚>°îð®Áý„{â÷u‹A\O‚ça¼;žãŒÓˆ§ñ¦`ÖU§úxò·¿'ìþŒòÛàD|�.>ñwö‹õÇü À@yƶÁ� D?>ƒ¸ÜŸáR€;Ø›'r=Žwy^ãWø€è{Û×X¿Á#°ܾ V˜ï£í;vU/6PžPÿèX_?p·š0¸ëáßBø®øÏ6`Þ ¿Q+/†o¶—}y©¾t»¹,7ã;x™/u@`V½^½«¼ôÍͦ!K…Û\ Y .ÄaíÈøSë±æòŒ°îÅ9v=ÓãEÚzX£ÂÐò‰6Ò^L·>ÜdD¤¡ÍQh$Á&Ì•á…M½zèl (3-M.$jMè¤K²À!“•V ñc¢t½Ëƒ<a˜2�7c%Ù<‹Ë}b„1©lœÙúÕžyÝbUM…ž×‹»AÅÑÀ Àƨa•á‘ÅÒ3sò–iá(¥”f­”jµ°×áM),Å­˜W/Õ®?I(FDD¨¯£÷è¡�Ù¼úb^œ¥ø|ÿ‡2”L Éd€lšÍæ1¡Ð)ST7–´HRóœÃxšYqV¢šf­a(ÿ …qÝ>ÏE.s6ì21÷ͳg—•(fF'¨ëŒhôäPN¢øü„%ø´TȈóA¨s}-90AŸÃ+D™Éɲ™ XÌ'øzÇè2 ebûæåm΢>A²‘òDe ›XV|ýäìšÍ–ß´„@#€%sÀ§püº›àÕ*—œ@<Ÿ )ßbV áƒ³¡~õ}f@îÞäæži©n–Î4ɯY_˜$‰9€d)9àÅçp‘°,ìC1÷D*%Ìä–(†ÎûÎ:¶½))Ï­b•â‘%ËzÆÚKÙlŠxcÞìyµïÕ8îb],v_ÇæOµ¿+§§vùç»’ÛÕ<¼ ÖÊKSÀ:$d]™+9Vàv`Ëã8㦠¿jxE|X:< ×ÙŽÙ7ìG6D-/›H÷rƒós>"—^ Ö-¾ÝÿUE%vŽ D çvd nð¼^`GÜUÔ‚\ðâoÄ}žk´‡—z\ïß>|3�ì1ö÷k+mmN<'òŒò=/è†5ðî|ÞxüûÝ3ºYYðtÆf tô÷è@~ T´5$Ð ­ÂYåQ¿P÷èþ‹Gw´ |‰å=vØ:Úæý>Û}·æ¨Eý!_õúµžûöò¸ãÛg>üžÝºsƒ»Ö~ÞócÆCÁ#ƾ\ö,­ûº,Z`9/§Ì3ðÙ¥4ÜÕh/Öþc¯Å´±(ôsœOx¾ã‹ñXx(‘6œX±Uþ$¹ Õí9úGK¿”ukvv?¯ RULuîꪕá5½Â9È4ƒ•P512i¹&/¡ " Ëtù¬ÅB”ˆA¬iMB84‰@³ûM\óÊ_¤*F ‹¬ºy1æÌ×✆A‚“%1-“ó ;‡V˜2fB’%¨"5X!Y-Z%&Yši†ü“š|>¯ÞZm^çÍÌ̼X©tçÜöš™»§1•Ñ»„¹öì¶Z·µ´æÖì:¨¤1ó£’ƒ W`„ˆ¸6ÎÒ”@—æÝ¸tY åJ‰¸ÎlHŸ?§²L…ò©ð‰8‹Œ×"ÜŸ\mrÈ•6WÆ`:á–ÁÅu£›F¥Òaå“÷4Æèà¨ÈH"Ëô-Ìú/~øã}rÜM¨Sʯ ˆ)D0êó©>CL‰Y~HQ×p­\°41n³“z�� �IDATi>ÌÜvü™!!íz)A ʸZÆ1·¤ý {H`^Ø035Q²I\é°f„CžB¦{ýT‘Q•°/rd0Ç9w! efGtƒ„E„ ¨ÙÁÈ/sC'ªP’‡ÌfÛÑݬԖ[ß¼¾ØÍ Q-L®n.õrëx^§ÀóæráóÅn7†eE«n½Öµ¿òÕw±»9-uU¿¡Ý^’Ïßà|±¶d¿óÕ¬°=•±¸—d²ÊZ °¢£=}ÅüDx=°½À½ ƒ±r´nÛ£¾î½ÚHÝq·|yðwǸ ßv†/ bë(××d`|Ü¢?µ  a1x¢8†ÁÊO‰m­ u]ÿ—G<}_ùKEiÿJÍŸ°í•»ƒü8NX_ax&”(ï0þ ø�ðõÛ)Uù/ ÿ×?u<`<–ïßž}ƒ¸�ÿþàKüwÀÿ&ü¹°'À+™·o¨?;¼º?â Ä9Ö3n>CyB-¨¿;öú§Ã|´#Ò½ø ´yëâA—£Î(q¨µþ#ø/—Öº[_Üw}µíÍ:J¶ˆ¦V¯‡È£„žÈ�ñ™ÛWµlÔ†À?„½{Ñ-W“,ƈޛÿ6ñkˆ#ÆW憧wÐÂKjIóP®qJ|\ðÞÊûð¿­<¸þÄõ{‘ÍÐÜܪXÝjíngr€Á€ŠƒTd®ˆ5y‚ΦÊ*4P#“c‘Ä‚”²Ë‹’¢aLPa”,„"Â5±pé�­ÀóæFg:Ák1Ø–)©Çè™ ˜ Ók® œ³ùçô©8«Hf"]*a…f‹T¡*ºiIjÊÞ&ñG’ÅZ­K)Õ¼ÐèæåJKu›@+æFBZ'Š£ò*½µzÓJ[œeJç3{F—| $*µšræèç´.ÝÓÍ9e-i¸¤bdIUÒ\,šÑySºŽÓ'«‡.ø'<]Æš¡LŒ¡122‘dN£Îµå›JÄ M9OØI25NcuñéWPïJ:fm{Ä4§’IŽ+ÙÕaó¿¯ü§™¼½¶&˜Ä\ÓNÏ%o4‚1s®ŠˆOñY%S>N3 &­˜ŸYÖ¼^‰3B«¢‚ÉÍ0ÁS„®ÎØ )M•ÑÄ ÚœçÍ£C˜Þ À,ŸÏjµ‰žp%¦EÎË<‡]Ê4ë0‘¤è‰Œ(I-Å‚–0)fP ËÜD „˜cæuåÕŒJDöaPPr·Â²¨º2Ä 8!r¬¾˜uËq&ÖžÏïø7/寶ÜÜ—.Xù:瀼}˲²<±þÜ•Ã5^åwËyÍ÷?ÕÇ®ÒøkØžeÍ}%Kà8 ÉO(”û€rO|ØË3ÚGЛÅ>²?˜ÖH ÷’1joÖ‚fDZ…Î`Ç™x•¸(1×iÂÙ?.gô êÀ²Åò†¼¼úéš÷°­wÖD­U¯Ë8þ·‰ÿcí¶[sE{·î¬o_ýu*dxèë >þkàÿ~õ ðå _Þ|ÞlÍ ^žÐïË×x÷ ~ñ3¼ÞŸ¯° …W‰Åqãp¢Ðì·÷8oð’8-Ø,[ø x9ø»0Ƹ•ø±ñÃH,qtƒó˜õ#*ŽøìáÚºõb Æ Áhʺô5Uιzïg@ȿؖæÜÈ74D-^êz\F÷Ûžm¼,úhþèG$"çGp/ën5Í3Kº k#pfq4ÏÚ}˜[ðsËjæµ³¯–Í‚6_ã$¸‚ =õâñbÊ!g°k Š@§Y©Ž!"ì$“Ø\ ÌÒ@*s Sa×°ÜhÛÐóB¦Ò]L–k6R@óVÄ+N(e¦ MƒóŒl^33H !°4‡YP`žNÌP¨JÄTf@fæÕ«×f×¥x)VS¶F˜s*£Ã PuUª‚”U+»Zw›ÚYŠ>Ðg©£$T"ûœæË,œÃ ¿ºÙ<a”²'³;¤ –FÛš•ù{;9‡€FøuD%¤ÈÈi¦‰ýÆ|{–¤Ì‘aH³R ÍRJæ^ÍÛÆj…4ÖUk1A|H\ã¢#æ¤hf¦DQ�Âܼ˜›™C.³@zWn‡ˆŒ4^ŸújÒuœÄ&^·pÚ¤é]Ç_Èõ©  3JáF“ ˜Ó2±˜ÎÓêÚ+¹Ž¬æ ?aÚ™LÍÏ.‘!Åk£!€a^Í(:AóO„>MÈZl'+PvbeІÑL&yŸ}'MÌ@ e^.ðh†ªbÝ´f%Ú Öfq%Åô©B1¹™›‹Ú©žpø`ÿü]<—òQÛf³I{Ùé_?Wþ¾ÕÞåâk+çQ~ãe=ožm¨î™z\x¯txs> <"ÞF¢ Zç ;Ãj°3¼Ã>B�?ƒm�Áû#V¸ê©´´Í÷Ū`í¥òq:ã7 ú€RPmE¹ kAì0€Üb] §bÅ«v ê0¼\ëþü´í›­Ówu]}é;–¯ÆÃ‡Rÿ|ÓÞñri×Òoÿé±ý˪Á–k¦VMÅŠƒáø;�¿ÀŸmìlØÕVDU?¨·¿Ä·7øÕ—øó-ö4b-x<áß;þÌð‡€ê-ªP…Ú0¶ÐH,ëéÀ<®ªG[þ¤hÔ—Rùpþêf[uyXòz˯ðÀVŸs»±>îÌîãwK‡ùí&û‹ •!á¤0‹,ñ·ŒÿÙ˰Ì=Ä}�ý„s.ãÉí=tT`ë ™Yw”»(ŒR|&V³mn¬Àã'ò¦×k>MYÌ›—æQK!š"×áÑ=Ç´«je|ÌQ¡-ÓT$Êí¹\mfY<#ÑS˜+_ÀÈÊb™+u‰áÌB˜y‹ÏV™¬6q=œò–”˜Ì�a^‹UZÉk'ÓiišScÙ5coÆ£~0' ór.¯a77UC¡ædFêI3·¹âžc$xƒWš_cœž¸ù’kYEj ¥/,›Rš{- sf­‹…L°Œ¡¦h6¡ßWÂÑ$k7( …ÉíJ‰0›”iÎ_??qÞy2#ûˆ>bÌL •”#gGLb̳!2b¬9ÐYJ ÷“4h,uSw·^€Ñ.8½è²N³שGÂç<S6·Ïº®}ÌËü æ©€ )1fçLb}P…ëöeÖÍ„”Ï‹KLWڸѦ;@s0'0a)£Kîr³J˜ÓÓmú9¦WÈ ÷›øYPSI8©+6§ Ê ºyW„c ¦5Pžn2c)–µ¢„¤º¹É"Âg½]ÎQ)%’5D˜�ÂRî ! 34wÆ2¬"©K0 k¢j‚(Îͺ–Š»­Êgãík¢Ú_æòÅ<Uª—m`Ku/Å’_’Û÷_þŸ÷ëWC[d«Ëº–Ç­þºà/KÙJ[+€ ÄzÈõ˜¾W,K h‹üþã¨Ùx9¿Å@y<ìî78m7†ÇZàfØlPÏp¡ Ä÷ˆ—W¸|�‘8}`]q»EÙ¢n±«/Oµÿ®Õ3Û&8Ne{Ëã¶íÙöKk^Wàñ¾Û—oŽ7?‡wX;§Vþ¦´=[½üìá‹ûÇ7_¼µåÇÎÅš¹òÒ7qÄïbüºb|Ž¥£ ´¬X„7¼ª¸OÔD%®±¨-¬bãØòͺîcÔµ><ñq»{k lfø¨ºØ¿i°ul>q< Zyó•íK)f§€¯_Úåâ9Ð6&³,¥”•’u¤¡LD"Ç·:UµVQEe׌U# gËßyþD_�úzäxÀéE}›diX¬ð2àŠAï©Ì5L9™j4º•ÆR­z1Æè‹ eäú¸X$bU ‡#`4ÇÖaEƒ2³œ1MÆÔ~'4”gX%'O¿�@çÈKô¾‘ZñF—/Y&2N)ÃÒçA\s‡ ÂY`5éœ[äuA—†à"gãlw®ÏMÎBÐÓR Qfsbq¥ ñê?žé—9¿V©,ÍÓK˜MÙüÌ;ÎS"£LÕdÌ(=lšå5ñH1mfsÔýɤ ÍIqÍš‚˜WíŠèFSÚÜ…Ò +YçÙP¬ó金&woŠqÐÇXLj™#33{ª�NM€Ó„L 3bdRŠ +2“y+^k­›º,óv”RÆÐ– Ms¡d^wL)æ@VH×éÔ̪jpµõÌW戈¡š›4L33§8h¢i‡€D®.Ÿ«éÇÊP ˜²Y¤)er˜ÑÍ´ ÍÕw"‡Òòj±H2ÁPˆ dL"ßüò–×ByгTŸ—¾£göÁ0£»›“O‹sRK nJ²!“‘ÁŽ5ƒðœ(MÑ”O ¥At(È ³„·d%£ç1V÷² ÕÒÀìŸn íJì_èáÝ1JR bKy±9¹O–—;ûÈŽ¥×8·87ÚMõòYGFóÚR`©Ð¿ön¾Vž*Çþ­Wl uo¨=?«ŒŒGñ- ñ\޼ :þ1ޝqØŠÁ·HǦ1•Où+ðÁ`p� ø °K”økhJÔuÜâÁÿ÷µ Vÿú”_þÛúÙ!KÝn[õ†‚ÀýoÏÛWÆ¿:<,N¦v½òô |¤¿•öaûüªëù^Ýà³úcgÃóÇßôú[ÚãCû½z³{8·G¬o/Â:€ëÀå |&ÜÜÀê¸ 0a(Qžûû3Û9Ößl±óÃÖÖÅû…©Å ÛáÎÎ[¯ãØeßc_Gc[£=®<½˜ýÆ«ŠaWén÷Þ6¬uTà<>'XÏ¿³õu½»Ãìü2µhSòßÎÑz7¬15õÇËMÂ×ê›fµ¹ê÷Wæ½oFÚ*ß`•V�dRnؘ/b ¯r“‰¢—¨bŽÌ³eD@Šj¬ÆÅ«ÑÕ ŠD‰\]½§í¢H3–nòÌëÊ.Z%¡^ä(K™Kž uÕÍÏgB¿¨ñi¤lŽk&q9ôÍ@Ÿ¥1Ù$/¤†r(SˆTГL ˜»TK›ô›*…2òÓbŠƒ )NεeŸÈ Ë`$º8Ÿ~É©!02#Öˆ‘1bDŒ>FDáQ]¥Ìë™>ƒ%UµÑÌ á•^¬š7x¡y±Zæ BfF¦FŽŽ•Ñ•=ÇPP*¤Ñ‘ós…¥¨ˆ N˜E…¯@²º“ÅÌg$ȼ¸§»c²,FÀÈTŠÌqý4tMI×Ëž¤"m]Ê«QaŒžq‘H¹Ã]ó«=·ÕADÌ$ì´Ÿ‚3dtµÍǶŒºfe©"EgšÌP>10FfGf†™®{‡)´°™$Ja\7 ×kgJis˜i¤[exÂ3•êc¬}œ/ÓÚ`^èä–p3˰ ­v+Y4TFfö`¬‡4®€ I8g‡#5Èñ”e$n93ÆëI::âÃï=‚XIqFï¡.Ö!óø©ñjþdv7ØÃzuÑza­'ÈüHëÍovGÓCYáØ¾W½tûêo¥«« †5Õ ÌÖ}][\Ö¾ :f²Ø ¥îñÙ^çfZ9ßÚpðÍñRPθ;½ùÓ§}ïõ¼<”Í£ámìæÓþ�ãï0€àòû°z(8BàŠö=¶Á¾AïàŠ$ªàùx{€¾«þ]ß<r},7(+v@[KøßûöwÍ©Sí.ø©éiõ×[n‰:¶mý²­‰›R³îtü‘³áÛw¿¶~¼‡9C2¬�`x7°ý€çÄ¥#_ ´[´ Œ3âO/‡ÜmÅF‡Û¨\Ïí¼Ã£ê?ÿ ú W%ª¯¨¸lÖÓmãvÍÚ·v¬ æ£.çVj“�«±¹¼”oÿ!ê+v³›V/`®umÔWdõÁ·ëú–Ø×ƲdYh%¤îyYôù{–GºAõ0Úq(ÁìmÙ<d¹-Í|)uQµçžßÝ¿¨Ÿ±ueµz|Wʦúb¾ÈÊì$Ò €‰%±E£Yå)ÝVª,žF³´–Z2ÀLõÇYµBŸ^†Y'æ)kôÖ‹Œ‹±˜OÞƒÜô顦€ÿIX3Øœ»À WãÌAçð„ÒHYhúéõ)ÎyõcrB&m“D3át}#¾ó'U38dC‘6ã%3¹‹ÿQŒì#G¨ÙׂÇeŒX­$ÈÔ|^â²Æeëˆ>p\½…³JŸ­Ò™¨«±Uz!haâ,Á~ÅØ¦„"rô#úkï=úÐ%cE +F‘>>šúe„.³™‘M„s WdÌ…LÊÁ”“îåÊ<J$VLͪKÎÑ–MÁÎ<B"S1²ehBÔ&g#"F ¥LU4:8ÿN„R7B,¥œJÚ|¸º€òšŠ³œGˆ˜å9ÚÜ1'Å™\ˆˆÎ0K7ÒÍŠ_»µ�¦Q0‰ðÀ§…|J ¹Mk“û-¹ºE÷±ŽùK¢˜®{þfE¸½Ðdg: †Ê fhD 5D[‚Bk,/ÃÇðû^’%Ì92GàÒcMÅ–ÈvIžcÄP-gùjÖ–Å/¨±Fÿ¸ŒŽÊAõ¬yég=¶e˜]Ø�lÜ8}¹ noÌßd{”¬²^”‘‹mwX Ž>ª>z=ŠØð�ÖlÙÆ*÷~þËZFì6/oÛoöÂ^ß´Àzù%ÊýA:ª�[œÿ�ë÷ˆ_âù=úú&oö­Ö§òPÇc{~ÛV€‰.œŸ­bsFomÜô³#îaêЇG»Ùû+#ÛŸñ³×ÖÚl£¯ùôlíãvWZÖÑ«¥­ë+ŒóºCßà¸ÄfXÏÇw~ØnêöˆØÚŠ-ëWyÈ8æw°ö ¶?¿€áˆ'\Þ¿9·÷µÚÃ¥?î×·5ÊyíÙ×wìEÇâoLXjeöZ¨½ÒëÇÖ[{l†í€áXãëZÆDRõ´¿ðÚû~¼©oZÙßÖZG×åë­©ª.¸lk¯}ì̯i. ŸKåqpoÄ}¶ªú|”ÞÊœµ%ÉM±â„ë•S^;¼†«yÜ1éíu+·µ¶jÅÌäh²8É™$Y–° ÀaÖí}Á!Y7ƒ¸e…”á (-€4¥›äT ‡`D‘·ÒŠ/´jVÜYŒf˜%és¨ƒR–.#Í&¼LÙd‚νݬS@LШ„´y˜ÛÝOÆüª²Q*q­ÎÎ[>¦Ðw&ì’c¢â®oæàô*)Ÿ¶¡Š>.Ñ/Ñ{Že0» ZIC±®—s?úù’=0†u+k¤ˆbP‡A0H¹™Y±â,…îÊdæ[>€Dœ EÆšcŒ1úèc¬ÑûÚs:!.у´j,fåʾS(C‘ÉËe‡’CÌÌKô“"F¬™Ãm®±Sk0ISê‡9 Kàô)ŽFfƈ޳TÌÒeŽû1 j2Èi…¸ÎmšJç~ˆ‘˜j&š®˜q#³™NžæPõY¨¸šŸ3#".1FšŠ³¤ûäVЯdŽ š\ûY”ÎÌy: Ýfô é@%™ i¤NZ‡H„©™ÓK›67•Ì®ré>Pqº_ÂO™'6 ä°iÅTKÏa™~©ÞQÒ-Éi1Vm +ì$Ñ}]ä5=QŠ•ÑÌ ãä–þœö·’Ð8\.ÇÒÑn§^Þnõ`q[ïhXŒ{â¯P¢CoÄŸË=·‰øÐŸÇ±ŸpkXÛÑóZÀÖîukj”°Ù²Öoêd}®_×~ã%îÜ¿Jím.x^0¶H`‰ýËvÿ±¶ðµöÀ P?CDŸ è˜åIÛ"×£/ˆ² ðÆ>ìÏ>†•Ç<¿Ç\–ÖZM3 ý òÅŸ>lu·övå^Ýûòüh|_ýÿŸ Ÿ;^}vŒòW1*ÎFT¿oŸåQ8´¯Ž<¢àPテoðL<Wœ.û›û½}Õr»áe@ß>6 oê¶÷Ÿ_ ¯ôvó¬Ç&t;<áø9@¡Ì®y}Ô ¬TŒžåqBaÿÈŽm‡Wz[„b'Ü*ìÉ­YdÍj™åó—¸…U¸×J•º©(Y~.~y'îäC&òæ¢Ø]/w¥µ‹¬»_*aºæ5ûR=C|…¼…¿²M³B£ŒCÓeBJ!h`5Ǥj-J7VÃ$rБÖe»€If‘Jhé¹#¶#à˜›¹O½T# ŲڬùJT΂]ü“œé–2]à.z¦Ë¨ÌYl˜ußkç 3ÄŸn;=kS‹i‰™o™?ˆÒ Äµ05í˜0kÍv"=ØüšbOä¼YÄÈK_Ï£çË™£a÷‰‚I‹Œóe==Ÿ.O/ýrá—,™Ã0$X™>o+d¡58hN$Lq­]c‚²Óg5‘áè‘ëšcÄ#z¿Dô±J=rd ÈÍ}¯Ñ`�èP‡6s MÊÌ+ÑÇx™Ì qú2HcfrÄ€D¸ÉL4ýàêtrž 1ÏÝ®Þcdt2ÈùËÍ tÂ’ z»Œ6í ò„'S¼êê$Í+ŸÀ„MÝ|.),Å+öü“r[™FŽ‘±æ¸d0U’ ŇW‰"ð V˜PРY•œU¾‰fá¤çc÷ÖµiC©™ç`-.÷beáÜ8»B=ÖLyg­W<—å° ï##SÊ5²*§RÔÙäs»rM%™Éšû¦©S7k¤ elpqÐÓq*\ïì%ùÍ¿õ[Ø1xÌ©= Þ�lÔ*2›*"ï¬2ް£€Ñö©ÅrÉnë©<>—Žè39÷¸tØ¥æK©Öd¯´½UƒÆÍøjS~¹òïVþ ~_ý³o½ F #á[ °<|ÔZÛc¶^¯µöCÍ£¨ºWƒ -A@[DE4è4„#seYÚ3Ö·ï´û{ÚfJ­cð%ô¬w¿B9О[´ðïnˆŽÕp•3þ—φûŠQpnh� \Qc³«¾©‰¿ÚÐ^Ö¥þ¥ü×g›³Ãëûº¼´ºiÙ°¢>ÃÈqwùëesðqÜvŒ3¬'ÀaŽ¥"+nyüƒ„ |hoáP9€G» 4îxl[a!0Ž@iHÚBKÜÊ"p›åvm´’ÎŠÖÆVcXiÒ— ÕÊÒpBÞ!ýw¥¼¶6ÚP ê\’´²¥D© ÈÖ¡ÍÀ&á2ˆ]⤀M¸ƒèÁ†„èFÑW-Ú «Û F¢ÒlÑs0Fª\¸IÝØX’¥"fëÊ-²DŸ,7æ³*%fªgJÃ`´PÎ7Û2аÌÕ-éÉ+! ›Ô6äu޹›Í¹'±%Ι˜´ “4s D}ª'3¯pf(3C‚ìXc7Ñb$chDô É&2ÐP\´Ô3zç—~úxQOf:»%F´tGõ´4©V²Xw¡ ˆ„ÌäÈ«`3Rž2Ñ=°väš™cD±ªg$†,þ?ÂÞ¦7Ò$ËÒ;ç^3{ÝdD&+3«•(µzF* �-ƒX BƒÛúúg³„^HÛ!ø®‚ ̪Ô3SýUÌÌ`t7³{æQ³ÌM 6Á`I{_»÷œçÑzžÓgäç<�L–BŠ!f¦¦™‘É raVJE\ |×57kN"¥u+…~-3'S‘‹U§¼¢f¡Æ ¥®íŒàk™_‘ž€Ã ± m«¯P®Àé?-”®E#¼„A«]b „Ìœî@^ IÑ5†"òÚE_¶Ðª‰t"¹ÆTÚ5_»"³L2éæNÛÌŒ¶àèæ! ÝlrÐ-ÇT—šáÍÜ­˜ÑJªfL÷ð€¹¼-{’ æðÏÊY}˜ =j^Ü'Ôˆ­²!i±–@¦0ÇæªcÆë´³6•de°½Š½åÎ.ÅÎü±`¦Ý¶ä²~•»œ»Gæù˜?œôŠv†•Sã§ÕTÍO;ç7Œc÷ØoÔ4@‘‘ŒÛô€;œ(€ëqKØÇcûþÔoº¿;ïK¶úVJ70žöx*?¿³ÛÞíäm8欗z|Õé#qcÀ×§Qû!ñÕìÛËhO'øÌûY«ô€òþ˜¹-‰x5¼ÍÓkµöæí%Ëÿ5'„_dÜÆH]Ú|Í?þëÛïöûçßµí]Ïó¸ðô˜õ‚¨¸ø=šóHtÍYònŒÍ°û©’ûRM¥]P,]{⩼>Ô…¾@E³ü懬ÚZyÚ æÀe‡^?ÀîuoÞžl÷Xˆýzä¾|ð~ÏYiâð( íƒÅ})•öpkO[<– çL޳Ôî£P?Ùü[‰ƒcÏQ›Á-QG qfÒÆÎÒ<÷eLëyCÍr»OáçXawHÎVâ ŸjßO¾ïéo-mfL7YfŸ×v6˶œa2K«*ÊÍYj¤i(_ššƒ9ȦÐQ\Õ²&U¤+K§J®p®Á¹` !sò%`+HCŠi¹ÎtÚV¬¸ ˜+þøÙLŠS ”À�'¹bH¾¢BÊi)î¶Þ.×$׺r^×È5Éà"æ2 ,´4)ØL›Ã$2eW·2­Tfr§›Ñ<BÀÌ9Æyê5182CÚ²˜è¡RƒCÊÀ–«¥6Q ŸÆ²œ™IÌÏïÅŠ`ŒÌnì‰1W74#†FÎCe€"f ²ÜŒ0Rò0ŽH.ÐÕº`u<˜™J[Ï-²ÉŸ ,b,>öµmL€H®xê!é þQ®r锸¸Ofë¯\îkF(µð½>Ó'þ$-Z¼5õ±u;t³Š«t!ËWcÜÖã/C9s¬eƒ"=#-S>Óײƒü¥%�� �IDATcQö¹úy"l)‰B\ˆIx¥7÷B iHˆ!«‡"O+CÓ3,d“ÎBŠÆÅ• "ÝT “Ži‰Áˆ³Â(f‡¿Ì"ÙnÀ¹ƒíXhD¦9×UPW¾kÔ]õ[%³^Ì_ŒæÓJßaîd¦×ÐÎâÅ'ØéûÖ~BjXÍñ`/Oýò¸ÛxB"ÍGîô¼î³cð}9M= t rØnÓ7#?Üû£'Tà Zžòü2Ç¿ !?/¥ÖÒò`íúÞýÎߨÝg¶söÑGï§@'ö s÷ËúSO›c‡ûúݽ}jý‹îÝ ‚¼L<Oxžîü!¬_5ˆþØ„íù\^Ó“¯¸?ü¦ ãæ/Ÿ¶7lDø†K¢ÿh†5~wÔûêFÏ=^öºì°«<`on%›«ØsòS1üì†Àe<é?ƒY‰qÜï÷‡Ök× `°‚<ãåöþÚý·¥]¼ï Ì1Nì'šîýrÏçö< Úíþ’÷R+ê¶Þ†âC,rHŒ¹{Í0©ÖéMÖ,¶-±eì7nN´XÓjsœ»_T1Ql”ÝyÜ9»ÉvζãŒz…°LgìQ¥ª¼™%cLaL¹§Y«[Cˆ!2„é–>ȬHË5¸md+–œ–SçÝr6 …U!çƒ%ft¹¦–¨Ø2´ub`ˆB("ñF¼’Šg¡!w»Q6*ËyTSSn…FxˆL$ЙAÄ*aQÿëÞš(`¡]mǺ´X35Ó1ɔЉ1säZ1þï„3Ó3<£:̰֞¤Ü©%i0z±âšÀÔ.“ã‚K7&ÒÉ-ÛVa•0ƒ©�{È2‹Š¹­9ýâ/™L‘yqž³ý Ž3tQDj&8à]œL䢥÷uEsVXz#s(e˜–uqÊœ&LÐâ7š±²Z+/ &”;Hz`‘•¹JZIh[ÄZ>ŠD,Y’v--¬,ðzœÌ\íåCM ]U×°×Ò(ä•\ÔY®+g ʵ0Ò5& ¥¹6ìI…²e¬hp’tÕj/ùœÅU­q4±Ð IC–dÕR‚±®Y 2{B‘MÉÒ,2g¬&ºÃ7·ž‘´I›Zy-§zõà¸+©bÞTMìœÆ¨©‰y†pFþ>´;k¿÷[YU¼ƒ£U4Ç–nQ˜ïJHyÞ²ÖðR÷ ·Éž[ÓÖ±ÇÐ�ì~tÜexZãÇÿRÇû£ÏÓ¼{ OîÜvmÞ¿ h!²*@pï`G8þŽÿüp.‡Eÿe·Zò²;ŇíC=ê8—OO/Àáp‹ºÁÚã˜ÇN¸NvÀáËcý®–¿oü¶ÅðòçU÷Ç·r2G1 ñøÃ/Ïøiãép€ysüÏ…*Úæó{Žd½üÝâÞ/8úoN¸ù9¶ ¾`îñxûQ_ôù7§ìÛ'ñç59L7ßP¹Óm¦ÐÿPíwßܪüm}ù»Ä#ßcž¨ÈçŸy¿£5Ýâ\+pÌËéUÇÿgÔÙÚ[¶¯ÞÚìè8yÂttTÎ¦ï› Æ¥Î/*«½´©æÂ¦ªqL܇(ýlRù׉º»¢Ö*vÙj)pE)¥úF ¡~)ÂTÎD³©´sË6ëžð¶ÙËVX2H³‚Rµím»Ôö®X °5\¸j“øâÄºàƒŠDÒŠ%PÜPsC4³ÊùÌXõ]˶Kš¬˜Ä)JÅe,´õƒVÃ|Œ±Nˆšé * ˜Ô+xnPo¹CÙ9·Bs×I°4ø*¶’£+ʺ®¶ÆIZïº÷wøZŒ¯<»Rœ ¯v”'4GŒ—sŽÏÉ÷L™HFVÈLI'}Y¨Í‚p½íÒA&¤rµ~ç�¢iï¾#+°Ñ6ZŵVÖç—©èÌ ÒXD³�lù¼k®}èè£ç<'&4×2U‚†Ëu-2Òbd"K³ÆIs`dŒŽ (Pб­:\vK “ë]:™X‹eJµìÌ=¥©È$b®ÛÑed@äò.,Ôjê-ù'!bÚr0WEºò¹3´,rC«ºP®•­ÿuà:Ò‚p]J“e•ÓÍ«8/!’ÒÊQ\N ñsÌ @*ç¼R™XÖ&<Y´V^ ׇ K˜xÅ£x±2WÏ/„ÐCð€s®Ot¸÷Ô˜‘)•¤hBÆd*WûáœåÂ’Vˆh¦]ÍÊiéÙ9¼( Ñegã‹L²Ÿ$êà]êP³‰QŠ V“5*ÃIè}/tËás®ûÔžã’v¸„M ¨z;ÞN–€N³|#¯Jä[×oÿâ„=Ûã¥çáÎÜmï­}¬y9^x/h„퀟b¾b\žðé“>ù¡ZÙ͸ÅyÜaêÑ/Ø]Žö|Â?£íQ¿ÆÎÐ*š}x÷oY/cÜ-³œ¬>èÛŽß‚ßöÛ½œ’˜Ä ŒžñÏÀo¸õqGøí±ÕS)ÂqÜòT:vÀÚ %pƒSÿ l†ZQv@b&êwøô£ý†€}‹=w€½ñÕÉõaÓýÞ*­‰÷gGÔ·¦ËÎoL/È=ÎwðÝ +ö©7Ã÷¥[ŒÈS¹@ϧ;.èVqÉþ=†ëtÛq+d?æ¾ó[ÄKïc§Ø#nÞ¬?rôö2pFm5¼½ÙaØ^m¨œ#_>•KÅK”ò®­ÃÕá…ÕáX¬Ñ¬ñ)æPT«De¶4³)SZ3TM›QÁ¢6áµ”í'µì’7 %à ©¬¸ªÌÅè*ë…ÐæôHÄ&+W#‚œAÓê`';aÀmš.‰.ŒõΛœ�52 ú0¹)aS™ªè"aoðÉrñíÎöî/ÅÆ FJIƒDn–.˼ ˜]¬ Âá¢[l-“f…Vd–W'e^ã0X¬eéVGcŽ1f1âZÐuO-Øš´®…¥yDrË…õHG” PÌ9bŽ‘½ÇÌà&çÎUݪY•5pYKWXÈRìÊ„1̦¹EvE†h™œR9ƘE"ª®ré¾ÌŸK P¤DN,¨éÔ´(΄„ˆašš!‡a]<ÀPŒ„CÚ„‘¶ìœŠœÈeÙ«3#F 2»v‡ÕÍN F}vä,ãô”M¤ ¿R^•‘ñ¹ð€œ33!Oq ×§Mb->–¢È|äòT¸¹qí°@jºöéd´B›n/ÔͤÜo}-ëÉN^©X«&m’n¶d1^à€2Ã…9SScæëepN™|$ÎJêšÕ¥­ŽÇj×9B'ŸÅ?ʾÔÝ^7•{׿³rœT“”ñB›4CûÂÐûTuÂMEA]|X™äÈ$£ Æ åÁ³$ZQ„.]èmŽîu´q*»µà™õ‰¨8|ûÄŽÝpžÒ¾A«4Tö؆ýþä„tÔþtYñ¡ aÎññeœJýEÅŸ½Å=öG”“OÜvØOó_0žpùsÀ°sì À=p¿íåÜûÀA°‰OÞ0~Y½ŽÍž¶3´GO¼&>¾á¿|œ°°ÿÚw¨:ikS}*m©Áå×0`�õ=t<`8pƒñ/øùÇž 7ÿ#røD9ŸÊDÎÇÒ¡ò·Žcï£x+Ê{ìk·ÇÈÓSÃl¸«¸Ï§ÖpûVsŽóëSôì~ÝýS¼"ïj7^üé’ØçDÒŸêe«£ŒÙžTÁ;Äþéx›u¼âÉqR<dé^î’Í2ÏQ_øýqÓöæ_šÁÍŠ{e©V ]U÷âäfg”'æA»]– ¬•ûQe ZÀˆd¸r35•ºÕ·¸%Jè ¶H�dAåfž™!›ÃÇôÌ"V®Ä'̘”eFæLvóN*¥bòê6ÚEŽË\%²„ͤÏ©ŸˆÉˆ™Q4K' ênÚ6¶Â¶ymë듘PH¹ú�CrÁ!À‹ùrÚX! T˜¾* ’ä€-%Zçßâz „ˆ„ ‘‘W©r^JëÅœ©T‚9W–&I(ds¹p"F„E^§Õ!ÚeÌ·—·Ëk´¨ÍÐÈÍ`&Zaz‘X¿™˜“9i s• dWÜlˆ×O$‰ÀXž2$22Wô3ÍX\Å‘Lš8#LSfEÆ4+€XP ZˆZ…3¥%1é² ‡ÓIÌs’@‚¦ Ì®>3¹\¢«Y5I_˜×Í]È(B‹“½Œk‘34Vç?kC ‰hŽæVÜ ×(*ü¿öM<*¶ÔNXÙ+»¦Ë”¶SñÍçŒ%R¦Ã¡uûXpÆ«;ݸjô¦«\Uf¹”æ¶ž‚3§¹ÄˆÝgÔŒ4À(ËuC�á„€Åæ ËièÆ SÌõB1Eþª[ØlƒZqô—3oj¬\ቴ]‚bªEÙ§¼¦éB¼0?Yî1º¥‡;#[C8.>ý —·Û^7 ëOÞ?pÞ«¿Û¿‡ˆúƒêÅñwoóxm(†­<Y½NŽ·ýSÃüpoª˜éOi }`Þ“»—#+æ¨6O|™Ø?#ž`¿Ååk𠔎¢#Ps¶Ã[{~†õZóØìÔ~xô÷h_g9µ �ó½Àü=þâï¯__ú5ì— ŽºœvÂ4ôrd=Ùš ø-xVô†! ^ˆlàÛò”¾ÄÜÁ+êjr¿BB8Ly(Ê|uÞnz«£à4ð±âûНòÑ j;¾ûî䯰Dûö€G gœÒ`Ä­À‰ÄªØxŒÛS¥¢4È:N³àLìöO°½×À4«vµ¹÷ˆ:º¡Y óæ…Å]i°pë ø÷–Åê?…ý4QIÍr yAÒf¦;,­ÐjšWgµ5ªG‘Ö9Y™´ÕfàJ±ÎÐ6Š%QÀ� É1™`„.=Ë�¦›+m%, ‰³,3 8ñ¨ÔXoBÅ¥\ð¶—[ fîdÝHåt_œNqDGNf(;ÒXÌ€õØ4÷b,T59ˆ”2y]]+¡©ëAhר#È€B9•±ªœ†‰u—BÕ5Ù’1'#ƒÓK.ËÌ‘ž¬–}Ž×—þvAª¥íÍ6Zãõv£ƒœÈœÊHiÂDŸ‹B$` Hp]fjÿXæjGA™‰9$Ò-i´J¯�•¡¢Œaæ,ÅØÜ̈ŒÈÌ`Ä!ZºY)´Ýš�­"˜P çâµæÙ¢Š`&cæ9#à-áfQJZ¦+ŠÖ¾j­²™W„ €P¦2bæœ9¦Í´µfBê èmÞŠ¹9  c¦hÅ‹`yU$]ÑŸ?aA ~­¼˜‰^lNedäâŒðj–[’j$ÅåéæõÖ¼„@¶ðì´ULº¥È’á‘-£Î(D3º‰d.¤¯¢²^ÊH¤”iiȪ¼an¬uÚöÆ ·FY$LçÁ樢Iné2L+ᨚfé¦7Å+2söÌšaé3ÐFQÔ¡3Ç¥Œ’¯[þ§?™³CídzÈ~o»÷Ú;÷ÁêVžr}qýÕa‰âƒ'+8ñ°«÷®fèz…Û‘y*‡ûVîËn÷ ØÆ™þôÖŸÊï Ê„½Á ô[°øÚöÅ)·óÞv¸ëøíà7'&ìl YNÞ0�œ1;(_üÛ+d»~ þöCÆ=~_¡(ªfeyp=¹=æ ú·(@ù-êÏ1 |$:ñ{ávÿÑœ’íPv(#P!G˜/Ç3êáÒÈJ»—ýv¦=ïí‰+–ñΕ¨x9É`ý�ûV` >ƒýt½@9v�Xñ=AG¯§·„M89¸œ¶ lÂðÝcÙŽf_foý*T1£Ð3Ϻ}te…›–E•v`1×;âLû3ÀÕBrù´OU‘ÍòU^Ý]åRÒ \´y”{ˆ+/“)Mp8Ó˜ÆLX¦Æµ„Œ‹4Ã4¸a7)’N¤LnÝ2s8‚™´ªDOÐ)—ʂ˵’á‰6åb),Ãl‡tMËÁIŒ°ÅÞÒ@b8t-*X±"ÊÊùr˜–±ý×3h “ë&°ø›�l_¶z¶ñ¹?·n’äW-™©H<³¬°è˜Ce_p×5Þb¾ÍèP…Z1÷Ï$§ÅÕ™ŠžùŠ9Cò4!rFÌ™sÀ-É+'4è¹SÒ ³Œ%#WÕÓ®ÿ{浺%‚Ò–¹±XÙ±ì7ßvæU@fÎ1{ Îu‹Ø5´f¥š VF kv&™ë%Ê”™«>šš#é%S%嵘WXYq4¤ñ02S3æc`¦)¸¨‹•ìJ£F"dTú#™–H®~õF®øu¿-؆™¹<!–9 d4^§Š#¯B å¢D]ýt… á\ÌÝk|mmäiZ+,ô¹YO_Km‚)/òõäñqݺÀíšËPT.ðsÁ¥¼ P—„Ú¯¥ÊUÜ91A5fÍ,PG¾EŽð}ç{•°xYž5.>Lý†¯‡rjñÁv?‹6çü•Zãù€Ñ¬”‚I?ÀžƒÇxꉬ0 Ö[’‰“&zËu²Uk™•ÏvGÿo0›—ÖÈŸ¢÷ÃùP~·^†ˆ†yD\ÀŠ|ƒ>A ³<]6D«µÿT`M×_ëD<cûû£ýâ„[ÜÞÀ~ üÆ*¸üÕ=ç}<7>÷ñäWÈwí°ëˆ7ŒDÿ犛¯á;x NìHüÄ!ÍŒ™q9ƒ€*0 3ÆGŒ7¼ÕSØzMð‹î|Rþn?OnW®ØmÁ¥B3ÁíЊËî8îNݱð:>ᎺÑNoâmɱ ” Ïg\âð ¥Â·ì¿=æHÚ´ùÎÞö@ŒÞßþéÕïà?w«¦…$# sÕé·Ä¼Àhðâ>UlÍŠœt&’æ9ŒÞàÉ¥­Ú ˜ži@¬ÅÞ†tf •q1?#’V‰ S Om�—‚Úé×·ÎÔª¹_õò$g0„ÈYSE»¡Ê9̹“iºX",ß0�U†µ.„*’iRér¦#¦b"/¶šmŸí”Pr _®¨Ö¢¤Vq a¹Êµnæ\ñx⚸ æT&˜ Íë£3449äKœ649ÀµÓ•&´ppZÈ€-˜8è 팞S%P$("ÏѦ\ÔsŠ˜ŒC4§5#]3çÊwJt°€Õ¬V/µ®Œhúª¡—­,ÝÐz6DDïP†dVh;øn«¥Ș1zæõÔ¼æ€-k bs0ÂrAꔩõð—Ò“—R¬”jt‘‰P†lq#"W2X6.ŠURŽp1Éb¶bDEЏ‚\˜Dµ B®ùÏÒT¯ï63rå,!OLPkìC!Œ™œb$ó*$ZàÆ¼ZäÖÅV(™Xø)sS+(îæ¥ØÅ- ÔÕÚ½JkžB¤TJΆIQ²dAsç‰VDÕlšt›UczȦÃÈAõ2Т”9K¨L&jÌ-‘ƒ‡qØå؇&Ù1Î#ÈøcµíyßžöõCñ¿$î”6ãm^zÚ«½V(|Äð×Á8¹°3h€:?LÝcTµ‡OŽGùCßznzû]9ox{Þ¢‡c·ïïësÍS™¸ý‚R;¤ iÀÄš¯$1Úã¬ðü_¶Ýÿi÷GðéÛùÈ~BBãƒÿpŸ¨vxØß?Ùá±� è‚ðc–ŠÙ¢´ø®¼ýýŒcድ¸W~<övz½½¾`ʵCWwóÃ…÷Ãë3~äÙðOßawƒÑ&ô=Æ'œ }‹ñÛ'ã—u7‡ðTÇ)tìŽä©tbz,PôaÇûK«Oþð_üé›|ü©Ã; °~0¿Ï­j{0<Ý”Ç9°›vgìšhÄwŸð pƒ–ÈDóçh/3î2sGì²{ ›Oç>Ïù•Ò1<÷Þê°R×…]¥Ê (ÃN¬Š-%颿Bï™ÈÎHN!M9 X.�³á‰Ì匑!¹¤ËÅ(¦BCqÆe°œ¯³ ÔÀúŽß‚ª-œ1VÍVˆ4àn4V”œ©³ò<µ)¤²‡«XŠIBfI—9¡LX· Ì4×—ÂúЄ ™ÂÐ̘–®´™VJT­±A¤VÂ3‘ Á#R®²B¹J‚W³‚rÅÇ"�-úçò¦ÈÄHÅœž²ºª ˜Ê ,Ý#,Lr È !0édC6Ó*+ÕÃbÊ3—ð Áœ€{¹Ò¬]n.C©Œ,³(Ý’bI”Š*+Å}W¬ Pæòêµ”ÖJ«î.%™ n¤À/V«×JS!_{ùXÔŒDиvF‘þ¹øð¹u Rš×“ÙÝ‹J5:ÄJòPà²d×´ ®MyÐ.Š•µãT7¯™BEq+ŸåH…R„9ei,„/z®yz¯÷…Ä縘’ûÊ:­ñ“ °ua“œâ”yÂR"dº‚‘+r„”FØÌ 3¸Õ¶6?4IÔ¤, €Õ– +Ó+ÆÁ9©I­(®_Ne`£ª¥0KÁ3T䥸Œá’‡m¨ŒÝKë±lضi»Wßµ xoœð×ÿ‰ÃýiJûUñ»Ä-7¤½I¼x^ùCò© CЀl`öûˆûÙÚ¥uþ”À†»À;÷ÃØì¼«Ý_.|ñ\ê8Ô§]¯mБkè—Àœ¸íÈ3x�ËÙ=¼Öx¨oOqÿx)z»ûTqz(¿xª¿¾ßþâÇæ?é¸oc¹¦OÕjïÚ#f?Ùo¬õÑ™C_ž>íð²Áþ«Øbs@÷U÷¯l¯óÇ|Ñü‡Ž&ö@½€;Ø/a? ãñ´Ž/8ÝÝaWÀ‰iÐïg«öÕC–§1CØ.h¯ðóýÎï/³åè_$r »Š àr?nîUš¶^ J´ æΟïö9H\„ÿøà«3¾õµÞßXmònòïJGÉ£÷„sAœ_îv·ïcÛÝm7Õv›êV¯Ð|Sšìsv¬#Õ"­’mñõ1•,nÖ¨BÛà•i°ôe¨ÙE[AÍ =ÑsN7¾vÂY/K\œ¢˜„C–0Ì•a“€5]Øù‘ˆ©×®7ឥŠé×~“Õ€=¬HR L™èBŸJ*MP È‘cUt †äâò‚ÅT®„ ”L¬Uhfµ¦TVl*}—lG²¯‡(LejRÉ¥PdŒè—yÞ ­¸«"‰i3š³%ƒY-‡qM «ÈA£«'«l—\¥í "2cø‘6S­x¸%Fƒ©°6"ÒØÂj–ânÕ¯:›1YàžÅãª#Ògk¨2!²¼Â„–¥ ZÛUL&#9AM8ÅV`Îb$ A%Äu²C xÐÓÊçû›Ö(P„»¹PsÌ8Ç|ÍõTeH1ÓBCsVïŠb3‡9éÔdNi*•I˜I2N“/\V)è¾0ݼB¯(×5ÙZÐѺ¶IÀÂl.×ø »b)4Öo¥«ò'8åA©8«W9æŸjž‘E™ç¤óº™"å¦â ¦ë‚'3S·© ÓÈ4„c#»ôæ ô¢ùÑY-o2ª–ÝÔ5iÂ-Ë‹÷¶k>ŒróîÕ>Ê“}‚Ýi3df"fföà¿‡ŽŽ“>ãõÔ+.Ö¬{ûæÑ¿¯°6o›*8«ñH=úcÍ¿Ÿö}WþМÿIÿþ+¿ê'«° TCbEº¯àD?㼇W4¢ò>yßÑ`÷û²aÖŸ½iÿý]û?~Ùêþî—ófßö»V Ü*âãtd 64{*„fel…¥ˆ­ ãâO/·{ ÂÝà�7BæÑ½šeËùcû†ûŸá ø¯ø�|Up?qØÐƒ|úÍéÈ#Tàw°·ûùݽG뵇02a/¨ÿr´—Ê/[eûr`Ûê—ãx÷zÚ vóøªzÎVÙ6ÀQ‹Ž§ó+êÇã¾üµ�[ÅŽøw;|/|oÀ¸7ï/Þ¾d¿ÑÓ¾£Ä±¼žÐ1„¾ÇGÇe>ýä ù|w¸ýz?¿ÜFjWQ‡¯Ws¬aqžñzEx¸™Ý8h¥-/”(%¡¨jíó¼ÞjdQ†i,S`q[oRª4…ˆ˜*3k •4ñÚK5EÑR?²ŸÒeØÌbu­%Ë9s#ÓÞ `K\0M0X­FG6TV¥3œ0“#5…�kƒ´ Ä”æj TÌ€\ŽR×úëŠbfäP^,C(N“%|Ð$S˜WŽ“™üêeP€"¥C=pI¸d›EÐp¥€zu·bÅ|• xrƘÐTs9 7¸­•xuícZY¬ô�¦"2®^š -|ùbÂÂÄD8&1ÑœµZ+Vë’‚qa*R–²4“ýI÷&eÄчé9)¤¹ÄËe‘W– ˆ©èAM:TÉÏ•a35/˵yecµ"l†Ür –‘1gfæ¥ZeA ]úÔ¥_FŽ\µ³yÌœ^f û,ï[Ê ~öò¬Î$¯›hÃzæÃS¹LqiI[d.‹)è$´ü´Ì%•M0Èapƒ�“Ã`,†bŸeqÄç?`q5ï5ÄÒp¯LîTа…ε ÑLlZ™™ÃbÊ ¬#Kè¬ÛJE9›· ËŽt*SiÈ7àRÆÎR´œ5Gܾ¿«[õ÷ŽÂÃvÓ^S[R§ù‚þ‚É“åý-€”]ò9â!°œ2ÀrÂÀlˆ‰-1ï>ž¶çþÐõß¡HÚFé'ûˆ— l˜ †æ¥ÇDüºÿfœþû[ bùy»0$² 8VDmÐ'ÇÈÙb¢ì뼡ÿouÇ]mü›¯ ´óÇ�� �IDATñxþå¬~ nØ·>ˆÓxAOˆh††GMPGŸ§÷;”Àc´ÓGÇwøØp 4Ã3p¸›a>y}ôçÄãÇî í€wÄ¿þï ü¢b;‚¿Ã§ßÀ¿â¥YªÏ¿i¸ÇGÝýqw|øê÷'þ瓵‡þ¾¿ ôþ.Çž§VP?8¹Οz%\½Ù@œFÿ0uÿú®j÷«›Ý?Ö×G¾BŽ÷{üüÿFxÓñ#ëoÔþr¶ŸÚ|߯¯ÚœõõAŸžxó¸Ý;O#ÇÄk?«³iV»¼bS´TÙ5³kt9zȬ kÖ@*=‹%LV€zMuK®%êåø]ç$­0s± ¬Nž%SƧËüÄ|Íô´[w `©-Å™%*-+?@l’)SsϜ‹q€!%À™nc�Ãpps+…\ÍñQײQœâL!¶JT‚„�¦£6”²á6M””‘™iZÈy.ãÐ@Ìþ‚Fb08‰%ˆ0K †‘Ôœk;-ÍŒ‰1,giK¯\aÉ\…¿bt·]-Íb†Ù@d$lÝ( Y+KHÓt†3h—aÁJkб"’rzB9s@Sd”êµ²U«\|ê…Ò–pq)׿ ƒ3gÇèÐ(© 92ú9PaÈåžËÈEæ Nêbt3ó’VQ –Ó±ºä{ RE¹Ø€1ž4"2Rs`ÊTÝ ‹Ã0ÎLÆœ™Îdª,{uw3GL3V�º>«à„-ª-%ÖoÁaöcÉ•K[ˆÅkfÙ°€K [r\í «‹mÆ+Ïeq|×È Œ’1G*àäŽH¯A`æ ÆŸ® ME8²õ´ ùF»X6Äa-½»Õ!¿ ø(›Äzƒ²yiDcDq¾D°Ä¼Ò†ªef˜ËÞ_kK«P3ü ;«žK9W" ‰c9OVo’ѽ†]º ;VÒàrCã±îN_¯{a_ÐðdßÜôæ¹C±ÌÊÇ‹ãÍN°otçÊçñú.~Àóé›3²¡ïÆSΚ@Â&¸ÁKpC²¡Û)ôð:ú'í·ðŸì·ýaz-»›y¨ñÿFǯû¿þ îúçs|¥'Od¢ºá¸t¸0¾?-Ån¶Ó%ACOü‡_¾0|]P¯\>"Î(—§) Ô Ç<ö»ÄVð¿Nüö Y ß¡ ”÷Øþ[ð¯`(§’¾ïó늬Eïüò×/çp|_?/Ÿì=Ê¡¾ocÃS=£&ü í`zº{C¹Ôö2Š=MaÌûyûgu¿ÿ]Ém¿GûþÑßãæ€ýÏ:íóá]éw†]ö-}Ûö5›³GÜxþªrÞåÃOu<fAdÄ�^ÂÞÆ¬äAÛÙ¶õ¾á-?EdÁîÚÓ›y…@©j* ͬйæ¦é˜Ð”ò GX×c73Cærê0L92 —>9Î6éå ÛS—D‹È®&Òâë(ÿ�PªDP¹w&˜Ô`¬¦¤¦Íð2LÅXà…žôtÀ"—²,—ÏE\qÄòD2§ed–T¤Ùu"©HL(ÍÖôÙW†¾ÝËܬ¤L ¼ÎKɼs¹~W[rÆ”.,fµ•U²ŒiEHšÕÂZ½¹QŒ.ç4Ûr™àH(“#戙 ¥0¨ŽÕ¶¾¢Ã ©d`d†0g Q@iY+v­4§¯±›…RHƒ\( Ã:¨–I3sÍ ²ÛUD·ŽÐ‘Yt*a dØÌèD8ÝYlmc¶çœÚL•l„­¢Ô-4lŠ€Ó§7ºÜ)_;ž­h–Ú]d)¹»XÈ1 ¯¨@®8qëÊUW£ÅëúÊ)×”²"X¦ˆ‰%ûcB.æ.©É´6×v×}Fƒ|–Jñ j]ƒ»e0UdΚXÌö«Œ¾îg‹8EÍD¿~óÃIÒ’¶¦XB–4†Dù”u3s…2¿1oå ÄÈKµ²A~§YšgµùÞw›¾l(´6ªŸàbyÆì·¯»ë–³b{˜/O^^p¸EÍnwáÉñó¡äÿOØûüH–dWzçÜkfÏÝ#"»ª§§Š?Ð$ÄQA"@@ Ç Ah%Í*µ,p#ê_ÓrZ Ñ Z[!¾#ЋÞÍ€€ºH±º:ª23"Üß3»÷ha^ÜÖ*J *22ý™½{Ïù>ÿ¡à­Þùû‚ÇþŸnñë²<(ßo[\÷¾�Þ‚‡Ç:0Ƨ/£z~|ܵwíüE¼—xÿÏãa·b×AGéˆ Ç¡ÓÚpèç|üÎÞ|ìçÏãöYpñªêh<µ;#ñòðÛ €cùÙé©á³‚ÝmÅ>°9.gpÀ å[ì^c†/l®àËévÁ«‚’HC<ýh‡‡–ßÞÿTN©$ZbxîˆdÅÍ-^M%NEÿ؈ ì|<–†òï=ÊÎÚÁ¹ÿ¨°p{‹ýáïÇk¼©Ç×vªæ/'6°Àñ`å÷Güþ4€~ä¡òÏ÷K9¼møWàûâ—88è˜cË…"öº;`ÔÒŒ{•–¨jw‰"ÏÛ<ßm(f'Äçc{¥m1Eg·­ç+;7æÊþ²Û¶ÌµBû´¦ÖT‹rÌN¥9›‰˜+Vrå!Ù¬6Cˆà eÖ²–½Œ´·Â'f7î`HVEïÊ‘p†Û¤eTïèàq±xƒ,€y­²[ñ%3S˜»n£ù&†2sˆ8$%¥QQÀ&šZ˜œ—Ë�Š+óGŽÛD.L&·‘pZ›b$:1QÓ:s`bÐÌ,Ò‚1ë­¡‘2¹‡—¤‰ºfÁˆa. Y@ƒ¥ÀôPë©¡Ír¦nFŽ‘´Ô¼ o‹ùp{räï+%æÂbrM•]ò°bc-¾4¯Í«+27YÏè¹¥.R÷œ¢h‰’ =r²ŸÆ"’ýãç$©`†2,1%U™óéð4&M(4síˆjbŽ¡¾Æ½§lZ;2-FIÍ ã캹–ÝNUC ØcDô1¢¾ÂäiîN›‰×>%­nt³RÜŠ“žš4I×$¬ ©01#29Û-9#b†«Ë¢@…áÊ!0ͧ€`À$q…×B@R¹1Mr™Ë‘E¹)eBváLuP€‰f2y: mQš‰ 7’˜eöÈp–Ú‰`ñ‰˜Š R ØÖò¥sy … îfoK[RÅöDË®•Ï>¶ÝÖ«Ýô²l‰MÚ§Te•ŒÅã•и0~f»fÚfø#µ¿Ø¡-¯ÿÓy«"p›ùTK­:ærârypÁâˆõô–ý]~÷¼½S·­ž/ÀÇx>Þô�ïï€ûVë‹Þ›Wó¥|ÜÝÿÓx.ÛîOÚSæÃÁHûPêù8üçx¾ÇŸ}Àï>?ýƆ÷åxЩT�z…WÄÀë×ÀœáÄÖ0ô.¿»ÿj©¿8¼ÿÙëÇ››‡ÂfÔD1øË©ÝýÔ¾!_ྡ?¡^P^a×áD!zÇù—Û£nN›¡”|È8bg»4Ëò Ž7:ìvŸÚí±•Ó®ž½+ùEjxyïõ74”—›Sþüð»“ÿÍ×·Ã"€}Ø’c8ÞØiè>U–X€}dz™±l£Ü—¥×‚‚PUMGÅ)zn¸ø¸Ø¶�©\Å7ÛZY¢³´íû¦b)˜C;¨±Ù¤Ü8 YŠJ™# …4[(¡n¡!ÒäFf$Íô«™S¤VnFÖÌ’è}´ÈŽÜܬFFÔЛ(/@o*‚hæŽ2f»$£ŒéÏ!ü*ЧÌYÁB²™(ôÁ”¥ ]ª9'Íæ ¦0FYlŠÄ’4 ³sQˆB«é²1r*Ü¢«`d¥¦òSœþxf"3¥ ¥Ùd‘škØâ^'©–‚A5*Y‰€RRfÆÈ›€ÒDfn™ç€¥,h‘è%qM°NreÆ@n12œI(àÁ%Ptóf…¥y­¥¶V–Z÷&xŒ±n—µkëÑ3Ǽ1—+¦;36E—A¸4+NÚLúÂ$dRaŒ°`å…Q2ÊÒèVÒ*æîò¢f*SV;hʈìYÛF23á,4úTE‰ó «,ð2y£!Û†6 ÆØ™›kJÕ R™#"’d5Àé0¸Óan`èÇ‚œlz¥§èG¨"3…Pˆ6ÿ»»è˜çú˜nØ& Éðí ð€H$Ì †¡$*8q^MÉd‘S‚S.6ƒæÍÙ€Q®Ê.ˆ¨æ½ÕaتS¥Ê³<ÓÝÃ/ѲÝ1_RwÔ­£íÝKx–¶Á_ €ß{|´hô·\–,{4Fb¤™íòêHW¯I£ö<„56ª 9¹«»beU>êÌ(wÙ›ŒÙ»ÿ«À LBê8¹`Bô/wQo× X¾>Œ¯_c´õ}ùðÈ/ïy¹G¶Åã>õ©·»£Ý'>ϛݞsçö¡úãÝü—øϧòÝWyV};¾®åà! Þ:¾òâ.+;¢oèãþóqó©ÝüÙvÚ@"0þ Œ/àŠåù§Î†m®‚¶ŽŽû‰K™ðý»ËÍýoë¿ìÞÿY<~²ÛÀvòòy šjɨ[ìôr[z㉆–ï4þBÛ]\ª÷'`Í‘À¸Åø ü À;KóuÄ˸eú8ïÏåærª·`Ç&tCߣÄ}ãýb­öšËÚñØq7,¶Û:Íû5]ÅË)¿Z·÷Ú¬®lÚyvç,»K²é¥äGécäm޼¬ÅÆ­² îcKÑÎQ 4&‰>Cꩨœ`ϦÙÓl·mf׺Œ¢Y%Ó“}$}K ‹ºeó€aIƒe‚fn‡¡]Q“Á  •HJÞ³&À*œ^¦sE VÂç—#,hsS<õoçHø| ²”A¸~Ô¤rc*á0 “ )3%Û„Èéd=ay}¯D'ÂM,NLP_a)ÕáV͘•¡ æÏ­�l(Fva ƒ)DWqIiØ2TeTr¤˜ŠÁ 6˜èч3Á÷t¥fÆBC1«dñRJ)K«‡Z‡ËÇ*¾l—çuÌÑ“9JŠ´žìJ 4wÁ¦HyÞ¥Mb¤å5îi%“43L~¬ (œVÜZ1ó X°Lws*€«à‚˜ŠˆT2V·VXͦwivÜÊŒ E’9¯0&0†epM*X¡i‘ë)ç@î ¯(ìçº"j™€‚˜Õ #“ÓÞ#)c2#GÒQ�›=6CºÒ‘ÐTA` Ä”˜ÐçU"Æô|ÚÈITÇ´ïY5™Ôcڦ΃ѥb$aá–(§,=€_ßU½ ØÊaÙÕS#h¥¤-Ëâ~SBC<dÙÉvÕGªž“=}“}ŠüCðÅ¿õßfcÄ~È»‘Yë¶ö¶ìÂiÚJÈ. ™nÝÜL®XÂR-%²Hwm½ÝukaÍ/è/µ´£ãÄ@Ä€<Qxô2ro—1åYéÚß7¿9´ævoBÏ=[öFºmKæˆ[ÙçŠClËøÄíy<ýzóc–“ÔŠ4tÇ«Ž¯.÷¿Å¿ûï|¦çx}à@ß5|ø¼â‹ ýŒòt¼éuÙ·Ýg{œÕâý¤@:. ™�õÝþéþ'ΆïËø„s wx^š‰§ŸÝŸ_ßÿßû†²aÒ�K€ã‘Wl›÷-r|H<"a+:¾ðííwZÉQ¬ž=ލ'ÛÁ T0�ývK*ÇeÝ=÷Ö·]iíî=ì1ð‰sÏVW³Ø‹%ÖOݾ}Æ·Òçpöì™ø”øf67‡ã1ò×Høæ¼ô,?0køwÌoD |qQí[·j’­¨¨9›TÁb?öš�°›yZ‡E² ”Prá0†¥ˆôDæ(9жä9ü¥›­¹\hI/.°9Ì6×%XÓnv„[1Z5µ´b– QbŽ Gæ¤å°¦¹à²"Ë+Óæ°ÊtZäuãè1U]JQ¼ Ò …&s:gº}î.}"[¯`¤ÙŠ“À+9‚}À2 )F("\1\k-£¸«¢‰Ñ ƒ yq”©“SH6ˈ1½‘WxzÏUò:aÖŽÁ€"ÝúPf ¸®O²òˆ­cùm©�™”Ó²¸Â6yšÉ-}z8ff^Ì ]’Ì»¹Ïènuo­ÔfWî]EvL”iº•9 ±°é "5{Ên¢a.‰æñ s–j­ÖÚª—šp&‡®esÒ&Ç0©9•*QB’1óý©ä5 5ÿÊ•Ù8FI›]Ïd$С‘ÔÈäPÌõÙ¤eøô“z 3—;kí1‘zׂB(5ÛìêPBVÂô®\$Ì‚ƒ‚J³œ¥tiôúŠ> ë^V&ŠAZå]*ÔÍ ½Ðž²ðK14±æóàÕvna3k¨u+¥¨ù"Û ›åj!ààFC°®âsâœTÇyœ¯­¼‰ºSì{ÖsvˆKc-¹ƒÕnŠè–Ñ­l(»lŽðœïA`¦mëÆò²»Àï8˜Åb8þ{¶Ï½=ö|Øâ¸Æi—€NïçQ°2_|=,ç[ì÷vpßgœ/ØÅŠÔJ…±†Éμë¹ÚÜúeüzÝ¡·ÓfhD3tCÜa#>þþX¾­s³¿‡ûoÑþG¨}b'|&¼ºàcÅÏ ‡Žö„v9 Ûoj{e}_³´ NU‰sÃ¥�@YA»×o~êløà« øGüÀ_ão.×Nüñ‰õŸjCÝ£�¬k]']ÀËCøÃÑú‰¯OvÂ�V,<FŒŽÊ­tÚ«Ö•ûS 9YçDãq+µïZŠã|q·úÏ5?kcï¨H½{Éû—¬çµïù*b?ÆÎJÛìžÖ}iïê‚ÆšQÖË7½<X�vx>$Ý×[:Øêyg0-=êÞʽüï (¿~æ¾Çg/Ó°VŠŠÁÌ'­ LÌkö”0v&³ë¹Sά Ë:멌Ðô•Ñ-Ÿƒ1Xíì»tÛ)[r gÍØU÷ƒ¶3Ÿ±œ)žï!Y&ºLæaNiblÄLT•àf^œbþÎ`’i‚ sCºî )äUÝ 0fªÓ&‡óŠ†Öˆ a$¬:\= Œ¹u9€Tót�æÆbfp3MyP_ ˆLeNÓ‹ Æ–‰ŒäŒäF»"ö4âîÒ""Õ &-ƒE´[™†Jƒ¥¹¹Ó1±·?¢¿éaê–ógR0FÆˆáæ #cD I,î»Òvµz±T®aÅ= ЉŸ®,.3'Ó‘k€L¯9g4„ŽRK)楔ÒX*aÄ|âÍÜ™(ZþØ6SâºTJ*GFL󞔚¾ƒÛÈ+8#eŠJîÝ**4“9æÈ(h¯´z΀Íè3âœH‘¸–µ³çµÓÆŒÌ1Q´+²ÁŠ‚èᜪ(0uµÀ¦9§|zô-úeŒ-·˜Éà¨/pdéâH™¸d&’4º[s«æóÝ{XŒÄÈIbc ó«5ÈÈ„©šU8Tƒ!-hfW½ŽÎ©ïBºà÷Ýÿ謶2øŽHîU¼«þÂtË´ñ bBW\>•§ï’7,¯-oå–á£HÀY[ô|yºú½7í<c@·^?UŸë|#½q׷ϩǺ{P>Ž‚1êjEüf+÷„ÃöÖ½û¾¿œÏçÍžÿ ¸ãSÃkÔ,ÏÛ>>-=ñÈÏÐ÷xÙÐ:Ê ´a,x:àƒðÃùô¦}ýåÈ·+no±¼X?ŒÌã§ñŒeÃ]GÊ@íàoÀ#v 6ÃpÄDu¯ØC)Xm­Bû‰³áo ~Hüf"œ>ààöc îN«ýT!û*ê›Ñ^ÇI:úåä oQ·Ó-ðXOÿõ3ü¥Ã^ œ¸~½–þRÆA|ö±úyÉãÀ©9è(É“ùûO»í@¦›ìþ'žlÛ XªôEäÞÕÞŒm¿UßJ²]¾ä~÷ö„²<, ‹cäélØx”v‰š¨ÄrsÌ6†5nû²™§Û(X€}ŽàÉòy/êÁšÛ:Üe¨«Öâ`Â8÷”`8åò’Ö‡E*ç×é…Å„¥zLZ]'Æ÷b!iwc)dº€†Ù™µºÁ4çêä&PŒ³ôB Ø^e`Šæ(É3,‘È®mhldÓ”4Ê0¡O¼2mƒuƒAmŠurv¤ù½ãZŒå•|bs$ÂÌH¨g "ÇÌ?’!$rd‡DC EÀšDh΋h^‰H ´)‘£h ÄœFúÝÀº3ºf«šs]êò˜èÀDbDpkÒmÔÜœ=e“õÍˬ9ÍWZ–@q KC„ú6ÎHet‡!bÛ.ç\WÏtkÕJ¥Zˆï¾÷šI7Îk­ÌÍHLé&B"•C² eLS [)´b¤ƒNTÁ&ÐÙ5» šÃn])·´™ýÊж…aõ‘$5ëÖ##ú6b$•,JG“¡…9XÜ Ìé6*;¥˜WC…ŠXÄ2qx¸GPÏ9"cÎ~B‰Ì‘è9ÿò06°HÔtq[¥(Ÿf¼@f2@C2£÷µ÷mäÚ¡ˆ1 89kõ* ¥é wv+î…n0XÌ„LÉLNgªR0£W³ê™bdn"æËqEIg*ÜU`åP×›n¾²^8½ëûšQŒB0Îûø8ºùy‰ó&\b‰^rŒÍFh|Wú¯Ü¿¦6Øëa.…ðÁâ‘ëVŸ~½?¼WÞ{ÈÐa© ¨¯|?Ý•YKYß°Ýl¢=táÒŽgœhã]¶½F ì1¨ï€ßÊß=Û—ÿjíÞq‡ÛOÞ­ ü씣àeo þ¸a'ºãÙñ†¯XôÍÝe¸Áþ“•8ó¹_–“ÄÍ·P PÁxƨǣ¿Þ°t÷’£‹›åÑóä@«xq€ÅN¶¼OüT¿á~�ýÊöð›=ÞÜâ&ÞYÜ·—×e÷f³Wm[bg—÷~©Ô{|›üo¿ª@ù%Þ|¼Æ³cOä÷Àï¿É·û²ò:âéÂÝOC87øqÀl <þW¯(ýËvsɯÊVkYÆhû—¶Œ² øÊØó‰\݆îRÇC?ÀqRyÇÛû–ºØ{àq­ ÔS.ï[–¨&pëݶ^;òe3Ë@Rcà£dI áÚRdÑ0ì4«´…­Y­„!’!ót]œfi¼Qx°¥ïM­y³fÃLÑdÞ[ªÖh†xžRR`î0=>¯E†˜¼éÑå:ˆ•(48ËôÔ§˜éR1똋V¦ÿ¸P�ѯWÔë@´ÌX1!‡©1°õ±"ŒŠi¸DáõUjЏ‘>;d>‰l³U|•…æt±®²CJΨ…‚_=«Af"‡R¨tÀÉ«u™ ‚îR*×i3½[Ó,©D€"s™Fjo¤LRäÀ8_z!ŠR[ô û:Iw”쪺UÉbS.à ÃUÕI&¸*5Fäèd·2à9¥OÕÀæÞªŒ@‚¢åÜ'À®–ΜŽ¦fíÎÉ¢âCÀ1Ò4Œ9çÊH%”̉@µân…EVÍ Ý‰yLD6˜W›°Çô°Y¸››žìkŽËèëØr\(ÒªT2‰A‹¼ÂYÈ„gRi˜Uæ Ûøq¹5ó ©Dô>¶1¶ ÃàDªo`Ñ•Îad5¯¢2‹Hý(+ºÆ£h4À#ÌÓÈ6ãx4§W„€b"Al9º¥Y–ˆ’ÎncK¸O,í’¥(ó£èÉôn™çèÿÙÎïâù^ñ‰ø£Ì²5_À8œüŒry&ÎZÂèô?Z>ÈŽm{m£ÈðÁ­Üxž=£X1+,…oöU[PGø©œ§›ÀE8ë¡0¿^bëç6b»´Î¿þ5ë»å-°o�Gç rÃyàc}·o÷9*ð|”3N_Ýàxë¶‚¾@µÞùØW¼t,Àþãë >& °Û^íÞOFlŶ¢Û8Ùö^íÑ`å_þ¤/ú{,ðð[�¯ñÕ=^pÀ}{ùy}Ümò›X{-ý<ØVÂ^_ˆ÷Âc{ýðú¹GbjaãÁ¾ÇÝÓ¸V{»}Ü 0¸0 ØÞE¹GÔ—ì¿Ðú/úÕ?仯ìþ5ÙÆGúý>¶jhcóO�¸{9àìʧ};EG?~¿Ù½{˲aC)(D G¦ÚÐ0m‹ÑÇË#Ê;ã}Ñ¿§^1ZuѦH®(H›Öuwtd¤©dfDbKFq«,Þf:Ô" B€5£Ü8”¨ÆÖÌ ec8Ò}ÀÒZ·4Éwô*VZH#ã袼UÞ2÷`û·k'J ä™Ô°p Áhæ5'+Z2P�kÀ ಒÆÜ15/I$d…¥M=[^™XsèÂLW˜uób¶£‚ò Aª2O*ƒp#ÍeF%g9â:.Ÿ•ï˜ß¥€ ©çu´eH·Â4_ ™°¸¥rDŽb£b¸™{œ‘#X4bÕ˜pô´ùÈèn£X6 C"ÀNŽ£ •àF¬p¦>O!C�H-YlxÎSÁ‘2%=·.[…FºŒ“’T½Ø¤ÞuC0%¨˜:p*#˜pá2Ì—žy÷ß2Ù £kálšÁ`�SWµÍ‡­WÑé×÷Îá`¸“>R E߯¶öíyôuôu»Œu-9Ý?ž°‘IsÉ‘eš×Li5æ(É›8°k±áº¯È@d …,aR6:s“0¼ÌH®¹Ã!˜"1ƈË6”Ì9õ 4º»™SQ”UG5˜Ùa] ØÐr³ìfBŒ4bæ’Øyk&wÈ™Õw5^ÈçÈOÂ#ˆáºy—úyî¹_x6.ÕÞ¡ÝãRmô°ï™¿’×åä,'ÇÈÍé �bHQî`�� �IDAT—¶eãØ¢¸ag¥¹¤l;\þ”^¸{8�XÀx9ú‚ß ÜÛm{þìûro‡û›][wõ\Aa+`Áyƒ·{”û´6÷—õSmïÿØow·BÃC_°úÑúéB< Û–üÊú$Ý}B^|lˆºª=®LôŽx&zA.Ø}ö€üÉœÒ?b~ |õWøí ~[ñ—í訥æúˆ@opõ(•c2¯_�ÿ´#íÇæè·Ø}†åñ¡\°ëGûì´HÃ0�Ø÷ØîGo»m{ÅÇó ¬¿}ÁÿêÇCžÊ%ß)í._>å ·¶~Âå)ñM{y[¾W¿ÛôùÒwkÔÈÖÕn€=+¶#ì„g(HØvÌ—Œ~Üxêûßúø ¼3ÛyñTò9sD/}-/S[i1,Ï‘/HDÀ^È¥ðÖdÒ†—¨rážD02»ªËD%bÓ, n©ÞbM,%§ù²C…¸$ôÚu06'y•üdJ OX£ ÷ iËÈÈx!ª)‚¡*}Ò¡)5É”%P¦Ú~Ö%™B)mžÆ0:y-ÄM+‰:K&ÎâîΊbQr$"]óÝŠ!*®™MO›`ì *™Q2ŒMz¶0eÊ‘™éØ2DÀâ‚RYܦÅáàNÐHKÑgSÍF Ø H…ð CZ‹N…P-Ã] 3Þ�‚«Y’™Ì´”eΜ°¨ôùåX™'MiÒÌ¡¸j”Ì©D/n•(cd¨ƒ¤Y‘©"RsteÅÍa”¹¦þUc¶)Ù ÔÅ83ÒçÌÙºè0¿þHpM4a>QYÌsÐ99À™¡Hõëy\Îc=±öÞ×—1F#Ý&Ñ Å€êIÐÍY ¹�žô 8¹�˜‡¾A1Ų”ÅÌS ™’Èy9™`Æ’YJµb´¹ÁQRŒˆ¸l›sÔVÝÝÝÉ -*C-”59É"0È$GaМNëè¼ÎüÖBZY¶ Û6ÿ±˜¤/ –‹øQúÃЯ»_*d@Ü»½æØ/›aìæ_ŒZbmâ–Ûc¼ v'/„¡ù‘�ˆ- ò2¨ð‘KØl…iJGÝ;ï+ÁñÎÎÜûáÆk±fÿo¼±;=^°çq_j³ælîÕÀQyꚎ¯³f´š-ÎþᲜ÷‡;{¹sÜ9¡^ò¤àgC)¨ätÜ8v»ååÁ 4Žeœ¶#VàùŒóŠ_·#ìô¿9ì€vÿSgÃ#`¿Äß¼ÆRñ³†0¦¶³o1Î=!\<_üfôÛ¢ÞzµÆòúuϯ7 ÷çþø ðÖqx‹Ý÷Xö'k¨ !±/õˆ^_jÛ­ípšãøŸþõ¤ ?»;Ý-XÆì|‚8cüîùÙ¹ìŽèx»?±þí'»~¸ ®/£~êû±%·]vŠ£#V4aŒ“?wèËiÈ#ÇyÚG«0:Ó/é8Ç“—…[$ î…-4˜fi-~.4r.I„ÍJP)¸Ý£Y7Ï\ªÃ-aC2cIzÏ1z^º*fµ\ù© &\¼u[èÅd¦ %²”¤†{ºµRUp}€ ˜¤%$¢‡]bŒ0‘asóĨ²:mi”>]™9*3ò˜é¡’(¢h. ²Y)�Íf+X@€A‹ÓÝܯù&y5æÉì%…­¨€DKp�=Õ Ì¼JÑŠÁŒ0âß #ón›Á.Q …ÄDa’±d†2‹†‰”YÉ$0«7%I ,€OÈ ,¦ðRIå$ƒW"eIòš¯rÖ‰g+Äô[”«˜‡{bªÒ&Ò#sÌæÍfâ+Â#<#Lt91çU–ü‘ãǤÂ…,L$B TˆBº¹[]fW4r6÷8ÑI³³n³k@™12·-¶Kl«¶TLlºõóõð1h²ÒX†³>Ës^ÖEh¾@cÞ7Ê+Ë]„…é&x†´ „ÖÔ6ÆèØ*‰&o6ß«J�½«¯£k¨ÄBÎOQÚèîaÖ Ò&DeŒT€ÝM°€UÈ¡AÖ`b‰¨elXKõ^b*¡ ô<ø”þ¢|êüß_Ft~Ïæµr¿øaò¤CpëÜœi…~Aö:÷—Û‚(cĉÛçJGÇ4ßÊÑ`_«¯Žc¸©Vèh:•qß^>¯ÛíάÞÜ ¶ÍÿÏ ŽßëôF_›m»Äþ²Éú§ñt\ò¤õ¤»÷À6¼¼T®´2Ô¼PoòXqÊÄÖ±^€~}:î?œòOð¢«)jgØêáh<‰Ð8•€M1Ê»—íÏË×ÿ߀ÿËþ§Î�‡ÏѸ)�qéÈg�ñŒþí§|ÝŸGîñ«ß¡ßçS‰nÏìðºÆ[ŒÅ±µ>¶‘ø„ÿ˜@ÀðSU1„È‚‹ŸžôžcCÀŸ·{^Nù úG,ÿ3ø‚¾‡ù}è^Þ,«ÿ½aÁéB¯Çm9¬vV”[E[í—ÅŸXM,è+bCî°=£ ¥/¨XtX7¸knEƨ7ácÛ»{Æ —;QÌ,¹s®‘®!Ί¥ø’^DO+.¯J˜1‹w!GñHZ(L!h ©Œb’º›Ñb°„<¨N¢Zã}S0„F„WH* ]aê�I¢Èl¤À0LF¤Ø§}ž¬2ÊÆàKÒIºšÁ§ìß⑼¶¢˜2ФÌŒ¾(c˜:«Ádœ“ÝÍJÝì=_¥a³µEl30Ä€…×á VÒ]´HŸzéÒ€:ä XAçuQ?ÊdL9ÓžÈ@!5ÜHdÊl…Ú_Ôð1p‡Š‘)8T®g+¼&1M�QE7:h“C§HE÷ÈœKt¦ÌÓdJ(”çä>ÌE&4÷ïfl´½Ùb4Ê1¿–@K7Tq¥+Ú|‚ê(MɳºÓ¬‘U`FäŒûÂŒp³9×vÃÄ»JWÜûµC™]ÍRÆ ¸Ê «"˜sïá†4Ëb¨#s°DRæm&s 3ó9Ôr€d1,’¼rÆ€!dnN«ÅÈ0Ǻ*“[g9zD¿ªZâEKµB2 ­Cêg‡(±Ó¼—šè‘³D"æ°KnEë‚ »nÀà%Ó½ÒS ½Î•E°ÈsàcÄ·ÿS¯2Ä|YòŸÏ¦G£jz¹øþR;üœýbþ$Ûòc·~òÞ,Ȇ †`ù˜S"lû¦ºE¤[þñMÅŸÚ¶ÇÚÚØÂ»çIãç;~·+O{~Y¸+]:ãï^lû§(éÿ£ÐÇ’gë0Øò}|¨ƒï¡Gí³aõOq¸{…¶ Õ¶šãd‰¼ Ýë(¹Ýþ±&Þçíc¼yøÇçËxgyO«±zdÈ uÀ úËå>¿ÿwh{Ü$Ú ~âløùù¾Ã®Â;D‡?>à7 ŽÛ/O7 J¢ÙCùºý»õ7V¾l£ºí³ >µÃ :ê×ÏÇ}{Z úÀËÀ×-¦o;ØéÚ÷ÕÑõáqé8,XŽh¯á7P=v«^Kó†ŠZþÛ1¾D[NÏ;ø‚×0K_Âv•å>X'ÔåÛÄ©Tä+`ÃÈ#oOÀ†a Ãu¤ŸÿKÛo]¥»i-}ñôtãÁs?úbÅ P —´4)nIö JÁAº[aÒhé…DÀ‚Õ“F#á²dº®†Pµ•>œaꙆ(]¾À1 ^œ4iøb*©1$¦ æ*g¢EÕt}VÅd`ˆ[(R Ú1wWzg?ö¹HÂ<ÓŒŽ­¹hv ¦Þ§˜¹Ñ'mÈgî=T›v<äLºrtŽˆ4$,™ËÊ\/ÏÊ•‡eTå’±ilP¨lvPØ;+þˆ¨Ð@Ÿ[(Œ)ët&#H ÉKÎa·u/iw‡ØDe³‘e°Y1‡Y:bbRsZ#R0@Á øcÀ ¢ k™Ìap“5Z-ÖèÍÝI &u!§ŒI`N(¶Ô €JÉâ:tp'݈‚Hi…´Yª¡¤„mÊ;ÌÜ|ºßB¢d^ÕÞä|–)i -Cc(&Diô4Raf.kF–ì` u§H-'Šó§fJBÒH­ÒI´šXY˜×âÅéP‰¨K¿¬îºhôTvò Œ:AófÎÂÚ$!¬‰1úŒÖF“WB£32Õ-’i3­Ô÷@%šYQYœ~õ–½8в$c æÖ v'}žÚ…Ô¢VýpàÓ¢, únXË£z/±ïŸv»g«Ÿë݆!¬sÇR<Qí˜8_Wí·hÑ6 ûv"ŠïÛcK·ò˜§~þÓñ”þ›Ä/ÐÓ׬½þgÆ+¥xõ(ãÆæö÷øôžvÏÒ©"íïƒ(Ëqç%ì~5Ô×ñX:r…ÎïúùþÒêw·¥Õ¿Bõ-*Îgì/»¼~µ±l"ŠàÛÕ,ÝxtÕWO·_ÙòÛÀ þ£ÿùbþgÀ^/¨;xŸíG¬¿<é5JÃ~‡"ÔÃ1ÇSþõ’(öæb»hÃm+c‹§¾ÛŸê[G|À0ø2±ð 0yÄÃE ã‡SpÞPÞÀïà;DE”“ô>°½,7ÿ«fþyÔëû›?<Ê^ìòi¼/^€ÝÅ—-ó©“U° Žw,÷ËZ ï³>Žå!Ê»°{YÝÛ{ó‹á÷Ž·È|¤±¹×ò¦ÙM7Å«­Þ^à ÀIŸŠdf2³ô1¼„èÉQ «šáªn¿B$Ì|N <”œa“¥[/ µyÊDÆ0„°–S GBŽt°˜Ua1Ú|ú «åÃ2ðš.L›0 *g‰A6½õƒ™#9Ù‚ô㤴 Ï18e@Úi—”6ªÂhÍ­T#¯fêjšss¹Ïe¦F`Ú2s¦’àIŸŽƒ fmm^Ï' [I®ó1ĄŦî Áü*ˆÖ&m¦nRI"Rˆ,HpXºU—£Tí;½ÒŒe†ƒ˜‘ê “]Ï(¦¥9ÓU(*•=£çˆž€ +Ôˆ’æÃÌ”YX雥HǬM£OP¡M‹æ  š~¿”0U›0SÌ,—8^ŒW'8KBFØœÍÁaÔ$ó4'1™‰>qx‹u¥pdÏ”FF÷> ™44MƒEžJÑQ:Í.U漕”E"Ôøÿ{ŸɲäJï3»×Ý#òG•³ªÙd—(¢!H^4Àc f%€V„vô D/z´ ÁwpÑÚÌMq†]ÍŽª¬Ìˆp÷š-®gÙ³ËU "2üÝûÌÎù> …‰º²f ¤¦`ë` Ñ­y‹F£¤¹5oMôÔuNcýfXXHÆåîñصÑr5Fn[Õ\LX©aŸ5 J²„LͰÒĘ“Sw&Ýʦj¥’š¦UQy0}Á<²Ý›½JFfq^ƒÃ'6™ƒ­¼+îØÝp—Ï÷×?´ú[ÇÕqÑ A�vP tFÁ¶Ì:î[{ÆØì‰ïíÚN¾Ñ¡Ä&äË?úã[ü*Ò§„KÅÇôÏØÛ]Üm›°»1>jûC›yŸ<¨'Tsümõ_WÙqgØtú4ÏOOÐ úz9Nywwèn2ëÙ æí¤ëù2N—jŽ®»~g4>Ÿøé\±±çŸÜøí¿k¿B}öUßáÍ«¿¸ûc»èÀFüørâžØ DÃü õ““ßÛk @Gæ¹æC¶zÝmjWOý¹ÅõÙcùÚ‚ƺ¥~‰2ð�[Á‹ +d;×gØ:ª£5ܽ†7,Ç¡òÑD³~wÏ»ãŒnsË ÚïÿcÜ?¾`íŠ ö¬|L@D#ÊŽ½Žñr‡zÖ°aÛ;ÜG"êB<'Ÿ^m=v0ý ¹÷º£íš»,ËmÒ2Y‹ö¹ˆ¥3½jZ¸ i^à\JEÑɱ_Â2š-\l–—JÅÌ&›´[�sB0–ê¥j'󚇢¹Œ%C‘L+¢‚ê j¦ïMífŽh!™¸%|²¢¦`R”y’C=ÊQN«O­Xbw.‚Þ ¡ÐkY3ÍÌݬ»…SÆœ‹<eMÍ{Y9õãEu¦'§Xª©z)4¹A¢ Iœëˆ]l½5<ÛŒ…™â&FÖ€•)ZúnЪ²«¬Ò‹¦IÎBÉ+Ey36pgèæSp•ÓÖ‹œ ª2¢ €I-"µVF5“F[0§šµfÕ…æî¾‹Øyë Ó… 9ˆ.¯¤Ãt%–l2Æò¬”þÅ8N-üϲ/,QÖ[WÙ²­q¥’BqMê–‰!‘e•e¼áìÜçâd»›;ÌPÒŠþ%ª4Scd^¯¹Y¥¯õàk£rsO¤\K#ët]³±"à¤%c #9o Ú¬"*¤YÝ<¨e&ÁHÐa-"œ€‡“Tj¦‘*·æÑ­E‰¥‡Hóæi¢Õ”Æ5· ¿z¯hÑÜLL Q5g"ŠC¶ƒƒ óÈÍ0)±ŒÖ¢ÊVýž[Z  ÙÖ Þ¯ÑbrdVKUû´F­pذs÷kØS³Ùò7mÍ•�@¬3`6,Ƥ ÖÞ‡PuR…< g4‚ 4ìí•áðj„º§Ýax{zdæËóöilÏ¿©ñ ÆÞÓÜ×4¬ }0Ïx9Õ÷ç—§“þ-âç­Þö[Û™Ý-fñfÁóH_êïÆu{3‘ÏÛ£ól°4‡ûô¿Æ|…Ù¿Ñ=îâ/öl=ñý3þaâ]À&¾ ì'"ÞͯŽù¶}÷êáØÓß?.ŒíñÒ1^·m?š?úõ}ΓíϵG¼Ãnè P?Åõ ²Ãý$œ­€ QðÀÓ[`>Û£Ö9ß{¡·S½?S¼;ŸkõÃÔÿ÷÷:žøæŒýé6œçÙ6á´Ã[Ëc\½idîþFla½ÍC¤]fÉß™¾½«3Ç)bO*M;“£l •ª¹†ºE&ªŒ*ãÜyEÉÌT3¡52³›�e…IWy‹ZV!¬AwY•iA‡TDJ>Ñ£Òk.+Äœ}Ò ‡• ­Ê× Eª¢aO=«¾­z¼¢öD|ÝÓmaEkc f¨*ö" ¦µ$X{+§Hèë5`%i¸8ýh.º·%a[«HX¹ù®QÙòEg•Pª‰‘¥IÊŠµL£,h[Ó/©™Òšç¤8O\55·Í%Ùar›¼[éÞœÃ"aÖˆÁØI¶'v²0ÜÂLÊZ7Ô*/[SEAò€Åê4ÎF©H$R˜kýB!Ì­1šE ‹&X±Ö èlp0¬RYFë´C†µê¿–éARÖBBÝÌÜ‹|KÔƒ]¬õÈœ#瀻¸¸%Iˆ+\Œ*!«\háÞV%žªÌ%ÔL(•SÛ†ëeäµ´Io¶N£*Þ”ÒJI,9bý7M Á„uxLv-sÍ…¦R)g!¹(çSA³˜RˆâïOZô]¿›ôu‰f¾“ï!l‘îV47sÉ,¥‚¹µ÷ÍMQˆ¡ºÌ‡@XÐÊB€(XC ˆ%%1—~:-ÔàáÉîVSŽÍµ¹}—móbYÈl'˜U²þCîÀîfņP +°A?f,«àm½""» 6a:ì�y®˜kè‡cûó÷Ò¾ÒÔU^%¼x¾PŽ-ë㇗ÿX�¾©ùó ßöÑ|h5N~={aÆ»Ë8þðñíÛ?üßšðÏøºï¾ÚêNÌ»í9>¾Ãæ£áïüå8fŸß!ÿò“o>ø¯u‡ø ´ƒpr¼ ?ì¿ÔûWxþpõ¯¯¯¾ºïSälø¿¾0°ïlàíáx¸;æ¾;6/ä€92qñ÷?8rwúçÝùÏ)\÷H"Ÿ3àö�æy÷n׎×j±=˜ïy –ØêxÜ t¡tÊíD°8Çi†MÀ¼Ûr?æá¼}ÝåÜ^屬½øÃ•Ï|oŠ{¼y{û<bpÒ·í7Â(Ìä0ëž{†5 –h®gëÓ•hŒÆL•Z)§9ƒv-GÓòÒ¬2%à „™…Z±mˆ³Ö­ &Úz¸žÂ.ù܇] ×@í,Ÿ¦ eH0OÕ³Ji=s–]ÁÍéFݛ˅Gé…)hw¥žÕéNºCÆ2$ÊŒNsÁRHM"VµÌá7rÃÚO,²‘ Ý,¼ÌÜÖlG¦2¨™½9bU©œUuµÚBE0Š(l¥Ke®]7Ð üñ„˜b™¯8Þd]W/gí§Pé¬!K ûuW-2ådJXLly7Ýkf¿æoÉÅ<­Ì¡5'&CÀ¼Q¥EÉ¡%¶ñL¨ŠS^° ¢…ÑÂͰœpë¢*½$»qü6iR„{ P¨Á*e!‹™©+؉rʽ¸Tkz‡Lj3•£òZ•ŠUM nÙNBÀ¬%l¥�›Exs9K¨œ#çœ#ÇVs¤®ÀV˜"K™"F¦4Myk $ÂkVÎ"h°0y/îŠFfh˖Σ†0fj€›œ–ÃÓg®Ž*I…ù¾Á édkò£|mWŒ‹u_% F4CZMËt¢Â¢…5³ôaËÌ£ åfÃj¼¹Ä!+;!Îuê€nP„¦™µØik¾!¶ÀÅ·òvA{tî-£f± Ü„—‘Ÿò½»fÇF\„¼À¸*˜þ.âH5ÇCØ£vïW„aNcžØ=NûÖl׃ Ÿ ±½¼˜ý‡§¬ßÔå4ŸÎù ¿Ž¯¶ÿŠù[»ˆsOWŒÇmû§?á¹*p žõÍâ/Ú¸µ{ Nå¹^@ƒêX:>^ú?Øþl†¿¯G´=Š'àl8#~¡Ïݯ‡+/û¯ÿ©óÓ×4§ôþK/úýWøN?ýó¶‹nì¯&üÚ¶íd:ÏĶÇóW…7|×x¬Ö.zØúãö~ïÀý5Áv²~L;jömn׫ãõÄ!Ñ&B8lP mï˜G©Íù îí6 ðXÏ(¶êcóÇq6a ÞòcZ·a¨Â%Fõ¾¶ãHŒ-¯×Óöü…ʵoÀÝ69JzP¶ÄÅÚÜmlF g-4„yÊeªê«&­²ı– =­’a«†«ªJæLÒ%_oÖ­ÐDr%T–YnSÓlšmܻՄ¦À$¼j Ê­ÉjdD9 Æ’¾/ÅL1 š3L ç¿< Afi±˜‹†W%.F­%-×[i´5š¬ŠZehÊš!î0© 9‘#q!®¨±{–e#wÊ*ÁæJ({"Ì\ÔzN‚^ó2£±v@_®�ˆeº ÉtU.f„źôúmÏB.’,’PMdr¨$ÑÍm’¨ò) 7HƒœtѯâæÈ`ï„i§ÔÜR†YšYˆP¸ý¦K¨•ª Z#]‚¸TA «‘sd]½j}ÔL¸ñMs±VË8™y{¸k¦$¶²È] f¶x+%޼­P,;ýÚ6dŽm—ë9”°¢Á'™ÀœÕQ™JG:W¾Œ‹B[ºp É"¤T¬ò™E ˜HQS€¬m6“[‚YÕÖtnNR´@¹+B ›°o]> ¨‡aÕ}Ž6kݱ*œá0ó,Cz¦åKmV µ(3B¬?xMÓ¨fÕYÓ²›7vÊÑI<O|’]h™ûU.Ìœk×<€Ù4?IÛË8m87 ¦£ëÀ 4À0$уGC73˜í]¶Ÿ)ç|ó0üñïÝÎ9¶Úl‹QL—áØl7°ý&íåœÿ„ç0<N ¡á~ÄÝcuT"_Nzjíñn|Ø;v‚&h¸4|[ÀpX?ï »ÕfÕé2Ûdß¡ãmôûõåi~Žc]ZÅ¢fËë>Ÿ÷s»äv}ñ¯êøÍ?Ň?üñ ë¿ ëß쾯æÖž¡¹Íø·çú Ä_ ÷4bçG¯£eŸmCǽÁ ¼G=½ãØõºm{Çþ²ñãÀﶦ»ÓçÃGØwÀu �Çütœu@Þ¥ÇCÅcòýL\Æ{˜~‚Îã€ÎÛvÈü”Þh½UO¢míeþÍÄô(øxif|¹\7^ÏûD¿‚ío+,«aŽâ#Çq^Ž7Ü·l;y³f B©¬e}¶Ž“µ1*Ò¨‘CÉЭ‰Ãm­V•·%+ÖPݾ/O0`FƒCphŠJYuŽ}!ae]-àÍÝî9¯iwõ²7ët¸—9ôË;ªÈ^(b/ô¥dhÈ�ní(™nÏÎ(ËômšÜF ˆåô)±Ò´K•�à¢çÔ·[³—ëÆ´–ß”Y9j\†^&¯…kp«W…Qš†rZKè(˜-gI·660%ŸÈ­[íÀ C(N˜D£X C³Ìhr7ÑA#l“™d¸mþ½j–7Z<�‘Î5Ö¯Ò„üV&¦ˆ„YƒÙd^1¯µÍ1‘Ûœ9«¢£õëÐBÁhJ¯¹†]URâ6XÊBå :K܄ܪ` •KÓ-%uóžŠs2 î–ÉW“@@±h9[%”P Ömš—9¶Qp“9MŠySóLÖ˜Zjm¢¹PR)•QZ;'ˆ$ÝÍÀÎh(Çæb•­Xöœ³pE!³r›·"ó¯¢A‡îeœEU"×c° )Ób¯�¬ò ”¼(rrõ¥ kæ>Å f“Ìõ@' ¤–K¤lÀ%¡Úš¸1ZsSL LC° ô-â@Yq“ªÛ˜Ý7R›WŽ1ÏÏ ;Á °H1Z¤OÐc‡hˆû¢©úV$j¶´¿-ûõ:šÚKö ¹ñ:Ëœ/à6<~ÀÝpTƒOx¡6°¿9’fÃß'àÜ–2)Ñ^·ß?\ÇÝ7ÓÐ6 Pð«/jéµù|ôݽEq�� �IDAT{vŒ:=< ×Ö½ÆgÁÃqüÓ±ÐUÛÓëǾ7ÂÝÏwøø5}}ú¯8�`a3ÞýÇB³¸âõG‹õxý+äl_ÿ„u8`×Sk ÙѺíÑ£'·óœ¨WÇÌ£^º=56Tßr·éÕ Îq½)£Æ·oÁö75šú¸{UêöÚîGÃ,¼LØÄÞÎ-ðÆÑ!x!ý¬x0mÑç6çðß_Zg{Žd!?Öö–ØÚhÿœvN?]ò:Å|›ßâúf~vÀ Ñ(X!$Œò ~¥®a®!î͆ ×¢¨½Í `Î6+SbjÔ"Zhd$b2vîŽ�+óšÁÚ7Á hH*õÝ#vBuÛ<½Ñš5zO393…rÓ¶cÙm‹08ËLÄ:Ä–Ìq5­Pdú(†(×§Ø!hRµ|är‚ŠàÒdfœ„¯ý9 Ë?+sãåZÏW]GZ yÐl¤Ò²J¢d¢—¹9Ì7Åó 'WÛ‚ŠàÁ!€`6ªXReÌ‚)­ B@–Y[,†H&ªl¤Œ4ÁÄ^•Ãl”ÌÕ‰F�™Ì‚ ¤±ÓÌ„0öRÙܡګbæuÙfŽ dKܵ¶Ì€§pPjɵ‘Yès‚n n%g‰Ì%Éd¶ÊkµÎ_À̼ÊÌd¦¢¦ª?HªIɹ>µI%Ê`�’¦fêä�‹¢9 ‘˜2ÕĬ阎\k [(7¶FA&4AͺÕåfe𥹓³[ÁÎÈÀâ§0åÌ,)³¸Í4Í6›³ÝÙÌ‚tƒÓü}-à&Æêò¤T4MHUe€¥qËÒœf¶L¢l®½CF˜!{i!sY¬þý:·Ò½Fkfã…5l¢†W¨8„nb‰~™æ®Íð„­@BW$OÎ3—(e~/°ÿŒøüÄû3â,ü¯Ó[ʶKã쉘öÚù*;boíZ§¼žçUþù»ðݳí5¿Eœá €‚vDÿï„c¢ˆGÀh™èþ~À—ÁÓ¾¶ç<÷nèz%3·”a^ñøŽßÛîdÿKöëËÏp±udÿô‚dû¡]ÿ<þ²>þö:þ§§Çûo�¬Tî;~|ì€/püÇ+úåëÍñ˜§o=εLjÕÇ5ô=dç|~mÜ¡bÃÑÎ §‹µ§èõûîùŸ^,.óðñ®=¾IìH`ûúÝÄq~ÕvxÝÿ<ü�c3‡)UwízšvƽÁö ±–Ø/lLpMÛ:·?½õÑ_öM°kÄõ-ßï ‡ý»¸?Zk[=d=6bâüEë]/æ? :fOö,¯fWòÙŒ²—iª¤X`7`gæaÝh¥¤ÍÂ÷Pרõ oÕKY9P((Ì;c˜ÚPKtcÈlZifÕ¬ FN°¾kÑ}é>›G‹R˜Ó[ºMJ4Á“r¢‘‚m·ÐLtQiœÀ5!AŽ›Œ<à]&ñÇä+­T¸Ù8W ¶Ò‘* nO<já,#'rÎÜ®—ütåÓĦ™Ì‹¶½¦£@K‡'1ù/áSt[â„P‚Ƭœ5QnØGÌK­4“9Xi™«±E“Ø:¡`7tÐS µÕ­Lo€Ù"]”PÌä²,“Y«–­‡;rõÁeUû¡2$‡|˜ëªÜ8•@´R¦¸9çÀ\I¤\K™Uæ€j¶W\%f!ËÊåpCÕžMnE.éF!§fÎQ2»)T-]*sý€0¸y‹èK~ðc­B©ds1Qµ¨º™·p.Ž04&TBUm˜W Œ¶ª!TÑ!¬Ž`ÙLæTmM‚bÁMMÙ¬7ªE9wÄÊÁÒ$«%¦È4NÐÌIW¥ÀB&Q3k\u½á8¦$vº&¼¬Êú¬®æE³lškV6LòÚvI!’‚Ä(MhÛtÑnÖY´ðÍj3\ Ùkw£FÚïK¿©wžGþÐÄÙckï ð~ÿζcûC+=ÌÝãrÑnu[|êj2t õ‚…é¼ÍÓõ±áCߌÚÍ–K'Ñ/(¡|ø+ðÑ_ëç?Ýì3àKÊQ Þñó£Åt<ß&|ÄW‡zûe¶WIçöòÒ>ö8=÷󇎯ûü-?ÂïPúî‚~Ñ"¾Ú¬ðªoW=ýú¯›§ÿæwç/òÝk<m~õðÇφπ#ÐqÚЀþ=:€ÝWíËBÔ!`¾†N¸+Ì/‘ÆÝ#>Á² &ðIçOõð^¶_Úݶï¶ÿöm;¯Mb8²¡._?~s<|Ów?^Íð«ZQ¨@ÚAwhB#šà‰¥‘ô¹ü$ç¡ek—بǞßîŸÏöŒ°|÷3´¢SZ3ã •ŒÍﺆ¼â*\F*­Ïкü5È@+Üà ÍÑÝ�%ø »?ÎÒ¬7È&J2¤1ËJ¤‰‘´«ä ÍŠd€77µ÷tʱ �æ Tf`,1˜-û:.f#bY$E;¼—@B^0‘E˜U– ƒaBбHwÄÍ V†U˜ZŒ ÀZ˜R©€vºèO«M5rÌËUÏ›odeiø'F¡åK­[hºœšÆåž^cyµM³jk#Bêæ„Û’OLÖI2–{(×Z\  B¥„¦t…XH.€I^ÊL¾¨†©k‰œ•e°úÊìû-i2ó2+‡³e)¬I^ZÍd½Ø&P• jQ ÖA,Ñd(÷Z¥†âŠæ@$&T낞  ™Úˆ¹úçánŒ2KX¦&*oÖRSxÓ1X†”¨Å52wo­[I“Jº¡1‰ba$ÍDËz ¸-R¶Š@!k^WØ5ª¶*G#"1](²V²T6‹5+kÊRK*R†Â#C›Ï%Tç¼YÍe•Uˆ¤£uÞ.X�Ts›ójU³â’ªc£·4Ó²)FÐÉ…iµŠA8Ì ¢¬–²OFy9A›¦êˆça×­y ÷OháñÑðÈ‚ÇÏÈi6¶z¤a6h¹;òU·±ñY°:MœýíÑ^Žvßçn³:`n–#W ¨šþĆP5èiÿÈp†¶ø þz+3Ïx¿`&|€ùæ<%Ðó'}þõYS;Å8çG´>ò=áô­_Ï~ÿp}óÅxÕVìÍ5ÜÎÙQ _´óÿhÿ'ŸÿÕìÜ>Ÿ£ñwýÍ‘hÆáãÑ¿Ã_äî<wø¬Žwÿêhè9ÿ£û—Àè@ÇxØa›À÷Øþì›ññËsLL`›èÃô×°=ª£ˆQ﹃>´ë ÏâåŠÿ÷Óãüß}Þ¯Çaÿh»ó½ÁçRšãÅQ¯NóØÞ~Ó‰îo7kP“l$:¸q>‡Î½A¸!pÖ U+æqÒÖfô¬†½m\z¸ãPm÷Œ.Ä ,ÞÑ^¶‡>Û’…-Xò¿UýÚý' ›;cz<aZ½t³)íÓv+ Dº3ëjƒ ¦P £Ñv@QmŠÈ>ÊS¥K1áéœAÁwÃöÃ9Œw·:¬\yÜúfÖip—Ùâ,ÜHU hœ Dš»™̬ɬ`I¿a¤AÈoŒ+g®�eÛH& $'LFr—% iqçj):‹–P­©‡¦ê:·kŽ9·ºNMmâ„ÖòÌš*f–fpš�˜Ó¬Ü¸˜š\+ºS‰JÌô9×~` Í4ÁîÆl&¦�J®‰rн`f+P7+#Ëq5î }ùª+”Rå•+œ7yåÚ /CiÒ§ŒÞŒá+PlÍ­lñ;ÜȀܖbYT.‡g.G“Vü±ˆ¢­%Ç:œ2¸ ÍÌÝè�'j²6–BÞàafNy˫ʀæÞ‚-䨦¡Ê…èTdEw«.™4«òVV'kŽ˜Û†,³UŠ\ss§™QY³tc`«*SC‹í?ò=°ÚIos²I@ÊJ„ªä]HY7ÈØÈ,MYV1Ó2#KróænA®%DÕ¸Ôœ5`ÙX±]Ù÷ôªÖÒY `¹TwKGZëI@¤ Ðj˜;žÒ*¥1S륭i§¼‡¸wÛ«™ŠxßS�NÔ9s¢åIhÜõl½6ˆoMW˜Öþ.ßvZWu3>2£ûæßmfî¯Âx)»Öåß“s ™°Ý£î¡û¦Ãk@Û)ýÌ m½žw¼à\¯ê_o¼G¾Ýân4?çÊç^NÕ›¢sß'àÑ´.§jm{ ë5™;\Üʉð¥ð6áxüß…¼4=ûñx§÷ý ¨S^Ïý;Äñ ã/Ñ^îØœÝfçöÇrJ¿¾ÀÍò°áñ �í3ŒÃWý6`kø7†¿¾‡ßápì±o7Ð0 ÏÛGÌOxÚáø7OÀï±ÃÿêÔßœm‡n@Ž®†gÚ¹ùÃ–@ÛB£âÿ©8æ|]úhõØ‘5¤# K”°Ô•£ÎY9·Œ0ãpD÷¶íçhvŽðÎõßU~®Ëý»´ÜÌÚn³°$F=ZÜ{|ðÃvMœlÍ7BÀ{*,ÊÎ Â僪*ެʢà¦2”×´9c2¹æ(üqË&#§Û¢o†Ð…˜B¡¤é)j®d„©ÒT!mš ŽbAUu+%ØÒÍ,!sWeY€1•·ñ¶WÍx%LfÂ"Í-¨•ÝR«4øÒFRZ])­ÒóÍlÌ5TRΩí:¯ŸÆvɉ”­ ¶»‘o°ÀRw4ÃR(˜» ¤YÝxý«NÍ4h—2Ù.¨š)•*JðÚTá¾S˜–L#×óþ¶jTH…«®£®©áxaìŒE¤ÐÄšª©"jºbºÌÓûi¹„\YÀÝ—íhy¢a¢Ì°ZH¾*ãô’W‰*j"L@I«¨›çíÜ3€\»òé”Ö®„ICÔÎÙŒ ùÂ'Q¸­¥ÜÂ.gª®¹ 9´8¬„ht šÐ Vé¬ ª±Ì*¼ l4EbýR¼ñTU ¹äÎȪ2š„Ê’Í›\jñ­$T™Ê…FUÐ4‹³ª’ÅÉ‚ùÌô^IsóJd@ß×2•$ vã-@µL†s*FTœ/W¸)!³r¥¡ÀÃÒ¬ÑÛJ)Å”™igI4¨*1IÄ ;xØîņuO;tÕ¢LN<‰�<kžâåÌÝõ¬ÝCÙVŽºÈ…¢WmA€[%ÄmÆØówÎcTsEâ^dª•æËÜ~6|¦=ï±üT<‹ïz>lÙ2r>¶óœxŠG pß c§Gbõ ögÆÛVŽì[îÇØp¹;¿à¡úÓ§Ý5øûƒýZD$lÃþŠîï!ä8]Çy×ÐïàŽœçLlû´î^ÁîÏÍ87#ÛŸ)}�ØáÔðþðæç§ÝÛó¾ø€§Wø¥ãûŸâp‡ûŽ»sX¡¹!? |ºàºÇ÷�ð„_î°íÎÕ±NB&OWœ_„ÿ4ñ…p¨ÇFà÷ wc¼~ôÃ{6¼ÌæÙ šˆ Õ‘´…:ƒ=á:‘†,\Aö9gCãÞØûØGNÈÀøâµñsŒ]~²š£¿)ÛÖˆSå{ð¡ö¯ê®¶ÁöbC; ÅJLxÞ»²ÕXݤ\zr¹³z¦Æä˜ž‚+üZœª¥E\›×`¼ºÔ³¢¨M¥2Ã5X¶šoRÒ¬œ73Ù함*Âafà²íZ¾þŠhe�ޤih·&­ƒ.­$¥ µÜ”bÐn<gT¢²l®^R±„)˜*V*3Ǭq͹QFk c`ÃzW¬�­[7¿÷Ø?–­ÈJY…ª›?¢¦é*^é0ëŠëÔ¸ ­t¥˜b·tí‹ÓÔX;LM(β91¡&j"«À\Ïæ’'€\®"ãD3C±M¸†[‘¾¾íQIÎB&º¼9݌Ƥ™Ù�»Eºœn2J!…¨„mÒXQÜ‚tC ß «>bUUËÿy»m“ËÛL–• söˆn n–±²fÍ×n(k¦ò2a¾UnÖ 3×o…ÓࢌæåU U^ Áe¦µEt¼¹VÂH¹º–¬BêúŽQæ20 ´!ËçfN¸fÑiŽ1Õ uIIÍÔëÕ@* §ålª„\ªV 3¹9Òk0Aí7GáxÃoâ2ÁÆœUµÍºŠY͹KŽmô0Cz=yBEmG]›=?°áï­Q÷W÷B3…ÜÖíÙ_¸Û*?vŽÆ½ü½ ^Ë9 ¯¦šÏ|v=¤>|s"^ƒŽég+Ä8ÆvlÏ}¾lcÞçåÁ_ZÝ?x<ö»÷ÚÁãd:óŠî°Dæ Ù=ÂÖ6ö«Ý?÷ŸM=<?Õã5›ùøÜ»Ãaè/ˆB0`qŽ{0Tâ<í€{ðtÚõ³°z´BUó—ñÇφÀ;àøK´/ðpÄãÝÛ÷ü¸LlÀõ€ßþ°vøi‰¶ÆWäËéåé<¾ÇÓÿ7ðË=~5ñgoÑvi…ÉwÀ1Õ>ùæÇÿˆ÷Ýqßßqâ¨ý9:؆çmÃu`@¡Hœ çjÃ¥0t öÜqûèxlú¶û™BæîÄÖ£^!;GØð tm±eó¬SíZFÏxeÔñÞÛ±›Be^gzY¸¡Å2šaÕX3Ó@rÖ&wLËR F›é×dYëT±œì>›¦cÙÌbñ5|H‡Ò­„$ŒÈšÉ©Äfl«ï¹ä¿Eƒ™ÆêVÀ"ŒW©èVí*a²rñ-Ml Ê–—EJhëjè4#Ì·M30¤W‚†©åhäÔ³¦uxÑÌÃ܇Á¬²f¡œ”¬[»~ïÞÉHÔúÊÂD.ºCþ¸xÎúN|NÝ¥Åò'˜¯h{šíkÕìFÁ·bbfi+°Y±ô•ìiÞÁ𥛛æVVåcÓmÐé‹0-_`,úXÛås’Έ5½tÊŒ0Ð+ÂÜš¡‘j%—$·ÒÚÝ/1Ú ¤NC² *wXR"&2µºð5c2+À¦!Ȭ¤4Psá)Qk-‹2°”9 f(N¥’Vm¹'tSó‘& :ÔÜ(+T•i5I&ÀÌ‚(—UT•aÊÌ‹1²f‹$fÓ,À*pÌ&±¼Éld…hèôÛf+©:ªªPXá%S ©4®Èél»èªAf­¥ùmu¾º"’m…4tŠdJVë\åhN‰©ëÀŽš›¡4 Þ…'Ê!¤6áã¨sæÃ¸mëž[°œ…§¨WCÕÕ0!m3¶¡Oñ÷3þî¯K}oÿêÅù‚:ÎÚ_ ð‹×‹±·víÚ¡¿jÜÿMùo¡<ÙKëÏ/ßCà ¯°cÇ&Cu ¡t¶+ì‚E~¯ 9ðìï}Âæi‹Ÿ\üøI¯?ÙöŸõ8õ÷¿§ÛÈ]ĵ C%,á€yÛá*`àšøØÞ]>;~­^‰÷Ôûq>žjžÿk2¬Çµ~‹ííW840°ulÀv<}ÿæŒ7Àæ0 ¯þJ¾ÓvÜhñíƒ_kÿþnðŽ7ÄÁÀ*‰‹Ày|Êãì½|›_$üòîÃõ8ÑÆ]T‹ûÝûû2±í`ϘØ+( Ý;ñXj©‡²Ç{?pz|noïòm÷nOV—än› l~ºÄ9ø‹½ä%n…,ÿôv5þÐðˆ„o˜/£€š}VsE`í�w!t×V=V²­Äi5„’û‰‘²Í°Bå!ëP© û¤ŒÝd©Š˜¾m%§TUê!3—•|"Ó|…ú¼\.ã6‰ñãÕ^³U¨•½‘¼ŠE˜‡»ÃéAT­Hj–ÒlÅåÜ‹P ,Μ9ÃmñUéYL¥ÐÈ)N-ÃŒå,-¨›îl®Ù~$½Òˆ€)l.:¼Áì;ó˜%¨2Í’¨°JK€%YBÍÄLÛR‘5X{Ál-zŒ¦ âdJ{a›‚Ò}›®ôv;Ï÷´pßA¦ºfYVլĜ,7Cƒ&Ǩj`&Neå™FwcHC­*Þm4$†òE%\òµu¬ÈXåsÙ;«J1Y“UNc*å̹Õ,`©Í¬ aEnVXžŸ• X´mæDU•Õ¬Jœ P•šÓ¬¤Äª"…L“,a�d%U¢ y“y-<)Lÿ?eïóbY–eg®µ÷>ç¾g?Â#,+"³È¨*uU!DB jf4N#zÒE#zhÖ£ž÷Ÿ¥AC“h Í4pÄç ¡'A EªP¦Ò2ü—Ù{÷œ½WÎsuÍ*eøØ{†ÝsÏÞk}_–lÖܧ´<S¦„-H ƒA$“ Ée¦]·†ëë…âbº¸f8@NE‘@eaÑRÏjY _OûL¹-ЍTæÜÁ©ÌçÊ›GJw`Ò. ‚r ZBsÜàX“Xs£à ™ÂTÍ=Qs2F)–dZ¨r—ì÷ET=ƒO—K»ì=Ðã�ø+Ÿß¡y@v*å:û<ùaøý±ü¸ëg6}¯ju.v°bç^:WýÇÍþ›×}q/GÆ›9Ÿ.ùVõ¦ùnodgð†~×yDŽñxÎә؄£„MhÇ»÷øÔñÐ�À[kèúûŽ/Õ~œÀé+âvbŒ8 " k1ìŸE^,Œ„ò1âÁûøëãw{êHÃø-öïOøöõ?z6<mm£ðZÿúQó”xóáã±ýª¿A{ú…¿íD«+¦wìuy°ß÷þ¼ûáhG ã6pïØ„j˜<;_žÛ‡w=ýhøâܾàc}üùÙ^=ûVŒcÌÞ6ˆæè­aÔ“¨‡±wË=ëvlo&ÛmŒÀ1F÷ ½#ú¥çiÿjZÿØ>¾à»£EÚ ÑM7ûï¥w¶ÿkê5òM=·6~òbÇiÁ¾uDî\¥Ó’ÊÄ:Ÿ¦…ä1ÂÒx„t«–e&†ÉBºªY6sœêëOõ, s7Mè !„E‘HW&+°îÓæîÝjƒ)Ì‚M´nd³Âõ²tYsc€ðä’"°ÄA‹˜`†Ê4 ·¸vŒ¢œË‡º^I­�•±Æ]De^Y×ûEYî• ŽTÓ— ¢fi^+Õ4±É€�:u¬ùÍ´wì…€yøÑÅJoU!á%ëŽÚ1ÍT²a^–‰*L,C³pï,¯0MdÎÄÜ1æ,Úd¸¯é(AÀ!Kn¨ g™Ì± sA†-–›XÊRL(Òµ4Û³P³r ÒPÉ«+!wi“ÉÎn,‡¢¶rP0ùr`”-g²<«¼@)I+BU3S£ª2%REÔj”/TãÚÁ,ŒrÐikˆŸSsŤ('ŒÞÍe&CYLsdެJ¤D¦…GÀ]F®œî éWX$Y4.á+JHÑäôÚªúÚꯆŒ*F¶´b,4ùÂV•ʣ楔P³Æ®*#eRÅŸ`vâŽpî1Ù\¾ÁZNˆ®iÒ$M+,á£Æ`•ï³|/r‚éð EXu^^à¿)þHžª€ìorî DìN°®K› ¥½ùîñdù[el|èùç;¿DÞÌŠ½fo ‰í¢Ú©=fѾAusØÍ ËmvŸ ì>°O$žè/£xk7›!Û­†Oûçg16ô Ôñwxõ5Žß ÷ùfø~îl‡~úŸ }`+ôZ€ÈO £&0_kмG;ôvp_¡þÐv{œÏ§—;$pùáá=Nÿo¾Äþ°xõîd@Ü?´ÃÃÆþ ÛQÀŽe¦×@âqìm~ìÇyOÇöuñ]Öo:Þ…­ À¸êrûwö»Ýýa?|êí·ÿôòýa~ûåóׇ÷Հ㫟ç£Å©GÜ¢ì¸ÄãDóê‡èž0÷;Þ=ƒÍ¢ã€°™Æ#*ûž?—µ=ì÷ü2ðâswÔnéHò?ëSAðþàç‡öcÏã±·Mé–ìîn+È-©²Ækà¹bª‰‘òa„”Ôô,+/®Ëª!•ÙÅ‘$Qƒ»Á¹Ë(þ!épšmh°Žh„UMè¥É5ëý7/0÷å¸IjÒæ´µá.®×:6¸h4~ÖH +DÃeêYì¼" ÁÅ)%‰k1i¦–6L…Z}‚6¨nµpþ"KVn076¡öª=3™Ã•ž…Ó·²V؃™Q+/’cÌ‚¨´9Y4Y¡YÒ®ni|­Á7Ê‘Ò,Ø…^ð LwŠ [k3º ‚"é EKÓt¥§UY&/¾±¸Ê…rL:ÊIK)ÌáF„›¬i©kŠXW¼Q•µ8Xée~eb »0¬ØØµï5w]}x3k&ªj®Wù „'q5dsVM*Š`™_ÖÜ«` M`$²¼tÅ 6³L„Ê´‹IK³Í-`“TU™3«´\@æ¶ðÇ!cYÀby›SU¹_#X ßmmNˆÒŠ(¨FiLi¹à—*º4¥¬^ ÆTmAÇU,’5 ›¤¹ÃˆE§ÂÜ«�‰’™,søRœš49Ò?,¤"‹²f戉Ö€ÏÁ*Ùêh.ðhLhN*£48&àÅUmêwð“b,jzQOfmclÞ}ËzU<vF|p¯ÊS78?°nŽçÕæˆÁŠ‹ù™­XOÆ[Ûdm'~€~½›jæÏ|[ŽV§6_óæ¡¶{؇½ž.8B(Gq©{ppÃñ€Þ 2ÀÑPãÒž¾0|ïøià²?bœú� !l;ÚGèïñÕ‰÷@ÎЃÍÞ_5.¶·=¿À© càåOÇoÛÓoxz�:š};>ýð„ïáß>jkŒ~wìÿ$q|i­{xi`æå;içÃѼì¨Ú¥^'(À×ëÀCó~+½Ó�� �IDATüYÿ/ýå‹ÃlÇûn›}ÿEþÐìö‹#~ݸÜñøW1¿éxjõÖ'èÈótÑ›ì1ÐR(c³nr²•ˆ.`Šv@lrûÒ:ž/-wàƒÏ±Ï£vŒË¶ïÚè½u¿Üãö†±Y 6XŸ¶y­ùf¥Ïr¿Ì²a#›=|Ò¢Œ´É~TYVˆfÅ€Éáè²jj¾ö‰VfF­Y ?„h]d9…º˜×¥õJÏ ©U Í“LÍ fp§üe¼k�4òJp&äÊBN®Y±Ôš_0 1É%8+h%ŒÊ`)µòùµž)ä(‹´ó˜çÌÑj÷ùѪÊo'["2û˜áH«}×\º_p[Î1±„ Ž0’ô¤Ž2óUÜeHt¹VôJÙθèæãÉü™œ¶,ôLT1 U>åeF™9,'æ:Ú0@ùõ÷k̪Ê2š`nÝÞ„X5àµX²LæÐ,*ÎõI/ðPJ£jJ S¨³0@¸¢©õj­¢D‚‚-’÷ç¾F¥(Ø�>�C«RªëXižò,Ž¡ZÕ;XºEÀmv³ánî‰HçL‰@©23gjíIh$`ÍÌ,ÌáeæÅ9G•–^c!™H@Å\÷BÕgµÅLf-¢“JC˜ò dU­ûXY•C`YÎ2 m¡�S!«¦&–L¾ª;² ‘2z {ñ"v&K3YkÍ–t­ö-iߺìÌ ^­©RHÔn®!µ’ûŠ2ÑÑà+ _7û¹râÒÛÿí‡ÏÂ,]ô»ÝªºÉ7Ëï.ì¹ßßÍž ¬š©ùPlc÷DfG! î³Wƒü÷²Ü­µ—°S $`: `v˜$0ˆÄÛŽÛWS0¾Åöô" ¾­‰9N‡Ä]ÇŸñõ;[ØåÓ6ÞŸ^ûû‡qÛêïÞÌWOv;Û§æè±u@ùÅÙ¼º?m퉘á¦`ϧçñæé7¼í‰þêQítþsÐídÇ7ØöÞpƒýöeàrÊó„â5ñ­wöº›£AÅ}ïÏÕêüxàÉžQ\ =XýìËñ¼ìÝ/¶m­îâÛ^?øÝ÷ßè…56cÃÎðg¨Ã'j@þTTsŒÐ-^¶C?¨õ³ù¹™ãâí ×j<°À2ýQBÛ¿a=ÌÑ»Qý ³Í’&“{Ñ–® ƒŠ–æR¼€Ctp÷x’ƒÍ@±œ–*HatwÐhî67;¸ÝEtïÞzc€ªin9G®è„Ö¾¸Š&?& VÙ%ØÌš¢Y8;Ø akì]Ëï¾`Zýç+K͈0,ZCâÄڣʔZDËFî¥9sVFA„$[î¡D_“h¬|RîTÐ^h«²YóL ›,^.ÔN+Fƒ5°™ TòT�³8^LÏn›Sr Wa¼* m+n”/fÝú@3¿×lôŽVÇ(W2¨X‰æâ^æa†¢f} ¡EQäÕAçålfáA¹RXû-eø$Õ ÙµH6ª&W¿Q•!£T¾Ü4È€ªRéZg¿†‡ &BñÙ$þBí`‡L…T–¡hŸìnEåÌ’0‘œYÁ çÕùGÍ)Êœ5FÎY‹U«Ó¿õ]ÒAYÂ蜹X;+@@¦ÆÌÌU>˜˜™9G%lH 9-3vh •´¥ßÃ,«ÚPÁi^fá ×,œ ¸ò‹¡0´ÔånmÉH´pêEÊÕkM±Š%˜r}"4d²�MIƒV3zÕ`Jžã%³ÊR¢]<†Ú—�¨×ô¿¶øªGM¼X¼‹#¬— JË}Œy»hÛÎîØ«ÐóCØÑæémµÃD/ë{ {ô½úxñÿ2õ�5Å(<Ñq³Ü¨×gýõ%ï'íw¼=N„ð'B?b»\ûÅ2ØíQƒ†šÐÄvœ^�›¸Ú|¸øÃ`Ú pÂ? oê§C=¿Ü/O¸ý»_ò‡7½ó_ ~Ÿq?ü¾2ÙJ´ùx¸úãú ¯€¯N{à¥ã|±£õ'1Ú±Î'¼àRÈwØï¶ÃCD÷ÃnG$?±úYûËÈÓa‚ùçË£¶vw8x#âÎâ,+ÃÕþ²Žßè/_½<݉vk».³ÙHûôXãÔvTaÛ0ç[»}Ôe§Z€Üášc–æ‘÷þÑçï±íU<Ûnõaâ7s¼N>`ÜŒCܳšÂ}‡£h96É Ÿä$7bZ\¬M`—íÉ..¿)É’¶ËÚPË×lV £ã@ ²ËæŠÞ¼¡·ƒÅ­Û!¼y³h¤™D¢¡YYu]BeR$,g( ºY÷æh@®°¢°–‰iòµ&u¬êÕšO9AqUçƒ�E+ÊX¨Z¢g”ÖÖS&e¾|ª½|ªœÚ:§0É»€‘?¡g³rÎ nJ«gh”Q€ÓÝj3d¥Ê$’›íw-EÛœ EIÊÑŒPn†.k’,ƒâMàH»qëd1À¶Èå„X“žè`2ЛŒ`z²Ž5’ŒUÌÉ2£»µ°ˆ•›_¸<È4S f!?£Ì×oûÚ °lÅÈL=0“‚Õ²¬Â(”$ÐÖ9[“ [ÿ­5pGre` ¡Ä饕!bý~ÍÁY…Tå—ðIÂÚP¢"—aŽšSš-wˆ-m&>GŸƒXt¤@ÁÃ$ðÊl—jVŽ‘{Na¢¦jŽƒ%±q¥L'æD†qx•Ÿ \¢>2Ìh¹.‰î›YÁ„……­T¹–1ЈR®Ä“Ng“Òu«´Ê½RK5¦HÅÒ¹†“î+xÆâœ,%RÏH˜ü`–šƒ:‡râ™IâCµà¿€ì¯È¯Ýo¬™ë\­eû¿ÐRÚÛ¨‹×Öu9”[v ÄóŒý“ž¢q°2 ³Ž“³ç„ï/¨öm ž ·£Px¬y2ƒì?ƒÏ˜‡Ÿ·»ûOv÷©À3æhG{ì8ÝŒuÀ%…Hbìð$qùCÁ‰/Î-·^­£jãyßòþfºD;þ‡GáÉÿ|ÕZÝË:Ÿ»£AÈ�òµæƒöùGdXühØ—ñ ð�æÛ$öxt;Y¾Âüˆÿ¼=þWkÿãì½|¼öQ/ãùüdùû@½ÃþÍ©ÿô»ÛnÇ€Á.³bs˜ÍDoßÔÝ͹ö/pÃ!ìÛ¬¼|pâ´< 7`¾v¸D;û¿&ßÞØcä=´@víKÅ/9ÿe}ø]Vó-òø›äÛgsÙº%·Ñú†ƒïÞ[yËf#Zš<f“u,ˆð€€ÍD7³¶¥ÉµY’–œ.ÕSU8‹ V.:fú ßHž ˜›)|ßÂz»‰~îÞÂÚŠœZ&KÓgÖLË 3Ћg™¼‚Ø`fš5‹n­»u“/…2J¢Œ‹f)±ÈõÈ×g!ôºýYû ˆfa¾þiRCuU¶Òeʪ¡ÏA`õ$æ_–™ 38¤ÍàôXì …ª\¡vaQ¦¼d\V:òJ¹¬ÁÈ4Ö$J/Àó$ÍoK[,¦çòN“›Ñ]ævtëà’loK”,÷ì•3Ò*ɳ˜dÁ{U$‚ºˆåXUÙ’!ݼî滺H±2 {‰HQFóÅ¡b®4WÉX$LXÀq;4� W÷[-a¯´¦lNk­õf&Ès jW.¢)²ª¢ÔH_ª ™ÓÜMµà{ Ì*Le D%±î3*67o«-ZY˜6³ h0“`(¨,‹ÒœûÔ>ç˜Brm¥´8 1«.Ò^HÍ4089Mt1ˆÀ~e©z­ë‚­%^‰ 6WýiI3øÙÁ·jvÞ S…@Mf!¯¤w’L³rqõ*gz/›4£*šS½Ÿ»^˜ËŠ“(üíäqóÔ ã0â6 ¨¼)¯¸Ii^ú~~:Ì—O<l#í£[_Z\Do¦ô¹wâ]µ_ú—ĉõØ/ì8uÁHp@g­M?Ú½ƒÖq^§`­^%Ð`‚ˆ‘ð ôóº6°áˆ3B'\ÞìcÏ÷ÌqÙOçþúGÞß¹×f |}Â[èøõß ja8[—Ç—ËÃe<l/Ýëè¾ýêàküb"žñW·@Û1V‘ÍNñÞaü©N7zsänDßwÏwÊ_¶ýÑ_Nü�{‡íö+è[ôÛ×ÝÌb±àT‰–5Ï?Ôlúö¯övkGˆ#cR›’[<žè°†M´ô›—öü(ÃôÓ­þ´gu•eîsÿhíQãß\>>fÁëäľýË÷úú÷ûÝÃî_qôüˆ(ÂL¶Û!½uvÃÞ/³Öà\O£7—ub©77™¦Ù4³X²X‰v²ÚV’p§gg;8·vhÛ1ÚÆ¶Ìm\•§ªPî,J+‚ÈÒ s׳Š9L¤'½¬gôêÞP¦]ZYVÔbà­52“ÏÂ2¾­ê'ȼz¶ŒKÆå´`s3^¹=Xˆ;™ ò‚MŒ)O4P‚¥Íá…`à #½ÃªF£bEhh¤�Ó‚’¦™MvÁeε4”D §Š[Ó¬ª‚J4iºÎâN‚ OR¦Á˜Ü æìQ›ÉŽ5qáÊ+–`æ4y½ÔèæëDZÙzÙ¤#‚›·fÑ,ŒÆk1oUôÖ§×mjªU@v `%M™�h¹x×P"ÇÂT‘Ud‚ÒR&Dó°èáŽLdÔ˜)ì{%KÈ’€ÐnfE®¤š•AµêŠ(šæE”Mi{*3½�µ0$0„]¹c†c“§]Ók±¾“tÍ)1’chì¹_(ºÖ°2%jWí•gLqÂÊ—NÊ)ƒrë´)Gµ¤šIRHSåZù\G ‰9ËW!h¹´•† g‹ŒÌÕ÷¨2ƒ|1fÌDؘ0Ñ•Žè[Ãnù©Ø'þÕKýôRw…ƒè啵 ]šO‹Ú·ófc`?ø§gñPo8o•G5ÀR©œCÏ{òíÓÁÛ°þDŠÊïlŸ}¼±ç§}¼Õ†õ’®†N<¾q‰À±ê+û€úÍ¡€õò8û©î1–ðobìØ÷ØÇI_€`Ãfhý {ú¯Oþ¦ÚËíØýéý=ö÷ÿoô¿”ÝŒbîÆ'îÈý¶}œö3Áû0?`æ˜ïñüÒžöþÓßñ¿ÄÇè~‡_ÿkÃ]à�`bfG$’`Á ÆêA<Eà8Z{?ìù ?`þpÒ·¨Žz4ðo0ÒÃÐVÅ,¢¦rJç‹ý’wº9•Cø®¯<Úaú�nÞµíÇ©“e¯ÀWè½µv©œzÜëÄúMر&æÙF{yÆ(üIâÍŽ¶q«×oÛ´Wy¨OÍÆqŽãïÎj[ äŸ1z‹y8Ú±YGzæ& îôn ãÂTùnÑÂ7W4oáÁ)̲ «¡Ò´\ 3bÇÕm2ó`sªÁ7ææ±µ­õÍûfáô‚]!IÕ¡BæbÌ’åŽøTs°öÜÊݬ™·æaîfD©ªŠÄJ•¬Qê4«BÌ¢ñªÑ„›œŒ”ͪ‘ÝÌ4“Z¡¦UeZŽ˜É7ÊMHÌáé–Û¢êTZåÀhä\62£l1¹ ­+©5år‡Cy-ÊZ5 ÔVüÕŠby‹3Ê:¦¡€±ä_E’™å£`™•Œ4–`K¶´X™™]Ym\V<°7ë[ôÞZë¶4%\¯F+J¸êómë*_Z²£ ¯²Ei5§:´/^ª€\NQË¥N›`9ÝœæäÊKK³°ÏÊkZ• N—H˶™²‚­ÇÕ¤,læ(iiL!‹¨£I¥Å iº‘6]^Ø‹V©Zk€ÊΪ‘s¹ŸµÏ•RE§BW¥À²Ö—e¸*ó`Úu‘…‚r”•ÑÑÀDƒTe“p* 6•¨]ÉX»£’²*…Ò¢M‚TX9׈Žkeá,£Q®Úz^jΑ̪!˜Œî}ó£çCeìÕ*o06*ÅsѦYîŽ Ü-Ò¸_5­Ö€®CGõišmoœ“û®Ä8×|§üO}{Ëþˆ~BCáõ¨¿6Þ·i/½AÌ�6бºô'Š­EpûÍåðöÓËkÿôÖ8ß =™Þ‘ó5^ös›_¼=±½ bKø?ƒ|õ ôÇò“'üøXÑþ¨—ÜUm|8äì_":¸áìï[?O»u‡ÝçÓ~>Åû7?ù-ú·³ýqgÃ÷øPß–çç[Ôhƒ Ü~ƒ|¢uo»Áíó¤ êÈP}…¸Ld{¼Üµ-n>ÈfVœ©¾º}u:'ó±§¢oî[_Ê‹|’aÆ�ê„úg½»#¹ÁWŽÎýmJ?ßjÚKÏv{ö›Y‡ËÑ>µ{ã±Ôl"5ŽÉ[?÷?óñ#Z|Új;Øáà£%E•B±)%΢½7"ÑÀÞ¬…{Э#µ§ÃY¨\•#ö´Fv´ƒYÐÝYa3¨fŒ°÷ú —^/ã_¯D,‹bg‰“X¸¨Î¤O:a/KĶz-+^zíäÖº@"#\ô7Ùªâ’î09 Ê,ä’Ò-iç¶© eµLÍ1³žESô²«E͘¤æI{ѳBBÑá€(�äBš¶4‡y�(°’UB³>+ˆrI²HwÞ˜} ¾‡l ÀVŲa ÝöÒ\‰+×YigYNZre’VäF4â�D ȬRi] AïfÍ·CÛzï="àQB!s`4$¹LÑЄ­ÏlõÞ,aS˜—0H¹ì 9š¤uo¸ê¹E!3˜fA^ïªQY•–ôa•Ü×#ûl>àXÅË„íh“žæ.ƒfp+c¢lÌÂVæ$L3¥™— (ÉÃÀ!”ÖƒVª™º$FbÚJ1d>¡Ê© îƒÓ!C2W¤W••E™«šyev²‡Ü‚pVobIºK^r#‹ð@fÍif€TŠ�8Ë0§$jVά,iಕÞOb°&äe!ÀÌîᦊd¯å®ÓÅ4Z‹5÷…­êÚª4ÇHìÉš¯¨œ/D Å ?ZëÖX¸w¸•úœF”¹‰çÄÇ´÷gû†Óa…Nt1 S?ï™w4lÀ†ËcÚébÈ7¬,øn›ú·øÔð¼?T>øK?ôÝΈôéa¼<œ½Û¹Á 1ÀDÿ€ú ìxÞÀüt\ ÷~:ò]öOð„ýðnÄÍ©ß# Õ/½ýøäyþéþá6ïxA?=5<4lúÇ ÿp)ýÎ+çý>—wèÀGp žØÖavª‰ Là|ú—†@G6\è7þL´=32÷ùü‰ã§†!Üæé‹—7í~7íãÒ ú4ñ0õõö\ÀùÌ[ä=ç&†ŽØÿjž¿)<M½íüˆý›?Ýïï^f“ê‹ûqìm#PÃú'pÌ[iëæ[Ž/8/íøÔý¥ã›˜e~4x\Ás1#n(£y¹¦ [ï±´�["ø†I3O§yëÍx0?Èš�qàJHí ¹vÕ—J–•«L‹J2+Õ¸èÊVÎÍaë5Ó8iS¥…d¢“¤Ü$YfBë.š¨b.…1Z¢­§?LfŸ÷±bC ÜJ»ÊÉR93S ޾¨e°F[K¤0“ÁTf¹ ­iª)˜&#ƒÖ…ëÁ øR ©òbU…4¨´�Z<¿•¯„µµb'/b@ƒé­Ì(`Z]X…™êN©4Qœ-[›ž¾Áš‰V93+“k»°fÑz„Gk¾ržK$°PÅD«µŸ5ì¼f»¸2±Nb²r·l“pX±*ë(­ÃE,Ñ�«Í¹¢÷)­Úœ]•£8f²Š™§%I¼‘(/A‡CmSÎÌ£h4JHb/)33— @ ¤/ðµ²rì)•2k7€±U‹2S…€­}A ªèªkÀµ™“œžE< PÖœJ.Mˆ«NÚ (Ô4ªŒÓV\Ë¨Š„IÓ8R35çzÓu…Á®èu%1M•²^ª27w Öá5c\f ¥¹—-Ö°¹*¤€:ÕcT¦ùÅýÅhµÇ¸œÛoÑ?1î©[Å6WØcN9ý’M;jwývâÜa921ñX˜˜oàX®ÈqÚ/xiÈ3¶Ž¾Â©ç×¾=¤7Øðé9æÖþúØ-úÄí¼·zôm?Ü|:Ø~³vÈGÃi^ ø1aýQý´žâÍàÀÐÓÍÀù¥Í?Œýø„~-ôK'ä›Ùñ‰n°ûYÃ{ÛßÊñ!pƒwúcφ�݃à{|ù-¶[`CsTÇfP TÃù—oñþO¿Âþ-ÆÄ¥¿>Äù·?îq)šå¨ÜõîýåéßÀã/öÓ¯_ð¿·§;C;ÞG¿uá~2µ'Ð ‘x±“¿˜çwU7ì0ÖmŒ¶?CBž¡'´W­ŒûÙåx9d…Ìy"^;à‡Öú­E—o“=ˆÖnƒÍ.ÏðƒÊØ,<ܬÌ•&šÊ*Z´j·hÝÝ"’6«Š!å\1”Sh} 4_µê›¦t3»:bõˆW&(³f)kV Õ\Àz©£,éd¹tÕМ^ý™EX#£Ñá®âucNìƒËo3†4¡$-&3PkÞ¤Hû V¨uF-›ZzíÂî0£Ín)VõJŸ\'w`‘ßl‘¿“\ËñÅ3 �Ö`ÝÔL-ɆԲ2a +M.ÁtÕ»í«%ìµ¹ÑvO6'§çÄ -aÃðB;ãð%-àUe¹gDŸYsk=¢ƒ¦LÍ¡qÁ>äDï0˜7oˆk $E_G£J2-µ$¤Uqe%å5Î:ÍR>Á×$P­Ý¿J\Þ3®ÄÌš‘N(«¹†™û¬e’K†U&gŽ(@¿ïD§‡Ó’%®Uu8äÔs·9˧i‡}$wñPuÖ¼AµÏJ×ÒfYf U!±W•hƒ!‘Ž [™Uz–Œ"¯TÒÍèi†Ï¨•#ã(3p¦æE* mu¥‘Ÿ;åƒÑ-/Ž4M7,—m¢ªX…¬aU•¨5ÇNæÂhB·�ƺFt:£<ÌÂðì4®v°iI©3•^’fä4ëŽôöœ0ëï“/Õ/¯ @F`R/Qp¦ÍaLEo£? § €•§Ëû©ü ÛËt\¬r^¬~S ñ<Nw ”†î}¿€_~cßeìÆÆ½ÍË¡µoœºO÷êö©£×ðq â€[pÝõÖÄ7SOéo?+mÞÞ ¼ÿÃãxwúŸ¿Âý†ÞPÀ^¸ÔSãÃ-7çVÞÞ+lúÝ?j¿…g|ßÿ;Ά_ýÿrÐÏJ¸ð§_ã_ââø'†­ƒ'4q¸t<ÿS<Ýàÿùs ðú «‡Ž‡ûêwµßÎ'Óo'NG<þažþ~—7íןÞüâîiâ-ñ•e…§úÐк?‡z8³×ŽÜÏÙXÛÁöžÏÐÞêwöp²¯NÙߨ¾3_^^`vžíwç|2Âð¶€Mn'«ÿ£¸9av±³!Üçn’ ŒhÑ\Æ2¹ G«µµ­ÚA­q9]5UÊJ° r&¼1¢ÙÃ7‡mÑ®€~UðX'eL[Ù L¢¤Z¯Òë­]°4MI„Á`¼$ú5¶i-¼™…™ UÌ9E+ U4 ëI¼J¸BÊPe^ާ–¾f•´Ê˜–©²°@›ÜMVÆŒ^i£¤¡CfÖÜ 0Ú¶ÖÏFãuŸ %›)”ª2­–™eÌ(X¦_Ÿ&²SI·ð�‚pf²®ñGä>Ñß›ìJdHùLíJ«r †±7ß*ˆBNà°6ŒÍD”¬¼É½Vo ‹ƒ*ƒAUÌ«%0WJ‹g2»Æ`±ìIM;™ÆiLZ/2å%Ó‡™Í`0 •H_GhUªRµO]ÇÒ’L*Q…±ôј†*&IxÌ€H#«t•„:Ý[72xùTS¦ËÔnÚiÏäÅøÕ ± c*¬ÛR(@WÐQ‘† xªré;Ú2•1×O ´4WÀ±Å°Ö‰ Z©jS«”M]JÁL§ j$¹ôçé”Ñε›Ñ•YÈI¦$0e`^Ùæöùž138Åe<1ˆF"˜-b†lšiE—¼ô<Fåh®lšÑeaÖ;Œ%i·g Sž¾lÞŽÒ‹œn=Ñ€?1ÿ?“/³ÿŒ¹kíÉæ[ÆS5œùꥎÐäx(¼®xÛí‚nÀêÑ­aö-n-oø]¶þRx~Wmk¶;¢±FcÔ¾žPx)´[¼ Œöp“}öä>…J4‰:#wÌß~üèxï°ŽÃ猘=?|³ÝcªžcÌþòåÍû?üÙß\ìÝ¿oÿgÃ.]¿¾Å—?à˜è¨a8>5$Ñ…ËD=ã|Ä»¾¿Å/ˆ_¿ÀæãCµ>û]ôm¢ÍÖsCòtçÀxÀóž:ö_ßàÏnð1ŽyÝ•viÖ„:âṀ›è9w|œûíj=cÏ1æW'| vØöäx~ðOcV}ÚÿM9Òà�;nÛ©æ/â“ÔÓp‘W½"z+5”u|–§=ssö-z; ·ô–ðJ̬1z4h3—p#›5oÑzóÍ,®MaT˜‡3ì³$¡°6²ë…‡”!ËŒ£-ËÊÊh¬TfˆeQÖÅÂS Ó›{óháñYá›n\ÊLSU‘WÖÆ2 k­€ÕO]ñ ••i)Nó „Y0:·¾Èé^<',K#¹«e­Ø¬d(ºa®¡Ü¡<ÅY„ ÈŒïu0�� �IDAT*«ATaLî²p™Y@.š<æ{ÕÍzo­8h kGñ,›Ã•"ò[�/]÷^P RU¥lN´Õ(J„Ì"¾¹ÖîÎXúíU5Üåf4‰JÜŒ‚i9K.«[é eÖN•ƒÎöy߀%`3ÉP ºkf W¡TPÍ)®ÜM޳Æsκ~é\ré„<AO"[Áà!1Ñ/ Éüÿ£ìý},Ë®,½µöÞçÜ÷"òWYü!fOϰ’À‚ ‚,‰‘Y4§-ýkÂŒ§ Ê“‘h„×@”£!z ¢ºÙäDUVfÄ{ïž³÷’q^ –Q…DV%2£âÝ{ÎÞk}hfN&SÜEÔn4'½,×xA² P¬*Ãê*hiphåU=—T ŦA-B¥5%ÍP”1u][²,Ër/VÂq¨ŠcÁ¢‘WfËJ/‹ ¥°&ŒòŠ%\™†ë­@xB2H±~Æp„¯Ëõú÷œám‹Ò$Š ;I±'žQßdLô®fG?ÂʲrX¦×v°£p0Æ`Œ˜*¥-%ã>£™yb«šô#9Gù¦3|W¢7ïUØñ¯3ÛǼÍíx°ÛÍðbâpº:Íhï`¸’-^±I1ævùàÞÑo¼õ·øèñܼÌSÌoøt‹¶~ÿÚ¬ïÖÓP£Íºïù‚€Sb_Ïí†7DÇÅ „N>ßò£§‘ŸZzÎã8Í_m€¿½ÿ“ß �~öSà5а}ŽþGÇ©aÅ6GƒMHȨÀ|…PŸ9ú|èß¹ó6wÆàˇ¶† ÷?fûò¹ã¦ÿì ðæå?´~3nâtó¢6ëµ1ý„tO´h½×MŽã~8MûìTrûô�ùñuïïMàù~Óí¿~þ€Vx:àè¸!<¾hqç6ËNÌç‹þíÀ_ŸæÑ¤ÀÏôƒÜhr›nófÛn/Ú¶±yÒÏYû…Ș'­†çî2/Z+gwÚ‚dSÒèf¤ÑÃÝÝÜér•ÎÖ=ØH—á%ÂÌÍÂåVkÚâÆ¢èEK"™âõ´æÖ͛۵x{Åù9¬0ÀgN74·ÙŒf¾d•×=4ÂÔV ª¬†-®*H¸»;¢±›‚2¥³È*Ï©}XƒO,ËÀ@¥ kra¤ÓÛpʸt­ œe¸8.ª=5wà4Þ1+-œ�•‡1ZC¿`³p³"NR–]FÔ(w‘È4§Ê*m®¹‹ùlstÊ –Ûѽ™7@”`‚; ©æÔj X §É®¦¼ ‘¬*eŽTE]crN×lÔ4º Žò¥ß+I¢„Њd¡Ã)Oñz^W¡ªRB”Ub–¨:Rr,åkÁ²´mŽâX©8–ØIˆNãš©�Õ ¯“½-^˜¿ºÄ«Nz=gÍÀB®™ËVÁ¡&L¨LÅššÂμH¦Õ´W8\$]ÂÐp-(ø‹×:}RU™ ïÞÜs";ÍY$c½·•€Ò5É„²ÉL!YÉëî°M¡IN¸]!â µ^K2ƒVtTí%”h ²Yö 070cW�é6 i%7†±Ààeáî­1NÂ‹š–¶•¸Åf·œßÂ?Òî5î[ëèÞZ´óqÞ.ÇþŒêÐ ŒíýNmc4šŒa‘Æ-sÓS;sÞÚp ¬à2ÿà†‡ñöþéüð·ŸÙÃOñŽÜ[ƒ´ï>0nÎàûÀ§'üÃW�𳉠Ñnðgx<2¡Sâè´ôã‡æ‘H~øð§½þ x _ŸáØ&`ЀñŸ€o /zA;öm�Љݱ‘­Àç¶aÇGÞá‹ýáùüî Û_ŽÛŽþñä¸äÝ% 'ݸ€š8‡ö*Ì›v×ÑÜm¼Ü­jÔfãäºóófï[Gv„þUà³¼é7þ×Ö¿nøý±º#âζ9Žneñù‹¬ÌÌ1ý”¹o§ZhBæÌðÚz;ÚvØÐ8 YÉfqF,ž$Ü$â@rÊ(%V¿Ô‡ù `­ä`Ò²åÈ„ÊEáYËDæaakò$È´>€Q°$ŠUW§‘±nØWä‹Z»Jaí€=jÙu±”AÆb±DÒ–è´XW  *•\ ˆ$<Z‹fÍ®¸Â’«Ž5F¦4”I«™U–±fEUؾòí°X¿šMÎÌ<gí£¢ÌÜBôªe½FbxÌ^èe=iûj㜻{YLy°–‰™4ˆ¢öÉ® Þ°ž aî2¢‘Q@Y¦e²r í‚&ç ¬š¡’.Ú¢`Ïòœ L_âyNÓÜ(Ý=…âzQ­ö<”àC³—5³˜|a•³r.:i@ö ² š‰QDòŠA5cBU Ó” Ë2­’#‹CuP´•#%7ç­×”žÃ.­ßÆöÊÚ-÷9÷̪EÛÆºØTy¸on‹0ªl83lª2c`/ÔÔ,‚ææfIJ5-3rÚjeË ¹©rŸƒ™ºÛ5î„XþŠEþF­3 ‹ªQ’¦T‰ 3:mõÄQL±ökdzn¤¡ëÌôšÔ+xY—óú:*©‚Iâ‚xÁþ-3rÛf”GŠžf•6BtÇZÐC’ZÅG§"þox›µ'_7¸¸5l‡ÞbLX–u؃Ìp˜xA\:n Ç^ègØ ¢vXÌÂGÕ L3\ª"/ÝÎ3¾ù7Ø€5”ʸËð¨öËooâoÛ Çxzßú£pl´áþˆ.ßâüã ÿ_x‹ßLüÙ{Ã1Ñv„ðÄ<þ\óׇÃχÿ:(àÿS‹þÿ{7¼>{‹Ûž:&€숿CÿŸ | ”°í84ptt»G=Ø ïóìö~>=<=ãMC/tâ°ãîòxø'l?hQãñ©Þ<çü7ã/ÊæåèÊ9¾©ÇmQÝq$¬[&kT~:Ú×Î×Àv¸c골»Û¶µ™Û¸m=¶ùÎ϶MVCé7¶èÛvjœ›Ó9eç]ß„Šõ’ÜPfòu.ó%.ƒš­dÜ*BšÅ(4UOœG–¤`š­pK`Z)3Vb-’™²óÃJ;’¤ÓÂÌÍœkþC:èpÒ/@\ ,TÂwóY]GÂ’”Ò¢@…‚±ÊE«k]×ÖÎU+8Wäfñ:+W&¦”QNFÖ‚j0w€ªGhÌœ^Ò.K˜ÌŽ ÎŠõÀ1p²¹¹KCyž9“*õªKq8ÛäT6*Š!zÓÒm_ê4†ìH‚Ú”6�¡¦X¸VÕÏaô"ÅõLç¥qȺ›Rk>Óh*«ÁÜK6³;e \ƒí%¥Çò˜NXª8®ðÃ’±ÌÐl‰;ìŒ*V²&$&¹Ã&Ë¥Û,/ƒ™Ã ÎuÎÎ"µîŽ+7Êrå û¬00±{—ä/¯¡9éTùxÆ"OÆÁ=܃Üìp°¼ñm‹ã‹v¸mý`ÖTÚ‡?_æé¢,JB²°æÍ·‡fA,]¹)0á39Ü.û~®å±(­E˜{.\ëp0{µ––¢ä®(öðD+7X¾ôçn¢‰!@U*À·U6%…QÚ h¥üS*‘Å+$P”aMU&¬zªb‰2ÀiK…aUƒÙœÉ¸À£Ü¦3m¹›(Ì {¦M`§.•LlC}÷·¦ïO<• zl ºŽ^Ýœ•¡è+akù°mÿbäáMŒ>÷m<ÛÇûˆú€|y¯ù0ò¾ê¡w´çÌ~. ßÏ5>Õ݇ˆh~Ss³o™ŸŽyDÞ”?ïŸõóñûßÜtô7ðÛ7Àq¾·ý¾¶�!Ìh;.‡7ÀÀ·_áÍ_¢?¡/¸æ3âá Ä]Î×Â_ç9ûáâ1í½u˜ÿ)¯€þúçÀD§ ÔWÀ[tásÃpü>ñ ðc ¾F;~󮬩½S<žß¼?¾Á>Î7зØG¢Otáøáýþ[îñúaeðË»ØçÖŽ9y¾ø8ý#lŸGLüR)DS†}ò…G Üøùã¾ß÷Ëãç•Úè<hslùŸ9?Fç¿ÙñKeÁàW ïÄxÑj$>x¦þæ/”ÿEU —©9üâË’Q5™ôe1T’Róš‡*G~˜«vœE¤‡%™ Ê ²R ˜]Ãw¹,ÃE[ÙQ‚&[°á¥‹¤sÅý,H¿²L\q4^G™Z)éJ¬^-^3Bb&1M‰ÌQ‹¬·^J»HjJ¬ÔÌ‚Ä)«RµRE(˜ØA[¡…“%$w7˜O™jmÍ© bµþhéÞó. x87ÐeòR‰~_OsN¬®,éN™ Å„& vl+‹“Õ¬šØ xÂc†¥ùºE­ ak—:)ùJ°¬0˜ҞJ)Ky^˜Áit¥Ú,˜“43¶V†U¥Z ¤e Œ“ rñMP¨e+›«à[JÚZš…SU ¿ÐD ¦X®å¥Áê ¢X&–/Ïœ¡pU›]¥»àÖŒØ -hp¦û%Zö€ûvõ‚šy¬•o½m­õæî*Å‚¶ï㲪ǒµfm­EX£l™{Ýåœ9±¾†9‡Äéfîîá4d¢wÀ½3,S‰j…¢—³¼‡#Ì›"Êåkĸ¾]쌂Ó$p.$8‹‹SH*) a½¾M´UDª2­+öwûŠëªB k)¹C*É¢J\N%¨ Ú(á×'!Ñ䘆‘{z)Ê;äé°—¨­êàGoÿ¾ü¿uiB%/Ç4s¿oöÐZþ_Ç|Âþ’ã£ÏG¿@ó }v7âõä©Cbþyñ <2[r<Æã˜3³¾ªúý ÷—zÞêw—yg5æíÜãøÄÛÙûÏí®Ÿ?Ÿ÷7—]0¶‡!4Á·Ÿaþü¿Æë8¿ÆçŸ¡ß@ý8!žÐOpÜU»›ãµàñu†»ß}ÿþ)û†ÅÝ{ ´�pjxÐÜ�t„›„?š8<a{Fÿt—/ïøªŸú^Ù1 OŽ?vü7;‚èÙ€·àov`þ� ô§ÇÃíU3Ž*ýêÅGlŸÐk¹Ïy8ªM+ëœã&ëöy´ñòæáÒAýzè¯ÉËžÖ›$äEDOµüö>÷ß~œgD·ðÓDÈ>i¾oFÝÌúEåÌ=¸™ã°K<OžóÅf‡V~˜ 0RsÍ–Q³ å¶×w§°Å½7NX äêËÒlÈ¢l¹½ ²ZÏkƒa®7`D㺷[ÐWÜǹú³FØÏÃLjQ9U�eX‰ÏïÞ8 I$l=‚­f–�š¨P.Z¸Ô?�ŠÅ¥0#ËRt ÌÅ©#k¸–uzP“Ef^'(ë k4Ï“‰rU“µ2¸MnfÛðºÈY­Ò’žð³4Ó8Ye 0ìø]APƒû\ášÎ!Ûkýî͹HÏUF&g’ƒj,œ(¸J{ÕX_¢½c÷äÌQÊ@¹¹›÷u»žmË ƒœIU§Ûp¿Bo× z¦jWŽ\çÂÈÚÏÒ,]R¤)jXí,¸:, nE® ÊJÔ$®Š$eVk7%.„w·Í†Fµ›Ÿ#äLSs}'X˜‡¹É,”! Á «Á™’É®èóO•áê-'a0Pn^áRÀ”+ul‹Ò•”™±9p[’(B‹,otÈD0VáO°Th•hÆQd‰ sqH€ts­­¹�³R:±>µÐaßµ.�·ë•Ø@¹¾—º„˜DRË|aŃÅ+¦‡D[9ŽY\õ «h2('�ÓhU‘ê©ÈlCã,»ôÍÐ\”WÕÎvàܾH¾§¿çŽÌ{ŽÀÃÝœwóæõå¸Í@³“ôÑöÿsÁˆ^Œ‡˜Á§Ñ_>ÛdzªL¨ap TÇ÷ ›áÂm _ Ž¹Zò·ºÐçxqÂ�n?ÃþÔ‘ø€ü?°…÷Mooì«„½þÛúô‘/~±ãþ'放^¼Åù·�oñÍW(à xÜ}‹—· p à ö{lyß¾lußÕû±ãtl߯ýÙo o®;zp€óÞÆC|… äo‘¿…Þ¢ã}ÿçÞ$†í�Ðnï9’B»ats5Ë#>Ívªö¡ÙãÉŽfÈñ5&¬õ©ö o‡ö}æûvŒg ¢oçœ#_>¦ß)�™Ð&—fçüæÐÇì1›MÏãüü‡—Ÿšíµlc9kÇ@R3¶õ)2™Éɉy•r¨˜•–±°X ×M°opÛw˜¯EC…À)¤^ÕDóÅŠ£-ÝÌÍðÝUšª³˜X8\Û+W™çjL›°˜Zo•JHtÈLZ._ÖÜ–E\E½‰œÊZu‹ÕøB¢€YÈ¥yøîV†™L• Ø ¦c†âðjQ2ÂÎN¼6 Wíi³Â*\îXz£ç49}ìF0àQÖKÍ‹ÈBÙ @ù”=©Î™Iu_¢XYÅy™¤W3‹U?#)ו2 RŒpت”èš(^Ž�,l\Ê€°‚‰qº,GJ6mí[«frL«iÚ "=XÍ ª„uá\بLjHg»ª¡š³Ujq8&*µö“`¹¼Ê*ÜËšI˜×s>#Ô¼³‡šgðl5 G‰X–êšgPò†Â˜•5³v(­t½“ÀXUU³L K*Ǻ.g‘²@Ø"ã.«W.ìødÑÜÙ̃t“-é­ªqaˆ¹‚E^"ÖUØšØefœb8&´Nÿ*ðîfJ™3Q`0šÑZOªYJ.?·ÃÂ×@Ä8Z+~!•ëCrI¨Ð§‡ñ Þ™5µa,â (-“)ziHfÌÐ^yj3­jÚ–x=ªœ¯ªìdà@é’Ú•ÏÏï]š8ĵMjãAøùÉÝ÷¦fŸnè<œŸÐn‰Ãþ6¾nŸZœßéãa¾zù7âv°°íŒ¿œèÚð„ý„ÄùéÇ·û~sxîù� w çüb‹»~i÷û.à€qÀ˜Øß_áŸãáïøÕs½m³g¾Îƒ=#Æó´|¾‹OJ¿?Å—¯ñå-¾ø·‰ú|óSÌ×øg †ûþé¡(Ô„voó¡ýïè{,vi|ÐÃ%ñljß$~VÄåüEÔ]]òÝD¿À3pù ¯€›ÏÑÞ<¨�;Ô¿ÐË;žð¯s¿^šm­¥ûs÷‡öïg{Hƒñ¾ð „Ûÿ* õóçú´ã'wš7}@0hbkïK¨ó½Ùƒ„´_­HW4„_Ú?Ù/ÊSu+;ÔEcN§¯ãÙÌšìltJe%ƒõŠÈÖœ)÷ Œˆ\‡)/c@©B.‚§°*̃!3‘ÆU€  ¶¿‹›¯+ l™ºìŠ„^ÿ4.¯MÝU}^.†ÅvÖw¤8ýG@·ò;¨*ÁeŠ\gFh–Jp &\(¬=_ÉZd—T ˜kÎZOD9lc¸irŒÂi™—«*2Ý,Ü—Gl ð…¾tÉAÆ Ť yÅ"`§W yÉ}ã5ó›ðÔâ%µpÎLƒO¥oüÒŠò*µÛ¢_GÙûÇ+*ÈÊ[°ÁM¥ë°Ï´€w™—ƒ‹P"-ÒúÒ\; ­K6Yø8רY¨iHHYsÎÚóâ€Ͱ™dFN`#‚¼¬8e­.KìB\²¶9PµU=æ,’ÞÌénNɲ,E8Ò‰Fô20Ã)R�UY9jzÍE'U+ñ9Œ¡ò9tsΜª%'5÷œ—" ,™r…±b›ìW9ÉÚ çP^+\^Y_;3 Ö„+3lÁÏ ˆe¾¦¢æ Þ 3sUðš©\V*0BæFU˜f‹&Õ`4¬âN ´îQr_“ÞBLU"§ç(\ŒÉ5¢ª\…Uëf*vÉz¾®îª`­Ê¨\šYŸ°_||•5`ŸU{uâåyúÄàm3Õ-LaÏ<Á*OÏ/št¯zàøWQŸíÕ­ÿÏS¿çeÄþŒO‡ÑçŽøE³ö"âôÃc1ÏÐßÝ9>úÛwøê6þj»øÍ~ëOGË-ÿÝ|<ýÔ>fçÇm<˺4Ñq×Ïwœ=.»íà¿>Ãåªðââøx<½…÷ÇþÙÒ_øly>~˜½Îµ¢¿Üþ¤wÀ;üì+Oè7Øÿ Ç×øß>ûâÏâÎf³ñ.žÑ༫›FW74{1r> 0Çož€OøÍÄe8å]Î;þñ–_:ðxG<ïØ€-Ñ>¡n—ÊðŸXuìû¹%nÇÞC±MøVÖçæ(}¼kj[½ã|´zÀÓ§<Ü]l~ð[ùo{¾ÇÀð±zƒ Œ‰¼=MT”¬%jöê¾×~¸œyw¼x>·Ó®¿lú¶²¦¥Ÿ³³o<ò|[è†æ&±Ú"b/€Ù´År#J™PŠR‹>Ì.fkNÝŒÍÃAÑ|­–ÍmÑžc[ VJo-+ W®©J믺¾c“Ëu£}!’ffÁ¯9U8« ]š’'š˲¸x­•5Æ(CRj22T.©ÊÄ]Nï Øwñ”zÎñ\˜�æ­n颢(Ѱ-ðßðP"- °æ4g}¢•:¸ M)LŠR¨Ã5} Ix¾G¸ê#Ç· %×%ƒ¨*߉oe%é^±F^^4Á¿£è­›‘å*2W¡JF-Q´(ܼ±—Ñ3Lš³J{ÕTŽÂ,�ˆbÎèlF‡‘,ÐXr¬8‚¹*E£œIÌjq CÈhnæaÖÂ^OAWR5š-*Èwˆ Ú,pRÒÐÜçÌeû–…DÉÛ©‰ò9¡¹æùsΚé)ƒd†±V™éMÅØÒÝÍ·òò|@I¼Â© ͺɜh@�AÒ¸îm«¡ 36÷X¦rwª’3KV3A ŒfŒÕ(œaÓÉådAH¸™kaaNƒ²”Ša9Ë'4Y“–l…eWUª,=¨F¹'£a7ÖÍ¢,Œ¬QóIù¨¼H¶·Jÿø‰í é—8èÉölf¦Ô4<ÍŸ`?”ï1ü¡>sü ÷ÃŽ)Óÿx¬È¼¼út<>q|î£9¶Fõc6Œÿ~ÃãK|yTÿÒÛ[ë°ñŸ×y«×}zóaÓ÷{ìKó1€‰ûr6Îî—>žÑØüù¾><hC{Â8:~øò‡Àÿ€ÿî ‹÷Ÿ5ô¸w¨vÿl¿Šï}ÿÉöŸ¾‹~‹¿ºÅ›¼ºÁf8Ü m8¾ÂvÆ»¸S¿›­Ï¹ïk(ÞMïÕwo´¿AÞŸëaN˜î_îÿÓÀ×üï…q¿©átûí‡×·ð[m 0ñSØkô†v†v\Î_Øö“É׌c"õü¤ËÔöÃ^íý0ê8öãÃó|wÐÔí´ÇDNÐ`q‡üÑ?Ùñkè/_ ·þgè‚ÊŽy¸›‰Ù™lg¯î`Ÿéžìpòö ¿T<•^Íy[õñ¢q>óÉÊ'±ÝNò`>-DÃ\ªæ! Æ2ô¥LëÜ’•9È¢]hë´uk¾ùl¡õ 4ÅÕž,"©U0¢Ì¾Û+”X´ Õ éz€«k= Wë;PB¢fÕ%sæ`ÄJ´cúbÇê¢ri¨ºÊ„XÎá¥}œCÉ*ÑüAò"ea݃adfô>ã"Ë=Q^ ?„oôNyáúXþߌ´i2Qn03ZgÈš#D*j¶‘Y»g±Ò5»ãì™f­Ø¥Cb3¾�ÏYš•S¨ÕÓ¶^aŽø©¡¹¶VXÝB å´4ÐKd)¥QK;¥¬SU‹ñD0,¸Á מ˄ÆÉÄn”=h-|ó¾ÑàDujðJ‚¨šK·4œ&º Ê}¹–èÔÂ>˜S«™¥^i×ëÀ••GÃjh«&†TUµç˜5gÌ›±\Îu¯fÕ Ir4ažQ5/©Ê™5•i2æk9påx)¦@8 ᦕŠ+7J¢/¬¯~9±9ˆÕ&„ÓœK­'`%ÕúoWmq½ÖMy|ÖKtE©I3Ø>a•ƽì‚(µY¨ÊÒbËÂt¡¡³¬Ê)CÜ'··Î^å3£ž@3߫ݎ©þ„ý£>òñûqâ˜lê°}>ŸkJ‚2u™ ¿C¢áç–ý¨ƒÕMOp³ŸÌ×_ÖvðíñUûÞ±ŸÂŸÇÞÌ"Åq˜é6°;æ¡í}Àoö½<ÆVu6ÔxØ ç3¦}qáÝ%Ú‘ƒìÂNDö£ »}ÈØß£_ðêÇÀ³ãËWÀ Là3qÌ'8ö Üñ{ÄÀŸµ?eßð¸3t¢9@èž8à¾f›èŸfp/90{Ÿ£ïûMëvã᜿x {ulÝÞ}¬GðýßãÃÞÅ'³{ h87¼ìoïÇë|8¡g Ý]ú8¦¹YsÎØÿéü|(ß¿y:\þ`íqüø¾zKõ:w=¢f›ã~þ9æÖ¸›ò¡Ÿp�;æéúçRƒ¶ù;ÇSÔÄúd˜Žï;ÚÅ6ßTJõ9t04'ÌöÜghÓlýÖÏÁüÆù I¨ ÆêX+7'¬à´ÅÂPV]#¡IîÀ®ÖÍwú1ÚM¡š»ä¦–ò*‹2˜Ñ#Ö:@ß :’×à‘®ú†ª+)kwŒ"¨Ê‘‰œšc¤¸¨Ú¬Z‡9j²Òs"gVQîÒÂòMUSsšy’†&RôrÍ­5w˜eÍæ¼¸ÚÞÆ¼$ÒQÆn¶™yM×¾["åË.œÀ¤†UÊòš2õf=ViË¢U“•Lµ}°¦cÎŽi¯€{‘tW qËP9KÅ„’KJ×ÄEH›U’9�[~·Äj»•q̺P²¢˜Òœ™»dpЉf4‚fl2ǧ˧)¹™¹¹_ÅUËɽT<ZÂ%¨H+ÆpÊ k�� �IDATJ@¢JšWƒ;iåœNw’ÞdÛr»M«¹\âërˆB­AdæÔ¨9÷Ë3³›m¢›̰u‚Ä’NS§kOŸhÍÃÊÙsŽ9ózÄ` ?š,`öߢdæ-<ÜZÒrrýE›îéî½ùæ"’™`â;¼íª÷È 7+[œ@šÃ!ÒPtš-¯I¥Mh³N±>*ZÍ·|VSÉ’¾˜õëŠÝ¡PZ]]˜¹f DÑ3è"UCÐæœ/ç@þþ8~wszÓ÷Þí‡ÎJ\¨‘JÐÙ÷=fÆ¿Ûùþ#ñz~³é§QrYw;êöeÛ~6º7¿9tkf8#o Y­éÖÔâ´å震ñûí°ðêÛ ØœïÎù¸?½ÿ”øööîæp÷2úÅ÷W`Ac›ÑÆñv€}ömCýŸ:~Öñ,­2ú ‡ O…;�õþ¯pý'ç”~ö¶†¾¡ôÝ­,ˆÃùÁìÝùy?=áû->¢á)ÚxŒ½Îão·x‡w·ú¼ópë0=ùN—ÂÍ©l<ͯŽP?íóõKÜþ€Ç/æ6w<Àé¾.­¾oŒcbžTû«Ãþ<Æøºìïø—°ƒýÒæn˜ÿ¸}\îö‚ü—¯£¬ éy©Ãxa—_pþªvì7ˆ´#Ô ´D ùð;; öù®vJý›™ïârG6/ãZ<ÆÉ.aöjm«îõ̹CϨ†rYG?Xïr7_4Õµ§%h¨>•J:#lÒ„ÃÓlAuborËK]"å>-è͸Ôff ®“&\©Úµ@®•™™™ZJKæ5´šmNäL©Ñ’X`ƒQ¨õ–¼v«JPÊZ %T@r–l¥=%×5±äF307_Î_ÓèÞÐ ÃP«YeÚµÆóDyUi"FéRÜé²ÿˆy63Q¨©Ú1“å*i£bîÅsQU³AæKÒKQÑD”­ZZY¥*¢†Ì÷ÒDŒ‚»2HÎZ~·a=°AMæ»lQáéäœ5GIri+c0ˆå`2CÀ*šIæwfã$“\�)!‡jXM’¹Æß,[Š2˜ÔÌ+Û(Êú*rÁU˜ Í"¬™9ÀÔ¼ä€KKA·æZ¨Á9çeÌc<«Ž°7´†¤¹_¥Q`™U¸çu˜9A©™B”fšMîÉ,}Ãz3ÑSUJ“®,óÖ[o½‡Ó´ÖeXI67c#å3ô8tßÂCV‰9«fq‚+Æœf`˜u_u¢+# ¯2TιGÎYØjíÂÖ&|¤(q.eÐ"~‚E“™³ JàŒ¤u‚DqNCÕÜ£rÎÉfÏÖ¶ÑÍXÆl<‡v˜Uþzéó2^çseøÊÛKÅ‹¢—F îÎ YékpN|ñbþ…UŒqf5©)è~¸Ã­Ù»s×ydÌz‚“ÍRœÇOçÃ?øþ±ÌcCìæ@ßõ— ö¼·í{­¿Úzxø¼ ·ÃûÎ CÈ?~ ï Ñ pṵ̈M ááG´#Ú†; o½þF÷?b?'ìG<vßOÜÑêq?à±Úÿqüæ·õ?ý G´7oÇøêñ÷wùꇉ­·x.Óh§vÀÏ3~½M8~Õñ®c3œ}¼®úÌ{üˆý¿»™üøž÷N÷»¿únÛIùoºð‚÷[<ܾ„}Žöý/ÔïB'äá´¿þp¾{<?á,|–¿{cocŸÍ¨ƒ],i°#ââ`(½×u¾o§:<¾@‚Þ·æ°yœÙ}…ò<ÑwÛ+ºÛÁ#&mOÌQj´ƒìÆâ†ýÆÝ®4°*Ô$œ¹�YÜ•ŽU½Ê 7W\{g˜ã¼°Mk#̃ѪµNYlXö€õ7â?žN+W…mל*-†‘dXAÕÙTa6´¶ß2ÁV[´P.@ƒš�ûd0»‹ñæ,W±lá‘Jðe‘[Í4ƒ»AM¦%ÞD¢Ê3!¨FÊÄëÐKÔ¥l'•E…Œa+‹TU351§ö]eÀøbíÀT+'ìåœkÚ&”rÉQ‰*/zÊ.*9 sðv %ãèÉ’kRkèN2%Pp–’•Å”÷ ‰²F•íCœep#@§ æðAœd™†`RÎ’e±†Lˆe9+ËE/u)]“]רX£[Ŭ…™@GsD³ V.u*¹kTí£¼h¶hv“¹«f&.Â�_Ê#g²•`%s¡[Û ݈*·ŠHrBªŠZ±9NNÆ [çšý*û:´è½oýîPÍœ³J('Ü#ÂÝc)L·h=Z¸Ã*¥YœeS6d£4*„,ÊWÆbC!€Pº¦Š{r2K¢¡&4UÓl•ú×ôÏVtÊ}Åin¬“ V¹›P¨–ËiÈ3·ËNûr4+&Lgbw}¿7ñrÆKKkíbö=VÈâ›Këj)lç>„ÀpÏq´ÏÓ¿À1ûË™ôi\©/ïôî7— ™Îõ¦G'RþIÙÒ1!«çQ2ÎþîèwŽ›Ú½š ÇñÐìæÞøðâæÝ+ÃMw«ætÍj$²£·‹ßÏÛø—û}. ¿™€ãûB,_Õê�Ûð²ã¡Dßÿ”îÛ7¿€í-.ßü�Uxñý¬¿°Å=N�Þ|…[à îÛWãíý7ÕžAï>€yI;EÖËü Íße{œŸÞàÛ—…—j®#Éc`;]n¾>=·'¼LÞ>ö |6kƒ_?Ævã!&n^¢½€¿¼³~§ì³öú|ßÿ›S÷gÜ$âò¾ß¼9ð`íX›ƒÈÙl»Wˆ[ôØtŒDî8ŒßÑnÁö^e÷8<X€9A!=ÙŠ.ØÙqöŠnÕz:P»†³™y³Ñ7F÷8x8Y‚T»²$ eŠM¦dKö97É l9åY9ædVç²IOºÂ½Go}ƒÿ®Ùå 7¼"Wß®ÉXb Õ®*e®ý#�À¢c!…H9]2À4M�Ew[&cw9Ó Q&7cs.ÿÄw–”„L£(4‰«¬'KqÑÕÂÌ@TVF†s&…Eã‡)](qqy–¡ŽââF%ó"U£ò EGu © r2—ɹp)|,œ¤FÄzz;h‚gªNi=í%AGšJ5«jÒ*½iÚUôªtg%xˆÖi^PÎ:sO¹4ZÝŒf„ì»ÄðúÿB¤0K©nFw‡K6aÅŒZ³ò´”& Î)ˆUJÌmÍ|*żº1I¬ž¼Y’i™VUI˜MÓPíœK:g¯`GXIcÄtkbP!FÁ=¢‘]jöÄy¶º¨†Õ‚úÊ*T¹UÙõF·jÝ<<¬µÍÍž%%*K˜î݃qõaÀ™fáf+ʧº¶uÖ…gíÔ ŽE„YÃë·Bƒ©±&¶Îé–a…Ò,ðÿpö>?–%É•Þ9fæ~ß‹È_ìª&§k(õcfZ@½ ¹àjÄ‘mÄ­þ½YŠ €ÖNBìh%Z"•„È&UY™ï½ënv´ð—3[5Z …ŒÌŒ÷º›ó}•YL‚æžäú¤-ô¯­_šZµ¶f”äP+æD€UÍb9÷åù'‰BFpþ´t”½²¸YmmÂÔsƒ-7¯mÌBËì1Ë÷ÀÓ¡Û ¶›K?¬ÒDÁV€ïlIc˜ïeU59uÄP¦ÎÒù¼N=ô™96>žë~°Ðq6îvéuª’©bl·›ÃÛvç~ë(“Ù^–;}¯}°?°a¾y{Ùïíy¾»ì¨÷¿0¼h�0{a6ÌÂ$¢`Dv½ýÝÝð€ß�¿ÀÝa;và2¾»ÅϿū8 à‡‡ã×ïÎsÄ©MŒïÏ=óÓï÷|õ{ç¾3 ùž÷°Û{¾™/ïÂoHγÐ_mýñØþùíýÿ³÷·†f÷-< „Ú¹ƒD¿h°^ÕaÈíSîg<ܱ‰xGû©w*w¼¸<ôðv€w¬Çõ0" è€P{@CU÷Y³€B`Â^¨Õ¦nW§fÙT»iÆ,h:Š fIª¬´`sÖàëlØËÕÊ0" Z $J&X) E;›]Ôè·θöÞX‚˜•³–âMæ@|áí%!š$­›ÅòöÒ—åÄzŠ­hl 9° {-ñÝvk\7 ¯vR­1HI)_Çu…1qùÍôåý%2·r‘U¨x£»ÉÞh«¼tqEMͳòûMðÜÂÈÞ#"ÓX-xr'M¥:k\POŒGS³rË4‡—3‡ûtIsC‘*]$%rbSjz¡¯UO@t\íBrÖ9G]�+ïtY ù5ˆ_XP*p_ʤB¤§ã@6wÂVÈŒJ„œ4Ù¢¹–4ˆR)¨R[¼,`Š39GºÌl]+“šQSS3URq”âÖy0Ï2Ó ¤^f·w3gÐÔ«u˜ƒÉj^ù\9¼(™Ñ$s™•ÈéaáqèîÝÃÍ‹-ÉJ娱Ï}ì¢Ð›Y[†6“J)×çE5¥` ô¥ÿ)[Æ'1‹¢™¹ÓÝ,È­š«9,8YiUUsÒTYÈ›E˜_=ÚV$a¤‘á4zFªBVB •XI¿hS9•Oâª8……»ée]h"Š-*d-g»4»X¥¼-J€×4'û|Ù-зh}7;g›sÎ՜ɆÊö´û…ö„ù¸gý@#÷CÅaþŸ'ÏõnÛw~‚Zœúüñ lºm|;ü=âÍ…¹M÷ËàùÜ{ÕócÆã^ »“ßÍÑOÚÇÀÏ/xCÜnð†žüˆ(aëx ̦»"£ûÀ›_£ÿó æŽÀxÂw®Ýé 0€ÓÇDZá¬O:Æ17ww¿W/ûÞðéÒÎÏ÷o¾z˜ö‡oGóSŒ—ýéˆÇWûw·#úÃ׉Hàò`~=ý.h>`¾DÍŒwª} œç®múÃm‰y?b€×Æ¿³jàP>ªCá°õ„֠ןá~O{ Êîi˜|¨üsÌsØqi5«¬tœ Ÿ0mºÊPV´ žVC6Ãg38d ŸØªjeî&cjŽå——Êž´Iž% gը䒻ùçÖ< (YUÍ9¦ÙàB*|™"•ÖC6ùõãw-ÁÙÔª>`Õ Vßj—`jKA@K³]Œë…&ˆH(¤Nupu±›Ys÷E»Ôq]ÕÕǰº^´õ q&4 ºé¢ Ö Ók*á®(•X3<E‹º¯á‹5˜#Ç%ƹIA™†ˆnå΢±Ó.‰™94çeåÞÍFd‡¦ J“¹±637 é™ÖK%iÕÖ¡i2+"SZÕ>ÆÌÌ­r36k°]Ð̪¼NìÌ›ÓäVTÉF©æ4\Ì$©hÖW¨b¦¥×´•úJÖœ‰±s •— £á@öR[\Æ= 7NÍ‘™…9­¦MqG¦å’Q4õ6œ\�¿U `CkÝâØÐ:b£5"Pºy`Œƒ *©t@2¡±ÌCaˆfÞ{´ØÌÃlñ[ œ³æÔ¾Ëe¿ä –…#)Ét¦Š…uÈ©)ÁÌÌJ×$Åš«UN©ÜÌ—·4:J ‹BÑ £5p²ŠT$ÝÖ? |FƒÌŒpÚ‰Mg #«æµá¹Z›©Æ1,³ýÙ ³µCÚ¼d7Ø+Ëd6+°*éû´Ó`ëu¤ z3¼¶¦>nX 8i&éÓ8Æ|*žj¾@ cø6:,ÿÇq±ÇÏãîïu÷Uu'^ðØo?mõ.÷#ΗKùEùi÷ŒÍjþT[ú.°‹3-Ž'ôž[ŒKÇLœ ±ß÷­¡:fç—sÃÿ{¿}óÀK `8Οр|…—†b?ߟ½ýSÝ×ÌpóÏGìÿsOÀÇ/Ýi €À?F{ýþ«À÷¿Ý>þóWïâÅî4ßkŽçx8x‰Ú°ë½ ´Ó=;îN·í»ã@œÄßíèóšÞŸ'öÀ,ìÀíò3gà´·Óy´þøZˆ„]xŽ·ŸÆÝ1[Öè~qþe:f[§XA;,¡Vo½Ý mê/Å—MõîR©|ê1ÂgRF80á—]ry£n¼ì(Ĭiûiž&Ö5º<’Ø•¥µRSíà(T&7¹Ãm—FÒX†DUQ‰6Ø í€þý†±ò*åœsÑõ¤7°B2“QîBÉWôX.“„A²¬Z}¥dØ.®aðz– àhå^‡R£\€pÞ“×XÔÚd[%W³% ÍKRŠ)ËZàt«ÜÍW\Š#TJaÒ"½ %Ä$³æ¬}÷‘¾-4¸ P.šõ(w§Ae£0çÒ6Ó 8(¢ÖAq@Û* Â8ˆB]JÍ ‰WwNúªä9.ðE÷ ËÌÝŽn9± ¦!‹²¶8ÞS9å%˜2¸ë*èè°}Q( ½j`B»rzBÉ,íœÏv9á|)ë3n$ÔÈž¦YóRsy^¥¹ÏÚGΉ)L± B !DëÙ‚ 9a4‡ñØüзֶÎe-µ©¼ˆî?´)aE/»r¨XœjlaÁØÐ6÷-"Œþ¥09fîû^—}ìs¤P¨Ì9s÷Q^0fC ó^°tY­…Q,…|‘ÇQRU–²ÜØÀʼn1@k­_ -E™l€ÑÐá]Z>‚fÍâ:e�ƒNí…)[ÐBæÕ¦T¸¤gf×|yŒÚ*¾z&°Sƒs§Pƒœf§<`¤}š8~<o‡’H¬Ü²gkà&U+˜’à>sßuU#/>Ø9?ìÿšŸñðùtš —þ\ý»¿Úl§äù¼̉ílø+ùÃþU™O°7Ë?Ö~,pÔÿý1ÿ¥U¯›ãaž¢˜;¾i·çwžûé„ý‡Ý>Åw—‡Ÿ�;p^ßlâük´_âö"  ß<ÔùÝ?Éß�¼^h'¤áçßýøÍ=%ЀŸþ>^Ý¡5”=ü$‘·ÇÇ`´ãd±F솛Ûƒ€i€ß¿mïß%þõĘ (±TÔ6pø€Ñaœ·÷;0ìÞãáv ŸÐ:ò|?çƒåÝþ|7ÏÜañ £cÁ3áÏ0 MÀîôÕF·ËŽÄì³ï¶cŸãåÍ(Ò…4Ž=õyê¬Ë7£Y ƒyù IÖ† û<«ÀÊ:\ØXæ—+“RÀ"µ)KY•ÁÚé!'‚‚2î´Š^èݶ¶ûfíàFgA¥‚t-¼s€;dEФ,Å’ ©‘$‰šd²¦ˆX¬¢’,‰ ¶9TÖ%ú•ÏO°(b…í+¥Äµ5aÀêDÌjáñhP,Á +µ$ÒZY3z ëL¬Ê1ǘҌ¦—¡òj–?C€º€Š**•Ó/*3øJjÊVæªb}žé—YkÍ¿ÖrA4i1ƒž¬âJÑQsî'ªg‹ÖšG„Y”Ê\™eEZhÁ®ßVT+€I_ÅÅ KêԘµ[î9' ÏÆ‹gê3èe57Ûœ±t7¤ÑP^£”5X©š9•S£TUÓªDcÊ€¶î4°€‹±y´ˆ›Ö¶Ö‚á Sù g¹(“¼RP)S%@f0E"`£yÀ;¢1ÜÝV[¼ªrfóû¥†0Á27‹2욬”GKÝÚHF_@a^ónÈå8]®r®ç¾Y¹-ÅÕ^4˜%¿XÖž,‚åU@Ñ 'lá PÊ–Å}µÝ à" ^Û /ò§ªO©^|Éz¡ÜŒáUûômZžˆ)±æVšôglÓà/.mÛ3O­vTîÑ.Ç0»Ý”FÉ—<Ö!Jå'û™3ôy{þlñ7Vï·†³ðùò`çw`ºµ:6†[S‹‹Ž~ÈÓVó_5ûýª7Y‡Ú CøÕï^â çñŸž½´ã+';ˆí¦îûÃ1ý ~y}þ_}{Ýñõ»ÚÛ{wÔáþE=¼ü7ØÎ@6 ÇòøøOy7|üKÀøyƒ|7×ÿñÍñ8¯¾Åñ·7h�xq�·÷TÝÓ¼p>![G¾"(TaoØ:~bGÃ3ÑOˆÝ1;ž2õŒ|Æë¸¸c¬}b‡ñáÆqHÄåm]îæ¹í—?Úû>ûöÜóæ¿nÉûaá&Ñ΋&‡˜Û½{óêÎ>ŸÃçô ã%28Ÿ·1ýBÂ&3í4bÿdùÉžÁvyS²ÝÂn¹S.ß÷8§8“½ªÙ„Mš˜‹To²X<ÏrÔ %PºšÎcYµ¼›!¼›,�µ’*ç—Ö“óúds°Ì#Ö×lVPªrM_3hzeXWܾª,Ë”ôX�X3†)•$Vy’¼ÂtÖ{‚ÐÚÆš% ÄJ@Q 9Ìœ.¹&Ì‚ª”onçðÙÒé¾9[p±FÕÜ«jŒš DÀƒµ£V;mŸUK\†a6ÑÜÁ* ©¶b« jRŸ;2Å!6º,(÷jQؾh}jùÄtÝ] %„¨YðiµlóÖÌ×øZ6S•,IU³rî9§ÖÈ‚›Š´„ ªÒ™åY¹$psøT&JÆ“ë9üB?¡½.‹²ƒÙEÍk)xÅ•'°æÔ˜S3çD¦æi¨ ­’#˜QͺÁÄ%vŠâ€h¼¢ˆ(°d‰õïU*!Kc"q[74—5FÐq�cy´+U™¹g]vŒ]sQE¬i5QÊÌJ­õÝÊÜ4‹’’ZÈ`“k-À�/·45JÒ¬Ê\|U_¿ˆ4ËIUðZá¹8Ë[ŽCc]ÕŠ5XÓh„™· B%C‹ŒD›f±šçš¥œ9ŸmžX½¼%zr¡Ç`çC<[¾ÌKŽÚ"ýl{âséÔæyªÝÎÖO6.…–“¹£¦Ìñ}ä%†åù'û_õèè;x„ñmÛÃmo/N/_Š\c!{éEõfì=÷þÉ.Ãûãôñ8Ψs{ù? ü›[Õ‰—ØgŽVnð9a?þy{q|ÑŽïà*„Þ¾ä{‹zçùhýýÜp \ ;pÆûßùÝðó5íÿcä7˜¯Œøù3¾køÅ·xó¯€m ”�ÇÒv`AÒx†íÐå`€íqÂö‘ІË³ÐHø@{†�¼ÆÞñ¹€ Nô| àÂpt…~AÕÏæ<>]ú|Þó3ÚØÛGÔ‡}ÿÃQ¯NŽðiÀ 耋=”¿»Ñ®¾Úã ÙvYÏÚër›Xœ=³=Çåoáù7äûÒÛyóÀŽþ•mlTTI°Õy›-v7S¼0Ì”C¨ÅÂD‚Ì\ôšF4»rõ¶ÑJè*¢s Q²4Ò8K”¬Á´&ÿ‹«0`"+œ–²¢•æœi6`ˆ"]¢•­ØwV«1w”T,(ÍÓoAªy#!6AM'Œùe‘° ÎfVf¾FN�$b=Ü¬Õ —™Y"U^ÃjDk ,hFVÎÚ™…,–œfæb2!·Â`íÀ˜B!P6kHEb’Áj*Km4m†Äª°]¢së¹E¢ÃÛ*ð‚J§°R, `“• X°VXU+¿i ™‚%åžshŒ—ʉµ&5V‹ÕYQ°ªˆJ K!Epš̆YÑ:×xK&DΨ4ª‚ƒZjOä@Í•  ¢ý.9L¤9¬@P šÓŠcµ--&`UU‰,Ô‚D‚«“€fQ CÁå#4C úŠa–¡ ×ùϬº”Æ@eX¦0£Ù 8•J•¥¡ÊÐm­XÔjÕ,v leÊ[Èn æ¸Â_R5¨iVèšU[‚‹gw½ŒZ‹4[Ð¥õÅpÍÔÕz¿°ÑDŸ¶!Fåk¯'vCRŽœY£lŽy9!ÏhMå3¼"JaùÝÈÿD|5­™Ôÿn{ð…õËÅì =¥]z9Fîû.û|Žñ¹öŸÆÔöà߃ÿü[ø /î^µ­»‡dñ)ëé¿>æa6dÙö×õIsÜÎGÃÄË…Òû�æ~¿ÿÉû[âÎ÷V>ìü¨övÔÝÎæç?ß³_÷¿ìAto[üÌâHvÛöÝ0>ç‚õ»dX¼6àäkœo°àÛ‰?šˆ?¸&”°¶§ˆ?„^a‚hvA=c¦pê 5ß"^þœý ˜ýª :8á�øá~@¼ž /Ç_bûÿ ü[ÔDh†Þß:~–ãõ´ãœ<}FÉÿ~/|†>?ÖKq LÈÀ:Ô�Àæc f­Å¨×¬!ÎvQ\"ZEgó]öcåS¶_Õ¬Ýõø}øQ,UL;Ùƒ†Æ Ì™p`’Æ_„’HhbÒä %Ó,$:TwkëŽ` ™7%¥r×´ Ì(™ËéA²-ÇŽ Ëõõ`-íèR®ŒPB€hKícXq'Š úy ÿÙõž/0õeyQ2ŠZdŽÒUl¾ŒÉE\ß±¥ ­à,š™Ñ¼h“yÍ'¶B)ˆI©1±H;ëg~ª0´cç*—/!<%]G¥ªò-)ˆMáåJ/u©!‰¦1Õ•ÍN +W÷zÝ‘Ë9v Êx^½bHHò*S:dG§c ä:ºRe5¥Ké<j\4wÕ\hC©’R””a²”u©�k ¢(ã M´3äY¬\ú­Â¤oòÞ–žOY™Usª¢°ØL0’0W\J4!-l"}£ß2e}’PšRsä„®¶©¶¾ùëc‚äXÓ}®¢¥L­!X„©Õ•·iP¨0Àj6VoßU.�á-¢¹7Òë xUIÓ@ Q+7vU¢É¹�3U†ÜLf°õû‘ˆ¤S0&°>£+í+_R¬ý|Mi�� �IDAT5gÅÊÈ)-¥Óä^£IG®Œ�{fI8ÓËêyÖ¼¤æÈJ™’31£íó¸;lþ«mfC0¶†÷‹ÏÏõoÏPÚÌ‹}>§…m¯Æ6|\„[ÕËÂaöx~gO‰i—‡7¯ï_°UôÆNìÏØ?×oO£ÃȶGãã!ç‹Óƒ}†îÖnɧ¶=lø{ˆû9Ìñ\ïN¸ºÏý4aßîo>¢³7†c–w«¾ü½£î/þ`DÆ¡ð÷¿#3èÀþ-ö†= ¢OÄ|Æ›È/×…œ 0>ãò#Ž„ Ç l ž†ó—†vÆé ÿ#Ü5 avìÄ øÑ±Øq¹ ÚÛ6îüк½£Sïo9n¾ÂØ€ù§¯¡O‡u�ºSåGºGäûåñãþË¿ÀÇûøÍƒÿø%‚ðã¢¡Ž°[4…}¼‡‡ûÖ*¡Äœ÷{>L½»ñ;ãÅóÄÇò_¢ÁÛ½Y3¡†+¥‡õf´I‘rvÖ0:ËaR¥4U³r”šÌ6î­»Â7©–(§’ª‚.iÉØ:Z¬Êát7#Áº>è ­ÆF8r!D#¸ö ƒ9 %U€Ž ªS…ªEó՜嶜”e…•¡Fb`©vxUù•ò½Ü^×ôìb·Ù:Ú¢Ä2/‹ŠfÙÌK¢,`$J…&j'­®íº•Êrª§R<É1¨)w4“QÁ•›_ðž*"[qÒ‚gx65¤åU5¬Q’�æz6by ±þhrgkpJ¨šUÄ:ÏÔ¥ê”yšØS£àô[K©l&¤$T–Æ‹VdŒÍm•ÃŒV´\ŠnUIKD9j:ÝHÄ‚o\¯4UPqÀ.˜±Ì‹Ì%aZht\nŒN»1;7"J5•–¥}Ôœ¨ä•8¶&M~}®Ƭ÷ò5®¼¶Å $³DùbøjuÝÒ`ࢵ8D77™‡Ó›ÅU« %?{åK`²/­Å‰¯‰ÄLJP:ÜMF-ù¡Lu¥ ”X+Ժꚭ°Ò.iá´ne`’NNJ Ty«²¬&(1)9oúp^$Õ¥80¦üäí’ÚÆ×¨5{lÑšùr¶µ«ƒ.´~:pë~°Úvx/ß49z3žñùHÜñ>µã»Þ}¯ŽKÛ…¡ñ€‰§ç{¼€æCn'çkm`8rb�ETûÓ]¿jŽCÀ m>°aŒûΦÑÏÕõ)ƧO/>ìÛ/>·a·Õî {%rì‰áÛCwL"ðg·ÏÖOÿ¿sJ?6 ÀØ×À„žÁ‰öŒW˜¸ò[\>à xþøÉ¯¡_¢t| —.ŸÐ¾G¾Á‘˜/që(bEü`Ž�šaöÄ𻺹{‰Ú­L¨ã86´o‘`‰Ï5°·û°ìpÒ³Íyºèq4 Ä| q�`‡9Dx!&T÷ܦÃ'ê‚Óé»yŒz~Búãl@»O<À ?÷QL(W,t$ûayµŽ[lÍŒð*e•qn”—q ‰ÌõÜwƒ¢Ó6Ú JRÈÂÔ+J¬išÅ¡œŠMp©W¡&kÝûé4‡¹Ù¢û-0 fI¹‘$™VJ# \‡ñr0TàUS*B±ðÞËÌ`++¬ ˆ¸Ð0\R‡Õ‡ãš;ûõ¼©’¦a5¥‰«pƒ*h‚Kx³ÜgAõ@1!LSM(×£>V o„4.—QCt¹Ã`‘>–X™¯¦,×oä«ÉÐML³fá-É)æ:׊"0"­›Ë›WC±Js¥C1 35kmâ‘*MD"ìŠTKµ,fÁYÞŠéˆУµh\ÙŵJÕr˲ØcÕPat ŒiÖé2k …“€¦0 C¢È„bAZ»õóîˆõ—Ž{Íc &B¶*&rH¦+<ÛŒ¯MI/AʵiWÁŠh€VbÊŠK>1¹NtX˜ÌÍ"ä4²ŠsÉÉq{½eðe8i4ÑkÕ3!3¥Õb’…›­{žD+È8¯”y¬¯ÙÈ0³¥,Y›½Ä¸4zÉ«09³@®o›Áymâ4º{¹±Qù|^sP)K‚_RŸÕn-oi7Þ ðê¬â´ä±¬Ø¸áu³êJ,ßçí<”äé¦=ËõbsÜØñÙ†GnÇyø4}Æã%ßÎÓzsŒ‘ooö÷í|‡:|Cd¨ü·_=¡·ùß•¾çù¿o í�èöz·ïg÷gnýˆ¿9ÜMùPò?ÛóqœÛx—þXo Û·â]Ä×ÌvÚ~f° h@~D£Á¶o wí[½~—íñüõûÓÇ/%j „ý'˜·ÐhŸáÏ÷o~xÐ|µøX&ÎÄÇBŸ¸y…f0GñþïíæÜ[v?¡Uãé~ÇC›° à8Ð~î˜öy;޶7G´ÝâdóßñˆšÀgÄ·°Ž|œˆ?ÃãŠ^€ƒùV¸l˜ïz¬|?ÏØ¿Gúç÷¼¹7ƒñ!ñÖðnz3¼ƒ=bþ]޼ ¼‰‚ÛŒf|iíÆ¶C{øŠzµ„ Kcî•̲)9ÕaèfÞ +d ¬Š,áp›|M «Öƒå0c3ïŒf† üÊn«TÑRð%¯ô56¹˜ª„ ±–Û2(],m©=‹þ%½¾£Åœ0‰¾‚-‚{M†$'YÀ*”Óa23ƒ ªX:M´¼N¨²–©: r1 óZ©F$Ao¶ºkdôM,*ÑÁ"Z™nFC!d ŽÜKUéHä i ÃTDC6-¬Ü'¶èP—“<e)UšÃ›GTƒº_‰ºë1>S9&³Lé;°«j))­\óI˜K'>EX6íÖÂxÞÀz„{ÈmÚuaR˜:áB§o`]h*K^Ûƒfp£¹G§¹(&4w(`Õ“àÖ­½°88;a¬¤vi"/c^”g“ˆt‘+GÊú2N‚£Ñ–î‚ū棪²4Ód!´i¾ÌÎX]F+ærÀ X£~½Ï^ïHihL&ÊBF¸°‚Vy—/«É*PÛ ß­0à +!Ø5 geJˆÂdÍ­An¢çârÑ*ËÖL%cyA#-%›«É1G,󘎥,tºÕ1§)u©|ÎÙ{UÀ/Í5óÌYî`†mÓèUÛá!–OjV;ñ\ð½Ó'²åûa w«Mió5n޵MBø;äû—ãݦ»ùU²½ì|ùSŒ lЄ÷¯LwfqÉÏÈïa_Á�Û�€û#?ÝáyÃzÿöÎ!;üîlí¹ÆI—3ÿ² FxÜ]ìg;_¼ì·ðø]˜ ¹�€ÃŽùïqþ—Øpwƒ;Ýó«ý8Mü?¾Ûø ÀßÀ¿Åáq³îo w|nÛxçóxï„Ægd€Àxœ€áwxw±ýéóýxއ( 3æG8 oapóñíþénWSöq¼øñSßøÈÄ˶0°}�þó5Òì3x(BÛÝô»1»Æ~ÍÝñô õÛ·z¼Ë›¦ÃÞúágiGóNß5ÑΡgÔ矡Mô—qûMÃÁýÐú!ZcëljÓ<C‹UÊœI”ffÑ‚µFB$¯+ÏZãÍ5ë7­‘Aït‡­…Eø•GàæîÝ¢[4wkíùêJª÷à—±Ö쵄”OYÉ‹±Ê¢’S®¸Š®‹¥½øo…œÅ2% ´f` œf×Ð9¨¹€†¹6¤W°&4”Yi³0—‘‡™™ºÑPòYœvňÁÌ›£ ¿á5l«*N³¨åÃF³ò‚™›•V‚4(åò2£§[1`.ac ê¨$+ä±ZÂÛí‹7/{;H¸œ.ŸŸ>ö3y›¬ÃšyXÄu8‡ä2k{Îv™¶k?A†ÁX}2”4w·8°m‘e»$ÑËLÞ¥8˜Lµ‚l,Ó0 ]f‰.ëî±ü‰Q•`ÂÙ›7úvð~c¶±L51/Â^ºdí£&•b… šÈs¥_y¥µ÷Ár`ó?~ *,£Ï"GE¹ÁaÈ5a$W•€l¥® ºE—¿2»’%ÊÉ ¾ —Þj °ÖôÐ(­µ•´A AüE†a‚Ö ²hB"Ì;¶°\?–ëÿ 5Z°XHb²„´Â„PŽªU÷·ŠÂÒULjŸ©ö±¿hsw¾éºÙ¦¦,ÏA(˜ÛŽ›=¶š-'ÒÙÄšñ©æP SåÀÓyçþ—¶u:Ì÷ ÝÚQ­gìÒ龡µcŸ7Çfè—O÷ȇüç¯Q€÷‡ù³‹ÇŽ…çK¯óŸîßÿÊë¨õyŽçOã·7éQß´q¸î.y÷Œþ9÷g{ü߉F¼ò?›øzçá{ÝÖÜx±ß™ñsàÕÃ_£7èk|ÿO¸‰öæÛ~h½ûM›þ§?{õ«Ÿ¼Áˆþ¿÷¼ø€ø›à@áNíŽÑ;¾40ÏxÂýÿñááÛ?ÁSCmC�hžöv|—|¼m¸å•F¬Ø 6Œ¯áïÚ÷w8ô{ÍÇš¿`ó¡=áæ3â{�П`ÿ)žnð=ñò„í Ékò&·ûôv±~b§�5¶û²‡ À§»ñ×wã×½O¿?_‚íh0©§{}| øâÞ_ü¤ÙW[·Þ#¬šUØ"ÓTMJ©¢2jféâÚBhEúZSSh­Ü9š­éy‡mô 9aÆp6° 5÷nÑÌà nfXy \ q@¤kMm…’›@ùõ ɪʑkê!¸ÑŘÄuÙ,‚¸ì+4Yn4¿Ö-×µ«®æ,šK(P¥JTe‰RMÍkéj¨LáVŽE´¾œv=û]U5D8Bh’C×¢*éPiVÒ§IŽr¯æ§Z@ÅðK°ª¡Yu°íx|ñòÍë¾%Äé|¶š?~šH–i¸F-ÉfÐ2¹dö¥j®5Máå–”]ÿVÀ·•ë…Ãh#—ƒiŠ6-’ ¶avdƒò«T9¤aÚ'Ã3}ñWŽeq v¢”¢{XóèíqCÐÌ‘s¨ž sÔJI­U‹ƒTÉ¥B%èt�I§­`¬XŠÔ\(‘1¡¼V˜™¸ÊÍh0ÈŒt|L–å‚ÏÙÌîËB"$‹ë²pe¥€‹‘¥µMX×d#–‘Ë$´ó@‘pT†UDyÄÕuJ¤¡ŠZôâUt»¶€Ì&¦ÉkmËLæ ¦ëUXž,›YŸPOmþÅs3¥éX:‰Y¸Ù«ÊÛ®sk&ȪÊrÖ.­$+NFæþ<.ãÓ<?ÍÛ¿;ÚÕqi}¶£¬Kx•í(´­ëذY µê½=ð_àü—o+îšZT·¸A®—w²öÏ¿Ê?_BÄ0œâaüöÝù7ÏGôz½ŸnR;>ª[lßî7{Ød-¡ g=?ïù»eX¿~ò âìàÁÃ/ðîôaß¾†Mõ²w¼°w{D¼Ÿ'|^ö[Ø Ôï­µyèöÝžÀZÕ}âáó›·Ï?¹û¶_ÿgïPŸOï_½Äë‰Û@ð=‰yº®‡ßßqh77Àz’LØóýüº™zlj{8Í~ygûØþú=>`þ§×8Ýâ|€ uÁ0 &ïQŒwî;—±o66>ÈñfÞ-¿íû‡~øk×ëòÛ†[à}käAçoæxkû{8¶ø‡vü/ÛMô£{sÀRÊ*˜¹àh\kBUUbˆgÓÞ–é1$]åÜqåy‰ft˜¡ ¹D[;?ê˺ÎÝÃ,|)7×fùê|SeU*‹ëUc0+9Ö½@FàDH¦R%9™BåI .®E?å([wG9Êl˜i%\!lM×׿JPiP®òö =f•’Àº»T 0™Ê YsQnÈiî×`®6¥UiÑo„ýZbcE釹4¥š²2T¤hWƒª#H(eµ¡Eв)ˆVˆ¶mÛáØú¶m]`BÛ8˜^×ù)Dh‡<5K±*¶f­ZP–™{^FV[œž5ÖvÑ££§™of46 Á ëÕIG�Ë륖l`'á*u]@¤f©Ýt*ÃÏVb…*,}¥P×b:ÍÞÍéY™ûeäb2ÍõFÊLpÂH iªÎ‚`rn¦¯ð›™ ei«‚_°•`ƪû/“øò -AÇ22¬> BΚ‰„•!|½ÖÖS™W¸žH­M¨ë1DXÕNp}bWòèúª Hq,×"†¬ÛŽ•lÁ¼@s”ˆ« Kb+YÃæ\] €~DL³L«á’ƒSØš¾Ötè ƒá¼N†€½¨jÄí¬­õf¶†sÏ‘—KñÂqJMÖ€•f™öÆß~ó«ˆ;âF÷˜qxçò'^i9Úxðö/²¡7Ø„~ƒØ_âÔîÜïbv ©ºa2§ðTñ=;ò+\À†ç‰ÏÇ×·€}Û.m<ß<úö`ö®lwb·]¯âá°ßÏ À´gåéÂ#~7_4¾Á¯6âòŒ~þ-~ýáñçÀÝÇv»½ÜŽýP¿Ç¶7Â.·¸ý·Ð�?Cù°oï´í¾A}z~˜7ÀWwÿp¸ûŸ¬ã¼ÿº€3þ«®Ê‚�àøâáø·¸=áØÑuÌ�ˆHäÄðð]ö=Âöá¾ëˆêÐnü€ÿ³÷ù‘,É®ôι×Ìž»GDeetU7›]ÌP‚4j@-p —„Ð@Ò?¨=Ñ .g‘ |G€‹Ä,Ãþõ#3"ü™Ù½G ó,.$ÃFÕ¦P…ʨJ÷göî=çûðö{|¸Å8bT&¶‚½a^Þm¼?ÍÚÊ#ò¦cfÂÅBT¡òüÚç]/Vò;òï¿HvI$¶(˜å~oìöq»ûŸ—íÊáÆk3wA9{¬Ç­®JHq÷àÅ–B©§Â­Xq§»XÒLr¥"èÉkœ?¤ŒVç3Ю餫 :‘K�13#r¦®µ)I/4£e¥Ön ‹œ½«1€`Áú%<¶’I+:o�rà: LkœK¢ë¥~…bS’®AÁR×'Ö>#†4#/ À P¶–ª\í) dEºI€ 2iô+.Á\(‰%ƒŒf4:×>~¦®»{ºŒÙÖ<|EŒ…°˜ˆDÐTË ALÉqÆâÖ̃ÅÍ‹QEP‹ì#sFvŒÎá0Á˜fZ,&§TFÄÌ¥§!Ëz ¦R«@ákÕ®Œ1çZÁ+“œPO½&GbÂ,§HU ~Z¤.ÞïÄÄJk½")bDì1ÇØ‘p˜©PdR^rš_½kI¬V¸Ÿ5½]óHnDÌ„QÁO³ „ŒHºäôCn¹Æ?‰PNa$"]+ô– ›s­,A¬˜›9|-³×¨J4–•5¦p]µAÈ4A"Vö"32§M1Ò´èG2¯&päDjÅ|¾mb—©b’2 ›°³"om”9ÅÜ2üú=ìƒëGf›ù±ÙV§ \‰±‰PÎ2wö]³sì©‘£›>ÔÇÃÓý°Àöz>n Ÿ(½–7ó©ð!mH…döpiç¿Wý<[ÃT4mDôœsÿ//þ/Çÿüvƒ¬°·ÛÍ{û ó뇗/Ïœ8Ö§ƒªCåiìØxÆ|´—çÀ¨{±——Éÿ–³á pÂ?€‚ŸO”‰ÏÞ|ÿï'Pþñ¯Ú?âðð#g VãÁçùæk4€oÀ[À1ëÕ4ÊMB¨þà‡z<µ?¯íïNøù^í‡óÿ L!9ähwðW´Ô#dà†4ø€@ =É0X«d8†š:ʬüÅCÇyáØoˆ¶ò qsÏÃ=­qï° Z+³v3Õ€|€öTnauØVÕO|šú²`nùAqwœ7ožËÍçõðÓÚîy8±äE�BˆH]VxÝ}+^œëÒM–p§¹YsVÚznLZ“p’'r½Â8ÈeF\ˆ.V „%&õ‰‘9S35×ý˜4]§õÓqâN[OT7wp†…™McL­¥0è ,™\w²Oȼ5<¾qQIu-¥U+ Ö "Äu6äõ½ÂµpE‹N—Tš‰Š„&‡‘…æ€/v·˜B E2ÈIÉ‚HÉ@sÑ’žÅ鉕QU±E- ó4s$!f·He¾î¯~©%sØç>ãRÅEµNrDæžÈ‹’I®ýIº[­~jm¼^€©Ù‘ž*d‘[1+&§(´ŒÌ´¹rŸë'FJBÉÈTÆŒ>æH y&(Z8ÆšÚe°)³tLʴ⽈TÊP*ÑP§.Æ93±F/æf,d «v-¬dá•9v"öšqë–³ú„ oJ#ë`H,¶$Á´Œ„¶jg¹rÙ¦L)ÏP„,¸Î.¼S!ë,úµþZ/Ò¤AŸ£QZòTSP)Ï™×!4Zqš#‘=Ô׋«†åHuS¸ç §ÒTwGÒdtµbZù«–rܲڴ¹;2væQv ¿qL Ëd fAhËL|ÿQøý^†á©rúvn†›€zA­h‹÷9°Ùƒ÷sŃÕs”¿ë9Ùs£Ÿ_+F?o|,Þ3²aZ~ˆ¡9_DZœÝQ7Ô AÜ,é×3ô5æWˆÀeâ pÃ÷Í0õ0xþˆ ý‰¨jæDþ ¾è«œÀį/ø‹Ü‡7«ü ü­}õÈßô8aZ:¼œw°?V!` ˆ÷A�¿¬Óìyó×G;<¥Æ úO ÿ;ú‡6¾¾-W¬Í ,0 rCnÀøKà-²  Øö ;¼´|<k>º\Â,=:ò§çAÌ w'…–ðDãö!ŽÕZ£7EÏÓ_ÊñÎlk›UÃÅYãÁ*¢B·Þ|¥ÜƒÏˆKÕñ4£Œr(w§v{[÷^°C7ÀHÌHtâµä4«íð¦Ü™9á/³¼rí×ÔÜ|u@Ç:s寝¤#‰P]È&Ðhuµ D¥0ÅUf6˜"‘‰+Ÿ²X[5}¹ž1”ÑÜnÅÌÃÜhi#ëJH“ÏÅÊæ4ÔøÚ-"3e°*¶üG)fN¥r•¿‚>$‹ÑR×á�×1@ÀÒÑŠy1o2ÏU1 ÈÅtNwÄÊXhIsNw¡(<E’%DË@ˆkù_k ˆæaE1Sf3Fù8cÞN¹÷¸L¡åY†)P3ÇèB’ÙÐJ1YKÙŽ#‡áâú–ñìAÛ [Ò›¹;ÓƒLyÄ‚@”šôI)'cr„BcÆ1§GV¤sµ¶y…†@ÁÌ„r* /*!®îH.‚ÖrJåœ^TŠ¢EŽ™±þ5ż¢ÔÅFrK`¬ h„)5GÌ00®®NäuEÍu­Y^3×.‰b.P¼ŠÑÖ¥Ëà,K˜Ü!óIÆZAÍð9Ë䘄 Fè×àU6b×¶ýCËÅ�[E¹µ C–A„œÅŠƒžŸR{3sÌÙ=vDa–Õ/‘uN·(À¤lJ^‚9¬ažÍáÎ�w–¤†‰ù ܤ޲Jº1©žšJ®!iRS{/¿ÏþÜío]a+¢n:l‚ôet}°,žÈ7:üBÊ}ί|þ®ï‰Àü<áFO¾Á&”Ø7uò[“½­7ïêá}­0ƒ­øþæ]ÿ³{«ÕÆãöýÓáô¾[E­ç ŽÄ«BÿøÞ+PgØ£÷ãõÙð5ð%0`âç/ØÎXÉ£Ì?Þ`Ô§x¹Ô×2^ëÓ½ãæ„ò%â·è ƒ�<(q ‹q_ÐX{Øåé¦àª{{«›oËÏŽõq”§QÞ—@î°Ú 21¾‚@ìD�uÂâ ´#6?«#=s>Í^³qû„ rœ€J e>øë9šŸ{}DéæPtKÔè²vd÷2ExŒZ?Ú]mmØq+® ¾"]_ÿçAÿSõj¾lkܰ¤rF΂Aì²4tÂÝŠ“µ•Ì ¹)=;m3] ÕY…ñœÌ™sK�)]³!HM_…ˆF®‘…D2s& ƒ#¹îôø×/Ò%㺎XE¥k-^W¦¥ֈŲ²ÐŠkC [Z_Ó¤¨\`³e@6�×0£‘¶$1L Hd0ˆÁKOmKéH¬,k”ÅœëùÀ˜T¡3“@KÐåi²4Crý²¾z­¨š53Ø„|®)X@cZ&À( ­d¼Ëlš­  qš±§öËD‡,îÆÓ†æ!Hnk­)KeŽyy‹dn­7ÒYÜjópµt}_J3¯¨@qZ\,™>ÉÌ”"gvUV€˜SÖ˜3GĈ>"Åú©é¢«QU5¥](–n(tÑÒJáB MĸgŒ^ÍP‘ÛjÕu ²LÛÌÝš»{!ÊšUúšó¹d31ÒFrÛT+a Åm=«iîfÅH13¦Éf^<ŠÂ‹–,Z¤‚’B(ø´s)(#3§V0Š×Ô™qÕÆ”&põìÖŽ�¸2uþ $|¥(ôé6¤ % 2,ƒ¾ˆ~´$RŠ9£ïsG\»´¬' †±Wš±PÛsÈIDɽÌH5øj¥¦ÖˆØu@¨èˆh²ÒYgRS¹'ôJŽpàÄe–×цµ¿ý ê| pGé¨�'ÆËÃdÁç÷Ìšånúá&.eØLûö²ï³c>ox}¬‡§S}ö^B௧w¯o2Z9©tv»'aB˜ÀXv»{ûÙ=Ðltå|‡9¶ w8±yÛ™§ôê—öo™)}�¨ÀÀ¯¿ÃÀËê:,„Æ[ôòþ#°ë!ëùq¹ÇÙ�� �IDAT{8 zG–‡ïuþî·íác¯e6gËøZ}¿=>ÿÍáô`åǽÝg¹ûw#:P 7%QO°£FÅfâ5Q¶ýaöó±àðöޏ½¾î#sþ+´ ­ádp½óy½âåÑæÚûЧ$¨;ãÛX‡JVj0Ÿ"îç¼W?m›[©µ9k!¦mƒ • `Sl–U¡ÂÔ>£S}Ãwnp°Ñô#jU-Vˆl̰ɦ\á †s˜É-Ö4Zs=µ™HLEbæèâ ôµ"Ö“€ˆT2,&_èîk³ymµN›å•Æ®Ñt5Ë3—± s–j¦’4ÍõãXb˜œ*ÈJ9•$Ö¬èºe¸Ö—œ°€ 2ÑB \‹n&úÚHÊÌHÎ%«3±Ãf”•\šMBŒ4Ç']Ðu ÍR¬Ílž©Ì‘érŒnSi@® o¡›Ë·dyÒ$;Сœ±Ïl³´B• W7[°h5¶Â&7¡àŠŠóÂâŒRPhp©4,WRBÂvAg`ær[†sk¤G*42ff§’ÛD~´Ù™Ü,«f·úâ°ÊC©²"V¤/×EºÄ˜Ð^¬xuóêæ`…®ñ‘ «£¸mµ6_óK"‰G.EõÚãúb_Ø‚x¬P ÑÖ¢Xv˜ÒÍÅ4—ºY²¤\"æ*×'ך2f�s‘d¥ºÑ ¹èxr‰±JhJ[5û’©$‘«NJ9§ff®WˆBˆšË죌 hιïýuß÷¹ÅÄÈkêÊ Óôꪖ \FC)ƒ¸ é }?e‰te%aåPJEÄÁÑ-vî¯n‚óK>'ËJññ¨ú2O»½¿I ¿Lš.5û]nM­4¸p8p:ûHΈø€Ÿ¼€7‡~<!ˆ 'ÿ üL¥ù-$¼^ü!ó\=п{࡚µíä0ÕŒ^Î|�{ƒv ?¢\`„8ÀüŒöhÿ/)èÿïÙðŸ†K_ÿkÝ!€»¯ð¡â»‚oOøì†óqÀúC–ón˜qóÎêý>êÇòØëÓïÊûÍO¥s q¸+Ï(ß<nß%P³µø¬ßâ?«~î?7⦢ÝÁ fÁt¼&rÇŒw——ûˇzº<úýÓáôÞ÷Â}d›ê{>i"„[  •0Ü#ïc4õŽßo¯#Rš¨¿g{oùÀýŒxЬyiv8šaTCe¸‡ù„¸Oܺ±ÌÖÒ꜅S´±ç%ó¹Ú÷iÓ͈ÏÜ7Úuc-(.§¸‘VYzq7º¬†·V¶bÄ1¥1c¦Ùö\ß ¦3ç‚­Áà\„‡\ø²u,)Ö—òz&h9dpZÚ’= Zˆ‹Ñn0w‘ŠõÔ°¼®ׄ£p½‹p&øœXCï &F²8lÙ{ �2M0æÂ´*àL V^d²„“Ç4_ EîJ¹!‰Ð\ÏMЉ⬥l^6XÐÌ:s"&&²+¢rDÖÈÚHpuMCŒX×§°æQ¦‡ÍaÓ¨YI3w§`Q|ÆÒb%áP:ètúÉU šYI¶”­gîšÏ­ÁaáÄõUÌÍ V>‰@*ºaoTš“k'峯Äâ—À‹ë£ÕÛR»·æ•ò„bíª˜0$8ÝgÁVŒî\îN:Š;†Um5[‹ZÌKé5ÍDDZ€±UæI3_6[l B¢‚üÊ^Ðs×ú“,ƒ (WšæjÕ/Þûº,0_1w7/(k% ÈP©¤©,åìjoãºh[CW*,“ %Ë ìÊÐŒÜ/³¿î—×ý5{çŒäàß³`ž<èY¥Åd Τ-“ÊÊg&"A«£wb·™aˆx™]ž½÷¬O½–—ù\˯ö¸á'nÜjƒ À;ú}=þqÀõ¥ç?kÎjÙ£/ QТ%oNí(§ªãÃ(çøÞ&Xÿš·{‹è¡ÁyÆÄÔƒÙ¹<ϵ>]‰j6¶zV"ï¿A~ƒjˆêO·À"J>µ‚;£ûë­;ü%pâkÿ>4üñ ÷/ïÚ7÷ý¾>éÑŽOYÞ»§Ý×Ú>³þ¶â¹Azú>pSªé./Íð£2ºþþ ñUßžþ]ÿ‡ÏÆ»ÏÏ¥Á(GÔ„ P0_ãÆû}Üïw§öãTp{°Rg´dq™Õóáôr.|hÛÙÚXc´¸4þÞ+?<Àÿ„¸·c£h7*@ž±ƒ:ÇË#÷n^ÑjwE‘éj·%†ÛAÖfšG{�#u‘=™Ë¬9šáh¹9 ‹qép ”›±s·£ùD±²måØêV­ ˜cÌ>B#0&BÓ°².‹ÁŠµŽƒ®ÙMK.Ý—!W|Hë^J‹�,Pž´bF†t³5~‘R9!¦0™‹{÷¯ ®ˆJ&rµOk‚ , Sb.“äk}ˆb^‹*´Â[ Mb’iÈ5ÏZ°ŒWtQ\k‹EO7¥;•ɘË_¥¨õ¿Ö KB–d.AX"§—„�–ÈÂ( Œâ~]¦G"$ŽÅ¾@lnÙŠ¹é=i°(n�åØÁn ã„tÄõ¿}eñ Šx ý”�T-¹´à §ÓëR!!I €ÕY\VB d䀺) æRE¦>šžåæÀ ¸›yuô%CžÆ%tâtmý¹IsùÌŠof[³­™y#F&CZ !L!3™,@á¬VK5¯× 0¥d–ÅçUͬõVÃ\¢’d†0pýmÅtLObÕ“±ÈM0Ò‡Òé¾ò+§Å ‡ÖÆ(MŸ ˆW¸cBžZ~i_Þ¸kç.Si¹xݳܟgéÏ—18ú÷D(JoYË4[ pÍ 'D¦ û°Ò£UÖÅ­¤êU×°•ãz^ ýƒükás+Ämú~ó×:ÿúÈ·[9–ô毻}˜ùø“à—á7:Ù Ïæ ô)ª=ÉY:ç7{ÃvcØÐ­Žîç0ÇiùÁñÏ}ÜÇ¥cèIönÛïQ*ÊcòižÞ[² ìûJ?=Yƒcƒ~‡Ëßcÿ Ï ÛÏáo€ã Ë£Œ÷îø½o�€‡·8ß~"³Ž˜K—ûö÷÷õ«vø²óK´ãKµÙN³mÕzãüýS`æ_Õ êG§½E Q'||ý„¯êÛÿ4þâO·ýv�ˆéÀ§uØöŠúò0û›öù›yÓ¢UÔHûMäõ(ú©ŒÊrÄc¹TÇ#ûSjpôòö¡Ûwo žä7YJ….Áäö`q†žF·Z}8žÈ‰8ËÿW•ŸÈNÂ-µv¡”ˆ½ºUlÁ,ÔæK°\P™•«ààfT%eµ6³0«êVˡ֭Òå\×~F¦K&cY_†›¹ãÚ ˜ŸJBÒº¹¬>é’†«W€˜‰LäZäB$Ibb,io Aæz6sË @ŠzÒåëm>Wç f×ɉ”s}•I/ 3w¢¼ HŒ˜ÊE€þT®‘Qkf…\WÑÕX_¿Õá`ÒÀä\«î¤p“)TÍ–(mÕA 5J¦ Q�ÕX• L#ÌdÂ&tÌ“ ¯³ÊKÅ’\ÓWÑÍv³Ý`”kuh¡ˆn”ÜÓne>¯65ÚÉÛVë7Q˜«ÓKÒL2¡ŒŽ  ‚K9K¥‰ ¥Ñ^ˆfHn€ã”™ áH­6 W·§Õ\)¥‘Ë5‹De©nÕ‹¹Ó‘™¡i¹â ²qÕìD¥œ^ª{+,¾è%©°µÐR‘RA.³,„¤R©$¦¸CqýA¦l†DÉyÍ ¸z¥5XÙù‘È´L^áE×Èœp…†Ë€ÕÅÐÚ_eKךÊ5é\F1³_Ô/ñú4_s¦Š½.âëAð4OqZH2ä ¦L#åj”Ã-ŠDqÀ–8.9“!íÌ/âé Ü~çöæ_”RâèQk?µl@ZôÁ1/y*q€o0Œ{ÍÉl/Ú8ä“ ¹å%òYŠþrº</µb¨=ŠYQP‚ãýË øñ8&ìôXŸïíó¶{O‡„ÝÞ×àãŒÄr(M`Üàõ+ì_C‰~U°`�‡ŽÍý<Þ÷ŽÚð¸á©ýâ=&ZÇÏ öþÐg­_µÃ×ÍîÁßÖz/#ØýuocŽsÇ·ñ·ŸÅã1zþã À]þâÃp´ºßù«C _pº`6ìD3äÄœ@ 8œiÿ±omËm^tŽþ.z®åeOÛͽ×{k-²ÇžŸÊ·ðßU‹aÿø wÈD"ú|,¨ÈGÚSëƒíÁq^ÄfÙ»Sáxƒâ–4“i05™ÊìR`Zãv(µm[Ûj9˜7gƒƒÅÍ’²¢"˜[܉jµÔâ•‹Òjî–žVœf™TÂÁÂêf&0ÈO7K(i\±ÅŠå\¶PhëœB@¹°Þ‹K¤•E’WõÎ5CË•\L^y‹oéI|Š* (X§ÅzÀÙb_µq¹&8¤¹ÞQf '¯feºñ ôLÄRŽ¥VŒQV)cõ‰i‚³U LR0¥€�†¼s’¾Š|«¿-yz Y0 á ³+Ö•™®tÑQBÞ\²«¶�$é«=f3“ËiÞé¢-%· Ã8’&°ÊŽIOXš ^M«åF²B[™®´•éŠDö©}ÆXʿȥ®˜±Ö®f¿¡TÅÍáHl™›¥›%at¤ëÚ»®“ç JRŸcÎ’ùj\.¤.ÈÀšC1>…ÿ%Jk€htc¥U˜‹S9WQE@RˆU4X7]?KkËÀåj£[@¬ØŒÅM¥¹‘nfÞ‚eqví Ì®s£РÛŸà1åLû”§p(RÌ EĈÙsΘ¯xÙõñ!ã;ÌÆq籺ýIu‹ÎIÉÒ`¨f‚# +Ūҙ¾¥¨Ä´UŠ‘]9O‘"/ŸåM³ÔŸV?Õ¬Eu´h”Ž ãœYmØÛž¹/AO™^0¾¯ýå9oNýîy¯G£•ÎÃsÎïû-_zùæÿÀ|HœÃñìx 솷cb|ÀìpœË m{8°ÖÒXš*f©Ïó¡êœp†Ã³ciÐq„¾D½G{Aä�f‡á<îû¿Cû_þ´ïo€Š¸E!ðòp;Ï}üõ¡uû3nzyÞÏì¿lå)÷ê—aß=ÙgðÄæÈ‰ÚŸò‚xSóî.þ»–‡¥õ‚' ø€;ޝ(måwØL @ùË<ß4봓јœïñ >?Xž…‡˜µ”S6 �Ïý–þÆñà‡3þ (ÿÃÀ¡ctv³ã¼·K³ì6Plž³BĤýÌø£‘[5ç˜\x•="Æšª\²z±rhÛÝÝÍakÕJ…W¸«’žîª"õšOIÂÍÍÜD¦2�Ò)Üxaf1lemÅX¸Ôò,E¤óì[ÅipÒ![¸íåw[¥…¥ÖUë�@iJ*À$¥\sðê0´<\ì@òz„Šd«¦ ÆèÀ’i\o5‚c0 5h“Š…ÖǦȡœ‘š¨Ìæ´ë‹d˜®Å7•t ±ªÃ‘ÐSHä\ó "3%ºyM+�Ä™TšCE¤\ZÞÏt "kÍ8ênþÜ9á’!RD­;º¬­º×¢R‚nS"a ˆÊâRÀ(h§ª�c‘·¥ ‘¹HšàMÄ%õÑ#rEueD®ñÌ4ÊÑÝÁ*VÉ+u) Ü–èzÃ^Ã7aŽx‰Ø<¨1㢌s“+¥˜Êˆfd¿`¾(ÃUH—­§ÃbU³*«ÉbÀzõT¦)󚊦®ýå•IÎ5á"µ>˜t$¶D± aæð–, 4SÆp^?¤–dñe![˵E|_±ŸZKéè±sιkîš‘¡Þm \f|TH«òújïçkÎÁ°DÝ­vºÒ ŽÀHMîªôR³lŠ=bX ÍŽÝrbvh~ƒ†ÊYEÕ^«WÏb]¦Ž›=1‚&Z©Ü`/Ö©Ù'°oÏl§a/=v‹dÜ\ˆ][¤NqñÓC^γãuâã ¾I<|>Û—´å üéçŒÇÌn`ò<+ðÏ Çó†;¬ l8¼ÅåÔú‚tôƒcj`Ž?älxX¬k }óx[[y(,ÐýÛoßtû¯ß•4·û×V;¿ ãѲÞìû‡_•o¯ˆ#ö†Jèò—‡½}¾áíGÝÚAPÔð‡²áÀóØ&ê X¡þŠ N ººî</…ßyžuç|Áe”íÍÝ-X­ÜÅ€ðÈ·O(° | =Ü?À²r³<ñÙlÀžªo™ÓAûeÆ­fA±]ÓM0Ø8]VMäÇj³Öv:–·w§»»ÓÖNg ÃÚ=‘Mh2×®o­•¯|eŠ&úÚÙÑŒ€ŠÇÕÓŠ›W  mY áàRö,Ði*‘Ôd¬`*åH^Ñë zµï\QÛÀ¢³&>ó évý¾!"sÅ•¢®u&D]ᛟØÊ úoWž>$£¸†çù€¦i±þi«iMXR´È¡H*è‘s(vª(á0–”ÏÂXiPËÔd+±²è<W6ŒØ —åÚr©P¬µFÞndQ˜¢ÓI”Â2Ì|½è¬ÁÙÈ9s"†x¡ͶRj«Ë»lKš6WpÚê�˜Md§Yà…vp”¬m@d¡œÑ…PŽŒ¡!O¯¦° äÈ,© £Ì—ªl@iÆV¬V¶‚êæ&­9 L+B ‘¹GŒÌááœBO,×$R=)f"fôn¹1Q@Rk°cnnVa5é&D.BWL`üðg,D1\ï¸Ja)põ2À¯]hH&±Èj®ááâ© fÈá”™§Ú°^ã–HÅréYæš6ÍÈ1gû>÷×ÜçœsâD,]kCÉB‚ÄU[‡¡˜Ê4Ó�÷C Ufó9Ëðš•ÍÆÄL–�F|ŒþÁÆ–c›¯-i2nࣕé…½è%ò8tP”Ñ3$(]íà•ùxîy§òã~kx*óD0_ØÿEzK´ïE6ädàâø |¨ø›5MK`âÏ'no7ðyDF&ç“ec>ùŽy .iˆ 8$¶„N°VÔ âŸQnPïlÿ/ ÿ•gÃx:¾Âªýçeüìt†߯}ûò >øó£|þŠÔ^’o§„È.<å7˜¿Åü-^¾Dÿch¾c¹Çm½´ñÛ­Ðeh£—¼möãC֌Ǣ§Â÷Up>$Î"¶>¬Õ›¶‘‡>/B*0=1Žx-¼´V•tµØ~䥳`6” ûˆ´÷óqxˆrÞì]ÿ¶t·±5dž1NqÈ4»Dl‘Þé7»ß…J…—ª–r{%†óùæÆ>¿Ù>;o‡¶mÏ©X¢P£9½p%S3B+)εB�`ÏL•H¬t¡@MU1­Ò›– qE0ÒL¾,e™&M†Ì$’N8ÓRë…Üì“;Ò® ‹u5ç"¯.KÛuèËë ˆÁ$Öø ¸ˆÍ‹¬™L3'r…p0`ÝÆ q¿¹<ÃWU­‡éuü°ì±$ˆàu÷=(w›‘`ZŒ±nÚÌ�Cf²üS¢'€ÌÌ`îL�%Ya¾Ò•`&¼Ü™^à Ô f28«ÍUªYšHŒ5q‰˜Ãùìo*Õ[ñRQkmJi 4 QWÊ€ëo¬ðB«D…5Z…›3º”ê’Š”ªåªõµ4ˬYÊV½»W‡¯“׬ ­ZuU_¦n‹7ˆu{œc¦f¦ÍZdn© †)"#£¤<±BÊ ¿^ }HvµÉ9JS-æŠÙ]?Èj–nÕ–=–$UR‚&F¹™ÑàH¸à’\¤÷ë|ÄS)wÊÜÜ®M¤Â’\£>@´•êš¡ÌTæÙG}Ž1fÆÈì=¯NC",\¹!2§bf䌙=3U[‰i5ÌGE²”´ qJo–îfJp&Í=-gF>SÏQ8Ýg#¢Œ. 3V×L Â sFgåKK4³Š¦ýª;fü²“ûÑ?­^Ð[Èü<ð:<ÛPlÏ£âRñdø¹€Ž_¿�‡‡¿Ès`¨öNvŸªS#bOüjÆ€  ¬!FŸ„8â`PC<„½Áàw(orž£bêœ)=x÷uµ/Ç6Ÿv=Ü—Ú·¢õRö×Y‹OŒWûã)€Ë– ¨îöо>_þßâG~öŒãŽ–Ö¿/;ô´Å›žþ¿œn/·RñY}Ž éïòp/«¬üø—÷õ³ól¬Ï5G2þ6ô«¸4¼îx)˜õaªV"J'4ôZl·}µV Îq þgäŽlç2QË}}mã³ÚñÅSÙ1…ä_µ`1wMM<9ʤyËM³ñRj÷L?øÍí—ÇÓiku«µzHeh‚q/äO‡kásMe�[yô+¿2 „]eW ½–`M«ÄÊë.!eËãIÌëpí=DÂV@ðªEÌÖȘÎO„ä•ùYÒ¬kunýˆ!%Eð:4Xe:'2Wr ‹aPà+5+:h´ò‰Ó üº¿‰+Ru®}œ¢!M= à"DfÍXõiZrᙃ±Éi%t——w&#sçø¨”p¿µRKYÐ6:´žþ€¹ÁéEfikw¾ªMæ ׆B^ŒÓ1Qëéx@Ûµš;ÌWjÓ¤r-:ǰ�SVŠQ† ãuˆ_hin^P]V–Þ§•FK0P²Z2䯷bªÕ¬HY¦YšÂ‰br«ëš½(uÈ�”92v`D:Ö#õêUPÌ™WÈʺ€:—ËÛcñ6–žéS'Þé•ÅÍi&äHuæ@Ì7Òèn(îÅá¶(±ð‘®\/qa–¶¶&f€ÅP‰R® ®´°ÔÃòÉÿ¶þf®Ž…]1੉œ3rÄÚ9Çè9†f®RPä\©Z£ :0Áð™3bfŸºDly`LS$5¬–u¡ kaÍĦ¨† ÉFÔLãø‘Å"3F”ÕȽX¶Ï¬bJÆ ]”»æÅ~«ü/¹ÒF©ö„D|t«öéöàÕ, ¥Rûø§gáÿÊ/¾0¸†ýoîÿôZÞVð“�ÿÞÞ}?îßÏú-aOŸ½¾¿³ûRîÛlØûÀÓø†(†SEyÅfHC&Âñݨ8Mà“àùøíî]‹{Ë:/ãÛ'Þÿ!gÃ/ðþsàñо;— {EÞ>†½¼zýÎ"'†ÆØ­Œx6Od™Y$û8¶ßœ;?ÆÇÛw¿¹ûٯ뛟ãøëàω/øá'öòÈþÙ‰‡ùM½=&¾Ùj¿ù™êÑ 4ì@ƒÝ>E¢æË°x0öć‚ß_Ðâ¬ñ8³ÞѲW@û¼´<t÷QÛy±'ôùô%xWùy+~Àíòùì½ëyQM?*:Á]î" ¶2Š‘aQ|¸?W›…Û—ÃOÚö¦øÁ¹&âZ[c…¥JÖª”E€­®®ÏÎÅ9r+E¦4f"•™4›€ì`…úh"±ÒskšP¬ch€‚rb"©ÀºÊB3ù†#âZ°ÿ¹¿à{¶îö$hŸ8ª¸Ê­ï§]wÒX‰<åUÍ‚\%ä«t‘H,wtÎ@ÅBKlÊžÜuÝ&7\ÍEK,ºl”¨(nM¤X&.sÎÔ2ãù’ó"¾I/i«p+ ’Y À; ,ÉŒEð\4m™«ºU#QÞYë¬^Ìœ@5E©(}~Jæ˜ÍbYŠ»êPŠkœ)J´4ZP„›ŠmQfÙf{NäZ¶Êܽ¹ÕÅeHcZ¤G–˜V:fQú<×ó×™‰™1A5[¢8‹„È’Y(&7XaÒÏ,˜–©\ÅõƒÊÊ"©¸¹“¹®ëI‚Ih.³Ž×�¨XY‡D.ga¬&&œJ“C†´ H¥Ö§ÚüjuöEb À¶tY^+Œævmëäjfƈ9‡ÆÈùªHOY4KŽÁI¢° h&+Ý1/%#4ÓÖ"<&dðSuñ(T©Y¡¤f(Mˆ´¼”òÖd˜æ ’Sä´Q9kP{]öÁ=<âx¹xýx!3>¨Lª?Üf`ƒs5XŒQΡ‡ï÷ç_ç—¿àá–pXžïÇ–ð@ÏûÏpÿ³}‹þ»ü®=ü³ZÛ²¡Cªßz=¨ÀÄ›Šº¯£ã€Ï0üÝ?7”Ÿàó ÿÍí}Á=þÒÞßDz,»Ò[ûÇ9÷½ø‘Y]UM‹ªEpFm40€ „‘ r†‘Ž b,ýy‚ 9 #wä(£�£DgØÕdteEf¼wÏÙ{/çeS®ØeFf$2^ÜsÏÞk}ßèñ~ì/ßý³î _�¼Â©ý ò+ŒGŒùôrxþ?°o$ÿ<m|ìŒ3ž€cäOw/·þ«7øúݹ°Ë÷Ûvt±?Ïü2ÆmÍM!é2̶J3ÚÑ÷-†Þ6w¤DÙý_ªþƒø;qìx”vbb.X¹â}áÿ2üá{Ÿ¾lÙ6ÌÂ9ï[ÜLïOâ° ”ˆ{È—è‡G»;ñî¯âum„̃P-0æãaç­¶ÏöÛ£ŠCJT¼¬§ºE—Ïj)(ØAÌD_7ÅC†ÇXY œ5#EAsá0…ø5YJ) j]'DÝTMÍÆ\ÅæÊ댕AÉXó{Yp9UK“^…\wlB$º„޵œÇ¢e¢%~¬ußZ ㊽.Y;R!T>ÅLW*–²°DëQ„ßÍ%E¯Iüë»æºÿ¬³¢ôjÃ�� �IDATÖ_ðÊë¸:Ÿ³À¬ŒŠ™™Å,Í” a¡JBH™Š^e\~M%È¥š4Â\ ¢¥q2by‚j.3'°+Ί4a!UÒÃ|l‚Rrí›×\EWA\µkë¾`H݆qïff¥ŠB&GedE•UJ1[Ä·ætDó2]ßHr%Gƒ“œ–a+…cÕ• nbåDÉ ² F·æªƒK±®råÔ¤z&$½ªŠ‰ zÂQœ¨•¥pº^£Á4µÌÙLÕiN1¼`UJ'ƒÅRM°.f&zm³C¡Fm©•×ý–\ÕL]Åþ ňJa™ÔâÀc!…¼0IRQªp1®¨UY%fq £"QZÿŸÔuÀ•¬ÊÊŠd™*Yš‚ò9²0)&„íô*!è• ›ë”yH±j6Ï2ƒ0é ÑJTèF³%jE 9—îÈ ô"T©Mq,ª!K¦ØÙ¬u9ÊŽLеJ³ÚqóòååYŽ?Ž~cc?ÎÞO¢@4ßj0ãl‚©Õß„ãøöåþǸ¶ofÿCAç½ïx<ðä…‡j‡¼¹qýxÆÓo›&n†·»á½ =Οĩwüè‡>A°Ô‡[Ümkóƒ_8¾¹Á/:ŽwÕ[²³z—j2ÿŸ ?ŽÀ¸(À¾‡¾~Ç@úãŸNßèãÍqyزíÿÛ|ÛËã]ƒôæÿæ!Þƒþøƒ·Ÿ£kò™äOó|ÃóžO…·¡£ËpÏ›íÒõôïD¦à=õ0tûx§ÈÃÛ%Þîxª|‡‰,”bâj”ùà j‡þÍ;{ mmž<ÁðæÑ§ÚÐ&ZA¤¿áíÃùæuÞükíGvu'‹Voˆ¿Ø~Ój»±÷·ûM/éÑ­4¶+e!|Oш$«µ—‚[GlµÛ hPl–ŽÉ „P6ÀÖ––^j¹l>`%­XªFSÀ.Ÿ¦¶\/鼿NSêŠÓë(—Ì-Ó*…‰J)J\Y¤(ʲXóJg^)Jêõq\)\˦ºÔŸÞÕy­Ú-Ð®Š®"T¯á”«÷G?›dMδêŸÈh+˜ÄeªÑJ­¥“Ϩ@…fVd0×LZÌtò¿UX½²Éš†ûºP’C*бA¢¹©9H“l aU®%—ÔTPŠ©¨�šàZûû¡oÝÕ¥\ݱRŸQÌ£b¯ÚcæÎT¸þ QSª¦®”ÿR`FNÍ‚"™ W]·1¹�„sGK°Ö‹ùl ¶ÁU•`øˆÌ(¡À¨êÇuË$"Ša3h™bˆ´ªE1œ«SA ÐT;–SG­>]¯ŽÕb–2¬„µˆ§&0,D­Ù º¸¯ÿrE]óIŸ%A¦’¤*D´èälËw\Ù²@©ùʧŠÔÄ|ýsºÖr5ÁáºRUë/›ä\Š¢Êê£YY¦TT ¢™%Ä$5a uG$j/ÙxIµS)V©ÌªnK‚)—¡ çMΣÕ+‰MÂE ú\þ#m—fô¡~/™QkYæ!}o?Ù_ýö×íò°?¿>ξ=ÉQoRo…q9·—Œª†²»‹}ñaÃ;à£~vŠÎÁ|Ž:e@„›Ý·[C¨MØCÇÿù•èø êgýøÞ¿zºí¨À”c;`Øk8aŽƒâ‚×Àñ‡þx´êmÔ@à=ÆÓœøîôϹ7´OìÕëâW }#Nã_áßÝþËÿqÃ_¼<þäßâFÿèáNúÖ³À÷Äã§?Œ·ãÏ Ç·ûùÿs»\Áh ëÑ›9‚ñó˜¸ðÜAÓ·÷øâ¦á%‚¸ Ô6Ì€^%"q3@@~óœâ;ð/åæG tB^=ìÇ^§5ÝBe\:‡}œzþ€í}î)zž”ˆð¼€…Ø,£.̆ܰéæ#u­‚}¦Ž�=EgèœV)bbÓSPXøüõiWkµÕõ¯•_‡AV+’¥QˆªXÑ¡õÐD­F[.;J$E—¸ R¬VdUŠ¢(A0U¢‰9~—W\vµ•gÅ’ðòÓs=Þey°®Ç[, ®ÖëeUV „”’Á•NtM½2ª&¯á‰JÄd&³X¤TˆÐU³2J ˆ¡â*xQ»²ÁIB®,«šXr± Ӯթ䪫Q\Eý:<SjS7ÝTæÝáêj.Ò‰9sGeUÎû¥æÅ9ÄҡÍTË CR‚ÉJDr‚I”ÀBì,±AQ˜‘•u)Š™Pjf½Ó „F«Ô …Ý¥©9`-ÁÈY5$ª¥:\a %4);tBTéSqry9Ö‘PkÌ‚©F\Ë×­¯"Q!Õ2ICQ'”µT\]¸\f¬W�êJ¯¨VÉ,)âÓ7�׎9D0ºjSÑåS5‘…zÏ €•«£!¬LY%žQ9sIÈá©”0ªC (T¶³VSnÎJˆ¦&Ý[#ê$+XAÐÊ]šL°‚¯TS04ò¼ËGÇ.e„͆¹!…1xLê?þoãWæ±17Ï®»;ÛAx Z¯øYý£û÷[;õ!s µÜxÉ—†ý©ò®³=Hý¹Ÿÿ ^î|õ2­½ }º.‘ÇWùp®ªâe÷£%üÏ—®ç‘>°ý²ÎPb3¼J”£ß¡)ºB }%LyóßúCZÞ¶’9ž.{;˜?¼úç䔾þ¸ Ëñ‰3ëw~‡ÃŸáèø¬/ÝÃéÁз·± z«l‡vûÕWxóáüÄ´l·5Ûxê€ß"ÙoêåV>?^‘-JÂõñ©ôlÔmûÂÄ”ßRþ´ckCKOÙáV8Äç‚ñù›ýC‹ùöò/Å(Ÿ7½}kú¤ãØ¡ùÚ`7³úß" tû(ó—gO6ô¦ûçu{˜8¨ú,JŸ9 º‹5¶È—>MÓo.r8j‘2Ë(äÒ`ÒÔDW'Ál×C’Äv®%f&ÔËX,IU3ëR9³Õ‚Di@¸¶Šù”â»"¾?áN™µ–kKf!AaBdѪBQ]Ìî+)¼¾ž­ �ÿÔsX_ƒLa­åÇêã®Aë§9ÓÚ¡ŠºV—ð Bžë¿JAÓdUH~”LƒšBD)€‰B•J½d+]iˆ”p$Ï…Ð]¤T—Ô%a, ædA˜^G·&Þ¯º¯©H)¨ª43ïT”2Ä¥-SóâÁš‰)Ä£¼(cŽçËåÜóE°Kµ0$Ñˬµjˆ VJK�à¥Z¢(MÓ)’Ì%ºÀ§ùÌïv2aV¦j.Àïæýkþw}² lQ©ÀˆTL§n)BIÑZËÝePT®Ìö%Ò&PÊd‘"!( Á¹ÂI$Kójì‹ j%Aè ìÂ) wXI©ü]“OOŠ˜š¹7óUª\M]e…jÍQMTÔèB\ÍMš‰©ˆH±"l9?s…‘®$¥®¯ë#¹°Ã•kLBWê:ª‘°JeHŽÕ«ŽeÙ“åÖ‚OÉç&àFö[4/¥d³$DR2Ë¡–¦³1œ»YŠ‘cVßáÊ'ShNÑÿhújÍÃTÍížòýAqS0AÊ£TcvzO ±ûƒ …ÜL«B0ïe´öëþòýa¢â„†oþNžòþÏp¸eë…†ŒÃœÐn]öž/ ?G<' ðŒÖB7º]φ=1 :°ÕCÇÐãO/—_þ˜ÿëù„_½Þþsî kK±¬Œ¨Ÿa{hh_£ºb+ü¥ãpÄñˆÎ§Ñ±ÃZºº?Ì÷èý—ã…Ç'ÿ5ð5 ß=7ù‹[¯Ãè"ý’Dç—v¾µ¿¾=´úü>[W@9L§o§P@Q‚£àа pDԃ͇ó}yû=ú-ò®Ú¸r +Œ¯NÙÞN¾<Ï{vO9þÈöñ½ÎíÑo›À›¬›ÝýƒNd´‡z%æKäËž{è¡ÉjoAh˜ IS$J³¤„UȘ¢%¥ÊiîSšR“ˆ2#Wú™5"_2Ï™µU„±ßT!S ®bX Ô’¥‘¬+›»”&"ªëŽbËhRkeeº,b’rÕø|*?È5^þœÏÅI-¨ÚZ¬’Xƒž•„Ò5ëaIa±d!cY•5³f­¤×»©ƒB ÂEÄl…oÓ°ƒYŒ"IÍŠ¬eòZÕŽ$Gr$'Q…"¢®ÆèJTͲJ3Ul¦SDIË5ÅB„¤ƒÙš ¤©ØŠÙ2+CPc)U‹%3kΣeHN‰)(É„ÌCáJ5°XšIVÓj(@¦¤”šuoÛaëÝ ¬ÊQ#*’‘×[7,^ÝÚð”²FQ+âtòwQ¤ HÉ…ÀEj£ºðz ²*®ßš‚"Õ(¾¾;.4­e:×5Âa«Ó†P ©ë“XÚM«jV®¸º³)*¶Vé}ÈÁTQ‘U¬ŒÅ‚´@Ue½KÀ.j*æ**Já’X‘ x*DšÔ•“!²dŠEjE&2£rÌ£¼H+•D¿b_uŠ—X”æ"p0Ò#Õ>¦=±¾`õ.¬o8Lª<[ÌBãÌ9 Ór’:Óbgž§¨< ~õÇðS¶7êZêU]«Cø ž$'O4?1ßÒ‡Ô‡ög|´†³ŸQr)ùMòÉôT…¹cïxñ‡'}øÝõøõðŸDAÄ´¬ŒC›DéðšÄÉ.1h î®Cáw™ r‡¼<zÝ7ffXùøqžÞ4¼ûúáçxøçœ ß�ß�?ÿôË/^ãás<8B ²ãÎ1ýÊ7ygñèóÞÓ^Ï®ÕëuóËãû§œ'Mø7Wz­5÷“á§:!¦&´YˆÃ½Úó¦Pß«~=Žýë†ÃìÇ'Ý0W«+!#pp¨<κ7ëÂþBW‹±­XÍðžÆ=`({‰mæ˜yº¿§<•ž†Ãíý¯ô0Ø2€§C}¯*_0¾€Þ ”uŽñÂÃoph²ý>×Û;ݺ ¥�„ÅI]1T"f€Lu5åQÕUÚ‘UËSV”BDí‘—9÷JT-¦› ˆB‘ÈŒH¬j#@YþÈB¥æÚ,Ì5 ¢.&bË$JÁêH³Rª‹Qz…òÈu;}MÛ^å)”O]H=[V­¶þÎr-J@ *¥"M«}©ë »êºsLƒnÄÅTf—OÌfQd¡g••5«l­CT”W1+ QPp­ßY©“T¸XhÛ½ÔÑAjfiªe¨”™B˜ÌUüedÒ@‹rV+µ(Ó"¼bcÜê—˜¨ebï-^AÒðI†Ð°rRIsßw‡Û›ã¶¹*2s\ÆØ÷1ö3¨ªeZpY+—†ÄUåC¾0£Š“› S-áX/µ²€ÖX´;-æRÎkÔ,KÇãK‰ä’<K/QŠU.”ÑL›B•p¨%$(f$MDéhÆ×êf»Þ�T÷Lµ©­±—^ië3h Ï.¸ò³–œLDJ®9@mQ•>-“¬èî‰Ìk~Ú±bÐë`Žˆ q©ú¸'småÊ{„×¹²&¨‚d•ê ASw‘Wl‡Š#±%UZ&KkŠ‹i¦ZôcÖ˜Qè Û!ヸJ¯l!*'Ê) «wûBÓˆ«¢ìe/‰x«h¥oáOÀ;³''BÕ§ 4Õs×ɨпGøã~sŠÄûÇÛÖþ›ÞÿDßÁ?ˆþÁ³ûR^<½ ŒÑúË<Ÿ¶�žÑƒýO@A]P{Âz@#‘ó _|ôóÆFi£É<¶ÓçÏxåþeÓÖÿù¬½o×júkl 7Žê áb  O4‡¡Ï'{ÿÕÁZøç#uîOø{àt áÑq²Ÿ¡^Ÿ²ýWûÓç‹ÉÔÖJ¤›·îÈ'Ä;æþè¯Oí;€ �°Zp¾1<ˆÒÚ­Så% ü8¤õÄÈš6NLp�·ùކc=Z?µþ=UéoÆÝÉè! Ï–ïÛ|²á>ä¥áv‡ö!·éZyøkï±µ”Ãï¥76)C²’@I ÊF`‡]àC*´n4EbÊ.Y&H‚U•iR‘û̱3\d8DE±\n”D.5n±‘ôÜ> ,ËÒSá*âÔåQôŽ”Rä“x@¯%X¨ª &²šT%ë'ri ¹~ ÁkµK¯ú90©ü”£¿âuV}Ct9îp6,°ëbƒ“TIµò!¬‹H`s3U$9µR™ª£P³ ¥E•²�€4†TĪO©¨®}úDQa®nÖa½Ô¢™¤–E’PSwqC76KjDŽÀDj„ L¦•7ö#}KjPƒVl¢±)­¨RžÞwmlê®MÑ ×\&I ‘0¥R`›µãáxssss»m›‹23WƒNª$©S4«ò¬$L ÅŠªd /Câ\šD…šÌ,‰¢°ô9ÓEb)S¬›*²*)«¿Jmæ"Ò€ÖTH·5í¶2®+\-ëÈÔZô.È’J#¯WRs[Ó(ÕöWD-RP SM5Õ¢íêº;\ã +”J]rS]¿”^‚—u_Y[®œ`±‚9*#r$Gñ…!à¦s9amm–+Y2\Rà ò¹è…Ú8»ì æU„î‰á•ª\ZÑlóÃÇ—y9„Êåhå¾qz øtžŠ°„ì¨ …w‰w?裆.þö?ݦLàSß ¼Éú™ìk˜òõKÌG©“ ÊÞ }x¾oå­æSû/ïîãßë]{¾ii­éè·ç‰6À8ë/ÓoÛ p�ü;è—ÈŽËÄ8# `S —BއÃñw‡¸‡ô ýIæÓ6±=#ú©Þî>~+�øw¸û`Ã…8'JpÓÐ'rÃËcüxÚžžà7¼ž%O¼…6è‡7ú«‡ ÍðÖ^?áówáÏ#~¨‹Ø¥÷Wì±I“²’ÅÌmŽÇY'ܨpE9 HBWõ°àÁäÐŒ ò)§è ƒ­Ž“ùT¨À :ÐÚIh'ŠùKé_LÞ„fžu¾ÿ|üòPèç·È>w™CnŸÖk|Ýl‡í­mÇv¼kîÚ–i}MP`%ªl tЃ˜ÌÐ)¥ÐD]¥9%¤´D„Ð(¶fÿ&‰œ˜Q{VIí®R4Ôâ!À#WLj*§­\Q$kr¹ œl¦hTeŸ–´øD´„ˆHiº”Ñ×Û½Šª¸‹˜ÈI¸°¢ª‹% )³Õ= ¶t/ ˆ2Š,Õ5è:*V£ K")¶ŠÁ‰ßáu–�Ö”b¶Â*ºŠ ’寯ȵ¯v5°$PÇŠ1m&"E®\ÝЛ´¦m}U¸ »°º€&ÞÔzÓ­‰9(ÜQ¬‘UV)Mo ‚.&A%hM÷€Oö±õqh‡®ÝÐEÚ².Ψu¤ &j‡v8Ž‡Ã¡u·¶PAUMÔ!vÍ Ê4Ó+t’ª*˜…” amÊL`‚Æòµu¦$%DH¤ŠX‰^w6¬O)²u”*uQU_æpÁ‰ÃMÜèJ”^[iÊëlKh€RW÷¥TTÍšÑ,Å„j%BQU½2.@.x©B ð¢ÒØ Ÿ`.X7¨Wôîú¿Š/ÏV#ëê¨W#UUefTìchÍÊ¡ëXÖžP¨-,¤¯» ª*##Š ¦å‹B´ŠÊ x]y@Žƒ*«.Ö¦‘Žjš£~û|U/V?lè¶}uâ @æcOµ£~‡ó žûéÇBÙ_Jÿò_Ê™Å<£žcô³ý)ò~^>¿ä™;jýTŠæ<ìòðâ]C>â¶ãð7`?àOŽ—;Ó2mÏð!ÛÔ›ÓKâoÛégį'†“D<ržÎçd‡ã±øÙq6ÿ¬×Aòfd» ýÞÇ©;ø¶ñ$‚ß÷lø èï¡@}�>CŽ´‚:ÆxõÀ—¦?¾=ÿïOþo¿oÔv Çtè|õ`¿ú©@äëQ âÈþ×Ä[~м­­í9YeU£ÌGé”ËéÃ4l‚c@ÊЉ:gÄåq¢•v¡�CqÁøÞ8Éÿô‘zÊÏ‘À¡ ¦ÐÂÕ7£Á¬7ŠÉ¡yOôb âUýãVÝ¡7­ÐëöÈ€JS÷Ò#´»mƒ7š)€,ÄUý5Ù½ ¥SQ’(Ci±$‘µ@=‹^µu±– t$1„È„HQ¢2ÈVeTIZr²ª˜ŠI¡eë ‘2Úµó¼, صop}¾\—ùÚ`MÌEkñ|ÍBÈÕ/ŽëÚC«Ô Š2Bò:®õêºØàŸ ¬O�¾5ð•‰T¡i¥A,­Òa&âL½º‰°°Ó ª€  r±ž´‚„„ÚE€ ÛB*IMiÛ¨F]ÇŸšª® E­^¼›wSU)h&w2ƒ{«dn¦Væ ÕSP¢w»¨œ»—uíý¶ûm“[ÅpPŠ-KEæRÚ­É©7ïÍ›BAT0#çŒ1Çœ#ƒ•¢!W*:mÅw%@Qqê-T)íj÷%·¤£V8{äN°A›ˆ‚%×®±–¯©f•REÌÔÅL †JPIÚz_G¢”¢ -î€QuÕ,xÄœfPˆ0`8Ý�“2¬+ Öô© EIŠ.>Œ¬rÛ5rÇk¢a%§Ö½SE\ETá_6k"æ¼ìûeŒÜgI¦OT9×  (–z][ �Ö¬ˆœÉbÇ4£«š0*+_{ä¯C³×fM6´]² ÓÉ ã&"?xþÖÑxngWüD4 \üe~¨ý->>a{WŽCÃø{yüIé—rx­íà †ê§KþUùý¸Üñxè-?{´W's°!-¢_ØI¼Öæ/¡5º|Øê¨ç&ŸßéÜžp÷tÙàÀ¿ÚÑ w/or>ì­é×o "`÷|ûO?¶ãêæ^¡¯M6TÃGØsÊI(¨ƒàÆïw6,a…üê+Ä·ô€‚š=â;¾‡áx.]Þˆ¼…ë_üKÿúßY~wæ—Ï#NãiÓÛc}q„£3sÿ(öœ˜åOñ ¢€#µÃw4{Dðü(Oé§Ë|Û}0P1¦?NkÖâsÊ×x¹ƒÝ#;DtpìŠ@=¨üÔó(èVÖ«zÔ=¼Ob€ÿûBK*³wiÒ:¼£mj»›QUU-ifžfl†æ”Â2¯È«£HVÍCJ8t‰H”H“f"j¥–4P™ •æY9“™‘UÔ\ûAäâp§J¨îW€é"#™¬éšA�IÊê`C×�hMŠEUÔE¬‹5�ZEH,Š*Ìu@ŒB©º¬îK:GYW®Ï¢¼®"’ ÎBd!KkX‘RqT­)‰/ÓðÂøE²&0„¹¾PYK—#%•hCtJ‘%K±]´¢l­P Üš­Ú„¨PD bŸ ¨e\î1#.UL©¤÷@æá@u îîÚÂ{3ßÜn MáŠH¥)PÈ„Úò™òZå{ÊŒ¬9sŒ}\Îóå1³t4 a2cb›´(aÁV[Âxuû±d+n*]hdHP«B�õc3°¤µláT(yõšJ¥Z­wfƒH9ƒ•š¡ŒW…š˜A̺ ëÁm©ªŠ;̘“(² ŠL]IYIP ®r6Kr�b²ÔUW½çU‚^‹¢´>×aJ%M¦‘3$ªÆ˜ûyŸû>¯º¶"¥RJáHc)e2‘3Î{~œŒéÌVÍ4&L™O2ÿVôcÉg‰‹PEÃQT©Æ^ueð(àŒ|`þ¤¢Ë”"Uˆ<Kœ×2Ì µ¿¹É‡W¼ÿŒ‡›òÕ(J­¼ÕñW2zˆÎ‰¸à<«uo~ 'ÛßJ÷áÏ3æ|÷3ÂÇ×MϪž› JßýVp(Ü["çÃK<¼Ìþ £5ØSúhc(°ïÜÊSvø{ÊóÈyÆSD¢ÕPîè~¿³á[à `�x ¾� 0»?þM_úvê;ìó¯o?ÆÍç//·zÀ&nBÛǃ}×V‡õåý|Æi4Ä|çïßÚëÏ(ÄGüö?Í×áŸbÇZÂÆ9?àÃkÿø¯«+._ñ«§øÉS]�´ÂÛ“nÀ+øðXÐÄ”|”85GØ‘@EÚQÅ›‰**ÂãÙüï`ˆj±"´!e¤ÎåƒUTÊ]¢„™s±Þ²¶Ð¦¹v?¥:Ao‹VeUQ9Srª4½¢óè†R)wšÃZY¥(–d1³2fÍ(eˆ.yKN�êTP7sª™5·}´…Ö»æQW¹må°&Ò¦b&×»‚‰µO¤«bzÕØ® ËX×´h]ëÜ«ô|­“ÌZÜ%HQ¯¶äâXë” ­•€¿NTè×ÑmŒ«*Œ!R!r…¹`šŠ[DqÍ5N—Ê,TЦo aT$£B©¨&¢²–ïr5Þ cˆÌš¡«>9+÷-j7mýc˜³5 g™±¹@¥©tÐ@¨–+VPM`ÄÀâ-UÌ9eG1D²8çÜGÅØk¿ðH³ŠÕX Ѥ]éÖ—€„¹„6ª!]Æp.0Ea• ¡YF¡~âR@˜×M„`U’§ˆI›W°v© $…!5kfæäê6ƒ¶Åd UyÕ~€+Pdj®êõÉÛ‘Q$Õ$J‰Búê»±²¬Ô]Í;¬+?ïzÉ\6P\©ˆ¨˜“•ÈXT˜Œç˜çQ—2;ŪP`DMfÌRßuõª‰#y>G½ìMWýœ6#e~Tþ­(€?(ÌY]ŠÈ]õ"@G�� �IDATCïGªgCÜbšÞ6†ÔM홲%iš€á�ö†ö(rÒùàñð%ºf[>jòÀ(MÇÇþ[Ì㙎˱Î_<ßûß-±@è˜Oúr¼‹çó¯çóóÓåýƒý,â5_z=qt~¤L¹X\™¬Ûý‡ÇñÛöqöËûþÒýæ.¶Íw×и¿}î‡è‡›Î À9g~<Ïÿ€:0M Ð^`ïï™Ò�~í ì·¸SôøcàÇ:½Ó·ø~ü‡oÖñZÿühš"ÏφÇvÆáš&�È×sÿîrõ÷ÿž¾†~÷¸áþægA¨ÜÖŒç|<žÂ€ë¸qXA&dü‘\ŽÄOòUç¥ê«c}v+ýª óüˆý¯áG4…\ÀŽö=ô�õ7©6ö·ryâñ]\`ãäxÛŽÃõ\:™Õk wQ$ÞLù¯§|.²¹*1 #¬BGàÖ¸YQB*'çȽéÑèô’óò1 ZUiQÙÆBÒ{a—Ü¥¥E¥ãú#ÕÚêŽÖb ªR¥#„X墾XVZ°&FmÒ\››YsÀñ»z3——kIâXyïâ]ÌEUÔTT¯•·*f‹ðº_-3YfÉO‰¦µÔà’¯¬¡�,!W¶³*2‘Ù2´¦ õZd»z�LÜMÕt.ærN©é• RÄT¡[Y“ô–MÕ:´"IFæ’4H;ë ’ÁÄdAK$›I_Ý<‚X„\(8  drDÍ´e+*›eY5CF~šÌ¾¥mœCØÔU²^ •)Ów5Mº”“3k0öš!Ó¢ÈȈ9ÆN‰¡cÇ,bËT2PII:E*A.Šd’™¤ ÅxP7¥JMÖ0 »&HÉÔ%‘Xò*¯dBÖϸ„ ÃŽLÕ±î •Zfåœ3#Å©‚4)±E@GE’•‚ÒE¸5q¥@ ¢˜¦%š‹Óµ¶M¤±²¸Ú˜¨™®VW•š´«Ï YA" ™œ‘cĘsäœÌ¬Èˆ¨¼”îôÁôªHa¦ÆŒœY—bKÙB1aêR`éûÄûRS¹YÅïbŒÌºÌ ¦Û¹~ÿ1øS)jÖ�?4þXÒÔšNbŅ̃YľÅ\—k¼B8%þ‚Õ¬ú@oÊeµ™nMEˆóøÍûøúŸný§Ç¿;â]O´3´¡ò _dÄùoý|ùõÇo¢¡áß`~>šÛÀzn›]󴽇þˆúûÓ>ÞÎïÆÿ¼ù7C^ùøÑûÆ-ž_qÌ™­^!ûˆËóeþ‡KnXG, ;úËï}6|Àðó ß6üø Øž±'~¸ê ¯ñíÏ _5ÜøïþqÞ=ŸÀþïõ3࿟»eüÙËYþú?}‰oóÍ/¾{xÂAÑn<ܽTN=œê€thǶ¡ z¾‘ü£Âë¼½›Û]ˆ1(› _ª?"OÀ‰ü}[’ø=\PwðÃCɃUï—¡?¢J‘ÀèõdÀgòuS³87±‡H܉Þ›`º:­‡â¹ã´®ø ¹ëüˆi0aóÙì£V•)€Öòpn¤PæúA„µ¤¤qeª¸Bà,Ok0)ÍýÑlfw•O4$4h]šI“æÖTºK÷¾‚¼K}R,ÖºÝUB…(´©7ñ®ÖÕÌ>1òW`¤È AkA”Uo9áW'üJPËÕÜø»Ø É"GæLÌdDV…æ` á¤-‘‚¬¡†]°BA‚¬J‰ÀL­²¥Õž‰MÊz¹§8¥U) ©¥Ø¡Å,•Óbh²È°°¦µR¦bÌÕ›("Mj-"uÁ@“^Í Ô´Y>WøÊ ÚŽØdÄèMÕ¬]ä¦Zæ`_K–Êéóc%²jÆ\•¸=*JÙ*¼&4–ÛÐÖÄŸ(ÑÂCÊÊ̘5,s'LUÅ?@Ó`‹+§dMd$ ;% -­Ë@­‰%‘^µli–]¶Òš! ©x¥Hšºèµ�¹bÑr¥¯—,Y¯- 0$‰€Ô"¯d®‹c@PVd‰®´=×7hm.p%öš™@¸®€•QYœÁ1bŽ9çœ9÷Q{Ö¢l›”hI8‹cÊLb/RPLŇç.1”�eÇn-áD ÁäË(\`–Ç͇éAxǹ äRU½Týgå­” 9ÔfÓ_7=ƒ.I„¥¢„XÏ…KámU ÜWakã¼>ÝÍz%_xÒÝü5ðñ}ûðË»ÛÇ?¾;í¢Ÿ¡;*‘x˜ù°E=Çᛇ ~ù«ÿîm`|vüÁÛÇÙº~ð62[œZ@@|üOüù×­Úü.?'!íg÷§cCßnåæR ûx‰|ª€8ºÁ¤0 µƒöà7¿÷Ù€¯†o$¾) ðó×ø¶€w˜ø÷ˆ òäg/—ÛsÍï€/ÁÏQ÷¨#¦ä�†âÛÏ€óÃ7öðÍûÿ{ñpÁÍÓ†'yA�»cStÂ�«™GàžÇÝf_×ë:h@}YŒ¯öd[ ®Ìa-´»$0ڬǗ:uÅ�l¼“øÿ�y¶½gt>cØ=­ƒ]µ UÅáó->@ªÞS!©@¦áņ¨´"»å”2†È�C²#&¡¡sÊKðP»iQ-‘LŒÌsUlëy\T™”ƒ*šl1¹Wô;¨@+ôÒÖÔÜTš«{3íÂV%K„Pt©o„Y£$ó®mo Y $ŸLÔ¥"ÔF®ªñi„D~Š;añ©k‘¨¾–¡u•׌ÚgÈÌB…ä`]€¢D³TA¡t[ca¡JeÕ^5’2Ѧ+ÕE`Z]iq+k©­èEÍ´ H)š”¤IVR˜J*MV6J-Ñ„R+É,b“ð()™ýÊÄ5Ek””кTi(F@á=õVÂs`Ž&}m`âT…ØÚj Êd:Y‰ŠQÅʨI†èŠÒЇÄ^ µ»˜CLDV•I ³²„‚ªŒ)Iòƒp7½…lB[êPª2‘R%(©¹Šˆ)eÕ4¯æb +« VèŠÎа€†Vy,Íx•Tz¥€×.©EuÓUMÄ /pUI꺞fIC¶ÆDjk­x-ΩS—6Ú®Â=Ö•¢·nsÖZÖGì³æà>x)ÎüP«'8YQs§V8Bv*ºl¬l&*Ã’©q°,ÕñUNu¸ÌbJXëð@þ¿´½M¥Ëu¥·ÖÞñžs²>n%y)¶I -A$p– =3š¢ ÃÂðDsÿ2Ù£n ž …Æk ÏÁº„į¼U™ç¼±÷ò NÑF·'–d €º£ªºYY'"ö^ëyw–³ÑÜ#1_ßʼF<cÿP.Ãð÷²·´7°.ž{ä%fñ+Ž{ðÞÐ(ï/¶²ñk{L»×hG·cM³nŸ=¶;Gu¼,°‰0쌇,•l®öæˆýÇõùðð§Ç¹áXj\›9Jï£n‡ ÏþÑyà¿„áý øÁ×ÏÏÿ þ6¾=Ï÷ôJofE¿œ=€¯p:¡½D]­ø‰¹¿¿FÿÓéÙð€/Îøx^k`âïpT€ø¡Îàw`§¿Ãøá³6üöÅÓÏO@©õMÏc¶2}\Ô¿Ì4 TÌöãw¥£^Ëá7-Ï™(1ârΆăzõçf½ÐQ^dó ëVžÂŸçL8& P:0'äG¨`ú9üÝTgEÏ2fž³à‰p`èmî÷[ÀêK>áxíûïúh¬Ü™™!êL׎úÁ´?s7Öã,™OmË$žBɉì¶Ã ¢+¤Ýò™ª>²bÖž(G+'àh ÏÉÙ•@½†GnŽæðàÊJkà&¯æ¤1„T¼Á«ÙVj-ÕK13w/­XC›‚@[ßEG¾•”ArÁ$ÊfµILd CÊ›qÁmq””�ƒ·®ÒºËŠ\C§€BZËj|é„#æ²âdŒŒÕǘÊ.õ\ŠÇ”1(@ÐXmíœWÙ¦ZlÛJ;²w6dÁÕ4Ä 4¡Häú+·›@ŽpÏÛC túZl„Í•(.À±ì Ó£¹4 W à!åH3¬+GôܯI©Q€•–[BíÈ¢,RIYJ±4Üd¹¤˜£9¦)•3"„)º``®õÄd5M£[]È”L™!„4À¯I¤|øzj,ÀH9ysòYÖ^ÞM2*-r&¦YÚ-<;3(ïV½ÊVKžkлŽ}d ¨\§¼É@X¬æä:Ö§|¦e"r•ÊXD™1Rr†èVÌ̬|b‚@\M9PLeIqý†hdŒÙLj9bŽ}h^•»bgvd`&gš‚9 Ïá>–ácÊ/bát7§2|Àm”ƒ ·ÏHz&ŵÌðlf± %PX¼Ð„Æ8¢²Î}þÞŸOxîd™åÝćù¬×]¿¾æoFžáe¯-šfcöv÷Áñþ‚þð+ÕbD25?Øñ3õÎF­zñ8óý$6`œË|w`gÃxÑц^œïŽp‡ô œ?î¸ÄÃ,gé­—wfö®ò±?¼/¿ý绯aÛ¿rü@żOgv~‡ú?Ÿ°¸v/@�¿Äøñ?ÿlx Üx‡¯÷¨€ (ø¡áø¶ÿäX>ìî ÿ·_à¹Ú£}Dmhãlx—µgÅÎÎÇ<¿¾)ï¾_û1qWúÉ>¸Î8ßâÃýõCm/ßíå±÷vyW†øußÞÈ-‹?ûiŒòûÉ_`‘°�ŸàÀß!æ ×Às<–z… Øãb£Á0…÷øpÏlå[ ÷Ü>臟£Ü±ªDÇÌà. kÇv8ÙÖè¥AžÓbVg¥¸ø¢kö’S#Øi1+Š93ÁðW²jшê¤+)»ÂwÃ…ídl̆,©J4.vâÆM²£yauÔê¥ÕRÝ«›{¡•jæH“É#A“%à‚ÀÀMµ¸€6u-¢W±Zã¤náK[H)-iÏ °¯Õ¨QB‘Ì5GZC)Öèú9€Y‰÷@Ÿ˜f6½€æXÊÏN¨�N:•f(›èäVÚ©ŽVk1º&£"z$UK1—ÉX=í$ƒ GO™§ 38P Õéfp'Šd–ò,™+»~;Ò"F Â5³„L@ru dŸ²&sЬ5‡²E{X„@,§Íù‡ÔpfZ.±Ù̸";m³ŸJF(ÇA“‚݈iLóL¥…â.3l5³&ÓdB:¬‚…­“h1!f/²$Db¦f•æwgŽâ)ßQ7–™°%\‹œÒR.Mc˜äó“%ÐÖ÷t.jï-yB*’‹tn™„T"æjGÐ*«YåR¨.=á€K.8b™[Sš‘}ö>öÞ÷ÙGŒÌ‘9FŽ=ó*uå°\€¦ˆèÂu ÓD74Ójwä,tÃdébIO%Fh†Z^KHÚ€1K oq, 3¢xÒçP&­íÉ<•QN#+.ÕͳÎÎNNGyª=ðÔ ž·Ó;{îØaê>F¿° gá{ Ðm:X¼¼ç±Áz;ߎ¸/ªß²w L¯ú|dK᎟çá˜ßàãåüqb÷©{Ù©ÕçÜà¯0wPÿö(áÇÿüÌÓÃ7¯Îß>Áx%0P ð#ú3`@m8Mð�>`~öÏ?î{ ¿ü4\úù#|¿àõþß¿ØÞ¼`«~bóݳ±}<<·ç÷má¦À¬cëŸ%.Öß ÜYõ><£Ã¸ÜÛ—÷4|Ô¸ìñ±~òýäׇš =‘Ú_³€Ž�Òq2À+Úõ { µ‹s\Þ{¢~|hyΗ°ª­‹ÏC¢ÖhɆè8| =Uý¢ÔŸÊO0ejÆžþO*wµ%X^DºšÙé*쨚&ذ„²Ód¼kƒšá D Òœ†!›ôðjV›ûÉQ¡ ÕT‘»™¹Å¬•eC©lf¥¸ÕÂæ¨«2d7E—br5L†$)OYæR9,n0½õ�WžéÖɺ](×!´´_K6· I 㡘R¦2FÄuæ5r_Z³É ²ÓzñͼÁLZ÷÷pYáp¯tCn‘L”fíhÛ¡ÔZK•²ÌŒ´˜Š3¦bJ£i…1WQ„°L˜«é~CD.›[Yå¾)És1¬Àœ=æž2Ê,V«›1 ™¹kžT6šyI§<AjynºdeffÌ¡2¤\ÙsväNŽ‚Ë2B¡Jâ¥tÒÈ LMÀ¼YÔÆô"³{ò.YPJU˜fZ‚‹sb–0‡5Z€FWAºÜKr(‹k¤›âIF/¸òSí#n æ¡ì·ÙvccÉyK<§" È\5rš>ÑUHÐB>?`”¾ê e™‚pÓ &C&,#¨fˆ™ÀÆŒë>ú~Ý÷ëìý&ÔsΞêÔ(LÈEoŒ«Ì]*°’b[²DݼØHÏ�b§" †Ùqº‚láî¥df÷L*‹lýái*•çÉ}£MÏqRj¹ݽ#pîÄ¥á]�ªï£ðq›°ŽZp²Ç .^FdÒ·þòt-Ö+„z‰ï]õê[…ýÚ…ÿøiw{>l—úîu{„½_ ò<aþÓåá‡|ýçã5KsTC$¢žË÷Ѿ‹òØ$ö»·ÿÇûy¬½¾ƒ=6½—±óÝñ1àN@«hŸA@–æÙð�T í´ûañ¾?ûo€Ï?¾9¾¸?¼9Z))Òç]éßæ©ÛÃsžïž€ÿ~z¿WŒò�œíÚ¯ Ûûv@Û,Î1ÑŽ~Yó·wí‹cÿ~<}‘ÀOçŸþœ?Âñî§–Æ^y¬*ð +0b8:ðð&q×€?~ë‡ïѦû»×äü¹³9t€7bòó´w»uwhvpØá$¬šû!¢Î‰aÑc\í—/ÊŸy-µÖÀtË>eáái“Èð}èèÑŸA³p¿z6ÚLNV¢�4ÆAf ’š7þŠ6óê,ÍU¶H if2ÅêE‘†â,ÕÝÝ*øûF@]{aùª 7ž_Ò*ºRŠÐœš}%È “9¡Ð x©OC#)oki)׸ãS›·ñ½˜Š™1bæ„bDÌP¿Ý ÒiQ¬ºU÷RìS ŸäõN+F/)åô@œ4ÂײCiXšÉL42ûBo„BCa™46º™ž±øBJÌ MøÚ³,þHñDÉŒ•¥1äÂ6áÅ›{:‹™D( ƒ’¼–â(&ÃZ«X·âîN@1ƈŒé9É`†qn>Û–15sÕÄ XäÇQcÎqí£ %ܲx `(=ÓÖ‡S†,Ì/š Q:V¼ 4"Í–šÔ°œ³ÂT²£Œ²itÐÌ´­ìæPÛcNpª þ)júé'Ü?)µ ÙÈÅ\É«'‡?”ØN‹{sßÐëZ>±Ê%–¦"×Aß#ÇŒ½÷ýºïûuöP€ÃbÌ9còæ†%0?Mïzh¦I”¦Y™‰ÁâaàDŒ¥]Ús\’sskVaŠÐNû  W©ÓÌ\Áž}‰EʺAš­T8£yÙRŠ]µDÍp»Ì¼œâqïxAl@Õ{Ãzž«ÕÁDÝÞÓàþ“¡_ÈߢýÙ.ÿÆlXÞ‡òà/"=ü2âÃOžòû_£û肈Y‘—‚·ÛÙžÿüôܼ”�Üæ9�àöõˆÃÀwqÏqï—–¥ká‚… Ç~TÜ ±V¢`VࡇÞÙpÞ}Ú0t`�çU…{õKñ“ú—mÃæ§Êâ9¤R¢ô'àBÜOŽ�ð%&€ã¹\€/ßb|ާ?Æqà çØ†Íófïø&Ì`‰Ã3¬}ï1ëφ9Ïý SˆÃ¼áP±bb7àøVõ϶ÃKSóœqy§|œß{oJ…„è@ax¾TlƒxTâ°=4V’™{¹>gv¾'pàv@q¸epú@~»fÓP¨H’fxp†•«LÉ?Z-„¹—õ,_Itp’V“…›ÁK6óU–Úa2€àL1!#c/Ö¿:Æâ¯bÕ‡H§Y,Vå²8®–k®XbôœÈ>© 30L“ˆ%ãYάÏâ5¹Y©W.åf¾½% H­[|Nhf„›n«_†ÂF7V[YK…,o~»e0LÅŒ9MŒÈ1VŸÚ#@>õì¸ÔÔ!æÈõ9¬Ê"«‹ïW|A0'"‡&sÐ |kéª9çM´Ê€¥SÕæ¢W23sb!A!ôiênp÷R‹£0Ô…¨&/ë—¥¹ˆŽxîã‰3 äf®R ‘5Œ¦¡Ð*‚µÎ^}ލûÀ4¿½~d’i^2œìä�§y®fãò‡ßq\]‚ºr¤¯F6Üxú<˜·O/Кì`¬4 Ó"9g·®óâñJy«G¤0ÅLÎHS–%G0p¹¦|}즷]û*/nµX1sÝ,­ì'›ƒ™#æ>¢9ÇÜGßûå:ú>§‚ KÝÆu…q–s&bFGL„S¦Ôdl>M@Òh›iä,K¶#Õõn”¶ô¹KÀ l˜UDö>§Psz%a=“+HÈ0'ÖpR1®̾þZ§�…ãCåC³óó _ /ٱ߶v?¢öx7âήm§åÁ¤Z3?Ó £YF ìs áªú5Û3ÛýÄeV+äùš޽áÕÓOß<o‡'îOíëó¼Çx ?aVм׭>7#òZãΑxÞðøoðmàÎq$pE®Ä3Q°ŸÿÙ3¥ÇO/†ñé¿oU¸ïàøÛ¿ÊíÑݺòš×žÝýÙÆùŸ0¿Á«/€†�D~ ~�.wØëÃl甜8î€ÖÒ~|hÏÓ¯ŸcF¯Ê‹soaïg8úÄþöÄvB3´3±·ïíþrâEÃF ]m<Ù¬GjA#ÜÅÓÞú/ ;‹ˆÀ‹~¾«ïOâéÊßîÛÏ©·Ô}è!än¶ƒ¿7žÈóÄ(XTî€xEÇt&.¬W•£ŸBØÜ›2m‚»3«gÕV^VV¤00f\æ­”+I 1 78‘ÈP®xJ.ؤŧD?Æ…I0gmg„æH5xáÍèó©Û¶”> ¸©ÿ§ÔS«}, 9¡ä-‹ž9—.Ó¤ÄrHÒ‹¹»Û¢_,Ö*jk®Ï‰EÔ JŠ™9çˆèRÑ0e.¿ ¶V·]/h@€HæŽð ›tg—æVÜJ:ÌÇäžÖufe4›r˜“K~çNÚ´„UkÖ¬x‹êëã•P€bpN/Å+[õRœT2Âfæäb™ÉsÚ¼’O„ŠÅ¶Âš°"š¡8VÌbÊ"dÁœ¹; ™¶¸·éJMm3%=ƒëöíðv3gb Ci¦Ío;Á2�ìFStCeV®®²L·Jx¹¥”8…‰ì˜¼ÅQKÆŒin&˜â.ôD$JBw±ÊHº„e­áM°t«3ºªÌä§]óºÄঈΌÈ9£÷دš#ûˆ>³Ï¡å­JZ³\Ú«rŽ˜1cnƒBdîUásĸK«Q˜F jdœ™¹‘THéи‚ÓÌÐæG-ÃDª¸»»rй#ÏSfÏžÒ®¸Þîð 6óíÐ{ìh€ô6ë=TÃßm|¤ÞcG \�Ã}‹ûÒNÁ‘cÂM¾µÃ!¸]«íTfŸ×¡ žŸâÝ‹Ù=qÈÎ6žŽgk†a¸7«½švìŠÁ××À×Â9€x~µ�ŽgÍwÛ¥—,½ÄèíÌĺÞùÃ)q˜ç&h Ôe>Ã…Úûÿp6¼ÿ4\:ÿU¸'àîO¿ÄPÛççÑÑCZ>~Ü‘ÿˆúO�P_£¼ùö¯ß¶Ó=XM︼÷_£l8ž°~ŽönÀfgcsq8óˆFô‰=áÀÇ‚}¢~Äñ HˆF80õ 9¯jÄ6Pš…û1wð´ý þ«fï]�Qùv³û^kñ1òíìï{ _±×Ç—ª*s¼°<Ì¿8Æ·ŽùÒÇÆtŒÀnpG=φWCk’Q(6åŽS„e9Xe+8˜ ˜WèBæÅlsoNw——°BÒ˜fv#ž*™‚`I+dÌHi9'Ó–i™É&–ƒ ‚0«æÅé4,©DÞ`HkvÅOÕ7H+©*bEoÍg¬m�qërFNqrM¤àæðjVæ¾N:"nŸ\Êê4*×\fU%rFLå—Yh*&2‹p(ÅÍ A‰A4‘„IÊA+æÕ}M‘b–ÉX(†D¦¥ÙB‡”šUÊ«J( Jñâ%È0­Ö\Ü¡JUgu«Å·Vk©æbbƒh4f®­>—eP©¢¬ŽbQ`„c=UnUBKBa‘Vmd^‰Rpp‘i& a ËSÚ›,eiŠfÎP­ÂiÍÞiZà]Òè¶þ®©&s"8Ãf¸Òhòâ&bFŒA�-ÓÊw±§ÖEÞ¥B–¼!T©ë÷2€X0©¥ƒÈ)…˜Ò­§­D̘}fŸ9"Ç̵Ö�RNOs˜;`reŸ³*£Oe8ƒž™b‡®®K˃†<«çY‰Ø’ë_ÒbE¿É£uñ�¯2Ž¢½ŠÐ¡y)îäŒ)Gt-„æWÏð¯lüº¢°¿”9±÷&¨ š÷{ÜËÚD/Ä@b'8žçëj¯5›yìÎ9†qº›µpšÍ˜CøªŸñ1Ÿð¢ÔË6.xôgáÀæ‡Z·‚öEêGcs%{C§7ø°áÎp]èççG6Ø¡ned{Œ#†þöh?Øtª´6„�� �IDAT’óœï·Q ‚õûfXÿËwÇíõØHþäãá4ÏíŠí÷öžý ÔïYpm(@{ |~ÿêÅ}+­Eo;òŒ…ì‚N ÀVO^²=Ú:b`îˆg\ p!h Ÿ¿€9*a‚MŒ}Ìéãd ÝEV·»ãþ¢×z@–à~oåþΚj¯<"®Ø;.þþî‚R~ênàý ý¸õÃÁ[iÍ2-Ö7„S q—,Ëa²tj bò˜æ #è¥oETO&sŒ¿cÛ÷Ð6Øô´’îlžåvÉ^Ú.BB¡‡Œ±`=RšÄ,æå–2]•´%ãL&‹XÌ*¼Â+‹™¯©²Ù ®€µjà·WǪéšA`¤(4¥ÌŒ äLL1e`ØkÈŒF/æfN#U¥DHH™™ÅÒ ½PHóiž† « ”¡$Ãh„\·8C*&bܾ—sRp[zlgºe1¬Ð¼‘%X¨&éIµÞd+µfôj�®Äˆ®V–ÌRM²å¯àÊ㻕Zj«ëCÄ5]1ÉXÊÒ#"æˆX–â:Ã! Z.u@%¥Â Å*= ;²€ˆ£ž.é¶Hði2¥S/T¶´"P=fO‚¬fr¥H‹ô³Òë ±HÌGž\½M!h(íäLyM”œcý?0G yìôçE`—@%o6x‹.ùª¸¯¯ûÂTI™˜©¼õ ‘ZÒ¹ŒŒsŸ³‡fLäDcÚ„¥Ã Yµ>þ~Ι5²¥<#„¼ôœ•ò‰¥<”B»ÈB˜köŠdÌ0‘5³ ó[“éØŠÕ47§§qZRAÐêS¶¤¾‰ý7cÿ‚öšÓ÷VÉ*{˜<3æ¥îÇvU+ÌZ®x>ÛvþœÞÝ7++H1ðëäç,•Y‚òªÎì˜}´ç~NzoÂðß·Þ�¹c×qöË;Î'üåвüöéôó|Æ7_<üM9ÿø»^ðÙ‡÷Û3Ÿ=àtDZÞò>p'ÈCò©jÑÀ3¾™àÓ¿¼ûö_–¾o*®j¿ø†¸4Üû¹äÛ÷öTó‹wøþc|ñ>?Çu¢�׉íðpw¨ukGoÈ^÷|¸|<‡OÄ3ÐÞïx;·ïÕ6m»w«|£c�ß à‹À©<èt¾¼ªÈx;û}²N¼ë3Ÿ¯%%6ŽbÔKÊšX÷|°y®Ïø¦ÖÍ·ìH¶(?ÛâWñüþ°áXЦy»ÏlQåØÚÇRÝ\évãc×Èx®£Yƒ­È»AÉoŽbYÙ6rV>Œ;’ŒiT>!ÿ^åßêâ¦ZÁ4'ÍÌšcs[U·˜Jqˆ1‰BûŸR*9#FδYá%ié,éRu8P“+ôf¥™W–ʲn“ôel»)‚ ?w;nºšü4IvP´Àš¬}DDÆŒ¥‡\l˜rå ±r+«L»F ™Éå ˜•e¸&K¡—…ܰ)›æ è–.X#$fæ2ïô{Žë{LeC…À&¨†ô•®!iD% ÓÍ�Ïä¼é’fîÅ Á`Òh‚%Ì–¸Òàž°å÷ÎUWfIs¹[m¥V#JÎ>'3˜šŒ‰ÞÕ{Ƥb†l!L"Úr*¥#SSsÆž³÷Œ�ÍAƒÂØu‰¤ÍA#.ÈCªÊÚÚ9‡2rŽØ!†<e‹ñ‡TŽXÑ23˜[ Ó4é¦ARÀW/2‹—²¹˜pMfäP ƒ#T–ÍU`¸…7XJ˜ô¤%JÒS(‚Cå�Œ%í\Róõb\ÏX¶çu6ä1#”Á˜‹&¬H¦tÀ Ù™¦Z˜C„Çœ9•ëN:}C:Õ˜}LÌ™mÃÝF±µiFQ¡×hU8˜7$ÊVÓ³€–*†a3,Í9T4¯U_¿œ×¿ó%¬ÄVfóÚ͆Ú9&t9§Þùµoì³Ï>ìùl_c^q|ñÀáŠà„…â’è{½×J®ßÌ®-ž/èY9ó\&*ÎÅÁ NpÇxÚ1û‡G›€W½óøHÃÓñm÷û¯Xw%ÿÝxÿjàÀ .óŒ‰Ü‰vyxÙ^Öl9Û5ð”câåÝö€q¶uØ>~ý¯}6�øê às¼ž(M§<7CŒ{î÷ûÖòGý©b|Ž#`_"+^J;ïèÕÀìý0âtÎ×øúkÌ [âZÀv¿éxðæ¥/U¸_€xu@ÇÛ|¸?Õz,?;m¿jþºŸå~Ö6¢—~1Ÿ[<Ñleëb»Z¿èî’g¿Bý̧wdçË£Ñ]ÇÂ^üŸ¡qˆgÅhYšÂfnµvÁ(ÆÉD # v äÓ¼@&VKCM–HõȧáaAW°±¿"wÁà°f^Š#25ƒ›fjB‘º&'‘´A:`°¼0TDÄì>¯‰fQC5é2O+d‘ ­ºWóUƒ(‹‡sûÀ^Ÿà·DŠ­§ÃÍø$=I¶”Ðk>@.xv&#rf å§mÅ71éÁRèCeèDÁ±MËŒÀÊ[ZA.Ù0èãªHe(– ŒË~–˜#ú{ŒKöKFf4à`,ÎFni(”)”Œu¥½1>I—½�SZ–Ü$YÚB‚fšp˜‰N/„­xˆÓJzA)VkiÍÈŒ"ôìcÆÈù©É;úÌ‘N£P• r‚,Ia"lîš—¸rFÈK1å¶LÉ•ç1;4U¡’i¡[PÀä–SŒ\è®ã·EæTÉD`ú’+‘RIåX³F—/¦7a"“á33“P.,…ÀB¸è¦†AÄ”I<Äí%”&ÙÒH­»2ƒ”n:òÕ–„RSsÆH%^4¬oZfN,ù:± R=4ÂlÊèe…è�´‚#Ø”#¦,yLrÊ;rph ïŽQ|„ß½ÍÊ™¶@ò7·ìA›@“#Œ¢ÀTîô´e¼¼Žøø¿ÆóÛl÷c¯|=t|—ĨH>úv¬ö!b<öG&.÷¯q,çþ¯;íýYׯGüÂ껫×Ì‘æÕ.r ¶­?Æø#?7ƒ[ÀûC ÎzÂå+ÔßwÀ|¿ÛÞ€Çólè‰æ÷¿Åýߎ†½x¸3Ü¿vć…zA^òÜò;Ÿ%j 5úÀ‡ Ϫ`â²á«Äïÿ?œ ø›¯ñïñÖ?ÞßÔƒ½‹LeÕS˽}õ(u›õù|wÆéû(_ÀK³¦FÆcŒ—à†ßL<]Ê¥þÑ¡µÞ¡¬%Îl8ÞÁ*¢ß¿8}×üh-7?šFÖÁãX&ŽºøÓ¥ùl>Ú‘•RûNâî2˼þÕóüò´ÿo¹¥†<)5]Ký‰o¿ 1â¹@°Ê£rÏÙÔ™u!ÅHìæÍŒÓšÊ|‚76ªEÅ4+ŸéžšlŠkh­u`ûA!ÜJ•UYM+¹à©Ÿ`E¹Ä‰pY]аÃC‚ŒZç91ž"¨¬M¸3¶åÕ¡ह9hn·ëRm7ÝÂÍèÁ[™a1Ïn¨ݬm"ažKùzË×#9C‘‚ä¹Ö4¬¥³ ~Ûââæ»íµtÙ‘M/…ÎÕœ WÝJÔL%‚I­ÁÑÄqs.¸Ðà³¶e«¦™9çÌ ,×!J uû1•9Ò 1D¡NªBõæÆ£§ ÅYÝ­¾^OVXªy¥—…[¹MEFŸsŒ¾÷Ë—˜C·]އf²(-—}hdŽ93,.y[©~ªÕÁ(Œ’f–]Rô¾¸{Èžc5Ír“¬÷btȪ(3HÕYL´õ—ƒ3™!I)RÅÜŒeIÿàF[^“ ÊD%3É,Ë÷'%E `‘ j‹ i[À’[�V€IÊÔŠB"”K¾ʆ´Ú‹L =•IƒO£Ù"_E¤2£+®]1¬L_ ïbVŒ­ÕŽdS(‚]¡šò.ûzõL*•¶»êiS¡LþLMbq¼m9nÖoP¨I̲”Gaåx*f›ÏþnÿúQ§ÿ8ô ÃYÀsâ)ÑËÛÃá¾n“¸kãñïÿ7Ã_àÛ ¯Žõ‘†1?ðih>®×öXOwÓÓz4Ê®‘ÆVÿ‘`C¶·ûøÁëqB‚þ'©Èö~ܽ帇ÕQím±÷/ÊCú9Û[´Çß¶z¯‡VÏÓñìxNà‚JœN¨G$ï`W쨗gÇãÇ‚¯Ž¨¾éøâþÿMãö/9n¬=àÏ~ áþîû÷w¥yíªc¶þÊð»Òÿæ4þ;QqzÀá70€/Áß¼Ï/‘Ÿ=tžŸ„§‰þ‡7ìuœã]”¾ ù¨ñaàÕùnâîÛ(ÃCzåÈãɶ¥yº„ {µ4–Zú‡¶ÿ5¿y(ß:û„¿Fê)ùªõöaœr¶¤Þ+1ÇÏÜzgó€^êtÊí¯¤ˆ>gì×áÇÖP‡¶uUYaÌ#X…"(•Ó.j×ÚŽ¥šÁ-á4~PÉõ¤ vtGmÞŒ5éi–"–Nù‡`\ ²¦LŽPv1•ËcÈ9©g…!ŽJ<XVd.Ê…ß–ÄF®äÐ:ÖÜgyª±`|€éÿnÅ-X2ÖúŸV0 ëFž–b$ÃeTXvóbæ4_õ:.,Óf &á©åÖ¶[>?©Àž)dH#ÍÄT)])ƒWeC:ÃÓŽb)"#b Û>µ@&TŠ&A¶‚”N«…Lˆ)Ó’˜ÊY‚u¹Êr²ŠdYp’Ûñ½·}ô}¿>??õëSß¿û—™‰¬!Ãm£¬î°d('$Í>ûÈ9Ö=ÛWçÀVE@&' ¨\8'ÎiSBFYY´¥ÕY9Ò7ye-yó7Ãà`Ê¢`1Ó´RÊ\pÐŒ·½ÊŠT%NÀ$¦À\Ùž¨áF×Z#I£à[)Kœ$cÒ”ÔbÁ¯ëóæ:Œ\dÙõ¸ä®”éHŒŒIÒd˜„#£$#'"0ƒZ‰ ,­Ì(VÍRVw=»LŽÊV¢•aʬêMjÈHÃW–¯¼KÊÉ͕ŽX pB*m*w×sfÅ0H3ßJ³r2~Ͻ" ×À⛉߶û?Ù¾û¢½,°V^ø?ýÇøu¼¯èï1¡ñ0ìÛ¶ßk–ûË©ã—m{‘—V¯üt®Ýq1€÷›ÝÛ~‡‚°C´§Ë¸Gå½áž×–O=;¼Àp–½;°[ÇgìÛ6ŽvÞ*†ƒ !xÃa¢8 Áò>3´#žÏixz…Gâ«þnÿþ_÷lø ø7ÀH<$jAÃlµ¥&ö—‡GÇËo—éÿ;ð?üo¡ ñ xÆõŸÎǯ_¢¿ÄëWÈ’8ìˆ'l‡G–»=|äøöôæ½ Pp–ý /3˜ n–1c¾˜40Ñ ¬Á>ž×Hü$gE?F4›žã4¶Ÿ°ü‚‚ï¿Ò~Ÿ¬s{™jÅÍœÏÝ­LX•¡§6‘8`³¬.¦!ªä)uDƒ—ƒ¿2“I@š–<Í’s©.¸iÒ=Ks-¼/•æPÉ´î ŠžhHWz¦’EÚŒU㵸%ЉDÒHb"fÎ}! +\söõ™¿†FkUø)K¸ày¢ëã_ ʺ6Zn7@0Ò–•Þ NÑr A×XÉ@sÚm)én7娭_,–6Î>=/n›vÞÄn‚ E„è‚+3TW.{qš`,,�Q ¢t_J?"LÃóIV‹W³ÍÜÝn“!ÈÖBZ_µR‹Ñ ëªÖYª¬Àn)ª…ͭЩZŠ{˜‘¡¡ÈÑ÷ç§>|üðüáãØ¿šããT*µ™š™"Q>‰tÒœŠ sUÂñ©É†PN¦ ƒ9JªR#Õcñè‚ ƒ‰,ðË)K•a2&†Qt[%­ÇÜ—[{Âe&wºûâ;ÝÎx ¬»}"Ã53,ëÞ [Û‰t÷âÅk-kHi7ÿóÊóææA ™ëé;¤.u ‰”Q+ÙšT35#9ZÒc2ÜÃÖåEY=Á§{’ädIä™ gˆ>}„NR%Ýa%LS)h^\¥„ל^J­^É ˜ ˆ–¡ Í©=té>7C1wè¦ÿÈ×Ü~NòÝ!G?íỨ==ïŽ^Ž:¼ªœùô{˜8DíÐxý¾äçvw cC÷«ÊÑðeâ4ë@<¼ŒóKƒÊC¯/{k{màEWÙíÁ*^ËhQÚìÐ¥JywK⿱êm<Ò`ŽêC»ƒ?øˆt CÌ~žÐÏè?Â7oðŸPð—ÀŸ¾£½³a9àÀ �ÎïðEŸã8»ÏÁÓWE÷ž¸ø¡°{_¡œ Å>œ¿ùˆßŒ‡¯^œ_mè@Âwä{ù;óa¼ÓF¿÷¶Š÷€!õ«,Ǭ¬—Ù‹®óº!ŠÇÈ¢ò³:gyýN§Ç´¯˜Adëy—9Z8¾*@Ýç÷A<ÏŸ<ðtø£cowj§®µí95;›Âž‚fݼwKmcW÷ÈôÑTësRa18…iV“[Ò¹PEÅĸݸ„9S™ä„”Qvm‹Ú¦E¯I2MhD‘DëKÆû±ö>¯–gÙ•ßZ{Ÿs¾÷¾÷"#òUe–Ô•ê¶ ƒÝ41ˆ¦nE -ÿ…Ý##4и ÌÅ š´]`)Ë’ªJ/3òý¸÷{ÎÙ{ypn”Ôà‰‘r’If¼Èï9gïµ>–J#ÔkRDŒZÉêEÅ<ùµéÏ1U%ÿQ…m!•qX_Í=Âg?Ð"á­$˜q�0Ú2n_ûØ0‚&sÖÂ%Ÿ[ËóëŸ4BWÙ´¢R Nt-Ö]KJUYS]Ù3g 3i`µB¯ÅËòœÉ5ÃÈ+Ì<˜é«B[šùfVõ3)*% K9!Ái¤ÛZE0d(p+ŽZTœ."™ŠD,^Ä\½°ÑÏçóóó?¼~úûþt™ó%™Q ¹9,Ó%¯L<-F2Á„îÔ†õ¬aù=Ôš6GVq07¦­¿Š8çȜ̲ôÌÕKc)ôºÚüFSØ¡A,®aº:aIa³dÂååztä ”®|ÁL˜Ýb×*ʧ n4…3 24º•R¯ÚéKª„Ñ ÈuëÈÄ\¿XF¾AíÌðõB–©2 !ådL)'’),epJÒM“ùˆàâ S cZ8ËRsä¥ò#ŠPd6ÜöB#KXZ(S³\*‘Èáð¢YÌècæˆÈ½Ï=컡t®Õ¼Á„zö¡ —z4¶¢îB!¬œ¾?žÃÜè²;¸c›ø¦7ÏñõåòXÆG¼Þƒ?‘Ýùí!éœá¥Ä#•Ïyw»]£:>Øå1n>Ö7__쳦ãÑzñ§VNØ`ö¥Ï‰‘}ÿ~\~|j†¿0ÜÚCúis >˜N`Å$ËIŸ0áéó—Ø?T|_ð» iø&ð£·ßýóœ Àé/ßÁµ1å@àqê§:ŽÃÞ>Öv¯r_g»yª¶ã׉_s{øÒO¯åýÝvoQküûø’ÝÚ‡V½~$P6Qêi­4$ÚVk>8N*ƒÊÇQDk©]—>^/öƒôÒË-²ô4vÌh`wÀð'Ä¿6µm¶È.{.85Cm°Wôïàø³ýëy~}T}SÊkàÛY^8Gä8\¨,ÆBµŒnñƒù�Ïð ü‚îO–·²³º1E5¢”5p‘‡×a {Mâ»Á‘cEFi“MÆ�tb¹\y•î3ìsU²’Uæ´ëÇ<!)sT‚® Fa¡…)]²5皇¤–áy¡—«N×#aùB¯7ÀÏm$Vˆ�°\í ¬˜çš-㦭gÃúgðªñ±ºÔÓ´5›ˆŒŒ”´L�–‰P@,ë)L) "³xcñë«„'–×8Á…ò�ÍÜæeUàª/ã‚–»,’>:2 W³Y2-Â#«P¸P žeÑGC P ä@3"bïûëëëùùešyé F©±Ö- e.t"e3˜°]™.:мÁ€È+i™ $‚DjýÊ€dRÊÔÌœ„MgÐä\ó:£¹C«æ25—v‰npÁ ¯.“*åëÀ‡�EÊ"#{F\„31@Q±º H–  7nQÜ™iI.àµû!)23s§3MóÊ^ H–RÎä›BÌ’Q³Ï9)fäN®X ±=ä@VÝg Ãç‹+]i„G…*YX©²èJ¯–—\»¹Tš) fQCѰÐÌ [�‰sÆ®—{Z¼q ÝÍÒºÕ»O»©î³ ¬–(çZô ýÔù åñˆrSZcº’é5nmT¾Ç|(½£Ýº™AœV4³`´vþ1žúèä½E3õœÈ ÎÇC¹-¸x஼ e{p;ÉGbª¾ÆxýÉãÍü€»‚Û “ø~òþ2kìÊáQó£ÃnàÞÑ¿ÃÅð²ãü]QÞác~gàG_ü ÇÿçŸz6ü#+ÿo��GÀñ±�ýçöõ‰x Õ´V¬ÝY©—§ÿöÓ±šF}ýW´Ýî¶ÝdSÖBÜ}1¬öfx³Ôt/8ü ø5ä§l½QÝç@9 "´JŠnûM^ºÿ½ðËG¿KÍVvµà1j+Ux0üç’÷a?r¾VýÂ*,á×ïÞ'àËÇ¿Æï Ûf£¸ [L÷ãÈ›QfÇVZA±a9”/Ï¡®bÝñÂxñ|ƒ‘åeÒ3–„-É ÌmVg±YN)mp˜Í€Τ¡¸6´”E1“ªñ ÇWBéƒ $á$Š9mQ¹?×Ö†$‚ÈuA³ëc_ú‡+ý•‡ƒ%Ÿ7[ú5o`@‚W‡#á”q1,¯<§HÑPÖôêPÂZ‰¯ËÞ%p GØjÚ­÷ü¢:ñ:pºjxrº¹g.æ8±p9뼺’B¯³pYÁçJ°¯¹Öº•_ÿ=´úXRîFw™X"\p°h-ˆL´+÷VH)böИ41S™{Ÿ}̉´˜ƒ1ç5^“ÊÛœiÁ4›T7ë¦Dl+%=g‚>A 3IÍÌ@˜Òè†ab¦CèÊ.ç"ˆ ¤)¡É¬+Ãû,Šf(‹Ó‹Ñ‰º`´­f‰4]÷�±ØèsÄŒ±‡^ /²õc Ð 9ÆÜs…’e¥L c¸¬˜ƒ%m!À´•›‘‘ŲP…t¯©ʈ¡à Ìfç ‹ sZjK_4Úäv™A#¤a#ŒÌhÕfæ9Î9.Ù?eðB5cdXÈvaF4“Q¹ÜéÇ%j ô‘é£x¶ŒäÀeÚÈ2*¼¢ˆê0Å�¥`\|¤9ºÎ>J?‘¨‡ÏKÚ:KªBÕvÞôv|=¶²ÿ«€™wWÏᆗmOÕ/1«6–7­ œuøÃ?¶@›区•í‹{5ýÃÈÇè²_žì„7¼­¸5´Èy?çý9ÚˆnO(¸&Ÿ7Ô€‡×_áõ[|ú}ä—øË‚?h¸'Ú„îÐ�¾ý§ž ÿˆÆ üðP�ûG |‹Ë7§sâ’§ÈLÔô[ðÐß´h¯¿Úfk·Sùšuw×±šaákpU\|?ù¸€ôÎGw+lÈ÷’\ÿûç£"šzÕSÓ^ë›oþÄnÿíÏ‚^ÌAlê¦Áy’#ì½tÄeN¿7Ÿø8 TÐqþø/ß¼ßp¬¤·[”˜õeÚÞo¶yh|Ã'Ë>X|I;gËÐ1y¼xÛÛV¬J¾³yP±°³jƒŒŒ"cb§Íé[±°¤%³ðt“M™WçfÖÈb|5í°DòµL1 QP–)›„¨Xþ¥É1ƒ¥ÁŸÁdŽ@tMÅ5ɽ,=€AfK†ÏQ»npÍ1]ÿ¸’Y¸ÙÉ%þJJ4-š&Á¤²Sb®ùþZx®GÄ5뚘„#¯ßà™ë!‘×i§8R¡¤É˜–Âòjš­Ïa&d™JO0¬i,²kTVL!V*tù®ƒ+dfts3À(˜Vp^àõhŠÌ ™Ê˜sŒ±Ù虈9!¸¥*M3#³Dtaª®<ŽÌa®WçSSߦ9 ¦Ùçkdzf*{€b‹œ;”3XˆS­Sjíœëò6hIÇ5Ó5)ä>b¿D*QS„W.€¬0ωBsH’]6Fô‰4/ÀNOØaa®Wå1%up‚Írø yÀ²–ëkc•–Dz¦e”\["UªÐ)”ÌsΜ#lOY D7}/¬¹o6}å}Cuq†Ï¡1 6£†jÉ1/ýòÃ8?—iÁdm¤É")X¤í°Ò rlR ר:’{±l¥LÄœýœ­æ­Å¢º·YWÆ: 2Ò Ÿð—DóîÆÌË%^/zyÚþê17ðrÂÞ|äœ)Ì€ðõÅï÷ííSÇÁØcî>^´ë¼ÕÉý¥¼8χü‡ÀÄdC:4J9ˆ‰|=ùZû°Ù}±ÖÕ‡€3Æ÷§Ã/ѿư’0n@þ¡FE´ÜÛ'•ãxòí㔉»ôŠðo€ŠcÁ¿kÍOMh‰¾C¯èŸpù§í¢ÿ ëÃÃö³Óü-ø-À¿þ?ð|Á¿Àã»vàÖdøê‹íö¥Þy~ÙX»uÐÅ¿=ãPËO±å@vÌ1ÇéòŠÒ{¨‰ÝùÀršŽKG$2àÂ'Æ¿WÖ¸˜ª­4»-vø V‡}èÆ¨ç^ÍJÄctÔ Æ{Ä:“‡žÃ�a4ÄOÏ86lÛOÛáXËÁ<¦_z=ïM�¶ØŠ ½¸!Ît&|êÝ” ðÅ›j;¸½5{G¶4Dó´W+gH̉ TB´% ¥ä•N/^¢š¹5Ïj(ôÊŒ±Ó�õ™iVa ˜Ç±�� �IDATSðA%¸Óvƒœ2é«å¶ô+€ÌYŒN9„9SœÐJv[«iù›&Àâ)áênÄ5,éÚiƒ4cšea¦CÕAK+¿vŠHb.ÙÄŠÅÒDØÂø¯‡1‘ë¿À†Ö\e*¯€‡ÔW΂ø¢7­êõ°(Lf*r OÅ™ndÐbZ²:‚\ )½ âZ^¯ìŽ–ß&™(ÉÅò[ƒ– EdŒ³Ü“;¬:�EaXÉØö°3ÇÎDf´ž…©4ehLMÄŒœäÎÒdž^Órmÿ)æ`Œ”+âfŸ‡M¾'bý’B›F5Ò’nlœYZñØÄœÚgÌ3�Sü m墭¤ hjî !l‘mÂF¤ïIA_uìD.½3fd1ÖL¦ðùnpå1®™W€s…Y]W°S‘ùbJÆ£c'€œ‰§Ãé0#tÛbd'gb$&F+ùbª˜Vû¨ÏÂ+ÂÓŠ¥OÖ‰¥¬¦©œŒ‘Ñf¶)ŠÇª9 ÊîéHs¤oƒÕXF´ }dPrõ9Æ‹—_:¦Ð‚þ’ö8ü—ÇË©�ÜÁgdyž÷7ªÛÒã,SǶG€¯j¡'ÏbÏVJJûëíåìwù8v´•Ç�n¼îcÜùc!ÌÀ„^°ÿÕÃok-h^½¾ö‡Ãÿqê?‡þ-p@$&Þ÷jo²Þž£îæ=Yof–FÞqýÙ~‹øÉWï9ï{­ÔÅcï»0ž‘wÐ?ílø/h¬ï0îqºy ¿oxÈít9ã‡Ox¾¸_Ü=•ÃÛ]•în¦Å^;Ù3vzUïM;¶½Ž×x´Ä8àP°àĸPxŠ@ì¸ƆÞÇq‰Øô{‡ß`Ûîu¸ïhR÷|t<Zùé(óõå§ãöý!ßó+Ú]Ý/gø“ùƒpâqØÞÓÚô¶àrr€uo%Ú„Ïh™®¤ašŠy–; äÌ`Ô´¸)ö†~Û,HEÂDî0t |0èátw¸[1QȺ$:×ý5šl(S ¤…Ü;Ä$_̺y1+¾´e.^9$7™å5’¤\Ä ")3¸9×góó"zÑlMQø`æïå‚r¯ÉLÉø÷,uÂh¨a×£ ZéVÅâ¦"L™¸f%ó:–V·ŠŒ¹�O#WÂD*b1ÊŒ…Kñf±HϺÖ1Ì`b¬"sÊ9AKés3¤{‰j鬣‚Š5HK‚Å–ë8‘ŠXœ•ÀZÔ‡Ï{ú”à0ƒiHIuÃ4£ Ã…ÙW˜<Nãà–j>DÀ<†_&bi>‘;ò 4é0dÌaÙ#Ä´ÌR`™§™D³ôë ÕXh ò\k¡ÜSCاÆ�ÂÜ´À„`¦å´œ+œQrë2ÖÓp ç“6`ãr™Ó̥닕WóžÕéîŽv]*³˜‰IN¿¢ ™e¹n¬30"G2rA^š{&ÑÀÚÖx*Ã1g¤&õФ/ör_› Œ¬²Ä-Â8}¤_j± Q®DÆY=5,£LÝwÕ¬¼èÙaÎC:æ6� `ØiÖ¤zyƒ:4 {ç´rîíÑò”7ÀWȉ<bk÷7ã>{Ùqoÿ„Üò]ýåÜôÒç¹ô2{åqòÐú!/1™ý˜(þñPáx¸+§•æ0!8²Ÿðç,º¸íeŽýò”?Gþ ¯\~À 0âwlûšw‡Yùª{³£E“ß7Ï(ψü„ñ ð-øé¾á¾>·|×E ¡¸Cößÿ§Î”®4ÖßÅØðؾÝÂêûÞîuŒ¿º}üø«¿ûç8~s:üËõ˰“˜O»?MŽËx,/Û|àŽÒOê*§žèwÀØ0…jX"W°‰ìÚO¾a?àRÑ…K<ÀËv)_f)‡r(ÇÖl¢ÍÑZàÕΟmãûqÖœ8ZÙ=ÍêÚ1PÃöpÂnP?E9ŽÎJLsê–ìÕ/ÎgƒL°9 3lÖªWa3"Ó^<¼:áYW©27¡#ãœanN;ŒÌu³k?™Z\1d¨ÎNV±‚ºÍŠf^ ؉N0­v³Z|΄‚ bÕ~×S_º‚ãDËÅB»æßס™HYYûõþMfiq4¯ƒw-aI™eñ‰ª% 0+ɲ¤Ò²LK±.”L[eÞkÏaq¢VbŠÈe‚ Œ*`J,ëyê<ÂÝ- QrQ%ë h¦Ô"µ®O'S†·fKÐ,ÅBƒSî0Ù\Û˜‹±%б‚´Å¿½Ækit®Î³ÃÃMK8·L¤V�áèV–[RiEæÌY‚ΣC¦×F6‘55ɘd‚9à{g\“)^<A9ÑèZa=¢ldH„Ô‰Kâ5±ËDVC£Š›™`ŒL!SÓû\tòYP áLaBt@læX[¢(aí .¬ÈkY ¦å äHhÊ"9 YLKÙšk(#b“„Ç¡¤Z ¨eížDLr´Ô¦´H¥b.8¼¦•¢dK™µ§-Ò÷É·Œ õÔeÏñ${‡òf!Øô E^S]½Œà±×Ë=Ïò|žmŽ/.‘uŽm¾÷-ñq«yÈ«!8` °B|`Ôœí‚ÆÀ¡TÃæ/æù~{ªã8û—÷ð¾;\½õ§–§ó@^6Üqï8Ì“ŸáŽ0˜Áؾ…ã1ÿ†šßŒòm�ôõ�Oôýá¹ÜÌvg‡ãKÕˆý§ÊÛ~>6k·Ëó)ö_ãå-~¨8~õŸ*>µúu³ F©6¢œ²BïÐÿɬ½+õ/qú1пEù ãÝ}ï÷Ïhûèö‚?øÛÒ ¶œv¡7Vή'•—WýÙËD³÷îKT懂GœÃ(¸#:aJã}™÷úeÍ·Ò£}¼1…'å÷¥»‹µ»[O†ZLÜŽ5À.ïj4£—ò³¥%<^ÀŒ ÅáÛ{~ ‹ygiÒà9‡'­d| î—ñ´Å™aŒ£á­üð@Tí"ëfFñ +IÐyœÈ$^˜¥fr˜ÒŽ”`JÂÖµës[&@&wkD’&ä4+�mö ¨Ò"zàGÑ“ž×«k`™W”™`Š(_1’kè}Á¶¯2ùÅÆù›Þ´@À„¸þØ×ñ°N ¦ÙŸÐWdׯôçÕÄ’ÿ,f*�üFF÷YÄ@¯´"X®u5 äëLªä¤Ãmñö–XÒ vu2é0˜ÜÓ©—úJ [»ê 4傿41é3L‰ÌsŒH89Ý*< ÅàŽkNfõºÝ ÓRí.::@f%îÀƒhé®”!+He!ɰ2DÓô�2 ²mE·ÒYH)¨LžÍ¥€mLØLÚd9œ “ÍJE9ÈkÀ#eÔ¼ß1ÏÐonG·eGmN2±úë¡}#¼çL…1³ F d×ÍÁA§TäË3nTÀ¨v¸Ìˆ)2"æÙ)I¥Åp$9W4iBS½çËœl°…%ÜsyˆÌ´ æz¨•ÉÌÚ¡®¤Ed3ºÊ-k*{5½zÕÈœOÀÿINËmsx6K—ΨmM¥‚1K?Ó{±ñú­ïWhJå·KÖ0×­tœô~+þÖ:œúžœ±—ÓàÏx½ëúíÑpÚeÿxû=üop@~uºØûKùWõÑxTâÓ þÓ=þ‡8î‰&XY•WôŽ2¹ÄšóÄ·dßZÃÖðÁ¿yŒ:UNÞððCf³y#jŸ‡—¼9w`Ìvš_ã2ðÝïb�çŽ6Oeû{Jost;ÕgŒwèퟭ}úÈ#>=ôc=ïíhù‚?øTïöpóöÔnâð§" “B'GèÏž_M|5ïûòØü'7X„ÛÄËD1´ '\¨yÏý^_5Bq oØ0h>4uÌ̘k^óèO8¿ñÑ¢ßU ;3¾Ûò¦ " ì|ù•ô§² ÖûÚÞßY+6§òœüÄ b¼Žî…Ó~¨ó‡/¾OàË,ÑÆ[G+Þt© O¤J`›l{¶„h MD–ð›îY§ SNÈS.QÍéfÌ¥WçÚ5çÚá.Aôë¨RW ¤'¹­ ¹XiGZKTpŠ3ˆ0éYȤ_ ËXe‚¼~Ð\úÆk²Çl¤ dæo³TR >'æ×Ê{…–`\p7…Äõ/|m[_)Hr¬’}¥pWGDZÂŒFe$m‚I&×vÙÖ„§@ÅfâJøÛ²2!ã*¼Yfœ…Âj«AKŒ<‡¤%\àˆ½1”Az­*”š‹e¾N€…_Ò¶"Jä„TÇÉHH¡.Îô²;4•ÆŒ¶àµÄ„‡Y’™ZlÒ!Mc‡¯ß!»Óž* šÏ´RÍ7³ÂÒàEðPfG/|1{2=/R ɵx6³UV×°@ÙêŒ&0J®öö¬&J.#  å!±颫 ,A�ÃA—3Ww q}Iá”™»ÁMŽ ­ábçΉñÍéë"dË0Ë„n ¤-Ùá™">©‘e†(C_i L#n… ë3>eNêÿ2|”ùµC™/è A[t(숑 Y}fuk6{f¼ÝúöÒ­G™õU…*ŽTÄ1f}ê—yê;n_qIí±üùßÔç·ƒ7µ 'êÀVßÇážw5øáÂǦ?9ò—?ã¯1wø½wøßÿ.јp=D9í‰ö Oà=ÆW`¾±ñËûÒ›¾¾½ÇWOœØKûXñ_‹_Ü%Î{>ï=¿zÒÒb~¼Á¹âï„;á¾£Môããì¥Æx¬ßc3ä€ïæ?_÷-ÛÏOåçì›þcàý·}Ãh¿_ìË*õR>ŒÉíùïÒªqL<FÃtÜ·c©xÛ„Æ@{®=ü–N0wô OÂ@ƒÏFÅáÖü˜%¼dÃÿ|ÖDÂtjúzƒ›ßDyÝcÚ´ô™ã¶Lӎ´}¦4s߯¹Ä+ëËl5sôñxù„z‡£?°Tó£•F3–iQ‡12³B•ÝŒU³Ä˜ˆ#+R¯fÞGT©ÐAvÛ¨Y§<DB¡RCµZªW²`JWšÖÝcÑŠÀÉ”±Ø ͨ¬¸¸˜HD$Ù‚�™‰‡D¡9lëÚWCJvÀR…¿z…samõ €PäL¡”X—Pw=(´”6 …D"˜Òõ2ÀUâgÈ7BÀ•Õ~N1)A+f|M·WØuŽ–\sÁeþëò@«•k jBúuê„ì¶ ƒhifæt˜'@K  Ìœ 0%<fRÌ«q “’Œ‰95ç˜ Ë!¹I¦µÐhZÛ•4®¾œ.–#;Q§‹K¡ÑÉî¶’�æ®9QbÒÊ胾ˆC#Ô%ÜY€‚˜f’p;8Í­Z©r5ÄÐØ;âø¡–s+o 4O·éšnsÁs-ìeœÈ@¦fÑðP"IN³” NT¨&Ä™E±ìÓ¤G!3\ G *˜‰df&×û3»Zš› æ MYX‡D&×\Af‡ÈIrvÍàœÈÉtɹú)èÀ4L° ÌÄE £‰‚'ãÆð?‘ø£Ì[©Û|ñ´ at•;ðXW!cóñÎóG·û¡žÛ¬S¥›öz¤02sÚ¹ç(o§_7<nøñ îC~ô·h7ý‹S=À %Qæ÷í«û˜-!ÌÛ l¾¹Å?>^ÊÇóñÛ 3ð7g¼Í÷÷˜5Û‡K<îûÇ�ž¾ÂWBÜ"üªúq»œ[|åü´éÓÍåíkT ¾× ¬<qŽm¿¼¼|ÿüׯ1‰Sýï‘ᆃcÄÃÝvºxwù8'ê'Ÿ¨‡O8¼Å¥ÂÊ?ÓÙ°JÑ ¨À °oëßaìß<özrÏÖ.ÞùôØòOxptÄå Б:Á>ÌCG™¯£úéx[ÑØîʉy9 äfòê0ʇæÏúˆñX&&ž0x;xßú­ Än~N+šØ-¬Î,^müµ×âÃ^N牢~‡ÒN¥ý±1±qAŽ-pO¯Ön K¶&›7ž,•hgÖ]Qâ\äž(8h«5ªhËßB€‰0Ê`¦æ*Lª2V¬˜7«ÅÜÍ+u ˜KE…r—|•i!Å3Ä•ÿ÷iFùâÕ-™ýšëRb¬›.C‚[±Êe»YzF䈌šA`ùÏV¥H™ Ô€Õ¥âUÁ‚˜Ðg¶ægKæºõÁ�ËÏk- óúÑ®=3µâY´D›«î¶¶Ó‹¾WH¯nMínÅM/È}ΑŠ‚4[ûv)»4€™LÒDÁÍ¥ëB‚A%™Xr‰)ZæÂ„ËósT"¡AD¤ i¥+H_JÓ…p,ÈuÌÅbA$ÉðHd Ë0w¢Ò óô’f Lƒ|2+]äM×À”&åÈ-³Ò™PÎl3o¾5+…e™rÂrŠZ¦½™#õ)5FV騹ç„)C†Ïþo…,™YÊÁœÄ®,Om ·LÑÉ 9S¦´a•ÉÜa`&Vâ–©YRȈëo:&,)Æ®jéÅE¤s$3¯^!•šSQr.Zw¬QŸ-|Š’9l^œì2ºN±*ÏEm¬¦´dÉÙ#.˜i8˜ ƒ)’»¡’ÞvÜ Lp¯ve-“º€A¯v(Úr”˜öÚJ‡§—Ž×’—àKW§tíyy}Ч'þâ­øÝ�|_p|€mƒN÷²‚ ÖÊ^·³c„ì ;ÞHG¾³»[; vàˉ=FÞ_Úý<´´~I<ð¼akh†Í¡<É>tõO£èXË—ÀEû—Moj·ŸÞÖÍ>žcüPžÿÃwtÀÿwþ-²#ëû‹ß£TƇãöxãíŒØO#ßa~Bù9h¿ó¦³aÙ@äÏPß~´ ~õ°}:þðøUÝØª7‡Kůøx*ßÀnà­ð&q,ñ%zVæðþ�•÷f÷jÑÏǘ/�öŒíbhÎÂÑnËG³½ààøX:¬?@ØÛO©7°#½Ô«*­fÞ ›Ýæ‹ðQ‰,'%bCù5ûÍ/4ß®çm ×8ŒKÙ/Û,Ð '&¦œdݲ¤ì°«‘E­²¶’­JªŽ p 5ôŒ‚,07‡Šëà4w¸«8œf¶Ñ6¯Ôì+-`š”€å´0œ3)›n™ók. à†€q±ôåβ w€­@æ˜sŒ¡!s•LŠ©š94!p]M¤‘ ÅÌåzƒ¬êÙµK¶ f¼ÚÖkk‘ž‰Ïð:2¯OÍ„`Zç^‚N:ݬxiÍË+\ æ=âÜûëè#zÚôRŠy#Æyäó@T¬©×H Hºe¬Ûg Ò2Ẇ@™<)B‘È`&×Ò} Í}iul¹ðVª*–ð@3sΜ3g^I¢KxadiÕÝWoêJ –p(Rä�™ê²,˜Ä«¨LØç_Aór(e³VYF.1÷ÔŒ²Ñ5@œªÈš t—T àIRrcʘ&Q¦p¤Òtˆ›ÔÀµÔZ#8"3‘4ʯx¥%ª¤4 ˜DÄÔ˜ˆ4Š6áSœ‰Ðn¥$L¦d!Í)šE*cæ~+$†® ¦#,Ó4 íR¢$JŽÊˆ˜[�Æ•‰ #°‡Gؼô´ï[©¦CÁÙk§7ðMêË@ —ØŠ…ÙÖf‰¥#ßÓ§¼É*àE,©XPsoÃzæsìaó"$ùó±Ì_ëÇÿÅŽnï7ä~„—­€và|âåƒ 6m¢”ayC/ôZé—Rà§Š÷Û¼s‰C×!ì£ú}}ø‹rú X;¢>^pû½9îüWfÛ;ÕÛ~·³’Ùb´^ö¹ñáøoNý¯ðòs$ðÅw°ð~ÓýÙ›J¯ÄF!˜|ý öv ÿùÞ ßwÀñ-ô%PÀyÚ8áÓ‡ßý²ÿxÃ={©Ãý4¿Áù n‚¸8LXùØ7ìí!òd;¢cw »ïm¶6»wPg$þ”ø`Þ,áªE£{xO|Î'm0}б¨¸TíÖ¨#tDl¦Â‰ö0ì´¬Àºƒ?Ãð>ç}ç–˜11ÈýGãu›£Ê”³Ÿ©KàEû‘ Ýb’¥›íÄî“V-üÖ¨2§…’4ººbxÈAZŠY%ÜáÅ…Ë k —´�‘Š+ñè ƒ�#8Ú\J¸Ö•ÓTIrMÀ)3‰in¤›•U ^¡ˆ3ú˜s¦N!Ó"8»ôCg`¡s«Ò¥\ö·4’™n¬K5¸ÚKʸfW[ãz2`)åÒˆM¥4k­nK=ÐW.k=çŒÆQ¹¿ŽË°iµKÛh6çd}íÂPÇL³˜/t¶œÌÕçN]§^$e~]£–\’‚Eì\fØõ`À•µ3²ÏÜ—›,§fDfÌ©Ê0HN§ EÅ­9¡€E$9KΚÝÎæœÚ ƒ™Ë, gA2™»v4ÕRÖÊo:++”CdÒËÕ’Têˆ^™ ¡,C‰,%—¹¹OÒ¤ÖÄtyƒqºX 0ÍÅMDN­çh)a.CDÌ…ÝM8�1‚rdÎn1}ÑKÐÓ´ú)Hï´ji‚e3k–Ô$Œ#•cæcby“’R(€:„¿È‡¬[À57Âk¦s:0’ê ²ŒîCçÈÔÞš.ÅF+ |£<(&Š—‚Ö¬†cb¿t$ÐW[©"ê˜-A]Tæ­Ÿow·Çz.|}š8XüG'ÞÊ„]g;Ý”x� ËQbŽ´’¯|×êV»u·ËÆvÖŒÕë½îGi´*`FwëGŒïu‚ G L$ýã,RwÏHÔ<ó²»¾¢ÝÍgígÐãpsº1¼þWøkÀ~ûóýßÔý®=ÞµwGL«óް‰øŸ°?ç èÿcýÿûlø —{¶oP*X` �¾¯À7@Dǵ±´ú¨#í¹áVØ:j@Bq¶Ó÷@%ñ¢‡çY¿PÛÔJÀöjù€×Sî(x”Aõ+›XïÕFê¤;Cßcî(?yÌv»Å!ó "Êx•U+Téãûrº1°Àò!§úv Ûî‰{ªetíg޳^îüR·F×ø~äßYùåÌŸ´øR¯7™¯ÑîÂkrTOW:·Ï7g"iS‚—[s1Ó2§±/Õè¤yƒ¹¬ˆ®Å1½F{"MT’¸2Je©TP#TY¸ž„‰0„ˆiZš!I–ƨ�yÅc3•3 0§Æ˜cjÝ rªûHCø,¾aµ’†õ·+òºÓe.M‚9an$“ ë?Sk¾”¹ H‰¼¦U‘Ÿ•ó+Æ [«nA`ÒÝܽ¶R·R7zÅ•V‘‚y¨ØŠoìœVê±¶Ý9gsgŒKr[è…{ËZkNiŠWÜÍiVœNŠ�€fîNVÚj2P S¢Ì˜½Ïóœ]c`fä*é…$L/¬îN‡ JAs9™35Qºª2#)M$e>3êJ/á ^ šd7È­n^ÅB?²ÜIfhbõ©ËDJ¥÷4åX¤@]®›ŒTJ1"¯· ‡‰ ¸UŒ^IJ"ÁË&·hº‚%+Üiž@‰Èt-*†}nÍddvi(?ÓÞÇL§ Î 7ŽJá¤# tK·€íÓrx–Œ0MeÑ’k0ÌÒ˜#ùY R×Dì1º&9b\¬ú8x›Ô®üûÌwð< J)Õê!ŽnUUsƒò2û€ÒJ]ìÃ:ü]©u·¦B—C)·óÜgýÐìñÆ>–x_âþ ZõÁüѶ½@%\°ñv76ÿ_ÖÞ¦GÎíÊÎ\kï}ΙIò¦xï•|)»Jv» }õ ‘(FÚ‚!$l°Q#û§yÖè­Ö@ž D!fp@UT•ë^9ø‘ï9gïíÁ Ê?@8H0Df$ç={¯õ<„D0—m¨A£IK<¦ïG¿Q+aÕ—z’4œ´Ÿw[^?I\'vÒXí&FÙ‚åÄvÌc)¥”m\nÝdåx¶;”\Àå?üùñ7ò÷( úú±Æe{«øñhÚ û€¡_c à |Å£CˆÃ>Szöš‘ÀöìKØ�€10:P¯^¿Ý¾ú1¿iÀuÛ½b}½¹€–›ì@ÙǰA$²á ëNû7›Û—ÒžÙ›I§¢\›Ž×tDüüØD{»¯OŒGà„²ÜŒRïÆÅ“Ó6%]žî+OžŽ‘«Øáʱâåz €·¬•¥¨V‰­ H¿ËÓyOUuC$OØA.¬îá¯|déÇ£o·\šl¥¸wHWû䈟 Jª!B«,T£`ªu,¥$ôÌ”8+{†Oè&)Êd¤õ>|´töLIdÂF3§…Áƒ³®ÀŒDÊ4Êrxxöˆ½ûè3-$l<=N")™šº µ™rÆ<|&^™BQ1(çj4“!© 2˜Îs̃äÉÌŸò<Ô LLf¸NUË|ËÉÈø|̃͘Ψ5X“Ee+’3- 8çNÃçül†ED•"J«V*Õ4¦zY¤‹¨ ÅBȹáô”pï}ôcôìŽ@F¸xfCBdcVJ1ѹÑPBŠ©‘ÎO3’´pGØ�ÏQ£!3kЍ‡HÒh,…u-´Ï¼“�� �IDAT!Èèlk¬§ž#RÎ!1bjš5d£Ò% ŒôÌ’“ћԉ¬`(<Ë …B˜¢1;&ÓÛ'žSÔ$ø—¨’LŸ¿(ˆÍy`ª¦Ljá\$eœ»FŠÐÉn¢EÜhŸå9ÈL"@O(.ˆtÌô,5a#‡GHt¡+˜²$Z&ÁŽ¢J-Š!}ºòX�”u§1 Î¥äf)Aü‚½g{šB„^ Kñ­¦B2·"L¶‘OÁ¾Úê~äøNvÐúòš¼’R¤C¶ÝjsEâ×’×8Õ¥´±`tÁ*�P%¯=®Yk ÑVÕ¿÷SñQcÁ0Yx~Xïpú´ç7·¨m­ÈlK6øŽ²¯ \$.;–�8rÿ>nµ·ú öX¤Êª¾-QBÖ£OùÅwVöf€½ÚèõóõËßoÿú›‡ív­Ëá_kQí'?´ pA(. t@€«4Ãå˜aýý ºÎì8` .€©¢þ|{‰gåºbˇzô¦ 6Ë««åÇÔ ñ§õâo¬¾žíxø€Ã;¼}|{€âTJ»¬ýÉ…Öÿ%ðÏøèñø•cÝþ² ðþöý j7X ŠÍGè~?¿Å×Gç©•tô‹6ªŒ¼ÂÃÖ_wBýº÷ëÁú)ÛBôå[û‹Š¢"´"R3ÿ¯XoÒ[Ilº,XÖS]¤ qÍ¸ŽØ™ì2Åõdgñ…G‰,vס æµ\5³œ½6áÄ�:©>ùÖÆF¶DÐUS(€°á¹v¬ ½d@Iž‘È9 ™ó Á…Îý7} φðˆ g¹1ÊÔ4Ol]:)cBñR … p5%@‚ÄYüy=±Û1Ë!Á<OÃ�sn¢áó¢€1IfP µ´:Ç¢9Ç4é~NJ%á>bDL?¶Fº p¦È*¥Â<r¾ƒÅ)pá>€SBI$ïÉù.UU#32¬ETÔe4Id Ï¨ïÈ6؇Ä(H1&l™Hª«U‹*s¾Èç"¦àš¨¨«‰¹CHé):r˜Ó5 E½�%1Qäb%‹83{z=3“*Pu#³)m  3•>_y¡ÐTŠ‚’2IIØlÄI`€BƒðdH sŠ`'—І¢È|’PQMft ¸g'èRæÄP3kz%Š,¦ešÏy>ŽÏÑ5a)-è Œq ¬F15‰ÌÜ�¤Ÿ4….‘!Œ„sù`æ‘»Ì\Ò…2DÙDö¥Ê€µÔL»eV ­Y¼  ™aÙº„G´Ñùø‘ºg½QbY”¢%m5 )§ò³È²É7Ž¥”&7ºoÄqé7;)*Uu»È;õïZÅÈý¨ÝôÜÇ@;!Á÷¬qõNï~„Ã6÷U°ú€ê@@MpŒÃ•@õŠ›ËÃæ}ÔíØ¹Ö »«¹I§æõ¨_óéå“SYþ$xÙåÉÝv÷6Xcü„¿Q<ïøú•(‰²‚]Q7ØÙ0WÐí3}­P`ŽÀÛ/ ~tu³ÕR×ÚP[ǎ忹â5õ¢îËæxõpXÈ ËwØðøðæõ%ðýÿqsÙþ‘pk›§Ê`Œ'kœÆíﯯÿ O_àô¹C½B¼ ½ðâè:†ÆØl™UŽmñ²Œ’e´ú`õÉŠ6ŠÔŸ‘•@ØÞx?ÄñYŒîب»e³­nÿæã@ÛÔFÔ%EÖÔ™ <’–¦Û€(kDHNLC�nAƒ‰hš=èÎ髟ú§7F“<‰v¸J”Y™ÍÌðáŽÓŠÓ:ÚX%:áaÃç6“9£àW IC ]FÇ„µ1"²xX¦&„ì™6ŸßR…çXjeI…édV¤èä@ÏAε’HÿŒL„ )óaUæyÇúgÎf´øŸ¦(LiZ&ºnôžÙÎNÏÙâC$sž>F¤pd÷Ռȱf jj™í¨†ôHJDŽ„ "B,U\9Q|J5ÑB1Ò.¢T¢0MPço-3Ó]"ˆHôžJTÃT†§E¤„HBg®5˜®cv—HK¦â%Fá"J�'JOî$-‹p'Ø+É`rú 2•³ÏÒð™åEh$E‰ 1o)¤ÂJšA™žnª(X Ä@ŒlÌPaœƒg0x¾ßé̘ÂfÒ)TŠ1!z–Jgjb†(È]RMŠpáçíÓ3"B°ˆ¦Ô”–ié–íC}V#Å! I ‰ 2Rzr œ„.RƒTAxŒˆ'æ;eª¨ bÑÅXCóäÖ;&/Ý2ŠfI©”ô}}œ(>n—O[–ŠàóäS5! +CFÖ­G¹nC¯†@ô ÷§ÄC†cÙ#ÿbAÙ¤€eÔÚÛ~M|l8ÙöÈ#x‡ò?}f[è ÷†¿Kü³‚‹ (P Ì®yœk§ ø„׋ ~q#ý«º½ŽþË~TO߇®ËÀf¹Q/ âBE±[äâ]Â2®ÓËît;øë×þ�Âp1°ý�üÿ(_ýž)}��,À%`@>¿À§Þý�ß?ª7ÏÊ~£·DÂñ)ŸÁ¶wv¡U²: ÙW&7Eö6@?Ãöw ðãŸ`<}Uð /žÞÕË-«‹I.EOu˜|ì86BˆKdERÑÿü:d‰ÐiùÞ#”@]`vÜÓ‘·¨m{DD€ã—Í6X”dÙéøÇº½#3þÛfÙ’W‹Ùº–vÔÿô˜ñÁ6v¡[± kEN‚“jª´!ŒAÛ¤aæD³tBX3¨:MÈÙÒ5<#G'ºJhІf’#&¡¦ —>¼ÅºÆ]ÉŽ•ùÀŽTÎ4‘$ è<” fOÏp§Å}˜ÚöÙKC†¥7BƒÂ@R Ø•j”BJ$EÒ(ç¤éç3KBF’‘1f€sBãBILhöbINÈž$ 0 )C1ªA- éé½¹w­5ÝçÂ"§…l2ZAÖ•uU’ƒÙ™ 5Àqž©M·�":/H:£Â&¢2ùØ1)Sé1Ø WPÉÉ.šð¨I…Ì ÆgÇõ¼0 3‰sæŽ{æ@Ìø¾køDƒ‹“T5÷$4DàÔĢś€ƒ–Et!” qO ñfšœÑv€DÁt ”ÔR}¾Ö© T|Ž Š@3!q�PUf„ŒYPŒLL-P :’]HI¥—óȉs}4â ¦ÃÃy–…‹PRÒ,Y’‚J,” „`ÎLÍÔT XNã&X<˜.euq£Uu!¨3‹‰â 7mÖ„'ë)9å²mMn=wƒËNHr…P¥T:f£{ºù©œq(ƇÈиc{ð¶f7é¨¿Õ ´ÞR¿L½a‘Ë*í.¢at—Ã)¯…ÕTºÇE¶ÄÁ•Ø.´D'„0;Âð~Åßà©ãJP¶¯ž|{½Å—褕ëG\oðä iX'Çš(j€£$Âp/ØÚ>ë«lXÖ»qßÿóûxY~‰|…gŠËØŸ¶·_zÛà¨YNöøýØÊÃõ׌ÊOmùküø7ø;à×_ágð;XÃx„®ðÙð�ðg«ô,Ãý‚¡¯žóz[ËFoUéXÛNåä“Ôz×걌Š]¶–w‚½è Æž )§Øöüâ¶=]n@Fl,¹‘ÊÌE—Æ-ÊåýMýv¿(Êr‡Un2ö§å¦/%vµ²Ú}ƒÉUõ õ©‹Âkã­®‡<òùEÙèUÆS%Jˆò( ÚÆ‹V݃½ø{®Í–*›¶Ñ÷JÅGðQm˜¸Še©Qª4yÜð8j¢ACR\5˜1 \!1/ò¤(Lž+ ÑÂ{ RED™øý¡‘I!Þ‡7÷AO6&…Qˆ U!%!™I r|FÏ)¿9ü Ob¢ºÌÛŠ#'"Ç™ŠLx�Óý’röâÌÕD»ªL¹—1%‚Ñ#G†Yo›O¬s ý{5 Ýq.G!ç_‚ XA©Ð 1QÕs]Î=F÷~í~ôÕ‡ÃóŒ@=Çh‘`šJ©RÔ„E©&2¥÷9³3�ÁÄì^ì,×EDÈ©P Ê”Ûg ?«ŒÝ“ŠH¥N˜¸L3§ Òqæû'í#f:ÀϽ®É çž‹ŸóRâV©¤fU hPÓ•&ð‘CERÌ¡C D¦&Ñ9@šæ„Pô¹…Ùr„F¸L%K@"çÎ:¦–‰I&4Š”Ð¹qÌHè"Q©Uh""êà�N„KÆ€hˆt¦OÑPfm8Ò{øˆ´”JK~3І3!܈lD*ä|ÎLa@"4ÕQU’ðáîéii”Fº¦§Älº©"ƒ^â#Gλ÷ ’Q*PN¸lÜfl" tvxžûž™è—1¶s鬡‘àFRÞ2Ì?~�Db³ôE¾Ñ8†~z,™óÑþûê¿ A÷Û¼Ù  °u_",îÀ‰Ë@°Àí¦g뽋Xó.h7'ì?¬x|‹›ê^ Ëõõòƒ¯—ؕ¨£å‹ÓÍ6ö(°Ä}�sL퇀<VT¼nÀŠ›·ØûWxñOߡܠ|4|‡0ï–S¿ôˆþK;ÜÈÇÒ®k<Ôíw¸øMÙáf÷›=~ƒ|¬Èb\ ËÜ3ý12¬ üóoÑÞ�_¢M´€^/¸®k¥6×ÉÇrùwÛr=ÜÇŠ÷‡ä‰iرû­d›ÛÆÃ¨¯åù nö5nlWpQ‹pGoX%z@{• ˆ¶]ôO—ûØa­ÀòjÈ7«Œ#nSYzÛ´'À“µ•µoä—4Äîß¹ml (;4‘O ÛŸ-¶‘.}­i1š¤ºK.»í–pÓpý{“ÿhò³‚(n²¥B¦k/}“¶ºð–k–Ñ—e~FÄHRž’É>‘ŠRÜ{ö–ía)[l-d <Ð3�t6"#‚QŒ¦ÍÊ7b"¶Î±Ó‘4fW 5"ܽGw0Y™+„8¯þ‚âH™8#L‘¼@(jjÕJÓ³¬RET¦q}*8ဇ‡O>)|NÇ@ çÂtÃ@†3tÂï(A%KIÛ¤Õ”""¡3£ ð†qŠvôõÁ»‡gŽôÈ1²ù„?PhQÓ4aQ˜¥ÊÈÈA† \¦$  IE¸Á¬`p^[$2#=#à=Ý‘"‰ä˜ø*‚8<129]N#"#}nlÇ4 ’#1ù°ŸŽÏimCœ7AŸ¹µêJõ˜ ·„ ‡[Ì—Á\gcpzÅ£3"B¤ÎŠC ŒðàHø�Öô!LÕ.29Æ©p:¦YsRH¦þ4° ¦Â*VDêÉ–ðiÚ! dš½Ó¡Ié¡Óç £J¥%dVIºj+¥SSf À`Ž€'<Ò‰ú‚ô¤Ÿ=¡^$«�šÙ|LE`ç@ö>º rxêXBFbë–GÑ*ŇúP“Áx¤ug6/ZG¶ÌÖ ÄH;õ<r<J<|­—U—M`Ó¦2µ ÞÑOÒ{ìñˆJHî¿¥7y„FtÔ½U”6'¸¡—}Úíí{à¶+tóýñB_½Y¯äeYn/—Í¢ÒM¥�â¹ Û—£à¢à@ ;Ö†�,ñ¡�ÀXd žÝà‹ϾD t@Üëë_7/ÇÞÏžb‰½Ø-Ѿ\q…fè;ì7Àðw¸ø)â¹C)à§ûöSà |(Às|y¿GÍ›çK)Z›T8Z»:êòŸqõÒtÝ•ÇÇÃrÿÿÅ ~‰ÓõþØo[^W­êv¡r{êeó»ÛŽƒh·lUàÑtÿ÷É~ȈÂ0îKÁpÜå«ûåŸd^ ÈÇî8Ú¡&¶ZÆÒk?( vãc «'­QS‘ÝÍn³/˯»-ú,¼¬€ÈCŒß‘G“[n‹‰pƒ&à+ÊßÈÀ¢Ú!=°zf-ÒVÆbL]jXj‘("d EQ2U`ªAIÔ3Äg7€„#=ÒGc»×ذš4óž‘#u„ûˆˆE† UJ‘²M²G¦;ÖÌí#±KNÄ7=FÏ1(  —œÏÂIJJŽ)ý¤Ì:[bŽ%*m)¥ª™¨N¸UÕÌÔ M @Òæü R>×ífñŒKJ`æãEÒ =/˜4a©( ´ íŒÁvÿŸÃè10Z®§h‘¡d žS/×<ME Ch…Ö@f†eÎý$pú?Q‰ ”ǤÍ=Ò=éžA„©|9 1…‚ÎáÞ›·uô5=†‹G´³å‚ó+…øü !. ‚"rV‰:r™³ß«¢ÉqDfÊ9¨!Éái‰t ñÐÉ@tÎëf}ÝS&­ÂSFÆÊ¥Ej<‹X'L9Uu%„ƒ¨©.J2ÄR©,¢J$BXé…ÞÄ>„– <ûpm«ÄD¶H¢Í„"&4ÊV¸0HVz)¨ç6÷<KcôîÍG÷Ñ1dœÁ¸‚Ð*YfõD&r†ayŒ|$" 1´,šÅÃ%˜ðP­(FÉS‡uˆS ²Üî:ÅóéèÚN£§ûèY¤11³|€ÿ7÷qáW[©ÅLR‹¸Æƒ††<EÜgTÀTa”ƒ8TËè=—ƒî +¨íæánÿ‰ø~wø@ –`rØv8¯ÿìñºŒ !PNkq(ºÐäÔôûØ.�SÀàZ 'ÜÑ:xüÚ�ÁËÀ[�[¼ÜàIb¨› p‡mÁó/·mÿvB„/Ÿâ­þåÀ“,;táÀæx,8m0 Œ”³á à‹³ü­¼‡þ%ðí^õ¶•v¸Ä’m­ñA¶ßöͳղч®}¿¾AþÞãgw(\êµÕªPÕÒ//ÁqÕp‰ÁÍbÞm=tÃ)~y’W÷üfc£âúÙòªÅëøfØÕG^~ AXî}|ð_üã¼IÙS!¬{/·1€­,Ý|Ÿ„*Œ‹‹à)ÁßÖøIíRŠ"$Ã|-|ø~­rAAê†r?UŠš†U—Œª„ FÉä‚\˜FKEG xôâ`(Ó2˜C"5ÌŠ`3Åt0¬³Ô Ô ZöÂ$ÄÔÄT†Ò–©‘pÊ1bM¤ÓÅé=Ò%S¢A£!"I ÈH)*S¦ ¢1Å<¶¤Õ°’b)ƒz1aª‘žg4¦FùYJLvÚ9Ót^jRfâ*“笤*­Ò–T匦|ʧ{Ïá±z´>Ú³Œ® :Æ #šfŒèÉ1AÈ\ðO»ÜYB¡3©™°8³¡‚˜7DŠF ˆ` †'²K6õÑ¢ÖN}í@Ö©€$q®›döä@2Ä(&"äH¸£C’©ÌZ› ÒGºŽy›T„ðüÒ‡&áˆá>àbN¨ègƒ«3Rj’‘–`xmkhI)%g©^Í,‹I�V")*bJPB&µBÎÌAÀˆ‚�1L¤Óî$ âÈœún“­è–,)$W±!™zwïko­µÞúÚû9ú2Fž#Âcôð¤M5Í©D‡{fO|'~eD1¿Š¬éé‘V<2Qe4´6O]ÁP5Dìºi~ýiP3ï*Í3|Ô»~G¿0^ŠšªQ <Дl†–±ÖŒ6×kø+Úk]à¯9å¦nö¶E0_‰^g/íãm»:üZ^CðRnxÚ (<~vQËóûZ¾ÛbÍZújËcâ¿ç¦ÄIéŠkbÙ`Ut•$à Ë /·Ä[ ¨x <|= �Š¡(˜øqÀ:Þt¼Þ>Å[ÃK{ýD`Û½ßóø�6/ ï _âô qÂÉa„{÷gùÛ³Š¯mAùxƒŽÃà ü®üÃþ¶|Ôîv}¢°{ûxöŽë;)+W l¤-KÚ�;GÖþÄNr7긳_\ÆÍ&÷)ð¼ëÃf{½­?°V ;Þ ¤—ŽRâÁméûñˆÿºìÐÀÀ&qpG–²±žã pä)¯óy“,f˵åÅ’—²ÖôÖVăµ{Û.u|ª Dµ«žQ,™.]/›‘Ý'm)cñ¾£ï ;³*f‡ˆÈ6²{îpK"ݼKc‰ÊÆ–8ejøQdGlµÈv`3[[¦Uê’¥ªR"ážÁ•út#¯5‡$"Ý=Ý9­ œÁ¯©:y~!**qÌ&p5)&çbÁÙo“3#ƒ9ŸŠGD÷#<"¦íçLg’gªÒyK1¡¨LÃC€T£ª¥È,=̾U¸GwoÑWŒU¼!BÉT¸ÁE"$$cÀ{Ý35]Èì‘"ˆ¢pM‘)v“œZ#I”H͹iÉpÁ˜°¿¤%ÎÐ<Çï3Göˆ†~”q‚·h£·æáKð,ëFZá¹£—D¸£¥4fD˜NˆtÐ!žÊJÌ©Ž˜ª"t'*g»ER Æ¢jóª52›Ð¨0£$$=GHf(’ 1x¬À ¢Y‹hr(S!"¥X5µÂ³}-HŠŠQ•"LÐñ™a>› ¤§!—�Ó=y¶ý…ˆSÝ…E’NÍPR2•¹U0Íg*zd™t­N§Çµ¯­}ôîeÌ•Uˆá¾ž[:dB™Ø2»ŒUÜ%‡@-MóßÐ9‚--˜ÑR•6Jˆô §?(ÔVOœ8±:4ÖÚ”ãjpl?vû[”»ˆ]X+ššeD EÅ]àÁÔN[�oì6 "íÆdÿXpÂÞ/qG<çÍίѮ Õ—öÿ ‚·ÿû€ŽWäu)å W «¿ñÉoµê¨Wwn¼üÕÇ ¬w÷ç MˆÂU±(PH¼'ÞŽ`sÝ0|øüo¤ÈŽxìÏ/}ÁóÄb8zÃ8î½#ÞáôÄSŒ| Ƈ­ þö o€çxÙ°�l¨ölðºT¼}zƒG@ÊËÇgË›^!öâ˜ï°ÇOoý«ë¸ª@µVÊÝ¢Ýò‚¸R¨Töåꓚ't? Œ†‡vóÉÊ_FýY/ 6¥Hâ :ýhŽ­qçñÛ �‰7—ħŽBCÅë’¸(7Ãö'AWàGôŽåø~ß*üâvä×RŸ„nåA²IÜÇéoz7þô™hÉQ"¬«Pm+\“"lY›Q–4kB±æ%|ÇÜ™nÅdúl<#מÇÖ×–k‰$=ÁL‘íHXFRY a%…ÜÈÆÑƒ°ºÄ²e1‡NûD0 ac>É\\J*p†ŸÉ© Z¤DʘŒ S­¥ˆ’ˆDOºÈVÔDM¤œé×ü½µ!#AG ÷ÑÚÃ#<æ¡1SA3ƒ„Ï"¡ Ub"‚ßÛ´P%™éáÑÓGŽá½{ãäýä­ÓÃ2 )ÎO"é*á©â$#Ò"G $s.Ä!)ª¦§vÍ‚P›î1OOxA™ÖŒD8ܧ¯y÷qÌ~d„wï}øȰE�Ž(¡“µ;³÷0Ùœº¦H É$e§ 乩<Ÿ&T ™NOíƒ0r¦RÂ8C`™š¦¡™†N!�U<9ĦÂLlQUŠé¡RU“ªT#…Aª°ˆU5sLt*¦c’ ‡D"FAïpÏAZp¸$¨Á’)¤$R=e²ˆÉDF¤kï™NÒ½¯­ŸF6ŸKœYÇ™ ¸\g€ÑítʱŽt_zYð¬êÆ‚â[øÏl:\‡©‰>LÍU4`Ñ«@k„¦ëºKDÓDúHõ&'Ót-÷¦ÿuDK)©ÜžÂÒCéñÝru\iYòçBA/«Ý¦Ä^ßñUÓë“_-¾)c“'^|Ÿ=-m?»•—,´ÛŒ –e‰ª u<ök¼Û”7¨/Úò}OüŠ‚«@¿€7Tbæ½ l– íôª~¸Æ(¸¼ð×/·‚äŠxD*b€  FÁn‹¢u`ůþ×OèwX?‚€?ŧ/�ƒ È{œþ_à×À¿z÷G™)½Ç[àyAëï1y9à)ðŌ۷ëñ9Ðxw·à·‰ù¦èëRëÉ›ðñ øã•ä?±ï—ø‘$*x½:ŽŠš(Ä{ÁDzÿÀÛ?—ö,± m¼ öᯚ#zÑazÿ[}|M`ûÿ›ãÑ uȤb· ÉþÑP#ñq  hÇBl7ÐqãV4ÊèvJÔ“Ç€7ð\äêË£WÙu—£–™¹Jœ¢­™š 3VŒ p¹ ,@AhDч¯½7?Ö‡î}tÁ=ó¸à‘¹ˆ0ÕJnHCXÀd^ Ma¢E”*ð(bžu£µ†ÙÈ9½G†fãÈãÜ iôpU„i™ÖÓ2´D­K±¢ÌÌáéÈÔ4¢’u>J'¦š1‘>éÈîÙ›·î>FÌNìL§N¸(E’⑘Ñ$ˆAtJÔ�”3#gLhôl=Öîë:zîaú¡‹pÏ윸É2a =!%B€„Ä #C¨ôÐÐâ®™8f([£N’ÓŒ™i9“'ÃÃWxøÙ½£Ÿ€“ç)c Ä@8ˆƒÁ..1éêAøœ™…0¨C™#)(D¬‰O”D¬ÓÁ,¡>ÑUd¨Ä »:\Žì ’Ã$YÎÁaI£†E°ŒÞ!)æ¡#§ø(´ Ó¤bÆ ‘¢R%gWQ(”*ºhYh¦"c&ʈ9ßÓ‘ÞeDÈÌÖû9¡ä‘ëüÞB‹&!– >W"î”A�éÇî}˜Ù[”˜�p9‡<1ãLÑCc̾FúG_…)I q�� �IDATŠm‘PDO ï>Z®†fº”ŔΠ¨!6ˆ¢ì®82N¢ Ë­øá«çǬF¦ÉQâqèþ‹Qÿ½t!$¬w(§_.wQ·Ñ¶µDƵKÍ–,P@åz“×é5N…àߵ;}ýv[åŸn¯«Õ­d­±¨¢Õ:Zô»þNO?ùÞž–Ž~ÀGäZ…7\´£T `7¡ûÐÓŸr-výrT|jöˆgËÏ/a+¬#ßcøMè~äe»À0àÁñ0ðò;¬'œÞ �ò­ |‡þˆcÁúÞá% /þ(gÃ_À‡o±}ƒ{`Ð_ ¼4¼­�(øð¢à=ÁoŸà5n€g·rÙ¤@¢Soþ«ÕQǰǻÜí©ŽM”È›Úö©x´À=ükÅR6­n2õµî7ì{í0@ôæR÷kÅf OÀ˜$Çq¦ž(°Ö†Pœ%P—}å­ãÑc{<E®$Ÿl¹±|ÒPÂÿ2ú?…\Yæ£pI£'ü”Ú“q‘4b“^“ÂYU’‘Þ[íxZ×ÓãC?ŽXq*¼¥Ac­Tª e! 4Oƒ«“NZ&5e¯é™0¸L<TêÊÈ„#×D‹ KõD‡|$ ²!•šiN”¡6J35dºCfJG!A„D(D$ïç`&àÑGzÑ[Œ‘~ÖË’Ótª¦Åf[V1!„)gågxÆ& DDøÑzœZœڊјƒt± V‡„8ÝÈ ¦;~ÌÐtb¡I}ÚHGØ„+22MQW]*k¡bb¹C’"3ÝéÝÇî1(ÝI‡`ê% ˜ â³;W&K`ŠÐ:&ÕŠóŸ,…ƒc²IÕ…ò!&9C¦¿: DBl¤!Rb S""³#*­@EŽn”A](:X$C“ê¦9}|Ed¡b69RdNUUtfu«ДšÁpH}Œs)32ž20‘䉠Pcâ¦)ÃÓ‘ÓÞÓ£ 3NŽÀœÄ5$gNKb’^Çôë=<Góé--PAJÑ¥OÅCAÿ,6ΞN9R•¨LÝBj&–Œ%O˸‡·6¼ób­ê¢=Çé(½8dÝŠ=¡mš¥ÝŒ¸ïÛ Mú9uÆã`°:jñv•Ç‹ø¸ô0Y¼\Œ¶¥úhý·Uܳr­hés;m~z÷åe<}ºŒR%«¡Í>—Hãc“=ñŸvO‘_Þöm q~ߌŽË§P¾ò~R(·økO4¹éµœ¬>—ºü—ß—úî&ºÏ b‹Ñ_5\ç›ÒrÛ¿:Äx½5”ø¬lXO@‡¼Á|S;l*ˆaxýø ^>ÊÏíóæ Þ�ÿâ¶ïPöë—x;åAã5:Þàæ[ìŸð'°ÝA .K¹h]ã€=ÁÇ}ô[´GÏšÒŠö'm¿(b` \*TpY_ïUþ啌êý?X¾×åÿÛoöø y]jérK;¤½þ¤xHì õÎiò(bGl ØÊSh¢Êa4dzÜiëË"•?¸ÔËŠmžÿÈ"Ãzæ‘Ñ´Ç0·Ôš™Q #óѲÎsú2Vz˜ž¾?®§ûŸœ§øÖ\®4Œ€HH$Íqvª©‡Å%]º`ð÷²åJ�Æ ÕL:‚5¼G¤‡z°¥4„§ÑSµ‹,Ì|³ V-:§ÙÞs$AÂ3Ü9”Yšž"眬<„‡ûð1bŒ©˜ s…šˆšj5S+)ª¤ †0yÖÑgEúüž’ÃÇê¹zG®-û`L¬BœGTZ63š&L‘±&6HÉ^JŸþ¸Èᣅö¹$�‡ÐͽʨR * Ð�´)‹cŒˆ²e8B¨‚’!6†ÂƒDw€ ¦VX†A’lS‡úY˜j)Ãe.ëÕaÏž)dœ©v)N9ê¹3½qÈ:Y†g\E™ûb@ –¤fad�AI²N8„Ð5½[ºÆtbTÑ"R!³:­HžwÊç?PЉ•"³™˜!L`DD¸GLÛ35†éWg•x°{8½»{[K 7ÐŒ,WX:§5ndœPç>¢ !h‚Ö³7ˆ“kËX™%‘É¥jŸªé¼wÚ \cucXwnPÂlbbÍÅ‘ôÁ>pœ:Å$ºP$ˆÕq”ÌÌØf¹z™Tö£ŸîZC·n9Z=%K „ce?&Ù$hßYÛss "UNç&Æ÷…Ød[½É—‡íæ»ûr _nGm>�o#Wâ(²t~õ?h{›ËŽ$Ë»ß÷‘™|ÅdWÙSÓƒ‘¸ P»€( f£†ÐˆmcþDmµ(m…Äàíà"a ¨b¬zÌdD¼÷®»™-<XHZ Ô2‹ˆ@\¿nvÎïwj7X?÷ÇUë#®þÐ/ðâe‡,‡ë8œ£mÀ¬<ÚñOrïqEÝwûnègGTŒ‚Up.¯‡öYûáe¿ì°/芛Žâ‰ë»ïðñ,Ÿ¡6¬?‡ïa·ˆŠMâ0pšò—x÷þ¦ütg~¼Ä¿ìñ‹×xú€õ+¼ÿ0q@¶À/¯^C? t$1ä­û¸ƒeÅ8Ý]Çñ<Ðpª7«£³S1”DQì;.„l‘Tˆ¾LÞз ömŠá /ìj3ë™È‚ØÁqwΣ&6ˆ�6Њ¢0@Ð@VDy«¥ß­·Gë—øTu+Ť ¤X¾EFöâjdV^ÖÎRJr‘dt ްu•Èa`LÚ\p¬Ã¯£{’Í­^¥o{/{­‹((r¡­e*sRÉ:�È\É.Øfª°d"bNjLÓJ¤ÇBÚmR)sð“LenF ‘)*²HÝ[ªµZUAÒ‘˜  „1q6é¢ ¦ÌBNYÁä!F™csyî@˜¬Èó4I2É <Sª"A‘†ûˆuðÜqX?îCm>gI¦0U2f®qÚå©Ô–‚T‹ª’QKŠÔLxŠ2ˆW§–"[õ•"@V©jA*º1™.yBQSk€*3#ծœ9[{RU©LÎJ`³MÒ0³tXòESL­M :K2S•,j¢‹ÙFÅ F‘­ÊVm+�•IJŠ’’aÎt)ZMËdˆg6Áj9ŠÒÌ´)MKƒ¤>çYUdVƒ…AREõÇ�•d2#Ýs vçŒ�‚’°d¦b"TTt²Ay]{k» „µ0Ô´Åd­À4†ÏÃÏ1gL3j^ÈsçÒ¥^j)çPf€%ªuÄ>êEÒj“ÅŠMP¾°xÈìªØ¸Ž1Êyá¢N»Ó…¶Áœ½1F–mæ ¢Â!gäãØ|´Ã)‡2J&F.±bàâ킺6Ök7Ÿ¶C®—ÚÎ0t˜Uk³Ë¨c?ÆG§Ž5!ljžuA9]ñÖ쮵ãƒ.+à@¿íõ�ìîêû¾n?]c]’øûÄo?àîŸyú‹ÀMVõa_ŸÐ×ÅÝÉkŽ´}E”úM»Ûúq}BSð[|À#/±©À _àqƒ›úÌkj‹ãó/ðn/ Ð~³áçøâ€Wù ºÅû¯ðåW�€Ï€×ÀGø¼`q4�u I,‹Ëãüépý}}Àý§Sùå[{…²¹#ŽêËCEìÍ*¿ºèK•Û&¥+XUþò;⎵†7F‹£ÞÿûºU”vyZým^vƒª¨…pb$®D�,°å(;øú;íÿIu£ƨâ¢âµ ŠÐ%«œµ,û“É“L~FÿØWÈâi)e(E2R¢k®Û^·!û-ŠÈb©Åk“ƒ„Œ¢gèUé)²¤ˆ`hžÉ.ÁKQÉáÀèâUµ…‰@U5˜‚‹¤<HMTYÍ´–²”¶”Z´BéœUQ¨–À“ÌL¤¡˜ŠÌšTN¨§ÄLDNXí9›d <—¢ET™E1#2óÇ×Öd:Ò}äºâÒqž  ]$9qÞAù±û`@ŠÍÔ4Pƒ!V ¤M[4gš)Î…,Hê"4FB‹ˆÌ& é‚!s ˆA…¢™uŽA¡ƒÏq¨©Te‘”`B P’=Œt“@Š[¤nT…d‘!.¢Š¢�3ªÊŽÅD±ÅT ª‹é^l3ÅJÂÁŒi™zòLUJÕªVE5ФÁl2VkÑjjJ€*ÈY÷˜´ùÅs-NZ䜥d¸GÞǸztÇHF =$œé” Z¦ŠÞņ¯-/éƒ2BÔå`ÚREÜÅ@™H˜›ŸCÍg±Pòª™(Ž,ŽrÙ–Š”ˆÐ‡Î÷À!eî¬.™‚H_»"ÅÈ+G·îë¨Ú‹Kd\Õáñ$¾áµ³ kn¡k¤yl¾¿2Ó®°ðˆ‡ì;ÐÌJĸ,kXŽ5ëÙ6Ú,P­œÜ.£¨B ]Ù”#Ô¹”h+í­(ÐÁDÄÛÕqwqZQy¼m¿€®ˆ‚¸¼áòïp®xñï¡ ÐŽ5ïsà“¦jÚe#rëã>¼þr[=-WÏvį! Ѐ^1îñ¡—¯Ñ^÷—>Çï—ÀrÁ ä#¶/Ñ>‚lÑÖ†?|l8°¢kÁ;¶xÕþŸGÃÿç³á3`W;ZG_ñê3àÏ›î lñNð7À¦"ô qðŠ-ËçC¼hëSÿ}î`Û°óãFá4~qH�ÑÜ,ßrù…•LqA@ùÌãÈû,Ý¥jÔËz­j¶[ÁÖziŽ$ê@)Лãst3 ž€pxA3°À&ÐxÂùv‘‡¶ìYn]¤PÖn­]1¿+€Ä?„çº"™ç凨ã¬ò$‹H…иM7 Yl1]¢Ö`5/|þw Uaà ®’¯‚—ž¢”NNòê­É±ªªÛá¡ÂâUP¨:i˜{x¸$ K ×¾hS¢@ ›²$  Q QHþ÷ð‘R3Ò"ª©ƒbÎ dÆy‰g½g0…™ùÜmʩϙkVR2˜c’0Ü#œ`€Óµ–‘1²¯XWgDHºÂE)†‰€âó1“P|^~`.ÉSšˆ)ÒE$•YŤPHa¡*+²@ &4ˆ)ŠÍ*4ØÉî1Ü1œ‰a†€(Càj¥©…ˆøl¤PèLÉ”4JÎå»!sD×´ÈEªVÑRX@q2UuBŒÈ°”­iQ,+* ˆÕ­é4íòGûj"’’à*yU S5¥L§�ªÖf%@}VPÈ„î‘9›êtˆ‹Ŧl6“ÓÌ1ÃÇÑ{¬W¿\}í~õô‘d†fgv—ÞÑœªTDZú<‡ÀÉ”\àûÄ.e¡ Kš&ÔÁ,J„™²(…¤¦P[#칡Õ@=Kac¯ñ¢¢ÂI¤ ó,ض› Z‰ŒÑ4a棱G&A¯ŠŠâÕÐ…kયƒêâ¡1¢|Wý·úRŽ6îé#Å´fb„ôë”^ Û<Ö¦‚ [ßP«ÈÈØ¯r î½íÆô^x¢¼uÇeÅß<¸"ÿ²Ã½!�,†€c£ð ¸ÇºÇ÷ÀƱ\PÆ<äuÍæ‹]PwÀͲʶ÷º@oþ³ná¹ Î,ë¨_žÀPˇ8•z÷öæˆ?ï}ü&Ñ ðŒÆ;â‹KÇúˆ÷�^ã󆨭?ݽá¿åuOúÞçÀ;� ¸ _nËõ YÁ+”`Ü‘5_´XÚhHÔ3î68š£˜¡ ¬  Þ0Úßy——?[ $ÕSÆX}ÅõnØñ*°<5c«º“sA¿-–›\÷[0«Ô»|<BQ€%Pt"¼ :P;â©8 .ÀhñV·zWG)u/H+`¬ÅΪ­Œ‘<ÉÀ Tþ)}«½\‡×ü×ê«Gn”7*u‹Va’Ô¦Ä"tKÎþ¬È€+Ø™—Œk jªCFa 1ÖYl {}Î|f®Pk -7¢[цPg3 a{4A?`É4{¦#+‚F‘È6½”LŠD2#S†$«¯¥²èd%�˜ÎÁÉœOmdd"r„ûPQ’’IË‹”ŒœlíHz°{zAK"ƒÑé#ÆÈxÍ;§i2³0 Q˜aró@ •Âé·(�‘39#?í)=4 …RÕø|މ Z 5¥ŠDdЃÃ#èé³Íf*`„Ãd)¨EX…)™Id†8™‰T*€($ Jz¸$W§šj…Yi µ˜± <Ã&y5C3T ¨U¤ÌzºA{þSΫCr0®É‘pbºŠ@;Ì  šP T fÚ(EÂæ‚gò!„‹&̤˜ሠx’îÑ׸\ãºæµûêì#‘Ô"\¢Çb%Lœ™ Òž„µTж%cÛµêPeIX¨‘¬ª³io™‘Ž‘¶:/¡#á1L#•hiÕU•{Cˆ,ÔH‘L•²�fnT¨Df¸\œH_Tªb-†ÄÄ0úBê^½täZúȵ¯ú´ÁÃ’í$ ‚(ª' (S¸I‡à‰8)¿ÝÙ'Q" ¥‹àoM!¸sñ)x;d{…MRc@Î8¯øþOø¯ üzÁvs÷›<þ°Çfƒ‡ŠæØ TG1` Û#6x¯¸lÕ¡×ß¶¸/Ð'ÈjtCíRJk[èRSî®y<¨à�:Ò±ûõ[ù€òÕ¿*ƒQ?Çý»W§wííÌ“¼WÜ�ÛŽ*(WüÏ ¾^ð¿ >¼›/!{¼køøŠóå§:¾Æ»¿ÂÇ ú�úÖ¯ñîÇÍ* ø…aW±½Ànàãv̼ÆGô‡ÞOûñ)Ž­# 쌼"ôn9Ë€¼„.-¹)E÷1–e÷ôï§6Ç+°!¼¼ÝÊ]¿l½­+™½—%]ÊH=ö—€cûtÈ ¢Àz†`WGt&À8Êæ^rÁ ÉSâ[ê1ä.å8}<_>š Ãtø0¬‘ïÝ]®?KÈòTm˜í‚Z†5oZ¨ÍQ<5ë bM<¦R…e‚ê”HÈÈE²�•QY”â¤fJÀ%ÖÁ(Z‹-Æœ˜K Rº‘9¯NºD–�]t‰B+!  32##îá ‹`x©4K•‚© 6U±TËg`‚É̱x¸¸Ïþ³R™‘b™š‘™ÁLxrxöâ©‘… z$ƒe$ž”9§šÌ°ŽqŽA*‹Z#JzJ0ÉD²¨X(VÉš©‘é‰fN¨(­Tµ‰ûààÜžT§ŒÈôHT.:‡n*ÅTÔPÈŒáÙ%W""`Bå3 c(QJŠªè¦–e©­™¢D’>e¯LF@­ (¥bòLHA2˜™ *‡dgž“+05â¤U–ÈrUuŠ m¶ð($èàPÐt6ÏL´mFï9ºÌ ID¬W¬W÷ˆœ$mH$¨!yNvg¸`dfú<¼µ\ EhÉR´9^!Ô†hŠê´qª6kGO;;C.Àª+太Q—” /Äkp“ØQ9Äüùm'‚$Dk±5êô(™ìàO¹9¯ÊU9¶7›º•Ò¼Êl¯`ÁØãÿؘW;¢âJp¦@øÖÖ»¼ä¨û€k”ГåqÉ7¤ÜRœH| Ú±ÎqŸÉ€hsc_+þt—ôã/ϰ§7úí½úßÜ=åæmi(fØ” ¸C�CЉ%‘ê¨\Oµ Œš9ºîk]¦ÝBÚH{b}¼‹z@éÏ@`Ǹÿ€Ã‡/~ÝñÂç_¯ˆÍ#6Ð×x¬€â]vÀöû# ï ž¿ë§Ù7ü+Þ_€=–'¬žÙÝøl^ˆñy ª¢ÜBÛ Û7¡ûŽŒ„—~ZWôvWÏGø›x8ä?VûâÞ¾<ɯ߶î.µU²m{•+âim'±S+€aï(ì: †¶œ#¹ >Hy ž1%@wÇ\àa/ Xƒ&Üñ§ ¶· V¤Ü ¯ ÖTiùšqë—O§!èÀ“`¬¸±[yhu+­ìÜ0|“íÖÕ–uáP®`×Ñ0v0!Ë2T]:àç°¢l »RŠ™ÊˆLµ´”Eª‘P1Ò’ y”àâ° ªh¤hXqˆ†ØÄ¾õFV%,Tº’â óG)'SrZ}ø92Ó¥¨xËši)€RTT'¨§d˜=L—¤ÅÌø+ÃÉ)Y–ÙzöLŸÜþÈðÁá%B˜&@ü›“„äôŠŠé3Û) hRŸ ¢¢`8™Hdzh0­ºƒLŽ‰è³”çN…ÊóT֙鞢f*ÜÕ|ÅÍ ºP6‹kJ¥Ìêpq„ÑÕ$© ¨˜•Ö I†«­.mÓZƒÚ¬^c.¯Å‰HˆNr-Õ0HÁôDr˜JĪéÀê:ƒÖ4Óª(Ðâ6õΜé`a&s‚¯*ƒBƒ@ $…ÀÛ2ÂÇXWïkd"Iï]"%ÅÆÜù»0#9Y%õ:]¬–`ætz³$KRFjJ&W£T"•SóWtWmÓtµŽÒ¯®+¥<ˆ} -7™Å¢gƒÊH£”&MU’1t" a3aªjU‘KÏoÖ2ÜöÍÚ¦tE‹ä5Ý™¾ðO‹zëÇÈDMdGè›’ÁK¹XF‰½^ì²”CË7KB°w=ŒDŠKýO`¼5BýtU3}3ìyiùÝ'RêFï_îN‡üä ÇÆ¿ê›Š2÷qIHÀv�±ípA(ÔŸEYLoý;°Ü‰ÛæÆ_Æ~Ø›n8çáq__è½ê©ïßn; á_Ü]¿¬ímù€QµÞå8.[üå nætç|‰ññø¼àÞ|ÎÃ;T”{”Ó—x‹ÍOx6|…/|†Ïÿ|c�ð5ðp¼«øÛq7.G!ü¹Dz¦ŒÊÓ»¾¸ÞãZÍï7coXô®evþºEâ(å~\ž¢Žf´å±oµ¥`+x‘°€UŽRÿMÓMÈø¨ôГ–ÿ“vœ¸áaXñf»9ðZ‰ûÀ OoãÔ ^Q–ŽWItEß Ú1q¿²7‡Flx5^k8¼Þy=v¼Yë§;ýY‘­.îº –�¨]wvᨌ'ò‚@ 3óÔ¸X öÇsèÕ·/Eª™BSeEÝx-ƒ*AºYQˆšJVKJK©¤¥P(4 CÎæšºd"C<+IÕ^TF„t�F“"“ûÏÑÔáyùq¨¯êŒ @"E9]¿2÷ÁeÿI:È„B åYý<½Ÿ³òçy;úì÷~Í Ñ„%…A™>Ð0Š’Ïé­ù²=»ÝT 6 #ud¬`ˆhÅF`ÂðÌq>KˆP¡Ì�5Ó=<|Võ� l¥íGBܘì)GŠ<çx¢KtuG&iip'¬4¨IÕbX%R�Љ±Êé6�IcŠ›‘ù; P #dnÚæ%)58ÁTTµœÉ«¥j+4™Ï~Ntô`È@*©‚‘ 8 rUÍk¬—ѹ&<"= î­´bB4‹.â™p‘Tc)VBʼnɀOͤ9#†:ÅÃadM¶_ĸ7Š¥êRË"ª@Šdº"•XMDvY4¸ÍP¸Mßt‚+c(¸¦$oÂtMxºákнpëËZrˆõä%òiØïty³Xk¹(—…×`\Ñ?�#å(À¤Ï[‡;˃¬ô—~¶ø¡œ_»½ÚªoJÂ:¤<^°U·WÑ'5È@·ƒÈßQd}øã^ËÁ¬5í±Ýbqœ›Þµr‹­T“;Èqè¥C8cúy×óX¯p `�üýqÿòã·÷£Ü$EÎ íз¸Åá•4o½ °(r�v,¸¿¢à«þ„!Ÿy@ÛCö( YÁŠüÝ1Eñ?õCòð1Úûè_–9³ý φ?—þoŸ|ÀË›WÉ›]¯xà¿)þ×·znî"êÊö„vÚô÷K>ýòÃöóïw/¾ãþÐëÇÆ›FÁêýÎåø(§¾«ËvÄæ$í¨Šš�ïJ?–GdG–;Õ?Àž·ÖZ=YS0ˆLd`#ñCK‡ì±u¤ ’0:nNøý» z… ¨'ÔowÜ”uƒ÷-7.Æv›7Ÿ(÷¡7±T4ÃÔ!-|‘J;h­Šâ]Ñ™·®]·ž¶dµ-& ïIòû_ból–M]AÆŽìàм*jZˆ)`ÅŠš‚–0&C&S8IËŠ‚™ ³Ps•N-P"¤”ta)æ"À$á{ôÈ+Ç ¸Ù"R¨B&"S#%§[ ŠD%Q£ÎæCÎ>[â9¾ÄÄ<8»mâÎîÙû‰Ó{0É€(TS0'G )Μ,S5Å –“­À‰™¯Å2 "ÊÈHŽiNS¹UÙ(ja%:Øói$ê¦MRÉÈ‘cøá„ÍÇ/jH¡­šF(#1DT#Ø-ºŒÌi’2ÂÅAˆYQ3©¨¢™óšÁpú¼)Â$U‚Èbôœ0&T§?ÇF:K*ñì_Uh3«TÒ̤¬¨U³b?Ê6 3!J`γÖ))L0'ÈÑU!pŽ‹¯½»^Sz¤GšX+µÔj!"d®b¡æ©"lŠD…3R\¨‘9†3£:)·ö!KjÞ,DL…³é2-ÜL2Ò«ö ÜP_Z5ižÀY“XE=p=óÚc톦,Rƒt¿>^®–Jš®†+D‡•'èïwþ&ì íQòF×^yí$Ì?�� �IDAT¡ãaÅ¿®#+ѰAôMê§Ö‹^7ì{÷æÞüK±ÿ¸2Ë&ºÅ3·ýC{ªu¼”R·Ún!wÊcM4"Æo%q^ï>$P>•å¥eêÃ@¹¢—Xv}[†É‘w}=ÊÓÝÐc `y“~­¦÷;©¼=“õÊ ÊùŽu„üpne‡­Üî¥6Ë6·ª¸ky4À+ì³Sû50ˆS| { ]` ˆ¡ø—ð_ã¶àã›»öXóÚ®›²Âï0Ž?õÙðÿVzx•‡ƒÚ÷{FÝ|?žn> }žì÷ß¼è4¼«›ò¹7øÏÊ_lêâÛWc{{-›Þý<¼W౿•·¼»ÖãNQ Ô7ŠCéUú}®âÙjêœzÿVÇq<FG ÖŽ²Þ1n‡5h«Š`µø‘Z5ЀËô”Å«¿ °b”·$ÜîF~²½þœuÛF­À5eWÖ|©Ri=J]gú?¡x©'”O); ;‘'•†ë¢µ\¤m[]F”žÛ¿‹MC“Hdsò_WÄ_¦«u×ëÎL¬»@26RAiÀ"YÓ!*.2$ ¶JFƒâR]‘‰kHzäPt²ëL\³jR‚Cb¥¯V*K‹ºP›<+Á2‹¦a¨è¸ºxŽ”§j1‰È¡Ã#…€D"’ð”1²w®CbH:à‰¤Á@¥y.ÊB(MH’As*&�Ѥbî¾'é/2ÅRlNÍ!IM!" q£,�U @4f\5EJ*Q2ÄG&ƒ’gŽ‹FÎűiJU‘EÌ EÒDkNëšÀ)Cy!‡Ñ¡‘ú̺è…Qˆ¢A‰Èè#UA„¥Š U³L™§Î l  B\$rFµ Ð”"Rê´X—g ´(TÕ¬˜ª¦�Ìd"B’”�¤$-)î2"™C5-××1|õ¼†y¤H‘²³Z(åti¤i #e"uŒÐÅœŒîWøP.(…Q¢Ë£y©½ÔÒ&Ž)èTéÃ{ïk¿FD°‰Xâuã.=ñ`yyHRcã«øŒ­/Ýë&ÅÕ{ö‡±~ãþ0â¯Ùc3…D@Cû^×OËþ–Þb”!š#ä)1‡l³úõr¯õ„ ˆ¿~†‹#÷Îsï-ô®ˆUxªØÛþAÏ—NËuaÿ¯£ýÍÅ^>H±Lú$Qϸ>㺻ץ€è×C¿¹êaÙTp¬8‰¿¡žðrĉÂORO!‡ŽCgsöµ  bƒº¢|òFÝVl†dóÞÅñøm¯·Û‚Æ*€®Ý0´ÛŠÚáç¯ß �Ü%ŽðÏÀŠ˜xgœùù+$ðجǂûqé¸`ÙöÏÇx—GœñÿÏÙðç�ëK|þÑÝ‹rÛ¼µµõÄ÷Ÿ§vûÍË»Wí¸Th;½w¼ÛÔ/¶ã3;mñ·XÚ¶,7/j»åææ\ÊC_GØ ÙQöØ^ÑöÇ›+¤A�”ƒúA¼eï]á†Ìޕȇÿ,¥!¶ÀH˜¼‘<„lλJ%Ù‹MUQ6�Åæ‚XˆM`Q,œCîo®íаÏEµ”&Òbð])ú8Êã0u[2ìoS‚u«u«T”Zš…$¶ÄÖk=oËË‚3k±ìk]¬kP:2…ïS+¥2¬ %*VbŒ@GQ4S«B…Qr(~0»Ò¶HF.‘BN _¡�)#泓ª`ÉÕ2„‘)ʼš?´Ø¼Š¥Á6´"LMGfš„Mb†æI.É2 ÛiÝEÈ*"D$sî¼cí W¸Í¾³Î–‚ˆ¨˜Îž3A! RâY¢–Á c’™‘H&9’L%4a#sÀ"K’Y„Æ€%LEŠˆ©šKª‘ˆLð"q®¹’!i`šÈ¬¼Q‹J›EgœAQ)Pg€±fˆ.J B­‹ä` ‚„V èšÆÊVb&¥T(l*ˆ2gÆ@žÕ?’ .“V¨ 5¡j**ªªb:±ÚU™ãƤ2$f¹ J´L’‘ÔîXá©Ù+cxœW&iV¤™ÒžMs™Œy_J±g «$I²Ã;¤I˜ä•Ñ…{#r M}dç³ÍÒë(Ë@WJFчŸÏ×§µ¯‚à)ÊêiCK¼W}0†p³“}ñ›°¨¥°DÌe°u”Uÿªl¶×f˜\÷p±éUÅr£ã«jõÔÔ[@_ E*Ý@ù9ð±è®‚lgÉo©e©kž·5n.åéÖrÓêÆ°{ôÛ\¿-O_yà½~r²‚Û-nwÏOþ°ÁWØæ„@A-c\·§æo_8êãÕc«Þçr{ɽe ‡¶—mÍÖV¿ÃÝÉŽ¹àÅáPo¶kUz_WÆér®úí N¹Z+cÀOmE[a¼“Ç<Žãø¸ùËk¬gC6 ‚Š|‰0 È8)¨zïpÂ�¾ÿÉφ_ýLz ¾¨xUŽ7íÃ+ÖÚ?Ãúuÿ/¿~øü£ãû‚_T¤¾}µà‹ýÝ«vüHïöÐ-RAl±Ù³nðÔòw.à fh7H`ãhwz9Æ‹;XiYZ_Š›_·%BsEš¼Óß××(¯-¬AûAÊái³¹¾ÖëGåôbœv »Ä¦À% èKƒ½Ä~‹my6*†Â Uçò@Û)LVĦSóOð*2Ò>bHØ (H4EU4Ûd| «¾­«µ—rk²GkØ®j¤þ)ATÊE%R~€m/S_ˆµ²€6 ‘LxDôÔsx‹ÜêbVL3 *È!bÌM2"éŒT‰"E Àù.‚ ¹ƒÞ ÆU×GøŽZ™EX!¦HÒ<uzá ©Jл{z®Üh)C#d8( 1"2b8}0:1LQ„ªÿ ØM•j´Ù[¢fijoNF)³hŒùý\ÿZr&$)$(Ê’¹A.+uhTͪQ“ªÚ¦ÂN¡BI¢3åU¹‚ƒhH,fUØ€èüWó …ZÃe„¦»jH:¤!i½Zv“¼D·`es”S÷4v-5KcÅ87 d†x0I“,SLQLÅl†Ô)n›'ƒ©©U'bödLH#2E3Óžp0*<3ÃÓ=0œé~U^ÉŠT«jMÓ*¢Jg¿fêüë%cºœÄ=8Bú&Ýp<iT².ƒ4aªˆD·e×Eêà—TïÄeí—§5:ÃKJ‘ЈÄE€%€›!ò° n çcÕ[,b*)ˆ”‘{E¹©´ºR£†•’½¶HÿX#4<W˸t½ö>H½ÙmêMeÕU òÒ¹³Ü¤„l;Â,µ<Xßĵ{·s+rÜö†ÿ½øë¸|yü_¿Â›;üu`OÌUÞ 8þjAàmq¸Ü]ò¸yB¶+Ê÷G�XîÆ¶Že÷P¬HqñÙJYµc@²;Ç>vy§›š›µuÂðÀë·ëïû èÍï(G\ÐOoJìË ÜN+Þþ3À[à7@û�[àx¬‡=Î@-ÊÛ˸û—rœÒ«Ÿ’§„?'V?zRá{|6ð‘ã'úþa\O_C?;ÿ¦ž^Ôš€@ßa[Õp+ÇùÉrÙjn3íLy üÎ ¢!ïw®GÁï_ÑîóËSÿïGm7X·ý±ÑmS»ŽRoþú} 4ÞÖ M~hýíæúýöõrlŠ&…™@ nP‰y[œ+é(ŠcË{•sVQCÕkãw"§âoGÜÉ´±{e¶£iQ”cݘ-=L½´¶H-òBu—fYZª!wé>¨OäŠì’H£9Ž!ð”¼Àµí™;—](ŠŠ²agŽ‘Ã%L%¡©’n”FaF‡÷1&0 ¡±J–Œ­DWU f¦t$.YLT“2BcMŒ@zƒt€jŒñ¼`§& ªVµé rV6fȆ9UHIÓI ÊsÄ”)%LI O$˜6ÝB,ˆÂ4@¨ôBˆ-ZMJ‘ &2û1ÉS’ŽTI#D3a`!X$U­È³ì"˜¨A’Žs KENQ²6EV”ñìÞÁ"Zl¦‡r¨§Äà€'•V )sh4q}jÈœ’MME%ge"$Ÿ"2‰$*6¡ç„L…dî£KAwç zI IG0œ 3#$9DE¤™Õ¢KAÑù—Ì ‡„wÏàÌ 'ÄC9:œººdȃâѸš¿ª)Êm`¤#ÄW¨Ö,·päPï9i)ÌH^¯£_ƒƒ5K�ˆwO6õc«,(·”]5·¥×Ã(nkA˜ºÕ„…T£NÖŸNW\ÃV ‹iÝ¢/냯£œOµ:–O˜7…mÑ*R@Æh8IÛ€¥ôª8ñÁ仇W/Û“÷-ÎM,ˆ¼¸àé¼ûÇÜÃ÷pCH�ߢ.P`%ÞÇÑž 6Èõ;È×ÈÏŽù‹û¾?_QcFóbT+ß´< Öë(ÅOæxyÅîzŒzßÙ=èæ£ðø‹ ~öË+ldƒ/Ǽ úá _ÍÑ/À#ðGàð9ðh_A¿‚ÿ<È[G<¡�O àâèOø¿lÏWŒŸöløìGzR€Ï+^^ñ³ï±Ô·>î¸ùúøÑklr¾ËÝqÝO†a°:N•{íW_°Žs–+ž |ù&ëaŒÚ/÷~ÞoeÁM“Çî/qùç_¢hõ2.M ¸Õ—µØ²oÅþAøOþÝÛ~Áú íz Ü z°éoäá—åxcØê3­;®ŠRà‰ñ KE×çÔóè 8Px*ƶ£05~«3’üCá'[öl K‘’ g@°Y&­_DJn µä¶¡¨h*Ø4¨Ñ¹*%CwêY"%¡C5êv©”"VñزjX§Í̇D¶”mîèŽp%§zÞ|0ßÑÂdÄ"½s5$´‰š©––º×\0¤ô„ÂWÊS!R˜3™BMÑââ—¾*"¥‚«–EQ$Žœ5Þ˜ …|¶H«ˆ’Š˜Ü†Š "玙p>ó®CÈ „…D¦XÑ¢$ÁB'ˆsJc(I¸¢(Ͳ©óŠ(SD ' J¸$dÍÿ‹¶·ù,KÏüž÷ãœ{o?2£+³»§¨Q«$ŒÛµ(£V ½•2 ¯o ¯ü‡y7ðj‚ÑKà „Ø Hjd‹­VwUE&“dĽç¼^\vax©æ‚«�I0÷|¼ÏóûÁÀÉX·/_±:VÚøšnb&WÊÂÖ48J§`0ëz;Bà X…ª‘3ÜÒáQõ¥¬!ÁT$™b ò&­wGÁH"¼ds_á«ëO Bˆ‚œ’‚Ö@”À/õêîÁ&ä¾JeW³wáÎè @ÔiÅ—LŽ\{Û °ônáæä”LÉÈ`DaNˆ²¸\„¸b“6r¯,Da9$–ná5A‚AS(à Á–Afa‹çpp¬Òn#?Kdi‹:ŠUŒ&Sw~”éQ*ÂÅwFo:'ÓF˜|5o–ž#yÉ%ûsõ ¬S«ù!æßLǃûœ U @3¡`„J ú6/K’.[<úÞøÍ³ÇåÒŽ™{³CËwŸ6»¥–oä|üoÊݳ#�tÔ¥b*È<-(ŠFxÞ�ü å Âá˱5|'þ}NŸÏr³Hb;Ú| ûÜŸm·µw~7ÇvÆÜ‹DÇùŠñ-(#|@¯˜ 3ÐÆ}{[.¾­*3.?aÿ _?`ü~VP ÀÀ€=  ¸ã×x|Ø£¾ìøæá_vmø]bõ÷+Oyn ÷XpØ­Í»‡w»,¥Ñ-Ç&w…±5pCÎw8ÂöˈÖÏ‚ç@T<èîébwu®}Î_Ÿâ‹*T*^¡YùðÁìïþarX Âû)§ \S¸0†IþKÔ¼ Âö¾ót*Òûvs¬Œ"/Þ¤H<&ší•Ã�ˆ ,3ZG $îpÝG¤ œÁÏÈO{þíŽ7?F¹°±».” ˆ2N)âXÅ:¢6„2¢é Yå>…@Â>·ˆ–MòG’ÚOÜfS¶¤ÈÐì‚Væ+)ÌRC@lN ¥zR¤ÃK õŽhÉkò[ˆÜ™xáRƒŒÑ m+Ý `J�©! ©'Ú‚Db :¹ü6¤$†d(»#2¹’LŽŽ%b¶äô*2¨«“&s˜“¬J.–BÄ«e‚"Ék_-Á‘á �Yºƒ:<öD¬E&d½r2ÙÀ™u…TÖè:Œ€$Yåf”¹*®}ͦe–H«Œ̶"[‘«.±n⓱NB˜à)AÚŠdŠk8׬hI(‡”ZxS¨ÖuºLÕÈ3½# ë*ÅIÉ’‹Pfâ�Y¬ç©õ¦(x=>auE2uQ% HA2"SÁÂ"X÷þ¢žÜ\NÁ=$–‰S†pr„Š‹¯S4O÷RDÉëƒVYs³°¤¦Ä„‘“8KÉJD,cêÚ5BIHŽènh¦Î^ŪVå”ÈLkÌÒ{´¥[³ r‚{'oég†ä:‚Å / •IäG(?À·Ù³åCÈYBœkÄ9ÒûSDq¸ÆÙì™à@ÙZÒr =ß²ßÎçOÔÉxŠV’% –‹xKúþ5—šgåîø[‘¯ÿÚ_cö0EÛ5+³ß>òö¸>RÚ—uú°VQfl ”œ0N˜:zGUœ*l@'LÔÓÝæˆŸ\í?ÒŸ,ó›e–bâIϧœþé‡ ´ñL`á®<@±=HGLÐ)P‚)N„“ã”øTã7íg÷匲`üˆ·_áÝŸâî0yÓk´+Tà˜N�àßâ ¼¹Á©âÕõ;”ÝW½¼šo‡÷ÇÏp÷/}§ô{öjÇîø½’týéÀ·;`‡¯*¬9@²üÐKÃð��íóÃ|‚ =°Èþc-W\»Öº´Ÿ7LÈЦµõÚE¾CèaÛß½ê»ËåòUK}Å›Ñ+EQLIö]i%]ýñWi&ÛÃw ŽP"ñ®÷Ý)ŠÙíçz¼Ô»Ê/ïúòŒ³ +lFýQ�‡Ò;’^]*ô¡f¤g7Š…JýTäLöG«›Ò Ù7e•…Á°ˆÅBPf(€–krºT^R{ò¹3=y¥ð&¥@'ˆ8¡!zzd¯ x"aÉš”`â‚K¡€Ï®lÌTDŠS©$`"'­9{Ïî` œ\~ˆ8jäe÷ÂnˆÐ—»qNags6‹ìæQ¸ò�ªŠÊ$ADDHH"VÀRVÀ·sø ¸™(b-½eF’Ezb-HS¬INtfQ!& q¢S$’(Y¸0(#3ßõ@‰—~5œ‚�àLF„„fHô .&JœŒH˜dä »bELg:¥–6¤+5޳bℼΫƒ4i`½t¬\„’$Ý"3=Ù]@k´>Þ *@É”À`\QxéXßÓÕœEÙ(ÎɨšÉ:pQ*´Ñ XI’‰9S—¥óìbL vH"™gNã xFxæ²nÖ‰VYsUp’S¨5<Kr)©ˆQ9bv ¹R1‚‘¤ë’L™-)8DòTkRU." ¦ôèÞsii­G›Í{h®¨ÐÒÑS´dNhŽ'á-%€XÀsúdb#AÇd”'Z¢i¦æ¹p ³ûÄÆ$Õ¬ö5qîˆvÌgò¾™—Ž OYN¨?„n’w ³ç·í>6Ý:n{îúsýÍSþŸc|3ÉW´ù¦«^?á¯ÎËóöû¿>—¯á†ÃÒ°b‹Sb°T”Š` zÕëGµWÍ¢îݸ rTÛbF™7{ʃ8¸æƒ(pL€B«ŽãÅñùñ àã«{œ!Œñ#Æ÷Øý9p\z»ÄüÛ ÁeB>ÁoPî‘÷¨_cx½ûRw?µ:}hh7ÿâó†oÿSN‰¿@ÿ­€Þ`yÀó·ø¸À^P:*¿¯öç%GѼ ¼•8Òó][à[Ø„¾ÁƽÃ:vvx%·o¸„«‹†‹NÏVKCÏzT@l+ÆØMóîúT7¿õºjTnceQ‰Ï¹]Ÿ8"¯'ÿÎ:vI,„Ê€€x·µD¥Þ¶„-Pdðù€%`eFtd{×c÷tQ·zìb»«^s,ò içî8}˜=¿CKàGè5Œ3¯–…h Â"€Âã7¨ ¹2£€‰kŒQHú˜°®Ý¢·H¦yÀ눒/’_"ÏpvsC,)&ÌLˆ_˜™%#&ƒqF? =ä°Þ~ÈÐyTÒD Y$­ÖΗâowyž™Ÿy„Á“ÙáEÚ`‡ktj3æµ8 PÒjXd#*´ Aƒ!%=x¡"áŒ|ñÒÚšÎp_HŽ ^blÁ”¢É)¤‘ò‚muZÿ©zU¯·U3©œ ¸¦+1ŒÕÀD±2ÍÕjùB¦]õÈÂ"ÆïùnÙ-¢¹,©†U@À  0È,’[ch}UÆ«R†" °ðŽnÞ‰Aʤk¦´vØ’�¥( ]‹!†�­d€3#<Éñ¢[òˆÞ€tWÈD" ’H]‰¼$!ƒqs¶¤ XûB™žÔô!`sølé4XTW摆lIÞé$¸B#Ã9‘Y€ÈdI‡’S Q@Ô£Œ¢â$”T%ÁáÞ›µ¥ÍÔŸ‚Ÿ’ÁeË©ÖÍ™I™Z2=–™.‰P\®8mè,sðÀÌ.Ï:trîCkéÿØ6·=$ŸaÔ|è‡þ p‚?ÝõW8êþ·qåèV®âu;8E\Îð?=µë-ÓZ›gg£†XÞ _w©íòÚŠ.òým¹9z¹;Mhë óðô¸A}A¡ãFAÖw©Ÿw™Š0Ë#Ä:WsmoGüSiß¡³šá Pƒ4°¢Wø€"Hƒ1ÖXzuL ^u Þí¾ÞׇËö­¼Bý·¨R°'øôoÀ@(¶ J8¡)N÷0 oÐʾhù£Z_¡Ž— }Aìÿ0Ö{| ×Àk˜†p>qxÂíghtƒQ ÓH,@I`VôÛD0Dð™b`üxÓ°¥ãFP¬ŒÜéÍ1Ýú®‡! ŠbËûeCusªÃwàï\¾vƒÆx–R¡5§h5p…_~~Y̘N è°/Cª{-¥ª{‘ƒØ÷c¶†F€ŽÝù³Ý}©ÓÐzFT3k}ʼžçˆvþëÏ9x‡Ôè›Å»õ!€R8ˆBÉ)Œ¢ÓlT… WIîšpóÞ£%æDãÖ׬¢•Y“84l °‡ekœg¥Î¼¤ªD6 †15(#غJ NAÏ…¦ÀÀE0iŽ ˜¦yúdA”DNœXf™žì@9k™Œu¯”“…ÓgŠ`§h.…%È=™DœE8«CÙ™D DxYˆVŒ¾€Fáî½GZ$Ö„h’;YCOB¦g¨RKOxR6ÍîŒ N¬ýàðŒ$æ\Ü B&V(eŠ‹6fâ¤d°uD j ˆ `"Å „%¸%[b >'GRM¬Sx0™ƒ†”¡ŽSÝ\ã¦%xÆlÝŒò2çHÎL$ˆ$I�G°FiƒNÂ�¿CFQ$R„WK}†d†YgI6S}¡©3 ¡0W)&Cs#Z¹âÈŒˆ°BœFÝ—žfì 'B&§‹¯Ka7 š<%x%}8!<2¼€ ^ɹ@(|ÍéB3 ®žÕ¢¬+š{‡Í§à䣰“Èxd äì#9fW6!p)9–œJ™urZ†ÉFRNM“"c¦ · jy|J‰ÎË‘´ÀmOv° 2Q¦ƒ–ÿúyó§³¾NÙd£”V~ô©À­åðCN]ùHRDU.’â>œ¾Ô¸2Ú–©Öqðí™k~Åò§ ' Š0…Þ#¸ÇT¡�oÁ‰z šÀãNi’rŠr²ägƉگ6Ã.§ÂÜ?áØ ‹¡o‘#\à‚`Œ^pfD¢Ž¸š€Žª‡Š·E€­ /8¬N3˜Z"äå|†{,ov{…6D›kmúöÕ}û柘¢UÐ þùï_.—Ž_Ÿár‡±bl¨-Õý‘c¿õƒ6 Ò116„Ë„J¿«’{N¥º3-}ìTßqÜ 4·ˆ–@ Ñýœ6ò+±Þ:=<{LKðBÀÈRM˾äg”e Ã-£‡Ÿš}èýú —ï@;dÑév«GÅ0í›”Oµ~§�>£ÇêÒ¶‚¨óèùÛ³<QùŒä½ÑeF9ÍÙ®¾D’™8 ìl>´%2ÈÒÐPQ&$!’Ò3z¸×B,9rUSÔUš$‰¢Ywb&;%ÏYZpo;ÊG§šÌ™L‰ 7§¥ÉsåFpe Ùz ©ƒƒ)eUÔy<§’TX,(¸zÈ`éé*ÁˆN<88-ÒûˆÖ èÎp—¬Êœ•@LB¼v©×‘rb5m",£»u7‹fáJ0s†#’zd †0¶L¶àH†'X< †Èž/¬nr“²$å üÉ3ˆˆŒÈ_|@IÐÈ”pÏ4Ç*Õà ÜéD‹r‡öœº™Ô85¢" Àf-©DZëf·›a•9£» Eu&h6D$"DÊ”BA"æt ¬ø!b‰�¡ÄtEF‚"9IKÔk—�� �IDATr¯dY 7ïÌ)ÎëÄœ”8EHE‹ÔHÎÌ$,Â,ssçtÎ$‹hžÓÍ2Ò;Qµn=iöº0k ©�EG†'GZ‚8{p 0‚KFIx)ØÒ«Yôµ·ß£[óîFD idÏœ.$—Áˆ.§º)¼­tÁ9"•#ŇÚd¸¹ƒCƒ À‰­t”2 •#É8ù¾,H9LË;ÅŽ³ÄxË8Êön»Åëúã6×2n=r`—)p~¦Ç'y¾Øüò‚Žb 윫)W‹Ò®Ë?Nt·ÿªÔdá R¯„ž R†Ëýi8´‚ËÄ8‚`Ÿ8”oQ�ºÿçˆ�éR:Õþi8yë~à§_¿.‡º Ú!èì5|ƒnBLðİ‚d´Ä§ (€r,7ïË€î8ž€OÀÕ=â Úa‰GBžñÃÿzó²ß=`Âñ¢ r±Úçq{®»?X/úñ³a°¡v¼¹Ç;¬Ž»o€¯î÷ø/Þù“ŦDïíòÏ ÁeG}F!±O94ßë§7ä£ÑmÈÎÇjÛfŠâÏÈ3ÈÑý˜gà¹Ä}/ Ó¯. =j?fÃéyªÈàéõÔYC€¶ 4‚ÔŽäÈs±³žë1.;•]åšÚ¨‡®ÿ-†ò7…!å]ÔGþÇš; ujG’€)¡È;ËñØH;Ì¢õJJsF÷…<ȉÙA–¢Ñ25ER2”¼{ ŬR*¥Bœø ê '¢ÔöÔ½P&Œ‡3ëÔ^®Q7 '§*ód<‹ã‚˘ âT2™WFP†gt´ôOM—íþ$ Õ • rˆéݳ›d£ôXŸb!YÄGäz#rEJ€•)ŽfÊ’@‘óK±,Ò-¼EÜÈ×’s&ñ  Iˆ…!!Aì(¡a¢«ç1Vj£e7I&M¨K¬ØA$ùêr`¢#Á�“@âHQ "Z‡ÛXÛÖ,b¦äÂêˆd¦•wDRY¤”‚A™E´ÔiG]ÅzaéaIÆlk: ÆÈˆ“h…†¤Ä:¢'(±`]82(DΔ@3”y55GsGPÆB"Î<0Q ƒ‰ ìéáf‹›ÏÝÎÞ‡pE¬£ =Ñ"–îd^Ó§lÐ"à–p3)D 8QKrÏ™™F”JËdJO "š3[‚­ `fIkè©!1º^yJ°þœíï4Mp(e¯åOD&)×.DR$2Óó2»±%"ãT]gÎò#ªµD ó_2؇Ây;æVûóÆçSŒ`Æ q=¢TÕ c‰˜3ˆ;?Dû¿Ñïì—ï oŸ°÷ÚŠW{ϨxܱI@ùWàs«ñ¬ãÕŒm¼èsŠ °CåÞìp_·Œ£|q‡kø‚n°óqÛ¤™ãØšãló¿ ‚8jBôP ä9BÞáèÀð@˜|ªhŒp,‰±ðY¿“{l°gÚ N÷øx�~ ˆ RðÁ±�ûKCùà ãßÞ•äý~þõó_ãòØ‹¾{À/€ë‚ÚQð ø#ÁßßðøîË«Ÿ|ÃdÌõ×¶ƒãmE”w°òZèçÅ\âm~:Ƨ»9ö²)óem^•”É÷d‡<£ÿGœ·wü yØ3€¼_쉵 fä¾ÿ_>õµñU>‚A °" Hðù.í>}Øùr÷éõ_Nz9åf�ó� €öˆƒ7Xà´î(w‚¿êwÕA¶×ó!Í!€(HÁegå'N—ŽrJx´ÁL”K¸ÇÆÁÌÊX½݉Ŧd ¨,”çÔ–¤# s¸;õ–FÔˆX\z›*¥/Y;Ó,rÎb¥ ‹Ï…˜Í„?)u"*Ê›¤!’á°nBA½¸wç¹§YGënÚºÕ™$•§€pB"2—hž‚Æ¥ F€©±X†"bvZ!gSV¥H–Y˜•h†c"(Ì"ºçì IH ñºÝ%â“ÉÝ):Q I“‰(=-Ô#[¸G§�0 Ä„ÆÁ 0"ÄÊóY‡ Zu3,ŒL2)U’5ˆÌÄàÌД4I¬e„Ë0”ZTD’ˆ„µ†ª³v ƒ—ä™Ä¸€H¡!ðtH¤9¨%…p±+)‘* ¯µnO£tÊ4 ¼Ô¤ñr)‰ t„8ÂÈÔ ¶ G…ÃÂ=ÂÝÝÍ|1k½-­5;Y›ÃZfM&¬&Ô~r?‡-äúÄ=F#!šnå¼ eJ ±F Œ)±jWÉ2Iì ¨ä@‰%èSv�Go¤PeVø&béýìéhîí1OF ùŠË+®?B¹$ M&&$Ð#)О< q++ï·…PÑ$:gîæ¬ìI®ðW—ë’ê’{à—*ÿ=•9 ÎbOíü›Gkÿ{ô÷qãØ€3¦è»ÃXnIš:6½]zŸæƒ ²ßµŠà¿¼¬\¤LµópôÕ[è€cW°“UÈÐ5ì5Ba �èã1e }üÞú„£T(CqªÂà€’Ñàßâù |†ŠlƒOpÇ?xåøhø¦ã«� ˜�ùâ ×ð‚é >>àóoAÀÈÄì˜çÄû ø�¾¼Æ°¶•Ðq˜ðŒÛW¥ý!{ш¿…Ý€î_:Óï…?�ê;èçß,� zàÞ{1Ù¿EvI;ãë’éÌ èo!7‡~û¼o~Ö@½úAÙqæO #úýáâç{\r>È#xŸÑç;NûñÍaX–èŒFØêX ¿Þ1Oç›_ZøÈ||í1•V¤ ¸#|?Ÿšqÿ’õ÷s«¹×åPü@ïkŸÈ´ÇT²L‘µ/爋†Í\4 ?J8÷+«[¡‰X�AçœÉ׌¥R¸PsQQàE™„`Q…áB¢ä®­Ç"•¼uu_œ’Ë�ÍО2'Œ@‚ èˆÆ.L+&šÒÒg#£HŽè­g3Àq9÷H y¦)EÏâ΂d·D#, õZEÒie‡2§(ŽÞÅK'b@=9À"- ‹ç&àM‘†q4òpÃÒÉR2‰)™Š(ƒ’¾:8` 9§LÍ’æ�JDÊUâäDDg8˜’¦a+²¶'À´z+Á@f–J¢1¨1¡–akò‰A`IBè ð)À)¥Ô©Ö"²7$.Üž„…ÙK¨ %“#„^Ê«±Ç(=Ș„E•* ³³¬b9Z³¿e]ùt«¼“�rÀ$NÄ’©ÆéJFÑ„È=ÚÒ—¹ÏÝgó³ÍgëK›}‰<w™ ²ð ,ohÏy~ö��²)Á!LJLÁÜ@sP'ik°TN”B™ÁZpížA) ¼M¸eáîÿl¹rg&ךtI¤AÂlÈ™(s~¢ó‰¬bþcÕW)?·ä ×Äc¼ä"k/Dxaé$.ásb‘øí€ÃTߣeéÑÇs†5³6oU¨úŸi3ÏBíPFÐöÃp­§„ËoŽòïëû÷åðÎqLœàÿ�ÚgÇ,cwÉcy…jˆD8ÿ:[ÙW9$A}Æÿ6ãçý/ì¹\ß×é¦Ê=â¦dÙ»Ú™àùÚ®þ½MoõÏ–ßägV/¡²ïãÔUb_!ý'Xžà×xž¯Ñ^ƒ HƒÞc÷\_¡8:ãg�ÛDYÛe×È×PE1üörsh“B”Š_8>^ã=ðÍküL!¶.i8‹#ŽŸßüA{ÑÀøñ=6X· ÿŸWîP&Ðô"Öyj@ÿæâð³Ø³”Æ·¬DV±Ñòè7ûáþ@_·ŒOV†ÖŸìx D"Ëc9£¼‚ü̆|ƒù¯€ El@‚ãå„å#ä±  >”Ð^ öÄ×ëºTs†|kø 7E›ä¸#l©·»Þ. ÜÛŸX¿ìý„Ãg WX®¨üÕˆäÉ+–š:˜”Ê¿ç�»²ÿQâ'ÄÛ¤1P#Š?U'df/ÌL¥ÜQç$áR𫼧YfHïÜ›CD‚+IíÔzΞ£$Á^Ìœä)¹ á­g;S`6ŠHxl9ÜI+f.5BÏ ‹hè^èTEx+ÉjIœIâ„ÎÈ4Àz¦%N)cj&ŽøÁîs7骦Yh²³{wµ^,‰I°"F™™HI"�Ää¬iÑUØ“ÈÀ}íeyf$»Wf×=8Ck&‡8(@‚¤„äpŠ@Zzb…®Jx(µ’jV5å…ÀaKz‡V¹‘p„Ò�ZÆ"Eùug)Iðu„B‘BL:ˆì!”LÁ§èS:Æ< •‰@¬´d£v—Â!Œ5Øåëú@žé‚Á;¥u¸ÚœÄ=–¹Ÿ{Ž8G{Î6»µîܘ—A癑™,gj,&§¤×Œîá–ìä…Œ¤3?Ÿ ãÌ瞨0dHSÀbH“X]L%:C…8+«û¦,Ήy2Ô¹wsÀªD’¥öƒ79Œž1çB$ÁDœ “ˆXÌ¡Ü4º{˜»‡¸GúA�æ;ÌØ_,z-·<7Tœ‡46¾j6ÀgÇìU÷y>Ðùß‚ô¿ÐüåÉöO èáŠ7„72dƒ¿A< ?Þ‘ƒ¯÷d`€ Ò`  ôPΨ„Íó»«çÝÿq,ÿÙp_£oÛø¦éCG?„aD…Æ.Ÿwù“ªƒá«‰Å5΃~KtL½«� HÙçé`´7;à+p+ž*& h˜þã d‡>bz  œÀçÀ¨ðúnÀn*¥áö܃Ýcb¨ž€�_).+@ Î7+Kûîg÷È^4 ¾¹ÁÏ€Ç{T çßnö(Y¡„ê°3Þœñxüò;Üçái¸½Â©£¼¿:;Ù‰z—ûƒ¸¾£ ï½ãS`+KÀ1ÈÃwŠi€ P_ Ú»W»|(}¾}~:¦Ý›³BΈÇÃ?ÿôFžµn@%("ÿø{ä{êÿU˜ùíPåñ¨—€•Ènç£.°G=¸Â:rAo(’¿‚Lœ¨eŠ-@ë©É#Ç!B(¶±ãóĦ±xáR)éL¡âÐ U§ôàÄëFœØƒN 6hPº¸§ykɽº_h”–µezFõ‚ðX2̲œT/Š<"<¸#ˆ!ê(MgBl(„„•«ò C!J@Ï.æXˆ‰WŠt†«$ƒ"A³ B£˜q~ /®Y(™ÝS‡}Œ®}á.…$Sq“´Õ‚‘ÌÊ !RD­êˆHR8"»0ŠP‰,™šÉæIîðERUHàJÎ.¤É=�S€º(()R9Å,àPbö`BŠP)TDkЍè+áƒê 9$€¬T”«R)D«¥M#ƒ’2ˆ")IHY@Œäˆ$"¦&d: eJQQ©JŒ\¥FŽU§í}­—3±é=<Ò23‚z’yF$QoZ#!e¢X²µ<»£?“Ÿ©{D¸P®¿a¢H:U &ëheø§Ôß:©µuêÝÍÃysVœ‰X43èšd BAä–äÉB *Ê%°"þ£ÐçPS…¨*‡ö@¤�8g°B—4\9«oL=:ù¬âG8YôlÅ¥ž0–fç¦Øa,å}‰C d~8’#¶—‰Ççaã°)šN›ÍÙ ,‚§Äíà¸ý¾§r÷ T°làÿ §×ƒñῆ3ú$D ð «B|ÆpÞ½yÞ}BýŸvøó©]ñãtîÛéHÿ  +4Ýw*‘5–ê7B2T-T îœ2&øÈÎòÚ‡ŸS÷з´ÊÍ  éÐ{( ÷(÷ ¯‘€P ,ßc°ŎmwÝëñ¾ýC€«'ðÊ, Ü_Õ×3~ºâ Ü{ôüÛûÿŸ§û¿h/Z÷xs¸/xzƒ«|úöw28�÷¼¹ýí¤AÎ_ù¿{uÂÕwøäø(Çï  ^!£yëùp\×Ù"�‰ƒ.ø¿¯�Q\ ƒ ðDc\L8?á‰Á— ­¸v“î®O?´ú[ÌÎ(€/ð‚¹#|ÿ<ú'¸Y+ mŒÁ�År~•qÑß^žË¸Ü?ÊæŽû0ô8dyǺC-À-–£âÎ6¬Ó»b þÜP’ìžaGK”Dí :PüqjöB hƒzlÜ*r`&Ö`!ÀÓdÁ ©âçÌg§!²Wn©];±mó´EÛ@ ·ä„XøB Z,–åäoJÍQ©Ò³ô'mß’|vÝM±¸ HIDEª «HeŠDèèÏhKš›)&²,ªHE"Ó"a!>#žh8¦±…¦sÀÔ—h‘ÈþìÂM ‘4ªM¹wÆ‚tL¤�S®½dÊH÷LØ"—@ÏT&g0:€H6ˆA„899dHh'‰âLr #@©&»’;x !™ÁDLµRTNëi™ÂT…‡"\ˆH“ZH Xc%‡Óª®PC˜ƒ3iF…S€"%±:ÃÅ%R‰RH˜ ˆ°XI…–ÞÂ{xðÚ`HPf$� žªÑ5ÌÍ#Ä—Þ¨CšFžÙ‡“­ŒB …hb›…x`KÖ*\þ˜t"œ) #4 ô6“Ÿ³G…t¦˜Gʪ•©†¯¾£0‚©P!bDo““ï ùïT/‰7@ÎIgçÌ¢¯É&V¥R‚“z¢Yð9’,‰šç)íQæv¦K É”ì¹ñð!_%ÅáŸäo9À¦Z�‹Ÿ¸<î[<–ñˆÀÒ~Bé;`G±1=aÂTA1HBgÅæÌO¨Œr‚]à̰‚bÈ�QÏ@� rÔ§ýð\®—úÓ7õýeüzúáŒç¡þ²,xÝpqB! 8œùö©4‡Ò޶¥0D\k7ó m9÷wŽûµ¹t¸˜Ð ì  vðï$ê¾~Ð×`« O¿™ñ¯>ì­”¡Wy¨ |ómQìqsˆŠñgïôbW¨ åöæcýpÇeýP€¿Æë‚á_ãøõ¢ß¡ï0¼¾}¯GØÝ3��ÞŒã�|å#ú{>Þ�¯ \¿Çîþçà~ÿr³—{ 8Ô/ö¸>ÐT¸ÃØ‚‘Q&TE�0¨güÐqz@Ý`ºÀ€½–ÂZ!µwÊÕq/rÈ‚úŒÓËýá¼ “‹ySÃt€¥óF>}x}ÚM½Öï›N`…Ê;šwŽ‚¼ÍÍ–§!¥F6Ihªè@,°¼ëÊ}m‡Ì}ÒÁãLØ$Rx¦œ›ŸÎÂà$v“lðÞ…ÁcÕ�GZ F­–�Ê&î" uáÆÅJ­h[æ dàR’»‘²'–NóI¥ SIFEˆ?r<'ùcÒ5�;—Þ5 SÖ …%(~ð„“Á=,!CcHŠ¥„B,JO‰ú˜Å!‹—1s±Òº< ̧$ËC˜›qãì™c‚¨+w²ÕSšÄœêÁ GZ‡õ,ÁÁOj`…@&ÎÙ‰=Ó2-sFœÉÆfëßß“_ª „ �€µQ‘XB ‰ža¾âŽÖê qee³©[ï¨f©¹ÂÑf°$)H2á©”Aî+)€�%Ö;¨Dö€g&q8­G·@ “P p÷ÖúÙº{ËìAÄ…A”�`iˆFÖyYOkÖ1<»“XQ¼È·‘álf‘ŠPf§ŠÚ¢$Q@j^ý?´½M$Yv¦÷ž{ÍÜ="#Ó+³ŠÅŠâ ‹‡ÈEµs´^‰A#-4 jAéïQËM­D€°•¨EnD–(v9ÝUí‘învïùгæÔˆXDÀŽÙ9ïû<D”üqH ÓÎ%´w_D‚YÈ Zi­´tU¸2JÎbQÒ“ 1_ *3ƒª•ê@§Ÿ¿&Þ‡|Âtä 䜄Ǥ'È{a8ÿ"¬q6‰¹ÄŒa§äï¼ob¾°ßQ[ÚiÆée³¬DŸ•"¨™ƒ³;YIçâFØj²­QG*Œ|(…Pè‰%}GW¥]‘ÕqUØ8û®`bÏÐÄEÁÂè 'ð÷pB�g! cc CmÀ r°!òž#¢Èk¥¯ê%äw¯ïžïþËõT€1‚óþ �?®ž.Ij=®¸9àjG^zla‡â´n½šW|ßôqMwŒÝŒi~¬GЗðØ×xlA wSžû¯ðÓêúÆîš_ÃÐÞ¢3¦¸ƒ_ãû§íjµ©ŽÙÜP¿Å|N–~‰x¢øh*»©½¶øã mÿ}¿t/½ž¯€·0h‡˜^VŽc¼ÃŒÝŒéõÞaºÇ[ÜmG\ þR¯œ^|lþãöx€‡—ŽKÁ³X­@#¢"~ng}ᧆýê%*OTn‚VÐô O²:áÔÑžãâ/p!û Ð÷¢=/÷¸°UžíóŸ ]¦W¿Æ"}G±%Ûæ²&î| I:S—‹bG:™@°àŸfÚTÀT!kœ ‚Ðèï½Dæ°¢Og¡l&ÐE™$†30OlF‘‡)ŒsC9J¨dÕ(RµRjŠ’ÁP ÝÛd]Â8G…”Ìr ¤²¼¤ºfm«Jîc‚(W‘*–F=˜Œv¶Ù¡Yr,AÏ ÖˆÒC³)5冼wx ¯@— vŽ™Kp$-…œÙ‚нè ú!;›X’ÁÆn‘Þ? =Ó¼§õnyJ~H9:u§5çÚ©@:e§L Cvä ž ðX'Jp8ÇY%É|›ŽH"µ‚Ðæ{„³+Yºq0Î „ó~¤°0§Kt¢WJPòYTJ�(ÏçÂÙÃy.{gžÝ¿IgïZDô´Îé 0Î`‹ŸŸYÎ ÀzŸ;õÙÒ ¢ª�ø‘ÑÓ;z ƒ\ƒ-‰")2‚”Ï6ž&„ÀL%Œ2X”’J=Ðch†fÔ´çž?In•k‰ÒYf·tSî%ˈ*X•\k‘’é‰ìdï•©Ê"2${¨uÒ†_3¥@,œ‚ ‰Åí8:„µd×<‘wZÀ>—æ*Õ¯¢C»î»ïÛ¤B—ê/*F•7Ä›d‚XÊžîŽ.ˆ'Ó¿aMÖJ¨— i|PfÉ@ÜÑ ä÷¿ô£Ð±òòU`óqÚÛ¼¼õh<G)�°øžÑcG1}<Ï ŠáÕ ÕÀ‡·ò´¿½<ÞEÿÜãÝÌ*øów|ó“U¡Ïnôi_†Ûd¬è64îVW*ÛÄU!v®©{?Mrc‹-lÎÍ#ɃzÇ$À(_`­Ã€åïËÛÀ½ß(ïëæöå—pÇÃÓ~ý%Ž¥<¼êü°ÿäkÐîvþª,§*«º6\õbw»Ži *HÅvýv=lK-?F†u‡»T¼ª0¼ÁåsÛ=ëÓË;ÜÏO€‹k”Wô˜ÇsF5”ù­`[P*np½ÇÝíWؾÆö®†kÑâE%k †o±¹ÃöK €œÑ±4ô†ö-ø·�®ñ¿ÌÀ +ß3 \.j_?ßpÀ 䌳͓pë3:víÛ)€ºƒÁè&¹Ö`jª}0_É|¥s%nÜ©yo Öi5%# B{ÀÜð@Œ@�ã eaI,²1‘ÿV[ÔŽŒMŒãÁ)FpµÔ(™LY5HÁƒ …�`G©H@„³°V&P“„"á–G³ä†q•,ÝJÌÅ—ßhÝRÙ$U8'!dñb©0RIæ8Æ‚2ÙAÙŒæCÒ åŠyxn%Ž >&9…G¬™Ïd¢žéÝChá\„Bx㊠’Äiy^¢uJÊ| F4‚‡7DºEÆ‘Ø\ÎvÒ™Hœ &'к®3:è˜ ðQ4(lâ1*¹h‚‰(C’22…#•˜RRtnqIâÜDf’s ”ÀIiì¼~Vüp28ÎdŽŒ³kôƒ§îÜíPOX†YϾˆud„¸ u"Š?ô–½›µ¥·eÖÊ™â@;¯¬"-²S Bà KæäL±�!͓έ" 5Îé€�ÎÞi‰LŸ L²€‚9Z1¾ Ì5(,¡Z¦‹Y`@ôlœ#$“gZP:ç 8¥9sE8 -õ1åfÔ„ä'%6’ç—8xDd‰p²ìQp)~À2À�?ærAeMä€}þ·šàõ®Öéb}ckÙHA%8ðððÞLBñbi•AÙª€(aL-+Ñ ;?N=A´;\xݸ>O¿ógŸô c¬¶z.¯�7ÐüVx‹¹ðüKÅ7ßáö;û!~™0|‡m¿«ó?­zMÿiäý _a ¹¸¯ôI¶>b0‘ :Õº€ýfç×ßíðåÄ ;¢Ù~>ncêúòUg4Á~üZPZ¡@´kÔ;<{µ=·ûVW«&Ëä3´û—·‡‚%wk›6?°WgLÜt´fX¡ º`:�íÿ eˆ¾EÙ"ê1&àhx(@¹.ã‹þq}x{…Û-p�à;àd`þøÝÆõ6j«ö®�¯vx(ï¾^¿DÝÜ)^eµNxTÛ­Ý¡\cU Šdã‰ñ�@ Ô/vÿùjÂQð¾a–ÛaÄÚw+Ÿ”AŒ¬Ès|Jv…§A �™ZÔPr@ÇþaÀ£¢^9jLƒýå²*:<9Žžö;GéK'Ý;¡\@"èøa)˜/v› à^áôv–­gyŸ7Ï–ýÅü·ùí'³ò�� �IDATÿFß/quqºæädkäÄ!�X Ð!s¤“Žd¢D¢"dˆº(¥°GXï½w3ÄÜ3¹®ÔÕ\dæ<ÊòNÙÔ Òƒ’™Ôc`ïC3å"ê„GIAÓl'>ª¬®Ü/8Æ-¶P‰ßGü{Rõø¤÷µ{©¬gªƒHzEhr !$¹4(!hì@dDÓ‰‚’ÀÞj™NœÊÉU@‘+æeuf@\9™’ΞG Pp ¹2„œáªJ,…XÓ’éÉÔ“Y„™ H„I$>tˆƒÏœ &'â³ìÌýŒœÎB ö øÀÆ‹ˆïçâ2%è|è aæh]çÆÝ]£«,‚  Ad’zÖšw 9OŒDº$!ÝÃÎÕ<WD!$E;qÏh–BNp%¸¤‚"ds‚ƒ4>p­¼³7÷\=Õ<œ¥™F\ Ÿ)Š*$ÔJÚ ”¦4JXH<²7¢ä¬-é‰`cê¬ÿ:–߉¼­øRã²ô5ríRÉd2¬fkðÿoÀsQ¾F  |0óØ­lû¤#DöIPò’§„xÇÒýt Ÿyô’eà$¡zbmÌıQ Ç@ï ÇÎû ' {1ùøq‹ñ„Rþ„óOòøŒæËËäÝ“O51¶sDÙa¶Mü‘øêâÜWo€÷ýö=°^ö-ë6¾«úÜt8ŸÇ¡çÃó5 ZKÁъЮútÞAJ}Šü}7Åïá˜Æ�èѭᑾ\—M/Ãùkc`szÀpCtä;~(õÙ¦‰‹¡ÔaWdÚøÎÀ;Ÿ~ |TP®;°`|ªeÓû€=W€¯ðïØ­ŸŠ¼¨¹ª?R/z�_ËkŒ«ëqs·­@f€öæ+ b6|ë¸ü8ênÔ’wõôe=¾ÀO´ü£èÀñ+€Ÿ=ØÅ@›¨µO‡åôjG6µ#ÞÿÞuÜÞæÝvõ“²ÚÞè¸gº%æG¬ËTÏØcAš¿uÙ2¦â=Ê­;ú3$Á;†DéH‚¯nIðoú‹=ñK¶ô˵è\Ò¤;ϧ°ß÷"&@ÿËp‰•¢DìXôÊ· 7ÐýAoCPh›¾¬l Ü#—NÛ¶‡—÷­N›Ë‹Î;(“3©rˆ:ÔBÃ)2æÙ(¯H= ¥¤"ötóè‹·'7( "Áäû,·iˆùÔ]<;(ižK§Õ™(DLYªç@¼" 0H ¸È²‚IFô<–èNHþuäÛžXòRœj#™:ò„�7")а,Ô‰\8)-aΠ’ Q_œ)4gXPTÔÑ.DÀc’ƒ…±pR$(%‚Êt6!d°df¦FAr¤ñ™ü#¡ªŠgµ²«ˆ ‰8‰#¸Ÿ³QH¢O¸‹FÀ,šÙÒ¨‹ˆ2‹“XrÐ9¢{.îÍÏGãsÏ ´¤»-èf½k 7êl'á Ê̳¢9ÑY\{!G²ºq!þá0žp I Fd,Ï ¤‡‘ DÉDgj$ÆÒD˜‹³à ·£úl9 ³j÷î^ÉÙeeˆ%3À+äj±BVC˜¼bª”Òi±´9¨¢°²Ÿûè"Ÿ åK¹rÔ\ 4‡ ‚dã?(éel6}ŽÑ{.J‹T¸pSëýØ'zÄ0Ã/¡q CÉ]ø}7/xš§§owEÔø5e0ȸüÊeG:%ÞFÛÎY½`ÏÙà^áÃ~v¢c¬õ0”¹ŒOñqïoWýö•B€êpìì²t¬j¬Ë G ŸÕOŒ— ò�½’ò‘.#½¤BËû~ÿKßæ>ÔZi@gŸ<Q;˜`ŒX#øŒããÙiÿØØWýäfµ=–Róy‹Uo_O ¬¾€|YÁñ4Ÿ9uS~}ÓÐÞ_ã£WM^©–Éšx@â'‰Á€ºtm¹½Wü=íþWlƒárÞ} `Âõͧߵ‹«É[`\‚» œGØÀé ‡X#pßñÜ1T¨M³Ýô7Í TÛ¦öŸbº/o¿ºÞ|u—¯¿Èï®äóвFm e÷¿ßÒCi¸9•ýñéö[@uÀêa;^ouS˺iE­`‡j3â}ƒYGúÖê^“œ0FxJèîÀŒ   Xø]nßPš±¥<`½ŽåH§{œºfxEßàc} Þ&•‚K™ë�jsÅÌÞŠY-V×ì%†—[«x_~~ š]T‹ áüÁ .ÊD…|¨"áÔ<0ƒ„°!"ÂÓ€`k>ŸüÔ}¶ÀY¡Ùq~·}rm¨;Y¦h{Äç)‚�ó |D#@˜S<G’̺1N¯^“h¬Ù=J£æ²A¼5¹m´3þE؉ŒiA¾ç¬–ë´bc„eO2Ö]ï3Ÿ!F501šÄ«-D^:ņ¬jŽ…j†’€ÅƒB„- Î$$xP Áç>œS�‚d  œÄ 8™ )À O —„„‹(ŸO?¨þ8™á’M(XèKç~:zZg&®TŠK5R$Qff:葳g÷ð$"$Á);²ÃÃ;y' 3²µ!ÌI SÎÊÉH¸e‚ NÄD‘¹$?Q ’BK "ÝѼKW"ƒ°ˆSÉ55²²$”“ !=q¢¨ð` +"(ˆ“B1“fåÊŒEq.k?'¾d‰]:ÍB+3zVù½h*FJª†Œ¤•‡JE‚ˆ“¨HÁ,ÖFácá‘È<Ê,r*+ó÷Þ=™[/±¿xÐ ² „à˜¢ÁçéxÀû†Ãý´oxƒ‘8=Ø[Ö}¬L*ˆ¸5…ØnÐ)G¤Á:…œø6R1VæÍ«Í8vaÛ á�̆g„\a¡é0ÿòDñX¸ÜY­»?»ʤ}â«?Íç7ªcdz‰ïI~¿ùn:üæ­ül[‡‚«~ª{uüà–�­B+¼€öçXf´¿ÀƒaÙáòùkP-Ñúûe¿¾F­ÿˆzµ‹Õt <îG| 0`¿�qweUÕòƇ½áömw O¸è°ÌçrÁð ׆OëDšÈWð ûúC1ù«»ýWÀÏQ~¤ÙpÞ,}üå?‡ëÖïzÃtn¯‚· ®È†?ë¨4Ð íqÿô.¾,Õú ì›ýöÍÝ/?EÆU./xQ<ÕVu§9inéÙÖÿ©Î¿i×øÝ÷_áù¬ö»EP5EEIw¬pÍpAxt'¥PÔ†zLÈ©ìT'�ðŒ˜K$#W»!Êë¨_Q}]ð]9}Îø1©ûý>¯0ûŽÆÉ8 Ö‚Û®[•5LêÀµy,P*Ïênމýojkc –6ŒÊd}…÷ñ놛ÁOÛ¾ÞPW±än$žÜšHåQ˜%ˆ™{rjŠ0+ˆˆ%,<ü\ªÂÁã˜ËcÉ~•9wrË�5ªM¨÷2é€þ½±ÍRT¨ ƒ|Åü˜í}Q"^ÜøÂÈU<YÑ`rÀb9'Q©Ém tBÐq%+°8Z‘{ÎïSV ²` ÌæÜ#ö”å`ü‡äŸCLBR$¼;"„ºH!¸ö•Ì\…ÁH"æP?¿ñw "b ŒK†¥žmË‘ÒÁ*?ˆÏ•“ ifãTФ3áàÌì†èIÇÒs>öeîéÎ,’\À|h‰ðDÄ™¡×‘ͼ‘ €4ò…Ì(®I& ¢ÅÑ‘‘É A$°$j ¢‘¡WxS )ÇL¹<d„PK†°€ÎÌò…\ážRˆR! ””ÂÁ–AjˆÀ�\¹Ÿ<Ýò°d‰òôS"ïT©V*RŠƒÖd•žœ’váiH’d,šÂ9ªSM©) "¢H:zš‡™g6*i—ÄãYŠmê-=V†û̇À=|ªGäùß`¯0+*AcG6ᄘqš±0W;ÔBŠ0_E<]ø�9Àn ÉòüÉ‚#ã(0øœôÿ;weø¥_¡–¬nåY٭ˤ@ÈÁøfÌ%¨2=ò®*>^£øõ o÷|ùˆÕ=4îf¤ñ¾Ãõmþ+ÚŸì¨MªXÃèˆåÎHÅ&P6b¹ÄøgNø3½]Á;Ã4�ÆßâÅÖW¥7§Üÿ®Þþj¼Áë¯>ê€_þÕ׫#Vý×xðY¢sú Ì8ìQ � t€ À+<�×xwwN ݾVØýx³À_àîª<•þìÕþýî¿þ0µØ°­XWH€þˆöˆ§‡[�O»˜ê8àêa÷G°á:¸`Öx\ÇBº¬&Ñ ðR۟ק?Â~,ÿ°Þ½þb5'Znèp‘F1\Ô(èJ FByİšh¹Á¦cßš,ý•Mùá(8A šô~nÓ†nÔÛO+®j[¯6ô+é;¢I_½mv“ëbtǽæí3ÆØw,\âQÎoº‘½QônŸ°þï56c¢Ð’ë½Ô=ÌàÄÕ‚Cß¿š7W¨£1E'  cgœÚ]²i:%‰‹• €$©Ÿ[£hˆ'øûÁS£PòÁé^«UŽä}ºBVȘ‚„Ò•Be=ìYS8B/ÒW1n çròì+, Œ`^D#¥ZÏxÞ¦’ê¸H¦.! 9€f —C£êžƒ×ôb6fù¼óÈ*•™”Ù¢Ìé=Óà ò|õŒ�áüI&#êN ™:\zõD <"g" NI!A”Nªç16§t0¥rw"pœ+”™é nÝÝ2Ä”Ñ{¶e‰ÞLÈ4EqrÌ�¼gvdD ›ÃAf’E&<о(ˆáT”„NÔ#‘®@F¶ �‘©! öÌ%óL·HnHä“XrvN Z§°L‰ÂT8#hqŸá'ÊAr#q!ØHÅ� Rͳ@²§8V=³Óý)Æ£g˜ .g!(r8{™‰XÀ’ Y“bMÀ%I Ëôìþ|pIW„ ”ufÏLŽ`‹aövjóÒ‹9S00z©têN„ô‘©„Àž±½UŽ·¥[~?µ=–OÑËÛÎÛK‹9í{»í+,§œ¾›Wsû¨ƒötI#Po´ï•ÀØÖ( 7¥ìA·½ W@â»ÌI Bo+¶NKxmÍ{ib9ß0Øm…ºˆÏ–è‰ a ÔR½DŒ¿RþkƆ\Ô5âÓÓrñÙiüÓ§þÛ¡Ý^$V†s €Þ£lF†RÏ.VpAcüNñã­a�È>™#ÀÛb[‰Ú½u‡~vB|…X€Ÿ]ïÖwöñuZ» E Þ­0Õ+Ô‚ø¸ü`@¿†_ƒ6 5\1¯pqÿ ðxcxþ ü€Ë¯§u6Üâ _½ØA§×¶ûïý†×€*à X@´{,_〟b:Cž°Â4àæâî„kˆ…Ù#¯¿ FêôÈ7æ#¾[µÿK;6Ó»ŠÏ-€¾/u»¹ò=U_o+AqΚϰÀø÷1À¬ÈÜyÙûà ;* ÄÀ‚Wy¿ÿ3 nʸíkÚ š'^0Ûv·¢•¬AA¼@Ç)pk4 µž9÷'ÓåK²í ƒøR†ÎïB�ÓŽÚä„’·eF‰_hþ1ŧFQÌ—Þ@ɺ!I‚äq0'ø¨‰$2ötWX:ÂÐÀ÷„5¥f J.K£’%ÆÏ™Þ&߯0þOˆ“£$Ôh,ªÿ7âÀ’\�J=r< ¿ét›ø#†~´öÚ2a~!4]*~Kã@„*”/àlÜ¡ÚK-‰QP%ظëL`°%9f9tiþañÎègh)I÷€!Zà˜ få”ÌhÁæÂ®îLˆ FΚ§Š ûg C¥8e"Ö<‰–¥³þæ.aÔ9g7êA<p#7$’R™ðn 8ÁÏšHë d©ÎZ‰–áîÑØ–LInURÍ]2(ðÌtO— „"´ – À©òÀ£†@½K–Ftê„S’t.™ŒNþ„ª¯ BE%A™šÙ‚¢“;²‡[•fÛœ kr2êè:Rs¢sóÁ+s€òÜ<çu328 qe¢eQ.’F´Â¡ NG±‡,6œÜFK£d•!màlANoŒ¬Ôb$[jú'D–}›xÄãMl÷Yo¶Œ­E­Þ<ÐG´Š¹â} æý²àp,þxY~_åãdÓdÀ¥@d+TŸIë„# 8ß>³m"v؇lÝþ¸lÄ­ÏÖ—Áö¨Úüvl[{*«¡ýÍÂЯ?³»KCÕ?A^©»¸¹Pjú㺽ÂÝiü ‡ÿ1Á¾|Z$õn¨ß`° Ȩ€F ·†W'\Ô@Œ˜|ÀÝnóªØ\ÇCÍ'+õ~7|?%P¿@»ÂÅåtù7+k¡8–öMö[›~ú džÀÿñ X*j*ZÅIð÷ Œ€ã¹áÅP¯ñcΆ E½yW ž>$Sß}—oÐN(k "F,ïîeÂ\áÀꋽ\kôE|Ãí¶dà„ý1ðïC¹÷ŽõþÍ€çÇW~_Œ×ùÝZæDÁ’å½ï0L ô³úÿ]ô6q²Ýrœ.&Ð5p ;ƒTc'41€†áˆ‹½å;”ÝNÖÓ¨(»’¥keT%dÙìx˜$ Ç}ލ(={Ë}Êó…øiõj)WÌ+e]3RŸœ~}"lá…ý¦´}[nÉýï,œçNõä\œ¢1jY$’y𘩫v"‚û‡8=3$ÜiMFœÂæÑUÉ¥¤R¾¢þz0EIXýCÆ�Wk�5ÑçAá/@`ϺÛ)ãoÉá„Ä×mÉ•°ÚQôA«üõ@¿6D=t1g„º]f¿lÓÈB>Èj ®¬E4\<jäX²X’E—´´Þ{&‰U[*„¼‹GcUæÔ³ Öã è¨hRœ§DèÔ¸HŸÑšDÎÒ̳º¯%K(‘eÒ-:±/¬I‘ÉÔdvÉÂlì‰nOòžÌA¬HN"Ø9#)p-ÒÎòm1AfrFÇ™ûÝJ¾WK¢‘ü"Iê‘gi8»gt$³Q$[¤†[ P0 I¦Cåü/Ô“hÉå˜,n£yÍçoÉÞ † •ç€ §³šˆ#a‚fìFÍ"šçâšÝG )gäy0ŒÀ¡},¡œAB„r ‚wøÉú½„£)¥%NDÚ@*Ø3†<ÆÅËÜpZøt*iàD”0µ–vò ÞŠ5¡‰"F6gÙàºÎÕ1^v†2ôʨÞ*Mv§:¹€Ï—Ûr‚ÑÏ«« utlò#F“¨•ªÅbgËTÛvˆmm5[ë¹²b§²Zz=qjuýàÛas¾:A¶ËwÛµÔú¢©ö«èXînæ/Zÿ§¡­Ç¾ ÖÄ;rȤ±,ÃÖÇ—3~ùY³¡Ý�{·[gèsƒ, ôôü ~ Vl  µ¢$æ³ ¼ßM«åfóû¶|áFèë»Éï �_A_àò—º�ïÅ©?£ýkÁ}â#Bu”#² ®áwà 8} ^a`,÷ ( xxåX†'~ÔÙpFhвEV\4Ô Öû¬1ž¿¼åºÕUùêÕ †ýWq Åë �/ Ößkèjç}âÀx„±Â·÷†xÚ¡L <gl ë‚câɧS¿ù\•{;õþÝÓt±Á EU¬ÝW°�°îÓ¬¿„l`+ "ñmË(ŒiûÀ­†Šü üÙDk4dFè´¬n,1 M¢ÇjjAíVŠïS2ysXoO\~+òŽâövô%¸ýÚüFh[£Šµn8.€@ †¿ºiô‰åX;Ô/š]MçV{㧈ƒàÙEV¶�…Ó’&�!²(ŸœÞ7NZ,T–[-MÊ¢Œêy™õ9°diñV™f®£1_¦^9?K‰èÎAÆfÙwÙ'¨ÞFü|ä÷™µ÷µ‹ÏÂOŸ–g—ZœÇµ9$¢ca[< Z¢^WñàÂ=ÄB)ŠºpV–Á=‘bcòÊ¥¤q,–p!'-\L™Ù±8¼žW4!õ|*à€°SP´š¸H×2éIÞ9©.Q`8S³Sœ¼2Aˆš¤ÉHµ¤ONóLæ0÷¤¤$5gñ$tPÒ #ê$K�ŽÒɘÀîÜ:wÊã˜O=¢8¤Fd ¤•ZT±Q:`AƒûJS�I7P’sFíÄ`ᣳ9P¼õ¡wÏLúm•vã”´qI(S:$̲™I[èäX8ƒsæl•V#¯‰„cH ¶ðÀP,êŽû´ )+U@rîîd-“z4x3o-ÐSÂtrt“3œV 0,–i={“eŸ‹ž Ó€,é‹/ì |¦< <]¶¬)J3¡°lÒkM-XC¹S47ó<yâ…á£ø„f˜/~ýýç7Ý[KÝŒƒxR‚x£Þ½ôéÐvÜ ÷ŠCe‡ð#å'ãÿã^~òy¼.~áñwí†)ã×U¾¨  ë»æÓŒýwWøûgåõØ?Æ>mòF²)ž Å[žàïïÛÏ->WW§ª›Ö VA#¸aÀ0?àô-wX]£ÞA¾D*ÒàŠ÷#¾è;Yöå7ÈëbµËÕþøÇ WHG-P½%Ê.ûÄŠwÀkÅ“c•HƒtÄ8~åcÜ^#^—Y&؇Vò†±&ˆ¢ßý¨³ÀÃ/ † ª(ÀUvx1A±"HÃ(±eÞÎ\ÿ Úïÿ•ñÆð¼`0lKÅà lx¢í�ƒŽÀ š(÷xݧw+¼qµàjƒ:¢¼ãð~l±u`ÏØ< \auvhâPplàßàt~‡Í—Ȉ(Ù¶i[Ÿk Ås„ |ÁkW`:À†½ L £ÓGûVÑ&†qñ„„ó®•Bc­R?‡i´ïÓǺ|ŸØ—‹R•ª -}³[æiaÀ66þs‘¼Ôˆb`ËNkK=,t œË݈5…!é(霣î-÷G+'ª‡Ä:¯6¼ªî½-¸Ñ¶Pej‰=Q`0ÏKæX%ЏdD¤ºòIq•·”[Y¦ ¨˜¦<ggñ‹’ù‚“¸UáÞôdüÜ:UÔÞŠûà[8 €9if¡TvE°“ºg’¡"Kj N7!1€ÓàH*™TŒ^ƒ@x¢‰SœÕ¤Ô9±¡¬‘0#:ç`!IâŽÒ[àÜ[pcëìOš£¤C4!ÎçåQv"O¢@¤sÏšŽÔ³È98’s/šA$A’əԻI6!…Ÿ§tÔä„p'È- Ù2¨2ƒjœ¼£gE¨- sF’g'€ˆäœX¢ñtfh C=ÙúÇ6°Ô¦Þ!O‚Årdë±ô ëÉ=܇a.2¢Ô$(v1@J¤ œÈµ‡RcaÍlù~NÍ”d¤¤œuoÇ„…QÇ*cå"|#Á„æáf±˜ŽáKâ8±娊^@GG¶CÌÿ²‡Z¨ZnÉ V—¥WQ¸·Ð.2y¼�õ’½»ìÅðÌ08ôáxºÀ²ÊþÉ7¯ô’yp/dsæÁûc¶î¾?ÍX–©ïoØZ0ÎToð×rúsjã›Çú|âí—ã0rè;NãÕÍðE“¯hþ¦ŸdZFÌ?»=¬õîL/ q‚É~NP)3UÔñd|Ÿ@Ú³9®N«5jXŠó.iúðÿú èÈ à7xððÐ�+ ñíŸÑö¥–Zz\ïÛÍ_Nö ,†§ïqÕ¡'˜¢ÒÐæé)ñ/ 0âá¥á8£AhÀ°\á~ Œ@Å;>k"€'<¯ødÀÀà>âˆ{6´ O7X5 ›LP<¯xÞ°ywC)4Ôj1ô^€Ýóõô©aˆñð Ë€EQå;`ð„øo( úƒ·è?í OÐKxÇjÆÿ¹¿ý鈕î6uâ†/ Ë¿A�í `އ»ÝŒ‰ï×X¤"+pÛé±ø¡š×&À«ë锄"gˆ@d†ðíÓÁ®ëdÀ,¸¬Ï¨÷(½œØo^Ö@³¶îûîí¿ú¯"»Ìé?ëÍ…4Wˆ´E4æ‰eþŸ*^ *YK=Eù'Æ–å%õ+öÆs¥ÇRU°à¡Óx«,ÆdéUž0gCÒúÛø+mx¶îžƒ”£æ1bôpŠJT%¡ùþ&äyÖ±çeF¥^Jg¨PsYáaK9lsØ2ªˆ‚OµPø#rá8‘Ï•N(EAÔB¬ÊAÊ#ç^ÛgJ'â!“f8t ÇšüEö P(Ó2]ˆ£8ƒH‰œHÜ“2š$ˆФtUf6!Mf8Áøÿy{›ɲä<ó1³sν×="#Ó«²ª›-‘ ª f èƒHÂ�# ‚3ZhÚÍßÓ– äÌN¾k 0Èj¤Q´DV=32>Üïù0›ETc~Aó/à^;ÇÌÞç 8 à SÙ1ªjjbÍI%K×.¥GWé*]© $½eT¥ãâ¨õ ‡D$†K`FÓUSí"Öa(Cñ‚‰kEF¤,‘&l4d¨u³A<Êá«Ä¢š°)Pï>dx;ù¨Fr]íÂÊÞ%(]=¤Z ñr7S¡… QÅÝMŠxòp©Âå:ŠÔjŒæÛö”Ä‘™‘¥‹Ôa½¥ˆ&E¬Im–ã�� �IDATº‘Ìâe+:[J˜aè]´K®‹‹±Ú ¼ÒªE ÓW)'ÉÅ-«oÐ+¯µ÷!cñ˜^2é­ŸÏë¼ÖÔOaâk¦+iN2.é#¤}/~L6†îe$e'd´mãXi·"¨ïñCvd%¯¨ÃOLŸ1)*·¦¿i9žb¥F÷xHãÉýoNÎü°"?w°ù<ÛEÓ|dÜ"¯aþã²\îm[ДcÚßÛ!+*Ç ‚´jÇú†ûÄ—Ü(‡wÂW•7{ºí|ÊûÆá˜8²Ogþm>|yº¹ÀÊ[œê¥Ùù˜¨™sP׃ØQ®ùåÝO:ƒñòç=SÛmÓnÓKnµßßüÕøÛ²*+ÿá‘¿<c¨ODçüÀ»çÛ/ Aâc‡g¦+|d߯ï_PÙ‰¯÷í§ùëŸdzƒ$<3 7êõº6ÜÁÛ#'H™Þx:_&˜;åù·‡ôÍZ™¹Õrßþç«p1± ä‚\¸OüðJ÷®‡©ðº‘Nøwxýâ;ý†~ÅxE(ÉÉŸ¸ù–òk.úa ¹Óqo‰ ƒw•“Ÿ¹ÙrÔ»ÛþïÔ…¤qðÍ{u¥¾©inm:œ TH¶•òÀtdTÊîå!rèP;'ãoáß}"1Rà5Ǥçµ5NÇ?v¾åæ?Žüu¾ÑåX¸ ³m)¡7óÓ±”7ÙwÒ§¡k#që‰Æ^×?Ïÿ´÷ÅXr[žžlš ‡Í>gO†é‹99¤÷í_ˆ¬¯ùBƒ tã®^U;FŠ!ýR)êBÕœ"Ò˜~ÑóU˜õU¥#1 Aºó¬œ/Ýÿe“#o#/¤¡i$¤hÃÈêX´ìŸ2ÝÙÎišjÊEÅM\=Å —:zïú¸Ú}µßã«iH˜,!2zH÷ÜHÍ»H“—Ëu÷‘úÐÚ¢‡ÏeÕ$Xíæá¡ÝÝ»ûjt‰!˜¼¸²CFG(’LÔLE’˜‹)a¡>¢kt—1$5÷¨!2÷”b<Ä:†Š âN Có¢]$"’ÖeDV§%ëÇJ-â™*c‘bf.ó!.=¼ÅxÒÑáÂC]íÅ»‡¯·†\R0BÏ¢TÀMƒR]Ý,¥)²Eò'UFóRסýÌZ›µu–GÔ$f¯"ç‰UÕUJf²ˆ3Õ¹h"™™…ŠXv&ŸCVm³–ˆUÚI|5÷4 uÖžËëȳäI²¥„ÅÐÞÂÎÔç>ˆö²ØÚœÑG}ÐÔ1OæéÂ%gLB2U½Eíãù O¸�‡ÀÞú!:Kà Cp=„£058á'ªâ žHçý¢Tï¿zJ´³®É-R²¿9)Qx†<ÛíóÄöb¿l[Ã+›ï_–GÉ­*­ùaJãV2Óõ^8¬™Ç m‹O¼ht^¯•m'%Zb”C/¼…¥.„McÚsF—ìÚÚz¬•Qaðä<%ð‰2!ýöýíOå¡Bý~ï_äî%Zñ{œ¶éà™üyÿ¥�לïkÎàðÍ÷ô+Þg¾mpÏ×¼{Ï2w7¼=¾ë·úÀTøÜÐÞ™:gò‚ùOójÿƒ¿€û[€¼§^(­ïáO3Þˆ{*è·G¿Îý®ÅõñÿºÜß¼9èLº@WŠaíÝ’vôŒÜ$9Vne‹CÓ%_ÿŠ÷[>…m)•ô9ú Û{Ì[òqOƒXˆ >ÓeWÏ» ,Ôf8C–=ÛC\2ú±¿!Ȥ–ËñÅ^Ù:ÅÉ@'­ä3éÙ„Ô¨ƒŸàãàkåãÂcë¨ßêÜs:,?P§›¿¼ÚÅEù?½~ÞŽ_Ê_9¿I²¹t,Ùkµ"L¢Eâþ/WÿüËâ_Ö6×%æÎ듉N´ÓÝ$,Ð"¤fm”‘Fø®ð´“^ú˜ÇÈ6\O"14ZîÉÛsö‘Älì<ÿÒôµZêIÎáUFW!6üò–ÆŒ¨Š¨DNi„NXi1¤Œ¦îm0SÒFsmâ†L.æ>ûh}ÔΧÕþ}WÒØgùbÑK“æª*ŒÁÓ`t=gE’HoÑ«×>>:#±S±w× u5u³†ûH:Òðôâe¦Çb„W÷©› D\‰þ¢×†{òÐ<N—¦M55¬ªViLH(щIyA)A¨à*¥CFà®êf¨N w=‘êx„{?I?Éj¸F²n2\D¼D+¬¥ð¬ˆûÀΈóH§éK’*‰IU(R'¥jy´D›ñtnqŸyTGbç!=óŸ$)öb„¤…+Íçs¤´DN~á4ï«´îêcM¬/}4Gž5™e2CÍ‚ÑÂ"Öè#ª ž —¨tqO§P–í¬ÙM“…:Ä:äwÚ_<vHÂdßã°|ÖƒœØ¬¤ˆ#¯éÖ‰¦Otˆ+Ö‹wMwÒsyhOåÇÞýb¼Êã³Ù%Îm¦(æ$xkœ·áIgxVJ¢*§8Æ jǦŸŽ6ñÁ¸ïÐØr(wø[.! fü+å¼Rf£(x¡[£—ƒ HÜJBò^8d8?q†V¸O™NpAßÒÍÈìƒ@…ó/ùtuXüæ¬5Ý£ßÕõ›¶æƒê¬+ÿq𠄢ޱý%üŒ¼åÎOÿŽÏ+ïøÞ_ï¸ÛAù†úúž·0gH<t¢± …‰hH#?1ýcÔ†ŸÈ¬‡oõËÄ#®Ñ;ž!Cç–kÚÝþ‰ôx·û‹_å\n´GÜzà•¼î^Å®xÙ¶3R X ‘YgÞÈ{-‡W Srtƒ?"?½«° üš±E6œË~hNkÙ\/ŸÝ‘ÈÊž)Ó®MY—›ÈÇì·@“½î‡æœ+½³í,NœØ¼ô6¾Ø+Ô¹h<7–ÆGãý+~á<Mä‰ìLŠ8²Be¬‡öé~E¾Ø”ÞÊ¿1bÍÏã_æS™Ó•k ñ†°–Uákïõìà Ɨ×ÈvlÒy]¥žs[²ø&éÆU´¹ ÉÝÊ ܈ –ÑŸ';•^ᱠר]< o 1úháŸK¼a¾(Y°1ŠxnŠ6B(ÍÇò3H™d¡§E&DJÒÔQ“ѵ3¹_õH¡êibXV1G|dQuIMÇ)>EÒšÞY¦¤¯æv‘%%ICè„Eäá£Ú«ÔðV£=ô“K%%AÔ0m/úœªѤ «ú)EHdA¥9R%$ð`¬P{˜F®.Ò‡kÉÄ’DR‰´º×®ªCzä´†œVIkäA7wMde$Ì$œ3TuˆE[³Ô& <t šÕ5ÄÆP†Ó›k÷Ö»õîI¥3šŽžºK„´—‰KêÅÖ"OæÍ‡:.âŽk_<Pe\©iËYÒ0AuøÕ°Ôy:\žbƵ }BŠ…È‹¥'¦9O‘óœl«ñâJetO¡Ò%9¡y襫 '|£ú@zHŒ©­ix0FÃC‡¿xêDBÇ xû¤³[È€ôSõ¨U·˜j&%íˆàÃÜo[Á aï$vÝsë¿YÛïâ|ûÔØžß“~‹\#gú51![Bpçi‹Ï»ÎŽVêS]ÿn}_Ÿx«ñ&oS {&ŒT(9Q:¶Ò¶ü}âÿ€‘HÊv¾-AÊû¦‡ÄØó|˜2¿ËLo™3ñ–<1­Ì3›¶öCq% ^6{CAÉNRÄ)IÈ/á»qPGW´GŽ ÿuËW•HÔLÏŒò®ËÎÖ<sӎǧ»ÎÕ7Œt¬ï–ëU{ÊÇO¼nL•>þßþô—5(W莲! L؉çß¾ìþìÉùë·åý}yý_}—·ìõú0îo˜ ›0ŽÈï+¨ýÑ?Bmø}sék�^ÃÏa¾CAàøKÆ=#oÿùþæuÝý\ÊìU +5±Ö}[s9—7µ”Yò˜öët aöîÙ!ù ¿™úï6z«ýÅò²o_Φ ý5²b"³Bpü»A^Ðí79?–øâ0®nbÞõ©x®Å„Ä»»³åQoNëñÃí4~H¼…Y¡½ÛÈN§vqÌõv»rñ#íž×\ –i Î%,Œñÿ-Îa{}#u,«÷´ßµ¿!þwž,æl½•–§Æúa8¾üo!K“_–5ɧI_ERºðüªSâI‚¡Öl`‹$SM)²K†c½æUE'oçnQ½ã=o…çÑ-ùe²m¶I³ijKj´¡©É{¬ÖTO/UtH<e/9&M:Pµt6Þ,¬ QÔ¤©FÚ` ¦†×–B‡¥Ýœ¶Å®±¨§Ps\$Œ>".q–~ ? ÿ1Gq•ý¢DÖl¡Ñìô"ø ÷_½šÿ¸Ä“ð¹a/~{ª‡©êˆ¤^ºØ'h¥µÉkÈè¦&b“¦Œ’$´4v©/t¤@σO#<<® œ*˜Ô¤nªêš1P·ÔS99Æéè*îÝ61’we„ö£ö4\KBËñ¨ç“ŒÆÚÐð¨bÍJW+F$Ï ÃݺZ´°!E]U4K¢+ŒMuYݺtRÁHj»¤‘%KSœ‡œ%ÿ]ÊŸ™l-Dš÷8ÈX´—E" ÝtíÑúhÉ×O£ ĬªE¥§&ÃV‰j¢¡C´u_‡ŸÏVeT(¡ái.Þ»ö°Ä4Rò!CFï½õñazy‰{í¬ýlmË©»œ—1vKc :èëõsúœP¢Ð€´÷”¥QÊŒ~Ѹk_oÇ”B„Böu/~ȉ2ÁŒ&Ò™óþw¯9_ò‹-Û‚%D§x7úW|èOܬÛ#r[[(g¦‡½ŒcWjNõ7–~·‰[Q8 m˜ ”gR'ý:£í¤Ê¹Ã¯à5«PO?±)JìvS*a¬´“ë‡Rn.ÓQËíž·û¿½8üD…m|ýÈûŸšE´Â5i‹dR¡‚5ò–rÍtÅ»7M7S¯¿‚WÔ mæàwœ A1ì iaœèè?ßRÞP6ÿ(µáö×È °å'Z,åŠÿû =ñ¾ï¿&O¿-óÛ²YЗåe?ü¿ýpá7ŸßWÈ©FjM]Њí~ÞF_®ž|“—¤hÇw‹fó›çt<O·ÉÐÆ =S£Q”ò+rÆ2ÂËs):J4ðœ}_Ù…íÜËêµvÖø 6¼+l;°iç^ܪ;~b>ÁL…¾a†‘:³"F ^HÚ}óƒ]£wÈÝ1ÿ ›säÖÓñZöãa¬+5 ÒØv©ñÞãÂýo^¬‡!s‰DÃK¼®'÷ÇIXFÌ}$ªËXµ>÷)§1륑ÕRˆŠšFR‰bÝij!ˆÅjîIÝ^¬O 5±ÅÌ&-Òc0œ![i½[š™N£eÓÙ%F²Ö!U§~–."fE_ƺ¢.Y¤Kˆg âBåçÆ†¸ Ÿš‹¸·Ôz„kKÒ„5¨øGéo¾jÿL{6’¥”aC ¢{wB:ƧO9j‚!Ò1OJNjzVùĸê=¼)ª”x¡™c]³ŽMg‘ÜÅ{H!½1(B„®¢ÂðˆÌšEÓ‚«vÁ\&ËVL‡GX$‰ó ô±Ö‘Û9´Gj«èÙM°¦Úr<iÿ¤C£žTšðˆÝ8—#MC½a-Zê¥Ô¤ª=Ež”¬9ÌUUºèðéÔDµU3Ÿh9Ò¢iÒ¦ÔÁÇfLjïÃÒÐ_X”ð —Ð&RAI“ :fAéáÝ[;ûãtÙ½y¨>;Í2òÙ,g7=¥!‚sË~þ4Fŧ4,˜‡õª­I r,§E4‰¸Dõ¦2N½¶ûÇí¹±6²î㔥/Þ6©a+›ò•ÂWįy¾g­<v+Æ4¥9Ïq°vƒVqªT/ëÓû%^JPý¹=8L?Þ"ÿ„4! JþÀö¶?’ÿ¥p1X¡ï®ÒŸžæËOŸ©øI7¼Oüë;c—–,qóV<y÷öi‰øöVžÐ…<£‰=1%¬b—?-Ù{Æ…¾£_Ò¾fy¿ðM‚-6ض}ò\j1/í­µ<-§ñ|Ñz9üyæ? _WÞ?òþüÓ‹á=| ô{K¼æ\Y¡7NOTX3º°“cœóåuËwÇVh×,—Ø%ZÄÚ‘Á)c‰4ýÁkÃ;ؽ&¿áfËn—o‚ùšSæç‰¿-|Íá}¾ùÓëê÷°TïṁÆÂ›r,_’,kjÃŽCé‰ZØÈ~yëËxØØ'&_¹Ÿh»q_äª. JLˆã í™õG~LûôT/¾hò&é܈:95©57¬ÔÈ͉<¬<§òäGþ8ï©:Ÿ@Ù§ÜNåþóAÖ¾ÏO‡|¿&6ØÛ@e0ÔÞEÛeË=Ýô»#Ü·##ó^—CNÔ`ÿt‰“ô©Ú” “úWØïªÜ¸\Ùü-‹Ït«ÃÖfúPÚŸ™J½L¨U‚ÇVµÇÖý”KOI<!–4» ¦6òEóèI=Cs5,»Mn)5ÉÔ]{'I$‘ÙdÜe1$šŽ¹YKX–‡ìC.R]1Êy$ûDnN=÷)‚«,‘³ª©[ÁXe#©ˆ&“&&É]Ç„o¤Ï^‹;Ê ;2J¤2<¤ •±YäâíµŽIG‘ˆì Yin¦N{5šò8ñ‹â—&9Ä]W/«ÛÆ,‰©ª*¨þ½Oî]I *Í^Ì-G'ų{šÎ‘ZxhËÅ Ť:è Î*䜉ì.±ºÓ‡ÔÞZ;·Z¬£Þ„¡] “) êªí?Å:!ÝmF}ð±™°u`}°zmµ·çbA×ðÄyíšT­!ó5Î:Õ¬iY’f%©'­)õ¤ç°ÚåärdV~#®1Mˆ¡Úœó9dHÆ5)ÕG~6¯êpÓsŒžÿûY6Hæ]ýIÛ@Ç¡­U¼5iÛ~*ž£±V¯gý>ÒçC6i¢t£ÉèôÄãóðG_ûöv˜ë!=ý&Ä펫…ùR³õdûxu°é'¡Àóoùá-§gAÀ+d45p¹*g›æòçI§õ3–µÉ‡ãtÏ }‹(¹`Š4Ê–ø‹Êø@MXf‚"¿Œ¸œü"3¤ü¿Úþµæ¼[v»$›Hæ±´j­¡?Âo¿z±–Ù5l‰@.P}'yÇ&»Þ4Ž£ÜŽ‰û-?ðß _;¯ž±ÌMÎURÒE´¨¤ÈÏŲúžtø£KžŒ“éÏ¿}) û—‰}€@ÜÓÎ+G¨OÌ÷ þšÅ(r{),mŸïtXátÇöW?íèŸï?~Ë/~Í—™9ýÁkËœ§j…4Ðkü}Kéü%\tþ¬í'ûw-®qÍvß%.Ëívbbïé°v2®ô`þš³ÒàéN•Äõ¥Ü£è/aÉòfïzhÆØðøÀ»ãÈábw³¡Z!JEZ´ÃÈïôºfÑfGËᦶjHý‘ö^/¼‚×ÁÏ9l¹I÷µž­–Ü^Æìýšž!1 ´Sâ÷@«„ùvbÔ+äoèìñƒ @É~Wä*Õ,çìyÖ”ûЯ—êŸY.–‹ç>´EœóxÜð£ñ0õªlä1üÙºM‘‡÷O¶®1¯#©,]r²¡b#4ÂÕÑ¡„™©ÆT$¬dµ¢gTÒºGôT0U\¼‡ð‘0³Ð!’ϲUËVÒ›…@ÓPLzÌÙˆl’eT»¨j©:'MÉÊL1ãä5&ÞEG„ˆØ(ч47i6WgÄœíUäü_£l zŒ .M¢ËPÊÈ*,¾Êìr,â6´‡ÕA kbj˜’­m…ŠdiÖz—h£›Ø*½Â=Ä…–$Rv-ÉÆÓZ gÖs˜g=™”¡NJ5 Ç+Ô‘Le63xcDm²†6æs÷ID=¥¬¡0i®[ þ§¢xk1/*âi†'Wy èΨããy2ü•XrÍ)j<›¸š‡gBRË2/Ë«ËiN˜õU8Òã4Æq=´¾?yr/­™“ºJ„o<2¢Ce¼„6œêC¤Iê-{gä‹jW'Y°íd¹[J„wo±}îc†¢uDí©ç ªL½g‚±jôˆÿxJþ`Òd{Ê“Røµ%Aœ4_œŠ6Óƒ%€V!s¾æã=ûm:ØL©2Ÿn‡3ü72/ea©_ÊñÕó÷Óé ƒþáô–ésrPb_ôàŽÜ1ÇÂ’iñNü«³öÅÔ(ã„«'‡×c_JN¥è¬Ã²Zèš|uÝ\÷^öã×Í„2®8;ä˦âZ½°káûÎÙ X„¿P>ßú»Ïû.y>ÿ]mÕ/|¹©˜3F‡æ×}Ë´cšé™ù÷wnÈpsäø%·à;êw<_s†åŽå—|öÇ|¸`MHÇv°ß‹¨Ä £3:®xg×™®±{Ö7ðî)í!¿§|Nù ‚ {çðøKæ+ÈŒ·�›¼Ê\6dÜXÙÃ!îÐÂ|ÅÕŽYY ªÚƒO°…I˜ãwb ÁcÉ+§ÆƒÜ¡äÏ`¡¦7-Ò¡eªÐƒ§×øŸ‘Ž\ÜSCz£‰Ýië­÷}>èBrb:z!$;í}:²áÏÆ«‰‹ÁvåŠüÛËtýÐ9滟N|\35ôDžà’ö/ÑKê´ëìwÿúù[ŸçÜoÎë1åÛ1¯õü0•í´t¼¤)©ô“¸9C9»?Ù}ÇÕçæ›8K%R“´æ¾.ˆ³äíÈ>ålúbhf1Mª!"Iôe »˜2$©ÑFêW•`ÐR0\SU™"‹ë ™Ô¡«ˆjIó‹qA¤ˆ&š%)²$ÍCÓŒdê%ÆFz£5Ü•P†ÂЈâLgÉ«ŒKÍsù™ñ�ÿÏ!ë0WmM¨^šÊE$S)ÉgcË‚Ht—>ÄC]•xÉ÷ö×ѨÕK…pù fd‚¨Ù¥£ !Ñ-ÒÉôhÕŸ'uñ*˜ºx =$;â1Ä»r²T=3¼)$™¦0)Êx¤pÉ}l‰™êž.CçÁV„1ZÄ?Œþco~VÍÓÔ&fÓì¡ÏÚ]CÏôhS3,Ù|±/__l/Ê”D¢Ót4z«áS?{_žz<3{̘,î=TÇ1(1f„ˆåÁèÙ±“i‹hf•m³ù?kÎ’?ÓäH ™ðNDêcö°0SñxÙãnŸ’<UáÄX'?ëSçžôÃc”6]_ 'xPž.n—ŽÛWKë]ZÑ£‘ßSÎîø‚w3»ríî†_õímb¯Úý¾N)R)Ky›(=ÏB*èÌ寱{N÷ŒÓ;Ë;Ñã&Êqp Xáh¼eׯ’eÉz;mÇæÿ.™å`q#KõŒ¨UõÔµé©ßµíþÀ†šðN ü‘)þµèÛZ/Ö³=Ú©ÛÃiÚ²Ãß*ÑÙ5J£6¾^wê;y.«Öuãôý˜Ó¬»ÔsH{¾>ö–Ù0#)¡Ìéz÷înwKúþ @…Ow,×¼é ¦ ˜øOð³Hýÿ ƒ€@º£¿¥'dAOL”;ê5õ¿üÃÖ†ŸpaP…ƒåŠxóÊ? ?°ÙQ ™ñ_“îñý;lOZB€WzãôÈmÁÍ`å¶ôÏj.Ç«õGê{þkþr—¿üY›_u¦&ÎÁʺðÙàM°,·`±§†Ð¡gêJÝT‘åM·Ã©¶ïãð¿TÔØl@)™iP*vIÝãNjDa…ñ36Ÿ“&’Ããþôx `mŸ/¦7P¥Àëê?6EŸØµe¡–†Û»ÌNNoûy–ì‘×dOž {ü¢õô\s¶EÀFía©‹œsZ¯rÿMgüØô¡Í—ÏkqÈ#l„×ÇVR­«Ö‡\r—œòÔÅÎ!âf&f¢žÏ’Ep)X´!]i îê-B<¢ëh!cˆÉ ®HrM~ZuK¦yØT3k^Nl+sr ïÑUÍ’Iš5õ˜Ù^€Í5źÆ*Þº3Ì‚t—\‡çˆ¬ä!VÅ»]˜üÒäJÉ}äX›œÝÎ+å^íUd.ºO¡QtDTo­ù0`¨B(*ê’º/MC_ô<²Ššð¢Z !†‹ éuy‚IôRb²n&}¬<wå”=YÌ‘§aŠàc¸ŽÖ<Nªa¦JÖÈ6MN‘D#t¸”¡-JcLž^üp** Ùˆü ëÉû_…‘íÝ4S©ž¬2‚É$Þžd.bIJžæåâr³Ù,KI)ðÚ¥ÇhcL­mÖúÙsž:Æë,y²”5¥¡ážGOb &*AËÚªú*±fß4] ¬Â{øG,ÝKZtôKëâ]e„F˜¹ªz}Ý'mN•“êG±ÿªg/ñ×4üno±t˜KÁ ÝÈv;+Ö÷M/ƒÖ4èƒÞ©`ð»™]¹+~][Þ’oDrðïd‹qùœìUŠÜ«žÛˆ™òš¹“aÔ;I»1þÏy*¼ÊXÚ÷”+E\F^ÝO½Ÿ¥~gëmù{ò€vŒ¾múµúã½·ÇGÖÆ??މç„öLœØÞÃI‰yô|~àÂ\·9|„?OLƒ ä;ï_•œ/JYÊtæÓšOät;]2ƾjÒëÝó÷y³¹±8n¹ÅÉ™¸Üoþ8ëÛÂ}á; ß±äð >ý’ùŠËÌtM) làKøÐ¸RÖ»Ÿ² ý÷ý›ù‡üHiL÷THwŒ·ØÃ¼§t^‘•¦äë—æ © Œ±…Bd¼ã Ð¡Á¸&^2 Q*¬—{6‡w/]ãgŠïO#î£~Ì›÷וüìöë-~µ—í¡,hÂ…~æô"Á(¼ZXf挌Øhž ~AmØ™õÌ« <Æ:©ryb;˜&FÂAaGÚ•T,åÑ:nvè%S~§cW×Ë8¨E�� �IDAT1ÿÉ3„Ô¨7d±ùHκ4&û®œ(ü–²Ïýªo_5»`›«zêŸzœßw9ôøw:7¦á9‘‰ÚªÅsŒuáTÑ“Ë_Uß?“*;ñÏóÖÝR¤ÜO½§“rÊK*š7*SÕi›ò¬2i2ñá½S}éa#&Þ„!¾ª #ˆ1Üc€a"òM"ÐÃCm„;žäœÊC΋$S ìܽ÷fî`**ZBb˜"ÞƒaCÄ}ŒÔ\O¡8ªi)r`–ÕšSð®V}kòÊGÑTV†º˜¥/Ð6¢¢‘À\|ÈPÎ.D¤v[3æªá A}”as-é<ÉIÇBK¬Eú]eØÂÃQUNÉuÍþFc£a& iV.áZ\ex²a‚žBž‡%Ù:ËFTªÖ M/H¾aî!Žà’F¶k›{<[×hêe´‡æûΡ̷Sé)¿cÄ£ú/MöÜ‘’G¼LÉrÊb&&(á/hïêãäí±§§vµ6Õ:•d%[-!Œâ®ˆH/óÀœ“bà&³Ke}Ž*dC·2}ié1Å¥´ÅÇÒÍžL°–©ÞšÇF{²Fšº¦bªÛðìÍ»&ìÁø^ì€Oïän7Ê¥ó…ôã’nËkò²Ÿô‰3‡<¨/Wÿ©?^¯HìòLQŠÆ… »ˆI¬-é)Í‹þQñäÏ6ŽÇÓGίñÂE¡ù´·’{/Ú‹%üêRÇþ3=,²Ïé õ¦¦êpê5·“¶oÁ@a½­ç›¦kÈÃóˆì‡ïysà‚¶å<°•ÖÉðÛ=×™;üÚ¹—û3Õsð™Ð`›Ø:±27R;lÓMYj†N½Ê-åfäí¡M7Ÿ.wŸ—/ÖºuÆJ„ÀtP¹yUê×ðž í[À×ðþ Þðo+h‡39¸|¤\3îxº&îè/Ù:8Ç[öåú~Pz‚zÿûÔβ6Ü[ö‡¹þÞß ™ˆB5ºÐ5“®éw øtÇô5“ò “¾¾ë–—éæ•§J:íêó%iþ/}þ¶ w…_gvû÷‡Ï—C_ˆ ¦Î_‘Ê›ÎÒ˜gÒ„\YÁƒ³$4a‹ bœà\t.?±}`³’Þ0àlð¼ï9—"s™ ƒ<¶û>Î3Rˆü‹h;ß–V4­}äÓS«ÆÑ–¿Ò²÷8¨q“®ê6SÞÖËïÓ|Õ㜒õ‚ù@ÌÛÃh‡U÷Ÿ¢Ön«ê¥ÈhZ°ÞEªõ:¼J{,äÜm¿úṿëÈJ,Ó,‚Ô¡ë“u]{Zr®Þ礯òÆ fÙ_OÃ5÷�Á£yˆöHêæƒ$ýe7¿iDŒ‘†Š$éàÞ½öÖÅ£—¨Ù{™ƒ\´˜£«8^]RxÄÈ1¬í½¹…zÕ1r÷ÍÚÇ9†‡…©šŠº'› e‹¸Gò~FÕ71±ê‹Cg훑6.³| ÑPš¬Æs÷ßqd|¡kÒ\Uˆ QJ·¥Où4ñ¨µR_?G 㫈ÅHË[õ¢§u’ ÃÌÕ›ú0d2D„ˆè!1r+.>lï6tRÉ!Y,«Hr5E»¸„+-Æ ª{ïžû :î+㪷’£»ªJZ>ÊæÝì¿Xd£þ<ü1:©n¥M–ˤÒJERÈèv‘®6zÔu]ϵëHÙdJ©çDJª/MA׎‹h°ERÅEc¼°`_„E”™MÑ”|q¹ ™ª©§*rêc.UmhŠ—4DòTeÔ©{taôWð+•Èü¢\ïâ»â|V®·¯vïb»+9§t#zzÛ„a�çNÌ´ é¤qH?ÜÈo«‚_E~EÝŠë">ëCY…3„ð½?FãS' Ò„Ê!ËMDÕ‘mÊlç‰?ÉüÉ4ªù CÎr|”\´ù8.ƒjÈô·xÛ·§| y:•ÓÊéïò¼A^ã/ŠžŠ?ïåù ƒÁ¡ÝÝtžÎw âòðƒÿO}¹Å•ž™@Œ‘a°4$gr×vÒcú½fÞÒ7ûuÎÏ©ü‡Vþr¥?f«ûx>¤…ub-ÇOð>g®wÇ—_íûkÈ|½áÃ/µä™ô7JZÉW¤KäWÌö–õžúÿw×서ïnŒ£s{‚ þqrÑ_ƒ¿Äß?®÷<Áå êÄ£P…| 6çÆÕé-<~Á]¡'~¡,¾+y—µl­þ¼½Ídé•Þ÷;çý¸÷FäWEw5Ùì$EõPž™2Ðp{aˆ¡Á@¤í…Dx#ÌÊ ÿOÞxç…�‹”½ D�^®E†Ç%i&‡ät7£*+3"î}?Îñ"«eYðÖŒmÄî"ÞóÞç<Ïï  RÙ,–ééÓ·¼º/\Ö•´#c‰®ˆU.Œóмel„‚G:X¤NÎI¨•³Â9¬9nÛå®Áx,ÌœíèŸÃ„:´º¿º‰—E#šJ$úa—¬&lØš¯*ë®c< ¥;'E4e¶9ïܱJ^ïc¤¶tÞjöÁ6K\ªÆÐ,‹×úì¥Õ[åŸ×Þź·’KëÚ¼w;´ê}Öèm®…9õô}?>O¬û••!”à1Ï›Pj_µì=Öƒ,Å5!K—ÞûÜTñh(–*è,ƒ'u%‰E7ÑŠRµ· æMÅLL­57ǃ‰Ò55RKq˜T•‰Qh£7kK˜‹ÚhM½i«6b ^cµtìñÔç^\UÑìAl0K–‚{hîÒÕê±×Ù’´¤&&îÈÉeè1†0¸ 渴@±pêmnþûïé¨ü9cG»jÔ:îf±¹»Ó®®¡Þƒ?¦¾hsésõ:7¿ì,M“% )Ådˆu«ÞìyÕ‡Rje–!ÒƒˆvÕŽ ¢ÁU=Šh"Å,ÌRj†é‚š‡Ú{é]‹½Šè õwh–Å6"¬»aÎP?[µÍÐ×Qi6–j~Z±¬“¦dÑ4,¦Vûtœgï„"«s*õ±XmH 12©6µâ¡‰¸zóNgQ¡Ó\ÄM‚åDP ÝiÞ*Z»µi^Ú0Œq•–UULé‘Hˆ}î4i¦eÄm‘$ÄвõÓ“ËɼtE£ÙØëÖTWñîb`Èôpçú<»K”<ö"No9%̶§¼K‘P@(mo®“§ÚóZ‡¡„!uËÏ,}-RX¥Ð2Pßr\sr¶žwµX·Ÿ> ¤1…1„1v†¹z+%íá™­„]È p¡pê°«rsjå›D+åþ»uã»<QD^zÛäÊr3Œûöåm¿ßÛ„¤ÔÌ>‘º&PÌ)‹„ÈÔocÝ:»¬„Ïß~DŸvót3Äò"aVr¬öõ®Ì”öŒoÏ_Ôm»Û=9Y—wèsX_re}OþšñŽú%ùéÄÆ)r‚Ghl2›@Ê“ZÓ¯y¼ã«Kxöÿÿlxrà>‚ƒÁ=¼}ƒÁókì9í÷‘wB«¼~üäøé—„D8c“ ðWm{ÕÒEɃå1³Îs$œe$wóùóë_?ð|ÏÌÜÂOœ #FB'V8¾A÷Øþ© Nkî#Ÿ€ó…õ×/‡¾Ñl¾ýÞoã#å+fð7pI;cUä“}ZÐté)xÈáÙ o÷º¿­F‰ôd[EµÒ«õrˆÕØY§?!;ó­fƶµeWaõÒÓ‡Îi+­Aß ^6Ã6¼iñ¼2Œt!¨wúÒcƒT 5¶µ_Ú©Mv‰Ž2 IT½©kP )ö¸ÖPEÔî[;I]@Ô,X˜‹Ø‘šMZ —Õ¦A²VÉ®\Ô‚˜Òƒ?­¼w&ÞžJ‘»…("ÕeÊŒ0©g·ðÔ«i)jHAš÷BŸYiÏ-i‘Ö¤¹KµØ=6Chƒ´ˆR›˜IT•%ÚiêÒª¶%Ü=Î]ÿwã@Æ&w7·¦%Ú£ðЉ±io¤o‘îq!º0‰¹.¸Usµ>x®H¹G)™ãØ-U sí³öšÅGz¶ª]*Åâäà®ÇÅS‹j,‰Jp+9ºŠD“nꢆû ªI%ªå5¨$X7ÁÅ U ÑŽ.-,[4T‰K•v¥á¿+ýÏíl(¬½7IúßÄ0¥0&mH¯Ì«vLÖ 9Ù‚wźÏÍÇ*mѦAKÐE験2á­Q“È1H‘ž%š{¯>w¡ES¢?¡+TÌÄ‹ô%XõÜ™´Gõ`…ZÌSõÚ-"¾îuEequ뮦©Kª„•ö®Ö‚™”U[þ”~LKn_êpÓ®W¾© &!'G–$iSLqs$á7n{·>ÒÓíã¬^mãvÈ A‹AšéÊB+~<ŠìÂù‘5,ï_>6åÙe’[_k‰Õ•*2×СÄ.˜$Ò6èN+jT‡2ÑiÊœ÷%²Š©­êê°/ÆÛÈ"¨oÛj^žk\pû6l?bçà;äKø”VHãÄSpÁȈL»± ÂBa”½ «å´§â¯ÏyžWþô~'×Ô;þ˜`ì°pH%Ây"€_>¡Ó‡âË>qöH¼Þþà.er$'°Ï“\nYïÒõöã¼»œþ Ù7…'?¹Ã[øË§÷‰;^g^Àëî¡À/¶ØŠ<}(]"/ŒWe÷‚›VJ<²Y•1<¤SªÞÊ’÷ð츇éÉ"Š%Nk4f‰ø ýû1eÅ£rPN•o`rdapâ°QÛHÌúPä-Y±¯Ð7thׄÄlާÛÁaú9ãlÂBxKü\ïüóhi”±ÆdN­ýþ4ÖV÷­“g’£Ž$’Ðã®ÂRþæ¶ü6üYÎdÍ5f]hÿóùi»=~ï¶ðQÔóÊú«x,fóà'ñ‰ôaàø}¹3}>Ê'I’h_bo¡W%¹d•àÁU²xLro‚}Oz𛵢¶èÉê^õÊü·Îw«û€·nNÜTEqkÒ»™·f„*TïÝ›Ô")¦1ˆ1™ÌhݬQè&îÞ…Ú­Žø‚­±(Ý¡w÷f©š.jÞM¬¼Ä¥mÕ#Á%4¼t_š5ñØ\´Õ?6_9#$IVé­·…¯’üŸ±]ùòË'LƒDH÷‚…Uõj k݈ jiŠÇ4{÷Ç,u¨ššú"Ò½†hš¤G¤úáAl…©©i8¹/EmhÁrž<¤ÞµAPí®„<ijJ ®<uñyéÝŠ{wQ¤›š‰.êK³¥C–jjÿ-L5æž³‡bÒgY£IŠ"*æ4•FÇÜ»…ÌC…%˜ø±?IšÝÖݳ÷IÑ0§2=º5WÔrtE:H·¹ ¥·î>*&aPñ'΢H#4‚ª¬²·ÑIµ¨Ý[Y:¹ÊÔ÷>©)”(Õ¼”®¹‹‹©µŒ‰Z ëVýÐ[‘âœâq²Qc,J Ÿ{¼l¬kÏ*÷âTï»6Þ´´‰–9íÄ€9§„?òŽÝ´GÏœ€ÅÈ|ìµØßT.H{;Ã~El o7óýæ+.ÿ6…?®ý¼ßÇs‹µXÇ,yÁæêRRª*;Uܨ{äév-ŸpŠ,Sº•‘!n¯dwÊ”çÄy{E²%«åwð*'ؾH;®îv—|èåž>à—”†­˜;Zé…Õ6 ‚-è4¥6æ~«eû®ïÎŽ„{Èäš!3\ý9vÏ¡îH¯è_R…s8oŒ•pGƒÓp¡;ƒÐr¢TÎïv‰›L0Jÿní›xJ7xÚpsiû?Älx2N8þ{2Ökà ¯ŸK¯x¯?‡-\²Œ¸P¥²ÌÄÄ?É\Ô}íXMþûú8î LJ’Xý¾î/ëîû[~»ãÕØò¨q¼B4gzË Ö—È;£{ç_yø¡2à¸m«DÌÒ²¿Å¿Nv·Ù­`ýUÎØxpz„3N¶]r 1CžŒ³O’\oõnçÏÿ¶=?¨žáAØ'Z–ÝÁù퉋L.„)ó”R=6æKÆ{Ò7„üK™nNZÉSZþ³q^¢þò,üËU ¦®éhé¬XÍkS*ãPBŠ'ÉkíçÁ.³£òèK•ò;ç{èZCöÜ‘"íAë_ ÐMÅT‘gc,N¡kÈ9é"TÑ\ÓÐ,£+5Ô1“*ObhéZ»yëÁ–1hNM’IÝiÔî­+Õ}Q›]Z³ªX3 ÒªM¤K”`=Úc§ã=ÚY Ékï-Ëli=uq3ïVâì—‹CËcTíÖs;1›ß›íB…^_>óÜúY–.Eòº·ûHÌ£æ Zµ7J VMݺö%Y ;V‰6{bwO .ò34Ⓠ¬¡ªÎ!¤.\E Žng¦ƒø€D÷h ·Ò[ñÞœS÷Xb075×…p¬O=bÓÈ4ªY¨*O,0Ųª1zHÝ Š/Áê)=zSÖ^²ÄÈ Fè"ÍäÄ^¼ 2Äà!*A{xÀnQZÝ­9¨&×ì!xm8N©ê-‰$R‹ÉæàîÞÃ…éªHrU¡8ê®,з.Ö–Á‰^ˆx,Ê<ȼøûSŸÇ®Üg;¡ù½RCjú‰±9ép4=@ò^-î—°]HKÏê9�5¹o=îbg §ïÒ/9¤m>&óÜ›ž*oüÍAø¥}Aƒv…d:[OIÎVé×ù®ãÙ] ¬ÒdU<=hÈ5ÐcQ¯Íö±#Є('â¯Ñ/à=8*c£œå]†ÐX„«Qv›å&?–2s5R¥í^W¸ãcžà¢L`o8¼A·<VZÿàSâæN»ú~:*Ë…ã#Sâóy÷þ�Ë‹Ñ`Ãîˆ_2<#GT(ÏGä9õ»'€¤§@ò9~IYqèB*pÂÞâ÷D˜Øgh¤r]ëz¿œmjüŽº¬zÉõ²oà)øöä9zñ­@öÔ÷EâêK†{~x +«€BiãÝןÂ$·eû¯m7X”Ë´ÍNÝ…²œV_p¸=çjà;ôGæÌ×GVðñ„ á&‚pVøi#XÏH¥Ù®7äÒTfj»Þå;2è5ñ»G<qùZx¼ ‰q]z¨ù?ÞõkÌn[߯öU/;¼¡3§Â_5~\XO¬Õ0å=<À]æO.Ñ_“òéþÐðÏÆÙÆ‹ióÑȺ3øÖìPl<´²˜=”e}\÷SjÂ(szžw›Ž Ž}ã3o+îÆ4¦£×=@CÂ_¸Á²%à–L¯R<K=„&¤B¼GSõÐýYo!ÕDš˜K+˜¸6šV¥Š/å¼õ4j*ê¢w[:ÕhRçЬÔЪô!¦lq¤ .! †u3Á‰]½Ç¾4x4mÎÚqÒÇ =å¢Q[‹µÏZ$ÖjCjŠ»˜ÇÐMÆPQCûK)?r9÷ ÉöK—Ðãzž´ôËÔMÚ!-®'Õ¬®Ú\è­õSKiÁš„@¥Õšm´·ô ÀŠI7\+¸©¸£'ÑE—³î“‰jHVB »7¡ž¬õ ãi±�‹¢Ú-z(ºLjS i³¼X×*¡¤`‚EcW¤DæfïÔ%’M’xˆÝ‚¶Qû1¨(½RO6#]x ’!!8ÞЀ 43䱇‡ú41\Õ5jÛ´à5k”n¢s¥œ³ï¼ÿ#K箃o‘%ª„"Ô âV£÷¼;òÇ;1·ã†9C±r?µ]WŸµ±…¡Ú°7¿ímk}W‘EnB/Qµø¡Rv2¡J(Øš~†±û¦Ý¬Sz§R⫪üRÀ^mË—»‡†€¥]8»™8Ž_&îûxÝc>Â=Ë/dµõ°k‚[æ* J§@Oè5ùöTÁæüuâËŽ÷-º…À»ÀgÛUÛë¿!^¦ÃX_4{ýí!ú&XóÁ{aþŠÿã’«GÖ•gyät‰)ç¼OÈË'¬29`”úŒ28Ìà×ÄÄðÔEˆy¢œè0ÿš=|çyò}‰?‡ûÀÿäüø_yñ5߿㠔[c[®wÓÏŽéùûtFOëvþðÚ7<iJO×ÿî»KxÆUdÓÈi gÄDt£9•¦lÞ29«}½»0Þ՗ò™sBäeæ–ÈêcÆÀ0ð_gÆŽæ5‹ðM&6¦™õDN´LØø¸2}Üa`ÏIqo m©¯j¾Ÿé([o;{N딇-w•W+^F´î㓜J®SÚ÷H«/ëÛS“Êꥷ[i 3¸3¡(ÜùÚxƒ$Æ/Èp+ãö!žÿæ,|?æó/=­ê6žv%Þ8%¡ùªkïÉD»¯!7Ͻ)fÐ.ËIÒº‡Á1N¡þ[w€5zE”&HÛõ²mýÌ=GS'#§ÿ¾ ³¥Goš<ªk‹ØÐ.­X±ÞCñÜòBc”‚G7é­×^´"å¤öèõT†ã}Ô+9¯ñÙ "QœØÌåd-YÇ=H ÍÀÅZèþEIƒhT)-Ó¥…Ãì±É°Ž‘hš«©ÏÝïTþfȤ²•ð™çó.ÏØu š>³0wpµxìiUmluaÉE”èeªQTzñE95ù{ã¢ûJ›ô¶àwê®uOâ$‰'kÉ]»ö:ô,#D÷®®¢³ùÿêþ²*¦j1뜨j"Ýû�k±üäÞì±k ]+A5®ˆ™Õ»Er )²`¸$—ØŠHÞÃoMr÷ª¤$4¤àYëà¦.âQKÁDµªT{/õ¨’-‰Xn¼¹U¼‹ê¢~2û¿Ä6”vbèz·êæ&ÕlVt[¬H§̃$y’<…g¯UzŠ÷=MgâÑJŸ(a.Öø#¼ÇBXDjû›¢Qñ‡´œª§}Œ·ýœ~µm«ÝÍÞ»£³¥Ã¼×„Z ­¶ÓþÉ>ÞLPцf>aß?¦J*Rëw÷§÷/Ïv'éýNûº¾µÀp±VDïò,ðØýì¾MûØ®wšÐÙ¹Xâƒs©ŒwtàƒúÈ•¾\¦yŠzc}ŒÄÍt–†·5]îëtu–4ž ÔžŸÿÅ«7¼‚ &X¿ácxwM¼£<ÜÏ8(aAáï‰÷È%iDd'*%s<GÚ¶_ïwìá›;~øœØ LðHMœ®ùWwüüŽ õMtX” ~x}G„OŸÒŸS/wÇs¾žt‘³wuEÓ–^ù¡)½`à©{èÛÏ“ã*2drf èa$FZ :—#W'ÂjÛŽ#–é± ¾97£äÅË0 q|ÅZà ™+ïáuæ'lW;q¥AuaÉ|¤ig„t;¶ÚŠî䌑—„M#•~£ìÛrÛ¾ä^½…ð”§¼ýÏ#Í·*;èPŸmÜ6úu¼PÑHm„ÎÅ=zÏŸ~Bq¬œï*W°i¬+1 ghB¦ÝJ?ù,$%ÔâNaÙ«Bæ:µõ"=,5^:ñkÖ{† )Õƒêw,Ï‚]déÄü2=Ò+VX$R|éöY-ÍÞž¢©OÙ¢¸©‰æ>ZmÝK“¤Ú+VÏÕsðÐ=ºùPNùV)Në)cŒ9HŒ®Úz³&´¦ÍÝ›2Hz_SG¿®úØY›† ±“šéÁËâ:z­GkMÒ(š[‹Úr/Ùÿÿ‘£T<hTÎjŒ!MaqrRNûBÖð¢ýITº^0®ÂåE\%ÍâÚšÏn5u;wu·ÆJiý1T§‡rë½ÙÂ[oä|íÖ[īƎ¾ÃÖøÐO+‰ûˆ˜…Ö5/U§AR°$tÙš˜öž´ç`Yw¼)> bÏ>T}WeA‘´N%x«nÚ.¢9¸JÌ#Ñ[÷SÏÇÊÃÌ÷Ñ£«X@9s5o•ž[óZºegjĽ·þXìAkô´`fI‹>­vˆÕäÞĤwï]k †¨ZÞk Õýò®‡ßuI guUDúÅàã@Œæ¡Ú¢ï-üuÔ5ÅÖ<eI^Ó wµ~å'í(ÿŒù_\Vêï¶úfç×,?" è¸+QéÝy<@ã¢ßæÚ·Ýwòˆ¯X<e;S!¶[ž±„mZ횣—7ª›ô»<¾)Ã%튶q¼U¶õÕÎ>ÚvvM?lƒ)ˆsœi{Ò Ô™ƒ3<’¾B A{ÃN_lßí71oÏ"å©ÓeJ›¬9]–˜ 2›OóúUf>¹áÍþ·'˜¾]»ðk¸ãœ]9ò,‘z$~mH „Œb$dR|™m3Ç4ßÝìÙ¿ãö5lîy„ï¦LLˆCc®îø1ŸÈwès¤q±�ütá·ßðêþI>à÷OZÎ%§çì×Ûƒ¦_Õø¢ŽòxÔé3^}+.½þ+áxÝøJ†)‚èãH /]6qŸªÞô¾Ÿ—Û÷¬¶›cÊähÙ;ór.}Ê®CV†ê‘Ã7ä‰Õøò›û ¾÷~ë•ÉHŽNT¥ezf²îš’M›'w-²À„¬¸8ò0^Èü/ ÿÕ°;bÛFzŸ/~Ç/H!ùÇ[Yí:ðŒiâGg^ð™vÏXWÒ€œ£Ä±ý¢`—UBrö—}_ÝRê–ÓÎüeΞ%5 {‰·1l çJˆ} ¡zÆq³¢­„uÜ=e K¡v,½lú£¤ç>'+ÞŠ²¢5Ì…Ç@QÏÙ[Š3¢²y:õá´xªªª9Ø€Oµgíã´R!ª†ˆu¯&óȱ©†ÇR||&cöïE6âç‹ ³'ñpòÐDG™ôà&ÑT´Åd1ôÑZ´­+±°´œMR¼ðÑUEU¢JL‹[+�ƒö+Ô;ž}¼’³3ֲʥQñ }ŽÄ,ÝM…dãÒÝÝkŒjÑÁ[Å-ÐÎsŸ\Î#ѹ¥‹ÞþæË–�� �IDAT_›yà}¢Ði]Ì»Y[¥“¦(Y=P¥z‘‘Á\ @»HóÐu0²¦Ôó\ƹÏjë -„Œ¤ÚÝ–ÖâªAžžb°*}–šqº/G o翱õ¾åÖù58þ(̼”^Ìz'z¥Q¥ãíof sø42g[ùãÈSûíH"ßXSi¹’±¹Å¤Èìò•ë_w½]òöÑ>‰ºÑðÌ𗂤ìRGb’úÑIèh¦ÔÁÛºz°ç›cùëÎÐ8/»ÓçÜÂ<Ð×x•)ê,#ù$5B‡¸óöÔúòdœj¬ŒUFGÈ «]ÏDÛRÿnާ®Ñtiíçmj]obØ;·ÞYlçŠ)ñIL¾GèSϴĤ\~Åô† 3xù–M~<ÿìãq=¡‹Aà| å`ÙÔÎC jNLÿ%úFò+S®y}ÇÇðdMÒϱK$qñœoîy|ÃåÈ™ ļmmWŸ“ÖÔLz¡7’`ljÛÌ-/×å›;"üäß»jÿfæùÌØ RîYàWðO¯÷$ˆ¬+¥szõÿ’sÂ5«Äîu÷ØþÓZlÉËo5ýº¯ÿPý ÿß•p�ïÖÛÉw‡dÐ NtšR„œ6Ó¸éçùñTÚ¢ÔAvc¾‘c)%•žªŒÇöI8½¹µsÖ ±Á;8²zEûœérÓF5›.°ÎdHg0ThÊûÄq g#QPÅtë!…œÑ,H9l ;Sþá¡ñqã]æ•ð¶€³DbÛ•~“Ö%\_•°v®Äˆ>…Š…2rê 0°aOxNø,¡Nh·ç~Ãd«iÉAÞ°€<î‚m»Ýöˆ‡­§ÛÓkÓNýª$3•’”*ú5vC dçÆe_ýöTéFŠŸùpîráj4âcM4éµV—ZÕ{OJú¨á™†«ÞܬúRÿþ´¬R~ÊOAc]ܵNW7Ì[×fÞš·F˜-¸jšâY´ó±‹.¹ÚX{ð¬fšÍ¬ !ipMçaî#kÓÅô/¤!í&Õ£×Ñ«%£¶ÄIXÆ84­-¬çv6ˆóÄcô˜ú4†=FW<X6 QQ‚ɘu(â+¼ŠŠŠ¸ÛØé¦É~%dÂE›¤ùY_®°Y-Ö¢‘.]¬{S'Œ!gÙ‰îÞ¥ Ñ£Ž"¨»ôê.^½ÄnŸÔëµK›ÜF :éjTÓ^|îËÑ“kJ.ƒZctífá$§÷ö~¹'oÚ˜fÑÚ{0³Sªk§šˆu³©š­­žz,øÑêΈQÒ>’²JåÊ뚨ÔÃsä‘ö{/X}èú‘µÐ›¶àUæîJë ‰U½Ì~cΩH|ÔÔ%ŽYš*⪶W£5õj[ÍUæYÅÚ:ÍÑþÞ+%GÂú%§§‘¹#ÐéÊ™•èC¾‚Käœé™ˆ™ÜY£RŒä@èééϵkñF½ÈšñëjÐ6iË­”®<}bE4œ,†qE?Ðß ààפ»X …Ê6°9c3\æË”f¡×Ò—"õ¡…‰©,ÊØ ía˜±²’Þ›èÕ¨òã»ô+¶ïØ=-™ÇKâ3RdhüGß®"^¦sWŸ„ÕÞSÃwõDyG­ôK.tkSj§\òû;^“~ÂvÃ._Rž±üUãå[ôk†;ô[aæiÕñ.žÈC× w\‚Á˧@òÓ/ï8<gièÂñwgˤß0ßë§ý]ýÃô7p| ïþŸª"xóò 6W×Éžßè'û»áöUçEãJxç¼ÎÛŸX žI¹TN–NãvÃn„}˜I¿ í“ñhc­¨#«NŠ„DèÄ‘þ9Ó›íÙçéÓOòos¾<gŒiÔmöÝà`œsçX5¦Ìh¤ú `]—›ê¥B“B¬*»A8¨<›y÷Äv¿l|øO…‰½LðƒKûAðuf}CÞ‡~›íwóÀ}ÄWè'¼.¼ìÌÏÉ} ‘†UÂÚ^d‰¹dÔ“ÙVZtÙØ’úÙM {O·èVÛ./H@:r:ÞçСóÏm™äìÜ‹Rì~[+é*K˜<EÄe} Kþ_·"6/^±ß7Ý„‹1­‚®ðX´}Óç½·QrÌ5¥Ç€Òr/b‡žbzó¤Šwë™ÔêjqIž½§d!W¤ ½’‰µÁ{¯ê1Ê`!v$X'Ôĉü<úAÛÞË$§ÇxŠ2¹¤(­KQU3›¤æPd¬¢AÑ»uO+Óу6Ä»9]d’H.ÂèBrºµÖ» ˆGÇÓ˜}Ý=“$ÆsIk—ºµx’%‡Fñ¦¾¸O1$!¨"x7Kg–œ˜¢hìknx±ØjÔ–ÕCjÈ"ÞBôÔc cPu¤f±Ú–¥<ö0‡h‘󻜭rÓÝ8ùêï½ýBò Ãw$ˆSNíÔK-µ®ý] "ÃQ%D9;õ¥zèr ñoMàäVr™Ó"­æÞ†Slë.ÏZù—< } Uâ÷{Ì]¬÷Å¥šìˆDvaü“¡‡(1Jªø½{¢Ú ö<tóå^¶mþâh—ÇchsÌKM<$™;oÔ~Ñ`, ÿ‚žÈ‘GaÝ©Ü;ß­Ô@î$G;åßUFná èläŽç¼ hÆ„T‰f¼¯ûµ²¶t~§œ#¹ŸÑ§´È6±‹JòJ®¨‘‘ÈØ>À…ÞÃãø5v÷6Îyd\]Óú‰°5/>÷·ÆoÖ¸\£ËÉÒ=uÏ= áË6~Vùg÷%Q¿ÃîɵÿòM<ŒOúDbümP¾oqS=‡ôq¿Kü=åf5ïMo;ã·º;Î7ÃÛ²tÞQ^P/Øåkòò9ón_ÀáWŒŸ¼‚ŸÂ6| ãSî·rÎ  óú-?-œnÏ:¼ú ÚžÚ®ÿ Ö+Ø|‹ üÞW×›ïÜeÉ¥<ãªò…g ß)|’v{½¡—áÈÒŠiŽ»œ‰ÊmhÛXÎÛ.Øuæ.Û—i·}Ø3žX¯…¨Dvzy“WåÓsN±\ŪºKBTzçT© °¸R'dÆwøh_CL*5-û.œ ƒ¡=`!òBøaæÓÎÕ‘Ooç~¾„iÑÉsˆ0¿ôãÆk²á¦¥ý0ÜJ" ÿD¸k¬WdžîÝ`´Îä iwÖor+"H-N­e§Ç›~ÿ0È©ÖëÞo‚¥xºñû}ø}c£í²ö!ö\ÕJ*æ‡,ÇK Ù<Í1–Ÿ»·œkîÓ Xð%z Æð>½ÕVzS{8õ~/«½¬e\Ï K—½%›L+æ˜m:õQLÓc;×ΤAqO­=™‹µ<š õH ÍÔ‚Í´PfÄi“DQ73ƒØ ‚iÏ&1ãÕ ÁΤ©ä¿³‹Q]̳¸hŸ½¤Ó{O tSÌ‹WÉæn=©àÖªÓD›`¡5— ’ÔŸÒË-[¬A<!BrO-¨‘°ŽqÚ»‰Ö.ʼ«»ˆi¤öŒÄ7oűŠDŸbÌEb/ÚÓ(ò%j˜Eºy0¼K«Á]¢Ë Á£³îM÷‹~UÃ.)‰mÔe¥•Ôj\̪ÿ,ðœtF̱û™KÏ´HÏ]ì}b¯é¼µÜÚXka5Ä«·!nâ¼|•©bÁ{‘%c*)’Vÿl©¿¬ ÙR2¤7†>úìÉ4ãËÛ =”h*ÝúÒ|°†‹t‰ê£wåD;ÐÍ–C_§ç%¬L‡#)ù3±_†Ž7x…‰56Çmj»1rvÄV„ˆvèPvoˆç0`#>ÂLØ9ÿl߃1 ·o;¶ÎÎËÍú×A®É¹,—uH»XÑáCËÂ)ÖHü%¾€W\ÀêsÊ%–˜ŸoÒýÆÞdÿ<åKÂTz.ƾž¾:ÔOVys¼Ì'+‰ç_ø+VOñÞ7?+×:Ü¥‰:²ŸáI¶¿½ãÅs.¦†Vâ+üËmi«å¸Vr ®–U#é(#,BHìá¯dÿÂy-é‹/ëÇ÷ûá éNi,ðºñEåî8ƒg0Ûë�üöÛKyƒì[¡éD¸úœá’圗ô�·€±Uv¿âèaÍßn¤ŸÊA_¾}y™ž§|ö<kg~L‡iû,íÎ"Cg)pâ/O{2/Žéu­ÜïÿÉ% äˆ�uçwŸÒúŽx]rªœíN‰e¢aHX£þ€zÜljÓE®„ýLÇ;ʶv ¤3‚óTYŽÔH5Ž¿¿}ÃökÙ çÇõ•dxNÇ”¹žž5ΤH_¡çÛ“µ#ysS†ž®ä3;Lò˜[*-±qeÌdá|@©Cåî ®”ïDTö)k‚Úmoõg½<—ñ¬§ zjhgTñ‡ÂoÖ~0Æ>&OÍ)Úý—ýáÏ…à%Ö±Ï:ÜÇv&yõÞó³ÛââK‹½[Ÿ9ÝN%þ6mÛÕ.œ“W耦?S~YúÖúnâFÒ´"¤´à'““ù½Ú¥øgÝb‰’¢¸[)&着қuo¡¬ºy7ë+«¡‹¶¨¢!kïæ1š…¢I.Ñh' ë9L!eiøxè~ryެc•<¤Úã)Pš™y§I8Y˜<4¤t°RB7Sjôì®QbÈ“Kr‹&Þ… M4h@4l‘sD¦¤£¨š„îCl =}p+å“°j¤ —^+A;S‰1è0¨$ï±554drLQ%¹ikn}YZûiDÏ"d9ƸÝ›î, BŽ»8€ÿLlÓƒ‰œYY•(‰“NÉ&Æ ÞjÌdñf¢+Oc I‡a ú(!‡ž¤%o&)Cî{8÷ªÍ†_ÖLH;™®íçékõ¿ø@«Ô]³OŒÐe¥¥Ñ†.gÖs«ÚrU!XbþY?hÿM¶Ã’xwÁz˜5Áóó0‚ÝtöÆm‡ÓýËÆfJiŠ7øÇo­2Ò0ǽâw´çØ€¥ý þÈòá@/×?ML™³N�qŽüq÷O· qŸŸ3Þ'ÞÔÿ›··i‘,Íòü~ç</÷^3ó7Ëð¨¬*Ïî®ì¢U“HÁ`>Å Ðt/@Eï´Ñ|+}€nÐbŠB´F›¦qšËl‚!F‚™Ôhʪ«3#Ë"ÜÍÍìÞçíhá­ÒvÊV¶´…ñœç9ÿ—ŸgWo´@=`=óD‹HÂ2¼þ Ûåj£ž\‚Ñ]W“-¦RK›wùé!.b¸ŠÎÓ•½¼ÛÆã‡ï/Ý–›3Æ�üþÞ<ð| dú¤rDZÑgí¯Lš"Á4ƒk›(cöœ;¾÷oΡl.‡q=°üàðÀÞÈ|ÿœä:t„/¸{ó‘¥v€ò1}¼z °¾ ^‘ÎØùÍ\ÆÉ>,ž>sñ1Iñ»ô°xñ¼_ºWWw½O¡À»DÎÃi”þà ¡ÿÍéþ×ÊÝð0~ÈxªG i€Ïwú5•c«ïp=Ò1 ÞhŽxl<é½8ó›ÖF¥’#%ÝÖ²>>-wŸÆãžHk¤ÊiÁq`¢¾C¾£,F§ÿæœÿ"â• äH½dþ³Ìê‰>ãÐO±ˆo#zWj:$c:6ÿãT.‰îuô_²ÃFd¬õôŠZƒÆÓÌùŒ ÆR(î>Uܼa ›vT ½# 8œ%d­Qþ- g«²Œæ)arnWe—ÝfZÕv¨NJuLŽ8,Ú¹êœü>i,­k®2Ô¾S¾Šr³·ëMºËáŒ: øK—©u”¼é4ø½VuÇ–r“ßúzð9x™Õª�¦^MT¼ ¬ÕœçÙÖJ™¬‰yßâsRkЙՖÔkU RUÅûÖB-ˆ±@°Ø7š½¯ú]¶'“·±]×êU>§“É©ÒæäuV•ÎïŸ Æs;8ó2eÌ4¸Z¼ÈÌðH¬¶(¥¥Ü”,±x'ªÝsv´˜LÍæÕDUªII¢ê°rèë{•®³î™oÔ,—*Å4(5Ks‘*®*YTª«8Lƒhpßh­´f!—pšS>Ìõ;'YQÅê^Üûóó~\6†G?“úÂìÌ|ORCsm8SeáÃÒ3” µeuÙÊm|'â–Ž^E5V Ovy´š¶"!KŸUqõÖ…µÆ(áäíÁ•S¤Q*ÒÈe—mðuoîÓP/\ -y™jŽ'q)¸ì˙Ե—E,­<ìËű-S;¤¶8Ó´p1¶˜j¦7ä´_­¹‰ÃuŠ=&(ÔwÈ %óô€Ýl4Œ´â2mF„ÒÈ`¤ÕÆåñ.qyÅù‘¡GËœÃùœî¹Ä†¦Ñoi[äK¸Â¨¢3n†#ó»+—psëÂÍ—s"¶ìºNe5×\š¤­ííî‰ü]HŸy†˜–äƧÚ–³î§ÀèÁL6|0g&Þ7¸-üç´‹±´%í—Y´¾,ÅNø¤’Œ¢4áQ?D ¿ˆã…ðÉLCÝb_Óàõ ?ÝaÅ3óg]ùÞyCú‡ ù¬{™}Ú 1‡[âºóá¤w¿vÝÓ½Þð› ^_ýÿŒ‚ÿäÖÕóϽÁÍïˆTB yÒÝÎsmÌþ™:Áà9¿à“ÀLã¶§<{„ˆ ¥G/îû\òz1¶�úqvj´J‚GÏØò‡¸2ªgv›C½Ã×µ¹õLÔeòKžÁL-RáÔm¾Óñßy>+¼üšù5×޵`‘ªXOôœñO„‰üÀ}Jqœ Õ]ËØ)Wù=»¿KkWÒê†ø:²{1æL»Ä"≅V±‰<Á®§WÌ Äûe¸³|†ô­z ­•Š´«µ½%'+׸+©ƒÔ>97‰~KO•ýÓËáèæ°ðgG1°ÖØ\jïg\³Å®NgýS¬•p“”¬at)êÉžRñJßputrç,¹ -¹v’ùÏœü /*¡˜-^ÔK‹NUÓR¥´:µSK­¾W±àºgTBP×µjS™ÍÒzi=óÒ$1õ½3q&½Ñgd¢™ÛßÎrfœ,„Üy4¤jeª%çCË2-êäX8•RÓlYÌO‹¼4V–mAtGìºXšç®Î­Ó“juÎW)?·º¯íT¨9›Q’–SË%Ä£¸§Žæ,Ò"J³Ü b.8’¥ÚZU¯Í «x#ÔÖŠ™”fµ”6•<—:ÍV];¨¿¨%[ÖšP·¯Œµ£ÊmµµùP9s\#‹¦ ×b\ˆë°2eRj®kâÕ9¯ªšœL¦Ú©C4ˆE‘H853kÇÚªiç:q^†æj3£Å#¤æ6®ýPóà-:Iâú‹Qu¥e’ݦ¼Nµ„ºvµóÚÉ©ó¥ÕÓÉçSrßH×\]¸ºŒ>ڜʧ6¯¿)á/íò¿×ì\è$,‚föÕo¸Æ‡³pC$n°Ñä-e½)¯}»Y—m°ë»pܵtïÁ²'_2•ÛÂúHè®ïÎØ­ì>òAo³Ùóã5Ý"§ ::¥]c Tt4GÍô]bþ+Ì7Èö–íýõE=§RöæwÍ–Qgª]iWÞNqËíòzwU‚le—2º%ƒƒç·Â39Ç>®qþðsÞ\À’××|ñÀ98X\®hþWçåà/ÎÒW;Æ6IY‡jÆ;>]Ð9^Þƒoâà 2œÃ϶tp ×Â*áàôSö›È¸àƒ?âÞ–pØâ®I§uòë¹Åû’8ñEæ ÀÜóüÎ<¬—aÖÓ5”û¹l,oá¾ðO…hÔL„UÏù@ëY®`ÁÿÒóâùMá‰àæ'Ü ß1Ö�M©Ž&¤F(H‚)Ü$âWèÍmÛ®Ÿn¿ßÞ}zÓ¦m8ßÄn{G‚…ÍQÇŽ[ñk_•¿û'mû{©_r2·šð63tˆ2+A3öšÓÍf¿mIS¦Hw¸{Vg—Ç^x/·W™Å68rÇN^! N¹ ) lBö 0Ò}Nx‰4\Æg­a­«˜¡¹’擊µé­ØŽ²®9$²_.Õw²DCj~ŸçJ+„ãÎ}ËÐïõ³‰oÖÍÁv1.J=ùÌ;9X\œÅ~òÎ<zb>b‚sLàÎ(Ð5|Ú©!5XÉxÔÿ©ïœss“ÜðTm“SGšZnÕ$y9zö'M*¾hçŠ8•ÉYÑVžylÐ5¯µJIÚÄk±*¾Cµøv.%›ßOe4Ôn°®5-2›óYÞͳOË©UõÊ{å·Rû”þ¯’×Óñ‡“,â|ÉÎŽÖŽjn)"'ŸýK±S,òPÛ¾—bIù(Q‚BÍNXèºd^ˆ;s~‘Kl…fÙ¹“iQ=hS™½; „ÖY¡¯µÌ6YÉ!µÖæÄôXÒ£¥ß¶ü ¢’±ª©6¦¤m'=ÕˆnÂZÚ9nYÚ`m¨tÍyçÄY«¹åäJuJ×Uç‚5WšÔ£«ÞõQD½ *­V_»P¼Vg©ø9—‰"]pÞ;måYêr1ÊÒBñ4/n/²o¶‘6’©•ZHu}<­ ×'zßœz KÜÓvR~AÙ4ûžÜÒ¹Uh‹O¦x§Å…©÷\E~Î-ú³þ‡ø^òÖjNY<nt†\Ý:¿Ö!¸ÿúŒ»kR|KÌÃב•:¯÷qˆÃ–НØùD9ðT7m7êý³i[Ñ]c9âg<´†w8¥ƒþH|ÅÉQõú‡ùá¬{X=ßü-ÿ¶ ßækZ÷ûh׳¢ ÅÛM]l§åÃþŠ9†_¶ÌñãG¥×б™ ` ßÿ”Ÿ¯ù&ðW—¼xñ5þ†!€ÇÇ{ „ÝŒu‹Î·»÷Ž®âÃ÷™EOØÛ~HKœÃ ¦‘B/„ øchä+ÆçÅÇ~¿¼�6ßûH}xó°a;rýñùó»ñ°¾‚K6ãú£VÈðvIwçÊûü•çgðûƒ�1`ç•/:Z¥&r£/t'bÆmÉðëkòÄPñŸ‰'Üþ ö胺]+ë§m,Ø¿Ú~ÃMþ¢¥žõ"Ř“Eñ~½HëñÜRçè#òãýáZ6:ëGâÉÓÁÂðåvþr½áqu·_î¶áþ3ãœ{ÎÊ8x¢ñ]¾/•ýͦc [ÜkøœxÎqô´ô;üásìbC¢¸¯7ŽÀM”õÇÖú ™Žuo¶sïï-£lâõx>ÜʰÖ¤æ¹ì&å”quÓéýâÓMlÔ'4Ý„6ž—:¬';k¤©ª\ú :!{ì™+µÃ+(Í#φ¾tßf¨G©ÈKTUj¬^°Ôr1ri £xWºVtöz”xz¤Õ“, *&Z‹0‹œ„*åI›™ÿ.˪¥™–ÚJ©sËfÁ)*BSIº˜y"›\ªo^çN¬¸jj56K­,̦×b›\IH®ö?AfŽõOO¢õñÃÒÙKR ©åÇT‡z"`VŠ™Z<Íf yùÑ×…–Ð"CË!W7Κ ÅG±¾JÌâ'‡K¹9sdÓ{.êBÌåÁÕÖä”kÊŬ”R§™òý;kß–ÚhЬa߬DpmsæÎ:–ƒ­´v¦C±X˜kâE¬¢N%øêL"†j‘Ö¼œzMÃy&\h1Xç“ó¹é\¦\\Tû.t8Sb1LĹªt°ÚŠ…&QëX�¥frÞ”¬ÅZ§:UEZ¦¬¤¿G´Ž¦?j¥o%·¢Vµé²èâÔZh„©=ãlu?tíǼ<Ó.ÒJ±Ôösœº»•ìúÕZWkõ §n™ÔûÚOè)46³Žy fÙIã¯B\E°À¼™¿åííãv=wñ÷vÒÝKÃy𘃞|„ç3Á¥BA2ÞÑ]a~“Kièð vÓfüáã7l†VÈJß({Ûåîòë°`çoÈÛQ²À‡ò" Ø5sÅ^¡»Á- RäQôþ†aKwM_ðËcÝ"P;À#ú_ÁÑ–<8ø°šùðRѧÿ‚½B^7¥^2õ´¿§¼ñìIýÇYb_»x“.·¼ºI¯·Æ/àM…w¿½á¹Zü’õš¹ëÙyîŸ]d3üõs&îéƒô ¥Ó}³¬BÅŒ kЙÜX­Àÿðá铸‹ þÙĤüÀqq¢Ûã¾Åe¦(÷Cû×ËÕÍà·Û§7×»Wp¹³Ý ‹º±9,¦è§¸<#|·AÇ&·¾®?áÉÝõm'îÞBÁöÝÚ-ÖçCì]ºt,+Ö˜ gBo´Š:èÙÿ>öc_Ðߣÿ;ü}àB8Mä§Mùnt¯ ÜÚ—ëzª¿+ì"÷-m{çcj¿’BØ%ù¶0>Ý‚ø^Žî|cñ^ÛÔiœá»p+²^ÉÅòú'Cõ’ ¹êüÒþÝÎo‹|j›ÄSàqéd±*Ôt‡¼Åu´Šœ£Ì3 )>7ÚŽZÐwèå¦Õ«oɉÔ\%YJ§ÎW¥„¹wOøYÔ¤öGikÊä 9Fç¶w¤Ö²¥¥¹3¯f67µæ¬P«׋†ª4oÕBQeЉ^§¥ªªZ-ÙB­5Q]ì³² ¹VCÙÕ°‹íià¦_FÙ49S]–º²§Î*E¥Jr›‹Í&óA#~Qæ(û ‡NÎv44%¬f)E‡*}’Î;'æ²s+Ú¬•XO–‚39˜ëò0!®„Þyç$ieJeªùØÒ„{T·¯í¹à¸«’4 šˆYÚ(ò§½Óèû>,½,fq-ØDSg•êÄI •ð°Ò´–XkWð¾ïú 8ïcT4t®ó½6_Ô«&uÞ÷ÚGß©—ªÁ¬Y3EŒÚÈ…êj…FM´ôXRÓ]ÐÔ„R‚om¶ƒ¨ŠWü¿$ÑÞaï~U–‡Z>©³–½¹˜4y9Õ·ÙËù-uwæY‰Ã\aoޱA�� �IDATayŸ"ƒ;†Áùâ†Øœ–¦hsCÃ%]å4ŒÇ¹{¾Qî>ái.՜ѱëhÛõ’u%IòwÛ¦÷ãp‰[z ThGX&É'bÅ÷¨glj;NzÛ–·ûʯíšPFæ»ÄéifùòPmAì #°ÝTÆçs³�ØyÁn†/qÄD€èXx~*üÍÀë5¯·üñÄ@ÈøPnÐ@ñ¨à=>àoÐ-ìH[®n[T˜á»’vƒmi_Žåw”ƒ¾È¼³åWo;~ÉG8Âôñpwà?~qб›·|Aøf›a÷ì\zxŸy=ýNfì;Ö‘8žG™@¾ _ñ…çÍób«ÂÌ›%/‡*þ­nN6Ö„îY¿£Ëi‹»¡nQ˜oHkþÆAÏV q®t{º_£o?Âã~Êj=ºáN?sñ¤—×ÊCÏ×oyøÅë« 2Þ* µŽsº+S*$IÚg“1 ÕÖÅÖ'‰}—H$7梛èCó±“89­›ïòèÞ;ôœ rÈ=ÿGàUšò" z;—u{ º»óìäfMXÛb¡gG”tE½Fÿhç]bŸ…]ǘ=±g‚îÝJ¿n}¨î.ÕåûSã)1³vmý…/õÖ+5MNnÐõ/wøD¤–´•¼ ñ‰~N7žQ#ò U©‚6žyd8hÏJ;ð/6Zþy!¥\eî«H8BN*'wÎt^Z¡›3ö€Z½('+ùBãúëÚî[Þ´ÃHüLºæ$/¥h.¬fZ£óBreÖ0é¢'®|èµZ׎:ªªIFZ¬LÚbD-¹ºG¿U½#*8‚§ÕñI_[”DvÑŽa¦Ö.;­ÁOÃ\ÛHBçü‰°wr2­*ç¡:ÍÍd®®›BŸ+Ég…§4O!‰Y§nhΕ¾š„ÔEsT¬8+–›‰ è`m]ÓŸŠý2—Žèƒ†ŒÇãª.†Î‹9ßLO"ê Á¬Ö,-™‰°p.tÏzµYsM3®2TªS/ËNœo¼‹¡smÒ$“Ïâê5JšEÍÞJh•Òž|&§‰’ò´±2V#LiaWÀJHýŒXjÃÒ…¯÷u‰4ÜLâ¾EJÝÔ‹—e¹&ÄäRïgòA¿ õUn®•¾ÈB[C ñJ$œÉ2Çà ü¾xŸ$á$¤’œí£ËÕí²çØówsL*»¹‚³åIwç0oAŸí쟻p´3ó/Û¼sݽk˜R•À:L˜a†Ã }Mü’V0в“Œmƒá3¿ž(úÀ'Оv¢Ø1ô¯½C] *©‘1C¹¡m©4T¦ŽƒƒÀ;áû°ú ù=Ú9xžžå`𛯹„óζ,žã-ó5¥0C+h&FäK$ ל=°úXÄt„G¸þœá°?b¾F†SæSèÈÆîïùïáìcvås;<S8¹ °9»¿¿exv.y(|ñîw16o/ˆ‰lìfLKæƒá‹À›·°àÕŠ•Ò`Žû[Kkw Í»Þß÷„-e‹}Îü)Ç%ïÎxÕqéè<3´LQrGÛ~øÄ5a}†«ÖÔŽr>ñ¼¹ ¬6_¸ñMD=ëF³]›HsÐ9×¼kž*›œCK1®¢y¦f¿ylã'uSÃØÎÇfw]L”4ûþiŒžÅô¨ÇŒ)òØó¦Ã.+“ Š*ëi^?åè¶IØFýñÅÐÅØu¶Íƒß÷Å6ŸzÎÜ*Ìt œ­ˆýÚku‹¤Ç9S•Câ±l¨gƒ_HŠ–cub-Ì>MýU³ý0o4ïD˜» 1Ǹ<h‡Ð\j>ûóQ#걆’°‚©‰˜Ñdê;Zõש¾H‰2Y,Ns åÑ}ŠjÑiZÔÎ dñi¥í\¦¥}×åªí/ÌÑÊÆNc›ÿDëÂ\gÁ™ÏEÍžÃIR+ª–=ÎY²ïVÍ/v*ÕŸÌNÕJKZLN5¤(‰J˵îÕÁ‡¦F„EëÍ?Š?s±æ…oIk£óÍgG˜ªŽµ&¢wåPý/Eï ª¨KÍ.›tÝc^2’ÐÞ¤Uš×¤z ¢¾.=Á¹`êfuP³äæ´ŠªU´Ì¡Ö®µ&ÍKQ‘_·™’‹Ê/šûï¼ÿ…ògbרÒ9mæf*ލÅ–M+)OÇ–kq¾‰÷Þg&Ö¼˜x'ƒ›3%D Áœ '*N¼˜om˜½žª+ÎÀœhõÖ¢£ÍÖê¢Õ}µ”æÌn,¸¤.©F‘û©p²M±•[Ú]Öæo³Ü·@X2/žWü£Ømê)1Ÿ±\y…º±\S¸«å$!´({•ÙwÝùJÕeë¿™ÜznaN¹œvV Ë‘€Eªàž»È i÷+ã<m:cÁÀasg-•k¿äqÕn.!Tºw$8Þg*¬ ,HG,ðpêâÞQ.ßë…MÅO¬„˯ï†Ïwúò^Þmø|äëÛÆ: ¹±+Ÿ3_p ooi™Xcçx¯�!o螨 \ÚÇõÓ ¯·06ÿ9„gQe:–‘êrEõ8a¸bù„¿Æ?0Í@wA¼F`^SWÔî^…ÀfcyEyÍskÔ¬>jã$þk“|N¼ûÀò<!âà|ù»˜ #ܽ'iEŽŸ\ ¹-œg^ly¹\+N°‰·ûõ_¿]ÿ·Äómr7„-3ØG…çt­ù÷+^ü̱V¢‘dŽ‚6 Óþ1ËÈE·¶(µYn­[§îðO—¹‹c»â³Ž‰˜IñÞ®8úMžÆÓ‰o]gîÖ]Š•äÓŽü]ño¸{åÃMWuWÛŽŠ?\Ôï\}ˆ-Ý-¯w¶¾×­‘+ÓL2ÞGPŠã[O¤busháaŽïkìÀ¾..äÌ-–¾‹U¼SûÛoY¿·à%k½÷®b'Ü@XlÂò"Æ‹æb"<J=úÍ;ñ—å‡"½©´Swê’ÏÎâpôÓA?=³Òïÿe—Ѽñn¤Üvy]8ël/ºs üïÑ dÆÍÔ3>qì t‚F=C;²¿o|ÖÚ²ÃÕ“£ävulkËo5þh{—Ï";ÇgN^øù\5?æ?Chs²éÏžæƒ.ZmMºÚü¥ÉPgp4ê”™›©HÑbÔÖ¦2íçIjé~¯j÷‡O‰äO«]˜½ÄíÔßKF§îò•#Z—4Ì^›_t“t–{=úجõÕڻì­JV:Ñ»\Åê7ÎðÍ_U§YPK™’ÍKËb¡Óæô¤vrZ½öž ­¯âBsÍð‚J“ØšHmâ)Áæh5{3«¨ítÍÚé¿*‚è¿Pß›ôÊ¢š)‚"ÕµÔ…>jQbsmÎõ˜Jfi½Óê}ÞEñÁy{óBð;íÑ!"MPÔ)j¡Ypâ¬Ø\r-ŨVMŠ5­YÛÞOCŸŽº«q'ËÖñù¶Y„CÃ23#9­UÎñÒB*PE P+sà :¹oñ›¬~åÖ⃻ñ–½.ïgÝÕ;…4{ô×¢¬] CÍù´Ë‡û\¨²™Æ3Á?›rmĉ ¥êÆòØ&â#Ñý@Ê´ó‚ÇÄé¥ÓƒÊ4óô\ÚÔ2fÏT8í9»b¹@„SäaÅöšï GxýÜ]:ž¶wO¬31ݤåqAôh2÷…MfTÈ<¾¤õƒåí-ùã!U ÿ&óù–õ–ö%Yèà‹Â3Ýáï?§çýçÔOIK*¤LýøD ˆgŠÌßÁ€g»ê+†„%µGUš" i#žÇ׌RçÐÁâãìy‚÷ð <Á?yn¿ ]‘<Sá ´Ðƒ/¸ÃïHoؽ__°[_°¸"v\A?³x‡>pë¯9@|Il$¿é†ðÏ~Ïs¼Z^‡ÊF'à†nÉ)ðýHñtB4…!S&ê„dÒÿfñrçP}œ×ÒÒNÝò$q§uLB’#4†Hl¨§ê[þ·-¯¾Ü± ë‚’ß—Ý›º¦[¿îãeLK¥–_”'ÊéçõíP¶C}åêšnI6“9sò|3|0¿iüQ%RÁlLùîñ»ô¯^ó3’»ðù§óÅ`®(Õ—šÚ&¤õgÓúG5:KÙˆO›ùÝ(à""£÷?‰Þ^¨¢Îš_ø/Û™OÑ…’üÑRmÑ/³úG¿úºOÛ•ßóò‰0Œšˆ'¤PQtp¶Äa†>áúWÔ/Y\SÊFâ(O´Ú)=Åo*É烜œ<µ¼˜›j«][`!·lV)a§ú!'ï¼ó/\ª˜ä¢ùÔÒоñ²Ü•GUCn]–PƒÌQR‚å8%ìT©ÐW³ä­>ƒÛçºJþoÓ´<¥î¬Äé]á{:Å–¢[ 'BuhÛ°¿²ýZ—ÚìÓö»®¼è’ˆ‚öx/¥ÆB˾–A}4I…] ¿¨ö§%z¼UñNl°Iê©r^«i¾æ(“”·ÎVŽ‚šÞTÍ9úR /е‚•¦‰^qŠ”28¹Pç[êJòenOUñòA[,¦”çN%íðCˆN}­ƒ˜¤òÀÞYªN[Œtâcð.D±Ž…à Q½ÇIi­ÕjÖs¢^-x§]mÅjI”V…ÖªI«ÚOÑfü)ô;¹DX…ÐÍwâv¾ÜÌíÈyÞhyáʵM«vtµžê°/m#Óè0ÔQ  5ƒÞIýTý@ln58G¨÷G˜vÏÈ5†y£¯Gù’±„1.÷àiKÌøÌêx+~]}HíNó®K÷a‹^PMI‘Ö[˜£Í\«-¿#ýÝ>û¯Æz³ÉÛñxCÜrþS– <Š+ÂKrϬè|I ›ÓuxK|OüÉ’i®Ûسá' ¯¨¯‰ŒÊ p=¶ÀA‚t$Ž„W,Ÿžòf~<B| Áx“?>¸Õ”k;þ­òOÌ/qãF®)e| `¨àï©éH‡´"&úBkèý[ü¯pÊÇ…ÕGQú¹mî3Ho°ÀiàIxnu itÿð;š ÷‹QÆî†PO€!±8ß ôkÒ×pƒ]óÕÝå"uÐÍÉ™ËÃØ@/6§0†LðXf5qóüJšfb†·‘gø¬ÀíFÇ]«I=)ø“çÏ­ Ô r,¤†+|Âíª­¡å»ývwÅý«^‡ûWžï³ii¼<n^•ðZâOCì<"¡µM3æR,Fû2ÓpüÏgŠ—»Â®éýº14.CaÄ eCÙ]ÁÏz“waWüÚ:wîRŽVü‘Õ8Ä奄¦}ûöLV/ób—ÃýBÿÄždZ„Ú¹ísÕ³ÈJ¼æ8=jÕøXm­JÅ5'SÃÏ,~ïìOæü—ÁÈÓg)¿¬ô%¶¬Õ£«ûv¢zZÃøÀjÃm¶µi˜Ú]×íæëûy Fa\Ö;ä0›šwiñçêÑ€÷w}s”ì«{‘í²Ÿ;«^–ÔE©}Í͹¹u®JH׃›ƒ3õ"ô¡ÅR½Š=Òf)±Ô\Òp<i&¸8Å–""ºoœf³w.Æ–†!÷kÁ¦¡äU;úâbí¬Ôªõç>/h䣷¦Oͽõ çÞÄ— Ö¥ª©v¾NEæHˆAh¦¶9¡M>U9§…U­É ’HFhÙ´D®½ÃþÏÆO«ÎÁG ƒÊJ[p¢f•šÑškkU 笠!J‹ƒ+bg’|K¡7e'æ's*!šS¿rËà\ðÞ;_|?·Nã’ª%ùà%,4vw®߉ó₈ÕÚ¬XkVK-VUœ3¡µ&4sÙÈ”¬f8«*¶2ßJ¬µÍU±õB£^$o¸ŠÀY¹­¶ÎSðåL÷«úäDöä9;ˆ _¾aB~¶Ñ„M"x :ÌcòÃ:Ñfݘ¾ÅC]¢Âø"Ô€ÏÈvÁ|IKxàˆ~·Ž~}¼ˆGIbøFŸà+ê Ó–ôåféCî£3uͬM*ÓrÞç*p—¶¡q—·»xsïʇîk³Í’ñxÁÔSñÈðÌö)w+Ò{øß}úIÌ'ÆO^p+�ýÿ€ÿÝb7ôÆ¢@ÃÝ ¯qÜÆ›õ° Gî»÷Ý×ÌÐnþ_/†çxZñú=üaÁÃmç>«›ÅãL{÷£ùô«W«ûyà˜YÄ#7ø j‡ -‘'¨P0Où[ÒWü¾€\=7îB »ƒ©=Ót"yÅ£# '!îñ_Á qûÿµ)ý§íaßÀ‹-é_9|ð˜>[¬ôøÌïèˆ.XðMvÆmd}¼ ~qWÝŽ|ï2—'xÂWbî>1m1 >ßþ†v³Kÿ%µ a‘q§…ò„õè‰Ôó+·ùIý¼Žóºÿ.¶‡d8ny}Íeá<ŒRH‡qõpw9§ÎXY—[ó|{g)]‘‡dÑÚàRìJzÎ_]æBñ…3eð·Ãr-s9;vBÙnÇ¿¾á »ý¬röýœÃqgóŽw‡Ô=M}‰:ºh/–óp•üg>,R]´JÐ9Èã¥Håàëµ›»ÔI3狼.úlj_q å}€ó¿lOôŽ.þIi‹CYÕy°ÚzGÌ?|ÞÙ@=Ò ]ÐVëÖâb×Rƒ6v=> ì´!ÁÍY» Ϧ¹[eé[ò“??}.‹CòËG#¤ìäĉxrOŽî$Ì.øØõHÙ×ê`Û•I—8ÛëêaÁo›­C~á›L®þOÕÝý:ZX ¹va9Z»ËVíƒØ‹µx×l´99onNÔR[r \/b3›L§æö-ìHë.$ià’X†-þÀÜ9¶ðM45OIòéÚTšW«ê›ýÄ!E{kT‰ÑB½f“”¬$Z–RÕ¬Q‚EÁZ/V\x¥âî}kír ÑD¼<.xç‚hÀ æ3KôµYZ.´�NCp!ª÷ªÎ‰´gX„¥’O55×Ôg§ sµÒL¬zªZi5VUé<Åš05»È1Ÿ¼U&ÔÊÆéOë’ÖžEMN¾òåUk/k]´Ö_©iwRvÁÝ£, sá4S¦±ï~.ÖèÈ ­µh·iÇñ¢Á§Ï–M&hÏÛ¯17¸-Â&¿óŽýÌàÐÇ ß»ˆ%Æ“GJм‰Û1òA€„ñ‰;™“¤&µ]Òo[åêéåó¾9“-W×´r[kJÀ߉튻?:Ú‚YYU–†”]œ¸ôá¯%¯Ù½œy".ð»ä¢|ˆ ð-y‡N˜'†LÚ¢7´íZ·k#FÒ¾{¶Y°åá7Ï‘¯¾Ørþ¼Øqt=¹ç2±uìÖ²X–™w_õ¼:¼ö¼vü1”‰sˆ ZO0a'ä-ÝW¤W”×Tx„ò±"ÃÇ2áÞÃøƒgÐ)„ÿ`\fÒ€ßþ½^þ»íè~<p€U fäჀ¾‡ÜÃÏ`¹%^ã¸÷í6»µk[.3_Ä|–ÔCc˜èœ¿G¿%'úíµÁÎþÁ–-s¿?Òm‚Ež Å´Lk$¹ýÍiý¦†ÏÊÏó>Zíu”бY1þsð°*ôð.í–_!¯Bïò>잔շĴs£ˆo5¶ÃÐûØgAÝÆÕq™h`Ž0à–kgkŸ£{L퉋›_ì·ÜY>Ý¿�“M-£œ¨`‹]Œ(½|Øôv­õ|!Ý©W'¸RÉ’à(Šsæìõ‘s±’3Cl6±*:gË_¸Ãëò nãíy[rÚy5ÿõI¿ïXMeÛDÅ@UUaBÕØ}E-6¸1yœ£Ú½b¿‘ÅØã©´iݤ«87ÕzØûiï«çpHZÒ!S»ÈtSqÇ)ø‡ÐwÁ-Å;ïn6;¶¥—K¤Ã_f]ä¬×” ,Á#v—m×É/BܬâW?Ь™²¥Šµ.—¡.¼Šy)Q(E$ks†•U®? n‹„jÓ¡¶·%}[ý(•Xný#Bõ¹ŠÄð¢“«à†¨Þf#©¯fÝ*ûg»êÊúe«/À7)μóÍ—„Þ$š/Y“´©†œÄQ‚GÔD}Á‡BõRBmÎV²6×[0 •jWÞ­ÅRÉ¥Õf*V¥¥ŠËEQ/ª^ƒ§M¬5kFRN*G«EÚ€X«¾jÓZ=Åùê¥b®bBC¤9 -5§SÒC’Ó¢Ö¤d‘QÓF\ÐkPŠ–MⲆO2CvAš}’JBÐç‹sEO´ÃsOѯÓjh¢MO?Ëè¢ÑG´D”‘1Ù··úùZ.‚†»»S¾ŸNÿ7qïóÙzæy~ž÷×9'"¤â¦òúúÆu¹³šê&§IHf“˜¢6.šB3½2½š¿o3Æ ³iŒ0g1p!²éE«‹êp]û¦RHŠ8缿žY„ÔU ³.k¥¥B::ß÷ý>Ï÷óe>ôp}ØÇ?ÀßúHJ?Ý÷'·äd@ØígÉR0B}=÷gòºu·mD"Üãaó´ï=«¹_Õ´‰Ò²oùµòVÁÑR Ó ‰&mÞº¾fâˆ Ü ³'´G¼Gפ-é…ôš¶Ò&€òžÑoÆ+oö!Þ†þÓzó³mº"T˜½%=Ÿ®xµgQo)Ž–õgÞíÂÙ“×é­=ûÔnÞJïÁWL÷léHó€î)>2½À'x ž÷q ܾÆûÊk&OQ •wO\Dî`‚ÁâŸ_>·¼·æbËòÂg¸óyèö¨®bÓ6k9T‡•/BvLÎ_ʦһJW)Ó·Ï{°uMÜ>ǰo˜–›qÞßÏéLïN¬ÓL± Žò*Wôá»u¼Øb‰Ý·…¤ô-áÎÌ%þF®˜ï7zÛóŽú‘ÿ¼æb{³¼b™7ž^äÚ';ZÊy4MJô>!ø–ÒR»M>Ö Äb’—°9ß;Ï¢°Çþ®®-n&6þìLÿò|œ›cë'ogÞ“]µ…|,58ëÄ£Á°(NJ%£Z5NêöÆ–ì.£õ{oÝ_Èo]ø¿>v~užW󬩶ÆuªÇ"SÔ"Fx-öƒ­75Sœë‹¿žmÄ<EÓbÑ×Ì Ùo¼ôÁѼê}ÄTˆq“’O)TBÑK8γ?T1i_ÇQ¿§û—#î©øC²6™@jgÕJUѳÑÔà'‹F ñbë47Ùi«\Äjµ¢1¯D®­x§×EvêL]­’ƒ5îÄâue/6—±Vç br ϲ8g\qG(Ó®ä¾XšŒ²yøEµ­ò«<ÿ¹µgš FÈ‚ÖRÉ^Ij'ãϽï”s©mÖ ¶6Nç¬ âšlÌXªÖ$9ÕaÐ8™<‘³±*Ò¡A¬ïÔ[ã³h69¸¤jšZœŠ³à„ŒbJ±š11 ÕL“ŒcM¹V[r3UeRŠ:©ÅU µƒ­Uˆ†IM vԀ벀pJ¶6[S­ZTɦf´æÊ¤qÒá{ûdòjÆ)§KºN|Âæ^üui#J='k,Ý#Á9®š…ïdãèËÈT1 "¸`’¯w%4ØJP®]³kìÍLp…è¤3êWa~¿’åÊ^†ì¢ LP"c�v÷|‡gØîî9ÕÓ‚_ã<ÙÝaï6šúEs=—U×Å— åû˜nc&±îw·›9>¼ | ô'þ^6øþ“€áU&V˜ˆG¦©ÇÓ$fÞZ&‡Íä̘°[†“eiz¿EÞ/Áõ9_+Ñ@|Í2ýÌ÷W,÷„[ °ä«K>:ÈÜÃ÷´k‘D±¨ô%¾¶õƒÖ¤`ðõë/MÄUÄ0e8R3æˆôÏ^K„ÔFÑÅK Záó?mF€· mqWŒ™éaËÒKÀûOÓíó‰gßíT÷O+á~|º¬Ý›ôÎïl|øÛ¶§[h8Fi£³)J &PO\3æK¬']a÷È-•²\åK?¸ë?èî‡ã …T!2 Â]ØDü§X‡[x3|µŒþqv•Ü~Wo±k‚§uÏCËÒàðDèz³„3ÿŠÖül¢¹ë——vZ0Wþ¡¦ƒÝ8K,ŸÉB”þA®g&6`‰©IºìÍk–-s%<áGÊGʆäHàr?º?+¤W÷¦,J—<7 e4¹”r—‡™±^;‹ŠA(J±EçS¦>¥\gSò3W9þ¨êÂra7¯Ô/l˜—`cö³û’mÉ¢“Z3­N¥VuÜÔØÇ€‚/»Xñoþt·«W¸ùãWo¸nÍÎ77ƃ#Y"}™®k€‹Ñ`Ó’h¿‹ÑßæÑF¹ü<ž_<æ +Öµ'⪑d›h«QÛXgj+Áë³-“‚ñ—hJ•¢Fôç……æV'[õA‘„KÕ®˜8ÔyWNƒ5f>vM‰6&K2njªok–Æb]¤ >pXÙ¼4î_-‘Ÿ“‡à½µ9©Pˆ9M5UL°e_`:‘&ÛP ÁÄ9qâ+†X4•:Ny|2Ó(cL&G—¥NEˆ5¶©.˜Ö¯V³©ÑŒ–ì*ÎF묩^j1ùXÅ9©x.Nz|2ÉIÙ¦ )΢£-cW‚&Õ*b³1#f›EÄ[_Š“b´äZ $d´u²ZEl­F´hÎ%¹<Ç?ñ×ã±y˜¹@4YOö‚¤ x¯š(;£YJ¯ãuµv²ÜILšf¦ŸgRfʸB¦Œ7ãÄãìçÿ/Ýmg°3afÁ Š›°™É¡g¨Cu#ç¾– 6Œ3ñŸÙüÚõo\ø›û5Ÿ¶¶ý©f€ö”êÚb¯p™W0æþ‰MHÞç­š4¦å¸xóøÍr÷Çü¨O\§yOÞǻߥ<ôÌ9µùÜ'€æLßr«5+8û!â@øœ©#gG¦=òöKZÏü ¿'¬:Jà‚Ýäñk?-—»X:Úü�� �IDATà˜ççCpYã=Õñ6ð >z>®ù_¿çü|Ó ½ƒQ`Üéãò1÷fØæOWü4ó,3.¡{â’'OI˜= 8(МƫðçðÃ$Ò©¡ùïß´ÿÈ?Ý£0y¾H\í™ñvYó§Ò†ÿ©xawó’„«ôÇ×;âý¶ñ»õtññм÷‹YêtgRÈcfL [Žï±—´ŽyF!Á¸^áWGAÿn`:` õÀ<´8ú¯šâý–ÄËýÇ«_¼eó*÷_‚@Ü2»"åMõ½±§Ç+h‹,0¡á'p?2"ü³ˆÛÞ(ï7C×ï"3¸ GZ¨1ïÆB^îRÝ[º¡€Š¾GêHhøíÛî÷’wqñ± ÉÞTòq’c—0Úëí©­Ž®h7óô¢Vƒta2RâÅmŒíƒ»D§˜.ªìfD7~ÑØ¹ÙsÔe­?ŸL>|—;ãnDoR">näc?[ gw«Æ¬&BtQõÙ8ŽJÑ ¦÷~g2¢>{—C8†.ù ¸cEœÆm­WÉ¢í^‹uÙÔèmk­†b´Ò„6i §b³ºcJ¹Ö2Y«Å…¢¶”4•Æç )¡fË‘„¹+Í×¥qÅÌrÕClÅ4-ɈǔV5JÕ‚LOM'˜àTÆQ̯†ŠVK]»ÌÎZKá1’Î5›±XUm޹¤ê°AÕŠŠ­V‹žÌîZEŒŠ)hr’NSzziðFªµÖ öÑÙ€Šj[+Ö[‡'Ù‰Cƒ0ŠUuSu…"5Úú$à$MË0•H*þ1¹Zm“ÐAm‡ŒæÜZ§Ægç£øl¬x錸*¶ŠV)¢Ik42Š$¤Tñ_¤æ:¥q<Nwq;7)û‡Yx:3Ó<Øî,äæ¾N7UHÓ¦ØÞŠÂ¥îbÇcðw.y»›M䈛Å`çømÚ\ìóŸ×»N<SðƒÛée¤NhEf˜¥!ÑËp}4Qs| ÝÇÈy¦K|µåÇôÛÿ/z ý¶{Z˜{B¢¡ïšëÆGß’$âv­ÿ~ñº_θpü>ðÄŽˆÉ~$Mßîž‘> °|¼Ý?S¬¿Þò4W©G{¤öÏ£ÝÝ’x‰sLÐ@ù½B3È7³Ä´Ú¬|pÔ€xô‰´†-zÅ"ãxo?ܲZã¿äšvçý Où°ÿ£ôî¿ex» ›Ö÷'Þó©¿úñâ»oY¿`3ìi¦ Í ¥#xÐÓÌ™ç&Ñó—‚µûÓ'¾ørMØ>³4ü ®5ý µáŸ–Á¬Ãîax¢ypd÷ø<ïÓG¿ãêæ'lxì½ÒAФãŸ÷üzÍ[Ϲìç°Þ·^®æ»ÜýgÊÛ\óÝߔϿŒ·<¼CÔәݞwéí—»OŸBÿn„'šwL?Ü—Õ×wÞ=]»×»ÑÝÜ€WЦ@lùðÖ3‚y ý3Þ¤îû±£N°Ü€›‘²½™2yØÔ»~Üòð/i8TQø\õšLŒ”žøþÆ:Ž_Ê÷?®6×’ÌÞ†*õMêqL»ªÕÚèÌ¢¯“>•½ï«¿6ÑZE‰Ö%»èÏØST¼˜äÃN¸ñîÚGO¢ëÌæî<r¿Œ§;ibàqÕÿîgü–6msæc` ZÁø"›Œ;ÊÊ9?ãÚ›*ü¢Ô må:9{0>$™×Æ‹;§oçiáÒ¦II…Xüè§`5N¬kѬr•§Q\Õ\%:£!d·PçR Õ7E‹Ä,u^M—ÅŒ1I ®[&çD,Øa¸ZÆ`mGÆRÅ’r5ic-då,Ø®º6x±¦¥ÁŒÙ“3¦øÑ¹‡êL©Åb‹¹¨Xr­:‰F4Ô싚©X©¢1§CŒÂ¼ÖÊlnÑRL: ¾2mĘ*¢’Ä‘bJ5¥PíTÅ(FÕ0X›h;c¬ÑR)–R³±.g AœdL}Èñq²­ø¢­Ö¶8mQ ­hÕ2Ö2˜r¤VaT5UÛ\RRRÌSyH:Ô>ͯ˱ßÌ|lÚ"¯sü€¿‰G&úƒ#|¢äéfÚ1|¹‘¶¿2ÌaÚèÐ'¨—x÷ܜ㽿û÷‹â˹9.}òáB¯…¹Ý”Úˈ.),¸»Xœÿ¯aý‡ù__åë‹´ û›‡çSã?žˆkÌ–z{"lc¶§Wä.lÐä«K5ïæ¦qØÙf’þ?sóUC7þ©_¼£ùÈ+ËýâÅuøtËÏà.aáÔµài^æ£ÀaÍ÷ž_ÏøY«ÄwÔ=åÔä°ä¾,èÞb] êž�ž÷YWY}u”è^ã+&õÍþº®yŽÄÿp›¾¡—5²Å¬1ï±—xOþ+þîŽî[œ½ˆe§dÂé÷3Âîa —ÐÁðwðËÓ©nËŒçÏ%ÿDþdÚpÿ¤—hþrcyöò¸ù,7\ö8Þf~sìúDì>æ~ ðéŠW/j,‰¸íŸ¸6{¾Ã|ô†Ô~³7û-³7ß=ÕqÇ–,ßo~vÙ× ¾™ñð1€lÞúOµ"¯þ2†¢LÄwò,_!+Sæ§žóÊ\¨óM\÷l)nI·Ì×tžW)àî‘0Ç8âß÷Ã-<Eb¥©ø�+‹7\vpsZ‰ëö7î9O›´ïµÙhÛ° ™¨áÆø/g:Y3ùª®þXWYLïZŠìäH)¾”ó.ý bKÐc6Öô8œ qW£ø²Zx;«¡ÅÙ.ÄǦ6ýXþ…ÇòÁ—•ÓVÆÖ¥šXkªÚG®'V‰ùLFáZí®Xp;k»!ÛË´hÆÙ|çéÞÛG;E‘¨zH¥To°Þ+bzê¡®2U£-øGgLÇdŠ­ÚT/ÎoÜA$–z6«­To«oÈP­.Sª‰YÜhº± NZu‹š—FKN¶j ©8ӟˇ–3›ðŹàª5E¤†,¹Š+â’qj܃Ö=³u&ÕR²-­ÅÐZ¤f7P§”ãà¤Î»Æ·3fb¼b‚afrÕÜešêÛ,.™*ÆMjRÑ”SdD'Cñ*¹jªî8̓¢Aº .d/Ѥb‘,çÁtkJÊã5 ‡ÔÎiJ Eœ;3¦‚*P*éɤ‰\E’kM¹>Æ<ŸFœ8<ÈtS{fÝÆ²«çœcÕ·Á·Ñ®41d 7ÄÀÜâ2úÈÔL¿€óü¡I+#¾4ׄZý/‹ lJìµÃ<á?c->0Ιø0˜Õ½uçËWNy”nž V7ÿÆþY÷÷]³=sk5[šéåPÁ¿Á¿¦© W˜=·´Ûg{Ýq3}Yn’ïÛDØ3[~м*G6»ÎÍîo¹y{Öã9Dþ’8{Ù1ñÎóÕš‹í³Ï ÜR×t0l^ÄiÜR×�ßY¬el˜YÜ- ó5ºFgˆÃ ¬bñ¤%·(4k~²å7lÀÿ„Pßýˆ¹õ²ÞøÐ7Ë]ñè•O%ñq÷ÌÍ{òœzAœñ`ùá%© ÿˆÁ ÁÇ—oNä¥%¬^â'-i^pß㋜žë%Nïá?6¼…%›/Nlñ5õeµ¾LÕOÀ{` ¾ç¸4ðªb »ƒÃdnNûÂkÞî©°ó4‰iÏ=äuýt;Bx÷Î^|$à…Íã²ß_rï¸D œ¦~ÖÒ¶Ô†%0«â?…Ÿ¿%|²á?äÀÄOŒÿ ´§ðvââ3÷ÊÏùFéì™­ŠøÇ¿¸W»øùæ�eKx¶çÓŸÍnä²÷2qI9­ f…¤Ø²:¤•Hhr¨n‹B ‹5ݶ—5ÝЛ#N©Ã¦¤^ 5öb_Ûêóºõ*™Ð»uh¾I0î6és÷c¦#:|îƒGê‰Ôx39öã^¯š…ǻʪ%ŽéØõÕ@Këi-˜UæLgј©ŽS¬ì‚n2¨Ý€)µ“d2ŒöƒÊʪ[Wï§f¶·aÜZÌ^ÍrnËdó®:+S“†TüPƒ5¾-…œ]õ~2dRsP1®¤¦ZñØÉ­tb¬SÕÚÚÌRÈéÌI+Æ"TSK[3UMöµfÑ£vÿEÅÙfeùÚ$K1©”aTÛ Înº²š7!àͤªZÅLâ3g„¶RJ(âjq?FÀ\å¼pX²’SЃDjÔ8ϤÉ6‡ì1ͬeî¥éÄ5j¼ªXQ'Fª±Fl6FÅÄbjU#Y©±æeJö1×U“)©’s±¥ª¯ŸŒPµ:ñÖ9µ¡(9'¦2MCªs’>æ¶-­«ÎMΜ1Æ”D±ª F©¥~ŸÒç8½LJöøDž¢mí«Ð¥M®ge²Å†\ÃX½ÔÍxß.‹€P|&XZG#´neuUtž²“þo•Hc¼Ö¡’¢Ù&ËÔ”Xê×™n <ŒñhºÕ‘/ªÅfœpf>töë….›Õ™n†¨ï«™ÿ»ú¥ßn!¾Áþ˜vÁBhGF6…þî¥À€½EéͶ87+X‰"‘†w7žeK× ™GÖg/þ"ÑmùoÀˆú}žP1½%ƒ¼¡.y˜ƒá£Bå+ðžºæ<`^Ã’Ü’…”pQœ§®1[Ž<\ÿíºçê:]Æ…'¿ŠÃ]j¾íå=íå™áØÈÔÿä=O{¦p\!s’gï¸Ao^VWy1ÙôÅJ:í­~‚/„ ÷’up/K@'ïèå ³%GO¸‚=åöO£ >±úWøðæº[îÄß”+âžrû¼{ÿõŸ®[%.òfE21±Ûs¿ä+OM˜=ïÞÀ’µç<‘ö ‘‡-7oà=ø_ò£ë·˜‹,«÷1ìSŒ}ôüÚÁï*+G™ã m&´t‚QF»ú7²Z¹PÛØ¯\¬°Kñ79‘û“Y¸Ï|Õ07Ìøveü—ÙH ñþœéÿ�÷?â_ÿw ï(?LëÞ·îZÂN¹©}Çå¼#XLÙŒêk ù)4Þ{—6fßÿ71ï¶Ø5³-íÎ}0y‡3u¯§§õ7UwJë™’ßù9&Ф  Ã×ýø6ÐE¬â˜™c�‡QÔ3\ÐXÁOÕå"ãXLõëh,ÎojãºlC„ÃèšRá&8ÜtMÔ»,»ì›Œ}šUYÚW]Cç LÁÞkù{™–˜¹äƒ‹±ë¼óîB¬× å)eÆII¸Z¥VQÍŸ'sf3´Ô,z,Fgƒ)­±âJëêÑVšâ«ux5ç,£‹£›J)•Dm™†žöÚÖ/½w®*¤œs˜ÑF 4xŸð%ªäb½Åf‘\ÕGE´ÉU³´©Ì]nêdímKÆ h­eR†jæÑÌ´ ÉÚhlãBtVÁÈ„ÄSÈ×”j5—*QÉT,µšœœ¦¦LÙjÄ£¥(úäÅ4jlu¢J-h4Q#ø*R ”šrÒÊhœªŽS8=ŸsGㆮ¥ñÞ[ÑV ªZ4–*Q픞†éééøÍÃÃìn`²Ç®î¼�¨@~´xF¢‹©¦cés ŠuŒ™P_i¦ÁºŸL˜´{Â'F1šsõ`Ç”d‰æ–1,›²šÐM³ôØ™}X½þ¹ñ¿mò\b¡“•/]x‰šúÕU[½‘ Ú½ÅÂá5Ó;g·†Uðþi}½Ûî*7'pPYÓlQ¨lò­Ï„ø.¤œù¯Ìfnû¥#84B¡f^E>L, Ëæ¤@,@NˆZòÉß_Ò]qñ!»xq‰f‹Û 3bKq$8fÄÐV Ì2.!Ûgç'¼ár‰÷ðz—fxë‰ib'küK‘Ú>z~#ü´!Ì™f¨çÁñ·'.S„ÄÍG^Á¸;è¤ §LC}Áµž–}OÆTó" Ïw 5aËÙ’rIuóóýO¢ «·¬ A–‘KŒ£f* ^ (^Á»7|\‚ÿð֭Ϋ÷×!íØß4·|Ý;ÂGâ®X\ò•£Ë(<}ËÓéuÉ;ÇEØÃ"z›“°ã[?âm`U1kX)Õà,vÄU\Ý8ë!üY £àQåñK“þUÙM‰®ÐŽ´¥bÇß®Œ,ÄÛh‡‡ðøy¾¹IýÛ†¡%ÿ˜ä‘W«z·r)L9ZÈ™bÀòÃKòŒÆPk_òõ£1³øç$·í+ä7”%ö ÷´™pE�{÷䕺NÇ‹ÜÎóHð7ZÉf#¦×‡vƒé „�…8&ÀÓ˜(#õ‰4 -ÙC`.=\ëtМrR}ü,û_êr¤OJUjèóóÁÖGËCæ·±þÏ6û° ¦vL l'u÷ß¿·¯»`Ž] Ø%=Žãt\äÖ{ó¥.T§¶=ëŠÅõ ꘳ˆ«´4UœVl2[%gžtzˆ%ŠoŒY4ÁŠ §²Úƨ‘ŒZS£ÏS’yŠ—4‰‰±ýk’VJUc&ÉÙKR7ygÔ»¢)WÄXS]ñ&ù::¦ê‹Ú’+b’)šG¼&O2îIÝSÁ¤Žø'*ZR¦‰­¨•¨V°AÌPSNF,PG#Iª3Ù"G+I4 dÑÉžþ]Eˆ•RmÉ”£US³je-U²Ú¬Hç•\«¦<Õü˜k6vž³+•" µ³ÅšPm›å|ÐæBŒT•’%WIʘgCZ¦_ì3÷fó z͸üÁè*W/š2•ÚìFÙ9˜Ö*ʉÙa@<êû˜®Ó¤Câ³IM'jµæhKMeámžÊûÅ‹OZvNVvŠLÝU±Üvî6Î7+E0óM±^SÀºúeÕ zÎ0ÁkÜ0õݱ‚œ^y+£+1A¶±fo˜-qgLdòӾϷיøøD}¿‘ôeíg• Ø …6nÎŽý*±ûÝÇç×èå5Ó‚Ëù³¥a<Úv…{…™seø�‹^ÌxÐ iIi)žC" O/4•ù„»ƒý‰ŒÂù’zI]@wãZC/»Â¤Ó†Õ‚á4Ž`ŸG5ñ“ÈoŽ0À¬¹Ý>»Cþ…QÀ@ÝšŸm Þ0.±žzEÝ#·˜Þ°_Ræ´kæÆ!Oz÷'І øO„WëÐz¼ó6‰þÞó‡5lé ;¥òNï÷Ùê‚U3…ÖDöÄ[º7 KÂá¯@87\4t0ƒê)kÎO`WÇÅŒ¯ÜM[n#Çþà‰ëçÂê+XÂ,á1äB=P©mošëYñØE÷mþ…e³¨ý”IG¬eÑbbÈ  ´9øhˆÂ“¤=O‰WKfŽì6)û@ð0g^Üfš÷á ×` ZÉJ4»½òë…ÿYHóÛÝéÊx\’®(ó@wùöÂn.肞5gm­uSK/†Úôê>ØfU½7ævÆÜð†Æñ¥g4¨žzäqO3qXVGµ(w9q8zù.Ù½èíµ[{>_sµ«ë›è‰á·ÑvàÌ7í`SÛ‹È«›®y•žÌ‚P)Ý÷C7snˆã>N»³:ÎæÿwX~P·2úMg­ ›mL)ÍÃ̶bU$“9-Vš9¡Z/Y‹–hãSò¥¸¹ÆŒ‘EPÑê*±dÃÑ–G‡–BV‰Y“%íõh"2ä2XcŒ15¸¦ðµæßÆüMÖ¶ª)V¢#I+–hë$PR2ÙÔ:¥qÔÙ>•Ç£wþ‹ÏÒu‚-“›:hšH9LVÝSdÈÙŒm³uÑYëk'EE+VŒUÑh¡ˆˆµ£øQmñÁX#E ö(2åZFõUM,z¯2%§O. V‹¶IuÈ#š&“ƒ±UŠÌ(ø\d¨zòXÍù ÞW•T4¥4%=’÷ÙßÇÍçÔÿGåµï/ ’p¬´®JMñÎâœZY-äp'¬^ÄLˆŠ…⨖¬4"“¦±T-±Æ‚±U}¥Q'ÉŸý²<qø~£®O`㇮vþìÇÄÌ÷¾þ`“BŸéÇö:iœìcXxç­u£%R¦æNo W˜‘ÀÆ©¯O!\â;6˾½„3¬cÌdwbZì*ŒKï}ú²îf#mB”\?˜´*ƒ×»ëó´k÷7§3õéæqp4ºÓÜÆà¶”+Úæ¹»×DºÂüùGÌ{¦Ó‚#ûÚ°›øxùjÀF·4kÊvcÖ}ñG6àP!h !!‘7(ˆRðÇÌt ÖçΟE‚?}âþ‰Kø!¯ 0íXlŸüì’Îs¼Bö<-ÑKÄQ3æå†qø+¬gž0 Ò3°6%ìŸ@z¸†h¶ä«ø”“¡Ÿ2w‰Ãöt€5ç­Û\4þ+–>8A'oØ<-{{‰œ1“ ,#5SeK‚OW¼¥Î nês&%î€Ì—‘ Çü‘V1žš©™Ãòþßìjâk“ºi×FÂØW™¦#x|E iG¼Û$ïk&û:RŽ~œšúÉn G¸¯hÚÞäë)ÅË×|ÑG¿IÖõE¥šMt}ÃÍBø_ê_»å¯NhÚðtÆã%Ò2N8³üÄì3Λ…oæêÄÕJ­LGŒajVUV*ÁJl*¡"§ UA!€ÁFêœ!ð£Ò Æ<{woâ~ÿ×þÛ_É›ëó÷«Ö‡&Eßq8ð0ã.ÝXK¨__j¶%5ìj! TŠíýìõµèÌp4ì­ßY³*Æ×âyÝ»_þÚl°¯çæË…çb2Ô!ªjú\jgL3CŒÆmœÌ«â¬±šS16ìL¸oóÊ?/ìµØ(ÎJ­ˆ)ÔZÈJ¡aÔZgÉ„5;i1uW*ñ±1Nê<ˆk˜Ù¼ u^òå8S[T5bÔ„ Á{o‹Q[S¦JCN>罪è½á¿Hm}:÷n^°%–˜rå<gRQ‹jªQƒi/¦…%H4u.¥5Xgl“E‹A©M1³ƒ¸£­Æg£YöU§"{©?´øfJ¥JÅf|ðò:oCL”£è$G#¿wÙaŒ)mTk´%3þñH;éãXº2H›“¦)¥q,ă¤£¸X¯_%?K×jv¦æ1ûBHSP5ÕÕ,vÖú‚œN²˜H4Øô\þ“"TC®ŠàL¤*ñ‘î2Ÿ»Ô:±†Òòàû}8³o<~®D!1Ç4 }]p¯PvÑ`ð_˜P3 ¢›RI;M¤Ãs)ËÅ…Æ÷Ö\çïc¾¥A=i¶î[OÓQê ÇŽðD]ß�ÁoZíýD0p HnÅa÷!ÆX¶Øõ3Ž7ì— ÕÑE\‚'Ì÷„5Å“,0¼2tÆb×èzžï*µ` +¼ ¼ƒ‹Lw Êû¿½©W^ö×%íÆ|3)±Ò&šJw„;,Ô[ È»·½ó\%{v{šÅœpàrO¼…÷pÉÛŸ+ùKø—|ó÷œßâÁ.1—ÏÍóµA+‡¨ßÌÖý†9ÿuÆ×"ù‰²'UšDW8?ÿSxJoÙ}‚Нû4°Kž‡Äßî~zJd@Ü2]ýy½nml ÎGñɽëÕ3vÄÀ“c2ÜGÖGžʲçaÍw[Øóé’ojÅÌ„¹C÷¸-Ã’iŽøŒa xÆÄ°ç>°XÒt7&ÛÍ‘¾*ÝR0 ãÑ3tŽ3}>Gèç>s­ÛÑ4½ÓÇû…aþ5\sØ}<»¡ãmå“ì°¼›¼_§¦îN»¶¨Ô®p^Üu0ò**Ö{íÞí²½)gÔs´Áy€ï +\9ŒÅ,’kņdÉ¥R&b`¨›ˆÏ)àC…/uã¦^+g $sl0òl¦5—ìþžÿÓñÁa ™ð<|Hw«iòõÍϸ gWA.£xÃ&HßDTo‚¥M_{Qâ@ª%U »°Ýc–$Ó®è:Jû7G5»®¹w×ït÷•î.,Kñ^“V©ƒN~(!çÙG/¿SÚœe¨]*s âgU,8«¦™_žý²MSÎRiÆ<º<jnÔÕTŒ©Ù•‘ôûÎ]é ‡l¿o›Þƒµ72íæ¦Ç\_ÊÊIçR°yf³‰©1ÖˆumMš1δF‚¬d(¦ä4Øzצ‡RöG±O³Û¦É]÷çgm$8Ž¥ÆêóaªLe éhe0Uç©¥äî¡ÓdªÚ¬&5~n¼cr59&{4iWùI~mHÆ+©”}Q`ðÕZ™¤ÖœÜAÞü1¦`š$6gW‹piÈ¿÷iÈÙ'›ªÙ¹r1‰1Æ5¿Û¿å®ýú¡Ë\,bl‰í”¸Ú¿:s«¶§1XœÿE®GâÓÔ”?w¹“jé¯óç_±§BS1žÆâ+¶E¥Ý`¼ú ¾J–ñÕš±é,s£Š¢3r&C ”H™ÿÖ¾[ñäÓ2¥ù.väÀ\8ěɱÈ[ú&cŸ6Z{u¤ýóBŽ¿%€{GÝíêv>Ç&°ÌÃöƒ\ݘRq™0îDe¾ê[ÁZŒ’”ôýæý¸ #Á¼÷¾õ¹êËžq ¯± Äax î0·<¾áiÁ—©ÄÊ.óEbæW8Gv„¦`”.:b¡›¨wÌöÊruy\;e„C, G¾ó\8ŒCÁL¸B]3m? ¬ÂGo¸öë]»½ù ¿†Ÿ�k.·tÀš¥çgŽÚðãi‰i ¦ˆóà°RɆYæÈ‡˜W%ùÃözZïî¹9åàºÅÃ|Ë Ìû^mxÉ4ÜüàØ´·½YS·ÏK§´w˜=¯`¡»Ùk½·É,væ`уãPù ðw<}æUà°ä;ÿ|Ãâ‰ï:–•1ÒÔÏè–ÌKÐ%Ø“nÉkî·üÜ¿‡+¾rTä}U‚26Ø#xЧœ€IhÅNÙ`Þøh~ΰâ)°‹o·|Ú@sªßPÈ~sG¿N”üÌ}rºb±"ãcÁ &¨‰jIW”9]ËÌBa¬ ™ÇéÃ"¬æm¦ YÊroK_”’™r§×;b3pi¢Óäb/ò„$"%¦�� �IDAT¼A ´;áÒ&¯û7à'…ßdH«·íê“ o—ñÒ“æQuŒ2&ßô’0–ªÎ`+éÈQyH¸Ë‘M6} TBòæÞ¯þ–€ÄŸ&:ýżØXzͤ#eظû?ó®«ù,iÔ4Œä‡äxn;ûª¸Vª”ì¤õ_´úóV~K~Lã¼Tj5LÕÍÒ£¾Z›š¦Øöʤƅ&ƒq´î„`±Oõ;õ—*b«7¹Õƒ±M0ASÕTŠº89ë*UЉe:RïmýÎòŸª¿Ðú++¨gÙ¾žÍ.Œkª›k�#eæŸùíX)†* ¯Ýø äêïBÞÛ§¯íü<fk¤j”<–ú£Á4¡}Dæ’„¹f¤:#Õ¨·êÚÖ0Ž?pãÁ.%ïÅd!Õ²›âÍðÄT7³ÒŸ7Ì nÚhíëŽßK\ól7¬û·¥cÓþe¯nãðÇ1H ^êß­–Ýwx¼øüƒò#\kÛ<™gùWòíó~K�ÿšàh˜%bɦ/þºÚ˜ëbah˜ëxf[kâÒ–âÓ&M½œÍ‰Í©HŽÜÜ`ÉËÍñ²¯Žðà2BåüЇLÈ@_+š±{o™Úæßà~€Ìá‡7æG×ò»…¿•LSX•= 4S6Ó<böÏ‘¿Ç_" E(ž²ìß^‰·p±Œî2­\2±a¨ Vsæ–\¨Gò{訞ßWšÊ4r?a„°@®}6™¡ á’` R*Ýgìjeü—â»àŸBmlšŸ7S¿ò›sÛÏÀÏq¯H-ÓÕ*îW÷·áœh¶Ï¯ÄŸÀoàßnŸwUý¹ÂB7=žÞ@&½F{âd„ü¼¶c–Ìýʦմ‰xÐpŸ Ñ0[<ãÿìþŸW.à«—üžãÿ#îí^£IÏ4Ïßóù¡”¢^©\®´÷mµ·§Z³Þ“!(Daæ`lL“ÓK˜f`™ÿn–>˜ZÓ¸çh1IìIX4³ÐÛ5媷RJ™Ïç¤äöÌàÑ‘R¡Lîûyî뺯_ûâ¢Ý0¾º’n—ðÚ'>»ç#˜^¯ÕÒ¬‰¢•µÀl)¡Pè‚ë?ä„lpïèÏ^£à¹íAóIxyìFx¼§½Dl¨ÀC¿a€Ç%Á�üƒäjà.A䳈ö$‰gËAr “Dôà‘°$nÖ ì¢99£Òæ×ötCyÓ6é]»þˆ£ÅAûv¶!XJð†¤›47&Za¬‰šŽçÀ¡ÄOM 9ØVÁ<¢2ö€|Æ>×V×r"cÒ ÿMÐ%‰Ëì‘ûCy»ë®fæã?Ñè™=4’6ZÜÊ#*ÞØC-½©ÄjJwÖ§p’ø,4ÁÜZ ö.󿤝KWÈg…¢ ‚Bc!ö7A×X£íJû.‰uÚ‘Þk&¹eëe ÆŒöØÐì£ÙUöZÛºÏvl„oSn½€?Þäï>V~!ΫDìõsð³ìK1£*²A>‹$¢°Æh*éëÔw10 “´Îá+!?îËŠx&à ž•VR̳Ò9eJoRÆäFÊ6 ¢¤rˆI(샔‹(SEÎÊr$+´"!‚ ÅœEpbôû}Úý-­þ—J"ùÛ’g¡egÔT›¡gb icPÙåè ¥E­ÉÒ§Qä¡~°‘ÂöòŸFNü_¬:è²@ŒzLnŸc™S¶ì¥îMÐ1<‡½òXìD ³6™d’’”Æ­‡çl¾²I›Üýïožd=95¥X•9•þrÛ¦ï³m'6ü„öë öö‡­>!Bðnt¹Ç‹,k¸(²ño«ñ×ËÍwÓ³;k¯*§ãÃ'‚âÇÌ ÷ Ô­Q= ÷HKŸ;4*™çÑ×cgã܉ŠZ»ý^åç6Jb‰›%)1D ¸)Ž6h¶–˜sÈT`~$ž59 LÁMD ÒqJ’ŸÈ÷vá¾I´iù‚9›%ÙCáH;BEì3{ƒ[viÛ¥91>éËÈÄ~™d¡¨ â„tNöT™yŠôŽõQ ¶|f(4B’"¾öœœ…­ç4&Í„j㸵ñÓiþbâ?ͺˆ+›Œñ«RvZ­Õ‚X5¢7¿ÃJ¬Á\ÓÌhc•?DY(Hñƾ¯«l¤\!»B®³€„NôKä ÊpðØã ŠÆ,M¹±êÒºwœsEs×µ·’«=l¹ƒÏ^ƒ7ìŸÒÃzÌÑ+aöú6Ç5·áknaιÛruÿ2íP%TmäŒ2‡þ’iC<^/ktK¬AO5€†ÿêùhûâÊz„[hÿzó²'b^ý¿Ü~–·‰MàjÏÝÀ£nf²4zGRHE%É 4ýÂ9ù)Mk5ή’qµÃ,Ýxh‡-?¯ ·žÓ-Ì=à ê¼-ç+a\©Á9"…pƒ´~–Ÿ¤ŸÚL=Õ®Ò˜Ê +.îöÉ+lëKœÂå{8œÝ~géÜíYüææ¿ê·Æ²Êta·Žš“ù±Îºfn•u³Ì'vO=¶=«[÷2ÕKlwês)šR·:#FŠÄC¨û²¶r"åAJL‰ ÌÎoJY«GƒøùXí‡â1¡yh•Z ©vRÌò\ý<žlÔꢲªÒBE{íöÊK팎Ú&=IB /*…E ÖŒ{ÃÓç4¾l§Uã«ó$ûlUR,£*“.¢J:¦?Ëñß“‹,þ‚²“ùqRÕè¹4¥ÐÂ…”mHÏÒ9‚…̘=DFïSJÏã°èûý>u`6;QERDgģޯʢÓé?¤Ø˜ô†$Íh¬ö™.óñTTAÚѺ,;!þC·ÅÈVj‚Â7£ùX–Z™€ÿJŽë8üÍséKñ½L‡Ä¡òÛoFʈQÓH®D²ÎÙɬ|8Ï>xž[ë ‘<"E-ûº0Ó ¤Dÿ·ù‘ÔºÈÊü«®üÖü¯À,nä¼vÊŒ£ ˆïdü@cõÜŒsé08[v%ÿé¿`zgy f™É³ºI¶ êwDåÚŠØ\ ­9‰ºˆƒ û1ª>ŠÃOcùK_á#&¡8|ÚÓÃÎ2Bˆ´ÆN(žÔì4Â’†¨%iƒ[¢¦ E›*zÙVáÄ Kv7Ã;Úé%,Ž˜O²ÅÝã ‚´!œzFÍ6pðl7ëàͦ)ÎÛ£[ÒzOß1©_ KR!J‚gæ)aÚÑ ‘OKŠS‹…”ð‚`x” 8‘x‰R}¿~•„ÛùþÄñYÅûÿÝvZïk=X\¬È– ‰²Mb%wî륩6FQN¹0ÜÌY÷¯MN_2,ˆ¦–¾îŸ­Ù;¾‡¯C‹Àk2pà%0¼ÔÛVnV g˜3§´? íÛxß0Â5<.y¿a„ÉŸÒÃz?x±¿P­0\ò~Ag`öÿñG/–Ç0ñsÆž íaCºF̱S ɧ‚b‡ë!ü3uïú–S(–Œ¾~ɧ½Ì«=Ý kó×q\§TÇå»@áÙínÞücýøÖüýduEwêÖ_àø‰¤°˜Ó—¨*l‡ìÑ‚\t IPF%?µ¸ÇßsJ3Yò½M[@y‰Z [‰³œšnn‘Ú¼”‚a"µŠ•§)ÞÆu‘ñšâu ¦ÖLV©p†Ñéçç|h9!$ö§ÎNU½:)~­ÆÛmÇ{nëšÛú#lÂI˜-á‘M\š|nóܿę7.4SÚéy èþÃo½ù¿~í»ŸyºÍëሇF¥…Œ‹,l*L"†ÔÈI;™Ô&-•®œ—Y Ný­Pÿ”Šuê¾3e­DQi‰·ýPïÙý#¼á„Æžš³3k³"º¢ïUH)9#1ZbÇÑŒ&ìq.„6œ~öîÛÝ‚ýE{ØÓM´Ôó¯³úd°CRF§C1Q…*ÍäPùû1Êœ}¦÷j›¤Ó†\TNê¨Ó}?s©×>¦EŒeDÚ'ù~HU{zvÓÉ)+¯+ 鳞-‚ÈIæ=Y“r‹CC#JüXª…•Â@V&ëfT­30Py¦í×ùl#'-R⪯žÍÇäJû‰Ì’oŸâ}™ù–{q^û3¢^‘aoÞŒåêÎ(¹2ªS6ÞTƇ 'v|?Í_Æá_{7q{‹¹`Ñ1ì(çD[¦…í•û]™¿¨äÏ„)J¥žeqˆ$´1&4Ÿ”-ò—À[Å¢â$Q-Qñ&ùº&°C'üLßþRì°T ãÛIdœ´qvaJLa»Wì¦áÍj,ºB¯ýW=ŸqÛ—U,k=Ó-Åm± i„Ò2€ xÛ°ã¦ÚÔaidZåØmYçÔ}I˜5þ3ºü‚|FÐäÐLh3l!=þÛ&ÑzÃèq[Ìá„v²†‰dØRÞ#?"VÐ åB¾#¦Æ§¶ðÜl‘÷ï8 /Kg"SXÞ¤¢�,J0Q(wŒ»g9øCšT¿Pö§3Ûvtäl‚n¤nÅïéFÏéFU” JK­_ó#è¸óÆavÁÖ¼7Xås#/ óóõø–Ù9vKuÿBb8nfx:µ$ƒö¥íóbCq—°àW†Ûs®¶üàOyo¸~-¾Gûí;èÌÎ(*Þ( ·¼´Ž«kö·/!VzK€Á=j‹„ è œa„/à3Û€ýï¨{/\›qûW¯{wØ;܈¯‹æÇ5´DpHpÌõ5{{mÝ©¥°üLc=QÓkFÅN#*¦-°#j+×X¬n¦©U=šøÁȤØpàÏ2ÿT,Öꌨ‰_k>Q¡ÔŸ;Õ@«R®Œ˜-&îê$±‰ 1 9!tŒ£¼×SÈDxþ¦°¶( +ìŸOá†ô7wpû©½ý½ºçóÙ¦©i¡u¬¼qEÆF§“/s[f*0Õ—k»$nšëËöö-€Ì6#{R ?´¦øDUJhT YÓ*ñWFž æYÏâ(9< ±ce@=…<¶b¢tö0 #tó÷ßk¯vüå¬=©Vé¬$ §soÄ<haeRÄñ2¹ôÃWâPggDïíCH”Ì rήªGe?’f¢0!zå„•Vù¤æZÙLT,RV1/Ë!Ýs2Qe=H} =eðEö)F=Lãû‚Ôó ïWåøaµ›ÍEÚŠØÆðoõX -ò’Pÿ$Æ‹yÖ ¢Í=Œ×±ÊeD“J9‚Á«ÔN31ÇÑœG÷Ⱦç`²‰¡5ýÏS’A'„ZÌA¡5InFoß•ÚMã“ßúiz²¿x,Vo‹: ›¥Ó@ñy.Wy—…a»g# ¿SÛt˜“•ÉcciùÞ4û…Ñ£ÕØò ?Êá¯+­ é”eIe‡ðÉ´Îñ‰ÄHNsIQ ¼©y¨åƒí9Èø­¯ø÷óûqÿŸìm›|ÑÆºè¤@»g7·hÇÅOÆ ý¢$t¤/_OÁP.14ÄKŠ£ÍúØ™Æ0zâ–ÞSCýá·V,œ€$ñãºÚóõ¦öñÕâ8ꛉ­+Œ6+±ìÎ6ëÄ ÔùÞVfÙM6ë=Ô0=rî‘—è DB.è¯{ÂŽ|‚” !‘Ü$j‘Lž¬Æßvò~½³EB28©(#K0ÈŒ (I2)¯]`â›ém»¸¼)&+0NÌýÀîÙ‰÷®ë«¢=æ›ÜëÓØ|È|š`+,³l¦h¾¹n‹7ŒÓöQ®Bt(îjƒ,¯¢ºÅÕ ws®>ª(î_Ö¡Ë%iƒ`7Ä󯇶„* ýËê8 Š3®4w;¨ÿ”÷†cžø±+ìáý±jÍLàÄKœàuâ´ PŒKž7�êþmú» ' —8ƒ‡1ò˜`ä1©{¯ŠEñ»û¢äÜÐHL}ƒ}„„h­~m yƒ;G8`C“½Yll´¶‚ª4Óª)e+%)zÆŠ^0ƒR¼„ëeŽ”‘«Zm¨¦èeͦ.˜V0¡ Ë}28 B¾¹¤6Æø´ ± ±1µ79 UØ T0nhrßbH±…1¬3Û8ÝÆ Áb†÷PË)6SDe]¡FcÝAýÝ›´z,ÜmÏŽ¥Ü´/:ÿ¦›³ F/‡îHeÐK†“eûöž�òiQR‘3i Æ&¤8ªhuˆ*š+ј$¥œæ<ëU12çŒ(‡yr”m‘Úz\ÍìA)k”K•¯[*îžš!ۙ芄ÁäèSî&`I¤‡àlNo¢_¨=á7_íbªµçØV7V·B7ј…Åá¬FF_¨(1krLEJE26H9"üàŸkƒ.•¥Ì¨@ŽyœšKÃN<?»$Â/8ÕdoR¶ÖLËÒÈ… ?ÆûhÆ1†”bïŸß{QêB‡«×Y3èFU&v"fRîEß:="F<TÇì6Òäš<AT7bZ aWO ÓÑ.ĬS-ór"61/]ÞtéþÛqÑ>Ìš_›6h´i>¦²Ö([Jt2èFÐå aHñ©<|ÉÃ;fKú‰/Kw"=©U–â_íØ­ÊÑ ˜7ò$ÝA[)8={Öï½Ôg(d3ñ­ÎKxÛä™ñ;~kÃÅÄiÂ_öþžÌMÞÔâÉ“•(»ÄÚ àš¿cì>Øßv)MMÊíTS$K† êÈÅÜp,�áb‰ùì–xè6<Ò<bÀV÷6ÁìÂLt£C›¾eAû‚‡ÙpsŽ u¤ž;õNnp4‰:RƒÍ¸´á�gP.©6/[ÐéUG‰ý@ÿÌû’Â0“äHr¨T»³úQÛ÷ÙMÞ2…“{ª#Þg‰Ø.‘ ¤©È3€Aà=ý/ÉÛ¶y_C.¬K¼·Ï¿Úxλ+ Ž;¸úŽâ¶5\(ŒuéXøh4ç«ÃÖ|§V6ëSºÆb~íÊ[[Þañ`Ìmí­$ŒTK´Å,°†tθÅßsض¢ÁzLðKœaÔÜY®ai¨–ªÞð‡b}äB¿$@møø¨�C‘¹RœJj}ƒ›2žóû-ç÷$›¡b¿a<'X“¸¿ãö^uü#â½3¯Š‚I[±²¸ à¾ÃOiO!_"ŒwN†þ¹ÁúVoWWÝ3,ýÐOUk-*"|@ÂÇ÷: µC*ò€Ç¼{Ô¾Q›9X¹´rCÆ«ÍÜ7*´>Sµ¢žgkq¨Þï|ñk«g.+²qÑû¼mÓ=q‰Ø�äKÈ))·¡�K2Ôæ}mÞÛ|Ž:ÛÛÊGé¬|ˆšÝÌs[înÏaËÕ=w¬ÿÍ–‘¦r­œ,^Q*Ò qŽ:Gúó†m«[dó’LîE³ïÛÝm›|§ŠbbÌAæ­î)ÅB¤Ò'‘¥*`I§úùW²Er#Ñ®3SÌ“zÖª+äÍ5ÚX·"u2|.C#†¶ÔÈ„Óìí/r¥G)w-T¹«ÔÞùmî?ïÿ5ûùžÕ¥4¤Õ‰è*åGéÎZ;‘âY37~e&xGR8+còÁŒù°KÏ¿'T:œöS£’Pi´þ½Ußfَѱjƒ^M•VJ¡UЂ¤d®ö)ûáð­{žu”eQ¶žTÈDNˆÜ†j•5Qd‘¼Éù+å×rD=qöLYQ–HÒU¬³²Ñ»ìûø$tQ–˜Ó¿”ÕUeáÜì#ÃçU‹Åg²­ìÏgÒUƒSx™Ú(‰ ¡ÿ*%é¯4ÖœWF¯S§$‚'ʯ’žwR!½œ‹‰ÊR)½‘ôA­Þ‚¾9)j‡1ýJÚ.k'‰´ƒX¥äö?,ô a4§BTE¸·žË´”ÉØ¨]Ò/UµRÖ™ I¸_I“ÚYÂz”Çl^X4%TKÒ†z—øÅ+ˆEò‚+Ïù‡m{}¿:Å%¨î]@ë¶s‡\0\òÉý =Ln›sbìÔÛÙÖHTâ‡)"ÁÓ_6‹E{VSÖì J“-¢aøÕ{®2ºà”o æIÛ§‰]Ãg˜‹‹ÆÞ·Ç"c7¤W¬©X’7˜KX xˆ‚YÂ/(.›xoò½ïí~éúÍó#{øåQ Æ€çnË8ÐÍÀaXø|Ö]ïBí {—ð“ȉX›ÈA5Ø ¨¯F{—Ê£Ûkõ’r]€^Ïš^C–_rzM¡0%¼Cnyò<€ÓÀ™gºùSõ†¦I¼&@½Tð-¤ÁxL3 °¶�ÁÞòÝ+à©zž±4޶ãÅüóÇqߟÕæÿØ­á Ìè4$L…ÿ˜.\ ÄJ#þù%»k¦vÓ=Fâsìüq=’w‰ìHœÁgN ä[ĦÃ$Ð{ܶåòB,N“1ñ¹uùþYnÛT`L# SY[e«÷Åîq²ûöïÇŠnº46Ý11e÷Êõö÷ÌÀ.Éçä3 õFmlZZ³u†ß›yöwæ—ɬÏ•nîÞ´W†»S¨¸»øÏðïª6œ!#è&ËvŒHƒ8#p3èz æŽÕ_,»Ö¾ºñ¢Þgó`Vÿç²»q] ây*}J‹p"½¡’’¡â™x(HWŠ»’7‰É{LFgÆ)Q!©ïbM°?Hî<ãDߊ„üó©F0ÝcªfÂ*ó$ô­•˜ù¿jü¤•óZWµŒVŒNRê&…Aú:-f&!´M!úäF/vT™$ûQ0"~'ú·R£…pÚ˜ŒNB·'0ø@:àÅÐg{­+…–9§¬uV™¬ú&Ûu_«ÿhìÏŒ}k̘š¢j1¤Ü YgŠ¥ÊŒ¦¢#Iª/1—ØÒà'ø I5c²uÑ IÏv³îÄN&F˜Tô¾ryðýs›K~bùÚôM!k+­•hÙk¶Æu9‘<ÂCþ…–T]Sü¨Õí+[Qˆ‹›lê„Q£WÅ¿H%BcrS¦Ö€1¨ß!$‰:‹Z ›J—<Evž¯‡.Ijó,'ß›X¬SiÝ5ûÛ½Ø| Ïm èƒQ¶Aµ9ç]œ¡Js2õ?ÓÝ›D-1™\!.q÷ˆKäaÈ綸{ÔaBÖHvDž£ ®ç Néj°,Ü¥²omš­ä¢ÓÃz=¼…�Å}k—+‰+6Œ¡Œø„ÙÇ=áÀoÛꌉŞ’žÿ3þ�B {ä-W ¯9Ö·~±Úe÷W¸…ð&µjyt±¿¬"•TŽ>—û— дw/7’i@‡º¸Gˆ—ð§üòÂ=w8ªošGÚëò²)Lu3X³Ã~ªÉ›ƒùÀ5Z­Ö7? ¤óæ½üaw›xkžÉ’ÆYç<5<&nϹª ¤~ù«^&xW†ݾxzþD3¥?ì.…ç#¹¡xý²Kî¾Ç›œ€§1~`¨–”4'†«‚îJ¯ï<ÀGprÌ ¼¤Zpk¸:Çoñ÷/Ï#wyÖ Ñ´X¶Ñ 4Ær ~ÎþÇ †áCÔ×éwèûæyÓ~ó#ÒäѾ‘û6ÁPãÀÈæÕž”Èø¹$@¿Áƒ~×峩ÔCd‚.ÝÃ=éÇ-ÃÊ(§Ñ vRnòÿµ±\>_-¾­ R¶…e¼ç‘&ÐÞ½’Ç5œn(jÆf†3ßVò‹íÜzé>ñ=ü1GÏSOÚÏ&%oG½áô{¨“%?c~bçôèuD]cWÆKâ„¡¨½®‚ýfæ®k¤ü¼”ñ¯b”Q”úʧ‰È2$|ö1:“}ðFüâÎpU¢vØE­žkö–S#t¥t¸N–`+ÏèÍShŠªÕ ]’'‰’À:àçrïÌ­U—N,|¤=)©Ö =©‚RŸ'ÙøÐŽ@ÄäUñ;pH‡!ëœr/ÒSöV„ï‡Tˆ]åKHY—JO…%JŒfŒˆR|컈)õÓ¬²D§Qª].©ú¥œ¬ÜÁ|j©¢ËÑ Ñˆr~Îi‚Ï$T2Ž&‹V±l«{ ¤%j‰?e°­Š«(\ŽˆÞMzÿ[ÿÍ­«?-Ÿ…µ•$'7J¯édbQ5§¶=µüêQÖë“óÒ•ñóccÈ;Â@‘&ÙÆ9¢@Ц! Žœ et­”s‹n,y¶ ™‰oõ�ò@”ˆ±Áˆ`…±ÉðÍàš¯íoÑ~}Éó¦ dÎ’²²rýÉÃø.O·Nm)qÅÔ“ÛPà'x»Ž lS©¶†ÅÈD¢,>Œ ¤s†#²¥âá‚ï€-‰2¢OA`4ª’Ob¹.7~Ϋ~V•SuT,´ádIÚðƒKÔgº™GÚ9÷%”+Éša¿ºÍólÙMgsDAŽDÍØ°1Dƒð[ xsÉLa ‰Ú¶‹oó+¡ÿÅÐå£ÌùJ;¯ì™ñÕÞ’6„%Á4•ÅB6ˆe×o�Sá't>¸dwÁ,_ë›ÛPsnØ®ŠûN±´Ï6´;þvÄœzùý­™.ì´ƿˆÌ…YÝ6nÓ~`ù¤gZc:Ò¿!-‰tï4wškÍg°ÈL‹…`˜:ø’_-y³yqŒþézÃíëpé ÔpŒK|£6xð÷\-xœA¦€13 Tþ%–=@ †Ú/­3nÔÜ®árÇâši‡ÙàLÎøkÍ}`,p÷/«:ò5½V´’Em0n³â¼³amÁJ™0L�d=ù²ü}âÆÝ¼ïë¢3Ó¸¢ì´c:¯‘æ±Ò¦Û±."!–/¡=È%˜µÒHÛ˜˜V.Q4Øßßv¼x6Ã<ï­ÞðÜ× {ÑRr•9Ü|AͽárŢìïÎ_t†;Éõ{K|×ù3JmTð%‰/ÉK¤¸|5ñ�� �IDAT%=Ä9¡6L±àÃî÷}‚šÝ¨Étžg)eèsÆ÷šàMÒv*¬œQ)Ãô§‡Ê²}]>SæÃ}Sõ­°²¤ÎzÒ£PBjïSCÇ GûÚ±Ë&õÆ=Zñk~ <ÛZ/•+¦,ö.mýóE»?ÁL˜H´BÂD©©úJT5±ðù¬KU£u«òÊG"Œ.Œ>ŽmÐ(Ó’¤dtÔHù…5Îz¿ãÁ#§„*±l1Š2ã“Ö2c“­”F*�knäìc?@˜30ìs¼È±Ç¢Ê|—tç4Awèh¦{¯}-1¿¢­gU¤ƒV—‚N÷êòÆlVbÙ »–?DˆŠ\p ¨hôÁO÷ÝŸwûùch~àÛ™Á¦¦ m’7V­ÊÁ¤éÊ’²0ÿ ûM´ÊS¤gG“}KߌûvÜ£²†Ê^pŒT±%yh¢4IXàÙ«æÑ–=àŸqžÔ#,jÒbVÙ¸ ÙávÊÿ†öW04ŸÝ¶5ØO[]Px„ü©4aÒf{# üÒTxµìÂ’9|ÀAÓ¼n“¥P ùè`nðsò‚ y <ÌH‚A£ ¬&'$hI¨ÈIb¯1¸lÜE…Õ¥}P”ÑøÜÙ¦°_¡Íëð4š A±þÒ ‹ng¾ ç­/’(5Aâ ö5Û¯ _²X2Û nû»3¦G¢ç‚ôåZq/>þ4…à븽‰¬‡#—þUt D:Ö·qƒ;Ç ˆèq›µ‡ŠfFkA\’Ä›_2¡f¬oµ}‹;½d¾@z ðO™·ð¦b¾¥üÒG¨”à–ä ’(¡(¨F2Œ †w8ËÆGÇ…’SKíXÀ ”ÁÆ®6$x8ÂVÿô™Åa›ŽëÁG’ϸäμÄ_(̶/ÈÉfÄ8¬ßØñ‡<N EsZ¶Ó’YOõ!êG˜„Є §™GCÝ0~‹¾É&äõóƒše6Üq _M19¥0dË‘œ“§Õ‚«’u®¯†ºÞÚñÞŸòýŠ‚Ú{’\ˆ8‡8OÞ!B\ò¸¡:gÈ´6 %åæ%WÜë|AJMð:lk0'Kß›îºd99JèõÏ.êͽ Çwúõ w%7’“-êÌ:jvö¯²š²Y‘:w¾>&Ú*ÃÇ–‰BJ„Ä[æ–ì°‘J|¬Ä\‰™‚ä‰ïóÍ@›YÆ3ŠÊå‰wå/µzÊ.%n´ûØø…l'¾‘ÉÄh1Ò#Áë˜CÜùò“öÞ:_5WE{gxÚ'µª‚³äÖiüÂ~#/êcñyÖí5;ƒ´Hš"·Ç`e+¨ &ÅÚ–ˆeŒu=”†¼²^ˆÜÅÞäw¾ó]‚!‚VDÇC~ø<—-\£Fô?}œÔoì¡(»\TƒÌ…˜K¡%J[™šÃ/c&‹?/üÌŠ™D Ücþ½Wý·ñ7³ØN÷’­°¸„RëY‰è›ißÊ@Þ"OˆšƒDÐEÉ4í¼ÚwrW«}=ÁªwNÌá,¢h ݺÀ^®ƒgrhô¨Ë}}ªÌ'yûî,5¥n-mêÉ»Úu1³9;rw–}L.E„p{é¥Ð¶_åƒé¿:lº“·km(4ÄD„DvèІ~••;œh_8/üžvpÌÒÀaÏ É„BgJÑ™„Ãìñßæî1Ü\ùš[S,n7_Í~·Î=öÃe-ÅÇr¾’c§wŸëe#m+¨ù‹C~¼ÏŒ‘1{\$è{O€ø†Þ ÿŸæ.q Î%SÁT¡$Iàà˜;dyɰhód•Kg¡rξصù[$KN _k¢å‚iÝò&nˆ˜qáÃY÷¤Û/?{ÀôŒs܈€ï}`cKþ·×Æ–`k¨lÒ’t_ŸÜW¿YZ½9.·½ì@˜éµ¤×)2hà°å÷¦”{ؾÀi> U`/‘?œ!JMÉö£ÊÎwL.Œ4èÖ ÂUø²,ÍB Š´ùyâ«Ìz€aÃa‰Ý ®oÐ3” Nñž~­™¾pÐÂ;®4LÕ€{0TèK¦÷¼v¯cÿ?ioø„»×ŒÇ œC€w¼iÿù•=í?°ww8”¿²í‰Â–˜åÔ°™4U‰ÊLG4Œ¼Ü<X’lã&;œÛ°¥Â$Iˈ–P¡ðˆð¢”Õ“æ3L=»°âž‚y)“5Þ’Þ˜çfü®í·$ˆ—ˆÎPS@ù€šc5ÆR¼{fX8—²6¨%S¹iÓ’:3…) ÆŒi2¿6a Ú¼µÍÆ´·ë§%ç‚SM°ÅHj_Ú¨ÔŒñ¸Ó7£’Øøb4Bâ/°-úGM‚P2HÉ º¿mŸ@Ð×L0Rû¬;¯HªëU2³ÞÏ}WA™[Ò*)7$¤ÀyÜ3ˆžPÖ‰¹U{W€d#ØùîİHfºôÖvúíZΰ¢±Ó6}ÛŒ{8½ ¡Éȸt¬ƒ‰©Àê6êÕ“­‡ÒÎ*—e—Üç)7Áµ>Ai‚B177¤ztf¯Vש)ŠI[x$+9•Ï.|eѤ?–*8¢ë³‹ñ—Š?–ñLÚ©Æ é„ŠFöß𕜴'ßÎvØ †\"Ú¶Æ£;”&ˆ ½Xé[†&>skí;+Ïg&åµ É„´BçóZD†];ûnEU›3[ÊC]¸gó~%¦)‡ïò·&aÓÂR"…1z¬Ç. ½÷ºm=µßÛá[7ÝÎ1§àÈ•°qœqì‘ßa·bœ‘cx’<)ñAà,b·¤Œ³|k%Éqx#×JàR³Oí×#+S|ïé]uf’9¯òó嚦Noj#¬T.€ñ„M+ßÁqBРyðôžifHøÀa`ç‰;=ßDê«pÐeî�É-\eNF”ÄzP Š1Ó'òÛ½ƒî¤@F >Ýð[&÷/³þxŽ ˆ/ǵµ„´lÓ4é8GŸ£2a‹›âÿeä.€çÓW»”†°A39¦–„GlÍÜbßn쯡Âìi¦´Ž¥â¸( ú£Jêiv´ß½ŽžŽµîV~wAY¢ ŒBÐÆ°š&Wö̤+“G·Þ }h?Ö+„ƒŒ ËÊoÔ Ü%ã‚~Îþ/§|T¢,$FÍ~ǯ5§‚>K<.¹Ýro¦ö”[ªaàKúÅñÔürjïþ§ÜŽÂÃÉ+Ùí–— ^õ^Iª/Å’qsü½î–éÝäb!8(¼Âx¼ Eä@1ãÃ’‰De¸†Žhñ 0äY;˜UÎn X\ÂsÖ>k´¥`÷Bµˆ{Ò·¸ z‰¤ýH®¦Âé×Î…g©0 rtyðÁ·i‹¿ÇC· 8£Ò¤@õ€ýÝ 5¦DêWðÞkŠ”³Íø®MqÞš-Óoq¬¦Ô:åïɳIù,Å)Ûv׃æ4ó¡b¡(-º„óÐTsç6 ›*²0É7J´¢ H¤&'âq$™%ä5ú·­¶«4öAâwI=?§Û¯Ž_Öžµ¹%5M¦ 'ÙÇu=294Õ¡ÕñÂ,ï² Js>»N=ûÝ7ú}m6Æ7Þùîñ¨Í nÄõ§;JßL7­j3Ô›´aåŒIr•üTùÂI«“+FRÉô%Á9#îšýÌ …•Í”0B7µù #9¢í%¨ŒNµ µŒ6{·]°HÃÇJÌŸux‚Ž^žìéÁØR;wñ¸ëŒÅTuæDæ"IãR–ÑG=¤ô›'Ýž*ìœØ3þ@²Ä¡IQ!$"£*ƒ'blƒ$OÚ¬†;‘P•KÆG-GQ?eëF÷äy@™oˆÆ+µ5V) O(bbð£°êÞM–ÈÚ%áµýEpè¾ û–±é§&jËלּL±môY+$Ú¡éûHïIqK"çkö;ÝÍÝ£Ìç0±§š]ÑbøU„Äu`×s¢x*Z 隓Êg“ IÍÇòÉ€ÍѪ„Mˆ ×m6¸ aA3DÎvH  ‰÷Àðžý Ý;ŠgFx´àt{e¹ƒ7‰éˆß3VÄŠÿWBâp²Á.IaÍšáÐêöeqµ„ vˢ߾ŒþÙ´Õ9" á¯U‰ ”ÂŽìОÛ-_ÀÏ!‚?Þ¶$0éIÛ›L e‰©ÈáF|¦õ¯È„¼‡GøÔ hà&P;æãââî¬C¯±¨uÍg´jÉI" lzi?æÐMàÙ[/Œ°?¢Ž}§u‚}ö•Û° #h‹¶;ãWs>­ø"ócÍ™Â&œç!sÚSkŽT´£¦{¬À3ègØ)¢e€'Ã~ÉÙ \R,þçñ¢ÿ‡ËÄËÏKÓp{ Š+ÃÝ9lá~ `l{ü@33"Ö£±£üÑP„Âä”üU’fƒÔHÅLt}äÌœ×tJƒeo¢Ç¤ã-ò’'IT’’®mBçòÛöÏhk´ò¤n¤aI„™Ájö–9(C¾&$´f°†tM©PæFž×©2E¹Úë.‡5À—0?ºI儘ËÓ2ÕÙª #jÏø7vŠ dAVˆ=AŒ-å*Yç £Omž ×¯Ã´‘)ÅŒ²¤xƒÈß㓞§n{ëãíx~IXm›nÏÐ#ÓgÊCkZ¤wxKë!³÷MÛ§-ç[Ò–¼AЈoÛÝ ¡zî¶|±åßm[µD[˜‚&ç:«i5YøäP«Z†FÐÆ H†µß«ÌÿOÜÛüÆ’^i~¿÷3"2“ÌdóªJ•*WS=­1!paÀˆ a€i5BzfÕ0¼ñÊÿša¯lA õ®QHbW�„?D:Õ¥ª{d’ùñ~z‘ÉR©aoGü.o‚yÎ{ÎyžßãÆcœÖ>ËÖÈ1JAF%²‡Ð¨ƒ)¼-¢-daâËsjþÛß æ%¹Ò |sÑ_vãâ1ägZƧÿm[1.›2e…ײ—!ô1lTÑþ4R ‚ÀT×t«ÙŒØVÌ5Tj²o³ ŠëÈ{¢€bB!;»E{…9¹Xì„ýÖÙŽr0_ÚßÞÈögj¹÷n´°BØ2Èœ*±[+ŸØ¦EW¯{™;ÎP‘ƒlãˆþ²uj¹ÍîÍçœáª¯]› g¨1* -Q"¿Æ¿jòó’ìa"¿êí N³¯ÕO̘å»wn•¬¾… ×î¿0Ì|{ÿΖ)i¼% £ =l¥w{gáØù¨ÚÁÀ9Tb(^â;C‚Æ$` _n¸¦¹—hy̬ZUw©W²ÇuØß6rѺKf¾�Ë ó–‘Ehbß /­Ü4{Z%„£›õâ^5²'ƒÛ†”gìKôѵ#(÷ä-CÏìÄe;¥Rg­ý” šDí©¥†)=tŽN¼Æ«à ®_ "?é© ûdfèñQúsonYÔ¬ÍKÖÝn¾šôÑãÿqjÝHÚ|E€'Ãà±o†•6ÿwnã,¸ï­3È3ÞM(4ï ËüÃÀޝ¶\?ò)Xƒõ°¡€ë)÷ÜifcÆžuµþKàI2[ã@Óˆi;™ÿ9zÃìurùÿýÇŽým —0âþˆ×øþgÚžòw‘;ǵЙS!¯Ð{Ì€2$IV¤ nB%P!ÐjUi¤o”mu(,»‚,ؾ¸;~Ž%~)¬€T7á¼ÝIž"ß>š¾h Ë`©Œ©vã G0 HOês†Ð$ZH;"(u-©S¶N¸4Â퉳@:âþÓ`.¢)’Õ¹LJ&=È¢orl.*m‰>åˆê#ä¨Ë#„2.x¶¬š!µÛÀ I.ª„5”gÜJ½Üâ>Ý}½‹:q+X•¦˜ ‚†@·§Û€aêQäÜœ p çyŽmµál µ'ç=´þ ÷pSòI‰‰|>Ã[ì9Y#Tƒ7$KiUáìe²Î»6÷ÈÙéZèÆ(Ó¥Ä8šBø$º£lЕ /˜Döô£]KZfgL9RÅ>Tÿ;K2ÌòmÕ×zo~œ¼Ofýky…€‹-jÒŽ.–&;é·C$o£Hÿ¤;Ì$9áómȵ³F†¥›t¸ÕÓ†$nõ¥1…]Bû•Ýa>œTvL‘# ±Ê™ìš!µ9±í—OÙ}‘Âå¿­$H¦÷•xÔYMÝÈF+¥H)¦½Y¹ýø»0Ÿ]ò›ñ#FAAñ”ù¦äIuè1³Ï¼švbŒ?'OI%J _ÏzáŠßÞÊÉò½p2òn/};°ôµVD7˜>ÑàÝÝI ~»æÍ‚³5#~§›*$R…ƒÓÞÎÛg{ûOð³Þ /^N»\rÐìsO8`4e@¾ 7ˆ)êøø Ö àöúá'0b1b-g7áGýNd܈ƒ»Ý†ºú±Éz™MWèÕ5, ãsÎ.°å­òµgjÖÿV?DÁ¹èäzuÜþKP×ì`�g` x@€l_a4& 9wDøâUnäA-Ø­é~¬5ŠÆcV"ÎÒùZõzyÞ¾.a~°3o£ã¿_[æ†ÐCChñ5ëì¸ÞPCiÈóû‡cki=ˆànð “(Áô w¿Ô£ñ–ή9ÌI‘F‚}‚×Ï|õßqÿÀ%¸¬pÐÕ\[ …(‚>²O|ÐÜ[~þöVlê81ååR»ÿÒ½áú·èã]úú‡sÃ�ü&`!p ÷[Xœv…§é1Áþ/îÿ’›)?UŒj*P_Á[¼�ƒ³dÁ!’*#2ô$C”ÑbÐ=êÆÄLYàGT{fn¸7Pä›ÄH€EŽÛ^ñùûüž»¡å‚k –bÄ… ²ÈI¡ÉêÇ·Aש7/aét7LWaÒÄhÔÞc“Á ST޶ʧÍP…$’™œ >ÉÅ‹ÌmYSI¸V`+´A–«`ȪQQKUûƒ ,ßÇ.ØÕW ÿ!r€™G‘BƒEPçPåÆ:í8&:¤!i¤e‡'žÞsý{_ >>-S•ÀÌŠ„o ÒÃé õÍ7ð_Æ9¨é‚0ÂŒP ]’)¶),³sÙ"KgTÚ‰hDðâ¥sÈ)A±?Ãö‰4¬¦;4ôm,HŽÝÀ¦Ç•h…ˆMέÊô¡+Æ?A 3Š…9,tº•fõe«¸Hµõõ(ÙqçÒº .ÜFšòÐi/yï‡ß¦üæ×ZPcmª¯ŸÊº/¬ÖN…Ù¾Lõ;YWo¬´nHè-ú[äò[R:Eø¢ñ‡vèñ‚ïÌ1•ñÎeDF‡Û‰ÿÔÜã~l¡¢Â!R;­mU¼Ö¸Çåô}gÇ+½%|)¸–«§Ä'¢I¦ s2ìÏé-cÓ(у¤›ÆÚ8áý¸[Q½Û¿|²õeßÉ»F~a8·ƒ²:Q&ÿSS=´ò ¦\ÎçL6WÈé úSÑùâMÕé ”^}@6m,p%ϳçý–¢'ß‘È5Ò´AJÄ o RßR¿pv¹6#Ò¸&s/ƒé÷ÍNÔrRï·ÖZç2Æq g‰KI1FUµÌµØNy£,ÑNÕÁ„ïÈ'·Aà>À^†X T ¸è‘{Ćjèa“+Ì”h`Îû <ð#0´™eÆ@â/ž6ÃþUô=IúúOƒžþõª¼acNõoksÿÐ@ûîÕ'±mf³×UU¯Ø^p®1ýˆdˆuSÑjpp©&›¨Õ3ç/\¶§uý'Òñ {=ç>po¸Ì8Ï÷T¤ª¶ÔçXQ¸‘ùsߢ‡ÿÏÆpsd=BÁÉ৸ô<­¹þê¨g÷Êæ3|R0)™ô¨¼Àoˆq̳b+`Òc=lgÙžadFâ=ú=ê³S#ÅRh®ï¸ ÐÜ%€O4É2˜æ)µÃ¹¯ùB2Xœ†³…÷dsÌQ×&ÔáÑê÷n˜ãÏØNIºMaéNE°.[/R;:#e+‹¥ç`_t²×}ÎúØÙÌhš‘5jO/¯¥G(bÂIúÜJ¹”òGh¡zWkv;‰œHŽTá™&F“+Ï«`f¦¯õU[ÍÉà3*ð?AÞA1%}ŒžbÎÞñ€÷YžœJ/¯¦wà“ÎßpöÚâ5ƒ9²ì) 7öH Â:;¬”kd߯ä·!~N_Ð[ÉØPn¶E#}bÎy·…¬S4ˉè¢Xí³QÚk¤rcã®ìdU&’j¼3rkí{[lˆ˜aÑ ë6ÃÑZX‰õܘu;,gX‹Ö¨@|l¢3ñ`幬5èæ\ð¾5—c;±•1èl^R#»V\0Dœcr@id2B‡=ŠÕ¹@™Æˆv�ß3<Þþ/íæ¬¢Ôk}>7q$¶Cê9½—tÖŽ¡ŽÎjã2¨ÙRBåY’AB»ƒâˆñö9Ö—Ñļœxas)Êe%„$_ ©KùíÙÝJ/ãe°.RpÂyáZà|оàR3 ”G„çB¹òI#žZ@SØ&ÓNrk-aB8BLCSù¶¿Ã€z…^¤¸B¿!'Äs…v^Ÿyì-®ÔaJi0:“<O ódìlfÏÏSïš¿€z×(ÝmÈ#©­LZ½ LG©|I¹‰£Öƒz8)ã{HpÿâQ£h‰öŠç̸'n°íiVP§W(rJ¼ iú@‚g˜œÑ]“ñÎÁw¯˜N`?‡ôƒ–hïù‹kJð<8سhYK®S0޹gÓÞ<0ùAI\ÃâUnÀð¤ùÈ2u†h !çmÚœ6ðþõ%^k÷â×è×Íü÷Î}4o¸„§-O“Šb¨xÒ ¹¦)0åØj¬ÍŸíýþúÇÑáê•Ô=;N†Ì vØ=.¾ž"ŽvhÉ5Ü ¨¹6$ƒT`w|Nq¶‰]j¾Ú›Ì6ŽaÍSC8€æ>ð OX3ñÙ+ðû޵yj‚àïÇ·_õWÊÀòZw÷f…âç. lÕ Z§xãaZ J7•5`1–gÌsù7•ýÍ^qˆÒÄS–~¤»2¡FHAL:íP‡? 4ì£_‡=¼PhŒA°¤=å#öx•¿ v’¤)Ý\öÓˆî@ÿ2Ÿ7:µQ’%VÃàȉ Ø`¯äÆšƒ³“¡U7Ø Š’,Ù ~ œ§‚fØ URid„DµAŽÐ@X×XøÌ ê ]œˆ%9²)02dP=y³J=ªl’oõ•ÿв ¬O}?¼!ùg¨4UIÜ£ôÄ„€œp’dkCí±OÎ%OUþj/ÿgŸE+—ô#1ìrj¼k;ß–ýÒÿÞwè+'ßúhps|$œÁÂ’qÜ3‚EŽ †œÉZß.oÜÁP—ÎX_™v qþ?L1•’JmªÚnŸ“Έ9%/ä5¦äØrÚ£úeûBü—OóúL2ÑP])]…”… ‡˜ž¶æÿÌ«>ué¬Ã<“µ‰¶‘´Œ)vL ,К¸cWaJž÷$[ËTוּɉá=k¼+{ ÍLZ]*k{CÙ¡éÌKòé¸@_` h„EC3€(‰#"´jDns¨%fÌÒ˜.›UoðéÖ uµ7f³ t=«’Úcé,¦˜¹"üEc·­ž¿±›™~0Lãã…SgO1nÓÐõ£6…%Úa)œûøÉŽú7³ÎŒê¥Ö]¯bXy/ƒQ£È>ær/FÞÓ>zsWäï� šþ˜<å`xüß™¿ôŒ¿CÁèUlªA,8¢Æ[ÞÃÊÀ‚Ùú¸Û^Ù¬›@;À ü¼ƒ)D°œê»]œ qOðŽ>gwÉÙ/wt¯°†Ž)\´'tȚXƒš“7lÇÆvE5Åü„‰À;b k¤¦ÐN`ºýQì´¡‚lÀ#7TW0¥0\ϹßÀ÷ Þ7ù÷5,øÒ”ë1÷ùTõïi’—)8’uÁù?Co¸ûA?¸y ¬¸<j–¦pñê@w\ Øpw²fÜϹ©˜’Ë1éÀJr™‰˜ˆ‘¸&,pgnꯜ᰼{ßÁ꺆9Úr EÏO^Nîp¹ zGÖtާ�‹S[¾Y0[3]ð³Ï> ²ú…uÚùÀ¥æé‚‹âö"ÕfˆK—Òï†_ß�ÿqžS†Ö°Á èP‹³Z‘亃\­_øD6UnITG)zÄ ¼[É€ MîÛ\±Í.´“€±'ß�®'}M¹À¯á†­â‚¨Î&afû*î“ùο™ú·Â2ƒ ðOHÉÎü21ùù,Ÿé¾b€êšr„.IãÑ`4 ¤F€ŠÐî¤ã¨8LÀxÄšóÅiÕ«©Àgˆ¸À“£ËL,µÄzª¡QûÖ@¦U9‚ø–¸9-ÇÅǨ1Î-OŠ­ |ƒ äˆMέI\šæGÒ€ƒ­ÑÌw;õÒ¼¸ {dÚ)é®=8Vž›ßvÿî‹QS+.ÆYzËçÇnЫléKÆ#`rÚ+g‰÷DI°¤«N)¤4ôŠnc‰ÉX:²{I2±áÏš30û„„”%òµ‰š„‚àš2Ѽ&vëé`J‡8ääœ{ÜôívÄŽå0¸§&×ã-í6:Šè‚&Âá@8P˜Fjóƒu#ý‡>ü-~,…ÖÕKx“ôwçrTa #Î9ÁÄUÞ“}£|+vÄcýœ| ï ô;dAΧòš:b=<Ö{cKïâREÄX[WÛÖª…KŒ3ˈ)X*:»XÙ3äÉÞ×µ~|�� �IDAT&QÇ`DµTZôâŒÑYz>O>…ìê÷›ÛUèÞjÌ$xåÇgÛºš[mœÐä!vÙ3l£ú­ o"y3Ðõ’Að”7w ðtSî —sÊ Éá%sˆ|.™n±óº}:NýšaÎü±x®×ÌatÅxŠ6¤y«7ô(øë×õöÉævEš¢ OsŠ WŒYY˜ÒLhï¾/‹Õ1�ãÚ¶÷p=¦˜œÒÙÜ1ºgÁ°nÜ´Õ81èÅ!ÉQ¢-îÈ¥^ð/kžà“6¯¼?À¿Å]0hîrÚ¹žQ”X¨zøŒâ÷G®÷ ˜?1ñͶ}Yùþ¿ü½á_i“f?PÔ²x]%Ùté^r¹ÇyØüÉs~vA-Ðô‚w¹gŸ‘ª,NãSõ“¨–äøŒ›1³ŠB2 Ý·Ùá¾>!ÑY#椀ßCàÜÿ‘È4[Ss;]ZØ)‡*×"zmv43ÝZ]º¶û1kúY\’ºë·+µ¡Ø Áš.jDeøñ™*mHÁeÍûȆj¯>GA¨žàq›“k_lZ>¿}ÖõN˜»œ•|Z9‹Ôìϵ8¾Ò/oyÍžQÄŽžÕ¾eLª®’•¡`}@ë[O]úù@évJ}—{‰+’÷~’ÝÔ6Û–cdA^0ÖÌ<2 :avˆ@pøoÙx©0ã â-Ôœ!b h‡ ì/#~gù4ß^É:j£fKi»$WÙB¤WÄ‹“-CMaÎð¬YIn…"ÈÛ³¾¶½Éò +ÕJëe\<PnÝøàµií¸öW¿;TÞ”Ý³à Øp÷°úøE£Íª:ˆ³Œ›ÔLÏ9”*v’*3ËTrë59‘ö¸ÏV¶ NšÖíeBDLh,NÏNKáQÎäfdZ ^,3M°ˆ]‘ÑЃÐhnu_›0 RÅuµ³ Ì‹Öÿ(ìD¸ßÈ@éø¶ÝÝ[®“‘SﯺÃ.šêøVÐðõÈð5£ÿ®µ_-%9ݸwù.ÄŠ½{ôÁ]Œ¬»¬l(ßDaÂûe~ìÒx%wÈÍIäá7xð†Þ£#ñ;‘¡Äé›áÎ|À²°|mrh¾•L­n¬H¨¹Š› Bà PkÄ_&Ø:ä:`£sBwrü¿ä÷©è'oú¢øÈ ÷×áWçŽQj¬§ŒŸê陼°ŒÈÚ¸Ôð¼Úzüo›ðÐz=mC“<kVÍõ®å-÷x}h>&Ð s—™rršwã‚°ÆÃ3¸+|Å$ãaÑÆ;øÙ1%_ 52œG#ØÀŽGÉjЏ�}Jü0†zÚþ‡«‘57s> mz}àl­;chnïSýó…±vG(VEÂ:ÆÙ¢Þ’4d {¶kÊW¾µ€—5 Üo4OÇ‹îFÍý¬ýÜ`@0sxýeì«I/Cà®_Ÿ<4iÚ“?«†õ_ߥ_O%§MÎ |}bnÿÉj¹ÅjJƒJX‰L¤Ïê@|A­Io±¦y/Ì]¶d P›Ù¤©¥ZõFºeL‹ÕaƒL6X¦þt.{zå>¨-UùP)‹èçN]x?jGMYš!Xb5¤ ö+#™ Ìæk èÅJÎIoþF—ŒäGaË@ô×܆öÙ!þ óa‰º‰©}†Ð3¹ƒ¨š²~2öNº›ÀGÀs¬=³õ‰2›áw‘/·ÜŒ¸“¡º éa¯>(078…5üÞ£ªúãòGQLJŒ9¤þÁG’;ÄoÆî§Ö[Óê%‘‘ä5P:L 4ÈHêÉ ·!ý#Û5ý[>”T‚ ˆÄA³ ”xÉaÏÈ€÷Íø}»ýo¸/ø‰¬÷¹. ›•ó>ñ¢ØKþPq¾%53ä ‚§‚.3ÎêCªãÖ2¸ìк)ugùŰñ‚N~½[帊4]hwšÎrï¸1|²À® –81^Y'¬|”–M°íFò”Ùf.â­¡.´IyR7Ø•›cÓ)cÛIžƒç|Û¦°ŒŽŠP8¢W±­hò¶ ‚"Q¬Ge² 8I´x…uVµ4SkUx+ì¦Û~½•óßå°Rúý5³_ÎW7%‹ÙßÔá7EJ¤ i•™^ÿš,~©ÿýX?¦�Å|ã=&‹h¤óB «³’F ÕØåZH;HÇ{x\7†öÄ~xÀ�7ô uŽRèGâžœxòÄMûå wc™M]!ýÛ'/Kp»}l÷Ba%DLZ4!´Ðxg¶Â¾+SktnÌ¢ME0QXŸmÊ\qæ^šâkDÓ¦‚ —ªr¾@.)o1ÈôíÓ‚oÚÙÇ%ƒ¼•¶~73Åh9̺›éênzhÞÁázÔcÁØ`>&M‰?çiCï8L¹( €Ý-\¿%Œqº8­3”A.°Ç¼�°pü–¡I–Áà˜5 Ìk};‚¢oà§&2Ñ{¨nŸÊLÁrÐÝ“®ot}l3 ƒBÈNSu48OÜ` €ùk½4ðÚ4gu¬¢Ü2©97L–莸:ÝÍÇ'>ÛýÊ×_ÑAÉÝ”»E{kN6¬?[oøWwi ÷?ô¾E€»õŸ$nàE¡O9RyÌ3þÀÄ <iƒZ Ms[ˆåµv÷>r×¥/tkÕRRKa.yÜš | _�\ÀtA¹&ÂÙ‚—5ß„&b"6 $1­Ù<]V Eû]µô1Û!ºA>n35÷4ŸÛïG< ¹üM?ZJéJG9¸¼?´ò…OÖLÀ>ܪ¦F›P.•îÜãJ-ж…)´½¨,‘»d‚oð-áôQüü8^áŽÈø²½³qãËOJŸ§N.öfÝ îA^0£)l´c«p8ýÂÛ‡ý{^—eçfrˆHè}Ò#çˆï…Žýšý‚­Áj”¥w0&<.j-_*þVQ:èoÕKm7F°,RwÃ7˜™°NÚl‰Òìcó’Û÷äX¸öÜškšûÈMâow|¤Ð¹Á™ðhãÞÊÖ ¨óÅYæ%ÓåuÐWmùo`†vKõØ.&3ÇeàcY3;m³Yá‚ÄdWYoÊÖK‚ ƒ* S]äÚb“v‰+9¡Q’2’â@캸!UgÄ!…f)½1Ë"tI¯Ä±¾W¤IãL«3¥!Ñ$L2#QZ‘µÒA=©ç?ÇMëÁ¬'oîÍíL×—ÖŒYJÛųUFa�dFER$@(~é iìW¢‘O³Cþ @6¡BäVìˆûFi¤ýtŸÎöÞš¬§W4KI—XIE+&Èc3L‡ÿ ·hòºýϰ¢ ]t÷Àö–ës£ ?ãi. öÎi|e[4·½Yƒ;ìQÊ™ÂOŠÖ "möK¼›ySîŒ}>OüÛðE —o\ÑùÔåÙ¤äê²D8#7|“¸[€æúÀýYýŽº¶vT8TDÈWÌLàÚ£×ÌœmW'J' °ø ÇyŨÀo8ÇÍÈ"A9t@xXw0WÇ/à)ÀcÖ'ŠÆqÎøXøO`®(¦LŽ&é Ŧ×_Ží¥ûJWÈð ì;‰LôM’­8ÞÄ<¸Ïk4T¯èÒøj̞ú?VÑšQ¶×ÒyÈ Ñã{ÔŽ_¬I . Owßû *ØHϧáÏí}{z¬;ð»ž^-o”ðöhyûccøé‚‰¡9Ê-ê÷Œˆ ú5·‰:ÌÏ\x3äêžmˆþ>u—®qјhÙØôacÍ-Çð¸£0jMõ ½sÒ†øÐ:–' ãààþ×çïkž¡èþ¾Pé«¡®ƒ»·Û>gú9¾FÝ‘DEe:!°É˜ÏÙq¹ŽÜÖZ¤mÖ –R¡ÆèQËx©´³’¿®´þ0neÏ7üÉb“¡˜2\ª£FïŸgbwnÏFêe4îì¹Á< !¯ù˜–ùRg9ä@òýhý~GW¸kß¿¥ (OØÃ3~Ͱ¦{Ã0B dA´zžÆt7ìî¨æL\`ðË`x:¾g±'»:}Yg¬Ã Å}ü~¹H®�]TþƒkÃzªÀ»ž"GeÌ}â:Bdùdà<£bÂÒ?º¼a‡±W¥Ÿªƒ1x°¿ŠŸ¡.a ‚ìd+5U`ìÑ[¢Çl�ªœéœÆ ²/U—9ãã�}#0ÒZ)mÎHm”kF©­$6 "eÀoq‘t‡\Ù¡ô(ºBnmŽnx"v”P®IW·bZ§Ú¨í2]t:¯zÚ –!ì³4yã^ŒR®ßø‡ÛŠÕG Ò{$¶¬ùl^ÏB=ÆÁ%Í`x*‘–2Òc#ÑߢÞÙyoÇ…-4›âÜ£L ñN‹T“Œ/–^tâe•‚YnqiGµq U\ذvšq`™0úfÏ;9Z‹rˆáV/jµ6åœî–Õj¦¡jï¿g¢­W̹¯ÊöFÞV¹þngÆxèâ”sC)ØùnØ3|0þÜ[Ñ©#š4ÀЕž±Wå¶Ôí(¾­Ü<ÎÕ^#ã¯üŽá¹9WmöNWÙG}rá�÷¡¹îÍtd?J¶DŒ¦¹Ý·«ÃÌSl˜@µf4oÌ¡EŸ£ zKVè‚QÄ ¸Œ ¸Ï{î+nA?P`GÚœ¤4î(—™2\õñ¶DÜðüÊ÷<€„Ë#‡†×Õ4mä×Flßl!yg_RÔiïd€G'ñÕ¼- î€ôÄ5¼_ÿh]½þ/Ž.¼|D<p ÷‹†…AY¤­3µ7ã]£ömÕ!6¨c&æü$Å<A<àù›5o,gü¹{ØQýÑe€z½Hÿiïú&k&sÌžèÈ Ÿ¡=-¦ŽúøÉj¿=éÉì)‡à×xR –*¸ÒÃÆÉ¿ýÁèéÕ>!§¨9t „-l骇µÉxO·]ð~ÍógÌfœ‹Õ¥â)ýòFË™3ÅÁ_ª.tc~R\ƒÈŽœVV¢bC߆"­ÉWÈR½ÉÚÆ`=Œ¬ÑESÚV*BîBÄD3OþœNj\ÉL°ÈÀÙ‚HÃTׂ:¯æ™©hª¢•‚dÿHŸ-¨ÈM'!š¼7›ùõøWQÀÄÐÆ ÁžSň<âP’-R²7 þ^übƒƒò £‰–§ɰJ®GxŸ4éÅÐXÿµŽQ0„æÚu2Ñ{S9cw¾ƒ-êìŽò½97ŽYOøI棞q~GÑE€³ŠrxSº‘í5"Q4¹lµ{›D²ñféM7ò«rKÑ#ï^1‹kü‚ÌjP¼ÐT£vï‘oq‰Ib¬ÛqXªì¢Ä ¯S«=…£8*çß#5¦B†F¼­ó¦ÎÞaöI •?±Á³ÓF.žÚlÓZ\Ô¹´±rGá½øÐEGbrÊ…ÊKyX—[ê)œAZÿ‘àfiÎ7Fa¥±L‰Êtó^´ÿmÆœP(õn÷£ƒ˜k:º#ý$Ká­oû~éb]TÖ.È„oq]—Á¯AÛ+¦•36ÏQ•˜„E:wbJ*pG³±ª%µÀ¸òÈ}±0i)^¿§ö5Ö1µHfjUYì¸q‹ÖÁÄ0ÊØˆÍ«ç-èš Ú?X2œÄ{X]ÔèÎØy!óX{ÆjäÕKHMLmÿÒ¦=#…0dɳe(¹?.kzpí½[þ,8[Q—¼÷»VÞÌÔkFPpk¨‹I,¦Ë~å*úep™Rp&)1Œ 9Kˆl{Î>àÞŸÎiXS@\0öú(AÞ¢zw<Á^ÙùÕçkÎ5ÿgkÚon–³±«+¬v.ú®ÿvØ×ýΰñÕ´³!N¥ûü î[øèUç_¥•Çýý]özÝÞÏ—7¸™gžÜ´÷åû6ÝS¬qßoòféðŠò| Áìá¤]þ³õ†c&Ï9œvDGzÒµá^sd`¸ùLG=ä <îõz¦8Šý›Èèl1Þ>Œx€FãúÛëÀý#wEs}Þƒ²ÆN½ û¡ó.À{¸¸Á_’Æ a‹»a¬VÊP,1´¶†nÎç%`#S˜ðë-ü(46¶èç£cä„ä°ÛÈǨ‰Ï‚hs¿äʼnGÄØÙì‹¢Õ‚(ÂêÞsߌi§=h PhzÍìÄ€†{Á;ÏÄQT­.ˆ;ƒ}ƒkàaåÁ-±nãë4j_›t00¦Ypþ9õ[ ¦„_’ D¸5ÈÅßœ=ü¦�Ó`4EI´tÇ’Qp_p©p±âR;3`¾vã¹ÿ[ÝRQ0 ïÛôúÄ7v–ü–ázÂLP‡Ææö˜ÏÑ€Fû•™#«¦xóÆLë—Ò"Üaï³n+påë”k7Ø? .{Š€ñ½k=²¿"Nfô’}&Êv‘þ„ Es.GŒîb `øÃ!¥=Õš| I2·”µÒg)”™r؈/g9]´.â·‡¶–ˆCægâÌæÒ¦L× ± Û½k¢¦×?}oÇO½ûÎ.Œ£´Ç— M+–ê­ s¢qãwº}Š0àÃñÜôÑ F©´CDßû¡T»R½²K¡ÉOföPY©Ê„¢ñ£ÖÝ­º×,¦Ët¡¢¦Ù�Y[7"ÆÑ¸ØÚØL¤sk­GjÍõ´=šlOß[Sx?âzD!°{¤F¯Ï „€õœÓv6PŒ?õ—<´‘7Ó¯šG=‹bØì}tíaCúŽÍ;/kÜÛìôÕ¸Ö|!¿˜,½Üu2r_@±n,­„’ÚRëqqÁn»â0e³¥ž€APD‰×„È�IAä>péyÞ Ö¸+Ô”Þ çÈH¾c7‡€‚Ç@ï±w|ó½å“7û“×Wï°&~ÆÎbÙò¨ tEÅÈi¼Ýî°:h¾Ù4çíÇo)tSèÖxöÄÏÞð|ÉG\|ÍèUÎÙŸ>�:(^Wï XpiºId<˜)¾ÜuòÖ§v•¸5îSeÁÍšÏáìAj¶Þð½H©zk ˜£J5°àtzý|} #ü‘“”þß}º¦ˆ+ª)ÑÈ~.êà;}353c ÿËË(S2+ë/‹N§@nÝ ÃÝwÇãÇ“‚‚¢$HvŽ~B§™œqQbrK¢÷  ÊŒ_°“‘sK¥Ûêñ–ýˆ‹„–d¯‰H’<^Ö Lã#¹¥ËTïMñÞÛygŽÖÁÞã·„Q{LQæœTQHLJäÏÈŠ =_¼p¾A;Ì.ÈšØxÆë“0NñŠ_·þ/|üùëý˜Â0ž4wš/M©Q†¤Éý鶨èðßKÿ£zÍxñ?Ùú±HÿGÖ0b*ˆp]5÷E‹!I‰‚®4cÆ o7ÝâöRlåóz ‹ ÞGL4µ½-¨­4Õ°< ÉË_&‰”T‚j‡·Rܪ­Í!xº´£Oe“±a°‡iÍß%Bf ]`ÕÌPód8X6’IÏñtI,P™a» ’½ýå£=Ÿ_†Mçç«H%»’!×FÔÑZñ†ƒs‡÷nó“j÷ÑØã/R7Íh¬óUK]Æ‘I*»èrö.µò™pÿ€§}nHÕ›Õ™Ar=r_=´¼ŽøÇ„DG7\П›\úgÑý½ãfËe@âCj‡´ô3W„ÃhŒ½Ø½—É”¿® (ÿw/Ñí²q¹ô}ÑSžž¾ƒ‡v²@™Nj k4ÚŽ¥.ŠlÀ:Ú”‘¡ry~á (\Ä›Åkcȯ«““¼!¶÷¹¹¤Í W-†L“L4¢bôcÙ°s¨5ú-悬 ¶ÛÃ#qºQÓ*šacè’Çü÷p¢S#¦ó†t|{A gÜçÕe`òؘ؊)‘ÞÞ~µ©ß=ÇR“2F`V.(Ö&Ѥ‡¶‚ÍeQoÈ3D…,Q- ™¾ð|xÚR9"è)á=ÂBpoq0y¤8ñøx‚/ÿTns?‡‹výÇT{H ÕêBR¤ÆäÖÃDñ­änÚ~qs[\ÖÅØ¹L¢órõXðÏó£øèn øþ´ ;¸8Êj×äù*=c÷Õ­ê %‚»âyÊÖPÌ6<=¼j2×|òºªâUÚûçé '‘Ò»Fÿ 5éh1ŸÁ…a,!²[°]SqÚÀz°_Ÿ&†Ýé© `¦­ºø ¥_&!o Y´îöÕÂ×êþ­}‡“ŠNýª(ÔÛûi­´ 28/ÙK† …—0"JR ¤át@—¯7t­Ñöê$ òÄ¥è%NHÒ€ˆ¿@%¤à˜xíòJKŠuhµe�a8x7üÚñ?® ä9Ã/Aà%fû¢CÍÅ‚ññ õ‹½Á]á>æ|L>#þžÍª~ͰÀ­é×ÔsF± ¸Éèò(b G?ù�Žn¥_œ3}¡í¸×`$@Úcí­Võ}07,g¡+Äê0P «t@úƬÛãßœZÖøŽã¤ºB¾!NÉ%V#um¨ˈQ}è—¦ŠUNÌJEJ+'p¡ñ}˱!lЇ¶/Ep¥äMé•Ò¾ŠX‡ Ð/ØŒÙøß-×"…¢ôŒzønØO8ŒOY߇ /…tgµ*¬»<â •Û$xÞ7°gsÈY÷Ã_öîì…QG„œ•ykb]$£ÃYÎÖI³ô¹±û™{ŸG’4MﱟîN2‚ÞÁ¬Ê.¯šÚ˜QO# ”—…£HìE[ À¤°ýwtl4ÓÚË AüV± „=½Ý¾“U™9žÁˆà737ÓdVÎh¤k Èc A'í³ïûÞ÷yeè|`0èáöpÚM:Æ ÌRûÿNw¬ŽªÊÞÀF·ómAfë>k"ì¸ØP¾Áv¨áU§9OŸ6ÑÇßeP ˜xG_†ÁÊé›­SìÞYÞOXz˜¼l™Ìæ£p—ó… Ál¬Úô±x’ÎC7éñÑ3±]¡ÑƨÊû¶ã€Óÿ'£ê;|I;½ùê×: “ìE¤Cχ)®ºÓ«Rcduf]ºœ5E`o¾ç±B¤F[æÏ†¾ªY5iU›ªÑÚ£éuÒ šÝÙ”› KÃQ Ôó�ÃY3äè%Èö%Yùà,­ t/®]>Egg^¯³b ŸYÄ”AÓÃ>2 HCŒ‘@ò7<¾ÅUüCÐèŒ Efèå;²wL€Ý?…�-kþ~ÊábãÀ¥Cj¬c*ù|Ì80 ÍQC ßMË¿ÉÊgcÜ`yŒ¼Ñ§ßÙÒºE\£¦(Ãp¤‘kÆ!'Æ ðuÖ(Í0&¼ây͇)í% ÍMøé÷¼…—pq¢ùŸ·6,¯¹šâ z†[ãU=xøfÅù5ö+ì^*¾ú óL\Õ29ÐV ³[’Áë?ûÑæ9]9e=Ä·k»Š9™Âƒ•=?óYßÐ,ÍOÀ×ãò£e1ã[G¿ÇfˆÀhO¯˜H<ERâgž¸ è=)J1äHÁ dƒ�yKÿ9~Ì.âOï¸ñµ@€žÁž)ñá™ø–H“𪡠-àæä~Œ-Éòk‡;ÇO0$ÞÑ&/k.#ãrøs4‡þCI¡€ ±#¿f7es†¾a3°›Õ³u3Ycß‘'†Œ"Rhd†WuLÍŸvLÖØ†l«ë®St)'#$#åþ‡°ý»ø€Ó¥´å°{WjlÄmj×5»¨uã>¾ËÿŠ4æ°*×+Ä”aÄCF¢Î´±Ê* „DZŒL–¤ØöÈ�FrȨxØ6j‹kP0©Hߣn»¬ÃÿÒH­3a•.¢±Û[¦§~Có�H– _&¢CJTEZпªw“æŒå‘šÖ\~mÇÂ’¯T/Îb|a]—…9û{vnoØÜóY7>«¬g_*Fª'”q¨­B…Bîìð Ý&ìwñíÄS‚Ä$Æšá_ŽØËùkÅÄÔÑŒ#æß2ìÙÍx·¦_ ¸bçš¹„Ä#{ËxÁøbr=r\C#%™$w‡¦ŒïKÖãv¸œßzÉD QïEËd͘R™By+×:U¼õ}ƒ!°ŠÂ’1×åëØ6 ÎàfÍ’SÓ੼]—Õ4“j‡%ʰ©`\>Ue÷ÖJçÎÇäšsK YŦåqÆ(àa(l’F¶Hׄ)Êf¤5qEWÑ–œ& xBNÌa ¦–#sSØÅ…å+n~0fÕ›i'/M®½ � ÌyIÒxH[´A „ÅeÂHÈðàZ.füáÐÖ)ndm²+¦cÔiV\Âÿlr>åâ’©Fä¢GÜ–(6d0²h‡(HÊ‘ n.ê¥0mfŸ…=wøgÓÛúB5ô{…ù%j†.H9B“‡#;6rI¯‰S’!÷d9Ò’ ¡ ›òÇíqb,3´\@qÈŒƒž>½©ÿ }Ô‡KÐl©÷q‘ò¼ž2`¦`Б³‚ì‘ø ¿æù ¼©p-ϰ‡kFS”¡Ÿ0ˆù&±ÕõcÞ<øúbÚ$Ü F¯ÜTøšC”ǧ…ácËò.SÏ9ØÀÙúÈnàa ÏTž|X!ÿ niq†¸E<#& ÙÀ“ç{{n?z.Ö§ýÊšCt»“doÙ¬ø‘;I™azîó¶k™ªúÇVæqE„ßVð+n –à&ÂŽLs¡)46#¨hI0Ü"ÆxÃÆ"AûZŒ›,#Mq%ÂÞKyaÆoî'ßuf5w·”#7ŸÄÓ�� �IDATº1ã³»IV*iöᾺæl¨{»y¨)ÅXêLdJØèïâ(„?VöËcmÀæSÿÖüŠ?ݧ¶3>ùû³Ï‘%ò lArµ0Í¡AñàT3–÷ФÄ`Œ¤ ZŒ”‘©‡fPìâ !ïQX¯á;%œ1ú*Ì¥Âè:„FqP~Âκ_ù?¯›å²Sã9ð&0*Èvv'ÊRó_íýû¬CÌIͯ³{»qvÑô*ïQÉöœmÑo»ú…ÙçÞO;1j¬¹w±ôýØîä~7 ÿèÃp%‡I|²±‹î÷"Þ¹#åýHv™ž‹€Q$…±±É$ň$ >[ŽÎÐt'“Õò™«5 dUÛ¶ WôS˜4 gL@Fuܘ~mwXW!ÂS¾«³¼ÑàÂS´\B±ª FT6´V�˜a…¯pýèÈ8‰=ÆuÓW8xÓž®œ=l`¨Y˜ F%ö|¦³‹ ö#©ž„®Õrb~ìíû©½xÂæÒÖš&‘ÏðÙš�ù˜ÈÖÇQIühWž¢/é5ûpœ³=CßòpÈSG(ËmàkMö„:`WMƒ¹¿°Ë7Ú=ì|_ýΔ®¥mƒ«Ž?¡qùµCŒÄÏ(22‰ÐŸ¶¡kn`™îÈÊ%n/æ™=þ€€‹OÏ“Š C©ùÅ),z·gøÀÎ`<b}œ…$ƒf€m Ÿ°4 ùýÇž›[¾÷¯iÊØI†?¾à«Äl"D‹ƒdˆ» Ôp 6Gç –Áñس”Ü. \IZÂÉg&>)þg© ·pQ‘Ì{´á¢"kO·Š‡1“œ½Å~‘˜€‡þ1%ÜŒ~à»L¹º$hΉnOÈ›ïÍí3TmwˆSk¯é–§ì Oá±N¬X�·Ü+¤!÷Çixc÷¼Û°xæŠÅñÝäOȯ2œÉ6c¬°SRÉn„‡ßFnÞÔ|ß,O/qLÌ^1=uʺâþò2`5î¾8Ù&Nã¿Ãt÷5<‡oId¹å62‹èm‘0döxqØ[Þ%ÆîÎRâ÷2vÙd®Fļ<§«½3·¨z„¢Bÿª,Ti¬µÁ‰GDÃ3Hš‡éýb´y­)¤-†!#*]¢qò·vznX#2—2åBar{Qº¬=Š4RÅÿ¯Ç|6¢°uæ´îKùKü}º­Ÿ¿‹ô†‰ë. ÆDȃ3))mccÒ!'è±cxÇsËCÍÅuF®±¤ñûfÿÞt\Ïͳð›‹nYÀ°ƒñ1Îo1áÜ’i YÊ·%ÞfÚ‘Sj¤A˜N>0<Ÿ )ßfùŸ±Å–rkRSæò”u‘5)ÙÎÜ`ÙÚ÷ÿHñ÷ÉVR}íµÚùd…=Œ'²´{› W€v(‹Ì™ôàk”dÐxˆñ™â»ÀßsßÜò]-ñúnóª#g÷úónÞ °E–ˆÞ7awVn€iëF3¯Cà ëùæ=Ùúx!4‘{Úƒ¼É9|¤Ù•¬#™FŸbý€ûœ~Ì<|œ$>47ÜglG•1ëÁƒí·rêã¸INÞO+,&wåàMê {\Á›_r1ÃB^`'Ø+é!¬Ž3 QcWËÞ*BËnÖÁ9À­à׊Ì1’0=hÙýRñ¿X£¼ãN¿cðšpjPö-[øqFPì²w˜–t‹>'Ⱥ—eØW$èzúÛõcAáFàÜà+R{bK4-ÙŒQà°2LlÁV -æ#®Âµ<Âú_óð| °v؛壿YwÙ ûŠQE ›3 <;$œCr¤pÌ|>raµÅúyìîr`ËEOy†Õ8 ¯øÃš«Õ!¹&§ŽâgÊoh±3\�øÃé ÿ©­|1c±ç&ã/á Ì€I$Àðð‚ýˆlD=Ô`‰šÎ²q˜>ñ�¯s,‹ 7–s–zX5n*–;†t¿ÓÀîX°ƒËaøD‰ÑlÎÉ2nÆ�æø¸"­&ì,Û#yT\gHÃ`‰òî[_š±¹ªîÚnÁü0‚¼ãÀ¯'·Œ_‘˜ÕvmÞ¯ìÀ¾†c© §ÕÖ·e¾‡Q¯>ÍÔ¶T ù+¤f€> $´¤WÄKvš'ÁÞñå¦Ô”“oxj)£ ¥.ˆ##¨šXÕŒ>ÕÆ Ï䃨 šmÅ…én4™8»K£R¦„6å&õðÜÉ qF'c±…46WL^E­i¼áIfîeŽÉÌ™¸°ƒÅ·öü—wt6d1ñ!Ïöòbó-ú<þÏYüóXÎ …6HÚà-ç5ï§¼ŸpnØ„DlžÙ½ã¹œûÈ8¯ÑMáxÝóàX|ºÔ0e®yMýYnŒ±[iMäJ™™©sÝdqþ]½y~±S僱һ¸ö‚FÞ"¯PY£óz#›ç¡™¦Ú]„½yþ×}7ÝéóáeÆ¥ì³Ôëá}ý™ZÛqÔ9OJÖ)5Ø!CIâ–Ü‚#å 0DLèÁ½Â¬)VŒ![ð?ÂÚi)/ˬ°fç"<χY�ÃyB ‚@B4QWÝykÀ§u׃{&zäÀw ^C~º¡tLÀ?_wÔÿdXL¸Ì“€Ü°W„’ÿsÄnF§dËC™AßvEaã? Ãd-Uw ¢º‘ ôfÜ{+º¸Åíp‘ÇMPiÉGDÐìŽÕtKšø!ð‡öa[qåx¸€œ_ .yR¸ˆÛ£ZΧ‰IªoØ@Koéa0 ±fOð‡5wÈ•g´Æ´¤k¢ºs×!Ž‚‡í¿Bÿ9ŸÍ½a2ãvý›Åbnv·HO¨ú¢Ùû#¼¿fy:R–k¾^“8-«½…h…ù3é[Þ\3™òÝAr#`;'À¶¦i–pu‹»¢Ð(IÁ3$B ‹ k¤A{ܨÏi†–4C à"à žÿ}ÃÍá^[ShÈÉôO\ñÃ[Wä§„¸Ÿ)¿a},¶‡\0þ¬{ ËÈ—q�™†À^ÒF–š›Œ¥íà"z¦žìO\þ7l,‡ªºüœ«Œh¶°æ“ÂÀOÐÂQS{àsØ·PaÇÄ{‹Kô9zà""2†Ý19d¿`«Ð¿$jv©v¶q;ÌÛD–Ê+YÚh§¸üô»Ã„`ÊÙ%…†ÐÀ½Ç}Îâú¿Ã„[Í|ÒØòÌÒs·æ Fk¤³£AÔ`‘š½E9®ê~oÖu­ÍaÀÈQ­ íåJ¤ ˆèíî'÷ŒÍ…òúÑš?:5Ñ,œ¬|Q5ª…–ÍlN@në}xt9VfNà MvèBÇu2Í^ß'­¤F'…W¡Ñ 5ú¡LÛÒû³!ÇY™ô°u<~0ó¨± S®®ß ýƒÎ’› ¯ÂfЃHƒ7åqÄ2¸ŠèH;=¿okÊæ®`bš‰b6ðÅÁOÓBÅ2ÇR6!ÝKéìka› gW°6Í›wwßµP™×­×t ¢"ewÁ”Aïï³]çd§†qöêÜ.s^O'¿(ĹÍô°‰C³~ºßwäRºŠ3Qi7£Ïð–EDîˆ!ë¹ãkÏÆ°»€@„ŒàE…hé«ú/ÎÌã™}°Vj|0oªúbÝ0}f4abHén%Þ¨Ö›ªWíïŠ›ŠØÒì,‰`upðÎl©{š8åÝ!ÜI0OÜ>ðÒDtƒÎy ™æJ#Ñ‘®<¿PóóKŒ®eh ïõË£ô~`nÓX±Q;ú€ t‘µæa„V ¡±ïaŒ«èÛ£’Ò¬ ?…—ý›…ÄÅ@–ÈAKˆÈHáèwFbý!-œÒŠ�ÛêPøÓvS‡׃ŸÂeùœ•Ûal{܇|Zlì%BcÃÁzŸƒáxþø¿LMæ1ëÚÓ8xxqâ ³ï„×Ðâàé$9ýËüþ�О’]òZó Xx8ÉùŽ2E‘‘Æ Ù3!0ÒˆHaO\ÜYJ…‰ÜKº°žGˆ†?ª|ݘX³„¯+LDjŒÅÀÇÍëÍ5?NùKÃd†,~¾ü³:ª¯®ZnOpV> ]qSa!•8…4l=›5Ë)h–ñ¸¿84ƒ­™l­É\=ÄE¦¹I,ÇG(ÓæÓ´C¡:!63†ò©ÙÈà6 %ð y©("ƳÿÄA¼^3º¼MÊ_“Ì}¿ïünŽ©¥4cl~f‡_¢gæÛu­VÍøã:ýk0º¶£FlLg*Z£ñŽîc¾EYqÞ2ƒ˯¸:¼uðY[g4ù uKÌröfƒ ü+ßì÷΀V^Ð ñþùÜÆBÚí³ÃwI•ëe>¶éFc¡Hé‡à¾!…ýò†5?ÂÓŒäÝÈ2X3|Š=jÀ´ ³F_`B—>š˜|0]8<PëÝ”õ4N­LÂŽ#Ö?㌧ln,+â¸v¢±Ô’3Ô…·$–#ÛŸq^¶ÙK¤ÄMÙmyÐGYÂCŽlOÿt×%Ô})»«8?ío˜´ü{ˆàZ¾žÑ,²ˆÝ¸G(ã¥bgYB$Ä@ïynçÀM[ŸÓX*¼ÊíPâí‹ÁJüVh†IM"KüÆ~Ñ[a2k:çjõ¾‹oË¡Í$R`c[º’ǾL3–$û;©KáØÞ‡Nºù¹fkÙÂØ`o)¹AV„·M®ï…vNã£Ûåþ¼mô·óŠ‘ÅNÁ”É—«_9m:1ƒ5~…np… ®®™L93èaMZ¡h\…3ôšåˆ›ÄrÏbÄ¢ãfÁò¼”kpáH»' ùaˆÑ$p¦‘àá’ÞðAs¹C=5æ2à7Ü)“@–à ÃPã› ž[<<\c+$d_´ÜAç'ë–™’ƒr<1ÙiiËh‡³ Ã)ðèq]Kâ¨rœTœ·ŒaÔboQ |ãz_œõXœÝí83Þ†3­kl3¢ÞsS±$bÒþë!NÒ]þ\âL¸¾~Ñ…«9££ãô뀭Ð-©exê¸>2â–ðº¢4§!Ïa£²ÿäL¬Xðí@™nPïQ#ÐŒr¤F}`O e‚‹àWìàù–~qäÂ}÷©îæ0{�öÓÍë”Å%h^BÔ?ÇLéáä}>@ÊÿBÒò×àZ$Pѵü_×P€çF³LܲÀ8÷Ã]A)1pOìŠÓ:÷S*øÍ'¶»¬åjÆC`7ÌcÛcÉßC ´Ä¯È2db¢ùLc#ãˆôì6ì[ÞþÇÙs9*J)윒ô:ݨüžàd†š¹bç?£9üáòšý”½¹³—¥.Œ÷ÉvQÏ=pÂxd`®)§ä†ñŒ³5zu„¶ ]3žÞ)SŠ™ÑÜC'>›‹3¤ED<˜#‡Œž|Í–nšb¢K«z¿2£[ÞŽ†ç_ú§~˜¸s£GVVK$C<—!j_º8JúÔì»ý hçé—º®1 Þ“`,Èûy*²îCÃàÉó Y†÷kuWÙø+&ÊÛ×|÷zÁ”»¿nK93Ø{A7„§ôá"ÌbéÜbHÍͧ!`Ëò@´ÙB`±…†» Ù–åßÜZk\ï)êõ|¼ïΊÍ.yi¸”~žgÄX{Ùx—ØÕ#{НŸŸæñ0}lfµÛšgsìø Wõ5²1/<AÞÿ"9 Cr\ã¶u¾z’Œ)€cº_ü­{”¸èb˜GJ|½g? �Kn0<Z!_ rTBœãS7 Æì”/l÷cMÿ¿:ª5µ¬ ­í_ÙtIÐfµ£9 FœÃFSF—X|̶ܶø2ðZ‘ÁÕ„ð|97i¬Â´b�Õ##qx…<ñG§h%ÃB°÷„§:þ©I0´xØ]ó‹ c9ZÜí)q&‹÷Áw±˜®Ù­ÈNö £Ó¾†ƒ1;Ý‚A%ô�ïsP‚~@ ˆ§£±Q!Ú“² Ä5vŠ6裂"GÒK"5CöBÆ‹wÊ93yL38¶¡éýý²Ý€¿¥—á]ÁïŠp¯|9´Ö¿rrÄrÄÍ-y¹§8gbQàaOðûOöŽ£â²;£�YàÆÃ'Ö«ãQ¾åã†÷è•ó™FX8S»Ê¼ÃŽ[ ì1ï®ë‡iîÔþ4¹ñ~MÚy¾]ÓC¬È WšËï7ÙÏQœŒóSÖ’ýK­¸iý×á#õaÊmÎKAøò™7Ïô¦˜4Ê–‘røÞú¯\ŸñÇCÓ¸9¾/ú“¬ˆ µ¥Áö°ÑŠ,=WkÜ Ý‘Ÿ6mæÄŽá3†™a#¦‡·>¦JÝÁy[OfÆî¬Ð6ÄÆˆ¢¾M]ȉÁ¨èµîŒAV¨–8E]btIQÊú袦?c÷K–UÃ[Xqå”ò’ìl{úž I)—eÒ¥ Vàz+ÀâC„„v¨†¬:ÊÃ=sµ¦9(Ä÷»…+AV.µ^]ÿþü¾•îsA õ‘ˆÆrmla¡V¾Q%¶æ<rãYX.ÖŒhzƒòˆõ‘àVœ­”ÕÃO‚áÍè;ðjèÖ(4IØäßæcQ*Êamn0$ß¹õ¸Ÿî—/ìM>,•½÷˾c˜/÷'5Áô(Sá-À¸­‹ë3;µÆX&Œ¼‘®xߘÅq4w°Èø çŠA1NXƒ±Ä¼IgOŒ°e¼C½§X0ƒ‡pyØkvxeœö¨uÊW>ýÛfŸaú k»Á0`•·®SÏ‹&r?b›°·Gõfm-ƒóuä¸àI½6ù´Ž41°‡]Æ&BNÿ°Ÿû'ÐuA“)ôˆaz%Èh$÷¢rÆà´F~¿mC_‘Zµ§ñâ1iŽÈ÷z¸,°‚$qš ÅÂñ—KÉUÄI�§‚$±W‘­ vL] ¯1 ´bØwÿ0”Ò˜Ù½Xw=s “ç+Fõáƒ]ºTnÅ(„m ø1ES?VÍø˜nO:ÍÁ Äkö~ê„\ }€=2â"#”ºúW„@6 ýqޤatŒÊÀ_"u­B£G¨ i®4 ZvÞ3ö;C÷b;èNG‚c½ça}60k_Ð妯·¶»Ê>ú¼–u&›‰dd8·èÄž¯ùãÇÕæÀrñÓ(åk0k$ÃÄsµ&ƒ/áÍÇæa °0à¹Ð-ÿíìÁ-èf?»Æ½Ñ¯]\ùnÚ,ÿ%ì×,§\œ'¬±ZŠÃuó“0°ì& ëòŸú—“A¯¹™²4,g\­QŽø–u…6ü¥æÂbþ™‘d—±Ï°9RÔnk¼±©²ý<î ãšMsbÿ4¦¼K”c¹·×™Î‡È7’ïÖ<¬( «ÈÛC )²CE3DT@'Äšð'²u*rg4z}/qÑ0x×^Ò<ª¹×jÝ7¤'¶ÄŠhØèz83*Ú°AB0›qͤ¹õ,F�WŽ_&s¢þ†ŠÔ2THЦ¦0IØ4¶›-dFÊ:Æ&öŽÉ3¼Eœ”¬áTW$GÏmAg@bBë3º4EŠî«ë̽یÃcævô…SÎ4ƒEñ¨Y¾ÉÈš#þÞ·DØ@Áˆ–ÔâÁWl[zøýKCþ/ sµ“Û‡dGCú“aUâñ46¬¬‚P™¡ ¢ú_KS¿Îÿb:*þš"ôêªçá knV,¯á7=ååíÝŢ̧¹¾4Q'„‹ÞöÏ/ðÆ®ï©:ÑÎÓGk‚ì¸Ê‚ãx}lO[ÆðÄx}DÖ®/ü#wï)Y™%–Jü»vè+L5NÃ] saH %°Óyx`³©÷“fë¹ðŒ®au˜‡öXE‘¯¬¬˜¾Åã-.Td­“x^5R#5xv=]FžŽÖ$%H{¢D=7*gHÍÞà©J×È)…é¤'MÌ`ý³ˆÑ²ÑÐÞ)ÊÈ™âEl;7›÷§Ã%ù# ÿìó5BŽ0 9àá’<JþnšL {„c»'óô-â”ó f9Ù”  ÙUùYÙìþÒ©ýˆ#à:‹ÕdÓ™¦dÿcÄùM:“¡6.Þ¿›uÓõ<9=Fƒˆu¦MºäYãƒÇ>“4Š£a-¬+"„5=d†à‰ëc)¦Šhî”þÂÛ@~ïuG>׆^0Dü0w’>Õs YscXöÜ–;XÍêlÕŒ@Tôíý·ƒ?ÎÜÅΗy3Ú“F; "®B¶ô‡Õæè¤ýýx£ÿ8E*lËKÈ9cÕiÜ¡Xæ|û úñfâ²Ûid0OÕ]Ÿ:€Å'&†ëÕMP ¾?šÝúCQ<`;àâgª ÿb2èO ×)Ù%WšÁà &’ÏWL~ ôLg Az¶—¼Ë‘š!4C¸WÞ©W¹ô½¯ªæeK„+êHsÜW¥kKƒµ8=E\Rjö×S®ùý”o ã·èÕ‘Oø É2€ˆ ©=2€Køì0ú\u€¯Ì¾õ©êB€D®q°‹ ˆ¸5BKúŠw¶y÷•u1qî1~,« |Eþ÷d3l@Bl=½%½B´&ž5qt¬ë›Ü™àŒM¶£ß?áÞ2ZÊzê'Nà©tœxÎ%jCc*0 i>Ú«ý¾ ÿx·}[î1ºðªïœ+ØÂ¥áµ'3Lj†-~q¤ ^â0ÃÜÜH×¼~A̘ç :¶0Žq’w'§^Ñ ¦½?°nBëh½¢’œ§`° ; ¨w†}}»h+ý¯§0˜€íËq]bó  vëüóxO9^Û|ê2ƒœ‘Öô+öÃ&C*Hô+ ? ?¼ã|Ïtqœ|šÓ?` |O¹ÄÞà–6í^Ys6$™¬d äÀˆ$IÏðÔü¨ø"A>%1÷¨Mà>¿UFqxlÃêxlÁn;y…ã$‚ö™‡-á™+ø+ÁÅýÄø{\÷ ‘‰?6ˆaJ‰Ðsæ7 Yâ^Ó¾””VsãÃÑ) É£Ö„kôûÃ/  JŒC÷Lzò^'·‘ë€`t„‚?\Vˆ|¥%1芴¢¨ê¥Ù+;²6áƒñUíÚF‡yndñëUŸi‘†Ç¤lN—kmÿ ÝM@Ã×fD®ïòP¦Ì ñ~«»G;p\XŠ u‰ÕÓ#—b»B@ªí“Nþ}{Çì¯zÎöNʰ #2€¤p‚xý†‡]sàù,͉ou:g5Í„#‡fO÷�¿Çܬ}FgòœÜbôå-¾âÊ€f‘>Uâ“!Ï‘u|ˆãèxyËbq«(¸äFæé{bÅ�ü£ç3Ë–úÂ4šÚz¦ ,>]'|ž&À˜#¤à H`W8è2Î럯6,þYRôG…ë§kÅ,ŠqDdŒwÄ\ï ©cÌ1c$~Úvö¯Œ5~<ëÎ×Hîåó†ûþºsÓ€1ifÓÚ:‡2ÆèZÙæKØxSÞ䌣ú`·œâ {ÍnOvðm®ªj_¸T‚y€M[ïib‹ªÐ 108Ä3â}ËøS9\ÈÉ…0rð¹ì´ÀËZˆ&åüç�¸~`0ì=ÖüS¾œqE}f›¨ ¶û”ÑÁïûŽ'vÏÌßsÛñ—-û#Fø.R®1ïªûqÛæ‡]W8¹êÏhr-r†ˆ-)4f‹oæ¶B´5«FTÄ¿b?Áåì%¾µÒMo '¾B¬Q«ã0zÁW¬/y((®àçp>bŸó­æM˜ü&3r, øÍYWÔ¸H÷U§AÃÌçtÎ J6²¿çnïFÞoÍK(*,•¡TmŒÑ† úàûp~b¤;{üÚ~n CÝÓì+ö-üŠt$Eü†øq‰ž‡þ´½ä§oq­1û;%ÿë© —ú‡3*½s<ÙP×ô–Ár® l8–2ÃPáZ¹E¨NÚD|Øvæ jG³Q‘ [èá½g¹àæšìY$÷dkàíak…ñ˜5bÅÖ€ÆÈ=Ù§Ò%‹s"º…v,±#ª½]Õ‚&Tô`Zâ+â 9!Yz…J„‘ýˆÖ¨‚/NŒä‹ÈX0N(‹ñ y½ãá{3¾ ¼†_žÎ#Y!Û&ûÕßZí¬FE·×~Ó6l“Û–PÕ: z2ˆú8ìžäÆõÖ>äËÒl½PÍFŠrº-u´Aºu Â"pëyÙI¡q–Íá#QáÛcôÍ¡§ÙŸ€Äö°½þbWœíÒïö&äõÊ0€ <xÀFÜÆ£¼ðÊóв8¥­øØŽù€šUÓƒ«Ð–ý tDyÔ EË0£€ÿ>òÕéÊ9†ŠeûIŒMŨÅjÃ+ä%ÖðíñWïx0,4KËl º¢oQàgè@:háï‹Öh{oèöfþQúé ú%LÚ£Ú#nÛ7õö“>ægdt/ÿŸ ×;Ã0d’o$™F€õ¸1¼cÿ=ºÆk‚bcé-ÓÀx‹oæññ²vºÉY†^•P*l†ÛMé.ßNµ×Áß;f>…æ°¿B’Enrˆg¸R¤ˆžá’^³tˆï¸l1pÎa†žjoÓƒù="‡ Ð{âæõ ïoY§<ó—%ëÌ6ÖýF‰{“‹{EWæsíI=ñûšªZv·,¯î¾—Êï­ìz5V²Nª)JÑq‘cgˆ5Û†^€ãÇ��ïIDATÒ_—aj ãâŒíšýêh­§¥ƒ‡É¬Q  x¤W$Cš5iMtDC1dœ‰»,–Vô½°4ó\¯Õ‡@yhJ^°+ù³å ÇeAþ«9œ0$޳ìw¹ÂŠZˆfÐ8ͳæÏáWëк14: žº¸†hœ÷Û¡“×Ä)ÖPx¬F«#ï®ä÷6>õ—ÏïçÚ}+ØKgƒW²cbɤB*L J¢#ü€ù�†äÉÖ|}2ê§Ó.À@¸‰+`Zeò¡@Y^…Iòì csÔþŸL6 =´ä×Èé5?—jšÞ¡ ã Õâh¶Þ0@ØFÞôG´ÍrÅ_¹#vì°S+pYû“j~øŠG‹ô¢Nœ… Þfà=­ ¯‘SŒÁÌŽ¡a ƒe€Ø ¼s< ¼ê~$5È 9c¸$+ø&rn°kÑ¥ë *Xs å!b bˆw²*3e ¹#¬³ÐéŠl‰§T}Ö0y‘¬’ÃH¹íï]wÓ°|eަ;ëot³TÌuM07Á.½½[3žšhêo}£ÖœµŒgøÀ3<þãÉ,uö´¸v°là™ú?M¹¼Œ5bí÷ÚUMøk.·dg(ÃD¢r⸣¿ØóYDô¸â¸Ô9~ë#<Ã9¼¦9€ê\ËPa¨ízšZÌšòÄ¿Ëø ù{ËMb9Ëà ®™N) nF¶f¿"^â/Ñå°à¾ÿI\tȲޞ–££5”Áû2­Ëˆeåþ‰¥÷oÀ Ä“Ù"ž#ßzS¿ùÙóþe…ëÀ=×ý¤ùîœ× xÜ×ò®b)4;Ëb Ø’oÈÖdÞð¨›íˆ!aL­j#ßÚae/+ó£Q }voc2½|~R•ß­»,CGŒgXsù‚ É—ŠDˆ‘½¥ƒ?€á×0œ‚9GŸŽ8IfŽÝëŠù dO¾°×|1%˜p`G´H©cºâ,õy„¸!çJ0Õwf\êÊÄö>ÑI5¿ÉÊ­)E²6ºa‡NŒa£›Ë€u°&Ó|£É4) ¶µÀè©_Z­Ù3P?ÓìNO'üxÅb…lI¯§tÏöÝqGç@…r¢K#mR® ¹A™;Q•©5‘û@çoç® ËYf\IÔ1BÔ`˾'{ÁD S#)Ðç0"‰ƒv¾1žM@i2 Ã<ìÙR?«¦Ë‰Ÿ#.A Û#Þ¡E†ÎºhѽI½ŸeÝ6²³–7ÉŒðè®0˜DaíëøÔ¤¿#8Ì‚ÄñË,awœÅ«Âîôp]„/m+õL†<×~ˆû,D½Cï‰ùqE$$J⟑ÏHËÛ)vg ½fŽÀö½Ç¶ÇƒÌ´¨nKrhxùžé‚«kä”p†Ó¸pLêWx0íqÍsˆ‘9ÜÜJísñÁH“”wzý4j˜úlæ`+C“ 1'HœGx¼gÓÓ¼—\$6=#°×°"Y4ôŽï,¯ ¦–B)’B’µÜ@ã aák† ƒ(å¾Þ¦'§'N?ÿÖ?1my‚ÿ�7Sâ%Ù9Ó¬K†Á= å‰Ý²:¬^ÍÝØËÔeW‚‡Ð„ýýrën×ÌVîoªæ0ÉÁ®I¶ò'ÞAvª ê”{s ¶ÄªùÚÜ3ÚùŒ‰ˆâêÉÝþW· ˜‘Í8“H…Ò<Kn,KÇ]ÏÌ1ûž´8þ÷ê“ÀÊãe îšnJaH3Ìq Sœa?C¬±ß£oÉöŠ×YÆÕ%çÓ”Ï/É4ò€ù×ì Æ’RÁ Ür¾>: ¦Ü˜q}‚ÑŪ޴g ;`=8Ì®­—4ÿÌppÒíÇó3¼ù—nêËêÿgµá¸‡XÝe”}eì=Ÿwã9mè×<À¢åfvŒYßâ¹BAš1\âQ£óFù{;u€hM5Ë_ U(—§NLÞngA¢×¨.FñÆò¹fƒÇG¨Àµç±%˜œnÜû“î%;È¥OÔ åÐüšUSü%çš×‚sß¡4ûü ä¹c¢¶Æíãvâe”©‹QiR©f6Z'˜ú3ì(ZÝ£·&ô5YÓk\€·¥·|—óÚâ Å3Tæ>‡f°®ÀcšPaÚcÊùAøq°ìÓ"Aµ¤ a@³³$xgCèþïöîçE’äJðø×ÌÍÌÝ#"32£3ªU-W£É& uXš¤K_–tØ¿eÿ–=,ìu 3G‘Î.lCò¦@×–TÙ™Q?ÍÌÍöàÕ¥VK­_£ÖLۇơ»«#‚èLnÏž½7jgC´‹F`ĨUœákï&ŽIÀ´X .ðßGF~8è€^ 3¤Gl¡@DD‰TÈ …áCëYÀ[G¡ÈbD€Í¨þÕ�™S*tDX¤£]‘i¤C´³Lݨœ½šé¶.7]JáæSxÍì§¾þ¾&dœHŒ¼ÊÚI{¯ƒ½ÞúÅZ݃xA¾$̱ðNºz¤>cðk™ÀØ 4¦]ŠÿÖï‡êÿcñ„YGCV"$Á£WHh?C€¨ÙuïQ-ë=o‘Kä¡ë²©ðK2ðå.æÔ«#¬båÙý]‰C˜ïöÞVl=XŒš”v²]êž!»¬Y‘…¿\˳#1|ÊÌ¢õì!g#{Ì’õ²?8}6&7´°)0㾋ѶûÝÜ!wø!ëH‘á»ñM?[f ' ƒrD;œµèˆ‘ˆ@¶ÒÌ2ê�“ÃÑ¢ªäI¢ÕMNΈõ'’WMWb>›Vu1…S¼âÏj³8«™p4âiÌB5ýj@ƒžÃ9ñ§«17çÜÍ9;l0d *\Óÿ’†ÓETøB·RÙø‹ÕúFB¶$Ë‘Ò $Úp`‹ÜSlû§Ïx¸M=æ%t‡ÊwÓrÆŸ2T =]‹XwŠUxøc·PÑNø®¥5XÕ÷U}®É#†MÆj‹Ñ´-Ú‚%:ô-yÅÙg\^r{#îÆ°ë‹zW±™ÜS<¢OˆÇØ·¸Ç÷C·†8‡1^/‘ó÷J¡¾¤ù«‰ ï–3·�“ &w¹À2ç¶âh¾˜ z²$‡}ÆeÎmÎë–Á3Š9Ä’"ç^óX0QìÕBiDu¤š¢\òÔ9™Ð­Æžb¡U8Ù ˜3qe8+Qœdo ÎÈ–ŒáVë¦_NZ°ðýøÖ.±ö9ÆhŒ#3È9±»5(>ð fE»»ÚÞ~wq9^g¥Òƺ(Çí[Â=—dh™›xj<ØÏt;åÕÆý(Zá÷–Ï\¨êuC¸dqK^±ox|ÁEÉcFŽh Ù|Á¼V8áÞVŠ1F“Ìœ‡)q‰œÓ6„)m÷“í™J|ƒý˜Ç=¢>‘×Yk‡‚1Vïœ\Ö>Ìv¥Þ|dž¦f³äÙ\›fVü]ý=73eëb…ºE€¯hÁ7ì?!38A ð¿$ŒÉ4E ÊóäÈ»¹(š0"h™1,(3ŒÆFÈh5ñoðþ*“'t&®‰ ¸éNØf6”Žç®þ§È­áGЍÈäDÊI&ÔVþ€TA¦ú$[×ßæ]¡„<Ôvƒà/˜<ò!”-FÍ…ÇÙj­j‚¿í7ôÚ 7EA´#X_ –0ÇLɶİõ»b_óؽ×9Ã1êÐ…MÙ~ã+ÌW" Ѱ¦¯ë—ȲØU¼mxjØM™0otæÍÈ ×X]írÞHj&ƒáL j$(Ö’]Æ&cày˜Ö•j”V#*Ú1«S¼âÂf¬ê,£=¢-;˜Ñ9aN¦B‚ÀRïäµ4ÖI gcæpu· ›Á÷&SþyËF `¿«íŠWoú’©G Ú�ì5FR¾é7l«ì0ÙFcŒ{ߟ¥ívÜ9zŒÐ‡¾¿€h} ÿål“Õo ë!¯.y™1RèHô´Š(J>˜ÏឬézÅaÎçï=k¿ìBu…Õ¼U ²!@«Xž ëö~ ~L”´xrÇ'·„à "§X(7xÇΡwd/(4“)Ý4±~v<j¨È›‰dòHq °»`qÇâ+Ú•Pp«ÀÕ±ßéˆ ïÚHt­ån™qØñËáûhš™«êî · 4™c*ì°/޹=âX“Ï(ß ç0'ÿ#ÍBrln¼‚f–ñ ;Ñ+#JÛ ·SõÖoß Äˆ¹$tÍæ2†Ï)ºu\Àm!PÜcô9»1o5¯§}Ôí6¢ JYº3ÏÙN ïñôå¤Ûñ%rE¸d”ö¶Ü-.ýã`çóÝ]qÿR-B¬C¸¶Ê¶Š¶o*÷Hý)WÂ#¼nq- ×Þr ª ™§ìs^‹~×Zx˜µºÝJçAGdÉ ¶–Ì÷­u"´K<}÷ºÒÐÎØ(¶–G~!4oœÞ-â’õ¾~:½þYi·xì)®¤6?»Ê&v¢åâÚ,7ñ°¸ÞTì Ì!Wca?§„AÅ éCÈ®a¿€ç—ìAœà™F ŒÄ€ è@V20X5±aÒZãöÖ´ø€ƒVÎøy­?fâY¯ùÖÏx1 3‡Î¤‰Òä3D®u1“¢–›¾1§:´T¹ ß'ìº÷Œá‡Ì<z‰d?¥½Ã]œïî¾sÿrøã >aóKìœÑ’–~¸¼×¸)jÛŸK/Q9Á³Sl÷‹Ù~YK8-iO áöŸQB<GŽ%FÐx ?DžŠÙæãÚAôÜOù<ç\2ˆµáZí¬^D©ŸÄ´K2‹ÐȬ6Bâ#­`±ŽÅ8t3Ë»'Í)ÂpxØktÉ™¸:f’k=º¿.šE˜Ý…(hÕìˆú¬Kï4dSÜŽ‚YA¦´ÕJ·‹¨Pš¶bÐp£%/aïù\1ðl,o¸˜÷QYt“]æpŽxF lÆq>Ñs#ÑâЀrÛýÄVä¡0†<×ÜV„†ÈLŽkŠVßå{¯“l¡å‡×í`a"ªå0@Ø)T$÷xOÏ,ë-f‰mXŠñ¿~c Ý2¢a謗yXÓv=Àx ×O¬Ûbs"°Ç>°_ò ^.q°"#.'3Yä#ÚÿÍþEPÑ@¹Ð‡wÜJ.›ÙstÀœ .±·ìîxÃaÑp1¦?ëð®TËÀ{­2þzcÃÝQúPÃõ v«ÏãÚiì´/iïKQ˜’wû9Š›‚—ŽÇýÿ¿‘%?äyZÔŽ«¢ANuÜ:§{ÏJÍGÝ‘¥‘õ=ÏZÌk²3dNP(CæÉ¦`úêàEÉÝ–«C©ÙðP±ðn^RV‘iÚ/ˆ‡£ Ý™ÕüÐ$]1sh ­Ê¶ –?)ÖêǹǷlYXËÚës?m'S޹Q çfzNà~`b1+lI)xÉŽØÍÐíê°›©ÛÚ½ÀJÖ´]glEì%»†§9äŒ\aоÓoðL<:»íø™ÙÕê‰Ð"Oàhá ·J_xçª Ì'‰¯ íòií˜Ý3lSHG ØH°¬=‹Š²¦?Ä&›¾Sê„[Ö/úí“Ö¡KD æ3ëQF.É‹Ù^ë]4o…züFG÷Ÿ—a¢åÙµf!ìZ“ݳ³´ dŵñÖdèc« TÝz„Ç)˜â‡\M‘]º@s9ådÙ7Íͨ×ÇØ[ —ìnÇ÷“Åã�`£·�ÛnèÂ%ÛŽp†½BzòK3TÀX^7WÁN¾ãú%‹ 7¦B QŠÖÀivÌuJÌûÜvt˜ˆÙ•M6¥~׎þ@Ù™$ˆ–`ûí²Ý)J ½¿’Ü >CV(‡tH íHÖ‘áÛ«üç“ÝÍȳ˛¶šàØ/ †Ý“1#&#gòƪ êÊ›É:ÓצZÍM7”ÍCôè&ª+‘7d~&†+ÜMW�vfŽ„uÅ¿4Ý)ð]ØŸ£ÇXMœ–ˆ1j@«f™×&b\…mtÆÌRwÛBþPh'¡ôÉ'ÍUÎÄTÚ ¯ƒZ8s#Ái²jB31ÑÛ˜5ÒqḠýIÀ"#kÉö¨Hð¨Þö{ŠT…=Œ]úÒ£í¶p³äSPz]í—lGì°š¡#[ÒVXÍë’G8±ä[ö÷<6\ÂhÎöÅzh*ìà3lÅJ£,ì%wZ.<¬¸{à uɵÁÚ>×øÔ†w¯û³ØC™yó„õ—O%åïRu_´–[ä`Ð%NŽœ¢ø¾æwÿnhÉ>çN÷'˜ƒâWš¼b4ÁxJ‹PxËÖ+|sc`´œIê¨ÉÏs²ŒL#$Ž™Ôõö’UšÒ±{B]UJIT„16°=âÎôEåÇEÓ÷hõŽ´a?¢ÍØVçøYÃóŠ=™Å(2Këk_]»ÆÆ ‰5z›—ÿóÁ+ÏÙŽõgo¢gïfÿ¸¬¯*¦š‘¼ª—C¶eÓ§®3à˜†Á”rK®ÀÓ(ŽCu5ò“ã¶ÕµÕ‹½ºy%ø/)�ZKæ‰×ÐÕ¶´êû~Ëc‰—ƒQˆU,ígxðÿÀ£ºy¥ ÌPõ¶aÇ, ·˜MÓ ÕŒaíG¸!oxÔý„ð䎣Qõ=,CF>„5üË’è7ÊgWm9ɤ.³ë‘_äáFÅZ‰ë,XamÅÏË('íÈèÂf`vDƒœ0•¬=¯=‹°ø8 3MpR,ZÛ7Äë Kü€Éã°ŠòÐê®/Y芲y’¸QN†?Î5Òð¼ãlȤbØ�È[îÿG…ïz)ȸ8åNqå‘ãIùÙä s…ÍapŽ#K„¡…•g£˜OùÞ²d#�‹Û0ô¨c¤†lâÅd­ÍÏ„î Ÿ*ÊŒp¸§›vx £­ÚäŠÉPã/ÉßàHP¡ Ù2Å$g¢1¢²mC˜³¡Ÿ !¾`¥ bvµqÆ, í§3ï'–Iîq¶<D÷`ÑŸ!+â”x:i)ÆîíÛ5²„(§¨%rŽ…Ð0ÑpzhgbLj)œGçè€PSK®·Gv3CËÔ…eÍœíaH™\’ƒ:…2¼z1yÉÄbY¥Ø‚÷”n¶mô1fˆi‰Øêípv¿®Yr1fì™t•?ž Øó×7(åœ_ŒkÊ)Û%'ó÷Òï5λ˜_&¡ÒÞ\Çñ"êé8Úaº´ê9nDžá?\¬ûEêËþQÖ°3äô›s,‰à”…'‡½áQré¨"å~ÆßÙ®‘èBÒòv,ãu_À»}¯Bñůµ þÊCßd ëÙ¯ïøßÜœeF…Ö5 ×LÍ]Åes8^0çq?àRs"É ûbŠ×0‚°aãÙ8\ƒéžëçu·Ý'»áÉ/âÊ1ñ^;wm³Evz“)¼gûÀþõ!"ÃV‚¸çsÑÏ̺ L£æ‹ÜHvø+@#5­`§hÛ%Ïat¨ÍZu,Íbÿ¯u¦œ8ZŒ2òÈËrÉ¢f ª"6õKA1E{¢agxŒ<MùC>ïcêJ°P.ɠД’gƒÉIœmv#yô\�éÈVD…€G~¨i»‡Ç†“)™'BîOˆœü”Lø‚§¨ððèyð\JN|=öŒ+²¦\ƒ}€€UçŽq-FÄ‚`Á&²pdŠ5´/È4nŠë6<könýîç¬*Æ]aØÙ9Ñ¥)°Ê£[2‹`AD8¥ ã@ÈÛc# !4ÙL˜Z zîá'+þS¼Ù¬îf±¨Û Îã7Ä÷÷Ø#BN0ÌZ<8ͦB7pŽ~v“²él°¬Õœ“)Å Î2€û@¾fÐô©pWñ¡ÏOº´·€a?okȬjSÛ 9:ÏÔiåDh÷ˆÞ–Ü¢'];\Ó.9ÙƒžÉ‘δEsf™þž¨ºPˆÈ&"²™]ë1˜Ì¢…ÎG3E3öü¡%ö˜¶`fE®ùØø±š0Õûål?¯ÿ_Ó7¹Ûk#'m­ãõÑÊ*‹ÀÜfÉíµñΨ%:žÏ¸švJ\’-gíWgÚ–6Ó§³RÕݪx(ê+€ºD±¢$ÅžbÕÅ¢ý"*„ÒV¹{¿Ð‡ÿª³›#ÁͰ _Ì.”~Ôf¤MVÒ Íj–=ÔËZr½Á*sÛâÚª5ä°?ç¸D 5WXS´%â#Ì”‡’Ï JEæûÊѯ|´…‰d²jŒa‹®­‡‡~pj;f£Ù î"N¼ÿ"˜ãèO¹wmZöpÓýÉ!w±%§‘áž±ø)ry#çf{ê»ßèx­`ý®ãõü°VxñE jr.ç<?¬×¿jƒúÈ)}åéG®`’7ZO¯ñ ÇÍÞ4¿qhÎòüP'`5‹S†ŠL û;Ç|ÉtwØ�áœ8&j”�î~bõdåŒlmVô…Ûûn‡gBÙ¾×J7ãÎõ'!¤§ðýÜÍ®ÀîVŠ—/±%B¢Gœ>ÃÎ °]’w3žOK~5¾ÙŸrªfÆÔ#Eq‘±ãá ÿ«ØÐôƒú°¤…±Ë)r¶§ýOg×oÊV,ºeÄœâ«=~A®f'Q”¡0™c°Ó'³3]w+\aéÆ.UÐô‰Ô®öãöP ý}͙ôȀDˆ’Md+Ù5,áŸ+Øòi¤\1~bÐC[-²†gè-NŒá”,GBÞÒ VŽÏ·¿%¿E¾ÀœÒ*œgOß%Ôj÷ç¼óR3vdíLgZJ#2#3@{7cU·ò&J2?Ã×Î üµXÙuÁ‰´A8O&@+¯ùtöè78jžáë®ý„Œ•da8‹X‰nÑrPÛ°8Gý-'…@îê>‹¸¤,‰a¦T=¢dtŽœ# mSrÅň»<�\žNʺ×bj1ds›WNêZ*€` [lˣŭødÏ«�\,9›£ ¨0Æ…±Í4e.×…"ËPXĦä×iÛˆÂJá ]ó  Ýã>g·!z\I4²6âZhÛNi±Ö» õ[¸ 8ix5í;ØÏ/„C7:àv,VóúW\ÿ¤²× Váòq-OñŠàÐ~V;®ÛK»¿e[Yû‘³ªÞ šPAÇ_ù¶«ÝÏ09J÷‡f”Bˆ Ü”¶˜-Mý5g“¦ÿ °®8¼UXSßéë mWC†ÚŠÖ®¦Å̉,lÑà‹}·jéŠÎÇøQÿRÛ-÷Ø)œbö‘A00ýöﯥ1b…nfghƒ±•ñš½ÒÙÑL?ÕQ³¯p°Õ,#íatƒýŠçã® ë¸éoÚ˾t*îÂ)Ç ã1 òPåÀvSoùâH ¯ÀU¨÷û°¾;#=€È¥æ?̽AÎû ½Ë¯ 1F’$I’o7™¾‚$I’$ņ$I’$ņ$I’äôåý!DúR’$I¾m¾´Ùü[ë”Dº¦kº¦kº~k®)§”$I’|’$I’’$I’’$I’’$I’?Õo­SŠâ‹kÚÂO×tM×tý÷}iÝ$I’¤œR’$I’bC’$I’bC’$I’bC’$I’bC’$Iò—õÛg‚¦"ÖtM×tM×okkZ7$I’$)§”$I’¤Ø$I’¤Ø$I’¤Ø$I’¤Ø$I’ükûí5¬}ASLßQ’$É·@ü]±!Æ ’$I~/Bˆ¿ü=óOÓßçRN)I’$I±!I’äÏäI´üéoúû¼BŠ I’$IŠ I’$IŠ I’$IŠ I’$IŠ I’$ÉŸ›J_A’$ÉJñþßþ«,ýæq„wïþû¿ï—^äk?Š I’$Œ¿@ë—îà¿y—ÿ}N±}å‹|íçO9¥$I’¿Þðóg9ÍðG¼HZ7$I’üIõÿF[ ýîÏŸbC’$Éó0þþMöß\xøÚÏŸrJI’$ )6$I’ü©~ÛᅴϟbC’$Iòei¿!I’äcü¦ö¢ÿ,oýµ/’bC’$Éy{ý¦Þèxë?ôERN)I’$I±!I’$I±!I’$I±!I’$I±!I’$ùsû¢Nip|úù¯ÿí¿§/%I’ä[hp|ú±áKÿ"I’$ù¶¯¦ï"I’$éˆãüôGé‹H’$I:ÿçŸþÇÿ ͘n?¹˜����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/thread.xml��������������������������������������������������������������������0000644�0001750�0001750�00000026455�11213747166�015415� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="us-ascii" ?> <!DOCTYPE thread> <thread> <info> <version>June 2009</version> <title> <long>Create a True Color Image in an RGB frame</long> </title> <history> <entry day="4" month="June" year="9" who="liz"> Original version <!--// built from CIAO true_color_ds9 thread //--> </entry> </history> </info> <text> <overview> <synopsis> <p> Most astronomical images map color to intensity level, e.g. lighter tones may correspond to a brighter intensity level in a greyscale image. An alternative way of presenting data is via an image that correllates color and energy. </p> <p> ds9 has the capability to create an RGB image and interactively adjust many of its parameters to achieve optimal display results. </p> </synopsis> </overview> <sectionlist> <section id="frame"> <title>Creating an RGB Frame</title> <p> To use the three-color capabilities of ds9, the data must be loaded into a special RGB frame. This frame will contain all three files, stacked together in separate layers. </p> <p> This thread uses Chandra data from an observation of Cas A (ObsID 198); the level=2 event file is named "casa.fits". The same file is loaded into each layer of the RGB frame; different energy filters will be applied to the layers in a later step. </p> <p> There are two options for creating the RGB frame: </p> <subsectionlist type="A"> <subsection id="frame.cmdline"> <title>From the command line</title> <p> The command-line syntax can be used to create the RGB frame and load the three files into the red, green, and blue layers: </p> <screen> unix% ds9 -rgb -red casa.fits \ -green casa.fits \ -blue casa.fits &amp; </screen> <p> ds9 will open with the three files in one frame. The <figlink id="rgb">RGB window</figlink> should open as well. If it doesn't, open it from the "Frame &#8594; RGB..." menu. </p> </subsection> <subsection id="frame.gui"> <title>From the ds9 GUI</title> <p> To load the files from the ds9 GUI: </p> <list type="1"> <li> <p> Launch ds9 </p> </li> <li> <p> Choose "New Frame RGB" from the "Frame" menu. </p> <p> When the new frame is created, the <figlink id="rgb">RGB window</figlink> should open as well. If it doesn't, open it from the "Frame &#8594; RGB..." menu. </p> </li> <li> <p> Make sure the "Red" band is selected in the "Current" column of the RGB window, then choose "File &#8594; Open..." in the main ds9 window and select the red file. </p> </li> <li> <p> Change the current band to "Green" in the RGB window and open the green file. </p> </li> <li> <p> Change the current band to "Blue" in the RGB window and open the blue file. </p> </li> </list> </subsection> </subsectionlist> <figure id="rgb"> <title>RGB window</title> <description>The RGB window indicates that all three layers are visible and Blue is selected as the current one.</description> <bitmap format="png">rgb.png</bitmap> </figure> <p> Each frame of the RGB image may have different binning, scaling, smoothing, and colorbars applied to it. You can "lock" the frames together, so that the setting is applied to all three frames at once. This is done with the <figlink id="lock">Lock menu in the RGB window</figlink>; all four options are checked in this thread. </p> <figure id="lock"> <title>Lock menu in the RGB window</title> <description>The lock menu is expanded and all four options are checked.</description> <bitmap format="png">lock.png</bitmap> </figure> <p> Use the binning and zoom options in ds9 to adjust the image so that the full region of interest is visible. <figlink id="ds9"/> uses binning=2 and zoom=1. The "Scale" is set to "log: minmax" </p> <figure id="ds9"> <title>RGB frame with three files loaded</title> <description>The data is loaded into one ds9 frame; the RGB window indicates the current layer is Blue.</description> <bitmap format="png">ds9.png</bitmap> </figure> </section> <section id="energy"> <title>Apply Energy Filters</title> <p> The following energy bands are used for the RGB layers: </p> <list> <li>red (soft band): 200-1500 eV</li> <li>green (medium band): 1500-2500 eV</li> <li>blue (hard band): 2500-8000 eV</li> </list> <p> The values are just guidelines and may need to be adjusted for your analysis. </p> <p> To filter the data, first select the Red frame from the RGB window. Open the <tt>Bin &#8594; Binning Parameters</tt> dialog box and type "<tt>energy=200:1500</tt>" in the Bin Filter field. Choose "Apply" and the ds9 display will be updated to reflect the energy filter. </p> <p> Without closing the Binning Parameters box, select the Green frame. Type "<tt>energy=1500:2500</tt>" in the Bin Filter field and choose "Apply" again. Repeat these two steps for the Blue layer, using the filter "<tt>energy=2500:8000</tt>". </p> <p> The colors in the image, as seen in <figlink id="efilt"/>, are correlated to the energy of the data. </p> <figure id="efilt"> <title>Energy-filtered RGB data</title> <description>Each layer of data has a different energy filtered applied, correlating color and energy in the image.</description> <bitmap format="png">filtered.png</bitmap> </figure> </section> <section id="smooth"> <title>Smoothing the Data (optional)</title> <p> Smoothing can help bring out finer features in the data by removing statistical noise. It is an optional step; experiment with smoothing to see if it improves the appearance of your data. </p> <p> The smoothing capability in ds9 lets you interactively smooth the data. Note that for quantitative data analysis, smoothing should be done with the appropriate data analysis software; ds9 does a nice job for publication purposes. </p> <p> Choose "Smooth" from the "Analysis" menu and the ds9 display is updated with the results of smoothing. The "Smooth" option can be toggled on and off during your ds9 session. </p> <p> Open the "Smoothing Parameters..." dialog box from the same menu to adjust the function and kernel radius of the smoothing. This data were smoothed with a Gaussian function with radius of two. The results are shown in <figlink id="smooth"/>. </p> <figure id="smooth"> <title>Data smoothed with a Gaussian of radius three</title> <description>The smoothed data are displayed in ds9.</description> <bitmap format="png">smooth.png</bitmap> </figure> </section> <section id="scale"> <title>Adjusting the Scale Parameters</title> <p> This data is being displayed with a "log: minmax" scale. That means that ds9 stretches the scale to encompass the range of pixel values in the file. Adjusting the minimum and maximum scale values sets a threshold for the background data and brings out features. </p> <p> To change the minimum and maximum values, open the "Scale &#8594; Scale Parameters" dialog box. The pixel distribution shown is for the band selected as "Current" in the RGB window; when the a different band is selected, the histogram of pixel values is updated to match. </p> <p> To adjust the values, use the cursor to grab the red (minimum) or green (maximum) vertical lines on the plot and drag them to the desired location. You can type a value in to the "Low" or "High" field and hit "Apply" to set the limits. </p> <p> A basic guideline for setting the low value is to minimize the contribution of the background. That is, adjust the minimum of each band until the background of the image is flat (i.e. solid black). For the maximum value, bringing it in to the last data point in the pixel distribution is usually sufficient. </p> <p> For ObsID 198 with the smoothing applied, the following limits were chosen (listed as "low:high" pairs): </p> <list> <li>Red - 0.4 : 20</li> <li>Green - 0.3 : 35</li> <li>Blue - 0.1 : 10</li> </list> <p> <figlink id="scale"/> shows the image with the new pixel value limits set. </p> <figure id="scale"> <title>The adjusted pixel distribution for scaling</title> <description>The background of the image is almost completely flat (black) after changing the scaling values.</description> <bitmap format="png">scale.png</bitmap> </figure> </section> <section id="coordgrid"> <title>Adding a Coordinate Grid</title> <p> To add a coordinate grid to the image, choose the "Coordinate Grid" option from the "Analysis" menu. Then choose "Coordinate Grid Parameters" from the same menu to open <figlink id="grid">the preferences dialog</figlink>. </p> <figure id="grid"> <title>Coordinate Grid parameters dialog box</title> <description>The parameter box contains fields to set the plot title and axis labels and to change the axis spacing and numbering.</description> <bitmap format="png">grid.png</bitmap> </figure> <p> From the preferences box, you can change the color, font, line style (solid or dash), and line thickness for all elements of the grid. The font style, size, and color can be edited, and you can add titles. It is also possible to turn off the display of individual items via the "View" menu. </p> <p> In <figlink id="color"/>, we have turned off the grid lines and border. The axes have been changed to "Exterior Axes" (from the "Type" menu). </p> <figure id="color"> <title>Final three-color image with coordinate grid overlaid</title> <description>The three-color image is displayed in ds9.</description> <bitmap format="png">color.png</bitmap> </figure> </section> <section id="output"> <title>Saving the Output</title> <p> Once you are happy with your true color image, there are a number of output options in ds9. </p> <list> <li> <p> <strong>Image formats:</strong> from the "File &#8594; Save Image As..." menu, you can choose JPG, PNG, or TIFF file formats. </p> </li> <li> <p> <strong>Postscript:</strong> to create a postscript file, go to "File &#8594; Print..." and select "Print To: File". </p> </li> </list> <p> Currently it is not possible to save the state of the ds9 imager, meaning that you cannot save the composite RGB frame and reopen later for further analysis. </p> </section> </sectionlist> </text> </thread> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/filtered.png������������������������������������������������������������������0000644�0001750�0001750�00000647431�11332353405�015722� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR�� ��O���yÐÞ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ ¥˜RJ�� �IDATxÚì½{”×yø›žWc `P€�©nR$1|�¢ø’,Q´)ËM#éØN{Û1e'Ú›®M´ÑzílJ7~%»ÇwoåÊ8MѶÊécxã–G´F¦…ˆKI$EêARÔ@Ån‚¨Â�60xÎþq«ª«««ªóêîïðð4jêqŸßû~_ßââ"€{üEHHHHH\õxöË_�0 ÃÇþ¤ ‰{üÅg¿ü…¾{öå?öð':órD$$$$$Þ¨¼R}é™ñs gåˆHHHHHHÞ !!!±ü8}êĹZö˜aetÓæ­kûlo8n!xuöûO½csßæÍ›/^¼ø£ù¡­™[#_zfî­‘ùVæ.dßý“r)HHHHxÒö™sµùÛo»­ýG^úþ÷ §GÖêÙhÞ€¾¾àÕm7ß»0ûü'>öÑþþþò§Ÿ:>²e{èÉ çÎfGjoÌaÇî{CKHHH\Õ¼áÌéÛo¿½£Gn¿ýö—¾ÿýá ÊZ=Íú‰ûàpúÌ–›ÿâ ußûÞ{ë-»ô•ƒ—”ÍCéà=)ç—6ÖF2[7n–KABBBÂG____çs_�«ÿloH…þ Œíxó5û™gžÝ¶M»ùúkŸ?ôÍ{>¸ÏŸª~ï¶kFŸ~åÄu·Ý!×À/ì»ç#÷¿ë+O¿üù¿û† ‰«›7¤º¢Ñ)ï¿5x¶-½A`Û {~ø½ƒóó‡S©ÔæþsÇgûMw8}¼úÎ1|ã…Ù»ºe;vi›égÞ{sfûà@ÿÉÓg_?zâ¿–¿>7Æû.þðSÿTÛ²ÀÿÎþß7Ÿô¼ë–ÌþûödvníO¥Þræ>7ó•§_^\€ÿçÓ¿06:òG¾öÔw÷Ðj@€3ó'æ·6k;#ïÉ^³5ÿÓï¹ùÛ./.¾øÊ›}é›þPHHH\IÌMÔ¶M>ôìïÿ«ÆÝþÿùoÛy¶á¶È‹ zCœÃ`çž¼þL9s�._>572:2¶có¹#߯ßµw__ª¿eO?ýð¾mcß:>wä­ãc›7Þqóu‹gO^ºœêï0žÝ!€;²›«³GÓ�öýØ­?ô^�‡«³gÎÝvSæáŸù±]êÆG¿ô¬¯»Ì{ãlíÔ†[z‡9,‹QìvãÈðoL>¤lúû'ŸëÃâƒ÷ß³}ËÈoýqè—[IBâÊb ]ÚvЉ]è‡ßýæîw¿¯å³¿ÿ¯>ú›¼,~ÿ™ˆ{¶]›’@ÿÀð޽?uüÛ7ØTªÏ9ü\jÛö —ÎŽdïÚ°±eÓÕÍʶ±çÎ_øåOÿÇžÔÀàð¨2\«ÕF¶^;00 à¾;nðÊkoÜtýµzÿ¥¯<½IݵqÃð/üÔÝ�û›éÏÿÍôÀPú}wÞúýŸ}è½{¾tðÙãgëM]¼|ùÏé'�<úwßüÈý{ÓCƒûµïýèMçW'Þ§nVž~éµÿò·_¿|yÀ¿þ…nzÇöM#Ãç/^:|äø_üý³o; àæÌö_ýÈû¶müÞ+oο}öƒ÷ìþ‡gfûÒÓ�¶mÊ?xÏ­×ïèÿáëÇÿâñgŽ;êàxvû¯|ä}Ú÷ñ Žö‹Þûþwݰi$}öÜ…7ŽŸd¥ƒ»3;” C¯Ïÿ¿þØÚ°qó·ßœÙµíF-}عØéÌ—6¥h»ÐÏÿ‹ßh¾ù¯ÿä÷ƒ&ŸÈgës_üÝÿù#‚%ø¿ý†žíÀ¦$02ºU¹þÞsÕgΜ»´ØŸI?žºæº™vºúö™s ç/¤‡çßþÊgOý°zlæµ·FÒcýýý@ßà@ÿ½·g|î _¤ÿæ—whc7]«=»xKöš¡ÁÅÅÅ¿þû¯mÛ¶q˶Co=~rç¶-{oÜõø³‡› éÇ~|Ï«o»ëÖòûî~û̹C•·Æ6møÀ7~ó¹_¨žB_Ÿ6¶ñkÏ~ïø‰“ï¾å†»n¿Yÿù|ú‘££›>•ÿàÆ Ãß›ùQmþô÷îP;eŸ´ßÜymö7'Ü::òµo½äœ˜ûèO½ÿ×þЯÿßÎ]ª{Ãðà¿ùŸ>¨l~ñÐk µ·¸»°÷¦]½ÿ¶Ê›Ç<þ5edøÝ·ÝT;1{nÇ�ê–M×íÚ¡íºaó&ÀMïØñâkßW6Iî !qeé ©®žê‹|ö–»>ÇN’Ÿýw4õ;ŸÜ Ä‚/ìÌÄå3'./âÜâÐ;·m¼Ôn·/\Zü£¿~ò—ºûÞwßû.�8êœzä¯þǬ=¾¾w_§¤‡NοýÝ—?ÿråÇï¾å'ìŽG§žÝ4’°pî|í̹Û®O¥úûOÖvnÃæQeáÌéæýáŸýõ7¾óƒâúôu×h|úOÿÛ—>ýk¿ðàýw½cûè7_|mãfí·ÿì˯~qãÆMÿøì>ÿ{7îÚ¾ Îwß²qð=wêßþîç†Òå®ÛoêÈ»w_·utäµ#Gù³ÒІ™kwÞ}û{3›Ÿ}e.50èÁn¾NÙ0윜ÿÔïðþÁáßÿôä·¾SüixpÀé·ko;qôä™/<þsgÏœOU~X}ëæÌ5Ÿÿ?ÿ7�Âw²!=|áÜlëb%IHHô*sH!Õ×ÅS}}©ègãÞæ_ößýÉ—~ç_üLc¸çþˆïFò†„ ó³¯\<ñê… ÛG‡Îœ?þܹs8oŸ¶¯Ý´íítö;¯Ì~õßÿñÎÍ÷ߜù¹Ÿþñ];Ô‡î½áO¾øÌÀІ÷ï½À7žÿ~_ªÿ¹CoüøÝ·üÄ{îøÓ_=}ö€ôð¢lèëO¥úûÑ×7¶Ipêtíò¥KX åpõÍÍÚÎ…‹‹�~øÚ‘ ›¶\L 8îlÿ@ß/ïÏ]ã?«löêïSÒ�ŽÌG_ÿÖÙ£§êF¡­›G�\ÝŽ¿ùõ/^£m9ýÜ+£Ú5´yÓ€×ß<†TJÝuýì‰3wzw~ïð‘ç¾ÿ£»n½~Ïîë;1ÿŸ>ÿ¥·æÎþî£_¾íš‘]ÛÇf9ï¿ûöûîÞsrþôâåË—±Ø/ψHH\QzÃrúâÞ° Å>ûÛ¿öPÐõüéã‘ßÑb˜ÒÂé¹Ó‡¿yæÒÀ;ïþðÙyçÄ _Iဓ3_ÞôÑá‘MÉ]èßóÎÏãÒ\íí'_zSÝöƒ_ü™û6*é¹codo¾õŽ›¯ðÐïyè÷ˆû•‘ô»¯ýÁÞ<áâÐàÀÏ~ø¾¯|ûõÔpê]7íºFÝà[ß›éïðÜ^ºti`xX ÊÅK—‡Ó)ÏO¾¸xù¾wÝpÿ»o|ó؉ßÿÜjgÎþÁo~2•Jõõõ8õ6€k¯Ù6”N£/•¹Fó_87@õÍ£ì±ÿî_<qòô¥‹/§ú�Ì×�lÛºe`p¸©jýœÇ…‹—ÿð¯¾zþÔÑ]ÚæÜÏüÄ}wßþžñ_üÆ«ýýÃßúáÑ‹/U6Ž ‘‡?àù—^éëD_ìHHH\E6¥T´M)îm 6¥¨gÿÃ?Ðׄ‹â·í¡ÿ_¾ÜüÝlJ—/^¨½ú ôõíz÷¾Áá‘Ám#—vßöÕ§†‡‡ß>üÍá½NîÿÐàÀÿòOï¯-¼÷ȱ“‹‹¸ù: Àw_>¼xùÒ½ãïèO9»ðíï»q¨×_»ãÚk´Ÿºï®?üË(ýÃs¿ôÐ{?ñóÞÿÞ£—ºé: Àô“ßzùpUÝuC´i¾/ðè6°AÑÈK—. =ðá{S)·Íß™©ž®-lÛºù~ýWÎ^Ä­7ìðy~æõ§ÞÎìÚ±ÿƒï{Ãy{lT¹cwæO|õí׎bÑ}á‹?z«vöܵ×hú?Û¾oøÎÝ×ùï¹q×Gï×˯9»pþº;�œš{~îèïý¯Ÿ8yúLíì¹{nÍ(†Ÿ|ö…®ª»nHuµ’$$$z•74ø„é¯î‹»Óø³éƧ¢Ï(´¡7D<ëW˜’Œ?›WþÃ?°ù»q¼!âÃg|GÛ4tlôÎQ/Zë;v?s"³éÂàààâââë•ïn¾á®„:áòÔ×_ºiçhfçŽá¡Açäü?~ýÛõů¦GÕ÷¿ë�_üÇoþé{\¤òØ»;û?ý‰÷ÜqËÀŸOý÷^yýõ#yà»úûSÕ7}éàÓó÷Onظypxâü¶}‘?ñõï¾:~ÝØ½·¿ó_âcSO~wáÜ…ôð €³çÎö OLþ“{oÌìüÖ‹?üÊSßyðw^º|ÀÂù‹¿ûè—öã÷ì½ùÇÓé¹Óµ—¿þÊ+¯ô Žö Šá:{îâg­'~ù¡{÷}àî—¿þÔwfî¿ëñÅ“§Ï¦úðá»}$=túÌÂã_ûÖŸþÿ†6Ž››¿÷–w(ÒÎÉÓ_øâW?àïÓ#£ƒÃRý}Ò¦$!q1‡63 ½ôôWoÿ±Ÿ ªÍÏ y?öC‰ÏúŒA|Åø¯_¡¿òáèï†^,ê7üèȱÐÎ}%›>õÝêé]{~"ø±ÅË—/yæî[2—.]:5??sJQ¶_ŸÐóË—/­Ì\ºpáâÅs‹—Sýý6nÙ¸uÛÐ`úhuæüÂe³ºiëvQ~îÜÙÚÉ£¯÷¡oÇ;oëÞ>eŸ«Í_8wn‹CFǔѭýCCÃéÊ÷Ÿ½|ùÒ–m»6©;_ÿÁs�¶½c·2ºåÈ¡ï^¼pnËöëFÕkœ7^­ÍŸݺõšÌ¥‹œÙ×Î/œI¥úGFÇj'ÅÅËÚu7ªêö7üèìü‰‹/üáo‘;n¹ásùÅ/=õÂÖk2ƒC'9[;}aáÌåË—ûû†Ó›µ]”M¦$ VÎlåì鹋/ §Gúúúμ-¾xñü‚=ûÚ¥ ç/_N¥ú‡G6Žj»††7ãð¹³o/^ºÜ?ПV¶lÛÖ?844¼Aî& ‰+§ì·n¿½!Eé‹ßø‡¸›÷¼ï§\>ñÒË›µkVâYÿ¶È‹âYÿ¯sÇŽÔë7„XÍùÓNv¤v¨zbÇm Õ kôõ÷_Þ¶çÌù“·ÜtÃéÓ§T}µvj8þ�Z*5°eûu—/_ìC___¿ç‡†Ò£ÚÎTª?Õ?008<8œ04<’Jõ¥G€ÅôÈhÿÀ๑Ѿ¾Tª?%4¡¡tÿÐ0€ÍÛ¯JoèëK¡¯oËöëÒʨèÅæí×ôöõ÷Ø´õš £cƒÃ@_zdÓíZôAõ´2:08ôýÒC÷ôáî×^ë¦ì5wÜrýÛgÎþãןúúRý›·];´áÔbR}ý}}}‹Xì/¯ëqý[¶];4²q °/•Z\\ÜtébÿÀ €¡ Ƕ]›J ôyïÚ¬î¼|ùRÿ€xÉàÐÐÀd W˜Ú–Ä÷¾ÿÃí<éO^ögC“Ͼ5üám»:sf.¹g`p¸ù½ieôEçÌûÅ……… Ο¾p&½éîø&cdS4çݺ#tep8½eÛ.ÿŸCé‘¡¦Ì±cÛ¯õo½¦~Øb³Zç~ƒCÁG6ŽiÍïyÓžÿ໯ïmÙ³çÎ?ûâ+ü—{òtM»ng_*Õ×××?0¸q‹–<%ƒÃéÍÃéÈ?mjê �%*Uº„„ÄÕiSjf)köl¤M©2{âªÄcÕ™ÚüÉË—.¦R©á £[·oHoÜ’’� ‰®p~áÌÙ·O…Ì;Éx饗7lÜ<”Y«gý+Îìku›ÒÕìUw¦•Í©á©Oõ¤7lL¥dÔ„„D—å^zéåöÙ°q³xj­ž ¡õÙ·+6mÙ°i‹\ÍËÉF6l\_ÏFð¡7œ™Ÿ“3*!!!qubdt¬Io�ÎÌÏ=ö™ËÑ‘¸:ññÏ<æ³iU—À#<üç@ó'Ož”Ã$!!!qõàÑG ]‘zƒ„„„„$o¼ABBBBBò É$$$$$$o¼ABBBBBò ‰5Æ@§ŒE^Ÿ››š›[¶¤LÍß ½ÜÿbðÓKiFó³Á6,c×–Þ÷µE\ó–w D.¶5‡P«:mϲo“öê }zíJ·0ô‰º9žKœú+œ7¬þ ´ó­•nÏZ-‚_|Á=366677·¼ Žz14w¼wZµæMZÊàôÈ‚ÏÞœúžã -YýŠŠÛqÒ½?âJßoðŸMÐKâ„ååÒ`zÝÜÙàƒ×C¿Wsj"‡nyŽ–ýjg4VZrOíe™‹ÐwýéeŸ²6'nµ¬r [ŽçÕ†ÔŠnó/;õ‰“;VzݬD×:Úcq- Êï¡ß«ßþ—]^;@;ýJ®…b!@4±£Ñ^mÒé§WbI$Nä“[¸”K  ÉD#nê¥ÞM¡VatâÄŸ¸Uµ&Jt³‚¹,¢Mä8÷Ίl)ö.KSWÁ½Dö°Êʪ…VhUDnŸU¶;EîÖ¥O½ä m ÊrîUž€H[Í u­‹¾w± Waj®xÛkÂ:IîxË¡îùf·[œPßk=]é©¿JyCÒô•“ˆ{³kq–Ù+ljzM@ ¶§¥ÀÛÎ]©Ä¥Y™î)Í/Ò­¸ŒS µ {i…qå$²6Ws°k!‹öºP9Wnj®Tưr»”¹hv±ôò´67¯75§õ2žëLoðÙò²È ! Oçǹ£WÎı¼][®–„ZµVS³::\dVm^š‡:¡És´ŒmŽ|UÂËWy'NäF^ÛÖÎÕîoè»g_þcòõc§üzѲ„„T¯*ˆºoÏŸÜ:2:vüÈáêKÏÈœkîN[Ízä k€«*t=b@„„IJ ©7HHHHHHÞ !!!!!yƒ„„„„„ä ’7HHHHHHÞ !!!!!yƒ„„„„„„ä ’7HHHHHHÞ !!!!!yƒ„„„„„ä ’7HHHHHHÞ !!!!!yƒ„„„„„ä Wo躞_wÊòW3B40™$. ÁLu×ÊЕÆÜÜœ,%!!!±jè²&¨_ë5È$æææB¥_ƒÌ#DÜ#ï ½6t%î¯W³JÑ’ÌvQ”;µ”v„þ966$ß~kšizË÷Ç=ÕÝ;%$$$®`ÆLC”yeõ†e¢M¡^°2Ñèfž&®Ç½!ù¯W¼ŠÐ5e^YÞБÐE7|_J$¿‰û«„„„ÄŒHs=VƂҙM)¨¿´4ì„”6 sD¾<ù¯WÏÒä5à «£4%èRcH&ž‘bzñ† ý'NÃh&ñÒ¦$!!!Ñ™#‰ÝÅ) tÑŽö¯ÄýN~Iûzx@›$±+k©7´©ÉY—è5¬%ov! ‰ÞÄÀ~[r ‰Þ¤±2«„„„„„ä ’7HHHHHHÞ !!!!!yƒ„„„„„ä ’7HHHHH¬6"Î7<úè£r\$$$$¤ÞPÇ#<"EBBBBòÉ$$$$$¶)}⟃"!!!qµaË–-ÿÌc±¼Aܱ:M9yòäj~®G>½.Ú³¶-ßê5¿—›zpŽzpñôþzî©vöB3D’ô†¸û–>ú¨¯£¬ÂçzäÓë¢=kÛÂà·zG‹Ý²e‹ßñžš£\<½¿ž{ª½ÐŒ`|ÈV HÞ !!!!!yƒ„„„„„ä KDÇußBžçææÖª´§ÿÝ`V´1k[ÄÔù¬—92²æë:Z]ëeÊ®ÎEÕ~¯—q|®€‰Yµö¬aÇ×ã–\AB.ª«BoðåÖ±±±8u!¨U,}#ßÖüÝá·p¹q‚‚l[œú²t²7òÍ~4x=ô{%&«yèâÚ¹Äo5k®ÉK¥ÓaY¡ÛÑà/ûÔ,K–qÛYÃ-—Њ¶0a=Gþ^…ÍGš"¿²ô¡èÀßà¿=î3~#š‡l)£|[äJj¿…Ë>CËÒÓîF>È0"#è`&FŽä2vÁgÉ‘oKþkG£á7»¥ÒѰ¬ÜŠmð—}j–· ˸ړ×pòfOnáêlÌîÆv¹öW;_YÊP¬W_ôŠRÿÈ èè©Õ±ÍÐû“²¼ìY#[hÇ6ÏWÜ_WmŽ–þéel;¯êô[Ë8¶mêd‘eMˆÞR>=°B{£7ßÖË=]ʬwÝ’^Þµ•–BGÚá[-G¾g§fÙ)»^ =K…z|Ç®¡xÕrj{„6Å™>×#y½XšoIpzµ3eW¡Óõ ër;+¡—-µr»wyí’‘j]/`ÛBVìõ\´\“µ:cÞËÖ¤ä¶u1ÎË»Vâ…«°{AAogSû-_¡i]ÊÐ¥Vb—e\"ßœ§–¹,݉|ÏjêŒ TûÚÃJta5Ùᘇ–KeÕšÔ~3’§lÙ[ÞÅø¬òèu±Ù{d®áÚkç+KÙ’]´&ô;òâÊ©KÍß\Ö+Ñ€vzºB£‘üÚîþºÍ[…’¼*’/®ôPt×¶äv®fÃV­Um¾|¹–úªí¾U „6¦ë–Èœëø$±š¼ABB¢ÑS–Û«r$$$z™=H¬ÉÐI½ABBBBBò ‰Vˆ¶)­r÷5¬ßkë{­=kÛÂÞ,Fß³sÔƒ ëýõÜSíì©áê»g_þcòõc§ÎÌÏݵåDïTo—XMQìãŸyldtìø‘ÃÕ—ž‘6% ‰0–K‘?yòä�KÃÒÑ m¹‚;Òû6a9èý_/ c}µ³oˆ¼/>ú¨oŒêôÙåzÃÒÑ m¹â;ÒËfÛ-[¶øãÜ˾^Æzl§iS’€ä ’7HHHHHHÞ !!!!±D¬|J]$Û ep fÉ_ÅvS11TZ½Çû’Ü‘¥Ì¯œ‘UÛJkÕÈu1žëbT»Ï+3×ÞúMÜØf=»æâ0ë®#]Ü)gduf¤w6o/çúZÀ]ŒçÀzY+T€Jfƒ¡û›…».V[‚jFd¯à×C¿CjYCx‰ ±w:Ò<Gëº#ë}Fz­½?žëewÔªÑ÷®e¨|˜OëãÖzËzp] ßœ‡fnlF\Ûüb³Í¿;]IKLjß;Y"z°#ëtFz¶r<—¥]S é‹^g¦ª–¬qÙÜ–n.èãá[²®=aWíx®‹Ü5ÅhÿíÝ ÝÁg¯€úMkØøU¨Å½šY.;r/ÌȲ,ìõ²/zŸ1¬N;¯€¼ ¼a)­__B«` ‘‰kI§›­G:²ôµ½¾¼Är<¯°¼$Þpå­Îîfq­xÛ2®¡ÞéÈcX匬;x…µs]/àâ KWƒÑWAÏvGo½§kŠ ŒwÍ͈¼¸ì#¹ôOôBG–—F¯yG–’¿^fdÕÚ)Çs¹ÚÙõÖÞìRËî%ÜÜÝ"ˆ|ªÍ‹qIhIr›—nâ둎,¥G½Ó‘•0‹¯ZGz°ëk<×ÅînHeœ’„„„„„ä ’7HHHHHHÞ !!!!!yƒ„„„„Är#:Ni)Ï—^-½ê­÷~ÍwÙ‘uŠÞ/+¿¾\¶s…ÐwϾüÇþäëÇN™Ÿ»kˉ^.t.!!!!±rRËÇ?óØÈèØñ#‡«/=3°N… ‰•C˜7<òÈ#rP$$$$®Jlå ŸúÔ§äðHHHH¬ ÷̇?þ™ÇüÊ8% ‰µA;Œ­Ö‡B¼ABBBb}ó.ÔÉ$$$$Ö†¼öl#Ûá7’7HHHHô„8ßS”¼ABBBb=ª|EõÉ$$$$º¦æ¦«¯j„—'µœ¶õvÉ$$$$º¦æ6VF‡ ÓôÖ-o¯©’7HHH\U’~Ô=tù›Á–Âuh7Úì&_¢Æ yƒ„„Ä(é³6î “W£«Ñ0ÁeOèí3'Úö·¼z;ªL·ƒä ëUöïB$gHîmµÁ��f$rØò$’m´úh'åÝÆ;XÉ$$$z‹4Rm¾\Eï¤1mÝ#·ÇuH¤ÒÀ’E~Úð‰øEÑ¥MIBBb}!žÌ�ÖÕÚ}cX+½!E±vÚitÂÀ]¬qÐ"Þ)mJëKWHF~ ŸÐÛ âË¥m ÑᡯäÐéQŸîz„%o躿Œ’~”]_¦n²vºÓÉàÿjµ§Ùèö±á•¼ABBbù™Þ=¹ç:ô»é’T––¼'Âß@Ãÿl=81MT˜x;L.º§Fk>!yƒ„„D—<€Ñ0Ec Fv£Í7“È;õ¶Þ0Õ3¢è/]ÁaáýÓk€N;à£mƒ =|‹{ É$$$:¡ª­!B!1zÛd—µ·£ _s'ç¡èRÚø'Ú¹¸+‚¾óp¢Îléª á+4š÷ÈV ‰îéóhYdtf“¯•t$Ë'Yç›üð9€F§«Kah.¦•Ív*£…¸×øÐ0æCW(�fE4aÚ Òg#æ¶Χ·q`»Ž{öåçÏÿÇ¿üƒòÃÆç?ûÙÏÊý#!q•¨\Oû¢hU¢Ñ ŒÅfÖIp¤st�� �IDAT›Y{ßj“2¯×V h98VçS×Í€Ó&5+ ‹‹‹Ÿÿ—PþÙO}öž}y©7HH\ A{&fÞŽC[¹¸?Ú @#®$¥‘0ÂÒ4‹2†è‘F#‰´8ÅFc‡Ká@º×ë|pкuwç‘hk[¡‰»SL«Þ8Å-›'yƒ„ĺ‡Þ¥,OÚ¡eztê¡Æc½†+¥ ï43Âl¦e\¦ÿOW] QünÁ>dÄSÒ ÂèŒà2šÈkiin9̈UÅX³Ó•nÁÛê²´)IHô °¬´ ú6 wŒ¶«…°åÜä²&Á¼]4æžcQZ kÿ%hëÖíø³åžÊ¥>5Ú!›’ä ½È:½²ôwúkœ¸Ú 8 xK¶×fEšÎˆ~à)Ö-3fñocÝ ;ïÁ•&yƒ„ÄÚ¡“¸IÖa­ÄpÖŠZ1Ô¼{¡5Ê®Åh¸m]ÖZ�ЛIz<†sX]Kå4B• ¶6RGifí”™cí4 +HÞ !±Ö,¡EêͶ„JÖ.wéÒË-̰ü”Ç“#‘X2 ¡ÑÌ)bZ­z3¤œµb„¬!mì ³ÚÙòh F›Øíp¥uÂã%oXVeœF û­ m;“v` W¬ÄG¬Nµ®”¡ö-,àjN~9k–Á[i0íRÕà¼Ð¥*,‘Ù³„e@“Dж4-šÄï™ä ËM7iÓ®kÓÚ‚xñ„ýܚƊÏ]pD÷ ûNÖTËÛЫZHúmÞž=³©n´…–ÜÖ]ã;ZmŸo¼AB¢À"©íLvé±Ò8±—·–¯iÇ„ƒ%ªÑdËô ks“8Ê]kc Zk9|ÐJ«Nœ+¼ke«ó@2Þ…Û|‰ %oˆ·í˜þEÞ$‡òfÁ�‹vµc;Ò0’Ë ¥QT&FÝéTG‰pH„Ìî@Y#Æ¢u/¯ît®Ç„f3�+ö)û³ÈÇÇj©L´Yë­M©ŸÖûÒщqÉ$$Â$Àʲ¹¦Y\ì7Ÿ3“7îü ¡‰[íÑtæ{h-ޤŒ÷ðHÊhù„û~ÞÀ„hkÓ2~4VgBl_b ¦,Êγ—;g$¥hiøbÍL+üƒ·i½I¾­Ëß%Cò‰«Ë $\‹ºÆõéåõÍiõŸÂòŽB-#É–åeà±Ââ3!Ó<Z�¤ߪh!M»žI­µ0Äh ´µµ„hºÏ¢X›T,ÁªC[ë ‘®£êȳ3C�­ØdÔ³íÄ­¶)ñ,1±«ä W¬6M=™Î¢á3ÀuÓ…”ýÍÆ8Z¿-Ž XÁÃP´\o.ÓhƒRLPG“áÖdYj²ñXD+‹VXF6;aŠ4NçI41Ží5s¬ŠFtÍjCbè€ ·§X­èrû!Ŭ/ưa€™Ro¸Ú@›%GŽFÑØj¼'*p“»œ€‚™`®ù…³�ƒa>y-66¦=®À]ǃ ËãxÙ3ï4° Z7z„ŒHÂrÅ"©jÈO šd˜òÚÌ8GÈ0EÂs˜Ð7iIž’ù(ãRTŽ–ÇÁxXu Ñì¤#;~`][xXòÂn¶qu‰›ÄáxäJÞ Ñë@¬]"dIo Ó<öØ--1�EßçÌå®@ƒ¦pF¹EÊ™éQOZÉC‡¿X™°<BÃL€Â¢°(¦i¦§¾©OÐ0ÝgÔü‰.Í0Ù²<<¬Ü´eÜàÍÑ÷‘¹•X¢øùÃB»§Ä›O€¶`EÉi‹vÓm 9bŠl•Iê0+Ik»\WÁ¾RoXGz@tdƒ3ÀÛ~¬• hÊg®Gûg¦¦ÁËî6渠àðÀ´Ç ,ÊËîÞ 0Ô½Áð¤ ç€™`eW¥pã8½³]%ѲÏê’/·šiõæ‘ä‰FŸ°³ÂDœGjíDZf²hyÈåE¬y˜XwBJë³îÄ|Ëk‰ÕŽÕˆ&2›¶Í› t?éØ6]žs ÑS&yƒÄza ŒÖ)k6Á½Ílu…R@?h4>аqpɱ°;•Á­"÷| ®ÚIªs (›"Ê…[”3 Ë3=o ]…À{œ[àÓE>mоÔ#d,/ZÆ¢Ü2Ýï–),Ú¨ãû¦-3ÂeIv£ã”|-ªI°µšxm˜‚ÄÇG²D‹M;¹˜ŽÈ f\Œf?‘D¡EÌ ÐÖr”Ò-¼ÓhO2Ú³ø'n–¨‹´¤õ]X«–Â$yƒÄª"ñ„'oJa ¶£)ïúTH±¦4>*¶«sX(‚ ¢L¹3wdò†oy(œ™°,—XàŒò2åO™˜p€‰²ËÀ¸XEnQ׎ärŸý"gÔµk•‹`”‹V5dÉöžýG°Šrƒ…»âÍÓ¬Éμ´ä°vL:‰ MCã_·§!âë"#÷ò˜×—° Ñ!è™o©[°(»Ä}Ä–éNÉ$VÔÔù®£QWLDŸ5 …ÐúeuK=ot?\F† o)h`”û4—y:‡Ð',ìÀ”%ìQE.þ$DÑiak21MÏð|ÑE~–,Ê™ÉåžÆ�e“»·QÁ<J– V„e5š\Šn_,ÏQ„#‹8kÊTayÙŠÉT7…7ùÕuù°†%™ebæ1ŽâG{bh˜9YQÚ‰Õ¡ÛLøm&¬ÃÓÈK—»ÙŠÝÜb¶Ú‰Vâ(IÞ ±Æ #lþ.¨^Ø–Íë"Úœ˜‡nFãy4aÒ '€ÏN‚V)¸†þrЀn¢L1 þJŒNÁs?0ZbfÉ*â)“—M19�f•ž*rfò²YwE0“3/žÇ¢xZxŠ‚•Ê”?g–¬¢ç[Š…G+­F³xÝ…PôhbÀÄâ‹-{¼¤T··øþ`Ú¬L¡±¢¥`îSgÖöijÖRÂ¥¾W�ÁˆaÖ¹PÂ"Â[-Îæâ -ÌDf‡šM'Ç¡ÙênOÈzÑË®DŒŒ€Wƒ�Ð)¬*� S¯÷[¯æhÝpëñ2Ã5õX~[J<%ƒ‹›`» "ê‹fÛ@Þä"Pµ °t §ù´À äÁ'�f€Qž5a;¨X(¡¶†ý »>d%ëäÔv"í@²WªxÁÄÞe J´ZÏpÐ)à \ €¿jPX“dÚ�`×Tâ gWyÅä8ª�T0p%›Kè¢#¾°? &*YÑ2¾Ž’e–„&¤Ó’F9@4j3Ê™¨€Ã€¦"ìS¹e•, «à™³ŒzuO»:sQä’nAPÝ€®ɱ?þ4b$Ð;=\I”øUŽýê•åVk¬¡ªsó#vaëKÔï²N#ÞY¿RˆhL³k¤ÎxŒ†‹ÉU9Û)Sm÷KسF'{_ê W-Xû,!±K«#E<lj² °P}Ê@l‰&ô¤M4\?¤°×k¹Ø ç ·6k0tp”ݰTáŠ(rFKž§+ór‘[OñT±T.rÎh©\,YÅ©ƒE,¢|Ú,YÀŠ¥iÏÿìsʦP\¸erakš¦˜ñµõî—¬†À.ô˜º³¡XWP.zÁ©ÂÕ.LReÀ2Kž­¦Ä‚É \µÆõ…X&åV±>Ú–o 3“²V„¢¡Z¦y`A³RœÞã‹ä³Ù­üºm–”ˆi05¾ Ý¥éë]¹¸—b›bíh'TÚ”$’ÅVyܰ,iãÂ$£)APSv#×ÜO#ì4Xs#AÍ:Ñ÷ù£n|QÝÇà‡6ºô‘3á%¶`Q”)`bÚ„…)F¹e=ÁL”‹Ü¢¥§Ê¥ƒæO•§Z¼l•¦‹SO—ùtÓfɲxÙœÖ'Ÿ‡•…9Ëš*?^²\£S‰(%yÐpS?�ar7jÓ*•­©éS �-± £ãXQœáà ÜÂÌt]ëâ¬Æ´YÃe¾kÁtaX´Ô0¦w,ÜôØj {(7{¹£¦’µ"ˆVB>¥äãu|´™ ·4ÁGœ»¦ˆHÉWGòû[ìîhŸ=tq¼¹…1›ZÚ”$<uÕh½’t£éAŠpö#¬»á’Á³¸MñHº«Vx‡ua 1\S†sžb€A>FK�"Þ�À2À ’XA8·‰&Äj•Àf€VZè %­È5p‚°®D©‘l Úà‡ÊU€JŽÂŠn%ÿ¡¬Ê+“DÍäª5Ì;3Ï×*ç’Vr@e JðmØ8D&vV´Ý€’'¥5 XŽ…ý•·€×T(ªµ§Í›£`y×E¡„Qh� t� vmA™­¡È¡B/ˆî€‘Ó}Ê[µu³T®¡¬"O?¤Äp•ò˜Aö(`p®H×À÷Rd’mؾ¡_GVÃè©Vz xk"°<x>jñ0 ½i…tÊ<uí‡:m<Þ¸>}“”¿Ò˜€´IÒðõĵ²Ûè®Q‹X¾q,Š-1÷5|ÑF/ Þ¬'vÚYËþq‡ë/1Zp ½éž8ãUß=ûò{ø“¯;uf~î®-'>õ©OIÒ¹n<F˜ùÇÛ(9ÑÛ3t†d =á"¶`ú$Þ ´'ºá=%ˆTýYÍ¢¹<8 ÂÀuJ`48ºø"åÂÒ-~×wf  f(²j”$Ÿ�V㺰L ØjvzgÅ9¯) ¨B·»Ôw>ÿ†Mj/òÌîñç9šëQª»÷+‡P² ÆÓ PÓf`¿ß!  ÔðªÂ3 5œU¦f±g /ø8à˜Dq¦ÒØïܦš¦Â.Øš UÑöUØÌÈŽcÿ  £T†]£È«¤ Ô#«˜ûk¾ó€öÀlNk‚ëuéÀu“0Ún؇�ã `Fa&PàH>0kbjx¤Räú$@‰ð1è”3ƒˆ{`@£° €ÁmJbé;…ðdDÌþ ,rÝg*^³#œþših1¶÷NgÚpÂ{šG&áþÀ~Y긵ÙÈÅÅÅ汑ѱãGW_zFê ëÖ=ÐÄüw"cˆ¯ØÕìòó(Hdê— SÁ4wWÔ% Â@`F ƒ-d[Pè ÁNé€î…üë1MF$Á„ÑÜ&Ÿà3&4pPä äÁVK¬Vw€Ý8¢:¶¢*P5dFÕóṲ̀G¡œÏ-ŒfgªÕÓ¯jé§Ï;‚jçw+¶ŠûPÉ;H£¤e®rÈÂ$ÔÜx‡ÔÒ}“8 (Ur!]z¥ùÚ~e”oqø] EbiTT Y䔂¥ãpÈL ¹²`ÿ …f¢ŒÜ„)GèIÈÓÊ(8L¼ðs6èž$«ÄB t“g,s¸nð¼#V…ãN–$_¬{’-@W"4  ×êÞÝ„·œzkÉ� ÆPÓ›,$, ¼ë¬n´¶@Fø¢"³ÅH¸ DHº§°e"¨˜ú&&t'°V{§»CÑz'Zx@“ºrß2kói¾–Œ¡®IÞЃà],»(S~Û÷ A>Fª “OÐ(­<¼8CN`”¸^„ˆÃeÞ .¹gFÄ 0[XB€uãdˆÇi8 L ]^tÁ€n8PUR18LbÌfl9'C¦óä Å@UrVõþ7”Ê}‡3ûÎÛ•CHŸßäf«¹µR¹ ÈB›Æþ½;m+CÊ(Í —€‰biÂDí(QœœU,© ÒÌ.äìB(MüyäP›„VÀŒAFäó¨e.’šº� kØPy­P—¬OPn9Ä6JPêV» ° LmHPa#Ç�V à¦Ðº1¶ˆÝÒÔ39ªG¡ÄàpaýÐ)G�Ð3ȃÃqµ´¼ªdƒ £h†OOyh}êAS»²ÃðH%£Ñ*èÚEˆ”Ë!Œ—óÝ!.u#|T‘ÔÀ ÔƒTØå¯¤ayG9TB¶—جà:šjFùõ®“&G ié]ÐmnþÔ.e¾è5¶ uÈ!Zòõ8[Rc"+¡»)‰8Tåo!«ÈAŸ�8+s˜%á1öÏ ([®¯5Â%Hà …¢ºÈ?CÓ æñÎðƒÞ)07…·ÿ˼ÔFæ+Â2KÖãx `f EL›œ™°L>-¼Ð&,SÄ)q˜%FaY¼\ä–fNY&˜éúi§M^6q(£$>jÑ’8Ê r+M›°Š€p›S ®W¹ qdš—)Ÿgë0e™\øÌ™YB±d[&gîÁˆÆŠ þñ=‘ÃôSq”\2T,¹g,"ÏÄQ0Zb(á@DÚ+êx7_QE4[)*+‘ÈJRšRe$æñF‹xÁX\=¢øã2¬eš¼˜°‹ŽÏ{Ç›m½÷Y BÁ;Úø>ù¢¥¿áJð:„,EÉÿl¶EÆß0Ñ6Øô¹ÒlžbR‰F‘3^`¾0ƒÃ ÷’Cä)aô ×!î ,¶ 8\aשƌÊÐ'Ü<MùQhØ0 ›„zÌè`rV Yð4%3àYÚ$l K‰ð(Tª€ñ"œZÉvrÚn®ÊVöìÇ‹%ÝÈY´äò�2ܪ[ŸÃ÷ÝI˜Ã³“¨µl-Wq¸¦ òibáIûЬ¦Ž Ûàzl’ÀaÐа'¹R6QSž@uFQÉ„Š2xíÙ©òY‡(>Q#Â?9 Ìø”Èp§CH…–?Œ¶*\Zžæ‚¸ë%΀Õ-`¢qÅ€3ÊaÝ3ùÓþ!V éùÉ#íþÍk’Öóúü�m2Xµv•5,×P³ë”׈^·‘ïg †¬Ž³Ìöd}…=%Òß°Î} Í[v"–ŽÑÊZeø²'©Kñ ž�ˆ¡<¤Ø Ëx^X„ Ϊ¾¿øjMžÂ¢„ä=;3Je³Ôý©ÿà¾!Uô‚ ,< ÀÈÁäŒÁ(Þk �&Ã5–G¹…¥­ˆ‰"Y�*AäA�R×€Ê$ÏføxN•ç\Ö€}ˆÀ¨dg¹f °EDŠU% ¸VàØƒß†V#”d'sgJ7 (š”®.¼½3—wryE´j…V� ì�¨¿Tq€ÚŒ pæ ’‡º»ô€£©»§P#PÕãŽgš „¹67€rÛ@žÂ¦¶‚ˆˉpUÏ]á:¬*P¡¼ñ�¹q¤"Ê ñj6§èÁXh’[iÚ'¾å€õChy?Û’æ+Í´˜Eçç>c.WÖ­¤7zG\Bcí-:m4dµ´ñ.9O”å•ÑÛôp4ä[²ýYÚ”V×R´ ¬‚%«œ´­6°NsDfë4#Π1Ú÷mSCS÷„å[Š¥zæ;Ó«µ@Áü*l"ß3IY~E?kéXE^6Keqø‹òƒ€8ÌU.Š£d~Þ:ÎL0‹¼\té”e¢\.1q§¸ÙÏ„jò2-Y&‡ 7«YXaÂ2y¹È™é%Jr4‰ ²„²ér»²Y‚VD¼\?y ’³òrÓ^ê ¼Œzr@Ëäå-•‹O”‹¼|`ª\tûÃPO-ÎD‰ï„ g4\$Î=áA}òZòÍ8e/xýbc‰!+áìK „CDæ‰`ŠÀμÕU¤ÅŒ\ðVcˤÃ:ÙgäËB¢-iHʧÛRoçV˜ôK2ë'pòà™€†\7FtšM¢zó>”DêÖ3 Ü£�Ýðl†WOFä±ðRÑåÛw6`“ÈšP( "kVµ5”`‚ˆîpfØ�,•Ã$6`™¼l¸ñ6ÂZ’§Ä¾Gƒ0sŠ9çKùIRA®Î�[% °'¡ƒc2§�…"t;ô<)ƒT&Š À¯Õ MÚ¶Šiƒƒ"ï O¡P0Z&§*`JÉ®«�89ky”Xù©T¡;<¯’€ �EÔÛ ®©-Ø5 V+AE@µ"Igˆ(*Dkm ÆŒ¡å)Òl“L@S ¼¬…Å!j†¼3“«UÑ´6Šô ï|âéß±Lž5=“ Ò >£r¨Ð Àà…n¸âpVÄ™<‹)«�f@3ÄBÊé´$xa-Ãk IwÜÔ&Ì�£Èûæ#3@€T\oº'e»²¶X¥îj!0<©<èÆhµ•òkO¤Ð4ª°¨  rÕ›̃{®ìúöa­$t–hùiv7=HØÒÒ%5w†+�é1ô‡h �dœR70–ÆKb'!Ë šrB„·Ñð`ò ÖÍPÁ64´1V!�ç·ämÑRÞ#Iº¼éžfÒ ÷µ àYðŠÃuÀ¦ö´Ã5Ê™ @ƒ‰¼CPàz¶C&<�[‹3ÁŠ`@ûÇ3Ž2-Âl@² Yðy ”A&LTŠ€ŠŠŠp�P3¡ShBSa/Ø6ˆ^àû„7Õ�¯©|¼�Ôø¾*ѫРAG¸Ma¹,å–ɵ ˜A˜ÃgU(°Qå:`Of �x°\-ŸSxVåJµä�ª‰Šð4�™<4š+|Мs@j ¯�µ ª8ZÅÎ÷� 6æqé’:<:ºóž»yR§°ö𬺟Q’-ÝA˜± R¦€20áF©’ ì·‹%­q[· •Pq»ªÙ”ë&Ñ)4á ð"’™ÁQ�Ü¡óøG}‘ó:è¸Áu¨Ö¿Žp*­¸Rz ¼.¸1nv=~åGÛâiÀÆe¢~t.p¿ÞÈX ifM‡¥õFÃkRYôF…¶´Ø}íñ¹¤ûõ˜^è’7´«©Ñ%<ÇŒX-µÌúbtÄŠÂQÛí·\7à%Þqw¾k¾oê‘8rå±1rÞ·rřÙA˜çsÖýÓ΂p;šbeH˜*Î+äPâ0±�¨uuò†o—àzz:E ˜©rÛÙÓ¥P)*�s Oè%¶ÁóÓ@ÞØ*²š£i*²g–¡ÙbÏ«Dqˆ()œÁ¶)g 6ˆn�E>a»�ÔˆhÉPSIÚ󦨂q ˜�ϪP(4´š‘Sª%§�Íà;UhEè §€ %Y Ûȉ$µv YvPQËà…ùj@Í©UÞªœ8áBúšA S˜×j�Ô©‰"¬Ýœû¨K‚-Š qøÃ„ꔬ=¥,r˜äJZ,’LJÆ`€ 4d™#2€Û”ë4l¯×MW°ý|ÁÓ¿”øëG§Aÿs=U¾¾8¹_¨U÷” äµ.…¤ÎEÜóÏÂB"íŸ:­ŸÂ ëF ޶€ _DæÔØ£Q2õX`£[ÚtV”hèëñ:m×–¥#)K•Þ¡YLò†˜!6Úc4Ñ#Ô–†A‚›q§obXŒr@ü­™&ÂQAy= r~úRÍCÇ‹ ž7üv" 6å®ÝÉw3ÐAtƒ�\7§,º(Ÿ@…ÔÉ'Àª¹< Lòšðy:@è*4“£�ù*× Èȸ[ýÍã”,Ãx¾� ZÖàC¢S‡«(i€ªbÐLh^ÍË@ÞpÃmOÍ:¨€(È¡JF¡ewk ÐT‘² ¼f è⻣�¸=IQC–ÉUÊËJ3(Á„̘ȻùS931Q@@•ÏÀ†‰‰ l ›’œ&Á&ɾ TŒf¥Ð)òU®9&×Àá@™Ä¸Ã÷*d¶»€ýOœ?ºùggê~À¶1¥¡bÕxþÑLÎv#o¢F‘ç(‡ƒ5·s6‡Gµ<ÊY€Î<¦wÏdG•ìî(`N• ÌÔ€»> ¾k”7Ù9ëúhÞû­ÌKj¢‡kÒÀ¤·GŠõU|-k"úºÁC6œÐ.ÐC•QDV2­°&aN÷å Ïƃ³åmáC- ¾!Ÿ@‹ŒØHÙhZo4ÚZÚÀUú¤“èí¼¹¦¿©Z<l€Â2ô:áñÐ^õÙXBZ‹@ ¡&|J˜È—à®6/Š”5‘ƒ€\É"Ìße ŠŠÁ5|‘³Iñ-Ô_ÎÀa8"¿lp‘]Ãl Í@Þ?gkÂ*âN„eI£È(Êu•X˜Ê«û­Cȃ—A jWÄ`aŸÁ÷Q-ÙF.‹R­%mWòÈ •Y Àaܤºo™¡ÐU�a*4ù ·&Jlƒk¦¦(9TSTè˜Á³™È‹L%ÇÌåÁÛJZ5§ŽGbtƒƒ‚©ZÖqiNE‚I€b\…³ö<´W‚Zi¢�ËÌÙ±·°oÖ¨–ÿ¹œû+ &g*Ak*ˆ£"ïpMWmVÐPÌi€.eaWª%¨9(Oh“3yª1#'¤{qÌP§Ä*Sï®L? ˆ+$”È$:Hº90º9Æ4¼D[ofª7%öˆ÷ÄßG4Þ¸æaÒ‰ "Û§mβ¦œfv‡ÌàjaÕ$ú¥ Œ³B’­°É°!‰äiЪ¿üë4P4-Î)mÎÖSè¦ÿÅæçy?›ÏÓ€‘´Á^‚ðBûZ?uƒåu æåäaU€’,Lè´¤ÔÍ_D/@7P3¡^\£h‰¼›ÐŸ[E°l“¨  ™< ä÷�i“ƒ �û§Á€J*%5¿0�HÖtM6r:x9Læ*‡�ªMÌB+p‘O`F�� �IDAT™ô , "œºFÝ6¢9°ÁË“Ä6‰ªbd§cW€ŠÊ]“ºãš#&ò°(Æ)öÑœâ€í†e [³a�FÉF)kp œ™è* išJ�‚*@‘EÉqy˜DÞ!¨¡æä˜™³U>.Œ'”ì)W5{Öž~¼”¥ psP6HÖFI^…®¸eݰŸÆ‹60`ܱÓCš^ãlMáÙªc?®1ÕÖ(,—D,W÷â Ð…«Æ^n€Kp…/t¸ºC ‡öÐêj“½ÞKˆâj$fùÓ¿}E\GýX%‚§…ã‹ …ý| f�í!`“ÃM=É^ïO¬¨²Œé±õ\Ãq®ùCVû´îŠâ ¬=gNNæÖØûõ(ÇQè%zb1Åú©z#ÖÛ¬7ªDzÌ9{+x !øþt7u·¼<B´×‚iŽ(4–)͹dÂß™"ÝåEÈ$kr€h& hà ¹ @§ZÖ„^tc™ì¯0ˆhŽˆxqíTºIìIè�¾ ¢bLÙÐ@¹õ"žÊ��Ë„æ`Æ€"¼�· @Þ¨[|f€ÁgLÀ€†z6À<JšJ²FØ&É«%F¡‰#]“</ܶ@Dw HÜö²}¼Çá ;§œ˜}Zò+éªðsäÜ7\ËC)–*Šf[|Á²³j®b’|†è(M×ÈA5—50£r€g¬QÒÁ'`Û*wÀǽzpª,Í“q|`‡PAndè°=‘?0eí)i**&jà0PQTL˜ÈS>]Ôž)`¡FôjÍ®ñ™Bv sß �#§=„,4%…‚©nJÝ2Ä)ÍEXÀ$O]?r k\i>ÎûškÀ\4[E°Ÿ¼ê×ó¤5ž›Ë7{¶D9(léM¤6.kƒÆãÖ1ÂÆ[=ôHƒGèa§7Ab*Ž•ˆ3:‘0Å×RôNÀ´6w{èµó lîlë=ñÅÙ“Ÿm‹x;EpÖ8­Ý4B�"S½óæF¼“F}½!7÷_n…‡‡ìTŽNiÓMÛ þ:mŠú—"Ÿ7Tøñ’^0Ôÿ_®Ÿ‡(¹Å,Fñ”‰§€²—Wƒ¢Ä¦[œÁJË¢œN½`§çKw½ë0“»I&¼óþÍÓnc¸[§šºCT.bºÈŸ39{OYüàÎ(wó|a™ÙAÊnN ¯ÜYzú�·À§EÝ**ŒºÐʸ›�uk$”áöK¼Y¬œzS X”3“—‹`&·Š˜¦¥i ë�Ÿ6¹_¨‡Qq@Ä=m`•y% œQ·°s+ªrËäÓÖRÙä¾Tn5¬ÎÌ@Hk}M6V°i¢PÍ×›ãSc¢•¥]Qv"ÑÀ:ÜÝíЖô›³6äK©аË30È<‚^Q¾tJØëçtÚ®*°\'Åõ€HŽs˜Æ©`4,}ëçsû\=w<%ÁÀjËhQ½Îð&-¤ÐÀXP” \‡ë ¾Ç ¼° ^ç1…Æ,…€¤f‚™n,Lb‰bô"žZgQ®2ap€èÆáçö˜š4À2P¡È;IJÐÀa o”t“h&tJt·¦& g ÁÖDG(�<_@ ¨©S5¬ÈAKö$&„/×ð’é«nå•×ü2”[ :8Ëp`j 4}ÒÖ@˜ \3`«Ð€},ˆÎÿqÔÒyC%Ú3¼z³³*ɘ�¬*·ÝD¤b<¡»DŸ3ƒT”Ü«³šR$ûèvª€Š|QË@žbâEL8qNØ=`<LÝ®à%ÀŠ*¬C„ÙQŸCì*ØC*ì‰m€KØ»(± ÂT®ƒ+UÔL(& æòŽˆ0.AŠ€Cö©\y–9…`ÁNŒr¦­�Và Ü`…wøFo’O™ŸP/Á^oxIa#<†krŒ–Ï @¡¾6\Þh;tÞÝ,îL§4Ö‘úmDÅJñÐ^Ö V ÇÂæ—“ -Á{œ$°®.SÈsÑË«Ü4)’móso¤<ürÚ L±È V Bý­:nÌpf1‘,Ô»2mP/‚uu#q™Ö+Yº¥ÍŠÞ[ ¿sk;{wŠ÷ˆZfõdM0å",³T®k*n¨£éËÔ^:<Q\SÆ.‹òpnAa0A¹”Á\Æ«*ϲ«Lp·hJh£°L^¦ÜW¬"˜‰²é*F"^Óg&g(Y·ÊÅ) n:¿iŠre«tPŒ˜X9EoüM÷»eð2p00M–¸MÔuÕ20³qML›(S^vu{¥OMî—6ù´ ÐRÙs#YÞËË&@Ÿ´Ì)PnQÞXgmÊm¤Éã–}¹±z(˜*ݬûZ‚WÈÊbdÖ”»%aE–¤E«øu–°UµÞ?2›};ÇÅYSaшlzq"u{YzBoèì<]K¢ŸpŒ^oÙ©`ItÚàˆ‹ý–¥9¹B= «8FX¾hˆ´ƒƒJó«äŽz„IÀÞZ?ÔZ·êº>®¬0•Òàîå47½D½úót#‹r½�­àx2ÀLäU€ñªë‘˲sg…hé¸ÿT}e†¨pÒüà®B©–†ªØ L¡…f€QT,"Âf˜ð‹ˆåIdy÷¥d ¶§¨åMMx›'�ËqÏsÕÃN(ÊÌäYŠÁ"N‡iàšIž°›k»¡:HÃux”MŽ*Ï‚§UØ 4ÊY+ «E�Z¾ªYµŠ]„ ¢«|f7Ò5^qì DSy%‹VóÈ DsP¡³{M7*FA•[LÐ’  ˆšÃA9L0 %æÀq�ƒ`¶Qr%j ¹½ô 8Ä,#7Š�µmÊ™˜¨8°2÷ç±ß ŽƒjÌuJt?£“œ)D§¾š(H¹»b'ÄJ0ƒk;çKÊeW÷-ÕO)‹õi4ØOXȳJLmxY@¢dç€Óއ<zc±ç¹Ù¨Ä8Cr}sÝžèêCͿģ zƒwÄuù„iQ\)7£¹œC»ÒêêòÚ–!(¤&çéM º³/…ýQ͉iƒôÊÔ–AŒú’ŠóKëMš&kô•5 )ZSz ÿ”(©¨Ó¦f"ŸšÔL½ãl"#E½”£)*qò ƒ»f“3ùÃÀmÊóp«û¸æÍ‚mˆ,°á–qÖ ÀA1ã»ÊÅáZb&* y \4ÆÁ”.œÉU>#Þ9I,`\åÏ[9À$Ñ€Qƒç)lƒä) ýX6%ð²ÀÚ&t:À <ë@åLnS^VrŠ m7¬Z)_ãO©ÐU€BË@uPÞÃkwò»TR1ÁTÔ(`;€Ãm(*ÁÉoáN†Ì¨° Àà•ÝÄVIÄqˆ>ÉÔ’@Ñjódzˆki[YÈ6T¢©|¯æ}ˆÏ(ÚøNè&Gž¤Íœ® «B+ªºV²½**@ÞÀ€°nMPX 6ÔœN9&½Â–aè“ÈÈy`‚Ô¶�d`«„9¶J1kÌh(Ù*©Mô*,•_}¾@4а¤ÄV?ÕÖÍòõ´‰DÔrã˜^âú‘·Bƒ/Ú?1ã…´å¼N¬0 &¡Ý¡ûçæêEÔá2ÎÂaDo/€EÈFzó‰Ê›…úH‰~Ò$D&í–7oöH£ Ú¨‡•-Ò¦˜žZQN/MwI¯[ÀXN?DRŒhd£4áËP [¢‚P­zXÉ–ç vP§ÀVO¡ðT‘wÓ“¿4êš_½ÎÑ«™ˆP_h·Ür1„èà6À"âˆån^#€©„y–q¯À$tJòn¥6’§Ð�Û[ššQ÷Þ3O– ª5 ° P%ºÐ (ì"™9DîÏcôwÀó*^�)Y ¶Z�Ç$× d Àä�‡³‚°W ”DØ’ªò÷ˆ¦¢Rå�Ù¹…+7æ,Ï«œ©ü`Ê$œÝ¨m"Ê`öyÕ;²Åùƒ`7´ÝP eÁµó‡ Ò<›‡ faÜá{w M V‘¤UÔT’ÍÙà·Ôj(ƒÀáù Úì�UÛ9¢˜|¡€ìdÉJ£â�5Øpíì(@eqäÛàŒÂB *²@Ù%t DpèiŠ j× Î(Ϻ²0± Ð&KYYƒÌ%˜ÄÎä² YSÓLÀpIy€‰¼‰ ]åö`–†œÈü*¾ pJbÁX;¾åWèk´§#ºÚ䀵]ŠìG.pF—+õ½z$|H‚)2iØtMNìÂ96h„ZPߘþaì€ÇQHxÍô=9Sd™6ÿ…:õ‹E$ሠ·F¢æá_k½ÁXv™RÑà¼!V¬%‘wÚÓpÁ ê®!»Ñ©Ó«‘Ÿ¦õó {ÌѨ:Íh½0–e„’ñº¨¾ZwÜe§n&"ᤠZ·4ÏA×`{5õNDçÛx:¸ßD…5ꚪôBÀ BÝóz0ø4PVQÎp È;"¡4t¶Qgˆôp@Á ²T_Å$B¡Ñ �¸jpÈVKš—ù ±M‚t@ Èþʱ›h&Ê�±)ꉾ)`ä”ÝT•œ*b§ª!ƒQà“¨<ƒ ²_Ðf€²ö%>º±ò~‡[y@w8 ¢Qè ö!T&s•!‚C°”'µÚ 3Àü&ÔØà¨ò…¡œ¢ðÚ<PÓ”3$}c *¯ÝÈ…°y;_ƒ6JÊд=P i˜š(å5š³*lš½Àu˜„>‰ XQÓ Ø† �j"Ù%¬àžÑ)ö¡dDœà«8®Q%k‘|1WŸ Ðh.ïp½Æk‡PQlœaØ J¬�Ëûÿy{›ÞF’4MðIQ$]2‰’Ò,#‚Uôª¨Zq¦'„žŒbfºP@a` @—ð£®÷Ãþ5øop‡]utÀ¾v‹X$èîÂ"»ªíZi;³ÇY•©Œ(³Tˆ’K)*÷`î¤óCÊꞎC!+¤ œ”ûkïû>_ÙAŽß‚epèüÅ}]ý"'ÖAL-Æ£ƒ?¹# '!ÖPŒõÆù½šç:pcnQމ ÄFV³sùœ':‹åT™ögºILñ™bÂQڌŘ6ƒB0/ ­¤Lû¨ßž™ƒ=ðrm™°cšÄýÖøâ¾=ôûφº¢ ÿu1s÷ß’'î}ÁøžÍ§õgRßû}<¿`b¿_,gäœ÷8Ï6c^(r‘;Ê54[{£Ë/)}rJF”S#Š-­d%MD>O˜-“¹MUñ8ùbÌûö ýZêJ_$~KAÆÁãA'.‘ Ò±ùé*B~ #IºËÝV¾ÈB€0Ê‹—¹ûÝ '†ê�w5Œ=FX^&´ø¸À‚ b™î‚y2bM H�öòXºàÍí€ìÂßÍL*q€ Î*µ~UCÒ‡ÓÎxŸÊÏzœmb]óÇG–zb!ƒÌ€¿?9å_sµ;ûÆ Éþq~²nÈæ'Ö/�ÚŸäð@z÷9Ðd¤ÅÓ_#5B6,£÷­ãÖÞ‚>’v›Å8Gý–g=‡íø%(e­MØOa“–{¥È1À¶, †0ÕA (sþ‰¼Š½lI´�8*~Àqæ?Mö!w4Ð1³ T@,xè´ìÚÐÜÎà’ÉjÈ@(�÷[q ±€ ÁC-•0V‰Å6²¨•áÌÎs´!ñ'¥6EÏ$§zö2_.Ǧ ñØ÷ÅœŽ“øp©sò'ʈœZøä¹³ÑäN{䂎P”¡JÛ¡h÷Ëá¦B–ýÄ&¶ß#v¢åA'|Gášp,°±©5@€p®ŽúÞÝó¿‘gÆ»3’~X‚ÒûÄåw©Ìß!Lÿ®¤¬àŸ©‹ü©;4ôþýÞã$t6€V2½È.`’¼v'Ú«8¿#‹¤¶Qƒf\ n¾3熊 ç�ã*1 TÀI H\8qª¥Æ)‘–“vPâ{Ûf)±³'ÃŒû^~…~xxáȃïÊ¡„DÀMÏŠümªHú^¾\jÐB’ˆ§I[óCÀxÙK2(·ÃCâfÌA)^¼�öw‘ÈÃÝ, 'AYs ÕK•]Ú½“í PXÇVÕX'òëUžý7I(§M|Ø]d¼„˜g¼=�0?R/ ïYrg!Ñç¨IØ]K¦š3�DÂâT'½Ÿ)ë’÷–%À²·ýø&Y«9¯û2#œü]Òxîœ�ê¿ÂŽev P®šÉVUv8£ .Rã8‚„m:Dc‡ Þ• ô[<ìÀ° Ai€J[ó …¿È^bwTV!®‘¶åcŸ ¶b3Çß:ˆ)\-Ä› ÇN!;gˆÀ˜VDðãªHˆG¥óʾÜþvÚdEÜïÏoÈQÈ ,ÒMšñý€¼Ïó8û—qéa/}I†SœÝâ/'êÀŸZ'4zâGÕ(§˜ûjå,ó”þ­<3‚ûb? !ïy‘yñL²Ìê™Ý#…åþú®ƒzfTT“뼩y À›‹³×§¼ B–ÔC~Ù7Ø  crpBæÃøîy)wÞ&»›±-U|7Wÿð‘„@) ’¾™3ZÒÂÀqNAiÑ6‚P(8)¤/3¯³ɸÃ}-÷ ¥Eè!޼İ ¦P¢¬õ—Fní~r!HŒ”JìÁöx* 1 ìa§ã`׬¿ÙŽæfD؇ÔÀKcÇMAdZ6- C÷ÒÉ.y­ŸY”J»öjk ûΛH‡À'ƒß&¬TëÀò¾R`Ç÷'ôxÏz,üö Q°?[]noð2jÛD* Þ\—/¨“~ÉX—v ‡nɵëDòŸ€lãïQœ õ_%ÛK2ðf‹£u`wÕ¯:ð=¸Çr„RÇ2%Àn‚ñ¢O2ýXàz°)˜‡H—"v�W퀻‚»àn Cx`Úøo3?â¿:n3êÚMB—�`ñ&DZŠ-Á¸ ði!5™HT hAÒõÌh+ç૳Ôsé×£/‰Òj1§üÉQcÎæí*¦Ã¯‚ î>[—‚˜4 8»³$Ÿ™Y qbÍ[âpÓW–0’wñ!ÅÔ¦‘’|z&˜÷þ ¥ÎsÃÔ ÿoŽúƒŽÙ÷\Ø{›”(¯àî¿øzæ÷DÅÇÅû‚š ÁÉÀßåóLj©ßˆqγ’|ÇÚ-žwdÎL£6GÆ'BîDðä/£äˆ8l€T¤/¸y8I+AHáØ±´ŽñBð<™™"Ô`°€EŒ ZÈ]äkŸ,€Ke¬yáÁ—'K‡¶ài�Ö‚ÊòIOØ@¸›%Z¼áHK!¸­ñøÏ|îoBp%3Ôš}<¯&7p¬Kùõ9;Æ'Ï¡²³‚Ö ÓçNÚLž_)‡T‘¾…ß“qhN)^@|ßËÙAf¦À•´ÉŽºÊ~ÌKèÿ=­¬&Žª¬ è@f/9´»vÐ@v²¬Hg@s%9ü=¶ºN×J²‡P)ìÇØ9'1Rôí'ë×õÃ4eÈ`7UÖçêXÚVÀX¢åxÜv¡@Àޤ1öˆ Ê}}ŠO†àˆðLã-Ä”'pØÀž ;ÆG„«HÚ;.G”ÄZÁÌ^âï9û™ŠÜêÜcŽM»TŒpt¤¢|¤šœ_CÊÁ¬³d0ß{Æçß”ñíÑCí{÷© ãQˆ!ÝQ z¹OŸÉ>š f®y2%û>5ÊLWïÈ©Æâ]¸ÑØùžPnXêDÝ{Œ)÷üY6οèüAÈDøÎAdë+¸sÈxO^ Wn æ|ó|€`–T0ïúÇ22Ó]Òä?á!�û»boæø¥^#(ùÚ“p÷XR: ý|É[è¤ÌÏådS¦QQÄ÷ä í IµPø"åÜV’uœLPD¤.a~®B-™€Ò�G„@ìñ}Ç‚ïŠ}”d;{‰ ì{Ü-H¦% [`”§�»ÒÚ@Ò<…ôPqO20;“°[ü%8z²œ_8_·�‚--ítíG ªøê[ ¾”_÷ÙÖº$O¾­$Ù§ >XRô±|6TõÔ¡@z)m`ßb -©µ„DLô •�å6•ägœtv!úPµu²~Ô笣^XªÙR è?R òñjÖe�Ur-»Úñ«�²9M€=‚Uw>CJ—ÛÐøÍ·ÝÆ5Ú”¶©²ªífí ýIÛÜl Zì³M¸©Œù°C8´Ä&ÜŒ=¤rG#?þ5~`TƒEœ ™ �2ìpPæ\E°=žº<Þ“ÐŽjqéjø‘Š!³÷Á”u]RÄǹv§­8ófžM1a¬Tf]O¹mO”ì`º˜<üÉï1àj9óÙ÷¦Slçº3…/ÃŪüÔÜQdä>›—0޼Gó† ‘Sá¼²ƒéëéJ¸ €'™S°\ZËïw2®U´‰ÕÅ»ªÜÿ(žÒ)Ÿ}çïÈž£÷÷e ½ËZCLÊ}'½f¿ÙÇX¦Ÿ¿,h+æ^áÔ‰ú9Á„Áƒ"܆ñîĪ´€ïd™bQ̤Òð£9ùº¡%-O`0Î9‚CH_ ’PK;8x%ÐÌ×<ðö;<›ÐŒu¸¯2ô�Øu\�G™gb&e˜[ä7«ŠàL€ n Ó.°9!8<ÄŒ"ì(PdA0™}œíš4P¸o‚‡zZðxˆx(`çÙÂaägØÉdMÃîð®'«ZZšÙÝ䟱š¥,¨ö·²r¢™¥U·ÂÝíÞ€ö±>°³ÇÏþ'‰ì€õyÈ´À} ú1¸&PÏ^Êf‹ƒÊŒš[ 2¬1Þ­8´ÇÙ_CÚD¢É^í¾Å±&{oyì/†ª1|‚ k]CZOâÒ§)…ìÞPõVá›,3 ´¢Ù/³ìðK®³£Ú:?ªôiÕV»G¥ê¨Ô‰>0wcF%üu÷gÒÎ=Q¸1b ûz�ÑÒ(WbpŸž³ß’¶'wöÀ"‰]N”qçöàv¸›%/#‡¡ûôK¥‘¾@Îg£©Ñeò…œÝ/•+,&h?üÎî¸ä[75@”-¸ËóJˆ±"oj»åBAîèðÊ¥‹iÕP·Çù†æYÀ$àp懎£÷;eÒ,æ«ØÂ҆ʟå2MU61NêEPö Px(Ì×]ýkž ứ;S, {[çêýÞ“wŸœœ‘XqÖ³eV©ýÞäËzvF¡˜àL˜Ð‰ñ5e/\º`i`P>ÙÞ•# Ù5i9†\4æÕñ}Qp¢¢ù2ŒïÂO¦ìI`ˆÞˆ&f#_v÷Ø€V“µ8ZY ØÑN,àF< v„$ÖË@•Ú”ŸAp?pŠÌ¯mw¯F4dMƒàÐåù¨¡à¹¤ÈËõ.àzÒ5”àyMÑ*£ž ’“�~ÀS«=¨]�°Tpß^÷%2d¿€.Aã)Ò€ÿ¢ƒ‘'”5–PYTý‡là(ã+¥›Ð„¥CµD“ö@ÖÖ(ù9Òµ+™­%ƒïx­—ªcyx Õ”Œàå9?zË…ê ½‰æ1ºÕd«Å‰NÒMÔ†ò°…¯Î’’sKú+ªC dÙé]¦d˜oB‚8ÿX±ñúú «Scl¥Õº�6¶j Žåø'oÑÓ`P`‹HBìî�í/ÙS¢«µÃ>t´?±X?K3FšÛ/5g-®š<ká ò‰BP¾ƒT2ml´%´4‚¸ø)2ŠTp×hAöÌ;»<âˆÇH¶gØb’ ‚C ÔÎ €a~ÀÝŽÁAájRäv¥ÔèIí./! 2ÝÏ“ƒBÑÅËPL•Åò&£0ý“'P‰j¾3»žL«ÞŠŸÎ �6~^¢éf|ú¨(0†YQ‚ÜÝà"„Ã÷v®wƒ¦áTLÏ £‘bÄ7yWàÄü\Òû á½ÿÒÿSÏ’w,ŽÂ{|d÷ôÝ çF‹Ìûïpz%K^rîZÉ/Ûb¥_ 椎8Ka0ÒvætUhÄ^8¶+ò‡9 ¸1³ó‹+Ü)N”ГaÀÇ+Ájžv„×ùÞÉ/’>sm3å�R|ά¾²þ>ÍÔÉÏœp3qìkø"E€Ô;ø"s˜Çýc~Hy ¼s–à{Üñ}H@2`hˆƒ$.sqÌ/$Ófò=‘CcëfðýbVó¨�ˆ%R ëH`cÉb@ËtOºÇ3(Ä„§äá ¶6e(ø 89Vý‹$»ÙP7 Øt׎•‚ÓØ_ Ts?NsÆì ®”³ª íMÎþ �N)Hþ±cÙFr´žT[ —ª«%šÓ'¿a>$í8K_«*e{Êš´ ú¼±|ÐØ`·H)k÷°ÔI®þÛöÖ ÃïI h¦Múe²»ß8«ö“ÅäRBUãE­6ðL§é@‚⤓v®ø ByOk·§š;ýƒÞ¦$™ôO$v¥ß‘М´’fûPÊã `‘üLp“¯ ñk©<Y¬˜²�xO†T€œà�� �IDATÛB@ ®v%Ó‘S¥ã8„t#ÇïH�®'Í>6¤Ò÷ ÀAùQáz;ŠâKLÿÎÔbî‹q×’¯òE>ûÓ{Ñ §¹ wËÒ4šÞ"˜uÌLf×îã°/o¦Ÿª§˜%­DÅjkºÓ“SÊÞl4»Dï/bá¼uQbŽ–`æË§§Íî^õÿÛqXçg™ÍA#øS¤x?È<LÎüþ9´Þ—6Zq¾�Ÿžp'¯°øïÜÔ³Ij#~jñ. s 0à“0s¸teë:±ñÄ]¤ÔñuJàm24¤ÒèUˆO}-2ëü]ƒ¹SÞt…4·n5úcôoŸ¤ 2Ž~Ë~ŽCæ‰r&‘8¡�bÉ\Ž|œân #Ʀ JÀ}¤G{ÜÞ•�'Jƒ=Å“>Î>æk—ÉÙ@0ò�oΓ䫮S=‘ƒ*ïVëR‘*²*ÈC q›èÿÏy¬ñ¿S´ÊÞEÛÚ9Âÿ2`ƒÌùU û] ‘X]µÖhŸ=èõN·ÓŽô[ˆ5§–Ôë ÀÚ�ÿÉÂ~Ùƒíƒ|ìd—’.3} ¼lÚ\Ôý[Ò¸F· Ôά“ÊQk ‹°‘ÞTøëXËRø’(d ½ǃŽõyô~±æÊ“,à Ri¾µ)ûÇ\¤%³GK"ãJƒÑDAÁ7öYq n±«ü 8Dê0ÀÕXxRyþDþ™ˆI? `)M|ÏdæC,Œ4å®gºoz|¼Ö(­@ý™›¶ÔËrNN#:Æøáºƒú1·Ô†ÓTZiÎþ¬�sMšclï-,ïq›æÚ–@ï÷Ö®û•Ê;Ëï=±è{ºœÇx'eª<¾½GfÌçà ³€;°‡©M:Š‘vV4?ó ç͸ÃTÝsdñe®j(¦¼’&¯ÐPQ›¡ÛxND¥'rÌ9ŸaƒÜ}!·«37ôh &Ùr(Ùüš)(|Ê‚‘‰˜TA²$±ˆh(TF•O€MjC?妑ß×G¾Y QLJd€ß‘  F ¢/ i¾F ¤pÅaÜ�Y ý|2à#‘‰V‹*\ &yÆ1Ás¶ËUWp²ÇU Ãc“’&Hò �dt{)ÊôcÙ"~B9!�E ¨×P»ÆÙ¥Ò ¤ª²SeW“Ê"°’èÇ@U6¾Ä‹*²ŽMëü³|Ô“ýU­É7ZÚú ÷šcpÔ‹Mn4úDfhl8´¦}T;ÝÎVäó&5§»Ð¸dd™_ ø~™æäJªNmà:Á;¾tjÕ['äLn1XMIͪ-¤ÝŸôÈ Óà¯/Òó*?ƒ|¸ rÉšî”rÒä<í&Öÿ©Ò:�°>ÿÛcÞò€hާ89æ/6%¥ô¹Dâá…ÒÊÖÜw#ø±€ê ŽdÉâÒ‡ò ”–/qà‰¢ à‰O¤$ÎUùHzÉ„L…„Væ jÃÙxø›¶ë! JE±è'—ÌqÁ‰ðG¢zL®%gëæ„”WŽÄ¡¡˜1-)«'žî<²bb{l&õ©Î½L]¥Ó. á]{rOb \N%7Ì!žóy4QwÑÌ6,˜ÄΣM=qÇV&¸{Hš?7tÿ—мÿIÄÓ?uZŽ?’„L=§~â\Ý{±tqgW2õ ½™æ%;Ü•e“¬vÅ®WúYù3f�: >?ü6˜�ôÆX\/: @郇›Ò?( ‰b#Œâi`tg‰‚Ê嵡«J&ò`/@"`1B†&Þ9>FWZž4¦¤®8ˆ ,áIÃö®@ é¡à£Es l jæˆäÈx“Õ$à)°õTžœ04Aºª‘ñ.iЧr­‹«G¼;üX^çÙ?³ÓålýTe§è Øæ²S«¿Z}¨ÿû5Y}½ËW5u«ÜÒRƒë6ûré!²SK¡‡/ãÙƒ:ªûßlÿµ– ¨—Ý6 VpxÊ|¿n“ìÿ�ùŸÓì–Õ”êo`í�VÊÏo€«ÕæN÷Ô›*·ìdÉù‘~uõ‘Ößàh Ð‡ {§—þm¯ô9 -‚Þ€ãDBó”Tâ˜ÛBZ{üh7ñ²ŒR¥)vŽ îÇIØsì …Ò27¸Ü°¹ßâ;bûßbñ®³à/€} pK÷Xh²» ‡2�…Ì Kö€L†~c+ìþ˜PTúÂ`¼, ”M(ó¹6,­gß/q½CÎ�¹þŸÀŸ©-å/ŸÆòÙÊPf¾Î¥ÌŽþ2žlï ±ÞW@÷ž]È=d¿Þ{æq' èÝ„§ùGÖ< Ot$.Ÿ;d¸˜Ð‚á¤z:êóê¹CRyD w|¢ds÷Û¡ SܵI´\æoÀ‡tµ™;å¾"Ï:ιR‚Ï6a±d E:ãHÞ\"7Â$( …„ËBðX;~‡+ð<3§€ʧ‘± à1¤®r8„ã–Ú¥’ìáE~r+å†)8¨t…ÄÞ6ñ =nïqȼG û-žp枬�àS `IãÊ•+) É„8¡Ào+ã'E«%Ñçkà«°X¥+ÁøZ•UÎ_}÷†]\¤KZ]_¬ÙO˜Ò“5¦‡CÒ»}~)Átw-{@òi¨¡†ÇôAÛ<nûšéoíþ : [šøâG³¨TdÖE§ó©µÌú´¡þÞB¦²Þ'içôLuûmzÁ±Ü~]µßüáàêêóÅ!]ì®.ªÅkûÁàùå%z×òƒÞù7¨m8Ï–9ëûÿ [;à– KóÞ�è"ÕÀÓ„µ�  ‰/:`‘óÝÎ>q¾�8žs¶—„ 6•;®†OÀì÷ )²ŽŒ…Œ)g-wÄø H�;{Rå·zÙ$àÖ{1x(àFœy°c ƒmÖàq÷„A2ýÊÝ“Ê%EÜ!ºc?ŒÂï+0(²ã)ËáI·¢°„ð!˜ Èúóå®åï”sVLÁ”ô©ÝTXªò£8,·ä�8þæÒxNØÉê0f©¸w•‘ |ý<¼‡;Þˆ‹8ëû9\Î#Ýøÿ <%q?Ÿíw0æI–%vAÎ`ãwí¸Ø ,Î^Ø”üdÊxDÌkä1•I+§É{Ñ´ÆÍŽœñ7•ã»GŒ•²¸N~Åfà(î6£v–a áåa2á,&Ê.â­×ÍŸ7éšñ�¶6»€+¶$¨9œ8„ŒcØ ¦mPTªˆ›ôi£®Rrï~˜!xº[(?MzÁü@úT†•ÔA* ³ˆïC¦»�…aF²@bYJŒBŠxnîäÉÜ/Âö8ıàˆx· ôT«%{T*$¤g>Õ¤×Hj_<<ÇÚ^¼”ßÞâ´~Ô=n€K¬Û×_5n®·þÝ Èò×´y!±Ìõ7޲GÊ2Êu-Ñ«ü÷Tqôæ&]ÕGŸõ`=ÉÖz¼ÕM³ ½Ìžýƒ¾¢œÛx<ÅùЩ½FmXÈVxóšëŒ¡öéqv°XÿôñŠõh-[žœŸöjFqF UÔÎã[üôQF«t}èË ÛÒ™ÕL°ñKà ·'5IÐ2<{j§} ƒMxï9£h%--ûD6Den_‚Z 3 kì{;Ü‘6^}( _s\pÕm%T'ØÄKHdœ™Ó‚æà1°ãM¸~€ØKaÇ=i¢ôùu¢�X€øôeÇf”ømÌìKK-fø©¬  ‚ýI\ן`M<ªqÞÆÉÙ³)¬/E‰M4£#uE(ÞY励£@ìÙ2BKœ”`Æ$JŒ­Ÿü8¸sÝέ¥whf×GÚäÎ÷—½³>ÿ€³á^zëà¾/5CM+˜^x—âÌ-âSÊ‚šÙßë]âÉÙ)¡ –ÉIðƒÖpåÌœ©›o*÷£œç3u"ÆÓ&Ãã5Ÿñ2bÅ6 jãÛÅñ˜g‚ç”êÉý£É&ói ðU7·*‚ #iSé·øŽPá8ÁQún4na„0àÐÈ€X(W¤ð$ó¸!8žûQq£ „{ù' � mžR DH;<à>¸¡ ø€ïÉ4ÂNÄYÎéæˆŠ€À` éç؆žË}H_ðHƒDÁq=¸�ÛëÀ)Í 3†÷)Ñ»è4@×1¬:}’.2ÒÌ´®ØK‡êãSªÓ0`gÍlÕ>|PÿåõM/²Kh íoüß­ŸÊ‡9™Åª–ó|€îcÕ«Ë_ ãäÚ†m?°@/×U¹ØàÏÞ&é·šXͰ´œ’knHz-<ÄÉ$%€º9èMÔÃêÁ“·{+çë½AÕ©T±´ŠJ•®ày…tÏÉÍïØA¥Ž!œ5}}C7û¤µœ‚8tCÑôàår†G @vÌ3ƒ“Ô~B$Ù¥úBó0SšrÝÁI ¶ûWhý6Aᵃ.#MX@eÜãìDwuÆôA¼)Asë*´€Ìy¼<†ŠJ¦e„wG@ ãá¯eè%û4p”úÚA éX¦�¨HêVêjÄ{ЛÅÄ?ɸñr´ìu‹‡Bù"kÂ.3˜iíƒ1çÕboŽûi1IËå"0Ë îP‰ XNM(·Ûåq?œñ½€WX݉ÒR!˜óÏÇffáζ³+ NÉÅ‚Éâ3»™¥�(ñî÷çœ þ]´ª÷®¤f ´??:OÚS]@áVè–¾g>µô.ô¿ü¥iÉ7Ÿ6YÆ©ü)5ͼ— góÑ!?áÒUPÌ“ãnPò46ïTK(ýÒýcŒJ±_ â.�ÁÓ\úÈ¥R,rGI6’Ýiìx<ìÈ0â 2Ü‚¡ÏÜ7>•®'•ànÀC0 wb@žscòl*wa”ƒäJàÈìд4â‚<v- òˆÍý€ûB-ID{ÏíÛRpx’\cOÓï8÷þt|!á€ëÂß3ž£ò å7µ$¼múWh­¢6ÀGVRàë³´²Np¼ýØÙ—¼ò-š-VÅ3r^±Ve7;Ú¸u6ÒîÆÑ·×gÇ×¼~‹Z]ýxI^nȇ]öìËŠÔ¯åÛ?¤7½ôüGè} «n¿Þ@üå™U³¯©z½Ì¡ú+L_âŸnØf†þ€5αµb=¨4Ÿlðú‹×ÒZÀÒ9´õyõCòᇨÖjXúªûºa©ì¹…Ÿ´ÚŸ_-4ë‹$ûiª7˜¶äù?ÂöÑ[—”bS’¿Jú€uãXUÐæv«Ë¶R’´þ S€¯·_2ç¤ös§MÁA= ŸÓ'm©ÖS ‡â³Íí =X;…߃ۂ ’„”+OP숳@¥GÈq¦’ul?ƒÒ@¯ ÂH‡‡^êîr¥7�Zfà„cC3ŽƒUV¬B€Ey¼ó[e²sµÍÛ0ÇY¦fÆÚܤÛÁ¸Ó/û²¹Œ1QÖý‘éY0>x&°e:Þð„óB$Ë¡­þ«)Ô„¬˜ZŸÈ2ÿþNóñÚý=ë<#‘û¢%Ai+¼/Õ¨°í¼fyÇ+Ìu4 ÆÞ>sfR6tO8hX0:¢JúÙ4e#3Mr°Q”á÷wGW…0âLC ØR/ÇëöÐl³ñbŒ1ˆ†i 0$ Ê7vI€ >Ϙ‹<EÀÈ”ræ™%’‰‘áŠnúM™ûõ �x !apT´áîËÂ]ÉNŽÌGÉÐ3e2|tü˜äó¿6äNÀc@Qø:GíH„4?<$Zð3¼¤Œh²HÒ:ø$°ýÇj7èö$®3\ÕøÒròºâü²Œ‚®q»lW«ioeoШªî€ëdíõªƒYyƒî «í:ée·ÙâpvCè‚Õ¸Å?­×–ÉÙ%,goNß’ú­þÅÏÚƒôEÆãÚç„4†­Õ«·RYìu7°t«7–~tôàzkÈN~ô†~O{ç¿G6*õ~u…(Xo´^ºÒ‹CÆ—¾NN—Õ"ØÕ™ªì“ÆéÏ;ßrd ‚Õ¿©â,“мFPÅþyfUHsÑÞÔ²³½ìdß¼RúÈÖ�å ô[Jè�O¹ÛMâ†=q å8Z~c;>1®yüÙ~ -ʵÀ§Ø×I ‡ cþŠ-àÐè()ß×H…lï±ZFu Ê¡áC‚ò‘n $w§w¹†©)ðzâ™ Æ1·cr§¡Y£|gNzµÎ´Ë”–¹<Î;i÷÷à°L¡Ð éæÿö‡½ì˜¡#cp÷ß|_ë»C›ïÔBwÁÝ㈀‡:žÃîâeYò’–˜¦Ì†åc3˜ù”ÇÒ-‡”…4J¡F=?ÊÔôËX˜À3b1ngBSˆG1ñztðw‹>Ë$©i¸ Øñr“ƒHƒ\ÿ\0ùøècý½/À |*I ‘B`p?wƒ¸pRŠ£¼_ó¸Da;{¯ÒÑ«!±) «@ŒÄŒk*0ÙIaÐ,¢è-dŽd „»@À•€|€E2ôr‚¬G|!íâgùT ¤¾©Œ7Í¿3óà›À Á‘ñ}Ê5ðM“±ßQ‰(źNH3±–kÕöò:\•_½u~úõ+œ³Å µqʾ­óz}{PC¯®ÈÇ´·ŒÆFò£ ²VWÃ^òÑ5[yÀU»^ÿçÛ.°â,Þ ¶˜VªŸöuoXÍÕôº®ÖW°ÈžÀÖ[Ò°‚x=¡ËÝÇC<®â¦~¼ß­V·oN³þ¥uó¨FëíZõdé”\6ކo¶{kÙÂò/¿«Ô²þ^ªëõª¾ª«õ jý¿é/+ºÁ¯†­þZ{°jý=Ä%'Õ”h 3ùz€Z ½-yøX.ÚÛ?¨ZÍêo'Ö†J¯¡ˆ¶Á³ç,û™<¤D[Œ€7Ÿòf7ùìçJýÜÞüw´÷ËÏÌb³³Ÿ€ŸyìÌÀÈv ðRÇpÁY�_  ØæÇAJáìEæT±–ík™ÃlÞxÍâ–†p ðšr1é‘'Æ©Se¾Ó(Ýâ€û%¼- øh·^€jVwvÕ`ÎÉh„‰ &ß!0Ɣד˜^;‡˜#é-Þ¾œ äÜ!ÎÈ1È)xy®†WÌáú›Éý{ýþvJþ|ot9Ÿð”¨isÂù&±þ; Ü».ѽÇÇdl\fRüÎÝWi!øîüXì;„I3!ã’CïhëWôѲŒg�piì…sØ ‚¿;1„†- 00€&$<�œ ä"�³“¶&±©IN­,˜à2Þƒ í82}¹,ÖŽ…Ý·€oD«`1@ÀâÎÑe¾'C FÔe@Hg?â�÷)÷„Ôñ4‚<Üt�„›pÇ>99%ÃàF� 4gQž'aŽä8â;€$2¤’ `Oý*B žs.=„X� Œ¸ù3ª±YSYcù窵ÂôU¥Ç¯ªµȰŽÊ«Tz¨tWìÍš¼´,M¬m«‹SœÕ’Á³†v=Ó•k¨êGi¯Ën ¾]ÂmM¯0¼‘XU¼®�—Îú«œ¾êÿ©ºYÑ—ëüê¤êj#}|‰Çõíÿø¬9 G Ú|ƒ/^ƒžœÓÊ«ÇURYÆÕÛ“…S¬ ²›kþÝò+ë¬Y­~¾Zé/÷äõzÖ÷x´¾u½ŽjEmëâÖ5]Ðë mýŒY«² a ØI•+Õ~ØO賆Ü^Äë›d¸Ü^ÍôâmïA“œ/Ù6f9MšËÎÓŸãÙŸjÇêÈþÆÁRƒV+ìY-­5X€ÂPBªðÿ ånánr”åZ™_Ÿ ¤ûà.Ùfb(xÉ/`7 [ˆÁÙž–jnX¢±¢|»d=2ÁDŒ.+Õ;6¶ªÎK¹;ÉUEy·>E„ îM$ïæ0ƒ7Ivc÷Éó•¿{…îcÉÔlè¯_²ÍŸJ¿ÇÇC8ÙFOöÇrNÅÞÌ }ÞP’–ȱDBÌSj”0Øùñ§S‹ó¬Éß3—Ì7eâ£/GÅH¾4ùPAR¶r çÈ37ò²GÃìd$7wEñ;¥XcgV^QˆÜÐOsL¢øev"“v�£ü‚p˜NãôD³‡9ƒWÒ)ß«†Á88:ÂMæBÉŽVhq¹|Æx�d |°H2¡ÜÐ hÙ]­bpß+” ÒÜLÀN¬e(¤ï aìX†�ÜbjC Ø�„Zæ¦ ^NH5×àz;r�p—ƒæž Àƒ2ÎzqÄY�t ó»²¬ô#¯ÂÞd¯úÊþ †æ‡MXôz˜^Ö­›ë솱ÅSþÝ«tRû¹SßÀÚQóCåþöò‚j4ä`°•ý‘Yug¹b“ßãòmÒÈ>\äo¯ðOP‡Ó£¨¬¨>@>ÆùÛ-¬«º>Xúx •vïšW«¶nnС_,e½gÕTZÿÔº~E-Ý­n¯Ö~ò1][Fo ½zsaýï—to£zúý¡uþéà´]¯aekä¤^y–}Hi•ô~²d-­aõ›¿GíQ»ZU¿:å5ÐV&™ýiþúÙÍ¥ì§QY¬õVÕÃ¥´Òo,uAÏj5E×*—íì5=jA·˜>M_/kÔTãjëò«Ïõáá–fb©çøqœ„¡Ñ­t� ŸÀ `“|i鿢0 Ò‡(�{*¦Gƕ؅ÿWÒ”õ0lû…ß—[~Š^ž¹ÝÑ LÜÿe5@L×GD³¡"oÈFí_�>¦ƒØæÑß§Wñì!1¢ZM€Õ Di>ó¤p÷¡ÿ3´Ô9¼üy+{Ä6üžÒ´¿ò}'Oö®øSÿ}xˆ÷=g0”›ÑãñA¢"„Ô)ÓÝü©#wà=HŽ?…uO€¨d4gíQ/>rõ*2leøYΓřÁG܉1‚$¸çWÂsµg�c>€ûB†‚p;¾vìì{DyN¸ –I`{”Z¨¯9ü*wÁã.{Ø¥ÿžÂj1AX†�¹c.^›~'Wtû©+@š#Í|†¶HŒAìŽ|°Áp¼|Ê]ãIxÒŒ&v„ ºð!ã€Çà€´?@F9´$:y² ÐÄ"r]§«à­†"y[Yïu¾N³3ëôûnåãûøÙÚªF‹J‘*ÖRgý1²žâÒ:øŽv¿»ÝXòv‰Õ.í…›“õ:ô¥¼<K±AªL/\6ד'Y›°Å«¹ýÜ2J1¸¦KìЂýv%{\9ilЄÜâÁ†}ƒƒ‡qCSòˆ?°ØM…Ó•ƒÎÉh¿öj°v5ìêÞ W(\wÉ¥¾¾ Õ¬kÞ·’¬Þõ¢u:l]üŽT*‹µÿ®>�[¨­€6Ôði}dv»¿ñ ÍÞ¢Íþ|!ÉÖÒ›:ëAŸV+hÔØ`i«ß­.Þ¦x Z?NVÿl«2Ìþés‡_°L6Ÿ¨ÖÆÖæ¬ —oOn�Òá†cÆ6ávòô=å:hqÿXî›Õ‡0(v:mF€å ¸ÌÜ·&1⥂ÔÖ’Aú`@wYH¡Øî1R‰_ª0a€²œL>²† …Tsm‚"wª™{Õãw›rÊBHQø ˆÙŽs®ˆŠï—kcÍ)PîÖ¾šîpfêº#˜z¦nÌ,‹ü¹’…)h¥?üxXÀ½èFò®-UøNž¬?eY>ïÀ|ÇuÇw½‡ñ:HbÒÛ®à¤:LK¦“ñ¶'ÿÊ»>”ùNÝÁ$K¡b= gyt’À˲atbÒ2Ñ»~dÒ¬¸ ‰,È“ËFWPÎÔ’Èy›ù[v[†Èü�±`!Ò0€KðW Ü/Ø ùèà¡e4 ç5ÕÙÚCXŠi¹/”À ¤¯ÁÀA9 AÊ÷.3Kž½ä†i’„ÓÀ 8&—xÇÃNà�H!_üV‚Â$<Ž€#¾^"P!Y€0à®9ò7ùN€P€xÒ,8‹J«Zƒ¿ù„©¬¾Aícµ E°me ƒ£á)ÐÛ¾üç/ÎþAÕ¿V_WíêÊ«¬qðv¨¬f¶¶’Xg@=ktåò9ÔèùJºÞ"Ã<zdÿè'üv9­\ þðdpƒõ+§¾ÒZg­·•þÐR’®U«ßÚè§ë·*½PÃà¶•-Yo.³E¤ËË[dëÕƒµJkIågU=¬ë!t¯·�.ð:Ikõ^ƒÖV±:ü›Ê÷è²Êð烌Y8ùªºj-ô;ìœÜÞ²z¥¶Ñ°Éâ/?ª ÕÕ—ô‚kM€,Öíe´+ À ûh «ƒî2y²¼ŒJ-«UmTíFEé+œß:VK­Uðç?}¶Nž=xpr{©Î°|ªpÉ­Íä8 =ÄB†þ÷ƒ$3ëxpÛ“ €€¿'}p?’.˜ (¡lÁÃ�68ˆ<ê±´‡Œr¥@Q(Çd=¥¦5Œ`¼¹òÖ;‚ßʽ&óÔØ’çÝÈŒMvc¾HÂyëwæ‘ Ëe€äk÷°´ ïðÃ'·@;%['hc9_sO€ÁÔn0¯ž©òa0AŠ} 4˜N€ðKK05¯ÇÿzV~×!ãßç8¹÷'f°‡wY©ï�� �IDATï¸S4ç9!¼lQça ÍÏruBLª¬=þ¥Å<ÊW8üM%öP�ÉÊàS„tžÙ¤1RB²…ί€|-ÝQH\)ï!Ü+»ssö¸ wóË‹;|r?ɉ1X ì×G£Y»°rÄöN€�ŠP$æÔÜj%„&,~u¦kmEöx®™hÁ݃o`s/ ¢B ¥9!™—ÔJ@ûg \Qø‚›%rlRqØã*‡'wdÐxpõT2@ºuNpDÀw<®!¿ÖÌp"×ÎYÆ¿?òãKöæ2¡ÿï·XY}X]JªupBù&²ÛëOk«ø¬2TgùÝ�Ù®nìÛõ\ ºÀ®®Söaóõ¬úý«Gõvý­­mÖðä|ù>È®+ƒG ¸ØZ¬uH¯‹~Z«µ‡ hÜ¢·ˆ«Û޵ÐûÑZÖÖº×K\d‹=릕-Áz`}P£KKt‡¤ÚÄ Ö*×Ö³…*½¡ëý%«û¡>[n®>h¾Yh¯ºèõÎÑ\QGƒ‹ÖÙB£Þ',œTû{Ùç7CºòøÉðŠT­êúáòMV¿êGƒÛÞê> XxÔ ‹¯ÿxÛÏúÄZÊèmúØ"½*²l­jc¥S³ôâ%Î-Ö½â'«øâí«žVhÈ­‡pÖ<ØBê0ê–OÆ›x!äšL†—  ÇTí,’ |gè�pŒÑoñxîïæbÆ|VðÆÍ¬�°[2JyÄygæl„+Œ]W L´„ð™Ça¿0\šf‰ Q,cý)'% A0¶îðcÒÅO”ùÀ4@ã}Ž;Qúùœf?¸s³TÖúù³’¬à}¢11]]ýÉp ‡è¿ôlï÷=á;þ¡7þµù“ž)è"œ‡ ybFƒFÇï?o44Œl'ÕæfâE‚‡ 'êrù—1­“}¬j´# #Ó&sdð…ô¤…eXèÁG²?‹® °üž6Ñfܬkc!Ã\Í}š¥X¸H€ƒüŽ7o»PĆwÁÊŠmH�øE Ž2 jÛÞ¶!¦PfédZòÂHü‘A¼ˆ=~˜©âœüczf©“� Òd¿ìwï"ÒÇ æIxÒYÀ]p¾/Ì0TÀ÷µdš‡b¸{ ÔË‘pß“n á-‰€‡CÉ(öü–ØøKÀÖ`h SÏI>áÐm±>ág«x “µ¿Kj§ ËN³Izøz•]¾9[>§Ù ÖÉ7HΪ*û(YfÙÍJsá‚c?·3ûìÞ�Ãz«µÖÖŸmõ?PÍáµî.`pÓËÎð]X¨u+jý妮×NoP¹†¬ßïU€á‚Ýèë—(én¯5ž­>cd)[þe¶ˆ~¯ÿój ‹«=k©·¼´¶Zk[+݇UZ³,J·Ukñâzõì|élX½9ín¤µËе:h¬¢Û]´QX«ë— ·W´‹›ï¿ï¿^Ðêê{Xõ~¯úÝó0<¡Ö5[øèàÔ*Xê÷»üŇkÍŸüÃ⵪nè›ÕÉjÙÕÎ5RM‘";NÈ×Ü?þÔ¢Ìîãð·5Î�÷×Ûé.X  ÉÎ.ÒD#ް¿ìÉ0€À>Í oMÀÕð‚± @âRéƒ'jS ÷GlÔÈÜ þ^`üéŒE#‡« M sÅ8Ëlµ¤Ì…)dÌ;TŽ,/§ÁÅ zO!C|²­vŠê/ Å1σgd”í þŽÿîÅÌ69»º/‡žŠ;ù5˜\x˜3ubùÜC‚öCφ‰LcÈ©:WÎ6W´ìO¢"eM²×NK!`d]´ÒÞØç=ŒL# _H_¬I†E¸Räü%7@(ädŠ7ŸðW™¢1˜�Z`àæÀ0‚̲’¡çì`‚“0ZžæÈA”ËÇBH#ý )óØ8ç;+g?ÚÎÙºÇÅgëÂÍ«\VSà+Êt—&h%€Ól%®vÚn{ÛiŒÐãð84\ (!Ç—§9‚Ä\§˜�®æ½g^íè�ÍS$†+R ipuÜßcaÀcÁ•a Ã@¦@Hsk2 fã$²ý]hà(Ýô<4 E‡3¹#8m"¥ÒoA2+î4JÑ{n³=Ùmqºƒ´•hêÀÂÑ×ÉÜTgOU÷øý£tðð Vo6ÖI}Pû¸§VÁ PÿÃ+‚V¿ äê)Ö²ÖÚ2Yÿ^/¯YöK—úæò«µî§Wè«ÍÁ‡ p›·xý,-žÿƒÞY^ÔÔÅ:.fŠ,d«œ³ ݳÐßè,ÞÒúb«W;Ö°4À‡ ¯n«YeH‡ßÓúrýê£5¬4ØÆùJmx¶zuÓ«|eu-üüüûÁÍB¶V=¼Bo°ÚT.Óôz¡yš­0ëæÖk½œÕ>ªô,àŠ‹jã»…×·‹t}ù‹Þººý_è.9éÓÅÕfuui¥»\¿dUºjuW1ø·é­PXFVÿíÑW5…¦ú‚Ê¿þm¦ëÌ~j“_CµŠÎ©“Û¡Có¤"ÜÚåvv ;¦\… ÁBÁ÷5B*Y丞´3'>FÜ2ö½I¬¥IÚÙ�‹zÆš ªaÅ(œ—ÛDó‹¼ œâ älÓp¦7vˆi9ïašÒ3·Íu§Êîn~K_SL´¤˜š<ær÷ïnùýr†c <Ï«œ˜Æ·g+m8µÚÅ™Šé7Þ÷høhß&”&ó,Kïs@M@Iâÿp¤™\ßœë¼rkÏLÆýÈß1¤+8„…œ*(où1khLO‘û:�I,œ‘ùbŒÜ™Ò$˜4‚\Dfæ!:ž–üòoZ#,üËŒTͼ~é·¸¹l¯ì%ÛzŒUQ¸cPA‚Úpt&(“&/òõ£Ri^$’Ž?Jr�ìSd^âF*7ÜoÉpvÄS’ £åÄ{µ<<6qÏ€¡›÷&8“Ü_1J¯“!`‹\O _È<½.B¦A„ x8 {H3éþ²“ ÕŽpäžµ�Ê7:É›?sú§Éƒ¾z{Üînö²ãmÚ’=°ÇêY£Š+O¾¯œªÚU¥Û'ÙjFªÕôöC{ð6ýnÁ®_4>¼èÒÿ`½½À÷kk˃ק§,à,K¯êøIÝ®7P[¤ç—ƒ·ÃîÚEz±¸ee'_Z½ÒnÕ5ÚÃ¥Zÿ¦»T£ •¬:Ôo¯AÚ[ÛZý¾«®²—Ôõß’ëFÆ*OVÙÍ÷àöûÅ[uÓß ÕîÛë³î-É´>XÍjר.¬ýqálñëÚ…ªÞ6;C´°b­Þ/ܪêÕ³ë•첺¶28«^­©ÚÕƒÚáøÚ‚<_íÿÍ÷Ùàƒz÷êÕÇê"]¤«7—¯//¾ªÝÒzêkÍnI oÿù¬ÿÓü󷵯 ûà$û‡MЕæÚÅ/Ï€£¡do9ÑhhüŠb¿)Ó>ñc¶‚®ÆËjNòw˜&ÐŽ[Î=;4V€Íº-örzÏÁ®tÁã=¸»ˆ‘¸…Z(y¾æV.Ü´Y¹íëQ˜ô‹¬—¹ê×}`§Ð¸±â Âmk9Î!·zœÚÆÜ•¸ÌYÝÌÔ.YöŹÇgÒruN%,Å9DcáÈ]6S©6á»Åžÿ_ï¡}»ûžÂrTé wè>”_T¨PLkèJ/(CL.£&?Ž@à˜réeC§X=qáj$pÓ€ù¿þØ©´À‘ š³é•À¾�„£J¨˜[PïÝÈ\ó¨x;¤ E˜V=@ „á&Ð) ®‰t@˜@7Cã¡ÒXkŒ^ÄTÞ0Æ0CAú ~‡ #] ¶¯“Xtà ›k�qà˜gØœˆˆ…„†8(’XÂ]øR/Ùj¨ö&WD¦{ŸÆ.‡[¤@çæKÀ1|HWÀŽŒNm¯4Dîú/Îvö‚ÛH <rH �ìDÒØ…I#»ÛßEO(ɲ¾µ‰0°pºz`YuÃæ§Yó¹ìYüñ#Õûrt±JÎ.ÎN¡×i¿:lX™ª^fõë}ƒ…[¬iëz¥‹§oz½zWƒ×gWÙàÊÊnR ½ÚÅÛ+«wñ05TþÖÞï·+M|L²È"EI>'’§Y¤GúzÖÂnƒ`¶ 4`l.V€n(€—º=`ý …úŠ8·º, €¾ à…� Ì4³Î7ãl÷'M'=ÅÄ–%Ÿc‰¤Yd‘ô^TQ¢~ØIf?]RLJüQ|Ïû>ïóc`¾<ÝhãM©¾6ŽQÂÀØ,••q¼~~®“L2©•£Y¬„\>º?ªÇç(žëï‡(ÖÌJùÊÉ 6‹³Úè Þ 4âN¯Ø“µý39uW‘ó·dúvRÅgecù!`’Ê´S=ë&õâ(T†‡µÓ“Üè0¹?\EYMX2ý kiütëi¹%==Ÿ(•ë'ùÉò½üF‰o£µÙÃY>ÉçN«üâáao×>2ŽÇµ¿~Z'±¤Óß|;ž`‚$¢ÖÇ€¾æLÙ é¯8µ‹cÒÚ A…T2%%Ï›*=á¤@]²G`4j6¬}M!¥�ófGø€lÛ—‡Laƒv:er�Ö|.¿£Ñö² ãfrÃÂ;ðD |¼k<‘¹ÿÍB›ï�‹â·«sGÑ»9p8wØç,˜�yWÞ—xð¾`ì,ªí¼Eê?¿Ú@´nÑñß¹¯]dð¿«ew ¦äÜ)ˆ{·‰àìû·Í7CšÚ×–ÕÎbp{Þ8º›×EA–‹¸’ 8 ¤#ߎ7ÖÜÔ²B\FÚ63ÍA*ôÏxÐQšHãÍÕÑŠ*˜Êüt‚KïžåŒï—ó×wO0�Gy¢ xbs1ƒHÁoÙ�¬4;Á–âé¢ûr RÍ3å> -ÐÆ¾‹}º}ènù$¢�¶Óhªm´E䵡) Óm¹(ø.ö=HðajžÌð=aûàN›³Ãf˜®4d¾ÇYcN™mÁq…ŸfÒ¥o½Ê¬œRo®ˆÎ¦~éa¿¸ˆ,OHˆæ‡gp³%žìÀ 8Ûp€6ЀÚൠü¶PFžªÃ8/q »$±ƒ‡GýŠ•p5{±_~\œ’Ù”Œ^¥„ÚCy¯LïWtÎÜZù ^Z1Qü¼V ³s5}…{ •%U„Õ-©|Í*V‹/‡ÝÑHëÉÒ�ÊdǕѳIÒ›G5`©¨’|G“Êb2Õ‡ý¡YÖV™lMFÏ/Î,ã1è´L‹I}<Š«ë5]3Æqÿ¬7½æ ñéwëãA´T;þ_?Ôæì0g¨B\¸—ǬD—Ìäôf‰È¼1ÎåÊýܯ—ËÝùl´‚YòYeÒë½9YïÓÒˆ3]˜VL21Æý¾îsjrK$ñ½üT÷] ^¬š=³J†ãÞðŒ­}oâ\“•ç4yþ1Ôètƒ9 8öTH €ý…Î0d@!ò [ü°a ¸TÂGÊ1þÇ.ßO·Ê=ÞüšKŠ'Б8 MØhã‰ËN WŸÍ6|PWV{—Œpì_ç¡øî5lù¦ï_Ã*ÑôæìÄëõÁo/ddáßwY¯­'¹=ºçŠ6º@‹ºm6þß½;Ö�r‘þã^;cD»|ݺ֣»·ˆ°? ¿ÿ%ž’w‡Fï™®øaâý§ÓÍT£ÖÕY!m õÞÂU€x†BÒë ”y:ñ<nÓnºÂ™+\²í|¦{ä˜_Žó7†/RT/_¬ù3§T#zEBu¹t/u@×yô*/)Ñȃœ[>8”§³sü 7¥N‹K9(R¿n—û.×s[êãªÀ 6Z|SñÈÛŽˆpðF éf^f¾‹'`p! dºân…N ‹Í”`îÂ63R'»©mŸ€1¥’N`oî‚i›)l6€]îPÁ–4ÙÚ#{Ú°<¤\F?݃¹‚ÔÀw¨€ ¶v™î#ôð÷Úœµö�Ýp�ÈàEšŽ&Ž•z¨¶R‡÷Yíˆi €EÆ·(kûþš[ §g¡™[G¾c´hé)ò÷c]$ç=mêÕüÚ´ˆ¡Nt$ËÑ4gvk|éá§åOŠUól2&³bŒåü Ë_ÈñÔ2³gñüHN'¤d|n¬ªÑäYÒÅ`+ˆ‡ •é8ÆÖ:ÉS’#ƒÂ2EÏL¢ Óñëa’ô:FnŒ‰YYýV¶†%j�ñŒ™£(qr6*\Ä#o”ŠÅµÚÚ0Þ,VÕ,wbTþ9Ή6ÁPS]ƒ>/ÅÈat±Ù=ïœÏ@›úbGg•{/JK+ Ö§±¼¨®O Zšg ÅWÐëjeò$àÊÜœBãkfŽÙZ,÷M ”ˆ4ê` l4Â'1—.ÜôBP¶ áx’ò Pnµa)ì¸ÜÙh#j ߬`1‡‰f§µ8ðB´ðÅåªÏÍ–ÒiWá§V(óŽí²îG×árg1‰d‘ß^�œœš|On4þ^F”ºÃ{q)í]çzÞÌòâwíVùÕ#§7+/[ì}o”Ê[ Ë¥0û¶à÷¶½öm2çÍã‡ÞݪÃü'Ÿ þ[m;7Ö÷sÁˆãÝ¡» h[#¦/±‚ïÂRi¥p.5—¿Y²}É&W$W_Ò=}ˆ´ÉõéÕ¸—êËö½@p]yž7އÀãàPžfXúm€.äl´ç dïFß'ݶÍÍP-§'õ—n8'Èb–Óǹü 2™O>°´{r3¿¿Ë'ñY‹h¶Å4è0УŹ—fpŠCb3N¬•>A  ÙÆ¡+S—‚Àƒr·ƒÖ¿Ýž¿¼”7õ!ÛàA,I@6wÐôÂý—é:ÄãNÚÄQ�[飊\Á€¬JV›Pˆ}pæB¤mÃ…Õ±Ñv9d›ïk8àxâFÒƒãQÞTÌj@¶Q(Ðû“(?Â)ìÁÃða?,Ú*hMÒÿ]Ô*ønÿœŠÒ a|ßä —º÷Î1]ÆÛ¢®7Í8ªäõr5Z©|2+Š÷†Fq µíiÎJ¦ÈËÎÔx1CwÜÃi±<Ð…ã³#Zb*¯Ë•ÃÕ^8-±ÿt¨º h<ÝR«æ«œL&¨Lk£˜£¸ºÑŸÆ¥’bãa~VK.¬éY¡7˜Ö/^©Ò(®¼¶kÆ15âx‰,uíñÈJªë¹Ü·åq£‹Î›ò¸<=G-¿ú¤VúظØ4Ëã³Ã×zË\ÁRþ—lÐúêúj®q¿ÚU~DÌÞ¡9B :É5*÷ÍÉ�§CœLG}L"s3,ÝKf³>)cP•§£ú©:0ÇÜ�ƈ'SÙkȸHN²Fœ~ #Ø<æT •ت8¦8tí& \€2h–Zê2„:5uog¦›-ny@Œ†D ¿F´y“‚e–òÖ<AꆜvlÒ»®qC*­Âôñ§Í¯¥¹µîôø|qƒýyµâžDî‘qg¯F‡æ­æ˜Ý¥¾IqleåÈY ;ftMïz#ïÞ-s»†ÿx¸.ŸºUN½÷ÆY¶~¬ÞàÚ.ú¿öåÿ³ÕwYlÚÂQ©‚Fø�ShÒ¹ñŽ{ÝÅÐ[ŒÒœŸÞ®h¦’ˆ…x4•¤Dà¹^ ÛhÁo‡P¶ÓÐ û.v²|Älåë�„ÌŒ!/×Dó¿žýž @º"MÚ± v(üc�`§¹MÊEÓC@CBí¨yý¡‚cÐð•¸Ì½Ú"Ìã²gWdî{€åAg$<.‚J(nN‹£�¡$ÔÙ=¼Æ-QŒüx^ï°•°Ùâ1 =AÀ5…l ¶² ÝæT!Î6És•Ð¥+ÒìOÙØåØÓ‚*;˜ ±úž z€ÖöÖ^¸¤¥jpÕ¡ ´Îõ×hhtPܰÇ1È’—+ZëÚ)Ê5%ƒ™%#JªŸå^?KJ¬´„aÜ0Ë)H­RÃàÁYñUþíqnFóÕÇ…ÑÓÓ„ªALËÏâ{LDzfXæN«ÚœQ5 ÿHŒƒb©Ö¿x^1ò4iYñi¿~ÎŽ1 *¡õê3¬°z™ô§á½N†Ã|¯¶‚¸‡i¾vš+Óä$Ÿlß_}z1%g/ŸÕ–7UN=øž”þä¡g%'µjïy¡üÙI…ô.⌑aÍ@/_Õoqeö°0™,×Or9³\\ž¾)M§£ãxXžýaÇX¥I¬Þ˜ô~ñpjüfV9-½"ƒ·fþüȨÔRO%5Rë‹xÒ3O^€>|\@8Œ16m‚°óÂþ„ ƒnC—ëÇÏŸh$5V¶ðísÈðµµX+"àº%#ÊYKÈ=Î:�¨�á0œ8òw �Ä€ìHÇÅ—àcàpÖn¨=)³!Á ¿•}r­”Ë„ŒÏ*ßÑí^ú¤šîÂz™íü sb`ÁùØû¨ÑË6_ÞZjÞ€2eïºAìÂ’üÆñîPäwå%û?¦¦ßúÓ7›uw‘sµ¿½TÿQ>¬ïjóXMç½OáãÛ÷»A¹óÜ ;‚r(ÞLí)à{\q¸HK|æ9AáP6�aí‰}Šý´qNEX"%/9@éé„m_¥64 �:—G¦R²6˜'°â-@mj¾yðÛb_¥–DDR!)8R�x à´¥ô즇€žø{\–©«q2¸Ôc§cÞ@ù…åqPátDÐæ™Øhz.kRX°Î(v¡öZ- <ö=¾I¹ãr¸BûœjÞkÈBh�”G.š ÌãØåð¸T8t±ÓžûØ´Å>Àö.û2žZÌ[š;, ®�ƒ+{®žìÙ¬YÀ¸#c€!ˆøÃqxø«(®ÉxKGb­†$kÕíѺ,˜6]‘&cÚä/Gz–ß,|§f0ÒEï]21."oÐ{÷V4SÓÚR²ôɬ‚düG•Ðî@}R)t“Íó®4M6½ SsˆIñð£jRXýãé°–;>¬Zù¡K ¡Ì„üìsã7“M’¨Î[y ?¬ÝŸÓñ·9j¬XëeÚ¨~ôñiáù+ Vª-U@ÊÄXé<úõçüÝÇt•–>[_#ÉÙo’Ó­x%™•Áp½d*¬–Èa:!(Õ åž¬t‡ƒÚ…&ߟt“s9Ž&Ï1zvºD¦ÝÃr¡^)Ãÿ3OcD`$(¼(瑌ÆÉEm¥‚¤P¤U³ôááÇ[X]yZ*áyb+ª¾-þa‚[šjày¯A9©Ck<_B7’è`«'A™¥¶‰ÝiÙå„ôXz08.˜bV'Ü"z¿f9ÿDqAKÒ!p´ñÛ¶Pm0Ñž˜Í”Pø l^ëwÜ«ôÀæ"[}A ‡… ‚¦{%o¥NÍ[ožöøþ•~-Û4,Š!îlÃ4¯Ô[À!°¯2k‚ÖAæj© nx78×·#þâóºáñƒK_,`$wÂõW‚ÙëÏ\ëÇo*ïÜŸ®o¸“KÛüAí›{Ät-Òçó¨o6©x²µ8dÙ~ Â's{/ô;h‚7ÛÙÍšíãÜ=…G‘æ‘ÂÎQ›Ã àe߀LÓÍ\޲àh�ððë�°¯RµN6`»ØÉ ØôɆ©œ'} £ìT‹X:èxbÞ•478(w€À › ŽË}�»Bz¼ 1§T¥¨|pÇ…OÐ0[ù¶p§Åw šŠûYg-|Êáž v\á´ б¡ìCï7¤:mî삹8ÌŽm†$¶áñ/”ØÙåèÀêl¦{{©„…Ч)9 QlûðPÅw\`7õÜ-  À޾ ÝkAn�4zÒæBFâ -4áõ6jAƒ©O¾±iŸåC*M*+ü²²i*™„éX”Ç›gqÁ*j°èËz¾� 89—ob5ªÖò#úÝ2©õŸHn}ZVËX*®Ñj‘=¨›¹øí¸cŒûÄgã“f(Ï,Z†µVx5Æ„V™/ ;k<ŸMÙÏrQ¿`M–úx“×/ !`BÅ«*ë.ÓiõyÿPãã·÷ŒA±^uVY}em}U×r›ƒÙ?T—{¨þwÐÚêú/‘ûù0ÿ—µêyt»KÉ˧Åi­2é•jãDQÐùû“QÑX¿WÆèt5W@!y[LîçÊxó›\…Žs+÷¦ó¥9{Õ3§X©nõ‡›k'%ìl C©iòÕ´¯s3•CÏÓ™AKXÖµñùÓ×F2Qø19æëúk#¤‘ÂÏTv¶&LVhyëÇÖ”á_äaôsÙ d¡)“ ;@EÐâpm¸áVšæÖ•ÇšFã(xõ¸¹ÚèºÛΧŠû ²Ã¤:p(|ÇEà¦A›âr™|5wBøí,ë2¿]B\ú\i¤\ø©¹¯'n€3r¡àî¥$;ýœf‰„‹µò2jåҺ߹®Æ½"¶\7þ[€›8nÙwÞÞl7ßqܦó¼ÃnŽß.žþ]Ô¡ŸÀæýè³áÇ›ÞI¸ö Ü»wúïbxwhܯD1éÔÀÙnêî vvdù|ÂW)æŽ�€<Hš¡p`Cììòg´�� �IDATSh!èßÙ�ÚSð÷Dzä¤Â·Àû P€ó;컈æòý¦‚tù"ÃÌOE•— +ÅV‚F— ) §ÿ‘€šØd–$,Š4G3SlzÙ7—Ž)z¹ ÆCK€+p1O hB°VÆøjRøsWÀ #*�¡•ô[He®N ð„ãJòµÀ.¢tûí=õÁµûxœ´„¾Ó––A–Ôà+ÈvÀˆßd¶mP;"M®h¶–o¦Î€G€bqµ=)›Lþ¥B] (~¬lMíž~wp\±Ž:PE>­áE¢ÖþÓ%¯£@TBìŠ!Çè½Ú¬c"¦«á›+W±Iþùðì1¦‘?Vïp\ŽkÓîh¿8W½ãï_Çok½±<ïõ¦‰9îm?,b€d@eÜýù K0%:±I+1Y:c•ŸÑüì×õàeÇ]Yú…sËø3-uãþ+œÙô^¢óoa{ÅñÅË‹‰ñ³©ýñ$Ö9óÉñ Ÿ’B%߸˜ rŵŠÑ×—Çåc$Q1 ±9E¹K ÷žåe¿_+vs±™_©”Öîå U2*ÎjËñ© “zC³õA Ó‹qm¥Uä&õÊ)t ¥ #”ºzxä:ÉE9Ü×ÈÏz##Ñù‹¿$@?]í~H–/"�©%ŸöjR¨RÁ,b»[×OV°ùˆ[`qbi0€3—Se3„ pš¼ÙðÐü½ü-lxš;�UŠ)«iŠËVØÜàÚC°¦³-¬ŽðwwÛOÛ yvBŠ/]µóT8mLñýv¶NHE?ì–W¶Ÿn[i^Hvýß´ºñà{—•y°Õ\w‰Íf‚-÷&Fâ\gððYón*æ.#%î¸ï‚Xø Vë;·Çw±{÷–qß»&[žÿ?ö ?œÈö·¼ÌôS·‹ë Š %šíÌ!#}ÏØ†h‚£™ÅÃùmî´Ä/¸ (‚]Ö„ìAØH£ÖÒMFÊò<@æèž”€ãò}ˆh;~ –«xqÖ†œç²¡-ÐBGEá·ÛcrW2€Ø9Bðˆãk€†RÙ�*üG[döJO™©Ì%~¸é.ü6œöÁõ¾@ ŠXt{gþR NJvY”… Ф æºâ p쫬½bnØlÔ#ÿkÎ�Jq¨àl`ÿQè¤I¥`̵ A°4&Èއ')áÊà E ;p\ž €v™ôl¸b«Í{ !\›€špÙlƒÓ•°ø<®sj@}%$µÝnv¿²‹Ÿ‹¥sþ…‹éÓÒf•ÃÂó­Ñ§ÇÝ’d'¼$N?çky‘/óü,¬è›ÁáÒ˜U~…³J% €%9bŒ×äOÓËe¥l JÛfIà%›VmU †=ÄS:RùFYêÞ[íåAÿGÇ(ÚÉR8žÚÀ+¡À㇢ãœ1ú hüªîß§ËÓØÀzB±”+ôß-¿­'ecTD9¯'¨—È}ÃßæOFo¦ßŸwåñòjBjèj\¬¡š˜•"-aò6WJô©Q£Ðý8oÔœWin4.Mã\±6}{<=/šÅqœ?Ìu¶äÃcsŒ·ÞŒ >6ÑÃýª2sˆgÔ0—åyÁ4ú@¹dtßäTùBVjÖyYçûÀþÛÄAqU÷zô—±Š«dp¬ 6� †Ä~~,¬ÛÙƒ_³ñuˆ ›)A¢4Ï\‰�™rÈj MLàHJ—³=H ¦„t3“˜Km—Cá“ÐÙµ÷=ì\— ¤M:óÒq!M4As¾ÿK7X×$oW…rA¹¶˜®ø. ¢}E‰Äõ‰!ýÞBöØíÚü;"ÄbA¿­AËÜ[·¶§îí=Äââä}ë…ø2þ·üqEõòë'ï€gÄáÞ¡Z¸›)å½[çÝÖB ÷q2«Ð÷/!?W�¢y]ªšyêÛ•r¥RëD¸»€gï§λ€Ç±  < ðœ#áS #|h xvY 3 ¿Ö>ˆ€¦‹&Bæ 'cRñìpnñ ¥6¹x8¯wl'•†!�š=È4¤“ ¸s®t‹; xjí´çJ‹¹ŽFzéùað'mµ¯x³…M%l›©Õ…ÈÝŒüç{ÌÏ ÌE„ì`®@›ûØWT€ @ÈßË@éà˜§Ÿ¥Ã˜Gb`:cš;.,×–mµÁRò8lƒòCðÄE ÈÎåžx}϶ ,踶lÃTØ!�„µ Wò¸| ÕAü3DŸ‰g'¹Üs”I8CH ’WŒmŽ>?6‰ˆ%$œ>ât�³ÄŒ3ßÚIþ1³¾EgçöztåsÓ`£‘urÿÛbEÈq‰É¼†ñ=œVë†q€™ÄT<ìæ ´va3fâ89Ó÷^)ºBÍc±T õ$,¿ óz³Aû8eÖ´·aÃÔ%ÐRÿpÖ5ÝoãÓåëÝY97îT_ë^o_OKùn±H“þÅôt„îx˜#]P]Óc“FFmùžž 0)©ó2ú8—UšLŠcslš×o‘›öî½äïצ½iOÓ¡ Šo†lôáØœÒ˜ÔOëvü©Ù¨òôñ¨K#9Ì-òXÉ÷_•Ëúþɨ¼ÜÏ‘³į·—Gõ¥ˆÙ æàiµŸßÿäÕ¸·,Ç]PÜ̳ñ*–:•ð³¿çØ·Sn}}À -JÂ58öø>„—3O0´¸„l–.w<È]€„Òå,ÓqC¸"u%ò ÐAÐæÆE0­ËAj«çrü‰{Åô÷ÝËñâ–¹æÜ`!Ëk1öʽ²Ö¸Ö8«›�õ¸ÛP{ÍUÚ÷®uú¸­Æ½DŸZ·Ü;ö¥óÆ.Á»F…ò¯5ï\î:?Úþîw6¸ï±ïÈÖ¤‹K’÷ýÕöÍ„#ÿ®?´0æðôºi^œ9XZ:—ÃåAvN¤À%¿.°+B4—.¢¶uõö´:ÂÙÍ–H´€;®¸ômµÒÎ¥-Ò«J¶¶Ì!Ë–.‡+œGFè)„’Ϊ?Ï)ü6d‡k@n�°÷wÀÅ/¯Î,›a±×˜7Ž ´·*¾P!kRø?€/<îS0%6�›Ž ‹Ú¸<𲈺&`+«&„Óâ”pë‘e�•²%ü½,…ž”.|W4[`¦ÿ÷\NêTãr¸p—»ØÏ~³P@XÀ& iðÏ6Ðë„Q ¢¾ ¢¤FÈZP ÿ43Á”JƒöЄ€Ï](ÅK ü_ñþÔš˜Ò\áÕU;¾ “3L ˜ ±2©Ÿ¯±B zU¾cÂÂüH®,‡ ûý°²n§ßžž—Ð{ÛÅ ÉD"Õ‰ŽpúW–'¤;•ãe«'‘ÌŽ_4X,ÏOÁÐS½ÊÓÄDÕhT&ŸœW£AÅÆVÛƒŽüë»Óxl<`«Ø\Î=ü8W¬­„«+r–——~]¹_앤Y‰ÉD—FÏU~‚Ù/§yRžÄ÷ŠçÝÓqÿ›¿¼>>…:é£<ÎéŒÖªu«vüºT—Ëߣ”L.Æã3ű1û4™Ò‚{J…oãó^?w>Òqaøua0f½:Ôrù­ZÒÏKR¬}÷˜ÂîÐ-Eýîf9ަÂêÒœmæGß~2Ôd‚Òφz|r¡sc²õTJ+Jž /�°¸,?¨cöÇËom?8—d"j ê„õ ›”S"™idÞŽV#¤mÈFEŰå7ïÀwap:6�©Óv[:{pLáÐÐ1C§A�þE3…y3þ:ó„ôDYè� âÒ¼9½þ› u?õñÍê¯+𮏔›]ÝËÃ5Yòõ˜7X΢SÃ"atÁËïê6wØ7\ݲùn´ÇyOC¼(Ðó®$ ð—¸&¸ãw çl9î*ÑwõëwaJÞ{—?+Ý5þà§M'.=õ˜š»3¦Éò5Žc@eyÙ™õ7×˸7yÙPÖæP™°ð’™€yÛž¡U.ö!¢t—ÐΨJŽ‚ŸZ6!sJ»žfA MˆÀãpÔ–N ûm¾Ó‚ÐoÊ`mz<h@îÂÙ:™ZÛwy»]3E mä)éFópvëŸÄÎ7)ÀÅw\±n¶q¨)ÒÙ4ã@øiçå ™žTº,šzeƒ(±Óà>àtDÒ^a£Ö$íh¸£d@¹$ésp9Ú÷—ðDÜßÀ¦ÂaKÀã›.ÐFL±£°O� Ú…ÕÆŽÂ>�*´\.=°†€ rÄM‡>ÿUxßÀ›„,W –K47RƒL¼E¥Z<;9V@-Á2–†²?f%ØE<¢Èrãiáñð(Ô¶~8>Åy³6èŽÏOã£èá9'Џ LW °Ÿ˜•íxUüìÿ#±ˆÆ–¦0ªõéÛ爭хŽûÀFÊ.¡{BSÔ ë~I÷«VF_¿9#eS_¬`:r4¿W4£Üƒ6“ÙZ²ò—äMãÃ\òãUº|ñòäUdª;g¤öóèAe3OÖŒÑôíË#óÃ_g£¾2Y‚˜ c]./—rÝÁpyLþ”ïa4Þ¼¿Çãõj®0DüB*Ž·;Ÿ'Ö7«ºüÌ ýù|<Xú¸tÞ»o&oLczò,¿nMûºH$ŒÍê¬xo´ôï³ÿ­auÙó6éƒVþˆü³BKž;ɧÌ(á« ÐDªkhÙ¡œ®ˆø®À³œŽ(—ê€Ñˆ(¶Cm?Rï‚íAvR6°jØ9>Ô66„Œ-t4¨¼Ô*]&Ÿ2ÍIô®¶ÁD”â´îµ47,TêE¢ªï½Pz·-’sŸÕ™wÀ—þ Á±rɲùuˆYÙ»ŠÛ»*çG…¹•Ã"Åö}+�O\ÉúÜ»oö#0¥wlQ®mÞ;v)îuÇû¬ÆÅ5­öœ\ä»ïÛ¼_í­y   ÇåŽfø|%ü Žö)XC¤Xó²ÒŸ®²/…—É’dfpØóàƒ.âñK…6\ì{ˆ. ³Z`Ô@�Ö.˜ ‡"²I!üV Í¥‹M 6U„û@¤„ ¶x3ã‰ì¹ï¦Ž|?ÅL½¹þÊi]ú�TØì<Ž6S`í�;ß�-0ðÈMWÜP Ì› ¼­=þeúÞ7¸ãrÐT‹F3»Më˜Ü„`Ç4,dzo Tl™€ËwÜ0rÁÎÏ.�|F9�+“/‰f[4)‚p„¸:mnmˆ/žˆ¢‚IÂ/ ´F´ ÇCMáɆ�  “\þ^0„uÍ>!\oà`.N4 y¹œDÆÈ\®êQ·0šF£DMôãJñ¸Êh­l÷ äþ‰ìƒO€åÂÓûæã%Ù‡¯’ûV·Xö‹ùaãLöúÓÃl7*�Ê€^eñ2ùp¢Ëkõd=\KØh¬¡fXÅ‚\2h)”ؽ\¤J2¿$O òdEŒ*O &§k0KÑô¤Q™üýk bšÝ21synÆè£²TÈ•zåš‘/–Œ4]*©du©±ºl ôÁº ŒJõF²ýp°‰<ùÀdFy¥È~•ŒO{Ã!6 ßj¼éI‘ 'ÇrÙ(t'ƒ­$¶âéuͪq"§ÿ+õáE'_¢¤’¾3¢a/MÈ`xh^——ôý“¿MWU+±¦% c—åtÈò /±üóºyP.³7%Y/‰‡«B%/XlˆÐüõç«›rÔ ( ;¡ Gq‰ÑOCÒ8Ð(‡H €VÈX'ÐÔÙ¼7´ œ]±ó;øj» Ñ<bÌÔŒJ(î(À SÂÞÜÝ€9@à‰Ë^Ó¢”£áÎÕÅî\$»˜QïÍYÈþWòiïV$°{G™r®CCÁå(0Ïsl¾—Qê\_¢4½+ ©•",ÜÕõÞp¿¸ ,òï’17ŒäÎÁüÛÞO”î’_ßT¾Ç³éfÌÞMV’s-ï‚û­ÛÎVsZ›{ºëiø-Û÷à¸1š&4 ékßþï!éü½QÙÛ™c5~Înj‚Ä›@³‘y£~‘^sm‘Vg^šm8©\�À.| J뻂ÌÈÚnÈÚ4ƒG¿Øƒ__PδH¡R« ¿#š)Ù#°@yZd,@ ;^8—s£9‡ËæÖâÔö] i£Jµ ˆ}Å}°{•¶Ú@B¦´¿6ÐÁs xØßÒâQCHÒ]0ºî·$3­H‡¸¯4¾„˜C®¼—^t{°<0…}—û Θ‹ÿC¥Ìá{`öÁýdG0@·í�Gðÿ Ub?×€57UVGœRAµ½©À à)‰Ž ê�mÔ!>‹å¬õ5¯Šg’$úÛüêæj½ÒÓ³¡¼•‹dböò¼¢ÌDKÏKjÙÌ÷¶þRÅð?´>üS·‹èÿwLÏ­W8ÈX¾Ï?LXaˆó.NjÒ¨Pôdãœäò$·ÌL ’Då kŠ".Æå!Qe‹¬¼5°‘G÷Õa¡(ò@a`uÞ\ˆJ‰ô)BOÇJ›lEÖ ˜ƒï¾Å í_²w<{­g=T§ôíÛÉàíp˜èÞ™Îu××ÈxåïB£Z¬Lõx(+# §/Êd2çFrtñBŸtÏ&˹‘.W×êðÏoãòôxV5MÒySˆ‹S÷¬iEç> d”,M@7ø±²z“P"Ô,e<ÿ¶8¯ÉT“Cü¶†|á“Úd“�ãõÃÚE±Oy¡o_Õã+ç­‡Œ¬RiæIq…¥“dÌÎòt)‘Ÿôø³zË¿Òtµñ¬ «?FZìÓP6¸ßióMØû° ¨ÌÌ]î´ÏÖ4e+a³ŸÂ§JÖOƒI‚¶í@è´HOf„ÔöÆr™Øì·2äÄY,ÍóÎRί167¦ÌØGÞUpK–»U3qwõóDó2¨'DùTwT³G‘ƒkÎØÁ”å»cê…W�¥¿ v~Ä^!xGev¼»„hîO:Ü÷!bw³âtsîMVÀ»¶"ÎU¬¦¸y—ÖÝtXç’†ÜÁ~QÈ"Ï·MðϾSØß@à‰}Ào �ž\F7ïf&ò̾\|!�œ6›7sÐó‚=îÎ.XŠ#Q‘³N;cš²¶”-î·æI™°ß!%¿JËåh ¸@Ûö[ð›ÛN+lzÜQ¶(]ø°Ó—šµáï!heæE <%ƒMH4À# vÓ…å.z@sW8àà·�sn¾'wÒ—TsæÚª-І„­µÍš€E¡[èyéÑèÔÖ´k.štNÞÐhz" ð—3 P®ƒ2– àQƒ\)‰¯…M 4”„£%–)¤gNLvB°ŽhK…½�&{KoXªs\YÞ^ýˆ$…â½s»üJ%๾=L°”{³§Æ’~°jåÉAe¢ó¬øŸgÇú{¨ØV+Öào=½Ê—>Ñ“/£ÂY4­’éªxÓ•“>ÊæöÊ‹­RQ×™¬D˜%ØÉL÷µeT£x`ÌPìG ç:Îã¯Y“!×G|Ù*Œô€î¡Ÿ©m³Ÿ g4.Êec©j”LU5­ä;…35Í}ò]­1UÕ/],}Þyq®f¥?M^¨Ò¸‘Kz³QqpÖ9ï}óJ«¾î&ã?•_›£œêºþ¼)bm\;9“/º1^Ö‹³õWçs½ÈL¤êÓûǯ¦(˜Q ¹|²…S³ß,èõ®Þˆ5^×ÌÉԌɷãÜZ<l@2äŒñKQœª^þ¹¦LWm52Õ´3¬ZæÚì0?Å쵄q'›áç¡c6\–³Îf^’’~ÞaE¦•½e†ˆ  ÛBS.:)7~êcßâiìë° P§ìØ ‚æžJ %|Oú€ˆ=â>åM Pó"©Ÿ/PžÖ} ×’AåÜ”-›w»ñÛU՟듆Ó_uWˆ™X¬]óŵ¸ñOÍÛ%Ñ»½óàÎ]ZçRçá¾´zùš4ß í,Æc8ï¶2úi»èwŸTWÙ8þ‡!Ï8‚wÙƒ\_Äß~þ啱°ñßùšãwÒR8l„*d€×4S« ¿‚¿!ö÷àS‘B@M�:Ë,lzðš»—D±tn©Áªßž£‡­ŒÒ“ºh8Í,h) =îdGÙ&ƒïxØi{<hÁñþ €}e5ì^žp"pÑlÁÙÍ&¸™ÃŒ$à 'Ðèpg¬-RO'ìñˆÂicG÷÷�0„Ø…JóØÜ÷7øŽ'%$ƒ‚ÓŽø9@ÃÞo‹›{¡ÙH ô¹Õ ³7+¿õD �`ÓP€Ëh ΂4µ ìS�öÎGJrÝÅ(—T0ŠC€zøRƒì è]z|¨0]åÖá³ØÖ•:/ŠäXB£·cl¿÷dEœ19’áttP,35Z&åzB"ÝÓ úß±RÁ'd›˜ÛGë¡ÿRâski¸Ðå (ű*K³ç3’Ÿ’AcÄ/ð‡¤ ýßjÉùÖ½j2ª—ê0ðË|\C>ZV¡jüa6Nj¾üÉÁrNƒÓ™.™YUýá³á�gµ¿ –äÊýõüÅI­—i<¡„‹û}�¥)©þ™éŸ¼œèL5î½ÕÑ©R“¤ˆ’Î_nžøk"»¯bÔ4wrÐËÅÇT¶VNu1úv8ÀÈÀ«/Ii¾Nìn]@áYOÈo`ÐBI §êEáødÚÿOƒ®œÅñúsUBñýDŒ/þ‘ä7tl!kÃ?Щ"3™ÏÓigK¿þwRû®„$A¡‚‰Ò€ÕQïÞ8“jjÑüfa�9¶ Áo•­h<ëA*.EÓþ^–Ý„`žˆ‚ ¸`pùñ‘”ûð5ü]î48ó8ܘÇéï²pÐÔáæÒ¢.¸jŸÅb%ñ]È9¹èF\qà]k:yk¸˼Èj^OмÓÜ‚ÍÆ|SÍq=òa¡èñaDÎUíWŒ£÷´ü‹¾ºY“ýw è\±xü8 öWõªÉÿE}ƒÿÓ›~GõN›ï–WÒµ¡/r/WÍ~;Åâ!÷ÀLÈX°š=è4l(ì˜Âá즗/o±ßá`5°ÓOá@§:Þl�@“f× B‚³42hΘv�?�Ђã‰};à>šàé*Û¡Ù äx©ú!ûsW´‡úiZçš~K¤ßKÍYK4= ÝHï…AÇnºÙ`GŒØù•½ßH º-d‹Ñ ¸l†›°cOè .›°ÚB·xÓ~ƒ[D®`mÞ$À.°¿¸ÂòøPH+Uz·�„س?ÛÏö9ûjN p…³Ç±‹/Û¢·†be¯L´è“Ó#G(þÆ?áô” ”`8ÏQ†þx ƒwvDãŸØ,!ß' е5 „Õ‘Ãh%aç ¦»? ËL ‚jÍz=Jõ·U»x*ÆcP°8–‰ÅGÿDЖHrVy„ÉËHº5DZ]8;X_«ÅÃã|$#%Ä&–âcP(ß7ÞEyRø¾MŽ�úóþa¼Ä: $Ž «W至ѦYVù<úœžÓÕiqœJÈŽTwˆÕÍr~¹Zìbϰ~2è.ÕÔP#.ÓÂL-Í ‡ “¸†Éóû1{ñn×iøå¿È­_möª‡üÖRÉäÌ|E 1FþßäqŒµ¼X}jOÿê3Ð&D‘°ÁWÑIl=|øSE ’W5Tˆú¶»Ò(|ßQ&p_’׌”0:‘ÝÐsÀbå"VÍzR¤oÞü­½~†Â@ö—bÛÀ2£õ+ døE‚3þÅn>Â~/DÇŽÂ7MñÅ÷7„Óä¾§ P@AÒì#I<�Ð4$‘â—X‡ï†l@s>¡“Ñ ™“ŽÔîMõÀ5ã£y¡ðÝ;H¥òÝNnþøÁoÜý=ê³wßì¦èáö/ æ­}àΣð£8>WõíÝ›óËðo*õ#vÑÞµñäòÜþŸz0ÜÁ£z§É”;÷Dºã…X4ÔåW kíybÍ#`stÐ$vôv4ÅÑáÁ¤—’V¡]ÀÅNpÁZ:iPoÒ4EN4!Ð)¡(MUkf³­Èœ Ûp޲Q.t;y³ ßk‰Ôô‚µÀ�ü*CN/‡Êì9¶øe.ô¾‡fG-ÀãØãÍ@ö€ ø­}-›,5m æÎä†mRJDõ°I Û �óðì÷1ж¿€Ø¡°£xs/™#¬trß¾‡ b�\4[¡"¢`�k Ö¶­Nø _‰&Ä~æ£Î}-¾„è^û¦•ü%}:4E‡pYƒV"ù9Fúh 0oˆqÑÖɶyNÇ<©|lªoä¿u4#üú{Ùƒ,T°R@ÿIœŠ²”IŒ¶ÍWã³$>­Jš” c6¡T×xytð(ÙÖ{³òÇäÿæÆ_ÌÑ ÒŸn.Ož¯ò³êÓõ_�Ç•2-£V^EaÅ\JhlüM_üÃl¨§Ãåóµ s²R{´Vþø›I‰~45?]ÝZÿ�f5c«tŸtÑÐd ûÃÂá´:>}Ñ;>”¤þV•õ×Ç%9¼x­’‘œý©2Šs/IÜý$)©JòɰP++Xg«ð†ÖYÿªª”ý†«ªqÁÌrïX>W¹i\Jô©NB�� �IDAT´1"cksí!Ç«ùX'f#4/„úPô›ìËÒEÔÅæº¹Ÿª|r¨(éM¶I/^鼯:DRd 5JÆ,¡(XaEl–é籉‹r9É÷t%ªõHáê˜?˜beí@3ÔJ›ËSr>`ëUë߀¾�…x2Øå舸ÉáÂiò`ެ6ÝÔ> ƒ7%Ä…¦”î´¸•é:ÓxgÛo#hs€Ë†p¦‰@Ξ}Õ .¢ç—;ØöÂÿ§Ù¦a«i^îŸéœ™â]S>gä”KâÓÝ´w˜ãÜŽ˜¢à®Ê¶F5±(àÞåäzK±ì,ÐÙ³Û×÷ê×w„H»7ÿé§ënGµ®½:?|0xïŽ7ºÄ ®AC¿nY¾ø„ƒ[†é êÜBîœË«§ÅÓôc‡ÚN>`y\@ÐŽ+ D³ÇEs—ƒ Ñìðf&â}Òp< ‹XòŸr€;©×£ÇW\rRõ|ê9| MJ…:€@e¤Õ'ÑA½ ¹ú;bþRpŸ\=k¶'à ´$æé†Mx$ök!(ÐäØeˆ¹ÛoÛL± †¦'Èž¹¹ŽåOmZcÖØ€&;uàÑû]„L…ûíMŸpv„è÷hÖÙ5ÛÂI7 -ø, ;™3 Ú†ÿ{pH% 8ia¶•¾”G- ‘²Èøñ7k ¿Âêß³˜(�”b«Ç~ü ~©ÀhHÖ…jceÙîÖ2þ¸\Á2‰JŽÏ¢Óâ!Qì—TêX÷ÆV=æxÅãi”›¡Z²É«o2<�.6Éàé‹‹Ãét»±âÙö‰f0q2=,~¾‰¦«T’þ=<Ž+|ªÏÃZn†ø'Ëäˆgôù½‘™×ˆ§º›ÔFçO¿9ûßÏ̳I4í~«O¿îÏ0íÕty|®^{ÿÙk¼ù.>ÁóIÔÉ%ÏèïÄËÊf~¨¶ÿViÄbFÿ ÖòôãÒÀ d¹Ê ª»«ºVýÓš"«åoWFÇ£œ~µ: gä-£²I†$7ÇqãB┌L©Ïq?§_7T%Ò¯ÏãWå(žN!NÚ¹2ò} ø‚Õº·%ûýö2˜*>.@L—c›µ‰i–Bu(5ëãççƒ"îj $uBŽÏå)Pø�ãÁa®4\Ι+ã†C#.<ÀÖJUç?ªãBÝø¥ ÄÝí•©z[èßðCjƒC1ª% ]ûm  PŠ�"˜§i94sžU@üØOÍL¶9C˜î›-!Ûp4ƒG}Ϙ¿{µ1¾Nqœ—£Öß¿uIÚá7ÊZp©zk]íqKôÀndJßE ]$›72|Ãí½krh·êþ]#ÂM—§…„‰k÷R?Q$ðÿ®¯;0¥›):?ÞåâÎáè=Þ·ñ²Ùóƒ£ïÐÍßÞ™_æ©¶³€è}`gîªvè;ØöÐÜ…ïÁj@w€ 4Z¥Ò‡fÆA›Kuµ Zéïk¡y6ë¥bQ0ï�m‰»6Ú€zê¸*hK þÅeÄ42v*pöàwpi³6ÏT:m¸Ä“ þ…ˆØï ¢œ©tLNmdD@9ê=€‚bk­z¬+Dÿ%RÈ·´ˆê;Žš_Rö\asW¶Áêœc§ÿ+0ÊÔÔìÈÆ6„¢*K‚'XÍ÷‚Úé,ÏdGlº<Þ&ø!°kÐzXÃ(’‡•褄¥Œ=ñ+PÊ–ü¡Ó}~¢ÐÐŒÔqÚ“…޵´ðÓªX:Ã䨒h©Æ‹c¡ÀƱMЇŒÎé…q˜OØß ã˜(³ ©+{õ~t �œöÄšÉÛKÖÓ‘ù¸/Ã%mÿuEÐ* y«nÖÐwËqï;½V¡(!ä*Å‹rÏLÖsÿñm²N^EQ¹†Ò8²Îµ¥½þ7ÛÏ? ­"ØŸã`8F(5ÖìâÕ*º‡¢Ô(;Ó|hC†…cûÿ#íí~ÛHÒtÏÇ$3™TˆrDIbÉÅÛÕÒ©™Ò6Ú;[§{0¶°tÓ@¼ôm€ù7ü’ˆ[]H`n¼fQ€0¦º×˜ãžjª—ê.×IVÉ”T–˜dI&)ïõA}¸ººWW¶@2I‘Œ7â}Ÿç÷ô¨0 >É9Ó1I®ZÓS•;}2‡I‚ÁñG ‰—ƒt§åaÞÏöDw_ª·›FéBžÄ)�î$ÂéƒƆ…#˜Vk¼ÈI,tæö ‚ž°<HZ•§QéQÎRÓE}£cåð x™´Ÿ,®%†85 }}´ß2Wm#ÃñnœÝȤHžBC”õŸ‹yz:±Ž_™‹ÌX„šJLC{²¨FN§¼-Š p´´€‚]B®mÿåó4r+ä"°*ê,øsþçuç k €n‘¨hæAº„7ŸÎ<C;h¯!]u1öQwÜÚ{W’«øýK{ÄõDz\ï·x á‚Ï<Ìì†y µ ËÑ™™éJ7û=ë^³v†õþ±ï/r†ê7²ÿ¦zà]e+Ýt~xuTÿb^ô Z*ÿ)U7G· ¤ê·éP/4¯óJ¤ÚyA¾~q»CýBÇ6³œTχÕê¬øoó°\€U´ú™TŸQmŸBøÏf…¾W>¢³KÏÎg¦k 2;xAêðjœA4â줹-*ÐаŸJÔ…­„KŸ ŽŠâŸŸuº¨ðjÂk�5aƒÍ^šM/¶g¡®¬ ¶¯„ÖžïUÑÏÍŒf%_�ŸÂkø^ „ìHƒ‘5À`æR˜-,h’côW6Ö2t æ­¢£$Óø¼Î€ßˆ­*žµá– X$aJ”�…EE YkˆºÏ�¢ñ[€•f…AØê ñy[m®�öT„Ú„ ú7å“ûîÈ^^`‹Ìþ(‡klÁú²3ÙBüˆâßdL‘úU0.`Ìžg‚0TååQ(¾x(@+~x"ã‘‚ÁB è3$Å^d#&Ë™N)@Är› §^ª¥Äóü’LÜû=m’F>“Kš¡ad‚.T2ò- ´5 Ã¥)¢!zQQOôn޹&6> Véã’ÅÆ‰°a¼H¡<F®KÊ8˜ú£HOУvü!Œ©„H-È^QŒ÷X*1ätaG%Ñ[FÈ@¦¢ÃQ8Ž ¤¾ùáT.fÊÝȦ$ö»ÖŒF Fq< ït;ý(<Œq’À4CÉ)LC-ô잺‹¨oû;¡LÐo6°‚!±ÚÄŠ,6ÚÓ‚•4I»+}õüðdóŸ¦ÖŸã—…YĈòÑꆱXÀj–¯.šÙÅ8i)3«OJ×í?þ²—Üè@ô‹¹ü£i‚a‚á ¾Êì¨O9>‡Pm0»Äð”ïB?+‰fÝY—ų¹]vEa†ÍpëøN³vV‚†¨TѼYu�îµw*3ÖY#�WÁƒ=ó18nm>s~Û+š×ºÐçë˜;7ðê×û-gV=ó“ºW Ù¤§qKÌÏ]\üZw ýóK\7c_Õ y×µYos©‘εj¼÷󇮄Ý*7ý«ò¢ñÓÐ?ÒÀrohiÝÚû‹Þœ¢ëÌ62g|Ÿ{JüæÓ»`.ºó½:ÜÆ¹Ü­~œ[9×´U.üe5§E±Uq4õ½<8v›»pÎrKÜ«‹ó^Ù=n›oa¦â3>6¨ÀS€:تc£Æõì0[rf±V—hÉm@Ámp 5@‹­*<ï<¢½I… PQµ¨Ä6*ZìÖiq¨/äŒP{¹ËWÂF1]2 } A÷iølÑοþ¹ýè¡Ã¾lóJuæ„�i Ùôµž rÜ 9¬d‰7gªYÂ#È  ß- ùTù› [T0F¹4K¢ø¨Ã"ΧëøÄ$ÙŸKúßÅêjû» Aä ³t3Q10Þ÷Uè¨&GÊ”øF*õh%ÍïÆjÁzrÐáí°xN‹RDï¨HàkþN÷Èéµ$±ˆ•âÔ*G z÷OäÃ#Ë„‚ã„}FÒ–‰v~e“nüä”°ƒ!R«zôÝq¨§4µð65E<ˆ§I|Ç^ÌåÌ(·xÚ%ÿ€ÉÔy4¹>ˆ Ìt ñ]¤Í1–#äB¡³7ö Ý¥�ÁCúG#~w10ÇtaÊ Äþ fÙ{ùWN7F¸ÊÍ$h| ŠSƒGÜ6[0¡‡„öÙq^”ÝÚæê“Þ‚$Ê%ÐI–¼PccOŸ,:ãQ€~Çe+lkaÿ¹T6Mƒi”×>…ÚÂ!É¢eµ:4vÌ2~£Èf7O~Ï/Ùc$[¹7¶‘Ðf £{‡§£Wi6鿹û{µ8ÞEHžü"9裢 2cfAOG‘ÓC.3•ŸüɆÖ$þž7"DeCKëŸý êh‹U¨ã*1C!m `6àA4Û‚÷+õYÇÖ¶€âx@P™…$"˜á¤:oZÔÊ€ïU…¬ný’œ:×ÍçrN9ÏL½žp=–X\˜çR"®NF«· n£Ï—òëŒîÚ¥AÁ›§ºÖ®¹[‡Þ+šºî]Àí½6<¿R#ëí¼a^Kú#–Šú-éû,ïã~x7ï8§èºx ¯8¥oû«]Aã^<`^]°óö"Îîü‡�g¹µgù³à  ¢¤ûÁ”€fc–F�· VãÞŒ9ËE€ðj¼yî E h Ñ„ím³fUØUá­mÈm^Q@Ûÿ¢Ž&[€Wã¨s´ùàUÅLˆí)Ž\pÂgT�þ5>K¸Cä@qh¿©8äS ®]U¹Yb4”ô;…%•Uã }¨žz L‚2’GZòslüB|Ñ”hK—ò- ©œÊºxÞÔBf, 7bP~ €ÔªqœP¸àl[Dër—rOqB€G¤°!ȯ¼ïr :9ܸg<N­>J™OÂ7¯¿ëKõf<VƒHì[ŽËô;Ÿî<�>yEy~Ô–‹Ï_O¥¢"&ÐV@„%»Ý¢ùaIìì¼T¾aÙ$*cIÐU_ŸÊOòúíGQååƒçTùæb9™Fšæöåèôù4Ií”ÊOH>k­LT"¦)ôϲdsl¸€¼8½«ÍNwÚŠGã»Iù!_î BYæc;ÇÒÉÛ9¶f%íBRSìÇlb•{C'yˆ¨ÃR¯Å·¢þ½ì;,ÝY$™,OÔWX;Á4$9jŸd”6–FØL„ñdŸL‹Ó.ŒÁ«Ñ=¥È�ìiúÉ0*o˜8*98zNèFöÀW±£˜ t²šÜɪÇÙ:x¾¨Ð1#n­Ú0…('¾1NÇX.Ñ1 ÕËÈiߌz›™B9Ðt¸@?‹Kÿ•=É1=Ž>HdÂw÷Ç™XOÆ:3™©$ 1?IõŸÓÅp²ÀôŠ6IX>ðÌÄ}ðÖØi)_*§y6™›}GÐRø¢}nS \6`ŸÑìË ðžÎbá>À›5>#ðÏR€P›Álœ3Üö¥@sÞÉÅ0DZǜȵ~Óo|5qü’9q8Å׿Ëa½k}ŽÚjqmû{®—=C¼ú~,i³þžnùÍÿÖß»wç[5µ«YCµ¿<”þÑü†÷¬Üf¶vßE}ëqÆ»6åÆœ¥¥þ^ÿºwk®Žfãz«îÌQj¼¿9›7\¼as’ûŒâwU‹vnhä岯Qƒ¬ò­Ù ¨8;HÖЬžFê ž‚ Ž6PS¼¢·-å6p—röìéìSè´(¤âÏÈìsìcæÁ®o¸ %Á¨xá•D 6š¼çó: ˜K¸§ÁàC9’¢RbnS@ã…üƒÀ‰ ûN÷Èž€©e‚×/G ¢$Ó¯QJ•Õ‡À¢ê¬!¢,8BË€&åÞþÀ¨ø×=¾õßùß¹=Å3%Ü&CNÚp^¸T�ø°)ˆg íðM%lú|¥äÐ^í1ëW a½‘Ë£Žuú<Z¦wïÂÈœ$§:9>Š3äTáø›'£ƒ4JÊWke3tJ 9ŒÙ4Þø¸ð<O,Œ°ü53öY† ØU¦p«< >biÙ†£UðG&è1#²žúìm‚­ðû£œê=”Æ‘˜‚ò\êùhÔ²Ž NÀ*˜Sèd&Ÿ ÃDœžý®ñ�áÚñ80GÌ0@;qÚJeH8KKÓ{4yd‘;ŪáßÏÊ·;Q;9á ·:ÐJdöЋd\”°Øý-þYGtòîð-‚$ž**Ù~A´¿¶-CgÓä£QÑJ·£|܆RýNõ÷¶d¼{8õSS;Þ ƒeCà«–õaâÉi_¡˜ÿ¨86Æã{&‘3QElOèWvô! E¨ð1xnìëÄîd÷X‰ÊÞ²^*›bá" ”A÷ÏJeTŠÄÿ#õ|xØ1 M&Ã7 Ñ·:9‰&i;½P„#WÔ§;©¿ks5À2下 HPÜ-áþ:›x¤Ä&u˜ ‚Uá6^¸ëÛÂ¥PÀV n ´êCa«4‹Ì¨ ÔÅleoÎâX�R÷ŸQ4ÂVuÑžQÎÖÅNµÍPçÍÊÉÊõ¿ V·8æ†Ã—A= ]õ+s`àœÓó£H¢ë#èÚERÐeôíè½ú•Å­òãd‹ÚÜû‹M§Ú1þ–ÚðÞžÒO0[{ï;:PqsRïÕn´ËÊÙ¸R!.§15TÔùß½~›%¤äTÎ΃ç,øí¼›q«ÃkˆYýpkp.7)¬OqÔÅì´HgNÅ7fÓ ¯I… &k�µ½w5w·ÏÒ@Qg(ÑYì¨ØjCn%ÇÅ_מ�šWª|KÁ}ÊQR¤Î¡à‘PѤÒ{ ‚À±k` Ï,éoPXгu¨J±oŽ¡3X;Öã5‡½‘º€\Ï!;úø9Mø…5‘[’›Ëø¬ÇMÊPôQBÏDEñWë>’œ~çë$¬‡Ü3I³ëÓçk¢YÄF‰5›Ðt‡Q¦MAi04}ã1J�&î­>ôkRZ-~²²ñðáF!M×rtõn¾°²œ4 ™,,05ùøáŽÂÈn—p?% «‚|ƒw—ZùòéÑ¡D4\w´¦Ðè™èh16Xœã4²Ÿ5|[amÌÇZ੯/lÿXƽòIÿåðTw“0Ú¿¼gH$‘[`™V–$‡$Ÿco'­¢!'§NÇ ¤gàt\èOåDkë¤K¢=ãõŽå~@â5­ÒìMþ¼`ôòÓÄgéñFœ[‹—è`Xs²$�-Ãyâ�`E°3 ,µâDcdbý*Ro¾ &'°¦­$Ø¿“•V)èÂ9EpëÄ“õäwI'L–1Ås]@ªûo鎎cj±á ýo8Ÿ”05€>¨µ›ÿÎè!ÒÒéí¡#ƒ\̰êD9?þ¬¬>¥0±D¸UØù¾ƒU‚Ô÷#£ëÐ##dòµz²Ñû¦póciàÐÀçJ£¬NUbf*?Î#^^±x9÷iÃŒ-2¶£¾üËkÌTèlñ/Ú€æ_}ý¯…¢è(O9Ñ M4Iø…)XûLµñEÝGŸ×�ÍöŒE~,�* •º(ns]…¦ŽE9ßZçͰ¥|€3pIP•ó¯3Aj Ÿ×¨AîUå|‹ÿ‹+Î1Ph^‚ÄüîÖŵfÉ¥.öRGTŸë”Ôç*âGš+ÃsïGÃ1/3æÎ¯uE±ùÃöO×­þµÁ}ÿhÁ­ÿÔ{]¶ÌªWjµ{SG<'“/¦:×<¿=Õ˜ìùâ9;R¸uà©ðjâòHu~ß_Ÿ¡÷xóطʽ9Ãä™ ðª˜9¢e³làóªß„pKø¼гx8pðPv¦Ú|«† P©Iï)¤šÅPs¯<Eó©xÖ3v©§à*ÌüMÀ…”à–À¬²T° ØútÆxñÅìH�Ì, D¼¸ÀÛ’p% }| ©öP4¹<±Ãe?Ÿ Ç8 ÌK㔇1P™©¤YùÈÈâ_©°áxSA,IS<ÿ¡ØÌ–ñÐ&¶Ê³ ²ÆÉ*>¹ïÓûøGêÐe^¼‡ñGX[ÚÌ/FËË›ÓÕüG÷¬•»[YþàÃ{¬Ê2F×<žNWÌØ*ä]HÓlˆd\ήB=-¯hg dW™ùY“N2›cýr”²¢HÉ(Žß O9bgÂÔe@æ¨T„2lZ+_ñÁoÅÉ!¿qB»ø| Œ#6�ÁÒãÄ8~øJ›dè °h)ã.Å$8}÷zrüǃã×'ôè Ôo§TÁÎ[‘#4!×1²ÂîB«÷úeÿ¸› ž,L÷¬!&9>ù\¨5”ÈŽÙ$ô y¨u7&9ˆiÁYúxÈ@ØþÉFz 5Ö]Í" mü>Äã¥;ŽïÃÝ©–#b¤CšOã^ÔêNS­,@V@‰ýòAQ˜wm„޵X<nb´S/–K4oA©uð<·€Î‰_,JK$í±!kB…2hºà¿L¾:J¨‹Ò9ÄMúèÐÈ(+é} e©´V¾2í4Jw2kw`3C_g&t5÷ra”ÁÝ–^Œ3DéêH'õ@³ä”îjB¶}²Îmø%´"‹{œü‚¡ã ˆvJZ«P›¡)yT“3Ô«ÍÈ1bãrëô,ѽ£Q©û µ7ƒ• ´!ëhÖYAEù.P) þÛúLiÍQL͸ܗm€KÇrý|s9ÀÀyþèçõ‹üQ~ º®~é ºšöp51¿V`.éan¿{aæjï}aŸµ+Ñr?b«\xªg 4ï–M<_Óå§üü5Œî¿hØû˺ÕrØ÷ U½Ú•8ïFH“W»â ôê¾ ç¬†W¯ŠÏÎ/Ôœ5Ïï&fƒ„yñëmû2eÉ«3@ºà3(àà©ðÜ…€b¨9gID3víœöEE³Ê+ @‰g5ÔáÖ0˽ò(�Ê€šHulÁoÖ¤l€Ëª`Û\n[<[·@a£„Ï5u¾ Ï#mR{·ÝAÅà_´¡ˆ_ÊI½ÄÈ1i/çÈq'—Gv$÷RÊza(9dÁp,§‹öx¨3L-90qøöÑÿu²ˆiFï’âDXNâ.ŠýÌãÄ;*ƒ\¬ó $24™"wîÄ“QÖƒL*m½Ó“‰¥Ô»ô03 él¯·Ÿ!èƒÙÝ3bdVÙòCš7ÌS„½ëÑ©=,'%ÔÔÇ"ð½4"¦s _Qý™Š^:(!§A×a(¿m‚Žeh…|ÙÁñ O_ÚQƒÀZ²3ÇÖøPY÷eœ”¿ƒ8ü¥…Ëœ¾>5?=–߯m; Ã?X”)²q8Æú>º†94:8!´€š@ž$7v£'cœ„Ï|böGHrlX9ÕÿÃf2šo¬ñIkZÀ—/íÍ_hºTJöÛÓ˜ Œ`’äíý¢æ¦õÕnò1’„{ z!M¦…Üa§ýc¨ßE­· ¢D{YAã“»ƒ?v³¥…Åvo r\Œ,$3À÷ᑉ ðåYÂèÝhÃ\ma`£C3D½¶±~ŒdVO÷ …¥‘úìó_е¢T¤ŒÒR^ïǪ;’jÊhž*¨Oc2.¬G£.€ÔÒÂÝäàm’ÿÒÀN´˜›b\H«w’cç»ás·bpšÜ™æôhŸLÊíoü‡9¹ Ë Š<þÊihMIq/è¬sì �´Æ$œíË5´ T¶Ñl‹îa«OÍhÒÂ1êL–h¸çãC>ƒS¡¾W•î™´Ô÷êÒMòÎ&Žür÷Ý8[¾½Ùè¢v¹¤Ì䪷F¶ÍÃ\ÝŸj‰ÛlÉïúÏ+_¯éòßG øÿçfðæc'þ&_´ðj?MžT¿`tS"v#òô:]ä Š×ÕÇï«{îUÝØ¬)äÖÔª˜aΟoÎ]HžÏ9Χç}¤:??úg®…J8Â<wkÒ-qPü–rV‚KŠÂ{ ¯xUÞ¤`Ù¾ƒ°o{¦Jâ€B³Ý�žÕ±µÔÀ %áB¢  À �%XhõðEÐv‘aCó/¨ô "+yÜî¢2æMõЧ¶l/³ðj­üɰ“³ÈX’^ÄJà#Ccèt2l˜`Ó„L|ÄBÃÚ‡<R²sÀóCvªþgšvµÙ-#‰‡ºd¾+&RLÿ÷:c-w-•”§IjÝYîžæÞ†ádHéa ¤`­e‰QêäŽu·k.dÒºÜ0aZ™Ýì‚üåJyuÅpšŠ&Ëãiö¾•G’¬é¸l%wÆ-/3B ˆm©~ã´é $- +'2EF8ØsÈ“�Án³^©‚Èæq0*ç&ä8�¡§ f Õé¯F§~‡qºx¬¿BF’}(I²zÄò½ÖÊ~ë˪‡«IY�Œo`I`¼ßÚPB‡~H[?|Û9N”° ?™R†Ó°0Ê¥iÿѳ¥¨ãötA0`©EK£�ýUGý ÉC»3e¹¤54Š'©œÕÒ¤Ô‰¥U£¥‚©è©L¤‹&ÛñýbˆW£.É“Ôb8Æî÷Ã]AÁÐ a@Ç;qÈt߆ÚÄZ+{`‡ åÎÃ9Ð>ö³e½H3%'ÿ±2!õ7?%»€Jé®…iR±šL9º•�� �IDAT‰™³iˆð€`ÊôÄl§R]29ÌNoÇéå©ÂÝçz)—5;Ù¤z§ÑO¢Ÿ|ô‡Ù´°¦:;@> t ªœ®åPðÉßO“ˆ„ÿA}4ÊZª<äž Åu¨ºƒm.«Øz*„ ÿÙ,«ŽæSQ©¡Y6[u4«˜Åy¹õ¢£h0Táѳ–‹¤�ä sé^]ºà(qÔ…[‡Û¸ÈZŸÃõý¯,A•w§~ Q»ºÜ×n#áŠhÕ½Q®Ç Í¯lõùHÇ3ƒÚí.`o>n�WT·ê_o±\0ÌqÃ!ð{J³”c÷ý•ç–Ö5‰êUÚ•Ý­Þš¸nržûÍÙ;w«yýBÅdÏÕ’ÊL€tŽ—’âßÚ­10wÒ¼À©×ó&•@ h£BÑTb @ƒ{mñ0V‚jÞls·sf f. �TÎ03æ¶pŸ ¯t¶yñ( A�¡O ¯Ù6Фœµys¨¢Rn£ gF쨀Wà7+~k[ÚfQw¦ÄçT(›p݃6|ÄDÀ`2IZÇ ÇÄؾ8v£rkÍBìŒq8”/{Xî;™IöY7F¼µÂ4òÑ4Ì• Pj‘$ñà^„µ~©GÕòBx:¤oôÝiké8Bwc?6'›K©qư¦0ÕiÞ8ÍÇæý¾Ÿ$ÕÈ̼‹ß.ž¾[HþCÊÐÙ׬GÙ›tĆ„‰(º—šއ8|×KöwNG $¢ œá"ϼØDQc®sœ‚uÁÉ2Ôo›ò,Žv¬Ÿ—3pb©n´D'ᇽVw´™ªÂrk©O² Á;ØùŒs4Ì 9%Q?ÐÖÊß@*‰I–=8&t¬£)4 º’”ƒ4#m˜”ë¬-¶!uôËã„áç•Ì-Xñrvaµh Öœ3E‹§v”D*‹®YÓ逬ƒLy¸ #“ïâ4|ûñ†ÙÅáb¢´dÜ5ÚûH ó&·2êuR°ÿ|R>AùO#$÷ymìG3Ó ‹ eØNjÉ>Ü…â=X¹ q§»¬óZÓ©Ÿê«?Çâå‘̘ÈAG«ÜÈÉïãdª‘ d²–YÀòrÑ´TvJORXŽó“è~ŽÞ9LÛ}håuß8|‡Ä€‘<t0 ãÅ'd™öó2î;ØØ yŠîøÝ_Ë ­Êr_ ².+DDàîcFÿž÷6A ·.¼&—àº&õ¬¹ZÃ,6ªRçA•7g¾™ux^ öºp!H]¢zÖafUáÖ|Ô‹®PÜSt&3á�Ð.å¨Á«‚Í`eµkj"1߸ží)øuêÅìáÒ'Ð8©Ö®*9oôÎÜ›Ýø9‡³{k“j~þzuÁôê×µ|^×s>»·ú.âó.‚aÜ¿º§„¿Å†wè„ÛBó=¥«ÙÙõë´×ÛÌ„5~éu¼-é,¯üÖ£YýúÛvåùNԙɫÂÅŽ×gȹ;ÏgIåP{ö–Üš!4æÒɽú¼—Ä@0ë{VÅ/„ÍLp3Cõ FD`?ú<OÔ=O¦ójböôžA,âh I#N‘ŠÁFLÆrc‰)8$öõ„PäTæ196ÌUtN[ò˜±˜óO0ůçÿžTÓØ™LqØÇJ¼s¸\Î!»,2–yK‚‚µ–5ã)Ò§»H³ÄH䃱‘É£×:-ó°‡Ù`›ÓD&yº($q‡’Ó01Âi*4OÍÞéâ#ùnôÝÛ®:zôË·äŸ$d2Ïò Ö»èíHë%iÞÙL§‡¿ï™m;º#^…x”ã¡Ú;9èì/d¦Í¾HÔ7Áź¿vÐõ‰á ‰”B¶ zÈÉ –6k‰Ìfr2^°òïÌ×ÇGЋ0û4O[§!‹‡ø¿#²©c•©,=3`b:CÃ7�¥ˆ¶Ê%å§ÁºF$»9` JÏRÿVsŸÝ½WJîèýÿ÷ß/ûâøgáÒ8>±¬Ÿ˜¿§¸(Ôe÷I/§±Œ 0þ{ð/äøþZfÚ¾[ÅN’ìõÞ›õ{Ó¨wŠTF«oTT™ª3–”p;F\Na=)„zÉrŽ#‘£üۺ㗊HeIWY¦RX'ãf¾<~ϵÕú¤€66sƒÝ1x4ö- ¢’~°™Êâ®ÿmd}BZxkŸ4;P™íQÃB÷N£·D«éÇ£h ¢à|mID1Ãñ‰,PõxîÐÕ�'*z²eÁS¾­œ ·-¼_`CsjâKcg3.‡_! ° ‚¶`à¤&¶ ÔAE`›£ ¯æÒmÌÈfBnƒ?«b«!šU.ë`@… ¯Ê݆ðÔCKÖleoÎÚæžr½³ G~ñeÖÀ.™ ^cn…mœýþ/câÞ×MjÀ­ž§Lâ¯[*äº?†~x¿3ü§tŸ®d_εÜkï¯i`Ý:3¹žÅzYWç{DÜ­ß:…?~m܃ó¹Ú~Ðqõ»uîÞ”QÕ¯ŸÔšWŵnýÆ¡l†«ŸI›Üš�¸®Á£Â]—òIÛ@pî×óf±º˜?<y€Ww‚ºØªc�šul\žCù™·*Pxêu^`€=ûpWj`Û¼ 4ë,¨sìq™óÉ:@ 6Óy° è�6 †@ìcŠ\”z\J>§�¹eO m;Mh¾ç†ÿïÃèHB,@äàw³An(ÀDaÈÒ?8os:k¨© ýÐ06Ð¥ z%žfî #)_N»ÔØo&Vf¸y:50N£pr’³&ýŽ{‰°G'ëÝ`ˆÓþcy< >JëÌb0pF ¦ŽÉh_ýé+ŽÉ,Èß‹ÿ<üåÉ×N;ðÛÀgšëÎN¬wî—Ê…ÏŠ9 ‹f¬”xú×2¿‹åU`ñ9…?YyÞ »Æ?ØØ ©RL=2†(æ‹$ggÇŸÞµŠ4 @uߨ{Gdÿwò‘ŒWÈ5%¬¶¿ ÑSò…3££œX;Ô!B%¼†LÓå3Áö7W8ÀO©ž|û&8¹ƒÌÀƹ„¾;°ðaÔƒQZNG0uöm trž=°ñ9ü�é“/ÍÄãtoÒ“Æäp¯„Tò¨ßFW«ïò�ùÖTè8Eð–ö;J#w;A·DR†¶Öä˜h¦´X …\G;+S -³•-Êe€hÝ=W–È­µ ðℯ|ÓÁò�(ͬ|þÈêg‡½Â¾…õIôB²?&ãXï^z•ÒIØB¦u³CYÊDß«`¬ÊYË^ÉïLŽ6ÉI¥K…‚=êÙ´(rºœØ)3¢¹5aaQà©ðJ°ÔTÇßüCíìäj`Uä´p)d AC9؃W¿=tP?CVTfà*¶�¯ÊÉ,ð™ÂwëUæ®+ æÖ˘[%\ Y—FèŸgÒmUêy$Ηrœ‰Mf+ »ÚVº€xÏnÙ¬ÏK‰Ä•$5/.W¼oõ÷†WÎ/e·.î׌ß®›*nÑ|Þ¢ ½Bç¾äÀDÅ”øQ‘’øqñ“[{¯É½6]¨]:n2ò¼+j¥³7u~úÍÐáÝp`ÌÎ}Í<*æ¦Óç$¬ÚYÊ4Φ —0¬Y*'�V…׸@nÌh˜Å×4@¬!$lÐgйµ²gAH·Ä=z~QpkÜ­£Y?Ã"¹�£`5îQìÖÚÂSðjh‘3àøÔ—@ü¬ªÕ„Wçh �G] Á<@¶}Iy’ÑøÔ·;$ˆ66MG*P8r�9å$bN”ıDZF}a¡¥Y[ë(í ³PŽÀ²ì ÑFyœ¢G#fåX¨5eôwXíò^†ž,¼HfŠæk¤ èQë|‚FÓèpq01˜e¥6­|„©¦o£;?ta›ìGïR™é«Þ‰ÄÂpi@²5N‡É~oøöÏñàÛ,˜<“0=Æ$ˆƒ?B¾2Ìqb'en~7ÔߘŽv‹$À© ´ ”ÇZ¬¢ó<‘ÝÍþÀÂô 6w̬ÅüéʃåÅV*ËŽ§ÏÇAëÎÐ:èÉ_ýåhy,Ç ·/{¿=”Pß!ÿ5±D Ú ¬}€ü W|rU“$À/ðE„qA|‚Œòc@ñü˜wKŒb£½Øú£”ó)v‡˜(‰Îžy¤þç÷ÃÃovó ‰•hz‚“Ìe™ [‰¤?]Š%ÿã`u'\¦è^Ù s'‹ºÑ‹…;ÑÚqzØî¦_©“……âÉþã½+j¬c¬`ï9E m‹i0º¨'‹r?bˆ‘z(;„g?Ư÷QÜçÊÔÿdlN–Ùq¯ *‹Q‹™ßm FüCJÃý_!r½(§û/m‚Å4P<‚| Ù«“–E˜Úí¶Þl,™SàØ&CmþŒ¡àS¹IÖÊŽCŒÊ]ü’ÄA6,ïuÙ*AzøU t*0¥�p÷)×G -âì~Ê÷‹º³í?ØF<«Âm ”ü&jÂ¥8ëÿÌ@¨Ãkp4fvŸÕý­g†.®q4¤Ç¥ÎÙj0'f­\l=¯fÍÛ Ãùxòrë}i¡½MD3»eeŽÃážy÷naf`Ö“ŸÓå»×»ï±³ý¥ŸëÆáúû×_Û•¿º¿¶'þѧñãçþ·)n+GÍÚíž‘kùvÍ‹IíêæJ 9§Î ÀÌòV øEûˆÍúkç§÷¢ØÐ¹ Õx³ ÔD¥V½8¯ðÙÏX­Mj“"6·ËL= ¨l6À�<eÍË·Y`–p‹óx)Ô!«Û€«q·ÁÎ=ún h~å ŠÊ6¾�¼†«A*¸5xëüYÕ±![ù(mì2ƒl‘ÀÖ­N(lºaŸð°·à„Sp«k§¡­lÕßÈ ‘Ê~½BÇÊz±’&{Än) &H¢efð­Æší¯'Ñùy1Jª¤&Gp oGÁ„<J$ºFdMˆuo¤²ùÝx $œ%LÓ4=¦½…;‡êXÉÔô�'?¨ð+¹vo0z«\ÿ­ùÍØ™€+ðo;@È:Ç|eÄ :“1ÜÐyʈë=ì*ôªüäD¦L?úöP>ÜÃ`á›òtâðõø´›²ìèÃbLŸìÞgÿñæK}ÂHáñ“Þ(:~ ¦ÇIDF¥àí/ý7òŠÈ¢Å'¦�PT@phPKD1N(&Tf(ÏÝ=´,¹µrýâgN†`€ò�EjBþdtÐSIœZÚHZÅ"]qw'ôté…9*"ÙYÞ§cä2ɵԷ:Éÿb¼0¨‘ü»¬eÄ“HbM=Òò1`¥ ŽŒ'YÖjgvL"rTŒ#‡˜h¯c2’ô˜­-Òiˆô§yŒû|¼Z -?úœ¨úˆ±£Y¨‘§lò)* (Bæ Ðað[ØáXï[;T%o‡ê.T~ŠW’§òÎÊKª`%[´Ž’ D嬼³“+(Y£]´ÌñŠ5J?Grç(f½§>=€ÎùíÐ ?ãk±ór•­Å‚@ØÛx¶ (T465ܯ„5vŠÚIçv k›7Mp(ø¹|HÌlOî¹½Ù®U1‹I¯ÀÁö™`½Bgø�0µã•ü˃~õÊêqñýòêüÚ¢y‘ÍyƒÔàÖæÒÐêpÏ3G/—Êx܆£®_zÜæ÷ÖÍ÷¬¨Þ¼âà’¸>—½9<¸ à{ïlY\5L\‰ý¹efþÞYôm«›ön)8«ÿ˜1â»èÕ¯WŽ ìEywkï­içè$>Gþr”Áù¡¯2ÿG¯ ¯PxõK¢_eÞY=S³yäüÕÕ0ãu{(A‡w4dU¸Š“’/Á%$´€n»Û�™=™í™ÈUÌBkñ6PÙ€Šâ´ÎÏ}ü¢!)Xh …ÙXÌ9ÿT ·‚­m| Ç{Ú ('[ðÀ…ŠÅ´*£ D±1ÖÞW`‹;jI(¥Ñ…¦å(§Æ÷’’øþ«á›Öƒ8즊`6=´õ †ŒFèM°Ÿ’Ë Bb§SŽî>YÊ“ØË“WÉS2I°Ž[H»q?·8ñÃS{”T§Iu¢dÓ.u{ÝðËñH'SÃ7a'Vöãp÷Þés+Þ±NüÒ?"þß–b‘ËÉ•Å2öõ ÔÁоl@þ†[€lêÿ8ˆ¸ê8,ñÔ·Fº´ç³ÄŽ•E6Ý!Aî4³:ôïÇt•b¹çä¾{®à·‘‹¿UÑh¡Ä¢ó|²æO›åM‹gö„þ ´Fâ…Ö+®"–Ûb†*¿zÈ#Ñ(”ý‚Õ9¯µâÇ?¬Ää2r²L€LŸÆKf'6“9dbDÓH÷Ç錑L ñ³Ì(õ’ i2ÂhuC©“ïõ^,qاH—×öeÞh+ãEÊx²ÚÈ’çûØüd-‚P d%M‡±­hrÒÂ*Ž¬è·¢öUz70\O¨ìÆ Q@5øHe£ÿ1`ƒ…³HŽ˜Kæ[:V¹8 öô°_Þï¨×ˆ€»l_•£R6Lhc\< S“Âxoð2Ì·±´™¢f7TËÝàÕ‚sØtŠ9º¿P,æ|š÷¡Ÿ?Š%–8JÜÒ@ûlÃñŒòH @ŒŒ`sdu§–™ö[ð½*÷ \ŠYb<ž`«Ì&Õ³=ïSÈ:¼Ú €/PÅ$j¢yÎÇvkÜkœ5Š+àÍó_ójsæÊ÷ýÆšvÅÌ > ºÁÁrnÙø{7û?³@ÉÛ»îâb8<?7½ŽŠ¸1ÇöÞCŽ˜ëÖ\™·_¸nÙñ×®9÷/Ö†«Wîm}±Ë˜ì+O”»·9³½Ûºlî Öàeõ®_wŠ{׆ûµõðì=óg‘>nMÌ}͹s¥;; ÌXªç}¤9é-?<÷é™y�êŽ[¨ú•@„¬ÎâÕÚö\Ê› xn [uÞ„ðÚ x „¤ hhxuîÑœ‹}æá¨T…Wcrv\€/Ô¸š 4Ÿò *$•’À­sVÁÖvàj ¯"lQ. ÏsÛ<¢Îgÿ‡#û+HÚ À¢&€Þ—苇†g6&F@BЊ–ãä_ñHaOæŽñÇøÕJˆ©zA§öò"r½ O¬!Ý%âÞ›Ö»A–å§a~ñ³tý”܇îeÜ'˜@`з¾é;cöv¤¾;~œàm_ŸþÞ‰ öoŸDv`ÚDüB¤‹KÝã  Ný/Qüâ�hÀ®|å¸6„j‹  •ôê~¸ SA¶wºJ¢oOŽJ¤ý'=HL13ŒÿQ dxÚŠ?`úcL—ž +é VûäqÒ²ñµT»ÏÛJööüÎÒ”}^©`‡�¡¢¥€¶ÜýgÙÖ;ì%`Z"S*°#¤”Ä~^Åaìo7}ô‘Ãw›8Þ˜ô0A+êî&e+G’ù•%ÃJ&Ÿê¥»?Ç»û¤plŸdGduJ¦ ½!¦“q:.æºÔ"R>lªqÑ^Ï\3:fÊÆÈ Á°øüI¬³ë ?™¦7"0e–5Žü„mŒŸgÖŸ·ó,ŠË« Šæïˆ"ÒѲ³~:%öý1þ áHnD°Œ´Î)€ Ì5¡5;$Ž®B/È˽æ_ªŠ}>ì’îQgE`l¦JSØÿ¿°¨ÍOhfqmÝ‚ŒVk{¬ä|BvPâ>#КY –B§¸Ù§ý }¢Ã§¨P�xS±Yü§7ÃÕ�^M4gÛÿúÙö™Õ�ˆŠÏÜÝæ¼rkpÁ*tÆ#8!TÎg•ó…¨Ò˜7`ùWL˵sçUŸ{ä^5W{çÍ+ àÜâÞ¼²ŠŠ‹œ1`>ˆ”ß¼ïûÚ-Þ½ïe[é–®;¿ÒPúqQíúyà/è”Þ3þ>—_è‹æoÖ¼†Zšã^Ü !ñ®ä3÷Ù¯ˆp»B�Õóç6Kñ¤@Ûq¼§Â½ø3QpO V›UrðYà¥[8­^ʇ*×T áU9k�D  ŽuÅÁŠ\Ž*ÜÍy¶9ÚçïßLVq¡«óK …w¦¹öݺ3Û‰°:—Ô·•�îº@…£î¸šàR M €Â®bkž† @‰­uûÿY)Ž$a§|}(ÉŠÖY­¾•Xf9Ã|5’Å ºb3æaÖ·Ò$zëÃr>-RGÀ‡Ì;jº“5`fs‹ÝаôHôh>«º“"ú»ÒbÝËSô˜ «U¯˜Ïî§ØyK/|è$G;ãE}Ô•t…eÆd˜pj€Q^£Wœ.„ߎËÁÿ%ìt(qùv[U4ëë&ÈW%äÖ„ ×¶ ”S% )>²ÄË þñGO Zö IÄ@»#‹`ê+Ùè:ÞӪù¾±Bq´’¿¥Eó7\Öa—ü@;¶9а«ÃPuHZÁ¤þXI,Q6ü{‡|-º?·SqPÙ‹° k2ÀðëVv«ËÿôNîPG$³hÝ5p„e’ÓèÔ ~›(äã“>[^."ø4;Œ•êGË‹ú$ƒµüÛ¨LÓ~þ,ÜÇÖÑþ“¼…SpJSÇ­Þ7 %OŠ›Æ¸£L'7 Ì؇ÒR¯ÛdjÑÒã"¹7Ö§(¥I:TÝ =ÉèÌX¥§ÚF·}j-¾<Šl«­÷R¤£Ü×Á¯){¹b2Œ.™b¯“²ôÖ*ë §'Nòá‹?žvè1¡±VyÜK”¦I² §‰e|«ÂpR̙dž Ô ·�¥ РܦÈ)?¤R?  Ì¦{<XîžT ÊÁê¼rnY½ŒI˜- <«úA€ã^S‹žüÏf >ûŠ±Ú¬=Å›—67q‘oï–Î(ýïYµD¼òSDGg™¦—¥‹ˆè§†¿÷AÞ›iq«}ø¯÷¾ÝÀÛ‘$.JwÏ=½ «æU…ÒbTízø Vá]½‹‡ËÊ?? oÞf‘s«³ªÎgÞqOmx%§ á6ØoŸÁ[GhV9ª>À+u4/"GÚp)Ðà.�ű}# 4·q–» ¸ ßSÜ­CÎåOáRß`¯t|˜p·:G®+M l»!¾¨ÏÎ(¼yöJEð”pgºl8D°ë¨�U¹ $°Ç½ºxV«–=Åd�šž‚X ¨"¨‹gOÁ ¶ t‰7UnØ÷õ ØÔGß¡nM|ìA«LÐî9Ö}n N,¨á<ËNüÇK¶±ìk ? Vj,?Ïc³`3rJ§ÙS}÷TOÛ:9¦ É"Vhפ‰þø?'l"e$qòµ4åd\žô –Ân„ð„) #¹¸,R¹£€D0µ#ˆN™™Ð§fy!&Ó{ËZÖ¡@‰kpÔ8Ú`ÀŠB³Rù@ h;_ùÐm„([Ÿb1†ønjc?†‹ì}QH¢gÊv—Ðë„NXâ ”ÂþgçÕïøxzv†s<%¼Î™IÞjK(Xໄ œD@›€”° ŸÚmÊ¿/Êä׈J|r\þòßÄÐÇå^Øê?éyo„﻽8óé·)’ù©$þ­¯ôñ‘5Õ½éáþËÃ)k#…btŒD™»&’æ½Ø2ãu{RŒ Ö/ýü!RÔRƒàä[üŒ!ÿ'?!uÜê NhbZÜ Ž6åÖWþ.ÐÙClIN25ˆÚÌ•0>mGª{¤û° C+û©DIǯ×Lsd(Ýýò(Åb“¿w¬oZ:(w(žE€n‡ ño€î1)Ž`­ÚjQfÓ9¬‘䇢­:ˆz–DW ÛFâd°ªº „™K#Gv Yj�ù-©`?… æbÇ2EH½Ç¥âºÆí’³1«T8j6p^|&I:÷-ós@]xUu‰šÃjâ kúrÌ΂ÜÜ$x|ü¿T»œ›^ñôrQº ì¼ÜM¿§0ÔçW:+•÷¬Î·{߃#º%º ?¾­Ëô^XÑXS÷¶EÞûxJWÔDµyLéeÇêf£êJ_ý="Ôy%Ö%A—_¯fµ+ªœEjˆ›úÔ™;Õa^Uüœ½ïoÙ™ïù‰%R%‹²sNl³ÝamwgÄ›Y wºwÖw6±ÁèE …Þ4P�_êíëo ø7qÞê%,ƒõ 4’™k̵ï¬<É’›vn1­ÐVÎiI”ŽT")Ͼ $K¶Ü¿´åR±H>çy¾Ï÷Î Y—Q]j“ˆ¾VŸðêóy%©“¸S¡`Ûë³û1µI¤ -C=¢BR!–¨ 42j£üPI Dñ$~ÂJÒm¨õ@êvÅ$2Ë #'¨©µˆ×ˆÑV¢&äÔSTT TÖ€ŠqMÖ™Øí¡*:ó“çÑ2H¬3“´ÂZïtÎõMš2²Gmq³ï­,¦µÝ¨ЙaÅëPL‰Èk)¯R×…)ÜQœØ­ æíöÈ»×âÞu1žZ:š³5›çåMë™{É1aq6Ú‰ã»Ñ¼X,.¸½ßöíŸcw:{™óûp›hP Ïõ aö ‘øí²{¦*Îþ«[wÔ·GúýO\öSÔÍß3µ <âð(Lm\ ²þëÈös÷D©�šF¶¨… ƒ3ASç=åÛÊ—> îEEPFH|Ã¸ç© pž[ÃäœÎGêh_ÛY¶‡Ë[D9&Ã`y«nxž*`Ñ„¤x.¢&ó"8©•¤áû³_¦]¢RÙ3O{Tëû™ÜÒ“ø‘Ûu+�� �IDATÒ¥!Åž=ú³:Ÿ3‹ÓzzëÁŸ¾ý²òZÎM‘w*»‘ Yç¿áÆÉð˜êl?Ÿ)ÜXš*¼~=|ýƒÃq±¤òáÁoövúû¶ã¾áUå'îÖ±’a¾}lºFbÛnÂÁKEnÚ|ø ëÙâ@¯ß³](ËÑ�`Jßh>öÑð †ý\>Aœ\¸?;[º.ÆÅS÷ƒÂÜkY¹¹4:°ÉÞ8¥‚èÁ‡xÏϺ¸Êò ˆwoAy˜mnUÁßúf‰Bû 8>¹ûzåã£r‘åÂIXôzvKäó}æÅÉ´û›ª³²\èqrý³¼¯@ѳ bIö+Ó–"qËî¹òÔ.¢<`&;‰Ï›Fa’ÖòʙυDœÖ5ѱblc‚ähšޱ(ùV¶qã :œò—Î;×3æÒùšºùF)7/©…/f-$\ÖE7Þ\á-VhûŠ iÃûO‹s<'i¾×Nõ».¯¼æeÊ~òþc þ7é¢ß‡sË%â÷½à÷¥¹ñ}2î ¢×|G.wYâ\8]â‹Ëý1´ëÐ`Åm¨_éxUK´/b†Å Ï¥Eû4¼ÁÄM3! ±˜¸I­nâ–‰'ŸI ,Bd¸dâU³^ÇBÍÓÎ[î’ç´ÅÙÇ®uCHÁÈÔQU'©“´ôºƒU’&±3“Î(a’–n|#ŠÑë«Ú6´—&iÃ*µÀ�€ Ôu\㵉Õpe¤Ëlõñ¯¢~‘~éTÅ!°mÌ`& xµoK/½Ï—!ˆ|û×ÿ¸8­ŠÈgôO~ìy­Àr˜ O‚Ñlp¨†ßUó'|{Ýg)¤·®ó;fgà6½Ý)н‘::¹#PÀ‹!%çŸ.¦•ë8g‚2Ü‹vÑܱüæÄ®c%5üÿ`;;ú÷fýÿ——ÿÏæó­e»IgDCw„I$qÛˆ5-*¡ õ2’]Ê<uOú"ȲF(ÑÒFTHQÙ}X Ô`†ieEùkQeFý|$A�’â*αÒR^R“ä5åR‹ŽwZ‚ª«¬CÔ Ò¬<QÝV„§ßÀ5+Æ­™‚Ó¶s¨7ÐýÔ Êüôsû¥—RŽ7\ÁNí==<ü?0Ês~°o·È¶Ýxš“¹Œ©“_Ï<üѽ>|µ0®Œ÷²Ý úÕ¡ÝCMß¶·bFsöd®<ìø½.üÞø–÷%Qš Ó.GIÁ¾)#yLáÕlÛ»½!‚Üíf®W þØþÓÉÌöLiú–Ýœ¾ñTœø@ô^Š! K•—¾x]H”¼ø†²ˆö+ˆ æ7äÝÎö ÃTïvöm>Û²8ýp¦0¿fúú¦¦~Ùb:.ãÊusj\> äÂÌ0¨¨­Ì•Êe†€eÀ¨çXGØÀ6È=ä °M8ÚÞ¶Á6u\'iœ¢8ÔêiX;¥„žr7§Íþ„ä7H$µ:!ÐJOCxÐÉä[Üš@»Z‘…Lm²ãmš7 ¤wâaìETãrû[û¾fü Õõ­Eì¹È®q‰{ú‚_˜H®¬À\ö®~·Ð'åÜ—³8cÞIÊk^‘Ðó—sX/¯.™Äê+ºæräªCòòRþ ¦„7ÏW¼çgÿ¥†±ë¬W–kÏaÝt¼4 t˜ƒDIp<ªc[ØI&ÏD<ašNHÍS >÷h;Ú•4̉נG2 iâ[iŒF�ÆJÕ¿‡z´ÛZÕ©µ èÚT¢šÓ©Ã–²m ¾a’µ³î£ŽjK´"Г4«›i­®U—vÓ´»:v¦xbLÒ\NÐIS'M¯Rk‚g30üá¡óÙhP´OËCm‹Zþ¯¶äñú=+Çiv°\|ݾYY’¸‚þ^ÿca^ÞÀVîVK°_êÜWnO›©ÁC<Û#{2gKÇ>r»ïï©ÑëŽã ËŃhžlŠlq/#`17³U"ÿÛP�à Ñ7Ciú^ïê±ü»áÊòxCE²§‘¦XÑGÏôþ¡b€‚Ïëø5XÕ°Ñî†ÁjzÛg®YgòOÙ*ˆ‚®úÙðvCkc3@x÷R¤ÌΙ[3j”sí楰¿v¦ÔM]Q«µÙ2‚4©Gµ+-[Cã)8\³ªA,M©©•ÓíJ$„#š”×'”Ý“¦×3ž–è�l/rXù+3r,£;,”í]–oÔ8´ó3Õ™‡ò¾žôÝ’õ²\»¡íeû#íg·ü—Kù±}|;ßö3, öó¥–˜ŒGa¡ Oþ4 Dç‚@÷HŸvme°ü:Þx E}7_záÂ\¶uóámŒ“v,ñÏeþʺË"WrÁ燌oNÿè5'¯ÇÇ׫3 9bôyc˜®õwo–g;r °dpgƒ’’û‘Øg¼º9åæè ô7pt _oœLõÂÃÞìI8õ‘\8Èæç,¤s?ø»±ÿý ¶¦ ·¦ å’ð›Ãù 5Xù‚u´• –}ÛÄkémUW>UqOÕ¤ ý™$i™¸iµ iÂs7Ì mûºœè‡ô¤¿ŽI'Æûª-V&Ã}CÓ4IÓP×c‰‰ZÍNf‘Æ[¤¸k§öj}Ùûek\4Vj^¢Ý_I0½ô§þ¦p_éeÔ¾ –¼5—ÄßÉ)z¯~ yitxk|—ÒâÚ{Ý£š—È¿V"ïIWœiñ•?ö®"ºy‰Åóæ`8Ïû¼"µu¾Ðq ’OͯoéðC%”õ9+=“Ô%é4‰4uü«IzT:1Â;-ÏdC¬Ä­x’‰„mUÇl=J*$¥Ôºê­ì[ë©5¨ÕL­itÚ­e<í ±c¥îŸëÄ÷°èØÆ¢“&¶N[˜‰"®œ¥2¢uŒ€šÔ¶a’†¦i¨Ÿ'³£Ä Úk¬KÓvF9­&ëDýAê‡z©nå)ãZ @Ž@ŸØŸ-lþÄ«ÜÍ~ázV<*žæE73,Lsk:,Œ–Ü‚û!ü¾h¦¢[7O3œ‡£ÎÌáòÜuqíšššEÒÍ‘™ý z8¥ÝuF¹ßÕÓ.Z+|T‚bÀ‚PeÁQ÷ñ¸˜æ˜Ò¢^ÑQÑvüÆ1@ WÓÁ§fð<¢g,$-…‡5ƒË€â¯¢Re-J,åÖJö+¶û„LLŒI–?Û}׎FlÏØW£ðõ1S¯˜²¡ÜRÈð÷"±ë„B¯`iñŸb•u§Ö+›%U’)¯iñ¨® ¤45 @Ô >MYÁ‰PT ®‘ºZIÝ#S¼cªœòÉQÁwE¯Ãìhãd×þpÒ5çÌøpƒÜ�b¤?  »$½éx3úgÊ’žÃÿË“ ùWs›ÁMÏn_Ì1s½:Âû|c¾›íÏEÕCMwC"F9RÕÕKh@öéé-çg•|•Žç¸¦l.ô+½”ôåíù‡£¯ ÆÃ’›f÷0¸3*3vÇ#•ç_÷gª~Ú—Ksþ§7ªÁÈ÷ç¬/l8üÑ‹',ìÉÊì†(ùÅËœv²4¶â·‡‹GrxÌQξ¼Ÿ‹ã|ãÚÌGǯ9ɹ½ã@Þ(x[eÿs¿œTR0+UªlÎ#8Z¤³F&…-›Ÿ÷iwÓ¬E¯B'èŽ#A¯Lúz a&¨T¾~¡ –$ؤe€ZÓ$îÌœuBþ‘úœZ{Ë tíèÖ“ýs|¡¤\h®'Ñ¿æ »„3þӼ×Îâ&‡ÄúEû¦«ð•Ú»]üÅ|¡Ëõ³}.{Ï0ñVAŽ/O$Iãí¿û lüÅgÃéàÖ¸ŸÒïZݵ/R©šg•ý­ÇѼJÚwq«,/<ý˹¸qiȈ/J½ëo² G܃žvÿ„ÿ†ìOJ@²“fßKÚ“Eî�Ñ34#z´%í6±4í¦'Ž+¹QVAö nXc}bÈáêwéæ2 O_šN¤VÛ4ÔYXo¨´Œª@ÓÄk´ŸŸ½RÓ0HÔš©õtÜ !}4á¤6L,MÖÒ+ Ö¡IÜ4¡$n¦Jê6Äkƶ ¥Y%º†¶„Ü5(šÍg>ó§ö^˜âP‹;Zî²uˆ»¡‚?Ë-ï«òGƒÝ믱ùÝ×GÂòZÿÎ~–ï‡r‹éë3õäH÷–wf•ŸÃg¯‰Ê,MýXÜÿ±úæÈñ##à™ÝÛ2ã²y52…g¸~¸€Î+Ì8Û—fð©ë}aù2‡b:FÉUªœ eKÏBÙ0öž¢ u+±WaEÛ ³ýÇ8TYùÅÅâ?0ôzI°¹ ô³qS© þ‹ÌUÔðyü_zvgy3úæCþ0ö.Ü ëC 4.*õx$À‘¬š üb„g�÷‡–ëöþ‡|æ¨8“·M©EYÒ+™J¸ôÓGˆëÚ¦\Zö~ƒ¶±eŠÒ–¦Õ@R¼ÏOÊ"ïÑÙJ‡äyÆ]v ˹$?äÛ¯#q¢^õ³n@þœÞÐøš±‹ý¥Ð”—¿,oН½¼Ú+=¼¦>ú¸üñÔ=qx{7ïÈW‚þxÍ'‡†E$ü(õ¬éP {jA ¾‚/W(Šé]5ÎÍh¨sAÕ ñŒJÁoæÓùãÁhkë8ø§¬ïÜ­E<ß±•¹öKÃñIeê ߺѿy"O޹…\Ü ‹7ƒ»GƒCf,AÞÃû9;uMßbCž Æ ·e¸?5Õ;¶îÖu5·{ôãÁÝoÇ¥9…©Òôk1ÜÅ˯QÍ‹ƒÄýãgÞ&M•¦ÒN‹wXòºÚAÑ„¤K,3à‘°,FÊ¥5Œ:uíÖ Ú ä“Ðö¬A´-7Ì©J«Îĉ2a‚Dj&cA\¿ÔkNÖ“§ÍßêmÚ¹l¶qVvšçÒ«‰µ¾No{ç‹ìâ·¬“šoØ¢“ú¾rZõ#È{\®ÞÀøƒ„ËÉÇïž—tsß¹ê8?âïf—×ÞwE%ïÔúø‚5ù_bwþ—øR]auÙé Û©¦iK X Ò(G-W‰ˆŒH;Ó^Ô8jœAxKp&©kšFIjèDBnèiSºQÌÆ$·'Y4䰪è§4m­kšUh“Ô&ÖTQ7vM«UCSÛS;07ô¥9©e§iœšÎŸ%ÍSJ’ªÃU°Þ(´f’BšTÒ*‘cÒð†¿î„—Ë`׈:;dižþ L¥‹×£<7Ó’q1dJÞ:˜ÞšÚÃ?œ_H§öäÉõ|ÿÀf¥(vv·×e¿ïoÙý# 9âŽZ˜+¿°{²9µ£¶½N?uiø©-¡£ôöóhoш\ù^ä>Ez:…©8uKF¾Ân`6ª¨ùÙ$¯/µ|Æç´{Ô ‘(´,ãž$8$ºS1Êk+Q9ÔœY‡�Ýq„Ò”* <·o0ƒúÝב,›Î·Õök{Ýv¦&y„v`K%³9Pªd?2 äJxá*þe§®óz‹krI¼ü÷Ár¾e:À8^͇¥{ûמï )Úùc•èt’’»5´½bXb¹ß§LÚ—ˆÜf^WËigh—º@8”¾X±ÃBUÌåþ½–s»o·ù׿ì0Ùû=”´šrÎf�hŠÜï³W'oœÎ0 e‰ÂŠ‘ΩÛEûb¸›5©×»deC_ÇÓ¨l)¨¸;½ÒK;„{7²…™pïzI÷wò…R ~:ÈsÄIÇCi6²â+u{7_ÛÙ ¯ëø ý¯?–ûGya”qRe'gn9˜Jg?`ˆU;jëÃÊ«o¼œ*Ù`+’“õÒð^ÄÀd=­$gžÞC õ§.ý¿+ðÌ>\T]TuÆ5¨µ ~¯2ù"·[ºëŽìBkxFm?M[™ŒõÔM¼¦“Õ‹QÇ­sÓ”F”œ¦A\êÖÕĤ¹AŒi7õzÒÛDöï©„Í·ý¾�›‹¡ßëdš¼Ÿò_Y ï5ï»2â’î¸IüïóÚK®Â‘â÷3oÅ×½—ÕüÎ…û;²Ž·#¬ïìvN6t­ŽØnQ+ê¶´T–U°¡ã: ºV35gp¦-HVuLÚv ´šÌFNK5TO…÷RU´Ü3È,†vºŠž¦m¼H-©mF5t2‰Œj(!¬G`lKÇ=jMm%qÓ¬ƒªœõaã |¬£*„M­$ɯÀŽb1f"W‚ÏÁ®šÄ=¬¦Iƒx5rÞàÃD²^Ì’Q°l}ZÛE8]Ú5 ÒÙvÓŠ‹þ§“Ô–ƿեeùšœ'óƒ‡òdcKt¦Nü=!Žð{Ÿõ±³Ž,D]¸1­<J¼¶ßîô÷÷ð S#A®J"URÈ‘î¯à‡vï> è§½ha1•Î䎰n¬ {Øß•Íöõ´ÐÕÊaŸ§“DU–#ã$í€$ÐWtR¡ê´­óyŸšÔ8-*¸†aU—ËT»ÔHmN›ÐC~º·Ô}O ޾V»»QÅ™âœ^ú€miå5⛚R5V»êR&Ä á’ä§è9Gž³7Ú™/Ø, ¿ýïŸ?R}·ùÇ×~œ›”VÉQ5t&"ŽnŠ;ôÇüf7깨‚íÐ)~a·»dd<7Â=Þ–ÜÊ’Re(Da‘AC±¸œKËuíóé“R¹ F£%~8WØN<õxzªzKª|>%gÖSÍuX4!¼&o§™Ó¨cëQøIºÒ#ÈÈ1K‹r ¤ú²k<i8TKÐö¡Ø½¦KÎ"õ‚,Ÿ ÇSˆ¯ÙunÝ,?ê;(þÁM÷ÅñTè>n2«Á‡ŒEYNU(³èû¿¾Íþ¹CL_S~‡^ÁOϤ³®Â ;¿³4*1Þñ·dprgü”%'EzV¬Ÿ3w%j)L¯¡ÕØœžˆªÏP÷Õ? GÓÔmBšÚ6u<±/C[G29šL˜#ëgÛษÌc‰ëÄhV‰1Š4n¾A¤OáûŠ}«˜^Âp“‹kûÆ-ãl þAò¹-Ò›ÌÊ Œ Sdå²3j^Øœÿ¢æÛÞoRÄï)›o$ñ• x~ü¤Ó‹t¦7ˆ†ùwî¢ã¿€ÅÄ;xQü–1Hó-éìnZW„f$ïo½¼æÕ`ÙùVk€3Þkž›Ú ÊoÔ*Ð64s’ JÚêd,¨“xS›ì¯$°ù+jD+ƒˆ~•ç§‘A5P2BBW[)gÕiÃ{šu>=¬@ ­ê“'`ªu¨èŒ]Õµ¦‰!kšöÚ³Ò0¢nøb’?z*ÜoË”VjÏáQÕ iZ6\;u|B.+¯èq~ƒ<j;“ ú]]•¼ºnÊ]ÛÃ<:²ù7›ÓŸ˜/sžýùéḺUHŸSš½žíM«í?ÚÝÃå“þÃÞÏþ΢_I(PþÏlOQÙü”¶9>4c©O>—Ñ Œ$YoÙ6䊗fìL¸˜¾¯} 72¤.¡8°OIE°AŠ4åÀÈ!`p:Ìyå©®êÏ?Eµh×ÍzÙH´>{¸ž‡t¤IV£*F¸L:ÕQÒxiDWÿ"×i ÝtzQ‡3¦`u9ÓãÿÌ£, Ÿ?T=ó—mUÀ Ðôü­›¢¨RWÖÓbŽ$ìêþ¬7zúç#{4RÛOí«ž Z”VEÒƒÀ0eýNg—Íëˆ-Biä]#G*\Õ›M]”ºúœá=ͽ< T9 GC[QHW†ØKK08H˃eÆ›óª33Õÿ×ùÂa¿Ÿ¢×òñ‰;Y°wó²”K¯>QHJµ2DÀínTud¢U‹ì%m¡»½ž?áf±Ëü¾Ü”UQ¶™ˆfeZÎYdBš½A`{é°kE~ÿî8›Þôûý*G›£#ŒÞ´ó?vÓ¹/ÿˆýŸf?œÄÔÇâƒûÓ.¿©Ä´«Œ©tnüs>Æ2—ß ä|PæWú„Ñì`<’gzajÿÀ=a4º{¯7O ðzq—ñ3dîhÖLM ˜bÅòÄ —©žñ•´†¡¾Ü>Õ?k[§Ý$nÕ8Ýë&$ö¼l6ô©OÚÄ6£i@׈ÎÛ°“2²zAÌ|y‘œ¥ýÄg”¤äÞçÞ çý·ðÆËŠËûÔÚ™{Ç%éÆU‹ÞœÛi¼9ÌÛ¦ﱟPWîÒ›Wûç¯:n^m÷}™ ßáÞ¼ø8þ=®|ß+½÷ŸÎlÙÛï†ù½“Öðà’´a¨9…‹ÞàŒÎ •ÅœNÎϳVˆ\ŽIÛ]+*:èñ9&‘„(ˆpd¤±´m©m—˜”FtzWg ªujÓÔnb1 mO•“†–¦kÄžvÛJO¥žu“\´—Äj´š-Ö1+uÝÆÔš:Y4 ÈE\Ê’çZI¬ H08ªhW à'†o”6G•RÜf1O ZÔnhÄ ²Cµ4Œ¤%õ1•‚y€[Åta>ºVúªsÜ¿û%[‹Ñì ÃŒâ«èÕ= pÇ: bFúÅTšô@6Ì­uŽGì¡<ö a*måoØÑ/«¬?œ¥S}»]×LØ¢TgØÒTR×ãÞ’p/JýÞƒò¢éçºìÃÃ~ÝÔš¬Wtæ©Ê4/FÀG£épQ´½wóõÕÉ󔿑Ty.(-s©øÚN }¤ƒ®•‹øbÈÜrñÔ3Yÿ ´t®—ÉOÃ|´ìûF,ªÒ¾*Їaá0ëÝT¿b\Œz}¬Øˆýòº ë¥ÕŨ“S•éÂM9¹vð[Ê÷lYª”Ê ,×Âá”7Åô^°@Ç]Ãÿ}øáƒÒöÁðÇU<ôrnöK{ÌÑØìCY«ç©¥39ùþk¯<.Å{àEŠÊÅ´ßÇ.¢þ!*j^ù®¨H?*‹a?c±Uuw¸;—ïf·®ëý©Ç3äS”®_+|{Íýp\Ú>áö[X¾¹°±myffãä_³­×º2ܘÝž¿6Χz/÷˜¿#JÅÊLáøÏߎåkGpûp8³³õ»ÞÄbåz×g–Å ƒ^**VôôŠ3m‰p ¢•EÚ]Úbbt[œ¶êÄ-³^‡¦^áíÏv“´1µ3;µ7_ü–‰ëúB0Éiî™ØµÔšXÿîûUÆ o‡¿ ú‹®¨l­ÓíÅ»!4ï-¿ß›£ó¼èŠø÷f‚¾¿a§¯?—­%$•¼‡Ë[çÛ»B‡wBjgçdr¾yë`€¸iÚM’†ÁQÃXO­«×‰¨L¶OR'`'Ch»‹Lb«õåjP“z%H…Lt½™À7ï‘8msƒ4í{ÍÔ®A˨³;©ÕOÍÀ­t­‚ÚZ:1wŠ8l‹j=Љ#ižž|É9Ŷf’&¢A{¢ÏpdB%-j-½^AåºÚÂÕåä9TR+º ¤äºZÑTŒÅX %ä‘â†è,„•ë`¹uhço›W7¨u΂à0 ?І˜àE4„òœÒ¾Û˜‡™y¦fØa0´üដ™‘^È츒úZøØéÈ…q+úÅsD+}*©HŠm}RPãy½0ožbFb‚¶òNÜ: çÿ¾3 Ìxh·ÑùÕ¦–e=hé\¤Î!_~é‡þ ]Uëœ DS·Ð3KÂäDwçÒæ7¾¼‹žDy.zC-<+¿ì¬ˆ4iéø>$H‚ÒòG:_”õÞ•*Êça>‡™yÌì!ƒÊ9¸œLÊjñY–}øÏí°OñÃÝÌ;Ñ«ZäxL9ñmRߣZ±.‡»ä#1s bþ•òR`鋈E;œ³ÃM58ð¢oG;%vŠÝíêÓ-ýö΃; ìŸÌÞœznO–¦¯W U!|([7Iü‰.¢*õLOüÃaw3¸ñOr$š§›óQ¹Bè„øß =‚b´øËÒ¨La®TüëjÞUA©#wÙÚ»]á7GãÜï•6·¸&_Ó¿=5xõ§ÒÍÑÆï3?·nÿ1È-Ò›ã|y8óâp¦·|<;Cq‡|xr°ûª8Ó;œ-þ`fgzW ¤¸­Ÿÿ–σûÜW}ÏJ+­ôL»¡šFä†”‰’ºý©©Mʺ#nÒvz¥I†I*§ÄŠ6f’=P“&‘؆^—æ´¿nžö¿ª®“ )  cÒpÒ¶J’†¹TÏjºm\‚VÞF°¯:ÞnþòèæÖ;—­¿WÆÌň‹PÏ÷þºÆûù¸áþ}ú†+Œóš¾nò8Zï9 Þ¾usåÑw _ºÈg&T0Ë%†Ùyšt»¡ko5tì4ld˜d•¤R·àPBSF5S+4-âœö¢Æ™Î¯ø¼·ÑΣ6‰‹zõ(†Žc]DjÕÔZøçQøéÆýªÏAFx³Ž®5'òºÓ±®Ý4Jœ6 5R¼=,=#eÅŽN“‰¿X j²fÀÄÊÓW´Ò25gNOÄRD}#¬xéçÒ¬´àSžU¹æXwžüYšÏûZöaߊÃåϳޱýN)w@0£Ä€ –:ó¾´o8 ;w6 ýš~é¼»ÁþItt¼qt¸\™··néU ‚Ü Õ-¨ÑQW¿B;iîz-šÆ6ðD8FŽ~žŽw#¿Å+GXÐe¿:a}9ƒRéeˆÓ¯ríÊéŠ'—Ÿ>O¥3%,>*UlˆÍ¡Ö4Y#J¤`]@ �/õfO{GþÒº­å_lQÌMÿža5³Î�ëkz=ˆTݬïqƒb.ò›Æaª2êéFCgXË~.óŽýyžÝþšºF”´sZµLØ åÕuñ6w ¶RHƒvê 9ˆÚ2¢bí}rO% 즥‚ß}ñpzg9¿}LZ”,µü›»ÕÙ¥SŽüKüÍêfóÅ̃,p?›"GÈaº·W,žíȹ­ÂÔ•?) ܃E[]S|ÂúË—5c+�� �IDAT´?S~úÈÊ’:Ý4¯ëÊè…º]…[ô(±,·Cù×Õ[…-¸Šé™!ÇŸ7¯Få•ÂÌôÑÝb.§wì´ÜÌ §§¼ûöé¾å0/M3Ø^þç+\/Ë›iBoÕøUºu(¶>æÕ“ùãÅÂ\0í^ßž;×v'S_Ý ~7ç‹~ÙåÊú¸—e+U{Ø)W48m× g|ù5¬‘“R6€õš¶b´+Ô*´:nhÕ;ìkè 2ÑFÇuiæt}‘Ùi!na+çLš4íÊļÏ£k+WgZÃUoçâ¸ä]UVü½m¾ãáÁ=Ó{kwã*ý\1×Òß3(\¥Ã¸(v{÷~.fY¿+Îø~}Cò.«õ Úåñêh3ïŽ0Iýªùàï'ÐHóÖc½½]4 äÔµ‘óÅFýòJg’ŒÚ0çë£DËÔµ:ÛVÕ04=øB )°°~G×ëÓd1“ Ä2Ú¦-Q˜ÀSkêDË~yïSm›Êb’²Yªëlr3R·´Äº¶ÊzcÂÍ’ºV°ÞÔëõ3ßÙ3:¶mhÆ¢“ “þ ´›:‘´ëš†ž¬×j_XVž¶ÐvÕ>rj]¤áŠò„Skàë8“É(sZ-â…É?Át64ìê Uºe>¶¶HÕ0äå››¡c`)O-?˜¡8g;ŠÄ/¢|”î~Í·'ˆcF[zwÛp­˜;7~e¡pîDöEê¥^jMèfDMó˜·sè1øËb…ÿ0¬NÏ=ð¾$Øðû…p*Ö5ô°§mÍU½"u톎[æ3‡—Xg61¶¥©V°Âô¼Þ ør•Míkÿ÷Z ¼4iæŒ]WÁô™ ¼ Ôð®v7 ¡ oš…{º$²W.åO¸€þ‰^z>©è»=Ú=òåŠ AªÒâr^B”­Ü1Ãq¸õ’^ DñŒ¼GmÅÔœ _Ð?wPg³gç& ð n™…Ynl(Ãê�DÅñð¯ìØ„Xwlz.sؽуl1˜yê§ùÝ'åü–¾­Ò2ê“¿K×?±rgSuÃNßXGܰ²™:„¢/÷¦dý<u?xåNüGãy1^ž?ósyñG¥…ÙòìNðÕèwvo,Œ¦ ÕÙ1…k¥ñ±ô3ቷG0µ#|³¢p½0µSwþ£¹È…ÜÉæí«ñT¸=·µ7pî`“ëcîä37®=<¢T™‘T)[/üüÓ‘ ª(Ë=ÝÆŠa¸"ÓC4´ÈÉ˨ Íê–çJ²3 ¨ìªY_Mi²>ù93ñ´˜ ´¶>© Q,O!åÚDöÜ$n21úNÐBDE_íNêÉE÷ ²2}î¿}Éñ³a..'.÷ãú´=?o.ȶ.VäÚ;DÒø}3Ê;œÓàÒÖw!HÉwâZï7IãÕé[ºŠ¿HßçæùŠÙ8óoè·@¤+ˆ´«‰º P¿tNÖ.,Öã ܧ¸Aܺø²ÍÄÞ¤}ï:{#ÏÃ44ø¾yQ­“Ÿ7ˆa¥ž…]T™•_Òv¦äÓ•nT톹7+ö¨u©Õ èŽ`½bbTHæ»i§¨*U8пh0É¢š42“@7Û44Y™<‡¦‰›Ø™dåL/Ú‰§Ü¤v“¸‰òÊ$ŽZ#¢Iµ–±MÚM F cKÄkªC´D~-ª5–ãÖÖ2-¶K­ÇÊ×éÇl ÕŒš±³SúÕ]Õ÷[Œ6Øóॕ¨“Ò†ßÉnͨ'eÌ1ÚC>³ƒ²q¿\½4ð†û‡ƒçù²Ëí¯²»ž!i ƒ"œé ªuÂu=¾ÏG0Î;ŽtL5Ü~©ó€JSäìσ^ž‰U¥Öh S’Zy2ø¼BØBAÛ¥JšZ“ý´b$JAÜÐU¨µRzÄ^×$ª;ÉÓU}I M ƒ%¡— sÌâ<{Ó’ üáíôoïWÿãUè'C=2ÕPmG BÕ™î=lC³Ê0°®hÈ£anJåçÔ­¾ŸJîg½ŠE*_1ÿ¥µ”øÈÚ²‘ˆ”f–U÷Žî˜³,ØÙÿÍÎŽÂ…ãÒîŸÃl™ÿqC‰”J2zÐÕÃ�jpCsÓÈâgã½dô­ûÛ ‹ÿøC)ï„v÷ZP˜-ËíP”Ëñ™žËÝ‹F=¿;òä¡Ù³~×NçvÿOvw·©­|&( Gß ®óòÑae÷x“ܵ½Ÿù㾚¡ø'9{;„Ííaot@0Ø~Lß;.n>óÁt!ÌçîÞ™ýh–ÒÑŒµ=ú»ã?È×ÇùÛSǃàU±À††Þm¸,ݸËô¥A„+9m™ÇòñífêWñCM©¦†È‰lI(H7`MûVTÆdŽyz0LÒy™„»µÞ´›É$#¡qš iÜ$iF¶Ð§õg½I­y*:‹›úb‡za=A˜O‰@ƒäbÒsÓÅ v^‘šgæ¡ÍÓèˆSFSS_QôO«¢y;·ø<˜èbá­_eˆôVm}—ÕÒÅ…v|¹–¾+ôoÒ7¼k‘ý.¯ö}Z„K±¥zò­\á@ûöiÔû®À¤1yÛô¥såœÈܸÂ჋¤±ó›Y#9gþLÖÑ“þ½¢i ’ž­JÕÐEÙ"ÕœÏ{iBtºFžÜ@ƒ£Z ‰œl•°I ù\˜vO—+f³§ß°¤eŠ‹&ñtHc¢äÔŽ Y#^MY‹’ ¬4ÊiÑ ;}Œ†¦N„5Q cÛĹN¨¥¬GÊ¥¢e‹,u Ro~‚ÚEÞ óu­Hèò¨b:«¡j-Ë¿Þȧ|é$L¥Ážu„ÂeÁPŽ<0^Ó‡ËcÌä_ƒ ù0ËŽ4ÿ°¡î-—é-¢ß{¼Àz |O*ñe\WG¶èâ?¥8¢0ÐÓ{]nI¶®”R ¼ÖðÞëz¸FîA {ÆK-eºå¬G#Œð:«·Íz®Y5Y‹§Ïè%f½¥½ÃÊTÕ#À¶ »ÆWtÙÓ'.ò‹ÔЦ=Teì|Èþµêü­âç 7(öÿüUß.ÛçT?5§Ã(‚ÙÇîè¡}AµgÜ=l_#MMn:=–îqc  sãJJ"áR;ÊÕ&¶Š*ö,‹ô…^ôfÿ¶ú{øÃ%^õONÊÁÜæ`TuGPù¾•7ñcÕqTE¢¾ƒE¸a~:ÃñÕ‡¯:<Þþöš+ˆ¹kÞÈéBgj†¢«î,±z›{ÚeCAÿtÄnŸMgâIS+R[±Ÿn‰ÅÜœšÞ?åÓC¦¤;q¥cÑé>¾s{a÷èõ_ ö<¯å˜ÜïÀ‚8v©[âö¡`á.ý­éÁr^2~^¹¼\õAdîægÜî-X¡æfŠk}þÅ<^hÛ3±äÑ'¸ÑÏl"ÉÊP€žŽëüz <?—&é*°|ªèEÊ!y,dÇÕñMm1 b¢ÓÌÝúPŒ¦yîžm5ôçg,•vÃØ¦¬œ‡Ï·ôÄYà<“æ¢[þé®&NÉöœìÿV¢çÅxZRÒ˜èýåîjÌ™úA]ðv½°ô¾Dç¹z ~E¥5ƒäb¾ï·7ÏâÞsÍ·vÑÿFíÛ¤N½ÃJú>!ÛÛÿåm È…Ë&\5d}§Zä}l¥«—BõSßÖä|dkÒž¨oÜ™{s#^\~ÔMùÔvFš©öø¼¢ñ´T°ÒƒŠI¤æñ=’¾QRã u=ù„µ[g5wzV%M&F'u£8ý1Öh÷N×b´ÒØÙ‰¢r¢[›8ËN®ÓÒR·4‰+ºíA¦¬1¾-° ‘zaè)Y‰rÉÊÊF»éå½(€7€/#Ú{c—ÔÑ`ÏxÂr!J(°0RGÎ2£@p°ÜQ.PÀŒzjˆÍ è•€Ämà|^FÒ!î1=Lç…ÅëΡDy`Ô Áö3[¼§ú7YTêm dVrz¸hò<Ä/Î¥¦Î eJRÏ:³çè4´‚Zˬ×õJ3¥aA¯¯‘õ ‚êaİÞ$膖kFô´k˜¬EèôJ…¤dÔŠª<ŒYÓþW©üX[BœÌ48tn÷ÿD)ÍúÑ’ ÿñÆ}™Ù¢=¾@µSѵ,†ˆ,€Ü|P-î¹ÍgÄ÷Ä#²ÎpI¹–ô3¹žñ‹Xˆn—SÛþ¿5?(Vç÷;¿—†d0T!#\Á‹|UF˜SAns”—V,ðѱZø¸2ÊŸþñ°* ŽòÒÞò—_§ñ'6yÉÒ #5‚_Ñ—[fèÃŽÈ>+i?g:#XÑaÓøE-œ¹]Ñ?\xœŸˆ!¾x\<¹;d/?9*9×—E9¾)¦srëÅÓÅ;UvÿýQ€Àg¿Éß}œ¹“°˜C\.£»~c*vïÀîÃ!©C–‹Ž!³·?.¿8”Öþ¦˜ÝrÔÕH3taG.+ñw±nºŽwŠE[ËU»‰ç&[Ô±ã×ò+L»lÚáî…¡W"ª­œRõ’‰]BZ¦]×§Íbó”ÌÚnR«¨d5âWð&néd²Ðn¼íÒ–\SOôÑöBã˜\J(˜ÈåÌ)âôNyK;ög)á…öåx†ï`1ý[tÁ§i:W^ö<Vç 2ÿ>žÒw¯ÂÏDZ業�ïÙ(L ›ÉÚ÷Ⱦ‹vÜñG8¹jzºÒWäân'¹¸cy+U¼n`†CìÞdÖ0ÔIFµ©2#74lþL©Ár µîI$åEc½Y H�¯q¨{)}ó™DäiÍiÖN9×b"²¯ƒ<ƒ2'UnòbÓ¸IèÛ ¶hh¢êQ{Q³¨ãÖ’2í:qS+ ¥cu£C©Û`ÖYñÌÆ7²/oPóB½0øj¹uJ&ó<Z[¶ÿKäúP"“¡—ZÌÁT,Ú¨`SFTX.\WE§óûGNÊ…p>`8• œa~ƒ=Ǧ‹¨”—YÕ¬w nù3"‘p,:Ì+l!¨ÎÓÿ˜ f7ŠL9+ïëy"ùU¬Òg¹äô�ò®¾í3é 7Ë¦ÐÆCŸ1 ëØ–Ywø¦¡ÑÒmÈ&ä÷Uj 3y¼Ù„ÍÝ"÷ú)M]Eû‰0µ¯E®%Q_‰f=å¦í¾pxûÏ\|õ%ƒÁK#@~aC—î˜{Ç3áx–'s„–Ö(ÚLjéX…ëú£´8yØXúí~VìëM[1a%¦ô)9‰4²U+æÛÃê¿N»ÁÝ¥Gá윔…px…§/² 6Ë­,˜Þ>ýœÌYÀJ¯åŒêçü±ÿô‡jö 3µã¦–ÿ0ÚPÛÞUJ2;…óöÆHü׳YÒ‘…žQÿ1SÕp¤ªÉ°ÜMåco¶\w”Šs·g)~trýîxf^JÉÝâÑN¯ûu–¿xJÿð²Øû«è7ߨAoyº·<F}VòùŸ¯²ÙRGxü äü7¹aþߤ•nÐg{O¾½.F_ë­|¹:Ç“œAƒT¹Œ0"è3K˜3BKÄpÝ[ž§%‰Êiczù&’9A÷žú¼=ÀN¤±¤½ˆj˜¶ƒfŠSµ–Qç°¡Ú-j øˆ&ñ§NRCðO€Ê…ò)äp;Otg-|Œ¹¢.ºpkïltë¡s}ºØÂ'§üÚƒžì}¹l“­º¼ÊN®Z$Ä7ÁÍ·Y ÿ†]ô÷KU¸ön¥~ kœ­Ý/KBÚW2½.HKâ7˜Ý›ÃüÜÖ*¾ÜÄ;ͳġIôfS¿ñƒj²r®‚yãâw8ek&i “€|Me2²½LåQ­i3Ýô];M~¶ýŒØG‚ŸwuFÔž¨—Æ6ñîÌÑÅ¥´L²uÍ$Œ¨iNu:éM“v®OŸdº´ëÄ’]ƒ¶<³ «…n“fPë7ˆÎ¤n­»öKámIÙrgÓ›˜0ì’{£öüÀTó¬æÒ•]µ2²~šÊ­ÑMJ·BdžÁ9õd¯ùq`å¡–w´ØÏCð:þ”|E»~Ýt¼É¤®JžBö+‚{é+e}]Aow;¯‡ÑÎ =­�½Ý·ÎãFä_AŠ$X„†yá´­kTûºW3Bb]6r8‚—ÚJ4yTOm“¸GT5MÒ„†™øˆØ†Æ8);#¨UÝÆøUè§Âi—›‘^é2v`‘[iÏé§Æ¡izÏÊ=ŒàÆÒñ~&^DÕQ )²…é-úÿv£ñÆ`Ïô^¥åÁ5K% èªê39æ‹álAûž®zý�-Ê©P0vÙ=¶ü9s¹!Jáü_«âÝjoj ÜK(¤ö¡Ð¡ƒÕÛæé–ë~Ïð¼8¨~“EONÌÝÂ2…Ü2â•S¥"~°¼?béy–»ŸÁ'™uuþÞTÅòðõ{á´ÀÏ<í25˜š›ÚÝØq3‡ÝýÜ1Ø"á”÷:“á¯{ƒrfbH_þS.|?úy®]®ž ´+K±ÆozË2°²Pq¥ßüÆýÿ¬½MYzïù›’H…òHTªÏ±$–ì´Ê&§Jø–5×mP°p 䦀�b™ÛÆgÄgâlsI €ZL 4£‹„v_|U3HÝ6H»ª'­¦$ŸÓ’¨:Rˆ”ŒY03•©L©«}§V Ißžç<Ïÿ ÷‚Ë]ë„®ÿf P6ß)®jŸ›ÊÅ)¥ªÙpØßÎ;Á<íV}¹#¿£ú$²R|º¡ê^ÑÁiÿF"Zl/Ôc£\ߦ´ À6qÚm‡FíMϱušÜ¤ƒåÙŸ"7E¦’ 8Èo`Ó‡\ÚÒLÙ¾šáOÓC(én·8¤±=„,kŽy»©F¿ãetï|§âí7 ~Ð,¯8Öf Žy¦îßnO>j‡ õ †N©G£ÿpo(NòoJ„õÇ{ ¶ùÓàííƒcš†|_…ø¶‘èwBPÓìHæG]Ë‹­·�‘:ÌRd{#HºÝ/ ¯)¤ÙzêtUÇé€m7ͶÔ`q! ŸRx¸Î/s£èßòPëíÌ,]E1B#K»<ØJÒ,•î;yÒ,[Z²…Èaë÷ÞØ¤·÷y3 p04ÉÀØ\Ylj 6·©£˜‘4 c‰« ø8ºo™ÑhVmH¼@@úÑÑøhÿж…Ó¢ÒÿéÉúî“xöƒ¯jϯå¼eîµ¢—»gÿn5º9wçÞCª™®@„¦p†Ò“@"p]"I:¥™ÇÞ•ÔÎÔ’¿0¯wqÓô8+¹´0õWZL´™@Ú©£í¨¶4Ò04*/ÇdŽoè݌٦¦£«NHå-â¥g‘Ç ©£å¼ï ClÆ-ŒØ[=|Ob 딚®‹; ²«wž5f>ÇO•Ø´Ý®‰.ÊÆkù¾=ÓÎáþÇîG4˜1’\Œntʪ£»“øñ¾˜¬û:’½t¦:ÿX'ßV7UfÇ!¸ùú£o@š ]î^f±Ÿn«ÎY+«ÈÍvÅtñæß~zñ,÷~<‡³4ö!â92Àú8½N éûrüw¾ÝŠ˜ëö·T›Š¹µœ îD§¢³  > twïà¢ö” å±—•ljõÔ?vévÎ洞rWÊp’™³¼é<kžÌ‚ÿ—§§Úþ)_œpÉá?µ·0JøEV­¡‹UÆNŠŽù Ç×Þàmß›jvseƒrÔ¥"ª–ýfŠh)ïÊN·³€ÐÛV=7¢§•dÛÙå¨D3m(f}V·ýSWéyœÅ³ëÄô)“»â±£ZЙÑ8í%Ifˆ–uVR}Š/õ†#‘{ã~šíùÒ½cŸN‰S·W4F”ä,“¨ÍRºTât¦Ù‘jx8Ì'ÝWM¥GKVr„äª[ø™•ùK×ÃËðóMß¹Cš¿»!O߃ò¦Ç:Pq¢Hù½RâC/ð?ÒÞÖè=Ц8¢R>FE͹ ¾»çÇ’»O$2••Ûcw~×ÛöÇÛœ¦Í}5y¶Í‘½5�ß,0 “fû-ÇÁÐŒ@e¦š 5ÔR°©ÓE ZÚ…š¶ûZèæ¯¾"ýTÓ3)Ø!,Ò-ŠÁrŸµ^Ú+§GèTBm* P8ƒ+UŠdL5ÚBe{Ó«Ê ³Ñp9½ê¥]4ÔVè­*ÔsWúO¡&bØÆv´_5£)sUžÍûk²ô˜¯Q­r㡈>‰ƒãñC"»~ö‘¿Ñ¾0ÿÝEûqZcmSwœÁ±}Ùår¯dF ¸îÐ ¤½ü }M0ûØü¯ç8- Wôå¼nót¦º_ÚŒ¶˜³ÎD58:Á’ãÀÖ±5dchú_îSÈrÍ•ö³¸`ÿô—™mipø\“ëQFºÌu‘ô¶ƒ†N5)±}—í°iê)Óoœ«iO´ñé¡Þm,”í4�í+X¯[ͼ¹ª¢ 7ý<ž>®jlô%sœê ¡QôÛ×Ð*‹ïT”m`š¶ñÑÖ߯˜ÏØá gNÅÍ"š:œü0}zñ7,ªµsîûWñ³¦Rµf7°&wnÏáBÙ\éæ?Tª½3—šmë„þl7–‚`ÂcWò,ö—  ![•W8ËÏxýæÏxzæQ ætªn€Ä²fOËñË7öy+:xþÑØÃ‚ËÏ_íâââIxý´.“o5¬·ÓœâKÃS1ö÷u‚gf·K[jBÝ—æ—Ü‘¡ð‚ê)¿X‘¢òŸs#’t´iµv‘<vzÚ…™®š; T2‡0PlTÖ»4h7¶ƒõñ›çê¬Üî‘HTPYgÈÖÇÍ@ÒùùNã¹ëJÄÕPƒ‰0}(+ ²ÏrFÌËÑ$+É)B,†¬Ü·Ù7d$ÄHÒ<N÷aç=’ëðpñ~AØ?€e {ûÞw!ùÁ&ÃlŸöû>lÙTv{Ë8º y‡ÃzôÀ}DÎeÞ=XçǤfÙQÂg~¼RüˆÙâç)ýa¼×pÔãðÇz`R·§'!̶¾x¤qŽ?N¬zÿµÐKßÓC ¨¥¡EYä6 Áký‹ÊÞJíÒÙBW35A¨g‚c3{`øJ¨·kºZÔ0Öé(Ø‚ƒŒ%ÖºtOûÃiN_êñ�5"™@F1„Á>õbk©CQZ+°™Yû;¦±5ª§(&’¦hsc®p±F^A,ÔÓ–>ÔÝÎÎteSØçD¡µÓ9Ãî¿®G3ãkͧ§„}Hø-ý™Ù}ÁlE-^XPÜgþ¹u?(ˆ»-³ºÐoZ%‹øõ…òÌ+륒9æÂ'êåÃxºI’³ Uf¢¥¢g`ü–¶›¤#FÈˤ¥ïÈuÔ´L¶X¾ERãî¨ì¦ÈÍÆR(ëöÈ‹#ŒÍ5!jÓXH‡º˜:¨Ýaa¼Côд‘˜óÈ·½\‰›‡ø€ë«åÚ™ø¿¿.ÛØÙí0û}±QRÚæœ¦2>PˆØ]D>¹#ÜøzMšÝo5˜µPÏkÆ}füBÓ*¯?§ü·6÷fÐÑÙ þÌ ùø”Ï…ky_[!uGZkóSÓ ìi”ëËæ‡›¾1 lQå*Õ€ºŸ0;³Î£2pbú!ƒ 8í^Ÿ²^¬uÎÌ©nž¿b\\»úb>yÕ\_ßù©œ«> xqú³ÙË—âÍÔÿúoï%}"Då<B²1Ñd¦étBQ†ß6‰ÓÛ~Ç‹õ®73Ùç²ëüÀî¹®z²+a<ÖÚ~ޝ~ão‡4ØàŠr… *‡˜ § W*w_lR ËTÚÂE¢NàÏ_²«wÕ¿"ïƒä–ÓæFO×òŽxàèX_ ŒG'¡ymÝòá:ÅR§P“.|lƒšd G9ö}Ñ‘_ÚI,aäá#ÞrªÇè6û%å0V|`“¥Ó%­&ß§Õ¾#«>F*>¨.ŽDmê㜨“~@ºù1Tý‰äާôÇþ—¿+‘K¼=ȃéO´rzŸKíÁg³%æm´õaÒÔÈ¢,j«¤NÜ>~•£BŽÛ×O N§=S¨éwu{næ\m¤Ô·B¾öåncU ¥cL™ ¾&ÞÝDí¹˜%Ú‘.Sá6uš3ê‘$#Ò‰)Щ¤p¨Œe‚PJY§”ôì¶Ó^;Ñ,åÓÒ b»´G¼FšÈi„ Ð!å3iÿ·ÿp>úþMÕ]ÑógwšÅX¶¨¥:¯Äôùº˜Rõè»Ò$¾�¯…9½àtWŸzfꧪÂönº3ƒäzåB9eÛϵ»ofè à D·™f$¹æ:ÛS†FW¾T.PIÖ_ô%0D` ’¬ÿ5;UßéFšÀi—±d¤Ø¬TÃ8ÁŒÚ‰—vïGžƒD9l†ÊIB€íº ˆ]h’Hýòê×⵫ê+Êb?{ªž‰øÒ‚º¿s-¬y. ¾‘ú†LuçÞ¬Ü}õ»Ï­îq~ÂøM¢<¶½ÆôwôÚkÏ/~~é‰y‚vé<1gç<“J¬öO›Vs¯^À\ ‡ü¾ƒ.÷VˆÕ‹&bYÙ‰ì(8¿­šUüCdG¹©èJ?ÿX´_МÇ7gäi{óõÊŽ{áý¬S'màèJ5Å^XíŸ~9>Õéûëâî»ãË»œåó:æS¦uie¬0v¢SL‘±$Î14HMbz¦ó±’»ÌCûÜõé°;»IPB¬œ »‘»¿¾qÝŒæ¡YÜa6öu$eÕ€h†HÌ0©¤ØPinG2êvƒÖ%yú”ø¦š¨I•„„î_¥Û¹3}ÒnÎìV•Nër$ãÄ%¡ÕˆLo Ii,B�� �IDATÇh°ÌñÕ#Hä’`¢Õ^ˆôìœæªÈâô(©ý8o~´§žÓÉIܪê öGæíùíÛ ×ÉIu¯8¶bJ?Pdž{¨{òÇxÖýÔå)(ùatòYÞÄÞ¹¸·‘§ïY“ïÈЊ‹ã:uÌ[&R~ÌÒã(î”f‡¯_˜åÄö!=äÁ2J: É(4éБlšb`ißG-ÒoU?ÔÍÜÌ&ú–4m°==MQ›]'T€t%£°ÛÄ»›,åÅÐ0Ôäz‰°¥›:R`’¶P ©SÉÈ‘f†‘!Ô V¸hØp&™@hú”éÀN+ 2¶! ušy­$L4ïõ'Í•ø¥W·[ú帨¾xAóíÍΊö.ê^Œ‚gñ”J^,‘ð€Æ!š¸™š»~ÁÊŒçUY_P@Ú@— Œðºù–—-³òƶÏð¢U‚’”ÍÐt»8ÊÝq[zf{F% ÚøÚ¤"ª…™b˜ ¨ÐUwÝa¶Ýzäô8Ü-²rc§Kò‰M–Fë¹ITP§è(g#Œ+­$Êé†lc¾ÞÄ÷ìøº^ÿò®]Ô¶û0~ƺ÷J¬Øõ÷ÂþwÞPŠÏÖ_J-{¼ÜÔ76Jç¸÷%¾Ëý§æ±ýü5ȧÞÉJJ„ƒ9D ÝÏ­œµX±6QÓÕGw¯¨†×ÌÏ÷‘J¼‘‹ï^Ïݽú\_Ì”hË¢~a]<6‚ËO]´R]ž›Î•xúDÞêÿìr§Íåf5 V”¼ªX¹*ä+Ïi8M§cƒW㟜¿Ã —AÊÏOcq}VÕ‹ÓöOϨ3Ýüø£(xÕvÏã… >2§»æõU1—åô[ó3aÕª±‰V”E¨U޶ KÚÄ•Ä;øÞN»âTÜù•›‘,×Ö„Ó~Vq}ç뙦!¨éÌšN‡^4]<Ø!‰¤A§Î¨MM­UnGR#«/Ÿ¦9söÔ;\@+µqÏ˵Ç[|îïjê’0F˜Sôâ‘׉ÔÕ£±ŠÉÒfϦl//ÁæD BŠá„ˆÕÖ[©l!ö-æðîÅæ{4V½—7—¿ë T–I?ÎÂxßå×ìüD '9ëíKáÔ±:™r’‹êà‹xþ‡äÉû‰u‡Cߊüðøà)¥Ù{Jö1‚Ô[(æhØé "êÃñÜęî3äéGÄØ™Þ÷L×£üxé?Ò„ÞqÜMû­IÑý»%9`ÔfœJÆ™QŽÄ3{Ï£r]l²Û[®ƒŒïQ„vìËÀizŒ|ÔªKÕÞéo õ™¬D£°·r-Á{³–›®L·ÀQ8³´Wнã€Á¶‡Ô•8dfȵMt±™¡gt±IêujB¨õ-C­„‘R[g&Fy3Ú2PZgÒ쀇ëæR›Æ3g½ûé„åîCšh}úƒoÎÝ ŸGíG¶sÙ¨+ ØðÈOõ³Îç¦Ê]cu5ö÷ìU¼b^2ÃKªÏà;ý¯§ôü•zíãY/v2Fèé—º+läUu ÑDÒÐ6í™!·=“ú;v Ét‘é[¹±#ú¢Lç�¾gÈ ^÷ÂüõV• q$5JêQNäí}èFÉ=W2ä%Ä62v;åLGe’(¦lt©%H½[Ó8ãtvuÿÜrˆƒEyÉSO˜}E=ŒÙÔäÚÍ˰­Ý}œ3´-çtó±¹2ºr†J=¨ÕËiô‹Öüš¼öê/Úó ´Tüj‡77O?ǯÐâq¹/IyEr~<—Hú³™pD¼/?¶½¼¼ÆŠùYë¿áÝïínkñýÕï|ó}Üœ¶ÍÃXôÆîÅzsÖž=Õœ=Õ™=Ž^£~z,¹ÌŸ…—.íœYåêÇî»DÏÄOýG«oÿi—ùzÛÑ~|ãÔŠzý€ Ÿ!©Qò¥¾2Ý,Ž‚åþ“t“t¦·½‰0 º…†Š†Swc÷]yÙdzN<˹ü¹q.·‚Ù#ê¨-˜^õçDmyIýeØÿ3j—S LA™H#5šéožøWß¿ñ­Ê•ÎîvˆzØû’ ì·iÒ^¼-w¬× #‡…m±£¼±C­ ÊAê"Ô£ÐDKŽxnMŠ0Éæ>7}ù÷A'Ø3Ÿ(Óì-ÐÛ cŠeÿد¤‡Ž‰okÈá™ã°Å\qòµï?:ï‡fš#u93ÕÌîj‹w؇.õýìs2héÖ78*ÉÎ3BÍÓòwÛÎq=Zqdfч}/Š÷f‹÷ñvßž}SöÿNNâGÔ« ßË`8LGK÷;ðèÇfûï[¿%¨Êb ¡S´€Ñ�üžÎ@€ÊI’̤#-V¨ÈÅcGG ÚëôbæëŒô¨ƒ"(E­G½rì”zú)÷B[`T¦—à•Q•c3ln6 ñÆ#YÞÊõ“é×úLɽ…iºIá5j g¬WãI™¢­W#´Eãu%ãHR8#:¨-üÖÎ÷Sýò|4pµœvã¨fv-äJ¼2ׂ<ÕµûšîE:Þ"9ݵŒºÁêGýS/L·=ðÆ7Ç#"çP %?3öª|ý�×ߦª‘9x]‰6×GßjV4˜ŽgìJ' Æ*7“ælK&Œë˜ ~ Iô¤ÒØÍ%9ͤ™Ù–XGBé¾C8Ò¡&[:®[BؤÈwúÓxTk1±£m úö ;Ðó k×ËNØŠgá©~¥ÇßÄÌ«ãŸO°f&tø¼TRXy~çÚõnÿtWuáê3ý,R~[{võ†Œù4n ß>usåwß<ò³Ÿ6bñzþÂÃ;Zt_µ=ý þÞá‚_©[o9î\ñb¾Þ¹ïξˆÎ_ V/îž}Ó¯[ÿùÍjüèMäWy-(;•æZÙqÑîySÿKôòÅUuþÊk¼|ÃëWª~óèüÓÓ_INEóÝ«ûó<ÿ¾3}uóñáñ˜¹ÔSîñÔº€ïâQ·ÌÔ[†Æ$‚"Ô£¡)6wQ%ÔmQúNÉLÿÓBš.ßK*LšG3ýoøNo|êç‘ ßØç–ö¹ùäGQã~ñ‹¿œ‰e§.†ô±#i¶‰<oÒsâÙŇÍš3óÁêüSY I·ûHêÄi&°ðýžA‰•_g qƆl,£±jì&¹I·4èe„ç­œb?@¾@‘/×÷*R‘ƒ³oùñûñYjIyÊM:ÐÈ=Š g{¿æ¼›W¶_ö+dš¿CQÝ´é¼-hoc«—×é»V§Ç°ó“E ÅÛÊ® =o—%úÆz8Íÿ(î 3ò“eËwÇæ'7€Ã ¶8nÄ}T ðÎjh-0¥!¬‹£ÊÆt_F7zG ˆ91yuO"Ÿ°dØ<îµò¦Øb#46× fIŽÞXþ1„\3¡-Jác$PÎÁÜxghp v^2ár;æ3#$êÓØwH<tˆj’-SÀvh’¼Ü鹄Ct1 À›0ˆ ‰E˜[’”ñZPBFC"PˆÓL+iû½¸ ,åT$Ô„‰VèjnLã+¦9mšÀ´MVŒÿÌx{¯ÿÔ¶OE¯ŸÃ7Õ´éŸÖÓß0sŒóÍSÓ ÔÓÆž:Ó~£4÷½DG]#Ï ~æm—PÙùkžŸ±Ï|L€ðÚU¿G- †-3^‚çËÔ3¤Xët’«$Ôý\™ÙpÐÍR¾LÂØF+ÀïéT:"iŠ,–9B"2“º=°±Ú*÷ w½‰† +çJ‰ñ¡Nj"¸Uðt=¦_2“zã1Éò³ó‰î³´8ük Ýœ -‚7—_Ϫ˜ù(<»R>¿D¸Š¼`šÐE]vZÔijçÆ9uõYàÍü ¢øY0¦%Þ4³1ãÝʵ½f!ܧŒ®X¾böPÊv¹û9§O­7Oð/£gOnð\dìÅk Žé¾·óÆGÍZOz>Ú,^¶o^½ /] ×þü*öúÒwá'•?ÍÏk˜+á·ñ.íÜ1çé*|W®wEÜF®¢ŽG›Ú×l"R�•"n$n&n±#¾ôw1Ûýê>Î+k;F±^9n{ë*êï`eíÔ+÷ô¢Xü/ò*“—^uØOw"G#”hGAPuGÒvû¿|uzœ ÿ´ñÉ›Æ åº *D‡½Šì§¶íte¥®¤ºCT¨Óš¢c¬@}jöt ›Œ$…/ÉM!]dLšÅK“>2Ò¼LrÈʃTœô­ N'C’œ4Ô )d°…ËØ x8ì §öM“–Vž£}+§“ŽŸzÓ£zÞô½Ä!süè|¢ˆaO]q<èì¯'9TlGÇFâ¤Éãÿ',:?Jø°ðqa÷q­ùÁ=ß'þ~/Rÿž…ÕòÉ#¨öóc÷Ž�K HF¦ÊI÷½YT†8:Íal¦£ÜxHöÏ&„Ð)ûsÛž�jÚ‹ÁXÔÚª=»ÐZ;þ»Šn”L}!b:¥šÛdòVè· äK–ŽAêb°ç –qê[˜t¢G’dÀ(7,3±0܃^ÙBy“ (¶tì“õ´G‘F:r¦B«.á´¬»ñµ™y)÷ˆär¼]•Ь¬à^yù<·ˆZt.~Ëy½nsú/ªæ5§Ÿê—O -5kÙài_üܯp¯b^î4¬˜K¿R5ö²ä¡ÒÀÞžh—í!‡Û!Ô¦“é/†ŒH,DÎxI2ÐÅþWHåX‰‚ÄíÁƒJ’3ò:qûàž$°±4>q™QCä2R»FíA”èŒk°ô•w–Xq‡Oû°Zój.`²~/cmÄl²ã{ëK×124ºsi.´øÉŸEWÕÏ•lq¡e_?Ô¯îÌOûSÎ3“1íòªâ¹dÕñøY(ùϨÒ5"î®7Yé·„õD|%ܼÓ³]çׂx·]®ÍåL´¯2ÔiƒF·)§}º‚ù]Û|g¸ük^†zÚ*åB¸s\{]©ËýŬ}æÒ¥àüËæÉóW/ç‹kÏþdzz—׈šJx´HJ9´N"'jqÝîÞW*´6PQcéh?5לú¾gåD?+×ÚÝZGÒT’hUù…À# J¼Ê CAí¶%û¸1RKaƪM8S®cÿ\EóÎÕŸ<y>}õùÊ‹ò멌业}¦‚…p ƒÎ˜çX³žz<¥oeûF{VÏ�¨++5ΨëJÂ…®x9^oùZTÖëtPnçq…I¡èiå€2ÄKo%+M:ÐÛP夙)Ð{˜íd@±Eê÷–ÀÅþQýÀª§Ø'ö¼ëb”¿µìæPVØ[RN!—,Ç·gßô˜ùÒìÛé· ÷q|øGºe|�¬þ:tmÇû?ᙑ›‰¥'Åé‡o9ÚÐàä1%9¤à(þ`—:2ˆ™w†6`/X<ß;,=S—$è\ƒÞ†RZÌÆí!# B3„¬L2æl “ŒÑÐdIM:³¬j`&­hLwíx÷ýý·¦z¸n…’T#a×¼QÄ¢©‘lÃ6:P¦‹aHáÀ‘ I Ý$M41 ’È>áÌr¹”ÀZNZcÑ£-­jCÛ÷{l7;j¨ûñN#Œ¸Ï=‹™9SëæIÜ»loW¥ìÄøY,ü¥Ñ¡½b"LçŒi½ŽvÏ©Éju†õSìÚËW;³óZbƒ jÜŒ¯ž ¬ûÁ,ÓâWúqR}O¿/%0ÆØ¡‰r½ µ 2¾ÀŒœ‘˜ÄåÌ†Ô Ô(߆&\Ò|f DËMÑ&ÉÀŒB¬4…4 ŒÏa”£È [Ç-45©T½-PCÜrÚÖàÛVÆJÄMû§£§ØÆSã=T^ιÌ2{@“S5Ú{ðÏé§ü£ëð+Ä}ë|üì¡Z\)7ÕãGbZdz9)/OéH±zVðLÈÀ¿öf2íÞº«ÄßTMÏ0ï×Äzðwq3¯æ».À[(o frìýü{pžÝÚZO«ú<ìË'êügÑY/וý3?Q‹ß‰‡ÌÏÿ¤óâ ÿül¾`ü›ïvÙµ|샀ACè yìeŸ¶º÷Wv:Ó*‹¯™tƒZmL‚g ,Õ‚™G…fÃ)… ¾‹¥»,›ªj‚µ¯l÷º]\‘|*+IÔÓVŒÅr [ë¨AÌ”»Ju>ú—xâþ÷S»/ÏÀùîg¢‘mÕÿTu¢­|÷â9ýÓWU»s)ú9½5ª=½wþª:ë‰Ô8“fŠ™mÏãóù¹§ëUêv ®¤Q=¶¥fbp$ÎŽrF`%ºÈÙ–ifF¨eбÎ9ýM ±Ü-ëe$ðð{à˜08’¢SäoCq´1U/ÞîÞÓ}õ·Œ$ß+8K£޶„ôƒÕ¬86O6ÿ`Zó Þà‡¯-Í͇KéÑT×ʼnFù1ÙAöîÆæˆ”ãð ï@*r|t:03ÉŽ ócÞM'¼Ô·DãüÑ;ú‘lÿüžQí¯ St1 r�ª^Þoï_m¶LŠˆ2S¸ïøBjï¨jýE¨ÓŠRH­€:¾µ‚è0íjØ©jF¡Ùvl„%y¹C†ØÛ„êÔíM¯Ûò²ÀŒ pfcH*(ÜØfi%P™¹ »=¸nR›$°=¦ã×í�ç±=£¼ª®›µA‡»9Åý b×Ú‰„×âñË&|L딪ZzÖRþ‡õþkѽÈãyùÅéÙŒ*èìUû#{cGoü+K÷íFÉo—åø«8pñ5Æî[·=Ñ :]I¼ä—’ñ-DC½îö((e[P"s]HZÏa‚ÜX¹·¢µ›f™-pöˆªšB¶!‘jÛÍQ²ôHwFìªêÈnÞA’NËî@{l’Øic,0P¤Yû%ÝÏXÃü 3ër:‰\¢“Ý]'ñ9ÁyfßÅs§ÛÐ¸¾.^†üf~G[áθoÚkr…¯¯so¤qQåb1°³÷ÐD£ÆÁ;Ts'ÜÌM„hhcA¬¦O¿_—Âq¡w3¸æ‘}ó:à —çôeÔ|]ñ{ó mûÝ£WöÁŸ.Æ®Š|¨Ý¦ÆÑ0+JŸ¨ŽdœÜܘÃJFÜ(ù9’ÛŽš±ôã‰ê bÖ°ž_^mBÆ®}ÎÕöîJŸy4c8§AÛ¤¨ -„!xlå¬z¾|sóÿ¨nö?âì¯wæÏ§+‘_Lí…³s~þÑ5~êÙlüäWò÷/^ÎM7ù’gž7W/'Ó;…CIÈ­õð1óB~bdϧRŒdÅ–L4Žhÿ—+ ‘Gå ’b`‹\'y\ Kj[ ÒL.‡zO“[äàHò=cͽR›ëÃçÎå‘qOˆ’eïêsÓ܇飱9Eþî)=É©8É3ctBõ×'“ƒòÛ¢Yµ>Î)-Þ4ü‡<ºÄðr$c'×3ׇ×Gïæ?,¦;<%æ8ëõýÆ„fߍyDÏ3±E¦&AÛ¤Ї[˯TN")Ü~8Ð#p[‡–ÆËDÒL ¨rD°!Ùž˜ †Ü·ËhWl屑›Q¨ÏÈ®k¦àH23ÊRW¢ŒÀûX:n…fäa ÙBn2EÉVlk¢°¬|¬Di}¬@HSMX õAÉ$õ«ˆïÌi©Ÿ­šöC5«­ÿLu¿³«ŸDü‰ÿ'/¯½¹ùì,JV¶ôG•í'v6ãj¤åOéN5³3Uð?hæÊ·ãä>ËÔß0Äo·¤@äÚf¥"¶ùNš­C£ZäeÆcP›ÆnÁRí!5¶sãÑBâ’PµU`ÑJ’ ö¼O–XŸâkè;ÑÒ“¥+ B©ÀÚd£“¤ŽÛáÎ-Ö Ìš¿F#ËÛŠ ò€[w’¤ÍöÔH§×iaêû)›[²ån׌rD¦ùÊø™’5câHÒ‘LWï^[ìžxð†Ÿ.ôìb¹xÉ|7!Wî"•‚{Râ›Èu*;‹”—‚{t#æ>hìØ³ÖUÓ©µ’í¤ ¤¢¡©-¡–€7‹.3ækbuzñò_¶Ä›Å ÷rqþÔœªþ~zU”kØy ЈZVÖ)jKÏ®UM<•´’t]¹ëb`M˜Y½d¾™êºVÜ•-Ú‹Ù¬Û Ú»Mu#À372òÎÛÚ‚êßÚ0£\#M2€¯Ôíû4=ü$–Ÿ–â\ÌkÓAý¤éþ³šÏŸµo=ä—¹k]è´^ÏÏy÷Ø1òÚO݋߈ïÖ+±CàIⵯÌlE÷.P7¥xbïÍuêvpëÛ²¬±ÂÀì÷\‚²’1Ž´gHÄ#HrCí ÕÒLi¹Ø[}ŠUÈØÛJe{¦ýÅ€#Gû-Ø\î…ŽX\¤ÙCÖCC¦Ù—µþ¿ŠØ#ÛªÏꋪÁþãyÑïa ~ˆE{ØN5;ê‚wÈ 59‰ uR›ÑK Á{¥‡Ãéá £ãÍùè[`sFù ë€^–¢ Ö‹‰­†$¹.røvÏd|ˆ5Âô—ß Ñ2n t2`œ›h‹Q¨-lä¡xÇ(1Ef¶½cÖo¢¼I)Õ•dcH!u² ÎÈžîÎM"Ë¥dÆJ60ªc+bé¸Õã—h;€¼´Ó`Ô¶€2½NEÜß«Ÿ‰wº2óå¨mG¡IV;…mš‹Ñ ‚ð…ÝíªWO×ßÌãðwã—¯iN•]eA¹ÀÀ+f+Í&xfÝÓ›<Âÿ_ÜšéÊÅö>Û!]4×ñ›†‘y)Є¦ŸÇ"'e}D™JlN%ãf6¢j¡Éôh°´ÝÖIˆ‡$T6£¨c•i+5™a`F9J– جŒ2¦ª˜Äéc7¹-)ØÍ@©š¤Qi¾3Ú2Û©3£Ì¸Nu».ÓZ݃۔ÛX<έ·›ÊÉòg¹=3§ÉÌô¾YÜǂܲ|ªÓ¡.–™=]ëq=ú²ì°³Û6ò»ù£o•kèœb˜ú¥à9Øñu¹ëíš¿)?¹Wý¥®'Ñ­ ²÷Õš¯k‰Ú€N#`)ñµntc¢]ŽcLÜ`‘øÀ¸+¥—ê‹)úm7ç̵3þùìó'g¯¼~ý“W¯[Qä”ý ¦Óo&,Víi*» òVI•6ú±ÊHjå:šhÕ.»oÊ9b £0³lxH¥îcïï6ìÎ瞵ƻkAËqyEQ{q%5a<Þ(‹-ŒŒ†l߇ÐV%ĵdýëÒ?`ú þ/´.½á§§Zÿ÷•™Ÿ»/wYÜzÒØ¹µW.‹7§ìÓ ê¢jŸ6±Ê™ÎuðÐüŸ¿0Tç•;·Yÿ:4Žtˆ˜dŸlšdÆRú,ŽdŒ]äñòº¡7ö‰õË]Ü·æá9@'“;j¡ Åæ[¥ÂahÁ^9²ÉM‘é½ÿuDÝõn5e'8I¿/ê9}O>det¢ÿ9™’”ýï»·S2'ˆ)>8@VH¼ûÇ[Y‘Ÿå¿•J8¡0‡¶~ïàþI~Œ{Ô|)ÍH²·/a¹ULöÙ){j‰lÏKkÙöÉå%åf$— (cݲ¯hjˆ_CŠ-z£6É&*§¨¡Ir“€Í5Y¬ Bߘh¦ZéBác)ËT˜Ñ d@ñ•n9vÛý¢‰“/°y;Ó}ʦ·S8îmÂH âhNµ¥¦Û@ŽZw"v\ˆ…($Y%f,uÇѽ¯e ‹ït÷4Ô¼ž#ø í+ºnéþÜ>ûxgR™{÷¿xcä1mTÓ¢ÝD^Ò~Jç…Bàýæoõìn¹ûf©‹Mú ôžÖ�;eœëq™õ9‰×SaFäq&ÛI)õ8`*Ì’•´‘™C ]Sø8®rÖ€Nrma‘D/±™5Éúkwt:äVcÒ¬b€ÚŠ‘ñÈ‹"[Oj<bK'÷µ#¾M#–×Õ4s©{—ùOãZ}Rƒ”jµ¶d.(\©¤fX£¶Sú‚.ö–°SüÚL7² dL ç·úu…çªÝóöà†Xûy¿åÊæ›ˆ)“°5šžÊµ®‹½°ÛÓkUîªòÕâ3Óqe«§pȾ‹ul<ŒÇ‰ý=ŸåÏÇ¢óýG/_žº8?¾þ}À‹+Ï R6@Ërv¡_^QÜW•C ìmiÆ’:öß‹í– @Líôí?õtŽŠ¨¢‹CÐ3i‹~›YðЫ�·ð„nòÔÒ9Ó-¤¹eSèÈG ð·j­PÒ#º©.tÌÅÜ“S7ýéúñ O»;õ¨Å"øLÞ¸qQÕ¯ž«f & ãÂBbƵf„ âçbYW Ì6ûÛ2&Äç=5 u$U1Ò©´6ÇcR ›Felç04U(-eñÖôt/ø3=Æ.-€­ý#ãñÊsœiy¤^-ú™N‹æŽÖåâPÉJN~BóÎ?ôÎê¤@„J+Ãå¢IŸhDô£ÿê Åû°ÙÉ ¯wøEï ƒû�Ñê0sëÀɶ8œµ¿k³JöÖ±}§·¿×Ú×»eo-G{ÜYÃ’šö®ä­´}y 6£’ARdΙ¶ÎS u„¾µ…¥T™Á!¾"•Œ†›™"Ô`lÄž¶Ë¬e$#D®•ä^ˆÅ´á‹‰V¸:þz“d¯HWØîéÛ.Žûn c/ˆRÃ"*º¦ÿ•‰ši‚UúDÍœ¼èð v¢Žª‹r[jÕbÚ³³ë;8Óï¯MóóÇb&.H;¢ÆE€G(õ»›ÛDõ©J´âŸ¶¬ô¾÷€³mûg¹pN‹û7;@ó 8£†f¼eúYœ Œ–é`rm3s–X‹ÅŒ æ2ÞÈa¦ÈI­¶ôT›»�� �IDATvnz”i2ì}Öhõ¥N2¾X~yd™J#ö>2S€„™3#iZ=wY2rw¶½åZma7M2ÀÊõs;ÓÉа¥70XišÌTh$>PbºÓüi4>·ó÷•-œæS ; Õ-A¿g§×¹³=°ÎX+4‹\Ôì.àU»›Æ»êVÁþksmQ-ý>J…>yÆîãºGÐãF FDÓ >ß ×Ö‚‹ÎZ<ZHmg´¿Ô Z?·A÷×îÞ»˜ÁöÕRm©]aÆ‚VKý‰¿?{6øÇÓzúÛGÏþ­q¸|¡Ý‘f•øòqæ‚á¡UaÜŸC­#Ø–ØžN&&­õXÓZȳ!•š®·ç¤SX‰S7Tã må<AŽ—©$ËÎóf±­M‘iµEŠa°:Éãºuì;iÚ¦êÎo×½½[ßÅ̶[3@8"ÜËï!|ô:k¼IAy³§<hI9íàzºƒñ_ÝôÒÜ^”­\lýN…d²³ÏyÓä:A L TZÓĦ¤9À–ß®_²£RŒFèPxÐ0ÔA3ȦR5ŸxŒNÒI³“ÓnŽÄØäG ÕýZg8¤­{K<ÍN*úƒju‘Ÿà^¼«“ø1ºè³h:Æç=ò:óî_ð1æîá¶yX)ýÖx#?Ð0/Ÿ|¿‡ õá®{°%Ü‹ŠE“íÑU°£ä-:­÷\ —1⃒Ž@AŠVC£Ð`¢!3£ºL³¸›k‘±15ÛÄ#ãæþf,7ž%?UOaÛáA´Kå Bí:F!6Ð]aéb`¾p†Qåh;ÞÅ}Iã ÄWA G@G{¯Ó©f¦åÕØ;Õ~A³r‡P3³–â wóÖ¯Z–©V-[yÄCc! jÂþxÅ̤Þxt—µ’ zùÜî. g®=£ýÊ^à §¼\];ýÓSêÅjüZò¨…ý!~V™{=¦Ãr©!m:E·G¹öÂ.,¦/Q9cL506$ µ¥Üî1’l7Œ®|¬rCˆÝ4z4Xf1-.õ5£Ü$#¶sFy¹üáÝFo€ÊËæ–c#Ó‰Óub¿w$r¼á°¶&QlÁ¾bŒ­jØÔdF9] écºŽqb½Xç¿Â¿ %èíκÅnKë&Q"ó¦’¦¢¤ês‰ÅWa0w}ÜZ!ºÛXµ²?šïðܵ­?göbÜœ¶×ZâöÃõ”H6ÐtÜeo;Qta¡d]Þ@]jqᕽ¾Öa"oî¬>$xÔ}ÕtiEó‹ËÐ é<°¡ì~~5ú/¨ÿß?ó<yôìáø…·Ÿxÿ²é°ê.1?OŸy}^ôW¯ʲ¹ŽD7K݆3j¡¾-I%‰´8üÝç;¡D0o¸íŒØ,ýW¥¨[Hˆ¢É¬†í’�UUñ.•õ¤Ðb=E¨«Ü,UM ¦™aȆ(7=««3¡š»mvùlÇjŠg²ëëÏý}ÁZ+Z\ðç¿Ì(ÆEÂ)ˆ@ÛM’;'yPN»JÜG´µ¸oÉJá n=8EµDžRÉ(ÌÆ–3".$ÅÒ²w@*)2sP—T~Ô1!c4x+aÛo$ú@‰u@’Lò}@8{×O;Ùƒ-OÈ·/Žö˜w H'øpnöÕÄúm–‡ò /TeN3Ò÷Pr–úåã&I„¾á}†Å`?xyð#dûÛ¤4ûáCXMþA„ç½[9F˜do2 GËO:{ëºu qX²ÜØiEfÈušíÃu…IºšŦ!ßó;˜Jê=\¾×ä¶%¸Á55äZ@mâ·ŒôÜ’zDÉ„DÆ#õf¹ÈJ{š #Œ•:’%Îv„Þ]<ݯ˦g½S ök–º-vU­žî$íêë™Ú%Æ—`•Dº¨-×gZƣħV.”_±|§é\Ônüîú+¶°]B¾,/‹d.=ü3ðÔh› 0 µ•k˜mt•m™jS«¯ŒýR«¼Lˆ¿–̸-“ÔÜîi7)ãÊ"$õŒq¾1jÞT œNöiãK¾ù’¾Um¡˜°LõI{I®Tn’ž*’8îo“3åš ?„A™äv”‘Œ4 #Œ† iitß›[Rå ë” ¢À¯;alˆús?¦«ÜœOñ]'ød÷ÖbíëÅt:·.µõ›œ1þøV!‘XqY•¥Óϵà¯|ô†àr΃UÁ‹ CÓšwœ˜÷ç+¬”Ê;ñ¼©ÎÖ<û+>oÔ×+"zUuõç—Â'¹Oý{‡ï"gwO]Ù}ºÐ«ìˆKþôEÁóðÙÏNßœ’î“ ñfÿÛÀ{çü¬½ß‹Yšçý¡lÉá<¶lÏ9[¶Ú3Û®wRtãä¥j_j·g)ÞƒaIÐMA@\æíAñ7ñ7„8·yP7 bÁà—‚bzæmv]³¤™EI—›ˆmìÚs¦l¹Ž–ìæ½ò—îîíwóÂ8åp*3Rzžó<ß_"¶i[±c‹¯,h[í}%·„üÿ˜¾o¿°ÍDmn‹ãCl£ÔfÜïVó…ð?órß¶"òMJÝô‰Õj¤lG›  R—#cKb8Ð{¡ ÐWz“§À¬®%[¨ý¢Ïá{Á'×寯ù‹oŸþæu-)'Žbµ³™½q4„Rn[W)ait]H”ƒ ™swõÈ*:TB[}ƒÝo`S§+ßâÝ ;Ûé‰÷~‘¯‰I«ø‡$£Ü%Ù9i½w,Sàh]q„â~8wóè4|¶oô{¾­g½Sn¤g•Á~zº”kLô„[Ä{_ùýŒë¿\ßpv->ŒŒþ´ò 8ü1N’ÃàÝô‰â=·Œ"Š9ÓÀãD(ƒ•|á°£î­_æh@IƧµ’ܬeÉë>gRLzBç²7®;Ò|EѬ½Wµ¦F§Žb¬Kô!Ó×Ô‚»#’1inÚJjLÔ ©n5Ê U8ÄM°`lƒZÁ�]8Vê Ãx(ôÜ“:pÐp;<жo÷>añ‰âºš‰ˆn´õdÂÕm.3“1‘H«ÂtªíoÏ’Šïà|*ê€æ«xú„î/q­ægu¹ÜzîûäBß[ÀÕ”¸™Vüwž=Ñþ9,õg96'YE^oV^š=©{’Ô;zkŒýJvAÆÅm3÷Ý®.ÃÃØÐPdï¹XŒ™Á^à^A‚{cÊlÕM)ÀÃ;&IŒ•koœC¶JF2dºHâ4gŠìp‚̨sƒ«lƒ¶9$0†]æ¨Qœ: Æ¡î93pÐFI£So“z—ŸÜÑ,ÚZø¶ÞÎDØeéÙêt/|þÍÇ‹Ë×Â~«$[¢¿»¬øQ ¯¸m¥W¤…®ëÐI=]¸ÈǃÿÔãÁ÷ñt;âáÒûÙt1Ã]ß÷MºXþ/±êì9ÉÅ zÒÂË|ó„-ëƒÅRØt^Á?Ä«•[˜7ÁçÎÑYþãÛku»”¯=ÏçÍÛ‹ü¶Ãöå÷böSÏ?½./9‰ C‘x“böz¢óùCZ¡{A%ú‚ýúq·üÂbaî!vGE·jŸ¸>@XœTuÏ÷7µÇôFlÔ‘Ó”1’aKêÂas°—h$¦¾z„¯Þ 8`æà—ÒËíàÙyÇüÍ÷o¯‡¿Q=pì}jÔˆ=aŠ\Õ£í½Qm[ÔÈÚF[i ¯ËM3$¡±c\hJt‰ARJS˜ÂÛý &¦)v«Ôo«Ü”ãjeѺ~wKM¦“UB{NÒˉxŸìdŒ>&åç§¢xì;ÖS–Ú§œÜÒã‚fŠ`ï0kN=rªW}ÐÃâ¤ÐQ@Å™'éôpåþ!(âO÷†³ÓJOÈ ŠüÏ[Ce§£”²SÀÃé¤ÖµÛÉ;¬€÷猓Å}e†QÎ%wO(àÈ¢&ÑQ¿2…-2Íh=F#ÒñaBQ™VP´Ê¬D™¹‡NG$#Ê*Í ™IÝj8YÛ›4p˜ísÒiF-yÛ§2–;qꌿ­€Ò‘‚è»›I¤3Hö<Áhro“Hjª„bÓD ê'š¥=¥÷Ì·KS´[›—ÌàµF d0u‚zaÄ^|ÊPªpY+‰]£¼šÿhúñnÝ™oHñ²EÅøAÓ5sëçvë­éý"æ‹ÈÐt&ÿÜh/#¢Ðˆ1ƒ6¦¯¥`¶¾Ïf>Båu÷?_(ÉÙÓµüVzgTèhd€Ô1 ›ãs’†äPîG«Û¨SŒÚ%{ÐŽ)r­Ü*‹qµÙÃcXEÌçÜËLÞÊ'JfE[´k—f£`o× ŒÅ”¡cS:Tƒu¡º±~õ{ÊRÏ6ÅÁò¨ ¿=»jýåÿò憤ƒoÌ_?Z<î¶o<)ºóùóögý‚žáBqcûÑ0pMúK“¶v( ¯÷#„ëÃqnR4ô”íà)ÂÝy¢©f^ýšø·öó×p^nË ºÞòòrôyÏ.æB`ç‹Ú?SÍG<ý•ñ.n¯Fºfö8ê-šöœšÿ~úä©?÷ºwñÇyøÃ­Oßlw\Ð]Îyöæà)/ºŠ¥ÿûͨˆ>óµt<‡á²ú²‹_øí/φÍV€ãò­«í$ŸíâØnñO·é¾°})¢ƒ™¢fW£ë/ñ›àHGUÙ¬Rl+¤!c8Œ*•V\i+äM¥n“àSH¸÷ùÙ9ÿ/îÁ{ŠfÑ·Ù„ï”Ü55j@¬ÆÔc6F”¨ 5Òp § 4 ŒTâ i‰ZWÞ‡:Y‰ر8“dX«¼Zœ"[˘‹w‹YC¸³’޶ðå;u,?^ø¨üTÄý‘ÏRq,v#¿S6õ‰rgÞ[­ËŽ}§”Ãæ½¯3;ó‚ÃÊ™üEÚ·ÓÔ¨$BËÏÔ'çê.櫚‹ìÝgLOw‘âÁQF §dîëÿ²JÏYeì¬n½Êw‚éQœÓš'`îAáŽ Ææ(ª„;äÆèinVÞ/å(^¡¤»ê;­k2þ^f,Ü[±#R{‡[5¹E|Oj+)`è*çLé4m•nª{!SI9Âhw멃Ê Ð8¼ÓŒóŠn%ˆ·¢I÷º•×ÔV4{q‰î¥û.¸ÃE%zñg®ÐíÜßSœÿ›¨µæ†â—qÐaæ·Î_Sî£û×;îÚFÀr"ÖÞº¬¬Ðožªù5½ÿâ_Ô´Vל~Ñño%â Ä&Œ#ïp;ØYå<PµQ†ÏI2p{ú¦Û§÷›vf”œ»¾P·í^kê\©\—¡)¼îfØÂã“”ÈIs¬c-óÿÞæcŽ´’$R§»¤è$7ôàðEåvŸš¹Äî‘‹ñz­LRØÑÊkéãm1"Ôi襈›: kåŒÊk{0ÁyÑL¤SË-qáió›;þÉ~ê%Dןˆv¾/ÞÞ¹øSÛ\£}ÒÛ ”„ËßµA·ßÆÓZ’î0Hô¢éï .<4‘IJ½²‰Ý’•ŠÛfÿ†YŠXnZnÎ_ý¦½ùøî·nû l¼àù\uÙn„ò­níïkÿbËÊJÞþÙv·Ñ󳫱{nP³ïãÙ“Å«Kþ-OŸ0q¡ˆÁÏÄBÙe'æE0Xº_œSmµ¡¾·!öÚä@ýJØ{7ÔŒ(¼ùëçç~+‚ϸ!e{kk1Ço®†31X´µeÛÃ@ZñÌ?í ƒ0ÅnLX•®*B ºØ5…3{b0l ÕõA¯dgY¨BÆ¥¤pUÇëg²Û‹äï'¢“×>Œ§‚¸•‡r”›:8 Ù5I^ ûf�XÞVªѵ…Ó6§pÆîÆÅ×àÔÚ%;«Ê•ERä*ÅØ,^½µÕ‰*|j£’ëÕ‘ådÒC:^STއƒãLûjuåj ]¬®ÌN±]WîTJOeSë3ê8gAÖÇ…T¿_åËwv3Ù’º˜-ÞÿÌÞ OÙï-¹²ÓŠâw‚²cl$=C1¨ß›bÌÉ»srn(Ž€ Ž#"NUÿµ;®áLqC~ ©^}3{Ù1´p,”G¹&7úîèð06:ÍHÖ|‚’z¸òóÈMÂáÔÙ°•k‰QÙê(aLs÷ðUÕ›a1{¹¶íd*r(ªÂÅɪy܈ËÖºÆDNK°9AC:—Q#H¨zÓYˆDÕ¢®çDÁ9qñ­èüaй8ݼ0i;�ÁÇQÉÅëwüSûÈmÏ6T°AøÚ´—¢PÌÞœ‹¥àQ—”8ÿÜ?|Û{zÑF,s¶~ªz‚/zömh.¿”¦jë -[n;‘$F±A\çø\Û °SPÑfæÑMâíÃÚΠ!’ØÌpC«Quoå¾·ªÚ!I Tþðdà3|¦ŸÏhv!'”#öSÀ^¦S2îfë“W²Gßi@ŒZËœ±k‡¶# ô½ÜXÇt´â°ëÚCcÛ3…à;¬Ô|>Ø k=‰p¨ÿ,¿¨¿éÙÍ*lE{§¿Ñ;ßÛ–½è‡—¼q^üÄ’/Np`oòã8”‹Ù¥ÞO1ÛV]Íã)Ÿ‚€¾QPæË›,c?ÓÑ3= ªn«Õ®iƒ/¢á¯ýæ´q8pxÄ'ûÅì‹(ŒÝ‚¶;ùåÒs÷ ÿ½–8”• Z÷“è.¹ø–À‰ùÂ<÷ÝýÏ ºÖqWž¯/…7oHLZêz“2ôÓ‡LÓß Z=u=ù¸q/»Óèé¢È ÿêåÒ]jßbÃL»Êµ âa£8lOã±=l³3H™(�5l¦¢ð¤Ì“¦š&[8¡Zc±‘·û­¸ëfn¶_ƒ=ð5^mFø ­U Ɔ$B Ï^fË9ÓÏo›>±Å×($©ŒÒ@§椛V•+09¶«}†Ó©Œ‹L³K1>¦®¤ÅøÈÚà°Rz‡ûÌâ¨òãíô þO\œX¥£ã- 'òŸW×¼!œœÎÄ'Êü BQzm=e qÔ²3¤pEvŠ#šž¢eþÿóÌ8múaÞEÀOM(š³ÌËÃâ~¶”á¸[¼— ”ŸH�ý'„ã™á8BŸ9w‘â¬ôéá Eô‘åÆÊÏ´ÊaW“ åH§GCâJF¿‹r†å*Ø9ãÞ‘¾/Ó_Â]t2fo¤StV2]‚ÍIa~øÓ%·(!µø4޲ª€áÉÄzÍ&Hãrqe^IQq€ìÅv‡Ç}͆Ô¸h‹ëÇÏ·Ÿ?«ýã¶ùWå>¢wQp{¿Û èÈç/Œ¼ ú7¿½uÑŠ·1¨^'à’å'³|Ó†çþA{KÊ7_ð{<A>Á_‚×ñ¼‰ßn0 Ø8W©zf_RËÆXGíH³õ´Á³mf–¦^C;¡NµT«$íä? ngò÷ì»Cq�ã8•WiN’±º±ž"do§²PK®¤æù*ÕѤèo0%f…ñ€óÉjvŒ²õAOå(‰[EÀ—²—‘:Ú8ôÀûr: ðŸHºòÛf[<{ê:“Hîºñƒlšî˜Ù“ù¿›WÍ|›ù}w têEcîÊ©|B§ñ)6ÓIŸÂ:¶ú¦ß1Ýž¾å"ßÀL[‰B}s›b^mŠ Xϩ›ºiM0Ö²‹ÜÄ/5 ëZ3ˆ~õ šPÕ-vdh  ü¢Þ›ÅíΈ°rçàg¶ÿ3ÚKõ¹ƒ7/ë®ôÞÅ.@6r!\Ç‹}îºo~Zº ûú6ËAÄ`mZ%‰6mØóî?ÿë ~ƒ-èÎïø¥ó?z!fÑoˆf6 à *�¯£ÈЇ1Ψñ´ ¶R!…é•»ÏhSî ¼ô¤N ¥Âû=g-}¡x+\â·nD+žˆÈtêA2ÝQ‘Ó>WV*TæzÿšaN„L%õ=ªbdt²ì’®ÞG™) p¤Tis˜.ÎÚ^bõi:><ÈÅë}æ‰"›p²¯Üê¬^'Í­Õ¸ë¢oŽÖàG©>ÅYèñÚàh|†uR’½[BÓ|í6]œ>‘ŸT¼W‡OJ1Ëü…~JgËù»fßé;óN‡LNRnÏpÖ3ï )ŠÓ)KééeYt<RYk˜#ŒèÈýb='r|:(ÎPju⯣{ ÒЬ'Ðd|†ç0¦í‘‘äˆu`ˆvÒ@Å®.�I‘ƒ`˜SfD¡IÐ[!ÖqÐõˆtw2øšVVrÉTƦvôr«„cݲ3´º7Ò à+™k{Èxêm+«é¢âküƤñ3ä¹/$°œ´¸½½`ÛKÛ/{AýlÑN;=¸ò:j¯YÞ.8¯Äëo›—–݃N´|«æ?Õ<ª/oDà“;f*‘3ÃÒøÇÏè:fmübÎM§¶¨^76ˆ•ZrL4F…»$9öÀÐRô=aöF±Ú¡D+×9jL1V.“Ýíf¥Hjôz–Q É⽌]g¸C5UXå¨E¾¾“«Ð®2ãËÛ4¡Žšh²m•Qæz 2•&ÉHFˆ%)ª´! *¤)!ÙÑI»ÄmF‘‚îçö\ˆK7« ­…ë!TwV1ÖÅ8²Þ—>Ád*§A¸=x ©¿q´Ä”µÿÊ‹ït”S<DIêL¡îÌÔE-àéícMµXÇ¢)øº–† íò1rGOû|ü¶K_UóVû@ Ø9ߦÞâc•ëzdh\r@-Á)é6qp×ðè3¬¿‰zû‡ÖoD8+De[þwÚ¦~ üy>kƒÙòñìã·bþfz]I¤h#0" ®¡ÜU^½Â}níÆ|VoïËʹ¨žW|×ßÙ†Ž{­¬¥eD䨩҄4#uZ¸•ò«Ÿ46u*M¬•wÊ]Ê‘QOÿîñ½Ön9[C$jE5•8ÞÑ„ý‹ß_ïˉةê]¾Ž­\Ô›$Ä a[kxÍ ²þáB’J¦.¦„n¥ª5+44»HCÈc @ W¯1‰CÎ0_ ›|)VKH5>>¯ÞÑéñjD§9¯÷Ø«B?~Ç9BŸd:¥‡¤˜54›½'ó€1Noàê•=ܧg&&œ<¬Xó\¼£‹ÎCŠÆÿ‹ºèôòµâ¬Îq"õâÔ­x_¬ñn#ѼÛÓLšŸšWÞá³Áü”WGy!dúȧïh$<Oœ2.·ÆC™“d:iÐE®“|ÍÐ]ëG$#†¹öh2ü.%àH„&G5&Å®R’b‡=˜!š1s´ï™¢O?'Úã›Þö•…îuí•Nu æ¡¶ž@@`@Ó°¿K™M¢ÐN1<ćfêŒ"ò}uãϘp©^Ôú1¯+×kô~GHë5½ÿ1ùí|¿{iÞ ç—êÍ¥ ·,–ÓGOyvmÞW[³[Ô‹sôz‘ïGÝÿáÿæGÂõå«¶ÝC-}=|—™Äyš¸~|׉%„‘#R4 À7 õˆdvªR‚ÔÌê"ã.z6ÇÞÆ¶&ݬ¤ÓÊY $ùa JN:FQŽdÌpŒÌŒ¢îfXâý]À$9iH1beU’ŽÈ)g$94U*»Ú.އG‘¨"§Ì©™02–¸È¸[Z5Ò8³—W{þ[$ày­dç)/ÂÙK_t­$ nì=:ýøó>[ýl(Dyº¾¢¡U3 ïô•Ý8¦Þ¬@«Ó1ʳü„GÝz:3õ÷•’ØP'ÆŽmá*ÙW§·Æ•/õ"0ÝÒ 0?„Q0›ÌþoKƒ¸j|Wù…†/î­ò“oWä:bSã†ñÉ=‰+u<˜}?þçøwêé÷õ~ƒox¾ù¤’2RÞâ}ÏÅó›¼=÷Àõ~ûª>Î7ýVNY»—ôD¿KÓy!{K5°^z”³ô‚+rØØ 5þŽ5žÔ5ŠÉ)v3Üœ€BîEfË\GÎà+›GH¬XV™¢÷¥J]ä’ ™:¬p2TÒÏŸ÷ß,$ä6êÝŸÝ0‘dnÓ5%&Öé8Ã2º[c7'ê-…ˆ"iè¢ÆBXÅmØ!åèÏ£ÕB¼./Žt´¢ŸœÚ…¤@H:&qǧû g޵½«“û¡îaeÞ\Œ…·Ù=[^pº¦™³eÅÙ)¡Xú¡’{ô#ä§¼ùÞ÷Ò(N?oqRôðíÁÕ7œ$ÏþŽíI§?ù‘Sf&Y[™ÿY ×ä_‹ãÉC¿¯{Xé“?BpzO“qÒc3>ÖÖ¡2ìÑã92c QÎU­IGzoL=B‘+K%¨å*âœ]C„éõY\fú˜Èëž„ë“ùO^.c7Ÿ ñe# R÷X„LwŒÊIBðQéj‹fÕNB‚榻uG/¥ÀùïŸlË¥i—[õåý-ôÌ)?k[w½³ýêßL¸xýâ«G¼áÍyÁ«º'Ôìwt7lçe´ÜèͯÍoþt/LgçÔ•ÄS~_ AÓpKêG)q]ú«ù§qÝ€483¬ÎŒîè2¯dOÒ• ¡4åH36v¤#ð¹Y¹é•e%Z;ôºˆãÇʯ53ê1jJ‘“f”»Ø•a™ ÆõÝåøð$á´ ª³x3ŤŸê¿wUãb›‘M†ù6˜Rj;BåU’ņ±NG¦ÈuJµG\g(°%´“h§öÿ9ºõ$xs³õoƒî÷íLxÙ Žä-ÿø_âZ|-÷ýÙjÁ„žoHg‘L!rx§„bœJºì"©Ü<¦‡XT>±b7âil"½îöÍ|¡ddýsÜäÞ<CÏ`šåŸ^*fLéä¬í2œÅ…0[;j¶k%Êùg,DRKÁô¦@¥£¸È!4ªG¿uQoö”›Å.¬'¾löîç�� �IDAT‘Û3_t[¹ñ,ŸýÉ—/Ú{^w  ž¸}H{1 ʶ^Ôb;m(1v!ikðO‡ãbdRt‰±c­œmC£-dŦåþ¡–·Íô+EnU87\ýLÐÖ4j€ävW\^¸Öù%vnA šxº"óH# ©W®½~¢²´¿q|*üÒÛY¼*å+~yÑ×ÑC3”º8D˜ÙœÙ:9qu62VØ!‡š`Š\§Ù»uC­Ž’cŠ‘Qœ´®ËOs²Ö±cÙÁØ0ÒïýßÉ~HÞÑRœ>y§zÆ]Øùгš™þåú†™[œÁYÒÅæ; v!9©"IßÓT¿3[‡fÚ'ÛÝ{QúH;~r>:ÅÐÊN7Ò•Æ}dNÐMyM)rì.Z8ÒðP}½ ccaŠ!7C(2”§ ð#CŽ8¬¶–n{ªÀ1Ÿè‹•pÑßÝ ÷ 7>¹|©ÞÄ>¸l‚f»ðqH%$Ò™Yhè¡vµ@^—ÎêHšÏÛJö¶}oÚoyôÜÚå´^ ù‰gã~ë~6¼P‹ófS Ä ×ëÔÜøöòÿ¤óüÑ…sò9"øƒ¿v)š¿‘®#.^,UÀÆìú\º+Ó·%ˆ_-}o WñJ÷ûú‘0ö—¸ë†ŽÙ¿ÞDZͨRîj!‘Rû]ŽAZ×µb�¯Ôæc’iÎp+×wÛ¶¯‹>ìÿµF¢œI3†¡ñ\•¬à¢ŒrŒmÌرù,ß¾ë4cmGØÑZç3›ŽÍ”Ôåw«@ìÚú Ìm˜ìIP%v3&G¢*Ç: «"‹ë,D‰àÙՂޅȺë¦ðÿ Ôî‘íµµüâúlti¥i‚ @ô[‰`ÚE¡‰Û"€¡0”¨â�šv[ùvÎÐÅŒõu¿]J[¢ñú®c6‹z]IW]¹°uKb¿3ß0醨râáî3-æ8båöE »'«A£¾,±M4õÖJ#25�ïLÓ« ©¶% ^‹…î8ïC¤W_ÅÓOLØØ½ Æ®:9óÍ…ßó·=û7í½Ž'¸Êå«ósbªg÷­M\SCUJC¦ÔVÒ*¯¦ó4¤›ÔQˆªÁ×ccÇ02mo›´Án„å@"²j:Ccµ©,Î/¥:ðx¥Â¸½íDg¿¹à®{!”ˆ¼¢±mX)TjEŦñ ªGò]¥ÚZ\aúýt‚«!þ S®:SN¥ójH„I)×§lu„’ŽŽ÷ÕÃ2Sd#“f¦È h•;âí¨'‡ˆ´¶‡Âi¯<y*/ß³ÏKO‹�F§ÔÈåYz…“Óä„=ÄÑ`Q|¨&ïœ5»¬Që÷M÷þW<3þH}ŸAu¦{ÒÙÐhí¼ßKNŒQú¡yrAjÒü4°œŸZ¥¥£³íJ8 ¥ëän½BS÷$ ×ÓLnÔ*žiǤ«C¡a‡e¨\GèeÍJ“JØÅæI½Ãjj®eu@—Î"¹Û˜ŸpáW¶w5ø«ÏnnðÑÕúÍë×Ô€ûrò9&q¯Kû‰’^u畽aj `Ã8ñƇúéN<Ý0W® n\³·oDƒ+:ºTw_ZñÑ w'ñÝk¢û†ÖMÌ=èW¯ç¿¾8ì³ÿáÜùíÏÂo·Ï?!¼Â«—®ÃTvÂðRÐo/ôkøIÎ~¤%’Ë F.QÿŒ­uâ4—«©cø…I=Œcr¯‡‡)$c䊥j›¡Æ¦Ø5 KgŠ]J(”Ó{9Å®VèÚÁCîNæÆX+)rÃŽNr .œ.wI!¡÷A´“¦ΤcÒœÆ!sî´;ªÕÔÇÑ®k3S²=tºpÐU"cåcBjoÙ#‚!•*+ŸëîM¤4×/]ôoä›ËÝóËYž·=)èzÚ`k’꩸SBð‹«´—ëEt§ëµš!»Üe›‡Û8ʆö6�›$€3Qç?ÐP c…ù÷ñV+(Bl[öoàÍü©3d‰O°’Ù¿z#4M¼Ù¯ú¿Š\P¹.uºÛ1ÝöQÔ2Ķhbg2u¤>²ã5{˜L–;L½JßëBKɬ«>E>-OÛyýßúè.­{ñÃìÅ·õc?ÅÚ¯ÔðÀ²£‡˜T(X¤îçq" ÈIšrX%JAêcIç ´)rmVÌt‘iµ§–“"ÔÁ®LQbdìA!l§›1#KcêEüÀcÿÅþ¦Kð’ÀYBíÛßQ!âA‚¸m¸\q;N¼òÿâ#¡ ý ã%"gc]dqéã"Ü.¤II€Üìù¶Š½wÈpI©T®A«L3^_¹rÜ©OTÏÃ!‚}œë°‚¬ÇÇgV{z3ŸRÞ‘…ä[&'W@ù»Â€âhx/ü¹ø€!=Kð>Wê Ó¼?_ûvJ„|$ËÎþ„jºxïîÆhà ¼“}BL˜ž¶YóÃV΂'úÓjîKÿȤ’ºYéûJ½‘ñ«V?iÒL'é®VG¿°ÕÃk0‰3õK5ÌŒ‚Afiäz­™ŽPä:Ê€¸›!©ú¡–‚’Y½EmlÜùמÿ×&/þçà¯:wxe»—Ú_¼Ý~.qýŠ¿¡wNvûÌoõRoI”¨Ü“Ú:ü×&ºÀ£é9¢·¯ê.ð£š}ŒüÑt¦ñ¦¨·gÿ 4ØÙ²ºøx;úáNï'fØþÿ¬þÛ®yLåÅz¡‚Nðàb·wyCtÿ0ç2‹eWnô<þñëí/Ÿ¬²ž‰v¸çIâôÿÔ÷~ReRß@Ìé £¨ö„™#7iI‚R^# Ó‘×IhgI’ØÆ° ¡² …×�¡dšÜµz…4”‡À]”¹‹w¤#ƒ¤t†°B’dL‰Vîo*·d±AcS§#t‰‘r¥RŒmfðÄ{É$ÜDˆ<u`صÖÅlVV4_<ÿñ¹Ûú·<wÂ{ÿ¢+õ\D7»óöfïJ‡°!œkõvëõ3¼ˆ +n!‹ªÎh¥ ‰ê‡Ê­)$õç ¿¿¯06€&*¼‚f�óüð;ûèüvèÁ.)ÚŽrÚæ¨ƒIzP%’Ç3»pÛõAÌChþP¸¸~ˆÿDz9u†GGîNáLÙßNÁºU0Ôö~­ý½Ø&L*¨œSýE|ðlª¾‹DKݱ³¯êÙWZΦ,QàR©Ò]{ORäf%õOTâ˜Q­‘¹¤^Û IŽH ¨wUÑXœIÆa´׉@•CDÔPMq{2®Ñé&55O<×ÿ)Úû,a@KÔê-G´ðîåöT‚¯˜%u07A`Ü?pñÞÜì}ÓBϤK;.DPŽI%j×Í$éb½øÕ¶6![¥¼™ÕBl¸6¶3'‡GõÂB@×[kL1&y/`çq´†JYgþ.¢Öűèêƒgë4;Í==z–ck¸cmÖ;í$çßëÓ 3ó$ø/å°¾ÿirš¢ZœÙ òwÎï+…ˆ>©X>­×'aô4×woÅK;v¡zŸÅ•ŸÂaÊc£Ö“Q§Ì9Š\[‡ë`¤×Æë,û5â´Ê)ѕڌ÷ÆÚŽ™®ŒsÌaÓ2ìš"c¸k"Ì—»¦…YÃãÀ¼¼^rîj|îòù«y{}éÌ_š?\U§þíU-;ñÇÏÚËy}é7aæ*{Ãö%íU£$:øQ÷§ÿ¸ýìyôåsz×Ð=ˆ0RÒØM6æs”Å>ã—UçEd—Ì/Ø+¯«óÕ¢=ƒþãøÜB]ƒWÁ?ÿ“ù.lqîr‘œ‹¯ÃÞŽ¾Û($Ch¡t”¿eÚ‰YÛžÐ0Ù÷º/âºAI’]#GŽÂÅV6Ø1õêwºR!ÜP´(‰rÕßíØTµ¢ ¸Ø)QéH'{+±a†Ê¨s†cí<½‡NGÚ¢Ê&Ʊ*ÛêÌt=ÆBf8&é©£Þ$¢bEÒܯǞÖ× Îp ïyŠª/l¯½þesågýéòúôʬ‹lé§¢ê,!ØþõœÞùý§Kûz“óÒ„çf®ÊÇ´ªý“2µí”]寣j°Aä5Bž©RNÙ\%ôm+9±N¥~ÐoL(ÁäàÕT\×ò5w[ÓúI)ªHhû))f©]ȸ„@èéIW1gTv>I1ißz²$T¥ÔiŽh¨1 ÄCS¢S©ëL#Ù’–@•«• ±­ µó«ø6x|}c•ìÒ:%Ä4ñ= íˆ4S‡Å%.…±Y\Œ°Nƒ.¤Ne…LéŽ4JêhS!xª”mµƒÍˆ‡¬ #X%EM¥þ3p?…Ô[ÿí¯ýw éð“3ëSwcæ0¶@'»ú.Üu¥N$š'$ÄÌ]v™ý´í6ƒ¥=Åëµ—&Ͷ“®¿’dÌ—­Y3çZ¡×\låÏoN‹Ÿ½íŠUŽ zí±6:µñ.X–Š# ¿£ì wB'ß1ÿ1QðÜÓ3OíãdÎì ìSVÖ'*áI|[õ,ÿ+yÑg-j °ù^çg÷ÃwÎ?O ïvT­òSΈï6§µ \¹´&'œMœªâ„ödõ,v¤U9³·Ò^…+ný¡ƒ!Czý‡ÇD#”ÔQN"µ’¤9{hÁ ç¤Fž Œ-Ô‰Æsáa<3Ïü£ú%®Ž÷ÃÔ=å·Ox%-Ö {~x{gyÑ?vÓ7FHÔ÷|yÉø ÄmãbQ!˜]2;5ÐyCЩ¶Ä·Á•ˆ¥O¶þWê)vË+Ù±ˆYlGŠaÀ‚+bº¬Ÿ?¿ó»+æúožˆ×ÂǯÚ7¯÷zÿãç ¦ß<ž¼zAïž)dl(J°áÉý¤ÕŒ4¨$ª•0_z¡Nxh„’&m(2£œI]¦ÌuR~o‹fb‰‹ÿ]®ï¡q”Õ+LB\@±«k&‰Ôj _¯Y­ø±¹‡89|]‰56i®½4jdÒ••¤Qä•’“Ô1Ìã•+Íî¤Î®ÞŸe®ïŽ0ìIƒÙ¬wùßð/¿ì<ú¢ÞœÓøoù, ž¬¶?ªÃ¯ôSÌ«çDsÎÉ¥W¡à UôP¨hGÕ·! š6À;3ðfz`…SÉé;mKpÛÈÜ—hºÖ/<lù÷ÄüW¯Q /ê©£±+ŽÜˆÄUÓ³>K ¢0Žšº”Wz³Ä­KÀ0¢U;O\U8Ò1#¶6‘q;&ÙA5’à‰‘Þo‹¡ÓµD`÷ÀúFÝmîOßHê±*Ñf¥ Ü4Ö“–9©4INäÌv5b»¤â î‹û¾Û§§’ƒ¸›¤T*7õ´¤ ¢ûYò]­º}û¤*¥§èl¨Å§š¾UÔªÙ’óˆ¹>Ž„¾»ƒ’¦h؃¢OÝÓ@ùØÔÆ{Š5zoö­]hëh]»üÇ`nïå¤#c^€îj!Œr”#Šl¾ª§UrXR ¬úˆrèŠq˜Ï|Bê»J¨>–d¤Gr„Ó[ñô,yó©•ÉèÏnõI‘ïIº#ïŸwRÞcêŸÀtó3Jqr’áúgñ”þ·~œÔõýñkŠ#êчýȯ\Ú÷ŽKby43®h0+=Úz 1*Ç¢#L-µ$˜rG“#Wà3ŠÌvõ]̽Fß•”šhGwÁ›= io@ „ŸúPˆ+âÛç½ý‰ü5ļß-‚>nÝ6žQÑ‹ÃEµìÚÙ†âœå1}Ô¼ûË•}l(7ˆeM+è]ªo­p\’Ý‹]ù¯óß]ÀÛíðZÕ<E$Öh$taa|«å­Šäô·ÓÁ Ý>1½[Š âêGžÁRºWwÎwî?_vÛËÈß±ì˜Ù3m[³ÕãË….\¥„Q=|ªË«°Ä‚ZùG5%·…0ÞcGš1鈒1¥ƒÌØÂ(mêb½ýSÅ혇 I1…#Ít™“j˜9dŒì9<ÆJ­FǤ ‰™ŽõÀá&¡’2žºUÜ£)Ç: `ËPÙ}½5œí#­=jÒŒb\©Q,rC¨¼´¿Xê׿酭pƒs?ÎݲÞwDMH?6ùâ]¸?—[ò΢S‰ï…ï÷Übv«kŸ¢zap û’yß çªÒÇÖUÑ&Cg ¡")êf{àh1l*ß%œãoˆ+Kÿï¿cxˆÙ u°cZ4c3D—T‰‹÷²Êïb›XIp••Z“Þ¿G낞è^®;£ïêZj5ª’2ÞKvq+8Ñ+ò… «¶±>Ã~ •’qè*ŸÙé.ªÙÙ6n2ø|{úd~èâ‚*’Ö@)µ“º¹­œ!SI™-ʵé)9„ÿTÊ74ì(N©À»ƒtgZ~­˜Ç‰§è£ÿhÝùH>¯Ûég^?f¬,Ä#/®[÷úû›8½m b¶]`p:Ýœp°]J¬4t£¨SÓÀ'øïµfpS·/.WS'£ÖÕ>F š¬¢Œ“d­`Xýîe ë¯ÂÈ]ívÖÕ€1…;QÖó“tüÃðàCÉÛqÌð‘nLêÞ㤞¥ H1Å)o%þHÅûÓ¿CsúÓ´Òwkì_îÃz¶ŸÒŸuå‰0£ìà‡Ü‘àðHz]œq£uú'Ýýòã_Ûê+$G¢ùД¯” ¨µ©†Ž 'IGØöv´Å„’63Q¨?»m_+ç)vp!8“d¯¢1{#=èÃMóq€fËnr+˜ÞüDßjèÿÒüÕ­ýö+Þ.|tŽ·—ÂÎeÿ«î´Cü×-^úX>4çEÜYž‹o]TRêÎMá/ù6Š˜öb13íUS{³x­¿ä~MŠ+íßþëþüß½ëÁ­ï/{ÈO¤ÿ+T ¨» çÈëº ÞÂw¶¤bƒë·ôeËÕ×ÛÝ×Ò/YºÖ¿žÐ¶¿Ü¿n¿.1[jqݨÌÜëN#KSû§z¯5viÄ’¨S%ž40JnKaj´¨±Y½+ìØ”`%¶„ |]„z­} Q3 ¨ ´‚{ãÉšf–+Ƈ8¡£–ØM $O26`î¢SÇT"$efH·#“®tsùÊ#^©“’¦¯¾Ž†‹#ÍØ$„Õ=HEœŒéAàù…üÀäÕ3uýé¬y=Ÿ}O‡­­h?[2Üröu‡ÿ6³JÞ™¹ úH¥³èwù ÚϨå4šÛ¦ÃЧAœP¥›±?à^?Ф­›íHÒJSƒwÈËÀ¶ßo?ýΖ2&ä^¦koÚ\sj4Žd—˜:oS Î$ØhDÒh2ö|{ÄÁÌwPHÚØ<.3Ì™z,¨DGc�›á¼­Ñ”Z=TJZ‹i°m©Ê>ÜNJÖî%)Ûõ@VJP£’R*úÔ;5¡g„%Jvmڽؓ”yEV•¼Ix“›æ0¶ì*ÕÜaW'3›øªä~ú¤Û¨þ£ºëèñ@vèÊûµ Æ'Íÿ•bÅ,cªDÃv1ªR§ÐÖ«êµQ:Ûö^רú ¢?Q(OzóŠ–«w‚ Œ 1 ÚJ’±µŽb—´<^H sÊC­ÍõÝ•Îf-¥^ãc³’"W­\Ÿ²5Í)òÇælî½ÅN~"kòÔG§' Ô{BÅ™ ¥ìÄ>ê@ûçØ`p")çÆPþe<%>¬ƒ{ÿg~g‰V¬¼†Nn¸Nµ‡w¤&=b£f'Ìòò÷’‰òSŠ„â à}„'=™”àD­8÷N23=i¾tÜËQì²…^:‚±ÆWÍBób„Êu²cî¡‹\o9|ÎßIÝÛ­ÜW•;ÐÏÚªçyŽn^ðœ{bèj>z«Â]vùù“?wA.¯E\­^ܲË>çCóñmž^1ˆöþâJ‡àB-æKýóŸt&ÁM‚¥R?Sw߯Ýç„;ߊ–'WA§¿½Ã.þ«lÝTmݲNNÔFUJã~2/ÂUÁ’}üˆ Ï'/ÔæÛ·ß.ho<éÏéÑãUÝë>Q¯.L\md§’ç´=§åuD‡îÿ£ú¿Ráu#oèèš”©—ñ^‚P‰�ÔàõÆE÷dUŒM*5 hµB+Ñtò÷ĉÓém’X©ïºÚfš=ÀÒàH3Sd&u¤nRxÚ±böœ¶hÆ™•ÙëdÄÝ‘c“æ&•FIwÖ0`!¿Hf¾-c³rذT˜–“½Æ02 ©®ô…—mÛ f<máyýóÐÜ™Í.™áíº~Â>Íâê๋…À6•ô1Ofîº}ûËÃJR©ÅB™~�í {£ºwP•..¨ÀºNí!êW+£F…N  ãY eŦ¸œÈézåûâ(×RMMBãH¤.2Uç¶ÈŒ…¡Û.Ø®¥exx×ß”ôª¬ØÕ+ØFÝ5^ n5žÐW•máSk‘H"ï*K¼šž…T– _Á6WaG¦.¦§­ˆÅCÈu¬ŒÀk<µ¤«œ5iÁÚàUñݯïmR  o“UÞ2ª€DÜAšâ¡eæ ¡6”ê)v£ÅÛnôÝVšØ²oŠ›ã‰t†F&󪘣ò˜ KU6¨ÍJ85d»ì›DTƒ•œm^[â6¨gA¿»¡# ;qãjåÝ #JTcöLr\”ÖWc£0k}F®SP«$àŒt¤Óle yl“w莳>ò®4NX7áæXˆpÂÖ³8"¹œ2Ð>Yßô‰`}¦Ö˜Ñq�Ñþ§{IñA§¢ãBšüoé é{®G§i?§ëò{´¥ÓMUŸÚ‚­H¥GÆ'íüN2Póc…öÑR/ù€kÓq²ÇNyä¶¢)zßiBîfˆ1f6æßþjòñ–¹Æ·Ý<®1lVeŽƒ3˰pà˜ûXîÅB²p¡=†™þ¸{§ïyÓÁIýìW¶h¯«ŸOß¶/ìôñ~¹´¯uç'.8ýƺþr`ÿšsÊÍ„³19÷V÷¯Oþúõ·‹`À åµ’ŠPð_/ÜŸwTï",h^üÔ²z¯'Åôéywó’ênÔ³"¹ôâY.ׯñæM%žú+?¿ÿåßÚö¢i®�¿n{»Ë›Ï.-ؘÉùöÅhqS\~íèîÒ.áó•8‰Îöß\£óo¡ò[©Vÿ¼½_oIšîù+K¤Ò ›’;âØf»†9m×!ÏœµpNy>³=( °¼˜ ›à¥n̯°D~†$âV— $P7„]ðÂô ç¸vVÚiPÓU5Éi횈¶D9¤4)¹÷‚”-ùOwOÏÙõ…� TŠf¦ßˆxßçù=­«¦±éí£}oÝ·ÐD²Zu‘êîëÀ<í^Þv>¢¤QR`Ðmgbg2´êm±]ï¾vÀhÈÓŽWlÑÑiG¯Î¢R4äÅ©”D§=uH»:ë`;ô”s 8Ô FG!I;9·¹@Éš$ýRÝì‹ Ô}ÙˆŠøÙRkaéæ÷4ìß“}òÅÏ«uq(ú×ó`]µ )%ų–ð}¾iѰÞó cØÌíõ|‚QNBñ4º/­JÛ–Z8Å@;B`alóa*)ÈħÎÒ6ÞÑw¦Ý0…œ¦˜é¬al—øSèB§ëùTk¯£U‰Ù”´¦ ±,JYÝF wl x<„N[‰òZ0Ôu †¶6ö4„M|µïš^8Ë€4É‘¦Ftw$6±`íÑîõSȆ†Ä·Íæ.4tŒÏ uë^ÚU¸™zG¹±êŽÓº¹¡>ÍXœVgwlæóŽì‚Êõ½ºÝ±xÜÓ±—ŸmöZb¤ÃƒâŽô÷A5ûÙºUëÆÞÍÓÈÈJ%œ]»mñ¦½C6°÷ë„’ZMÅò¡\FºÑè0÷‡ôG«¢.”£ÝÑ8HrV*NOø SŒœ¶]L•ÓY2MvÑ)&Ý M`}6x 0LÐ]-=;¿]’7Ú¡øÔ:—¾N˜Ž4ºæu};{8ƒk5ltÿ tγ§–·' ÉÛ+Ç»6$¿Ï"—¼À÷öŠòÞ©u÷en¢ß2RÄoÄdçž7£ùjÓkP{–;ŠÄ¤ ºlž*‘_ßW•‚’d½™€c n ~Ròñ5ù¾ÂåFΗº^Z!iKãÑ"!ìÛŽ�„Ô߯óx ©o½×Ô. R1b_þ0â¤"ÃbïõxQ\Z£ƒ-YFÕëycQ.NÜÒ$ æùø•˜\ðÕ—¯Ô¼\ÊŸTöJ^¦A`o\`n±¼±$™÷2¸Q“bn®¨Ž«:ö?^Pò¥åËWîˆJ oÀOMm\]xÞrmíßíõ¿÷Úý oìû ­ë£g¿~¾û¤RÎÿ`wË­£_–ü‰¥>c¯F?<<ºí®ž\ÏŸVDp"׆“ÊÃòß›¥ úÎ X¦RAÝBÜ"ÐdÜ„žV’ð6™#–9.J;lÖi;¸mÚSõÞTétz+±Õ4Ói/bš¢‘|¥0Ȉ„6ÅZbØ8µÎØÈä±SS)ZÜÁ¢ØD+t– ÛÐxó�kÝ0Í,N‡¢l· „RC±IÔ/õÁa\§?0JúÃö/<ã[w¯®ØÀÊÖî•Ñ 2QOé÷"œEèZ`Co«°Q…Ð:S~ÔÓht )£Ò[<)„ÒÄ^?€bÙŽUÍU_m¹ÚŠ¢ «./%±Ã©áaèž•zN3ObÙÚ–í¡v£•žm'ÄÛUt좺gX7läv×àhµ=MUkJ!¶Do&—h`–ª¦yg r‹;‚ü1»­›#d•¢ M£¤…ªT9ªtôݦª”âQC·†:ª›‡ Ò¡.šX ÎÒÈ‹z‹Ã\%Ñ &í˜8Óí[%0láTü†DÅ 3˜�� �IDATÇ $z³§­Œî7ÈŠ£k$ªQ°îh<\£Ê�FÊ·£4À:-z¡ÝD=µ±Ûбˆ ¡3u¤íȆ0QÛñ Àªû‚blÅxK­›µñª•¤=ânN3¢“Ç.jwMœ¡ºd³®‘nKÚ]b´u]c1¸Yp¼~ŠÌKLzý’߆Æ]vß4úãÎCWŸöŒÏhOÏÀÏ„uÞ[úõï©ÃÝ·9}ï©®gYGïØëf§?.4}çÿÁ“ aþ°‹¿C‰ÏÍpÌYØì™±sž&Q| Ýßþ&C·Ï¿½×Y€ñÖÙž®]\÷¼ªSVòáÄ^BGŸô(;Æ' ußvaƒ5O†‘Hèwµê™›0/u•ÜU£‹#C u…½g”BKì[œIÛpŠëâåÂêü³­ãkþ(7öñÒ÷/îˆ îzà÷.Ü\,÷OŽ«½íÕüò‰< ªË•‹ÿt¼ÿ“â7î¢ôµæñˆ¦ö‚ËP]`TcòT÷¢ê2ò)£O˜ÿ1?º"eÅ e?F=¿açÔñ¢ðO n„UŒ¹'AeÁâf`ë/[£å’Å 8)ÿ|ÑÿÃå/üóË ðs¥ý¥Uuìö„p¬}™·=©�¶ÑYöÈÓ@´ªô=ßÚØéT‚ ö&CÏ46 ð³¤Ï×+}Ü1i¢hÅj{ÝL»+±4™ íuÚ bOÚ1ª‡tÜoêÔ¡:¦èÙî,1á] Zìõ) ºÀ¨nÞ&Q,Í&º o¹†^­9›Ýâ6­ñ¡8¹¯ƒËãÖ^_ÈÐôŸÀ K2§e#g=*³‡”ÈZé†u‚±.w)x¨º®D™Ì%Q_‚#–æ£O¨Dŭ«-¨ÎI�¥•«ÊÛ •ð °R°[ 5ä±³³ ̆ì:ô núQ(ë­ê {8tÛ‘Ý6BÝ)¹«š æö„¹±tg²à'ýÃIëÇg|^ö7šF^x«\hñHq‡Àý'~ö«þ¸¦Ê bP?¹5~r 9)ƒ¯Š_Ü&ÞÑYësÕ€‰µ‹+ Ä·ŸÑ1³×¼³¶ìøÖov,z­F:ÊcIR Ñ–g7kaQ©…nX ¶-Úò|òߨýÅÚèaêïQ'²ÉÃBÜã:Ø/Mü)š/bë¨/ A|ª½Ëñ¹*Á9#÷k*Û±âvXŒ¼ªY»3ÅÞ¨˜hZÄÓ ÔT³t¾8­§:ˆØlåTxjHtØ¥èÍ¢f ÉíŽ9'%‚]îó&,ù iãÅ ïÊsÞÁoœÙ¹éñ¢îùWˆþ˜Ytü^‹Ý‡"áÞêõ÷Þ¹ZrÎýîÅÓ„Nœy™ŽÏ u9ô Ñl=<MϬ.ºý–Y<™õþ¦®«„½|jœ~¼Î·~³ƒû&rè9¡Nz8Á•DW¥F€ÌIL±NÖ´ËtÙD%Æ:ŽÑÇe>bŒáº>†—/)!ðöà0º#I€Þóvo¯8~Ž«úÅçâꉛ?t—Gá'UÏ…ààXNܳýW’¥JPm|üQ£R] Ž/Ž÷k¾|µ0?wÊæÑu>)·®•!¨¹ƒpˆò•p¼ÇÕª?5‡7Íã#s黣ò:¿’vPSÇÊÎÊyƸҙùúÃq°5ù2o„øí¨D–E°°:ÿJ\ü¨øï/í…Cð²^»¸ZÝ‹Ä|ØpÑö„pªØ J…h…Žö”¾7»#‘*}ð­U@ÓLÃMÓ)7 Riðć3I— £Ü”ŸhãÁj{MSÇä›NÙ¦“Ç=˜’×m;º¦m”ÌÛ@cºÅÛ %þ)ñS»Ÿ‡^ät¡·JÑï;[º\ .Ê:ŠÉÊ!î@Mö[µ1¾3qâZèàI?œ’ÐÑõ.®•½­b×7ÝdÇãX†Õ*E%ï‘IèD£¡dÝG«NѨ¶[õ­-F9C¶*}Ñ,ºiHugÙóEXå С0ÊÙ´«cèöÀXJ˜Z ¦Ëð4;oúçošæf…Ú£Çwoÿ¡in6˜ Í ¦r……Š¿þªýzëâœîÞÛ\‡¦ñAÔ’!r…²põòÆQõäfË£«pÒ/.}ò ù‚'·YYlewvlÛEì æÆr2\“¦èáïêàn0ÈÉ:QÑSkƒ‡ŒrÖÉ„I…¦ií `�òCZ~»Øa‰ØT¢µ±â︱@%OƒjÌV<ÚÊdîë}®‹Ü~i’n@B\Á !ÑV†Þ‰µ+ˆêÃþr.ÀÕôæ�ÅEì#¾�°:îF›§ žxº0túbZæsuº•ÄäÔ—c¦{ùwYƒ¸c8Um»Yÿ3=ªÓO ™…9¾u\HÏôsâDúœÅöœ+Ý·ºñ;†­ßƒ,:ø;;áH“?‚µ÷ǯEoàwgE`oéJ?$È}<ûv`÷[š¥·Û3½ìŒbõ­·ªÎ¾3ŒnNå ÓåçõøÞÂxœbŠ.ª§…3H¼Óuɶc¥Ëú ¬ÁßH;V¯/bŽ„¦ÆhœKOŠ—µp±‡—ò\¿Â"T&y9ÇÞeú¥9±¿ÿyy||8wùÚÑÁ…K‹.TÊòÕá…¿?öÍùê/Ž\9¹ü™o]™ž{wµbS åà[÷‰ð¿®Db±œÿ(myŒ´Jx"ª9CŽ(j/ôè›\6­_Æ-póykžþÁX—)÷ |è¯ß»½°U ‚ýKýùýVõ'}üݹùgGÇ@ñäŸ]±=�™‡.ò]È Uì ¼ÎÚ¡NG¯ï¸­ÉíUÆ Öï’vó¸eδ¤ëLœ‘îêxºYK¦Ð4…°xRw‡ÛÉ[q¯@€'ëÐîé ¬ƒ¬CB(ÍšÓ©$îöÀ¡ºÀC›À§%ƒÕXv5’´cè…¸"n†à¹hÜ27çîÌp|eÀœ<úÁ]^ÆM(àDq{Us»KŒåS9Qí1#…k¬¦ÎÄ]õ ]C%9ȶ”\mÏPn&tz ÀlJ]âÁLO™%¹•Q \Û3èPnáŠ@r¿£èE© ôÆ;-d¾&£eîjVÀµEuLT[àÒ‹ü%ÑÓÀH§—Í«I8™ôè sÇ[Á<¯þ¡8¸¥ŽžÚêúþÈd¬Ôwdî«¶J8úšCjõåíÊ!¨P~£‚»Üß‹6Ƀ*ÉØQbDድ™€Z£½¤2æ15Ò¡VrËV Æ!®P[kÅ_ôÓ/ï´F8é™8Æ¢]õÙPÚz©*^ÀZ…ìëˆÆCqC»»16%Dx…mßh¥¥‹½HÛ^m‚‹y=£ƒãm_bZUî£6+ÑÚ7¤@Ää4"¤SX$§ÛðÞt­eŠö²]=u®ÍÚ>É”­2­ úì~?Ý€uâÄ õ›vP´óF¶Ä™dˆi9ž5<ý»®ÿŠb{–1úV·¦÷AÆê{ïÿ8 ëÌÖ§ÓÂYBÞÛ·39¨ñûšKék˜Ô[øòäµ­áÌy%9ƒlœ†ŸQ˜ÅÝ·!ñ©N`æ¥8›ÿÓT|:Ÿþ^‹‰áñÔdßÕ ÛÖ èhÑ58ZÀeÏÄSý5&kn ¬tÍ2Œêæk§Ça‡V`çŠ=ɾú­šÀÅùâz`Ž/™ÅçfrLõ2—Eõå¥gÁ¥«WŽŸ\(—Æ¿-Ïs|rôjòѸúQãÒ«_ì…“åÑ+oÄ!`¾¡Žþ¹˜;|òk"óÚÇ[sD©O&<&ò%Áã?Ó£cßx¦XʃOy\jñT×Õñ•òÏwôˆ¼ÿ4¯A1è˹¯_òt¾¿8Ý«>ûáÜ«¿øñ{_î­üš 5Ìv€‚PF¾ѦV^+tqÈ£+(„qwWÇC3*pF9“A«!L»K:ÐôLŒbWǘÌ⦦Φƒé½ðñމ)èÀ@¥èv¢gÄ›î ȬÀ;ÒÆL•4C'î)îÅŽ“9•6MêPIÈ”–Zi)†u°ÇQé«W qy_V~jæØOnÉ áù"·UK‘vUº¦·a{}Pìè5o Ü–ê’%ÆvŒýÆ<l²j…I!sIqÛÐ E˜p$käé†iw­êÐwXrœn:ÆxWø.}¡³^” Óª±æ�Š›U³ZÆÔ†úhÎÎï™üè"·Æø>;%_­¿Ÿ¿é'csðŒÁîêàyñk¡ŸÚaMûu]Š!ÀŠ3‰ª°]Y¥ ŪÝýìó¯,êþ¥SþSú_ÛL> œdµÇÎbíxuU„òÂfBÔíx~ºËà16 •Û²Ë0ÒªíhF.Ëî¨Åùþ f©ŠÅ:U6A4ûñNE¥±9'姆ë"x²‹‹p(| jw²¿-W6-‰±í‰ 0 ÇçóµÆp,ŠR9`ùI[ª ëÐ •–õ<“yÜѪAŒ 7tÜCMyïSaWÓƒž~mª»¬Íj‘Ž{@>3¯õˆ×M8HwNÕJ@çm¸éëÓCöºá‘è×™ÏgÁÚÙûK¬ùÇ‚³‚³!Ø1ï¾¾{…˜÷[²ÿm¾è÷Õô×´mõ¡Á;³õßXšœG-Í>vÍ3úYéØú;Ÿïù)Ík…@zžÅ=½aÙ9©¯M™`Û³¼¶™<ÿµõ1MxÐÕªGÐÓ#Iµk† `S MW‰ÝÕ›.'úGc%£f>ªê¯ÖôÑH<ƒQ4”b´ÓzþRíÀwê¥bqž c–;œ«6N^‰Nj\x\rµz調'‡öª¿}5ÿrñ®Z`¿xMÌyÔŸ¿ å¼¼¼Ç÷A4~á¯.åBqò«âp)÷ ÑstèÌäzÄw[ý)ì/XªJã=£'<~^l²å]ÔªEãå­ð6ìn?ƒÑ †¿¡z…ê_˜7ÿDÔæÍÅÏó�]©„-¹e?¥p†!1k‰fá°îîèÑ3Ó*£ü·[¥TE¬T4L¿Cè¬G Ê‘&vú€NWôÌ QÄøY‚"Qi¢R¢XœþOp zd ºØ†f�]CÂGÚ3HÝNò6¤ƒBJe;"v™Ó\Åùl­µBMÒ²b ô2åáqãé‹'üËøäæÜ¥;ã%X+_Ѫ近ž^=Þ@ ¬êEªyz6—E;QâD‡R©®Ko×E³UHb¯C‘[ôŠÓj¨69%u�Ô Iĺ"Án˜Xš¸gcIßådؾØÔÊDÎuª;&mh 7D°£¿þ_t}WW£æÛêqaŽa°aÊ`Ú7Ô}ÏçNouãvô}ŸCì0¿™ñùºíwè¯J=’µò¬í9@uó ìShê``­ââ z_Þ»ß Ýµ+€3€2´7ƒz9 ¯5-š-¿´?õñÓ ™P»ûPÕh‹‹‹w>…‰¼v8dQ2º<!» U¯˜ø&wä¡ï_±dÚ ËOY9nÛ·tì‹t#d§°„Ukl>ÿøûîp¥-¥º!íHg;‚FÐn'§Y‰mw G{`Ò®žzßloöÎx•§ á3u#ž>i§ýê´‰^{´KÌ9*OïFèm‘h÷M?¼}&NÆžoû¼QrvßnÈŸUôœmÅïF8'¿Sešœ}þׯ ÉûvoHOÉ›Íôk;÷õÂÞ]£Þ]?ÔÙÁÃŒRbÎÃuÌ9û_üÖ HÎuŸÞÍLjÏ$»ÎrCìVGN±VòtE9í'¦gîKÀQv Îl£m]í w¹¶I$›a$eC¯íòIÓ_×~¹Cˆ  ­KLíÖä½ùom9n FѯÊÖAÅrQLä…ãÁܼ?¸8ž;¹ÃIõB ö.5Ž÷˹/ºãÉáw“¹b~¯ùd$J8€ƒW÷.⮩Ú÷æ»wÁŠK‹Ë"1Çä$÷5ÆOqrµ5ae¬ÑhtYË€¾¤ RŠ5YÔnÑ0‡©ªPþ°ð/4 ŽÕ±8ðêø˜a…ãCQ9å‚W•\Ièêð®Þl˜S4‰1ϚƣdøðÆu£(²Pwu¸l¹®ã Ú¥±N§š:DA˜vh[¶¡RØtZ÷h{º6“l,Ù\‡Äd%¡K»ƒ…5ˆÄR“(ºÆI”ÓV’J›6 RJ»’S÷€m…ËÃ!Ûµq¿âðåÖ/+,2¸~õ`ç ƒŠ.ÿzÿÇgƒ=[åUM.Ô…gR¡àA°%š´É<º%´rš†»aÊ–¯cñxìŠVýï2òµ R­a:vmúœï2“ u *‰2´èÌéÌ鳂(¥ð…f‚m"kß² ð°�êí¼Õ3C™».þÝ/£–çq`ĺöNYO&ÌMIìH…¡ÌӖб-§CQΖñ†.:¹åŒ�±Ëæm}ßµ]­Öa×”MµR²Yƒá0s[é`‹ÛzèT mý€/Ônx£¼¬q«Ê{©ë[y/ð@†xlµf]¨رM+’“C_‡‹‡ß]–vîq៕(‹f(Ú_ÅD°ƒ-©¯‹L𢩲‰J¿ƒë¾MKš­˜"E±KŠ+ôŸ#¯ÓI‰s\7Ö‚ˆëý´g '!ëè´«Ó$¢n6»Ä‰a@ìˆAš©±&#O{Ä“ž!¤Î²ë7ÎíDãiÜôëÌ®>ÃÙ™•ˆp:âzï± ÷ú›¯ç¦æŒÿ@ó;öÖÝ·œoUöøÃ¿sìî‡_óÍÞM®8g¼þÐ_?(^Jß’ ½ïñ–êÝÁ[ïä}ÖsÙäuôÞºr†±§]ÅxªCÀ¤“OÓÃOg8zúƒ6éÃ.dÂchA¿Akݸž¾)Ìþ@-uÙߌÊoðÙÕôÌ}tÒá@H<‡lÀqÉüJ^À(ðz¡ù›—n©”¯–wç?úôøÂþ”ûû£V^V/–ßÍÁ…WìWÅâØ†v²²XTÝI#KåˆDy<Oø ÿ Áø†ªO¢Ê7@6 hé;}ã@Jõøš µÇˆüˆ›¦ž3šû»Ú¼»¸°wU––Õñ‰Ÿwÿ¸»‡¤_¢jFŽ�J”¯!wè7#årdÝºí°ŽÿB·¿4vÔ¶Œ8e^†]]$9 ~mº‹*Ãt°Š$v[›¬Ò(X×k½QC4Támìx€îcèê7‚iYBz&u R+gÚrÊäPk.J¥AЪÑßQJ"¤JÏu±´ì ç*V<U~]²Ù·“;­pÀèf•gcs =Om;�§tL?Ó´·â^ñèV8zøàc–ìÓ¯‘:ü&/¤B®u‹4ÑŠœÛ‘ü—»K,Uæ�kѪÐjWrÓ³/µ°fê|ŽÞ XsæºÚÙ‚‚ŒJ©=¦ïuˆñh+¡=¥{åÈȳ…(dMõ‡ÑŠ3Ÿ7È<Öi$aÝøm1ê6â UÛ#¿êÉÛDi'oeÑ}7…ã‚ÐÖ}…†ŽÀ‹þT7Ū•y,ì£@˼]!]¬‡û㇔ÁŠgtë{yP W«‰Ë•ƒQ) @ýo¼8.úê+7úÁ{,e(ƒ¢O»k™8&À.;õá ïhß^I+£ØùŒÈú±Þ­´ïŽÒ¿\U\dáYû;Ÿz»bÊ\Y“¤NÓÍãÌ2BµMÚÓªC{ð®gx I úäq'z³ñ=<ϲÈΔ£Œsñs!9Éé#÷fýæ±|k1ÅxØ÷‡+ÏöÊíÞ Ò÷oœI¼%ú SJÏ»”Ï ÎSðÞO4JÞÓ{]»ÛïH˜Þ:(ÍÊúïié·––™›ô¼âÝ“Ô9¤k2 ùÓ¯S^éa;Йºä£,9ç8W]6Êo¸ óxxÜ$ìRm‚ÇõðÌë« »ß³Âå@[ê~‚ëèÍt(ðbª‹0ƒ2?X6û’ƒßD£çµGÿÓ‰ý'çÇåoœ›ÿ­œÿ­_œŸõòø£ â¹h-¾üláè;.ȃ—Ñ«}~À íü•p8Yå0Û«ò%Õ’ƒJ„Ë݃!+ÞÐAº¸eZNìð²áº©5ÍÄi¿KµÇ„0j�ªÀ?1ò¤åGÚJÍy-— îâ%¿¸Wýú’Ù§¼¸t¼$‚犯R½“‹jÞºnìeú]•ºöI$”p·­Ô…lßuÈ‘n;lKKgšü®cð‰‰ïZ%ýš‹Ò]–ŠÀÓÈcGÚ-<ÄNÛu]$¤Sï[W¯­Gʱ)õýi€W0ñib²&%§7…’NokÞîBG§mMGd:„]j%iKë«€½è¿®^u•†ü–Önô­»«FÅH,ýóË/}y,¥qIÜDm¦ÐO´"W½ÕÌ1|Zà±Õ_˯ÿB±òBÒBƒö’h´»ÖŽpØ]èê¬Ù)#äô}º]-¼:ª,s&å— kdA^¸üQ'&«•„ñ552ÐÊåÓÂïÒšeœXê9¢5í†Q«a¶:õJº¦ %Å´ÐmµÇøMF׋Bá,£²È¹ÙئíÔM·×>cb ¢RzÅj[@ƒ¸ZÄÏÇF8ûè’ +ÑòõZ”Eß/à¥$ n.Â<£ÉRÀ%ŠþÓµ.Ö.[Y|,Û‚vXô—[­eÿàÖÑÍ^üT„Okâ:Å-lCÁgñ7> h¶¸eÏŠ½[á[ávÊpwˆûΞøTJêMwÖº*­[q5=,¦IJÚ Ù@“:(‰êp”³éô| I»°1Ën'ú-±}#õyǰu&bóttªÓ×ÍY!5¼ ¤¡Ý5³^wbÞu¨µOÇqòîËÙ²Üû@›çLùMÿà¥åÿCÖÞ{‘yéyßvü¯šÔ'ü¡ÃýäÜgèhò>Ƹ~yßLÌÚ4ÉçŒÁbèéÀQv ÀH/r¶ú©O h14NàAzM‡²‡‡8‡ïÐbïè`wKÜöƒ! MäÖв.-ó‡Š+òÚŸÖ?z5žTÜÂáU^î]XØ~qØ::vÕc±ó´A°ºtÀÑ(¿X‹öG¦¼®åÓœ�WFA-ghYÁjžbk´v(?ÅOŒé¥Zþõ0ú9<‘Ô0Ÿ/óà>0Ö+0FÚ•yC‰ÉI1ðJ5ŠÆÞ w}Â䢼\uÿtR»üÛíƒ_+>®WÄÈ?ñÕZ$ç~üÓ½þ·¹HlÀT?®ébTÐ5ñT žé´ýU¼1L´š8gÛhxƒSi7bæBÒÓ|ï DϤŽ1t4‰¡©³Ý¼Ý¦°L+¡ƒJh7IwMŒN&ôzÍ™G]ýy»Ls#,J !‚¢ØUHËÊ–}|D:Ð1y&m½Îp±ÕüÖ=¹%®íñ¬ä“þÇ1®TZnÒLJ­ ã@«u·5¤ «Û=Á¶0Ôˆ+šÁVæV¥¤ïLÜ$më7Z»ÆVê½jDÖÑò€MÔEäsç&»Ñ°‰eš'H†‘R—œ©5ØözÚÍH§ÿê 쀸aðüMÇ#Õò¶DyµË­,€]¬\1™À‚¢…ìÛoBd1#Êu ·6$[ûÛZÚÜŽY*‘ªc+ù½¥Æ'+ý矵*W­LÆH8¬NŽFê3?oþìÕJõ¥¼výÒdîŸxjsÕòùxxT/ç+<Û/~Føœbî¸u2ùxaôüR18 /ó 'ó/k»ÿg»®(ÈJË€6­¬áÚ5ËX±KÖˆ¬üŠ`ÌßJÕÜ×ðÏê–‘ZFìÅnv}±ac•eÖ¢Ù…&j‹¡;ÛÎ6ˆ½<vQ&íè6{¬ÖåôóÁŒ­0«&F¿î«¿ÞËžm3L±ž`â®&1SŒPún÷¿ûöèéðÁ†Š!ÑçR¦gý<˜8ýúÛÿý߬Súùzoi@y+‰âì"y4Pö>‚Svö‘|`¸ß…ù½Ñð¾5â~Ç"øôÝ?mx}¶(μó4!L`ŠBëL÷UÆ%ØÄÔ0Îåå +Tœ©c楮 tÝë¾Ãe`%(º´{°¶Žuøšf—~³˜E 0£Áªèr¼º¨Ê+QU2™Œ&{Ç׿™{ùã¥ßŽF-~Kí{¾éë%Š~ÉÑ‚èÙ' žB 碚7ý/lUhaµ˜ä2ØR#\Ã0ÉQ^gÝ‘<©SÛeT’>ÕeE¯Œµª2jéuÕå „ŸË/¸v ‚ ¿¼ñ—•WÁ«WÁð•ÿ§òúIÅ•w–C9œÕ.ÿþOíÅj>œã?O\ÿ0WÒJ„¸NÜPTÁi?Ëe4*Ñ›ÝJجš0fR(ÉýÝÈ6ÔLÂN¥àläßT¡Ô£p9Õ†êÍi—¶ÄM7wv–%E[Â.1òØãÉ3©‡=Ø%%c1¼ßÕª)‡úî/Ë1)´äCnc¥ÚÞoË?—{Åw˾6Xýõ½¸ˆ Uýöžè:¾F‚Ü´…5¼‘l=rf[n)Zj¨ð€Õ:¦†¦ÊJ55y<HØd‹AÐ’0¡÷oç”sê㓲æl¥±%1¡#¤!¸¿kpø®Þ:ÒÞŒãÝ뉻[Ù:iGO†¨u{_êB »lÜ,¬¯:³º†0ôܳN+YİIžaâ/ øšÿËb·HÙŽQ™Ó ðßUßb”ß¹*.ËÊÂç¼ø¬54.ð£É°*ÇraáúõË“­Oïîý8^¨ŒÇìÛúñQµ2/Õª?[Þù¤1üÔy‰°6ï.mÿx\ãeKœP[öûÿÝñÉ¥F¥õ¨$Eˆš²Ÿ©Í¦ž´BŠH¥°ò«xB|¿äÞm/ ž7ÚÕa¼¼Ú>ôEU‡rµØ öÂ,; f|�� �IDAT‹,:vyŒ‰Û´aŠüzM:R(Mg*!KXëLñ×9 qbÒä,½ÍœßÔêמS˜’™&˜ÍÚ =lbâ.Ó%dÖbš>ÏgíÝwgºoÄôïÞìtÊ›””wRs8—/Mò>èûGO)yÏ„9}k.ºÊµß×2:;sætKþ–ˆ*>3XVïŒûÓSÀzûy;›öèó³øÙ§9‹–<+“=ã4‰»ò5©ÉÄÝÙIºœ]2©ï€O°] ´í²Òe,µoD7¦Ü!uYh'ØùeÌ]ih³"ó“ ˆÙÂé¶Ìÿ4v�TÉ×äBäí¾‰o³4Œæ vžõpƒ=ör4œTæNŽË—¯Ê¥Qµ¢Ï¹¸ hMfˆ‘Á–p”µÜ#¨oq«ÕÚPÃÀø1µ ”Ü Œ Â`ÑÖÍ!}‘O0×FŒnC åYà «4*†M-D>„ÉÇEõ›Î‹›£-7ìÿý…ª|%Fåä›ñ¼|áOFåmŠñ¾úÁòì¹pûâ7¿•-eËá}Ïã§úñ­Áô¦hšˆ.k=ãº:…Ha}a!m˜xÍÆ©±'dr+íé3ö9B™+A¼ Pô Kºòô±é’uXé’ 2IÖ04¢Ìië")óv‡¬kT7ŠŽ=tk¥± ÖçÁ²ºóÉç®~5E”–tVÙ5E©Å×vx{«¿ÃÒÄ» aF»Qè”󬡿 V³öA¤šaÐ FMî¸UqݵåÃLÉÑÔ>ДVQŒQè>f­»Š¼×'jWÌý€Í¯AFcßm¿<Ä ýïªøN^[Ïg®+€œ$WèBg Bè÷r«S@áÈaMµ[ÜY¸#~¸»â¼o ù_?–•‡Üô5tÃåø¯¬d<V8«ÐÙmLèˆÑYUÈf.„ª7#ùi«ÁKø~—‡n°åœ²Î,®:‡U¼ØxʳË8,Ÿ”ÇþåÕáþâx¯ä_üÅïŧF–þe¡ñ“ýÉ‹}?Zà(à_ôýqmørâ‚“ý¥󗮎ž ª ä õÂ7lˆŽE×WÕ`;­|FÏ«'"›\ãò€Å?c﫬"âÑWkÂ0°È‡©(€Ø=L¥E’eI*òÙŽ0!;À6�²mMÒÕ#N¢TNyò3;í4Itꇘ.¯J)&NHC¢‘ÓbÏ´¤³õà,õG¿i¼U¿£ž©û¯7Êí388ÅùL‹[ïýÞºô] _÷ßÈSzÐñ®wúÃ}!óÖÒÔþðØàÝ™ý€œ)îž™4È· qS9ZÜ=÷z}^éœfœu-¦oyFöH;¤=âÄÄ ÷¡Ýá¯^;*è1L´ë€çIEWÇ Wß•0Á p ø/RÛŒí][44°Ù[M›&uöq‚”ú±¤v›ö:j=òëQ<ÀB³Dl˜gõ‡„ˆ“p¾´þ¨teò|g´zø¬ÿÂû߈ñ‰hüt‰ãór1¬ß07$R äjPÓ7F¶º¸JeutxÏÖ.S…á¡Å¯>sT««Õ§úb•`œ† þ yQ!¨ $›mÉqÈA>¸ýÙÇòòq«²„¼ ŽjßÝœøÿ2ïA×¶ž<–/FÍ“¯ÝOúå\À>îí_½$øÎóêñà¤O ·à3ŠŸ×ò2´kæt %©µ„´£Ûô×W9A®4` Ó =MUŠ&ôÓÇ`a|oêž1!¬u¢¶×ÓöØö[;FIØ h‘0êÇvht:0ö¶ÓoGYB;ÓmLÖ0iG§‰îC,txºqO£ù£‘e¿zÚn˜ôSÅÀ¬uµý‚°ÁàëÖzz<¬‰ÈíjÀ:c¥¡Šàš(]p ×Äÿuô`÷Nÿ¹+‹FÞv9묕d‰–ÓœóžÉ­6œÊÄÖZÙ1}Á±S,2ªbÅP ì0‰pfm@,õ‘%jw ] t±n :`7�£ACs—G=¬Ä?<.¿ℼQôù™|ysèrag¨vñ`]èQ©H(5Rg·KÂ~r³ÁB†2qûÁw£âqñtV­´Œ@èÑá÷¿|ñ„Ã1ã_Ž÷kn~ð}pí7sÂþ¸T–ÿù…{2¿_}é&Çvþß½ôþêè’óðOGn/ääbùë«büQ}þÂÑÜž¿ÄœT·çÆËe!]x“NHÉ-ÄäÔ­¼PGÅ%™þrSlÛoVÓõÏ2’´t±ŲÉpñ®Î€RÓ1 lœÌN–vª_À&&…bwê0HwLêôiU}S£²ÓŒtÜ©Ú%Ñi—¸ñÆP'Ñ›‘µ„®É¦WØ8ÃŒè¾Fù;¤¡3EòZé¤ßÈÆ§Œ;æ]é €\üÿ:oø­®säýñpçÄEïˬxo·î÷ÀšNó»³SÂÉkÇõYëõÙÆb6ûèß N²„z×l£b¢©Ì@B¿;ëÿÚž¾‹9îhÿ¥©ÕPD‚|è¿{óçš:ÛÅÎ YúNçñ@'½hš\ ºIt òê *kkÿ«M¸úŠù+òè‰;¹.GÅÞŰöÔÏÿ” þo¢@åW¿¿Í»¸9]:jÊ|ì£ê²îi ei‚@W—óñ^T-©ÜäñaÞšˆ¥`õèÀŒuõ)à §ÄJ”³R*&‘=t+Ž£›°Ï«²zmõò÷¦\T~ß.UÂg{ÔcK?³ûOBGÁš/ƒ ÍÌ)ñƒ¥Ú\qö+6Š5t6ÀÊÙ6*•JíBSZ׿SÇYkÏöYºôOEG±$[jPØw5(#<ÖÕÕöô`:u9ø3•81›à¥žµé%i•£-fâ41Ð&–¯¥ÄMÃ.iS)'ì­Z¸·]+õ¨fŠ¡ÆmÑXmySÖW‚ñxI”ßM°c”[êŽaY5åxÚò2+eøùbóo)>ÕáÚõ¤ŸÝÖö‹‡ôî)‡•ÓIÉ 6£ 4e †+C%±Î¶P%‘”]·*ÖŠA&–Óø<ÚäÑ5›‰.N]¾¢÷HtÙ1þ¿"_@åNy8`,|)…÷ÁºÊs…ÿWÒöý”·ÊmÔ!òµ)ÑJ3§”ÃZµþ'Ûý»uŽ—/ú/VˆžF}|>úE:@5•-#‚\•´ƒz&ÆTJûÔ¯ÜÔ./^üÅÒ³VA)<? þlîò÷ž.©“g¼ê—?s®¬ µ‹—¹ô³!?Š®xáÔ\`wÅ9pÂâZkòÞæÀxZmÑç“Vú¢ ðÇXpÅaC]šØ£aüD<�‚ eá¡ZċНmŠ¢k_·¦ü·­ÅoÕ–7eêµôѼn¤˜ø5¿ë´JLÅE©›ÑÒîï×9 k‡ÎóÝœÿNï¼>ê_Yš¾·“/:ýc—†ôÝs“|Ÿ÷¼:>3iˆ‡Î•Y¦[öÞvÛ[¿º;Ë O[Oé™…wóôðúðÕ†vb`ÚÎhwù­ˆ2 Gî3ë-N% Ïœvì¨Ï]d½ñë6˜_H :Ý¥ÝEa¦–®Ç5 AìFS$´{šÌ¤Ÿ"êxðòaõ&,Dâs˜oÔ.I*Ñ‹ÃòÒÿ…½…VíEñ›Ÿ²8g«„Ä,a÷jEý¶v— ¦V攀Ã!¢¤/ Ю4ãCë$ãëæñ>­o#(ŽÌø²v Œ¥‘»–še"Љ­^Éo¸áè/®¾pœøáèa¹ºïìÕ€£‰÷²/?®ŠhŸ–ø“U®¬Ø—j÷Û—øÙs]½ ÜÇLÆîæ± é„›+QR§A³kÖ–}àñŽ*J=‹zïrJÏï0›BVEW±®½‹3 í'F%&+YÃØÄ¼éØvõšÔíéEdì.¸<['`=k]Z]•¢³žÉºÐ$sz³Æe$„o=±ÌSì„¡4ªá•7®oWK±ài Ê¢A˜íi8ÝPû¶nIàWíjßÕ+Ðßìêö&Lî!]èh…¡K,Q2b—ªÔk(/FaSØÒR×á‘5÷´Ý…U&•XLÚŒRò4ÑðP´xêk_†Í㬔OCIYPઓ—åÒ¯Êj)p›u¥Å 9;Xr6•õ7\–ãÛW/òòŽœß¿qò¸:¡úc?ÀºÁöÐ¥4ÎlÅ+eêʵ¿öª&‡Žáâø{ÇáI­¬Öj .¬žüËovÊ*‡GÙ¨¸ícî‹z»FQyn0W½¼’ÿøŠ‡bÁ!½¯F°9ØZ«+qK¤é¯îÅ—jÅKÏÖe¼0im«ƒ›øÕ²Vô]çß­1<µ44Dqï´žJpgiBùƒÄLµª‘Ï^ Iè‘IÒÞ7ÃlaH ™áSPh•cÚÌÎ ÙôÎ&ïÁÐ¥wº&§è‡ô-­æoÚy„>;ß=»Ò¤"o'üÞ“ÄÙSú¶Yò¶Eî=‹X‡ßMzzwDÁy&ëëÔ‡7™nçóeïõsœ›œÍèÀOïeç,‘jflñç?\;EhuH»fJrŸæq·:]ã¡/mJ>™"‰wóGÒ É6¦Þ@ceÇ0 í5àþ@‡èG±«Wœñ—l ~ZVòä¿qáÎð©<e>ÈÝ|ñâ‚X8ñV¯¶®]h½d®â¯(_êÊe%¯šò×Ì_P£šÅ™‹ýø•_ÑAͬœP’‹šv¤ËïêÖÀT¡ïôpVs¸¥°z;”Ъ¬^«EÕQëóÂî_´æá"_õ+|úmµÊ/pqbÅKR¯n ú“ÿ'Ç•;Û¬ðsÂÑÏŒ¬5Ôøû µ;Ž5V é¢kÀ(©Ö@yÓÓ=YOÅè´Çƒa6Ýiÿ%këXÈû.ŸÞ’¸A ›R·¥V]âéÿö®novi¡Ã©®Á=Ãóu‰1VZ@Ib§é—D³Û™p—vÇë« ðƒè>°°"‚;á§5Y¥]£.•¨ü\Žjƒ_â3O¼®S§-úŽ4}‡ªC/wË(ôvÃŒÿ_ÖÞ¦·,Í÷ü¥$R!‰’óœ²M»:â–³Zœª±Ð]žFÞêjÈiãhÐ, ÀÍ�ZÎã3ü Aœ­–¨�a�]ø"D¿%jœ·!O¨®tND§“¶ëœ´DéH!Rr΂’-ÉÎìBwo¼0(FðíyÎóüß„±ít{€k³Ú1oÄ®~­Ú¦Û¤!63ºÍ­Y+Ö2vˆ$Qß<\[i,é^Ÿ¼u–J¦Z€±¡nˆ±ëƒŽwPÔi–ˆÐˆ<M<V îFåáƒùÙ…ÛvE?«øU‰¿3ã+SÈjÿàiðÍuOà±ÙÐ’GÃu…àµØ•Ü_çºâ…ë^ ^â7藓ŶpVÖÉmQ±ŒS«RSf#”xÔŸ V[îb=!2ûœ‚£A0ËÌîá?; awø«Ù땃©Ñ¬X.Ê[¥a2;¤˜+úS³ŸÛÃò®˜Ñ¤ ¾©ÖÊEïO>ËÏO ~î»C»J ­"Ó}9`„¸]$É«ígÊ^›N–ŸE-Õ*·evìz‹5ˆºyŠ™žU†æ:6ÉØ?­ÍÖVm’6v¬v$M3-o¸3>oÍCM<^à4ÏŠ‰=ƒH5mMÇТÁÙÂóJ@ÛU ×Å#ïØÊé}ºèä‚ïÞU½–~Wêœü I]rÑO¨ýî ?d¼zÙþ(¹Ð¾®èä}7÷½HëýÍ)¾<^tßs'ú]£Ž‹€ù™<ªõ6ïB£}‘X¥ßöÕö•Æs>¬ŒWÓ³½SÒâ!ôP¶a"P-Q:nj!u²dûhœ[ÒͶt$¡«-lÜ5,™RH%d�ÒQ|¡ý1X÷x™s뱟,Ÿ¼ úv™R þ‹¸umætÒMœ0ý*z]ÈéÅèGróÔ~u ÂŸÔ^Û%®ÃÜ·ÈéBU 'SnZ©)!êÉÀ?×GͧUçóð›Ô~³2îÚr±ðÙ›ŸD½Jä~¯¾ø†êhsy2ŽêN0e3S\û&:¹¦oÌDY9ʦ~óñÌO©ÌüRjrTa&àƒèÉ35¬„e‹, óPlFNÓ¦*µ!µrCj!t숻uÀ Ûm™X˜^‹¬qîŒô·&i·uܮǭúª3,™$'qxg’&v„©Dz ‡mùX§ãÎÙÚ×®c…ABŽË®j4ôjËtÛŠ³dSÓe¥’Ý—· w­r»ÁîE<©ÛF½Þêl*¹ÉN œ¦¥Î!ìy]xÉ:¹n ªÛÁ¯£rÃr¢‹XÒ‚t#ȸÜ÷þF¯®G|„ÏU&I:$…¦CBK7:ºÑÔ¬rm;&$µÉœñ^g%tèÕaeXNŸ=!ˆ‚’Œ†bËõßœÈÁtT`séÊ¿§ßk¬-«AYÞƒ”*+o|ìÄQ(ŸÈJÙÊã̘Ê~YýòÑàÓ@y"6—e´*z}B±±³É•k‹ŽWY²¤º}«rµêUô‚rî> ùÑõϾ˜rô´zX¸Ê«áŸPš ƒ‡“n™£­Òãà4àøÿå ¿-~Çóòêbá(=„åƒ>‹òÞk™W­Pɤ…G²„õñ‚\u™zîéG«ÁÏj'§Øšx~_ìË>RíK$øFhqi²SgB“tÏI.íq®N½{®6ˆ×ÎmÔøTÞ:3SHÜ›:¦¯äùÄmçqžÍqpÅyÝX×\–˽Çé¢ ë™óÒU •wDÉ…3ô›Sx|UIvÉÑî=³Bë?knhýSEü¾<ë7€Á{úDû2ÿ¦Ö·ÿ•œkÖo$ˆ—/‘¼£%¹„æ7/µ–±wwãÍm´MÒ¾Ô¨Õå#iÝwëÍóô×¶îÂ2ö<¹,ëiÒfu'UŽêøç JŽ= Vay,¬¨`GçÞS (£Áˆg+ù ;Ú-òkOÕþii°+^VúpƒQöêÕç{/Å·G÷å®tû§ÙÑ0}ÖÂI+^õÜ¡z1§¾¾I v¯3y˾°¶Ø'x®üMëæíãœ(Àÿî"ªõ ÙVÝ2Ódƒíàøþ Dr‚Àºøw€¤þ“âQ¾ )ô‹“ú?ßZ ²M`öyÄQøtþˆ™×©˜bž¾(â;yç/«r4š¯„' ¢z]wë>4FVê¸l«0QÞËÆ\a “@”k‹NrT[«u½±NÒÞltuÜbk‰DB› ©»;ãU  Äk¨–ivÑvì†ÒÒI‹tAµÓX‚Àž¡…†\ã T^¢B„«'í4Û²J Z›‘î¥oüSï‹’õãn_,û•ž€5\‹hÝl`œ[iˆ Œ÷Êb¬0ËUø[e!Ø!“©‡6$‰¯7@æ4BhÓ ð9èÚÌ)å6CIÜ6]¿â3‘÷¨†i4ÁéOssv(éÕf+¤æôª`Ë¥.Ô«šÚ6QÔ Ò  bè†"‹‚—d޲=Á]pìéGK Õ*T—Ùêƒh„½þêSøYcà]pÿ•Õzw)¹Y%¾`sðó8+åjAŸl#)(áÜ[ <ÃÞçÒŽà™µÕ)’² ¨•#{çäôǼdº—xq"†ÓþÕˉ©ÇQ™†i¶§gœüo4F·cöâoe6àûã|k>Û.Éå#çO]4ÛWs6*¢ Wü>R‡²»Wà"°1¾{ëwîôDͺìNîK“Õ©B 0ªbTMÚX<‰×4h@ÒÑ1ãÀmèè·GlIÒÒ¢}ÆR}s$Úªsû’6-iêKi•oJeþC•ó<Ðìý•6á’§ÜO½äGƼ§y\\FÃPãÖ÷®˜þ<¥ö B¼c>ÿ�¯©uõ1Ë´ïkQñÅ·û<7ôÊ%ÞmŒï¦ 5Ú—ÈaçŠ_¶ó³çÝ;i›Ö[÷U°g3„±ítÐѪƒÛ¦æêªÅÐÔƒ+i´"[Äwµk‚3Û;uÕ¡’×Ël†R—̶c@ê¡’z~ÇW2n`á—®¼r4£Säim¢Âáqv<]{ý'£É)1¹Œ˜>.~tãÞàGJLRyU/O«ÊõÍáÇßè :Àº€ê!œR“F¢‘æF)}ŒaÉf^¯Ž´x ƒèSt™4(­¨¹HÜôUKð 9ã³Á3sø'$ì‘Êýôg‡Lþ¹_p”f£usŽéBLcOgÃýRuÒVüähïÅ <×?™È¯ï?.•sÍ„·É$®…^U$‘L£JzOêñBÒ“ŽßP‹iä›YŽb%Ù1Ý6n‡Ø4«Ðš³Ðñ¼o,:ii¨7`¼ÇW“ŒåNuœIrÿ\Ç¿0]A½áŒÍÍ*)­ºZ'nkë£Õnà‰XÇËAQþíãFé÷0ï‹4^­ƒ‚Ôç:sJ@²¦£Ž¶²N¨£€í>¶]GòP¢ kaµ…w(Ì8i’\ššC8ƒ`uGÇXËÊã¦M¤²MSí/)8§ÇCÌ'-âpÌ¿Ô ´ (dšxb­gáڛQÛÀ#)†iwtÝ"ÕqÙüÜ<ö¿TkøBI>—Ò• ì°¿±”A2RtDÅçÝ@â~ótr¦»4R}ܬ/žV=Îû,È4¡`¿è®¶zWßs^íz‘÷»ž-•£_ôâ!ª6ôT½*•‹/0\þ|ôìëÁPGYô‹k¸ã"úÑ`¹q,—Kpœ's'sÏ’¹ÓEÜwÉl¡^ËÞL½Û%ŠÀû’²’F¬JoUÑpQE(ì¡´“Óv$âo‰ïûÕŠŸÀ,qŽsQq3Å¥tLÒ¹è¿`’sUó™DÙÃjëR==ÿ¶Ú$­3kä šÝ~›œ .VùäÊèpŽ$í÷¹Ï½ãÀzq _ñ»»ä@aÞ³Š¿t™ü5|âÝ#]8>' Ñú£ÛLûýç’ßlûªîm{lŸŸñðþßx¯Æïƽ‰½ò2ÏNgo?øÜ^1né윕Ÿç5Ƴ‘¬gÛÄ6MÔ¢×Dv¡U·müÚ8²Æd¹M:&y‚í°!YS‰Ù„™o¤…ӑûú©ûÒ�ûKõa`‘ºÿ¥‘óf†ìt¡Z1ðábíÃA1qP*Ä8ñ|àoÌ‹üC ]Ì8dÅÁÉ-Ãܦ»¦CY\GÎÕ‘cÔžªG%í…ŽH¤¢?V†¥Güƒ¸~HXdÁœ•ý´¼ðàÅ EEýáÑ©‘Çv¤8Üôƒúëç+œŇro’㛕òôòÜÀ—KÛ‡ýk»ÃòsÜ?ˆ£¡üv.íëb’ÜÔ£ +ÃjTYñXÒ: AÖcgT+Š—t®D!ÐÄ-Ý�Ž·çô厉ۚÐÄ­Í §ãމa«3N{W mºœÙÛ5�ôY½4*4|¡iÕ“‰ƒP%²N;vrmú­Â éUŽpzEVZR[#º#+×äiÖÁv­Tµê«ãïcÙå&sš¦Q-ƒ qFä:–l´±-Ó@‹*¶ªj!U‰ É‘g«ÅVuŒréXÔA Å@TÕÛ„©%m¬§8´!¯ Œ­š¤µi›Y³®štÑŠÔK-Ȳ–F8q(3þ¬:Ø$á— Õ Õr:ºáeo§†_î1óø òqT]ÅR±üD"² Øöîžîñ÷eµç¿d5(5ÈZÁf¯Dó^Þ°Çì#W©SàCT5"ß^ Ôw¬+ Q «?f¯÷Y¿6ÊÜ ×ø&P¥Œ—µà€`Fº©Qp´¯^çžòàhV\_ˆ'²Ý öúÞ† ’J=,«É• &TYd{?³§ó*b’ÕùêÖȪOÙlÜGV)µÙ2§Ç*º=ò— ºKºñ<âc³¸©“v=¦®ÜXNoÎ¥�šI‡nkLŽO/è®ôÛµÄ9<ù°eÆ£ÿy0÷Bq›¨56ƒ9ï@í æ…*·qqïߺZE/ñìÛWQŠ7{û‹æ€ãzÂ{ÄdñåuÓÛÛþÏæ°~¯Ý¡Û¾J6}“®sYþÇ<ÿÅ®ø}¿«~î«ÏÓ^UÉ·¯ŠGâ·ÿÚZµ°jîL)MKÛ.ÊA“p=}ì-èXÒm Úd-h›ècí?7UI_D" âV†Ž^H„ñ^ÛªQOaÜ u¸œNa_ªŸ|ɰ*Šë~êëúõ(=rjòÇ'üóéª/ö«•×”J¿|=‘²oݱrHfzrZŸL˜Ùoj‡¥ÞÑ‚š9åDˆ©¯WöÒpÏîÍ©¯¸Ý¯»0ÅÛ¢¬‚¡uåš-õj£¨\ÊE3¥l þÞGJúê4óVî«^é‚[ŠC1¹°rZ¤3ÌݪNLô_œÜ‘|^ì27=U“¯ênÖÈðþá³—Gs®Tðø·bÙd-è¢Ä&yf!®ªäI]- P~ЍÛ5·!ÔÝ<µ²7ÙX7«k:é*Ô6#ÒxÌ8þüënÞÈŽÆÛظ{ç‚Ahr£“V uÕ6´ëšÜ¬BÒÒ1fãÿŽüso%‘G.òx—ÚÎÏËÈÔ6mÜÖÝÖ8•d“p%öl4ñëØµ7“F¡CxÜDu°ÎªÈ[„öÞ,}ÄΗºêØ– ;JI+šÈHUy÷NÑÿ Ù4; ÊAZQU¾/¦ϱèDž ¡ÄšÍ:𑎿L7–l°S+ã>©² ôr…ÖÈ—k!S/¬¬(†¸2Õ-É{þæ”Ü=*NûnšìØ2Òjá3>í[)•ìYˆËËÝþ¢ü¹ï1âE —#øò™t•¼¾ÍgQØÏJ?‹žçA  ¨Ì–·‡j¾°§&ï«JÊ¡°s•åãþ€‘«ÌV†Çb ÿpã¯æèΈç¿ ìT/:ZöCû5êOËÅ™gŸg%uÿCš*œ�� �IDATT¼y^ÉÞl¨QÖ¢SU?êÛàŽrÈ{œ,ôN§Ô—ûö£>»6Q×gÜÐÏL7ÔÜ0Žn\ƒ¶I¤Ž›ç=@¾4¼ùùŸéÔ.ê]¶ú¿˜hkT“Æ÷ø\ôÀx×iã{ëÛ¿· ¿½ÄûVýÉ;ß}÷ýçdûüÀÇß³ƒJ.ø^Äï3Z\Dçã÷I¯ßsÞôÀäò“¼;gt/4†øÂPÖý·XXI‹îå5ßhHÇ-m£H{Ò¦‚H@ì°ÑNV &q†6™<ûÃÕ¿1 úB7¼÷ål[¤C`|…†0ê‰úń¶=yª²QÕI[ž÷•Wv!J?8µ3¸ò•¡`jIü ·ƒ™Å#ÿzbsª–f–™±b¦–tåõ£…#u:WÍ1ÔO^rýëÊôœq{6Ÿ‹ö*õŸ Ù_¢På2âš«yʃ¬ïô`6ÛCÿ}I)Áy(Ša1s¸|í`YÀgéâ$û×ø»Áöɾ¼|~zMΑÁî¤ðhx¨Ü³—/\=é~kkb¥×-w Œð™ýH+¡»–å#±ÈØÀ0 !Æ¡]š%>…F«7én˜ìlÕ«hir‡iÒbB[ˆÚ$’Ó•úÌ]Y5V·ÐLÕ˜Šæ ¡îbjÔØyV! uÜ6tT6K#ʉ@âžCcÙ.\]uI±9)LâÈ@¬AלñX@.¡CHª–”¢HnÜ4í¾D¶—LÊéH"Ùú¦ïþ#ä’è=9ÊÜf¾EØk[VT£Ê°.>Êwl£­³¶^u͈¼N›Øiuh6Äÿ÷œè ¥ø»R=j·¡]õZ8\®ehQoFÅ@<ܱôÙö8÷¸üùÉÿV”þêPÿx2ªñˆojô(×”øÕÖpÆŠcw¨¹åÑ})bê;Òe9Ã!¶GM~†ôîIÐ#% D}ϨϾ±eªô“w˜&†Åüb…Ÿ=–nÌL3AðÕmKY=VçµÿeAÂ?'~ïWÑHä%Älµ§ E%:î%3•ì–ðÓ‹\ÿ™š¦qk¯8âDͺFu;zÔ¶<”Uø×&ii»hšoºã2Ý<s,Ó“âqûmXBÂ;ëës¨2–ãøzs~ÙLZÄMÝ@¿Ý#uÞÅ~uò¹æ;ß|Ÿü­ûjM¯ÖÆö•Âh®TÚøû¶;mó^éñÄß Þi�æßD3º­÷±©Þ'ŠŽ¹8½ÿÒW¼˜’÷õÀä]×ËÄÓ·ÙoÏ•Wöæ~oÆ ÓhGJpWÐ>Oöh!›6v4¼ þÒWÖM‚QãkÊ¢q:vÚM’ðlñ'$2çïDR¯![¨UêO=aˆ ÌrEyIàåË7ë÷ƒ¾”‹ÕÓ›Q‰êi©6àîþw§Gê¶š*O‰¥Ñ锸y}¢By¢RúñÌÌœú/3ý×lS½éb.““Ìî?ÊÂïæ/_Ý«ÑÂqÆ0ýª\:˜Å‰ˆ…l0ÏíëÊ °׺œ³<ª‡ Á ‘S?ñLo¿œU“–™½ŒEk'ìÔý8ˆFÅèYm¶äGV‰§JóWCÀòÌÉ,ŽøÀc±Ûzë#†Bó%2d©÷?êù]õ¬N³ÆV`í]ÓÅ$޾;雯DkÐ2¬·±’dMÄë)Î$kĤ«­”&c]XâI:tÖ‘`X,¢¦ŽQ±7@¯»I‡¸=ö2P«µñ´^¯= 6–q¦†—*¯7–ˆv°aÚØQø3W$6WQ‹¸CІâPÓf£¥ J¦£{H°Èhï¹Ê>¡ñPèU´h¦a{a¤¨ˆbKù°á‘Û V2§³\G¿†a6ÆT,t" ˜DjK&¥ñwKÈ¡úimAÜ ¬W½ïq˜F—(ÐH“ɨŠ)ÕóÆ}îýÍ`+ŒDµŽ#È™—7óˆü_Ìùbä‹^ÝÅ9-†epEy*®¼°n_|Ô†óyá»Þ0’JZ·ë"OÁNy–äÒÏIЯ”|w·ˆ~ª—‹;ƒƒbùDìev×ï Ç…ŠÁë¯8x–ù—âÔ¹Ù}Å¢øqì¡òîÕ^ÁÓ‘·Á~¶˜eT¦ž•øÆÛÉRV ìBõÕÔO·iŒ¼˜9ê’Qí•rËufkþ§ÙëáïÌÊÇmâN¯›DÒmƒc쿟ŸG»o÷†øîÚO‡¤C™·ÒXÛŒ;#¡œ;è­ÄmX¿ QxGŸ|5/úÍÅ2_tm8¯TI‹¸]¿ºÛ¿ºÑ\Œ=nK%ÚïlqΈšÿÞÜ·øû,.Z?ÔKoWf†÷ôP„¿#q¸¢z;ßç¼Á�.m„’|-gY=Dçï49ó¦—p¾¿»r•±…o¶Z$mÝkëî’N$½ŸäQ,”€ ì�™ÒB¿v9@Mâí…äë²îº}ˆÔ·wÌ¢Ô‚†ê—EâÁSÄáæËS¹p,œ få.ó"üîðÚôì3ÿlz·äOòýI÷¬ÿ{ƒï¾òýRE|w$Jó+¥¡ž¼Îéltx §î®7®g\ÏÓ]SÅ Ó¢`uWˆ’gZË9½³ (ÕKºWÒ•Ÿ~¾Yò©ÿ¦ÊÊÃ|~ª:_Ròuõe•‰¹hj^©ÅC}\¬ üh¡W¼²ŠãŸZPŸò€’ܱþ3òÀÜÙUN¤Ë¨îÝ´øЙg¹ú¨>¨å›<GìØ`h”شݧâ¿Õ¶£ÏzKt×j´ôêºJÚĈdÉD.еzÒR êgŸ¦Kï`bRUèuM›¨£¥`µcºÍz—HHõ>¸÷¿ÿû[a”üz ÞØuÆ"©"ïQ.üNEœ–¥\¨~üÙÆâgíÊú™±¾4 âV=koŽ4F'AÚ•éj'ýÔ™^ˆuõíÌ: ÓÛ©ô¨«çP5ÜŒo¦I¸É:–X¿÷7$:R!Yõ(L-dõ‰^-ôªÓUäi ÷¤æ£GtTU%ü”GeÄ×…¯° ”¬¹²;º»eΰ£ÕÎÊ'èl§Žƒ_Ô󠨬d}¸Kòl1òÞÓÕð#Wɪ«OÂÝ*%Ñø8]å¾øbÁÏפZ,e‹ïx©l©WuJ ËG „( 9çÜyUÕ“*b;Ü ª~wsq×L•9XˆØfºì ªÏ¾ ž‹h‘èGˆÓ¡˜8ÆöjÓn´2w}y"àNg¢ÉkS<ýSßÑÔcu³ˆ`ãGU†§IlLq2Ã8í3ª½Iv£Þò”Bðt¶…$²ÎšŽ›cj‰N–R:$˜h‰¤Ú´uw쟖Ãß¾5^MÜ8ÊL P»ùÙÉòL2ÝÒÉéÃÚ8@ÔœOßëô6–çâ²ú‚)Ã[&çåË+k•ø‘Ýø¢sÝUVŽù>Ë¢?z§ôƒóAòŽûÞ;÷­ÿ×pHi]]C]Z%µ/÷§Ö%zo|…†Ô¾?ÄßhÎåòçF÷’­~ '\x‹¯xŒÛ66½¶ŽÂTIcwˆwt,te†'(6{²®¼ñM›pfÇ8–\!Œh)ú~Ž@m­×3 !Ç*†6"·Ï|Ñ»iŽ^d»}/ž÷þ�˜)^¹Å™íÒLðÁÌÔáÉóŸsãdrïôˆa.ìÓ‰¿ø×¯ƒl1·'™ö³l¾ÆLœfV¢`Žà&|P[xm™f0¨W¦‘·ª•Êæ?ýxERŽÓÑbBTçÒQYŒxÔ?Vd´ bå¹Õÿßm;œÜæˆÒi_ö#÷*£lpÝLd›“p\ÔŽ½âÀNÀý²!·7öTyICm¯ö¶Ýî[9¬Ó$Á'ƒ^ìS®PÓ´”+ƒ_QNŒmqÄ`;*ÙIEçÝt#·1*Yóª¡We–tüØ«Ñ6 ƒ”tè¶êÿÕu!`­Þ;ÿ%øæfϳá¢F'µ¬ÒæOxñ?æÃ4^Ò8Tnº¤Êm®‚d¥íüàŸGÑüÌí?½q£Dèã5%šDc‚ŠS¶9¶ØÌ6šluáêIÓÐQNŒ‰Ñˆ:ëÔÄ€ ÒC_õXÙ¢±‚·ž~ƒšÔŠÍUz±34ê±;;œÞ$!In’‚¡+gÔ7œþ+÷H}þ nÚXÔg†£í Ê¿I^o@† µià džÄJ“´L„AêÌ‘tŒï?B¤ñí½Î¾\Â_·÷ÿüË`(ØøÄËhˆ¿Á®Ý(of|.fɲÇv”G‡÷,72YÕUëœö»‘/¨Š›táÉ‘ð·±|•ÅÏzãêiýï&žÊ¯‚ÕWýÞÔS?ªÉƒ¾=èmÏ–‹ïwÙPŽA‘¾¸AÄèÎ`±{:Š*âþ$|pRfF¯ÿÝ¢ô“JW˜·Ù``'ãݽ‡Óø½ì…zÞ«Ù‘]p"´ªª’¬n묢ÙIÇÄRÓ"nÔgâ6« â°wH¤¡I"uÜ:£¢¼¥žÓUÏwú¬¼®ÓmŸ³¢Çàp“ä¢]ô{7­KÀÀ™‘ÌX]{ñOZ&~qß~ßâ¤ý¾ÃqëýeùáÐÿ~žÒÁ;2ñûÜ÷’Ë7´I®øg´Í»W‰ßaš¾uÂ8‹aº4R¼¥ˆ¹‚¿C]}†ðvA*b/+Èß4Ûq÷V­KcWrQoBêóºp*&«cp:qõ‡¤„jb U›èÍE.øv]äiUàï*n²p3­…D°çУþ§YÄr] ëܬL |Pò°<*=œ¼þ€×§ñíá‹Ážë—«©âõD*{ Ù›#ãΩ÷”Õá!/>øø˜gú»Û³óböÇË?™‘7n~VÚãñÞ6×WŽÌh2-OÔ'ÿX9ÈÇÕþЗF½p×GщãéÈ,›‹‡ˆ?èG…ˆ™ª÷ œûùkµ?©â¶gÖ.?˜\dú4ò‡êÉóPÕGÎ]š¹^/ÈÔŽŽÐe‘úŽÞZ#Ð[Xá©þw²_ ÙW`ìXú,  ‡õ¬ÉÆŽ]mAXg½n1‰;kªYgI7Z$ÍÚNšPo¬‘åg¿7ëu‚‘íåÈd–ÈzìŒs<ùMíÓÍíP#Dâ Ä.-7šufI«ÖXÓ•ÍÙî}ýôù¿|îü©¤]÷ÝÍ ÔÇçDЫPYÒJ¢¼jë:["f£©·œiH5TjP„ˆf]5ÒÞ—¦â6ýØÜi-Umýpme«Í†TjÝ$-`D+]E+O$kxzùýÈ› 4¸FËÐÖ‰ç¿îô „G¸p§ÿ$SK&iEYœë¨…DMXWÄnŸFÂ=�»µd„4¼äw}“¸žóýì°È/Tåå_­öa ŽGÑíZìªþZ®Ø‹J}„`@Öז͆Ëäá³Õ§yÈãýgDî¨nE'Ïx>àš•¯«9=žØå¡-•°«˜œYµ=ûÊǸÑü”/{5{ãéâ FG•r…±8%rutû»`^|¸0Qv“Srz‰W¿ÅÇ>²t¶^M3¢;\¹Ë½Þuj¥RpÓsÍBn‹miâAJhGŒNš&î@;¥•tMâM∶ëÄM“t Íq‘10~ðyL½d¼ÐS’–NÖhH_&C6Þ”¾‹[ëÖ¥ò}u)Ò~t™_Óz{ðßÇvÛ—äñ;–Boïí«åÿ€gFûßÄ!ô»ýà¢<íì¦[ïª ôûŸüòíÚËP³½Ø]Zïw’w{éUUºIÞbæ"´~QAÞ=ÿÏÆ[èBÇoY­¦Û‚Ö¦j¥`‘&£žH«Æ–m-j°åêøÕuÔ9UfUê¤m)Òôw–C™fa}èÓÇ×lå°þâKÜmÈé••EG’Oa+‚ŸLn‡2ÁÔ¡£”‰ f¦ÄáÁàÛ?Ü8œÞ[û~s÷õã]9»ÊÁä‘<Tš_úÖß<~úíAu®lg®‹©ù½¹é`ª#±?w<úP”‚Jðáé¼TaífT:2C©SÕ™£G?ȇDŒú²l™G”)JÙ‹Z”j§û+§D§˜Zú£ƒúÂLı(ÿ–SìïNÅäžÞ›MŸ=¯ïMfSׄð+å}%K¦€ËNÝ ±Yqf0ª p"Aâ¨,4Ÿ,¥JU\ˆu5@U­BÙµ4‘†¦îVP˜ÕPÓÖÝ•ÖU„ƱÑ6´Ivè¶Q ¨GÔ•4]L’t¨¡©µ¤ Ò)c]¨ijëÒHêÌå+*L“\ÕÜ€ö£Ø·{ жÊIµÖ³E?ú:äßÝýLY¯Q­3{œ¨MÒ1Û ªR|ïPì°ºÎC«DÞ=výxG¶;¶×|#§±fºmÚ©ƒÌÕ^ÑA]‹ ÉÜšfYâ~˜« ›¬ënH,L÷|£4²«È_P-Peϸ7d-×ÒʺŽ«Ð]éD_¬°dTN¯€"R>_XˆTKÛx.e•þiŸÒ~WdËþtqõYùÓ œ„U ú<‹o:Uý üÊ‘mÜ ŠÝ;”(v"Ä¢µÃT¡³È»’âéPÊm3¢#”µý½n)Šgmwî§¥×{w¾•bpÄÁ•'&å„χ¾2äÙÐíŸ~ËÔQøÁ¯Ÿ”² È^¼hL÷{×^6æ*vñ_ÜŸÑt‰ åç |­ìÈÆ¥µÈF…Z®ÇNÌqWÓ$iÕi¦´êㄱ?k¦ 45ãŸy¤ºœAÜÔttc¼hB5âŽk ’ gÓ·¤ù )“oÌ{Þ`Ýñ»Æ­÷ZÒ™w'†ÆÛ ‡÷A¶­ ㊊¢õѾµÞ/xïŽ(¾¡´ÞÄ_9Ô_êfozÉ;I1—-«.«Þ=ï¿í(Wt€ÉERã¹enüŽ­yãê«3o Út×µ]‡¶o¬×c4MT œ¶Ýmž¥A86ïHðcMñ¸¥i×A‹¥ûE]­á\]ýV÷Ÿ˜¬)x†õrß*O ¸7RÛN÷Ÿi?…dsvÖÎÏÕvPÊú0äóå—³ÅÄ”,O1=ç‚ý¬§¯‹™ýG‡_ÚÑ„›œ ®õ‹¥J¥è߯¿cútûõë™o÷G3S ÔÉÞ‚ªÉ]{»Ô?9}°?!s¶|¿£guÅãçzn˜ºƒ•$ê´$á3ž{1u{ò!L«»“+‡Žý§¢äÙVGÇY¥0 ­#ª:%¤H\ ï·TVÚ”"•Â�J/ªËym«,Øë W>~€b€uuÚuåT}c»˜$¤¦´tœ×}ËX¬µ$E¦²¥mÓhnfv=ꮤ‡‰‡š2›´êHT[“cÛ(lVi¼£±Êrh{.Kä„êJµÍª¤Ñê5ÖUämÆËþɾ»Ö_ ¢qî“íŒÍôª§é²%O¤í5!4ÙŸ®¥É´Yu6ruHŒªá<’¸SOÆZzgèPGêX’PWMl ßЬ:–ØnÂtCZ–PkXOwMYW‹Ý±¼!%ѶGˆz´„B'˜Ø¥ÛvÛ›Õ†bé3!DUÔ+KfµÀ.éå`9¨HQ­gR7ð¬ZrÙST÷ìçõ|»zç~tg†ÉÓÛÛ%5/ŠÛýÕá/©ÞÛøÒÊÒ@å–%Q*ÓE ?¿7Â/e¾Ø¿ý<Û¨lòBò²NàØ÷IX©9øò~c>‹\ÑCZlM×äÔïý‰Û[,˜C.Î/L.•˜ñ/§Žr Sƒìƒërpòâdòw‡®Œw·¿W•JHHàG~þ´rcžÞ©Oc!Ôu’ñ7zõIiI6 A·MÜ1PO:ç†ÿ.§î4Ðñ:Ý_kÛFµtâ ºcëÖ¶aÍœ‘…Zg¨g·-“8èè÷Æø[é"]õMóà{”Â]1â7'ÔKRç÷bÑWUÀÝwf—ÿ¨öí½ tü}ãÅ óž6s¹›½kËñ}$¢÷Ú%M KøJÑÛç¡oâÞò³ÍÕ[ÒøÚ6Vac«%sÆÑÊMœd=Y3@£­mÆœÅFÛD-z­Ô.eS…Ù–©E+Øtwt¼Pm²ºcTžV;ˆ*Â!BTg¥ê5>Ý–Z8ÊÞä}å,ä¸cëJÙW#=üʼn:©ê4“^??Lû_xÇ ß ±pŒX¬ ü$”®Õ˜ò#1¨ŸN”^ |½Ü÷¥Š×NŠ£…×Ã×”+³Ó ×Ã¥ŠtžB)Jbj:^HwÍèò’9™¦tK-aÊÇËb¦(Ne”ÝÔðdÁ³; ˆ;¨l~X1pþ±ª~¤úpýš/-ãwDPXë™D®³<ÂIdÁxŸ¾= óY5—`VwjU² ‘ÜŒ°¾Ñ&q¨8 ýÔ‹¦K :’4rÓ“õHØ^[€îvWb€šZ[itRvÔ²dxBã/uÔ&n*;öÚ+‰ÿ–¸¡Kt; ò¨&#UÝìæXYÏd´Q’¬Y?þú¹'òÓÅ‘<9s篶 µPÎÃ]ã n[¼Æ©~§Ó‡Ð&û(<Q«°åô8&阮Ա#Û¤Û$j"Ú›ã¸ùn‡Ä‘4µj«¤·M¡ÅºA`»uèáÈú÷··?ª TVIgÄYh¥Mˆ”S[ëV,néŒSh%Liñ~Qú%}7 ‚ÆZÄz±Nñ+Ç’©H†‡ÇìÍ ÷Ì»_æËÁõÝê'SýÅß4®üÒÇEI†wkb‡þ³Êà°R,ÖòŸTª7–eÔßñ™*îug¹¿è8Qï=±ñÛ®Úª›ÝBg;0_D•ÇŽ¯3FaqRÉè‹ý“½ïòÑÄ‘øºØ›·â¨28É8ÊÝYLŠC¹}jß.·Ãþ †Yw7àÔÇ rù_ž¹“ßì=®ý¾xøÌ&û?´’©_'ù…y(t≿0g¡/NÓ1±#é@“dŒ;¶4r£ZcSÈ34‹æØìHqÓÒ>‹mhŒ=Y/æEw.WÅæ{ qüvMb’wôÌWÏè—|"Ì% ¢ö»Ë¢KãErÁŠ4y—ÚþÏè ß»nj]5�yWöܸà^w KxãÕºškq©¬¿ã{Ñå-ŒqÑÃ$o ;g´¢q[Vo û 1öüÉgýü’ýáø(ñfp±ãϯ -l+¢¥ã&ñyn]Ý6IH7d¢® EU5±4låT¥ù¤ÍJ.Õ‡9À/mVrm¥`ªUp ͶCT5°‡¹³«gFÑOæÒ㩞Ÿ–§¯«¥)ïIú­ß=4Ls}ô”îESßö_ŸÔG3ÅèõƒÓ ñÁÄö·¤øûLøùƒÊÄ{凘âhq²´ÐÿàðÙ«—¾<,÷þ×ëîÚ´(&äÉ\xº»YYðr!cÄüŒªÌþãÔ!'Fý©ÉúI¡¯ ®õüT!pàó‡/³‘RÓA‘V‹·ëwêá¢ò‹ðç¾|Ge×Òš«÷jõþ ®Yy‡{‹HŒw0²Å ù «Ô¶Šù÷U?ònIcÍ R[R%Pž¾ ºÝšýŻΪP‰TÈtu8 ¹Ùh<¢ed×taŽÀ™›ÉŽ Zf ‹ÄÂVËDãñ±ÎXêYk·Â“•jȽrªš+¾ŸÅR'B¢DÒù¬èÍŒ¦32$‰£&)¡»’l}ü¥Ò¾¯d“nK'¤±³¶Ðã4ÓÝÜ,P–z"ë=iºÎ*ˆ›Ê6IÐ[áÙ·0k3¾`›DÕ¦Ú²~=*>Ò¾BäÏuœÃNZËÏÔѵ©Ù~Tk³¢ì– Iš QÒÛ¥ºóÊt¯o·='U[ R9ÒŸÃi&£­N„·ü:£îsÖQDÛ;ÚqâégTä­gÔ_g 1Ir0îLz_•ü<¸ûg}_„EXôû“ƒâ…´B Ë/WòC™ RQ21ª{WÛYQ¹†,mò×ò#JË'«8Êxº­ì_¹ruûÛ÷Y±±ß¦–ïO!'FB~••\mR1½÷p'¯U/>FÑ8=ìߢüRº¯£¢ä“@ÅE‡4ʈ¿ Y;‹+¦Cc¬_kꤕŽ'6ÚuÛÖçH3S!<kgVo-ºgp±æ, îòÚ|\î›o«brŽ $WÇo*¸Ž1gàvû2·µ}Y#|n_®¥Êcr¾¹‚(tß{¶n_mÿI½¡õ½”©äÝ•Yë"8~¹•]öLåMšß˜÷n+-®°TÇVÛí7'ý3Bí›ñ¢{~«ÝKrhýÆÍ*9WkÛ ¨MË$@geì¨q‰KØ–!G®Ñí¤¾÷v§D£4’M 8ýÿ„›½¥º€²4Bš? ¹WèLRÖ—I½Ðq¨PYBH}D:…?={'Ü>.&_3¹[¯ê“3öG•åiäñ±¼uâ7Wƒ™tâ`e¢’2é¿~í•ìÞ¡yy‚e»ôZ ¿;)&j~⳯Ÿ²{"ýÂNQž8ˆþÕWg*^–¸6í‘ÌГ¥hòÇ#{ø*GQÕ“©t Žôé±*S§ÃÓÈaó¯–÷Žë§ LWFYq,çqåãÏNxtmNŒÈ–ýÞÛ§vù•èÝæÞ7w¼.)··üW“ˆE¸‰Yä®Ü2µÙ^qû/î¼H­ h™.ÐÖ^�&Zª7¼FP-¨Þ‚Ò,2%¨*)bg¢Ä÷âæJÒ~°ÑÑÖ·£lÕ~²d=ªÝÖ ׿a[vuæè¶éžÙî§´y¶Å'9±rÐé.&rúqá£<+ª"Îù|”ãôص·ƒƒêNºœå©b²N[Û®‰±‰Ô4)Ü™¡ÿ?ɔÕì®%|;£A7ƨFÇ )ÖÌ™…g‹m›:j·ÉBšíެð¥±OLæhv1JÖÄb¬£üj´8W•·¶‹/WÛ`5�� �IDAT†òþª×qÛàt#¬âR»$ý&–5Bt_Ø^ò4[Bá{dݰÖí=Y‰*ˤ,‚è/ÿ§˜ÎC×£Üö6wòí]ò€§ËsÏF³OÅtÙ¸QI~%ÄhÅOò˜Pìá¥#Ë®ºé¯õ”´þK½"®¡výð s#jÓφŸ}îüjðªà¥ªN-wK8woN.É{LȪì†Ãü8øT,æE¥Vª–-[§’ªèÏ ÄÜ^õÃ,øæhãä…Èõ£J6²qÙvx“<YixƒÔª­p$’X@Õ2Ý6q{¼³NÇRy zó1žð$] Û!îb;ç°ðºþ!ö湤`\a­sc× ÌÑøM†X['@ˆËñ WàË»©Kv——Ko²Þ¯*k}ï²ç?Ö¾Çséü¦Í»&Pñå–ø½›«ñÁÿ¥õŠÞï,³áÊ›xaƒ¤ÚoÞ—w¡rÃ…VÑ8œx«ôî\èÆíóÉæl[ehëqŽkƒ;#¹FM,†ŽŽ1=ÎòkªBËœ­¾]Ö»hú®ñ¡‘’²w7ÌŸ|ü1ª&nÙë®b"È ÎR!ÁÊ› ¹LíþB]Ìùë7¢gÓ~ò¸?ó×ÒãQtüÕ`n7ß+ìP*mŸN<(ûê·³›{¯ø×¿L¨½ÉhTˆ½iuüš§FN쪪—×_æ³þó{ÛÁ«•ùbxl)‚Qi†^í)&ðE:õBMÚ bŽJÛ¾„ 8)™¢Diò_{T-÷ÅK#ŽÁô|4šC\¯^ó(ލ,Ž"ÌÂs>AÍýªx”ÿBÏWÓ’³\»ÿ©3nW…³sš¥í¨Ù3^”áãž [ÆæZ9í]Š�ئØ~êÔèI-— ÷7*]y¯¶žÑ¤ Q‹LnÆRYi£'$ÑÊaÛFIªãÛANÒ0´ µ‰Ó Z9K!ªc@¨'ºÒ\Ž¿f_ψ˜_Ù¨FË}¢?#|A,ñ’A«>„†3ÛBwn åè6uTEaüRJˆjóBÔfQy¯ÛÒ4±°š ©­#v›«³SaÜ;¬à'…9­•À€VhÕÒ[².B@SGa¤–l¿ üžö˜Â™ è¢jáfòÅ69)fO6p‘³FæÄÎ(i)#œ¡‘÷pø»& w®÷¢"`'{e]JwÜíg|Ã=±CI2R J“wò½~µ ôµ1›e¸º¬äíi5þ¡Ün”</"¼"ÜÌë ·Â÷P<¯|r2ÍÛ²8=ñ׉؞ŠÃ)(ùøÿi{¿ßFŽü^ô³"»ÙTI-iªVZÞî»ãxœŒNâ¹{gFg.èÅ@|Ôký7üš¨W=hÀ/ˆ�s!ÀF²›Aîøš³ r׳è¶eŽ”ª‘ÔR‰ÍnR{(iôË»9IÎûL£IIßoÕçç­çtidP]6×åÑŠÆB2؃y¸ó1VìC•ý–¥ûÉÆž|Ç™ výYŽ„×ÓKÀ]!P¢N=PøJt6E§)ê-^w.Ü‹SgƒßbWö©¨&Š ¢€û¨‹©Ým`óS(ü&:à€Gûµ~i«º^E\¿<Ââ&òÓÁÍ<×Ö7ܳ$î¯o_®Jß…•þ=»á®V׿oÜ·< ­› ¥?î–¸Í÷¾[üºÕ�ÍÛœ .W4p¿ο¬ŵ€Õë?ªéfºB¢‚æÄ$ .LpSØñÊØ²qy‹ìPp ŒƒŠŠrQáÿ`qâDè„Ç ªy%‹?ÝY™«Î¯­ã§°Ì®€R—¬v­ÇÕGIX]…:Â2 -z9_ü>Ü;E!ÒäÈ™9sÊÇ@R`z0¤§´ô‡s(Øý1t©€å2Ë~£ÊÑâË@–4õþ9-å¿þ–G8JQV÷';¦©âÌO>ݧ9["…0#‡?E¹øñ~޽S]xȈLѵҪe»¤æáé%¢G=‚?åú½Ž–‰i”Q.§y®ÔÁîÑBm\&çïy¯ rÌØžÑ£Vx0K�Fóî.8UR}UèÆÆ¯ôÑú u"ÙQõ¢%£4!×@:1¤F5®±‡D*<£=7ív~H¼ìYð[0Ú }UñáÑcæè¶–÷ ¾Kù˜ŠL Û5Ù ý°ÆÝM±½)*pA5�Ý÷*´/ô\—DH…=ÀgDãÍ@Ç)T%ên´*ßh€˜ „‘¢*-Ⱥ”›\Bè‡!SÌÿï ²NK0@o"R¡OyЬ¡6å9§ò\Š:À.⣅Œ±[Ç %�Dh ÏÔ[�Õ0‡ˆ¿‹w©âÓðséx=€} ·T±�¼yõe¤¹¯ šŒ(DŠwè4@Áë™›VmkrTS•z,a@•éc;±Tú(7*û§Hež(µO±–!UP«oàý>¦øxáS(¹­Ñ¬¤À¢$sš%eíZj{ÎÒKÙ ø=Ò™ãýʹùÌÐ80íŸí“y¤%Ý?Ç£¡úã{Ã$)eãÓ¤ôcÊÆ´¼„¿'Ñðç“é A #Õuh¿Âƒ7øð ‰úTkÔ@ðih6§ùH€T@Ó Z�BÎÚ.~I<ÒæÁ&ðΔ@n\É  Ш¸6j„¼âP¯“ Ç\¿yͪu‡U­ßdsýPù×àî{CÍûü ­›oÕüÏØ õû1%~ëüë{÷p ÷þà¾HÂà:¥|®i½;ì¿ÛmqWPËnm—ËOq‹ú¾ì}}·KëSÍkKø@¼Ó|×â4>_ _äÖôD+êk°ëbþkvö±&Y÷»68 h•Ò´<‹‰BqüôìE:úVꂘ$\ÍF‰ÆË~ÍVºg¨}-ñŒ"&^éøi€7±ÈüîË㣗3`rˆ|Mr‚#¼]ÕñX9_ž¸“L¨<yãÜJy® ð¯&zïà &…J¡dlVXQ“7Þ‰å.Nz˜í)È÷Ï©,ˆŸdšŽ¬³3](ÕŠ [Ìéüéø§3Úþ‰£G¤(ݵb4¶z*[ùý죓sD/ïqœT°â½×oÎRœÂÈv¿Í³!TÙ tÖ5ŽEiFÏ~:_}OÂ^ÂBÑÌÖ^¨ýZU UÁeˆà”T:Ë@äÇ\¦J+.[ h ÔYÔ¤2x)@´ë~ø<uµeU7åÇ@*Ú¹È*‘`[³:¤¯š J¸Øñ·žS�‚t.üf(жØgªÀ…lb ¡.,G@sË`åjËÛ ’PM{AA»Æ ‰Åª±PŠ%0�b B…»kð[ŒUÊêg^r<R@#¬Oóe[Üozh€]˜1½©lA¶ ÐSă¬¹ã·ð¼¦ø #”ŤBO! °µ¬œ¾èô‰"‘rº¾¦àÒ®¯#yíš©Ò`�¯ѧbÏÝ’Ú©ùX Ñaø‚c ²qúpP( ± •E5HŸ‚òÌ>Söì|4òt_§y_Д(€®@¥,£ôµ’ûÇ"°E…ÏVkòÌÕ#ÎéÊ©&CE[ï™#›ñ"ÁÊÊnJ·Qñç²Á÷¶>Qš-TFfÑúäæ ”`ϤK¢Ì #Å‘ê¤/ÙÉNú=6NÕÆFÍ%Ø€‹Ôëd!Óð7áÛ¢®à·†` ´ lòiðAKh„’¡©Sª)�¯¾†úô—¡!ÐBÔ�šœµÄ¥wA\ˆ .ˆ<PSÙë嶸™µ‡k ·¬È×Ëþs÷i×2ü;Š¿õƒ¤Ä£þ½»AüÓ÷ü›‹$¸sQò¯ûæî{¹{÷žË û[áü¿ka«_¿ô4oÙÅu¢&¸}Ëõ°-Ô[¨·„‘Ù;å ®A„äñŽ®ˆ_üö¥â·Ü1dñ:­T>Óet‹c<U*……5Uø¦brV˜¸Ä†>Z_©ðu„ó+Þ“+–Û )·6l¼]¶EŠg_öjGÀ°¿^š£³[•ÝßæÑÄôpcàYßâí¨[8­}¯PHÙìÜÎp<8=Ucà¿-�ã-«q>˜”3òÖ3´à†?™‰”ÍAgª“Sõ@»G)È¢ÏJc¦[|�žÎ¼«²7_ˆqŽBÙ:»¯S,‡+ãû@VCRùÔ:#éòr¤—˜>\§HO 3:™­YKî‘FúP¼Ÿ©¿gLJ Ç]R*¡(×| ¹Ñ×z¤­ v S© ªð(ºUR¹¨p¿åmo‚Å hìô¢_¯+ÉTÙ±ŽHŠòó.Ñ�¾�bHKÂÂ!�áAÛcPO±éFM®b»Í£®Ò ] Y( D]Ám ”›¨’j ¶òœ3úúH8‹ÝŽrí*ùkƒ‘XðRÊ#Gl8\“PS}àùŽd}¾ B·ºjÍë D¢°Ñ~“û--~6‚6$„?Õ½lÂ…@á-c4¬SNÛ½p:¤òHŸ×Ð�t÷ ?#<Ø=H"Áë:ÚÖ�BûkTª¾‚ÔX5©¥¡6A”�`é陆ûŠ Oè+¡ú`Ž¡÷Ò×§žå„àQxäRªÎõdÞ@î¾Ùs _‡l)i˜.SpW–¨J?Y;sí‚ûÄp£³ÐÑÕm…jF+Äx40H#%2ýÄ?Lñ&ûðÈT‡Ô ±”ià¹2B,šíÏ“r|€\«ó"9Éy4VÃŽŠê Rs™õ"“#÷‚66à‚Ö‚XÔû²N€‚ÏŠ€�-ȶĦJ°‹±C9¶.dåh…øÌ”‹Â΅̽̓+;ôTÂM\‡tp"]M³+{šxçÿ½¦Å¿kCó[2¦èŽÝ¡uß½*q‹xèüЪhÞ_Ìü¿´nGÝ{jÝüáüŒë·¤›¡L×"QƒÖ}Ãz.غMcüÐ: n¾Øô½ËŒ)ö%oî¶ yÍ qÕ{±™ùUÄ÷»ÈÜ-N“§?+(E÷ÿ±£b“íõå²›@ÒÙ¿ˆpâÃø!WÊ#JšïËå%” iY©šj¯Ä<%'¿Þ± YšȯŠ1HÛ5çy©€,ÕãùÁÙÃpL™ñãm¡W˜ÐßiLbáH’Šø}&çt– ;—æ[©æÒ‡@–EnÒò }sFŽÇ²°o’÷phX3g#×Lˆ~ïc«˜>Xprm/šÔÊ+K¨¦£ˆ€L¬°¡\ÓT>Ì#”Ô­T nñ|w¬ñ³qwñÇ•£“SŒ#bï 2—Í—m€.gXFh¢e ð­[ÎIù'µEBÀºvEFäâûÏÀ:kHßHÊO {.ÑèA˜©ÍàDlкQ uÊI[À#�àí6)"*°E-Ê\�7X¾é2E`Ù„ëA؆ƒjhí6´ân¤…rºÅ7´�€¾@hò�ÅAå“6LúË%(<•`ñ™®oF»ÚÛˆ_J¸Ä2a1Õ`6:›] ¯±>»Ó‰]JþÆNQ«ïu¥º¶ALíµP؆¨+ø hñN[Àh!Ü-Ž~§ Êâu€”â¥ÍaÕ2Ú;¬Í\@§r[ÁoqŸògM°ÍK£é (q_õ¦‰@²TPÔÛ<¢€#Tõ6wJWœ(uܺ#êZQ@L¾x‰<"[µº!ñ5\ÛS§¬:ËHƪ0A l[! j¥VB#ûõIrÑŸÕ€.¨.{öº¢t‡5X¨æ§Ç¤TàŸÙø™ØžÕš‘ƒrk™žfýÃjÍ/ç&zæ}Œè^©äüO¢mJJ/ôéWÖÈÝË”$Ùè¸gPwz¾4 ™B+5PÊ‚&b :db€ùŠûýëÀ‹�àÇ�…¿5Mâ~ëRR\ïÂWá4™5h^kG¸8}^ÐõÐÆ60²ã:Û ŽöT{§Í­ym€\O^jÝ º»NZï<ŧç[¡wÆã]˜ýž;Ä”‹~‡^‰{ï~KøÍÛCîtYÔo^AnÁ>5¿Í;[ñ8캪W\¯°îÜ`ä]uÓµÞi^BF—éíÁÔ3IÃé†è´/³¾)¶›Â–W»¥e’{j?e{mB3ìƒÎâìæ@Ïä‡o`Uº0™u^Ål/ŸƒA{Ä‹k|ø1OM½LÕÄbó‡8²â¡Z?×°w¬™õBU�À>‘t4«'3°hË•°cÊF³,¥˜Y$&�½>I¹¡tÿ„˜KÔ5†æp&]šÕËæ“£¹d’Eç¡æÜ¬Œ‚¥ ù‹™?XC—–“sûß'Y‰LÊP 5S®J2ËÎIIŽÏ÷éYÍœ]' ìd85 Ý#ª‹Óõ×Z|'ÿ9]Nÿ03(ø~†Ïd2ÇŒIŒZt•†]mi5ãTñÔœì¦àIH€§ ×'P�Ufñ²ix @Ewkæ„„¨†Ô mjŒjë©G O\«¶&²¦ÜàUD”ÞFF?ÄÁ€He;¬B\:‚!ª‚íj¡6Ñ!D®:&ŠèaáûS„Ÿ.‚$Þ?´8ƒšp¡ÑlÔ=IáPT/j©-2êâuÏY³h +´û%tÕaàp Ûœ)6EJõš"h ¿Ù­7x°É 8\Ç‚5EP¯I…uê¤ìI&€Ð¤^òXJÇ%Ä‹*5l@Hñü‹°¾%msÙhDQ“ûM6­Âç @ à.79Úx¶ÝcMÏ¥26´µ­ÝÎû6�Í£3­ÑÑ\;L‚* ÈHIB¡óÁ‡aÙ©¤§=©5¶Š�1v-ðGðæ't˜ƒ–vÎ&$g –íäØ-�û±N‹¨$ìz–Ðèå³ï4&GÅÙÇú3õ`O— =_qö¿[˜±¬“£—«ÅJ!EÎHá‰Jk8Uë=e_«(ú`Џ›¾AŸùðü¶`‰)É|!2lzhM1Móõ›è49‚¦è(ñôÁ‚i—F>8SaÐô‚ë©%ÞÉ#[W®c… à"¤ïrR]‘ õ{9Ú–¸=¯GŽ6¯Å:4ï—}Þ\ý'H¸éÿgë”ZW¡—¨ÙXÖä÷£fWgÿÖŸÀ¬Þ%iß|HýZL¹oS‹ûïÀ+þGîhþMÕ“3�ý²ƒš_[ªbZ܃Æe:®‚lÂÆŸ·„‘"?1òÞnväY¤F2O+Ì"­‘­KcÀ‰ÂÐË2—©‘À8uÏá ŒÙÝÕÙÂäï(ϳyEúèÁïåp¦‡|w"Q(Éã’çOòcÏUñ´r “ü»Á8÷^ôéñ‘´O¸>Šš)s÷•…ü�FQ\”¿i¡ ¢…ÃA~¢–F´0ÛªÀ¨ŽÎÉø$Éí¼ –-Îéô|½h¨ärÈ÷ O&™§ç«vÎçß"£áÙaÙLi1ô¥ ëoþ‹.Î&kÇ(.8¥Ìý¨öÛŒ<ÔXž sXó=(Fæ²0J®žhU$º9ÖÍ7�˜ŠÊ)\“GV7‚ˆ!*µ½¥ÖÒî1ÉbF™iyU©¸Zë1p4xâ�p‰—¨�ÞgˆÜ¿êÄ‚SÝxL6ž¹‘îJ0½ ƒ)¯ç B—<%Þ: ·� ºU“G‹» ˆ-Á>v¢\Ë*çžzC4 s�„+ŽìtBFx±ÂâvÖÅ€÷5bÄýOÓtå»ùý%dñè™-·)XÌ}@6eàp´86…ßâ~‹£p[Â'b}ÓÐ ·%ļ—s žê»«)IrXóxbE–ê�ØäÛÓ¾š¸«´c¡ù·D`ËÐAGö2æwÀ: æRÑY…ZÛþšÉ6´‚Ön@ Ô1¿0>Òš±_ºŠz ;x$ç =UÀºÃQÒ\:°\;wñjÏZˆ¬j:Àë7az¦æ ŽzÇ#{÷ˆÄä»ÄMÞ“2©CŽªòõŠIXgÑ£zœ“Ó}ôýJ| )²˜.¼Æž9Ê>^|@g4µ©]ΩÑÕ¯‘-€8’i¾Ýd2Ö-”ŠcÍ ¨è.ã‹à<4„ï\Gü6/n«hÂoñ‹ô~*ÐðÐ`P2h@�má_ª}¶Jh·¯ó¦âR–©Ä |÷y˜/ްwZî ´hþ‰¶=•®},ú#ÆäÖŸ@®þ—wCðÃÿ>õÑ ©yƒ0¸† ‰lvëÒ™|ýѺ¡¸úÁ|_©œ“µn\¸Kyv›á¿M°¦˜º£ý-0L3L„ØGØÖBÁÝWÑ·g:Ïåo^ã 8€ ŽžyŒ‘¾f "1ñ!—1ÉôäoôÛ=+O½ó¢5·hþxæÉÿU¢ E:·è‘à,¼>X¬’S¤ÆsÕ³×Õ…B8s2=”*‡FDAãYñ„öLðE ¿Â–áe [SbÞ W¾ŽÎuYWÿlv­\µg¨*üöØL)IJ¤\Ö£Ô²“ÀÂù¼þQyÍ;dîg“ÔØŠ#gl‹RéåI¶3’0fºÙœ.Ï Tx=36ÇŪÛ¦•Ñ=ÙCùáS’~bÍd%½CËx9 ¦äl�ŸGñ©gFô, Ùw´(þ™ž¶¼¡jj×–Øâ /±ä^¬ @ûŒA¦YåS›ºt·§Á€ú/A6Ùô¨á78b»)Paº+µè€ëîv¬˜îŸ×¶i¯ $r5©·�xõ¦Xß„¯PÙd> 5ífê3¸p{Øa›â9„îðG©p¥Šg+|˜qáÁÇ´VÉ€‚Zž»…U[-PxkûMo`Š 5›�gHN¨èYÑ0VôÀ6GÃ/?G¤v@E‡À÷-Ášm¾MEè€m ³É?Û¾#¸Ýä�, ÿsÑÓ 4:Ñ‘ýJ˜{<WPƒ°×�iJ`ÔˆRD¹ÛÞgi×_cŒpôÁ Üzù[°É:í輻kÒ¯@:.ETí¿¬ç…t81 €O#Š !°E4ÔN0ÏÂüøÑX!•°‹+“¥H­Öð( E°¶[jT0«ÿêÄ}†¬zšïâÏãЯQ¥ƒ*âh1eôõÀ ÀŽ‚ê•é_¥ñpnŸ�Ï&=r´_YÙL:$y%¦»ÃAY#,cl�m£èméCbû±ð›À4+žr}°‹:¯XíK1½u'.æ…ßàB²CÙt,Hp¿q¡ ê4¡4è\¸£§Ï™AátvîÃáýÖõ›Ç»±ãß ±n Ü¬Æ š·ü7Õ«×ÈíÆ¤? Òàªû?¸‚ÛMä3:š7o ­ËÜzÇÝßè༵T§?ò»”@óÞpŽw Òtýtî´ÈMI ëâfÜ1@à" ›_’LOpS’MiKrCD`fª�Æ@(n)͔ԄþÚ{ë\¹piNY9£ìëÈ›ŒaDJ´—Îî†ærüá§21`ýsžë‰D¦ŠÜ£˜Çj¸ªÆ#zRŠªùôÔ MÙ„<]û†©”•Sq”t1öâ~˜Rœ¤üdßSw¨ÉpQŸÿÕoe¢fÈä<-,%ÖÐy˜èè{5ÿ‡§†îâ™b|6q&“ÊâoGýlh•ϳó‰…Mµ{4ÇΨb±wt‚ÂŒ<V©³!0yˆr¶pvn.3;Ç:,e ùä©:‡‰äí¬SÊÉ|9%§ü&tR·`ŽÿŸyUžÕ\(¢$tØ©@&Ø ÂÌ`§.“ÉcASØŽÌŸASHpš&1àô×™r4Y´lrIÑi ¦ù8I @”Í@$q«­¸4{UíÚª†Ç´Þ ÿ |·å4´dG|­Õß%îÈýÚ® ò÷Xø¾·³ú6(Õ\YP „LÁ´·ÿµxþ&©‚FW¼œb ÿh«‹ÏyØÀç^c¥Â]åfPq2Àw@›­œRÅ€nÐ ƒ>—­ D HGH%«Sái[›|{“GÀ.R‚çmîWD 4yŠ× "­¹‹P:Âr¼5$¢Ž°®k)aïÀq1W¬çÏIG“Ýí©žßvÑ–âÛI—!2+nºÆ¢˧Öna¹R¡ÄpMê( ‚Q­VXjrg–ä•Áò~n«&Fû‡ ø2uôï?&*š¤õYfÎgÿxFÿ_Ø_ž) Jóucÿ‘k€XLYx6¶XÁ†&²  &OþɰqévÁÕ¬òðýÔX-ùËl€C]íKvTÕ•²âaÀv êïPÞQ<h Lƒð¡!§ C î·ÅT®òNHÙâA“Ã@h´ÝzÃC‹ã"zOt�PÔ§‘vÓˆ‡üö¶!X h^À ²uçüÞºv¨¿¾$¦PzWðɯ[ü늣ÿÓèн‚Öý©~“ÿçÜ~¨•ó>ŒHÜ×äïËiƒ;dºÓ½}exîܲ2´î×)]ýãúµïÔo¾“K½£¦¯’ 7§º´w‰Tïïj¦xe ~Û7Xo�-ÎÄòŸ7]¥ÄPð$õ"Â÷~â ]“o£Þ¼r¾ƒzqäiýéo¨¶MZ˜X“Ü]:SÃÈ¢dÿXÍ$µÁw8(ïI¨£¶jÆGäoASª•ZKgh°Ub¯’‘…1¤õîÛ VDNBëo< dT$¦Ð•(C ßÑi×´k/‡È†vé[+ÅoFðÊ?!CýÕ™­ FkVD (�� �IDATAŸ%Ù$Ói±RøC:‹¥EKå3úá÷Hß -0˶&#V|MFYñT=?µòÁ0Ù/"1N@fÏñ¶øúx,ÈÛh˜Ø³Z¼@óS‡RPÌÓ°ƒ§Õ¶#µ(O@,ÐÇn*4Riíd–+ |ÁÑ®úJ:ùäèƒ.y¬¸m -ÑHX§ Û-áÇ0¿æ®’�ª@ôXº‡èËh”A¯³åíou™#Ü“”§FÖù._=³­¥òÊ,YÍñ¡Ëç öØ`î)…V¨�» †Í®£°ž¾‘– ­† qDtø;û_‹GßtcÔd. !CÈ(^¼H­G@- 0(™|SëQé Âc 2*Yëâ/¿ú à:œ5à·°Ñ‚ QmC}� ¢3B8¦q=1D°¶å2*$…nI\Y‡ˆbއäKº¯ª2QŒFØÏõ4Uºîh©9À t""«FbžÀŠI5Y8Ú+àäÀ0Ò¿FÕK]Aômä ‰ÔƒPŸ¡<útíÌÂñ²ÞƒšCª>ÃßéøÏðÚ¢îÝ.ÈÁ‰É 8YF2/S¸²<Ú³rŬ¹GÛs&)–éûôÉÜ£•<vJéÇ˲ݥutUE«aqÇóOÝ—é DðsPôä>³W] ·Š:BÖ†O§YÂ×�áØZB½`§„wgóâkD >jAãâà8űÅëÓ!@�÷ öhÀ¿ÈmãïhÞæåÅ¥uÛ˜vÓм:ß<ì·n×hú­»¶°{B‰üpÞD7Ôºi—ûïÿf,¸ÿ'Â3ømejëžMp']ä2Á¢yÃ3Q¿Y›çßù‚‚ûìÁÍM㾃¶¦¸zδïsûöGã—·ÅËà*аqq±àþTа¦ -<jºd«fOÿ~c@u±)‡@7Vüeûúx .ÐS!Ý“ ½ì¨GæõžA²³—#—’˜bU¨Å§“ÃZ¶Q‹¤+$]„FôO“hdôžQü.eù7ªLŸ�Ñ<ôü^ÊÓ#E™˜ÌéMB(¨ÜEÆÌyNM R{}jívŸ”,³0øöi›ÈÊ;ó…ÕBipü#w4cåéÞ‘Tg†ù‘š#L2¨Òk”-ìËdDÔµJ2ò¬Ó§Z‚ãü¼·8–éP¤ç´T¤˜±&i<;Ôœ‰Äˆç–ûÀN %s<„Å¿[ϸUÒÇ:DŽŠžlrh'd*ÄGÀº†Œ9ÉŽÄÆ<O4êØÁ¶«g¶eKKdˆ"x’òHqwZH{ÛŠ[àšr€ïRè¯;n¯½ƒaÕ:êu%S/Ki—*æè®¥õ#û :Ž¡5VMi`¯,ËX?uÏþU  ~‡½o ><†(¾lBƒ+â™Û¼GYQyôå¯Q«SÁÐm F–¦ò¤’r ‘‹7˸¯¼zƒI*ÐDÕFª¡¦5°Í¦Ñ®'±°´XÖ.Q1ê À"¢†D×$8ë‹i^Н?FðÎ;ú±ò-YÑU „¥( ³ *A=’i@u7œ®NzìH«‡/2ë«ñRÅÖI™T2oý ÙN¤ÒÜQ²ïEQìí?ÍÞôf“ÁЕòƒ 9ôþ2[ù;‰u±J1 s ÉùÀš¬ëÌzºl=ù륅ý•ÓÁFa¼lEÆ¥åŠM6?oOðd<H¬—ÿ˜ºä �2sŒIW?±œQ­wȃmgÒuàÕ‡Ô:ò6Ìð¤h›aðï æp� _ñ Ý…â�÷ÛÝKu©�à¯Áo4ák lEòJDè‹æù .‹Ê§'Tu£v@Ðâf”æÍ¸½¨Ž¸90o×5×™‰.q‹+ nùîtÛ\áQ~ófEÄŸÒÈþ'dfÜå::¸Ã­ßtuß·ôÄöW¿Å îe2Z»qñ]þ³+$êâi|Šô]mL7SKt®.\W å>Dи�5U:±‹ðmù×­º»K@#¬ª¨ú ›@l ÜY>'–.P´P^æ¤ï¦Eà_èŒUMuœ¯½<:áÏpd)ú}`+ 9+¾ÁðlŸx+ƒŠ7ìÇòãù;ûè®,"¦ˆà ý‹#âØž³¤WL@€A¥~Q²‹§O9¯“ìñ'Æ @Ì 8J Ë"sôx˜Ñ‰ž5sѶ9:4ÇKÕâ’ÆÌBúmu4 9ìæK´0Q'{OŽ˜ý„œÑ3CÑ‘2–ù9š˜ùù³Ë©þ>NÞ&öjµ¸$ñ=гÀ¾·@*Ù,’pûØÝRÈ©BI£ó˜¯¡>HùóHyg ž} Ìö2$OR˜ßÀ…*Öb¾á;ˆš¢Ô©˜aÊ‚ÍÈUO]¢ %ª] Z`ºµ´)ÿ–F¦ƒc#·MÕ¡ ì-eÔuÆÙàø°RÆÂìÒü·#jп4–(‰¡wºBmŸ‚ ;Øè²Š„B‘ »!hC|© 54ksBP§L’Ôs|ø|:S ¥Ü"¨£´¤Û�kCÛ °<ZéÂBÐäè�ˆÀå#¢- z-¦èiÞ!Ò§°Ôh —ŠmnS 2°†T¯>‘ Pl·ß“ªæ:xFÛt«�ˆ€ºu_Eˆu¬N@rwÁt_dU냧ú»p8W�+Â&^c!"hòÏ gIÓÈFõløÿfÊÅ£Lg •}bò–AÌ…勵;0hᓬD·Š9¡ãRåË㥣ŸN–I> ‚²ŒÒꓟÕ0çà°çHQ«Ÿ¦ºº¹ük,EdV¡(ô^ôz©^§"|�ªlIÿs!c øM jmƒ¾èD m`‹Oó´Q¿H[€BЈVˆö…ü„5Ä…J¼~5ˆšïâí:-mLó}hó�¼s-nÏ:íwb÷à²`º<‚ë҆ʛço~“sæw¤ë¤·ßz—;÷î,Þ¼Ñeù¿q7Üå:$®ÇÉŠ»M÷¶Fû¸ýißæ;­×Ó2:7èøk­m1ýv‚›\‚óëš7òÓë@§Éßå—pÖ5êé¶jx N9 ?V\7úã)Êz¯„Ûä5:ëê‹—GèmÕRÂ-Ð"°p€ÔA!ò*úÜzŠ -0P³"ÛCü5³iá fÞ˜²d úUø}…Ïþ†¸†;|ÅV�º¨ÿ;¨FÝGZîõkE#T#ª1ÎÂxV8§aö¾7Æ 8‡…s¤#û¤+MÇ'І•O4F~Ôƒ¥Þ'f!#gг('ó/Xò^QÊ¥Ù×zöi± å3=°p`㥗eä_ã™Óþ2ùéÌ¢SHõÙì‰ •«TOŠtI?™'À¾Ú/¸Ú”iA˜nø:¤9qÃr�K-žØ«@¢â¢gqiƒÄPJvÖtåÛëpw ÇÒ8d €èlq@°G% ú·U×Ûâ6`kl¤iô…Üç+aµù—`»Zö4 âŠédGÿ]JNSTèëÝ_ϼ9:è¿Ó}Lð*Z£ã@Bø †ÍÀ3Íu\«·kx…!Å>8Ú<móœ!$`D ”‡Ø³ˆX©ì|ìüjÿ±÷¹ƒ'¸:’_B]µ8‰ ý0Mjä—p[&$…Ž5<�Ǜ詰úÊón�Õ†ÀfµCðl î%©û Šj"d*ÐáÒ›¨!ÌÁ“‹ q„-ýl ý¯é68꺳†/×Ü/×äsMãõ¼f¤÷ìLhlܨ}®ÿžˆÞ"#»`vÕaû&,,§0t5q [·‚7#ì–r’ªÄEÂp<q+“•,·Xz&~…‰Ò¥Eã�˜” ‰~=ŸéŽ×š°çmòã5˜;—ªa¸qø$ ‡éÂç'šèÊ\µóÒfHžj¢ýÇáS žð )@ÍË6ž:m(޶çSø€¸° ˆÅUŒB�tš!èÔ¿éËжiŽÖT´Ú¾�Ž.õ2—¨Cã¢Ü)Ð@ãºNérj5Þez^Œ ´à«gÜ{dK÷ ;7µªwt7WÚýà7﬜kîËn~ ²í¦@èþ2Ò;âÔÜË»7¾÷á_ÃÈük‹¤¼Ö;íìÅÃüJÛz_ Ó;Bâ0W¿ví’—?ãÎõ{퀖èl ¸ÎŽj "ò5BÀ 6E½áÁZxTš\6yµÏ4�±�¥Ù±±sDk™Õ-$êÛÙ¯ŸþË¿¸GTè7 1tS¢‚ŸYìØ–eSÀðè„9I— mb{R[µðÙc¿’ú ÐK¹‰Ú “éOž’ö‘"®±*—KU«LRÀÛûV”^£8÷iù,XX^PR™0R~¿š.üb’Ó“r²ðc,ä•tôšüèu>óɰàž�ø­,æ;iZu;ôñ$µjŽQ=1ؤHN–In&çX*•Mœeéy†æ©*Z°çóƒÎ,8Í2UdH½JæVœ ECÔ¡)œý’»ÿM€!; Á“Là1¨†Dè‚×SošQk«JÑé‹ xu… Ê%€¤ <è4EеD#[Ã@‘8Z Êc€¦@“)`·Ož(ÆÌFj:¬íÔ&JšÊû©Bï›OÞ>IW‡xù8= Ür@ Z¸@�}á¡@(¶èËÂv�€VD�DS¹lôFEj T¥óU½>çÒŸcáa×2X䀽âÚ‰*k¡»†º3g'’Ê"‚ÜxÌåç` N(°RGÚñÖ‰TN@~¹ÅT‡×[O¥ÝžJéCI½ÈQˆ9,·®àk¡- ÖÐxÙèN­yR„tšØ@èv$OL¤ 4rWª_zPn±ž©{}WV9¡<ÒМ}S©Ô^È0þì•BÅ| ‹3ÉÀ(ç)<¦bäc:‡Aé85*Ø+¢¬È©®�ú'Z/× s6ÁÁ,¾MužYÃòY¢ ;*‘í%Z¯óèÌ{y E(¬ÂÍÀlHH 2| (щá·/îdp¿¿ Á(  p8ùh2�P|zê—- h 4xÐîú­»Elü²ažß>k¶/‡ò¡}ÛŸ\¿ ÷|7Á7Ík­‹“þý¦ãkÊ×à2Á·.õÐÿIÑ¿7Ü.Sû‘ký`Fp‡»~÷!/‹)‚[õÍÖÓé]oâŽÐèkÜ|ái¼ëõ„íë^’»„Ï;z÷߯Ěð› [ŒØì‘6ܘ×áÕº-[¢Ú€VœPt€Ý6Ü-5÷…­±O¤Yû_?Mba"úÍ*rŠ]صAÊ•åõÖmóy°lâÑöÁ^Ÿ‰øO+ØQKX/°×·žd í‘-YÃ,›xõ_ò܌"Kì¹£ÙÞÉï`åUØ!fa®¢XüÕØ¤([ùùš‘'†\™d ?N ¥• ›±Þfô„ έJšS5óUV´)s³ywž)j¤ö"¬‚m°î›‚9<s °Žfð»5ÉONÇóv’Î=Ó4Ï2<«ÃÒüÏ&lz4ÑÈaÈòXd‹°s¥ ƒ®øFSFH(ôKÉ0ë"_ )Xìm౤¨<]€knÝ€²NØÃÑ Ý)àø ¯N8TxQ7Ôk,…¨·9­àyRÁ…Î+ä/g#’׿c`‘÷L‘RœQñаõ4(hC§3g~¢ŸõÃTUÑBDùF>à¿ÂsuRXk"U^oËM”P(OÖ�U«(tÖð%•p¡ÕÕ…'Ä´gò÷ÇlÍ:³Çs8±$SpÖBä¤$JE°iÍW`1gMàX Øh€Å@:‰æõUIìÕûa¢J@(# Þ¨W{ðÓÚ6Û •”6˜ßªQ„NV­Rt`Ñ­´S!ª ŠY©m˜˜£XÄËÇ!µjî¢tò Õn‚žå0B4¥»¶|¹„áKJ–^ïaðÂF¢É1ìµC`Æ®ŽòòŸ×¢⾡Í"Å\§¤òhh”¡XÅ8ý µB²r±ð# @ÍÕy{üÞœœ-YÍOf, ñe‘`/"Òr×ÈñcH%íÔC" yÐðЇOáƒ××."ó‚@ÑimÔc^Ÿq7¤ß¨@,: -Ž-(`毦ƒ[- -|Ôàˆ u¹šüîìò§^ó*yór†¨›‘<W;·`ê›ò\Ÿµ`â_…&ý;¼lïn$ïn<ûìné¦tܼ۟-u­ß\†W¶µàfx,®¤A›€û÷ÙÞÅðݪä¾Tû·’š·‰n\Æ»^h®oòkѵx¾‹€³['… [õ×›žtDÔ‚†Øhv·!¶Û2rÀ(OÛ ¨|*ºÐÐýˆö‘(Ø6}9B7øï¨ï•/6"’ ƒ¤X79�d2>C_¹öÀ#£èö€Ï …¢äiª˜Ý °ÀõÔfˆ¸J#SI2A>[+îñò£È<ìÍ&ÒYr¿+±ôœ,#/ÂÄŒ:ªüGCäûoçõ8`öƒÅ?(d•“™dRLZFÅN r¥0!•Æèɭ켨³ÓFÖ!Òdd­.âûåÑ8™YÙOÜBV.œSd•Ù¡Ê¡Æ$FeÌH6Á ÈÞ‡ ²²¸Àë=øÂ‹�RA¾ä‘TÂ8ƒÕÀËØ…#:Â¥üÜÁçxsWEhFPià ÂZ“Sü¾Ý„v$™ iÆÈ!J,Ê;•î L+äãBû#úÑli,tOžòB¸ b}Åd,-ë�="ÄxØ•mxª°ÛàA›Ãèø+°#jšÐŠÇ© kbð˜¡/àpú_as=xkœîü^�:×ÙdŒ—JÒy.-í?äþ¶Ï´Àëwê[< @ ÑÙ’ ‹„•˜kµ³í^ ÛÁsH¹Æ¡ùFß8iÂÜâH UX¥a'F”&Áíõ:•ŽÓíÅä%Ì´B žÙºž @ÏNñ噋W4É™50åÉ2¨ÅPÃie=W•È•ëæ'Èk ¢‡j6äÕäƒOòaEŸ?òóeؽSš.|‡Òï{Ô8kŒM×~TÉײs3Ú{«üp0)[ke&‰íÇ•ÑBÏ æXj2Úÿ/僳Ãý£tE¢tfý‹6y@01³ÿ i± +²N£üP± “}¶ h††ðÛMtnAvT7ØâHQW¨vÖD° P^o]Aö¼Þ ñ»!îغˆ=¦Ã&ó¯ÆÑµ™Æ®OõÇR¯¯´ø×]oºß�Ù~Msý®ËnÙüYp7¹„»ÚœÖ kp�>åE®÷Óý¾ôïÜ Áý6é?•žt}Žß—ãÑiÝ ëý{Eš÷H§.èæýÛ+[£üþü2Y…_‡ËÈ5﷼攙ú*ªü–@ ø1Gî6jÅÏ*øxŒÐVÀêÀà”ªE üÙTÎü9‡BU- Ï¡ÄPáu›[ÀÇA,Ab,JBâÔv•ØØðÒF͵x¢^ophQ/kóg1T Þ’˜„ «.HG¬LEº´ƒ3÷3ÃMFî$ÁòÄÃè«dÈ ?Z(R˘$Fne–kÌü´€Ñùhi 3V¡¸zþ‡¢1¡¥¹ñdÆ>É"ŸYï`¦BJ˜/¤0ì•<9·ËoõAñø |<>·JØŸ}kž?˜?)¨ßîWÔoÓÕQBÒšsZ³lWcGýyWŸ¹0FÁÀ±$ª¬$ìÃÚ‡ñ‚çžn¡êÔÅœ(Ös @E² Ÿ .Á«ÀZB‚)Å" Ö:ˆ΀ºfúGMƒè_Ft=üpIï@œY]™ó <5櫳…ù™‰žé°,—Ô¹oÕˆºÏ!@ôä,¯²AÔ‰áRáX°�¦Ä—ô3‘BXÍSà#öón ¶0Ø¡– š¯( “ô1H§Ð™$?&ì¾þö`½wð"íöþ=p· �½¾`JvŽ6 5Ûn�ô:UŸ~µy]s¼ga—‚8*еK1Ø„¢@Š`› «-°ÕÍôŽoM¯GeÝ‹]M¥° ¾+cý„Úëôõ®eX–·= ¶˜Ãçc‘5êôy½ÁÀ“ kgd­òUƒÄAõå,¬$¿"†[]LÍ“Z=MEb'õãÏ ¨4s—rFÞ³èÇC…EbÏöp<0NTvæ2‘df¨Ê ¥%Rž$Æñ“¤˜ô~¾pn–K«oG¥ùóysÒ7²Î&yfé!Ѥ¶½®ÈsÅÒ¹õ²òq¼’A[Hâa Ï guåEMáozuÔüM æP¡Ôÿ?oï÷ÚH–ç ~Ò’Â![vÖ9m§Ú5ÓY}¥­&MOå49?š‚b“M¸+0 zØ¿]Їù bãoq^ û"¨ƒ¹—„„‚¢kf’!kzÓ=Ò­Êšˆ.—2]ç”mÙÇ …$ç}ɖΪž»=ë'aÂ?$…¾çœÏO)3@_M[â<@ñL°t¹ËôàÆ3y< ÈbZ®bý³Íš®Y+y¹n\ œÎ\P3Hû´Ø†ÏÎF·q•p¾^ÛÉð†JMÜD_㆞ŸàM®ÂŸuÿI1¥7«®gF¶¸NKxW|³½³¿¤uñƼ¹”Íàw­kØ‘?»À^?7\[̯x/î‰I#éeç_ö–oN—àâðà‚gÈ`g¡ðb"ãý#R‹|œ¤ló®rpOÈZ „ be2bˆ|žú¢¨L†HÀ»ÙAÄà/>Ư·ÂölÅ#;–Ñ–°=Ž&6} .ì˜ï4Ðj>ÑŠ3 MX‚ZŽFغÇœû–½~¢{ZQ8Çç0‘ô‡µO 5u¤±OÌÂF~N%zœÎV—hÔú r…EŠùþxDG·z…s HR\Z:ÇgýüQÞ2ì¿6”!ô°ºB ´H‹‹…t¾Dߥ…RyY¢8§L$/“Òp±xÒÿüè0ÛQ®îžDX>N*Ÿó k c3a@  ] ÷Ï )–,±±\ˆŠÒ=É4ÐÀ°¡žu ÷( UF±”Êa Ô=u 1y ¤2Å>8éEËXî[è¢Ü<ºßƒ*?ÿêÔÙ‡†Å“N-òñøÈ{ÈêQ›B}!?Ï=Qg`-yĤˆ;�ðå1/Ù/!»qm~Hþw¥ïAŽðÐè0ƒ†O —@òÜÆ âXîKý¯ÿJà�²Yï)gpª[ÐÛ ØR±ºâ;Mî6dä³*åœ(¡4µgS h%Б¬òO0ïº :ƒ¶œ!D,"ð6Øf="j§Îà£Úá-ÖiDêhÅNk’pã<³ööÆØPêÙÕöm|ž†/@À4mQ�0ÐI£ýB:zŽ]#ÅSÐ=¯” K"o‚œnDg`·Ï(©h@Žòú¿Ÿ 1%#U<Óî»cŠèXãŒôhÉè¿ÒƒCŒL=€f0oýj®87<1ƹ47þ:µr…îø@§‡ßÇZ[HMÐ5“Á7¾0QWp-¸ îØâm-êÛYòdô£™iÓ9¨ƒwŸxžg4[Þ´1þ² Á¤”MLì·M´Ïr¶ƒ‹ÄSÿb¾]—]ž�ZþŒ6ÇËL¸|N\Ð7¨.wÞÂ:}à\gzùr×§î„*¿׋KRäj.Ñ0Ò‚¾h÷-·Ù抙lÑzËbSŸR7,?3/nýêÉÀõÞ~”¹øæî•êi>K™Ô/VÔiž¢  yyd/è&Ô_Jªb¸{ýºÓñ 4ÒgtWBD@´•½|³�Š"ë”e•¡º€ÇÛóU„Ýp6=ŸoB - ¾ ˜>J*$DU ;æm‰TJa<ŒöŸKýž&B!9ÕKËáÒÓpmEž$8YWÅ|·¬;Kåâ-"ÇgÅÒóáp+™äÆ:¹¥ÏŒöBNo.ä˜äñýŒ>16~z (éÇ:OÆÇIiîá’VÅ…äà<=/©]N@ÁzzÜ?Ò›Þ©ì}ÙÃiõ� ©ñý™^Èáä#ÈžÀxþ|Ë·yÉæø…óÞ‘C!ľâ£-ôSh`¯ ÒàÔÇG”ïчUÊ%‚4” ŠL”̬i�@K¸u�·ˆ½ÙZ³ÑK‰wói©tÆŸÿýÿ\•ìË矩ز†I`›Ö?3*�±!4 Áí3öþü©kEªnK/lÇüäPêz¨Ûáw Ž µóÒSŠ pOÒg!"«†ç(W {?z^{¤°§DÝw4€í0ÊqèúLkîhˆM…V“Û†BÒ„ê ®t2·&w=.;¯6ë¿j!B“׉(€#)…MÑ å¦ïÔ=ц�œí³: ©�8¼°ªà¾¤]R{<Գ̰ó‘v6;r¸«‡ŠÚåûK%J«Z=Œ+Ór`h»ËPCs9—ª|y;ŠRvj?†v JÉFñ�9¬ªÂè›?/–^9 ;zúýs¬�kï +ó9¼6“w=?¾»bÑÓdd¬™ýÄ,¤ÆóA’V¯O—ǃ“ýü 2G†HÚéó(Q›÷t¤D½Ž0Y°¶b¸MႵ¶À<~æO|᪉ù ˜Ñõ»ÛÓªÇiÂež]s2÷å´t!h@ZÙS#”w9.¦óGdÉÙãÁÂ�� �IDAT³´w½êy&9TÜè^Î*�›oÆW\ãõ›×þÆ@æ×5.‰€·w<üôE¿å_œ9pùc×3°O0zî^æX\å®ý+ŠàÀ¿¤n ¤ fN*“å^^Üò®Ø³]ŸGEo&ÜJÁ¥ÙPç®Ç[*둮ž?)"7J 𠨰™Ï„Ì]< ÁA0‰†Ã²VjÅ@=¨ÒÃF%­m¸[Mn{¡Ì¨­{H,D P°ÚĦ•]üç¿À½³ÝdA–ŸÛæü—_UQBy´?“ØÃèž YqÁ.üíŠ"ró¹ƒÂ`eŒüñIîõáâøè|ðÕú`X¸•˜§gKç¥ïnÅébu\H–îÐ^r’Žpܯößé|?Or °¼žâÉ @£ã¥Hçq±—_Šõ!ŽÐÝ“äå¾]ÖÎÚx&{ zŠe._+;�ž”–¿<Ã|/T£Ý¥‘øCêc ”LñÌçi‚G”W L*‚$TT ³XU­Õ{¦¨û!£@ ’x�¿VQ TjÍÈi¨°W( ì}òðAŠR…ƒÊ¿2ž��vwÌ¥ü1|Î|îúÜöÂÖÑ``?¸ Âe³Æà0`ï wù^G ÂhÇÀŠsó0Q0×AXî+±²(ÎL”2xWï–Ø¡p·Ð²„„ ÚÑÀuv<)•¨³ãó€Bªp>4NŸGž`ž|ÑlD;Òãu…–Æ^KH/¬PÐÄÇ TDÐâŒB6 =^÷œ–²:w)ܦ|³ÀTÐaRdH"Ÿ×!… "Y!{^£¿>ìitÚåRXVŠÝ_«RŠß ô’~1¡,ú`½]V‘úB§Rš{GIñÅC½†;ïõN—¬B¨U9ãýÄd=º?<(Ü2tÿ`ØÏç‘?ýhíŽÂÒx®d¦wΓNÞ|7™Ç Õßó˸«À¨„Y~Ü• š@Ɇ’®–u¶Ž„¨7áz"²0itÏJÝ=Íé‰_!ð€8K`ÍŠ<§Aj^–¤”}ºùÄ5íÏä°y<Ûº>}ä½ìS?²ÝÆ›8ÊÔµ~ðøoÄê]©ÞjTæ—*)ÿݯ_Lü·k~|†ßúÕ£úÿñþ—?Ÿõï¯|ÿw÷wÿŽCí 7ׄïÆgx³ï\_dKnsf=ô¯ûƒ‹÷ÆÁ–u¡ª_Y¢§ùé¼®by-/óióà µ.XuÅ[@½‚NÁÉv%6E¤À<Ô§í’Ân ò'níÈ ¼>9Z ø\z¨†=UmÀµÄŽæ%%ö(À$BV‘uƒït¡-H%î›È'ÀûóGÏ~OlK!¶#yŠ!G7ìIK ·ép•®žŹnñ?ç ¼>¹õ:Α¢¡ÍáÊùk•ÞJ†‡d4F¡¤_÷Íïo}>|ÈÎd®w<§é˜Â@î\GØþℜ–tÿuÙHÓ´ˆâ+¤EŸ*é°;2ªØ6´6¤ÕCÞäy#Ìu#K`ˆ^ÏÞ¤úñ¢\-àè€cK¿'ï)l–Dð1ÐD0/ZbÙä±!VØï¿’‹uVIù@§&iŸh<—¸¤P{6å›u¾°=¾é‹ XçÈﮟjCã9-Hœñä9J÷°.á2m*A«�Ùì<xëÈX ±QEJþ+_vä–„F„(@-®Ê$g/'Ñà•ýÒ�-¯§É‰:í&Ë(}*{蓞´[\'»5w+lÁ!-Dé ¸¨ðä‹êMÞ" qA2€PMuqÁ6˜F ¥Q'»ÿ×þ ác8IE˜uÞn0Ø6Qo ÖÚrР\*0"¤æP!(ªJ¶© …ª!†dvÚî0<uð�•…'³äîž"{XÅpBЋ¶.¿^dfž"¯’Dn>c(Ë ­â]ÂúC9îÞÏYÃE³?º+C9.l$_ö@KÃÛiZ Æ�«4÷Má÷Æ!).­-ûCceq€c¥Í¾Vs$_ äš­úWQðܯx »uZkՅܶݸ6A{<¸Miê5åAc[ö@ÀË `€»ÙhºLxã €Ê>×K|™¿y1v.Bú˜²æ¥) •í#¯£ÙþÍ•ÞìÔ:W÷ÞAxËäô¯áó7ì^›ÕþÌ8ùzýúõÿõÿ? ¥Ûß}óUü/Oçþ”‡ÿFMîŒFÈ¿Q]½X\ªKßàŸ[àI°möT§ƒ¾qEvaV¼<HÎÄo\¢þM³¦ÇÌ"äñÙ>¸–ÀƒZYso¶eGpÙÀލîTX5`O_Šº™mñ¶Ûš<52ÝAÔ³¸à&Ú¾øˆ-ñ¡ ±nZèfá ðó¬ð‚ÐD¼ñ Ä‡ Ã:âqgã®Æ°Ñß±`« (üBšë0o;ji|‚âxPTÈõ1—ôçœë­èÁiòê<?:ŸW£sÎÔûcõíü_”tuþÖx°²²4¦ïÞ²VÉã‘Ì;)¿k€ænõzX¦Ãä`Eô•ùRo&‰£ØUE†#Sþë’}L œÏ x!ÌèåòˆáÐ^íaåûЧ_ ŠE«Ëíæ„¯ëU€;ü%«K¬9Ô²OnËòaÔÕ@§V½Mª�ëɇ¶â‘Ç­°J¹ö°HsŒQ*D9 ›PõŒ.J4,,‰ês¾Ñ`�@�Z=Œ’¿nQÖ¢¡T 0MU½Dìmn£ å@Á£e�D=—ñ—6ÚÑ)˜2PX*©¹\çpi¹@)hJ N‰½ÍÑR×ÜÒn°MÑBT,ØT,A”ÃçŸ*-YˆÇ3R!ƒ;\•Y‚Xh™Ñ_y" Ž¢ÐÞnI*HSÔ¿˜ú¹b§HÂë6@âLû/7à(«ê–qß2•¶Šºe³„E°åäSI¨ ¹p@è| ¬Vm¤m …¿ŽL¨Òä\%š”º¼E°³TeJm(ì÷œQuò¬;þ<t‹ýr¼°±?Lqš0ŸsõQáä$ù=âüÚÂÒêráÏrù•cc¬—Éñü²&Ï^짪+ ]…ÄQ à PWµV² lÕ‚ÊäÓmûbm4É膻-v¶38ÄTôŠ�Ümâ‚‚üéc…`²á‰x-oÒû{¡:Ñ7z—Nwfâ3`Æå™ÊXgV“]<½œ 3v1þ6ƒ;3šf@”·)Ü;ç]­ŸûòEãF[ÙM¼J}z ¼7—~Aâ»ÞuÇÌøž¤h]éµð¯`V­«8’ûf ÐÕ…íÂÁÞ<ù©ë„Á¾xƒ·Qo„ÒÂhLv6QnC>"L(¬V®¢~±t[Y^® lÆ0}ØàÚk"� vO|ªÑv‡J%À¢-/ )w!4¤Ée8�(­~¦zañ}²°†eÐÑßtV¢âmàWd­ û‹¡:´W¶ j:+ãBßÀùâG %f.Òyº¸8G‡s橉â­Qrk¹0®Ü>ÇâOò·çÖÈ`¯p›ŽÍq:MÔp¤§é;·ªZ‡Ã†œ;ÅÁiIi¤ç’¬hÜ•ÿ¸Îíõ9”9R°‚nÍ0‘œ…V´ü”¯8 "sÐýŽb”�Á>¡(UÄÎ+ÿŠ­m`iK?á°Ïw jiÝ3På´I˜ü®¦*6ØàÁ}¶<" v ÝÕ9qç럒e “F¨(RGísEw?Ú–�I«’„n,@”¬€M<<‚$_¨Ç¬´iþN[ªn…ÚC »LÇft¯šPl±t€üm@õŠVaË«ß*£ÌKж 3ÃT7Bü �°-Dà®ÇÉV¨P{Q¢K9À±ù€z¶ :QLÚ ¾ˆTH4"„ÂVpµtŠ·<Ô Zdª¶ŒJ„Ià1ø@Jí´ökSÕE`;u8 5w›£Â5e$êÄ˃ôÅœH6t©ÎT C3¬þT.-¢ThÓ9iš½C¢Gí:%½¤/(2zˆ»ßH K ¥\ Ô˜Ëc°VZãÂ,Ü6ß)çný÷ÓáÉøìߎÎGЃW#HÐ…6UDwL½"Û†M ‚O8K9  u?dŠ»>˜‘íúEäñÀŸ¸‘'ð΢83=8“Áí‹Ì¶¨iXƒ?Ùk>à‰l͘B "ÈìÐ0òÅÜP—Fe÷ Íä,s\‰ÜÄcÌèø7ØÅ² wª  ~°Ýop~d>_»ÌûééŸhmð~kš„UÍråÞ3Á/D f˸§º ÝËlÒ�v®Æ^X?‚Y³‰?Ãã{ו¯®À›¸§?Ë%Ä$ºu¢†µúp=lú Q¶IñD†uJ…À áó–'vš"�ÜXìx€ªµÀ[²®®: 6Z€íñ(´²ÑÄ&Úƒý W�ø á� !è"ŒeÅî¶œïCœÏÓ‘‚ Xrý¿ó89”Hk %ÊþéƳÜñr±PLæÎæÆf¿?,$¥tÿ<éoå1Òã^2^ÖçýÑ Ï^çNŠýWsãÒ œBJï,«h¨Ô<íÉÜ¢/&I¡[JÈÑqdrõR&¼JÍ;Vâ Ì�±`—ÅÞ‰0Wå¤ê!>žG<MùxÅÛ¢û ô†Âú{d[¿ëÜ_ÿ¹J–Ÿ,ŠÏ¢}‚ö^ J´#Hðö{‚ÅD”“õæ°eÁÕN+L‹—“ÆxùîÒÃqÁ ´Sƒõh]Ü-ë@ê,Ѥí <ȸV·˜2aû5|b·�X2ÙÛÛ!g äqì`&Å^™RëáÔÚ%|‚ÑK9:Õ±ª½ˆUŒ_­dï¹èR²ù¢žqT 0/”¥,ò® LH4@À³†n Âþ�Z ›p D¶Ë‹²Äžzk—) †V(Y"òD‹ðˆM ´)pмŽÝl«Ô"\—¨YH*`V¸™ì‚È€r('B 1Ê- VT9j¬™U~ñÒÀAR¢U.<ìž ý­­ ,íÂ<­ªeŠ!’¡ÞxÌZF î š‰Â_½kJïëÕÕ%Ú¡éÒ«•Òèll”‹C3g®ŸäÆXª¡<JÓ.ŽUúP*áê+´‰.Ó6} ö¼¶Yç¬" @f§±ç�E‹òÉÀñÃ�¢ìx>w=ìÉ>2�\OÆ®×çnsºñÏN�Í©áÙϤë7¤9´f2ˆ2OÜe)Û4”Û½QQzñÍKZBÜ(îo]Óô7Þž³í‰à-[ð·q�ÞFxoùñ/ßðV8ìê4®Ï§Ö8†à&ì%—ð–¿uñS‘•|ýÐRt#µ ¯¹ ¯QSêbbÞôìXbÈ1}š“ï7&&ð:D�Î�i2¾|õXÖ”µUC`›ËxrTb1P„‘-@ÉG"¢ØPè}ÀÍ/D¶¨ôzÃj {½&ÖM¨Ò¬U$ Pžï¥ã“¶‘²žñ~¼“aͺ½;8¯=•áƒQJî‚Åü|!W˜?ÃðøõÉ;£PHn©å×dãó¹Üis§º×GÇÉèµ™¿õúá{énnÑüûîFªÿ.Y§ýÁ³Î¹]c)WÛ?Û^Ö�0’E'z%6:¬wQÁ±M4Âü‚³?/J¾ô¥(É]nÂ…Eù/Ò^Íé£1z§rüñÝ¦É r½â�é\¤Ó/¥V0%l f–¡º» 5è]@ ‚ã’°¥z#lmËòï¶Äûkì`D�]#=£ÉRc¨—:ŒHæž[gASf™þ;M舰Le¯ÌÍ.)Še$q`>1Ñ7J"MmÃ0)KzŸF´bÇ0ÛÉCÐ&h¸'Œ”ï)°† Û\Å µ%sâínúµÀÌçÒàƒx¡†SoíˆQ.  á*PæÂ ”�åh€ù‚Rž¨0²[ä①ËYå©*8ø㦠Jl‚µ,H W9¿ÑP@‰†…©B¤éèF(›k„²éغ–¥´Ü¡é]¶œ—¯:ãGÜJ„²«ˆ`šjÙÇ=<¢v`Flß.ßA/­p×У%¢5"«ôŸþšÿ!7ȧt¤¿æâÒ÷Çýâ2z#µ¦WûF<Z¢Fgø R�&Y>©=í �Õ;¬ýTÚuàÂÉt>;÷} ´˜›8Á–˜ˆV-Ä“<%d¯O¶µ§.¶n© Ó²Lq¡YüÐõl[Sî¡À‡ë!ð…›ÑÚSY <Ñòyïïz?žζIN~íô?áç±Ðƒîb^5'Ví pí½˜coဃëÞpüäÞÊ“@€Ð½*ú#9÷*švñ·‚·<½GoÈ[oø…þ„¸X*äEö†7« žÁ¬jhr÷¼á`MÔm.f7¨+d!²rªaì-ÈXÀ£p=0Êë@àï4Kaä2®‡PõQ‡ - ÁiìPDBS…B…#Fþ�µ¨‚bnvÛ)„Y’%%;T)BP /`�8ë‘q;ÇVÊ>û`Y—�œFýù'ö’<61´ãüD'ONO¿?}·t|ôççG s_ç_éܹ2óƒþùèütPüf|<‡„Ñ­åÜx™`÷dÁRgÉ/çÐÿ‹r:Œææu”¿Õ{§‘:ÞÕg¥ ìV)0tpV‰Šc.84¨ÿÙÆü’³Ÿ é)KÅ~ ÿMCÉpn,OÎXÙ¬ÅcúQä” >ÿËónò>øZÇ ÃŸHk D¯ðg»Ô¨mR=€Ô …lhR&› 6î”) [d‹}´"á¿ÿLöŒÏ,ciyxÂò/*(qPÚ«*Þò%ÔD5Po¢Q†LÜ|¥�ŠÇ D9QIPÒ6 @±ÄD7eÄ0×ÚéØ$÷Ø1ÑJµÙ–ØdX0žóžn�õm^P  �¡ÂÜÖ;ß®h¢/Ķ”Û!’¨Jù%k`Ç”‚ ÊílÄ£ 4ÍÎB%,èÁ&¨w‘®<Q Ia5肺BäñÀ*£D˜r>E[b“îv °lI}g“øÒU¨7¥PS!o£�š¬ô¬üò«¤Ÿœ€Ù B•Xid`+Q¯Ê6YgM Ï©½Û5hB£W ÓŽI´¦Qú‡ôué„`œòº€Ñ«Ãܪê¿Èò«Çç ¥Þ_è‰MbhÒVúi.àšìÑK”G�,Ø÷ ÂÍ·›‰€5§^×8+íTx“P<x€Y °D�ÁüYíÿŒÎÞs�`KLLgpbðáz<ÈX ðÉf¼î¡åÏöB^A&p5â’ïlà ÏJêypÝØ+&iK7„/íW7ò:F"~èHá]ü)uJÌêô?ÁU\ùUW§ÿ ap¹8Ïlà#ð&Z)÷Ì�7_øWß•& ²¶†©"H¨éûç£åM&³íl‹Ñ„ Ñ"\nM¨Â¬bǼ ¤4l+ǦX#â8Ñ‚H/m¡×P@ƒÓ&4Ç]²™ßØjê •4JVXiXÎRäT᎞2HY¼Íöœµ¥p¾Ý+ëwºÆ÷¸»Fއúl•Î'Àëw—Ì/ -,¨o{kÉOòg=væÌÿC!5“eT¢F:?Pù"ňH‹HN©*)JÒåæ’€â0 PšS*HÂÔÇ|BcM¯äxžÿ zT,ƒ÷MQ؇ùKœÜb´õ­ì‚—×Dzʰˆd$é>Ï#Ù …Uã¶yÄ“NU°±âtŸŠ:åhˆÇ-–0»~‡¤×4åõO¸-´£IϪÄ6â~/ù&ÚTØ!€F€€•@žs�k–xgyËÜ…Ø¡ JÐ &}b ÍèWVÏÊÊ^¢QŽ@¯³ü<=.¨÷ÆÎ¿�æo¡M t„uÓT$Œÿ†©¿wÚ�³v±…ò6�3ÝzøÈŸcZ²! }êdU0„ ¾éM|þØIÌ4•hpù‰`=.MÁêM›©î‰ús¶CaR$JnR|ª°G6\ì=ÞBÒbº#AmúžiäÚ½´â"siI .˜uT·™*,Dì~zE}|$YЕ¬ÌÉ‚0‡Ue>¤'!@ÔBDrU}¹@«óû@´ v@Ëå;EœŸb40òƒ^~~ý$Gò˘7Î?;Ø¡ižªGCÚZj“„EJ"æî"ø"‹éÜE% À«ñ€5ÑžNBŠ<`›»[Û¼µuÙÏÜj‚4M{ã/' ½Ü‰O3„ë_ÊO2Ñc+këºa ‰k îÕqt³Bé¹¼æòc¤7çÒ¿G¡„·è¦Z{åÿÒš¥€<¸¡+Ô»n;¸Ú¿ví~-ú;“']íÄ.¸ë]‰è˜MUºT•ù7gr¸ÞÌv`"ˆ ³6×À›ˆÐ�€–JÀÎŒò�ógþ·ì/.·P 8Ü%h5 §]€s߃†xN5´âyÊ l“¢€p½(nú€BB8)ÐÃS6JjÉË}€áLŽ {8k÷ÇŸb>‘cÓþv(׎J€Y*Byéò¯çzaDFGFN.¯ÌAö×ÏoáøL¿s{Dcä_ ÀÂ`oáµÉN ýÑñHd”?ï%'yuxŽqAžáö+˜}Y‰ž‹ä¤JÖvÛ L}ke×�#‹ÎÚË‹ÎòOk‘Ö;’$µ °>v  4F#¶~õ­Ü¯'Hã¶“ ¨N¸Z/ Õ)í-¡ Ió*’$ÔäȽ§G­&ÚlB¶-‘D$-˜%Âh"Z÷¶ .5ÅO *¥ååhÕ€2”°Iù8£UùœoV`R1‚]¥ �k„¸NˆV„Ñ&5KŠGô/•¿ûK–Vtòž jÓÁ‹ÄJ¬²[ RåN êÜžuÅKÅõ=ö—(Àµµ#ÚÔ]¥w’¤%>¥`@¹|.› U29¿ºà›3Tg‹â‘†I!)Gì9—±``¤Éª$‚ÒcAEj娟:ZÙ-ƒõ¯Æ½Ç@²Ã�GV€²Æ<ÝÛ‡žÜðÜ¥¼NA ¬{›'r‰Ò§`/å³±“(ìóß`¿‡z*ô©Bb©H HRmÍÛ›‰" Ë'dA«ÓûŸ¡B½ñÉrúj9nħi>·–œŸ$ƒbÿxÎø·¹j²ˆ ±ƒeü=´’LVØŠð€{5(¸‰xäñ�|§ÄŸc-_�Ümòl©¶ ýKýw|Óçî‘Ï”"ðD 2˜^ÀšzZ/”¬ÞtS¯Po\¦Ý¹þE™ó¥ºýÃï5™w=È(˜Êg.R!Bhϲ§ÁÛà–æ[ƒ'®·¹ù7ã1ÁUq&ü©Äæ&éПš‹~3‡ÕËÊáߌã_áܧ>€k*«Yqª{í)Ý@Äó7q0w* pµfïMýïUŒ+ð32ÊÏ%¸ë‡Ù5ÁT…Öê¾ãúˆ&™¢~Åš'ª °-áú¢Ý<Ø>oA*lÖ‘H P€eqjŠD…ÔýήR5ª7åþ'<‚H,A>xRЧX}*Ó3ùBÇ�e…½ÝÅÑKþ Ë9I‚?äxÚÑfÄN–shç±iIÁ¤2\Y³G(,/%¨®•`¦æâüFçKg®ÓsFówÆC æ–Ô¨ß?]7`æÓ¿-c¥é1r`+EЄ|Yý|¨0,´}áLZÃògÑÊ<¦½{÷gæ“wΰ]Zr¾Lªß¯Õº=¬ÀIYÂ5ø¼r’œS4¸m C=À*„yôÄBX‹õqùî1TDîŸqóޤ/ñBñ v ;MQWA—3Å"­—o«âz¹}ÇF1 €¨¢m $ypÐîóœm|´†hÚiY`ø÷–ڥeü‘A$#¾cAQƒjMÚ•@›0’8ÿËY«+­A'¥yŸÆ¿ÿmô2âϺ¼«° –xQAU¡ ¡ž;‰C(Z±m2ò ‡*¦žFQ‚½¯gúú˜»!Ñ@¢!i8á¥,øY½@KÙ”ã*Ô•¨{`¯×Q"HbHzK"ᨠR‰Ès©c(j¶c¦‡ŽNƒ.Áï>¯RÈ2'–�Ðj„AÕnWÔ}®M¡cTU¬*(S~ÿ›_1 ¡bC °Lè¼&ô™6¥6¿Â»kçSb!®ŽFæ`mðýÈ¿ê WÎÑ“ÅWz¿‡èÙü«ž–ß$¿ÿÕN^x*+Lš àl uÅ wwz‚k5…ë‰Í Ðoy�Âɡ܇K§Že�D€N0úlyh»þĪæ‚c+Ãù¥/�/Pš qI:N®áW"’nZfS+‚ë&~¡;š‰xpµAÀ}›®qEé^,'oÎRïæ!ì^•®_¼]ô§Ä”~À ÷V:z†ú+§µ×ÜŸ¾|,‚&w'Ð,û4Ë#‰`êÑ»öww€Í+¦±ÓäQã2ÿ£î_]W|€"h7§Î×C�ÁÀ3š>¿HŽb€ôQ¥OÚxX¥!”C�m(˜'Tô+QtBa‰¨PC¾¿Å¿-Pâ@DA߃‘ŠüÝŽèÄKãðàÅš"9Ägw°�� �IDAT¤ ŽV¬#?0^½“·¾½wk¥üaŽÐáúJi?y½º<ßû>Ù_ÈÿüÖ\?9%…Ñ‚¡În­ å‚ivõþòxíE ôëD­æ‰>ž øÆRˆåÅDÿFjÄhQÒ/qòs¾~üd�sN¾ñÂaHÎ0X  ‹{§aiÞY<§?CTã¨tøZEô‘æmõ/¥¼]÷Ï_ßÀy·J{ÉC]­¯¤&¼½%Ø6dŠO;¬kAšJ?°HÞ4““eÕë›z/yæQ5ù)5;ɻĔ°ŠæqßÈ'v”@ BQ²øžn‚ðÍ­ð7-iv°oq�T‡Ï(˜’ÔB2ÜX[(ÌÿËУïWõøàèLÝY€^@åó½ø)¯Ð�Ù #ßa�JË 7Ù}L£DñH‹ªâ€hgø•B�ØThp[õѦ`�UhS !XÆQ™`YȨBA X‚i[6jžÌËD“{µ^æ- þ±Ø7·EbfjíDê3¦ö`q »‚M…Ç”«2®Um™ÆÃj"‘ª²À4$yÉ5†!RI ÞN…M¡Áî¾Sõ÷ãs“ üĤ¯Û¦¾²8\:,Wò_ž#R´@†C³wû!Å&X ¨/Èà¥]5k DT󹤙ÞÔ¶QÚ¬¤Jl‚(®1ŠºÚ…Á·ZsÕ”àͶÕJ°‰%_cw§F„‰•õB×OÂG`e){à õl\4/T'W) ÓD«q½ áÆ¹\hs.7²Óqt‹ž€tôÝû?šR1‰kÕ ¥k˜ÒŸtmø÷þ£þõLï¿.|ƒ?´5¯Ê�®}Wn‘ë/ñ[ES@�áÎÐV;ÈŽÙ¶uˆx}r6„íq PàDàsæAN˜lª<«�ßÉĈ“ûLÐm®¶@·‘�Z ‹°’‰4q ¯Û|³„O{è%ìö¶"s†fP2}�õ' D¾pÁƒvY\»k…¯†„®#VËv÷sšÎÃ\±Þ¹EúÐß¼¾m-ösPKãò÷¹qñXHÁ„‰ÁÜÜÎÆ¹Å^‡Ãú/Ó¹•ycpxŠÛóù/ÏNHŽŽû_ãL&éåkù#ñj%Ýè· 4¸ZÝma?1¢jÏ~÷—æáQ¢kúK ] Ö°?ÆÚQí¸°K ¦QTå%|óç¨ pÌ{¹0RÎЧ*Ü0°Ô#'UÝ“ÎæP)ì„›€Ò Ì4æ  •ð‘";ÔDÇX»×ë/˜½#”ˆ*ªòSô˜•ÁR"“ÛÖðâø�ägtxž,}uŽ8Mh•îƒÅ[€ïPK,›ì‘fÌ ðŒîÚˆ�˜°—aöJ«óÉñíÒÊy÷»{˜ÒÏŒAqôÿðÛn—JùßðÐõµ8´€b ¤¶¶œz3|L¥ªsÚD¡\ú`�¡ØT“{/k57)”�— š¢ÞØmùÀ)mÀU<nCDMTPÍ*!íM“?îàQ†­ãÉÎJtCP%A¸iî&ª5ÀZ‚(ÑІC“Ý!Åž®UUØnÈéô¬Úhk‹3Ô+îCì=³jwKâU—›D$%`ÁŽ^jWÓÇ h`>èò`¿? ¢BîoóÆh>i ŸUt“cª]ƒ`O™XoWO zvY×öÊÂZÏQ·LJ,怨{Û"0Å\È Á/‡>‚,ôb²ÿË(hÈI¨%U@JLÖ‰¬ù'ÛÈ_ù¼ÿñ÷-öã?†õhú·¦ ‡û?5rß roÞCÿÇó 7mĽ:ÞM=ןž¨{o¨q›W¯iN$F—Êß7TO-ïíï\s‚K^d7eïJàOØ©¨‰G™PÚ›�v-?ˆâÇ™Ç# <ò'½:B–�éAzà™&!ØEj£ÏU âcÙÕÂ"<Ö8ë ô²[<ÆÎs±¢aÆb 5³É©É÷Nzxi×Û¸ïñŠêµºB(éz44L”ž(èµ"ÉH1gÞšÜ.â~¹0>™;_NçÔíñ PÊGã<ôw¹üëa!]ã¤ÐKÆó£ãüëâðÖÑë×Ç‹·‘ï'«çi_çÍ“ºÒž¼P�ì4ŽmÃ`Zsuèec$úÛUNm¤¯Ô° Ë‹O—æÓ“±£wúº‚Úüâ?ýìP¿S|¸ˆòá15È“â\µ8/L8¶Â‹ g¯WÞ·£Âß’xÜ…­i¨uTÂúÑZ"é (C+èJñEuÚ¦¡º ¯ÌnµJØRB0´Kß<Íÿö®*õuRŒÐ™çPBÅa©ÌÑåU0"›–P1ï'Rk¶ü4ÝÝHt‰ð�˜ùBçFs?]-çQ˜ûÙ˜þsn°§NŸ¶÷zpsPÑkBR$Z(ÊêD`rË!>‚†lw ’†ˆ¯U )´�TC¸i!‚h+Q¦LŒˆ²›”"ðk Û .áÇÝ&48o椽 ´´!€]TÂëáf |,dáJê¶„êÔ"¶Þ­s¢jÈR]è;Qª�#LÊÛ`°&sѦCêDZG"ÑèvÁ¬Z¹¾HH("ÜŽÀÖñ¸üyEú)[^$ýùRt%gO^é§DZî 1ßCaO¡¬Ož¨½aÄî*û„µŸfmO…è1€Ë oi‰:°Ì"Áƒm`‹»Î�L†¬Š§å©¬×“·|4³¨gšvfšûb\tB¨,ó& èÅŒštÈÃáMduÂÍ›5<ÁSøF1ýLÖÕ’Ÿ·Ð ³^¶úœ®àö3Å3þ 0~ö˜Ý$Oú÷E¿•pæ×žvëêÞÜ}3þèíªÙKl®qñ{Ä”%žJ•¦Áè³6·à Щ5{hhL]õŠ‚&ê3V=«mðð–/\º\y“|Ö¬j|ò¿Q°m lÁ©g´³5ùÏm�>˜'˜: @<�¡ 1RaIqqNŸ:ßĦå¬Q…F€ O4@ð—ÀýÐã‰YÛ75´P>­ ]àú ôÕÃã¾ÂmŒÎ×°¢Ÿ¨$é¦Ê ïã|}iÜ/Ìӹ²‘,ôÓÑiBØñÆ)™ÃËâx|4ìŸa¦…äurxþ«oç†KE’Ci<\Nç@ÍÄ|ª,›?¯%”AÕz©HhíR‹—ùGèA3Ìf,˜æ½“#é<r£˜ãï,ÚßɹÆrá)VÉùp·¿Ô.é罇¯nc”~–µxÚ íøCœ²Ò­¹_ˆ¤bk‹»Ò;؆ÜÙÆ§DšG‡}¬¥J`ü Š—;\u¥ÔRÉóZ¢Ñ¹ƒås/a‰õqd¦µþí9ݪeêôž‡�Ô„™¤….ø]…ãa¸¼Rƒ)Ó‚€âÆJt¸Z\>MÇÃqNÿ›ÑßYoøt8Õ <6פƒÍÉ®%,Yp·9¨$Mù<Û´=dgRÁc’¢‹*åŒÚÉ ê%ô,¾ÓÁ^“ƒBª,ÞÃÞ)[ QoÂÕ!ké6°£!5Ü oD; ¢-± Ÿeº¸:Âê„ßòES<",é¢ço¨—<A„Û=0Ø2É:º¡áà)M(£ª“hšáœrÇÑ;á¦ÆÆíaÕ(‘‰4T§N<O’´ß/ WÎSr”7ò¥ÂB!TÉBY ¡Î×6ò¼<ŸÒ¥6Y¯EH¶TOl ˜NŠ*Ù¥Š·šOÐÐödÆeê>*$•òN³N›¨SÀ¥¨{ÜmpéMXp²^¶ÍKY§3MÐq\� >Íîá#ðœ, sÒÍÐÙ¼uuÜ_á;›“µèÏ ÒâjîÅ•øŠk½“þrÔÅ[-Í3;ǵ¬Ž›¶àõ«|øÿ‹ž>qIâ]7¸?â_‰±}›3P^Æ·9éÙ¸\¨guÀõ/š!²|•K”ðÍTðÀÂT>8c)œÂ…ÒãÇ-_HÌȨ1Y'ZJÈ-*ë@às` ÂQ3P¯C>˜Ê&hä²…!dÏB |¤DAáC-ŽºJØ[¡ª M€8üMÏ Ý¶³}"X4{¨3Ay!:Ƽ:þù¿ã$o W¿?5ǯóHëç_³›ŸÇÒ-䎒…ÔÈõz'9óåBóϾ[é§…¡Êý|éø³…âR2§æ–Òtõ1H2Öø%4°sb(Ë›1hIª5,w‹­µZa…äF�’!ŒÜ 0žï.‡CD«9ô‹â4‡d¥vbšó}]ØKP- ó%3¨ØËÉ^ÂmꘈH“¯ÏD`ñ’Šè0Ü!¢º Javm­ÑÓØS‚‘'ä§ji A!Òl.ÐÂ(žêѰ½Ae^ÙØØX&Ÿ­ žhhRnw!ð¿–m%EÉÄ…P eIŒ¨¤&™Ç“?_aÆßÛ-H~~å,§Ï“¸ûýáw{xòBG_ÈÍM¡=üZ fB6Àº–¨×y�¢ú�6ÐÓxO²£m A<ႳO8QJÏ9£àЉZs�­ùæ–ˆ,à= TiÀõ¢¨ Žôy DK$’mRØØ ’j²Ç´ Öb&½_§N\Á'ÀÑAŒMp€J]†¾·Gµˆ´ßU#r«Æ4àq(ÞFˆ/€Ä.uXÀÛ‰c§»{ô ½Âžb]k‰k’.…aiœ¢—ê"¥Ö¯~û2Uó¸Ç’Á‡ˆžâ¢÷µ2íh?t‡ö^­N°S‰ì26Ð ®âZªíj@jðÂ�á|W É}×up(îúÌ…¨@CL.ð§®cŸ@«yeûÌÀ[˜iiöE B4áúTÀ—™WiÂÙL‚•¦9=3¡ª×k€'‚ÆŒù­Û³ÃMÜl5¸°8dM3ËÌE{Dð¦ägú€½±Õ¾¦auñ# öŸ’‹~sqs]pÿhRåÆ ®$§ÎbŽÞŒ%¿É0á#ðnÆg°¿Ìq³èx"OnòK¡´—mFø…MJÀ˹ÁÙ áAB¸ÙÝ !› UÀð€¦HWhS Á“mDŒ†´ã$k?nж‚ Àâ‘ tó8m (ÞØ=”Ÿ£�Ä(@€_cw'Ö´â<£áƒDæWïcN•Þùùb!½uË¿îŸF‹)²°|²xPÚƒ´~R<xÕ7h‘ž–ÎÌ4’ŒÎÍùå×G‰N‡f²8¦ýÒ°¦ã“ÕÜi|4·¦ÕS•³£$ÂUSIÀtR’*嚺ŒÕc{l‚þDÿý¼?gâ{EÆè ¥˜ïÚù[QáõÆaòa·(V _™ ÿí�KùÿÁÛÛõ¶‘¤é‚Å¥)9¢%³T“9åêQ³ÖžSµwO 0Ž…�Ý@^ê6Àü ‰ü IÄ­.H n„àEF÷4Œ3®™•O×RÛåêÌn-u„-R 2Åy/’”HY®ê93½¾d‰LRÉ7Þ÷}¾*¯Ð[Užu^°*lE!?^ƒ%‘iÚ}- †¶L4îþ=º¿«6i`D!6+ zqD  ªx‘F0HO™•¾m$‰¹&O @î¦ÉÌO¡ç–¦Æ]üó?œ~¡,›?à.Ýh¥½¢Æ M»KÀYiî¨×ý¨ˆN{nVwc îÞ-Ï ô[ãTýæ¡Æ¾BºÎc®ÐÝÆãº€â»f„DÆg!èa¤ Ï&œ(¡=`‡;Ûë¨(4=!Á¬ºÜv¹ë2p¸[G@…¥ #[ }ÛñÄø>äð£€ÚÀS·†¯ëÍ €²½á–~)È`p AR¦TÖiS5  ïq·‡ðpÜÛ,í/Ÿõƒ´ݬ G1˜2ØæÖŽØ‚mîÖE¨àÜCð‚á±±õ*î`óÿÚ>?¥³=Ýi ÷E9¯ŽÎh©¬ç êå ­\ÐRÈ~±ßë­”ñíyT9´±=ùµÜT ñ`ê)è£X ¤›©šM@#�\%BpJ¡¤Y°·Á·AŸ„µ†ãó ®“Ï̘³`è Çã£*ác—€h(~EX÷®–2³h¡•b¤½ ÇþŒ<6¼i=šÀã7þbp•:ÌDÖð!‘Ät‰û à!˜žE>¬¾9üU°èÑ®ËÇ.ÿ]JÆ?,‚›¬×£< oŠe„› 0n¼€ëïÎø”b€sݦû:$}¸Þ»9ô ë€Ê¾9ú”^ÞU=‰ùYpñ˜Ÿ ¿ŠÃî؃[”<¸>!ˆ ­™£ä®Çá£DÑ#P (J1âÙq]Xà�âÌ/P”;!`;4 •-!ªŠ?¦»à0¢xInœð%"tÁ2æémúœ,<|—ºÅׯéÜkt‰.àgý¹[‹ƒ“ÓÓŸõ by¦=œ¡yC÷nUŠƒÎÌÌü»w½pvªØírKϧÃï“a¼–‡:eé•Rÿ  ‹´cÜq‚´cä‚©!Y[ äõ/[˿ŬZ<Ó¥ÞÎØ²×?Ù,QsHVºúxNvû K_ÌßR¯»:_¬´ºÐ}Òȧ,6h)M¿ÜŒwSÛuT?é V—X´™kÜ=eƒúѹaƒYÿc9^;æXD(§âÿµªåX­,˜ƒ¥~?m¾íß- †9c8|4<m6ËŸÚG X¿ØëCÏÉÿ0 Cbeàˆ ?Ω…Îz{ÎæÕyÙ¶9Ìε†h¤çÕüVÎq�µ¥ìpt뾕q]BC^õ¢Ç¾„7òÞÙ xH¢0±¥)Ø6GÖaÔ@Qß~Ê-"´�8äšp´)—‡@€Í à óØ °T¤M›½�†›"0PMiC¿ªV ÚÚ¹#ýWµÈð‘R;&°(tAà5œm¶ëËø>c¯aj©ˆ¥·7îQg³ñX3’°Q–ϵ) ´)�¾U¨ó]µg˜›©™Få¸uP\æÍÎ2O0ûÜ<¯ž/”[? Êè·ÐÃ0mÀ°æ40„>Œ¢U\¤mõ|‹°@¡J¥J8UÑãu;P`P·|`ËdH$27¤Œ¿”Õå¯8^x@‡jÌ ñÔÁ¤'ÜÉ æË]E=3)ðY&‡ü)åÁèƒ?iû¿ƒ IƇŠÆiö£¢4¡–… YZÒ nCä¿\«“þ´Àõ÷Bž?€„ÿ;dÈýqíÿžÒÕµþ„ÿþ2â{mh˜AüKãõ÷¦ d}z{“1L7P¸&ÿíC<{%Mj#Ÿ3DŽg_ïMBÁÕ|0Ò²³!·9êpviH­¸€Šýo�U áƒypê"TœP EŠ&(ÌC¨Ï¹ñP”ËZ_V=®|AÀ5E…`I‹„p#AhB M¸Ô¨ªhås:\H—rúbÑÄ-_*æôÒ°¨ÏÚÉâL%´gg?É-¶soúýB{ö‚¾5(5tqvéÍÌEaffø®?wKŸê/ ÚOi»ý›SbÁ�â‚â}ˆ¹Š5hjeJÝ·>C¬ç™•e…!-èôÏ9`æ“¥â÷…\üg}©õ²ÿ3ĺÚ6ró̘£úüÑ«®(Í¡§6Ò\Ó8$E€o<ÜÂ>¢Çu€WiÔ ÔBJ q~ºÑßÍ’?žÇƒW|°ö¤úhn~óÀ9e«ú¢ØÈ÷ªó(Ÿ 8íŸwzC`þNñä]ap¢gÏËÇg+°–þ¦ÔŸé÷ÊkéàGý¥õ)ý4ŸÎâö­Ö°U,æ~×yV §¬Ã@;(–u³uåp{b+á1Põ„ ¹tFÌ´*EJ°µÐ"½G€pÇòÝý¡&a»ˆBØ2C¡¹4mX;ˆ5�¬ƒr QŒ+n`FH¤KÖ€:ˆâ1„{ocs+8JÚzKÛPQ�Û2E 0pzG<þûà ìY&4bú k˜Ò‡!�h‡Ëqœ™E°R$Û6¶…û_ À‡€ 7@ÛV>Ž _ü Šôô2¡TΓ D–Jó…öwIüi…åйh¥KNf±ØÚ<Õh!!˜l‚Á6•HF>H‘R&©í"3q³´ wDåÚƒ©Ýľ„Gx€§.‚ÌyGš»êªƒ�Pá*L´n× \ï}I³p³SÄ<ìf9Ám%n¬ïu/¸L–DÚ$ã&︫Šc|éÿ6iÎñ¨Øµ¿OiBbüÇ™¶#@} Z¸†FLV^gZàž“ä5S‘ú”õ·8Þ(w>ø�ðøÒ6|j£Çá dz¯ô,—J½ >6q?¾“a>œmÀ‡«á{ZqPa?Þ 4�æ ZÇnSSPŠ"Ð#0Ê!O�c+Rà²Ôe< À·( ¢-Ž) ½W\GÏŒ@™Qaâ‹ ðßPd©š×§3tf®_¢¨Úýããø(Ÿ˜é)°¨o]¨³n¿W\ìÍþPÏàu·s»“¾&}ÁE««{ƒÃ™ü|¾xwfÎÍ«Õ%‹¾ÑK½Kì¹(6o$÷¹9¯OzP©ÏªºM:äÍ,y”ÐÆ- °Ò³îEÎì_¬«÷²øj€c ?Läi©ÃNXy¡‰ÒJ|�¾Ñî‹Ð:ö ,*‘÷õ#ªãä;þòß"}j?y¹ùêGÛHRÕìí½<ÁË—z~øüÙïÇ`-­Ôùb'ÕÏdóio¾xRhžö’Ùó´8{ôñ –ã!ij¤^Ð[-䆧êãõÙÑñQë-ÕBá÷ýV ÿ ¤›Î˸ü=iâäˆÄ{_ëM+¦ó v¸ãìŒö‡ `K‹�pðÈ­uŽÄGXG#¥rã^† FÅ+�Ó€x[¸®âð8K9pÁE´Õ<0mcP\á±',̓ÇÍ£§_Æñ¶ %j3OÄ0¸,í¥'V¨½/¨a|cHm=¾K³--bðøÒßsǤ-ÀÚ†|a³m`»/žJÊ]Øðl g‡£x€T#;^JªXí§ò,ŽÆ~6‹ÕÅv¯Ÿi<0óOé…<^ÐwÎ7Qí4ª|¹mÈpk É:�8&¨gà¨Ù8Öaí@á*0 — dötZ^"±áÈAÈQy�°Í¡ÒQôB†³Ú¨m——Ñã¤ÏÌ@áRÂŒS Ý:¿ jD<¡wsÞ×$O*Ëü©êqu>M–Do²Öók%Èð€1­\»¬‡êêq½)^hðã8³SÅþO¢ÅO{fx×¹IWçÁûºåÚ<@&ñÿº…ßH.8&&]]Cí†-“‹ñr¥K¼¤6]—f?98E™ÆÒõyFx /"o4Ê0x"S߸œ:€‘0êž(¤GAš©ñ;Q ñõW¨Öa†¬¨"#Øæ‰í{P t·MT�JBˆ*a O‡ A ”ÚŒð†â)A@¨¬˜²ñB–€d+RSýñ¹½Øoý^³ÛøÓ…îC-ᨗÿ¥q§0Ûªô ½Bn±[PiK_\ÀÈ/¾\E5Hsƒ~yø*×]/ÜRƒôèüÝ)RuqŽÜtŠ^GÞ¿ÿôáRÄ:J¬êü^¿Ú¶°fÑ1œ ;Ø|tú¥Õ+wzùµ¤PPƱ>·šF©JúDõVe»7‹x‹ø-1¹¥p�l½€C¹¥lÀÒ)Ç7ìeQ$E&QHÕŽ¨­X¼# å]lµIÙ9±d›'€n’a÷Ió¬XAÎ8ÅÁaƒ¾''œ¢tüÖ²ç²r¢ •Væ“•3|½Ð[}•ÒVJáLæúÉÜEãèwøìU‚@ó—ÐuRqJPqÛ„¦TÊ €#ÉBƒjk�¢‘‚·†]Š8ËŠ?l#¤ö®—Ùí=4!•pÁçá!B«’ öxðCì"+pBB0‡#…fÄêÕ8¤ê‹Pmºu .Ïr•pê �K…ÕÛ„Š±tbµJ?xÄœ=;þ”€ë<åìÞ&j#µð~ [!\ ù\ƒo­ &ÆmÃtT˜’¨ZfECÎÍ®Äý#…ôE®¡_(éÊÈ2£KOJƒÍþÊ<“ öÒ8´ý6J÷ìpI"w€À USH_¸^Š­Øæ)$`Õ„TÙzvTÜÇsÜE6yðË �G!ðÀ¼£Fmô©g>@yà_³°cÁ3wëp=îz#ù†ò}S¹»ŽñÖ'¨¥ï'¾ÝèxñdØ™²Ü˜¸€ø5 Oà}À¦è§ÄÿÓgÿIÏŒ ¾—˜ ¼v'•Ü“ÞMßœx%‡ëRõé×6™7ú¢> è{ïlïúN†4ÙJ»®'àe:{îBÈÑcò‘0ÂËN>B�Q6�AM0?;áùˆþDá&¶HÀJ¤qШAÊž'SRÀx _a5Mp¤ÜP`àµÍÀƒ£ˇ¢ÂÔ°ÔÞšâ=ˆ|Ÿ· þ…Ép‡¯¡`©æ†âuékh |F.ÎI9g‹½™Ó|½Ù\c±§ÊÝtú袜ö^]'í™Õ³’4rh½£?çŠçKýüjz:÷6ÖÒÚ(òÕ"Ã໿ë b- ¼°y ÍjŸá.E¬_æcü€rI¯4£n|{X’ýž +…~J Á<Š©Bé�ƒãåRJ×›åÊ‘&¬c4Ò$á»à!AìA›Ø†C%Ú\~ Àn|ÊP²©�•H8ÀZ1öJ&{†M7yê|'Ÿ/ë?°퇅R^•¶V¤„yš?š»³@ÿ¨YÑüÒ�� �IDAT‡o Í^ S zYo¼~t{Ñèܾ»¾DÑÙžãv‡ÑOmmbë~„Š †¦²¹s` IT¡ à8D[á_vÀh–Åݺp|Î @Ùð×àzØ÷€3†Ä~d»JgKíГ®‡Bz|«mQ0_�p<ŽTèm‘…ÑVhÝv©`á†NlG)W¥ø%<€rW¾=@¢jp­„¦œ´@^3#~<dÈ¡¢ï´«x°Û�‰Lá}%À¾"·‰"HY@ C€ÈÆ"75GŸö¥ÆéËo/¾8(ÈA¶¸®4f;hÿêý~±9µ.s)käµ:šˆ`x!ª/¤[ p^ ˜â.,ŠÀ·däï„3= Õ‰}î®g~æ|,ñUá+Ë :%‚q.›{:jé P`@G‰lð€¹þøÈQÓÕ¬>úwÚ°h÷¦Ê~Õã×Þ¯“âC6B“õíšÛP�„?º–wß÷_ò®?…û¡Bíý5õ Á¿ê†n=ôø5®•{S@Ýõ­Î{ˆ¼ûA‘Ýèg#±˜ôÅuß;cƒi½øµ?­‹L¡6ÿ¡£ÍU Ÿ>vý±`Ì“¯HŽFZæú™Z0ð¹ãMÌ¿TXafõUPRÜÒºˆ)Oa­*þ8 ¼A¡©xüÂd•{O�‘z‚Ô* Žýul¥{ à}º¾ùŠˆT¡ÕŽÖ^ RB»Ô´‹³qoˆî—^Ï¡tÌÒœFNÏ æEá(¿„áp£{–¶n­½™/ÎÒV_S\‹½EWggO1§ú·““wÉ\¶\貜Ùë[½âò9 „åÿ>z‹˜,jj`pö»ûZ©hô»”^0ÜÅEt+t±ô|1§‹'Vo°ÞWÀlœ3Œîœ<H5=ëmœ«‚m§w sXEe¾˜À&%Y´'�<ø*ª`OîDû %:¬šp;’ôP5�Â�!S¤‡œ!n&´ªÄîz;ø/pc eǧñnaôQsÞj@¿yp‚A±¥sj.—ö¥,6Oõ€õ}û¿}…Áêàe‰‚üç³8îÓåÙ½ÿbÝÝï›ìk8{(qòs+½«W?µ XÇaª�‡Ž¶<LR„ðêhÔQÍ 5ÀŽ Ofkh ú¹¡o‡5!éˆCÉîø£€šÇëüq-Ú«O„°3ÒÇnŠ]Ê`ÚØKÀÀã ­p’"N¸ lW5ûá§6¨`šW#¼’­Ãi3øP ‘aE8Š[†Ý� CÄ&S–Å$èÊ“Ð\n�RóVëim2ã m²ós[S¹F Ôé’×-r¬`rÕ �{»à Ê‚&w·÷Ž’ì…”UÛ\ã{Y" µ,ÑSÀËH€WtÄ�5¸Ùò „KÁjÂõ¸ëO˜rŽE¦®ɱûŽ“-h–# 7KwÏŠƒ7™½ÃG¶WÌ×9~krn2ã›h©oð/òn®ìÁUEúÑ.|\ôÆ ñÁÑ䪊¿¤¹ÿž î »³kà‹±ïÕõ«™ÒNB¹Ú?÷¦£èÚ;žåZŒ¬[½÷P«ßîØÿnrÄŸÄå)â�ðj#´ç’°å”n¨Ôù8vCXðÀ|.=;ðàPÇiÜJ0é#¨q­8>@q@At�ú›Ï(˜K#€âôKü‹!›_>¢+íðXíÑuñ€C±ëcñ P(Åš%«Q²`É %t§ÿxAÏŸm¶|ј_!ås2?WÁÒÆùùq›í£ôÍY{bx~¸4Ó\œ© ïäI^žÏöO;§ƒ²1øl¡÷ÉâóEÝï£c¨r=lŸ–A@!uÙ‚ÄL åï¡uj´Q€ŠÝÊüñ]h:˜kàšéÚ¹%­ÛéÌ­_žv«ßöŠ… X’?i:TÏ·ÕŽò0VJÍg=¨È�”zBþOHˆã¦=§ô†LÓylT$B`F1j| jÀ·îH˜¡¸û@X†Š­·l—riŠûó–±|¤NŸÞílK(½°UÔ-+}Õ¢G¿Jz Ø;Pÿüµñ¢Úþ·ƒCô{ ÿðwLM>Éuòç´ßOrÝ•eÐÏÉF¸YYŽVßBK9èõ tIX †&¸¶.…PñзàCBÈœuîz ®ÂcŸ»àÌßÛÍî·DTC^õyàƒíÀ¡5‰:—0 †`‡K!�}@EAÝÖ5ÒlÿW€Iˆê:w�ØÒbKIw¢ aÒÅ&´LÑТáYd€}üïÑ~C‰Ç4{E@&6Ì= ¶Ž6 ÈÞV: ­,$%ÛÝ+Šb¯Ñ” ŽÚÀÑK­ú N{²Û‰*KHSô�…>4l£‰(°½©×ˆ …pg;€ fl:‡P `ëLáx`T@ ·.¡>Üwê"ð8|0ol•šM ‚Daý ðÒxvfØ^–ÎÚ˜“ŠI˼±™]ýêt¹ôM˜Z]m;8¦×8×¤ÑøÐ™áß„ÔNwÃîûó AŒ7ó# Çzñ÷›ãÿxîÛƒüFÉøõd…¿Ì ×­¦µˆW‘Ñb¤jƇ(À#êȇN¯Ë<¸À».G¼t9¿Y–1= f‰Ý„g˜ó…ƒ ¾óÄ}ãú!²÷À^@BX`”9ÄÞ…0�¼ü9~ñØ]G)ÅœF 57}ñÜlBA„K@S€¢—rh” ŽJ0!ž6ñàS뤕üÛy\É1ºPY Ý“jw9ý¸¥Ï»wß̶;ê;Üý»å.–‘+®]ôõRœÍ¼9+°Etf:Ãó ½c´Êï–€tSÌ•ú² ‘SÏcî¢Òm=(Ìî©\ ç͵Uò*ޱ\-õÓö¼^;Ç`™,¾ÕèTþ4ß^–ró½áLz|¾J»/‘'§…¸/hYÁ0Ô›¾¯bˆFÂÔ:!ÅMº,žƒ[ñm4*)Ö˜5¬è!§Š³hv*8Ytp@ZKÕR?m'†®40oá$&°Ö¨‘¦e]~ÙhÙLGN*w «–:/ỦCìP €  Ö€d¥*Wiç3,&ôt³½vS—LòP!ÔŸ’»ÝZ~/¡¹"½cã³l�Î6öw„Úæ¨ P.S@ Vƒ�̇CEHpK‰­U†¸Ý:r•=¾]#øvHP`Ä2ýüE/Å¡ï« T8ù[@X‡¬Á (0I#�–²Km@C85Žz*Û°í+[ CAQ8á6�QÙါžb©iÇ:‚‚µŽ’9œ„) ùª¹÷›¤ 4,¼Ž‰±gi ¬Jy{}à-Úßv„¶?o?>Á®Úä"V`�I˜j¦°‹µí*Ð|·&4àø,ÄCOÈÑgy$*‚/²3¹¬éθ „£î{œçM0JG-é(ëåzé¨ó‘QÛ¤M·÷aúþ‡è§?I!^¨\³TzŸ„ù#Ù ‘ßM%÷¯ç§ÄßOF�º7…ôN5¿ï;¥¼ rSà¾weƒázÜ}3ÈhÈ—>H“cMðÊíŒÕ†.Àü©‘™XØûžp!²ëÜ÷&Ðë‚A¸;¨x€[Ï„øYØœ€æ#¤p�æE ‚½@Å3QZ·%å¤&�`ÊäåuÑJį×9R~ ­— )6_%˜mr³'úÚäå$š+Ds«MÐ(AQ´ J½èì Âщ ýøø,¾×g+CYη‹9ëtƒ?Í3r6léVz2OWîÛ(®�mç ÇGùò,ÎûºÝz§‡ùãwçéia0¸�n}’/~r2<Ð+ §K2/Q8‰új ›«¨üæ(^]`Ÿ@ ]:'¹‚=hmbVΘÍJAB¡¨Î Ê^¦%Ãh.3ãB0úï}…¸ã\iƒ?ölRÔñ¢PG`±(ÝyT)n4 ¾¿nªï5R³Ù!t¡mO÷éÝjÊÐQÍ$}„#'€ÃQÄáé#¥ŽðP|  +o×Ì8•»¿¦¡À‘°bI²ÖÛªqBŒÅ§Æœ6–Ÿ¬°¸Dì^!Þ¯âþ}òÙI Lâ­jTÈM¤z†QH#Ô„ÜŽd"„¦âŽ#˜j£,XV/£w‰ˆ=ŽÃã#Ó…Pö×cj&|z 5!}85î*.uü6š©«bx\À©q4Çž. –ÐAU®ƒUì*…š€V‚db;뀉ðÐnÔ€mÄ5Ѹ§vé¬À4�ìþØ´u –’Ì”8¹¬#>ä1e”â% è¯A^Ç2aPˆK34*Òø¿xÁÒÔ:’Sû8'Ðf!¤:A"&\ª':4è6bÓì@EH¸ÖvU@¨yPÃVKp˜£ÃRúÜÍ6´þXaQŒ€�Q†šŒGþh‘àbÒPhœçóѼ>^]‚ S:‡™X:“X½ßb¾¯1¦­)~Bg0‘s#kh‚ueûMÞ޴˹}n¤9ý„×ÿ$¼á&ë‹ÂúWÐ9wß÷÷ð®Zìðêwù$Ë€{ÃI3½¹Ë’™¯]íδI†7Á9óD5“ç‘z^`!\Í•Ù_ëñåRËG#ãËr‡ò ÁÃ:‚u fžÀN¶•â BzpTz\îØ’¢².àzJTkX­@IÃLD7å�ÓEÄ 1× űJá�Ñb°.[Ýš&`MQ!HK¼yh§mûy‚ãEÞŸç([m&gÊÖðlõM_þ¨ºhè“Í·'å‚.Î60C×)¹ÕíwðFúK§ÉùÛîÉ-\ô¬F·µfU~.ŸâmÚ¾=S-ÞJõ‚,MØ`ýÐ{õKRÀ³´÷¬Öi÷ i.ÇÃa„¹ßvû–Ò¤}&s©z-élOåŽiþxõ”rLÕœVïÔÊyn1†GidIìïƒ.Û¿`þ|c±¿×\ëÝ¥OÒÍ J@¢ ýÜ|­éŸ4Š EP ²^©鞣Rz¤ ±ÓúŽFIºrW¶¤À·=¥–z_7”–ZiÖí‡màKöJÃ"‡Vz,sGtç¨X™·èþ}oÐ’HW «uÈϱ•‚¤Òõy²šõ& ŠÄDð$O%¨ìp„ w}f[‘€KЇƒÞ�$Ä–¬#¨G¡eö\@*ÎÆŸ|Yƒ®óŒ{!4BhCÁ&T8J8ÔŠD¨EàDØ1Q­¾@ãÅ^PK„ó•Ø\D,‰¶¶±ŸD¤-¶Ö7ˆÁcSZ÷S&˜¶Uº'¿iP…\k‹QlÝkÚŽ²u5Ö±û9¾ïo2ÅÖ{x<ËéÏ%™ç„ÀÒO˜ÓH»àê+Æ’¬ “¬†ŠÂc ðx&R à#Ø03üOuúp=ø°Ækg�ì‘® =ÞÄ¢{äÝ=–7ù£†5ð2G}—*Åë 9#Ñw´ž—’^\ËuïÙÏû7ôûîtó=V6¢`yÞö×~âñƒ¿ÞÙà~è <qóø7¬ÕÜ($œÉ—t MÿñBoòœ6yÿa·qóÖËCàó+ï¿ìq¼qŒFgL"w莖Œu`Þ8ÅIT€{ȃ:\ðê6v)œHpžMwÀQ­¡WäTC®À‡(–‡hÂ&÷@2‘x–�š�¡"=)�…ª¶q^„ݾ'ÿ ¨€¾¥ž ŸCo —Fé¡h÷ŸÒÖf°7ÎÏžµ_S²BzH#EùÛœ¶QÉà5d7½8OÏ ‚\Qýì]iaPü}[ û¿éäéÑ`þ´“¢Ðï·Š3ݵ•W$¾‰s Þ4‡ŸEÆ1­–‹ÏoÓF!Ö±Ö©6¥5èÊþEx½Y²ÄˆWUñwÎ4ðq«]ìÓ˜ó”iïVé>©µÈ¨Ü]]eÅ¿}š_ŽNo[:åêìàU?&}u”d­DP†iÈ¬Ä ‡‡ƒ¹â `½†A…ï”v+0  S"a»tVª 0eX¥ xV|H°¥¸$2€dNmÁ‡®� fiuÑ~rúÇN³[þBÏjäÐlÑÓç4X¥b›ë!8U`[ [o³BÕycÄ¡©À¼ÅÝ:wë"ðE�®�W#¦‘ìR.×D�{CE¨E®¨G®'á!¸å#¤@1T ¥KÁ  H_ &‚º€©D€=™I½ f7^ìAÃQˆ€ò�›® «Âe VÝ-†¼ÌGgíTØf[ ¨IÀÞ…(BjÍ÷ÛPº·!)P‚ÄS”b�©’ {RmÞ…½ßÌ( @"­«Jêžø#AJÄþ ÊÇ ¨¤ ñ4K]E@á¼°%E�ì‚;ˆš»4ó›À¥®æs$<¸Š»5.3`Ù[Þ•“ëÚ/øõ ùm}DF 2Ãf_¸ Î cšÖÅ4x+&Š¿!lçF[½qy™æ¿ðà=ÖÌõ ÉI“w+'¸þó|z/$þï¦)47¸icÿŸ6|˜DÄofky7Áñþu<äšx—˜³¦Çg ~àÁ Q7м&sÓFà]'.ĤgV�¸°/û2«,PÙ¸*.ÝËĨqÔxpkÀcº$£3ŸÕ…*”Ái €ÂvS¡A^‚ƒDI= € PnÕìÇq Úäð¸A¹‚ˆÁ©ŠpÍø×`MÞKY¬ÙÁ>±)¬Ÿ÷Û·‡(0ëâœô—­Ò¼:¿Ð д²ú ý”á6RC¾"ý™n?=R´£_§´N åV¯y–¶gq1°Žoõ‹ƒvþâû\»ÙŸE:<mÿ `îåK¶ªàþÈùMïZ6ÔFŸ)Ë|uf—rè–ØÜ9-ôW¢vŸÌð\Wj8n©Ÿ7›8¤:é`¡ˆ%”Wþæý_þ±üy¹²þp…Ía•*†üø)-Wéß0}§òsQjü ªÈÓ¢v°ILô«¿X~ž?T•6gXÌ5K=P ¥x6O U I¨˜¼åÀPX½ßÛ‡°‡@áødWmJHZ°³¸øñÜâÐ(µÛs ªw<ÿ§ñfùä ßC<ïë]-Ã’; ‡¢âD<L¢ø+VQÐ[ÛÜêlf÷�jÜI5\e[�v·… x6|‚5™u²Ž¹·eV%À(qð€ÔxPÒO¸”c‡»à ‚yÜÅfÖB±çbÓQ@ –b Ø×ˆ_�>U–8"\øŠ@P¤.ˆ¶wÍ8ð9¡ˆ}Þ[‡³.Õ1,�Ô9pk°Ú+m€òz4z¦Dœ$v&2ˆ—šÁáK}[,u,^ÂR”`BHÎ!b8шOh"ö¢À·%å¨!†B ‹p�Ò‹FŸ5O †‘[Æ-ç2Ø»"¸g,¦ ˱�·&\ð+äÙãnÇ[ãðFg†ëáÆ¤)j©úàrfÒŽ;¼t`{Ÿ¹3a:þ->UâëÖxÞMàÁU-åò±v';uo�¾Éfô¯r6|H}÷>Ý*¸¶ ›DªÇv%?28Yêúµäç‰ãÄ ]Ⱦö§·OõëÈÁåñsé+>i0>ÕeL:pycSQžP‹YvCÔX=TEHz”IiÆ_|(û1å}�Ä*‘èù§B—857 ݶKàÍ–Ð'Q uàð¹ÔЄ€(0@Ãù:µ+Û‘A‘Bº`18È“ÍáŠ>½0þô*þ×ß?o¾•DWJÕŒ§…œkÙ)VW¯/zC@Ó9õªõ&yÕj ߇}oçJ‹oÚ ¯’¸‹™Ve¾Øf³…%Å¡.žÐë$gš}¼—ö[(mbÁ–GZ#ú~Qßy…Árc¨ÓöŒÌ¯æÌo‹yÖ;{ª†OZgvwùRd,•fË»8³²TbG¹|y¦<O~6;o®•?)ÉÆ\»HTÿë]”ÿñ£¿ýè¿•WJ?RªÈÝô‰•†`/©nŸäKýô ñ)¡$Ùkã‰VØú¿YÚJ Ò¢6 ÒÐ*ªÆ³×ÆÊØ—ÌRØõ6±¾gQ(XÒƒÓ\QçãVW¦Ä®–l£nŠƒÃ½R¬i¯£WµˆMôÌ8¨ì±„ÿP>lËÂ:«�»õ(î!¨ó°&û™ÔÖ}V]‡ Ò„öù~¬.pg,3gÄÞn² (N ˆ­l »ÃqÈY¶ .ÇŸ…ÐÏ€ ¾OEàuÄžm€K Q0GÔj‡F ,¬Ãi ©$Ûßd!´â±ÐT@Á]ßS„‡Äv‰vS; àñ6È—¶`Q&\µj6(×� ‡F̰¥²e'mÐùóøl(“/ {ÿTaØÁ."×çîŽxÂÊHº¾ WAC¸à®BXC¼ Ù$À³µ[PƒMçâ*R~ÂaÔ·k—Æšõ#Î굇,òóª[Ù.ñ+2Ò±˜2k˜Ì´÷nÊv®Oõ¾î­ &E¾þ4ëOsî'Ï€Ú{Ĥ‰ÉãsýI®ÑµNÝýµ†ÿ×9>˜8z“paê;7 ˜³?•;=øŒ ýU>óÓô:\<A4önÊ…®Mdqi¤š*—%®ez0É¥<=»E\ð¸ôÖìÐçŽ7Z}J€¨=—"�— DÙ�EZçÔ‡cFÎz´[Áâ2‰{°«Ï8}CxÑÇb%j¥öI[h;ö¨ÈòLa)!wx’}h¨¨ ¦½,7ÔNAó]Ø–úŽ5{GrøF6^¶˜6,|ÃÛ=4¿DIñ‡ÔzYlªß¡ÛáG¿Uß*´ãâ·'q{VáÜh):ø}Ú;k·»8ýˆô—ÐvÜ5*wŒÅ¿iÎÜ2nåûøÙÊò¬iäR"K…Ùò„\ÄÆŠÖóOqmwV¿‡ž·WzÖù‚QRÖlw³<Po{ëå³v¯Û(÷£â2Ü2Wf›Fï¤?7wëÝÌìé =m5Ïâ?öÒî@wJË‹óŸÐ²l0(õŽŒ™‹~ábövÁXi¡Kw ”49²Q±fa®­Pé)ëÀPz}S›Š®‹ÐŒ¶RM ®Û(–ªÆzÿÅkÖÆw ¬k¹£ì#NK †‘†gjqØ;X+‡ †Pí½vÓ>HÀ¼X‚9/¸Tx¥ê�©Z�JÜ}±)iTêX…»À’ݼÏ�¹¡2ÏNŠF–hï#ðùÈ@Þn ñX5îR„ŽÀºpêQðUÉ@$‡‡-ب!ÌÚ¦dA@Y¨Œ; 5Ò€`@£Æ±ƒ]¹¾P…Û¶Á('ಙ² f–Çä!$à�åqeϪ!†•&IİÀ¡'„ 1Ø´.hWÙUS ŽxG€0 ܃¡²FûwŒ’›'LŸëµó¸_ØÜmÚ®†Î$iÛpw¸‚d”˜˜B‚g^÷ÎNÖE³ˆ‰n]5æ|Rø�¢pܰáåñva,qpv�ŸÅª@;T1Joö¦»û÷šÔ�W™+‹½q5s§ÃÇ‚›äÓÓ`ÿ`'=.J•öÚ2f <?l ~Ô3ApcŸùŸ?þSEàý”í¦Çw' ý‡~qê‡=> û\;œ‚i×*w$¯ç“âò?¡6½ ó¯ïæFÖ°þHÖäR!G¢'áz™%Ÿˆ±ÔàB0OhŠp¨p£&R¡Æ×‡(õ<q\i€BQ! Ú4jRœ¾°S*`€)Á ØœmsP²ÇSÌ”ñº½^G ²Å¨`Ë0A:›ÿõ5ÂlóueSµY¤ˆ!+`m‚¯µ&M{•ؽïöP‘Ÿ,`mùàî![;“/gÓâ|úr-VÅX„Œ%µ×/Y½~¯0SüsùBq8CÎNïúi¯dÌ÷ú ws7Š]¥p"{Œår°bÊÑ›#ת0ãi>oôgçW4ú ”|QÌϨáŒ9‹Û¸è6ßþÇ'§Ã=TrñèøUŠ|{.7TíÞ¯P¦Ý!É•fd.ÿ§wçÀq¥‚»‹‘%AÚ bùßÃX~PÜŽ-€( ±Sʼn–_k»ŸFôÚ@9·I Iþgks°�Û‚T!Öþù‰E›ú0Æ Vû–:ѧHÛÊ8&0À`lj%ªTP ö×÷Põ›ü_*¬b©5‹™ˆþõþ£rñ»Í×CàuD¾³¡ø" ˜`µàÌÖèSÖgC*<a ÒR„5›¡ÝøG ì¡.‚šÁ ¸ ÒàÄ‹Ý/yf!“#v¸[Ϧ^ùplQ;0A|ÈT�ê*ˆ}T×mi%㯤E„¥x�l!B{sk‡»&$¡ZUˆa±:ª`$dÁ½x—Øò«(! ŸÓЃÒ`£ì;®nºŠ“‚Š „}v"ZÙ¤ÑdVB¡}‚R0…“™Ð�A¹—rPÀçØæ.� éÆwWÙ8²ÄõmÄãò}¹i<°3c gº)Üõ�ÊÀ¥Q�À´Ç)^"¨!¨‰I›£©ÅÆ•N\Öw“¸QÌëâj4q§—QS± “8Ä4çåýÆzlïáO)Ód$÷ñ†ÉSÊ¿Á£é¯¤oxŸ<+Þ÷”ÛíR©ü¿”kuÀê^€‹ #8y×ÞV>i¤á~ÐQ<ì鋜æ8_ePG€@¸#Ç`ì" øEà æÁáúh(ÎLA43+J%]Н z 쉰À¨!Þ`*i�� �IDATÝt¤k6üH†ËGl Wó]D¨É¸Î7 Ú”o¥b_óµ-ôÿ Bœ–¬^/Ny|÷.Dûô=ÐàÖ!ŒûBuÚ6-Ei[‚rª÷T1Öó0û,¿"ç±QXhöÿH:¹ÍÅ…= ™rqáÝÁù…µÝ*Ó!Ò~ouØ=ÂPŸÌÙö/‘ÇçXû-J}»½&tߢs1Þ ²Õ{ÐËÿ·™=³¥5-“|ÑèæÊÖì|«Ûþöuž²gåáh¤i~6\XÉk˜ÐjžÆ…tcAcΜ;ëw‡½ƒbñ~®ùìî¿´_& &Ô‚À'ˆ�‰Ä*QÝL5µy—쵌¸‘¯ZgPøïŸÑÛº “ÿg#V{Œh$•õÏÛ¦[))6±÷›Óë5´²¯› Ø.Abýês}ZÆâüß(ÿºˆö‹(þ_èŠZj®žÈnjµ¯ H·û`&d‰³¶p¡©ïy÷^¦µdú†º€â÷=<«G ë©|cÕmÞ¨ Ô˜»cC# `² BûŒ¬ËXÁUükˆpP  Øò@0Àÿ'ÁWb£‰‡Š‡÷9ašØR æpYCfXÉ«J<Î@éD îÔúîI47ò`B­ÁTýb³×– ÍYæ›­„CÊC%$á÷ ¥‚|¥(þ;P)�`Ûê hè”9‰R@Á1è'¬öÎTLdz¶¼4Òß“�̃ãsP„5ÈLZ;Þ,…uH•QK®ŠŒ;!"ø”gu#½Bf~5-˜½Öì‡>L%Ï_OSð§ËÚi­þÝ-¸‹¿8¶úÒÁ{ì"~õ ?u1Ùýõ󢯎£kŠqé…+¢2v~ô¹®±}ÝK2’©€¿'—ßKçGxµ£ÉíX‚TŸÐÞú±ºâò´ŸÒÒû^´…ÈQ;`'>4„²›¡â�°¸& 8!v†R>W!8U<®ˆPF£fK2 /bHx `Yªs†h‘ ¤¢0AŠ«uNKj¼2X³¹IR”¨°ÚQ·‰ƒ/¹ñ9GpÀÓˆt�غWnÛ´ÄuAhµ¹Ö†9ËŒ2]l#7Ó,œaa¶´ºðd8£çJ˜{ aÆ…õþ)Ô‰îœ?3r8¹ÀlG}‹'IÎ*ϱB_ê;ô`%Z=¶èŸtùÏX‹a¿¼ØÓ%ë÷$2Ï¡s wÌÒli°¸Bçíã·Ê¤ÏÈ6è$Ï[’3£û;–ü9&'±î?¤VºÙü9ø!Á¹GHÛ³jõÑÒpVœEt´Ú—[ßðXHÉÆéfxùMLû"nh­Í?{£4Þž«{ÌŒ ×›‡ %ä)1pªØüÁ½" ï<h| Tž~­­ /~¥0w _­ã×éz"¦6ÓT‘ž>‘/Sôô¦6p˜ðT3í³ p”š¨�»YXM}dñfe¸ZV)`ÂÝ�FÁ ~ T  bæs¶Íõ=¦8v°› P€à‹-Ÿ;ÚEâ<g¦€®/â(³’®P¦M`î—xP!;V €)îÔ©8(  ÖÜã¡/dŠ˜ÀQjBö¸$vÑÐòôW‰:è5íÇÛ` JHðÝO 0—‡(yDo –¹Ì5GYþê$2ß:dDËÀ2¶Ø6P{”­}ÂúHÍÁ=éøYÖPÎöôꀇ@@àÔǘ"ÕGTÀ‡K… Xu‘ý—ë#€‚*r=áÞ‹Ê'—Ø“õÄn´ozä]uñ}QsµMò¦m„n"!pëýèä1 Qd¯Èõ¯ÓmÜ7™è?ÏOéºÈ`ú5°¬™Î5ubCÅGÊÜÀÓÚxkcÔ„SîD1† ¼¿àâîÄ8N<Ñþå&qjèá×oˆÌá½ÎÃx6höz ÞØá¡’Ä@»ëØJ`ePX©@êH=Á P“Jqµ.ӀРlx°(TÂd 4aW(7ˆ´€<â@j›Ï5@k{ŽkJOCT|îÂNš 4Õf+ê…ÀkˆW–Õ_YÄÌm g°p,[…ÞÉYqyîn4fC·TládøªwRÔÚ¼}V'^àøæ’2:˜ï’þ£€EìÙå˜|‚ÖüÃãYY-‹{3q1GK}Ji:„ñ.ß»]È§Ãæ›n÷*-äzÉ1,Df¡q@l¼bºÈÿqï÷Ç•gy~Z"S!])%Õ½m™åíˆn{—DÍŠhسðôt¡°Æ° /ˆG¾^dü ø"q_ù@�~I€X@€ŒšÝ1fåPÓäŽ]ÙåJËuoIJùJ¡LR5‘$“?${{¦jý`Ø)23•q¿ßï9ç{Ž»lÕÿhì¸æûo¦{¿ßÝpŒhd€»cJÉX"­nÅ/nëò}£äÇåšefä ®JäûÌï¤ ïü¢y¹ùbîÇõ´ùG¿v]û VûÃÞ—O÷´«¦#Èçÿ›kuøä3õÑÃ)kõÞ§àíS§ëoÕ/Ùš8"IØ4ÞD¢-8*œJBÓ$Äù™}h?”f:ŽjI*wéWéºfôòª„3ÌLÑ×lëEC³¯ÖdTîoH'¦ÂZ§E†Ý1°¤cQg¤Ùg8ƒ3„™)e« Ùf˜aÛ‹\j…$H½×‡íŠñn™S8 µI;NæØ~;X•Sê.8xhZÁ¦JYQîŽÆÐ˜40u¨ÓðWédŸ¾ɪ ²mn•Ô„¦÷¥N¥nkÒˆu3:ܸpP=k¸qI]…¦Ëý÷­—¨± µ3ÅQ,2mû­iN¤á]d0Ðо*Û[»O*)Ûóz»Ø:6¶«ZHkTö) v:íÃUBEf tùÔc"‘–A»aœ;§d?*;ÙÙIç~vâBgèsÒ›2û‘:ñS‘ìüÏ›ÿ¯gû??¥Óûg>‹–4¶œsU:£•GSö²°µ¸HeÜ;ÿëùBÚž_…;c‰~²Ä`N×3Ø%1Õ½ìˆæÊ8«Ž, ɰýïL§}“`l^¹ïl É6m3ðX§;àƒOñXeb€†y•f¤ë}ØÁ´h™‘$:´€ƒA2„2go@ â.¦Êy„cúÂÃØì¿ÃÁŒ5Œ÷xNÏœV’o¼òÑ5bÇNO2SH“Hôª5 Rûõhým„PáõÕ'ö•5¿'X ÿøWÑ[×gÁUæ/7¸µvøjïYÇÉÃÀ‹É[׿ƣ«×åÍËx¡ßüË6½¬ ^ñO/¢ùsä­‡<åo:ѬÉÛó©jÆb%¼þâgÏV¾|úìæ¬¹¡‚º#Ç—«Î^Ì<æ·øÿ‚š°v§˜Ü.ÿJoˆHAñžÕ7Ÿ×üV®< B#¡ókL_9'ü[B”lhž}ñè°ê¬n^}Ô%àÁõÃñÊêdîê·k)åäqe÷wy/fÎæ·]žüê·üϸ¹úmxeSÄ8®×·¦×¢)RÂ]mÛÖÀï3öÞî«zç‹´«$1P÷}\„ÆŠFe<ÚY§‚ÒÕÃË>½°6ӉģÕä‹ÁVÜ?r[V:·îk´b—¼Âƒ0"¬Š°Ž0ÅàãL×™N½JѶo¡*dUB=€m]Hv¬jׯ‡ÄnÇÝ–•z3Ã{;ýDoHÃĨÜl:¹aUä¬}ˆ* A"ÆLE´vßÚövPcŠžº˜OcöcE ÔŽQ²J½.Öw‡@¦'û@&r¸Û+ÜŠ Øg"&F|¥@ Â(©D™iGµ£?om û:ÍÍIú6Éuë¼Ýª<–êäí· Švƒzç$ù§ha€Œ4W逄¸'b¤ås³È ßr úÄKíøOû§¤ŒÉiÊ:=-¨ù1õ¦)—¦–vŒ°o ®ò>óki}aþçä §–Ë ¤§ýËØ‹ŸðàÒµ0®É``NŠg¾ž£ì§e$®ÈIå‘€,?žF—¾§Ü'kúF¡–-«ô®e¢p ‰ÉZ›FC¨‡Û¦›3ƒ{RßÇ8‡Í´5(°G×4™–9£Œ4gµDõI”Îi©ÑQ º™Þ5݇L¤¶‚m:;°Ít`¼#A—!ɸ*ïÆb‚wØd]—û•\]Lj‡ºîNº[!f<U‹ýíXw>4\$Ü^í~Ë„çbeÕ\¯º/»Ó•—/ódõç‡û‡31#‚qǽóüìâiøÛxÖ}yãêAóh¾Ú½úÓGÔw¾U+?îfÐyêVW-+­òàòÊí—W^];|rØ4~å27¯<˜?Õ¿ùg¼3Z:Œ\×¾5ª«™Á>IHÛ?Zˆ€k ¨’\‹?ÂT˜;è§óÝεšçz•jüp-¼;uxf"¸ãÅKñà2ê™g&¬]¯g?€FMWkÂͤ¼5oæ‰] xä6àcö—Z:3‚HF=·5”»=·»E¶¥>ÅNv£~]4Î 7”l¤ó#ò6q°®‹¦ÚôñGΔwµ}HV…Œùʤh²j˜‹š­t}+€»¶˜‘:J´u»Ô÷BðªÀâ@êT¶[­Î‰7\ õÛUl%!…g¢uzN®«¤^c÷#¶J°}„NJvEÇ„£é…¶õ•±!cÝ„:º÷IUâ5˜B Ñ‘¦¶è›9³jؽçý}¬Ì;êíÛ!šg|‡W×Gß4X`Üå*…µèT2L¨¾5jˆeGû#_n+IÛCy¡w7ä‹Nq‘îåZ¼ºÖÌA±î]„0.Òy9K;Ÿ 8vÕ,‹¤¹×SžÄ¿q_:½Ðìh™¢ÈÏ;ÿÔ3ð¼çõ¡¡¯cS–µBý?1ß O‘ïG$OzA2V¹‚sÞ„ÙEõ0{í ”.…G3æ‰upŒJ—^4ÅGÆ2-q¿ÕË–°¼#eqŠ^LB;Iñ¢“ŵ¬üÀ”;¦@1=ô^¨оõI€Ý$7½|sÓmwA”S`ºGÕ¨èC¦í€¥rpøI5à!{™F,.µ½m¦¹éõuˆ.ÁnS†qò^¿ë±XW8ʸé`'É4Ø«f¾ª ~ŒvëFÞdõ…®ûÇWö®]o\óï^ÿ“¨gõW+×Þ™©ðÕ ¹zõÙácÁaÐíøÃ•QøJÜ:äûO‚ø·V®põ«‡“•6EtåλM‡Î³›·nŠù µ²Âí«þo®uçWÅ çå‹ÃƒKÞó¯ÜÓçÏW]Ï»okÛ1÷Bõ‡k¦¬¤ðØmmR´ïT£†Äƒ³åÔ_ƒ¨j¯ùª3Ýš}ÍG«<À†N¸ñNp[xüè1þ9®®­5µ„i½Aï:Áf©µµ·¦Þþ|ΓsŒõ£}å ^êÄ‘¤f«ÈL-·Ê°*¥c'¨þ–G§¤¢ïì~í�b+t)UÙ1©·“÷v‘Qòp7 ãX}µ»�ʉ{Y}œD_HY`ï¢ITé´u’Q+R\[‹„Fjåv ¯È‰ŽÄÖ ©p=±›ÊZHSl›H’†x(¥!³‘ÔÖUç‡ÂàŒÚÙÝ\Ûˆ‚jx‹w©™­¹k”Ttan¸« ´ éúݺ~hJ,}óQŸÚ™Ô™žÓ…`è*UêFµŽó»÷dX;”üõ[öúÁøÕaä§t&Ü’?Ú×6Ðj¬£vŧ GÚ‡„^¹JÑEn{àǕ퓀Í@P¸g¶’E [ eúr¡ÎJÑí !í£Ê-– —ãNd‡Ç¦8©$=’-B!ûKÖm§÷™—1^–¬}ÈßpRqlÚÆ™®%ã´$÷ s‘.K]û¯ù±%‹§ üìâå¿anXªQ¯¯xåEŸŽÞfÙãð\©/:ˆ –®_o:øºÕÁã Øå—.—Ë’eãRÜ뱩j« )rThÚž(tÚ­›î¾š¬Ç$†N³ˆ®ƒ[Dú!Q}Ä€ºÊ‘€däLÚ&èfK^°è£v ^ ŒÚD ]oö„f›Í{T›.ÞäèÏa·­-»éôž„~åq½ŽÚß]ëíu›pc¾ûìéÖ­ŸWÁLðÔ77å-Üê\\zûNp?þÅ‹ÙÁUÿÇ•¹k¼ÿ»«‡Õ¥5ñêÿõo‡âÒß=yµË¼¾µ=yÕ}'¸õŸ=Yp•[â*—_¼|>½ÒyçÉ“pµ¹ºòW§žýLÎêî_Üxxù¼yëãgc¬ìMF÷n] è ¦ÞøŽfb*iâa@Ýì*_ãwc;1ôDü:ØrÎtaâÔ»wy:‹›d·›oq÷‹½k«~çþJGH3–µxžGõ”Í.­ÅxÞ©Ý—¤ûɰo‚Ü6É€a_÷rC‹t÷û,­ˆþg½+ˆ£¾a {‚ҥǴa´£œëô’ªÜ‰Ù6ä: MÙ’YMB9Ð"azc]„FIÄWôBÍ6eŽÍ 9›ROúFæúž4…Si—ùBY¤ a›¢’ºAXgp€âýøƒ±™K¬&߯aÀCG…«vîÕ¤IP—ŽdM}>‘9²Bm¬"æñܛپv² …õ^„Àoµ;e¿–æJaA[*å ´ŒÕš\ÛlŒ÷FèîšÛ·Õ‹l~ƒÆáÆ ŸŒÐá2Óh0¥#AŸxnJp‹»cqñe;/ÎtIÚçTTûÀàÒ¬ceçB““fg$üæx+âT0e~$‘‚6P:á¬ôèÄ‚3;}úí\àÄóãÈÊO?cÝëýS‚µê›'†3ü÷Ó)õ_³FpúS(.,SK…·=|Ëó{†œ 5Çr´eÒ…iGgt»Å9 (=íãÔZé%ÇIR'ÿÖ‹Âp²¢q”(’™ã¥îÂUEN„I¶µ¬Hƒ‹¦2¶û$¹>"É–0÷)ú¤¡I!u›žc#7VrFÎDèaŸûÒ}¼U "³îµí›Ú‘l“î·.›:Â0`Ò7¸xOš–žÙÌƈV9Ef”#Êãîû&jXcˡ˿5›Â\}ÊÝ’o™ÄO/m]–‚«ÍêU®¯ž¾üç§ãƒÕ?®<wÿÞ¿pîRõÛŸ ÿØ?¾réïŸ|ÁãúÖ«^¾òÓÎôûß|!™­ÎàOþð´3[ýÙJøò¥»ÌoÌ/_ý‹àZçÒ•ƒæÎêïV˜v›¿ýá@¾ðþ7ãÞï³æþ{8©[‘Ì䫪¥F¥Ãº¸S;ØÞJúZÈ8Ôéžc8Þ*ü–Û7^0“:yßþ›©½™˜`°5“Õôᯢ'þK ×ÄÚû̓õ­ÄéžøÈw§3_z·±¢†§Êoà(ågerFcmÑôµ§mNIœ.s]fê>#ðqáb„©wtí(ÆØ>¥cS¦ö5:`Ç#Ö«r[3Ý*U”ÚbTßô¶u‰Á+üf½N16÷óʆ†*c v î±[ À–@¨:}ß$娥a@Ý5Gä4¡Þ¼Ëæ¼BªYS]=dÍãšJÜá},·Õ´¯ÿÂ…á×oÅ3÷qøó bŽ›ïN£°²}ë»Ú‰ø¿•®›4¤¤ú%àbëtâLDœH¬Wòý5äLÉ©[×jÝŒ'úñc¾«ÿ8¦q8L"±ŽÄñ�ê.¤¡O’é²½§$i¦q:…bÿäv¶G7¾jí@vÙ'nE_“QôͱŒ°xã¨0Ù²ƒN—›+õ�Ïh#l-N°t)ÛçDŸ’/ª2çüïΠ K§n¥4ʏà4ï_tæ¿_(ý£<vúçà¢ß$4:ó“'i×ÅR/Ÿœ/‰gwöt+'].ûoPÁž_ó,•+“\˜#”S£œmt×Òä:mÅv9§u¦‡Zvyᔤnk~‘UIŸÖt/mõ‹­b¼‘]fŒZWڌݥ"7­ÊÊæ”¹Åñdµ²Î³÷` 7¤æ 3ÖÞn³Æt䪤dC¢ÚR‘“fz#Ó=I$´%þèSð®«î;æêû4kÿIϺúÑsã­Ï`㟾X¹Âô%¼š¹x¹Ê,p¸9ê¼_ònZ«æ±s!þsíæøÉ˜WŸ=»:»z .qãú«2P/‡S˜\½ÒÞ`*^¾¸&üꪸìŸ6Û«Á“Ëo¯4ó+”߃ïW^<£ß°Å8?z­­A×DãÊ®Ç^(‹Ým›J“:Àr@óùÃVOšTâCma´oН(·õ£œøÌ‰8È’ÑÆxäWݪ‡ýª\g §Á­ÎÚè!Œ•ï„û8rÊòq’›^¨1‚ƒv«V}]dFdXb‡N%Óäé¶N}¥0iF”c3& ZAÝ€ºTi‘‰wPb1Q`£}ƒÓÉN›Ç¢ØÎ¯p:BÂx#�°Cº˜¨2û±BÛO+á!£üJ³™VÚlŒ‘w !Áû|˜é fgsðÜ®®FW?(ÿ?n¼=ïÜ0¼²ë7 >ØX¹^½õïL·Kx;qç-°u…ÊqSC—±0Åÿ©‹16³…Ó Òõªx·[G}Ü|6k9†Æˆ} šOcOL_cO!ˆB3”† i£Š.1"PKŒ`Ô\›I czì“ÚV…Á£À¤GþBÅ»» Ã8ÆpLzá¾ñôö—Ŭzi1âd™éħçÂ|K¿.ÎÌù½·Üƒž—¨æ'òΟ²eœœ^Û¾`íùÍÊÒ?Qm¸�¨y³)à@ŸôïƒeÌœ-‰ÙÅÃJyzòxÃK—ùk¤ÁXïµÖIúŒCa‘-H‹ :Ítq¼—™"#,h‰!»äÆ÷µwÕ|Ê ì/îaÒ)1- Hêãª&¶è™iéè ¨%“,®á02‰£Ì$¡’§Î>í˜Õ¯¡n·w—î�¾¤ µ`‹D7ޤráKØÉMé Þ M±ªïƒæÆÜj¢•9c"êÎc=ûÉ•oÌ'—ŸÑ­o0b•?¬ºƒÇâÊAtÍJw0Z¹mWV…äÊ*KpC°â®^n^žˆ³ÃiÌ/weó—|¿ZÏî¬]9”«^¸?^¹ñjþÖo{!;×.¿øá÷W/=sׯ¾lhšo÷žNnüyȇÿ(ø ŽØÚ»†úDköŒÛô.|¢7]È®*œþHîeL©ÕXã°I½V-s“W~ŒÝÉ1#̽núН¶Ü~­B±Ö©Ô¾UžÈá¾tb2Q¡îÉ8É©Ùí§Ž†v ×…3ÖðÌM:P Lz¤¸K¶a‡r‡r�}k¥.rj |–8¼Ô@í(`êÀé T‚Ndl* —è:ÔdÍIÀ:ËÌ(LwݤT[°¦6=±þCHÊ.Yµ1‰{ý˜Ü´I™6'ñÖÁ5zˆè!\õM£ü-1½ÌÑMˆŸàuosóç¢{…ùsígêòUÈêíÛ/¬¸¢V_H¾¯º×ƒ¿oŠQw¶eÁñ¼¢Œ4'¢²w«á¾MJ²AoÇ&“_;W[¯A Oºˆ‰±ŸšQ¸[ "výXwÑÀl„ DZr´ÏŽ<›Ó!iCæçrÚÇf•ÍàH¡ ª}¼5©\ ÷DÙÉËX—-ŸV9æ O[G‹bcÈ+–¸âc¬¿\xB›ÅAÜ?â®óEù)ÏC&'ÚH}!˜s1æ³Ä@Kù1o¡¾$?o*^œW–¾ñŸ?Í^ôЮsZñ†`µÓPÚrìÑ›ö¢ß ´-Sù9ÃŒÞy!A»X¸dõ±,K8Ãp6{ðah¶õƒ£g‹0mòmrîm”ùsà3’îͽÅ2§R¹µèM ‚ÕÀ¸}í3È‘pSòÍò! QÕWå°”D µG ôŠÕ­’‰-–ë8Œúžóå'†–}úæÐ\óÚQqËÞº¾yxõWÝs8ß¼ÂÞÁ«o=bE¾z:þ¾«Ô.G›/k®F³ßúæÝŸ‹[/‚ÎKw©+o^]{¾2›?{6çÆ¡rO.­]åòØ™®|¿z{ír3›¯^½t0ûnåðÆáåË/¾Oèþ®™È­ðÐÌŸ³wMGW¾¨í)§ Mâ¢r\'ëQ‘•uíˆÞS½¯ãÏSw$ì’ùK®7¤9Rt!IŸÃ$#ÁSfحƩŚáísú^£šìÇ6Ûe°…•ÇìØ¨PÉíøÞÀ|.øÈë¡Ûíe[ÅŽQcmO´ÎºÌvjvT9Ž aÜbšÜDèTH²M‘“®›b_Â%¡Ø!è2z Bc=H&†5ôq-H·¹ÿ)ég{~„Ój}w­SïM.†]²­Ö¬E®«Ñ~œ†žúŒfÍñѺ*:vc5n«äÊMÖÞãÆ5ÑØ-¡þáò[ÿþù¡:˜[þ¸ñ×òæüþ8{´zë;ÙgŽ·±›¿R%X¤bÛì‡Ôéá]zSSl£rÚÔèÅå-ÍPêÚÁ<¬ñ¦«&`3»±£GžsFŽ´]:ëq‡'nw‹Ï¶X„bca ât*)ú§@à°èî èav$mç">òDt"5<ëŸN‚[üïêcšóÇHÖcBtñ×,Þö)3?qîûÑ]å "~t_ú_¦ ýÓïE¿äÉ/ð×KÏ©KÏZŠ}I~îñüäƒH/‚Š¥Ï±8š<–}[{K®ŠËŒH:8Ó%•B‘-Yõµû/}>ÊP’o¶õ8¯ÒÖ@=Ðv°h0OrëLd$PgX ct™k…&·IF2qìmóÀiŸ´v�� �IDATaóÖ6‡`jdfÆÃ怲íž2¢8jIä°ÛÔc>ßÏÚçí:®A ®š¯o±£CA³£;øJ¹[¼%íÞ€ßïÂõë“W7ÿðòÀ¹àÕáƒgêొýô[½úʿՉïÀ¬Þz²Òð–¸q•ÕkÏE·Y½yãò;Ïn¾#žß˜Í˜^~üj<;tî÷Ï¿ý}ûÛùc&OŸ¹?ø'ÓŽÇI×]kvýœÙL)ª þÕÆ¾–ÿŠÄGž£Ây5ð 6ë'vu©‰¤Èêûy¬rÍÈ‘®«£DõyÆG6§Èu‰ Æ$Ö&ªÎw­Ô¶1Ó[XYE¥œ‘É6Àš·¼"ÔÓm†}jê"Gy-2 j5Íź­"WÅ8N °€ÔQ^©u]g¨u“ŒöµÊH·!4cóªöfô „üý]¤'í+ՠض€êrÿÓ/F3a„`sý³„îÞê&k¨õJ…µ*«ûá®ý·Ñ½}±šÒWÊ7¨€)ú~o\‹`KòŦ0/öpÂý½­`Õþnßýƒ>ø†Û?lv¿Êgß¼ºtçò#^Îíøé ìºZ ¢pÖ'(PÜÅcÊmH2èc³Š#5`´¹ªlJ»SiźMsÝl›ÔQ ¡6¤3tGÞ6’";àªüX•»°9JÛ̆la­ºhómŸnŠ\§’"3dºhïå#›ƒ"_Œ é’D§8-5<Eßé w¦oÿzÍï/1¯XÊ%Sÿ"Cìì!Ìy牽RvÖø/½HõDä5Å#ÿñ­ˆ?ÇÜpJGœ½¶*œ1Y:çnÔ>R-¬,ý…²èöÿÁÔÅkrVÏÔä#¯¤å Ys²Br Yæ¦Ì´m;£­È²µ|ÉNòíÓ–InZRq‘‚Gµ>k¶Ú¤ø>b@W˜½måtCèV³Ob·cÞÝÖ_ˆ„»loùE몤¶}£$NÃ`ln†¼­Þ¾?›ï~ñÃÖcæACèÿðs®Ùj:ç]3¹Á/V¨ùåøÅóêàreÕ^¾¼á.¹[—øþkšŽ··~‰)/³fÕª’]Ù¹}åÆ|Ö¹qùù³`åÕ•[¯V›k˜~÷ò¶}:»Äáuqð®ú›‡ì_Áãæ²ðsÄžï†ñÌW4‚ nЈ]ï¶È¯Œ[×cÇ(§“Ì”ÿ;| ()Rªý‘•*úq™2Ý~°ŠŒ]8DÎÔè4£(‰ö«ž´%Ñšðøx*‘ŽŽ(Äû]úµØÑc=©Ó­jÅf&E—9H¬«T&ÈI6FŒ”Ķmu¶8Žk*œ-ÑVVȘÄÃ]µ1Á¹Z+!£¤²Ž”Û¦,#œbì)çLjuF~¤œnå*TÒ €Œ¤£gÙÁõÌÖ·vçW‚é®ëä4¸Ù•ßÐ0»‰üxÖÔ«o\ÛWF\âÉ‹Ë7Ä5þŽËŸ}÷’•'?íV|/›ñÇ3#ØÈ¢f§ŒM“é†RC‰w:é/ÌˆŠ JRGéP·Nà^ ûÆgPjœ‘ƺ éæ#§?ïóÑq#Ÿé±â`±Ùp¼ÄP8R ®5¤:q`³œÇ^d¤m¾ÞR“^r¢A‚Ó¹[þM›XËÓÀ©±àø ,ÖâÒüœe?~æœè ²aïÿ/Aþ”sCþã´,%:¶ÂN_·ïw”s” ‡—#ÂóxÁË÷¬Ý„>+…Ê/’úf§ çlié!_Zfá8kÁMeÀ.ØÛ+ ” {´Ð, JNç’§~ P„$¹)BÍÂ’ž4Dm£ÉÀ¤’4¤›9jG’S÷™x¢œfoÌl ž˜ i|VÕÁ±h2-û¤9‰ÓC ¤î‡~ŠÏíËWÕ“êÍy%×XÙ×ú×9ø¼zˆ@Vôšc\«o¯ñøÊg\få%O/sù{5Œn±Æ¶â`Ƹ6ÿp™µçêÆ +¯t¹ñøàÙÁe¯<ªÿ‚—óéüéô‡Ýgßr‡4Ï~ðßà¿ùîãñï\ðxÎ÷28Ü ç=1n·!nßt”dPá«&T­¬¡¹K©äsÖ¤Nd|›n„Ô©ˆËÐB´´)`q*ÚiÉ“‚îs£ö+2”Q"ëi»¾½o~)PTõ6–-rMP±M$)ØM1‰4ºÀ$`û¨0N5|œÀ½l”†$N¥Y Œh¨Z6‚DܦzDÄ졚‰ L’qŒrÚ:X£pUáùu®Á[±Â/Þ›„X'hš¦7"ÑJ§#´ü `LuŸÇ>¢weµ·¾+Ägþ9«\pÝ"éÊÿeo?¼ñ•hžòŒzöŽžßÞ¸uÃ=šoüñš V]0ó«¯vŸ½lÞúáãßšæ7²ùjTË]wW£Aí=~Ì=to‡b Š}S`_Û~KÌ ÷¢š:4Pm�k&hLðo±;Z4&¸±wͪ½D—}>:ì– …ò¨s_@IýSòñ#JRŸSèë#/Šc 祼¯czy)ú¥\Üòín„9ZÚòôQv|Œ´vâ4ÄŸåMÓ×Fœ&²s/ú^¡xCŒÏ…Ožÿû'â¢_ˤgoßÁ9Õ×…„ÌYñÒQðÓyÖ!;?¸™2;ºPWï£Íµå©ªÝsIóSR°$g88Žî9²“W´ýã1h!™8y·Ç¹¦ ‰û„Ò1Húö"6÷°9¶õ„é·iò:•Ô©4÷3ÒÜ´¡¤m»4r<�çôd ›}-v, >Çu”  (¥.Cê ¼I§ZÞåfP]¾ÍÌrõ+Í 73Þçf. Âxm²åœ]ûÄLu`§ßÛñ÷ÍÁ·¢9„§LÁ­©ñãÉ?½½1¹wºúû§zú„gèï^M˜>›¾b>ûû仇îpêyú|åiÃJø›<£;ÃÉ{}Ön>žq£ã~»‹°k¡™,¼=âzf™RJ7ê °u7Va;P¼W—u™R¥¤1}AÉgö+­¤ÁQ49å˜[{Í¥Ó÷]$Þ×R[b‚¸¦[‚ß÷$>Ô…7VÆ sFÝÄ ¨©¬ Tá´ÇD;ºÈª4ÇúÝ¢¯mfJ¨b¬ âû¹NwÚµÊÖŸÑ”YUlr¬ˆkgÔ@f"§qô¤.0.ÛµëFI»*kÆÉÿ+Ù—Ê?õÿqü ð°å›øÞçZí첆 ©¡³.¼ð@ÊieeíÆ[Oß#êxç¦uСóRÏüÇ{ºƒ÷·þÆÇS4˜wþ²c_ñÍ|ôý?‹ñSÛÌÝfõKWÿÓãj²w£Þ]H¶’I ýãà q*QN×j@™Óú¤R¢2“ªî±mÐö!b[7Ïtê ¶Žu(«ñ ý q+N-wŽ h³&\ Ý[‘cÛ´Ý¥´²6Ϲè VÉ�¸ŸŸ²S+Nu{úÌYrôGÉ÷kó¥øüD¼TKöGèÓqÒNëêºýZ1äÙZ²|fî,€ñ³‚û%Ëbɧ‡‹r”/>„ó7Å?­¿ÿóbJ¯ß/^Hôú_¹À77'­D~1ã}¢V~ý>È)òù),h穤ÓhÕ1ñ^öM²*TV-ÂZŽT gO<�Ü ²ðÕÈ«(Œå˜­*Ã-8ù!øõŠ$~7穬F.VGŒt¦ƒžd$P‚€.¬bæ5 -NÙnüáCž®ï–ƒp¿zÅìÐiÀdbÆŸ*&v­ÏäÓÈNؾ¹¿C徎;r—ÆO»qð¼0Íõï~yíoþÿíóÕ.~vpù­•Ã'O‘âò÷öôåÌ]Y÷Atç|¬æðÑ4.‚Ju“د&™ébߪÈÇ=aÊ®bUÚÕ‘z®íµÝèÊVýx¼z ij¡Òq\b¬¡£qÕ“¶@#HJg¸ïp`Û¬@ ®b=¦©¬·›a´7®#ßÖ"7=T™ÅÉ�\–Pc“†ªô$Òû*’¶'(·±¹nÛˆö¥Ó¾îT~ÛÚ¢oÉõbßJ†¾.‰ß¯’,.sªk3Ø1*T"°4º7¦\ÇRáĆ Û¦ú¾Ût]—±†*Ú‡÷ñ.¶’9÷®™ûßáºÑ»³àìuF Õ5³~æw¸ŽªWíèA•>ãþ5»v9ºüžüí׎okçµx;OªGûöL»A5"Þ€Q«‘X®™Bj’J•q’,d‘m-:°\·×˜…43ä Ñ=Ì}ô6ïìÍØt|$øu?3£}­²#ÙO®OyìèâÄDÙ,Äâ˜b Óþ‰–?9uh˜bÐú/ ®1é u¬O¸Ììü 훜ãýÖ‹=®¸ôâÍÍûyÁäy†üü®Ø²jfpšŠÿo{²ÿ¹èüâ÷à”{Éy~æÂ¡i!2;³žžjó‹s‹!åEEû‚üÕÓÁÇ3©jQHwô<ýÓE8?Ý)œrŸ5 Æ¢ß.¾-,‚A'™J4h»4K¶ü[éZ‹G“b¢ ¦Þ1÷¶Íƒ 2£œ)2lF)é.9$®“™d½"DöËø(#´!é•Ïù¨d¾£W‰“ùÆ»ïðñ¬úæ}ãöý¨Æ8âÍ5ÖѶ¹Ÿ¿Ïx “iŒS“Ró°Žœo|gâÎ:PO¢XÞ€*qˆ¼"%ß\‹V'nú¼{íåŒË‚—ßÿl6[›9Å‹ƒÕÑu§ÒfL̓UquFIµy »*¼D°kW£Ï©Ô]yëÅ6+VnæÔwÕÔG3¬4ô£(°÷16Ô)¨±ñØRcʆ6¯û^¦ÉZ_ #6ŒiàmmnL¾ò)º×ÕIizR2Nrо)‰É(Ǩ Ʊu¢líç\T@BDH ef´rºÌMÏÛ$×Êź= LÙ§èë‚J®UAcÀ²SñáîpÝZtéX)`×(˜â}#öwUBÄÖ½ÆIg¢®|´Mêû¼Ž*‰ýÝØ;k»¨9bFùD^ ¾üùhÏñÁCaú_?ǣߙ٠¯V”Ùü6.Vcù%ü,xüxÜy¶Õéªõ÷ðÏÍÓ[±¿«ÿý€f úÆ9”c³¸ò…Vû@l[ ﺠæ;°£‘¦À,ÌivtÑN«R$®›|„QY•üßïî®`FN¥`†Çøþ¼£/n«ÒL§½¨}h§ŠÜ$9ÅàDóJ®Ó¾>¿–¶Ÿký7Íñ!³�‘N/W _×Ôf ©ý)/Ñ3«mGôFú¦õ)Ž©¯r9Zî4ú&åmYÅÖ2s}aƒ^\8Fäâý†7�Ji~v-™Ÿy±ÄË/¾€ä ù© ”¢§ßÌy$npƒËO#’#m²=Cë/£en†ÇKÿKÓä1]˜¨éeãߺ5 Ýü­]¢{}@·³j1€Ò\#µæ weDUK¼3ÉN¥>Õ¥³ ŒreÛûÁé¡Ó6‹‘æó}³0Æ”“Ÿ~kÿËËX¿Ú·=Ø“& ñ¹-dÅ{fè]·4I°{ ]ønw²b®v"ñˆ_:šË¸Ëßw¾½ŠN×w>^Íž7ÅX¼ÿô|ô9³¹ pãySŠxˆe¬™×O;V¾m÷žˆt¼µÖ1õ¬¦·5ÅÊ©í¡ÄzÅ�f‘ÿZ$Ïu´êYõ±o@RçÞ;=’oJ§m†E+¡ L$IÆ I[Ké+W™vºFnùõ{£$ŒKLù Ã}]"p”Ñ@'ÃÂ#V™-ûUÜã³t1¨Ó1EnfØŒDjúº”&ɨsŠ&#•*tǨҊÛrÔýÀBÑÉ×ô„J3SØDêd½Š!÷Ù«ZÖÛs†®p(?müN<›¦ÄÔ»c’‰AêÍk•Up§âVõA'?ù8ºÄ暯Ç~¦ybÊ'š[4nÍÆ[°Ð|È¡wó?Ä`ÿëïÌÚT戩QPG¥’¡‘ëÆ¡Ë¢Ð°mZ<G™é“B*©%鯨¾N¥fPl“Ž50죜ùÆáf|~ÑEŠÝËOë+J),­‘µ;!`޼T3ÒvÉ43­(¨ÈˆS±x\“‘öÛm8}´YfÚ{dùLh©#ÀJ/7Ž6?ÛöΜžùrÅâ8²Xîbó¥eiNÝÑK¡2æÔ¹Ü?ÁÉO%œÊ'¾ðô»èäáÂ(Lýº6=å¢êrLÍæÎÚpŽ àÔ‚øö8 Ëžù›øí";§èÊO#TýSôp©P•KSÛ™ŠšdçÞf–â–§" õ‘õl18Ù¦^®‹EvÔòämúRúy}ŠŒz!eFš/RËÅ„a@§Û¦”$á(2åI2¶©ÄJJ31Éšz±ÊhåÞuF Ò±·Žsô4è;ÿN[É7c•ÔèafR§‡ï‚Û¡+bû%ÒíkKÅš9ÃWŒfzÜ ÖÐ&[¦tÔWã`%X¹>wnÓYíˆÝ}škÝÙw‡ëããà Ú˜ºÉJgÏÉÑc/¼ Ý[烉Í´{‚Ú§Ì¢µ±³ëMW—.®Hµ¬õü¬ªŸˆtl­øÌú6Th­0©3 ‰Êu‰7€wæ×r‘2Ÿ PÚVN'êÞדjøN•8€^ˆ•uб˜^Ÿ"7µÔb‹Isƒ4ifŠ,¶h<ô)3º ]l4­ß:U *…]†¦À20Å»ÏüÑÇÑÌ©»šÙÖPÖ÷ç¶ØQé€"Ô¥0Å>ràGª=GRE;j˜ifµ ãzãÑuY9 èB*qý³ l¼ü"¸LxÙÎoW¢cº¯˜Ý�ñYˆñ.’û¦3GtÍ;A<ÿ¡yŒÙÛ¯Üs¾ø½úÌübÆ* á£ÀâªÞ¶¶}Ô§¦×ØQ�·´|ÛH߯Hú(ÌF£¨îCéHû ¡ \qáâ£NȤSC‚Æi٘ɷº;U¯¼þ‡èÉKÖ%F¡)Àòèi×Ê\­é@'[&E+wbÀc—ú°E*Lÿä(gI×3°Á2˜qÌyí™c»Ž%'³ *_Gê.''ž>Á¯Î¹ïvâ¹Hêº [’ؘâõ]ÿÕ%{lÞ@Pÿùvß^‹;e?YÚ‚nǸ?g•agv#Î-Ó¼JyÑJÚÙ‹ì¬çí¹Ÿ4m<õ‰lñøÕG‹øÇö^§æ>½ h¦Ë4É)+à…bO˜ØÑÃmz;”cl»K•®uÎ(°¥¦1j¬CxpôŠé" Ñêh ÁÀ8G"¹/´CF˜ãª7¶%ZfÜÛ1÷·i .5·H/ù|}wï–WßÅb\Õï[VõÆM¸dÖ^n^r/¿çÑ;öÎKž®Ò4QýÈGwlï‘.’Ï¢Á¨çT±NDìc冚7rÕ7s‚™ÝEÏU=ƒ}K¨69¨±cmÕ_Y¿«6éªÁCxË:“z†è^Ÿ¢„ ò»½~=Ìñw•}+i’> tk䉤t¦õ*_DéIS@º¦Ë‡Æ¢Uˆ  ©ðàˆ°½L˜ p¹N¨ÈâlNš™2W6‹[УÕJb½^“­9¼ ë44ÅX)i…#X× †Ž®™{ßQŒõÆÝU€]µéÅz¤öëDª_ ÆcJåß‹ÝsNôƒ¾Ùø”ÎC}õ}VþʼˆžÖÝ¿V“8Ë»Wâo0ÔSñÚœ««æ‘§ûsfÿ+®ÔBìJ¿EcÆhÆ‹¨Ë6%m(u ª›þoñ_z®.@ `J4ÞØ>ÑŽfÛô È5™IsJt²|Ê tÑ_ð(€’¡CÌ8P¿ >¼cšTœ]¸Ïºëûb`R§y£‚³8¦ —ä¡EvñÂì’ÒÔ°d®·¼ê´ +¥? Žúî¿þS¼ã�^÷Ìç NÎ9‡ÿˆjÿ4ðŸo÷­XÏyÝg‘…Š7|ŽÇj¶üT™-.ìòSó§Ó@“³s̰òè=¸óB±e-ĉÿÇ©Jsìü¾dﵸšGÆ‚ E›ÿ¾s4{æK£´Ê ˜d  4Û¹)Û|Äm”„\û£_Q¹J€}ØÖ`&º»xŸ TÊScz´$-ôõh›$Cä<Èè½!3Úaèõ½Uïh:&znŠïøü®™²•þo6ã¥ý Ç¯0vGÿ„»Ò<ye¹aƒï7¾¹¤:‡Ú¿ô‘£~Ýï5èôÞÛ(ïÚÈ!›ÝdEcǪo\ìg¶¹%¢+ºžå$™N»vÄÇjìa™üÊúÝ´³$ÆÉ´&óx“nëêÖê`Ÿt /|1Ðõºf«¬²Žá§º¤ Y•}x?*#îÆikŒã´rI$*4b›´1³f#ûP9äÊí�Ü—ñ¨¤æ좷•‘d:kúU* ’"§pÛZat´[Io]u H`jFÏ£¡G…ÆIìCùîÌFc]ˆ!Zí×"ÔÅšõÛÖ¢œ°÷ž;Ý|€IKÜ*“»æEP=;ܸvèýµÉSéâµëö›«•°l~£×+<««|3§{KM¾áÞ€5Gï«-×ð`»m’lav­2 ¡{ûÞ¾hþ“ïø@‰ *ƒÈnëtšÓó¦Î!GI"4R'ÇÉh­ùM[€Ç´ëŸ¶¯“€¹G¿Ïþ?ª±Œ^ÙΜЭTôõÉmµàNîµcMçr¢ðÑ@¿èè‹ü(”¶½ÿ‘bµ86¤'¿~-Ñ–æ'­ñ^Ôéçe¬çÀ¢òÇ‚S©ç/Î o–±žÃŠŸ¼<qéO7´GÛ'“9»ÖÀk?Ð2;•¥—žñbâPpHÇÒòZzn å¯<ñÏD´ù©¿Ñðø%²¥Ã-¾òry¬iyŽ4¯’ö[—¤²/LêuÖ‹æH‹ð$I®§¸'uB• *EÕú~KˆÖÙpX—¹N3Ô�‹î¡ëOL*'›(ƒ~l!B—y»§•s¿Ý� *œQŠÖQ˜`ÂÇx“®R¯Fi·šÎTݺI¤~0àÉwLñ¨½o·@}s¨ÕÈßÚéÿaì—ø¾ÅÕ÷¦‘“òëå”~)ýý°î†„XÖ<y@m”è"F Lùtßà(¤Ò°_’qq¤FO°¸ r9­ÄîÂÕ93© ÙŽ•3é>Öaó8 uobD."šíW¤í§€; 3©72s_j;Ö~`†žÈWŸèžÃú8¤YlÇëÜ듆 »q/„lAr–Δ¹)=x¼ðÈ’¤™N1Vêbßôœa_Ó±{ДªÖ½¾N< J­»G2ÂU)£žD„ÚF}¢F¥Þø0îzø_©uýP‚È^ÓÓ¦SVÿ’›¢Ó<nì×_Ìì¦ý.æÓ.7uÐTnŒx¨W¿‹í6Åõ)CÓ³™kº`¡”ÈÜlx IÓa6†‡1NGXµÍVŠRm@‚Ói¦ ©mŸŽâˆ%Ƈê˜x±æ” «àiÖ%v"µ3\šú—Øã^;uçç3}rПtu ïÕôˆÝMOj‰^>Z=szÅÌ€N—¢Ó‹ „Ÿ•¿ù^*'­É’I–3ò×1†×Ìgp§â'ÈË…í§ü5ÿ4µ!{ãûËOIÄŽ.‚ûÃä¢_L–>…¤í…OžJ¿n» nz‰Ò)ó³4”:ÁÒ#uÁѵ¥Þ±ƒ“gê-Ë3ÒÜ,4Ú­×NÑּ̔G¾ÿm$l›Òsdà¡O’[í#•=ºâ§ËÅ¥OA;ŒÇÛÜ9V2‚^Â(„þÂMÖ¶`”4éŽîIlÆPêúSSæ¨>½›-º§b€È¸2CìØÔií6ʺyhX3›‚±ÉV9½‹ÙÖCHSì“:¦žž³£(ŽÞÚþNعô£úžÓu¦Xí8}Ÿº›Ä‚ÏFc>¢ ì5›[nânV±£†�-ƒ  b]—‰L{ÔÒŒš ‡ ÿ+uïóbIvf ž.UDz¦I‘ʹ)½²yoZ5¸C‘±(Š®.  ± x‹I0°E/|Õp±»˜¿À¸0Û¦÷òmÍ,.äÆÀ)pHÈATw•˜‘("z wJÞ£5ž)®MVºd’gDj4‹{Íìš={?<"2•‹$qþž=ûñý8ç|çC%wõ{z†EAhK ÊàX—aÖ‰Až¿Žú˜/ Ž ’8$pë²bÀ‘‚Np©DÀ,á °�îƒì»çœù™^pÖd „+@^ÖpƤÂÌdA d ‚à6 Ò7à·åê6åkÌgÀº>Ež&·îèWX1§Q%hΈ]q·t¸Âýß”OpÞ\‹Ó¤<þÕ¾ø“Ï›ÓçÄ~¸¼ýܽÖ<{ç9~Èþ:ùæ“Ô´ø…X]—_ü¬¬(¿‹ò' *ÌoæäÎ <ñ‚®cœ&` û7âÇhÞ—Eš�`hj‘\g¨Tšå|چ؋5xØGÔ�¦l=+CpÏ ­2àøÏW)f�ÈùIÕÚc­äÙûA] j¹:÷ ݰ‚jçŸ[¥S·9x4¢£ÄÞåÓ [}czÕËcž�*¢£7þÙÄûC3ÑÍÒN̬ͷÅt-&²ŽÞ;yVìŒÏÅ—šÔÓpŰç2ö|ìz„ ’y#‹Ê)!×™ƒ¨*‰Òp¦û¬Ì ‡×ó¸W ä[ì«Ã°·'ÂŽYäÂ'†pñÚê@¥3NÙ dQöœ¶4Ý.r¡ 'A¾U·µkGÁÛŽX×ÄgÀ<'ÒÀüÌ›øB„ZTkèÜÐ"/åµ@LùU$ä׎"Ǩ@5М‰ªÆêjŽuzšañd-d#®ÈÎpŒÀ" 8¨š‰¦n@áu�� �IDATO©ùo›yÃ×ïe�’’_�IÉ×sœàòL<±.ÌßÅ_aå~¼ �õž|.Öà§oŸ^•—5ð�ŽaqEÃ#viAòZh�ÌÙúÜ­ês»&½öØ…ÐK¸XAhã,K­*1PêzŽe9oÊùSgv}…ÕÚ-ÖsÇœ8K›‹#\² dâÕM’1QÕ€Ùõcw%2…ª&Ô¸x.ôP_€œtQÊ\d(™¯½ÜE�"+ QÍb WÀ)€7"[§8£¬à  j Ù{•"<xvtZ8GCXŠ[†‡Œs†g7Ž_=Îj™»~ö¤q+p$oÍ“ï$÷¾àëÿëÏëúmà»6_ðúø@Â}‚”5îYÏrà «õcnÄ\áÂg¨ÎOéåeëãçkánÒÄ`n°*ˆƒ2Ъs`ÅP)¯²º]p’€‚+|ÕÒÖãy ¼µ9ˆ@ \‰‹šŽd¾FÕr¿¾Ü GØèÙŽ†(Z) À¼ |ºw@¢ˆŽiê~pUG;ÔO(5*Ÿ~–­4ŠK¤‡Õg¶ï6”º I†9pËîõ6æÎÖaÓ»Q¦ƒÿ})\ôÞC£ 춬0&´}û’:K“<LKé"jÛû-6&_6WëI5ÂåÃ5‘“V˜«Ps^¬`„«KÀÉ‚kÏ‹"ÜdÞ쓃bã «È1qšãH/oy{™¥°gÈ,pd!h®|Ä ÔÞk–l!œ"YÛ¯Ló5k¿òº´H=aY°r s`QC§*c`@“³‚gäŒà@–ÖBÏÀÏÈ-o€IS®XʳÒ-uz:C}D,Áåsާ)ð÷œÕ8^¹pˆä-žì´Êß[TÀUr¾X¯08£Ê�9V†?LÒëI].X n¸ì}` Ý�¹~aZåxhùõ•sLðüËÕìŒÿ•IuNÜôz,º±‡ Ý4bUƒŸ”î*å9Ãy탬¡—¹ÓÈÄX�ÚœK<FÝZö²Ne'xRºu ”œ¥I<à<;]Õ¢¹™øAƒ:GcË$K=b\'î¸<2>Çq£ždà7së3$†åimÀáÛóÛY=¨ù·O\þÖï’|m…{§ÇŸ^¾þþÛOÓë ôŸ� ]Ã1p&’áJÜ€p"š+:fâ‡(užò%²5ªY¹jRäÁň3Êjè–=îÇújOä�á É\ŒêtÎÀjÔ혛F¼‹t»Ž%ˆ UƇÓ!66ûÛ?Òd™)!S!Pß+Ä6+ÓijwÃímÁ²»ÃÃãg¼’z°žZÝÁúâð#ùЏh½»Éˆ²b6yÄë …V;?.§xÑQƒ"‡oÛ%æ©hÔµ¨ÁL,^v‹aoh–·&ä¾kV¢·†‡«BpY4™A–CŽ3¤­Nº;I…¬½üÖ�€+„Ì©ööÂkrí:}FÎ�W>6‰L‘Tb&yà»Q¤™pÁe¬L€¹ MÆêL8À¤gÈ€gµ@F\ ¸YðtªPÊÀåx”#SWpK!sd€ndCn)æÈå”5´:†¼"(ð·<)oPòmñè§üá[ŒŸ”üÝËŽ÷ 8;¢Õµ¨þòÔ¢n–„5Ù«³•ª³R›ù"+Îð¤)h1ƒßua›Ô=0 p nJmÀg5V98ð$K ‚Z¹5ÿ‰r¥TÂ1Hp(pEö ò x¬j’€«Ÿ‘SÇIÂ0Ϲ.€<­ (¬€ ˜çCI«lÔ„ZpPÖ¸yÓ"Mr¬Šé’é%Pc5ûÐ1`]cÂmÊLy €9ÎP‰‡W§óe²RO� H놻å|‘¸ÚÀ—µ¨ÿåqsÅoŽÝ7À›_áŸ_Ãñ7ø¿MðÎ7Oßø#wý1ðcм?€¦)/Ö"+0gâ{WX�Ï®ft±¨™¸É¡‘b‰ä ÍJœ¥kòÍ1XPˆr@æ$Avy^Í`ë¸ßn«„SµÐ* ?}-\£žSaÌm!ý´A[õËn©Ž 4@æ·ôÔC´¤ Ê3¡ dý3mˆÚ‰G¥ºn¥®rj«Üˆ3}^Qq£—{nD¹l[ÜS[DPcþ™0$Ÿš ‡m‹](ÐÄa¨¡öropþ²ù9ÿÐ@¬vnR-è¿Éž3"ÂÞPÕ‚?S§INnånM–“z“J€6Oðö'óQ“F!ø…«r”Pä €4ÜýF &½ ónþÚW]iÐzªdyG À.ê�¼òv<B瘺@T~s–Grk€ ä8…@A•IW kÀ™à 9à”8mR J Ì!’Næ  �V,Õ¨áj² d  �?ŒßK ›Cçà šk¿RBà:ã8I“ŸÁÞw 8~Fzæ°zÏ]Á=-ë§ÉüVœÞç5æ�­ê÷\îÜ�dŒ°DcR°ÎÙýt>K‘p»v�YÐ ]�§×ÂÁIˆìŒ|SèTXå]­c3w <­XÉs®oŸ�ä�¹òDXjîÖb®Ÿ=^ÔX)p®°ð½&p ,–e£ð0/å’*?.×@2! r@ÅxcËG˲±%ð׸Xr�8PÏk’G”�sjþü/¹®‘ÔHêó'Å{‹£Çó BBžb½²kqœƒ×˜×@M3æ¼ë_àÍï€áñÿöÖ¿zóõ£ïÜüúáìmàA &0+Ùû˜±4™Q¥æ ÊOÞ…­Q3<k ØÙ+\¼K�°Ä5 Lžô^‡ `¸�t!ÜÙjÕP†v[µ!Ì øÿz³<î±xF `¨ÛgaaJ¡™]ѹ‰ž4öÀi,!9‹ÊÊ¢w͋ˆÈÔ®(´IO¶Ú±1ñ°éù&vЦaœH“ª§~8>žb+•}@> É*ö›8H5^~Ù¹AïŠÝÑÙêOOylÄ÷8ÁF^Tó!×/Ýñ1BuXg»ù¹Ø‡Ù™p?em•´~÷ sìJï!ŒÇ)f§aÈÐ #c‚Ÿ•(J©` Ò(>ò.Ã5«Z‚Z¢”�/€ZHÓe…àðSW´PJ4V P”åç>©¸Òà‘”Xå8õ§"AR“Sh�xTþÊ`¥hq„Ëšº]kÙõõ!]y• e¾=* sÊ ¤Yx±@ ÉušÔ´ªEöî:Y1>o€øÁ_¦˜Á±Õâ ÷Ÿ%¸ZÉc~zu.!pÅõ±Ð5pVjOÈgaý*ž¯ qY!Pó,Òoð(—u‰c¡kª–BU-$ÃG3Ì!V3ºÌÖ¸-ˆ<8IaÒÓÚ­ ´ß3SÔT1TW”Ïg Ÿ£�²LHÀe Z o}i`×.cå¤ho 8¯,Xâ촹ώ÷ÑÛHn4¥½Â£µã *@6nÅP]ñ°X\~ñ_¤8jæ {| ª®Ð,qÉJŽùÊÐ`(Ÿ8N¯g?æ·Üo |J¿ÿ£ËÿzóÉ7~ýOï¼qóÖÏè膮×X4®^¢=À›w'·ió”£ã· .•)‘œÑ|‰ùŒX }°jâÀÜCÏÕ„š.•.9×ðw@.ª5Y�ë¶?V”™‚LÄ£‚n“ ³°*h1ü]nÁõjÆ%�‘õ…Z+3)‚¯Œ6Ð(}Ôb5)wèi\L(e1¡†o×3ˆ)]þ.¦Woi øàMZñíš>W™a3±!lÕ©Kn§c§à±™xõ¹Aª}Òàá&ŠÁøxü£½:›¶‚&(|€B…bPY„ÍàgøÑùèÔè!1>%H ` ”b tV‘`.nB[¼H8»Ô�Ï=H%Z‚$•ËÔá³Jd œùf‹"(Ç­I/2%æU9²²¸P†4ÞF¿ŸœPeA`à^qغÆ^°KJ@ &�á ¿S™UíwÑ�k¸8#^øÌ,ý>w¸‚²šd.ªȃ®Wû]~9e~ÿ‰­…ѪrFêÕÃûX77®QʵãŒWKº¹Z¹àýô+ ð"•OƒŽKΜÇèô ÂÞ>ž×µ€‡p¹€…­‘ÕB7�Rù(øb]Z…ÅŒlŽ›3¬âk%ç —àÉf Ë™˜3œ&àŒ¬! ¬r¬ è"źÉÖ“¤dý޲ ^_2“Bç©TÀK3Dù‘!þÎ_ƒ½Éðæõsþägéê ‰Ë¯˜p@s… ^cõnúÐoƒ3qúH\®‘åâQ¾Â-.š$Í©Dêòj,€GÌÍA¼@s… –2àòÝÏî¹æ)V¿>Åç«Ï^ý?nîýéœñãüø¨LqóÇ7`@v".ž€VgÄYÀåkÑ4Xœ‰GJ\Ÿá‡€+à ,j�¤×Ð…ÈüŒN]Ê",¸Õ çuJ…È–¤û*^Tþ±Z“š3rp…ðv§@v2=kó³h»{»^†!ƒ2¸ ©Ô3áÜP¼LÇ|lzQŒ¢B60@4ròïÅQÅ6­èŠôÉ?ÆlÔˆd^ÜhhôUœñ0„ u©mUÿ>2£Ø“wŒX ˜R±Ï*DL5Ë- -½•Œ-l¤ë8š&¯ýÁf{ȇ):‹[¿b#¥uYmØ?ʶQh’p€¾ÌøYJŠÒ³£YAº·ñù™‰: òQ,†°ÀBÁúI¡¿Ú"Tm™ü”‚BÉ1±�lNó‚ (+ ,°(,«„S~Gw‰38O™pWЏºû¹` -¼7§,àj¸3ÈÒkуŸˆ›o¥?8æÍÛµ;‚eóc¸ãÍ ¸Eõ䉀Ef rÆœn¸Îa¹&°2kÐäVêŒA.I^!×A&ï¼Ô"Í�4"S¼Q„5ÀÏÒ¤†õ£$ ?®á“Ö—^T. -NP¡Ìò°ÚÍÄÜ k˜0#“IPÀB‚´™ãÝôÙÉŽ_kÖ·¯}çÞ“k‡N­¨Ï`“´IˆçÈÀ/s86Ÿ¿~&XF÷mÉg°KúH ÷ œ~|  ¶ Ó¥@Á/fB3 «¸ce}…[†ù5±7ÏqËÄ5Þ;ºÅgŸãÙýäÞ[G¿b¸wDqß½~?ź<*Üà'k²Wµàm»¬¸‚ep9¬BUxÚ–¤Ò÷µ²�ï%Ú©ú‘€4B*d »Þ^Û?b‹"9%ÓOªjEVE²Žü,"] ªî®®½ëŒ€W)@¾(ñ–åbË(øx³>êþ ÷eï¨ß=уyºn1M„5ömC41úçlh/NbP:ŸÀ*ô¨PžW¤x‹ÝÅúôk¾,¾aàµØ’ÁÔ6*s«|«b5æ—FS²0É™£Oq{ØE½6i´)¨è7Ê‘Z®“Ã<Rü`„èš¡¬èÖþ¥¶€\‹�F™ñɌډMï dÜl!jB•׊d>HIWª\”©¶û®!kòš ©Ä kèF8`¥„dB:G†¶EhÏOR@2h ËÓ>³ÖÂ÷øÒ{o²5ä•°ŽA€+a3qÊ€§H2j®ÊŸ I>N'«ë[.šf —X<-íí92èZh@7NµÃ²ÌjèÈ<È)ŽÜÉ‚nY©¡!O¥Üа:C€È4iðL¡™ÁF ?†Ð(çKÂŒgW€‚^Šy {F<¶f«"µKèóDü�„š8H¿ —Su&ä²kí?t·B'sÉPÝàÍúù½{?9þ׿ü§ jº¬48nü)u0åiþVÀi| žÜOf pïÝòá[郣æÞÑ9"Á›�_âv ÔhÖâQ yŒãï£ÉÐäâyï^ã¨ÆñǸ…xãuö¯¾XýþÓ÷^¿ÅóŸÝà“gçë$½\B6˜ÏDïå%8ÙI(S\Kü®àmõ:<'øe^6Ê„T­ï£Î)³ð3äЊæíئ¯å¹¦{ˆÄPqÔŠP¼¨)Ç¢Εº€f”¡”  œ9ô”+œl­Ìd>^o`#‚³Ë@~9X†=^¤º‹ã#X»èQ,»|ôpù¨Ü6‚°¸Ö8@Ž¿}9¼“ è€|Y~JûôRO¡mŽ&•C´ÛõjªÙ‰% #N™­=ÙI+!‹-ªÜVA;*¸!WŠ"<0`àêÖä‹r1_bµ`e,nün8xK>ÍÀk$ÿ¹'H®pz¿HÀo+2=×ÝšÛ´Y«(c"lUÌû­[>'IßýdUØ|&d Ì Vy)•߯ x\~ð#Ü\ 4ÃëôzF8BvÕ:‹œ”È`—©Ã¹ÄÊžy¸™¤U].àZ“’s¨ÇðÆý5æò)€6BÖ%Þuö}á–à w&¤f¨€Õó+™–Bü¨D4p·©lJ§ÕûçG¦A‚Ë5€c‰kÍRÔ%g ¸Ìj®áø÷êo§³Ï›+<åõ‰›Ýçë·’Ù½UóÏâû°ºwùà7âÙõùe½z8ãO€y“6Œ²+^ÍÒE $ G Ë[<<š?û“Çþáºüm‚ëw\ò Þ4©KJ¾v`ÂÕ$OæÕ«'5ókµr35ñwÅñûxÝ–ÿsô;þùÇîŸßÁwáÇK!½dN€èÄâ:L®µÚñhS/ü¥äJ h_`¼%*‚�Zû=çá6VÑv³¾Wh7}zŸ% <›¡é4Ââ,§€ɳà!–ye0+åUÚ ÛoQŒÅëóÀüQ[3M‰ÎGtfñÑfëo£µÁÛv½l¥ƒ¶×¼XȽ‹Úõ«óSÚ§)ÚDÄ‚-»Þ–ÓŠý¹nòÉ‘MS‹*ÊÅ?M4£1±ãD˸6ñ>þÑ;kÛݾùmǤK �¥\"Ë!g\Ï„V¥?�Ê’¬ ¥RQH ¬í¦•×JõýuVÃ2È®ÀÂsƒ@–aQà²ð’Y¸ÂOí"ó[ÝgÁ„RÃÇ‘ $É<$• ä­ ÔPÀ ²Ù¬D!d˜û#¬R¥cbž#1¸4ÀÓ¿ÆÚÉ:Içp?,­…»ÀyAš‘­UÈ€Óæ1ÖÜ©’ÛsèœVHõ ¼F«•·Y•‰ð Fp(QK!½íp€<£ ‚›Rƒ°¦Õ§¬\(’ •~†ÎݦÒ„¥x»Ô³D¿A쪮]}äŽÏžUïìÃÓ“ì’Ã"å3$?-Ý;îø7&ÿÓÑwnÄ}¤ø.ž˱/šúS\> ‹{ï=�Õ1ÿ!ž1†·ÑüÙ’ûßwGŒìŒ\‚#಼÷îƒ}DÝ+›¸o1|ïJ4p®Æiã0ãI0¡¯V7§L\›c|¾f‚]ãåoïã—Wø¯?sÿ¸ÆÑÁ'Xš‡à.<KÜJõ¦ïž»y1¿}½ã`3©‚1L`ò2‡é¥äàŠ¼õÞÜãT9d°ÜCCÞ|0/5мtUnx2Y@6ÐFÀ óäv d©ž^›m®ˆü¢£y{\ˆ6…¾î.öUÓÅ’Š>Ôª~uñfdÓØÔÈnçe‹áª±6MØó«i—§bË0Ú£_QßpxvzŽå'Öpïö,ÜÝlû¡ê<¶Ä!žˆÓŸµÑY [g‘wcWw›vˆd!ƒ s’Kn ½ÆÃ—í ök°ÐÓà-ðEíVÛgxgª¬Ó´©VSÛyäž²¾cZ É8Ð:Ø5T…óú†x. à H¿e%]«¤YÒv÷_ðÝ,%R0B-*`ň×"+J‡znY“!Õ y‚¸n\ 0ðh%kÒà(R XœgxlÌ…/±h<Zí€ €t=—ìqU»r­ˆCdŒt-$J°T3Ⱥ´]òG`ŸÎÿ¸Æß;zþ®gµ[§œ•IîV§5Àx’¸õzž°ÕwqúÛã÷ðÆù³×ŽðëÛú^sü¾õkÔ÷Ø›¿¹ýí³÷ñìÞœãçŽ%o¿÷ÝßÒ'ŸÍøƒ[w}„ãº~âÌÞ¹Ù}$Ï~~ÿ¯?»)ÁR†ÿã‹æÏ?¹¥gâfyþ injö€½÷$!ž4éà:!¬…qæ'ðÃüe„\´³f¢Û~o › ÌA+©pÜXĦaI%�ò¢çJaåM\ò~äÍp~ŠÓË´ïìßHú0íó eàPNƒóÂež~¨‰H¢ !]_;Œ�=Ø0èö.M‹þÄ¿ó ’D€þîÅm“V¯w ›–Ìý ºwÑûpûƒ<\·üpÔ7ü<ºÕž¼-ÁýÿL­ÿ¼kºšƒþĶQOQB¹y¿2è|jˆqp—|ø;~,@âxä]`Õ僰‘�¡=$¢Ä ÌJ¿œÝ?u}É#ûõm«z_©¬h7�ÏJ·vB3ð¼":»c?{ì»›ˆj:B'¸`py;  Ñô ü ™i×Z-¡þ~~õ“æîJÌg竳O°„[{óÏÁ›–@#’ššBdKh�GÀÕ9ØJÖ¢*ÎWËÕi#y°¢&Ÿ çàÍIš]´®ˆ3¸Ç=7ƒ7q¿ý-¿~ž±º÷ þ8¬ÅPþdæ�Ì1çhõ+œ¾~ÿò ˆë›“÷Ÿ¿sóÏñ¿;š}~Ù€ß~#9ªQß6 KVhþpüÊ=~ýÍò³ÏÒûÏôÃgOì¿Æñ§¸^ àÜÕå÷Ë¿{‹±_ã§ÏÁž×x–ÔõcÇèá-ž¬g` XSÞ‡ûðO5Ž!n Dƒ2S©·bä9\…%Wîü‡Hu’µhÛ‚6”w« ®„+pªðh4ã­“YLJZ?ÈâmϽNÁ§ ™õkÕ竬½¯ PƒÏȉþº½,Pƒ8x†´n±ÁA{'«¡r¤ IÛ�÷¨¯ƤåÁTÄÐÛq!="D;›çbo¸óÀuîrK(Û_@OƒQû,$¶„Ùÿrà d¼m̶,hJ¤¼%µŽ â‡#ø|È»[#qhzCÿ`À@Ö¡<Ç tÝ–9ª”…€¥À:Ü.À%È£ùAdR1‰Ɇ!ÔB3BíyÒ2ƒôÉÚúnúYÐ ”-¡Ïâî!*” P—.+|?ÏÛ6Åø3@¨{M(Ø‚œš£xܶ)¥®S9Π-äi†y4X%À™Šô‰Wžÿ�Ù‚;•¤kmÎËŠR#•1àk óH+…E(²PVਮ€9МûÁGì ~{ãÞnoš¯—@ͨ^ã]àÙŸr¼†ú‹ä;¿ÃÑGëßÔøæìþ/ÜÜ«î=»ý Ž®ï'3<þìÙ½÷nþþ»WÍgÇ··XášÕîþŒß;rÉ-ÿ§†×õ3°û‰›Û÷¾{ïÿ‚ã1nK¹Nõ XgŒp…Ù»óçOÿð„ôøLd ô1øS¨‘„¥°kòãÖ¼&0¸Zød,“†˜+ZÌ„^ûëXêÂIËðÙÚ_td-^ßã6 žC ýå’tX%ÙÂÞª¤”yÚ]‘P"0�”åá> E Æ®:FZŠÊÃÇ*ZÏý¦¼mT4ëZôÄF6ŒžcÓ‹ÉíÐSaaÕ8 ´Ø.‚ÿàx:ï.®úàµÕ¾á�$kB ´½’[Hy½ƒmï§ZÄá2ª~4AEèÚ¯“ ±BFó j"ìê¡À »dÞrÎ!ƒÌ!I «Π‹àsyé÷ßöÞ2ÂßÐ~>®ö[‘…,üŽháÝ¢­ÚƒÄà”X—ä%aN œµe~+ií8ä@‘fLxê" TÁw6T‹24‚3À Ê”Åcé· @*  )5W¥fsYÏWgb.×-Çs}AgR PЊàÅ3  M* i%ú_%À2µª\´B7+Á°€àpºH ɰx®>;gŸ£þÅìèwøÕ-Ø›ÿøöýP£^s–ðg'§Ékp·¿ÃçããÏ/“×¾Ç>ýão£>úæ=ü&™ÝKÀnž¯¯oî%I]Õkü)’7]?\%®~w~³fkà—�Ëß{ý]wVã5ôÉÇ^¯pœ¥„˜!¹š»wQ_¯žÌJ{%8àÀÏ�ÈËÐF` Ç8râ5ƒ«¹œ¡ò+¡êàb½‚Ðg]õíÂ4 JYgáÎL¬ ‰!­­…TÄ â z ž—mÅ ¤VÐFð¢<­ƒ˜M2X?,  FV ëï6Ô’ª$íyÔE?i´¹ Y‚¬÷Õ(¼¥?õ¢óÔ‹¢ Õ†ki·ëwàë  []l±°ŽÆ äftš¢1ìÔlÁ¦_ƒŒ÷1•½MÒº#ÒîÊ"mã-¾‚¹hÚOò¨;&@µ3gl›þ(ú©Âîõvd—¸#µ„?c÷¿H$¼@ Ö‹½ä¤:MGwX_óöC|æ#)G«évExJÐÃ5àç¨à@Z‰…! Òð†¬Üzã ïnæc¢! щÓ=£ë-¦eA:8*‹°¢²è¡!‘CVu“[?‘§À PÌ;¿qj÷jÀ@+Ø#è\hoj²$[À)áø)9Ô)”ÀI*ë•Æc�©î,”½fíió„º}mB‚×Ðu° w…+<Ù�Ù�kd³Ô*ÒŠ¤ò,µ€= !? ÍjØgåüXÌ¿ùoðÙ³ŸÔoáxóGÏø ÝÓ+�� �IDATë÷ñ<¹™¿ËÜñ‘{½®ÿ¿#qû…ÀÇÀÛøö-ëÞgõ7?YìÓçÉM³~^'ßnnà^óüA‚[÷Éoׯúä@rݬX]‰Û3Ô?ÆoÎÒž¥+… X Y”áDׄµÐ5—‰›MͱN3 +®§À-àN¥‹¾Naà�ÔbŽg媀+…hË<­åÏ^‹2©Ôzk^Ïêguç ®{åA¿2¼K(Á…’\¡Ê! G¦ÒšAh$È�yÖ;9`ò4/‚+õ.a½j0y +ÜGAÐø”/Ú‡BÈVÀ¡T˺íº_·–A‰äT}¹Âz$jÚµ¨9¢¾£¬^,«ÆKuúˆ_ZpßÑEcóOĶý?“ó¯67ˆýÀ’ÛsŒÜnn%N0ÈûË¢EÐ^{ ÕØòjÄãæ4®wn\E4WLÏÆÛ PŒžO¶$"…)e¨¥·¸­$i¡�•ú¤"Õœû's™ W‹¹I3/Wã±7( oâk4»j?*$ m{ifЭp›Gw¤îœËÂþjd ¼@dŽ¢÷O^vèB6² ÒxâZèµÈ¡�ÎÈ?ð`$AÈÜœ)ÈÒ{Ó*ÒŠ ‚M4 èµÐ \ Îà HEžYù‰“2!ëç³à©þ²:ƒ;œÇAVŸeäLyñ¾�CÅÈݺ£o}¸ú”êÏ’£D°ÿ{~y”¼~ïò›¿¼^¿utÔ47@}Ëu‹_^ãÁ¯hv„7¿©ÿÛ/ñÏño¾õä‹7®ë·/®7?cÍ‘;Âí³›æòŒãÉÿU⹨4uŠ:Á ­à\N@ºP€*qƒóGPéÈ æ �=,\Õ<Œ¬Ô³²2˜×†4Ð,õ52¯ @–wz|jBM€LúKY{sVø<*0¾ÆËoTÙ.É!]Ð*7ŒVÈÞ÷ÃÂ"¬9YD<V–Cz“•¦ì1H”ФÂjØg †^÷¼óÐ=z :ºÛ.Úê‘ÿaÞ~D`j@¡Ýô¹d臮”“+—azÊp)ï$—1»³sèF‚s'Å$AÓê&µ§ÐÓH }©¹aëÇË]˜mÉ1›^Z½W×þÌ%9X�IN£J¿çÑ{šAß ‡Ãt;Œù¦‡kòáñ¡@06ôæ©TEúh ­ÎƒÉ¥ e¾4€AU< r±ªT9šº[zÕ7Ý\ ĸ€+ !\\ÞøØ}? ìOo’Œ-!Ušd¾É»§H@gaW(ù}FQ„:¾Í׬]ãUC¶­ëT|Þ�f~éSé]ÿ$€¢„>…RÈc#aŠ•ª³Ð’[ è"]Ìka!ì ô�è๫/ ¯pTÏùZÔ·ïÉgœ=_ýjM·÷›W?þÿoÒä“ÛË$mj<[»OÖîúš®oøïnWÿ—æõwž±gXÿKó›_¼ÁšŸñúÏÎ//]úgM 7ÿÀÝ®šYzÛÐQ-2Y4új.•�„»*+ÍRXû^«p“ ñD‰ÊÎo“”×À:mŽÑÈÖ y;–³V0mˆû"] >K¥TgàÞà‹ XHÀ²îþ/uw5AÈá‚BÁµÞò"hö 2&Âö›Â»SfBù¯=Œã»É5ø 6AeÁœé} äLô2 []¿†Lõ«ý´„ÿÄ<¸Y¸b솠Ûå(K‚Õx•‚ŽyGs³U%¿1»c³Ø¬'ôî£ÅÔz;7 7�¥£ž…0\íCì÷Täâ+È t8'Ñ_¡í­Àfë·+ªqª—QË"G9c#»ÈM½lõ•#¿FìÁ%uwƒö“Õ„Iƒø /"”ydÉSÊ h€b¥ Ž‚dÍ%J€tä´0ÞŸ¤ ’ÆÏ‘¶Ä²dÒp¾64a'ÉeûÅy·è´ Ieí6È Ê<޶ìÓj\ÌúBÆx[üV‹Õ>T$ Xßû«� Íkqx,޲îÝ %üâ<[ ÂY‰‚ Rä¥f° ©œ!cÐ(¡J]@/ Hu�бðžt5\LÑ©*õ +Vº3¸µÀû@‚G‰‚»‚}·Äì1 $küR¼1¿žáèž«Ao}úäÿýÏ´®WrM¨QC43áj~y–ÖÍüæ?ÿ]}uõ^s›þø–?ÿèò˜Áýh…§žI€k~ù@°5­2\ÎJ h8~ò~ëKWµ'´7aHç$U †pYQ¢NÇ‹†–ÊÙûÈ–Ð\Õ8CVûD.` káç $J¬C¡ E¨–@Mü– àjÌÃ3’rÓÊ—ÑoQÔFø*$ðRl|,°üÐBpoŸ잟=ƒk |·Fvv ÖPRÓ÷Nð¤€.\o'Ü©! ½}A‚lÑW©&`g-p ·™é>½)¾Ø,Úòí…¬=’<ü—u9`Ã"z„ š’íEý&H.GèîB|¯Oèa,ï—š¶û©HY±+ÇÈøúQ†ÏiL3ØÎ§¨KøjÜ*ê‘Â5‚w·„2¢µ ©›« ±A@ug ”iZÊÁ”–µ;x—* OœV)Œð¤kÎ ¼e·+g…+S<Û¹ $a¨ÑVÈ òœ¤D7Ëš¼ÞotQ”©v½;R;\µÀ,¢ÖcÞ¾[¬­„n—dé"�Ê ÃàJh©Èµ´¬Iƒœ"§¤(HÇkd P¤ýÞºeŠ"•*˜v„u4LØ’q̼s†xÄœ¬!¯Rx^Ä”ví/ç(qíj�ŠÐÖ¯f?EýSQCüÙñÏ Ž Íp žî ˜y’¦¹ŸºÃyÒÐ|'?¼u¼Œ\ýX‚¯êT>-åB*µCMsÀÕdAÙ xHTA ¡‹zîIädkÁ ç×ü¡«.x­@’ H€ŠH@ç„BBiHƒÊgßg°ЄkÝ´�zˆ×…Çî[€%ï XoèkðQAÀ܃÷�8À*êÕì §gŠBû¨ºÅ+ëD�â·ÁL^ØöŸû)O#)ÑyDÇÀxžKµæùÅÔæÖT¦O±°Õ µé1Zeºš, PjH‹·1]‰v‹îõdPVÙ¢ØÊýîŠ*fç îáàpÕÓŸ?Êþ×ÿíÿÿ±ú÷Åú›¿ù|%ÿôþŸÐf%¾€Úr¢ÍKÏDbS*²Æ~è“ ¼ÆÐ£Iõ„ygÝÚæ‰R/©ReeJÝç3Ò¦ÔÆ{¢•ñž“N˜¡csöðVÐ…`AÕèðTw�ƒh{—ColEƒ#Wƒ³ä¥Jv󼵯ïRµV4 þü‹Ãr¤ð½¬! Òþ —¤ ÂS‘^¶‡dÈ·5þ¬¡þ›*è%|˜Ó�K` ÒK‚!˜R+hm¨2¨–t¡èÂËœPbIV(½³´V¨�»,õßRÕ A‘¶!?ý«Uiý·0¨�­Î+kHÿž°(­ çÓvj1ÿ¥ü¯:—FüVuÆòþõåàü«ÖÏy ­ÈªTéYXœ&¼ÛàÒ¨$ÒÝ]ÁO•Ú�Š*SZ|ˆe01 Ÿn ª5¨ þ°†ìP¸…ÁG/œFÐ&fÒw-jú©<D¥£GµçÑÖÃêpï2N½y̯DÒ©¶~ÍÃÄ;tx4Ûý†¿ÿýïÿ}ñŸþìþçÿåoþüQö•æý2¯Tw<ãSe1±Úz‹#÷o|ÆÍ®cÓ[1ÊVÎÔ=«&hŠ�¿¨½ ¾¥î ѺŒ¨A‘b·|´Ž¿¦êýÈ,«Û[;þ‰ÛwbG^̹y4¹uØ·ÃÄ3ðð¯±Ðf ä0åqò_Öšöݬi Ÿ/ã d£ËªP)Ò†¬}¤€ Pd=¿ Ò •)aJmJ­ÿkH+Ò¦¼PmN. ¬:÷ïi=ßãÄPX ­JXÒ•iSš€ÚŒ¨ B’3°¦M¦Ëâ¥Ï@]Ìò?×´×®}½íγjßPžÿoºP°8¯ºUdmHÛ>cµÿÊþ¢˜cTÁÝR+ºP°¶*­‚U?p± Zg,TÉŸ ºP¸X¢R¸øÛöNè¯~—–Â…ÖQá¿õùRÃ;{¶Ów']¹­Oœž Ê›ç&ä0 ăÚ÷°¿D0$|Uÿ¾’Ü ^èW;"ïæßš¨öéc"郯͎¼ª·Ô zÔKb{š™ØjWö±rófg¦¸0'tõu'Éõe©M çeð¦khœÀ&Š)êR‘Œ‰rXûéVmgzÔ†€ÚÇMÕE·ø^§ðnôB‰Î^to‚®)¡è(…'Úàll£èÂ]Vå=ýYEþ”úd¬»X À‚V‘6ÐKÒê\ûèÙ]²%ù ]©óÑÕ ºYE>B•Uk[ ÀÂÿø¦•ÿ.%Ú‰d9̸*îùPqt¡È_ßödÒà΄Îv—Ô°¿´­¢² wÛ{Ò¿¦Z¶9Éà#ßÜ,Q•*íÒ'ß*Qt!ÚfhðdÑö¢px_™14j¶EØDyNw [ãE76m‹oz{=zHQ¯÷¾Õ–‚XïíW¢€ð‡ìv¥‡N'w˜Øv–G¬ÞÉò¿‚Gíy­ów­Hi»ýìz¾G¹'<–4€YÊØ‰þÚ„»<Î[v|OümÔñ´Ý ÅEŸõpŠ unˆ\jŒft¡J#J‡ ¤ !JÚØÊS¦Z‘5çÝ;XÐ8"²(=ÖÀš²ý,ß:´ R…Œ¨;UXÀmJkH/óoM©QB‘FÙ#Kar*Äåp±<ºÕ%]C°ËràxMµ—¸-±mÜÏ™²ûjíõ-ã @…þMÂ1t·J€ãT̲Òy׊,(ü·¿ëÚ Ø~)Ýv0•ï0>R>Ç61C¡Û3ÃgPMGÛéâÀðÒ¢Xz ÐÆ»Ñöøð²»ÞûÈ¿¦¿¡Uw|7õïvžY}XÄ×ûÒì'T«C¯‡~ÓªqMOÜ´½¥­gF ±~5î‘Ãn"rÂŒ—P’ãÊ"Ð&.o7ÔVq²QÑçNÖ;jãRúb¿Í6@FUýÐPh†bL@‘GÏÃc°lÿ¼jTµwí㲯÷C5Ý ª>;šPÈëeà$´AÕ†¿¸Ó¾X6-¸�Ùö³�Ò(G`HøCUúÀꛡÊFHü}eݽ¿ÖZà¥Ôþºþ/>ˆHЦ˯4(5Ôð&1Q׿‰ø ½_‹nûÝø z, Q¯¦+Ò ÕrP”X $E7‰šzT7¸F½ÉîNý$ž\Ó/‡iï¯Õ—ƒ©¯ú¿Ú¾a¿%ì—ƒ£©»Ü ãæ‹&áˉmg ïzœj+!¡GŽŠ‰âWiƒB¥†Ø»Uš:†¶*4ý&¢p 'Zþça#ļÅÍQ© J¿Ë*ä€>6™a—¨¨þ‹wGÒâéýWë˜ù:ƒÒ¶GWZÄ)|"U&`8Ú–ƒ·íz¬^ @P!Eµ_ÙãHžÕ@Ô4´_Át}Ù® õ„)Û¬@—S¤U E0°¸nÝ#H4„†h�q˜>ÓÛX_Ð]”AR);r÷úP+ôќ ÖFôHËvV°ÝETT ÑÛžóQÝ£7A½³ÜžæÔ� Ý]€Ú]`Ô¡ÔãîžÆb{u«¶cJ; 'õŠ£ÚZ:]¸h{Çs}`žüÉî+1M,«­…ÉîldG·µÚmª2&qU½É¨èÁn‹D­kq"2Ùª15gûC\Å–6y•Þà{¢'Ÿ6iÀ)J°m, ä4ˆ`.Ee¨»=Ų ÅuHHËR«óžuWÐæÜc; Pt S £,beÊ[JÙ”­ ªô<áÜv3Ãt]›Ò±¯¶‹ìËá’’%i5Û˜‡r…NѤ}ÑiÒ†ÑpÕ˜$³º¢Hà‡6.bÌPŸ¼;È®m\‚¤JE—W¾Å·hÄBÙð¹í]·ÉWmÁuõ!úáå¦Ú"Ôëžßª/[õ†"ÿe1¨ÎƘoÐ;1ú¼Š>ì2îxÖôÙKmÀ/8ìÈÕÈš¢D ßïÆÄzÈ‚Æ8•é˨ŽjŽk™j>ìB�»uTþ„(ÜUvv+h‡gcôæ:ÎL]9Ù%†VD:Uèž`XRµlÁ} #Ñ0+·äAá#ããT×3•1 åAž‹öËV¡9h[”X¶R±¥›µU=òCZÁ.Éì‹ì²ãÊŽºìSW$YŽBÿ‰> Ì·ÿ¾ÅÆbe=šÞR‘ÌaI}_ ,Û >ÜÉ·¦„*­¶j”vƒUÞHHÝRvf7B¿V[y}`A¹ƒq½žq@$UÛYÉ‘h嘉W‹2Ýåß×€‹~U„ŒÚ¾·ñ­Bˆ¥ÍTj7è´YÐ$o1…wÑHh©Q_äê¾`'öoK¶ðsÛiE0 ÙAÖ9ݲ $1ãHèh€Ú r ²Ë-}[¬}2í~ùþÓËq•Ð_hùmL}{-,uE÷pä‚›Ýq?¡í ;t²Æ÷!|Û¶µŠÉLkJmÚO1­:K¶e}Eç–bÌD·¯éš!k†—5&ù[Z¥˜¨¯RÀ•}ñ•Zn ²†º¡¯Öè©?`Q ¼H¼ç3™Ï K² ‹ZÕ–œ± 1¸Ô}‹s»Áyè˜vG­¦^.¤¨ƒ y½øQ€{£þ=ÍW3·6“b§¯kn˜¸T´µZ?€p€Û^ &ªx½O1uàûAJÜIÈhâsËQž²ÖD5Úœkã•”Ô)ôÖÜN«J#Ú!/ÃbËAíÖƒÑØÐžåí\F±¦íªvvAÇÖN+eµÒ>?-ÛÉÄhLW’ûù,ê²írH+\øº¾Œz,¨PjÔ•ðÛ2FäS XªîÛÅ”¾iIã¡§^ÒÓ]‘èÔ…fÂëG+Ußm¶ÐQmu<4¸RQƒ“}ÿOB úNêk…åHDDãyÐà …ÀG-º5©·j¨EÞxœõvb@oÔz@’ `IýUݾŠð…ÿüÅHw86õÊDP˜Ü°;¹íÿVÛã»>øÌê‰?¡ý_m=˜=­ö’`€¤jË3°¡Jê´ðÚü¨§aU4hÖ}œRK®"ˆg|t®Z@¹ÓJVQÎÖ**6{àeá2Š'´m$Ì-| iõSЇOÝuYúÃð±)”âÜ_ú‘®‹3D?Ç׆oÉsuß9 f¹;-¯@S9¼¾Ô[‡«Äa:BäÚ36èÄ ŸÒö’„¶nX""ö{ñkwüw¬"ùnÇ*-ÂèÚ{=êk•d½wwG•·¿­b¬‰*¼N½õé ½åö4¬¯^*(éAw�µ0™¢¦h½WÝ®&x¼*þyßN Þª?\ß ÷ÑAÓ±xšƒ"ì'±jO‡¥·Æ÷ÝtíÁšÔT)½í.ÙtÿP#ïF«&&<}L)a Šl?2V¶4évBG·Ã>iµ¥ôÒëjüŸô–­2‡âó¯#c\i¶ö -ﺌ$öÝp<«BBê�w»qt£�¶[Ì‚ë#º{Àëj–ƒ¹“xZ¾Í Ä®†tÔð��ª)MˆÐ§>Û-§¢ÆðƨbVFMßÞ£Awÿ½âzübƒ“蟵—=γ‰a^Dm™õ8¤Ÿ“÷ãèj¶ú‚�ä ç@ëFL:•ªGçFj"ŠÈ•ma^ â>Tžs¢hbNmÔæS%ì&U®Žé“ Ð+d)^ éùêrÃËè‹ÀèÀ¨=ø¡ÙÕ÷é—9° .nëa˜©ßŽt߃¹­8}[³‚TL.£Ñ5 *#ahˆù‘Z¯UoµŸO®ºÅXèÛ‚A U!æ¶Áô¼7#Sý\wôÄvO4âç톱1ßM·ÙV÷‰Hvµ5ªSú€åßçÂ5…3”0¸h_[õ·8LÔRØÞåd}T J$_ÖèTWC&s“‰µm¤Õ`HÞv´yWlª–Ûz.ù£º�]´ÒÞ±•Š€»þŠøq²Ÿ0Þ“]àÏj5rìÎÆ�žŠ®ªŒ†Âõe¡1£ÕF}6B¶c•×Öø¦¦u(c?±WJ)ë—ùCõË ¯`vA«éVã ly×Ñó}pÐ]5dzËÍ´ûëTcÚœâYè±üf²…øëd£ÿ“(R÷Hq?”Ô iZL£òr϶L¶m}az!ÓÀ¨Ëd±êQÔ¹]¡–?ïæ™£@E}ÕÜý£Œkh€U¸hCyG`hC•ê§%6eݶíâ95}\×4´_мB)šh'ÌudA)J{7Ã6Ê´æKm話)ÛQg52gô©½¬ ¯’ÂĨ<Æ#;e aì76‘XmpóXË·0‘¢w“[VÛŸS5‚°vvêS=Ç]‘w»ALößw9™0v¼3½H¢šz­^4¨Ì_.z—ƒÅKvj減Ÿ‰ÚOjMέ軞ŠqÐ Ri”/µšLlëЇˆSç¯Pú4 sYCPá‘óšî´ð@?™á304´ðe^(µ!˜²Å²IÇ¢—¡ýFl¬d#áì¸Ã‹e�vhô­;½ÐÈOº¯üYjMñFkÀ;üª;½vèUEÉ0l¡»‘´¥ÇúËn!’{õ|FìÝ´y+vÓàC¦=Ÿ†tUV{þ|x¡¨2mu?ºÍLGéS�FP˜ #lýØJoÒßÒe'ЊlTjlÔ¡ÕØ,o/GXJßÉ9M«8í©Õôç¤ÃÌSÕjn»312¨û•憵ù] x ýj¢0ѯ"Íè»Cg‡9´V[ÒÒ°Ý+Awµ1NÕjü[`ý¼ó~ðQ'VAØÁi#âÔcÊvhl©Íà‹ÌsÈk¥´"˜Ò{—z×kÛFd½9Ög�UêúÀТc0d·ŒžXoR¤»ÁGp¹õJ‡\µˆŠw׈‡~«(1´Ôˆ÷Îëí;6˶̊è)P5Fv¹þÌ´x‹é3M ã Dhf¨&Pî4'U†þÏÎÿÁ’ýÛv EMëNÖl1¤|z92˜‰~fÃ$¼ëöigÐ2T(`´(í.Ûd‹¼w²A;Š<{Ǻ{<f„á•=ÀðõpdþËãþp¹a;®r·l¿#Ϊ»´ ûö1ØÉÖUM•Û 0veøÍ¯0DäÇ®™ =ôVÛ ¸Å¨Q¥†7}Àš¨Ç]ÆÔN0´!Ût•2!f>CßPjóáH÷­UiÃû|œG.­ñ \k[dhà0húq m†—/²ý表ö<¥’5mµk�õaom*zŠCžE9@‡ éH\ƒZ¶ÃâÔÆ¼wíº1ˆH†»åþ´± Š[Õƒx±‰¬ú‘6¥E©Qö¦f#rupMX-G¶+ùÛFGGS„ݵÐQã‚ n-.¢ÉgÝNºmâìBÕ}Ö“À晡½¥´Þ±FEí®á¶"ÃÛ,sîæÍ£v¿ì‘íeˆ–?dnÐ/óM63ðþ1µÁRl ¶[ÑÃ}-¶¦Xo¿YwHõžÌ×YOh@;{FLŒÖZGÊNµõqë}ô:ãRòÐ�8¶­1QŒ†õ ù¡ Žfzab ˆ[+bߎ^ˆtV½ï´ŽE¨Ñ¹µ±W]_ç–0ä7üÄ©]GhÆ€`ŒmšTDÌDÃám³û±¯pž—a °scÜGhì–l&nà °¾·½Ò ¸—6Q/IP}A3²å ]^´ãÞU{ÒEæïÚ#Ì|,cÆ%Ò³™®¬¡žìÙΠ솚w·:PéÃ÷ÿ¨­VEö¤á€ðe7ª[} ÷ùÒhÇæ9ôדo8øß¨‘< Vš;´c/y0,ê±{ãÛ†¶‘Î;²ŽšÚ¨3’½›¡èPíjzÆ»€T»[¢Sv‚´_›«¤LI·õX¶‚Å®‚ö«‡"º[wc½Ë˜TˆÂ™ÍŠôh£Üæy‹'¥Íhmu«…µ}D(Ö~Dë) tÃë٥ƒn$Í£F•íì˜ÙSÄ–Jã=eã‘õÁAFÓyÊ'`Y¦«ë[wUÓyw÷³Ê±<šÚ²`è¯îÀDJåÈØÃe½mcÊ}óI.’yÄýÙtæ0w€Ô1”ÒŽ:×m<³~¹%4©Ní*._†sê‡v¿¢?<¦ô"WÝù”7šŒC¶mì‚k¶¸A@½@¢K]›Þ±íÚ\Õ‰ÍÓëCL÷oBÃ=­\×ͨ>BiÔ¹F œK°'ÔP½t¹9t¶ü´[È·Q~µ±ýçFºí{3éÝAC&° 6Vî›þ|j3$óÕ@"ÜvE3ìmIM·M³=Îe‹Ñíº¾åÈbÚëŽôÈ* a]O,uëZ·p�Ú”6xzÇZárØÚ‹hÔ\›ËûzìË B¿,­H¶¶Í'éÃPõCôöph^M¿Ìîý«i ˜¶¶&‡î‰Ðw÷èñ ç¾Æžû^0À^eBºChŽq˜ÝÂÜÃDVWƒgqÿa7”Ž#Ië¶¥jgåôTN”º°ý¸c"‘úãiýﺸÙ6нÞÛ¢õAÍ�›˜- Q8yLºuŽ™À!V®MOäF§½ÜDü‹Q7lh»‘òÞsb  ´m”,¶ÛX{>ÑÞ©Û„¡%â8Ìmz.Ed–UFÅ#]Œ:¿h+ç…ê&É)^f1ØÓЧ‡ëREÕ‰î¬ûkˆ&�� �IDAT·˜†D¢v`"?tÈ’d½3úÀ·-icÏ…W߯¸V/èáFäúó¨ùð _y;¢Õ^þg_³÷ejß©P/t~ mÿ\ÚÝÙlVUƒå©[Í*º¨2þôÍ ×‚‚•¿™*yÔpž9Æî͈r߀YabCKÇy”ÀÄjÕÑåÞv½ò £µ”SÇ*ýÁº¡¶4î¡Ï¥ûÁ‚0Ò—ðƒ@3tEE©G¶µf074K§Ž²î´ÕÉ^u™6¤­¿”íâ  i·Ön~°ëQ:‹ÜMÜ` šhõæ`øÔ–¦öÔõwÞB¿w;Ðî¾á°Õ¯"$Nצ‡¿^øšð~ýúu·¼º5Û«Ÿ8UiL«ƒLTv#Kzëàm~ýIeð¦Éóæÿ´gccŒ@GCm u·¼>6Çž!ìañRGJ§awEDÈ„“Úвf`÷=Æ‘uÇë.Ç Á ûØrj3<©©M¨qÿjâ=UÂÆ‡™’í,Ì”6¡ÜðMi ÛnrÏšÁcVTá¼7èŽZ»l À A‘žØ‘ ­"ƒ^µÅ^¬[8Šj j%Sž{W§è ë/a_ù ë«­¡õ_sÿk^èD}]öEëÝ€ÀÐûÔ¨¯fÖaDò˜Wðnz£<±;�ÐÉëmvÍO Â͆űžŽ0 Ì6:œG… -X–­†µ·fÚªæŽÖÙcè¦7Šë ²ÑLù£^±«v¯¸Ý˜ŒQ ½áÈ?ò‘Ö£><å�Yja4‚=·æC½,I°¬Ë¢°iâ­bSîsŽî½ž¢7#Ãvžc Ÿ¸ Rï¿Ô6vsÓdóm:ÿóÖn¶ÿÝù!¡mïüéá ĶJQ\qgÕ¡æt2Y´©»%ËÔ¶˜_S¾Aþ‚ y¸:`\YíÉÒï¶-‹¨CÑÏC/ÏËñ+ 6¢¡Šœ5£¡°ƒÞÿ$ШÞzÀÄ¨å –T‚*±üP›²5‹èMûÈíó-¡Ê Oæ —1;ªëûÐ<˜©î÷Žìä–çÚ´âú‘¿wü)#Ýú¨GQÛUL#IBïH¸,õdmÄ#ùoÜÙQ}m¨GÛ‡Þ>v XÜÎ(Dý¡íU6é¡×©Ž›^ó:µ>ÝJ×ÖÇ #à«S%mÓ­!iÃ7l >j‹‡´m5bÚ÷øðoä‚7\;º“Ñ/õWuéë—àÚ{–ï�Gª-ÿ3u¦î’´†‡q€ÇÆîªgóµá›µäˆÕ«Í23XÅ ³Ô#áæ 1{²´¨L˜À°#q^d_1œ¤PTÆÈ"|¦5͸EP éhï&¢ÍE=¯H/ϵw6a½¨·ëèþ°ÇÊÇ2'Ò›ë`甈Ö[zp¬2T©rp LiÍyïÿ¨2ãåÞ›°áƬ%«¦Êùj Ý=Y¼·uÌâ`@cXƒ*¢²m< 7tž8À˜ˆ¾3¯0ÅKMͺªƒ‚—ˆÈ‡:ÈÝE±ú‚®t/,ŠýÏ7ôñè¥NÊÄ™=|÷…zÁõRuÍÞ–s‡‘ø6ÀÊL §›R¥-É•b…’ÞòPm¡ /î‘õņ`ú‘ºÅ&¯BgñßGÒ‘%ܦ¡´ö·¡!äç¼…­ü{RŸU俤ºÙäÁÜ_x#r4�vÔ�™ 3äKt3b~ÆG¶³ÅŽ]žÌ àíB=tÖÒjÏâñAoa0ée4½¶¶kMâ¿2yÅv¥¨`Œ6›Æõõh7¸ÝVNR N­mß§T¤»B1ÛÈ!�׋¬óT/Ò"¼ ãràÙøïnömÙer' Ɖâk{»YÒ{ïø„Rv{%5)óßlxuÔóŽÊìy<ôv˜Nc¸†ÚxÜ£ô4oÙ›a=®0ïçÎ;‹Ø¹ÃÈ£á~ÇÀ4O“…å­vV}Ù ´:}~±OgT×b xé'oW-¤Qê`%Û¯–³† Èª^#«Ãn8ª`£H­"Éïr:LlÊ£éUfË9wêVdO8} + «zä­Rñå-;ýTÒÞ=Ï»÷(L¸Iâ݇&ÆQÍ¡=Š~‰ßèeY"$v¿àë a¥®Ê§§ŽÕ–)ôô$„u`η»gªÝ™nÔV4öÿoïÚud[’j„5ƈù¿�..HŒ9Ÿ@|Cl…[)mé8%µF´tQKè——‡‰c1/·1ö+ß‘™Õs"ŒÖ½}ª«jï•kUC#— FÒ,å¨m¼Á,‚и8ñAÝs Ší¤Lì’³Âóˆä¸~ÁÞ¾y%År0áSkßö½wߘÀwÉšŽVNXV‡�ËÓEDë™n™É@o:Ý?Þ¾9®G·è‰´ðFînÇ—ŒBàâ‰"x^þ~eè±Óì2EÕšÊäñåÕûâÃYåk&Ñ+tbü݉w}3cëoœßeÄ݉S~J$«G . æK|ĺÁéÿDÒùK“M`÷vFÃuŸÛQfú[ ÍtˆrÈn.UÎÉFwÂ)çìÂë³_µxì:^^@LžTÓrñ„Ó-äÀð”"¬)v.ÞxÄÉ®º_ήB±z!j§¿Ÿã »euË Ëev”PYÄ¢f[ëê¹ìÂpO÷ûê~½ÒòpA éñ>]ènY7qÑá¹£v¡Ø­0‚ÕäÝ1Î%d‡ ü·riWÆZL)�˜þ7¡(‰®4}Pu¿KÎ …a‰P†Þàc<u¹¯dôÚ ·YvDïPÉÈ]¾nø›ˆ¾€–ÃCЛ,` °l,ÆjkŽVG@=šBXL#Üÿ.ðÎO„¼yCZNÐ\•³µB´Ø•�åL×<ÇãK&@!0˜]8¢ÚFÎzó`Ÿ®Ã\O.Øî§øòžÎÎ@µ o\ß7†ÛJ˺“x#ûp?-…¥uÌÙ]“ è »]EðzêU€¯€{;¢ŽG©6}1y÷Êa†´*Ôq»6šó Á°G‹+y òeÂašíÈ`V•7‘¤¤ùsUªªõ$PÏö´·÷½fߨÏeƒ@jQÝJîX €T>èÎ + ¨¬ÕÝØ.˜ššÅ`‹�êdƧ],c¯}ŽzÑ|¬áô Š1lj( @�åQ9ñÈ¥C<ä²²o˜ÁÙ›°óÆÙ®3ü@â”–VΩª¹$¡‹ñô !‡d|oëÓ½"{”ºytwŠp@\%¼Üá=?¨5îé9œ'ï“Öd9,8¤*Qf‚Cð|‡=Û¿ÿ$\Ž}0L E9ue®„&¥+D?6d^͔ͪB P–ªx*ìŸ,í§Ï;~ýíS~P#ärÄœ=âŠ$fp -ôÅ×( Ø­ićc…œŽ£0»?)W=ï0xŠÍû ³¯¨L9q.,Ë !xãsužÃömŸ8q÷�}Gp‡K÷4¨ÞÎÆ¤ÛQCÄ»#‹CRUä1âéõE¸YÒ¶4Pêv󎲠£ 9Q4­ö©Ìið,Äéƒö)Å$¨‘J ¨\+òž<Tù4ˆ‰T+‹ñ-Ê}"7k«›óñƒŠ·ôh]ØÃ^0Du¢«;”5)rXGº™A8ºÃó�¬”í\ºQ'UÔ3z¦ÌžrÃ!—Üá㶯°3 r”^çöIVýÇÁõU.2A{e¶¬p²\ßÊyCæ�pß$¼¶.ºÁêv$†î7†hl0ŒÄ®PGº¢[äj©ÍÙµM¡B*´´?;R.Êæ:úøÑd´,Ö‚šùÄ?N¿îÛ VÆLÌjì¨àØ*¬­þ ¢ŠÚUúPé—¹Pfô\ ÉK‚'TR*Œcg…¡°.Çíó qÜΟ²Îá'-/BUç$ t.]8 rj`P,z\è¬Ã˜ˆé�ÖB!åäFQ4„¼3,à¶‘½í•·è±ò!寴ɠB, J{e÷_ª;™Òú|˜ï²G?Uê]aPvi‰z“":knxF5²ûF߇Æu4fN<Ø8Ÿ[_s }ŒØ ·ë:ê²òË$AU¯íê_ …é�C+WÔÈþpµZZzeÚO%öc,ÏŸqb œÎ®ÿsjœÞs=¹¾³Ê.ô2ÇÝcd¹RŽ¿º—žãV4,ìbßÏ·½]'äkÚ,ÅŰ¡xÂy´u£ËKÔDëq¥�;ØG+wøº×mÛ ^à ݲ¾,à`uI£k¹xÈw7Ú\yñè¤4ËJË:rV”z•~:£I}MN–ÔÇ�%ïï¯üÏ7û¦86ðíVý×0–¸úCÂ"lJ᮫E¯¬jJ–]CÖ÷íB?P媒ð-g´ .þ»èFeF½æŸƒçuÍÜ[ÿxÙ²§œÜ£n ô 6 Ä< çû}÷óØ‹ÚoÓ×ôHî8«ô™ž1œøÛD¢¶1<ßüq[�€ïûìŹÕݶ¿'º=¹Ûêà‰Ne¥Ðr! ©¤ ¥ÃÕ‚™ÇMâ €°6g*ò†Åý5…L!vÐŒ·UdýXÄ!‚ÙtŸï†)uÝG®!zuLhh8—#¹¶3µ2ö,æhŒë”9©:GJ…ój—%aNéêõc—8ÇH+)KQ=ê4Ã$êL¹vÌ¸Ž¹ÅÊBQâ¶êâ¹S½ƒ_.Ë/Ú ÅrÇk^nðàðÒœ€ó(bÙ>nu»ÌܺU3na·0ÝVÚ~ùk¦åé§ÿt[Ÿ—òɬVЪqÏ2SÂÎT®¶;¸¬•ðK,©ëš™Ð›eÀÊ¡Â6Ö—Ë߯‡UsÞ28§Fõ%+#³D˜§lªŒdKž=É7!¦r¾Azëýr­ÕÑXÄ©Ô'ChJ_b †?«‘Õž|Á;g”ªHZtWwÌÊW÷$LÔâPíaC"¢Äm?fp×±<ì$ÛG“÷UW¿e <Ñ´ áù¶¾ÜÀ?xß8Üôî°:·iû¬îöôüõ‡—ûß®´Mh/p¿1!Ó ùùгÛX:9à1½…R£Å\ªë.`.½“tRhüc1q-7%ºo¦ÆÍª¯aû¨ûÕw®](xàF&ðÒ”š«¥4H›²k|yQOdª*%+Ì͵¥°ZÐÁTU†cA˜j‡½ò@[Â4Г&Ýìk!Xž¸æ:¼tÒ?j>º}Ö]m-¨ŸVÈò9û]¤K@§�ÿ´€[øù~uF×JGÈw÷õ ÝéëÓ}“‹p{·«Ã•€ ~¸ß¶³}v$õÓñéÏKSÊ"êTY*Î¥V†Nd›‹dÅ ôù T¬ðŽHs—oSÂ>Ý:|­Vî¯TJ­)tS傽ç×"g—/C7j£E*3ôÙÁAËý2&Z8Ø¡”Ô þÅb.‡õެ?å¯M;_Ÿ–nüK±Ï.ËmÊúþíN¦ti霜Io¿$öqk&äû?:¾#;„û&Õ !»ÃÎ=Ý¿®?ÞŸî÷õ·Ã Æá:ww�wHñ8|rKX¸¤:wYݽ²&hó©Eœ5f¬ò0*!*¥€ˆÑŸz)kÑãÃì Enµª*2UK¿,xò¸øÜÀFËãlˆ):sf(vÚp àÔÑTî!¹‡w²$4û͈)D¼Ñ-À½‹Ÿ \Š™| ºx3 ä·ùŽ/­…ã#–È3 ;ŸÎ×i#¢9»ŒÎד“#lr]€n»Èó†Ñ½ÜàeCXô˜ƒóÇô&÷w/·Õ-«C¸å—ÛÞ �wOWÂugsBp »cæüøüig±¬<g¶ËR ©JZHu5!®§ÿe åû¢›Cå7ØÔDNó}>EŸR9cEõÅ“8ÍŸ  ˆY¨:?Í Ò‰Í“Aošÿì¥Áò׈& {Izí:Ö2àSœo÷B]ª5DaÇ}Iް@¹4\áñçÿXõ~ˬ1çP®³ÞŽ×/pÇÕᛘùõÐØ<iÒ…÷À³Ÿ‡¯°S_0áÛ—`ºíÃk>3GÄÈMËz¿ñËWp¸>#¼8 ÃW d·€»±[àî˜nü @ÈÏÏžqçyuKš‹T“z-ó¼Ú1±š¸¬’GN__à |E›sgzù‘ øs÷°ê´6Ç,n,Mü»¾‡TP3-]‚J�¢:,å)R0Ôë’‹‘Þ%|² ?À„¹ˆëI§–æéE¦g1?£{rWlŽìZ˜¾†èSÌÌTK[ÙõðŒç)ô%A±ÿS–L ÁéÐÂ÷^¿Üáù+»;<»õå¶Òß>½,ðŒ›òl}J´°Ãõ™òY|†#½$>XÚb®šäQA!y¦+À7r;Tß8‡éèÑÊ ÑûGçÌP¿�5}>ƒë Û~Ù¿ï —ª»ÊlÙóž+8XŸr ®Å\«qæø¢¶¾°²ÛvÓ8‹D'“TÒÈÌ“g`¨8EV ¹4||ïbf]SD8(8®ág`p�·SõšÏ|ù~öqíútÔ";Øuü×mp?•Ä7øÉñË?ÝØÝø~t޹èÆ?â60Î-áp_ ÕÁÒãØÖS²¨’oPlŠÙêÐÔõej9«öbés× “2‚9¥¥fÌRTý¡¨óÌyw>×Ö²æzŠª”“[m”ín<;ý›ûÐåò8ä¦]�—ùÁ&äåNH¡És¯Çÿf¥l8RŸO§(ìA ]“£þ2ŒÀ�ð¼-,k¤Zñ¼³¥®äð霃þú¼®õ’=È_¯aép"šŽàýÐbÙNØá>ææŽ6*w±Ø²ßú™^t²ãR´PÖÜI‚î d¿O­SB—4„g$Keâxp�âƒpf´ãüÃx–xÈõ+•Á{ž*™rQþo—pcão)•Û,†1®uì~É‹ TŽï÷Ñ‚–v ï,Ô;!X)[’« %~”¹ÿ‘îÑâÇQ>ô¼˜³ž¡îîÐfaýtu{ïS®;+¸uÛ7ùa¯¥Q oTÂÛ;^eãàb£r ÜqgLr[¿Ów€{Q|;€ _¬°ykÃn,ÚÎK¡¼{L8îë%l ¤‡•´ô4¯­ö“× ³ÊL’Ì íÖ“á#àªêY_(¥ðÝ»›”à҉䃸€ò1ÄÄG\A. ?„k¨^Øy¢ÇRÀÀ}'¯ö(˜|`gÉ¥xÈñy¸wàL¸5üp0“oy¯*^ª×çhÞuZ¾Daî·ËY»£ÃÕ“ãŽÏo·òŽnðrƒpÈ/�ÏËÑ¿T!b)DÍî„5˜±°ê¸V=Èà95@ij[Wä%¥Ïåd€(´á4ßóýë›k› Q)Ç©öê\½Œ 4~øÜBþ¶¢uŒ…’"­E0:5¤ë°ÆôwϬì5œàl:nlo®ã‰/bHi™1}Ðì÷_L‹îqC’vñªÏÿºµ*ÝŽdá]=ITLÔR/¹]¼z+8®Ê`á2ŸÄμ²E»gZøîvÈŽ|­:¬fÕ…š™HÈÑÜf!S×v^Á›ÚD(nÍùt©7RIFQ5q¶7?ºCAZ›Âú7äcC;ÅP\*V÷Q‘zÈÅÚ,OUHQ{ù áOYƒs°ox*‚ÑÛaf‰ol2ÇÇõ'•<}N!‹PtsÍ>Ü]N' Üàà ¸ùôd©zè¹®ß�°"ÉòÆÐK.§,¶_[\…š—'qi‚,8§Á`b‘Žî¦XƒúºdqvߨBõЬB­Ø‘1dç LHî4˜éS×íà ÎgüHy<Qþð\{(1ôÈI•,«®Þº§,G%e ‘`ûÕÛHD \K[˵Ð<J`]å±xE¸–f•¯ 4òs¢:ài;­ÐÚøüÏÈ'¿÷?ÖXo‡‡ H"„Eþ+>f­ìûÈ'„u 4PÄ4u#½G"!ü5¦Ñqî­û TÜçÏqÞ@Ø~öª'1¤2„Åq„¾l¢c#V¬, f¾ä¢.館ҞYaØzp‚úŒÒ::eŒÆâ ßž/y”¯e× >Âò!ªÇmd_=ûdsòT ž …‚¸µæÓð%‡øzAß”ûˆUTOgy››W˜¸hÒ>’Õ •6wêÝÅýaL_š(ÊT_Åù¨OIºûõ=­tèwìkäßs±cÝ]lÕFXöì‹,*ËdÜ…>?¤–ǦØ's½Ê”%ƒQn€™°¢‹Çt�ôW^ê:±Ph®"¬Ö|³‹c½<J0_cSá½ZFØà¯ji|ÿº<~»×®Œò55+‘‰”¨È »Ñ$l%F­ñN‰=$ugû½ö),ˆ6%½¶ç•Ó„±^SÓØ”5ð¥ê¡z߆An–\’NÕ˜ë£ãäOJ×A<<'ØÃO8.YÊ芃K­Ašù¶Ü•§î£»T?huÊtU>ZD²z),Üe¨CT¤ê,%hHÌWQ?×[ygUªXÙîÖÌ–‹Þùbƒ ! ø8öØ‘C\’‹Ì î�7üš[…Ê%E±këȃ"ðPÈjG­ŸÉd®VÊÜvÎÇ!¬`ÂâvaÝônb>µëXEÒÐ#–ÜøšiqìsçöÄxï“&YoáË|át£Z*!BÒ¯Tªùó÷ÓöézqE–²{’ðAñF ’¶‘AУx%£)î )ƒ¿Œ\Œs޹m±ÉÞÌwºå.ë ûÊi£Ž‹ºé±CŒŒE>²‘ƒ/á5† çñ§ ZqLH\JšèE³ªØ‘ÝÚí.j¿ä‘oØ ¶nÝÔº&Ë&F,QÜN&ãhd%…àFû±5šùVùÒ!edu¥½90 Éo³bHrƺàk (ùÇn?¯Nˆ˜JãØ"_J~s—ÜÃò­Î9AVé åÀ8.Ej-�’8tì;pÚÔMïL¨úûÒMúµK+u ßuw»á|ŒØ€ú«æaÀØ�p‘ê@'l÷ËrGcw²sç*•ÒP+«˜ñ[å‹o~rN³óFð2×øÝJóJJáˆxý{—À$ âÏÏ$‹ÇÕŽ:£ò‹äÖZB‹ IÇÆ 5s[Tû/’íâYEé]¤B$—ÇÈ6%‰ªèyëØÐ.HßL˜[óä(›ÏVW�‡‡¬%®hç\Øò°bÆùfšVGrò½öùJ3|ãN9­«XqŽGF¼´½ö,kMœÊ‡å…ÑÄëx=6þUÊüX~çRó>åëÔ¬Tê{í_N¹>Û‹_ÀjŸÖ—wÊ eU¡²ÏÊÑýè·-é3+Rø¤@Îù'¡B÷…er[&a΂™÷¡LýÓÒ�ú\«fp‚p®8z϶%äü×ð:kóµ¶oÂÕA«}ô‘ 'вïÚ­Æ\¿©ÞìLçݘ9q¦Gõ /%ø4ö(:t »‡•ußH0À ß“†DÌ'Ôȵ TpˆB¢˜4ѾÜJ-ÉÂTv©Ä?C3^âÝÃbâ&d›)膦9CuÀ¾aKyKc®^)»*¨ûú%Ÿ÷Pr“%»&?¸“Û)NãËÚäE­òˆÛË~jÞ©ÓO|ÇT?vÝ0>Z ]„Ýl‹íšNv÷iv‚¯L±ÂˆÀWÿk–÷c`û„ÒIõÂüô·”›“ó®ËÃŒª3°fdÍ?2Ô³ J½[_æT©KH‰¸úªŸcåÏŸŶvš¨¦£»‰¨0¾Ó— ¬³è‘œaİþeP#O¨l¬Œäšê¾ñ¹#[ö•”Â5 †í©ø…J$m€®{‘„¯Tu÷¥L  ý79¦sû$îÚŒFö@ ÷]ì$cWN 2Qº%[G8»‡š*%ÊqÞ@e©j|Çè#× ãaFÈ£"Á4HŒü8ñ„ª$ (,VV—)Ïè÷ ½£|‘¶WMúQvQbòõ/`¦˜À™ø»qÕå‰hD5$q¡ª—,¥ˆà¹ù²¼@°¤¾¼;µQšè¡$Ó·È|«z6HU €¥þdÔ]|úØ€e1²Â ›Ò+MšL¹�Ö c$ÞTvkŽ^z„ƒ¹ï†C@íÍP»½âi¸ÊƒyÃâ�å sí6A$7ºQ¡Ô‘Åuء޹/ö›Ùîä<óü ØÀ\(bä°šft£6wŠ bí¾Smðo§n‡­æÎ©—�Ê%&ÍeG‚AhzÀÂ"M*‘K”®x¨2Œú —ÈÂ'›ëdí¤y”N~¥½½ ¤÷, ¨ªZh¶K|“­=%=ðâ#/P?;Ò´o36áéjóYçÃÎgÜÈ×NògT¯ujeîÝ"éºÀ 9œ.îÓ‡º,½RZY·ä-kõeQfýåÒVï¡d­ôeúÞ‰d ã©h»ektÔí©@×ÈɨŠ&)¡ˆNµùéZuLåņ‘Sõž-*üÐIBªÒHp\4%ÕI§s(ðƒ²«ëé*®"§4ðô‹öl°>’.W*ûZ(°ÞAÁò^¢b¥òκj@‚Îéó剈jÒXçÕÀ’àéuaþòÇÅ?[Ý �ƒ!GäÓQý†ÂE,9º¨SŸBï?ô¹¤cYN«V9¦fä¡×FyNÆ"™µUÖ1µº}H·Ï×J¨n  4¦’ä÷•;êœ'˽ª×‡¸)�� nIDAT˱TŸÞ}ÓÚ{{ÂÍ·ž—S’;b|ØDbw¸‚Ü4c™#Þ%[N-\}S dÐu°U8Q/YÈßíOÊ”e]ˆ\Ñ)Ë[¹H’Ì’ë<TCÓ‘¤ ·P”Œ¦^0=¦î­D¸ØtÐsŠ®ƒ{ó95É#Sp¸5úuø£×º$|ȵOhQ´LIpÀN­ÍOÍP¡'nÑÒ*Ñ“I' æ2¯•²Š9ý2¦‚D³S¶bK" %”«•Ul:,Òì/­;v­Ú´ÛЦâ.»· Ù>mÜ‘~ÈØ€oøWjË ¸OB ž¶—w^‘_°g'¼:V«¬ŠF�ìL¦@îM0WTÁ"ŸÌ*+{ ¬NTÀ±pFWENƒ{!Wߤ?w‰H\Ñqó[ ï•ÔÊuèô[¦Û>1g¡0áåf~-ü†å”ŠÅÛ˜ÕÍ|Ø¿c©K„dJ¼ƒU0%ž´ݠر**–Ô^õK¸oi:^ìµ!¶ï@:ÉLSûëk, \˜0Ú¶_ý+êèQDAÅŒ¹™ÔëTJSð ô°Jæ§üDýÏ€%/(žõº•ù€ 2UsáÒFURµdÖ®ÔRðƒbß½¦#~‚)’a TеÎ^”û¬„+§­¦)×:}Sßé‹ •¥fŠ£ßºT‰¨ !(nitTöx‰ÐRröicÃPÅÄÓ¢´¦e¾0Ì\ÜNö²¹œéŒ�DçÌ_ |µûå9õ8¤L*ÛpŽ6ÕäyU»8Ûó|”س*Æ—+u"`L¨¼R]ŠEvx¶ÒN°¥çá|ÊØ@åmÊÚuó_¿SªSÐwDI"3ñŠTÛ>ƒÞ æ›`½pÉiÏUiyDZŒXL›Ç$TÝäÚ~üâÅb…~Ž›ØÉ6èœ ‘O¥Pñ *Kœ¹IºdCô÷ã1x Ø *¢[Q´¿2 Í:V=iz½«j±ªá„/Ðñ­¨Ð¬EIŸ%É·4¶ü`^4Ðõk:”¦(׿³ e¨ëªÉâÀêp•$uÏì”åÍF&SÔ ârº+iù[¹oé¼!G=Æã>KõDóŒcõ"1—͹BÒ‘b*Î¦Š½‚ªºtr§Ç}g<%o.€tYšî lÅð&õË”¶ÔN|F„ŸDë 5Àý Lü †0Dï=è@úyÊ=üºoŸý4äk^¾ UçÑÌlE¹4xŸ ÔMe+aÝ#wBÙö¡:—ÝÌÄ—®§#t@‹ºns³6#>Dév9öPÑ~<®¬'T/ûhuuÇZù-úÀ˜Rýض'bÝV”ϾâÐÃèÜ´‚¼æ‘ÉÅ ?ZùIß°t†YS*|p8tO!k[ócMTYa”œò]Õ°šÜ«ÛÙµÛ¹ùnq»÷NþËäö8Ë›®ü¬êÏŠ)«ñ=(ë‘#ô˜{BYÈÕ¬ª˜ÈåýÏ=ùx.Sï»Í%Èuä˜*ž‰í r¼ì®4jn†Q°þÂr+gé.AHàÓ…üÓ”ð‘~�缆>Vlh>EœÚ)ñ½÷NSš¹£T×ÊâSÜáÜgØ‘´ ùàT£âë ='œ/wÄ]Îk~J• :Ùe*(ªº«™n"JHÆt›]~ÖS£ôIÍdÕ|1×UÊšºÁMmCƒ;Úˈ@:— VÞçïŽl—Ë,IL Á®¶7ZÚDíóeYž‚»ƒÎ½.¿:%ÿð>¢>FûД‹¦nú(½WÇÎûÏɺØ÷æ¦ Ú÷¤ÝðI8 }ý†îxþfõÍî†öa“¨Q6nQ÷÷A9ß¿ç³+ÇR¥8ááê¯KtëÜÜ]©™ÄŒ2¤fHøMä:{‚?¨uˆ,õ¹µOÎÃZ¢@ìÙgöÝ|ó·²›ìykK#P.j¥óUÄ|¶ž«T"›ÑB4£ÜÀò€‰ñÊ!«¯·ËM7Y'v×T’¡¾ú#—}²vBÙŒ¢ä•¦8"lÄþ¹NàÑÍàè[©^S¢ö”¤4ïò›ÌkÙv ò³Q¼R-x§suì2TÆÝ‘]Q«™jÉ  ø>çeÁ‚b…%ïI}E|‹÷PAOÒrèNïO'‚KSò‰G¥w` w½sl˜~×Þ±$<™„Iã¡Hì|›Œr5ò™.竉ºV“öaÏ+stœw…Ãìßn¦‰oKÇ4LLð‡ Oÿ“æÂ¦ìkùöiB4cÝ%åówKß_Ý€õz–'.8 +V~)_q“²šs={¢¯$¡œ€Äƒ×((& LLx±pYŠ£E±†pJ=ŒA—¡äìÛ6Ï uûÔç+34·˜+òPÑGÃ5ëƒný`=¬o-GÎÀIœ˜Hšâ%Ïr„F®Q,)À§éý«<þ)ކòýÊib ˆmÚœ`ZUl8}|Á ¾áBzüº• v¸šb¤œÝ_÷cößaÿY÷6Pøkm’õmU0˜JÏj“ñ§fb0מõ|ÀŠAo$¾@ˆH2Öäü‰Û¡ 5Ðì>¢ðb9¾ÉÚz¥õת\—Âv´Yv6à §=6¤+õ¡…B€~àIlÂF'oå¾päE်_“Æ-ÂF\i†½ñǧKu±8–%!.$ÁCl|Vu±©<Óµâpö©×ïœØ<ÌÊ$(·ÏDoÎÒ'2 ܽñ9è”]ÿ™û”ºäÚ€6Ó½2P‹HåªNJ;®,lFšréú›à_Êßd¬~¢v¹¸$ðÍÂk”J\«)ã©ÖÃ@}Rêü-e¬ê¶t¬Õ9ûýéa}û0þ˜…Ò"—ǘ+E�´“%z‘ª¨¼ø¥î1æJjì79Ñž·X‡åkwº6Ùi~¶tó§÷ œÅÍé†q]šçºïL¬ãc{Ÿ¾£}S±¡‘þW#*=,'Šñ”VÊTž››®F0Ãûð\Ï¢aHÂÞ30% ä’Ú‘d«rçjÙÁ‚ÑFa”oÍl @Œ$a#-§"¤K"V*¿¥ØµÔg´!}«±;œ”¨ø’·¡î©_06÷¡3Ú…nH乺šiÊd_ᨣ£ý_ÅN:´2ß»€.]> Ö? l‡ÒßÒ䨷¶äžLU'œ¹O;¹ö¸ûÍ¿ºa:|ÔlѶ]‹OêøVädQíbà˜Ñ•Gh*}z÷%Ÿ§ñ èD"q|fefr'ÉXÇ;ëpB#Yš,`ÅÐìz(1”gÂ;4qUŒ ú¿ý(±¡- ÖqåbšÌ)RÌ4¼ùÛgnS¸fUdz¨ ,Fд:=5#}±¯ûn8sBX§Æ#á0/„m×uÿëôˆ¤A{tIÛdü„'.ByÑ£Íhß®LùÄuÃŒèVµß‘lê2¨É5äÅìì¹›ëlcSÆïmÒjé>šÏ]wìYóÔ<ü8¸•å°æqTAj¥!·v oi*ÑôŸ¦0Þwz‰7ÄBºñ¾ÅØð–xT“–�eKßök77gãŠzs|Fa|¸™çœÔúÚMb¸‘‡ÒÓ ‹C. ý©›Ú#œé£3‘ÖÝ*2ç vÀypÁýy¨f\¾üÁýéŸüù_üûüÏÿýïýþïýç¯~õ+03333ûþì—ùW?ûù/~û›ý·ùûß±Ûaffff™Å33333‹ fffff-ûÝèÿ¿|ùb7ÅÌÌÌì{³×××Zl¸‚„ý´ŸöÓ~ÚÏïæ§aJfffff ³Ø`fffff±ÁÌÌÌÌÌbƒ™™™™™Å3333³Q+ö)½~¹~Ú¾ý´ŸöÓ~~Û?_­n033333LÉÌÌÌÌÌbƒ™™™™™Å33333‹ fffffÌÌÌÌÌÞÖŠ=¬ÖÄj?í§ý´Ÿßm«Õ fffff†)™™™™™Yl03333³Ø`fffff±ÁÌÌÌÌÌbƒ™™™™Ù£­Üú74½Ú=2333ûìµ^_-˜™™}×öåË—7ö„S>Qû&õצdfffff±ÁÌÌ̬joŸLùDí›Ô_o±ÁÌÌÌÌÌbƒ™™™™™Å33333‹ fffffÌÌÌÌÌfÛïÚ-033ûÎ-íôÿòe6xTÏRöýUÚ÷Ñ•V^o±ÁÌÌ컎 uúˆ9¸ìû«>´ï¢‹­¿Þ0%33³ï×^__?ã4CÇ;hƒœÕ ffffïVµŒÄ‰­xPl³ºÁÌÌÌìó†³èÉÂbãŸe±ÁÌÌÌìó†G–Å333³O$µBôúÍäkç ffffß²EM«Â°d±ÁÌÌÌ,v¦o6ßp~„êC³/Ö~íúë-6˜™™Y0xmþæ¡×ñ¡ÙK‚ŠðõvÞ`fffff±ÁÌÌÌÌÌbƒ™™™™™Å33333‹ fffff³íêSúÙÏñÏÿ ¿üË¿²›bffföÚÏ~þ‹LlˆþÁÌÌÌÌì{¯~û›µ{affff¶Ù—×××?üã?³affff¶Ù?üÍ_ÿ?Øay”+è����IEND®B`‚���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/scale.png���������������������������������������������������������������������0000644�0001750�0001750�00000751212�11332353406�015205� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR�� ��N���²]{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚtº<ê�� �IDATxÚì½y”\×}ßù}Û}û«½7  @ÜIÉZ-ÙiÊ£HÇãŒG¶%Ëvœ£qŽ'ÑDã9¶3±oÉ̉߉¼ÄJ±ÇÇòÄ–%Y’c)R´)‰"H‚$€Ðè½êÕú–û¶ù£ºÕÕUÕÕÝÕÝà~þh¼zï.¿{ïïw¿{ß»\’$�yìÇÁ`0ŒÛžg>ÿI�bË0¼÷ýba0 Æ#ýø3Ÿÿ$÷ð£ï{ïû?´Tª1‰0 ãú•×®žZlýÇ÷\&ƒÁ`´`¶Á`0†O½Zö›;ˆÇȺe¦²‡ûlÛ@}¯ýê‹_;šâR©T†—k$;}W×D{Q«½zÅŽÝÿ¬+0 ÆúlÛñ›µ³wß=ø#ç_|€¬h‡õlwÛ�Žk¿Z8õˆ·ðÜßûAþêÓŸ¹X]ÑÒcO¾{Lk^·1~ç#3 ÆmmœúÙ³gwôÈÙ³gÏ¿ø¢¬ê‡õlwÛÀmVî’¬8éSüÉ?}Ó^×™;/ñË‘ž‰Ò~_z92¤¦65R¬+0 ÆÇq;Ÿ1smü³½lßñƒžŸŸ]}úég …ü©™#ϽòÍñsoÖž¯^}þî ë©×ÊÅ»ïcý Å=úð»ßrïŸzéãý & ãö¶ ü®t4¿þïžÈohQ8~îÕç¿\«]äy>%ø+¿3vòA�õ•«wdðï]œ~臶-ÇT>õ“ïzý©é1I*u÷ÚRùßÿÕ×íš³ž/~çÃ?Ÿ6�üo¿ûÿͯT6|ðÌô¿éÜôdVàùÅRíËÏ^øâS/% �üßù±Œ¥ýÞ§¾òµï^¡Þ�€S+×J‹©üd×{ŽMdß÷C¯;u´'É ¯Íâ³ß܃Á¸•Œ¶hÛ'ðÏþö?zO¯ÛéÿùËAžÝt[׋}ü†^ “çÞ|íé¿Ràˆãª­YZf<åϽxueêžG9^ض¦yÿ£…Œ±¸bÏ-®dRÆ}§Š‰[‰b^$�§· €ûŽ¥®.,‰’àÑï»ëý¿ÀÅ« ®çß}rúýïú¾©œñägŸÙð]ìåën³ªéÑ1- éfn Mþ¥Ÿ~\WÉß|õYÉcoyx,­ýÊïÿ °¡Ä`ÜZ¦a—±ì$.ôêw¿yçýoØöÙßþGïùåûW­¿ëçÿ^¯g)µDyüžw¬|û¯%<Ï•.>ËÆ‚ÈÕŽ=BTcÛ¢çRz!cø4ø©üË„ãEI¶t¹ÙljÙ#¢(xÓ}'¼6{ýäÌ‘|ãöŧÌÜ”¡Ê?öއ�|â/¾ðñ¿ø‚H”7<p×Gá'~ðõç>ûågVÜEMâø?üÚ<ù×ß|÷[îQˆô—_yþò|égÿÞr)ý©ó³ÿî/¿Ç €üco;ytÌÔdFçVþøož¹¾\pjzìgßý†BÆxþµùZÃ}ûÃwþíÓ>ñÙ§�ŒeÌ÷=öð]3ã’(¼zmå?÷ôÜr¥£‚§ýÌ»ßO¯=Þî£ýøc¼ñÞ㦦¸~p}¥ò»öå;§Çu•\[Xù?ÿ?ªFê³§¦§ 'òÊÅRÈ-æ3,¦Ô=.ô£ÿð—¶ÞüçðÛí!Ÿ®ÏþÊÇ>ý›ÿÓ»[&aãï;žÝAL©…feõ™Gü«O;~”ŠÆÓ~¢8>=HUŽïÑ@!ÒoüÓŸyu¡úêÕå ³‹š’à$Qxäì1�ûä§íŸüÔx>sòHnÉMΛ ’˜$ÉŸÿÍWŒLÁH^YtV*“…ô='¦>÷ÌÅ­Šô½o=wéúòƒwߣ5ÿ•+‹S}ó}'¾ùì ß»ZÇå3ÆWžy~¥\¹ÿÌñÏžú…}óGžø”e™~ßÛ U~þÂåf­þ¶GîЬ®VVç'ûåŸ~,ki_ùÖùRÙ~Ï;Þø‹ïÿÁ_ü¿>åG7òVeéŸüo×Uù…Wf½fãmÝØpÏÉ©Çßx÷•ù•O}î+º&ß÷ÉfyÁOÈ¥ÍâÔx~êxÊÔœ<:þÂ싺™aÖÁ¸µü~WOq]Ÿ=óà›{™“þÏþ³ßûÌo|è‡t†öw¶ÝNì”ã~Bî(„)´ÚA”üÞŸõ'è‘{O?r/�,•ªOüé]X­ãî?]ÔR©5¾ûÒÅç^ºòÖ‡ÎüÀ÷Ý÷ägž15€çÓ¦ãfx^$¡Òô& HYºçÔ·fô;ôçßøÎËÿï¿úHq"ÿ¹/?õ‡ÿé³ù¹{ì-³¾ù¬‘Êÿú}þÚÅ Ãü»g^þøo˜ËÂ+Ý÷ÐC•Wíê?ý͉D1týÁ³'ZîÈýw³–6;·ôÄýQé#“=qÏtê™×l^”Ö‚`§Šº*—*µÿÆ¿$ù·?òÓÜuGë'Y’�ÔÍëË奊óÉÏ}ÃwÊ_yõêâ©é‰ÿÿ+€ÖÚ‰ªÈïÀÌì¢'1ŒQ5<xnOqßýÙ^©m\ïýì?ûƒÏþÆ?|×&Ãðð[ºäÛÕ6ôyA¡¶ðZX¾¨cq(¥¾ïƒ®ÖW˜…£ƒTö;¯-|éŸÿþdJ>{jú¿ÿ¡·Nçäø|úi‘¨o¼ç8€o<÷"Ç Ï¾rý­ùþ×Ý÷‡ŸúRÝõ(2Ñu•x^ÀqSP­7ã(BÒ™ËÅ«ó©ü¤&�^SÍtÈK�$I¤¾+ˆÜOýðë<ý#º*o<BNWD�s +à„ìä±¥ê P6¥˜)ŽÿÅÇ~mãâD>]ö5+?Ñ ¥L Àµùeð|njf¡ì<°~çóçž}ñòƒwÍœ»sÀr¹ö¯>þÙEÛýÍ'?÷„65–YX.½ñ¡³ozè\¥VOâ8F"°wDŒ[ÊoæzC¯ÔÚâB=ŸýõŸ{¼=õ¿ÿáçºæÛÃoèa”¼º]¿øM'ïxèn­TþÞyD�*¾"›ï‘5³U%Q8wÇäsˆìfã«ççs…—ü]o2tÅ^¾~ìÔ]÷:àñ·½îñ·½®u¿®)ÜyäåËó4‰$þÈ;ßôÅo_ãeþÞ“S9À·ž¿ ]Vn£(e¹%”0Š$Yá××É“$~Ó½Çßrÿ‰ùåòoì“MÇý׿ü!žç9Ž+W�ŽLˆ¢€ã§'ò Ú5ÀÕù¥ßýÄÞ¸X®Ô£0H’˜D�µ¦ M‹’ÌÏÝxÏ#ãßùÓ/ÑêÒT>õ?¼ëûßôÐÙמüô7. ‚ü­W—ÂóW üüûß à¹ó¯q‚®g0ŒÛ(¦Äw)õJmSL©Û³ÿâ<¶á1´–(~ýçÿçÿîó[óÝAL)ƒæ¥o€ã¦îT’5© Ew¾Å½ô5Y&’$5.~S¾çýëO$ñþûoiz¯Ÿ[®$ Nó�¾ûÒÅ$Ž9}TxÇõ¾ýâÚ>Ô™#ãG&òïxÓƒ¿ó'ûgûìO>þúþècoyýRþd1à _ýÖK¯æ¦ŽwÍs|ÛŠî&3Ø*dED"o{ç#<¿Væï\¸Zoz…lê_ÿâϸ!î:>¾ñÈs®•«é©ñ~û®—K¿ïÎé?üÔ—³KHÖ|áòbÓõLäá'~˜ròw7?wbê=o¹÷¥Ks®G‹“ã�ªµFÍ^ú­ÿ僕ºÓtý‡ïšÖUù«Ï|ïå‹WsSÇù]õ$ƒ1ª¶aÓšð¯ý죽îüÕ?úÂæ§º¿£0€ßÐåÙ|[¡¤_ý£/´®ü‹ðØÖ|{Ù†.»sßÉ›dÙzÀZß­Ÿ=zçŠSž6I’’$¹v廩ãö âÏ|ýüÉIkzr\&R©Rû»¯ûO?ý%ÅʽñÞã�>ýwßüÃÿô¹Ö§<î¹óØ¿üÈ_wßñ?|æo¿õÚµksï~ÛC'M u~ù³_~ê/þ櫪‘’d½Öm¹®âëß½tº˜yäìÿøƒïýÌW¿ëù"K�\Ÿþ›Oþ—Ÿþï91=ù­^ýâ×¾óØ›ˆâ€GÃß|òó?òæÓßsê­Šb×›/]¼öÚk¯q’%ˆRK\®þ›ÿø_~êñG}óCç/^ûÚw.¼åÁ3­+u—çðÎï;«)¤îxŸûÊ·þóþ12Ëví‘3GuU)UêŸüô—>þ©¿Q4K’U^9Sb0n!ã0à—„Î?õ¥³ß÷íîÆÖg[óýžõ}vÃ0´rùÕÿÅ_û™wvÏ·#áÖù —ç–;~p–^;¦T¿{µ>uîûÛ3Kâ8œ{ú¡3ÓQUkµ U]›éSó8Ž–®\ˆ‚ ý$NxAP´‘-IYºzzŽžÊ™Ù±Öñs¾Û¬,]ãÀßq74ª«~³ø~‚D‰jet++ˆ„ÈÊ•Ÿ‰ã(]˜2s“×^~@á躕ž{å»aà§ÇŠVn¢týR³VÖ¬lvb: ƒÒÂ,õž4+Ó¬”’$ÎOärcós—ÝZ9 ƒßù•Ÿ¿ïÌñýɧ?ûµïe'¦E‰T–çÜf=ðœ8ŽAe%•ŸRu³Sj¬J Wܺ†¬hÇyN£•cH½Õ…Ù( Ió¼ k†•Ÿ"²ºrý¢ï6’(DAÑÓf¦ H„È*M Æ-CuuñìÙMŸ(}áÛëæsoxÇš8ÿR*?±ÏnÜÖõbëÙ_íå¹ç7t˜Z/Óš¯\-ßý6ð›| NâÂ9‡VΜ<^¯×“ËW/5«rïÐx^Lã8äÀqœÐšÏ‹’,ÅÊOò¼À ¢(É’¬� ²ÆóQ4 Q4K%_³8Žç¾å ¢D+Eå8—+*ºÕªEjìˆ(Hœ �0³ª•%àÍLç€CK­+º%Jà~òñ‡9<4{mñ䱉ûÎÌ4÷ï¾þœ(i�ÇñBªp„¨Õ„Ï Ç%H„Vâ7ü8!]8B4C$Žç“$1£P%�D52…#</rë…DI$$•›ŒãHÄV"!"a†Á¸Å܆Ιø=o|ç Ou]Oú³û¿û¶é‡ÆêÕ Ž­L?,JòÖtÝz¡äÌ­¾ày^Ðzà(æC½‹ Íìn9¬ìxÇIVÒ…©ÿE#[¾Û"3vdãïìÄ—-R¹ÖO”Hû#F&¿5ùÕÚÛïŸyýÝÇ\Ÿ>óÂk¿ÿ'Y©7óÅIŽç9ŽDÉHçû7‰$+)Yéú“¹¥‚�ônŸJg0·gLi«I9´g»Æ”®,”oÛF\¾z¡Y«ÄQÈó¼(«VvL’UÅHól€Á`ì ê9n£ÚÞéÏùó/©FŠ(Úa=»q¥´0{#¦t;/„Z¹IEOñ¢ØZ©çQQ žg»† Æ.i‡pþüKƒ?¢©ÖS‡õlÛ¿ûvË£šiÕL³ÞÌ`0†i4CÖŒ›ëÙ.¶¡å785›µ(ƒÁ`ÜžhVf‹ß�85ûý�“ƒÁ`Üž|ࣟØ0,ªÎ`0 <ñÄíÿ·ÞQ©T˜˜ ãöáÉ'Ÿì¸ÂüƒÁ`€ÙƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0˜m`0 ³ ƒÁ`¶Á`0‡Œ¸Ó2™L×ë¶m·~²í¡}”ik^‰oäØžõ^бõÙö2 ±j{¯ûáÒ«xÃí];Û¡Ë¡£T;-ÏЇÉàuŸ²b§ÝïvdÑGot•ç›þ· /”AòÚïòV'ñÎ×>f2™ŒmÛÃ-pשÀ(†­Rz‘ö"œéð]å9šM?r¶a[S¿¯Óí^³ûök]ÙE¾­6žíã—ôš,˃éSë­•mϱýzÇßÙ4]E7ÜéÞ¶õDû=sï/í¡´E‡„wõЛl@áôê-\Âmåy»Áï«p·¶ñеO¯yÇ~÷›ý¨ÚŽÆX¯’´Ïß;þ>øòwXÙáÆ©WiìzRÜš@lÍqGÒ>˜a²Ó¬÷£KôN×û—p/ë£ú+^MÏü†îê�¤ÓkúÓ«WнÕÁÊÔ¦«œG§Gn;íJQ ½GópÀ” íS¯è:|8îÔu´î½é™mH(ÃRÜÜ�]c5ûTµ]Ô}ú�šæ–½öé'ý+¾­¨Gd~3ÄáÖkR?j5Ý樂MmÃêôý›fÕzEfo±¦µ Z{y¶ðÒF·ªrÙêL”ç×uYqˆM ÀÀXÚ'!îߌlÀÞÜ^µŽˆöMárî_Óܪ†aÿ»—¶ØºÄ2Êͺµx£é9Ý,ò¼Éü† ³<”ùBG„§Ýæ÷ZŽÞ¿Çp«6¬’t”ê°šæ`|¸®U8°vÙ*ê>èßFC,sפú$~Àݸ¿pºäÃhƒô1Üêë Üþï½ïÿеåêÆyÑìÜ7ƒÁÄÛŠÖ¹oÏU²š•Y™»xõüÓì› ãpìÁí«¹Y`¶Á`·Õ~Л‘‰€Á`¢y`0¿Á`0Ì60 ƒÙƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0˜m`0 ƒÙƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0˜m`0 ³ ƒÁ`¶Á`0Ì60 ƒÙƒÁ`ÜB¶a×çùíîAv| ƒÁ¸éÐýUâP&¿»Rvü±ßض͎ˆb0Œc—g‚nœõÚn$lÛî8úµÝxt(÷®wv$Ûq¥×¯ ƒq;»ÛªÙ]ÊÍï¥ÿÍd2íê{£4[uú¶é÷zjwi2 Æ-lú«Äͼ¿~CgbÀI}Ë”µ ½Õ¦µ®÷J¡ÿ¯ ƒqË»»ÖÌûkväì¢k)]íM¯_ ã¦k¸ûAÙYL©ÝÙ6°Óáìô1}|Ž®‰÷ÿ•Á`0n7›Ñ®“Á6ŒÓÔÇ'`ƒÁ`ôWž]§é#dÚã?½<Œ­*žÅ” cj¶—JÜÝ>%qåüJ¯¿û'2xš ƒqûØ€Uâ WÓoÐ b­Î`0£ÆaÚb0ŒÑD<ļ™U`0ŒÑÔ±ì;¬ ƒÁ`¶Á`0Ì60 ƒÙƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0š.ï7<ùä“L. ƒÁü†<ñÄL( ƒÁl3 ƒÁØDgLéƒü  ƒÁ`Ün¤Óé|ô=mC뎃)J¥R9ÈìF$뛢<‡[ÂÑ”F«T#¸ךϔ¸F¿?T9G¡­2ôózÝ7tž|òÉ å�²‘¬oŠòn GSí¥)ß:NoHiDÄ5úýy¤Ê9 Åh/Ãl+ƒÁ`0ÀlƒÁ`0˜m`0 ³ ƒÁØ#;>÷­ã„gÛ¶ëhÏ|Û °¯…9ÜCL7$?‚çåu• ;óõ&ê]7K“ÝžjðZQ>â-Ð0VžC¬øÍ8$˜U`°Nu[ø óÖL&ÓË]h÷*öÞŠ]SÛšo‡±QÂa)â>J{Ùz¹/{Wë½$¿µâí™¶_ïø{?k«èz•symõ\ûw•ŠeŸz쎄?ô¦J†ØŽƒôám»Ð¾–°Oîú÷ ®^ª©k.{ÅÖ6Rï•ÍF!¶Šl/RhO­kO¼„Co¡¡Ôtw’o7] ÓÒƒí:±«$‡X… “Ü5µþ¿îHŤ«ìH,û×cþЛf¸eboï߇ûöþ%<˜¹;Ùk| ’Ë^Dq³®Eï«öïÚ�;zê`bAv£ß(Ã-äÈÙ:FìÖöêõëµÑÞ³bùIj§y Q¶;Ôý§,‡¢ôö’µ¸Occ4Såšî¥Õw]’QïáÎö¢G±[ÛJ~d›fèš÷Öè»î #«…ı‡8½Ú¶iGD7õ }ÞŒêõ0i1>‹^ƒ4Ùm¸èz‹Uyž0ÊBã÷oô7.ÙÕ­õÑ^¶Ž(öͲ¹hXu02åhRÿ²íBÎÃGû‘àôÆQpÐÔ%?afÝ‹èøýâPäÒ5µövÚ¶!‡R®é¤Ï¸#A î=ìGÒfÖÙ¶«X‘/Fÿ&zÉw!Ÿ–Þ.ûˆŒÁCì{ƒä²—!)î¢4w½¸îÒÖ|»vëý(À 5Ý'iôOvw¿îGñ ‡ôïý/î·(vW¶þå<È‚X©L|X]ýÀFßhÂf×%aßÌ`07Gp‰q0ÛÀ`0F‘‘ŠÜÞ†ˆL c”ÍãPDÇüƒÁ`0ÛÀ`0ŒíèS:àÓñ|öQ;~ª?Äަ4ýèù›H\£ßŸGªœ#%.îáGß÷Þ÷èÚrÕ©Ù¦Ë#uN:ƒÁ`0lÒó~B³2+s¯žšÅ” ƒÑ‰x³¸Ì•Jå }®–ÿ4²Ñƒ­’¹)ŠÊäÀÚôö©ïÍU©Vi·± ]ï;\ž|òÉ`×D½Òéô†FM}$3âEer`mzûÔ÷æªT{i7`1%ƒÁ`€ÙƒÁ`0ÛÀ`0 f ƒq ¶aëá£ûjã­Ê­Ô²C<Fik:Û&~ 6ü‡.„]~k}‹Á5nçQÉ4ÒÐÙ¥mØøjîÖ?Úoèh¶®‡[aÎ ë“û°ò¼â[îõ÷þI¦s´réÈk§ÅëšÅ¶fÀ‚!åwXrØ¿¯Lï´¨í’p˜ RÇv¹uÜ3”Zo›þ¶ið¤v4ЇÕû4ÜŽ.öïêûSêßrÚݶ»ÊhX£¥kîCÏkÀ:î´ÀC”Ll›Ë Űâýïïz±×é~7‘ö©ïõÒòJr§Eݶ­7NTÞú÷+;`úýÏÇíŸÔîFñî|\v:.úr(U‡UÉ=Þs`.áp‡è€o?x§É!úRq@ Òpƒ‹t¿ÇÛ(Ëaèæ¡‘zÕt×Ãä&ŠÛ쥨}^®3ÔKôi¸!N•È6 â1õ9,VØK8C‘ÌÞÏϰá¶U|‡ÛУ#‡Ñ¯iÿ:Þò«¾½ã>Å·ºtƒd´m+ì±™Äýî }£ŒƒÔ›={§ûÁñ·v]ÓaÉá¦6 ý#‡û±2º£†¤öXHþ�=Rh?Ö6ŸÇµ\Å>“‚ýWÿiH¯€ì¶ø“=t9Ø@Øvâ¹ßSÎ[Ø` Ñ(v&mÛp;Íz×ãq_lCWϨýâ¾N:úç>Ü9]‡¢ß/¿ßg¦.þû4ÜN«°méêhïQ2‡%‡}ê{»èQ]W_wZÔÈ£‘;€ fÖÙѸè_È¡¨qRC%‘^~ðb2Ûæ¾± ^¹ô/Þ W†°|±k†Ûé^ƒµÑ°¤qXrúb×’ì´xJ£ÿ•þ:ÜÑ=¸F<©]ŒÖë{Q)#S—¹É & f4nÃ`°a¸•o·~?š©ÝJ’ar`B`0¿Á`0Ì60 ã6 {LéÉ'ŸÙðÙÜ£,Š›·¨L¬MoŸúÞ¤•â~ô}ï}ÿ‡®-Wšý`º¼õDiƒÁ`Üò¤Óé|ôš•Y™»xõüÓâáÎÊ ƒ1‚tÚ†'žx‚ …Á`0nK²=mÇ?üa&ƒÁ¸ÝH’äýÄÆÙ>%ƒÁ`tÂlƒÁ`0˜m`0Œ[ÂlƒÁ`ÜŽ ºo¾Å}ÍÙƒÁQÝ Ì”ÙƒÁ5ö]Ao—û>º2Ì60 ÆÐôMïÊ0ÛÀ`0‡¢ÄØ•ÙYŽÌ60ŒÛP‡Þ"³ûæì=Gf Æí©C‘}]¨è*´çÈlƒÁ¸=uè¡W퀅¶³™m`0·§eBc¶Á`Ü4&‚Q³ c¤ô]‘™‡Q³ ctf¯·ÆÃØ6ö^4ƒÁ%ô}Ÿ½ÒÝêÙÃñ6¤½ÎèÉÕ†ÀlƒÁ8Xš:{\Ïnw§¶_E ö4£ßŸÐ?"i0Œ›2Œg÷5þÓ©gEÀìÎNœaËêôŸžÑïÉìÞ^1ÛÀ`0†>%?¨Ùno=+®_µžE:¸UŠZ§ÿÔ}à % 4Ü9³ Æ-·¿3ÖîÏrûVô61¡-¶jèŠmWº»9ø­ÑÈÍ ˜m`0nA’Ág¬{˜Îž©È{ð3V{º Ýl•d†-Ð!ëîCܤ;蜀Ùc”9%"nþ¯´Y¨ Y¥¡U‡ô³Uàî8Ee—«Iï™;9Œþ0М€ÙcdíÁA„õ9 ½Ù»)ê¶ÚÄ\0œ%béiÆœmµs§2{´ Ü«´'6ç¸1sßÅn׃{1Ùc¤&ûíªä ^K€ÕÙ½SU ¸ÌPšaÐ6Ä¢ úH±¿ÅM€`u/¥â‹ˆÛÒÔÚÿ¶””Ò¾œÐ±š=@Þš6³ Æpuý'wª„u`¯ÍµS{±aÍNU•lÊo—çz¼%[gC,ÕAC(í*u; «éŸÂŸC@»9.õÞBÛ¯}“hëjövýaxë"Ì60ÃÕõNöIïhH´Ýnüí ÷®H°¦R‡  �Žhi0wâ¾ P¤þ²%Û”s@ ëõúl/Š.›µ(pqç6þð¿(ÅlƒÑ•Ìf}Ô¾÷eÓ¸Dm‡“»~Jp[U²ëO2ìpú<`_„@6GÒïIã\¸A_lÖ(Ý‘X”A_2hTÜÕ4*vy‡ÎÁ>¸žÌ60»Uú"0¹1̶ÿ®éÿgÁÏ´í4p8 d€`âç‘�� �IDAT"0Óºu ˜�N8$¿ãéö@õǺ(P®Ÿ¦ëÐ2ÛLŸÅʲõØ*ÅâêTº‘&üUÈóÈ”‘I¶×tÁ"`'NGwSG Cü>郫cšßÞn‘–סîÜlK=ßg¶Á„଄™‡€»€Ó˜ÁÑŒ€d¦€l›;p4‹#§%¬[]|Àìu3B–2ˆ‡b ¤bÕ€"px(¶†@9@詌Ȁ Tòm¥^[­X»3BaΉ*Ý´DÉwW» îD”_^‰ 3À±M³æ€ïù°CØÛjº,¨¼õž4Û©JÝ$+®IÂþ•jöPÇÝõ"›ì»Cè¨tgñ¥€ôdˆL[0n z|2� ‚Ò$B“6ã–×/‡@„Œ‡"˜µ«\C³m Èæ,D Ç„?X!jU€¢Y*�ÖÍÃZŽs æ&@—»h=$@È µ”PÜÒ­™nz“X(ÖÕ5;$´Öoè/º®†Ü–•ˆ!:-UHH6@í“e¨¯9½%'uÙÉ$€V� à7ÍÓéæ?z~Ö¢ Э?U€ú][ q  æÐ꺽‘` è¯5÷ßÅ”mbÎÝðä’¡uìâvƵýž¡};„ù Œ[ F4³e y›n–L‰ÅS:™fÁ× §œ.!i’h@”ƒà¼U[z›´¬B ¤È<æëˆL88j«€»‡&íŠÏ�R c ãÀ `ZÂý<œ�9‹tÄ BÀá×6FHˆ»}’Z‹Ú\“Í3GÚº:¾nuÖ C ç·ïR©<D‚&àQH¯¥µ=1Ûô·Y—q-ÝÀ:Œ.ú¨T�M` ¸ÚO™o Úp›Caþ¦Ü×+[v.[w£´5±×(sg7}=Çdh†aÀøÒ–&ômkº½ŸÊüÆMâ´?³Õp) ÖP§à¥m-1˜Bc‚ãN›CBÕ:&0¥ú€—…³Ï§LÔÊ“I”[E&U/Ì�öÑW$uU󊆨]—#±°X –骱mø­­äÖfá„à 5‰J3ÈÆÐLèU¢w©IdjQžÆÔÅ0_]ÛBD<ð­Šp@Â*`$EqiÎmsM„"¢¹VL# (@Ü1­³�‰v£âØ<š%PÄ­HÚ �eà" ‡p(:mJ§eCç×ÓKZFO#ˆ)Ü­{E PL0WõÖ•S÷°¾°±«r“Ž3 (ífšÜ~ÖÛìµWs¿´pO|¿ÞD¡ß³^…掑+Ì60F×´ºi+œ’t.NÊXgá�Í9`Ȭ4!òkzñÆ&9ú`’É ×XÖä°~ÞÊž:ZžPÅ̼¤®f"Ý—µ%ÁB˵kjÊ„™:’Ÿ¨©',Ió&#A þR@4c6ò© EqdNvèô5 B�ð@ yjˆ¼˜Ÿ×xˆ)  ÅÐb'2ÁY¸˜#´Úx}Å_ —D<Uj 5s}ëàr$‰hk›¼Úh N“N7q£~´6’Ç hy!¶DÓ5Í[$À˜@ÔR¾-9-7#k ÌÂÕQuAg€Š›ßR¶n{­4Šæf|ê�ËšˆŸCLu@�饎£öÆ¥íŽB¼KMÁÏ£ëA¶ÍtKt#8$Á6!º‡¼—¨Î?"K¸¡CÂÝeÎlãÐ#B)€_ï­ùr ˜°Ž¨<ò•`Q¥àÂ?É…ã9ê—°’ I)³�P" 76˜‹ îŽ$â<–$ÓY5ŸŸQÇŽ *{å ©‹Ëó9 a\ÇäµqE*,[)kÑ\E²Ò¢MøÂ‚Y®K¡” î SÇæ'*˜×P¤ç8d3HÎã…{EL¦­tö„Ê“ù 4^â7ã9¶¥ PrÚøØ*Æë—•|äNçžofðœJe ŽD?§y%¬•½ç�šL`˜®c(�Ï€¶”žx�T@ Ìq ˆ«ª�0hÀ"ˆ#Ðu½œÊy,¦à$Wq6ŒÁ&]PëªDâ9ø”ŒNÛ�p7^K–€¸çT}ó,Õt †/Ã…5m®�^/í&�ÑÚv£µ…“xjT �@©n»ßcägåºJàˆPSbŒò9Ä2‚`C¦ëQ °11C ÷ ‘‰ ƒØ‡da±8ªX}˜uÌ`=&ÓêÜ’²Š& ‚¡’)’ÖƒPu2I’ 3–™â²q5 ±·¸™®"Êž@4 ÑŒ ÑóÊ«æ…Y>œÈ›6QãI#.””€ÈÜ’ˆeÌ.9¨rÐUXx÷"´O›å™8zRÐÇà%w8ŽÇ¹Šp)n–‹e¤ã1ÙÏ‚¥{†Äq iJœ'3bVŽ9Ηd1Uèº6Ãų*ˆ*�!™°ê8\XÍÚÓ�m`ŽÕЀeÀÀi Åf´akç$Ðh€DjqÕhb™vL¨û)—#ä¶,H´ü•:õŸ´õµh÷ÆÍkJSi-*¨­P h•µ©×'Šèì FÔZWÙØsëFÅï=AÖ}Åz}ƒª»]Tç bYû³ ŒÃ‹#ù-M2‹ À�.µÅ¢ÉjÍ ‚œŒ¦ØÀ¢‹šŒr0y;Šíf+© &ÈS¸NB¤DD‚îNeôtÀ)©01¢ªYGèÐfÔpy·"IÉ„,rÞ…’» ª+šlH(KiN3šÙb1+:¢¬‹±.|…¬p\ÕÌšgL.Ÿ“.6=›ç„hrà³Ð !›U i9ѨÝòe9i†i¬”ÅZQæïàL# ª!7!$™3 (E±¬J—–‚lS]äxè5\…L¼bö2:މäàuÜÁ7Ò/Ä À§ Ð�x@Æ:`�EiÓ;nP ˆæt…VÖ÷Å�0Pf!�:PÞ¢£"$€Ý6ƒÚ›ÿ›HˆHš“*À ‹.lˆ�ºfÇ�Tûüàí¬WÙ[Jr‘Ïà�àµ=. +–ÅlãV2  Ð�"úDº¾O¾}j–AÉWWêßÄØ%eÔg€YàBuã ÀY³P�ˆÎÁ–¡^B2† �9ø€­4_ÉÍQ‚âªU¬ògª±{5Åñ³å0çIJ¹ÈWi]®êñ„\É &²+Ëjfúh&ÉÈr!ÊQoÌåi…»dúµ6ÕÄ%[3ã¿6Ÿ«•àˆ‰œ—2yÃ’I#Œ}å yÑ3æ'5ÑÂHp0 Ñpu˯Ë$R’&/ŒK™±XÓŠ…o‡µÅ´”¤V R|Á¡’£q.FÉö(.Pp–âÎQ¾Ne%" B᯽bà{à–!c€¢°ºI×<˜À²õWÏ[*=¦b<¹E"(cSKñ)[q‘¦æ¹‰Ìvj*:Uôøxû¤Û»oí÷�·åßPØ­ [mú›o›(7ö_»µÐﲟY€3Øáz¤.$ú}³Öäw_¡!ìËÑ@Ì60Ø09LÒ´…£Öpl}â§5Æ-“¡eÿµ§ ,B³5áBT†ˆÂð“µJ… #ôOØ^Éõ+Mª,¥IziQ©Yo,W㘊‰å¨^¸$ˆjÚ?* amõjuÜ®ŠãrúÅ®èÚsØÕÉé”üB*@žŸÌT§W£bpÏñ¦EóÓ¬‹Fª˜t^ V›æ*0R͘ʤU1Nà$bÒØòÜT\T2'‰£6”�&‡¼éóIìbÃP ¨iAJËÉåcZ/ŽÃ­VÔK¡’“ý“©ÚÑHZå1ï®^EU†”@œ@hÂR_–IP£^K–c€†HA¹‚*©Þ=‚…žª"›Ç4`$ó6ÿ™<ïæu:©‚KCÈŸÊr™’­6â¹Õ&üðq“bÌ*ÐX{½l ©AÒ n+êÕ[C-´âWþ¦ýL-u¼¡ZuÙP™G1Á@¹]í4lû‚Ä:µÎ.ºÕýX§ÝúMîúK/‡ÈþœÇlã@…ŽÐª‡Bž„€&°} Ð�Q”æR kʨù:ˆ\úk¡Œ…k€@1>•b™€N CX0è¼LQpg‰Ì›Ói!«i)¯æ¸ã“Á¤ ®D*ׯ\»ªº ít5PYÜù¥�TÏiY%Ž0/Xð §îÙ®¨'®ÈñFXÓbÎ?bi©4ó)¡lÁP³5ï­B–šZ!ef22QIùvÈq‘®‡ü±JgËyIŠ8ZüºSˇša%‰'UR†“†%s&"U‘T¼V§M¾ÃçpüXP—B’\<âÏå¦ÅpCÊu4rS±:èÔ-!¬R&<‰šSˆ¯ªqüpdÎàh>²›È~kVÍ1NhÄ®S=åFר•QÄ8È[nvL˦83«*Né¨Q›¿p‰‚Î�µÙP`r aÍi¸aDÌ…ëûÊ æ�z ¸Òw&»Uƒu(ý8"�UÐdÝö´ßSÊÛ}†pèl¶„w¤õ×·ciGNÍØ³ ŒÃ2 '6<޶ó†ð+´µ%"Àf@Çp2*òdŒlþt]]FÆF)| Ѐ,¨ˆ `PbLI¶)•C‰‹5UÎOf>&^È[1iTôhn‰~™·Íb­Îc×AÅ¥#Ržd=5Õu>L;²êIJÇIŠ@u± 7Ê@©[>Ï™pÅzS’-Nš2’*Ç<áEEN"K±ër¼%’<• h9θ,UWDgEÅ µ.,L¼#œ™Ž9^\­s%1´:$>Áj=®ê|óš·t‹ÏŒ¥r€¸D¨…Ñ”´±7¦ÎÎÆÆ¢F¹ž®5⸡\åçt‰Hññ)K×LTË•ª‘ 5↕ç³5Q/… 8pb/«2傦T…Z•mU€(¥$» 9E=X ”ׂX@œfRw„ÚDµiÚµ˜Âõr&?o»íK¦!è4À¶@—£94Ûñ~C·™¬X½W¿9'*¸Xõ[ýd‹q»¨â …{zmíjÆî;­À|OUÞÚ˜ñàêþà7#1ÛÀ8dW 3�Ö_rÒ¶Þ_q@ 0 TºŒyˆU¨|ym?È�z Râ×H!@m,´Ð� ¾ pÀr�ÛŒIdâÊœO(Ðä “*ˆj,®ð±š£¹IøZÞ§Ü‘7ÊÒjá¼8VNeU3—à«F(ñ’Ï*ŽsaÀ'jVl˜jCQòQÂQ*¡‘ä ¥#^ÑGâcAˆ8„8>”C ެ芟.Vu!‰r¸ÀEg¹Ìx33­ˆ„ƒ-¡ÝŒu5ŽDû5Éó²ÏGK˜¾Îû•0¡Õ ™RM;äÇ 3÷g­‚z6™Ÿ«Õb7‰¢E%œ¢ÍÔJ¤f»AÝ™ˆ GÇ}b‚èu’8zÙç*ÍdÞ]Ñ}—SBÞ°Vyb%Ù–åãf*w<jäœH°E›’K¶Pjº3: xÍÍéö¸ˆ+l~©ÓQâKW¾lØõu _�h„h pA”û µõ¸”»u¤I@�V ù‚ö®"Þ&k`wÚ†øÏQ`ðo|edg§×u¤É~¿@Â-ê¾ï¾¯]mFÒwù³ ŒCñg·ŸéÈ4QR€Hàˈ+mц™Ö×áLpЄ”fj˜ŸpéeN´—�¡õ] p/,ÅhÔ±Šðíž>J€,¶ð nsÎhR]€š£™\# ¾$X’š@žˆ,ŸX)nJSOš†0fD Õ&f(IFV ª”VM=Ò¼fÓV9]®e¢T¥D y¥ˆÕUAZi†+DVÏä¹(â-kpÕ€â*GA⊙ð.áB…WR R–¹@6·‘hÌ¯åš DÜ$‚Æ'GJ‰Ó¬ª“ž©û÷À»¦7õ´ øù¯`åS,e=’µBMçµDäÍ”"UÊ~ÅMlÅM¼:1’Òl3*ÏÚʹS>TK ¢''fcE¬^_ˆ«±ò¾£ëµ…xõJœBƒ6UUi“÷yúEÕCRw¬jÉ+ÕjUGG–ÒÈX½¬sȉ0|ÌB&|*«’¹±Ó‹ËÚÖ"°ØÖ%ÜÍoY·ÇvjÛù” kOm9¸"ÜüŠû&Ã@6vèH>Ðè"¿`ü½þw¶^0´·¨{0û²v>�›‡©2˜m¸M à þìàƒ§_Rrk†Ç¯ÀaÝNÌK'#{6(¡!�é Jg�£5”ÒˆX©‹¼£% I½ÙJùÕÖg ÒÄ“i½ÜoUÄ̸ À!P? ¥u` T&$O4KàĨPUCÌÓdœ “ãgPc܃–ŠÒ"—â3¦/Š!…Ë…‰–誢K’ã†&#èºÆ/E]"q˜ø+<_ W¨'Åœ)ˆfÛ>_¢…Hºƒ@ç§‹YÔå¨N¯¦fCU—›S Ï å à|©”æ9 rÆaX#ºÏ™c'7«Èç%®ê¹#*7¥º²Õt4®\—êͪô²¿ò$«œõVm!irfºy}Zš>Vs®øµÈ‹CÂý³±H Ó 25Et+Õgk5ѽ DÝqJº&aE¥†ìÊÚ<æý7yIOG¾"[K 1°!…©à8¹HçBˆ˜XÅ¢«Âº±<°6N¸£�ÀSÄ›® ½VY pà/´¾\"`¶Úöɶœ®C`OoG'7Lжïew8 Ì6ÜÚsüýÙŽ—“·OPì½;Pl¹óñu òÁd¨Ž{©Hø![[6‹ÏÅ|±Q²<H–$ø:ˆ[j$õ2¨ \nË=SCÊ”yÙ›«N’9¨T  “œ‰»2qBg_ªߣu‹„S'Șªqºãçš)ªÆ§*ÔÀ•Í|Ý7ŽO‹ ƒðÞÔ ^ ë^=–=_æAÌ%a%Ž«~LbÞä .¾PCŽD¼¦N4E©‘4bWÐñe]š1G#/„¾œ¸Fu1¦~$ÍW0ÃQÒU¾*žªŽÑÀmÇ“šAH)Â)ê¸HÆ>ö8EuL³iT’¤–®ME kMÏqjb¹çª_Ò¸PÅZ’³AÙü9…˜àµìJm6.éWŒ%Ó¿ZšæŠX4bÕj²zÑEé•1L¨GÒÞDU —ÝfýÊÊÌUS½Æ%Šî™¸äh¼ö=N fˆqø¡â—ê¼Ðh½¢à´NË´0uÚºóžÜæ(´¦Ü"E Û_séÕŸ}@n¥ß\;…ÁížC§‡qè¡2ÀUíÍþñᔖنќãÇí‘ÓatÁþÝ1³¾ç¼÷oûø2·vQëüÞ�ÀâQž|šS8bB"^?"5˰<MWCkj&%Mׯx‹ß0&"v)¿Ù0¬iÊ÷t‡6àhpkp%È€�8®k“©ÉÕúXæúœð®Js‘y®QU9’ða@㸬XÉ¼È ’Qƒ@±i\(6܆ïTÍ×Dô!8P›Ë²äfÄi¤6“¸ȱ j" xÙóÒ4q,ß•øZÒÔ¢Œ%¿‘­—µ²(i‰Gë$s«Ñ«ÍÚó"÷\¾ðAÈÕD•PNw¼Äo”Ù•³±mÈu?[+Ä0NâI[H5ãW÷ø(•$µâGZHA>/FuÑ•ë/Ȇ—¸ÒjZã´ÀŽ‚êŠWoViõÄC Åcš‘nZà’©—•íhÑCªég Øè*­hÉBL‘ñÉŠôPÒøJ´HUÔë-ÍL¤èDcåâ’þJ5ôà´â6€¥@Ö‘åñ\sÍB¢õ}¨7® ÑúÇ3@Q_s¤AËî˜.í·i²µ;è…öÞ\ë0Ø2dÚëz¾uºåKsƒ©Ý!¼F°­¢oÿ¸ú€;n.Øp>èÄlè±ñA¡ÌÚgíwníÃÍ5zu>Pnø>mËâ#DˆÖö ­ ÓwMç§«ñx³D9§jp|ªsqc1/$CN'y~9öó!¬(`ieËÇ¿hÖ"§GˆÐ�­ãb4ƒÌJꎺhÀæBMª¨–<U”Å SY*_ÂTMÎÄCM5%?‰ªËÉbP«,ˆ¯žJ” !¥…h\ñ~•‹“P²±$%Õº[«ñ‰…+ç ’.—¥¤!xbœxADÃp<4*e}±dÄéPFƒ[Œä ÉËÞdSòLSHš.u][ ̹2O1¥ÕE$‰¡s“±@¼pµ”œ¨j#W|¶\"’©‘¬šð9ÑÐêžHE%oÆ\¶!ð4åT•¦›c2„ˆ×¬™ësY|®fÃļ…y�u MùÁŠ`‘«¸5^\^»$.›ª/(/$’D¥ÃÌkc/ÖéstÖF@`ÑZ͆¤ŠÓ²eŠÊ*ä¥@@ a}í#¯"4B�M çùpÞ�"B³0Î!ïƒKÚµI!Öúí‹Ýb‹Ö»å€(l˜€Øp Â"ܵ§D ÚúrÝð*::Ìæ§<W¥I¼¹ ­S&|º›Y9¿wÛ0ÈŠtuýÛìt°‰ÝÚ7z÷àg°ï°Þ4l::f§„ƒvÁþ)à. f·ø$€ 4€2°ºö½µhí*/ Ê)£ ‘xÍñ2iHùe4ëõÅ §9E›t=Ôxä8ŒkhÆpÇq…f¤9uéš‘Š€94]ÐkȰ'AÏ¢i›Êw…q]•᨞’òˆ˜R\^}-I#vLÉ3#= ”ªšÏÅܲÕ(]X¶C~Yö0áéú5Ï\eΧnõª F0eÊ©^¬‡/‚‡ã‡Í†çÇ1„ÀPD7‘o²æÆbÐh¥ÎÕ1IyA$›Q,eIpU/æ-1”†EÒ®¬ß/CN¤\DÕjÖª±·ÚÍyÁ/ø×¹àKWÕäSDµ„ØJÄläÅ<Çe.ljžÚ0TÎà“ OTä|Ù¸$UÄâ¥Ü,1A)MC§—õ¹ ·îJ´êä4ÉZVä«*/‰h Õ)ÇSç̨FDӺ΃�Ú2%¨xÒÏå.CYnÄé•«Ö¼»ZjY⃺àB! BG’§H­½s@T8\¨·wNqíÝè°²uJ±éX šÁ@m�ñšoœd€¶ÞƒkŸÑçFà¶¾VVêÚO“@ýÆÆÓ , R‚R…v(ÞÍ/Óíd¤CÝt€áßÜrî[÷§¸.+=Cû ³ £ì@ìeAbÑÉ,ªÀÒ–HîúFޱõÿ¹Es_Çœ¯â·`Ãu‡;!L¼)ÏÛÂü2€™ ÆÅÀãÂÕ(ˆñ®© ²hç\Ë0'³z1'Ô#jxi‘'ʼV‚-åh"ÌËEs“˜5@DŸŠ—’eY4sSÔÌ D×BÞŽSWДؓ—9Ý«i…´$ÈœÔçDå5¤µã "«æbÔ”ù:á.ëô8ߌºñj Žç(±bÎr=ð•$´y¥Â P#¹žpŽÃsár,JÚr.9bJ²ˆœÏ…‰çÓe·. 1ˆJâD5¥lˆ2Ç ^] ¼x%rÓTʼßðþe­ EO«P•ù0È5c’¸AâTäª"šÔŒ#"D"§q|J“ù1U=§§òdjà=õ —·k2ÆCÛ,eÆ0KØYHŠ>OÅBÈ{üÅ GÕï’aS¯L¤P¾jVNšJšwI–&K)[É®Ð\ ×%Åâ/#rj5‘ €\º± ‡nšŒ4ʆêì Š¶½P sýãNaë=éxmq!ÞX¦ÚH9âîqê¶ZV�d vãqn §ÛË›JH½þgxJ€º£…f²çMtÀ0TÒ}¤ïâeröÖQ_i ƒÝVÜeÀtÓŒ£kïÙHªå`–; Cëó™-/!"0) ŠØƒC[qÖ€8O<^A² ÄUõU5Gˆ9E¼@íãÊ›æOK±,™ÄUˆÔã(ÕÐ5"Xªk*8£ëcGR£E£Á¸(Æ+r‚ŒG24¶µ•šyçt‘¤f8=ËéOÜ)IÊ©©0Û$þ¶‘)d˜­6k_‚¬=XM‘8¢R¤ÅÔmú˨ú"¦céÁ3C/lNcµQiVãò±9GÕS‰(¦›<šÔ’ÄVC¢À8G‹So¹Hx>Rì˜MÔ£Ä{5‰+æ3jT©ó"üh*” jh5jVÔdL­—dZòÜ¥(›q•ÓQAã>®Éã¨ڢ녚îK†,U}CwÕ%jFt])æõqLH•£Áµâ½³/ÿyä¿æ˜÷ˆGNùŒš}1”+vU ™*b¸å…YÍu%<ÇC%êëòêCš0ïrÏjM8׳^u¦Ae'cgSŠÉñF9é\­oãÜ**€ŒÈ_û Rc³VE†`…Þ8 ¯gPôF �»¥î×L£OdÐ×Ï•Ûn¢Ýꮳ7®¹8µY­N¦žvî³vä1ìèl¢a…¡úÚ¿ÝÂlÃè†{ íqfÓÞ{Ï ¬'Uéò™°€°å×”N ¾C…8!Ö AQæT‚9C§i¢¢P×øTD&A­y ¤¬ ©±ÓzTŒÈ“M*Åá¸c„¥H©7"?Ìð2U&},áéJÐ ¸^.ö�� �IDAT~2ëEU65±|Pì æÏî‘\6oZÇóç{×1È)HDPÂùï)q¢ä«—cÞ•ã³Z0u¿]…_7œm6T.{R22¯ˆQL%ö&ÒœÛ\â ᫲šæUÅr «Új…KêŸø1G¡`5D®Ñ­èÄT}]ä’Pœå£gdîn=�ßLP=X‰ E+PÏHa"’¿Y÷Qã܆Ñ(=Œ4Ø"Ijn”T © YQù—LqB”"!iSÏi™œÇ ¹ñ;̉#¯]zΧ4)¢Zèhq¼b”y’&W#ÙT!øÐTG&Uõ¸l§Ã§kAõ…Ù…ÉZ-«-Z“™¼¢iœáù|Ö¹ú2–eÐ<h=r©d#(Á²ˆD`Š€§(!C!%+J1qçànš£H@F¶ß¶×v+耺Ñ?›ëFaÀ‰mµûìg�PiÛ 1»»A碿sìÈ�·û�Ò�gu¿ô] >˜m/îp*ÑõÁ½l~Ž®ŒKY ÜõˆÇÖyÇkgQ¶>Y12•…L6"à!¿ DÔKŸNÌ|(E¥EU‰\Åq\‚wôÄTÓ¸_3'äD_R9ÙQ%=Œl#|§7"‚ ]Ñ\[Œ(-Ã…G…Œ—KRë†-¥œðÊ„"¥ÃÑ•¢rm5,óü¢æåy®Âûs|™ŠüW쩱inIÇI ¹UQ(EÊÒ<'#‘æÁIÓHID%æ‚P¤Iœ BCIê5‹rbD¢ÖX >,ÇW£+Jü| £Ÿ&ºf%š*ø B;5ê6}Í— Ïù4ª®6–æS*ÇiVh9¦º`ÖóŠ®è*õ§‚ˆ±Bð}W›¿Ü\©i «rèrH^ÃmH¯ù†Zãâe{>à!H|ÌKb H!1yK5ÔPUš„óÍY¹Â;‘§9>o¹~¬ðÔŒ/h59g]XÁçÀ™Ðs’2e™)%FNƒFê˜å¡ñ¼t‡.M3•rÔ rUN[¼zÜ5~sâ[Í‘ƒÕVde’À,™ã(Íp=š„sX霣dxZÈ£YFàRS2N'h8°€k[Ê@BP*Û~öˆ�EhspèzG-"PÜÍŸc �0(s:ß´ÿ*ÝóSzROûA­mBPtÏγ ·——Ð¥[ öÎ<íç,lÕº¢w© æ2€U}Ë'l$+PHÀéÍ„ùŽÓ\  C Q” ëž+ð|Î(‡ã‚åë@p‰p°ÿöÞ´I’ìº;o÷=Ö\+»ºº@ƒ @AŽQ3™4f’™>é¿êhÄù0 e3Ñ&°tuuuV®‘á¾û[õ!3«2«²ª«±‘FÁ?eFz<‹|ïÜ{Ͻ÷Üð45©c4'½õux¶Dô*3N°á›µ•Nƒ³’yöYµó„tQÓnº:ÚGÜÎBÓ W‰™&zÊN)¡éR^ÒÀÃÈ4É@å²õ»¿ªšõf£®´÷1 R¨'‰}>Î (Šh."ψU*YR=IƬoº4¡#§Ç¡£p½NZp;tíËÈ*mÒ]GNÑDŒÝî¦W¦ÅXéLxïm—ÛÛúïÕtÖµ±?lÚüʯ \ÒŒÄÚ;üé)CŠÍÖ1¬DÄä÷_Däiš•Ÿn"Eè4òc?Vþ ƒ_Sºt€ê¤ J„Y&¦,Vç4êÉèÍ_|1ì~™4}h0 h âÉ!›|²LÇ4ÕŽ=píT;ÃUüh;=8äÅ\XIÕ|©v¿a9˜éÁiÐû—ýNÝš/nd.LªŽqž„ñð¨Ÿ=¿Ì n¼{ ”tF0(4 B(åƒè ýp³™gÀÄ‚">ÆL߀P0àÙ»íNßF×3ÜÖ÷ã†ïâ‡%· í¯ ¢ð®ÄFüNÛp}F„TùaÈkßã&€üGVxý£møG¹>4JÐßmÍ÷¿>”¨`Gp׆ÄÍàs„k‚ëñ\«öö\Ý”¨Ê|< 8æÐÛ@÷Ìüü\ÈjðÕ*¿ú¸-Ë—³fGÍóöã©OYµŸË5<ß25™¶kYߎ¬Wèt·ä&ž¹ø©"ué=fnm䇙ÝÌ:v0ð½Å2~¬G3”ê’ƒFˆªŒ':hQÉÆü έ©¸˜Æ(zI~0í÷~tyþ<ËK%x"fb“íX•#¦,¦ÂØ(ë“dÂT¬r+ZÑÈM¥\¾í¶v³oD¬ûvÂýbóhõr²l¦ß[&ÍGj3õ»Kçi‘¯c¸]Âf¡Ð4¤]‚ÐÒw»4Þ!3ÇÍiw®�^ÇõKfKÈ8YL,ŠÞ9O´l®ü>Ÿôyò¯#ÆŠ­³ƒíØŽ£Ü8a' 4°cÈhüÚ…µEMÊG å¸ö/‡íÈDŠ(ÊäÞ J+nšñlÜ÷s"–Ií²á|„ÚB·Ó%—Í÷ÕÁ9™i¾€Obî|¥^ò±)U³% G`:…UWè<ð¤‚4pò 0x¨á…œZ „ç� |a�Q ¤¯7ám3M¯Q#@¯‡6Hé»…”7Í@$g¸n…ùðÖ)p^ Ç>Pé´�P=8Fèô)ºÕÛ7S@Áöýé­Ë¾ÿ¬w¿d·´ ÿÔ¯‡ÿ‚}s»€þ�4B ”à Ïûö#Þ1Cœj¤(Äé¤áFÛ5>s¸`(c€@üh2÷ù�DÐ Çš‘„¨|» t A`G‹´þH_Ÿ¢/”ÂíäJ­"þ$ ã`" Mâºí¥m\Ôƒ9û2}ìöhÍǸRJ¤Zø«Úl[ž`êEÒïÄ«?%ó|ëJìr§y¿áÏ£ôHé,0r5eMÆ'ý(4-(ߣªöVÍú®zãи1Õ…̹ˆ1k»Xû—ò£ÔE¹!ž¡uÝ 6†oƒý´©ÿvhË«yKèÖV½¿d×çËYþÉ~C™¤–ГÆT1µ/EGÜ4³¹–4‰j”å4N§Ì Ò$öe¿žÚlÆmt¢ùÓÀcËŠgÛ¨‹·Û$|<SFã9ÛÌTñÐÐ~ ë3æyNü—¿¨Üå¶jź¼²0öe{õù0îêݽ"™Pöâ}Õôź)Ÿ©.)Ms“Ž÷Õkf\YOciž'>¹œÏS1ZSf1ØŒ¤Yè=kÇðõ®[›36·‹ü\yr1âª8 ™GÀ?½ÂNÀ0³y�~ ”§�ð…Ôë’†û›ð›×Np”…c²¯»³P ×yÛ:À� úº"îºø5<DõÜÁqmqÞ{Ü.�ù ‰úvŠîÎ$óv¿ÿ”¾«]ôTðw3o.2úßNé¶á÷µ n²_o‘# DR¾UCrŸ-½®8Ša§϶yŽ<Bfq5b«p$.]à—º"è0Ó.‘%4lˆŒ”Û•åÏ™† õÿ¹$çaÔûª7F«h3Æ3o#ÒÊz°6²flé›>3æc°ºh}¢ZÿQ×l¶Jö/Dq ¢_>¶³Eö¸°G.)„{ä“çÓâ×óéñ,]tzˈf÷®±[q¯(ÄÆð‘øã3s&ãŽ2”Q½t“”dB¸gåký˜Œ~¹Áœi6Õ#íjœÅh²Î|FÈÏ{¦µX¥Xæ-¢ËÇñ4¼å‚ìw|aE®öˆ,¢„…¥‰ ÄeÔH}N0õÞæâh²ÃU7©¬_ùöjÂìR©,/bæEHç2°*G.ÒHJ:hÏ,cm9ú­Ž»nÂ¥ÈÆÝxýÌ uGÖ4ÿÙ`.}H,;¡ö×eu6¤L±³KMeÅûuþ(VÃ$œØ¾ÜÅEê¸öÁ!kuÔÔŒh’¨0›“1Ò8Öb-dºžúT ‘—Tñìp§üåj¿úªÎ_')DJӓݪGLz<ž4JÖ_kúk™ƒH4#Vç—â3x~±Çû·€NÞÎ|¥8ÖRW‹×¯]×P¿ÊQ\÷ß!֯ν·ì ,_†}€ÝV/…ÐG¿ó¡|@„•µß*,È^·‹¾¦È~ûLÃÛJøÄ.ßµ°õ¶á÷ša~à*Þ2õ;Ë>mîÙ�LЕïJ ÝóoztqÙÙS IÕk(ƒ}‚° ÁŒXœàVnP f*Œ±Îƒ^l¡¡%Ž52H‚£€R«sªÚ¥ÞÒ—•_k~± ¦’MhFþT—/ša\½ Á¯+lÔ“g$ú·ÆOW¼Øžš½ÝqœogAä'µÚ!nʼÎu£ÂdÆEÆ®6ÁÕÝKh¶ý­_êã Õ^P«~ò«—ûõsþÓÉ/uÑOŸqGj§ÑÔåÃy>|–3So“˜n‡±‹³ "–è—|HK?~š–L]fýËQ¤u<ý&êȨ±H_d»º7+üAÄÒº †H× dGÞ?K%z<'Zñ,ýW¥ÙȪòW“„>YÌ÷¢(Fº5ýh{K=¦Bç!ZšÓ½Oµ–~p£m%½,èÔž¶&áÃLœyñØ…ðßBÿ’†¹cÝb=˜3÷ìI’–ï‹4Â,g.Ûw }…xE2凫mâ[÷ÈH>:’0SéÖ'r4S>$}™¸©o<F·åmEŒ4]ÈIáæ¹Îð¥PM0ºâIÏ1ï°ø !°äÒjú•.ÜÏÆÙç=’Êt3yÏ%î‡ÂÛ‡vï 8¿ùõ�à�½GIÐ#˜×0z·HÕÌI g7X_ÑïƒoñïŒÂãÛ‹w ¾€¼z1| ½ü¦VÇÛ q_µðWòÝÔ?Ú†ßÖÜ3ûí.�önŽÀýûó7%Š__ê›×ÌÕõg»Ûy/ trà ?tÕ€†èJ|…X#J°,1É05±¼~çT;øB^©N_±(‡ ÷€ÓÝòc 5º—:‡1¹c®¡­Þ¡h‰ª7iy=ÙÉØŒHá‚™Ò»BÖæ×/«‹¬ ‰¼ú ŠŒK6/ª¤ÛíVfr/pârÕüØ— !ýf¡JÚ®È3áb2|DBÌÄ_NsÂ&~^«ÄJa´ÝÓ«ãôi©RÃÓÄî —wcšÅŸ¶Œ%OŸ¶¦À&á›l~¢£9‰ ±Rq>Égl ^É·KÙ�©¾¨¢¨ß²žMï•ߟóÉ'‰@ƒ0B?ÃeAðHÊÝXÓzýOÐc7c¶ÎNgõ"VíØé­±>ç† Õ9çܶ'«À÷:ˆ±?kÎ=¢º yu1ëìØÒᜯÉÈ—ºžá²oJw;ûi¶nÈÆjp›ÌµŠïZ¦ 3"ð>ÛDd’v ¿GpZ7œ9u5D<Si<Àt}k;C¿ÚÖ¶)iä|b¢(ÐŒÑxaçcíÈò+Sþ;ãú �!Fr:+y£‡Ýª=¥µ;F 5Höð åW0—ÜŸÍðJÛÚßx0§¯â†»ÏìN?|¼æsqc†‡Î¾'íü›d ï¥È='].qÔḽgô­îÓ›ëˆ÷ÐQw ›ÁÍÞYÚ½;~sþâ¶á73 ¯1ýÛúïß4òå;î-– íÛÕoˆå]9£‡O]ûÆg»í¼O$²Ÿ„ÕØúÏï~$<No7Ô¬•³Ç(42€�­†>©±l@n?“\s½ÙÁ\`þ¾è3öñ#¹ó0Ø;ʉÈËcý ¶À>Å“L'¬m]-™:¶“†él´«è“ñ4ûbáÓêIúT´IdÔ¹g©uÙæ)CN±ùÏ­3aµp[’þŸTa+¦ÄÿEÓíÔ*ÚÒÅ ÅÖ#Jgåèk›IjÏ;>Dç¬,"žÉ¢Þü(r6Ky±cYæóXd†ƒó1áEP¢ÄfüW3éŽÛAk{R£h9–»ùV¬‡,Äš¨ÇƒŒG{9´ÛmE‰Ÿ…žŽå¦mâ`BöIâ•ú>þµi«å4¨´íè–×+vÙ%"øh*a}„ñŸª6’]Ù~%7u,™šÏÍiYïb5™Ìû8?‘ÕZ z¼”Ã8Ÿ,'Ñ÷±>¯,ÙR³d‡†'uµíóh$ŠP›òliÆË^Ì7}¾Éf2Î2Åè`±æs—ÙU±]ã„h?»éÊÅÂûù$“Û‹¤ÀºY'¦¬Ó†ýåöqÔ$º†ÝZ.6xöÝß ø9êå+<K€ë)Ô)°\¸i}³?7oz'�€%�È4î†ÏÇjˆwP%[€J#Þé–Ù)ˆþ`_ý&4S¸÷³fw௤‡KE>´ÂM€é­2&î%¿ãú×?Ú†ßÌ_xWp ßOJ¾ç~ãqú`'§– ÷ñwü¯àî´»ŸM�Ó ¯_‰�‚r0À‹RX“ë7`¸Õ ÀXŒ3œÏ0+1+í±[Q7dbë§Õ&éZ <—húYT¶¶Ñ`(sìÆù¢Ø‘LœQü}ÛG,+ižnÒ< }j~Ý|³v›0b¾Â<†Ô‘­ä7š¼˜ú“¾gpŒâ©_:)kË+,Ea)æ‚FûM§œ õÕfè)E ‰QY˜È6ü¤Ö‘îávz5ÑÇYÑ…‰7Ù,gZ1£8=…uã8Q®H�–Ÿ‰20"‚ÝV‡ðEB%…61ÊïcÖ8k¿ØÈ?‰äÁ:ms’Ë1ŒÛåE&:l]4-©×0•ØæËdOÅ¢1QÌŽv誜:äSQ—GçRY©×I ›X·Á7*V9+ȘFœ¶Irähµ.¾ö—å– ™ËhA˜zédÛ/ðL”.ÂVc¢ i3rÒÕ Jžøp²6ѶÏ[û_*úã…M'Ê.h•Ž…ó¹E'“ĦÍdÂ3áûØ+Nƾ‰‡FŸçÎ Á÷ã´¯]Î"yJf:ý 5„°*±ùšT¢ŠæšÈUéÇž)€÷àç�V×Ûž@_Sì« ¨»ÀŽ ì6×β´ƑÅ1°‰1s˜”÷´âåµ üÀ€~‹]`¼O¦+€Ý¥Äå{Ïš–¡û0ô¤@ô›Ø†7®³ûŸäC¤oñJã[ëÃ…–¿3ïýGÛð; 'ßMe~øVxoWä[­› w=éý¾Øý{¢Ã­¯•öH%Ìøy㥹^aWãÂr{Ǧt� —i­7CåQeÅ}<IS^·.]Vtd Ñ£Nw5SX»|Uͤoðñs½oaè¡<…‘‰ËMQSª DòßÍHÉÐI{.‡òÔ³ÉAøiÉŠëÊóŠênNXùYlž¨Ý¶9|fæ…,WBç–¸x~@¦‹dj,'.øAœJ½I.˜Íz/§NOœêzÚÕp„ù9³á¨×S4t[}â bcº$slå±HYG2¢ùÅ!Q†}ãÙk…„èå>Æâ³ù'T_º‹gfUr<¢$OÞçŽz_ñ¢‹É6÷Ìú‚z&ü¨pp¨vT!EâñÊ…>'yÊã+R`ÆxèŒ÷T"šuc¿ªÁ¦û|N¼êYÍI&â`Ÿ…äTM±oÐpù/KÆ£Ž4Z{ø)* ½~Nú#2¡!L׿të•ÓjHð·ÜK>Oº"7Ý£©y{ÒÓV³=ŸÐ"ƒ®rÍD%S•{uH£ª£› œáG| U»¡öóRGcJED¬ŸDó_±é•BçWYº¹bUаN�?{µíùm…j·‡Š#Òð›c _Ï -€GŽ,$p!Ò÷´â¯S¬½Åö¥½ 0äý‚ŸáÊ»÷+oKtœòõïOÚþ–9Bý&É&ß3Åèí÷~ù.müß,…þGÛðû¼îŒ$ì! `lÞ·ßîþÃhOÐwCÎkáìëz¹rûæ– ×?'sã°ðØõ¯„ùu öãìøVáàŽ1“GŽ}¦eŠËI ±ÛÛ±J3${¢D]rŠsQœCôHuÎEÑÇá,Yc à%Ðc,©)z_J+Õc¡ÚY®]è6îÌ—}Ð[ùMÙ`Šö©ÙIù’lE6ë á_Œð§Oó«?‰Ó==ÝL¾è“¾ú¨?™]FÅ~&rCâüºÓ¶« ©£‰ÏØ´ãÇ%©ŒQ±YÉŽ¦Ë¯xg%mþ\ŒÓ8ËøÍ$ Åû<÷™™LœŸÉH|jŒƒ–ùü¸û/;ÑîŒ,ÿ¥ŒæèŠãéÿÛÉ>4[ofZ+–QÃ'ªŸ…â<Ä)M9‰ÚH‹ ™-iæ/ý¦Ì’…'ñ,WŒUéHR'dCF=6® Á ’$Éþè|%öIïŒpšBŠXŽ)j€®t/u Lák¬‡ÞæœD3ºvdÓ'¨mtÚïfMR´cÜ7Gí6ɲyYsÔâbC¿ê’«J?Ž‹,áU´¬ZÕ,m&]A¨t'KÜI`ÿ9÷ÿ[nÓ¡ÕkóK;ÿ‚¿ ikÈ’‰Çi’<±>]ÄÇ»Ÿ¿jÃD"Pm®7ášfk”¨Î…¦ÂKH l{SLt l¦ôpu³™ b€Ú[¦‚$ɧ讇ÆþÐw0ì^“6¹Wºúöê]&ál½“*øîfÃ=<”èÝvHÿÖ–éøŸwÜð’÷Á˜ÞŽ.ò×›êÇ€ºÖ+=ì·TéÇý·„V7┳fˆË*-ǧ�‹ó{„{úøÛí#|‰DÎÃ2LfXÄh ²+óZøà¶亵µÂq ½ˆÑIÔƒµ¥åÀòhʳ +ÌX†:à) ‘«“q\é1ÔgYºšsÍ%œ†”˜*Ôü<õ§Œ÷ÙÒZá@¢µÜèÙ7_ŽLëø¦'„ÏÄÀ£Úá™N6O<äóemº M»ùÅ©xòöÉ¡XÏ0¤ãÀ¶Ñ·&°a3¶aZ*RÆs$ÑBaÁüÂi=õ´f[º÷©L¨ ó_²!½ ³£ø Ù͆)¯#&+ ÂÉI‹ ,ÖÂóƒb˜¨‚ ù·ag‹I"¦®²²üü\ú¾ƒˆIbœŒ¹PÒ‰™}b\Dl¦VrÆT4Í·©¿õ¯ÆÍÿB#'¥ñªeÔxª"”¯ÚÈP3Zµì£¥“#wÖ2£%¹ ªQÅid·Œ7ÄbÕÊU¦§q�éÀ£Ÿ>?4)+b:Ílbþ¦7‹Æ”ziGCøi”ýj 3Y2ßs«£zçǶXn³Ó„žFl'Œt «Æ-;™ôjœ$"ñ±¢;{M’ÚõDìxá¶$_±œ©™fjFÿ ^°ÃD87ùšˆÿ[¨á¯h3G’ LQ­)@nŠÙž0WxþfeÒ�0„_êF¹K š�þF$ãºüº'趯#Ó¡ûøä6¡BK7{>Î(õz×$¼‰­ôƒ]òâ»Í ýýi¼9蟕møh|—GÜ ÂDÀ€³Ûd–¾> ¨¼Qny«žýë Áñ.ô0[€aÂ1剡=& Û°Žln{¨ÆA‰a‚«èzj#ÆOòZ÷ô9¶Jx9tZDˆ:­€9˜DRþúüiè5RQA-¡(Êá§ñÞ®ô|3¸ÍlظZ6«…Á)­í+©Of&>¤ÿ{´dS³ù‹D>;p]ÒŸïÌöã\6Ьt³I±.©ÖéL¶­¾–Ø­Ô—éðEB‘3¹ˆb*Ϫ]Èñ߯×uÕ­ÊÏÁ¬ë¸`lw))Sû+uá£Ùéž%çˆ7äaþç;Ó6oÄì 2îØ—$Äv‘ÕÎ]ÙÉ ¿¿;y¤&i^ø £„„ž†žÛ¥ÛäTºÓ$iG.½t¯¢:v‘Ö4o>=(?ët|€ƒ¾4¦wãã)Ýϼ2!I<ó6% ‹:¦©,ºÉÿ0bεÓüÔù­û!d”’ ÂYŒ|-âꙤë'"Ø„FQJŒ•*òqðm «Š¨gg?ÿ¨Ñ?qT#_<>\,˹4Ý`}⨻âcÇ:©Ôl¦?Ø4rqÚW< (âÉ„M?µôôÄ É ,‚l“´±Ä’™fe?(úÊÒ˜ç‹4ͬßS´cݧ~xÖ·rãÝ«cK ÝªRn»ÄPÍŸçoõ EyÍ&Uï mT D·}™â\¢¤¹J^‰d�í]ˆÏ8ÔÐÀWÀ§·™å{¸?y­áñþã,îp9û€¼M¿½U÷¡c¤×­÷ÊŠÈ+¶€iÐÔ™^=n =ýÛ ëI ©üóÍEëß¿(ÕýG°÷~§·„Ò P ³u?¹Âòù5À¯�P‰ÉVÇÀóï»-ºê†Õ…â—ÀòjŸ"ø\7gN-Ñ0T¯Äñ'šäåä L–³Ísßx±¼øôpüÒBŸÕ8¯ PäÇTêƒ !{ª-ÃŽÇ ÀæZe¯zdl:-þeŒž¥û­˜…htʳö³ýÞ¼˜zx9[M÷›}ò}w±'ø|wú‘âi¿g[ûÓÑÿW²ý÷r7Å"ëãÝÖÔ_™£ÊХēCõ˜Ù_4¥VxÞ&Ià%‡ÇÒÒXŒq•t6«×u ºtò ÂΆö½Yk/­'Ʀ®OeÿÚä‹í8Î3ý4r¼àë†Ur—Z·Ú5:Ùhøc—übvðgù~\¤3aR22ž(w1FFòóIôb‡,Úç]`Œí²Ð‘ñom÷Ø^NüY  7Ò”fbÌ–/\6}É¢h^zç¨/„w5GO'.)˜1[”„IÊBõ^z�� �IDAT¥b�)¬H3ÙN9Í é;ëÜ¥Ó‚ø–Æ”©*ÈXt4ö‰WSÁ§Æ4Ž}µNÒ‘ÍV˜Ñi>ÿñd7õ 3¶ì| }+ê’gƒï½ú<b31› ©ÐYÛv]‘ýHÑNAóa|>¶ÍËÎLXp¢†esò–dYÌ“x/Æ{Þ·ÜTÓ`}è\Ò|byÒ4'YïM”Mvö§þG³õfs¥?&I˜OmgãÓ˜v}¥qqÈ?ÿ[‹ò‹7 Šàp½‘«W ›1 °·Aü5˪ 9´¼9p·•9Tb~{²ÞÅÝÈÉ<l-ÂR(ˆ¦½OàvØ<ôª}»¬HfÐêÆ?æçw!þîG+ëoŸ}üAæäNÁ•@=¶ÿ<8¥ßÁ4Ôïðˆké¬û´` wÔV®ýˆ+‡Ë¼áiê›ç�`ôÝíûþBºšÍ†¬4ãÍ0Xžb. –üzêØ€‘ ?A4B~ÎcŒIIm‰¯g°¡»šO€# ¾‚ÓÔ]-²Ä‘ÊL—NQÔ®ZLcü8ÛùñQQ�:¬·úÒÝe~”Sr’æšd,$G—“½¿^ØO!©¡Ûh7ó<êšèr;¾¼ú”Ä_’‰7qâ;[míV—Aç¬4ô'™Xö“ÏäÓŸg|œ;§ Ç2ÔkÿIÓ](›C}ÞÖëX}8‘d'­¥ªŠo ƪSµ$./¢8‰Çx>¸¡¢™gA ¦Ý|M¢—a:îäG¾{æ$`Àtþg!’-ÓyN#* Á0z/g$P$"úÔh½ ]ׯ×Ñ0¡>êè‹m½.ÏÒ¶­4;ã�G=oªÄ9ÑOFGœ§ÁrLK¥Œ ‘ÔT¾ÒX8·#„æLŃˆ4 Ré„-¹Š|…Œ¤¦S”ø!4&,<R ¸´Ö@@Êã$ !y–¤éã‚®¤úa?%"„0ÔÖôeèV(?þ“¤?Sº'´}Éìá¡[dÁTçðõüâkµÉRµë ùyŠ ?qm˜7”}¡é¶ûëq'„hAç‘­W—qÙò²VJÊÉ,Œ)ofã2_Ïâ*Y?IÝB-ì`‡É§}×ê61)bŸò¯ÙæoX‡Í(—ú”=p ¬ ˜�£Ä&¹;!î¶ áê¾O–ôzjÐMY€OGŒŸ_ÃÖô)€4Ô1º×.Wø óþÚù{Õô xenWè^.½…$7YÄ7ÀúÄ—·îâ«QÕÇ€®~W.ï]�€ÿ݆ÿŸä¢å«ŠºHx|äÞž—ú^KôÆÿ¼®«»ùÓ¢‡¸šÇû«¤o/²/‘/Sù‰ãÙ0~õóÛÕN€¹†VopY{X¢Ñ«p)W^ßtÀX�›ÕuÍ÷ëb¼5P’¦»ãq·™—¥Äy‰:‰|ÿÂΞÐM!“ f´ŸÇÔÖŽÌ6‰¨Óv<°;³óìãO'ÉÇÉðÄë1d4ä›úª^r¼È›ˆÈ—“j•vñäôDO4ÏóAþ›Õ8ëÆe—ðVž,ŒO%t>DG5³9°½ŠNS ÓN‘èÈ?ÛƒÓy¡çE+ÔH×¶­Éæ<Uç¼X³ü©–b ‹vLd¨k”6v–ô‘l>™~4/BH‡óø¤b>þÄ'Q"8‰Y ·¨`,MöÆ<7ÑÌ(¹UÚòY'¬wgýèçk}t\q¥Õ]uìë¿ÌCoÉŸ5ÉîÆeËà«fO%Ëà3&¦4 ¨m¤m+—¾î¢tŒUÆÓÈ!h Rp!T6È88ƒÐ:ÅnïƒÍˆ¤­<õA*–& ²5COŽ‚Heú}eOÐ2§»Èyßl×´¢oýϳݙü“(úE£û¦†º‚‹EätOÔ8ÄU÷‹Åéß¹øÉHúzl]%¤ƒÀ…ÙIúh°Ü­[ɬ(¸ÍZâ‡-¥™ÙÁhX#8"_ÇÄduÙèI{Î|“²$b‘Ì›®šÂ'V½õaÿ¢zÆqì Ü¹Òk25†ŽQm¾Í'»ö…ýˆ9Š@*èÉm0H}ý ¹ñýeýÀð«·» n"vkäxOÒøõ ç7DíRÇ8®î®iÞøÀ·OdÀTßœY÷f"67PðÃ0$pùŽ/¬ý}á&ÿô?–4¹~#x|ó{ß"rïüæßÃ&µïÝß7óÈ-äÉ·ß+‘|J¢ØN§N3´ @oûÀj­ßz‹99ƺDa£qq£–úê$ÜF¾Ï¯ws ¤×ow¦@Á$Γ/ ÿøQ²ûøÐFÉŠ¹ZucÂ$÷ Þ-¬¬û¸¶ËçÑÁ£½$lGŒÜaîrÊÑôCË"Û}ýƒçb2œ%gzVÊžÓ<Ãã,Ž±Ý«dö BÀ¿èÛçß› <š&SÎ:wZJ2ÐËàÒŠ/>Þa± öxÒêbìãžä‰‰Ei[Ö‹LFŸSñ³ŽaäÿG,² ƒPëŽÂHºäŸÌòl7%£‚úá{rý£®Î Æ@½r†t¸ÊóLåH Ïô p`„çTMU¢Ù&/M]”}D=' ÅlŠ~?Ö,¿üÊ%+ŠÃÈÅÄçÒëV(D¦à6ÄÃ`˜WqœÉŠ)0šaÎUEéVÖŽØè¬ b¢¤òéLÛ˜‘™œ0E‰*ÄBç0"¥“(£™ S-OwHõ·˜Z™JÊTZ×{åh«yke¤ãIQ‹?oÕïB¤úHÀ8Ñc¸p$ÉœÈþ« '§é4 øk[‡qýt…nö#ås5"ýÒ›Ê3EÓŽ(šŒR¹®ƒ÷D÷éØ"c¹èŸ‡zhJß Áü’ªÏ 46µýxzñâä…ÐþºNîþ„µþVL77éë"ºW÷|H Í€‹û~=$2`ˆš§Çe¯ß£oqûôO/+h$ŽŽ[èá­ûÃ=nj—c´ö: Hî{ñ×¶j|eØnäá1׈2ƒñ=`"pMi!H¬ôo­·±Ñwaþ‡ôÜÿQÍÃ;®"àåw=|�xù¡·¯€§GÇã&ê¦Ô•¯¿Ìå’tm=�§_`  h€Q‰â&»-Ó€Ö0Ǩ5"€Féé}}©{»Ð»L€CÀþ†‹œÎöGÉ)¤ŸühÏÇßß™>ÞQrá*CûærÔNùm:±;DÆù2êË<™Vê¯Va„}$[µ#=ÿ¦-~]®ËŠØN“ШÀ”±$ØËñâyÓͨ¤¬œîÂd`Ž^JÃgÙX¶R˜T¸Lð0ãí™l¾ªõ‰Õàx’&I®zJ¶Ÿë™b¤(T¬9SÉÕ¼^‡ŒmžDN ¾œ˜4åûy>’¤O±e‰¤I½#Ë(žî;/w†MZûš:j›Â™Ü¨‰U Üð¬¤y•Ȉ„"xË0ÀKÃÆ3‹&abŒl<QÄD“f‡¬FùÑežðLLÇFÙ(.^Nã1‰f4ZR>Í­eÎ& ]H —<ÊDpZØLgûc,¹ÈaÁŵUޱ<.d–Dr@‚d¬ ë$#árn‹©$dÎYAm ù´ýFj)\6Iˆ—c¥MÂÌb:œätmèã!9è©Jø;Ï5­møz°žúºž,7QÎ,¦¢ß¡3™˜J‹MÖnÒY"2³„ÎøKiU�•$8Mëqðí8¸yáRj ®ûŠè4ÛãvÒí2Oüf“¿È.žmn’_Ýß„î6”½ $ð)Ò/!4.²€½~/;†Ô°À¨n�×óI»^ß•~}&&ØeP .tÑAhûĸý½& C_¼RŠpÓÑÖALÀ Ö§� šòðy­Äc€ç�‘ÐïúºÞzÝ 1 Ìõúo޹ķh‰ó?¤çþO“r¾õŽ»"Ûˆ’¬x¯1·ÐÇáaÃpøÝf*Þm¥ (W_4-°‡Vb­ž ôsæ¯/™àHLýFoáJ€!š¡ÚEbZÀ.ÊŠl‹Õëˆáõ†(nk*n¢ Å§HDÅ?ðGñä_©GóÝ4}âL“&l/›—q˜Qy:ÙMç$-´q3³{qÑø‹Q^¬«À[º­Òád8þgáñ™¨÷ú¹Ÿ`ˆëiÖŠãq ®JAPÖµárÐÑm¦¾ïÜßõ‘VYÒÄ5EÓ‹Z²ñ϶¡6Q¹åÇ¥•ЗŸ9q:Ý ?…NLöŒöCÒæ).ÆlÖe20•i–¿Í £~Щ»éµTén–Hnk^ªº÷.ðjPv6ÒÄfµd 5‚¦Ì K@ýÇ8e­ÅxJq’L$ÄçD8EJ)v²Åã\²¾]_ŠTÑä9‰¶Lˆ ÞPI”Èyî N¥ö‰u® BpæU2*•ˆÈzË•‰ŠÙ@Ò^OBPã%ÞŽÚ¢¯‘´"3^ˆ˜æiSŽÌó)…ì—n�cG©â(¡q–ò#ãb2ÛmFþëÖh°¥–G§.#¤•Âp>`he˜NŠù–òDŒšQ¥\L͆ÜÆF«K]o×ÒÛ¶mœL.(§ü{7†È&1sÌÎ6‰"C4«³¨ÁÈ€Òá(ÜœúÙæýš…/9t„ãæf´Ž$·;– Q`ƒJ ôÃÚ07oÇH4$67aú%0\ó:Ð(bD=*ÈáA#$;$²{U‚jÞ[óÚ¾~V(̌גgoçÃßá° |Ø+ oÜöN}èõë²Üà�ʇ[²Ý·iò|ÏýŸt¢Bßî‹ÛŸ=°z Ÿ^0÷Ncþâº]ùÞ ‡ÛÎ85|o”‰ßoÏcŠb"¬2[”ívv]Œˆúy‹Ÿ9 @[ 9r$3„]D)ú0X0?î”gæ[È×u·â VÂz £ÀB"ÏÈt<ò>^î|â-Ò((ZÑpÙµ½¹ÚQwà;*Š6£oÙçDÇZËãÿü ÿ“«´U,Zvÿ—b²b`E½žË3‹‚EaÅ!@‚0)-B»yÒ¿d y–ÈAˆ“¼ùËòâS^Mý£‘ú&”—dóô€ìÇIí§ÿO,Jó]À¶HSeÝôeP ,aŽõQ¾—‡ÁŠ™ZŽLÒÒÚs')–‰¡²íK%,—™”yˆmLc®zíˆVYOXL 5¥$&;Á•pÁ³Ñ‘‘ ƒ8JNÙFpÖx¥?I³Ýé4â„Ö´«èÂRRúï5¾-\>#Q�—Q¢d¦(ãÂ*Ú9Ÿ{ƒÄºÌŽQ2R"¨L¸ˆµ¥ÌCÅ^JçÓ^�$x 4ƒå¦CGõfÐ"¢£°J¸áÁF‰)÷AlReyàÉf$|k)TÎUÎõ^4†Jö4cz2.j§6.!s–ò§õ°tYšäQ.ö•¨ü–êKÚò$ff6‘ÎÂr¿£ è‹5Ý%f’Ö™¤0dWl>ª"æd„^õj}nM'4/²=çfíXvAfÕ2'ǪÛþš·õ·gáÉuþv‚ç×ö`„´wË…Ö8 ÃÊ>ì&׸N…c@Ûû£E÷å=N _¼>‰S¼RsÒϿ̠£Û³ëò’÷ðaq0¬j¼£PêÍÕ¢ñG@jm߀&qN¼_5Ãn¦þmU¨·…Ýäû%~ÿWò­”Íï#!kIô»½Êwþ»eÒ,½›–x`…;¾Ç rÄO;4Àz6öSt'k$#¦0°(;ÈÓz6ê, YGšëDň¼tSˆ âõ.D@€ÛÇÙ‰…¾xØ*Ï\Rž§¸Nާ„ñð¢ñZ©%öU>Tra}À¸î¶­8“ñŸž¸lÍ(«ÍU7Ûè¿L$d†ÂÃ]þ§sòË^y— ›%Âäx,µaàã(´Ôh%z»§¿šI¤$ë¶q{xIŸ·GÇqÿ²ä¯£‹Q»=•,óÜòfRµ¾Jp9-²¼Y4õäï|Ø,õ!ow¦éÓ ûÑ$”9¸u§m4á¶šgË4“E…ibGBXË‚1¤QàJ{§5ùš ƒ,‹%‰R©³™ ‡ÒZ-¬Õ–0-b•M³O(7‘-õð3ØñG³érž§<vÆ]…Ñ”“C{FóDrgŠ,=á1muÆ™àçQ%‰"oõ.xæÄèXë `HhièÆD4c+g{[Ô©×ÖA[¦]TÉ’ºº·íU}Ö  ”§`-¬‰LS ž†” G‚µÕ¨éD|ÙÉÓ uÅ¢H’lZòÍ™Ëc;I÷‘Ê 3cû>càg¬¦ŒQ%ëÖˆ†'‘’yn(uÝÀI±Vw¡‚±ä©¥‹µO£Ø×²Ù’øË(öä jǽ¶T_ËÐÓ7Æ´]KvIÈZC߆XB$-¾„ÖBcÀ7@û@ôåön…«»#yyÝ/j02Àklr|SßÅÄ#àèÖÅwת ¨¯}©í«#¬?Pí†a>†›íoeM8pSó:âwŒ} ÄȽ¤ç-Q}/®¢€ºŸ?âÞ9Eøbº÷#õï#ñÛ¯ù†hÝ·)o›{ÑY=¼ÛPN°4H{dˆà4¾ ЀÞb3T¡³ºÖ%ôÓa7ôSœn /0=ÄðdÔ E¡†)Ñ*`,°œ£é0 (€OúçGu| þÀOŸÈOò6>KK½_3™Œë¾lY5¶YWõuùø$n,2ó+¯yrÖÇë3•9»8HÆO¦½+»áëèoÐ]iŽtúäP̃ª–ßLäC‡~ìØqÿ”¾|æô 5‚ι žT+×ì9qÎø…4¿ÌÚ–ü‰g"8ûÝ4Ý¥A;V©¢¬}Î>ê»?e«E²¸Ò ’wË4Ê,Ù]Ûuì¯bÓ‘$Rt²äd?›@Œ=¨\‰£sa¥b”f-9àkÙ7ðŽÇÜ I•Úr™$cç4åfTÏ Ë&"N²àB—tî?r\¥Óö³4Ž“Ž ç­Ó¬$À(0W*Hn]7Ä´>¶#lÄ-•–ó@iêlŒ<Ê#*E°=s«È6è?&}G8—^q¬x’ÉýÖÊZhjZéµ ªñúÖ#‹¬ W¹í#Ë·A®˜*™Oc—²àb"È Ü™O3¢–V“1ªJ¬º â±!ªBd¢L ¦¡ÖÌ2—©œˆ8DÂDQhIïwÎ<¥Ck6§ÖÿºåŸ-2×":7:SYßèìE7¨Svø(ŽóÕ<i&3ï¿©ê5Ýn›Ç™½Y“c@ß&cŸ/°0Œ)ŽJ ,oZôeŠ£Ç×ÜŽÅu!ë-³oÞƒÔÈ J䀾޼¼'·Ç·{î¶wiÞþ.Li<Ö¯’ï†/0 ·uáÕãøö•¾lõ—ùJC3F ][†¡é è÷÷C§‚¸÷Mþ§‹þ}d#~'k>Ô„òzMåoï䑆÷²x+$z"K²YGXIh[àà’‚Å�­€ºD>Á$5tÒå|DìǺzÔîVùò—:z•¢· )À6èÁC²X„åŸM&ßËø~Æ’%ÉD’P=ŒãU¨·ƒXlJBVº¸ t[si#»šsûÒêavWnÛÎ*ÿXÚÙ¯Îg=(0`¹>|”å4áÇyÖ;œžòî,�*uô¿’aOÛdÿ«ÎºnšÒç쥪ŸG#:º<ÙûõØ“¾…œñqŠ‹ÚŒW5&f!Ç(¬Úr,I/óêðÅöˆ¤l9+Xôë¾¾Ðü0N²4JG‚D·Ro! bᣠlLµQp¹è3& Ε’Žæ[ŸtÁx›:Cr-¥ŒÕ(©‚‹’}‰Ðu11aäÄ,ÎIn©ì)é…OŠ¶È·±òÖ1Ô™»JY ôÑcÎc* ï ë¡S¤‹œÒJ…°»Öó˜ #Ó Þq‘ e`í ·„L ëàKRNY$e̵ÃFê»À¸ÎuO´æÒvÅý¹c‹»Bî$)RnfûÐ5aBþܽI“$×™-vî|}ŒðrªPàM6›2QÃB2ë´ÐoÖJ=³göeFÀš ’5�U9ÇäóµÈÌBV¡�8YK¾JË ‹p÷H?ß½ßw)­a7{vy1;ˆç©V[¶ešÓô#Áš~°ÆÕ¢ú$¨”&Sï)î¼hFž¶×qšNº½{³ v7AçCÈ‹©[è!û¼Óù4=©ÂA±Óª™êâG<®á.oÝ„ŸWcø´yø<̰Ñ)ca/']ÿF  V݃‡îå=h=ÀPÙ± ¬…7˜Þy:¾Õ—o`(¾[ WÀcG°³Ø<x¯ÞÓæ½‡©)08ðÍÍ žIŒ§Ø7M©pZî=‹qùn%û!J$&�18 Àäáû»ˆž¿ZÞæ@¼¿òý™E?üÓ÷«îÝ<øgry*ðàGŽ9`ÞW„Ùûù¬û÷ΑÞ}„=°¿J1lxÒ¥xm²Ü›^"L±N‘´"T93c|Öú¦“m׈=uxáP£~}? €=Å^ßïÏ*³àèZt#0b_€a ì3sý+5}²+ŠA+AamF‡h÷äå5o¶ ]§>ËjÐr&ô$ö£úùxM8I’>ê×»×¥ÁØÉ6›_á Næ.ýg.úN®Æ±9˜®ÓAÉÌÔE‘U1ùïþÈMuNÚÌ2Üä2ËQ…!Â*$tG«‰œŸ*êñ ¶Á÷íMÇD^/ü3†Ð÷–Ãø:éfiœÒË>]&L§íç¼YÛü•'AÌ¥ =§Ï Æ%±©›jt#¨ŒDy£Ä È’xE}"£/y¢´R…Ô”t>™å÷Fk=¼´ikâ°“äLK± ³\Q6©“Ã×m"‘1:z©¥ü‚Ó„‰†PXK„˨ õ3+˜¥‹–†¬VcÏKIGlâG×Ë„EDb ÚO½ðnZ{7`¤(C¨H\ûØ^PH.Ž)ßX7ðæLø‚èÑCBj£ñ!ßçjL¶¶„L)a!Žcدub ™¥L\ÛþÏfÑ|>ËÊt“en´!J‘F¢L´#%ÌDŠT$ì·öÆkë®éò³ç¦ÀîóíkZ^îìrù±;<n¶ENZúÉá‰d¦(P±¼àDQµÈfb”KÑU®OšÕbß½~ðh«kŒKй4dªãY…ݰdtÕck²CìÑv߀ üê.ÈöPï›î#P|×Ö€uè¿‡Ôæ{€ò�¦nY¥—?�_w8÷ãb÷&ék£±ÀúÞ8ö¾>Mîahln‘$ù!Ÿ=\Þ^ÝÄ®»‹iÿ.øüÿYtuß|·êÞ®@ÿ¶Pà§ö3,Dîþƒ%Ðmßc„û¡ï#óöw( 0@±CÈÝ öH<¼À©Â*s} Pì¦@ò˜Œ_c“mÏ^±,‰zt64ÀŽEœuß­}î”5T! �*L+|¶ÂhŠ—è:À€ÔUƒtÊd_3Kצák¨½ËVÀ ]ýW<üæeUVYµ´8 Á÷ÜÓ&fÝ.!»‘_O—¿·—ZÍÖƒéÙ WŸ}Ö±4÷"ÞùÍÎðI•¤")#;Q³˜Ü®Ô>U/Óœø#Œ]ǯ^È‹+!S}0!¬š Óø\ýzèºÝgl±=/‡Üû”ìh_¤’“ÇsÝ?’[’öló 9×äfâwž]HIô„ô‡}™ˆ:åsM–‚¤4ÎxôÁFÝ ©3Á8¯,a¶”¬, ·˜b–ªàh7¶ýÐFêI$‘¾c\K+%I.tNmº »iíÇ«À'T.%úH¯moFQëHJF) ,DOËjØN:»B0OEAƒ #–»È´4™`*L‚Ñ`tM¡¨KL8 ˆ ,UÔ6TÛp£ü¨ãã¦2ê`˜ ‘gt’ædçÓÞpÖ§#)«£ØFÄTÅÉܩԇÈv)7m¢Á&“ÅÚͺábçG˜„w€³Bé)åQ«¾‹ë±Ú™«!|Kw#ðH#R$‡ßöÆŸnÏ'Š‹ãäâä@f)9mÓÆ=š„,3X™ÄÉrÇ|J/³ø”tÅus§qþ8°Á•G-°Û*uiÌnR(,8W‚°ûîÃÖ|GÀù»ËÞp@ Ìkt#ÖÀùOÌ#ïPÂ|×_zöàOÑ€æ~½çoƒÖï ÆÂ`�Ù"8Ç yk¿q[­R‰®º V$ð)0Â…7`½eš³ b ò}w¼÷¯ô“ÏŸ=ýþÅ z#O~Ïl¤N =Nÿü³úEþƒÑüMq:ãÀ�ìþ¢4¥ïï@«)*‚Õ&¼æ�1@ä%ü &Å*ƒé€ƒÛ•Š„bE:a|´þÓæ#¦&½ÐÀ[tw$ðÈË´3kà&8 82×Êk"þ¶Fi¹šœ¤‹‘hkŸw£;óâÚ>®™ íPMXI'[íd<ÙŒ²7Šq#”•ñ-íúuP©”*9öÿ\~ÌÿGÓöO…Oé®ó'&ÎaéïˆîJîOú&9kiÿk¹ŸäOiöß–â î6š{Ò<˹fŸæA¨më¥ñ˜ôSZOKÄÍt›ã[T2LX±“lÊòƒ8’…üÚ{Æö‘%Ùæ=§QEí jrdÂ,e¹H ä\" ~PÆHŒ«1€ÚqÀèóH„ÏÕJ ç^x.¦Í²ˆ¼Í61ö„ÓT¤„ŽVå7‰É¦È Ç‹Æu>ÖÒ ÞDÏ—ÁKÊXÄ“kˆVÑ!†i$ÖÐ1 ´,$Áa” ’±œsIñˆ¤D¥*%q:‚ “â2Î#“æˆÒ–ð0òÈdj�� �IDAT!âÁ[RÉ,Œ-Pß“¬Ä^F¼"jt…6ƒËÒv¯f7H ’Gl„¦ŒÁz†‰°$FV¦)šqy†³5­óÁæÉë-rùQˆdÊ yÍ_f0 ãûÓdÐwI±éx,ħÇÇÓXµ™1Ëv½l˲$JQË¢ãÎÍ¢M #íÌ™1ûjS�S‹ã øØö kŠ´EL~†/ft—îq  Û}ÐÓ:¤Ü¾¯á3P”Dy#`^㩹Åõþ¶PLâ[ B?Šoú<ß‹€èÝL/Öw/ŽïÌ€ß –Èm}v™ïƒ7¶ï‚dÿ7…cþ©0¼/,ðí£!oÙfýMNù×`Ìîoµù™—`Þ×@›”æ®âÝ åÖ�RSÂÜR &@˜àšâb^~¤u½´_3LÃW¸B·Á!Ðcfò#ŒW°WÀ²àŸUî<Ö ûqƒ‹@²ß”ê84b;QÅ2§³`ø~Ö?©MËÚZÛëHÂyîÖçü+1û"K4Ú–­ ô™!å7 {êÛÞ™ÎYškI¿õʈœ6ùLâ�‘É@ÎáÇr�¦ûó¡Û‹ÈÝE{‘’Ll‘õÞ[N0¹Þ|BXžfA™aq}ù­h|N~Ë“IÒi7Q»X}+è£Ur/Ô°Ä{WSè½VÕp<Ì2y ÚhæˆH áõÈ­ ¢IÊ•6xNà=AÚA‡@2…•rPÌ!xã-1‰ ©N¨W¸ÑŠÑ¤ïƒ\‹d”ºç;BóAðlª‡Á›}G¼à:#hÉHôpÁ˜â$£6š`©ž±’ŸæVШS/4£‚0eˆ,ðBj®åè¹òŒ—ÉLùdØfÄÁ¦Ìè«Ñ6Þ6ÞU–9žNh cã…ÛK1R%tB…§aŒcàÑ¥±ôVé:á-ËžPuBg›Kœ[Û3ë$nûhX ©JUrp(Cun*"’ðêþS21ÆÄ×Òšž$S]L)3f–t5oéÑØ¦õ2‹‹<Ö‚_µ¯wû¤ Ð½RÛ §Z@°@B 'ê÷Ž«×rÓÕÐÿvªQ4¸®cqºí™7äÀ 7TÃÜBy” ĈË7¹U·üºˆ€ù“�mL{?¾~‹ïQÊõú_”{|`2 ½+ ¨NnùN¯¿gžO€Ç€�®ÞÞ€l¿Ÿ³r›çÞ®.·ÿéK?<½¯~>jIàT|w™¸ŸC|בÿ?Îý€é1Ã+ÿ÷ 8=ä_ãÎab^AîмùvOÀfð?RºžÌ;"Úa3¼;¿¸& ëþ”bS#,æÕ¨7Y€i§¦PŒ¢ Û,lÁý‡X^àêóB‚gÀ ðiCØø•hÉs37ø8 éNbõ©æœù›j?#IÙ‘þL5й$OJލîì•>Z£)LiÆî“5òå•áÛ]AF/6Ø4,éUÄ` WjDȸp®ác’£WÕÆ`w þ)ù”¶¿tI"M6F_ëÙ¨Ÿ yö1¡é£Íbê6 Ýä#ÝÌ²ÝÆ‡BåÑ´´ÛyþŠi4²ÐDøE‘›SÎo ÷rÛ[R3.„ô7Æœô&;håc•ÎpÈy‘€´¥1(gcžôb„÷’zê m׆F‹=ç#ƒ²™g¢§|Ì"Ø!€ÄÌÐÄsæ¨Ì 2&” G#9„lŒÎDÄ8‘ÜÍ„ŸHêèHå—{Ãj aQø ¼·£•”¨ŒTŒOŠBî9Á¤¥Òò(yL£Ìc1À[Áe–çÑËÑÇè:¦\N,Ö® ºÛ–A§lÂt6 ¶¼³ØÈHª,çœç]Iu’’*ÉK•äú‰˜TÁ®éú~ÝG~SÆ<7&%kÊ­ÌÙ¡Ì5G‚rD²i_=÷£ÞÂ$hÄí•ôð™(²/Á¹¯û~˜!ˆ¢Û¦ë÷»åšÏ2&ò*&S€ ÆmЃ«F»þLè³ìãžÙ¸Š@™YiLbSÕea0CÜaoPBê]Zç]—›4AE!¸D0¸>øíV·«µ[d<�6#¸´ƒ·®H䯥ãK§$!�(#°*a@0\LᆷLòžZòKø·IíÌ VoTH%Ä»Ÿl‹}P¤ƒÁ»õï~áÍ#áÏ.ÿQjƒ†Ÿ<u( Z¡oï!xóƒ–,z#îmSßßß´ (› ÿ%üä!3�˜„7êNûb(Vë·ô)ß}¯5Ìø'ÚìŸBÌq­qí*ø'b>Gñ§||‘²ï²›þ ¿–’ébÒfáj5?C!18(‰Á¾ÛL|³ënC $@¯±x2èC—G*c±aØ×2ë÷QNyÞ#4tü2ÝM 6€6K—Íe‘óO.ˆ­Ãz´#%¿Õl¹½ „Òï—dxf²´ ¢©kGŸ•õH^üî“SÖŽ¼È¨Y»éÜgW1A™6jP‡ÉµÞ›À’­‘.Úý«º^FéÛ¿JmÀSÇm±þ|²HýÑq¿+X-.®·[}öÏ­ÎÓn]î nN‰\.#?5da¼V²W¢™ÏétºœÌ|ªk€åz§÷½åƒX¨€è飕†)Ëá@b :°1’– (*N,^ÝŹ¢Œ»hG„¨<eJÅG H:€µ5%$êÑ1Õ ‘Ñ랊’f…È3– &˜ Œ[N¼ Qzî ¼dFÆŽz’8Fd¦%e2ik’¡ë[ú)‘?ôÂ1]¥M¢Í;&K›¸ç­£lb`ÂaJ¤LäÅbš"›NxžF㇜²jh$‘ɧ¥š°};ŠäŠ+5Ï«Êlª+þ8\mŒÑ<oŒ$&s‡¼ÛÑßn {87EÊ\¡·.+^÷”A™ºë_;^¯Å~¹ÛÔô³ÖU} 9•6Ò9§|úwþpÓ;º€æEƒmeäDžfv5¤¦]b— ØË~¹ ìz×oÅÓ)5Ò¢Ü倯`¸+›wx£KÐô¤ùÊîނȃD~µDg"ÐÜxe 3À܆48§�ñÆíu˜ñ^Ûºy?ž¼Mj÷ïëGÀ%ºð ó°ˆTæ{ü¢?#ÕN§÷b—Úð“—ñ—ïk>T(8<Z¡1ø‘ޤ¬`ªÞOü°ý¶ú$Àèì€ðÀ¿�I‹‰ÅåÊsÿBCÞwŒ G�áø!’#`ø£8ôG2áëþcÉK“‘ãU33n㸧Ҫa ýòêbÐ]â›9^~Š2 SO­4Ö¨ŒÚ\.0Yœè|Þ«¤Ñó‚,¦'NÐvùr8{ù´uÓ¤ú³Ò_›Ë=&ST/‘§rM•l¹ow;SÔn>÷š’Ú÷•?hžK¡ |k¹)“­.Ò%غwTw™[emì¯#MͯìçÌnÉö,ò?î¹i±‘×L˜0´1T¯ÀÃy2½–©Ï}êÎËÝœ“YG‡Ôét±$Ø‚oØÇ/ãödÓ“]OüAO—ö[ä³íIè?Öù„‘DtÚ*ÊJˆi~0ÍYšg¾cdjà”kÒ*™"q NØ&ø6RIdICB<§vËÀ-tŒÀ36R&³Z3XF} a`sé@#AEç¨ObŠˆ@F8UÇ2M%D”¢'¤'±U±žxH 1DÃÐf¢„VL÷ dtéçc’uÜÉHJ"`d I¶×”¶– m0N$2†iÀB4Ä’©åd?2dILÓ‰”’P/„wIÈBºóÙDëʬóáÕ†¢Ï É«rq"Ôá‘àE==¹hèþå—fw=á„BÓ¸nü×rw²WŸí²–É”fÉ8†ÁþÑŒûíµÅù׬4Й?©Né)ldmOú1ã“|¢„QµÄ£Ùìbܽ�ÐLŒ¤«™]"qà1�>Ki_‚cXãÜlX�ˆ P¹À5: èÞ‘à0îØ&s-ݾ‘•=_5Æ ©1š‡aºTî‹ÓýîíŽÐ­·ÄH¯;Äþû-wúû?Š-áÃH•A¢ÿ°ÎÇ1`Þ1ì3ï+òGtýßgßð†ƒµúë$l‹¦XûF ø–õî1ÐÞîÏŠÉ£&§ã“s‹•Æv¼ï*¾¥V ¶ü±ëo_ðŸ¨ÑÇ Š‘ñšpã<œ¿û7‹w7*zúFË>¢Å)�qi×»Ä]"â(,Ó'ÓbÙ"œ¹«èíIHrؽݬ·æÅõn¤ý»ÅoáдX 8"µ0ºƒÌØVÀ …*î'¤*˜ÈŸêpL‡!5i½0ssm8þsÅ7´@»ÇØË£Þ°ErH«M*¦%/å$ãdìMÝyëDC.Uè<›åbç*w®>3ë%í6¡?£»GúYWm;ðeGÙ×—ìu_‡–ý¶œ¯HŸ“¹Ù¡æ²aO¥B$fÕ6;áŸÛCÍÒOÕÁªyª9]6[yaG¶ßN·òx9üi©{Äc@yUøã‘³‡öÓƒÒÈRÆläÞ)¯™*™L²ÒKî öp–P¥LCi$„0å „†%BRÒ!Ï¡ƒ¡àŒJæ)öÎ73 ©“ÞÊ@]ä41\Ø@lDf]”v5ið޸ܨ6*B�ÚŽtKhHà% Šä�c„†hT©Vž*G%á’sO]m”NX ¹ò˜;¯ˆóÊö,TÅ ûh\k´·TÎbhœËH'̹éšð*㚉À´q„ö1Ïx½PÛyÁË`Ý�;òd9™HYj*Oµá¬0]pÑZ}܆]ø™Ùoé¹I¾MñË ] Ìùúר=DÄ‹úäQ}”+š ½¥íÅ5x‹ÉT`´N0ÿ(”¤L1µgj>?»ÑÓ Å†Õp=h‹é¤GÈæ€6Ø�5®ï¢>±½åø+lnîÙÝ›®¯ÜŒ3Œ£y3-€J˜F±6õ;fA Š C/Fà+¸7O¿¹c®oÃ÷ûïê Þ= ` l¡ê;Ïíûž§`ôùû"áÌÏ—üKX0?ƒ)šýEµAG¸#›¿b`ð7l~â›S’FûDOº,•Ä<Õ%®/·o.>>, ò瘯¦Ý­l _YȺK1‡²‰r§*Ø) SHs?aØ€®0+q5l‹Í-N–Xø×}Vý"×|ºoâeÓî×í{2^SúeåÑ ÌÆ \ƒaˆ-¾I·uÑý‹V£š<\ûKy¤ª²ˆ“-Ñ.ŠÈ™0&J"Ë(,W½n[¡U½ø´ºœÖ›e†Œ£8õå¦z”ˆ…•ÚW¼x”N2Nöýúú¦ 7«ÁmIòÌÈ'© lß2ö,¤:—'¬£îú¦KÏÌl»·È“ßOû_GRÞÔfã¿ÞØÿrbÿ•—^ÿÊÍô\Uý6ø±™ýj›ªÐoÏÈÕÆ‹£¶ho–aÛ¥¸îý=n~•\g“X,Ò_Nº?¨©—Óêp2›ÎÌ4üÏšp5T¹¥…ˆ$ÖdÞ,z——R–r.uåÇÁÄhcØÉ°g1cHµ€`LbÎ\)œSl͉°QdIŒ.ðÀ’(t&-øà9iÃl¤ÜdTWœð@m$"*NspcCq¶cÎÖRÞ³ÔsÙSÒIœçŒk Æc°&JÑD$Á3°€¸¦¶ £bJ)- ¤ ÊpÅèÈ„Mb¤’Z›6®¤}_ŒÖŒÁRˤ8^5ÉÕ˜ ! Á„㜠NÚ`+¢²Ùt¢‹išz¯h&]\¨I’h–„žµ|´#½è’o.+\ˆý6ÓØ&T4M3=2*uÿmgÑ (. ±á9*ÏÁƪãó¤^Z鯽‹z;?˜aó¬ëИèZ–‹å‚'¿]°os¶D¾µ!³Wͪn· h°)Ë=©’Qv»[@ЏpÈz@@N.Í­˜´ЙØØïÓ!î~‰¬×Ò‘S`åÞd'Üö|^…A/Åm„‚4;õ=¸ûwG‚œ*ÞÕdJà¬~À¡”@â¾°ÝŸê)ðñMôú\5> ?ˆôÿ«ð© )ÀÞD~ÿ"†¿Ÿ«N[¬2M Ë™äIšO¹¹Ó[K8`|hûÞýœOïvoèR�N?E;‚½‚ Rnâ*� vÝ[§—QT/!õêšÀ 0éoQg MXÏÇ5¯·[.ZUl¸vDÃ>f@ nÐ0gToÃAޤę6cü,_L kûô¨G<›r3fíõB.;ÈDÖEß‘®»DÝäî²À“á” +±ùúéÁj»`q¶áúuÇY^f„,&»³ƒõ'ûZŽ©É ‹¯ý©¿ Ÿ µ,L(¯/˳ÃOד†˜Á1Øý8Ž$öR:Z6Läs_äÑtó:%½p¾·”‚Ox1ºRöì—Á‡vW…oUüC’#X,êf‹íÍFü©Hÿ)²¢ŒÂÇö4±§Eœe"£Ä JeÁÕ A9qË[Aº!´ûaœ•q¢·Þ½ F9.B&<'„SE¨Zx’Û@…«)3LhB 7² ¤ pÔGÅh¡Ó”ê †¼gƒ¦^ÊÄ{Ê£¡VÐÔsi28KhÐÉÄKÝ&‰£\P0åË"¦\F'¨ÑgLÓ”1é‰ç`1:zå­¤†\ $q(C´^ˆAr¥ý8ÄÀÚ ÁxR¡t!©à‚ð”éu”¡›¥©Ó…Y´vì;æØr1Í1ál3ø~ïêh¿¹aÖ$G1‰Óí¶¾ò¦ƒM̤b2Zlzï® u•¼¤ø=E¡~ËŽgivÊ’„Xf;B3Ëf<«l’)}?šÈÃk&NÜ.$LÒÂw°({Ï{r°jlsÀ?<x>뎺-Ù Ä9 16_§«9 ÎÍÝó;8-nVõÛˆt Ⱦ}€3 0.p+;“§iºêºM„70Ñß·~Þç6¿³èØdh ˜;•ÄƱÀ¿?€‘ ˜k z‹ÃjK4šüaøGø¾g4}[ ÒM£ý‹jÃm“½ûËOø6ÎÔâo]$PAµ °ºÍËÌD}­·Õ? š‘d.gø ðû^ºB<ÂþgHRà ðèü^A±–¥‹—›ÇW‹ˆ™ƒº_’O Óq¾éÍ;däßBeÀ§ðç V¯.M ŒÙ§x4¡9ÙŒ|Îòn^•ÇkâˆÀCÜ:´uÿjÞ#_`C³S⟓R… Óä‚ëZÒ„3.ePžSDÚD3†o|ÿÇŒü¹qÿ%§';,_£\ü‰Ìöµ=ì(-¢‘I…¡G³n¥™ ^¼”ùS#·ûKÌ93lÚÐ_ëtN(ÿŒ:ôc¾ŽŽÅn6U+“ÈÈ"Æii¶;3®Wyö%M|GR:FÓ‰²¾˜¦½�ò~`™IuÒÇTi²%íbcæ<.®Ù “ûA\ô:¹P2M¨`H‡‘Æà„¥ÞpB†Ö¬ÃP‚0 X ²mùÎsš žs"(SÖ2툌ÁëÈbœF1…D¢¹ læâ,%R¥*•15’—Æêè…¢†FÁˆå–zb¨ë%:ðDD"™ T“$)<!0)(a , ~°.šHÀdLtHR)Xâ"(q„Q‹è=º6r„í¤€QhÅyäBDÆ­£œ¨Œ8¢X€IÞZÖƒH lÊ=KIHó!’ÑØ”K)fF&#bïo¼oª¼ÌòR %bgz·ï/ûVÔÛØYfË‚”=ñö'Ç”…P8qä*¡ÙÑ›^ȋŋô7:v‹>ÉrÓg¤«`dÓãÞW~”ĉr¤ýÀt?Ùòµòg{U[C6õåúkæ§25³Õ"&Ø€èßl_NbqÜ$·-ã°b0· ypäpP¿ÕC¨n>÷ÑF#Rè�V¢íoÛÄbÕ&æ–r=ޗ팷ìZï`R.݃ÑÅî�޽ Ÿðk@_¦fßírž×РÿP#ê;<t?ccòîÌ_${{?ù© ‰¿ìÐ . Œi®”öãSÏ!md!ÈèÊ¢6¨ó‡×B~4`ö�È€È0p§È¦ÕÁl¢¦ô<B)Æ ¢ÊÔ(Ëé ?'«Õ‹m|x’ª!û<^E˜Š@&PÇxzf2wùÈôŽæè+.WÏ»¥î~}=¦cqƒOú3¶!>:E®q°ÅåÙïçãµßÔhßÿ‘ýwmö±"YUº$ÉR5é^]Â˜ÑøžÖÚîF³ÏbG¬óU«‘Íš)?áäWɹ¶4¦åAšM=ïZ_{÷Ž{ž‹´Ö{‡\‰‰è_caûhšŒY‰ðò±±¶hÀF e´—á|Ò!ß~ð¬-Ò˜é<ºÅÀþ©"aFþ ãq}¡ÛÔ™I‘ ôR·T¡¬Š•–!'…òiõjŠ´#‚]»ø4¡}Aþ9]û0_‘Ò #k[tŠû¾S½eL³Ü-KÒ„EˆÞùæZXÎrÁ ɹ氞òÈ™gR16 RG%¥b�˜gˆљȽ˜>÷ ŒR“aàÞ"8ê½ð†{@‚·œ¹‘Ài™`^ëÈ(€8!œÂ4‘eà–x St^P=Q!Z³àq†ŒXG0º˜•‘B$%DºÈi`šy êúhaÓ,<ã,hâsyZ˜|ެ]£KœK ‘Æ÷.*T¦i¦ÁH½ïF¿Þ“mmº&ÛfËc“yï4¡Tx½Ì)ËÄväÜ£Xºí„b&ü¹®'‰8JY é ÂÌ6Õe£ólì:Æ…Úõœ¬r;j·ÏÚóÿò|p'ûǼ?Û)Û–ý–�Y‡­vˆ67P¡Ï±öHžBL_› öÀ†½q]íî›·ÇcàªÃøü¶B, ,çòÊšþ ŠÀ-}¯Œvælé½ÙÎøÎ®5á*ÊBÑâbÕ½‰¬3÷éÒ·\.µòˆ›{—À‹ïX°&â—ÿ Þ2"4S@�gB‘ýëfÑæÁ×€ï›ýÄa¼0üüÖ"€¹A@fo•1'å,6q|.Z6�±Ù€þæÀ3ôìŽt²�ùêñ©˜®ž(S¥rL¤ïY˜‘W—2{Ö°jpruJóS?¼=9*€ò«ùÕ;³°ÝÁL¡?¾\¤˜uŸ‹ÙS“”3ÃèöþЇí.¯pæ U@¹@ö:ÂtÁ¤—›ÎØêkÀ¿ƒ‚>YþqQ¤‹üs¢³rHĬ¤Æ ‚Óž:Œ:îÎU~>ï-­ÿ'¯ký]~í¤\°ÿÅ­guׄý¦ýHo†²mW–ö“x¼Ù±n )±3Þýb(ÌCÿù¤Ò«k6±×Âôj¯’åØ2⬯w¾£¡º<íB€Uûnß´\ðRÔ…^ÊPN-ýÿiÆ/ÇëbØ*¿0'’VÐ…§ˆ#‹¨¸,û‰¦¥Ö‹D$¡c¾óÿ|F©Uâ5OòP ^R"ú6VÖft¬Gµ¥ºOóÊ‹´¦ÐàÄ–ŒvƒvNƘ‘Fi¢3!PUh™©Èá:I´'ˆ½ƒÕ`ˆ’¡û Ú 81ùZ || Æ‹àÁI$iŒA…½åŠ<aZ<é|ìÀHàd”RÊŒgE)÷Êû!FIÁSÄ€‡HGL¼ó¢ ÌNá#ãŒDÍ aÑyË­'1B©ŒÄ3bGiaáI bÎÓÊJ†í­%"m£$mE0qp]¶asÃ^õÜÚ>"Ȥ°…Þ÷ïh.ÝÀt±zdx²kì,!2u€l Rf’Š] ´¾.Íe4àìW±×¶ç}çFÇRÓ’FÇôËiÈbéûÿ4µ]n*UìãÜ" @ÈŽß,äÄ‹†¢kº:Lú¶‘-5ü6lñÆ Ã{úÛG’ >Bßf0r‡S߬l0S†>`§f†ôí§þÍ«è±Fw~ Úýômzú›¦4z³ýž»Sü¹…:À|¹ÃýòûN·ÀÁ?Pûö}³£¿vâ¡(•é½L€ûžÙŒc­ïƒ6P˜FœvóU’lIHzRD‘¾B76¿YÝŸY`ÎLu>8#õÍépËf›…A·Bc¾û²åaïÆÀøÃÕdù$"gÙ·gån[Ø­a‚A^Êpii±òãŠSØÈ€pgúU[C._«¢ŠŸQÍÍ,éõU.•~AFk[56ÃksÚ6º˜$…yV»ßìq½G/+ú²²¯VøÈ ò@U÷).)ðÅ'ö‰’Óè8 ‰©i³–MO<¬î„Ùõ¦gýï›Íÿš<=ìÛt8ù·6Ùü>a Ø2sîŠÉæãäÅ5?ê–Ÿ˜·NôÓ”LzVÔ¹‰Åzšì‡K³3ç/>ÚeùÑarr°íŽÓF!íMÌh`#19ÆdØ Ïô1ÉBäžËÈ•å6IvâæbV[•›Óf/•ˆ}®’(ŽFÖ¦yIe:²5”ÊfEœú…›>‰³£Œ·3ê%“}N‚ô6~dât祚«i%Iª“dšˆ¬¤šzÂÙ”$@ì¬$Z™8Æk3’Õ‰Ð<* Óv½ žÒ,' ‹<ÆvÆç…³cMèB™‚QÁ¨Ž"o™ášÀšLˆR ”DO,„1™.‡ãà�� �IDATq•.ðD‘è)œõÎ3FF8¢é|äNÁI é‰ð2°Äi "FÊC$} ÖÇ9IT ‘zæ<´#%xI)ó"8â)8e”cÚ:Òu#;Ñ^›}ͼÈé„¥Œz‡^›¦#óöÿ2ý<”¿Y4®Èãå`»™Þ§\…cÑ‹—6ú 9¢ÊÖ;)·@j-64cj¸bãD2pVžZÉe^Lª‰H ®ý`º“ ©òÍ©¡k㯜ûÍ@6zö¥e§7Xbæ×`ÀåƒuÛHV#7P@ÝÉáAª%€k¼€Û¡è»¦�¶µ©ëUsÄ)ÅÍýâ™ø7oûÙ·C¶ Ûþv)ì€oÖc²ùSÿiwÅw‡Õ<~ïõ PÞ{ŠÿÔîÞ^æº{UÇ?¦6ÜúI¨…á¯åùPË;×\yÇðmoã ní:œnqŠJr>Ú“qäWðÅà‚SÄNg~ØÓÏÿ’`³ >>$ò-grà j Sàà×p ¼º–xzÒõÙ6ƒ=iêb5„W+S™ß”§FÌ`ÂVZœr<§½'xu H ‘EŸZ× Â�8^nDÕºÂp žΪ¤m·T~cËf:Á~q„®no^ÎÛMÞ>›ÔÉ~þx¿.¶my€Í¬¡F$™5+°g‹Ò—Ç>cŒ»Ž².î|ÿzrý*²Ïka.Êö|ï{}ÕoGkT³&!ˆ¦G¸üÈëåqyeò}Í~½#ˆÄ.Ôåžedd¾0¬ÙXYNkÎbjrÍ^Bݪÿa?˜ék)o${’h>¶ß4Íæ²™!±¶þ3[}$h‰­°1¥1ü·;ñxè]~ÔLó§Óã"&Ͷjã‘Inze‰aÁdƒŸ‰qK|ÂI¦¼"'ZN‡„w<„Vb˜F"49¢ƒâ£^hFwDø\2XGS6ˆ(I´Ú2Í  (EÂ#¥Ä:×u›®Y5'E¦ÓœHÆ8¡vt½o- ÌÅЊÀSï)4 I#Ü41ZϹ%„9X;DgCìBÔ&)¸ ,Bˆ‰õÎïíèëžHIr­(à”k¡4·€£12"D‡@C¤8Be$ÄbïÈ9'R𔪊àa@m„ó �‡Õ¢½WT%D†Á0ãXïe9¥!ÏË(uÛo!1lSÞn9!bÙ¸4DfNóÆŒ.EËüVõ‹á ¨É6Ωì`Ûmïwñìó¨tme;H3a_$<ŸÄIB³±UHX-öÖYû))Ö¯éf‰BmlζzwÕbýå0(Jü@o€¼Á�8 –9N¬ncyÞ á�‰Çs Å‹à›ßðï”)àáŽ_“>6¼•ap¯žzq·î °Þ Лïm¾ƒG”Àîç1På]BÃþ>îíd­y§;óßçYnoVõ7äÙïï¹R`xh©}G¶æmÒ`ï˜C{¬p�d«‘o»AÁxú)G˜{+Ô³oê×hâ—&ÞÖy*¡  @�Š!|昂ü0I@ï%²NAÁÈòË­\`lé–ªË6�ÉØÌ@–òHš¢½1=Vfâ oÝ_,—‹þ³ÓoÙHýSþ´ÊÌ]1‘8-Ãbf[Á¯Dv¼ «L†5½¡~Ü 9ë']ªÝÇì’=+ǽ,0?#G˜Ž(”Lä¿‘›§åAo¤ÝwV©:í»±íĩ܇*øÉ¤ßÊd³0Øgg¨È·Ù³<ô%±Ü~=“TžFÏÔå±ßî‹Øäõ\OÊR$ÎóÂF·Kšf鮵õl¾¦ñß&IÜ˜ß Wº©»¯íª=L4]ûþÜÄ;ÇNÉN˜Y‰‰ùº÷ß¶ä_™4q’*ŠÇÙpºH/×E³Õ¤É\“ãÉo&ç“i?$½ñ'jÏS¯²& T³žàÅ.$šÉ‚‰‰TÊkƒX;9 ·eŽR@$U¢+˜HúΧÄf½MªЈ‚°aT!Rª"¹Íh"bŒ¾wÆ7Œîjà[› &Ü(Ð AÄàƒñ¡ï<1ðEE=£‘‘a–DÂc‚³ ã„êÇ! $XâhnA” „FDLçÚ®7ÔŒ¦3u‡>™AI88…Ò"ƒ†#¤õ<(D…èY„‹ÄP&"­·ÎSŠQcF¨ Œ’°#a¤]‹ºA9‰LP–`�‹L1Æ)q`ðžOh'YiÅd0&´#jÂ]Ôcú›Ò$=Õ©ÝZYd ±ý íÆq= ã¨a)É¢D¥'VñËxÜ›¹ËyÔmF¿ ]—7–%¥£•ч¢íÃmZK.‹qp\¶Ùj˜ô×:>\öv]⢙õfP`?`Qà¦G¼50¦� #ͦ€¹ (Ù}!Ó¡zŽÓˆØÍ° Àè1Þ¼Åâï i‡›‡üšwÙŸñ]ÐG÷Úˆf”ÆÒö~÷úìqS¸%Ýž¢X¡~û$ÛN-½§í†·ù¸ùO°•ä_YÞ)°ægï’~|˜2Ü-5з߿Ávõˆ™kñv:|«Š™JÌ ® �ƒ-®·(‹Ú˜a“°é–²±¦kUâõŽ"Î  z sŠÙ Ô`�Î�Rù½rõmî˜Ä—Ûs¤Èz|ZÃ%×7í§ÝNHûgÿs “Ñ}–OùÖðP˜h„¶‚Áê©R ²|lÓÇsù˜n³55MÌÇ4sS®òÞ~;N‚Üñq}ù­=«/Oççd‚ UJ)tŒrýšð=Ò1Œ’#§˜%§2QUÍ/3‹ÿ—·7ë±ôÊ®ÄÖ™¿ùN‘#™d²ª(š*Y]BC€üÒüæ?ë'?5ÐÚ€ ØÕvWI5H,ÉÈÈŒñßt¦}Ž"3™$“E–JR¼ÝîEÄE¬=¬½Öªlty˜a[ "`àûÛ™ÃëZɼ¾KŽ¿tL”ò×GlÙ…g"¼4»mÅÚædDÕŃ”++½I޵{4’<'ió•JéD~ùx¶S{jé|T<oÔ>h’Èî‹ÝÃòÆTé¯Nôvéð°ÓÅö­•ýEÇôb˜kwø_Ì|Lñ¸ª%[‹ýêò ü÷7ÜSk¬W-çÚÿÂ÷ÔÚÅXh{ÂÐô̼¬».×HÒ0fD†Œsˆã˜ö:ËÆW•ÑK™µN^¦)Óh©˜²è !'®9˜ÈT„ÄÛªEÝ0.(û8mlHÂñ …22&Ɔ¬‚FÊ¢M,†!X!ejot0|Áa@1¦HYym¤VF(Sv‰ÅÈ‘êD"¨LŠ©ä²K6Gn'7¹i”.2—ɉdÉQ¦Ä4çŒI“*&UV!Î)Š, Á$äœcNDN 1ªÈ‰—œ‹Œ”y²9†œs&³•ºJ 1) eŽ^Y–@¦è}´®˜¢¶L³^°±q+ilô¡> !&'«•´RØÊZ1ƒs!¯(ɶcÅ}ãˆ&¤Ñ˜ñÉrD3âÑæ dá—¶?¤â3Võ•â·ç»Ãu¢•g+5Wý~$µÀojšµ}àf9"�7¢¸ñ'°{À¡Ð<8Æó ;0s„5äÕRcºÿ{çnã�°½>¼Ľð£‚_ƒ>«áÇw^ò-Ò÷ÉÜ<ƒ0ñ룷€qyOˆ¼ u@ûƒ߀Óï„N èßñ ïȦù9±vß¶üž©åϪ Ò¬ðã—NðHÀ €'ÀJGZå#AÚàìšûIIãéGʤŸ WóÅuÄ‹ü“FåaÁ3÷ Ž—ÕQÚü”3–—(ÏØùÎcyŽ¥7rÙÄÓý%Ó‡~E·8{[(¿ö{»|lÓÀÕ~Xd6>²7ÅKÔüò*ô"^T|òá­‚lï%ÚìA“çÆó§«åiÙ%þÈÙÒ]m‡î‚ÊGQ/ëCߘëôÒ¼ß)Éuý¯¯.v5–Ö0L¿û³Úà¤BëV·/¶IB(ˆå¹ˆ?ËB„¦Æâ�M“¯£F¶¿¦ímé¾ÊÞÊp]öÉýãþgÃ6Ƶ/ •áDÛ÷êòœ"ÙòhIkU·ì¥»¬à uÐpÚß w½ÐŸ•â<—Ÿ ‡ú–?ÒÝ®6~G¿]=øbªÿÃOËâQÇÏ4Z„jõh™l§Å“Ò_·‹sR|b6ɨ§—e. 4R»`L¦Ç ª”Ò‚ ­9ü¤Û~4—|,·qË–¤º©BH^j—t¶R$)³ÃÒM9B"–Šj#\ËQ‰]“š²ãàÄU„0Pܓʒ5«+A2ŽÌzL<DY&]I©«È=â”Ĥ²ŒeBFàI`Ê(CeN”)¼Ì^ªÒ¨š 퉹äƒà‚é’TŒsæa¶<Ä 2‰ólsŠÐž©¬4Šäuš¹ÕA”F”$B–Ls%QrÈ1!e`9dò™2—܈%àkÊ…MÎ apš{î™ÔYK°(RŸ#sGU̬F ¥}ÜÙoÉÝF>¤ÿ’3‘ÒÄ‚F˜ŒŠ»¤Š';VjT»*œ÷Û»C`Ñ€/Öb*b\ÜTaä6ãªaiÙ°š>ÿŽd]€ÚX,†'Ù©Ù$õ²"]ªéøÐy£…dØü 169,®þc½^=/w/±·Ï·�¿Âb{~„“‡/ðB]à±AÙb·Ãæöuî¾<:ÀÏ¡f¢Ÿixo^Å¥#¼ˆ½9دùدk®^ÝÓ»ï6¯Ü£NÀý÷J —øuÿŽ–÷›¢ŠØ}ý=ÇÀ ¸ò~x»4~»íöß’yó8ýàhùйïØÿ¬Úð'ÑîþG†ÓW[Å7èüH0 ½RùeÙËîFF Åìõ)VŽôr¡g,tÑŸáŸ4pŠiûJ)Ýüoˆ?ÇÔÞ R¨™êLUvÜ´C¿ß]ÔkB=ÓGm›¸¹*ñÙDØîôZ{öþ§áøÁózˆÌs[VU5_eíXúþŽzB l&7!�t/|À)ÐðBîýéJ-V‡âÃF}ä«V•üàòm]A¥2¤£½nNnÜë…)±z ¶¡>ÅÑ)Þó)•ÃK\¸¶cZ%¿5ÑUKñ++^tÕS^´Y'wÈ41û|å¸Ç²3]¼*Âm"FìoÒxCeØApßbQ(.Oß3t «V<M…Ö¡ÊÝ‹Tÿ®ÅJùVm)þv…rÙVÞ–eï]óìIGݸ´ŸÒ9ÚìwkJŽ-ÿ}ˆ·©°Z-ÖˆÊÒ¢CME‰š]ÔýAºÎ¿Ìe ë•t@YŠã%DÁè)«ÚgüÐáBõEŪ–uqiòƒj:22‰x7Á–­buÈ.i¹Xj¿”¾å©Ô ^,3Z%%¡t ÕR2§AÒW1ÏLLLO`”Ç”Áx&Ø,lÈ*xÂr‘‚‘âJäÆGCÁĤ8å9çœuÉ¢Ip•E›‰G晘%Ï"§Y¾O$ù¬…”ó‰Y‘¬âªT\VL†2É—ÌXR‚²aÉð(”HœË¤¤R¦æ(  à”˜båæ!ô!Zb MŠyc’IÈ6ÌÖ ž%\úL.f›+­O3e‘c`˜˜Í™Y.$7¥6 5ñÈã¶pÏ‹ºf%Yžlå‡Ë⨙Š.š”Xã›ÙŒa<öðLD©ŸÇT2Åëæ¨–›²\‚5M©…6:—lfDããä:M|á-_ûý¢Ã‚¶ºhÿ{mÂ(Ï_Ƴ†P Ìö®‚$|5kÀ€³%F Í:u(墨©æ.Mõ×\¯.çí[§Gßpïßê>åÍç[Ý{|ƒ<•e¡©�½GZ}ߣÀîþK÷yÖýw€Ñ/¾ÑÏ@ Ž@õghÚþˆ«üNBê›Òqù#9ÿÖyÑïx½øcJHžãì¹ï»ÏÆŸUv½„1HXÁü GG8j¸à½a»Î<¯F`Jm¿À‹m`ò(…ü2WKWí—u5|p¬ÿZŸ|¦Ž/Ç\Md9’Q‚ÕG%]l_ üRopšN×áäñØ®³È‘/½i‹ªz |^VXáyBÞ´Ÿ=ÐŽÖA›XÆÝËÏûíͽÊïNÃ}ôò$UÇF*ÌÓÏ’zO–L§›bo7ñÖðªÐjÒ'ù‘¶ý¾®Ü`‚Ž þ“mÍÛÜ ,Z/…‹¸¸‚O0ôAÄ)þâüæ'g*ü¤|±¹šÚ›.™Eô]ŠNí%7jÒ¦ô¥eöw,µI”òaÔY?» jd¦3ñI¸6‘­§ ß cv”â(­òòas|jêMÉÊ6;y/ÖÖý5í ÐçŒÆÓÂɵ雳0 ø‰qcŵ+�qá5¼Y)DYÈ®ª&ʢТɬ¯o½»+ÆT=häñ‚V«×OOäâýy\†#$ë’·„ija¼Ñó\—û$¯cU±¬5‰l„*JQ«±¢VëÒÔLw sÌ!&i¸¨ *¨„&Á,çŽÅ9z¸Èm®}'Úó슔E̪dNÉ%¢Y'Ës"jNš±DqïÏ™ qÅ IPœ„ÈÜp‰ª1‚Ÿóž§@:Å’ÛÂÞ*†&‡àM²•"EI±ö‚3.8càÚsÙA‚4œ¥�(SÎ\†R¡à€Fð‚yÎ2ŒKÎy]–†¤Ì<Ma$Œ£D‰Ù@bNIiãkªeåÂfðû= €Nª6ºT,¥TIF<²³4RÈ:hÍ*_W¬ ‰Wn4i4¥v$$UŒõ£§1~»¿9^?®ëUxTy§”`M¦dØ…8—íÀÚ°Õ¶h‚my› Ñ(Hå²Ä“�~Œ‚Ý`-qáôîê´Ày ß\A^¡Ô¸¬.z}.}q0´•ÃNhŒ -}àô¼?K8ûæéÑ+höðÏâõqó¦<¼uÃ:½Ådæí‰;TWÀá;ðu_b^ígÖ¯ÓÙâ7Á7};ÄåþÀ%ÞW‰ù¦ê‡ ß˜Wêï5ì{ âïiõí×Ä·Ÿ?ýÈEŽþ7® øã«°,‹·£ÇäQí^y”øÇ€Äcƒ:>Þå»îw0K¨g¬Qq-¬V[?*t¥—ï–Î<Üœ<VÝVà}ýðã$Ê£RÕ“Î3g· ‚<æÒ(w ë³5|y²íåõ¸6$Æ}r“Ö'ÂðÓd½­¡ðt‡}Òï·b}¼4éÔFA£r¬lûíͰD} Uã¤lN7ÕñÐäI¹ªVkÉöŒµ:×óCSþW_<žÖú¦©Þ+Ãå©(3†ÌáÒ˜"cv¿ÔìÄo4&Ýh?ÿ阎BiMÚ¬cpe LÕ’êÞi½³;γW[š•“ìz.‚¨Ý’ÿUgWRšïïÒÔ‹ÝR>7~ëB»Ÿ²cU‹hl½íµÛòÖ¢k-‹#˜à£7õk¿K¸²E^’þOÝöS1ý½`§N¨¦ZY±!M‘וˆÌ™)EÉBvú!aI›Ç4WÍal&Û  X9Þ‘(Y]˜¬¸oÌPª¦ÀR’f™ «˜KQR ƒG°K.µÔVi’X–Rf1ùìç !k-%xtäYΜT¥LzS@-dž0ïÂ0ÍsJ ,œ F×>ÇL¡å–G„2Y Ç2QÎÑ Päbà¬è‰ñÞrA1[ï Æx ¶\½92ZÏÎA_‡Ý¡ä©©ªjÝÊf•EåB˜†ƒ˜œqû"db ÚhΕÚÏàD)Æ)—œsÒJ°w/Ýb!¤9$s¢Äs®3Iò,«Ààå"›"ËŒ8|1^È"·Þˆ9zŒvaÊO’éøºeÒˆD™QV+zs4g—‰å ‘B€wU5Pø*hK¢×l_ÉÐÑðSb•Z/ÔcÓu½C°å8cCŒ{ðy&pGõUX\ZêfÆGsèÕÇìΖÆõÝÁg@áglguh×âÌyàÀ¯6o9< ô«ÃìœÓz‘ºr³^NgÍ|4C|…*¿Î×bð'_2ÁtpêžÓþÚ9´ƒ÷÷á-(^5ûï€Ñ·Ùo~ùí}ƒÎo~ªòoåÃ7Só;Zü^÷ÙÛh=þà®~z‡ÕÇ?k‘óÃsƒÆ¿¦Š/ÿ©¯B¯us ò Ñ_ ›ðtFT Ú¥ ´A|„tÛüÄ–`Fµ_iï¯Ñ/?æõ±gç6}ò“Ü,Ë’¯õ¢ŽbÍKÉkÓÕV8:yŒìéö9_Èæïâ:^Åë¿Ý·šWR°±-p4B%íã)/¶ŠARR5Õ¥6»å3Ù,cý"⤪–­mð/—9®ÕP+ä–æ ‘ÆÕf·¸ùÕ¶›ø¢Y´=næMÉT¡Bòl}Û_z,ÏÙÝj%Vœ{si6^±âÿtÅžªî–ŒwqHw»9‰P²àn͵+ö¯ =½=XWºÆí’;Ïü³°ú”‡š:SfÏKî7pï§ÿc<^·ÊÍþŸ¦+3Ïõu±ñ•8ž‘©ÊúA¢ˆ¥Vñ?úæÌÖ5ŠG" Ãõéxüù‘¹õíœü¥9>q¦K\:±÷Ên­6…¬Ç`Du¤¯D†,«U_ޤ~ Æ²”ÙNÖ¾Á3?jr©¥ŽUòFªT˜¥‹„Gy6A˜Y+*2×Lgcšbö,�È %\÷2eÅ4ƒâ€�㓇q½Ë9™©”M­•‘š1扤φۜ= +ç¼g>nÌ^c6Ö«dS¡S–9$?ŃäyæÌèFê¶­u À…µã^2f–U±\Ýw­Rƒ¯EÒ£8È´—Ü[ ¸ÌRJ%¤b@€N"sFQF\ P„óp Á!2T–Þ#™b&ë¢**iœð$XÖHELÉ…ÌWL‘¡¢„b\ñdMslÚÔvŠsæˆ3¦‰Lá÷ûqTÚé,rö`"†ÃBžËqLCŠ'UE^0óȧ}bÉS4ŽçÒõéz¯Òd›™ ËŒs³Þn•%ßE/'qÜ¥b°ü¡¿Zxhè~÷ów7øõi¦û@=úðElûT<+öí¸?ø-$P‚µ©¹1 nû5tÜcwz|WèM×!7y½DÁp³Åä ß4£õ ¸ô¦*$` T‡wžú ˜¾Fã7Úñ¯;}´ð7o¼¾¿ßÊó{>m¾£ýº?Îú3Iß6#ðŽÚð¯-ïþ1vßßü¸,Ì=ÓŒ­Ûaúåbû¸NŸh&nRo0é¦Ã#k°Ó¸ûyާ º!z”,¸ÀÍÒôÇÇÉXÏjdÕ¹L¡ ¡qUY#×+>zËì…ÝþÍû÷7…ªÙìaÓ9Í!zTû–¹‡ŸÉ²»à›elžš“°­=O¾ÖD‡}Î嬚xrb«µôËÅŠ“ø¸óBÕÅæN 'ñK>ÿf1þ$Ï›º$­ 5çý!~ñrׯ.n»©€4ީղõ™;š)VžµZ3½·v=m eQ°¸OWN_§n±l•.¸ŸÕ>ù¶‡òåæpÑÛĉ×sÀ‹€Ê®¶h^¶ô÷| k?åi‘×[ÿÜì>W/ÕH??l°Ä¶ÅPë[.s8²ë„Ðê°ÿ'²u¶˜©Xæ#¢;º¾ˆn[}Øäv5³‚”žszˆ€ÞÎ+w0\ %5BÑ8- U%Ó€LÉ 9»$ì|ˆ#øîÄË®2hÍ^ÅY ÎE.Ûh´db{)£g`è)rï%#y0b–´H© N²–™ì¤ˆJO ±ÈªôHn‡þj„‹ÄyHYñ(!ÐäŒÌYž"¸*T“}Aaî{çEïar` ÷R)—c$gD]DÊÜPÖ¯ä•âÊè,iD0ùzØ7h\Ü‹ÄdÁÉ)‘À9Ë‚#1 C0dp‘3 ÁàÈY± ¢ÌQ 2ëõ{Ç”ïd]%™³šç*q%b"ã‘ñ„4I?Jp£ªªÎÚ‡;—4cÌ‘¤D‚BéEm&¤˜˜cÜ’d.ê3b™¸c#÷̵»}µ¨öaš_˜àì´Rº!ï“¿Ù÷g)Š„I&ù4RDl¥7Ñz‡)µàbc¶Rc˜¼‹Ž`¾2(—å§vóhkô±›V᪊% #¬ÃF.Xy›æ·MÎÈï•*=Ú†£[  ô zÄäë ³E|ÝÛߥûS¢lÁ·¯óA_7à ¯>,üåw è›ëš€SˆsÐÙý—voðó[yòw2ȸ~{h ?–�áÿµ›øûÒ[oÏŸpìä‹ r¿ÿôæ&ÛÑ›ÂÃ_öxµ|<­[¡á{ìÝõáa6MŸÊõ…~‘Žúíb…ðð å$_º¡ºœ Ïl� ƒøêªæ–­²°®\|—S¼¦Oü¢[Á^¦d<ŽU¥#},ô ÏWéö«°ýtJ1·1‹¾�ÍaöûB| Ri¬ù?–›§Çòi3´)ÄMiæ¡”Y°ÌÌÚµ¡×ñn"ÉÊ%á‚Ô=ñÛ›@õ\V{]â°ƒ<P«ÕéI·HöI;ÑPq|YW™êºF!×¥ñ$¼,ö7›ß$V)°H%¦î;àxh—×&ýÍ•X{W²ë±¸¨è}tšºÿ¶©Ö¹®¦Xfšµøß7æ´0Ú5בýç}ø'¹¼»5),…WB<ÌÅߨƒ‘ÞX=1#¥×… Ëc˜ú×#ÿ}š?r×OÇédÙèRV‹"\v¥�*ß'âÏb’­„TRIfXÒŠÒ4—7Úd¹[ Kiö}æÉN¥L«Õc­ZÞHø"øz˜n¢BºuìÆ—|Š6 pÇ^¬L• 42g>{ë¹c•çE°×v¿%'#ÌV¦ÔsH§BšT�� �IDAT)Z‘[8’ç‰qnT”™2<Qž#›dÙNÃÇ””M+$ƒËÙMÎ o »¿³¦5œyrBp3YòJ¼j 8AôH“Ÿ]°Q$}Ù ­¤”ùµ:ŸÜ‚‘Á‡b�c<QÁeÄà2k;d5‡B:Á—L‚AòFÈŒ¥4S¤”ö…è„A2<&={Å•’•àÁ‹)0ßâ`ä,EÁ­ð>mù4–T­j©$ ¼ÖÓ×ùxpÖÜÖ)…AØ¡»£Jßåºu4ñÝ ®_Цx I#ÂÞbLõ‘l”¢~NºiØòIùl‰ë>nožoù׊ëµòÇÎV½GþÃàW»«¦ÿ•½è“?Eܾ¿AÁ¹m·7ó7y³uŒmnF|†ç3Žô½j_‚û (oßô£°ºDŸ|| D{ø ç€ÿ Ð}‹Áý#ëzë@ñwùÍw4ì»õæ>}òêmÖ!|Ã雎Aô/‡üoZôd<¨s$ÿcìAîŸá´Æy‚'àòÍ@·ƒUþK÷K'=*`ÿØQs¡ •=w{|9¹ÕÝUhƒ"Ð_^Õs?Ú#¨Û¤V–™[)fû¿ ÿW|.³®]Údÿt ;ŽT³‘ì“Áih³­_\æ2¸;fÃ"å>Êñd §9½?rà  |Ú<ñâ¥:*K§ì6):Ú—ÏêwrµEû’M"ë.ë¼ ‘M°sŽVõc³í7µÿjâÅn>«£¼¹‰¿t¯„߀ ‹kµjÖË"qÕ…tØg÷\Dâûj2òÀä£ÇBè´mhç3:U©ìž:u]zß;{Ñà·¬9©¸·ÅÌæ%ø“bõ¸êN–ZÍ“ßMsOwEBu}Q¦“à‹[óAj¢]µ/f½ VÞé!…ìmÂÍP³F?,.»3-˜W•õ›ýþeß(ºÒµ™cÃÙP—ÜCú»<Ò¡á³iJ³É’¢´2 Oõìoô[Œgë¦jéydÐlhM×궨j]r–ÊÑ/’gƒó)€¹\:œdd»j®´©J(Ø9Îv<ØýÌíLβ¤˜Ê,ã”sä‰w<eá*ɼ`…ŠJ$ò>¤ì¥–57)Ú<åd3WŒw ]/…Bgn4›E*’מî¬ò!¤¢T¤¢›(F‹Î^¼ê]Øß û­µ!‹jј:è<2ÊDLF I\Hp–9‘„‡ 0&)ÉÄ‘$rÅx29ÃõˆHÙ0KT¬ š2�ƒˆ ŒXä’sž„“M›–e¬ 2‘‚õyæiW¨Ý‘HQÃET¶MÛJéV­æÜ„~fÜ6ÍÔ”Rõ8´‚”™Û•t‚Í¥óv›âáj,§,ÌURrH‡XŽ{_Lá=_i½‘^7V~ø˜Š¥UUøù< 4wYü/Uéë7¼V«^°ß-¬*v×éòvïq‹óõÖ¯#¤ÀËù;Ž ®¤HüN¥9_«…{lã+Œ{Àóû8ÌØ¥¯Þ�Ç@|ß“ñ­Œµ·Á­øýêÙ[îAß/î~€tÍßX½ƒuxëÕ+`ý9qȼ}æûoY~D5»þþ±µÁg~>0ú戦�ç=$P|€g§ˆ‡8ÉpG.ô·«­ÙâúE^ÞÁàK€Ìõé8#l탻Ûú6l¾7~ho–øTÏ R{˜5›ùÒ_ALºÝîÃQ¤?ˆLK 3cs Yf|‚Üq„ò|.ýáïÒ´¸| ´çGËŽ{·}_†‰¥;ÆMv¿`yísŠlJlˆ²Q8š&Gr7ƒÕ»È>Ë<Ü„±—æìA pÄOæ©ð9xq¯]yûrZš±”NngÁ$2nC|.¬÷¼XÊn! ‹…=Ì”¡òÍ"6Êï ýÓã~zhºÉ'åÕ˼¼´Œ¦éï¸XäMWÖhypaJ·»R½ÔE\ëKásƒ°aËì‹M*{5àŽÿ6Ëű¯çù®5g#¹•”¿0ð‘ÿR1¬õCu¥D0Ým]ФY–YÀdsdìªgFU‰ê(hœåÉ15º#}=š¿;~Z,äÏÊâÄšB+·i— ë Zž¥P‚ ƧȜn ÞçµÉRòHPI>2µ‡PB¬„ªPTÈ‘¤˜ÃÝnê³%QÈä'ãÁ2EÍ©A9Æ}JÞ˜F7’—”XÈ ÆÈ@pþàr´ºåÕîjyl ÒŠ 2ãîrðqÆœ7 :‰Qf†àñÖ/•Tó<º——öò0O!ª¬ŒÒ]mŒÉ1$—(± R–Zr‰¬àîÏ*=’KˆðŽù9 ™$H Ê,÷äRtW˜,ƒp Y™ì eàÚ+$ˆ'bÉçÄ"@Œ%‚”¦ÒŒ²D.f—î2Ÿµ¬ã…:(p¾PªÔJf}538p5“aa5Éy™Ü*:¬TÜ=Ð|‘ûNƃôǨ>—†œý}w9\¤ð·7ùiÕæzUr½aaMž;f³úùäsS^ú'w~_Gõ •7W©Ô®JªÙmVç7[<L¬ù½«¨¯ù¹€?$`¿²¹úœdT3 îõÒ…}ÏÏ#òë ‡ÝW¥0:øðVãÿå[½ùúó¯ï „Ëš{û#½þl&àþÕïÏŸý³Â7ïI¯ãלúö_º6ˆ?ëß!IªïìÝnÞ}‰üuÿ–|°ðßÝÜ)*`oµBýïÔqÄîö$á}ÇžÝMë‹/ÿoÐY]ãºGÜésd%züæ¿X™/>Á‡#p%ª£… ²œNÊÄ»!çæg/Âï;/>ÜÓòpJt%žØ¸"Zø±ø•›±p¨¶òÜ}ÉÞ¿ÞéËZÞÊÍ3Òµó´À .ùêg$Õì 7fš¬{ ý|ϼy²ã ÚÇ_~q@߬–›ã¼oB´Ï ¸:ƒ8Ãx¿—ü8ý¼—Ël–M¶ÂWáöò©Ü­YVî&¿<—¹nîj¼pãÖ¸ðåç­,Lû%׫¡î$?Y¡[QÝÅòlP@:ŒR)«Ù% þ0Z¹c äâñ¼ƒX¥ÕC+ø¬w-í«¼°AÖSåût$äÙûš¡X¹ÞS‚˜ã§øÉcÿ^2Íø€¥Öº)ÄÆòÚñÒ)RyåÿßÿÒS.º­HHÑÅyØëlc¨bÓuìa͇%†›Ïê/>hô¢Õ Uè¢]º†FEð*#³Œ11"0.E®Á[AKÄB ÏYnX^DP‰ÛLÄçÛ8ÏR·,Ê…ðFóÐc2 U(ÈsÇQª,¤TÉø(ö”£¼ž{¦Y]ï–üÑ‚HãY9äf¯RàT²¦†\–r&„L‰Ș¿fJ›8—ÞW½Š\8£RWÖM½Ïž1]@pøˆL1¤¹äðžÆÑBKpM‘Â,ç¹öõ<ÍŠsVŽ+À½ã’“ä�—™sR)³ ë $²—  ÊšFßOé.úçB^¶,hVò®ÐEÑ”>b3ÄÆÅLªTùúµ?ÍS`!“ Þ\:ó §¼ B ©¶º¢X¼gÒÖa¢|!“ÖlÌaJe#Q!RŃDWh¥+¯RŸâ“¥ê}ᆱšî˜bú. ëQ…r±-nP�ºÆCÍFœxÔ ²E±Åè¶ãîpØlqï €ÐPaû5ý;Ñë?¼&ŠÞþx�,K`äeè°»øÓZõ{vA�-p#!�¼ò~—)Ñ;û>(áO½„6Xo@ýM­_g]îG•´?¹6äWýîKH ˆûÚð­»Ý·‹›NQŸ¿šÝwþÜï¢tÂÙkiáK •£Ð¨ø¢P]·]UZþéã©zïäô°ûŸÈ¡]àö­Ç�bÎ~qß×µ/ÝMjyû•·§_½/Ÿ/Ëùr·É+ÞéßX2øx¾óÕhi=)(ŽÚ¡ à,R±gˆ¥û ÿÝ�w]’n4^ïÕù()Éòò¶äväÆ4ã¨`ÔÓ¢i?é´a©ßÒïLÞŠ…ˆ¢¸8†“(jÌ5ø<Í *TbÇÅÕ<•Éh’_Ú)E± [íçÌ!èêÿªN}Šå`õ•÷—KÔ _¿QÑ«¸UxbR³RzQ8W< b}D¿_ãËz5†¬lÜ÷»¢œŽ¹VS²Q¤b¬ÊÃ2]OìƒÞ´¡§}Œ«›:AñmÇ>=÷m–KÙ›õÒ5)æ¿vñV¢ä+MÝ&T&•Ñûyî-í¦á?›Œצø[a¦¨ö¢ \¬‹pü@.¢éޝÛ_0]d_Ð�¦µo”,²KƒHÂ0΃ðŽ»Ì˜Ñ‰J­”‚H)9 ùÄ:-ÆÒ ÁM“E˜tNF{&c†b‰U²H’,q‘Ф%˜È†Àj¨"k#²•>Óœ¤'1>Rjqm\i¼æWÌ3®9K¼p)…08dJ%„æg9RŒp‘ Tf� .ZULEH<B ”¢“¦ã Óð…ˆþ3Cȉ"·sœ]$â`<"Q ÊI$<øRd,9/]½PeR‚'Âc‚µL-UÆsnl)’ÏÜz!æQÌ!Œ’2 bÃegr)yiÚ²îL’nÚOÍ´o§­Ï½Àq»zèÚÊYœMã”ÕB«—UL¹.Æåb²Âñ¤šXÿ»„ÏFnY>¶l¹Uw!âxç›m#R³Xj.ùÌq9”ní«;Î=Q}ùá Þ_³Æð½®s+ÝåÍïn€UñU `ú¾roŽU¶H@‰jÆ{[Ü9¤ w?xC~½vüÛî+R×½ƒÖ ^K ¶žÂÐ��.ÞÕÑ/Ï^í‘ÚÝk-Ä÷³´ý^àþÚ^<ÂË?-úµñý `ÿ'Ö†ôãhÂ[íïnоã2úï<Û» ­ó·œÛgüË|±+Ž^4O?7ëØâ§Z?kZv$ÉÖŸâo^®ð×wz+ý®E—Pìñ›SdÜB ôȇ#¶¢».§8Ó‹ßU/á:¤…NÝi»=÷Ùïý±¿>®uwºçç±÷qßì­#wvÀ™-ý²:’‹O›îØÈƒI_ÌÕ4E¬TSÄLÛÂl zVA*ªÕ?†´Û°¶k%ZŽÖy‹DpE?¨vÛMÍY«ÁœžáSø¥MÚox~è?º «ºkXq`ϳ~±/62q~ÂÌéýTôÑM{<ýCå—’û<‚E´&¨%%s2r\Uù(5ƒ— R‚ªÙCõ¡ñÃCféFâ6…º?û{çW´l·åð_«¼ÝW8àC8Îùhµr¢HNõC^Êq%r+BÒe ?5Vðè™u»°ë¡,ªZÔq+âƒR_mLA]«ýºšL)çB7/¢¡[U¡”€‘LÈÇ0úH)ž3å‚A×´•9Ë™ø0™ÃèlŒnÞ…±Hpwa]Ÿ‰‹¼àµ Æ…©„ð"3¸$%ã&*h0‘™¤ÐRžIX£J<§Bs£øHt7ç‘)Ì*Ê“ÈC"¡©�ŒaÊ$G°Ž¤ËƤ¬Df‘QôÓlyHPÚ4JHW6'íc˜È³0ÉI…œãlI.ã"2SdÁEÏyâ.’J}J}L™ñŽ+¡%(g¥ª‰’qéá¹c \±’)”BE9³lSŠ63o½Ÿª0[&(UH©MbU)›º0u¶Ùfm5†‘¨Ò¢”e=“ÔØ®XRGÜÈö’‹­¨>ÓõªíiJ|àÖS¼â£¿)V©aek›ýpÀãÿ¢ª_èÜ,Ty”“`ûQ\®‹\J}<Õ/×ÕPPkUg"ÇÑ4¹ßå—øS¾OŸ¼ ¡?Ê/?_5—+`|´õe„ (‡#`èQÖ°%ø¬NóNø#ƒ»£G°¹g.5è;0ýšìý ç3ü+¹ñÇ<�æ;S·,]ßI@½v‰Û¾£»×o…ÞŸ®p¾ý¾2óпbBþx¨zÇ*ëO+ ÿR|Ã?ƒ4÷ßWè$°„¿{ÇÛðâ±×ØY»»˜úÓý¡ÖBsèR'¢ú oõƒÕið[§¶*C­±ú—Q;ö¨½^ž|ÎX%Å…ŽZ/Õù²ŠÛZo·b¾Y MSðó Š›ý¸ïhç÷—zkÚ Z],ÛgJ{5 &‡åÈÌÆwfì•ÝmÌ»#Ë ÁCF»V¥‹Û]_psÙÚO#ÌV•óÃæE'aðØŒEÛŸO/åÿéª ñS&øµl/S,e>..›!ãfÞWÒ…¾SŸ>¯Û²89_Ôþ·vÞ%UáDEü¤…SÑ÷«%« TàÞ…?HÑð.˜*W ‰²xĉ‚gó^ós³ø•èªFן›k¨ã‰¿êýZ µmXs^v7’}ʼnûô)+ù ²°ƒàƒŠ•ej*wãôBOè º%ÊšŒ˜xú­¶Ç¬ªæ§Žhb‰–Eµ>ªêÒµ©ØZ~dìRî“©˜â!G7Á§ ‡ÔkU˜F’dqt²'ygínïí¼÷uA!iîÜ•\ !T <$ŸØH*­²–YpO)'EYdÎUÄëJˆRƒ¹v4úYîX$0K«v$˜¹ÊEIL$ŸT‘d‚�Ød ”E–)O.†iÚ¥íŽOBÕ†+“lçÉ“:D>§Þ¸}3…<:îDQUM©’åè1!ûD9„Ìv‰]GOÓŠž®]Øõ¹)æ ÐQ'Éw2™(*S™beT)‹àû�ÏFÏüh)‰’ÉÄ9qZ˺E•<›G?Œþ.óÁeN'ƒ1Ì/öRÓHJ©ÅÞHÄb+«¬ºÏrÉ©ç\åxÎÊkúU'åð|±?üdöeå’q^<®lþþnºªl\1/“²«ñ)üJñ;ï.bÑ£JC]TÖkûÙöÞlî¶Ç8�ÿà=¾vÀHÀÕýÒà±?ü|…ÆÁ ß/y2ГÇü ¸îÁ´}­ox“I&gDüмzÀ¿Z£¼32ùÛôÀwâÍÞ¡¾ ž>àÜ}Š>?ÊÐ@øcI?öøõ_¤6üq-ÆÙ¤>ÞHKf�â× þj,F¤û)ïîu^#M_ÙšfýSq1óOR÷]'~Æù¥J¦(ëK‘žÝÛÃR:­wÜcbªôƒ¿<£5”Äsøƒ~ŒÍ§Çjõ‚L¨”õ™#{´NÄsÎé0£Zx¿ÁPý&¦ØéKiê.Š,Cûë»qy`6-l]ÏSáôbwbîfþô¬Ø[¼\û™³ÕA¬Æýx¨WlþhÏY><¨ÿéΈ?LÏPg "WÊj4õ4ç²±ïЙÌ~vg3PŠbq$›''É ñA–ë\þÏ…CS@¥ë9.¨T³?’¶”·|_ ³ÛJwÎÌ‹IÍ>ç!n‘Fï§>K§}ñ³iŽ"õì™6v5¬sýc]cUS]¿”•žl曆YÈX`ÌÕ{ž/kuÒµe²Ò²}ž ñ ÚômþÇ£Ž–8-ÄyÌ‚ŠçëòáB?rý<…´Ô³. °ÖI=ˆâ€\“5£*SÒÆÇÁú¬’�«fJ^›hdÒÁ¦¹ï{»Û’ÝyŒ;Áú;Ê+Ú‹TU<qÙIHÏšÌC2@B›©"ž|BÌZrÁx-d£xŠ,¤ìI'Ä‚XbÜI$6±l ž…ÖPħœ '¼IˆŒœÅJA!)DÑ;§=쬼Ѣt‚Gò>§ólDX.|?Úà‚ÚQÊe8fàT N9IA*8B¿‹{/®„¹K™¦psåŠÁ’'‘ ˆèbT…B! ȱ´÷1 i 9\ä.€…¦&²šHFʉ”¬8|U©²]°²:H7‡Ð[¬9€H¾,¸Ò§2J%§Ü5Î#]Q"k'{RÕlίÛÚ9ÄM«÷ªÜ.ÚU5”|ÕòQùQƯÀü >Ñõ(øÄh 7޶õÿÏÛ›5Ë™]Wbëì3SN÷C‹EŠ”Zlµ%;BŽp?øûÁŽ£¡°-u«[E³ª@fܛ×ßtf?à ‚ÙùD&òžÌ‹µ÷Y{­µËŽñªJ‡f4«ÌC¶ù®*Éÿ¾t/þ/ÄŽ«ók2yBpžÚ[w›Ÿ=0ß|�‘·;/ Ø{„×k~§7@#ðhÀ½[¤÷ßgyó¼vÕ Àñ{V&«[ÑÓ›ñÀ÷µ´êŒ‡ñ6ßÛ=7ýÈLûü‘>¿» â}ÿãúø?•NéÇßéðMoÆ[Vê÷‡ô9닆ÿÏãÓÿ£ÞüŃO7ŸhSO<MÛÂï Ùiyw¡«ËŽAcSRb¢âU–Ül]e8W¦÷»Gc…#ð0ãeýðúÁ¥Ù(Yï'7_6ñj‰¨¹zé6³Œq'ùÏ·ù0œû3Úxhî ’äövºX–­›Mº×{>ÞQŒæ)ÝXœ8ý·Ë¨®Õ³u5£^}vÞla÷80Æó¯¿<Å«ì»ûJݱ›‹M-r…eUÚªÁ†ô"ª§üî cu“ ±8ŒusZ¯«Ú˜‹ÒÔNÕ¯röiú¯ÕÜ*ÿ©4ˆ&É&O½bŠO–“0òü…»“IQ¤.ýÆ–µc*¦øý)_ƬD•Ë ¾\‡'³—jo±P™;½±ÕbÍf’è£òSï¿8Ìë mTµ¾S¯ï¬Ú,‹q·/q3䤸¶â¿nñ¸‡œ=û7zÛ€‹¼xµÀê–URƨR(K…QÐ ÏEk+›<ˆ½ä1EåÂhô"öièû“ÊC"dA”áY)k™4“FÆD͹æ†Õ¢dp\øÖ–”Š"R…×HuÎ6E‚2øŒ mÒ–™h§¬¤ªUÛ)¥É(1Ò̱xhïht%¥e”AS™Ï!sf$/ešrNÙ§Y”Ú+ë# ‚õnœ—Ó\Fó3?yï‘×`EÔ ŒI®™â" áüt˜æ›D“÷ ¦~~5†gK"áï™q]F¬Ùk®5•ÂŽ 9„*Asn bdÙažòèÉW”Œ:^ZK•6©íd×™"ÔÙ-/§èö…Ÿ¹bw³ªB1VrULI“c¥0rJœêèûâtKr+_½Ìe¼¢O ~9(ù»9ú\­šëSëd{ÿÄ›Ê!…)­onÒÜû0Ç|æ´yð‚%ÉKY÷ó6~Yð0²õú…N˜þÓטÇùË×;s¶À<z°,6=ÎgD¨·K_Ôk·H T�80¾±|O3ÁälÐïø–Ó÷ ß{÷€ÖôxÇQ{¸¶ß�óZê~°Yÿ‡ÿ§¼7Ô?fÑûSpP¿çŠ`Þ¹K½#eòñƒ3{cùæ7Õ`´ÇÕØ®®Z7ÆùjxžØ±¨ŽÔXæä¿ ãÔø-râ“lòýžñû§e+]Xgtêa;TDzœpº¼gÙrÚ]ëç…Aëâäóüü—˜\}ùäÞ{ÌÏ¢*s×vòù²ª†d:žùêÐÚPÛêdVá§K‰©)^¶Bôæ9îÿÖí×öJ²ÝËZÅþ¤û E]Zó©«ìJŽÙñ,wE ¦Åù¸TµHJ¬@cÐo;»Ú½ªÚî>d6°öÚýràÂieʧªÔ’Ï1qvws”Š[«„Xãü¿qu=Ï÷ËÅ&þºñ­#nøÁŠѯOf~¶â‡¢ï‘þô9‹²ÔU¾iùN„Ä¢¦rD÷,‡ºÚ[¶nl¨Úu~Ûò;õåF¶%%–hÉn*óìkÇfࡵÿC&M¢üB–;<›3xäÂd^•³Hsa䲦~q˜g]¦Š·VøviDZR¹B 3›ØÒÉOóâ] ÅPQ2¦*$¥+3³‹¹ö¼–i”¶H¬Æ¢�“‘‰˜Øâ–1.–1¹$dÔŒªÂ ‰C-f£µQ\ˆÂÁK!Ÿ£ÇäK\’yJ!…8Gû˜£ÎÚ¬ƒ÷ev‘ ²b ™+®I ÒŒµ‰JåœR¥f0!`ð&Id)1,,‡Ì|–)ÌÔr¾Že5CM±ò!,Ac¯Iš>Za°V<C†”û%˜è;¡k&xñTb¦ÈØ$HêD¬Ò¡Rje ´•B‰ŒL)ò9¨Ipñ¹ntà¬D—“ÔxR“KÞ‡¥ÄúnT!Àn>¹WYì­z²Ímqï<µÃáëýü2µêLia _ «ûJïœ+³¦¯vØI.—ç!¶Ùëñx?J¬öúA;¼ŠñxÍ&” Ôçôv{ ¾ævº7–e ìÀkÄó{ 3¾Å1d ƒ ÔÇwÓ²oASÁÍôûqéÃâñ:'ãøQà{ýúÝœ†Ïðþ]éêµBß§_úƒ“/ÄGAùø§uß}8Š‘xþ8Tþõ~ž÷ë9äû_C,0ß–«÷ϼ àùftÆ?óë¾~üþÁéië¿õb¸YN¢;ƒ_ý,ü_ñ*ïÚ% áe{öéâ.Bmi̹Y;>7ñÐïPV÷$‡Þ?F¬÷Åsv…žÉêzw0/P‡¾©·AžÏüæiýôß+õi}¿áI¨OU›/ÆöJ³K׫¨iU²‰ß«Ý<çúª+ñ;=6ÀÿÅfÕÕuЇ”æêÅAáŠD¨»;— ÓÄæ”¹MÙ”ëdד ¬Žâ¯v+Þ­Në56m~`ôVˆ1ju¾öÓAQTŸÈؑ˒¼¥Ö(ÖgnTË4r}ÐþPæ¿ß‡_EÉǰoÆWëRºÂc:ÆÉù¨„¥æ²«ª1г+Æw\ýš“˜fÓ™ó+IâÒ)üv¥¶örÕ¬.›FµV&*,H©šðÛ*�� �IDATRb|Å7›î­ä/]J³s™î„².™›<(6“)1ûäD<„Ì“&æG?ÝôÇvXéQ–µ&í¤àÉ—Dq.bñŽ—”’÷X–<»eJÙ&©cj8Y–¸Í½ŸçìO¨¶¸¬icsåÁ–JI ®%cŒã)!,óy<13ÖŠÛà„Ϧd3ú‘uÊu..fÇH±±°äØ”¨OsJÂ;£gað4G9ŸUFnÀ#7vUÇÈhÎ*Èšg&šÈ9¹ÈKJFÁ°"ˆ8å\AêÌy&QÊÅÑ…8!ÍB%Ór¾¾�‚“±Iä8Ÿ(•ÕÔ)E/ 'V1©2Ó‹§qXüü‚Õ+%.PkÆtA›\ü@Œ”МH hÊ”cN¥b-¯É$ëJ°)Msñ.3™s³Ÿ§óù¼¨ÑóŒ<˲´ú(Ò1;û_ä]k„Pe[M"ýæê4Ñò—«Ãåå|ÁiÐ÷â±,gðÇløÚæI]ü;Í͸å“g}×÷1óR¿jª•Ø,b5¬n޽ð¾ý‹–o™–hß ïw1z`� æwâS5p¥=žà¨&ðw¼_S1܃ޮç|¯lÜ®­^þì±CN˜ÃïÝÞðçõEÿ™ÌÙïazx¡¾{Cнï¢$T„ÿþ{L(Àµx9¾è–T<Ä£C'ÁØ,ǧ þ¹ÙÖ¥ö7Šn¦ôªŸlemÚ¿[Ij–ü—ùÅlršÑ{Y¥ŽSú j==3õT]ýòB·ê„{_2OMbÿaH§¨ÿZ|þÓ;»M)ƒò‘dæÎX3'Ò#1}l† †ìpSÌ®‰+ŽÏÍÅÿ-æ¸ùõÅ$/ÄñYõUÐmÀ¾¶‚‘­" îØDyádV¯†‹½‘Ûóít¾¼¤ËÝVî.‹nuWßß­›mÍ[?g¦CRœR(VÎvae©ˆfÐai¸¹[h·Ö7žþiMH¯æ µ›Ée¶4V•û¥.?§º¾TKU\J¹ÈèYþ¿%ÿuPõZIa‡–+bÿQ˜­j>­êOH4¼ÁsSÓ–­?I? mðËó"³T÷yÙŽg¿,ÇÄ’K%¥DĬ¦"tH„4réMŒr‰zÞçk3[&îêNg#‰ñR|Xæ˜S]£²¶‰ñS ÇüãЅƺ ”Òd…ȼn¨Y6ddS]Jê«“CÈ‹9‹Á‰DF¥°è·r]B^§»r*Bl"™!ž¯Ë±k9³ÅVÈÊ„9 ÞsF²,IKë\bÓ̲[¦td¼wÄu^C pÍ$Y%èb Ó9 ™ú¸\k?Ƽ)%ÆœcκΓÔ\dÆ“O,d¸&n-8âuq}fŒ¥ Â9Ä,k‚íŒObjr(€NN-Žûå (”9—\(•väÜ4+¯¢a$ÏYðÄâsôeœÓ²  JÉŠÎ 2Ҥ<s1ié§Wçá0„ÙU!/aWä†_\“3ßpV§p}4iÆr­û¯XšLÿËúàLÛ~ï¾6ñÕ W'{þßtýïçÕ!w»Öê]’—“dí[,ÚOO6á¬yÎÔŸ#=y€ž¼ã={©*ø(Ó[ôødߨü=ðì¹PX?|=”~-fußV®°~Àù]9þæ-*^¿†ÑünFëÇ¡6ǤR€á7ßyÆóÿ®µÁÿ¹S;nßå DÀûo r økǵJ÷€›×ŠÙ÷£ AP4CøÃƒ?,8ÜY ó³¸.íUjžÁè»GÚ_qûsÉËÎŽ}£Î©–×1̈å±™N3NûûÈ5Úa’ÿðÍÖn¨^W]Ýà®|Ñ#kŸÉÕ—+äfÛI~©¢È±5xÑœ¿Ê¬O_}–Åí|9«¦âYüâY¶uR!]͸;õçI¤%…¯îªÙð ]2Š«øˆP4&Ë›ÐL´ùÕl¶÷>ÍO5ûÉO²½´I®ÝšVÚ&ª$/P½YùsJ’¦r3͇t> UHíÍ"Vieâ眈ñ´IºYæ')oîû†ÄÄš¿©Û;&Þ/gÒòPcŒL©b“sØô¤‹žB›¶%Èù¯¸êVwW›®6[%¸fh4Ûl¶•`*ßE'מœ?ûpž¦Ãáôbœ¸°I‰v[ [o‰òxN%œB>Dý$–XÂÏãÒ<‹(éL«±S<¹DîŽeZ)Šd[©KV¶šNI(¿¨Â$«•0œ¤V*@K^/pÜ” Ïg$3Eø¢+JfÄF%ËÅ•/s))5§#‘–ñEãyu"åh %ObnL¦†*VÆ"&&kÙ¬¸ç°dÆò:•b˜ÖÔ™²–¬–Œ K%q_‚-É!U|Qe-’åYR¤¸4p¦¸³q™Mð)E!I´šJÚµ÷sDrÎG'JPŒ6ÌTÉ¥!§Ea6<3ÊL +V‘ƒgçÀ=éJrm„€‰&HJA md†'¤É§) }8Â{%)'-Ë|S(¦¥ ?ëSØŸdà<²3œœíjcjvŠ'.ÜÏhoÅñèÙMË~u¼8a1ÿYù §¢~š§ÇÇ_´&×ÍLaÎ!‹GE·-3ÀÕ5[½Ð ͇ÂÝ™â ÂÃW´VÝb¯ÇnD?UU‡÷ñøüñpK! €«&z‡vßYws]!=Fò \çwÓO= @Ø[ýxX qþvÙ·W¨å©ý<ôGÎÞÄþèƒ}ŒíOªaýBñþML3ngÀâ¯Ê·…€;Àïm¼S@Å/&}‡“žá2ÜÐÎÀazýñ=-¿>`“n¾Áð¿KËek‰Öjî¬Òì^šÛìñ/åðýEjþçMhÒrq¨, þ&úê•^¯yÈëîÇ-9Ë.¶[$å<–›}(\ë…êžËÕ6¦m9zÊš_¸VpÑá£HÁKo¼¼Ì‰w|eݺËA¨|7®†…Øï"ºÊJ'Û°Ô—ØîHk®vŸYû³mýp•./¢®ìÂ;âtñÅ€¤]5¢ŽÂ„ÌDØÿÈMÇŸe~S•^±Ÿ ãgÒ+KœÛgQ—%Î[/Ôv”­uY€3°aŠ9,iO•SùNçΧ»5 3B-u¾¨Xe.~zqU_6²!ÝRwiõå¶®;œ° ˆ¶õ®ï‡ùåiØ/q’†(ÉÀUY§¦’O>>Ù3WÎ…ý$úÆOíÒ³§˜ø²ïlÉ¢òÌ”*ÙÚ%%ó,„6°-|IÊFÚI¤ET‰ñ–¸®¢"IB(S Ã)»ØgíÏ*F¸9 “\lí7¡§ ›\L=eëB˜iI+L¬è>2x9ŽYä2+K„餼°zWÓt´3k^Æ9-qJBI†I A %q°\rrΆ€¼® Tq ž¨.¬šœíG%hJmŸ›’/¢5\äDÎqšG|ž²p‹R 2±ÑÓóÌgš’:bFñ\µÂð¨ƒóa^2åÂ9³Bk;6FT+)j#¸ gLŒFÍ–¹ï…pc§Xrä¹r5ÏE™JR$ߨzÞÙ‰«’Üj!çHÎS?ÌÉ4سήÕAܹûO†².EÐf>3xþÊtWY}¼NS´ìYcê‹L>Ú¯;à|Q/–½¶›M³Ò1ÛSž 5Îÿ ÿ�ÿ®UÖßÅc _¾µU©ßúÍÚµôšy:�‹B~« RÀC¸ÇÕs/_‡$q\§÷;Ñð×þ=0\øí÷4þHé1úulxùÞùÁ¿îË×!÷{qøÏ¢Súc¨§ðPË{/üÑkJzýaù×AMØ*£úöÛß àgà¼4W´)[ö5ö2õ—N»½}ƒÒáN—H8ýìððKd‡/ŸþSëÈèyüÛ‹°»Œ¸;žøók>Çuüú!ü´¦”ã@Çö™ °{KíO‹>ËUãEK‰ªhîñõ’/ç%1îò!wCb¬//>AwQbc~æË‹qÞœ=øé`Ùvèú6¥Ê¯™cº¢roÃ.”;sq ­Kà/™Ø§¸ ½uÜ:61T;2®Rݹx¯ «y½¢Z!ÀKYûÅ 8g_RäHÙ`‘ª!0Å´•”Yàù´ìà×µ©(†%¬ôî$v6’£ýúºÜ« oùÐZ•]dxyHMLõ½†w­çQ“‚­ÑZGÑjÙ #ÍjµÞuëJ­K³“ë ]ëNB¡ŒÇpŽlvs ¡ßž¦©'îV+˺JgKNWWªj¢ˆÑç&C±ŒtâÛ`Ä8¥—%ÓdPåÊĬë`뼪D«•¬ô ‘U^Űñl¯¬"e„1A"™s¶¢T€"n#–kSI®Ø\ǰ $ÀGàTœÈ…sžj+þÉJ•53!JOÎÄœõàJD¨ò%ŸÏ¥$éSYêè%TuŠêZ.‹\8ÓJª¤2†9§6:‚È$"p$°23?»(Ä9 ϱ”)¥ÑrdNiVX[B—’ŽšXñ¹ÄŒcéG?zâ #¿”ôBòe€~”)'übN‰K•Tá²0ÎÀ,XpeÆ Š–‚1WB… &™ˆI;_–$‰q#¢‰eOÎb ",S9«ìb'[5…GM+ŠÛõKÉ÷ýioV¼œtì½sÞÞÙ7þ©.Ÿ×ElÊyÇ×.ו«_Ï÷¢Ó/HV‹gôL·ÌÙêâÙº“(| n¶þŽØssw÷ yÑ`iX\W ÿŠãá-Ø ÀÃ÷ßnbVàKz|†·€$6‡ÀôÝ`¢Ç¯E®·ó‚¢ò{ ŸÛH;ìÞü8×ï†×B©3âôÎßów¼ÀÜ0>n´ >>éG»©C® A=Y R¸ñïž¿…òö…¯36Žþcjc³¾„à8½Ä0„÷ƒGÒÃ"Š[ÆÇ”§q&@�->»ÂE€ê 8Jíq�B8;{ƒýÓ—ùoàEÚï»xdí*ËÊ!êgÿAQ¯Äßp!?-*ãÅcöåÂ>ÃÏr/ç oÃļ2§Ö `7Êå‘. ¼ ..$(u/çQ§T§ûûêÞ²‰»:mÙ°ÃÅ}YjS—Þ,Θ#S¡¸6ø{®ßMº—iÓŒfëõe“Н,»iƒ”Çàãpb“w‹ÄH¬®¨(££ÈIÐÂ!¤ºn•ÊHaÚŠÅ‹ît‘š»—«F$ßµ¹ÖÑ&^­¦è!}œÛ¶‚˺Té;lµܨšUFÕ»$Ra1•‘¬"³ªê¶®WÊl©Rƒ3äÙ-~¿âOHŽ<E¥Më-ë¿ìTn,7ºaÖæÔϾMËÂð©á/‹…‹¤óbÜè©ã"ÃM1ºÑUÌQm¨jQë¬CBJÑFBkâŠ]Œ)F¸äMv‚b%­ZJÆ•‚! 9•bè)NÙTBâLKö™R- K60é­bäë>>ñCe lŠa“1ˆ$}ÉûÉ7|Ò9M‹› “VïxÙÎ9.)¤20AL‰ÂläÄJw1M‹w©(ID’BÅi¶p?;œ´? ‰Tw¢´mÒÖSðe„Ï%%ÐS˜#ø,DÊÒ:­ ÙÂJ2AaJÉG‘IdÊL;V%ÎÈ9>Ì..K§µZsȺ0A^1W²r>Ÿ|IJÞvFts”erä2kZÙ—¾·ÓT¦pަáö§EŽYʱ]87²¥Ÿww£<ç!-¯®ù²cçõ‰˜Y®±0¦~8T÷<‹Õ…X?+Ølýj{f@”s«å©MÇìîÚÀ›zqéW!¢kûÕSKµ9²Î Éc‡JáôLßâòðo;ÆÏÔ­™àÑ»ÁDà<>;Ý:±ìCÌÁü­áL¿y —ùv¡ý·ê wI¤ôA;û–Pùìßë÷ß~o=¸Õâ(Àâ]¹Õ÷S27.NéObq¸uº¿ëÙ÷ üáí¤¨úöH«·GþVA{{TVAj„€¯Ý›t­÷&?^诞PÍSCé_A ဠH(‹õ»ãtˆ ótë¿æÖn€Ç|’ÿü x&Ðlv¨ÙyÞÍÓƒêÌå}.~ÑãtJ¡;Ñ_}£±¶!8oÎa>ÅWA˜~æÍ‹Íñ% YÄF¬¢ùé²O³éô¯sUˊɨF‘Ÿ`™E4y_/ _ÔY ¦ŽÞÜäj:ËÆiÍc¾›b+––{C‚Ã*Swº<‘¥�5 ™!Ub*æâ]?N׳GÔ‚”¨d1¬UEn 9[.e”‚2¤Ð‹EGÌžMÕº¶´ÓR©´!}¥­vW7L­š4ð˜tT*¢OAk}aÖ«jeÛ†ÕT„Ф:UU\›ÈtáÂH! „7H#7Ð`|H/‡`Ç@©ÉÛ­°­U¢ÒŒ*–…à‘Íçŧ8—�6³TlKD,l°Y_I[SZ«¥„C™‡l_|ªò¤F—˜[E–å"T–\/¢‰Q1í ›Ši¥­Ñ¢‹äRc*ã0Lçiñ>¦ì Cæ…"sŽ$BKMZ® EÅù¢©/ÆáE.\¡Â)–d2Ö‘µ¥Ž¦â…¾8 4,:‡8-Y2i¨êØ<aq`NZ#ã˜ãD‰ ¦tŽ¡f‰¡ðì=Ë¡LÊÏqžsîc•΢>"®= CÍ¥p!ù¶°’Eâ&×RP!~faݶyÕp$³`ŽRɤi\¨âZ+‹P©°)s3AÄ(Ãà“£©¨CÉLˆ¬±\âÌ03͹"ž[EJò9•K^)-™d½×ýTf ¨Q~&ÄÒ—™”c‚Û°[Ùñjba<ØÐ7âPRÎäÈ ú:0™§Êy™ׯ–‰"åÈ©è=ÌI�‚x]¢ …•˜|Ȭ)´†–ŸØJ<¢Ïo.ï@÷î|™–ÍuZ!<ßäÃáF¼—Ôâ0 `·iþçÀ%0/± xàÖ¢+cöHoa}Œ°1½éú ßa{Ì-–_RÅkBå�Xà!Êï3‹÷¯á‡I�cl¯0û?¹Œè¿ãnŸ¹Âü^ðH©ðD½?´™¾=’|k+?<jÑh~w¾5&`´.xµÇ§Oa{ ?‡Ï1V8Ü…üí›l^ž£êüUøÒzÿ5g`»Zb†ðÀx«rssƘ0Ÿ‘_m«Ó¥ÜÕ…(ÒO¢Ì‹™ÎýKØú<Ȧž,w˜ªðh}Þó*1÷êôèfXŸW«FÌV¼8Oˆ×j•/Ìêñ¶y [{Òý,å’œ‰ƒ˜czvu­õ+ÖžP1Yë°�©pª$㓺§µqT(E£É좮#KK<Lóót¸í´¸²R ÑRªBÂûÌ—Š¼$SË‚êVðÌ¥gì7Òk[êzÉbuÑnáš"T®å"M—U›Ñ±ªf…E¾¤òºÑõ»ªš³†x«Z!*„‚X�.¡-‡+(U[·»WÓ4{7ŠØ®õÅÃíf·&ÖSIÇ'ï÷Q»R9LKtŧµ`i–tî˜Z×n­KÛRUÉ ê¦/¦±{Fk9ÙŠÄìJpNJ &IŒEͲ^A0 i³h„%’®ÌËtŽãõâhÃà)yƃæ‘s5 M3•<Å)…\Z÷L®$3J€ VÖ´–Ó:Ž Bf=-eS!Uó<¹ä]*Á›ZÔ¦€—¼á¾ÔM’m$mx!’DJ¤Èù\„F“œ<ÙF*¡bŒl­×†W)²àBÉéTfe¶ØH)RM\HQë´ªªT)c,"XÎ!äÁÒ¸ ÏV2—Ã<©( ŠU\pF<“(‚U MÐ|¨‘JÜhNAÆÄÒ8{ž†°L‘Ï!1Ê¥b™•Âl©¬BhDæ—kîGÝ©LÅÖ™–õ<ñOÏj6 q',ë'.}£ûŇK徚L•ÙÎíòÙ&Ý@Ήz7uÓ«9q/¶³Ê¯æiì…ûÉ—|VŠÿB—Ëî¯Àù\j°g̨ æBZØMØÝ`ÞªSðƒ�<°6p:á· ¤7ýåȱm‘ϨÒá„ÇßZtÏþ¶ÑÔ€{C‡ÜozUº½”w]i�¬€ó‡¬þ[Bå�¨�‡(?<XþHÒéÙ['^Qðß[þ­2¢þh ä?Hƒõà‘ °?HO ß–ÜÇG=àú]¡a×=¼f¿Àæ„ËÄ ¼\0]£o�VÀ€‡Ót»lo­<oÕùk¡0Zèç û0[„ǘ00˜qN¨ŸŸ®/Íêò¸“{^sÞ¬ä¹ö˜qŠÌ³õ™ï‰k~CþõÄͦc'Wð¤þo¥–C¸«ÏèÚ{Ÿî.†½:Šý×ÈîÆªZeW—NÆÆÃjµ5¿=5`“«‹Ú4àœG&ÏlR¬[º•»¬†àó\’cÖ§Z†EÊñà^ŽóXsÝñZ*¸QÄs9–X8%¹¢ŠÈF+EEFä¦ô”gؽ±Š©»È;®URÞ×ò¤8e½eüRÈŠJJÕâ.\„á²±¶µ]Ö:¯) £AJ 2ç·ñ“†Ág4”W†\Í7 ݃ÕÅ'—«í/zîõ4ž]nyšã 㤒²ù•v³ 3Ï¢87ÍÞÊs•«’¯ YRÀ¨ÓlBª¤9Zó„k m«8od,{ÊY0¦„¶²ir£‹IžíÒîsÈLBÀ+™HÏQû$æŠaZÒxt{çÃE4.vz½]ÀˆVÒ2^)½ÛhUÁÇ¡ÿætœ‡EZ¦í«XŒ) æ3ÉyNˆ(jU„"’’3¥8¯mǨ‰ÉgœD¥Ï$£™¬`&–¸°"ËÔh­- E,sIe!”9C(j‹ç‘å@¬$%²á²â\2Ë(™P&"!D¶,(Ê—ÌUJšæ€y²¾7\JÛÔÊX!¸ŠJ%X)r6<eÉ$ ‰…‰!QtÏ3gE•X…í5EcÕh&UòîG?Ùä²ô±Lª3ò³:Îs2G+œ²Š?©¾ãtÏÄÒ©]å>ks´eòúÚ×#O/{uÝTj~`·²¨Å…zšnùé^@íÔO“aOXz:¤»ØÏ©p•óÁ”ùã!ù×67(€�zlÞjOŸ%TG(`uz—çIïnð:ÁéøÎŠó\?¿§r?H¨<úýã?bÐ{ªð‡e²~¬vö»µá£¯!á žø/?æÅíó3°zç öíkßMc×ߟ—“s üÓ¦}9ø6¡| ̟ဌç”7¬àëÊü«ÕððÄc¼€ä6àâCd uKKå'‰K]+i™÷ËÝ‹pG®¨ŽmË”™²ÿC^Tcâ~"3ë\Êñ‰øìd"êÏÚ‹nà¿+éz ¿^ýݪ¹ð?)›ÓHþd=bS!T¸šJWÏŒ„ïú‡ó %6>ØmD %Z™ÛÒÔ]‹N0*ÑߌYN­ù0Ocyõ2õI]d]ii½œba‘!gfdŒ†Šˆ.p‘°PVuR d[ â©x&8ã fY‘w³ä¼l%[K&�ï+AÁ²Ta’ŠÈ)Ŭ öš¤ïl@7(ÚÏU,­oEÏ-º«KµÝ(Ý1(–ç+‘c'UD­Šò‰Î‡<eç+Á‚m™*­b¹ôKŽK®tºH‘t‘ºèª(Žm‰µ2 ô)ÙFxö¯›ìâ´,Ó)æ3¼ãe†P(6¦šRÎyˆ  trq™æyœæ1·§PUeÖ‰{IÙ^w]½~À ĵ˜ØWf,Yå‰%N†+OyÉiDZúœcš{›r))–˜—Ü(.5"Ï<q‰0¢$Ï…’BÆcèc8‹”Àõ\˜ŽBæ.iŠ3O𑱗ˆ�K @° óL yŠ9S™ ¢L²$Í'çÍž c¹àºmAIÓUì*OÞK“’p.‰\ ל!¢œá—C MAPEø)ÇHyü‘¦ÇYš(¯˜œ¢ZøIM³é§J¦¼<ÓŠ™«Õ&öçgϧüù¶—íÁ~J*è/röÙ'!]–ôf^­õ¢? ™7£) Å­êBé««åä²ZèW_Ñö°©¾7؞п˜z^‘”e•)Sew™NVy0àôfeÂ-ά€üÖ¼¶‡¿eow>'™î]ÿøNÇ<}Ç­o!êˆïw^|·G.ßÄíǤÎíÞÕàþkôýý½âmHø-U?ýh¡únmø7»>Ò÷ñξËÓ]ÝÚ8NÀæÝ ÛïÿÙžV8¸éSöÿ]ˆ{¨2Á~‰³@ Ü^*\ëwµ®þ4½>ì5Ü xŒá{œÒY=,é1²Ï\i?Ýeú"ðØ5Ý…o6J§Ý°Äø„Î{˜ÆŒ’ã¤B¦k,<TÅÿmZªŸÉß ÿÔÔȉø’ Ÿ2$ÈJ»Qê_—Z±Ê nóP†gòÙ“/ŽéL¢YT¥$Ö~'r÷éÜÆ»dKtp9ê@¹Eªh.ü|DìKœÙ…©:&침ÝR”Æ.Í hÊŠÅ…±S6”Œ&bÙ»èçR)ˆ¬©Nd˜ ª¤uãkÁTMÑ’Ó, )J²Ž"¥8–ä’[ÊY2*G•ùÁïY÷*ïù²È^²“èlV¼0æA~@š„‹¤ ÕBä—⦘oP¾àúü@™ÝŠURïB¼˜‡>1ŒmAË)ÙxgI-­d•R¦P®@š—δ•ËÃ'—DJEÄÁûeúÁç%2–ú±ä@[Š[F©ð“# °9Æ%L²šëLâ0Cžm›-M•F6Ûöjsñ@2:ºp‘$îJ–œ%ÁDv†Ib甚Æ…ÀOÎ0O•NŒy‘8å,8‡)…a.*ÆÔB´wX?¶òå�� �IDATìFÖe¤È«,‹Ä —^Pà$¼ðÙe$ÙÂ%ñB<Åi.²aI3‹¤á9U’Á§â}¼Òàh›ªå­Ì¬,‚ƒÑBÙ‰”UHsÙ—@Œ—Ì2C(eÎ%¦9ö.0 'WxgÄ¢rVô0¤æ<Ð^<?{…é›cY\mÑ=šõçoID!ëóËìW>S>Á²z6»L=ÏñÜyRBwPµbæ:tl¬¥Ð×Î>>}F°Íò\ü;/¯ÆÍZ—çèÎðÿXF¸ø ZÂÜ)ù0†Gë•U‚|LÀ×ÀÐÀOzÂÍ�H!?<à±¹ãùú1¢ÇW?žèówcï¿§!®·iÃ@|ç™ñ#ãHÍ»½—ÿÂðýýýò=n‰c‰ÄëføÑŸ~z» ûƒj¼¹5¼€Üm~¼ýìøv·ÑžÙ/ˆYâ%°Ÿ Àt ùZ‡€°ÀÒݪˆ›·ßâáì'_¢õðOÑ?}-.ü1¼GÀqñ¢—Ý‘w^·luø´[ìÅX×^—ŽñÎ/wËtŒO“@:({¨*ù•šmü2~æª+±Y3›Í|SÆGáz<ôÏ~'&[:ätqXAÄk Uà+ç”çñÅá>t‡Ç_¨Ïz?#&ÙÔWeãúÍpX*k¥ˆQ`rÜ^j´1©%ãÐɈb ¸¦YbšCò!_Ä €|V1ˆ¹d‘öÜæc"6;oXhKPjSP—”lH‚‚ˆ± ä(YQÄ– §ä1͈…G.›LÅ¿I¦|çfþ¶…b£N3¹HB(ëhC‘¦ƒËfïór.£Ë„2¤\ðË4îO‡éf¡Ó_˜©iÔEÃŒ% ¦z ¾{Fvås¥ W:fíOÒ‰ºl7âŠWÛ¤$‹¢Û•ÝÀäSÁã™ .O,_†ó4ßLÉcqðÃ~™È$!eY¤›Û›È–K‚r^ò9ŠEI]Q0/3?P5©Y7ª•† ±ªmW¯’‹¬PAö18‘P˜æwEfLÛ0ƒâi ïÈ£BŠ1/%§H*!&qHz)¥¼?O|ÞÇÅMn²èdéZŸs4…+HV¡˜Ðg¿Ä0&°ÀJ–dŠI2¦›˜=µäb&“”… H‹Ãâòèse%©Òr“y"]˜Ïi°ÑǼ”¬sFR$Ä’ Á¡ôŒ\ˆ” q•°™sDˆ}Q»Ú®J¹ŸRåÂ1ºazáN§%Ž}}u)GÍKW&2Eï&wO$œ² ¼?pù¬É_È+­íƒ£Õõ2ïR çí¨©MÕc‘ö†k!ÙMÌ7®ýçÁ&Ï›¡·}'V­X;Iô>z—€„8}ÅÂZ Ò-{|‰›¤^¤‡Qðõ@µÂz‡cñ{|«“¼ôXcñÏZx ›>XÝü>gÿvæü¤.ÀÐ0*â U>Bã®ã·»N�®ýGÕ©ŽüƒgÑ”mz]¿ûƨ€‡Ö£ö@ð3ZµÛ݉ípýh<Eþ¶æD`è€7N˜¶ŸÞÄ©ßQØz´þ¢Â|˜_‹ ÅC¦`á¨Í••WE\ö¢z =#·‚–^·qÿ×’_€£ÊO_ªÖ an>ý—.ûjíørWÕšÄ:òýÈþyE€>¤å©ðw‡Õ¶qŸ¤¾S/ïÎå¢ýf6kªÛ³ÊíêN|/ÄŸY§ª úv"Ò¥šVR&~”åRåÈ ë$E™f¦­ N–|CB b"12(i¦õƒe;‘ ±Tš"y³šf!©–¬ ,Î%Ë&aXÑH¥LaNœ'*ž„ƒê7|R|óËÏ,¥@éœR $‡cš†^Ïj "!åpîûÓÍ0LËi9÷‰ú¦9×õN7]U S\Ñ^‚[ãX#ØjÇùNäÄçæÉD¬ªRÕ³ñ‘ Cfná8ù ¡ÄerS8áÅ1œÓ)ˆAÇ›y¤ôœÏ¾YBwS–$‹å¾,lqÔÛRÀ®%)ž½§I‚ç¬SH¦}€ÌÃØg ¸’Œ¸°Šb¸,%3ã™O¢V<1Š’sbÁ¥8ûÀ?ž–r^\VÞ/ÁåÙ§DKò“{<åŸ5´4¥"QˤÁ‹¦eNa.jª¤EI3y%¹48%‘%’ðEœcV¢4ABh™ÄÕ™ÑF #BγëGw#¦y lm4תQª\DŒ1º9æ%éIYi®9(Fd“¦T Τáÿ?ooú#Ù‘Ü š™ŸïŠ#¯:YÍ£»)iGF³ƒv€öß/ v€‘Zi%¨[dÉbUå×;ü4÷ýPÅ&‹w·zô>%"óE<÷H˜™›ýŽ œ(tÙÅzãá&¤‹‘K£_ yPN®‚ÖüîjU¯:\l=V„lB¢¦¼ì Õíý‘ÜüõñЉWšõþøL<.LöüzŸÜt ‹šn”«ÃÏŠ[ޝïoëg¯ß¶šÇõwÚ~Áîà 鳯ÛÑm¯kbúyŒ�ºÔ– À´<‡3�óµ£[ì�:€#@Ü@e€1ö#x�A<­¿E#€�@ÄOCƒô¿µøþ9tëoxÞŽl< ÿa¹áߊ?0:ÿÆÏ €à-Š4¼{øït®¿ëV1ÀW¦Êšà£F nÅêòît €¹€�@¨Ü`�ð�+Ø_�Ì�Ÿ€Æöi5¥“ñ²¾T�Ÿ1×€V°=´ë¯~õìl:Ý{SsÈnRœ•Ì N¸Ží«mÄX£Q÷ÛvÔq‡�kPòSݾZZ |UÒû¸œµj>!ÿÌ0苵^ªàq.iV#WyVñ‚Ó0­¨œ»Õ³hs» úLt *YD *È |€åK¡W.—d‰†YØ‹(²aÀª™�@iŒ°1©”³Ë#–¢f#âVIIš\4v¨›‚gDö”D.J«©d "  *E=eEÉÕ¦“‹JЮ { „•¹f™]>úi¦/—Ã+L°¨ÞÛBl»5­”ü<în^]_á÷;²Ë,cc#¥·¸ªÕ”8×Lsì¡Ò€m„$Š2h¿LÞW0ÆrÐK0!  “1§qœŽ‹O±,s˜Òî‡e‰êNêSÜÏ'Sâ…¸m¹j!éR¥­(â¾Ðg\z¦èAYÀRõ4 YOèïÝîË–¥Ù]³K­Æh"YKE¶´4•tB  ŽWPF•3é¾È!—NeTä /ÓrÜÏ8.bˆ…‚W¢”ÎWäRÕ]ßœY·sÃvPº‰J²®Yg…=Y}f½8ÎXSP‘­Uæ\²€ÜCËÊ8¨³¬äÊ5ôJ ,Jdå ͬ¹ ÏÅ-n¹v¡«Å2oV®¶šêP[FR®2iSuE‰ÀO„'GsР)äû`!Ò€ rñxhê‹ênRs{0wVmt»:?×ÜÔ)›#ò w§gûe7¶]n7/Ngw�§<”ÿ¢4œÊpT¼zuåžÔuíN ‹‡Øÿ=ä'JŸŸõÂÛëzù)Üÿ- @ó>ðSÀå¿{3ôª¿jGo@·˜_”WñžÅ©”!|Õ[®àfîÍpZAlß0†¨�ÅC«áß¼ù»‘í�@°À׎@\þ§L!â÷6¿Ï‘ož­}7Æ?Ãú5'ðṎ?Dö{gšý†¾ñ úû€"ì¿ûÉíïAà) {¸ÜÃ�˜ãòåñ‹=<ÐwC{¡/îT‰¸…ƒ„üW°Ö°ŠÐL�òí?Ácˆ«çûÓæƒÝÐz½9=oÖpTÌ ØGH›×òé“A —›‹­^ã¬Ý”P³ BOµ:"{¹¢fÞˆäZžó¤üFý~¢BD'÷¹8C._ø£Û»î1ª~|tô7ŸÉ}>n—Þt^”“lr÷àË4µi"\À%5eXmwï¾<mÛSl‹V ¨xïû¢°¯–Æ` A ÃÆ‚œ•(ÑgG‰’BIc«í U*Äin/ÊZáÑfª,ˆ”`!|S‹Î’" 0¢â‚R¥‘bå YæHÅAŽ%Ö„*e:OvHÕš¥Ö%põ±.ÃBq<ÆQ³!ªIñ}õªBýó‹ãõo_}~ÿYÒ‹xl¬+õ&ÌÝ|w¦Ó íyÕuœÖ.»®Cqa›NÉ2“\Èj"Ùv<!N3ºÓï#„“¬m•à;ÜïóéÈ<É<?³§:Ÿ¹ˆqίƒ#†[+6¹<´é€-Éæ>._âñ7”þCQP!fG%™m¦M_š)ÕëÓxº‹¾f¿±é¬n;U©2ÑEè  4šZ…YÅàQNVFTMMÁašŠßÕ%cØpª�NÇÖpJ¯yfŽ‹ nØ.]'E1P £ã ž:Š• Á‹)gMȧÕ\Žkc¤Ð&#Ï (ë˜3äì„¶V“ œÔ((œÐ)Jº•iUyUCq¢uƒj¨/²h€ •Å” \) ¤*]É”ç: ŒDè÷lN­)šJNÛ’¦nTŸÌ1Dq/ñ1Á'z&º­éz’&¦ª]½›R{Ÿ—eŽPqý!ôk/×ÙY©U…û…»üjå^™ñWíçúk§ W„Û²}k‡ ô—KÓ¤âö÷�Àî(ìèKxêàÅ=ìf Ñ�¨/f€Ø�lÞȰ*øÍw°Dþ]u¦<áE…hØ�Œ�‹è&€ð}Ûþ>4½S³+اw 4_ûíü^ßá;añßX”ëoؾ™´¤¯‚s|môSh¥WÍŒô½ !ñ--Å|eÇôƒ,¿ðÍ{ ŒkXï¡�ØÀê×Yœ¾TvÅWpþȆO«Øç^G([X¶°ÚCÞ„-¸=¼RìÝaíËêÕ ^WXYmÏ£?Dˆ�·Oáƒ_ïÈ\гÓ ÷>Üý¯µ6¢p ÑBÙh^ß:u0YtM·æ«K­÷\8_œï=¬ž×rM¦=ÀýqÁ'œ%¾šÅþµÿxMMÓí1—«í"H½”x“@û×0ò{ñ^ÛQÛ¡Ø’s¹Ï§cä>f8æpëò•‹Š½UÝ´jUgúªìÆY3cŸGK[‹!­ –ŒTÑÊ©à\ÁÇ`­3‰k,‘ aÚ©–UµP Z «ŠVFD€Ê±Ê@µ-W•9fGN.•%V£*HÁª>qJ}1K²„Ä×´êÈ&aô�Óvçê¡Üï^ßví^? $€æ2fäuYš4_-]}æ^€[‡IU'HAšzÛ5r)ª;’´Q‘ÍÈ‚½œ�#ò±.æ�i—]ql³Z–""SÎÄ.Ÿt˜¢Ï.NIM‡_‹ãÃBòjÎíynèc®8˜}ŒN3XîW°±8\…*Çs–c&k­í ¥læ XmZƒÒ•„«ÄUJ›€rÎUø\«)$—u¤œ $•Q ®AH©Š­Ìñ¢ˆ¹ÁmjÏ”09GUFÙn³Ÿ-R‰FSHa‚M̽¯­©'!±ÑEriYE@HY %•ÐI`Î#p±Çƒ_Ž]ak¤ñX0æUP«ÆdÄÜÖ"—’j ’)BT"² lNC¦X׺oZÛ“œÞÍ!—8Iœq“1<³îƒZ®s1&w­3d _5r°–— —´LOLg§ªJÛ®WÂK3mmÛ}TÈÏW˜]óØ/ëüòÒÁb>nÌ£„Ã*«<5ÕñpzzÑÿ—œþöb<ìGÚ�û 4 Jàž£††§^h8ìÂW!f�Ào;©u� Ä;xñflà?7 ð•F÷÷ºð5Ç~mW|�°þúëÑé×]©ò‡kLü¬8¬¿R=~é§`¬?ÞSÚ¾; þ°Ð°¯�Ü7 C �¿wDóUr#€Âo$˜Þ Ü�[¸C| O~ ¿z�O¶ Ÿž¸£}¤}f_&Ø�pÙíJðûüücЗð‹ðçÏók¸Ùkg'T?ѤŸnÅ‹SŠs�x°\}4Nâ¶xSãú0 �™ä’uÄÎÈdÚ?ÛKÂÙ8‹Iš Ô«M¸à,ù q:æÿá—ý¨Ýž€Ðis\6§y-g’{ÔÖè®Ä¦Nõmš«pv¤uìÖ(öc˜^óËïU÷`‰AMj§e³™Ý=¨[]SV]Ú©f”c âEu•´"’2Î\’(³„ƒ¤diK‰²ÏPF P“.¨˜ªdA¥jËYJªEPä ‰E‰Fƒµ‰G6'ž=T\8×£fÖÕ“q ÍAÙYòº.*‘íÛIU©î±³¦‹Õ,y9”ør½Ý•p1…eÇ'¹Ï›K~ØÁ‘²É¥U"Àb�bD9(î,“žK†8'˜F– [Qkä¸x·ìÂQÏûÉæTJ\¬Ž•E™“ëa³wø²%£C[ ½=QÕµ(¿T ®Êø§fÎè bH˜Ô$š‰»Uk*r¶žÛrK¬ÑÑAKR)+pqª¥’„I(åT8r†è$±`1Û’Z%JWU(%&‘iÕt:R¥åb«6lŽbZrÐÚ¸j§Ún.Êuš4™ÜØC'Y!²Ô¨%*Û𚢨è¸=’ ÉEP#”¥föì]ò9D•x‹]\Fúâi"1/eaÈ0ÍÞCž ·P@`[µ,`°¶Â±2]w¾Q‰Áe“Ëá”ЬÚ~¸ˆà–úS<Ê*“ïNÔ¶’Ñ&…©”˜]f²bûH=ôqÔŠóêbüŵ —C®*6LØ;(¿i 4láGbè†n.jZFõÅa9îçnÕ_ˆgËÍ?cL Ï!Ã_)פîΞW ä÷—ã `00€·g€W�À§ïH[g�õN_“ܺ �pp �>û:=´Ðµ0¿Ë…øoÂ?‡—ð}Q·ý®JÒÏ™éþ ¼}âwGß,ïC€�ðßi}uµú…í˜`p°¸{›r+hÿ½;Âñ A¼Lïäø=À **§×`>ácxñ4C¿‚Ò6Óù/4Vé¦üöó£ñ^JgÍlîÌ-<:Eà1À…†›V‹°»Qß^<¸{AåS˜?�ˆ/?Rε÷w±÷C÷°4ë#eÀ•–;£Ådщó¤a|8Ñ ;»ÜvÙ¼NÏZµ¾Bnõînt· žp×ûp~²Yú%¢tC'KB>†¦O©]Y)~‘n[¸Qñ½ šëc•l¯„¿óô‰ùCC»fú¸ƒ­¿KÍߌ´±åRm´Ê®!¨e ¨�;ÕhÙ*mIæ cÈ'ªÎ©‹42†Œ¹B©Ô -³(ØlŒ$Ò¥†Jd"˜ ¶°®¶r‹h)b Õ¹pÏÙ'YÔÈ9—°˜’`V˱™pÕÅ3©;¿¤Ð$ÓÎÚôˆÒ�6ºÕÍ™0«S¡%æÅŒQìæLÏ×é¿[÷W[?„Ae•¯½€Ö )+Õi¢î¼Ì£è[ÞV5¥éÀþ Û j6;J$ö¼»_Â"Û\°ÐQûÜ$_3,AÓAlnl6¡˜,;Q#]ër¡BÓˆ¡g:M)½Lb(ø°P/k±0YÏ´sF.%ç&baQ·'öU)3\báðH31ŠI* Vg9ö™c¡SB4ŒÄ…aOŒ pvÓ<¹¨E@TÀ…°šŒ"—âpña9B´ tD•xäL¼Ø’"y xB†:€WÚ i,éú#ë"VA(¨ˆ‘Ρ”\Àí¦jVE“&,ÎEïjK% J ÁÉîAHQT%  -4è�ª-D*wÒ¢ÀY-' q™æWœžÍ彯šÒ Ç1¤]¸#£Û+mVïjð0òÊÈ/‚±±¢A¾J÷¯Ã ¹1ì-4!›ÕA´$š|Ë1_¼ºÙÁ«ûüÏÉýNǘ� BÎÿØ?¯XìºñíQÉ}wÿx}|:ŒÜTXNÀGøK€�øˆP[€•†×ñ›€ð½ï+‘;�ñ�`þ:ª¾Ð0›oÃSþÀcÁ<Éò“ÚEÿ¦¡…üyóîoæ‰7³ãí7üC ?h½0å°‘Þä?-áééÛ‹ÿúï@óö˜¡ßyª Ä�/žˆO· ž¦§{ú3ìÔGk³¾LV·óË&6{ÿÑkEˆšM ã <Ü^ãj·gŸlÅÓÎ@’½}ø¥EÝjû‹Øm RcnZQ4w£ø§s|˜ô“ÜO­Pú {æ×cÖ_D8¨nÒó™ê„½m >ü5=Âzvnf•Ìaô~AS£Öœá£*›Në&M{¾ßÜáûêéCËú±‘Jˆ³öZë –nvå0Dèh‰F>œLø-ÈO“† Vçüh1µŠ8UĹG鲿³zoÔ¼’+iÞ£V8$yæÛTGÎ +aU§ˆQ[XUÙ*4Ú^×í m³ø.å9ÇIJî©k¥Q©[²rPJNË4íNþF%9öRÅÓlJòç1¤æ¼@+!*¹Èõ´Ø‡\Lr˜k­Zª¶kP·¡:*ɆSLÇ"NuÿßE‚>C»0œQí8=¤v-@tÝü]<™ÙOšRˆlÇs&¡¥æ”IZ”µ"&Öó§{7ÝÆeΩ<ƒ}oTc6ÙØ•‚Û8ÝìÝ–Y´¯°4‹¡_`•3ûW¡ük–ç¥ÚªÈ™Ø´ÅWñôÀÇäêeÁ] ÆAp0Ÿ2H¬d?"LòtSæQ-Ýy#L*.WS-kWÊZMš­ñ^U)0dYªˆµá‹"M•jMs*³yô‹çÑ&寧ì˜eêj1Y„T^WBÊš¢€†P@ÅbR1UvV6`*‰y&(„‚9ÆìžœÉÑï}™¦¢(µT%¡ %5%PŠ2U°8c°iJ˜û¹ÊÄžóXxF'ƒi“’ R²VZäÑ¢‡¢É…ý’V'÷O{‰®–bWG¾ÃÛ¤pW¾œÂ"üR6]sxtGv‰ vq·MòV>y½Ð²?½ÈÏãCx,ῆîl»»ìÓF߯Mºóúnó/àN�$€y‡æ²sPvIíyöµ6\_‹ç–Ï+Œ.àMúZWaÐàÞ »Ý×ï(á­`ßOë …À-Àô 5Às€í¿‡’é{ýˆ¸üCžïÍõ�ï¿KWþ™+ùÆë_~ë±|÷–6Â[nÚïu3¾ó•�€<Ä®ÂYüKÿ¼±zh–ó& -»4R†“tÿy±×)ìzóR-#lêîAsÿ|Sa]ãÆ¿È‡á\¤³_¿¾.ç´à‹^ÇMyPÖCqÜðfl«ï£9¤Æ5róˆž\BJEÜN÷9¨f~%ÐõÔ°xFV]Ô«Õ„‚²Ö„Áõ©¨·@Ü'í9äjÃÅ7r^]þŽå“Ì@¹ZÖÇŠ7î‘ñNëÀOð+ Í6ß-iýßüà‚ iG¿úåÅûÛ®YÍŒ!Ð’ `d°ÓõQâÄ’bU·\Îr…ÂE ì%¤„‹•ÉjiUSõàMW$Sõ«,ÕJŒ’“  ¨ç“÷;ÎÑÃý<yÄ ’ 9ÔK¢»)¬Ç]6ëÁhnJ2yF¼u=ƒiŬ9 Çâ4(a 1ór7¥Ò-¸ÜËÿ<,}§9À%‘-ËÏ.ÐlMSE$—98Kƒ)o´WZ/™DÖ•+jy¹OÓÎ¥Qκ "ÆÕMð½ÊŠ+2ÍJ[^>ˆí¾Pù(d©üPqj—çë´Ÿ“}˜ÈØz$¡ISd ¸,sð’ _ˆ€[¬å0þ–XÙfS;[Ë’ÃÞݽÔr#%ŠŠÅ% 4‰ô”ª®³&E4 n œR©‡O«�YÔR|¬]âibé]‰à _r:,YçFökhª˜‡«ƒ­M‡Fä,R­È Iyftg�1K´\“®Ò˾ÂIÅД}A©´R#¥jHÍ¥ŠB©€N 3TÙØ„Û\�‘O„˜L¯šþ¬ ÛÆS™§ØÇX£ÓÓ¼?q·¨Žá¡ÜŸ|aÑÇ…N!,ݸÇú8¡q£Nói—L!ßͧ‹›Gâ%‚a�œå�Í�îÒ9™îÒiØíûdC‘†õV¼Ñ?¯Ï«úAR¾d€‘ËÎÊ߯ô !œ7\«üé}A€{òòr„ÏÎ"Œ_ÇüªþU)þ`ˆ^¼•Óx·ŠŸ¾M1ûFg~ Ð;ôýlÒÿ,wµúÇž~èú]ùgëxüÀëù»_ÃS€`Žðùw³K Ð}33¹âöC¸zŸ†5‰Êr–ZU,”[aööüåŽ/-maY¶jµŽƒ|zQtM¬^Ûû)<2­½¹œAgÚ‡NÀ­Zõò¿˜Û´À˜Ú/·F „¶häy?ýå±®=yö/¹!ÎÛ1Í“ÛñŽÍ¿<Rï°¾‘ûY®– ØÈüàÙÓ{!î^ýÅ$[¯/ ½4ÐÈu59W”OC¬¿!Ò1þâæFÛk!§Ç‹øk¹ù´y?øP>jûG—WF­š”î'é8§HA0j‘0_‚‹ -„<kÚ3@Ù _o(K妉KÎIÖF(%•<» B®’©¥„–rñ¡Luv^w[Òàk&Ô `aÔç*Jò9ž¼OK¡ÆwùÎæ¥Æý"^» W‹sé'Ÿ:ž¯BÑw¯öÓoþõ“e‰Bà²ù‹I\Ñú\£h²‚1.*WÉ$ô¹§£Ò7„Û“>Yý@v—HªÔN—bë€rbYQë(— ç“jT�� �IDATX9Ù•q<9à²À\š‰U[Ogz–†NÄ÷Bô….hÞU±*-Ç$ÈéÃ}Pêaµ›”Gvc€ÐVª±¯¬²®AÀA«¨Õ3#ÏPÄÊ5ÌŸ$¤RÄÃK:ÌYLw‹ˆEfq¾n¨7›Rd å4§¾¨â‹ñXxÉ^Èjt°ìg¸Kqr rM±`ÉœêkŸcÕÓ•hM«"H#wpXs Ä\ò$8«$ž ©L1š½/žÑ*Sk©¢4Ú¶!Ò=k¨ÂpÁÖ½B©’š¹:Ž9{ʵŠIi‚A„*!ɶíc#‹B!´!£­â8šÃmôI8r¤wUý™ei  ŸAìuËå½FžI┃1ûÚ¼˜ÐÞ‚áeµ•gfzÓp `¿ëžë\<wv;‹‡?ñ›¿tÅϤ)ÝöÕ°>OÿcZÎ!{x”dMzX|fÓB·ÄË.¨Ù¬Ánݳ`/ë"ÈúHAkàà�°{'( �ùŽKØ_«~ïûöM¢•ø¡‚Ø~¥¸”¿‡ý')ýÑ*‚Ü ¿Â¶ÎÿBß8 ï=™D€Ç_mßs %‚Ñ_l YŸÚ3c6t¶íŒ½¢Xɧžñ ׉ç+¨ œix˜¶« ÓÀîѨvÇthÍ'·ÇÓ<ÆÁÕóÙ ð$?iñ1«…éb8ÂZø!¨ejsnom£¤X|ö.\SêTé¿!¯2Ëv²¸/e¢¥ŽÓxýî=xß1o×õc%ÎDîrþÿ6›Æ›®´Í—çG¨÷x£Ï§½è:c/qemJ+?ÿš\ïU³/Ow²ì­¼/Ãz­þÆYæ2…Ú¸Åac‚/…°�±*£×3®A“ÓµíJˆ¾VšªMN„ÎÈžêŠÃgR¥ž1¢L…í Õ «.±„j §\š*Œn  . !ꘉeéb>«ÌŠOY‡c:ä87÷®Þàr\¤;¥³U·7½v‡½¿í–ÎÎ^Ƕ>_n>?ùÂFàö¢|ø@´ƒeÉó ä×V7sá¹–Iu‹¹iå`ìudŒ”ŠÑ¶=ƒ¢ —”Vš{…)Ë& Š`bÕ)†H»Aî0c‚sÀ ÚƒjYTèµÏ¾@p:å5{Ÿç¤ ÃJ_nmé´ê=?‹¸¼ÙؾU/ò”㚤+¦v«Å%bce$á%’Ä#”³«ÑQ™2…cZn—ÕåÊY7öK¶‰rñ¨RͬF]Y­­Ö$DŽØ»èN'Ÿ.RA^ †PSÅÐ=$°XQ¢Î T°�§4.àT ‹e‚P±TVÂYQFÌDFf[µd¬\N¢”@MMA™%eC¥ÂJˆY‰™P7†€ÐÒ¤ÖÐ$ÓJEÑÖ ¥–ȶ— ¥ò!ž’½™Ômø…!¿­{Û)±)­j†œdݦ¦ÏC'P75f_·7©Çî#µV™/lø8n"T†ÅžÅ³³ççg-ïŸó<‘�cKs5} ª!]ýâÖh Ї³0´QÆ“£¿ÌàæO�ØCÔb½[Í(Nu /Á†ïU>b€;ÐùÍwˆ_q§¾G&cV�í7sÃÛB¹ô_sÔ¾‰}Lj´8}Íþ§náŸvÞ �ÞØ¨ñä´ø#iê§}ì¾5a¾ÚÆð”õAßý·ïRþ­lÑÛ™G¿…ôT¼æ]ùô!~ø¾}rÞüµÕ›XRÅ ÔD¹$Ÿ îqt›°ÍŸëÐ_Þ?Htìà�«a=Õ‡÷úsO[@ ü’õÚµZ¸Q.*,ƒ˜[Û¡Uu•«bNË"nvþËI®Ñ+¿v{“n—:Îæï—ÿ»ÎÝ‹:¦f±FZr†VŸKPe˜ß¿Ì½ª‹½›ïº(ƒWÚ“ue yκ® =[�n*ÄAÕUfDŽ|A¯•Óy×,KBòZ—¦„>¤låÒ×Èvo“j“i‚‘TMVB+½„4‘P ËÆ¨Ä9UÇ…JEYì¢d,”D‘5¶Øt¶»€î:z"çSÉK Eb6ê¶Vc’„¢Œò\2Êu,Æ's¾Ññveªp¼q×ðx%|#£wÒØï’‘Q)äªmWE¯ÑdOåp¾¡¾×*Pþ×è^ÏYåY;–\°ä"æptl1ˆž QH~ãB›xÈ…¬¬)ŸŒÐN~º/Óg­<³õp×6kµêú^S¸_çëãÒ)¹jØ<ôèTç4åãâÍfÊ~¡$‡¤Î·í…RÕQh×%…“±è¦â:¥¾°&¯rSÒ!%àjºš ¼ ³ :”Õ}V½TÉú°R$Ûü¨oJé�-W* ‹ ~Þ-îº)ê“ú‰ KêµJ-¡ÂêF n°Æ:£ž–ð>iQ•1ÔW’ŇdNˆõÑõÉë–+ñŒ ² ¢ Q´º•X›ŽäY'B0Ü)QQe¤c¢qæuàÆ³U)€ -ÔÔbÕÀºJ”@P•ˆ`™Úš$TN�ñ²æ©ü£nךLíÐÊ`KÞJ:?)å"«Èst~ìšW©6Xš9<;mDëÜ ?¡Wšü~>™®,ìÛLAP1z'ÈØÏ¸©<AþüoåÙƒR!økxIÁ‹ 0ÃPàþ¸zÛ#ÀF€ñhêmÌYh‚»òÞ¸ÂÃêèâ×&мÃÄ7¤ûï Œ-€P�‡=V÷þíÕ$€ús3Æ»"ÿ¤¹ˆ™ýS9Mh�uü)¬Õònþ €Õi €#Àøú¬+—à_=‡xبr„�ê³xC°LŸ®R¿Êì3Ï%p¿­6Õ?ÚóAq,õÿšTà ˜íÙÌhTóW˜™‡Õq,§‹G»‡@—µL£úÌJeê£sÑ)•аs"7¡ÖêPm/ª ¢°üg=¯Ô¢„ÞKû9ÑÒãk(²£•°Ö~˜ÙmÓïä¼—Âgz‚ÆT°�*Ï0Œ²W28’w&'}cƒË¹N.4]gÚ*5^˜ ut¢?�h˜Š9ÍbXmòÐŒ&²Þ3Uè(YÍq1úÌÌd-G^€Šy]‚yéUÕ­«rMœËIäbJ¬œs¶PΑj…eIuáEÁìZX¡^7ær-JóÂSŒÅÍy™Œ.$…à 2VY“,¡Ê¥j?q7'C, µî@öáÄꞺ{–ÚC[¨ZU(•¬ˆõœñ²€/Ø'™µš¥]¨_•s(óðåÉ_0ÏÕXÒ˜î§ÉKé' •{”$¼( ªc]|T¢•k \–¬‚©ó«¤šøÔe½ùWÓ¦Ú<QÖ¬ ´ÎC¯”Òõ—áü±î×W¨ÏKÑ‘»»ýõ·qF“° áÙ¦¹|Öuô!§Å+ÏÅ\JMEW •@ñ)/<s8Ù4‹ÊÉ¡òY"N2×Åu7¢¦ÕvhÌö¬3]_j3MÅEžB KðË4ûûPŸH®`rSœ >³ŒÚ ²9s#IS'%ÁšÀ'°Y‹‘j‚¹@c’È1Mœ3$—WEt‡XšsL&E&`ÒD ±J ­iX@*e͉²q¬œ¨ÁdQz¢]ÀÞzKH,b>� AB—A”R1‡<dïEÍ–ãV²nôÐ=n·ûs{ð™–LµT*J®U r6÷wP£%Ò2Jš®’Öf;7v+a<nOæý[—›Ã1™½Õ_¤î½3�°;ŸoâÕ:”Ÿ¯É­>{>(÷[©ÝÁBnõèÿw@§—0¿�ÞÃîMI¿‡Уg`& ´Ö±ÄÓK€ød m-ËîU¬ÛwÉYéЛ›ïŒ h÷–ÔöG�Vßæ[À;“íï¹ÞÅ‚~‹ßðïêíóS®Ÿðqóöûõ[iôø3>|þÀÀëýÛAt‰à ¤O!½†é þëÕó{gÛsgÖ ¬ g¶=÷±5ÞÈz¯m<=?å‰Fa]ûÑFѲ ¤ÁêIVÝMK ¬‡ÒòЋÛ6ƪ]àÃR‚ßõcœ¾RŒµÚ\ÚV,ÂÇyŸìµ¨ÊÿóÙ=<€æYÖ’Ö@=†$ü3}Z›>’dÎ Úý­^Ýn…úOBôk:¨ÃúúÖþ½9¹z:Ê/G€ƒ‘­®­ZgñËÆô\n–Ò_džo¤;k×YШ̂eо £õ³Ì-ŒXz!\¨·”%§D.DR¥&‰ @$·äìUõȺr͹˸­5…hçé˜16)wÈä³”Œ”P/)/OªÜöaGÓŠd-Xç¶Vc ”yIå4¦/î¿nÛK£áj` .ÃDfn"Ú/SEjTn˜r¨©ž£h²Åûòù4@°¸ä±9N£Ÿ…öïçíÿ:%u%™j .œæyÎRÈF¦¸5#È n£œÊ°ÞX£Óz/Úû0/sÏ¢­Ù¬ïy5çîYQ�ö6ŸLÜXióÅ9šFmj{Ö¬W+-5WtÁ¤ ãqvCéOÕ%î”Þ®†µì§Qó²÷eIÔfšQT°(\`ZÔ!JÆJÂ2¹ÔŒu¶½ÃÆ)\¹U¢mkÓªUÓYÝöM(¢”q.è½Ì£¬'ÜÈèX½Ž*1Þ´‘xá¨RH>-*nN]'/ËÕZ´Æ>�̉kÉûƒv»#çeQ½öCªÖí9•·BW–ºGUU£JL†¹(TU‹F+uÑä+è˜eNHµ¢fVG¤#ÈBF˜‹+"1!e‹(Y!¦öýL€.¨Ú ù2V¼XõŠ4a]ÀÏ×8õNë–âP¬½SÚ¬ ýÌw¦º÷:PwÉ›×G–]Td†Ïõ@�Ì–z ]Þð^¼wävMÿº4{Wç&}äŃÕôqÛ4P_ ñÜØç\ ®à‹5ÂøÛ¯9h'xbà€Wà? 4æ¨9&�QA”�÷åG¬4õ[?ª_[[~}Š?ÓÓÀýÁ éæ7|›Ðí`�þ'õ}ß=phX~Xvêa„Àá[IøGÓ«7,èo¾‰¸‡Óaÿÿö¿~øDœ}Ô®Þÿ3}>Dá²\wV«&o<?¥•éw£Ü¡JÐF ]½R|•ö;X‡Æ†ÁtB±n¶¤%—¼–××õ àØòcȇ=`W‡Ò ¶½wó˜Òãë“€†uW^nò#HýPÒx±° þn«²¹Áù„eÛó a^¦ùÃ2"]¶gfÌÒ áî *>ßñà?RˆƒÿÔLæ–¤ï”Õkå›6‘އù¾£N©uC²Õc—YBCqqY¸Ót^Ök5WWànQ¤ ©ì™ Xæ\·¤´�“„KEÖ\a*ùœŸ&]Çbe ]BéhÂ�!Äzœè$É Š…šškt…)/$vE`ä!Õ¶L·îvô/¦ƒú#kEÜ^–¢4“šUÓ-­“OhߨR<ùæP®ïìãÈ .‰Úü™¶÷λ¨Î,›”œ³[Š—™S*óÙ ËÆ ]uƒŽå|&£^)è[Õ©„lEß´4tºQZ÷CwuiUS#1µ”Ád$'taKI6È%Ç1,Ó’œ?ŠùB1»,v›ÃÓâ¶ëBq'ÂS/$¹~¾W‡Ý~iji´GyÆ4Cl0TAr¨S½ÓB  rF¤~Hm§¬ÖP°@ª*«tׄXú‚•ì‹�¯g¹E“ºP^c™OÞhYÕ™^+Û´F×êýÑÄœqTa†Ü*Ys¢&Þ®Õ4Ê´ìkR¡™LM©0€Ò¢‰ÅèZ‘„\é˜J ÓĤ(¢øÒ¦ ¥ÉŒ„"ÅX2AÀD D¬ë1v ´JTh¨Ãú»Ë[Å2Õˆ%§Sa^ƒ¶6¥!5"L­[M¤û(ŽYúÃΦ+1øÎX•” ¦SËCZeHk�ŸÂîÊh–w÷ð>ÚXÄüÞ~¹�ª)¹Óðåógà^J—· Á!}‹k•oá”!)ýÒ™MzßL¡=üdKüGêñàkË·ÊÃý7˜¼ßPû®t„þQ?†; à[-©Ÿ‹nzã{ ýÛ÷üÓçýµ$áÏÝD ôì 0úoç†îûŽ_-Vÿبã͈g‰ŸîáÆóCGýƒû±8ì×öLjŒgšÝÝ~wá¶…6ï ƒltÀmϹìK—ªuEëD· Jy¨ç^]ÎS›’áCý9³ÊŸs6^ýc¬«k§áõ¦?æ['º‡1~r²/ƒ ¥<ró¶°Úš3Á à]˜ÛcZ“~ÔoLÖ¯óýmÀ'˜õž´˜Ä¼ÿ>þ]<€î=Y“†Í„Ùê/O¿å{¸œO¹ß‘²Ÿíü.”ó†A¹(â »èñP[‘]£´µ2×0ºš„î ·'›£jŒ)"Ń(Ù•|’eA×¢Ʋ“|_y¦t€†J´De"ƒ \kr(fqîû$9æìUä.pNifÕƒÌ%DuýþÙè3á±sÔB)%%™‚¥"¡ëô¶-’‘ä4üR¢òõ‚JçKšæJÙ‡ýÙf­#·“ ¼d¿Y×NOyÙ…=¨¼’±âÈ3'h{æÖ8QWÑ»‰œêò¨änTFÛF íY§ò ©ÔËj ‹(A0«ÙÕýÞAÔØ¿øÓa—ÇC Ó³,*"5aIK|5Í\kž\I4•L À%p:¼j–Yœ?®Ý:½]™óµ58dˆÅ+…Lº•¨ÄAHë#�DœctîÈN2›¶D7l/8°YRH{z½Ÿ±&ȳpQ¦‚58³‚²l6�µ b+e–Rê(”ê9B¶…I€ªÊà’�e¥˜»RÕ\ªäZ¡6­–ÊbEnu#Q—ââa©²W"Ž’³ÉM à€®mßÛA™k”Œ)ÒF\˜w�Þ¶ÖU_Úñ³–KM” ßçÈù÷ܪ9²ÚIW€ñÄKÅEƒ‰÷þ׃ùoÓùÿ¹…GkPpsµË¿»¾/_mÀž/€QCŒ—.xîÓ|â2!<¼¾qÛG1ò|…cb� Û ùlü­› ½UíM~ž¾9®`b€¸~7¤ÔŸ.Q¨ÿ޵å›~¿áZ¿k*÷®ËýW éÜ#~Þi`õ#ý—á{j÷Ó®Hþ)ÃÓ¯ÅSî&F(/àyü^ìü#Ÿµy«Ú%0(^¼ÙÖpóõvO¹]^îáP¿´‡æÑ¯.¯Š²-,½†8Áá²…h¡¿‚¾‰JË$¡È‹a5S—rç‚9ƒê„pÆHW9ŸnË…ãv%[™N à2Ï ¶`{üÿi{³Í®ìJlŸy¸Ó7EDÁä¤RI¥RuC²[0`øÍü§ðC£Ý-¡­rQTY¬d023â›îxæsü™d&™YdIåû/nÜ{?`í»×^{-ÞåJÃŽ"ÿìn¯Ñ½·èP£C¸ôתp»ÉOB¡CÂCŠºçYÐ…íæÙNÙM-gTŽkTŸ”0þ‰`vÊjeïwés5ïÊ]¶¿¬ªq~JUÕiË¢‰£X�£(‰<NÌ(J$/Éìp^Š_ð,Jq›¡ÅeJÖóRJÊÁÛç\²¡TŒ.Œš˜MÊ‹(=M%T‚C$T•¬U‹¹šS.tD†$f»8…ŒÌ½ êFÙ#ad÷èk¾ê/õß®XÉ r}2ep{`ñ#W-i%—š-¡ÜÒ‚Ž‹ýúŠo�« ×™ë¢(!Œr ž%_Çé¢U—E‹³ÇR„Øi­½ÖlÓREÄ£ƒ\ÌC7Wsœ—Ùœ,›&?Ò>5dµ’lVDñ¸ ×[Äb±Ë¢— iJ^`<3¢;L¡ïi/I!˜ºHÏ q:-czH&…nuÈt‰økNUs…S•ćPñÕvÓ´Z$XŽ }.ÄâBW@$ÇPlŒ½3ÈÐ%yðØøÁL4Õ ¤jÛU×’òÿáLoŸÏaŒ¶Ì*Ìίš†®x xü•y¤1’ÆçR2­Ñ• Hqv"š9&B Z øR|’UÀ0—¢)H+‚(F‚¢‚£ €2G?*<L ×€q&{*cDðì" ¢yQM&¡…3` {F?¹S&É Fv NÓx¿LpÞ0P$âcHÎ|løý‚Îh`8'Õ ¼ÿôÊsCy§æ*­¶8]ßÕ7¶¬÷'-{°ðqzr×ÑË¿ÌØ{xá>¿F�Õ© {³±0>íÑ-ÌŸ�äüè֛°·Oìú†Ã÷=¶�üò¶=ÏO§ÖÙ;(/~ˆhË;)õüNŽýM·T b§ß•'ñÞÝ‚ï멾ýa|}ÖŸ<,ø÷׆?Îjù¹ÿ6ô7þû͇xÛbÏß¼$©f€-p ¾@�O¿÷E=„^t&l¿8Žmú—ßæ†z×К‡ðþúkzb tƒ*ø‹õjlµ¬H^¬Šö?-HåE”†! ’=’"1)³Z=T”¦ë~òvU†®ÞÌ6Û8Ðp²§Ö¤ÝÞØí.§ýÝø·„<p²9„Ü÷ÆO,f“þyç6£ˆ|)+É»T—>.²¿eä˶\1[µÕÏ5ƒ?u2æZO¢Ä²[·®¤ÇÀd ”JF0•ôÙ&]TÆsáCLÉN O�HÜ%\,ΊEÞao}~¼ˆ©ÔÈ= Z-+ê9>ùu,áX� ‰™Å\žp�ì +K¶“ Goo0µCÓb¸‡Kyu×4HT–’&â{,$&º F;”ÝŠ B§Т¥¯?„´©©ÅXF£2ÄSay9ÜsIlx !zfòT[ì‡Øâº¥MÅ}‚л2Ñä‰õfÌ硸'»õwø²ó;D&lYœóG!¡ä7(¯¨BE5ƒ\L1Ùs˜-g Ñ…†Ð»„c’*Ÿíœ½Ž%T,$£O PyÞ TµÖ ®Ç©Ç$p8A²B¸aÅý<+FU2sÎK6ÇzÌ”òDò’Ó„­P‘®PV@•Æ—Z—µ>ª¼T-¬¤_E¾ê©¸1Å~aÌ]ŠtËÔúª “Ý\œá SÖ‰Ò¦Žˆ)Í�Š¥s )ú€2ÓÊAåý(aÜŒcÈ#H… fa.a_Qæ§d2>•ì Js&(ƒÄ9•H}�”)D ö™D÷iœÇО1käõ’«ÅÉÞ;ÀÁ•Œ‹»+¸ƒceŠMT  õ©7²±à;±íoKø`¢ A0õÉÅOáØå½xA?©p÷ó ~F­ˆÃ!#œ�¿¾\qò±Gî¾>Áñ�>¡ÚÁý%>Þó™{,go;5œ(À ·‡ê-c%xWÁh¿}Ý&°çá‡Sÿî÷yóvÞ}þ7Îð)�a8…w›ŸÎñ¿»F5?i‰ãÏÂ)};‡y)Hòߟ£×?%ú[Ø8ˆ¿~s CÄ7›¯åÛñwpMàf~e†ÅA½‘Ø·ÀQxi{7oʸ!ö¿Xí¶©½Nö±‡ùÔ/çû_ˆããH5ûRc­Ú§=hÍ”© GëËMž=^NxLèsðƒ9{'>xÀøNRa5 dA±½¤4arÿøã3«·ÇFˆhù©ÖµBÿxˆ~ŠåÐ[‘/Á~¬‚Ö§rúACnñ|+ Çùïd¿Í©ªiJvìùì*N�µgÕ¦%¶iÄ#.*ù¬šªIxUü6Z$90,Ñ¢rå¸å¾–@í:%„|ªE1õ’Þ• Ç ˜‘Î¥óÔ@œÊ…Ô™›CA”Â]AÁP<ÑÒ' ~Ji†8(õ„ñ fPâ#…—;7>6CzL2c0þ¦Ïí–ëLÊu$å:åg8Ç+Ì ©(«áKw˜ço œè¶ƒ-‰ ÇCLû‚‡ÓDÇÙ¼8 =B¼òBjÃÏNù<’óÓt¤ÒKìúìÙ”‡>ùžq±â°^m.ÖpQi%E<±äˆp¤6Ȥyò”¥D£<GÃŽ'âx†€˜ vZs® †Ã…�cûH²7Žšò{" ˜Ä|•Ó)‰ãE–Œ¨&;ì°ú±@ö/Æg“£=Ø”›€ #ý:f@b>;Aöžœ#j¤pÛÕÃéjSTÕËÜ%±òˆN陯õ‹û]ËZL€¥hÇ vªjyUÚN2V­q+X¡Ñ"ð ¢ XŽ”—‚q¤Ì¤¼„Ä‚OuÆ(ÓL-u%hÂ.¹ÆGa¤3ZHÄÁLeá(„bñ1Û #ÅçCÆ—Ih Ĩʼnƒ›Ó5ÎÍLù&}†åŽŠ+Šp 󢘯áùQ ‚þî@Q0Ìô_(¨ˆ ”ánûFŽ•ÿÅéXÄ:Wi°Pàð �iýª†Qõ«�Wñg§³þ »3/Î|åýËìΗÓ<ÀË€/øø dÿ&³_Pàç74 @ó Õ9¤kH7é[¬[¨×ÚþRëÃûÁ=½Q¿�Ð-�þ§ ¨ßq ï«?-vîÏèÑýéë"øºÐ½¬NäîuÓT¿W’åÁ9ðâM{t€Fˆù-¾l äK_ÜÍ|ç'�€_þÀ¿Ò€õ�=ÜB€<r}}ÀvŸC}y<©Ó—úôÐûjð N*²¿`µ¢—±ðçšØ‹åÓŽ×my &àÏ@,5[8St€úC[6U%:CÎÐbÜòšæû;¸æ,ï(~´üf}JíèHìô)ÌŸ…ó\Äí.…Ø¿*’‡|‰ÆÓ¹‚Ï(/àWdžp€³&³õÂm¶/hEJa4Šåf™6ah\ý5ÌîV‰ª€(7‹Âˆ0š©ÇÆ (4Ò5�� �IDATÓÍÆC¢2UˆbÆ9A6·J¬h¢4Ì–Š)§y hömJšrGÄﺒ×DŽ] 6 3zFÈÃ1—gSã—ÀÈŠÍu(»€­ËÇÈgh¼#—… Œ9)#›S-žJ-êöZÐ ®Ê¾B¹Så>‘;}W˜¶5I(ùhq²«½P|íhÂ2ƒÙ—sz±L¹ì.­èÇfÐQEiǰry)U¢ÔçæÙ]zºûb3UÿêXãýªÑµJp¤iÝ€Rè–¨Z|¨Ú:Œñ|¾½yŸz2yyŸ,bK-s +®˜?ÀD)ïÚ•6 `šøÂ%Q’#’²ð‘§ˆ²wù”êH‘©Å ÷ŒÔöÌ8`ýB&Y9-pB)’hÍ«ªŽ`å±48Gpv™¢úÈSL ±[” ŽÄ’B’Y6úö!Zíh‚ÌôðaÃÙ= îs8÷ü‰Oâ� cNKJ£I&©Þ”œ)–‰gÌ âœ&–K®s.$dìɳ¤(a¸Â…Ø€‚‹cˆ %ÀYI¤Ê8L„ÅàEÌ!F‘Ïœêl˜Yž p†FŒF …Ð$9-$¥Š B0ÉʃMÉÆªgWYs_qóµkÎÔfÁG­3\ ESrqì%Ãx—‚ïÆDOài>‡Ýõʬk€»Ž«©\ÛýŽÍŸUÀ |z _üü¡�L«*ýj5·G(êásº½+íÿe¥IwÀ¼™œ�"p×Ëkn�ùÞƒ{Ig€à$k¸žà&‚XÕpÝÁ óô »íK«%õR[Ä$�$¡p@‡o9¢_€þÞ3HïHM~sìì< �ê{Üп{*œ~¢êÏV^º·ú†×-M ¯žØý¹nþ5<ûîa½Ì¤ˆéQ3ð øs†» ¯ýL8`ÙøG�€Ãë¼Ï×ûÛ�È2?Ÿ ž"x$!­îN æÏˆîobÓ/›ŸÓ‹.€øE™/õ²«bG˜L4yëRÉ ì§šš`hŽÕ’ ÚDÝN]¢èÞТB-ÊdxP­8½Î‹^ƒ5Þˆý7ì“C~ä¬óø÷kÓÔ@~4Qi‚ ‚ºÃõúäWŒsŽVd…”°mjÎFîm}FÛ ÙÐUþ=¾zBæ‹Â’I¬–¶®õ¡ÈŸcޱ—u!Êrš sS»¢d•J�îýšh‘DƒAZÊHÚ¢  ·Yj†1rˆ[ÍP2À'“§%×€ àd¦¤ž÷SY&GaªhT¸¡T 8y cÍŃN?¬ÚØñ/Rì"t$‘À0‰O¹û’MÊkX<øå žÜeIš-R—¾˜}~äqv–ÄQTB`y¦º—•Œ°ãÒCEH‹tHÕq±'û|ï~'ñ#„UzÊÊØþ.#œIÁš¥Tjµª/äååcÕÁ _ Ïþpÿߦœ>ʂر®>´”%Ps?ø{‘Ié’%çh„È(buÖÚåÑ¥#Dœ"à0’ùR�£Æ ‚&±vBQ‘KP«‡-×!j)š8d/•ny…·¬Ø'GKÓ©T—M®TÕ),¨@Ñ{fœ¬1ù„9 ÙÁxoŸßøÓ «Ÿgœ§ÇÅŸûIÊÚ‚“®ZÏqKBD"M©ŽÅ—áŒJ¡®8, ‹Ï¡Èl„¦D’#@´dQ’, 'ð)¬êL(`R™Jì€ÂtX3¦�.‰#§Iá¸[•gÛl¿Ðó7€ÏSº.ñšƒ®ˆÄ„ü�¡®aX†¨êɧ±àÏÿúŠƒò`/NÓÍi‹BzþéŒþzeHAúÒú»ð‰™~¶ ÝÇ<>ÒŸ¥ñ޾Œ5w x GØ ˆ<Kühhn�¼�,ðQY H'áýN º¬Ìˆ{U�ȵ-×8Ãðj˜»x�°D8Gøn  àeŽÐ=ððŠÿ~\|Ç.Â{6ÌO³¶ïkþíVôßRˆçøÛÿxüÖ.é—�5À?ðä½d×wûå` à¿w³=�p ×nîƒÿβªõ€þ¬·/ÇÀ}Û¬ù—_¿õC àAI�HB)ÞBõeyÈüuLÈfUúåÑ:­HU"â‹U4 ¾Åañ}…Šw³ ~‘·ô€%â¡ß…²À&¨„®MéœÚäÜãgß«ié YÕA<T²;ïâ í4ó»píVÒ lWºMüQT2!OÂ}e®ìAVcì›o&díãROÛõƒ–>(H¤–Å­ LÙEÑ:‚$"¼»ëv§ê|É‹5gÏ1ò×Å*E¿:eSÎUô)uJN :1´DÂ1àB !QJÒDÎ (dÆáÊÅ-[SÈ€Ê9ñ•KÏï'bïG6á ÷Bü¾]UšéJØ9ô'‰¿æ•jµbå ø)¦Þ³ìsãFå*Ø}ŸG· >>ÓçxÛ–4Z‘�cz¤z$Ÿ2rºˆIgÏU0# ‡Ô'¿7ç;÷ÕSÔ=¬È;ÑHÕÕ鯣Ø�_±iAbí•ZJÊ$E¥èÕ¼jtÓVRP5J<ÛŽa@%t,]¯ë‹"Ý'oUœÖ—<×:†0fElM(*1û $J9e9Ö¢æIxàLB@–Y‘y·âº«‡íŠ‹ÊD8{©Ø!N!,3žCι0@VÀÙ$€TYÇÅPQÚ f)7Ñ‘€h Ö¦9ŽT ˜Æ\!×5æSt{e7;ŠAžljOɾ¸sMšê‚hhDÖØ× , '&—†˜3êK¡8ùèKBàrjJ¿Àdp<ß ¸B^‘Ù; (™é¥˜èKA³å)(�U)² ÑÍÞöf¼'§¹²t$‰l×mY²g¯­ëÂ>ÇõL×á3J¯xý3šWm%%òA|0¯5ÙèìO1ÅóHÎbs¤ØQÈk…9F,8<¢ÍþâDÞ‰'èAlš„ð´²ß¸óÏÏù m• ¾þÀã?žŽpܘë}uÈ£8Ï41\Ü@ë@ùuã.7ë‹çk¦»‹ñ¤á4ÂI^7ÌÜ`àAßĆ—*O€¯!\øït?/÷v—·ˆýþíŽ3¸ÖpÓ_qô&pÿtøæðÒlüe\‚ùÑw÷ÓŸ:·øÓý”Ô5Иý[8¥oïa@�v�·_¼›ãÞ,kü�>½CLæ{8…o³ô¾#ÕÞ²_ÿ¡,`x¹;þ;€ŠCãÅÐD;œN`–ÄÍ„ª£)œD;ÝUµPáL…Hü*&ª¨ÓíóVÞ7P'RAþï/²-ò «UK¤æ8˜–F äýoÊÙ�|F*8¸t 9½œW%U•­rõBøÚ›ÈÏ`S]ÁŠÄˆˆ+ šx›$L…qÏäþñòdPô®û0· Ï ®Ï‘œrT•S¢Ò %fkVº'…AÚñ=A%(7U %š 6ŠD9Y’ `\tœ £‚GгgŽ¢ Èf }á¬`]*‚yâc<g?§1,~6b<1à)®•‡¶ÓWRÉ­>êx8SáBçF”uà‡TÀçÑ.Þ™–»l“J8œ‰3&º¼¾å¯48N`¼Ä«<k3ò§!ÔÅlà ð8ÇÇÙÌ}ØC1w^þªlA¬)ã~›b· îU{ :+¬ØÄ…PØ(×2Ék§~LR[Á°˜~´yÉmn2°µfm¶ë®]b2Ã8°Ô4OI+ ª®&Å'Em¡Ê„z\’_0uiNØPÐÔ0¬IH�}›z!2g뵨ÝrÎRatIýb——.>¥#¶A%œp öAFR¶Æ…e��.Ù’ü¸L±‡of;•^£ºÊCy(VŒ~|I°Î%0‰CÏàgU¯IÝfÙ©èL9PÅ(#ÈÇâ½ °ü&ëJ XyÂü£›],vÑáRzGŒC³°ýˆçgL¬Š²3Ã4Eœm %94ÕaaÈ‘XPoÆóÉÞßò1Ö~u¶Ø¯D\U¨Ò¬Ïñ0è–¶Ñé/Bi^¨Þ<àݵ "…žc±Ö¹¤iD¿=‡vZ¨[;å\·'O&´Ú•Ç LÍèг�»e®æçqâ+²tÕúžá¯úòŸ„ =ØøÊƒ€[ ˆ÷ AÝÀàÁ8n]K6@*0–{�ôr,ùÝ�,º�è€|ñü]À�ð Ü|ûR+3Øåsß73|™oÂ[‰Íþ] k?ªq�¢¾€áÏB:ý;÷¢Ñ ü[…Á«üø÷ßàþŽéùှñ¾õ¼åñ _ÿú/Ý[{ïT’½ñ{ `_Iȯõ醎þLÀr�°�œ~\%xkëê¯"í&f6Hos)“2 ƒTz…7˜¥‚Õľ9Å'sô’ô¶+ü°)˜±ä²uq6®ñwÏ¡nD:ÈÿCG·{~ëTˆüûI¸õ.ìž& quÖçöa$U10YÊ )x_¤˜¿ŽQ\<¼Û ÿY—ž'¼šÌÇ}1ÿٌϚ5®™BÔ@›¥¨GGTL.ç=ÍÏBe>ñ¯ã²›$ƒ&Sew”ÈÌtæ¡H� “’P®0âX”Œfƒ›‹/ÜÅSpƒµÀaŒ94Lcf&Û8 :ËŠÏøŠ&K»f£HÎ9{WH('JD&ãîz>¡úPè¯ö÷>Ov ·i¥ÕÚÓ-Ǹ+K‰65Œ ¹„‚]Ÿ‰óSè^xs�ó‹|¾¦qw âw6ßãª@¡Pb‹ èqtvɘšR‘J·!rJ;@ºˆóÑݧi*ý É+=Æãùî7ÒÏ"Î;µÚªuC '–ÍþCZ+nRy¥h[«VL%‡RŠSR§™17ÒYÊg­FÅvn1o¸fB;&bˆVÀöX²­bÈlI6Ää!“3lÔ‚ò’Ñ0™oòóIO‰@ô\.þpšÑÞà—/Éýáëœ[Ð Á„… “ é1\!v¹€¾ä»u¥[HU4j¤²j¤ZqBP1…x 6•%¸ñ4Yö‘¨ºÁlsêãÑŸPc0),ÇŒs(¥¶[Æ99#'Ž6)ÔÅeŠ #iާB: ‰i(öÙ~¶ƒÍ#KXŽKªkíÔãf])•5…©ÉËÜfQuóÒærÛÔqÛ˜ŽKÁFM0?øå÷’f.ëº,&D\ëÕµ$ÝŽUõñjØ•´¡àâb‡ç=vÂ,WaÅë{Ǿ<,ð<@¨�6`8Áà9DÁóµ”7•÷ç—>ÚÙ÷pƒÁgÓ‡›÷n¤ì|á^’äɃyÃ95�˜=Èómè™}%¶Yÿ1ÕÍ ñUÄõO—¥þÑã×ïÀó}l}'î¯Ì õ߿߰¼k•ïÇîáË~é LÏ�Ø¿¦Ìü;W?(x k ¯ ¦ÓÖL�Ïo.¾8Â|o ,�š!R�b¹'lT¸Á'Žg>Ør¹…þ~)4ÄiÀ—<ÂÅ\Û§”íIõ—ôáãôit1kwH“;§aï©%5Zÿ/Æ1ú­3µ#?ï· £€œOøoQ‰„¿ŸÀ]…ok¼ßÓ¢;nóü4#˜|à T]w–4“$µœ–ŒÈ”l‚`–2ž à .të4–û }B=–Ñmš¸TìY¡· ûJÿ@¡¦ž»d)Š,ö S¢Â.¸ ¡mij Äð’󼨓Kýœf°&{"Ö6_a×AzÎÐqí ®þw„?É3pü\ë•VSa2÷y)�¹œM±C ZH!ÓSfón†…œf; lX®[SÑmïbëW@'#'¹æ´yÊRYÓÅÃ…*† ê:õ›ïùRúck]ŸXº«Ï³ pS7RÔ!ónDê1‡%ÎÎ$b¢ Õ˜å‹#Š é1²u.¨˜‚±) å*å&1ÐñÌ8â§°.cÊ*á- ¼ïÇdÕ@+F&ÙwùNÊ@¥–›'²É)•ƒIp"5õ—ÌpŠÄK¨!"ˆi®†H&;¬1¢ŠªE8ô³[îïsEq š—È3bWTä°AŽ›£†¤(»hW‘·œ1Á¸"Ø3›ŠªëT­)MÔ[6 æfb Ö;(áÞ.‡ãqèûŽŒ›ô˜Ü¿(.ŸdÃVNÅu@¦/Ù#*"â…‘T‚,•# Ð*ŽMÙ.V|&eª¨/»<"ç‰V3]A1j¥”3W æl[æž2ŸqƒIIQ”1CA®ªÜ¸‘Ÿ_|†>yþ——Œéz"‰ïÈü\×ÛûŽùeØÇ1 ë“Uá“´wt\Ø‹Ó~ž}âàõ%lÿyðøùnýb½Ö3fð‡—SÉôh®v�Àƒ·oh^W�‡o×Óî?øâ5žæ×a6}çýoýÿiG�o~’õ=ÿô¥¶*ý8¥5@€ß"ýƒåüã²ßð^±•c³áÕ]]88={µØ}z÷£â€ü·ÕKc†Öà·�€Ãþ®ƒ˜FØ% ^$Ë“5hHæ‹Û½Íù?1 ›¾–nðç(QO1 H.V;&v8¨Ï?P»ywQ.$jiX¦z¶Y-BÕð±²2› !!LK‡ÍÖ]?‘m}÷ðÐ4ò“F°ø‰?ÉÜžóòÀˆ�Ý9óá3Âw¹4¨n†E¸iÏÓ)šº¬w´åÕœ–¼sa[\w²ˆs Á„p Ôcvé‚'[{¼- 8ž`Æá<ð©c–8¡Œ UÆÏO:Y($D÷‘C’ðx¼ÊIU»"fÿÚô÷‘=Hº9cÜÅaä[–%$±BcÖe~£º¤K¹ …Š–=ézÎ_ÄÍËéòž‰aïÌW4>^*2Ï ðU§4?‰i±h÷—ò/´œ”!r—÷^ø`QºU ¥;ßÕÓªÜrïªô·;.jïP<ù®™Ù¥1†QD‚rDU([TaíóHÊ×>nìø©yt›r€VYˆ)‹¶À½š÷¨´¡\E´Ò²hl‰÷x ç3¡§)7c¤0•Ä˱°;Ú<¡m+»¨µ+>Ù½1B3c¡8`ŸIX¼G³enj0µ¥Ö$c~áDÀ¢9Lwásé!-í–ÒJy$siáQL…E!…”ˆa*™N´ÊÏ«€ æ‰*)ð±óaDÜðâ4|sgOÄßÃi2è+‹ë@ò ðäþ9©I"<¡<ÍMt+5 í½ržW>µ UEg‡8h#%¤¢(úÀ–¹Ë²r 2Ëì¢¶Ô %÷½‹rÒJ^cL´._jd‰`Ç š#Üs…‰(L§ª’:EC‚W¹ºÚn¾V[hšèêî$~åyÜ?ê’2É„dPÁë^,ھ̰œ†�ñW06xµËТ¹¦¾„H×É=‚Ï£öÏ€àßýÊL5 j�ùzm™Âwñ1ûïc| ð{�ÿ2̆Á:€�ý²#yƒáïœøwq9@þ¡—Æ0V4¯¼$î�N?Ñ©é@MÿØ ‚þ)lÔ ¿1ÓxKòõÝ_J}Ÿýéâªïî­»º¥ãúêýþTÜ5T¯Ê£�PÈWбÀ1¿¾ÒÎ�4.4ˆùà |' ÿñ›0¯=5ç°³ü.»© _ùƒœ»FÿßÇù$V·Xo1~BcòÈ›CNz <çîì RL‰õ›óÅ2>tD/>ÁHÂ颥²²»t“ðú^ªcê.áQ7HÎÞ·!0ö£Muõ³på½ô< ›:o¨õŽ~}×´‡üù§ÒéîUC,¿¬†¼ Ÿ jÚš‚lY‚Ü÷ܧL)&…††6iëE)”ðv±@ æÓïN@W¨dQTŽ.xŸì¹àwU…I‡}jñ–ÉŽw¸’½ý?§YE¬ )¨êª™0X!ª+( €²ónFKrW²(YßRðêÐ+Í1T’œb>ˆû9h=gNÄGŠY^Tá\´LÊí„M*¡TՓ飊mW|!ðÛtÕ‚Mu f¿0 ûL¬tH¿q¹A‰/‘$Sߺ!„³ge^’¤7šF¦%Ù\|€rKÑÈ!èäöKñXÇr0•ÑÅÖÅÚí=]#YGK´bÄ–ºX9cX ·tý‰J¬6e2bK¦g¢Ar‹‹Á¶ŸÍdÎÏ5xY?fÕ¦ÀI ¬ë9 yIÄ G( ÎÒ ’ÚĵGç‚Y‰ ¢J²Ž+K®RŽ$§L)cZÜV]ƒçŠ W<áX0)·)"7ä9õýápÜ—IŸ¼wþ7ÓÐLþè­'·–Ô×éb"0#YU\ëŠjUq±Žz·dé¹ )4ËÂ1âcÆ.) ›tñ¹ØDR) ìNI¬VÈãá…·ùv³ Š’lJaŒok<ñmº¿‰G÷lœŸyW¯øîêºMäR¼Kê6QKsÅùÿÌs;¡îÄ?QÝ— Û–*@a˜Æó&œû€ «’?ô8øxÀ^ä¶/ކRÖ:ÌaB`ׯ–¡` � â0¼z›Œ�à¸@^Àó÷8,¯%˜/» p^{×w <hŒC¤?êÀñ¶ˆ(þ}Ñkœ\½Ûï( [� ðõO€ÞñÏ3‹öïâÈN�Ý÷™¬óû,¾ÿ]âªù‡+€i îô–Çè_š“8€Û×ONL�æíáv|Õ†x5Ü xfZ¤×°B¿'Û¨»¥P¿üýp‹Ó-²~·â 0÷àv‡3zŠHGyºLb]ÈóE™¥U½h.õ…H7³ãñÎÙépñ‰¬p›žéóÿ˜žêç“\a ª¸r9dºò" qÝo?Rùò ÅÏI|åÐÞڟϤ¹‘0é»ÃFÇVØŠDÐ0¸¥=cÆG8dçÁû2ÄTÞ`ÒCŒIƲ.±Â4`A=—ŒÔè9Æ¥ÌÌAy[)±ØHqQ_±…H�˺Tr'ÂæÎÕœ ŠS"ʉ֒(®)B(yæC8–Þf‰3¡`Š]Æû|-0æ—‚[Yx¨3þoˆC &ω.,´E6;ÅíBy®¨ÇñCV k&cÁ—)¹Ad9€U´¿•òrê–ãÿ”f—®WgDg#倌<ª\ØzÇ&LhI©V‘o �<cëÀdG(§€]À>Dd\ëŒG\*ªN£¢äQÐìyq3÷‰±¼=èѸ*(3þ‘Á˜äÇØiš]�0‹?»œhÒ(D¼!D•Ԧ蟗Xs’n44¹ÈÙem“+1fbË#–PHñŠ›pô¡¤Ò¥¹^)-p]•ˆ–qÁÇÁg …¦BHdID<âxQÀ! cÉ0Ù0çÞU‰¡€#|”1™»¬:Ù™>®á _m죟Ä= °’+൓m‰¨ÏS3 N’ºâ�ÎÞDìZé]»8Q7×Öœ§LœiÈ~Êð4¸0]r#º†¬[RÉÖ ¶¸b_Äùî˜& AÈ+QW6‰à[ÚaF‡Ò˜°QCíƒ÷ÞlÁ'uhRP¨—ű!Ïüh¬ÿ™>šÇê8‰ó¿œr�ôÌ—P¯ïØéÄ!¼ –�`û 8ä¿ë�Ž�{8¿4\àó ’øìµ^ÿ{Û¾'ßšJ€ý·Xø€XÃç@àôNo¡äßÓaü@ËD_¡ö{G¼Þ™\ô§§ôÇõòy¯ß97þ‘C�ä— Þ†w3”�_,�3€øêÛ}¯VÛœQˆ "T� ßÝz½ß<†2Ãù‹øuñ›¥ÎGN>Å\ z[ÁWéç-yZ¾ŠÒíðW]Êr¿г•Dü‚ø  ƒÈKËx•¹ÕãmZW×37CÝ:³@MŸUB'7^,Ð);7zXú|®í¯A¬) ž)ŽAÊø9ûŒw±.¥ævàk|™8²âñ‘ Ešc2ó0Œ cæa¤ÄÅ%œ]<™~¨Íc7Løf_× :Œ5ýÐ`Æ!W;*¦:T"‚€*ÞSH ¦[}µœ²t¬êð/e®ëÀ)X@:J<&Å*³ð8 ƧH¦6@8wËïýT–°õ„cܵÄqE‚-XŠz'ÊBèšáHAåp‰ÝS$~ÏÕ¬B±I'¹Æ'2ˆÙ¬ž/qñåÑœ§¨˜Yí>%‹(^»#³ã²¸gÏÅà úr§ýö®l’㜣¬ YKÄê,H¦s.Yhò$mФÀ³uÖxé ¤dp!„[ÎP®8Ž$Yår_„÷9” ÏB\óT!%´æR¶‚íf|¥PMü¹ÄÅå»…&JeN• Rí3Ùg„€´2(%\"Æ Ë™&òر+-¶’¯|BÖØýRPî5ϺeH¶€Ǭ0"Aˆ(æª_SÀ8;¬¢¼BÙ;8Ïiž{ðϾë8!Û8ço >Ìb4ÎSÆÆÊO~hèDJ+‘)±lPÅ0(dœ\X†¹KXàjS ¤ÒÏnæPQr!A¨DxÌ—/<&™e[Üže[„|5!¹M›KVQÒÞµè™N§ÌB³ ‰«ÈÀZ;ˆË^'kÎ'À…dÇÆ¹Æ~ù1óWþÿvñá|þ›†I±Ó˜ÿ2§Iò²ž¬ºˆÕ£¯nå£Ån(®7Áã|‚G;h�� �IDAT0À3�ª�I@'ˆ�l™ß¹ž€ßÂ�ðï¦æ_ÍïÔ뿆l0¼\ºzõ烕°ø9QÜÀçï„Ö—RÎïEÝ7®Êƒ�ý[½Ÿyðcpýgõèþ±&@äo‘ÿ„½XÞÎþåõ·/ƒôN?m”€•ýê7 ’á:Ée‘+@ÓîÙÀe«â7(w~eÄÿJë iùh\ˆ,‹Xõ2~ý-m`<²õJ}Æϸl¯2)&[XÕ´ª‹MÈi (¡ž¦«¿zþð¯N¹¡Ž=Èûfü<ª«œ�e§ózU>Ø|)ß“G¨‚—г‡nÍ[\ØNÎíXîK9žpÕFpCœ0,šR¦˜Ï3Â\–¶‹µÎÄ»°àÿ>Âã -ÿ‡•Ï—�˜ÅœwÒp\p& {’ £%®ÄÐ7(”4»Èš§ ’ ÊÆGK6€–C"Â1[[ߘ* ž-3,°2œ¤œsa3WY}¨Ôeæ}À ³ªäLhÉâCçÿ|ÈýÞoyUÕº¬Å“Ì4…È…D¨Êª¸8ó¿dÚ¸„PD<ß6X8tD#ÔTì7¡¾ˆìrÑü€~MÕZµZëÙV Ö“Õb˜ÛWø¼xP §Œ”+HZŒ€Ï  ËÒ#dÈ9É+ÕEna"RÒDÆÌ“hŸå…Vä3*ºD))¿ x#Õ^K„ÚhžOs6¸Ô Èå.¹#”HéKÌÞÇÙR�‰9‹�â%Å9T-nÔpŸâ‘ƒˆuÖÈ7ºš ޤ�‡³Ñ¼²¬Á ?4{R¸FÀ¬Tœ£ˆ­ ö¸ŒeöG]«»¼åaÞ&ÚñÉÞhÓr&z¬á…œ3 ã)„b ª%dÁ2/)ÈŽ`{.k´eŠzHYˆpz¥!’Í„:MîùÞÚóXŽ$­âDñÌË’£‹±¡éªbj+/Ý£‰q±;oŸzröçýpÚI­2¬Æ;LO’tŒ^î¿ÑMsï’I¢ú„îdüû“Yß­Ôuc/7k•¡Ù©Do“ï5â„kzæ°÷€�4ÀƒG`ÿó?|ÕŒðH€ä_`¸BpU]næUøüW듯úWƒM @†÷Bè�F¸xÓÕuúîzŠ�7PAúVËô–ÉÐË0Ñ`®Á‡“ �0�òz’úâ[nï»DÌ›X÷Ç6$þ¨ oª£~¤ o²cò'˜,-ß=}PÁ«à¦×­ÃW�=…a�NæaøN‚[Þ˧% ¾9þã«Õ /ð\I¿.ŸTèW—ß<–ºhM5‰àE¾ØÊªáå(ûfJUpèx:D0‘2Z`,¤�$‚Q RÓ¬ ¤uñáªdŠ]bÈP†QŒðÕ.è«n™ëy þÀÝ}}&îôúäðå# ]©í¢ ‚Æ\˜¸Ô Pþ8ùÍ™;…ÿëÆ¿øíÂFxسíâ€×4³‘ÌDjÇxáuF®D“° Äý¾Ê? 5&$‰{1šœ÷e•UÐŒ  ’$BF®©a?†¥/å•ÀU'tË9Éi¥Pg8v‰u†TÉŒJ§Ìx†,:{{*óÀ§\n±­PÎÓH ÎÍÌ0&ˆS)“L©2¦žÎgøÚí½¾¨¢àfÈn·2fãñ­°þÿx{³I®4Kì»ûb‹o±e2¸Éîêî©îé.5f @úú­0FÀh€z_ÉJ’‘‘±¸»¹­w¿W™If2™EVÕHöán››ç»ßrÎYy™¿:†2ȧôï8þ l|]Ä›Óêâׯ otýq¡`yvâ£BŸP¾Ý±K8к#$²´]î+¢Þ–¼ Ù ½ y´Ì>tØáÙ%wHS·6—ï.HÙXG"Á¨"¸Í*rfPUŽùH’…Ä#Þd!`M1V…\â©gS@ aÁPŒ8¹R€b,¨4%W<¢%¦Œ/¸i‰hI2÷ž/…'[ ÁI7GÓg9G’Bå-F¸ìTi9 C.„I±A€T $S±˜ óìšúǾ?=— ²‚,3æ†ù0¥’¢ˆI•òÇŒ‹ãÝ¢CiW]¥è–¢TbqÞLn¦)’8#tèwDg,‹× AÐP\ˆÎ¼¶M•[¡)­‚__ æÅc‡¿zö<wí„´bBÊ Dá¾_Ôj)¨ÄÛörÍkÃ.‡‡ç9¤üÃR^øjsµ‘U”¶Hd"¹œ².x‰YÉíí 5 ù¹šV$mî ™·éHqw¤hx:å_šôO`ÒÂtòOgñK(^·°lþ ÖOàè`nÀ®H€:Y@¬ 2[>ŸP[ø‹œýœ ü+�@�|~kH)h Ë÷—¶ôÞѹø¯�O_£åËíêM‘¡À�€\/¯ê1¯ $øu„xoHxßš\C¸ùÁþ;�ymÂÌÿÿÐaEà_þâ›÷Ćï™~Cæû¢þ7Àß~/kw'�0oU™A�àkðà 6/ß×£O"y™=|€6þˬþürã>²Z§á ³ÚO<UaÁsx¢âÞn'l [ÔƒO“†?«Ù O4§´œõRô’(u€S@2¢Ç"é¼Ñ)˜LЕ÷8ô˜Å¥’‰ÖŸf®’û¿òaémew—ÎîL‰»"‘ž0Ä OUZÖ¢vX¥ô?s éß\àOò—w¡\}\ñHÄœý ¼Ÿàë�r —™Œj¨ÿ×ó„Ï—Ny)J£ Ä#ñ%°-“™‘¤¸ˆ™¦)ÇB³À¨-‚à:òuP•„ÁÀ¥ï¹·ª6h]™¨PLº¦¢Æà¸[ðÐÇ·°ãÖÿçâþ§‚¶‹gBqš-T®¤ø*¼ÌzòJ¡ôÑïóÃf^sSšúÇ“Ü Ç†¼þÙåïñÓc.¿z±>Û|‘NiÓºž* Ôí|{Ê?Ýù3Ù@Î’É Ù+è(«]$¦Û£u§øa™e Øû™§ñ¹* u¢$•¿‰ãzÈ*áÐ XìTóaýᦾšp:J$Úˆ¤g)f½C•ïÃÉÌ™7Èòà˜Û¨J�Ud‚TI’}2.‡Œ '»€EØ‘@%B>‰A ¥5K{·8×EÄ v±Hbg68-ÚéSUÌZÑ`ŽXHØ+Õ2­y¢ÑfÀHýRFcÓ!ïÑô˜\ªi—ÂiÉ>'W‚#žô)1 E¤2¢ÐFœón'ëFIqEÆ#&aá¶$–½vdÙ$ŠÐðÑ™Hr˜Ls ˆP"[®´F˜Ö“%\´IDu¥øF ¿)±r¥ÙÇœ½A9ʘÞÒMÅ,i†.ßOþ÷ˆÿùWQÛ6M9% àGœOÆyͽxª(ÎâPÝuñ¡¹Eº*ag-XËËܬ¦ ˆÕT,�—?—åµîD»ðào†Cã]Õ9o<¹<Éõàʳ' v�O.aý À €{=íÂ�†eL�ÎðtÀ °î»:÷›Š!·os f ÒwíŠðý¡ØoÅ„Þzx_æåß}þCƒþéU£åÕ¿üÿF‡U¬�î �<¾íÌöé¤÷ÏNá×Þ¢o) €{'<Æ÷/Üg�àøŒÁ¯('@ðu¸¾€l ŸÆîÛðÔdPèN’%­á\³™j¾ÇÌ:z ™MÓã؉GÄ–¬ðÀFŽ4ªÉ‚_ÛR’¨Xi«Dð<äŠÈ Á0H+– í\} ¥Ë�˜àÂê|fpj0žñä«B¨W•g^ùý"„]>Ðø@JÊequ'†!2úù÷+ú×U_Îéü¯ª²Fp‘ M%ᨘãò¬¢MúPT,ӺȦ·'(y²pܧ€J`…à,`’™¿äcHw˜Œ#&ÖÈ5•¤tÅ‘‚K! ¡•–krvÞdì, +‰"g½yìQ‰ë¢q.tƒ–ÑŒ,Ïë»SfW#ïsà÷±É’´TdN—\G݈N£€óŽ~= Ø/™Öå:ýWœ>[ašèúJ8i}RÎÅHù"gŠg_ÏŠãôi®Ï±ç’x&IVh2Žç¸^—\“xæl{¥Úx EV‚øl0?í]º4d3-ö!¯ª-"ÝVâì\nÖu[WÀÂR2&L¡§ך¢º8k ÌÈbeâš%¹‡EË$ (¡‹²/]€¡,‚ ÜŽXVÈ$Œ(e Dv4,ÉûenÁî³ÜVçœ*)ZˆðÈaAºLœ5)‚Q5›-“ÌZëzœÎ¼‹Ë‰tÇåÞôñHàq#Y• vh™p¶ÎÅ#<€Z°î³4­·Eµ¼d¥ÎCvØ£ZÚ¦Šyu¿=Y<QkŽ6|.£Án…´°p¤p¯õj&­ÈÔP©J%—¨øU/6ä£xÙŸ‚VXµ e-¤vnš ØH\m41@'´ª™É Õ‚b?W¼YK,äˆT4¬‰ñ–Šq$‚¢=ÎÉÑk›Îå6# ‰Á]=ß¶×â·»õ Îáé‡IФ1 '·/ñg 0 ýˆÉ¦y¡Ÿœ¦õ&ÑNXpŽ�u9¤-tÌ 0€ ¬—ÀX0 x€5‡¼ûðîÈþ[@¬4ðý»6¢É¿§]°ùþZ>ýèºüG\Â÷ÉÂüõœÕ·C§è÷‰ ïo\¬�ÚWÖ:ñ'JÀ¾g@ e(?dÓúÚîî§ÑF^Õ’ÎN@èÃËC�¿†®‚UO3â(Tþ �«€@ç–¯QSñ ¹;]ëQ¡èoÛIt¦W­Ct?lwóf§oªRù¨îg›6ÆHÆén"¡SßÈ6(T RYHD5(\x.Sò˜¢ÏÒíïsÎlÿ5NFp hYÅêè·lá@þ!Æ¿2 ’½Þ;~Rÿružc÷1æç;ø\•ÿ#änJ§ëéÇLáð«]àÔx¢8gðŸšx�›2ÏÁ‰ô8#J Œqà¸ZÃâ-ÅÉ¥L²™È>±GÎ+I×(^JA·ª0†<F.›ˆF¨�A³iŸn[Qÿ€îœEÝ2Š# ݹªë±‚>A˜þô¢  •’·äî0q<ƒ\?Ę18í(±xÌ¿¤PÎýº’ȆZ¥<*ñ¥F1l¾ÚJk‘) çb`äXªËÑ®)VÎΫVf>Wrå !;Š—LîFÓúlNç­ (®g+ÎN¥¸œçȉV8"ðÉfˆ’ɼT§Å6?`â´(µ<kšó"‹åÑØe'Ò±Â%‚Ѻ2<x¢‡jWÓö‰æJ£I%J(K›£w6£›TgH’ Ó9ÕµËuF„¥@sÁK‘]Çyï¦ùdæS‰'²[/ÕÄ1Åáú¬ÒsE²MC—ɘ1‡¼N’ªêËfµC,¦b0ÖL³ vÊÇ;/„:ÏI]¡ “fç¦~‰S’¬´ Ó,ŸóÔ*±É¸Ì:Ùà æ•% "ÇŒðŒLðHçÃ67+\¥\Ü÷“Gg 2É&‡"G]ܣūAD,ζåë%¿o¦¢2ÙP¥HΘ’ªgu­È p™únì}b˜^±%%ƒaˆÿΦ˜媒5Ã-äЋôÑŽãL`Ö„pé 9Fcäì©k•¡-5yËBr$Û5†Ì΂;Mú…D Ô^®#…Ðã€o¸O L^N'TKД‡q_ø†ÁŸ kV0X€…€`!°$pÀ�(X4Àz„ø1Ip ßq§3?¹{ÿ/[èGò“ƒëðKC¿Zþö÷á7¼¿Ï<ßâîý&J?2Èô>uñòþgñ†ž;Ìn ÔXÞ,_=ƒî�N±g Às‚€r¸“�›ÿö¤v¼i>Ý.?ïî×+î..Õ:L+}•iú²ÄÑv7ãKãb˜ÅiÅtU¯Vš£),'b‹—ná…TnŽAÀdf3'¾ÕDÖØ22¯Ô;/ëEÌmå>¢·/P{Šœ´b^‘`,ƒëããçË$åê¡ái"+í/[Ë8üi@_7¨×¥‹¹Çc6 2O·b§‰ºÔ+êI.s&m,,„’³Ïä¾x‹§èÓóŠé$]BC ™Ù„„�"F‚/å 3‰Ø%´œâTpÌae3Ÿ”Ñ5^S ZWTÄdu”㼌²9ìQ‰‡ŠXbݧ5æ(§ÛËtƧ-ÖËb®˜Q¸ID¤>Pd]Ó] ¾?¦=¯ùîÉØfß"ØÖP†ð4‘6¡r¬aÄ„±ZU£%ì|bg¬ã%ó™7­‚'¦p�ÿ•´Ï(H¤FA1/ö4”ì×!@â‰).R"ÁØ +÷\ÿßUøtƒšL[Öe$§£n<¦þþIVËâh‘ŠGaB(SUE+Ík%IŒt0zv2íìJ|4¡ŸÒ!DR2H§ÛÅ ³Š8,̉ØÃ4/ÓÞ¥…M™)ÍÅsÚ4UÛ´l”v4Ã<G:Æ`œ¶|-‘ô@!ºÉ.ýÐww·ýñèNÜ”9#н‘~q (‘@쩟§Éžµe€#n1V ×"I Å•ŒeÀµÖˆâÌ%iÙŠÅšóŒ%Å2×Q/r8 ðÙ<.4+œ87Ùݤe9&çáLr@¶ÀA^T˜Sb4 U$GNLÕ…ÕDm_d8t÷ ktüØãÂzh±—@’n¥‰¢k«!¡¿…§7@<w½2‰Æ8Ì”$fø–Áª°ÁŠ«e·žMí7_­ úääà³îtÁÿ± ÿy%€˜·Œ—O�apÉÏ“9<¿˜lòa~©Ú](üýKel"ƒ¹¤NÐoωf0Ï…ö¿96ìßZÔÎß*ŠÆßŠ§öj¥¿`�Ï~Œ}ý£Ü€wíKw͌߸fßþò;²âO„}#ö¼å³úF,‡F�žŠõßËQF��ï$¨×Ræ¿Î¾�Øí˜>økò ÿ<îóÍ8Ÿ~îËêÙåryñÐgüxŽG±ì~´òvÿhÆ¿dù ¯v9J5ûØ› ß,CZú‹ÁØ<wž7-:.kbõTWUñÇL.ë’aµmUˆøªòÏ´„¿&u‚æ¤e_ÉUC¡„ºÌ®íoç\É3²¥^hЉtdt9êš_¬´T=ý°à-ôd„Ö±Hi™}Y<T„® eN C‰DÜÒµëª0'%qŠ}€L‚¨”f¾Ni†D�JI)â~‰à—Ú#KäŠ*ÍçIƒLœ£ïSØ£|Ó# ô‚ÁÄ/Z‡ûý–q¢Êy׋äZΕՂ „§…$Ž H¦¡$PÊqÆóJN5¢\A˜DÏÁö™h Íi¡‹‹ÙP"z…½êÞZ/1x!»¼ACáüèãã-Û v«²I…@ 1Å8CJËšóº’)£ŽÒe´:Ãe—V’œ£Ôº[ýðÂVa<ôéðHi6ºi¼ZaY´É/"ç† çn€=c9±² 6!·H‚G•4‚´?Ë!Ex ³’Xp¢7Kq”6vlÏdêë•#•&Š&œŠ§&ZëDvø4Lõ‰ÑšStu½éÿÁÚ3\RQ²*ÐË\£3_¹¼)æI™Vø_(™”«hB–/‡Š\0=àqö!ñ1Š%À%c쥠\#J(…TŠwR­PÉN|`5*¤¸aæòòœ2súšsfuf[Ä©L+9n馈j¦õÁ¡¼¸”F ÒâIˆ¤ÔrÉ=ÎH°ÈvN‰+ê1=1Š ?5åg #–]ÁXælëª!e{–&Yh¨ðž1G"le:zqL îLKµµ y§ƒ* £9øso"ôœìiúÈ?>ïñ·˜F€€ƒû T`{èMv´ÐPåÚnñ!½@¼Y9÷ßû#Âo»y€»—¦6?øõÛÝoÿžÖô›·ñ#Žr¿'¿áýп8¾™Ið÷ 2¡ïÇ‘oéÖþu÷æ'Þ&¦SÆ~IoÜíø· Þ ×�àöå0¯¢&ÇðÙà©ÇxäW¾Ê‘Æ}óÉê6´·§ÚàòL”^Ýwˆ†[òÎv›õTöð…U·5˜*~ŒgïìØ£ì€g'?ÅÇ. h¹rë)_‚ýßbïFêDx5b-GZ-±¨ëHñ6½’v]K‘?_)ÿÀNÍ̵²„¬õIS¶¼Fùg„3b¯"Š>ÅÓ­toôGZú"šDg_ðŒR–Ï9ýTb(DÍ(Õèç¬È@9Ž0ÀLù$gn&1s–%ž IžÞæ°ÌÉ—¤,FS¤ÔeR0ŠwÎõǻ顳ÇuKÑyMS¾ÿ#Ú >ukí=œ»&¾{ÔvSV¶…ÄS È»£AÍÉzôT`èÁìkñië”ê ²Êc†pNç²ì§P@fJƒe0jUʘhSì˜ f.Soê ¸!W¬Y/¾ûC:ýÄš®~Ñè )_ÒÌPvRs®JÓ`„ 5!¿Z¥a÷5µÉõ4ã½™þÙÏÇÃ,¾TÅVðþÈ7 )Ûᥤ\²ypþyÜTž‰ƒ/³ªfMÆMÔ׈TÁºrR’4¹€ ™D›3ÍÊŒ²ZòÐdD£ÝŒ²õIøäíXŒ´<º0!–¼‡6çÕ8fÀ‘h»a˜sC{²(2Ìib˜Ä$‰IÃ)”ÜÏZ-uœKÙàR 3ÊIY}Î@f½”°<t©P ÷Éì"S9r¾eHR”¸6%"‡4A×+NÆlúm=,OC¡ãH§!KÉ‘¸EØ·ë´¢Ñ×L‹YAx-‘ˆ3@i6Kò8tŠîS?ÚÐ&]°K¸PŽÏ¨ÉAáÓâ¤$MJBIúDù¯BžÑìwf™lŸm8Ûc‚Rb¸ð 3ZÚÉj"ÃàóØ»_>­‰LŒØƒCþ×u›‡eÝÍÌ{èä ¹í Àu†rù†¦ÃK©Ó5ÕÛ0EH�‡<:€7ƒúìoá܃36ðwí}Þ ò‡hXïç“uï"þòpÍߦ{7Jý>±á'ÓÙ¾…~ �Î^‰~¼}[þ=Å¢ïÑ­öÚ§ç‡S'°zéñðzí¾xñÖ3z+0à—Ýh ãòÖ°ï%h ê9�À0»ÇôžÛFÿCÊÍ„ÀGxÆÀïì.ðÉù=ÿéÖšŸTí†ú‹&ýdà0Àüô’æš\}X°épètæ£ó_V‘äÂ1Áì󃄗ŒQÁ€“–éÌGúˇ‡1±tßòO©Õ‡jÝøíªo±Ô¼lâÙÂuªr¥È…Á_¾¢BeUCÃY¼ºj¯Í7Üw²t¦ §I ­NK¢ŽYºÏ(Hdùeá2!Ž˜¤Qälr>e(.ÏØXbÉÅ‘3ŽÙºK±" ÈÙ„ÌâUš¼˜ú¯¾ô_yçUx.PÌ´ü‡Œ[cmù–2çØ¨Ÿû¹ß¦¡)ç²jG<¸Äº<Ã>ë}¾6ér9¬?í/\|Ê5S N ‘I-·ú¸?_ªIQ gê#uI`oWÒ×ø³<oQQGö<K<ψ……s²®[Cu¤’³…Ì’…6™ÖS6¨*ÂÅÒŒk+„,ˆUþg§á"ÝxäÐlœ ¶DÿAŸD?@†%üÚž3ÆuNˆÑb4،撋õ¨ê¥p޹OEL,ßb†¥ŽlB‹Jƒ ÖDS)ª&ãD)r„B@ .šQ_Užã™`-¶<3D\îHf ˹ äW47¯ áX0¢‚I)rlÖÇøéˆNÌQ¨ïK²ˆ‘%lJ’¸sÙ„±q°),"‚FͦR•b …CÏv ŠÁT0êhŽ9ßlSྱŠ/€²qÔL’ànM¼OþxTvD'p”ç\ÉRg@}ÈÌ/VTÌ* ‰Š©A$aVöN†ì³Q©ôç¥ ¼ƒeƒ‹Ý.Þ{÷"³A»Šy@ù<ÏÙ`ý(S'7¥K®¢”æÙ¨8¹Ý4 ª¸`r:¦Ï÷¬úP×JH?ΧîîëG€» |>öÐyP7 =ä—„‚¿ƒyd~úJzŸ^1F¸X¿]ÞHá]e ^@rUô|~³õõ’ ¾±Ò¯_IUÿ°íÞÖ¸Û¼<sùÞDäP®ݼöQöÿý}~[àWÌ=8}FxóÓÒÿúǯà•Ðù{KO{€öLª�ŸÁ/ï³oó úÂÝÎC_E~Zj0{0ä¿îÿ Ÿõ©íœ0Eý¥óR-ŽÇû[õWG„/aÍ€KöD“( ªé± €.v/ðõYY Î ܪšoPn§¡Ò'›NR@+~æÓ)BÄÑg‰8?_ds^ÛÓzø¤Õ8RÐz©ê‚œ¦ Óü: èH¹üI–l_³’)•›Xâ B•ª¶Z5v(v@†Ë™BICk–Ƭ6¨"£/’†) Â2/T @37‘n²+ǬVg‹&4µ,e˜7ß÷ÇIÚƒÝÒ™g{Ñ)j\>‹Í|òvZþNôÎ.a‚DGØ6„ñø”éÙ¿Œ¸<å@8Ø›GT»dwóG‹ÑE×`Øׄ²~M‹tùïpÀÑ|f~vÝ Kæ;è×㺩H& Î _¶lœŽt3¸"Ó±8Ï`öJà¶’ýO�� �IDATŽ8ÔÑ 9¯ˆ­š‘Ñ®Â(Š ´>/kì[á%"ŽžbõÀD¤&R!Ž}Áµ¥MU³°9]a-=¬¢Î+´“8/NYp›aÆ2$j“ªx¬’Pò(ÐÜò ãÆGƒÎ| pŒ“Áá)Ÿ1J­ªÈÓgˆ§9L2 Œ¨\)¢É$°%‡éØ’6d¼RhW³VšU)¾ hŒÌGÎX½YaÏ¥%˜1œ3È€^ŠH bfŽÏ{|å€{QÔ2i³næŠl*Ýð̰%c°àÞ†&TJ@¦sHñ…Á•�œôI̼íÜããd–`؉¢‡š¦IÅä—Æ%Z¹œvIã"ø,æìŒfð%&’òz²ÂD¨¨Þ®.„Z3 ;Žá›A§MB³å§iwwbëšž¯–M»@B5­ˆ ¶Å,WX—1pR·€´5ËHî9žCçíó• ¥£ÖŸ>¬ÎF´êýxgÐ-Cðá=<CðoßNÂ{ZÍà&\ëƒÿà€Ã;pô�à�ÎÞ€ïò6»ëÕ°LúÛ—^¡m~33ø�ìßßýƒ-IŸ>½•p¬^—X^ODE� pÀ=ô7ðâ'*óß¡ßð»*ÊŽ¿G=ꕦ^ÿ}vÜk÷}X¿Š üáÛI€Ýv70x¸ƒ ÀÀ 0´�3ðÑ\{Ñ)Ùå\|)Õç9|¡Á3ØØP¸yx sNûÓT?Q =OÃÊ÷}þ¬át+ù¼N’ãõBPqd3cYªÛ54r”³Û|õBøõrÙJ¡‡ÀGGVc³þkòÃêshŸZ|Qlˆ1:÷ Ãyz•4¦µdCwvÖyN.iz’9N"dWf_î¹À‚û v2U©aX‚®dëˆÃ¦Pª)EI²CW4%’ = Ö‚r¤xìÑF$ÉK¡Pf¥• hh<]| UQax’(0𩌨$ l†yÝò/fŸ7%†HE8'»çÕ›§~~âÝ?M"ÐÒF$ýJšd7¢`„$®ÓtT‘™ˆHþ«[öîðá+›u‰ø9…ÞºèÑq‰ »ÛØO>&çk'~hÁ3I7K0*c_ L p&0æ0Ýdu˜u ´Ûâ¶%k¿;M¸œ6!0ãìÓ±å˜!WAÄçŽ+†³+§cöÿ*<“—WEiœÑH™wç$ð–bd‹˜]²‚€’ïK’q4ØKT€«qTH‰)C&H®”” §ZVãp¦K¢q‹H•£ÐuU N,[n úByŠÒ‡ŒUŠW¼ÁŠ*Fר”™ÜÉxéºM£L»r’w8Vy¤9b ÆÙb&’Ji¥Ò²ÎpÁ(6hÈ»ÚÒÆÀhÁ-CI6>{ä{‹wTÒ-RqáõBQ¥´fN#¾"ËG!±XX x´9!›Îé\1ZÁ4"%¤TJö³�ÅÞ]TGˆåè†.tËWç¹j]VW­kVÅ…‘4g³Ucd)q¸:;Ób‹Ž3 ñu_ç–‡-1×ãä&J7Ä Ü ^¤Â…ÚQ9Ue§FZcO+|˜ô°¨¯Ÿ_õ˜†3ÔHoÒã~ž±1ûDUÍÄ/Œû^¼Â“*ºƒ£‚`S] xobîÛp”���yãs@ÀÇ×û\�8à'ð/›/€�¸{�wðjZòîÛ´ƒ×`Û�¬Nßëã^ܘWß~ˆßÉåõi–—7ñÓ-ä®ßå¤ÑŸš ¼¯!Ì@óýŸý{rèÞI¾Ï`xYž‹ßu‡Þ8|5ƒð/]Œ4¼¢\`€ÜÀ™‡ §‚®pÀà €o�dÕ‰0›äñŽÏþÏìa‡Éh‚ëá?°z'™ í!“u=ŠÔ©… I,‰:Ñ›?„QÀ˜ þšÎ‘ÌŸ7_ŸaΆÀn#šUå€ù¯(ù¸§Õº%—‘¤Ç r ûB¶‰µSŸ§¨:cP*´-iZ° èž…;DK -Ï@5œ1TªN¡ÄÆ’ ÞÏñœÉ"}©„á£cŸ ªWHÄi!š"©8�‡yOj¼”„=j,2¦Œ1�Å@’ܧ었úùþn*KgáN_T¹ uÉ›C¡9ÓËÚ–º•ü¢*×ÈÔ´b²ä̰œªjÕ9 'ˆQ! gÓ:uD¾À²Bd…Ï×’v½}±¿{ä8K'ìV°¦?¿Ü>åaÒ¥  Š›œÔ2¸Ç$½<}€RÊö«àîüMíÿçÄ3Fð/ ÿ ª´[6S5ÝûŽXÜþÌVçË9Ǧ|ö£]ªÑKŒ& >?a¤‘#œÉÔAÙdl¥+Bt,:ƒª‚­H +€]kQ; ŒL C Þ�Á£UK²Š"Ö8b\ì2;q`jZ0b Ÿ·1׎ ,M™ §3^뤛ЊšT«*V A:æbȶ٨ “® ûä–i¾Öa‘9\T©Tª•ëJ¤rᢎ%dŸñ§Â¬¶Å¦áQ/f“Ø3ÏaÊŠ²ª–$PÖK%4S¬Õ¨™ÌŸp#À×X¡y”rá¦tÆ*„RMQ² ¹âS."%W͇®¯NOì¶SÃŽ'þ–ú>ãÏC·ñZ ´d~–d”£5ù´˜…Íà)æ”’ò�ðb\[.÷„“¥1Jži\W›U)+p4t*ÙjXå»YO‰‘Y–8/"Ãö›ƒz£ø´óaCIË¿Jó׿PËæÑÔøo>úä*€(Ï ö#h ¨Œ/àüñu‰HCEü¬nÀx0Àãf€üÎP€ €?¼$T%Žàš~k1ý� ß©ƒ÷?€ á]°øwAð3ÜÀkÙ_¸ßýžØûûsß0@ 0¤Ÿv¦o©ËßRÀóo•[|oãoˆa/ü‚ë&€€8 ð‹g'°� À´�g+àáU¶Èžr¶öóÉÛAh¢êЉ¼8Õ쬦Oi¾`</¤3òî›pq‰ù@ÝJÜ-¬‹^ÝÕx¢è„¿Vô‘MOvgâ¶YÃÂÆFb›ŸˆHŸ ·Ûvb|V4œ�'¢:S“B}^aeÇ#Š©ëû[rr¨¡BÕœE K6CZ€\f³ ZÖF DÕ‰@ª²ã.a牫JgÑñÚq+iã)ÒÖ‹˜XqxŠ8¸ÂRà{–2dºâ4a`ÈR8fâ2B.)g$`ŠmÀ£qÏ{¼ô¦ê'*é'Ds`^Å©ÿ¦y¥"çYñÀr[cYÉÒ@<ly£„,ùÔ£1/±ÊigÕÔ{ õ¯A|Hž¶˜ ¢‡Ö<ó<|2Zq•¿Äa]se„ ødɯ'õEgÿgtThÜ7g$Ò$N(Œ¥ûï0>™oÏÆñ‰K;ëý°¨ºwú.¥ÃÔä*˜ÀƋĉk‰#5Ã>ûçØŒÎ¯\ˆ“k‡ž°Js?`NŠÊÒ¶™cÅq£2T™(‡´Â¡­¢£ËóXn]† òX"Cø„(/¤Ì’Â{6uUZe>×%T%¢$,gKüiSÑŠo‰~ÊÞ/$,œQ¼çH"Q ±«¡ižaèº`–\ÆJ`¥I¡”Ö^Ö ´Hq•=÷ÙÆb‹PJÕ/zÍþ´¡q30TEñ­4•œ(; Šj@,ª]tÄ›X GAƒ¥¶4Æ+ê% _¸µf¢kM›Íd03>%}lx’pHÊɇ#ϸÌ}XOÉc S cò!˜k‡Jd¶ÕEÄH D3cjõá/ð7€X¶C* D¤û<¡dƒËü´N÷>œ0[YAO­°võÕ¬.‰¼X¡¶Užg°ö™“„gªIêˆlÏ̯¡!ðɦn¯iÝõRu§ ÿÄ$€_‚ÓÃ#÷à�} ìÀëððŠ%0<ˆ�K�_ÈMLþU;ó×…þ×Û#@zYâþ®€óÞþóá]©PÿCÜ€×—X¿N^3{‡VðÃ|²WHü?\3#¼^½/?mÿå$†¾3_û½¨“ßÓÓ×ï;г—>M*� 0½å]_Ãæ4¨ø=t�ž=yýGíõ­è"ï`Á>ªšëGéËø¸w/Hø¨Šn…yrTJÎå=w0÷­‡ –~ê—ô,Î<¾¨Ñçrаv/D8|L~Ô›ëM.…¢5òé|Ai+ 6Í"œ€%˾ú\»§êaÅ’AøÅÙ;ëi ±=Ë«¶gS¸õç½ ‚SÚ@ÒÒ*Ê‘ò¥,%ÉY²$Rƒ–µâÖtž€D_JÆ\#. Fчà@ —PðŠ(NJ³â”Æb‰{_1=àxÊd™¢EƒuX¡ÄÁK°<ÂΞÚJ]må5R2TþA°¾&]mKÑ®¯SuÑ4Ÿ6¬yâca„;rrešæ˜û~ÙÒLo!|¦/}€¥í|üdÉÇgg¨àvŒãÔy<‘ѱÊND-®çíôüèïØ–÷êLK\NñE<i‚ӯȦmVWqêíÊ’‰^4Ã~¢ë BÄÇC;C’Ò—D–SpÎêt±óêÑž¦ šÆTÓ•Ø ÅjBZ–¨¢œ$11Öq@‚ÔœUU"jm&‚”¾´¼”-âˆâJUqS\Àšƒ*JW¢Ø±{ÍPÊv¡eòcD‚¡Y.^ P²ÈbMÕ 4Ü¥äm h¹w¾›]¦).VT|?ûã]I)‹Öó,Qàˆ‚£Í¼ÈGÏböÆSg.-'HÐ’+wIÐD¶–#5Ç'·]“J’"9•”ýœ[x²òª¹xB0ÒI©©›TH)V¶ºX’¬dUPŸsY9íMžYÑŽMæt)Ó`omyqÁÿãBô-«»RBX‚/s_¬%©®E*à–.[[ì=r×~rPìy—BÌ)¸˜b²U¼$:à¦"=Â~¼ú ÂRÒÚ¦HæÌ7·ÙaN\]¼îyAsD¶X ´a)%7QÍìn`²t€à…„9¡�gà?~­1Ä2lнqï¡{{Y­� �Z˜ái†{¹gò/¿\~°s��žgpýÜ”ßhV´?h‚“Þsˆ ¿³Ò�5€yÍgx{kÒ»ö?!6ðQH}ép„¶¯Ñ¿Åfø”ªÖ�ö»»~¯6Æw‹^Ëc� ðåë¼Ê’v0ß`?ƒ£€8è�µ‡>Aœ?<d ?ƒÇ•üñÕ5«ÛXM!…ǯŸÔ Þ—¬)½«?ZÖ�@õÜŸÍnÕÞ‘f™Ð¨‘ÔHnê«}KNîÅþ¥ø3« ˆ˜Ð’ÌxŒƒ’s«¢f‹ì†³†T<HnYB<`¬±Øâô1E½vÙ&B®Ï„1´mÆ’S9­†CäOëuÉL3Ô¤¡†ëì÷ÂÙ™Ei@L!Ý0¹¦…† ͉G¼ÊÀ(("%�UàVlRq‰ "2ˆ1²d¦ s²X¢@,3 ¾êÍ'hu ReÎ,—Àé ›!5häñTÑ·¤Ú®Ö­«�ZhÏõ(µØó]HÓlãîf"Öÿ\ †ã陿ý¨\yÚ8©Î6›Ïžæ/äýþ0^ªeAUÀ\-(ðk™MÚœ¢þd·þãºý@DqînüÏÑ­a‘Ë×½€fó!¬%=“¼Ý ²ñ®LÆ-> D‘vÆQ5…0ë\¡„`QJ(ÉZ&$!æüX¢ôŒf')U4QÖô´ÅÆmÁ4Ù¥øÙªn‚Ø€‡žû¤›kL©ÏΤÃc0Ø4íJ\4¡´Jq"é”(·i=gåŠ3^pDq Å,areÎàÝ‹Š`G#‡|&0}BJ2öÉ—ǘY™1AŒD\N^b@ Qâ‰J‚ËkÞÖ‚a9‹)Z_‡¢¹K¡¦ƒX£yK4•"‡¢+­rò6Dž¦ uhJ(¦ÌQ¬ Åšœ@»¶F÷ãSF>ÓœCÍa`ŽVð)àë“l,k -Ǧă51ÿ DÁ%ëOæCô½M„¤ V0Ñ#Ç1§)ßG~èJ¡5â3«³V˳@þ$ÖÙúLdWâ <Ë2 ¤+#K€pûðpÊFD¼Ê²û ŒaˆJ‹†½Ò{#É3ë€ 9Ì €â9Àuhn­‡ B�¿Æ÷ üüñ%ð`€5�Zƒ»†|3““PŽàºÀ €§ð’ØàÜLà V0­î_!ä¾òªmðÞæóòÛ½ï€òÚ¨3ÿ�¶¿ÓœÒo옿,%Á뎇�/oî'N»þàÉßf5ãßl~ð*z¤]À£ïÉ xà èß–Å¿€[ P{¨Ž0v@�Æ—Ïèˆ4…'œ-â}Îã¯S0³éê~–YGÃúüDæcUo2·êôWÃáOkÜÔˆ*e–Ÿ±jM?NèóÁß.p¤Ÿ¸¼Ìtµ4,ß°àÃþ¯‰(s­a^uîc\}ND¬i‹X“aÈžŒtM*y© ª³ª–˜ŽÏÄ&Å”+G¹[¤IÄ)pGdâ(.ÐhÂQ¯+…ÙZÅQñÑ+ë–®¨ KƒÕ¹ç$aŒ–<0Ésn9¬•LhI©` 1Bc!¯�=H@fë¦híAxÏ…n8³Xû†`Òéñ!· O¬f±²8ء̥q'¶ù|Åko¦âgˆá’][*„˜¸@]UKÀƒûÿŸ7‰{öÙF~!®ÎÌi+ÝnþbÓð´¸hR†gÇÐÏô*aÃÂ¥\~J+¸—}Ÿèfßf¼Ú–5WmÃC¥MTe?7·NYRd‰¤f ­óµ<�†T\(ÈÁzÄ|ÍÁ¬Èô’ow\T¨B‰`')Q‘âè%f9¥Ù:̰”V—ÌèTÌIú) §L<Ö%#lúe¼ŸÔs” ’›=ˆ-—ŒV‰ˆ(fÂ‚í ŸÊ 9(TlNt⤠yva)ûLXÁÿ/moÖ$×un‰­=ï}¦« C¤HÉ”®¯Ýv¿ùÕ¿ÚoŽð›í¶ûêFKÔ),�…ªÊÊÌ“gØóö‚$I×ê|ÌÈÊ<çTÄú¾½¾o­å‹!Þ0¦XH1’xØÇpó ~.u;:xÙòzf™±”Ê8ù!åb+=©©\­DFȾ¸cr!&ÍŠ¤¢%8gt-L®”=dÔ;¢%e¢Â9ŠÐQ©±®‡,3˜Œ|‰TªZ&8#‘å~ÈYð„"X ³§<7UM¶BÔŠ¶{®te™y`bWâ¶ŸŠlðe†WЏšMÄÏõ¼‚ž"éÝ<ÙÝu$ÙEí‹(JGRy-äˆîë"­Œð}+r>Kz§iY ]¯³jCPÓÉîË‚d1*2ÝçóÉâ¦)äþÞ”ýF>ƒ¡:)2.ΗìÙ¦g æ¤{OÝxà µ€Å €´ðõF4ïûò Àð[ä%°Àá/Wìåbá!®Ðû7¹m#Ð�êÝRéb–P~x‡f=пƒ/ÏpUàÝÇ }üôl€¾GÝOwáïìûþþÕSþw®'IÀ#pP˜Þ_ßÇr”7F©?ŒäýÇ ÃÄ3Ð~ x+¦ ?ù•·u¢IH~Dç½»ZïÑ~óÆ�ýÍìú·À¸G� ¤|ûa„5uÛÒfècöãüù 1puçÏÁäîkÑ’yû<yd¨Q‚ô~åËë]5®«ãlzr·¬t}op”¸9KË”73L"Í8Dº¸,Û?êIBrj¦¦b�i£ÙÉÑOÇNRÓ‘À8Ó±!tL!‡ûq43ûÞÐϺÖS ŸKä¼Lç‰èMä&sÆIdà…hP&ª\7 Ïš?”Ó@#Eæ†ç -F1BeN‘X\8ºi,°‚¢Ë¡›³‰…‰ÀÍ”ãQ*Ð(8|ªîîׯoEÛ•G­£îCðütg3¦Ç¶¼vd{,÷~°÷ÇÝÉÖBy9CXNØ”m5j~|pº¯Ùã¿ü9³¨/ãªr¿ýïø‹Ã=»ùÞÝE¹d¼]b?=ÈÖ,çÎÙ['D17ˆ{wcúX9ñ”kªö9ŠÈ1uyXÐö«CN9AÎßÍéùu\ª"óâëû.Lq(î‹XßȆdˆÚØR/5ã5: I|!¼DÊìÂ~ŸNE´_ÈÄNÎOɨ6EïkûœcŒƒË1»|w+B ¦©A<³ekÇ&בSGJ_ÝXvÒì³HµN9&1—â”5ÒKâsqhrÞqó¬Ëʤ³TÆA8 » ¿8'"YÁôQä’ 1ç2Gw]Ô©£ŽˆÍ‰YÁ #4!ºàf¢‘ß ÒQâ g™È$•\«TñópâRÂȃcEW«ÀpP1L‰Gn ¼J€#ÊM¤£'$ráI°Cί#½™Q[S!ð¬uf&Z¢“ŒÌŽFûJô®ÞÊ…à b‰Ïn Dz”îü½ikx¦É”܇½û@›Y}=—/j0*ÝHÙ5R°Ö̬I…ŠiÀ¡UH’é<µÖ€s‘\y^×:Þ”¥z>²½ã›…¦$a×;÷lXR\H0†Îáù�Áx:ââ„ $Áå=®vð=$üì n¾ò›$‡_ €3 ]’7Â#xppÈž¿ ©pYÞž!~NɇÖC·½¡~+ŽcxëЧßy’2€}2j3ýuòßË)ùOõûù—ÊIõ“¿eïóé̇#ùŸ†-P~ä$žL$å7…áí¯¬à÷?¾ž‹w%òÍ›U Kÿnôÿ£Ûù# ù.kì=žÜ¨áV6¡y€²1¯d ¯Íg¤nò·Nî{¼|Tu/—Æ4òŸLn"W¨.°�­æ º“§a|¥®Š˜«ÏþpЕH÷Ëô["N5¯*òÙåmó­¸BáÿCjÿÇfÕ.Î)YXFЧ¡!q·©n2äŒ@-!é9u_9S³Ff¥FE§&‘‡³ÜMR”Ê*½D.t¶s¦…¤ì‰Ê,×Fk¹Q0&…N.fÉ#㼉e¢p„Rq9Ê‘9KãpŒ“EJž ¤”|ši-H"G1t#™>Š+þ%ÖßÜb=–i>~kfHþ�I¼ìñ»êôÔ÷«Èòx:²þ f2eš¤båM}_ŠÀõÄt|œ®‡ÛtêùUÂe4.FñsÖ³€Ýá.pƒh¾åŸž*ݽ¼+v¨¿µ¿ ðÏ’VL«(Æõ~5üäåAEÆãIôÚºÇ YÍþl†ª¿˜ÅåžkÛâÜ@¯¥Šs×'²lTæ+õRqÞN™èy$óiÝÞ!dt`¢H/ù)†rµ1-j.¨Ï,“gŠz”$W,ýr±XÆDù0Î ¡‰2¾drÛ¨FÅPMe>Ùl‚XC^dú’§–ˆ‚j8²ÆÆHvZ‚?0QŽ3?Í÷u5­]WÝ©©c‡6yFZ [I£ˆQE”àr:¥a°²hË8Ó‚ –S&Ë"Tµ’ЏMEgˆiTeoC‘‰²JÍi¤,xn}ñ9ì\$6—C ³óÉÓ$c’~æ§éÄ”Müáë!~’1±¼¹™£·4°œ%?Ø‘PêÅy2& VÊÄìœ,=5±z¢ÉÔãTñº #ëE*wù0ÉÙ JKf2 ÅgeŽúqÐ/ˆÉ.:"‹¨sÃÉjž45kg1/îί yhTuJ[ýâÆ§;Ò™±«‡Jöm~€v³ 9Ãø j‚jŽeÄ@Ãôjâ¾ø·äùíÀ=p’Àï€- €;à0 k  êÐ_¿¥|<Õÿî~2L~#GÍ}þPŸ‹ vz'~ß”›_r®û[ó7mýü½žŸ.8þ3ÅûÁ¤ÿ1#ôöý3 €þ‡~ïZú>0ÃXØÃ7¸Jð=Vï÷|9||#“ ŒÃîýñíC£Z ø7á W5¶-tõ-Š-¬ò>³¤‘Kt힤FÊÕKÅÀ¡åØðŠòÝò™R—™|VΖfn‚ü~ñʘmE^žŸX-nìê‘f‡u%Üy…lÄr®Oe·ÞÓtA,JÎ'bQ+–„b9ßcš|x^â…ïÎ]ctÙ#×I8ËX!k¦C¬+º ¥6T[É=Íû’ØìIf,Ó‘L`œfE¢@LÈ’Ê(å”åÈH5bIDö22æÑ`n5Ï)–Ràx™giwÖæÑËùXÁ…ü(“íÁɱÇË:\ù}uÄòË5Ê –-k²ðÞÇþ góЄgÕ8EqTÝ·OÝñŒñt#’z¸#¯_Lû=\MŽù•þ¶Z¾êÌïx6U‰ê~“¯7‡8¯„êªO ±{yÐÐyDæ—Îí­láKþ*Sý)—[î_Që@ÿx§[×ÖÀE8nNé¨í?—À«!QªÔzÒsl1#uËZÍ›¦ÐÕ mÝ`üIdº Œ°(Ú£ vð*Z~¤ÇZŠR±…L¤L–æ!{V<•m 0Nì:DÚVOjÖ0R¦0 )1Ì4'Ê!"—YRh:‰0;ДU¦å$i£ÄÖ¥óäN§¸Lz¾¢Y(éò”Ø8ûi”ót Ýiæanmˆ7sâÜ] >åˆÓ§ù4yÐ2²CL9P/aàUä¦åÌhF8“L3^…ì| ”ɺ0•˜ÍädSšý~˜J *v𝇓€OšVRÐâ4?>¤YÌtqpò9ëŠ× ½¸%iwB3@±Ã¥Hgr:'(‚Iב‘©Tnªää” ¾3s'½çÔ ”ä+M%´è¬šu]?ð^(™ö μŽXñ%Í¥&0o:o<¯R!0<�� �IDATש*EÖžÌdó‚ýö®Ê†³Å-‹§ALl>’W¬¢¯Ð,àJ„›`FÈüìÑ=„Ø€­¿;ð@G%¬Çé ¾ý³_Å$€û-f\àîM¶ñ½Dë{ ßâJÃßþ Ñõo×2  ~ÆÍó_Gꈀ›~5ú8Íþ“7½—€ùèÔûïÞSòeÀ<ÒÕ'?öŽ;jƒÔ»Ãðnû÷'Æây=Ðkx ôX¼-À9°ÃÞaÃKÏßÑváè¶—ðw/ðÇòÜÔó4ÈCZ{naÕ ]ËU¼´ùêeòì°ßÚ¯ÙëO¾Sš-9fÚùkªòY„HŸéDK½´-•Œüµê¶Z/Ö’5+ÁûvQ¯‰6,‰ƒä‘Ñã…ÙìX)ºüžÙbfvnv¡£!ù2i*n*#Ö«5/²ølR<R"xZf,xÈ’z^¼Ìv,ÊUˆ”ª°“G!‰ñÌP’gE'pž¸ö¾ŠH)‘hV©¤Ì‚H$X ñ~δäÔc¨1ölz]â)¨fÜ6Óç›ôº"†»ÅYV5jŸæ˜Ã21ªNPˆÝçñ_¢ QØû,k¦¥Y°2¹Û)½Ü O3;¹J¹ÃŽ•7sbÿ98ú¨ê½±ûÛq|Ò|¦lc†rfŸwæYSVK\æùQcˆ!ŒÆLªîrW&yÜ&é•Miä¿™õ7*n~/¤ÛÚ#=5+Ò“™^QC³eªÎîsÉËEá„1ÙS3”2JZˆôÆ™¢êDt1ù$é]EkY4/48§&V{*ï‹·4.e-Ьf:Ì‹?ºvae“º¡÷Ò–JЋ›i:ÕÑWIHeÔãÑ’PWÒ±àL—5q]éáòdYŽ G¥•¤ö‘´¹Ò Æ:ÝhÇI¥!Óê$lŠ‘Žƒ÷,ñ,uÜèv··§câœ.¶ºâœÄÄSÌå˜1»À|8c¥#ã„qad»*–H@ëR4R$¾íÍh+•:>ûÐÏ“{URS›�Js!Žš4-›t>6‡©n[šïƒÃ1œ†îþl}ZœWI4D,¤"Q•ŒPKcw‚!ÜxAçÍ&!j´ägµ^žÏB€*3Þå¢M¯Ç<íS­Ü!úJj_²aõB-4!*†§­§ì&ðìZݯÑzF†¹ÐÿŠ#€~ xø€SÂcAþãï@"~«üõÔ9,Áw;ÀId Hã%îßFOžÃ³³¯'fV/.|ÞŸží8Ê 1_b…üfÆàÀ?ÄœôKã7ñï?ĺ+ÿŽñ­¸D¸úYyxÞà»7ízÿ‹|Ô?$Û烋KŸ”)¾pÕµz‰“gþ“]®Ÿ‹CúÇ×_€Ü ÈÀæ½-SäÛý-Ïßj¡J·i\=€ÏÀóús;âÀ¸8?\tý³’Ÿ1öìáÔí£´\È–±»ñC@ìdpž1ðy´Ï<ƒç×=yVs5Û…žk1-FØEÝ ÌvÆhÂ)~\«_-ô®«Â†šÞTËÇR¬|b2£Iä˜(e ’ˆ{%.|wYÎi²Þ„,M|Щã‚KSÑ®•ZÓ¨è>Ó)xVjƲô I,goX±MEÆ:%"1„qV˜G‚`.qéEi²$ ,7”¤1E›³Ä„º¢¬ªÒ®øÙ‡ad½*Es7Äa¯^Îtèk>J™åbC–Qդ݀ÝÐÓKŠÃˆ&²ÛÚG;“Tq‰Ès¿_¹¹0íž±]URE•ÎZ7âôŸ[2wú×±°C¾½ÿ¹*/Is¿]wqÚ´ƒ*h›oó¤ëÊW þ´Ã*êMðƒ¤CAnÔ'&Ac}Ž&6ÍÙSsßС6Èu 7ŽSKñ2¥Ósº”.ØYmêJ9±ÊeU2!aÎ4s]Ș˜Ke&bKX0liÙLЮLn…6sgIGÕÚdgòdfž²ã$^O£'¡/d¢x³¾óº úd÷ãpkèy¥×ˇèBLã´¹ßÛ<2íÁå~ uŒRy"SÊÕÕ¬<e*ñÌËCB\ÊÞ“#4/ãÐøýab»)îïFYÜæÑbÃ/ŒR„¨4MG—†yRœ¸LÌ‹H6¤^ź"š›HX%*²‡ŸOΦ]˜ÆÖèXÁ7ubsˆ™œî©¸Ž~Js`Iªùœ„¶e pK•$×éY-fWE'«JøJß!I:Š’K@ŽœÔÔðLs˜ƒ|F¤§Pe"½ÈJ¤Å0$k£3IÅÌ3/û6ËÉqZ‰õV× (ÅFx™S<õ£§³Pè¨Úxó¥ÂYº"ä¿’‡óÍée–è\AŽÛíç—íY½ü°æÎùË;Ÿ÷îÂî9n¬°¿Ù‹ìWåŠyß¿Súb„^é—˜NÇ2í<â(ÜŒA§O³D�$¶ G÷“ÀÎOðCo™'´ïTe¿t ¯ð¿¿ˆ÷ÖA2à’à*½gïÿ½žÿ®éóªù×¥\{“>n]ûscq ¬�þƒåˆûh€W@÷Ö,ñí¬b_ÃŽ?Ûñc¦T^+Œ—�ð€ŠòϢť"o¿7²”fI؅ȯ›RQ9íå–™yCÏ+«•b`ç)Û±?¦h#[dý}ɇ¢Ç¢¯E¬á?£å7Y'Ùb`­Ò†ïW±?çíZ?’õÓ^6+ÑÖf:‰c µŸ«ñTM"µÂ± *A†©}Å÷_“ü€`Óµ~©|WÝ7Í¢ëx[cî”@¢`ŒÈîCô%³�é…u‚šP ·)ž‹R$¡ŠTž@RáU¬ˆªYU3•9b8ùD‡(X‘NæE*®ndýŽ Œm…o8žöîv•ŠkÒÒšy‘^Ûx†?Ïš,tü“ž;É£ U–ûµì;FlÞ’[§Í•M!Kº1ĽÞv™²#¯Jºîç— þ/E~¹b™ê5U§—Äöäfœ‡%iL`¢J³’NšV—ŒI"bJÉSi©î5Fž×KUO•ÙïÑìW™¼é\ML  dGu®aô¶ÝF“¶~Щª“ 1›˜,‘>ØSòÒí…àÙK°A ¢¶µnX6ƒ&‚jf&¡Åkhâ‚´Òä�:ha³§ùÐBÔ‘n’*nÞÇ«¢e½ú²^­ë–8{ò{{sšã¸ç±ä0G³Ù™uÇÔï*Â4kÔ‚Féծ⥾ÖBØÔKÜ):fô‰óïPná…Qnm¬¦S¶ÉÒ)‡knÊü%ÕrIÁo90Î)ã"±˜YŸYʼwìn¤¯ï惟¸VMõJXÓS_ò‘ÓSt/ÒéU¸_u‹-÷KO‚¯xˆ2—Sa%UkW£­‡1ÚMYT¾a×È‘ÆSM´, ËZÄ佛ȩg3a-`Ú1íy:Õijµ€:CŒU•òÈç>ÚHC±!„˜²m¸_«”Ò¨? ½_˜Šˆ` ‚còjå.Æ©Þù"ð íBIpQMlløé”çÓíÿÊ]'Žd=ÍÆ%#^É‘½i4[xXÈ=<p’ó²X\ià¥ÿ!cÇ�Ê`œ$PauøÁç(¼ þIž™ô¿¯¤ûp@ý 9Ù[ÿ¤Ã’/ÄŸco†-MGxàªüHbýï÷Ìøû¸&ò‰(èky×V1~b¯öM°Ñ¥ øËÛ¥Y ñ%šo>| =Ò¿¾¯{vüåºôîŸU€Zì+`Ý>ͿѡEš–¥jÝôUáíáèø§¤WÇpùe¬ŪAÕpÇu·5Žºí/Ký9±UHäTöN8;J¸¦“ÊÆÂ(»fó’Õ+½\vªê:VT†¨#H’]&¡0éGJEZlTyà™ÜëX ýÖÏ7™D Ž‘Ø¨´>µ ³Ö¬%Îû#‡ …‹èH!³“ó* O.²7$yËub ŒwRPRHQR&ÃbCËÝ6¢õTî¬ “,så2Ï"2zòŧXœ½É~ßÓz2R*MÕF³ƒ4» ÕëBÊp6²M$3·W‘4AøiùO¼«6Šô’£ê‚§í&ÎbLd’ q5Ñ7¶\2½½›Óª*:ÁNJ¾¤ä´þŽTª; LX’né†6ë›2Ò·ƒÕUž¦z‰ï:º¡^ï'飛=»¯j¿®B 4îõŒ&V<³%‘àš1ɪäO®^æQUÚzC.Vu½¤zI&%ä@iޤDs™MÖN“Ì‘¤kN ´ÐL*̉™;åpfC ;”ÃX%!™ôFîX^÷¥™…X¢“â&aåJ"Cc2’æ¸XäFgA‰K.E×÷óõ¤Ì&GÎbTá8ÆS<QÕõ!Ë*æÔ‡z*b¬§)!šóRO&»xÌqŠž÷¶éY̱Cœô°c×;*V^lBȇè¯r¹©Ôº)FKS=M»SÉHÐéT—R˜¸îø³Ãᑆ;ò'y¬.ª¥ÂBp&†@Tˆ1$ÓÏÊ3å±s„7eb©%¸•K±h¤Ì÷Îs„nâ››™ Ž2“Úb9õŽÐ˜ëªˆZvÌðƒ»-îûi,uxÄÄ‚„œýb&‰u5¥ð6³Á$RGg™NÅÏ!çŸkÃ4íÎÝæxR“;½>·œ–‹7Å(öX-Ôzûú\|Ÿ Âá+¶«ƒGZÜöìë+úrCë7{³¹ª+d þÐþy-Ð0®Û\YsøIªñÜBŸ!: `À ¼f¼Ù‡e�ý�û=à?ÙOÿ<M�+à5¶@zç)¤>b!ŸJŸÐ�ü·ðÌø±Å/ãþ—É oµxþïUôoè&Ê`«Mo(>Fd½½ÿ ¨ÞZ'þÈ”ª¼ýÂgÀña\mõ’oƒË‡94!—½&FW¦Xõ]N{ä±ð¯bꊕšnø¦* !Û{öýEÎ*ŽEÔM§½…ôO9­§ª¬«ºEë×-á•™–UXÉ'MÍ«µ0 £LeRRôÈ£(¥áœ±œWް*,:‘מ•*¹ m‰Ô¨ž`_f]*¾HLt${/¨ÏÙ#8$áKµ}ôûåÜ%ÕpYbâ™ë’Y`J™ÌƒŒ{#©fã’.×25”%L¡í §Ù¸bÌ©ô~ ‡# {ÈÃêê—ùüŸüöi%ê”3"è‚‡Ž»K+³Šã)U¼¤‰´E^hFnj÷\ÑRÔ“‰T/ì‚´+ÕA!¬ÚÌk¹H»ïèŽU+ñ°cd»1ó4l½lÓ^E„|Œ™Ô*:ë§ÅCÖN­ŒêˆñÛ¹'òe tLrcóÕn¨ˆ—UñE£÷¶ðË~ÿ$ÙRª¢“dH§|[RI9ÏS+¨QÝvÛµ]]­FÚöÔW±!§¢N(;Z=,ܰÚxœ5(H%)/‰MÑô¾Ú%N)÷{ª¤–™HÑÂVÔŠ ㄠ²šˆÊ÷)hmDÚ4íC]jY™¬¿?¸›!Þ$¹f9ŽÓ= ï•3öz]µ7´$_½šú×n[ô"ªØ“ð$¬t£cn®–³Ùý§îô9sŸŸ bMô,y c/i&\R´4gWø¬/Wºešp¢óãÀ¸â¬Lö†‰¶§´h³‘L,ysKÛ×êtÁŸû<1Һɤ<7IƒÏîaœr—˜Ï›;¹PºD>â5Ëu©š-sšNlyÚò‰+‡¼ix ‘Òϱ§Å&û8-QBKÈnr¢ìhuG„÷©x;õ~f‰&[Ú*ðb2’±»m9²8°žIô²:ñ4¢•5Ê##ûç‚Z ¾rt˜—~ôlYIÍÍÙ5]TšmëÝ“‹ÓÿJϸJõu¯VW˜þ9¦ÃK¼þoµÃVK×\îî÷{Ù®Rl03@ªÕ=oŽ€œä­0Ø¿±ø¾Ê?ßAmñûÅ[gh�˜)°ø`9ç㮟‡W~ðf�^�ჟŸŒ"Ø{0üŠ~à+ñqŒ%ðåÝ?¶6\�;€àÍnï'Ì”<¦oÞY^ø¿‰›ú©=Æ—:LâõyüÈlõnûø ð¿zë ëÝN|K —HWÀ¡ZìÉ /$W-r5ùU+¶ŒnUW)óD”�Ry¥='jËóɬLÈnÒžÒPrXMvŽBDµZwª~s7/;) ÏaŒÔ5y¤`œqÆ JŠi,Á—RÄLTìs>$I%”!Ip(´ ”Ù`˜( é¶F”á[;¸}1Ç’‚¬9YÀµU®ÌóQ™ ÈÑæñ@%Ϧö†U<ðÐD‚ÀJ¦³#D ”]ŠÑÅ #¼T!Ú¸gþÆ»ýÑ6£<¢½IX5°ÏBÕ’‰|Š|)S|GÈÕä)»±;Çeb&¼:‘£·GÍtjP··µ®«v1e1áâÂz1ºÝ‘ ÚÕ„S Vb¢“Iô 1Bÿo,ûaÞGµ¨ÉM`±ÞSÕé±6ûoÚïENpmĆ6æÞ Gûo½]}åÎÃQ˜RÎ Q!çe½~È Òœ^îñžm¥‰7gõ°ììÅò³º]ÖM£/‚ú(" cN&Æ­à=qUºÉ3Íw¬V±”T0yqëÏ‘ŸK/GHžÒÆ÷䘧àèJæò˜˜<q4ò™_ŽE—¹ ”(%—¶÷ÅÅcú†„Í’>Î+$îŽÝ.ì,^Æ1ÙÓ—È4÷öæ[wëôýEó;)³<¨˜sf¼ýqOî\=i '%ùp˜Ý­—ßdõa_~Éœ`Ã#šÑGUçr.qôΖˆsÂTæÂDNÌšdWXTµ6i+’ëI}ʧ9ÏõÝÑåñSµ8_<¸£CŸÕŠ,g¨¥Xmk¥z:Ø©×^Iá•´že)ê$hÖÌN«º·Yzs:uÜRB¸ð!®³«3óoûä á|7ßžTª¢–U[Š dbnîâ÷4¥‹H¿ˆHGÊZækzÎtnc™È~Æ}¶¯†}²ÛBÖr†§iKþ¼¤eÑk±¡vÇ×/K 1±-ÿ6¤Õ~À1¼€'&—Í"ŠbšE¯ñwéŽ}Ñ2œN?�¨zc£wîß@’”£Î¿YOuï)¡»˜• t�ìûOü’(øƒ7ÃÇì5ÆŸ+~°í}ñÇÈ;\þƒkƒüߘo'ãß/•þ"7õöV%à6Ö÷À7üÈþÕO'øoìÔ3°¼~·‡öf4 ƒŠc¦—¥\hqx” ãÕþøºðê±êb¡]Û‰ûŠ'¾ÝS1>ÿìÁy³_4¯´ “OI¼r­fÆé´ç$c[¿~¼þu«bŸ;A×£Z¤¹ÌÄÆðÝ„Ëè6qvF¦!ûCò‘e”c¦þÊDCÎvéDñ´Ì1ð(ë‘'¢. mtQ<ߊ\ûT2Q¶ˆÂÑ-P‡"îµ=QZLÑeÎÜ•èmÖ|ε)ìqHªØÜ§ƒ.a+D«<Üà†ÑG DcR>¦<L”s5§FCþ/~x¢ÃãÙ5'È! vÇ|OS'JEgÃÙ,ëDªqâðšKrým*—F­–æŒ- pTùÈn­«pUò_DžH6úµˆ¡xnoÁ¯BYë®ZŠU×.°+ÃjòJçY`è çÏõ{¹z¶°ßÖBKçåo”YgZf\ï*щU+aV߇M HVgÛ\ÙÅÜEÿo‡´ÔX ^¬·ÕÊ´†6’T%O £!œS4)Ý%;ù³$ô,R©ËÁ„™iN. šRÈqÊÂ2Å[<H÷L¢Z|yIô1ÉÏ2m²-´¯‰Kœˆ¨™`fZ´÷CïKì&J#­F'ÓDÝÜâþ ¯¹¹–¬ÐâBuÇØ˜ª»Ø³ýåDήê>ʼn²Ee–(2’@hIe$„£e›ÿ Âzx}]»ê($†BIêè+Ô/ q.“x86ʧã4Z™3)s¢v&îèT¢¢äPÓè½§Ð8׬D¬H»ºqŸ²žÖ‡åzÎ^Æ¥tb)Él&šnÕDøü•©ŸÖuåÉÑNÓ×ÓQçú\R¦ˆ"c!Éeª°c£é†¦éŸJŸã‰”;%f©Äήœ§$î3|°žñ“¡!r—w—ŽQz‚(-Ë¿3ù¡B²ÌuB5§$ ¾$”XòùTú=®Šq—Ž]ª'm^¦û[EN6óÚ;BÊn í_ª´]ݧü§?ßø?WÀ% QŽGð§%53RL×HûXf©NþÄé"‡÷°;Ðo~àonÐç,ýÐ@÷ôC­ØGûSÓ\Äñ“ùÏ­™G’?éÑß%ZÿCkƒý›¢ìä[/ì’hY×ú¹ä_� RáÒájúäs´ÀËŠGíñ�pîê–#ú+PŠ2Í~žIPëjua(—QF\Q,—´¬èkq¾¨£Ûht…¦Áö½§ùlNlÃŽ`X”•êÄ“…zzö²[5N™¬'J]ÇU*‚žmøç‚=òN‹ž3.É›†â)IÙù„E4×¼Ÿ œ€fJB©XÌY~Hñl¦›,¶­& ­Ì¢25Q¡¢wÅò9¦¶ §ŸO;ï‹þ ؾ¦ûuÆ£1¤ÆÈ¿OŒÑMp’.³9ù3¨rj¸³eÌ¥It/i÷Pü6M J«LÑèõÉÐ[Þßûõ÷9|Y–”ȇÒÝDi8ú¾¯H[/Ø^êMŽç+BÆx(ã ÄºüQÙ߆^„Øšð:©ž ×–óp\[ˆ?Ër÷?cg”LüK=Ü©è£àT¯s´|êÉúl Ò QéR Ffû:›}ûÜ7•®ÕÁlvžÝ‡Å£JèªE%Æã~tÏëæÿR©Ùna’ðÎ’ÅÌ73åSôðH·¬‰RRgŠ•yš{]Äšh(TJ™®PKŒòÂ0.#]2B1ù») ÉXßæ¨«8‹ãÇ$R(‹È†_dÕ0¶«âëÎsùBcI2Ø”CˆaäóÎǗɹ"„H}WF›Ÿž.]Ãx}ìrörÅ,Ý%)‚ع!"v2yUªzÛ=Ô…Qßâx%|¿ËûE¾•ÕMƒS.çeü/¡tŠýGÂÎDŽÓHGÊýÌÌd‹1È<€CZ¨œÙ°¼$š+j()4"{F¼ö‘“Å”é†þ*Ñ2ÖÜ-v)ý‰ÌGlªGç÷œY7Ýîö÷wŒQ7â5›*ZrL™‘dCFDM…†3؃¡2"ózÌ>¦ sæ$8]½Òñµ—“­.‡6ù„,Ÿæ õ* ’„–)È”åf‘GÃsᣫs½æëy1:G3AÕÔ¥r|ð‚õõ|3íÊÉ|µ8™-þø€bÕ­t¾q{v¾‡Æ§ ‘b™XJ)„|æ=€¸tò*)ÿÖóíð1¨ûþM"²ýÔÒ‘ ¸DþÈšéϲ<ƒp@~»ú÷Avz#xÄß|""ô?oø+S„ô“òð“{û�pxÓø¿gô?ˆ[zõ©Zê¢ù¡^&„×8Dz€ÂƒÍ2Ù/%¾ÉØ«¶ß¶šªŠœóãýYúnA³q¶zä/.6œT2Mèûõ!ÐãgDޤààdCéCYŶž/¸é H>dë2—0†é…Ñ’ðd¡o"cR“ŠÈâ‰,‰s¦|¤‘Ô-¥bIÕ‰çÌœ·3J®’+0Ž’D%ûÒÆÖºª:%jŠQä™@ÍÓ†œMÇ —íÌ+½n›cmPØä¡énA\W¾Ø0Á q¾R ’ù¤Krô>²af=©õR¨J?ªM†=%ùòB­šJ®On;Ã9 •«‰†°%ûQ5¥zx¬hn_¡~î9õ–‰ü›DYæS&×çõª6¢ðÒ—‹5E(y&ådjtÆvñgÄ{ßï^ÅÏóù¯Lw!çñ/%¬‚D3¾R6‘s)©Ð'BA Öq´ækýä7Ê»r1¿yÁÔHј;ŽCãÅâéEuÞñ”ä;ÛwQ´~± JGiÇ0Îs ´5¼Ë´n¼å�™i‹,y˜©˜£½¡¡lDŽ ‰'ïRp½ëŸÏ§ ±Ó -5ŠlPkEÉ,Rà,±ðPÙ€iƒÒ>1qJ9—`óäúÄ}˜¯}ø.åg1¿ß·?¤Ø×÷“+¦œ/âY¸•å_<ìN»*Æó]®ˇYˆ*Ë´0­n—ggë÷ãK¶ßùüŒ{VýJR&Ú\…ämæU,ÇB§9è9¹æ\ÐyÂ|=÷Ôƒ¯F.ߦjÉe©ˆ.§™Þw¶_eŸ‚Di)Ñ©’S(P#×Óv‘í4U¶®1å’¾~ؘ|vwwÜ®•T)ŒŠ'ЬÎKéEËÎ(kCô½-·ôÖê|$ŠÈÖqžô¦þnì|£“¸ +Íy–ô¨3‡ i¡ "ríšÀÉ#7÷hcמ-ñò>û¼GBgÙýJ•ÖÇgϯ®ÿOí=Åa}‰RýÊvÝÇ™ßõǡüªœ<a«W8]"Ä„=�/½p5£R=À+ð +ý@l›-o£îW ¡y‡i>|A ÃÛ/ùa£òÅ^XG‰ð78#}ÄÖûÓÜþ»ÚÐáÃmÿQ¯Úñk+ààÀ+àôþ±@Br\Ú_Â@Uã8ÿ¢CŸ�¶€jŠ#ÞÒL=*d6¢j©§ñšL›t&GB ²[¯?xxyvñY\° )ÝÚ£>íy‰ë*ÛÊ+{lùó†¹*ÿšQa²oH’bL‘&ÐIRj2UòRH‹ *Õ,es¦…¨ÌE¦UJBT¤4ZU”ÙÔJ†Cái9Ê&P5ˆìy H,E¢ˆ‚2! !$ðbXÎ!)ŠÂ Uox¦øÕR¦®¶J#“*p% {ÄÒž“9­�� �IDATCBÏy®ŠGŽ!Æ)%+]1DIIÛ%\T­ÔõReM­¤¾l#5žHï÷»~5Ç‹*·üžÄ!‘(¸{ W[u&™¼«¤Õ£§÷…•Ê…"T¥GÕ¾<ËߩȯÓéuЇ"*ŒBÕmáCmPØý»§÷³9чÛó‹-é£ÛÎùªÇxüìþu{÷pÁ.YEt¾÷lªrXߤ‡gÚ!f¾ï‰8\ÑpŸTÙ'.é%ÑÔ®Ök½ÉÁSœRNMà L¸PîûYùaËÚFHB4ÏäÅê%á™6{Ûö4ŽËÒËš‹ÙFzÊ¡oq_W®áµ1*“°La“œbÂ.|q)L !º$F‹¢üK>ÍÆò¼Ÿ‹å–ÅÕ8¢Ëéz—p+ŠÅ†«ÿ½Å¯ÉfŸ…š)Ʊ?¢¦“µ=ôìåâZlfÒ×ËÏÆ®>cZtçk’;Ì;Læ)M©^vU­–ü«<>HLúì¨tˆ„*fêèÈìæy¼ö¬!çü‚=YÀS¦Ò]9äüªÉ76ï'¦™æ|LYU±Õ`Þø~•'ŸeÒd”ÃÌ-ÎÖY5ìx< ¯ŸçS:lª‹º^ÉÂÞ?2wÁŠedf@'m½çÃÝy7“›YǤÄó<v89x×4<ämÔuE©¢×pÑ"ì¶äZHFÁY È9ÉC¡Q5©òS“{"G‰”‹*~>æcö·|á>騋Xê³™TÎlæ%á{>0=Éùþ Öê¼8>ã¤áVÀ¾_büÃ"A]£5â¤#®8ü¨¦ú7mîp{ö~xzXàõ{+½ÊÃI0/‰äá2¼=Cœðœ!¦ŸŠ½~ð:ÔWhýÏlVÿêvÿÿé§ôï}õ�ýÕÔïÊFHà°¦w!ÐáÃj<Áw¸Ú zñ ßZسw‹]Ûm7Øœ¡ÊRzOú„?_ÿ ¥8Óþ¥]¶}¦^s¡õùWëí£Ï×_=>»È5¹NßßûcV+¨ŠSãMºÉ£tyÆÙs%#¡*{æK}“+ÕLºFª•QˆFj)¸t‰¸hcp1ZŸ‹£•('B‰ÑUÂVk. !w2K»©¨o©bdá˜ì ›À§R¼¦™1UÕS)49áC+BJó”Ò’UkQWÖ²³QwE7ÞåŠAg€”T¡Œ°H‰ðÞº2Ç0ò@b¦1ЄšG.¤2$.ªlºBp²ò´ÎäQH;{zQ±ªÎj*µW!ù)Ÿs6SoÎ9EéÉ=]¾( ’ª³ÄV©zCO×nøz»ûÙ£Y¯k´r^ÓS¢ÕyJ/"pš0±ºÝhBò]GYçÅÿÇÛ{5éu¤ibOúÌã>S€Û÷¸•±Úˆ•nt¡[ý�ý`ÅΆbV;Ó½œ6dƒDÁ”ùìqéS ˆîæìL﹫úΉc.Þ'ó}Sí¡·yÊÏ«%·Ü¬Û*1ýRûÏéo—öëKÄG£Žj‚ì›xªó©©~¿ð†÷õ–/¥g YªŒÌ–[Þˆw”F&Å~I¼KÎÚ ôR #Ee#gãV ¹ˆD¹ LLXŒýHç>j7“9z3dw¬ít±Â¿k™­¤SžSÙj;fËS±ŽÏVUó<Ö<œ1ÞQ~"Õi4mJJ‡apþ`,¥Šž©´Èߺj¢í,§QººžSÁU2Žsݰv1ˆ½m˜s¿Î¦a©å¤uÏ¡õ¶;qgðÉ®oËúªIž¯äô•ÔõJæôSÉÏM3Ï~‚Š¥ÉІAIe !h£õ'º¬:Í*yO2ãéH¦7è'ŸÍ¬D1V‰iHÒUYÕM‰$z`<=øn·R=)Œ@Ïì1áþ€!C|=ÿhÚ|’:Í#-)‘&° M—èD†ið³qbMPµc-󹽟DP­g‹jyXò×ÅcªÌ Lµ7ùëìoçð?‡¼Ö‘+¦Ì‚™BŒN¹R9¯œL:•a•¢K&ÚŒ<¹»HW—?ÚéiÜMQµrÎÇŠËvQ_%Õ†ÑEçéÑ)'ˆ{AÒÓ3 ççl·PØ ë;ÿÅNVHtõɱ½hào–àû÷FÀïE{6�ÿ àNxv=1z ê1>μ÷búˆØë{:ˆÐP"ÿ…ü/ÓSúd9øïJÉÿ�\3pøàµðàxß‚fùΞ¨é€8.ßÁõþa†ÿàbÒ1ŒTFüm§Ú_Õ_0”—xø–€jìØo*ö=¯ÚHa[,VœI]ZÎ¥tåÚH§ÄwZ:¢Ê|:3Ùß(¼êâcbW½›w;>³U[ei<”‹BN©è$ ¨§eb“+6äBe 5i%£ Ôn8ÏI NA¢¬%ã´uE·99"‹d”s’ëDx¤b*Ê{_%¯Rpy>¤ž–RÑFéŠ1Ì„H—»¹HÇ|‰Á(®@Êì©?p¥AÜàɧ9MÅÅ8eQ²ƒq ÆäªR5‡R¥V¥RD;&k-êâ׆È:Å&³>ç‹CÈ9מ`ʪðDÆFhc“àשyþ©h×5ËIÞ–îxؾô›GµT„h’¹Û½I¥ÅŠÜß”Ab¸Ô'uKÓÈcÌl¯ÃÄÕà‹(MÙÕZ¤ß‹>ë-!‚¯ÏÄøÉ85Ëc¤=įꤖ/ ùëSuеÂŽE˜´n—ÕP²ÏU‹±ûp¼Ÿr)&æ2RQh5–\dÏ[¯ØÜ×:êÊ&.{irD¹ïl%Ê\oºâeÐKNu5í ?$Kbd¾/V 4„FN¿E2¡ÿiÌŠwÍ(–ÊH…9ØPfïÇ6‹µ×*ù’CG*BíOv³-Á %geU¡«lgwfï B Y¯½¢󄮎÷>ð ™½l•< j»!¥?©ü¢{V-ÿF·Ÿ±„Tú]_¿<æí>’HŸ£q¢/.eµ8Ó«š¶±,}fL£®¦¦º<öWSØÜ„nP!•™^*iê^/´õr·cÖTKZ¯ÖiZMMÉûS•ŸŸ×²„^×õOxWÏJd¡I©L‘…äP0L>yÙ²Ò-#Ø´ýx Ç^ø%¹€èYÜ9}¸'ÃL›Xè‘—§¦)åD³V…°Bõˆc >P'džœ¼¢;Rt9†r 4×R/eÀÙ 1üÊryÝú„¯qÿËî°úR„nVq–_ާӮ‡-ÎܪgÓÙ''®ížo€ûŒ>{Hu¾ªø3zttõG±]`YðHc7£¯žC0íx%зÀÝwñÞâ•GzÿÞ’Ú}·ÿãß#a~¯IßçBýiÖÿÁØðMÈÏ¿ò˜¾™¨ ïáñࣇËïÏR/&?Oð–Œå€dàûË[\ßú5\†ê¤¼Yûrx˳@dx11\ x”M¼»ÜÚ Ã?^Ž».ÿ ]v£(ÑÕuŠ•?ûrNkÞß)5Ñ«´s!ÆíLÚÉóÑëq“˜ä뚈Je¯ †”yò2ÀæÂr"9*–}™é”e*)Sy#iT•!¢Z‰¬xá4tM%5—ˆrÄ%Æ‘x‰®ŸB¥F ÔQZ4FîTŒ)dÇH–,’2æT\¤›TŽaˆ'"4L³ö©ä¹°!Qok¡è:hÃxM)ÉÄ N•X’B$ó|í„˲ôÏ©¡1MùiÈ‹†’™'J÷R~}júUQ“8YŠºRmDµK±_=#úw§|ÍC,ÞmÊ‹HÜDÿz²c)þ?ƒüï¦6šºjª»B±T®4žÕº¥hu³¿áÇ’ÇLÃR¸S}QKF;Ö]Lmé˜ w4=ŠÃ)9isë¢âD.*%_ßÒÛAø=ïÙ=Eúù®/yÍ„H@Ú»pïfE ‘B-—‹Tƒ;­M„òl¥zÃéân¬Ó ÍÅ¢6kÖð*øÝý!Îå8¬íŽC³†ûŠg©zG74äqa§z"V;+Ä›^åh%\S¡´R^J C£T9Æ,=­<&ˆîTµ3!¤t#½r›,Wc'ÜºŽºc‰0ëŲðûj‰…zÊUWi^Õ‚)Õ­ôéº^®ºv©)âþJ˜w÷½ £2î½R)­šî¬Y4KÖĉðÌ‹&õ™íèZœ¹?ƒYùîp<2È%ÌTBu”YÑtôquÖu‹¥ö5î}@ÊlKB'¬^\±Ôuœ/ϱ¾Q¨˜| E )HØŽFFŽd¡õ"òf Õ==þ· =H)ÍRòZeJTâÎõÖwâJèPénOóGgCQHEŽÜ«y uÂ\´ b¬ÎCNt=»@÷i씇;à|¢™a2ÐùPº˜ú×hê¡;ûºÜnÝ PVå#b-w“ßZ@ ¯þð²jaWÛ‹b…:àÇ?Á¯#Âf‡K` $À} 0€…ÿ6²-¿U\}�ü{³Ø'À5Äóï0Yéä‰~_bü—ž7ÈzH½k=¤Â…ï„hwﻲþ ìü¾ÝGßí]žÏk $àÉ×ñ½èŒ~¥ o½ŸÞfmK‡•�vl÷†ÿ‹Ÿ>Ãô‹Wè¯Í—~ù÷Ãþ^?ùÑ~ùË(׋^Óù.LžÄÀ5‘f9äN†žxÃ.û×¶éf°±¨Îöabã‘u ÌÓ­õsrÅåÆóªh-s±É¥8íSÖ$ðÀ¹ØÌu2Ì !®§"rž¹mkЊµJ”"D$q*cñS¡$f°Ì$b+2ã4Rf,Q4DÌ ~NØ$ÍGÕxå õeŠv”=¥D—XR« T”‘dB…+\©"_ÇTM™¸TÕ‰ÉH (Q™0/chHf 3ËÇbCî©4Œ$»¨-ŠIVþê©Ü(µµî„»jQè •›²‹66º;™v‘˜§®j)¹˜Žú­!ô :Áþ¤§Ý]9µøt]]iÆ„M>Ëõ¿oíQÐ)×ÁE’•>ä3¥NJ#9Ë} ®: Ñ4Î[*Çe Ê.¸××Önƒ¹ÞÒ­´Ÿ‘iˆ LŸ×^¹¹Ðã1¬WÓFˆŠ,}i“}‚õ¤ NᦸvGU­¤`s±¡ ½ˆDöÃv7Å)o©3p‚…Ÿkãœå¯ûY¸~¨é‘Ñ[Nvºœðedd!iІÕ41ÛOóPà<ѽ@©ÆuKä<‘-ÇNT¯u7@vӢͧUª$‰qUʹMÕ/«/[EPÖLõÕNÈOQ¯¡„â}#¦NJFǸâvÉï‡b)—F’hJ6œ‰D8“´PU$LH#£ÞèVžw$äXX")fš#GékÉ.WÊÈJq‰b Jç {ÃE/ÙªT˺¼„Ð…¤K,¤P›DòˆD2jÈb‘ ç„2*9Žš¥Id'¥:¡º”XzŸ:uÊsÉE“lœ²Êyï"!´8ÁWœ¨ÌSÄ¡$Bh©]š,0e:’¨Ù2O~neŽR´>Ofqü1U³xÍá¨aÑÒ‰V^xW%i <zE}ú„=WP·#æñÙs³pôs$5º 5»y}õÈõGvÀn(NN ZŠmÿÖˆ:}[ì¿-\ß2<§?Å8ýÈÑ�ÃwõÕô_Z²?ÊSú7džýŸ$&u�ýð&æÇKLÞñM<…ÿ޼p tÀ-0íQïß}¿ûæx_�ÔÀÏ‘ $ï¢Áÿ¡ààNØýòfVý|{¿]¾Ü-»/§§–œÿèœ-RNsyæaÍÆ(JML‹ Òƒò¯S;ŸÑp\ܦ1ºd6Ž›ùhÑKNMÙM §¢+,äDˆ‘Vh+t59ŸF¢ '„WBñ¬$¡`T)FÁ¡L/ÃìKä°¡9FB²Ò QØÂ„$ ÉóLŒR<K¡$ iÎÑ?z¬´ 5É…‘àbp�¬]ÇÈ åsá)²x˜ú:’"ƒ"‰ˆï IŒerÑ&ëGG” s¿–ѰážÄ®tP€Œ=½Ð¡"{à†í¼QÓ ]ߦi‘Ãó¦pí³ ‘·–nDSÚ®*9ÌÇQ†7*9CGê(>æ >ÞOý]&¾I™úUÙPq òóí<Ç=ØôÅÉÒøQNo¦/†,íBôMy¸¤a¥ilx}Ÿ·Î­e|4ñΚd…,®e_è!D[rR2U5ÊbÈ^†R&F§VŒâé뉇Àk.ƒã%‡àöSÜCá‘Ûú<ÝUKÇdëìÅ<U?²p˜äë¹ÝiÞêúèŽq¾æ¾¹l®‰ÿՔψ½0eµ”AË>„Ý|PtI ’b§ª°–¥I¤[AÛFÖì':AW¦ê–h[Ï“ïh8­ÙR-;>VîK7ÝÆl¡Æ"Vm‰ÖŽ/vÅ&wÊ ÝÝäî…šZbKaã@M>Ç9Ïi¯¬Äχ(IIÓ!ÛCïÔ̘ë®^J¡ûa‡1;›R Í&dEðÄ̪ÜtìVÅ š.Z-„NÌå!›4ÊLYDÞZ¾¦ ¥ZIuGŠ—!•|@) ¦?‘º±ç-ÚL ìD,,‘§QD^èli¼‹8’Ð5ÃyM„Yv¢eàc wÅy t˜Ež3Ùg7m>/äff?ýª9ƒ?Íóßž}ÒúqÛu<ùNÄ{„WJLA! ‚f^e¾u×ÂߘMZ_ÕHòöf^½ž>…×H«ß Æ’¯êþü nJûƒ>Áûñ|¡2Ž_}KÚ¥‡R+ãۢ܀ H¿úÁ¥Ü¿³Ÿ>�»±#ü ºùxJ]ôû»¤´ð ×÷wõïû¾=nñçÅø2Mß¶Û~ÄáâC<\ ÔClÀ�Õ»”†o?‡Ïdhÿ0¬(@€ЧNFø8ÀpÞ Ï'Ûÿ¯Ýé ‹{¹ýõÂÿzÂlXÝ¿œTC ÕÎØ’ RojÑÒêïJý(jÍèh°(q•e)éVÌSÎ|ϳ NˆJ¨2 'Å) ©J©¢œpÉJSxJ22C8ו4S,™R!ÀP$Ê!-™ùÂ9‡”‘‚)‰äˆ‚ Ù›\<¥®c>“%øLSbAf‡™Ç$£L ‰ÎÉoh –+9MsHÈõŠ”u<ÄÃB@aÚQ–8½!A¤y§qg ä•èÚUö7eRý¼ïÅɬ†ÆoORwª—d™t/bAQ…^€Ô¼\v¬¯«Á—K¹ 9Nƒ$ì)Ì×þt$êaeQÅGÒ¼`•¥õ‹¬Ë0á�$  ÝùæŸïʬ*‹õ‹¿oŸ¦PÿTÈÓÉÞŽñó.¼,»_²içy^𮝆x±)²£e¥Z-YФ®ê¤µËÜâf‘Fg•âÌ•’HídÅ´,i5gëît|³úò˜§~¯Ç[ËÕL»â÷s{ão?©÷ФqêÓÚJMû¿ yÊO7*%¿|E%“¯eÚÌws¼>Šzà- §«±ÖN;#Ë¢º¼N\%Mg²0³®J¶Îªª¤YPפ;‘½aAÑe.•³sœîìýq«,¥C‰CÖ_AÂÈOËaŠ›ó̧2])"%:1.¯7óí ê4„DÆ3ëî½tU}-â"ç•gõ Λ¬½‡v>y¿‰èXíUÍ„!‚«BiiñW…žs#¢šàPñÂIh„œ$óuKåše%èÀá¹W)ät߇ØBªîDÊ–fšÕ~îÕ8·Ç¾<>›MÕQ³J.ǃóôKËG^T/ÙŠÐZg‰|=Šóv>˜³½]:y,ã¯,½àñ“7v¥Jw-ÔÕâ«™D#߸ü±Òþ`ÿa7éŠÕ¯3­^Ñ ¤Gò¸+ðj÷úÜ GŽ�Y6?¢¯õâþ~o æÇ€ÂüOøÒß>Feý{éýÛé€/€S�Ho½Aé['iÿ½J.ßK*û†Ÿ¹ûòC¬½ýÇL†þ­uÑ5ÞmŽì»²Ë>ÎX}¿:\²A€“wŽ#¬E|h¥²¼=ùÐ�:È >ŽïdÙGàlñû¿ó�'€Žï€áÝGÉþSà‹·ÿ¹{†ê̼zõã¼ïðÛ ‹ÊßÞ^ÏS›¦þÞ?làþÜJŸ>A>ÉåÇ%“†@’˜pàéD%ב‰çy*Í€ý4WbîTš sùáTˆ%%Ÿ¦L•¦T)QÔ 4åJJE˜,‚sÊcÑp�)ÂQ3Ï<3’yEÓ`}I)ÓìKð3¥¦”Â%b¢=)»0xê< ¼ 9‰8¦RµIM9mÍû¾ÐFr³XQfh Ó8¾QE2«hYiUeG³‰ð‰Ô™$)Î’T¾Ü\xŸæ‘µŽøxìsyÅ…¨ÙUµzÄim5§åk¢&>y ‚9Ó!æ°5ûŽ)4¢[Õí ,š©íè"œ·ÊLåÊGnÈ?sÜŽ1v¤tÒq¿dÏIòAÿ”ø-Vˆ#ìþÿΖ½}÷ì2ËG„ÉUíW»>¿pD¬ÃrÌ&§-M‚EpœÕ®‘µ/"zæ½)š ˆGìCιb²¦«Ô‰êï/4=½àúS wǼ|§aÏüòF©Iwc«?ŒÓeZžò®ÒrA’š‹hâq‰ØY=yš‚¼¨<Cµ“ê.Fï¥ñPb®ÅЧlÙ©GŠò¢6©ÙqÉEXÖYøñ'AˆÜ-*£ª�>&2ïR•Çl&ª¶¡ËCœîÍÆ­6Féú7nÅÊÔŒå]¦~¨µ 'd06 [qcÌÒˆaîå<âËÂc4r÷cûõbªv7çw.+É’Œ”‰„öÈ.O,Ï'iŒ!5T°ªªj"®X« .ù9†¡¯„ö¤PJá WÂÖ£ÕÂKV ¡Êº@r.1%rÜÛš©™4™¹àcô ÷«³²oó¾‰S 4Î$ÍdžßY¦ªZÔTWI‘E†|mï)æ»1G›ðÊhKÏÛá5¹WiäKEŸ(q˜Î9¾d“æs(ÏB^³¸9)¹ä<†xÛoAnqðïøî'Àâæ ož \C�?sï±GyÔñeƒq¬Â²Á“óöAìÞåWÀ«·Bg9½«þþ;aÆß@±¸þ¡ÐÎKûß $>4zõ�öìOdY¼ÿ&¸ý� p8 âƒMyO°Û}ãHq{üÆyüî!qTþC`€üÀýGí‡À@["Õxòw_*¼Qó«s‚¨0Bò³k/-üÛdŒG~f ç»Òî$}Ø”pu¯ Ñݯs:‰9W^R– ®µ45qŸ£Â@lô·¹è¤>Pò(ñåÁ1ª²NéÄ0NjJ@}¤³'œdäÌ0A⌘ˆYñ¥¨œxˆ.dëËXJ¡Y†])’°"æTnC¾ó®=¸d)mH"æ"ïu¾/$”à©Ù¯iV¥Í²òÔ‡rœœO½=ãÂPmé‰u mT²f´nT§gðM71¦°ú@ÓÇǵ½’t™ÈVN£q¤í@„ÓV²cR‡$D(5Ý͉+²ê–Lø¦½«Óª·ë(¤8KöÜK&W¾çsªÊð¤u7×­5ûŸ©vü=ÿ¯œôÁÝï'¿ûçZF{Á¹U›ùý½¹S_2 q 8ÍV‚,˜MEF{”ª©RÌ~ιOz•˜MaÊ>0ºÃá6lãN×:!‹áçõ¢WI«Žcß÷ûPh59!Ô/ï­X­gz)NqBc\ï´”£Ì.Ú@ó®8OÚ“FòµáóE(£tSM…ÀìèýBÔ+±\‚Õœr9ÎÕæ(NBî+ŸÅ–·‹Vp.¥­ùá,ƒ&y¿·ƒ¤¸h#R8º4—ꌜAµ}â~V%V‡ißÏã6ž"£¾ÍÒÍUûÒù(VY6Wì” ƒf˾ì\<OG!ç˜|W%ɯ U qò"’/’{dÆ-+“¨ŠAÓ ´L¼.²ñEÛ²ÂĈ穬“YAPUf+}ÖPºEe‰)zŸ†18<�HoÙ’K¨-9…\³šráyõûBkØç%´œ.ÿ ‚Ȫ—U­h‘Äb3™"¦P|àÉ“BAÝÄ™#Ÿi½íð%±›§íÙ‚¹ç_÷ÍK¬AmCŸ=ݹú÷Õí>ÜÌ×›Yó›±ÌK ”DåA¼‡ßXM¨0ü*~[ÍßËç©dP<©ð3„à€Mø w€ÀEö³Ý½™= ÷2·÷!ÁÿàÊîÿuëüÿ]ôÇ].>@ªâ}þìC<hÑš2\«.Á{`/QWðßÜåc¦ôÇ ªÞÌ}wÞðÁ“p\Gøa‚(XA>Ó×/±Ÿ5CXý/U¼ÌQœÁGìo”î¯wz½£ÆìÚü\høôÜzÈj•AT„zÊ™.— g*’šVC¾Ç—ÓVi1ÚtWôÖgðêÿ¡Æ¸ñY*¿¨¹ŸºÂü½/ÊÍ9mMHD$ZAe­r!”x`éiœ‘™ó9øÄBæ…˜lž})Á'>ÍÄbÊ£»Ÿ'?ß3G_q²à�M H ü ¢Ss6c”ìµ"³·':.x]Yžf>jI)q>Zº+ôÒ±U.21A)R3ÕtÝ©¬Ä‰Ÿn”°ÍèöAaô:Åu[Ò;¦RB*‹A,°»ý`[ÒŸñþûù»ˆ‰/ÜéRÈ®$Ð[Mö\Þ¢ÜBL½?nšXBŽu¼2NújE‰6 ÇÉ!ób;*ny<=ñ;WïôÕd#gCã‹ù$å!:?0_Âɲ¸ø jÄô…’¢ç€Íè@7í1éíTòþ澜ER­™8S¼&lHÓ0^Lg;)ÈfCÙ‘,„LŸÖ¹6ù¼«•^ÈLR(.˜“­½wIñQîý4¤°b…eVr«^xK&QãU�� �IDAT MUKù”gÁK“¸ Š¥Ÿg®(ˆ£³§B6³ÀD#åG¡˜¢ë*p:„ÑÏÄΓõ_l¼µ»3’>¡Wk&.ÚJpV,…DÁ‹Zr-Ì}Oe)+Ë®J×ASÍr¹Ÿû¤$þqrLî›Õº½ŒºrBMÅ·ÁWE¬i},iߪNO©Å]ýQÎŒEQX…²¢òT¦ó*/D:z‘Ev…N&ž#D©(—‰²úúè|i领%n„ Œ–È%œé˜ÄÑŠ:–Áá1véxE—‰6¹Hc‹ˆeÜ’ÜçtgÙv:ÓcÝdwAF]ª~¹°uÍXÏ&ß”|)w½Ä¨@ñ©zþ„=i‹v²Ú,6÷bBø¼œúÇ1|”i|r7]#<Ä‚âx Ðkàûoj{W÷N�쀄 ¶ j¸GÀæÛþ6]ï�‹,8¦îwdn~Tq˜50ÿ9ÓÖ™4úÏTÿ@lH?©þpIú±¦?p 4owaßÐ×ßÞPO0^ÿ¹÷ÿØ­+é!ðgõ§çþ-|�œGðà?Åuÿ9ðE‹z�ËþÂê|¦N†r{í?!†Ÿ=yysùøyëP»ç™aZ#¬æ²,²ˆœåS™Õ\XÖud˜ùJI£\ƒ1ê.\Y[Ž$Àø™e%B´)b0ž2µ|ö5wš8eK)[3id¡4Q©=)3‰s¡±”±„’f9ø9Dï¼S‘¡Œ÷©äê0­Çð‰²t@}’Yvq@¼5²ÚX¨N‚ú¡ñ#ÅÖûe©j—øü”FÂCE$')ó”\LUÌÌfRXB1ÓÑÔÂiÅh½—a¡e™•»nÁYgl&7÷9ÌNÒ¸pÓ8Âçí1³1“Sê}xÄ:ß¶˜Î2¼q±±öNÑß“|¯ŠìÕ㽯îo¦î7N,´£‹¸ÛŸÒ;B%é8«ÙL ä:´ºm+.q9Õòqt5c3—¯ï^ºríå2Œ4û,¹bfwzÈWŒ?¦5)¿ìã˲¨2/¹*#ü8oóžÞBòrRËœ²Œt \TŽôŽ«/uPWzX²È!©kª’X¶½ÝÂÝÂmÝ+±žOS¬]œ­!~vÇIšíHv.Ã~¬”Óµ7ÿñL$FC—^Ûrª±¨…nuKYšòÒÃKoë©_-W ÙLH3? œìއôσÛ䀺ÿ?æÕ/±jF’Ò*â%£Q.ùbé8Ý«Ž€87ºÌÆÚk½n8eÙ³óÃ8ìì$«[Åâ ?«ùOŒi3WÛ<¿ÎîŠ]/ë‡$°£ÐŸ-OžV­fúo²)Ád©IÓ ¾\ïe·/Wtý„].j¸Ý¦èCšãŠOTt¤ŽÊ5ÆÇ Œ æÒèÁÑûØî#3Ä4ÉhÎ= œcCª°T©yÚfBb^dfJ'¢V55±éîmF“ßV’W`êS!‡Æ1•G*^we]"•{ZùÜ?ÝÿåŠuëÜñö³*ÐÖ¨=Ž3³7×ïM|ŒV «-®ß|³2æï°¡¼/V{±€»N9V;`…ö3ÔÜ5vÏ<‡$~U¾-µßvZúzýƒ‹_ý”ù'WçÆãâaIý½‘múмùót¨UOÉÿÉ?ßzeë8â= À?}ÌXêý¦×ß(ù1k…é°øà#<ÄcØw$ڇ߽c GøðKƒé» ÓK$Õµç6žöÃý>f, tk,éÝÓn<Êä«i}!Ãg¢{b+ˆH¿cd9IóiôÇR¶X¼<„…›?³SëäD ‚CÌ—>l4·ª&\ÆŠ®egÝ’WFúº.¨,TPQX±‚DIfrÎnçÃè¬/„õq̹0ËY,¥åqîÂÌJ Ê̦¥“ê\Î%ߺ™v‘t™ Jr’:ß”ªšÍb¯]¢y#'Ɖ” 4œ‡ô(ÄBÔ>“Ê1M“69 ˆ-œŪew9é¥0Ê^…‚,?uz?½ÞTœúÂÝD YÌ¥G:ˆ}““z2MjjXSsYùBŒ­Eö`ý=¿&/ÁÏk˜W‡—ËI¹EÑ/ez6í©¾ëH•:J7¦Cœ‘¤¯„H¦_ww3éúF:“¾žäç\ÜÒK/ãRé'¡?ážæaâáXð:²EÈ#)2DççÑÆ>qÃI‡zô1l©Sþît£ŽS)àD‘ÉH2ÜÖR£fŒ…Á©˜J•ÀŽøf´Lëô6®‹3UTËj׈žFßîíe;HB/·tu4e _éôBÌ?ëõ3T+ÙØZþÖ§¯çÀ´Vg²^W Êà’˜ƒ ‡ÞÈ—{ý‹‰æfŠlžÂVGï§`÷Çͭ™�]ü§>?¾=.“gÂZÝYðL+ßr¹0DžæQÑ£oøH„U<…”GJGFŽ¢"2:˜HÇ¡t¸Ñ¥-1ïœ|]B]BÅŒ/ èIÇž®êGõI.:!¹ÀiŒž6êZͯ|”iE.žšåI§=å[B¤ÁÒó@îc6QNIužçÔ†‚¬©¢y]‘‡éïåÐ¥òi ÙÖ‘ÇAîŠ/%Hé{N¼ƒc©K”VfŒëThC¬U°cÜIÆ×"ÔLLBÎÖöe_ÒÍä[ÝÝßg ä§tSºÃð˜}Ò¤±-Þ{x¿<NOŽA¼Æ´k€¡Å0âe^̳e_¿³?rï*Õø C{ö³hÁ)û¬{:ÈŘâ;d ¯ßé|ÁÇû"˜ #<²Dú^k„y¤k(  <¿&;_Â1Ëøî }ø`?ñ±}Ä_Èkï[¯lûGŠ{ývVñ>úÉòãªwóŒï€N€$ÅÞ‡1kŸIöX%ÈòžÄAb $ß´jÀ�_{@Íê 4àÞáXÚªªåz»F{¿RX]kâtòlow’Üþ˜vš^°G-¯ÖfÑÔ„!O‡œŸíéÄêC™ªúç}y4ëã6W»ùê–/õ7Ëär„¸ÍSw ŸIjB¹ ùUfÛŠ ¥——ëåž°©"ʬr%…¤Œ<¤H‰,LbÆ¥c³‹»%éÆN/£ûE,,v¥49 BêœgÉn9ëj|J³Ìá 4æ€È^O´É4éHþ=%¿w¼žsÊ´o‘ FÂØJÒÇHUL^:8R¦Vz˜œ,R™‰@aµ¡MÝKYŒó'ÀR"œh3É(·Ên\»)Že¬í«È.kRA6Yó¦’SÍwVÒÙ²c_…_ÿ�ÿ÷rÙÍþ¢Ìê4èïü>W/ž\ž¤•ô 冒ßuqšìÄÆŸ +÷“ϼo—âš›2&B;JÖV¢¬ªsgýl‡!òB©ç¬‚»r.Ú£¿=ÆÙ)ÞW]Ú§3X˜oÝË~Û®«’¢Í"ÙpËÎÐÁE?”(ŒÊ’sGöÜ»‰å, _ŸŸRÕÈ-±¢*l¸˜OŸPbŒØk>èN•tzÒT¹«ø± ­ZHORÞöV_‚Ó*“¹)L檙Ÿåa9¶±v”|óˆNÔòy¦·\­.«]§–%üÍÊñ•»rñ4Úf´¼eh¯«ÎÚX¤?¥«’R; r]=,Ÿ³*/¢0XMlA„è0ç/ÖÅG\ž3³Î+ÄîÉ¢Yµ|]WZIhöKwÜŒbK}®Ki”I2Z|¹¦DÊ Fˆ�G­9áua÷>nF0ÊY4œ„\2AŒŒq©9#†ˆå¸¾rçQu’ud² ‡â•šfF2¶¤L0[Î~Ì…á"3uŒéŽóUð•œ=&M\ø¥ ™¶÷Aì‘[ö “š“«9…¡ê׳H%ìÌx»¦^K;þH.Ÿâ”@^®î·¸ÎØê€ÅŽQ\ìÞ+çxFð¸ =-'—X?‚:`wæxq?˜*”Iàúˆ}DsVhF(öpí÷׸ÒáÉ[䘾·JN0Ìg'<à\Ûäã À °ù3:|ÐÊaÏŒ÷X§ß.ùóŸ X}çÌÇå= Ö)ðú R‹(dñO¾ñ2üð‹0„‹Ý´uðÐï† C…ñÅ�àù[î«H6áÀpªPI¼Ù"CÞ·–ùhnü¦È’|MŸkâiå>÷ Ö¼Yv†W*Ƹgò²"S`– 3€ ­N…ºùYÊ…¡³½s)lÍÅ,eŠ´Ýßµ«õÁ–~˜Î3É>͇òÅ ý /Uõ;A†–ÆÃW…»…ij&hûè‡ Ê$Ùe1+V,kú«1."c(YPS˜Jø™†Š&Bë¹ã׌!“™Òc&H0‚­2í©:–Ò'š («&}*¹¦õiÕ,yM%…( Þº¢ËŒzF‘)#šN·c »)ˆCŒÅ"Q”w”L(“ªgÖΆ[Êì1éu1ÛÁñQÄD*ž¹([›Sÿ»ãmô7tþ/ŸÈ‹“ºÆyS¡9-œîòÜ»Jþ{ÆÆLŠž…_!ZÔ韚pÅÏ_‘ö™ðñ²?VF€æëšüÍ ·†6Ù¥æÒÞº…Œ%‹<»riÒ<ÆÞ”ÝNù¼­î.ÁÉLÂ8¿´nó& 6{iÉ#çzÖ2WJ ›]ß§þ¦4¥fœsh•e"õOW´>% ml(SØÕ •_H¡¼²½Ü“8Vå¨x˜öñ¾‹î&QëSÞõóIÇ2=é÷$Ìs…ûbö­mn÷"EõX±# ÅS5æçZ@Pmµî¥¥î¾²»;_Õ–EŽOÛô³E2²hÇ´_t¹ª² "5•{ž÷6&™BbTˆ¹R”ƒùC »’Æ3ñÙ£Uó”}ÒQId+Úª5¬$Ø~Ú óáõ¸9}h1-YiZ!Q„#Maž”Ê–ù.ø§” ¦PÚ�GKÊiÎqoSô„1Eµœ…¨L %÷µDHz /ئvÇ¿[“y*>–ãTª¶ðµ\WÕ"0.KZÌsrjÛ‡š('É(Í#-–c,2ÉŠ|š²FžÈnCÒ+]!ǽ_oæé*b@5ø„ºm;RÝË‚4O³j ŒÎBìÐ�?– ù ^)Ò/ÅÓ4-×(AÀl4pÄÍ×o§‚S€Ã°0;œJî»òö#µ1ü‰‰´Äì¿ul-ðñ›Ixõn^$n~Ø€:ý…±¡üÑ>ž@]ÃùQoýŸí }Ÿ§»è1õ~úæ’XÓ·4Öçá|Á?„Dól ;#aÂ80æÀ{�}`¦Á¯Ò?-Ëâuo.î<ýý|]íüš<µÕ¯«}½Úy½ÛûU0ÍáÓ¶iE"Ò‘ÅüU™¢FV¢ÏòPÒÆ;MoHÖ+y\.«Ë²•fK²uEÑ©³¿=¿±‹ÿ²\¼æÿ$üQbçΧrœvä¶NGSªÀ™ } S&‹ a¬S¢ÄаÄH#"%1ÍbOÉÄ{È%!Š š¼wå€4J/dî( ‚$yU8 ôoIêê‘–@@2«CwÀÒÇ®€p¥Z£+®'¾dDÅå².ûdE²)×D虦)ŒãΗ} !´òµ" µ–QËœ´%¡õÚ]ŒÈ4O‚¿YŸÎ³¿T‹hÙ2ņF!æm¸§ÇßžöÿIY-ÍWY±Q]2µV\ yú×ËÔ’ÆW[Sèákw‹¡F‰8ór¤žGþ܇ â3žÐf¤·|λ)”m}_='EtûD§|Gxa³’ŒKC§~tÜç" ¥­¦Ex¬^y3l(u…(±5ãÔ‰¼ã]Ï^Iû‚¸a¨DaOii´(\PRÒÙø¹˜®hß9/_1Sñbš©»fÓ¿N“>šÓx”vSëÜßѼteva»™½9L´rû|Ü$œ#›˜Íi3–òÅ}VK¡[vrô‰¾¹|Üõ—AÇÅ §A,×ÄðP™Z]bµjWd­A‹Ë6EZ-ÍI R“;¦ÉIšì9=Ãlx“V·Ò賓Óe»:=Í’ò"‘B!ó6‡én{wóæzŠÞ“¾ÐÜíxAöÇ*Ï}A°ªŸüLÃËqrÎ×Uuν&ÅÎ)„l‹µið»TjYêe¥<¬N£“Ûœ. 9¤%•J“’ˆ¸—ÁUãÞ­Tnt˜YY!Õ)ÏCr!gCµXi,ös¨²?·™zÅúÒOÁ¶² ¸ÇäÅ­¼;\æ×iætl¹Ïiµ¹GÀaF<¸C¿…œ=ÊÂ3¸çà*†X@!Rµâ©fäˆí&×È¿3`—H_"Ïå%»/ý# —éOæß:Ãhû]=û?ª``@·Àñ¡¼½W!ôdP»±õ@~�“kÀÇê#ÉþOX»~Ï[é»—D¨l~o”“€„¨ßƒän‰ÃêsBJ €f ú=*@Ãs†{Gi:?2þUuRVÍqs+wo¢ÿ,_)\Ð9<óòâÿÏÜ›-[–\ÉasÄÎtÇÌÊP &k6Úš”Œ"ÍôªÐ?è+%Mo”D¶Qjtƒè&ª ¨œîx†=żôYUY#ÐÝ ©ýxíœ8{ïkæ+bùr÷G¡ï¼5µÝE‹O•n¹ÞMºžÄûKàjáa”ìu<¼ôÇvÿЮì®íôçΜ’ùÿ=žˆ¼–G û#}øg¡4?Ëâç±{šzÛÙÜrcac¥qÙ!J,¡ðÊç°¢4&SàS¶žª�—ÒëfŸ˜ÏÄ&+«ÌñËKT ä Õ±¨¿#þç•`ˆ¸¨’{ Ïæ§,_l7p»ÊUÉ`À5 A"×& UT°ÅVÁÊ$sEâKÊÜ R(ˆ9ê¿ V2™åÈ1™ê3¶Už+ä²ðuP·ÞË[uþ¹\]nŸ}L|>-Z†8íór^ß㛳tiãjᣯ݅ìèÂÈÞŠtÖÅDóñô"ÓÆÍWA†Î~&s#WâÁMýþñÞühv¹›f:fe?3F Ë¢'$CkXéw[n|Æ-KSÙ¯ÚQ›ãëüþð¢\²Î‰Ô™®Ä ΤÌöàjËIŸébz®­}cÕËÀDÚ·aÚ•EïUŽšS¥c®w)²B÷Á‹ºøö¡yíÃq]¼æMêýïËmMlH«Ón垬|¯Ÿ)Ѷ­¦ΓöQL‹®É#¦¹ú9Ÿ UÅÆ¤D=Küa6·ñœ ñº8Ý?>ÛÚ Jó(Ôy+Î6f³kdw~&ÏLÁ&.ÝuŠ*njªH1™údD|„¼n$[ëÐ7}׬ß_o;µëx£ “…Ër_ÊãœnêpÀÝœ&6H'Ó¯kÚkŭÏmô;Ýùmž§Ãœ˜žŒžbíÂm)ûä)Ì,‡œ0«˜s²S ŠÁs<q§ ¼¬Kˆ%Ô\çt•R¿ÉnMâñuØiˆ³Du¦2)’NÕ®]-õLçFÙ]cÇ&Ø!-4©)t‡‚¿wýáÔüç×jösDûÛ}h?jÖsêÿö…ùÑÆªCM¯ôg Ò Ò</”žá…” Ü�à²ßç‹6cÀ5æg¹ÔÛ¥9=#ÔÓʵú¥?C8Þð×ôYþº"¾ÍŠ{ÔùòÍžý{[ëß#‚…E¦*u| ‹óŸf°õ¿Nm�T„þzÏÇ}§ßÆ?òâ v/`¾ôJ§Ì¾{æ8ETd`$ �}ƒàc …îÿ®oWxY‹=š „÷ñYñ+àS¼x®áÆÛO¼ÂAþD)ægW/Äkö`WõGq~7ïf %ûÖðÂ{™F¹|RE}k^Õ‰ãweî"Rºžº¸YŸèÚ–«¿´öýÈŸÉÕÆnšÖŠF¶šI)ÓC-”H笘PR¡aU˺šR^¼–B$ÝtD]NI¦«ÀÍRy®| ~[$*ñl,É\ëE~dþ&12&‹& ­ —:\®™¬Œ´â…¹Hœp”´ð’C”µPS´X8yh<«ËE2®r"¸IÌ8Uz™œ.ž©UAj3[6T—Ø!Ôi0SÄ=rêj“µ•Xæ)T¶O£ŸÃ'÷½¨¿°òrÕ­xRñ4vý´ ¯Íbé•ä ªBÖ~п¾sÛõõ¥]=Y‡œdœë‡IlM6CøX/{yÏü:Œ;dÝ£ø>ŽCJK<wñüŸžÔɳմ´­å;–ÖmÛÑ>™C™‡×é& sÛ]ïv=Ógší6”t37"(e;·æÜæ"),ùèŸé§l'éJ–ÁøMb>…ÄŽ žóYçœèq(ûÛmú9§ÿCÜÿ¸¼>_.îkœ*U?©ÎVQæ IŒ"”âjTˆtàÓ4³•ŠõÊu œ<V³ã›3ãÜz§WÒË7ÌžY³Ûu»U»JN`“×&¨–AšM9p¡X&}Œ<)….n‡ä3_qVÏz¶ƒÜÛÛÆÙªÏ5å½OÏïÃþÞŬ+ÙÒ¬™(d¶InÉŠƒÈ>OãeA±qqjæÜV+eIóó²T=„ÊT­X¤½uÖºvÕ¸*©`&h®-E2è”u{LBøVÉʘ S~)¨06„™<†œt&ír“â\;©$ÍIs8àa‘yq{¾ºaô×YBOðËÏ0™-ûÉæôôZ&u1¨2ÉËWís„{è¸ÃK³…2˜Ûç“‹Ø{; æ1þ[²±q…¨ñ:Ö÷ÕÆÊV©ún‹~ø ñãW~Ó?ÔZ¯_0Õ? ‚‹_RâÏpüê_ì‰ÿIЇÿ"µáü«}ýÛß(þ[>¯þÉ?óÎÐî:áÕ·¼¦o¼ñj‘î­Þ¾ýÝãY˜Ÿãï¿J\üµC¼�à÷ÀküÕ3  ð¯þÅ0Àı==ëâöâ|šÙíÛÊÍ(Ý45ƒÌ†-Löªqyóg³±=nNª]3¹#*ÝgÍÎv¡Å^“õ‹m«nMÛµ5ÐȲxQ*¯ÅU“‰knǵÕÜT/²²J¬û`Òq”ô»ª5dœj $OA;¥Ï*UasR�/¹.u§æçvx™Ò®v]fïM²jyÖwkÎ%çI‡{¬drfiDÍ,ψkAFGÍ…¼…Ú•”’úZ/êZTGª1Fv’ "“¡tºé¹¤¶OFtD?¡öÇ]ß3ר¤y™‰/¢ÞO%¿î§ÝYo:Ãæ >ä¤BùOËİ’_vçéêú¥úï^uÿ¾K¤å9–¥Ô³I\ÕM+B1J5ã¡ø–†É]_·Û°œÅrÍ…Pv+øÝßW}ݲØ]Û[b êÏøÃXŠQØÛ{‘|j?VÝyÓ¬Ù–tê´è*¤Ô5¥Ó|XÂa?ÜÖ!öµÉò‚Ř™¸cŠÄ‹àKM<º¡KŸÛɲOU¹“ê?[µ¸÷~+ßÄ_¸î*ÐÚ續W±ÅYNi¼¯3÷ë¬eÓ0 ï«K],’1-ˆ¬þþYÆJ‡^~¤×žéµµÆ ÝÂvFXžhdÙSºgJjÄ–q9-ƒá|šNãÂk6gzÕ± o®ÆªÄ¶³mKM‰bB=ÕD”«õ2^†|:óiáµË=×bG 5­TÓIC“ü>Çô0JÞ—œÔÚ°FwÚZ8SDNk‚%gY %±u±Ú v_!#‘kÖÄ!TzSQëyZâÀX|ÂGò…‘˜ à™P›•îµÔ²£šû‚^TS TÍgMG±ZÔ*Õ§rz¹9ý¬ýìgeËêS]¨ø™PÂìÞ#?"öçûgŽ×1|z8ۊؾáŸ?Ã|¶gš"&°Ì@¾Þ?¶¾¯ãÁSŠ%ŒåHˆàçϰ<ÿÖê×˃—VÓÛ/Æ–~@÷ÎpøZåhpzK²êÜéá¿Hm(_€õ ÐoêÄé;èù0—ýÆÏp â ÈoWú²¿¤é[¤ žÄ�ÄG<Ÿã›o5€€k #¦øûúÖh÷ ß#°�vqç ³«"#öènoíõífyåÒ¿hªLZ:‰x'ë]eµ.œÍóãg«Ð_=˶erÝÛ±Ý*?ŠºNž%¦–x(l•² Š{–ˆq.¹l¬@å iY¯‚P³EEU+fS«Ò†2–feª¨­FCü\h]¢Š2O•-”Àb)Š˼îWTØ )•.Zf¡£ŽCMuÈ}Ã} ^ù ià† ¯àÒž e8DàÉ«„ÌDj¥²ºf7™µ'nªcÁZQVjß§Õæ¼[eh·Y¦Y¾Ñý.×§e¿AV¯‹VŒ…*›I©“wJÿUÝí_ow/«ÝFUôÓ®þ²É÷jyôSˆücÅ."b<ÏOxfDZF<ïvÃ'éÅÇó?ïF{6É•#¡ÒÝ«ŽþZ6é}qùu ¿\îÕx¼”íåÊùA?DÖß›nÕw²šfÔ] §² Hs>íÃýïǺ/Ñ>Ý©¬¹RS^2†ÜΦ$Ì,åGY”g3 Ó<<ŠÕéÚ¶9JcVWwêê7Üڜւ¯Ó üŒAÇО6zUIQÚ/SÉ,ßÚ¥çfhBÚ3°’Ì>ÁhU¬¸Š·²+ìᬬ35OWxçíöÊj*&‡JE&ÙF(˜"K%ä”e‘î²4¡s¤ÓHV•Ë­â¼ã‰q8°+!7´„%Ç=é»*\S‚W£±n0ý…g½hdVÑL!\ó$5iòÕùUWºNp#GfÖeäÕ:¡¸i²æi‰šO›ÚMI¤ßÇ4Õl«—5x*k­æÂ(-øÀä"¥:´"Tý˜+ù,‡â˜‘+½ÒMqÚ ÞŠ%Ç%FÃËJJÅ6Ò ÷æ\•Qh@ã%�� �IDAT3Hƒåý°ô!™O>‰çÃ0a|8=Ç!�õÑy’»“»gì¦QD;áƒañɼ˜°{‹0£Æ'åB'Í1ü¼Ç¡Üˆ/ðç<âò9–ˆú}Gú–û—VÓ¼.ú›»ýZaøz3Jh”øß¬6ìßAïåË©áÛº³?¬¿øWÅ ~÷o!~ß[ €Þžn8¢ ð�Ü ÒÛãÈ S°žÁÞÞyð øØBoEœCý›–/múDàà± ý®´zÖá!ÉkÓ–’ç&³2 ëf“^ÿ+[þ àþª¿ÏwÂ_yÑ–Ò‡«F Áÿ¢Š=ÅU‰$ãc8æSë…=cUŠ*M)°(Rø˜ªOšB'˜®Z3Þ™*œh¡äìýq9fÁjw&•cœ8Í”eεVUd#á£,IbËWFÈ´”yæaŽË1ZÆ€.£MQ Sô´je³r14â&T)³¼mDçÈ5!³XsŽEV¦«åJ …ÉšGÉXRVÈ*j=gác!øÚ=>FøNXneÃ,÷±žfQ¦-°¸«ÐMÛ8‘«KB7ÕÙ§ÿÖ'w›þ¬Qg*aã]=ôy©û¥¯UgÈz_‰«¦nòéC_/¯®7/V-Z†ÕëtñŠof¡h.ÖOËÆÎªW¼e2-B›åÃú?©j9[Ë~݈DŽùŽR³ŽÍ’ô1›Íp;ηòåîNÅ…¦¡X…KåÄcµ”…µLsŸÃ˜r˜Ém¢Ç½ðÿ['þåÜùÆx‘6Kí¥•¡ êœRšçTÖܳåˆSÓÌ‘fm÷¢C ¨}mšÓV=…maç¶q¢žj“‹ËJ³K%ª³fӺλöââwRe>öyFˆòÄ…#£ƒi™\d2*3…Œ1BrK5Ë-“¾ V³M…-Þ3?Rôã'íÀW³:03YWV¢7Älâ©–ÙÇÊb—ÑȆêºÙ¶ÝZv5:FĹLQ¹MIIÇd3s=Tã‘©dåH·iz™ä+«|Ë£wá}Š$”£É´YL äeŽMa2@.žÅcí}N«ÒÙ²ˆŒLÈ`Š(ø¨Ó©c³uNŸ\ög bdÛž>ã«W¨Ÿ3zxîæÜ̘,�Ø}ÓqÑÏ–D£i0F  ~Ü#ºx°¸7@vðþ9¦7º‡w@LÄð…áðæ]FöŸh€¡ýwï’¿K*ñß„o˜þ¸òOàÀ+<ߣÿág¾Ì&ü ò#räK”Úé«q®ˆô[Ybfo{VËI»Æ³F¯ÅŸ›!LòW÷8Lá¯jB­¿^ëK7,¨;°O*ÐuVTžÛO±¿ñáz mlžLö”šÍ⌮º¸n)ÚâY¹( ‰·#%NG>Ý¥ñÖﻬaê¬ q¶‰k:Åj¡s¶Bs%²”ÔYÝiË™Á€9úFsS¬üXb)XP“²\hÙÆdWÓµ²3·“o—eŠ{¦xè*qÈ*i^›B:+£] ª KŠñ3^gANJeXv†ZÈ*…$)¸tŠIV|Õ‚Ë@IUÉähíë¦ÏØ”áDÅ4Ö¬Û¾òf¡¨7²Ý×Èa˜/k.0Ö6{›µŒéqò W…žŽ\?7Ó# M݉Ñ1áf}™ŠÑDex$òQY­qQ`E—-r†ÌR-qSHäÉ·¤xvHWq,Eܪ«¤dœÜ±èfФe»jzáSÖãƒ`)C›ò4å—5>ïì¨D;áxŸòoÉ~¾½àV_ÍÊäByôó)57Rž=uvÊS¿á[»ªÍÎn[VÙŸ/>¤ù˜êKŸÍL]È~&McÙ´\EÅØc=ªÏÕ¤¬E·Ò}×VWý†bõlJáÁK˸¨jym¤»PêZàŒ°RÈKŽiJâxWE9mª['©Z¥¬T|†Ê!Á¦dæÈ‚@¯4—’‘AžãrÏTšÅ1–.¢ ÄìÒªæÈMNRÓ5ÅL{^ÕÄóÈÕÀYGÍFiÍš^lºÚ`A,~Jyà“—©cĪÌ<VÏyâU í„Ù7,ˆì–ùÇqz¤4D=7…˵³JŸ¨¢ÆÈ Ês˜` <G¸&FMgW:f >V*¾è«/åô˜â" ´bŽÂ½™ò®£Xuf­óZ#0”þŒFe}â1”6ßüÀôëOÆý‹™Âªm FúÛ:ï7Wøè|'?ûüMŸz£‘"x>ÀÕ\Ò¯òŸÌ¿‚N`øÒ6ô]Žù pÕïmÑç9ûÍ]ò[‡WVÞ•Ú}ŸÒe.ú¹Ì»ÉvßÑ#S@óµ”  â…Á6hàøsÔ?\ @À(_Œ?ùö­×Rÿ¥\è€óEÅïVÈ~Á'ïÁˆ]ˆaPÍcÔ@\°}…µ¿X__ ³ ¹)§˜P<DéãK·0×§x ×©2Ÿ\96)*õQcìöLîÖáIÛ^J~@S8zèýX¥ Ü KDùÔ2²f-M­°<v5¯S`…sÍ…SçW…q¯‹Q\(-™(­d]P³¤Pt¨’ ÙZÞ­ô’Uªªµ/,Cz¥|²{¾KÊgi3‡U æ”5¸iŠoh0<IªN¤ÈùȺÈdSzI³JUR‘`œ2Õ¹0ÍlÇ¥TÂqÎyN<12=JÎs.º<—C¥ëšƒ_-íƒi:²š˜ ‰Mý±-Ê`˜Q»*"cTi¡Ç.£É7ácwƒ\PÙ,§9¯Ÿµ¨Ê7›V™•ôbsÈ77,Ô‰¯Gu)[~={\Ž‚›rûÐg)ÓÆœC•Øuœ7˜æ6b’è;RÂÞv£ðuÚ±NÔµåÝ\ø¢ièËŽcG;Þy_XбyŒyÆl¥~o¶ñ?4ËS|›·Ó=›“(gíy Mü=¿ô“èþy«¬í¸”ŒKæô:ÆJ'ËE)5O#¦€1ø'üÈØE'U×’'7³z1 -Ód7}}b¯ëQNwjñˆLë´×Ú Iu-²±Æ®líElŒªŠ[¨Ó4»0¦¬åélIõ…eªªb«˜]µ¢‘ð¡fÏgVH •&ŸÃã¤n72uY.Ÿ 2¶¸•ž9wÚVgE’É)â“j”Qkr[òÂ)át²<S¾]–š—áQ³Þè  D 9ž83àBJ.U>«Ld¶Mì$kaB(GŠÎæõ¢f,‰;¤™1Ë|¥x-+­VλVs­£X©j¢TæTCÒ&W1®I—£ŸoÅç§IW&ã$Lö[¤z®iËKÎ çQ¸{ÓO¯Õ„k�§ˆµA½F+0”Çþõ£v²<ÛT8}4Ç}¶[4{Ø=6àá£Kõ"> œkLÐÏò;ÃH x0ÀKįÑù"ˆà„e_—|³£î€‰4ýDBß4“øÿkm¨ßW÷¾z館û7ï¢o“·ÿ:O<B}9;¼íÝí@ÔˆB@÷6Ðgà>ÃàWÞ(õÛF^l¯¯ž\öM¯$6ZnÃÌÇö³¨ßæ=¾ÞT1ËÊßøWŠýǨþBú~Õþȱ•é¶ÌµQ»<}NyŒjˆ†MyY¦]ÌfèLÎŽKqÒÉ"d¢'bYuZ7+¡;’Á°Ø7–ƒe^b3;»ò65ÃöRe™.“<J/¹Ùf< \ !Û—žÛƒ´ Z0,†Nµ(vª¨™³œ)-ÜŽ\õÙò 4uŒMRxÉj®5•ÈUdPFH­I‚R|E9"õXl±f® Üø¥¯ñ±º©YN#©ßÜ“f\¥lSšjß÷?¿/>•‰?TK…ùigÚô‚xŒ£>¿våýÊ^¤«g—”Ì*Ÿ²€¥z`ü®#Ðþå¨ëså½ô2ý§1œÿHˆ¶¦þ7qýtK"'dçI#çÍo^¶P¡^Ao‚r¹ÕiÚ—(î;É·bªÇ šIK.«0n÷Ñ?äåwŬ¦wÓêÏMý w/ÉèÀÚ»ÀSdgY[VôÿXñQ¹ü×.k“µ-ŽgÉUK-ŒsC¢ÓìÂbm4Úö‰çkaÚÁ=!­µµê¼:áìʦõN¨$âH塤!×óÞ*eYNrVcÞœmÔSÉ£e÷Lz„ûeð§iȬŠv^‡°°»¦ÂøN‘[¬N´¶i‚ÓÝK6)…Xäšç”S…r¢iú‹¸©Á•¦{ABKÆ&*zFN0e©ò,81å”Èõ®ÄÇg1;[Õ Î+s-«J¤âx6ÜeÝDf ´iθP©Mm.š+-dï”Ö"¥ªY¾àÄ”ªYR²Ô.[:»Ør• K´†ä$f*ƒg•é-V¤éšF²{&>?µ7§¢îYÚ"3G¨0Rÿ*_Á^IÖÙõ‚ùnÕ~rjð÷¨Q&”¨in�†ÕuÿwIo+"6}ìÒÏ¡4ht*GŸéoü¢€½q[Šùë:ß„ø(`xøf'ê\üÖàÎæ „<¼FöôÃÛE웉ý«Q¬L[ o‚–ÿdµAÿ£›bßí‘þ€“RþÎ⫯¬†/xﯹn|­¯õÀ0‡/Er_=Eúº¢B�»:"(®¯xôqÆ €/åâ ʺ§R¾'uÏ#ÖýºÊ웘3¼Èê,»M<ãäÅÅm^ïOì‚â/Öûm¶6ó¢Ý¤£ $ë<Œ¿^ÄÔè–dgø%¤«èoDí¬QÆÖUKhµ1fÅ›^(݉ `yÙ "ù‚íí ’$!¡<˜€ô|UJ#ª©Ä™ÌÌÖ &¸)r–Ü0Ç…,šDºNqŒK9ŽBûV¨dMzÅMW4$ ŠQ¢r‰ÕZ•«…s¦y®Ùû¦”‡”>‡¸ˆA>‡™Ÿfx*"§]M¨êõcJ6måÜ\²uïú’¼Ì‘^§°I¼ÏÙQ¡+9<4ó¿×¢ñÝUÑûÑŠv£I¦}Îq×UëjgåuâŸØÍ¡S÷že˜ø`3¨1¥ãð“Bgg•‚0™7L4ë§ú£¿<ŸNúwÿç礸mg{GgÝM:ï”n•ÕZ0#Ã0OÃ1L¢›¦öqaéxz¹\ü;^þ{Þ_K)ö§AóÿªéIZ뻵Áa¡¼ßµý¨íþGm?îH%¬ã’ 5<Îq !Ž\FÓ5¾iøVö+¾YsãO·€ÜÏ.º<H>®MÑZm.¥êsÎ8„ãÍÕë4ÌÅŽ´ãÄ[‹–=[ÿ|g>.3 ÃMe÷F<Ÿð0v'Ê"ø‡¹µ2nÄ#àiÊcZJ؇"›^ä &¡¥9ƒgl¨,K˜P.#Ñ&î&)½¬e•™*5Ö:I®  ƒ!Hb…*Ï2dÅ8g`Œ‹§xrqײ'B›jE5…é’8çµÑ T_¹+Q Ig¾0—EjUØÔª—Œ±ÂS!ð M²Å©2N¶Lª„­©ÝÖQGdHQ”À˜Ø':‘T\l¥ÞF¶+9›ÇùLÅZ(èé" ¦£//¡: öP"›ÕhøùW(`ñw@BÛÄñ"ân‹Gà= ¶—ØÇ-Ô3à N!npPxviÿ[v›óÀŠã$5büNïé mã÷íŒðú;àîÙQ<‡/q\| üß.¢ßIýb+ÀlqÚÀúOUþ¡i_»­ô‡?ÿ^Ö~1ƒtzçœ1}K¹= 2Ð^#½óÍ»6ˆ:"J`p ê³òðœ#j �8èKÍìj1‰Jj³Z™–¯Ø¤ùokžb¦,Ð}<÷Ô"Ûyòª­‚èfBáåúL³_9àBúµX¤àA®ys-dÃ-’kæ:k×k׊Y!…ж7z]´“Ê@THy00.”ÖÍ=÷FN%ªK)•"­Êkµ>WÆxA¥²¥¸ƒ–ű®™ámŽÄæD|&,«Ø¹ Æ°l…"(V2ÅHD5/S¥óRˆ X5ÚTBˆäcêÁ–GEGP9@„¼ÖµãV= ôÚæ\Ä*µœƒ â…Î)¯yÝ4…G6K› ÆK(Ž8ÓS¯S9Õ®žóÄ[‘ûtln²«À”ŽýÒïÈm>^kwyfW7êì¢l5eù¨Ôˆ Âfå—e3`½Rí¿úŸ~öÓ3û¿~ùÙÿþþÝ­Y$ ÖÞ¾—ÅÙôÞΗ†™¶Û6ÂA/Mw“UšöC ]C¥Í+ñçôªf58¿üÄ—†$KòR´\âìlŽ(]öëvˆÜ71#÷â3ŠÍd.†¦O¾ÛÒ¥Æ6èv‘.q3“_æS%Ïëþœž·¸Q5$w~Moú"ì¸Òù2©b¤`ã"Ö«ÍúÜm:yÕ]÷zw`ñáÈC8¶9Ì$î€Qó¹ÓÑx^„‹<.Y"åÙã1Ç9Œ3•»µiE[w¨lˆH<%¢\U˜´8ò˜KU3É%«ÂQG¢–gÃ#I'‰Y²6©ŽD„™¥Y'ÃêÚ6Ï´¼b±È¹ÈœJ¨¨"p]jâ!ÕXêØ¥LÐ:«3Á˜Sœ˜(T|¤Påd\ B&/SªI X‡ÔºÐ­Bu[–,Ë è®ržÅb òÂb™‰¤F6[øö÷ÝcsìŸVÞ¾êCÞ8~¹~ÿ¢È»;:ÈV»+¬ðÏp4²½˵ØmÅa . Œ™`+{4ùuÞÝb®ÀÖbßV}:<û.u¦Ÿ!¾kõÁ÷°ñ ‰/‡9{ÀéMóãñƤ雠ú¶ü¤FìXÖ˜póí³Ç?º6Ä`axö§HŸø¡e bïJ©ÀÞ‚þ‹/þf`á·¯ž¿�:{×"WÏ&<_—/Xî‘X€ àÀðÇv{j¯”{² +¯)ÉÖÈÚº²à…d˜KÐF¼lÓáãpñI'ðtÎq‘¢89Jºô‚›$#¼—ÑwëXóu*k„žqÎX-ºVi•VÆ0ˬ6½ë”R…3V ¨ÅW¿„’¡QER«Ìç\ÇÄx_¢Ü*Á O“A]j%YC“j›ä¨q;ÈöEjž:][Ëûª³#Þ08”4Ò5Úª*©Í…UrñM%ë½§ççR‘ª`qO©PJ¹²6±–T`Ì·©A™°¸rÏ£býLä—ªÄ|H‹Ø–j¼eõÅ”vŠý3©7×iÕd ‹PV3'ób0"Š«;±¡v¥i¦Ýä\Ïa—õÚKÓn[1°ÒEuwf´œ5n›°ër÷ãÎüá?ûÑÄÊÇ\›_¿¾g¿K- 3zÜåÊVZ3í:³u—g£?¿ñ{ÿ·¿_M£y¨ÈOƒpËœëPe·LWªœo´½hõލ©1•á”'Öoi8®ÑvŸŠ–|GöŒ5lV`ÝÍ¡„%.ª(œâ)=ÌòÈp›ê«–{µŽGï—.Äv%º³Âœ}¢©»“ÖkP·íÜV)©ÉqV… ûñqX¥f«ƒ FÝÇ!½Z„Ô)±“ä{)¯«3…I ¾ª­EuÙʪ'X!¨×tXñ‡e˜ÂxµTL¨J*EJqY#“ª')s’$¬ËN:­kæ‰J¤ñDÃXýIºmU}VŽtNÈ) ä\X\RªB€ñ¥CvŠUd ÖdXa(÷^ê’òº’å‚Í9çÈ’·©0ªbJѱT.‰XXŽ<!€÷ÄS-—PUÖäíÉÛ»›³çåfLšÚYM­qõÉeã/õ: ¤Mç·9([ï{½,ÀkàSàg³ˆ²Þ!îz„º}<]c®¸²¸^öòþó¼ŸÑ¾ÂÈ$_ l3¦W%bù苈Ïq¿Æ£~,pþ%½z @k¤Hoûßûoå\þðöú»{xãxû…DûOÖSŠtsé{Óþ˜j±ú.ÏŒo/KÐ{Ä74r}W'¿£å&Ø ¯Þ0o^ÄÃ[³¾üÎÊÐÏ€ç¢ôoþ7¨€âˆíûòšõ*ÉT—ñ0þ~aSúNÕbwK0uò’ùmîø‡Ž[³Þ©Îi"¸î¥t:î´š{ A+f{E^ÅcÕ&'#KI<̺híš±FFÙ@Ã¥ÍIÔˆ² %PÒ0ù‚<IÅ„sµ¶œÀèBâ5a ÙiQÖÎtRB¦tU˜Ẻ¹èTâr • Ú*»"6E+¦ °€%Á •)×!°¨øFEZó¬XQðÂzTÇh©I-‰¤¨¹0Y˜ ä ƒsX3óv ø²ˆt™Ù0Mó¯‚ýéAޟ˵â7L4Hç‰Jz,6LYgq(ü,C5\œ—%Åtž©®–*s‘-‚eGô`MáÖt•ıf,‡)Ôh3×¥Ù*nÚ&g‚j¼¬Çé8 §ñ2W—}w±3(?WèQÙ8³¯äë­…PÜ4ºïÛRB6·÷ÃãÞųãTJ))Þà·=Qó¯kÇ÷Äì¶ò521µ(?åt;4Téƒ7-¤¤¨ê˺œ%ÐFsÃ=—fXê0.yØ‹èÚYœ‹é¦y|XNÝ,Kÿ”‡Ç"6þ~5/|-‚ñIy=íYüŒ½”]Zk¡c &ÓrÇæWG¿,¯W2÷~×ä³êsåÉëc²Õ¡ÛQ¶Éfn‰MG~Œù“Íejm†–UÙ®äB¿ÊjöSSA@f( H:¢äóRòŒ\Wœ3+ká³b~Èé4²»—9p¬ÏÒŠ;JŒ†%Ýyf«‰O)gÁ tõ"ot£*J,L‘’ÕUÙsè¥EJFJr¡"+Rðqá)Ó‰-C®^”c aîý°ª‚ f§s¦\%;&¡î뱫)>õõɹ«ËæD*ç§/›…ÚÅí"çå¶-+·¯Û€ß«ŸA„Sù Ò÷ ÌAĵ’ëÝ&wö¢ô…÷¯|ßT˜ßœ…½‡>âM`\t?äñM%x«÷:ÓÀuâÛù›¼ŸñÍøép€ýv„'ú깿zî{‡þåŸvóþ½æ>²(ïãý3 à0!ñVÚ6h vÀë¯DsñÛ·1~ãîÔwܳBdo{[oë“øæ»ˆè%žoP°±ýrlÝ\ü¥‘¿8ÙÞòΑ®‹c£Ðåw=þfíÖçö#å>ÖM­£¯§×úáP·{Óœ‹›M?i^ŸhqA5I•eÇu#1[J¨ò@!ÐbØÑJ4LJ!HY‚%Yªš]QsñcYòœç¡Ô¢ÒÌr,õÒ–Ô‚zFŒŒ­ºWJëVZÕTÚ9Œ‡0Ôã*² ~%Šk©ˆ9×os5–</T„N SÎ¥ÆkWu,Bê³ÀT,c“ª¾R)Q$n&N ‘&VbÍYÂSñÁä“ÁŒt³ö/èÿ]ëÿʼnÚJbÔ %Êsd9£­ÿÒ—ÌåÉðG! eæ![BKÖîjm$§nïÍýCÃVG&y^é\¥÷³˜+«¯QÖ+Xç;ÕóEÆIWųÓËùôïÿ §ýÁ³ú»‡¿a¤¶ÂmlÜäÏ)¶Ÿ/—§½žèÓ³º•EÙvsu!"6w˜ÂýoÕ½£Ð×/Ñ6Ö’’»ž‹`…×RÛUìf¦«n ×F+ÏJš¦à÷Š ‚sæùn'õ¸èZ§ÛnÞ‚™ ×܀˓SêôÔ©ÃPÍI±ì}æ8Öû©ùÛÏñK¢^p)³º¢±õ/ñ¸©áTõè°³œÎ•ãnýh;ÊíXœ«µ+°,¥ÊŒÞ ‡{ŸÚ9/ÇÛ;É$.¨ ¬f©Gâ² Q¹BT’¨C‘'¹®Ô<»¼ôz Z²Âh"̉C·¢iÓ‹ª¼Òªj¦S>º*a-‹JÅLY䘖ÐJ+¹6ŠÈGR”Q†K©¹0Ä,KB&„š4%Â}ÂÏLL²JmÈ×êÑ£¹¶ºìø"ɺ9ᮎH‹)©ä]Ïæ§áæ7ýiYÖXîñp -±ãì‘[ÜDCëâÛ5sã¢W½¬ÍîþÃyDÞ#�=È<ͶïÙ³é±øÃQàÄî‡&cÛb>Çé7@~ƒN˜aþÐ&ß¾iõ�EŒ_GÅù ü½ÁñæMÄý7`SõHü-$z`Á×íþP÷þŸ^¾·¹¤Þu ?@¼¡Äßý¢x޳øÃVã /‰�z;ºù:çüC·Á&@å›Åly×ÁªaÀý×uÚgÀDÄ—og½Öoÿ%ç8ï·n~ÑÈ_ ù´p5”“=މQÞäØÖÏ®ç—}ó?wíªÕ<õÿ0|rwözÞ`ÐWBmÌÔKÖ{¥y¡Rë©f_(ç””‡J5-™BzÜu*¯x«’TÂJîkš`ŒÔ*×ÚŽ!Dî[#4P“œ,’‰ Á‹¢œ(ŸjÕT‡æ¦!k”a’˜¬¨BJ+uÒÚ‰Ä8Ëjžb¯êZD£`Pá‹à|äò^áF–2s„l—‹K…ð9­¬:FÚÊ5D "ÄÙ7é1'YÀgÝŠ ѳ"5SY´"[Ç9¯UÖµðíhZ¾Ê7PkèÕ–ÿˆ »7&‹¦²¥D(DÐÜ Óµ‹#š}XOI«§¦”ϳiBiKãb´JpBvú¬ô!PžgÞ奨n•ph»–ì6Iç¹–Íð²†S`Í=ÕŸßœ†‡[¾~äÒ«÷»ÚÉè Ø¯%fS\—Úç…ËýÝÍ~ñ§t~µY¯áúÝy*•÷QŒ£Ñÿ·>ž¯Ÿý¤œí;_{gͅÙ¤‹…ä:“+›x˜ìsIZ:E¹¹#P–Ýao—=Ÿ˜óøÒ'Q¢ñôĆ,JmX&ßjôG_–»W¨ï®9ƤmÛbÊ(NŸ=Ó¡šz§ô¡ªÆÖ&UÏ'‹ßåyºg4`{N¢µ-øö¼Š³b'>rÖ­ÍG’SÙj�� �IDAT«)îãR¦tÜçÆSPÂ"Føsdôk¡-…«µ7ŠgÅòÒX•Üάf[™…nJTKõÒq§D 8{E5PN)ÄŠÉPá£(Q$‹Þd-DY±ºQÌòÄ2"˜’Z*!dáµ0ÊžjEV•$£"°6Ù’SFñ)ÔÃá$îš÷”³ jR¤ZÃ1Ýêr'üÔUa›V¿)¯@¥=ý›)0+Ð!¸ÙÛ„å£ÛE‰µÉêl³\¾ïÎDœµ‹&œ´ƒÙÛž„ºƒ\…VßWž^Ôçt6@õø@bð8éü%ÍÀ7&ï¿ëÊ_zîE|A\ëjÞ»okÃRþŠp`ø–AQÁåoðMDróŸf†5~Ÿ’àß|£‰tˆß¨ú–|š€Óã;´HÃWœÁ÷ÞÆ;éwí„Í‚CEüŠÇÖ=O1Æö&tiñ6/Žï–U= )˜ÃWát耧0óêéOW»÷‹áKȧ4IïÃs“¦Yûbkçû2þk½ºlµÙ¬§)Úû¸ËêÓì\t·†…Mû˜KZò3bƒY>]÷ÓôSÚ@®ÃÿGÜ›5Yv$éaîëÙî–K-¨B£·i©Y8M’IüËz׃ž(£‰¢©Ñ »{€®Fí™7ó.g‰=\…B€º¡™Ïã½'Ïiæ_øçŸ^Òi('!û”Ã2þ×\Áj‹j„*UaDïL[L4Xµc…@ 3¢`МKÊËZQ2ƒ®€X’¬ET($HƒVF%zÓf³’§Ì> sFƒ@°27R¼ ^)ð 6 ˜y,ްCêkÝPÐZÒ&Ęd iiC೉Žü9ÔªQ)Û£2 ‰kð5Ùm«¶hVJKÍÏEÝص[’ãÅKl$W2æŒ.hÅ)µã° ZlópyjèT✻zmëÖZÙª´ºÙËóRÎY4«¸j쥓ÓÊ–•>°úr1mÞŠ8nåkVõŽðÿ øoo¼pfõû&^^Ú…RDúÔDÛçMz¥2˜}9óy”÷õ- l0¤ÖÊ#”¾tÓú¡Ü´wq7ÇþäÆ*©k—ÀÜ:ù{µ} s[ÐêÍr\ËSóéiCÇ–~™ÊZJüwûó]®¡“Mº÷Ù#þƒ<ºŽ~ÞÉÄ‹1íþv›·Çÿéúv…—k©+w‹…I¤ƒÁ>”Æû¢a4„}/¹ŠµXt'>ùû0üÞ_Q.3(ÛlVfŸIÌ"¢È¾•½V¢jŸpÊü<H£[ÅJ\ÂbøM'ú¶½ˆºsÌkSz5Ȫ<ËŠ¥ ¹ãÜ«¼ A«(ZQA•UŒ)&4pù@êFt‡ut+.$DKòº¤! ®xUEÌŠŒ–Â*Yk,eJ¹V rÏU¡PÇ<Ë2’¼ZÕ8‡”Ÿšö6B™š•ãeÝx7;ð'¹¼6îTœÎê ¶l/‚ïÍ¿Óîi~üÜ_ÀòŽb˜ß ûÍ“ù§Ím#6z.œ ñ!E«X•|‡>™J @öm¸%ã¦Þ¾¾ùnHäw&Gó`ƒ¸„ãþ{ -Þ% ˇÙCüÆ!:«iá7€-Àí þ[ö7èòöé}»›ˆ Àüí.†û“®?¥îú«œEXÍPgï Ÿd€à¢�@€5@ ±Œ�#´ÞþaC5\ü|±B‰òÙü9ÞÅ{P;xô{xšÂ힎]—Óü¢<óãý\~û0›òª´Ðµ¿râ§^\O›‡»t]‘6HjàåÕu~£ì—·&çíÚK/dZù”ƒsµ\I•S¨Pfb½Šõ ñuXî„üïëPr_ Ùa.Ýèùj-â @IŒ’+pd� •dr1€HlX– $0sµVRT €-è¢JËMÖ*-‹® "ÉNaG`ôg·2 ….‰ƒƒÌTYÈ€D”Wà5IeI÷hµÚ•Ežep•°™%t(›TÖ)–”Šs¢šØV£•l©¬uøæSÉ£n’RUDÊÑ(m P+€ˆjoßdæÐjÙ®iX‹G›v5?‹.¾Éc+ ùõùy•ì‘ÍSçºFôB7r7„²!œõO£vQÐV.Ä©Fn@¥ÑÍæ?Ö˜O14%ïœoÛð¤¡ONAjœ9]#Ë2á|:’ºPÆP·-Û›Eï>½X67ÉñДz#ñÏ�dðqªù·‰ÑÃzî0˜ùü ›üòŽ"…¥çI¨`UY¼A‘:q³*/›»ÿ¨FèÍ/´é”at×ñ‹«õÅeúó <î¯5]žÐÞw>×âsÑ­Ã]œNh>uYôº0ªª›¼¯çÕ¶Œ7 ÏCÛÙ`VUõYTV·µ “y#I渮PÇ,_´Öiù×6¯À‹å\ÓAw®$…Ô¬(’ç4¨lû\.j2%t"fS„a”(-9Í SÚ綨M…6¥ÄËyyu.'Ø]Ú¶×ÑIÊBXCd½Ss ÕOBx˜;n¨§%-wÌ‚©dS‹!çßæ:&ѱŽb]Ê“V­”P1„$–èÆót÷úvys:ÆŒξ¸2ŠzÉÐQç^˜ ´zê3ÈØ×'óOuõB|q*Ü´Z¬¾íéÔó­(ž _lønsŸ|ñ7’@8€âx'€»tüêÊ��üæÓî«øá›ÔºˆP4Àß�tPf€ÿôÑaÉ¯Áߌ¥å[MÎߦú=@û#øÿbCœ¿ -À�ðöë׸‹ßxý- Õ¦_•^ž�8€gnb�x °Uc¯ `Ö�ñ }°uÛwJV€ ÐTàçïLs?ØP÷9PÛëeÕÆr€u…Æ …íyéÎoÖ»(ÏâfïþÒ?@{Ð×Ð!X½µúé…þDÙKØÈdØ[=×Èz̰?ÁåmV¿îÛ¿®êÉШ¦›vÍ_ í\8/âD²GjÀÕQ?^P¬iló?¨åßX²5P±VYj#Ñê4«ô¶)QX%³Â’„X°rBW¡€LÈÑÔÈ1>‹œ6¨µÔIs…ŠL1d ‹dQ½¤Ø7e›U—}¡<¯KÌ[ne*_Ae¤€é9ЇE¯"T"Æ2§r]2`£Xo –¦I˜˜$eÑ –I+rK JÉúYË7ƒØÕ¦bÕº§LE¥“hîd[*]*Ül³,f¯|À’F¯Rk·½2¸²ÜѰ~pÕ4ýKªó´=ú;WØL±FyfsõÒ £ISh6RØlIJQž².2§nJ"œÝåWÕÄ‚çç·âíÊÜuü&†e߆¢êV©µ6µ³%*pˆÛ ÎbÆlV*‘Ò&ÄZ`ÕÄ]mzúÔÒÓP©Ô”C•­EMa,ñÅJÿ²€Uß6±¿ˆ¡»;Ã1ï ö6¹˜,a‹ÛÊÒò¾ŽàŸAøäõU"º/» C¹[Û0ürÖ v.çcWÎkÆÚÓ±Ë%C×^V-ôÐ ÄdrªÇ5Âë¹Ûd؉؉“mξD·‚*rŽÓœö©4.Ù¦.5 -u-’ø2káëRŠE )kBG”i-²Î´Î`ŒQËQ€¯(YØ$Ó(bÀJ ºš+ä¥ò¹ª�Ý—v¸îuÓš&+„®!ajË‚©Ö ÝB4ר2ö!«@Ä‚h™1Q@Áºx[–)qð&n-|ÚÐhê}I‡ãÝ´”ðrš÷Ç»—Ó±Iþ÷Iuµß;•Ïî­"=?”¸«°YH¦ší‰= oùV)¹‹õõR`n7ê¥Ã7¯6÷“ü%ðj@Û7çÕp›õ¦½v�7ïÙŽøðä¢zß»Pa÷Þ�ã‹oOe�ñÝø˜€á},j¿ú>B¡—?rÃü‘þ¸ÿ–~Júc:ª?|Eðî¨þÁkÔ÷¤Ð:†|÷±ÚÉûÇJ�wã¢Á}B#Ȱ–òá«-ÞCüš†{Û8øò®£ì6ö«•l¶!†%rÓ5”Ko´…%Ð<^ PK´ì$xò·ñÒÂ'[ú›Tv½Ðú‹nÓjU³˜Cng!É^5z³53UWWÚôMÓòeÚ]~Öt@Ú/‡¹™ïüâTG1³’ghJŸÝkýE¡T#I)$ %Q4Ù4,6œyJ„ ´«˜y’X d.ÕøSÎXKØ �)æRÏ4Öêe¢R`6Ù �¡„!j_Uö‘ U‚ÊI$!…bAEÍØJµ€t„Y†d—…ÏÆì­6¦«XTïV¢6UP)^F/¤—*TL!çaÔ•¹)>š>ê6©‡­!i±íA5EÀ f*:É<xXnÓ|©¢JÖZÒD,ºHƒj­6(‚Jˆ Yéå<Âx¿Îã±åem… ÐÚ0—TÔ27Ñ»VW1M¾¹¹1ÿ“ÙÀÔ¦Ÿ\”§(’ž¾”¿Wùu3ý»^w×2 õÍß"ÈT–*Ê ÒRbî@æ~x”ççæÿ=† O6ê³cwW`NzÂ^Yµ{Ê¥æSOAÃuÓ³ªKÛÊ©…;ƒËRnFoÝ«5.+»ÕöaáuA›ˆb÷W¯¬úßvù¨ÄXëÛš¶K^·Û墽J1-Gâ7ÖrS›¤( ŸLß4Ø´Jô* s(õv GŸªé3¤K3}Û®ÈEž§:ÏTâý¸žó ŒÔBTU®©ôì/+Õ}²•gÜS”¨,r >‰D¦-BÕ•D¸TJ�…K-S„ûÊýp.âNÐlÅ RTEyìPò 3ô›&BW…éÓXcÉsA(K&•WìY7²'‚L2Ì(H”hjÝÆÒÄÅ£”²´ºŠº(WdÈ8ïÏ>¿Œü»txϹÞçÚºÖ‡Š ‹ZþdÃO»"kñпދ)¼?uÔê&:ó¯ŽûOøM­¯Îúg»¸îäfÚù3CIJíªÏ ý”†ûø‘Úïøîºñ®#Œ�îäð½†Dï!áÅ{i¸ÿ`�ÍQQýÀoÍ]þSó€w5}ÌîªäòŸ ~@¿ôÝá ñÛæf ྠ˜_U�ˆ€Ã ~¤ Ý�äÌ¢„éý·ÀðÙ OvåE€gðUµº6Øk¨÷ P%àl·Ø>,XÝ'™WGð.ùú¶¦À3N?ct}Q¯cyä¤âsîKÁëØ÷iËZV¥žÜ<6½GjþUn§Î°mºÕ£ÍúzgÛ>$çÏÑB_T—P³T¶KæõJîÚT¤nd3²êI*BA™ UJ‹’UPª9|^õE´–TZYcå“„H!µs$)*Cñ² ø™+Ê¥� _D, ÅÙ.(²T1�fÆM›ÁfÁ¡g”> Žå-WÊl äì\„\£*¨ž”n„mĺ M‹Ž5 ,Rfbß2‰FnI«&I* c¤È”³n5ˆ+�Aj=ÇÚ":½â‹“¤%e«j¶ šTÈÏ£³µ(»JNî„Ò=‹Õ~p{¤½ÖÇ•z-sRŠ *!=créh ½wá˜&W§ý‚$'Ó2ºük—/ö^Á”<´"v§4×ò‡¼¢8Ö¢£m.àWç$^~ê—îÜ‚ è—(ï«]®.‰:jõ„óÎÁ©]mÙŠÊ)ÇYåòØ-ËéåЈ®}0K³/ôb&›®Qüåüx)é(ð?JUn!> ©Á*E9—(Ø7â®ìüY]‘ÛÆ‰÷œ4ô’we ²;Æó—ãá.JÞè_Ô®iúþ†š² iŽîÄIN«r2[±â±Þ•™-ו-úÑ%ízÙvc)ÇÎÈĦŠX3T* V*2ùR*»4Ý{óª˜K¦!îl¼mãÊ‚Ed°!–‡Áé­OÖ0 DƒàbÙ!º¢|‚KÚ`µ˜Q€D°°š sŒ—e$âÖ±œ¤Ì¢Ê:âXÑ9ç”o§Š_rü{øíþÃÅ0Ê|Y‹­´6t$‰ÒË»ù¶½{Ýþç / î Špj†ÆÄyX›õ ò“ j/­¼ãò9)7¥õù”î�¶�AÀg��ŸA.ð<¾?l®C}U"€î]þìÆ?õûß½WØ|%$hOß wïcÚñ{ þä~�þ>wŠõ×”ý?#6| >Ùßvû‹ïç_ÿu `¾ �ÐB+@·_Õ±ëG AOï.¶[€ f€·�g€_ô_÷�äUU÷�<j$ØòS—W"ží9}¦ïÓèÂë7{ÛÀ¤¡6=¸“<H±¾Ðó°k,žŠ¸)Ø\Ro±kdµ­7{Ù(5@ÃR«‡n³¶”Œe®õ¤`£…èYZRǽÀ³ÅI›õ ƒªݘh%+§Ä¢f!CgŸ¦Y¥ªEžÀ ^U…X3Šh¦R2+,E”Œ9ƒ‰ÕEØœØP˜P‘^4ˆTuÍÄ…¹`+p+eïe©Ê%‘E±6=�5°¾Òq¾…8 RZè.ÊTKš•É ó’–s¥ÉЂTl‘¥iª ¾‘S0®Öâb]æ´tA4²ÙjX:…ÉsŽX¤ÇÍæB1%ι7©Ã’$ßÁ‰k‹¶¢É¥I̪0†º:±¸ãtauÓ¸oL»¢­+bîâž’s•h@c+ü«Ë¨×÷%Ö{V´Ì;S–ĸø`B{ˆs>¾ñêµè ¨‹FRe×Ò~%UÍçQÖ¹˜^Ê®^A)_˜.p­½(KWEž¯JíuÁˆCáõ<@šÚ¥œx½÷é6ò1Fw™!ûB žK𦏋®]C£ŸP'F¾¼·Ýà†T‰ãSûÔÊ妙ÅE›Z¨Muj;e;îKÃKM÷æî~sÂäÛ$&ì8Ùùã4žëô«Áv³.Ï.ÔÂÖO[¹±ãæ» 5sŒ5aƦvjаÔÂ,+b¨€PËäbTäEó¤j´ rõ­*RÜ'916ÜËÚ¢1BƒR ØU„ ©æšT….I…Í,ÇT¥�R!¹6„²BáK)l+.U”¡Æ<†ºÔ9—)»x¼§´_b nìýEþÿ¹üÊ`¼#÷o;⦰þnç?ëî ¸£—pÿg€, ðù=¾Êq+)öáRøä~îî¡YG1í7süÙ§ç}z{Ÿê¯Úf[€'ÐJxpp«éór'fø9€qðÅ·UJ `ÿ™nà,íÚÞ~Ì…_»ø‰ô'ÙN|<OßÏáÿHlÐ?ÔÝ÷‘!~¥d-?¾o.~ßO!,Äò­t鋼|Âó pñ8ê«8€`„g œ2Ž`â4B¤÷ï‹�§Û¯¸¬×”üÎW¶ f±@óâ1›#<€è„#ÁéðR:>þé'O¬\K-õEèw¡Ùà¦ôCÛŠT|?L–I T…2R‘Ïä’ã]r’H™¥ÔRE2N‘)*Ý›m•iÙb>ÏÕ3¨¦¬°Z•sÁÅìÏ…ÅùÐ$ƒòÈ„l<(¨rTÂeˆ¢J_K•$WmȦ.�«�iŠÌ5©¾HÄ ,KÔŒ\„®N‘âFWÁœtQè$2–5wY "³Y—âTÎ-*l(ÉÌêÅ!‘@ ªÍÖIŒ³,÷‹™ÝAÞGÉ$PšÕ@F×¢ŒLyd/ä¼þDr™(ÇPÖnî ˜D$/„Sµe,²‹™RÍ".@]V½C62ú—"wVGE=¾,§ëÔdhA¡++ÛÿÆ5v_HúûUÁÁˆ$lŽÅórð§aùO“Vv¢{,ôõ¦Ï,é3‘Z™MoÌÅðHÊjÖ©¡³š9']–?/Ô„µ=E€d•íU3ŠÁŒýËçóím¼¸'Ñûß ‹? ®é¼~9+ÓͽR þkî®æ ”lÏ2õÆâÅ*nÛdTõà™ížW§¸ÕØ›fÞO‹†Q§Ã¡¨¦6TP®&�çæM¬3ÓùèöÏUD Ú.kù¥0•†_h½ÆÂæ"à®æ¾úšŠÊ±%&Â*ò9AtÜj‘ÕKÉN.Á+önTD6F}š Yq kÆÈÐéš@íU×È¡ðzÉ*Ç:–ôÊ-eOµ‚–R«!Ï3b© XJà ]ÅP BÖ„*‚:£ä!†Û·eB>¾GªçêrÝ7Iø…À€ÿË}]Q9{Ó]†¾#e‰}øòíáæ>ú°yô¦ÿ9ÖG|7ÀaÔ©™�X5?êw!Ÿ tæñK÷[{<áÛGñÕå”Û<�ßC°ü­4X^äèîøÈ,Åý ç±˜мßöîzÖÁiþ*úÇ樂G‹g? øk¿ò'‰SÿP¢(ÿ4õ†?Úãö')YÔ3?"Ô…5€ûáÑzœ^À¿&ÑÞD€å½5w °À諞”wk@xñb|oYÕ¾ãæÀmÓ M“ÚOý†þR» `ƒ§T޲ÀÃÍO>{ºþëÏ~úèº7B Í]áYc¯Áö›¶7(lYRœJu’³ÁK�r†êäÄ¥¨ä6l¥NRgÝ@™¯ý©ÓE+%õç.U“ý’S’¶©F”œsN)gWc Ø(¥ëˆÉ†+«È¨@ŠV["Y9ù‹ÈdrƥĪ:”ÒR§ŠÀwÓ€£*ïJւψ#« ¤L°M”°d^ϨÑkÛeNÙÃìc‚šu2L…¥SêÔëÀ d6 Š2ˆK6Xz—ô1¤ÉåÆ¿²øK^¢SBÐÝA`P‚1[ª6+!»3±XB]Nyºb)ø«tÚ:+Ê|F› %QçOtȪ1-–¨š×ú“I®+o1ë㟧åq#VعüÔô3ÙþS9˜Øüt°Ô6.û2·ã(ä=;{_n„zÊú²¥mÓõ׫tÝ%*M€"`ð u0]îõ^æœôq ÍªÞ­Wz1VÛ6Zt“Ü—àËéèŽyŸâ粚òsö«úÿh윜գ¿^tܯ«eõ+³kÐ<íMÆjÛeׯöë®HSdU£3ίâY¯†m¯Ž§ðüpøÛ;?_Mb†RV3õ¸h]¢×||I7cå9¥ ê…+Rƒd”Ñ$M2B5ƒ"8C³TÕäÎÉÏÙSžL:«³ÚU)ô’6…¦äµ«˜¶^– ’kZX?”t¼hµÐ(†PÛXè6çxÚ¢ÎÔ±0Tš„DuÁªfe¤Æ"RÅq1•Ó¹&žw?ÝߥýDáõ²?;Qñ2“vçð}øº(�Ð4òiiìBa/Ï7“KgàªÂê 㪅MÇ'óE�í¹ŠY› oAßžÓïAì—u�€î¬ò úÂIJ{&*lÐ xK°ïBȰxÍ h¿jäš¿‘üã<„� 0�*üS×¢?šèo²f?Ö¢õ{ûæàá»ôëÛ%ûA#oN6ßXÆ×ÿék…qXà1Àâ/Zˆ `F�¸P p„2®y¼z;€¸‘!\A¨°uÛzp_„†Ÿ<ÿî'§óXþËë~w±ãªÂ‚_b­ÜiR­0ÂdB9†<4FÙ¶gKUÆ"¼Ì²³”¢Ím#6&X‰¢Ø×;-•(^Q.‹BP[¤®b‚ä”Ç>£Óµ–| Á˜ko $® ½%½R@kåZªZ¢ e‚N-u×kcQäRS͈ÌBGÔ‰È)8VÅ ÄÀz‹ÂJ(+\E”ƒiV–,N¡¨š…"Ñëfh©"ÁB‚jEA ¨"J£+¶\NµžI¢Ù%Ó9S¹—d“{T|±\ìªdTÄ`›Ñe( Å:w?Âw}ýâu(×g»*¸Û‘ìy©X2Èc ꆚKEF®ÖØÛÜ%@/¥ì@òJ®R -²•¥}_é”ËÚE{ŽÓËg)n~þj}ùÉÊêM£m[úÁií*·\|ä»Ãý¡quÐv·R5: ZÑuƒ0°î‰»f³ÑÛlimi0±žÅ‰nosèÆÍI¯í“"VB]F{Qý=ŽKùôØlC³Tû[njm\tmݘ°Úº¡ãAe)ûF)ÈÔÈnMJhìe-€1ø¿swáOL—"â¶Ã$Õý¹aSLŸ'5EOh¦ ¾++Š—Ë“|XmÓ2ˆlWmÄ‹¹jÏh|ˆ÷¹¾TáM ‡™kRÑB×R@�ªERÓ´V‚µ:V$ –‹Á$B$¹WÛ¾µBFKë¡ d Òˆx²\å¢!פæ$”l{²’4ˆZ0˜,b¶&ËX(VÎè5úçc�Wj®aòi9ùÛÉ«æ.˜ûN2æ!;®5@Á<^U˜ó Œ Ï8°kðvýæ¢=óhÜþàv€=”)¯nõZ¡`u:éó wÐÏ0XŽP Ç3@|»{©‰ãã˜!œŽï¦¼¯6w‘ÒÇÈ¥>œõö àôNéûÔ›ù½2àŸ~,§?V~WLøüÇð?šahøxZ`ŽN@þŽ0«;ˆ?îòþ§Ç,¿ùcïfYoAˆïF@€üžl%<íÁI0›Ç, ªþð ñJÔg1hžè_<þ³Ÿ\¬õM«uAu.)îJA'%µ© H䥆+«íŠ´Ñ’Œô3ö½'&Áy«‘[% v[Id®|³ÎÌ\)¥¹ °“DL†Y€ Rb_p6€µ‰"ŠåìdE![­³ .$¡ 40I÷�� �IDATL $Xp&”œQ¥„TB„L  F¶9뜔"ÉÈZPÑ$ ¨šÈêªH‚M\Y‘V¢c´µ˜¦H¦F´Õ¶\dÓ’S`ž…NZ ê¦Æ{%L 83„%7èÐä MKA·Ùh{ýŒ8ê<\ê•uCUÓKAO©ÊóI…/ª—>þìh~"Ö‡–RÉ‘¸Ù”Öt’úNX <³rÅHXÚA6ƒLíZpŽ…T’@ëH¾Â…Cëî/ÎWú˵½`«u'…n BñJ–µp“<„Wi¬ ºn•>ÃQ1¬›,MçE®ØÒ&(Q,µkÚšŒ Bºo„9ÙØ¿f„MÞ"xt^Æòæšé²_oéhõdGA±]×4\ßl…׿E]+À®–UÙ]ºfã8å2éM/Ní¿x„—²ç¬N³Êó9ÏU©e»J¹¨E¬!˜v\ìá­¹§tõ|VdŠX‡a7ÃÕFv”r]}ÛäÇJœ%D+T%ª}SšÖ·½2@˜tÉu P¢JIr­™ÎTPЮAÁªIRçªs45A¨aáäe¤{Ü´9†tN‚:XëlŒP TòPe¬,ª¨hAtZ-5Î.‡%MSã1d_&'~MÊ= ÞÀÛ„£"ݯ`…8ðÓS5cø àáþ¼?Ãoð¸…Ý_€9É㛋“?Þ«Íz½é÷¡=Mª2w@k onד[7Jiu8áqë'ú¾¡3G¸0¿YÁ 4pósŸ ¬^ïÕ«¾Ñõ.Zˆ>Ÿ¿>7ï¿Û·�ë÷j¥ÃÒáÛ™A �^ Ü:ˆÿóbÃw¡âóò†cñÃw‘c °øÆNËwÞYƒ‹qùp[¾/)IJÄ7“Œ3�‚®ð¤‡À!~ÓÓ{Yà®Ù¨YWÐp]>»¾û+aÌr·ì»Ã“î7~%#T¯Û?‹Ýƒ'ÃöçZ^Cµ\rÆ`.x }–xÕe;…ès ±²•(8¤š+ƒ¬BÚV¶VGî‚C¹Å9'ŒET2J”3”T � ÀQsïjvÈ ¤R–ZCL ç¬SZÒ:§˜yÌ”´°ɪ„ÒX.( "BJiB!52%IâB¦ w —Ku¬,mpPœ,bMµ-*–ŒHBg „ØšjZB%½t�(«P¢ÏRÆPý¨çs6KÆZT†¦““¢’À‚Ï"{¿Èüä@½ Z©¤ ‰F�A—EL§ê{¯š{(Ñ¿ ,Ðó9| üÕd‘ö MæÉ�$w¾«vÒh~¨CŠø³ß¦[+J1›Ø^Ôβxdj‘'º¬îR”݃Ÿ}rÉbýÀ`1ƒ,çyi¡°cUQ°¤~7wxxØÕF‹‘o!œ‡².ìYÀ"xL]hüJv̓jÕ0вYšÃÅTï<&QJér*ƤŸÕÍ=òãb¯CÛt€\XÊÍí¤ƒ3òÿÆõ&¨AâµÌº±Ä›I±¦eÏþ¿zžµ½ E¹Zé+6!5îÐËq#ƈœ‚Úueµ™F(žDº.޹ŵO {ŒoXH¥Ìe×\hescREP} ‘\¸Þ–:§X×öÝuשÆj›Qrur5ë–Ù.¸†ºµµv³’ñÔXI¥Ì C9ÆJ­¡°"÷ä\%WUŽŠCÊ2W.nf‚¬tÖIÙ¡”É&ѼÔìü–Éó¡õñ2ŸÉmoŸŒ¿7›—­PÖ®Œÿ¸uݩ녟ƒ¸uî`‹ód~÷l*®ÿfªÍª9nÏQÈC³±6‹tL]^\´!„ÅÕ/pŸXÙ¶´Í¹ž  °Ð�7v }º_O÷ÛçW/‡£ /Dþh‡Úbà >'?{ŸC¼×Éà·æž}¿´ûcs˜Lù©SŠ&ý0|wªówvÊ�л®…Ã€ô!@ðãuˆ Šï¶(|íuõOõ­{Ïù¢¯w÷‡wª¨÷néJ<Î \na@ž–·Ov¿ïw¢&øÍvû[ »L'ÒÍcjVÊ ‘èéÍù‚ǘNó‘ãy§—^À�`6lHV&’ zÁ„Ek0r²µ»šL°Hh³ò‰©$®QxÏ)S “•ÉÂVT5:Ÿb˜ÑLÕâò9äJãQŠZO\ŒQ0a-\7D²�– R®R�$ #µbA‘…‘Bra¸!@ÂX=b†ªEfE’¸H�²f�A’ !hƒ‹‚ÐT¡Š*@ jÁÎH\¹p.ÍTšCr)sìS¹t‹uç:ù‹,O‹:ÿ]+þe/WZ6Vù¶œP¨‘Y¨I\åÞ®6­j½ÔTæçÇ9й•Åç #üŒmcÕk; ]+‚Ÿëi±žÖZX‰,Iv…°ÈSÊúXÌa¢Zº•´ë*dÙ<Ê»~­©àƒ u(-]´zèÚ,Ê\îCþ/žóäì/sШÉ!Ë•Œ].[èTêËóenÓÑ/‹ñêsÇ›ÙwM8çú¤9ôµÝY"Ü–á¶ö-ï÷4•<ФòZk»æ_(9Œ áÊÅÙñžó±·º£à±Œ7“hƒ¼è–öó^Ü^æ›t|¾“Ö™!?œƸÞL,ýYÕƒéN¦!h5l¯W` µˆCÜäå´¤ÕœL«¬í0£  « 'ê6ÝIæ„PL• x«!5êÂØ RëÊ 1�Èó\ÂX“†Ž±ñæQˆn(r^ uÅhFÞ–¤ìDM•¼�’¤9r…<_æ„ùìê²´µ­}.¢©À2—”|ð)D—|D6AgZ´ZÒ¬NîæŒÇj†,ÐÕ‹;ß½=ÊîíµYÝ·+’+<þÒ²R—Ë­y³¿+P†-š¶äA¹; Y›:XÛE(îõpôråµ_Xµ� p¿éîW`î;xÖ‰SÒ ›K€â·€<5¥;Âeäý»8ôAH| ò ù@�6Âòþóà`üº}zû~hÏ{rÉý9¨ú@£ÿÿ ¾—ã‘?6ËÈ*é¤?†–O¾GÎôÍ-€‰à*ÀúØpz/8ýðøÿ1n°xûqßݼ0߭׬ ]A^RضU«cT_a‚'� ê#˜·ÐÜ€ôSº}ëˆÇ+ýŸÉ¹¿zÝ]‘Z¼ibOû1÷ã¬÷Í‚ò8©û{TǬ;¶t”+ÂàÚ]@UE†4!È”µ4Ej®À­, Y ÀJÅ ©.5ÔÙ×uÂ’š†HpÉ…tž‹ Ë¥J]>[†PDžKdvRØšRš\S™Ó$Ø®ë„Pvµ•DT ÔPKNà³$Bfê™%V¬ k)%‘Ù±$BfŽs­¶.Ò²TˆŒ5‹Ê ”ʪVB¢ HžSJj™ª±+häT³'Äœ ì1ž¹ÜO¹Î‹FO”œ£2æÕÿãƒØ¬!)¤–bSŠ&W-L’:´à;”ÍI¥B¹É‘L°PC†Ê`Ò«÷”ýrTzqe¹Z3S2"l QKü€V–³H©N)©Wdlß´›vÝßû5ù+mÔ*Xâç½w·§¥Ìó_Î¥ÙEìªZÒÚò@Š€fDíró6ü:ùÑ'ò3c<è6.á*ÝËœ;!Ͼ š5I™Êòjš!Ïœor Û]kÑZŒ÷Ë9óý]ð´ ù¡Çµë¶{8›x·Ím¡ÓïZw"½¾¿>„ÇZµ­›Yv¯«=úZ#ˆÊ» ¼$RÉȦé5m.ýÆ3¥SÌËÄ÷®µ«, tJ4(”4Rg­ÃÌ[Óne“©¼ uÏIJµeÛԤРRT(šJIPÏ9ŠËò¸2J ™@Ü›¢²hDõ²f‹f‰‚Ñ‘VÂÈjKêKßQ²‘ŠžØCöšÓ¦TÅEVY±L!Æe aŒË½Î2²°>»9¡\c'ïŸÎÇóħҼÍøÞ«vÊæaþ”O©k¾ÔÀK˜²9ü:�°8<P/.:pæ°Ç ØY/Ô:‰'èþôï]�&˜–làÔã_¾}o²y ó%Ìëƒð'€(�²›ù 7�;€×ïÂ}�xpùà 0€ß,ߟq¿ ˜‡÷æÛ‡?±@›þQ„Òq<?€þ#ØðÃ0ðëˆß€ŸÓ×h°}·e hçâGˆ¤òñFýwÌh%À#�z7Þ§Õ Z—ðêÝLÇøÎ&öÀ Ä ×�æó×0Ìôüxù_lñ^Â%ÝðàÅe~ŸYÿ™.:?�PÕÙÙß¿íw÷r½&!#eš® (©RQ2å°à(.Äj]LCL, sŽÌ1.ç—;0œ¤pK ¾ž°Î81¡BVÅœEHlVÒiŸ}–$ås8d™Îˆ]U-ú†ö§ä7§i•¬m I•#@`¦"u�Ä)1U–•2`• k-¹"C…À%2TY$/x©ÐT4$@VGå(‘U½À² DÐq„\o}ºÏfȪÇJ)ršRšku¨²’¼á2‰øÒijd"5Œ™~²Ï¾ºÚÕÛ3ê…å!¯«s—¯R¼Dj'd€·UOyØ‹k§—¢k8¡²4káæpLw£\äkLC´MìAJYVŒ‚’$o‰¯„Óï>-ª‹1çôzÐóŽÂEÁ§„ÆA[u5´¢Ú/óœÆs9žæi¿º|q‘f­ÔY<þ‚®>•¤ß07ñœPÀ”ôèW÷i™8G ä¯ã¡ÌIjÕd‰EpçÌ3«•dî³*² ¢ëÖÇn.lcDcÐV–õãò(ó¶YëvmžÌrîNp°Éù´]x}Òv¦š>Ö L¬«óI—\òO¶xÝÕu%òe%“"ÇEbXš´§ðFÖÛ¦>Qu—‰‚Z´R€й+‹„ºiæK9fႪçŠsáêK^:{yU«]€¡–c¡C•«Žw0‰švÅ“5Š4j„ Ùb±F‰¬Dk£´F KÊ®­05 i–ä|YÊ„TBMsJ¨b—8sº³¼d2‚ë±Ôà”Ãízk¶}¼qV€‹GîdŲ׿àë•RuJB§ö®Àx€8µÁÃÿÂðŽpwýLXx 0€¹mœÛC tw3þ¯põn2ØöbŒ1|¦Ü¯pWðú >{gþŸ,ÜBdøü�ñßÀó_$mö ~ýUYz�Þ?5Ôø‡šÁ³-è5ýb„òìÇôÿã+ ÿÝéOnªø~ø¾u|Ýñ¡ÕW»ü9ßIƒuý1cãNkôï°/AÃò¾„þòsXÅpŽ'€À�4�Ÿ‚~ ‡#�€ø5 —pÁ>B:Â-è<Œn;>Ûhè×Ϥøer‹Ž+`‡n9(Ñw ü¿Ô½YdIvøÙnwõ%–\*jc±»)¤Äj$è}^óç?ÌÛ  ÇP"Ød³šÍªê®¨ÌŒÍ·»Ù~æ!2+³ªk#À&0÷%Âá~ÝÍsÌηٻÒÌI05Pù°E›mŠ4ø–ºê—FÖ”ûlÈ•O!Q™q ù…Ï7u¢uȫŦ"G…¨SpD¡pFB}²6KÆ2‰Âd%ŠefB@³bŒ(œ×CÍþAò{—ÿçyYó"K•<9.2Z3ÕHæMˆÐ)…’gV`9 ÆåóŒÄÈ*”LsŒ’©ÄSóм /š2ƒJHÍ“/1I6(VK¸ü|ô9ù9Å•ÂZaç/Êô¦ü—N^eö<‹¦-¥’A£ñ)ª!©í¢ž,²Û¶c¶â!²)”ÏbÛK³Èóþ$´dÔeáóÝþ^9cþsO«ÊV\%qâõiÕ3³T캫7¨M Ž»É4¥«äJP—h%¹°µàœñÕB´[^]ï~}ûÛýét·ûÕðâý>·u¿Ãþ¯yßIs•µÑ)a¾‰ã»89{s‚?Ó^0kÇê“¢‡†O–{Dá2Ý/ËMŠk<³Òdxš"œ1’56®ë E,]5oâJsÖsÝ1‘9)UVm¬ÀÅ)¿:”hrºÚ‰.ª©-^dh”"DT•À]G—UN†É Ì—,¦¡‰ÉŽ´`ÙhÍx5›ð22—ª6Ø£a}•ZvjY¡xÊ,åpWäŽ((žúIÂw~‹1z1ë†\IÝ`b1!*Ö?µÛ³º/œÓ˜5ÀŠ”*Ž[Á•,‚¸ÎFeS×"v€PXW¶­¤aF2H’ÈsdIÍ©0£/Έ!Á»²VH&FÉ“QÉfxô²0sDµÓËKcä Åž±îÌ_ïãñ–dÔ«IØÈ›†u£àI?íýxŽÓþ*þUØ£l[¬>ÍlkôEüÏpº†¥'ë±ÂK£bÝ–9â¾`80#kC˜>~œQ¬ K‹Ãx‹nX`è<F hà üç#0k`ƒP öá±Â±ïV2kÃýãÁ9 XãwÔíŸÔTþùý”^Ã!¯­ÆÊ›ø¸î€[`³|[ øŸÚÞ¹ÒhÜëÝ xùÆ£û-„n p±z` ]pµâׇ*@~ч”ŠÇdÌþ aF�þ €_b|ï.®7cŸ«JÀ™<œGµUAð‚ñÝ.G5ñÕä•ÈÊALu§´mCGX¡:™ä4e1:sŠþ7Søå„³|ú‹)×$ ©´9Ýû"9±…wÉô2²Ú“ȵ‡ŒˆŽ"ãIÙ"2©…¨`d/õÍ$ÉÕ„*ÍY˜™µIi«¹(ޱ . „dY3Á¥—™ŠŽ"3’&LvB¥¬m,5 FS:UZ©TÑ)Ê\–`ZAç2ULp SÉ©Ls~àbGt™˜E„ z‰gÇp$ynD¨$ƒ:^Õ§¾è@ƒS± ÅyòO§1ã+Ãe,jI‹8¹å·%rÍ:b³Wü@Ž)3Yñyd¿r_þëã‹çgÏÎt}ÎÀ‹Œ$#µ”–=wóÌÖ•ðõVZÑ%MÁ¸æ ¹„’T`!·õ±°i&ÜlóC=ºÃœý$Ž™uÚ®rùÄŒÌ1ÉHI6•Ã,Ó+¹o _I…šþ R,:—«o/jqfž( iv…¢ò¬€ ›Åya,e)f#G•Ö6%+Ósz¾1$†œŽ.¡xßæU E¹þý1{î× [tì+P‘dæI“.«²bòÒ.¤¯g£è—%¶á¤ã� s|ʘ–¨ÖB>WÅ"­‹î…VEæ} ³¼:…’bYRÒ²°£uÉ ­tºÙYÎ!:ba‘xª…êͪ©Î„®rŽÜÂp%[5‘ä 2ž’AYHr¦$ET¡Ô\*MR˜P˜%ÕÔÉ% IŒ¹)±Q²trË +˜(ΔO 2‰<Å=§ñ6|9¥EA´ˆªŸ™*êé1Õ2ßÛ²#a•’S¦5¾ÌMñVây† !¬A=XšÌ°” –Opüó>Ǽÿ"DD‹ý=NAÏnÒ €(¨2ÚK” LT@ýWX>b3êi?MÀX(…[Ì¿ù�p¯®ñAÀs€€!àËkò[æ%}wY oÙ˜~<•¹z ‹o©jBó?o˜ßþÐÀÕ×ûŸzðÙSCø.ì¾oÌõ `À�ì¾ñ™5¶W(×Po'Q/BgB¿fÊ>Þûá ®_™�\,À«[þ˪èù­ÏG� èê骗]™«½ÕÑC«ÈÇ¥; $…V%¢¿YÔþ.As›sভ±­á’ÈåH2ÌY± §Ã)íBâãt~ëeµ¤¥ æ‰óÄËÙ…¡ì…úY…ÕTr…ˆùÄ B±Yð‰*.˜¤*è¨z"$3rÐìÇ©IÌD)Á¢‘•PR°Š /¹$’uÉJ bEe^Á‹2ñ(³Ç07;Q·¶„™{V˜¡$d1Ú°Úz•b,,š–‘4Ò è ÆEšŒ ð)pÁä3¨ÿ(p>¶˜I•³†Ÿ«§ºÌ4/ÅD±lÅ8¹ÓÎØ2†M ˜„h½[¹i“ +<õX[’>R:&Õ…¿PÍŸõëå²ú«µt‘щ5šr?z7í‚^À¬¥Í%öÌk•6‘sdó Ø¢¿EÅòY&‘ôjµ–Û²ó ÿÓ’Û˜ŸgÙ}n¢”×Uør³cÖn])‹Í”GvµH—múp‰—…(óSÊ!xZõtùô“g—´œw|ow8·9ÅÛ9jÉ&úàüäEñ\‡:$ác ¤ â:{;ÅÁƒK)èTUü“JB Ï£NJwI]ØyH©el[äÓ ÆCLZ éÚ‚éÈ{§ªÁ+þŠuÌÉ~Jµ* ìý{9=Yû†KSJ8#¥òÂÝW ËEêb BU&®;£ØôuÕXm¤ªIW•dÒ¬`›ƒKX–œ’U•×JŠ*J»ø žYF%qÁ8±X ó(V. ™`L³ÒÍe³cñ¸4"®µØH•iøpˇŒe0ô"=ßÁÿZÎQú¹ÄŒ(W§s î•Ô7ÕKkÊ/Së(€ÒîFþm›käO`Ÿ£¾Gª°„?bšÁ~æ5Íù+ÉLáÒ\¦|ÅPÝ#gÀØãüœ!_a¹F¨qŠð~�˜ °/¨Æ´ƒ†Îˆ° ÆÁk@ÈwlQMxˤÌ?m>?ý$é\�pÊ?q¨ó‡Ïox§é…×Ïjü@ Ï#[ëMŽÃ·¼4¦ïzÿ«7œ¦òúvòâ»D©›oŒt†TPo:ÆçxÝNš7ßÔØ.€ã¼B~¡žü¯ë¶«MS‘‰eÎÅOòô@7gÌøÑÚ¢ì+|ð·EþJþ“½o[k51¥Eµžb‘Õâ+9…a"—F–ö9OnØŽSªïŸïÅs.È _ %D9"ÝÈxÅYçFŠã!'x_|½˜ß›¨jZ•ŒE®¬ÄÙœø(ýÀ©“Öpi”2+£­Ö–‰"µá”yŽ’ž²/œ‚ ™HFÁólkÖ0Vu<×<EÔ®d˜&Å-dž#[˜æR() ‡…y&•Ñ5(—òønb]ÑχöüpÚo—:ï+%ªîbe0Qqt"3·<™œÍþnNÑ¸âøºé¼®´ ŸÜy½L£R¯&VÌn/î”ç²»?Sïw¨ìaŒ—(1wЧ¢xà­Íú¬Ë+>Z1 õ+7¹œo™giœߟ¦šx…ÍŸ –§ UÚœ*3é­¸öQÕ¡þ®5/:ñÇ•üOš?wâyÞSÿH9ò¡è=[”rêÑ\ž?òþÏŸ?yÞ*ŽyZVýñÕÝx㎧<Ñ7ÑÉezo‰k'vpÓ8¤w3Ývñïì2{QVˆòß/²Žþ=Íêu›l+¦•�×¼¢–GÎw|zÊ3[RHó)²­E`)ÙÁäSõ™jÙÚÖ<¨‡IZ’Šçníõj¶Ú› k mÈ…X–1ò Gô:ÉœÖP2G䔫VÖvŒµ2%•BJ*¥U©C¦Å3"Dã½…‘\ˆ•U@Ði4È‚R™„÷Æ0Ï2cMQšYÙñ\ ­Yë 0O>¶dŸUA͹P"—(DÜæÝ‰¦{Ÿç\x)ý§¯2ßîYò½pü¥¯þ;Y;£ù©ÏgÃÂ)¨ÊûÎe„g(=ä:Zõ¢³ˆyv´÷¶…N~«¡|w¬ÙWŸž`€,Àï÷0�Ÿ Ö€*ø‡7A=òh�\|}Ð.‡/œ€¿)‘Ÿ#°ûf‰âÀ8~kôõqá‘Ï9±ïr¢ûÎ1T|mtýGþÐù ¾ßÍió¿6ÀGo˜[ß{êa hóæƒ ˆ@�N5t‹°ÿ6ôý½ ÷È™=®ÞZ¦ÇoޤpLÀ5ô3„GþðêàVØHÐY'´4FiÆ !y1øH\šó§sݧ:>¨rŸþÊl~!å¹±­"I¹€/Ý‘•ÁUAöæ(r#Ü0ÍÕ]}Ú•Îî”à]“Œru€ðQ„D1ª)èpTb>IÛä}ã “Cä5r˜ ó­<IùQÚÌ× *ÌURF²5-ãO…8“¢¶’*¡4DÉZHS Îx^(ʈ“Oe‘ S eôÒšxâF𤬶‰8[¢‰©šy´äcž»ÄEe° ÉgJsÎÁH‚a—‘«%Û q›÷bÍ™& aÖzVj,MËLa“’-<?È0õj”vqÀ-dòƇvá%¶è§)Ìr)¢R«n}Á)-Áþ"ø¾æEë-[5mUi^‰jZlg<„Y«b$¯6Æ\5ì¬IùüÕC9L~»ãÊÆf¸Mwã]°jÛ}"=±û¬{×msý.ngW:õwO6/Þ·8«ÿ˜‰'<¬ÁY2 º„r4Öl’‰-*¯tvùþ³÷?|²¹lMg$ÏEò ÅÏiÙå�.ŠymïÔå8ìMÈÉÝÜ&³Ï)æ¤Ü/Û»~•Üûÿ“[Á×umN¶6'“†¢JbÔ°¬‚‡È3¯Ùr°,‡6x-W•TÜÇHÈ¥‹¤7Tmx×iÝ#Þsœ`b£u]—UYì&”9Q•]Í«n‘$êÙ$/2�äbEél©ub#øÈ™SB’éÉtDœåÈXPªØ ;ÉJ :¡Î\Z-9ž)€¢(•І’Ò$¥RR.,‡–T„Élù´sñä%ƒ–èŽÁíæ}œ'¶ß±AÊÓ][F)Š”z\ug¢Y$¶Êéj¡xéìÇA˃›gíQ-˜ Øõ70ú–'Zî1¼p‡ú°Nî*¯7ƒ{±•S ÌøL¬¿ŠÀ§oÑ#¬@Z=Ž?Ò�� �IDATkP$f8`xGˆûüM‡ˆÀ3à°AÜ ]Ÿ¾vնد»F@"À€÷5¾ ¿TÀò¥âÒÓP„ή‘Ãkßï—ÿ²3¥w¯ øŒÃoðn(4ƒ&„ðoÉ»û7K´y3Vúî]?íþV­^GôhàJý,£ûø�‡Çnq�Ä››‹?E6@€ ôÀo¡«×ç ¨� ]Qè;\<Ab÷“¹™Ë”¨ŸËUWêM¢‹unž€mM”ƒ›ö»ñ¿0Ñ|$ó6¥t˜FIž1gòršË Ì2Õë +s5INªðP‰ÿÊø,„ÈX‚DÄñ”§ŒA€eÉîÙÚÍãê8_ð’vŸåÞg¶qËš‚œ¡·VæJ>“Ca9e)M«1^C(ΘâLó¨rŽ%'ÛÝh(.LÊ,²E‚¶–«:g‘ y°ÌgK¤åLÌ%²â` \Ça!p¨”9) 4qÆ)ƒ|&ŸEBÒœZÁ׉˘ÊaeòIß–ÕÎ×3ª2j¶7rOŤÜMêûhª™Ý¸KÁ1O͸œr•è ×\½ù3a·\î5¶ÿÀyÍ/Ù²Xi)j¥ 3¬×[«¢x"I¯·Ì)žU«¾å 0ºEûÍ~É·#‰£œsôA –UÅ…–²d6ySåªúõS~fR_ø÷Ÿ|ô¼úwkþ' —±T)e’å1q›H×Òv«F?Ýôïmê5b†‚ÉÇÓ8>œÆ›ûa¿Ÿ#ãy;í¸¾Qy´•™ie—˾ªÎigÅ¿cËfü(Qs'Ú§$VQž§iK…³xläÑÛ&Hšyl¥®+±’í*•¸ ˆ¸˜Øë`u©öÌE¥WlÍU+TÇ)*ë ó1åUΛ”rð,RäcTU©[YoŠQjå$“ÚgŠ3™7B°ºž•.QáÈÄŽÉ!‹žK]p.½‚§ÚŸ «Lå„NÐSC`$Ek´’L%;gžcÎIJÊBRMK•*DA’e®H¯55µ3ͦ15ܪĤ÷9¿Ýü•ÏѰ9¾7W%Ä\.sk`º(E_Æ„yÒAý¬S]áÇ)ýcò_¤¹} •à·\Êl†u)ãü*>�¾0úgb¹(/7‹Îû‡ÏèçÀaµ_ÿŸ}Í(­.ƒvЄ¬PfT¯ßF߉§$`½‚,ì&PxSç2°ü)ð¶Ô Â©=ºÍoêoLPþ €_/ÞŠ½�¼ú¶}Æ#ÿßý0EHøodˆþKö†oàÏþ1éómtц°®Ço×ñýSì%ôõ¨ç¾ÑfÞP§ÂŒkùcöå`oäuïÝ=šgl€Õ)›×Ó%à9ÀÌᛀa_v€èŒ+j®ß[‡§öåìöaÚÃ0ÎÛu± Û6½‰Ídâ¬è¡`çÿx ¿á0Þw¼Ë�Q6ì"ìÄÒÇaŒ¼§Èø²v/ìÓ ÎÄMñµ/Õ«]¬¦,üÝaZNAŠÕ²IA˲áÎÄšýNÔ‘X!&³àÞŠuÛWÕªWbÄ™bBeV•ÄÜ’3J9.”µ‘RPç«€�X  “ÜØF$É\LLFÆ™Š\ò ·e4DÎ$˜…R)£Ì³®JÔ“ !Sާv³?R”qjéC`båÊ¥€ŒFîj=È8·U½QBÇVÏGF×j©äÔóÜÚ:u‰Ž¹e>ŽÑçÑîs3cäßn.vJþµÌ«qþÙ˜/"äyo–éì.º3.g—ë˜(¹IJÝ ^mÚÄ,“Xa1" ì$Ay.óZì2öé4Ý…»’Y·ŠÏ<Æ%–Ik¯”“"ªÜôøè‚ö´måÅÍÙÕŠ?×a˨3J ÍÝb¦…ûÔ&:LŠ“”EF$Yy|Xw7§W!‡Ó´{1½úb¸ã˶â^4Ù ~·ªù=ëßcG¥Y›°}æò.ò}.ŒW—Ö|E5ß-X …]Q,å*+®Êê½lÎ×c<ññ†iQŠtc—¹²ß•ØûmÓô¥VÁP„t¤¦‹!¯gßžfÌÅOeUÉXÝ5RÔPà*È$P$ ÍkRÊèTé“°ÓÀéŽè6*)eCdH•˜£EpÆæf)<ÍnŒ!Y~V1&…V,×ÊÆ„ÐYs¡bL8U2çŒø¥O:…ZÏ¥ DåžÊ!¸/‡ãîåM>5iX[c‘â(‡»ÓñAÞï§/{UÓ©1Ka½’5’à‘vîÂï°Xø=Nh%dÿQ±OR:¤ûOqN@ ÷ìoºáJÞîù²Çå=ºÿ€ªÆ™@yŽÓ‹¯QÔ¨»#ójït~·ò€  ŒšiN{ªßÔ³ô›zø2¦¯Ëð0}kÛXOßö†ï¯ºî;hHï­ðà€ú¡,ˆ?Poø& Œ€�ܾ;Wz„ Âï£Ê+hÿPëï4žr?üÄ7˜öwuT-°(ÀëÝÁ0Ÿqä † dà¡‚“�‚O׈!:ä˜#þÕùîaQ¯W ·w«:=u;kr»P ™mJù÷ÞýÇ!)ÊÉcNaàqˆRUÑâmI‹I¢Ð†Ü<™û*j GãëSÑI˜_Ü2¼ZÂòë“ '*®kÓ6¹w¦¨µÓK¶FÈEŠKÁ¬Ú–®.­¥–+f‚b�wÖ0â9©è"S©ª´È\S‚ë¦f¢–¼bVê7ÚÆR8q•´,"RJ ƒîHÅgðÀ„’¼m +HDÑ2¡¢ ™@sf"‚Ï(¥ âÖ‹ÛTü3üÂA’éªTu.³!+äûüBËÒÚdLe…åç%ÌÂYkB¥‡%™eQjvýrUW©¶Ôí^»;±þ\¹õÑݹ‰Å<ÑÍ”ôGÿ1%Mã!«:‚Õ~\õ¶…uœ»äËd!ž³¯) ~¿;ÜŽS;fºwCºÿªD!Nu)3íõùZeÕŸÍwÑÄsyüׯ|ÞÕ¥ª[N]r¦'¥üºÙXÞ/©ai¶‚’0™ã>#O~æãÛÅ ,›ÜiÿêèîB.÷ìpwKm×!›S#!%ÏüXú d7ßN3Ÿvâý,ND{¾üõþóIwuÕJ(*£óeŘ8PYªpÁ¦®Rµv³:¹ŒÁuÓ±î‹Î†O¡°údË—C¼èó“‰ÅÈ¢ "=5ÜgÊù”D¯r»IV)³±ÖVJDJSr¹ Ç“Ê`V)µQ¶Ö©²> EY ¾,´ð¢;f„ÉD²‘ œÙ!PIÉÇI Ô¼�à™e.x-±"ÆYæ9¥àr¦B1Eyôù8ùàK.,DOl˜N~ùíïæå3ºrÅ_0W’oXÇòí?_v¯æø”vNm5U»GÙù…Qù<êO!õ‚ìˆË B~áó‘ö{Z�‡M;Âkq‡:o.æ¿Âé…\ý_ëöƒûËNãüëM/?¶'©ä˜ ëËßœb� âácýÚ_OÓ£ÌM¿ãñ7øf;é,p÷Ýsÿ¸ývézõÃU÷Ýü;BëfÿÁ-øÎ@Í?toøz´6¯/¯{ÂÚ‚ ì§ï€Mô§?ȬúÚ£¼6Þ`ÿ„Œ’’‡Ì¯mäᵎú‘»<à‰M¥§° P °è_N!:lÒ¯&×Bëâ¢òøÓ˜<ô{qäþº¼?ý‘ŒOíÐÍ¢Þú„–áÅ"¿äíÅ©CvГŽÕ>7ËõÝi—¦ÏÆýÓbº*jÊÇýI–œóU-õ¤_µì×¶_|jªHOWòçÊ„¶Ê›7µåÔåä©@²²N¤rauY¤ d)‰FT²}Ý®dÓ“±‘+)Þh)ƒy—K`zVRpˆ(KT«ÉÙ:P,BÁ9œx”E.$T‰© ³pÌîKb£ç7 &ÏêâÇùÁc…#§ESò1(&Ÿ¯ m}4, â;΋]L 7>:î–|¬Â‹ÜýÆo ï/ÖRõ|ÁûUü·,…Y™¿Iârºø¹ä²ª1“ÍsôPÛ%qÈÄcæDô.…!#2àÖtÙŸòqŠ«hš¢´`,û$~y{<sûÁ³f²]»îÖz¾ò·?êƒÞn:¶žhŽ–™»»M7jö—¾,”Ö5 %çgºcì´ù»!FÜ÷_,$çÁl繟¢dY̆KG:oó 餫Vr©Å½£ãÑ­¾\®Kl.ó½Þ›Ç^îT¨¹ã§ÛMóÛ±ÁJU*ŠŒ)µÁ•ÕÞñKòáJävÜјRš(6±°›—±óã²ZÅ¥ñྺ 9ÛÄšÝI#Ð6Z(¤4aïÂÞ+›*Ë,/bfR²ZQ·<Ûc<ÛÏž;×cV‰9'{R*7½˜ÒLŽ’k«´25—‘˜ä Q3!*@P)sŽ<Ä3ónyXÂ~r³wáÄä—a÷>È—êcðU±= r˜2-E޵Š~³®, IóàjÀ|ôþøpùÈ.ô†Vû‘°(=7(rÀ3Ø<c7ça}^Èä›sŒ/Ö´(û)ävƒ QÔ`]hÒ«ñ®BRpcݘë�(ÄÇø°AWB¶ _7†«o[ ½a%µKþ¾½í×OÜü .á[~EïVÑw„ÖÿDG?ÄL)|çùà0޽øÉrpÀ€% ßÂÅŸ�[@_�_ ÂF>s¨‡o™|èA¾ÓO¾æ¿º.Ü5H�šÆ·=õ#ämÁN„P½Dœ”Fú3ŒþÓñ—ϰôÇÿ2áÏíWÏ+s&du¨ª¿Vã.‰mä)Uöƒ­ŠŠ‹ð,’¡PØâÜ‹: T:#£Î»‡½"Ê:w„q/à «~QW9i6k¹{ú‰åæYÞ*—†³nXïK49,Ccz»â¦êk»ªÆ [7ú2åz,$ÏUETb¢ÂRòŒM©)⬨ UuÖ¶F¯¸â  Q¸áP�3•@¹NQ   d.Hg–É*ΘÌ®%9—…3%gÅr†ÄÀ(¤C˜‡¥~ŠdãÀâû™M‹‘Q$ˆ\`ë}ey Qø‘aJiÉGyrv4ÏŒ¤fÊ5ð›ÕP¶«ú,Í:ÚÜyQPÑÂ(‡mOT?È'©Y×y¨åÎ8ÐMp‹N¹ç½æÉ2 æœÂ‰\IbÙi61=¥µÊ<sQKn·›È鿚ïdzs;5ád¤ª«:óθv<ý†’1´×Gg”4õ“®i¶ÖöBI®µ±í3+Ÿˆ»x¿_Þé¥Ñx7Þ§8æî!Öl*µœM›f?|ÌÞ[þq±í"gɼ™«)]Þå² v{¼_e]óçKþ‡Ùݳl6üP¸’b»ªö33C¡9Ѫgq¨Ý$Ýu6y*ÛÃ^—{¯·$/~›D³gK†¶¥â\f&ŽÓaqÇU®¸9gÖº¡7¢adt§e“Ìb³Ywv•,e#'Ôml'&ÇE»½Jìž×’Ñ\‘,ŠM£Lf¥¦+Ëeæ9s¡ ¦" dá^2@–Zuµ1Æ U<s),g5/Å óx7ݧùA¤ÑEæè¢)݆W"*WZ¾ÿmxH,]ÇÚT;:‚yL‡ˆ0h…¹†št ì#Ðø|«>‡ ðkjp  /{4G`/"ÇÜZQ4ŽôX;ö8L,QmpÖ`³ìoïö¿Å 3 ašÞ@š¯'çúàwu)0vmrøÆæÿ ¸}$:a|§L}—ÄþÇ´báûG_üËû°þðd‰ÿþ¾ž¾3åó˜U€9 …QG¨ ñ =¸vozCófä4½ý²Ng@Ö8\\‡wnP7ÇG-õë=~ó,vŽW 8`3ƒ›°mýŽ6“ŽCˆe¾çäu{¦VóåÄéVHWl?Rø¿õ\›ô’Ö™¿:¬®aê}Å 9_˜¨Ä<L¿ÖùðàÀý¾M—^µV, 9p³´ÐïŸ^¯Ü[òhvˆñƒ4=]j®.|©÷†‘–¾E2+D-ó–x1zµ$%N ³Ï¥0ÃT«X¥uoL¥t%%ŒÀ ‚"À1¦RÕTÙÕ,å‡H)g¦…$–b)¥ (QX¦ò@à`’sQd•„%¦Ù’KXÊpr_íw7KÖ$ –˜÷sˆ)G+¦2 ¼ø…©(tÑe±‘Àá8§à—Kxاͭn Õ2÷W ëíÝ™‘jûá¦}îÔ&Æ6É*@Å‘ycª¥8§(jaUUNFݶé´¦ªÕÛBgu¢NNy–ÛIÜ>eOWÃÀòÂT>X}Á÷õÚ=£37˜'?ÿæ°dUú ˜bxÒlvÌwqçLeø¶5u£êµ±I¨š‹È©æâ2ª6è˜Ã¦“–<ó ?¥6øÐhòö¬¨M¡Bqœéo®õé·õÕÚ¬Çú8…]ʉqÇûµ=žªôåAM÷úò´zº~vkšÿWÕÿKm>ÒaË÷¹ä¤åÂì ’)Ž*Ž б³ûœ¸ZÌÅ‘¯± @tsT q¢õ-çš™Žä]Ý·¶7à!ígò¾ !Ö]Ávs“4Ûpem‰*ï¹I‘SDÍÉ e?³t ZjÎtå ³ª—IBQÈ ^ŸOœó1Gæ<1å•i¶•éꆫ’²O‘àÃ<&å–2C:C9Nä†ì2;D)ãÜ™K.Wv·å×ïïG!Å¡‰/é¶‘+ t±¦»àfüøÄ)!KZ‚W P~…)@4X®@×ðÁ¨—Dq6>×OšðÅ|Ò$è— f`‚xBCÔ{Ôx-­ýzÆ=¼)ß! ¼a% Ñ]ÝŒ_ùùã9.¼[‚¿Ïjèlj—ˆëÔ¾ã _§n¿a"½z|¿N¯� ` h«ññ,R>{;SÚ½6)`3�öÀ#¬}|Åð�\ßÿÞëÞ‰é¾B¸þöYìÎÂwxá xŸë3ø9Ü–õºýÇÙþ.ôÿÊuLÝz zý”Né6óö°ÄÝþvŸ—3Z.Ë¯Ž«ýøÙõSÄç—ÍŸAüyFéèo»0µc?�÷›ÏNöåáɓ˳Ë:}\¦çû& siËó-)¥~+Ń/ /Õx¡¡­=?kºªØ®X#!W¬¬t’ÁáHAè¥CRˆ“ÑIeÉï•zfL–U%šZ*€$xÉKÌ`L &++9ùÅ%ƒÐL8ã©€ Î9(Ç”s¾aÀªéÉ ©œf—üœ£÷CŽwÄÈÎyX⋃·–ß“S!¹—ÕjC;P[Ô3ÈÝò_—¼MÍfaIÖ¹v¾RÛ³fܨٚW\}\ô“ÍKyÌžxNŠ8«²ZOÁÌÃvÔjôF¼7¶cb¥dmkóÆ-‹ºÊEs8ÖÚ‰ËÓèËÄÏX’õ>+ÇÕJ=gÌ©Ã4-_žØÄ?±Ä[yù Kçêô•¶ÑJÐ:Åztü4M>™è9fU£9mÙ"ät-Ò)æ<>pûPVOŽJ­›¼”ñhã9liúT5BkhSxư·çc×UÖóYãÄåKMš|<0y§MâK),.ÞÜ›t3—Í~z9Ú¸;c“Ï™ËqœoÝ—ÊÚš|aÝÅX¿µïmf.,yŸ+ÆŠËË¥c¢œ­Z–­È¢°Zó”dIŠÅ$g…¥ÈHT’ƒ eœK(¦!Û.X³ tŠ‹{•g›¡µè` [ %ŠÐÙˆ”JâQð*´*YU%ª Qð™Ø$ÙXò>Ç9Ì÷ói 2h/â8å/céDvj¥Oûñ·õ+·ñc³mrnÂ_…À÷VoõóU­¶Íy‰e7>Ÿöû6$ç V7RÞêårÞ+L5Ö¸<nkè& —À3ÔM<kŸôô õ"Ü5æpú:<ç÷Í sÒàé[Èç7ë˜*À¼þûÜ\7_ûë=V¶øúÇŸæ|÷=²ÿÿõ†oŸk °n¨z䌟¼"X€ a…ýV;XÊ÷@@pÀàˆ@)À9P xñxR;þ¨†P„p 4_�áíÒßVØ;à(O5ÌŸU‹ß7/¿ªÎŽt.üôñ>U ÛØüÝQaVJ1SºûœÇ“ýtÖ¨òóÝé_™`KÿLäaÀïNq»¢OT<+%¤EçrVMþà°z†Ê.ršæ¼žÿØa]øyU§¾J\øÆÓ?¸°6¼jÖÛ„†¯R¯×}ý¤Á9C2 õ¶ªlÍÃÊ’á‹™Ii„d¨´ÀR`9<¸d¶åêõ¶æ ÄŸrŠi - ¥"&Dš5/ªE”BÎA”(A±dŠ2„ª¤Â"Ò!Ä$‹sùËÌ|Öß6Å èÓ¼›ýÿ“KwÊ?ïôJ2«²aü`åuET¢ìŒ3‘™ŽêYÞ~؈Ÿ}h•¸Ü˜Í™VMgë˜ú)o±E¤˜NK ÷nŠC•§µ)Y:a”îddk÷¼NÕLî*ßðb…­Uct[¤•ÁŠ”k^騒,™·E®˜8ž+ÄRÂÁå{GU4VVUVBdÖìLl¾`ý¹]÷"Ê=ìBµR¢BgoT·KQÓH"¸Øi’7®, dÉ 9 ·iùoîÏ­1Êò”^ºaôwHZµ‹2ûö¸ðá”bBʆÅrõo¤ºõ³¨~n·ýÓaî÷‹ž»¤~ÁͳD2çÙ×ñ¼nyM©àuðq»©+"š=îÏ}µizޱʆòKÑþ=;W¬‘aØ&¸” öU¾)ìhÊZæ5ÏÜ/"h¦¤.*ª˜Á— ’–Eç…¹n^ÌÉ÷‚ùVrPñÅÉg,zž\ñçæy®žHsFR1• ¢a©£ã Í,C~aeï÷iŽû»i:–¹ƒËstGЇ*ï7'Z(÷ àå0âï‰Ï¥ù…¸Òüw×%üÔó’>:Ý#}Ӹ͵ÒÝÜŸÆûkUoL?w2d5Åú“¨jð'ÀEïN`ü䀕Çåˆ'ô:.B¿ÂâöxøfÆÌÍÓè®Ð^#…×uúu“x[Ç@¯5!@]'¦öµÏóë}òWßaq1¿[¦6@K éGM÷~ìê¾; ퟷ7üÄ÷´ùÖ@éq¡$yø. ÕðÃ÷zÐ%ìר?ƒ§@@0À¾ž&Ýß—oó¾q]§7xÿ×d' Ýá*ãzB˜ß°m3Í&ûÍ‚)"x�:¸äÉÝžïqOø¼B£qÊÀPΗqûéN 9  òyæÉôó¦ƒÀS`[3¬ý#Žãv桸=XeJÈf÷Àî÷vÅšySãi‹b~fÙS‘[>¦KÖóRo2W9/OëÓF?k«ÍºTMT¥lƒ•PF@ µÖÚ˜”5™È"1j<jQÊL<D4T4[6&è”@ïˆö B&V(#“ÄP8#%c9°à‹÷ÉŸT`™!æt 2æ•æÙ£œR:ÒÀñeŠwN·%•\2–`¬ÂCg‚æ\˜*‹Œ B޼±M-µ9sù<ÅÿMfeGýeýô¢Z¯4ƒZ†<ðeª“|•î1&7`ÎÙÂÇ’¥òœÉó¢R@x \– !ΤìÍXi­Ù“ÈWš[µêìl{„ÆE·äÍ¢W¾b˱Îcâ´;DŸ\d²å¼­ªÏ™e)1œãÖXB볤: ȈRiSKr%ºiöó¾äEJ¹ƒó‡$ Óqà{åФÁ]µ"¨.ÿÓa?g©nBv_xH—òtÖã½uÒ‚Ä Ã—Þ<œÒsÏ{§;¿÷6g•Ž #[1)#´IZfUõœ/µ<5éö¬}ºRu!©:õÜ{.â‡~Õ‘Ù˜®H}+âB˜Â—4Ý囯Ï"do*v³âI0a8LÈ,‰º¦…HaLËœ˜ØpÊ]ÊŠ3=’å& žŠ’G–8 H]Ð ²kšÊ6V[™$OÈ6pé9#VeaBBòn¾‹(ÅcH§Cžv»Ïœ#¼YX7÷ËÀ ñÚlRŸª ¼ìÔx/ÜJ¤Ž»ºp´0ŸôK´|cv‡C¾Óv°æÈgŽÃ§`‚vûufŽØm‡}ƒ.7~;7§Ä_á£hj‚Þ;üNby“7óDâ£5pïî@ŸC’úð:"Àh”Ghám½Âüšö�]�ÇL›Ný:Azù†Ä7xþ�¶xDRE‹T~?Åá“7Q›?­1ˆ?ø¹á‡MšÖÀ•Å®‚Þã Ý5š/0½^Ó×-sú'Ýëm¶Ï£Â@�!<ö‚û#¡ùm‹¹ ^£ôÎúl•€,£óÔ„à¾v|jÀ\¨£[Ý¡Ð;¡ãê—Ånºæãƒßï·ûX¯_ö§{ÛiV×1/˲l³g­åþª„J"g„îE.Ž[Ë—µôgË^ø§ÿsoÚdÉq] ßÃcy[feÖ�)RjI3jŽúK[›õ_˜_<_ÆdÖcÓ¦‘QT³)@•ȪÊå-±úz}>TP� $Øbk&>eš½çÏì^¿çÜ{Î ø?l±žs=ñ§nþ´û¼6íÓÂÛ†ÖUQünQQ­ìPÕºŽ]svLnGêWJ˜F™ºQ0¹¨žs£  qPÌYeÆ’TYSÙ¨d‘gJÎKï¶p²ré")ê7Ø¥€/™±ÂK¦RŠÏÙ‡œËhñ1‡D…1*BfSŠYÄÂ+^-CæÀ…ç©g‡YÌ| ZtbÕy­B°¤™úsm‡NÉÆrÆJàŠâ¹ð¤°n _­jiUŽiH£›RŽeNæ,–#²ŸKž*³°Íž‚ã|«Õ{W*?•„6+‹‹LiZ%ûMý¢¤†’ÈŰðI¬‚0ªæ¬“Èd|V) —ÅÐ?ô‡{ô¿ þ7yZÛÿ°Å'[Óè:`¼ëU$½Ùmj·Úä:!ð©”ÁCLºø�� �IDATÈÕ™´«Fi¦X4˜c˜ýËù+®öÐ,}0µzÝV~/íå…;ë£Zü4ž³VåëþàËýáxN¦ŠŸT̓a¥]-­ƒXtJàܨÀ\›Ïº°]r7^óò°6V[[$OŒ /ëÐ2¡ï;}f»'V‹ÚÝÅæÝ|cÉâÏþÓ-,ÓÆÌ†_d|Xч:TfRÍ麟Âi. ´©~¦6B®j¦m-¥R*ÙŠ!)Îáàr_ܦ°n)™©Éš¨JQÌ1“¨r<1±bZp3™Zƒ «ë¤K<§”91 eN ¹"#…>-ÞõÎ…Þ§eZúãõþt“íšR=£q}ô÷bY+µ"QqÅnt^Âr8íp°¹=¬Îœ]^”(ê¶ÌñX͇0îs·v~¿‡©ñd³q¦Ã!�è·ˆ¸ÝÍ�Ë Ò ÑhLºÂÈWÇóKñ¨-`ñü¬Æ:ƒAyÜ=|Ü}jr¸Íï߆þÍûPž—oÃØÅ›&£äßžƒ?¸Â:¼5xxÓÏîÞ~&€�B2@ýÜP¨¿‡×Àé[éåíÙzø·À”~øÓà©ÆÓ½¼uNƒù#D½ß·Ö·½}Þ¦•vï$À}û¥ž5ð„ë…ám“ð‹×;\`Þêš¼¾–w@á@εмÄû‰oZãPÎ麕W/”úmy´uÚ»lé/îR–®âîWQ®Ôg›ýái ~®cwôþeÖ׃y\o~‘tÓðíq«öR•i¶ã¹ÆÝ“º[·?)ñ)Ë'ÃFޤÈۊו1 ×÷ nDÜûr†|¤ÌBð¦*ÆT“Âs¿0Êܱf®yTÄ”îEu*ÉÑ„aD$­ƒÚh)ˆƒ—}™æ$ª”VY×–g`4ä|bQ‰¥@ä¼'_2c,‘*E—œRa"Æ()æ¤`@qGwš¦dÂ*ÎÃJ£’<KÔJIÉ!J½.mSѪMš)çÍ>–L[Ç™€”Òf]1©rDˆ¬Ÿ—of)Ô]=ýùä*ï‰%â¨K¥µ—nN2.¹Êœ±ë˜Òõt©Å¦íÐÚT·YUk£Û2ÊÙŸ¾œB»—+6!*…‘U%¢´45Þs(%–ªáˆþæ‘{ÖU+*.–P<O4áš×pƒTYu¬S­ÌFÎǘ–uAcC]éR1‘yn¼•÷yº»ïÿKÚÓýMg¶gfà?&QŽ¡Æ$H¶6žËJ?8ÏõMýÜ,ŸoÙ*ØÇu[u:£É<›Ùò_ý m0È=Ê+4ÇuºÛH­WY¬Ü\ç˜9£²0…l|¨xa™3§Î¸Îº©¦øHÛÀcü�8[rlÄhpáJ•ØSe7V–zLÞç>°ÈéÄ”oY·©;»i¥ÎÄ”HÄG&©!‰9‘}\³*$/ü_&&ÃÌxá5c@Z•ÆX¾1vÃ…L *)óTY&! dæÂG¡Ÿ§c?ûCžY; ¿vË+mèÏNrô«i#º*¯¸®„“9útsÌóžö6™âiNGYN‰a¾Á`ÁõMÛmé£3šïOæ€ú›€³B�£a€[£ZN¯‰ÏU?NظN€BQÌTe6%}û%äËJ§÷}øà_À~ÄøÙpüá0fÞ‚NßøzjÃ7r ï™÷ÒÀS¼xiÃ÷g^Ï\}·­§­¬ñŽÎé÷5ø“`Já‡G®&�¸ŽÀ÷‡w˜ÿ¨Ë¼¡j¾ñöùsÿíÝû$ góWµ7÷Ã[w½þmï*÷?L枀ÈWá›g:àüñUþx3­ÍW³¦xl€p¨+<­7Ó"âéÜߢš>Vâ·;Ø)ö{ WáWéq0Ñ]ÞÍÕƒs5ˆ ÃQ/ž™å²3—çÆ†ëlb©ª{­)iÎÖÑjÛÕ³hZ.JxÁ½‰Asþï[k¡Á¼_Šš¦Rx)9r™•uÂF–r)'ïÀH¬¹iÈ´¤’P=£ÛèLf»p)¸ŒDŽ1$²ž)µ ÌK++¦ ¸œA¥PN|@ÑD™+šc‘DL)Äžf„"8¯¥Ê‚¬(le”•…„(©Ò¹ktÓªIÈ–Y@¨Ìô€R¨(R&§i‰ãx? w¶NR¦ýxòrZì²Ím#S«‚ j2ŽÕRPM§ñù¾¶êôFØf©k¬Œi9–ËýMf¿-åÂ¥OÔ´³’´Cg$ñ²l\Oü–§{]ÙªO]µ©».ÿwÅ>˜>¦Ø‡¨ÌƒŠs(µR ÒN»Ú$ÉÚ•6‰ÖžîkT QRá­Øa­ï>v×/nÏŽ ÁÉhª-Cc ´£à1L¾!£+]êZXËXË’ü"«V\ù¹bœ©tè—ö‹}Xe׉ÏÇ«¨ošú‘›3ñQAC¹_âȉH¬áê.ê2¢Ätb‚mH±êR¦§yã+pÎ"µˆ€ ¢KºËF1ñÂÇ«£{^-«ÿ–ë],ØŒ!4÷õX15³¬õlå)èžxHñä—ì&nuM¨#)‘=S«ž·›F–t)Æš®©ÛJŠRœ›ãR¸'‘´VUÉ’q—¦Üiáã¢g7 ÅßÍÁÍvÎ®Ž‡/¹^Öò§¿M^htì´OÏæq ¥ug¬íš|“‡ÑÒ—»“ ¿VÏÍþR\¬š.èÕ‚ÏÉ£æ33WxÉ»ä´Í?!z †^áÁ/p¸‡ÚB:´f%ÿæ$$èwxñ ¸æõÿµ7ôç@ðÀçþGDz×RK/5š×Ê¡xŠá Ãë °õûú9¿}¾/º–ï‡âòúÖùG‘¸ 0ÿ!NûOÈE¿ ñþ‡Ÿòø(À Ͼ#Ùý{™û‹·€ÝÍëÜëÍÔ[ü›ç‹GúŽÕôw|§3€ð­dóÒBþûúü"Ý„ú¸ÉÚK‡ëwØo·‹ûeǪ±ýß^àìÐ}|Ì7Î8 4×ø‹n»9]HÞ’;Øå ã—nfŸi µÖ<]°ü:ÿûº>ÉzÅ› ;)7µâBs1±Zd•X×µNj :ª´eÄ‚ïC¯dÜ£KŠ1p˜ÂÄ\ÌŒdÒ"|V¤+HkDÅ+[´Pj“Œ¤vš«Á%”äV$9’$²¼-¤…³X¢„Â…(!/Í:ž4y¾èš¥žºäcár2¡Þä³3ÃV²UŒWŒ¢ð^”L©) ÌäI™”ñnŠsô x®Âp7Ý?Ÿùí¶úEg¤œÝÑ3¥ôÀÈ-W)‰…Ñ¢(T<%™‹GXŽÂ™“Çr+C™ÖÉ®4Úº*Ovnâû¹ï(,ŠäRÆ€"¤á<íÖÝ’X<&š»ŒXi×üeŒÁ*8&—ÃÌr2Lš®UbM3·mêl²«jÛm¬Êuh¬œ "•¥PˆÊhŽÖòƪiúIÏl3w=IðBUu î–Øž'Ë¥B1‰Öµ·™¦@ïñ4£ýÚ*näùPÿÕWöp£ïŸ0³®üÕãýŸIV=…²fá÷ñ>ί /*7;.ºhT¨ú›W.ÂW‰ôÔ5«@›•¬m "WÊ’Ä Á<“†˜¤°”~·{é^VZiuB—…šÓfbŠ…‘ôçT9¯ÈSÖ1øA¬á$e"¹L#ÅëJ‹FeFÑKY:t,eï¦è<D„ȳá20r‚•œN…N±Ì$¦Ìæ”’;º˜CÍÀ ¿ìÔÓ”Yï»Õè–éõÝ\B›öëéqÎjÔ*Oªìm›°)ªàÝ«öâÓ)5?O,é"ÿüüÄx_ænvæN<bW#14[”æø=Î�ù.{œOq£Gzùš šŒ‰F `ù­­½ÿ1\¬~ŠéSð�úÎh0½ ›ÿà\âkXéýão ­ü£Îñ?ÚÿŸ­ÃúG“Ûòm @èë}G¦ÐMX¿6^}sã=`€WÀ Ô_o–Ì  ¸{ý*¼ÑM|OÛÀ›»Ê—»d[ïx=™5ôn?\'G&8·ø´ÿx?ÛØÜM§¶(á|\?ÂG»ß~té1¶»U<Žçé™Ýƒ„3äÝ›³$âVßT"ªUâª1s+‹Ád ƒ—ǹ⋅î.¨éˆM|X<-Õéèïó»þ¤jÏæo´åI+ÅK¿(Ç%lÑ\qÎ!5³ÆhÅ8I´† §R¨hI•Eå”KLˆjE™3 ³DZ‹Â‘—gðs¦çyŒ>Ï•·±VYƨÊ&‹J°ÚÉ+Yí KÌܦ\ ‘táM­ª$J/óÜÈÑŠ ) p„úݶÚÚ•U,«ÜÓ8Ç,¸¨[U �Ñ'Ÿ¸s:-<NótUÂÔVôôI]Hs ¶9¡~¬¸i”²­—Û'4UôRÈp&V`jDŽùhXÝÚöƒ5“¥=„—®Ô[fØÊÜ —òäàÄšÌ3ÉjZs»1̓®®˜Xx5j_ÒP”×È1¦iˆ¯‡ë»ÿv›Vñ°æí)µñÞd,ÕiªÆC^¯6Öª¬ØËÙ©iÀ2Æf6Ì øU'O†O,Û *°ÇvMôæy÷¨Ú|À7rî-÷îÕ0=3¥ÙÄ£¶Ï`Rù>ñ:¥ö…÷¥°Ú#çI˜7a\Zî‹GáwQ+¾ýùj+9jû€ÅÂe)ÞœüS9­[eꙋ —Ä´`Œ'ÉÅXˆe.›ªêªJT"S’ÈX|*.K© ˆŽ-S !3JæËtçç—³›\É©0?©ytSÒ÷$ °zÒ˜u#jE $QŽÂBv -óÝPŠÜqŠbB K ¬P}¼y4\¼â) þœF©¬W|WA¸#—±T8r¬zÌ׿Àr†j‹ èÎÁ@?ÀY@uB/AºAûöcÀPý#|@²–óS«á[Àôë‚@\!?dÕ€€­ÑÜ}g4øÙjð™~°Ïñ{Ñ­÷h+ýÿ:7¼{ŒoIþ××9€ãüÃú‚5°C¿` w«¤ÔëwáÍ�®€0M˜€úMºÐÀÓª\‰!LßkjÚGèñ@÷n³çgöùT—sYûXCûúZ4s©n^îô5dù‹ÈÓÆ=ÈxkîõmâÏ*À|Ù©úQS/hŸÃQ>­ÿóO¸zÈ×}© É[&šJuu«œ‹‡!ˆI~ÌWžß¢ümV?qLçÌÕ‰)ý*ôø’Q/‚`ꑎ+×òŠå3dÁXëy•tQ•0v«tçu[´Ö CF'Yr&✔RÊ�F%dYD"O)“'Àp¹,P‰922¬ˆPqŒåvÈe,‰ kµªcFY&á<+D6Ì®@rViˆ³ÌRJIBpm¬TÊQ骵Vg“yA<Ë?_dËDëKä'Í5MÑuÒ÷st~J¾—ãý|ÜŸ†DjUUÕyY›ê,ã²Äul Ьj‹x�¥)ïѤz5˜èÉÕTÖ²2-­™Q¥yÈ")V ¹ò2K™l»Õ¢î ·>ž…*'å“VÙ&Îa8[Õu«•­Ù4``ªbÍ‘}užÝ}UÒ—^+ 7˜tÚø‘‘¯µŒ"L¤WnŸüµð®Oz oFl·ŠMF¾Ð±yØñò‘™dýÙº<ögjž>qÝÎÈ Å+ÇšG¿»süeâ}^ÞìÛmÄfç«ñ|½®MÝ%Å' ‘Êx<£Ú6K)Ï32É“ÕÙ‹‹©jÌbžÝœ½3O /7J”­‘®áµ×F•ÎÇi—æCÁýLiáªGWx¥H®¹”àYÆŠP!—!xM¥2°Š0>Pvs}Ÿ™R<xýe –‡ªP[†ˆìÍxèríì;¶VÙš•¦xØ®çv\];7xùr¬Â¬‹Ý£¸lpÈ‹}Ä|sJׯ.JýËP¶¸ýðxü—-üÈ—9Î5¶o1* ÇsÕ­šŸ§Ü`½ƒ^cùÞ �†°ÁU‹p�Nê]Š8�ïM ¯áÿŒ0Ó7)4À‘oþÎ?@ <–÷†û÷­Rý°æm¥·Ÿþ=ctò߸,ø>²Öà»qùð­÷ÓÂi†ÿ=ò³g@H”ðîŠЄÓ³½òpzSÌo\+ÑÔ|BøzGvÀ¡=ž:\1„çHí¢»¯4Ú™ø¿+\WЄŸFØûÃYS›Åj}M‚–;2y‰¶>ž‹ºË¿ ýÃü²›³ñƒ®}BÀL€J7ü0©Í½õGkGW9|ÀéÂ"õÏóÁçm6· _›ÜpﱘJaÚ¹qË…:}:Íÿý Ëë&U—ÝÞœS]£È¹T¶Ñö¼µm«$ ©8AZ(ÁÀ¸`¢0.Q¤f¥€‚‰%ÆëÅÇDG0‚"R™ŠnñåäOT NSfaCOÖ…ò¸VqYP¸ˆŽ5Ä»Hª >C¢•Yj ¥Ò|Õ–¦­!Ð%» µð§>Œ³Ë<Œ¶*E»|w§»é~ì5}ªO/Ç¡\çtzrC¥6Ý-å”ÛF –gç|`<©ˆ¬`²È à™J4Tø,Š‹^±(e¦Ì–ÙÔ9ÅvYS<YŬ2–9ˆXJ¶S$ I%ꕱíÂïOóɉ@Ò§ì2<«Šÿ‹ÎÅ&Ii™®ÈfqÕ|Ô9…) ½¸ùvôáz¼Oñn*¢S]ìª2UìÛ‹Õƒ²gâTÅ Ðíì¤M-½žvEi>TŒÇV4ŒÛsâsò›žm2÷\¶"S¯å)û8ëcwÑ«-*[‰œJèh6ÔPñ˜ˆÝ.”¤V°†«J˜úRZ½r•9VúÅU1ŠÃg>±LqcDM¦nMY» ¬‡Ä]3ûDSPçKý( ëCnT€÷•®¹l`KbÌ,sbIrÆ’1ScTiZÊT|bF³¥H–zDˆ¹Óýjá>ÑéøU”Îò"ç{Œ7‹|~SwJr©ÔàišnQžaXª‚ó ¬ênBZjê=x ǰR€À°º˜º0çüZ2ý|eð¨ÃîçÈ爡Q¨€©ÁÕŒ›Ö]>‰“(ØÜAE°Ï± ß!}ïޝûãûÉÅàSäw0êüÎÙ¿ 8þ�1ð€þGÉâéo²×ú‡Ã×ÚJ?bŒNþ—ߣD‚øCOx‰«„ðš8FÀ}ãªÐ4KÀ]Þ]1ä7.=­ _ÈoýÊâk}ïE>U÷W-Bƒ]F„®€×Nþûݰ0sóÁž®«)Tͧªs§86û¢�ÿÅìÛO˜{èoÚÊ–²Ý¶›ex˜¶fýk©ð"`Lá3ÕÿYkó™_ -‚“"§‹Lù \Ç ãü#)È2/é•O^‰%ÈB_.¡'©nw2þã"}œÎ]¹ÚÔölÒB@xT :²BkÁ¬b\p΄Fâ‚ ¨’³€œr‘¢�™2bBŽœ'b‘s§…´*ydâƒZ|΋¦jI"–"É£H%q¨Jº­-3¢Ò™edNJD#- “‰£ÑZ(«¸1Ì¹Š„T¦¯„‹«áÙm™‹qÂÍà˜÷§Ãx'ú}¬ž$ñÄÄš‡¬ -ExpG,,ñ@Ç12‘ɪ"€ÄÁMLÌR)|Þ7AëåŒËOPFž—4pÉ,r§ªtÌÁ¨쬒[kˆee˜sJÄÖ–³Î´µmšºR$x8¹jž–ãtô‡»»»ßó$˶°.ñ%*7ciÅ))òužæ¬¦qdCêKŸŽ \U­êŸÕgÊ럑?†[Éí(7�ÕF5 Ïm¹qS(3lKmEJ7¸á.úÔé®-Ú:Fã™´>_©³*UÝ3 >C{ª² ;ïG¶ø+.[jx™‚åB EZ¡5K•gÙ’_ñûŽÇC(k-•9Ë,"©É>bú‘f¼É{å_Qà,©Z[ÉKà +‘‡]rLä(¥mq ÅëTbÔ‰ ” Ç©IE¦úÖ—Z>œ9sx~^DL|/†/Õôÿ\ÉþÎÿ»N]>UÅÊ=hÜ_nrõ0~Þ‰»iâGùÍ´•-S‘꺊ÓÍk<¸‹‡±ìŽ›ü,ùO^„‘.%Ê[PœEŸp’˜­Íañ:ÀTHÿÌ‚@¥‹ lùV Mï!Hßé4}›?xöÏ�ïµ?co´ÿW‡Y¼Ãû£´•äÿÌBá=ÐØw¶ÿ%Ò;Oˆoךéu{’Žøë ¾-¿GÊ;vÛÈ@ ¬3@ذ>>Žê¤|^÷@:Ãô„þ%îïßþ„6<ÚÓUF_ÂY\«c󋕸iÖ;íssÿ÷/5˜Vø‹‹‹uõ kz”C=šòjÁSž¤¦Ò*æx6°—±增Ïõn'/»T›¿gå>ß/<W1+™­Ð©=Æcã­†Âï;Bü9ÿg¶Å¸}Áq°îÿ‚ÿ„RŠÙ-£—Û";J²¤4»©1Êr®••‚g!˜àœÅR2…@‚8@(¼°JŠÈÄ(3J%ËRd¦I+‰S⼚#ÏÌÁñèSò<ëUÍ·‚ÏH&s»ªÛ(#ACàcJ…Á›I gIU…‹ŠW<©ì)ØñȼS„ªJ^a@\–¬CÔ2‹£F)Um¨ûH‹Úê'\4tj ;­¹ò¼ô\º˜]pŸÃl禳¬QÜJ›zže!ž$8R‰%§Ö)Ýœïr”#‘Œªí`îE®[骱«†#QtÅ'Ýn·ÍjmªJ²‹nœ‡ÃiuýòÅ—Ëí³0üŸw9-^>希.÷ýý"×Z›z‡Jéa y¦ƒ0/ç^e·’kËWíG+‹R­F.C:÷%¹¢ç’‹4:u…GQ³Þüg×Ì}TÂ*Q*Ö)–êÃhϺŽõ•cèÔÚn+k«YVX\Zf^³¤XY¢Ó]#3[gk¸1‚Õ%—âs/ÕÁ(B bᔄêÉòhø¢W*¶’4%?òƒ–i*Zäµ×J4;Ù˜ 6ŽŒ÷‘U¡œu)I)HQ)šÅÈ\šÉ-IÉ$£F¯›EšM>P˜‹¥hX®BI|Öw+³lX§£nGRï%-ó~‰ŸdŒ»!=HÖÈ-uñÚ»@M—ë}wý"-Sù'ðãþôËËã…í¦¬©qá)Î/oQAŸt‡þ˜pãz¤æ1¨ÃÜC�—5VkANrŸ¢@¹Ã ÓO±£Ë¯N ŸþP”ú¨5rÀí[è-MÍj”ò{Cå|T€Û÷„òï#1ß ³Û÷aK ˜PËîß(7|?ƒ…ï `ükºfÓ[Òeà— 34!¼»iìµy'ðZi›ÂcÂ_O ü]|ß* @«KSÜŒ¾ùN:x\q„ˆÇ¹¿JÏï>Lº|9§R�¬UZlV¢5¹ ÌK嬄gg錙]sfO-+a|X¶ ëØV–sùüÒ6M͹à!ø˜=‰>±™?h«I·ž Ï‚7Jb›Õê•OgDVP‰_%¿ÍòÚéuÚ2g+gXP®ï4šft…)m9ãÈ –8c¦aÚN„ VdaP…©TD$QËšf™< ’J(/ ¬*¢ðÊó&¯Ý¬e¥(ƒo\æ…ifµ”†g§-½ÒÂrÅ•rÉJ§…g'S Šk&#W.ð˜Äb¸Í刲dÖ€)*²qÎEù[Ç‚cZ¸Ì|hI[×¥z ”,Ø„¨¦"–†åª;ÓÄù¾ò{“Ž(¾¨¹4›ŠÖ-«yíeÕ£H‰Lzm”мZ/›³ºÉœÅ¦ÇÀ„&Á±miUØ6i[uj+Ò¬,3{¥5•`¢øàý1MËÝþæÙïž_ýËW׿»z®îe–*} ëœw`+7û;j;¬ÎEWL4+ëlâŠÏ^ðÜ J¹j=“‰OŒÏ€KG|¡»ôE&¦"_íÒÅÜY§ÌbQ‹WÉÉãÐä´„ªù°ÐÏÎi­ø"m=P-’–6pCBy¥EÔiÃLÑ«’¶årÐ F®£ð9¥i4ÃPrtªåF1?òâø.;ª­$HÏ}jêI2¼ë¶M·RV´|6Q´‹®åB1Ÿ™ ŒpOÄ|0ù1R&TT#¡‹%SòI{EŒCÑ­ûÓË#½2iÕ¤G ªšs[Bí l"é/®D÷;Ó=`"ÛŸ·T*Vgh*w¨ O¯îÜÇözMìQÚ2äþp5C]_ÕãgÃ-€ö±¼üh“Ì“0·8ÿ�'í–!…nD hPpZø–Ñ[¸o|Ó¾ŽLW«¿FUÁÞáø[4oûX&ÿÞ¡¯ƒÔ·­ß~1PÞõ À4ï-» ¼7ħ?>šÿisÃÕŠúnÏè;íForܤÊ×þ ã×UF è_ä–_Ax×Dû+@ KÁò…ßÛ…†Ÿâ+SÆþ囀{ „Ï€K÷`Ÿ7þ@áå°e/V¥˜.‡.àT%€^"Vá†ëÅ’édΔj'§ƒ#«ý}+y茨»”]«¬\Òâ&§Ë ^ïaǾÒ6­Sê$ËœUM\‘cnö™•UvÚ&±˜§öieS;ï<Ù¸<:î7¯+ æmsÔÐݦ’¼­Œ•BIÅœc,³¢JÉ‚R‰ŒR‚`ÐY&¥�$e¡’Y$ÏXfŠ+‚N¼’sjUL&„]&•µäÁRæÌÆ“ö¼ÒÆT­*ªdÀ-‚›Ì]|bÑ€ h‘»\b`dž É©ÒlÕ‰vɹOfŒç~Y˜ãE½üj‘ÚQwçWí¦f;®·RŠb±J“¶MÓWª6ÊV�z™$K]êµÁƒ5ZÞL!»RBˤô\–å:�� �IDAT�FÅè¾ÕbË+äÔñ<ä®Mk‹†­:·•E¦–'³¯DŸ¹óƒŸRŒÎ»›Ãõo¿øôæ³ßݽÜç—ÏæA.Šæ“ø¸›Ïýü0¯VÙ²û Õ¬ù’"Bjk!VÉó€<Ô3ºcŽbë<‹‹’wáî._‘,VñeKý–’b³>Ýúëêàæ‚¨[¯ªÕ–Ìyá-u‘¶aµÇ_ù|Ò|ÔRÛ¸Œ1¡x‹A ìøä.WFšV‹Žé&2Ä22®zHCœ Ò/šOAw³Ÿdn»•e9h®¥©/-6kÝYÍL"pç…£”•J°2¾°ÅåèKEA²{™¿ n]œ.íŠI®9×y¨R©BÐEܧ0Çý§D(úËájE¿l¨"*d$–Eó RŠ7 ×¼@gÙmõ8.ÑEJ\0¿»0åT‡y™Ìg—²¾XiSmía:ØdX^í‰lQõݸmKòÕ˜F|ÉÆùwè&px{à Pžô‹×I[Àj´¯Þ1� €chѱ }¦Ã1½E‚ò»á~ Á‘_k·~Ûúí»×;¦ _‹ül€pøöÕ׈yþaìÿ#L)üa.ZO€¯Þ—ÞŸ¾I•-P¯!{„€›¯y¡ï$' „‡€~ó;üý€—é­¯^<~û´o—öŸb_7Øl°N8d ¿–�ÁöX?Ú<©Uò½®7È(-úù4hüsˆg`ÕÞ-ZÞ0 bôtiÞIR¨ä•»½}ô‰êÔOÓzóþÙÌ«ÜHZWsšK™ïCÙî¼2/wm0"8‹MfÛS+’_-½ž¨mÆ*%´rÕ®ˆ^¥Û™h[ØmœŒƒ™’+ô]d²KÒÉ$Ó,Èð˜2åäœÙ¡”,`1³™&J%ÈVŒ[¡ˆW 6“g™EŠ¥¤B‚¥œ}ËEÏ6ˆÜ°F¨%ñD"rÅn:[7JU‚åNŠsY›®h ©E)¢€’&/|´&¢c  P ‘Ó™Y"(#}%‡~î[6ä½î ¿lô†K#ì,.-U‘Ç*GÆ…æ¦}Z[£: ÛT¥jJ©§ÀÁÈ V•™¢x\Š@\kœUœ£í¨«’ ¾V±SªÚ•ïxÞLNPæ¹xp7b˜cѹ‰~ùÒ¿K7Ó25§/Ö_æ¸3Ãp6 š˜êdÐ%ñPB¾<¾Ýê”»t»‰*ôMR¬™Y® LY o‚ç£oà#d-‰q9–eò|±°(ê}äbIôêIêõZ=ll·Qz±Fí)›=SÖ—ÂÖ”zysKÉ‹õ{¹d¤‚u u`jðyÝðð]'‹D”Ü…ŒŒg3Ü«úŽQ¬loxS’/&Ü™áàÆÍÞøE* c "fæ"´ F!¥…yOq9fïÒ ®’‰K%ËÓ:$b,ΡhébŽI纥ØiäËt,î g÷åIG½Â•LŸëøÄ7y”÷sÝO¤^ÊÈOÀb° îæ$åÜß[Û_Îì!»Œ‘5†Ëóì®÷éÑÝ‹çÃýu“P t8âáñN<½“-ÆÏ®å+~2<Ú §o¾à àï1-à^khÿýÎŽ¸m—¦ÁŸ¶‡+ƒÿ–„êߣ|´ËØ…Ž^oÔy ²˜¿W1è4]x´´x«€öãÚúó¸Õ¿)ýCíYñubøz;4x€|w¨ïk¼xK¯ 4N7ït ¾Óõô&©¬^O/,@ÀuúÞ¾»\¸�;Ãöô‰‡ù͸J ^œú.²\ȯ…ÀGWÀo€ª½Ò «Œg58¿_*Ëòú<l×'‰ögŸ™ê—kÕå\ç1]åùÚ÷_tn_î*pÛ®˜ªéSÉÿ®•6$”JØh-fZ„J¨l0<f_jo7FVbËÛEǵÌ–Ú”²Î=†×JqÉ âÄ‚L‘0!aŽ):Çy&eD¥8¥¨’ Ë�WBÔJŠÄ!²à‰¥\¢D&›–¹Dƒhi‘Ë1…jíeAº(“ÈFÝ€W† )8ñ­•’ *†Ë "y !z—-)C•‹;…eöR‚BTò$ìQy.‡ÝoŠÀ`¼à•ä\²œsnÄ DÕrµÄ\Rq¹K²*åC¥0FW$¬|}œŽ‰yu!Ö0ª#H‰,X)zS‰ºÕY M;ë%i&ŒPŒUTDf<rɸ*˜næ2$ó‚ËÂ";¥ÒŸ˜_%ûNÆ5{¦ æIjÎæa5Ÿt.•[䱚îªò�æAc×™?¸UÂ÷½ÜÝÐÊ ¼¤ƒ?O±Œ¢Xtë<–W‰Jó¨þÑ_üftµlùî|ç$Ïžãtm,yG´#Ý ÅMpÂÅ}tKôÅå–ŸÒ™â)%’êZy¾b#˜ã~˜ó¼ðžàfó^…ÏŽî™ÑRä¡´çŒ=$ÿ€³š¼;ÞÍ_NœåÎÚÀx·a%£9SZözZT”hb KÊSJa`š¬^½mrÏl¤x{œÅ¡Ÿ{J_zѸC/et—QXwqéøhD09uÏóÕÁî£ü¯7ò×~h½¹Ðõ"Ø wÿû~ gå°iÄß0˜¸zt?÷¼¸W»ÓÆŒ›îPnð߸¦ kŸÊ|¥éz­NA•~8¤å·ÏÔt!Õ¬ÿ8i Æ†¡ù�ÍS -пÏ?¥ðÅÒp¥6Àñ[¹’=s®þýÐú»#oó{D2~â¢õÍ@Ö·š\_àknµü˜Q‰ß7=ü§É ?î ò÷!¦·7Ư¥ô�½Åã+ä€ç¸9½Û* €“Fx:¿³ÊüzËpÿfõß[ ú^Q3wÀü¾škÀÁ`Ú‹0•¯G,¢^¡áŸ9͆…‰Nø�°C@h/ æ-}yé’⠻њ8Ÿà¢ßKieÍg û¸Žù,,žB¨Íܹjù»­üO ýBµ—¬Œ´Ö ¿áøµ¤RüΫMN-÷66B â–tºs1mcÚFÓ˜ºiTcÑŠ¼N”E5¬4+¡ZR¦×ð"ÐD™»d—ÌH¤Z”Â)§BÂR<qÁ…’I h$ !�‰3–yŒZ2Åì\qN«í dV¼â¤ÁÃB2W±’óš3 fžÍ+dbÒ×AÆcv®`a/¹Î$|ÑÙ—’¥¸ì«ÀÆ!ò¼XC]½¸æÉ'×…Q{²ûÈ–)Ý$-:eTBÔ,/SÒQ‘ñ‘Ç%äÓ”JŽœe¤TŒ–¥Ö[k×j(bA&*eæQò¿¸<Dk&]Èóø2|õbòó^ÅZ1n2åäÙÃeIFM5¶¦¤&µÎ¿ÔÃ|H‡¸ZõIË¥Û×á+áÖøüÑôé/þ“´^7–YUDºg¼6bÕÑè:¹vÑÇØÌÆËË85á¦é=òfJõ?„TÅ[&gĈÒWƒ?+Í6,–G�êü¸ׇþöÓ!ÌB‰Š7ÐVi%WBYU1¥.mZõKön>d©˜ ”*žÜl—/‡pµ¸ÿ öÅ~–õ'ƒœ”Ú¢ƒ C¼jJMåƒÅ‰–0 R±æWr¥·!¸\\L–O’ÒF0'g–<ºàúœ°Í"^Ì<Qÿüt¬¿äÕDµ;õköÌ›®Iã×c�m…cÏ…êê¿M¸Ð:ÒêÒÑØÿ—¡^)ºù‹ÓKüËW¸¿Ç€lØd.ä~„Øë±\ù5Ïõg— ¥ÞÌééÕ|µG~wH94·`—¿jºûãç8þW÷ùW¿�cuœƒs¡êëiÆÈ±0„ zÞ4L†×£Ìü;Ñ.}² xrWãßc^xÖÀâyд„÷H-ßAþUJéO‘þ¨7ï$’wo|g;ÂþGTù¦×Ï?”wÞ¤à]‡½ðîÀDƒ¯]EÃ×R%ßÏ–Šë; aú¦.û¸ÆÏç6 Çø½Ý¢ÿ üK'¡<jQ©¿búaév”Å~ýåþòÀäúl£­¿+$ý kIߊc2¯Î¾êñ(tÙîÚmÓÕgÃÓ&_ j`Ž… …éD{þ¬¹ òç!7‹q<&f$ïD¨GùºµEIžJ•¨ÖF˜U$5¯‚ .7R4œ4zE…Ç8yRÌ)´¤µ¶•RJ±Œ²PÉ”uÈ`%Še‰¼0V¤(%DÏ(1ÆJ©,‚“ÐZÓÚðÌd®Z›³eUT¬¢È\âFB”äH¤”RNJ£ÊJY Å‘ɇYјlÉ]LV¢N°%NÑ{–Ê,²x£óirÓÃEiË}qÎPñrŽJ5å^ÌÖ»ý^%áW¢ï˜ “%á†ïk!·ñƒî¸6£ .UųâÜ\›&¨­²™sÏEHù˜È/\EWŒÏÞM3cŽDÎÙþó‹ÉßV×j0Z«ŠÍ–²__'ëÜòÅêô¹dÊÝuzÿËC¹ýs(ÕÊQô¢sZÈcW!\Ì"@q§êZÄXŨ® £?½Pr §«þ_æÞ¤Y²ä¼;>»ß!¦7fæ« @Š)vÓ -´’~³2™62c›±ÙÖDÓHL5å«Ì|CLwôÙµx¯ª2³²€¨;–aq=îõ°ø>ÿÎw¾sDŠ´.o;.Š&ºúƵUhðª:«JEˆ %N‰” +Z”ê¦ûøò޾x1›8é¥[ª8‹˜u>p„(+&ƒ'~šûßä=ÏPDŽÅÜ‘éY“¨xÙÎ_þÄÝK¶¨ÈÊæ3Ïš›æN²O7Ìfï$Ý^ÔzµYû IWá”ú5>l!/13Ÿr¸ S¤ý)-+ŒE ãõåK°»!Èn,wÝ|ÝMƒ2I%ÞÞ}VnÖäWZ¥?g²õG#¬Kn/’c6„q—“ד0éßDì¤-øRã‹'@ßa¦¼Û¯ÎÍ}ÃO_¦™í09¨î ÷WÈèŠsíÎh5ÓÍÞ4ãºöû 0Hì<º3à)ºK´/!^¢:†é; Ðþ%¨FuŠéúù›Æ3âMviy3œ£öWÈoCÜ?løüƒñv«íô®x{øcÛ½¶~Ãt²ÂUÂÞ=RKßIaòz¶`ßúíÖ>Ü`!Ñ{p@�æù”Xc½ÇúÛÛh¿7¿r )ôU˜®ûï g�ÃjŸlýÞçA='nVn³À“…€\Ž_ïî2¾Ëi½ÀeÉŸÆöÌôÚ/öTµy!÷ÃÝ~åtš+ÆŸæÌô¡S{"͹­J *Ý(uâ,™ÄÍšå Æ=‘ç”~bË òßUßôU—ò±/{Mÿ¥^Ⱥ=7©ãq%b*… ”°™0PRC°Dàu&ÙÒb!1Ì-aZN(!¡dŸrr1¹B#áœxQ¸’„Qbð™€&BJ”ˆ¼ b ­i\ã‰V)ª5£¦dÎrä@dÖòƒ¦Y ó„i¦.‹B%‰<y!fèè]åOA0¡’¨£j²½ëX¯$’Ãgr\ëeíÌ‘€êfêI”,m¤³Lw0U.eÒêìØç ™ïò‹5;Ñ¥:+ˆv¢ÊAiTÅIásÈSô{¯`‹‰3˜å‘Ö‚).‚lc�¼7b1ž^„…;öw&ÜDÛª–¬Ô9f·ìšúÿZi¬£áUŽôê׉ YœõüÒD³›KÇ æÃÇT|±r¹íæŽl?ÑE™‘<¶‡À‡W|ÿÒ­§!ÄòloÄ‘©L®Ž/0Ép²>å„¿„³1Õ3ý)­šar·v¬eñä_Q gò'”"Љ“ˆ «äTìJø’§d¤eçi?Ï™XKYQŸÁmØ Ê–è9žü­ Osùû†T^©Èç$†jJœL¬èÅB¨Mˆ§,™I2Ú¢Ò >Ž»œA²#ÓX¶9¹šDœ ~™\¢Þ‡9 syô>›NG¾¡ÓÌìN;û“Š­£ù¤ÕEgب}/Ýì§ÝD‚{öÖ¡²?ÙŠàyÆ“º”§ >ö’ŽgY`W¯Êz_1Sû ‚zÕÿ‚ï|¸½æ�Îwh´›þ®Z0¡þ xÁ‚ר$š«¢-8ÇNbô8&H{‹ƒÿ.æŸ5(3jÿ¨ŠÝ?’†–À—?¥Ü<ÌÒ¾•þ˜C} _ãzû{®ú–¹êßÔy/àçÔÞÿñ<Ežèù>òhñ‡ê³†ßó—À¸‚¿LØC¾zø,™ÂÛ»À°\ wð�ïà{É{Tëé:Â�k‰¥‡ÄAÿ'¥f»söŦÀâçÖHþÑÙižYzõb…õ« ¹FYEM¨y•žµaä¯ö\ÿj¸ñlźҭñgg Õè‘ÖtQiŠÆæB –ä8uAòàXš9UIˆ|&ô•'g- ¢1ŸWó²½Väyð{^P·§Fß°pçl:q¶TY¶™ (űŽlÉÐ ’ ETT5DªBR!¹sH$­£”“LX‚ˆ€�çÁ9 ‹Ìa u¤„Q:›j(ÁYg!›¤T&ËHH’% Ðe`Ù«�);‘ÛP”#919s%d;ÉQC²RU…KÞðs±¡dŰn”R•jØîŒŸSºDVÚ'<É}æD¦RÕ•¤%ÖmŸüaŒVL°5 žÛÏíÍÓºªŒ4!¥|p¡$3 m¸Ž>Fgac•½®Š¢í5§¦æš·1 v1ûÑú¼jò”XVÖ½ÐK+[­³«æTšð•¥+N.dûñjQ»—©çêR°ÎÚüEÖ²C³ß||p^È.¦›¥ÞTî¼›ÙSv>Õ‹i·œïÂSQ–gw¨©CìSm6ÃâØÓèˆáçѪñ4²šÄ5Ý`½Q5ƒ)nTîU÷}éÿUÓÿÝÉ>- чe`"ÎÊ}°/\H¤Ót¿*øª¤ýAј7¬W¼©}㦿…ú¦Ü³ªy•×9mÈjŽ3+;—» ®Bå&¶ $“ÜÂCð}¶¾xÊ™FBJÎ!gK¬æY¹lÅ–çtèBÌLÐfY§lÆ)YÈÓõë¹n5=K¬°2Àüs³ ½;KãÿÔX·%ó˾¯EYøÀïmÍfi¸!Ëk{×fDøçÐ{48–Dƒºí]ºñ쇃Ãà ÝNY߉²/ Ž=p†ò¨'X‹i<ü)ü§½bñKl€£CØÃõwÈKþŽÀò®¸ï¿'ÿÈC½~_bøì§x:€ý3¾Hï‘Þ7Ký {ÑïÎE=b½Æ^"{l~¨kýƒuþ} ì žë£ÍE?žàº¼‘«8à¿YnAå7½ç鼎�+`ÿÍ–í¿EÀ¾º‚¿†ñ ¸™þ †t„Çͽ0¹tgÕ+­¬ÄS‰+DeÙrKd%&Îꩉ§ÓšÆzôû)NtwW˜ ¶Ö'¤"¬ÞqÕ³´ñ´±2#ÛDSä!Quæ¼ØäwDLb) ªË¦&¦m eã¸Oã­@Íp­>):Í*3BËL#I1`ä%¦è ’ B S1I˜�£9…`óP¼K4åBê"•T¦ÖLiÂRFd `†Ó@’#%pBÀPRq$.¹¨œ™‚””æBr$ÎR&¸·9#KJÆ$Ù±bV$’sëcN<ƒÃR“2ÕÑ«8J]¡DQbr±%¥B\ó¸Îjbæ,±B«Ì¸QÌ¡Zª\A]yF‰K*I$=h¯¥j‹)s<—„ ØÂNˆ:çÒH’c™ÃRd1E’t•<9ìŽöøù!.ꆑº]ÔSX¶LæÂCBr ŒSFÀÊè,݈˜g›çäýºÐŸk5ø°¢d•¤22?Å$,¿¨eEÅn})õ}aU?âeœ89ôõOeÝVº]Ø”S‰‚šú3ñÓ™Nþã}T:ñ}~6-Ù¨U4¿ß0ÔØˆõât±`µ¹kÏnr#û(pðåfQnè÷öÿ³°ºc'Œ5ÈBº;‰]¦]_ž½ê„žãÈ$!r3³-鑹ˆ.‰‰sñ$+*¸¥@KÏU],¨ÖYžfá}êЫ uÙ0>:Q¦28Ç’“UÙR‘#]NŒâkžLž|Êv=ñÇ0ØÈUdf’Ær¯góãÈoG!GžZZbòæØ®FqU‡jaiÙumûM±e(vŒ%êÊμ̦A×\œ–n¾Ý+À@¿ÿÅ4xD\˜÷@½— ¶Ÿgø ÆBYéFÏ'+`y@þ dQÍwìÒ$øW˜fL±÷ßGÝ¥ü1hOxíp| (`û¶tBQÈ@÷ ©t½„?þ)€þ§K ?‹ôiDö;ÊÞ•N~ 1<øöpÀ~ûI,ðMn¨&¸ÄÓt PÀWà“­3s ¸GCRí1ù‚k÷ÍÆ×Ô˜ÚJúéÔຂŸé�¸^¾òÓk¿Í7îu_ ;>×ûóɈðazé#ÛÔ⃠èÖûðlAëX®þMÊàeU>Û×™s7ùMæaù· š’r ô+å@Õ‚q8’`b«2"‰’%—Ž|òqµ¡š*ך¬XEyê%'¬åâ’ñKJT¤Á“ÏC]©yBB›&žUíSH”63³šMmb!F=ÃÇ2fn )šÖ\+^+QKB(¥éa̰€$¨s’T(ã ²¨…)F3œ3%¢‹™dE]Ž’83I:G:³‰²)—P ‘cŠ‘%¸$5(a¤TÅ ›*'>3OI4…”kÑ1+Òo@)çëÀµÎË@…IÁIÅ©Ü ì3K1#„<gÊ\U'ad-")®L1ÜOÔÛ±¶^é*¸åÁ‹ý‘Žs™Ýçý¸8#Éå…ÁÑb=$nLnèdìœC±vˆz‘„X6™£=Ú8…Þå}òGNò ŸÏîG RG¹aÛ…j—µEQ‹À–|rKOâäP±mXÌJiZ`½ØC»ÜÌ“.mœJ¸Ý/®õ߉aõ³;ý¬9§Ñ, × µVr«öÕL_M{ [´¿þHm¥ýZçg‘þ‹0‹F.—ú¯?1~Òs‡áןFÈv©KºOd<™ë…=êy›—÷–]Zöµñ·•=_&K69KiÒô´²b:dGÊN…|ª–˲ Ù¥9 ŒzÒ±Ÿsƒ‘{$%T*%H­=ã6")“½‹6–Ýû$B¶(ÏÎÂQ©E¶ù.’ƒ½%&.JÒs‚J“œECjeV¡U#¢ðëº{5,Îڇ݇ۧƒß”öºCŸ= ˆ¢(rUïŸ`Oð›,¿ò·£];¾†¼< @Ö`K´'˜6w¯±K%ÂÏ ø¨ÂïUßåÿaD]Þ¾CSî—ÐÀK÷ˆÍÀw"àçO•~8M¯É‰LXió`Åê!\yì;ì‘ðFs¢x”ßF|·þ÷ZöûÇƇ¯ïhz;-!~FNqû ƒã€ûoü1ކ±tBöõ ûÍ-~Îpq~ ù™hNÕÒV nO̽ŽGHß=¥y^Šã 9.Ò§­oB¥ÿ„›…JZaeÊY%}£b|Y²qLY–…Öb£%K²$NÞ"ÕfØUq«ÅK&rÀÓP§BJžJ¶¢S¾%48ò§?f°p‚ÁŽb¯EUj(UT &!]²¶f"’Æ“µæ•–BМcÉ…{ŸU $gOSOÓL] Єԅ(`"<“MA$k™ £ ²dD]¬aJDt6e&d‰d„RJ½ZÌ*Ì4F6.(¡d6°»ð€úʯ***žXMâZÆÖiÉÀ Cf¼*ÄP‰ª¶Ä؉12æämBŸ¼%•Mù(…Ãt?ΡSzN…0f’´Â°´‰™DÖíyæÉÊãF%ŒøV áWl)T`i?©»¦Zj*iƒãá0Ä9k2ÉV\NDí²öû¡ê½X™ÒP¶øGFΠ׹½“F'ÙçA¬VgxzVñ¬¾Žyšü4#Ü!ÜÇy7—äÓ*½d.]vGÆ~c6Sl^k‰Ÿ¸sÚñ³Â@˱ɘ-òä·/·wÿeùô³ó˜) ÿ°ò/¸ø‚è§›:›v5’]Æý¼Ÿÿ~´kσස¨¶Äß7øŒxåf׫¿M™H Tföã.nxò6ÜèL5ÉÄ<¡ÄPB@Üì'P~–H;ÍÊÚ¹Š1“8’=õ´ à&DÅEP(Rö‰:í:Z'ïý4Ã5elÀ µ±„–ÄDƒËLj:·&™|]Žƒœõº0’:_!»QtÄ/oE_UŸTÞû˜Û3iZõËÞfgEúÑÊ_Ù¼ìØç6¾ <á¨á ¼ÆÁ£Š{ƒ}$ð%#V#T…æ/¡6˜-Ò„© (àß�Î ~|®ñlfÀâðûCê P€ÝwGÛòÿTú&¢.«ûÇhù½5Ý/_œ(oö+ÞÛ†ùψ)½ÇÔÛRÚ@�=àá\Þô}ÅõÎ’w-þ3w}òƒrÌ+ÏÒ@q(߬S­Ñ\‚2°„ñ·ËéƦ;¹®ÄA½‚ÂÓ-êxFeóW—&‡›ãüá¶t;éŸÈ^WÏûÌR”?®ÒG¢¯4 p¥;{Ê.xUÙZ¨’ËêÉ:2i©NÆ'r ±"ÊI•+¤¸Ñ¥ÒÍsv!~IJ¶éo걦\AfÂm‰Ñ2JˆëÄãÑïÃ,¹÷gÕ-#g•i+VCåÀ玃=ìr˜…$BT5[hf%HÙëâ”4P8#2•Ó7PG¨ÔŒ –Dˆ´0FÁÁX¦$2¨<¦’x¦³×U©–™ÇÅr®,i !4Î1쫨缤’O+Ïu$ãYð"©Ôç+ÖÐ{¥É‹¸I�� �IDAT9v¾Á¬tT™}Z%OŽ™;)­4ª—R5DY±ŠÆp8BæypðsB™é8ÉÁˆ*’0æ¢AH)LÑÒ­ŸRòÉíÍ‘¤( KT@™™ªi¥ø’’ £¦—ºˆ="'šQÀFöÎïC?ç†E®æ Ý± þÀZFOÓ¢OË¿KíåM]u·}¤>ašˆêU0U! .jì®ø-eO—ò£Müé~ž'oo"[¨:l2©¦U¼\ú³S#âØå_¹ùë8ŸÖ»!¹/òfó9•­üÉPI>`üw]gëÿž•ËÞáèÈfÇ—Ç"[ !Ÿâ÷'¢|%ùuqUİþƒªDõJÒ|¸§'¾/öq•\sÖDÑ0Ú&i=SŒÉÌ>$­ØéÁk2:ëIA"‘š`í2÷¬ŸÈÈâRäÅ!冺%b4‡–É:—B:Õ‹~—'g)zÍr~9!‰Ï?d*1iû_W¯6.ŠýEÃÖ"¨/Îcó¹ì¡0³ŠQu¶;¼…L/„ß¿˜àp- È›¬¥“I/zt=ú p‚1È_ßùÓ„$S2—Õ'¨ÿ~8#þúñÉc@¦¯BÇ=¾&`3Òç¿_[�í;¿ßº÷¬ç"¿_²ú›Äpõv—;ùßIæüe.újwøß=‹±Ãëƒ kàãG‘5p÷ý«¾4£NîßÞñðÃØÅý·(äÍè3¬û›GXoR03âaBÏØT¸j*4õÁg¼¸½ŒˆX¾Ày¸ŠdÙúôëžK›Fÿµúà¿é0Ÿìj{·¼ðTaÀÎ ¹¢guµ¯7¤.Õ‚W‚,f6û´£|Èúiª–¡”L¼¤®ÂÀÂlœãž]œªMIÔû˜'?Û"›âÌÛÝDŸ½ìŒ¨7¡jmáG—kÿáfz¶ÆÅyÍV5a^Ú9)Ló8Ρ¶¢©É½‰¤øEœlŽÔy?Â3Šš+ABNaò㘀H*{æSqs¦„Áˆ<SYr2¥‚Ç29›²r)I:…‰™2¸ Éõ$ôDM2§ì8aŽq¢©jI,Šé¦®¤1ë¶½"Œ2CHIwѽÚ}îSÚ[‚2BòÊP1íè1ì¦á’)¦í9-LqÑTRj%/ɧâóÄâ)JNÚ™jÆ÷9û—b£½û—–Úé> ³Ìµ±Õr¹ÒuC%ãÅ“<Db²,Întq‹¥ŽáHp²u¤Šu|X„Ú ‹Õi'SŠÙ-_u\zå¾Ôž—£Ér‹cÇbÈœÚb:á»…ÊGÉÜ©sô×2êÜîùºÙÐåšœ®è†ëEÝ8FnéÈ"Éf»4‡Ë«“B¢¥#Î{¾K5ÄÏÓ$]ŽÕ+Rê*^EC^Iq+ã”?¥Û`ùÉÜŠY‰FS¿R³‘sYœï™ä…E5Õ Ã%„ñ©*š gà‰ªDWcœãñÆR™4KéEÚº8•˜¡Œè±ø¾ô‚–bÖ¥´UjKñ"ÄGç=ί|×Ü×WC$þc UÆ.ZaÌð­mYˆ º5ŸÎNÑ…á–„§¢p^2•Õ}ì¾>û—ô�ü3v@‘åÂk &”ÍXb¢K²_HKžþÕ°$è>ƒÛÞa¡ÁØHì%`$p5>Æ®_·F ï:{ý [пüWð=r|<Ô~üMHüâ½æÃ°Ûë`û£Eñk§^¤÷Œ´ß…Á÷/$þL¹áýÚæâFïÌŸ{�Ës¬û¥wü‘AöZ³úA„õœ`]L¾·q?Äy:Ì« ,ÍD¶ÇoYÄ®9`¶×Žb'Ö±]�g/P=-aeåÕ@+/L5ΙQs8*÷õ'4ü¢›ûc=¯&½Ø•ö,ž,x¨L¤*—ÄIÌ9®(=º%æeÉÔ>o]v¾ªP‰ t¾[ôUêÇβ=ÒR&’ކ fMžs\(ÂT®À(ƒ')n&¾$‘:{~IÄ)ã ٥й4ÄivÁ§œâ‰Ñ#ÌIJ0+Éìí<+œ+Æ<¥)Y;SïS¥Üc6ó8qͧ²’Fš ™8AìPœ ÉŽÉç¸+ ‚­9“4rš+9ð•’4SZ`# Ö ¦s{¡V~.ÀN� h â|À9Òm¿ÛÑGNš³Íú,±úmõåðå«ãKFB2¹¯ˆ«Š®H%8•"Ræb?ÉHXáÞê\²\e&iæLsšI˜…ÈŒäÀ›Êùup’&YÝô²Š‹j³Vª% ygÝ|?rž«r ƒš ñŠL1Nñ‡ZR^C°ª ùŒ.«®4êùÖîÊj¬â‡ÒÝÕãÍi‰kÎS°Ï÷óo§“¡„ŸÈ^6ÃI! Û ²Œžß.ô%ó•œ__Äê9=ÅZJ²›'ÜßLûWîìMËåž§‚-|Ñ‘J+"g~’Ò½œ§>ŒÓ]•)™~²)s̵Ão­’Ý®¸ ¿øÑÐ<b¨éZn2Óõ\x¸e¼qÕµª¬=_¥s>Š]×+o&!mö`*Qøù1uÌŽaô ªŠè v)v“à‘­¶Aä`ïÝ­1'©4,žæ² 4¥ûºõpøÑá¸zÞ²Cë>ËEhÙ=b¢¦ñj^? ŸQý[ã×»òómX—û 1P››Št…- ‰ë6�Fd LÐðé·B"’¿ò–ćñƒðÉž—¸—ËBø%üö�c°©F—æQ]£ýV!õ]'ýù]CÅô5‰ @�5 q|ù8 ­~gÔþ^À\Ç7sCzsBâÑ–Ò¿_bøcè³>ÍŒ÷¸ Þšàø±/ØHÑûö’`ú6‹ijY&¼YâÀàoçüÇOC~xÃLôõÛ8Hø„ã—ˆ´�fF÷¢ô‰N¥:ÌNdÌ™ò ×Ã_Ó~ºˆ¯ôR–¤Ï|u!Ô¹ŠÑïöyÕk°<WYR¶äªµ#q—Å@¾”Òz±ÉeŒ‘<ˆ‹e™‹¡BQ„Ï“r7Ëä•hB‰½™ŸCvŒ¬4–K4«ðªsܹÒõe<ŽSrÞÍÇ™ RSß0?›==òÌcò¹‹žVJ´|–EœÃà|byBBfš‹Ɉ*W• ­JEÚKÅF>òyÇcCK#On<”TJT%3&<ôÌ)Å"£Í!ZÇvšF.‰ªi-?kÀÔ7ÿ;õø¿8 L¤31¥LƼZ<9=}F]Ç’èäíä­íű‡ SB¬3S…ژ˜ÅLõ)S‡\Ñ$cÒÊ@ÔYhZN}åãbd­ÕL-¹’mâü¨³S9Ð&;]ûã0ØÁ…©ô®?ž´LÕ½²z¨ñIi𦉱0­'zEóÔªxC\H±»ý´ûz5Ï*šýLöf+wö°ê—‘Ms¾Ò†µ÷ÖtF«ªVm}^ËYsµnâ~ÎÝ4²iïØ×¿Ü¢\Ô5[6е¼ üb˜Â@X[ö'$K{ÙKÉäʘkÅIÌÇ€OÈÈò®0ßç¿v™ñ$¤bB/ê DN¤,‹ÈBô1íîNÓSÉ€º‰XôõÆËûÛrëÊZ&E§‚½½š¢é¶N‡‰´ùVäùH7‘rê…c뙇‰† ã»,ÔùÓ .Ï!WÛºq‡‹ûh»>ômx2O+ÓÌi52g ñÉõÎ8GÏ ùåžÜ.ÄNqud«\­ ®h4ãÑûù‹hH=³þ8>üIóŠàªÆ5K‡q†ó’X…ä0ß0òa–›äU!Â(^¡Ïþî3¬#8:GP^a™Ç °†wîÉá{3³¸xéÀÀ¾„Þ·ßË4Ë+¨kôoÖ½-ñýØ8í“÷âG}ÇÿrÃ{¼n¾¯Ùýøü‘žôÝÎ?|ðöá ¿þŽeü½í£ß©Ú¾•¢}¡_¯L„DxÜñéñÇ=kÔFÿVÙèê¡öȰ«çW‹€ÑÖaví|«(qëÄec ÓYgÓ)TuÑb4'ñ”7U—,ž‰ržµö¸#]§û¨è!†)Ý–ðT ¦hEeãòn¤/÷m>úÌK›gÈ‹hIÕ1ñ”¬0#ÌÜ+Gz¹tBØÒË’+¹" ¬ž÷ùÞïÙat‡m°£#Yd›"sc\ºwƒ ºŠÜãG AJÉãHL•˜Ê”RJ]¬ôEÊ$“º(Í™Vžjé(w&¤ÌsÌ”ãC™Ov˜ÉTE‘¨…RŠJÙÐÂcÌ¥TNê–Um¥êü¡´@øF9u…UiÇ©DW×áQR—óÅRŸ´ÍìR™=É=1ÒDž#|W\_\§æ"¦”l݇–™ªbÐ•ÐÆmš:e x×¹YN«¢Íªµª=*]Ã\b²saÎSÛé8ö“cóÉVîb˜Š ù³ÓéEå¶x¢ë…R}É®²4H"EU$pŸÅ¶ÔY¶KoMœ Áu¡í_çÅ}›û•qÔØ²\dÏû£d'’¬ëå=y*ÛÓZÇq¿›ow±OôÕqNZâ6¥xf›f|Bž¹ªŸ*<K+Œ¬œ—ÌÔ¼¢¡3ž’0“£8ÙÒ«ÞÔ×µé!?мšC“äJ|~¹¥ÔÕ”4'\hÑö¬J/žø]cXT½rl •F¨šäb$oKˆbrl=e.ó"D‚)q½¯eºhÍzy²–5!ŠZø”1¿’âkWaæÙ»çšüg¶Ñ™ýÃ(nž‡S—ÓÉ)Š˜*è)=½Ó«{D˜Ýh%S÷:ügz˜ý=„´÷ ˜Z±¿Z§«ÅÙ”»óƒÿÅ�ý‘;œÅC^³ØtÁõX’5a>A%±ö~‹Î0L�l€�8àå; i€ñ-xãÁ àÛ7j‰Ñ»·CÐþQ›_¿a ÷¾!~ ,Z¾y‡�ÕÛq_þ¯„÷*þsû¾ùß…å,8â›åT~ÿb¥¾ÆÒ㳇kÞüÊ�ÜA>NÆ=ìÎÆãæ±9Q©{`Äø €kàðÐC*@™½C=ðÛÅÚK¶ŽéÓ;} ß]Ô/½Ø÷u³9Vmíx0}fì–]ޯϼu›³X3«³ÇHœhR̓fÈaاtKØ×Èý!|BTS©ârºÏþj²yÛ-o·c<M¯«Š‡ìÑÌež‰aºšmg£šÙ騈¡óY+² …ïì̶x›§™¢ÓŠÅRÒ ý< FpÌVqá?"WtbÞ¯¢§,…X+¦‹”%ËZ’ŠL8")…£xÊ�Îuá$ÏÌF6F5ÁyN+ÒcÁÇ�¢`’B‘e*ŒãFñJNïq,¹$Ï$ ¢ÄRü¬‡|‰æ’X…æL0âÝõ@;SmJê\bÑÎÎÅœ#-‡¢f‚´ˆb)8o*oP$o—‹e{šsLvÞêW!V•Pë¶ ªrÌdÏ;ïsVÖ²©¯:«÷>6n³Ú„$éù}ŒwQ¯ªåÙêtÝhÆaû dôŽØàRèÆÜ÷Ó„ì¸Ææ2ðaèuù%à²8}a|U! 8D—î|úÙîÐ�†ª5ç m¸Û˜$“ 'ìÕ®™:Ñe^§òâÀ“>,ìð¢"õ¤žsÜQáØ4¬žL7Êy2 ewL¥Ô¬ŽJ9AÃÊðu%º8 I 3â4 >B»Ì¹ó^q?ŠOi¼ñ‚:Exé™ ÓDQ7A Dhå…É5u¥Ûß³¸GgƒÑ[T|:'ûýìR·§f)…(T&XfîbüM!µ¯B­¦…žmõGuŽ)Dûe7¢ofq³à¶åc,Ÿ_-�ͪºÌT‰AÞ*w1pǾ¤W m@YI(ãu•@O¯ Çð Ç^‘cÉ¿˜ä'{¶ž7B´{ÎîgùÎ>)¾Óˆ@ÌÀçñõɵ{À½¦ùö­˜Bõ@†|íÏ� „7=Æ÷Æp¶þc¾Quý®«ŠŒßù¦=fŽïîaõ.%Óüß­nø:Ô~ ô_¼çõå?ú6°óû^ÙCçÀ«wÁSó›of`÷Ø^|Ͼû Ä£½F{xœ†™šT8Bí¡ýK 2Ù" Ž«=©‰pMí?Ž'gu#–˃ycX ËÆssu²éJ ÓÞ†\]æA0›Ù @$ Û6Œ4JB$ë“HÄÁßÏÓÆmý×éëúþÿLÓºØÿ…Õ+i]”’¤®LfΖe2Ìóýš¸uy^“SæaIî{ X¾Ñá¾ååi"&Ž ÁæP¤š=¯iŽbÎŽmK^ðYƒV"£†Z’XCÕÔ+ “œrÏJŽÉOAq2V†ä,M‘'ÍSô9ZL‰vsÅÆH-)”¢]Ìq;g®„Ï4ž=QQVL6к°*&>;Ça?uã<óDI)'0(‰£·ýtŒ sr'¡6uqóØß&dÝ*V†||ζ¿Bø±ˆ…Ïó4—jtK¢Hä;iFƒ¤ ¦¹åŒ Îh­YH RçJ¹È¢<agÂ,GŠNZ'£6Ú.–#ˆ#- Ró´Z¹jlf÷—ž%KÏgÑ ¨|ô"°èS¶s7ÈÕaŸG§ûÅ17ФÄã¼3þPsf^¬î^M©êÀo.Ô‹-© >ͦj—FÖ*imsˆnäQ¥É©”ÎO› ‘ªW^oýW¹{fŽ ’>4OW™YÇ|Gæv½¯}Y&EJ“ã¹.Ó)JjÙîh*ð ÄÕŸò…¦œ–tóvž&î•‹`’V˜‡\ªü9SI=—ÉrE## Q”¢õT­ªLTÚ²û¡/î^0Žö<VŽIµ™ãFÌk2­å©ÊEÚ2‡=àCÝ… ê\|­Ÿ(inèSÚŸo3ï§çóW/ËÍ-[óõ [¡ÃÙó_œÓC=s;ú•cš¿®j¬ÖÇv³GЃ<¶W]på`.q€œtE¶ä™-¢Båî8C©ó®ö"$Ÿ¦¢g|ý7Y ìÞ>Ô‡ïÎéÈß äE@Ú#_£÷QùáôÝ8�Ù¿µÿÿëæš‡Âá™ãÝ×é¿[nxãÖ˜¯Ê„oHD¿· ‘À¾˜ž¿½ê÷'¤­‡ÿV†ïðv@ `Ü[Ûš€$Ö~5‚½¥tx @áÚ=­²‡-Œ]Ã(/Q0ñpÈT¥ê©mÎ÷̇v_eA~så þçPž„r¢kïÃðÂÏË̹•ó÷¼ãÑÝŠ¯.SЇ3Ÿvâ«Oc˜ûéøÛí~¸“ñ3üû倿Ú/—ÿO-¢’ç%/d9i"AF¤¤üÊܯI¿H.ÇÎÇCJMñ%É¢ ;ìf¶‹¹V³žÇ’i!54›MÎe˜¦0GvTùƒJV•æ§ŠÖ”¶1ë„D •4YÈ�§À"J‰Ù!8¸Rú‹,IØZ$QkÉIG)½ ž§¶ Š¥~ïeË•ñ\¢ˆªô¢ÖUVϳ?Ãí0=O>„L¼'ÅÙüdYœ³Ì3L¯òvù¢jÃI.^(É©ö¨Ž;>¥T9Rl¤ýXèAh^r­½63OKVĬC¢°CrÙú8“z¢©ºWN(±4:á(Jâ,%¨ÔŒDEªk%µsš‹‡£•/O"³±¨Î’)û'>ía1Ç\¢ –ú}UT©™Ti"‰>'§¹¯þº4Óys Ë›K<ÕU»ð_s]øôåêð$ž^n>æü‚Ò/šO2íÊþ¹K6­ëëÀ¨˜HÉ´ð@5Äp>÷†ß2Ö¤nˆ\Ss9%Ã2[ʲÎã"説3©"±{DÓ4¥Ow»¸uä—r\XO’2d%uë%'Î[гr”d7S“´€OC‡ÄbÓ;ã“¡ndÇÐïó~{6ûç䜣Še±Zù°â›¶(–e* åI<“-Å®-Z—ÊÆ,lU‡T²£ >}Ê{ÈW{ó¼‡(§O7„|ØUk­›Ä¹'Põ™ —Õtvwwê—%ÍçôZ*œÊ}W!s‹äå§°EÉÆ\éËŽl„¨dšj¹Ûëßö~gËúÀLÝ.¬H«MX®ËîqÜ¢¬ÑZÀ<‰Éc~8^¿‰p xPÔù5Ç� À�/ÿ {Kù»yüåý»¹ãgŽ „|÷ŸSúîVN±gÓ5^|âåïÊ Ão ÀòÁÍíõÏÞÐ3y³Réß@Ù¦zwßxs¿¶ÈÇæˆkx@rø“Gï¤Ã%À—òmßcF Ü߃xÌ�Ã"A|ðO[!QÖ¾×ä¶¥Ó¨ } sW X/²Z¿«Ä¿‚üC:ØiÇ~ÅÇ]u{¶u¦ûɦìGõJvÌ$› sî;?lõWŸAOþ@%äã÷JüNÿÃÄÿc.L§LÙæ´’R¨ÊCýzîûÎþÊ––f´™é7VF_ŠŒ;27Å’.Rk‡Ó¬¥uÙ²àÚFh®ŒXªeÖŒ(0NˆIƈ*35º€ò1äBLÈÄr>åâc¡žÒ"K ‚(êJ„‹ÊºPÉs ¢ÈÅÊ7')dUU•© 8õÄÙç©;Œ;?쉿­rR›ý4o‡4û¨"% nGã‹#šåb…S)´Y²VyT-SýŒK’ ;Š}½ˆ²§¢g‚*žŸ(ºÈjíôòPØÐuÎu6uª"îïà‚ÍýB B( •,&f—Ž3¨©=å£óû)áX²%Dù¥ ñ03³E*ú¤„D曊+jN;a¤ÊPÕVkvIYZ©LÎ Ûœhvi[™î®ÛÚt!þ«”ÿ«)Ua+[Rn9xïÇJ G)?5Òꥑ«}iJ'ä‘qz‡j§µnF=3“æœU$I†òäJ´}¢$.14Oæé4c©¥Óq<úØ‹ýŒûЦcB¤^Ñ"h’šÐÀÚÒ0ºm3$>‹´e·C:Êr£9QíXºãÜ7¡~"N~>6¶×K•rí•"ꓨM¤§ÅœE ¼Œ¤È@íœxOØJRèµÿ·âDí,ñwywí>¾¼¬øš¶/èä8©1âESo…ÿ±½[Ñ™ñë;÷…|p‹1àVÈÒ{Äá)ß.”¼S›ÝúèT™KCŸg¼ò£ß;`+öYÅÛº™5%G)Ž&'·EüIBùÇÀ°�Äv AÁ¯áü^�£D\xþ:2sûM9ËïÇ«w½ÞF~Z@½Ù„.2ÐCUú“çùÎa´;`/Øk”Óñ½À¨oEÏßNzwï_j ‰ì‘ÞÚè×Y§¦%pÅÎö<ï›-†‡¾u‹%Ç'DHäOAÖ{ì[ùñÂúâóêæ«z}£ŸaÐzd)_îóx÷¢é;²|¿Àã%©æcžYéûº¿w#ö–~I6ç—{»€,YÓÊYÿ<‡.¸›>W#šÀ>ù(‰ª¬VòÐ|ô™ür…,!£Ë=#¿nجü2ÝÌ©¶¡tópð.2  MW‰mf´š …§Ò Œ¯ˆ` 5u\;%\äZ‹Z6õjcšŠ€çÁ «„PJ)ªÓ´È*qZŠËqˆIúB£‰Âi$¡E°Ì¨#(ÄrD  bÑÌmxKˆVÊ0ÁcˆÖYe'–•¦qçívžÀ-ÉOÖâÞ—B\±µB{–†[?fª“É­V³ÄìVÙìIqœu”& E:“2~„tž‚!:Vq¡’–GΆ‚ïe8j^4/”z?§<W¼áF ¯y1‰f¤fž\ÞFÉu±ĦÉe]Èz˜4z¢D^˜ØÏ¨<—µšgnBçHòÁþ¿Ì½Y“\Wz-¶ö¼Ï”c`Ù­¦déÞ¶e‡å°#¾¿Ú¶ÃáÛO×òµº¯$ª9€@5fžÌ<Óž· E�$Èf·Æó„ªÈ<‰Ú™ù­oXßZe…?×¢JéÎÓÍ©¼_`®ÙQ?Å ¯Øúó°Ê]›¾¹¥JýY,M­-¡–XÁøSÉá‹ í—BËRGrÚ†ørÒéUw,1NÖÅLTtqÉ„h(›hœ¢!pcé½g˜ñOÓšé²óÁºt#ãyÖ¼Yåb¡!êò#& 0zú;*ñ÷¦,gy(-‹Ð«þº‰¯9ö4y2M- WUQ¨EAQ¡QI vÔQMŠºZTJk=ý,GmŒÁfšÒ**aG[*·–E&K·Òdè¬hð…(œ“ß “<ð-økLØl–©k%°‹2zºE8B¿ ¬:4I:¾Yê6¬–“hw;ô;¹hË6H]Î] 8¼û–¸ÿXF¢¾�{Ì)X¢K8nQ;,Þ[³z·!Á~(_‘~>ƒÿŸ5þ§‚Ê¥‚NlxDúB_=üŸ?·˜r?m–ý“7y·R€{!±ºÀáò-El ÔÐw-ÆKóyÀa‘ì|nS;l�à[àÏ-š€?W¸«q;:ÀÂט"I([Yá‚N—¶iâì‚/ŸD)·’íŸ&;#é@rYýId¹pJ¥:í]^û"R.ûD‡[­¯§xÿZÎÙü,ëbò‰mÿ[K@#L|F·¬Í§*‰Æ|\5Ÿˆù‚W;®E|šC°®íÈ ‚ÿÈÌDí(õ%iئ[•³Ö uJÎfFj€*f}á)õËfQ•¼LBE§„cK-ÅbQÏÊBëà’g œAÖ•Ò%$`œ;ÊDàÑfXH@‰¦¤‘©PDë U Ž%>'ÊÂd€NŠ‘$´T´šI5#¤æ„Jd‚Ì®d£È`oû®ý×Êì…×MއFÿÂM šÏ³áûdç¢÷éÞmΆ²j³YÅ8±H-£¶âžrtœSÁÂQ&…‹Öfç³c,¥”aü‰a¹ ¡®ƒIð…)úm‚Ô�� �IDATDTYH‹€°‡™¢1ßÚþ&Ð%1UÙz± ¢FSÏCß§¥Q©€9 ¹Û±ZhYh"¹éJs“vJºžF%IU•È_t<Ú…*({Ît0a~8.iI\Ùâïw™Ñ&4v< {–'îE‹ )Ý45R(‘èžíÒ!ÒÛ¸¼ïÜÑ®öýæÜÖòµ\¶qökQ–¤iò`5ÍUr,3;øNh“²P6j:Næê\Õež{­mC©'§|“P‡äÃ8æ+í–²¤È!„¼õ-/ñóvÔåžÐÈ-¨ÔÌó©Ÿb^:²•òö£SýdÅg¡!XÃ![—ûa¼éúývÙ›LœÎ2zºÙëª|j¦ÛÖ~¡ÂLµŽ}1&Gzò×·ù:l^Ãã³ Ëîî‡/Jæ½<,  ®ÙÕ}0•ø´ké Ñ´»Œa/ý7¿ `@\c¨=â%Æÿ=OL8‰PBµÐ%™!ÜîPéðÐLÎ?Å— ƒ_~È î½.vü£ÂîÛÖS¤.ý¾¥‚©ò.tŠñ™áêùO×8?âòzX`þ°�Vÿ€êÞáæý÷ Áš£ Èx~óò�WJí¬TpæaýÊ=[¾‚Y?'oÎi‹ €2Ã8Ë-Ü­T¯‹úˆºóV(D¬kõ”ýj¦LòcèÇÑÊMïwåçòeè3=—󪣯g Ë|#åQŒÿQp”ösÑûøÜܶò®%ê×Ó±òX¬Å ç¹? !E˜Ämà_“wCa^ÿgø“T¦!}9¨ÖŸf"&·"JKJuØs¿³Âxö-erhÇû¾9È"ò†ë&Ë*Ê"0–Pç0—BWš$"¼>çYöEÍ$ûŒÀctžÊÀAy) ‘”ÄJ® \ ¹!4¦*ÐHŠ™*‚¹a@€Ï)%’‚7Ñ\nIîs"­S_‰\ùX#œÈ¸,±ö• ÷ƒ_zQk–_&"í?ô&q– ²æ:01-3Ï0!‰‚è²äT–!æýM ‹i*„•Ƥ³ Ž1§–TqJÉÖgéîw-“¦Ø]m¦þuôj °\]bÜ'®ç¡‘1OýážÃÛÛ¾vݼÀ¥ …êm6 ¤Ð”ÓÜ ˜í ¨#« /…RzpËÛs:ü"pÊóÎhU}¤ä,ìzë݈©è’šK®X–*šYîTH½¢D|Άê“}ÿÙÍN¿šÊßœ”'8>†’9Ðbà1kR«E-×,óJ»‚Êó€T ÍJq„|+=‰;ÎÍ‚E–DÐ(¯ÀDxšÐFOdˆEÖ!“¾Ç¦ëíC±NìhÌõÈs¡§eYÊùÐ&&c™d½]4vјýd·¿Ûߎf7íâÕ¾ŽíŠl‹1>Ì$ü¹|ʼn˜—²ü†çRÓjA«‚ {¨äÔ¾®6Ð’bUV\å!~á®1_ºq&Cu¡€%’ÞwÜô€x#ÐîèWH­éct3Ò…^B�ˆáHeÊ'ç_©Ú)æà€éý)ç `ßñžüñîöçÍéÑé÷£Vøa¤¦?kt‘ß]ÊK?!êR}?:—þG`Ç—¯ßýƒW@ýAèwÅðÚ÷ãê­šî.óîk½ƒŠâ9Øû†M§ö €¥¦½µμ9çå.0mö7E ¤‡dcœzØn,pÅÄýqOOÓa&òzQ~T-ì8p²ˆãmØnoÓí¦«¾ýO|õ'™ŸæLûž¤ûã9žy¤+³¢á« à�®Ž”_ð4î³1®U¹*Ov¹ß×îâ`TçÂ(_Bþ¦Ô]þÒÙÞV'iâšḙ̀øZJˆ~Фp©HÈ¡‹ BÏ$b²Ð>¨žTw¹–Åì¤.¢#rN©æD—PE $‚ —ÈèÓ®Ÿã³#T÷`97¹‹@sJÙf¢)G¸ÒBiŽÈH$.TQð\Tu!È!<¢§.±ß²öj>m×~¬&yI0X“iɇ"£²$±¼®†‰ÑƒÁ¾žNøŽ*…¥I…â„Ë’!¡‰DØÌýQ®¦b¢ÉDFB§±K/,”t±²‰Q¦8&A‰ì†»®Û»úîÕ8ÞqÈ®Ãн4#Ö>îÆC`Ò£¬_,pîÆÂ2nD'¢·<êfÑn#ÓrUW<êâ㽑tÃ>‰6‰äÊh9ͳF~TŸ÷¥3 BUÕñ²i˜BºÚ‹}ŠŒÆ´—Ñ.†ƒÉëhÔ."¶™øt*¼_ áhKs_ËËÏæ•­uÇÕ ˆPôH•ÍiÉ–$ JóÌ9æde›ZŠL& Éc ˆ¾ e}‚KVÅ5i¦4uÑqW³‚Õ‰ Eظ;…¼=®ÙšÅ,™S!1^Ø(…žUüLˆˆFØ)Ü¡ìÞf?ôÛûéúÖ½¯vþÿ›ŠþsF~9ÖÅí8ͯm ØÍN^æGÅöu}ë+L®3æÅì¿êA*9ŸÀ*)£ËÃÝÝFÞŒÏ�W~)‹švIÀ{ÈãÓ„Õ5þJª¸Ú<J@;d‡Ü~É¡€!´_  r-ؼbø Ÿ6ä›5wlðNÌ9 €r y£ï ìLޝ>PûÁÑéFê‡}ºé‡þn?ÁÒü=bþ…zJÃïÅIô?®Áç íœv:?ºêÚ= t;à7#?yQà 8¼1lòÀíNmIð)Ap÷NZÐîq™2¦gxã>1� 8·ë*á,ùßL"îílØÔuþä‚=9Qs®•-FƒÁmì!ßµzLÅítm”U~XlÿN„i Ë-ùÌëU%†ÆiãbN¬O¨"ÖaQ§å‚¨åò´KñžV%²´ŸÍ‡'§$ñK×}#·Jmfx"x•ù'Ý\&UzÚÃ’ÎËÝý±2L–#ÓÌ%žÂl$–E§õbµžiž„¹Šð‘Y!POJy¬•O¦œ©DI™$ÛLà] ýnhw»ÞNY½Î $ë’’*â’ñ“Ë‘Fžl満*W,ج LK1“ �v4 9d憱ۮnÌ®MÌjÏtp§1-•; = ÆÆ8:2›Ïòø"ç¦`·SXÑCr}æõÆò±·cf¢‡Tú—C ÇÈaš†Ë0F[jE)å¹ï‡1Ý"‡\hÎ…&‰¸ÉmÑ«@gfšÓš¶ó]ü6öîú`úqËNýMÖ4ÅužÜeu¨9(ý’ò!±³Áö}9É#x¯ºÿEMÓ‚Ÿ4Å™$³ ãd¾.ý¾ÀÿÏY5Àu¶¬s UÀEQz=ÑÔŠ= ¿$LqÍr ªV¤d\ÒCF™:¤ê¾—Ï%%'ó Döt¼U›Ç#ÿÙ¬¨eWJé )þ®ÑŸsœVͪáº6† $•½Ž¼\Š“ýî,¥ÙÛLT†adò”©äN¥8u{ﺼÛCtfTµ&ǽ)xVD‹óŒO$C†Ü]U"")Þï^m½I†Ä¡ïïwÃî[‡V¬¬û¼ö0Öìu©ÇÄ\{dÛ?-C 4gâßzõEÛvû®óØ:¹G zÝ2¿LÓåv§_à °vZ¦ñuú  ;¨ºÚ4á Gs”{Œ-¾* ê€ç{ÿ³wìªky¿Åx„Írç¨j¾Â;9«nÓù÷ùð�Ú`ø‰ìV¾37}3:ý°ÿàîóû¾ºúÇhåýc¯Vëo> ïâ[7nçŽ arÐï>ê÷�ÃC3+T@óX夞³ß¡˜ƒï߯(Jö\Ep,ž3¨êkl�ünåNe¯“Ú^ì~Ù¸ÕŠ¸ãLÖ\ÖR…>ÅÞî‡Wmûõ«§‡Òí`ò“ÿ<íú³Wh–mœÙ£¬–¾ò !4»0UdÐU†4J¯ë¢IZÇ$}%óy-ÏÖËùROìËÂtºX¬¨3fù>¥”©tqmå!Æ-å7BÈR8·fµÞùŠn++ù¡ãÑúâlù‘d.vwƒÿ?lü¯JüBÄ; LF–q2çHàGâS4~¢#äÞ¤nÓ;XÊ‚õ>û ÕV$ Θ¤ªÔÈ)c2C&."çxp¢•@’ó£íÆàÓm£5 anrO‘çU8C¨óô„´MܦøÄ¢¾§ÓY¸ŽÓ“2ÈhæM>L´½'[Çf·KVÖ9ƒR–Ü-¹¿ ó;;uI³‹ÜûÄ‚upð@¢'®m¿‰C&ŸÃàs›ÈpUÞOüþkÃWº`ükÐrÔ³Aêqäl3’»Žy£wÛørrÕ”Ïë)‡e1ýUÐ'VD2»iKØó ù%%å²ò’;e©ÚI?ÑÈœ5=u[·™¹æâãÓàÇ›²šÊjžª¹Ì©pZ¹Þ­Ã°w¬R•XLÔû¹Ê1C³b%ª%¯e4…æ•8r ¹à‰%Ï“5´à´Ô²R˵^ÍG‘‚ {YŠ“œK—MÎuåh‚Í£ã92Z)\åjÈc“¿åÓAoNxK¦…L2¶ö½²‘2?Œi1«³Kîžx:µÎÆ›ÄqŸ¿>‹ ìqñK{ß´LâäÂr0qêiòÛ4íýn7ÿb:�hÏáŸeù›«Æ)y¼HœRá·ß„{×c£ÙÎÊo$1º °�)¡žŸú¿©fzÏò†ˆ9š3îQ$tÛ%Ô%àÂc‡hý …ßLAýf¬XE€{Õ9Èw:ä ³„SàåÎö€|´¢ÙIì‡ ß†wª/~è…¼ùÅ€ŽßKÂÿ*ûcgÿòÖÇ^¿ÃÓKl ¢ø ?«­äà›ŸÙ‚{ƒ %pß#  è€pß;8|\íA¾§¦›$È…6à9°ªôvl^çv‰äÑ…Ã a©þB<?Jé\éQ½ImèéÞméýv¸w/_Ýo¿} æÿ' |cÐX,ƒüT:¡{Ô/‰:ò$ÄÜG–<§iÊR4"EY¨JÄU5´ñ•¢s–‘q—%ɼŒ¨E„Çòw,e›TOÔÿŒÙ,QžhëIyΛ&‰Àô–—팪³RΡˆã½]¤ý…T² Š4ºà|)Q<pâh2U4Eš¬sn´ã8ôÖÄ’DN Áú‚•Ì2N$š¢P¥n˜èyì›ÉÈÄŠŠ¨9raZªL%y³*²³y·Ývý=Ÿ¶Ëì»"wÞ;'U8¢ÑAñƒ¥U–šk­ÎÕOݽ‰žø!k'ÌmP~Êlo"ÛøfòÙÚ1gÇÆqœÒn/ç^¸M1¯UQ™«Ä\œÜ•„¦ƒ2c?¤Þç;—[;P+L‘â]9£26ÿžžš¾k8í$a4—ýÒu¡YmýMwNóQêíCà„ý—¾:>Äc#nBî<ž÷�óR’;š^C®Mô]‰–懒ëb3-kÃ6¬Cc¶'γüJk]5¬lhÈ”I®—•ªy2q¯§Q9ØÐIA›ü,È«MìWÔ6Ì—±¨½XFu 2 ‰)kÂIæà¢Ì󪨚B6”ÒAZ¡årÎxæ.ÄèÙ02H0ÞLÌš’I俥=¦ý«iã–´J¬žŒ>·9ÐÁŒÉRŸ²Kév wÊú�–{Rî£P‰Ò*aAÓ»÷Uº&‡hw,Ñ~Ï÷7ÆÀEЂ>3Âå»Bá(£r“,¦´èRÍ~»ux…(Â!WëbÞÏ‘#|ûd{óËnÊÝ44@ø ÔŸv™»¯1Xç¾ëËóµ\׿M%–g(ç(D'!ñh]ìð4bÁq€4¸°háÛ’ûwq?À½ßöøÓòaíçt‰"°yþjü7]7|èZ�Ú½U$<|7ëÿlêÂÏ~µ{ zø× àáCM_ã›»=°{Ë—Eg½ºÀÑ%üsãQL}®ñ|6Alп6膊¡x"¿YÍŒVfãvÛÎ ¦¸#ak®«ÍWGÀ½Õ,å¶œ—uQé}í^ëÐrâç¬àª Ç)ö’«u›³b±‘ñR§èýe ÞŒMyyp†ôýq†.µÌý¯‘<±§-  yj¥jSàG#«rHŒì—zQªZ;¤{³sãýÞöBëYQ$Ù^l<g$5µbJxI£²¡JÔJ&3ô탥`*$%I•dr©ªuU—U¹:”A1=•$ñRºŠÐ4Pæ“”Eäx2ÔYÔskùÝ@›­#ÄçL‘"S#W6Î Y `£Oó0QáãLiâ¯úÍ>Ÿºý˜¢žTÒQ7ã³fr¬gãŠ[ ¯Üýó¶ã*b9+ãXl»½aÍbQ͈ .õBz–beîͲšR•:lGG+§/¸(ÔÙ  ëw.™\2jtÜÖ‹›ÄÛÅE%æE¿ªmÕŸÆ¢–EK†RÔ¶Ì2ñÃ$ö†^v{$)úg“ý»‚œR"´r‘}&/gìEQþwóôYޝèE‡JLD¸ƒÔg «”yâÔGšNדÌÞx7uR M‹"¥’˜‡o´cÊQ2atéD)³Jc „9ž¸lE•bá'a¹ur™Å*«S*k‰dÙ˜©÷Á‡ñÐoÛIT8&öžð$ˆ]£ÌîD×jïÇ&(휾>ìÙðåâ‹ËpÕ…'»²zÁõy™OaxÞW‘kŒÑÑ} Ð1s›q a˜^Úÿ§‹z³>1}½é2õÖFVé¼çÚ¥0ð(€¸ÕÖ¹°/·Ãò!^ƒ³ ÊãprC?#ZÀy 7,Œ ˜€¡“€C;"ÆÎŽúÍÆëc6].–cºŒßý’:è¯P!9°ôïÑ<p,ÝÔá ,:îö$¡˜ãÐþzãß[Ír/ßhë̀ú -¿ãAuß%¹ãOGHùϱ†ý/‹ #°}£­ý‡Q¬±%¼Ï  |W%ñçó¶[×á;‘ŒïêŽðf-,‹  hù@|6Àà¤{xËñÅsÜmñ§<¬~Ãè4‰_Ø}õòæ0¬v‹5õñn:,KÈ%èã;½Ü…ãz½¹8ÄËj¸qù¹º*ÅUaž¿رB©^(÷EÈ€“)_P¾ (mx-ó'<=UR²Ö27QŽvü¯¥ZP‹Õ—ŸRŽìvN³µLýÍXÜëô߬“¨8{Ú-Î%/Ìx˜È KmЋX{.aC6|¤#‰:ÆLŠ˜h²} ³ÞN6ÄD<¼ícN JR²E² º*ô¼.šJ—IPA¤Ô $‘„ÁeÓ;á-‡åÀHS 7ú ­I­‘›Ï “QZ"3·‚¶†’ÆŒz(%'1ˆ  ýÌébçÊf ™ªL›hÑËL%rãi:÷͘º]-êæsUJ˜ºu²çÓŠy’dǪ¹séD1ª4 bõÖYUfº,D*òÀ­?”|Û¦1 Õgw [Èæ´Ñë³B4ŽO†l¬èMéXȉ ÎY^ýœf?ñôÊÿ÷²¿mdAkÃ{p¼Òç ¾*l¦ÛW¶xY)ÌëãÂ=Yy~dÏMh_qvÄt½%>:Ïx±2Rt²z¿=2Í3q^ Yí““S1s³Âš"&yTUÉë7œ›"' ²`ÓÓdS`¼„Њ0iÁx4ø8X³7¦u¬í‹!ÑÊ&€g«&#Œ8u*éªig\á÷³·Û!Ýn3Žþ·›<?k¾þX¢¥ Í!’(„±ߦEG«§4¥0³Ä¢.£œöd}{¹ú·%ˆæÖA0øz«/óÚu«ÿûP2° +`ÿ¬ê¨ùÖ±î5ûCYpÏиaÜ+€à/(g¿ …CøÊ™Ò>Æ–‡ÖÜÍtõ}™<{úíÃo“ô×À`ÀM�°‡_¾ 5oš6o5žI@ S*àêq“Žàht¼­Ú÷Rãïåñÿ1Üÿưa:€ýÄÄœ½Mê¿_"4èÞ,3£ñßIþàt~¬Ýöƒßÿ<žcÚcÓ’ˆ$ìªK ‡ÇWáNÏá%ÚN~qóïØÆÞv¿ ‹ñëíÙk*ÖL¯ÚžÞ_!Ì€±*¯íyK%h>)VͤÎ].†¾Ðgi^JÝZÛt-Ã!~¶ô| 7|@ àÖ)%Jvöžd#+0‘8d.ËÏùÔÕç&j9ÛÑø1ëœÅŽwû&•#ª}!­âÛµ<9/Ο4‹ºh&pÏöŠÝÓrª5Ô±OÕŒnƒƒDÌ…unוý(©M`ª y4ã!æI{®,Í„YJs•ÈܣБ‚Ê%PR€ÀÒiˆý.ši$yBbÉK1“6[ã:ìüfÄÎç !•6ø”3EDå:“mDtY´Œ&ªÉ,¦±;è‘~~G+¢i:ëÃÀrÝÙb<Ìl±ÉÍ>1I~úk‹?û]ÇŸ7ù<Ì7ÑÄÌU‹9AÞäÞ³Ûàü41?dd0‘“Ì^æ66‡‰š«^ÊmÞO¢° ¹ºœÏESy®2I<©ÙŽÏŒÝõ‡)í¹.üê`…üÍ‹ô?|Í×OÅÉEI‡w/³› Wðºà.ºÙ®¡ëFÉãQV=Q6š?×»5=xF›O”Òíýþ¶âŒƒM£íÒ½7¯ê°­øÉ‘˜—bå©ê©A©Y—ÖébbM.VµªŽ eâšP•Á9µŒ9 ³·¬ÓRóLË(UŒqšàƒ%!wcØw›­Ï»XŽ˜¦ò0#—d$nçú–Vë±_Õ‚é)–d³‘ׇ) S¹,§,6s»± ÞÃ’%åÂÕIòQ6c]gt<‘¹`±¶âdËÆrƒˆÎ½î[¡‘©â>~åc‹yÄøéÓN¬Ær/Üaá8üIÂ'%‹ØcGGø­‹ ÷wWÀ[ aÙC5°<º0‚NÎ�Õ#s4£E”�ý€úŽ“Ø~ÏìòQUAþ-y3£xÜ– áѳáXg[ /qèÿNt30<�@Â=.ÿI÷Úþíaƒü›ìGê ø6©_sIØ„èFùmYðƒÓ‰?rs !ÀaÅ9ßq¢v-6øeÂÜ—óË´w`XGGp9Á@“¡"{îl°÷Pê•üÒ¼Þ‹×PØÐg›ðµÎ9ªqøà¨@žTq»ÓKNG9Ê3—eë#ºñÙmºøº¸SêëÆÌ­Ûæ$ìQeŸÒš“a¸×¤Uê] Ô„Õhš J‰böåÕý6&ÎjåE?±å—¢üuÍŸR2Óu…¹ˆ…u c]Š‹ùH8­²S½W&å=툼qiÖó¦´!ÄhR¶ÑÄDdÂÙ)Gž¬wL2pFdÎ4)²}È);‘³q1M‰xëS×%×O~èœÚÄ1y[¤bœ˜ßnwSßk9Œ ¥=­%×ÊÝå0�­…èÄ„y­¥/’¡aïSÞ2ƒ¤-Ÿˆ´®È"û&¾˜“#}ñe)|)–óE¨E⃋‹0žó|® "„°d&TQf朿£þÛ)o¶¾>LÊú]FÑ3Ki´pQߤ¥YÖN¯Ó6Å?mg›¬5«ö¹½ÉýXl ² ~xÑgìß1ƒ ¯¬šþ,}Ú d¡°¤(Kaî_ˆTlýÐÆî—>í‹U\°9—¿Î³ =·ì4’†HÎ`„¦£ÃäÓdªô '¿MnÓè¿Rô\¦œeIr¸œ ÕÌR%¡ÏLÀ{~?êjŒ…ŽtŒÈÏïq<§'¡ÌG›ýH@%è09ß¶öþn·?ÌnÆp°¹†<jÙMJ^gÿª+Ûk¬_[u4ñù8ÔæRNÿW&Ežäæµ’°ùßÏöqÍË‹8[WÔ2ÕÊðÂIËŽ‰É’Ê‚¦‘§>¸ë‹~4a”0¬ØS8rȀžY‹?c‘åw '±—Ç,Ô:µÌŽW0`³5¸ùn×K`^bÓ>«MH€‡»ƒy\BÞ Ù¼jàþ‘`zåCÿÖáMÒ™¥ƒŽâ €ò€ÄÌa ”�`(øAH·?ç@ú®sôÝõàq)d÷ënºüdžô‡ÕAþ=‰‹3`@ŒÀ7?~:ËG–ØE…Ëø¸©€G˜™{Ôx3q~¶yPÓ{{i aÐO0wÇ h,Dr0­Aü'eB‹ß H ·O€<žã €Dñ+²@ž¯p×,ÅmŽ/wìú¿p^vUu0p»¯Ô^bK,Éí"O4°z”ÕøgÂ}dêùŒÌýç¯YûÔc¹‡ž}^Ì?ϼ–t‡@RŒ£¡4|Éù%-ž\†p{=¶d81’@ĘرiÊ/ÇÈdZX™S^$ì¸õC8D?`è´¥Ñ.Y3©=]&)Rê5 ̉”<ÆÌdžHð‚êͨ@ýÜ…ÁKRFâS°Æro]¶Ü‚ƒë÷&Î kb”9D&3ú@'dïîL'›C˜y*ç>†œF–‚Xk*XÙ'šT¦9H—g=EØ•ÆÓL¬sŒUŒ$žjS̼˜Pýc¯:ý„ÔR²%;kú‚;îhÈšSἎ\YYÔˆqÆ>í'7nµ³>™{G»(>/¬¨Ñ Q™RMçG„æÂ”„äC~²÷PCû¯Õ¾ ¢é“¡=®,˜¬“õþë°ZÒ‹³ÂÌjâPVì9Ÿ™ÈR7ãÄD¹›RCEÙÎʸVqŒ ¼b'È‹ˆ¬$=K;nïú¼ï!ÙRi™8Õ‘L,êýH‘”Ê<§ät¡¸©àFÄ‘[ §RÇs &”÷1’!S±ø˜×UoÃýaOl¯°/©¢išF{{ç®/Í+Û^ç|ëº~Òir3ñßz“�� �IDATæ{ )·‚]«Mo âWª•ó>ØaJ6«–.àÕ’ÚÏ·q%’®‰¡tТ|‹ƒ¦ŒÄu-„(¼S¹í77›_ߦ}óÙ•a¾Æ®Í@øÕ§P¬Zó²šÕŽ~š_TܯGw'ð×óæB·.šöÁ© ø°Àóä)èÍw±yþ jå'ntÀýƒ:’{7™·)~ËÑ&Mtùí¦ñ#–¸kH ÒCCC a«#Úö †ð ûï¹µÀ�ê0vÿ\ý¢{ØðÇ×As`B·ûIÉîgï8²^8ö>Ì(@?Ï~¸›ñþ-ë:C²•ó;8ž¢ÀÙ {Ôô¾x¾ì;¾©óû…77lÂß-Óò ŠîBìjSÈ~ ̼Þfæî=öŽŸC/ïNëÝ9ý§’ܨA1{Ìf'´žzA´ ñóçæù6¡d_,òržëÙ8©€¡;rhìü/ ¹,¦SÚ©iÊÔý™Øº©G÷ÌV^n4£b•†²‡fi/Ü]Üî†.md˜*J]À~èG,Î@2@¢lœe™f|Sq+õ‘'˜1btÁ¬ jÜ(yÌ,¥èˆóŽ'Ës‚Έ$ûèÓqco3Æ2»èœs´•Ò"F½àЧÈLŒKfçJ^”³FF¦D=’îŒÌ4*6Î;Å,Ù.Óqtȹ·GŠ”ûÙŽò×k±éšôŸLcu„¶ÎÙ‘ƒTJŽWDΟ*Ž4’.dKy$'SœO®÷SméêÊÌ«”×v¤tor5?•ZŸ ø”•·Ø¹qzöšôûòüüXf¼¢œ©jéIÎv—joÖÇeìçN\,«ÓÙYAä]q²ýµÎZIÉÍ6»Òs+…â©HØžÖÁ¬q(§H€ï‚wÁßì^K™¹¤b–±IòJˆßJ²È8VôHªB%Ÿmî"}Ýê‘2+|âVVº…ÒV¢ókñ¤` ¦Ãövë§;I£¤\ fØÑv£¯ÛÁäoµ¾,Ü™ÙÍ&&£îmêé }fqênë¦’Ž• Gãê3v¶<¶:°ûdé!Û])¢ êÐÆ©¬G®{Ê÷I¦Š“#]ª¾»—ûf°W«Õ×p߉cKˆ3ˆaÎ\L´ô…ØG÷³c¹ßcñׄ8¿fûá²ÁÑ”àS @%Pà ÷ûÄÚæòð]ލŸ¡<ÇJ`7âúk Åˆ ݇ÚŠû辿i ‡Ü!ŒŠáÂ=¸LK¼~–ÿñ›à€0þA]šý‡Âc `÷'®Ëó?åPú_Ñ÷ÍýôÎuñv7äM—P`'¿;¢?¦ÀÙG©Ýw˻ßñý™ö›O®F)î.’»üȹ»,нs}ûRø|{…ç·~„zêâøÛÝ(Ñ;ˆ{aÿ †Ëé¨Ü, Uá²Û=wÀË”ϪÅùGõvEKìžq†rbE+J1*vÎX?³9ÈJºïs Nrb £·e_«MUÛB,ì}™ïr±™'žë°gë¶ö‡+ƒjRe­)‰|CýÁš0¹ÉL²ºSrS°õ¶­©¡}ŒÐ‰ë<¢,E=°™£…aL'n<5– È'Ê)BÀ(Í̃c&^$} žf8xD—óÃÔ‡ž&w"‰È)Ri‰p"iZ1¬ÔÜùä³í²1Z&^Ö’jJ#™êIpÉ’D`ñH¤ÀI&¸ELƒeŒÌt%cQº¯¶¿à_¢ç“¨Ía6§nתTJé§Ž&CÆûœÏœèQÔžYá­öA…,²YëÝ g²¬V’ëä«H“yª-B6lT†Êî9—~ŸËë<oeÝPí÷‹,.?zj¢ôE<*Ê_=ùôüd‚jéä)ég¢27ŒÞE§l˳º™J)iÎÉ[ß·[§´…g1n„‡c¾â唞 ~Æê®©6…è4Œô:¦‚I‘8GÚ žßíSG!ùB±J2ãdH$ÁNfj_ûýeð¶1çlw×þ¶ÃSCiMTÍk ÔU°Î1vûÖZ"Œ+t\$CU],‘1¦òʑŽ©“=91‡Ã7Å‹cUÛ}«×I¯CµŠº:åOžÐyÙT½Ãm¯¯oí¥ˆ_Ë Ò׈¯fð÷اCûiÛÚ»ëU><‡LHÜëž´őȫ£[oM_áëá°Æ.2‘þR¶¯P(„ÞˆŸ�Зßß§šÏß›n6~ö]…ð0+eîoÑ-:ù³èCñ¿‚�Âw‘o2@^½'.0üQEÆLËÿµ°á÷(ÄŠ ÿ=®ØûÁsÿŽÍá˜P¼7n.ónRpü‘ùû#ótp8\žD7@!_ÀáÒ[>ÿuóyÕÙ#ìƒðPo®ñÆLнî h»¸ŸqwlÞ̲ÀQ�êÓºšÑõ¡P¯?vrwÿI¶ºmµÏ~x2ÙÚßËx2“,™#yÉÛLåç!>Å'“g¥‚e|œ…(øØ{Ð0Œq?ôŠu¥5–Q®LQw¬÷ãk'ƆN´Þä 7›žš-}±YÈvOd(­9!,;¤øÁ‰ jÊbP:F&3ít˜ ÞxÒx^Q6Æ<D­H6Ö…~úÄGCÆ.;Ó-Ì%ÆÛíVJ2zžÜHb¦ E„¦Á:VGºžW!³)Š”˜c&Æ%œ`ÌpfËÄÜÔ‡nH½3 gYA%ž®Ý ‡[ÛO¿Ù½PK+gó¬ËÉ74ª§Ã‚1M’‚ñ݆šÊÈdPªƒ¤]YÜÎ/0ªÁäLM?ÛwJ`ìê(Àph2Ë·Â&ßW›{ºI<yq*4_Ÿ“CQ èÞ-׳fU«je™'î ÅÀô´Pw§#vìÌÍ‹±’BRæH¦nšn™±’YÎUq(b^½êig8Iª¨šYY<Y¨¼ Ù»àÌKXr¥B$±š:Œl;'¯ ^SzÆ£ˆqAÜ }w¸Kä>nþžN¡m¨»8ŒÉ~¢üX®æ ÿ…®Š"@ßWãε]Ë¿ÙÏ–|~úÄher“ÍØd:ò×Cú÷mø„„jòw°»Ë|zfýnVa\79fΖôüt¶ 'Æ‹dËAÖ½\ζ»üúŒBð±ae¾ÿ8§×–‚EjÑŌŜ7Oðíxgo¶C„òžÄ“ò¤œáàwÆ–8'_¨Û/öxÒŽxÓP Œ„ß}‘{`„ olÄÞ˜‰}œ¸Æ³î~lçPïÿ#p…7\Õ„µ·‘šãa£çMÃÿ”1Ãω–Jéϸ³þ°°ÿW†ïáÛ÷×p‡X>fï»÷Gám«î‘ã¾?²(!Wpª¸% €½ÆˆgQ¤ï,í©» .8.Ã÷Ï}e ËD_…¶"Ä€Ù±ã7Û‡ 8ŒrlôËò²*ÝÈirÐ g€ã÷e´v;ˆñ9 nÿüWŠC5‡Ø_ÓÈJ'G›ºº.y<U5PÚç”"‚O¤¸c!‹˜aŒ«,yæ>úöe¹}Ñ×Ó þCç*ôBNWÒþn(,79Ã<icÒ0ÅPø~^Êâˆy ¸^d&=±Q›¹ªÃNÇ üÔσ“ƒ'ÒQêgý\ÃSÅ(%,f;¤,s”ouÉöÊß— ¢©ÉŽ~f8sT «4S‘Qƒ}2Á,ÜbKÚ³¼¨¢Ïɳ} 1³šhUä(§Ö˜±S9¾PôÆ6û\ úWE|ÒôgRlüQ÷«7†´1 ½'qÍÕ™¥lÝYƒÔ¹¡O”z2²EÍÒÖܰ#îËl ³Ñ_u~òjçíÑ”ÎhÉr÷÷®_ÇYqÈ˃ÛÃu£ æ3Ú¤¦Á¹œv»O¼ ¡³»n’#4h÷$ s&ñÛ#?Ÿù^xâ” R¤Ây÷!0š ‹(£¥råšãqi ¶ð›Õi¹]KV„xcÊÑ«0°xŒœ%3cò&t#ø}NCÄÂNÅÞ6!¡r‡&µüðmš½Ù}ÙÞzÛê‚ô«ó¸h.J5;Oö9Ñ‘(aRvý'³ÆÖYsÌ‚×ûÁî}ïÂBÆÏùâöð7]{/ðiÚ— CZaW•vw‡íŠÓº¬/•¤H”Д3MDù±Iûÿü‰‡š0…‘”Gy÷wä¶œaÛaå‹-6;€<HâɯúëšíߨÃÃ|ð; PX‰–Þ5g …‡´ qÚ¡Íïï<íüNtmßÚˆ=°#pmÑî€ ËûAÌ€=ÆöûŒüŸ ko#uX€üÀyíg¯jýP–ô'Š÷ÇÄáÑýË÷”ž½Yø1|+<ãÞ›ëï±Ç>p(öGü~j+PޏøÝãÍÅCwèÕ‡ž,¡C¸Â}r’Œ•ÀÒ°íßüÿä½[“\×™%¶öýÜóRYW@”H©GjÏtxb&Üa;a‡Ãáßë7‡'Âî¶=–Ý’z$°I uÍÌ“yîûî‡H€AJ#µ&ìý˜•çdÖ>¹¿ËúÖ·>vý!¿4½ÖˆØF}í^?Èö"ž™.Êlüù5~×ÃŒôc.£òz¸ªwÏèNÂör2Åé(/…ì©Vþe¦‹%H¥ɋĮÑÄÙ財SïfŒÃ`Èu²ìfþ4— ây£¿|³ËN2J3—/Õ>ÜliHF–íÓtˆ ·òúEn)+Þ”¶Rº}› ·‡²lHÂöÎ’ÂÕrÌú±£c:OYé{¯¬K'­©³“«;=e.â¶a›Ý0™Ð·y¿K]à+fñAŒÌ»r ¹ä1UZŠŠ%ÊQًÑ+•"Rᤠ³žkGÛQ.4Ì /r@¢!ÎFŸ²¥Uÿ°Wµ`TQÁ¦ÌJAÄ”çÉ ÁÒ•Écâ¢K[6ô¦(78¡Y7´ã¦¯7ƒÇ ˆÌ /¹,ç»*Ä¡$e2k‡h5Ó~6c|~ëºÆ¾PÉ©Ï3Ô4¹9½€»æEj,µ95dåá^ c²µÇOý¨õ6æó@Ld >-$­ 1°¬k¢ì›)&Œ*ÂQÆeÒïQêÑbƒ´A1¦[ž—ÌÚŠLd2bj#²Ì3™Ó¤à¡ê¤=wƒcÜÂó!®iÜjÇëw}Ûf62oµèÕûÍ‹áɵ-¶ýTöN=<JøÑœ/³¸lÚLFû½/£N¥%Ìø]G¥ä¹¤"í=‰Üáq›å϶¿ÒûË`V<«ÉU²²fŒÏºpÛÙ_Ì;êzs×ò!¹ëíËÛÛ+»û²š‚B9@Ñ3_šœGõPG³kØÎÍŸ¡¿GQÀÌŽ2Ý\´=Þ®| @à™x0h�Í•lý\`q€~ýzÎó«Òã(€H+ç0fÿjŒØ}Þ0ŽÖ¨×¯|Ï3à>oøÁZówm×7#9ãðmÔÚ}+,þ^• óÉ?Uiúnõçó oÏ©ßíß^É£gÀH¿Oºö-�î~rwòÝôÍà;•€÷lÄþ=_üŸ¼ŸCäñ:á2ß™Ód€ Œf¢ø}x-Ç8‡[ð¦0µ½ÿЃ9Žù‡ÎÝËiž=)þ ¦ÄD³NtpÛê9äÆ1œBvOró$èO‰ü˜ÎfJNõ¶Ím;êqö˜˜S«Dhw9ù²Â“T)Áüá¸%ûžúJ’¹¢ÉOB–«îZ›ÏÛ¡ŒþlG”qUo—ò–÷s}³i´[Ÿ¿^làÒù擳mvÐäꈨ@.é÷Q ‰å¡P§%|bC×l.Íz×î~†ùa]ÍËăìÅ•·íH¬‰´ t;aÛðn#Gï�•YäQ±˜FDT‰bAÇâÜqJBTíHvCÒ&¡’[®…¦ÔZÄ>jmB;ô¼1Cîg8UNEAù-ÿ/ïÜ“ÉjŽBmü˜&wðRð̦i™æL“STF&Ü,M"œÝi÷¢hž‰î«#j·§³¢Q ¬$BÌ~2aÂl`Ü㵚ñe`ÙLÿÈüžþ+>q k½Øniˆ^ d÷ù°OC;󳃢ڔæéui­nj8úD¥†¥Œú,Fá©2eª§q´Ü“¸pÉÌ2rkÇ]IŒ"¢1𘪀„ 4´L•Êxê;¦SR"K…¢^˜à†0hßFÒyò2e$÷6ZÚš’ÆÝ�ÕL䦛´Ýï§Îlú«_á)pù¡>˜gÒ8>²i"±ÓSWO=\¦RØÄ’xÅ­¦{øHÙêe›Ö—׃Ô\"7bÙd¶J]¦¯Ÿêù¥¡˜’zÝþv•ç†n:ÖEÓEU}¹o~óÕïÝmwUØ¿aän2?kq\À7H,FW� ÀöžxúŠ6hé´éOô7 ¦)ðo€#`¯q;¡®€d}¯Ì6žÇñÂÂÜâ"‡A °ûyï¯'<@ûo#,Ão⫳üu° ÞsŸ^‡¶Ïþck¨Ã7=Óo³iÞˆËo)i|kØÃŸ‰±jþ"µèú~äòûüí«Â=yÇ/Þ3JúÕ‹÷9ß[‡?¦#ßxü?°ªL£ž`@qO` ÌTµIÆ{ê›9lG •A86 aÏçéÅb¸inñ`ÈKsZ"Á§XzåØê‰IqGÑõ ÏÃzžÀsl3tÝßT¨ªá3*ž˜bù“ÚíöïnÛÑL©ÿÂå+9•¥XåBùd` r3©Â6Ó0þßÀñ—±He±"þËL'R¥^hß Þ¿èÍ—kºÚ﯂t÷„ÞAmÀ~ú/G·ÐD®DµXêÆžv"/“„Ê%‰wÖ c{uaŸ¯Ù^ØÇ³NˆÍlŠ®K§Â‡TdNó68ߺ©k»­¬7\¤˜±³™µ†1ÏU ‰ Q/S£ÒÚûmÁo#ÍÇÌxý4NÛÔˆSšoz®ãÀ´·†‰nƒÚŸÞh©À1e Kxêfdú›—¦¼àø©ÝHñeÊwy<¡Qt’ü¨„£ô¾ÚL~C{;籘]MG3²}%d"Ù"á§1‹^(ßtÊ ‰ eôE¼=Ì…Êny6úÿSñOÙ¼¦áZzgüԳ¹;îÖëí©‰ êjN×a?Œªéû…caW°QJÊIie×…:Ø›Žl5{ÀXN £†”]>zª…U§ Î\“å|‘*ª¥ Ü"@áNªAä:PkZCLG²É$®rÓÜíuðƒóÛ!ÎÆ6Û{Œwµý*‰ê.×Yuy@Nü/âÌ%«ÖÒN?wéõµˆT ódmÝûaw¡v4½ë)Éø—6Od³T-©Ë‚0¥yÆùù¾[´·Ÿ´/FzRË DN»œÎ¸ó4š^XÖÝî¯÷íe±a$;Ùr½[Ì]Qû ®F{ 7#¡Žð81Áô¯õ³©åvÜ|ùÆþ9 P`ãºZH†óךwß�;ý½&Â|¹€©Áj0`ó7À#`¿¾ïk{vp “Ä”ý�>ñ‡8Ã0´þÕ¸3Ps{rTûö›é9Èë?ý…ÖŸSz¯¿=Ä=ªS¿~gà°íû{ÞF¥ó#ûœ@ÞNåJä9ìt¯³¾ê¥2ˆ¨ R,ž¿"6¬9 Gü…W…äºïÕáÇósÂÓ&×ån!»‡á¹lêÜ$ ¾ZGù‘µGãõs45f_ø™ZíÎÐÿ¤Ù¦«‰ÿO™¹©×ù´½ÞŒãHëñJþ®Î’Wîø”5áS?jö±nÜ—dGÙ£‰Ì¬`¥µ [WHÿ(&§œl!þilŸvÝ~íY¨q–€OˆaÁu"vÍÁnYe¡rÜkˆÖ|Xš‰³ JöÎ/Uò¹Jš8]ìL£vcRhŽ#±6Ž“¿k:×Md¢ÖÐÀ4#U%œT™Š¸Ô·¹¯`%DøÀX”Ö Á‘èÌ6ð £°tïÐðÞ¬+•,˜˜Å±Z wΔ¤áÔRÓĦ_ Òã6¸†mi1OècÉæ •Œ-iLUbB¼eVhnúA1¥ª_¯ugc÷,_˜/¹œ3š©ÉsGÙõR²tàŒÉ‚Œ|q£¿âÿùC´Ñ…Ö5‡îc™¹, Ã"OÌÁ¥dž:7É¿F–—lAüg©Ûò+-vizjuÄ&Á®WÁ¹H&ꇩۉ@CHƒ¡… ’:nf Yn™‰íI‘ÒY!T¢R¡˜œÊjzG q±ˆ,#~píêuÝýprº³^_y¶Q!äÙÀ§;ÊsåÔ:ÉW±øo+r\ÆEÊT aŠõÔ5檦­—Ðj ÎñÑÎ[êÏy_sOX?èç·fk$týA˜ŽÇã Á ØÐ&G%ÜCÜFrB\÷ÉÖé¨råïÇ~Sïk±+—,IMÂŒˆWžˆm‘ oá–rHëŒRòh2 à`n€[ Þø/í+M4æÁ²[p‚öîu2ð¦êw¬›ápÎûà| ÐÜCPñuìøJœÏ^A ÿ„¾Á@|á¼ÁáµÚëwqpƒðã#ùÿ‰Þ·7ÿìÕv”Àˆg¯Ð7òí´ïßó [iøÁ©¯EØïÛÑ{…(ôo?• WÙÛÉÝúµK0¨‡ì)p\è�L¤>ÉíÂ~¹»3ÑG+^g*W#A´i1‰’œ ²@8Ž4ÅÉ$ÿ•oNXøEÒ<séSgž®-„ƒÚ]òë®Â’È"V?­·/Ø8ö³tñ`V—[l§úF]•KÝÌéôÏZ·oûfèî®”¦gùáýlA§W”\i£x8ò*Ê`·Eswà»VCEwôÓ!GmguûM‹bëŠê޶JOû©¾ÞþÞKEt>1»Ô¬øx,ùÅŠÑDf\³èÛz.“=¨šüX…ƒ~ç6ã`Ÿ'3• •wag`T §U˜Ô¤9¹¥rI¤a[%í¼ïéû`¸ºc×y~›t&>sz>’d¾’‰#lZFr¡µ!»ç²¥™štˆl°|u–8ocç¥K¹8>ˆ‡§ ¹ :H«yçÀ´µÜŒu"s+º§—Å¥õéÇz1Y$d¢ƒ1Ã49MRî³ ‘YB=›‡Ó;ÑŠžá¥-ã/¦ñ å‰œš*DºÜúìuzZ)O+ŽÉ᜘7'ã?‘㎠•O"ÒT,ÓzÁy×'A¦±AQKgRû!‰3bËDŒqê0 ;»sÈjxdOD“ÌÚc¬#22N…W@iFÍB=ab¹u) †ëÛK˜êËäâä¼Îü2ÆÇ{“vú€"﬩ub=¸Ë@‰tb¶ £Ûu³©ÏÃDø2Qz¢î€ºµ›5Ì¿ÌÑLøp·J¶‹Ã 4Nûv½[ØØ^BFi­ÊÏ+Îæ„'ó¶k…hœ&×íhfÑq²7&Ö$}*tÙÕ:ü ì=Øï¤.ÎwäâFI,[ÔÆØö‹ +°%ü/5üþ7¸*‘˜7[ˆÍ›Ã×-RÕ)­0Û¥ 7ÎäX3Œ ž¾6,_ì`›”–áÇ:†ûÆ©ý¾ïμ•ø÷Pðß‹ö¼U™ø36ÇýY|Ã7j8`ó*ºïnt_sÃkvñ½<úû«óoñ\¢7ïÛh ,�¤ˆ÷8Vû6‹×¼oU/^‘ 6À·�C1å‹-f>³_Zg d¯r†LcK`Ú»òä$MÉ1s4³z-I}yÆÃÆýçE7+ -&|¸CÀ¿þ»I$·žgªÞŽÈÙ,}4_•¥ä&ÇPŒ’nŒÝc—·™@6^‰ë&a?ÉŒš"å0Ñò:l’x–\h6?‘—‡‡Æ30ÿøˆ£gÉ·Œ›ýxJ ^ÞͺiâwõÍ~þÇŒ#Ï„>«›“i\3¶Î{MQÒ)'|;X_Ë~ÐÛd¾ŒÙÜñjðZÎå„8ú’Õ•b/ÈÌÚ™¤n•y§zŽ‘8£!w‘dc Æî2.Ù–<d‡3IIN­T‰n4tËÀd’Z.WÏÃiºJ$uyËÙà§Ø•Kl)œd‰‰ÒN£øB ‚wÃ!!P&klÕÇùsR<òè[ª·S,µA7¡˜x¶ŒŒ¶Á4Ñd±2üC”yûÅòz²x`øšé_/œØ4SbY†)Y‡U’d5i9�áƒÎ}p5ë¶ÉUO÷ ²Ê]™Ê!×sÓ!„•øiJ¬ÕqË’ùÜ&ˆ có0rÛ*rÁˆ *˜Ý¾r·^¨åPž‚R¼ZXYˆœeP‘æÇz¶ëºè±™”‡Ú¹¦/'OJ¹_d¿Í­ÈÈJŽIb@uëau/vAkò4/âÜŸ±¢rmgó_Æ\EYqèÉø ÑáÑ\©¼ú/Ü?… † ¡ÂÌqGVgŰ¿ÆÐ£ßZ ®Ìè!YÎŽ²(ì&ßÆØš¥ÙôdŒûMaï³ #û;ê  å#˜s`„¼`Y—ÕW{s½ÀÃhû%P<XcùˆïyQX|0„Cö¦MP§0÷åM ,#` X˜>|]æA|ˆ1ëq<y9b@6üas'¿YÉœ§æß¬ÅÖhàÿÛ£oÞÊüùº¦ÿ,¾Á¼s ¾Á×öß׎!Xý­›÷¿"ð+¼‡>\¿f3H¼Ò\üV»Kû½¾ìÍÂÒîuzs9Ãb‡Çë›Ñ *@Ô³ý³½V ›s—v8_·Ç—ÇŠeÑtûKë×·ª;‚®ŽHÉ=éU¿­¢<›Ï/e £ÇÏ«'zx„¸m$èƒ:µ5 ç£[Ðbi‘¢ G�� �IDAT3ãé•íþ/·¡h~éM®™oÜ%¼Îã,S§UhûÐ<yé|G36þ2¿*ö=ÙgÑ•ò¸<´F°ö¨çlFµl(Rç+¢Lªúg>¶úBHƒÔÃNK†£4-ýb®Cƒðâq[ñ¾}9F\¢-ÆDû¹PgJ%¼ê{SO{­ˆ°ê0g2÷,ó„iN 3,§è×ÎixN-%‘†àã”\“À¨Œžd£Žûf¸–|TÉ& “Â|åŒ$®#M+S/îÔtg™>QÕ,e+¦FîZ"£¯‡ýÐ42 O «g†òCN ©¸[î4èÒ L´çVÒÉ)’÷ébÏ Äs­«/+R¦<MÓ4÷ÄK˜ëÄ@Ë>Iwý“ysÆSdýJùŠêÑÊÜKŒœ²8ç…œ Âi›g´SvàéÐ&‡K?K°¦¸´»ß ý×8lyÐlø¸ ‘A¡£S´¡´n|2º¢t >7O‡úWTü7YÎ…˜¥dó„0$±`‹(ªÛ$ ²+²kM(qÖ³AhyÈÏ„OµNØ"„ÿuTÂ7nÚi‚0-¦‘«Ex| Ï£<ºÂýû”Ôû J=N|u0ðî3g\ä2™ÊÙáÔõåÖ>žµé’§[>ju„ÖäLå*βB•<ßEö¬ÛÞÆÛ¼vÚöͳ%èj!/¦)@I(%Q­’f ˜µ è º:f�—1h€)Cõ+ÐU¼]C¿³Ê(5ÎG\Ô0�Ðì›m�3�Àì•þÑ[ÚOŽ  stÿ‡YÇÇoÈ7ü¿üÚ7ØwšÛ?YúÞ ÿ,¾Á¾ôg?¢ñcºo*¹øþbý7wÎa–0H" ̃<‹{€ ñ2‡!ßš½§¿u³W[“�ƒÈ°ÞÕÄþ¶ûÖ€‚¬`$LÄEûõíZpŠ¢{æj ûÇSø0Ê«y•TÞëKs7M›¶<ê©VÁ¥ôº ÙO ú/3Ý¿ÒÕ hŽÛ]y„´BæE²˜EŸé¶!ÔÔ¦¬úEñUþI:×û‚¹$¹ÎÍ]:®·öo );aóâï þ=ç<Ïÿh.{ÎníÁEYüLÙLÕi쯤úœê`‡XƒÝ$ó-$HÄu€g£Ä]ÜNÖ?jg»T IîdO3ê"µýZ*†nÍü4&¾âUrˆ;F~f<O¥5åÀçÑÛ"ö•p"’›ƒ+Me9j¼³So;¿%]§JjM½ãƒØúU*)f³SvbγjÒjÜéð<ÉóL'ð’LND™Mf£|¿_Ó‘(+³RRÎŒ¦¡]-›U>'#ú Lí v˾ɯªˆÜL^ðéH%‰÷’;>îl/m°{G·ƒ¹ÙÕn†bþ!Á‘DÁ˜y¬–ˆ#ü‡»®ªâ“ãùqY$œ5DõNº‘A5 =JF ¢.œ_Lá¯ö/¥˜#FÌ[$–óÞënC1Å¡Ãd²zІ¦´eÚú ¼è¼íLGɘµRa±]@BYt8°Þɱ§4 ª¤EBgİ"úŸCLØÂ|Ùu7âŽ*é†ÉtI—¥:ÌàœìÛä"¦ÀšbâÏ>Š]@.¬‡×®—p)›Š®šq0·CÝÙ~v|°Lǰjk6“Q<ò¬€gžh¯õâr÷{àA…²ªÍcùô)´‘úüc"˜ëý µDHP/N]zx›¸›©.{Ì1žãrpî)–�ƒö»„Ñ‹›7^©¿ßòí"¨.ß¾ð‹w™—ïÆ¦ÙGZ½"Ãÿ1DÒ¯Wÿ‡uŒýÑ­fzÃ[àåÛÍ„¯A4ùÆD6 ¨z ì¾7â|‰‹ŒÆúäU Œ~y�MðÛñ];›¿=o.Ø 8Ä÷ù a°:´Fvú<âb„IaÞÌ*’=Ì«B†D¸Ÿ˜‰AfCÊ•˜¸Í~Ê'İ—âqªœ£$s¸•Œ•Ö§ŠgPwcÆÈQ3G¨ÎO“‚ôÒ“Üîg~wgp×ü<öK½K T dƒçö¼M)‚ûë VÍT!Ølå&gO{Ì|æÛÒnøò¯Y™‹.3ñpn÷wk—S¡†¬ÜçRyL#j-{·cr·€Ô_$Ó‡˜E¤>õ.†ôÌdÿ«u¼°å#Ã>—¢ Cô× všøÙ�&Öl’Oeª˜Š ÃÀ 1Á¹Ðy$Qƒì [c×»PŽ´ò¹[˜˜õ²íÉï×a»7i´¸f ¶C¿wÇfòr ‰ÒùQÂDkjIíEo²w •K³n΋ƒdŠršâ FDV'‹Û*ß+¥â;ýœÄ½¶Ê·Ë¬&L›yL™)–©Ì´c®ܺP']Ën½2.rW¥_A*Yï *%QI»ý féÙñuþà““j•ÊiŒ·½¾IÜ(ŒX†^˜P¢Ód#µiȱ,MÎ:Ñ$ÁúQ£.ùTLÐ [&£KŽ ;šŒ1}Lèè¹ ü°,º`„Ý Þ§¢ŒTû| »$IXAÌ É&T‹:f‰²,*ªlbÇvš¨•awÖ™Ëýð[—ìç‡YÎÈÄ Ün7I«»z¸×ó$Õ;’ úH¹ÊÐÜãí~íM 4 6%A1éåì d?×}ŸvTE<Lã^Þ•ç9œõ}¿ÛÈívÑ%Ñ/ˆ¨W OQ­¤>:_¯.š­ü"ªì²Æ™îž(‘eU+ÅøP:wŒYsÌvÛOü¸?É`?¸X3ƒémãð­i oïàÛé0¿üÞÚu·ßMß”òþ±K1z2K`÷ËÍ�п» âF–Þwá?g-úuî“£¿øZñ­Ê ûN€ÿø¹o¢¦€Äàuü•Öýê2¾ëŸ7  öâë ®÷~y?¬éÛ?% œƒ^`0Ѐ1ñ»2�€÷âá÷®˜âs·Óu¨NÝî¤ÛÖ|ßÞtí0‡£(yÅ¥êì~0º‰) ïÐå:AÉQnçÏ 2'»1Ýú0Õõí§Ow§€=þ‚]¡ñ9Á³“Ç$3Ö!lÐö-mG Í º¯LÂø“OÃÑiÂŽ]ǽ‰£ã[˜_÷ÉÙ’œl†ìÂ!6˜í%'ç$¹è+Ë—©¼˜ÂnÇÐ;vmòó�Þ4ã Cùªñ›(ûnµ¼+WIÑÍE–‡}ÊÉL)Ê*Cè.R.}@¦ÞOúÁãd·ã´ ì0øJ²‰:CÂÿqœþ×sØlçY0ýv”ö&WÄȸ͎¢ÏÖzº—=Ƶ{xdeïr–²;‘ÌL=±T÷¾ !^NIÑÒ}§Œ\rÙ¥ô"ççÊ.œÉšÆhãLÞQšÛ¿ÃÍ,1ÕÑhè–èºA‘Ó=ª½QêjJëV~X5ìt“•g§¿øÉ‡Ÿ­UBaÜY}íì6úiáeCcâ÷n°Y#MÒ“Â1QÁ#’aè»Ûpu0”Çâ@ªY^ø´Ó#LpÜi %'ô˜R/éHdo(Õ“¡4Tq2&’) «<Ï+«jÖ}°×<&l§àÝs¿ØÚr G".C»Üê¢ï>£ìLOd×íæf¬„·­[n¶Å>96óï,·›½köœ§–0¼pŽLIœÉ–Üôb3Sœ&¹œñmöË4åní+CºziGR%0xc÷Ïâõc—Í”¬[‚Í€±5D\,‰q#†AnÊ9ÅB¡.n r?žQìey¢’" ¢ÜïFB‘%ãÇð_`4¯í—d0ú`ÀÝ·­ÜwŽçðsÀÿÿ0/±ø^˘�•ÄÚ¼ ;¿’ò~CñûÒ…{Äâ%YN£~×'¾§Bû­×ý;‹Øæ?Î,ÿ'ÁS2p ßþB¯Ì±/(v�|!`ö@ Ì�ŽÚ½¥‡þ[yñ…ùͪŽõïˆ5Ö�ƒ|Sc|óg¡Í+!Æ7Ä~¿çiÞ'ª+ ›C6¸¨×IY„¦âgìVtÝe¤”Ì÷i<²¬¤r˜Üõ¥gí ÐI2¬>J²óhŸx¹ îS&:èÉ ì$¢åpw|?D¡)—>äGnM/—þÂ\HœK):#g‹6yä&¤¾µ´êE0²£U#ê9.5»ìúÅ?}Uã¿hÌâQÍY¿; ÓѤå­ùUmt] {¥(ZÏŠØö”6è?:ìP¦ìQºÛt|.Ø’LU™jf‚Ψ£É1ÝÖÃÅ”–å›îlgRâÆÚ¶é{™kË&æh ÒÍNÄÿ0Д¸´Ù0;VcKŽŠeZl'Iö6ÙòÁv²&†n²ão×ñÃå‰þ,b*åº}ãGì2RDfo{Y ,zeYJäÄœ1tOѲgг™·Á;‹&ÝÆ²;Sê áŽ0jΖÒQ…#dD«jæÉ¼¼U•aÙÑAùà°,‹ÎºNw»!¼`q/ÄÙ!¼éöén¬Rš+Í]\„扤¹ ¬:æâ�a‘d¤d-L'qj˜LÒ*MrDåøJ²ŽÚ;îô-— ¦ƒi k.>( ¢dÎRÈJV6eÆÃF=¹Ý¾ÛZÝc}cö7SXìO„¢ƒÈ½(ÕÔòú¦z× gÛB6ÃtcI°BÄ\Þv Œcëv©™_Î9!Å ¯>¯³G·V'Âlýo.W‚¯óÁ˜Äô †LÈ|]êßøt¿ÒwLß®à·ûƒr1Ë¥ïÌúsèBfÁ” Ù°0xTb¶ÄAÀ•\<—i>ÿ)ÇIò<ßÍbó¿õ›rÌÃË,bpûMAá\ò í 2àá7ýËGÀöõAþ¦úX.Ñ΀½ÃTc|Ÿ}ßIçï"’Ö¯§�ü°-Þ¿á£âÕ{ƒôþG›Oû¶Þ矘<úç°Žæ»›+ß'0"sd(Ì÷Á=á{s¼wäÙ÷nÐÍ{»û–ˆûï:ü`yçÖ¼„_ÀGøûJ=âX,ýØ=7>µW…–ÖMeÈf,M.’åÓ£ÏJ`"ÈΫìØáÆ®'ÌäLšš'O¦ò Œ&{‘ÙS (,2ÔåȦ²ÄV_ÊçÊ›K‰<“3u~âC´?Ù“ÔêÏ\ó÷¾û[Ô¥`ÃŽ]m| xéárÜú^¼/T�ümÜíÐÞ@<x¶bôŒÿlÇëBëÉÌYŸ“1F 8»•ánΞˆìÌ T@–îr¦“ÁœŒ|6¥bˆ}M¦…·v°ã“‰öF)'¤¤mÈ2^s"xjíónœóªIM¢ªA§Ý(v—èúDœUU1ëÍnðlÕIÕÖ˜F'Õåµ:Ï‘k¿2´Œ,¸Ýæ&9O÷DØL7&y6ˌəÌFB“’dÖ0à [%—£â”TÙñÈW9)R1è|¿Š)ã”+²œ%Yž¥œÓYHÄÓ$–²á‚x #¿Db•ç”X ›&¼ˆRÁ‘X—ú8Ý/„8 2ÍUž©ÈfÎgDiECD)ŸH®‰÷‡}WT6Q%C¥uX.ˆ5 ä.úÿÉcš/‚®<i­6ÞŽÖëar{»©y>u/íVtbØüšô¿®Õ§jyèò;£u´ÉÐI5šb/ OBBìæ¾²T.kضíúñæ£Ey"©´¼ÊŒ ‹#B÷DY¹¿KÙ\^®"FIVõÇ_Ì(Á=¹æ¸jæ×s½–X<ªW4UÊÐ-.C8ïvÝë#ÆTÔ tùØfÿ™"‚‡Ä³òªì¡’êÐvwŸ¿A\ ß½ª2÷èŠéq¡gæÈÂo±É%A 9>Þã ¼Öêwxx�ŸoŸ™ñbí`p÷”Æ|9R²×cc,þ„Ñýëµùsã:áþ†w@Ößt= ïê¿À`°ý^ÑZoCuü[’&ÀøF'æßšG½�éA̽ٯ�ÿNŸJè_"h`ûJ�5wXæ¸ó'×ÎŒ.DÆÈoA¾âºoãŽ2#æø¤À|‡†=î×GÇÀ<ŸBò²)ï¤|P,ŒK{:º%míÒøÒêQ€/eÉDP¥ù…,‰ ÞT¶.üCÍ3­ û4ÏoáÝ £U—ýº`}¿p7õ]p‰Á€c’²NNZÉC»°§ë‘è…ßÕañt¶}¨"éMÅÑÑåI²J,“as1îºkÕÑGL~¨í㦋y˜èøÛH?±Öl9Ý¥tG‘J=ƒcÍNw–…²ë £)Ky«QžPÏY–DÂ=µûaÉñ%úN:ìÌ“}áCÉ‹8”Áq×ßÁw™Ò„o—K‘­ŽÙ¬$w ý¢IàZrØÇ©¥ûÇÑÍMÒ¸éRnl°-5ºbÁ“$gV§£ÉŽB2ïbæùÄ—Cȃ-÷Ò„|b„Ë@ÆZÄ1f¦8”ežŸÕe®ë3Q1ÄàÛ1 ©£$G¢ÌÔ|*�ãš*ÏKo†1Ñhu^ø§£œ% 9UR2®OXpczëG.¬‘ð4³[âG 3­:Š® hCÕºp‹ ‹$##³CÛm÷Ó®¿šôó05ãúÅøìb¨V7Ùì 4wàËçûOnE^'L¿—{ʰp&5̳ ?²ùa…L\¹å¯› >¸˜ÂÞmž¸ö„§hÓtŸ~Uv-¶3_ºµ–[¥FFWÙ¤ÌD±é¤oèAfY:ƒ:3<å'†üÕuú¹ÂN¥z÷ÖßLýò8ÎgÊZ^û¿bS’:”IÁ„ògùn¶%}"[ w¯5N‚]at;©é9ÂE„Ù ›^Íây]4€ÛAî^cÎ?&„ýþuð.¢#¤Å¹}­½JÞpï^?®þ¥ÿK8†ì]ù×jˆþ]´ï¶•ÿáË»ÚÔ¼Ñùa0<~Íd�æ@ ø¯[( pûC¿)Ì n4Pàaî <0¥Åâ X{,ã“Ô!“g ýd‡™E%zzœ ŠÇ}2«B‘õ¦ÈZX":šnÇbc¤®ù™;*#ù´I¶hé…a»Ç 3dtK/ö£‰ñI·C¹]DwÞeuoJRë¾6R¾¾fÜ''EŸÇÉ!�[ö˜Šó}¸Í­5%ZTî†Å¸w_L›MƒrkO 9»[ÆyÌ 2Íî¦iÎíüÃA±!q×ù½1»f¹›90ëÒëÎ킌ÅHåÀ3NÖëüyZ´´˜t«¸sûmߨ†-˜':–©‹LÌxȸJY–ò@$M:§õynÀz(;ÛnãÃ~Ìfý°ës?#årq-cIÒÇ‚X=Œù†<üðˆ/iÃ7b$2¥”6òrŠývØÆŒ(þà¸:®ŠlN–gc57lž±@=Zç'â(s"Ãe318žÍ¢#¢Èe’.²eY.qÜ1¿s9/âDˆõJÇ‹•L9¯^xæxáfNÇ~gM„(©"· ÉH–„“çì(1’"æfÓŒ„w’`^EGH£éØ»*ÞIí8öœ6GTÚ¨ØÍ£Ÿš½¥Î4u¿©Íí®¹pîéœ9»½±ãÚ¦9X†Ç‡þÆß}l¥JþfÕ™èM«1PÐ9Èh(k,ê#±Èö’` X RC¬`V·ÞÍîªE†¤œ9.»¶xbW<[XmJ{Ť/ÝÀÖ#n:ó¨ûâ8|¸R•ú«.”ÖXLÖçðÿk²19à^ÍÄ<Û`°lj&aƒ´§lH/È–ñ:IŠ,Öâe½ÔûL§†û7x›�np œF¿F¦w2S?Ê?Àùž•Ðùw-ÒÚ«ßé‘ú^$*ùa4ãÿ¾á=”©{€>{ïd·?åj¾ñ Xán„C°ýn\`Þuùw3Ž~‹[‰N ±Û@�Pv€D|)¯§7YÖ#ö£ë–zZÎyy 6W‘îõnãúkÐI%â ^~.(9Yåu§­4ðx©qrt0ÒlºôY?!³¨73Ú†0�òc$û—h¡ïŒ÷2Z“åÁíä”g«R'§ËMþï:Û/Íç;`…]¡²„Š‘ÊÞIµSÓs’4ÛImšãðÿpSGÈîeæÍg]ý_ +µ ·,ŽSLwÛ—ã&¢\W¬H^ÔÉFn7œZ–” KTQ)‘ž²›)¦‘¤ aý<iˆk"³3æÇ=M|Õ{JzÛvÚêJ°ãì´:Þ¢¶CÚó´£²†5c¥“ÁÛƒ1m·ž-ò¡Â6Në@ÓPDræH…8(Ô)Ò,W“à“Ó{Ý’®N`£&HÈ"°CNH"<ŸÇ›C¤I&À¤g4XÏUä(ü „N½“©Ð,åDFGnJh)Þs¯úqÕŒ2–Éãä`çѸ>²`©&‚¸½Áv'傊’§‚-ÖŠ02½‰®vDô½l4õ|è†xg®e£Tâc[Ò ë§©þ§é³ÇIJ ‹µNŒ’Ûùqy»_BÅV”ýy•^ 0Ö§ØTp$vò™"Èê;<ϦqÉ!¤”ÖLÙ‚£,ý˜Ž)å]2÷‹±ëòøW“Ñçõõ²€JŒ`˜E×È™I-Ëù‘írÒJíÂ÷ÄÔʼ:x3ü÷†-7~»—ÏA®±íÁ¯ö¸ZÙ'áÙãäô»§·+˜–úÖôk³[Ç@Ü‚ã«ÒàëCšôï`¦-ì›4—@�wï©t€ÿ&ö|ó-®Ì÷SžÞaúÞHÚ{Næ]?bößFEãŸÙ7¼Ÿkeþ ^á·é>¾XÛoÄßÕ7âëúù&x{µx%Ãrnpg0Ø!¶¸½O] f/±…¹#É (kvnÿ‡ä³EEþ­ãs†³m!vÖê¢~tQ©Ì—Ϛɭ]˜¹muʺÖFÀ|zÿ±·Gìö‘Zf«1.P$×)òÚþ·O_q¾24'ÒSõPÆ¡ßýö¥Y 3p�v‡˜øƒ]žYF‹ÜÓ¬£+ýÿœïM›]ì£V¯ãg£(ƒ°óÅ2) µ½áæ¢ÚÒC\”'Æïá3 &:Ìž•‹Ÿ’Øn;\·%§×ëª:j½Èc~ØV‹<$#%Ÿ÷<ïø"ŠGBä‡!&Èy10×›è ·’Ö“±ŽU'SrBØÛòã‘õS£å—8Ñùì‘ç 5”r'eÝ;çì"߃$Ûi}ŒÃ.%sMeTµ·/İàâ\‘$6µ~æe†È¤ælˆ¼`Ô&n:t~ï5zj<K Z,d’T™•!¬Š9·RzšY_FRø8#à ‚õTB #RyõzŠÁ½œ2Ç‘±ŽÏ·«¸IÆE‘+Ÿt£«‡~o<1m°ÛÐ]ŽT(ÆDRUFQ"¬#;1ŽèÆ×½›ƒÖbÔqcü–Éw³ÙRdl÷³–Æ¡eºöƒÛŸp&ñâÈ6M^Gß’~VúE2»J.–9úáéˆ}Ò£{r7"›Kþ“s.0,¤>)bY6wSìô™Öìy/-C8:µU¬Å ÄŽ$x!SÄÅeRu³Xy3 µþ¥ / - ŒÁ™ÇRÇ”ƒY¿‡®ÑרÞN´Ökа€ìצ_0P_ 5h_ÛqöJSad€ý–yïj PhhÀ¾Æ“g@<ýšo2¾6�?¢]+¾M¢,¾!»ÿ˜öó†cø@¢ßÄT~ 8Ž|üýŸ:¦ôϤ,H€øcŸÙ×ñÅ3àMI^—²WÀìî&€™tëwÝöæí{[`ûú§¬ 4€L1Uk€à”áÌ>_<—ã˜éŸÖµbãèJÄ~6Z­ïè‹“=L2ÍÕ ºËe‹¬tähnãƒZxØC6Y‹M"%f5 n˜¾hpTãà©“×Qa÷zi¤G²öuç¾Ìü‰xù‘ú\•7,pf¦OÁnoªºóuª/ëÊ C“ô1;.å F —èg4C\dð>Çî̬R#Íhè,ƒtMƲË\¹Ë…“nœ‘‹_ÁFr;Z­üáN/M‰³l0šo§©‹×¬ü-üífš]R¤FÃ5î6ôÂr&jK¾g¿nÌ“£®j÷™èôݦžFv“:]^Àåíý ö¶›-&HG’Ò¬òA.¤ßG±±rØ«cù,!rXVº’ÕiQÛz£»^ÒB‘rÆÒ¥×‚hÇy`‚ÜøR8ÆC¼ÆØäHðQP¸ŸD´!†LOZw´FePrP# /C¢ :>´^ï‡é徿Ùß4z ì‚ÅŒ%3©ä(g“½‰þ–îÇÕÞË'ΖŒÎŠŠ{1îË“¥ŸQ*\,/`D'™ù‚þ,N$Ú¢wåQe¿=Ä [¶b¶.KVå2ÀwÔ iqä÷b–þãþÖj¼„ä!‹Ó£;ôÓG f‡ƒœ­ïúÛ¤½‚²Ù!ªöþúƒòX ãÌžìhq žÃ¦òwÙØÇв¹Ë~WÈqŽë‹% °-ð¿~o!o±;®c†ÖÁ¢~›G$¡Wвº€Œÿ¿Ô½é“Gž%öÜ=ÜãÌȌ̬¬°4=}Íh´6«Õšé°•™LŸôÿJ2“ÌvfWc;KÙìæ€$Àb!‘UyFdÜáî®UEâ(€d7ØÓ†0X"#ÒÃý½ßù~YÍ*ÙÐÜ·If˜,QI\Þ*`×�‡ðñ¨¸>õõ ø·fäK¸©î4yÙ;˜F¾3@òî ú{±¿œ?áüiô?Ýe¿ßMy ]}Çá§öö¿—ßeË%€ž ì_móæ×ñ·USwf;êÛB(ž@¨@âNÞÿ?‚8 èŒ×xî¶÷ú¸PÛÆÒcò¬Ù£f¢iå ƒÌ“™l³{ØRüU ÚžÑ|8²¾ôãqçr•—�� �IDATr쪩ªUsuãïèGSl7XK«Qƒ{pL_<,ÝNùO;(Äñ‹´uÒ'RëÎôÝvŸll…N¶×éú‘@u‰|—EóÜcÏb+.K‚Ð=M²ašrÀvÀö Piýô¸Oèþp˜°mCÆ[ÛrÐÄó‡¼FEÔb[[·×Ûf¹¾Zÿ?R{Yê&‡hý© ¿ÜxþV/¼Å�ƒ(:æ.ûÄ/R4ÿ™õª¢ôV&ã†Ç36Ø1½ŽÊ¸õÚ ŠÒ.Šû>öÙ�åM©ÊK¶ðËbˆ œ0Á…` ÌZ‡øþA8ñZòÐ]ÓzÄyj'¨;¤¢]c­&NODO©R[ÒwÚjE´c‘èUW»´Sš7TMe©¥C꥽å~gj^ÎûµØƤµ½\§W»¼Ò#®¨£¡ãù\´}_Jõ¢N÷bŠç6ZðVrÏ¥í F`øÈé•$uÎvÖãa3rt9Ð&/šÂþÅÏ„£âñr,R®‘ÃÆbܧ!?>/1]‚{v0d?£GϮйÉ7N29úø±O9‰XD¥G»LJÚWôâ@hÞʧZM”‰rWÕKNàC0,+œçuÀ%  ‘!æò›�ö!2�5„†dKô÷q©¯]óÛƒÉÄ#hÿ¾Ž‡|#ò‚jTš”º«Ÿv߉à§(o¥­G¢3’÷0/¥*Ó…Õ›4õk…‹ÀúmïzhïÀÈ׈¿µZémAõémË{·¿´?á¼Wbx_Š€â½%Byz o…Ìÿ úmo‰à© Ùv/·y°?l¬ €ôzË,�EŒ…ƒ Á1ÀSðQë2]}hÒÒ8<bìŠ4û”H.q,ÁÁw߆|_ý6ƈÞ#Ž/"º]=³’Ñ bm™›U]¢Û �\õnÐlL÷Ô“ð€àý#¸z¶Þt‹«™¶ÑyíAýt, Q}qN%¢›ã 6×ÑÝÀùM—wÎÕg§£ÿgr O�DtåéziJ_rï(ŠÏY£Xîê˜ã€B¹éZ5›ƒt—ùæA¾#à¦Û¦š¢¡ð„R%W¤oõ.Ûió\ì‰ìúŠŠq[§[ާR 6=ùïV‚¹îƒC\%a£”CjK§[ÔâÿTÁƒi€Ð/€W$šËvH|:âa<˜;H¡ Ý�Ëià2g-lŽàtêGN¨.²V1h—û‚‡´ƒªœxMPCmgôš˜À•ÇX0PÒsäÌ¢…ÕJ*ÝJ[×%à´‘m#­’ˆskK‡8û.¼l…ìÕ¤H^'x×5<]Á#]<yÞo.¶tÕz÷XØSW¸Ô÷z›wâªt’Uî2¸ÆgºÍÚnI% ˜¹àÒ1è¬#̺¯¸51oýêDª\ ŠS}…¾kš€×C±ŽÅ¤F°rU‰¢¼!û-¯Jä y‚€ÖÂ5mD‚{ðwࣸ†ç~ê±'=H†<5´’Úø°qZ8=6û†:Ÿ×jɆ5†Ïˆ€ê±«GXý«xOL‡^#߈̜û@ �H‹§-dˆ~t5>(ì·õð„óUÐ¥(ó y ¨®~EÇÂJÏ›OŒì;,¹€:­óù7FÊ×ëP®£H#€¼Vú¾~Û±Í�{§Í÷­jÞKèÕ©~4¦¿•Žõë)îe‹ÿY?7üÁ}Ûâ§ñ­nÃŽ€t@õj«u0 |—†¢¼‰ÝĈ€…œ›úå—ÌüàÇýw,Bpn±,ꊞÁM Ž”*1§¡qí¨Ý^ >IcÄ•›º 4è<^ˆ6ׄzø æcï¹ìó¬éÎWŦ68øæk8ÁØy¦›´Ì€`‡º5”ÓlF(Z#ÍÝaªP ’Ýv"_Ï¥`p´¬ˆ�ÓK·íå *¤–}‹B ÕòâyZÃÉ#Ÿ¹Î¾êü:m%&AzLá¤&ÙË š ò´ûL^¦^Fa7²Ä>¤\ï·—îÿ­ø‹ö(™d{Öº…G.\õ9½:5îB¦—qÛ«b½×nÍ3î3'_«N&¹Šùª`WíññòAäšä^ãO£Ÿ¹ÜrWª¤~À7÷‡Ó@ù1;»#ÏŒ˜qMïPÙ3£©Cáx.«¸uਆ…¬kMO¥¦Ä e˜C5aZICjB$Z¢2Ó4Ö¨Ô ¸ìt¥4¤Ã3¡·ª–E>ýªœeTìäØË.ËZíZû÷­¿&ù¥\ÞÎÕ¡W ÖZxV8>)•Ìeî(ˆb; {Ç+BÊIÌ·Ó¾ÓaÛ]¹í–1·ÌŽt§81ÄSylæR1¯›¹)êË FIÇÜËq¿ R韷 NÒýx o¤µe¥Šòà¸e‚+å8”ÞI•™K]÷Uw¯I7rUÇ'ë€AÔèPdtáï|�3ÄÏ4†5b‹HþbHOeç×é‹*ñÍ<ïn¢¶£ëRÈçÀCNÐ5p{4ò[t€Þ8h/gRÙVÃ^Ýܪ[Pn€F†×Ii)Aç0²¾©®~p{óÞÀíuö’jÞKèWý$êFÕÄðcïò½Cn~˜Ò øæ/ü6GÞW„Jöæ¸îU©í×Ë�èM…Ý[H´t‰úiKü6 ¹/ÂÚ7÷ºâ Ƈ.ÑîQ3ÐNGéUX#HÚìr ñ³b¬‹U 3‡xVÆI·²‹´ÞËé`·®OÜŠÌ¿¨›ÍÆ" !$È#¨Æp¹ ÓN@¬À�_¢üTö㹨§h±#P\ ÿïQ3~nî/T‡^ ÖJÛ@-F—8E;‡ýŒKQ%çØUå ¨SP…cÛnôjE»4XÁF¹KT1\Re;àåb:‚ë‰=ª®>즱/ºÌèË^´Û|wçÐ@ñŒ×q‡±{œ1›7»hx iu�nåšó¤ÙÝë7þÕ´Ýûžñb˜j¶n¢ú“€ýSežÝëD¡;옻Q÷}y%"¯BÑæ8A –í­[8fÖSjz ‡8¢0¼UyÛ_6%]§ŽîÕÎa1gäJ$]gˆ2=HÊ­'Wý•’YÙõ= xãkP^p£u½m›®¬ªEá¶Ê¯„qHa›¥)¼Þ‘2"¹ß¥¾»ìÍåÈ=’´óú!™Gæ˜Ë¹!½‰xc­¤f_rÙÂ÷õ‡!Ùr²™ú¿kIÒö(³h.»d8PqeÆÎ¨¥á¦g{8Ôõ>h,ÅGžd?x2Êào±l«åð@ú)·cµu‘ESúÌKR2¸\‡ŽÄ.”©wV/”Å´ú"ŒÄ•fýJæ^Éͤ;Á‡§Gz®/¤“c4÷0 q˜øA}è·.X³kÅÓœ«°¯“%v�‡GáwÐ;ˆôV±ÆÅgù5tÔ7&Ý6þ¸oáäXlä÷ø÷…@Û_Ïìzz¼ÔÞLÿm…­ø П½½-Á}yu£ü½Ùâï¸õO›‹þ±lvç/”·ó™ßO¶ÃÞõÉúÝe�×Ó: ÀoÑÜ•èžÒ¾#aÅ€ê[ßóöy·%LPoYœ.Aw1CK°gÐ'Äñ÷Æ¿Z8'}ðK¦bŸx°ã ; öï[v¨¦ÂeB6’Ú†}ëÏá®ûìavh�"6Âë†J®5.·È€ËË>thGôöÓþJbÌÐ1˜¡"ãóÃEߊûåoÝÕølë€V§cï4{^g ¹rˆ¥ €˜ÖNìîw¤I»ÝDtÛ# ¶ëôÈkLŸ¢·( çð9ˆ+[!MCÝŒ2¯ÖU–vTãC‚‘Eu6»øÙÙnÇÒóöUßÁÑ‹ž™­IÉö"ôg®‘“Ár4ì[’«¦ÊØnbâšLÔœ‰`MgQ?‹e˜[S¹«” pŒß÷Ö^Uú£”€K]Òý%|"©ˆZ½gm±×þºõ¸²Ï7Õ×/Í ÚíkŸ«üàÇ$)©¯*-úº£U)¸%Ž›“ÖͶՒ"¾m™÷m­+[4©›±É§m&ßy!é‡=ñWšm= ôƒÓ§N²$Å_µE'm:YéN®&®öª«U7ßú{ÇýkAø}„Cù;߆Î 2-HYô‡±EMúª}zWóÄVÿÆŸzîà1u]A§†5­›x&JÏ7>ßYÖ(ÿ!Ùz3{˜Rÿ§þºR±äèòâP·ïd@jôÿ[0{D‰ ä_‚ÿ¬J_º§Ö< å½Á<²A5:QÉF¨üß±©oÞ­[öeJ'ªÛlyÝd3`ä ו#æõ òÚë 7v÷wÇâ¦Á¸ZÌï6|oN™4x€õõ†| àÕª;Ð]ÞLžïÞQ9y­úy¶(œ.&ê7ŽÞ›ºÑ;gáÈŸÀ²ÿ ¹á`³;?ükÀ>½«EîÌ´¼úIvëY¼YÚŠ—МIx@/ßUîæ¸qŠ_ºKñC'Ev â‚À" …–Ø{W®jvò!!YT­èUë¶`½7ñ‰õõÑý´-vË/ŒîL*ñûQe²†'±6 ººÕp%\ÀÅSÀ-à6‡.täæÈ8Ÿ»l̇J5 Hráuˆ]@G>º?+suÀ­+GVæväÕ!`Ñ›þ<‚çÂÎà¸þS¬‚ú¨¶¾L{@ 4§ªªWfÌ[€€öCñ¦êš“¡Š7y &ÀsÇÜ™Ñ>!ÖñxqìÚ ­§þ`ç·KJ¶t¸¿5 +…“ £8fªR®©´Ÿ)´c°Ñ•þÊŠ}̘ԕ[®üÆw¨›GDW¶±¼ôxYU€#ý ÇUB¢®sy¹qÜ?òhýu¦ŸÜI)5 k„1õšÞ5R—ikì֢ЂøyU—yãä5>צaŒŠºE×ôå&¨¬ÏœŽ¢£:‡l¸¯-×:蔩6ðò öºaÙõ•Ó/I}Êtfêí²Ùæƒ&ÙÖý꙾çKçù>Šk™ß7“=êõÏZïŸi ¤ë+ÎÝöR¸÷}ËÃò¿œ O -zwÝ+ŸÈHz´ÜŸ–]Å–²ñ²¥ÌÐÒGóÌb–C¸ïImžM½ÿq“ÑCXîMznÈÅ}=Т•òXþ_Óý/^Àn£¶ïÔrØNÍþ” ™l“Þû1a¾ÆÞʼè?O{”ÕÉx³'€+meTˆw`íM-è;# .àCé;Å7¿;e͵óÝ¢�ò–<€¼®¯MG ?…žß(CS€¿v£ÏÞõxƒ‚F|Oõqu�Ž�òV↓™ ï%}=‚Gþ`xv¯ãŽæûØKÿ0ªÓ7ý/ﺶ¸þú@ó·,Îàe'(žÌŠ oü×O×µF¸ž;óÈKh84 !Žéls^·KW´"™Cu+ ΗžÊ‹yð•ñÿSá#‰S ,°(q<ÅJbî"0.X‡)ÞN9)á_ÉF®�,‚Á‚Ôg0^"ºDô2i)”Î*‘-‰�á€ÁÕØ?E!¡n¥¥Êsð=î¥-AÄ)U.™@z-i\I˜9¬ÜíÑW€ðäë=´«Öñ³Ë¨r#nÑ]î¼x4p’ÒF' ®Û lîé…ïGº„øj•ù‚ú¨§ iÝ·¹¯ú|xô±cG¡"¨24ÛŽ~ÊÄ/‡zGÚlFL7ûÙˆw—4JE…AÚy.© €c¿õÛ²1n*ß?³'ëðYïÊ R§¬¤c¯è©ëÍû‚µª+³Z#¼g/ÝWeÞ*ÒÔ÷…é¢~Ïû]»¯öÓf3Њ ‡w’éNKÍ[Ç:éiö)97eµ¯dQÚy§ú¿Ê‚1Y•xе¹â,E…_Œ8’Æ«¢«¬ýl3TõqÙ YµoLKÛt „É(wŸŒ¼9BÜgÌ3ìjÛW #À0BZ/ÌÚ¿­åºÿ  G(Náî€'‰•ÁÅ>$á}ÐÃ?lxk˜á$àÊ='"µ :3rfÿ;ìp·]éÐE\ („³®ãPñA)‰×6Èvz£ì'ë>-`éBX$ÃÓ½`KœjùŒ`g àê``Aº;K=Þ8eW7 �3ÀÇ·ª;{ú¥opïT²“w±ôEz­ÊüÓÕ[öØË·‹Rÿ¥Í}ìò†ÇÀpÛžöð% U€û¶‰¬o]ÇáSœ¾›ÛóèZÂÌq(±Ã«£ÛW˜½’yõ GhúêÿmÈߦà`ÏJû¸ëo”ÃD·}j¾R à§CŸ‹­×ÿ^" ü±;Õ+þûÚË ‰�‚AÒ—kõ6PÊðºëÉÙç[ŒkÄ%q|6,EP † €¿Ï Øâ 80½î5 Дò;±©ëVÁãŽàVÒªGÛÀ}(àI4@ 0É`+ &1އ{×x^jûª"p) BØá=‘Ì+Gjë¸}gµÒÔ(¶í«OTžSáØÒ#º6² ‡UyU¢Ü¢y¶AÙlj¦^¶!lÚpÛ;M씂(ÛœU‡6½Wnã <Ç Ú™@V:ÕMéåÝiUv–.¶æÐ1^•Gu®<â0á8‰[²Žµ-i[±éÊú°Õ¤%V­B·óp,q\ ·û ­Õ-®bzÑåEÉ*B¡\t™brPsn­£–kûÕ¦ÖþîPÆÁ”Ç•È~ë¶p‡Ë*r~ D¹L™>ûmHbê¯}áûÛ×yEÅÅi 4”ƒ‡žEèÆžZ¡V†ÄýPºĶd}Íœvlw•[‡½„z=Ã@ ™ ç®R]ß”_÷ˆuy*£)éôd áZÖXº÷{9ÓVkÿ¡ (Mùñ• `³¼o~ßáaCïíéÑ—ýùÓåךr÷È€0Y“|Ž!ƒ{©?é6s [Ô °z›ý+�)œ—ÉcäßUòõó¨®ýbWBÜÆ„îÄÖæÚÞé¦Í9è×±ä Àí4·÷¢oÞ zQ3AçãµW Èn£ù/Sè´\˜á¦‡oKS¯c�ïµúµÓë2�ŽLMnešÞÈx쬃µ_#8B;ÇÒ‡ÇQvð–ÏÚÃO@>‡~hv­í”ï—ˆÿ‰z÷øì$–‡”$µøuyú÷Ϭ Ý)›§ZbÂtXŸç.¡íqÒ ¥ÈŸ·ûG€K B.ÃCÔu±Dö(„Ž[k=„@åÀ`p|I ©òWRAI�µ§¶œ³ ™B – „§ÍÉ@´"Ù³®Óûæ7i7€ þT÷€b(SxSÐRBÁµQnêj´«Ù‹ <€w€À_Õ¨²sÛÁKD–è;W ÃãA’ëCä™W#)Æ&Õh‘yésy˜C^œü‰5 £OHîMÝ9EÛ]‡!“ÝTmÜrÔÙƒ¼#)¥ÝRg­ô¯ÚNä²qtE¹~ è«Ö.@$©½£ Ü ã¡-y·Ž—¥ý’NÅ‚…Ik´¡ó@ÿžúIÿ«žÈÞôo‡“G’Å…níAŸ{†ê" i§Ž¸³Rºb&Ãã‰8fdÇIeõ䲨lôÙÆ~øÉŒ[Í7[²µ r…­Ã HD=h˜Ù¬95©¸B ¶·i?½Š%ŸW=O­ê2ÎâU©%\Àáh `<�~æT}ÒŸ/ÙËŸ�¿õËØ£žWp£xé3VêRgŸí:Wí?l÷A7Ü?÷dÎ}#½Œ#$“:ê¤sV=©rW¯ªsÕÑ4H6¹óûµàR×tÚ…ŒñÔ…4ä»v¢WIB 7v7aÿÕAñ¯Ç�Äãõi[Ì«ZÞLںÞ{Wžù-Æß+@|Ûj—Ü”_RÜùS…è xu¶Ø_7üÄ}pù-ÏO¾µèß…6×S=Þ"—dà;[¿¹×5�suz î^¢å·¹‡°B+±èf5¼ñø@ží«¸×kÛµá¥!ÓŒ:}í|ðÀ¤µó~,ot4Ãæ h å¾×)ÆèOQÔ ì?„éùC0{€Ô´ƒd¤Ø+Xç !€ÀCÀ6À“pt-“]1G*Óúö fr#ˆ±óλTÖµckwÝ{å`¸Î2Ï—;„/¶.ôJº4’Nž ¾=øs ™^:k÷ <8DÌ9•Çt²_С #â×â¬_>‘ëÇý`¢–ÑPvºrÙ5¿: “4ŽHj–í}½ luvM\-íE V¬>$úô¶ inj½éó„kÑ)þT‹>cÎ,¦Ûxv +ÊR ÷_*–PZúNÐû¶·{~ÒK[†_1ç©K£xÿUùJeï-¸F?òä‰dú ¹a*ýô¤¯‡úñ–Zu”6Cº¢Ï!Û^Ú|*šFû|¼¡ÄÕ»vø�€+žö^oÈ|lF §]›õ-Râ'Ý£-Üž–2üÊz]Ê3SNâÌR\N–ÐçÐð¤‡=ô Gžø%ôMʚ‘P-ˆFD&fȉ1_ïw©Û kóyZ”Ûu‰ååj=ÕOÈk‚¨’ŠÃGÒx¾å !i»Ü­=y^Ò%tW$%•U¿ =Û§¸ü …¸„Ìú¦¸ãeI‰W­®âÕ³f¾;'wc¨æÈwŽL^¾Cœî¿ûªoóÌÉ]hþ6ãïml‘Þö¤ï�å»ëûŸ bŸŒN@«ÅûX»í{Lu©Þ¦£÷îwv[Oðª–x)””½šè~û �}mïÈ>v7Óýp dp*púÿmBµeŽ%#¤GXh8çIòZ$=ž�‘h€1à¤0)LwÔH—·–i-à|;ÓJ�U`DlëÀ¢Ÿä=­Ö]z½Ï»ëýnÀà�Ä• i`U Ýâ,0h×ç¯E^:¨¹L¨ÇÖ¡q¥ø"'— í'½¿ì'èfÅ~Ü“)¢¯0ž:N÷sóD,SÉÏç񴃮ІD„¥tkSwŠþÄ“ «—mþltªŸÉ'ùùr‹®¼²#nŒv郥œ´¥}Ö™²OU×DÜq‚î‘nrZ~�ƦlŸh2£ïÉz–‹#^7­¥Üìû ÑêødÝ× µ4ºU½nZ‡¹’9/ú÷þÑT íy,§èÝK¡|ZZùª.ê–¦†0 ÁiãÙ±”tè:í/×hz:ÄPùå‚u{«QŽˆtiûáÓ5 òpè5Û £¬ãpÖ oQ˜C5W{È]à¨A“ïJ÷ôâØ+"çW””0qµ< ä¼H%e¬ '˜l´ �Ûð7Àh4ÂbT£©ÁYNêv@ÛK#ånÿ/ŸöÞ$¢ÿ4¡©Ȫ‚Ëœö(3Q×r_áA|–&¿ –jV;ê¼dÙ7ùÕfïãÅ®ÁØ¢q££_£O±ýìz{Ô�óÑË—§lÉïGdóŽó(ÐH·AÑIþúA–ùëßüpv=ëÍos1ï~ž|û™ó?MàåkóS~ùOÄ ?¤ïO±v�Ÿ•¯=Rp;äõÝWõ]Æ"û!ëàJxsìå[Ù.�fh é4 •&@‚6Á@‚a ï™í‡èï1,‹ü>iOØ“f^C]—[¬�çÚ©:ÿú帕ÈNAçð¥s»Ã6#ý#” Ƭo„‹î õùˆ‹qäƒ9ýØÆg(7E“´8àÜ/Ü‹z'@!C`6�w ÷P•Þ›]h79“-Çeú ê ìÏÑOr×À¯à»hï;5kXüDZ„D -ÈÎ\.³’”ôÊsðÁC„¿X™ˆ:;ݤöYtaÅ®ç«aÕ`õÄ„ÿ¶|ÔÝz›y ܇Ñ#ÇlœNË/GºqÙƒl¤ºa•yç-§©ÑNzÚ‰¸t˜l4‚f¶É?S½»ã^;_\6Þt»&gÙà¤C7'VÞwÖ‘ŠÓìƒçZÀ÷ƒ^øuÿ ºnÏý½U_DUƒìÈÎT wQwæY…þj—ºõ8þh¥í¾lÐhÐ%3nýÁÆ3p»È-¼Ø„rÔVû•Óä¤:²©s¶o"š­c¤¾@9í »„@¦äN?p¹Sow¿[êK/7§9LÛ쩟FœŸaf&Ãúz‚Š£XzøÔ�AˆÃJ+—G—_à”÷\^£ÇƒÏ‡CéSîš ¨¶ZöWt/r\nš‘úå)ëqÙkw¯6ÕJ,Ø@š–AÊýDÀBÜLŒO�¿ÁþV´ÎB`ù‡N4ø5àâêÓJËên¿ÿÍãv£è÷æ!õ »?�‡˜×ïH°ÿ«Ç]þUcJïþa’c®þŒˆá;WßRBý­ÿ#.ú×®|­%b€‘Âi{íg$À½ƒ´¹Åç,E$‰.EéqÓX«'±;n,¹hÝB<WmŠkuüßùˈúúægFN Ê[‰Í°ÕS¤Á »ó±`®Ö1Çž#-p úäÔÒÔߥ÷?ÀÂ=ï%°.Ò5Cì`4Õª´‡´@�=¼ ’ˆ}qÚ’y½“Ý ®;ÔŽMA>ê«ýtAhë°y<˜Ä'¬?Û/]õ k'_à°}Ú%Xý“ûÐAN&޼˜4•¸hµÚ2éØj¶Ñ0Nâaja·"_b@œˆpêeÔÆ­7©\Í‹ÜÕÒE—«í³/ÔÃ)q3¯:UÚ/Ƈ_Ľ”æWCM¬õõ iï¦P¦‚*írwàÜs”hŠÁ¡-ÙöuKZ¯.'nulYµPùIãøµï3N”¼¯ehm&ÝÂÀ ‹�� �IDAT¯©ôùÞ"•g?ß»z[/Àæ#îÇí@–e5 ôsê\L|WE“«¢ä™èþÉJ$øŸzxbll@ (•ÄÙ¬äQ põBn,97›sla58Ð)“”©o#PvJã0œ:µåÞ ç ÃY™í—~ò¡Fç§°µ¤K_C;8n�“;ÃÜk…ûa<tØA3ž…vÂrx‹åþCU‘¦$Ñyç%ûÌ>YºÈª'¾nÙÈ+›‡m‚ɬޯ}Óógá@6[ì€ p¯ ¿õMθEåô¿¹-nÔ? UÒ·µFïÿ84Q,1üë›Îÿj¹è÷C ÁØýv}óï¥bùjØç®¿3ì¼2.hn;³!Jà€S…S�™ºž?z“Jñ0ÎÑJÔ@lÓÈ9úV€ÉØ9wFè² °‡ˆWPíibëT~(M<œtb ¹Ž!?h0×?µ© [5O8$™ V.6éµLÔ CÙML^ ƒQÚ x£³2#Ø!8ï꯿Äc§÷‚ =ñ#@Ÿ E ^JóE)éuÃa$À÷é¡GÆšîºÖÿ†èŒnydÅD5e{…%X 6Ð÷‘LÁ)l ´&Êõ÷SÒ^ÊfY` G yP~ÝŒ&à¡5Ï«dŒÁpãèr*(c¤-QtõEÀµa—„Ù×2Ϻâê…cptõÁ•nç—=ƒc­Œu\µùŠ»E[Á!%£¡·EKl…AG­’ ìÒ õÜåÛ‡z0Ól¨)UƒF$>xé¾9Ø»£¦cãr½";vGyh:‚¥“iôÏØ<±âäØ,r ¿šé¾&º©sç]Ô÷“¥–_“ñ†ƒ§=°b.ô ÏË‘1„ʱ"HœÍÄ4 Ôš«xßO"‹^f#÷\‹g| T”ОóʶÙÖôEõÃ$R )?*F‡ÄŸÊÑd9¨TJíóU|ÑTŠ\ÕÓ1N$¼YÙ|“4–>ÍqìŠÑ ·ùGb ¬€îVب˜ ×°õw‰½ò6É›½D > Þa¿.ndïÛŠ}#À/� ¢_J@¾ÑaGþØQ=òý ÓÉ¿<nx?,�b }ýÅØ»éáOBÅàßñHw?ƒ¤€|t-¥€ãXÎan…µ$€à7À�¸ö0)ºjøíPÆc©C¡* jc¯Ï±ŽPlî¹Î¤ö‡ÅÑ‹À‘¸H´r@B|ƒÇI÷ÛétB¼làb‹' örRJ±ãË7�›{°Zä{Ý&öâ$ˆ¡‹3]'ޣɾ¬)P*¸E8u :»ßìÓ¦a Ù î@‰™Æ¬Ûdfƒ @Ç«©ÊRxEl¥ùŠ¿Ý4@ƒ¶�­0À•U— àtî4çN„g®ÿ×äüÒ£O?r”ⳓ5óæwãæxHÃu;¨v‘­‘yØç99vÿ$Œ MÖ£:õv¨}xÐö ÁÎÕOX»ÐΉ)› ¼ò/ŠÚ;˜M(ÒÇH×ô42)ó³ÀÕSÚeWº|”Æ÷w­æõq×XoÔ…ù“F]ìLœO ©÷‘ú R7áÑñH&Õ•ÜÇ 9 æ±suóRé…1 Ñ7B_>V#ÁE¤†9WâßÂ=jÑlã«ÏJ½¬WM?iêÁg¨´)@æ¡—B¹òª“À\B8Ó½7M&„$Í“õÒLÔʹÞùì,Oáµ~ûLì JÀßmk$z“òÅiÔË®(W’I`#Û†~Þ„©rò¶YLùbæ¢ßƒê„VÀPkªíV6H¯1ø»ö÷C¼h¶‡ì-z@èïh-†{[Ý¿ô/odÄ«bâ´,¿çÒ7Ïù¼Ä€½Ml¿AßÏ ñ»›ï…þ(Äsþ\8àuÝóðÃê·¢ð[ÚdÒ»»¬}@ÞÞ}ðÇM­ß½ÛÞ4n§Îa�&C“Ýü¢ï¾ç˜Üöä¤èDa¸¸j侉†[O…øƒC?„3ê˜ÎɺíçÍi±!NMªvaš³3 Mÿ ü–ãì÷ü±«b5òð¸¨FƒŽkÒ€ÎP6Hû¼S¸óé*‹)mg. ¹î½ü\º`yÉííäª ˜„Ŧ™ç2•:F¸Óßhn+/ÃvŽVb„ À(=áŒk­vÐÊä-2IZbŽ »Ñ*¶@q6 ‡Q8Jþµ[°a¬¡ÞCþ*í-(5d±B³Ý!1ÜDql|±òωó_¬9}š†ÝÚ{Œýq”Šî€šØø®ˆ<‚#!ŸrõI¯ËgêÆ{.ÖC¶  ¹Ü„jHÌQ,ÀÚöø%[ý]ß°jØtÃQ98úç:ÒVÈ_|¸J§Îéo·Ä®õ Q>÷HœÏC@?o؃§‘Ƚf”0=Ú.õ±óêÊo\Šî^ÕŽC²¹çnÎ[ RöC¿÷CiGKB±o^¤»É—þ¯p>ðúÆ/Cš§uµþ-Üî^II*¼út«æ²I5ñ‡û$¥fF³»r(¦¦í>Â69Ä™¿r±êïçíCùÅߟCbrý0’]ŽÏܩܦÏÙ×8gSbÐæa×Uç©úæ÷ÛÅPãQ‡E>…Iú‰ÙUiZÊ�ÕðöDivu‹¯_²Þ6×ÕúC°�È«^ÂëzsL@¿Œ? ë÷^oÁwpß þÍOWøcçÏ€NùQÂwÿ0ñéýÇßúå~÷BüĵUòíÝÆ=›úµ-6ä`.àw7ßPÍgDžJldzÑ-@Oªpþ]¨#ÕmìwN7D0¿Ó‹ÔíÿQ±Æ‹MŽàpŠüЀQ z–ç‘CÇ’èipòo7•3ÈéÕú2Ø\^8¦³£5Z„k÷Û\ zÇ^tjïÕ¤ Oaæh$4œeBB©È¾7‡³ öŠÁi«kÝΰý8¬åA€½~¼÷¨¬eÿ|“šœì %5É8Õ ; k€¨‹ÁY4‹ã{: ô—}ƒœ²¨£m_¢K!€¢çTTær’eM·Cîû8ðûçŽ:¾û«þÂÏïU¦êöƒQíêAÐÆš@\ÆÔ\:¸ÔÆÛ³tç$åûÉt\™ïȼjŠôjü|4NžF«Üæ¡"Jy¨O†›”#oŸoȯ³Œ8•£Ör)uÜ%5Ð?óPÖjEïbÄä”BwŸlFøù91‹b…~(ëà¤uÏV¾j̦iåGâ ‡RO°nPJ—ê³JòÓ¾úUBÑPÄ#"]kŸÁI½>ñ©%î|p&M‰Ë—P§öM–\–CFìð“E8;²ÓI>Ȉ_þ\s¿¸êw€Àß;Í}Óx+�8ãØÇHû£/qF¯f‡¹ùm³µ€½ZåH÷ÏÁ©è¹ŽäE2o kûç‚ã¨A˜@Ör½sl~=êêëMßÝjP½!%ôº1þz3ìGC Íõ¹{gÿÛÔˆó½ŸVxcP¨ü è¹ÜðŽ×ùbxs'½²²w%¯Ä’¼oÞúÝvǶJØ÷Jq|û ”ÀÀ=8àPÀ[C6PÏÑ¥7l¢e’‹áu©‡^,@€Ñg¢ïhðKe&ÞXݧ"œ}tU$—•‹bø SÏØ<‰ðäpÛìyØÚ&÷²¸ïMwpNSŒîzB<9ªcM ’‘¼¶g;F1z(ê_€åqþü¯è~覊cE«ç£ëŠÕ³üÌ ÕnºÛ˜ß–ˆvI pãP/0“ PŠê¸OÜլ«:m (b1òTf@ ¯Ä´FäHQŸ_•c×pJ}OG¬þzPx<¸jí®r�†B@Δ>h/5yB]Èíj#fÂM”ãúFL´úä—æd#ˆçîöœú|?³5 ¼+8¹ñòÝñ¨;Lvä¬â~žk|aG/êSÛÏ![ÂÓÊÎ÷-T#ÐéÏ|þUMÖÍÁOþçi$½H9¾vÞ_Ù/æÒ¶—ÿˆç¿Qð€ð¼@j1XRU+åHn‘¬€‹ 9Àó ‰Á¾B`öF6¨®P§�öø0ác<¸j³[€>›À×ÿK-Ӏà›ÙÃf6Ðíóö¾<üðñ½xŸ7Nf¶ —È+€â ¹ydw^'ÊàhsÈÒÒ%i1ÎÕÐ+Ûi–C]õ&¯¼¿Ý#n¡€K@"‰€6¸?‹Æ“¸Z介ràq: ÞA•¸@&¦Kûóq)äÐ…jqªò7!ÀšTï Å[zÊÞ*i÷#áïÇýwb0\¢2Pß#àv7{yo9«—ˆíǠߟaÝæOØß ß?¹ÝÄßÜI¯¯¬zÛk¸õóöõ>ÚÓõ·›æ®uo¥™nøãé­ƒ ^’ÿ°†‰…3Gu«$l¯7¨qºÇüÅ·æÆ|þÄ‹ dmû+±WAlœÈóØ‘‹®S=TæxY\÷ƒÎÛ ôâžAe¿¦Þh:Á£Á3ÂA³Vö6·³D7‡Îš=D¸4Ó“'Їû²6òÀ¤‘‡rˆ‚Jô€&0¸ƒÞ÷#¿Š :ƒ¶Àdè´£éÌú~]&«ê>y‘8[F1Œû™hd÷¼iŒ·ägvà¢BkŸ4÷°%ÊàÜÒó}“ŒéC¯ìº[Ò9Ç#:Üð–ã$?¹ÏþŃÎ<9áb}Ðö¶s£Ñ0g¦¡FuÚyãáQ_ue ·ôÙÕ(uŒÝ´UV¨:6¡ µwÐÑ�þŽ-«™j�'³“̆Y¤‘M¢åžŽüh" ôÄ ‡) ƒZrÚ9ªPDgÑó®Ä3àW@{näbÝb1´«ù¿i\  T†¡Oí¤r0€ΣbO«´N±7�N$N…òí®Ö~Ê<xÝzò¥ã­'!\,à¯7:4Â7Œøçå}¾÷QDØZ ”8ï] 'ÁçDͺEí<,œ“6`s¢dL–¬3ÝÒË×~?€hK`1f²?NÆûø°««Í6oP5a& %ב/ò1nóâŒÔç»Îö¨ö× Êd<m€‚Ü­dü BHy›È=p#Îú&]-pl@ ¶p—w ¸…ü´óç}Ã`:è×Ù«»Ã|ç“Üa5Ê÷š|þs熟ŒëWvÒ÷%%©¾w8›|/4vêèï\‡ê͸ãg€p!O.-j+`c”º/Á:qÓ 'à´ æéKK­€Ëç¸" *pçÁqJ…î{ð ÐN·÷à™‘×ÙÓˆQwg†Ã£Òêñnk«VÕ¹œ\†¾rªi£ƒ¹ üNä:â¡'ªÖì«öçƒu'EB>Ç¢a{(v•Äs@ xî:€6‡ÌÇÒyAk°)tDqâù\Øî*’jRš«%Â?šÜ®›œ&–?™ÀuḕûÉÄA˜`å ¬Áž§*øÔÉä¾€@œ<¥&è%¬”9 »È²pMãnqb<¥&>kß×~aÚÒ¤‰’ò\—WÈ/VâÁlJÆJGÅU×1“uäø¥uœ xÈYÿ`A½Z¹dR ðiÒ{ ºôœ=ßȼR1ÓÄ Ú" ÆqTÛZ[öñz>äÕ/ïcW£¹¢!0Ź $DË#!Cá5›¡HÕHˆN=s0V#c:ŽÿÄÉ è.Ý}§®¶°˜Wð#{i]º‰2òâRØËÕãI1 ólOůŽ=Љחýv ¹VŠËÏJ\´×ƒJ¸D°E»Ì=ï5šG(À;RQ÷/ãÔ2 7åîóèþ7ÇÙB!{,F€¥è ­ÏÝÁ¾ÇiAµ™Õ׬”5•»(ÕƒhøT;-Ê»D@Hï@ ò\"…x€y\½åpU·&ÒµâŒø“�N 1D@ñ©w3³ë%‡€ËúgsÛJìÝ‚¬öå5�$@ò®'Ñï 3ùÓQàŸ7üi8ðí+ûöŽýS-+Fû×{8î|µÂƒl!= ¡ªkYÇ=0ƒŒ¢ß£M ç(dÄÐ! !óÛ¥vnUàAøŸ¡H/º^ÔpÔ=ø¡×Fã¶¹“ÆWæ¾úÿÉ{÷ç6®,Ï󓯛O$�ß‚dJ[žn—{§¦'v¢cæ‡Ýˆý}cÿÕùy#¶cz{§{=Óõh7Ë%™– $€|ß|í�$’"%J%»ªf2›3/nÞóúžs¾ç¨1ìâÐj ’‰Sž95Þ¬©šš´Ö…öŠºßŠÒ8Z«íÒì„–ÕÖƒ^žãI¬|Μê±KÜ!¿HÂ]óIÐÙ°ëÅ•BÑ•u õ23Óæ»DI&ÚÞymþÅv¶2DO+'+e€ôÐlZ…ª_ë MéPÂô…èΤ  uQ|™I—ËÏ1û³"H´Tˆlažü±ÿ£(ޤ#‘ f˜a$ëC£±š°P#k(øâû8œª —e½7ZewÊ®œªš¡(½pÕfÞ,¨4 öÈŸYví(W›©Ò†q™)i¶‡­Mœ¤iÍ^òL²³˜žk³/ûX6¶?ÈÌnžO Í}¤juW‰0÷ÝC?«Ò*‰™Ë<*ôTºyVÕ{CÇ)R²6 X°€æÛñ}4ûŨL%&OiŽfX¥o|õ‹£/ú»®ÖVhæÑ(‰—ûáôéïÒj˜B*8Ðè›Ö·’N´qªbºA{æMkt.1Ë,L…˜ÚH…ÌÍdö˜3ý%½˜bÎÊÇÿlvf «ä»¨’«âvië´·4ЍW‰dþËÂ%7þ>_“ÛÛØ 6h·òœ^¹Šmíax;,üF|®Ô"ÞGáÜ¡U5q^Ïßúó`]'XÒ†’†uŽä:­{¿gÌ~nÜIÿY÷Ï[ÝŹøóbeáæø¾;™@Ô‚‘Ž\nøO_Ó1Ùø�ÌCʄȚZ H¯UkÈz#'FÌäv°mŠÌPCÖ¡÷¯y¬ ­L·ŠrÖé¥Zìۉט]UT)ŠiÇ“R]zÄùWÛy[›¡Ë:·£ò!¶Vj~Qó‚h‘º³pÊÔð³ÐÝiÏPlìvž{šºñ«ñ|bªCÝ z}%è”ý6¶òLÏu3ü}j%QŽ\e‘a|_ª™ýƒvE+ÚæÁºíVéŠV³ÔŽÏÅ…¨¬D±b¸’£Ï(&©I¹ì’7 ]ËéFmè¨ÿÒ5ž‡‘”ú)¸ú<‘/¹à@ÝÝo½Ú3’ÃôðI¾÷¿c¶ÔiXNfé bËÒì±ÒÉg”²4ãVw åëªÑ,P þK¢/÷cxãÚ9™V c+aO„{Z@ýåh°³tU¥î–âÛÜ©ÊP %?Xzºœ{•°‹ÖvX4z‘ùMeKÝ:ͬ íɸeÕŒY¥$Kª”vä5ÃÎl{B<ðé X„¯T” Ý—Î &6¸)zájúgögÔ^КjUDU1.fçñe‘[3õ˜jÂYH!à¨íŽe8iµ/íí•Ökªi§ÆÜœÙýƪü‹ÃååEUh T‚–nÙ.c-4] …hÊwº‘‹0w¦Ïóv…ŒTÔAg–ÎFš%»Ñyª.ÿÞ4¾Å^'Ž6Óuã÷ÉÎåíp²P&WJ’¶MÎÁmõ‡÷ÖªwP;W¯ÝËóûK½X‡¼†'á=‹»ó¯£?÷¸ág¬nº±S¨~:ÛpÛCµmá`}uªø–©Ñ¹ZeûæÕÚmrã „íÚñ/^¿:ÀÔÈuÎím½Û0cd¾E»Ø¾yèÕÑC›)uÐaÁ×óð°÷<’yºDì[rPJV”eÓQ®Õæ±\ú†S={ ­ñUu^hUÙ«÷»­£«ZÝ_®ª8ŒH»ÁB š€ù+|*îj?ºÝœU¯.òU1Íw§ZqXÙþ"oÿÅð:êÊošIÓ{± _Ñ„åÊ¢ç´ûij5ut±¯xN@*¯*¥ÁÚEÙŸéÇ^bêíIUž*ýŠ\J˜§r߈ô’ÜÑBa§ªÕ[´K%Þ©Td "‚¤nü³Ðèð ÝRgQ)Šâ‹ØÝ¡o`^%eô}ãL¥vP %[€>Võqd}ÕÃQî‚�tUæ¡Q,ºšûPW¨„È\N›Ý\œÛªæÎ[Evä¢#[ ÊÅžî…AÏQU£tŽkµë:ÝGEö«, œ¤Õ/VeÌ,$Ÿ¡MAR-‹5Që#QËMŸðbîcxÄ-å}‰–Ð3‹VïçG§mùÂYý¯ñ™5+Y‰Õ¸ž=Ÿ]Ì/Æz3Í‚: H†-…]š ¹°êRÓSùÊ«‘é‰ÅË=Í?Z:”F¯´4Ž2 2˜n%j™|QÊ…Rú¼>.<8:C=‰[ÒKÆñ®Ü=ä²Ëi­çê—«n°Zƒø3ºß¢ƒ ÑëNã›Üvê=ê ;Èš‘Ü4¯%1„=ØÝNl~+Ï|ßÀB¾Ó>Ýß[ë)ÉGxÏï~ÜÏšÐÿÌ€¼b·Jðm½îˆôA¾—‡ýÂÊ\¯Þ5Ûöfªø%L®Ž>øWáUùúÔú·0½N½iÐÒ(¼Ìi:ð9¬¹ÉFíHt{` R5,oð_¹ùi›X¹Z,¥V|[+ÿZJ-4:ÉT¡pƒ©è–Ú‰¼¶T²?®Ý¦)8œb^^Hg˜‰D)ÒLEí©—Ÿ wÔUòâ ä!ôÇ(ûn¶[F²©ý.«!±B|YWáê·äQ^ôd GÝóPù[–g¼Øgñ%†NÏX:%;ÖR?PSÅ3õ²9k/M‡¤Wý蘘N4Y;Ä tŽ)}¹R4í¥qøÜÑæº:)ŸïæôÊ4¬ÚÑ÷cퟠ©ÉP—£°þu4Ý/K_mwc¬”vFôb9[ÚØ>ÔE¸†; æ/×Õ aVŽÑÅñ£Òf+W;n¹³l¡›L¤áe¶“G9¥]”fÙ:G”˜J~PôÌ]»ôég;nb¸­QµDF1¶&4Åét!Šö)šK‘ ¿Ý¼¦t‰ é{Wòj)ÊËcMr(OóË5–xÜp ¥åÏsÙ˜Y~ÿýÅÓ߯¿—UêTq[Ï­vüB‹’æÚ!Á—ÚîÄ4­WQTÌj¼”'I‘$~i;ÓÞ¡¢x‘Úf«—V†=%ƒZð¾jœ)Ý48+3­ÛJO…FÝÐ&ˆrŠ‹r`þÚpKÓBÖ„µG4ã+îÚkI9y“ïEêï#¶¾¸zž5‰:¢”Ð}]‘èB}½j¨½E«ŠwÏ´¿c|Ëu95× {?^òó÷Š„ô?yÃ0„ÉÛõHòf’§†<>{ÛwødXYrç®7éYæ·4½~’†¯Þ,5ƒïà‚Æ|S‘eÊÛ¦Ú®%-%=Ç[Ê„BqN· § ƒ˜ÏÕ± ê9­dùOx`€ý×DØä«VOͺhü¾& kv ¬Ò°¥ú¹?¥ÐÌyâu(ZÅVlÎÊu\tõ›ƒêa‰è…îîòµMk Ää/«å?ÚùQ+iÎÃ"îá«hOÐsšæ6•ËÁŒ*E‰÷_xÝ 1k—rÂbL‘[Ðo¹02Êx½ÐâTÚŸ)Y•ÛçqÑ.4ùm“s1g)i»x-]vkß~æ½Ü±æ´ŒZIMñò2íNàŸ¨”qzðŠ(òU8!†Œ–hQ‡ÏRm•×±óßÚ6¿Üv§ÓfÒ€–žõ0*¯E3+ÃXì›ÊÓf1èŠxWŸ9~¼cìÛ¦§æ–Ìå2±òæKUï–Ÿ-µ$–4Ql"%˜/@ô"{xQªm“Ë#‚îáÐÖ¨^-+Â5’­SùdFÝK¤¼˜4ßQw¨ÿµ³§»jQ[™Rü•ÒÙÝÕ»ÍNÙX;+þÁ/KS}T›ÚRÿN*Ïj\rôªýzЫ+-ŽÒY¾ŠÃuøy�yê¯j¿N«„0 /ËÓI°zâVŽv"—½t5L“‘Å©Å2%<íyhmQ’P7¨&jAÙ'_׸.´;œ”°DÀÐaä!Ûæ¦(.íÛÞ· ]É8µY„k™Þ[¥7•‰6¤·±ËhÓrk¾Èå}|üæ5iÚGf†ßVJ×pù3)Õ÷=èOÜ6|xoËòÉç[z°?,)T!¹ÖEq Küìú¸7yŸ‹9CÉè:IäxÓ) 5¼.[¹u©s²±²aÖÛkµ]O£´— a¹9ôãtA$7ÇPƒ PŸÑóʲ™¡-“¢m Cf'×´ÒÍR+Šf<DéæÚEG9Õ«¯«b˜¬òHTBQ¤¹—=Î’/òf ½4ò°âa‡^ sв)ꧺpmV£ˆ¬ƒ*°úœ}Î+‡Æ#YNè?§<NX9á´mEá‚Ú2]ÃI‹¯Ð+½,‰gì‹SÏQÃÂärJ‡PÁ[¢7(Ñ5ËZFÞ³ ¤_-ÆëÀY½2™–ËšðÿA™#†1ì{'‡?r9grþÙ¿} uËçO|þoTÙÏâx'12ü#ÈO¤rb§Ù>4­rÞS0íR¯”*wiœåƒ)Ú@9Ü×t_ÙçuëÊZMä$œ^¾TƱþ0žV«S;àUÎys8­A{­&C´aH~€´k¦½£ÖŒŒÔ´á,FL8,}ÂÆÒê “©f/º)nŠÛ§l’ËbêOmý+Ë?ô»ìncEÙ|™;Õî®’wô^誗ƒ~­ŒËö7Š^h†!­ÝÔ×ÎNŹl#pèH<aá<‰ž9‘œhTN9æim<]dßÈYÇxÕñéæü « Ê_î.|·u"©¾3VZI>ÚÌÊÝœÛSVbÅ`�� �IDATèƒâ#jär[La\SëWPÙ[a™¦›Ï¬ím†`y‹\—½oëDߌÿÜ:p5¤ïãò€vÅp•hf¸½Í©|oÍÏ_+ô§)]æTù6£Ê_õÇXÑ·?ßÞH?äªdz×Ó;°_s!·47*äÖÔáK JBê"®a²­ 9€Çà üz} k¡O¥’Q*!Æßж(ME<Y¶Ÿõek«š0mö›ÙË–T‡™Ù#ËF^ƒ|É0 {4VLK}õM{é,š@ZaÏ3ê©QÏ4æ¹w”hŽg¬ÜÜÒ:šÒ.Û"'Y1+ñ-hÈ-æ=u9íLó1R‚À:÷†L._‡ù¹$7×AÒDîÐdÔ’jbð „â%mD¹µDc•³Ú*“o8¦[%Ih)JâãRx­QÚ¤«"öTÜöEeîѺhyÉ8•­&Üp}fª†q?<lºû}5œ˜aT Ç;õ• %Ï¢Ë_º†Qï”^ÓWV‡Ù¥½´/ez&ª¿U+ðŠ05É,÷Ü©0 &@umXìˆZðÒ.eÙ©/ýgbUxçÁdE¾a%á%hqÛÌ»¶vַljr´B£õˆHÎÏŸ7‹ƒcáxžêi*JÖT•Ô치™gËJ¤©>JªK³iÅÎNdX3WïHM|†úb¨ó}%}2x¡É_ï"›T ‚r”ήÔá´ì°�Y`MZöò—‡Æ…aÉÒGé0øvããß±o×Þ•]X!%ÌßÈô=G¿¼ùLvCi¿ùÌç[]ûìJÁ-¾yùÞâ#–7™? øó>Ãð‡!Ê-\å·;ÇV¹èb‹¸|èõ.kü¡ïøÍç«OlÿÞzC•€!Õëåm*ä|ÐáZ<:’”²¾z¾O¯~ï5»‚ìu%Âå½´(ÒyÌ”]é;”N¦Œóª³7/›2heÉbøm&©Ê¼€Ï–¸^‡Â ZÏxžçŽõ;eoÆÌæÔ* Kà«“ Nýiií »•†Þ–n‰;E±™Wœ)45"Àש,¡v¡ZÁ…¤q+EQ�C°Aå€l3W#Út:ÇN$\ŸJGÀç>£æ9].ͨ°¢°#žœ÷Åt®uä©o˺ã€ñ]+/.˜oNXà &^†/™šAÑé¦]µW…fM›Q·§ž†g°rYžTa×Ñ2W׺–Ü+«f1 í8Ù­ŽT5û¯ùïï9J}À/4Šï [`ðgÏJ»UøCÕŒñ¿µ–MîäûÊTÕ¬ûÉj¨"lNDÌPgd"eøÄ–‡Î¯±é/{i.«² *(ž!²™Ñ<´_øšQÔZh¨3_èÊþ^ ÊE¢žEå"®°Rq`u;VÖ*%V–TnšéVi?ª¨„`áµ-2%Ô óK »¬§íóPi§j‹ÞP#.7ÁÏY†ð€Àä<zÀÜ"bòô­@_¾SÜbs™•ðìzÜð±W|÷ÿãd†ß„üAw¸³'ãO×6|ÊTAýîbˆ?°Mÿƒ€Cð!†™ä÷W£„M…ÜjS;‰ÿzTÃ5벓XËöäæúÛÏDtéù³º#Ï`BÑ6„S«°c,윘–¨‹$�5 þœd@Ïò­ž&÷Ì©)Ûø"M3?›R…›Åü0!œ ªŠâµÒ¢=B[Q¯(^riŠvz¼Ð7e•ŸÒ[båä5a7Þ€Á!ê% ˜1#rt“ªF€ (| æaî?×TÛ3êr÷ñ+E£ï0•+ÄeŲÂn¥SD rµà´QÉ{ÐcŒ¿Þ#¿­bTV˜Y¨$˜…0‹ X5ËUXvCC9JÜ~¢Œ„XËšÆô©z?¶ƒÊê Ž!›ø2ÖV_Ê܆q¼ÿýÒ? [X2í,¶G¨îä¶›¥J·š ³]Zuhå²n¤*Ÿâ Tîš Ò�ìj#ÇsŒåŽÂ®™ôÛ*(3C›ˆAº¸8L”nÝö3rÊh*ëˆF©dRkK£Ì¬QRÛæóª •ò¥cWšeÈ6(¢JK 9/‹®ü½‘ŒÛ9 ÆS¤”pÈÑ‘6|åyEž-‹“\£ùU£)üåN*¦ ±h*õsøß^±_lAÑ[DFâ]å„7û˦)ƒòÓˆêôämû¿º`ü™Å íǦ×o¿>íÛí gŸbaW]!Gz馃t~S®Ï1ï€&éÒSDS¬ûàÞX—5këôî`9!I0A@ÓD2%$g¿ƒpB¦ÀC>Sì°cð/ gè x4xôPú†ž;»¯¼àEñˆx¿$y™b\ZÝosKÂèЇ ŽüÖ> õˆ¦4 qÉÔ%¶ÄéíBüú«Y yb ç Ѓ(Í¥B­ G`€ „Àì>øª4ÿCX†m]®Ìª…Ü'íC¾mqfldPmøÊMÈ!¼›L't ç4ލ£À'ŒÐF²ˆ(jëH×0…Þ|›i´ ð.9Z°Û=ïCÓó¦/ôUÓmV"‘¥¢®4õT/©T¾ÌV8 _3QLïw¨Hõ@íØµ>ÐB+O¢²*bõ¿ê$—9çKÆ´PÕrÙÐj}¿®½N*嫹žbTLEO7#û¸º8%%ÜEÞ‰•Ö‰l)»ÖÂ3ïåýŽEÖ¡ºLÔ¢ÈDÞ©òeh-sûyÏk-uÃT“Ô[аĨè-]¯ ‹dYBÌ᪟›=ÍÓ»Ì}Y+ &Øà²é͹[´5¶8?_áÍǪÁ»:X?ñ£•Ÿ±E îzàŸ¦ô³µÞãe/®º=Ÿja’”ζi„[}¥}H]¢h„3¶ÍHC*ÈQ‹  o³rnLÒ¾úÕ6M!õ.4Dk+ÒƒèÀ-!„8½Ç” iþr{†o ½rÏT#e¿¦c•ÂÊdR¾*WµtÅÎåá´JØš8÷ ÚC܉JÕ¥²h×F‹µ¹q tد˜_ˆSgH6‚ŽCÔvdÖ à¸ƒé…rÒæÐRéBŸ8’f…¬Ø)Е‡âø@ÕM-bù}Ü;$.Y>e¬Á…Â?¶Ì ¤àù#}ï…­’ jÉá¿H)Zž5v)dé:;ú´d·@+ˆPKÃ<!Ó°÷QœG­y°š¹=™ü-ÆÖƒ“¼÷•a=Z¹¥aU‰Ð.[{ñÓ«|ߤ ÕäCz.ƒ(Xbž/Ûd&j­t»†hœ2¨W^ŠRPrQ:nNö`¹E`r ‘ŠöœßëMQΓˆªEÀ3xJŸ%DÁ˜jÿ$N'DyÀ*ŸÏ@™Y¶•ÕÖ†çÑᙋ´ê°H©Ì"6Æ#¯Ëe|åxÛKæ6ÞÁ¯ŒG#9A!0ØUÐZY«Ï®sV>¢Ü bƒ¼µáàæIìm‰ó¯X÷¾,uk_a-'†£ü'èïþßföûÔ>±øYØ%îd9üS² ï᫺d¼£ÌàãvöÞŠ>»¹°î<Gp½€™tA¿U¹Sƒ™g”=Èä$ k¤ãÐ%•+0 ÕÉÄÛþÈ×í†iRƒ¼˜v…Ðå¦mb¨sÔ'˱V|’qˆ2ÿö &~]¦•ÍJÕµHˆøpZñ"mVü#\ä²®Ü_àä¿Ù9g=/ÜèKI¡ŒZÁ~ÃWOXŒy5eñ9öН.Ö‡Qkp—¤¯Ö[º£Ð79vìçEœO—q«YÅÃ"_O<m¾¦òRb¥¨šŽ#·³²Õ­»žk4IÞ>^¼´ZL¯£ªÁ/ãÕ¨Z<Ó„ZõJaöä«ÍäŒn!}ŠÀ܉ÌI5ýUØÐß1“='+‹¢‡ÃŽBÖÖvÏh5m ú´½páU„…ã ìtsÛ[µ²™ËùÊ{1ÕÚùг?óJ߬—‹£ç/²Ù,Hp7 ûtUÚsÈhá3÷@¶Pr\lŠÉl’ó .a4•ÒÚLJKdxª…Ÿ@š` äj"Òð |zÉz|w‡_å€×ä†d™S-Q@E¶¤Tu”;V)EYÉȆ8_ £@ùë™êHôpèt«;a¯"(PÂD&µDQH7Àÿßã«ß)¡Ð1šk¿Jî/( 8o°@ê›àÇ«TåÕüîRɵqë¾Åñügä ÿæÏ!]¿wSnÏÙ–Ÿrg%Έôc2W ƒwn€wCÞ"%t™N‚†tN±Í‡)4`Cƒ˜EruãÏ;¢u=ÂxÝ$qÈo~·bgÌÔFnñÜQ<JCûaµ§q!ë¢×õœ¾G5ø»S÷iÕi»ç—ûKYVEÚ«˜Ãi ˜6J‹aòòÈïTgÔü®f7¡jPÔ;ìõ(Ÿ2ÙÃPðƒ5ã {¹¶‰¦:‡«_ï¹á‰Ù¬ÒÊ[„æ*†J°òèűœç l¾àá@¡¹Lb­QÕ"õôÐn¾ðb·)šÌ™=Óû ü§…öÍÄÕ…gÈJñ5»Fµµ‘ááí=«{_xÚa¼<"Ú£ˆñe {~²jôœ¶l>k"ºRÕÔFTz1Së¼ùK³³¯¨½6‘Q¾Z–+kl¨—ž-ìAwþ sátB—GhZ7i÷¬´«ck±5)¸”²¶Ðº³S\ˆ²lÆ$E¼s’gœ®Ï¶ß•Ú„U QHö·(¹{5šøŸeµ“_þVæ ´ë%€*ÄJ4$’ t Ä˜àTZS9I%ç ~¹ìéAKÐhaÖb$”cÒ4›:"‹À+ë‚}Pnå×[Þ%¼ï»ÖÁEvÍ?k߆W©íí äݤx!„n‚÷Å?'C†üÓÁ”Þ½ï%Þ¯Jávöš_ó–a¸7EÓ›ïÕÜÆíþÞKEŒJd3½í¶ÍFœ,pÁ1¢%€¤BnQ.¡óyÅ3šëßB8ø1Ì×2ZB…„ñõñ)‹‚Eá0k¯H]±þ'KÜ\(ÿùoNÆŠ½Ûfâ·{|.Q¨žRôð )-­££/©«µ/mºžÞŒª(eÐßCtWt¥ž´ÚrD!«˜ó˜°‘ÏKö²ì5G††1 †`ì`Ä,æÆÎXºAk–ºéi™«—“tiï·¥©jÛ)œÞÞ¢ìé¦ê ï*Jy¶ß‘f]8îgma¨Ú{ôÊ~Y¶ÿEõþ§]çðHüˆRI»þjȼqò©}Žnc$•¾Wc¹»†eWËE–ªaª¯VÇ=“㣡¡X¥šŸUé~YHõ¯:=Ç÷öí¶©šóy]4œœ,³*0,D¹ÔgÜt>á%@ÕEoØ ,Pä2ã|I IM­Š´öˆÙúÍÚ`A¨t)=.ç=äæTcŒí\Ü)HŽ"ö ìTfÅìÛ×IÖõá0ªa…å’½ŒÆ!û‚vˆÝÒ¿L;N­vSLÎRÂ,l›nctÓ6ìGXc’¨§[¯ÙÌ ôëôºõS^ïä¢Pn¶ ÝfWÞ/Å·*ñAÄw_Ç[%vúéîùé/ýaÞ«Ü?Ðr\on¼ÿξ!ßí¼X·Ù¼k£©®}¯”oÝÞâ±å»òåÅÍe_©0«¡ ²úfté›ÝخЩÐÀ¹c³4¦.ãµ6Ó;6§„¨ ¿–š ›eHˆ´cŠ!U¼RvÍVШ^ýŸ„–NsI}áå™Ö£,fd/c Ô]½I+æœÙØ+½“%KÑž EC=¤j°—ÅQXë´³õû !œ¯Dˆô�[æîÃÆê3óÈ^9Î^0©hm½H£˜Õ Çó'i•K=¾’¹‡5^^׃$§ÐK؆éZj½ßw"ï³sU]´ÇŸë…ZzÒÓʳhÕœQŸhzPÒE/p¼ß¶Á*×´I›×mÞF™nù‰û€ÝýÜMéÓv5µgy®=rö»ÝCÑUì2òÃÄ‹ ý»ùtKÌ#yá8J¨xéb\×…RnÅÞ\ºDE‡|I¾y×]ý¨éhNÆQ>ûKrÿÚ=?5¡—°$ i3lèâ'Bð¹Á3é2öµø‚çý·êÖvµçÒ�´VùÏ™fÏ:¥TTô/ƒJËŠ&wÞ‰Køöõ‘»ûÏÞVüWûnÁOî¯ä‡*®D•Í÷szÿfþðXIÞtçëýzÏz€[ß÷îV›'·/ÑÞ8Iëö!ñ¡QôUÖ_CÁH"gP¾vp‚«&'Ýl‡éæ4÷‘.R›=›¾c”yI]—‡Ã¡z1ÊÖQH Kt9u›¼TʲìífŠÖº¥igŠWI¥xUÓÄì—¤/¦ó,ëu“~cŠÍ„T­”.ƒ.\”V:·&–‰ÞÉ §é¿ÒÎñêAnB'du )[ˆÜ)†Å´ƒ|ŒbM!¼È°Z-¤0PËËqiž¤âº&ñ!gßUÝ;˜5âoVÙÅ,®Ú,´äžYÚCÝw•zר³¨N){Ëâ°(=Å)bÝ*˦r²ªé*áajª8¯e¥B}R—d9ù š#%÷Xv“j…Œ—¶¹;Ãú0ûVJ/V—YÖ”aê^îèóq% /s…óv茓}_®9‡ÐÀ Ñi1 ’–8%™ã@A„T«:fßçßY|VöÌ•5ÍÏ} ,‰Oº ¼šf×7W½Bz§µé,_hföØÑ&Ez|×ôX, °ÞÌE÷A ›­Wívè4()£9¤¼@ú?r`Ò)~ù9Ê?3kYæ…œõP5Œš·˜Peý–—ýåWßQÒc|Zõž1”ïQ\ê}Ÿrz%w}w–âz¤’¬õSú4_Cý˜?úd›øã{¾×m'©üÐ{ƒõw“s+®{1JL[^}î3@’Ž@Î!‚ò¦Öe›kÁèÍɨ‘z6*›5ù%FDZvJ!rÏkjÓIöØ֖К6iÏŠjÁé³u‚7™µô<žbœµÌ³Ê²1– äïâæñ\}ä5»Ö©0Ô3Ì1Jãz‚H)$»`Àïõ¼#×ge¢]R?[¯<_§ •8ٔ謞qù˜\¡(¦Úi,)òÿÔ®þ^.X*9ßï9ú΋ ã›™LgiÓVÿÀâß³Ìþ‹Ñè»qéI2ÝâùÄ$%»%j#‡ª˜4ZZemvœ—&ƒ©Ò¬x9Q2§½PêV$3¢kÚ`^çÍsé-—<L«iU@‹ÞÒ©e˜– Y®0ýµJ†9¹ ¶1Uâôéê‡CÛ2…í4š4¢“â¤]8Ë££Ríô”ê3mQ5í3É^ŸÔhÐŒKVf7?Ô%gµLÚ C{ÅŽçªR±£¥RÓü¤“nK¹J-C4DAÏAó`NòºvLÅ€¦xÚg]j|ú[ ¦˜QCÀ±Ïðä:j *£âšzýS´Ž¾Ã·+?^-¼£>õ=ªcñO ßÏû†>þL¹öîm-³µWíÁÙ= ¥æáReƒýÊ´a·4”¾m{Úö6µ¸öùò&&»©éfAç½U6‰LÄBW,ˆ‰–uv'©¦eo¶¨týp®I[èÕ oÆâùkŠM¥Œö¸$'úJšù¢Þ]æÚ S‹"·;\…’ç&}h”žU‰ºì”Ñ+xF,À�fóÿÊAÝ',ø~«‰Á" N¨%Öëï"Ã?Ûâ]b欞ÿ_môͺî>=Ízö'al’-©G„¿æ•ÑByþ’cÆ@„ˆ_SM˜AO¹û7B줡¤)p—ØsúÜ[ç%:~E:‘Ì¿W–³Õ$ÃþŤ–/ÆRÿ§˜ÑÙBƒícÅBYÈ– ½¬ÀºbÙ‘†z4y¶ÛX]×/œ®¥æ½8Z´ ÉÅcð2=5ýu¶[ÙžÑv¸Žhi+ÚˆØRNM+ÔH,æ!ä`ºê®ØmÕƒ"Y*rQobÑU+Ls¸êü}i6xsò„,ãùŠ²ÙžÃ}Kœx'¬èÖÓâ nŸÁºpuï-š<…nK#ïž¹[}ŒÎú‰j:ïš}×ÏÿPâS_÷(ôÁjðOÎ6(ÚÕ½›b"PÞýá»G‡ÞsÄëp59Kâ ç¨²‹œpIZ·ÉU êÛÙòˆ7êuû«6à; °èúfØmþþÙŒ(ýÿ|Ž.*{ÌpŽó‚)8°s\6û̪-¦Va›ˆ2•²Å€ 7d‰Z$ä4 µÀÉÑy{H¢mŽûlû¦�WâIl…&Ä„bk>£ÑPÊ‘x{µñX<—õFnG0ÎW¢þÖ²zFE û‚Õ‰AÙbViÃä·ø¹ßÍVë@jq,s¡”Òï%ú.eÂjLzé–'µE®¡Õ£– j|u°ß„g«•üþ¬2Œg+­ø¾Ò³• JÑ¢­‡ív’k¸>()j-¬†ý'F^Ò´~¦6êàRó*Qîצ¢Ïqް“¡{¾<í’YÏÚÁfÁjj@屮èìN»2Û{Å.\dO«]w§ê¹n¦qØú?ô…£ˆÔŒÅ"ÜÛ‘•ƒ¨¨LŠ‚ËåÃÀ³°PyÙäÙ9'屩 ÁéÞxD\¼£ÖkRí‡uÄ>rŽLoÁ…^·Ý atÇ@éOæØ]YÄœ~;»põçbíQiŸ’)çS¥oÕl­ø³åÚk³é–lÞȽžr[÷VɬscÚÂ'¦”ö)Þÿò”­ÂÜ“_q!’·Ž¯r3ù!xKD7W4xõfµùÖH(Õ¤‘h‹ÁrÒnñ·àÀhÂ Ú´�kHÙŠéKœ›YY…¬3çç;˜|gu)†lc ÃÁX°w†íÑ:“uæ›<‚JH}MaÒ<Gž@¿ñêíL‹vKŸsý�T¯jü:ÚT‘¡½hL”‚˜…Dbwžâx¡¯BÍ u¡°öØ=¶mÓ)N_K<³úÏñù>Ô$ýP™_Ìé´^Õ Då©ç‹"z™¬^i4VQe Pbªä Ô2f„#Ù…Šj&ßIéûFaî\æjÚ©£µj[²IP*4¹åþ»ü‹Cœn©ûåR÷ÎV‡“‹çAAtß1Ü õ!íµç?(az+óGƒ´x;bÐšŽ¡zv¾ÇþAî™õÌÊ‚F.V¡L/h"2C{ë6À¯gÈõg°a&·84oŠ…”|]bžóëê–2t¡kÃjÃ:y‡þ½K(>رSnÞö×w”ËÿúF¿ÛgÈÆï3î}rÞ?oúVÝ&`šAõõŸØ¦}¸‘/>íÆ5Ð}§]•W‹‹Ò{-þÃ\˜ö=íâîNŽ;¯ü*aÇ›û8iõ¿X{õ�Ù‚½!“™¼™Í3@¹¾Ð+ý›­)wà—0……ÿÔò„ì9Çx~[@ yH>"yJ0 ’×­ÐrX”eÁo,›ª‡pè4;Nªæa„Tduà¯ñæÝú[å•(¾33¯ 1€ß$M,åzÃvÀÀh)C(ÖSõ$aHõváK8ƒÙê„®9.J¹.˜Í\VÆr' ö¤HÏäi.èà4XEVR:ÅŒNI÷’‡/I2Á¥Ã~ʾŒ÷¾'\¨FÅÚÕºq´hYVˆÊ8@…(äj”æJ뼋²Dwðvp»¢kJC™Ô­'Í"é¶”Ð$\œ¤ÍÑ®õ°êú…EÛ.ãV›é††Ùÿ}¯8¯S‚Àq”¡ZÇûú.ÖÑÐÕG©¦”â’½ %õƒ]e§Ó \Stå°èWÓÈ»t±×fÝhb±Y%íµd”W¹îë>y…ÃT£ŠÐ·UÔéµo^v²õÁ«ÛZ‹[dõ†:ûÝ–òž’øî:Õò¾²vo(!ºGÜðsY…Hß^0îÏÉ¡ÿ”†aøÇ,ÏÚð%÷è¨ø ÅoHç«wgM:mÞI|§1X3 ?»õAÊJm‰“ RV¿uÏíw%ÆhÝBeBÿª)ß28·ógàm™‹'{„3žWœŸ‚¤7Æ…\Ÿ¾yþ%(7Ú¼‡”ë3'ÀébYh=G&õrÞÔx}ŠîߤêªUŸWŒésÒ­™ïý†\ÐH«¦Z'Hvlü±ä•„t@YOŽ^šääPC¼—´‚–2/4eÒCê@âбɟ£Ÿ$ÚQâà÷1ÀPÙ È`zà'š?·æý(uñMˆºÒÅC¥ãÂÈe)Ö1±MqÍ;QÜVcœô¨r„4ÔËhdYa"~-ís±_å_¤q¡V8Ó±±'Êà(2f” ­6µZ}à·´öó{Ðtµ¢ß8}·çxSØÃå^usÝë>´=±¬‰ê‰¶=¨¼@Ñ2©œºåï/ÊœÓ 1AÚ Àße—·€0µÁ&šP¾Ý¾ãÈ m<ô!áj…ëÆ×75£ûæxïÎ>z_»Õ¹H~ýûê¡Ævn§`Ä/Ë¿w¡­þSZ³ÑDzVÈO`ÁJpÙÞ^–Óü‹—ïq껸oX4 ÇîÈPÛ0N¿+µ5Èωž¡É+°×‰×ÿÖn_Ø9¨k”€8[ ~�’—mkçf×<©ŒuQ£ÐQKk‰¶@ƒzIÚð€nUmö$ !$ ˆ›$³ÓßMU¨ì¹õ©VÓÜž…?ÞP ^á[ï•–AŒq‰Yo—™É67^\©¥ÉÕ7Xo_°@€<€=TŸ¸G¼ ct(|ä ó-DÇ!9âß$«žÓë9¥9lòGMå“ìèR:Ä]Ê>QÀÒ]ç9®¾ÙÙ\Ôô8aèÏÓjqžJY8ÔŸË.‡C!͸„)“Ó‹¨þ±»Tyªi'ŽájGÓû}¿PK¿µMÙïx{¾í¡Y¦¢ÚqO­»ê±zò¶�� �IDAT^¦&z÷<7¢YøÃ²ì—uT"©rÉA޽à·ç,JŸ2aU¿ÇñÎÆ™dg£òoéëLÁ~cSš;Ü/ãMÉÜ;ºkÀï-W|íΟÄoóÅþ‘ÒËo´sý©5åòCžþÇ v>&ÚжmŸõ;ãÆbë™ÊO±xñ¬ómGÞÇê¤P[¤ntöºû©µ¼RÃûº¨éu`þœíĘÛ"LÀa¶aÅ~ó3®7߸”ðÃkÂðÿ’ ò�º¼2Ù+Ø—†ÀÖÈAJØèY@I�-œ›æBz¢•Cìµ$ •*,R‘!“…À=Å\Fù ,ÝP&›6ÀíbŠ-†–¿â Î7kÞÎÌ ÈOÖ;ao ¥J}¾¹„µÄÀ¿@ÑêŠz›Û‘.3ôôyå,Ö«8DVd58(œ|¯Ô¼i=«KÞk/£,h?c.È:ÃCœ±›®–Ç`ÀˆlѬãýßGKzj§' ßœ~¦š¶'2Ï‚Õï™P˗ʃRéýeßî×-èûVe&¢jOܾ§˜"«‹¢È¤•Yšîiê)vöT+õ¢jRMæ?¼J.ô`GiÆJ/¢5é\RÃß³ ÞÆrmÞþ-Žw0'(šù®³± E¹m˜¸qÝ'‘ûQå§òS†›êÂÿ4 iUïÎ2¿úÉ-ÓŸÔ%ß_þ| WÚòîãÒ|‹uý‡õ[ÎzWîäF4ýlLîi“ÔÏêÕZŸorjoWÚÙðºÀ™ú�'DЦ,ßÚgÉÝËFs\ߨ›.„D² ™u¡dºd‡²d‘·ÃÚ¤ªƒš°e¡„¸Q³ÖéŽp¥QPžÒ®¶8ÏzŒ°NªÓbêxû|¾ÍŠ?Ûâ×[Ìj#‰ý NlÆ"@JU5ÊmÉKxš`w˜‹‰$†–Ä„X`¨,K¢:T(AgȆ‰Jc–Ižz-ªÌP>ïPʬ,å«Z’­ÈJ´x`~“n€z±q°÷d§H™ DmvSó@tmUþE¬:‡ö ¨´c]¨ÙY#Ÿw çFï éí]ÓpL›ÖUöêÜé z;=Íni^&á´ Í,³VµRi•/)¥šËºW—/ìY1$¾™¨ýøÌízq9–ÔÛ±³éÃÅmÚy‡nMm7_‡}˜Þ~Àü ÐùͧÀvĽÀ½§v£½Ÿæ¹ËŶ?j¨Ø½®Ÿcè¶O2R­ýÀ%@d[·ñC ¦›Ð×>ÐÜ”°»OçffÀm·}+È-¤«>Ö+ˆ„‹™¼é X~oXÞAUp OIcÒÿÌmmÚïjaõ^+yÍU´@‡ !u‚FòÏkqê¯Q+à Ë6i3 {ëšF‹ ïY˜ÿ/–D£, Yº“‰QGë_ñfƒ¶Ïí¬'Iȶb+·2&¶{Œ6i8 jÑaØ0J2™kúð jI²+¿&¯5ø+÷•¦¥¬Ê�²s„MFì¿.<ÿ€euûKç‹ÿ#ùâIòBµ³/½lRõlÜRH-2'ª·}Þ!(`àŽÐÁƒlÌ.¹%òô1êîWÂt×ò<EX•º_êºÒëä%Ñ%óþ³ŒV?ÔÚ®†çù¦ØŽ¥hVÙ,“dœ†¿Ë.;«éãeǪEi›Q®W­•7šìš/ìle°²”ã`×mõ¬­ÏÇ‚©d"`h0j‘ê-ªY,P«+.lµM¨É[Nµ„ÂÀ,?8ü^á¾ÅK7éÜʤðëò“àá×þâx?½ùÿÀ¶á'H?¼óþÃü^ä}ïøá[‡¸¾¹ËDx÷#ü+“·Yî¯Á»BSs ´òôÌ•t6uäw=‚þ•�âï@»ÃÑ1×üº5,¹¿XÚ׺n‹mÅÕjkóø9ø0)åždâ‚päÁcD€õådî÷@`ÿ‚I‡\'Ï~ ošÉ¯|•@<!)¹øçµo§ÂLXˆ+ã—°UÅ5ô´i=ò¤Ì1orãn$ëh   ØyˆÝÑJƒÂQ µÀƒö �â4lN³@¹\þÇòp'Tvs-ë\?>UŸ;PÃh¥o–Ö JD©Š£VVå¤jŸ£Õ¢Œ!„àw¬îôš|²Ÿ=¶ή«›m]i¬'Ó׿yJœUÏõ\_š²WÛ}w×éíZª¡Ô ò$Íæ~ú£ÍÚt/Ÿè²[Ú•YµÅªW*ûƒ<pöµšjÕk̇¦ŠV &±Œ·±àÙ¹*¾9Õë“°áb‘/¶¬ÿõ-žÜoâO#¶÷œýyO‹reIN±“~KvGаé3 ¶ŸlÄ—¶A|\ŠI‡Þ´þñÚE–’±<︉JeŠ0¾ƒ!òò&&+Ö¤ýðgD¾G³»97zˆ±Î‡WŒÂØÊÊ»-Ùú+¿N̆W÷My«wF&2xÝð¡löè^‚±ÃNÙ¾2cµí’û( Ù.Ö &肽!mõ¹€”"£ Ij ‰ñFcUU‰LÖ¡X¸É@8`&ýh´Ò%k7‹ë1¶Á£yüû1Àùæ[éVó+™Uçë g,´ÉJ]%A"7†§9òw¿\ÕèzhÙ~¹4«ÿ¿½3ÛnÜÎóû$øç&n’Jµ˜í–]{:Ýž‹ÎI.òy‡\äYò,¹È}.ó�sæLâ¤Çžé±{ª,Û,I¥ øc˸ ¤¤Òÿ{|xÊüñ_~ûr[È}íØ¯ÎÍÊ0ÓÇìß·ßk½N®5ÞøwGÖ²V!ãžö+¥L²eÄ!}ÿøê»“¿©VÈär¢œ“¾f†YS´s~ÏÉoʯœww†~•y5,x~¿§¹Î?ùÎgÃW§C>ó(ZnÖ6}çFËüR.~<r7t²ˆòqþ`à[eÑ×sƒ®¨dïJ¯û¥JÞ¾/ôL×sLwàØîõ]ç}Í"3 O’>t 0êyGéÒ²gwT‰\QØÃ&^‹ vËR«†²ÔŠGÂ_#~mé{ØCØäF>}²ù hAþ‘0†ÇÉ“hâO·³,*»q™LigD­’AËOð 7>[ó ´ìµïZ`à-8hÒ38�[ÃëáÜáþ8§ÇT䔈g‚¾†“Wþaö,i#9l Öl& 9Jo0•®°°Í¬É…¤<„èh~á®0äüŽâ;^~ƒákZÙ¿ â3Ú¸—¹aÁv¸-Ä´æg×™wòÞ{;9’´^C-/)€×ÀªAŽ\ÀªáâùìpÈÌ1;/}3û÷Vg¼OÚ-¤¤\äõ7åJ³ãTÉäÈÕh¼8n|Ùнn=ûÓð¯òŽgæÕÇBÞàCÛ‡îÙmté•1 ü¦Ô-©¿À~K¯@潎>ü%[Ïø—®é´{i¼*T3nÙù%÷Ã/âÿºwþXÐß;ý:þ—dÞ÷rÙkû«WöcjNÖ¦ßÉÎEõv(¼z±\-ëo*"#„ÛïÞ¹¼ëzæ¼P¹Ïæ¿Õ"×ݾùç Ûmyÿû];DZÂÁت#íyáÙ6çÚN ô#¾T˜2º‘á^G:s‹'ùýç$­3h(C|ö›lºû±ÌP±6JœRŽE Oã�o7Û7ßÄ^L~eìWî‚%‘-tËêUšµnë×àû ”¡êÈm–héí¦ã¬Œ@ÊhÖjas-±<èÀ„²&d1[µº¯|,ʵòÃW‡?å®ñ.à_àÜÉm‘“c³EjÅ‚õnÈ­•@›x20mÝ}Á‹9û|\þçp`/Éâ~.UPÒ¿uþ’/5°²3ûÄÝEwoŠ·|ôé”y‘¿«çë¥l!“Õ:=÷ã•v÷g¿óÞâ½eÖxyCŠx¼kô,ù2VQ@/’͆í¡î 2Eɯ½z;Sv´ÊkôºÐûK»Ôæ¸ÊÞÜû9'ogKÃ{ðL¬oJd¹Ón®Ûß5Ñ^.£UKFAds•¼Ö@{éPékŒŽv“×LQº;ð®™7óš¦ç¼yï§Nûü/?ÊȾ¶Î¨ûCr1h¥¨>HWâN|“ô5†´½Óbýã6'qÓ¦´½ø`Äh«´qbé|0+´L]Åy+qçA†lC9¿È!‹c–1ñÀ—h•&Ýຌܭuˆ3Zr*®b¨Gpp"„»%7»¤Ô "Må|g1.éÜö¥Ñ3²ä‹4ÅK§žq‡"›wŠV»Ë¼‡Sßz6V~lË@½P²P¤ý9™cpÇŽq€´=)ïZ~f6p«õÿ§¥­ò²T²8¿00�ûœ+Œª¤ –¥~8Çt.ížË¯Îç”þõÁ••ùàkÖO–óá|þp¯#ŠUŠVæËîËß!>RþLÓ¯æŠæœëø¹|±ö†¡ö2ð‘Æ}Õh¿¸>Êšî½x÷ù«þ Ãyõ;[óoݻۼ|&y9€ßàØz÷L\ü}çÇF®~håeæ½.¾9»à9¾6Žtzýö_í«ïìb¥ËxÚ•tŒ+S÷Š/¼âðF/~lŸÎû<ç«N\ÿÂÒ¯>Pò¡éÆŠýi¥HÉr¾Cåf-‰›4§ñŸoØr¬­“±Á²E"ÊIu‘îk-D ŽŠÍ5mZ6²0_ìy9ãí 4ÎmóÇ}?ޏ…35{E–ù-À1‘­®!K홀ø 4À”ã¡c”à³Ñ‘“&­[ä3å#^W­bË=wŽoî†ÖÙÌKêc§@Ð8Ù>æîÚ5&|‰ø7h%†Á"4¡u@³AËGöly?Ýî.¼"ã“;FžÏo•wð¢Fõ . \%ú~AÊ m(¢ç…ã7¹.ñ¯dÀ5�nÿš½uÌ®gq&¼àëZõoßœhUïØ-”þ_­€öy‚gz•·z­’­Á/å¼§Uú :X™Ÿzhfß:x–¿±)Þ¼é×?_ð;Ÿß}÷A0<lxå/èÔ¹2ËÞåðlУÐÍ»Æß•<ù•iä¾~âú}ß¶ÝuoÿdšRXuW4-ß—&šü¶×¡+ßüúáË”–|žrbìw'IlkBô Tgc­Ó‰=)Cv•ê³æÚáÎkêEù?¼»Ù­k ŸšÞ°%âÔɘ±˜û {®ö±qÕ©©”±*�×›)²åAJËÉMÑe~³ ]Þ!œÐNXf¼þ,•)L´ jO׸Ôù^ JHºˆ!¿äÉ·ÑÚhnû '¯ÈhÃÚƒ °d,œ øõcò·|ô³ZÞ=‘¸¿—Ór.ãÙ—=Ì^0FÙ¸Bòäªd:ÇÖµ§Ñkqò&Ÿ¹Â& WÙÛ×·Å\7ÛÀvp‹5™yƒ´Ö³Žø^•¡={RÊóÊî6à*3-á×€bµúöÍ7GùÚÝ)¸V–¢¤_#ëQr²™ƒl'_p´#͕¾=ñœ¾ÉÙ%üêõ+¾¼*]pdãy|¨‚úAýöàä£Ð;fÿ¸Qº±ý¯ þ«sòn×Þ›ðÏ™Z§1hß˃åã-²QÒû•zæ ä5µ+òÇæ�óDÇu ¦S"wNö†~ëü~«kÌ{ŒÆ;¿Û9÷*Í™#Šp¿¦ìØ‚…$ìÇù‘^—Dé/Ôor¸†–€]ZÎc±—’Õƒ™³ÒОo0ØìèAzòlfLư‡î4”è3år¹>†€ŒŽ~\@8|= 1˜5x5p†“p‘^þyÁÁ 0^Âähôh@Ëç-Nà²‰Ñæà†n½O'‡ÊÀUÚ.¿ñ3u´â‡NNaÀ¡KùG2&Å Únðt{–¨  BÆkéâ–¾5 âpDSˆ7·Í,­>Æ9л4Á·Èw3·™á½U¢ à+®ßr¯#Ïu®²º]®Š‚cÜ˾†ÔŠPù甼NÁ¢ õËúY^¸Ùê;ßDs6šN5ÛÏd.ï,zw"ÓÖËwг‡\!à°Nõ — Mʦ_ÊÑhh½Š§÷½×CGú}ã¥Wz>S°ÎŠ–Ε+²åLŸ!}züåX|åȯJ²Ð|Wÿ\ŠùÒg9ç•çý¦——w†à|ÀÏе&¹1lnøÆíŒv¯GH™n¶ú`b/9Jv JÿHv²ž§žÂ˜¯ì%M&3b÷×~nôæ)ð†Ñ¾ÙK•’ؤv¶qK2F<sƒrc”6µ9óXχÊcÆ¥álwfü‰&1Ñrp#¡å¬Éĵ¸ÍO^§0ÕFqÙ™ÕÞd&¿‡áDpà?B nÆjŠžÏ EÁp¨»N¥Ká?BžÎ9Åèîé ¼ò(\Rø[®òðû ³ªçz¶|96Ï ª6|Öaúójüp‡ádáTÀãgw Ù>Â,ؾX>Ð #ÿŽR–bûˆNéV‘ð׎釲â1@vƒ=}[c¥xßñ­ÎÝ{Mî5ŠÅ´¬nûår‹Žá›ÏêóÆq«u]ú ¬2dqk\gt9p€,”þÙ±¾¼¹Ò4¯Ñ½ÑL·Xvš?01¯ü!Äbˆ,t=,úM[znûžs£g‘û­«•^õ©IÙãrØøÙ4Þ™x¹Ö~ ΂<‘¡ïM< 5ø|èƒHlõRÄSiàŸ(Ä88qÄ2¹"åhw$5éjëÄñÖ|Õ÷ÈF$ÃOÂHv¤.­ÙF±Rcjô½Ø ý›³± R?Çi‰ÓgqÓ&³ã‹CÕãÌ8™¹¿n »‚ï¹®HµB¦; o5çv/‡™ý‚¢<ׄeŽº‘Ø�ÿB6K}€üÖõÁ-R®`6 7f €Äk¡K^Qëâæ¹uè~N¯?ÐßнË­a>­Ûº™,ꂚ$=œ6gHx‚¼ÆKßåÖç—Ð1éèä-ü>Ö5 :üs GÞL¡æu†7€"ý!‰åRúóoù2‹>IJݶÏA…¬D÷û™ûþFÇaàÑÍók× c�n7Ëå CótãÚ2®Ë»Äû8ÆÇkÿؼîϘæï ²1¬ l‰müäÖtUúâÏ2Ó’îÛËà^ÝݵÊfŸŒ¤±"=eå>,̬pvAG7à`œ3w#R¨ ­ÜBtìtíŒxŒ!¦¶ý@E œ®?)ÞÈkíýôG˜ˆÕE·[IéD GúæáÁ¨ÎÃY¬³íNÕ›’]Þb·ŠÈ[yð1Ø&Ó/î,}³õÀËÐy展ÏÂÒ¦¥û'Ú`á{À€£+ :Eg>BPÒ“×ðŠÜG´:9ÈÉÝ#;c'»±8 9(z#c í¶Ùð[[úÝ`zN¡É­ ï9jrð[œÏ)çô)HÌ.æcÆ6œ sfkxcnmŽM ]ÞEϧgøÂÂyMñ%¥<_3qrt«]lÉßu8‡;xÝe0ã6:GÀ}/ÇÁÕ˳ÞðO-P Ë4|út‚H*Œ¿NÖîn¥m¦˜Š·P&}ù¸Ãax‰F3ÊÄ$Æ bLûê´Bô”©“Yƒ?}ìÓ¦”(ókïrPˆªB|q+GØO_lѸs©Â]®DÕÄž‹ÁXÉJC‹„Eº½4õÓÒåvHõZKÎ<TF[ö$·¿rT¡fr°£žÛŽ-èåq.雸-œ¯Éøpçð5¼`¾£ýh Ó béÓêÜ•JàRr(YpÇ­ÍÑÚo5·–µq4Ó€ŸÇ~fcÑ–8ªm‡«ù–‚óé~W.ÜÀ96´Ñ?÷ý^ŽÞ=Xè¹19tƆðo¾ñ©CkþD'XîÜ·¼ô%-²Ñ8k$ÈóèÊxÔV„Y{²p8~µvrnÊ„ôÈlÊÅb1m=A×ý·–y’¬èÑú¢÷>•öJ³N9•[¬½X¼¢$é¿y}1pp%£º«;{°@ñæüðΓ?RæÆUw¹”½zšƒ·y(Qkpdð‘ßÚxðÞ“t¿£?Î÷ö¾c@@]Ë÷G­W"#Ê9ïí!‡×ä¬J‡ú9½6ýmŸ¡q"{ƒºÓéö\À?†ß¤bPmq—g`Eg*c.uŽ Ãð~ñÛ6Í×d/È}‹õoá8øMŽø¶¸E‚ÔìÑž,ÎÒr’2èKá)&º»T0&e þÝšùŒ´- §Ó²·ù-¼«#àruø\ª×OVÙ{Ÿ¢gj‰÷Ä„d¤¿0T,ýSá {³?&CÒ†ã\+@14ÈÃmˆ!úòe¥!³pjwPADšÈ +ÃøËÎêy“0 BnuÚ.7þ½yMæ9v�æÇv#ð¤Ž(2 \>ÊIwë ‡ý…õ(Qóñº $9º à¾^ð2ÃÞÏ´”Þw E4wÅ$Ô™üY[¸ È…›G˜Ó`[¢Õ o`ÿgVÓª”MdŸwà¹Î<eéÂ_À cö.o¡<íÚ”2¶Wk Ѐ BàL­”YZ•…Ò òfçgug~¥M*ñE²^ˆµ3•72Óœ«çûö *NkS‹™ŒÇæê8›ïÔ± b°ÁøYYpã ƒmI±EIFG_‹q÷!9ÏÇL²çŽ+µà7NÓ•­Ö((héVZÙ¾Ó9.—\g8¢›¾‡]Æw÷åjÂdLyÅQ=î[tp35ƒ6dó”÷”xg£â½‡@ùwàŸGGk­tf,Oˆ¸Xá‚äàÕL—½(š&@Öà`u›°"'UÛ7Ty{3Ÿ´Ê݆²Öª%ÆmGw&û[{  b»ŠOI­ÎUF‘ö‡°€É$×Ê™Æë Ö¤:üêK['ŠÁˆMÇ/à-®.ê¡"Z_‘ÜŠˆŠ3Á`Ì%"Õ�’âØ˜n´œPÆP‚ú$&Ò…¬S¹¹ÕÔONá ÔáM§_´ƒz U¡†ý…ä0ˆ«¹÷·0œü™ýƒÊÈ<5f blhrØ$óõ´Z:£@f.ͪII$gØßÀ––ã/Ђwp¶2Ø?˜ÉÓsøn£Vä38œùSC¬ÚÙ5ì!z½Û˜^×⣹-³£»kʰâ$Êèóó §E ž‹ÞˆÍ®ûñNš4‰Mã\›KÎùø‹_æI#sÁܲ ßý p3SÛ5Ž&Õ+Ƀ¶1cûŒxñ!ddGÕ2ê-*²àͲvôË}êà´ÿžŽÀk:‡-²’:Ü‚=CÅœ‘Ç{,SÏšq†Ðâ.=u-èÐ0F5Õð¯#Ê=VƒÌ ¤KãÀñËU[e´G>q–´ÈÉEè‡yK¦>ù÷ªd·ÃqÜÁ0l‹¶èá:€û1w^sF̧NŽVKñ‰ÚíÖÅýÉë ‰ØìºgÖ3-0DŒÂSáZãÿâì¼Å/'Q)o±Î\àž@êð"¬¶ðª3P ÿþ2ÜŠõç_ Jîè)š¤CöÖÈ~¤ïÔàêp ¿7xZ|ôÜ6‚ Tä( Ë…»‰‘^@£@^gȨ#Äöp6kÓ»ž‘FŒ!»¬­ä³sšÞ?ªd^uA¾IEŒZêLìT£á£�5ÉgK„v ÌX2ó-rëÝK]èŽC°EßÌê©ZÚ[ÚNá†"Æ7дhÑZ)^BK‹%)nC7”ÞØÖ¶îÇÞš©Ô¡JäÙQ:#†Š°™50¸O¨ó0î­ºãpËðCÍãžÇp€ø™Œ?²™v9jÙã©Aš!ÃADiÍ[dá…Äkq1¦nF0ˆÆ#iÞ¡Ö¡!9ûe‡*±áý ¶5íïh)Á+PöÉߣ="góRRÍúÔ à'YA?Pz&¿¿hA† O«¿BfÌ´@†ý}&\µ 2”ÐÎ\æH‘nëIHž=·Eƒ\o"E×Ô±]b‹B÷öáªi¼&È×ócvmõlJrg?žC`w¶0z´� Ã_µ?ÄÆ=*ÒÚ¯½5æã¥™qFµòçXP´F‰—‘¹!%6;ã§R8`š:;÷vUèˆ)Y×!+§©eŠR ìÀìs 6ù ÜóÅf¼ö‹©Ðšú—W¶)MÎEedQ™ŸöI~!¿žŒ:Ã!iéÁ`!@kb¦_Y,ºD®«¶à­k,8IìѼž@.gÜéщi A®«Í†û?ÅËö–z íi‘àEÀf|K€â ÎÈW|FxÚ¶LººëýºZ<YúÆiN Ï¡…€Ë±É{í=ç^yÎjE¼]iÍΡ&ÈŒZQܘ¡€ïXnZC{L®¢êå§Êß ÜÌë‚n J´¯]EÃåiïÌ{k³Á…á š8^J/(à à1Ñ T”¸àJ–[›-nTÙ]oAg*"¬Ý– zjÜ}Xó½ìÒr©Í5’›ÿ}·½ÁqÛ¿:¹Äx¨¼¹'áo|:HZêuÍ>ÓW^–QhE„x"V~3éÀ ‹ü¸=õ`¥È#VÓ‘ñM˜ëPNC`š-ÿ`cÝ0f ,…?ÕÇ4ŦZáu*ü |³<`“QѪvãì ¢TiæÎ—ÓÒ¶3>áðuÂýK¿ì¯¶X h2ôAã&1c/„WMµ¦Kz&“,ëÖzv9ÊG’1' cÈÅy‘5F;¹¢L€QÜuýí]‘8Mñ†Í6ÄnxŒØ—’© ÒYaÌ =«™?À7KO “d£²ç:û¼7µalIF$ßnt¬u—G–�y Mø#|Ú>6錛ßMžFX¾ÅX[FÞ»Qo"/rø��¯IDAT'&ß7Rϯ–Ã’xàÏ,„\›AX^9„BÙrG\/Á³ØÁÊn©.Güìb³NžâHœ˜=_iU+ÇûÙãç iÙO6à1 —lÂ¥ôÝ2ᖽܑ«q Ä>Fo¢ú W'ÕÙ=•dÕrp¼¬óˆH­èŽÂ(Èg ~wÐ{äµFv±ï&Þ‡Sø½F|Ä€½5a+Öч›UÖí¨]šöÜ_åK/ç¹ì–4Q,(<wÉW+áŽ?Ýšwâ++ì*"(;!«c [㔿ÔS‡{6%¹(“f÷Ãc–ËM'»Cuf¤Çã¶ëža^,¥²eyÿû­ÖÂŽ^ •¶sô÷~A¿`%Œ‚tÁ˜P1½"³°©ƒ"áßÃwð-|»ÙÕ¦ü` å•t¢œ`çhÈüz";YÁEM΢u³& ^Ħq›Q–м¼ÅG[ûév°cØ)“ŽX\P‹Åóä¸åí¾MëO-¿Á6˜lnƉI²;tf¤´B,Âr 'á1ÓÚ²»ôkuã0†=Ì%Œë´øLò:lV³9Ìãû½æ¼ø/.(5àÞÃö:»wªô§§+Š”/Ä&œÎ§‰È ¨•Ÿ¦Ø+Á‚<‹êKë9¸ÉOM# †ÄƒÏ¹ª™±'´F‰·+ŽèGµ¦ë$§7 ¡ŠÇÜ´æÌykMœ™‘/”Hrמœ±†6q! Q8–¯5ƒ †óEùc [Á,ÿŠa4`šE·ì¼‰¿ôyÈ…Ú0£\Gëµ^}¤om%!%4X=6Æ”­žÂïÃR_·|Ù`ÆŠ7ìþ§“=¸¦¯ñgbï@ešé¶×3©¯¢S2R)šàŒµöìãouÞÌÙVôIrØâÔ­7¸/d2knŽBÞBq6ûzTá„a¸YIn@ò:#ã^‚ñäãRϯG•’ÅzLBÎb!ËŠ»]<ˆQhK&­xÃ:Ô7¹Eœ­6opüþ?pï f©Ä#WòmZL>Ù¹GçÖQÉ5ëÛµÔC›¯~§SÔ&êzwûc)"è×Ü—þ¼©ÉOW% 8.Šu¸49"”÷¬¢åW1-kHÞÆ±’Ö’X ‡Ø[šðòK®µè•Ê™äos4ámÌÕ´Ói ‘”1œÁ?-5g|̆¸Èiʼ!»—§È Ê{­-µ*úÇÝ:™ðóß‘$›& 5(&xymiˆöN6ô,îà\×OSô‹ª ˜J:RL”sj-uÔ™‹tŠåæ°ÄÌD‹bÊ 7ÌÆ¶æá xT|¢?,¥LF¯”ôzgjÓ>ro‡ñHŒB[êFO9/ÚÝËSL±‘¿7=Ú,StÉWz–šÒ$_&»Âß 7X¢›³3|>ZJ½´€ŒR¥Û¾B¬òsÎ]Î^¤ÈIYZTèŹ*Cv¹ÍR‚§ÄìF0’YÚã½`ÁùˆUœÅ›m‘GæŠÒKÕäygìá¹Ø”DÚdhƒâŽrƒ ÅéXC9-bÙá©íTFÈîb+/ÓÍA¼Zlaˆm1ÓÆ8HÁµø|oÃÜEVXÙlNV5êoÅÖZØD oæÆ›lÖÅe…yÄŠgYˆ{E·ŸoH7º™¼q˜â`6üj{|cÆõ·H,*;êI±¨Þ%|©lä„èªKk1Ùû±m†›–˜C}!,ÒÜœX¯à%Kÿ.m/©Èu}AF3Ôñ3àçi­ÖÐB«M¯Ï0R6=”á("9ôó† #ö"H‰‘3âpƒ-ž”œ…ù¾nð0#´#tœ0¹UKyë'ä‘näµN*#»ü†"É­âhË÷ x¼Ý6¹î†fÈL&×W›ìw»³ú¸r]›‡ ªIP‚Z ë•z“@ ·[ }Ÿ¤M)qÄž–˜¬±#eÂm-©´(%b's¾¯\ø‹œ­l-%#§EªÒr‹ý[Úhc,VeÐ$³}Å­³ðˆïM7˜r#"tí–>©W“}Ÿ,8u—T56Õùb•¡ÜJó]eSššM6Þ6”\ä¶Kº­ûr›à»:Ô×u/ºyvõ«%Cn.p3ºÑÕ Tw§n®-A±:a%ô)íMÚg¡¾lhÀ)ý¥pí�BG.N*ŸW§J)¬Ú>á§³ÙÒîƒÔIᆟo8…ßã9Äš™ºyå&b['®ì6‡khouƒMQ™ì¦N¬=Äu<õ1,ÝvÔ/º¾ÙŠÌÏšožÚPž]ûƒù;-’ÆŒ klqÿ{ÊçÕ)sƒË¯Ñiƒak»¼ù*ýóã ù¹ƒ\„WOªÙê%<ˆ›eʶ›,•bAZ··Må`º¨2D«÷I˜ÐT5QN8•™§ÚEÉɲP/)·6+ˆû„¯6&º¿Œîݶ©|VJ])i>­0U¸ÐüÄxÃXå?ƒ?Ã?-YrŸpS Þ…ú£l<I7EæšÈ‡@Ÿ Dßô‡ãÚ1Ê¥ÁÛœFƒÊÈ9qËZê@? ƒäëUS¾|‡Ê´Ì9©´Â­?ÉH¡']P¬æ÷È“ž6o˜©²c,‰OOdH鹋ð;øjÜG>l7›[š±V…Ç+‘Ê¢'ª¼™0E‘l�qÔµ‹¥‚â±&"qÿ\Ä�_®Ó^áF~£·<ÿ2=[ÍÞßÈÑ|Âõ”žEˆt~fÓ·¿]¸œÄôÜ*ÉîDg—É ‘væ·\ô•1Q³·QöÓqÅM•>²º–l'ØÐ‰½"¹™_ÚüaMpÛŠ¨Ü‡’ÌU/W$kYÍŒ,T  .¹*/< Æ ¶g@ÌëÓ ‚tNOE-è#ýľˆ°;ÿ/ÈÂ�„†ôWÙs6~Œébçãù›/ºˆîv·\–cCÆe¬€{Fe‚$@F¢ÍfüíifF .}±ÓiZþJ‹i@y°6¼yªÄ­6¹÷S¿‡Õ|D$ë‘é 3ñÇÏÂð³­xu·Æ-!üI ,ÈD†]j«,*uš'‘Á©£wÑ׬xgcõ̯#mLËÆs#÷fCÚ9MÑl2‡ÛÏö’ùN‚8ŠMnÞO-K<u4ž›úñÚ”úOxVeØîN‹\¢M·p%ñ"ûÌøk#Û´nWå1µ@ 8ˆœ“8äòNw_Hqf泡ç ΢œÍg¤‹].n\Nó^<¬]ÄÙ*Žbûƒ_Û<éå4¬-ϬÒýŒŠý=^ÞÐyªSë Çk›ù› ¼be’Ôúègj‡9y;RÉ×w6Æý »_©™ì/þâFÿ©Øäh™=l(ijPëȇӈ@o©>àöoOMBå½ÚLq¿!õX±÷‚Fä÷’Ú<?ÞHLxLkKZÜ—glmùA©I]”§EFSÀ’£¨Ù‘wMpç‚¡fÃ…Èïj­×™¡DÒz-«&¼�¯à7ÓþeáS7n¡3zÖ5¼‹¾g>‹lJ¾É«¶õ7UŠs–Wì=öýƒÛ—vëðÿxÃýƒ-ÒŠñ)°z-ùå¥52cX²¾ÙBÊþš–¥[ÂêÚ€Xi¨Ùd!r{ÓÃf1K^ÔÕ¹Óa/5·öá þ gëú—9àB©ÇJ,ð’Òù €IfÇ'b"Œ–¬Ø{›ôUݽä·Ã¸¦O€7<à"í¶ÌªŸür}ý¹ ‹Ì1w½Õä¸CP#I°ãæn›Þžô°D—„†Þ†]ˆtâmœxûHª”yÐß jpmÁ¨·L[Ë{>ûdC>#Þs‘RÞ…Ú†k³f´ëL´k.ïlø»»­U¹vã’D +»Ó|x‘ÆÍ£úºïöu3£¢« CUÎ(¸›ÍXøòéðùèyÙù§î‡O¤˜Yö‰û¥?Ü7¹ñNÝùÝŒ6†‰V~r+%·cùÍWßÞpË@ÆÈ×é®ÔêS—C-svx§ðûèØ›Æ R_èðå š…TGfF3Uõq-‚ÝÏ·VÂ3ä k÷Sú àðA^+赘KúúU/O †–;n¥_ôxtÇ d<HàžÝˆ5š‰‹sl³|-èŒòæÖÖûK·c~‡Õ¹S¼!ÙñOvQg~ôZ´÷­$­¸Ûœ–óú‘è"r7hÄdL—e& ÛZ ²gëÚ>À®ö×iõ1æÌ|ß?vêUÞ`¶wâpýTû¾µâuPy@„·ë*¥P—&uÁyE}ÿy ß9J3b)PbQéþüe°UçÞ„Dyaéý®ÉÜny¨n‰n•b¾nÕßà¥vâT¼A¤½ m)ÖåÎÁÆ2:”åŽÑ-¸—æ¶½ïy\ÿž^*»+`äf?lêî6Uz%`7'ˆs»%Ë€ÿ(oµ…4ð©ñ†]ÐñÝÆ™64(…6fñ‘Nt(ËC«b{Û˜§b}PV ¥fù&2¸½¿5z˜°+Ê:)-´Â¾hæcä ;¢5r§+ëksËi&ïºþð8]t(È8ÆEøŽ’žŠmv×êk r7掤Îi‘¿O’Á<£Ü·'?ÐI2bÿ±ˆÛ›ãjMñä}Xð à/O£ØåîJ±^Þ®ïùƒÒ†ã ]V±û7Ý켈‡Ú™ŸÍü„{ûìq,·ÚðÀôO‚¹Ù1ÞÞº]“;@ÉÌþK=þrâA‹ÌíAŽS)òý Çʆ7Æ.Éߊ6»È>AÆólyC:k'¦À˜· 9$åwF”°”õï"FõMM¸�ÓZöëJhaËMÊo–ö¶(©ôÒYSD=É#âÿXîrû™a¹ÿãöÔ±XÄÅ÷}ž7”MIAAAAAñÅ’bÑß išš…ç†gsTC‘Q@‹úTŸêS}ªÏçð©lJ k xƒ‚‚‚‚‚â Š7((((((Þ     °-"ã”|mú©\øêS}ªOõùiúJoPPPPPP6%ÅoPPPPPP¼AAAAAAñ…ý"2†U±ªOõ©>Õç³ bUzƒ‚‚‚‚‚²))(((((Þ      xƒ‚‚‚‚‚â Š7(((((ìÑ1¬£€&_Í‘‚‚‚Â3€¿Š7ø¾b Ÿ4MSGûIÌÆþÇõDeSRPPPPP¼AAá ”ÒðDfcÿc‹z¢â Š7((((((Þ      xƒ‚‚‚‚‚â iCWS  ð©BÓ´Ùÿ}¶ÑJË!ü“™y s²0¼®Zè‹_.<Hñ…OÏ<zuÎ.Óâ‡Íƒ ÞîV-ôÅU‚Âsd<›aŸÃKô,¥7((< ÁY¥¿©U U oPPxŽRs"r ðV-æ=•MIAAAái$1™â Ÿ2!P“ Vm3-Dñ…E(ƒ‚Â' ß÷•/úÉMËN‡7«”7Ÿ<Nå7((</:¨&ayÕ´ìmxQ·Uù ± xƒ‚‚‚‚‚â Š7((((((Þ     °-¦qJ¥jãÛ6ÿå¿þ75) Ï¥j#„7,üAAAAAá¹ë ×­wj.h¾ïÿûÿôŸÕD(((((ø‡ÿùßÿ?·rÕÌó–¡����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/ds9.png�����������������������������������������������������������������������0000644�0001750�0001750�00000460322�11332353405�014613� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR����P���dC ®���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚza´Ø�� �IDATxÚì½y|×}/z° f°€�.‚(ÀÖÚ´Ût,GJ”:qbg±“8ËÜ*7bož«Þ&·4ãÖ}æçó’û¹a›ûZÓìKÓ²Ík);Jªô9NmÇv7Š5R,;LlZ’E‹’ Ñ€H€�ˆíýñNŽf�p'Aò÷ýƒ˜9sΙ™ß¾è†‡‡@ —a, w¾6‚@ O?ÚÉÓ½óŽ{?ñ¹ƒ´AÄÔëÏÒ&lدÿ>üû·»Ÿ~´S÷µoÿl$2IûB 8,—þ󡇢}Ø8øË¿üËéÍïaŒ½=x.xꤑ1–N%i_àšøÕC=T(h+6>ùÉO>ñÄ®›ñ/1PÉ$‘… Î ŒŒ±™tJüíÒé_luèG6›½0iÚä»¶èÓÖÉ7'2þßOJ c ŒŒŒD"‘¹ïv»kkkW÷\œcL§«ÞyKêRïO|Ü`0<õô3±1‹³Fu~&ô[oO°ÚÀ-ªÓ Â:@*u…¼øï|' A^lll¼í¶ÛŠžuîܹïÿûn·û _øÂFÛ±X,‰D®½öÚ¹ŸræÌƘÃáX­sÕ?\&æFƘîJÊ.ÉÊ´sçáïy÷î[¯½&pá…sV‡Ñ¤ˆÇè#oälRÂâÛdsÐ+D ¬?¨ÈÂ=÷ÜÓÓÓs÷Ýw †ýèGƒƒƒW]u•ê”ÉÉÉW^yE’¤{î¹G·ñäÅñññÆÆÆyÒØØxæÌ§Ó¹Zç–ºé` zÕÏVWmè­ðÉ“/WW{v^µ¥·ÿ—µ×¿±ßž ¾ÖXWõÒ¹ñúÆèý>{Ç;ïÞûŽ^:óèOÐnÖc°ÙlûØÇüñ›o¾yûöíO<ñÄýÑÙl6~@¡Pxúé§ãñø>ðêêê¹c `‡:+®æK}I¨¾úú7_{qrr@¯×; é±ßÔìhfŒM·¹Ø‰¾ßÍšu6^cÿGnÝé«‘Œ†èTòâÈø¿<u|bršk-÷Æã´1ÆüÆBcQ~bó5¾¾ûzßæM½~82ùâ¯Î¾ðÒDIü?|ÖUeéþþÏñê@=LÇ›žŸŒ ;<›‹ã¯Ûtï‡víÜZ/^?zìÙ_ò­ * z½Z^¼úê«o¼ñÆ—_~Ùãñ¸\®Ã‡ÿñÿ1'Ï<óL&“©««knnÞ°;¶�­¿ŒU9·œÆPÊI°ùú÷\<ù”ÂÒŒ±|>6a©²¸jé¡ÓÁ1oÓ:½aVŽôÀçî¨vÙ†Ç&††Ç\Û ;ë Éh.¯7$ÆXƒ¿\1vƒß¼4b”ÆØïºös¾•16¼”L¥wø>÷‘wyݶCϾ̵–‰Ñ·“‰˜Ùæ¬Îð[¹‰±B1^k³Èÿgˇ­fÓŽýJÇ wî}gÓÒþO1f D¨|xÿûßáÂ…½^ŸN§Ÿ}öٻ1öÚk¯ ÎÌÌ´´´ÌJ¤¾ûÝïNOOã&“ióæÍ»wï¶Z­øuddäµ×^™™™‘$Éãñ\ýõ[·nÕžXSSsë­·jí!«¸cZR;w©_<÷›ßüf©ãÿäOþd.犇ý²¸žQÞ”ŒrmÓÆ~ýCÉÀôz]dàWúêšL.iñßb2Ûf]°Ûa­vÙÒ3™Ï?ðõ‚No”ä*«œH$,›¶2cìÝ7ì`Œ{ëíWm¹}ÏMÿöÂKv·×f–?û›c=ñãGŸø±Ñ¤ì¾éÚ¯~én¿õúg_|y,ù»©òùoÿÏŒ±C?üåÝ{›“ôäÏ_»Šü·ív;¬/zëÿ}òx>_`ŒýégoÛ±µÆn‘g²¹¡±Ã?zùíÑ(cl§¯æ¿Ý½»Úe{í\h2ž|ß;ÿqòìcϾÄ«qÙï½ó×^U+ o^;üÜɡѨj þš?¼{·ÇùÛÓEuì÷ï¼eÏ;®¶[”d:óöXôÿöbÀWk5›.^ûëüW³ÍqÓu;}Þêíe ’Õ1òÞÖc`Œ}îsŸûÚ×¾666Æ{î¹çª««wìØñ“Ÿü$~ùË_6s_–e½^ŸJ¥Þzë­X,v÷Ýw˲|îܹ_|±P(H’d6›s¹\(J¥RV«ÕívãD³Ù,IR2™¼xñâøøø'>ñ ‹Å²qLI?þñï¼óÎYÏýæ7¿ùÅ/~Ÿÿîïþ®Ô¹¥LIzÕè*Xª6Y¯º¥P($RÙÓ[ô3“R³Ö§›âÓéÔLF6I_ûò¸÷ž[w½So­¶¸ë F#c:Éh¼å:?cì¾ût|:YëqíØâf…Â5þ:“d, ÿèç6Wµg˶þá䥱(c¬i»7Œk©è'Þ{ý`hÔj6Ý{ÇÍÿã¿üÞÛ#ãù|þ=7l¿¾¾JǘN§ó¸l?ùµC?xáô›®Û¶ùKŸ~Ov&mQL÷ßû>oµãÌ@019qÛÍ;c‰X8™eé¡–;o¾fë+¯¿ùã'®ñ×üùçnWŒWl”E1µî{ßfãìù‹©D §M;¼ÞÓŒúþxôx!7“¿”N§cn§½Þ[Ûp͵»•1¶ckmr*¦c:¡r 2S¨`6›¿øÅ/ÆB¡P(ž|òÉÇÿÁüËåÒϸ„ÃáØ¹s§×ëeŒÅãñÓ§Og³ÙÿüÏÿ, v»}ëÖ­õõõMMM‹åí·ß. 8Ñn·oß¾Ýï÷3ÆR©Ô믿^f¶+ŒìvÑsc;‹A«(hÏýÒ—¾ÄùN§ã\§kÏmJº¹h @~z<_`é‚i[µÍd2I9]ùã92¹B÷ãÇöøæ[ÞÑpË;cl$ë:ò³KáI¦ÓÝØPoULÑÉø«gzÏ ¾÷ækÞÿ®=ó²Ý¢0ÆRé™Ätº¶ú*½Þh ÑDjs5sTYSÓSÚ uþóã'~óFÏÿ~ ¾ÎóÜ‹/}ë{Ï>ð|öνÍ[kª~ùú[6‡çýóó^·ÙìG_~ãÑ¿Üî­ÙÄR‘n¾Æf–ñ/wüƒÑ¤Ø¬Öæë¶C¹1P¿©ÊòÖÐH×?ÿ›ÉlómÙ|óuÛ›|Ž—ÏMèÒom_;ë­f9¼ÿkoä¿z å¦k·ýV’$ÆØT<ñöèøHtú»ÏH'§gôƒo‡wúêý¿ÿŒ1‰Y‘3éifwÍqK „U×c^¯÷Þ{ï}ôÑG ƒÑhÛ³gÏ|ccµµµ‰DÚÃôôôàà`&“Ñétn·»ººzûö팱|>ŸËåÒét6›ÅYSSScccŒ±ªªªT*•b=™’€|ä#ªoþöoÿVtÿ”:÷OÿôOqä7¾ñ ‘+ˆÎî|.“ˆ0yé\vü|Æ\Sešž™™I§Ól&<Þb¯Þ:—5ÿæÜ¥Ÿþ_ÿ¸Ù!_·Ó÷©½×[ëþð-WÿÓÓ'&󞦫c'zOëô†_õ¿ýÞ›¯ù½]7|ëû?J¦cŠl²ZÍ:ƒ^o00Îe·2ÆbS‰|.Ç4‰úÁó9•-0ÆÞ|kÈlwfõcL’Œ3é¤Á¨ûüGw57|Òj–ù)&ƒÎªcC—Ƙΰi³$ö;[Ð&‡…1vU}íÿð?ù—uçÔ¯ÎUyê`ùqØ-Œ±‹¡Q¦×»½W]Ÿ¾éò‘¯ ýêô…æk¯º>pclt|ò?úìðD²ãÐóuoëÒhdÏÍ×½ûæë£“S…|>Ï Ê!TÊÓ¸ÁÁANçr¹²Ù¬¢(ù|~¾4qttô…^€êàr¹¬V+Rêt:Á`ðûý¯¾úê©S§cƒáóŸÿ<7R%“É¡¡!Nˆ‘¨µ�м;¶´äR£iµ:í‘­­­]]]"WøèG?ª½nYƒ¾øåSSS¿œÎ·ÝüÁädd¼ï=Ë1Æ¢g.Û?.[ìå, ×oÛÜËr‰ø±S!wõ¿ÿ‘wÛ¬ÊÄèÛþ×Þ°s cì÷íúðm»p¼Õ¢ÜØòÆ…ÐL&k’ŒŸüà»_øõE½¬ÇoÛÎ{åµ³CWm.—3Ê2¶&›ËI²¢¿ì/òï~ÇÕ{oÜÿ«ønb:ùðC±ã±8clK]µIQ˜Nï«óð'&“Œ±`häý;ÿr<:•Ëf …¼Þ`dŒM&RŒ±êMN£$똾Öý»|ŽL6ßyä§3±¯Çñ_>ò{ï¾ùº] ›Ÿ>qÞ`_ys${jÐf1ý÷Ï}‚1Ö{êœÎ 1]É[@ T ÆðÒK/ýüç?Ç;Þ1::šL&Óéô /¼pÍ5×\wÝusßl6ƒÊONNÖÖÖ^}õÕÈÝ……J’¤­[·†Ãá‘‘‘|>ìØ±;î¸'ÖÔÔØl¶T* …ÆÇdz٬$I•6±ä>†YC™syäþùÍ7ß¼ÿþûç2[NˆJš’òÙLâü ¦Óyo¼C’-Rµ%Ø›<ÿ Y6I’ø¥ÜôÁò“düŸÙ›HÝ:4-ØÎzcìÕ3…|î–†­Fƒ~:™úõé߆œ^µ¥vKçïnîüÎüÛüjÿ‡o=ðé;÷Þ:’cúõÆØ½rf èö^]ÜS«Ó .\¨a’¹\Î$™nûà-œIþælp*‘ªÞäxøÏÿ0™e×^ý»ñÞ³ÇcqŸ·ö£ïÛýv$Þð}ëû?¿5 ¿ðõ ÉdzKçKðÑ|S žŸ~ývïÇ÷¾ãÌù¡dj¦~s-c,6Ÿœù˶Ñ©éD2ýÎk}V³|ìå¾7‚nïÕzŽLI„µÂ.]ºôØc¹\®ûî»ohh¨³³þ³ú§úêW¿ºiÓ¦9Žo·Û½^ïàààÄÄD0¼þúë·mÛö³Ÿý,›ÍŽe³Ù;vLMMŒŒàøhôwÑ;wît¹\ßûÞ÷ …Â… ¶mÛV þç%7%•mVSÒÃ?Ì7êÍ7ߟøò—¿<;c˜5!9ôÝ4ZuSÕå¨üM[cÓã>{F’¤B¡pqðUÇÕå–g2ùgŽŸÚ±¹Ê·¹V6I‘èäÑã¿>òôO•*÷žw\Í{úè/¿õ½çdÅÂk ø¿þÀ]7\cüö3ÿñʹ‹‡î¾íæ~¯Á †FŸ}ñ¥'~tÌlsH²™•ŠáÑýÈŽ¿z¾¡ÞuËuÛþôÀ'ž9öj*Qd‰1–LÏ<òÝŸ´ÜuËvßæW^ó…_üæÎ÷Ü”Ëçc©™lÇ¡ç?ùž†w6í|¯¢LL%Î \<wîœNª2+›$ÓÙGþõ'Ÿÿð-w¼çæSñ›³{›¯ùí<•ÔëØßuE1MM§žûù+ÿþãÿ4Ù\£“·\³ÕjV"Ñ©ï>ýÓG¿ÿ#ÅR%Éf½Á¨#Sa-˜’Òéô¿üË¿èõú/}éKv»ýÚk¯ý¾ð­o}K’$½^ÿ裶¶¶Uë‹¢¶¶¶¾¾þ™gžI¥R¿ùÍo>ô¡Ýzë­ÇŸššúÁ~PWWǵgMMM:u*•JÁ-Ër4u8s¿îʘ’þæoþ¦Ô‘<ðÀò™’øuaAzàðÍÃ?¬½n©‘‹k Ó#ç¶¹¥Wƒfïõ7ˆÒwuà]“C'oÞéËårŽÉɳcAkÍU¥Ÿ/°ï¿øúÈàÙ\&“ͦ ù‚Þ`0Û\V§û¯ý‘àÙ™Ô´Õá¶oª) ÁhöS_þÛèÈEÓÕÚ«O ͼôÍÿ/˜Ì¤ÓV0M¶MµÖªM£éϾùÌàé—óùœ³Ú{àkÿzñ_1ƪ­µþd¨ÿÕl&í¬©ÿÞO^ýûÇ~˜·TmšÉåþþ‰_D¾ù™Ô´^oøÞsÇÑH¡÷ÔÛ‡£©/}ý±ääx6›élÿ‘p»Îuþq21•IMçóyƒÁh”‡Ç¥¶ëÂHüKu(95‘ÍfdÅòu.5·Tmz{,öÕz*|é­\f¦ÏëõÙb³T¹{ö•‡¿õ½t2^Èå FƒbuÙ]Õ£„¬¡ò5†'žx"›Í~æ3Ÿg˜1ö®w½kppp``@’¤|>ÿôÓOßsÏ=s¿J}}ý–-[†††.]º444ÔÜÜ<99900J¥.^¼h4ív»J€A¯×[,‡Ã!I’Åbá1Kk”ôä“O~âŸ(ozóÍ7K±–¹˜’Àp•?û³?ûë¿þë¢×-§1¨œÏ3S¿%ѯm¼]ÉRtC¾úúé™è5;®žšš*\žOÄäÒYfz½ÑYSŸÏguL§Ó É%ÙhRª<›õzƒÞ`4J²$+Œ1“lÑë &ÅÂXA±TŒRÚR¥Óéõ=t�“I1˜dƘ£¦Þ¤˜u:=Óéœ5õе «pÔl1$ÁÀ³oª3W¹Œ’̘N±Øž-LÇàP¬UFÉĘnÿ‡ß©c7¿uqx‡¿î†k®ŠO'ï5JÆt:½ÁQ½ÅdŽtL¯3ètº+0øïîŠÁY½Åd± ’N¯/ ö\Ö`”c&³ÍU½E¯7ê.OÞ`”Œ&“ý9ŸÏ F "™LF“™haMh ¿øÅ/ÂáðöíÛo¿ýv‘¦|æ3Ÿ9tèÝnÏårápøÕW_½é¦›ÊŒ|ß}÷=÷Üs™Läéãÿø‰'b±X0¬¯¯ßµkWmmíÄÄD<‡ÿÀb±ÔÔÔ¨NÄ -ËÖ­[%I‚ʲê;&ÎáÁ|â‰'fÝ^mÌèRûÉO~Rû¥ê\-Ï)iJЇƒg§'ß;’¬“b­z=2=~=•Je23S™iÅ~siÊ,öâl£j“ºè«$+Îj/ÿפXLJq»¡«f ÿ¼©ÎÇ?;Üuü³Q2‰§Ø\í8¡ðäûn¼êÖF2=óòëçþñ;OF§žúÍ:½^§ÓŒ’Íé)ÿ(H²â•â&ÔMEªÚZ›ˆâÖ¢Æ _{íµ|>ÿû¿ÿû*‚"IÒ§>õ©Ÿþô§>Ÿojjêµ×^Û²eKѪÎ@ÀjµÂ"ËòÎ;óù¼ÉdJ&“.—kÇŽˆF5 ˜†Á`°Ùl:ŽŸÈ‡2 v»}ÕíHEeðO}êSs<kÎU}YÞÝ]Ä”äÙþÎò³±lòÎ0¯ž1™±šµüèÿøåÃß61Íç²z½Þ(›7m¾Ê`”Œ&…Œþb â¿È#»÷Þ{M¤‚Ûí¾á†^{í5ë~å•WP*£x®7(]!?Y­¥òT'VÚŽ­ÿ"zUîÍŠÕ¡7±#zƒQ1Û*!&š@¨(SÒÝwß]þø††††††¼c555gÏž½æškæ~Êo¼QSS£×ëWëÜrÃFî´c¶;Ív'Q¡¼Æ@˜è{óÆoÌý”êêjœµZçjïºZc˜žœ [K \Ä §Ó¹àj¯«uni±éɉǾú_龄¿ø‹¿à4btt”6d}_*i_BQŒŽŽÚ‡õþþ~-oP31ïœ@ ë]]]Ú®¤1„ÙAòâºÄ¡C‡JýDq™@ Æ@ b @ Æ@ b @ Æ@ b @XFÌ/Áårý~bb?¡Šú’@{-ÕàüŠâ¥3 í¹â–pi‹_ûê¢Ôô–ö(ú°­ú>¨f5ßù,ùk2÷u™.M ư /ç\®µÜóY­w©Âßa>=—Ëår¹&&&–vÂEå€Jà Ú…WάVeJ+)/–ºËz¹%d±k…=—c–UÐ.%×óÇß,ຟ[F#)%&/•îRfÕÚÅŠW¿W}^É[³ä/jù[Pê¾ÌºË-³—ßí%¹ª^ð¥Å[öàƒV²Sæ5'}h© _¦ÛÆåÇ¥ôŠ’Eíc±LÏDz.m¾¯DÑ™ˆ’»êóÊÏ_Åb—+Ìq]åwcÁ´ÒƒöŠóÚí•yMæ{饚ß"í—EZÀ(úŽ‹ƒóÏe>,ížkWW~ÉË1Õd Kuw¼Ý%”÷–díÚWbÉí6‹œ^ÑÉ,É +Mõéi)éTÂ=ªÁ©aÑm^äRÉ+³®nŽìyý˜’沘¥ÚôÞ¸¢&šeZÚÖ^Ê1¾˜WkñÓ«Sûª<'å>ëVWšÀ¸˜›¸¬–º¥z£Wkz¥g*ö 7Và¶ê(ÿºVÂÒJÙÜ×Ù­©´÷GœO){æ¼îÑzâ¦+)/V¬fÝ@¿Ü/Ò2ÝÂå“Åæè¨—¦²b¯‰ÀƒJ¶o®©j©6v1÷BëV©äÛºHC¨hœYEWßR1ÑJž¹q9Ö¬%šKÂ�8ÙUœ½úr”¥]ÚRÍD5«Õº5+£½]ŠÝíV—™@ù{´„s.:T™ÁWý1^I–_!ÄW»äe¥T+ÍÊX½Uk^>ÍT{Å%Y+3ଳZŽ ÌúÍÜ]á[³˜+Îe«W~<«¹ÜÓ y`V€§®Øåfµø-•`´�y¥’yup#ËÅ–VX`Z˜´´$ÂÁäVÁ–Rª•D Ö*ß…Vá Æ@ Ö§S>φPdJ"ë–7Hc 1@ c 1@ c 1@ c BÅòÂ,8tèmi ð[tuuÑ&c â dJ"åpàÀÚ„õ §ÓÙßßO@ f1@ c 1@ ,#cXpw¤…H͘¡¢§Ñ+F¬'&&¨ç@ ¬®ÊÛæ‰bbbBÕEOä*Ê^ôHÕ°ªoJýJ „ÕÔTZ‚ø¯Ëåi7§æZ‚>ëø¥ÎZؘ@XFÆ0«!þ[F¢/ÊBJ1€ò̃@ K‹…˜’æ%þ/€»po³–Ù”ù•@ +ÍŠŠö¥¨)Ç€HåË0�®Lh©ù_ ¡”„ºcabk)ÃÉŠM[}¥ÝÂ2ÛJº@XÁ]£ŽÉÕ²™—o="/ª[pÙ¿èY¥4‰R¿B1¼T”£Q©’ÓK}ÏJDcбšó"Pœ¸ÍeðòkY°Ö²@ÆPÔªSæ›RŸË2÷1 aɉö_͉>>ó/µQûËÁäTsXè+ç6ÂêBeº™Õ’³º¢jù°þÅŒ¼jýÈ[@ *+”ùw¹Ù¢«Õ¦ra ±e•˜WlRuU°žI¹è*PkXá^îD®Y€6gÉ=ÄÂúç Ú¸Õ¹SÏy¥Ö.`ü%ŸÃâA=Ÿ Âúç åóyÅFj¿™õôÏv.1™Ë·I@ ˆ1@ ˆ1a!P;Ÿ:D›B ¤1ü]]]´#@Œ¸@ ~‡+LI !68¾þõ¯Ó&c¸N§se.FWòrré51ŸÕ!®Ui¾.ÈLx*ÿá!¬ÆÀµeÅ¡C‡¸v²—«K¯‰ù¬î ÅkUŽþêt:ùÂ+êUþÃCX£ pU@ c 1@ c „yÀét’˜_ÙmUë‰åë|=Ç™¨&°¬“YÝ^¤ª¾…¢;C­[×ÐÓµø9h›ÒÌqœÊyNxˆk°Z˜5*o¹C3ŒkëÙÕbÅæ³Š _‹D–X¿éè'³†žUàY%ð†«}µÔOÿuÏrOo®ŒAlWJQ˜µ“õ‚eñS ®RØ¢{'©.QF5çVJqY<M/µóÚ…³+»G‰J†VáXÚ›¥ÝºRó\äµ´:kùGe¾Û²LOì¼6ÉoÍæ°Ênù¹B¸BEñ†UÄ\} ³6#ÕvÎ[#ŽV”Î}†K.¿/ÉJ¶ó"·(:ÞVûy™–ÀùqÑÑÊÿ:¯ÝàӞˣ2¯mY¾'vä·fsXî—¥ü‹¼ê\Aä –1¬ÉÖžËúHað2ŠÑ¬g­Œ hmÙô–v¶k[™Íj .«øÌÌW YuÞP^-ØÈzƒ~ÉŸŒ%¼ÓK;Z%¯t1o¸ë2ÖÓö®E¾¨j×>ëΗ9lÞšRL±2—sèСY‰~4ݘŒ•üº®ÖËÏÅ6·ܫ˟X1SûZ¤­ K+V—-ãèšË-[Ó®{­ö\™Ë9pà€XS¤óؘ¥EõËôê.«Þ0‰låõ•åz­„-ÕÍZ™=¯d#Rù¹-`Ÿ—\Ð^]É}/òÊðâ ËÈTzô"_Ý¢£‰”·üY‹'â—u¥K¸ís×–c +É ESLùGeŦ4÷i”¿eK>óÕÝŸ…½È•À62W˜Ÿ)I¼‹E•İ#i¯«:l çPf乨—–i&ÚaöërLožòOEù/—{+6·òó\ɉ-æºó}Y*Êʤµ)mp®ÀÖhT@ ,o¨®ðñ_÷c „Õç ¬28p`uÃd‰1cÔÛX�UW%1@ ”FSÒ gú­bba¥å4V~ŽåJΰ2+ÕTì=Ú˜ º„e‚îkßþÙÅÑØôäD³sœLláë_ÿúC=”ÏçGGGŸ}öY" ëN§³¿¿¿¦¦¦¿¿ÿ‰'žˆÖ¼{lh xê$™’pŒK¢¿óÎG žÇâGX<*a´u¼Ê·ör@(ÎøC<wˆù ‹½]ü‹G%̲îRÉ”wƒ·¦!ˆ S@ ˆ1@~ê �� �IDAT ˆ1Â<àt:7rŸgk VÒJÆ«zˆUï×Dçí<‹öO¯ðµ”_Èbî/Ý‘{•0þZÙ -WàQp«î„Ÿ5€m¹£Öa½µÂ�f}¯Ê/MÕ=qm-dGÒY™;²Tï]%ïF®À‹F£•À®~ôÕR?}ü×=Ë=½Jg ü.ÓîªÌñZ±nkýC5¢­¸Ä««>«.4kàE¾Þ•³í=ZÓ Yëwd9¤1ÕÌ‹¾Œ³.­Hg@-¨Þ°ŠX Ãb:ͪ:=ñG¤Ôƒ>kg·<^—¡} Äi”šï­ý<_ò±ÈŽŒ•³E¢²FïȪHxs_`)‰pY¹‚È6,c ~ kÉBµ$†‹ 1µ-ÞÎP96ÃEÎdí?gåšZb¾ô}Y·¥¼Z°‘õý\n³Ø{}ÁºÂbô† Á*¾º+ÐO{%²TÖçJ¸#KBÖ× Wÿ2 ,J V˜D:thV¢F7fÙZã²>²k+hl ´R3™/«¨…,þÙ^7Öâá “±Ïsæ±1ëG­¥<†¥z…æ;Îê2¶%$•³  tG*“Ð/àÍZ]½÷y&®0oaÕõ}„%ˆ>¨2ÑsgÁä�äL;¢_.ùN.þ•°¥%Ы¾E¦2¬;¢dQú^i ,¥7ld®ÀÖŠó¹hÜ^Ø7wµ·¼iuŽ«(?çÅ[ö*d!‹YQå,d9\ +¶å9Ñ_Ú®�oØà\QT@ ˆ¼¡B¸ÂÇÝCŒ@ VŸ7°Êè™qàÀÕ “%Æ@ ŒQ;T]•@ ÄPELI‹Éô[|–`%ä®›\GZH¥ÊýÖ$cˆF£ 6´-æÜ¥añ¨„9ÐBÖåBVÝ£H ,„18C „+CWWí@ cøî¿ÿ~ÚaƒãÁ¤MØà ¨$@ c 1@ c „yàСC³_›T+‰@ ,ÚÖ k®{ã¡C‡®~ôUÆØ!¶úÕUgåOË=Cb ai öÁ^ª¶Þ+ÌcW?új%ð>->þëžåΔ$S@X •‚kÚÏ+Ùγ<WøoØØ6%b aÕ¸»ÜД-i3íÅpâ Ä«kѯP™7c Kƒ‰Ë˜—ø¿Zv$§ÓY†+pÞ°1+Èc ÁNVXɈF£³öU^7/1°ÑQJ9X½¡<oذ\@XJ¢_ÊÇÀíKâ÷üËUtK”â ™+0Êc ‹G)š®e¥¾\E€7<yS qb P„7TW˜ÕÿAŒ@ V‚7àêOfÕ»Àc V!,¡B@ÎgaC ­­m #c kåI?¾ç‡ˆ1„õ£ ”—úAú;::Jq°NT°„9Ú‚ÚÛÛçÎKÄÂ*‹ÿó"Ó¢ìßye ñ8·££cVC@X!0% ü‰*Ù¿Ô…ø˜mmmø·½½½­­ ‰%ˆ1«Ì Tr½Š|sJ­ÿK± •NÀ?k/Þ€Ýn7¾!°Òü�”WÅJýZžR«Î*Ê9D¾"^ßðïÛÛÛÅAˆ=cìkßþÙ=üÔç¾òè#<B»A ÌKð×RyÑ‚_J„çG–ªü÷¥\ø¦«««Ì)Úx$Õä|ðÁX,611qöìÙGy¤@X×8{öìÄÄÄK/½ôàƒþÑÃO}òþGÞyǽº¯}ûgGcÓ“ÍÎñû￟^{AkxQÙd´f.nkM7ó¼¨!^h^ƒ«†RÙ J õàƒ>ôÐCù|~ttôÙgŸ¥g`}ã#ùHMMMÿO<­y÷ØÐ@ðÔI*‰A Ì ðôe ZSLQâËi½ø«êƒÊÁÀTU”i1Æ0Ï¢œ¦”Ɉ/M‹ÐÝ_¯p:ýýýÚïÉÇ@Øè §ÂÜÆÒÑÑ¡¢§ø Ñ;â¹>ŸÓk­aGôñ–¢È¥d|îc(Ê D^¥e'<ʨ|D“x &ˆ16.�•ïêê¥rDæ@dæ_vttpVáv»Åü˜D"Á.甉2âö}•õ_§$z Xéø"þk{{»v’â|8óÐò*-û!Ï3a=SþY¤ïÜf‚Î)i{{»ÛíæÒw$Á÷‘H£<x)Jý°ØðãUÁ?¢+¸££Ãív·¶¶e ¥”€Y-Qmmm¸:glâ´Áðøô´ªRùɈ1k›hÿñ/ÈbWW—˜ß ÊUÐnüÛÑёǩáEb ú J 3§ËŒ10ðv¥Ã@¥Op².ª¥hº8x‰ø%×Tz€6nU;œÏ„µÄ�T±:\^ÆO]]] ĪH!N÷#‘HWWW"‘ÀEQ<ØÖÖÆ©v$Á˜V«5‘H” àÁY8ØçóƒAè@ ÐßßÏQ×.GüÛÝÝ ÕDåmÖ~ÃuÎüTÔ_t‡ˆ—à.À¿Ç¾­!S’Óé\Cîšëô@¡²H)û—ǹ„Ë%b·ÛÍ e0%bŸÏ1¬+ЂÁ ht"‘à!à>ŸÏívû|>Ñâ$N NøË©j$éïïÇUcV«µ§§‡1ÖÝÝÍi±¸.žxÜÖÖÅW'îÖÎ]ܵ€ƒEï>tuuq&Š_¹ZÃY”ÈiÄ}#,-Ц•Æ@ ”Ó�´Q›¢}\…©’E»ÖZ‚ãÝnw"‘À…¼^o:†˜{¾QSQEQTÖy.¼C“à'нÕjÅ9oðù|}}}n·;•Ja Nˆ#‘ܸ–èå¶Z­Á`PLQ¤(ò‹ns‘AŠÕ/¬V«v£TzÉšCåKâ‡Z‹Kaø»²&(§øœþ“èŒe%Ú ¨ƒmµZaVŠD"ÝÝÝÍÍÍ¡P(•JƒÁ`0èv»q ¨9¶Ùl ì@ÀívŸÏ×ÝÝ#AýÁW�ŸÏ·gϞǃA«ÕÚßßñÁ Ð€Óttt(Š".°Z­\âNÜÅ}Μ…ðÏ¢&!²ÕŽŽØÄTLN¬˜DO&aåx@Q)Uü—[6D[èo{{»Õjå_F">xÃånîl`—RAdA—S©T8ŽD"Á1¸HI¹s˜1‡›››9ÉN¥R‡ÃãñtwwG"‡ÃS °Z­n·Ûãñ …ÃaƘÇãá¤6 ‚µD"h ~¿�WŒ`³âÞˆÖÖV®ë€AŠÎ›Ý \“õ�¸ÜÛÛÛ±@‘ˆ~éYK´6È”DX¸h1#pJÄ 2ªø™ÖÖVP1‚DQ†™ã¬B“#‘h+ø¾ÏYźººº@ǹcÙjµ¶´´ÀUÐÔÔÄ/mÀëõÂôÕ!ƒÖ3Æ><88ˆ9¤R©¦¦¦x<®(ŠÓéàd;Ãa¤â çv"T¡±°MƒAžm'BåjGÃ7\§›Øaá(¥Sªî‚*‡ûf‹2 ՘ܘ®5€‹wd®qÛˆxp[[žLÀóþþ~.wŒŒ8Žúúú©©)°EQº»»%IbŒ9Îh4 ’½k×®}ûö9rÄd21ÆdYæ½»»»¿¿?ƒî×ÖÖž>}ZQ”þþþ@ L&›››‡‡‡c±cŒ« X ßYäÞÎ#ÅÜm­ŸÏÇYl à*—ßïß¿?â¦Ä(XÂÑ#,J-˜;)í!Ü1Ëi—²EpÍ€ IìÊ ÎKDç­B 9šó!|ÙÙÙÙÓÓ·0?Øáp„B!Püd2 ªÍSE–åt:m³Ùª««C¡P,稫«Ëår©TêìÙ³¹\.ÃÇ�~ƒ …B!ˆä0j)Šb³ÙÂá°¢(©TŠÇ>A;I$øËY…Ê.r qß:::ü~oo/4�Dâvww§R),™kEìéé±ÛíCCCÐÉDÞ,I’XD¯2k%!\u­8Ÿ+¶Þj%i‹è‘aãýYR%=͸R¦2ÓÙÙÙÚÚ*¦3ÁÖ)Ò+À™°[9O%ãtwÓ?ªV –_rÑÒÒ‚0Ö¦¦&Ö×ׇs£Ñh:ÅdŒy<»ÝžJ¥ªªª2™ŒÙlN$ápØn·' ø Ünw.—Ëf³6› ¾Î¥úúú¼^/†’e¹µµÕf³e2™ºººþþþÖÖV¾(„!µ··ãKh<G޳ÆÃ‡ƒ+tuuq=)û|>¿ßH\0n‹›„ÒÐ××§ˆÃá€N[±c=Á%€ÿKt ˆ1K¸â{•­†Í­sˬ½ÆT¦b‘1)AÛ¾Yª¸Åœg¥AvN$~Nºÿ~PFÄ,áK>ïX,"ëóù¼^/hz$ñx<^¯—1f2™†††êêê"‘ˆ,Ë6›í]ïz—×ë5 &“Éáp(ŠR[[›ÍfFc<—e9 "U Þo»ÝÞÜÜìv»C¡POO¢(¡P("©o 8%’´cÍÍÍ^¯÷ƒü X­«\ƒƒƒ`‡‡ aŒÕÕÕ)Š‚ŸpÊöíÛ9ÝÇvY­V¬Nõ––îÝN³.¹clbbbbb‚ÿK Æ@PëR¡ë"qÍ LˆãMµ%}@…UýjTÁ‘bô}ww7»2¢F¥"´¶¶Šv$>è ܹDPQ”¦¦&8!xŒ©ÇãAjss3÷ÓʲœH$2™Œ,Ëõõõ±XÌáp8NÎX,ÖÚÚzþüùúúú“'OšÍæX,666véÒ¥ÉÉIƒÁ033“L&£Ñh.—N¥RˆJòù|` ° ! *•J¹ÝnI’R©”ßïÇBŽ4ßRn ëììŒÇãz½~xx¸©©IQÑ+•ÚU( 6›Íï÷Ÿ<y2•JÅâ˜}ûöqw Ÿ‡ÃáØµk—Çã …B¸;<4ksüËÙC)eb¾_c T¨Ô_¾`r©tâ9v(%ø-ÍÆ9 =RˆUâdA¥¼þ'°+ÓÊ@ UåB9ÉÑM¥Rét‘¦œ@÷ööz<Y–3™ŒÃá¸í¶ÛöìÙc·Ûív»×ë­«««¯¯Ç¥EÁaO=õ”Ç㠇ØO*•²Ûíø5—Ë †\.§(ŠÁ`ðûýN§sjj ¶&‡ÃÝáp¤R©x<îñx"‘H&“±Z­ñxœ]HE\_²Ãá===²,Ÿ;w®®®. !Çz–©c뛚š`³²Z­œÍˆNˆöövøH’Édoo¯ª–ÆDQebî_c T'Ðÿ”I^-ZÙVË+ÖŽ†» @îUDŸK÷°n³ËU aÊà¶ Ð,T§(ÕyXÌÕ…Y.,‹¹ÇàCÊÿ“H$êëë‡Ífóz½ˆ4µÛíf³¹ººÚjµº\.EQÒé´¢(.\gŒ¥ÓéS§N1ÆÌf3c¬¯¯oppÐét¬‡Ãáp6›…áåž{î‰F£ápX’¤D"166æt:!¼C3Èf³’$ÕÕÕ1ÆâñxCCC,¬¿¿Á¬àa©TÊjµ" / Ùív‡ÃòÍ.Wàhmm…ŽåóùàS‰lpp*tnR㕘= áDÁ÷ðU¸ÝnΧ ZN@¦$B¥0€Rœ Ì1eªr…*¬³è|8ñå£buÒRf(˜w@¹@µUbl)qU¬3Ê ,œ«Í`ð¦¦&±Dv0L$6› dÔ6 á€X,f4 ƒÑhJ$Ñht``�éÐçÏŸ‡Í§¾¾ÞétÆêêj¯×»}ûöt:L&!þ§Óéx<~äȧÓét:ÇÆÆz{{Ífó=÷ÜsîÜ9ÈïPSŒFãÉ“'eYv:à(ØR›ÍW°ØBKQ1ÆŽ?ò NÜ’†ã‘¹Í.\ÁYH$Óà÷û»»»yE 1%›w¨€õ®­:zËQ-PiÄkMŒ¡²xÀª‹¦|mÛáRÍ9ŸõŠ*q^ bÂáÇ{zzÚÚÚ`'AöVkk+>444ÀªÎí'ªêÖü_^þš³îÀ´C¡¬1 ÇÃVƒöï߉Dz{{ûúúà'8}ú4¨3œŒ1¯×;44´}ûvƘ,ËHNŽF£SSS¯¾új:FL¤Óé4›Í’$y<îþþþ“'O‚a0ÆšššºººG<Ç<@6›mjjjiiÆ‘©TêàÁƒWõù|p!Àô/Ë2Fæ*Ž×ë…UJ¥ÿq• ng,D¿³³sppÐf³AE€… 줟'F`|ve"g¢ê òŒu¯FcX5”ÍæžÀ4õýË÷|/QZÔjT”Qî€R½.¨°Ïç;~ü8jÕqÞ²õéO&&$!ó˜¦i À‹Cð’ÚÐ<8_ÅétbJÁ`°±±™h�ŠŒBâþô§? ÎFeY‡Ãp;Çb±D"F‰„$Iƒƒƒ½½½N§“g´9N¿ßF÷íÛ—Éd©À90Áå÷ûG,“eaHõõõñx\’$ØB¡ÜÈÈvæI ‘H¤¥¥—ƒç<N#FÖn·§Óið-ì†b—£r!ûƒõòVx¼aU§Qyw`vcŒ!*‰gªÌƒë†¾sâ>‘ŸSŠú¯{½Ü*Z¥(êXneŸ§M• B¿×6‘S¸(ʳ±¸)1ûb~cÌãñ †DQ— η€i \ ÓüBHébŒ!"™ wŽzd6›0 Ägiàh4Š:zˆà´Ùlps³ âb±’âñ8Žw8}}}{öìÉf³Ùl~écÇŽA{@®†D"ÍÍ̓ƒƒ0UùýþÁÁAÌP’$𭦦¦óçÏïØ±cll,N#uŽ i˜\ÂÆrBÏ—)¦¹ñ]bB;ëÎÎÎ|pý%¸©¤~‘î«~*z|™/˃Ül •q-+=̪CÌ:xùlÞÀRÕæ^”ë– %Vºæ÷ðˆÕž!àc ‰D¢¹¹Ä‹ÂÑÊíéܼÎ.w%ƒ‘9‘HäÈ‘#6›mÏž=p6¸ÝnóƒÁúúzPC$0ÃÕ!IR__ŸÇãéëëv»Ý;vì8|ø0Zë ín``�^‡ææfØpl6,3ðÃjTWW‹Å4€L1Ä>I’äv»Ïž=Ë ‡Ãˆ °Û8~[@&“ñûý0mÅãq«ÕšN§Óé4<É^¯7 9Ž|>o6›ëëë¡…ˆ…ð×ëõâê\àÌ•û¸®�~ÜßßÏëËrõºwph *jšû—dJ"ÌNsË‹óåÉ1+V’ZY Î)ÃÊ„õ7hóŠ,Î 3áuŠØå™0hðT•"0(‘×ë ‡ÃÈ6€t­©© ü£©© ’5<]]]—‘8}øða«Õj4÷ïߺˆRégŒáKä4Àö’H$öïßïóùP4Ùd¨º*ËrSSüºœue2‘@¦!Âs³Ïðð0¤~ǃÀ§H$‚Emß¾Ýívg³Yžíìt:‘g6›;::ÀoÀ3EÇ› þ²,£0_:v: ò6›M–e$aôôôÀýÀÝïˆÍåºHàZPƒøÝäí(šššàŠ ²Ûb Ë☠'(uº*Q€“¢§‹–×Òô¢ã—™ƒ*2UŠIJ\ ઠ/qÂÄ5Ñ<…bD–}˜b|`µZÑÖ&‘Hø|>$—ÁÁ.ÇÞX­Öîîî¶¶6””Èf³===)lñx¦d€ªŠ!˜ ʈ²ÙlSSSÁ`°¯¯/ ù|>¨/²,Ã4ìØ1h|ð¶žž$%ðŒ„L&ÃÃ䇇‡cƒƒƒV«uppðôéÓ<€5›Íúý~”N ƒ©Têøñãìr7P‡Ã-’$ "†B¡úúúL&“Ífõz½Íf»îºëo±wï^ÎQKã ›¬wçäÉ“~¿¿©©Éï÷c!HÄs:ÜDÆ®l2A Æ@˜%GlŽò~)C|)ƒOù2Dˆ5œ»Ž_*yM«a¨ú´psO ÐV9Å)¼–>·µµñ:<œÀÃÉ{œ‰1ø\¤µE¼ äqÐ\PÿöövŽ@ �ã8¢n‚Á < étzxxx``Àl6ó>½½½(Q‡qZZZÑ„št(=Ç8¢qöìÙƒbÜÞ’N§!†Ãþa”×ï÷·´´„B¡x<Ž KDP©èSÁ”‚Á Œ<ÑhF'Î0êêꌄ”´T*úúúÐff¥P($˲,˧NI¥RcccSSSȼknn†Ý ´~×®]ÐxÀ'àHÀ¦9ÎÛn» Îô bŒíß¿ïÞ½ÑhÔf³I@£À$1†’Ú@Q>1¯XÒò²¹ªý€6p¨¨ÍGÍ©’ų´„žçA‹10M+(&sçÕ踃šxX¤Ûínjj‚íˆç"@„¯««CŽˆT*rßÔÔZ …0d^b‚ ÁÄtðàA(Éd3÷ûý(œ‡ÒÖ^¯—«2h¬ë æjE™LaB ­(”„òsbwîÑmkkëíííêêÛëééAº�ŒBP8Då&´´´ ךçNƒ‡¡æv?·y<¾v”Öp»Ýét:‹y<ÇsúôéD"qñâÅH$rüøñx<žÍfN'øÄÉ“'›ššx!Þ9ךžžÆ%†††°Ñh1WŒ±ÆÆÆ¶¶¶žžRŽ1Ìj—Éqy³J</Å-JÿiO +¿¢kWå�Pµ¯Ñ6CV•Ry ¸,/öf—“cyz³(ó äVlD^ò`¢‰ƒ4Í Ø!• |@vA‰ð·¥¥…7 €¶Á'€ôà¶¶6¸ ÿ"mûöí°Ô3Æâñ8ìï±XÌçóñYÄ9޶¶¶ÖÖVÞ;Áét¦R)ä6úÅYï Ê+³ŠDÓívÇb1¸<Ífãm¢9ÍíëëC<koo¯ßïG¬þ$‰©©)¸:à`Èd2pxx<£Ñ‡½^/R©ûúúÚÝÛÛ;00àt:ÓéôÞ½{[ZZz{{EÅ…[Ï’Éd<TzH§Ó(×122âóùìv;ÑD†c ÚŠos±üÌzd™RѺ]Êî/AdEE9jœ°–2(‰}1y§xUO¦iÀi4þŠ2ç7œ’"õŒ ÝÈäi†êÀ«ãDÂÔÃ…q¾===˜�ìþP)GGGG]]ŒòÃÃÃÈ Ã‘}}}<“çý"Õ.NãêH‡îëëRåôéÓìrX'—úÑ*™]Ž”å}ßÀ9 ƒ»ÝnU儞×(Ý·o_wwwSSè5”'LÌl6ƒ:ƒß@9À¬@¬c±˜ÛíöûýÜÉÑ××—Éd¢Ñ¨ÕjµÙl-‰ŒŒŒØl¶‘‘‘矾hQ™³Z­±XŒ»úûû·mÛæñxÀ´pkøZR©Ô¶mÛˆ,ÖOCùÄ®9ž5ÇcÄž3óJ5P‚Š¢Í^.•Ϭb<G©Ô4´9ª#EM‚ ™ü0.‡òüU^ ä½-1úÕ€F˲ ñ\ìÃsŰzv‰tât:  f€FC!à)ìrÇ{VÏÓøŠ¢À'Ø*ž.Àµ+ÞÞÇjµÂŸÇ-K.—C ¬H,ûÊ­m‰D¢¡¡!•JF£Ñ855…PZôí1ˆÊÇ¡oa´ ÂOØÕîÁ’¦(J6›EÑø$°¯×Ë#иàsõõõçÎs8’$õöö .¬•<†µÒ@‚ò–ÀÔ³°#µuå0Ú¬UHKY“xNé¬j‡*º‚µ¦$ÕVyŒ‹Rü¢\A[T¹ÔzyËxD…ŠÅ®Ùå8H¸s<¹¾ó28…Bt<L[p´Â3Ñ®]»`ÿQŽYŒ#rnM)‡Ø‹Å"‘lS‰D"—ËqÉLUµy¥R”çà™à61~9øxë7ˆÌ|Õ˜¶¨$uuu…B!l¬ÇãÁŒF£^¯çéÖ( …�Ù={öÀÅr Œ±l6[]]Ý Í ãƒƒƒµµµpz·´´ôõõaëpd?ÿ�SW%q‰x<ŽJ¨ã„*â ž¡P¨··V²Ó§O# Ëï÷˲œJ¥ 0…B¡ÁÁAÁÖŠ,¸ŽÛ ‘Æ0©îÖž%ÑÊHôlþq«å‡³‚U!¡sÔ?Tºg$\zÕ6LùºlªT Õéœ\rIœ·P†o¹hózÆXssóþýûqȪœ…ðcDšŸ3–€f\èƒMMM±X ¹»èÀ 9Z{uÞÅõ'ø°œ!ƒ ‰Çø•{xM±›4_8r¡!¡óä[dZ[[{zz уd‡B!XxúúúÐ81‡ƒÁ ¤Q@ Šˆ×ëÅêxr¸˜« ]]îÅÆ7Ç766"¼Õív;NdSãZüH¾»víBbf•'Y–ßxãÊ×Hc(ÕJžÿ;_r<Çã‹V&ö¿|-ÒòA¨¥†åý)Ù•e´9J¿? �� �IDATÓ¹òU!LbY:îN(ó·³³“Wèd—Ë®á{.Móà%DmB±ƒÜ!Á>@ �ëyoo/üØŠ¢´´´ œ´µµA8˜6·ÿ0Æ<Í«@#’µµµuÏž=ˆÒAøÍ¾}ûúûûa¡‚‘JìøS :µo!PŠ].k-dxxØï÷£%'.„ÉðA¨GÍ.§Oó2׃a``� °ÿˆ¬Ds;þ|,C £Ñˆ” ·Û=55500À“$iïÞ½(ÊÍ=Ø[(OXŠyà�hQø€_;&I’Õjíïïß·oc¬··wppѨø‹_Ýn7’-z{{EÁf¢ì/FKØÈXQÆ0ÛNQªº„±Õséu¬F©´¯òF-Ñø£%質5ª~8eb¸nÁÉ·êrbÁ;ÑCÀ®Œ[Å  Gb¥kÎiÄD‡ƒ"œ z[;¤¹߀Ê#­Leúg— 9p‘œ{¤y”P ‡ÃÈí‚-¥»»€tòX#ÐS̯-v¹H*wðr'<–ÙÝÝÝÝÝ É]QÞ~ñûýð4pSÒáÇA…QßÂëõ‹£‘‘‘L&ƒ¸&ðB8Ž?Žü±½3×–"‘bŠvíÚÅÓ›ùŽ1Æ�âŽ`CÝY¬TâV#¯â¶Ûn‹D"ñx X,‘E‚~%¹ÂÜ› °bY¾åÆË•ÉüÒ6Š)Cë9õ3ªÊBâñZugÖ¨Y•AIdN\P9Äyª¸5‰ç0ó¹q¹ � á™ <VŒ×Äab$ˆÕü�4Ìá ð=o4Æ•$(¸„XO[’¤ÎÎNXØñ=ì<µµµSSSßDpw$À©Ÿ[À¬V+Ÿ¢€0I¿"· ‡Ã ‰DÍ dYÞ»womm-ÌA¼)œÀ(é -¡¥ñx‚|UU¨ðÈÈH¿ÙlF›èh4êõzF# .I’T[[ëñx¡”Ífëêê|>ßÀÀ€$IÐuxåm¸(н¹µµJJ‰ð¶<Ø¢ööv8Òá’eé¼y¢Â0¯×{þüy¯× Vü81òŠ@>†%ö1,mÐòÁ6+€2ñ<*ꯚ¤Öj¯=L,7¤b‡<Uìi£e–âüDž0 Ô[~X±:|ÃáR¶X•‡!a|¬EÔEø%�È·˜!².±º'¿"¿ø ´„ÆÆF¤=#,B1êÜñ¡`ù¾",êÁ%›L&a™ñz½étzzz6wEQ†††<OUU•,ËÓÓÓ ñ˜C0„áCe³ÙG°ÙlV«Õ`0À‡ º …jkk£Ñ(•N§m6[&“ψF£ª««‹BŒ6ðÌmÄË¢,63=<R¶¿¿¿©© µ7Àà÷aKL¨TŠ Þk¢º*aY} Æ•ñÌ…è—‰ ¿/Sík¾<CKµK•’.Ó$½”  ,噊Š+p/ÒÄ8QcBWd^ÙTUmBdˆ REO‰Pćºª¦ö�·$j\ó4UQnD$"º»»Q6nxxvm¾4î©æ<ùàS\ÞçB‡# ÕÕÕE"‘Ó§O#4NolÈ¿ Åb!nØßñ·µµõ?øÁÈȈÑhDtcÌl6‡B¡P(ÔÜÜ<<< ov}}½ÉdB3g‘æb7ЄE³‘O799É36ð²!â(NÏÌÌ`LÆØÌÌŒ×똘°X,“““Éd2™LšÍf‹Å‚êÜuuuH}Sí˜)‚=(í …°jÎ<˜Ð¬{ s‡­Þ³gÊ âщÃÃÃ0‘Á�899©¢D@IcX©-à¿x¥aaQF¥z”×J‰ç¥.ÓŠVÀç¢÷·Z_¬*AAŒîg(fˆ!4b~—èUö*i]€Ämôìr� oOŒ`›ÁÁAÛºSWWwòäI^$µ«« )»üBªd>g‘ébCcÍÍÍápØãñôööâèŒväÈÞ2í Nž<©ŠðÓ‚Ë7‘H˜L¦™™¤7çr9¾r¹ªD¤R)ƒÁPUU511Ú«ìr®¸X­ÖúúzEQPIT5x¦B*•Bf�J\TUUMNNâ'‡Ãa2™ÆÇÇGFFjkkOŸ>íõzÁ$fff0=ƒÁ€ä5äÇqw‹×ë­®®F¯iÑÇÀo J_p©ŠW]]]2™„o¬‚G^544 …aZ“““Ðc£££D%×7jjj bŠÃÒ˜’ÊÓëÅü:ǃË'‹1!ò²ÌPsŸ‰8šhiQV-¿™{>væâ€Z_4‰LEËxÿ+–ïç‘É%šØå¬1„¯twwsf Ë2R½l6ÛþýûAÍE»ç@GŽ«à"ÕÐ'`ÓhkkCp*,!°<x°££"3òÅÀ'Ðä»±}ûvDÝ fÖ8�ÇÌÌL6›åñþv»Ýn·›ÍfÔ¤’e”×h4Âf®¦ŠÓ­««ƒò†<\ãÁäຊ¢À"‘Hmmm2™”$)‘H Î;¶gÏp x°Ïž= û·†Á%Æ­òm«†á· y]]]'“É ­ZŒãmò`zêïï—$‰3ÂÁ<Ãb¤þ•ñÌ‘Î2¡H}Q£¿VÆ×šû祻ð¤Y•ó@¥¨¼\^Öf¨²š¹Â¥iÑį:KűJmŽªçZCCÃÙ³gA£;::¼^/ŒÔ¼EÜ¡Ùl¥è lŠ¡÷¢•_ìÔÆI˜hMâæo°®¯ð¼3$9C9^´›czÁï÷ÂFѱ�eJÝn7„ñ\.6ÆËk' EQªªª ƒ²ƒåìÚµ Î^qžÐ“víÚÆ Ë2’Ý ƒÅbyþùçï¼óΉ‰‰ááẺ:¸cµµµmòûýÓÓÓSSScccN§¥UUU}}}ØR0’x<><<,v¬Ã¶ÃÙÀ}õÜ4‡ú`c<—‚KŽávHQo€›=N#óù7Þ r¹¡0;c(åJ­ÌÝ=ë´Uä{‘6.•F¢%»eÌFyôþÕŽ¯º#¢šRÊAR¦*FQE†^<§µµõñLJ‘û?A§`HI¥R™L†w²Ü·oŸ(VC&…íH”jEeK,K§*3Î T@äMä'|à!46› >[ü»sçα±1´t»jmm=räHmmíÌÌŒ^¯ŠÅb·ÜrK<Ïçó¸Ëå‚ËÁd2qï1´ \ј&ZuÆÆÆ`ŠF£“““UUUðO`{«ªª"‘HuuµÁ`Èd2’$år¹M›6Áª^266V]]=55…oª««‰ÄØØš% 8¢eY†æ„ày ý°³q‚]N¿äܔϊ«}\�þô§?ÝÝÝ}áÂ"” !¥ÑRåZJSÒäúy%ô.àø¢?•§ÎsÉp.£.pš+zÄ¡Êø«EI_¤ |Ò²^̧|=%ñ¢â 8ø•sv9D9·Üì�ó=¬ÈáU®ˆ]šyx W,à@ƒU³bXÄTdägíß¿ŸÛÇà3�©…KQ”©©)³ÙŒðPnØAJ¤{£ÑZœÉd¬Vk6›5›Í¹\Îh4ær¹d2‰%Ƙ,ËåQmö¾ BÕkƒÁ`6›ãñxUUÕ/ùKˆÞN§úÊØy½ÞL&ƒ“Éd>ŸŸ™™QE’$“É·D:6›ÍcccF£Ñn·ëõz¬+ŸÏëõúH$‚i³ÙŒU ð¯SË.WÄÃæƒ+¨¬…===à²Øpñ°Ë1Wð‹ðÖÖü.sO¿)Š¢8NXÛDWÑ—¨Ô»¦:†?H¥ ¿ÚcJˆ«^•\¥rÝ-P¦§TöXí¦QjÚâ<K…,jÍ¥lEEËs©°Imc¡Pø¯_}Œ3ýr°Õ‡¢}fmWÀf+X¤:~.eŽT#‹Â¸–Ö#Ò_lMÄ´/í ù= :îò8ø€¼À5+ ì�¼ñ/‹-滩bs -¼ŠÙЦ~·AAS±Z­»vízüñÇAŽy‚‚Ïçkhh`ŒÁ‹Ë ZZZ2§DNÃi)=ƒO¬µµô½á…d+qg…Þ Á`Ðáp`7{zzp ôÕ ‡Ã¼ìR8Îf³ét:rû¸¢(;vì0 ø×ápLMM!Ä•æc¨t”J¥’ɤÃáÐëõÙlÖb±àW˃‡�~Úêêjp…x<n0Ѐ3NK’499ÙØØˆŠð.ØíöX,f³ÙFGGÍf³$IF£ÑétJ’ýFQ”|>Ï”™™œuæÌ™H$b±X`C³Ûí.— it²,c¥HÆA¬¾¾ÞápȲìp8Ð {‹$äs´µµAâÑ_Œ±¾¾¾]»vÁxÕÔÔ? ÒJÀ°{{{ш·ìÆÌƒÁ ,Ëxày ve ymÎ /Æ_[m÷@mm‘žˆAÏâàE¹‚x�/&Ï®LBÒF?ŠÊ«hhå5ÄÄW•†q:w©–Üy%X±"ÇEIXå^ÛT±Ôl9ÛÓv/]ªœ„~©Ø€–‹ÄKEg§h}ì2 ÔT¹]Ú¢Eå}Õߢým¸ìÏï¥öxÞ2¡h—4ÞYUÓ‚¢@c^Hå˜âùÛÅ‘bÆ»º‹aåiÉüÒ\Üà/&=tww×ÖÖ:¡ÇGÜNOOšM‚ˆx<ž]»v±ËÅéP¹šKÄØ.õ£ª/è ‚Â«n€²···£=/Ò�9”GăAðT®èííåŽt�ŵ³ÙìùóçcÙlÖëõ¢*/:­×ë‘Ë644ÄÃü§§§].—Åbq:Édr||\¯×›ÍæX,†¦:}}}N§“'`˲ …SÑh”eY¯×3ƢѨÙlÎçóà(ŠÇã&“ijj Sõõõããã›6mÂ~º\.½^ïr¹l6›Íf«ªª  œ˜˜ðûý‡czz:—Ëa-ét:“ÉÔ××C³Ah2dYF# èÈÐæV#,¡½½w°··9á(bØÙÙ¹oß>¤¼—ðÔkL|Å3 I UµÛí†âB:.Z\’K¦¼¹ˆªà£X²WKÇU$R³hO!É& dâ¯âûÒ&€¿nE{dñÄÏ¢B¤X ¥¨ ÊY‹ª€MѤÚ2âlÑ4^í¿eœ åù‡áýŸl™L¤3éÔf%ùüóÏãÌÝ»wŸ8qB;â‰'ð—©=L…o¼Q<¦££ãèÑ£|4Õ8E/QôZâ1üþ%ÿIŇwïÞ½{÷nÕåT»ÉêììÄg>gÕµp@[[ü'NðñUbŒ=z£évøÄ‰]]]çÏŸ?qâÄÑ£GŸ|òÉÝ»wßu×]ÃÃÃG½ë®»>ö±}å+_Á¹?úѰ¥·ß~»ÅbÁgÜ2œrâ2Ä[p×]wÝ~ûíwÝu×Ñ£Go¿ýöd2i±X,‹Çã‘$Éår…B!‡ÃQSSsîܹ­[·ŽŽŽZ,“É4::‹ÅΟ?o0b±ØÖ­[cÉd²££ã‡?üá7Þ‹Å>ÿùÏ£NÑŸÿùŸßwß}ÈOîèèØ»wo&“v»Ý˜­Ûí6™L÷Ýwßèè(Þí¯|å+GýЇ>„‚BøÀ@¡0ÿááaŒÓéthqsÕUW!W ººúå—_Þ´iÓøøxuuuUUÕ[o½uÍ5ל9sÑG‹Åh4šÍf$[,–D"Fkjjb±XMMM.—3 …BA¯×ONNêõúB¡`µZ½^o2™ù>vìXcc£ÝnWÅb± d_ †‰‰ I’@¦m6›Á`€®�Àøø8Ø�6X,–ééi³Ù<==FG6›E+S(ªªªt:Ýôôôôôt:.  ï:îâÅ‹v»| æ³Ù\(Âá0½™ÍæššhKgΜé·Ûío¾ù¦ÅbùØÇ>Çc±˜Åb¹ýöÛáþI$û÷ïï{ß‹^ÆØùóçs¹œÉd2ܺžûžL&yS¦ÚÚZøáM&S,Ãýíèè¸ñÆ?ûÙÏ666òw/Ë7ÞÈßþ =z§tttð#ñøJ2Æðôòw°±±ï -~ðîÝ»F#'ÇüÆéâûŽËÝu×]ªw¼(éã„KeÌÁ›¥¥cœñY8q×ÂY"m,Or1€1sñB|ŸùÞòqøà*Ó–xÌW¿úÕ¼øª$›§''bco—t>/‰·¹Œ_·ŒuoîÁ©E¯R>g‘>m­¥¾C‡*iÊó“UF-•F¬ <“ÂÊ{¡Åì ÑçÁ'ÀÍôÜtÞÒÒ„3“‡±ËY ø+Z®yš‚i /4?—Ï\ôgˆ½yÌc¬¹¹Q°<F *bFƒÁ ¸QR,«¯¯·Z­H€˜3ÔæÍ›GFF }Ã,Ër>Ÿw¹\Œ1I’Þ~ûmLµ¾¾>ŸÏ#™Ô™ÉUUU333ÕÕÕ:½qpQ§Ói0` ‚e ΃Á`·Ûgffl6[<Gƒ \T¯×ÃÁ�ÛTUUXB¡P¶Z­™L)fð<çr9”ÛC¼ P¼àí@éÖX,÷r]]±ü~?rñ¸Õix6>OFáQOü®á¹…‘÷ñbó €�6î@ÒfAŠo*C^û•šYéªÃelÈ"‘ EClÊwkWs´IE¥|sôwÎeeŒló ÀáÌîc5¦2ó-Ú¥ŽTô/cq*ÕÇx.w]œyQL52õì´F0ÕaÜ&#ŽT¦$íC,† ÁFÄ}}ÜÓ NkGÙ8±ÊÒƒ‹j  ªÜ¨‡Ê•eÐîÇû|>ôºÉd2à étÂ4”ÉdZ[[QO¤ìâûÜÞÞÎÕù®®.,þO1“#‹[lJ¼í3c u<ˆ ÜÕŒô˜nE1›Í(XKŽ¢(V«Õd2åóy¸ !ƺ\.ƒÁ`µZ- | Ç­Vk8–$ î뉉 »Ý‰D¦§§‘ë ·Ü�f³ÙëõnÚ´irrñ@  ’É$¯„Á„îi£££z½t:\Șs8v»=Nçr¹\.E–eø±ív{"‘H¥Ro¿ý6v&›ÍÚívä7 ³Úï÷ÃŒVWWg±X ¿"gM|öPœ£§§§»»ùÛpY§R©={ö !$ãiêÝÝÝmmm¨X…»‹Å@áÚihhe¹®®1Nìrcp쀪Ð/ž@îBà¢äUeo¹Ut(­D)z5ø3Ï îŠtIe‰}!Ü9Ç_´¢® ¼}â´ÑM¶(¡S•IÖÒXÀ»³¨¬=¢-n.v!-ÕÌex p…ÆpñâÅ¢LxÑÊëó=L”/XéÚD廞ͫÉAyd.»QT±sÊŠñ†¢Ï–JÈ*u›´2šŠŠ°“ÁÁAî>«�!›ŒQ@žþ»³ñ\b1ˆžøCð½è 0‰¨FæÜŽ¿±<ê ÁNbÝÄécœn¸M.AˆA¦½^¯^¯ç:. É:™L"½ z†ÕjµÛíHE†](ŸÏcÚ°™¸\.PíD"ãŒÙlÕ~ýõ×kkk¡(@üG¯£ÑwHCCC(‚Š×ȃŸ&Nçóy$6K’”N§ñÙd2 8ó³ÙlUUE@Û07B>B¤ T!(YoÈâ>{ö,>°|Üe, M Lôöör•qpp°±±ñرc<œ¬h€9cBbÃဦÂËx@ƒ’µnÄ"óœQ‚¯>ëC^¦È欉2V¬qz-¡”à[ªùŠÊŠ0«ö°àhþ9ÚNÚÚÚ~øá’CÑÆ¥Äöò$•L]ʯ¢å`bAiU¤ŠJ|(ÓnS%¶kŸUÉÒ¢|[«¦h…RÌC¥X�ª@ ®™ÁB‚ññª¨¼pP)xITüÊõ6qá Ý*:ËsÇPY‚d,ëííåeGA|C¡ܳ¨QÊãY!@ñ:”PõÚï÷£›[$È—2oÀ»<xò>¼Êp;ûý~xÚ¾à ¼26¾GOJ„Ÿæóy«Õ:88ˆf»ÝîõzgffÌf³Ëåâ\.ñññ©©©D"‘N§‡ÓécÈårð€1€˜ºÝn„*Y,¸7&''ãñx6›G´ Ô½8uꔢ( õ2™LˆIeŒåóy¸¦ÇÇÇáÌ�'Ðëõv»+‹Á!ëêëåóùh4F1±T*‡½^/ ûý~ÇsòäILÅ9²ÙìöíÛe_4Ï÷x<(*Çñœ ´Ìï÷#òUl Ç_äööv¯×ËŽ‰D"‘صk,oðØK’„T>Ü ŸÏ‡˜]íËŽ8 ö÷÷óºâxÂy£êõcœDYlST±Ð¾§bXTy1‘¿˜Ü;­Õ´š œkâ|ø[_´Š¥Ö†\ÞrÃ? Ê¬Þl•½¤Ôòç•4ÇV9ªàªò†)íJQ[‘Y&2UÅ¢Uv*ÕÈüo ¯½€ØÜRz®—ÅgÈùŠåñG—æÄÔ™ëઠQ‡àuñðÌáAá1QV«U’¤öövøZ[[›ššxcÆØ‘#G¼^/xP;Ã"z•ïªXyÁ*œ÷0ÆÐ*�V p t»„”ÚÛÛ@kk+r²Äž Üh† ¥R)‡Ã*ÙV«¬KQ”ÉÉÉt:½mÛ6ÄY¤j›N§õz=dùééé™™n²7™L‰DqJ8�ç^ºt .´ÜA•‹éééB¡�q»ªªÊét" Š<ÕÈR®««›žžN&“ Ž„Œ_(Aă‚"I’Á`0 ù|^–åšš»Ýn2™ÒétUUU2™¬®®†Áét"Ç"“É\wÝuÓÓÓ˜Ûí6 MMMèñ�«ï í;‰DGUUÕSO=…øTÜ´JŸóz½ÍÍÍØvE¨åŽŽŽ––ijË%›†‡‡›šš†††’É$²C<Óé„X …ŠFàhß,cðT§ð^•[ |Ä× RaT}s¹ˆV^ˆæSEÝIÑfË45=ù{­m‘"ú>Åôü yELíÁ"§QùU¬Tü¦|?´ù1-Ÿ™KèêÿÏÚÛĶu¦gÿ¤D‰ß¢(Q¢%1±yƨ0 pк-¦€`ŠA'<˜ª‹BEgaxÕbºÑ²–ÚiãÅ,¼@1‹t¼ÀÀS”:c%’MI–(ñ›"EJ¤¨ÿâ_xæ9$%çÿz(6uxxxÎýq]×}Ý]ß¾ëíâ ¬Î#›·Õ8µª]+d÷Yhcñ`V¶ï¥¯íÚ9Zˆ§™Š¸¹U’››™ƒÁ wv½^ç¦äÑÑD `uªr5 A]NQï£G67798ô@¹\–a?°$õÝÆÆ†–©­¯¯‹$ 6$j³N€H$Q ¹N¦ª€š¥ ºÔG“‡ÃÁÁÁòòòîîîÄÄ/ÀßOìf³É$Ý�1=ÓT*ùÙ¹\.·ÛÍ0Áåå%£>ŸozzúwÞ‰Çã0Ããããh™ŠÅ"Ò#t«NÖNÅëõzÞü!£$‰jµ =88800�oŒD•óA"E/2<<|yyI’èt:¡Pèòò2ûý~—ˉD:N …Bgÿàà�±V$¨×ëÏŸ?ËçóµZ d‰n)›Í^\\°j‚ [­V«Õ*²c™ë!M†kÉd2ÐBtÀJ¬BZ__g,q~~žmH,ŽF,Ë—’J¥X:½°° ¿äŽ•Yw²–Šë¾µ$«À²WoÃc•)ËËË©àŒÈ&#í|;KVëúÃ…í¦øÛ _f¬èºÑ½Wqé°š‚Ú^<¼39A*³A¹ðó“ϳ}¿¹ï¼»¸¿ÀÉ0¾¦„©ÿ È$ÃY¸Î§è5šØÕТ+áaN9 dg@LÏ ®ÈRþtå3,l¤R"£ÔþHÝgæì±Ô&&Û,Û;ÓÍR™–«àת1———×ÖÖp72y?‰²dË¢¯@Â'Ó‚‰OA5]¯×ïß¿ÿë_ÿšb? •J¥z½žH$`e™&ƒ”&jƒÁ““þ’!çZ­†þGVz÷SòÇã9<<„]oµZñxîYd @·J_‡¡ÎÏÏÙÛBÌm·Ûp¹\nhhÈï÷1—¡;¿X,NNN8[ÚŽp8ŒçùƯ_¿Îçó?øÁ ÓONN …‚ßfÚ9NMM1¸‹Å�ǤMÂfCnr^B6??¯%Eº4ŽNMæ4µËaVfóöÓе“鵞Yk¿ˆ5Õ,!Ÿ0U€Ü»úX‹s�Û v-çûïo7Ÿô^m½~æ|´(ÅŠZ]CPI•ù¿–*©Kbø*Ï+ãf7+=^g®Ï;¾múé*\sý¡Iµy[›_†©¹ì¥©è3æî|HÄ<+Âãa‰#¿ 3U˜G°t¨zOÿd:m˜çƒ÷œt«š´2£³Þ‚  @ùíPøË;Á\/#å»I<¸{ôÄ*¦ð¦J“Jl7oÞ®¤˜œœ<;;s»Ý@:Dp„=Úˆ å'ÑétªÕª×ëEÂOÏÑ`†‡‡[­ú%Øl*÷€X&/�� �IDATp8|zz‡Q²bp’³¿¿ŸN§‡‡‡ñºd^äòò‹ì5888<<\*•}ðûýL'´Z-¸“f³yqq100�î„eÓþþ>sË(¬ÓXcÆ«ú$F£q$‘€Ë‘F8ÆÕÕõÆ«ÜÂʉN‚oG[©Qa°åšÎ¥ÁÁAò±’–+e4ÇΩR§3Š¥.uJ´nÁ}‰-ã™þîß¡¸¼RMÛ_‡ÚËäú þ>UiW'··N ýÕ;׉þ×L×ìº=8Þçê¸ÞÒðš©ÛéXé°pŠ.,é‘Ò€©ÕÑC%)H¯ejVm%½?ÑjyyùñãÇ<Ûz&õb§#všÉ,-r‘Y¯7[Ó¬ ÁŒ–Ä™^ªæIê½ô¡¬×Kå¢ ×täˆè(üÐБ1 5f³900Ðjµ<ÏË—/™ÈCÔn·‡‡‡GFF.//i NOO=lp³Ù„‘n·Û———­V óÔááa·ÛÍÜ”£mÐËÀPØZ`Ö„{ëÅÅ2‚܆©òêt: î¡”õz½ÃÃÃX$Õj5x‚ããcSrã§§§Ì<凇‡iYêõz  =—Ëå±±1R _S$á"ÃCœý÷ÿ·¾GìÕh’‰i/pH4Wû!Nm6›¨’ø­Û·o³ÕΉá8Åu]…ªÖ°±Ó-X1ÎY8›I¢é¬ »ÂÂ×™i¸2Xw5VpZ-õŸê£³úÎ .Í_=Ç`NŸ;Í…úÃ÷Ökœž$}@çç±Hl§„À̱]ç,¦Ëä úÌ‹›Z mr6¿NöÚ;ÏÖâHÌqñÀ$Þ5>zôˆ:‹á“ 瘟Ÿ·È(“Áæ‹ ƒ<¥‰Db}}ÈXÇ~àÅ•JØWYŠâ>.lkzM6¸ŒUü`~~b�gKŠzpp@ï"þío¡iypp@Àœ/PØ™œœœ››cg»Ý&JB):].W2™êi·Û2PâT­ä�F£/..MhµZȇèÈ4µZ-3‹Ðl6Á£Ð&ù|¾ááa ò†‡‡«Õ*¯–U©TjµÊ¥f³yyyév»i,0È` Ýív·Û ðåóù&'')ðÇÆÆxkZ‡D"w}~~îõz9m¤´d¯±±1¿ßëÖ-í¬fù‡…Æ`<9Èó+ú~ …B6›]]]õù|æÅô‰ÏçÃD{ ŸÏoooC;ݾ}x]»ÄÕ[ómê¶´d‚ÚQ=XÙBÁTm‡¨r‹¬6ÿ•Ì #& mñæ3ÕKêd>ºrË]¬øÖ'šKŽèr,µì#á½>ïÛ•Ö¸&™ì4/rÒ¿½° s ««zõJO$S£ÖÕèJeÅÚÚÚÜÜ#-–GP×/Ø™9¬E˜&Ô£÷"¼Z¨ÔDæL¯0Yý¥Ù=è.Ÿ››£Ä#%è•–þ€¾ëÒ!$[«««<Ì>Ÿovv6ŸÏ‡B¡/^µùXÝñ3¬òüü<QÃçó% ¶?|øGµµ5Î ‡"¬/xÁÊÊ ‘ÉÞÍÍM2u%/#F-Àˆ8& ’!I]—––,¯GÕº»»›J¥Ð&!E{êñxXÔÌ(�ªÓññqlJ].êUÂ(Ðp8 Ø‚™„×륂±¡gò�ˆ©\.³Ã‡-###PN‡å FCå.—ëµR©€J)A߸qƒuÐn·›yiΟéŠáááP(ÄŽÏ@ @BÂ]ƒ ‰x<ÎXæE£Qèx<ÎE†‡ÁƉÿ& /€rç42™ÌÖÖV"‘à–ˆF£OŸ>ÝÝÝýì³ÏЀõÃ' …P(ÄãÀWóé§ŸÒO<|øÙÑÑÑd2ÉÏõzýä䥂Ôt: •- 2=¶R$óDˆã5-ÜMBÕš5cõœ³”T5&×#Ä*OÀ¯3™' ÿZ”Úµ«_Ü[iyœÌó•&u}}YЉÁš¦ë•‚ººÎõz0g¬×ôw¥6g‡a^)äeèÜÍjÚYõ›Ó˜×ŸÏè:-“é=`®>VN–C½¡4BRpS^9›+£ ì1Už¦ ¤˜ ÆÏž=K§ÓxÀ™Sæ4,Ï6¬ìÄÄ2lÈLü÷áÇ*<)µÖÖÖ8+~õ=‚oXYYAû”J¥pòù|wîÜÁ‰o}}½^¯Ó”Ðm¬­­‘!È:&„p(ºuëV"‘À’‹'8^ŸÏ···GÙ‰D&''\Xª|vv622‚÷€O­VCÒ (]­V‡‡‡ŒB¡Ð7ÆÇÇ)Æâñ8âTôE û‰Dbpp0£M¿#¶;¨'ÀûÕ©ð%úÂôùùy6›%vÓL ¿ûj·ÛøMaoF/..ÔU˜z'æ'ü~:~÷Ýw;Îÿþïÿò½$“ÉÉÉÉñññv»]©Tãb=;11¡MGOž<A &õ0ÿìÙ3Jþwmm‰nÝ¥ÉdòââBÂ\²$„Ïç{öìÒgó1\]]››SÌÓÁME‰ w4uè1#�wµ¹Ø\5“â€F‚,%hÁˆð¡µÖ®À q˜XÆÆ×s:ƒ­)k약ÌwqNP_37 \ù¢>¦%ý±«Ûvÿ\×õãYZ`kžË ”3T¾Þ‚5n×·îj¾­ùëËV9O7uf·aÞd¤ª&ÒÑÓñF6F×v"K[b¸8°»ŠË¤FÂÇÜÜ\­VÓ¼ØÊÊ ¶ÌŸàEºººšÍfqšs½YEÉɈ|ôèWU7ºãÀ:�@q)àŠq_( KKK,.n6›ÏŸ?G¨°¶¶vvv†l‰#P„2yÇ[°Ï’ÅËpÅõzýüüs$sкÑhd³Ùýýýf³Ùn·)ºÁèPºÝnÌòH*ccc“““SSS@F@OdJ2ŠŒö�šp¿àïqßët:áp˜)V7ã½áv»I°˜â±ÈaxxØï÷»Ýî³³3¸b'¸hâ5Ýœ {ŠJà�F»¸¸ ‚â†r …B!¯×û½ï}odd‡p80£=::Bæ j§dL—ÆÌ÷ 6-à{°Jj%ibèpô#«•Ëeáš³qfô‘2Æèjjm>)|ÅìDf4_fÞ®²øíjçã$ ÌâÌdË9N×rYÍDW©üö èã!ät·B– Ps¤£Oæø W½ŽÊ¨×v{J§Üu”K¹Ô‹6;¸;h)XÚ^ŸQZ7óµDL]ÅsâM³9Sq!Y§¹^Cg…æG÷¥EÈ‹LFQþàÁ-Àj]{¾tbxä¹Þxܼyóôôtrròüüüìì %%qËZûŒlÉeì6‰bü‘Ί_„ÖÚNØl3…³JÓ¢¦µnLŠŽ0<<Ì4 —Ëõ½ï}ïôô´V«Åãqì‰Ün·Çãq»ÝŒ/ÐgD"‘V«Å °QBÔÔjµäwÍæŽÏ®MšM±Éj»Ùl*…Al"‘ù ™V  Ò"À‡ãÔÄqHœ­ôKõz_ÄÊÛõÆ„1ÇÃàzV&¨áQÎÏÏÏÏÏ/..B¡.Åb‘Ï‹1¶¯ÛÛÛóóóÕjߨïP(DF×#¤‚À ÐåˆÁ6ŸzS"¡'©U1‰É(,]ŸÒ^›y*¯d»ª€œŠUKvh½»l%¯”®\Ÿ+îºÖ·OÔícãqMjú­õô·Àëãca•Ï&Âîrl 4A:ç ¹ù»]7ê¨q£.ž™™988€ ޤ5]÷=9ó¶Œ4t-†‚ n &ƒ6¶Î_¸ œ)}nnnmm"ÈçóÉ^ )ƒi¼…›yËJŸŠÁµZmmmmbb"Ê3•UkBœ„0rLâ¬×ëÙlvgg§Ñh ì$~©Fã)%kª™«MÚ¡ážM/ÍfsmmmaaQ5 áÉsÍfS)„Ý�sssZææææççñÃH§Ó[[[,æDfƒÄˆDqL&áŠËåòåå%œ %†¨©Ýn7œ‡ßÇãñx¼Ñh1=­Õjä º P`&ÚªçˆÅbçççñx|zzz€Žää䄊ñùéi‰²ýòò’hK.„* Á`ŸŸŸw:R Å>i ›žipppdd$•Jq}dåß~zzŠñÆÉÉI¹\>==ÝÜÜä£!0 ƒ}ôѳgϦ¦¦‰Äƒ¸¼óóó‹‹‹óóóˆ677¹††#"ãÜó¦eŽ”¦d@RÏ©:¿‘B,4¸+ý« Úé4Åée/a"+ìð8æd/º†Ç^(…IxôASº¶½X^ö0 œó¹WYW'•äæeí50læ§ß‘ö±N·—IœùF|`a…Ò#ÁgrbaZµ§©Ê·ÎÐLHN�Ú<¸õµq»omm‘ŠÌ/Ãìi`Þ´i‡Ðf¦>Q4å ò-XZZ¢`~Åñ%ÃÀ•¡P(ܼyóéÓ§ˆChíñ�Û5óòSµÆ¼ûææ&¦@”Z6G( — ådˆ™™™õõušó‚Kd‰=§Ë°¢âôÖKKK(ˆ£ºÂ‰Dblllaa¡Ýn×ëu�%€xÀ™\.W(òù<˜>š%B?›;Ûí6³ж QDw:LØ®ƒÕÒÅÅE³Ù<???==ÅCI­�¤ñèè(aI´*z²H®7æ¬^¯jDé‡ÌÄPÛÐЃo¤„‹‹‹““ö†¢‰âã°…‰­z…““d¬@�CÝ$‡×ë%y<žr¹LÒº¸¸øàƒâñøððð­[·²Ùl4¥!ÎçódôB¡€“ ´‰T]Ü?l%£3sC2fÞ Ä� !u€³È“ÆZEËXAh™˜>2GR•¦ÇÐõf –žV‹¯îŠ~+OHÈgMe›vjÎsý¡½ñ•D‚Ó‚ÚlœDo×Làü]k1p/.½W¤½–%†E­\™sœRÎ>'q³ ­3£‚€d6±~þž€Bl2E™ëëë|»J'ÒA«O´ˆ,}O@á´·4ŒbÆD˜ão$*“óQ²!¤’W–——ëõúÒÒŸD™®7îžÖ3 òJÞGÚ³`Ýn·åÀÌsË^b|—C™œP766úlmmÕëõ¹¹9ÌÒé4e×ââ¢×ëåyÆöN—”-iáá‰æ2vvJvâzãwD©Ú0“Vyþü¹¶NÆb±ƒƒƒX,–Éd¾þúk°õÉÉÉd2ÉRLÔD;;;á7ÎÏÏ ¬pŨ•‰˜>¸Óåååéé)–JTÙ…BáääWT¡=0ôÀôZÄÆâh-ÈdY4ˆM.—ƒF†ÿ ©¨f§ögC½^'?a¤Š=½ ‡N�Vm+@ÓÔn·›˜ÎØ P§Ó!1„Ãa¶ý°IÐŒ4 …FFFØD„?ùÅÅ[ƒ —îܹƒß**ç'Ož0aŽô–Û�ëCܹ‘ø£›¶ÕjAN„B¡ î¥T*Ez@Ϧ'¼žöWú:ÓRÅâ,9¸é&‰¹Êy«\³4K¥g‡ÎRÝÚ$aÁú®?ÜÞháôqNÊÓ9’ÖKKéÔõXµoÿûrÕ^�K¯^©?>Ó'å8+kr²RÑ} €¢¸MÁ=ÌæF}®ˆ/óõæ }È*Z©‚15]KUàègÓȈåRÎé6ŸŸaGÏ£›ì”9’Ù}›$’¦(”ÛØ´Ûm6/’ÉX༲²B¼7ÀqHEô^ggg4:ä6ÄE•J%‹MMMA (à<ɦJ»»»„ B„¯I«oHØç+q}䶤胥6Rœ›7oâX‡a5X<óeßÿþ÷yM6›E™S­Vñ@nÌCxõûýÕj+ú}*qø�·ÛÝn·ñé£!�ô'+`u‡%…9sÈ"{ONN ¯ÁñjµZµZ¥ó8==ýæ›o*•JµZ…��"4#6å„fŽ5m½^‡$@¡;00À90TAüE# qˆ’Éd£ÑˆÇã|"ŽÌÑŽŽŽÈ|wGGGl M¥RÔÛÛÛô8lÏÌÌÐMš²¶úý~Ì_C¡P8ÆÃÊçó± œÇ &´Ñº'» {íP±dèèhI9]' œF~N·T39îœÑÏiÄi;™{=»†YKøÞK_ÓuB°—¶Ó»ÒÇè-ÜUs%ý­»Î ]©Gê#�µTCÖ›ieõt@áÜaf ÜdÃ@ÆÍÒƒVÔä'ˆÔè1LA…ËØ ¡^CM¤õÈb§+• O/ödTôš –©iMNÖ!%@flll0•†çÁÌÌ Þ ä˜§OŸ‚ü¯MU+- ȺõT*¥tÈ( HWGGGggg•ÔyðÙi¤ø/ ’l§kŽÀ©\.C‡Ld–­¢B–`>¡’ÉdµZD"À>ív›µ°¥R‰€}gRèîÓgPb7 ’ DÏ@ P©TÀvðÀ�ð‘/Ååå% ‰įápÚ Ödÿììl||œˆÏ—>00€Å·×ëM¥Rd)þ‹Ò9,ÝŒßï¹¢a= CyÀtÈ€Q———F:ë'Æ›ONNd€Ñn·Ù“Ê$v*•b3’Ïç[\\Ä[—Û’lÁ³" =wÔüüüÜÜRW¾å'Ož`5ˆ_S¡PX^^Ö-虛DŽgc›¦`ÚÒYáØ ÙKyÀ­WrZîªN1h¯¹Ó2Ï"böyÎ`匿N“3KY¨ƒ é® Ö[íz»³¹Z•tëç4ò•ðQQ¬,Û>|ˆ!—ë=ÊÍu] zkª¾ë¤{¯¡y3”kI¡åÙçê±ÃZRHF¡ˆ6-çL%ƒÇL‘«Ë°Ž1}c€q°™Cn”J¥–––666(ÿõ}ðÁOž<1÷5‚¿Ý¾}ûÉ“'¼ÝgŸ}öâÅ Ó*ÃårݼysggG%!žئâ±ajÃ-o¾s飼wô+²‹ ¸ é"Mr)xGð‡¡¡¡ÑÑQÖM×jµ\.G¬V«¶ÙlNOOƒõ£Im6›¡P§#Px6óëOOO$?eÊÁõÆÖôââ"›Í’8,“exçs|(ÞËå2Ãeš/ƒ 7ðaiDh;.//©èa&x&F ïB@Lþ ùà t-$!„RœR hµZlfì{8>>%cŸ(ö4”l¶Àndttôèèh{{ÇV`4ö;i![ÿ¸¨?ô]Ã?±ÏŽy I˜TŸyW›"@ËßÅü_©®Í±ÙvYO¢¥ê¦úHwzYò¼•‘iêg {­ñq½åfâ>&FNçž^®öJº~V¸f’¸Î¦Sç•’“Ï‚)˜³· æ¥wýá"YiI͈& 0k°Þ´ó4¡!- 3‡û-s=Ëˈ¸Æ#±°°àr¹xG¥Táz³å˜bU¦ÔBÈ6“¢˜:Ånóhd¸A~P£`Ç*a¤R)àsíó Ïž=›››ÃN+À,w3ÎV àáÇ?~öìÆ 'è\u%‘Ër•~‚ájåÎäää$•Jžs&gggpÈ HrÅèt:�&KP†“P¯µ …˜Ü‰“¸¸¸�­È¢ØÇu•hâ3ã8OÀ“í  XÇ`×ååe³Ùd:Aý nd8Ίý£(‘0}‚0GT688ˆ•ì……ƒÖtÈvaÈI~@ 3IÀÌ€,@`‚† y.+QÉ—ðU|;|SðØc’½©{à_Ôø_ïj¿´°MéõYw—éiýý•KÐ,7$§Ñ‚†iƒÚßlîʵk]õ¯½vˆYÕd¯_1s§“Hèµðîmÿ¼]bxÛâšÌu¶f:?9òdb%1Qd¦sÐYk(7XM¢:Ë¿HšÓ,‚yƒšû/­ºÀ´#5£³b¥¢$‘‘I´……ǃ¾Èüt¼‘ôE�Á²I®gI[ÚMÛ"^ÆzZ—±€@Ÿ§GZGà ¬˜Gª/ûn³ SËÂtža˜¤%eè?û³?ƒE888H$Íf3‹1 €3ÝÙÙŸyf”<‚†ñ%)ÌÉ..—‹¿§$çáb M•îH#Ö^¯—ëÀÈ›Ûí&‡ñJ<õX:Íÿžœœ´Z­H$B/Bò`z®ÝnŒŒŒ�(‘ŸLkµZH‰°ã¦0)·•¼FAÆ…+—˰)4|.†Ýêõúåå%ñk¼=ÎÏÏ‹Å"ÞØÇú|¾W¯^½óÎ;„õH$"&‰mgg7Yå€D"Á²9å5‚‰DŸÍ”Ùl95ÿköˆŸTë gIÓ;Ïé3ª¿1-Z­â ú×à];þþu·U‰ö²øtôþ®«ýùûœ¹1ÿÕy­œ‡ýîC3Ø®Mós:³ñu2µ VK†Í‰0"¯U[@èƒ>899 ‡ÃÄD¢ZQ‹îç®e'ŒLFÕjøË\rk^tõ×S @ð¾êÊU¿›[—•«Ô4˜¶tæÎN9e/AFz#óeÔƒìq”íþƒÈUáp˜*ÂÖ4ÒД²<–Í3‘!¶ºM?mnn...â¾™H$hþ¸’‹‹‹ív[A' F"‘ÃÃÃééé\.ǵ•HTÎìVô)j§Ó!fñ70Ìà3ìÔÄK.ºÕjU«U•Ò ýú|>öS’9ø™”Àï¾§2®Ì@ (ÏŽ¼v»½··—H$Ф²çytt”OÊÂÎV«…Íj§ÓA«Õ0É|.©’à€¼ÚíöÉÉ /úãòò’רW€[†ºPµNóÔh4„‚¹aüG#‚«R(êt:…BfQ‰Y=¥ŒÙWVV?~ìr¹Ø7çr¹ö÷÷‘ûý~Üôh5Ô:èαZygEl²¬NŽAñÎL$V¼2) ªµð^+»˜À]ƒµ3^?Ž÷:¬«÷¢é®©ñšCý³à[¸«ö*áûdñ½Ü\†aÜ55¬æ„·µÌ’§z™M½^—nWrR~Ò8 >xð`ff†MX/^¼+ËWgSÜ&ÌcÔàÀÀé«x‡ÑÂLÃkè÷3™ ¥«ë¥(ð+uH(Ò Æ4ÆgÔ\ôèè(®dkkk òÈ¥ÇÌ”±«Y#ü=/ƒ<|þü9L2vù|žã÷û‰Ñ™Læã?FÃÎ94›Md'â‡Yæ•N§=zD‘¸¼¼ èÁžÈt:­Y…àV«µ°°0???11177—Íf[­ÖÔÔÔ­[·xßR©%022‚Ò7€eðÿ) ív{dd‰' Ëå"dóut:|>O†@2‡“É$³cÚsÀ´p0L&“LHð…¶Z-¢-Õ:áÆ›‰kÍKã*ê~óGëÒW±V: ŽCóŽ¡q¢Ýá¢ä÷ûýô.>Ÿr>ü/'Öh4Ø(GÕOŽdC]l<x½^qB/ëóùð€ÒÞlâ>‹Ki\¾ýöÛB¡011¹<…K"‘€…öù|·oßæš×j5fr¹œ×ëå³Ù¬¤}[[[FJp3›Õ›ºjžúõõudž#E�3\ðŒHðm­ä&ýhÕ´×´b±"•%ì1Cœs&N{‚ûNHTÙuD·ïmEEË"¨kÄvj…úß]W®z} À®ªSç§u2ø½TV]wvšòdvÖ3UË—¡e HŒ8‘quuU&_²QJ§Óèô‰Å:@CuÊ÷‘ÿu¹\¤¹‡¢Ý6MÁT›ƒêšñ]³Ä¬¥\\\D­!S jvÝÍ:šätHýˆƒ,¹d¼ƒ A!Ïéñî8­šâ]r!ãÁ…BAVæ?MÒÄ2eà‹/tæ�)HPˆ¡™LfnnŽYÞNštŠ(šh§Hl®ßÞÞ…Bpår¹V«MLLäóyŒ¯wwwÁdJ¥ÒÔÔµ<Ò~ $ŠÅ"„*b¡ÁÁA&°ˆ¹Xa]×h4ŠÅâÁÁ¦ÑïW«UƪÕ*Ig=ZÚDÄNø/ !$¥¢/‹|œÆðð0r ˆ Ì‡IÆ #¼ZywødXk¨lû`/�ˆ¥Æœ• £Ø"Á™£ÎbÙ TR—È1ËÃB£ÓéPÝ“¤Mâ“^\\Œ¥ÓijÝÉØ„ŒŽŽ>xð€ï4 =yòäÑ£GLߟƒ\É2ïšB,‘m Ürf¿«M´LÀñÄ5›Í M«™v–&‡GL3f»` ™êhš r®¶œîÑÒ/ŽÌ£®t/!PÝtiëªü¼èbîÙvº‚÷oM®Ë1|·µ6×4&ºæÁM‚×ÄÙùïììl¹\ÖSÒ#|IË`ÑðhM&ì½)’3’Ö’Ð@Xî@Z‘¦öVgår¹fgg‘ôLMM½xñbvv6›Í2C$û¹®vCò{¡•·Œì'N#Ï×вöá 1ÅBZˆî¿´´ô«_ýJËU‚2GâÜL‰¸nÉNÌ/YÔ£GZ­ËæÖ××AøD|;¡PˆeaÀë•J…ÁfÆÇX/Ck5:::<<Œáv§Ó™˜˜�Õ!´Æ¸Ýn|È ¥RÉçó%“IXfÊ„ö€Ñ3d@µNÍdœÊm†È¹ŒÐÅ ‘‘ þó—àû¸½âoZ,áoAœðê@wT«Õ˜¦D"¸#œåWÄTk;Ý8U³Ù1CV ƒR«Õ"‘–‚¼ —§7Hf®àQ „w™z�� �IDATÈ ô+¥R‰$Çø…¶¿ ‰Wwú0B‰y<ž|>É”ˆj¥ôàÁËÎH0¬xfË4ÉelÊ´� ©’¬èÙ¸îJØZ¿hm9ìÊ:\ÇÉIe[×uœ®¾ Ðú³oåkw-Žá;¬wî%½êEÜ»®Z©f)|œŒ®5£`.¼´üïÌÖ Q\áˆò¦zÚ„ÈMµ¨‚2.oBù·¶¶´ÚŒo†øÁ)¦Óiœ÷Å劻S×½b)ð\o ,ù]™”íîî"Ù2%@zUª›»Ïêõº4jMæÄĦllfaÈG“äIç`RÊf˜ÐÿJæ{ûömì61„`7‹‚YQIì;??ßßßç£ÑáÁ€ók À»c±X±Xl6›•J%‰�[Ãë¢×dáþHÁ`°X,²‹†x‰P‹½ñ pØ0/],¡``¤5ZŒ0‰z™·F:dDœ˜˜…BÅb±\.W«U%$&Š1kb¶�%+-¢)­P(trrÂÁ„C{ `7[¯×É1jP á=*¬V«522‰ÝÝÝ‘‘‘ÑÑÑR©0¥9 ú \cùŽ$Nãk¢¬¡lÒwª;Y·%e–x)îLn¤É"è¶ÑCa>ËÖ*7×® ï#=wn`îªí±|¼AOn¯”ãt ¼>Mk ¥ºVÒ½¢åõw÷͵8kx¤ÏˆAk,°×ÎUtêå…gzØ™ä„éy";kuˆæ¸£‰0Ê^Iö¹‚û%k6›…�øATw*E½Ëåzúô©Hon_ýi±´æÌ···½^/s¤@+¼5 ˜¤ j`-–ŒÉ߀Ãà™ œÉdØŸ“J¥�÷)ÊVVV¼^/]¹àW>;Úêõúòò2ë½Ô³ ªÃl§ð6XXXàWð_b¢÷Õ> 8ìšY±ÀãS+ çóy†cth\¼^ï³gÏŽŽŽ�뀤ÍÇš‚ÐFeM) '…K O¸D‚yvv†]D«ÕÊårgggLùÂî0ËV­VqN…E  ³3- +Û°ªV«±X  ¼%(ùãñ8;AÅR@Ó¬¸\®b±¸»»{ttT­V+• Ë݆‡‡ñ«Àiƒ©4€x˜mdˆe° &á?ÏA Få´áçA“în·cA|Óé47$¶ËågŸzVFGFF¨6¸IàQ\.×íÛ·Ùóñ‰DèV±QAb��K¬A …B¡Pèììì'?ù‰éO777G¥ÂŠ@Pbs2¹Ó+´VÆÝΨ8ÐÇ8Èvs® Ðr!'÷à4ê°üìœ+{±¹2q°ðùkŠ] ½ôr;½šcèE*˜G4OQPË0¤+õá¼.Ö¹ó³9Ó¼®\ä0}”·»Òd¿°¨C=xðÀ4¢Pô·6VòõÐ ¬¬¬Pàd•,–I¿®pL„%ä­¬¬Pg¡8bؘMs<!æöM]|cà’ɤ×ëEˆbD¾ü<„¡Pm%þ²P3oþ�S¬­­­•Ëå/¿üòàà€ò\ ¼® Ÿ”H*@ä$}äÝÝ] ©ƒƒƒÕÕUº¿ßŸÉdàZ·¶¶R©Ôîî.­Æœ™L¦ÙlÎÎΞѠ }>ßøø8ÊQ&†††€5¨ÊÀ{ï½GìcYNJàþ̲a\h·ÛÌQÅ0pÀvO¾&èH†Èd…-¨‡o“ Ü5w¨T*(Ž´ß·Û FÏ28-KÀ 4‰êž½ |.ø´¹œå¿ææ «jµõ>ï•í)W�˜Èãñ‹E !·ÛÝét²Ù,Ëã …Âññ1Ç×tôÀÀ@2™Dƒ;;;ËtÅèèèÉÉ Ü>f‹sss­V y»}@8çççõD µ@9–Ïçc±Ø¯~õ+n]žS9*Ò‰bÖK™Å# ógºã€› Ì©`ÓæÈtèë³§Ó„Lß:Å1³ü5]Kl¨e¨ÞÝræpú‡šgu¥×œe¾d2"]Ó•sßœ“o ½®¾†Î7vf‹+åVf2°Ö5_¹»¿ Ù(ž---a ; ‡Ìä½Åt™-hïôeãe$…µ€~¤ATåæ,oa d‰¤µ&•JšN�333ØÈß ¶Ü¼“ÌT ó›ßÐé/..º\®o¿ýVÖ§¼)Çןt:ýøñc Xñ„`$"‘²=•JṯÝÄwÖ4Ò lmmÊåÛÁïú|>ΙŠD JöÎ;¸¥F£ÑÛ·o×jµgÏž¡‘ÿð鑽^ïìì,FI###¡PˆƒcVAÅ ÏÏÏ)„ñž‹ÅbξËËK¶o’NOOùW ‚a…„ +R%¤8˜m  …Bƒƒƒ¨u‰žTâ4+ 4‰Dc¥óós<M™‰Ó 1Vtl…cs"‘Àå”·ääµäÃív3þ–Ä„•V£T*Ñë°´^¯—J%¥.šæÝ cPårÒ þ»p ápx||\{§Ó¹qãÆää$üd8©šl7oÞ$Ër§ÁIh 6‚…›9•Jmmmýä'?‹fQ×ë%X" -™LÀææ¦¹WÐé!Jý$Ã`“îµ)²k’0Ã4=Ö,û½‹ùë*‹¥ªïÓ£8™ƒ>îsZUÝ«àîš®deÝÕM¶kðèc‘ÔU«Ú erz˜X«Çœý”<G»îuÂP]?w�µF2™ÜØØ@W£dðúR™¦áåæ¶²²‚Á5ážgUÁZóý}-ìèè(}´üDgggq*UÊQBB-ʃ$Q©‰’©\¢]àGGGŸ>}ŠW„T¶ 9d Ì…ä+Nuf‚T´ö|d,ê\.ÞÎXïµZ-®ÚpäT*%9“äƒOž<!pa™¢ªT*ÈS©T½^Ïd2‘H¤R©°LMo‘Éd’É$ƒÊd „1Ú¾099ÙjµŽ‘KÖëu |d¦PÐ(îÁ@<ÕgÕ»z(ŠÍÐH’dyMȽA$*f›°È Z<?>>©V« ‘I2ÅÍðA.—cw[±XÄ•DEzã+`o(i¾Ñhð‰pi%–J%xr¼Á+• ˆÄC)â–=q dèzÿæ5L~ÐBáÒ“y¹\æh£££¤IvÞ‘‡`,HÉ###ì:===ÅbõzýÎ;ÜɈȵ·‡ïÚ¤¸ˆé³³³Üº¸ZÉ ÓI„àÍfÓ\ŸnDòé2+td` É °é?ÖÇÑY%6Ñœƒ˜‚C'pdnSت(]>áÎ’×j,z-èЯ\�×Õ‚ðZ‰á­Æ’]½7B÷Áºº‡wmºZ:g=ȇ…B†Ú–zmqqq}}]ûë766¸ôx ™°‰úS j`Met�îšzSø,ÚÜÜ4÷Že³Yé\ÍôS(ž>}ÊŽe,@-‰J×××.éø§r¹L2À(›Ö›åÈ@ie|f²&D|žaŸÏ—KãÿðáC–®Ôj5�_h�4)¢Ì:::º´´Ä‰‰pߤÒ4b–CpÐÚ²ì }xxxjj jˆ<›Í’9ë0Ìà?ô"¨‘]†ÃáÃÃÃb±ˆæ§T* Äb±ÃÃC aÌbq¾CDD½ … öBä½¼¼,‹XŸ"éÁˆai¿ßpp€gj»Ýfz�-2–à>ŸËëΛ?ØQär¹|>´ ¥)–×¥R©\.—Ëe/@·pí&z<ž\.‡ßÐÐKXIQ ]³ºàfE®JpÀYP/´Åbý.àw gE5S«Õ8ŸD"199É¥Èf³d¿ß‰DŽŽŽpáM§Óccc¸'i‹¸q›››L<}ú.gllŒ;DÔØëÖëõ‰‰ %µf$5ÍJåk-0€HzUAÊP)ªÍ©òßdÌÑ}«äï:[`Ðúæu3}þ¯©M饈í³ñíºPÒ•3 ÎÍkNƒUgëПQ_Ù5­Y›‚Ìæ£P(üæ7¿yñâH4¥N8’Èò>üðÃ………ǃ8Yˆ?/--™'�­Šd“Q X?�´Sê>‘HheÐîî®ÄH£££|ð9…gú¼’~–——éEtéÄâBù2nFSGZºÅך_YXX�z¢Šç1ÞÚÚÂ'Îår=~ü8ŸÏ§R)f;åú²<é j}VWWC¡‘"i­?fÐãGGG$!Ç3>>NkEäeŽy(f m2+ók‡¤ŠÁf¢ N˜JÜív‹E˜a&¨öz½$Äü<00À[3ó ÌBAm‹\'ŸÏ ¥R)<'hS4EäuqqPŠŠ›@Ïu£6gúmü0ÈçççÌ%€õsz£££ô1´`ettØ#]´F£ÁNÞI´üàà ½†0Ô×âD‹à¤Îëõ‹ELdå‹Å…B_~ù%¯Üßß—Íûîî®ÖRÉâW±’‰2NŽÂ²1×¾*¶˜?X‚¤"]矺Vô&Xd†`3þvÕ§ZmG$gÑl5NèÅZìc†»>«ÜzHÎ2½ZõÿfŽá­lÿ®éJØë]ÝHz†›ËŸ¥{c@­$¾ TO2ò´Œ€ð¹³>bMUÐôòn”@mccû ­)¦)a BrXÓßÂ㺌-Ç: Ö5kK³¡y;` Ž…þÕHªÔ¥øOÈæhhhèÙ³g˜÷™)J«:M‡TéVÍE"Å�° ù°Ÿ}öQ~ww—q*$¡íìì,CBBóAf¶··o߾̀%?¸¥RaˆŒ�-ª� )ñ‘¡eÙÏèY¦&u)Å;.Bá¹bÌ7Pn#ìÉår á\véx<ÎýCZ—¼ˆ¼h4z|| mNß000€1v{ÈdÔ¢åñxvww'''÷»ßÍÏÏ3àGv˜j”J¥ÑÑQ±¯^½B5„ÙIµZl6›7nÜÐÚ"¼öÂá0svår™I*Ú!*)º“F£ÁÎTÌp ¼:99ÕxñâE4ExÊ'… [XXÀdEV]¦#wô›Ì"¥¥6gnô÷Ö‚hËlÕY›º>W·]ñ½¬?ûX®öQ¬ÖWΘ*ü+-ð¬ÏVè›á¯cuŃó2õ²ýûn&z}¦3úä çG2?¹å^B™ ÀÍGPÄ7í QôÃÓš†¦(SŽq–¿jl¾ZrþBº¶ƒc‡&é4ð…­´Ù©èšsæÄb‘ÏŒ �€¼‹±”1`=ãÄ>ŸOÃù|^h„uœÑøYiÀtÙ“ ¶fŽ´\É ”µ|Ÿäª„K3Q>™L¢€bFlbb„Íëõ–J¥d2 …{æÌ'''Ûív.—«×ëd”Z­† w­VCYz#ã<"8›“ÙE“Ëåâñ8ä-ÖÜHBAœˆòˆ…�«¡0?99Á¸Bqvpp…ÞN —’\ޤ°.—ëðð0 2Ѐ4kvvæä‡ß‚Õ�}"(g³Y¬–`Œrfu�Ê"€…x<ÜD`ª!úÜU«ÕêØØs‚ÜH�_Ð}—ËÅ.9¿ßO¼.•J\êB¡ðÎ;ïHšé‡[­V±X”Ÿc«Õ’+™qHÊ&3Œˆ<H&“?þñ×××µžÄ¢ÔíD[£$q¥ªê°®AF¾jr<ë ~8gÙÞj<Kþüý}¦ûÛÍ]Y:w5ñvuÛÐgVì-æœË‰œWn‰ë:9a"ºÅ^J$kôAÃèn†é‡+E ÷7=———WVV<x@(D“$⟕P ™k@Ì;m`)§IîopžB¡0;;KV0'<Õ¢.,,�U)@ó+7oÞ ƒÏž=«ÕjðkøhHNS©ÔÈÈÑ8ÏÔZ­ÆJä?üR1‘H˜k|xG®O&ÓÔ$NléþÀL˜`âRë•ËËËFƒ ÉÉIFsGGGÁ¾¨çôP¡Gòz½ãããì©gtÝãñ€®à$Âá0ÿÄt8!†쪤„‡Î ƒ¥Réòò²\.ƒœ‰˜� FS¶£ÚÛÛ;::bpáèèˆ d y´@ù|¾\.sVN‡ƒ·Z­x<‹Åð8""k¤€uÍLV“è�ðÌ`à‹ÃõÄøÞÅãñ`z•Í/â«”$T?;$èfÀþþ~¡P€‡/‘¥Ùýää„|ÉYXØâÇ$”Q|³$$>Ø_1 eÑŽSŽÌÍÍ öaÀ}{tt„]üÇø-ƉÐ/˜†H– Q/64u]g¤4ðl.í*Ùt5½4ô–¨R“R½‚˜÷wæ++8QzS¥Òüwu[‘ye¬î%Y£äßmYÄõñ"3õ9ÃköÎ{Åòæ5Á%­ Î5Íåñþ4AÊüGÉ[=¯9#m-iX\\„$¤ Æa‚…3´Øæ¯h¨ØZ¶|2˜'¹ˆYePâÙêƒRªõýý} 'f€±É|÷Ýws¹Dk,ã<Ìæ Ç“q³áâpJšÆù�@©\.ã½LÅíõz£Ñh£Ñà°ã±X ›‹IJ`µ@0¤(¦'h6›Øäá766–L& ßpÝŒ #¶áñ¡P¦žŸŸ :k4èm¢Ñ(ù|~dd†V£dŒ[¿~ýY ª™ñ.Ò–G|F|èòù¼Çã‰F£¸P@ðâ>¯§ÖÖ€ TvÉá¥s€3¶|>Hä'¢3È­ Dд¦GÃÌZ:99I迸¸À œ†x&t ÷Ž@ �QbF_Åü6³ë\4V9y½Þßüæ7æƒ`:²ˆdå^B%AnÇ» \e¬gY®h}"€Â—Âô‚}œ>];‰®á¥WïÜÑ?ˆõê'ºâHß°¹rúzuuõßþí߮躺÷õI½¦$ºšÙöó¾VgÐKãÔk¸Ã91'¦TkñàC¨#gyÊç`0¨ z~~> r›"¿Ñe‘ Ó�Ü÷Ò!‘‰F£øOlnnʉ”äÅ�3¼®'N› ¥?€ H®ÏçK$³³³étš÷M&“ÃÃÃè>%� ‡Ãï½÷ƒ GGG¼,—ËX™•[ZZ…§åÃV*ˆ@³³³Ð0 È™ôÜò‘Ÿ>}ÊD.GÀéo{{A'«ä‰D:âç³ÐC  bò  0¾wvvöúõkBg©TB. @Ç€b'D£Q¨ˆh4*îË—/Ãáp8Æ8–e*ì10J|ts +LSã½øÃ„3L®Ñá÷‡ ‰È[=!zÒ3³ÍÐ-®7Øp'ÌôÑ=0áQ­VkµÚùùùöö6w)™u,o ½qyyY(`Ô7@*<˜ß¦˜ÀL°Õj}õÕW, ª×ëñxÒE*,x—|>ÝÖÔÔT6›=::Z\\ÜØØPÃMÀe€&˜Û›N¬àóùž={ƈÕ,4‘X @{Pºrª¢sõKHê4«Ð?X�‰"˜9ÑfÊ~¬¿4ã›sÜÚ©_’û^sét¯rY[å{)BM—óο¼î€Û•νþÕL]%§ÎcÍvõW;§ ¥.0¥–¶—Ñ ˆa üãÿ8 ÍÎÎò¤ñ¾Âõõu~‹ ½³w~Ff'© Šrs~gccƒ¢Iò¢$R(éšHQ< ÍÍÍU*ˆ>q˱Xlvv6‹MNNF£Qª`|=Iãããgaa!•J•ËåL&“Éd&‰Ï>û Öš7›Í†B!š2 åv¡PÈçó@Éz9l{½^¡L.—ë½÷Þ£º¿sçN<‚#=Èúä„%'á`pp"·Óé€ÔÓF€A™‹Å“““\.wxxˆÙÕôË—/Á‰× $3XžÚ–ÙØX_mÊD¶ïv»ñDæâ ^D¾R©`ÖM&�¼Â¹2�ÃŒH$299I­Í8ærÖ㜡+&''‘Ò!ø CCC‡‡‡ [ð œ?xFˆÇ¦¦¦"‘ˆö’rãÑîà÷744„c¼ÈdƼ]ovMÓL�" v;99y‰¦åBœ ’Ùl6oݺE!ßxÙ XÐ4 S¾$h—FgbbBR fB™…¶¦k»šîÚ5'œ­©.çD±é•í ¯ZR}%# Ù”Q9ÕA:>™Ãìu¢X½vt³ÒUŸÉs(ïºn},5Ìl‚}}‚>–‰%Þrâb½öQXž?,$0ý¹ÔR5èÒ÷™L&›Íb¼±±A˜y7ÝèL šò9NÏÍÍMLL,,, ©›¢Ñ(GÞØØ0ñ¨ƒƒIÃg$‰•••h4 ‘§vgiss³ÕjaÑp¥–|ÓãñÔëõ££#ðöúò¯333?øÁîܹÃãǃߨ3}>_&“aÖ Ý‹¦Ã�ŽðÑd4 Šxhhè½÷Þ›šš"^óG"v< ßGÊIú …B‘H$ß¼ySÌ4ùCÕ‡±#… (•J¹\íQ‰M8h@Âõ€–w¢+ ‡ÃŒ°]\\ÐC ¿„FªDóÄ|{8ŽÇãÁ`yvv666&Ýj£Ñ`a M½^ßÛÛcï&vÃá5B“>' T§4ÈØ—"{m·ÛÀ;Û${ÑHŒ˜ˆ†YÉårCCC¹\nllŒ‰bö¾1“E¥ÄϨ¤äÆ* B¦Æ›ËHÂ.(+µ¼¹\®V«íïïKwÄ…Êd2 šˆlSí "jø8™fyšãŦߥSç£d î>»Vù¬q6'ca:ñXD©ÓÎG]ŽŽÌ²Õ2è~-Ud¯É‰®8ŠSXåÌ.¦ªW¾üó¿]ªÖÏZgÍI_ã¿þë¿\.×oßü±^úþûïë/¿øâ‹Gñ²/¾øâ·¿ým/V€â¿wïÞ½{÷®Ž÷î]^Àwcßj5ô÷üúêêj£ÑøùÏ^(îÞ½Ûh4tÀO?ýô·¿ýí;w¢Ñh4ýÑ~”ÍfWWWù­{÷î­¬¬ðâ{÷îq#ò¿÷ïßÿý÷Áµwvv©`M333TŽŸ~ú)¿EQ fB"Éår,Ñ­T*©Tꫯ¾òx<PˆÔ˜N§X,¦ÓièÐV«õ‹_üâÿñÃáðÈÈaˆ÷§ú§n·ûððp @S©TâÑšššB᳿¿S‡Tßclyxüd΃f‘•ÔË…BE+tÓÓÓØ8ƒÉ0ÛEøX^^þÙÏ~F‡à3<<<99IiüúõëwÞy‡Ì¯ˆæ "A=ÆmøR‰£«0ÅbX\pª~ø†V«õÿðÿ÷ϡϠ`'|+Y9� ‚×¹ÀÊçóä(a(a&È%Ú‘Ùh4èoÐ>É ¶™‰†ø/sÅ\7>r>ŸgS´A¹\&ïb³ÁIºÞ,qâº]^^2äŒ9À ¯—÷3€$'¯×»··I044T­V‰­ ,·ÛíVk¢ß­×ëz¿ß_*•FFFÜn7é„;&m¸Svôù|‡‡‡ÔGGG˜ñ‘ùH0¡Pèðð¹m*•â+X^^¾sçN:æ1‘YÈØØ½ öS>Ÿÿoþæo|>ßâââ½{÷Òét"‘@ªàñx …ÂÏþs2aáþýûŠæD˜J¥¢€À£Mñª°¦ÿò—_|ñ…,A?ÿüs"ãý÷ß畟þ9ÙK3É¿*Fñáˆ?ü¢u:ˆ~¾ÿþ'Ÿ|b†;§"êêê*çlý“yLýáÏ¿ÿû¿ÿŸÿûå×Z-Ur¯úõb`ºÚnôG~LŸ"gÞ³@®µµ5i¿œ:\2b8go¡#ïîîbŸ'ßm§áÕE².ŠzÇGLUÑqÒ$Ræãƒ¤ D òìkãw!Öùðb‘ÛL!<xð�‘ÏÒÒR&“YZZR=;;K!Ï/ʈ“´455°Ni ò^*•0ÿa$5Z£Ñ‡Ã@‘H$™L20%É,v@óµZ­wß}7•JMMMa¸I�²Œujj* MOOÿÑýûÚfgg¡øÃ|,±†¶Z­2´<22Ç©…qIj·ÛP à–J%âl áqh…•m9˜§F"rDE§Ó‰D"''',ªDlC¶CÞC^gõî=Ì!“Kðì“çÝ£  xöq…©è···)¨²aejµH- O+Ãr&I´Ûí¯¾úÊdã97D¢…BXŸÏG²I$ÐÈ*¯_¿Á·ÂœŽ Aêññ±¹Îa1‚šŽÅb>Ÿ&‰lwvvF#K£öìÙ3†K²Ù,~±$T¤Ø'•JÉ?êW¿ú•¼UVküSî[Ì<BþI˜„aŸtÒ23– š��gg`úÍX® €ÃÖ0³$ˆÎý<]?ÉŽdÂÝ– †“uà#ôYsiÅL“YéO|¾Úî”<ͦÁùƒ²bס+}çÎ3}Ñ.˜9Íìx±ËåúüóÏÍZ€ü†ÂºÊþ—þþûï“·õvÿú¯ÿº¶¶öË_þòþýûô:_|ñůýkª^Æ1‘úqó÷£££l$øýï???ÿêÕ+ Šëááá•••>úhgggeeåÃ?ÜÙÙá± ëŽ?þ¸Óé,..F"‘ù—i·Û~ø!Q€ê =9®*�� �IDAT}|&¢‘ÓÓSÖ@V°ògŽj !f¬7°…([ð’ÂÒ'™Lb §ÉÞN§ƒ’'³‹·D"ÿÇã‰ÇãÃÃÃÄ bG8ŽD"@C˜ Ôª| ˆÖP(´¹¹Ç}>¹““Ø@åÎTå/"»Z®F£ÁŽšP(Ä^ØiªcZì¬îåQŠR H} 'O™L{§:Hª ä'îk'Ïçáo)®C¡Ðññ1û…Ø;óŒ#ûà@öé„°èÀ¬b|||pppllŒéeødúª{:L‡8+¦Ï˜•C¡€£*“†Ì‡ó‰ÄNCž_^^"Ù‚Ã`«Ç9sÍùt¤Øl6;11p äq¸yóæéé)ö\CCCÄ}teÐ3´Úõzý£>âñåïÁ¯*• ³@ @gÖjµvvvÐ<xð‹_üâÞ½{÷îÝ£QæáE¬à_]]¥�'Pyî߿ϣ­¢Þ kÄ»wïå 8`ö¼Xp!EqÏlJ@DLàÄŒ¢&ô¢¿w–ÿo88üÆ<ZW¸E)JAþ-:†þà—sÌØÉ.ô_e׈ÏüÁ2,´Hs¹‡º‡¹¹9“ØÑ+MäQ2�(e1Nü—“ÿ9Îòò²„&í 5=33#$~`¹‚©O€Œbˆ£ ØZ­¶¹¹©MŸ–Ì?Q†]`�D>›Í²Ù†±ÕJ¥â÷û à ”(ÏÃ/×hL4]oÖ¤`ê9>>ÎÀýùùùÄÄ[eèE�Í'&&ÆÇÇÉ„!Ù”{ % šÂ(„´P³çr9v�$“É‘‘ šq¶„¤œ|S¸¶á±qzzÊ?ù|>Œ]QjŽ‘Xô–L&ý~?XŠz<žd2 tލ†ž Óé¢à±üĉTÁÜÀÞÞMF,ÃÂ!aÙÀ©2M·¡Mƒƒƒñxœöˆfdd$Nû|>ö𨨠ã LNN*qr1;(%Æõz^½Óé„Ãa²ÚÅÅœD§Ói6›ÒŒU*’ ÓàPAããã”áVõ S"m�ÓI8K'“1”>::ú'ò'|ãÐÑPÄqÖè¦R)VzP˜›{siÁ嘤I#åòÕ`3(”nðšZX[[3ljyŠªSÉ@L÷¡^[ô‹Öx3p9¥GNVÙéPäü•+måºv�]·awU©^9�Ñ“|îcÎçŒÝÎËd9Z+º:‡X9ÀÔ#õZp*‡BS›¬ NÛ¨D¢ñ…~Eÿ`0|¤ûÉTø²®€ È1,‰fgg!Ó&&&ä Á íêê*Ð'2†™™æœåÞEDƒÜÖŸ~ú©DŸ`M°Ðš€­•_:>==Å]¼Ùl26ÌËŠÅ".o±XŒâ”G}`` ‰€œ€¼ãçz³>Œg2ŸÏsìœ8µVTR#4qÜdu%¹Ô…}5ÌL¾‰J7nܘšš'UPoÒüAp€�ßÿòË/÷÷÷‰ø‘Hã‡ÝÝ]‚šú3èb»°mp½Ù7€‘–‘‹E¹a3–Ŷ>/gB‡áv»q€?88`H˜ú—'„(Èårår9uN‡h{ttD3‡eÀ½:B2¨ìN¹1ªÕ*3Ò8[äóyõŽ8» ¤Ñâg¸ì’�>Q‡øÈ\MYDf!ü€.™R@g¥Õ¡ @[\ ® …G€H‡%Âu#ŸÏ‡B!”Ö˜²€£¦Óéùùy=×ÚS+ÿy™¤"P¦““˜Ü‹Yj¢ nµš±OŸ9«kƦ {¹ YvL]1"áWfDrÖÍ]…š½LzÅ=aìÎî•ZÌP¬kbÆë&3ÓvBvê^͘ný¢e8¥\b¦M¾ëé•ΕÜ]¯µ0Dn,Ê Lq±™xL'w>µµ>‰Í!˜uk�XRýl6kªcUæ˜n±µ 1N>²ŽY]]¥¡&ô/,,h2“æ#<­Käù„“„a)”ˆÅbTp8²Ñ•c¹ Aøýððìˆ%ò2S“xœ˜ƒ†ª€ÙWâÅééi©T¢L&U0±Eâ{¦F”Éà58î—�TÓ€üœC¡8â™f³‰Õ3'²ü»ºR©?îDr‚‚¦¾ft×U„^é$ô©²™‚7báêI‚;È!¯×ëe›LŒ/)ï•Ëåà~ÐæàÀ»5�…ËÃ(|Avww«Õ*–ÝúuH ¿ßOtƯÚ�àŽÑ¶b±¸··‡Ã †|(,¡Xf—L&i’8m¾ ´H¤PI÷QRÑ@€5©á@Ô‹g #/Ùl6‹ñ¡jµÚ­[·¦§§¹’øþæóyuØBöYD?Á(#Øgγ|7bôèÊ(õz:O)ÄŒ¿Îý’ÌFôâÍhÖu(Ì´\uNYwíœZÛþsÁÊ~gôwÎuY©BÅ´Rc¯ ßc.¸Í„¨,Õ {)IÞ½{wffF �8;S D € ó¡2Bû¤¿£�¢Ç?ÁC<zôèþýû…Bá—¿ü% b¤/¾ød_Ñ{I¥ 8ºeeåý÷ß¿ÿ>{"÷÷÷ïß¿.óË/¿ ‡ÃÓÓÓ———ccc?üáwvv …ïËi}~òÉ'_|ñÅýû÷~ô£íîîF£Ño¾ùæðð(£ñfˆê>ÊgQ÷ïßÇY¡":t˜\ªVE† ‰Y<í‘HDÑ„çÈFf‚¥`Õj�¦ü‡bÃRéÐðÌ…ÉèÂ-V5LNNÒFP΋E½Pþééi¹\ÞÛÛ­Â&ˆ¶fhhèøø ‹vƒc‹Ùu<‡aÖ°#.]©TX C€mÆ&(ŸÏóë\Cˆ탃t¡WÊãòÊÍ»Ýnýóä¶@G棾½AÞÆ¶5Þb†~Iz3hv½1+Ç0&0Í ¸Öù›?tŸ@—ÃÃÃ$!ΟÄLk%ãñr¹¬aˆR©ÄŽ#ºpéÜ~ÐòÅb‘Š¡ÙlîííÍÌÌܱX\Q,‘ÕÑÑÐÌÍÍ¡Fõ×jµVVVþâ/þ‚¡†ÝŠÅb ã!cjÂÃÂÓÊC' !ÏøÆÆÆøÃl6˃g@d@dhº®ª‰0Môß<$‡"Á¤+ kqæÍsprf8íJ(f*¯˜/µ`2&qÇpÍASØk97©·véY©Òäè¾ÜN8K6×}ô¼½<•‚uP:¾<‘¨Aˆæsss^¯p_…¿¬`XR¨TlJæçç}>Ý«4Á�ܤ™8z”ùùy•`Gô™LFl0üži˜L ”£À’2ô¬@,üBáC™OÐDï444Ä�3œ-a|D‚å9ðÉÀ&¤~‹BU«‰iF(ŠÇãD“J¥R,Ïçó§§§•Je{{ûåË—GGG´$•‘‘æ“‘®NMMŽŽ2£Ž©' D,ãQÎ_^^âÅÄÆ:(Ùr¹|||üòåKD 3Ä—R©Äð0’Xtú3°I{{{Ü$ÃÃÃÅbñèèH®ÝŒM\±£�™a ­ÔØØÈGære³ÙÁÁA&< X°`òz½§§§…BA2PÔV4š''˜²ÒsR&É5“Š(PÁl6[«ÕNOOÙWáv»1MB_ i(ÇÇÇI®Á`gÙd2I“ÇúO¾šX,Æäf»ÝÞßßgK¹_]8J$ÜMsö¥Ó3^Já/ãKø´ÑæL2›y8Ži‰$KKKjúÙFlî¦Û¿ά­­‰6Wíš‘‡•*æSßUØÙ‹ÆèeÁd5:] º²ÎÐ§ØØËT£«f©§íöÿÕ®¦]‡¿-ã‘ëØ:-¸Å,ÉÚÈ2GâMìÈL?ÄbÙ©2`"£lŽ€rŽ ûñdzæL&Øæø›|³WVV8ÁÈtÖgœeXÌ—3i4À(¯×{pppçÎ £ÒC`ãAYª&Îf³ Wóô¹à®Ca866†ÑÛW_}…ŸódM©TŠÅb'''°Ä$B©6É4 W²lÔ æß7“J¥ÂZQš�ÄɵZÊ'%­T;==F£“““ûûûñxÏmõhl�©jµ# ###ÇÇÇïRéÆà`«Õªv‘7HwÈgJNÔ¶ûûû~¿?•JA&§R)V �fTV@d»ÖÝ d"¡NMMÉCX¯Z­6 ¬±n¥•Ä*ujjŠìÉI‚˜MOO³å ¡¶ *J†‡ŽN‡ñ7(zÁÃÃCZR’ 欜6׋À„J=¤qìÀà³g2ž ÇC‡eq;ÇÃC– "eÙ+z™¶be&¿áåååµµ5h9•€2P²Ø]ý/ĵ }Ë I?›Ë¢{ÑÑÖ/öb‰{ù˜ö2ôîê&w¥“k;;+¢*ôõÙ†ðèÑ£ÿøÿèç•ôV.I}dKÎtSðk¾…Å’ ,êš÷LÂ"(4¬/U^uÚÅ&NIn‹¦ô/ÆA…%€§GGGív{}}‚š„÷÷. ïKù£=  I333Z ³Ù,¼m5)CÚ©TªÙlbZç÷ûggg(0«ÕêÍ›7éß5* Ö¯QUÂ7È&B˜GGG .x_¿óÎ;à$ÚŸŸŸãD„ò’SÝ:´6·P,€{àx& ñ!¨Á…/..q’=C±X,•J/^¼¨T*ÏŸ?' …íímò~¿¿X,¾xñbww7‹¡eDÆJOÀ'}þü9l¡P rˆ³%MÛ¶‘Wz<¥j\Êá<ŽaÚJNE— Ô#×&rÀÄÄ0í´6A9 ±·'Nñ|…¼%ÏÃë0t†z5‘H`£Ì…­,Ã}Ñh”õvø$b•‚Äo¡î%+ÐJ¢øDÃ:00°··‡æXCÎÍf ?¼ö†‡‡A/«Õ*[E‘0nr¹\ûûûÐÔÜôµ?®Õj±X,“ÉÐWñ¤àÿJAϤí2þÄ|M4lû1ã€ßï¿sçŽYþ›£†¥ô˜s(Å 5¦<ÉÚøâúÃõb*Ûusm§I&;1§j¦i,=Ž¥åqzl(Ðu%º-XEYÁ„d®´ÊècXt}Aªé0ѵK2§Ï­ÖA¢1Ž N°ë롵Z ÉCMM*Œ´fßuùDDKÁ&luu•¯Öãñd2èÊL&Ãà±®¾nMþ08à JPÄßÜܔ/è�D²­­­---!n‰F£åry{{¢NS æåró"@BÌÒ¿km�…9µ¹”$ããã”êïÚ_¦¡úÂMp9+0ñf`>�UÉdNãûßÿ>˜ßH(ªV«§§§OŸ> ƒ(YŸ<y‚ÏöìììÒÒÎH¹\îÖ­[ì7FkË1%é 8tjßY.—“Òæââ.Á"›Íb©N§kµçÀ<£!ĆB!R©Tp?eÃ% ‘®…` qÂÌóûäèeÈdÞ‚#H»… 9˜Þ—IæõøhhR÷÷÷eö‡Ëߊ&:9Ø&ö¾œœÈ�poo¯R©Äb±ƒƒH ÝÝ]`CN’T\ÅÒ7¦ðh7].×ä䤆lÌõPÂf)n :&''É7$K×›e@=ðÌŠš}Ó>2Ún,˜|Â|øY®Ã¦N]+?-|¦—åœ%«±ôºÚTX¡ÒªÓ-5eSayf˜ä¼~°~Ý© 5ýÓÖȉDue¹¿ ”Ô•Tèß¡ôÙháüÝ>è“õÖNU-èp½Y⦅kNgó]ä¹HÏeb\l¡äa +*)&&&�%ÉIØõfÁ'­½i²„²VÛ{¶Êy[o-@Ée,Ï‘>  Gë)âª�" —`ô‡Ñ5ñJü (% ü©T*££U‚Hf‚è…°‚-‹-Ûív<?<<¤æ|àŠq¡8::b)4ïŵb{öüü<ZÕjµŠl†ÑÔì¨EAÃAQ(‡/..Ø$ƒ�)™L2­ÆÞ´|>ÿî»ïþÏÿü²"øüùsYŽã.º®{ÿÝwß=99º€ËEÃÙ*\403z¸}¤ Ü|#Áƒ’ÅH Y*×+,ýÕ«WŒ7³5‹>@(Ùøø8ù‰|C,FcÆôñ‘eÊ9\³ÙÌd2 °/ô1ÌaÐJ*ýÐ’B˜S7([0‡Š $½3öÜ®àŸšÚI¥R¨�¬h@¯"óÅìl±�¥Wš¦Ü¦gµ,[ÎØý‘™>†ÛNÀÇzvÉYȹsÍŽ«ï&g'Öd~–þ!·¿·hAIÝ7¸õڵЙšSrkv1æë-ësëM {ɹô2¾lì4àSæ²L¡–æ"Å4ð¥eænb”DüP(„2/NçóyàÝv»Í ?U(~Ë2ð2±,×îø$‚S= Ze—' ‡>)ŸÅõfg82DvÔD"ÌÔ«²¿~ý"%6LB@0Dq?úWÜ:ùE4£X&\\\Pî‰dF|IEIÈ£ñz½ŒÈ±u™”N–õ]­V÷»ß •–––Ö×ת‚�G€Úggg ^Á‘¤5Ø5w:ƒƒƒh4zxxLŸËå*• …€¹‰K^ O·o߯“ O=p'K@n“t¡gÐþCÝC˲Ț^Š\Ë™ðI¹V$f8�åªÕ*}Ìàà †²èÊ\.×ÞÞÞää$ pW˜w„?à›ªÕjXìÑU0ÖÎBShd†ºÈÒv ÷MBàË& =RVü%‰„΃_¤NâZ±Ž”޹#™¤aÕLlk é¤–b!(»¹÷¢ú\Ž-F<#æ²E=éúu“®Óò]sˆA³¨7ÉH'&Ñk³‚Y«õYŸy%uzåã+ÛôO�}ÎÁÚàf[bXZ(s \妳…ÉÂk8Ûr³°ŒŸð¥b|œ£Õû"`•&ìîÝ»?ýéOMU+g%ÍÙ;wpÎår333 ËËË È:¿P(üô§?eºýÃ?Ô9ß½{÷ïþîï¸ÕÆ?ýÓ?ýð‡?L&“wïÞžžf€ÛˆçöüüüÆ<cHõ+•Ê­[·ŽS©Ô_ÿõ_cz‘N§ÿöoÿvhhû Fö™ÔE™wçΙ™¦·¾ùæ›d2ùõ×_ߺukssó§?ýéììl&“‰D"[[[Ñh4™L6V«•J¥¾ùæZ­Ê¡¦+•JÄ P~úg ^ܦ‘P ø‰DpR"ˆ‹…†%FzO>Àßø,‚‹I@ÁËszzÚívg³Yü- %Uð.XØ’k80Øùó?ÿs´=Åb1#Xt»ÝÕjµ^¯ONNj›&§"/§#·Û].—©ë±w ƒ_~ù¥Çã^—:s?�…ÃaN/g³Y·Û D>==Ë7Å/–HƒèNäT…9;ŸÏƒ™0='ô‰s†~×%eàCµK½^Góà Äív³fùââ"“É@ÚÖ“x;â8 ÷?ÿ$;nÆ, …Ý¡¶Â‘ÝÁßÐp}� ÁÊä, ‘ŽÔ æ)‹Áî°¨R©Ð¯`g‰îëìììøøxzz𠉝¾ú öë믿Ö@O£Ñ@AŽørmmM’ÖN§³³³366KL\ÊË{÷îa”‚ýÌ_|eÙûï¿OŒR<A]*™©)•ö�Õ5²¯LU¨å‡¡€fÅRKÃêüÙ)cuú/õrÁ3ÏÖ©¾u¾—%±½–\Õøî Z9Á©>˦9”µ¾Î„í¬÷Õ¯“ÃÅ8™G ±ÃbñÄ2� &ê ”Pµ€9Îfâ<0’ 1°«LFl](ž>}ªÝ £££›››,´€€UãbŽUk i(:88˜››;;;›››c+C4Íçóœ$&}<½ØÓúé§d;Ž‰Žˆ`MJf ¶V«e2äöN‡‘XDܘ‘ËÊÁÉ|㇇‡Ùl–b ŸW¤ä†F£±¿¿ŸËå|>ßôô4J°]hW`AÁjŽÐ1øZ(p°¡ÈÅîöíÛ%C¡.1©•¢FæÐײ?™ÏE0B… _ãÊà~µZ¯½ÓÁÁA"‘zþü9—=‹Á=�Î0:ÀD±9ý÷úõk4Äšd8Žq0äX¨”#`j:l,àƒ�W pÚßß???O§Ó7nÜ`èýk䜓€HÔnb[*ÙΨ“‘?hš+•ŠüYñ¬…¾b’Ú÷ŽËËË[·nú|>rÃ4 ¬XØÙÙ-sýáÞCí2Qô0%*PqrC�îj6ßjÁE&£a1z¸aSNÓ~k9˜E²:‡m†Þb›ûï’±ô¬NÀ®“q½‹Ø°æø,¸ÿrž·æ,<çš­Mÿô‘d9ùçÉ8§ÕQRüñÇÿùŸÿÉÔëÍ.bîEs¡‚îKå�³ eý'±^+ï¡ PÖ2X\Ã?íîî...f³Y8C–F±Í� íúÖZP>??ÏÆž Zyh“­$°SSSæ&žÌJ¥Æ"I :hgî@1­VKD"C2™T@ãÏ,»!, Âj·Ûšžžž&“Éׯ_3_MXÇã Õ´,„Ì·1%…`àà\´J¥Bà¦è>::ÂzX ðçäädssó/ÿò/Ex2¨Å>ŸËËËÀ3Î'‹±¯”m¦p _¸€/MLL�³p4pP—/^ܼyX À‡+Æ Á·ß~Kä®ÓêS¦äTˆ‚@jQ™@ €L‹×£€u``‚”r¹àR8Fœzxxˆ½»çÂá0$Çåå%ß<ß´²1•ÇãAZ ˆ5:¤h€‡pti§§§ð‡‡‡ÔdÕjÆþþ>Œ› ¹ìì‘EÏ*èÕ’;ý…À{eSÊCÕ ‡G¬X__GÕʰ_ÔäNÙzŸ Ô'ÊõGŠºP&µÐ’êJXÜ>kûÃû}<—,(éê7ɳ‚¥/êê©gm˜SsªN»7pe­æÔ¹Z6 x>?}úô³Ï>£¦|£?%+8'×ÄN3DCé ý~?7S«Õbo3ºRT€LöâcA-óé§Ÿ²æpss3ŸÏÏÎÎjZ 5þHÜ4(‘‚Á .ÂÇ–––*•Êúú: 1hÒ{{–——9Ûv»ýí·ßÖj5–î‰×`¾ûûû8ö\\\$ æ¶0jæ#PÚÃpRÓ‘H"‘l äî˜(M¤�‰bë/¡™ |ttÄίíím´±ö‹>”‘CCCOŸ>…ØWë388È hG� Þ{ï= <¨X‘“Žáà £‹èžÑ9ÒÀÖÖ–×ë…·Ä"þƒ–Bú(ØÆÙFGGoݺ"Ôh4ŽŽŽ^¼xAVØÞÞ®×ë·o߆Íöx<±XL[Û˜RžœœDGK:©Õjß|ó Ú-ÍôÂ<ŸœœÜºu‹ã P¢<—¤õÅ‹àc$T¦CNOOYÑŒc]¹\><<ÄK‘&"(~ T´S(Ó Èß›˜P¡b¼üüüÜï÷cB&@ª�Ä/º\®Ÿüä'Ñh”ù›‰‰‰ùùyÈ š±±1ú¡Û·o#H]\\4Š „J I¬_^^æá•Ù%1wmmmkk m:vÜ’ù©"ÜÝÝU]ßuˆÌrçtâ(ΛÏ2ï³ÊsK™iÙ]8%°Vx¼r•›5*ðèÿXfýM™ºìc° #S,eUÜ]O×Ú0g]¦®ó#ˆ¦üo~ ÖÆ75n|ÂíííZ­öÁLLLܸq#‰4 ØEÌïDXÍÏÏcÙHé-5ÿŠy(1Ù(»Ë§¦¦€YqÐ|øð¡,æWWWÁsçççwww˜¸¡1ÈÓªÕÕÕ­­-,_Ðn£‘Íd2ëëëÚoEW¡®Y·õÆÆÆÂÂÂèè(Áâ믿& “šx[BÒš�Iƒ2i¥VTèµãñ81x1)dxx˜1JP46áp8’ ‰ÈÊ[ ÎÏÏ677ÆD"‘L&CMJ“4??Ï•'Ê‹®„2¥3cÈ !žC»‘A–Èâ0˜Ífgff2™ íˆlM± gÝ£!(†ÏÎÎØ'ãñx‰(ÂyŒQ!ááxÚív&“‘¹!^! I·Z­²$¼X,2€Íˆ‚ñl¹qš² =*Uh m¶¡;ʇUâ{9??Ç{‚î$ÇÔí}'=%é–9È™`¹´Æ3%VasËñF‰DâÑ£G 6ÎÎβ§„AôòåK¾Ù/^ðE}€9ˆðèÑ£ƒƒË“ËŠZlÒÕƒ¬}œ<ã<DÂo-M§…[ΔäLB†5&ÝËŠT>EÎÕúdNn›3Þ}ƺ XÒX‹0¿î7øùiXµ¿ÉÒ@°¬­­É©WwfñÕwßüÑßÜ»wO>H?£EEwïÞ¥“°L–ÄSíïï»ÝnºZ­¸³³£UkÁ`RÅãñ¼zõÊårMOOüñÇív;™L2nÆr›ééiÇs||üÑG%  \?§¦¦ÌÎÎâ¡D`­T*ét;œ¥yGb\0œ}öìÙêêêÏþsN,¤yɵ�� �IDAT«Ýnÿâ¿øÙÏ~&&œ$ŒŽŽ2…  Çøø8 ¯_¿&D²Ì !i´•¼^ϳ AÏÏÏÑÉ€íx<:�”ˆ###�xzc¢nNhF¹™Éa·¶¶nܸAƒryy™ËåÆÇÇ!?±y…B¯^½B…Þ‰¼ÂÖ°d2Étq<ÿýïEÏn"¶^—ËejçB¡@\c ZÒx|°¡¬³Ùìää$ÛÀúnܸ3àÆÃ#'‰h‡[ˆ³bl%›Í2BÈ#ý Kñ‚ÁàÞÞQ˜9DncDJ¥R vŠ%B7nÜ6f,À™˜˜À V†id9£‘‘Õø|(¨æP(„/^¹\Äo‘LÃ�#ƒx°2hjá'Å•Ëe„ Ä}>24šZ¾þ†Å«Õ*ß#9� q¶‘“‰ãñ8ÃÒÀb###ô..¬Ad‰´Ïçûõ¯ «ÌÃ>==½¿¿#½ººÊ&µ÷ߟ¶R©à®¦½)£££Ä =zô¡Š¢AƒãËÛU.pÈÎm1Zúb­p0÷²¬ ¯e gíW°<ŽL7ä9ÖZ7ó˜NYŠsK¦Éu;çð2'ƒm‘Ï]V{Z[zL2Ý„½HeŸþ¹NH©ëU3™wù7™½—Ý·i®g?éBu€œiqq‘.¢x||üòò’Q#êJ$: IáÊI k·Û8Ã� @bOòöö6ò¤………F£ñôéÓd2‰ÇµÇãÙÙÙ‰F£Ÿ|òÉ_ýÕ_mmmy<~ðùÐîî.éááÇüÇØçƒ¨ŸG÷“O>Y[[ûçþçÏ?ÿüÞ½{Ÿxn™³Åû•÷@ÕÀ`¯×K ôàÁ#BL2ƒØÀm-ÇÇÇ‘Häðð¦! ×Vœ‡Ùv0zXiÉñ_½zÅC.5ï²½½Mº"ÃÑÄPsqø»a^‹4¶DÐíÁÁÁ—/_ÆãñH$R.—±xÚÚÚ …BØE`[tvvöêÕ«±±1R8;ÔÆÇÇÑh2S# )‚‹7£ÈD^ŸÏ7>>NðûýˆDG1•FlÚÛÛ“¬+›ÍNOO3\O …B¡?3$ÁÁI38cã­ÄÄ8"Ý££#@ªR©„˜Š•ŸÚºÌmŒœôÛo¿&b`žè‰ñ"ÃÒ´ÅlÀ–×\® Ì“íJ¥R­Vc†œ­;¨ãhÈXÿmoÓVžßÿc0`l 6ØØ8ÆL°ÂˆN†Òe´´Ý&«‘¢(í¶I¤&Š2ÒDŒ4!ªF«r‘+.qÉ]næb.ªÝ›‘:ÕJÕVÓfF´Ë”%±lŒñóÌÃïâõÿ}ôÝs “ýs1Jˆ9>>>çóý|ߟ÷C.—ãù,psÙµ¯®®²ö°Xöôôp•‚ÁàÖÖ–Ïçc/ «°\.Çb1ƒ††¸‚´ü_ý5ÔD•ìN2(ÿ§8€ ˜ÍfbzoÞ¼ùå—_ ‰H­?N§srr’¥Åçó}ùå—¬êšÑð‡œêÿ5ý±ZÙ5õ]_²Ô:®ºÝihEueÒOsžn½š ¤_ŠÔ+ þ„þáA=uƒ,ä´„N ˆŸwUŸý½x_]PLöYê;ÎÎÎNMMAGA|KÓÏ.rii ìÛáp„ÃaI*G{)ñ;@F£1àpâÇÇÆÆ�Ugò‹ Jè $K^àðð°ÃáàœU5ÐVww÷gŸ}†m8ŸïU xѵA|Êf³÷îÝÃþZc†ããc†ºòØðø!–&´‡Áo.—càÌ2‡)5”$ü\.‡4PµÝnÇJayy¢Kssóòò2$±,M&“´ÌÔ¸B¡@0*eˆ�� ˆÂáðêê*LG›ÍV,WVV8&åŒPIù+J 4P‰.]º$si.)²´l¼†ÎTò 0J&“¬1è¢Á‹(|ûûû™L6ãV,êá¤ÓéB¡L&YÏ V«U»Ýîv»%D“/BL‡XÐâJ.¼O6^¨ù`¯²d³Ù¥¥¥`0¸±±ÑÞÞÞÓÓCcNÂjÊtŠ_DûS®««‹Fµ|‰Àg†,–à„'{°*Ð(0!g»ÀoaóŠ—Óé$±9 áÙ‡›ÈÐÐ7 Ó)²}ø1Q`´Æ“N�;è_â}0, ïê À× óL&“D¨h’Øùq|Ž,ÿ¤¾¹ÀO…€ÔA‚ªq;OS]×õG¯X>¯üªsû ¬ŒêÒ¨dÎQwšRgÆpÁq/^?ÔTµº$ wJ"4£¾Å‹?ê÷’ ¨¹…B!‰|õÕW<*^¯—vžb4½w§îc®ÂyeeeccCü%©Íb±D"üA‰aN ÕjuzzšRÎ’ þ˃-'ùìÙ3>E<GúÏŠÅB‚ªyaaAV‚p8Ì­l2™ÆÆÆfffµgÁG摞¢ CEœJ¥¢Ñ(ð:¢0Jÿo~ó0 ª õ±P(0=¦˜ròôÎ###|ÞZ­622W’Ãi‹G4Í8{ÀA¼umxxØb±ßÐÐ088ø7ó70d@®©°‘H„…¤P(lll ›" ˜ L¤\ÿ@ €#joo­«Í>³"ÒŽ777aÍÊ ©¿P(°Î±Dy<F‘H„¦›Ó°Ùl}}}|^ÜŠ@·ú§à‚§á¾EÈ(>†ärpÁ\‚;�C—[·³³sss1ü.Ên·ËøDIÙr±à‰ñ-›<è¶Prå?Îê*šmâi{zzøéý@=*—Ëì-x#ö¬@R~¿Ÿ¼h~Ž?1#(|±¨žOŸ>Çã¬RâE¾ªVjžY`¬O% EÍ¥AÝFÏ*£õÿbÀ£ij5%NOµ¯['ë†óÀÒ˜OÔ•§I×Þ”ûâT•¼«74Ò¯g|–:tÕ ÄxuÇå?Ø„õ Åú“Fì~1ŸUR9° …÷Š\wõ©È¤Ýn7´,!Iò¢BÆEAD@Kû¯»ó «)QªÎYü3Tc�áÕÉË๠ÇnnnÎï÷ß»woaa!±0•;ƒf>A-ðz½ÂeO§/Wàlê âX„MMM Íf39ò…BÊÎÉ 1´½½ãÒÒ®±ýýýA#ÕöòåËä±Ô>::ŠD"HÊUéåË— …Âææ¦ÇãÉf³N§s3ZÄ烃ƒ XôÝ 'ÍÍ͉Dº¤•)a`kh ÂJj{ X,Í&ㄱ··çñx@u3û­Õj±X .,¶K‡#“Éøý~ ïð.e¸f xHN„îèâñx±Xôz½²Ò§R©X,­–ïû9pB«Õ*´Ô'\4›Íöúõë`0£¬££ƒÙ» `I¤ïƒS‘FØíöÍÍÍîîn†UÜ<`PPcs¹ž¾"$;:ïíí1 Ëår¢×ã6ÆNß_aXÉC7::JËÅC¡k«ÔOŒááaa©†b^ —"«ž* V\sôÖ zr] ©Ô¢?¶èɇú^¾ìÅ«”àM¸¶ßCWÕ·êzª¨´p?ßź }ÒçyÖܪk ì¡ÄðNŸ'*’‹ÅÛââ"¶ŽlS¨kb½F÷^Æè¸½½½P(0Û„V„Ùívó^ªŸ"¼R1ÿÂ&Ìï÷³ù• жÀM¢ú“Ê&\=žöè<‰õˆ$E*kïÎ!¤EFŒ4ñ>Ã÷Íívc§_ÌÔ¨eTIaËÇH¨ayy9 ±*x½^qîDoØÞÞîp8<óy"玎ŽhÉ=˜]S&¾ýö[º¥R)"ÁéÕj:Nǃâ,™LÊ÷õ¯ÿú¯p9€ßïç X­VÊ(�=L*6+¼€ýP‚ež?.Ô/Œ²<¯­­555!Gâ¢ár¹#Pý[¸mwe³Y¸¼�ñ$ša% Ó‰ù ‡Å�!žÍfóz½�bŒÄpîjmm…aÁ@åwÞ¡"_¹r…Ægá»�ÁƒB s‰OÍ•G®AÒu&“)•JŒ dêÀÊ0(1«¸s#ù\[[¯+ ì¹U8%ÜàÁ]žœœ|øð¡p²Ál.ðPãJ)*Qú!©n’Î;33#© ì@¥(B W»~ŒüD¥ª\ëfpêÓ*ß0}@ƒ‡«$(½ï©Sy¯ë j¦ÞÐèMFu $ýAõ±6çY–ë±#õŠ¿É¢9¥_?ØàëT›5¾ƒüŒž]$Á”`Ê1UþÜØØŒÏýý}úVæZ­Æc¿¼¼Œµ*µÅb …Bccc@á´±P)åœ9¤Xù!ÔxFûÌùH¡ªe£S¥÷–ÑÝÝÝ7ÙjÀ£­Õjp 0Cç ïã óù<¾r8†¢nÞ!þÉ4Ñ  Ówuu±vBR‚«ƒÏ6ôJˆ¹…Bºƒ*‚€ý„(�H)Ùlö*²m ‹p¢Z°ÑuR1©n«««˜¤RëqðØ@|N­7ü *«ÕšN§Óé49Ë�:/‚q`ÄÒ‰ …ÑÑѶ¶6yœ<¸sù€¤!‘@£¼¾ cƒŽŽŽ·ÞzËëõÒ£ fØÚÚâ#†3mbMæ˜Ùz<Œ¦Q²›ã ¢~ DáªÄåíëëƒ_×ÓÓƒtNö ¸§0ê‡0k€yÜ`0ˆußÞ'µZl;vü.Ë»FFz^¯—Lº¶¶¶±±1¾–áÃÃC‡Ãqpp0<<ÌlŒÅxnn¬Ë�šªjµ*2|“ÉÄž^6Ǫ8 ˆUh£‹E²hÅôC5ÆXˆÿú ­ ¦šèé3¢ÇÒü¢ .i RÄ$=¬n}>#RwMÓ\W"wå§ŽŽA³R©øšþíÕ9†Þ7\· 1Wÿ¬™©›5uT";z(õ'M3ó ×¢4+¾¸¸ˆD³Z­z<”™<B’œ†‡‡„F£Q0<`Ï@Z5­G6›Åå‚ÊNÑ'eÜIbïØ;³Y枈Çã>ŸO’Fpê^\\ä•ëëën·; ’3¬:ýf2´E”3Ø“øaÐW²ÓÇ7 ÒcWW[B¡àr¹˜!¿ìííÑxbwÊ?"ªðáááøø8—…úNYg+L&{{{á)á"Ç4‚wÅbÀ}_}õShúDæ“̹ª~¿ŸÙïÞÞÞ¿ýÛ¿%“ÉX,†|$fÝv»5-*aN§³»»›ªI \ 2®HÜuŸU@2™$·ÝÙóçÏY±[T*•ÍÍM¦Ç`ôâaN_†K$t&>)Ë‘ÚìóHLkoo¿|ù2B ê/£rÔ0´)@[Œ1àŒ1O¦ûéèè [ :ô0ê;|> º~÷ìì -†²ÌÞ‰¤F&IàÒÙÙû? 3Ø‹Hþ„ðnùÔx[­¯¯³ÁbP‡¢3‰°B<{ö 0 ÈefffttTÔÎòsú-‘tñ\P‹M&—ÔÍæ@ChSQTè¢ àÝ5TË`]•g®‰ ×¯7ªPÝÒ_7äF-Ôuƒe˜qÞž«cÐ[GÕ "¦x’ê ùIÄ *QUÏ�S…½Ð­„ƒ,¹ÍüúÜÜ<-I.eð YxÁÂÜâ·:;;y&F£DÅÞ¹sçã?þúë¯Á=Ç/~ñ‹Û·oÛíö¯¾új``àèè(“É †$þpÞó|¾õÖ[¨I Ûv8sHFFFž<y½ z3†‰‰ ³Ù|ûömvÁF£±¯¯Þçøøxdd„ ]XÃÃÃN§sl£ÑèóùÈ7f¥1<¿víä?^@;rr‚¥]©T¢n’ìŽ$4|2 ñ\J&“—.]¢{mnnÞÚÚ²Z­D¤577¯¯¯‹c«ý z^ƒÁ000Àè•¥H¹qY ]Íår '»ºº '¿zõÊd2a"ât:ívûëׯñòDöñÇß»wS‡T*’jb·ÛÁ`XRPB°cèìì¼|ù2P[,ÃX ~”Á``¸]«Õ~ÿûß³šbŽT5=2d|г«W¯noo3Œ…ÈÏ@â)[Oèª{{{Ñh´¿¿Ÿ+ljۆ‘,!šHXPPCçE[ÀÒÜܼ»»Ë�GX¯„aˆÍ‘ä¼²ó�Må+ÕǤE`v-Ipø¹²vŠ‹"ùNH Ÿ2ÁFËÂÞ…­Uwww"‘`í§Ä777»Ýîp8L°9�f_p fffn߾ͤmtgg'ÒBäĹÏÍÍ% jÀzyÆ}>Œð‘‘@‰t^XXˆÅbÚ%S]eôK,¼¨ÄM c6›ùuÕ0”WR@È Qó.ªž@´\jg,ìUñõãçI­9‚*óÒ¨Î+Ôü™Wj|�gff~þóŸ«tÕ:^IêvC?!Ñ`ap–ô““gÏž'^<WÑX¦¨îIš|ýZÝg¨Þå²,3¶ÕD#±,3XfÈ@k d™Ì¨%Ÿv~~^\ÐESqªÕªßï_]]ŸÆeâtgI$8%±¾Ð ÃÕË"ƒq†œlYh¥i·<Áú „çðð0¿÷Þ{ôÚÁ`U C=Ùæ3ÄfÀˆÞ ÷¨œ0U˜!U'‰ÑÑQ|8"‘á£ì˜~3ौr€!åFB‰«ÕªËå‚ôÉ·€7àgñ/FÌ0ê;9:VÚÚU¶D,!ÐÕÕµ·· …âñøúúúØØX$q¹\,ù|´Ðd2áÎÄg‰ÅbCCCœ?“Xàu*/Ši­8Áó)‹ÔtzV”®®../g›H$0,éêê²Ûí¬¦0Y!øh´¹\ŽyC6› ƒ‚^ˆ15#16ü¢˜¨Ã^ègSD¾Vv“�‡Æ‚ÖAÝl8JÀ»M&“ŒÜØäƒAv–¬¬€`±Xlzzú׿þµxXPÆ@àÏ|wlTVˆ䉳™D2ˆÿ˜ä²H>ƲAc”-H”[Ä<Mï¿-¦ýª_wÝ"Yw^­¡·žW`/6ÊÖ3ƒ.ÈuÐE\ð[šáó¹&zß[îëžâŽËëÆï\|‰Ï{—77.W=4ߺl©Äó¢� ÜÜÜœÉd¸çÐͲ¨îlÂ\âö¢Ö‹‹¤&{G~¨–°í‹=5Þ‡ŸPY9Ÿ Ž£M#Jž…¡µµ•]9cF"ÆGõ<ÿ¨çÊñ<£émllă&5W˜ZÔ &œ!ï@­½½½ M%N«V2– Æ¥RiiiI Ø a`er)ÔË ©¹Bta¥dx€ŽÏf³]ºt‰y�ž™L:ïÆÆ˜8–ü·¸¸øÞ{ïÁ±—Y’p677¹ì�}@4ÂSX__‰D"ñ!©œåÞa��‹”Y4½Ì¨Ífsoo/*n˜¾09mÇðWBÙHî„qûüùs–R¾ŒI˜UФ3O†Ëtttd³Vî²?Yþ@¢e=`Ã5A-ˆÊ¯P(¤Ói–(YJé*øÞÙVÒ põ~üããyŋŢÑh|þü¹JÌ£“çHU‚ÐWVVXÚõñ>šöQõïÑÄ'èSaÔ,h=õHoî©™¾{¾¸H¾I!½  _Ïð&q@?ÄD¯.gVÔê*ÔT‚FÕ¬_ÍêzÌÖ5ÄM3ÏœQ£àГ‹ûUI èww÷ØØØìì,w*px÷TIÇ388H�=·T¡P “ ÔXàZät2åæ`ª÷73!DÅãq¿ß…¸ŠQ2íŒF£ñx½4¢F1+Eÿ,`…BÁívƒÉY)ƒ@gž¿ {¢úcºN§WWW‰ÜÁ'ƒ%Çf³áR±çàà€þ´¿¿ݸÉd"ͱ±±‘0Oïþþ~2™¤¨ñð1Pl£Ñ8>>ŽìÃd2Áãš››cÓ€TŸP€HÁÕJŒðÖ××%ª¬¥¥Åårµ¶¶nmmU*•õõõßÿþ÷Åb‘Õèàà€åHàøøøg?ûžØ¬‹&“ ;ÓÓÓ+W®€ò9è¹n·Ûn·W*ˆjCCCÔ>VGŒê q¦ÓiÀD-ˆ%ÙO°T*•b±©jðÀëŒÁ9Æ‹ÅU6FÃÃìµ}}}øJ <ˆ*„Çb±äóy"µ÷öö¶··Ñë¡Ò°ÛíZ€&­¬¬œžž²! 1B½qzzšJ¥NNNr¹®®°ãH¢æ6¼OÚVK./2u†s²ðŒ1À sâÏò쎎NMMñ+÷îÝ£ü=IY'õS vž)y²Trc]êÕ¯)5úÀÕûHÏeÒó…ÞPDÜP/Z/+®ËÔ×h/¤•r}ÁÀü{l·ÿ(!›¬rš×h4Íîì yPu­¹õ:}–žšî­jØ�&°U§‘ÇìWn¯éééÏ>ûŒšûüùsæÉÒž«[]ä÷îÝSY̲¯d°FÑ—L:ùj`ÈHw#]3uJ%½3@“`)·)®Ñ]]]¸ìa»D+qžÁ`à8Œ@ñIÎd2^¯ÓS@sæó UÅbñÊ•+äDÒr¹ÀŽÍ®®®ÒÚs&H‡û#‘ƒq1ý~?¶P(‰½ µ€ÿ h‘~*oP´%nÞ\¨Yì'˜ÇàAbµZ777QC¥ÇG&ÆvŠióáá!oÄ•ÓLzŒ"ÀÍ@ÕñÎK&“ä\r Ñn²#18 à>Šh|îà8aÁÍ·À”‚ÿ···#ªàÒ!J Åš‹ÖÑÑaµZ™! …ös2™ôûýñFFFœN'Y ÒÚÛÛá_@`Smq98aJ,ÕlÁYNOO™‘H”Kˆ×ë…% MC~—¬7±¯—‡H³¿” À¤ZSgγÅÖ˳4.Ÿ2.æ°ï Þ°÷ÿÞ,OMÕÒ”8Mºç¨Õj=ü§ú§‹ÜÎ;®ÆmC€¨§«qX:o¢šRiâÞT7(<RT+Ռً ^äçòßÂÂANÜ@ ÉÅt<3j ÍÜÜÜäää§Ÿ~ú£ý(›Í>~üøÖ­[ä²1U#—íààÀëõÞ¾}Ûl6G"¬ÖØ Uóx<äŽY,–O>ùäÖ­[GGGx= W*•k×®Y,–ŽŽæÏŒg¿üòË[·nI>ɵk×0SB+°±±Áœ‚899944Dªp©TbÏŽÉ%y“H^¼Á`àÁ¦Å‹H$Øg²u€-c±X^¾|¹··wvvFB¾@Ô#Àb¦Y©×H£Ù ¬x€°Á�Óñ§BÄ`·Û———€ÑhÌår/_¾Dj‰Db±˜Ïç³Z­<¸víCxúP&º á£Ñ(àŒÁ`à½I0K�+oooç³,†„Øn·—J%¡Ù°zaˆÑF¤üîw¿ÃŠ »´´ÔÕÕ•J¥ ×jµòïè²ñn¢Þ1dnnnN¥Ràu;;;äçà‡ÑÑÑÁÄ¢££ƒôD"!ù `ý,*f³1n½½½,ZHØššš ñ.hSx#Ü%@9%¼©#¶WDº’Á6ƒôR©äñxPÈ×j52ˆ3:<<äW8bì•s@7ÂÑq: |ŒUØôHìùƒËËË|4–‡ÃÑÓîî.÷�Vz˜ aˆ„É"ü‰‰‰ȼáÚµk2 ¦÷¯T*TÍÀV¦Á„-R¤€ ¿†àHÕnH8/˜ñéWÁ‘>IMóõçLžÕʦÐ %炪«4‰w“ÆøŽBúF&zúãÊ™É{K§],¨ÔÄ8õt!qùêÎëUÎ’úCùbô§Á9gIþinnŽÛ÷ÖÙÙY¼±¸ â»'-�G»zõê;w€ìoݺ555uûöí>úhrr’ü2�BáF#TZ<îÑÓÓÓW¯^ᇺ±±111ÁÖb …ÍÕ–™Ãá�ã"¶ðÑ£G{{{¸½" ÛÝÝ%%”9)‰bc¢�JÓÔÔ¾Œx„Ä^Š!N v»}{{›ŽŒÐŒá(jÐf3BÉïêêJ§Ó­­­ØÒ555y<¼ZZZzzzÐ:ñ¨ƒ‡°ð„Ãa"8r¹\fí4ÛÛÛ`>œg>Ÿ‚þøöÛoƒ}!×J§Ó\À–––ééé;wîÀѤI·Z­ûûûápxddDÄh¨M#ìv;´Îããc>>0=Õà„jµ*!ýýýÁÖYËå296årÙn·ã!Êj$#e´ÁŒúáÅRŽ=”câ} ‡ —C‹ÅÂâDß@À5d$cƬ¦ÜNøErwaE½njjÊçó{{{ˆZÎÎÎþë¿þ 7ÉJ¥’J¥˜Q'“IƒÁJ¥ ‰á0Å–±9Âǃ.«©TªµµuooŸL5NOOwwwÙI°¦r‘YŒÉžÛÝÝe#‹Ám>ŸÇó•›„™ ª Lˆ‰ê¼qãF±X¼zõ*m6*ÒàñÅwî܉F£Øùá—W,ïܹóøñc•ô¨7ö»Â±„@¨6ÁRÁTsh*ešsCS!8©†¡ªªº&©Ö¢ò’†ÃÉ^Aý¹ÞoUHMª;¬¾¡×Þ?naãªÕ_õTݳùO³*h>n¬²®KL³èI­Ënµ¡æ°rM…“LM¥Ö\/Þˆ{ˆÅŒ“aJFpôÄÄ\Rj´ÙlËå—/_bå†G…m/˜/Ì9ŸÏGË“Ífûú$LI�� �IDATú,K.—c$ *òäÉ“»wïnnnšÍæ¾¾¾O>ùdbb"•Ja½±±1::º³³óÿøwîÜ!ªzvvöƒ>€"B´=Eo¿ývµZ–)•J[[[ìú1ò°v: LÅb‘Æ™ÄÃi4_¿~Ç:˜”4éÔ¸I”0À"üy¸<ùx¥Õj5F©/_¾$;âÍ�üµµµ%—Ân·3ÆD5]«ÕûúúÊårKK ú–CÌ$ ß¼y“”Ëåt:ÍvðT*eµZ+• &ƒà*ìl°Æë ïšD9¬¥ÂâmG]­Viÿq˜ðz½¬mh_¿~íõzY$ ê'-<îCº {h¾|"Š8 p*ˆ¶ ¨YØpÞ D.—Ã×Î(ÕU™Á†X¥îìì°á@244´½½Ínxkk‹×àà`:d dÛ³,Èñ·‡‡Üÿ¬Ä 9�J,óø;Ùíö?üðÖ­[L°8&:8òšÍæ×¯_ÃXmiiAÁTŒ½ˆ¬Ð –Ôw»ÝžJ¥,Ë“'O®_¿ît:_½zQ•‚~íÚµD"Aï_©Tº»»?~LåÔNR�=¾´ÿBŽ G­HRåd'¡§{ª» Ž#ý¾ž½JUý§õ;ÞÌUL¬ÏÛ"ˆß¸R—ª¦—…D³0üðÃ[u¡½ì°ô&ö ü¼î¼A?œ�¼fÐÇ\AKðŽ&''“É$Ýà,­=äq y†Ì9´îçÏŸ‹¼YMEç5>>~÷îÝgÏž‰ªú¼ !°×××y2U«øp�m‘®s¦··÷ŸÏ‡Àª"¨þ¬LVéIyžÙ…q .,cmâ½(CŽ2f`Á@íA&Õj…Ååe�ÿK+Ž)ta`ÆL}dØÀf‹)ˆ\O®†pÄÇÇJGFîìØ¨tàþPŒ0ð°Ûí¡¡~ÒVò½@Õ…5@¸i2™DÁÀ‚B ѓנLÆØ ¿?Nv*»ÝžN§‰Æc{Z(0ëE%'K‚ÑhärLî1X¿”c>ÁQŸŽiÐúúº:n…hǘÊét²±3^__nÂŒ’¿ò3´ïzøcô+ œñØ´´´´¼zõŠö…î÷û{zzJ¥ÒÑÑÑææ&S ¸ªÜ 2p‚Ø „ãjFz*™U?¨K¤þäy…E`è›Rgô~MçMR/65¢‚©Lª7¬ç}"õ<߈•tq4BÝÔgk’Ý4BóóL8ôCsýo ÍTLª51ßuãÔ`8.ò܃,ñ¤á­466ÎCíVïH&u8Y2ʆºC{ŶšèDj“¬ lй§}>ßÇ¡Rܽ{w~~ÿJp)Ä u4],!Ëz½Þh4ʪ Nm&“‰‹Í%f``€(˜ÎÎÎt:½¾¾NÉ£ZI)Dð,³Sù|>@L«ÈdÁ-!ÿGÌ0 ¿ññq.)‰ ²zuvvʪ�ÕŠI)Ü0X°Ìðà‘ ÒÐp8‰D¸ž>ŸÉ+CK¯×ëv»6rD^|"yÖrØSL/z{{‰oËçóKKKMMM»»»;;;ˆ?˜Rð¡„k·ÛŽŽ¸ø€oTy2?Ø;rL¾Pæ±\s0È‹%N{½ÞÞÞ^‰Tr¹\`) |@7 ^˜&±ÞóŽ€™LD(܇X>¹c±˜Ýnïîî^\\¿w<áYí¸þ¹\ÄŒ‡×ëeYb~îõzYÈÅjooçœFY×Ëå2bhTLþÙra´ÎÚÀÛAá[[[Ha0xÇÒX£ìA-­ßï'–ò·èŠÅºU õÔ$²‰XS=å'u{Yëª&ÕXµï¦”_@Üù´jÍ­)†š:vž×œ¦TªÄQ}Ö²žU_ù¬ êÔY±˜L 3͈CI©šFõ§þ¢ŠÉÇPãdsÄv‰l¦ùùù'OžÈY‘é!˜ zcÆÀKò.Híèîî®ÕjW¯^%º’x¸0ót8Èy‚m ,Ës[(ÈÒâ_^^îïï?<<ìïï7ì–––D"}ûæÍ›t “““+¢Ëõù|©TjggÇçóår¹¡¡¡µµ5<¡!ïžœœà ¸ÁÉüÝßý=)óÀµµ5V¬öövôZ­Æ¦'‹1~  '�²¾¾~ùòe0_ì àò³A_ʨ–ÂW*•¨¿MMM¡PèÒ¥Kƒá?ÿó?Êé?EsyyYNìóù<Š_rh~_¼xA ’Ëåº~ý:ñ–ï¿ÿ~±X$Ôìúõë”3†C¹\În·¿zõŠÚ y $—Ë1‘&Úšîj¿ÕjÍd2ÌEÉtZ__g†d0X¡óù|{{{:+gVA’ä.wwwÔ÷†…>(P>âjXghØØÑæ³|ŠË)S6 |¡TI.,ãr¥påcãÅlŒ%Á9¾u333?ùÉOÜn·ÉdŠD"N§Sp3¾}œ¯` ±âÆGâ)ܸË`„544”J¥Ìf3‰FtN°!`Ä1[¦S999 ÛÛÛÐÃÊåòåË—¡É1ˆâ!…ÂxÙãñ€&=xð€~Ël6úé§ *BlYXXØØØRÀ‚W*ÌX`Þÿ}oÀ(}½’#kæÆ2–`"­/˜u'Þ‚ÀËdB‚,e$®z@èé<:©ã]h~Eþª™=|ÏŒA}©Š¬ib>Ur‘ú62r¹öQ§7ŒL½vê—¡a1i085^tbb‚À?®)€€$_ª —äJ]½z•Ö©±±‘û¯££cff”ù!›ÅbùøãGFFˆÿdf‘†mÀ=èBƒÁ`.—C&ÊT3—Ë!¨æM%åÍétÂjii ËËËܯˆ³Ð0ÎÌÌ\¿~9*¾ù{{{0 ÁpGÀhšhf­]]]årÚ8ÒSh�ßpWŽŽŽžžž²(öõõáŸÉs"‘p»ÝÐO;;;}>­1TNuæ«…B¦”¦©©‰¡Ëééi>Ÿ÷ù| E‡††>|ø'ò'±Xìèè(ŸÏ?~üøæÍ›/_¾Dýd6›©2¼E¾S}I" ‡Ã=:;;+•Jƒ£»Ýþí·ßâŠAkV¾½½‰DÇîîî7ß|ÊE ÞÛÛÃÍ”(Jqce<À÷KeÄÛŽ˜#¾f3D÷°3 B ÙÚLnè Ì"a7Æ"ít:™ɇ-.Še5ÈæCϘÏç™=0¥`DzMeGäÁ*.i9wïÞe&ÜÐÐpéÒ%ŒQá#°­T*ðߘ `ßÍ’CÛ!ù¬ÙŒj gÿJ5«X%c PÀˆÜn7ßÌ(ú3Ö¼ŽŽŽl6ˆ8^Ü2NNNH|£ÊOLLd³Y¡Ãࡲ™Ç° r:Ÿ|òÉ7"ú|¾Ÿþô§###hM[[,×ˤA÷¥Z J¡†%k,+¤¨ÊøS?W÷'5²T% i <êöëç Ÿÿ8ÛmÕ0U/¬¨«¾ÓìÝÄQ¶®™­*RÓ°‰UZÙß©¢bNý' ±®¿-aÊãц*–AÈ,²Ù,äh$WþÚÚÚpfe[«Õ°x½^«ÕJ½•,ëÁøø¸¸¶Q¬q÷CщD€°¿­¬¬ðtÑâÛŠ±Ìôôt[[›Ãᥠ¹‹E(á¸ÐÎË€âVé4ãñ8Þ>ø¤¶··'“I>åE ŸAb[ºººÀÊØý�ƒAžm&(œ6–s_ëa÷ògff‚Á ß`1 >W†#øýþh4êñxÀYv8|GÕj•‹�Ø"êªÅÅE„Á‘Hi1Û¾‹P(d³ÙXƒ …Âââ¢Õjů»µµ•ÑkKK žzøÙq‘Q¤ÓiÈ—XÃR(1æÃ¤=²W€®^Oâ,Jf8f`útÊøôqpög| :9·Ûõ¼,œÎÎζ··áàòYwÓÙˆÚ±Z­Æb1Dš‡ ! ì˜0Û œÏE¯ÙីÌTÑèè¨Ìü›ššðÆv‰£¡¦f^¤ßÏf³ìÑA®p¨ììì ‡ÃÀwX!ᙊÐÁçóáæ-&HV±æD%ª)SRJ’h‡x<n2™€žT@[=!Õó<¡Õyã}Áyæ©jœÜyyj=OR§wëFdêtu ¤ºNLê #º¹df³Y~¨.M*HEœT$J³ç@Úª_�"ÉÑ4û¡ÈJþ*)VõJ¥·‡¡«ñ7œN'!ã@º‰D¢¹¹™0úÆÆFXÒ<ÀÅš?ŒŽŽÚl¶¿ÿû¿'øÓl6£899ÁoR´¯}‘/IîcKKK>ŸýúµÑhœ™™¹yó&ÙÉÉIö¶@Ì 3ÌfsOOÏîî®Ëåšššºuëõï{¼Æp\ÀƒêêíÛ·‹ÅâÐÐP[[x.¼)X’4¤wÐZR¡]#Ûl6Ôhß0ë‚âÒÒÒBoŽÒÎxˆÑhÜÚÚjhhØÚÚòûýÍÍÍ.—‹õ€ŸqÈÇvà,ÔÒÒrëÖ-:>ü¢ùD˜¾|ùÒçóær¹ÆÆFv÷ïßêùó?ÿs(4©T õPLÜ�Žl6ј{{{«««###PH1#òù|8â@NL‚0G …'\�+¤¾¾¾ÎÎNˆÈxhŒº½½ =fލ%ãc¾“““h4ÚÔÔÄ—Âî-™L²üPm©ïØbrztÜ‘XB i:ˆdgggü+O èb?û¶Dñxœ\6P)@ÑD"a0zzzL&ÓÁÁÆP\tò¬mt<@…ü+[ŠX,†iŠØ2"ŸäaeËåØ�a ÜÛÛ˾ :l.—ëëë#ðÁÝ»wõ«_MLL ðþ裠/³Q¸qãF6›}ðàÁ'Ÿ|òàÁÌk¥8¨Žœȶñãž››ûâ‹/fffŒF£4õ•JåÉ“'–¤¶Ü¹s‡Ê1))šDeÊ£l/(h¼L¯ýªë1zªL=Ž^:¦ÁrdÛ¤±äÓ³’ê, uW…ó6#T|ýLBL Uú©¦ ««ˆ\\Y'ä Ð0Ž5§§¢Rnhf Bê·L¶¹²Ød6üßTzh£7oÞ¤þðÃa×ÀÅädR©T6›}ôè> ©T ;££#°l@صµµÃÃCÈÔ ¢è'&&?~<<<Ì Ê!qÒ|ñÅ¿úÕ¯nܸ°ŽŠ‚{¹\FåðâŠ΄ö¿§§ÇjµžžžÚív¦årykk sSIa4›ÍÐXñN ÞJŒW(ôsZNtRp¶··q™Å}§˜6§§§ÝÝÝ¥R©X,2éîîÞÝݵZ­+++}}}íííÐùÁ…®_¿Ž¡³³Óëõ2Ƨ}£@“i:::j0 è'ÌŽhåÅ‹ˆªÀ"èS©ÚÚsêš8Çáo "N>|}”{ª'»¥R d†Õúàà€OD›Ìèå0mmm Ùh AÊ”oîdÕ'''�P»»»ŒUÒé4k°Édâ4(‘ÇÇÇÛÛÛ8C�õõõU«U w8fa€’ËTBdlØÑ.444¼zõŠñkHN'ø rÑ'âêÑÚÚŠnœ‘JIîÌ”ÀQ“É$?a¶?#bØ\F£‘4lt‘ðܸ&l饘„óOƒ°R‡Ã5!–vŠ{ò§?ýiggçÖÖÖðððìììýû÷S©…øoâd\©T¤Id¯”Q†’³& QÕ©98Ȫ“�¬ÕºŒdJõ{–ú£)åš9®X´jð(ÍñõB‡ºn¬BÉå'zÀÿ{ ¤ó"~ÔxƒºyšL±Qßê:/§ÕV³&ÔÁºžt¤F§©ä° …TãhdOŸ>%nS¼Nggg±$B‰êäQ²½½=‹­¯¯ïïï“~žÉdØÂbì˜^/‘H`) IÌJþƒ§Ávx~~žåM6™L&Ca´X,£££µZmll ?%¾)ž¨p8¼··}Åf³aåM5S5š÷ŽŽ /Å`¢¥¥ p¥R¡œ566^¹r¥\.—J%�8ì¶¥¥SkÐ6®¦R¼#fSPSئ²ÒÙÙ …¦¦¦àb qyùhápvþ¼²½½H DÂ[Ô�g�wÊ÷W_}6r||Ì6bqq1 º\.Æ'§§§›››ß~û-çP«ÕÄ˨©©‰2€—ÍÍMö.ˆ$L&S0ä s?0ÍFúGìóav¨äØÏa¢§"³immÀq„yÕÎÎ&|­\tõ6›í7¿ùM©TÊf³ c@�ZâÞÞÔd¿ýýý¡¡!ÊwCCÛ $“ø‚`ó(Ó©jµJ\v,ûŸÿù>ãþþ>4n+|סÀ ?`2™”DnìÓ¹=Ø[\ºt ô©µµË™ÅÅEFâ IB·Î1áp¶7 ’¤Âñ¼cP¦1[­ËÒÃM5­Rcµ„U‘Æ‚I¤k¢ž¥TÖ"V“|¤(é™T%]Ãæcë“Öô1 z(©ñ ½œô�–|T•ø%SbýV!¹ºo§_*êfMh^ɵV}–T{[ EUý8ò+’È ÆÆÆÊå2÷ÄÌÌÌ{ï½GÀ”±a‘AVˆp8LeK%Џ¤Í0ì]]]…ˆB »f• o2™ÆÇÇñR'7& R@Ù^Éú´¿¿ÏïƒAÆÚ‰DbxxŽ ëW_}U*•pÆó€­7CN(’œ*l¸ëGÎ0jUZ­Z­F&®¥L™¯Ê‡jmmýë¿þkh‹DC744PÈÄ *!-¼²µµ•3ç"ó=2�­"k/D"¥–––(p~¿||<OMME£Ñb±ˆo+D8›L¦·‹/Ò<‹Å"R’H$òðáÕ•æ(4ã8ˆ|Ï  è�MMM£££šÊ2 &CÁbKzttDp§ÁšÊÐ" ½|ùrww—ÙU©T¸'a±¶ƒÁ`wSB³ÙL†tXV)ˆI@dÝÝÝ„Çb1.&Bq¢‡ö÷÷I•"FÄ&2Ÿþüy&“AØÖÖÊ … ð™:N4wl©»HpbðFçà¹ñh°0CdàùbÀ ¦X\@‹Å™£Úá©ä‹ã²ã£ÌúÁ]$5‘–Žá „5üTñ»TœBvçž$©WmŽ9Ž*bP3Ä4u¹nÇÌ$CCWU ¯š¤RÕ>V³rè½c/®öÑUÏ^×?ÈE6,BºÛ =jTw÷¤ZYÕE‡Tµž|A÷¨ìòŽšSÅ}H 9dµxüø±¨<&&&ð3 DšuõêUŸÏG!ã¾Äá» xÐ¥ggg¯_¿Žì`kk«X,µs‹#Gòx<LêÖ×׿].—Ô”?þøÚµkH{ÎÎÎùbÀ@êäáá!Š*Üñ¤@”$-’€û\.çv»aB„ÁÕj¥ÌÁ@'b{5 ±�[aI´²Á®ˆP¶+W®Ð°Ó* Ç—¹¶¶öàÁÀ*(h8 çíÛ·A–€ R©ÔÞÞž‡€¡y<ž/^€æwvv‚_³p®¬¬¼ûî» f|ããch6}}}¬|„ùƒAÖ6ر|^vZø„çr»ÝÀå7oÞä‹À©»\.3ígZÃp‚ Ëȳ9 mØ·gooy,_%×KÇÃ‚ÚØØ¥Ê`0@H===]__j÷*B `$‰–––ŽŽŽ\. De‡ÓŒÇljD"$k‚eAÃ¥ïA|‡û‹,ÿà«Èæ!¡Q—Óé4,j«Õêr¹˜•J%`Éd2‰«#³æÞ,lˆ!D1Ã0‰)=fïƒaqq*KÝÐÐÐÎΨ”tZЗ%ÉïÛÛÛÙþðÖ——F#I2Q$Ê;ƒ•R/Ô&•ì.XFØ,q@* $\y ²¯Ž"T§ ÍÔAãû w«SEÔúÒª–nÍô,Ó7…’Þ$3Z§éôëÆ^ëùBXÎjV9‰öÔç7¨À‘þ·8U #«:0Ë»ÄÃV«Uõd(¾PNè Øè=‡¢Á$•“.>¢÷±X,™L–§ßïç.‡<éóÏ?ÇΞ=õàà EßívLÑ,õÕW¢¨‚„rÊív»\.¶Ò¥²Ñ^Åb1ÖiÜø <···YZ„,›­V›ÒP(„êægÎf"‘HÄãñçÏŸCn‰D"„±«ÊÓHë éqÀëfgg%ÙÔápà¨ÌúŠí(_—½\.óò|˜Ç&“Éx<Ž9ä™p8,ZÙöööçÏŸ3na–%I¬³ãñx&“!HÙáp°*бrÚäh¾÷Þ{àN---™L†•[6´0V1Aa‡‘ÍféåQw3ÌÀ+ 'pP5»Ý޲¨Ðd2e2™µµµ••·Û$§nÜUYÉ0Idvņ„544?ïE<@1Cá#c#ø{ n†x<Ît3ór¹Ìf—cÿùó猠‘ˆÕƒª‡¹÷×jppù?û‘’d2™P(ä÷ûaE7}rrÒÙÙ){DöУ££ÂÓ“QÁÂÂÂüü<†Ò›?ýÃÿÔö´Ve9jHçõõz!-ñÔP¡4¥Iƒº«ý@ï*-xÑ÷Æ9¨AÈuùNo²]8JÒ‡_Ÿ‡/Í(ÿ— Q—ªUäR' z=º,9‚b©Ëê—ªOeà»±´ž¯¦9Ïh4:??OÝrµZR„ÜÉ­_­VÉÒâ5,!333Ñh(œÍ5½³³ÓívK¢Îoû[”Éííí8mÆ@ �1ƒ šPΓvÞívÿå_þ¥Õje=À‰Ï8úG»Ýît:ù]¬iŸ‘5!«†µ‚ÊŒa#Ý%3Ub[0Ž&χ3ŸÏwvvòèV*(‰‚¤ ×–ë�\NÝñù|°Ô¹¶ŒL&“Çãyöì™zÇÇb1¯×;55µ¾¾>==MäŸ^%á T—ËEæ6—x<>55…—-ß‘Çãa°r>"_AWWWkkë«W¯ŠÅ¢Ëår8‡ƒ8âJ¥B·K£@UÅD Î%ØK(‚ðÃd˜×ƒò³  v¹\D�æ)„Äš¹7Ø7)Ü'''ï¾ûn(b"uåÊ•@ À4Aˆ@$:äóyÜMà,`‡…Í ¤O\’ø²2™ÌÊÊ p ¿ËåBèÖ„(‡ˆ§H$‚0›õ˜Y=*z>ÚØØ_Y¹\f‡}||œÉd˜WÁC}ñâØàQâ°Í_%qˆ‹,ž(Xo±ñ‚ T…O΃¬‚<w@:rï…B¡ÅÅEn<ˆäg%•è멺Zpãiô[üU“W¯:#¨x»f±Ñ[3hÞH³`¨5ó<‰óÚq5‰¡nÕ}#(é<ºª†A$ò<U›§ÙÔh¶Ku™UªóJR§ð²¥RýõD^Ⱦ =tO£›J¡©qh˜<³|ÿý÷±ðÄ ™ÎOþG}tïÞ=âÑàÄb1³ÙÌ”3Áè '¢b±ØÓÓƒeéæææÐÐ 2:t�ÊÖË—/Óé4z:L)@¨É³Z­ª€5Éîá?þã? CGGÿ|>/Bk”·’¼¶‹Þ><oIpÌ>99"Y«Õ`²ØÉƒMD3éÐ?úÑÌf³ÇãûD,³ÝnÇr5 âè700�«ÕápH�Vì©ÃáðƒÌfó7~ñ‹_`/aµZ=zôèÑ#Ñ=}úé§@àøø˜v•âŽüƒ>H¥RNOO?ùä“k×®Á²'Ÿ93æÅ®œœQ¸XìÐ0‹joo/œh<tʘ®ÓæÃ&â1åÆVGXhf===p7Ù¸Àtxiii~*DgPGÑ{zzÁ.—Ëì688s]NM54$Ä |õè±ãñ8µ8 ’!Øñ@Nã¶9==u»Ý,Qÿx‚ÍÖbzåÊ•L&/¨V«á pppÀÜ+N£ „ÃÚÕÕ…1íÎÎááô étzmm­R©àrϲW,ñh‚‰ �‰PñX,&?ÖCCCl1! c[©T:;;i€„wžšH¯V ©'þð¿§OŸŠlíéÓ§€Òª7x‘&£SÂÕN—ô[S0U}ÜÌÌŒbÕ ?Jõ9Õ“?¥±–¢ªÒœø+g>99ùýîªu}½õ(>…¬‡*ªîXBÄ{ª \µGUEB‡¸Õ y;Fù:åŸÄ$tO\vt:?†[†78òiÀY±!¢›fïíÚ5ˇ‡‡˜½Ð°LLL<zôˆ`SÀ_ ÀåR©äóùŽŽŽâñ¸äb„I”cccãåË—1eò†îB}/•J€?Èe[ZZÄý‚?çóy‡ÃA‰h›Édé‚l@¨¥R@}a䈼„^Y«Õö÷÷———›››á2bQ€Ä:‹õõõ½~ýúwÞùÝï~çp8ÖÖÖ�Z9Àè½½½x<Î' Úv0ŠÙÙY™èà”Î’ƒcrròôôÙ¹ÙlÆxÙf³½|ùì…!ñ8Ì0�vL&Ó_|Á ¸‰4º Ä_Dã/Â*‹0܆úÒÕÕ µT*577···snGGG(T¨¤V«•/h_ŒFp°@µ�Pƒe㎎¯×‹™¡Ekk+uÛmÂ,J �� �IDAT HZÍçóÈÎÎΨïx¿³‹ô£×†Õc0„gl2™0héîîf)²,û"ùðš%€ëÏÚ7ÉçóŠBø{Íì6±ÏìVóù<“ªdƒøSÁ…ãÆ-jccãwÞá:s>»»»F£ñÿ÷@är9DõìSYÈFc0ÛÚÚúå/ùèÑ£,xeŽˆ!ØÍ›7¹aFGGùË_JZòµÓ§_d8!*6Tv©{bϬÑZIÙQgŸj;«:f«1)÷AÓ%ëçÉrdŽ£MÓm«;©ºÿ¯ÜUõÙÖu¥Ñu_¦Wë©Uåʤ:«³‡………p8,ÇžššR¬TˆË) “ÚäçD˪qá¬z=ÊoIF¹š0Eîþz€ÝL„PNŠ©ÓoÞeeeEœû²Ùìøø8Ciøãì(:ò%¸<ï{zzº²²â÷û)èv»„šá3à$Å)añϾž²Üà0hÇÇÇ×××áDw—ÉårÁÖgäH…‚GÄ¢ :<== ÑP\l14|öì™\1Çeœ#˜€¸N 1‘Ë+™››ã°|(ǃ6Ô" ñEƒA·Û ­ Àñ Õ‘‡Á`H&“èþàð°µ¢,B"ä§R©ŒŒŒlooC@¢©‡@üÓ°&¼°EbWĤO$‚¡X¥ztbßÀ^‚Ÿ],ãѸ²²ÒÙÙét:ñXOV5ɯuØ«¢>†’MÍÄ»±±1‹am+ÌQyÄÔ�| •T8\7pm‚ß588¸²²ÂÍÃý/¾ªÌÕ`%±�sp&X|_&“ éŽŠä ‚[ZZRIê’¿V—:_7Ãù 3%õ1pzOSÇj]ÇS}ÌÜyÎu‹dÝ¡ÂÅ¿533óÏÿüÏDæ³²×ðPU¬MãE¡Ê4B=Ö¦þYü6TI„¼¯ lêûªþ‰)|xñãd(ÄqT …=‡ŠF£8žªqÐKKK@@æÃÃÃÀß|ÍàæPïù-1ëô3âC€+5\Uy¢ÙQΘ§‰Ád[[Û{ï½Çä`j£Ñ‹ÅÈ#_+ftmü.ªfx±$pÁÆÁ•ÚA“ O‰rvéÒ%´Öv»JrEr€ TQØZ,n·Û±|@|[(�”„&(yÅhA„Ý a”¹B4]XX ¬˜ ¥â¡2Ðf199É’ŒG# ~ñóÏ?ç¾ ˜y�ޱÔQý/lyŸ,3ŠàÉÉÉîî.;ÅÃÃCx–$Nø577ooo³Măˆ„Tª3²,À÷H$‚¸O].—é©ò„.ÁØŸ iv?‰D"‘H0Èårìù2™ K¤‚ŒšØ€r{¿óÎ;—/_¦‡‹×,¾U(Èë¡{gU¸té’×ëe€Á]æÆ† U£Ðõñnoð—Ëåõz©éÙlÙc:&NÎT1´&¨ ®Šk@"‘X__Ïf³Œ» D;ŽJ¥Âµ¾¾Î[ã¹+•‚£® X\H)—9ÆjBŸW¯þŠÞÊ[³H¨ƒné>õÍ´¦âk4Xç™lË"¤ÒúëÎ'ô¥[¥òÿáóÁÖú ¹ûÁj[•u[wè­: © ašÆíV¦=ô˜\ˆr¹Ì –Öå3Ýå•rA‡‡‡ÕmÓlJ$èIÔ&F^‹exx¸\./,,P° ÜpÓËx¶»»›A"6G‡c||œG޽í-åÅèÊ•+‹¥«« Æ*4SŠn85Ùívl6ØmÐ¥;‰?(--@-e Mcc#B·ÛÍ[ÄJ4¿}ñ—Ô$Ä.—‹Ja±XÆÆÆÈÈi‚J"à üág?û™ËåºwïžlÔ@&ÒmmmÔQÃÍÏÏËÒNɘšš’Ö•‚ÅybûÁÉÃÔ"hBêééé·ß~»»»Ë† ±±‘a25¯r±““á­¬¬sçp8vvvpÛu8°{›››‘’¸\.tÑN§see¸)›ÍæóyP¾ƒƒÞæ.¥þkØN>Ÿ?99Y__Ïd2¸Ýq>RRÙDc1„$“É€300À²T*•ð”£*ÒgÑ3² `S”»»»›):=ͳgÏ,Ëàà J@”.Ìíe憉éuìK ·âÔ„/VµZå„^0,dÈ'Iч‡‡ãããrÛ`Ê4;;ËÓÇ×A5ঢŠ&dž}/yêRÁ+YfDশ§ú]j©ÚmŸ§*Ðëº4¯Ôàç åäÃjÖ†ó8Qo:|Vc€Ô¥FÅÑ4IŸšaˆšâyåVc઺\^„'šrø[äZ±Q}œîܹÃ7*"u^ÓÝÝÍC²³³S©TnܸqóæÍb±877Ǣʟ‘5˜ÍæÙÙY‘õÒRXÁy�ß)Oø>®®®’˜Èó†(•JÁ³îïï‡_$3±ŽŽŽGݽ{—ljÐ1d¢ü+\-a¾cgT.—Ýn7% L_rž…ŠJˆO)æ –a&3�Ì-f³Yb añ£©¦¼téêÖÍÍÍÓÓÓt:}xxˆÕëþþ¾Ûí®T*@à_þå_ÈÈ»ÿ~KK‹ÍA¨d}êïïg³BªÓé$âô£>®üþáþê¯þ èŸÚJaƈ78ˆóÆÆ”¼°Ø »|ùrSS& ˜•âêÁ \9z hY)‘ €éS ©eÀý˜F`.-ö---¡Pˆ=„X!`‰DZZZâñ8)R9ÓéôÉÉI:¶Ûí;;;‡ƒo'“ÉX­VB, ¼aŠËEµZÅF‰Ù |LŠœ1•M¥Rô%|Ý€“gggü®Œ:ÈB¥qrrBF7ì,(L¢€;==ÝÚÚêééa>ÌÇlhh0 Ì-X� 6Ñ ÓA»B a4wwwÝn·:ë­·p”:;;«V«Œ÷¸ÿF£×ë%Ñx ¬ÙlæN àŠ!%E¼NÉZg|Eµ½sçN±X”ŒeUÇ d2°d—Àkô˜ªÊè[ˆäöË/¿Ôç<«fuþªz¬jP)“’æ€?ÄCo¨çré… ç¬ê¸zõ²æ_ b ®·ú“Ô$ðÈ‚,Ñ=ê»K§ çø¡í¿P/Ô_œ°ˆ? Ôåfgg—–– W `…_Nƒ’'âaèw6›cgôÃd˜twwg2™ùùy}.—«P(´¶¶â´ÊÓ‚1Q2™Ìçó¹\Žla³Ù|åÊ |€£þþ~†Ì2‘f@vg·Û«Õj>Ÿ§K…®“H$°P¦e£écŽm±Xĺ2#D$j•H$hN€&Ìë·¿ý-|ÊÏ?ÿ›Xqò€oªîjµ2oÕ_ú¸h4úÞ{ïÍÏÏS¿P/³93™LÜ ´¤•±;‘=`zv`Ltív»Édúæ›o0>¢///‡Ãát:Çc±d¬já‰Â™q¹\08mÒ 0Úå»3™LcccÍÍÍàéì`\.W©Tb®ëõzT@ CôŽI~¨l+• S’PÍf3{2³Ù S‰†Û ¹\ŽÙ5*6¼(à†aÓ‹"/&nÑÑåï³�°@²p»Ý¡Pˆ·�žâ°x"=|ø_asÆV€§€Í1 ûŸÏG¹gKMRw»x<ÎÒËÐåððH=¶ÄÉ–H@¶×œùùùééi¾DÃ,4VU`Ì8M¨i?*>!•GÐo¦(^*„p¯ñ7Õle¤„ª¿Xw¢±UݦÏÛyü@(éâ£è!* ô/%[?1¾Xd¡.hªg¬˜"hp=–B6w|CšI‰ºœ €¯ j·²|g|(ŸÏ'ŽFâ§$$}îŽ&Qk@`zzzll àbnnneeellltt´££I'r”¨°•xrjµZ4EëÄè—cÜ(ÇÆÆ@ð9Ó©±M¡knnÆ0¨mc>ŸÇa»q^£ðÐòÿ––˜é<K€K&“iaaœ8FÁ£££˜>±*ðìõzyÈYZ³ŽŽf2À(øï�àrc±X)¦Ô‚ãÉw!‹ )°op^À`éÙ³gÓÓÓSSS@|Df:Vˆ{÷îE"¸ð¼€ËBˆ|¿À_L„r‘ 8ƒ4œL&“É$* ›Í¶²²ÂÑØi1&åƒ**&NápÔ…â‹V®··—ØÆÚȾXãñx¡PTNXFétZÜJ@„PžW*•ÅÅÅR©‹”h6ÚdÛx‰Ûl6$;tâ4´çÕjuuuõõë×ÅbÍ 8§ØlÐðÛÛÛ×××ñ5J$ KLJgË‚‹»ð2NolläCA1k]YYÄÅŠër¹ÖÖÖÙmlløý~_š››yîħ'Qª-]5CA‹0Æò"C“¼†1¾H£D  QÔIðzM{-ý´:[Õûԉݷ^I¦™LèÛëóz}*› ¡«ÿ½+é{£˜ã«ëÁ¿¨NÿÏóñ8Ï©I3¦× 4aÎêY©çY×¾ ¬PfS2U–ï^N•{å³Ï>£×“ò•‚ûуDS¹SÁp@ÆáqSY`ò´¶¶®®® oÇét¾~ýši½Hޤâ¼_‘ÏùÌ¢j6 à¤çóy8©"Ç…J‡²§§‡ |JfÈãÌõ™}öì†}<-¢þƒU#Èï÷³ âžÌôX˜`Ô\VeÇÃËdlÃçåQgœÃUâÊ£´ÂIŽ,Ë 3p†½µâÑLveˆîõàà€):Ø"L@Àù Sw.}º¬©?‹E^&ÝŒC¸m q†�5ðÁÔ­€¨¥À÷¹=@Q¸Î4û˜¬x<î%ZoRhäív{>Ÿ‡D@û둊€ÁRC—ÀÖ„` &Il­8 sæ[ €–÷å„9Iør@=L˸±ÙCm*m¹\róv>_èðð0Ô2ÆiLhÜÃY:>>V9Hz|B<S5Ï8=„ì\¥ŽÍÏϳ´¨nH*N|ù׋yD§Óë•óZg9+µêUÆuyS꿾Qæ³~~­²†ô§¨®fçÑø³8Ö©Ói!ÔyI“_!x‚fÜ­¹¦²¥P‹»HÕÓŽF££Ìٹ˅‡Àæ`Ÿ;† IÑ'ÒzðdþÒÂàÌf³e)¯ìèñj®T*¬LITïîîÆ'Îh4²Q`@âãþþ>ãØ®Ì]Öj5Œ‘IPÀÿ€Àa²KY K˜;a–X1K ;99!;ŒˆºÜÝÝýùçŸ?|ø°µµu||\µ®¤þ" çü>|ˆû(~…LéEC. Çî¯Ífª2™L!Øä566Æ’9::Êt_ÆIizzšUœeÅ;Œ€2™Œ„ôa.‚õ)¾åØ©BºXƒöc³Ùx_„ܲ*p|˜šSm6ß‹Çã …B´áÁétÒä"{dõmmme' “¢ÙÝÝÍâAÅoooÇ"‚ÍÔX<9¦¦¦À¡ SÂswkk É¢\³$Ì=#ɦÜ]Ôô¥¥%–af*花¨¨á®�¥¡Ðƒ51~“•ÏãñÀ¿ Á âi2™DiØÑÑát:ÙeÂã°<wííí¬ ¢yæ)óûýp–·Ó¨(]…¦jsJ¼˜‚�yZuüÄSl•"BÔ@¢±—Ö$0K3T×U¥ƒª£c5èL_ß5Œl©õžÓwáßo¢§×ŽiÒž/HD¨+‹£%/—˪éžf­±çÔ‘¤É…ÿ)]ËGE˜¦ÉCò&?G“ŒMÞ”)6²[й=„4ܸqƒ×ôõõÑÂЧ_½zÔž8ÇS©T666À|F£Ýn·Ûíìñ©n^¯Ó1v÷ìšÙÂ#¸…8D­DÖÓÓÐ+�}+ÎÌŒø-zIÑ6Snˆ±dS_.—ѾH –s'''¤Ð×j5½˜B]Iƒ§žõissóöíÛ ~¹Vsss·nݪT*¤ô ³ÝÚÚš˜˜@K…•7vCGGG$g@Ï/—ËOž<¹zõêƒÀ˜Ä,..¢Á­òLgg'Ó]Dy;;;d|øá‡ www¯\¹rzz�æ >ŸïÅ‹p]0@$’Áf³‘<Πj¯ÙlÆ5d:á°²ÀÓDZôÝÝ]*,ׄ¶RßNOO_¼xát:»ººÚÚÚPxmll¤ÓiÆ¿v»=ìíí!7Á]•ädÆ(�˜£ÍÆÀƒ~||œ-—8šœžž.//_ºt‰6 �á¯3ÀR“– Ù…D A;&¶öôô;�—Ëõ‹_üâÕ«W@ Nëׯ3W'ð€…™AýÆÆ^åŒ8a¡±±r�¾1`K¥RN§“DŽŕ-K<Ç>#ü$7¢\.G£QR©y”¶¶¶ˆ¡Æå . ïäóÁ%úçD"ÌøÚµk�“ƃœÂ…N Öè×H•µú2µ~~ùå—ªîl~~þñãǪkžM¦Æ£iÏz·P^7¤™`"5¯ôšèÇ4}à †¦ñ'c@ãeT×|[µQi¯zÈOýu–÷ )²o¯ó¹¹9hέ0yÁ·~úô)ÁtŒRâ…“j±X–––, ݽ8| ÐK9 £™¤pC.$¨„_çù·X,¡Pˆy˲O‡›(Y¡P€º?Ê)ôJ?`ì Èãea„�˜¦¦¦X,‰DXá’ɤÇãá‚Øl6ÚgÚpôq­­­ÑhtttôÙ³gÖÑÑÑááa¼Tù3 ÐJ¡P`#5??O‡ÇËåò³gÏž>}:55E*=£dïÈ€‡¹ =#~S^¯ôinnN|¶3™ {8š_—Ë•ÉdP–ËeñèRÁʸ¤"Tæ—K§Ó´Ì €\`ollÄb1:\ÎS®§Dk‰DHe`3ÊZÈqòù<sn•P(„ñ\kkk(º|ù2�Ô À=æÆ(×€±’çúÀþþ~>ŸG¥Q.— †;99q:dvnooïíí¼³»» ¶‰DVWW§¦¦¨£«…‡mßE±Xôù|¨ÉØør###4ûÜ“¤UÇæÒ¦X­Öx<ÎUJ§ÓÉd’°<údq.— üÊï÷c%²¿¿ŽÊ.œO„T$Á£ìðð“ p¥ìþ)G´í@ül˜cɧãeRFGQýø¤¤°3VE—*É^ Œ‘±¥ ``U׿2ãÔÔLýô´®ã“&(á<\çûó.À÷52´º#rÍÉÉÔ`5‚÷i轫TýëÂ:ϳïÿ>—ßáááÌÌ Rƒééia,ðv<Æ€|ߠ爼Âá° ÓÓÓ´H6 ü¨ûöÛo>àC&¼ ‘žá™C' ¦ÔÞÞîõz“ɤ×ëÅfõ) )-QÑHä»ï¾ƒMÏžª Ñ")t¶ƒV éôôÚR&“ÙÜÜ‚ ì.//óî@Àëõ’±…å\ �çááaH¹&“2žEÌú[~ «K0µÃq°hzzºV«qñ)¸QããñxÜn7ÒqÒ ¢Ñ(Í)›0¹‡1ì#‚=;*¬¬ÐŒÚÚÚà 08å²·¶¶rŘs{<žd2)2@›ÍV*•¤}á:ÇM5Ò6£ÑÈ*%ÃmÔ¼hÅwww³Ùìêê*x’ÈF-CSÂ6®Z­bApw¥RI§ÓKKK‘HÄáp`×›¯ø»ï¾[^^&´«“Éæç祲G"x d¤˜NOO3ñ9‹Ãá “ ƒÁ6œY 4­ÞÞÞÿøÇÜð2®Ëf³\äl6 …è{X!§Š‹uŸÍÍfc£ÀÀ©µµ•Ð'¼OÊå2›ÔÜr}f“”fеF•&ÓcŠC]ûçééiµé‰F*eH­czü\C·‘zEo*q]´\_õ‰j껟×å¿]õ<>’ù:Ï<V «FxªûùuÈΓfhþUàźg%(h8reÆôT“¹¹¹ùùyU¹õ- •šò$‘dÜÊsss‚~ºÝnx±XŒÇ(u„q¥¼Ôj5æoF£X�ô‰Ó�b8")www—0H޶¶¶Æ"D¥¶Z­n·3"{à·€´zÐ!²')v»ªÕ*sQJ0-IGÉf³GGGðy¤FÈ?É”X®ì)ààææfá°NOO3eõx<SSS «  ŒBp¢ãC¡F¡œŸŸ3¹þÊr¹üðáÃõõu6m@ÀjµŽÕjµÙÙYü<hÞÛÛÛ‰Àã[£-Ǔ֘”1rŠH<èÀy4‰pzôªxbÊýÿµMM¼6Q €¶Oä'»v*콸»˜£ò¥s³~È(žƒOMM‘¢ÊO˜E“PM¡„…FšrI=³.2(á9gØh|ã¸à…Ãa¿ß˜œ+Oóu˜ ªF¯× µšA²¬ùh\ 4ꇃÍÊÊÊ«W¯Ô툴ìØX#‘†ð¬8r³[­V.#ÊD¾åÖÖÖ‡B8<<<d£ŸL&¥ÿ6þ 6Ñ\gŠ ³ þ•;GÃ%º‘>(MƒghʱÆU³–èi¦uk¼…7œçä¡W ¨ç©_Þ(¨G3xP³ƒˆR¬n¼:‡ÐÄj^+Ÿ~H NOLk•ÅCà<9,‚8’¯U¤K,;¢±y �´„-£fbt&ÞÔ±Xì­·Þ’$wúbú;Tf}}}€æÌˆ@I&“<Tø–J¥|>O;88�†-Nç¾³³ ¼ ši+mfúÀ¯íííD:wvvâhÆîË̳³3ŽS*•7Á«Á¤ð9¸¢òñ£Ñèýû÷A¨K¥«—/_ʦa}}ÝçósMÈÒ!.ôøøØívcËA^,_¾|F@©Tzÿý÷F#<®‰‰‰ááa$„}}}çõë×èàòù¼Óé¼uëV*•J$P°:::<ÏÖÖ`ú“'Onß¾$ðöíÛ 9¯^½Â“çÎ;ãã㌚œNg2™ òz½X $L! Þ%‡ã "Ã\¯··§U¾ÜÎÎÎo¿ý–µ­X,Úl¶íííöööÍÍM̽ÙÀžžþþ÷¿÷ûýÀúÉdj)»Æããc°õµµ5£Ñøøñãëׯ'“IäZN§ÈÈn·ÿä'?|L¡Ç†ægËî“#•J9Žû÷ïÿíßþ-RvýÅÅE†=8ÂJÆ2çcµZûúúÎÎÎ.]ºT*•`ñB óù|l¤ØWÁN¾rå *Ëo¾ù†dVšzƒÁP.—/]º´´´400€e$¹8œ#Øæ&ç†lkk[\\Â2m C‘T*EU©TBÙƒ§àƒ>Èårx\ÎÎÎÞ¹sÇápÀ¯e‚ÈFUšäÒ;NpyÊÂÓ§O-¼ÿþûxkRXæçç'''ù«Xybr§™<}úôÚµkÒ7kŒDÅ\O-›ªŸÆET¿ªÎиûé'á°jœ§ŸLð\üüç?ÿb¢w1KC$=+ÓÿóœòÔÉD]£+õ•*™UHBr˜¢€2!ŠJ±xS yz÷71Ò‘u6›ʧïñ™!'OnØÌ�èÔP®Ò²á'ÃCÈ€”}:³8…ļ€ïÓØöööRÔ„ ŸdooÆ«W¯œNçþþ~oo/v7Ì!YH˜Bã· oÊétÆb16:ëëë.—‹åÖ©¼Q¥RÁçN¶Ì²ãv»Ýàæü„y€üëôô´¸ªŒ@Ê=ÜG1¿“o‡EK-ÈPâ[.—Àúúú»ï¾»¶¶Æ‹iEá×bÕ'~>ð‘˜yÒrõhÿ™ß¤R)ô" TŠÅ"†ál•à˜A8ŽD"ÜBlø�pº»»C¡[Oñ°ƒ¼½]±X„¢Ã"‘ˆßï_ZZeL…ƒ_débŽØކZ¬å³"0K"UUÒаØÃY]]õx<Ø#rKóbõ-)­¬¬ðÅ!>O§Ó˜Ç =|þüùää$,̾á¤Ói®žÕj¥Ñ±X,è–Nçòò2ê„P(ÄÓqÇãë@qÍý‰‡ ³ˆÅr’�Y÷î݃ü"²S!¦û|>¹E¥,h6¥Jˆœí¼?½UÏ}“À›ïÅðÏûùyB‚7aÄò‡7¥«¾ÉDú‚´†e%«B]…³RÔbs¤aǪ#èºÓU”(*D:T¾,wð®ÕjÅ]<óL‡Ãá÷ûß~ûm!ïƒTª«‚ßï'‰°»»»««‹¶ñÒ¥K---LØH> ¸8ø¦�GŠÛÚÚJÊ.¯d­Âš|�ÚFCCCOOm;nKýýý­­­^¯—@M6±XÌn·û|¾ããc:¯ÖÖÖÞÞ^š/úJމ zooJÉUÎd2Éd/O1.fscµZ!§ªbÝB¡@a"[ üs4“Éôë_ÿš oU4]Ufþ>ä² x §6P;è4GGG÷öö¦§§E¦î÷ûøâà†²Ð25-•J©TŠ < ŒÞÞ^FÐâÉdb±v¹H±Ó%p¡Pƒ¡Pˆü%Ö-®d,c|‚‘~YÑh”r|ïÞ½áááx<ÎvÑ=ÌQöv¥R‰Ê_Àëõr'G£3ÙX�� �IDATQDXÈq» ¸ždø444 —lkkÃǘH$ð@åâÞF?‚Œß=‹Ç㣣£Ÿ}öTZìÇ9ÕÑÑÑX,Æ\z? .--˜Q­VÁ…âñ¸ÓéÄSö›o¾Yâ®Ã£#H&ë¢ÅbY]]€- ^¯Í3;?Iï©V« òÕj5“É,,,p�VCLç'årùîÝ»š´.&½jíR ‹è™ez,`€¡ÉÓ×(õ5‰™fæZ·®ªæHaé…¬+t]ŸÕóÇAI ¬g©ªŽIûUÕ@IŸçÌ¿ªÎ!›#‰pгcù+$3ùWÕyIv‹rpŽÆÏYêoܸA J(ºÿþÉɉÏçƒ8•Þ<¯^½â5¤oÚív'0hð"òFèÄÙqS5hNASÖÁFººº$¥¥¥Eâ”ayg2vÍØ"1‘¦Êçr9±*cj õb>)f0ó «²óÀÖ‰#1˜ÇŒó±Ûí TÄ9˜Íæ\.çóùšššr¹LÜï¾û®««k``àƒ>àá’ªT*ƒ!N÷õõ9Žÿþïÿ*•J˜LŒ'“I¿ß¿±±¦±q¯^½b›/é4Ÿ|òI6›½sç|GL)X‡GÙl¶?û³?CÜÑÑa·ÛqÚÚÚb-ç‹`Ôëh¡ßÁÁÍfK¥Rȶ¹æ|4Ö<æÈÏÎΈ|À8]#‘5ÚùX­Ö\.Ǧt>—Ë ’¶±±áóù&''¡$ ábmÃN1›Ínoo£RÌf³‰ÓÑÑõ, ÇÓÛÛ‹ßÔ¬D"ÑßßòY*•°Víëë#Ó;•J]ºtéððpssOÆjµŠ³ðÑîî.’iüþš››·¶¶xvvvÞ}÷]Å rñÚÛÛñ™çeEXC˜à×_ýÎ;ï�”‰Þ‚)Ý“'OnݺEkvv¶»»;88È„§›xæv„W÷ÑQE£Q¦GäôI)˜››»qãÆÃׯ_‡¢ŠWÿúÅ_üû¿ÿûƒ¾øâ !6üß°hnE9šüA­Úš°QÌ}ùå—*™•^“NF†O]¿˜5ŠKÕ 4&uug|´ÿÿó.ØÚ\¼s¹`T7tAã´Q†Òü¢zdèb¬ç*¾¤QâÑýìÙ3hú§J¦#Ð$ ƒ™L†)ŸLáРáöeµZa šMP2hÁ@NOOIcç©»0˜$3.¦ÜË$Ö6½¥Rt/ì{°/¼çHôu:$‹‰œÑ‹vUè6°/ç#$¥J¥Â2ƒ‚O·¶¶6âq|× ^,fvf @2Rµ3ó|d "˜ÇJðÙþó Š‹--¡ü\ØÎŽŽ¢Y]]• ˜3$¤gN§3‘HpYÞzë-ÀÀµµ5¾â@ @3’L&ƒ™B•G ÎwÊ1‘k¡UäžQó •q\.ùôÖ¥¥%R@€ª1–¬\­´€N˜ëÃG�â³Ãò‘ù3m;×cG¶ACCC¯_¿–Ø ö âf*>Û‘HDfÅ|L²+¬Vk(Rwä0…"‘ÈØØ¿ï¾ûŽ!D2™t¹\ò#‘ˆÍfC©388ˆ[%˜!›WÉ/a-DY ¥ v†×ëÅb¢¨1¿@FÜ¢ Øt‰}²ì\êÓ¸Iš5ìACÄWT¼Tõh"þëq1²tžÈ¹neþ# ¤ï¥4Õ5âÖLç56|uÝhõÃ=ÓTæïê&HÞ‹ê _„},(ÚwÕb2ý Z­.,,0Xöx<¤™³«u:øõssÃxƒçCÓJn;ôÖ�öôƒÀÖ¬x€<p&4>°ƒèÈÄdžœ"*ugg§°_˜4ðí’[ ΰ¹¹ÙÞÞžJ¥²Ùìîî.&H9�%‘IG«ˆÃ3ˆ|>O»*1vÀVF£‘‹ÓÜÜL,;æÞG;;;ƒÁ ´EüË‚Á`<÷z½Pú„TNÄÅââ",/(ƒŸ}öÏ'”§r¹,îX‡ãéÓ§ì „±CÖ ázƒŸ86"ñž™]3PI&“…B¡¥¥…¡6 ¹\nddÎ%sÂsxÇÖÖV8âsÓ‚±¹D7�° …#¼[rV›Í‰ Å— ZŒ%$›Íé!ŽO­ÇÆÆ0žbáéííu¹\ÔMTÓV«õwÞá¾õx<ccc¬[|YÍÍÍøqï566f2™+W®455 y½^ô~¿®‘,óìq0òEH˜èááa(’ì)¾tÔ@�îf‚¬ 0”P׳½�¿%ÍüÍ9D2¤\"Ú\ÁÍf3©'Ò Ò²€• ¢(,jnH\Ä^¦FOMMÉhAÖ�hN"ý?则¬²®ˆZU6Û^£”Ö{t_ìbWqÒG¨äÚó ï›BI*\£‘É—÷ÉŽF5ßÖä}ê¥ÑêÁUI³­ñ³ŒàeKõõ×_ONN²“b3ˆjvÁÌÌ ®œ$¯šÍæ­­-Õ“ãÜ‘‘n;ØŸ»»»øÃ¥”ÃE!MÔ­@�.Öùétš' ˜ˆ ‹5Ù™ <  Õ$¢°!@ÌÁ,‚q 0‡Í8 ÃB@,ake4Ûmv3mmmÌÌf3¨nKKK&“•³k¶H£¡3±mG@„¸ÏÞÞä(^¢áö€¥R)ŸÏçt:¡„&“Éááá;wîà¿ät:¿ýöÛb±ˆ I†»»»¤² àjkk[[[c©8>>¾wï^ssóÆÆø@CCÃýû÷½^/òãÆÆFŒµ?ýôÓŸþô§$„k~||l0S©™šÿ‡¶w‹mó¾ïÿEI”¨#ÏQ)‹ µª#œ…pÑÖÎ’�ž‘-mt.R[¡vÅ y€Q@¾Òå ]êN7¹ÈE°CeKç n«Öa#G’E‹Eñ|&EI”ô»xýóÁÏC)‡öï C–y|Ÿãû�•r5ÄiÎ,i¾··“¢ƒÁ@c‘ÍfAÚ`§ƒ¨ª…©Tª§§§V«¡ìF Úk¾(ƒ)Lô€Ù ‘ŽXz2™dɵ»Ñhx½^ŸÏ÷ÙgŸe2J¢¡ÇãiµZ¿ÿýïÇÆÆð ç<ŽcÛ)lhh¨¿¿ŸµóCùÀ}}}.— 9ö+Dyþ†g³¾¾n³Ù:::ÆÇÇŽŽúûû{{{©Q<Y­V$ÖY€Ú@Á71`àv6›íÙ³gl’kµN·===�¨¶··N'+“îîn¿ßÿÉ'ŸÄãññññ®®.—Ë?ƒ)¶Þ˜#áÑl6ùú"›Á˜ñàààÞ½{¢†ùÎ;ïŒß»wQE¯T*ç™yBÜL …œüᇮ®®f2dù%(¹ÝîP(¤Š5 R™KKKb-,ÁSuV£¿ :’ÿb®ù¥~æ¯Æ^ù§ÞéS?JúâƒWªÿÐú¥ùôzý U B3í’ùZ[eŽóÜž%C@XCmÍ[øýþ»wïª!¹tzzYÇŸýìgÏ?ÿ<¥¦Ê'''ÔÎFÃjµb\ÃæàñãÇ Lù' kn*AŒ˜és5b^tvvõ "+%l5Ü4Ñú‡cÅÜ€ä Þ…| t\¼½ÐŠ@¥Te>Ÿ§õ¦ÿ?ŸF£Q¯×A âùâ˜ûÑ-3¤ùÑÆ) @�ñ Fj À•ßï—A<é-•JõööºÝîB¡€ ¯.“ÉĹ´´ôöÛo3Y¾råÊÓ§Oñ‹_\¹rÅï÷Ÿžž‚Õˆ™H$x壣£D"155õÇ?þÑï÷_¿~¼Nç< BB ´G‹íÏ££#©ÖÉëìŸt<£ÑøÓŸþôÖ­[ìx¨j+• #x06°U,Ëþþ>وܖL&F£Ñ`qÊâŠН2�ÜX,Fôd‹ƒŸíQ¡P`]„£7òœÅbi4333´2.— .p€Viàêõúï~÷;ôÛ\.sQ›ÍF?ŠL¬Ú¿2nr8^¯w{{»§§'›Í¡¸G™z6Åk ®F®ýð``ìÙÕÕ…ó„Çã«(¾·FWW—Çã9;;ëïï7 ^¯—ñéÉÉ ¶Û”V`jÉI¨¡Ð¦³…~öì™ð(4{ûí·óùü7îܹÃ.éŽüÇ$¯ÓMÒdïèèÀ2úƒ>˜žžœè7¨/%Êsõâ)266F BŽ¥ÌÕøÙÈ:Vó`ÞQò‡,qåÁúJý¼º\þWM?’$þÿõ|¾@ Po^zžàöy+ýéÕÕÓ¶ÝX¨Ú‡ªà¢ì÷ÅÞYL¾@'©z˜ë&j 2~饗666¦§§ñÈ%”]'<±dc”nFa¡ÝÒ1àÌÌ®¸ÙlââB=>šê~ww×f³!”f±XPõ!™!ëm³Ù¨^AXùô1œœŒŒŒ åM©Ëª– q|ä äëƒA&oÌX¨Ëå2rÊì0ªÕªÌs‰AÂ$§ÚeO ÿ L…V†ÓÁÝΘl@æbz₦žAGGÇðð0ˆL)z«”Û€MaeÔü¡{`;"" |Íþþ~FÛrxß••‡ÃñðáC1–5Yq$<®Ю®® J•«+™LNMM!¾& 91O:ÌŒˆÂSöhû�DñMy ž Ï©©)`¸¬ú¹ivQ:r:Ïž=ƒ©ŽH×*S5.$«ÕÚh4ººº’É$5°-§7~ðàÁ+¯¼Â¡@–°Á¢–ÂÚf³mmmqXäÆdì“J¥&&&8ªlà«Õ*W VooïG}$«ÆG² ’›Z@ÌrÛªöï¬(D©WÙã*/ u‹ ÷¨WÇýÏç/³¦ý’ÁV õqïâõðŸ®zÞâ¡-îJã“×–®‚V5P-qúÕH–«yB5`Ðг%è«^*"V„MD5E¦·¿ÿ>{¹¹¹|>???ŸL&=zÄTÄ·x8÷öö^½z•}Âd‘Hä5TXì˜T°øµÙlÄ_ê}”ñ«�b¾¨Vt5Àç£ÉÅb‘µ–”],Hóù<Õ=Y=9²l› ÃüÇ�§AéÞf³1¤ÈHÐÙßß/•J[[[ä-0…HˆC—Å·€§0¤fÑ-.1œ/ ý›››âz„Ø#]ȃ ŒÙ‚Äb±ÍÍM–âƒÔl6ÒãC‡þ)ý+øÉ•J /[P¤–Dv”" ð£ÑˆÅ^OOPà\.Gc700€ÉÁ§Ÿ~º¾¾žH$õdÃÁŒ›+GŒ§�-³X,\«l/X¬®®F"¾#¶?„u–€Ó‚Á Û톱dËf³Þ¡¼€ËljD"‘ø¿ÿû¿\.ÇÉ* ›››‹’¶··iM¨ôYòs Á{üøñoûÛf³F¡p>yò$ B²ÏçY ´Z-$¼`çpÖ, Qfý•Jåå—_fÅuzz ]°ÓúúºÀµ'''A#ŸÅ=èv»éÝ9ûˆ»Ð"³Þã$‘GÃáp QÞz½>333??Ïò# Š$;|šùùy$¹Vœ<Œ$«M2:‹UjBcŠ J÷«Êo¥Õ¶Sþó¬m× )ÖŽsl¢/àQÿ©pUu7 êö©)Qš M#£‡éWò¦I*šŠy›qÅ“§À—ÖÛ‹ª2„´Œ¤ä‰¼àÍ›7§§§ß~ûíP(DÍH¹wïžqo-7•8½0ì'4GONNž>}êóùpûÃþÀ¤Â03n4·åâøÉ@T'©Ü™’˜wËÄüè舼!êM¬Ѻ8<<Ĩ‡Å8 p©z½E ¦cÈ+áÜ€êc úÐ}©(YPG£ÑL&c·Û3™ŒËå"l )Ì`0$“Iÿµµµ@ àp8vvv œK ppÀŠb``�†3­’ÛíF4[ ÀÇÇÇÏ?ÿ|(ºråŠ�‹{zz¦§§'''_{í5¬o�Œe³Yäoe’Æ—%l¡ü*Ã: ÏHd.—‹E €WΈ×ëajÎc<ŸššªT*ãããÃÃÙL¦P(LLL Û�渳³þ„ËåŠF£ ô¼^¯ÀØz{{:NÎ&kU> ÃÿüÏÿ¸Ýné2ÖQÈ#ˆ3sfæV¯×ÏÎÎ&&&þû¿ÿ¨+r­ƒõòöö6¨k25J­V»»»Ë>‰ÏÀ Îår±<w:¸ ‘oXc`B…ï4ã5¬Oé 郙V±Û`ÔItcoo¯ÕjÃB¡055µ±±ár¹8òb_Ê®M½ÞÞÞþð‡8z"ØW.—¯]».¹§§'Às†êŒq¬ôÀF™9«ƒ r¹,ÑCTK?þøc^JÕbP±¤êoQyM•ä¬.V5sx56ªáWBŸzž…fîôÕÔUÛÊ©jXñ&µ'h› .`ýI»M— ªJNÖlÛ5âS¢y¢ÚiZ-Í'¸&Ÿ -< F© œ¾pƒ—µµ5öD”!Xðööö>zôèå—_~øð!ËgLÇ�NÀ"¦&¢8‚Á@Â`d/W0]6L4Xi¨›ñ"È6À~`û R>Ð#Jד“Ê?>>Æ@˜¹9=°jµŠã} Y4jÈsb™Ïç'&&fggý~¿¸SÐÝØˆÐE¡)‹¸ßïGÕ™ S;Áb9¤öÅ}A^ÖëõR%!º°°€j݆˜¦aáÀE'2/+`ŽÔ•xS"øŠ@)V¤“É499) Ç#R¸ª,?�P·ær9Ú&Ü,8qn·[˜%ª´”0™S ‰³÷ØëõÎÎÎÒ=€›B¯;—Ëÿ N§Õk®4Ìò %žžžÒ¸ð¾¸/à;55E_B3‡²ïÐÐÛí.‹ð <F¤¢nT,©ŠœNgWW_³Ùl‚8†“"â‚0:qæápœœ|úé§�^ÙcƒAiFE?˜ãÉ}�[o.iè/Ô[+++  Å&ö5`Âx<^¯×ý~?ð‡••à‹*aMUCRqíj°Òh:ˆÅ²Ímk1"lkx|Á?5ø%ÍIÛlÒõxѯìàv±ÓÐW“éE2˜É^@ÿ2ò¶ÏÒ�dÏûxšWæ²Ç3� ©ñuâ‰ÿþïÿ‰D¸LÕM÷žÏçC]€‘«¸V‰¶ho@A¢¬F¬‚Ï!!ƒ]z胡R©°d•ÏçEŸdƒ#…$#£o|ãÉd&”˜…ù|>Ò pf÷uÒ:11A‘N& *^ä?ÁËDX0û»"`àv»×××<@XTæuÀ+¬ÀŠ`´"G‰±µìXhPê2–i¯&„ DçáÇHh üÁœŠIs6íÀpé*€  6ŸàK* ‡Ã�ùOOOwvvX·²c ñY³X,¨¨ryð]’Éäôô4ksD‰ëº ¦&""sK$óX µZ-‹ÅòôéSj|.<B$ �J !9æp,hX�ˆè7…¾££ÃjµÊVƒ6KèÇ´¤¬—™Ë±Ùk4슑7æ-äÁü,µ‡W°„ã¸q·Z-úB¹f`˜ó3 (‘HDH0°H(‘àÖ®’“YBHŒR ú­ƒfy©Ù_¶]¸ŠE>¾©¨­˜Ð×^úž®¿ÎŽA®ø2™M µz½@!‘kt õzªÝöy³0½ !Ud[åÍŠBäsUä„1"Cj®ÍŵÀ9¢!Jc&'™† ŸÏooo«Cdþ þâ¨O¹\e^iWWlÌgù¹^¯y3™Œ0QK¥5>U ŠÃáˆÇãPyÿ?eÝÎÎÁÁA†!Loa±ñ|Ä/Š8·ÛÍ^;_¼;::FGGÇÇLJ††@OOÏÆÆ†Éd"+ËŒf³ Ætqq‘¹?嬰¶îïï___çë¼âñ8éÍÍM¤ ÈËçóßÿþ÷É©4[! I`’áõz±•ÄÃ9EwnXŠ_„‰5ìQ¢W­VÏÎÎ�êX­V»Ýw7™LrBM&‚?år™Ÿ\€¯"‘1úï(mÄ1†$ð‰‰‰““ŸÏwpp099Išg°N˜­leïß¿½xt"‘˜œœä‡††‡Çãa¦´¿ÇÇÇxb3o¡³1›Íl&„ŽÇR¡¿¿Í ¥Qæ€êO“Ê—–% W¿Ùp5â Ä¢Ž%6™?¾|>F„òxÂ}³ÙL§Ó9aªáõz'&&’ɤÇãñz½XLÛívÔ;hm›Í&µÍD,;<<DM™C!ùCb‚„#~ß–˜¥–ó"¯­ê¶"תº°‰EưA^í¼šX/¦­6%çm#¾ÌÆâKí4;€¶€Ù¶°YFl÷îÝÓÿR¥’9—ŠßÒ¼£ƒ¥ßOh&wræÔ¡ž@lA€±f1âÇ ÙB^óG?úheI?W®\þŸÍf™‰ƒ½£Z‡ìC.Œ@u<Œ9i½^{'n4ȈøOŸ>¥¤"¾Ã!‡5È ”®Pyù,–«Õ*Sš—ËÕl6Ÿþy`ì Çѽ`æ»»» ÀC\?™± 1À™ºŒåï+râ0õ I;«Õ:444<< “ÐÎÎÎÝÝ]£ÑøÃþ)³˜è˜öôô0eÂú)è¯Ü´;;; ËßyçJ¥Â„êîÝ»³³³¸¤ýô§?ELE„§Ó‰BC8~ýõ×Y‡Ph‹q¿¾‰êg6›Ç㔽˜óð3gŒãNOOGGGY´Z­‘‘Ž|6›e–Ïçñù1™LìQP[©L&sppð‹_ü" â7‡…Dt›ÍÖßßo6›ñð`oD-ÌeÀÛ §ÓéŸÿüçW®\1™LÓÓÓÈÓ2fA¡–:ß‚ŽÊ::„fwûûû$†‘‘‘@ �Ò¤5c@öÂwÙÝÝEè/VP8"pi™Íf¶ÍXÌÒñða†‡‡!L€Çc©€km»®´ýýý££#›ÍF{‡ÆW,Ø ™sâMD‹–L&SžJ¥X? ÄŒR¯ßï„úÆoœœœ,..ÊR]L^»vé¿,$( @_5Mãr½yóæÕ«W‰6ªÚ´lIÕ=L– šQ‡ü‘݃„, FŸH¨¾WÑ®KKKW¯^ýjn_‰¤˜Š}„Þ’AÓæœg–Ý–A­yÁ¶«|qnÐçÏóR½,°dª-ä8Q¼â¿ÀÒ€á^’^é6êr5wwwÞÀ9'‘HˆÜíÛ·I9�P½‚^Çø å iÒ¡#Hß�¥�µ†££#Qg£ÉÀàIÅãÇ©úF#Në4ìqétzbb‚ÉïÑÑQ.—cwªaÅÀÀ�WêL,B Œ•àF‘3D‚ãÃî´>ÈE¡ 3á n·›>88øàÁ–4¬To,)«™ðàÐÀ>0™L ø¡ÎhfЋ°@[BŒ˜Ðä‰Ñh”„‡=O__ßÓ§O‹Åb,sÅ4þW±XdKva__/Ã`0ˆJpLoø ¯L}ººº:;; ÁŠá$m[Y8±ƒa†Æþvccãððg“Éo R»f¡|Z:?Te$èñx„°-ÐÕ`0GÃ"¼”!{–J%ôÁ:::FFF8þ¼2ÌpÖÑV«•æ! t0äE¥‘¦“‘(�¼im2™†‡‡YäðíØ<q?yò„Õ+™V«%Ü£ÑO0P�*䀨õÚz:NÀ‡2ðT$1G.Bæj¢üW=y˜™Ãê.´^'Bo`#¿× ü‘ÏÔ·nëßpžƒºgÕOe¾&*I¥§©|fõ÷ªÙ²>¤!¾©‹uÍkªªê J–¾uë¢êú~åùçŸ÷ûý  À2 ®iii Õ~yÓ7np†…¨ŸM `i#ìv{?d}Ît¹\Y$Va0ÂZ­ô¢þþ~‡Ã±··799ÉÌk-·ÛýÖ[oÁؤ?<<„ \¡V«´ ª¯ H ¸²¢t$TgˆH/0R綤<§–‡bMaEž`×]¯×©Ýð|f²„*'Ÿy¤å01¦³!4›Íjµ*B°@§ö÷÷a´nnn2aVËð=›Íz<†lÇÇÇn·û7¿ù 7�ü¬jµ‡ÑýçüvwwÙ‚!pL§Ó ¢†É› ‰9e¼×äääßýÝßáòN§?T‚‘Ãá¸téëb2ðv V«5Ž žùããã½½=p™“ÐXpÜhœNg¡P€¥e4÷ööÈ^ÿ÷?;;Kc!”PÍQÀ [z,Œ¬V+Ô66Oår9•Jùý~ƒÁP(PÆFÁRËÄÄ_öððhœ2.0Š8ö[[[SSS0œ¹®.]º„OÚggg¬ iI6°£é˜UÏpÀÁô¬ggg¬R˜Ýa¢ÝaÁÆ‚ñi†+‡>Î69r-dCØÔÀá éüøÇ?†³¿¿Ï½ N KÔ§¦¦^xá‘2äÒ/øGl]:”µè&Vq(ôò`Æ©Ý�±…2_eûj ŠÕÔÀ,Uš[[¢5j}zn‰t×�� �IDATn²Þé~eÏg}æi«wÔö÷m=ðÚblÛ>Ws’?=–|®¡8ˆÑ[I­Ô’9P7Ûò�UQ5 µoÑØíÛ·ªbÃhqÄ$P6R¹<}ú”[Îl6ÏÌÌ4›MQ†ñz½8/nll�­±X,Á`Á+aïF0$…B-ŠÞÞ^Ð ÝÝÝ£££D"àBPb’Μ§3ß�ÀE¶³³“1:Á‹›_lDa2ÃW d«hêÙÇ õ,‘Hð.PÒÄì¹çž£ó4À!< o±3!¯Œ¿‘çTq;o½õV,㛆€+°DÖhÖÖÖ(Õy/v  x$C$>Å&ŠÖØINOO7›Í¹¹9¤Ÿž={&êÈ;ÓÔj5¨¬.·X[[£âÞÞÞ¶X, ²Ü47¬FX 3»'Â"A@Á™ÊÆemm-™LR£$“I4®Å¾‚£×××755õÞ{ï1ÃDôÔét6 hz¤ÃjµÊEÅA†üavv–ƒpéÒ%*z¯ûûûøÃ¶··…¡ ¦$¡@ÁbŸ•í5¥lJ¥B*»kX{Bäóð‚Ì”äÓF0#}üøñÇi/dá‡$—Ùl>88ÀPåˆ5ÂGÐ šÍ¦ø7h€6Òº NehÉþYÌ¢Y-È,”îV–TÚVÛ9‡QÉc(¥ÁjŠ•Ÿ\…ú2»á/¶öüsý9Ï;AÔ©ôhª ö$’„Ê¡&Uè\} ùC\¼“˜•ªYA¤ÙØŸ™™Y^^-åÿââ" ÈjµšN§{zz(îÐóù|Éd’B E0äÕ(™‰PìNå}¹‘ ÂAG °2 eɉYf6›EM —pµ¨¹˜2Q¯¹Ýnj4YÌöõõ‘T(E©Ý*• “+ê/xÔ€¦§LF6Žd#†b¤«Z­F4BµZõx<Lö¥žu8ßûÞ÷ž={cnqq‘iS;¦"ÄhâÝÌÌLooïÊÊ ¿‡ lø0ÈíÅb±ÞÞÞP(üØëÌÌ ]·k(’R¢Ùññ1ѶV«Q®2ÙÀgee……*®Îð§8’¬X`P§R)†3X.Óß�™erØI–Ï8‚éCiªlXfÌ: Ž1ô:‰ŸÅ$НC2s8xA²Ã€ƒ+¾À–Ho¤Rdµ¸tív;Š$*˜™L¦³³S0¯¼ ¤VêõúÞÞ^gg'@¬#(›hžø%×Õ†åÉOP2 …î4 d ®j‹ÅÕá ‹ÅrùòeÔA@¦ Q0?!)‰Ë\*Ô‹r.(5ÄËS6<qaaáþýû\{LÎù½H쩸y~/«i̬4Ž2zÍ»ó¢¶XJh¶m‡ö*IBÜn¾Zb¸x‹}ÁÕSTúú u/ñZ?/»˜Á òjšIœú±rU{µƒa¤(àbõP‚%à¤Þ¾}› ó.5IÑèQ7>ú !n‘¼;ìJV�ŠøCCCâ;F d"„lºà^êõúÐÐÊ\ôé,Qvqï1Ka™Émè2óñ|>ç Ó!tR¢râ{zz€<¡P<Ñðð0Å&£ †iˆ‘1\â‰Ô¤„!Qü–€žJ¥Ž³ƒVRÏ‚äf:à˜ˆ>ÑZqϳû‘;S•(�Æ)#X-^µZm~~žp¼ºº*bápr|+Š}v'h‘B挣Ç088V2nll ÅQ.—-#еGíjEÇÃg†KA2ðûýÕjfŒ¼]*•śЌm²ƒ+DÕÃÃC·Û}éÒ%´x …(�à¶"vtrr211J•ƒãìòåË M¤Á¬dnF߉ôt6r 5Ì×H­V+—˱ƒaZ…T*~AL“xY¨3,ç€e‹N  õ—îînrÛÖÖ•¯Æƒ×R½^Gy3Wµ|$wªòÌï¾û.7;Ó6P ……T2càÚmž"3 µ¨×D0ÍD—žê¬‰ø_Õ§ íŽ¡-õúëï.€$i ªØ™Ê¦^]—«ã³?üP,Ü?Í>C]¯«X#Ó)Æ;š9š:ËS!OªG´ßï—�éQ>¼(°^¹r…Í­JS\ZZúàƒ`H2sY188ˆC2T�Ö}årù›ßüf³Ù¼uëV¡P`²?<<LŒîììüãÿèv»].W¥RAÝšf¹»»»X,vuuI×O ¶ÙlâÒÃŽÂ6Nà 43‹à“ðfµc;;;©þ@FÇ…É>ŠoQ–‰-\hXÖLŸªäóyžN×Bç„w ýÊÿþïÿZ, y@ÂÀo@¤R©D£Ñ™™™Ï>ûìÖ­[HRonnºÝn‡ÃñÃþèJûûûN§“©T&“!hÒþ;Îr¹<66†š! ÌîÎÎoMÝÜܼuëEîÐÐËåjµZOž<ÙÙÙA|°§§Þ o òu¬sssW¯^eòžN§Çðð0ðJÐVäcqž¹~ýº€MI¥HÚíïﳑF¸—Žá?øÁ7ŽŽŽ²Ù,[VâCxà[[[dq\`9AÝÝÝ###„l0šì 0MC+žuz'À @¹\.ô"«ÕêÁÁ`S“ÉD7\©T†Œ_x G\ÐþðÇC«GM€^“ÃáÀǰX,Úív0Öb…›*„J.u”néZ@IJ÷‚z» W� .—kxx1`‘~òz½ûûûh¬¢µŒk½ÙlþÉO~rëÖ-ðl‹‹‹ÓÓÓ˜s0}êîîFo•8CÈËÒ0’|·nÝJ¥R÷îÝÓ`–4`$5H»dU àI k*¾H³å5aËIÝÝjÀ™ªáüüõw Ûyʨ^¯«“"µ9ÒOŠhÓô¼}[ Ù¤«[ Õè®-¸XE@©jG†Òº 'лmhÚJñ˜ŸŸÏår0ƒPÙœŸŸ9ÎX“[….\9Ú>W¯^¥Ös8,f‰ís£Ñ`² ᙊ P’v´L6úúúÊåòøø8…u(±Éápˆ �å•&Fct9ˆíÀ<�r||ìóùÒéôîî.RÏ SÜÒB@Ct“U!µ««kooopp¥ŠÎÎN¤ŠÿÜBå+£yÐôôU,]à6§R)�!ñx|~~ÓJš Q©N&›†ùùyf5›››œA&0T‹„{FL *Fã[o½€"hP6›e–£ªV«•J%"ãÇ“Éä/ùË`0ˆ±(½E.—ß%Xd2¹¹¹É$ŠŠ7'Œð·`$ø_ÿõ_ƒƒƒÒ.//“T¤Óª×ësssår~>~Œ°`Ÿ0lÎd4‘zíëë#‘ ó ÒT˜m€deóÄÕÂåGáŸÉdÈ.¼#5è~(©LNN"ù ÇÇÇf³Ùjµò �@ñ2>©´ãsÃsé1½Dô…5»œ€ye…�Š<+³V'ˆmÊsº´X, …€ q•b‚€>’Šc¤yU‘HÝ tUÄqAºóô ôžÅç…J ¶ú`¥>ž ÇyÆ _¿c8¯od¨.ÓEYˆ…¾,åUÉnQ²U…’4þ êò7_Ôq%åjl$4 „ú^�“§ÌÇÐcæ¼PjæšøàƒnÞ¼ÙÝݽ´´4==YàgŸ}†tÁààà /¼@Ü××*†«&D"‘˜˜˜€ ÌòM´óˆ¿rÃÈ�Ê9 +lZozƒPbÖŒ¨�º`Ì766œN'¶ŒJ è!ÎÎÎPgcâŒ{Ã`0°¨„èÀê‚Å)ðAƒÁ0>>./ÍÂ`0ЋEjÒr¹ ]#‰F£N§ó?øÁ_ÿõ_ †D"ñÒK/ ¤Xcr{,..^¿~]æN¨ê#=‚˜Òää$ø*;«ÕšL&A.‘)€¨Áü@ІŒ…Jðh>ŸÏd2ápØf³ííí1øfÞM£“N§Ëå24è0´ÑÑzOjÏd2N§éríÇŸNôÇ?þñw¿û]{ìvûõëבˆ§RöûýtÑh”5†ÕjiÆðÂÇÐÐÅ/hf ‚˜ððùwwwGGGS©Ôáá¡ËåÊd2ÌÍèq™ªU*«Õ üA?ôˆ¼ †E‹}r©(#€\3Îbà “F[ ÀS0¬===T$€slàh”yYôE¸w¸ÈÙóAeß&*÷[[[�‡�³Qò ¤°¢Ø¬Š¹ Â\¡P"Ô•+W„IÀ-©F9 GA"§^DN£,§‰cun= HOù’X¯‰œX 둜__vû<Â^sâkf\Ìçþ’z_ø,½ò­>{Ÿg>ªÖÒëhÄ”(BÅ Š¡³8yår¹………÷ßÿûßÿþêê*Ë ‘SfI€F…ÛíN§ÓS¢NÁ¤Õb±p $zRïÓ7 —txxX(àŽ‹E2 U« Ñh …�â…ÛÉétÒþ3h4"®p||̈€HÑÓÓC8�LBF$bJ�lW®8 wvvnmm‰)_ÿEâ"°WkI±lëP\<;F– ‚!¡L+GuGÍøˆßƒAñê‹ÏÌÌ`«I¾$ÜCïAˆ·Þzkuu•'ʶ ãq8ªÚý"JàXT²Üf AdÙÀ‡—…>kww7¹ˆwáÛÜÜœ™™Þ(Ú¼8s<&K`F) h[= 5dQ’É$‚&?3ÈjµZÅb‘‘×éé)sBf†œ/РhÇuHòcO@‰#ØhÄäi ñ�ˆÝ\Ì@¿hðáÈÍ|`³ÙœH$ø¨â ‡£ªb±¸½½}ùòå§OŸ¢"è"Þ.v°råˆÞÑy!A\†¤òÔp¡—Ån«¤×½ÐHv_,M¤®ÚÚy ÌGóšò€¯&‰¡‰›z¹¶JL_˜ÚÔ}¡‡n¥¶{SÀ5C$½lŸÆ:TøŠâá#ÏÂK’q™tmB¼b‡úXGGÇÚÚÚÔÔ…÷ä;w‰r@ s½‚Øc¾Dn ÁG^ª»hÖÁÁÿQ#Øg ô!TÓv)¸?”À§’ˆÓJ>ÇÇÇìô(ráÖ"*ÀmÉ„W¬â°ëËÈ€‹Ò¬R©<{öŒ ù1@B•:¬ÀÑ`rrxxH�Å“D"À•••|>Ï Èd2Ñõ¿÷Þ{÷ï߇ƈoaa’;Îc xôèçKRÎìn"]6›…VÍA[]]¥Ðf|¦€Ñ¢â`,#²••Tù@4ƒAÈHR‡B!Ö¿ÀÛ › Úív8høýþH$ü& ÕjµGñ^ !QÅ@‘—œÍ¢BÔ·h‚ m%ÌvêzZ¨H$ÒÓÓÞLäü0´Ùl¹\Ž©×ëõŠø¿ááa›ÍJQ¼b±ÈžæèèˆÎ¸ÙlãõÅ K;ü ù™ƒ‰ �mOOO:ÆÎ„¦¾E‰ú�Ààæ"Þ·GM j7¸Ê®U£ªüCqÖ p@Äm^#‹­ÙȶTküôbGš¾@ðõñVû;˜ô•Eô¾FqÁŸWÑ«’g˯ž×Žè{¾dªkû²š×”Z@ŸíåBÝ.°§ [šÍæää$êuüž¢Ïï÷#ç"RÃ8 ƒ<#Z"ãôô´ÌaAs—J¥ÑÑQ„7ä¶g  >9™h’«ãžžìÌØÈ‰hÅüLÁÛùùŠG2 “Tç¨é€¨‚©¥Bdz†´ ÷?ò Däp8LË" ƒxÊ«= ­•á………÷Þ{ïÑ£G¸¿ñËx<Ž„*à.±¡Û^Ò6O‘ÄàP( g¶ˆäžW^y¥X,JËf³âbO”&6Mâ$÷$¾=¼¾( oll {ÎߢpGG†¾e2F­tPA3séN¨ÜEd© ý<{"‹ÅBÄçeÙIÈn�‘àíímÐÀ%€E0ÄCtodd„Æ‚ ÖÐÐP¡PàðR=”Ëe’q£Ñ°Ùl؂ҰÒ(è±éëë£yåøîŒŒ ²•xކpøYY£�he{P×|æÁÁÁǃA˜ T tœj» ×Z˜¶µöj;{àDó‚mCŸúR’34"K_uÜr4œ^8NU”Oõ¯ÿú¯£žó>®^Ôºm×£y.ŸOM[ºœZòŸÜ5_^/0¢'…ËÃ.8ú"¢§ßÀ 4z â>ªjˆ‘qÏSü±'X<xð�P [JT© ®á6¶X,ø“P•S­#>!BI”®@e�ᦀX¨ô ¡,ñaØRÒFPˆÉ^šP!€`!l8\нA¸‰th0`ù_À®P §Ói`©»»»â9A…ˆf±ãòåËà”˜ø3PZ\\Äñxnnnaaá—¿ü¥dÍx<.½E2™$+°0D—›z Xáýû÷Õ:QÔ#¤ñÇã©T Æ «l!!cÔÜjµÈ ¹\Ž’ ,û$!©ÌÌÌHƒ"T)¾{Ñ‘‘ÌxÁŽoíñx¦¦¦Ìf3ŽÇB4ëîîN&“�ŠDe6™LnllåÖN2ü�ŽL"‘èííÝÞÞFöÃçó¡{x||FÃÀ7¢\.S׋÷™ EGGGéc�tttŒËÇp:ä'’ø0SyPR`Ó„:ÒLÐæÙWc^fA|–ßÒÝ-í¯´¹lé­Vk__ÊIJáE`É j ŸÏ?zôˆŸ6ú‚àÑ™,I^—J_Mšº[3ˆóóó°Ú.{%©¨!ÜüÅsUiCUÜ“d£Fýb\¿mV‰½úè×ù%ÓÀ×`6È„Gó°óhÏš¶å¼¦]R_AΟÄŒ¤ ¸j¦oÁ„Ï¢Q&Q/,ì'&&€ñ‰Æ=�’z½.Soñ*Á+ð8"H‡#ˆ-;Z1´ÉHZ‚Ÿ‘u\ßçð™6–ŒwÑè†7Ä>î#=>÷³¬ì€£•²Ù,â¯$ƒÁ€õ#‹Y1:::òx<âBÁoŒF#ì$§0íÂ:;‰0"‡,M«D#‹˜©‹ÇãA~ÃÊÊÊúúº¨pËR‡vŽ!žxM·ÎÀgii‰1 l,øÿ¶GŒe$ #Ÿ$ ›f÷ð×äò`ñNú1›Í26”—òù|bÒ‡7û|Øòœ}DJ¨¦‡††?~Œ ùíímx׬ˆ¨0�21‹g¸ÔÓÓÃÏ�۲̑Åfùàà`oo¯¿¿bb‚ɤlY ô‰q,ÂàT Dj8í|5 ¼dMr9¦Óé¤È€€ Þ y ZÉ“““b±X«Õxßjµ 7RZè ƒd!¢­Ô+\¢Ð?¡ÓÓH[¥j±X\.„»ÝžJ¥XãÁÏçI¥PÕ + · u^‰Wv»}yyYtëà< 9Ž €ÚÂÊÊŠªÈ 2ÑTU"MŸ!¬æ¶ˆJ åK8ÕçÁ&ÕÐ/S³P£Ÿžý¥PIz$ÒÅ%ɪ]Uë£íãUñTý_™¼5ꃪ<ªा‚€¦@I©š…*¨IU+”wä½4²ˆ7nܸvíž<Õj5`z%`ÿL&YÁápüË¿ü˵k×XÃöôôx½^T% CµZµÙl‰D‚yîèè(Öƒ  ¤V‚pÔh4@OšL¦B¡ÀFr‚»�ŒÐ,E.4xÎà'ö¢”ç šYNÀp6™L6›LÀ(�MæQì*Ù%ðO`$⊷QoŸ';ÃÑÑQÀH¹\î›ßüæîî.nõ¼/xYƒÁðæ›o^¿~€ÛíüùÏþÆoX,ìl2çææ€‡Q’#ù †ÃĈ`0899‰½]&“Á#è{ßûÖÜ`xˆÝÒœ Ó”@ €@‹î¬H9Y,–wÞyçÖ­[xw£,„øösÉdÒ8¬ïl6‹!M=6:étšOrttäp8Z­ª>^¯÷ã?¦ FU(|>ßèè(kXÇÃ’œr¡\.þyúô©Íf«T*™L¦Ùl®¯¯ƒu:7nÜxã7˜,ßÁ.<ʇ«eooohh¨»»›…t…°Ã¿Ô:ü@ÍÁJ˜)ÿD‚ Q??�¨#ï2É, l ¼±i bþyvvl $ÚSÀXK¥ÒÐÐÐÙÙY:†/Bm„r×?üÃ?|ðÁׯ_?>>~á…._¾|íÚµ`0xýúuàj¡PÉäú§"&(¸¿WÂCP%¦¡ŒtåÊ•ÅÅEÄ‹j ×àŽˆi*= L&€IM|“°&"¯"FwA–—'Êÿò!åu4¨¤/•ôÙšÊMÓ$=M¸oû46*ÿTó ¿‘ƒ®·Uypäë{pf"9»´´$‡I=[bùyóæÍ{÷îi> ü—“““©©)¨°Ÿ}öÙÑÑ"q0BS©µÕôô´Óé¼{÷îµkלN'HÊsÊUJf¦ÆôÎàA¶P1ñx<)¹QÑfR Ïèìì¬T*êdÉæ€¦oHî"|áÙývwwÛl6»ôìÜÛ”‚­DŽ.›ŒZ­m,ï [Šh¥RAØ€8¸<‘H† ôA{>99!_ÂGÕcvv€)S”žžž¿ýÛ¿Ûñ‚™2¾ÕjL=`ùF£~mm–kŸÑÝO©TbiY*•~ýë_ˆAs¹\ýýýdkCN§ÓéìììÄk¡³³Óétîìì¸Ýî?þñW®\A ŠÐ ‘–ÓDlÀŠˆH[Éd²Õjýú׿îîî~úô©Pd8ã\ ÜAj&‰­­-t2R©”X÷lll@´&Cóù±�ëèèxíµ×(5~ûÛßRšP‚Ài7›Í,�²ÙìÈÈH"‘@Ê›Ä)•‰™•Ÿ“3’ÉdNOO …B*•Bè› éøø8“ÉðI¨÷™•Á¶¤‹!s!d`X`p³i`žÉ‰D{zzZ«Õr¹C-šcÙÌ1 L$×®]{óÍ7‘:þçþç›7oÿìg?#"qÀïÞ½+‘íùçŸO½ÈJÖccc7n܈F£¯@¾Je¬ÒâÔ�Èï5I>)v¥f+e•ã¦BùÕZ¥ô¶­ïåõÏ#¸}ýåóyË=JEˆªÝ‹}Ù4@.ý³4rÜ8Zè—9mIäê H#« ‚Ï:tb§Î¤p¤ÝnÇ­LÀ”f³ynnŽ×ÄÄD4…ÜD„ ¡óo}ë[À-D ’ÈàÐÐÝ=¸*/‚z–ýýý•JyKQ$îûC¸· °}Râv-‹ôŒ­0…FU bOæ+ GWWW¡P ±NGOO ³ïÙ³g2Ïaë‹îdLÌúÒ™,™Á„°Ïsûöm:w† Gc±˜àeK$€°€®Œ³×ë½yóæêê*BÍüÀ,›eþûï¿õêÕt:=??ÏÀ—Nñþýû¿üå/Óé´öÀE'ë`ËÁÆ­lM@h v-,,¼û£µµ5læÀìºÝn”°Àk6›ˆòí˜z0…Ã+y:/B½BaÎŽoA‹Å‚ìS¹\öù|BÌæFãèè(rX �; =\ ÀDš3Ž5,iJv___"‘ØÞÞ~ñÅA6 ·Û½··ÒÔív3¢v"àpä9@M|`Ю6›Ï®o||œy` \‘Àb¥ c¦‹ Ç 0L7ÕoX¢@‡h WÚyDݶ°"ý@©ãBß̶û€åååóLϤݑð{Þf[Wý‚ŽAß\s5ü5ézÔê^•šÐknkFIdláʩϒ©Ž$ýKAWm²á°ÈGM×jV_^^žžžæ—2ûøãWVVd]I°Ç1ócêõzñXöûýðN¶¼yó&ÆÝÝÝ.— Ž4x (lÌj©d¹pVÐ&3p�KJYÊЖ(O«A—Í4�zU3)ñð¸gšÄÜ\�¬D²˜TzŠA¦dbâFQ)¦(wl;{{{Áb’¢Hl6› ÖB«Õ¢¶µX,Fc÷V«`_b¾Q±Xt»ÝL~hGpEå2—xýõ×ÙdŒô2 6›íÛßþvOOÛíFmª“ú½P(Àà#�5::Š®õ«¯¾Z.— …ÂóÏ?ïv»Åæ…iF§ƒƒƒ¯½öEqÿäää믿þ›ßüŠ8üw¿ûŽGGGŸ|òÉÈÈ]&œ,ÚDèÇÅb‘ÞÍ›7OOO÷ööƒK�wÁÈ ƒ™L] ·Ûíõz Ëä®®®íííññq„¦¹öÈ÷X'uwwW*‹Ådz6F‚Ô˜ppí±G£—}Í3™ÎÎÎýý}ˆ{µZ šýÈÈý+˜¡GàåW«Õ°œ¢K ñÈ‹YÀTé@9»€]Hña0à:Pë †Á‚+úãF£¯±)VŒžÞ|óÍ;wî {q÷îÝoûÛl¤xŒÓé¤e!U#5þ›o¾9??ãÆ \}>üðCâ’ªç/¡O?ü`D¡ù/ñ`ЭW°án=?í QúÑDlÚ(i,ÎäŸ_M£mÊ:OÉî<ÉŠ9ª^¾[µ»S7$Â38A.â󰪘Ð[äÁ4V_Spš ???o·Û,¼#—ˆ×œ�� �IDAT”FËh4ú|¾V«…è¶ìñx\4s°…I&“‰D"™LЇ°È Åb±D"qzzJcÁ ¹q Yn3¢9Ptt yì‡ÈíĶ™(vv†–½È@2›Í Ð úä§b±H«Â¡·‘‘¢XµZå[œÁ„ m�sdºÆœÂø¦Ïç£b·ÛËår¥Ra–Ýjµ({{{±;6›Í¡PÈl6çóy´¬9þX9ŠIg2™¬ÕjЯ(“©ÊkµZ<§>•âÑh4⤉D¨ÊÉ=MÊå2¢Íäo21gŸGÞÿHé�‰D(kÄ…‡B5½=„ ¤dÉ) )¨ïù|~ccƒµ9ïµ½½+Ku¾þÉÉI*•2ápxhhˆàŽ×*…Ø|2óñz½dnŸÏGÖD/=×FããÇK¥R(r¹\d ¦aû\ÛtˆÑþÒžrâÈ Íf3›Í²ha¥ñäÉ–[�Â3çÚcÄÕÎEÈ%mƒ … 0~r6ŽŽh7QuŒF£<èëëóûýï½÷­žßï‡ÝFÅ-§raaÁï÷¿ôÒKrå‹G4mÁ;w¼^/݃ÚU¨bÚë0ÍNXU R•õ4ª«zÞ˜FaHuÚ¹�)ªû¹X\ï+õœ·sVµ¢Î{.Ë}”Ú_¾˜ú"¤AYÈèß]M¼¤SÙð,ð†àVe…põêÕk×®ñhxµ¤e‘—eõÄø˜e);+T1¤À—¦Á>Lp«ñxÜjµRÝ€B¡xg[ $‘Ò’Â|ÂTÄdÆÇòK^¹6e„nBÄã¸Çh¨(q tÄ”®2-<kn?©úéZ¨™#a™R­V™AŽeC—� ˆ6…= ib ÅÒÁÛÇív¿öÚkÀ™(´Ífó“'OÂá0…?ÒRlwvvv@4±Î” ¶T*•B¥ ™Ýng°þÎ;ïüÛ¿ýÛ믿îr¹Øg¢DF aÙûäÉ“‘‘¤xØÉ7›Íííml×ü~?<ú*F…Bïø’ÆÝ*„°p÷䤼ùæ›V«5“É0Ð@éÏï÷3ôûí·R©Ôää$⃌Խ^/y9Šr¹ €J(î¬ÙÖ.À3úËááaü_>ûì3¯×[,Ng__ßÎÎŽÍf£1 P:(ùéÿ ÑÑÓ@Ä;°× WAÖqaïììðKDÙ«ÑëÐVÂz£”¡Ïfa .o$²û'é§Y\Áð/‹Ïž=ëëëûä“Ohª&''Á"ïííÑF£Ñ[·nÅãq\¿^}õU.’+W® gÂÍÒÓÓsõêU¢öµk×XRf21Ô”¿ÏÂÈAJr±k[°«^›mÑÔæCÔ !ÙòÊ&U³÷åƒiÖ**çO5êi›ÊÔ|uê–¹ŠøT‘£jæÔ ̶••l¤iS(Í–——ɽªÐ·&te!0«ÀVŠ5Õv–ľ°° Œw …BÁ`paa-€}) Íf³Ùlöù|‘H$  |- Õz«Õ¢dFF‰Nœ‘óî¼(À`œ`4™É2HåÖb¹‡ l#ѨàíØŽ¢ªär¹ˆËh0°±ÎRšI Ÿ‡M Q@@ŠŒ’ÁΓKøü,¥¯A&kâ122‚~‚{—ùÁÁAú*»ÝÝÄ‹ôßùÎwp `¡êñx=zÔ××733ƒlN©T ‡Ã �"¦1oÚl6Ãá0Ã襥%`²=*•J`óaó²…B@9ц‡%Ö¤üÍ·ãDð!™V©Ô¶x<ÎW _aÌ”•…ÙÙY¹l (0ÑFdÛh4‚Zf J¥6779ÌÊA!œe¬f_øàƒñ….³½½Í ÷êÕ«årÙáptuuq D"fô\‡()q9‰“ (2fA°á8ðf0 ù`0Àl6ƒAhð`pÙ<ãËÉ"îƒ@iƒ.„ës}}-&Xèl×ЃaJÉ2Œã¹±±AÆÎ‰îŸæ€ �BûçÀÅŠÔŠ´ à§õÓµ–—‘ƒ„51 Ug$jxÑ8öèÇ6BÖаÕDÝ(¨!Tµ×,-ôMÃW¶ö¼X…›˜«:wª;Ñœâ‘úQ?///—Ëe5Cvè|ïîܹÈG#cË» ««q“<i·ÛÅÎ[€É*ºI: ñõ¼wïcÇÎÎNú õ�h³éêëëûÁ~�È!TN»ººŠÅ"³Ñ_|=°@4Â8¯1/Ba¸ÕjY­VJ!T(XâÑ@0!±G +–Ÿ´Õ½Ñ‚À9à¶dþ˼ˆtÂÝH7CšáÁTL„ŒhAˆ`a™JQ "pÍL gv¶È]§öÈDªÝÒ<±µ®Õj�s1¦g¤–Éd`ð1('ZQºÝîf³ùÎ;ï\¹r…)¨váLÑç †'Ož qrr’ÉdnÞ¼ét:·¶¶ü~?U-í'ˆ1ÉœþÎÎNWWW4E<™LvvvRz‹3Ï-‹===ñxùÛD"ñ½ï}ÿEgõx<Ζ‚óÂÝNUûäÉ 2 ¶`‡d2R>¶KœJ0„{ø†Ïž=cö=>>N“D±ßßß¿··××׋ÅàO Ä +• ë1 Ž¿ø‹¿ ZgRÏ%¸�|›™.—æ^à{á©�톄Çã¡$b@3 Õåra_!Æé€£ø´,¸f¸6h²i€Àp ß›íyâèèhww—M‰×ëÝÙÙ!�|õÕW™2ìïïçÈP½!ìèõzÁøqJb ¢™”ÈâS¢ÄbÀ¬¢Ó§ªj³WÎ@ø¨"Û"ð'FÅš1>[X Ü_`úú�®¶,¯¼òÊ×ïÚN£ôÉMpDšØªÚêqAÒ@›4“5XšE?¿QunõZxê £úª#‡Ì© DØDê 1„±5RÕ¢QÃ̽»»{jjŠêq:›Íöo|ƒà޾?0¶Ð (ÄȱŒÛíæö`n‹„²ø&’KÀt—Ëå\.ÇXœ Ž^xÍšŽªŒª1Q¹Ó¼åÙ7¢.„1:>·æVïêêÂ] !~ ü;LíÆ‘>'þÆ”–‰D‚0$R"±XŒÐÌ¡3ŠæA©TœššÂ1‘„äo Ø0l×°ëâP%8 P±fffÌf3;n3ìÒy÷©©©®®®_|ÑëõŠáh"‘àŒð0Žd½^÷ù|~¿ßáp úý~®y5.§ÙÙY´Wù¾BBï:[>Ÿ‡ {€TG‹À²*pU ¹JÁáõz½^o8~úô)D")% u=á• `ccãðð&?X^ ˜RŒ±Èår8ƒR0Ìa§%2À 3}>?¸\.9>ÐeØrqÖáÆ‡N—Ù;gB?ɘÎ,dT ı•ž‰ÛS¶8âÜ)°Iñòã×ÖÖPÁb™Á³677%@1TЄ ,"ޤ‰ê¢Tý/ýF–AeMUŒ(ƒ™¶D㋾ZbP[½%éyzšCv±ô‡Ð¸Õ%LÛ}‹:}Òý ÓˆX¨œo9Oò\˜«ŸûÿÁ§å(ËèŒoÇ+,,,pW3ý‡ÿÉÔ‚!,`|”«=Ä¢³L]|>±†QïÈÈ1‹ñE¥Rašþ0b×bSsÁ~@_ŒB[ð©TèJÒAA˜AÒ:€Aâæ$oÉ4th%‘ÒC$ŽæH¼J,ºq&€»ÀXŒm úbáÀXŸDÅ& ¡a:–Ün·W*T¦9A`ÈhCqle8ƒ¥(Q€‹ñ×µ63qòz,ã3ôõõÁ*'möð2¢>·ÛÍ‹H—àñx666€–ò}ô’º”2Ÿ¡à@Däž(•(Mm‘H„&23ð\\íðÒØÝÝ¥ @åûðð°ÑhLLL�å"ÁàaÀ’‰’_ÔŸ˜Õ°›ÁჯCÜ—SÉgP<‹ Hƒš}¢”sʲ: ,E [d(#8dPUHè,é}±ß¼ƒèK€œ’ê�8ˆë*¹Ó ¥Yb…€Ña/‹‡|(b¾Çj$%ˆHÆåÏÒÒ£f5 «ìbUCÀ?Ũ¹­j…<¾íD]Õ ÕÄI)põWƒûÿš’mA>zñ ½óœDyýþ༚~½~Þ>]=òú`I;.´•Ö¼‹ÆÅ[}#nH`K¢#¯&ߎœ±¼¼,×=Uq³R©MœN'š0à%hßs3üþ÷¿çÎçóÏž=YÈü„Ö¨%fë0†Hl D„2—Ë8D0ùää¤P(€_bmÈL9Æìˆ&w!ñõ€$Ò@0êaÌÂo¶DÐg£P­VQ!j ÌaµZ!!óÜf³É4ƒŽJ,À;ñõù­V+ a4O1Kaˆú'àÎÎÎ2Ëßcº+*GN\ �×?33sçÎ`0Hj…B©TŠ®îÁƒ¼N<Ïår¬IéöXÀ0Ó~¢´ŒƒƒƒðªÕ*™XŸÏwÏï÷Ó1ÌÏÏ#à1??/úbé,¾óRö4¢ÀçбñûýŒéÙ¯¢(ÇÅR©T¥RÙÝÝ¥u£!í‰n`0ôù|Œzº?ÿ²™±[__ëpYา`Mgþ=N“3ý y˜ƒ1DbìÆõ\IvT”Af³V —4çàà žnd#dWòùük¯½f±Xs¹O™ŸŸ¤ë’>¬ÙlF"G¥#"8C‚ÅÅE“ɤ>1‰ ·(“†@ŠzÙJ ÊHï詆¬ †1˜ù´í0Ô*ù<P“/Î _aÇp1âH/Y¡bŠdI —»8Ç¡nTÚ·êMÑÖÝâW¿úà"y‹ AIšQùÒ<…™`‡b)Êšazzš½³Z‘ÓW?Ö*áp¸»»û›ßüf£Ñðù|Ü'''¬ò(ʸ ý@¼ zj€è@°ôƒÃ G—@É^Ø »ål6 ¬›õS&Þ¹ Ê[Fá²Æ(‹â¬)£^Úv¾&K pG dPÕf ô…#Ï%ó1Ò[ÁÂÅC©‰‰éìì ß6ÑhÛ8YZbÑ¡¯¯ï³Ï>ƒ~->  å©@iˆ26› ÃTr¾˜===t`ÍfskkËh4¢är¹l6[¡PÀm›Œ‹_ÐÌÌLOOÏãÇ/_¾Üjµ�’¥R©‘‘&™YCæïPX¬V+s’F£Q©Tó“F£‚èîÝ»\Z~¿ÿîÝ»+++è40ã¾wïÞ~ô#TUòù<‚Nù|Þf³ù|>x׬òù¼Ëå+•JTýô……B”³Á`p8{{{ocuÄõŸÍf©ÐOOOS©T €cX(À5±ª×ëÃÃÃÅb‘Ÿ¸X,’•)áÙIQOù_¯×)0ÛÝÝFÁÝA{‡�¯Õj•A%pjþæ:„D ðá»ßý®ÉdÚßßÇöµ¿¿ÿÆü FèV«ukkKøÉüW"‘888`apíÚ5vŸ?þñ‘ã[@øÕ¯~%² ýýý~ø!º88}---±¨ÐƒˆX-ÀmÖ€‚4¶flp5NY`È>C#(§¾Îòò²ªÝ ne_•¤çìéÇGmÎs˜»@U?°RÿfЯW}R‡WêãU£UUJÝCè3¹Æ³[Ó[hTïܹÃKËét&“É®®.:У£#›Ír°90;lU@šâ&E-¥ŠÖ £(Ç‹/÷?I…;î^èµÌ…¨µéåa)3Gv8”ùÔql6471—¦~g ÔÞ5Üt+Âl`ì`µZ 7€O€À2°‚fe³Ù¸ÃEZ6$/> ##‘ ìîîÆËÏtÖâñ8)„¤ ˆÍD«ÕÂl‡B^€CPÿêõúÌÌ F{„Èår``Dt“üZ‘æ£P(P§?|ø0®­­1e¢KÃ(q¼ÃáÀ%Íãñ¸Ýnx¹¢`lŒ¼WVVdx½ºº …îܹS.—á N‰~”ïéé©ÃáÀo€A.ѹ¹9Ú‹Z­Æ´]d×ÖÖX±PÅÓÁ ą̂9*z\JŒ iF«ÕªÓéäT’x °ùgˆjµZÑŒbÊ€êôôôÒ¥KôXt¢™  Ðb(÷ÃN§ÓÌQÉm¬ß ßq ßå࣑'_œ…M$á^–ÑmõJ’ßØØ WÔ¢Œ(¸ñU/–¥¥¥ååe© Ñ[Èï5ÜfuÖ¯w ¾ äª8(_^° n»9OÕô댒.è€äˆ_ u¡f3ýžDN€&"Ë+«&-j—>@…g©Ñ\#¼zçÎõuôü8zL•Âå"£*,bx|(2™L£££Ð€FãØØØÑÑr `1űyK1¤e¶Ž“å(¬§ÓÉŠl†ÄPæ æ Œ­¤qttT¯×?áO?ëhšdg¸óyšôL&ÃЉÏÃŒv ’gƒƒƒôÀ“hMЪ£i :–¹P½^gWÌȘOœÝçó‘´Z­V©T"MKçE, Ã"Ä®AFÕjµp8ÌÀ Ì¥×ë¥ÁÆŠ1\‘QˆÂ¤<V (iooo³'0™L\-f³Y| §ÙÙYÙ<çóù¿ù›¿!3‘ÿØ©f³ÙÑÑQÔ±FGG‡‡‡@$á‰|r!'TÍÍÍaÚ!¢­(E»ÝnŸÏ »Md‘ïkµšßïo6›¿úÕ¯°ÄH-q<y•>YÌ!»h‡ÃÁ Ih\Àä~N.9õzýÒ¥Kœz±î`½EŽÍêžÕ i–pt¢™L&“ŸÜn7×ÀÀ�j+ÀdYz™Íæb±È…´¿¿*p2™äAŽ‘×p1‰šùùy ¨mˬ˜ˆm¸Édb¢ ݰ®×cf9ApPg×Ä´¶zÒš�¥&™ i8¿úkÛ þ_Æ/xÌŸäÇ ‰¤úü£Ï{çUúÌÔÔ-Š yÕwÑ{9è5ªG[Ûm¶¼²&·iø¨óóóB»ÿ>í Ó`<´ÀÜHâ®S–Ì숳À-ìv;3 aPk£uA”'(»\.àÞìr¹Yh8³l$¶‹Ebz:f6 …üjp¨B} I+S©T˜Ñ1`NÀ>ƒïËk’ˆw¬ écŒC8„a…$#f1ÌaxëË@ÖLH0Éñrxxˆ C$™CŸF m>Ÿý<u:H Ãh42€"[Èr˜|/o VWÞ”a,d¥ßÿ} ôðÀÏ<~ü˜¡|ggçÈÈH½^‡MÍ&œï¨!χÃaREz8fj> “Ôøl p'>²V™FCà*{<|&&&¸Ó´M¤v®R¬X›Í&´~ÉbÌçó †±±1ºLzJX�X“×ÙÐ °y“ÜÆ<"H¬SèpÜ åáb6›“É$wY__8Š)ôøt:‡} ÖˆQw±ˆf“Gb—CX8<<¡@d…Bšµ„&žpé•ü5�ñ\kîÏÛ"´eA«ŸA}Ò[¾¤£ÚWæ1´åÝÉ:ᮃ<E¦ÿ|YBÈÄŸT=B¾!ì>ÆmE–d¡êiË/…B¡Žö˜Êñ^*þWˆ ¬%äÚ-—Ë7nÜ`®Š…o½^Ÿššbx Î’ A‡VÈ<CÌ vÉjš}&à ©ú)®™Ï0ªFÎü%«<¸¾ |@µ2G¿³R©À†‘Æ\Ðe!µ‰¾0Dð'L¢¼$sHKÄ#òÊ…B;= 3b¦1,¥Ù^²Ì@ª¯R©ììì¸\.†Ñ”Û¬%ና*,‹Óé´Ûí(›îîî‘:==]XXøÉO~‚Â(€W1 >88øÝï~wéÒ%©¾ …Âááa<‰ßÙÙér¹H¢B¡ Ù“ÃLæ²ãa.‘ÉdPåSØöÎ 88c&{LIØÌî~ò“Ÿ¼ñƘÀ¯v8õWÕÝÝ ]Y¬ä[[[£K Ís„kµÚÚÚÚää¤Á`øä“O`�KƒBýQ,‘µØÞÞv:lzÿò/ÿ¦¸²ÓÓS¶¨©SDƒycÚžÍf­V+Öß\ÆäKžÈˆä ¢ ŸZš�iµZ­X,œ¥J�üŠìÝþþ>䂹´‡‚š…GÂÕÈ×ìë룮/•JwïÞýîw¿Ë½@ñ Y§Ýºu+ ^¹rÅív‡B!Ù&Êúœx<þo|î2éÂ)ƒ»¾´´Ä‚ø@†¸yóæ|0==-K/ã¯:¸©â "ꬉl".§1Ðè É;ªXÝ%œ'ÁX^Ô(¾æŽá 3ÌÅŒ_´ ÕÒ›eëÓ)‰]/¯tAŽ ™@4z„4†ÂTУª0–wçâã¶Úíö ®oÂY&“õ c¬££#@ý,„!-×j5°=@0 ¾•J…�dYA–oT @’ö÷÷$ɘ„á"òac­Õj™L¬[厎Žýý}¨d̈¤|Sà ˆäžjµÊ-™¸þ³>¯ÉWc#Í .öÎ"7 E' H(ir```Ÿ‚šÐS,‘ÓÀ­ªðÊÊÊáááææ&ÂMBïâu^~ùe6(ö¦@ÈÁÀ†£ÊÉÉI·ÛýÜsÏ¡Ÿ–—‘E­Vcpïõz- ;!ÎLÉ'&&b±Êt>D“ƒN(NS½ŽŒŒ°–Àý›~4‹aòC^a&N›L&Ùå²)•Jh”’>oß¾Nj©Tâ2Cƒ]ÁÞ ¸Q«ÕzñÅ©µ£Ñh À_ƒcµZE±2öδŒ0Òq’`G…6Ó›ÎÎν½= I\¬µ°ÊçÊ 8+(ìùÑAq: ñ€‡rRH¯×ëàè¸6xP×2d^YY1™Lóóóôˆl€™¢È+M¿Œ†�200›ÍápøöíÛj÷Æ’€ac%&R³c*Á­­5=o­J8·ÕÓ¯ ¤-¸x4¤Ç|¶U·Ó<þMÖί4>jK¡nû®šFæ< 6ýAÑ¿šf-¤¶YJð¹*ÕN¼ôdW Z9/..rÎôš$�Í«‘-p »sçQ—Dˆ6¨�¥Ói¦Ÿ…BaH¡PØÙÙÉf³T¯Œk¡ÉG­V'ÓX”·šÍІ½4WÌññ17*÷*¬QY¢æ+M4Æ u0œÆ¬¨® ¡¯Ã„%N+™,U«UÑP‚ÚNï›ËåH`ƒƒƒ,“)®ÝêÎMžL&ÑÂU%’²n°ÞX˳×e¤©mpp0 ˆv»¹VncR3 ¯×ËΖïȃáîâNÑ××711AÕÌìrF"‘à­#‘,nÉm•Jœh4&‹å‹ÝnGé„R¹\N§ÓñxœSÉü 2Þää$HP>Ú‹PpAˆ4"n ^]]ššâu8Mü!'ù|>Ž!ÚX,F“ÊŠÁšÙl.•JÌyу™çPË÷÷÷‹E–ÔË|ýr¹Lý^*•0g†‘ƒ¸)—«@ 8˜6›Íjµâ ív»q4êëëc‰Ý×׺‰“…h.&i vôññ1âÄÂôfìÓl6eI)D„p8¬. $¬ëËå2ø‘H$rxx(Æ™,¢Y%ä4Á‡àÔ½.~®ú FæPy ê¤Z¥UégAzÓ7½O¥&%h†Wª„ÆÅ Fþü©~ _²½h[ÝkxËçÙ$tœorý…/®J¨Ê¶YMsý˪– j—#Â)~¿ßãñ ,Í/,‹ÁDE—fjjŠžˆIg*®¼ð•Ø—âyB¡Ä28GÇçF¸ÇÇÇ6› % ô-ˆàL‡`B`ØÂ ‚1Èáá!“‘Zêïï§C`U†Bð™y2àb=44”ÍfÂ)qÙ…úÄ`{"£�À¬FbÊ‹Á···§¦¦‰D `KÉ€‹<ÄP‚sÕ0fìËegKìæ5IbfÀôƒ³‚'Ož˜L¦ééiN1R�à¯!YJÀ÷Ù9;Îl6KOÇÆ‚ K ¦@<ž…kƒ#¶¶¶ÆÚyssó;ßùTs²ýP ÀZº¥R‰Oâóù¯ kštÿ;ßù×'h(6ó±XÌçóÁ0H§Óh“ŽÁÓK pÐjµd&{¬:hpÙ 4K—.uwwˆAbµZ!?•J% NOOiGˆ¹�˜‚÷¥u ƒáðÒDÒõ®¯¯¿øâ‹”©Tª^¯#› ä.¼ñx<>33áöz½Ø¢ Àƒ Ì„Ã.78Ý÷¾*š$3šð¥º¶hbÎö0jô»€‹ ù¥4ç…Í/ãñ 4~ zPñU"uÞÛk>1³¶¶Ô¾/ÙI]ðUÕ§¨šVê[ E"̧¢TÔšhB …H$Bd¨I8ÎårÙlx%ƒiâ `¤uXDSÍA\ PÅœ‹ÉèŽb±þ‡y ·(Fð¨Ið‚Élć q:h¨ã€!˜"ht4P4gQr·3L‡ýÄ4€÷ÎÎÎX,&$5VåHÓT«U4«‘¤¥Ð~öì3´áááz½¾¶¶æñx@µZ“g¤ñhæË@|BŽK™R©”ÍfEUýê“““ÑìN ,�� �IDATÑQ aÐôµZÍf³1'¡2ÝÜÜ\ZZW677‡l°NàUäEÇÃ&Ùn·3^£ˆF±#p>è‰ C(bõÚjµ˜ðpåù=)Öáp,//›L¦D"ÁÉÒÈd2áù‡‘<ŠD"ŒÂž<yM’ädŸÏ—L&åæ˜ˆ`×3'Làv»³Ù,O‡F�ÍÅf³1,ÝVv-ôÌTiz(5$‘Òh‹™;ŒŒ ÃR‡ª‹ÃIzñH$Bòöù|ù|dÚÚÚùR„ PÞ&—ËeXÊš~i2Êå2}†ªçÏK M­Ó——————%s¨Ú9Äœû÷ïƒVR?‘áSÅøT%¡¶vЪ”žæ1š¦A…}J|SÓÏyó¥?*I3“ÏÇÕ/ Ïuša‘j5‡C…9égSüSµRP%~¯!N·ÕêPqÇ|59I—pžòÇÀÀ€ßï§�lµZ€‰ Œ¨UL ªÁ2n6d ØÎ­P Ƨ…© 5nÉd’~ik¦{{{|Z£Ñ¸µµ¹šgA%ã7ŒËÑL=>>&¸óŽì�¡}˜ð:¨¶¡¡/Ú™ÍÄ•ž˜Âð—ö{j̇¹±%8== ƒXzÆ@ Àˆœ¶ æ@år9‡Ã¾›ÑhÌår¡PˆEÐ;ݸN�™ ««+™Lær9Ü܈Ȭ‹Ñû0ÕÎÎ8±x<^,™æ0Åbl‡¹l@Ðoll¤Ói^狚šx 耼2>>þ­o}«³³“ÑUm0Ë‘ä¢Bo#ŸÏC™¥óèÑ#¡šŸi\¼^/Gƒ?b–Iç$2à€Pé’“¼N$Á`pfffrr’MêF|aæ7 ¼©qøAJ]µ£Àœx-ÖïìŠ9Mìáh+¹© x<C<$:(óÏ ²…Éd¢ 8y°J!(sÇq;0\l®ªtÈPv ýxðüü<5³&uB Jªhô‚¼ s' O‚Q› ~sçÎÜõXU5fªQTûÔ;7hz: ½{Í—YÍÄÐuª¨1Üys¡¶½…üS“Ûþ¤ß2õ“Ü®1üi«¬§™I‹ Ú)òÅù S &˜±XŒúôÛíÛ·©Ý°øèííå"rÓ2ܧ úôi:†ÇKHB ".#W€+‹…M,Cçt:]©TÈ:H’l6{xxh³Ù z2†:99AËS†KÔ¼CCCn·#9\ÏÄŒ“-Ch¨“““ìZm6ªMâ½ö†­5R¬,$ˆÅl>xwl“ûûûiöc±X4}饗X{RQ’b™°Qæ…b8³¶¶†+âc“ÕÕU¢$`Gàóp 8Y¨@³¨àaPÒ+ôõõu¬¤ùîŒMø0\F£‘«ò×ëÅóK2Áwss—!·Ûív8£££^¯wdd„õ ó´ÉÉI„.Hù4R¬^`0àM°Ín·sB±/][[ƒÚ‚ÍQ9“É„ò Ù‚×ÄešÚŸLŠâ›2ƒ¹ 2ƒ°³øŽÐ1Õ䈡dG"¤Ñd°&šÁ&“ ã&Þj nÖZ°LÀã ‹ÿŽR¨…~U%ž„n†˜öââ"78š‰4 ÇQ²‘'RÞ}÷]•'+¡C  ›„UúSCeP)”´ °ªê#UQ¦ó¶¿z³¶ÄRþ¤Ä ˶Bª‰ó´Ÿô+u Dšæ@õTÐÛ<h`Em{ùÀKŸÿQ!Àz¥?õ-$C¨\URíÂec(ìõzWWWáÁšÍ楥¥r¹<33ãt:‰@8ž<yÂè “úJ¥ÂÞáp€’dÓP.—·¶¶(ù�¬ã(©, ò¨c2›Bƒ€Œ$"CÞ‘Úœ”�€UdÔðé$Rˆ”&8H(ÓL ÐH·‚ äcs€Q>Í[“ä:;;I“€ÓwvvÈ"@9«Õ*å6ß—¯ÀŠÒápÌÌÌ!ˆÔÅäé¹¹¹r¹,�¿ßOXGÖmjjŠŽ¤··::Œ9¬]§Ó™J¥ØF0•â1„NlãÀÔ¢v “>æòåË©T [$A!„¢—j ÕjMMM±%’„ ! ÝnŸ››cuÁWfrB³ …X¢œÇã¡DH$SSSŒ1‰¶›››�piò†‡‡aêÁ=ÈñšŒNGØñ¹É5 ”Ìr¹Œ?9%Žø Ò©<X±Á¶ÙlxIÇ¿„&#äJޚ΀txx˜N‘Úˆ#§¦\.onnÂ\Á’ˆ?33Ôfii‰µ¿0  7 íYöÏÂnóûýËËËÌ÷d‚­’$ͨv2šjRÝkBYÛòTòŠFñA“ôp›¶‹„¶ñVb j«¸÷ç%éaEšØªC©ÈT•¡úçèô{I€zЪ&Éšì%Dvù£~ÍÚ™³ÎáÓ,9d …Ö××Ù‚ë õ—xìòK üÀH···{{{c±X±XÄã›ò‡zDM©Tj4L„Á~ àþ0®¥ëgw `Ÿ@#nŒ÷w|n‰Œæ<&Ò@)±€Þ,ΠÔò ©¸Áø‚¸w!³CDãV'ö&ž¡üC%HÔ.‰µ6δH>ÀW:88ˆD"Ÿ~ú)å0*Óðu©?âñøÂÂÂêê*LJ¢I^2÷‡Ã EÐBzFµ-•J•J%F‹t ßËl6ûý~¿ßxxèt:/]ºD×…+Îðð0k^ŸÏ@¨§§Ççó]ºt‰ñ Í `D^c±˜ˆý!žAÁU$ìÝwßåà3r™˜˜H$L‡¸ü>úè#.Bº„ÁiH6—^zI$Ä)íi7y"ÊÁÁ5½Úbǧ…‘#z_tfœ_ L\|<€@àX>‘„OŸ„µŽ¸ÀrÓé4]K£Ñ€o2™¾ÿýïs6E˜r(¢Wî1;;+ƒ£û÷ï“�بœ©T{ß/¨èÛ¨Õé¿J³Õ/œÕ'Š„³Œ˜.&0ëÑ¡çÁDõFgj÷sžÅ×L ç¡b¿P©í°L5B8ï‘0¿ÛÚJë3­¬’4”±[Шk€F¥Ð4•Œ†‘ào%™ÀãñŒy½^äÒ°äF£±XŒúއè Zö\¸ü033300�„€ûêÆ�óÙ[ÌÍÍQG·Z­G±2…M*2�§§§ÀÒ!é hU˜ÆP“ øÀŒ„¾Ô<z ₪(ÉQʃ’Íkž}þ‡Ñv¡P`ÿã«ò“Àχ††ØµóßßßÇä?<AÑ9 íÑ«‰B ÔB¿ß¡A\ÃØºïîî^ºt‰ çè興R—ˆ<øÄÄ„Édš™™aa‹–Û#^åósÏ='Ò­P  ŽÜäôL¨+ƒë‹‡D­V‹D"Œz˜¤q–=zÄIˆÅb¼Q0l6›Ø0°ïîîN&“‡ì,þ333,äÙñà§.¥s¹oêõzYËõ ‚€]T£ÑH$ô¨J�,¦gýE+€Fo4…¬Ê`® EN\P¢c a‹Þ;Žì±@©Šf0]&œG_‰DbeeM$ǃkB>Ÿ¿}ûööööüü|2™dŸpœÀ-,2âÃ!…?w±d…ÅÅE"€fd¤ê#© EÒ.¨ÁG¶Ðêx\³HP«gU C­qÕêþ¼Á{[Ô“¾PEŸþüËç¶æpm#¸|%M7¤ù%áX]\Ÿ÷U5Å»FªíáS£Q¿Ð‹;‰Ü—ˆ&{KËR*•¨;ÐY#¬ž¨n’ɤÅb¡déGZÂèÑh4ÆãqjCxü" ½¶¶¶¾¾¾½½Mp||LÁñÎ300ðþûïYXŠs‚&öÜsÏuvvÞ`P «T*QÈ Ï™zM4–Ƥ [Ì‹iDÈ1Œ˜E™æQð e0ï9: RKWW—Óé” <!Òét> hÈ4™ÖÄãñLLLâ‹O¸¹¹™Ëåå/,,P* jÀûèè(D0ZŸr¹ Y/NïïïƒÇ�‰D<x€QA,#QÍÎÎR)G£Qú6Æ_moo#ybµZ«Õ*BF¬FÉë,?¢Ñ(ëîR©ôìÙ3ú�r9¸Ïíííp8Lxb2¬“jL>R©Ô /¼@)F,c¤†2Êúú:® Ìa€‚êÅécw ÀŒÌG7‰>$¤DºººPR7•ˆ±$'h¡aƒ® xŠ\.Çþ¦£££ÑhðÝÁFSIpåÐqЇBI`XIWh°›Íf„+"‘­ž0Ýâ&­×ë›››\jÙ'—"O-Ò…Ò¤a rRŒ¹ä¹ª[§�^Ô¸0IÃ<ÐGT <Ió}u¯1ù¹àÅõ³#}0o›!þTÏçó2˜:ÙW¥èô_F%6Ÿ72“#«]¼ VùÕmGLú‹ùG_†‰\ªÛm©*ŒCç›Íf××ס ±Q¬Õj(ƒR郜£BáâfEI¾ ƒ@NËå2·�#Á#LAO Á’>Ó¹&ö‡ß�p£Ñˆ)ýA«Õ˜D;ÿY}™ø£žé=¸ÌÀ,!†AŽA<GŽ›2[¤˜Á59Îááa´Þh¡PNfƒzxx˜H$ÆØÞÞN&“tfÀI9øõz฼¼L¿E”w:°9V4:Ñh´R©‹ÅO?ý4“Ɉž9Ë�p,ê*2`§ÊiÚØØ@Ã*›Í¦R©h4êõzAÞ ÐW*•¨ÐS©Ôþçâ ™™>�qõR©Äê"‰„B!!ýÊÞùùù………ÝÝÝ—_~Y.Zè &Zår9‹áUY«ÕØ…à2-’A(uÓLÐÂ>~üxss3›ÍBrt¹\N§sddé=øáìYW@†–Fl ˆïV«• ±³³ÃIÚ)jt5hD æ ¡Èì‹þÄ6G¾T*ݾ}ÛápF–Ãý ê¡GËÏ�=ÄCED0eñ FH6—b}ÁÄ©ãsW=³Šø@²¡Øs!?«ÚnmÑ¥zìåüüüÅõ{[·µ ¬qôYDU†Öø7ü´’Úê }™ÿE}èþýûƒœ§Ý!:ãzsI’ªò8ÊHªŸ3ÒFzßTUŽI}q¦(¼KGG:Kò0Þ 4ÖEX©¿¿¿¿¿iiéƒ>xõÿñöv±mÝ÷ý?%QEŠO")R´DZ¦MÁZ•¦j ÀÆÔeu–¹˜gm{›‡ÔÁ¨]bÐ…¯tYÁ—ºó/r7`Ð�ÅŠÞÏÁ„T¨ÃÖ´Eë")‘Ÿ)>Iþ_¼þþàÛsHZkÝù"P(ê<<çóý~>ï§‹©õØFBȱÛí[[[v»Ýétb6ÐÝ݇ņÈívúé§Ø­È0ª««‹÷ØØ˜Édúû¿ÿ{øàˆŸñæ¤ïîîO©V«(u!•ù6 «ÕŠP‹v˜¢ zL•g¼ÀÞ ; TÖ2=€É ÇIfMÄÑÐtuu~@ìa,žN§ &ÀhÄŽdŽCé$üùñãǬdN§“iddÀ�I�²Édg62 €Äf³íïïsØÅomm¡ö×hÜœ¨Â,5QKÁÝ„S,Ùïcµ>ŒÃ_%.rpf°O§¶Cå´Z­‘HdzzšŽjŸ‰9Í š�2*<x0:: …Lro.^¼8;;ëp8Þ}÷]6Âx+U*·ÛÍfiïpê¦ç�»úøãßÿ}œEð¨ÀR‹Å`4LMMuuu%“IV†K$Š×ëõ“'OÒüÁn€¹Çéèd‹\4‹Á&‚>Èl;<› v´ýýýÈtIreÆï|ç;>Ÿo{{È­ÙlÆb1Ú_*5Ñ)l’ÈW¸yó&kô—.\û裸ß)—/_žŸŸ'ù½÷Þ%&ibˆDç–çÉÔ’œ /Ô€ÊÈââ¢Ô4Õ=I~«>¢:” 5ØFcˆÔÒËNõSÍèZVi~¥ñJú#•ÏdeÇ”+·ìuÀ3T5¹ü¬Nبó(A‰U¥¢žç«Ç®õ¯¨`©Ç‘Ù‚I¬’‘¶r±2;y½|.aGˆœ™%m`Úêê*6@µLŸ¤WKz<ñ ƒÓédøùª>ñèÐEãJÍ’ŒhÀ@6qŒz‹#7÷3*eŠ/“zx·2š�eÂ"chÌph& `1D&®‹q0‹–8<oll¸\.Ö8µ�Ôkkk'OžDËäšàL³ÙÌäý‡?ü!ƒ]t°`̬èWªÕêÎÎ2`„¸µZ è²··÷«¯¾¹E|@|ææææÚÚk9 `ƒÕjE)͸âSµZÍf³}}}(ž„B!£Ñˆê Œ ¥.°'W–*”{f&“D ËH dØn·[­Vì•?NLL$€ ©±*.�ö ˜uC1�öìY0áSd³Y¨h0 ðΓ•� cU¨Plêù-îx{{{h$9k'KoæÅ‹$ÿ°S Á%d·ÛŸ<y >|Ȥ”¡âÊÊŠ(å–¤ÈÊìALŠ4reÍE| Ô›]3ÏàÆƳf÷­§½è ªˆÖ.¼ÒÍAru¦·Ç„¢å4Êç×f‰Ñn© øÊ©1è’Týˆf:¤‘‰ëÿV¿ÆÈóÕ¿m÷НtìP¯9ćÃaÉüãg./Ö€………;wžåŠ‹I•Ýs‰3>ë™ËÜã'L)·Ùl Š¢œœd”Ï Ç!ÔæÎ^ŒMCÆút’¦ÀƒTylŽd¦D¾ h38 Ý$·4!¦…BaggÇ`0Œ3O ±6<{ö yÓ©ªÝÝÝOŸ>…,/¬yŸÏ'í6{IôÌÕjýĉÛÛÛ Ó†— Õ £9±ËtI`?›zª|>„#h\4ä„K-f}…!ƚͪ†É EOOÏÖÖ øy>Ÿg|OZk?ß/kÒ³gϸ$ÄŠœEr†1kûÿøZ­¶²²ÂÔ‹•›÷/› <½–——)â"ø…BLih%¹Zð.M$,~‡Õ”8ØÃÃCŒ%˜Y1T$@­R©x<žd2éñxŠÅ"§¤zØÇ÷‚ð‚·˜L€«×*3+ÆSF£‘¯¡ûÌÌ ë(ç!‚Ç,--ݹsçÆøsQ³±™’0J¤ «Ó$¹åeQ—UkÖÒ˜HC”W—%Mª”u=P|¯R}ÚÏñwÛí–®?Ë y+Ç)ÁŒ;Ú=Ø~ÐôÇ?¿êÚ£2 ô±R¯e×/Wß.ª˜æô’ +KGØkOv‹2¨Åçé/(t8öz½PéYKÄ¥‡¢ µfggÇãñ§Ì=Æ}‹V¨Ùlîïï[­Öd2966†É+£|&Â…BA¨DÌÉ’”e€ÿB؇cƒƒ?Tw^NÜ !Ѳ‹Ej}(¢‡ÈårCCC˜ ø‘Íf©¶µð’‚âe¥P(X,FOк¨àªç%’ 2¿bME”‡½+ Ô^:¦mllÐ+pÊ®Ûí>yò$žÏ²Š Å£ëÚÛÛƒÑ/iK0²á°º˜L&F@‘HD ý;wøÖxðÆÌÌÌÊÊ ! ð„×Hׂ`^ò!ªÕêüüüòò²´Ò³Z,–S§N ¹Š‚Á Ë’˜ruY­VÇ‹ÅB¡Ô t:=::* Qnáþ¯¬¬„B!Ìä£À±”bpÄE²‚(ò+S©TÚßß皺M§ËÏ<AVÁÍÍMî uˆ¤Þ¹r·rS…eh£Ž4íëA˨1^»¥º«©%X|“:©…Tš¡–ïäå÷J[9ÿùÏ®. <Æ âíÞ´Œþ¯^½ŠY9_Pÿé3Qer~À”#uD5HÏAºiKЂeȯ/_¾L ªáeNO`ðÂÉ鑽 Ãá°ÑhÄYÁl6_¾|™nÀãñ¹|ýúõoûÛHd…Ýuprr.ÓóçÏ©h¨xŽŽŽ@:ÞÜÜ|ã7Ô¡6VÌla’@•¡ÊcÜÍæ¯:v÷8÷‰m*w#Rè"f³ 3703q¯Ð“òù<X®÷d‹æóy†�2ñWp¼þ‹ÅâÐÐz ¸( ôYÒ¨TØ‘‘‘ññq›Í†•(z¹\~úô©ÅbI§Óà( ¾¨Å¨Õ¤ ÂÔx^ÀNqa€á§«« § ½½= º¡Õž á Ę„„ž d›5²§§'™L öþ\c…=66600ðé§Ÿ¾ùæ›ù|žx�¢ðÁ˜˜ØÚÚ‚Îàñxˆ¹¦@§R©@ €‘ 礫«Ëï÷“¯påÊ•r¹Œª@€/xŸ '&,C0ŸÀä‘Ù#«)^`ïìè1gDµŽUpooïøø8ºHúƒÁÁA` ñ™‡ }™„ Jår™/îC-q, Édòƒ>øþ÷¿ÏÔ‘Ee{{Ú…þêÕ«^¯÷ܹscccp‡>øàƒz½N}¸uëu–ŸºqáÂþ—Àmª¹Íf#p[S…().\àÏäŸÀœ2²gÆ«‚©“““€”š2­‚£êÀI“Ö<Y^WE£ùY ¥ÈAóLÁ!Î;÷·û·$ÆÐWPÙ`ú)|g¤AíéÚMëä‡ååe‰QëÐ^èáM\hË”ú~ô‡¥y—Ù‘í$F7²¹cB!Ó!ÙÚܾ}›öBÀFL$°çŘ³¿¿){[vÊHUÉE8<<”LDF½Œt%~ cæ�(œ¹ýDÝ&Rf;üé°QÂPÏd2Pý†ûvÓÁÁÁóçÏùì£) •JcÔP(]•yUe2™dÖO`Ü7¿ùM>,ëitt3Ân:bì%ÄÖEáÀÀÀØØXµZE2ÍBQÊ)ÝœƒÁpçÎAtD¢ç˜NÎáp�0ˆ±S©­­-ŸÏ‡=ƒ £\.—t ¬XlöéHTSUöõ\Àê4‰¥’¦AèÎb^ùUæo4—h'ñU'€8Çiç¥òò-£BÀæk¿P(`GÈÂ?00�@ÍÊ *çD’yœ'Ãj%qˆçðg³Y�­z½Î•?::úûßÿ> îììpr(¬À Ì”¸k¸ï¸ã4Ý€ÊÙçvSǹR‚)&²gÀäAµÿPŸðJœUEAÔVCæH𱇯¶YE:_YÕ*ª÷‡îPåç?Þ]µƒ‰)~vz{‰ãÌsÄE¤ZMóIdUhg°¡:^©<Ô–¾T¯ ½U”X‘©©)ÔBz}|4-—Ë›››hgpÑb&+_­Éd~@vOÃÁÄ ( ÏçóaéRj6›¹‡i#VWW9,»lÜ5�ˆÅÁ7 Yÿ>PDÌË(ëTÒß  D{¡?¤”‘‘pf¶{ét¼Ò'^ùàhL&Óo¼šsµZ}ôèS,¦óD`Bˆ"­3ŸÏ'“ÉÝÝÝ–L†- O$/•J9øþ>ŸO,?Á?£Ñ(¦³Œ5Ö‘À¾• —H/[]l…ıРÆ\$ŠŒàYPeãœJæ ¹ÓéÄoT‹Årþüy¿ßÏüräÀÀ@0_kɆbUà8SSSˆ±)úœ7$ kkkX•ð4ì¹"‘H0ä:uêpK&' †½ŽÏçcU�%f+Ãæ-. Ù°‹ .Oº»»é± CCLÀp—V¸»»Ws"`Óét>Ÿ‡4ñûßÿæ7wâÔÔ~3~¿_„ %> 1½-V©*_SÍX惃ði," ¢^F,ðÌÙ4I;ª?´”_NU×&)áÄk–U:×r”¤°kª®Ð[_™fÖÎKã5Œ’衤WRÿé Uíz=éJ}\ÏÁRGL‹‹‹PTÕ¿5›Í´~’B*}mšJíÒt|_|ñ˜´u‹‹‹ëëë—.]êë뛜œ$Q—Ù=¦ £òù<í'«f³Ù¼zõj$A!Õl6™/™ÍfŸÏ÷ôéS|uòùüÐÐ^ЄÛPè“ÉäÐз¨Ífcw Nd@ÍzN§!RpÈ`–BûÏ®ó}6n@Ùð/Ô€EÓ‘€bÑP6Ñè 9²$ ¡“·Š²jŠ)ÞàðRP½±íÅÈA¬u€+iH’@L°»»›J¥‚Á ¶‡¡§§çÁƒ@¬bÀÀkÁôZjåæ›ßü&œ(·Ûúšj;44Äê’J¥8¥¸ƒ0*„lŠ„øW"øDÞ´ ncã -u{{›Ö§P(ÌÏÏ¿ùæ›.?99¹½½ÏçOŸ>Í„0s(2;ùNûúú¶¶¶p4‚hpúôi)éP±94+€ÏÍf“™$èDaúN®=:¿\.·µµ%\ÉÍâyFV«% NæHÂÀâ—mZÎa>ŸßÝÝEgEt:\~³=z´°°�=ôÂ… ÿò/ÿ²¾¾fggS©ÔÒÒÒäää‡~ø½ï}Ì-Aœ÷)ÛÍ/¿ü’¢!5„a£$©2‘VkÎ_|¡2Aùsa£jàrpþ«’VU*ªL~4Äý–C'µ ©E•ç«áÄ*­_ý2KWߪf”ô†²=3Wô«ƒ9)Óàòýi°ÍÙØÏÿÆ�� �IDATçA 5Xä@¸Ær:¢`h¨Š5ê 9³r¢¯^½Š«ÃJ^÷òåË6›íóÏ?ÿý÷ãñx 0<™ã3¯$ýÑ£GˆÔ ·\¹rÅjµ¢_e&ˬó8—Ë!9ÜŸôˆ+• ÆÔ&¶ðĨx Ê^»ïå?æìêØö'Ôþ–—¦z²§`¢@±f°³»»k±XklooC“‡éÄ DŠ;£¤îîn°\ª-ÛC"ÃP ©ÃäˆÔšUÁl6¯®®ÆãñÅÅÅ?üÇEiº066ÆJÀ¾þÀÀ�b‹þþ~Â!†‡‡#‘ˆÙl¦Q ¼Œ*iµZ‰“7VVWš V;t(ø²˜Ÿ¬®®NNN&“IN2H’Íf˾¾¾¡¡!:<p&Ö0§Óù—ù—·nÝâjáš?wî\8Þßß·ïëëCt†‡.ˉÍf3›Í©TŠ5í 80fS|§àXLùQ²8 £ÈCG/l6ËÛËçóTv±ˆâkb>ÉåA‹Y(ÀùéV¹�èäxÃüÉúú:—ÊÐÐP­VÛßßë­·�غºº>øàƒ .J¥rùòå+W®Äãq³Ù¼¾¾ÎbÀõ�ʈ&ޓɾP: î}ǚȪ Îýß|óM:x 4ਦT´RàIÙ}kä¹Ì $Àª”8«.9‚hJ!ÒÔIê’š)­(}ÁTK«,]¢2ÖTæ?UÇÐÔ>eê84$™ZeÀµ¤[©}P»‘œúÆô¤#ý¡4G‚œho…Ê&4•ê r (%Â>yíÂÂÂÝ»w!Ãà…ÉðWÈ6£££DÁÀÖ]__§µ?::‚—‰ÑÓä¾¾>€eniÀÔ�===6› Öw–(40šØŠÕ+qrX4c®N f'È_1°â“Öëu@i{üø*Àò™L&s¹ÜÄÄXn ßúÖ·Èvçh(Àéf€R ÿàÍnwuu•–ßçó‘¦ÙÕÕ… M G‘+óW‹¥^¯ãZÁ‘Y®\.×ÚÚš×ëÅC‚Ñ ÿHeàc†B!0µ(¾½½½ëëëÂg%ðC€"bMYïaôö÷÷CO³À¡`XZZâò—b'2�Š`�Çĉ)S4=þ<37V\©`åBü½ÿ>W#æK›››çÏŸgy¨T*¬¬‰D¡ƒÏçÛØØÀsExkÆ€ä Ô‡Ïá•L&“AÄÀÛ`òÉwÄ[bLÄl\îL&(©PoC`!‰P”Š! €";PK‡ " !Ì1îÜ–ÌTpª%a²Ý]\êËN¢¦F°¥¯„ú?T)°í(ªê#¯“®z"T‡7Ô2‘®¥‹a; =§X= EšÓª7HM×¼®PÜd")Ôi=½U¥´ŠhCý_u(ë O@Âæ÷û¡c²ëglË‚š‰vµZeþ+*A:ttCp‡àð8†Æp«J¥’ìø¨Ö¼´G3¯`ËÏFÛl6“<ŠˆÒ•¸.Ȱ’˜®°9E¬À¶‘‘4;w<ã‰Ê5丄Á™L&@øF£†:+ñŠEÑÀÉ“'éŸ�f0€²ÛíDE–Ëe†N•Jegg‡'àxÁÏ™LæôéÓ,º¬©XÕ‚Ö æb!)—Ë…BÁn·“͆ #†�U–¥‚ŠÌKô ;‰ð$†LÕs j¡ fˆEèôÀÀÀÊÊŠ¸DhÖù-B :6rœH¾CcÇ)ÄB†¦ ø¹jÅ΃kËxdd–I!du°½€ÖL[ í ³P¢¥òä‰À¼äŽÈ¥þðáC\Op ¡|Ë&Lêudš-£JE{ÄÚ,û9yápXgJ9°Æ=ºeÝãµ:³êõµ[¯‰;þÞºƒH@³À¨Ç= Ãÿjèð´W T¿ÝÓÚõE-WQõ¯4´b •KGHÐ"‰’‰ÆSWU±É…ÂÒåóùÖÖÖB¡»KÇÃÝŽE;5ªÄGã…‰(4•JDonn¾ýöÛ‰DâÌ™3n·¬íCnZü'hù™A1vWÀê€ "# ˜Ôëõz½Ž~: ¥ŸÄ7ŒNId ƒ¼Cæþ/^¼`Ãï?§Ó¹µµ…è¡»»;‘H@Ï2.vñðŽòùü©S§`vÒf 3ØA{ÌrH²Q£8N“‘Gaóç|‚ÖÖj5á›òc¦F$k²¼A«D"e Hà+€&DR‰Y6�½ÅØXE” BbÅõù|œŠ-K#²ŒD"Db´,Õ¬s¹\nuu•~‚#'‹ A]‡ø l ØÁ’’Çñè>qâC<ä,ââ. vBÛ“—¥‚ž²Ùl QŠUÕqnnnyy™{AÖQÙ™±ÿSwrôª0Vê¯ÚR¨ú¤v]ŸèõðÊêסÊk¸O-û†ã+:8“¶\þH½§ Ój³î“uM–ÍÊ¡*Ô[¶ríâÛØ¿i¨ÑKŒU,˜ ¼‹Å²°°�™j”¤……H¼hKÂV’•ËZ¼S©ø$îÿ £4¦@P$8Åb±Ü»wý~$Á”ŸaB4e²Œÿ%[iAGA°™°3YC j†’ÄvaHp„¦.÷õõ1 Éf³�ÑÌ‹ÙÉ"ÊÅu‡7ÀÔžåJ,üà¹Ãt‚" )b7R¦±w…è™J¥¢Ñh("¹ltt´P(@´7›Í;;;;;;‡‡‡„+à·AÏ”Éd !¥R)Ò¬Ûl6xM¼=·Û½±±Q©Têõ:²g rªÛ|9,”Yr• …‚„J^æ3“_TM¦=X·.,,à±ÈB÷Uy&“áJ-E<•JÁY’fWF1T[¿ß?==el*•Z]]ÅbdccãÙ³g¥Riff†\8©¬^˜—Øívì»766Àä”Õj5ŒoaåÂU…!&ïtxpÛhShvèÑ=0ÛD²@7ƒøƒ”¶&0i³h…®®®öööròñÙ®±v–Ëåååeñ¸ÕA®4ooïöíÛ@@²äA¨"ü!#¦®šd4ƒ.LoÚrÿÚ’T©YÄÝY !å·¤‰è+MU_'+Ioê$€†ÆJ4òR;O(qÜò�¨2Çá¿ÈÍÄüNóÀßAœäUDgñ�lG|µ¼Â(téÒ¥½½½÷ßß`0ܼyÓ`0ÌÎÎz<žÙÙY^B<øÎž=KX ¤lù/¿üòý÷߇ÃÇn·ß¼ysvvöÂ… @8…±o%í–: ×…hô Üÿ“““PB1±ae2™&&&À]Q–QÇqÁ!p80‹=KÖ&‚1ܦ"ƒBÓpçã·A…A»rðaÀX†0Rú|ÑE㌄ƒÅ¢moo/ü"臇‡á/2çyðàÁ™3g\äóy¸˜>Ÿå¥™¡l"œ¥’É$ŸÔb±€œïììPß‘k€º“zÄŒZ Q‡%–¢T*!€B‡óR¥RÁSzoo7O…"=©P(üøÇ?¾tédSÈc¼LñHc%p¸««Ëáp ¥Ói0U<©˜k±Å¶X,xÏñÕ›ÍfØ´,¨@ Ùl®­­ ½5›Í’ùj6›Ñó1‰HcïÏåW.—³Ùì©S§�عÌÒé4¸:¡øÈÈ­�À4ÇÈÙv€áÃJÂRtšë³V«! ççÞÞ^žýèG±X Q$½Q @…óío{llLɬj˜Z~òÉ'Ÿþ9¤Aˆ'Øát ÷äððÕôÖ­[³³³7oÞ£¾té¸=¤Dj‚hr‘ªZa„Ò¢¢ÐR”¤’èÍC¬V™H*­HJ¹ž £9¬Z¬4t#S?ßV«®|þSÜ:ψ4+­Æ4»¥3¸&‘Mã’¤>vFÌ¢rŠÕh•ÛÛÁ®6K¨ïD¶f¸Z....//«mŠ4.—kuuUBF£ÑÛ·o‹e 9‚<Ù`”rª's‚_àfô÷÷ã ÍF,‘H ç’–‚mÝÇÑSÙé¶¶¶è`‹"¦Ä÷¾ü'½?]>9BN¥<1"§Í§"ár8±XLµégC-6XA`ÐÓŽ�`�)W*‡ÃQ,¡6 …4eûûûð€ñ³›˜˜’I¹\F¾ ;khRž83©TJBN:5<<L¿ÅùäÉ“¼aŽË“ æ ###ÝÝÝ### 7õz½\.#DF£Ïž=»wïÞÞÞvrrU\»v ‹æññqlÒImâ� Ñ4ð-ó‘øá`0ÖÖÖ¸œFGGÉ&"‡ s!Σ¨h4\Nú‰‰ ¯× n|ppÀhˆ¦$•JõööÂÄ…¸Ì §ÙlÞ¿Ÿû… (”€ðJ-K"‘°ÙläùcÇŒ~* nX°ˆ®X,b ½»» ÊÒ××ÇØŠE1•J%‰R©ôüùó|>¿³³311Á‹†ÃaI²³ÙlLk777Y‡HñãÕTÜ 5†z¢Hà”Ñ“Üéê®úlsñ¨‘ªæ@ uлݵKGè0nÑ #ÔÀ8ýAäùj[ÐyÕ烶Ó1ü©^IÇÇ=:;Ùi ‡v3»vlƒ.7´¥$»¥§SËï² Z£ë²�Î'°Y&—µj¡*)°e€û0 2†¸1%¬ßPæü ,{7n!(ƒxEÛÌ’ ó¶kµšL®èôáÏPÐÁ´á§Ó=0ÞaËo¡$w£0 À”Ÿ­({säÕa¡0D"$™ÑA>ŸF Cvµ@¯§N*‹À§BÃê Ša³Á ¥àøà4^¯—O744b2™ÒéôÈȨ;ôSº)íñ}«ÕjÉdrccÃívÆ••ƒÁ0== 0�±.Íôô4Ã7†„ŒzÜn÷õëךãÈ$Ö§¬ßÀ¡@¬sÌ „³ ”®~—ËÅâÄõ#îxÅbT�Õ;Ã1†û€À\„�333¹\‚¬‡R©äõz‰¤eÂ644„ðÒ ûã˜$AJæøXÄ#|¨ ì;EàÖÅ´J°åéééL&#Ü$ =î,LQ2³½#à _2MäÕüùqÃ-eÏzßåõ§·³¥Çèq$Æí*˜~¦Ô®V¿Œ¡ó¬JÍXÖ„BËä®eÑ7üaXìÜ5 l»˜lMô´,³<Aí©Ùè£ånß¾­j¤Åá’ŒY¥¤eQM}ççç‘e² ÀL¥ÏÀöG•)=ll¹“}>_<gI ‚˜nƒ©:“2§b¯G‘•TÈK´ ¢.Z@§†Ïõšé0ÔUÊÄ(žŒÄX >ì çªV«^¯Wfâbú]¯×ù_ü‹^¼xÞb¹Ó(Å ·[­V¯×Ëì…B™H$ˆºÄªèäÉ“Åb‘ÖÄçóŒŒ ‘L‡®êäÉ“Èqív;lW¯×‹7vL{{{ø>Ñ ¸\.º>2B%Íf3F¡Ìdp !kÊÚÚ)Ы««sss|;Õj¼'ÀUåã0vçJ€� vâóù‡Ãá�•ñûýDñ«àÈŒÅïÞ½ËgÇ“œöèèèhppÐårqLö ,¸o±áuIÅ`ªöðáCè 8f€ôééi¡–õ÷÷ß»woee^œfÃá/tww=Bf'(4h¶ù|žVé þ]ìv¹\.öø{{{v»Ýï÷ÛívB‡¸_X6VWW‘ ʈ g KDì<ŸÀΕ•ê5ÏB@Ã\­V%ÆGjµ P4V©rk~ex™åÙ.(M3cPëžDãã©Ö%•Ò¢_3¤Êiê˜úƒ¾Wh¥üڔϚŸl‰Yóa˜èU‚"MTÅLôD(kµ¤gÈtOB{d$ÇxÇãñ¨þ}âxÅ<N]räE?üðÃP(tëÖ-x‡f³Ùãñ|üñÇ2=T-Ô4F£Q$-L-C¡P2™¼zõj,›™™¡G ×ÕÕõõ×_ƒI¨Â1nH\h(màÀÙƒ@"´ÙlLœQ$ €‹900À Ÿ2©ïB„e /„%ª6I†—ï¢H’Á:ûA„u¸A0‰’¨j%S^…±>/$ EDKétzllìÊ•+ÿøÿ×–F„÷o±Xð£â@´Eñ‹\ƒÏyƒgEÞ]³rAô„Ê R¹Ä˜Öd2e2Tl4LœIõýçóyÇ3::úío›²N‰ÿè£>üðÃgÏžÑf•Ëå?þø§?ýiWW0C­VÛÙÙ Œq¾þúk¯×[©Tyfžc2™Ö××Åw/ e2”á===ù|~Å8}ÉÓ§O«Õj2™DæFc±¶¶ÆldˆjµÊÀ½§§Çív?~üøàà ‹ÕëuÇÓ××çõz³Ù,l4Üôˆ©ùíoK3§‚o„Å=ðsàÎ*c:”á•J…=CÙlÖív“YĨÊï÷»ÝîH$²»»ëp8”n ÆíƒhCggg)¸—/_FE866ÖÝÝ=99©ì¼÷Þ{±XLÈâ"l–Ä-êŤ¯¯=‰ÉÉI@ <’i^W#Ú�RôÆê¬_-2R»Tx@-§ª@XV&™€µ´–è¨ö¡|Ö›¡vÐB«bqΗ<_³`¨Ð´êÌʹP—Ì’ÕùÕ¯~…†CD1¡ÆC¾ÈŸýìgüJ]u–––.\¸ðñÇ òÃÛà¯^½ŠÞÒ`0à“!HC,c?== »Ãb±üìg?›íîîFàêñx1&f£788H£÷g,ÃÈétîïï3ÙÀÃR&ÄS6¶LÞ½KO@W !­îF@TC1m‡ ¨´RÈðÞ@€ Dm2Ÿ±è`ñà™T’«Es€×&{Ï¿þë¿~ñâ…Çã‘”·/^lll`Í´¶¶V*•¶··ñv& b```cc]¯ -UTʨYË”-Ö²X§1U­Õjëëëøÿär9À–½|>oµZ<x@Ib‚_©Tð±éâØØØ~ðƒt:ít:ÑñrÁ`ŽÄÉGF™8™L¦§OŸ:1]XXx÷ÝwÇãÇ9“,KÙl¶T*ýþ÷¿F£XSlÎõ€“•Åb¡Ãƒ„¶»»ÛÕÕ•N§IS�.FèŽmz2«©¿P•¸rŠÅ"†�ES8B|•ÃÃà å`²²*€`G"‹ÅhÏUŠ«y±X ƒ}}}<8}ú4Öl¤êõ:8zaaáÒ¥KÌ܈WûüóÏgggé ©}~+д"Õ…”ºtõêUöCøjð ŽÔMž:jU­ú2¨amjYÓ—8•5£ §Ù1kPeŒWÅã§¥»D;«Þ¾Z¯|îþ#€WX5²aMǤvF*ÜR| Žƒ ˜§ª²ÄäAÕ’¯ÝlNx¨š÷©g}É3§âS0 ch¨‰„ej¤:°UY]]…`šÏç"ÿ⿘™™™˜˜0™L˜ïc©–J¥ˆ»âÛ8Š7±½¸f‚åšÍf—ËõìÙ3pfÕ9µ««koo¯P(°ä ƒ“ ô ˆŸ™/I>; .0;þê¯þŠ LæTÌ—̨V«>c$‡G?,)&ãp:¡';ãMT(ˆ¶g¾_,™DÃhÄ7Éjµâ­¦o­VËd2”ðP•Jess“uñðð°P(…‰~›÷ =A.—ãñÃÃÃD"‘N§ãñ8ÑlÛÛÛˆ~A/ŒF#ú2f8¯Éö–9øüü<|âH$R.—×ÖÖÀ]Áêé Ø2s>ÃáðÔÔT­V#$D ®L(R´‡½P­€Û¬Ê2è®8ŒA$HG.c!€ÛËåè Ã°Ûí è�ɘ !¤¯×ë¹\®P(Àµs8Ìî@bà‹Åk×®!¼@„Ñl6÷öö@æ'&&ä$¬®®:$ú ®y-Ÿa“ƒ�sŸŠ²HÒø€œO©E2J’rÄ÷¥¹¯õ“MyÑ"•û®)Gúé:××qÑKk~%pwga–¾bSlÑýG€ Ç\-ø’äüR²55—“¢ÇúåAÍ`®å9R+5•A…ïõaܪɢ¬4ËËˬU*ÂA}çA¡9É\‹—ã^‚A¡b\ˆ” fÄ«««ä±PÔ666r¹\*•b£Ê4od2 R©r¹üðáCÀ†|>O„Õjõù|lÒ©æì°‹Ó㳕fSÙ\ŒNeÙ c`H"aŸˆ×+Áw‚ÎíOd_,Eä. –ÜäLœ(£œ47 èíí%É™}ƒÑh¤Šß*¾Ö@ÜìXapñV1œØÙÙ!Ÿ²Ùl& –%,á臨bCCC¸®ò‰Äú‚X=Ÿ—q°IôÀµZÍëõR¶r¹ÜçŸN²Ûíáp˜µZ¾­ ”B¹±¹f ùonnÂS‚ü†H磿M¥RÔ>,ù,Ë7¿ùÍx<N•_]]e1Pï^‚‹‹”ÝÝÝD"·ÑhD£QHA¢š˜˜ˆF£�ú ´&Gæ»îîî.‹ìp-‘.~xxÈþ†_;ýÞÞ^l<àšL¦••¿ß_*•¸Z�HÊår8$ì9`ž&%6? #ïsnnN¬¸UÕ˜O–€hÕ{U­f`” Íã¸Fzß~}…” Ór­bÚíêpK]BK|¢Çë\:[^·\Bd}Ö—c½MnË7ÝâÖ<H™Ùüü¼¤s²´zêy{¼aQ¢B]€¥Êe$¨0 è "q¥ Ínß¾ Ë"ô÷÷‡ÃaÂs¸Ï”›L¦øôÝ{{{ñÁ¾ šËå:þüüü<X"„ñJ¥%dX‚šé³;cv„iø60ˆˆp=YWõÀ¯‡Aç¤wxx¸T*‡ô÷÷ûý~¯×˱»»›ñˆXUÓ»°äÀ]a¦Wµ^¯3” Ûà—Oqþüy»Ý '&&¬V+v„âWñ5`o£Ñ�€±ÙlgÏžÝØØ <ÑšˆI8?P³ …B±XìééÙßß7¼LÌîîî¶Z­|õ™Îœ9€\,F#<z¾n, ;ñíSõÔ½‚lÈÆàŠÂ)"3ÌfÊ4gƒÝ'Ÿ|‚Ü—Z‰>Îçó‘NÊ�ŠÃ"šãù:‹Åà1s®æææjµöbg-ñœkkkF£Wy€ø ±‚ÒÒY …B¡�‚o–ñooßd2±ÜâBˆÏ.ï°n˜T¼ñÀ‡w¼Ïƒ´/,Tv¤£dbsÇ©@®Ôá¤.¼ü'e„Z¡lÙª¸®la=i HË1FKŽP;@X_5hyKì};kŠ;PiõþI C;n¬Z¬;Ä™j†EÊ©ž8¬‘¨*AYÏ5ÇWÏ#דœDy\ViØï«Wlå–––PÛÛívù[‹Ö¹ÈHï‡Ùr3Hz3‘,bOÆ„m-™Æ~¿eeÅf³‘ñ a÷///³ Ð#£†³¾¾Î Ú%A ˜`ãbMÐ16–TIð^“É0URqÐf i`~Â?Y?D7$aP!Á* Ë—ËeÌ6‚’Ó²� aGJ?}ú´Á`ØÞÞ><<d~…¶‹á;˜<ì ‡Ãáv»­V«ßï@n4^¯×ívŒŒ°÷§n2A‚ºú»ßý޲òÛßþ–ÒI¯·_ ¸¶Ùl ܽ^ïÑцÕñx\¨¼^¯Íf£.CéaÏLCXjD3MOO³5ÞÛÛ›œœôûý‹‹‹26q¹\Pqè!è?¸ÆØ¨"k—4žÑÑQn™Lfmm*ªy©TÅ£‰Ð…ååeˆmFÚ£!Àm”f³I0%•IN³Ù¼víšÕjåúa;’L&Éç�=‘…ïºT*‹ÅF£188¸²²K•ѳ¯jµJëÓßß §¦¦¢Ñ(k$£9~ž››cAU‹27õÜÜgXõÅSG@êMÝ×k$-‹êŒ gþtvíl)xÖ §ÛízÛ)®5Î"“§åöZ/•h÷^øÜûXV}ƒ5ເòz(¸FŸ² >GCAuôÁu©Ô&Š:6‘Æ‚ŒT\Pk‘`wt×»»»KKKW®\Á‚`œè¹2°˜f÷q¢Ùl&“I¿ßü �Ùáp0¦€¢ãóù¾ú꫉‰ V‹þþ~¤@%™�“dF=”i*Ëðð0L° J˜dOR»ù¯ÛQ·ÁMb6$+©[8­Â[¥è÷õõííí±N¬†é?/„È´ƒ—m6- Ð7D&L  ÷ööz½^fPláÄ@œ§óÀö™b„íM …upp>³;6¤0Ž@¹YÕÐ�g2BÊ*¢ßõõuÉ™�±€2 ÒûôéSÍfóã?þ×ý×µµ5ë˃áwÞ¹uëÖ¹sç<ÏÅ‹I¸óx<ëëëår™DX¸L±X °ñÂ… ï½÷ÞÞÞÞéÓ§kµZ p:¢˜u:‰DâÖ­[oÆÆÆÞyç®(æH&“‰‘2ìjµ‹Åðƒ‚% `ÓÝݽ¿¿OÎh0ýt£ññqR¡|>ß÷¿ÿ}fžœ4œ4wøîñ5q‘ pˆÇã Ê gÎq:uêÎKétš‹ ,w àóìì, 3wÖåË—£ä�� �IDAT!‹‹‹l¸=ggg…v¨‰–D^ (¸±Z‘¤.Á>â·M¡Óü¯:Ц¢@Ö-I:‚0kÂ4«æ%ÝSÞ›¼"´(¡w¶|Ÿ|vMÉý“l·c–×ÙÑ©ƒà¢U¬š¬ÝÁâJm8Äà¨Ã{@ŽãwK0¼¥äDüV ‘î  ±õcÃ(†ÀP÷‘FÆ6ª>7 ÃtÆ&˜‹ -D†2âi²•ûÓð2ÐÍápÀ­¤? Ï÷Ól6‡‡‡©ãô°ÔÜCWÇ:˜ZBCyÅhooZ:è7­w,†9œ@~ &vuumooƒ-§Óéëׯÿçþ§tv»½¯¯/™Lž8qb{{»T*ö�𾿿OøD___$!x‡óF(ËÌøø8†€pOc±˜Éd¢wnš¡îîîx<ÎŒ‹1PD¡Pà`{~xxøäɦ‹àF.— ŸTý5`x™üF±ðd>Ià ¯_¿.·ºà[4¦‰D†‚v2BQ/-¿ß±Íl6óÑè–èVÅû– ~yî8Ï‘P<`*°Ö€ÉÉIT4"À”‘õ7¾ñ 2´%‹$N4ñË“w…lE”kª‰½&…WÕˆhT…XT3|ut!Z5³³¥ÿ&ÒÎèôø†žz9í`9ªqomg_ýʈå×&pëìlÑoP—†¦”ëajýlN?V’<<}}XÖûsÈË©–a€ª†“³ér¹dU¸}û6háÊÊJ"‘(—Ë„÷ÎÍ͹\. DÔ4’4À¿S§N±Ç§ª2VyâèÔýC‹ÌårðsDšÍfyÓägÏžår¹‡ª«{ór¹¼¿¿O¼R[ö¿.— åj©T"% êŽhâ„*%Ú³ÙÇñÔÃ󇛜}9n Ô°[gÙ@ÁÀ 2%ëë/~ñ t.—kllŒ‘ÑÉ“'wvvÑiS\PÒööö²ëd% …BFòhOOO©Tr»Ý%wvvÐëåóy¼ö0!\%+Íàà º-¾#›Í[Éd2áË„^j ø‡áeŒÄÁÁÁÄÄ¢3™ûý~h?\²dÜa±X®_¿þÉ'ŸÀX3¼ô ¾sçÎÌÌ “Ú*|Yu¨õr ¦Àöºf2™°&œŸŸD¿†éÓ•`0Ș®¿¿ÿÚµk »Ø©4ÉÉIdh\Ož<1¼ Q@A’Édž<yB3:::šJ¥À¥págàúL&CcÍ„ûŽî6‰õˆsÍYZ^^$_\\ä¶¢öaR©ÎŽT;}±S•çó4V\A,ôÊYfVBtì µråEE«: ²-•ÂØ•<_S5ÏÔ«ôô¤>z¯cx¥IjKb–~ÑüJc¬¤©l³vàŒzråÒL�±J•dWùC敜wt•ÂŒæÍ#{=�I1ÆX[[“xX‘t²ýaŒËŒÝ27óÄDT…ðÔ²Nà Cœ¬J¶ðì(y'`}LŠŠÅ¢‘Ò¡3Þa¢R*• ‰"Yˆxww—!Àdsf&(�²Ùl½^ èïïÇT¢*3’sðó±ÙlP¤°áƒÉÎXchhÛëõ:ªÆþþ>YrØ1Rk4;;;È2u€(‰R“W>ˆø`óí”J¥B¡ðäÉ€hÃË e<yp÷Ã@°«««X,>{öìèèÈét:N|³×ÖÖ`ʆÃa¾)|C‰}&‘†A¹}S©777¡24')‹Pˆg‹Åï÷“ÂD'Êö‚Ê_-// c„œ>‰pÙlllÀöÉêv»¡$-..b¶*ÖÖ\œØŠD£ÑZ­ÆÛ`¦G[@ß088HÔ3W YÓHý~?,2¸[4—8"š9<<„3Jï÷ûaÙÉ\*•¦¦¦¸—––jµyÎx”E£Ñ¹¹9QAÏÍÍiÈîlÕÅk@¼“¹©oß¾-÷£4pìùTÄ‚u¢å]Ûç•B¡Z2…:8O·„4³)¥¾¢v¨ºêó[¦¼¶…¡í©O“¦–‘}g{qÕKC£fÐ4j²v»sª2VÕxnÍK«È•|ñlgXQ8‚è+Ãä (L؇ü\.—§¦¦ #q§‘‰ˆ Üáá!ÁíímâpiÏóù<¶üŒ|“&éÁ`ðàà�gér¹Œ¿‚ËåÂ( CPI]fÚ ñ\Ð2—°r¹\©TxNœÀÔ€L˜\ù|¾îîîX,–Ëå2™ŒÙlÚÝÝeú`³ÙÐâaªÁaÑCT*jèðððo¼‡qÊs:n·{llÌårŒŒ¸Ýî'Nx<Ü2ŽŽŽ0ym6›ûûûlcE\MMg(G,¶P­R©T½^gyƒ,œ|pÜŸ°.qéëëK$±X,N#gùD²KV3@7å~||\<ø®]»ã€m\�ˆ¬`þ³´´„{åžkãÝóðáCÊ7“~P‰:’òe.‰D£Ñ………ÁÁÁÑÑQòŽØã³H0]ñù|¬©–™žËåÂA+V…Z­–N§!SÁ‘ãPñxb+lÚ|>Ïh(—Ë­­­ ‡µV«áèîõz766àh°F²ÈñU«U¤'wîÜY\\³qáÒ7¨|CûD{r$Ù®BªÍ =X½°N4þBoч Š_·æiVw ÚkÈôê“U[Ž–óð–¦xô jy|¥ÌëµÏíg®X ™Ìh”åà¬ÁF$›]¢˜å¿b±kx™v­N~xiIÁÀÑ(±eQJA°E /ÿËhÅëõ>zôˆZÉjll ô)úé§ï½÷P!Îétš@Dª?qêTv³Ù ‰8â&ÃK[lÇCe¨€9ÉdÔ- xçAKÍf³Ïž=cI`¿ßh4À6ðP£ÖSX™Á.eØÂÓ0ðÉ4s0 ,U¤Â‚c‹ÚíeE4bœ.€“¡¡!†B¤ßðqØ{2js¹\øß1b¢a6=RpÐfi¿þçþ‡±&ŒéÈ``Þdè–@ÂyÏ€7X_ðdfî™LÆív¯¬¬`bHΘK$è?üáY¶m6Û¹sçNŸ> ÿ˜Ëì‹/¾¸|ù23¥ëׯÓnÆË—/¡º½½M{ôÑGa _©Tp­à t»Ý¾¹¹i6›§¦¦¶··/]º ª,²»ÝnµZßyç…@Àjµîîîò½°"’üœN§óQ¶ÿû¿ÿû¹sçG€ë@«ƒ:ñèÑ£@ À¢ÈBEW¯×¹6`…uwwƒÁÇãG"(W__죛7oÎÌÌÀ»té:Ç“Ïçi›ð±�œWcÈ&H”ùCÁ†..ŒªF Rj°h5@Þð‡ ðR4o¾ù¦ê ñVÐ[^Ë«ˆ¡ƒ”JÕâ[ï¡7Õ0tÌR±î–®®ùµÏÇÄ4ôàóq`rÓÎ]…&3OosØ2%Uð%¥‘LP½ýjËH8N7QUÍÌÌ`ëˆãÜÜÜÝ»w)|ü×d2Xñ±/c—422BÎ&bè`)ÇlÖ¾ÜØØ Y% a©ßl6½^/SÝõõuvd¸•A—C1I }!ð*'¶¯Sa”Â!‡ <Ú�ñ[¥žJžh³Çãaâ$®M@‘===Ä®áƒçŠS'z=ÔyÅb1™LŽŒŒ�×ëõL&³µµ±Z¿×ë ÀÁ«!”åÐårU*vš .¼gÔÔ¼ÑlÔ'pJ±Ãñ]>Ÿ?}ú4øö½{÷ƒ`+M†÷ª$nª»N‚«‰’\ ¹\ntt´T*¥R)I+ ‡Ã€ÕÌsŒF#VwzUrŹ6�À«™;A§–ñöðqwvvªÕ*re"µ14>_Ëeyþüy2®¹¤­V+s3ÉæÄ/û,áUÓ'q‰—*ílú|j¹òÁÉéù¤GWaaîùøbf¬– F­Nô íÞ–œ8³¥‹j»ªØÁLº³qµ¦é:Ç™í¿fð¹3¨Ð!œ¨³è¡Ýûîìr¡>Yø�úÈ6ýdMEíÅx•³/@–F.¯¾W*þ‹L�Ð"qÕbQ©vwîÜ¥+«å‚9c%¸ƒ¥R)™Lând2™�ˆÆ�bSÃκÑh0›š˜˜ÀGÝC­V{ôèê-v¾( °äd,NË KlïÈK¡>Ò‘¹ˆm>»uòØèqo¹°Œ·ÍfØÛÛC&ÌHÌVÉ ’W!t[ ¢+áûÒÑú�E°öà«*d¤¿1 £aÚ2Œ‘þKlœN'ë%0 Ø5*9‹ÅÂŒžaZ__tšP(„šäí·ß†§?555444::êñx¾ÿýïs†AkÒé4aÑ333€Òp~Th” H™½.86H†Ûíf%PÈx3×®]ãh\{h¡¹Þ¸f¢Ñ(µža—Édšššr»Ýårybb‚,R>ŸOÒ¤Yh�NMMÙl¶S§N9ŽÁÁAbN:…S ¼^âñx4­V«¡PÈjµBt:xà ÀÆ}ÄgÝl@nfbü–¹j@ “d&·ü–§É­'¦ªbõ¡úäKyQgSê8Z-2óQ—ͨG•¤©k~²­±…V߀f ¥}ÓƒÒ*¤ah$×r¨Õ¡’ÿ©Ã1—£±×rÌìhƒ’ôÍf¿ø»% VOí’@K¾—F@È+JÓÀ¾ 1 ˆð¹(%M—‰º\.‰DÀ¨¥u`Wˆ™>{FÈ|¡Pb’ˆEY!Ø8C&AZ ÖÁ?NcPJÕ#õ%—Ë‘ %_¢˜™þ¦fÊ#°�9 ”Ú­ú¦õ÷÷ öÝŒéÙA-E"g±X Ñ‚�³-e”׬Á`€ÕÎÊ_kT0#Ÿ?î÷ûaÖ"D�ÁŒ/NŸ8q‚áX©TB¡‰D°™3‡£¡ÁVy_¨ØúûûOž<‰ ƒuFL6› >xôIx±Š°`ãß’Š-ûȬ´}°c¿úê«`0 I\»EÏõÀ>=Ò¡Jˆ„‚8Žk×®}öÙgF£ñþýûo¿ý6‚sz €.Ô………Ï>û èxnnîÎ;\6Àå–Ëåx<.ïGȦ䭖J% ¦T*/®X,âÁn0îß¿Oï‚o[½mé�¤¯’N‚åSÍ]g*ÄϬ *!Ue¦ê[ ™F´Û˜CÕ�¥ÇNtp:þ¾¾].t;š¬q;¤=·{!MÇð:£=å54Z6Σ:Ä2°ƒ,GP!–¯%6®T|ñÅš·!:Õ¨lƒ_™Íf� õàP0 Q£ðÎåÈ_~ùåÅ‹'''qïi4gÏž- ù|þòåËårÙãñˆ3“zì…Ñ‚U*•ùùùsçÎ!5²Z­‘HääÉ“lÄÊå2ƒ6Å{{{”àááa‚ˆ©×`’E „@/†Ûÿýßÿýo|,ö®Ôbv‹Ð²Ù¬Íf£øª.Übü�.â8(RÐ(4lWi\p¿ÀªñZ__[~’>‡††x„]p&“AÐ ùýðð¥./p±v±Nð‡¿ýíoÏœ9#\øÿú¯ÿòx<™L­~«ÒÐØl6zýýýÐøttW,cl´áòrèTÐ!ᜠ¸ŠcDww÷ÆÆ’Cä]Édø„/#^„ZÀÇf³ «‡å1#J‹t:=<< ñƒkx>&“)‹!8' ááÇgÏžÅÄï÷×ëu›ÍÆxåÊ•¯¾úªR©@üErœÍféÉŠÅâððp:v»Ý6›íÝwßWxôèÑ¥K—ÆÆÆ¸žÙ+˜Íæ­­-‚¬I^ƒõ499¹»»K�ßîî.3IŠ@nˆÅ¶Ùl[[[¡P¨§§ç'?ùI À‹å½÷ÞÃ;„¨ ÞQ¸?ùÉOðNn47oÞ¼zõ*¼alí! Ò¬áU|ëÖ­û·k6›è 9”Íf‹ÇãõzBܶ Û)(¸¦Šwʦ^Lšƒ3fØVo­‡`õ`­ÆNU Ø–ÅP×|")SŠöëöl—d­7#S9½ÉTK<D"é[!ѻ뻧–Ö4šA“ðšT–ªJ|ºsçŽl+ä˜õl%u�aÏ îv¸tñøˆ1€›!CO¿ßºO½øµôÅ|X8d2øš0Ír þÄÞ ‘H i=N¯­­A"J$©T ò~¡PH§Ó° YoÌf3"K]¥RakO%eÅ¢Èööö'–ËeDUX|³0¤Bûæñx€py&Ó¤\.—L&{zzvwwÉ?�Û„DÛÓÓ“J¥àkÅãñD"e Ûj°kGà­vwwÏÎ΢Z�hµÙl8N @éÁ/ˆv ÅøÞÞfv|(»ÝŽƒ7&T�ÂPEIñÜÛÛƒÒ“ÍfS©- l®ƒƒƒH$BŒƒ1/òûýL6¥*377Çô›kˆdµZ Ë æ rÊP…ÏEÊû_\]†dCñŠ,iápÆjoo/¾ˆ8`£Ñ S¡…íïïw¹\ÓÓÓ“““ÈæE$¸¶¶†'J8f2ÃkýêW¿bã÷ûGGG—èX‡hûNŸ>Ýl6§¦¦VVVòù<nHr‘‹Óé:b«Jççç!°R$â—#£O>ùdccƒV^5áàà@U„±ÕZ’…:̱ hÛüʹ·¼nKÓ¶–CžvQ?EcÇQüGI¯l|4éÍú'K:¦`A-…Ç-›²vð‹~<××H5=£æ  Á”üNqÔb�,E_,X%‰¾¸MOO_¿~ýîÝ»™’3‰º{÷.ÕŠþWÞêèèh&“q8ôû~¿þ>£ ”®!rª9“€ª€‘ÈÁÁw2âñx$¸æ¦¯¯½˜¤]<@b¥L„ØwK‚"ð±±1&Îà 0è$ðûÛÝÝ¥§ó.ZYª·M¡P@RG3„P�ëZÐN”\ pBŒv’s &Oh6› …B,ulc÷»ßáÈ< „N<ç4¢¦¦™àTmèØ,+Šz¹*"‘Àòùóçïß¿?55ÅtH¾_^®ˆ–‘LS0rE1u™ššRé­8¹Ýnhf>Ÿ6/!òI 圈¤™±g©TâÍ£è'g-ŒÇㄌ²T3>%Ì®3™nÙl–o¶Ùl¦R)ΞŒˆá¼víšÊæ4SL–{ûN#Ë ‰¿UCyPD…¡®‡ÚM–ÚÁ_YZNÔÕ¤áã |:¼ŸcŽª:…4£¤×‰1´Ëmæ+|+MgóqþŠÑ¿þ¥5èB;# ͘RÝMÈägò{¹ýd©�”–ÛÖ;5õƒVÚa¨@%sd¶®TyYE )q÷F£Qê‚G³iEæÆÈ›)0”$ǃ؊½Åb!MVèÐÐÐÿÏk~™Õy”RN ±qø,•ËeX¡¨ñÑØøÓs€@H•Iñ8âÈ?¯×KÄ)õQ¦ö”]ØMjDÒ�O–üáb±ˆ[à˜âQéX™€1 / Ÿ!õÿb@$ì/ÎÛýû÷¥‚,oƒ˜Íf°VÐo&QÀE¡PЈeƒ €UÚ “¢IÖ7Ë ƒˆœÕ /—(=.K‚ì!ž<yÉi=Ãz!8qž9ÔJÌSY8σƒˆã j,3œg—†‡‡¡8ób%ç„ã³È¥.YoXEÝ/jö×jê‰Ü§âm£zZh6Žz¸Q¿ók¹`´ŒÞlWÁZæÌ·üo‡£s·­ÇK޹6ðÃÏþó?×Âpü*ßî‡-Â1y±jü§žR¦~ßšW•¨ ‡U³ÅÛ‘ÌÀ�1F–›“†= ]»vmyy™„w6‰H‹a‘\åÊ#Ò.°eËOŒ‰¸OMMݸqã³Ï>£â^ … ½¢­{€ƒÄN“ýòøø8lNêì‹/ð/ÂЂGéÄÄ‚UŠ1=h p4Soü´©/ûûû”Œ¾¾>€åÆËŒàa"ÁXeèOëC½f‡F¡NƒÁ–R–º³gϪRöï̯€g¨;@A8{‹¤œ†/?œYc±¯+.Ðø³Ígû ž#ûtÙ Cb¦„["äéééÕÕUu«Ëe933Ã'•�Ï"ÆîÌ»ØøS^…ãÀŸH^[[›˜˜ í@žÍ ]7¢äÙ¬Ê,·ƒ3TÆbFÃår‰‹8sj.–?då�/yúôéàà œ]*;¢ËÞÞ^LSär¥E¸qã7 ·'—®ê.%µ•OŠÉ17µ¦‚³¸J¯)*3U%ª¨@oÌÓdngï¦ß¶¾r#¯™)µ$¼ZÙw·Ä½õƒýìD}!}ÇðG‚Ï* Ò.VT¹ˆLC$!ŒE´w@½B„ÕX iy²ÄÝ©8 1CtH\¸QÁܼyS5&\\\ŒÇã_~ùåää¤úê"N‘÷öñÇÏÎΞ={ö;ßùƒþ¾¾> ¾óïÆÿøÇÀÔÔDp3ûè=z„΋¹6CŒ!÷öönݺuñâÅÍÍMvú‡£ÑhŒŽŽöôô !›:yòäßýÝßagD»0>>Nê=îC(~!áPñó›ß:u ƒR—Ë„@JÚ7 fJ-éz†È¨ÀPŸ1ÞÝÝå%h& ¥‚@ðTWÔÌÈu©V«kkkââÈæÀÀ�èë‰'x-òD‡‡‡a+URòبÂb Ä;§éI§ÓøÅ ø”›››D“ïöÿþßÿCh688˜H$Dò [ééÓ§f³o \¾iP0åfÿ‹T³Ùüè£Þ}÷]Ј‡Z­V0 üÀ‡††b±Øûï¿ÏL¦Z­ž>}šz fpåʾ>–´ &“éƒ>øÞ÷¾×ÝÝÏç»»»¯\¹òÑG!Çò„QX½^Ç¡Äh4†B¡|>OQ?q›h÷ •áˆÇáK/•J`àÐÕH¾{óÍ7¿õ­o[Äuz_«ÕçèêêÚØØp»Ý@ÍP$À{v»Ý|㕇ÃáK—.¡t¹rå ÆÃ¸°,--!Lcéҥ˗/ÃÔàv&O—®‹çð+îV„¨؉§²&#¢Êòò2v÷‚QËý.¬•r¢V¿Û·ob«PsËÌN&Nýªqžò¢„QËÓÔÐPUû¦@9ˆzd¡ó¨OÓèÝ^øÜ.b¡Ý2¨ï•PÕX¢t¾ázê.?«}SË0#=¤³ô‡ÿÔ½ryŸ†}, ‰á¥¼†øýþëׯû|>6ãH ÐÑ5Kz”ê¢Áe‰D¦§§amg2Pë™™YÕ———ÑÙl6¶7nÜX]]%íÄáp¤CÜÀl¢ãñ8@o€ãããlôòùüÌÌL0ÄØnxxXTÄ¢D£•Ëe4e6*Ù;‡‡‡d#kØØØ XìÅp«Hä˜8±UÇç.N7‰‰ �g£Ñˆæ…÷m*•ZYYaypp�O¶Ì²Dö…~äßëõrÂWWWY ½’xØýùùóçùŒñx|sss~~^eÙc8 ™«à7 ÌŸ9¡Ïç3™L´›¨‚¡¢a^"@«°“¯]»ÆK€ß †Ï>û lƒ ¥Šunqq‘YS(bÃ{÷îÝ@ ÀXŒN…S?¸�õzÝétÒ€V«Õ±±1Œ¾QSŽ¡ï#÷”–—ï×h4‚rOMMÅb±D"š)e£Ñõ=Îd<šŒh4Šx" –Ëe)ÐQ‹ø@mÙ9ó R+ÞU˜Z \Sm4R�žP­Vy޼¨¸dÊ“)2‹Øäh: pmRËZ;‰˜ªÆÐ£ÊòNgQ‚¡UšÛŸ1Á­Ã¡5ïCŸ¬©ž þèO¨j "<–¨CË�ƒ.«OÏ1 GVãýä€âº%W§X, ”5ZÝH$r÷î]ìò±"’yšG¦™Ìˆ�.›”]¦¸P¤.}÷»ß…«ÃTwyy9ø|>˜”L˜«@5™ŸŸg¼ÀÎWü Èg†C)6Dk5 Ä\J6ƒ4rh’ÉäÁÁÁîînooï‹/ÐŽAµZ­Ì85\A–$Ímww—±þPãQÌ2Î2âȆ> ,//ãÒAˆ#\,”·ñxœJÍ$Šw‹ÐŒ¢V«MOOóçÓb±möèÑ#9,Bù|²Ή²„óÅñLêÝÂÂk]902Ê’jµz÷î]ÞÏçc°ŒÂQeÚ@WcÃ<‘ßèè(ÉB¬Lƒ%c¹\N¥R¼=L^{{{ý~?QhˆTÀTdý<g‰´eddäĉ‹X»ÝŽôÏf³¡[FY­V>|ˆg0“O–F¡®‘ûÄĉĎb±H +{FšÓÓÓè@!m«”$uǹ°°@T"zŽ+vuªâO-ʸó8‹®¤r¶T–Q%(îÂ6­«:ÌQ3¢õÜ$•©øÊ]²ÆéÕ¾”|ÆãìÑÕµAhÖGúgYZVùÎ24ÕŸNú€W&ÞÉW¥Ïtk·DqÏè—Ÿü­ j$òuªA¯¢‘ÙÛÛcË–Éd¸=úúúîÝ»G[ÀE ä Á aש:~®fnBò3™ŒßïG_–ËåàùŒ‰6u*‰ H’;)¯e4¾2‡.v�� �IDAT õqÅ‚·-€3D˜o2á 4M >HÀ LZðwÂÆÙétŠ:šÕ&Å:f©T¢ aZŵQ¯××ÖÖH]†û¸²²BÕ ƒ|p*‹Ûív»Ý±±a—{\Ç©&‰DâàààÉ“'ðôÑÓÐ^lmm1òfUîïï_]]e°Ûíò]3æ¦Wp»ÝDøÁ6v¹\wîÜY^^FñKx'écìÜ!pÏÅÜ”Om4øÃj.$¾G»Ýî÷ûà`‚ÝÓÓãt:Ïœ9C´Z­^»vBÏÚ†›P©TŠÅb„¡ <*E¦yާú¶»»» ‘…§R)> —(‚üvee¨&N£¦DÕÏJL�ÜÀÀ€Ûíöz½(¦§§C¡ÌåeRO)\\\ä2–-9¸d G\íò¹sØôTxÙáIå9zë™îpg„mϺ¥ ‰Ó5Ë.^-níÈ£R¬U?iñu>N]íÜRèËÚqs¯Aà¦AÚ Ö¨* šLiÜ 4ÒæbˆG4ú½2Eþð‹/¾P‡k2¶“-¸óDÆ�ºPí´82¶\"mCwûömzçÉÉÉîîîh4úøñãb±H‚›OıëË/¿d¬Ì†>ßïüø±Çãá†988ÀŒlhh(›Íæóy\ƒ°yðz½˜!ýõ×TsƒÁðøñãééé¾¾>@îvÌ,³ÙlµZ…ÉÊ0ý7¿ù ãàƒƒÜ͸“Á™ÁÞR÷‘A1öaâOÔ©¿Üv»½§§ž’ÓéÙ¦ó€Ê‘4“„ღF£Q,=Ïþþ>lÔb±ˆ�-^.—‰ÅbMÎI2™2ΑS óùüúúºÙl&D XÅl6Ê ÇÙzONNòöL&ÓÄÄs0L§Ó@àG?úч~X«Õb±X2™õñûý»»»Á`µ ](1ZE§Óù“ŸüäÂ… gww]ý"Øõo¼Q,ƒÁ Ñht:²Hÿó?ÿó~ô£žžžd2ùüùsÚ»d2¹»»;<<¼ººzîÜ9‡Ãá÷û×ÖÖ0V±Z­]]]äFðUîîînmm‘âçñxHÂ1›ªk!Aª‡#›Í q(•JVq-áÁ‹ÅÞzë­l6»µµ…(Ð…YßÀ8Ìiäøì‘ÝÞÞN§ÓÙl´¤y=vF£Q òØ�< A¥œýêW¿¢`)ˆ¶”[f~~^ sÝJTUåÒ¥KFCîJ)J -¨}ÀmÆñjÎÚ7¸L ‘Xòñ¶Å<äRJ Ðà rLM=T½>[ÛUºå¿×)p;¾NÔa-ý´5 pB¼m ­LÆ5FÙúŸ*‘Ó(ØÈkÚ+±è"¥GEô„r¹|ýúu—ËõàÁƒF£Á΂®„Ój𕽽=L˜éÀ<eFƒÁ`*•ºÿþ³gÏxQxD ^(”{{{8P2c™ššbj2™"‘ÈÆÆ£ æ¼$H›ÍföËìàÄåSRvý„h2Ä®Õj$!³÷'â†í?E–if\¬ìv™AAòÙÛÛc×L¬YÁ4"c6™LúññqØ;ãããÌ%zzzðµ` !¡7Ä£Ò ù|¾©©©ëׯ o-v4å³ ²FÒl·Û½^/AµZ½qãœ^dgg‡Íøââ"ï‡ïˆmo"‘‡Ã`H2E™žžv»ÝÑh4 E"²˜ãÍÍÍ‘GMÒν{÷\.×[o½Å¸ŒÑÏt8¿üå/á\õ÷÷¿õÖ[†—ÙM„¼ž?þí·ßƒ‰Dbbb‚&€¶}˜ï’å@òÄÀÀÀ×_ 7ìÙ³g™L—\üékµZ&“Á€Äáp`oRÅ•9==ÐZÔÆzee…^„¾„,<¾wî2N,ÒN¶í,“²“ÕLNp=Â<\ÈåLw-‹¸‰HÓ�‰™~ /¹ ²åW_¨Ã˜Z%1ª)^íFÙ2pÿ"M¯ Ttž¸¨Q-!Ø–óùWÆä´l¤^ÿ(éøŠ ‰1hý¦GŒåAIÈ‘&ÞvíÖaÖ¬òWzøš¦•7IVæË€/¤Î¬(ñÌšåz’àަ¾s™TPÁù·´´QujjŠ}ëää$Ñ+0Q¢’Ò*qŒhe©•Ô,îgÇFFF(C2”Ïårv»Ýl6ïîî †l6‹wEüèèˆáÏA! ÛQdîyÈ'’ìvttT©T°8¥ìÂv­T*…B@ z1´gÿNš[&“¹wï<^‹s"WqP.—Ëçóxæp3ˆc¦')•¸À²&Y­Ö¸ÝîÏ>û¬úòrX3Ù0™LápøpðX^hsssuuuuu5\»vŒ{ ¿ß¿¸¸Èx‡¢É·ÿüùsì+666€¸‡ÙlÎçóLŠ@kØP£ÉUeÆ’�K ±,ùLá873gÎ@ÍR* l5s><<ÄPäÑ£G,´,“Õjuuu´`tt4/,,€c Æ4©ÑhЃ2žžæ›e�ÈrN´œ:RžŸŸg_Åw'ÕŸ¬rgñ³TyU-3M™ÖW©éú” ¦eµ{ ­Ôú;;¿©F‡}s‡?ïü·úÍ´>ãAð?IÇÐ!§´åëǪ]²«¡U©¡},sË fÍPRõÉR¹ÞMW}'ò˜Q£~Ð/Ú’}ãÆ ·¸%¬pqfÇ E]宀c3á¥8Ò:ììì0ä%†£=þõ«Ïçóx<ƒƒƒûûûp@%o�8<PQf±~°Gf²T©T†‡‡APº»»s¹¢TÍ’ÛÎbÓßßOì°s8ûÓÆz½Ž´éVOOŠ„r‡‡‡X׉‹à9\ÊʼnqFâ¨7˜üÒ`¡Î@�È’€)?ЮtÃ8â óÆŠÅ¢<(Óp” bþÌI–M%z®&­ó…ŠøÑn·ß¸qãÎ;¼4:g¾,z>¿ßË)½B"‘Ñ¢hPdõÅý œÙårÑÛa–Þl6‰bìéííeÊW©Tl6®J›7›Íd2IºšAäLíäÊa³\ù‰V†òY­ÖçÏŸ‹,ŽŽç—¿ü¥Ü†rïhnaQ'èw{Áð+az/©!»‘+é‹€F¬ Ïäñ;wîHÊïÿ¶Tv(€í$½ÇÔHÿo_úu*Ÿc#ÞRòwLŸú É„ç8ïJý¾[¦ë饗کBƒbàÚá°ŸÜ0-mš`¾‹°S´N¢Ú§�^úAªn Ü{b¡A‘[WôtT:`áz½N»ÀÞŠÉV¹3ïŠ*Cô!Ñ3cMšL&1se‚/tX)LŒûa²‹rŠãCOÚßßÇ£"ŸÏ#²e# †Cñ‘qãÀË',}p€ƒ>Ý8ؾXüs6ˆ7à˜t`6›­^¯#ôƒp)sss¨e:¤Š{777E˜†•ú= FÊW]9ø•ú…òWœäÁÁÁt:uY`�Õ¬–AµZ={öl±X”Èh–³gÏ‚}xxˆÍu¹\¶MÀù9uêoŒÓ;44ØS.—c±„¥ÕÕUI)WÉ"sÿ`愃ÒTѦ ³3Ož<A[õ–ô:q‚Qoq)V b…È'~±ì¨ôEæîÝ»ê[†¸t°¸Pƒú7?Ã?n§U>¾…¬.²øµsÝhéîüJoŒã/Bê“_§»jKô£¥e ÈÖ4ЊF.§ù[ù_,5i«ÁˆzªÔ—O¦ ,ZÕÈ%Ÿ` >†üM~k0PÐÈ“Uጠå‹åÖ­[@Ù€i7oÞ^Yœ{ñö€ÚØV#8¶ÙlÙlÖãñ¤R)Éuq»ÝOŸ>%~ ¿<°k†òõzýæÍ›³³³LùÙZ¢­Ã[›´zÐ_~ù%A•mëõú‹/vvvà´ÀLŠØÚÚr:‚v@c'§Áëõ¢›•0",óà±-¥äõôô<~ü8°„¾¾¾\.·³³ƒÁЀy­V³ÙlN§°4‘H`ÂC((à6Ú1°\fDx ¢ç°X,CCC($FFF°ÓØÜÜäÉÌÇ._¾ ¬MÐÐwWWJ=‹ÅBÀ'#5³ÙüÉ'Ÿüô§?M§Óv»ÕP”bzëÖ­K—.¹ÝîžžžŸýìg/^dwÛ (˜åöÁƒàÀ]]]�BØ»noowuu±ã†@3A“ äp8FGGÑŽ`ÝÁ7‹çUÿ‹/²Ù¬|œÝÝÝB¡�]ªÙl>þœQ^¡P wñz½Dx2º<::r»Ý|ðÁää¤ÑhDI1—K~Q*•‚5L&-Ëþþ>L´Š¹\Q},ã†:yò¤&BÑn·ONNrå{<žr¹Œò«T¸$/^¼yó¦A MûðÃC¡Ð¹sç>ýôS…¯^½Ê299)uÈZ”ªrÿJã·r;ó4Þ$ûù矫Xñ¹sç\.—„»sUci>‘¼ ÍAT®ÍíÛ·Qæês-5µKcë%uzáðÿø¬‡ŽÕQšJ9Õ0G[ŠT¿C*Ô°‘´hÆv*;X$uB艃fË/W*ÃZå­ªÜYý‚/(”mU«¢î€Ô!ÛI?ÁäÚn·£ÉZYYa×S›)ßb±5Óçóüf2™ëׯ[,–ååe¶iÔw###H™Òé4ÔÆØýÌm�À9ÅÜ¢Z­’t†p•†uˆ™ƒŽR˜ŽŽŽP23€J§Ó¯îînxý¥ðÉ€}oxŒÀˆ†0)Édšžž–}=c+Î3>Lü%‡&€.çìÙ³øR šÉ-?D"<!0"D0 ÏjµŠhüY¸båvûöíÑÑQærwîÜ™˜˜`‚ïr¹hìR©hÊùóçF#¹oTX—Ëb„qPooïÚÚÏ¡»BÈV¯×³Ù, ÜÑÑQ*•"©¯¯Ïf³q‚©HÆò™3g˜ø ÄãqŒ¡¸HKº¹¹™Édù\Õj5’Ùívq•~¿°-ŸÏƒT#”3›Í333¨4øøÂæT¥lwÀäÔlp>±677———Õy Àžfï Ñ“.ǧÏP«Ï×'ÉkRß&ÔÀ ªÝg;¿<¦jyyYny*ZúÔƒ¨§ƒ™ô+¥fzeXKyÝŸ|néÝ!uPÕ.gu(Ib›Ô´#Q¾hâ5¤pëi�êW«OÓæBQõhêÕ ×4ÏY^^FŒcøCë]õgõ SasaY iɬÅb¹qãÆÒÒÁmápfùCZxÆî4é X Þ°Õâù‘HÄn·TY,wvvPïììx<„Bºçhð ‘€|2,b×ÌÆ¹T*‰À˜ÅÀd2I XOOOWW×ÎÎN©TªT*Lrp Éd2@ÊH$Â4ì׿þuµZe®…xª§§'ŸÏ †—ÉÏÊL&C“E·¿¿�'MXI,®|.ž|AfAŒª˜ÍÏÏOMM1bâ³L¦Ú‰±.©aü » 8l˜®‡ÃaŸÏ5�º0…žwË`Z(Š&ý$ZJ3Êv<t™û{½^ÄhxOAÅ':ò1±ÛíN§“#—ËU*•jµúôéS”øj~ýë_ONN²6çr¹ééiT2\“êþ†od>‰”Ëe*õüü<3"v0©Tª\.ƒÏ»Ýn8áb¨²>™õ«õW’Å\€³ÊÆNE&d,£ÙJÊ(©åÜIîPX z„V¶›r;k^5ËÊ2u`¥±3RÇ×z¹•^áü¿R2KijgýÝnyxÍA=fMjü…:rQ?ƒèôOPõ ˆ!T“%¦0ý¦ÆÍiyy9KRÐ… äkV[0@ÈHJä<¢RŒ‘Î"}¸zõj>ŸGñÅ_ˆŸ }ëÞÞÿeÁw¿¤a´Ò2}fŒÅbt \§OŸîêêÚÞÞÆÙ†‘w8vÌdc±ØÒÒÒ?üÃ?ÀŽg�Àx!€ÃáˆF£®kÃø Z½^gæ³µµ…ýŽ ===¸h�*Øív²äÈÿCUÇÆ—éðð÷!b¥Ïœ9CÔ(ÜM *°ñâE½^ßÚÚòûý›››xìtuuíïïcøÃ¸§¦Z­699I0€ÙlF,ç ³Ø`0øäÉšܘìݾ}»V«ñnÑŽ­¯¯çóybj˜òõõõñ6$H ~ðƒ0óyï½÷ªÕê;#*q8©;¸E12bBHh™9¸'áHHĬ­ù€n·ÝŸÕjE™­ dÖoÚ&Š©wwwCÀ%Gé_WW×?ýÓ?…ÃáóçÏã"…öM«çææHÅq:ðP»ºº>úè£÷ß%WòÞÞ×¹¬— 2™ oÕétòrçΣoã»Ü)LW¸ƒ¤lqÿR.ßyç‘É XäM22By�Cš9Æ¢MõRk5u|Ä]‰�!7²FÇ )\¢—Òø±æé-dŒ¦qŠ“,x¸¨+ÄJ­?úú©Iê0ê—'´ êù?rWí°”9Qñç–^­í²ô ¥ÎŽ�×zú“>=BÄëªpZ/Ú2ÒÃàôLv¾ìRåi’!,À¦ ®ôòXl” Cáó@€Á+>ž¯@…ò4öæ] †û÷ïÿÍßü ·ª…ÃÃC¶ö#Én$ ­Ùl¦Ói§Óùüùs°eñIm6›$ Ñ‘ÇIFr q¦Ò¼sqK5›Í…B5è=”r·Û¶Ãáxøð¡XL s†Ÿ™5 †ÏÊŠ*·" IåÏ[–�W5l’ÿ ‡Ãør‹ŒP^WÔæœI¾‹ Üaù!bÈL34::J†(Œ#ƒÁðäÉ“©©©B¡àñxÙ³+'ꀨ tˆõzµ91ËëëëØ`ÐÕÑB1öáêbét:wwwc±˜œÞv"‘ ÔAM Ò„q 7^�868?–¹\.‹IF‚ÜeèÆ;Ü&Å¿ºó=nhcC­a¾´™ƒÜvNˆyeµi÷ÇñaÕð3 ÇHJ>NrA;VÒŸKÇ  'jù¶ôJ =ü Ci$æ-'ƒz{)õÉÒ(è…0ª,Eï`¥ÎõTõа ¸ì4L;ùC*AJ˜ 1y”÷à ÆÅ´´´DðûâùùybàĬMÕ|°¡N$ćÀ“Yæçç›Í&?¬¬¬ð„•••žžŠ#…Œ"Bàe&“ùîw¿›Ïçýë_3|'”ã7›M!¡ÂŒd#Y©Tð> eŽM§W NrÞR©¡žàÐL3™ÌÊÊ –Íf“ψd6';eÎçÎÎsüóçσ[àœÃˆá•|MØJ#–ƨƒì9«ÕÊZÂ~Üívó¥¸\®p8ÌR$_ñÜÜAlÉùŠå;r8¸ãõôô ÒÀ|‚ôozb±8::êr¹Yr8¤D0‹ãId•'+ôh­Ð*ãn„3îÿ×ÞÛ…Öu¥iÂ˶ýûÈ-ÉNN;RU\ØÄ ƒé Ò }Q4ÝíÏ€úfÔô?C_ù"s1º·.u'fF º4˜@3„.(¹ð‚´¨T[UJEŽêÄŠåDÇ–l)òÏwñŒžyõ®Ÿ½ÖÞG²ÒµÖ…°¥söÙgï½Þßç}øÎßÿþ÷­V«££ãã?~ôèÑÒÒR³Ùœœœ¤*?¤È†W<wîøòˆÂa8‚¯‰Q5ìˆf³‰Í‚Ôµp'Ož�µEùÑÑÑ©©)^%VVìG±XÚ¥s–}¤e@õ†cÆ¢ïtnꘒ½=E«&yín*sÅ«9 øTiHup}%}{h#¶tòR{ÈÙ÷%ywa”í*›Š›æ •į" å–ÕI²055533ÃÈÝ7”7==-#r¾Ò¸ókâ°ÛÛÛ˜3@ Š=m¶1úúúäÀÎ7ººº›ÃKÁVÂ6¡®]«Õ.\¸€’ýèè(ªÛ�B\“S}}}“““€ÒOOO/.."¶¤ê˜çÏŸ‡abRÊ”¹ðz Ù~ûí·À&}ñÅTp|ôèÑ—_~‰ºüúú:«˜žùÒððð™3gÀÞŠzJ48‡­­-0¯ ¯­­¡2ŽÆ/ª^èÍÂÐÃZá<¯^½ŠÁo^®µµµ½½=PP ÁÔ>~ü ©¸2¢„(4¾øææ&Z õz}rrxèçOOOc¤ î5úL¸¿Dg4 O|ÿþ}Ü8rE¬¯¯_»v £!˜[FRE 6™ÏŸ?ßÕÕ…ô¹ ¼;2züø1Ä·ÉuòäIdEÈÆXÆÕ«WµEŽ‚ uñâű±±þþ~J!BF)_ƒ 3Ïøj á)GADƒÞÉÀÀÀ¹sçVVV°¿å�‹ÛÄI7ÄXÊäÁ¾ËƤ éì]¬,€u¦è¦³Øà6ð¹Û¨Š‚=ÂFŒŒ ^/p޼ÅÐáÙì¢1_óH…z“Α´@®T8BQ˜u—: DØcnN(nŠ„pòVÖ1èÕˆµWJ¢ ²-‡!ä® è Ž#?‘ú\DâS2LNùs|'Œ)K—.½öÚk¸œ777GFF<x€âBoD‘xA9m�À™XÑgÃãÇWWWß~ûm¯OŸ>Mé͇bb Ѱ›ƒƒƒõW5??çΪ¥’c®ÙlJEL¼€ò,@Ë`¦ óõz¡+úóˆˆY2b^øÎ;ïàkBñ¥-”D:::îܹ£�õ€‡qÐm|Y¬¼ hÅ£=<<|íÚµùùyùI¥Ìj4 €…Î;‡~:+ ¬‘ ÚàÇÆ,ÂÈÈÇ¡8ÔÛÛ  …ÚNÙÛÛûüóÏåà†þØÙ’P:~w©"‡NYMRA¸2Íå¡8*Ìç\M·©®¯DÙ–Ñ)¸&®@JÎ. Â5°Bsgkæøæº’¦"_Ÿ4Íp(¥¤�¥¸}Ã$xK9^‚DÎÍ9ð­@g^fŠÏŸ"륄 _Ìè†Ü¿*[$ L2¤ Vq ò´É?ŒØ!ÀNHXzÂk€ô@‹'C:l?üö¨Ùl¢‘�:H'º±••€_ÁŸÓjµž>}úùçŸ7›ÍÏ>ûlbb(FÔ[qommíîî~ÿý÷_ý54žA,П~ú)fŒÁí³··7Ð"=yò„W ×}‘õõõééiœ’Ù§øG¯¦¼ÙlÑË‚uww÷ìì,(+:;;/\¸088øøñcÔCÖÖÖ@Ä X¸¼ÀÁ+ttt,--­¬¬@ããÜ´øꌎŽ"iCµ ÃÀˆ¬Á‚nöU‹á!vww¡q!8ƒÙÙY ¶ãàØÞÞ²`ßo¿ý¶¯¯ïÌ™3ƒƒƒ'Ožl6›H,@á÷ý÷ß¿õÖ[­V ‰.ÊDh‡\¼xq~~× HÙÍÍÍßýîw¿ýío×××ëõ:AÒÛÛÛY,{]êñI+?55511ÁBâ 7�cöðáCd„xzûúú"�Š*ó{¤’¦ŒÈ%ÖŸ%²QU¤}±öÇ‘ÕyIÝdþ—¿'¥mî”V³¬g(˜>„„ÙjnÆ"SŠô"I^áÐ3†øYh†b¿q ì)UÎ@ âãÆÌ ‡ÈdÈ]/ù°2Œ¥Î'Kå×g¬$“4!¨† Ç‘Í[6�åð-£Z¶O±@¸Ä¶6x P&Æ³Ž°‘ X`] %Äo›ˆH“$ ¾€…Ä©Ùçû»{÷.šì WŒœ�š¦—/_þüóÏñ½{ਿ3)øôÓO9…ËV*‚ �uvÀ«€D"% .jñ€i"ÅAÚ8°)HPPŠ!×µWÍAÂ>„É4š¸SlGã—¨’¡½ FR´¦QèÇhµZo½õB~ä�ª¶Z-ðÜ=þ'–‹3gÎ|÷Ýw GÅ)! Ã'bX¿Äø$ BŽ^ú{g± Xv"z™˜Êù™ËÙ ¼³#µÀo‚ ¥æC.þí¼Ab1$ÊÛ˵Òò4åÃúÁ¾ÚƒÍ´ÎJÌ$éIh¤3¹qã†Ò|ns¡ØOëq…ï R†É§g-a¹Î.9q¨ö‘³½Á yd¾…œœ$#…Þ…%׿òò2 Ù|ÙÔÔzÊH!Ì‘„nÔà%·ÊÐ'GÖº»…}}}õzÛ;wùß»w^½ÓîîîîînT3ÐTìîîžœœq)z¿“““ˆIT(*7›Í®®®Ó§OoõîÝ»gÏžÇ5l(¢ÝÕÕÕ?ù“?ûæÆÆF__¼BWWžAÕ /DÄ”¹l4/^Džã¿ø¼ZÊè0ZìëëƒGÁwû¸êàÆ€øÄkÆÇÇA†É5œ'±öä{¨Õj@Ãñ÷÷÷CfffýŒž€ôøñã·Þz %2L¥àr¡³rýúõ'OžHJÕÕÕõõõÇoJT.`¬§N &60…ÞÕÕµ¼¼Œ`±pn+++]]]è9_¼x±ÕjýéŸþéÚÚJL÷îÝÃX;¢{<{ F)¹ð¤I*i<·¸¹èØ3(AìŸ Éñ5*aöåÛ¸£eON6œå6§Sá„)•×T©)»ŒÎR¾³ a[’pŸÀ— Ø<zRM9–SMÁX³‡à|Õfžd�� �IDATÚÑ×rè=†@c§"ׇÍ+BO†s9Ó†B‘ØYÆ5*„‘ 9V¥ù¬£ŸüD {•‰¿—D[²RÄvß‹½¸y]XˆG`ë@2ä1¨ !`�ËhѪø$ÉiÃŒ„A"K. ÍÁ¬ˆõ#€…5ÜÛÛ NEn (¹‰HšDlø¬�ÂÙÚÚâ•$a-®ôšÍæ… ÀÎdA¤b¸#hŸÀMʹ\ù5i²åœÀ²¨ø#¡ÁoðQ˜2ûM˜Èƒ$êàà`GG Éׄ¯�e7à…"œ={^NåáÇ[[[?F^Gjx B÷éU.\¸�A\Fhž G4Hõ*<DŽà¡­%Ÿy{ïã½HO%-sÙásnOÇVä ( 6€#?l¸ˆà‹+Mæ„Þ.\ÕÎT͞ijûø¾–€¸"`NåŒf_PíJe%‚ŒPvJ�Úg( ép|ŠL1/n0°’±Ê ÑAØ«ã$ UZø’g�t¼ ÁK˜|† ˜t$ˆ|ëõú­[· òNþ‰ÅÅE¤€¦ ÇÀ®)!¹°SP3æÕ†gÂGcîàü~ccãîÝ»ààëìì|íµ×`ƒ¶¶¶®]»ÖÙÙ¹¾¾>88800póæM |‘wagg :á0[ÀVÕj5xÀ[áÕ ”À[véÒ%|Í»wï¢5R¯×Á¹ÔÙÙI£;ˆCAÚèÒ¥K{{{äÅÃ7⃄VDww÷;wRà»ß¼ys||üüùóò8þü³gÏ�lg "ôpÊàRã<ÁS-½&DÖ ‹€ß�£¡$èd`�It“ÖÖÖ<xÐÕÕõüùsðg B!XÜ,hx€YcótBÈ)ñLR[ È7Ž ó{<iÔ¯ÝÙÙYZZ¢ô©DcOMM!·c“%#¦,X³4==#³ÙæP8u_ @ÂFesÑnÚoqN&ÛŠªä`£ÄJª+Í·Ó:Sg Ö‡­ržÌ¡ë1¨ó!c‰_;Ý ¢»0 ‹`iÜy¥p_9|/©25¥Íà¤i’*ö¯”ƒQjŠÿ îÁ("ˆÍQ?7 B~\F£àNfåxtŠÈý±ådž!)€æææzzz wƒûmIÔ îÝ»ÇâÕöööôô4;Šèoã¿r{à÷(V@]FHG0Á€3Y]]=wîÜüü|³Ù¼zõêÚÚÚ7@úÏ,®?¼##Pµ`mÇìË Ã·Á«±Hõæ±±1‚ ~ýë_c" ´õz}vv½V0,mooúé§Hêõ:ó!|/˜TTáöàYûúú0t‚>ö¯~õ«••ø9è³"Ã‘ÇÆÆÐ0h6›+++Ÿ|ò @SðpøýÎ΀8þ ‰É À 2Ü ¯Á„˜ï0'¸±±:TÊÁ†rõêUÀsÁ.Ų'ï5Ü”sH¸2::Šé9ÚPÐc@§J·(“Bl»w é n,a©ñ“ûš(ðl" I˜fmšÜï² Œ=+é7”©uVªe¼K*¹Úx”UEÄ6TW¥*3§‘Iƒ9¡žBh­º²¶¯³uÜxezøÐJöÅA$—:oOC!ÛTGAž­³\hw¼U‚£´”)œ"²Z­†®,‘ÝxãÅ‹Ià Ñ1lBM~Øt“è¸Áà*è$�“GÚÁ�'CzžùÍ›7ÇÆÆ`àÏx;pNŸ4 ~kuuÑ4ÊÏŸ?ÿñŒ�öÂ… à݃ÀÂÂBww7 =Á¯à f³ÙlµZ°&ÃÃÃ/^„KàœsFš˜€ÛÞÞ&! ˆðdHÛÓÓçèè(»Fcyyy{{Æ'fö…z¸ÃÁ†„××jµ³gÏž8q•¢ííí×_ýÒ¥KkkkøšÛÛÛp{¨×ííí­®®îíí?¾^¯ÏÍÍ5 h´!“�ÿ®ø«/]ºT«Õp@<ˆñQÎzòä ´KOž< ¬4·÷öö666¾øâ d„Yëîî) Œðú¼ÚŒT( Ò@Ñ 3‰d®@"#4TÇ@Ô/·’T¯šžžÆÖæ<Äèè(7àI(±JD¬œ`ÅÏÞ¡tj¸ÌŽ—e˜(aÇ*úvÖl£'£CVœÍT{ÖDˆ<û¼Wá+#=ÇÉÃÈ Â_Ìá²M°êúR"Üv 4èö\¢ဉsN$ªº–“ŠÝîó¯�äÉž'#qlEĪj8“ÅÀÉP699)gn±“a­°…¬bÈ‚~É"8ZŽpEŒúqVvuãÆ ÖsèžQõBöƒ½×××·¸¸ˆý ñE„½hlmm¾ TQµZíÉ“'Ÿ|òÉÖÖV«Õ2 Óô½!t:11ÁA„ç¨5ÁLÀp³þ�ÿÇ‹Œ0 ÎÕÕÕááá+W®ôõõ>tñâE⩺»»áäúûûQTAÆÆN;,ïðððææ&¬vggçóçÏ_¼xÑÛÛ»¾¾I;H> î„“K ºâh± twwŒŒ€E$Q %Å@Ãæææýû÷ïß¿ßÓÓó“Ÿüduuru§N2Æ€u Zª¸#ày î)æqþ¤¡åOÀšÙ¸b3 ÃkÌÚYó¤‘ÖŽ!D<|z!yKy;sN•±0>[{ff·ƒ©ªÄ2ÙC¦,Ûr‚á9bpoØ”Æ>K%ndx®FVmØ«³‡l;ƒTä} <µ_3õætQrµ‡DϦsò}› V>¹j’¤Ûlã|äË“ͳ)®$w©©p¾X‰Ið¿|=¨áñÐótç1Á«Ò=VHÀÿüâÅ‹÷ßô?ûÙÏŒ1o¾ùæ7ß|ƒxüÍ7ß\[[û»¿û»¯¿þïÅæüéO ñµÞÞÞ/¾øâÍ7ß× ¬ dÏž=ûâÅ‹±±±ÎÎοýÛ¿ýó?ÿóëׯ¿ûî»o¾ù&xêqøðÃñeÿò/ÿòéÓ§?ùÉO®\¹òî»ïb'\¾|™äAƒˆ[­V»~ýúåË—GGGwwwïÝ»÷æ›o>zôxʳgÏ¢üôéÓ'N<{öì7ÞèííÝÚÚÃÇÛo¿ÝjµFFFzzzúúúž>} vÂV«õ7ó7<ÀÅÿë¿þ륥%1þìÏþìôéÓ¿þõ¯yq2à ìíí…lÊúÃÃà 0Æüë¿þ+”@ÝÕÕ…mGGÇË—/üãwuumoo÷öö~õÕW -'_!¡1¨­ðC{îåË—×Æ5Ž388YltJ ”ÖÛۋѹGýÑýÑ©S§@ýìÙ3tè`P:sæLGGÇ—_~ r‘'Ož<xð�¬Ú§OŸÆÁuˆ™8Ì=€…ûïÿþï?øàƒ§OŸ~øá‡?ýéO!P9k<? v„W�}÷ûï¿Gbjjêþýû###ׯ_ÿàƒ$ÎBâ­VëÃ?„hãÞ}÷]óÝwßEÈ±Š‘‘Òᑘá™3g¾üòKùþýû½½½£££¿ýíoö³ŸŒŒ ÃñþûïC8[àƒ>èííý‹¿ø |5®?ü/àV…¿‘<ž4ÊŽ)ã`Û© #ƒßSò&Ëf¾“?ÁÍÇW:Í M9ê³ÀRö&ðÛDŠCi9¤ÓßúšØaqgZÇ¥ݻ–9© lµ¥¤Ã<NÌ©ÕL&9‘d;92²fðcc®Mf—²C044ƲӰZÞiŽ ÍG ayyùÚµk óAðÅžÁòò2€8aIú„ÒðÒÒ’lú±…Ú *?h"7¢0/1¬¨°öÙgHP˺víÚââ"†±QÃwE«Õ•ÐÐÐÐûï¿£­®®bˆ a ~‰"Æää$Ï×1,ŠãFViuuõÒ¥K &‚ž6êþ`åƒ2óàààéÓ§ÁTÆò[o½566†N21N;;;0ýCCC0ªÕjhü¢°- è,]¸p¡§§çôéÓ?úÑúûûáTttt¬®®Âñ 8@yfØG`OÏŸ?ÿþýÇa…–Cww7´^¼xñõ×_ÿæ7¿ùÍo~óðáC4W̾"ÞÐÐKb4õË‚Œá੠ʈ‰/{-xìYgCå‡F1î^‰ØÛM{/Ãôó]ÆŒ¾“bUJùF|3[·@¡T ‹ò*Þ—Œ8rœMe öÛm“b'ät’ýpg/ÚWŸpö¢}ÕŽ@åPJI>#îDyúš6œ~ôÕΜð[{&ÐFìªj’z8XæS(`ÙöñUÛ|r†ž¥Õ›7orGÎúãY‡'ED7@àÈÆs¹‡)½�«:¯ªŸ²¬ÄºP”G?71µpFràíŽw–bh™ } ?ÿÂ^CéŽ Mˆf³¹»»ûúë¯ïíí—‰ÞÀØØX½^‡VLww7¾ûøø8Ú¸AW®\‘—ÌB(t °Ž«·¶¶†oÚÈ@ŽÚWoo/@™8Èööv³Ù\__5¼‚1ìÃ;yò$àCPÜëëëƒr‘1 Û¯½öÚ à¨VÄ.]º„ÁTºÎ;‡ÞÆÞÞÞåË—Á(4*ú([†„Y¿V«õñÇòÉ'¨]»v Ñ�gYø¨PåÏüZDRàO&Êe¦ó@%ÕžV«…Ân÷0È}ideÀDБœ7Æ‘ÁÎd”rû+¤z jDY…ÊèÛ¶Kq"Áo‘³S)?¡”cÔÉØA­³ÕZ8å ^®8<Êt!F¢Ç®Ð©n¾¯×í«²ù|µ‘ —ÿ¤ÒѨJ«ŽyžÄÑ DKx†´×�· U»¼¼ÜÕÕ…j,ùˆ¶Æ^²I©\¬öa¾‚`íÉ Ž˜npp-Gn�$§²+ѺØ-ÉK•c¼Q„µc¸ŠwÞy‡ÚsçΡ+�Û‡2=‡Bæææ ‰Æo„¾ªç âÛÞÞFʼnïÂßää$’¤Píïï‡62ômPÀéëëôôéÓ]]]###o¼ñâúžžžžžˆ»‹éûï¿ðà´ÕjµZGGÔ&677_{íµ»wï‚€”Pø/D÷̾ö¿üË¿@— #fgΜB jss œã3#jnCCC ¼; »)å )X=;;‹›¸ò»ÈTÿÀ„ ¸ln˜œ1¯¿þ:ÍÿØØÞ‚'™ƒø)‘xÚ‰UäÁ –ÂçÓÙ›$…†$è„MWÆGIuÙl@äÇ7P0}æ #¬ÄÊÇ´‹Õ©ÚYK�û“Ä.~¤pÕÒ鈚 óá·|Sáü†ÖSÍRªŒDŽ%!ÁæªäÈ¥z†8MCr$´Ž©{N^V«…JÑúdrå`aHØØõzΠÑh(&'™‰3Þa‡œyú;w$ÚÇTžà÷½+,Jd°DÜÉããã4"rĤV«}öÙg”UØÜÜDá Q0ò ¼E¡ÉÉɉ‰ #———[­È·1×®][ZZB']MtïWWW ¤~&  j÷àÁV ÔëõwÞyu¡‘‘6iñ51xeæžž¨+?{öìùóço¼ñFGG2†V«uêÔ©o¾ùæÉ“'_ýõÐÐ<´B/_¾<22²¾¾¾³³%j°Slmm¡¹¾ ü x\áááþþ~ò±ã”xýÁ+'+ñp\oƒ|Ž*¤d�“$Á28ÀÍBWîòEpgݺuëêÕ«lb£¬´··‡ÈÖáK(€TH<)¿hIUÌ®ˆÎìßó¡¢Ñ— ÅÆÆ¡<ç®—2œêvÔ_X9—&Bj;*2*'”š{Û``µŸ+)ž0uRÑù×�CF[*cαmžÛ‰HX=ƒðY œåv©B'iŽè–~…@CŠùØj6ヲʈ¹mxVòá“ÄVœP% Ž¤Þ”' ¿Åm ÛÄò°"õz½³³R0¬ª!R$™Mùo¢Vhå¿1š 1œð… VVVàŒIË Ùgœ�zƘ³gÏ¢Iþ»ßýf÷ìÙ³§N‚ ühÂböôô|ûí·` |úôé‹/À»··÷àÁƒ¡¡!d]]]ëëë˜)Cä#|åññq;á'&Ppc;¾ ð\\1)ÄDèUYÉáÍåÅÄm"ù ï³¢ãAF+Éð¹]]]¼ÎF°sb\ÞGÒ½HÊ95f—Aøx+~b§Éãp¾ï€joÚ,Æ5¨?í#‚+!°Öö‰7k>Š{ò¹mŽ!u4\'Yn¡öP¡‘Ç''¶óƒ’†Í+„óÎ×(3M—`;¦ä“å~B-[­Öðð0•¶¸áI¦Äƒ0­ð«ééiRþ1K }7ǹ¥›CÏœ‘, / ÚÎRiN©zÑÜLNNÎÎÎÂÒ1ÐèàÃÑIÀCp å)àhïÝ»÷Þ{ïñC!r�ýQ@•Ö××1ÖÑÑÑÝÝ U2§Bu§««  §§ç»ï¾«Õjг¾°¥'Ož<}úsy»»» ÑéB¼—H‘yœ;wÔ~¸ìø^òëà¦(„ Ø„A]+ÉMË;(c‘7n€7ÙáÂÂÂÝ»wå§HÒlž9w™tB”‘Ì6Oš €$¥Œ~lÂjVrݦ‹œóâ™ïœœzNÝ·@üêS†H v㹑D/FO=ö„°³ß.á®/îm"ÃvV•OòÍÐËdSÑl±ÓÀÙÙäàÆs~A´Я›™™*ÜìódHÝ:Noq†Ñääd³Ù¬Õj‹‹‹ØlôÁþÂ|˦÷íìì,^€z=¯€ÔÕB Kî:¸ÐVS„¨iŒ0ÁA F²¨]ÀK¡¤€ëÀÞ)ÙA¨6&9ÚìøâœÆ0ûÜݰ•èQãàýýýÀ6û3ÒÀÿÔjµF£Ú ÜRWW0µ€íííAC{{{N¢££c;;;ß}÷ä3Ÿ?‰íímøOž<Y[[wooïÑ£GÀ_Iˆî2ÈB0r œØðð0:ØÈ-P×j4³³³è£ Ž[ƒ˜�l†fŸ<œWž3b¬᧤\d9uHÎÄÀa/..n÷óŸÿI–=aŽI²uÄY–ùùyBȸ%ñ4*úzNÕ©­‡{©~É$&ͅ술Mb#PdHámyÇ@,k·TyÇù‰v˜[ȯç+©yiIú]8 JÁ‡šrv‰U?Ý9ùíüžƒ4в%K‡NÝWUZ‘Q0)ÒŸ)*.§Ã÷åžòâ` aÃòÎÎÎâ48ø ó £Œ/277ëf;34 %ƒ7 Ä’$ÃJè1H9Vi9(D÷-á"Ö£ÄþƒpYìvp\ªPÈë†B¶¼2û„ø+‰@`ýy¶¸zÀ¿¢‰F¼sss}}}(×àl1ýðáÃgÏž½xñ¢Õj¡4ôòåË×^{ xÖ­­-Xvè"ììì|õÕW¨ê|óÍ7PºÞÜÜ<wîÒ‚õõu4]¿ÿþ{ÊàD§¸µµ…ÖdÎ(N€ªËòyX]]…€3ºÃÃàëÀl9knà,rbêyŒcœÞì3²HK‡ú yGð¤Á°-ÌYH<6ì{¡ÑU¯×çç燇‡áÀ ·ÊN8çŸá‡h.áfìÉSÂ46ÙX#9*o6zGmO‰ ì-L>_;Si-øÌ &ÏŽV’VHumXMLÚaÿòÐIôWÙœòMæ“ìÌÙðQB²N¼³º7 sðùN"-EÓ-S õ˜Òöë`PHãLZoîyû9Šl+›rÿ#ÀñeȆ²ƒ}é9dTBÔ Áæ(qÐ|ËS‚Kà@,Ί6BV´àc€îhjzzšìâÌ .‰¿ÂÆÍÎÎÊž 5�·¿rå Æ–––VWW»»»'&&jµÚ_|ñþûïc(ìñãǧOŸîëë;uêÔÉ“'wvv¾ÿþûßÿþ÷ˆîA1„²þ'Ÿ|²³³sêÔ©ï¾ûî³Ï>ÛÜÜ|øðáW_}544ô«_ýêþýû¼YàF}öìÙÝ»w‡b ßeggV~hhªDDXaœ íèEã²C¸öÕÕUüt8E¸:êhÎÍÍá£ñä€À ÅÀ›BMFKCCC—/_¦fªz8 0{ïîîööö¢ò†9m@�ðTÀ¸Kt¬¤…@€|%eÙÇÂ$ ×ÀqîYÙv¢wœ6MÂÙUÀçä: T;|#Š*rð‰ƒ²Ífátô¡è1„³¤ÂDÆ©s]ÈCëq sdFýÒ„9/™Tšsö™}i œtõJøI-#h&(ßKB|„`´Ý€“ÃI°‚ÄkE«ÍøNµ¼8 ÁbÌ.s)ØzTrdýA4ê„IB`º4 ­x ËÊl:ºA˜D“1éÛ`dW9=+€­x ˜$îܹƒS¥n%†–7779îkŒùú믟?þÛßþv{{û—¿ü% ÷ÖÖxå0ÑJÔ@ÿdz²²~iØt ­¬¬lll\½z<é7xªÆ 3㎃ז ËËË„î WD·×h4ºººø€áFß»w‡…·‚Z5 É£511Ï-M3%%vþ•´}CÇýw¡lõ÷÷ƒÕƒ\èØ$A’$ÛN"UX†Ór–a¹me•X¡}°%ìPU:¶gœcqãd—ÕEÀSÈc!»‰©Cca;yn©ˆBg%)µ}=›Ç[~;”òRú&Ý~@ÚSu#œùŠz—|RÔ¸Æbçñ±uÁßIÖ¼F£qåÊ•ÅÅEvM€Ägc€ß‚¡½Ìð3*Äï¹E%] FÆÓ1kƧ°"ǃ°}­‚&IéJä.+QrþW‰ÃMôaèa’*ŠýXòA±ã £ ÍHì"HÓ€¤Vz—±±1x…©©)PËíîîBõJ@1ÁŽ“9•mshø *ºl•‚ûˆÃ(˜Pcfƒ9;Î+ìììLNNBiyy3Ÿ~ú)åö0\†ãÈÎ?Ó2^êk×®5›M ÃUňÄ_wvv 'uAx+ ž&†ßãoÄ@o³ß@  ¤°mP'ÝÛÛûòË/ÁQxõêUk¼—íg݃|õª1)¿µìËÀQÕU¹XîA9䘔18ö®uÂO€IEúŠ:0Ùçü:ª€i±]¨'`ZØONÂù J6zÌ·U;"1rÛ 7û•6zAVñª;ª#ƒ5sPIÔV@”]>ÎÍáeRFQBUžáCïIÁT)1¤ö¹<mjÍKü 5'$ЈýgN{("" y¡PX—Ú;f(šXUêöÐE�+§í`ÁdSÎaÀlÍÎÎvvvBöàéÓ§è(à÷ÐO–Å.ê)ë¥ÂlnÄ»&W(Ì<Êr–ÙŸ-‡ä‘Ù×S3.Q)sPH^ pÞf³9<<üóŸÿ|aaáÓO?ecZOç1ûÊçÏŸÿÅ/~ÁŒÈ",Ê VT346)°Ç–Oâœ�!ŸÙQ{Y—ìÝšã-Ûî/„â¯vˆB=ɲ@9Ì>iÔeWx”Tcжo´ù6TtÀAg¤ ‡Úí|“¿ÍUýD< ÙO•\-+99žššB‰™,8âGÔÙI¡Ï¥Ýw(y”ƒXßç¹!’ŠFrj_pÕ…B×è/Òc°v'ãA&ì"°­BzXCg<‹^ ú%”ŒÇG€š Þ˜„ó�))¡ú;;;ccck€¾ >%˜˜@:²³³sëÖ-pe£”„_6~&&&@xõêÕžž¢np´‚Qk»jµL$°@rBMrÀŠ€éb}’—$o%2Œ›7oJÛjµPûBûÅF"Y¥W»ƒµATáQ&&&0þ½¼¼|÷îÝ©©)(‹à òÐÙÙÙjµ ù³¹¹yåÊ$ dÁãļPŽÈgUL6BĽQ@Gö0˜^ÛUŸRũژIMöíxÜ6bÒtDB’ì Ê>TÀîù…SuGš1$¹ÊHônX‰;rfÄ©;)­Wbð¤0ðq޶Áˆ¨!Ù³ö´Å54'g¨%Oð8{!rhƒºðRGSŽbHÓ åæyd`Z8™ÁaŽ5`àêÕ«R/^&¨¥@ŸòÖ­[óóó+++t~«”¤ÓÌQP‡œžž†µÅË0�ÁØœZ§¸A»ã°¡šÉºpá ,1Ì÷òJd0ç?pb,´Jd'H®8Sæ›sÄ5D^¥‚q9Í€×P¿Sæ2±“  •A>Èë#ŸX$jrÀÍ74àl+FŽ4q¨_PþÛµÛ\–ž ´ “ˆÂ¢‹¯8o¬s ‡â /AaZd{KŸW*à9œ¦9éš*×P´Ÿg)ÉIî(µH–õ9}f´šF¶¡lLöíë¯FØ|7ÈŽ_”ÛîAŽ>‘|_z+Z­ /´÷“æ6HjS³¼Îÿòä PoAÞ€òˆ,³pšLŽyc.ÁîJ»,‡„iqœ'݉*"I³Ëî‘ýãm²o·L,Taê-˦ªTµ>gÑOüë{ï½wu§)â�� �IDAT÷î]9Òˆ¿²0ˆÀÔciãeqÒ7¤¦’ÊÑêP…\9CŸZ©n‹ÕyãaM>ÚÜrý†ö~®¯èKT[ÂV¤–}¯WVXt6CR}¼‡o[î=y§ìаês(bÂÛªaf¥‹+Ù d­ò5dÇÚ= ±L,ì€]â/ù$Ƙ×_TQ$Õ@Æ ­6Ù8ÔqhC‡‡l!ÀHïŽ)n‰°"<Iõ “íõˆ² Eÿ!]‹Q² $[œ7„à+ƒn<hó(úxkð¹ò†òÑâ{UœaçÊ>1gŸÕV4aÖ Ÿòõ9 ½ˆq‰ÃÛÝ5µeÂóÕÎ(³ÐfƵ¯yè=_wÞžrô•Ø Ëd‘è¦�‚ؾâÎö½ƒTc&Î�_>ô²-¡Ž@ú¹°,„Ò£&•Y?Ç•Ywv²ûÚÃ>fÚH=+jHÛÎ`ž¤R£*/P˜Vm»é"§ÇiD€Že¥K¡¡0ΆãÒ5z½ÎfÏÅ‹Ágö‰<ëõ:G‚ù}Áƒ{ç΂gpþÔ æ’C@LaPX ôHä5ûé2IB—ß ½q9ÇÎyr|}žÙW£ãø!ngÈà…¦U©J­4VÞ1ß@­ŽÖãûz$»nxêjµ!�œ}A×ÄìÚàÅh\Q;„ÁLœD£Ihœ"´÷DÛFᔘGAÃm¡>Èž`îí“´µå}Ã[N䧬œm×0…ª³KêÃMùÈÃÍQ²«Ê^Kc6²Å×Hýˆ0ø,Ll[þ;ý¹d-%U¤:výúuš<þvÓ§R+OD»cÌã°ï ÚbF%â[^JvqZìgد‡ÎÎ΢ÌwÑ'I˜,I,ÄÑüñ€ª!;¢’yëÛBïžíx|ýÅÅE4pXzãȆk6›| ­'Qÿ„½Â”Ã@ÃêA‚õññqˆEÃÚ‹ÂÔÔÔh-ðAÎ C¢$áNˆ5`ïÆfŸ#„•”ÐP®×øE®¤Ûà Câ´^¯ƒ}ß¹xUqjjª³³L-çÎ#_7ž%²nH»Ãçœþ["x‹áQtò(T_ëXvᮯOK8l+Ôñm\Œú gJa“vø\WLäþS�s¤šÏ…ßÇwê¶î±Í@vã>­œ÷sþI‘f› Ús ÿì¤óµ‹§Snu9½,D.lHôH<JÒ$’žˆ©½Ò 2ñãØ·Š5±$i½Á¢ÁAe•™ŽŽ‚INNÉKD+€˜Têm0Ä–ð-:$\Ÿ¥¥%Œk!ÔE­Ÿ9&ƹµØ¦¾sçÎ+ƒÐ×íúõëcccËËËRA_&rbbbzzºÑhtwwß¼y³Õj FëÏb:l.\ˆ7à¶AL-Û!¿£#—<Ò¼,„Ií?|®d¦â…âVRT l?Àçáä[­/2<¨Å W“dD¸&¸ò$"ìîîF‡«jö¥ôàf¤Ëg¹IN_â]2u•R+ù_>áSj³«á*e”OâÌ‹Ï�N2u;£xÅt6&Nû@Õ$Pk —Ž*ÉWsW6ÔGGZÈF+Šª³Ç«Š€ ¶ÙޤÌ5E$áá6»ÄØO›d¬CïÔîO×ð/Z»’Y²Ö°s(+Ú¨§Ë§ 2²½‰Ÿ²C`“f«&­×ÛÔ°¸­ %§�BýjnnîÚµk¤q%3«DI‘Y ^ypubìiK< Kí8»úD^YÍmðžμDrJ€ek9‚@t–个Qa·yäDŽâ¬æ[äu&Pjnn=g§ÌÉæF l …Yr:ƒ0 i•^f!Pª„e+Ý@öÙ“Âq Í{XìªáO ü^UÐŒös²P2#õJ¤±Î@†¥òþ9,c¾”ªŠ:S"§¦«“ØK:sÆÅ| ™3(·³³³³³síÚµóçÏÃ$™ƒòŠ²Ü¯Î“Œ ´’SSS333”oäßȺ¶¬Ù1]ww·œ¦†GÁ•‡-F/ TÌ6û¬y 6UMÉdÏ•ÒxÔŒˆã 8f³ j?™‚3hùpØXyÙ²–#µ˜ã¥6Oåm�^¥|Û!œ—‰jôNâhVÏqæÈ/%U¢ Æ¥J3.¨Dà·dØ (L~°›b+áH3 ÿ*É}ñ×­­-ÌdP$GvÚ–——mnT€VÑ«­f#_ì„-9…{g®˜J‹Î:„scUZïëóIs®h„wƒ RK8õÔoìé£p ÎdŠwÚÇVíC:[Ò3³/ê+DÊ¬6Kb¤–6Qç9;Zò„íç‰É¦’—ƒþìFÐvÃBݽ{J÷ããã´˜vg.$Ú‚ííí÷Þ{ïÞ½{èÍ¢¼ŽÐ•7äIUœ—òVR/˜9T<ðeÁÐ@mZ V!T¢š5i¥y)zÓâð<• ,8éÔ¥#´ÜL’À÷Ç‚ìѵÀ’J·ÁN8¬6•ŠU@ 'èÉú +ZŠþÊ"tñ$Ïä7%-6NRæ4à3ÇÃä 4PIÌ%¹‰T@C�ú+ÈøŒÁãÜä&ÏJjöÙh@î82µ8­[¸Šë4Á¾2²ê~;[žæ Õ¶±¨6œ7`ùDÙ…âB6¶˜˜Uç/üÍa•’ªÐZ0ë¬É¨HÌhEdÎhÔ?œ%¬À„Ê÷%/þF‚Áë€Z K²�¥”ãðÈÔëu0¬É‡ØW6‘Y‚$i`UÄ.©)9J³)ë©F䌛œû“®BfH¼nàÎC… gÕh4¶¶¶PÙ Ø—d0m Ö u¯$‰ 9:‡ÃrrBVÒ·Å¥b¶ª¢¶#hôeáŽWŒ—ZNân„®»9Èž"‹Q¼¹ ïƤˆýLÊŠ¥ÙÅàÛígÀˆáG^Æ0·¬ŠZÆêŠfFÇøÐêjRÄG„p4óXmæÇ_ß—=t¸ª“;0ìÛm·æzª~”¯íî»4UhzòRÙ³ïv&«º[²‰§rgš�Ê-p"¸–-DBŒì€ˆO„ó ež™™¡|‚äÑ3BV¢Ùl¢àÐl6éi{âNMMAnžBÝ^d43ñÞF££‘_!$CKP@ƒdËšˆLêÈÄ‚ð¶×_‡/‹`i ¢ì[·ná'ŠKÄS"í� Â^ü”¦PÑØáÞZŠ2PIÊ…) äF¼\w±õ*£60ÈHÖ쓪ÁP+iì7€lž³ÇXªLʯ ÿ»´´„›‹³²AqxK__ø\‰(à ³ç¬â0b”U"è á¥<ƒ)¢¾°÷£Üw‘Q6 ’®F Œ6^ÜÆÚ51»ž©RÉú“ L _.¥îpt¨¤ø3ö‘¤KD³]S+¬YšøN@‚Þñi´:1Å‘¨V{ÂÆ×ÂIä+ ¡,(ª ‡18->Š0ü ·®D4± T3ðKø d�0s}}} P£d˜ì}‘¿Ð öxžS,åïíímYoccv"ËjãIÚQ”Vîß¿O`Y˜`O‘&R‘‚×–(|/œ3þM>(¢qPI“-+PO³ˆgR‰às髨m‡“¸‹ò8,냊Õyôõõá]”N♚šºxñâØØX½^ÿã?þcp³Sr•¹,©“‰`S6Pb2‰üàËq„{÷î!•Ä…’Ï9n+ÿ‹§WÑ‹)Ñ'¦ˆßÙí³ß¢§ýuöÿduÑþ8|_9|cgí¼¥“žÏç œ*ÌŒ«ýÓ³‘€ÌCï1ØÍÕë(ôHª¬9!h6H40ÙPȶè54éœ$€ª$ã ©E%QŒ6u¾Ètyá°òa•J;h?Àä“òúÞ½{+++¨]Èþ*î`Y2&l}ê6À>J5`³OÖÆ­È¹ ²ÿÃîÀröJÂj8ËÊ5Û¨ÁÉ€õ¹S &dø¦×¯_¯×ëÛÛÛø/I@áänݺU«ÕP±·ƒÇÅaÍ™ÉÚºlÏ‚žm”wpg™s°˜ÃÝÎ?©Ù<'ýýýƒƒƒ/^¼ØÜÜÜØØ�ïé åë‘´!v½|/ÆI¼A«©ìÄ[#DX-Tz¢1a÷e†c‰¦hÜÕÞ’ö<š|—-!lª:ÝŒ=[ª6¸/ÆWÏIïaK~9‡ lóå[¼YÎ×û´j©ÃÍ1ÈÒ‡98—àëÒ8[ö¾IHgHù[yÀÂz‘ºÍÎ!j¥p`‚òAjbK&ø|Δ|+Œ>É ›rÔÞáuwwsNbbb‚ûU#U ÀÔÌ"rèsÉú>L6ŒÅÐЊ9ÔðáVOµ9ÈÅMW‡Ä‚y�­* †%’¥sÀƒT™%¬?®Ñc‡S„9f{�:Ò¨äàBQÈ}ÌmÀ‚£™Á;N\“R¤€Ýd_]b8 .'Õí(’3ÕÃ`»E"µ týå—_®®®BU”ð%`ÉêÓþIŽ:1uÈ:˜¼ª²%&¹ÐÌש¥ì¤¶¶!XÊ ¨p8 BuN¹ÚãÍÊ[È“§ê”ðt2¤ÚZ/>C_XVRÑj8W(Ä E N‘cpª`Æw–䕵é£}Pu&äýƒá¶?Ý9-?BêÏØKÊÏ:#zû<˺j`ØäáŠA}þ®|Víe[˜Ù�Ù`ÁIÑ\¯× ¢©åùÐ €L‚× îoi6›ÝÝÝì"°xÍÞ©ÙCS(,ü’h]ÎLI›H4ŽÚÏøšðFˆµa+¡Fq4üd'Y¡‰Ð{dÑŒǤB¢q'œ ýXøƒñññZ­†Zü]²óYUO‰ê¨”1æîÝ»KKKø"ìâRç•mg>'�(óéÔÕ+WŒà”&A:„+p#p¬¤QGšŸ®Búuß6—óÕ1›QMÙ¨¡�dÜÖÅ’¥¿—¼´ï²¼ã‹Ç¥ àðŠN*ì°o º§aóŠÜâ?NFRg­Í›â¦JãœþBž>9Þ)é𜽠ç 9ÈÔoSX;_¬|³$a&ÿ($HFÉû0¹!'¶T¥·ß”¾tØ0O³³³c÷ñœD›¼$iþœt{’hOÚÄœö0âh“°ßÚÞÞ¾té񮮠d³OÀþR6¥öøøøÄÄORŽàÉù5©M„ËHóÄi;¥$Ÿ:ŸlŠuE°*I %žGê;‹éÏiŒÔM”36rÅ–äÅs†)¾}QöãÜïJÏ*,&_häªU¬—á™»£`W5é3‡>ºÄÒóŠU,xáä¤÷„9ÀcdžìæÜZïB²LEJêÒI $-…ô1¶`�,ŽäÐ&Ç5ôåACÍÓž˜˜ç&Ǫ%ÀÔ¾z΋lOüÊ]çÔS•e~_ʨÙYš?5a.yR1¨ŒžßŽå)Täx@^'-£ 0å]¬VÚe~M@ŠÕ ´Ô¼›¥zt�T¸“èU€ÛcÏÒ‡ÑU0’ìßT— :ÆOú›ªhVú˜ Êí2çÇ™ N`ï‡UclZŒž]Òz´ÛÕ_O¯Ì“„¬<+¹u}^ÍL"ƒ³?&7˜œÃ`sßX¼ÔË"¾=Lo—2¨*jK8H‹@uú±)-‹²æêÛ™ƒÌÌdq �T%C´ÒÞÀÊsã P1µýe¥{bR]Ž×A¾Ì×Eó%vü\«X^|yXÞG:°‹ƒDûdÿÞÝÝU2«ÒÊ|Q‘Ó•R0Ãn«t_åvê÷…àÃ>yµ%¹K!OµjËŠ¡²(Œ#}øÉ'gâG!Ôc¢IÃUÁ›9ç¬J@`.&+  `Ãç¯X’œ�áÌÌO©ÈTæ’aŸÑ½qÉ¡HiÅ`\Òפ›Šúmï%#Ÿz¶JŸå5ö2ý«´ANC£Êý2¸–"9}&ûÌR‹Bž³ÌE佄v±H"œ*{¼h_3ÆP;¨$ BÈâ dÎa+‚¨èÇ'lð1]úTI~"¦\ìû\ge)\°M2ÁÍXÚš…#)áã—=:®¤Òæ^ʨú0©N€¢@ b;ö·‡ÑTg)F!–O‰“wE‚ý1ÅÓ³uûTK‘rËiA_ëBâ18`ÅÒ x/°±)^M„( ØÛ$í¾ñF"p&ÍLØ'¥¾D “J”Ž$6—x0’(°[¼“ü(ð fLmU©G­ a\¼Œü/Ì+Ùäkµ\ð$»ÅË—5ÛÅFðËJ*ÎJO¼�¨8†j9‚•’ÔKKK8>ˆ£€¨ñS”�qV¼G/^”’hž)gÃ+O»ºÅ6NFþH0'×i ÀÆõÂÊg4œÿ–ta&‘ûÚçÞl¦Ÿ@*£&®|jkÉ?Ò×÷]^æsØK‡Û…=Œ�+j[–Y«“|8ub\½] ¤–Îô¤í´/µ¢åÞ`+•´¬ÆRóõy4Ö©”²´±<l™k¥N¬RCÜ’1Øõ%%f—³”È¥lKȨânRuïzýõ×;::Ài¨D=U Mõ·Ä«ö¾à³§nË8¼ï<jsÓª†¶¤3±³uGX9´{Z>!☎ý<Çßÿ@™]Z¬Ò+ Äs%ê%ö‘K$@IyL¸©y n…™„ ç•6àL‚‚}`5• 8/“Ä&K\l˜º…i~ 5[†…9ÿKh ÙYAŠËbâÂ>òeSûËæP—³F{ŒÂ©¼ D{FÃ300�Š:ijŠY3´°)F&‰›“RÞJÙîVU δ¤Sç'�¸7œº†F0—I1spÜR2zÊ"’¤©˜žž†•—3bø÷ðð0¼ÂâââÌÌ fßnÞ¼IŽU#8n9Ú†kE#n–T‚€‘èÀ+Œ«Ù ¤)ò>"WÆ}Á{9HAp-†YþrJñ4¤·ªrsÉkâDOš}\r`-Sʧp®rP@FEvc‚ê,ÎfaÀ©LÆ­ìj„-›Cƒá‹† S(es¼ Õÿú?ùŸÿÛíÿøáÿ‡ø‡£ôêûûž¡À/U^ðN6§ˆöqž’&|çC`²)Ô³ý|«‡Uª°(µX S4ê”ÀÈ=555??oMŸ$_cö9Ô  ©s*žV^P¾—_M¡×I;???==iç™™ž’|£²¦²ziS^ž577º:¾’ŸŽã»æææõL¨Ëâ¤SÕIò0yòe¼þæ ï´]¿U¿™™™bßzß#xøÃ3§…ý[ç�“}M.ÊxèÚ’N&þÅ…V¥ôÕ(ñ6*é?~øßÿó»ýÿü¿ÿðïþý8êŒÁY£—¿w’gÜ â% £|NÛ¶ƒ©Íd%E bs'‘†}RùÙ&U%²R[$1à ¥œJiî"Yï–ºÎS’LÔ~øðá;w(èfÎß!œ”çÌ!gŒÏÌÌ0•|;¾°õq’dÈëƒÙ´F£±¼¼¼²²Âz YÑ¡%™ØPQ…í‘¡1ù?ÏÌÌ\»vmuu•ׯ\YY0 a8 n§OŸîëë#3eËÔD•Œ’ÇY&l‰Sô^ä†RMc^Õ’\NžÊåååf³9;;ˤ 9ÂF.yò>á0[¢<`¬íƒlHÝ4{ÇùØn ƒ°;‘qƒSV à‡œªŽ‹çT*)ÉTq?¯Ì1ØßÄÙ3 WiìÎmaÎås­2[ ËqJ¶œˆ/•öõÃY UŒð 0*¥ä‡r“Ûá§j;[èæ U�YnX!ˆ…toœ°EüH¶ ²JAÊs�Õ„œæåt®º\“ ÉSt„I^]]%‡Ls£Ñ Í\½^gù…¤ª’ê§^¯C“ÒìkŽ1’Íwigg‡FÓy,ÈLNNRãh{{{ww·Ùl’1ãÊðR ß WfeÏîÓ(â~50Å*¼Ks²Çì䵿GS%·”!x%F¦K±Z4–’«œ’ P+)PUZ‰¡Ñ,î¥æyLý'�BQ|6ƒãäß”ˆí îk— Æó…¿ö‹‘£°xRÈò!#qÖXíÙø‰.d]%�ï1.ž%#ÈJí;­6ª/)VNËg¬¹“U‘'Ï7±1²Ç¨è}±/‹rž!Ã=¹O¤=Ó‘{÷îÑâ$%ƒ1eȸä'NNN*FRöì*3 å`*e÷o”ÿ†ƒe„TÜêê*‹–––0ðeŒš“²É@¦ª \i1ÉŠ´Ÿ÷0==½»»[¯×ÑyBW�l"FéHIÑùØ€2wI•tÕ ¥²ÙPˆk’ñ©·ø8Q,/Å*·{DruÊ€ûHå|鸺§1Cgv«#ÆÈŠ'ËL:Œ_39ßë«i¼‹ „á¥û¸†|ØO5\Õ~†Mu3dÕHújÙ'F"ÒQ– =¤óÝjxNÓ(Ì«<y–elðŸ]ªæ~c­I~„oêR…{üš2jOŽÄ,2/»»¨Þ0«à+mEC* ÁÉεÉb ¢'Þþ›ÿ€U%«öÄÄtO¥N´ÌŒ1àtîééQ×A1¹Êˆ>×gg•\ñññóçÏŸ?¾³³Sv›i àx0‚ïˆâÒõëבÖzˆ7èúõëx1z'løó°làœ9QH„‚qÑŽÙƒ;@-Ë®êr“ôÐV!TE$_Èøåb£‘/Ê”Í{ÏÚ̦á°ZA|ùDØp;;çþ³lé+)—Àw,w;?ÔY’òä(›Ï¾^kLâ“Ôs.×÷šÂIYdËÈî:úŽ©º‚¶¿‹=Q˜ amÊnY«žž¬}£Q<;;{ãÆÙÙY6$íƒËÃ*~Js\Únãû:ŠêÅ{'¿?‘­iùuØëÆ¿ù.½d‹B†xhq³ü‚Îüìì,. {à²Cî|føAòPª?,;Û hÀRÿê<g °Ú@ØW˜½ô�¢!ÐK·Ÿ«*-V§Åpâ…lTHÀ¼2.‡qMI…CQ®6ã<¥BkyãÆ Õ|> ÇPñKeñÏ“­d"Ô0|†Øç� q‘ð'§ìx¡ÏûÅ€Ó Ÿwàìì¬BìØŽMg¤u°»¯ÊÁÈ2 S?Ýi ä×ô9<i÷U(j\3å•K“,|¢´Ý íCH %‘?òeÒ|K€²óÞáOÀIšºö³­n"«vê~ùöTتRIûìidé<ßYÙ›(¼’,UŒ§)”™)±‹S­ñ+p ñ×éÙb0£‘žÜ×O>ìïy‡ä-ü¾áMÈfÂà]ß§L‰Eát Æ©”!¹4£j”ݹEíêvµ‘¦v ¡ „ZÒFò+Ë"­*‘µrᲨ߫È™½I8©ü8&7òÌ?øbø •G–§j{#º1;à>8Qã½¶¶7„K(‘ŒÝŒ·Ô1A¤b^Å”µË¶–CŽ‘cð¥<N“WXIz‹ÓöI[àK2|W?ÌáÑ^eŸsàêùpå>¥Ygˆêc"‘¯„y’•Y!qÞhùÊûbvUÆ‘±¿3ºôùÛÞ)ç¤f • ´=“*ò8ç!|a©tô.òüté{¤Ý7gTÊbOuÌÏÏKc;f%Pã¬ÝÅì5ßÐ¨í ¶µD�W˜:8K”1f4¦(ä«h?œŸSl0EJ×* öçèC|MãÈJU©®Åù)N˜S8é³ßsq’J–¶á–Ê·ñ «4Ά„Ó»„CÂÂŒØö.vQNtYÙ°¿‚Ó©ó—FŽæ)ߣÆ�mÇ#mœýKûLdñGŽ bÙ1ŠœÑã%’ U4›ŸŸçW “Àä<‚Ìlœí¨Àó ¾TLÕ(>¹©õÖ…âãôÈ(>¼»«´IÊõ|ƒ±I™WPJJ7/gñãgž“JáÊuØú£›è3ô1Ñ*ßG¶¾“òh;vV¥ «X²"/S UÈ–X8Û_GÖ¬Tvâëv:ÓgÁJÕÄX®QÎ ÿ'\ˆ¦_õä÷¥Ûp&I<+ØzŒXÏÌÌpÖ/XXXÀ_ççç霿@*¯¦¯³ƒ`_È6ƒó—‘ŽÔÿ¦Ö©J[6ß¡ ƒ³T~‹¼ÈDZ””šCí¢P¹ä >î€|¶Rbº¾2E9wh÷x,‘Ø-ÛEÙn ü^Z4Y$Q¯ ô“e´ø*„²ËVŠJTo@ž’³©à«¥ oP&.üI`Ø8�…‚ÀéQðo XR‰QØvÛà®pWÀ—«‚ýJ  ‘~I᣽‘KD®¥»Ðá‘ü¦áàµÄz•Ž¡Ð¯ÊsÆBD>”%Z7¾‡5à—ëÿÄ?ÖñCà…I«Ó9·½ýÅUoÓW–�G_ùXUd,l—k"avaDý×>š]‚“ Ò@·CkÕȵ/fÀ=¨tdaaPW}Ug#,Lx#]2ƒ………¹¹¹>úèŸþ韘=Øø=yÙ Iakè#®/Üqå:Ìa+äËöÚè "¯|j+>’“¿\Irþ%|œóîrK1†R¢‡!ª‘•¤ó´OÉX“Ÿ>µqß—2éž;sRæàLœ=ó"7˜=ÿ©ˆ†ŒgÚH"ò5j`PAP(Gsýúu5Ø©æ¤Ìþ(+˜è¶ œ¤Œ��‡IDATÇ9Ók<Œ:öµ¢±æ™9(&Ï_Î{›ýigNÃá 9]hĬ%‡Àñéз*ÌÙ@ÉUE• |¾¾>λcÖÖÖÏŸ?ßl694ΉÂáááZ­6<<¼½½½µµõÞ{ï½ýöÛ?úÑZ­ÖÖÖÖÐÐÐÆÆ†1fccãÁƒwïÞíèèÀéa[úuŒjªÌÕ&ø, óåh§Í(KÚS¢ö°›o™çéS„åå¨b‚rnÜ\ù¨ð]Ô&±?. ÑhüT:HŠùeÕvÜ‹Â?…Nþè3†02'5÷÷‰11… >áªK ðµ�j£*õô˜~Zaõ,ùàƒÜ±«Jø|hŸpE;ÜeQˆLU ‘‘¸3u6`½wÙa­_>`ÆO §fÊøÆÛ·oÏÎÎÞ¾}Ûî{3]¸}ûöÔÔÔ?¹9$Æ — `ùˆ“w8R€éW³…]4¹Ô_¹4ºp ÇO•FÖ‡#‡XSËà©]⊘d)©œÍ-½ÄÙp}¦Ä ³‰›+,‘©Šy¸ÚãìFØè£@ú¯^ïÉb.oÀÚ†Ûn ص2ge‰CËÎL‰CU ì¿Êfo�TƆùÇÌqe{ºØX0\çÁ9LþÑG±”$'´ñ”†nß¾}ûöíþçþè£à繬wÑà¿pvÛùl8#�ávdµÇÆnv½:°mËÍÄ—Ž}&HmÛBn‚vyßù(ÇpÔ n¾suR Ù’ÅN #ŸŽk¡,s!y‘ïƒÂo±ß£'®ä˥ƖRivJ%ÇÍ€î«ú RÙ&åöÉö†µä”+U懆†&''¥àšq©q9Y2²µ±œrr*Ú•ì³R¸×„J×JÃopþJ#ÏìkœQÃY¬ðvMphhèÒ¥KÏž=ÛÜÜ+?‚oY¬1æÑ£GcccÏŸ?G êu]]]ƘÝÝ]\º¾¾¾Z­Æÿ’pÐ.#ø˔ܴ­Îí{{˜ùØ~x’6£±´ÙÇD]õíoŠ’Øû 7i˜ó®úù¼b7§—sʺ)S ¡³y\¸¶ÿ÷•&š¦HåÕÙJ¡£Íiêä†$=œz¤ì%ì~†“0\ýÒnÈEXre«â/¢)õ¬ªã³0+Šër|>Ú©l¥n7¥+¥W ²&þ$[Sdù–q… )Ç{7>>N?Áä¹¹9hÆ™}úRòx³@ eÖXÈ–:===44tïÞ½þþ~ø�¼qccãþýû¤5ÅkÈ¢zëÖ­®®®'OžcöööÀûøñã®®®ÙÙÙþþþÝÝÝ®®.pÖjµþþ~p’žg›æš¬‹ŠZÕÉ´*Í´lÚ]«øZ“3Õ~ä|MG©;³ÕVõ™6ÆôŸð—áoSš|ߨ ãøPb”{}¹*PáR…_!Ë—âÅ4ß õã5–ÀÇÀ¯…�0RÁBÄÔ÷ÌA96›ÆN}_?ÀF1ÉʾósÃt{á"ž<[€JQ“Qω¯¢¢”Ý䘛=±¡$ÒÌÁ s³j››»}ûöG}tûöí……Ô—>þøãùùù¹¹9T8Ü@ØRa‡©°Ä‰‘4Zƒ)ë!m綉oTIÇó0¾”ŠÞ^½‚›í$K#½ldž(Ä™*ÿë¼ÙR‚J.]0ET·á ÑÉh/í¦Ê-¤¨–Ì~Ê9í‰éÿûn±|% #p�£5äø!Ùµ]­¢Š‹Ôa–¯n„ó<e*ÆÐ^]U BãÆÙÊ;òðáÃÕÕUªËʘô8,ªCCC¤(çAxÔ·@˜oöñN¬8áßX^^îïï_\\\ZZÚÛÛëìì|öìÙÉ“'=z´¶¶vçÎÅÅÅîîîZ­ÖÑÑ144´¼¼ÜÙÙ¹±±A}='\M|e%çΕ‰šz&m͉4+ÑÚµgû¬Úe öÄ~,/‘ÆÐ‰J*<,pS>φu½úŒ¡b·¤\ã¥t°4ôXxæñ!†Ý,u6Ì}@'?þòJægãá-Ì'|D³Š\ÈÉB˜æS 2ß4œ%c|Õöe-ªè|Ø1V—Ñ:æ Ðû•yƒúD'Ñ·M©-É\Iˆ$gÙ$ †q͵9‡W"){¨‡¶»°ª•IÄí8sÊv¶ö.…—VH­ËÎù•e …änøºp^¡ðú:ƒßÂ$18;Ãüp\c7cUA6 Bxµ {÷§ÿ¬¡ûŠ¡ª|N¬ì1(Uú9Ywœe.|"Âp|(ÕÈ^æIþK¯@5¼�‰‚<ˆÔS’ñ¬q!èÍþÀ ΄öÍp¶[ybÌäœÄÂÂB³ÙDQ{ttTÎ.lmm¡¼¸¸¸¼¼LÁ>걫ù9 ìÈÆ/„¯å$ ®!¤C!7 ¡:ôÑ ŒïììpXDBãU¶DánuËTk¿tŠS…áü¶ø•êç…ÇböuØ\ŽïÜA> ^ã’B³+Šá¶¨Ý#ñ½²03ˆTýtÞ&÷‹ÆP=!(ŒwL‘ìARÚáÕNíš–€ã뿦”úBqq!¿·±Ø‡” ñyh'ák Hmse«MK:kâ) ´ÕÑlé$ùoâA©Q!ÙŸ¨3Áai•ÙO#ûFÌTûT.ä÷úÇüÇ……¤ G"7_¹ ÕòÇèÀij_ÄÌÿ:½Î»ïìê…3¿ÔdÅ´Ä3ÕÔÄšb๯²Ç$mZ‚«Ä§çl?0Þ±#n5híkŸúNI•õ agNÔ¹4AÍq»Òj·=Œ‹#SÎ];ëã&È3aƒšœêÙf5ÄK™¢Öæ A·Ô7–Å}ëÙél,ós)oi7¨;ÍhÇX–U¶‹ˆ&âq DúðáCàzÑoh6›f_¢ÙƒP_j êÅ9àœq¡¯ÕjÔm–ˆ ¾éÈòòòæææÆÆÆððp³Ù¼ÿþÎÎÎää$g°A·gì¬ãÉ™v¶Ÿp¥&ëìÏ©ƒøL¶_dwœh(ÕOâ“_¥‹ïÉ|Qã'2®/7â¡Ô´÷cÈMÆP2T(+ù>úkSÄZŽÉ¤4³£ú¾ÆÊ@‚â»÷ñ³EŠY¨°©PȦàl(|ŽóûJq7[Ÿó”le›<Ã',¾õ¾ˆÇžà“i*ôÆÄÔ»ìîŽRý4‡½#ád&nt¿P-žþ²eçcZôø©éx‚ÕÂýŸÄKoVlrļòØM>GòßUéÉ2Âû$wJf…¬¾/fHuZäÈ#'¡úbªFöõ‰×UÞç´N×Ü«{¡ >¶Š€Ìÿ”º\êÞØ8©~ê#Ó-ŒfœÛ;pÁSƒ_g¨-{0ÒŠEÖ- ‹‡¾rn’rÆöe䵬Ò@®ØÇ·±Çäó–«ÑÇ?åa—[â±K5Ð6b§µ\$⌿˜ñø2q (ó1))ˆ[ËQµ«®ƒO³ðaH%Ký %©}^¶X´ jg†Ÿ4IÄä‹NÂö+R61fï”k’9S®$£_ÓXšlµ-ØÈÒGöqØ;Úí°ë+wçJ(ÙÐõHŸO+ä3©1©±3ì |Š­WS¸ÿ_ˆÑ$r„ŠW1öZO$Ý:Iß\@TYÉ-(é'S¬s/ù>¢°<®ˆ†Y}˜Â“ñûËð°/²‰>'à*ôU…sÛi±MPc'&_)q+KPšG>¯À1TÇ›D„L•{þÜ*ŠÎQ€Â/˜ªC’´7 å×Ë%œª¢Î°º0e±•>m#fô³OÌW»·{3vJ¤>ñš_&n~>2€\óÒU¯Âº|ØYVŒµ#[1eä€[ao£b…'½•ækp6«TÉ^Y))•¯´°oôÛukKø›À½Œ)ãú$¥**UU)òúø'^ ZE*^h,œ 1IkŽñðÙÂH_Þ< 3lG† ÀZXG¶›Ï‘éZ‰šƒ‰à.gì M^LΚ¤NS¥Ó&Œ¬ƒµ·ÐR:ö=^CR9¾0z*Ñyk—‰œ*H +ŒkJ?èIIuÌÖrf]N»oæ|ù«F>à  âìwI×®<ARý3i%¾éêKÎl˜r g ›ÚB·—:ac"ºèñ%”*)©/,hÊ‚õK¸·ro<FÍçU¹6ô˜ûäÔ€ è§'i W/µ%RýƒÂ×;­@xÏÇ ³Œ_ù9üHØ"õf Ì'Æé<¸O¢pÚÎD·Â|ˆÄ(Þ¥Âb*->Á+ã6”.؆‘©I†/Þ˜: NÊUŒ#sñ°¾EÌeŒ9¥°M £^½c(×N([ˆ¿»%NÌikb_u¨ºbT|æ¯Ìe#8]„EçxXa˜TÇ&+ …|~KÙèHc'áF&BÝχT U,†âº®�û¬ó1ðY´˜ÝTÒzØ´©…C<NíÕjWq8ò Gêbj‚‡Í.["µƒ)»~꣢‹Ù3‘ÉS¡Ó*;r¾r"ãaÔ–/:vb¢|xИž„o.L½,0â`"x «jñe„ÂA³¤(5µÈoëìã1NËT€¨ø^ÛåÇ4)S«©¥‚ÀƒšZG*QïŠÍqœc(7ÕRø–HX}ê ÄhR…1µüu4âˆvª©HQ¨�j‚’ ¾®¦éCûn“qÈWIsfx…ÖÖ9“Q®îÓÌpª™:Ó\ZYÕŒŸ©.¬£–;BigƒŒÉnMQ—¨-{Ðw×"S¢¤;¦n¥•¾K :U¹ÓŸú`UÙ áÀ?2%Jí›–¡Rƒš@é ãÊDñ¹yÌ%òņ*ã ŒÝE&޾j~¸Ó§)ü _ -f×Ä´‹LšÎ©ì]:ï+ÕbŠoä«-Ñ›cN‰Ñ–Þrdý7•95æÓK s—›Ú+Úû6LL¢Zß•D]“/¨¢Lñ‰ºrúÁÎTbìT*Ö0‰gÅ9þo»cúX¥C±ÂÛ]Ø)Á(cáªUæ »î¥‹BUš ¥g¶#ó³Wã’èR#»ávŒ±N {ÇÇÛšÂcJèNŒKðm6§ Nà)Œ¬§îHuâ,'K~äŽ cêcÚÎ3¾÷æû8“r¹r<u¶MA˜Ô{©PEÖµ2¥© U¸•Ê=™1ÒF‘'?ïuŒÜÚX /„–¨KtÐÔåP褖¶ ƒµÒø„°çtK w ëÚêᆰ¯çˆ¦}ˆ€ÂWã’vˆÏ“œ$‡”Z™I’/ J)ñÈ¥ÒÿZç$´TÜZäµrÒ&ú€sÕiÛÍ97¾T¤/‰^¼aj;WüœÆå ‹�&btÀ7¸h[%‘_¶¼"£àHrò½]ÒS“Œi'ÚñiÌ=-7!>NáüTÀOWÄC\ï!Žš"F ÅHh¢»V©›±]fÍÆ T)U™ æ3ü`WmK×!~üؤ#ÀbÓbp5I»1©Ä_±*Ox™–•žuó†ú˜”"ƒð˜ÀD  ¶"ÓI‰gµœR[¼n/ ½½|Ôíê?W1 ËÑ¥ç0ëߎcˆ/ŽûFa#«Lñ¹[éæx,Z¡”¦ÏE•ðŽ1YT’Ur޹ò—ŠÃÉÓi<ÐrS4JVøØDvžÂ Ä¿ñRáÆL[æ"¹=bèRA žA|ÉÔy[“x—­Ž*J-IÁåa°v‡ßxìšÏ‘2Þþ&µøJ»Ô+n,"ÏÀ9ÆhIôŠa-&Ó ìó¤[î:¤òº¨*qq•PËn½:‹‡>–:C`ŠH‘Ò1&¥IÏQN 0f嵐]¡ÈÌ>Ææ”Å’¸U*áã W-‘|•ˆ¯SëI<ïI221¼(…ñ~*¡Þa€ |WL‘¤–sº1ôj*Òôµ +³a`¾]¼Š,ÁGúBßÃPP(×à)W*·M**fÒ¾©Õ¤ø¬4`´z�‘Z®l{=-°¿Žï€[‰ž]7lûD~EÄ…³D` Θ""pÚ‘—¥R¶ù1Ã¥}Uª’mL_=R†Ú¤÷-Kw\«ßT#&½(œSK-t¨›b³çÆS‰„…LÊݵÕàrfªte)²H[â„QÅ ÇÐÞÍfÚ:Ë“ZŽ7‰S-ñ£³úL˜Œ(Kî»P©\a’ý4·BFç0ÕFfi™"󍩸>+ž§62uH)øÜvx~’¯JížÌ˜ZtjôùÊ# œ>vŽ¡½ß¹b–Sß +º”Úâc’Ž`³ÑvSÕ0z2ÕQUyZbFíÂaߌK 7I¼äud™%¦—”.†þ¶VR|‚[E™ùø¥Ò¤#m?áãåÊaZ"I #g@’¦i"7¡ï!•@´ÊvM²ãÎļ :"•¤Äw‘Â/¥€H³[zä*¦…^±ήû\]Ò¸\ucjׯ+²¬·Å4§¶¸ÂâØ¶ú“IG(g â™Ð’>ñ‡ W lo'íeé[ )=El*7�"W@ Ó9"ä`â§7ËQäš ½ý€Ír ¤ÄpWÄk[ú¬¤Ó;ϧD]"i.7ÀòÖ. ~LªÞ>…þ¬z4f» _¢ZŠaudJŸÇQ¨çÈ2»¤7(~Y<’ÒøÕ ªÜø¤"r bŸy´‹±ÊSžô×ÈŽ«‰`4KeóM½¹…W;†1)‡«¨ž[úq}Wow²YÄW&M4?‰àŸˆT[ñƒ¯C„èÌGžçqq ‘ ૺ;U÷£ wc•l1¦b[X“ߥô˜UEçZb (°“ÆË“H5œÌ"I¬Ý1‘~R ¦dR¦Ê%=©õÌ’•°«#Zé0ŠKcÒb'}µ°3¨NÇy±õ1u ñ~»0$·¿åª:IؕҙC©¼\m„å%¥6@Öiݑ Ú�Ú¬SÎsŽÙðñŽ9µÝ½–kÿ$í¬˜WLÐ]Ñ¢UAÓ¦Z›Hö˜ ¸ª2Å–”žNMMýé1„ÃvÑ`¥rJÇð^Ø/(TTŽa?a…ç^Ä.¦—&É(gdÛ2R›´yb´_ì±ÄÒ–¤ç¿ði,4å¾nSé|¢´&ã!É;Î! {Øyv|4YŽÓ,þÊ¿úæsEù„ÂÊx¹SŠ4ññó¥‘hÈC¥oL½Œ&N3òž&aŠ _SZ«Š2`a¨Q˜˜ hÑȦ¨¯CP¥vÑ. ¼ÒTKñ›®D™jŽRو㋊ñÔŠ1eÕrW‰¯9C`b¾ôó%æ‘Hµx<k•¸¸ôŽüÐv‰Û„»x ˘lÃÍÍÅP…cá‘x˜Ôä½°!ò¡-çábJ40n¸ðåó¥ZO»<Rš£;)÷½¦r·½s¾ô:Io'~GnÏF)©í¢zUJUI¥Þ¶T âŸT)P .©ð† ûò<¾‚LÒž©È•VHªZ¢çìK%«pèÇûÈHû¥8¸ÊY½ÈþÜa§ÅHí†KUTÙCÕ1õûV„¥½zÇc5J¨³µñA,Í›äÒÚÈGÎà8ƒDs$Cö1%—0Mºi+±Uü£èNeÇWlú $›’ÊJi–F%ÅèQ‡/ŽóšÄç …ˉx'Å‹å~™tbù¤Àöüap%“#™®K_Ù`*ù¨ik×!æ‚p9ßâ+jK{ Ù2‹t…�¡Ô<²4=m’áH•ˆhã­¯´&]ÛÔqx»™$ÕÙà6ºê(¦r Œå‚òW¦ÇP.8 ­¢Ô¼¸í™J$‘CêcšZK嘌œÞLâ>k{U0õS"}L|-ø0 ñÝ‹*„]·­Aç“•NⓈ1动¸-*¿GP)©è±ÚÙÓŒ¡Ê],mÍ#“.t|©ÊcÔ^Ò‚f7<?ìÛ–1mŒ$<~uZ‘BzÑH¦¿BYoû†)JWÆ œ¤Ñ]®ÀXè Cƒ62Œ+QD Ä7IãÐ&ºsSÂ¤Ž¦Ç_á¤Càe1ÁvïÂö=¾:ÔÆéŠ$J5ûZÁ�I-HôNÛä¶P£G¦ å8æ ·œ ã‰‡ßøje>¥¦˜/V¬LzþSÉE’ŒfLö–Z\ª¸³ª|µ]Æ·—Û ¸jªxá± œM0'FG!5+/ü”0ô0}/Z:Õ;¤Ì=À TB@8&LnËæ⤊C„a ¶Z|¬z¿µÖTOþFaÄ]|>Ôö»¢äL‰õÛ|vF…ðcP¯ƒêŇËaxý|—¸Jñwa„ÃÿS¡ºÜPhÍ\üìB*oOéA÷*[‰¤'þIÝøøJT¸„àÄïÉT,>*MÕ5:Ê‚J¹©¯cçJW3«g ©ª)‘Ѻ1?),*!MišSG½Ú^õªR"+a.Ã&Žì3ÞV·U°’©…¸HàPäù"û•冨]]å¹->.¡×^÷ñÕcˆJ<ζ­Ç㣓åÉ’¦RcˆÒªhKT ™M‘hø•Iaf•D$2DH­<Ä”> ‡÷=¾/eW®«Ç¿aÁÚxÍÑÒ^ 9Ø!¹“î!Ub«D¬>ã(íYn& \úi‚”«Õ¹Sbʵñujg.RæQf`Š/w Âqe¹Ó.44…Ô§…I•¯ø©;_.¸‰/4¥¦¾µ¤…»2^v¢b}¬´ep¶ñSaÙ%œÖá¥%v}à•?T¡ž˜½Ðü2~ÌCêÌDL?3žÀ”EIÅë¿—{ªÂÓ~o–C‹T…µ:2²ð½‘1ZyÀªD?劄m—ž-Q‹«~§b’¶øPïè=3›I,#í*²#ÇpHœæmÿ S–å<)Pò‰ðDÒH”0CŠÜ;2bMåÍ׬ª`Ÿb¸lK0Ú—ð {$…hŽrf-m)ט ïï²Ø¼íe…Kb0+ÝN ã2b >GÐ¯Ž¿›?l=†¤P(µgÐFªáp#: Â\"¨oËs–ÚHHí=Ä·Ô"-Wá4\¸WQ‚E5ð¨”N€H ëœw Ï ”3p©<Ò©éKÅ`6°1}¼Ü©!]LØTEÿ ´¼Õa°‚Ư^ó9°ÍRÇŒãóèÃg›ò(ãpØ[±ÚPÑ9¤©ÔÒ ¾+‹ˆœ«³‡çì9 î©;– Þ+‘³Æ”XS#Ò‡7ùÔö2fÛE)¿ÿ¡öÊý2²WDD* G‚RÃ.n›H½IßyØ÷bnD9rûëÀñJ±…¹È¡²oU×KÕiËãoÝ Y›"«yåà°‘»2^½DœêÚ5›R‚­ç1Äçãå‚‘˜ Cä­*ûD>…7¯P)%i"¡DnkÒQ^©©q»x¿½÷‡„…¿ ñÀyÕê(qgKÃ(ÊU¨ÚÞ2GÒQ¯Xšn»v‰ãÿ�šÏíBw•#[­ŠÉbØ{â3͘ÒY{ïK•¶J¶ë“®tŽËJ}’ʼn «´RÚh©žøŠ~&}bÎAq©âÉ…°à®ê=ä*k|ŽXQl±]ÆóxI{÷ycª¢‡Ñõ­B<£;c³Êq8— \dg +^µ&†¶bÌÕ%óŠñP|±¨‘iy¨Ô¡r»¬|ÀÆÝµkð¢]&µwâçNü×ÿù˯¾i=yô]cðÛëׯ›¼òÊ+¯¼þðÖú/ÿ£÷ô™k+÷~uçd¾yå•W^yÉ•C^yå•W^Ù1ä•W^yåå_ò?'NœÈW$¯¼òÊëm½|ùÒëþ¯‡È?óÏü3ÿÌ?ÿ`~æRR^yå•W^¡•C^yå•W^Ù1ä•W^yå•C^yå•W^Ù1ä•W^yåUf¹QI/Oüߟ¹aŸæŸùgþùoûçËœ1ä•W^yå•KIyå•W^yeÇW^yå•Wv yå•W^yeÇW^yå•Wv yå•W^yærÃU3^5ÿÌ?óÏüó¯š3†¼òÊ+¯¼²cÈ+¯¼òÊ+;†¼òÊ+¯¼²cÈ+¯¼òÊ+;†¼òÊ+¯¼²cÈ+¯¼òÊ«½ËWý?Ø¥—ùå•W^yý¬—^Çðòeöyå•W^ ëĉGl9Ûò‰áƒäRR^yå•W^Ù1ä•W^yµi}¡¥-Ÿ>Hv yå•W^yeÇW^yå•Wv yå•W^yeÇW^yå•Wv yå•W^yU^ùä•W^yE®'NÈÿÛÃß·¤dO8?(ðéê¾óÏŽ!¯¼òÊ«ü ßvÍ») ø ß§;ã<L.%å•W^yO÷SÑÁT9BÎòÊ+¯¼ÊÄò?P¡˜óÏŽ!¯¼òÊ+! —öç"Ï?—’òÊ+¯¼òÊŽ!¯¼òÊ«Ôòutÿv yå•W^yX¹ÇW^yå»^¾|i7o¿<žŸî;Bv yå•W^•¬sä/ã³R?=òjåRR^yå•W^Ù1ä•W^yå•C^yå•W^Ù1ä•W^yå•C^yå•W^•×ÿA%õž>³¸iþÓùùŠä•W^yý®ÞÓg´cP¿Í+¯¼òÊë:cx°¶’/D^yå•W^X'þÝ¿ÿù*ä•W^yå…õÿýïÿõÿÜìO§–6o����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/rgb/color.png���������������������������������������������������������������������0000644�0001750�0001750�00000745623�11332353405�015244� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR�� ��N���²]{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ¢õ–S�� �IDATxÚì½y”dY}ßù}Û}û‹=·ŠÊÊÚºª»ªz± $hÔh0<$dù0òÑX3š#Éc#k³gŽåžÑ£Åò4X²ŽÐXB€�Y`0‚®î®îZ²ª¢rx±¾å¾mþˆÌ¬ÈȈÈÈÌÈ¥ªîçÔY/Þ»ËïÞûûÝßïÞ÷.—$ €ÇÞù£`0 Æ]ϳŸû�±mÞûþ1‰0 ã±wþ賟û÷èãï{ïû?´X®3‰0 ãæµK×/<#¶ÿã{.“ƒÁ`0Ú0ÛÀ`0£§Q«ø­mÄcdÝ2SÙƒ}¶‡m ¾×yuþůMq©T* ëu’¾·g¢Ž½ Õ_½fÇú>Ö cm¶íø­ú¹ûîþ‘ /¾@V´ƒz¶·m�Çu^-œ~Ì›îƒï} ù©O_®-ké±®'ß=¦µnÚ¿ç±®Ç ã®¶ NãܹsÛzäܹs^|QVõƒz¶·mà6*wIVœôé?úÄŸ¼ñõ¯»÷ì=W¿ð¥HO‰D鼇/¿RK›Î)Ö cŽã¸íϘ¹öÿÙ~¶ïúAÏŒÏÍ®<ó̳…BþôÌ‘ç^ùúøù·«Ï×®?ß„õô¥Jñ¾Y?hó#?úî7?ð…§_úØ_}IƒÁ¸»m¿#ͯý;€g‡òÚŽŸõù/Õë—yžO þòåoz@cùú‰ ¾öÝËÓüÀ–å˜Ê§~ü]¯;==&‰BµáÞX¬üû¿ü;»î¬å‹ßþ…¿ŸO�þ·ßùÿæ–«ë>|vúßx~z2+ðüB¹þ¥o^üÂÓ/% �üßþ‘Œ¥ýî'¿üÕï\>D½�§^©—RùÉž÷›È¾ï^{úh!N’.Í}ü3__ƒÁ¸“Œ6iÛ!'ð]ÏþÖ?zO¿Ûéÿù‹ažÝp[Ï‹ü†~ “çßt㙿Tàˆãš­YZf<å—^¼¾<uÿã/lYÓ¿ÿñBÆXX¶K Ë™”ñàébâV£˜ À™cãmÃ�àÁc©ë󋢤�xü{î}ÿ¯pùú¼ëù÷š~ÿ»¾g*g<õ™g×}{é¦Ûª©Fúð‡6 ô2·†&ÿÒO>¡«ä¯¿òMÉ;ßüèXZû•ßûK@`C‰Á¸³LÃc;ØN\èÕï|ýž‡^¿å³¿õÞóËÿö/ÛÿæÏþ½~ÏSj#ˆòøýo_þÖ_Ixž+_þ&_ "W;öQ-‹žKé…ŒáÓà'>ü/Ž%ÙÒåV«¥eˆ¢ àžpiöæ©™#ßÿ†×üéž6sS†*ÿÈÛðñ?ÿüÇþüó"Q^ÿš{?òs?öý¯;ÿ™/=»ìÞ*jÇÿáW?à©¿úú»ß|¿B¤¿øòóWçÊ?ý÷^ŸKéO_˜ýwñwqœ�øÇ?òÖSGÇLM¦at¹´üGýìÍ¥*€ÓÓc?ýî×2Æó—æêM÷mÞó7Ï\üøgž0–1ß÷ÎGï—DáÕËôÙgJKÕ® ž96öSï~}>½úx§ö£ï|ì 75Åõƒ›ËÕßùÓ/Ý3=®«äÆüòÿù{ÿQ5R¯9wzzªp2¯\.‡Øb>ƒÁbJ½ãB?üióÍöû¿Õòéùì¯|ôS¿ñ?½»mÖÿ^O°ëÙmÄ”ÚhVVŸyÌ¿þŒãG‰ h<]æ'ŠãÓÃTµéø "ýú?ù©Wçk¯^_º8» )A�N…ÇÎðÑO|êWþ'Æó™SGr‹nröØ‘Ä$Iþ쯿ld FºðÊ‚;¿\,¤ï?9õÙg/oV¤ï}Ëù+7—¾÷øû¤éø¯\[Șê›<ùõo¾ðÝë5p\>c|ùÙç—+Õ‡ÎøÜéŸûá7}øÉOZ–ù ï{›¡ÊÏ_¼Úª7ÞúØý�Zµ•êÊÜä‘c¿ü“ïÌZÚ—¿q¡\±ßóö7üâû¿ÿÿ¯OúÑ­¼UYúùÿñmº*¿ðʬ×j¾õ‘[Ûî?5õÄî»6·üÉÏ~Y×ä‡î;ÕªÌûãi�¹´YœÏOO™:€SGÇ_˜}Q73Ì:0w–ßÀïè)®ç³g~S?s2øÙú»Ÿþõý €.ÃЙàöÖ¢;‰JœÀOȉ‚A‘¢a«DÉïþÙW~ü‰G{àÌc�Àb¹öäŸü×ù•:8î¡3E]!Õzó;/]~î¥koyäì÷}σO}úYSS�x>m9þxa†çEAª-o²€”¥{NcsF¿ý‡öµo¿üÿþ«'òŸýÒÓðŸ>óáŸù‘w¾ùá£cÖ×_˜5Rù_ûÃÏݸü‚a˜ûìËûÍ“ScYxå9k¨òŠ]û'¿ñQ‘(†®?|îdÛyèžbÖÒfK‹OþáŸÕ˜>2ùȹ“÷O§ž½dó¢´;]ÔU¹\­ÿ¯ÿ[A’ëÃ?ùš{O´’% @£Ùº¹TY¬:Ÿøì×|סüµW¯/œžžøØÿñ¿h¯¨ŠøÌÌzƒÁ8¬ÆÏíà)Žã{?Û/µõëýŸý§¿ÿ™_ÿ‡ïÚ`}s|{Ú†/(Ôç/…•+:f‡Rêû>èJcåˆY8:Le¿}iþ‹ÿì÷&Sò¹ÓÓÿý¼ej<÷ÄcÇÿSψD}ÃýÇ|í¹9^øæ+7ßòÈÙï}íƒðÉ/6\€"]W9ç—1u�µF+Ž"$ݹ\¾>—ÊOzaàÕÙ’j¦C^ I"õ]Aä~â_ûð™ÒUyý"pº"(Í/ƒ²“Çk·‚BÙ”`¦8þçýÕõ‹ùtã›—¬üD;”25�7æ–À󹩙ùŠóšµ;Ÿ¿\úæ‹W¾wæü=3�–*õõ±Ï,Øîo<õ¹û&´©±ÌüRù œ{ã#ç«õFÇ1½#Â`ÜQ~Ã(×ú¥Öêûì¯ýÌ‘¨ÿý>Û3ß>~C£ä5ìÆå¯;‘xâ‘w¸õrå»_à¨^ü²l¾GÖÌÁU•Dáü‰ÉçÙ­æW.Ìå /ÿè»Þh芽tóØé{<}Ào}ío}mû~]S^sÏ‘—¯ÎÑ $’øCïxã¾uƒ—ùNMMäL�ßxþ¢ ôX¹¢H”å¶PÂ(’d…_['O’øóC'ç–*¿õÑO´÷_ÿò‡xžç8®Rk82Q ŠŽŸžÈ¯'h×]�×ççãÿyýb¥ÚˆÂ Ib^Ô[€B6-J2~<wë= ŒûO¾Hk‹SùÔÿð®ï}ã#ç^{fòS_»"ò7^] /\34ò³ï/€ç.\â \ß&`0wQL‰ïSê—Ú†˜R¯gÿÅ?xçºÇÐ^¢øµŸyâŸý»ÏmÎw1¥8 ZW¾Ž›zèqIÖ¤‚Ýóf÷ÊWe™H’Ô¼üuùþw ®?‘Äÿù彮´TMœ.æ|ç¥ËI=væ¨(ðŽë}ëÅÕ}¨3GÆLäßþƇûÿæOÿæ›?þÄë>øÃï|óë#ð§Šy�ŸÿÊ7^º|=7u¼whžã;Vt7˜Áv!£("yë;ãùÕ2ûâõFË+dSÿúÊ qïññõGž»x£RkNOÿàÛ^³ÜÌXúƒ÷LÿÁ'¿Øœ]D²šà WZ®d"ÿs?öƒ”“_sOqýñó'§Þóæ^ºRr=ZœP«7ëöâoþ/¬6œ–ë?zï´®Ê_yö»/_¾ž›:Îï¨'1ŒÃj6¬ ÿêO?ÞïÎþ‡ŸßøTïw†ðz<»žo;”ôÏÿðóí+ÿâ¼ss¾ýlCŒÝÒ·ó&Y²^c­íÖϽgÙ©L›$II’ܸöÔñ‡ˆñ§ÿî©Ikzr\&R¹ZÿÛ¿ûÖŸ|ꋊ•{ÃÇ|êo¿þÿé³íOyÜϱùá¾öÁ³âøôß|ãÒ¥w¿õ‘SǦ¿>·ô™/=ýçýÕHI²Š~ë¶\Ï?ñwß¹r¦˜yì܉üÁ÷~ú+ßñü@‘%�®OÿÍ'þËOþwœžüÆ ¯~á«ß~ç›^Å1�†¿ñÔç~èMg½ÿô[Ån´^º|ãÒ¥Kœd ¢Ô—ë‡ÿæ?þ—Ÿxâ±ÇßôÈ…Ë7¾úí‹o~øl;ÇjÃå9¼ã{Îi i8Þg¿üÿüùÿFŒÌ’]ììQ]UÊÕÆ'>õÅ}ò¯Í’d•DŽÅ”Œ;È8 ù%¡ OñÜ÷|_§»±ùÙö|¿oFŸ]7 í\þù¿ÿ¯þÔ;zçÛ•pûü†«¥¥®œÅKÇ”Úw®7¦ÎogfI‡¥g9;EQ­^¿XÓõ±™5ãhñÚÅ(ÂÐOâ„ÕHÙ‘”Åë©ç詜™k?ç»­êâ Üø‰û8 Y[ñ[õÀ÷$¢HT+£[YA$DV®½ølGé”™›¼ñò7ŽÞ£[éÒ+ß ?=V´rå›WZõŠfe³ÓQ”çg©çð¼ Y™Vµœ$q¾x2—›+]uë•0 ~ûW~öÁ³Ç?úÇŸúÌW¿›˜%R]*¹­Fà9q ‚(ÊJ*?¥êf;¦ÔX•篹 ; YÑ8Žóœf;Çz+ó³Q@“8æyAÖ +?Eduùæeßm&Q,ˆ‚¢§ÍLA‘U6šŒ;†Úʹs>QúÂ×þ¦ßÍç_ÿöU;qá¥T~b/ž]¿­çÅö³ë¿ÚK¥[ç7t™Ú(ÓZ¯\¯Œß÷Vð| NâÂy‡VÏž:Þh4’«×¯´jrÿÐx^Lã8äÀqœÐžÏ‹’,ÅÊOò¼À ¢(É’¬� ²ÆóQ4 Q4K%_³8Žç¾í ¢D+Eå8—+*ºÕ®Ejìˆ(Hœ �0³ª•%àÍLç€C[­+º%Jà~ü‰G9<2{cáÔ±‰ÏÎ4÷oÿî9QÒ�Žã…TáQk ž8ŽKíÄoùqBºp„h†(HÏ'IbF¡ J�ˆjd Gx^äÖ /ˆ’HH*7Ç‘ ˆíD$BD ƒq‡¹ Ý3ñûßðŽažê¹ž<òg».~÷mÃÍ•ë[™~T”äÍé*ºõBÙ)­¼ày^ÐFà(æ#ý‹ Íìm9¬ìx×IVÒ…©õÿE#›¾Û&3vdýïìÄ­—-R¹[ÖO”Hç#F&¿9¹•úÛšyÝ}Ç\Ÿ>ûÂ¥ßû㿨6Zùâ$ÇóÇ ¢d¤óƒ›D’•”¬ôüÉÜTA�z¯O¥3Œ»3¦´Ù¤س=cJ׿+wm#.]¿ØªWã(äy^”U+;&ɪb¤y¶�À`0võ·Yë ï æÂ…—T#Eí ž]¿RžŸ½Sº›B­Ü¤¢§xQl¯Ô󂨨ϳ]C c‡´C¸pá¥áQTû©ƒz¶‹­ß}»ãQÍ´j¦Yof0£4š!kÆíõlÛÐöœºÍZ”Á`0îN4+³Éo�œºýñ|€I‡Á`0îN>𑯛Ug0 ž|òÉÎÿŠ›ï¨V«LL ƒq÷ðÔSOu]a~ƒÁ`0ÀlƒÁ`0˜m`0 ³ ƒÁ`¶Á`0Ì60 ƒÙƒÁ`0ÛÀ`0ŒFÜî™L¦çuÛ¶Û?ÙöÈ>Ê´9¯®Ä×sìÌz7ÅØülgFXµÝ×ý`éW¼ÑöžíÀåÐUªí–gäÃdøŽºGY°Óîu »² 7zÊs—M‡Û†ýÊ0yíuyªòÎ×9f2™ŒmÛ£-pÏ©Àa0 ›+~xJuàEÚpI‡ï)ÏÃÙô‡Î6liê÷tºÝov¿Þ~í+;È·Âú³ü’~“åQy0j½¹²9v^ïú{?›¦§èF;ÝÛ²^ÃHc¯g=’¶è’ð޳y“ )œ~½eŸK¸¥<ï6ø=îæ6¹öé7ïØë~³UÛÖëW’Îù{×ßû_þ.+;Ú8À0õ,OŠÛˆÍ9nKÚû3L¶›õ^t‰ÁÂé™ãàîFb4Ã`¥Ñ¯é™ßÐ[CíƒtúMúõªq¢7;˜#™Úô”óáé‘[N{GRÔ}ˆAïÒ<ìóeß‚B{Ô+zŸ}Ž;õ­»ozf†ʨ÷>7@ÏXÍUmußA‡Þ‡¦¹ãc¯úÉàŠo)êC2¿ápë7©?l5Ý릿KmÃ!Ôé{7#>œU뙽Úæ°MÐ:˳å„w˜6ºS•ËfgúPy~=—GØôw�ü>Œ¥=âÞÍȆìÍUëŠhß.çÞ5ÍjöN°»i‹ÍK,‡¹Y7ïpzN·‹<o3¿aÝ,d¾Ðáé´ùý–£÷.Ä1Úªª$]¥:¨¦Ù®gö­]6‹z@·ÑËÜ3©‰ïs7,œžù`Ú0} wúz÷èãï{ïû?tc©¶~^4;÷Á`0ñ®¢}îÛsÕ¬fe–K—¯_x†}3ƒÁ`Œ=¸;c5· Ì60Œà®Úz;"20Œ4 æ70 ƒÙƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0˜m`0 ³ ƒÁ`0ÛÀ`0 f ƒÁlƒÁ`0˜m`0 ³ ƒÁ`¶Á`0Ì60 ƒÙƒÁ`0ÛÀ`0Œ;È6ìø<¿=ÈŽd0w3]:p°J‰ÂäwVÊ®?öÛ¶ÙQ ƒ±oìðLÐõ³^;„mÛ]G¿v.åÞóήd»®ôû•Á`0îf—bK5»ƒC¹ùÝ”£ë¿™L¦S}¯—f³Nß2ý~Oí,MƒÁ¸ƒ Ã`•Ø¥™÷ÖoàL 9©o›²v¡7Û´öõ~) þ•Á`0îxaÇšyomöœ€Tc}-¥§½é÷+ƒÁ`ÜÁô ×co"(Û‹)uú/[vºœf`€ÏÑ3ñÁ¿2 ÆÝf3:uò؆ýqšøÌc`0ŒÁʳç4ýÙ†ÎøO?c³Šg1%ƒÁØší§w¶OIÜA9†¿ÒïïÁ‰ Ÿ&ƒÁ`Ü=6`H•8Ì•ƒô†t‚X«3 Æaã m‹ 1 ÆáD<À¼™U`0ŒÃ©cÙwX ƒÁlƒÁ`0˜m`0 ³ ƒÁ`¶Á`0Ì60 ƒÙƒÁ`ì7=Þoxê©§˜\ ƒù ·xòÉ'™P ƒÙf ƒ±î˜Ò?øA&ƒÁ¸ÛH§ÓøÈÇûÚ†öûS”jµºŸÙ’¬o‹òl §4Ú¥:„«qíùÜ¡×áïχªœ‡¡í2 òúÝ7ržzê©ue²;$Yßå9ØNit–êPùÖétz]J‡D\‡¿?ªr†bt–a¶‡•Á`0`¶Á`0Ì60 ƒÙƒÁ`ì’mŸûÖu³mÛu´çz¾ØÓÂì!¦ë’?„çåõ” ;óõ6ê]·K“ÝjøZP>âÐ0ûVž¬øí8$˜U`°NuWø ëóÖL&ÓÏ]èô*vߊ=SÛœo—±^ÂQ)âJgÙú¹/»Wëý$¿¹â™v^ïú{/k³èú•s—ymö\w•íŠezì¶„?ò¦IFØŽÃôá-»Ðž–p@îù÷> ®~ª©g.»Å6ÖÖSï—Íz!6‹l7RèL­gO¾„#o¡‘Ôtg’ï4= ÓÖƒ:±§$GX…u“Ü3µÁ¿nKëŦ«lK,{×c‡þÈ›f´eao܇öÁ%ÜŸ¹3ÙŽj| “ËnDq»®Eï©öïÙ�ÛzjbAv‡¿QF[ÈCd뱛۫߯ûÖF»Ïz„å&©íæ5BÙnkPž²ˆÒÛMÖâÙÚa®énZ}Ç%9Ìâ=ØùÁnôÈ0vkKÉÚ¦¹æ½3zãŽ{¡ÕBâ!±8½Ú²i‰nêú¼Õë`ÒÖc ½†i²»pÑõ«ò0=á0 ß»Ñ;Ú¸dO·î0¨Î²uE±o—ÍE£j¬ý‘ùaŽ& .Ûä<Úq´ îCo< ú0ƒz½äûã1 Ó¬»¿B‰\z¦ÖÙN[6äHªÓ3ýô·%¨á½‡½¨Â~šÃÌ[v•}+ÒðÅÜd#/ùä³ÏÒÛÁ`?$cð�ûÞ0¹ìfHŠ;(M×ß=/î»´9ßžÝz/ 0LM÷Hƒ“ÝÙ¯{Q¼}è!ƒ{Åà‹{-Š•mp9÷³`ûVª!UWß·Ñ·šp»…ÙqIØ73 Æí\bì'Ì60ŒÃÈ¡ŠÜÞ…ˆL ã0›ƈŽù ƒÁ`¶Á`0[Ñ;¦´Ï¦àùì‡íhøCxTý–ðpJãÀž¿Äuøûó¡*ç¡÷èãï{ïû?tc©æÔí‡Ó•CuN:ƒÁ`0ömÒó|\³2Ë¥Ë×/<ÃbJ ƒÁèF¼]\æjµºŸ>WÛ:´ÑƒÍ’¹-ŠÊäÀÚôî©ïíU©vi·° =ï;Xžzê©õ`×>D½Òéôº›(Hæ•ɵéÝSßÛ«R¥]‡Å” ƒf ƒÁlƒÁ`0˜m`0 ƾچ͇WØWïTá1J›ÓÙ2ñ;xŒ°á?r!ìð[{ìX Æaãn•L#œÚ†õ¯ænþ£ó†®fëy¸ö༰¹*¯á+¾ùpà~ïd7G;—®¼¶[¼žYlÙa†ì!ÑY~%‡½ûÊôv‹Ú)É!‡É0uì”[×=#©õ–éo©‘†Oj[£xT½q@Ãmëâா‡1¥Á-·^ uÙmy±§ŒF5Zzæ>ò¼†¬ãv <BÉ È–¹ S¼!+>øþžûîwÉaú^?-?¤$·[Ô-ÛzýDåͰ²C¦?ø|ÜÁIílïÌ×YÏe»ãbp!GRqT•Üå=ûæŽvˆYñΓ·;‘¡/ÕÕ‡È0 7¼H÷z¼f9ŒÜ< .R¿šîx˜ÜFq›ÝuÀÁË£u†ú©‚ 7©Ò>Ù†a<¦#‡Å û g$’ÙýùYC6Ü–Šï`úðÈáð×tpïøUß~ƒqbƒ›]ºa2Ú²vÙLâ^wÐQÆ~êÍõž½ÝÀýð w[Øø»G;®é¨äp[†Á‘ýXÝVÃ Ó »,$¿‚>Th/Ö6†ŸÇµ]Å“‚½×àiH¿€ì!lñ]&{àrØ·°åÄs¯§œw°Á¡QìMڲᶛõŽÇãžØ†žžQçÅ=t Î}´sº.E¿3_~¯ÏL^ ƒ/h¸íVaËÒÓÑÞ¥dJ{Ô÷vУz®¾n·¨û6CDn*˜Yc[ãbp!G¢RÄH }–Dúý=ü £ŠÉl™ûÞÅ‚úå2¸xÃ\yÀjøÅ®an»{ ¶ÕF£’ÆAÉaäKˆ=K²Ýâ )ÁW¶ûëhG÷ðiø¤v0Z÷­7îF¥º˜Òáq ™›Ì`°aÂ`¶a_ã6 &Œ; ñnë÷‡3µ;I2LL æ70 ƒÙƒÁ`ÜôŽ)=õÔS‡¶Äû|6÷aÅí[T&Ö¦wO}oÓJq>þ¾÷¾ÿC7–jNÝ~8]Ù|¢4ƒÁ`0îxÒéô>òqÍÊ,—._¿ðŒx°³rƒÁ`BºmÓO>É„Â`0w%Ù¾¶áçþç9Ž>¥$IÏý‡ª0¬²¬ð¬ð¬²»+üI Ðý)L’$øÈÇ×ÿËö)1 ÆádXð0ÛÀ`0‡z€ywÛ†my%;¸»l+ý½.<«ìÔ”Uö�» «ìíRø÷æ70 ÆŽ!wh¥Š»¯³ ã®5 Å;Ñ<Б,Tì·mØk/ïPÁ*ËjÊ*{éÐ;¨²t÷-Ëüƒq×B™˜m`0 ÂD°CÛ¬ÁDÃ`0î8ÃPdæaH…ßck&5ƒqgMóéÁ¾Mve2@᳘ƒÁ8,è{>ͧ;Õ³ãmH»u}v^lf Æa¡µ¯ÓüáõìVwj{UÄ`W®Ï®Œ+³ c4ïîŸÝÓøO·žk¸;»qFY,«Ûìúl£‚Ì60Œ7 ;ž±îçŠ1m›„ö÷¨C Þ·Hû·JQïöŸz£]AÌ60Œ½gˆ*»™±ö~vï¶Ç¤·ˆ m²U#ך;ÒÝ­áo˜m`0{Ïp;Üw3ѦÛÊTä]ø+}Ý…^¶J2£h4ÚäFãr1ÛÀ`ܵìGܦëø0i²PA²(J#«d«ÀÝvŠÊ.W“þ^ήÂlƒqwÚƒýës@z£=öÀt­€¶P F³$pK,}͘³¥vîBf—¶A"û•öäÆ×½œÝîve¶Á¸{&ûªd?^K€•mÙ½[G¹ÌP™aÐÖÅ¢ ûHq°ÅM€y`e7¥â‹ˆ;ÒÔ:ÿ6•”Ó¾œÐµšM™m`0n_]¿ËÉ~—*íîÆÕ¹vj76¬Õ=ÿM6ä·ÃŠsC=Þ–­³.–ÚPiw©à­,®¤·[| ¿„€ör\ ê¿…vPû&Ñ«ÙÌ60k¶¥ë‡œì“þÑh«Ýø[&î_‘`U¥Ž$`E %кÒ$"`nÇ}¢HƒeK¶(çp^¿ßÉÖ¢è±Y‹—·oã‡jfŒý'³Quî}Ù0nÇ�QÛÆdp+{³¥*Ùqz›Óça°�àü"²1’~çóÀÀ ûb³6D‘è¶Ä¢ û’A‡ âž¦yX±ËÛtvÓÄÌ60#Vú"0¹>¼ÌŽÿ®êÿçÀÏtŒí4p8d€"0Ó¾u ˜�N:$¿íév  ú¶ã =(7HÓuȃN�� �IDATi™-¦ÏâveÙ~l…b¡„•n¥Iò2d’­5]w°ØŽÓÑÛÔèÐÀCúðê˜æ·¶[¤íu¨»í¢ÃšmfŒQ1œ“0óp/p38:ƒq�0€ÌípŽfq䌄5 ¡‹€Ø€½fFÈPñPL P¬PNÅö˜(}•Rª@¾£Ô«««wf@(Ì’¨Ò ¯nñ½Õ®„Û¥ä×¢W"è plìùà»>ìö–š. *o¾' ä¶«R7ÈŠk‘pp¥Z}Ôqo¥KÅá&ûî:*&¾Ô]žõy³Ït3ã‡ö¾\�"(-"´h+n{ýrDÈx("щP»Á54Û–€`ÎB¤pLø“¢^(Zu  `Í<¬æXµPš�= \í¡õ�Y X€ÔVBq[·f\dzéMb¡XG ÔVíÐ~÷ê–þÒ kjÈm[‰¢ÓV…ˆ`4Ü<YÖÆªÃ1Ô[rRL"x`°�yÃ<nü£ïg-Z�ÝüShl³ÑµÕpš ”€Ö¶Ñ…è­c@ï~­yð.¦,h %tÝ“Ñ;$Iü~ ¿Û60“À`lŒ¥�µw˜> È@…L‰EK/-:³ó‰)íøg|,¶È24~~Jˆi±&‘§É…T<W»4…L.R6n´€ÔZº­AVó2€èHÊ„¬ÉFÐ@ h p\P0€px€"DHˆ{}’Z‹`) ³ª6o)AÚ®ppùuÃ2àf;ßÞ­ˆ-ЏýP²êsDmEOLÐzG`ªS—q@¯9&"À¯9Kål€*@H€à<ÐÜbZ½jÛº´§ßSã7›„ Þr£�8ЀÖ£ük ¶¶÷p ÐAýQZ…U‹Åqr?›*²ÑÏ`À*2àg:Õy@¤€XCƒ‚”޵Ä` Í Ž 8­„„ª L`Jõ'�' / çžO™¨W&“(·‚LªQ˜죯HêŠæ Q»)Gba¡@,Ñÿr—JÒÜê,œp8)à²&QiÙš ½FÔà^5‰L-ªÚ—غ˜æj«[ˆˆ·¦qW± ˜IQ\,9 ® PDTjÇ4²€Ä]a Ph·*žÍ£UFÛ0Ì�3@�T€Ëp(¡èt(Ö¶ [N´žFS¸›÷Š ˜ Ô�õÖLVï°¾°þµ‰ A€ò– z‹6Ýf¯Æ¸Z;Ò»Yœ÷Aü½z…Sb0î\{ÐùípJÒ½8)g`ƒ´JÀ,Y5 hAäWõâ­M&(rôá$“A®¹¤Éaã‚•=}´2¡Š™9I].ÌDº/k‹‚„–k×Õ"” 3u$?QWOZ’æMF‚6ýR@4c6ò© Eq¤$;tú!�x Ž¼ 5D^ÌÏi<ÄЂbh±™à,\ÎZk¾®êŽ/†‹"ž.uкYh{ÂÉåHÑö6y´=ûM:ÝÂMŽúѪÎ,ÀÀ–bºªyë€8à�ˆÚÊW e§í1d „Y¸:j.è,�Pqã[ÊÁæm¯u‚fRiƧ°Ô¥­øbª ÐH?u¡ËéYwâ*h ¾Ž®Ù6Ò+Ñõà[|®•î¢;öhÑöÿíÁlãŽñkãª=_NÖ•G¾Ì!ª œ\ø§¸p<Gý2–´#)e`�ÊäÖs$À½À‘Dœ€gÂ’dz2«æó3êØD¯$ ±`y>'!Œ˜¼1®H…%+e-¸‚«HVZÔ¢ _˜7+ )”RÁ :uln¢Š9 µIzžC6ƒänPØx@ÄdÚJgOª<™ yð‘@ãE.q3žc[º�%§­`¼qUÉGîtîùVÏ©´YHôóš‘WÂzÅ{ yÀæé¦ð,h¼,p@$ Š@‰%@\CP€ @@®éå PÉc!'Ѹª³n 6(£zOE—àS0ºmÀÝz-Yâ¾Sõ~€ è@ _†ó«Ú\¼~ Z�¢ÕíF« '1Ý–ö,�p�¤¶…S²›©}©o¤k[±,f ÈçËÊ€ ™®E%lÀÆÄ )<$D&‚ b’……à¨vb!ôa60³1 N% d-@!8B%S$­¡êd’$f,3ÅeãZ@coa>2]E”=9€h¢¢çUVÍ ³|8‘7m¢Æ“F\(+¹/%˘]tPã «° ð@hŸ1+'52qô” ÁKN8ŽÇ¹Šp%nUФã1ÙÏ‚¥{†ÄqMiJœ'3bVç9/T�d1Uèº6Ãų*ˆ*�!™°8 \\ÍêÓ�m¢Äê€ hÀàà€´„b+Z·µ% 4š ‘Z\1ZX¢]êA*OÀÕ¹M m¥„@sí'mm-Ú½uóªÒT�HÔv¨ P ´€êêÔÀEt¶#Ê�éŽM!PZ3*~§Dôa_±^[Òpûù;Lí<–Ålã#ùmM2‹ À�®tÄ¢ÉZÝ ‚œŒ–ØÀ‚‹ešŒJ0y;ŠíV;© &ÈS¸IB¤DD‚îNeçõtÀ)©01¢šÙ@èÐVÔty·*IÉ„,rÞŲ»ª+šlH¨HiN3ZÙb1+:¢¬ ±.|•,s\ÍÌšgM.Ÿ“.·<›ç„hqà³Ð !›U i9ѨùŠœ´Â4–+b½(ó'8ÓHG‚jÈ-AˆÆIæ ŠDQ,+Ò•E¤ ÛT9z]—A!/Û€½D Žc¢�¹ ¸@ƒ�÷Cðô qði4€q @3GQÞðŽ›�4€&(¢’®ÐêÚ^¢�fÀÊ,@*›tT„ð¡×fЮõéDB@êÖœT¦�XpaË@ÐU; 6øào{½ÊÞTªpˆ¨‘<|G��—0ÒÀÔýfw–I�…Ñw!Òµ}òS³ ʾºÜøÆ® ¨ 1̨sO�Κ…(@t¶ õ ’1@ÈÁl¥õJ®D Š+V±ÆŸ­ÅNìÕÇÏVœËæ_£ ¹QhÄr5ƒJ˜È®,«™é£™$#Ë…(G½1—§UîŠéWÕúT G”lAÎŒ[ü|Øz®^†K &rf\Êä K&Í0öq”'äÏD˜ŸTÔD #ÁÁ$DÃÕ-K¼)“HIZ¼0.eÆbM+¾ÖÒR’Z4HñE#„JŽÆ¹eÛ£¸HÁEÛŠ;Gø:••ˆ4 …¿úŠï[‚ŒŠNÀÊ]ópËÖ_A<g©ô˜Šñ<J (DPƦãÓ¶â"M!Ìq  ˜íÖT u«è[ññÎI·÷ÞÚïnÛ¿¡° Þ ¿ùŽ)²¶ë v{¡;Þa?³�g¸76µH]2LôÿæF•Ì$»‡ÙÆdŠ@ “4m!äh³=ÛŸøi1@ËdhEÇ­Ç) ÐlM¸Uà‡�¢„ð0ì$F½šA!Èý“¶WvýjK„*Ki’^\ÐcjVáKµ8¦bb9ª. ¢šöÊBX_¹^·k⸜~bWuí¹fìêäLJ~! ÏOfjS‰«Q1¸ÁçxÓ¢ùé@ÖE#UÌ :¯+­fk…ˆ¯1R͘ʤU1Nà$bÒØòÜTƒ\V2'‰£6”�&‡¼éóIìbÓP ¨iAJËÉåcÚ(ŽÃ­TÕ+¡’“ýS©úÑHZá1ç®\GM†”@œ@hÂR_–HP§^[–c€†HA¥Š©“Þý‚…ž®!›Ç4`$ó6ÿé<ïæu:©‚KCÈŸÎr™²­6ãÒJ ~ø€¸A1æh®¾ÞÐcóh$ ê¶£^ýÀ™oǯü û™Úêx]µê²  2‡b‚@¹m 4lù‚Äõî.ºÙýX£ÓúMîÚK/Ì60;qºB« ixš�ZÀ2ôEpíÝñE¹”]UF­×BlæÒ_ eÌß�ŠñTŠ%:z aÞ s2EÁ%2oN§…¬¦¥`¼šãŽO“2¸2©Þsíšê6µ3IÔDu%rçPe<¤e•8Âd ¼`Á7œ†g»¢ž¸"Ça]‹9ÿˆ¥¥Ò|̧„ŠICÍÖ½·Yjj…”™ÉÈD%AäÛ!ÇEºòǪaœ­ä%)vâh%òNu,j†•$žTMN–Ì™TˆTEReðZƒH4ù„Ïáø± !…:$¹xÄ/å¦ÅpCÊM4sS±:èÔ-!¬R&š<‰ZSˆ¯«qühdÎàh>²›È~ƒkÕÌ1NhÆ®S;íF7¨•QÄ8È[nvL˦83«*Nù¨QŸ»x…‚Î�µÙP` r aÕi¸eD”µ}eŠ%€®­·¹ÐÃNl6]J?Ž@c`4Y³=÷ÊVŸ!\wC†MáiíµÁ­XÜ–Ó0ú­™m`ÜÖ†á䯷ÒhÛ1_¶a�O°LÛQ" \`t¨7!£*OÆÈæÏ4Ô%dl´€Â È‚ŠÑæ%Æ”d›R%”¸XSåüd`æcâ…¼“fUJãHô«¼më » *.‘ò$“è©©–¨óaÚ‘U'–=NRª‹5¸QJÃ*ðy΄+6Z’lqÒ´‘T9æ /*² pYŒ]—ã-‘ä©AËqÆU©¶,:Ë*–©uq~âíáÌtÌñâJƒ+‹± 5 ñ Vq•ÔæZ7¼Å›\|v,•ÄEBí,Œ–¤½!un¦065+t½ÇMåŠ(?§KDŠOYºf¢V©ÖŒ´hhä¨7­<Ÿµˆ¨‰z9lÂ{Y%)´¤Ôšl«Dù(%ÙÈ)êéÄR „¼Äâ 0“:jµ–i×C` 7+™üœíRt.™† Ó�Ø]ŠJh¶ëý†^„XýW¿9'«¸\_}ƒŒn60nU¼®pϬ®]­ÑÜy§Õ˜ë«ÊÛ³" ^Ýï|3³ ŒÛÔèÇ €µ—œ´Í÷WP'L5€.aNb*A^Ýr€^‡”øu’AP{õm`h€_8`)€mÆ$2qµä ´øÂ¤JࢋË|¬æhn¾–7Å)'òFEZ©"œÇ*©±¬jæ²|Õ%^ò¹BÕ1c. øDÍŠMSm*J>J8J%4“¤tÄ+šââH|,‡LJrȣɛU]ñÓÅZ³!$Q¹è—oe¦‘p°%4¡›±¢®Äñ¼h_’</û|´ˆé›Ü¸_ Z› œ)ÕµSA~¬0óPÖ*ˆ¡g“¹R½»I-(ám¥–#5ëØMêÖÉD\8:¦èDoÄÑ+>Wm%sî²î»œò†µÂós (˶,7S¹ãQ3çD‚-Ú”\±…rËE˜ÑIÀknN·ÇE\‹`ó3H‰_ºö¥`Ý®¯Yø@#ÔAË€ ¢ôêâÚg,Úß5ªôêH“€�,Có!]E¼ ÖÀî¶ ëñŸ£À àßúÊÈöN¯ëJ“üA=<€„›ÔýÀ}_;ÚŒ´ÕN2fû£Í·¹fÐ?A™Š@ � |qµ#Ú0Óþ:œƒ šrÂLs.½Ê‰vââ ´?§îÅÅÍV0¾ÓÓ'@€EÀV�Ôm•ŒÕ¨9šÉ5c±àK‚%© ä‰Èò‰•â¦4õ”9acaF¤Pmb†’ddªJiÕÔ#Íkµl•Óåz¦)J5JÔWêX[¤åV¸Ld%ðLž‹"Þ!Ñ’W x!®q$®š ï.Tx%Õ$™ d#|+‰Æüz®Õ”@tÁ I"h|"p¤œ8­š:険?¼zKO ŠŸ_ö V^1ÅrÖ#Y+Ôt^KDÞL)RµâWÝÄVÜÄk#)϶¢Êø¬­œ?íCµt± zrb6—ÅÚMñ…¸»!ï;º^ŸW®Å)48hS5‘6ù §QT=$ Ǫ•½r½^sÔqd)Œ•«:‡œÃÇ,d§²*)YXºØ©°€…Ž.án|˺3¶Sßʧœ_}jÓÁáÆWÜ7†õÏ–´3M>ÐrPໃïl¿`hoR÷` dm�nµu—ÙÆžkómžAIÉí¿ K„uœ˜—NEölPFS�Ò”ÏF{(¥!±ÚyGK@'’FûóAxµýˆ4ñdÚ¨´Ç[ ñD3.¨ð@TÁÏ‚C9B˜• ÉÍ81*4DÕsÅ4çÂ$ÂxÄÔwÆ ¥¢´È¥øŒé‹bHára¢%ºªè’両Iźî@£±ÀK‘DI&þ2Ï×Ãæ5êI1g B ¢ǶÏW…h>’Nèœàb1‹†5hàÕÕl¨êrk*áy¡œ/•Ó<gAÃ8 ëD÷bãù1sìTâæaù¼ÄC=7oDâ¦TW¶ZŽÆU’C½Y•^õ—¿d…³Þ¢Í'-ÎL·nNKÓÇêÎ5¿yq¨Qx¢¿l6¨aºA¦®ˆnµöÍzÝCô€Qwœ²î‡IUXV©!»²6G£9ÙM^ÒÓ‘¯ÈÖbS ìÀFHa*8N.&ÒùÐ#"&Ö^±è©°n-l‡õî(�ðñÆ/bÑ~‹Û¸ðÚ_.0[íøäGGNÏ!°«·£“[&hË÷G2#ì{JŒ‘Ïñ‡ôg»^NÞ:A±ÿî@±íÎÇ7!(È“¡:î¥"álmÉ,>óÅfÙò EX”àë n¹™4* 6pµ#÷L)Sæe¯T$$%¨T U “œ‰{3qBg_ªߣ ‹„S'ɘªqºãçZ)ªÆ§*ÔÀ•š­|Ã7ŽO‹MƒðÞÔ ^ ^#–<_æ›AÌ%a5Žk~LbÞä .¾PCŽD¼¦šN´D©™4cWÐñe]Z1G#/„¾œ¸Fm!¦~$ÍU1ÃQÒU¾&žªŽÑÀmÇ“ZAH)Âiê¸HÆ>ö8EuL³eT“¤ž®OE ë-Ïqêb¥]àj_Ô¸PÅz’³A Ùüy…˜àµìr}ž6¯è׌EÓ¿Þˆšæ²X4bµZ²rÙEù•1L¨GÒÞDM WÝVãÚòÌuS½Á%Šî™¸ìh¼ö]N fˆyqø¡ê—<ßl¿¢à´OË´0uÛºýžÜá(´§Ü"E;_séן}@n§ßZ=…ÁíC·‡±W¡ÿîÍ»¤•–}£û.œãÇ‘ÓQtÁÁÝ1³¶ç¼ÿïøø2·zQëþÞ�ÀâQ™|ZS8bB"Þ<"5˰<MWCkj&%-ׯz ß0&"v)¿Ñ0¬iÊ÷t‡¶�àhpëp%È€�8®k“©ÉµÆXææ|É� xW¥9‰È<׬©Iø0 qÜ�–­dNäÆÉЍÀA X4.›nÓwªˆæM"ú¨­%Yr3â´FR@[IÜ äXP5‘¼ìyiš8–ïJ|=ié QƉDzßÌ6*ZE”´Ä£’ÒJôj«þ¼Èý—o|ruQ%”Ó/ñ›•DvållrÃÏÂÄ 1Œ“xÒR­xÙÕ=>JeI­ú‘$RÏËQ[påÆK²aÀ%®´’Ö8-°£ ¶ì5Z5Z{Vñhñ˜f¤[¸$Bê%D;ZðjùöEºB«šG²Sd|²*=’4¿-Ðf F[3):Ù\¾¼¨¿R =8í¸Í`)udy<×Ú"ÜA¢µ}¨·® ÑÚÇ3@ÑXu¤AÛî˜.´i²½;è…ÎÞZí0Ø4d:ëZ¾®©ÒÐS1aÐ&ÝyðW_óÉ’Ëý>ûF÷]Åú…ֿϼ=z®’íÈ«På–?áÓŽ,Îó0B4huÒÚ°Q2}ït~º· A”sjÇ¡ZŠ›Kˆy!Ér:Éð+±·a%@‹ËÝ–¬¤@³8=B Ô&h—3 d–S'¢› 5©ªZòTQ/Ne©|Su9 5Õ’ü$ª-% A½:/¾z&(S‚¦”¢qÅø.NB!ÈÆ’”Ôn½Î'N.sœ+Hºd\•’¦à‰qâ ÃñHШ”õŲ§CMJl1’ƒ/{“-É3M!i¹Ôum1P2ržbJkˆHCç&cxáJ+(;QÍF®ø"l)¸B$S#Y5ás¢¡5<‘ŠJÞŒ¹lSàiÊ©)-?6Çd¯Y37çªø\݆‰9 s�ZòÃUÁ "Wq뼸"*¼4vE\2U_P^H$‰K‡™Kc/6èstÖF@`Ñz݆¤ŠÓ²eŠÊ äÅ@@acõ#¯"4B�M çøpÎ�"B³0Î!ïƒK:Uj!Öú‹½b‹Öºå€æ)l˜€Øp Â"ÜÕ§D Úür]÷*º:ÌÆ§<W£I¼± íS&|ºÍpëÚ³ÑîG÷–yÕÚÇFÝ:€º¿Âg1¥» GÇl—pØ.88 0Ü DÀì&‚&PVV¿·­ÞàAõ%A9m´ ¯ª9>P!M)¿„V£±á4§ªh“®£‡‡q ­î8NPhFÚ‘SWnøð¨xQ‘C˽L�{ô< š¶9¡|G×UŽê))ˆ)ÅåÕKI±cJžééH TÕܸsKV³|3B`Ér ùeÙħë74>s3–9Ÿºµë‚Á”)§z±z¼Ž¶šžÇCÝDr¼Éº‹A@£åWWÄ$å‘lRD±”u$ÁU½˜·ÄPjI»²þ 9‘rAÕjQX¯ÅÞJK4ç¿àßä‚/f\U“OÕb+³‘ó—M¸'zjÓP9ƒO2<Q‘óeC4â²T‹Wr³Ä¥4 ^ÕKnÕhÍÉi’µ¤È×U^ÑjSŽ;¦–̨NDӺɃ�Ú%¨xÒÏå®CYnÆéåëÖœ»Rn[⃺àB! BG’§H­¾s@T9\ltvNqõÝè°ºÙg¥Øp,Í P@¼ê§öétÎès#p›_++÷ìÀg€I qkãi–)A¹J»ïÆ—é¶3R‚‘Œn:Äðom:÷­70†Ñ]wÁÁdP7Er×6rŒ­ýÏ-"(­s®ˆß€} 7î¤0eð¦<g sK�f2 W¢ Ä{§‚È¢ žs-ÜÌêŜЈL¨á•ž(sZ¶”£‰0c,m”&1k€ˆ>=.%˲h榨™ˆ<®…¼§®¡(±'/qºW× iI9=h”D•u¤µãM"«æBÔ’ùá®êô8ß”Œ†ñz Žç(±bÎr=ð•$´y¥Ê P#¹‘pŽÃsáR,HÚR.9bJ²ˆœÏ…‰çÓ%·! 1ˆJâD5¥lˆ2Ç ^C ¼x9rÒTʼßôþe­EO«P•¹0ȵb’¸AâTåš"šÔŒ#"D"§q|J“ù1U=¯§òdjà=ý5—·ë2ÆCÛ,gÆ0KØ™OŠ>OÅBÈ{ý…‹MGÕî•aS¯L¤P¹jVNšJZ÷J–&‹)[É.Ó\7EÅ&â&/#rjµ €\¹µ ‡n˜Œ´€êºêìŠv¼P síãNaû=éxuq!^_¦ZO9âÞqêµZV�d ~ëqn §×ËJH½ÁgxJ€º­…f²ëMtÈ0³ wÏJî¶â¦‘ÉÞŸ"XOª�¨t†öç3Û^BD`R±‡¶?â¬qžx¼‚d^‰kê«jŽsŠxe$€$ÚÇ•ÿ6ÍŸ‘bY2‰«14¨-ÆQª©kD°T×TpV×ÇŽ¤ F Gƒq;PŒWådhl7ëËuóžé"IÍpz–Óž¸S’”SSa&¶Iü-'>"SÈ0ZkÕ¾ Y{¸–"qD¥H‹©Ûò—PóELÇÒ Á3C/lNs¥YmÕâʱ9GÕS‰(¦[<ZÔ’ÄVS¢À8G‹So¹Hx>Rì˜M4¢Ä{5‰+æ3êTið"üh*” jhujVÕdLm”eZöÜÅ(›q•3QAã>®Éã¨ڢ녚îK†,Õ|CwÕ%jFt])æõqLHÕ£Áâ³/ÿYä_rÌûÅ#'‰|V;ÊU»&…ÎL1ÜÊü¬æºžã¡õµyõM˜s¹oj-87³^m¦Ie'cgSŠÉñF%i)V†·‚ñ�n U@Fä¯~©¹Q«"C°Láv½©¼9(z«Ç€ÝV÷kF¦9 ²èkçÊm5Ñnw×Ù[×\CœÚ¬6'Ó®O»÷YÛò¶u6ÑnÃPÌ6Ü%†aȳy%m'›.z·)@YKªÚã31<`aÛ¯'(ŸDc† qBl8@‚¢"”T烒¡Ó4QQ¨‰|*"“ Ö RÖÅÔØ™@=ªFäÉ&•âpÜ1Âr¤4š‘fx™*‚>–ðt9h?™õ¢š›šX:(vóg÷H.›7-‰ãùÀ󽛉d‰”$"(áÜw€”8QöÕ«1ïÊñŒY+˜º_®Ã¯„€ζš*—=% ™WÄ(¦{“M©ä¶9ÈGøšÉ"�� �IDAT¬¦yUñ„\3HÂæŠ¶Rå’†Á'~ÌÇQF(XM‘kE´@«:1U_¹$gùèY™»OÀ·ÔD$E"ÈEÑ Ô³R˜ˆ¤Nį7|Ô9·i4ËDc-…¶H’º%UE*èE–Uþ%SœÅ‡¥HHÚÔsZ&çñBnü„9qäÒ•ç|J“B!ª‡ŽÉ+F9 ir-’M‚MEpdRUËÖx:,pºÔ^˜Ÿ¬×³Ú‚5™É+šÆžÏgë/ciA̓6"—J6òˆ,ùˆ€H¦xŠ22ÒQ²¬·wÃE2²ø¶½º[AÔõþÙZ3 C~%©Ö{ö3�¨vl…˜ÝÙ sQ„ß=vd€Ûy�iˆ³‰zß@.P³õ†»×K ÛœJô|p7›_§€ã€+ãJ¨ô<â1Âõ³(ÛŸ¬˜@…ÊB&‘ð_‰@…*"ê¥Ï$f>”¢ò‚ªD®€â8®À[=9Õ2’ÅLÀ 9Ñ—TŽ@vTI#ÛˆßiÆÍˆ HW5×#J+páQ!ãå¤Ô†a B9'¼2¡HépFt¥¨R_ +<¿ yyž«ò~‰¯P‘ÿ²=56/•uœ²[…r¤,Îq2aœ4Ô‘DTb.EšÄ™ 4”¤Q·('H$jÍå0àÁr|5º¦ÄÏ2jñ¢kV¢©‚*D±S§nË×|™ðœO£ÚJsq.¥rœf…–ÓlÉQ  f#¯èŠ®R*ˆøËÑwyU°ù«ÍÀ•Z–°"‡.‡Tà5ݦäñšo¨u.^¸ç‚ÄǼ$Š“·TC U¥E8_Ñœåk¼yšãó–ëÇ OÍø¢V—sÖÅ|œ =')S–™Rbä„0h¦ŽYšÏK'tiÂȘ©”› Qkr² Øâõã¨Ùô[ßhEˆ¬´#+“fN‰£4Àõh–°Ü=GÉð´G«‚À¥>¦dœIÐt`'«‡d¯"€„ 8 T·üìŠÐJpèZG-"PÜÞ‡„oá,�ÀE³„ ûñ û¯Ò}?¥'õµÔÚ"EwíL0Ûpwy =º…>ÔÉ·´gœw¸°UûŠ Ü ¤2˜;È@˜VôMŸ°i’¬@m ¤S4Fä;Nk 4€-DDQ&lx®Àó9£@Ž –n:�ÁÂÁNNè ¼É¹aÜЀÿŸ½7k’#»Òľ»ûk®H P(’ާÙ=ÖšQË$™IfzÒÕШça––ÍpzšebY…B¡¹F†GøîwÕCf Tb)6ÙmM£?E:ܯ;"îÙ¾sÎw<[ "z•§NØðÍÚJ§ÁYÉ<û´ÚyLº(‡i7]í#ng¡é†«ÄL= e§”Ðt)/iàadšd rÙúÝßVÍz³QWÚû˜)ÔãÄ>gE4‘gÄ*È,©'cÖ7]šÐ‘ÓãÐÎÑ ¸^'-¸ºÆöEd•6é.‰#§h"ÆnwÓ+Ób¬t&¼÷¶Ëí€mý÷j:ëÚØ‹ 6m~ë׊„?.iFbíŽ~ÈôŽ”!ÅfkÈV"bòûÏ#ò$ÍÊO7‘"tùƒ±+ÿ¹Á”. :)¨a„‰)‹UF㹃z2zóŸ»_&MÌZƒxrÈ&/Ó1Mµ#A\ûÕÎp?ØNy1VR5_ªÝoØ_ fzpôþe¿S·æóš “j„cœ'a<¼�ê§Ï®3¨ï^e M‚Ðã�ŠCyÀ ºB?Ülæ0± ˆ1Ó7®�ðôíŽv§o£ënë×ã†ïâ‡%· í/ ¢ð¶ÄFüVÛp-#÷êkùajݾÃ5L�ù~†×?Ù†?¾ãC£ýÝÖ|wñë}‰ vwmHÜ >G¸æ)¸ϵjoåê¦DUæãQÀ1‡ØºgæççBV£€×¨VéøÕG hYv¸œ5;jž·M}ʪý\®áù–©É°]Ëúvd½B§»u ¿6ñÌÅO4©Kï1ktk#?ÌìfÖ±ƒï-–ñ#=š¡T—¤0BTe<ÑA‹:H6æyp¶hMÅÅ4FÑKòƒi¿÷ãÓøËóÿàY^*Á1{œlǪ1e1ÆFYŸ$¦bµ[ÑŠFn*åúóm·µ›}#bÝ?·æè盫“e3ýÞ2iªÍÔï.Mœ§E¾Žáv ›…BÓvt BKßíÒx‡Ì7§Ý¹x×/˜-!ãd1±(zç<Ѳ¹òû|ÒçÉ¿+¶Î¶c;Žrã@†0ÐÀŽ!ÿ¡ñkÖ5)4*”ãÚ_¼¶#)¢(“{ƒ(­¸iijqktÞωXN\$µË†ójh ÝN—\6ß?Vçd>¤ù>‰¹stòQ”zYÈG¦TÍ:”€ èVa\¡óÀã ÐÀÉC@`ðP-Âs9µÏ�øÜ�£@I_mÂÛfš^£F€^m8Ò7‰ƒ—¸ÓMc³P� ä®[a>¼õG …Wı÷T:-€�T÷Ž:}kŠnõí‹) `ûûþé[‡}·¬wôû“mø~ÜïüÚ7· è�@#”@9Üà¼ß~„¾/R9ÕHQˆÓIök|êpÁPÆ� øÐd Ž 48" Qùvè‚À޵~¨¯¥èse§p;¹R«ˆ?ÎGÂ8ؤá¡I\·½´‹z°1g_æ¢Ý­ùWJ‰T U›íqËL½Húxõ2è[Wb—;Íû ¥GJg‘«)k2®8éG¡iAùUµ·jÖ‡pՇƩ(dÎEŒYÛÅzÜ¿”Så†xV„ÖuƒØ¾ ö“¦þÛ¡-¯æ-¡[[õþj]Ÿ/gùÇû e’ZBOLSQÄÔ¾qÓÌæZÒ$ªQr”SÐ82'H“Øýzh³=·Ñ‰æ?LU,+žm£.Þn“ðUüÑ\Lçl3SmÄCCûQ4¬Ï˜ç 8ñ_vþ¢r—ÛªëòÊÂØíÕgø«w÷ŠdBiØ‹÷ TÓë¦|ªºT\¤4ÍM:ÞWC¬™qýe=Œ¥yž<øør>OÅHhM™iÄhT8`3’f¡÷¬Ã×»nm6ÎØÜj,òsåÉň«à(dA^ �üâ ;cÀÌæ�ø-PžÀç P¯J^߄߼ÒàGY8&ûº;»Ñ›áZEÞ¶Î0 @ƒ¾ªˆ».~ ÷A=wô¸¶8ï· @Þ ¢~;Ewg’ùv¿[JßÖ.ú(¸ûÙ†7¾0òúyòw‘wž|ï]:îÇ/ÿ€ Üd¿ÞgG@‰¤üV ÉëhéuÅQ ;½èx¶½Èsä2‹«[…#t쿱РA/€ø3‰,¡a[6d¤Ü®,Æ4 0�®‰øÏ%9£ÞW½1ZE›1žy‘VÖƒµ‘íøScKßô‘˜ñ0ƒÕEëÕú‡]³Ùn(Ù¿ÅŠ~óÈÎ٣¹¤îOžM‹/æÓãYºèô–+Ì$î]c'¶â^ÿPˆá#ñχgæLÆe(£zé&)É„pOË-Öúýrƒ9ÓlªGÚÕ8ŠÑdù”_õLk±J±Ì[D—âi4xËÙïøÂŠ8\í;YD  KˆË¨‘úœ` ë½ÍÅÑd=†«nRY¿òíÕ„Ù¥RY^ÄÌ%ŠÎe`UŽ\¤‘”tОYÆÚ(r&ô[wÝ„K‘»ñú©ꎬiþËÁ\úXvBíeu6¤L±³KLeÅûuþ VÃ$œØ¾ÜÅEê¸öÁ!kuÔÔŒh’¨0›“1Ò8Öb-dºžúT ‘—Tñìp§üåj¿úªÎ_')DJӓݪGLz<š4JÖ_kú…ÌA$š+ŠóKñ)<¿«Æ×=n|{8ó•^àXK]-^»®¡~™£¸î¿C¬_Ê}mÙµ|möv[½>€iüÎBy +kßK,È^µ‹¾‚ÈŽþ9æE“·[‹·©xrû9ÜùIß8ùÞ»þ”a~ûQ¼9dê÷Fê²yÍx`‚®|[í5ÿ¦G—=šY°†2Ø'»Áˆ%Ì né¶±`¦ÂÈë<èµÁZâX#ƒ$8 (µ:§ªQêÝ(}Yùµæ›`*Ù$¡fä'º|Þ ãê9 ~]a£?%ÑÿjütÅ‹ é©ÙÛÇùvÄñ@~V«â¦Ìë\7*Lf\dìj\Ýý§±„f ÙÿÐú¥>Zíµê'¿}±_?㿘üF'ýÔùw¤vM]®1œçç93õ6‰év»8 "bI€~Á׈´ôã'iÉÔeF0Ñ¿EZÇÓo¢ŽŒ‹ôy¶û“½Yá"–Ö}1Dº^ ;òþi*ÑãÑŠG`é¿)ÍFV•¿š$ôñb¾E1Ò­éGÛ[ê1:ÑÒœè}ªµôƒm+éeA‡¤ö´5 fâÌ‹G.„ÿú4Ì…ëëÁœ¹§»´|¿X¤if9sÙ¾é+Ä+’)?\mߺFòÑ‘„™J·>‘£™ò!éËÄM}ã1º-o+b¼ é‚@N 7Äu†/Í€j‚ÑßHzŽy‡Å§8%—VÓ¯tá~Õ0ÖÈ>ï‘T¦›È×\’áõPx{ßî]ACç7� ¯Gô敽[¤jæˆ$†³=TчbýßåðoÂãÛ‹·h | $�yy2| ¼üv®Žïnî È[,Dø“¿ÿ²¯™}¿ À€½xýúüMŠâW‡ú�Çæruýnw;ï%NnpáûŽðÀÐ]‰¯kD@)–%&¦&–×wŽ@µ‰Ïå•êô‹rÈ€q8Ý!?ÂP£{¡sø“‹1æÚꊖ¨z“–ÑãŒÍˆ.˜) ±+dm¾xQ]dUPHäÕÏPd\²yQ%Ýn·2“‹x—«æ§¾lé7 UÒþ3Ež “á! 15p8Í ˜øU­Š•Âh»'WÇé“R¥†-¦‰Ý?.ïÆ5‹ >iKž?mMMÂ7ÙüDGsb¥â|’ÏØ¼þ’o—²R}QEQ¿e=› Þ+¿?;ç“a„2~2†-Ê‚à”»±.¦õ$úŸ 'ÆnÆlÎ,"êE¬0Ú±Ó[c}Î ªsιmOVïucÖœ zDuòêbÖÙ±¥Ã9_“‘/u=6Âeß”2îvöÓ8lÝÕà6™kßµLfDà}¶;ˆÈ$í@~3Žà´n8sêjˆx¦Òx€éúÖv†~5´­mSÒÈùÄDQ £ñþÂÎÇÚ‘åW¦üwÆõ�BŒ<ätV òF»U{JkwŒ$j4ìþAÊ/Õ\òúl†—ÜÖþƃ9}7ÜõxfÇpú~ñšcH <ÌÅ5îS£öiçß%køZú¼¦nåGŽÛ×̃¾å}zsñ8ÊýÞã†ð'œçg^éô÷õß¿”o¹^´X*´ß®~“@,ïÒÝ/uíïvÛyŸHd? «±õŸÝ}%<NoѬ•³Ç(42€�­†>©±l@nßI®¹Þì`.0 _t‹ûèÜyìåDä层~[`ŸâñF¦Ö¶®–L  ÛIËt6Ú ÕFôÉxš}¾ŠðIõ¸À}*Ú$2ê\‰³Ôºló„!§ˆØüWÖ™‹°Z¸-Iÿ/ª°Sâÿ¼évjmébbë‘ ¥³rôµÍ$µç‰GŸ�¢sVÏdQo~9›¥¼Ø±,óy,2ÃÁù˜ð"(Ñ b³ þ+È™tÇí µ=©Q ´ËÜ|+ÖC–bMÔ£AÆ£½Úí¶¢ÄÏBOÇrÓ6qH0!û$ñJ}ŸaßÚ´UÈrTÚvtK ƒë»ìü4•ư¾ ÂøOTÉ®l¿’›º –LÍgæ´¬w±šÌ æ}œŸÈj­=^ÊaœO–“hŒûXŸÆW–ŒÇl©Y²CÃ㺈Úöy4E¨My¶´ãe/惛>Ûd3g™bt°ÎXó”¹ËìªØ®‹qB´ƒÝôFåbáý|’ÉíGER`ݬSÖé Ãþrû(jÝ Ãn-<}€îoü õò¥>K€ë)Ô)°\¸i}³?7oz'�€%�È4^7 7žÕ÷€#áúj*x«[f§ úCs¼ä½\Ðìnü‚t©ÈïÖNñÝmÃPÒ»qž?YŽßÅ_x[p ß J¾ãzãqzo'§– ¯/âïø_ ÀÝ´»ï¦€iÐW„Æ/I€?F¹àù (¬Éõny0Vã ç3ÌJÌJ{ìÁVÔ $™ØúIµIºÖÏ$š~•­m´Ê»q¾(v$gßöËJš§›4ÏBŸš/Zƒo6ÐnFÌ7P˜Ç:²•üF“çS2Ã÷ ŽQ<ñKG#emy…¥(Ì£â/Ä\Ðh¿é”3¡¾Ú =¥È£!1* ÓÙ†ŸÔ:Ò=ÜN¯&ú8+º0ñ&;‚åL+f§§°n'Ê Àò3±SFD°Ûêï>O¨¤Ð&Fù}Ìgíç{£ùÇ‘<X§mNr9†q»¼ÈÄ@‡­‹¦%õ¦Û|™Lâ©X2&ŠÙÑ]•S‡<c*êòè\*+UCã:©“aë6øFÅ*g³ÀˆÓ6IŽ­ÖÅ×þ²Ü4s¹í/S/œlûžêƒÒEØjL´âƒ!mFNºTÉNÖ&ÚöykÿKEº°éDÙ­Ò±p>×¢èd‚Ø´™¬Qx&|{ÅÉØ7ñÐèóÜ™!ø~œöµËY¤â1OéÑL§®†V%6_“JTÑ\¹J"ýÈ3pàï~ü `ÀêzÛèkˆ}5U`ØÃQ‚£�”ÝæÚYV˜Ö8²861f“ò5®xyM¿0 ßb_¯R�ºK‰ËwÊš–¡û0ü–ÑïbÞ8Î^“EÞ㕾Ó6¼äè~¥ÞÿÄÌúÏ`>Êüð­ðήÈoµn.Üõ¤÷×Éîol½·¾VÚ#•0ãg—æz…] L4Êí›Ò€^B¦µÞH 9”G•IdWPôÑ$MyݺtYÑ95D:ÝÕLaíòU5“¾ÁGÏô¾…: ‡ZðF&.7mDM©&É7#%C'íe¸ÊoPÏ&áI$s(®+Ï+ª7º9aå§±y¬vÛæð©™²\ [ââù™.’©±œ¸àq*õ&¹`6[è½xœ:=qªë kVà æWtΆ£^OÑÐmAö‰/ˆé’Ìe°Q”Ç"eɈæ‡DögŸ¯¢—û‹O?âS}é.žšUÉñ€’< {ž;ê}Å‹.&ÛÜ3ë è™ð£ÂÁ¡ÚQ…‰Ä+úœä)®Hã! G0ÞS‰hÖýª›îó9ñªg5W$™ˆƒ}’S5žAÃuä¿T,:Òhí᧨,ôúéÈ„†0]óÒ­WN«! ÃÞzp/ø<éŠÜtSŒ¦æíIOXÍö|B‹d ºÊ5•LmTîÕ!ªŽn‚p†ñ1Tí†Ú ÌKQ)±~Í#|ŦŸW TeéæŠuVE(vÀb8üòå¶ç·ªÝ*ŽHÃoŽ)@p|=+´�z 8²ÀY„H¿Æ¿í-¶Ç(ím€!_/ø®Uy÷næm‰îƒS¾þÝÙÙdŽP¿ ²Éû§}ˆžÿîÝJ!üSwÆ�’{ö06ïÚowË{ÚÓôÝóš8ûº^®Ü¾¹eÃõçDc"`;£þí€0¿.ÁÞbœß2Ü1fRà¨À±Ï´LqÙB#)!v{»3Vi†d/B”¨KÎBq`.Šsˆ©Î¹(ú8œ%k,�¼�zŒ%5EïKi¥z$T;˵ ÝÆù²z+¿)LÑ>1;)_’­¨Ãf}!üóþôI~õ£8=ÐÓÓÍäó>é‹¡ÚñãÙeTìgÒ)7$ί;m»š:šøáðŒM»1~Tò˜Êø›%‘ìhº ñŠ'pVÒæÏÄ8³ŒÿÐLÒ©P¼ÏsŸ™ÉÄù™ŒÄ'Æ8h™Ⱥÿ²#íÎÈò_ËhŽ®8žþìC³õf¦µb1|¢úYØ(ÎCœÒ”“¨´˜Ù’fþÒoêÁ,YxÏrÅX•Ž$uB6dÔcãš¼ IB‘ìÎWbŸ‘4ñΗ¡)¤‰EᘠèJ÷R× Ê¾Æ(qèmÎI4£kG6}‚ÚF§ýnÖ$E;Æ}sÔn“,›·‘5G-.6ô«.¹ªô£¸È^%A˪UÍÒfÒ„JAw²ÄöŸsÿ¿ç6Z½6¿±ó ø‹¶†,™x”&ÉcëÓÕHüq¼û™ñ~¸úË6,A$ÒÕæz.¡)0`¶F©êPh*Üp±$€Ä°Á°7ÅDÇÀf A_�W7›9b ¨½Åa*H’|‚îzhì¯}GA¾Ö¤M^+]ýŽ{õ6“pp'UðÝ͆»(Ñ­žÏ‚àþ†ßÍü3›ù‡ŸÙôÁ˜ÞŽ.òW›ê§€ºæ+=ì{ÊÄtŒãþÎÎ[B«rÊÙ 3Äe•–c‹S�ƒÅyн½a]üíö¾D¢Ç�ça&3,b4Y‹•yE|p[ rÝÚZá8†^Äè$j‰ÁƒÚÒ‹r`y4åÙ…f,CðÈÕÉ8®ôê³,]͹æNCJLj~žúSÆûli­p  ÑZnôì›/G¦u |ÓÂgbàQíðT'ÈÇž�òY‰‡Y›nCÓn~}*ÿ€}|(Ö3 é8°íFô­ lØÆßŒm˜–Š”ñI´PX0¿pZO=­Ù–î}"$jÂü—lÈC¯Âì(>Hv³aÊëˆÉJDƒprÒ"‹µðü &ª`BþmØÙÇb’ˆ©«¬,ÿÕ?—¾€ï b’'c.”tbf—›©•œ1Mómê/FýÛqó¿ÐÈIi¼j5žªˆå«62ÔŒV-ûhéäȵLÁ(„@Iî€jTqÙ#Ç-ã ±Xµr•é)A@:ðèÄMÊŠ˜N3›˜¿éÍ¢1¥^ÚÑ~e¿ÃL–Ì÷Üê¨Þù©-–Ûì4¡§Û‰#]êq‹ÁN&½'‰H|¬èÎ^“¤v=;^¸-ÉW,gj¦™šÑGßì0ÎM¾&âÿjøKÚÌ‘$“ATk ›b¶Ç GÇž½Y™4�ì%Ô}ÃÜ¥�M�C’q]~ÝôÛWÂÈtè¾>¾Mgè—c{Þ@}ÃÐ\| Õë]“ð¦¡\ŠR|·¹¡ï_ðwÊ7„ïž‹¾÷®÷.õ»=ë÷— þçÄ-!Lì¨1»MfékAh@å sË·ºá9пÊïBï#°&SžøJÑc¢° +àÈæ¶§j”&¸Š®§6bü8ï¾Ú«u¿AŸc¡t€—C§E„¨Ó ˆ‘ƒI$%à¯åO@¯‘*ˆ j EQ¿ˆ÷v¥ç˜ÁmfÃÆÕ²Y- N±hm_I}23ñ!ý?¢¥ ›šÍŸ'òéë’þ|g¶ç²Qd¥›ÍHŠuIµNg²mõ5µÀîh¥¾L‡ÏŠœÉESyVíBŽÿ~½þË«nU~þS]Çc‹¸KI™Þ]© ÍN‡ð49G¼9àx Óð?ØÉ˜¶y#fWqǾœ !¶‹¬vîÊNžûýÝÉ5IóÂO%$ô4ô ÐØ.Ý&§ŠÐ&IC8r饛xÕ±‹´¦yóÉAùi? ãüô¥1½Mé~æ• Iâ™—°)iXÔ1MeÑMþ‡s®æ§Îo}Ø!£”„XÎ’`„äkwÖÍô ]ÇÀ8È8Á&4ŠRb¬|P‘‚o]UD==ûÕÃFÿ`ÄQ|ñèp±,çÒtƒõ‰s îŠë¤R³q˜tþ`ÓÈÅi_ñ0 ˆ'6=büÔÒÓ+$3D°²LÒÆKdšu–ý èw(KcžG,Ò4³~OÑŽuŸøáißÊt¯Ž},v«J¹íŠ¡š?ÏÿÞêˆòMªÞÚ¨ ˆn+:û2ŹD3Hs•¼$É�Ú»*>àPC_ŸÜf–_Óû“Wïg èpËÙämúí[u8FzÝZñZYy©ó˜½‡éåã–ÐÓ÷؆ï̱ö;Å äƒÏ“÷ÝõÞ“ÿÔуþÃÏz}ýì6ú»÷¸”f€b˜å¨û Ì–Ï®ü �•˜au Ü3ïðu·E÷@½@ðº@üX^íSdŸ©ñFæÔ Cõ’¢I^NÊd9Û<óÝ8Ë‹OÇ/-ôYóú�E~L¥>èÀ€²§Ú2ìxÌ�l®Yöz GƦÓâ_ÇèYºßŠYˆF§<k?ÝïÍÁóÙ¨‡³Õt¿Ù'ßw{‚Ïw§Oû=ÛÚ_Œþ¿’í¿—»)YﶦþÊU†.%B¨GÌþº)µÂ³6)H/A8<––ÆbŒ³¨¤³Y½®KÐ¥“væ0´ïÈBX{i=16u}ò û·&ïXlÇqžé'‘ã_7¬’»ÔºÕ®ÑÉF3ÀGs¸ä׳ƒŸçûq‘΄IÉ`Èx¢ÜÅÉÏ'Ñó²DLhŸw1¶ËBGÆ¿µÝ#{9ñgQ4D4&ÜHS:˜‰1[¾pÙô‹¢!x飾ÞÔ=¸¤cÆl S&)—"@Ф°"Íd;å4'¤ï¬s—N â[S¦ª cÑÑØ'^MŸÓ8öÕn8IG6[aF§ùü§“ÝÔ/ÌØ²ó1ô­dü‰Kž¾÷곈ÍÄl™ º�� �IDATB&<¦BdmÛuEö#qTD;͇ñÙØ6/:3au‰–ÍÉX’e1Oâ½?íyßrSMƒõq sIó‰åIwМd½_4Q6ÙÙŸúÏ֛͕Jü˜$a>µQœObÚõ•ÆÅ"ÿìl-ÊÏß((b€ÃõF®^6lÆ$À¾­Ä_¡¬ ’CËÓ7dTb~+YoCƒnèdî·áN)D Ó¾àvØ<ôªývY‘Ì ÕÌ5Îïªø»ŽV8ÖïŸ}üÁ£|ÿ 0¥?®TðïƒÒoV¼ ¦@q‡måÚ¸r¸ÜÈœ¦¾™q�Fßݾï.¤«ÙlÈJ3Þ€Áòsµ„ä×+xTÀ.°�Œù¢ò3cLJjK|=ƒ õØ Ð ðx ðœ¦î:h‘%ŽÌPfºt Œ¢æp5Ðbã§ÙÎOŠØÐa½Õ—Žè.󣜒“4×$c!9ºœìýÕÂ~I ÝF»™çQ×D—ÛñÅÕ'$þ’L¼‰ßÙjk·ú¸ :g¥¡?ËIJŸ|*Ÿü*£àãÜ9=–¡^û›æ€èBÙœêóþÓ^ÿÀêÉ$;i-ÝPU|c0Vª%qyÅI<ÆóÁ Í< b0íæk½Óq'?òÝS'. óŸ‡üq¶8Lç9¨0tÃ轜‘4B‘ˆè·P£õ6t]¿^GÄú¨£Ï·õº<KÛ¶ÒìŒ ô¼©çD?qžËM0-•2&DRSùJcáÜŽN˜3">Ð,H¥B´ä*òI2’šNQâ‡Ð˜°ðH 3àÒZU�)s,€„HäY’¦ º’ê‡uü„ˆÂP[Ó—¡[¡üèG!;8H©tOh9ú’ÙÃC·È‚©ÎáëùÅ×j“¥j×Aòó~âÚ0o(û\Ó…m÷×ãNÑ‚Î)"[¯.ã²åe­””“YSÞÌÆe¾žÅU²~œº…Z†YÁ“Oú®Õm<bRÄ>)ä_±Íß°›Q>*õÇ({àX0F‰MrwBÜmÂÕë>YÐë©A7eu�F<1r|v­w O<ÔPÇè^¹\áƒäý•ó÷²/è) ñÒ0ܮн*\ú–&¹ÉjÜh|¬_ªøòÖ]|9ªúÐÕïÛåý“møý�D䎀»‰$‡wi¾Þo‰Þà±0¯êên~cÚCô·Qóøú*é·Ù—È—©üØñl?ÇúÙíj'À‰\C«7°¬= ,ÑèU¸”+¯oºç,€ÍêºæûU1Þ(IÓ]áрǸÛÌËRâ<ŒDDH¾egéÃCSÈ$ˆíçã1µµ#³M"ê´ìÎì<ûè“IòQ2<öz  ù¦‡¾ê‡Ïó&"rÁå¤Z¥]<9=ÑÍó|½gݸìÞÊ“…ñi£„·è¨f¶"¶WÑiŠaÚ)ùGa{0b:/ô¼h…éÚ¶5Ùœ§êœk–?ÑR tÑŽ‰ uÒÆÎ’>’ÍÇÓ‡ó"„t8OÚ!æãÿHì¡¡q%‚“˜•p[€ ÆÒdoÌsÍŒ’[¥-ŸuÂzwÖ¯~¾ÖGÇWZ ÑUǾŽñ›<ô–ü¼Iv7.[_5{*YŸ11¥Q˜°@m#m[¹<ð=p¥c¬2žF>Ac‚ ¡²AÆÁÙx„Öñ(v{ÿlF$mÍà©R±D0=­zrD*Óï+{Ê€–9ÝEÎûf;¸¦}ë‡xžíÎä¢è×î›ê .‘Ó=QãWݯ§çâÇ#éë±u•f7&éƒÁr·nY$³¢à6k‰¶”ff£aàˆ|“ÕEtf£Çí9óMÊ’ˆE2;lºj ŸXôrÔ‡ýó>èDZƒpCäJ¯ÁÔ:FµyŸO&v̹‘PRAOnƒy0@êë?Èï/ë{†_}»«à&"a·æ!@ޝQ¿Záü¨}ƒêXÇÕÝ5Í/|ûDLõ̺739°¹Qo1 @—´¶áŸ {üƒÞö½o¹{¿ù;µx¿yxc{ÜÎK ¶w:$¿}¯Dò ‰b;:ÍÐ*d�½íÿI�«µþÖ-æäëY„ÆÅ [êKI¸|Ÿ]ïæH¯'2ÞîL‚Iœ'Ÿ#;@þуd÷Ñ¡’sµê Æ„Iî¼[X)„Y÷qm—Ï¢ƒ{I"ØŽ¹Ã(Üå0”£é‡–E¶û(úÏÅd8KÎô¬”=-¦y>†GYc»WÉìׄ€޷Ͼ7x4M ¦œuî´”d —Á¥_|´ÃbAíñ¤ÕÅØÇ=É‹þÒ¶¬™Œ>£â—ÃÈÿÏXd¡Ö…‘tÉ?žåÙnJF;õÃ÷äúÇ]Œzå éq•ç™Ê‘<žéA!àÀÏ©šª:D³M^šº(ûˆzNŠÙý~¬Y~ù•K#V‡‘‹‰Ï¥×¬P‰LÁmˆ‡Á0¯â8#’-S`4Ü«4ŠÒ­¬±ÐYÄDIåÓ™¶1#!39aŠ%Tˆ…ÎaDJ'QF3A§Zžîê?n1µ2•”©´®÷ÊÑVóÖÊHÇ“¢ÖªÿÞ…Hõ‘€q¢ÆpáH’9‘ýWAN NÓiðW¶ãúÉ6 ÝìÇÊçj>Dú…7•gЦQ4¥r]ï‰îÓ±EÆrÑ? õД¾ ‚ù%U;*žhl:kûñôâùÉs  ý5tœ¼^øÔú½:AÞ\¤¯‹è^^ó -4.^÷ë!‘»@ ÔÐ<=.{ý~‹Û§|YA ŒpDpÜBߺ>¼†MírÌ€Ö^Éë0Àµ­_¶[rÿ˜kD™Áøe"p i!H¬ôŸmø'Èÿ®Ô ðâƒû%à�àŇ^¾ž@J9÷˜¨›RW¾þ2—KÒµõ�œ~Ž)p( bD%Š›ì¶ L#�Zãֈ�¥K¤ôõu¦îÛ…Þeð7ðX ät¶?JN!ýäÇ{>þþÎôÑŽ’ WÚ7—£vÊoÓé<ˆÝ!2ΗQ_æÉ´R¹ #ìÙÒ¨éù7mñE¹.+b;ýMB£SÆ’`/Ç‹gM7£’²rº “9z) ŸecÙHaRá2ÁÃŒ·g²ùªÖ'Vƒãqš$¹ê)Ùn|®ŸgŠ‘¢P±æL%Wóz2¶y9-ørbÒ”ïçùH’>Å–$n&õŒ,£xº7û~¼Ü6iíkê¨m gr£&Vpó’æU"#Šà-Ã�/=Ï,š„‰1²ñDMš²åßÊ<á™˜Ž²Q\¼˜ÆcÍh´¤|›[ËœMº.y”‰à´°™ 2ÎöÇXr‘‚‹k«cy\È,%ˆä€$ÉX"ÖI FÂåÜSIÈœ³‚Ú@òiûÔR¸l’/ÇJ›„™Åt8ÉéÚÐGCrÐS•ð3vžkZÛðõ`=õu=Yn¢œYLE¿Cg21•›>¬Ý¤³Ddf ñÒª�*!IpšÖãàÛq:p?òÂ¥4.Ô@]÷2Ð=h¶Æí¤ÛežøÍ&]<ÝÜ’_½¾ +Üm({›NÀ'H¿„и¸‡È:�öú^v ©a5PÝ$�®ç“v½¾Kýú#”`—A%¸ÐaDmp í[4Æíß%0I€úâ%S,€›Žn´bN°>ý�Õ p‘¡)ïQ>¯˜x ð úèÛÐÆmÐÿ¬†á=ÇðÞ+î’lS ¾²âq’…¦8÷†#ÀÏè6Sñn+U@¹ú¼i=´kõ- Ÿ1í|ÉGbê7z W Ñ Õ.ÓvQîPd[¬^E ¯$°¸­©¸‰‚Ÿ YÿÀÅ“£ÌwÓô±3ILš°½l^ÄU`Fåéd7“´hTÐÆÍÌvîÅEã/Fy±®oé¶J‡“áø?œ…Gg¢Þ;èç~‚!®§Y+ŽÇ)¸*UA=Z׆ËAGC¶™ú¾s_ÔGZe]H×M/jÉÆŸoCl¢rËK+¡/?u&ât »~ ˜ì)퇤Í1R\ŒÙ¬Ëd`*Ó,~›AGý +Rw ÒÇj©ÒÝ,‘ÜÖ¼:Uuï]àÕ ìl¤‰#ÌjÉjM™–€ú!ŽqÊZ‹ñ”â$™H-ˆÏ‰pŠ”Rìd‹G¹d}?º¾©¢É3m™$"¼¡’(‘!óÜ œJíë\A…àÌ«dT*‘õ–*³¤½ ž„ ÆK¼µE_#iEf¼1ÍÓ8¦™ æ Ù+.Ý� )ÆŽ:!SÄQBã,åGÆÅ.d¶ÛŒü‹Öh°¥–G§.#¤•Âp>`he˜NŠù–òDŒšQ¥\L͆ÜÆF«K]o×?êmÛ6Î?" ”Sþ½ÀHCd“˜‰9fg›ÄˆN‘!šÕYÔ` dÀ�épn¤~vy¿FáKḹ­#ÉíŽ%HØ (}?7ÌMãÛ1 ‰ÍM˜~ ׸Ž4ŠQ r¸×ɉƒì^– šwÖ¼¶¯ÎÓ å½™ƒñšRàìÛùð·DH(ï÷J×½E…þq`Jú_à;ßþ¢íÏXÝÓO/Œ{«Oôüº]ùµA·qjøÞ(¿ßžÇÅDXe.¶(Ûíì»)ôó¿t@€¶räHf»ˆRô`°"`~Ü)Ï2Ì·¯ê(n·Ôc¬„3ô@G…Dž‘éx(ä!}´ÜùØ?X¤QP´¢á²k{sµ :¢îÀwT:lFß$²Ï‰Žµ–Çÿùþ£«´U,Zvÿ·b²b`E½žË3‹‚EaÅ!@‚0)-B»yÜ¿` yšÈAˆ“¼ù‹òâ^Mýƒ‘ú&”—dóä€ìÇIí§ÿo,Jó]À¶HSeÝôEP ,aŽõQ¾—‡ÁŠ™ZŽLÒÒÚs')–‰¡²íK%,—™”yˆmLc®zíˆVYOXL 5¥$&;Á•pÁ³Ñ‘‘ ƒ8JNÙFpÖx¥?K³Ýé4â„Ö´«èÂRRúï5¾-\>#Q�—Q¢d¦(ãÂ*Ú9Ÿ{ƒÄºÌŽQ2R"¨L¸ˆµ¥ÌCÅ^JçÓ^�$x 4ƒå¦CGõfÐ"¢£°J¸áÁF‰)÷AlReyàÉf$|k(TÎUÎõ^4†Jö$cz2.j§6.!s–ò'õ°tYš‡ò(ûJT~Kõ%my³ 3›Hg a¹ßÑôùšî3IëLR²+6«†ˆ9¡W½ZŸ›EFÓ Í‹lϹY;–]YµÌÉñ†ê¶¿Æmý­,<¾ÎßNðìÚŒöް,ÐY¸aÝ£ð7¨ìýD›áT8´}}´èžÃƒ²Ç ôóW’8ÅK6'­ñìË :ºmñ1û�¹./yÎqŸŽN�†U·J½¹Zô!þè=©mÿó É{!›?D6â¹æ½Êw~Ýû2i–ÞMKܳÂßc9â`=û):“5’SX”äi=u „¬#Íu¢ŒbD^º)Äñˆz" ÀíãìÄB_Üo•g.)ÏS\'ÇSÂxxÞøŸTjG‰}•O•œEB0®»m+Îdü“—­eµ™¢ê†cý·‘‰„ÌÐ@x¸ËÿtN~Ó+ï’!a³äB8¤6 |Å‚6­Do÷ôW3‰´€dÝ6n/éâöè8î_¶‘ü"ºµÛSÉ2Ï-8“ªõU‚Ëi‘åÍ¢©'çÃf©y»3MŸLØ'ùƒ<ÈÁ­;5h£ùÀ·Õ<[¦™,*L;ÂÒXŒ!WÚ;­É×dÌx`Y,I”JEÈí<”Özha­¶„i«lš}L¹‰l©‡_ÂþuÄ̦ËyžòØwF;PLíÍ XÉež)²ô„Ç´Ôg‚ŸGa”$мÔ»à™£c­3€!¡¥¡OÑ`Œ­œímQ§^[m™v!P%KêêÞ¶W½khd|:öY7€Rž‚E´°&2]L%xR. >ÖV £¤ñe'O+Ôÿ™"I²iÉ7g.í$ÝG*ƒÌŒíûŒ ƒž±š6n0Fi”¬[#žDJ湡Ôu'}ÄZmÜ…^Æ’'–.Ö>b_ËfKâ/£Ø“ƒª÷ÚR|u.COßÓvMÙ%!h }^` ´øZ @�ß�í+¢'(·w+\ÝÊËë~Qƒ^c“ã›ú®czݺøîšÕƒõµ/µ})Âú9Ðnæ#`¸éÑ~/j›š×)¿e¬è·”yKÒó_¾mèÞ­©ÿÙˆüšoÖ½yÛ¼†FÐÃÛ åKƒ´G€NãË� è-6#@:«k]BO1vC?Åéú’ÓC G­Pôj˜­ÆË9šîÀˆñ¸vTÇÇàÏ �üâ±ü8oã³ô°Ôû5“É¸ÞØáË–Uc›uU_—NbáÆ"3¿õøÚ˜Çg}¼>S™³‹ƒdüxÚ»²¾ŽþÝ•æH§Å<¨jùÍ$AÎ1tèÇÎç@ðOè‹§NZ#èœ êIµrÍžçŒ_Hó›¬=aÉÏI<ÓÁ‘Øï¦é. Ú±BHeí3ö°ï~ÂV‹dq¥A-$ï–i”Y²»¶ëØ_Ŧ#I¤èdÉÉ~6{:P¹3FçÂJÅ(ÍZrÀײo๒*µå2IÆÎiÊ/Ì&¨ž–MDœ.dÁ….éÜä¸J§÷³4Ž“Ž ç­Ó¬$À(0W*Hn]7Ä´>¶#lÄ-•–ó@iêlŒ<Ê#*E°=s«È6è?&}G8—^q¬x’ÉýÖÊZhjZéµ ªñúÖ#‹¬ W¹í#Ë·A®˜*™Oc—²àb"È Ü™O3¢–V“1ªJ¬º â±!ªBd¢L ¦¡ÖÌ2—©œˆ8DÂDQhIïwÎ<¥Ck6§ÖÑòO— ™k©,ˆotö¼Ô);|Ç‹ùjž4“™÷ ᯫz Å@·ÛæQf/dÆäÐ·ÉØg l# #dŠ£€(Ë›}™â¨Æñ5¶c�D@q]Èz‹ì›whjd%rÀ�_o^Z¤Ç·Ç·{îZ?lï¼ý]5¥ñ�X¿LZ¼]})€Iø»­ /wÏKÚ—ü²Õ}^æKÍ%üu9lþxkXß­©ÿÙˆßËš÷5¡Ü‡^CùÛ;y¤á]±!VHôD–d³Ž°’жÀ!Á%‹Zu‰|‚Ikè¤ËùˆØu9ô¨Ý-óåo(tô2…Eo.R€!lЃ‡d±ËŸO&ßËø~Æ’%ÉD’P=ŒãU¨·ƒXlJBVº¸ t[si#»šsûÂêavWnÛÎ*ÿHÚÙ¯Îg=(0`¹>|å4á§yÖ;œžòî,�*uô¿‘aOÛ‡²ÿmg]7MésöRÕÏ¢]žì}1ö¤o!g|œâ¢6ãU‰YÈ1 ë¶KÒ˼:|¾=")[Î }ÑךÆI–FéHèVê-¡A,|4!ƒI 6 .}ÆDÁ¹RÒÑ|ë“.oSgHN£¥”±ú%UpQÒ¡o"º.&&Œœø‚Å9É-•=%½ðIÑù6VÞ#†:sW) ”ž#zÄÙaL%áý€a=tŠt‘sBZB©Ö#p×zSa¤‚bšÁ;.R£ ¬‚á–‚)a|ÉBÊ)‹¤Œ¹vØhC}×¹î‰v¢Ò\š�Ò®¸?wl1bWÈ$EÊÍÀlú &LH)fW»8Ÿï†³$Rê7E’Ñä¡`M?˜smk1ûÈ«‡*"Sç(lhFž´«0M&]¥E¥·Þl'èœ÷Y>ýÿÉ{³¹®3[píyŸ1朘’HI×*»\n´{xèê¥û¡s?õK_à÷ºK(•l“¢È 3™CLgÜs?$I%%J–Ê6ʵŸ™ˆy¾oïõ­Á/õX|ÚëršŸÍâQµ×ª5Lõéž6ðWŒw~Â/g&þÚÞ¿æØjHŠœ±x“~x+HëþÞM÷ü ßî^ •=›uÓמŽïàò-ÐÕ·G•ðÃì¶÷žk÷À¼oÊÔ˜øæÇÇæO$Ì9ßNSf8o�ÿšçúÃHFüaJ$&�±¸ˆÀäG±ÿ#Ì¢ïÿéû]÷õ<?/^óÏüÈZ�ö]üò;]ýÝuxïé½1Ñ'8�‡ëã–g}Ž—!ëƒ$â›A â¬dÖ¤']¨\>Ùõ€4P§ š—o> à@qÐoÎg3»äè;ô08T`؇ÕBÿJMí«jÔJÐHXWÐ1¹y~ÃÛÝR7y(Š´ž =Iƒã°07„“,’~¹Y[˜^vÅüò×ð²ôù?ry4ôzô NíÑt“J¶©ªb–²ÿ±åüT—¤+ÂGãm)‹³8&8…Œîél"çŠ|ƒ]ô—CwÛ3Q6ËðÄÇ1ƒã°¡Éúy>œæôjÈWÓy÷)o7®|áY é"ÃÀ铊qI\î§½•‰¨`•Y‘ hÈd 5Ï”Vª’:²£š.&¡ÂÁÊè\ ‚×.ïl÷’\h)–d^ŠÊ&Mv|ëûm"2%ïâ`µ¢–Ÿqš1Ñ çˆðU"£aîs´`ɑȢÓÊ Ü³œôÄeÁøAf,!WÑaDðÓ&ø†¢ŽqFÒ&¤n ‚BrqJùÖù‘·"TD-‰¹Ô, ±<”Êd»‘GWCæ”°˜Œ‰‡ÎÜr)‹œ‰7üÉNÚOçEo‹Â“y"Ê&gˆ‘°)r=’xع[kú¶//¾¶öŸî^Òú¦òW«ýñi»«*ôÒÑŽÿ@$³U…++N¥I‹b.Œ\‰~æ‡|Ù{ ]/ýË{·¶ºYVØÊ•%S.fØ+F×vN ÈÐ3¤]ÿýÈ"¬_ÙÞê}Ó]À�Õ·°~œÇð½ k¿WPî•©;VéÕ”¯×8oÆ«5üÛ¤¯­ÆZ�›7ƱoúÓäMÚÛ»J’ýÏž®îÞÝý„®ŸÐÞz·þweÍý·ð³7€àw»îÝ^` ï þüb?œô¾õèwïIýþ©Ï#ûî¿,(À�¤±ô·8 ç ëhíÍ@±ŸÙCb>«L[ì.^°"™zp1¶Àž%\ôßî}^+k¨BÌ0á“5Œ­ž£ï ÒÌU Sþà¨øLØy¾±-ß@|1² Ýæ›¾àñ7Ïgõ¬˜­Ž#G ÷—´ME¿ÏÈÞð›éê÷îJ«ùf Ï[ãú“Oz–—A”_÷a»·|ks%©ÈêÄŽbÒ,e·„+uÈÕó̶gá¦ïùõSùêZÈ\M›MÆiúZYýrìû9=l¹»¬Ç2„œíéPå’“‡ =<;’lû¹ÔävN÷½’$‘Ž+ú<MΚ¬Éišó(¢Kºso£õA9Â\-Y]W~9Å<WÑÓÞtÃØ%H%‘¡gˆ\K'%É2.tI"mûZÛŽ–;kLJ³È'T®$†DoÜ`ht"5£”ES £c \/½J}%X ¢¢QFC“ã>1-m!˜Š“h5"ÝP(ê3›F("Ëu-Õ.Þª`TkCdÜά:'hå…ä%Ù‡|°œ yÁHΚ$v )Wi²ð*1±}Îm—ið“Édy¤öó~|µ6#Ñá¢RzJyÒjèÓÆÌöözŒÏèÞ�4Evülð°á|w9ùcZžf¯ÎŽd‘“ó.?nÙƒI, ‹%ñ‘@Iš¬ö,äôªHIß;Ü´¯5Îg�¶¸h¶`[B¥®­ÝO*…%G+àk06àÐÿ´=ß pùÝÒÙ¨pƒÞ`\þ™yäë*a¿Å—žÜûS²à€}³ß wAëoÆÒbÙ½6–»ÄSyg¿q×­r‰~v¬HàcÀ |4`}sª�¶EêR0?Tð¾G÷ÇÐÓ[yò{ŽQ ppþ§Ÿ……Ÿ\Íß6§ ŒÀþmê÷_ Í¦˜¬·Ñâ°�ˆZ ¬æ°9ÖlÝíT$ «ò ãÆ…·šLm~3¢EpèïŸH*àAyo7ÀSLpqbozÔ7¨DúmƒÚq59Ë—G"Ó,Î}ÝÄ{Ø0!ºq6a5ÌØªê&ælkä`ãV('Ó—í‡MT¹”*; ÿ\}È~É“í†Ç"ät߇3›pôwD5gC›]ttx‰<LÊÇ´øo+ñ÷[ÍiŸ”ŠÜ°O@ŽË(Ô® Ò†L†)m¦5Òvº+ñ 3'¬ÚK6eåQ2d)ÿ¿‘±CbYq«ùÀiRI{¨†œØ8ÏY)2¹(b˜DÔ)댠Ό0Áú€L„RQ­JDÐèSÞ®ªÄ»b›Ò@8ÍEN¨qª¼ÍBʶ•Œ@QyY²¾©‘~ 6¾ŠARÆLÊn :Eǧ‰8KMèXÌ¢‡‘ ’±œsI# H‘äDå*'ij@…Í+qUFPH{BiGx4|L„ðŽÌdM4·Â§¬¨1AIÅ ˆ2>²ØðEÞÔü9Aö€hÚË]`˜÷ФÄê<ÇR³#bV¸ØÐ¦]™½œÓª”Ä4ƒÌ¹u±l¸à«6cüpž‡>«¶=O•øòôtšf]aíªÛ¬ºº®‰RÔ±ä¹÷D³ärˈF7÷Ö_Ìa+€bêpÚ‚ß�»dC‘wè£-/`ðtN÷yµåW�Z°ýOº[çQÊÝû�Ÿ‘¢&ò$Xûí]]îðƒÁ$½´é¤�� �IDAT“ ô£Uâ-Îcñ½h€¾žé¥æõƒÓw¸Uß –(ïmý”ÚeĬû?ˆg†Ä{Ãß]-,yÇ6ë¯BpºÏ¿Þk`þfó`æ[°ïÐ&5¢†}Ýñ^å6�"r[ÃR@Ýqý&¸á€xµ¨?кY¹¯¦ñ \£ßâ0·å Ì5Ü50…¬ø'3™ЃÙÂ`Ù£�Hñ›ZÆVì&ªZ•t-?ŒÒ…GíX×hw“H¼,ýæ’!æŸÙ±‚F×±u… °¤þ&cC7x{Æù)ËËêÕFÒgAY±„×¶üÒ& Ð E•äÁÔ#ø8=\ŽýA$î_u¯òJ’‰«Š!Ç &7Ûè+ó"*;.o®ž‰6”ä·<›d½öµO³g‚>¸U5B›HBð %‘þ×5OÇ9C!OA[Í<¹%¼1Ü©(j‘å\Qébà!±¤ÛJ±tŒ¤€ÐI8)GÅ<b°Á› ’ëŒe[­͆!ÊÈŒÔßâYˆ‚S=ŽÁz×)ZA»D ÑcÆcŠ“‚ºdcT€£zÎjBB^:A“΃Ќ ÂH’1±È+©¹–&ð�”¯³¹ Ù¸+ˆ‡Ë™ÕׯµÁµÁÏó<ŸÐHL„?Ha¨:£"Ðh’‰<ù<ÕÁ)Ýd¼cÅ#ªÎ¨l{…Kç漤sËÝ,K1W¹ÊŽŽeŒF×ñvFD¿Qýb!LÊB#-ièY6ÕÕ”2`çYßðŽž˜.oVEZ–©üº{¹?d…”ÚdœjÁ"‰¼i8t<½”Û¾þ—sªÅpX‡óCì.‚%·¨�D½¥à* Î ®ÞæVÝñë ö­aÑ6‹ÐÖvoÆ×ïð=j¹Ùü“ fÀ¶�º×A³3Ä;¾ÓËï™çà! €ëïìO �Ù}?gå.!οÛ]îFx‹Kß¿¼/~~Õ’À¹øþÛüÓ~Âô˜áEø[œîó¯ñÚab1ƒÜ£}ûížÍ~¤uÝ¿˜ïˆhhíøÝùÅ 0iYÿÇÛ%à€¸˜½-"l7µ•bÝq†>;Æê®?Íð@!fxÜÏ‘·„=R)šDG¾¶ ‹#²þ,Í>Öœ³p;;ÌIV÷d¸P­b>+³Z£'ª¿x¡/7R[[Ó´A¹º¶|·¯ˆ b‹m˲A%Œ¶òµF‚LKï[n²ƒšmÃöWà_#'Óî—>ˤmòÖê›gýh,‹ Íl—S¿mmì'èv^ì·Á  U&ÛÑ~ø ¦ÑÊJ2TUiÏ9c¼­üóÝàHø2ÜZ{6$Øâ¨“U>?Â1çUF"òަX¡ž›2„A’<‰]ßÅV‹ç†A¹"01P>JæÝARai8ó4æ1eÂÓDNF!$3É»1‚ˆ”&’û¹I=5TPNÐy°¬¡Uˆ*gœ¤DdÆø”Q¡˜òÀ¹“ŽJÇ“ä)O²dŒ¥ˆàCYÕEY¦ MHÉ÷Lù’8:n|u¿«£ÎÙ„ébDêxï°•‰ÌRRltœs^ö5ÕYNfYY«¬ÔÄdÃèÛ~6 ñaâ·u*Kks²¡ÜÉ’ËRsd¨çQd‡çîÅ×ÁèC%l†Vܺá¤UÙ€Pˆj)‡œ‡fÆ9‚( Óµýpد6|ž“Éë”M&wQ~fÜ!† ¡/ŠŸj`|âÒ:}‰ºpÒÚÌåë«ÊbŽ´ÇÁ¢†Ôû¼)û¾´y†… àÑâæàwGm@ÞíÖ,#`k€È¥›X¼›pEz ´>7ϽB”–�<¢8¬Àº†Í�Áðj ?¾#`’o¨%ïÝ—ÔÎ,z`ýncPÀ ¹„Øcÿga±Ÿé`ñ¾Æð¥7h`ü³%>�J‚Î0toJðö-Y~jÃxc›úÎÚⶃ´P@ ¸ Ã/&÷™Ñ�À$‚U¯µ/–b½y>ÅëÖ|‡m-¡-¸Ñ¸ñ3„Gb±@õÇÒ<ÍH=ôÅ­+ªðK_É Ùt9éŠx½^\ ’=”Ä€Ðo'¡Ý÷w! 7@‚X>õ±/•©Ú2ˆï˜ ‡$§¼[j>Ï_Q‹¥„‹ íÊ Y•ü#ä+D⚸1ÎPò[=ÂÕ»W$’X‡Ãª‚ŒOl‘wQ´Íiã铺1äéÿì?:gáUAíÆO¡¸Nê¼U£:ÎnôÁF–í¬ŒtÙ^4Í*éDÇ”¹îôEì"{îªÍ§“e¾ÜêN‡}Åñêf· 7ÿØé2>ê7õ¡âöœÈÕ*ñsK–6h%%ÚÅ‚N§«É<äJ` ©ˆU~ðú08>Š¥ŠHž‘!9i™r$Eª#3‰ŒpTH1ãÄ14ÑQœ+ʸOÎ &(S**n€!éÖ5”¤g!©["SÐ5-*Q¬L0Awœ"“ <ɬL= $óŒÈBKÊdÖEÖfc?t2S" ~„gz–·™5Gê™ð,oÓwž²Qˆ‘ 9(‘2CVVËiŽb:áežlKÊfc+‰œH>­Õ„J8#²k®Ô¢`lVS=ããõÖ†§í×­•Äþ˜÷{ú;ã§pÇ [åÌWzç#qâå@¹‰Ê6ýðÒóf½¬«ý¶¡Ÿt~6DZRé]pÊǨŽ·ƒ™£hŸ¶ØÍ¬œÈó­ÇÜv+ì €™â/÷‘Ýì‡x<¥V:Ô@£ÑZŒwceûÞèŠ4¿™‰ríöïxä%X ò‹¤%z›€öõˆWæ°#ì]Hƒð oÝ^×€5o´­Û÷דwIíá}x”®ÐÇo]˜pQÀýÄJõÓfÑÿ®°ýËðƒë§ Ń5Z‹A$å vö“ÏöwÝ'L�°z �ÿ$d&Wëí›Zò¾ÏAÁ úÐ�ˆO À‘Àã,(À¡?ÿPJ^[Ø‚<0×í­Ù%s‘¦Ò©q¤ÃêúÕ<¢¿Â7 <ÿuD²¶;i0³j{µÄdy¦ËÅ ²V/*²œžyA»ÃÕóñâùãÎO³ÙŸ”þÊÖX0™b–ðeUpú ÔTÉŽ‡n¿·Uã‹ )iÂp4 GÝÈK)”%ãQè·u¶ÓU¾Û žê¾ðë¢KÃM¢Æ6üÚ}ÊÜŽì.ÿÃÛî[yÄc—âìx¼ ¦72Ńýe½_p2¯ðà˜z/‚DWñ-ûðyÚm²H8èÊ=C9ßÅáC]Nø ÉD¯¢¬†˜–GÓ’åeaS#§\“PÉÑ€H&:xáÚºD%‘5 œºwÐ12‚À˜¡L)Ž´apŒ†HâÈZ!2€z O¢JÞÓ¥1‘x•TÏ DM3%D’b d ©S©HŸ±DDË0Df“K„Θ@ˆñã˜hà&+zîe"5°2’¬8hJ;GÆ.Z/2™ât@d1Yâ+ÉÔÊD9†"Kyž#“R’„>‹EÌWb1Ÿh=³›r|±¥ÊJòY½<êøD𪙞½jéáùçv3á„BÓ´iÃWrvPŸì‹ŽÉœ™1qt°æ°»q¸üŠÕ¶zûGÕ+=…K¬È` >)'J8‘´U+<˜oñ‡>¥ýS�íÄJº™ÝW G#Šœ6å8Æ .í–5ˆ€èÑ5P ÜP Zˆþ- f϶…ïèî­¬Ìêźµ Hƒ)ÐÞÓ¥òPöï"BþÎ}ûMÈ /{¤áûÀöÝ~ñ£µ%þ4Re”~òq Ø÷öý=ô†·¬õ_&aûkŒº·‹ïXïžÝÝù¬š<hKj]B8¬5væ ªøŽZýžØòÇ^n¸{ÀØf™A1bnˆ·>À‡×ÿféõ•A=†±o¶3#Îᨄ+·Ùº^'"n Ù*4­Vâ…¿Þ‹ÁŬ„;¸ífgŸÞL°åVºÏ±_þA�m‡µ€'R «{ØÑšn<rH`ÆÃé„Ì*& ϧ:žÒqOHCº ìÂÞXŽÿ<ã[Z¡;À òd°l™ÓÙ6Óš×rRpbÛôÁyÑ’++OãvµÜû™¿TŸØÍŠöÛ8\Ðýý¤Ÿí; uOÙWWìåÐÄŽý®^l–È¿& »;AÃe˵JÅD Ì'ªk÷"|íŽ5Ë?VGGªá¹FâtsÜîä+gØa7ÝÉÓÕøÇ•8NTcŽð‡ïŽÝÇGµ•µL…áÁ« ™*™MŠ:Hî-ðŽP¥lKi" „0¼ =O„ÆOBR2D!ÆÀ¡cH £âŒJ(>´ˆs ©—ÁÉH}â4³\¸H\Bá|’΀Ú<†`}iU—!�í Ý3I¢"%À¡1YÕ'ªU ÊSI¸ä<Pß'—¥–b©>(âƒr‹$W)Ê!YßYÕÆ;K,’s™è„¹±´}F3>+¸f"2m=¡C* Þ,ÕnQñÓ匊Õ^°Wýgx¶šL¤¬µÎU Úò�VÙ>úäKŒ>ìâ‡>þŠÌÝ3zi³g9~9¡+¹ ¿Ãð’M€HxÚœ=hNJE³qp´§ƒ¸ï0™ ç bMêSw¡‹‹[=¡Ú²~�í0Ý€ è#¹€ÀÐ[ ÁÍë¨Oìî¸FáÛÛ×·ìþ-ê+·fcì[ºOÌ„m�™Û|'5ëEµ†e$ðO€¾€{÷Û×Ìõ-Rü>žñgt¨€)°ƒj^{n¿yé)pæ@¿~_$œýá’—ç œà5AØþƒ¿Òx`wÿß^’ °8dòtòðãU­$‘¬¯psµ{«7H÷ƒü9櫹E'[ƒÃ²ésŒä¾l¢†Ü«ÜÐ9¤}3aØ‚®1¯qm€\‡íNÖX†—C1ûE©ùôЦ«¶;lº)ÄÜPæù, Af°[‹xó þ‰!uø&ß5UÿOZ5y<¹ WòDÍê*MvDû$;neƘ¨‰¬“p\ ºë„VÍòãÙÕ´Ù® $À)pêíìA&–Nê0ãÕƒ|Rpr67·u¼]~G²'V>ÊUd‡Ž±'1×¥<c=õ7·}~a练C™ý~:ü:‘ú¶±ÛðÕÖý—3÷©²úW¡Új¦âd6<bæ(˜vþ«]®â°» ×Û >LÚ¡»]ÅQìÔâf¯øK³ýUvSLRµÌ9é¿TÓ §³ãÉ|:·Óø¿jÂÕ8+­äH$q¶v9øÂúœ²œs©gaÉŒ6%—â^ÆKC®c æká½bN„K’ h­!)ùÈ#Ë’Ð…tàcऋsC5¸-¨¾9ᑺDDRœ*æáMK½õ®gÞGÖQ>°<p9P‘òIZ”Œk ÆSt6JÑDd10°ˆ´¡®F1¥”PÒGe¹bÔ0á²4Dé’¤Îå­¯é0TÆYuLº‰çQ“R™BQI&<çlôÒE7#ª˜O'ºšæyº¥‘Ò§¥šd™fYXÇ3ôUŸ}s5ÓÙ+qØ%b[ׯÍóBF¥žõ½€â+ƒÀA0 üÌÌz¾Èš•“Þ|Ò»ÅÑ«¤X`}Ö&¿Ô²^®–<ûí’=+Ù åÚhK^Í_´ë¦Û) Å¶®d–Ùïïª]Â+b€ääÊÞ‰I‡{ȼÀÖU€y“ñú—(p-=9ÖþmvÂæó¨, ,ï¢ ¤ÝÛ¤ß÷ðÝ‘à=§Šïê Š 5pÑÜãPJ Aõ¦±½¹ÔsàÚô¸jü´b8üö†`o#¿ÿÃßÎUçÖ¬¦•ãÌMÊ,/§Ü¾ŠÓ;KxÀÜ·}ïÎ+˜×'ƒ·t)�ˆç£3`/�K§–ÔÛ´Ž@†}ÿÎå³ç™zqC`GX‰ü·hŠŒflàfÛݎ‹NU»%n<Ñ@HGˆ[ À+Ø ªwñ¨DVãB[“>)Ó$T˺!?Žâ¶Þš¢»YêÈ…bG…(ÁúzÒ·bŸ©ÛÒ_Uøl2ž³q-¶_=>Zï–,Í·\?¥þt0/ë‚‚ådq´ùèÐH“+‘ݲô2œ‡WäS¡V•õÍU|zqüñ¦÷Ò;†1Ew0‹èI殤§uËD¹U™BE·/s2I-ø„W“±¯åÀ~ýiìö³øL¥/³ÑaÙœ1Wín·âUþ‰Uu!uç™;¯Òü¤%^P*+®F ʉYÙ Ò±;Œf"TÁ‰òÜ…`­ò\ÄBN§ŠPµ ¤t‘ ßPf™Ð„VÞ° ¤‹ð4$Åh¥óœW‘êK†r`£¦AÊ,Ê“¥NÐ<ph6zGhÑË,HÝe™§\P0ê*å\&/hˆ‘XŸÐ#gLÓœ1Hà`)’j‚ NRË.’xÈH”L1¹ Ä(¹ÒÁŒ)ò‘c´AÆ\(]I*¸ <g:EÂS“dìçyîu%D‘œ3CÏ<[-§E&&‚íaÇ0|“Ü7·ÌÙì$eiºÛ5×Áöp™Ì˜,£Û!økBb3ËžSüž¢R¿e§ó¼8gYFK^³=¡…cs^Ì\V˜œ˜0›x|ÉÄ™_ÀÇŒIZ…õø@Ž6@ƒ] „GG_Ïû“~GiH˜æ�q°^Ààؾ¾§ çÕíºy·"]²CèîÕ™ ˜�W@¼“I‚ó<_÷ý6!XØÞ@?Í{núô­EǶ@WÁ¾VIÁ|ˆCþõ^¹•€½fïpX]¶B{‹/Ç¿Aéûwï w {ÿov7uÁ_»1H`ÕÁX`}——YˆæFï8fÿ hA²…X^à7ÀïèÒ ?C²€¯>ÜãTKéX¾|¾}x½L˜{¨Wòsò‘ez+.·ƒýNpào¡ àc„ËÐëWÖeÖò#<˜Ð’ìŒ�_°²ßä×Õ,à% $� à!îºfx±P.±¥@ŠHÅ9 OŽ„Í*)ÈRÆiöŠëFÒŒ3.eTS$Ú&kâ7aøCAþÔúÿƒ’ó³=V˯P/ÿHæ‡Æ v£IˆÄ¤ÂX‰£“yoŒ ÏsÁ«ç²|låÃîðag–M[úk/åŸÐ1RÁ”›äYêq;ëd–Y¦4­mÄnoÍf]ŸÓ,ô$§&Ù^ìQ Õ4P#«È\ª‹˜¯‰8¥J“é–[»àiyÃn™<ŒâÕ ‘K%óŒ †|4ÜÚh¢ŽË ;»‰c €è0nÉ®ãûÀi)xÉ9ˆ L9Ç´'2Å KišÄ™æ*°¹O&:J¤ÊU.Sj%¯­Ó)E-M‚Ç ÄR?D0Jtä™H D2©&Y&ržxªbd RPÂ28Ãè|²‰€É”é˜åR°Ì'Pâ £)ô]â! ×K%’ЊóÄ…HŒ;O9QñD±ˆ`HÙ96€D\ÎËIÌË1c]Î¥s+3ƒ4„ÛÚYYe­…©·ƒ? WC'š]êsõHAê÷‘—&e1V^œø™Ðœ vòÕòiþ›-5ýòƒŠ’¦|Ì,ZY¤üt³0JJÒž$iè02=Lv|ãÇòIë_4Î’msµùŠ…©Ìí‡l=æH¶G z¶G»ç“”%œö ÙDc=Ö ö®È¿FàÄã¨yC˜Ý>oò ¬ rèV£î ¶MÕºËìå4¼/ÛïØµ¾®Áråï.vðGðìmø€_ ø°-0ÿö”óu­ñ%ýÛQÿ»÷ûo’€½;ŽŸ|›™ù×¼0ºÆ‘Å+k; ¯¥ûðÕ“VH—XŒ2…º†˜[4¿€åÀÅý÷B~4`ö(€#ȧ°ðç(¦³£ùDMéeŠ„R˜¨’*”‘™MõôŒŸ§³õúé.Ý¿HÕ’C™®ìŒ@fP§xf õ�(ôžæé .2ß,ú•î}crSÝâ£á‚mI…ÎQjípuñ{ÀàÒÜ„mƒ.þ韑ØÿÐ*RÌjŸeE®Æ=è¨g ðÖØ0ÐF»½±‡"õ$æ\wżò3N~•]jGS^åÅ4ð¾ M°éàyàyµÌ}ð(•˜ˆá÷ –nH– -™×ˆ ZçªÌl)£ƒŒ—“åÎò£']•§B—ɨFö3çä_`N›WºË½Tê uGêYµÖ2–¤R!O AM‘÷D°Ÿgt¨È?曓(…°)±®ƒE¯xz58Æ4+=˜éX–g,A >´7ÂqV VIÎ5‡ ”'Î“Š°y”:))ÀCrHÞ&Ä„ð B�ñ`”Ò”#ÑÓD°<°ƒãÌgHŽHÇ Z'FÄÈ áD¦‰¬(w$¨˨ˊê‰H É‘TDOˆ·ÄDâh2>ÂøTÔ‰B$%DúÄidš ê‡äàòã,jJ•x^ÙrÛ Ï¼Ï ‘6 > *T¡i¡ÁHŒCèMØÈ®±}[ì#s™ã©-BðšP*‚>æ•cbg8¨V~7¡£˜‹p©›I&N²Q6fë =Dœ»vvÕê²0}ϸPû“uéŒösÑ]þ—¯Gvxȇ‹=³]=ìPôØ`Ôc{[�3 %6Ùc(‹)û (°eo]Wû7 ÄÝzœCõ0_ßuˆU…ÕB^;;\@ø ß(£½½'[zo¶3¾µkÍ ü DzR´zµîßFÖÙ7éÒw\.— HÛ7.¯¾eÁÚ„/¯þf ³h{ïkÀ÷ÍŽþÌr?Þ~þ€š ˆÀÂ"¢°Hwʘ3‹z –Úd^ÄW]@ÔƒlA{Lˆ�&ï\YÒBö� _<<Óõ#eg¹4ù‰ K#³ò:àJBOZ¶U-ήÏiyÆw'GP±¸þCo—²?š+ §WËóþÓ£j9l³ºõv4þ®yÜíËNãBaQ/Q¼L°=GA0ä¶·nö*à_AÁLÈVXVù²ü”è¢31¯©u#¨àtà„ŽfkcÏý¥*/ƒ£ÍÿÂÒM£ÿ߯꯼”Kö¿ùͼéÛxØvèíXwÝÚÑa’N·{Ö›˜7çý/ÆjÄ"ŸNš1¿¾aw#ì *[™ŽïB³ƒ0–Vè˼NÁ ý¡í¸àµh*½’±žzZ‡ÿÛšÏÍM5îª_Ø3IgÐU H†%̸¬‡XˆvµÖËLd±gaˆ‹ÿ“}B©Sâ%ÏÊXAR"†.Íœ+¨iŒÚQ=äå,ˆ ´¶ÒàÄÕŒö£ö^¦TF‘'i“·1RUiY¨Äá:Ë´'Hƒ‡Ó`H’F¡‡(º¨8±‘…;Â,BC$6ˆÀI"yJQŃå‰2cZ<ëCÝÈHäÄH)eÁ‹ªJ”˜„¤`‚ƒ)bÁc"„#eÁÑGæ#§‰qF’f–°äƒã. ¡T¦qF:$8#ƒXðüŒ²š!A{”cçˆHD»d‰D;m}ŸÆ]ÜÞ²wnHˆ2«\dqðÑÿ+Ú+?² }š=°<Û·n£…:B1R) IÅ>EÚÜÔö*Ypö«4h7˜Ö‡Ð{ãYn[R3Ðä™~>EªÃ🦮/íLU‡4wÈ#Ð 1äFâ™ÅRNqh)ú¶_£·`Àhî€l©¨åwa‹·=ÞƒoWY†æCWÀZÈ=ÎC»vÑN†òžš½ßòwïú·?¬3`Àý1ø9hoõ× ïÒÓß‚Ò ìî{îNéçN~he€ýAÙö߇õûfG)ïHÿP*Ó{™�o0Á9ÇFàÀ Ó„ó~±Î²‰Ù@ª$ò§QèÖ•W¢h:2!+,˜Ý‚ÞJ}{>Þ±Ù@eѯÑÚo¿lùÚ°w kaÃñz²zT&Q²žº‹z¿«-ÜNk‡`W2^9Z­ƒYs W_›~5Î’«—ªš¥O¨ævž úº”J ¿ ƹN™ÑËg®¤]««IVÙ'ÿ=¼Å7 rFŸÏÜ‹5>°(°ª0k†WGøì#÷HÉiòœ€ÄÌ6´ÝÈv N÷Âî;°á÷íöÏ]>žýK—mŸ± l•§£÷Õd{ 3yzÃÍýê#» ã2‡؋aš“ÉÀª¦´©ÚL³Ãxe÷öòéû¢<9ÎÎŽvýiÞ*äƒMÌ[” ãvü:N[›-E¸L\9î²l/n_Í›q§JûtÚ¤iâu–ĉa]^ÖT憩±V®¨ÒœÐÏüôQšŸ¼›Ó ™Jep雦û …Al¯§3IreÓL5Õ4Φ$Rï$ÑšÈÌ3>:Wè˜-©Ît„æI P Ø®\ ”%ÉXâi´®·žø ¼3ÑØØÇdXˆˆ‚QÁ¨N"‘àX0ðmäÍ&D)JR ŽG˜,¸* —^¢H Þï‰5Ƀ‘Τ@ú¸‡WðRC"‚L#q‘&i‚H‰ò˜È‰ ÑsN2i¢ù�íI ^S@$Ê‚ˆž Nå˜vÞƒô½a¦Ý=4,ˆ’NXÎhittynXpÿ±þ%ȲõU™®F×Ïõ!'ສ<KA<w)DaÉ U®ÙKq9FÒh±¥Sã53ÉÀY}î$—e5™MDNpFÛ—˜Ì»)ßž[º±á&ÃùiØŽd«çŸ;v~‹5!vq\ÝÛ·²6ÜB=t/ß÷Ë×"Ò§ð{ C_ÃVÀ®±M³Î`Ï€T"§¸}3&áíÓ~òÃpÈNa7Üm…=ðÍÆdÛ?ßôúVÜàßoŠ'ÿMÆ ï6†ú§øëüZ™¬ �� �IDATö†;? u¯1ü¥¼£ð“Ôòµk®|Íðíîâ 8àç;œc&#¹œ&ˆ1ü¡}”&g@êuÆýé7Ã⢠ØÛ5`ñð! Q[fÑ� ˜G¿†_âÅÄã³~(vÜYÛTë1¾XÛ™ýÝQ 3µbëwÒáœãk:Xqt†§€ZY ¹óý(,€ÓÕVÌ:_Y.¡ØWãÅ,këW*l]ÝN'8,OÐ7ÝíóE·-»'“&;,öÀ«]Wak�‹ ”AVHѰ ¶¬C} ƨU©ï)ëÓ> /'7/ûÔúöUÝ] ¯‡qVµ2‚dÄ«‚^Ö×¶<tÉ6{‚Ô{AÜRE(QV&*ËÚ­“õ´á,å¶Ôì9ôWúŸ£ý¾”òV²G™æ¦û¦m·W-ș۲͟ØúA+LÜ [[[Ë»ÇÁ—'í´|<=}*RÖîf]:±Ùí  lÂc&Ø2’b sav$dŒ‘lÊgäLËé˜ñžÇØIŒ“H¢!B“:*n”B3ʸ‡ "”’Áyš³Q$I’³ÐŽiA¡(2ž(%Îû¾ßöífl8© —D2Æ uÆ¡s42Ÿâ@("ÏC DÐ$$M4qKЦäçŽæáܘ¼‹©IÛD¤à>²A R".øCp&4µ’”ZQ"À)×Biî�OSbˆD ŽH‘ÆD#ñ„0ÊHL)¦Á“KN¤à9U3Bb€ó�u >@0�N‹! AQ•EhGˬgCCâ”Æ²d¬ <5ݰ‹„¤¸ËyGúÕ„ˆUëó<YxÍ[k|ŽŽ…Ž–ãQT“]ZPÙÃu-º!ìÓÅ+,’Ò“Ý(í„}–ñr’&-2¤Ú¨˜±F\8qîcjN½­6/év#IGBm]Évzšö³åæóÏ`PÕø€Ák‹ð@#KœXßÅò¼­Dxmô H<\�9ž.�ܶø†« È�Œ¯ù5ù½a÷lx|ë·ÿôõ>x¸/ÀzoÅß~ïˆðmy$@ ì¡æ^1”€…oõqòÍÖüï±7Ü}X³¿"ïÈ}ÿÌ•ã}Kí7ÙξKÜkæÐkÅÚð]?Ê*Ú@?戋à„zòMó2múѦ»>O%”Å @1ÆO<SŸ6‹‚DQÂ+ÈXY¾“K˜Žî¨ºê"míd%O¤­Z¸[;``'òÎýEÁq¹>9Æ ùãYaé™×2.ç®üZ¯P¶q]Ș£¡·4Ì£?#äϵÿóQ²'µ9(À‹ r‚©A¥d&ÿ™ˆ2º2¯b¬x+Ý¡wJ5ùЛʸ‰Weˆ³&“a'³íÒâP\`FžOÊ8ÔÌ`µûj.¨²°Œ^¨«Óp8>T©-›…žÔµÈ|à„K~ŸµíÊßhØbCÓ¿L²´µ¿¯uÛô_¹uwœiº Ã¥MÛÀ½’½°óûÕžu䟙4ó’*ЇÅx¾Ì¯6U»Ó ÙB“Ó=)o'—“é0fƒ gêÀó Š6T›ùÀ*ðj3ÍdÅÄD*´Ej¼4ÂÙ,Ó3ØD†>äăÍOªŠÐH‚°Ñ¨˜(Õ‘Ü4)¥0xë­¿ù΂ o!ˆC´!} "²¤h`41c$̱ˆDaLp6aœPBƒãH¢#ž–D JAh"qDbÑö¾ëK­±½mz ©*4jÂÁ)”4<!]HàQ!)$Ä|"–2‘€ä‚óP9¡22JâžDCûM‹z’˜ ,Ö˜bŒSâÁÐ^²,Ñc4‘ÑÚØ4„û(hÀô7µÍªs·s²*2â†3Ú³MEc´','E’HFâ¿J§ƒ]S/’î úÌTº©oËjOg^¤GˆnÈ,wy#¹¬Ìè·¸êŠõ8nzuz¼ ì DºÂ«v>Ø@Èe…ÛéÎÀ˜@.¬´Û ö. dÿ=†LÙ×8¯„ýÛ˜�sO2V�C†1ïq{Ÿ_c¿S”Ów‹þýrôFñ“Eµé'i{¿}|ñÖ¸)Þ‘nÏQ­Ñܱü=ö†ï4Xû³OI?²0ü5Ðwß¿Åný€Ù›�s7¾SÅL%æ×P€Å7;Ô€Ccí¸ÍØôË™ièFÕx¹§Hs‹ è€Ažc¾µ €ÌÂAùÆ@Û×Lâ+‹Ý%r>nà³›Ûîã~/¤û“Gø  ÉRŽùÎò[PØè�Ä®¢Åú±s ²zhó‡ ùîŠ µm*M^ø)Wåàž™I”“6WÏÜEsu¾¸$L¨RJ¡¢&ÉÍKÂÈM4’£¤˜gç2ŸS5[0^ùèMjŒUpÌa ûÛÂêy!xš1›ƒú)ů aÿbI¦µû˜¹KµÛæäd,:x–¿<Ž)¹UÑj’KÓ•ˆñˆ?;ƾ:ú4m—âÉÃ2²d¾Ùd7ÿ?uoÖ\é•]‰­3ó�ä@$“LVES%«KÑ¡ù¥á7ÿY?ù©#Ún·#ì»dw•Ä*I,‚$™ïðMgÚçø™d’™¬bI­–u߀‹{oX{ïµöZÛTé¯Oôvéð°ÓÅö­•ýEÇôb˜kwøŸÌ|Lñ¸ª%[‹ýêòKü•÷7ÜSk¬W-çÚÿÂ÷ÔÚÅXh{ÂÐô̼¬».×HÒ0fD†Œsˆã˜ö:ËÆW•ÑK™µN^¦)Óh©˜²è !'®9˜ÈT„ÄÛªEÝ0.(û8mlHÂñ …22&Ɔ¬‚FÊ¢M,†!X!ejot0|Áa@1¦HYym¤VF(Sv‰ÅÈ‘êD"¨LŠ©ä²K6Gn'7¹i”.2—ɉdÉQ¦Ä4çŒI“*&UV!Î)Š, Á$äœcNDN 1ªÈ‰—œ‹Œ”y²9†œs&³•ºJ 1) eŽ^Y–@¦è}´®˜¢¶L³^°±q+ilô¡> !&'«•´RØÊZ1ƒs!¯(ɶcÅ}ãˆ&¤Ñ˜ñÉrD3âÑæ dá—¶?¤âsVõ•â·ç»Ãu¢•g+5Wý~$µÀg5ÍÚÀ>p³Æ‘€QÜøØ=àÐè ãù„˜9‹òj©1Ýÿǽ“Û8�lï€ï qo�ü¨à×ÀàÏkøñûª€NÁ·H?dsó NÀÄwÐGo�ãò^ùæ¨Zü�%õnY÷­£“£ú?”µ÷/z¿áš~<é¤�plð¨Dq¤U>¤ÝΞ¡¹ÏFÑxú‘2é'èÕ|qñ"ÿ QyX„DðÌ=ˆãeu”6ÿåŒå%Ê3¶G¾óXžcé\6ñtÉô¡_ÑíÎÞ4ʯýÞ.›Ç4pµ™ ‡ìMñõ¿¼@¤ ½ˆŸ|xc=ÚÞ[´ ؃&ÏçOWË Ò²Kü‘³¥»ÚÝ•¢^Ö‡¾1×é¥y¿S’?êú__]ìj,56¬a˜~#ögµÁI…Ö­n_l“„PËs–…MÅš&_F1ŒlMÛÛÒ}:½)”áºì’ûÆýφmŒk_*ɶïÕå9/D²åÑ’ÖªnÙK5vYÁ>ê á´¿îz¡?/Åy.?õ-:¥»]müŽ*~»zðåTÿ»)ž–Å£ŽŸ=h´ÕêÑ2ÙN‹'¥¿nç¤øÄl’QO/Ë\h¤vÁ˜ L+Ž+@U)¥ZsøI·ýh.ùXnã&–-IuS…¼Ô.él¥HRf†¥›r„D,ÕF¸–£»&/4 d ÆÁ‰«%`8 ¸'•%k VW‚d™õ˜xˆ²Lº’RW‘{Ä)‰9HeË„ŒÀ1 “À”Q4†Êœ(S"x™½T¥Q5ÚsÉÁÓ%©çÌÃlyˆAd!æÙæ¡=SYiÉë4s«ƒ((I„,™æJ¢ä‘ bBÊÀrÈä3e.¹ JÀ×” ›œ'Âà4÷Ü3©³–`Q¤>G措˜Y!Jû¸³ß’»|<Hÿg"¥ˆ0wI Ov¬Ô"¨*vU.8ï·w‡À¢_¬ÅTĸ¸©ÂÈmÆUÃÒ²a5|þ-ɺ�µ±X O²S³I:ëeEºU1Òñ¡óF !ȰùblrX]ýûz½z^î^boŸo�~…Åöü'%_âw„ºÀcƒ²Ån‡Íí/êÜ}ut€ŸC%ÌD=>×ðÞ¼:—ŽðAìÕ¦Ìàä»ÍÿÈ«Wûôîíæ•{Ô X ÿA ô¿îßÑò~×TQ»oæX·@>Âf—Æï¶Ý9ÿ«¹ßàÿK’×%„¾µ¿ã9`z¥>ò˲—ÝŒ Š+Ø-êS¬éåBÏXè¢?Ã?hàÓö•Sºùˆ?ÇÔÞ R¨™êLUvÜ´C¿ß]ÔkB=ÓGm›¸¹*ñùDØîôZ{öþ§áøÁózˆÌs[VU5_eíXú­þŽzB l&7!�t/|À)ÐðBîýéJ-V‡âÃF}ä«V•üàòm]A¥2¤£½nNnÜë…)±z ¶¡>ÅÑ)Þó)•ÃK\¸¶cZ%¿5ÑUKñk+^tÕS^´Y'wÈ41û|å¸Ç²3]¼*Âm"Fì/ÒxCeØApßbQ(.Oß3t «V<M…Ö¡ÊÝ‹Tÿ…®ÅJùVm)þv…rÙVÞ–eï]óìIGݸ´_Ò9ÚìwkJŽ-ÿmˆ·©°Z-ÖˆÊÒ¢CME‰š]ÔýAºÎ¿Ìe ë•t@YŠã%DÁè)«ÚgüÐáBõEŪ–uqiòƒj:22‰x7Á–­buÈ.i¹Xj¿”¾å©Ô ^,3Z%%¡t ÕR2§AÒW1ÏLLLO`”Ç”Áx&Ø,lÈ*xÂr‘‚‘âJäÆGCÁĤ8å9çœuÉ¢Ip•E›‰G晘%Ï"§Y¾O$ù¬…”ó‰Y‘¬âªT\VL†2É—ÌXR‚²aÉð(”HœË¤¤R¦æ(  à”˜båæ!ô!Zb MŠyc’IÈ6ÌÖ ž%\úL.f›+­O3e‘c`˜˜Í™Y.$7¥6 5ñÈã¶pÏ‹ºf%Yžlå‡Ë⨙Š.š”Xã›ÙŒa<öðLD©ŸÇT2Åëæ¨–›²\‚5M©…6:—lfDããä:M|á-_ûý¢Ã‚¶ºhÿ{mÂ(Ï_Ƴ†P Ìö®‚$|=kÀ€³%F Í:u(墨©æ.Mõ×\¯.çí«GßIïßêþ&Šzmc{£{ß Oå_Eh*@ï‘~ðÔZ,€ÝýS÷÷¬û·€Ñ/¾ÓÏ@ Ž@õGîïüÕ9¬ï‚â)! x޳ç¾ï>VÙõÆ 9`ó3á¨á‚÷†í:ó¼)µý/¶=€É£üòG@Ê@^-]µ{\ÖÕðÁ±þs}ò¹:¾s5‘åHF V•t±}ò+½Ái:]‡“Çc»JÌ"G¾ô¦-ªê1ðEYa}„ç 9xÓ~þ@W8>Zmbw/¿è·7÷.¿; ÷ÑË“T©0O?Kê=Y2nнÝÄ[ëB«IŸäGÚöûºrƒ :.øO¶5os+°h½.ââ >ÁЧø“󛟜©ð“òÅæjjslºdÑw):µ;”4Þ¨I›Ò—>–Ùß±Ô&uRʇQgýì&¨‘™ÎÄ'áÚD¶ž6|/ŒÙQŠ£´ÊˇÍñ©©7%+ÛìTä½X[÷ç´+@_D0L &צSlÎÀ0 _â&Æý×®�Ä…×óf¥e!»vª˜(‹B‹&³f¼~¸¿º¾õî®Sõ ‘Ç Zm¬^S<=‘‹÷çqŽD¬KÞφñFÏs]ŽUŲÖ$²ª(E­ÆJˆZ­KS3Ý%PÌ1‡˜¤á¢‚ª V˜³œ;çèá"·¹öyœhϳ+RB1¨’9%—ˆf,Ï\ˆ¨9iÆŽ <g 0ÄS,$AYp"sÃ%ªÆ|Î{žéKn cx«š‚7ÉVŠ8X%ÅÚ Î¸àŒkÏ g Òp–D L9smJ…‚YÀ æ8Ë<2.9çAtY’2ó@6…‘0NŒ%fŠ9%¥¯©–• ›Áï÷4�:©ÚèR±”R%ñÈZÌÒH!ë 5«|]±6$N\¹Ñ¤Ñ”BÚ‘T1ÖžÆø ïþâxý¸®WáQåR‚5™Raâ\¶kÃVTÛ¢ ¶mäm>4D£ •ËOø1 vƒµÄ…Ó»«Óç%|sy…R㲺èõ¹ôeÄÁÐV;¡1&´ôÓðþ,á컫G¯ ÙÃ?¿Š×ÄÍ7åáÖé %3oOüØ¡ºoÁ×}‰yÅÛ¬__g‹ßítÓ÷¸Ü/¸Äû*1ã©zç"èwæ•úöý³Ö†âÒÕ?b1é›EnGÉ£Ú½Ê(ñ‰Çu|¼Ëw/Üoa–PÏX£6âZX­¶~TèJ/ßÿ<y2¸9y¬º­ÀûúáÇI”G¥ª'gÎnAyÌ¥Qî@×gkøòdÛ7ÊëqmHŒûä&­O„á+¦Éz[Cáéû¤ßoÅúxiÒ©‚FåXÙöÛ›a‰úªÆIÙœnªã¡É“rU­Ö’íku®ç‡¦üϾx<­õMS½W†Ë!SQf„ ÿ˜Ã¥)0=DÆì~©Ù‰ßhL»5Ð~ÿÓ1?„Ò*š´#XÇàʘª%Õ½Ózg5vœg¯:·4+'Ùõ\Q»%ÿ³Î®¤4ßߥ©»¥|nüÖ….v?eǪÑØ{Ûk·å­E×ZG0ÁG%në×~-–pe‹¼$ýºí§búÁNPMµ²bCš"¯+™2SŠ’…ìôCÂ’6i>®šÃØL¶A°r¼#Q²º0Yqߘ¡TM¥$Í2AW1—¢¤*`—\j©­Ò$±,¥ÌbòÙÏBÖZJ0ðèȳœ9©J™õ¦€ZÈ<aÞ…ašç8:•X*8Œ* ®}Ž™BË-9d²Že¢œ£ ÈÅÀYÑã)¼'ä‚b¶ÞŒñl¹4zsd´žƒ¾»CÉSSUÕº•Í*‹Ê…0 19ãö9 D8ÈÄ$´Ñœ+!´!žÁ‰RŒS.9礕`îÞºÅBHsH6æD‰ç\g’äYVÁ3 ÊE6E–qø b¼En½sô픟%Óñuˤ‰2£¬:WôæhÎ8.Ê"…�ïªj ðuЖD®Ù¾’¡£á§Ä*µ8^¨Ç¦ëz!†`Ëq.Æ †÷àóLàŽê«°¸´ÔÍŒæÐ«;=ŽÙ- Œë»ƒÏ€ ÂÏØÎ8êЮřóÀ3€ÿ2^mÞ<rxèW‡Ù8§õ"uåf½œÎšùh†øU~}_‹ÁŸ|»ÈÓÁ©{MûÛäÐÞßW„7 hxÕ쿃Sýæ—ß?BÏ ó7¯ªü›BùðÝÅÔüŽ„¤^goÂñ¿Tmx{kêôŸ-òè{–]„èµo.Až!ú tžÎˆJA»46ˆN`ûA€ŸøÃÌè¢ö+íý5úåǼ>öìܦ¯B~’›eYòµ^ÔQ¬y)ymºÚÊG'ñ@€=Ý>ç Ùü@\Ç«xý—ãVsàJ 6¶ŽF¨¤}<åÅVq#HJª†¢ºÔf·|&›e¬Ÿ@DœTÕ²Õ¢ þå2ǵ c…ÜÒüQ!Ò¸Úì7ÿÚv_4‹¶Çͼ)™*THží¯oûKå9»[­Äê€so.ÍÆ+V<⟮ؓBÕÝ’ñ.én7'JœÃ­¹vÅ~àB¡§¢·ëJ׸]rç™VŸòâPSgŠÀÂìùoÈ}÷7~ÚØø?Æãu«Üìÿaº2ó\__‰ã™ª¬!!ŠXjÿ½oÎlýg£x$‘0\ŸŽÇ_ù—[ß.ÌÉŸšãg°dÀ¥{¯ìÖjSÈz FTGêñJdȲZõÅáHêj,K™íd½áÛ<ó£&—ZêX%o¤J…IQ±Hx”g„™µ¢"sÍtF1¦)fÏâ�€œPÂEp/SV\@3(09ùxÇÑ»œs™JÙÔZ©cžHúl¸ÍÙ“°’qÎëqæÓèÆìU1fc½J6:e™CòS<HžgÎŒn¤nÛZ×�ŒQXÛ1î%cfYËÕ}×*5øZ$=ŠƒL{ɽBЉË,¥TB*F`è$2hedÁ¥�E8—2!Ceé=B)f².Ú¨¢’Æ ŸA‚eTÄ”\ÈLpÅ„*J(ÆOFÑ4ǦMm§8gŽ8cšÈy°G%¡Î"g�&b8,ä¹Ç4¤x²QUä3|Ú'–<Eãx.]Ÿ®÷ñ*M¶™™°Ì87ëíVYò]ôròñÇ]*Ëú«…‡†îw?ßywƒ_ŸhºÔ£_ĶOųbߎûƒßB%X›š“à¶ßBÇÝ8v§Çw…ÞÔqr“×K 7[L^�ò›f4¢~—¾© ØÕá‹§~¦æÃãÔÆ›¾Zø›o²¾8Êó¾mÞò~Ý/gýËÔÿ–-ðüŸ{nøqqßß}\æ^iÆÖí0ýr±}\§O47©‡7˜tS„ᑵ ØiÜý< ÇÓÝ=J\à‚fiz‰ããd¬gµ ²j\¦ŠÐ„иª€¬‘ë½eöÂnÿâáÝû›BÕì ö°éœæ=ª}KáÜÃÏdÙ]ðÍ26ÏFÍIØVž'_k¢Ã>çrVM<9±ÕZúåbÅI|Üy¡êbs§†“øŸ?[Œ?Éó¦.I«BÍyˆ_¾Üõ«Ë…Ûn* cªFµl}g掦GŠ•'B­ÖL/ä­]O[CY,îÓ•Óש[,[¥ îgµO>‡í¡|¹9\4Á6qâõð" ²«-š—-ý ßÂÚOFyZäõÖ?7»/ÔK5ÒÏ,±m1ÔúÖ…ËN£ì:!´úìÿŽl‚-f*–ùˆèŽ®/¢ÛV6¹]Íl  ¥çœ" ·óÊ —BIP4NËDBUÉ4 SòBÎ. ;â¾;ñ²« Z³WqÖ‚s‘Ë6-™XÆ^Êè@ÄzDŠÜ{ÉHŒ˜%-Rj‚“¬e&û�)¢ÒC,²*=’Æ¡¿šá"qRV<JHô9#3E–§® Õd_P˜ûÞyÑ{XØÂFã½TÊå‰ÅQ‘27”õë òJqet‰4"˜|½¯bи†9‰É‚“S")s–Gb@†`È à"g@‚ $. 3À‘³bAD™£@dÖ%ê÷Ž)ßɺJ2g4ÏUâJÄDÆ#ã i’~”àFUUµw.iƘ"I‰ …ÒŠÚLH11Ǹ%1È\Ô!fÄ2qÇFî™;kwûjQíÃ4¿0ÁÙi¥tCÞ'³ïÏR “Lòi¤> ˆØJo¢õSjÁÅÆl¥Æ0yÁ4|eP.ËOíæÑÖèc7­ÂUKFX†\°ò6Ío†2œ‘ß*Uz´ G·8@èôˆÉ×f‹øº·¿K÷«D Ø‚o_ß}Ý €¾ýò)`á/ߦþ¿C}�œBœƒÎîŸÚ}Si~”'Ç÷'ŽW|Öõ›Cýˆ ÿ¬œ’ÿÇêÌÿ”Øô‡â¾¿Ïzä~ÿôæ&ÛÑ›ÂÃ_öxµ|<­[¡á{ìÝõáa6MŸÊõ…~‘Žúíb…ðð å$_º¡ºœ Ïl� ƒøúªæ–­²°®\|—S¼¦Oü¢[Á^¦d<ŽU¥#},ô ÏWéöë°ýtJ1·1‹¾�ÍaöûB| Ri¬ùß—›§Çòi3´)ÄMiæ¡”Y°ÌÌÚµ¡×ñn"ÉÊ%á‚Ô=ñÛ›@õ\V{]â°ƒ<P«ÕéI·HöI;ÑPq|YW™êºF!×¥ñ$¼,ö7›Ï«X¤?S÷‚ˆp<´Ëë “~Çæ‡J¬½+ÙõX\Tô>:MÝÛTë\WS,3ÍZüosZíšëÈþÓ>üƒÜ?ÞÝš–Â+!æâ/ÔÁHo¬ž˜‘‡Òë†å1Lýë‘ÿ]š?r×OÇédÙèRV‹"\v¥�*ß'âÏb’­„TRIfXÒŠÒ4—7Úd¹[ Kiö}æÉN¥L«Õc­ZÞHø"øz˜n¢BºuìÆ—|Š6 pÇ^¬L• 42g>{ë¹c•çE°×v¿%'#ÌV¦ÔsH)Z‘[8’ç‰qnT”™2<Qž#›dÙNÃÇ””M+$ƒËÙMÎ o »¿³¦5œyrBp3YòJ¼j 8AôH“Ÿ]°Q$}Ù ­¤”ùµ;ŸÜ‚‘Á‡b�c<QÁeÄà2k;d5‡B:Á—L‚AòFÈŒ¥4S¤”ö…è„A2<&={Å•’•àÁ‹)0ßâ`ä,EÁ­ð>mù4–T­j©$ ¼ÖÓ×ùxpÖÜÖ)…AØ¡»£Jßåºu4ñÝ ®_Цx I#ÂÞbLõ‘l”¢~NºiØòIùl‰ë>nožoù׊ëµòÇÎV½GþÃàW»«¦ÿ•½è“?Eܾ¿AÁ¹m·7ówˆ‡¼ÙºÆ6 7#>ÇóGúÞ µ/Áý”@‚·ßô£°ºDŸ|| D{ø ç€ÿ З¿öxKnh/¿yË#ÁÞ®7÷×'¯ÞT·)°ÿ2µáŸ[Àx«©s$ÿ&3¶�� �IDATC²ÃÛïÆpZã<ÁpùÍ@·ƒUþ+÷K'=*`ÿØQs¡ •=w{|5¹ÕÝUhƒ"Ð_]Õs?Ú#¨Û¤V–™[)fû¿ ÿg|.³®]Údÿt ;ŽT³‘ì“Áih³­_\æ2¸;fÃ"å>Êñd §9½?rà  |Ú<ñâ¥:*K§ì6):Ú—ÏêwrµEû’M"ë.ë¼ ‘M°sŽVõc³í7µÿzâÅn>«£¼¹‰¿t¯Œß€ ‹kµjÖË"qÕ…tØg÷\Dâûj2òÀä£ÇBè´mhç3:U©ìž:u]zß;{Ñà7¬9©¸·ÅÌæ%ø“bõ¸êN–ZÍ“ßMsOwEBu}Q¦“à‹[óAj¢]µ/f½ VÞé!…ìmÂÍP³F?,.»3-˜W•õ›ýþeß(ºÒµ™cÃÙP—ÜCú»<Ò¡á³iJ³É’¢´2 Oõìoô[Œgë¦jéydÐlhM×궨j]r–ÊÑ/’gƒó)€¹\:œdd»j®´©J(Ø9Îv<ØýÌíLβ¤˜Ê,ã”sä‰w<eá*ɼ`…ŠJ$ò>¤ì¥–57)Ú<åd3WŒw ]/…Bgn4›E*’מî¬ò!¤¢T¤¢›(F‹Î^¼ê]Øß û­µ!‹jј:è<2ÊDLF I\Hp–9‘„‡ 0&)ÉÄ‘$rÅx29ÃõˆHÙ0KT¬ š2�ƒˆ ŒXä’sž„“M›–e¬ 2‘‚õyæiW¨Ý‘HQÃET¶MÛJéV­æÜ„~fÜ6ÍÔ”Rõ8´‚”™Û•t‚Í¥óv›âáj,§,ÌURrH‡XŽ{_Lá=_i½‘^7V~ø˜Š¥UUøù< 4wYü/Uéë7¼V«^°ß.¬*v×éòvïq‹óõÖ¯#¤ÀËù­D†‹WR$~§ÒŒ¯ñ§Ç6¾Ð÷€�<¿?Ç»ô-Ð਀Ïáïä/ßqcí5¸µ�¿ßC={#=è‡Í½Ã]ów8›w¨o|zõ_¿6ü—’ „bqøûÇÖŸùùÀ<è»#šBœ÷@ñž"â$ùÐß®¶f‹ëyyg€¯�2×§ãtްµînë_ذùjÜ tú¡½YâS=7HíaÖlæK1év»G‘~'2u.5ÌŒÍd™ñyrÇÊó]¸ô‡¿JÓâò%О-_<8îÝö}&–î7Ùý‚åµÏ)²)±!ÊFáhšxÉÝ Vï"û<ópÆ"\š³5\À?™§ÂçxàŽ‘æìËii>|`ÄR:¹ ȸ ñ¹°Þób)»…4,ö0S†Ê7‹Ø(¿k(ôOûé¡é&Ÿ”W/óòÒ2š¦¿âb‘7]Y£åýÁ…)ÝîJõR?q­/…Ï Â†A,³/6i¨ìÕ€;þ›,wľžç»ÖœæVRþÂÀGþKŰÖÿ Õ•Át·u)’VdYf“Í‘±«žU%N¨£ yp–'ÇÔèŽôõh^üöøi±?+‹k ­Ü¦]6¬3hy–B .œ"sº%xŸ×&KÉ7"U@%ùÈÔB ±ªBQ!G’bw»©Ïv”dD!“WœŒË5§IäCö)ycÝH^"Pb!+#ÁùƒËÑêV”Wº«å±)H+*hÈŒ¸ËÁÇsfÜ$è$ D™‚#Ä[¿<VRÍóè^^ÚËÃ<…¨²2Jwµ1&Ç\¢Ä‚JYjÉ%²‚»_«ôH,!Â;æç\€d’ )(³Ü“KÑ]a² Â%de²ƒ–kK¬ žˆ%Ÿ‹�1–RšJw0ʹ<š]ºË|Ö²nŒê À9øB©R+™õÕÌàÀÕL†…Õ$çe>hpw¨è°Rq÷@óEî;Ò£úBröﲸËá"…¿¼ÉO«6׫’ë kòÜ1›ÕÏ'Ÿ›òÒ?¹óû:ª‡L¨¼¹JÍ vURÍn³:¿Ùúà9`z`Í}ÍÏü!û•ÍÕ$£šá� t¯ö->?Œ@ȯ9ì¾IUZ£ƒo4þ_½ÑÑ›o¿ÿzJø7¢¹·?2ûáŸì ¸ÿtñ_¹6ü1´øý°þ–bQ½Å»Ý¼{ùÛ þ=û`áßfî”@°·€Z¡þ7ê¸ bw{’ð¾¿cOî¦õÅWÿ謮qÝ£îô9²Ç=>ûk+óÅ'øp®Du´°“AƒóÃI™x7äÜüî¬âEø»Î‹÷´<œ]‰'6®ˆ~,~åf,j­<w_±÷¯wú𢖷róŒtí<-0ˆ‡K¾úI5û™&kÅÞ;¥§B?ßóožìø‚öñ—_Ð7«åæ8ï›ís®Î Î0Þ󒟧 Ÿ÷r™Í²ÉVø*Ò^~ •»5ËÊÝä—ç2×íÃ]nÜú¡ü¢•…i¿âz5Ôä'+t+ ª»Xž H‡QŠ"e5»„ÁF+w¬\<žw«´zhŸõ®¥}•6Èzª|ŸŽ„<{_3+×{Jðsü?yìßK¦ð ÔZ7…ØX^;^:%C*¯ÜáÿãŸzÊE· )º8{m UlºŽ=¬ù°ÄpóÅAýÉ^´z¡ ]´ËB×ÂðÀ¨^%cd–1&FÆ¥È5b#x+h‰X”à9Ë Ë+PƒÊ"q›‰ø|çYê–EY ÞhzŒB&ᣠyî8J•…”J"ÅrôƒÁsÏ4«ëÝ’?Z b<K¢"‡ÃìU œJÖÔP‚ ÁR΄I8ó×LiçÒûJ W‘ gTêʺ©—"0`âÙ3¦  ‘)†”#—<ÞÓ8Z ðB(p ®)R˜å<—þž§YqΪÂq¥¸w\r’à2sN*ed=Dö”AYÓèû)ÝEÿ|¢CÈ Ã–ÍJÞº(š²ÑGl¦‘ظ˜ C•*_?£ö§y ,dÔ›Kgä”WAˆ!ÕV÷Q‹÷LÚ:L”/dÒú€9,B©l$*DªxPƒè ­tåUêS|ò¢T½/Ü0VÓóOLߥa=ªP.¶Å B×x¨ÙˆcáO¶(¶ÝvÜ]›-î”P�Š#l¿•'ú}xõ»×BÑ›À¸v@^V þ»‹?®·¾WÐ÷g$€W9Ðï %zç,r(á¿öÜðÇHÐùÇU¿ûÒâ¾6|oo÷Íj¤SÔç¯&A÷Ö¯û]’N8{m-|i¡r_ªë¶«êQË?}<Uïœvÿ9´ üí¡õX�@ŒÀÙ¯ .àûºö¥»Ií1oÿ¶òöôë÷åóe9_î6yÅ{#ýûKÏw¾-­³'ÅQ;t܃ÅC*ö ±t?áá¿à®KÒÃÆ‹â½:%%YCÞ–ÜŽÜØæqŒzZ4í'6,õ[ú­É[±Q·Çp`E¹?€§™A…J츸š§2ÍCòK;¥(–a«ýo9]ýŸÕ©O±¬¾òþr‰záëâ3½Š[…'&5+¥…sų ÖGôwKc|Ù@¯Æ•û~W”Ó1×jJ6ŠTŒUyX¦ë‰}Л6ô4¢‘buS'(¾íØÂ§'ã¾Ír)Ûc³^º&Åüç.ÞJ”|¥©Û„jä2z?Ͻ¥Ý4ü'“±àÚ)ÌÕ^´‹uŽÈÀE4Ýñuûo ¦‹ì À´ö’%ƒ@v cIÆyÞq—3:Q©•R)%§B`!ŸX§ÅX!ƒ !¸i²“ÎÉhÏdÌP,±JI²‚%.R‘´ÙX UdmD¶Ògš“ô$¦ÀGJ­ ®+×üŠyÆ"g‰.¥G‚L©„мà !GŠ.r£“Ê ÁE«Š©‰G”RtÒt¼a¾Ñbf9Qäv޳‹D<Œ'P$ D9éÀƒ„RŠŒ…"祋£ªLJðD˜cL°–© ¥*ÀrÎÍ"%Bò™[/„Ã<Š9„QCfAl¸ìL.%/M[ÖIÒMû©™öí´õ¹8nW][9낳iœ²Zhõ²Š)÷ÏŸ\LV8žTë“ðùÈ-ËÇ–-—¢ê.Dï|³mä!ãQjKÍ%Ÿ9.‡Ò­}uÇù¯'ª/?<ÁûkÖ¾×un¥»¼ùí Тê!¾¤ äQL_ÃWî›e•-P¢šñÞw©ÅÂÃÝÞЀ_o †ÿf§{AÞ½CÖ ^K ¶žÂÐ��.ÞÕÑÿð…öŠGjw¯½ôƒíxmpñï´‹ýÿÆêœ~+E¯-ïÞÛ}+-dôo½Û»­ó÷’Ûgüí‹|±+Ž^4O¿0ëØâ§Z?kZv$ÉÖŸâg/Wøó;½•~×¢K(öøì·(=òርè®Ë)Îôâ·ÕK¸i¡SwÚnÏ}ö;Bì¯kÝîùyì}œÁ÷{ëÈpfK¿¬ŽäâÓ¦;6ò`Ò—s5ÍE+Õ1Ó¶ð¨žUŠjõ÷!í6¬íÚcG‰–£uÞ"\ѪÝväÅcsÖj0§gø~i“vÇ›žúnêîVØó¬_ìÄ‹LœŸ0sz?}tÓGÿûPù¥ä>`í jEgIÉœŒWU>JÍू” jöP}hüðƒYº‘¸M¡îÁþó+Z6ÈÛrøÏŒÆUÞî+ðŒ‰Ç!ç|´Z9Q$§ú!/帹!é2P‚Ÿ+xô̺]ØõPU-ê¸ñA©¯6¦ ®Õ~]ÍN¦”s¡›ÇÇŠÑÐÀ-ªPJÀH&äc}¤”Ï™rÁ kaZJ‹œåL|˜Ìat6F7ïÂX$¸»0®ÏÄE^pŠÚ‚cŒ‹ÂTBx‘™\ ’‰q 4˜ÈLRh)Ï$¬ˆQ%žS¡¹Q|$º›óÈ‚fåIä!‘ÐT�Æ0eˆ#XGÒecRV"3ŽÈ(úi¶<¤N(m%¤ Ž+›“ö1LäY˜ä¤BÎq¶$‚q™)²à¢ç<qI¥>¥>¦ÌxǕД³RÕDɸôðÜ1®XÉŒ J¡¢œY¶)E›‡™‚·ÞOU˜-”*¤Ô&±ª”M]˜:Ûl3w\ضšFÃHTiQʲŒIjlW,©#nd{ÉÅVTŸëzÕö4%>pë)^ñ‹Ñ߫԰²µÍ~8àñ_«ê:7 Uå$Ø~—ë"—ROõËu5”ÔZÕÙ£ÈãqôMî·ù%¾À”ï¯OÞÐÐå—Ÿ¯šË0>Úú2B”Ã0ô(kØ|Ö §Ày'ü‘Á]Ñ#ØÜ+—ôL¿ÞYúç3ütïE¸ó˜À¼5%|/Òõ{òÀt?¨×)qÛw´ãú£÷§+œo?ø×§Eÿ#Œþ‡*“–ð7pïø3¼xçFì5vÖî.f†þt¨uPÇÜ0ªÔ‰¨>ã­~°: ~ëÔVe¨5Vá2j‡£Âµ×ë“O뤸pÀñ1Bë¥:ÿRVq[ëíV¬À7 ´i ~¾Aqó±³÷íüþRoM{A«‹eûLi¯´Ñä°™ÙøÎŒ½²³»ywdy!xcb¨Ãh7ªtq`»ë n.{ Cûi„Ùªr~ؼè$ ›±hûó©ó¥ü?\õq!~Ê¿–íeŠ¥ÌÇÅe3d<âÑÌûê@£ÐwêÓçu['ÇáËÚÿÆÎ»Ä¡*œ¨hƒŸ´p*ú~µd” Ü»ð;)žÀS…ãª!Q‚8QðlÞk~nö¿]•Ãèúss u¼"ñg½_ ´¶ kÎËîF²¯9qŸ>eÅ#Ÿ¡Sv|P±²LMånœ^è A·DY“O¿Ñö¸‘UÕüÔM,‘ò¨ÖGU]š #[ËŒ]Ê}2S<äèæ1"0ø”ãz­ ÓH’,ŽNö$ï¬Ýí½÷¾.($Í›c ’k!„J‡äI%°UÖ2 î)å¤(‹Ì£ŠxR)Qj0׎FŸ##Ë‹¤fiÃŽA WB¹(É€‰¤—*’L`�›¬b²È2ÅàÉÅ0M»´ÝñI¨Úper€í¯ã<yR‡ÈçÔ·/b¦GÇ(ªª)U² =&dŸ(Ù.±ëòiRÑÓµ »>7Å!ê$™ãN&Eb*S̠̀*e|àÙ虃-%Q2™8'NBkY·¨’góè‡Ñße>˜¢Ìéd0†™àÅ^ aI)uc¢Ø‰Xle•U÷y.9õ㜫Ï™ÃByM¿êÄ¢¼ž/ö‡ŸÌ¾¬\2΋G•ÍÀßßMW•+æeRv5>…_)~çÝE,zTéÑc¨‹Êzm?ßÞ‡ÍÝVàßÀ±ÎÀ?x¯p�p5B¿‡4xìÏ?_a§q0È÷$OZ`ò˜_×½.Ð�‰¾õ7|s“LΈø5 ;x ô€E£¼ódò7ò�Ýo7ó¯ÁíMðôçî‡Pô!î™]µá÷³R?BÍÿ®µd ~ úà yňt?åÝý½Îk¤ék[Ólø±w*.fþIê>ÓuRágœ_ªdвþ¸ÄéÙ=¼9,¥Óêpǽ1&¦J?øÓ3ZCI<‡?èÇØ|Šq¬V/È„JY‘9²GëD<ç<œ 3ª…÷ Õg1ÅÆH_JS—pQìdrØ_ß˳iaëzž §»s7ó§gÅÞâåÚÏœ­b5î¯ÀC}¼bóG{ÎòáAýwFünz†:ý¹zPV‹ ©t 9—}„Îdö³;›R|‹#Ù<9I^ˆ²\çò.š*]ÏqA¥šý‘´¥¼mäûbà˜ÝVºsfžXLêhö9¹p‹4z?õY:틟Ms!€¨gÏ´±«é¸`ë뫚êú¥¬ôd{7]ÌBÆc®Þó|Y«“®-“•–íóTˆ_Цoóßu´Äi!ÎcT<_—úé”ëçà)¤¥žuQ€µNêA亘¬U™’6>Ög•X5SòÚD#“î6Í}ßÛÝ–ìÎcÜ vÐßQ^Ñ^¤ªâ‰ËNBzÖd’ñ�ÚLñäbÖ’ Æk!Å«h Td!eGH:!ÄãN"±‰eSð,´æ€"–ØÈ8åd8à­HB@dä¤(V iL!ºˆÞÑ8íagå¥Ó<’÷9íœg#ÊÀráûÑÔŽR.Ã1§JpÊI RÁÙú]Ü{q%Ì]Ê4…›+W þ<‰\@D£* AŽ¥½IHÉá"w,„è0…0‰ÕD2RN¤dÅá«J•í‚•ÕAº9„Þâ`mÌìDòeÁ%p>•±P*9å®q銉X;Ù“ªfs~ØÖÎ!nZ½WåvÑ®ª¡ä«–Ê2~ æõ‰¶¨GÁ'FS¸q´­ó†‰ª¢m3‹$B*Ó¥x©+%þ2wWøÎv‹þžLžPú©}ånó3pÌÀ×ß#Ÿ_)v^pçîÏüN¯Fâ{ýû�<z…ôþ]–7Ï{Wßq2Y¿Zzz%·úwµ´ºÇi|›ß1™M¿GÓîÿUî°þ~ßþQêÍøŠ•úÃ!}üÍCCÛ¿>ß>ÿõê§ï½¿zbŠz4­³x,UgÔËZØ($›LÄd%ª¤$D±vU!„.~s6VØýْܽeÙq%¶¶ïñŒwŠÈŒªP¨"²‰f‹”Ì(3µÉôßzÐSËZf´6‘»Yj�*猈;i®‡œkBd·H·¼qvÜ›'"–»/÷µxXð¢yxýàÒmŒnn'?_¶éjIhZ½zá7³Ni§ågçý¼ŽÂÝxèî Öäo«ébY¶~vùZ]ßÊñŽ4Où¦ÂQÒ¹LæÚ<]×3zàå'çÍÕ-ö{ ûñü+#/骄þþ…1wªÍŦÄ¥IªuÞš¡Šùy2OäÝ!š¶8ù|ñšö¸^×sÜ6ÞŒõ¯J yúÏõÜ™ð±vH.ë¶L'#Œœ*IÊéóç!îŽ.'•ûü›Š×^˜”ÓcœŽå2ít­êÂÏårSšÜZ]B™Û ñÜÛMU/•ÛL§†ò$„Ï÷ózCS¯ï4ë;«n‡J¤´NÛ¸J6r[Ë_wxÔBBÏAü÷»m!UYö²^PÙNÔZ§dr¨hƒQÑ,¬cU xÁƒ˜‚ŒH'-SN2éEÐT:åÛýét4eÈ„¢ˆ ’`^ël…vš…P”V:Ñ(V(29å¥ ]Å9³!2,䦔*²!E…¡ Ú*ÛJ¸TyIÅhÓ˜®UZkW Á)Ñ,±Øàiôœó2êh‰g/K,R8-™§©”\B.I$mƒ©¼‚¤"#VÁórœy„²)Š0Ëce ÁªBK+ŒTE)¦ý4ßdšŒºÇ˜NóË1>]2©pÏku¬B,ÁJk‰Y@sŒu†•²b¤$ŠÇ<•1P¨);¥lŒ’»Šjër×ë¾w¬ÌÙ//¦äoYž¥w‹©#»JKÃŽóä3ù£ô‘‹’Ô¤pbo‹Z²_…ôòEi+!kúz–½Ñ¿›S(õª½>v^w÷²­=rœòúæ&ßèÛçTÎ2’už‹¬%óú4oÓŒ‡I¬×ÏmÆôߨÆÎ_¼Ú™³à p"@�+ Âæ„ó æíÒóJ-Ò5 � Œoäß!? Á•ܸpxO·œ¿ý>¨~x¦'X<J6ÀÿdJÿæ{|6þxt7?A¢÷Oâ ~O‰àÞ›0{o”)¤oõ-BÀ #ó›zpÖÆÃjìÖWIçC=<ËâÀ¦'3òœÃ7qœÚ°EÉrÒmYR¸òþqÙj×½yØ õ—sŽ÷QÖñì’XŽ·Cß…y°–½>cžŸýÓ€«/ßûÜú󳟙ÚÝ­zýlYÕCv½,rµïªØTõ±2XÅŸ/œ2(]vJÜ3Üþ¢¿]WWZì^4zàêgýŸêóZN}]­ôX¼,zÇ ->¤¥nT6júK‡Ó¶¯V»—u×߇î!Ñ]û_Rykl¸ÑrNYŠ»›ƒ6²B¬ŒRkœÿ·®®çù>_lÒ¯ÛÐy’NÞQ‚Ja}tóӕܳ½Göãg"inêrÓÉŠY$7L|@ÿ´Ä¦ÞX¶~l©ÞõaÛÉ;ÍåFwœ³È´?ñ<‡Æ‹xXUÿ]!KªWòBó™]U d’ÊYóYå™ùbé´x̳婖]¥Cœc‘—\T©Áq“Xb>†i^‚O‘±Ñ)×1[ ˜T„š}*L6ÈF÷®5¶B…HJDB'¡R‹_ÆCr–+!ô’QЪY8RûFÍÎZg¤R,!™)”0NK©L9æ˜æ¤Ó)•ųuëÏ>‘C1B H#-EVBˆ.³BäsÎQq#àbĤ\Ö:Eè¬rXD‰E„¢sœ¨“rx5ÃL©1.ÑâÖ’&´§T)‡µ‘:ærZ¢K¡W¶Ê@r N…’“"m3‰ÚÆÚ˜Uå`+­Œ*(”“œ£™”TŸÚÖF)8ù’•¦6aL>‡NÍÝdbDý¼ß#+ò/‹º­Ìãmù‹ ÷ÎS7쿺_äΜ)/¢•«auߨ÷<‡ñàNõ;-õò,¦®;î'Õ­}Ô/ÓE:\‹ ÌÐ@SáœßÂî H¯¸þd¹v Òùß☠ÐCšÃûnÙ¯ów ´7ÓïÇ¥oW>‡Ÿ4ÚsýêýO‚ËüÿÏ=ºÍwzÅÿ¼”Ñxù(ÖáÕ~žã9ô‡?† TÀü:\}Ø·Øûr3zž†õ©yÃíƒã“.|£šÅI·ÿæHwö ¾ü,þú²ìº%)t›NâãÅ_Ä;nݹ]{9·iÚW÷´„½}:ŒX=:qâ '¡ëëÝÞ=GOm³ú|–7Oš'ÿÖ˜›û­ÌÊ|lºr1vWŠÝ._¯’¥y4¹Êò^ãçé07/Q_©ßÙi¿þ1›¾irÚç<×Ï÷W¤bÓß¹l…%1çr(].ޝ>êþD.Š&©?ß­d¿:®×Øtå³[¥ÆdÍMü*L{CÉ|¤SO¾h uΈS‘Ît¢4{ö<ÿÍmüUÒrŒ·íørÍܳLùxÿ¡”ƒQµ—}]I=»ÐKókIvVLwf)¯4©ËаÏñ·+³­.Wíê²mMWéL,¢–‰ê)g!Wr³éÿ—ZÿÒç<{_èNä5éÊ`ÄLŽS Ù«´EfK"Œaº9ºaeGÍkKÖk%sàLifµ/9ç–¥Ì~™r©²¶)·’*‘eUNažK8¢Þ¶ê²¡MUê�±”ÈœAÒj!„ !sF\æó<nlŒ¬¢W¡8.n %¡Ø\šÂ>/Ȉ‘EöbÊtÊKÎ*x[Rq4'=ŸãŽ7Iº„j›L/ÈY)jèF¡Ú$ $ù$9ggà+"I¥ÔжHYHñB%Š4ú˜&äY™ì:)—(@IrUV%ÍGÊ¼šº¨µ:)–$j¡Mv 4K˜Ÿ‹feÔ+„etÅë% $È(«!‰Œ‚¥B%•\@IÑÉF‘κ©•˜ò4sðEˆ$¼ŸÃ<ÏçÅŒA”YóÒكʇâiXªÿ[ß­œR†·õ¤òo®Ž-¶Ú_^Î’{/x9C>ÃWU™ÌÅ¿±Ò[9qêO§T$×1¬Úz¥6‹Z «LǃÃßÀ®üïoÿð_cø›uÐ8Ýäý.F€�¤òž}ª® RÀc\�õù¾ƒ÷«®€  ·ë9?¯×V/ÿµÜ%Þ¾þ¦‹þ¯dÀ÷¦ÇWê»7݇*Šøí†„IߦÓh—�� �IDAT_Ç€�®Ã  ùð¼÷X2¨¯÷½†³ŸôöOܶá&ܺ™ò'¨¶Õëþz¥©]Êoªô»"/fWòéŒSÀAÔæ0å/aTûhgaž˜«_^ØÎqï ¨Íâß ù˜ì_¨O~çb·i P¹ ÒÂݹÖ«üµšÆSj‡h†âqÃîNߦ•ħîâ?• sZòúbÒêð´þ2Ú.â¶©” ªN"úC›ô…׿.þñFÿÕIn§óå%]î¶zwɶ³}s·n·ìÂ\„ÙHÊ‘+=W‹ˆDh+‘YµƒK+Ý]¦ÝÚÞù)äÏtåb~9OhüL¾ˆ[Ec]û_ZþjšK³Ôìs.¬°³þ?¹üE4ÍÚhU 4$þ½r[Ó~\7‘j%;%KÛÐV¬?Ê?‹] Ë3ÖE›û’·ã9,Ë!‹ì3眉De‰•™G©½¢IPádçÛríæJ¨»¶·Åi’9ÄeNÅÓ·¦Ø* yÌñPžcúØV>*c,UJÙ´̬[rº­/5õB4Ù#–I¤RTJD*ƒX³Hþ¼çkŽeïꉕÚ$rC:_óItRT\Õ(5Æí•;+y’‚(ÍÙj¨Êû,¦Y¿Lù äÉ“´e £ ­ÐT*‚劅-Yé|J˵ c*æ”JI¥XvRfm¤*BæE,:JK²ª ‘®ÙŸŠ"GÏ1ݪޅ¬¦¶D. löfñ2,{E‘çDRKeLÞ‘÷Ól‚IN²%³Hs*)ð8çe#i-Ø91› |*C^NÓËó°âìëX–¸c½‘—ìJ‘)š¯o€6ÏX®íéK‘'wúeó@Ia«Ó­ÿÊ¥—7Ò«óÿj›;¯ö¥ßu•Ýep9iÑ-©ÃbÃôxÏV–²Aó)òãh0áñw$`¯ªF˜žÞ¢Çw ë l�ÿZUúB. Ö_5¥_ ³úwÑEB¬"ìq~ó¯_atyߣõGF:º\ì{°ø_TløocÀpP·ïr„odžoÇ* Ün^õiöïZŠ`6h‡<ȇû°_°¿³@积pÍÝUnŸ! 8õ_Ûp%«?q±Õ’wÕxjÍ97ú:ʼnp ›é8ãx{¥A7Lú?|³­6Ô¬ë¾iqW+¹ØQtOõê‹J»íµ¼4‘ŽI•Ô9<oÏ_qÊ_~R¾N)UóålÚZõ‹nÙ6ÙÄ|5ã>ªétžT^rüò®™¼ ØG­“ºŠ¹EHˆl1U²íD›_Ín‹xï#ÕþÜŠŸý¬T—UÖ«Öv®ÓU›LÖ¨ÙnVᜳ¦‰o¦yŸÏÇ¡Ž¹»YÔ*¯\úT yC€uÙ¶ËÌiÒúf‘áÔ’šDû—MwÇ¥û|&«÷ Æ$Œá*+=Ç͉,Û)vyËQÏáÔU¿º»ÚôÛ%­@kÅf³­•0å.Ò8ùîèÃ9Äó4í÷Çç㬠U•ê¶µªš-QÏ™ã1–}²'Ž’–öiç3­ÆÞȨô’¤Ï8ð´2”¨ê´åbªz:feÂbXhÑå$ikL„Õ²Yà¥#­{¥[Yj)HY6F°Ñ‰!ˆ‹^<Q˜s+4’DV§—”\õ‘Œ§1r™ÔÜf¸B-Õ‚GV“ÐnW²Zï±!Ê:2;a-õŽ×Z4Z‹ÌYŽgt0éy]¬Ê!ò>‰lÈHíàûœŠWi™] 9'¥Iu–¸(ëÇ&„9!{’W p5#û<”¼ÌZAEU©U’Å{È@¶ÖÒ:¥`cQ(ÒZQ+T—„“y yÊÃ)‚ÑT²ÕJ¹aJyaD g{Œ·G¥Lâ ¯çjµq‰;#³Tþ3º­ÔáÄM'~]~u¸8bqÿ— Þ D§iž~ѹҴÿ>Çi8Ç¢¾fÛuÂW×bõÜ.4ïYú3¥ç„;N®hmú¥º>ú§ù;¨j<¼G/û×’ä»i¢÷hõ-³$ƒëùr�Ẽï~�ª!ÞÎÙ@@t#Îïv‘½+A: –oÚÿÀeÔ’ï{±ÿÂzÑ€)Þ?ɱcÆëÅÙßb ñ-­Ê»À@À` èzø¨åÅdïH²3|¿ûýØO¯hÉ'üë=6ù†ZŒÏð»¼\vÑÚÌ}e¬¸—箄x81ïc?Ïíÿ¸‰m^.öu…¨¿L¡~i×kK-úûi+S)ºOݦjöšJùæ6²´v¡æ$õj›ò–LODû ÏŒ‹6ªTŽ~\Òxôeɲ—«Ê¯û•)wÓjXäÁ©Û]KDWÅØ\µ"Ÿ8E±;ÐZšÝ'UõÙ¶y¸Ê—ÉÖÕ"{’5, ®V­j’r±7*|í§CJO‹¼©ùdÄÏU•Ò':˜Š¤¬ž&ËKš±^¨ë©T•/ R@ S*qÉ·T{Sî´¨Ò܇|wcôN™¥)µ¨ÝÅÏ/®šËV·d;ê/+{¹mšÞ¢d,RUƒNþtæÇávI“vDYs„ÌTot“9N\Ž!=ÅSÏg?K¡ S·œÄLr¹í+.ªÂq«Æg£…"Æ.Š’*„6‘Ö­q´QšÈªd²I['« TÖ¤”2®VNRñéTl²˜”àçˆBz©š°‰'ж-ìš©T>Æ™–¼Â$Ø.I è™dò2jÖËl"ST®×ú¢²»†¦C5‹öEšó’¦¬Œ&å„ÖP-ÀYB.ÙûÀe]3 û…è@Ô°¨'_F£hÊÝ)g1åÀªsPR•LÞKšGC™3JHð‹1‹ˆ:‹1г"ç*¶œ{ÎÈRwÊÉd£q^ –RTÊÚj`1‘PNÕ+­§¤‹QL‚F+–™cJù±@Râi|# WkJZÓÌ»j’†³_Í1–’È: sv-nE_­Í^ݹŸN ¼fV´™Î A¾tý•Eч®ó”*ñ´uÍE¡ª/½Øã|Áûçˈ“­6›veS©ŽM~<48ÿOØÿ„÷¥²á.i~'«2¡웵kùó´ƒòv‚È�áÕÏ‚~e’$q?ÌDã#\‡Àp lZà·ß“ø+ çT ¿² ç±%”~Tpü¯bN類z À,üÑ2%¿zXáÕÃj[Àœ€S÷îwø Rr{EÞŠ¯p«óéÒ[[} îqç„È8~¶øJÀ‚ýOþ®óäì<þÕEÜ]&ÜòÙµœÓ:}õPaZGÇ|èãm âÞŸ'nÂq±g½jƒê(SÜ=¹¾Ãår^²¾ìK?d!Nüü#ôœZ÷Yàçã¼9Èã¾Ûáô0t9×a-¼°5ñ½¸0þ,Õž¬å(_u›Ó6ž*/+/&!£éF!MnzŸîuñb5¯WÔV ’yA:-~À¹ÎI"‡E›– Œ°•¦"¢,ÇåÖ+yݸšR\âÊîŽjW%òt»¾æ{ ËN]…ƒ©fŸ¾N2æ6åæ^+û.ÈdÉ R³Ö&ÕYÝ+§ÝjµÞõëÚ¬¹Ýéõ…ml¯aÀã!ž“˜ýi8mÓt"éW«Jôµ-y[_™ºM*%?žsœlŠ\ ²Yn£Sã”_p¡É¡.u`¤b›X5eU«Î¶&W:$Q“â&ˆ[S2N9m$Ò¥”Jq ’U’ª’ÖÕZ17)®")È8²W…¥”¹q©–Ÿ® ¯…‹Iò.•bÏ<¨Ø 8ÇPÎÌY‡ÌK“‚–ŠêÞPÓ'5ëE k´É¦`˜Kî’WɨB*‘ƒD†àY„Ùç$ˆ@¤&èIdIÌSÎcõ(¼±‚EDZÏÙ&K‚CáTPRâÓÆ@rÎϵÁì×…JÆ/朥6Ù°Ô,¤€¨!¢ç3|2`«•žcQ,•ÐB¥l}à%kÒ©–h%÷LΦS‚7âXÕ-ËdiEi»~¡åí鸌7+ÉG›N®ºsÞÞ¹mü]Ã9ß'lø¼“k_šÚ7®ç{ÉÛç¤ë%zªç}‘¿lõé\ù£b9E?WᎺ•áæîîú¢?¢¢Iaíp]ƒþ3û·±Aáôn³|ÈùÑ¡  ±ÑØŸ�LßV¼œwMM6僵¯Z°{óoà \^ J‘¦÷^—ïi¿Uaüèõv‡©úQC¦-3¬¿/0T@mpÞÿÿwß|å±q?Ŷ£ÝÀ^BI_`‰âûŸä 䇬8¨­c.Ó¸� €Ÿ\á℈z¯$¸† Ø1ž}uƒÛ'/Ê_"¨|{Û§ƒè&È@ÂÔE×É>ýwös&¼T)•þ˜MÁóGâ‹E|<ÇÏÊIÏ¡Š“Æ;?@Ü_Fº$0äI ø´¢Ü¿˜G›s=ïßÖ÷–MÚ5y+†%:©îkn\Ã'·xçÂDö] ÷üi7Ùv\¦M;nDÕ¬·àuÉ&½¬Ä…Êë+À ! G1¿hŒ$ššØ8›TÉŠ ¥Í…ö«’Á#Åi«– úãEnï^®Z•CߕƦ*ËzÕ Ce:¥Ùˆm§¤nEµ½#V%iDíL³Ë*³h«5¹UÝtM³2nK­ÒR Ì~ ··ÃÙË} d¬ëB%z%/{SÚJ:ÛŠª*ù4‡./‹ÀÇN¾È"±TÙ–Åù1P/UŸRò£¯…§¨»X7ª±ÅÆŒœ“‚ ”µ$t–c§|®xE©Ö•VVk!# "{“SŒ8QšŠçMF–Âjñ‰1©Šª(t¨Œ ÐœÒã0DÅ“ZDSŠ£¢(„NQe-¤:q¹B+'[ò´ø™…®ìNòv.iÉ1ó  £XTI’à éSž–à3MDšbQì­Xd˜=Ž{º=(ÜôŠ;‰.Û*P <"δ¤ç9+•‹®¼5Ðb‰q¥…¢8å’*‚4 a½¨³ä½fŸ–¥·Ö¬%tÃBQ0Âs1>”³Gà‘´–]ïT/1gEEG¥G©‹¥EÈTŸNÕ4ñÏɵ²º'iÑcÑzì)îèO†»»QŸË——×rÙ‰óúHB©¢×XD§Ó°¯ï‘ê µ~ÊØlÃj{­BÒsgõ±Ë‡âïVQî7Í6á2¬bUßVOlâzs{œ rÀµÁñ©9¿Å!½Î?1¯Å_¿gL4=@�ðøäøZ‰eP=Äü"¼Ö/¼‡é7o±¸¼^hÿN•ö>‰”¿•ξ%T>y£÷úýµÂO4èû×âÑýûå0Ü÷ Âþm§¨~Ç2­Þfï&h_?eQC[Ĉ¯üw­:?AÙ/S#sb›èAqh˜ ë5v‡iŸ2æéµþZnD·aYÿýSà©Bï°Ù¡&䉭Ìê³Ô÷¥úE眷9ÇþHþźŠe¼ÀysŽó1½Œæ(ìÓàžo/hø3Vµˆæ'Ëmž]o]êF×B'3ªòˬ’+·Í²ÈÅœÍàšÜM©§³n½µ2•»9ujédp¤$*ãšÞò•DŽ0³ÒÚdaRáàOãt=$«È¨Z³aËÒ1¥X.uÒŠ ´²½Hlæ ¦zÝT´³Ú˜¼!{e«ª]Ó ³jó S¶É˜äˆŽ2Gkí…[¯êUÕµ¢!VÊ’éM]Kë’°,•ÓJ9( é Fé`!ä_ ±#å¶l·ªê*£j+¨E)™Ä|^BN3GˆYd®’Z‹¡*öJW åµY8rŠ<¥zC ¹.“}~1”DÑ‹2EKK’U›’Ö³˜öFXc+g“HäsSæq¦ó´„rñ,Pd‘u)‰T¬7d­“ÖQ2R.–Nì<ž–Æ)‰³+DX'Ñq“\-™>?4,¶Ä4-E í¨îÅ<añ^WN! 0 !‰²TÂØ’b#²�Ë‚(‘'æ4Ï¥œRϪ9 ­œ@#µò1‡ ±.*KW­ˆIžE\w]YµÙ-XÉ`Lvyª¥µÆ$V&³˜ŠtTJ:!Wsr5õà"”*V‘(œfYX) ÉÒɘ)™È9”Ìœ¸,ŠŒÕÂ+ªB°§‰g šQ¢Ôr♌JVq·ªv$ëIÄq_ÅS«öõ¨õLžü`¯£Ðeˆ?/3hü³ì¥m-¶B±Ö£$¶·pG(’ 'YpÊ!Ñ2­aõGU­#¾¦Oo.ï@÷î|‘—Íu^!>Û”ý”àG@¾· Ã~2, €áÕ’†K`^`ñÀk‰®~„9 ¿…õ 0¢ HùMÖÏ@yíq¯±\¦¿"Tö@<�ÿ>!°ú°¼ˆÿ¿ˆ ¿ïškÌpÇæÃ¦ÍôŽžÒoeåã·i+¶è"~w~-L hÍxs‹Ÿ B:åQÜбÆþ.ôçèÞxóœ$ê>\Å/ª¾"à lWK*P_O¹y‡¹`̘Ï(/·õñRï&Jô³¤Ëâ¦sMÿ7LŸF=Ã5S%=¦:~½>ß:÷2 ÿòøõͰ>¯V­š+õü<!]›U¹p«GÛöíª£=ÍZ/Ù»4¨9åçèV×Ö¾Ý1˵Р…‰ÇZ ù0›{6R—Ff;ŽNe·K¶I"/i?ÍÏòþ´³êªÒF©Žr“R!¹Ô4¹šDQÔtJ©ƒf»ÑÁVÜ4KQ«‹n ß²2¥Ñ‹v}1]A/êF°HrÉ{”uk›;ÕªnW¢rp$;Ó)U#2 RÃVPžÁŒºkºÝËišƒUêÖöâáv³[“hÙG¤ÌùÓÂm²žkiIžC^‘gMç^˜uã×–‹Úr]g?˜›Sz>ýSZ멪I]¡Z))ÉX%4©‘ͬ›”°ÐUQ­ªˆ´çy™Îi¼^< cå d´2IifeIb&.Sšr,¼Ðú$ôJ gA‰XéF¹®’´Nã‚xгÙjݲ!äzž'ŸƒÏƒkTã’ËFnÚ¬»DÖI&ÒDFå$åÌÊ¢I9@&IA¦R%âX A±¶k'ëœDô‘K>ò¢ " –*QNÔTZ±½­†ºæZ"Œ¬2A”c¨ßÈRi!áKœ'“4ƒ+#•$ )V2†v eåР8“¥³’¢NYäq2q™’œcT¸E0‹ŠëJE¥¬ÍªÈ˵ c•ü‘'®š"(vžäQ様•º—õcŸ¿±§%ÄK•ôm=¹ºˆ¿u&”jpùzÎtòS?½œ³ jÛúÊ„Õ<'åGú…œ‘¿°|Ùÿ9¤œ¹x*œ‰úaa²ªÚœö»Ì[sŒaP@�¶ÀækøíÞùM~9Jl;”3ê¼?âÑ;‰î9¼N4-àßÐ!wý›\•^Wü¾*m€pþ¶‘ô[Be€} ð ÆÒ‚©ÿcÃOn)k üA3Xß1™€êé©á]ÈÝ›¶ÚãúýA®x-~Í—{¨x±`ºÆ©<XFLÓëe{kdg.(\+ƒ±‚}º·E|„ù�€çŒfÿéñúÒ­.;½©Îk)Û•>wÃ-f“b½$N$cå~CáoíÕͦGÏxÜü—½1Ë>Þµgôݽwí9ì¹úÇ$^ßp¯SPY³u¿=¶“oØlZH)“ÐB1™Ñ/ý®Ò»b†ÊÌÙ‹*äFÇ%ù°÷/Æyl¤íe£‹Ò’¥¨’8¼ÑÒP- T¥J«šœ*m7٩̨n]e„¹‹²“ÖdB£FR±[!/•®‰s®áœÔmUuU_¬-,å,ÈÂ(B‘òµý¤-••#ßH¤Aÿ`uñÑåj{!ÙÎ';g£_ž#d+$™lªòÒúYÇYŤÎm{[és]j.W°"`´yv1×Ú*÷XZ [)QKÙê¬D TŠÂ([é¶-­e—ƒŒ!-áÚç1.2”&’›”B0:““ Y͵À´äñào}ˆÉùÔÛõv ZéJÈÚØÝÆš! §oއyXt%l¦]µH)çqÁ|&=Ϲ%kX"­¥0Fʦêµ)‡‚£âQ‡B:¹©RÂ%N‹`ÍSkm©*ˆ"a™9ócä¹@ê8È$J$Á٨⤮¥Ôlc\<©˜1‰e›ÀEšœ-ÍóT…““ZWmc\¥”4‰!A‘k%˜õìd.Zh90©ˆ,Ô)ù(çY@ 6œØÐAU'KÉU‹i­Ð&‡ÞžÆ0ÄpVÅ^N‰'Ó;ýI“æ9»C¥ö’ŠI?W¹¹PãtÿV¨¥7»ÚÒ•TñõõuhF™_œdÚ7M[›ùAµÕlÿîI¾YôCä{7?ÏNL2c9‰Ø#ßÅŽƒ$–¦”½ãXä£!‡W27€ö�Nؼ=}šQ`€Ìñ}ž'¿'¸5À+§Ã{+zÜwpýüÁ ”ÿABåë÷Yñ–ëŠ üë[/Š:~ê©ø}ï%~äÅ�<{÷ýìÃõúþ¬Þ+ÁÞ}¶÷ÝØ­FnÏËÑû ùqÛ½CLீùìQðl~à ¾ŠÌσY òÆ h‰aY#=D:ß‹¼ÔaÒ¸´Øuš–ùöb¹{ïØý5©ë„qS chãóz<Åt;‘›íß.|x¬>ùEUóIwÑòwœ¯ ëÕ_ߩۋð3ÞG Çê×#65b«Yûf¤Bz¾?úÀ© ±Ú&40ªÓ¥ã¶é«µê• Náf,š%1ºË~žF~ù"Ÿ²¹(¶¶º NIJ,’@)Âé”±J>J•±2•éµV(ä9!(¡¤ (Q Öw‹–’·Z¬µP@µ¢X ކ…&V%çT,£¯AúÎt¶a®w¡S'Y¡¿º4Û±½€eŽ¥P%õÚ$4†MÈtFÜ—©øP+«NîŒ(|ZJZJm‹²¬U¶¬-Ûš ‡(¶$:]”Öq©Tˆ²WŒMñiZ–é˜ §‚à%ÏP\¥ÜP.¥ i‘�ÃfŸ–ižÇiKwŒuͳµÈ2h*Îɦï›õÁP×j_º‘‹)“È’œ4ÊRòˆ¼œJI¬¬ U.Ì 9qÊBjéŒÔI™¥FÁ9He´Ò‰SЧÏ*gH;³ÉS,Òg Oi–Ù –è3 PP"ê2SF™R)Ä#é¬9[9yïiB¹J*i»” [§¾„‚v9+ï³*ŒÈÒJÊ„>#,9ÅÛ ‚"eX…©¤DeVòkKŠvI_ =%³Š“™fwšjs úL+á®Ô›t:?õx6åÎluÙí«ÉDûy9¡{úQÌNd»Y€—k»X#J—Íè¸WdÄ`MÔ¿¼Z޾˜…~õ%m÷›ú+uƒí§çÓIÖä 5¯ÊׯÕÅ_æcep|³2áõ·PÞŠ×nîÁT¯w>‡oçÇÇ÷2Þ˘§ïÈ¡íkˆ:àû•ßÍ‘ùûP¾ûé®sÿ uƒøN´x ÷üáá=õÝÞfôЩo¸ž½f�7ï{Ø~Mã!ð¤ÆÞO‹ÿçBÝÛÀ ÐÕ8‡tÀà…Áµ}Ö5§W…È5ü x„áз8æ³yÈùJ(ÒX£<Þö"ÊÚµýEh7ÆæÝ°¤ô˜Î·p\€Ãdb¡k,2Öþ*/õgú·*<q ŠB&¹gâÇYa£Š±~Ôö×ÜQ%«2ððT?}üù!ŸIµ‹©Æ:ìTé?ž»t—*N¾$©tÈ5Í,Ϥ§Y\¸ºª:³iÑ/¼ˆt ²q±XÉ ©‘!ŽMÞPv–H”àSX¼ÏÌH¢­ä„¢šóº ¦¡T‘·""ʺI*ç4röÙ/|Ö¢JŠ@µ§Úý`!jO¦ÜÊeÑ'-Žª¯Š‘,D�1€<)ŸÈ05J•œöS*7àÏ%Þ·[‰ZÛ]LópÊcÇè$Öí^2¤Èfé´¨qL¥Yɽëj Q†%M>«œY¥!„eNC(K6.1žF.‘¶”¶‚2Ë£'ЍJJKœ037…Ô~†2W]©hªUtºÝvW›‹J‘³ÉÇJ’‘¥ç¢¥ÈJ¨âÐ$Î9·9Ž A½j›…*K*EI Ç,°(ŸŒf!Z¢ß/KnA•/ÈIÖ3DQY°ÔAQ”¤‚ Å5U,5I&™SN4hŸÄ°äY$²RŽ&ëèχ®,$º¶îd§‹àEIZ¨x•‹‰YbfUG’‹(rŒ‘y.œòœN> ³J“gYƉM)¦=Œ¹=t«žƒÁôÍß8CtÇŽnýi-;RIé߆ò¢„U(TÎQ‰–*;»]¡“ÏéÜ2Êö0Qj–&öbl´²×‘Î!=yJ¨ÚåO¥ú7A_›µ9©ÏÉŸþ–GøôVÃÝá²ã×ëue…”¯€ `Ÿœ7{� ƒòpGîNëGH_þ¸£ÏCÜ}„Ûð=ô´€~íæ~ZÞ®¾sgúÃÃø‡+ƒ¹ù;õÝËý=õ¦±ó{l”ŒB_?»ý{÷ÿà˜¬^� ³Æ `3>€[Ð5ô«94@,ýkCuóö§øfpö£/Є'8=yeØÄòB@Äa ê¤ûƒìƒíÄjÿq¿TcÓ˽Ó!ž_ì–éþ˜žd…¼7Õ¾®õ#ÔáI©Òé__©ÍZTÅÍ7<~¯ÇýéâéïÔTq’/ö+¨t trå½ 2=ß߇íñèsóÉ)ÌHY·Íoü©$7ì×ûZ&/:E9aT˜¼¬Xrƒ®&¡­6;ÅÎAZš-“°Zå"E” °JQÍ\T¾•>Š2‰Ù'bÇј £áœ«˜ %îõ�� �IDATE•ƒKÒ‚ ÉEd–”¦‰e’º-Äá3å{•ùÛJŒ6Ïä)e*OJ4í}q·¡,g}!ðsô1,Óx{ÜO7 ÿÔMmk.Zá*ÒæD1ôO ±Z…R'Mņ£öªáíF]Éz›I5j»ª6¨Ê‘ñhƒ/“ˆ–á<Í7S˜TÂp»Lä²Òšíçî&ÉVÎ0>h9'µmkVŒy™åžêÉiëܺ5vUSõÍ*û$˜%¤èU +ïª"„­â Iæ‚'MJ9¥²pɉLFÊjŸíÂ|J’9Ì“œoÓâ§ 7Eõšû.”’K-j°‹§–Ç ÅC-²Î‰i!Œ“¨öÑ,…ݤ¢šŠÒyñX|C©+M†;éŠÌä“ó"Ò9U ©,\l)Ȇ”Zr1zðI‰2“”0›¹$Ä”pb³kªóýœkÉ?Ós<.i<5W—z´’{žl.”‚Ÿü]<Öxp,&ÊÓ^ê§mù\_Y[=8„T_/ó.s<ïiGmãê]ÝH«´¸IåÆw?T9Èv8U§^­:µöš¾¶·)ø d¤éK×fÐ~¹Å¸Éæy~˜ì_íÔ+¬w8p˜Ä£×s’—Ë#,áiF‡�ÔÓ·V7Èr—ð¶çüp-À°p &á Ã?“Oøç¹þغ?¬Ä› ?>¸á’³½«¹¾åßûп§­Ÿðh_ôÀ-ÃO“³ÛÝIÝpýõ-ðåë•€¡Þ(aºrzc§~Ç`Ð…‹ócyE,p€"c‘hÜU¥¯X]žTý&A&m-‚íÒí_hyùá+™¿0][ìãÜ~ü} õÚËå®i,©u’·£øûvŸ—'áÁ_ïWÛÖ”O½yqwæ‹î›Ù­©éΦ<¬VwN(÷bú¬ò¦ŽêÔMD–ëIa¥u–ÍǘK䃀n²VIš…­I‚ª(´¤´"¡² Î3­×*±S‘IdnYK”PsP–f¥©Ñ¢‹"Î\HWXB9ÁVA¹ Š\( ÎYÊLHyè1¢yÃ'¥7¿üÀ‚1ÃSŽ”Ï9çHz8äi8) ÅŒQeäϧÓñf¦å¸œO™Nm{nšmûºVŽ=Û ! +çE«Äj'åN•,ç=æÉ%¬êÚ4³ I(Gܲ‚—&DNËä§xãóC<çcTƒM7óHù™€œC»Äþ†—¬¹’±x:UÌ­´šŒ,!Ф!K±9æ ÓŒS„.Ãx*!9H£I= ,5¥>JÍ\„ "dÅ,8•’âR²ˆ>§9D1„ñ¸ðyðÅ„°D_æ3-9LþÑT>kii¹&™Ðèl!ÙÒ2ç8³™j]sÂLÁh©EIYAlTVÕ9£¸Ê‚„*¤–d΂6V9K™ýiô7jšçÑÉ$ÖÎJkj•´)¬RJÉÏ©,ÙN†um¥•D ”P\žb6 ¤ÐNz=K%¤)PMà—!^øxqÎÈ%œÃÒKuгê½1ù¶¹aÖO19>²@²>RUž´–xss¤ùÿiyúË®‘OM6ûãÇò~ÉävÏ÷q.1éá…ž¹;äm™§ã³›—üÛg¯i…ê>eÜ7Ùã¯&‘~ûŽŽ®[Ãä-Ì×!�¦†0ðS€<†=Ä[À¾Ûè Ž@Xƒ3píË‚à!¿Å¢3  J¿_æeþy=&Ô?•Jâï”ïÓ8âGN=Ä{µÖ¾Å^ß}FáÛÝlúD–ïýê‡O¹û©{³¦»®äJ,3÷x¦;|�Dq¨*J²†hµ;a=ùûÅîˆVwÈ’¥¨*‘’˜¾éNgØcîíE‚«XÝ-µ|ïw†{öý"×Î\¹VÂÛ¡ÊšàÓF nÅêòît €¹€�@¨Ü`�ð�+Ø_�Ì�_€ÆöI5¥“ñ²¾T�_2×îŸ�?‡V°=´ëÏ®~ñôl:Ý{SsÈnRœ•Ì N¸Ží«mÄX£Q÷ÛvÔq‡�kPò ݾZZ |UÒG¸œµj>!ïf ‹ôÅZ /Uð8—4«‘«<«xÁi˜VTÎÝêiˆ´¹]}&:•,¢„d>ÀòBè¤Ë¥Y¢aö"Šl°j&�ÐF#ìFL*åìòˆ¥¨ÙȆ¸UR…&ê¦àYÄ‘=%‘‹ÒªCª�¨€(ƒJQFOYQrµ©Å䢴kÂÞ@È�¡pe®Yf—~Ú…éÅrx… Õ{[H‚m·¦µ‚’ŸÇÝÍ«ëë¯Ýác‡Bv™elÌb¤ôWµšçZ‚iŽ=ôB°°ƒDQí—É»à ÆXz &dAt2æ4ŽÓqñ)–eSÚá°,QÝIý|ŠûùdJ¼p·-W-$]ª´¥@Üú’KÏ´=( Xªž&!#ë ý½Û½Ha9QšÝ5»Ô*aŒ&’µTdKKSI'©@¡àxeT9“î‹réTFE¾ð2-ÇýŒã"†X(x%Jé|5A.UÝõÍéu;7l¥›¨4!ëšuÆQØ“ÕgÖ‹ãŒ5ÕÙZeÎ% È=´¬Œƒ: YÀJ®\C¯Ê¢DV¾ÐÌš«ð\Üâ–kºZ,ófåj«©n�µh$å*“6PW”œñD8qr4 šRA¾¦" "‡¦>¯î&5·×qgÕF·«ósÍ@²9R!Ïpwzº_vcÛÑåvóütö_à´‚‡òWJé Gõñ«WWîq]×îİxˆýßA~¬ôùY/¼½®—_Àýß4?\ŽðÛ7¤W…ø¶½E�uÜb~^^Å7~§R†ð¶¶\ À-ÌÜwLh±}£Z ­†S|sów#Û€`o'ýxáä' „*„ü¨G÷·ú_Ê™õª€é?€?ìÿ}ïn\P„ý§ý]R¢žÀ°‡Ë=<� €9./Ž_ïá¾Ú }q§JÄ-$ä7}k «À ¿ù'ø�âêÙþ´ùx7´‡^oNÏš5UóöÒæµ|òxÃåæb«×8k7%Ô,ƒÐS-†ŽÈ^®¨™7¢¹–ç<)¿Q¿…_ƒ¨ÑÉ}.Î äþôö®û�U?>:ú›/å¾ ŸµKo:/ÊI6¹{ð"MmšpIMVÛ݇†/O[ÁöÛ¢(*Þ;Á¾(ì«¥1XBè°q† g%JôÙQAb£¤DÒØj;EB• qš›À‹²Ax´™* "%XßÔ¢³¤(Œ¨…¸ @@ TidX¹B–9Rqc‰5a`€ÊG™Î“Rµf©u \}¬KİP‡qÔãlˆjR<Çc_½ªÐ@?Æüüxý›W_Ý™ô"ëJ½ s7ßétB{^u§µË®ëP\ئS²Ì$²š…H¶OˆÓŒî´Ãûá$k[%ø÷û|:2O2ÁÏì©Î'E.bœóëàˆáÖŠM.mz `ËF²¹Ë <þšÒŸb&`qT’ÙfÚô¥™R½>§»èköÛ™Îê¶S•*-P„®�J£ip U˜U åÔieô@ÕÔT¦©ø]]2† § à”ql ¡Ôùšg渨à†íÒuR•P0:®à©C¡Xɼ˜rÖ„ÜxZÍåX°6F m2ò вŽ9CÎNhk…1©ÀI‚ ý‘Ò¡¤[™V•W5'Z7¨†ú"{¸PYL)ÀÀ•BªÒ•Ly®³�ùÀH„~ÏæDК¢©ä´-iêFõùC÷? ø¼SOE·5]OÒÄTµ«wSjïó²Ì*®?~íåñ:;+µj£ðc¿Ða—_­Ü+3þ¢ýJŸ`-àTáŠp[¶`í”~±4M*n �ìŽÂ^¾„'žßÃ`– €úzˆ Àæ «‚_ÿ —È¿ëÎt‚'#<¯í€`1�=ÀÞ¸íïBÓ;,…‚}z§•æwÀ çïðƒ°ø „Ôþ`œÿã=ºÿ(æà¿óªwÞç‹ßRúq‡óÖx*Ã; ß'¾]åãÖ{¨��6°úe§Ê®ø ÎÙðEûÜkàe ËV{È{`€°·‡oXн;¬}Y½:Áë +«íyô‡àö |üË™Kq¶`šáÞ‡›£?ãµÖF.!šB(Íë[§&‹®éÖ|u©õž ç‹ó½‡Õ³Z®É´¸?.ø˜³ÄW³Ø¿öŸ­é¯h²=ærµ]©—ohÿFþ0>Ðk;j;Ar.÷ùtŒÜÇ Çn]¾2bQ±·ª›V­êL_•Ý8kf`¬àórik1¤uÁ’‘*Z9œ+ø¬uÆ"q%$,B;Õ²ª¢JA+aUѪӈP9V9ƒ�¨–¢åª2Ç,bâÈÉ¥²ÄjT)XCÕ‡"N© /0fÉA–8ãšVÙ$Œ`ÚÀî\Ý ð1”ûÝëû/¯Ýë‡Ð\ÆŒ¼.K“æ«¥«OÝspë0©ê)HSo»F.EuG’6*²Y°—`D>ÖÅ í²+ŽíaVËRDdÊ™Øå“Sô™ÃÅ)#É éâkq|Xa@^͹= Ï }fÂç³/ÑiËý 6‡«PÅâxÎÁr,Ðd­µ¤”­Ã!�«M+pP@º’p•¸JiPι Ÿkõ!…䲎”s¤2 Ä5)U±•9^17¸Mí™&ç¨j@Â(ûÑmöÓ¡%@*ÑhÊ)L°‰¹÷µ5õ$$6ºH.-«È)K¡¤: Ìy.öxðË1°+,c4 Ƽ jÕ˜Œ˜ÛZäRR-AC2EˆJD6ÍiÈëZ÷ÍCk{’³À»9ä'‰3n2†§Ö}\Ëu.Æä®u†Œá«F¶Óòrá’–)ð‰éìTUiÛõJxi¦­­Àa»j¸ñÕj³k¾û¢Î//,æ³Æ<J8¬²ÊSS§'ýßäô·ãa<Òv_$À}Øgˆ mT ø�÷5l4<)ð\ÃaÞ†˜�¿ãïý–Zn ÞÁó7´ÿoà­G÷ûöþá[ã ûíØ¸’àc€õw´ÐßR§ßV¥Êûk'?eÇÿ/¬oøÞ›Ål¿“:¼Û,ô} yó>?éYßCÅD�|/Eó¶ë‰� ¿±`zã|rØÂ½>€Ç¿„_<€Ç[ONÜÑ>Ò>³¯@l €¸ìv%ø}~öèKøÙsøÓgù5Üì5‚³ªŸkÒO¶âù)Å9�<Ø®>'q[<È©q}€LrɈ‹:bgd2탟Ží%ál œÅ$ÍêÕÆ&\p–|…ƒ8óõË~ÔnOÀ è´9.›Ó¼–3É=jktWbS§ÏàÚ6M‚U8;Ò:vkû1L¯ùåÆ÷ª{°Ä &µÓ²ÙL‹îÔ‡­À®)«.íT³Ê1Pñ¢ºJZIg.I”YÂAR²´¥DÙg(#¨ITLU² R5‚å¬ %Õ"(r†Ä‚¢D#‹ÁÚDŽ#›Ï*.œkŠQ3ë‰êÉ΋8æ ì,y]•Èömƒ¤ªÔ‚@÷ØYÓÅj–¼J¼Xow%\LaÙñIîsÇæ’v0d@¤lri•°€QŠ;ˤç’!Î ¦…‘eÃVÔ9.Þ-»pÔó~²9•«ceQæäÇzØì¾lÉèÐVBoOTu-Ê/ˆ«2þ‰™3ú‚&5‰fânÕÚ„Š‡œ­ç6D†\ÄktAtÐ’TÊ \@…ªC©¤aJ9Žœ!: D,˜E̶¤V‰ÒUJ‰I¤@Z5‚Ti¹ØÆª�›#†˜–´6®Ú©ö£›‹r&M&7öÐIVˆ,5j‰Ê6¼¦(*:n$HrÔeE©™={—|Q%^Çb—ч¾x„HÌKY2L³÷gÃ-ØV- ¬­0E¬L×oÔFbpÙär8%…"«¶."¸%‡þ²Êä»u…­d´Ia*%f—™¬Ø>R}µâ¼ºöï@íÂ嫊Söʯ›[ø‘º¡›‹š–Q}}XŽû¹[õâéróOÇÓÈsÈð—Ê5©»†³gUÂÀ�ù£å¸ àÁí ÂÀ'�ðÅ7=‘¿ã&Õ;A<~+fp?ÎzV�€ €3�ðå·ðÐB×Âü®ZDàïÜ„ŠÇÄû«LÿM|Cýc¹è'€Ï¡ÆwOxþ«"��n>�ÿðƒgÅï<KÿàVïrôŸüê/SAû÷®G�XT€éŒßÌ ¢rz Öè~�ÏŸdèWPÚf:ÿùƒÆ*Ý”ß|uÔ >L鬙íù…G§h@|�p¡áæÓÕ"ìÃ.BÔ·îžGùæâKÀO•sÇCíý]ìýÐ=,ÍúHp¥åÎh1Ytâ<éCNE4ÃÎ.·]6¯ÓÓV­¯[½»Ýí‚'Üuãþœo–~É(ÝÐÉ’@Ó§Ô®¬H?K·-ܨøa Mõ1ÈJ6ŠWÂßyú?Åü‰¡]3}ÖÁVÈߦæ¯GÚØr©6Ze×?Ô2PT€j´l•¶$s†1äUgáTECÆ\¡Tê„–Yì6FéRC %²@L[XW[¹E´±„ê\¸çì‹,jdÈœKXLI0«åØL¸êâ™Tˆ_Rh’igmzDi�ÝêæL˜UŒ©ÐóbÆ(vs¦gëôŸ­ûË€­ ‹²Ê×^@ë…”•ê4Qw^æQô-o«šÒt`Ðí5›Š%û‰ÞÝ/a‘m.Xè¨}n’ˆ¯– é 67¶Æ ›PL–¨‘®u¹P¡iÄÐ3¦”^&1|X¨—µX˜¬gÚÇ9#—’s±°(‹Ûûª”.±ð x¤™Å$P«³Ž ûÌ1ŠÐ)! FâB‚°'Æ8»iž\Ô" *àBXMF‘Kq¸ø°!ZP:¢J<r&^lI‘¼ˆ<!CÀ+m4–t}‡‘u‘« TÄH çPJ.àŠv S5«¢I‡G“ç¢wµ¥’wQW%àä÷ ¤(ªH…t�U‰"•;iQଖиLó+NOçòaãMi…ãÒ.Ü‘Ñí•6+‹w5xyeägÁØXÑ _¥û×a†Üí-4!›ÕA´$š|Ë1_¼ºÙÁ«ûüOÉýVǘ� BÎÿØ?­XìºñíQÉ}wÿÁúød!¸©°œ€ð�ð¡¶�+ ¯ãw€ðè÷õÓw�â ÀümÈ~  a6ß/Îÿ¤ÇðSˆŠÿ¦¼ÿØŸÄjоs‚~«ü�ð;)¾ïMð‡o¢ß¾á ðÀpP -áÉéû/ÿ튀æe‚~§ñi‚1ÀóÇâ‹m‚'éÉžþ;õéÚ¬¯“Õíü²‰ÍÞúd¢fÓÂx·×¸…ÚÇíÙç[ñ¤3do¾°£¨[m» DjÌM‹"ŠænÿxŽ“~œÛâ©J_aÏüzÌúëÕMz>S°· ’Á‡¿¤GXÏÎͬ’9ŒÞ/hjÔš3|ZeÓiݤiÏ÷›;üH=yhY_"6²Q qVÃ^k½ÁÒÍ®†-ÑÈ'~ò‹¤!ă‚Õ9?ZL­"NqîQºìï¬Þ5¯äJš©NIžù6Õ‘óÂJXÕ)"…DÔVU¶ 6¤×u;H[À,¾KyÎq’’{êZiTê–¬”’Ó2M»“?…ÑGI½‡Dñ4›’üyL©9/ÐJˆJ.r=-ö!“æZ«–ªíÔm¨ŽJ²áÓ±ˆSÝÿg‘ ÏЮ gT;N©] ]·Ofö“¦"ÛñœIh©9e’e­ˆ‰õ<ÅéÞM÷‡q™s*$Ï dBà•ØF„M6v¥à6N7{·eí+,ÍbèçXåÌþU(ÿœåy©¶*r&6íDñU<=ð1¹zAYpƒq̧L+Ù“<Ý”yTKwÞ“Š ÂÕTKÅÚÆ•²V“&Bk¼WU Y–*b-Aø¢HS%„ZÓœÊìCýâù@´I¹ñ);f™ºZL!•וò£¦h !P±˜TL•• ˜Jbž ¡`FŽ1»„'grô{_¦©(J-UIèBIM@ ”¢L,ÆlZ§æ~®2±ç<žÑÉ`Ú¤$(‚”¬„•y´è¡hra¿¤ÕÉýãžC¢«¥ØÕ‘ïð6)Ü•SøZ„ŸËæ¡kÎ�îÈ.Ä.î¶IÞÊǯZö§çùY|HøØÃ/¡;$FÀî.û´Ñ·q“î?Ú¼¾Ûüê"Ü €0oàÐ\vÊ.©=/оÖR€ëkñÌòy…1À¼)C_ëj" Ü;a·ûvË%|cØ÷‡ƒõРà`úކàÀö„UÝóÿAyÿˆSÞïNø€Þ•+ÿÄ7ùÎç/¾÷‡X~xIámÚï|3~ð“�€<Ä®ÂYü ÿ´±zh–ó& -»4R†“tÿi±×)ìzóR-Ÿ!lêîAsÿlSa]ãÆ?χÏà\¤³_Ž¿¼.ç´àó^ÇMyPÖCqÜðfl«ï£9¤Æ5róˆ_BJEÜN÷9¨f~%ÐõÔ°xJV]Ô«Õ„‚²Ö„Áõ©¨·@Ü'í9äjÃÅ7r^]þ–åãÌ@¹ZÖÇŠ7î‘ñNëÀOŽð Í6ß-iýŸüà‚ ŸjG¿øùÅG´]³šC %*ÀÈ,`§ë£Ä‰%Å ªn¹œå …‹ØK I )+“ÕÒª¦êÁ›®H¦ê+VYª•%'AP'Î'ïw œ£;†ûyóˆ$7r¨—DwSX Ž»lÖƒÑÜ”dòŒxëzÓŠYs@ŽÅiPÂ*bçånJ7¤;Zp¹—ÿaXúNÿ|€K"[–!Ÿ] Ùš¦Š$H.s8p–RÞh¯´^2‰¬ *WÔ8òrŸ¦;9J£œu DŒ«)šà{•Wdš•¶¼}Û1|­òQÈRù¡âÔ.5Î×i?'û0‘±õH2B“¦ÈpY<æà%/¾�·XËaü ±²Í¦v¶–%‡½»{©åF6J‹Jhé)U]gMŠh.Ü8¥R!Ÿ V!�²¨¥øX#ºÄÓÄÒ»Á¾ätX²Îì×ÐT1 %V[›ÈY¤Z'A’òÌèÎ0�&b–h¹& \¥—}…“Š¡)û‚R h+¤FJÕ$š J…*Rf¨²± ·¹�"3 ž;0˜^5ýY¶§2O±±F§§yânQÃC;¹?ù¢ BXºqõƒ„Æ:ͧ]v0…|7Ÿ.n‰†A�Tp”4¸KçdºK§a·ìã EÖ[ñÑEÿ¬>ý@Õ“Êð‚F.;+OЃ†pÞ@rp­ð§ŸõîÈË;Ⱦ8‹0~Oð­ëm…#þhˆžc§ñnïþôý9Òßu­úŸÜ¤ÿ-ø)ý”ã{r城4ñÇ” ßÿž� �s„¯~ˆ.-@÷]dr3Äí'põ k•å,µªX(7¶ÂìíùËÿ_ZÚ²lÕj59øâ¢è>X½¶÷SxdZ{s!>>ƒÎ´€[#6´êåߘ۴À˜Ú[£B[4ò¼_üüØמ<ûg‹\ƒƒgí˜æÉíxÇæWÔG¬oä~–«%62?xúä^ˆ»—A=ÉÖë h/ 4r]MÎå“�믉tŒ?»¹ÑöZÈéƒEü•ÜüßÚ<‹"µý£Ë+£VMJ÷“tœS¤ µHƒ/ÁņŒBž5í lЯ7”¥rÓÄ%ç$k#È’Jž]!WÉÔRBK¹øP¦:;/Ç;-ið5ê °0ês%ùOÞ§¥Pã»|góRã~¯Ý€„+ŒÅ¹tˆ“OÏW¡è»Wûé×ÿüù²D!pÙüÙ$®h}®Q4YÁ•«d úÜÓQéƒÂíIŸ¬~ »K$Uj§K1Šu@9±¬¨u”KóI¬œìÊ8žð Y`.ÍĪ­§3=KC'â{!úB4ïªX•–cäôa‚>(õ°ÚMÊ#»1@ h+ÕØWVY× à UÔê©‘g(b忝R )âá%æ,¦»EÄ"³8_7Ô›M)²„ršS_TñÅÇx,¼d/d5º‚Ž Xö3Ü¥89¹¦X°dNõµOŠŠ±êÉJ´¦Õ@¤‘»F8¬¹b.yœUÏ…T¦ÍÀÞÏh•©µTQí Ûéž5Ta¸`k„^¡TIÍ\Çœ=åZŤ4Á Œ B•dÛö±‘E¡ÚÑVqÍá6ú$œ9RŽ»ªþIJ4ÐOˆ öºåòa#Ï$qÊÁ˜}mžOhoÁð²ÚÊ3³½Àék¸°ßuÏt .ž9»ÅCˆŸûÍ_¸âgÒ”nûjXŸ§‡ÿ.-ç=<J²&=,>³i¡[âeÔlÖ`·îi°—u d}¤ 5pp�ؽ”€|gJØ«~7÷í»B+ñcbûÖq)¿GýÇ÷¹þ›Ã†ßU–æÁA¡œÐ{3“ðÁÛå{¤¡D0úë 4ëS{f̆ζ±W+ùÔ3žáo;ñl¥�„3 Óv5aØ=ÕùüöøYšÇ8¸zþ«Í�óã?`Õ¢0] GX ?µLmÎÍ[Û()Ÿ½ ×”:UºÆoÈk§Ì²,îK™h©ã4ÞF¿û>²GÌÛuýL‰3‘»œÿßͦñ¦$ÒÖ:�� �IDAT+móâüõoôùô ]gì%®¬íOiåç_’ë½j–àåéN–½•÷eX¯Õ_Û!Ë\¦P·8lLð¥ VeôzÆ¢#ãÁ5hRcº¶] Ñ·ÂJSµÉ©‘ÐÙS]q˜£àLªTâÀÓ!F”©°]¡tÕ%–B-Áãtà‘KS…Ñ 4ÁE!D3±,]Ìg•Yñ)ëpL‡çæÞÕ\Ž‹t§t¶êöà¦×î°÷·ÝÒÙÃÙëØÖgËÍW'_ØÜžàB”Oˆv°,yžüÚêf.|"wÂ2©Îa17­ŒÝ¢ŽŒ‘R1Ú¶gPtá’ÒJs¯0eÙdAL¬:Åi7ÈfLp8A{PíÏ‹ ½öÙN§¼fïóœdXéË­-V½ãg——"Û·ªóEžr\“aÅÔnµ¸Dl¬Œ$¼D’x„’cv5:*S¦pLËí²Z B9ëÆ^bÉ6Q.Uª™Õ¨+«µÕš„€èÀ{ÝéäÓÁ×ÔE*È Äjª£‡k#JÔ¹ à”ÆœªAa1 L°� ""–ÊJø"+ ÈY€hÀÈl‹¢–Œ•ËI”H£©)(³D¢l¨TXB 1+1êÆRšÔšdZ©(Úš@¡ÔÙö¤T>ÄS²7“º ?3ä·uo;%6¥UÍ“¬ÛÔôyèJã¦Æìëöæ!õØ}ªÖ*ó… ŸåÃM„ʰسxvöìጠåý3ž'`li®æ£¯A•#¤«ŸÝ !Añp†6ÊxRcô÷€Üü9�{ˆZ¬w«Å©.ä%Øð^ç#¸ß4Ëñ­vê=6³h¿‹ ßl”+@ÿVóðö÷qòú;œÞoº÷ÇÍ`þWÇðfŒÿLû‘oOï:›ÿØÑ¾kY5¼]Æð¶•õÍ€¾ûï_¥ü7¶E�` ýÒsPñšŸw勇øÉGöñyóWVobI7PåP|,¸¢Ûü½mþT‡þòþA¢cX ë©><0¸×_1xÚbà—¬Ö¬ÕÂrQaÄÜÚ­ª«\sZq³ó/&¹nD¯üÚíMº]ê8›¿ûmþ_ì:WtÏë˜z˜Å^imÈZ}.m@}”aþè2÷ª.ön>~xê¢ ^AjOÖ•up,ä9ëº6töt¸©UWý™9ò½VNç]³, Ék]šú²•K_#Û½MªM¦ BDR5Y ­ô:ÐDB5,£RtSäT*e±‹’±PEÖØbÓÙîºëèAˆœO%/%‰Ù¨ÛZIŠ2ÊsÉ(×±ŸÌ øFÇÚ•©Âñþùý]Ãã•ðŒÞI7b¿KFF¥«¶]½nD“=•Ãù†ú^«@ùŸ£{=g•gíXrÁ’‹˜ÃѱŠz&DQ ù mâ!²²>¤|2B;ùé¾L_¶òÌZÔÃ]Û¬Õªë{Má~¯K§äªm`ó УQД‹w4›)û…’’:ß¶JHUG¡]—NRÄ¢›Šë”úš¼ÊMI‡”€«aèjZ0$ð&Ì2èPV÷YõR K$êÃJ‘ló£¾)¥´\©€,.øy·¸ëR¤¨shDtè'.,©×*µ„J«ºÁëŒzZÀû¤EUÆP_I’9 ÖG×'¯[®Ä32È‚ˆ‚D5ÒêVbmj8’g@UÀp§DE•‘Ž‰Æ™×ÏVT¥�2´@RS‹Uë*QAU"‚ejk’P9ÄËš§nðº]k2µC+7‚-y+éü¤”‹¬"ÏuÐùA²Gh^¥:Øt`iæðô´­sƒþœb\ihòGùgþ™²°o3AÅè c¿ä¦òùsð¿‘gJ…à¯á9$Ïg0À Cûãêl�{Æ =¨obÎ @Ü•7ÝF:¼™ G «Ï¡‹ß¶0)€æ›f˜o¹ÒÆÀ(€ÃïÍ�ŽLy¿H�õ}7úWÇþ±AØÓ$€PÇß‹�°¼‹°zcmp€ ßäq .Á¿zñ°P3äÔ—ñ†`™¾X¥~•=Ø9fžKà~[lª´ç¿Aq,õÿšTà ˜íÙÌhT󗘙‡Õq,§‹G»‡@—µL£úÒJeê£sÑ)•аs"7¡ÖêPm/ª ¢°ü'=¯Ô¢„ÞKûÑÒãk(²£•°Ö~’ÙmÓoå¼—ÂgzŒÆT°�*Ï0Œ²W28’w&'}cƒË¹N.4]gÚ*5^˜ ut¢?�h˜Š9ÍbXmòÐŒ&²Þ3Uè(YÍq1úÌÌd-G^€Šy]‚yéUÕ­«rMœËIäbJ¬œs¶PΑj…eIuáEÁìZX¡^7ær-JóÂSŒÅÍy™Œ.$…à 2VY“,¡Ê¥j?q7'C, µî@öáÄꞺ{–ÚC[¨ZU(•¬ˆõœñ²€/Ø'™µš¥]¨_•s(óðåÉ_0ÏÕXÒ˜î§ÉKé' •{”$¼( ªc]|T¢•k \–¬‚©ó«¤šø!Ôe½ùgÓ¦Ú<VÖ¬ ´ÎC¯”Òõ—áüݯ¯PŸ—¢#wwûë¯oãŒ&a/³Msù´ëéC:N‹Wž‹/¸”šŠ®*âS^x æp²i•“Cå³D œd®‹ënD L«íИíYgº¾ÔfšŠ‹<…–à—iö÷¡>–\Áä¦8|fµdsæF’¦NJ‚5O`³#ÕsÆ$‘cš8gH.¯Šè±4)æ˜LŠLÀ¤‰@b•ZÓ°€T4Êš-eãX9QƒÉ¢(ôD»€½#ô–XÄ |$�‚„. ‚(¥b)xÈÞ‹š-Ç­dÝè¡û ÝîÏíA—Z0mÔR=¨(¹VJÈÙ\ÜßAz”HË(hºJZ›íÜ<Ú­d„ð¸=™n]nÇdöVºÏ�Àî4~µ‰W{èP~µ&·úòÙX Üo¥v ¹Õ£ÿß œ^Âüx»7[ú=€=3% µŽ%ž^ÄØÀçkhkYv¯bݾ+ÎJßÑiݼ?0. Ý7¢¶øÇÎH~â¾§·€w˜íÓ5¥?4õ~`nÞ¾?‰¨ßƒÑãOxøü#€3€×ûoˆèÁH_@z ÓüÇ«¯ç϶çάXAÎl{îck¼‘õ^ÚxzvÊ=ºö1¢¢eHƒÕ“<¬º›–X¥å¡·mŒU»À‡¥¿ëÇ8%|¥9jµ¹´­X„ó>ÙkQ•ÿ§³{x�ÍÓ­5$­z Iø§ú´6}$1Èœ4´û[¼ºÝ õï…è×tP-†õõ­ý;srõt:•Ÿ$�#Z][µÎâçé¹Ü,¥¿Ž 'ÞHwÖ®³ Q™Ë }AFëg™[±ôB¸Po)KN‰\ˆ¤JM€6&HnÉÙ«ê‘uåšs—q[k ÑÎÓ1cl$RîÉg))¡^R^0žT¹íÃŽ¦ÉZ°Îm­:Æ@)ó’ÊiL_ß~Ù·—FÃÕÀ\†‰ÌÜD´/REjTn˜r¨©ž£h²ÅûòÕ4@°¸ä±9N£_†öïæíÿ:%u%™j .œæyÎRÈF¦¸5#È n£œÊ°ÞX£Óz/Úû0/sÏ¢­Ù¬ïy5çîiQö6ŸLÜXióÅ9šFmj{Ö¬W+-5WtÁ¤ ãqvCéOÕ%î”Þ®†µì§Qó²÷eIÔfšQT°(\`ZÔ!JÆJÂ2¹ÔŒu¶½ÃÆ)\¹U¢mkÓªUÓYÝöM(¢”q.è½Ì£¬'ÜÈèX½Ž*1Þ´‘xá¨RH>-*nN]'/ËÕZ´Æ>�̉kÉûƒv»#çeQ½öCªÖí9•·BW–ºGUU£JL†¹(TU‹F+uÑä+è˜eNHµ¢fVG¤#ÈBF˜‹+"1!e‹(Y!¦öýL€.¨Ú ù2V¼XõŠ4a]ÀÏ×8õNë–âP¬½SÚ¬ ýÌw¦º;PwÉ›×G–]Td†¯ô@�Ì–z ]Þð^¼wävMÿº4{Wç&}êŃÕôYÛ4P_ ñÌØg\ ®àë5Âø›o5h'xlà€WàÏQšóß×€€¨ J€ûò#;Ôßç¡>­ß޶ü¶÷)þÄ1Ÿî_Çkï_ÿ?L84,?n;õ0 àð=þ½Àôê ú}¦ À=œûÿë7ÿñ“ÇâìÓvõÑŸèó! —庳rXõ0ÙxûàÙ)­L¿käå¶U‚6Rèêåâ«´ßÁ:46 ¦Šu³%-¹äµ¼¾®Ç–?€|Øvu(Í`Û{7)1¾> hXwåå!?‚Ô%w êè±*›œOX¶=?æeš?)#Òe{fÆ,îž â³þ=(…8øøÍdnIúNY½V¾iƒéx˜ï;ê”Z7$[=v™%”1—…;Mçe½XsuîEºÊž¹€eÎeqKJ 0IX°Tdͦ’OÁùiÒu,V¶Ð%”Ž& B¬Ç‰N’¼ X¨©¹FW˜òBbWFRmËtënGÿ|:¸¡ÿ¬1²VÄ]àe :A3©Y5 ÙÒ:ù˜ö-Å“oåú>Ì:^€üt�*ᢑ¨ÍŸh{+êÌ‚°IÉ9»¥x™9¥2Ÿ°lÜÐU7èXÎ÷`2ê•‚¾U}‘*AÈVôMKC§¥u?tW—V55SPKLFrB¶”dƒ\rÃ2-Éù£˜/³Ëb·9<)^`[°.wb!<õB’ëç{uØí—¦–F{4‘‡`L3ÄCä!‡:Õ;-*gDê‡ÔvÊj  ¤ Q¡²JwMˆ¥/XÉ>ðzÆq[4© åå1–ù䈦‘Uéµ²Mkt­ÞMÌGfÈ}¡’å1ç jbá]áZM£L˾F!ešÉÔ„ (-šXŒ®IÈ•Ž©¡”0­ALŠ"Š6e(Mf $)ƪ &J b]±‹�¡U¢BCÖß^ÖØ*–©ž@„,y< ó´µ) © djEØj"ÝG‰pÌÒv6]‰Áwƪä L0µ˜Z~Ò*CZ¨øvWF³¼»¯€÷ÑÆ"æ÷Ëå�ÈPHɆÏž‚{)]Þ2t‡ô=gŠ| § Ié—ÎlBÐûø†…öðKâ¿§XÔ¼3Úò ±�Çpÿ%ï³ç±ŽÐïéþÿÿOŸÒ èøÓQ=ûL„þûØÐ½/ýx ú÷Qo(ž%~±‡ÏõîÇVà°_Û3©1ž=JhvwûÝa„ÛÚ¼+ ²}з=ç²/]Z¨Ö­?Ý*(塞{u9OmJ†ôçÌ*ÅÙxõgŒ±®® œ†×›füŒoèÆøùɾ 2”òÈÍÛr8ÀjkÎ3€waniMúQ¿1Y¿Î÷·cÖ{Òbóþ¯ùø_âtïÉš4l&ÌnüD¿8ý†ïáB||>=ä~DÊ~¶óK¸xPÎ墈7ì¢ÇCmEvÒÖÊ@\Ãèjº+ÜrœlŽª1¦ˆc ¢dWòI–Y]‹:@ËNò}å™ÒU�*Ñ•‰ ‚r­É¡˜Å¹ï“䘳W‘»À9¥™U2—ÕõKø'£Ï„ÇÎQ ¥””d –Š„®ÓÛN´HF’oÐlð…„Eåë•Η4Í•²û³ÍZ5Fn'xÉ~³®žò² {Py%cÅ‘gNÐ ÷Ì­q¢®¢v93ÔåQÉݨŒ¶Ú³NåAS+¨—Õ Q‚`V³«û½ƒ¨±-~ñ§Ã.‡¦§YT(DjÂ’–øjš¹Ö<¹“h*™€KátxÕ,³8ÿ vë<ôveÎ×Öà!t®2éBT¢!¬�qŽÑ¹#;ÉlÚvݰ½àÀfI!íéõ~Æš ÏÂE™NÖàÌüqʲÙ�Ô‚D ˆ­”YJ©£PPªçXÙ&ª*ƒK”•bîJUs©’k…Ú´X*‹¹ÕHD]Š‹„¥Ê^‰ 8JÎ&7-€W�º¶}omd®5R2¦HqaÞxÛBZW}iÇ/[.55R>‚~Ÿ#çcÜs«æÈj?&]Æ/ &ÞwúŸæ?MçÿÇ­AÁÍÕ.ÿöú6¾üàjö|Œb¼4pÁsŸæë—ááõÛ>Š‘wà+#�HØn€Ì—ãoÜí­j¿nò³ôÈq �{püýõ»!¥þá-ê‹~0ÚòM½ƒßh­ß*÷î”û·€ô#Ó#þ§êþ{€áÉ·æ©?u#”çð,¾çßó¬Í7©ýÛ™pàù›e-�7ß.÷”Ûååõ…=4~qyU”mÑ`é5Ä 7-D ýôMTZ& E^ «™º”;ÌT'„ƒ0FºÊù¼p[.·+ÙÊtb�—yî±Û£^—®… ‰ñÕÍ]‹·Ñã}÷å¤m|Ò¬‚¡0…ñiªòÄtâüpýº4{¼ôëù#çS SÂå€u·Å~ßgá¿ RûÒlüíÿª™ïvM¸Zýy×U¨¨õž»nÝz•]̈́٠»›T1[´WbT–šMí ŸXQݦZÚy©•KŠ>ç%„À>ÕNÉEI—‹ã²˜z”\9aMEê:Û7+ÒÍÌ¥Ê … ¬üºñÿGÝ›õH’egbçî‹m¾ED.QY›M6›-‰- !@ЛèO ‡4ÃÁˆ­.»«º–¨È̈p7·õî÷ê!3«²ª²ºIBÒöàƒûuà|vÎù–‘Y£7A½Ä¨ {"Œž|Í7Ã¥þë +™A®{SF÷�,>bäª%­äR³µ#”[ZÐiµ__ñ`Uá:s]%„QŽÁ³äë8_4°é£huöTŠ­µ×šíZª‚xr‹yì–j‰Ëº˜Þ²yöRC6ÙÉfC+rƒE,»®z :‘6Q ä%Æã)ó1ºã†–é’‚©‹ô̧~ÒK@2ù(p«C¦kÄ_³ÐWÍNUCÅ7û]Ój‘`=­tñ¹‹ Ý�‘C±1Î C×äÁcãG3Ñ\+ªm7][HvÈýû ½}±„)Ú²¨°¼¿ì<¾jºá%àé÷Væ‰ÆHŸKÉ´FcT. AÆÙ‰hhæ˜*hàKñIVÃRBЦ ­¢ Š "Œ2�ÊPœü¤ð0-\Æ™Xì© ŒÁ³‹€ˆæE5™„΀)ìQ˜üìúL’Œœæé~á¼c Hħ$œùÔ$ð+:£‘áTœT£5>òá¿Ð+CÌ åZª´Ùãt}Wߨ²}èµÀ‡éÙ]G/wþ2bïá¥ûôT}ÌÎÂôÕ€naù ÷ð·Ï VPØ`ÂfÚ?³Û{?ô@ÚDðë÷íyþé£õºä‡ïJ?P>üh¤žß9cÿ–¦�Ä Nÿ‘½Å¿rløã+ÿ'Î׿ô7þ‡Í‡ø¾Åž¿y5¤Z�öÀ%ø �|õƒê1ìôª3a«ãئø]þ`¬ ­yï᯿¦7 ¶@w¨‚?ÛnvÀ6ë†äÕªhŸð~E*¯¢4¬(‘àh¼è)iŒH™Õê±¢4]³·›2võn±ÙÆ‘†Û€í[ Lvc÷‡œ&ä‘“Í1äa0þÔ²˜]úûƒÛeŒ"ò¥l$ïR]†¸Êá–‘ÏÛrÅlÕV?× ¾ïd̵žE‰å°m]IOÇÉ@(•Œ`*éó]º¨&ŒçÂǘ’+œž�0,¸K¸Xœ‹¼ÃÞúüt R©‘,hµn¨ç4úä·±„G`X,$fsM4zư3¬¬ÙÎ&œ¼Y½ÁÔÍ«á.åÕ]Ó QYJšˆï±’˜èv@4Rv.fõ+ UK_¿iWS!аNFeˆ}ay=ÞÓO$6<=3ÙWÓ;Ç!¶¸niSqŸ ®Ìg4{b½™òy,nÄÉîýã¾ìüA ‘ [Wçü EH(ùÊ›ª@QÍ sLöËYBt¥! ®�ᘤÊg»d/„c  Éè>¡• JUkÑàJqœzL§€$+„VÜϹbT%³ä¼fsª§L)O$¯9ÍØØz$�é e…Q�Ti|©uÙ꾯òZµ°‘~ù¦S¤âÆû™1w)Ò=CRë«‚LvKq†+LY'J›:"¤4(–.1¤èbTÈL+•÷“@†q_0Ž!Œ ‚˜M„¹„}E™Ÿ“ɸ/Ù0”æLP‰s*‘ú�(Sˆ ì3‰(>¤i™B{Ƭ‘×k®R½½w€/‚+wWp!ÆÊ›¨@ë~�7±©à÷ëÙþw%¼7Ó„ ˜ºwñc8uùA<‡ ŸU¸ûù? “VÄáãÝ ú@Ào.7œ|è…»¯{8ý-ÀT¸¿Ä§{¾p/ƒå üÛ¥ü @¶�¸m<Tß3V‚wFûz[@8`Ï÷þÝfó}ß}ÿ·îð1�a8…wÍOb÷ÝÿŸYsÿËÔü !éG! õ?Å훃úkØ9ˆ¿y{!CÄ·›¯õÛõwpMàfym†ÅA½•Ø·ÂIxi·ìÊô�B<übóð¸}Líu²Oí2.ý°vœ?üBœžFªÙ¯ÒkÕ~5Ј¶L™ºp$±¾,ÑäÅãµÇSBÏ™‹€-Ù;ñÞ#Æ’ «Y +Š$¥ “û§žY½?ý=BD˵®ú»côs,߀ދ| öCì¼íKÿ ‚†ÜâåVŽóßÈašSUÓ”ì4ðÅUœ�jϪMklÓ„'\TòY5U“ð¦ø}´Hr`X¢Uå<ÉiÏ}-ÚmJùT‹b$½+)Ž#@1#Kç©"8•+© 227 †‚(),„»‚‚¡x¦eHüœÒqTêãÌ Ä'& /wnú Øé)uÈLÁø›!·{®3u(7Ö‘”딜âo0/¤¢¬B ‡r*ÝqY¾)ÐÓ}{ŽÇ˜ û™‹yy„vxã…Ô†Ÿòy>&ççùD¥—Øõ1س…9C <òãbÃa»Ù]lá¢ÒJ0ŠxbÉ;ãHmIóä)k‰ &xŽÆ3œzâx† €˜ vÚr® †Ã…�cûH²7Nšò {" ˜Ä|•Ó9BÏñ*KFT“öXýT /§ç³£Ø”›€ #Ã6f@b¾8Aöžœ#j¤pûÍãèfWT5È<�%±òˆÎé‘™§íËûCËZL€¥h§ #vªjyUÚN2Vmq+X¡Ñ"ð ¢ XŽ”—‚q¤Ì¤¼†Ä‚OuÆ(ÓL-u%hßc—\Hã“0RH-$âà ¦²p” B±ø˜m†‰âsÈ!ãË$´bìêÄ‚Á-éçf¡|—>Áò@ÅE 8…yQÌ×ðâŽÇ(As  (úTÄHÊpw€‡FN•ÿEª b«4Z( ð#ø€´~ÓCO¨úU„'€«ø‘³óYŽÿÝ™—g¾ñþUvç+‚éàUÀ| ü²{²_Pàç·r¤+€æuUç®!ݤokÝ@½áöÿx´>ú?F }wEý @¶ø²þdÁÿç{tÿ×™,}üß�Ý+‘D�9ƒ{Ó4Õ?IÉòàxñ¶=º@ÄüFA�ΰò¥/îf¹ó3�À/Œà_sÀ€na�À�¹¡>b»/ ¾<õªÿ\¿„_m¾ÁIEög¬Vô2þB{±~Üñº =/@Áüé ˆÅÁ¡fgŠŽP¿oË΢ªDçqÈZŒ[^Ó|לåÅOÖßnû„ÑNÄÎÃòI8/EÜRø€ý£"yÌ—hêÏ|By¿95„“�œ5™mWn³ |ER £Q¬7ë¼ cãê¯ayÿ°ITD¹YF„ÑL=6õ7;5ŠÊT!ŠçÙ8Ü*±¡‰Ò°X:*¦œæ% Å·)iÊeT#¼ëJÞE8vÚ4.è9!§\žÏ_#c*6×! ì¶.#_ ñŽ\*0æ¤LlIµøJjQ·×‚fpUöÊ*÷‰ÜÉè»Â´­IBÉG»ŠÞn „â«h'ÖåÌ>_ÒËuþóõpiÅ05£&ˆ*êH;…Ëk©¥>§p4ÏïÒWÛðB â¯æêk¼ß4ú±R Ž4­B ÝU‹÷U[‡)žÏ··1?¤Ì^Þ'‹ØZËÜBÊ+æK˜)åR‡ÒfL_¸$JrDR>òQö.÷©Ž4™Z¼rÏHmÏŒ60¬d–•Óò'”"‰¶¼ªêvUKƒs7b—)Š aˆ<Å´»G9âH¬)$™e£ßcï£Í&ÈL —0žÝóà¾\ÂyàÏ||G�sZSšLâ0ÛHõ®äL±L<cNç4±\rs!!cïH.˜%E Ã.Ä\œBd(ÎJÊ UÆ©`",/b1Šxæ<PgÃÂòB€3Ì0b4b(„&É ìÉ()U‚IîTmJ6V»êÈ–ûŠ›¯]p¦6 >iáR(š’‹È^2Œ©!ønJ´O³ô>«7f[Ü5pÚüCåÚî÷lù¤^àãKøì÷à`ÞTéW›¥=AQ_Ðý]iÿw+Mºæý«Dà;¸^߸pxÈ=xîÕx< �½®áz†›`SÃu7ÎóëÚm_Y-©WÜ" ( …:~;#ú%€�øû<1S€PþØÚÙx ÏÀv�� �IDATýÔœýßOé5Ð}¯ox£<Œáõ) €Ã¡ëæßÀóïK�€˜ÞZ58�ß?g¸ËðÆÏ„€ 8¼Éû|£ß~@–åEüdÌð‚'Òà®±|Bôp›aÝýœ^tÄ/Êr©×C;Âd¢È[—J^áa®© †æX­ ¢MÔ ïE÷†jQfÀjÃéu^õ¬ñF<|Ã>:æ'Î:ÿ°5M á'3•&Ø ¨;\o{¿aœs´¨—R¶©9ù`ë3Ú_`ȆnòðÕ3²\Lb³Ž´u­…txB¦ø sŒE¸Œ¨ ‘P–Ób˜£˜Ú %›Tpï·D3ˆ$º Ò:PFÒ¹ÍR3Œ‘CÜÚh†‚>›<¯¹L�'3'õb˜Ë:; sE£Â ¥bÄÉÃXk.uúqÕÆŽßˆx‘b¡#‰†IüŠ»ÏÙ¬¼–Å£_Ï¡àÙ]–¤Ù*uŠyÈ/|gIœD%¦‘gªYÉS\¨i‘©:­¶·/Üï%~‚ð±J_±ò8¦¿É'†GRð†f)•Úlê yyùT5d4ãgè“/ïÿã|„³Ñ'Y;ÕÕû–²jF/2i"]³äME¬ÎZ»<¹t‚ˆSdF2_ `ÔDÃ$ÖA(*r jó¸å:DÍ#EXÇB‚ì¥Ò-“ð– ûäh`îKuÙäJU‚ ½'AaÆÉa“O˜ã ]L÷öÅïïhØøÜ8 à<=­þ<Ì*PÖœtÕzŽëÄX    iJ¥ø˜ pŒ(Ö¸$(gT uÅù`YX}Ef#4%š!�¢%‹’dI87 8HdUgB³rÈÜPbGŽ  À–1pIÌ9M Çæ<ßgû™^¾|žÓu‰×tE$&ÌàGu Ã2¬@Õ@>Ž…�ø7W”“x!ÐÏ7ý…ôâã+˜üõÆ‚ô¥õwá#3ÿlºy|¢?IÓë?5w x 'Ø!ˆ#<Oü%hhn�¼œ€�¬ðAÙH½ð~}‚®‡m€Åq¯€\Ûr3Œ¯‰˜€G�k„s„ïdÐ` 8€¯r„î‡×3ñ&ÁÅ.™ù›×­Í¿%+âÂsüû8}k—ôK€àï øo5×?Avò¯¾ðÀÿ@2��Çpàæ>øï,«ZèïÁzppûj=¡Ü·ÍšõÃñ[?6� úJ@JñªÏËc@æ/cB6«òدO–ÐiEª_­¢ÁHð-ã„ï+ìP¼[l𫼥O�,'ÃŽ(”6A%tm‚LçÔ&/à?ÿ†\Íkͦâ±’Ýù_j·¢…ß…k·‘V`»ÑmâO¢’ yî+ûxc²šâÐ|3#kŸ–zÞoµôQA"µ,î]`ºÈ.ŠÖ$áÝ]wè«ó%/Ö\œ=ÇÈ_«ý¢Ï¦œ«èS&4ꔜ@ubh„cÀ…B¢”¤‰œQȌÕ‹Zö¦•sâ—4^ ÞÏÄÞOlÄøC»©4Ó•°Kz‰¿æ•jµbåø9¦Á³ìsãFå*؇!On}|1¥Oð:¶-i´&"ÆôDõD>f2ät“Ξ«`&ŽiHþÁœïÜ_¡îqE؉Fª¬NÅø†Í+[Ÿ0¨„ЊPR&)*EǨæU£›¶ª‚ªQª÷l?…•бt½­/ŠtŸ¼UqÞ^ò\#è˜Q±-¡¨ÄìC6(å”åX‹š'á€3 AXfE–Æ?ê®·.*áì¤bÇ8‡°Îx 9çÂ�Yg“�Re#CEi'˜¥ÜDG¢1X›–8YP1`s…\טÑí•Ý(qrx¶©í“}yçš4×7:ÑЈ¬±¯ XNL.)& 1g Ô—BqòÑ—„ÀäÔ”~…Ùà0z¾Cqƒ¼"‹)vDP2Ók1Ñ—‚ËS P�ªR*d £[¼ÌtOú¥²v$‰l·mY³g¯­ëÂCŽÛ…nÃ'”^ñúg4oÚJJäƒxoÙj²ÓÙ÷1ÅóDÎbw¤ØIÈk…9F,8<¡ÝÃň¼ÏУØ4 áyc¿q矟ó3Ú*A}=~Éãßõ'è7æú¡ºäт皿¯n õ� ü¶q—»íÅ‹- óÝÅÔkè'èáu£Á¬Á��<è›8Áø*¢†�àk—�þ;Îþ+Ýîú½åsÿýŽ3¸Öp3|×Üüþyr¹e~Jêè ,þN#ï¥q€�8�Ü~öna‡ô6`ò#øô2™ ßfé}·Õùžýúi㫈ßT/¶€¶ 2Ø  ïÁŽ,‰›U'S8‰v¾«j% Â™ ‘øULTQ§Û­¼o N¤‚üŸ^f[ä6›–HÍq0->È¿-gð ©|àèÒ-äôrÙ”TU¶ÊÕKàko"?ƒMu#"®0hâm’0Æ=k@û§ë³QÑ»îýÜ&¼ìT$¸>GÒç¨*§D¥AK̶¬t!Î ƒ´+â•@h ÜT)”h2Ø(ådM^¬€qÑq)Œ A Ìœ9Š6 oLX€ …³B‚u©æ‰ñœý’¦°úňéÄ€ç¸UÚN_I%÷ú¤ãñL† Q¶SŸ'»zgZî²M*áp&Θè ðú–CB¼BÐà\8Yñ¯ò¢ÍÄ¿ ¡.fG…§%¦8-fÂsçå_©úÑÄ–2î÷)v+â^µGª³ÂŠÍ\…r-3l°v¦$E±Œ«&›×Üæ&ÛjöÁn¿íÚ5&3N#KMÓùÔ‘´¡ êjV|VÔªL¨§5ùS—fà„Í Ãš„0°i"s¶ÝŠºÑ-ç,F×4¬Ö˜i}åâCQÊ1bT §Pad`$ek\XÇ��à’-ÉOë‡iüf±s4ª«\0”ÇbÃè‡ç‰Ûá\á‘8 ¬~Võ–Ôm–-ˆÎ”UŒ2‚|,Þû�ûHÁÏa¶®”€•'Ì/1ºÑÕb.epÄ8´;LxyÎĦ(»0LSÄÙR’CsV†‰ f:÷nòþ–O±ö›³Å~#â¦B•fCŽÇQ‡°ê°¶NJ“ðJõîï®) ‹­Î%ÍúÝy<¶óJÝÖ)çºòlF›C9rü%ejA€¶˜8¬Kµ´88ßµ«¶÷ íÐç/gøò‚ö`oà n5¬;>€u£à8¸m.Ù�©ÀTîÐ+Õä#°üñ  òÄów0€Ÿà9@¸ùö¡Vf°ë;¹Iog<ø²Ü„×$ÿý×›Èåþ-bƒÔƒÿ00xÿÓ㦀ú»IÏô‡ô­ç-ï`øú7¥ÿÒ}/cïL²·þ.ì+Xî¥ä·º¿¡“?°�¬�ý‚«o-c]ýE¤ÝÌÌé}.eVd0€Ê ð³T°šÙ7}|¶D/É@`¿Á›‚K.[ã÷êF¤£L@ñßvtÿÀ/`› ‘Ÿb? ·=„ÃW‰BÜœõ¹} AÕQŒL–²òBÊ—/ãËâ×1Š‹Çw{á?éÒ‹„73’9ãøPÌ¿7Ó¯Yó¨Æ5S¨ƒh³5à舊Éåü@óóPY _‰ø—q=Ì’A“©²Jdf:óP$�P„II(Wq,JF ŠÁ-ÅîbÜh-0Dcó4„…„Ù6ˆÎ²â ¾"…ÉÒnYÅ(’sÎÞ ƉÑ£Ù¸;‚^̨>ú›•ýÚ§so× p›6Zm=ÝsŒ»²F‘hSÃÄK(Øí™8?‡î¥7G0¿Èçkjw}¿·ù'P …[EO“³kÆÔ”ŠTº ‘S"ØÒE\Nî>Ís^J^é)žÎw¿•~ ðqÞ©Í^mZPèYn4ûoÒVq“BÈEÛZµb&(9”’Pœ’:-tŒ1¸‰.Röœµy#إżᚠ혈E Z` �ÛSɶŠ!°%Ù“‡LΰP ÊKFãl¾É/f='Ñgp¹øc¿ ƒo\¾$÷W„osnA3vL&¤kÄp…Øå ú’¶•n!UѨ‰Êª‘RhÅ AÅâØTÖà¦~¶þì#QuƒÙ®âÉ÷¨1˜–cÆ9”2DÛ­Ó’œ‘3G»êâ2E…‘´Ä~…z!1 Å>XìhóÄ–ÓšêÑZ;¸ÙVJeMa®Eò2·™CTݲ¶¹Ü6uÜ7¦ã’F°QÌ~ýƒ¤™Ëº.« G·zs-Iw`U½D¼%=Ä€Ppqµãˆóv¬7aÃë{Ç>?®ð"@¨�vO`ìá�ð¢à§åZÊ›Êûó+íì¸Áà³ÂÍ#H«{«n¤ì|æ^ É“ó–sj�0 {æÍ#o_“m¶Œu³@|ñc½Â¿Ð·ô_ÙLi}—”ïO\¿y‡´/½UÓ3�öo¼Dü;¥<…­…‹7¦þOb&�OЇ7Wßœ`97Ö€Í)�±Ü6)Üàžã…¶\îa¸_ qqÁ%Æ‚p±Ôö+ÊHõçôñÓôqu1kwL³;§ñÁSKj´ý9aô;gjG~>ìAG98÷øoQ‰„¿˜žÁ]…oküð@ŠºÍËWÉAÀôð ƒB2PuÝYÒÌ’ÔrAt^3"s²CÁ¬e:À\èÖi,2 XF·kâZ±ç…Þ®ìK”þ–BM=wÉRX4 íA§D…]qABÛ(ˆg3†á5çeµ½KÃ’°%Dlm¾Â®ƒô‚¡ÿàÚ\ý/”/fäø…Ö­æÂ dîóZ"�r9›bÇ8´’$B¦}fËnÆ•ô‹Ç v,×­©h‰6Ow±õ€+ ³‘“\sÚ|ÅGRYÓÅã#…*† ê:õF›ïùRúc[]÷,ÝÕçņG¸©)êy7!õãg1цjÊòeÈE…ôÙ6TLÁØ”•ÀúˆŠ'•r³étfñ‚SØ–ˆ1e•p„–ÞS2ê/ц†Iö]¾“2P©åî™lrJåh’œHM=Â%3œ"ñÒjˆb^ª1’ÙŽ[Œh…¢jÃâÖû{Æ\Qƒæ%ò „Ø 9l£Áæ¨!)Ê.ÚMä-gL0®ö̦¢jÇ:UkJõ–Í‚y ™‚X‚uÅNÆK¸·ëñt‡¡#Ó.=¥/‹Ë½B`Ø¡ÉÊy¦¸È %û`$PcD¼0’JÅ r"!ÚÄ)£9ûÑÅŠ/¤Ìõåh×'ä<Ój¢Kb (F­”ráj%ã’mË|ÃSæK . b0))Š2e.ÈU•7ñóËOÐG/þüò‚1]Ï$ñY^hø|ß1¿ŽqJã¶·*|t€ön‡N+{Y`~Ø„çx¸äA}ûÿK=~q£[¿Z`oøŒüñÕV2}ç*½8��Þ¾ÅyÝ�¿•§Ý ðÙ›šžß„Ù|ð?ô¿œôÿo¶��~Ë û'TÊøÙ? *ã»ÞüZÙðú(¯ôÏ_§R÷ïÖ1*È‹^ƒà0®°¿¨�öwÄ 0Á!ñð2\ŸmAC2ŸÝ>øÇœÿÓ°jéFŽ Ó€äjµÓifÇ£úô=uøwåB¢FЉ†u®Õ"Tm¡ŸJ!C±É´tØìíØ 3Ù×wÏÍï5‚•xÀïIüQæöl˜/æ@éÁ™÷Ÿ~È¥Au3®ÂÍ<õÑÔe{ -¯–´æµ˜ Û⺓Eœ ž „¡£€°K<ÙÚã}QÀñ ç‘ÇHå³,À ed¬2.x‘xÖÉB!!º—þ³’„§ÛàU–H¨Ú ѰÀþѦ_Gö4 é–Œñ0‡‘oYf”Ä QX—ø}Œ èš.å:f*ZÞ÷¤8[´¬ý ä+¼8Ã3_Ðøt­È²0À7Ò¼ójÑÜ_Ê?ÓrnP†È]Þ{áƒEéV5”|WÏ›r˽«Ò{ÞX¸¨½C±÷]³°-JS “ˆ刪Pö¨ÂÚ牔¯}ÜÙécó"è6å„m² Sm{µ< Ò†rÑFË¢±%Þã9œÏ„ösn¦Ha.‰—Saw´yFÛVvQkW|²ÆÍDŒ…â€}&`õ-–¹¹ÁÔ–ZTX“Œù…u‹–0ßY„Ï¥k„´´{J+qd|â‘,¥A†G1…Rv „©d:ÑRXL(w>o&˜'Z¨¤ÀsÄ· 9pãË~üæÎöÄßCÿÐô…Åu ù%xrÿ‚Ô$žPž—&ºZ„ö^9Ï+ŸÚ„*‹‹¢‹Cœ@´‘RQ}`kˆÜeY¹ ™evQ [ê•’ûÁE¹i%¯1&Z—Н5²D„°cÍ ˆî¹ÂD¦SUI¢!Á«\]íw_«½4Ïts׋ßCyžtI™dB2¨àí Ö÷íPXû1@üL Þ2´h©©/!ÒmrOàÓ¨ýs øw³ð©´B ßÈ–)|óðCcŒþ�à_…Ù0Ø _u$oFø;—ÉþÝK\ì¥Áÿú†ÿz,Õ-@è߆ï(_ß½ñÕ÷ù?ßrã—ûÞQÞ¿ÖK¿“Í·÷q×P½Æd ß ¯c=À)¿ù¤œ"<h"\hËÑø:ÏþÛo²õÔœÃÁò»ìæ*|>æ÷rbìý¿Ÿæ^ln±ÞcüŒ2Æä‰7ÇœôxÎÝÙA &¤˜vç‹uzìˆ^}‚‰„þ¢¥²²‡Wt“ðö^ªSê.áIwH.Þ·!0öƒ]uõ³på½ô< ›:o¨õŽ~}×´ÇüéÇÒéî9Uc,;¿nƼ"Ÿ jÚš‚lYƒ|¸O!™RL m.<ÒÖ‹Rv(á;ìbÌç5¬Þõ@7¨dQTŽ.xŸì¹àwU…Y‡‡Ôâ=“ïp%û¿Í‹ŠXRP50T3a°BTWQ�eçÝ‚Ö:å®dQ8²~8¦àGÔ¡=Všc¨$éc>Šû%h½gzâ#Å,¯ªp.Z&å~Æ&•PªêÙüAÅö¾ø]ºjÁ¦:óð0b@ö¹Øè~ërƒ_#5H¦¡u%BgÏ˼$Io4L=I²+¸"øå–¢‰ BPïökñXÇr4•ÑÅÖÅÚ=xºE ² Ž–h8Ĉ-u!±rÆ:°néö)”Ø l ÊdÄ<•LÏDƒä<ƒí°˜Ùœ_hð²~ʪ]!“X7pòšfˆŽPœ¥$µ‰kγ:D•dW– \¥IN™RÆ´¹¯º/A®x±`SnSDnÌK†ãñôpZge|ñƒó¿Çfö'o=¹µ¤¾N3É’¨âZWT«Š‹mÔ‡5KÏMH¡ÁXŽŸ2v9(HÙ¤‹ÏÅ&’JYáÐ#$±Ú Ç—ÞæÛÝ>t*J²+…1¾¯ñÌ÷éþ&žÜóiyî]½á‡«ëV4‘?Jñ.©ÛD!ì,ÍçÿÏ팺cÿ™ê¡dØ·T ã<w¡Wì=2nJfü8@âà[à?z™Û¡8J `Xë0‡ݾCÁ @@Åa|ý49�Ài…¼€ç?áx°¾¡`¾ê,ÀMx•j³½ƒTàÅë‚Æ8Dú'8¾OXŠÄvˆÿ¿”ýÿ‡þùUÈO÷]èÝ·t®ó¿Èrã^ËõŠ€y ®ÿžÇä_™“8€Û7½‰˜Ì÷—ÛñuâÕx*4à˜y•vÙÂýì£îÖBUüüã-N·È>ùÜŠ3À܃;Ïè…ç¾£ åé2‰m!gÌWeÖV ¢¹Ô"=Þ-ŽÇ;gçãÅG²Âmz®Ïÿe~ÞÕÏg¹ÁTqårÌt%ä+ˆ0Æí°ÿ@åË+D?'ñ…CÖþ|!¥Èý‚„Iÿó½w:¶jÂV$‚ÆÑ­í3®8Â!8ö4”1¦ðóð˜cL2–m‰¦ Bè¹d¤–@Ï1®eaÊû‚H‰ÅFŠ‹Bø²ˆ=DXÖ¥;®0¯p®–Qô‰D('ZK¢¸¦¡ä™át\›%΄‚)vnì‹­À˜_ neጠ^.ø?"%tš¼ º°ÐÙG´ Q亢žÆ÷IØ€¬™Œ_Τä‘õVÑáVÊ_ȹ[Oÿ}Z\>ºA=”#2²ï«\ØöÀV&LhI©6‘ï �<cëÀdG(§€]À>Dd\ëŒG\*ªN£¢äIÐìyšpš2÷‰±¼=äѴ)(3þÁ˜ä§Øiš]�0«?»œhÒ(D¼#D•Ô¦è_ÖXs’n44¹ÈÙem“+1fbË#–PHñŠ›qô¡¤Ò¥¥^)-p]•ˆ–qÁÇÑg …¦BHdID<âxQÀ! cÉ8Û0Ÿ—ã žOU‰¡€#|’1™»—¬êíB¿¯á3_í쓟Ä= °’൓m‰hÈs N’ºâ�ÎÞDìZéݺ8S·ÔÖœçLÂ’iÈ~ËøUpa¾äFt Ù¶¤’­luÅ?‹ËÝ)Í‚W¢®lÁ=µt0ÂL8Ž¥1a§ÆÚï½ÙƒOêØ¤ P3®.‹SC^4ø= ÐXÿ3;°OÕiç ~9ç�è+0ŸC½½c}Ï!¼ –�`ÿªpÈ Öœ�àüÊp/¢"y€OÞðõ öí!|WÐTì¿­…�ˆ-| úwz %ÿƸLÿJgJ?>¬Wç½}çÞøO\ ¿jðþ$0¼ëž  |�ø`X�Àß¾íXmtGI &ˆPÌ€~7vÛíÃî)”Οů‹ß­u>qò1æjÔû ¾H?o™ÈóðU”èÊXÖû‡�ÛHÄ/ˆßÁ2ˆ¼¹NWI‘‹I=ݧmÕx½p3Ñm3 Ô éX%Ô»éb…NÙ¥Ñã:äsm×x¥bMað¼Hq RÆOy|ÈøëRjnG¾Å—‰#+žYÙP¤9& ã´2fGJ\\ÃÙÅÞ +DÕh»qÆ7cøºfÐa¬éû3¹ØQ0Õ¡T¡ðBJ(0Ýê«µà”¥cU‡)s]NyÄ‚�ÒQâe2)ö¨,Âã$Sœ ™Ú�áÜ­ðsYÃÞŽ p#×r§ Uö`)œ(+¡[†#•Ã%v_!ñ®ÞcÌŠM:É-&8‘Q,fób«/O–<GÅÌ–h÷1YEñÚ˜ÖÕ=!ïÐç‹èöwe—ç}¸bUÈV"VgA2…˜ t™ÈB“'iW$ž­³ÆKïH %û€ !Ür†rÅq$É*—‡"¼Ï¡ô,<qËS…”КKÙ vXð•B5ñçW—ïVš(•9U>*HµÏ<fŸÒÈ ”p‰'(,gš\ÈSÇ®´ØK¾ñ Yc kAyÐ<ë–!Ùf³"Àˆ!¢˜«a `LLãìhT °ŠZð eï༤eÀ?'ø®ã„Dlã’k¼ƒø8‹É8O›*?û±¡3])­DF¤Ä²AÃ< qra—!®aE‚«]ʰ¸…CEÉ…! á%2s\?ó˜d–mq,Û"Äè l ÉmÚ]²Š’ö®EÏuê[0+Í2$®"hEì(.¬9÷€ É2NsýüCæ¯üÿéâãåüW!$ ³bý”ÿ<§Yò²­ºˆÕ“/nå“Õî(®wÁÓÒÃà9�U€$ "@{æ÷ÁA®gà·ð ÀüÝ»÷¯‚€–wòõß� _‰®^ÿûè_gÀl~NAT�7ðé;Kë+*çËŸ¬ºï®“ÿv<ºÿT ò·•ÿvô`ýé{¯§} „` ÐÇÚU6ö‹cÞ€@JH†ë$×Un�͇ç#—®Šß¡Üùÿ­ß[-¤õƒi%²¬b3ÈøEô´¶ñȶyòS¼à²W¼Ê¤Ì˜ìaSÓª.6!§1@¢„zšZ¬þâÅã¿èsC{”šéÓ¨®r”ÎÛMÕ¿·û4Rþ@ž á^+λ-oqAb?;w`y(¥<áª<à†8aX4¥Ì1­žg„¹,mk‰waÅÿi‚9ÆZþWŸ).0‹18ï¤á¸àLö$FK܈= oP(iq% 5O$”>–l�­9†D„c¶¬¶4¾1T<[Xac8I9箲z_©Ë̇€WfUəВÅûÎÿ9ø‡c¼åUUë²uBp{™i ‘ ‰P•Uqq9åÈ´q ¡ˆx¾m°pè8Š;F¨©ØoC}Ùåªùý†ª­jµÖ²­V¬g«Õ0÷Páxñ  N(V´_6Öu@Ès’=+ÕEna&RÒDÆÌ“hŸç•VGä3*ºD))¿ x'Õ#^K„ÚhžOs6¸Ô Èå.¹#”HéKÌÞÇÙR�‰9‹�â%ÅO9T-nÔð⑃ˆuÖÈ7ºš ޤ�‡³Ñ¼²¬Á ?’´xR¸FÀ¬Tœ£ˆ­ ö´Neñ']«»¼ça Þ&ÖñɃÑ.¦õLôTÃK¹dÇ>„b ª%dÁ2¯)ÈGN`.k´eŠzHYˆpz£!’ÝŒ:MOîŃµç©œHÚę⅗5GcCÓUÅÔ^^º'3ãâp:­Þ¾õCÈÙuyËÃ�� �IDATŸÆþHjµa3ÝaÚKÒ1Bxi¸ÿF4/ƒK&‰ê#zñ×½ÙÞmÔuc/w[•¡9¨Do“4â„kzæðàh€GOÀþ;–ÿ ðE3Á’†á ÁUu¹[6 àð_l{_ ¯Ñ5�ò‰÷­’�&¸xÛÕuþîzŽ�7PAú–Ëô=“¡Wa¢À \ƒÿ®N€À�ˆÿ1è_¿ë·3¥?Ñ„·÷ÏòŸ`²´~wú ‚×ÁMoZ‡/� %Â�$ôæ­eøA‚[2<YðÈéï^K4¼ÄK%ý¶|T¡_]~óTrè¢5Õ,‚ùb/«†—“š9UÁ¡SŒ`"e2´ÀXHH ¢¤¦YHÛâ=ÂUɻġ £,á›CÐWݺÔËü‘»ûúL8Üémïðõ ]©íª ‚Æ\˜¸Ö Pþ4ùÝ™;…ÿù»•Mðx`û+Äoif" ˜™ÔŽñÂëŒ \‰&aˆ9ù•=Ž5&$‰{1šœ÷e“UÐŒ  ’$BF®©ž`?…u(å•ÀU'tË9Éi…µPg8v‰u†TÉLJ§Ìx†,:{Û—eäs.·ØV(g‹i$PçfaÄ©”I¦ÔMNSÏç3|í§ö^_TQð dwX™²ñøˆ6Xw^æ/O¡Œò ý Çÿ6¾.â͹»<ÃѵñÒ]¿_èS,g>)ôå»=Û³„­{B"K»õeåÏ£ÂÛ’·!¤×±ñA ϖŇû“1<»äŽiî7æ*ðý%)[ëH$U¤·YBUå”O$YH<âm’ÖcUÈž6” ň“+(Æ‚Š@SrÅ#ZbÊñ‚›–ˆV$óàùZx²¥\tK4C–K$)TÞb„Ë^•–s 2äB˜[HB20E‹©à)/Ρy¸†óq™ !+ø¨{Ó^MŽô:ðÄ‘ۻܵŠÅ¥IJ-É-ÙÖvc ̇ùó[00€1ð�H²––Dv‘¬ºu·wË5ö˜U$«¸5í@Òûé.™73oçDœç9ÏÉ:S¹ÆTRT1p­¿rbqq¸«PºÕ¡6|ËI*±8¿Œnâ)²8²L:Veª‹¯ #h9-¬Ê²±m;Uq^¿¾ì—WúÅó—ùФ2Bi]C•w§Ù¬æBÙuWkÙ,âòa¿»™C ÉßÏ啯7×]Gm‹&Ë=#,—óÂÖ…Î1½½Y‘¶e¿4㊥ÍcÓ6í9=ì9韎ùO—ôwXÒ,ªäŸNêOQþ÷¾ê0oþë'Ø;L�ÎZDîtZ3²låt ÐXüÛ3œÿ Ž þ �äôN>1h úù»K[þÖ7õweðÿ <ý-_®ß2´z @Ïæ7zÌ× ýš!þ¥ÍÌx‡üë'~ñ#Üðm#ÓOÔh¾›!êßzòÝ—ñZ»;XÞ>«› �¹†÷À Û×oLVƒO‘½ff¯� lüçÙü+üéÆ}¶Z§þœô“yeªÃL§täêÎnGºà0›{ŸÆ ÒˆyNi>îµ:ifh¬zÊ À2ášÆ¢ù´©RX2##jïi8QçZ'Þ|œ¥IzPâÿ"ćùdO×öìÊÙ³¥Ä³¢I5RÄ FÇ:ÍkÕõgÔ¤ô·¿pÐü//éÇ3û³[KH®?¬edjÊ~‚lྠÐs¸ÊœQÒ ù_ï—'rºrÆkU’\`žH¯ ¶BgÁ’‘*fžRŽ…gE=¸-ŠÑ&Êu0µQL —ÚŸ¤·¦YȺ^¢!1U W …“n¦ý)|˜h¶þ?÷?²½PFòlQ»’VðutžªÑS”ÂùÑ?æûÍ´– cOGý¨œèóú3Ê_Ó§û\~ýj}¾ù4’*¥MçNÜPp÷hð%=qùñ™ÿ0³ rÖ,b¯qà¢q‘”sj÷Ö=ãLltÖ)Pï'²„</M1ä J2ù«8¬ûl - êÌ´ï7ïošë‘¦½&ª‹D{‘b®ÎH­†»p\¦,Ž-‹bepÂm ê`ŠNH%±cÙ§Åå r²3,¡Ž® ñ©h ­LU‰©w³s‡HÄB],šÙIôNDKTåÀN©.ËÚð¨$"$êéDUÉÄ£Í é4—aYvã.?’ñ!¹LÛÍEò’}N®Ç<;¥$8<‰ÄdfÈF]ÈÙ~hZ£Õ5#( ³´%‰ìe‘—Ä 9Q>º%–•…òaœéNšª"”7£e.Úû¤â‚¦6rS)¿)±v¥}Œ9û…äĸÕ–ojaYÛòíBãq'ÿšÈ³¥õF5¶KcNÉ~ ¹÷l˜ÖÒ«§†ÓlûúöïÛRµàzά…µ²Líj¼D¬Ç˜«_ê‡òžYT÷¨è#ð—bW£u’ëæ2çgWG½î]yþDà xr…õsàà¾îv€¡˜W 4ã錰 Ö}kŽ>ü”ró®b«¾-W„ï6Å~3LèíAÿÂ4%¬€[àáÝd¶ôãsBè×Ù¢ïn  ྦྷYÅ3^0Üe�rƒO>{c9‘€’ëðìyÁißÐS›av8µHUBßsíflä#ÖñcÈb!޼8¦¶lE{1HR‘†Í4É™¸Ç…•¤jQº:1:M…¸¢òÌ¡•ŠTFä®هrÈ�e´ˆ&Ÿ/4ô /dòuaÜÃÕå¹7þñ=ÂYÞñxÏIÆeu}«ú> N Ý ö¯Wü/ê‰Ï§´þ×uY\fÆ'àld’”e??¯ù}›ÞWµÈ¼)º=YI ‚cOfIO)Da4+ʲpðsÞ‡tKÙ )jM\[kÎW’¤X K`Œ×•^³ó‹v!‹4%q⬷ƒŒ'RâºT4+Iæ¿Èï "0/›Ûc׃<å ïbÙ³9UÚ°)]¸w9 þeßS?gÞ”gé?ÓôÉŠòÄ××Êië“q.F.g¨œ9|3IÓǹ¹ ^jæi5[‘)èX$âz]rÃâ¹³Ý^½WŒéR)]+æóBåñÑ¥KÅóÀ6ãlïóªÞVóm­Î/ôfÝtM æ’)†¬$´©8iг¶`"–š%®EÒ˜+f%Abrq¥X’}9ôeV<€KÏ$Ù%Q¹HPÙñ0'ïç¡¿}Ìz»ˆ&çT+¤\xaÊGY„v™9V”,ª>o7[¡…µÖh 4xç#;ìç»å÷ -ę̂#óH³ |*žÐf¦ ¤'Âò´ÞÓµúJ”&÷ÙQOmÛ:æÕÝ\ª1èâ™YK²‘SêVtÇ‹{Ž»ªZM¬S™/!Ź–š¿jãå†}¯NÇPjº–‹©›Ú610×D—P‡ ¯±dCË‚z&ñ4ÕºYkªô@Ìi¿x²³K¤D&üIR$r"‰ †ŸhNŽ?³éBo3ÑàDõîúå¶ß‰Çª'òælý‚æËðôý¤xª(ú#ÂÍküU=P¶i_UOŽãz“øAY¸€=Ð$ K¤-=¦¸¬ ¸„Åb™áµDÞÀÞ¿eÿÇUTßM?(±œ€Íw‹¬éŸ»¿áÇëÌ+ {­Ê#ýƒ-ªï|HFù¡˜Vòf>Éϳ¼Ñ’Î` Õîõ);`ç×8ÔXl|šˆôà¨~¯@Ô`8¸ùKÒÖ²Ea·ÃD×yR8ùKâÎ49¯V#ü±ßžM›³êE]jÍÝdÓfY´| Rµ‘qG¹ou )…õ©Ì,BZ’-²–Q½OÑgíïrÎâñKš%ÁȼŠõÞoÅ,Áþ&Æ?_’}öèäÑüôê*¼¤îC*/Îð©)ÿGȇ1Ÿÿ;††_Ïä’¦nÁ#¥Àhã>¶e,^0F;ÑLH(%!!i½Æì-§É¥Ì²R™3dŸÄìAÊZó5‰WZñ­)BO‰ËK$j´›îé¶“‘œîÉ­³ä0jÏÃNápašf¨qJãÿB^:­eÇnßÇsäæ>ÆL¥¢éŒó‹§òsŽrá×5Xb¿“ò`Ô繌a«èõV[KÜÀù´H©zÁö¥¾ìšSóûáü¢ît–S­Wž1vÆéœÙí`cZŸOé"u‘ÕdÕù±")Î9JV |²Q çúØ‹Øå{Ê\¥J£ÏÛö¢èbe\ì<#;ˆ" gJð¦^d x¢G}ÖðîI%MEF“<)¡Ì 6GïlÞG7šÃÂ’žE•SÓ¸ÜdÂD <(YŠ>¤<¹q:.Ó±Ä#;[Ïõ()§…Ðæ¼®¦še›úCfC¦y4©›«vuFDLe™±Øeœl°cÞßÛifÜy1kî ‡aKšœOs“¥3”gýR¦Î¨M¦­Öé–Ö˜V–DI“™´”ÑO%†mnW´N1¸øx=a4[è¸g›Šª²“žÌ¢Š$Xšm'×jy׎Åd¶áưœ)gõI4a+Ð2žÃÉ'A9èJÌ)-}üW6]å¬Wµní ˆ#¯Ò}¾ßÃT1&µCr‚Ç(ÅS×™…w|)Ä[’cÙ®)²8îBµéWšÀ˜G½Žá†= 7Ò'%Ϧû#i4ª ã1<âË€¯þˆ€­Ñ¯02̰3Üà,°�s¬¡øñ'1©‚Tx†o½ÓÓO‚ØáÇ¿ƒþ‰ò~²Î<}7âîÇC”~G#ûj)?¾W{+NÏ¿K³Û‚f‡ùmùê9;<$§^´ÀŒ)a¸Ä­6ÿåIãd‹q:ÞÌ¿<Ü­WÒ]^™uWÕuæéóWÄíD¯O»IW²'×ÍjUI2†ùÈlñÚÍ2’Ê‹}P­¢b¢á(·Ó µ‚„ æyb§y=«©«ÝüæéŽQ²NMsb*òBdø°Þ?|:Z¯î[52™F¶ªüUg…ÄòeKNU9Äv¹£C^f²<ݪ³Š™«jÅ=Ëeʬ‹E„Prö™ÝO0{N>¾¨E•´K¤O! ›ˆR`ZP¢ä\ΩÐD\¡“œ¦Bc+›åäˆâ‚¯éšsTUÍUL¶Šz˜æá@ìC¤DECÍ æØœÒšJ’ÓÍU:—ã–öëþUŽŠ*5Õb1´ML¥SàĺöpIävøŸd#Ïž ]öÁ¶AéÃÓĺDʾÁ@cj5 nþMt‚—pæ“85¯…ϲí”V211†ü¶¯|&A“ÊPŒðꑇ’ý:$™$X©iÑš(!^Yý(«ÿ»oHÛ`éʺ ì¸÷Ñ Çãxº»'Z4ºx…J¥âI ɼ¢¦æu%£YŒ|T¼8.ÝäJ|XÂiL»Y1d!Uб›½²1›H£JaJ̆Æi]êEØ”‰óÜ3•I¼àm[wm'm‡¥Ÿ¦È‡WY¹ÖD{pD7ÚùÔŸ·7§ýÞåRZvÎ6œúEûQÅž“ijÇÓ4Žö¼+€FÚQj ×‘¥‘‡âJ¦:Цª§YjÖ‰•ˆ”™jNunb5ë~GàóÂè0󰯫äÔÅ’Ý‹4Ïûä<εé©…„¾¬©äl©@VMÒ’85zÒÑ0³5rÖaw¸K ¢­’’Ç fqBG½KJ¹•Q,ªCW÷‰üÕ¤<ñâ…;™%ñû)RF’¦‚Þ¬Šè­ºžÏÖÓÒø ¡×+Ô>9/åßÖá?®DÁ´•X¼~Bá’ŸÆe÷òrÚ]гwÓë©Ý…㯠P *ÿ®“pÞiGÆB1{©*ÿÓÜðøÎ¢vúf¢hüy¡oþýnø'ÊoøÉ5ûð=è/ÿƒn†ø3aßâžwrV¿+Ñ*бXÿ=Ê��Þi˜ôFÚú-¤ØùØí¿ßû…hó„ß ùÅ0éËêùÕ|uyÊôá‚j~låÞê›)üí2ü™Èçtu–£6“§e¤/æ>ͧË~±y:xVlÜtd?¯™­®Q_×ÅS3»jJÆjÛ™éuíþ`Áš„öXéS­W-G M™þMeÿp;åZŸ³*ÍÌSLìÀ—cÕÈg…šJ›¿Ð÷-N²(߯cÑ4ò2ù2{ÔŒ¯ Nõ}‰LÝð„Æ©©d%IN}@fAÕ‰Pγ\§4!1 ””"=Í~n<¡±Di¸©“2©²%NÑŸRx$yÆòJ`”³W=oÂÝcæZõ,E“óÙI%×Ii¸®gÊX`2Í,I²@‹ %U„¤':­ôؾ¡ ¡,zÙ“{ʬÒh3Ÿ]Ì 7P±¯VÔ›‘Ñ[ë5eX1Egv–7¤/Rî}|¸g½ÝĺlRaˆ!¦‡¾Oi^‹ ÙÔºæ1eràü¯Ïi9K+Í.HêÜMuÿÊîVaØÒîÖnª¶õfEiÑ&[¼Št˜ZÑsš Ü@½9‰2“›ˆ›5£ƒIAš•ŸtAHу¦¢$\AôË\ç-™x:š•cuÅ O4')Mm´Ö©ìèq”î_<¢]ŽÑõÜ–ÃÃßX{N›jÎVeƒjžJxpË.oÊò¤Œ+ú÷œÆÕ<+ç]Í.…‹t˜|H2$Æ#hÉ”z­¸¬gœ#•âDŠªS&Ù‘Àg@4¤°âú Âåù%˾?5R [e±%’ë´ÒÖoŠª'ÞìɳK© ‘ÏBd'Njéi&JDq挺æžò£à”ÉsÕpyž(ÙJuÎ q‡ºOÙž§QjúȘAÌ‘)[/~¹O0·KÇ«E5Š âŽ;MVK%á/üq’’QÏ3h8Eù1 }~¤ß`N`�$Ü@ R°½yÛí€ e–(ÏÜñ…`>¤w1êmåÜç‹ø³‘÷-Àßü ò7ü8ôoýÛ; ùcLä»<òÝÚ]½ùÁN£wéܓᅟÓ[w;üÔ;Äð (ÀÍë+ÎXÞ”($Å'#2ðÔÓßßËk_çLXë¾úhuº›c³Ðò\•“¹;Šöçg›õXñ™57 –:~H'ïìp"¯ÄŽN,Ž~Œ¿)0¼\»õ‘•Ïaÿ·xrwªI²ž@Dǧ×s,æYäôž›“ÑvÝh•?]­ÏŽí$+c[µæ£¶leC,ñϙ܃ f¯#CÍŸÒñF»7Õ•öEï+iœ|¡IY¿”ücMQ˜™HÞ›Á)EÑK Âø¤ˆnb1K‘5ƒÌŒ%/‚‡·9ÌSò%U€¥dŒœ»Ì åcñιÓþv¼?ØýL½H–ðiÍS¾û~Pr<¬+ïqá&Œòì¡R8³±*,#Þår°9YOž*ŠƒbT|é/?NC“RL6yÈ|*s ~ :s¬¨!¸5u˜¹ªKñ@ÔT¨p™û¥ J.ìZ´ëÙŸÔã.ÿ±á«_µÕ $ãKšÉNWRšÒ¶”ÐÂUÃØ¯Wé^Y%}CT³äfœèã2þÆOûݤ¾êM-V}¿þÀ·Ð\œÑ¹¤\±¹wþeÜÔ^¨/…Šº5O‹¹oˆ, Ü`];­Y‹D.0!³hsæ™S,¸h´ m&Ü9~˜H¶>)Ÿ¼Ê¢­Œ.ŒD$ïÑåܦ†ãa¬²A„뻣%QPÉ“ ,&Í–ÔCɧ©2s§R6´”‚}&9[]è\Í%<©pŽ»´œÂƲcìb+ˆæ$Éj)‘8R1"i³’lÈËiÛôóÓPø0°Ý±ÏZK¢nõ¥UZñèQ©É hºÖDi"ÈCš–9y†?¦S¯xËÛ̪B]¢…KzÞ¢a;C³Óšµ))£ùãÿµ y"“?[æÑž² 甑”-r¤‚—$ïUåt=²¾÷yèú³?}Ú0³;Güo?8lîçõaª1=JgÐ/À<ò•CÐû怑¢\½5ÓÁX£ÔïÂX€#»ð1˜_!(ˆ¿Â…‡›ä÷ã}Þ¦ýC6¬’›þyqÃ϶³}ý0À9pÿýí‚ÿ±è;vë_|Óóü¯$€Õ댇¯×þ—ð ðêšô;Ä@_W£+ ó;œ®Pq˜—�ÐOûÃCÏN OØM[ýMÊíHà#ž ø3{äèü#Ô¸Àº’GÓ¸¾ù¬Mÿ‰,Øõ¸Õ_ñܰ뢣3]4frîœàÓŸÕ‘å")£âÓÆ–LI¡ ©ÒéÜGþ§÷÷C鮓óJÕï›uë·ç¤¹¡º’eÏgY¥:׆].ô³Âb ×\™l´RÄëëîY_É éº–B\Åëª47!V1«Â3 šXyU¤ND¡yT9/93Š ‹b(±äšÓZ@åLc¶.ÅR¬Ê 9/!„eö&M¯¦ûÓŸû/<‰Ó*¼T$f~êýûŒì·¦••[.œCõÒO§mêÛr¡ënvÌÃ%qÈsõx_.éjÞ­?>]\~,+aZ>a£™oªýãÅ\†spš¹Ü%E½]1ÊØ©¡ŸäiKŠÙ‹—YÓi""ÌR²uÓ-¼Š\K1³I36óö‘¥ó\ À‚ºfRÍ­¢´±JéBDíqì/ÃÞ {‰vã·%ú÷NIzdµˆDƒ_û"s¦´É‰^– 6“©dçb3˜f.RRé“"‘2+·TP]E1’Ù¤^»Ä¥$VLÃ¥‰sâ˜�!àŒ–Jp_×^Ò‰,ÁZjeKi¹eYª§Bˆ_ñÜ2º.TeBc¡„+¡µÊ±]ïãÇ9 ÇHaÞ—d‰`sØ”¤éÁå% ­Ã¦DÌ*¢"í¦6µ‰„ÝI&êfÃRc¨â²ÏùÅ6é[kä ’Çm ,)éÖÌûä÷{cr´F}!.M9…,ülU½`YÒÒ¢)P–š0ÂåÑ㸰ÇìRêê’©‹RÈü‚½‹‡³x×?ºWYô•«…É2ç…V:ô¦ç|ÎuTŠó<-&ŽîlìÙˆ:Δ/ÂrÊw¢~¿jŒÒ~˜Ž¯Üí—ÀíŸN ó•G~m(øox_FáǯPÒ÷ðéucÄ °~WÞHáû“$¼Bruôrz[ƒú½¤â[}®Í›QÕò_P~ÃÏiñÎÞâuèÅôóô¨ ¡×£8ªŸ84@÷Vqœàçï‘Ù7û DàT¤;ó8�ù ûÈãÜ`yÄâ ÿâôÿP|rJÝÁ©¥˜?s^›ÙÉxwc>¡êÚÓý@èÖR‹'‹ uÃÿ“5èC<¼¢ÏÎÙÊ‚;×Kk¹!¹ûºÚ9Ý4YAùIŽ÷¬(¬ú0k"åŬۋÆ×ýG]E#GUÍuSˆ«¸¡¼ƒ_GEAö\ª ŸdaO(™s½‰%®êTwõª-´TáŒÄX¢zâ(©ï–¹]V›ÀLÑÑÍCŠ„‰, Wd”q’Kä›ìÊ>B͹¦ªEOHY€JFB’ËΟNûQÛ ‡ù°<TcBCË'±ŽÞŽóS§šf—(#êÀÄ6b¤‰yzÌüü¡#-Oå„rû@j¸+q;}0/U©,âÆÅiÍ‹÷|þ¯ØÑ¸|²üâY§,›nqZ3ª¶f™œ#_ub\ù¦wE§}q^àöZÑ®‹44Ñ+ݳ/˜­ÛAðCMIT5ªê¢¬©ï”ׄ9~Œõ½PE±†iC$õ…6–·u#Âv’|E+í±š™¹¨É™¦y–8f%]lû‰ê¸M¦–±g¡äA‘©“#¥­&†*Ë1`Ç…†§r¢œ ^×Q¦9NˆÇ)Œ:J¸^V)–Y‚²%‡qb,©"6l¸6ä¬R<›R|!!ð…Rˆf³¢^j˨$8·Õ\Tš‰X¦øòD¯¤WÅÌcµ¬Û©f›ºjeÔ²!ØèÉ3AFRJ ËÁ#g±(Ñ›ÜÛ�2HvJj’%TÎ=<ŒË–gªT}#Žãhbòsë¯]Ng©¢EÉIMÙ÷”Lð%&–òz´j‰¨yµ]]*³KOì0„¯þž7‰LVdzۣX7üb5oº‰4¼fŠÛŽŠ\Óª A²¦©ì2ìNÒ)¼}¹Ò¡tXÌúãûÕù@V'?Ü.äF¼‡çÿøM'¼ç x†¡\烆 |ì¾G_� pÀù[ð]Þuw½i–Iõ:+´Ëoï ~��Oï"ûãïÛvó”þG'Êÿô¨×5ãïŒð{Ë÷ðÍ?}Öo¸AÞÓ p¶ÁÙ ô·Ø�—ÀL@LÃòÌ«ƒÑ‡<ÃE�Xà%>«à6 Ž÷÷lÊiœš'¦å©_ùÓ)ÒJŽªÓrZ'-ézf¤8¶‰Yˆ?+õÍ­ôä6;_߇zùl¾ê´ªú ÇVC»þ ö„bõ)º§–^bŒÎ}%h^¡Z¥ŠòBºK¶ágvªò”\ªøQçP$‹È®L¾ÜvI•ôÁœéT§VPª ÈÖ1G—ÂyÅ9Iª°3ÂiÍSb™ñÉ“`iáa­¸”`ÅSO6*iY G™LE¸†áqñ|ö×M&EÐQ“ àSHIbÂ4 nþûå1>ßoJ ‘͆IÉYìz˜V/Ü4ž¦'þ·-ûã¤/]$Ú¯ô’ìF¥™k±È¤7lb*²?¤æ†‡G·{@øÂæªDú’ãd]ôd?ÇVÜnìG²‹5ÁQî:x¡ù¹„ÅdêE9ƒŠ¢¿Ãø"›ÝTuà‡-í:¶ögÇ‘–ãæ!±8ûtè$#Prí "½pÒš]9î³ÿEô¹¾ª¥)¦¢™°Š˜ óÙ ²ã”ØR*.YY!Й廒tê5).çn5�� �IDAT¦!’VbÊÈŒ¨äJI©H^™ Ϋ’xÜV稪¦n”dVÌ/ò™ñœ¤÷…¨¬eK 7‚¯éR&v«ãmäëVµ­Yº•Óò@cž#[œ-ËÈR)6•n2-”Ä–ôù¬±¼]0X¸¹/ÉÆçòÑÒ3®ù–˜8Ëfæ¤6U%\E|èEø‚Í„$bÑÁæDlºàS-xq„a%¤TJöžŠ€bo/ë=â9ºþó¹î\VבìoQÇYì‰<g³5C)‚9ZŸŸWjK ÈpO_ì§N†-[ž £9¿raK/­’EZ$Ö,ÈHʱ~ð$;3ð†z^ÓÝXõ³ùr÷ðéõ‰òpNZí—ôð8MtY7P¿ZÜçxõOês‹½A Ø4à3"Ãz[äyŽ�€½õs0øøõ1—€ƒ<¿.F¼R€nßÀ3¼é–|kûn¾À×`Ûkàø:î?ÇyJþ§ ÂH@ûÝÇþÿƒ„?d“~Gž‹ßV‡Þ:}5Aù×í^ÞX.(P œ{dW‡pð8¾t}PaZ’§gròbwg¤Õ‚­dÕÿ;Ñœi¡X·ËlÝ *Ì,�2ª9q§NËïcPx¡¦B¿äSdÓ§í—çTŠ>ˆ›Å`Qm/ê— òל}xâõˆÀÝœËÀÒÆ¸D}aÛ‡$Oºñ”ÇW¤>(5Ù–4Ît äN„[ÂK Š0­‚Ô›@S(qÀPÒ"£÷S»x)tQŒ?‘\£#tïÄG„% ‹4ͬâD 8*ƒzÒЙ¥¤ì¾¢*S.„�<U=Kô”²Ÿ#9Mw·cÙYö0)wü¬Î]hJÞì Ï™_ɶ4–—uyF–†×B—œ]”ä¦^¡¾`ሠ;GLët`úÕ5y/z±Öüp²¯o$ÍZÀÓDÝ kþË«íS6Ð.…ª¸ÉÉ̽ qH:ñ«ã{$¥l¿îÖ¿hü‘òd¦/葺róf¬Ç;ßóª›_Øúb¾´¦\N~°s=xM© l$Áç'‚u*JB3h¥ÐB¬ªDÔŠ±ª(ŠÁÔÁÖ¬„pÖYÒ½`#tÜ/`t°fNÖp"ZÇY%D…†JD¢]Ì“ŠjÁ”&£"KMÓ¹lªTµ¡S3e<™ÎÔ¢QŠ„‹!oÄfc6B»Bî’›Çé.ZGU–¢wѤR›N¯k•Ê¥‹U,!û "Ÿªeµ-v7öÕ¼l’xî%Æl¸¨Í_ÂÎzmT%Œè*ÒŽËÉEÁ7Ôiйȥ95!©á$YA\ñé�‰Ñ«ö}W˜7ÇžOGqsR+öGùo-÷§L? ‡¯!s–GjY&9Ú%çef¥xJ%¥@))÷À«am¥JÒ3Éæva¤pö¼¢M½Y•²‚ãá`’­ûU¾ª1‰s6é§Y…}Ø~µSºÚ9žù0¡¤ùôòërh‚‰eóà?8áÒ·|t ÊóÖÂ~€®Àì0¼ÂÅÃ×Q…šùɼÀâ1�8—Xüýäoq†ÀÂ÷¯ UI<ãßDLßú{:øé4|l@~K `ðÓ¿°yJè€H?ï6¿±.cÏÿ]{‹où6þ‡½òçÏfŒÀpÀÀð«„ó#,0ã )V ¸³[O¥XûéèmDP3M8¨üøÐK^‰ó†?åùRÈ<³Ã¢o¿ —WTöÜ­Ôí,Ñ›»¡Žœé—†?ˆñÉÙùºiטå/ÃÐjjóùSåζ‡÷)=/Ž ‰™ÃÒ°Â YS³OÓátºaGGZ®L#E¤¸ŸóÒ§ì*/«P™"ºX™†X=#;éuž¹º,"}¯r²¢µ¶tŒ¼ó*&Q…L‘WD RS/RFæ+É… v—Â>3— qÉ88š=X œÚ@‡Å½<Ñǿԧ‘kþ«$„7qlÂoÂ8­L”òÀVç2ˆÜ5T׺´ˆ»­l2J$ŸNdÈs¬3'•³f<1{ Ío¡ÞgO;*«únyîx|4Xu?§aÝH³(ÅèѲߎ泃ýŸÉÞá±%4•Fu$a(‡ÿŠáÉts> O\:³Nð÷‹iN®ºMi7¶¹KDÓEª$™ë˜c >û—tœ_¹G«ÖŽ<u%}O%#œ¶\RÙNeI¤­É`¤^¢îÓŠ†®ŽŽÏ/c¹q#òP¢ r$\V&dhE½„M‡:ÍŠ Ÿ›êI sñ"HM?nk^Ë-óÊÙû™…Y n O’h¢¥ÎÁxš&ô‡CXæ\†ZQS±Â9o¼n`*•â*{é³ÅeŒb¦e^*¹÷Ç ›^:ª÷lõRë‘ÀØAqÒ€ˆh΢c~Ù¨–°W<XnKÛSºâÞqV€@|‘ÖjL¬j*ÞÎdbý2Ñcªîö­L»dœ¾ßËLËt ë1y >Æ0$ÂRbãH‰Â¶Xñª¨yA\&ÊCcÞÿý Ddû>1QæB>å‘$\–Çuºóá¶¶Š+²îaíê‹É\1}¹"ïmë<M°ö¹ÓB'ê³%™=±<_~‹–á£MÓ=ãÕá¤ÍáØ¢PøÏwHÀû¯Ái†¤xþ  ÔÕ3ˆ€Çzxãn'@æÀö"&ÿFÄÎó»€ö�¤×÷·êÐÖŸßZgÛ‡ÇÆÜ¾^½Ï?ïøù­ÒëP…ùÇY'ÿHM¿ú±³¤xÓ´ *`üz(ïrÍ+´Ô þÀ‹'_¿ƒ„½’¤{v£Q0C‰êöÙƒöexxt¯Xø ŽnEer\k)õt˜N‘¬û–ìçô<N2¾jȧº¯°v¯T¸PrH~¨î7Ï6¹NÖÄPåKÎ;]èÒÎÚà‘¬øª?åÆ=5÷+ Îzåggo­ç)('E^u…¥8-EZqRLIÎ[¤J[Ã%1>”µf9k‘Tjɼ6ÒZ&C•G°èKÉTVDªBIô!8(ÒÓ ]1#YiW’ &D !IïkQõ43›Çhc$q¡UX‘$á5¬ŒØñÉs[›ë­~FŒµ¿×;jû/Ù®ª·¥T=mž¥ú²m?n)ìòÄÇ"˜tìèÊ8N1ŸNó–g~ƒð%?÷swðñ£9#Ïϸ’g‚—Å™‹xdƒµ™™]ÙOÛñåÞߊ­<™óJÓrŒ¯â±b4ýšmZl³¹ŽãÉÞ’¬Ù¢É«¶ùú’1õaßMHZû’Ø| .ã¼I—g~$'òÈÓ«™ŒCjøJm• ã3/‰jRsÉ’…8HÅ)jFj+….3ÅÊ©t²”-‘DæIuqˆ)ΰKÈÁSÕªØáð*.})Û™—Ñ‘(A&={EîP²ÊjÍÍ •�=¤äm d¾s¾…Í.óg«)þ4ùýmI)«ÎˬID0F£Í^å £1ûÅs·Z:Ɉâ%×‘m­$fŠOnm*I«v,)û) 1Ëdõu{ù„QR%cÆÃhBªY!XÙÂølY²ZÔÁ0z!uí*¿äþ¹]í I¨Ø”®ô~ìí-¯.忟Yu#꣮”æàËt*¶‚ѼjT*pó![[ìTú¬ûè2 êå!…˜Sp1ÅdëSÓœxOÛSTéÃõ{5½Ôš76E6e¹a´;,gT2ï^zYÈÉûU¤"Õ"RJ<nbµ(ºLîf”ù�‚WSP ü‡�{½RÌØìpx âÞãðîšÝ� @Ák¨ O3þñõ‘É¿þåüƒ•ƒ�O!ž}å'ãÑj û!8ÿTÜ Ç„Ô× GؾqDÿw|ù;¤ª5`¿­fÿèlŒ·î–|=£�øük­Ï2ô©r˜n¡ì'Ø+ Q4§„ôÎïî3Ø/ð°Ò ^?Më±Ç)<|±û¨iécÉç·Íó�¯¦ÓùäVÝ-kç‘ ÑÑ›æú±cG÷j¿/þÜa S#™Ó2ìcoôåÔU÷qé'KìFŠ–Õ2/Hî,ŠDd ´¢jKÓ‡œœ*wŸmb¼•ÕEK(E7òv(9•ã:Q¤¢ t$´Z—,*AZ–*4x–ýâ½r6DaIê‰0¤j…^óÂÃH¦$#]eô  ¤¦”AZµIÅ%F˜ÊPCi7ÂébY†X&S}Z>"«Ó&Ka¥†ä+º|ˆÔ’AÆcÍ?ܲz»Z°®Ïxá'á¸'ÜR/ÏB'Ï^Œ¬§ÕoÊŒ¡ _$Ÿû¨^‚kÐÚóÖis¾Ù|ò4¦ïwÃÕ®žgRŠä fà×YŒÕrŒÕGgë?lº÷TTÇþö…ÿì%¹Q!Ìzþò¤ÐnÞÇZós-»­bïʸ¸ÙGeÀ ›a¨[7cS•k2@)Q猳\éD4bNÁ%j/xvšsê( ÚzŒsWlÜÊ“‹Ÿ¬9Œè™ ´?IŸªöåÜg·¤ÝCXèÈxVâ\1ÎëG–މK›ÖS6Q¯¤…F{–IÌ£+S†w¯²ˆP”Ø/ºÏçŠò'¬d©O¶¸<Ä,2t¦ŒÎs9õtŽ™g&)©ŸÉ®Q‚êIÑúâˆÚ•JºJU¿ÑV²c×*‡RÕ•ÉÉsl˜>å‚ȘHLY’XN+vDåº†Ü Oû¤’Ø…^8^ãcÐgGÝöT7à µ¤K‰;»<Äü ¨BK‚;-¦]ô'›K—¢PV ’Æœ^¥|å^‘kCÖÌgÑäÊÌÏû£Ø|`›s•]‰Gx‘u ©ª½ŸÂÍýý1/*ÒUÖ‡¯ˆB‚’ÀLš+<šêqÑì¹u`ƒÄ4 Š—À³Ð¾Øu#  _ã{ ¿ß¿ ¬²†{†ü¢gG§QfIð¬àà9^¼À‹@c0®»79À·xÁÞGÿhñùg.¶ù?1üxÅüµ”ôú  �ýúi~fÖþñw]Íô'Èæ¯RPxò1è÷r[@þqžý+ÜT@ãQï1À€áu&éžÇ“óyüÏyøm ËT |u×+¬ãa}qdÓ¾n6YZsüó~÷Ç mÂYæ_ˆzÍ?LäÓÞßÌØó ®®2_Í­È/Dðáñ/˜*SSaZ܇´þ”©Øð¢f5‡'}Ÿ=øšÕúªb¤É¦žcÚÿµP›S®—nÅHÅ"MA:¦“$qF[19«f]*Ö†IŠÞX—¨vÅ„ª´Ô\xÉ¥$Q-ƒÐ2çNbŸPiΕHD0 +tòPÀ&†u[ªÊCy/•‡\¤°´ò-£Úéá>w­L¢±¶4ؾL¥uG±ùt%…_Æâ'DGhÉ®+5!B]’CÝhÐÞýû…þŸ/’ôâ“þL]Ÿ/Ç­v{r¼!ô³M+ß«Ôe›2žïÃiâ׉."\éõ"i…;}:%¾yì2]mËZ𮕡®–hÊãÔÞ8cYH‡¸gH,µ=ëœoô©¸PˆÃz r-g%¬ÊüJnϤªIM£Nsf"§GTsÌzL“uTP­mU²à3j¹š’öcê™yZ•Lèrš‡»Ñ¼$Ùñ åò(ó•àub*ª‰‰`EŽä™]Dj1%>JÖ…<¹0—ÇÌD¡¾â cŠ…#‰ÇC Ô_òK©ÛɱÀË9¯–K©L³SÞ!¶Ò“šÊ•ÑJd„ì‹;%bÒ¬H*Z‚KF·ÂäJÙ A&½ã!ZRf*œó¡•šêzÌ2ƒÉÈ×H¥*¡e‚3Y^àÇœO(‚…À°xÊsSÕä\ˆZÑöÀ•®,3×&v%ž÷sñ>¤ÌðJW³™ø¥^6Ðs$½[f»»$»¨}EéÈC*wBNè~Sd¢•þ‰oEÎIï4-k¡ëíjQmjìN°,H3¨R!ÓC¾œ-î›Bö{Sgò9 ÕI‘iu¹fϯ0?¡°l Ý7Ò^ ö#°�H ïàQ¿À䯀ð¯®0þòXáøÛìfµò/Ðû×¹mÐ� þµj¾Z$”¿F³迆/ÿÿR÷&Mv\g–àwçÁ§7Å@Š‹’:³²«v½í_Ý»6ë]µUgw¥ÒJ¢R¤@0�"â >ÞùÞ^� A¤´(³R¾¥›?îþ̾sïw¾s›Þ}Ìbþ{ņŸOâ�ò{…å{Œû8œ¬Ê£Ô(yÿ1`øG�ð¯od€æ=僷bºðÁ¯¼Å‰P‚`µóÞÝ­÷Ð|ýÆ�ý wý€ù �çoOf�a§ªip= 1ûÙ|ú‚MT<øþ9¾ÿŠ5Èìþ¯'V‚¡Á¯}y½×óF÷F èa¥euPÐs¸;K«”·TBõ<EÜ]—ÝŸ ö(AœOåÔ(‰•&�¨‰ê8'?E¿ô-ǪEP"cðœB‡yV†|§ð'mã1Šˆš)- ‚óDÈm¤*SBQ$@ ’€ Ó¹ªkšÕ ø©ŒŽ2¥ hÎAá¢A˜ç¤ Òâ’§.ôn™ X†¡Í¡5YÅBX jɱçpd|Ò§Û×÷¬iË£ÆawÊ!x:>Ø/æôØ–×íúrð“=ôûÑVL fe€YŠÛ–ž%í/ÇCEÿåÏ™Dy×Úýæ?Ðe§¹ûÎæ"\RÞ®à¸\f«V¦uöÞ1VÔÄ£»SCÔŽ=¥‹cŽ,Ò€ÔI\Ÿ:Ü|yÊ)'àæ[“þ Š+Qxî¾:´a‰SqŸ@jð5¯Qö¡R¶T+Ih­Ž|A´ „ŠqáxLca¦Odt~IhRô~²vÈÙB(P>§yŸîYHµ3VÏlÙÙ¹ÎU¤Ø¡2è;KFI>‰XÊ”cb¦'¬âž#Ÿ˜§:ç=UÏÚ,T:Kež˜³`¡óû‰RÄ’eDö,—L.&ºÛ"Æ;Ķ#±Œ‚p‚è‚3~Ä‘ß2Ôbä%ñÄ߈¤éyiÀ˜„0Ó`MÔx½N"†%ÑH0/Ò�=a”»ˆgP¤Ì£`§œ_G|g ²<¦‚À“Æ)ƒ$‡–dŽ€!•è]A´á£²Èg7‡¾'a£;€YÚ)™ª3F‡pôñpmÄW¦|VaAËšó¶æŒ4Ê:Ì– Nˆ @›¥± (eÉ•çU%ã]Y‰ç39:zq²™ Ø–ÄìfïžM V.8­ƒç �@PÏp1Â8‚ëÜìÁÃ샿„#‚»ï�ò›$‡_t�À�H—øó<P "@>§o p­Oo÷?mɇƃ¸ÿëù£â¸ÿY=%ÿKëýüsp¢?ø.y® ê}Jþ`Ø�ñÞ ÿ¸‘”ß�ÃÛ_Yƒ?þø~è�Ì{áy tAþý;êÿGóG� €×=<¹-„{^‡úÊV½â%¼VŸ ªÎß8~<äÕ#ݾ\)Uóß©\GpT€¾€°6xÏÇi~%n 3ú“?œ¤fé°J¿Al¬¨Ö4ä³ëûúv…þcjþc½nºsŒ:KPñ8Ô(Î@mªê Ü@À–†¤Ií—NU$AFˆY D±JèÊðýÂYÑVÈ-pÈk2.(eD&¹RRò­�¥RÈat1s ¥5K$ó™C¤ÐŠËa ™’$ažú¸XÆä ƒ�)%Ÿ ®*�‘BQxˉìÙeÿ«¯ïa3—Åôß(½„Ä^ð[=>õÃ:’<=N %ûP'µO8 üŠ*"ããt;ݧq 7 ®£rÕ‚ž“ØŸUÕg¼üîé$ÒÃˇb§êûð�þY²ËšH±eEù©:ÀŠŽžŸD$4ŽlÖ=”…ñ Dõ™a×GZx¬dnŠsî_sM[#Ç:^¶"ÓÚ•j ©8o—ŒH3#3šÙ„ì‚ „î9#†©Œ³³6¦U€Š2ì3Éè™ÀÊ%ÊúÒâÏ»n¦ÓT(E'LèŠð]-jƒ^ŠmVmŠB/2~ISƒX=õ¤¶1”ä@/U䳡£9Tq–¸r­~KKNMòj�Ú5Wq@ÂBa%¸œÆ4M6/ÒJ$ÃŒä”Ѫ0¡×\ ·ÕØ�[fQŽ6ž0Ñ IŠ#&ÁSë‹Ïaï"²¹œ6>˜ÑãÄcâÞÐq‰°‰^M¹šâ©ó ‰äÍL•‰Þâ@r~”üdg„±gçI©ÌH) ±&°x,b!Õ‚“ªæEÓªf5A›.•‡|Z¸± ãÒD' ÏLP#T/ù©ì¢C¼°*×­ ó¨®H-(‰¹{8ë^t¥„ÓN¾¸óéµjn«Ió¡É—Ðtp–P¼±€¨(¬"<àg|³P_üÛæùý��Fð[€�x�ø¨ €Ð- ·o‹Ò |pà Üø÷ËÝFs€~8ÊúÓÏ@@úï—‹þ«ZÿΙâ‡Ó~p ~ÜzûŽþ@�ì"ÀðÃzÿè?tÈxÏ cÀ�Žàk¸IàXà73¯||#ã5(ûï·ooúû{xÞংƒd›{(¶í1øL’„\¢kŽAª9_¿(H>×t/"~íê™×}RÎVÊLw×½Rj§ÑËó‘TìήIrÚhæÎ5dÅVFwOy»Ù)U·u%çÑÇôh¥ ‰ ’ó–Ňç%^øöÜÕJ–#ä*1g )hCdˆ•Æ*•ÂÒrêq>–DŒG™ŒC†¤¡8 Ä™c™À“ Ò¦ ‹"dÏ#!j0¤9ÅR 8Z–Ç™[“‹ýƒµ9F‚äÊô\È2Ú-À(êkÖ_WáÆu«Xm ¬Á’U…:ï}ƈ(1Sžéy‰ìD54OkÙÒ=q¼cI\íÑëËñ_O7‹#~-¿Ñ«W­ú-ÍJ—(Û|»=M�皉Vç8ŠíË“I!ÏéµsÇGëé|É_fì£s¹§þ¶ðdãš à"ôÛ1õÒþC TO #¢S«ð(M`¤[”â²!¤u]ðÚ€´nR~dw˜ YÓ3d'/¢¥=î+ÎJAÈ´ ²XœG„Ž4¬iB"Û6€y!·!âF?©HMPYÂ4¥<Ç`pN˜‹”gŽ €Ä ÆNYd\FŽkÁv.'7Žñ÷t3S ¸ËK"³ñËÌÍrÂíhè_ˆÛ(È+“(µHêɧ<!6šØf\<à2“SL9`™-a¢:RÕP¢$A”p" Õ!;&¼*D$b3mJƧ¥¤ âds; |’Xs†‹“´¿Â™ÜN†+öº“Ý=Jûê 9]³tÆ—s…®Àµh&"•;_2"Ì·Ê´Ü{Š=“Ipº–˜†‹Ì¢ÞTÕ¥÷L pÊx`nrêu„5]á\*ñªõÊSM¨Lº^ydÐöù̓Î̆³îžÄq’ bzôêš@ô꼃Á-`ÌÀ;ðÆC{l ˆAoýC�<@ s°Æ7õí”ü*&pØ xx“m|àÐøÁßÀÿƒD׿ËD�â'L‚á`þz~ˆ�îï;÷Íÿ€xH7¿xÚ»ÞQpâ�âÝŽaz7ýË>“…ôs7ñ €�´�ð`€î-X�œìáèà§—<}×¶ ?Ãv¼ïàá\AŸ�=W•Y&~JÏ YXL¬ø:^Û|ó2yr:îìWäu O¾DÀTïmÉ1ã:ðÏH­Ë'U`,}".ÕÊ64hékÑî¤ì6œÔkF‡lWmT$±§‘à‘Ђ§¬ö¤YþžØ¢ 9·JºÐâ|Y$æJÖZ±ÍÚ@E />«{ŒM«  ™cϳ‹ðEĹ($ÉCA‰ÐL $OŠL@i¢Ò{=@J EµN%eXBÁÂ&ã’Ó�Só@–×%ŽAÔó®^>ݦ×)꺳,*¨|2' V‰`1N�Ùcžÿ%Ú™=‘O²$’«Ž”ÅÝ/éå‘yœÉè´p§K kT™Dþ9pø‘n̓²Çûy~R"l­¦Knȧ­zV—õ ®³yT+¤Ð£R‹¨ÚÜ–…÷»Ä½°)Íô #¿qûë|ÁÝÎöx¬×h@ßV$«¤Ï¹d «®PD¯‹ÒˆÅL#Æ£†ĽR§(Z]L>qü qÅ‹¤GãRG}ÄüP¼ÅqÅkàgaðdº?º¦³<ÌIb<·E3|q"§±Š^'Æ…×Hr„]I}3Y6ȵe�—Krìæ–£ÊGÔd-k˜«t'mœ‘¦ŒõÈlŠÏ“÷$ÑÌe<*ðn´cŸ(ÅÝNjJQL4Å\ú ÆâÃ)‰„"B™â͆‰X"\•"!EäKñ§ÙÞÍV‹ÔRãÃ`÷ª¤ºR0Î9¬ÒÒM6÷Øôõi©šçCpЇóÓtég›±;׉Ոu\ (J† ‘E ϱA!ª<Ã&Ç€³J V’Ó³J®Î c€…šrѦ×s^Ž©î½æÒ—¬HÕ‰N"$bHq)ÑòyÉn±OnÅa-Âgh2ÿw00Ã%ào€�xðÆ0ôŸ (Âïï…¿½�qÁ·{�Ç!{Ð�‰Ã| ‡·Ñ“çàÉÙW Që5|:ŒÏöÊÄÁ\ÃñòŽÁ3�ú~ÍI?G1¿YÿþýZ÷ÑÞÑü7ò ÿ“<ºÿ6n9ý¢LAùóÎé[ñ 8Œo¼•~Îri� ¿¿Žo‹÷ˆšp��8Àö{[¦ÀßfCxúV ý¡ßŸ„›Kðàyõ©á~èn‡�� �IDATœ�ö�ç§‹vxVò3Bž]=ªyÔäoÙ»@~ [œ'Äø4Úgž€§·zVÍFÛIS±¥›%Ä6Êz">3‚cNÐ~#~ÕÉ'TêB¦ ßéÕcÎÖ>p¶¨Y%Ô'Œ‰�ŽØA° ßÞG’sZ¬W!s/[Ñw”+Û†K‰£ÀÇŒ—àI©ÉÜ×(‘œ½"‰Å&«”hˆH!BI! <$`Ä%Ê=+uæ0É5ŒÒœ¢ÍÙF¤B¥1Ñ:í‹7>L3)ò˜Û)NÇxóÒài¨èÌyæ°5(´Ú2]¡f ä/1œf¨#¹¯|´SŸ¸ˆ+ˆô‹Ãq3çúBQhŽ„ìuIÿ*5(nÙøÏ 2­üu,ä”ïïã?ëòՇݦ˶™D&sŸ·€Ú¶|Ùѧ-¬£Ü?q<ȵ8£H%°9wA,½ëúì©:Ôx*ŒL|“YM•£XÅR<Oi|Ž㎜UªÒ±u.ë’ &ãLeAs".ƒØ‘ Èʃ )T¨Ü0©L dz¨®³SyQ†¦ì(ÊŠ–ÉãèQ Z0¼ŒXßzÙ°9Úã<Ý+|®åfuU³6Ä4/ǘ‡£Í3ñÑž\æPÅȹ’™†À2Æ”`©ð˜ˆD3-W¹”½G=™$-óTûýi!û%f^ÜöQ·¥J„DZ½K“YE.cÅsÑUëXi$Q± …uÂ,{ðft6íÃ2‡ÔY%cq”_W‰˜3˜ÝF¿$HâÂ\¨ñ„pS& n%Òer­4¢3NGǵf^ËHœ… Ϭä GŠ*¬hÆ9˜à&Ÿ!â1茸gY°ÔMS²6Š9£T”1´›têV‹Ÿ¢aR°ÍNV ¢Å¤8³Ç† h±Øzõ¹œÂYºAè¿£+s7¾ÌZ®À(Üï>½nΪãä§]TÎ_?ø|töHáÎ2ûû=Ë~]nˆ÷Ã;¥/Ì ×²‚k °Œ}YŽ<ÄÄ�! Ó/w‰�€ÃN@ï øšˆþ´àóŸü¿îÿ¾èú_W|}îý]ú`#âßÃÖ 0À€þ`9â¡y+|о5K|ËU+°ó`;ÿˆ_¿¹Ož0XÃ| �p‰Y üϬkZÚ|§x)õ ‘ –_×Ec¾ùŽ(³ÅçÚJ!ó”í<ô)ÚHº,¿+ùTä\ä-‹øOpù"ËÄ"é&Ò©èq‡sÚlä#^éy½fMU@-#ëc¨¼Ñó¨–æÈæCÓÒ¼¢Ç¯P¾D°m¿¾Õ‡ºîÚ–6LÌ Pd„ ^€ú}É$�÷Ì: «P µ)xŒ,”ÂH{3/¢F¢"º""Sˆaô O‘; …;ž»TÜÝL†=šÙ1_Sx:¸ûnDÜ WijôÙÚ(ñÓ, ‚NÆ?Éå±ãÄ#°Ö¡k·ÔoøÐd#óÝ;áp֌խðŽÅŽyÛfLzªKºÌËŽþK៯IÆrƒÅøÙÝÍfZ¡Z…�„éÄ<)i”X_‹)%¹År8*~^­Dµhu<B}\g„ò¶uR1�F{,Cp5Á÷-k·5Õe+tËǬb²ˆ[ðÁŽÉs‡¤gŒfÏLœ!±£PÉšd5ñiA  Q¡00˜€He¨á¶ØÀ'À“d6{œO °*âmÅ™c¼)’WëÏ«õ¦j³£?Ú»ÑÄùHcÉÁDµ3ä̺> {ˆ$µèpäŽ`é4]0ö¥ °a̦ÃaNÑ%GJ¿…r®+Sk£^Æl#PH/9ܺpWÌ#(©â+ $Ðæ”¡Ê‰™ ™¤LGf|òòÁœüB¥¨3«Ö̪û’{ŠÇè^¤ñU8¬ÛnG½&éIðš†Èséˆk.»žm5ÍÑnK§}AЃ%hÞ@Ž8Ž’¼Ô$K“÷nAã@ " f €HG¤§i¬'â b<‰"0ç=5C´‡bC1e[S¿)H³üd.€ð¡S± €GøÿÚð?\ÌKµ÷…Á×î”.Š…Ì5ÇlÆûÿº–õh³å’b¯øLÞ,4ðÀ?‚'�0r³*n$ÀKÿC¨ fhXŸÞZI¿iZ Ö¬ßCƒ‡ðûï•tïÔ{ÁÿûÏ…zÛ}äsËãlP²Ñ4”€¿¼šåÀ>‡úë÷_è@�Ò¿~¿í°óÏãÒ»?«�ü@G€€Mó4!OL²´¬ŠnÜòe¡š'ÌáùOI®ûpýyÔú]SGe•wô²®KbÃ9²:$4–£cÎÆ�ÝãKW¤RÙZPÂnˆY‘j-W«Vè¶%VH„%Þf á~Ƙ¥n7ÎÍè cQøoî2ž˜A±i36ÚHÒ ç}O¡BYt¨ ãÙâ¼ÉDk”¼Šå:1`B[Î0*¨Γ"±ÆåïjÖxÌ÷Ö†…£]¦™E‚G_|ŠÅÙ»ì®ŹXl%9qµßb¹)¨Lg3ÙFd¨½‰¨Ì/«ßÑVoB0ÔvJ’Í¢ ˜1švÛhØœ™Cq½àn¤ã”¹{0é„…ŽŽ‘Qð—XÌ? }!ÚÓD˜Eéoq½¹+SAC3Y¹`áqªVðm‹·ØËãÂ}tÆ“ƒ®üF‡p<JuÔ4“â@%!œèäM®ÚÌê‘.MµE닪Za¹Š(£rÀ8GT"¹•å–âÄsDé–b’I˜„zâÆÎl¨ÀNå4ëÄ8á^IDÉ›¡ ,“Kt<�»K°v%¡)!<¢ºïº\ËÌ0rÉ¥è†ÁÜ£r¤$Fú9ŽqTLWÕ)ssBµ6WËcõy©•]ìs\¢§ƒ­3…ØB\ä´'·{ÌÖžmCȧèor¹ÓbSőũZ–ýX2$i,“K),TaÞÛéÔ‡Ðãð€þÄ{}¡W:F ›!ÆÔ`„'ÂÃÞ!Z—5 %PÅZ¾b]Íy~pžBhº½3âÌ3ª”Bö”ÓàŽ¹Ò…U¼%ŠžÜ}qß-s©Â#Â:röKˆ%ÒVÐ)(…¦°5 –Zlx‹7!瑚J ·çnÛbqãësKq¹Ø{vW” E'6»×çìëXûT œ¾$û*xHÝý@¾ºÁŸA®àÔ¸Ó‚£ÚÞTÚž‚#t€ þá;€áóúQ°õU§RMò ¢p @€+ðÀÀ›yHÀ�¿Wû=€ÿÅõôOãÑØ¿KløQÃççëþçÓH&H?z÷K¢ŠáM» °úGì †5²ÞB…Ðo­ñûMåíŸôWq½“+º .ŸL¨C.G‰”Ô["ˆþ6§#ä¹Ð/cj‹åoéV—Žñæ@¾»ÈYŰjÁi<Zàþ)Åբ˺¶¢í¿iÕjYé°æOêŠê S5ÁDdTRôgVJM)!9¯":t-ËOŠN@Ü7ˆË€Ä€àXY4íaZ”=ϰÏÙCp˜/ú8ûè+Ó&QS^b¢™Ê(“@„P™ÆõŠcIæ^mxª1KXB3 гr9ĘSüN= Gà§ÿÚV/óùïüî©fU˜ÄpGCKݵåYÄyLš–´ ¦ˆÙ3IÐ]åž \Šx² ýÂv¨Y‹1 ÌŠ­ÙÐHYÚ‹÷‰J°«– …íçLÓ´óŒ“uLG!ä>¶jëè¬_º+Ò, ¢‡ù3 þ2 xN|kóÍ~ÒÈóÖ ñE-µ´àWÃñŸ8Úa,¢ãhJc¾/„0.8_€š¥aX‰v·k›¶Òë7vÁ‚lÈ©ˆÊë«"*R¹‘F#ÒÓ’ÈÈÕàõ>Q|Jy8ª “XeÄYŠ‘":Ë )„"ÌÐzA"RR±´­›+Y*^Z¬?œÜÝï_3 †Ïór@a¡ƒpÊÞÖê£Â%yýj^»]‘]q@áIXËZÆ\߬ŒÚÿ×vü”¸Oϲ*z’<LóÀqF”chpÎNŸ¨‘×kÙ‰¨ Ñùy¢'¸¡¤,öŽÌ 7cêšÌBD I^Ýãæµ/èsŸ‚·¨”Ít—$Pã.¡˜ºD|Þ>ðNÈ&"þˆV$WE×![â$^È&Ò´£ ò¶¦GTÐ`​MöqêLrÐ~q¬ì±~@ÌûT¼]oHÂÉ–FZTÆÌ'äaWz'6EÏõHÓ ¯ <R|xΰ…Ék‡'³ò³'+Í%Ug·¸Ó’ìªý“‹ñ‰% ܤêvÖ7°üCL§—ðàÿ{ØIîêëýáHáÈ›uŠ5ÀÅú@ëÀ_•Ñ[!4€‚ã‹ï@ù‡;ø}÷Ö�À`€î½áœK¸~^ùÞÁðï .�ö�ÞÌöþ‚™’‡åëw–þoêM}h±€K-,ìõyüÈûZ¿›>¾ð¿‚·ZD÷ƒß ¦kH7�§ #!ÐŽSÑ@Öó”_5lGðN´Z¨'¬@Ú é)«X®ÎµV!»EzŒC™PÈa½X‹b½iEu™skV-gŠf aŽØÕyÆ@(¡„" PRLsq| !E0HÄ!çSâ˜`„qa7Û( t_Aäá;¹=›}Q}IW­  @¥®˜‰ø( O Poó|œfUyE4 4ÔA %c# Ä  ”]ŠÑÅ A´èm<çݱ·õì#Ð^"¢'òIÐ ZÐɧH7A÷™(ɽj剨ðjD½·=Š¿&²¬ jî+Yé¦[2[s±³^Âݾ§ ·¢)1áE%ü)&Îÿ’ýdŽQtº $VG,£X"îõ´=~Ý|Çr×DØâZÜÔÛìúKwz¦J9/9¯ªÍULzyìãì¸c‰Ög ªiÕÚ‹Õ'U³ªêZZö‘EæÌO„ZFätf²ÎçRzëXJ*°xvï»çŸsÏgà4¥­PŸ—àðšçò¡˜xäp¤91×¾ôE£çB/“`¥äÒ ¾¸Øã×(lWøq^C¢®o÷aoñò2Ρ'O_.€3Ø»oܽ“‡‹ú·2cbi1çLЊ ý=tT<©E%ùp2îÞ󝳸‘Ï'¿"Ž‘éÎ0DQår .ÏñØ{ç'‹NÈ9fO"S¦"Ejƒ²+$‡š‹Jª´ã’P5æÑdS=ü7Y?Ýywù€§!‹5Z+¶ÞU2sñü8Žd¤œyÁ­'™³*1œ%±…b] 6³€ïƱ¥#D™q“]•‰÷pòvH!J÷æ~IGÉuSŠ h!δñ;œ’.âÏ"¤“†ø Ÿ™›Xt<†ù˜í«éÅì®  7àñ„š’?-iUä†m±ÝÓþöei€-dG¿ iý�¿�Gàx¤rÙv‘UwU¾…o½K´÷:BC`¨ÎâÞpxS’8€�á°óoÆSÝ÷Ý¢‡÷:+ @�öû3~Nü³+æ¿kl�þoÌ·ã�Ê?Tú³½©· Àÿ„Ö÷�_·à;€ <€õ!ƒÿÆN=¼|7‡ö†šš‚Á×¥\@§G�EÃ|sì_ª‹6¶d×6-;T h¢k{XŠòù·@.ÏëcW¿’*,>%öÊ5’('Ó‘*@vÕëÇ›_7"¹ex3‹.™báÛ®£ÛƉY‡ìSì§!äžd(!ÇŒý)•‡œíʱâàbb ‘W3MH\(\Ë"h¾g¹ò©d$la…^*ÖvP…Â&ê¥1.ªÈb2u¥ø>K ÔäJò8$QlÒI2—`ÇX#xp“›f*˜! ‹ð1åiÁ” “j üóÓWÀ§4 °{âœZV46Šë„ô¼0vzME9þM*×J¬Wµ¤„tÀ ¹'÷Öi¸)ù/,/(+ùšÅP<µ÷@oBšIž«V¯Øºm:Ø—i½x!³a0µŠÒ粇#_?ëì7•†Ð`³úB¨MÆÅÀí^³-D¯™Z¶ �Ça}¶ËZ2.Þù~ý¿ÒJB7y¶Ùéµj®9Ò%/f…(ÅP§ôìâCÎ᳈¹,' “I.3œRÈqÉÌA¸L‡�„C)¸øòÉ>ñO2®³-x¨K±( c@ÔÒ5‡ið%¶ ÆëÙñ´`g8œÁkÊB®8)¸¸ ™“~ˆ9^/èìö$).˜tZ­ ðˆÂ%•! Ùþ“›éõmåtÏ8L£ÔâWP½(ȹŒâé `«@ør\fËsFÅ$l r½ ³’C…£÷„£©H‰°F͆ÉÚµtÉŒ{\V“=+îjA¶œ#£œîÅ‚¨ùRUO«J{ÔÛeùjée®Î9& 4”\ÆVs¬%Þâ´ü® 9ލ<f¸tÀ>sví<Fñ˜ñâƒõ„Ž ‡H]Þ;¸v±2ˆXiHþ­Ê¯f¬ U® QRŒ£+„‘EŸ.e8ÂMQîÚ‘kñ¤É«òp/P‚ÑfZy‡PÙOÈC³‡ÏEÚ­)ÿéÏwþÏà€Cé{ OKª ¤˜n!€Uæbô—Æw¹1áûv„yo¼ý=wCþÈÐÑ è~_+öQâö—ØÜ¿kl°S”ë…ýÑ&ÚGƵ~*ý €\Àµƒ›åߣxùxT.œ»¹§ýÀ ðd¼1¨�½¾P˜òÈN3Ü`X­pYãÏ6켫C»•М&; 6ŽæÌ$²%=èÊZ´ìI'žž½lØNÌKF›c×R‘ Ãg[ú)#¼“l „2HeM–©xˆ¥ì|‚I*é` Π0 E“˜)\#zJñÌàmf;`DªÓªB"hüP,51M`uï|÷4Šü c…¯ùu†GsH1Ì‘~— ¬]Àq<¹LLò `ÎøRSgËœKð‘ãöŠý&-Æ:c¨eŠrTø^Â`‹üæ»>/+ŒøwwÑGz? ó jªŽ¹Üæx³F˜‘iާ2O‚mÊ…ýMXXÙ º£ÐtkqŸ§~cý™—‡ÿ{%x¢ŸËéADÅr“£¥Ë€6$;@5$Æ´,šdì묎Ís_kY‰“Úî=9„î‘fR7 ÙÜg÷¼ªÿo‘ê¢TbÞYÔº5˜.у‡tOꈀsìT±</f…mA‚H)ãõØ"%<S„òˆWaXæüí’˜NÈÐä(u4¬¿¡¡O,…ÒEÊ(Sô"‹š½Ž¯[7›ò™„Ê@–B 35w2÷/“s…1–†¶Ì6Ö6º<]¹šÐªosö|M.W©‹-O^]íÚG“¸Pâèo˜öùØå{®ïjs9/ó ¥ä?#rÆr\f<cê Q‹U.‹ç (p "g2#- gFGÈž /}¤¨[2Þâ_%\æŠêƒdû”þ„ÌE[ýèü@‰uËýþxx ˆ±ªf¯É¢qÉ1e‚bà5® bfœ‚#ЊeZ™@\¡s 2gŠ‚“ú•Œ¯=_¬¾žš8å2ƒø4k¨Ö‰¡Ä$‡C“\wyV4:»*Wº1ÝìÎt]íèä.â+s¸[öeT_v£ÚÁ¿�À°n×—í£¯Ý‘œwüTû´ÈbYHJ)„|Ì�jà�׎ß$áßz¾>Vê>àþM"ò/ÔF<À5äªÜO ø~ɈèßßðWX„ô<|ðäŸ�ÀéÍÂÿûŽˆïÅ-½ú%,õhF~ v·pŠøîØÌ“ýœÃ׎¢vÍe­u¤”ö‡³ôm‡¿èf8[?òWÝ–"ÍÓð9Ü/ÑØÀrD.�(Úb|Åul*sAU åþÄ—)¥ˆì”äˆ& "Ð:Â%ÒˆìdQ4ÓGT5K`+,Fš3qÞ(Y'W@9Œz”XJ­%˜µRJ­[Á* 3Ë0µ“ŠŒÎ¦>ðÚekÈc!7MÝW Y¼C8=tȵå3[ÂhAÎfCJŸdI"™ P%WLhùˆ‰&)ä’øË Ñ[±”\n7E)ÚUH³%ûYÔE_õçæTÏ=ÅÞ–¿H˜dºdt{^­+Å -C¹Ø@W˜àgœ?p"6IfØuÀþ ñà‡ý«øi>ÿ_„j/Øã<ÿ¥„MÏPTó+a:ç39úrl²>°Þª¯ä“/„wåb~rGÄŒjV« {‰ÍÝÓ }ÞÒKŒòƒÚÈß­‚‘Û9ÌÆÄ€EÛŒ«ÚsVNÀ³SMá%O3í.Ê–å(Ñä] npÃs3.[) ÁJ -TR`dX ”$®¤â5ÉbÒ'ÂÆä çl^ܨæÖ‡oS~sñÇ]pÇSŠCuX\Q弃ÏÂ=/c|q5\-{¡ù!ëDòÉ0¦3Ojd³:;Ód8Î/Éqïó32‰þÇ„5Y‡-§M¦:–¾àÅi’"‘JJ6 ˜[3`t@ðÉåû¤W”d >´vXgŸ‡Ò`$“æ‹ ‚\-».ÛeѶÒ'`1å{Ž__ÕjjÜÃBµÁE ³@Á±Â«.`³â>ahÈ&Mˆ~°åß[™¯c"‹d³ çÑ aæÖ×2± ¼–”fŽ{™)0”:Q€ Æ"•¾“ï©:@Ûæ¬sÈóCöùÈz„ o%Jãã³ç·nÿ‹tžÂis Eÿʶm½¡C}EoÊèY¿‚óÐ&„\�á�ž{yc@‹€j  ¬=TÄv ¢…ÓÛ¨ûõGBhÞÕ4>¼€‡·ùa¢ò¯Š½þ½aC ÞÑöõªýX+m p @^Œß¿ÖÀS¸¶?ºŽÿ€À×ôægúÀ@TzxÛf@C&3è{oѲMg|F¸¶EûÍúñåÕõÙÅ'±#'Rº·½´ÄÎVÛ^Û¾¡Ïkâtþ5Á"‚ʾF‰³9Eœ�/c•±à׌ƒ’±¨ RER&1g\È”eÌ@§Ä˜F¥–B·œgU 6œ MëH¡lËž¦�)�I ÄÄñ‚P@ hQ$ç†B tzP4UüzÅS[Y!!# PÁyDÒÂç4ëâ!Çã’’å®°"Ç(b»Ž”é†Ëj%²Ä–c_v+¸÷Çý°6ñB§~G(N EFÝ%_ïÄ'üAs+g…íBaBËY4/Ïò·"ÒÛ4¾òT˜&A ÐíÖ!:U J²…¡ƒýÓƒQ#¾Ú_ìÐÝÎ䛿þ“ÃëÀîª#×Dã6÷æHÃæ.]I1Óã€ØéÍJê“€‰r|$¶ëÍFnsðØ÷KÊ©®©bˆ0Êa0ÂO;ÒÔŒ#$iF8 R­͸>Úa²ã<_•W”ñC(§¡C¥]M+¥DFa•Â69A˜í|q),0É’.Ó XÑÅ(K ñÞ8lŠeåžÄ ô<C›Óí>Á=+¶TüŸ üm™ ƒaž‡*¼X;€4žw·lkÐðíÀ?!pÛêŒHÖžoPHîdö°¨§8¥jÕêJ¬è—y¾L„ûì0w5‹ ¢ªèqÆÌ÷soÏjtN/P‘ËœxLD‚ôPN9¿ªóÍÇ…H"):§,tl$¯ü°Î‹Ï<I4óÉPˆ/g›,jÒ÷§éõó<¦ÓV_TÕšŽDù™¸ ZcXE¢&h¹ÕÑ{:=œ·³R¹62&8Ïs £ïꚆ¼‹²Ò | .º€˜Ý•\1N0PRð)ÊSÁª®èXçÉŽ¨w1¡xyY.tütνÇûš¿pWOÚKqKufvj׫—ˆéDäÂÍá3ÒÈÜ…%¸5ÀqØ�´žy`óç°èˆ[he„ ~P%Xîà4¼Yæ¾)nϾ'OÏ,Àëï­ô´ÇxŽ8 ×áíâÀxJ ¦Å^ÿC±¡¼Ã©FˆÐ_›1B¿xð¾5�à¿QMý64�8–w!Ðá}4^À·p³ýâg®°g� àm¶°=9÷üùö-E°_ÚU3dì%eâT¹Ù=útóå㳋\¡ÛôÝ¡ú&¬×"`—ÚAVé.ÏÜegÏ‹ì‰/U?'W´Am- –ÎòÈXÍ%g”»„\´1¸­ÏÅaÍʈ0RR'ØII™BHSÇ3·[}ƒA#|@àÈt)‚—8"4j)'Ç|hXHÉ,)­•d•¶–œÍ²-²ö¾W2 ’JB˜ A¼·®˜fPÌ8œ ¢‘2.ŠÎª-¨ǵÇUFBÚÛñ…&ºÊb)Û›ü’¿Ë9«Ú‰7ûœ"æôä€W/J‡’>Kdj&·x¼uÓÿ;ØýÿGuh³© áfƒÇ„õyJ/"À¸€ùl}¿•凓Ö3} ýhó’ÿ ÕkŒþãj¿î:ùBú?à?­ìóKˆW³bKÙ×qôùRë?w^ѱ:Ð÷¤F+‘!“ÕÖ¬Ä#Æ‘Ä^åVÈ»ä¬ L®Sœi)™bÊ…%Ly lnglÆ(A&z5Oè8Tv¹XÃ?5]&kÎÙ’M*içli*ÖQc…6f®h8#´ÅtËŪ%®KJý49ß+‹±Àg"­&ôN/¸1|™¹«*“ <JÊQ*kÒtÛÛ»Ù“ÇMV5I E{RÎápd÷ žöxÃhS6êäÉü’/ßrY­ªwŸpòØÔµ1~KA*‚£ÈcÀœËäº�� �IDAT‚TR>­Å¥nUTëä=Ê„¦-·0.>+#°¢¬`!T£$uYWu‰(z€cð¸÷íq-FTiÈcD}Sœ¦øÊ|¶·OS+iÄ%%T¢¡n^дLÞ0RQ9ÒŸ :ù…ÑxÒéU¿¢¯ŠŸç¤Õ$”>©ü<û;þSÈ© BuñèbtÂí¼è)Zd*Ó:E9—&,¸žir÷¯/?;ʽ¡ÜÿÏÝ›õH–œYbÇv»«o±gfU‹l’½Œ£Fzу^õôƒ…éÐ3ÓMŠÍ&«˜¬Œ\"Â×»ÚnzˆÌª¬ì,’½ „–¿…»]ĽîÀw̾s¾s”°.”\6‹ê&ªÆ6XG;«¬ ö%‰LÏ1\\°ÃBá kÝWY"NÐåg]sÙÀÃÝyD,Á¿m4}?Ú³øGÕ|’ÀS°Û‰9Ð[P‡ñ9pþè½â'†½þõ°!ÿ0HäTè?¹àŸwÕ?!ËÁ}”üwÀ0§0 ƒ“�ÇÓ€œ€ü=½SÒ3Ð-ßÃõ@õÞŤe© ø«V5¿¨8¾bȯðp Õ8°_—ì×z^5Â4° Xq–%µq9È¥ +Û:E~ÐÒ•ç³Ñ“ùµÂë6<!fÕÛùpà3[5e’…ƒ²AÈ)fu4Ol²Ùøä£/ HMÉ((-/8OQ NA"¯%ã´±Y7)Z"³d”s’ªHx bÊÊ9WF§¢·i>Åžæ\ÒZé’1Ì„H›Ú9KË\¾P\ÁƒäÙQwâJƒØÁ‘1Lsœ² aJ"' Âä‹"•¥ª8”ʕʥ"Ú2YiQe·.ˆ¬b¨ëS¸8ù”R妤2d¬5.Lü6Ö¯Á?ͺb)ÊûÜv§ý+·»®¤"D“èÉýØ‹˜¬Èö.ÕÞT #!±£öWƒË"ÿe7kuÞ-H}Ò{B_Ÿ‹ñ³qª—] =ᫍ­–/ ògê¤++„! ?i+ì!©!'—Ê:äÂ}·RÎEHy¤"ÓrÌ©"HŽv½bs_é (›¸ìe‘úyÛšRä¹ÚµÙI¯/—œêrÎÚ~І„À\Ÿ¨÷µœ þ±ðýOBR¼­G±T…T˜½ñyvnl’X;­¢ËQ1´¤TÞWns€ŸMövÈ))£2]%Ã8{(Žöä!”ÕZÐ:1GèªÛ:ϽdæªQr#@Ô~Gr¿)Ý¢}^.ÿR7_°ˆ˜ûC_½êÒþH ŒÏ‘QÏ8Ñ—W²\œëUE›—.1¦Q•S]^Jú›Éïî|;(óL žKYT^-´qòp`¦(—´Z¬ã>ž´šêœŽg*½¸¨Ze½­ªó¶š•HB“\YJd’|Æ0¹èdÃr» `Ó~vã‰t½pKr Ñ &’x°ú´%ÃLëiÇóƪiŠ)Ò¤U&,S="†¼óÔÊÑÇ!E§…hÏ„m §!o;OS%õRzœ¯ü/ —·‹øÛŸ·§…ÔW·³ ³üz<›=L.0Ƚz>¶±Mûblúä Té¦äÏigéê×–b¿À2ãZã0£/_@œ0x%Ð÷ÀÃ÷K²†3¸EéÞ}°¥¶ªo>¨„«%lÈxíSÅýÿÃ×;x8üÀèãmŸÃ£®Þ³ß}q‹WÌÏSàéûï7pý£åÆ=nïÝ6AµRÞ­]>½ÓY 0¼ ˜n\§"<\í×þo¯ÆC›þ’.ÛQä`«*†ÒuÞ¼š†³Š÷JMô&¬§q?S¿fòbtzÜE&ùº"¢TÉéLø!& „zpO§9³I Š%Eb:&sLT^KT©@ˆÈ™–")žy ]QÉ@ O½DYb#ãˆ<›½‹Þû\Áj)Í#õˆ*„è’e$IHSÌ6Ð]ÌŸ0DâˆHõÓ¬]ÌiÎlˆÔ™J(ºöº`¼¢”$b§J,I&’¹Z¾±Â&™û‰§XÓ§ô̧EMÉÌ#¥G)¿9+úUV“Ø,EUª& <ÄЯžý›3¾æ>dgwùe v¢1™1g÷ŸAþ×¢*4µÁWÖ—™2b¨\i<¯tCÑèúxÇ»œÆDýRØ3}YIF[â×mˆMn™ñ4^‡áŒlšÔØ 8‘‹ÒÝÈ7÷ô~.CÏG¶¥ˆC??ô9­™ˆGë·vV´ R¨år+p«•¥‘PžŒTo9]<ŒUü]AS6¨Š5«y ¸ìÜ)̹ÖæÀ¡YÍ]É“T½¥;7i\˜©šˆÑÖñÀ¦×)Œ®©PZ)'¥DAƒT)„$-&ˆîOT53!$·#½²»$Wc+ìº ºe‘0cÙ0ÿÛr‰…zÆU[j^žW‚)Õ®ôÙºZ­Úf©Éb{òÙχmoý(¼ô„;§TŒ«º=¯õ’Õa"<ñ¬IunZºg^O¹À¬Çôpê:¹d‚¥P-eFÔ-}Rž·íb©]…­óˆ‰í‰o…Ñ‹›sÛ–3âäÅ Öw %“×Px½„iùid¤# ­×-·´û¼Rô$¥¨5‹Ñi•(Q‘[Û׊¡}©Û#M#,õœ Y!f9r§|àÙWsÖ‚ˆ±ª9÷)Òõ8<ñÜűUö„‹ˆf“žÎ§ÒƒÐÅ$пA] íÙpÝõU ØÃ2Ø ŒJB%“Û@ §~÷ªl�aVûË"B‰ÊãËã—~w@%°"`?€{ ñ¸¥~œ¾ÏR¸¸Ø§ÿ?à¢ß·ƒSáü÷B´Û]Yÿ v~ß‚Çáýøô÷æ$ÞçùÜ�ö@žq>ˆÎ8á òÞ¹éí»û´X àÀo9`ð?Yðé L?{ý»þ¶øÚ-ÿzøÑ_ë§?:.äzÑk:?øÉ‘à¹&²X©•¾'ätHî©Ûl̪5½ŸØØQ Šž9º7nŽ6ÛT;^f­eÊ&Ú¦cLšxî9¹ŠsBÈš+Á©œ'®@› ´d9 H˜ò˜Ý”@( ,1‰ÐˆÄ8 ”†(êf7Gì¢æ£jœ²™º<3ÊžR¢sÈ1ÃV*È@¡¢€Í\©,ß„XN‰ØXV‘É@2(Q‰0'ƒ¯Ib 3K]6>[ê #I6(B³b’U„¿~&wJíÝp[.2ÝP¹ÛC¸Þ™`d<R<³eCÉåÔµèG4¡o ¢ÓèÍ{Ú>TSÓŠÏ×åfL˜è’¼+¸vÛÆt‚N©ò6¤ô)+µÉuä<õžØò4„¢¶ÎP9.£WfÁ¾5fï‹Û=ÝK󙞞é‹Ê);gÚu~½*™.„(ÉÒå&ÑEG2bætpî²m´²¬”lÎÆç¡È~ØÏã.DÊ{j XÁüOuá<¬áoúYØ~¨hÇè='7|YHê5EÁ*™é§yȰŽè^ —ãº!ržÈžã Î7åÝí´hÒYKIBXå|¡E]öËòëFä5ScusòsTk(¡x_‹©•’„1¬¸Yòí å2£$`E…’5g"Î$ÍTeI’†À¨+t#/Z OrÌ,’M#÷•dW+UÈRq‰l2rë{ËE/Ù*—˪ <{ßú¨sÈ$SEtD2ZÅ"eÎ dP2ptšÅI$+¥ÚPsȽ‹­:ã)'‰¬I*¬2Ê:g!4[ÁWœ¨ÄcÀ)GBh®lœ 0u–Ž2v$h¶L“›ÙûNŠÆ¥©Xt_ÒYÕ‹7¬–,:ÑÒ gË( (‡^Q?c/Ôýˆy|þ¢XXú+D‡5Ú»{ssmûä€p‰;ŠÍ)£¡Ø÷;Úw­î|¦Ghói¾ÃŸ^gù?ÿÐð5ž?uŒ ÿ=€á=ÃÜôã'(þäÄ»o_ÕwRÔw~yß¡Âãxáh{`:¢:¾_}›¾4x —TÀÇ‘$£Áÿ&ãd7l»¼›U?ßo÷«ÓׇeûõôÌ‹]°ELqN>ÍܯÙDŽ¢q‘@zPþµj`3jŽËû8‹å…|4è%§‘ÆTM NE›YõH‘B¡Ð´Hé,M8!¼Š'% £J1 .e";ég—‡ ð™Ì!’” Âd&$QðˆŽ'R(Å“JRçLv££ÞHÃP‘”ñ6ô'ðÀšu<S>g §©÷±%10(‰ˆpް‘„'L4ntaD>?çñ 6lùHÌJ{ÉØ³KíKrîøØœÃjÚÐõ}ü‘9¯3×. xcèNÔ¹iËœüÜÒ¿UÁËBXRñ¹(ÎáÂvêquLÔ­òŽŠÎË_íç9Á¦ÿP+N–…‡åôvúÊïÈÒ,D_Wû+êWŠÚø7Û´·v-ÃõÄ[SD#´`a-ûLO>˜œ¢’±¤¨g|r*3ä<1:5bÏÞLÜ{^Iå-ÏÉ{{œÂzô×vïÒôP.-“5—óT–¼cþ4É7'rмÑUg»0ßrW_Õ·ÄýbJçÄ\yµ”^ËÞûÃ|RtI ¢bg*³†ÅIÄ{A›ZVìÇ:^—EÙ.Ñ4ŽG×RV±¥Z¶|,í×vºÉ@Y¬šŒ_²‰öŒezèìd·BM 19€°q ‘F—œæxÔ –C–§Sð”ĨéÌ©·jfLˆu[­ J¡GŸ`†1Y£§õ…OŠZáH1«|ײ{.i¼l´:2›†TÄQ&É"ðÆð5ÉåJª’ô1§Ó�J©/*ñc©ksÑ I”ÀLÄÀyÖŠÈK ñm=\TDËV4 |Œþ!÷”³Hs"Çd§Ý¯2¹›ÙO~_ŸÃ¥ù¯Î?kܸo[]+Âþµ“Wð ‰—‰ïí­pwÅ.®½++Dy7¯ÞLŸÃiDƒÕ¯QaÉWUñw¹y‹]>¹ñ3|“ ºßg}qˆu\| 0 ñOÛg¿;Rü ±!ÿ@Å'Ü×â_þZÁ1ÜnŸÇýÇ ÷Úÿÿ°6}×nû‡ ñp P=’Ø@”ïýF¾‡séZhdE<œ‡>³2À…�¾‚pú´Ùÿ׿ ',¶rÿË…ûåqÃŒ_m_Mª&Ð×Õõ9[²Aê]%Zþ»\]­ ,rX%™s¼ó”?òd½¢”T¢b‚d…XÆXRN¸ä%H‘yŒ2°‚p®KY@L!'J „�@)‡4'æ2ïRò1!ú"G’2&$W¤ìxÈU%s‰ŒÈÞ%#ó2YÌ<Dd‰tŽnG³7\YÈiš}DªV$¯Ã) ÔÌ{d¦-e‘Ó;âEœ§qÇqvBÞˆ¶ Pùx—'ÕÏÇ^lf5Ôn¿‰í™^^Ë<é^„Œ¬2½©x¾jY_•ƒË—rçS˜IØ3߸³‘¨×„åE ˆó‚•†V/“ÎÄÒ·t×ñ;Íuȳò( Ö/ÿºy}õ!Ï&s?†_µþU>üœM‹0Ïó²h3Yñr—»,[šWªÑ’yMª²ŠZÛÄ îq¤aÖA)ÎlΑdÐV–LËWs2v{¢ãÛÕ×]šú£ï W3=²;ÎUè wÿYu<F3ŸÒFjÚÇð{Ÿ¦¤ñLðBÅè–¯©dòŒG‚ùa·¨ÞP¶:c á$²s²ÌªMëÈe'i<—™ë2'oª¤ÊR jëø ’+˜Wt™riͦ³ív¡LÂr±SÚç0$ý{èϹäq9La¼e޹˜çÎæ,b¤ãòv7ߢšA½d<7vë¤-«[)­«Us^'í\8EpHÇ]@Ë*§*& "¸Ê”¶fw“é/„@P,Jž9ñµ“d®j¨\³¤˜ <õ*ú·½÷‘-¤j7R64ѤŽs¯Æ¹éúüä|.Ê–«hS8YG¿6|äÕ@õ’­­trÏ×á>[gæSq~4K+»<þÂÐK>{kV*··BÝ,~?“PÈ·6}E †x<™¿9Œ@¼aÕ›DKÄ×té2œ:¼¹(NÀ�@æÝè½ØnEù  0ÿ¾v÷OP÷#}|Ç. ø 8€øÎ”¾s’vßß )9¾µlýCF}ùOC‹ÿ>~JìÓŠÕoíÓؼwa }4ÇùÝâ @h!'¸0¾Ëî€Øã#÷+ }ï6€º÷Àðþ7Hîsà«wï<<Gy^¼~ýåßn[üÄEéîïNo橉S¿uŒÑ`€]é³§H›”¿ÌljIBĉNJ¶%Oó”ëÇi.ÅÜ*/5æü;©KJ>‰*#Š\ÆHQÕД+)a2 Î)g ŒGÀA�xÄ�KyH<ñÄHâ%ƒ‡q9ÆD“ËÞMLÌ”9g."íI>øˆÁQë¨çyHQ„1欨‰jJqoMr8ö™z?*ŸêÅŠ²‚z:ã[•%3Šæ•Ve²4.’*‘(Åy”Ê5—$lãü2°Æº>å×\ˆŠÝ”«kN+£Ù8-ß5ñÁË<Ë™!ù}ql™B-ÚåPÞÊ žš–.üE£Š)߸À ò÷÷c@-É­´Üm—ì‰ÎëŸ÷·£ÁêÑÁÿïé|Ù›ç°Ï¯’¼&L®*·:ôé¥%bí—K_¾Ø¥¸§Q°�Ž Q5ikY¹,‚cÎ S¦)ƒ8„Þ§”J&+ºŠ­(?sîRÓSÖ ®O)ÿÐ¥£ç sî–wJMºý™`œ.ãòŒ·¥– ÕœEº%Bkôàå…¯3Ò¢t åAª‡œõ”†S©'BŸ±e«®åYíb}à’ ¿¬’p㽩]”…*=øÉ|ˆeS1Qµ÷m´-vvµ+”®ÞãoæÌXcéà‡©*-è† …ñÃ^ܙӄbYˆaîå<žÂ«Ìc(äáKóÍb*w­Î+É¢ ”‰ˆ¦óä&–æMƒ5¬,ËŠÈB—¬QW¼C ~È…SB;’)¥Šðš+xQÖ’B«…“,„*c=I)‡Iw4#R3Y$f½ Á1lWçùؤc¦ài˜Iœ»š?x™§²\TT—Q‘E‚|Mï(æ‡1ñºÐ†^4Ãÿ\¤^Åã…—¯}ªÄiº`¤{Å&ÍgŸŸû´fa²É)§4úpßïAîqrïõî`ñó„·O‘o!€“›¹ [Ñcžõ(<…GÞa\+¿¬ñôå¼vðï6˯×ï …Nrz_ýÝ÷ÂŒŸæüÕ­óÿtnò)ªù‡8çý‰«Þ=Ø‘ý,‹›N¸ÿ à°@4€—Oq8|ëHpß}›úð˜8*÷10@~dŒþx¢0v‰Xáé+<@ |­ðVͯ/‚Â9È/|ª¾6pð¸v3½8ä°›øMdSÄÍVD·¿LqR*¤,fÜxjh$jÂ1…˜àî3vrÑJ}¢ä:òåÉbTyã¦`œT”€º@gG8IH‰3&<a‚F„!3³ìrV)r¬OÆå1çL“ô1Øœ%÷`YÀGÌ1ßûôàls²ÑX0D’ODÌYnuÚfâ ²÷pÔ„äÖ4©Ü$Y:ê|î&ëboι(¨6tã|åIÔ„¤­jÕ*ÅÙ0ìã]ѯ~#P÷áIen$]Fò”å3ÅÁhi3aµ‘¬‹ê…𹢇9Ò®$«V`É„«›‡r1­z³BŠóh.\—¹q=Ÿc™‡§¸Ë¸m̨ÙÿèIyà?ëùã¤÷v{œÜöð÷;µ æ’síË&ñí¶¸cŸóaò8KFy‚$˜‰YÓIU—1$7§ÔG½ŠÌD?%ç=àtï÷á +í…¹@Á/ªE¯¢V-ïB­;öGŸi9wœ¿êçÛE#V«Å¹^гAlˆbŒKâ¬v×)Èdƒñ4²u¤ÙÔ’¯ >_ú<JË1UTÌ–n¢Z‰å¬â”Ëq.wØ0øÔ—.‰=oà\JSñÓyr{4ƒ $Û`¢ïlœsyNΡš>ò?/#«ütìçqÎPÝ'iç²ye]«$ëvF†A³eŸ6\ÄNÈ9D×–QrÁKHU%F}˜œdų䉱Z˲ˆT¯©ZF^eY»¬M^abÄ€ó˜×±XAP•g#]ÒP: Ee18‡Ñ[�âIoØ’†P“Sô©båÂñò·™V0/²o8õ\þ9‘e/ËJÑ,‰ËÄ$2L>;Ï£#™ ‚Ú‰3K¾ÐzßâkbvÏšó³ οéëWXƒšš>"Ú õ3îÊû£¿›ow³æwcž–@(‰Òéw°šPz`øEø®šÏSH xZâÏàO€vþ#Vµ.“›Íáíì�é¿ssÀퟒÅð¯ÄEÄ7?mÁ¹J‚¸÷ ÜŸŒ1îý,ZýQæÑ£kÕå£ ø%ªîÛ#Õ§$Lñ‡ ªÞÌ}ŸoøèN8nÜ0Ad¬ ŸãiÛW8΀š!Œ îç*\¥ ÎáŽ÷“îoz} EqhÒ ¡áâ ã ËUµRê(g:_1œ«@*Zév_M{¥ÅhâCÖ{—ÀËÿ‹…ŸÇü³ŠbâS›™ûÒ¹¬ìœâÎÓˆHD¤%TÒ*eB‰fž†‰Y—¼‹Ì'î™ѤÙ#à]äÓLlá|ˆi´Ûyró–Yúš“h¬A<á'¬šS1ÉÞ(2;³ÑaÁ«Òð8ó)SCrsgè!Ó+ËV)ËÈa$KÍTݶg²7Ý)aêѽ&¢ˆÐCl×M5Ê›1æìc^Db€Ã6ôƒiHÎû[çf"_س¥mŽ ÷š¹|(ˆ² 1õz8ýdºSt,ÔÄòàS¨ÂMa¥+W”è¢æØœß)v âž‡“§Áw°ÕAßL&p6T)¼œ71 Áº¹ì7Ëlêá&¨I¢Ï”d={ìF jyÑtQï§œŽwÛ|H¹fâ\ñŠ´²&uÍx.ZÓJAvÇàó$!dü¼JU‘.ÚJéL$úl= )šÊ9ÕhOÁMCô+–Yb95zà™7´ ±l(ÿŠò$Ø)aYD.½bñ§‰+ béì¨õ,0Ñ@y'St]zN?º™˜y2î«3æpNâgôfÍÄeS Îò‚Ei-xV ’ýI®E±í©ÌyeØMn[hªY ã"õsŸ¼”Ä=‰–Éc½Z7WA—V¨)»Æ»2‹5­ºu¦ê쬖Z<$Ñwrf,ˆÌJä•g2®ø˜V|!âFèEÉf’9™x €¹¤\Fʼï«ÎºÜÐE y!a4Æ(áL‡(:#ª‹ „HØ•å%]FZ§, “Eȃ䆤>ÅÃöÓ¹«:ÙK2ê\öË…©*Æz6¹:§+i¹í HŒ Ÿ«OÙÓ&k+ËÝb·ü¯ò™{ò#ÀGǧÓ-üc,(6À€ÞJ×[s˜{·!Þ� 8�;ìO8AT°×Àî»þ6]àƒ ,8¦Ç9Üï¹¹P>ÆaVÀLõò)$üaÚùŸ´à{oÊïãÁ'ÛD’~ªéÜõ»SØ÷úê»S‡žbüÁYè?äEU:L?«?Ìû7p°Þa€û·%ܯ€¯TXr—îT¥sµòý­Ü„ôþìé«»«'/‹Ê¾H Ó~ ÔWyñ$“Eà$+ó¬æÌ’ΨÃÌÿSŒùŒQ{ióÚpDÆÏ Ë¢‰Cáø cÃgWq«‰åA6”²5“…Ì”F0*’#y&aÎ4ä<fŸã,7ûଳ*0äÑó>æä}å§õè?3C’¨6‰%„ûBV@2ÕQP7Ôn¤Ø;·Ìee#½›âH¸/‰ä$&£ ± ‰™$@2KB(VÔ…¨+aµb´:ˆ+¿P„²’ÌÊÞ6à¬-L"wÛäg+iXX‹ia¼u¦KlLdÀ{ç¯YëšÓy"‚×6ÔÆ<(ú[’¶*Ë^=9ºr{7µ¿¶bA -]„ÃñŒ>*IËYÅfR@®}£›æ§0âê–s§–O‚­›¹|ãyûÊæ['—~¤É}é±äЇ“?Ñ“Dºaü ­xˆéU^åE™xNeáÆyŸŽô’çM%SLÜ3Ò‚rQ¶t „}¥½ºÑÃ’Im]æÈ’éÍþäv§èQ‰õ|CeÃl âfÛM²Øôdæ<ÇRY]¹â?ž‹È¨oã“Ï4•Ðn(‹S:Qz:b`ñí`u«åj!ë qæ]“CwŠ?Ø]ò¨úÿm^ý«z$q!"N2ä’/––Ó£j ˆµ£Ml¬Š®ÒëšS–»8ÃÁL²¼W,ÜñóŠÿ¸(šÄÕ>Ío’½a·ËjÁ! Ì(ôËͳ²ÑLŸÒ@*²/’Ô¤n_®²=æ–+º~Ê®Uá¹ÙÇà|œ<k³T´¤ žÊ5Æ' Œ ¤ÜèÁÒmhŽ¿Bœ:2ŽzÎsa|*³XªxÜ'BBZ$Vä ND¥*Z„ºÝš„*E·/%/ÁÔçBµe*T¼ióºDÌ[ZºÔ¿ðíÿa³±ëÔò¿w³{&ÐT¨º™™»ÛØX a±Úãöí·- þò‡Ãj¯°7ÀÇ*à�¬Ð|ª„½Åá€Ä­òwý÷ï:-ý£¼þÑůz Êü7ã™áþàŸï¼²õ'ñQàï>e,õN‚úG ÿˆìUø¦çÀâ#lÀ 0ïE´Ÿ]ÔF€[�?/0mp˜0½BTmsË +�� �IDATaÂY?l!a \¢-p¹Æ’>œ0ÆNFWNëKé¿íÓb±‚žðFö“8Ÿ×å¼Çâ5�ï ìü…™Lj€')N!a\:ïq2¡¸Wá2”t¥(;o—¼,¤«2á‚ÊL™e#Hà$&çdÎÖ¸ðRÆ”23ü”ÄRæÖÏ,¯Š¹hè¤Z›RN÷vf m mbƒ’œ¤N§»\–s±8j©AÚɉq"¥õ>^û‰:&RZ¦iÔE Âyb2§Y±rÙ^Mz) Oe¯|FŒŸYO›ÞìJN]æv"þŽ,æÜ#žÄ±NQ=6^“Ь®¸,]&…©Dr`ý–ŽßWàŠÕ̩ӫå¤ì"ëW2>ŸŽT?´¤ JuÒŽñ&O$éK!bQoÚ‡™´}-m¿™ä¯N¸¼§WN†¥ÒO}¿áަaâ¾ËxØÂ§‘déƒuóhByÁI‹:ôÁï©Uîál§º)gp¢H†d$ÜTR£bŒùÁªs™¬À¸z4Lycõ>¬³-Ê –å¡= ®9^e3HB¯ötÕyò¿×ñ¥˜ÿ¬×ÏQ®dm*ù.~3{¦µ:—Õº\HŸÅì9ðöD¾>êŸM4ÕS`óä÷:87ysìv÷ çtñŸúôä¾[FÇ„=5º5à‰–®árQy–FE;Wó‘£xô1”ŽŒt¢$2XŽCn¯y¡s“C:Xù&û*û’wŒ/ ÐMËž­ªëj“²ƒÖs£gu­ÚF3ÆKd\‘ËgÅrÓjGùÞy¨7ô“-Ð%a|!òæZª‹tº †0d$MMër ÜO§ô°È§6æÏ³O¦ <Ü ò]Î^J×sâ,,‹m¤Ì³’°¢°­ò•òf É8ÂZøŠ‰IÈÙ˜>süo‰ü/«‡í6¹{ Õ8£»Ü®†'ì³:ŽMvÎÁ¹e7=íJ‚p‹éPCƒaÄ«´˜Ÿ$þyodßWªñqpíùÊ¢§ì‹öÙ oQd×"iý~ŽÁe|º/€ 2À!IÄO{þoxç•m~ ¸WpãÇ–Jò£ü¸ò݈OEåaD)Žîñ\ÂãtÄ*BæF –@D÷¤%Pð{à( ¾DU‚zl-ºÜ”eÕåÛýÍ®°ºê*bµÒlî’ÜIÛKM/ÙuÃËu±¨+¼£CJ/²vtbU >OeõÓ>_Ϻۧò0ßÜóåu·Œn!Gˆû4µÿBÒÂçŸ^'¶/¹Pzyµ^žè†M%QÅ*•RHÊÈcŠ”H¢ˆ¬°±ócrc¶÷$Þ™éU°? €Á‚…6ç:%AH•Ò,Ù=gm…Ïi’É߀†äØ›‰æ,™&-I¿¥ä·–WsЉö R±?fl%éÄ2D'­ò1Q£<=MÖ¨LD ³ª uÕK™ ë6ÀRÂot1Éè)7Êìl³Ë–%¬ÍëÀ®*RB{6™â)ŠRN?XIgú4¾ö¿„{ þïå²ÝežÕYÐ?¸ÑÿJ½|zµ‰+éjæó%¿iÃ4™‰?F '—xß,Å-/þvH˜U¬“¬)E^•+fwÖ¸Ù Cúì¥R/<Yy{cm0»ïÂlï˶fõ³ÌÏ÷ÀáU¿ï;Å…m˨h½DÖ¼àY'hoƒr…J’sKŽÜÙ‰¥$ __œyRVH 1¢Ìl¸œÏžRRâ¨ù [•ãÙ¦.SFñ®ôZHGjâcÚ÷Fy—½Õ*‘x‘™Le=?OÃr$lgÌ0(ùöšNÔðy¦÷\­®ÊC«–Ùÿåäs÷Ú„C¾|L= ZÞ3ÔOÖ‹Õ†³&déÎè*ÇØŒ‚ÜVcÃç$„J‹ ¬&¶ B´˜²uÖecÃ5—¬X§BûtQ¯¾®J­¤õ4¹¥ív£ØÓZ_èÅRJŠ(Í®\S"e# D€£Òœð*³­ »Œr N|ʉ ƸԜ‘‚ˆå¸¾±AµI:0YúSvJM3£’'{ξä¢à"1Õ…øÀùÊ»RÎŽ“&– .ÜRùD›­Ç.pÃþcÁ¤æäæïAÎPPõËYÄìÅx¿¦NKx3þH.ŸáŒ@^­¶¿Yl_0¶:aq`—‡wdå¼�Oð÷�$¡gys…õ5Ô ‡Kì `—Û¡ð¾Džn;êX¡¡Øãµÿx+-ž¾CŽéß`~èN¿Ûò'üŽÓ‡+?¦ òŠ®3àÍG¤AÈìž~ëeˆ °ûÐvþò0íGíô{²a(1^ À xñNûZ�¤›ð;à8S(%Þî‘ ·!dîŠ;·@‘eŽ®¢/4q´´ŸûS¼]¶/UÁsÇäUIžDÏ f:�—Z çuýg1e†ÖôÖF¿/.g)c Íñ®P‡JŸLî‡é"‘äâ|Ê_mè¯}¥ÊÿÓ 244œ~Ÿ‘¹]uÅMþÜa^Q¶‰ÌŠeëþ| ‹Àr´ÈLx%ÜL}I#¡UæÜòÚiÆÈLi—" ÁV‰¶žTsî#”ŠU?—\Óꬬ—¼¢Œ’L”‹‰yg¬Á&F£H”Í='ž›1úÃäÅÉ F²b(Ê[J&äIU3kæ‚ÊLõ:­=ÀòQ„HJž¸È{OSÿ›î>¸;:ÿ—Ïä妪pQ—¨Ï2§‡4÷¶”ÿž±1‘ì¼cþ@Æ×ˆ Uü»Úßð‹×¤y.\¸ê»²ÄÐt[‘¿ô¾ u²1€Ùx4v!CN"Ív§lœ4¡w#e÷SºhªE­Û+p2?ίŒÝ½M‚ÍNrmmÏfs®`’íûnêïrV^SZŒsŠ-“Œ¤úÉŠVg¤¦µñy*=»¤r )”S¦—».®Ìâ~†?†mvÜN¢Òþ*ÄtèçMÇ<z#éÄÏs‰m.Ž©ï"ôX²ŽølsQÖÅOµ€ ÚhÝKCí¶4‡WV†ŽÏ›øg‹XȬ-ÓnѦ²LÒ‹X—öE:šeô‘Q!æRARæNÙrÏÅ׫úû¬¥’ÈF4eS°aúé0̧7ãîÔ¹ÊÓ\4d¥ié…D®á;ý=É¥Éóƒw1DN)L!7–æ˜âœÂÑÄàcŠj9 Q DÜU… BÒ+8Áv•íNüaMæ)»»)—Mæk¹.Ë…g\渘çhÕ¾÷QV’Q×Z,Æe” îù<&ç ¹) Û‰¯u‰Ž&|³›§›@HªÁ'TMÓ’r+3â<ͪùí‡Zq@ |)A ¤·x 줈?Ïâ´\#Sx›±Ó@‡»oÞ>‰g�‡#`/Qp&‘Ú÷êÊûOÔÆïŠÛ¿uÖüƒ} <…º…uJ†¾¿òuþqô¢ÇÔ»éÛK`LßÉX_<†óy÷ýí½-ÌŒø à À ò°j�<}T¦Á­âß-óSât_\>8úÛù¶<¸5yfZ>ª_v«cµ:8}8ºU*êÓçMÝxŠH¤%‹ùóˆsE YŠ>ÉSŽ;g5½#I¯d·\–Wy/‹=IÆfE§fìf·õ=¿3‹ÿ²\¼ÅÿNøudÖÅÜMr_ŮȥçÌú>ø)‘E „0Ö*‘CIXd¤’gq¤äDÂrIˆb‚Fçl>!ŽÒ ™ZJ½`'I^gN<ý+[‚j¤ÙÄ*ßž°t¡Í œC©¦Ð%×…#.'áEÙ¦¼6¹hD41UDdè™ÆÉãÁåcô>Ž´tU1â+-ƒ–)jC|ã´Í:"Ñ4 þv}6ÏîJ-‚aËj„˜÷~K»8ëÿú³¼Z¿OŠêŠ©µâJȳ¿XƆÔy½wwÙ‚ž¾±÷*ä€s'~Aªyä/Üpò©@xÎ#šä:zÀçt˜R¼3ëË b“E{ŒtJ„g6+ɸ,èÔÖƒ»”EAi£i–'Ê×®v”ÚL”8ŠŠqjE:ð¶gž¯¥yIì0”"³g4×Zd.()iMø•˜nhßZ'_b¦âå4S{˦;5~'Ý+¦qObcí¿£iiólý~7»â4ÑÒS·‹®››˜Iq7æ—òå6©¥Ð Ût.Ò·WOÚþÊë°xi5håšÜ—E¥®°Z5+²Ö Ù&ƒñ–Å& 1Ñvq²’&+{NÏ1<‚I£YèóÍÙ²Y‰zIy–ˆ>“yð»Óô°¸{{;çHŸ3hj<#¹®LsŸáê'7Sÿjœ¬uUY^p§ |6sô>™lLÜa•ZæjY*ÇÀ£ãhå>Å«ÌDòâÀ¢Š¹ŽQl¥·åø”·+•jíg–WˆULó­© Z¬´ …,ô³/“»0‰:ÅúÜOÞìøtA±ÅäĽ|8Ý€¦7qætl¸KquÙÂã4#œì©ßCNHÀùþ9ì ð%CÈ ±\ñX1Òa¿KÒ/À °+ᑿü „msMa=àÀÜ;g¸îQ¶ÿÉݳûÔÜ¿ížÒ?zÂÍ-ླÂ'“1~Zè>á­ôýKÔ 6@åD ¢ª ¹]bÁ°ºÃ#(P�3Ðý% a‰9Á¾—4]tŒÿ¾ÜäUÝíîåámp_¤…Kz(NÏæ´ü›PáÄäþÁ˜7cUŸWø•ëQ¦Ž=›-3å°'oÝñµ9U‡]Ý]êuUË—…ê¼ú¯Gó?4¸faÁOè§üùkll,ØÏ\}ã]ëPQ¥¡]ÊÃ|°ŒEm¤‰XJ¡Y,UÈ–ŽA›œ(çF–#èHLÈdÔ<1®ALïŽ!¾FB&6àâÅ?dúW)CåLYâÔH2ÝpÑ“uOu’àVÊÌXf!•>!Ì:1G<}  )Ûœ¼3íÑr¯æŨRÁˆÒ•0TËç™F'­¸7†ß‹³—¼½XÝ�ótêfÉ­a>ö¯OOèrã/´kg:hö¶8çu>W¼ÑÌojçótê^¹|\Ó¥å¶Ö/x(ùñ’튱9ì·&â‹©8õ8å.cú…R¢ŸïD¾ÎÜVŠXväf½¢ÊÜ?ÆC[ RÞ†ŸÐÝ«ÆRNê‚ùZÕÑSÂyÐÇ"U4ËŒª¡R3Ö”Z¼¶„ùCeÇu܉ü$Q¤àS>…ôà‰yk K³©vå[cO‹h$-]Ÿv[6lã}ò¤÷m·n‹ëÖ4ò©`%«¤ªþÌKãØ8Ëä œŸ’™B§rdð‚¥§»IÝ»3Ò»«XÈfÿt¥­´ˆåž‰³Šm–j¹.ÿ_îÞ¬I“,¹s¿ûåÛ2³2«ºz™nÎ Æ@ ¤hh¦Wý�ýýJÉDÓ%’0I`0�¦×¬%×o‰í®îz¨êîêžž€‰¦Á}LˈïF<œןãª;?Sg¶Â&-Ý’LN:Ua‰¤®T�9°úU‚ôr¦Q¸6±oú®Y¿¿Þvz׉ÆXTªPõ¾ÖÇ9ßõá�wsžpP^F4¯)ïÇǵ},VÌm ;Ó…š\TAäÜÑLÖL‰º ñ¶Ö}g,±d«Óè½ê´<Hy§AEKL5R¡9_æÜoŠ_d“EzÝ Ú†f¦™ë¤YyM]»ZèÌ”F»]c¸!/<é)v‡ /¾ôýáÔüýk=‡9Aüë}è>jÖsîÿú…ýÑÆéåWæsˆ äÈ7ê¼r~/@õn�@¨~_.*à \Áü¼Tº]šÓs:­|k^†3ˆÇÃýš?O�IÞΊëö�/ßôÞüÖÒúo˜àþ¹q€N`¾[óñ?45é»Ä»`¿ÉJ‡fß=sœÈ�@P�F� $˜H�ð1@ ¦‡ô·ðøö/©º£½€ø>|Þ$øÀgðRµ?Þ~4ÔÏœËð—y~~ùB¾Æ·úKXp”çwónæXKh­¨¢WyT˧1ÐÓDeE“€/ÚÞ%>å|!wi³>ñ•«—ÿÚ¹÷“x®V·iZ'ÕaçÂT9³)E£ÔJViÀ"“ÃŽr.K0JÊlšŽ¹+9«<…]HK Ûª€XëX¢OdyÄp“‘­-²IÒ†'&>Y£"d£EEŸX0/¢–˜Unª‘‹à�FÆ�äKU(tÉl¢°­×µWÙ›j!0CnuTÆÎò‘¦ÁN î¡äŽšbœ‚ež"á>aŽŸÞ÷’~æÔ“U·Y§ÓØõÓ6¾¶‹ãWJ4@Š ƒùåß®¯ž¸ÕÓu,Y¥™>Ìrk‹âÇfÙ«{ ë8î ˜jèÓh`ÈùbIç>ŸÃg'} ¸š–¶ub‡yݶï³=Ôyxoò0·ÝÕn×£93¸Ûp6ÍÜȨµëüZWª„Âq)ǰ„Â?ÁâKɰT QÜd 9f<fB̦”ÌCÝ¿Øn£2ׂÿwyÿI}}¾\Ükl¼®dž’w$IsEŠå(c=,š’†Ä1MÓ±8¥±¥}§A0B€ÕìÅæÌz¿Þ™• êƒ,,º3gw»n·jWR« p &‚ºEБg[Bj¤a2Ç$²ÖÐ¥íC+Îè¬Ç¨Mu½k¼#­E @¹ÄB¾¾û{ŸŠ!vµY£¬l·YmÙÉYB™Æ'UFãâõ,„#§¬Ãl¥²,d†H"‚&"€E¹[ïœoW'‘!W˜Œ0Ž“:˜\L{ÌR†V+B”lëÏ%WÄ¡B¬éÕ À²WÞæ]¡4i!ŒWZñœ�𰨲ø½XÝ ÿeQ`&ËOa²[üñæôìJ&}1è:©'¯Úkˆ÷`Ò^Ú-h s{=ù{€½;�*+Fñkv©á’׉ÞÌð¨7N}°Êý³‡|[Í÷ˆŸ¾Í›þ]¥uúZ©~—3þYhÑçß~׿}€~#'ãÕ?ùgÞ1Ù½‘^ýF¦Óô½·9Cz‡-²‡ûƘ‡·o¿‚éáyœ¯áᄌ4@à/=¤K���_¼†¿xÐD¯þÍ0€òØžžwé)¾8Ÿf¼ý`KÂŽÊOS3¨bqy@ÕëÆ—ÍS8›­›¸b psÒíÕŽ¹F¼/Ïv±…½²¶˜OªkÉ´¶m¬ÞZ0PT ²’ êÉF¸Æ ㌰dÑNËum>ŽŠJGÆp…'J‘Õ)¯Í¹Ï”¦\É@ÔB íô|톗9ï¨ë ¾7)2ê¬ïÖB(!²‰%">ÛR0@Ë i-Ùšd„”RT©š£VJqOäEÕW’<ëÆZÕ)PÅÚ™¦ŠÛ>ù”~Ìí']ߣot6¢Î,ÆÉì§cXIÿ“æb(YÇú7ËI·Z^vçòåÕKýß½êþK—Ù¨sX–Jg“¼¤M+cµZ7ŸÃC 9.1 ¬v=m·q9KõJH©ÝVŠ»¿#sÕâx×öޱú©xkµöÇö^æÛuwÞ4kܲIM‹!©”¡œOóa‰‡ýpKCê©)ê‚‘SÊ‹ÊÂ#(ÍòE s“Ž~ aÂü•›~¦ëÒïôâßûµz&ø™ï.#¯C¡e삎ˆ‹w2!œòxO³ëbT–Ó0ªèÉç.U…hd²è¿{^`eb¯>2ë€fí$‘5ÐXh·à:+È<b œïQ+cQ•–Ó2X!¦é4.‚Š=3«7¢¹IËmçÚ–›šät¢Ì\(¤tˆ^Ær:ËiÔ•^¹cà5¯tÓ)Ë“¾¤ü0*Ñ×’õÚbc:ãx[eÉœ(ƒcïU#T㺂u&H¼'P  @¡bX€DÐ4õ–4ÊdÌ<-i@LOÅÈR=`UQ¨Y™Þ(£:¦ÒWè•â1§Èd7pÖ¸|”«E¯2=SÓËÍé§íç?­[¤g¦r 3Csˆc¼†ò©?ß?ÿp¼Jñ³ÃÙ¾r‚íýùs˜�[gžL€0”«ýõóõ=ysªq¬G†ÂÀùsX®°õ[z°�ñ›¨éí×mK¿Krøãã†ú5X¯�Ìž8ý@x†zÓ½ûOù@pPÞv£šß«^t�é›®§rN®-¤!=ÂõœÞ\Õ�Hð ¨Sú’Þí¾ÑÛÀ`p‹?_ЭªJ°‡îöÖ]Ýn–W>ÿ{ y‰ÊñI,:‰ØAò„D‹Ày~¼aûËçŵ¨Ö­uîVåQÒ:̨—t¨¸ÊÅE-fF!”P“@¢a£H ’ T$Y599["m,F W̳¶¤$Pk aq.©ÉJÍEdÂ…3`ª•AcÅ"hAÇTJ›jT‘&™ô` LC„Ò7"´ H Ša‘Á ¡Ü™ÔV€Œ"¡ Ì­ÒδÉî&»,,yŒÎA uõž-Qéö}^mλUã—ªê4«×2ù/ =«ûìSFŒ¤šIëSðÚüíö¯·»—ä¶IW󬣟7å^/aŠI|¬ñ"±ee~*h˜!ñ2Âu·>Í/>žÿe7º³I­<KãµéÜ^p WªÉï˃*¯süùr¯ÇãU }²òa0 û{Û­úN‘mFÓÕxªË�y.§}¼ÿr¤}MîYêNu-´žÊR`(ílk†sy 0Ëú|æaš‡G¹:]¹¶$Œø§´ºÓ—¿öЖ y-Å:2Ì0˜ÛÓÆ¬ˆ5ç ‡:Õ‚åÖ-½°Có%Ä•B÷F§Á…Ò¢U]ŇStŠfnž6¾ŠÎÆïµ3\m‰ÄUeÕ&9Úª*1”\T!ßecçÙ4¶QHÚ—V щŒBE°0ÖX^âRҞͩ ¾©1èÑ:?Øþ"`/Ut²SŒOc™”aÃüYXuµë¤°j”qq]GAÎK-lSŒÈK2bÚP# g™¿Ly¢â((ŠëZ$ë¨1BZm¤P-’¡’‡V‚Œd q(j¨­Z™•i*°àäTKZR²¢®”Ò¸Qv¸·çºŽAYXÞK³ýôÓt> óLJÓ5Œ $€þè<«ÝÉßãû‡i”ÉMðAéàÓya‚Ý[„ |ê ^˜l  !À¡Þȯñç<Á“kXÐi§ß�Wü¦¿ÿ](ûÿÚýßpíßAï·Ú0½~ô]ßÙ?$ŽöÁS€à‹ï·Ãþ.eßd ÀoO7’¨��7øíqd[a=¾Ýyð�Ͼ؂ÙÊ41 ôW­XÚü©„C€Mìwµ­`f²º²m­en ÖY:?Ûü:†_¸ú§�"\ö÷åNúsk«.ÚZûxÙ()Å¿"¹ç´ª‰UzŒÇrjƒtgè”$ekµÑRÉ2…l8v ƒ¢³$½lA«9„ãr,©;SÚ£`Á3U éª ËTÍ ¶be¥ÊKgç´<•£Cè P4œ”)§ÀKäV5+ŸbQÞDRªx)ÚFvž} &*%UEhÈ ­¤KÒ#’BÌÚIE’èãÇRе|L:é„Ó\,zp"$:ͲN[€Eú(üHÒ4mãe!Ÿ¥iÈ»gÿ1d›ÿ´Ñg:Ã&x:ôe¡ýÒ™Šî‰…nhSNøåòêjóbÕB‹°z/^‰Í,5ÏÕ…iÙ¸Y÷Z´¨ò"]>¤G“¦Hõl­úu#?’%•;Îm*&Uh–lŽÅn†Ûq¾U/àîT}lN$}®'‘Èq‘Ρ¡Ä1—8³·Æ¦�÷2ü¯ü·?òçdÞ,Ô+§b?€¦9ç<Ϲ®EÀå§.J4èÙ`ÛD-‚¤a(q®Ö\Ùæ´ÕÇÀq[ñÜ5^Ò‰šR}itž}~¬IŸ5›Öw–ýU_(]ÄØ—bR'!Ãh=[m‹jÅ JTùDBÎ Œ ”pL¥:áP… ‰l*.W\BÀ0r Š“ñ V³> œ¯+Ù[F—E¦:‡D˜ºj˜ÖͶíÖªë¸1)Ašë4ðH¸œµò¨šY˜l€¢Yg§îd¾ÍÓËrà@Hb+Rðñ}N,µç ],Eª¤¦¢Š –€éH}(yU;WY °�(€š9†dò©ÃÙyoN¾„³RÂmÏŸ¥‹¿KéÕ+@_!?\û¹43Ì ,�BÂîó”‹y¾dmc · " Ÿô|:8¸·�`A¨á¦7¾‡w@° †ßA Ï®Á¾«Èþ!¾®?f½aúÃ(䟠3€ �åm0úï÷ÊÝØ7Jø×âGPž@=A;Cþ60Aþµª©àÛšÕòÆÒnàycÖòÏì'õ‹{8Lñ/(CÛpµ6OtÚ`Ôw€Ÿ,<@×°ê2KÜO©¿ ñjàmjžNî”›ÏòŒ/»´n9¹°^T Y´ ²–§£˜îòxŠë÷}1`iÖ–nÒZÇN#UŽ©T€­4¤–E)îœéŒha€9…ÆKV‘8ÖT+,@Y;!K¸±ÅS¾Ònn í²LiZÄŽX€"ÅóÚV6E[-Qv5ê ™1ƒ©Qœ š%{¥´Åâ XnA‘’Š•ÊkTX)T‰ÀY“B5:÷ºéÇs€ÔÔáÄÕ6ή۞D³ðFÒj÷”X u ‹ˆm³wŨ”§Ð]ùÙ(̵yhh'GÒÏæI®Ö0×á‘uHÚœ$áI ¥€*J/iSY–)´¬Eñ/ÓX«¼Õ—1+…‚ý±šf0lT»jz Pe8NÅŒscS,ÓT^Rºîܨe;Áñ>—_³ûj{!œ¹œµ-•ËæS¨4JZQ<šâuà~#¶nEÍβi[$ü³%Ä<3½ Å.ÑÒ¡Š3eÛ¨¦:iÄG:(²¹Ù­Lßµä)l8QÀ)LJ  -¥Õä5Ê_h}%áŒa¥¡,%å)Ëã]}̜Դ!¿ÎJ·Z;¥Å H6f��� �IDAT€œ²F ½6B)d eNË=ê<Ëcª]‚62º¥ÕÍQØ’­§+N…÷‚ô$Ê(ô °ãf£š^n:j`TÃ>Öú ¦ r‡Œ¤ŠH1‘i¼´û£,~™?IÓ#ç!™¹©BQ2ÞisbJIX”:QbQ’Â0rÓ¹•ICHÄ5TS…ZO9-Ò‚Ñè9ÞÛ©ì:Nd ¶>¡ög<j÷Ë“H±¶åæ?�K˜~ùé¸1s\uÀÐ#ÿ5Í;H—ðÑù ¼úü«7uêœ@$�Àåøl^•?‹aþ(€ |ú.¾§ò¸è·–èËogÿYhÑȲïÌÂû¡†- Ð|/Âœà……m4�ÏA\ý~²Í� °¨_·?…ömÖR0¾Sz:§$ ¾XAñøô=pä ]Lqìc2�ií+X‡‹õÕiW±4õ”2Ô�²öé¥_Ð÷y�xà×™0d_MNZÔX·=S»u|Ú¶O”8@s<0±„‘”äÒK™j‚ú™Cvv­,8‘:*ë± a„ôúd'tELµZHmÊÚ*좞Ç*ÁDRBªÖ‰ne–¢3éVR_±€ Z‡ìöb9Ö\ÎòfŽ«ÈÍ©¶©¡áÁЬ˜¼ÌIˆ»„ª©½âYgR\ àÂ4W4è:¡”–^!Jå#šQ Q²ôÉw J-1#_Q‰r|µ´¶éØF3Ný±V#ë`ÑŽ@É„ÈÄ ?Þ•l¹‰ë´Ô„³šæ²~Þv’th6­¶+äæPnn0Ò$Ö£~¢ZqŸ>.G)l½}è‹RycÏA×ÔuB40ìm‚IAß±n4ì]7Ê@ËÐŽ4qkõVTàäç*ÃC_wn¼ ¡b4©yLe†Ù)óÞìÒm–g2}r[¶Ó=ÎYÖ³ö¼Æ&})Ò/#ÿ8ùÙjç:¡ …Þ¬S">9Œœ”2"0Ecx*ŽˆÒ]ËýŒt1@[§Éza{zê®è¨¦;½iå lëM0ÆB“i-‹uÖ­õ25V“æˆË4M³c.FΙu_9raÒ[nÕÊFAˆTjN*:O¡ÄÇIß6~Dý¤>y&ÙºêWf^ÔÜGÞɬr8rŠ,&Ýh«×ì·¤×Ò›ìDár»,T–â£ÁÞš*¥N Ì 3{‘ZR)¡t9#”·OŠ*J©=7:yWb1‹iÐ:–wgD‡8])âµ7ÚßaL’ëª4eÎ5Ü)fc ÉqͦÃ|+¿:M†P¥IÚ¶éÜðVÔR!’ôŸÛO¯õW�ÁÂ)ÁÚ]A+a¨ýëGãU}¾!ðæhû8l!n¡ÙƒÛÃDüè‰�ý"=@Œ`áÜÀ”�Œ„çåf$ ð€x i?èï}‹‹æä†o2ºÿ ¾?¦E¿qÈú.=ðæMEØ¿QÚôvòöïsçi�‘@Ó;¼­Ýç@€TèÞŽ� àb ¿˜ÀDH�f ÛF]l¯.Ÿ>é›^+ص³ÛÏ“y_Ú÷ÄzCr–U¨¡ ¯4þ_Iÿ+úUû#+ÛmÑ·Éø2}ÅeLzH§²¬4ȳ:[ŠJ^@íT•*3¥‰±èΘf%MÇ*ZL}ã`5ÑäÑîÜ*¸<R×+]T~’QYI%¼,®¸0 %¥jcYzáÊ-ÐÂb± ¦ªñD@E`)œáF¡ûâDÔ†;ÄIÉ  Q®Iè„ ­TưF>åôŠK‚ÜÃ⪳3!–ž#ù©YN#ë_ݳA¡s±9OÔ÷ýŸ\Ê—>SY<ãŠaZ†(ÐØ^²Hi4çW¾¾Oøâ <=álWåT$øQéwï_ކîÐ×÷òËü7c<ÿ‘”-¦þWiýlËf/UØ@)››Ð¼lAGº³‰Ú?”Öäi_“¼ï”Øn€5jª+Kž3 Š—RWqÜîSx(ËÕ®¦wÓêÏ,}w/Ùšˆí]9áY1+þ¿ü¨>ùó žPSŒ«^…‹¦J…°,;ƒÖÖ@Û> b-m›ˆÀÙµNŸ“—Þ­\^ï¤Î2\j ÷Nk‡%«iXes¶ÑÏ6*%‡÷¨Äûe§i(H²×1.xר@ñ” ââ¤ô²uM½™ø^á¤5¤ª&àyÎ%h/›&C?™6}m(ºÃ¨…¢AIÐ#{‰Ú1‰"£öZº«é1¦YÎÕÍNwRBŸ EÒ2W/о˜&¡cà °(¤ÎmnK5B©z¯‘9“Ár!µ¦¢˜�Š2>GW;·’°±ì ¥c^ƒ,g®C@B³…¾â‘ÝåW§öæTõ=ö@-äjç:ŽÜ¿*—à.vn½À|·j?=5÷@Ie¨ÉðÜ� ¬ö@û¿ÍfKÐ0ãôÀ’†ü'  ðèuI¡<ò_ ðkðMÚR*ßõùfH�`x@Â÷+QßÄývÀÿ‡gtÿ· ÆHÿ¸+8#ÿž$¥òšÅ·—¬†¯uïï¤n|§®õ€�8�Ìñ“Ü·O‘¿ë¨�»L‚A s)R¨f¸��_O”K'ÐÎ?Sê=ezl¬\÷kR%4©²è³â7YЧ0h!oËz N?[ï·$5óbü¤=òF…]�.T)7¦eÕYñ”'èQ4’:gµµl Fo¬]‰¦—Út²@Pe–ÅKf–å÷nŠ ³b©@@ *ˆU­$K,PtD€Rتf%,z!U5bd64¥1-õ8JZ©³m ›•°]5 �d•*) Á2# º‘U4¢P â”ËË1”˜YAr(q§WYò®Ä&’~ý˜³Ë[57OpÝû~£•¨sâ×9n²èKñ\y‡u£†‡f~ï÷F6¡»¬f?:ÙÎr´Ù¶×ø8È»Žœ§Î©«,>u›C§ï¢(P~°ô˜óqøqå³3â(m ÊfýÌ|ô¯Ï§“ùâÿøêµpíìîø¬»©²Ñç6­vÆH´*ãñ4ã$»ijÌÇÓËåâ?‰úïD¥”ÜŸþ Ïÿ‹á§ymîÖ³Œõý~ ö£¶ûŒû¸c1:/ç´Ä˜F¡’íšÐ4b«ú•ج…õKà[�µŸ}M}Pb\ÛjŒÞ<Qº/¥À!o.°3`/vl¼`Ñ:hñùúOvöã:cnï­¼žàaˆx'ë"Ň¥u*mä#JP òTƼԸU5½,7[˜¤Qjq , l¬Y¶YøI© ÈB]Ô•Ѥ„],ƒb¬L¢¨X4 €ÈYÄ%p:ù´kñ©4–œ$[ÑÔ,„ Æ4 {n&ædSÄ‚¾ÈÜê¸!2Z(D¬"WA`XU« vuÒ5n-u[ÏGV1'YsD¹Ï|b¥…Ü*³M¸«% ›ÇùL'ªÍt‘$šêà É@ õ e±«ÑáOŽpy� °Oð·�Ú& î¶ðð@ù|¯`Ÿ¶ Ÿœ×6pÐðüóþ×x[Ê�VNÊ@J?èó=½ múm_Æ ùJoøáOû?Hòb—ûÞÖ}݃tzçœ1ý†s{X�rè‚üÎS4ïÆ šI¬#Ü‚Éô¼>\ H (€#€èž€5èV‹Í\s[ôʶb…“ètK$§ÂE-À÷étÜs ÅÍ›XVT޲›ª¨WÇh›ýÊ\¨°–‹’"ªµh®¤j„C©„Aß9·n|»Ö褒Ҹޚu5^i ’@1p�RKåüÜ‹`ÕTKeŠB)©¹V Å©ƒÑK3!Š ”*áRýÁ¨ê±kf-F®$Æ9³˜‚#Ýj<—ÜX,ŠÔ kᔘ™Ê"`">¯•4–HÉåcâh ƒ«šÀI–2–µ¡N8ý,òkW6j‘«Ü BBeQùœËZЦ©"á¬djPÔX?áÌL½ÉõD‹,ZYú|lnŠ'€)û¥¯Á³ß|¼ÖþÉ™[Ý賋º5\Ô£Ö#\0lVaY6¬Wºý÷ÿãOòñÏRÁÿóçŸÿoÿõ?ÝÚEatîö½"Ϧ÷v¡6hÛnÛHfiº›¢ó´Rì( Ä›WòÇÞ›=ø°ü8Ô†fõD¶BÁÙÙœ@AíJXïŒod!ú ­”"ÈÏ95“½š>‡nËO l£iå³°3‡e>Aûs¾náFSÌþü šÞöUºqeÊ“¬«UÇE®W›õ¹ßtê²»êÍî€éá(b<¶%Î,ï�dE ¥3ÉQ¥O"-EA.s€Ç’æ4 @]ºµmeK; d‘³I-�]Q98ŠT*é™ÕRt‹¤‘¹ÅŠÄÊK(ŒŽËºc™ÀÎJÆb²EZ»æ¹Q—¸‘‹š«*¹F’©‚0•²ˆ™R¥±Ë…Á˜¢Ï¤ð€^ FY¹†Ä‘Ôd} …ƒÊ™²–à<äÖÇnÉo1;, ð QäÆ êÂÁº M¬Gœ‹bûe÷Øûg„ ÚW},oâ—OÖï_TuwÇ•âÊÁîÖ ˆÏá` Xà÷À #w[y˜¢OÑŒ ƒ¸D0 à åuÙÝÂL�[û–Ìéð›P™¾E0óÒ»Q¯ Ä\zƒEò›fÎþf üÿ“Ò?þADòá§;€ ðf ¾k¥ö�øô_|ý7ç„m‚W×oG�½‘k�žOp½@Z¾V¹gH ,�€�¸øHÀv{j/µº@W_s²Ø(j*_:•Uœk•`­|ÙæÃÇñâÓN³u>—,dNòä9›ÚKa³J‚J¡['*W¹®!ö(4Dª†ÈƒrÚhkÑ¡3¶÷Öº ÄZ(@ –X  ÉV³2ºˆ¹Ô,`BÑ×$•pZŠ*òd"V›LmV£‘,Ü ÚGP•¹3Ô:Ñ“)žEƒàá •U¾1NgàšÛR‘D,54Ä.)O1k!¢(• #Ĉ"p®œsBØflYGÄÐæê‹%CéEÒØÏÌa!-çóÈF¦¶ÖHééÅ”wÿ…2›«¼j ‹ÔΠWƒ¬LòòNn¸]žy7yß pËz”m·­°vV3íÎì­ÀÆo3ìºÒ}òÑù'þ‹}ðA"1úuyýúþqœÃ._´,íà~¬—ŽxÆwv럜áüþŗ᯿\M£} (Ï¢ôË\èFêºJ[4Ä$ÄÆ¸‹Öì˜J¹§|8a[ƒãá<ùƸ}®F‰»3lpW€Ý’ì¡Æ%-ºj8¥S~˜Õá6Ó«–{½NÇp–.äv%»³ŠÞ=5ÜÝ) p·íüVkeØ $ä8Á~|V¹™åê £Õw‘Çqȯ©LÎxRb¯Ô•Fš9NflÄõŠZä‹Sd&pRroø°Ë0ÅñÖJ£Ô%Ö\«<Ôê-DtVeM'¥JV,/^yc¨ˆÌ5ñxâa¤pR~Kº/Ú³)J. –R1-9“)ÅÒAñ Šl 8i¹ôA™šË𨠉Ö!…Çm®(#iÔšG ™Y¦Š%‰ DÏ"£n…MŠrp§àînήë͘ ·³ž ¶ÖÓÓ'MxbÖjÞta[¢vt—ñõbax ðÀOA*˜eRýui×C¤íãé f‚KW+ེÿªìgh_ÁˆJ¬%l L¯j‚åw@_‚t wé;:ê׃ο‘WŸ�D�cþX´èô—~‘üAU©ÕefüæmÌÒ™ÞõÇ©(Eù ܯÞ(oÞòÃÛ°¾òÎÀxxpÝAò�Ì-Žhéc€ö}uáìz•U¦e<Œ_.2njßiªn·DKÓP–"xsððAx脳ëî¼aQ˜^)oÒÎ蹇!Êêäì.9èt$cK¶ªÖ,âlª1¾)! RZ¡\•%%¨ ä œ†<L¡B™”Fé=Q+/¼fØ‚êŒ$kŒ·R r>:Î2•Œ>y…Xg-©®ÊM55hX�³ÄÊu*4DLZl$;ÈkQ4’LRTì<òBY3/™•¤RQUÔ‘Cåha€¹‰ØÌ¢B]$ESg¦iþEt?9¨ûsµÖâeù<£ålÆêR„©˜"UœÐçuIU£)3Ój!Uª*ÐB”ê Ý½�À¦ g;by¤ËaÊ'=º"Lm¶–«Ÿ¶ÙÛ¨› è8‡áñ4>)Çeå]ê,Ô?ÑÐá8c… Õë­©µiLß·µÆ<lnï‡Ç½OgÇ©ÖZsº_7îÄÍŸS'öŒnKbÅgʨ¦’o‡†‰?Ø Û‚Rœ4½¤å,oŒ°"e‡…†q)Ã^&ßÎò\N7ÍãÃrêfUûg">V¹ ÷«ykmÈ:˜9š€és{¥º¼6Ò¤ÈM¦åçWǰ,¯WTéî)g ‰Ì1;ò@Ñu\\vE8Æé(Ž©|º™“ÊMäÍÐ"©vm•æUÑs˜šzØH(u XyæÊRË …Ph!Ð)ªbÖ! %ŸF¼{Y¢€õY^ ÏyXò]€‘²˜r)A ²lLc�HÖTQ³VäIõÌŽsU)d­„Ô «’b\D.|Â…S,T„zL1Î}V$ÙÂìM)\ªäìÆÌ2ÒžŽ”ü,ÐÓ;{GËæÄº”g/›…[JòvQ‡ózÛÖ•HÛ‡×mŽ�_�¬~ 2žêç0AÓ^zéGV¯ÔznS:wQû*úW¡‡_Ø_Å}�s„7ã’ÿÅßÁ±ý;~¯3°š�ÒÛ ù›y?㛤î?¦>¥?àL ú„@}×m Ãõï5wœ½2ÐTؼþÖ4—~sã÷v§`Ͼ­m½å'ùý@IÁõTØÎ°ý&l}¦¹ø×Výìäz':φ£4õ‹þjí×çî#í?6 ÑèôÚ<h»·Í¹¼Ùô“ôÔÈ ¦¬tQ0ÒŒ"y\j$uày±xg– ( (#ç•‹’ƒcUIÏ<Í@¥†±.e.ó±RÕyÆ’*]€r5·À=2²udz-@‚6¦UN7Ä;ã!t<ðA‘,@\Êj[®r.T!¸’%ÅŠ9ˆÊUšÜÙ8•RkDA™T¥¬Ü Suˆ“¦@\k’YØå)Câ IB¢RL”PE®!Úr²0C¾Y‡üÿ¬Íÿì%5¬³ÜD}•3—¹JvyëÒ¿ µu²âQJ˨–¡eçªðDÜ탽hpuD%ÊÊR!Ìáa&¤×P×'± îÅ¢Ò¤Ž«ðôr>ý—¿€Óþ¾xø+äô#½•~ãÒ&BùŠSûÕòä´—c†§æôœ6²sªj×n./d‚‡ÍLñþ×ú^ªQš«Fª—Ð6αV»™«Ä*¨R»JÝŒ†Lc…±„Xó4Ű×8H!dœç»y<>žôãbrl½i»y h£Z B´œrg¦N²'%„>Îi¤û©ùë¯àç̽J}Éc^6òqCñDf p»œÎµ~ýè:.íX½'ê*8̙К­ˆ•Çá>äv.Ëq‡»s¯Pq’ÛˆT”Y(’’„“R+ ¡ªËB+=Ͼ,½£QX‘'†9 0­lÚü‚t0¢ršìt*ÇÁ–ÎaÒ:.²¤¼ÄV9%ŒÕÌ!±Ž¬­¶B)#¤et˜¥ª(¥–† gã}‰2Ì('U•Dzh®œ©;±(‘oNpG#äÅÖ\Ë®ÇùY¼ùUZ–5,÷ððŒäNà#K\üÄCëÓ%<¶kôãbV½¢fwÿau„²‡ÐÛgÅ5ò=w6=Öp8J8áýÐض0ŸÃéW�å :9€ìï↷ÿ%JÀ Æï¢âüþÒ]žÒo-.}+8W€H�û½øUy gé;!K?ä}æo„�~Ûºù®æü»¶!�P×ï“Ùòn‚UŸâ�÷ßõiŸ,� ÒË·1®k�HpçýöÃÍÏõs©žU¡‡zrÇ‘ #—MI-}~5¿ì›ÿ©kW­¹ÿ»‡áÓ»³×ós)õÆN½Â>h#*W¢•@¨çœu�)/…c~Üuº¬D«³ÒÒ)á56M´V]ˆÚ1Æ$Bk¥ ¬æV¥UsÉ\ND†«`„mØYmQ1*’ •rÊdc¼Ì(°èyJ½¦µLVƒ‚P¥£P÷nT­³pQJ‰»’1-2”¼ÒB"ydãÔd2¦94ù±dUA̦;USÀª ê"[YœB)ZË` m+VåôÌj+~$¤Û[[dC¸Ôš%3a‡éʧš}\OÙ诧\΋mbmkãSrZ †âÍYícä2Ï¢+ ÔêºU†CÛµì:Ã&›2SÝ /)ž"6÷L/¾º9 ·bý:ª¥×ïwÔ©ä+à/̶ú.·×U ËýÝÍ~ §|~¹Y¯Á÷»ó\IôIŽ£5ÿÙÏ×Ï\ÏöÇ] Þ;{ááLñÅÂê:[''w­Ø˜Ñä¤6w \TwØ»e/& q_†,k²ŸºXd¥ ‡Ö@E’ée½{ôþè›cÊ&ò¶­¶Žòäàóç&’¥Œó‡2jJ­Ë5O¾(ót<Àöœ)eëZÛs’=ÌObØ­íGJè)íãR§|Ü—&pÔÒAJΡ@¿–º1Jz¢ÞjQ4–!ç9")a­@gpkе³4M-’©RP^x-s„³WL‘KÎ1Uàd![®b”5Éì ·ÅHYWHNd,�µ2JK©ª Š\AÑÄr•°Hœ\-¹@ 9Òá�ñ¤¼éš÷´w>M91Q<æ[Sïd˜:’6ã´züU}\ÛÓ˜ò f |ˆ~.ÃòÑí¢åÞ}¶Yž¼ïÏdšO6žŒ»w=ñÐÔ*¶æ&úzýUÕ_ñÙ�º‡ N¦|ƒE3À÷:ïh•o2÷|-\ÿÆjþøò”Òos|ïá›ï‘ß½pýöi8½ ¾�-äá[Íà·nC|[Tj'Ø,p H�ò­–“œ¿Î)¥ øfèÒ:Á{°yùønP¬ ©0Ço‡Ó €àØyõì'«ÝûÕŠ%–SžT¸ñÚæi6¡:êB_Ç?7«'­±›õ4%wŸvEV¼OþÖbÜ´¥æ¥<gìòÙr¸Ÿ¦ŸðÀQ˜Xó±¯G©º\â<üÍ .`µEÝ+RWÒ˜0„Œó³WÉ,¬„Æ‚( àZ¥Š3ÄšUI  )¤´èTÒ²³M±+u,²¡a*hQHÖöVÉkÁ+ Aã•ÍÌC]¶(:¢ ÆÆ”²ª1ÏMŒ|²ia†‰ jí:Ô”`ŠA�eW¡iôíJeø+I; áÜVb„¼ð”\K-X .ÑhιúU4r[úó£Çš¦ÒÒ Œ£­sªÑy+¿W§¹žŠô«´òî|QãÊÕ•Ù³þr¶MÙÊ4lÕ+Öô ð?Güw·A.vý…OççQìb­2`“ëÊÆƒYéö¾žø4¨Gº+­Ðë(Ô®¶ãúJmš‡´›Rw jã´2Ôf°w‹úBo/Ui*†=Ý·µ:úŽqhÄs]+Cœî—ûëé¡Pl•Ïgò±Ä¿W‡¥Ÿ´û§*ó®ÇÝ/&¹¹9üù“»ž¯•!ng£Ì{‹]¬>„j`°»NyµJT.G>†ÇØ.DêÏ hç7+»bÜdf™P–ШÎhI&d •5f¯3×8[~ÝÊ®iÎ’iæµ­îéÀа’T;..«NÊëØ‰4"9ä”ÑÂù¥%\ö)™´¬¸ É i¨9h{PV`´âQ’NX´°FI§QªuÌ…äŒÜ1iTh(ã©ÎƒP’W+JSÌEóÑ7ç ÑKm©è…çqX†‡ipTó+»ëbŠ>ü¿Ü½Ù®%W’%ff{ôéL÷ÆA&sªìêV ]Õ‚I€ú[õz׃ž$4Ðj z¨Rf™‘ɘï¹÷L>ìÑLÁ`ÉHvô’ÕþèDZݱ`k›ÙZ¶"p+þ*†Þý_¯ÛÝ! 1\¾€å/`þŽj˜^ûÍÓéÇÍm£6v¯Ó#JÞˆ©åúìZ¨]¬�%´ñ–Ü2öðÈÛï‡D€î‡ÄÀ,À5÷Pÿ0¼³³üoSûfë÷ªOïån 0�ÓwU ÷&]Œ€îæëœEGXMÀhøzX÷W� .I À …T/�hxóûˆ…«ŸÎ^U?Ÿ¾À»ôRf Ÿ–ƒZvŸ^º®äéy}.÷Sýõ£rÙÔ—µ…®ýÅ¢~Ô͸ytµ[A×Uí£¦^ Åܔׯÿ® Þe·¿vÑÓsW!—¸,\+®´)92ԉĮŸ!½ŠóÒÿ†‡ZŠ'ÂR#.— '0k•FcÒ IH0é-N)‚ÊâDWRX$)f&CÕ°Š®X{iŠ5yVX- ¨¬;ƒ³Ÿ+Üê¬\Rº¬ !¥#QYA°t$S4Ý£3ÔÚàLQeÒqaÂfÒСnZ0ÅæTs®Ë¢Ø¥–5º¥º¶ñw0j¹Ø&Ã*QIÎX?�Ef�•ÌÞ¡)"±µº]Ó°V7íjz¢æ—ôâB[¥�)¬ÏÝËìâ>]–®Q½²Þ ±n'ûãd—¤h«çNãÈI0ù²Lî¹|õ¬qŸaljÙ-¡mãÓ†>iH56Guà4I¾AÑuÄét$seœ£n[·og»CøìjÞl–Q_ÝÁ˜×ÿ @ÇF.hy*Ì�� �IDAT¿Î¢ˆñ¹ÃèR:”óÃ2lÊ(;9ªç^Fe¢7uUîÔÛU}ÑÜý{sÞý̺.Ž.ËMúòÁúê:ÿùžô7–®Oèߪå|æJRiYÇ»4žÐ}æºÚu4l›²çój[/oAŸ‡¶óÑ­ØôE±˜´ÜÅѽ֤KZ3ð¥èç­_¬þk_VÔ|æ|°]g@¸‚l‡ŒÚ}΃)¾/õг«±S©¸ªœ Fíi±’1ç}i«Ù0´9g™ÏóË»x=ÂîÚ·½M‹¦¢”pD>,fª‘èT€©“†˜$Ïy¾QB 8®ŽL™JzSø’UÕ:©u­O[³2Ê@Á³šÓr9w¯nç×§c*Ø„áêRÇS5/ä!.Ô-Ï]TÖ<ó9ìùét†'#¯ž«/OUšö@³·T{:õr«j„§(W¹ÛÜçPÃ[M` €fx '€» lúú*�Âç—¯ãS‚o—ÖU‚jþ ƒ:ü‡š%¿¯,ý·‰ iú60´�À›o ;wéÃ#ÿw¯ïmÍ�ð`xöá&F€7�XõpiàL ]ä„qÛwLV€Ð0ÈWï†æ~Ð;Y¾�j{;¯ÚT°fháÒ�´°=ÏÝùõz—ôY½Ý/ÿ�ù¡=Øè¼Ýzûé•ýÄøkØèì$x;ñ4_E7ìOp}[Ì/ûö¯Ù<Ótã®ù ôÝÂà çYH÷H ,|±OfTkº´åÍü·>€n02ëÊFoódò›¦&å.kVjF–Œ CQ0¡ã$©\BQ%oÐZm=’F¡‹†Y‹â )õ ÝÓ•P©Lëš ”VZÍË`1@„¾Bõ¨ÚU&¬Sž ð\�#vã°6MÆ,¤©¨fðBÖÒP:˜#QÎ>LV¿ÔŽ›>©U»|*TM>©æN·•éÚàf[t 0"Ö| &·~Û—@XôކõÃMÓ¿ žÆí1Ü-Uܘ8鳸{àë œ%K±Ùhå‹SóÆ*¶ê’»1«x^®Ï¸b—*ž¿ººUoV×ù0Ìû6VÃ[cÖÖ´‹¯ÉÀ‚xµ-Ò¤&,ne¢S9obâ «&í¸éé3OŸF¦Ê¹Ä¦ø ®ª㥦ç+sù^¬ú¶IýUŠÝÝŽeO°÷yIÙcU¾.[][ÙóÂ3ˆŸÜ¡}ÀCÂåwÃPïÖ>?ŸìCàn)u ©«çµ ÷tìJ-е×l•Z…˜]É|\#œ‘ÏÝFÁ ãN¥N|s5é´UÄ(%SÞçÚ,Ù7Ípm@™IYm¹jAëbUà¹ÖEU­´æ¨•M¨óZ[h]À!8¥¢ÕQ‹òYç‹J™2t\ÊÌrfá`ûÚ7½mZ×d畲3æ¶Î˜™£^f¢‰S+ØÇb"‘(2`uQ$D•Ø|Ç,1¸H¶õðYCÇc 5Žwã\ã‹qÚï^ŒÇ&‡ßfÓq¿_L9/oÂè«CM;†ÍL:sl¶' €¡•[cô.ñ«¹ÂÔnÌ‹_¿ÜÜúç «}ßœWÃmY<ç·íàíûjGúVx �ɽ×.0ìÞÀøò»® ½³ù�ÞÇ¢ö#¨ðϾOCúµ‰àÝQýƒV¿/ í (wßrúβ`¹‚Ëlaùv:’@¿¿ÀÜA9|½Å{HßX–>‚íNB}§hÿ{ÌøúK¶�ۘ✤ƒñê5\ÞZs¤ér5�×äeÑPá5è_CÁkŸléorÝõáa®ºMk 5ÅÒNJ“ÐØÍÖMP ¯X×7M+×ywýyÓ]Ù0¦fº ób:JEŒ>CSû¢èÞÚÚ(cMÆi¥…�)“Jª)®m°‘"(c&Ì`Æ"£F®P¤² ÆRgOØ+Ð�9•Êgº0©V˜\ @åH%…6°)!Q•jj4%«¬´2¢H’â‚­63è…Тè˜ý<ËĹ½·ÎuŒÕôËJqÊj :¥ƒ6‘1G„R†rW§¦†äúdÛlµŽ´Ç¶›E´”�£™¨Ú¬Ë`¾ÍÓµI&{ïÉVP©ÚªšµÙ Š&S$©äuÐÓ.÷Ûñ¼q[™×^é­SÍÕÌS“ÂÒZVãš·oÝÿ#ä60¶ùGWµû«ãÕ)©lÇßéßšòªÿmo»~½Á7:W‚y…†Š<×T:Ð¥—éß.Óÿ™â•ƒ§óù±»«0e;bo¼Ù}*•Ë©§há¦éÅðܶzláÎá<×·—à——kœW~ký£*ëŠ>¥.í¼ôæÿØ•£Qæ7œ·sY·Ûçõª»Ê)ÏG’×ÞKÃM6”TÈ®olZ£zS”;T¾½ÄcÈÓtƒòµ›†¾m× ô¬Ï#Od“eYOeN[¥ØÔª½„kÆ]·õ¶Ï^’ ‚{JGi!d•ɵU^i4Q*S¨R¹Ž îYúà\բɫAådª Ø¡–Aè56M‚Ž•ë×x[R-KE¨Qj!Ð,J{±î‰ .*R59æmªMšj­kkYñl–ªcÁiåE’ßäÃWð•ðÝqâviCdœé2+má6òiW5×�ý«½3XÀûSѬna¤³üâ¸ÿD^3¿<ÛŸìÒºÓ›qÎ5³_ ?ƒüK0îÓGØ7—wGÐ-¨çp“à°À=€ž`°é=$<_Dš�î?0 ù *ÚoüçŠ ö#> ºús…ôÝá& °|0¿¶U�H€Ã€?Ò…n�ÊÜ*$ Ïóû_@àó žîêóÏàën3t ð7À÷`  FÁÙo±}T‘—OЬŽ–ø ç(Ž?\úŠoR}¼h#çÒ׊7©ïóV¬f•O nž¸> 5ÿª´cçÄ7Ýêñf}³ómóÎÉC_M—ÑV·RT·Ý’Ý«•Þµ¹jÛèæ"¦'m‚Ì”«Ñ¬(sÉ—¡¬úªÚs®­æÄSÖ(æ6`I¤ Ô +B˜„QÏD…ªR¨NévFU”"Æì�º 7|_”Ä^P‡ˆ6ÕO¬^·1¨PÊ"°$(œLm”Àôdl£|£Öiœm⢰j]HBG(¤½%kš¬©L‰’P)¶µ �(*À|N ´Uuv%W'Ms.Þpñ`š\)L—Å$r5~•C¸SÆö¢VûaÙ#íÕ°>®Ì+]²1É(€9é¹£9öa‰Çr|<.<îwŸ.¾ OÑ‚–캣3ÎÖ½”«}00§­JÁ)O\ßàPVÔƒ$®6ùæ ~qÎêåáÇaîê-è9ƒ}úžýzX:µdÅkžJÙ-pjW[ñŠ%—4™RŸ,ó|z14ªkNÚí+=ŸÈçT9=™k>*ü÷Ú�ë-¤G17ÈZÕsMJB£îê.œÍZ¶i”½d ½–$£Ä²Óùw—Ã]Ò²±?ãåÎ5} ç¢cžÒr’¬ÇU=¹„­ZÉ…ïê$^xå«}|M»^·]ÁTë±Æ3J£±a•¸�Sm©èjeYòè>¸—Õ]ƒv IçÓm›ÆX¯<‚"‡ ‰Ö8 ‹Ý†ìÐ@4(©^Ä¥š!§Z•uÈ *0ŠHV @cIéš’NDÒ.¢G­‹bͼ0. ]¦\nGÆßIúøõÿÝPÔpÑåþš«gZ;:’ÆÇùÑÃÙàÝtÛÞ½jÿ.Ú+H;(€*.и4 sã‹àÏArEíµ×wR¿ ³Œy}>å;€-�$°�ð9�À'GÐ3|•Þ6×O€_Ö {WSúümx ëö¿yϰù&KÈО¾îÞÇ´ãÑ8ÿY�Ãwàƒ­¾3æèëŸäÖ»pͤZhØöë>6Zìø~q °…Ô0€˜�Þ�œ~ пþP>dUÜ'ˆ�ð¸Òàë—²RéìÏùs{Ÿ/K|õzï-pÓÃrÒ­ÖWvvÇS5ƒ4õ ›kê=vf߇©×14¢õ±ñvè6kßi-X'æ“!TªíIi›ö ÏGëÖƒŽ†.—L+ÍH’³(.JÇ6M!“ÉlC`Q2#†ÄUrP­E ÖªjÁ€RÀ¥(挊Gq'qÄ 3²³•Ùr!©" €­Â­Ö}Е͒UQÕûüÌ öJéEÊ-¤I‘!°ÊvIoE\«²b\ɈXæ<Ÿ™FG3RõUצaC£Çèæº$ž§<wQ5ºÙ:jD/&)W¦’°ê€=ºÍ•¨FKïr‡5k¹ƒ“p‹žÑ•ÚdS#¯N¢î$ß$XÕx§î×®h»T5uiOyY˜h@çþÕu²ëûšø^Ì�íÓÎÕy§q£(|8¢?¤©_óJuPÍU£‰eii¿Ò†Ëù¢yª®×ºãPë—®…+\Û êÜ¥UÕ'•{[1áPe=MÆvnÕGYïC¾MrLi¹.PB¥χ9cÚ¥¥]CcŸR§.r}ï»a0À/Ÿ*xÔç†Li¼4ͤ®ÚÜKr¼˜íXüe_™9ß»»ûÍ sh³\P¹¸“2”%Çñô•Í/­Š¾›lõx^"WñaÜêÙ©47Øm¨ÑXRâŒîpN0sÑŒ¸ŽKJ¦b„2[ 'ªphMÕê>ëñ’R#½æSŒiÀbÚ¨LÌ\8g`ƒKÖrQ¾ˆ¾dÖ ÈÄäô¬Äj† *ÔZ!zN+©l êÀ©\"Ï<•:–%ï)ïçTãÁæ·þþªü;Lÿ·ž�0ÝÑòßw$M;"ÿf>ïî .Ç á|ùŸv0gÀ¯îñeI;Xiý¨×ö‚Oï§îšÕ卯ýfJ?™åôUŸßÜçGökÙìq ðZ Ï�Ëjü¢Þ© ~ àøò»,¥ °¿ÿž§[xsû{ÙÛwé?áÑSHÓ×LÖúO×Í¥?ô*„¹‚š¿3>ï[yýT¦ç°¤wä¨wS•`è.ðl†SÃ7`<EHô¾á}átûu-ë•£ÿFÊßÅ “š¡yþÍB �3‘àtx 9Ÿüø“§×o´Õö*ö»ØlpSû¡mU®¡F/d•beœ6$U•3ƒžKºË Ŭr@ç&­­6ÉÄ‚cJÆönÏ:Ï[Ì ç‰ƒ€iê Ù›R²ŠK*á\EMv¨B(.�©Š†À $£–I±\YSÔÂ&ùXÏ�YvUΦB¨±�E/­ Tey1d¤±¬DÊ]R6«‚µ—®(Dq3Ê\SJ‹ʺˆ¹GuFȤÐiKÂŒ<ªË¤ëýì¦å`.!$-¤P»Õ@Îr I'¡r‘ ô´þDK©¤X×ËÔAt™H_©Åp+Xu— e.*ÍÁ\³Ý¡8€sÕ»H«£¡ƒ½¼¨§›Üh#:E±«+ßÿji"í¾Ô2ô÷«ŠƒSYù’êr.ó!œ†ù?ŒÖ0ìT÷DÙ›M_zt:Ì &Š*·º¸Þ¹«á±ÖìÖ¹¡³™¤d[ç?¯QÔĵ?%€ìïMsQƒS˜ú=Ö/¦ÛÛôVážT~5Ìᬄóyýb2®›zc:ü×Ò=˜(û^tîÇ«UÚ¶Ù™>Ù!ˆø½¬Nik±wÍ ²g ]õ@}tÜPE½–eÚ$n7žËþ+“/N£‡}W¬þrLÃϬ]cwqÇ¥çÀ¹š’Z"dUÎÒ"mefÍAkYôƒ‘ÐáÆ$çÌgzUŒp\ &ÈrÎ�Ü›®ÑC•õ\LI|©ùe¨V래ÁjmHÌU ±²ÑÁIÆ…1rE(£2UQ猞!¦xû¦Ž(§Kàã…øÌKá}“U˜ „¿ÜóŠê9¸î:öOâïÞÞÞ§7_÷?E~,w.67#`o¦Çýo®ôS¤“åqºünùµ?žðÍãôòz,íBè¡D˜ÿ³v˜Ÿ—èîøØÍ¥ý`§K0 yoßöîzÖÁiú:ú§ï¦Ÿ¼G‹gÿ¼°á¿ªqû£˜¬ÿ¤5¿÷ß]—¶Ö“ü†ôÔä @˜ßænf8�}­Iy÷ ÏŸ@Jï¤Ûwú `Ùæ·4Žf?>ùåkúK»l�<Í`2H’tPpÐm~ôù§ë¿þüÇoz§4œÐÝU™,ö|¿i{‡Ê×9§±ò¢¥8l°F Å?€’¥V“—xm³¶Å6P§›pêìUµÆh{%¥ËìJ˜KÎÚ7ì,@-¥”œKY8E Qœ1F‰Mعâ„Å$A‹�ZµÖi–8UUÈ-(SÒÙt¨µ§ÎT…ïÜ@’©ïZÖJΈ1ȸè-º¤=`-2+™Pc×¾+’K€)¤ \lvSBUôbÌ©·Q@éâ Tãçâ°öK¶Ç˜Ç¥4á¥ÇŸËœ¬3‚í £Q‚¥úÊÖ­”îÎ$jŽ<ŸÊx§Ô\ñù´]¼ªÓáÒD­qH¤|bc1k±&Ó¼²ŸŒzͲYHÄÿ<ÏOµÂn‰9ŒM?‘ï?ÓƒKÍOm³”P§örQú¿ž\^l”úTìuKÛ¦ëoVù¦Ë M©–�UÄxpÝ8éí^—’íqÄ«š5°Ý:kWvv^9ß6Vu£Þ×êé¸Ë>§/t=4õ§Vü_,v‹žÌ㿞mÚ¯Ù‹ù…Û5è>í]ÁjÛyצ ë®jW5›Ëâ–°Jg»¶½9žâW‡Ã¾ ÓƒQMP+Âj¢7 ý’é•_ÐÛ Ë”ó|µTmªCrÆYÒ.;ešÁ)œ ™Ù4%æsS T&£Ígv—bv,*Ç^Ó¦ ²”ƒ àM×òM-€1/ B ëGºƒ.a¦*CP­UÕ¹M•nóåœN[´…:Q®ÑÆ’Òh‹­Èf‘*bœ¶XUfP©Že:W%„—YÆy¹ïïò~¤øjÞŸÅx]È.çøHBVøŠ#T�hýimüLq¯ÏoÇ%Ÿ¨�VwPW-l:9˜�90ОYMÖE} ööœ¿ü‡�j?Çb# �tgSf°W.ÕÝ3Ű=@«à Á^½ !3Àà)4Ï¡ýZÈ5}+-øÿ;CèOdF÷G3ûíªÙ?mÆèæàÑ»ôë»Ë’ƒƒÿ@!ßÇ›S‚Í·>ã›cü†aÌ�3<8Bšáy I�<À�îL’ ^Ör¹z;€¤Ñ1>€È°]¶|RpŸ^”…=…ÿîG§¿}¢ÿåM¿»Ú Ûˆ0ÇæÄ,%Ó*§\ 1Öc,#AãŒo{ñÄ:UtÑ5º¹V«ÐYi½`ã¢×¨ªß»³Ú¨ •:D�³Eê3äÅì .–¹–Xa"\¦Â½¯…5RvKve€¢0 WVÚjT´ÎÐ)eµízë<ªR9sAQ6¡EÈD‹ ¥±[T^C]á¬(¡\³ò0uŠÕpQ†To›¡¥êˆ”(èØ«Š3#jg[áA2ó™Œ#ŠI–R>ª÷š|^×P½T¿ª ø¦AôDªAµ.Ý&\àw=ÿÆÈ:Ö›³_UÜíH÷23ÖúXH¶¡æÚÓ«5ö¾t0h­;вҫɪâu­ÎÞ3J]/ÉßŸÓøâÙUN›Ÿ¾\_²òvÓXßÖ~X¬]XZ©!ÉÝáþÐ,<X¿[N‹‰­êºA9X÷$]³ÙØíCñ´ö4¸Ägu¢·‡7%v—ÍÉ®ýÓªVÊ\'Åá/sýìØlc3³­4ÌëŠKËWÛeèd0Eë¾1 5º[“Q{Í0Åð÷Ëß_…“еJ8Äí0jsÆpnÄU×—ÑŒI¥º‘!tuEéz~ºÑ8Ò6σ*~Õ&¼šú{Abº/üÂÄדp6ÉC×RD�⪩iZ¯Á{›Iƒ—ê0«X/ ÒÒ›mßz¥Nµ ÐFr3ªé‚xòÂz¶P8›)+£Ûž¼& Š+FWT*Þ*%–‚ÁbHi:FX*ŽcÈó)ÜŽáÈDºèîs<éXE†²s&€|åÒÁ“ÃtœÞÂôâ€üŸÀ¾¾jÑ=¾lÿXv€=Ô ¹¬níÚ s:_ò ¦3@¿@?Áa>;Ig€ôfþÚ’¤'°@<ß¹¼ï6w‰òǘÆ}èõö àô‘šÒfoþéÌèNk ¿k&|ñaÅ‘aXøxÚ~0 å»Å¨ÔÀó$HïÛ¿õå#Ÿß~Ù;/ë-Xét(ïkƒ­†Ç`ÃBG•@LÇ�ˆ¦?üL½Tü,e  ÍSû³'ö£«Õã¾i­­hÎ5§]­¸hMm®©2s,‰±zëWdÕätPXˆ°ï ùKð¥5 R·ÕDîAhÖED˜r.I*‚X°%kÄìDLˆ*g 'Gĺ¤J¥TÏ‹fTºµ¶hÕ “JX¡ %J ¡–‚J£´Q€4S1‰/Å–¡VMNsEMD ]±["OhÙ–¤¢ˆ!kT'蹺 ®j¡Fµì[©šÓ8—E&e³Uˆ¶á´“`”€Ë'8—teD×R´mqÖŸT?!^l®í Æ/›ñ…¢ˆM Ìú|2ñK:¤ŸÝÔúÑÐRfÐ’HšMmA§©ï”§ÁÁc5™¥: s;èfй]+)©’Éh(0\©8´ËýÕùÁ£Ç§þzí¯Ä[Ûie`¨¡B-š«49@|™/<Ëg;ÖØ3Àº)ÚuAÆF‘uѨê©]ÓÖlÐÙóÛË[åN>55¬aS¶—‡/Ò�es#tݯ·tôvôE©]snÞnU°îC]+ÀŽëªî®—fº¤ËXêx¦×½~4¶ÿâ1^ëZUšŠ9M¦Lç2±1=êv•K5³ZCtíeö‡7îžòph§³!WÕ:›´ltG¹”ËÂošr’Ä$ECDôÊ0÷MmÚÐöÆa¶µð¡&“³æBgª¨h× Ódm Û’gˆgÉA÷@¶ÇM[RÌ笨ƒµ-Î)S S�Ö‰E±bô :kfNÓRâœÇ‘/éK¨ã¢a]\.=*ÙÀ›ŒC¶_Á qOOì.ñW€ˆ÷çý~}€'-ìþÜI__ÂñÞlÖëM¿íi4,Ò­*¼¾]˺1ƚà {ØX?µ÷ %ÁýÃéõ .joŠƒÕ«½yÙ7–ï’‡¤à‹é›sóþû±} °~ÏVú0,¾ËÓï@^ýÑþ Jrè/>È>ŒÅ? ßGŽ-Àà[;u¬ßK>,,)ͿבüáD¤~$)QßN2Î�–ái€CúöLïy†»6g&Ë`á¦~~s÷WʹùnÞw‡§Ý¯:ûR'à`Û?KÝçÃö§Vß�{©¥à 0U<=k|Ð?Dƒ ÇÄâuGÎ�*‰™ hVÚ·ºõ6I”XZœJÆT“3 ž¡f®�¨�D+ÂÂeA™!×:3Ç” NÅF¡<çuɩȥP¶Ê$oPÆ2ˆ"$œQW"QJkíB¥- ePY;’J®bXÎ5U^Äx¬Öá`${‰$–¸­ Œµ ’²Å!¶Ž]KhtÐ �jVFõÅB.9\ìt.n.ÈÕhju%Š9+¬ø,IPø³"OÔ+¢•ÉÖ‘jtEõÑuf ¾¦¹‡šÂ+�*J}5ÅßÁòå¥þÕèÓþ`]‘·Z�HéB­£°]´³òÈÆœFç°Í1µ^Õ.aq>‹¿â΋zì¸ê]ór­êîáO>¹µ~è°‚š@×(Ó4·PeèDS¿›:<<긱ê"·ÏC]W ¢`VrÉ”–Ø„•î:_Óša y37‡«‘ïfUkíz¬ÎåŸðæåIõ7±m:@©¢õæv´qqú?ázÍ ñFÛxÈê€ÍhÄÒ¼—ðÿ™³}Ÿ¨ú`eˆ‹¹Y½¾lÔ%¡ähv]]mÆ T†§‰®‡ëŒw˼T³Ï]hDicÜu×\Yã O)›ªˆÚH¤gáÛÊSN¼°ïnºÎ4Þú‚¶ÒÂãÂñÈ[?ãxë™;…Åè„xÈæÂdr‘Œ±Sëh§¼*=- Ó¦$#1]Xê2I8A1¶Ø¬‰ü@2Æ—iš¹,aŽóäІt]δlßf9¹pï¾Ì[e¼_9=ÌáI»<ZN]¯ÂhÔ[0÷°<lqÝožâÍߌܬšÓeÙKRúÐl¼/*sWæ%ùã¼ð—¸O¬|[ÛæÌ'è"ì�,À[¿…>߯ÇûíW]GŸGHï½?ŸþrË€‹“Ÿ¿Ï!¾æÉ`‡ÿõ éãĤ†ï»:o§�½S-~¤�z€7p¸|ЇøˆIPz§Nß̺ú NõgÏäŠAÖ»ûÃ;VÔûiéj:N \oaAŸæ7Ow¿íwŠ3üj»ý5Ð]¡'#Ùæ 5+ㆿÈôéœÜù˜æ%F}¹¤|šŽ’Î;‹8÷ �'°Gš…HC†”VkÁéAëÖïhÁ¬¡-&d¡š…“ Ar¡H®W”g4œ–SœÐìñ@e†R� Óå¨óIªspQBÈUª’†¨CÑ� Ú€C*l!GPQ‹rÑQTE9­´TÑQ$Lì‚ê °UE i’ªIh.�Š´8B"°g±aeª©@¸bç´a©Rj3Öæ—œŽ%õ¹^/³_Î<†«¢O³9ü}«þe¯WV7Þ„¶žP™’PD™Q=(½_mZÓm©N_§¤&&ªs(Ñ&ø‰øÆ›W~ºVÅ0ñiöà>eÞ�� �IDATÖVy¢© ²î*aÕ§\챺ÃH;3w+í׬tÝ<.»~m›¢<Ô'ž®Z;tmQuª÷±üÇ eŽz ×%Z´´ èAŒNŸ¯[èLîëWóÔæc˜gÌ‹l¦Ð5ñ\øisè­ßy"ÜÖá¡õþì÷4ÖrQÙ"”µµ~-?3z¸€†KšÙK9öÞ¶é¢äR/oGÕF}ÕÍì ¦;¼º'¼.oóñ«ö‹Ê£É`JëÍ(:œ \wr Akt3»J�kàp ‰iSæМWSv­ñ¾Ã‚.:€Ž VÉÔmº-’.¡:Öxk!7æÊù+2k–†�ôyªñÂÙB'Ø^ð‘‹RÝP1.t*e†ÜUg_'кSœ™‚Pš´; C™®KÆr^xž[n¹/U5 ¢KÍ9ÄcZr¨@ŠÈ'§èL« ­æ<™Ór Ó[LGvCQ¸ðÕ]èÞu÷æÆ­îÛéîŘëùÖ½ÞßU¨Ã]Û ú`–; {_:xß%¨Ë«áô ó«0‹i à~ÓݯÀÝwð¬S§l6×�Ô¯eljw„ë$ûwqèƒø)è3”�øóûûÀÀåùôàݰÕ÷Å¥å;ñóOô·§Ñý`ÑÉ~ -Ÿþ:Ó·oz�—`a€õï±áôžpúáñÿce¸ À àÍ{’Ò»‡w�àÕ‡ˆäPV§·-[sLæ&x `€ô…æ-è0æÛ¯`ðøÀþ-K‚_¼ê™xݤžöSé/“Ý73êãhîïÑ‹íPY8øÚQa„aiw «yDйXíª¶Â ­®Ūa!ÔF@Ïy œ“ÍXsÓia•—˜ÏS]â|mrWÎ^ rƒ(Sm£.‹Vžsæ¡)œë”G% àšGd@Ýq«‰¨VàȵdE¡õ"4×ZsUE<‘h"D‘41ûª¤j/Ú rQ,Œ)†™´b9HÎÙÌ#;¯Á¢d.¥¦ ué,õ~,<ÍQ^ª—²ºÀÿø05ëFiEF™¹úœ“+‡AØ*—µ-„us2¹RiJ"ýãÌP€\~¹’žJ˜ÆÎKÝ&i•µ"”ЍUqm@ÒÊKQ9ó˜SÕvEÎ÷Mû¨i×} }XSx¸²Î¬r…9pÞ‡åö4×iú«Ó¹óôVw »ØjZ{ÈФ`ƒh—Ò¼‰¿Ìá2…I0l›æø ßëR:¥Ï¡Uš5iëürœ LRÞ–¶¿¶ªõ˜îçs‘û»4àiÉCGOj×m÷hré-Ü6·•N¿i—CTùÕýÍ!>±¦mø"º{Åþ˜(–Ý^™ìtÓt†š¶Ô~„ò)•y”û¥õ«¢ vF5¨ŒtÚkf'"[×nuS¨¾Ž¼Ýúºm8ôŠ ƒ‰ÕR­ø\ò©.EWÎX¥3˜‹ô®š¢ÅAsñ©ZѨhPY£œf§DS_û޲gDªF’�%XÉ›ÊFªfÍXǘÒ<ÆxIó½-:‰ð¡,SF½r /¾ÿt:žG9ÕæMY@îƒiÇ‚ `¦Ïä”+Yµ–k 2DZ¸Ã/#€¨ÃCóüªƒÅöx;”Yg•ÓÝ?‚ýÍ¡‹ ã\ü£yòó7ÓÛâžÀt Óú`<‚ÙÁ )€²LÇrЀÀ«wá>�<¸‚rp À�Þ‹¥Ëû3î×óð~Øêááûü©`ƒ°ÿløaøZSúüœ¾Aƒí»-kÀ.KúH!écîа‡ï ª5Àc�zgïÓZPí’g ø ËDÇônLìc€·f8Ü�8˜*L¸Y�ãD_¯ÿ£O ^À ¸–¡>¿./Ó3>·µ3ç‡�F’9/þ·oúݽ^¯IéD…¦ã jfªFçg¼(¤+µZW×((R’HJó9–ùœd­–¹ÆÀ'ä G!4Ji6"E%E‘L´Ù£J(š´a‰g€¢ó±cÓbhhïqÌasWÙû–Lm1DªÚF@äDYˆE3@Ö™ka`ˆR“�ëª %3CÃèHæ…êQ£¾Â š•("è$AáÛé‘)'ÉcÎó‚¦-©£J/\:k!2Ã… Ðö%ðŸğÑ΢eÍËr]ñAN×Híˆð†íX†½ºYì\-Ç.@~ƒn­–)óÝEÏ Ê æ!ù&õ å¢“¢¬)x’ʪëwŸUÓ¥TJ~5ØiGñªâ§„WÅÁzó`hU%³Ÿ§)_ÎõxšÆýþÓùË«<YcÎêÉ—ôà3­@‡H“ÎŒÙ^Âê>Ï£””ÃM:´£;)…Êì‘ÑŒžDÅå\dÂê­Ñƒ.}1U·QuÝúØmâ•ïñ’Ð9\ªD¯ŽêúI}\dÛ¬m»öNn¾‹w'8ø¼„¼e}²vŽ]Ÿ8—xu>ÙZªBùÑo:^3Q€¢™\N’fqnòžâkÍ· ?5¼+DÑÌV+­À�¥ÒÕYošéZ_ŠZ¢á3ãT…— ´ä ÐeÅìgàz¬t`½êd7€âÒÈRygÈ¢EˆZ<VïŒ*Fµ>iïŒòdüÊÐ sÙ‘MK¨3B‘jä<U Œ&ñ4§Iò—¹SÂÇÊq1 nwÐ{·íÓÛÅ+XÒ‘†;ÍX÷Ö=¼Àze YÙܾ…à@ÛàxG¸»y¦̲ÀݶÏí!R¾{{ùßáÁ;g°íÕ%¥ø¹Y~{x�¯^ã³wÃÿ³‡[H_ ½«7ÈôÙz =¨_~ÝFÖ�G€ �ÄwÇO œ~?déÙì})A}öƒqõOòååùÃ0ð‡jMß(>¬ùz—ß!ç;j°åŠmÜéÛ8ñî ï °/ÀÂü¾…þâ X¥xN'€À4�Ÿ}‡#�"€ø%( ×Wp%!A>Â-Ø ¸,Û˳€…~ýL«Ÿçe¶i²à2«ê»ü-wsQh.ÂÏ.ÖíJ–K¼·Ú6«¥Ó­ÔUM>Õ&–T„g8§ú2Ö7Ú"›T׋/¬GÙ–DŠ2ãŠÁx_5bŨ‹â¬–•‹ìœb¢VÃ¥Å_kÚ‡ú·ó²!ÖÜ”(TEUÁZ4Æd‚ ¶”ÄuFF�O¢‹ÔTë ų(“¸Êœ³FS¨TÀh$*Õ[©*ã@[*‘sÑx1Øj :Åùk‰sÉoLIÅÊÏÏxúßJý7A?­ø¤ª®gnôQÉÆ"4es)f·˜‡‹^©]? o(eœÿæ¨îsÿÆ‹†YÕùpVVãZ^h¾=ÓëàÜÿZÔ£¦ñ ™Ai"UAÚ½°ß ív fË)P˜\ÇC£×J†"kMÊ·Ši½ˆÜ/¯Ÿßÿjÿö·‡óùöþ./?]Õ¾]ÝÃáïh5h÷´ZgKùM/iñK‚ çèίlTèýØü”í¥£ÉS„¬B•ý²¼)y½v¢L‚s;Ÿ7m²*óІº¼¶$ÊG²ªJb ¯ûÜ�©s}}dàìjyz¯†l¦ž£ª1ɨUÊÐ4 n¹ijq¨'ÀÈUM—.—x bVg-R3Ûô*c(MŸüÉáª)=ž{dÉ犥¦[Ö÷"ÉPYMÐxw0æ¨fÛIà2\\f—²‡«G~wÕ®˜HÆjQ1†yEF³²Õ™êÚVå@Ø4¾o´C§ÑѢꜱ˜¹0Æœ#§.bàÅ!‹.(%Š3Å1:ÊQ3b®š{»¼rþN¯ýWñù!ŸÞŠÎv=)Ÿ©ëp­*öÑ*þOOà¼x, ½Hà-ÔÖÿuoÒ#Ù•^ ž;ß7ÙäC tƒÉTIUj”ºQ*ô¾7þ±½«jÙ…T%dJ)¦R$3éŒÁÞxç¯d’9ôJiwsø³kö øÎ½çœï|Ÿg¶3ú¢þWè¯aéQÆf¬ðÒ¨X·eޏ+˜Ìȧ¦OßpÂÒbÏ0Þ ; XzÏ€(¸¿ÆyÀÌØ"ˆdxSá¾Ï»ÿnÃý眧ô6‰¶Ý° ?®€[àØ.ßíü ,§4Ú�÷–°ë—Ýï%t �ëŒ-°6ÐWk~}¬äWaqH9 xLÆÜêofàç@°�üãG·q³W¹ªœÉÃyT;/ûèö9ª‰2¨&¯EVbª;¥m»:‰À ÕÉ$§)‹Ñ™>ú_OáÎrÿ7S®I@Ris»óEsb! ï’YÉÈjO"×2":ŠŒ'd‹È¤¢R€‘+©‡h&I®&TiÎÂ̬MÂ0HÃXÍ¥@ápŒepY $Ëš .¸ÌÄPt™‘,0a²*emc©a0Ò˜Ò©ÒJ¥ŠNÉP沋Р:—©b‚™JNešó={¢ËÄ,"LÐK<;…És#B%ÔéªîWEü˜Š](Γ<A_.cQKZDï–ß”È5ëˆÍ^ñ#9¦ÌdÅ—‘ýÒ}ýoO/žž=9Óõ9/2’tŽÔRBXÜÍ3Û4RTÂ×;iE—L4 ãš+äBHR…ÜFԧ¦™ðz—ïëÑçì'qʬÓvËgfdŽIFJ²©g™^ÉCkøZ*Ôôïbѹ¬)X%x{Q‹3óHQH³+•gTØ,Î c)K19ª´°©(Y™§§[CbÈéäŠ÷m^R”ëà?³çŽñq²EGÁ¾áIf5é²*k&_ íCú&p6ŠÕ²Ä6ô: 0ÇÇŒi‰j#äSU,Ò¦è•ЪȲa6ƒW}()–%%- 1Z—\ ÐJ§«‘å¼¢#!‰§Z¨•Y7Õ™ÐUÎQ€[®d«&’œAÁS2( CΔ¤ˆ*”šK¥I  ³¤š:¹„!‰17%!J–®Bn™aÅ™râ T&‘§xà4Þ„¯§”¢(ˆQ­f¦Šz|JµÌw¶ìIX¥$Á”iƒ¯sS¼•xšá†GÐ ,Mf8ÄNÊËg8}‚ùc>|"¢Åá}г›4(`� ªŒöåPÿ–çlF=¦ ˜� ¥ði‹9à×Ï�ðêÏž __ãß;/éûËZø]¢éÏ æ÷?4pµÅõámñ8|»‡ðÃÄóðC4×€°ÿ‘¥±»B¹†zÏD½ü yýÖ)ûfí[„G¸~epU°�¯n ø/ª¢ç÷9€ «Ÿ¥«•ìÊ\¬ŽZE>.Ý!)´â$ýëEn4·9n!lÚÛ.‰\Ž$Ü bq:ôi§ó~¬—iÔz–2˜'Î ,g^„rê'ÖsPÉ"æƒ ÅfÁK$ª¸`Bª ŸSõHHfä Ù=3R“˜‰R‚E#+¡¤`^rI$ë’•@Å8ŠÊ¼0‚eâQfanö¢n l 3÷¬0CIÈb´aµõ*9ÄXX4-#i¤AÑŒ .Š4àSà‚É'PÿQà|l1“*g ?Wu™i^Š?Š(bÙ‰qrýÞØ2†í*0 Ñz·vÓ6Vxë%°¶$}¢tJª £š¿Zm–Ëêï6ÒEF=k4åÕèÝ´zI�³F”6—¸b^«´ì”#›Á†ý *–Ï2‰¤×‹¨}°¬Ø–où_–ÜÆü4ËîK¥¼®Â×Û=³vçJYl¦<²«EºlÓ'K¼,D™÷)‡ài½¢ËÇŸ=¹|Ör^Üé£ýñ4çoæp¬%o˜Xç'/rˆç:Ô! ¡ M×ÙÛ)\ÚHù§ªâUZxuŠPºKêÂÎCJ-c»"W0bÒbH×LG¾rª¼â¯XÇœ\M©vCE}\âJN6¾áÒ”$zp¤Ô#/Ü}º\¤.©€!TeâZ°3ŠÍª®«T5"骒Lš5lsb Ë’S²ª’àZIQEiŸÁ3˨„ .'KAbÅŠÂ43ŒiVº¹Ìac c"—FÄ[i¢2 nø± †^ä“ç{ø_É9J?—˜åº?Çàá^Iýúy½´¦ü"µŽ( í_ËhsüìSÔwH–ð#¦ì^Óœ¿‘Ì.Íeú—W ÕpÎoÁò–kä€}„çð@À h€}E5¦Ãƒ:# À*¯ w~TÞ;)óŸÖ üg† €^hpý¡ÆïÈóÆ­õ0Çá;YÓ÷ݨõƒ§©¼]®3PBüÐ(õú5è ©< ãK¼…“æá›Ú»‚#›§Ëà8¯P§Ÿ©Gÿ˦íjÓTdb™sq§^ö÷ôúŒ?Z[”}…gÿPä/õñ?Û»¶•±VSZT›‰!Y-¾’S&ridéóäà†Ý8¥ÚùÕÓC£xÎ%yá ´dƒ('¤×2^qÖ¹‘âxÌ Þ_/fëfꆚV%c‘+«EÇq6'>J?pê¤5\¥ÌÚh«5„e¢Hm8ež£¤'¤ì § C&’‘Dð<Ûš5ŒUÏ5Oµ+‚™¦IqË�™çȦ¹J áC!GžIet Ê¥Ü'¾ŸXWôÓ¡=?ö‡møZçC¥DÕ]¬Mæ *ŽNdæ–G“³ÙßÎ)Wß4ו6á³[¯—iTêÕdšÙ]àÅõy.û»3õq‡ÚÉnÁx‰¢ãiÝÅoEèhÖg]^óÑŠa¨_¹Éå|Ã<Kã4øU?ÕÄ+lÿµìsL0T}bsªÌ¤wâÚGU…úÇÖ¼èÄ+ùŸ5êÄÓ¼%¦þ…räCѶ$(å´BsyþôÑÇ?}úèi«8æiY߯N¯nÇ×îÔ繈U\¦–¸ñQqbG7C y?ÓMÿÑÞ"³e(ÿã"ëè?Ҭ޴ɶbŠQ pÍ+jyä|ϧÇ<³% …4ß“"ÛZ–’LîÛ¨ÏTË6¶æAÝOÒ’T<w¯×³ÕÞY[hC.IJŒ‘çH8a¥“Ìi%ƒpDN¹jmmÇX+ƒQR)$¡¤RZU:dZ<#B4Þ[É…XûXFƒ,(™Ixo¼ó,3Ö¥™•ϕКµ¾ÐóäSaKöYÔœ %r‰BÄ]Þ÷4Ýù<§àÂKé‡8}“ùîÀ*_ wÁ_úê¿“5±3š÷«|6,œÒˆ* |ì\Fx‚²‚œ@'«^¬Ä,â8;Ù;ÛB'¿ÓP¾;Õì›Ï{  ð[Ä À'È€ ` þþÔ `€‹wç�írøjA¿�ü¡D~ ŒÀþÛ%Š[àôî><8ßø9ÿœ±á» ?<‘aû^¿¶ÀóçÖB%k@Û‡;6 è=jèáð]éû³7ÞxfOë÷‘éñÛ”®€ ¸†~‚ðF‡?¾êàÖØJÐY'´4FiÆ !y1øH\šóÇs½Ju¼Wå.>þ¥ÙþLÊsc[E’r_&º#+ƒ«‚\™“ÈpÃ4W·u¿/÷œÝ*Á»& ä*,êᣉbTSÐá¤ÄÜKÛäCãk&‡Èkä0æ[ÙKùQÚÌ× *ÌURF² -ã…8“¢¶’*¡4DÉZHS Îx^(ʈާ²H©„2ziM칆‘&)«m"Ζhbªf-ù˜ç.q‘@,CrƙҜs0‚`XÅeä*dÉBÜdŽØp¦‰B˜µž•KÓ2ÓAؤdËÏ÷2L+5J»8à2yãC»ð[¬§)Ìr)¢RënsÁ)-Áù"øU)Ì‹U¬wlÝ´U¥y%ªi±ñf£Š‘¼ÚsÕ°³:$}âó7÷å8ùÝž+›á&ÝŽ·Áª]÷™Äî²^¹Ñ.×÷éâfv¥Sÿøhûâc‹³úÇL<âaÎ’IÐ%”^ÐX³I&¶¨¼Ö«³ËŸ|üÉ£íek:#y.’W(~NË>pAPÌk{«.Çá`BNîõM2‡œbNÊý¢½ÝêWÉ}ü? ±|CQ'ÑædkÓ›4U£†e”8FžyÍ–£-p`9´Ák¹®¤â>FB.]$½¥jË»NëâG­ë¸$¨Êf5¡Ì‰ªìj^u‹$QÏ&y‘ +JgK­ÃÁGΜ’ÌŠLGÄYŽŒ¥Š ɰ^VU:sim´äx¦�6Š¢T*BJJ“”JI!¸°ZR&³Iä~ïbä%ƒ–èNÁíçCœ'vسAÊþ¶-£EÊ¿<­»3Ñ,;åtµP¼töÓ åÑͳö¤L ìæŒ}Ã-w^¸Œc}Ü$w•7ÛÁ½ØÉ©NPf|"6ßDàó÷‚è V ­ƒ5(30|Јûô!"ð8n·H×ý»ÔQ `Ñx> š€|¬ñuøi·–?»yÑ¿ï1_pø-> Í  ¡ü{óîáámh¥ïßõÓàﻢÕÛ=¸R¿W“`€ì›ï�8¾A‹# ‰lÞ �þ=°~ \¸>GH@HèŠÂªÃÅ#$v7™×s™­ærÕ•z›èb“›G`;åà¦Ã~ü¯ŒA4ÏeÞ¥”ŽÓ(É3æL^úù´ Â,S½¹°2W“ä¤ •øoŒÏBˆŒÍ1HDœú<e ”(KvÇ6n×§ù‚¿Ö!i÷E^ù̶nÙPó"ôNÃÊ\@Égr(,'°,¥iµ"ÆkÅSœiUαädWE7Š “2‹,d‘ ­åªÎYdƒÀD,óÙi9sI…¬8(×qX*eNE MœqÊ ŸÉg‘4§V@ðMbÆ2¦rX›Ü뛲>ÀùzFUFÍF¨˜”»ÉCõq@5²÷)8æ©—>W‰ÎpÍÕË‘?vÇEà^c÷Ïœ×ü‚‘}–ÅZKQ+U˜a+½³*ŠG’ôZpËœ‘âIµ^µ|F·h¿=,ùf$q’s^|Pg‚eUq¡¥,™M'ÞT¹ª~õ˜ŸÙ“ÔþãGÏŸV»áÁpK•RöP!QN·‰t-m·nôãíê£m½áQLÃP0ùØã}?¾¾‡92žwÓžë×*¶23Í¡ìs9TÕ9í­ø[¶lÇ牚[Ñ>&±Žò<M;*œÅ£d#Þ6AÒÌc+u]‰µlשÄAÄÅÄ•V—êÀ\àQTzÍ6\µBuœ¢²Þ0S^ç¼M‰!Ï!E>FU•º•õ¶¥ÖN2©}¦83‘y#«ëYéNL왲Xq© Î¥WðTû¾°ÊTNè=e1FR´F+ÉT²sæ9朤¤,$Õ´T©B$YæŠôFSS;ÓiS3Ì©JLzŸÃéxÿ›ýÈ_ù ›ãGsUBÌå2·¦‹R¬Ê˜0Oú"¨Ÿtª+ü4¥Iþ«47 ¯¡üŽK™Í°)eœ_Å{ ÂWFÿD,ååvÑùpÿý¸ ¬›áøÅ;¢¿º ÚC²B™Q½B|¿ö.–G|@¡lÖ…½ê\–¿Þ—TèЛt ùA©þƒòï�üxñçŽ ßÒŸý›IŸïGm [àzün?<ÆAB_ÿî¹oÁ̃u*̸–?|É›Cƒ؃÷í1bÿ&<c ¬ûlÞ²KÀS€™Ã7á ì ÐWÔ\´ ;íËÙÍýt€aœ·›bvmúøÛ-ÈÄYÑ}ÁÞÿx ¿æ0ÞwºË�Q¶ì"ìÅÒœÆaŒ¼§Èø²q/ìãO ÎÄmñµ/Õ«}¬¦,üíqZú ÅjÙ¤ ‡eÙrçaBÍ~+êH¬“YpoŦ]UÕz¥:ň3ńʬ*‰¹%+g&”<r2\()j#¥ ÎW[+�°,&!¹±H’¹˜˜ŒŒ3%î¹äAîÊhˆœI0 ¥RF™g!])”hE‚„L9ö)ìg¢(ãÔ†¾C`bíÊ¥€ŒFîk=È8·U½UBÇVÏ'F×j©ä´â¹µuêrË|£Ï£=äfÆ<ÈØ^ì•ü{™×ãü“13^DÈóÁ,ÓÙ?_tg\Î.×1Qr“”º¼Ú¶‰Y&±ÆbD†YI‚ò\æØgR?݆ےYwŠÏ<Æ%–Ik¯”“"ªÜ¬ðü‚´kåųæìjÍŸê°cÔ¥…æn1ÓÂ}j'ÅIÊ¢ #È,„<Þ/ƒ»Ó«OC?í_L¯¾nù²«xW�Mv‚߯«cþÈúØIi–Ä6잸¼ü ãÕ¥5ϲ¨æÛK¡°/Š%°\eÅUY”ÍyàzŒ=_3-J‘nì’ WûW~×4«R«` (B:RÓÅ7³oû™sñSY‡@U2Vw5¸ 2 IBóš”2:Uºv8ÝÝD%¥l¨‚Ì©s¡.ÐØÜ,…§Ù1$ËÏ*Á¤Ð*‚åZ¹À˜:k.T §Jæœ_¢ôI§Pë¹”¨ÜQ9÷õpÚ¿¼§É§& k,RåpÛŸîåÝaúz¥jê³¶R²F<ÒÞ½@ø- @VB®žû(¥cºû=Ð)ܱŸwÕ¼9ðå€Ë;tÿ+ªgå)úïTÔ¨»óêàtþ°ò#  ŒšiNªêYŽúB¸ª½«ñSÀô=n` <þsdžo ÂÀ͇¼Ò¹ ü®ª¼†ö„jý½ÁSî÷_ø i»ï{Ã[¼Ý\�3ðGÞbÈ`@î+8 øt¢C.9âßœïï7ñgõf½p{»®Ó#Q·³&·ÕÙ¶”ÿèÝ’¢œ<æ‡(UÍ1Þ”´˜$ mÉÍ“¹«¢¶z4þ´é‹NšÀüâ–áÕ–_õ‚#JÏ�� �IDAT©¸©MÛä•3Emœ^²5B.R\ fÕ®tui-µ\1¸‹°†ÏIE™JU¥E暘\¯`j&jÉ+f¥~èm,…ƒWIË""¥D2èŽdP|L(ÉÛ¶°‚D-* ’ 4g&"øŒR ¹ n¼¸AÅo1Ã/$™®JUç2²B~Ì/´,­MÆTfPÑQX~ZÂ,œµ&TzX’Y¥f·Zî¢ê*Õ–º=hw+ß*·9¹[7±˜'z=%ý<ðSÒ4#쩪#XíÇõʶ°Žs—¼c9,Äsö5¥ÁöÇ›qjÇLwnHwß”(D_—2ÓAŸoT†P«³ù6šx.OÿÖ˜/»ºTuË©KΔӤ”ß4[ËWKjXš­ $Læ¸ËÈ“ŸùøÚíc–M®?¼:¹ÛËÝ=;ÅíRÛMȦb$¤ä™«Q?‚ìæ[P?ói/>΢':ðåïïñ¿õº««VBQ/kÆÄ‘ÊR… 6u•ªµ›Uï2×M§zUt6<x …Õ½-_ñb•M,Fé©á>SÎ}>I¼Êí6Y¥ÌÖZ[))MÉå2œBL*ƒY¥ÔVÙZ§Êú$e5ø²Ð‹îL˜B&ÉFJ,pf‡@%%'dPó€g–¹àµtÄŠg™çD”‚Ë™ ÅåÉçÓäƒ/¹°eìÙ0õ~ùÍoçå ºrÅ_0W’oXÇòÍ¿\ö¯æø˜öŸLm5U{@Ùû…Qù2êÏ!Í‚ì„Ë B~åó‰Z�‡í v„×âuÞ^Þχþ…\ÿ_›öÙÝe§qþnŒ¦—Ÿ»^*ä9&ÃVåç} �”@<~ËYTûëizÓæ¦?ÈŒø9¾ '€n¿ßè?�7ß_ºþܰá´¶o/o1ámÁÓ÷4OèÏoûtŒò6xƒý C0¦ß÷†3¿¶« oû¨ßx—§Üb+±­ôvê^°è_L!:lÓ/'·:†ÖÅEåñ%¦1yêõGqäþº|<ý\ÆÇvèŠfQïGÝ#¤ex±È¯y{ÑwÈz²Ñ±ÚçfùѪÛ!íÓôÅxx\LWEMùtèÅqÉ9_ÕÂÑXOúUË~eW‹O-CéñZþT™ÐVy»æ¦¶œºœ<HRÖ‰T.¬.‹t,%шªSvU·kÙ¬ÈØÈ•€½”Á¼Ë%0=+)8D”%ªu„äl( !Œàœ N< Ê"*‹ÄTY8f%±ˆÑó× &ÏêâÇùÁc…§ESò1(&Ÿ¯¡m}2, âkwš»˜@n |tÜ-ùT…¹ûµß¾ºØHaÔÓWñß³Öüee~žÄåtñSÉÿb]5b&›ç"è¾¶Kâ‰Ç̉è] CFd*Àmè5g~ʧ)®£iŠÒ‚±ì“øÅÍéX8Ìͳ'Íd»vÓmô|åoþiÔG½Ûvl3Ñ(,3w·ÛnÔì?4ú²tPZ×\4”ü­Ÿ}ËX¿ùÇ!FÜ_-$çÁìæy5Eɲ˜ 1–NÔosÔ몕\jqçètr믗ë›Ë|ç†æñ5/·*ÔÜñþæEÓüfl°V•Š"cJmpe}püÅ’ƒ¼fC‰ÜŽ{SÊ@Å6öúeìü¸¬VñFE)B<ºon†BÎ6±æEwÒ´ )Íc8¸pðʦÊ2Ë‹˜™”¬VÔíÏöϳçέ0+‡Äœ“+R*7+1ß§™3$7Viej.3"1ÉA¢gBT€ Ræyˆ9fæÝr¿„ÃäfïŽÂß‹É/Ãî|/Õ§àëbW4ÈaÊ´9Ö*úí¦²($ͽ«Aó5Ò?ûÓ}fÀåw) ·´>Œ„Eéá´E™žÀ®À3ös6ç…L~}Žñņe?‡ÜÂn4ª€¬ Mz5ÞVH Nbb¬sà�…øf|Ø «7lÞÃÕw#…\ImÆ’hoûîÂí¿öÌŒ?¾ç|pÇAü`;øï�ƒ� Xú½\ü°ðð* <8Š8ðx3‡zøNȇîäxòÎÿêºpÛ hBß÷T?GÞìEÕKdÀY@i¤¿Âè?ñËêô_'üµýæie΄¬ŽUõ÷jÜ'±¦­ìSeo1ت¨¸Ï" ˆ-ν¨Ó@¥32úè¼q<(²¡lrG2¼°êgu•“f³–ûÇŸYnžäri8ë†Í¡D“Ã24fe×ÜT«Ú®«ñÂÖ¾L¹ž ÉsU•˜¨°”<cESjŠ8+êBUµ­Ñk®8(En8ÀÃL%P®S”(™ RÄ™ð…e²Š3&s†+BIÎeáL ÇY±œ!10 éæa)Ç…÷‘lX<r?³i1òˆ"Š‘ l3àBbUY^C~b˜RZòI¥œÍ3#©™r üv=”ݺ>K³Ž6¯Š¼(¨ha”ÃÀv=Õ÷òQj6uj¹7ô:¸E§¼â+Í“e(@Ì9…ž\IbÙk61=¥Ê<sQKnwÛÈ鿙ïƳs;5¡7RÕUyg\;ö¿¦d ôÉ% dý¨kšµ+¡$×ÚØö‰•Dˆ]¼ÛͯFïôR‡h¼ïRswk6•ZÎfu“f?|ÌÞ[þi±í"gɼ™«)]Þæ² Gvswº[g]ó§Ë*ü³¿cÙlù±p%Å&wUígf†Bs¢õŠÅ¡v“t×Ùä©ìŽ]î¼Þ‘d¼øElCÍ-Ú–Šs™™8MÇÅÖ¹âæœY놕 #£;Í(›d›Í¦³k¨d)9¡nc+819.ÚTbw¼–Œ†äŠdQle2+5í]Y.3Ï™ e¨0! ÷’²Ôª«1V¨âùèD˜Ka9«y)n˜ÇÓ0¸é.Í÷* .2GMé¶¼Q¹ÒòÃoÂ}bi<ê:Ö¦ ÚÓ Ìcr8F„A+Ì5Ô¤c`ÏAWàóú‚À¯q¬Á*¼\¡99æÖŠ¢‘p¢7µã€ãÄb0Õg ¶Ëáæöðl±0Ó¦éAÒ|Ëœèk< ÀoßÔ¥ÀصÉá[›ÿ3àæÑ ãeê²$ßÛ+ö¯d~ßÊ,ñßÝ×~(OPÿ¤7À€ÐB¨T…øðÙWÀþšÊizÿeõg@Ö8^\‡–ˆ@ÔÀëÓ›^ê·ý „¼ ½:Ç+ôØÎà&ìZ¿§íý¤ã¢E™ïø�yÝž©õ|9ÑßéãšF ÿEϵI#i“ù«ãú¦>T ’óM‰JÌÃô+÷ÜÚtéUkŲ71K ýñ™áõÚ±%faÇŸ¥éñRsuáK}0Œ´ô•(’Y!j™wijˆÑ«%y(Ñ3Ì>— S­b•Ö+c*¥+)¹à`N.ˆ1•ª¦Ê®f)Ç8DJ93-$±K)E‰Â2•{“œ‹"«$,1¥È–\ÂR†Þ}sØ¿^²&Q°Ä|˜CL9Z1•iàÅ/LE¡‹.‹Ç9¿¼XÂý!mlýš°P-óêJa³»=3Rí>Ù¶OÚÆØ&Y¨82oLµçE-¬ªJoDÐ i›úÃ0U­Þ:3¨ÛurʳœØ^âµáSùt5 ,/Lå£Õ\q_oÜ1sƒyòó¯KVeS šížù.î© ßµ¦nT½16 Us9Õ\\FÕsØvÒ’g~á}jƒ&oÏŠÚ*Ç™þ!àzQÿi~W_=Óf3Ö§)ìSNŒ;¾ŠP»S_¥¯jºÓ—ýúñæÉiþUÿϵy®ÃŽrÉIË…ÙA%RU/ cgw9qµ˜‹ß`€èæ¨â.Dë[Î5?1É»zÕJØ•±h?“÷ ±•Ñl77I³-WÖ–¨ò›9EÔœÜP3K}èÔRs¦³(G™U½LŠB­Dñ™ñÄ)1qdÁS^™fW™®n¸*9 û >ÌcRn)Ó8¤ã)”ÓDnÈ.³cĉ’1ιäRqeS~õñaR›ø’n¹&±@kº ~oÆO{ÖH|< é\2м=Cù%¦�Ñ`¹]à^>‹âl|ª55᫹×$ŽX-AÌÀñ1„†2¨% ¨ñ¶µöÇ=<”ïP\Iht—C7ãÅ;¥“¿9ÇÀ…ëû÷G ýž‚ÿ¯g~Ãÿfé;å_¿w"½oôøáæŽ (€. =®Æ7g‘òÅ{Niÿ–lRÀv�€7f°öÍ+&€àúîw^ÿøÁ˜î+„ëo½‡pká;¼ðÀ|Ìõ ünÇVºý§Ùþ6¬þ똺õôVSêÓMæíq‰ûÃÍ!/g´\–ÿ^Ö‡ñ‹ëLj-Î/!š¿‚øëŒÒÑ?tajÇÕ�Üm¿èíËã£G—g—uú´LOMæÒ–§;RJýFŠ{_@^ªñB;C;/Vü¬éªb»b„\7²²ÒI^‡#¡—I!NF'•%¿Sê‰1YV•hj© �à%/1C€1)˜¬¬ää—D J@3AàŒ§.8ç SÎù5‹�ÖEHOIå4»äç½r¼Õ FvÎÃ_ļµÌøi1’Y­·´µUA=ƒüÉ-ÿmÉ»Ôl–dWOÎ×jwÖŒ[5[óŠ«O‹~T yb)9ÀÏIgUV›)˜ùhØžZ•í˜A)Y[ÇšÀ¼qKE§"‚®rÑ޵vâ²}ùŠøKÒ¡>då¸Z«§Œ9uœ¦åëžMü3K¼•—Ÿ±t®úoD°V‚6)Ö£ãýT4ùd¢gä˜ITŒæ´c‹ÓµH}Ìy¼çö¾¬”Ú4y (ã1ÑÖsØÒ¬RÕ­¡MáUSÀÁVœOŒ]WYÏg—/u4iòñÈDä6‰/¥°¸xsgÒë¹lÓGÌÑÖÝ›”xÊ\Žã|ã¾VÖ>kò…ö÷b«­øÊfaæÂBЙ¯rÅXqy£tL”³u˲ÙBVkž’,I±˜ä¬°‰Jrp¡Œs Å4dÛ”Nqq¯òl3´La¡D‘:‘RI< ^…V%«±®DU! >›$K>„Ó8‡yâ~ž# TíïD§üuŒ"õd§Vúøx5þ¦~å¶~lvMÎMø;°øÁêm£~º®Õ®9/±ìǧÓáІä|Áúµ”7z¹œ SM�.›ºIÃ%ðuÏÄG+ú™zîsèýCtÛî šsÒàé;Êç·ë˜*À¼ýûÜ\7ïòõÞT¶øöÇ?5ô{ þŸ©‡õ[ŸÐ�[à5Uo'9ÿq|ooãLkΰÞÃR¾:€ˆ�GJ�Î HÀ‹7'µþ€ñ ú9Â%Ð |„÷Í7¸Êc óWÕâÍËoª³ ?}zHè&6ÿxRXƒ•RÌ”nâ!ç±·ŸÏU~ºïÿ ¶¬žˆ< ømwkúLųRBZt.waÝägÇõTv‘ëÐ4çõüc‡MásäUVUâÂ7žþÙ…áU³Ù%4|Vz³ª58gHF¡ÞU•­ùbXY2|13)­‘ •X ,‡—̶\½ÝÖ<Hü)§˜–ÐR*bB¤Yó¢ QD )äD‰K¦(C¨JJ ,"sAL²8—¿(ÁÌg«›¦ÝÏûÙÿß¹t}þi§×’Y• ãG+¯+¢`gœ‰ÌtTOòî“Füä«ÄåÖlÏ´jÚ8›XÇ´šòî[DŠ©_b¸sSª<mLÉÒ {¢t+#Û¸§uªfjtWù†+l­£Û"­ V¤\óJÇ–dɼ-rÍÄ)ð\!–Ž.ß9ª¢±²ª²"³f¿`bó[Ûͪ@DÙÓý>Tk%ê töFˆ |»5$‚‹M‘&yãʲ@– šÓp“–ÿ÷Þýµ5FYžÒK7ŒþI«vBfßž>ô)&¤lX,·QÿZª»P?‰ê§v·z<̫âç.©Ÿqó$‘Ìyöu<¯[žAÇD*x|ÜmëJ ˆæ@Ç[äs_m›ïXeCù…hÿ‰+Ö‰Èpl\J‡*¿.ìdÊFæ ÏÜ/"h¦¤.*ª˜Á— ’–Eç…¹n^LïW‚ùVrPñÅÉg,zž\ñçæi®IsFR1• ¢a©£5ã Í,C~aåàÃÞ‡iN‡Ûi:•¹ƒËst'ŠÇ*ï7=-”W àå8⟈ϥù™¸Òü·×%ü ´â%=ïoƒ‘¾iÜöZénÈ îúñîZÕ[³š;²šbýYT5ø#àbåz0Þ;`íq9â“ +¡_aqÜ{ÆÌë &¦Ñ]¡½F o¹· ñ¾Ž1€  „�uD˜Ú·9Ïo÷É¿Ó\ó‡ej °úa¹Tþ+#‹þ˜�Œíw¥77J‘?\žÿ`ß·ÆÀ á°Áá 4>¢�€ö-›twx\¾Ÿßð­Ç%Ð?èýïÌNºÃUÆõ„0?¸m3Í6ûí‚)"x�:¸äÉÝž_áŽðe…F£ÏÀPΗq÷ù^ 9  òyæÉ¬æmÇÀ®0fXû#Nãn桸XeJÈfÏîvÍšy[ãq‹b~bÙc‘[>¦KÖóRo3W9/ë~«Ÿ´ÕvSª&ªÒ¶ÅZ(# …ZkmLÊšLd‘5µ‡(e&"*š-[tJ šö B&V(#“ÄP8#%c9°à‹÷ÉŸT`™!æt 2æµæÙ£ô)h`Žørèã퀞Rø¶¤’KÆŒU¸ïLМ Se‘‘!B¨Â‰7¶©¥6g.Ÿ§ø¿‹Â¬ìhuY?¾¨6kÍ –!|™ªã$ïG¥‡{ŒÉ ˜s¶ð±d©<gò¼¨î)—%Hˆ3)Wf¬´ÖìQäkÍ­Zwv¶+„ÆE·äí¢×¾bË©Îcâ´?FŸ\d²å¼­ªÏ™e)1ôqk,¡ÎõYR…daD©´©¥¹Ý4ûùPò"% ‚ÜÑùcé4ðƒrhÒ`O®ZTNÿg<ÌYª×!»ozÒ¥ìÏVøh“´ 1Èðµ7÷}zêùÊéίÁ½ÍY¥SÃÈVLÊm’–YU+ΗZöMº9kŸ„®†T]ÈAªN=õž‹ø‰_wd¶¦+R߈†¸¦ð%M·ùuãg²Î¯+özÍ“`Âp˜ Yu1L ‘˜–9+0±å”»”gz$ËM:<$,qº d×4•m¬¶2IžmàÒsF¬Ê„„äÝ|QЧúcžîï÷û/œ#¼YX7wËÀ ñÚlÓ*UxÙ«ñ4ž^¸ ”HwϺp²0Ÿ­–hùÖìÇ|«í`͉ÏÇÏÁí›U˜9`´ îA¸ÜúÝÜô‰¿Âóhj‚>8üVby˜7óHâù¸s· /!I}rà� ´€Êiá}½ÂüÖö�]�ÇLo6úíéå[ßòùØá’*Z¤òƒ³Ìä¿&`ø=V¢ pe±¯ ¸Bwæ+LoïNÿ2§?i­÷³}Þtà9Â,8~H Íï!æ0x«RÐ&á- €—,cõpiBpWªÃèÖ·(ôî“N׿(vÛ5Ÿ~üá¸=ÄzóråÑßÙN³ºŽyY–C`Ûk-÷W%T9#t/rqÜZ¾l¤?[Â?¾ÿ[¬ç\OüÊÍÿÒ}Y›öŠxÛ”µ%ÅïuvU ¶Öuìš“¨ÆävE]p¥„i”©“IõœM…£ÄœUf,I•Ea*•ªE$Ç™RÄ9õn '›!S‹R¡~«ÊxÊÈ…F‘r!"Ÿ³9ÓÊâc©c…„Ì,¦³ˆÄ-§P–! sàÂóÔ³Ã,f>-:±ê¼V!TE3õº:%›Š3F«Ï…/ ëÆðÕª–•ÊñqÒè&„”#ÍÉœÁrdCö3åÉš…mö%8ŽÁ·ZÝ ¹wdýD mV.C2Ô´Jö›ú%¥¦$1ÃÂ'!° ¨š³zL"ã³JY¸,†þ±?Ü£ÿ<ø_näi]ýí?ÚšFס°aÆ»^Å¢7»MíV›\'> F®Îdµj”fŠEƒ9†Ù¿š¿áj?�ÍÒSWB¯»ÃÊïeõèÒõ±Z>‹ç¬UùEðt8¾'cãls1¬´«eå 87*0׿³.l—Ü/8=®M¥«Š$OŒ /ëÐ2¡ï;}VuUZÔî.(6ïæ›ªTø‹v£EÅ´1³á—Ïly¦ƒ5“jN/ú)œfZ ý±Ú¹ª™®j)•R©²ÌYâ.÷ä6ĺ…2SSe¢"RÌ1“Šu– ž˜ŠX1-¸L­Á†ÕuÒŠ%žSʼ0¨d^–âHÆú´x×;zŸ–ié/ö§û›\­KªgÐ/Žþ^,k¥VEXî¡ØÎKX§^ln«3W-/é¤n­`ŽG;¸ÏÝvÚùý¦ÆG›3@¿…4@ÄíhT * Æ¡-Fޏ:ž?#ò¨+ Â×g5Ö ÊãîñÓî_L·ãýCéß|_n꫇2vùÖd”üÃ>øãk¬ÃÀ‡·~Έp÷aõ3(H¨ÿ °á÷‘? ®4®ôò09 æOõþ¾µ¾=ÛçV~ì>�üÔ½Ù²%Gv¸|vá wÌ (�,V‰"ÙMU³_d2Ó/ô÷KÍÔÖ2¶ºXT±Èȼy3ógŠ>nï‡Ì2DU‘))žî±ëáƒÙÞá{­½–ü‡õh€Ç\ï)ïHÂ/ß<á óN×äÍ1¿—�*zp®…æ5mßO|ãÛf{FÎ/‚z©Ôoêõ×þxRýÉ].Ò[î™ÄöJ}µÚlŸ4àg:õ»^}=˜GÍêçY·-_ïÖj#U'w<Ó¸{ÜôËî'5=aeoR\É#) ÎòÆÓr}ßâF¤M¨§(;*,Æ`l5ÆZ&EàafT¸g%N\ó¤ˆ)}v_³'¢Ã‰´Žj¥¥ ^7uœ²°9/Šn/ÀÑ™%%æ Q| B-Œ±LªV]KΕˆT£¬˜—‚ÕS:úý8f%rVò"Ñ(%%‡¨Í²v­¥E—5S>˜Mª…Öž3)¥+Ú2©JBLì0¾ÜLR¨»f:ÎFoC –‰£©Vµj#ý”eš‹-œ±ë”óõx©ÅªëѹÜtEÙ¥Ñ]=Ê)쟱ÛÈ…Ž«˜”HÂHkE’ŽÆ6„]‰åÌãl[ŽÄnú§½ýKa¹˜c <ÓPDðjZÂRÕ³^u²9íRž—­‹ÕÕ2Qxiƒ“÷e¼»?ü§(‡%§Sú‹Þ¬OÍÀ}N¢îbƒQì\:“VŸŸ•æ¦ynæ¯×lÝ£¦³½.h Ä&6ÿç°G Êõ5ÚÝ2ß­¤Ö‹"~jJ*œQ™B1!Z^YáÌ«S®‹ní˜jyJŸ�§sI­8\øj3{¢ÜÊÉÚsåYâ´g*t¬_5½[uRbJd➣LÔRHļ(!Í(EUžW~Î瑃É81^yØH«ÚÇWÆ­¸D5ž++$d…,\øè)¦qw˜Â¶L3Ùáv~åç×$ºx8ÝËcXŒ+ÑÛ²àÚ /K ùfW¦ m\65Ð0ìw²î3ÃtƒÁë›®_Óg§4ÝïÍ{f¬"N?‹Œ†!~ ;#îß�Ÿ‹ÃqÄfÀuªbÆÖÉÔü)Ü3ÈWVV¯7‡øS #¼Døúþ>>2Hé=°a÷ãa̼+:±oÇkìâwr é÷ÒÀ¼|iã¼hþG­)Åo!¸à ØkÜoßo`þGæ-Tó·Ï÷¸K÷þôøˆ„ádþ¬ Æà~xç®wxÇ]åá£òèoÁç "ÊDünNœ=º*Ÿ¯Æ¥y1iJ»ˆÛÆâI³g‘ögávü\‰ßœÀe»Ù`¸Š÷¸Ê¢y€þòn²çg0j+†ž 3óeo.ÏŒ‹ ֻ̲mZSÖœ-“Ó®ofÖ4_ÔÃ^à%&EÍù¿m]£… a(ikåµ–ÄeQÎ —X™Éç’ƒ#±ä¦%Ó‘ÊBÝ&o ;)éœKÁe"òŒ!“ L‰4«y`A:i™6àrÕJ%óUSu²4¥,‰”sLš«à¼‘ªr¢²…QNV¢f«Kßê¶S£®%Γ€P…éµRU¤LÉ㜎Çûa¸sM>Ïi7Ç}ãìæuéZÙšFUTNP£ñ¬‘‚*ØŸoÑÙ^¯„kç¦Á˜Žóôp~9ßßö›Z/|þB'N’öè$^ç•?¤=¿åù^[·R;·«¦ÿäòÿPì³é]N‡˜”9·œC©…j‘O´oL–¬[á²èÜþ¾m©Šš+×heÛ¥¾ûÜ_¿¼=ÝeD/“±k†Ö<莂§8†–Œ¶º6pŽG°ŽeùMÚí(*f\…É2ÎTÞæî›M\ß‹¯w»«¤oÚæ‘«SñYEKå0§#'"±„oú¤ë5å=ÓlEŠÙKi˜§U°àœ%ê�EŸu_ŒŠbˆâeHW»7Ü΋ÿZš“T² ClejbEëÉÉ}Ôâ1§½Gš‹¹– ¡I¤D LE®¼[µ:²¬k5ÎômÓY)jõ~JsåDQ ÐZÙZ$ã>9úý̳žü8Ôp7E?¹©ø&mŸq=/åKN!Ú2ÓѰýæ¸:ÇX;ʺ¾-7e8:zv²wñWê¹¹ÀŸŠ‹EÛG½˜ñ5TÂt c&‹W¼Ï¾EçÐþ-R�èοx‰í=ÔÒ£öй�� �IDAT3 ù{!A¿Å˧XÁ·o>øßxC Ä�|þàXöFjé•FûF9TO0\axÓ¶üŸóÃOðá‡] ÿóaÑï—x¶ÿäYŸ¸Áöé÷$»ÇQqñ®`wó&÷sõÿnã° Èß³šþžït?H6¯ä¿kÎ.òMlv«¢ÍÎû¼½þü'g«³áâþF™Ì±hÝá//pºí?ß•¿:NØ"¶×ø“~½Ú_Hޑߺùæ~æžjµÔ<_°ò_tùwM³—Í‚·+¶W&­Å…æbb1Ï(ª±lÕ@´Sy͈Åpˆ%ÓÊ]sJ‘ÃT&¦j&d“gŠ"m!–[WµPj“Œ¤öš«’À%”äN$%‘$r¼ -¤•³˜Y¦ŒÊ…¨±Ì#M:í5>ëÛœ¤ûRår4±VÞ–ÓSòSŒ[FI„ j¡ÜÖ DfÊž¤ÌÊ?¦)…¼Ø8Ü÷Ï'~»¶?ßùýv¢œÏ\s•³˜ÍŠ¢å9ËRâ¼aǼÜÕ[똱Ìn¡Ñ5¶>>ñ#ßL‡žâ¬XE©õQ…4œç“e?g–vÛ‘¦¾ Y­Ò²•¿h£1XDÏä¼XɆIÓ[a3kÛ©ërï²[Øu¿rª4±ur"Hˆ\k’B!)£9:Ç[§Æñ'æÚ©?¯dí>ú[B2b}–÷”+¥,:ß­üj#ýuÀ“RK§¸‘gCóg/ÜöFß?ffÞ^…«G›?–Ì>rfæ÷é>M¯+¯ª´'\ôɨh7¯}B°™ôØ·‹H«…l\$"_ëœÅÁ“†˜¤8×Ã(n7,Å)Q3/´Òê6F›æœ„šòjdŠÅ#é¯Éú (PÑ©D„A¬å$e&]xHL#Å«E« £¤¬½NFz–Kðcò"A”ÉpyÁjÉûJûT'caSÎq.fc/¦Ø00Ã/{µå4výâèçñÍÝTc—7ËñQ)ê¨UUÝüʵñDl¥°1ø×ÝÅ—'x¨Ôô<³¬«ü7g{Æuê'oαwà ' 2C»F=À¼¿Ç) ?Áåg»}Ú`_C¾H¶`d #±¢ÆôÎÖ>ü!X¬þã—àô½Ö`z¿lþ£Ÿà /+ýO­Ãú·å»=�ýrч‡ƒ±|c¼úöÄ{À�¯ h¾}â²€€ àîͨøV7ñ#´·]‹ry’]<o¦c!Eí¹>Ù ×YÀ“‰ÞÏ!o>ßL.µw§ãþkÔøs> -®ⳓß|vpìNnT Øå§nnOQNþý±=Í"­õI-2W­™:Yˆ¦˜ƒÜM–Ϻ¿ ¶'6òq`i?Ûý.Ü—1õ‡Ÿ“j›b¹ÑŽgQ”.ì<—pUsÅ9‡ÔÌ£ã$Ñ2œj¥* %Y%ª*¹Ô$˜vA…3 °LZ‹Ê‘_&ð’J¡š¦é˜B©«àR£ŠLIÕUV°ÆTÉ­´'†efnsÌ>Ò‘t…ám£lõ ËÔÊ£RT`õÛµ]»…S¬¨r ã”Šà¢é”�RÈ!sïužy§ñªÆ±³ôäq9ú˜§]»GóHqÓ*åº ×i´ôJÈx*`ꈒÊΰ¦sÝ'K&k·¯|mÖˆÌ)°…7"yùsŠ—rŒàÄÚÂ3ÙiZr·2íyßX&fn:Ô<T4JJyÒëíöúî¿ÞæÅV<hx·Ï]º[™ªÝö¸-ËÅÊ9U{5y5˜Çí±Ä‰ SÆC~Õ˽á#+ÎBEöèÏbæé‘IÁü¼œ<´«OøJ¿¦ùÞ¿Ƨ¦¶«´ÓîÁ)L.¢Ü—cº‡Î¹{Â)œ(eORDLœ—Ž#Ž5 ò»¤_ÿl1­<jwN‚Rå²)ÝìÃ9.;“d>0Ÿf.‰i! ÁÏ’Í¨Š±˜ê!}1ÖöÖ k e)€‚9äê ±œ+ª˜áÙ<æ‹1GÉBïÂôjò£¯%WF5ý˜õ=É ,·fÙŠFYÔðûX|FÇŸ·”Qì“QãÜ ØÏW‡‹×<gÁŸÃQc¬Ë?±~G»ùX-v‹¦kÄŸc>…]ÃýØ9ô9N#ì 2Ð-ºWpw8FŒöo"*P´œžh\Mˆ¦ßlÄÊCV¸mÄÝ÷ZƒŸþAŸ)žR}W•LJ€ ûñÁßðO;ëŸ n?Žï@þ7Ç€ÇéG$EÞ<üf ôþµì¡ÖXN¸‹opÄqÄ4oÓ…žØz%†8þ€Ôtì oºOV~Úc`_M=Ÿê2¤zwh®E;ÕæÁêÕ‰þ¦áƒ¬ÿÞae\ùó‚‡éá™æAßfþÔæY¯š‡m3£{$ù¤ù?áê_ª5$o™h­ê›N xŸ¶C£ü&šߢþeQ?ñL—ÂÕž)“Â"ðŒÑADÁÔC=W¾ã–•SÁX¸Íº*+Œ[+ÝÝU­µ%#aÈè,k)Dœ“RJÀ¨Œ"«° ”  —KÁ"ÕT#êˆUDZÞ¥kfÂ9­šTPçQøÀ*‘‹“¯\Y qZXN@­Y®“jK%)m;÷pqÚ3Yf¤Óò³YvLt¡–H^qÒüaÛVÝ”(ÃaJ>Œ9äñ~ÚmöC&µ°ÖžÕ¥±§—5-›èš Q¥`¶«âJS&~hE››Å`R ßP]Jk:Zz3Áæi("+f…\=Ê<IŸšâúÅ¬î ·!F[² Y«â2ç0œ-š¦ÓÊ5lœ00eYdSb/nãÓ»5?ëõR±h¨úÁ ¤ó*…FË$â¸E~í79\‹àYãÛÛµb£‘/ujDNxýÌŒ²ùjY…S5_øþÄÈ(ÅkžŽ74à Øç¯2¿8”¥áí¦['\aòa»8ž-—iú¬øà4r=îN©qí\ëó‚Br/äJõîâbe“˜&?• …ç™×€+%êÚHßò&h£jÒx’§CÅýDyæê€¾r«H.¹”àEƪP±Ô!MÕ8Å*¨ø)á0?ä´ úY$V[©«CB æ¸íK>º)ô4¬r «m !²“wƒxè›ÆûÄÓÄwô`“z$N¦y…½@©Ø:l¦›}¾6nVꆺÆí@À£W¸ì>A¹Ä‘ãLcMG…aw擺UÓóã¾´Xž@/1 Šo7 �†¸ÂU‡¸öêýoù|41¼áÉÄé;Þ¤Ð�GÙ¾ý»üÁç!0ÿN0㟕ê'‰úƒ8þÑÿ´³þPÎk®Z|?.o?¸ym÷`Lqêh‰ß_q ±+`bÖW"öo÷#Ó;WàJ´ Ÿ¿}Ü'À)P žx\1ÄçÈݬûÝçLü?ךðG î~{Ú6æs±X^“„ ùŽL™“kvg¢é˃oHÿMÄ0½ê§b ›qF@å¾ÕêÞ…sG]%~Âé¡õ/Ó6\1·-_šÒòà±”ke:T9“ñó…Ú9N·ž•e›íeÎÛ3jT™ —ʵÚu®ë”$!'#H %xLTÆ%ª€Ô¬VP4©ÆÊ¸b½ £ø1ÓŒ ˆT¡’ŸC݇=UÃ…×TXœÅp çc}tHNqYQ¹HžµÄûDª"W>C¢“EjŠÕj¾èjÛ5è³[ÇF„ý!'_x<j|nØ¢VíËÝ]ïÆûãaPã—zÿê8Ôëò‰Î/R´jÕº“¹žK¹n¥`eò>DÆS”ŠÈ &«´�/T“¡Ê'AP¤X Š%) 6O¦)9ðèŽGÖÖ@N1§ŒãD^g"–³;€)’•ˆ¤ÍÂ8‰næ÷ûiïE$rñÙþ¤÷©ÍR:&…¯²½vºä8f¡g?ÝC¼>Þçt7VÑ«>õ¶Ž‘ýo±8¯&ö6­€þÄ}BÚ42èñ¤*ÍËxêD˸;#>å°:°ÓUáËNdcš¥Ü—&½ë/j ë¬(¹Æž&I –§Lìv¦,Cr‚µ\YašKéôÂ[ ò¬foSÛ-NCf…Òʈ†LÓ™ºôQ¹�‰»v ™Æ¨Îææa.ÄÒªˆ¬n¸lasR*¬pbYrTƲ1cŸRRyœëXCfF³¹J–HS¯‹™‡LûÝ‹$%¼ãUN÷8ÞÌòùMÓ+É¥RC q¼E}Ša¶g#˜íobžêg=ϰP€À°¸˜º0güZ2ý|að°ÇÉÏPÎ,¡U°ÀØâjÂMŠË¾ìÅ^T¬î Ø×XÄïi9Ü!îÞðã /QÞ«Q—÷…>b÷#Ÿ—8¿ Šþ'ç†ú£¦Ô?ÜÿU9¯oÊ5Qü¾^á*#¾A΀#à¿ó Õ@lÚ€9â]ß_±D”·.=ßÈÞ²øVß»C•OÔýU‡˜€Öà$GÄ-®€7L§p‡ÍɰŒ0SûɆ®ímûå¹=óiLÇ6a³§mà?ŸB÷óÂMg]­ëUeó®ÝRA€éàvx#^Œ‰2~¥ܹr–B‹èe…(¹¤*sÙ*ß³Ê8ÿL r,HzrPbŽò\èË9Z±—êöD¦¿™eHã™q ߘƎZˆ�« ë ´Ì)ÆçLhd.˜€ª¥x�(…¡T)*P¨ e”Äy&–8÷ZH§r@ ¨!ª9”2»q´s©V™yÊÁ„”D6¨™óH6ë®qÌ« +(¨ œ”HFÎZ&3G«µPNqc YŠM„\Ç"«oØ í˜OiâÍàYûíñN6É>Îâ±I EUš«àž XœÓ–vÇÄD!§ª�27)³Y̵òI„ÐF­ç}4¾<F=ò2çKæPzeó®D£Ž`§V®!V”aÞ#*‘:WO{Ó5®m«Hð¸÷vçݸ Û»»»ß§oHdV\e}æsRþk'öYQhÊ85lȇzÈ;P±UÙEóÓæTýS §Ãp+¹;ÊÀ£]©ö£A㹫7~Œuâ‘­©³¤t‹îSȽCפd#“—g uj³íG˜Qð :-‚îC8²9´XpÙQË›ÄR(Ò¢ EhX¶GaÁï{žjб.MrT+BÊäsDH¤F÷釚ñ¶lTxM‘³¬í$Cª-«¬&KòÙ3Q’”APrÕ3Ô sMIg&P£<Žm(1uèBm䃉3ç»áeÂÈ7bx¦Æÿ÷Jî¿íÕåUÜ€¦ÁÿéªØéë^Ü#ßÉ—hǵ|ðp«T×67oêÁ}ÚëÉnUžæðÅËø)ò%’D=ÂUTïpÈØKLNÄv»âXla,òß³(`uu‘ÍÄÑüÃ@Õ¿³†ûhUcŠ?Š(€ÇÚŸ±wÑ?à_¨¦ôþRõ½Tñ¯¡»ñÎë÷¶_·CÌïÍÞ9¯µãz’Nøs‹ÐÕ_¿¹¹oýó 4À8$ +à à+`§ÞÛ‚Ôñ ¿x�ò)ÆŸ Vðg¸¿÷ {mxrû«‚C§i©víÏâ¦]:œè0››û¿~¥Á °ÀŸ\\,íyÙ5ô°ÄæhêëOD|œÛVôJ«TÒéÀN¸LVÔ‹f:Ó''ò²ÏÉIñ{VïK ‡™›Š’Å »]ú<%0¾Õj¨üÞ³ÄÿYÊTq]ýž»—[çÿo„/(· T‚Ñ2¹®²§,kΓ[£çZ9) x‚ ÎYªµPŒ$ˆ„Ê+‹¹æ„BŒ £\3±"Eaš´"‘9eΫ )ñÂ<O!çÀ‹^4|-øT€l w ÛºV ª"?æ\‚©4s–•­\XnyV%Pܲݎ¯Öæ 0 ÍsQÛ!i™vÕS«”²+ê?Ó¢qú1-í[öUk®¯.}*>ú¯áwÖSÛ;Ö*nH¥ªË^d%ž%8rMµäÎ+Ýž”8(O"eíaîE±‚-´mÝ¢åÈ”| Ywëu»Xk%¡øäÓ°Ýo®î¯_½|6ß>ÃÿqWòäŽËäËáp?Ë¥Ö¦9ÕDz˜c™h+̫頊_È¥‚ã‹î³…Cµ‹#—1Ÿ…š}ÕS-UûÊ“hØÁü'ï–ÌVã"FQ,뫳ý4¹Ó¾gëú µtk뜉…¥¹“qâ ËŠÕ9ùc¾keaËâ 7F°¦–ZC9Hµ5Š£˜9e¡äx2|Ö •:Išr8ò­–y¬Z”eÐJ´'²5+]:2~HÌÆzÚç,¥ Eµjb”óy"?g%³LÍØ$òdÊ–âT%Ê 5óIß-̼b½NZø’z#iž6sú¢àˆx2äóìŒ\SŸ®ƒ?hèr¹é¯_æy¬ ¾Ûìq¹»p‡íùX4uÎ¥éÕ-,ôYE¿=ì2nü¹yê1 €Ë‹¥ /yÈI ÞaŽ•iÈ'8¡ËûÛ/,J} 4%âö] èLÍÔú;¡ÖáÇþûYnßÿmsÃ^üaÿÛ…øcû,úç±f3ÀßÉh3D Ìfh5b|YöƼx£´Í�0âO'€þ*}l•  Óµm¶~BßÝŽW1áQ©5,2!ð»O³p¾\N¹V�Ë_Ök£•èL©ˆÓl½Sƒì4Ÿ2sÒžº}ÇjÜÄçuËz¶–õL>¿tmÛp.xŒ!•@âeÈlâZkÒ]à"°̈šÙj±xò)Ñ–UXñËÖE^{ý©Îkæõ†E彦Hㄾ2¥g…ÁgÌ´L›Ê‰PÀª¬ ªr"•«H$*ŠbEÓ$s AR "âUÙ**··Ñí'-K¬UéCë ¯L3§¥4¼x=h”Ž+®$PjQ:ϼx™£PP\3™¸ò‘§,fÃ]©;Ô¹°L‘P‰§RU¸õ,z¦…/,ÄŽ„qö¬y$Õ¹R²b“«˜[Vlª‰ó “w¨¡ª©¶+KËŽ5¼ ÒP¥D!½4JhÞD­çÕiÓÎRÛMÇÈ„&Á±îhYT\·ymû^u–4«óÄ΋tÆ &jˆ!ìò8ßmnžþöùÕ?¼¸þíÕsuÿKײlõ..K9[ø)Ü…}×cq&új’Y¸°c#W| ‚—6Û&{“›P�Ÿ#O2†Jwù›BL%¾ŒÚç‹©w^ObI‹×ÙËÝЖ<GÛ~Zé§g´T|–®¨Ùs¹!! KÜj‘t^1Sõ¢æ5%9ïÅ´BÏ„‘Ë$B@Éy<ša¨yºv¾Q,yõü¤xjœ$ÈÀCn›QW•Œ2¼ï×m¿PNt|2ITt³n•J©ÔP˜ŒŒUð@ÄB4å)Q!\U+¡KµPYEŒCÑmH›ý«½6yÑæ‡3lù«±åÎLJ.“ W¢ÿ­éÏ™(îg1ÜÍV%»ò†Æz‡†a�ÊøúÎ`±ÑKbóš¡¶W#Ø.6ÍUsüj¸2Ð=’—Ÿ­²¹cægŸ`¯ý<äx„?"Et@ް[ì—[¾fôN®PÞ‹LW‹?‡µpwØýí;ˈ¾Ç­ÿ6H}hýö]‰'oAÓfû¶Ü±Ø?_£»þël þÑ=ø1Îè{t#°е~`ã,€ã·U~…qx3ä­–_E|ýÞù/�0Ìó¶¾Yhø#¼Øl^½>"p¯ø0cîÏ7e¶_ körQ«é£ðèS>­ô ÉÆ®gG¦—IxS퉷ž|²›ûNòØÑô¹ø,Eù()æÙ^×—¼ÙÀVXu^©½¬SQ qEžù)VÅkCÅ b»'Öå¦ô†_ri~¸Û´~ZZ§u{ÔÐýÊJÞYã¤PD©”#+¬ªZ‹ \£œ!t‘•I)ÀIY©–(0V˜âŠ 3·rÊJÙÄxR†Q-ytT8ó•ñ¬·ÚÛ©ªjü,¸)\QÔ5d– ˜€¥/5E¶›`˜œ¬f‹^ts)‡lŽé,Ì3ó¼ªW/f©=õwaÑ­vÂõZJQ f5i×¶«£œpà!š†IrÔ÷±Yœ/ÑñvŒ Å×;&eà²F0ªF:-ÖÜš(Çžà±ô]^¢:´lÑûµ¬2w<ëT‚‡ÂX˜SòÁßl¯óÍ—7_ýöîÕ¦¼z: rþTÄôÓ ˜Äçýt¦†i±(ŽÝG­&ÍçbrKX ±uJžE”¡™ÐïJkX𕼋wwåŠdýÔ~Æç5Ö,’«åþ6\Û­Ÿ*Z<¤~¹°‹5™³Ê;.š*]Ë#v9½e¯ùQKíÒ22Æ„â%pÂG´0ÒtZôL·‰!Õ#ãê�)RLãŒA†Yó1ê~ £,më6Ѻ£¬[͵4 Ò¥Ãj©{§™ÉNâ¬rc”rR Vcá1"T6û’Bµ%»—åYôËêuíLr͹.ƒÍÕÆ¨«¸ÏqJ›/)ŠXG.‡«ý¢¥Nˆ¤°•‰X1N/}Ì9Ý´\ó ]äaèblŽÇ9ùݶJ‰ N.LÝ7qšGóÕ¥l.ÚØµÛŽ[³Œ³ÇëÍ/Pìá‘?®Dב|J Æ#ž±ãô[ô#x@ºÆ=ðh¶HÛ@úåbÒp]Äë÷ �(bW!:ôìBßÄq»Ëï*Aåýp¿„à(o´[?´~ûþ±}g ½ýNäg…bÝ?ªÑý]¹è‡B}õwþüï«¿¤€ÇÀ‹¥‡'†ï „(À�¨7%{Ĉ›oq¡ïU±4�úí{øë¯ò;_½xôn¶ï—6_bÓ´X­°ÌØ ¼‘�Á7X>\=nT9\¯P8P;”ý ñ÷1‚ÙŸµ¼a€eôdy:‘¤`å•¿½}ø…êÕååêÂÓ‰ÛÒJZÚ)OµN÷ÑBv'A™—Œû.Q>Dƒ¶°õ¾9ÄóAԵǭZy{RÅA¥»‰h]Ùm‡s úÄdŸ¥!SHæIá)*ÙûJ¨B)YÀRa¯LT+ÈYÆPÄ-ƒ+Xa‰R­¹’`9fdoŽ¡ãâÀVHܰV¨9óL"qÅn{×´JYÁJ'ŹlL_5ÅÜ¡VQAYS!9“Ð3PN((ùTÄ"•K‰^Èá0:6”>T~Ùê—F¸I \:(²‰§ª$Æ…æ¦{Ò8£z×ÚjÛÚCê1òY0r‚Ù:Q OsHKSË9ºžz›M J½RèÑ-Bϳfô‚ /5€û#†)U]ÚægþøÛ|3Îc»ÿfù¬¤3 §“ ‘©^F]35–ËÝKÙ/ö¥Ï·«¤â¡-BŠ…"3Ée…©³ám ü:/ø²‘ĸ<Öyòlvp¨j½ãbÎôz—HêåR=h]¿Rzv=Ž:P1¦z,/…k(äÍMªµÌ.lä\+–96‘©!”eËÏú^V‰$#¸)"Mf¸WÍ£dÝÁp Ss¨&Þ™’༫ ŸŠ\TÆ2D*Ì'è Z&Œ6BJ!* Ò$J*Áç=¼•™K%ë“&fb,M±jéSIYTïû¹ºñÈçqWýÿOïëãž W2­ÓãЖ£¼ŸšÃHꕌ™€ò,E—áoöRN‡{ç—{À.Sb­áò¬øËM~x÷òùpÝf4BgÝä^Ä´}t"žÜÉǯ®åk¾7<¹ ¯ow¡âà¯1àßhhÿ­ý-Nw¸üI·½2)†$Tÿõ³“‚“¸eÀ.è´:¯BQ�Óv ?Œ“O?çòÏ×èf+%Õÿ¦XôrÖѳқÄðíãÐàˆµwø Üsàå»õ…Fž�¯Û÷¨ï±žÞ&•%â›î…ˆ¸Îßkqû~çIâØ)Ö¯¡÷<NoÛUz`úó|8ÑUÖëåøQã5𠢃:€^k†EÁÓœßÏÖ±²<‹ëå^¢ûéWÆþb©úRšrÌWeº6ÄÃ7½ßÔ; Π cëS })ù_U¡ò꓌j…KÆÓl¦¡C´BƒãÀS µ ne¤kÞÍ:-eY±Üå\t9€`x£—¼",Ê< 3¦”“÷œRFXÅ™¨UÕRY¸¢QRd†Q‡È,—š„$2¥º<O5$G³œw9*ØeTéªL&—t n Rpâ Z+%AT «ŽWEc ¾8R:E[ªßÇy ³A!)¹n§—É۬ªÀ`‚àVr.Y)¥´bPÂv\Í©Ô\}é³´µ~ª´ÆhKÂÉ7ŸÓ)³à“®ÄZFM)Q«•C¯¬h:]„¡Øv“ž³fÂŘ¥* ã‰KÆU¥´Ãx3Õq+YÜ0øTïgÙ+5þÂ|úÒ(yèeªI³§Ú³hçötÓ^—:P½E9ÚñÎÖs˜óÖ- ?¿U"òä†^àÅÃYHõ(ª3Qw>`~i¦<Õß„‹_ýŸÍk~rvâ%/cmOå„è„t/7Ñ Ÿ6ÉÏ)T_:¾Ï§Š÷¤”ȪïäÙ‚=J`ž‡ÇR¦™~"1 ùuüjçŸ-EjwÆØ2ÑóO8k(øÝÝôlä¬ôÎEÆmZÇ…ŒæL­4QÙ›nQQ“I5ιŒ9Çirznõº-æ¥ÛÝ$¶‡é@ùYýn†¿1ôJ&™„󗞈¦äþ¹`!ÁnÝ&Éÿ|#?}†.˜ ÝÌ‚½ôwϱ9 ô´nW­ø “璘þõÉ~eŽ«~[oðw\DSÑwOd¹Òt½Tû¨êaØæù7OÕx–"7[,ÿØk ÁŠ¡ýí Íп/Dñ›!æá€e�� �IDATJ!®€Ý¹’=õ®ÃG88ßky›>"’ñƒ8ù]œ×@4o²þ{`Ñðñ³>,íÿØ´å‡Xô»Ó·Rz€^ãÑJÄóß_¤Ú¿OPÀ^#>™Þ[ezà ŽÀýÛÕ¬ûƒj×ÜÓÇX¶ãFı~Ûbñ�Í-ÿÊk6Ìl7Hü}Æ'€KDº@w1­é٥ϊ·&žÜˆÎ¤iŸÂFJ'“@l¿šÙçM*§qcc¦ÞÛù¯Öò?´ôsÕ]²f0rÐZ3üšãW’j 'A­JnCêxp©Jw¤ó‡Hyò:™Ö4m«Z‡N”e¦"ì°lÑ.„êH™ƒ@‘F*Üg7F"7¢VN%W¦’⑈ .„LJ@#Èœ±Â«`Ôñ$ P(ï«÷‚|ã%‹â–“3Éb“•Ó’3 Í- 1éˆë(Ó®x_1³žWƒÒ!Æäj-R\Gö"²ãx™¡¾9¸æ9d8VFùxP±¨ã!±yÌ7Y‹žC•‘4‹1ÈœuRdBâiŽe?æZ§L9W£emôÚÁµª˜Qˆ*dx’<!̾ ‰¥†IËt|_¼Ãt£©QŒ›B%ö`ž³Qã#µ©ù¥É¯ô0mó6-‡¬åÜošøBø%¾~8þZú9ˆÿ ]ЭcNU‘ïoŒXôtôí}7ë]j'äeÛxS£ e5ææ¿ÄlÓ-Œ3bDùÅNk»Ž³ã‰G€;¾ÛÄëíáöË!NB ËÛst6/äB(§,SêÒåÅa.ÁOÛ"S’²åÙOn~6Ä«ÙÿïbSÝWE1È1󇹫:º8¤ÛãN¹µ!:ìiŽ£ •þ`!šq£/Õ§ìø()¯órb9P¥ ®Ï¸[ÍâåÄ3žïwÍ3nGjüþ°dOƒyéÛ|œÒòAkáÙsa†Æžá7Z'Z\z:v5üilŠnüåþþáîï1 6… ¹9Blô±^…%/ÍW— µYMùÉÕtµ;~·Í%¶·`—¿lûO»¯±Â/ïË/+~<Ââ 8çB5%5ä GŽ™!Гø–0ß´2óƒF)ß~ÙF<¾‚op ¯[|Dëá÷˜ð¨iŽ• ’ÿÜ”ð»ÓþQ¾Írìêƒôð»°‡÷öߥÇ÷Gáã?E•o|3ÿ¶¾÷X+ÞwØ‹ï7L´øÖU4~+UòÃÝ”âúŽbF¿«~ÞàgSaÇô·Æá'¯°…šð°ƒUÆôƒÚŸP›å³Íå–ÉåéJ»pWI†Ö‘¾»l^ŸÍ|qÀÃØwÒ­Ûþ´9ž´åRP ³«l¨LgÚö¬á&ÊŸÅÒÎÆó”™ó’‚±™=•ëÎU%y®6S£0‹DjZD#7\®¤h9iUžbä|Ì©äØ‘ÖÚY¥”bu¦Z¨èXÀj%Éšxe¬JQkLQfŒÕ*r'¡µ¦¥á…Éb;WŠc¶É* f)1Ÿ9‡‘5{’09ç\²Ò°EÉ(­P …Bœ³«¥OÙI4®¦1…ÀÊL…%–îSò!~|l¸¨÷åP½7Tƒœ’Rm½“ ~³QY„…8ôLÆÑ‘ðÞ!×é“~·48&}¶5°êýT‘Ú6ªµr…óÀEÌe—)Ì\¥‘WŒ/ÁcžD)% Ãæp,/Çpk¯Õ`´¨<YË&G%,¯³ó~þf±ÿµœ •þ:‡ð‹m½‡s³­v¾i¶zÖ%ÏpW1^L"Bq¯šF¤T¦¤w¾Ç°©ä"+oUɼQîRUËló ú&uxÕœ7µ¨ªÔ¥QgL낯Ʀ»üò–__Ï.Ov©Õ½LMžU&K;‰”u#tŠ,Nóð[ÚJ‚az¬î–M»ÂÕË~þægáN‹EÃVžÎ£è^w·Z|q"<Å ùýekW'ëx©ù*ñ¸Æ§=ã5“ˆ…Òë4e>œñÚˆ*Df² Ùžs¹„HùpLú0ÖÛÃ|u˜ŽÆSdûU}½fDoìOÔ¹î#ôÞ©8”°UÅç‘2P‰vR®üZåƒößX<}øæ0vU¹‰6÷ÇËWg/Ë,6˜Ìá p¨!(ôgÍÌO¶®×mÜž�GMÄáx„Ãô/¡^¢Ù§é›ˆdÐÿp‹æ ÓÕógÔ‡ìÒúa8GlŸ€¾_âþ‘ð»ÜeÖxr?}<yü¦™ñ{²Ü÷n¬Á“‚mxK-½ú…)¾Õ³ýGâÖ߇öæ!B pô§ŒÀë-Öß^Fÿƒþ•3heŸ¤éjxãôXmòÃû¸t4ÏY˜M8YàáBA/Ç›[ÂSͰœÖ <¨ôEîÏ=Ã`ãbËMO«”»;ÞnWÁ–¹ò‘°»ƒÙ2í.lêm2–YpFm‹Å<YA—BF¦/8ÿ$å^–ôß™¡šC¡ýP·–ÿ²]è¶¿på óJåR«T,å‰ pÖB‰Â-1Љ§2¦\Y.sÏ„µL2ÎXª •K¨<3)Y”PUÍc5§H ¼0V³Î@–}RG®Ð;¸.t‘YS²Y î*IAYYx/w–“f�É‚iæTãšeY¢R3lŽ¡ E–¤„2EµÙtÇ"…l4JÀW—z\Ûý”ÜžAVfYÖ¢œh?á…=$&|6Tëd·Ä×`;M·t½æ£§¶6çÙOÇl()¦i$«rN4帾º<Cx™y«„‘*é>'ð<!F§ãÙeZ„ýpëÒëlsß´ZÔ–2…û,®xüÿ‹uv²¡ÌŸüCGRçÃÿÏÝ{4K’¥WbçjáLQ²Àžf½à‚+ò7sA£qC3Œ0¢´*•¯2󉮮¾\dfUf‰îj iD/ã…{„_ñ}÷;ßwÎá׿ ÚÝ\O j>|HÅg+ÛÓ|"ÛtGf$OÝ!òá%ß¿ðëiÈ©>Ù»ñdª“oÒsL2ž­Fyn„0±¤bŒ}¢?¦¶&çÆFƘîAþv¸?¥ILœ$Dm³WéTãç|<'#­Ó8OûqxÆÄZJKyz¿aƒ¨[¢ÿùxöW‚>.õoZbƒR‰ÏY vÊœL¬êÅB¨MLç,›I2ÚÁj†Æ]) Å“i¬Û’}C’Š^°Ì>Óâqòeõ¾˜^'¾¡Ó=ÌìÏOî§–­“ù¨Ó–âdبC/ý¦ÝDbH{÷ÎúŸlEð¬àQSëˆóIÇ‹"°K«—u½·Ì4aƒ¨^ö¿â»ïn8€ËZí§¿¶ &Ôž³´¬Dû´jα“ŽRÁÝᾎù-êŒ&Àáµ.÷ XŸ_Ãàö—ö‰áéŸ9¿ÉÜl¿ç¬‡zJ?üöE™èå|ÐáOÕg¤×} Œ+„ëŒ=äËWà•%Süæ3cX.PN�ß¡o(`×ÓMBˆ�ÖË�‰ƒþJÍ4.Ùg› ‡_:#ùçefùåó=>Ô/¯äuM5±á6?éâÈ_î¹þÍpØ ŠµÕ  v Èkº°š¢u¥’Öe9N§(yô,Ïœª,D¹úi ‰¢5SVó²»QäY {^ÑtçFß²x ï]>ó®Ú"»‚BP•Kb„X'¶dh‘+É„EÈ*,U-‘ª’\bÌ>¥3IQë¤å¤–! ÀÀyôžÂ¡pFh“(a”ÎÆ5zçd›•*d™ɲ¦HºŒ¬AeAJ«ò¤dg¾Æâ&9jHV­­\ò–ÇRª‹µ(†u«”²ªe» ~IéFiuÈ4Rú‰ÌÕ6VÒššî„ÃaŒVL°5‰»Oã+ÓÚZ#MÌ9Ç}¬ÙÌB®SHÉ»cÇdKж!ªÑAsj®y—"Ò)•°1Z_Ú¶L™åüs½t²Óºx;çŠÜÆ/]qr%»W kÜ^N¤™íµ`gœuå³¢å í~óáÁI O)ß.õÆúËÓÌœ²Ë©YL»å|‹º¼¸GC=RŸ³Çž>lj~™œÏkHZÓ ÖÕ0˜êGå_VñÙ§‰þï ý_¼ìó²R‘B\F&Jå¬>D÷ÜÇLNšîW_Ô¼?(ºó†õŠ·Mhýô“Xihë{ÏΫ¸.yCVsšYÝùrŠêéA¨ªüÄv‘RZRyŒ¡OÃ6Ô@™"“ÂHH-%–âˆÓ¼(_Ì¡úÈÊœ§˜ ´]6¹˜qÊ2§ÃtEÃzn:M/2«¬0ÿØnbï/òøßµÎoÉü¢ï-Ѝ‹ùƒkØ, 7dù|í®ÒÚŒ8Eþ)ô-Ž5Ó¨îzŸo;Âãàq€ø_AwSÑ÷b£Üóx‹c\,n š Îa€pŽðñë^±ø56ÀÑ#îá€æk�º|=Àò]q?|;N†Cbx# þ?æ¾ýÿ2’ ôˆõ{‰°ù¾®õ7¶ß¾ùô‡æ\-À�kF "ÜÔwrõ/�ügP È-¨|Ó{žÞL³`ìß<àýWØOn`n§FÆ‚!pû L©§ ûR+'ñXâ)’rl¹%ÒŠ‰³fjÓù´¦‡±Ã>AJ£3ÝÝWæ£ë¦õ±„5;®z–7¶N—iN<fª.ü‚W—ÃŽˆ‰B,…½nbºÎP6Žû<Þ 4 WàÑÓÆÓ²¢Ó¬ #´Î4‘œ"F^SN¡" "¤0–IÂ-9FW†|¦¹TÒT©¤2fJ– £0œF’=©‘†š«'ÙpÉ…õfŠRRZ*)‰xG™àÁ•‚Lhl©“dG˜Ȥ”.¤’y‡£&ªSPiŒ”úJ‰¢Äd”êN”T‹´æi]ÔÄZÍYf•Ú¸IÌÑ.U±PUÛÀ(bI%I¤íµT]5uN—’DWÙQ—\IJªscN,åDÊ‘®r ‡ÝÑ?=¤%bÓ2Òt ‹fâiŠËŽÉRyÌÈ”qʨX]D«»‘ÊìÊœCXWúK­†W”¬²TF–ǘ„ãW´TìÖ×R?Tfû/ÒÄÉ¡o~&›ÎênMàrÉ5 rh›OÄÏþy:ûÛû žÄgôÙÅ´d£VÉXþ°ah°ëÅùbÁsß]Ü–VöIàêí¢ùÔÐÏÜÿ1átÇ($ÎkQ„ô÷»BO}}òò$ôœF& ‘›™m\êÈIYª8e1q.Ew¢Vh¸ ê”*ìºÈó"B(C{5¡©ÆG/êTïYöÒÖ-%ÑåĨ!¡áÙ”)äâfÑ“pŒÓM‘ÌI%f&!iªz6?NÌónrä¹£5åP`ŽÝjO›hŽÖ‘Ý4xØTW‡êÆT“¶næu6-NíÕy=ÍwûqHö¿š†€„+3âhörÁõ󌰓Ñ8('ýð)ð(`,(_€ì1j ýzºô= þ¦dêÃWÀÑéߥ„CTomŽÏÿ<sÃ÷WLz<¢„×+ʾ+äïí•(€î«w2` Ä7¹ÁNð™çé @°àSH__üð¯ IuÀ*nü›o˜ÞRcê¬ Ó¹ÁE˜^àfù2Lo=›7îuŸát|¦÷—“ñýÍÓ9F¶iÄ{QÑmñÉ0‚6©>ý/RÆ mýdßÎýn5™‡å_hJH.‘Ð/”U ÆáH†I*Xˆ,j‘\zòȇ16†jª|gŠb–òÜKNXÇÅ5ã×”¨Dc ŸÆ2úÚ0òˆÄ.O¼¨&ä˜)%lff)4#šºÌbJzFHu,ÜR5m¸V¼Q¢‘„PJó+šaÉP¯ÌIr¥Œ3ÈJ’!æT-DpÎD’H>Rõ%Iâi*$ë’èÌ&ʦRc…FI9$Z•à’4 „‘jk.+&T44M|f¨’i޹4*µâĜȂ¥œ¯#׺,#a\T&'–S5øØ–SAŒe.”yÛdad#©¾N)>L4¸±qAiýòÄþHǹÎþÓ~\\ìËÂàè°27¦´t2n.±:7$½ÈB,ÛÂÑ‚]šbï˾å/yÔOb`#¨§Ü°íBuËÆ¡IhDdK>¹¥çÇ+qv°l³RšV¸ ¶1âÐ¥SiçI×.M5>ŒþW7ú¯Å°úŽ~Ò^Rˆdë…Z+¹N¶{9Ó—ÓÃÝo?P[é¾TÇ9–YäfÑÊåRÿeæg&Lz>aø-ÄÇ ò¹›Gê³î3ÏæfáŽzÞ–åƒc׎}iÂu—ËìȦéb&m¾@f‚žWCVLÇâIÝ©XÎÕrY´ø<GÔQO:õsIc4r¯³¤„J¥it`Ü%”!Çcv÷É¥ºÛcŸÅBÈõÉE<*µ(®Ü'rpsб¦ìâUÍzÎPy’³hiK,*öãÑö)!‰p¢sÓœ^‹Ëž.ãîýíã!ljwSÉ¡/Ä@QT ¹Çª°'øÝ-–_„»Ñ­=_CÞ� k°%º3LŒ»·¦K%â/ +ø°ñQÕþqÿ‡o!êß±ùþ³È ߟ9§·äD¦?Mmé•k€lñ4`Âï4'j@ý}Â××Oß¼øþ5…ñÕG‹ïhz{-!~Aνñû+ƒã€‡×ß3_ÆÒ %4ï(|ì7w`ø%ÃeÂø-ä'¢û%UKgAýž˜>Láô˜–y)Žgä¸Èw¡VEþ7 •µÂÊÔ +C£b|Y‹ñL9V„Öb£%˲fNÁ!7fØÙ´Õâ%âqlr% %Ï%[QÈ©Ü=ù‚Ó38xÁàF±×­¢*·”**“™Sv®OfO’¦“æVK!h)©–ÊC(*ERJ ¹§y¦>hBšJ0^ˆ.Ùå(2I K,Œ•щ&Y ’®Î°H%N. &žˆd„R[JƒZÌ*Î4%6.(¡d6p» ðˆæ*¬,–gÖ´–©3U:2°JçXX·•*aGŒ›#cÉÁeô™ hQËQ¹\ŽR¸1NãOJÏ™ ÆL–N–7©ÄN{^xvò¸Qc$¡SB„[ YÞOê¾µKM%Mbð<†4âL!ʼn뉨]Ña?Ø>ˆ•©-e‹¿gäz]º§bÒ8Iöi«Õ_X^Ô—©LS˜fÄ{ć4/Òæš|ló æóõéÈØïÌæ?TWVÇFâ§þ’žøEe õØÌeò‡»ÛûZ>þä2$Jâß­Âs.>#úñ¦)¦Û&ì–i?ïç¿Ý:ð(øÝ šŒ- ->!AùÙ÷ê'£©I‘ÊÂ~|Jžƒ‹·ºPM 1(1”ÐÁE?‡ ”ƒ_dÒM³rn®•b,d ž”@­¸‰Iqª”}¦‡“ö'ÚäÂ4÷ulÁ u©ÆŽ¤L£/Ç„¦t&›rSƒœõº2’OÁ¢øQtįïDoíG6„"ó{&M§~=лâÈ?Z…§®,OìS—ž“ žqÔAã`ÓÞ`_! B-Hv„²hÿjƒÙ!O˜*ªðpÎã3'+0ž‘†?ž�΀ ìÞá”ÿ•iã­Äðôá5!îÏS ?búá…Ð(õ]Ð×ÇŒï¡|×Å¿‡s×ç0(Ï‚ ,‡úæ:vö”eŒ¿_Î56§³+ê%oÑÌÀs0*Û¿¼6%Þç÷·õ´“á‘ìµ}Ö–“ü±ÍˆÞjáëéBì)»âÖºF¨’K{‰ì *™´Tgã#9d‰2DRå+©~ô¹žæ¹‹»˜>'µ¸üQ0ÍØP® a(®¦ä%D‰uæéöq–<„ û^ÇÈ…5e T‰|.ñ8¸Ãî ‡YH"„mØB3£(A.!:Ÿ¦¬Ê‘¹Æ”GøzB¥fT°,b¢•1 Æ %‰¹HEä)×Ì ƒŽÌ"æFž+Å:ÒVBhšSÜfià¼æšÛ@mà:‘ñ"x•Tj‹Å%⊵ôÁ^*BJI§ÐbÖ : ªª,!¯r ǽ”NÕK©Z¢œX%c8<!ó<x„9£Îtœä`„M$Ž¥jRbNSr4%¦œCöûLK"9ÉÊ2Pf¦‘jj_rCreÔôRWQR@¢ãD *بóÞ‡}ìçÒ²ÄÕµ?¶1XÇèy^ôyù×¹»>°édï·˜ÔgLa_Fc+aðIc÷”ßQöx)?ؤŸíçy Nñ6±…jâ¦;­Òõ2\œs‘ÆSùŸ¿Lóy³²ÿì o§±\RÙÉŸöBòã¿ê¦¸ð7¬¦T÷GO6;¾<VÙ©hù8’°?õ Éoª· ÿƒ ï`3Õ+Iûþžž…ÓxµO«ìÛ‹6‰–Ñ.K˜bLöÑ ©e燠Éè] ™$j¢sËÒ³~"#KKQ‡\Zê—HÉLD:&›RgéÕ):ô»2yGÑkVÊ‹ Y|ú>S™ˆI»ÿkõrã“Ø_µl-¢úì2µŸÊ 3³´ {r§3Á;Èü\„ýó 72ޏ-Zzù ¢Ç©G¿Î0FùÛûpž‘%cJ&ð"À~„æ/H3Òï ï‘n�dþòUèxÀ—lFþôû•  ûÎíïWî=ë?x‘?.YýgZ7ü`ˆébo%àWĆ5ðák‘5pÿí³_}hÁkÐðÍßCÆŽ¨þ?'!oÇpœáü+©“-&3#'ôì€ÅÓÖ¢m¡àùÝuBÂò9.ãÓô^‘Ý Ï¿ìù±vy _ª÷®ñ»æ³ÝBmï—W* Øy!Wô¢±ûfCšjÜ ²˜ÙòŽò¡èÇÙ.c­…I½ÅÀâl¼㞈§4ÙMÍ4„T¦0»*ÛêÍ”ºÝDÚP‚<Ñl¢í\åG_šðþfz²ÆÕeÃV aAº¹Œ9Nó8αÎÒÜ–Þ$RÃ"M®$êCEÕ ±dÄ8…q,^@dU ¹ú¹PÂ`D™©¬¥ …RÁS¼ËEù‚œ%âŠ$ŽB™Î\ÅŒì{{¢&Yrñœ0Ï8ÑTu$UÅtÛXi̺ëžF™!¤æûä_îǾô9Q!¹5TLû zŒ»i8ÆlªézN+S\´VJ­ã5‡\C™X#!U ÂI7S͸⡔Pásªcr·cÿÑBOº/Â,Kcœ].Wºi©d¼R†ÄSDÊŽ¥Ù>McuÔ3 bqžØÙ‰‹Ø˜a±:oðhÊ©„£ã«—AùÏ5†ÇÃõ¨F²Üâxb)Î*í0ñÝ"<æ£dþÜ{ú[™téÿlÝnèrMÎWtÃõ¢i=#wÞtd‘e޳[šÃõÓ³J’£#.{¾K5$ÌÓ$[Žö%©Í•ÛdÈK)îdšÊágt?›»C5+ÑjVj6r®‹Ë=“¼²¤¦¨úqa¸ä‰0 IBKå <S•éjLs:ò8B*“g)ƒÈ[Ÿ¦šŠ'”=ÖÐ×^ÐZͺÖÎæ®Ö bÊiôá·ãü2œÚ‡æé#I_ã_6•¥ƒq‹N¸3<÷kW" ˆÓšOg­8ÅáŽÄÇ¢r^²|‘[uúÐyö/èøGì€*ëUÐ 4BL¨›5°ÄD—d¿Ž<þËaIpú~�†…c`ï!G°`€‘ÀÓñuìú5p÷ÚháíãÑ îÛܰôïÿB’^oj?|?ûAóúm°…ocï޹á‡5gÌwŠ}gþÜ X^bÙØ/ƒç¯'ÈÞjV¿a½$X×דo­ø÷Í<Ô«X(¼6Ø¿2טpó½ñ;±NÝð¸xû¸Æ•“Ojƒ0vœ £æpTþËhüÕiîͼþ… bW»‹t¶àÑšDU©™“TJZQz&tGÌ‹Zh¨|Þú⃵°" ]î½Íýxrl¼”™ä£a‚9Sæ’Š0U,e$§Íă$RçËÀ¯‰8g¼¥‚¢øO>iš} ¹ät&d ˆ3q,ÑI27ÇÀ*犱@iEÎÎMãÔ‡l•SªÂž&®¹àTZi¤)˜‰Ä Õ»˜ÝhCI»Ê Øš3I§9³Z"¯\)I ¥.‘âLÕ`ºtWjuµá—ì  €.\"ßõ»}'ãÉY{±Y_#öC¿µŸŸ¿<¾`$fSzK¼­Ú+8•"Q<R?ÉDXåÁéR‹\&iáLsZHœ…(Œ”È[ëÃ:zI³N¬i{iÓÂnÖJu¤ìœŸ†C)³­2¸y ¹’ È”Ò4ph$å ³6– º´m5šùÎíêjœâ‡zºoÆÛóšÖœçèžíçßOgC?•½l‡³JZ¶d™¿[èk¬œ_^%û„œŸc-ª%ÅÏn§ýKq Kór¹ç¹b‹Ð'ot¢Ò‰ÄY˜¤ô/æ©ãto %ÓO7ucñø½ ŠßU?Ú'B ]+ÂMa: ™+wŒ·ÞÞ(ëÜå*_òQìN½ ŽaÒ•�¦¢•O‰ó‰¹1ŽaAU=Á.§Ó$xb«m%ºgÌY®-Kç¥.(-Q©Ì¾ìS3~t8®ž@Ù¡óˆå"vì)SÓ5¯Å«O¨þ½ ë]ýå6®ëÆÅ©+ísEN•- ‰?m� Œ(˜ ò5î „D"ÿP([zï§÷ÎÀ'wq\âA,ÿñרŒÁyä§Œ°�{ƒî+…ÔïÚéÏß%Aß 0½‰í  q|ñš ­þ`¹ð­€¹Žï憌oOVþ™z‚þ�”m¨oý‚c_±¯¢Ý$Ãô›SL{ØeðÝÈÖ�ÿfÎýxòŠêšã�� �IDAT+RDÞ1}ûk$|Âñs$Z3ãô ’ˆôQ^å&Î^Ì…ò(×ÃÏé ?[¤—ú)kÖÁ^ u©R »}Yõ¬Ì¶HÊ–\U¡v$íŠ!"ÔZ» 6¥Î‘1R#Ju¬p14B#ªeRþv™ƒm¬É£7“âs,ž‘•Ær‰v5nOž{_O}ã”}ðóqæ‚44´, Ä•@¼ð”C9¥À«59>ˉ"Íqð!³2¡!3-UŠl„-Ö Ò©\¥[°\]â#Ÿw<µ´Ú”xö£à±æZ“ª…1 gN)]ˆÉy¶Ó4qI”U¤[tü¢So~wêõïâ"2‘/Ä” Ëjñèüü t“j¦SpSp®{¤>6L ±.LUêR©s35.ä4L'K³LY+Ñ¡©­œÒbdÓ–¦ñRÉ.s~ÔÅ« hŽ“›nÂqÜàãT{ß/Zfû Üì"=ªmÛ¶© U¦ ÕâL¯h™:•n‰9î>>}¹šg• -a&w»•;wXõËŸÓ^®´a݃3'£•mT×\6òCÖ>]·i?—Ó4²iïÙ—¿ü¢^5 [¶Šu¼"þj˜â@XW÷g¤HwÝKÉäʘÅI*LjÈÉò¾²Ð—ŸûÂxR1¡‘©Ë*Š}ÊG·»×ô\2 i}óˆñ:”þ®Þùº–YÑ©bïžNIŒtÛäÃDºr'Ê|¤›D9 ³õLȈÃDã„ñ‚=›òq…—™—Xì¶iýáê!¹Sû.>š§•iç¼™w†„ì{o<§—†üzÈîb§¸:²U±kƒ§4™ñÂüY2¤™Y_ýHËŠàiƒ–ã $q Ùc¾eäý"79¨J„Q Ü¢/þþ¬8#NžÀAáXÀ°†ï¸'‡oqf)põÿ-÷�ûš½i$–O¡nмK¬û¶<Æ›ØøßBnøÇí·5»_Gsþz<éë•õÆ»Wÿ_~=eü­å£_«Ú~#E¼ö…~»2ñu6š^?Ü#°F3a ß(`_ÕevÍür1º&®“Ç®›ï%þÄNâºu„鬄³áÑmSµÍY:ç­=e‡'¢^­îÉé¤û¤è!Åç9ßÕøX ¦h“…uiy?Òû®Cáµ+3äÕ@ ´¤ê˜yÎN˜fî•'½\z!\íe-V®H §ç}y{výaÝèIÅåÄÓÜš Ÿüࣶ‰›ŠhÂH!H­e‰±™©Bi$µ6ÕÉP%¡L2©«Òœi¨–žrob.¼¤B¹11Ô)òìÖ™™BU♆X A$µª\ ­<¥R«õ TwÌvV5 ø«Ðñ r(‹UíÆ©&ß4ñµ¤.ç‹¥>ëÚÙç 2Rzb"¤I¼$„Sõ}õ'5W1åìš>vÌXË ­ÐÆmÚ& ò³œVU›UçTwTºf†¹¦ìæÊ| î¤ÓØOžÍC![¹Kqª>–OΧç6übñH/Ö ¥úZ¼u4J"E¶ y(b[›""[Š¥Nw&Í„à¦ÒîçeñpJí û•ñÔ¸º\”Àû£dg’¬›å={,»óF§q¿›ïv©ÏôÔqÏ:â7¥xa›v|DžxÛOV ÌÒÉc'ç%3 ·ô ÔbÆ"Pgrg[ú´A0ÍMczÈ·slR–œBéC(/¶”" ÚšçŒ+®ºžÙüüQØE9Æ…í•gk¨<B5¤T#yWc“gë©pY1L™ë}#óUgÖ˳µlQ Ô!ärHå¥_z‹™—àŸiòŸØFöw£¸}Ï}Éc"ç|¨b²ÐS~|¯WH0»§ V ¦tüOô0‡!i0u¨ bÿtŸ.(á Ø}¯0èüá"Êš½Ç¦+®Çš‰ó¬Ä:@P„-N†aàp�À ¿š¾o¼2øê…Fb þ›!hÿh~óŽ%ÜcþÉ ï.ß·±¢ò½Gz·œ*?¼Xin° øäÕ9ï~d€(_3ã^~›€Û×͉7Fy{`Äø €àðª‡Td~í€ß/ÖA²uÊßëk„ÓUó"ˆ}ß´›£íÏ£é cwìúa}œß\¤†9]FâE›5C‰Ã>ç;¾Déñ#¢Z«2ˆ/ù¡„§“+ÛÓòn;¦cÕôÆZ7²GK —e&j„9%ÐâN.©™Š:_äÑ’U¬|çf·5¸2Íü ĘW,Õšgèg ¢gΦEhÈbéÄ‚A¥@YŽ©QLW)k‘´"$…p$R+G ”œ#éʯH™™KlLj‚œV¥#ºdÆbH>&Á $­„ž+TÏâVTN^+ÞãXKÍ1šH$@BMµ†Y%†š _Í0×Ì,Ú ÁHð7=ìŒÝÔ|ò™%7{ŸJI´ªš ò"‰¥à¼µÁ JÞ-Ëî¼””ݼÕ/c²V¨uׯU% fJà§JQα©·'§÷!µ~³ÚÄ$éùCJ÷I¯ìòbu¾n5ãp½ƒ'.úOcéûiBñ\csù0ôºþðEœ?7ÁZćäËÁ_ÎQ?ÙZÀPµæ¼%p-÷“evñŒ½ÜµÓIœJ¸lòeq`™Énø‰°¤y4sI;*<›†Õ£éVù@†¡î޹ֆ5I)/h\¾¶Ò««£T±8#MÓ´/œûó¨ø”Ç‘®¨W„מ‰¸0mM;4¥BÄN^™ÒP_OûVÒ�ŸÒè]ô"˧K²?ÓO®uwn–RˆJeIuöñ>¥ßUÒ Ù5-ôììߎêSLîóÓˆÓx;‹Û¿«’èøürhf›:S%y§üÕ|À=ûlA)tu%¡BJ76ƒžßŽá%Ú€‚Ç’6Éöl=o„èöœÝ/.ʽ{TC ¯‘€T€OÓÛ̵À¿¥ùö•˜‚}5 ù¼Á� Ä·#Äøƒ)ÐÛð_Æ|¯F÷dýwÕŽî>D�úÏ~àùõÕüè7?v”� \/¿ žšß}±�»×í…á•ïÙ×Ï@¼®àºÃk6ÌôªIU€#Ô:¼ “«Âà¸Ú“†ß6áÃtvÑ´b¹<˜g)ÅÕ°ü`¼4O¯c1§šã´w±Øªë<æ 0ˆ ×Å‘&Iˆd}™x„‡yÚøm˜àOú¦yøßò´®îdÍJºVW¥$i¬)Ì»ºÌ†¾_¿®ÏrÎ)}ï@#+·:>T¢‚<ÏĤ$º«Tsà -IÌųm- >kP+ ¨%I TS@ƒ"‰0É)¬–”Ã'SduÈÞÑœxÖ<§�Q’Ôéi¶lLÔ‘*I­Ú§’¶sáJ„B£à%•¤e²…Ö•Ù”ù\Ýœ†ýtç™gBHÎ%ƒÑHIƒë§c™³?‹iªŸÇþ.£èN±:”ã3¶ý âÝDB™§¹ÚÑ/‰"‰ï¤uŠ’.˜æŽ3.8£f]$‘H]¬ò‰%yÆ.„YdŽœ¼t^zO]r§T žt,JÍójAäbh°™ý_–½œE;À†Dd)äâæÓ<¢ØÃ¾Œ^÷‹ciÉ™§yg¡áÌ<_Ý¿œ²=ß^G,6h[b+>.ÆvK#•µv%&?ò¤òdˆTJ—ÇmÔÈöeÐÛHÿEã‚ä÷ÍãUaγp"s·Þ7¡.³"µ-éR×霈+%µìv4Wâ›ùBSNk¾Oe;O-ˆ*U0I-æ¡T[>eÊ#Ë¡ç2;®hb$#‰Zµ~ª•-Då-«©úêãè.“õLªÍœ6b^“i•)϶TéêK @ˆeôW!¶<ªKñ¥~r ¤½¥i¹9̼ŸžÍ_¼¨·wlÍ×?2l….žýê’úó˜ßÑ/<Ó„üÜ6X­Ýf/Ž yìžFvSÃÁ׃¹ÆrÒ–lÉWE7Eþ8C©ËSDH9ÏUÏøòn+Š@Ý}sS¿Æ0(P¾ÈK€t@¹A^·^u1;@� „·faþ_8þ@ÀÿÓ5ºÿýµ£ Ö˜ŸÖ o†ˆþ¨J’~ô†0=uÖOHÛ€ð• ß ^Ù-€ðßè@d ËŒuX`ßP:¼ pã%À^Qöà`$èaD xŠ戅G¡*ÛÇ®½Ü·²\ÎØƒ-‚üøïc}ë™nBˆÃó0/ çNž|xà•¤ŠÓøâ:G}¸Ðå1agÁ.xãÜOÇßo÷ýLŸà_¯¼ÿÅ~¹ü?‘”¼¬e!ëY›xŒ2!gVæaMúEö%B:äÜÖPS%‰,*ŠÇnf»T5ëy¬…VÒ@³Ù”R‡iŠsbGUÞ³ÒZÍÏm(íRÑ5ŠH­4EÈ’¦ÈjMÅ#zøZû —ª¬Y¸ Z%QkÉɉR{Ï]…MµþdÇ• \¢ˆ²zÑhkÁš9`Ça¸¦g9ÄXH¤zWb˜K“gކéeÙ.ŸÛ¶5œ”„‚œê�{ Øñ)gëIu‰öc¥¡y-Út)</Y °Z I ÙÒLš‰fû ¼Pbit¬ÂSÔÌYÎI©™ŠÜ4Jj?–<×�Om¨s©ª“#S %M|ÚÃaN¥& {[Um˜Ty"™>#çÅŠ—?¯ítÙãòöµíAàK®+Ÿ>_¥óë͇œ_QºàUóé@¦]Ý?óÙåu“S©…Vþw°CŠ—soøcm¾e‘á–È55×S6¬°¥¬ë2.¢¶u]ˆMÄíLmÛÖjÝíÒÖ“_ËqáÉÊ•ÔW”œùà(.êQ’ÝLEÊÒ!'d–ÚÞ› õ#;Æ~_öÛ‹9<#—6ÕÅjâŠoºªX‘¹*ÔGYðB¶»®j]­KE8ÛÄ\‹§ !Ì{È—{󬇨ç7„¼²k­ÛÌy PÍ…Œ×vº¸O»{õëšçKz#ÎåþdQ8Ž5Drƒú3¸ªäNc¶úúD6BX™§Fîöú÷‡}عº>0Ót 'òj•°›ºû{·¨ktû¯!†0¯‚ƒÄ0¿-ÞÅ?¸(šòçÉ� À�/þ${Kù‡çøë ø¾˜Ò×÷|Ž=›n(ðüMˆ—(7¼ª~X€�ËWnno_ðâ=“w+•þ9¿W¬ÞÝ×r±_ýõÃWæ„„€ @r„3à�×8\Ÿk¾z4tF<<€Ì�Ã"C¼÷[!Qס×䮣–éTD…>Òùd¬E ]ØYñ/ í‘nÚ±ßðqgï.¶Þœ~úˆ)÷A³’'æ"²+™Æ¹ô§0lõŸ@Oá@%äöJü¯^ÿÝÄÿ¶T¦s¡ìVsj¥ÊahXÏ}r¿qµ£…]a:¦“)Ô*ÓŽÌmu䔨sÃyÑÒùâXô ]+4WF, Õ²hF˜'Ädc„-L>"ÅrŒ%Ř2 qœO¥†Ti ´ÊE+H„ Šúš ÆªŠ®Tò©¨r± íYd EYkMcÀiˆ$Í¡L§Ã¸ Þ„ûÑ))u%LóvÈsH*QÂàw4=?¢].V8—B›%ëT€l™›' \’ y¢Ø7›(g!8¸TñòHÑEQk¯—‡Ê†ÓÉû“Ë'U ÷ðÑ•«~¡…@%”Š–ÊVV“ŠÏÇÔ4òчý”q¬Å¢Â€ÚÆt˜™Ù¦*"}ÖGB ­åŠšó“0RDe¨êìš]S–WªKÂ6gš]»Næû§‡í?lN1ý‹”ÿ“©¶²•« ©#wǼ£UUÂSÊFÔ¾0rµ¯m= ydœÞÃî´Öí¨§hfÒ^²ªª$ÙPž}M®Ï”¤%†öÑ<,µ t:ŽÇz±ÿ‘ñﻼbLˆÜ+ZÍRYW[F¢k‡Ìg‘·ìnÈGYoÕ 'ê“ëé8÷ml‰³_Ž­ëõRåÒe†„æ,i“èy5gBB#¯#©2R7gÞ¶’zíÇÿ¹zÑxGÂ}ÙÝø¯¯-_ÓîÅ'9NjLxÞ6[~ìîWt¦U<ÆúùÎ&Ÿ#ÞaŒ¸²ö©C|Ì· %ïÕf·>zUçÚ’Ìç/ÃöØŠ}Qé®igMÉQŠ£ÉÇÉoQ°G–Páu`X�b ·„ à7ðá@/€Q¢ Üþ6Þ}÷¦\ä·ãÕwk` з¥?Õ»Mè?jÉöç•äw’Ñî>coœŽ?ŒúJôü›Ùõþ‡Î ‰¿±Ðo9²¾fMKà)»Øó²o·^õ­;,9 <#A¢| ê±Þc´øÐÉ¡ÒçŸÚÛ/šõ­~‚Aë‘} ‚=<”ñþyÛŸÈJðýj�#Œ×¬Úyaµï›þnÞØ;ú9Ù\^ïݲuÌ+ï³OÑßöÅŽh#ûèƒ,l]­ä¡ýàùä EB&#=ÖF~Û²Y…º™sãb=ÍÃ!øÄ'ð4?Íl3£Ód¨<×v`|Ech¨çÚ+á×Z4²mVÓZ^J¯Ì ¡”RT1¦i•6sZ«/iHY† B3£™Âi$¡U°Â¨'¨Äq$3M  – ±h箉¼#D+e˜à)&çr+ƒÊÓ8óv;OàŽ ‚&çðj%¾ºF ¡ËÃ] U‚ÉìW«Ybö«bö¤zÎN”F& E¾2~€|™£!:Gf¹PYË#gCŒ1ô25*¯šWJC˜S™-o¹ÑU#h^M¦¹'_¶I2A}€CêqyòE‹&ž(Q&õ3là²QáÌO8y’Ct6M">Ò¢)å>Òí•|Xa©Ùù0ç-oØÙÏÒj´‡}ùôŽþ×ÙºV{B=ñ‚ñ÷$G4I:¬…vž•žÔ²Kù٬˗YܳÂ893 ÑÐÕ ¢£l¦yÎŽ L6úÀ°à#¹˜ç3¦mS8õåVæG&ñnSÍJC´ö ˜"ý-…Ä™Gg$«Už¬gÚc3¼ìò—Œ\DZ"Y¦®•„«Æµ2 :UrOÕĴͪQZó5“ìsN¾ÐÂP6•P!;ßQ¹ èÔ¸6•¬ÃF“±÷~¤Ò¯… A~:ÎòÄwàÏ1c»]—~/C–õ£§h÷Hç6‰5§®¨SÏϬާÍzûÃÃA®öv_�”¾Ö¾$œžƒ}NÂ?!g€“hŸ‚½ÙSž$°F_p±G°z‡fõ6 ÁÞ–y·/úC&øß8Á½…>áOv*àV‰á­M~… ýþÕÍŸ~h1õ+~X*z»R€!±yŠÓÍ×#bg@ }¿ÇtãÞX¿\ú²·�ð9ðs.áç ÷-î¦�xÄs&v/<¥óﺼxÊ׳”;ÉÈï¿ åDªm~’Y5A©Ò–㪯gÑdÊåPèx§õË9?<— T¶¼®Ú̱°]ˆÿ·' .?ÏSX·î#UDçÞoºÄrÅ›W+“ß«)ù°ïÉÿÀÜLG(†’2îNóªUkж-–³…“ Š9Ʀh"¥qÝ­Ëm*%[k±2«U»°FëJd œA¶Ò’ƒ'0Îe"ñs, ÉBKQ‚ÈbÑ:IUR`…/I¢ò’0™ ‹b¤ÈDµŠ6 ©„´œP‰êS’5X6‰zŽ~ø"ì†rG9P£ˆº«ù”Ê¿óŠÖGÕñcñK1Äò¶×£möÕmržY¦žQßðH9ú Ω`é¼²÷5Ä+¥T¸„8VâX5$µmrÑ8#²ªBz$¤#”ÜœûÜ·‰®‰k È.Š]Š-Š˜ž†¡¬*î4ÖþÀZ¡¥ÑDr×[w[J†f%I“USÈ ¾êyö+e(ûŒéäÒòta©%Áîñ¯‡Êh—:?§#«3¢ÍÿwoÖ$Ç•f‰»ûkîH¬.vº§¤–L-“Ìdš_­L&3IORÛLUMW³› $k„‡ïw¿zH$ € ‹õXuŸ2Ã<<"Ü#¾ï»ç;ß9y‚”vžk)”ˆ´e‡ØzÖ÷½=: c;ìÎM%_Ëu¿åiAr[ŸF“ÑTFË3£ëE¦cÊ„Ìúžø“¥:WU‘–.ËLMW%©fætQùèü4åúëÌ­eA‘¼÷i'ª[^à%–Í”-Ñ +šS!©^¦S!?Ų°d/åíG§Ùņ/rB½7&ø.›†qºé‡vô‡‘´:›%ݵ٠U<ÕóŠí+ ·R~¡˾œ¢% ù§Ûtíw¯á€éY‰'ëîîÇ/ f½ìÖ È4®ÙÕ½×¥ø´oèA7‡„±•îÛÏ Ð×K‡p‰éÿHóNÂP ²‚,:û†;TX<€Ééçø2þÏcðË9Á½ƒb‡¿ÞÜðÖñ™áêùÏwª2Äÿìz`þ°�ÖðÕÅÍ»÷ Æ–£öHx~óVæ'�:[ÈÌ©`õÃø•}¶~½}NÞÜ„=v�ŠK`.÷°·R½Î«#jÏSˆdÜÔ"¡ªÔSöë…ÒÑM~˜&#wC¸?dÈ)?—/«HŸeK¹, 0úz±2ÌÕR…ðÿ ŽÂ|¡ù±%² Ïõm#ï¢~;+‡ÕV<¡þ< GÞÇàºYÜzþ á0æúõ;‰e?ñ«1G¹ý41Û Q™¤4ó-w#´cßQ&W@F`ù0Ô̯yV'Y™{Æ’ªä—RdeŽzI€�ç‚KÉ'–\AI.Áó¬£ÒsP^(O$%¡”Û\ B® ±ô4|¡òš`é@àáRŒ‘DDïtpM ICФ±êk‘J*øÖÚ`^?ºµUÆÒËH¤ù×AG/ÎRN¶<óLŒ$“‰'hÅÈ&A²¢àT>¤v:úÕ<çÂÈ­cD’ô–1«ÖTqJÉÞh«-éïj{-c6Ρ¿ÚÍÃëàÔH`¸ºÄÔFž-} .cŽºîžj͛ۡ²ý2Ǥõ¹ê-mF6$Ï(§©±h ¨%›'…RÙÎã–7çtüÜsÊÓäÏhY~¤ä"Mìzïì„9ï£ZJ®X’*Œ'²8(E‰ø‚å'íðÙÍ!{5¿?)Np| %“§ùÈCÊH¥V•ܲÄËÌæ„”Ž{ÄJdü¨GHG¡Ìfqǹ^±À¢ðFÊK0áŸF4ÁéCž2ŸÈ0`×þÖ"ßFv4¥jâ)WŒÓœ²$åüô£™ÉPDYíWµYÕ:Ç0ëѶwíí¤ó!\uôuh6dŸO!w~!á®Èå‹ NIJŷ<-W´ÌÙØß¡¬‘ PóºÜ!K›¢ä*áK{åÚN éˬ³¶ç Â´@ÓZЯ écô Òûä_B�þ !)Š˜NÎ!¾V•UÌv=`ùÝ.ç `Þòžüitû§ëæøVëôý¨åß&ɆwÉûa¹¡ü 0ôöÞ�Õ= ßn§_*°ñc´Jý ¦û£¥ß~­·4ÀÅs°w ›Ãç�‹usk ¬~3ü¸¾ÂÌ»ö&o@øPl¬€SsÀ®XÐô4v ‘¶«â£r½bÇž“U˜ný~‡tow}ùÝ⛿Iü4dlWmAÛã%ž9ä¤/’¢þk¯`®Ž”ÛNp4´IkÛ¨TæÝÅáã#»âmeŸtZõÖOò%ä/ý?X3˜ò$Î<#YâÆ "¼Î�%Ä0RCؘG$߇!«g’1dΫ”w©’ùâ¤ÊC&&¤cÅIV@åI€P�*l$“‹‡aî¦9$K¨$öÁrn¶ž¦“I„<S–p• •qF±¾ ‚§¼ä¨AòI3ïµ¾ë°gÍÕrÞoÝTÎò’`é±%óšyBiHdi%må5“ƒy=ŸðU ksÅ %†EM|ˆ0‰»£TÎ>†H£™Ÿ§>ö<7PÒ†ÒDF ›ƒç˜U$°.Žw}ßN‡êîÕ4ÝqÈ¾ÇØ¿Ô·.¦ƒgÒ¡¨^¬pn§Ü0®E/V;’íyÒÔ.‚Ö\[FæÙ§2?.yÈò[-éŽ}LÑÁpšµü¨:Ëï «Kâ…*Ëãu]35úxÕŠ6FCle0«±Ói´:„&O…s›Ñíi*oxñÙ²4UÖsõBz"<=RE}Z°5 ‚Ò´°V³9Y„º’"‘™0MÒä ‚ËéLÙ„à’•áãŒÔsœû`¹­XΪHÆÜNìBÚWlËB’Ì*ÏM"[”üLˆZ˜Ùß¾Mk’‡ýý|}ë¾i§«ƒûϳG>|Áȯ¦*¿æåµ ‡ÅIÍ‹tb©Ø¿®n]‰ÙöZ¿XÜà×H)“å3X)e°i¼»ÛÉ›é`‹¯d^Ñ> 8Ù`z±¹Æ?Jõ¯×c“–@dÉ"·_q(`ôÍ—¨(-d¶,F¾AÈOkòí–ÛŽ�{À¿sN�(àÜBÞè;#&ÇR¨ù`ëô+¼5O7¿7ü‘Æ?™'0ü´Ÿ…B2oò„x°Óùù¬«.‘ÙGn üþƒ#øñÈâн1lrÀíø²k‚O »·Ê‚¦Åe:$ÌÏðÆ}bpn¶eÄYtÿv2‹ÐšÅ¸«ªôÉvq¢–<S&Ÿ4F»3]ºk²)æ·óµVF¹qµÿ£ðóHÖ{ò™Ë6¥k›iRdCD°õ«*®WD­×§} ÷´)ù›µùl9^œ’È/mŸ´Ü+µ[àBð2ñOú¥Œªpt€!½“‡ûc¥™,&–1yô‹‰l–­6ÛEÆ£ÐW.0#Šü¢Ç™ÊÀ£§1%K9Ïû�� �IDAT*QÂC"Ñ ^xíyïép›Ãa0s’ž—¥’²ä£’*zb£v³MMâY• ®˜7)#̳LŠ…àq ~L>1 ?Ný®»ºÑ‡&2“9–y{âZÙ3?P¯M3¡3it,M/Rªsv;û í¢¯v†Oƒ™\ Òù° XFºy/ýL‘)J)OÃ0Nñþا<ã\d$;Û=åéBÏó¨Ýô®ï½Û‡Á^wz˜öìÔݤŒÆ°íýÅ]R]ÅH§²—”‘fŠùHÁ9ÕÿojžWü¤ÎÏ$Y̘fýMáÚÿ g^T�Ï’a½U(=žä…Ëfq GþW„)ž±½ª)—´K(b/¼tc5 r縤ädé…HŽN·jçÃtä>[äÕ±ìKB)½!ùëì ŽÓ²ÞÔ<«´fQ%— ^¬ÅI aöw†ÒäL"*A32;JÇXp«bX‚ÚÖÙ>íÁZ¨.KŒªF§Ðêœ{oD0ð)-øL¤OµÈÊR¤1†ûƒÅ«½ÓQ“0Ãýa<|gш±_TÚ¸nÅ^Ùù‘mŽLó·…ž¦„.ü³S_6=`¶¸ï{‡½•+ùäˆ!Û6Ì­ã|¹?d/pl€C&ãôºBuŽÐÔˆ¬ÜÕþ GK-¦ß¥µÀs‚Ö=ÔìzP6`Õp{LGØ­–ªúkÀ¿U³*àö±œpŸÏ0 yH ?SÝÊ·ú¦oZ§ŸígŸßí^”W"ÊþåjfüþC‰á­‹øƒ·u¿D†0Zdoõ'ØåK ~ÜåÄŸJ<gÿ†| Þ¾»£(ØsÀ±öx, :TרøvcOe®£Ú?9üª¶› ±Ç‰l¹¬¤òC ƒ9tÝ«¦ùæÕÓ®°ètñ_¦¼ÙÞcñ õº s”ÔÚ•.Âûúà'¯òºIZeÛ*¯c–…(])Óy%϶ëå:›ÙW¹î³|›³¼JX¤ûc¢Ò†­‘]{Êo„…°v¿�Mj{p%Ý—Fò.÷ÓÑöÉÙú#ÉlèïF÷šðßø\„;ñL–<±2¥@à&âbÐn¦d«c¿ë§ eÞ8—\‚æ*S$ Θ¤ªÈbôZ3d‚Œ\Îñà,Ds *0Dë&3ÀOÞu;ÝïƒÑ9ó~©Ó@‘–¥?ƒ¯¬u; „4uØÇpaPÝÓùÌ_‡ù¢ð2èeº™6÷doÙB˜#bÑd0EJ ”E{Kîïü²cgÇ¢*h²;™7ÖSîIpÄ“vaüì’]j"¯Šû™ß£ù&Ëÿ´˜Fõl”Ù4q¶›ÈÝHsËœÎûðr¶åœÎ«ÙçÝ:ŸÿÑg'F²¸qOØóä‘ñKJ>JEé$·ÊPun¦Y£j÷v·°;9.ÅǧÞM5vE9å2–K™bn3eOx¿õw@kY©Êld!Rç–*…„ŒåQ®y%“ aÌ3^Š#!·+Yt<MsN‹L–j½Í6ËID¯}K q’Ra“N©6¶˜´7i²<FK…«TŽi*|7»[>wÙî„7d^É(a[7((sãW£7Y²ÑÞg}¯öÁšp3’0µqtÛŽ<ñÂç¿bapuÃ$>A Þ¯GæF·së‡å—s$ 9‡{–äï¯j«äñ*rJ…Ûëïí€pŒz¿(¾•Dg9…HõüÔý®\d-K;N –¨Ï¸CÑï×P—€õÑöA #¼é‚ºÝŒE ±rûª·o!ä ‹ˆS  ò�k@>ZÑ$ZËaýû‰áíê'?öBÞýÜfàÍRÀñ;E¸üëÐaý‰¶AmñôûGƒh>Cã/‚•,pó'!¸wrCÜ÷Àd@ ô@Ø÷š>ø¸jAÞSÓd†BãñØ”Ù~ª_§fèÐûn¿V'žÅx®²Q惎hk÷ô~?ÞÛ—¯î÷ß½ðPËÿ 9¾Õ¨ Ö^~*­Èþp4¬‰:òćìG†¼¤qNRÔ‘¢ÈU)¦›ðJÑ%K«À¸M’$^CT"ÀMÖá?¹;“‰j êE€¬×(N2ãHqÎë: ϲ=/šUg…\B˳Ší©dNËi°ÞºB2¢¸çÄÒ¨Jïi 4kíd¦iŒ œxæ½q9+˜aœH2Öy®Š¬fbàa¨g-#ËK¢–H9B„eR%*É›Q¡à‘¬I‡Ãd÷£îù¼_'×ç©wÎZ©|'HÆHæï -“Ìx–©3K³§ö^N$›yŽ3+=ô­WnN¬Õí\=»dÌ”’eÓ4ÍñÐÊ¥v—/+•çB¦22G+¡±SzÆ8¸tgScFj„ΓU¼/T†úßÓS=T`5§½$Œ¦bXÛÞ«|÷¤©.P÷ç4ÅÁŒÁ{NØíÊã.kqãSïð|�˜“’ÜÑør«ƒ è 4œ07Dêy]i¶c=j½?±Ž¥W2ßfeÍŠšúD™äÙºT:´Ù<)/Gã{)hžyyµ ÃÆƒšš¹"ä•ë NA>ò)¦Œp’x-¸(Ò²ÌË:—5¥t”Fdr½äG<qëCplœ ™:âµÓ3³žÆ¨#éâ²0Çtx5ïýjÚ³ãOX¦"Ë¥#“KÚî::ê)êb²1ÞξçVçÁÒ@Šƒg*RZF¬¨eÙáÀ]¯IÌE:LÓy{£5l�Íé3-lº«!ŽJ;Ë|Ž«>–A·û½õÀ+ä€Dî»Tnóå°<F pÍÅþæWýœúy¬p ¨>íß`4Ö~O å[¹òvø¡ ”XŸ¡X¢¨¬„Ä£u±ÀÓ€G©ñÄ kHîßÇ}û.ìñÓòaíð ÂW�vï$†'Mš?Z+ ³?(vß÷ú©™*ÿ9nÀûë(þz<|cè£ékxs¶3`�?ðeQáÙ žàèî¹vÈç‡cŸgx¾˜‘ìÐ�ÿìÐ%ÿR­p!¿Ýæõ‚–zgûÞ íçp ~¯¯ËÝ×GÀ½É,‡õ¾XU^fme_g¾ñäÄ-YÎU>æg(’·’—eMJŠ…Z†Ë,ç.ƒâôDPH£Õd ô±aö?raN"@ÒÜHÕD¦À&V&i×Yû¤PUfïõÁN÷­D–-ò<Êarbç8#±®SÂI‚”ñe¤ŽP2ëqèÍàõ)Sq"12I,%“kUn˪(‹ÀUWxŲ¹ ‘Ò–DƒÆ‘2K˜¤, Ï£¦Ö˜àç”ÃïF:šd,!.%≉j¹1a¡Éj›\\ú™ *ƒ&߶éÔ¶+­ójV1ûˆÚ_Ô³e›6Ü`|eïŸ7=ï¨Å¢S¾ï[ÍêÕª\ëm„t,?É4èu9Ç2öØO––6{ÂE®ÎÆ,7î`Ó‘Ny—P¡çn4NÜDÞ¬ž”b™›Ê”ÃiÈkdÞ°`ÈXˆÊIFÞÍ¢Õô²o¥éofóÇœœR"25¦<¹D^.Ø‹¼ø–ñ³ž¼¢Oz”b&Âv2;ÙÄ´J3§ŽXR÷Y5Ëäá´³s/¥Èhž§¼PK¿áÓMf™²”ûD˜][QȤâä)a–G.kKQÆ»Yn¬§\&±Iê”ÊJ"Y2zœ7c7uþ™åH…e¢u„GAÌE²'Y¥Z7Õ±£´·Ùuײñ«Õ——þª÷‡¢|Á³ó"BóÔ–g˜‚¥­—ÈBâ&¡£~œ_wÍÿׇl·=ÑCµëÃulµ,ãùÀ3ýÈ �Â>3Öú¶Øë‡xý-Îf(‡îä†~F2ë0Þ0?1`Æ^Í„z3eo&^{¼ÅÚc=ÅËðýƒÔ"ûå¢ËAÿõÇÒ>t.�oÐsÛ’ˆ|‰®ù1õƽ3še1]¾ÑÖY�ÝŸ; -¿çAõß¹Ó_ÃO¬ Ø¿ÑÖþe¬¯÷s‹“<Èâm•ÄCR? u=¾Éø~ßá?À¬…Áã&Ã#šZ>Ÿ50Zin9ž#»=þ¶—Ýæ÷ŒÎ³øÜ´åË›nÜV[6e7ÚÙ¹[kÐÇ;½>øãj»)ïÂe9ÞØÜR]â*×ÚmFvlF_¨Ê~é`eLO(_Æ¿–éŸ*)Yc˜)G3ý·R­¨»Åæ+ÏO)G²Œ§É¦~7å÷Yüï¶Q”œ=­Vç’çzêfòÂPã³U¨Œ°1i>щ„,„Dòi4Cðž³ÁÌÆ‡HœBŠ %1š<Ь̳e•×eVDA@‘2µ ‘DŒ6éÁ g88 &ØÉÍhtl´Ü8®‘»Ò™8È´´!ДԎ`ÊÆB‚q¼ðJÓÏl–lQ$Q•h<Í™¨Dª@'m¿b¨DU¡ ]5V|Þ0G¢ìY¹r)­È'gOŒ§ÎX£ŠD×¹ˆy¹q]Á÷Mœ‚P±º¶×0¹¬Oël{–‹ÚòY“ƒ.,ó)RÁ9Kk’=§ÉÍ<¾rÿ£nk™Åÿßw–—ÙùŠor“èþ•É_– Ëê8·Ço½¸®=ÍñkÎŽXVgˆ Ö1žo´ÌF:›¬Ýéz‹…8/E–X墕s¾°‹Üè<j&Gy”“MÁ«לë"Eå¡’`s‡y6Ñ3^@dŠ0iÀxòðÔ»0ÝjÝXÖ ùiôEíÁ“Q³…ZœZ´´å|Ð6wm§[³ãí>áè¿I˳ú›%jñYžqˆ(ra‚pSöqÕÓò) y!ô"²AÎ-™'×\n¾À-$& âFø¥± ®Úg£“ikûÍÿÓ lÆhŸUBÕßYÖ¿fÿ³/rî ;Ž£}ü…âì÷>·ð_[]˜ÇØò0Àšú%¯Þ—ɳ0÷ ¯Ñ<üûCáÿX ¸ñ�Z¸õ›Pó†ÞòƒÆ3ñ¨�rŠ®®'éþ  ã‡ýAóAjúÉùW”f ‡�>06ò#þÖ¶õôo†™Q‚8o¢ÿ )öTá=þãÜàðs‹]C’—0OP^b´€ì_…ç8=‡“hzùåÍß³¹íÿàWÓ7û³×TlY¶ñhz}¿�¦²¸6ç • é$ßÔ³:·)‡<;›IýRfÑ0uß0tᳵ㓿á#<7V)Q°cOÐ:’´,ÁDä©(>#äS[ëÉņÙàa ¼oëXL(Û\Å÷[yržŸ_Ô«*¯gpÇZÅîiÑúr µ²lÅc9{mÇ[o‘y"HâÂX{è½Jn’ÔD0 •“4é© iÎW†& ¥©ŒdéP†@Áå((@`è<†áô<‘4#²è$È”H“Œ¶=ÚŽßL8¸”¼&d¦Òx£ a¡ˆ(m¯“ 6‰†ÑH³UÔ«yê»l¢_ÜÑ’d4žõ‘ad©êM>u “ïRÝF&iÍOkpãÿÖóçuúœ‡œ¹:8hŸ¸ÊC¾$ÂÙœÜ;vë­›gæÆ„&R”ÉÉÔ„º›©¾¤Ü§v¹‘ãÈVÅr)êÒq•Hä1õ~z¦ÍaèæØò,w›Îùûñú†oŸŠ“'ξLv!lΫœÛ`Gfúšnk%'YD™ ÿ«ì°¥gÏhý‰’BÚÖµ·%glžLï~Uù}ÉOŽÄ²GÕ@5ÒDõ¶06ËgV§|S©ò™Œ<#T%pN c–„ä ë3™ñD‹ Uažá¼!>õ“oûÝÞ¥C(&̳÷iœó‰K2{°CCËí4l*Á²9d·“×ÝìǹXs»¥Ù™ç`Èšra«(ù$멪zÉR°P Sr² Eí>¹Á¿k_€)QËØ‹¡ _»Ð`0}ú´›©h…íVáA>âˆÿ¤`-t‚ÛÛ�zïqw|¹"ÖT Ãõèl5P>2G ШïX‰ý{¶`—ª òŸaɛţà¶ñž §Àà8Ûc|‰n�Ü[ÑMÿY‰á!D|Ðãò¯¨ýÄÒ÷f öÍçðCQÿ®æ’J°Á=�Fé‡mÁ6\á'NNAä8¬8Ò[NÔ¶Á¿ªA˜ýjy[ †m°—3ìÔ *`ÅÑrk¼¹‡R¯äWúu+^CaGŸíÀ78–(§ño€£iVùí![s:ÉIž9«Å½,ÐOÏnã“oò;¥¾©õÒØ© `V•æ)­8Çûl\‘¸‰cu¨€Š° uíEM)qcMt[\ÁíCä¬RN 3[%ŠßVü)%‹¬*±!7tªrRr±œè§e²jpJÇÔҞȯ Ãá}:&ãL&¬™SàÑ8Ë$!#gD¦D=™k}ŠÉŠ”4ˆ qŽÄû>ÚavcoÕ.Lљ DÂÌÜŽôûp˜‡XáíTæh%y¦ì]ò#Ј^ÌXV™tyÔÔ·.¦=Óˆ™á3‘ÆæI$W‡Ëq¶DbÈ¿*„+Äz¹ò•ˆ|´aå§sžÎT ³†,„ʋĬuwÔ}7§ÝÞUݬŒ;$ä3”æˆ+²›¸Ö›nk³mÜÇð·Íb—²Œ•mÄ Ó0åûœì½[zžÄjóG¦±ã¥qOãoâ§5 æsCò¢:‚àþ…ˆ%¡Þ¤ÉMèåâQ›oŠ-¹ümZ¬ˆ¨é¹a§ÔDr-2:éÉÏ.κŒßrò‡hwuöŠžË˜’L‚#JN— ¡êE,%2ÅpŽßOY9…< táµHã÷8^Ò“’Pæ‚In" tœ­kswh»ÅÍä;“úqLS&ûYÉëä^õEsík£Žf¾œÆJ_Êùÿ.ü¬ÈEª_+ “žñvц-/ž„Ŷ¤†¹RšçFKZô4LTæ4N<Þ^?&í' MÀ†€=0û#‹áÛ­ø +‰$(¸[Á[‰V3_e±afºš»½ÆÍ÷V;Ë»æÁXmFìôãòøv x¨æ3 î ¦O°n1°éÝNr’8ˆ…:¤€ÄÂb � ):ü(¤›Ÿ‡K ~}¿<.åOÌ~ýµæ†øS³o^o%†5pŒøö§!©õ#KìI‰Ëð8©€Ç4³t¨ð¦ãü9l÷ ¦÷ÃÊ€š!»ÀèíƒìPˆhs`ðN(Šˆ¶€àŸã €Dþk²Bšü¯qW¯Åm /ìúVŸ[—u‡²¼ï4¬ÆákÕJì‰!©Y¥™zVM²œ~#ìGºZ.èÈì¿Îaþ†5OÖ-²Åùò‹Ä+Ið$†0iJýWœ_Òü"çÒûÛë©!㉖r$Z‡žÍsꜜ“qedŠi‰7ÓÞ¾ nÄØg†³òdËdæ€d‰R—QϬˆÑaJL¦™x'h¶›¨[º1wÁ;IŠ@\ô^îŒM†ð bt¾3®Õa©Y‚L>X?ëÉy:#9{g¡{Yw~á¨\ºàSœXôb›QÁŠ!Ò¨M^Ú´è$ü¡ÐŽ&b¬e¬d$òXé|áÄŒò_{ÕgGH%%[³³zȹå–ú”q*¬ËWFæBhý4Ävvag7㢾·´â‹Üˆ ý”.Ô|~DhÊuAHêÒEë F? ߨ¶ö¢î-“¾9¶È™¬¢qî2ˆ³\/*b‘k–·œ/t`±_p¢ƒ<ÌÑO¾¤ì‚óš2ž©°ðÚz^²¤UôÄÌF’Å7wCj{OH2T&NDy$# Y;QD¥O1Ú,W\Š˜s-ÂÄ„U±ç©ÀˆʹÈ1_}Ì«r0þ¾k‰Ú‚*çy2·wöúR¿2ÍuJ·¶æ,ÎvÁ\m:S#ØµÚ &'n£¹¼g¡d½iè N­©ùb6"ŠIgÑ”Ž™h?„¼Ë(#a[ !rgUj†ÝÍîÅ7·±­?»Ê&èophà½Æ)T‡Mƒc^”‹ÊÒOÓ뜊ûído`þiY?QÇ ºypj> ð|y zó}l^>ƒÚ¸Y ?�=pÿ Ž‡hßEú‡¿áh4“:ØG­þ·ŠNû` @|�4$ð"·¸j0¡iþÌ`˜Ÿ� ¸Ïm¬FP‹pøqò/T£ûOPÿ¢µfô‡Ÿ•ì~ö–#륇eï¦dijÏf¼{ÊêNcDiÝV` ¨GðG¶CôšÞ÷Ï×€yË7BXu~¿rú†Íøç£u\_ C¥s9Lžé×ûÄì½C;ãø9²õÝiu¸Ñ§_áT’5*fŽÙâ„ÂQ'H&HMÜò¹~¾(Ø—«´^¦j1ÍÊcì,j³ü»\®óù”öjžuÇùp&öv®¦î螙ҩÓ]ƨXeæ±±Ø {ö‡±;éç’RëÑî=ýˆ…HHµÍ&YÄß•ÜB]àzŠ]Öë-A%¼$‰Å,±Îòh8BŠÈI.¸x§í4˜„©H6Xk-m¤4ð„Q'¸‡â10=xm£>Ø‚çÅ¢Îr-c¤1ëµL4(6-ºƒ bMŸè4Y¤4˜#EŠvq üõVìD¼&Ã'óTy‘kÍAËQ*¥rËK"—OGœHï“¡<“9,g;¸¹2ts¥—eL[3QÚêT.Oe– ëùœ”38Øi~æš mq~~,aNQÎT¹v$M5ý¥jõö¸ÃÒŠ'ëòtq–y—Ÿì›¥LIÈÍ>ÙBçK#…â13XKˆ`ÆM芹ñp½wÖ»»‰ÝgR&.©XDBLN¢¼â’¬Ž=’*‡PÑ%“ú@_7ÙD™.r#ˬʌì‚u[q‘³‘s·¿Ý»ùNÒ )£´Ùe×ͨÓwYv™Û3}XÌL†l0q cæ óÐÙ½ :•ÖM›ÏØÙúØdžÝGC»d…‚ª®é¦¹¨&ž ”·Q¦ò“£¬ÌTu;õ/{ûíh®6›o(`¿Ç–gã’Ù˜iárq˜ŽîDzm±ú'B¬Û²v¼¬q4§øÈQ 98È}YóB_vß׈Ù3çØ&\4X¤ÿlðTÜû8ðôVhÈÁ-üôxPxöÁeXãåø‹üß,€pêÒ>#‡Ç8ùáAã¿Tî?ŸáúîÌuþÃlÈ”Pà ¿¿D5à?h7ýæäæQj÷íí]÷ãg¼ßÓ~óÍ ÀÕ$ÅÝ“h/?²ö®ƒúÄ\ø)|±¹ÂóÇS?¦zjÃô‡Ã$1Xˆ{aþÃå|TìÖ¹*qÙž[àeŠgåêü£j¿¡Ϧ°@±öa¸¢%¥˜;g¬ Ÿ™äeðm‡Ôˆ“ÃäL1TjWV&+sNЗé.å»eä©ò-ëY¿7]¯4ÊYUFIÈÀÁwÐÔuFûÙκÓÑd½’»œm÷ME5B@y–&…¨F¶°4׌e‘kGµ!#Ò‰²Š0J³Z#„ˆQ¼£ Á&kÝ8÷S7ÐhO$)* VÄŒ– [µ´.ºdú¤u&#/*I3J‰f³à’E Ï‘ˆž“Dp‹{‹l’^x0²ÈJò¾xµÿœ…Ï¢ÒÝbIí¡&e¡”ÊžæDX5™îƒ·.q’M¢rÌg2ç•O"émv˜ƒæLåFò,º2PÏdš+Ÿ4›”¦²Î¥kSq–µ¥¬˶]%qùÑS¤ËÃQ^üúâÓó“môª¡³£dXˆR÷N3z¬2 ÷Ìdõ\HISŠÎ¸¡ÙÛ¬£…È p-ä4ó½/çølt VðÌ“r—‹>ƒ–. 1gRDÎ1€ö£ãwmì üʇ<=Q¬”Œ„0kâ%‰0³ž›×®½ôÎô"¤”ÌáÚÝ“ª)­ˆªx•U鵌݇¡1†mó,¬¢¦ªÊ×H˜bqeÉê^WÑœtdJ¾û6ñq(+ÓVIÛj³­/7!+OùÅ]u9XÜÙõ­¹á¹CüáõÑîm,024Ÿ6¹»Þ¤#ÀqȈÈ]6æI~$ÒæèV…[=”8Æ6€8ÀoqL¤Î½RŠÓr_Ã@˜ð pùøû}ú¨ùü^w³~ô³ïKø‡^){t|sD4èå/R{ @Œ€ÿùîgä›Í„ý3üþ*ÖŸ¸  ?Úd¸÷¸bï^#‚çî-›Â1 §Ý\�úí¢àø{"óû-óô°è.O‚]Œ /`ñ#é­_ü¶þ¢ìÍÚߣ�Ücª7ð×xc&Å^92 ³º_p{¬ßô²:àÈÕiU.è¶ËÕë­<Ü’LÖ4™Kn¼˜Måîe8YHõ‘¼äM¢ò Ÿ¾˜ÃÅÌdÏY¡`Ÿ>> ÔShÇA±¾PS†uW=ÜôÚŠ©&¹Ó)Âõn zOÄïV²Y„ésK+NK1yÞYqTÍI´¶&Ù¥S@7ëùÀù…àµ#µã%eSHcpžÑ’$m¬æqˆ|Òdê“ÕýJ_bºMÁŒ~£²Ü@Ç£HH4Ȩ†7–UngÅ•Ol"F&Ä”ˆ¶Ñy+Óœ™"2;¾ã`uÄÌYBP‰§[ûhwk†ù÷‡jmäb™²bv5 ÊûÕé¸b,#Ñ^»~GõHe`Ò+ÕCÒ¾ÈoŒç˜Ô¨S¢‘NzX´½˜ú*H?ÂwubéV˜è†rwOw‘‡1­NEÆ·çdÃç£'Ù`×ÛE½©T¹Ñ‘‡Ä#·¹b`Ù¼Rw§Vf”ìÌ.ó©”BRfI¢vžo™¡”I.,Ua,,BZ“l3Ð^sU^Ö‹"¿X©´¢ÉYoõ ãYîS©| ¡œ{Ll¿$¯s^QzƃaEìõÁèˆ�� �IDATCßÝErvÿBg?ø'¯ú0N½Nn¦üXn–5ÿ<+óÜ#»/§ƒ{jú†Û.Ö|yz¡3¥S¢IØ%:kòOcü÷ÿ„ørvw0‡ËtzfÜvQbÚÖ)¤,ž­éùéb-jN´Ñ£¬¹^ìéõ…Æ# °c˜dºÿ8Å×3Ö=¼AlЇ„Õ’×ønº37ûq¸?BqOÂɉG9R,йǙ±5ÎÉ—êöËÍ„7€Ò�Ãc§áûò�LþØ3±€SÀ×xÖßo€=ðêÝß�®ð†«ú°öÄñ0ÑóÀp?`V¿h¢~)¦ôW‘ÞÑÞ#ì`»o2°~¬Þï0ŽüPÝ#Çɿ߲( 7°ª¸ €VÓij(â÷–öÔÞŽˆO8.ýûwhdésÃÄPú¦$Ĉűå7û‡ XLrª³—Åe™3º“ólg`�F@.�Ëï‹`Ì~!Âsâmûü׊CÕ]¨…«Ži`…•“‰}U<œû²)RŒÞE’ß1ŸDHÐÚ–†<³}÷²Ø¿ªyTÿ¡·%ñÙè}ŠWÒüÛ˜w,Õ#9öã2fZÇq>wòùs°ƒHL:bB¦—f.»CfðS·ôVJŒnšIO©[ K¡5%£”°Ì“@JA›§ÆF3(wKlÔFÄAD3¹…æÌÒŒ˜•1ÕˆÁEíµÇʮ֡ K+ï€2¸k£‰U$Sy rn´žz• EoLݦêHÐÌÃE=œI±sGý¯ÿ~òq§WYKÂ.è1©3C!ض7±·ã)Ÿ2d³–ƒÏ½¨×&Ÿ±åšqW$C˜ îªw³SgŽæx®ECÖ‡±Ã6,ò.­;'öÝuE.j,´Žus9z{yN|oý,'d ý…—L(âöGn¹pƒpά÷’FHs븽—ÎyÏhÔ, †Ê­§µÎÙÊÍlQÅõt+Y•â´.&§üÈ‚ç!põRL5K¡;ÁïSVfÎ[SûˆÒvulx÷ëV¾¬5Î4YN†ÍyXÕO µ;æ9ÉQBÇd‡Oµ©RƱð.kGÓºÁú• _(òåm÷»¾¹ø4¶è78äBÅÃ]7²C~Zeä…’‘S¢‘(7Õ±=qÏ/ÔŒÙç:¤8J‡?’Ûb}Ë÷Ø�ò ‰ü¿¬¯÷¿3ÝCð{ P‰†u?45 ¹ƒ4 a> IïÎ<µ@z+†7?؈=°pmЀëûA,€Só>#ÿçÂÚ°¹_Ø÷ÿÅ£Z?×røËÍ ÏÞŒüT³¡xðŒ¸7×ï±Ç>°Ž€ (€æ'üÞç:½s‰'<ù·Ç“‹tèÕ‡ž,SGà ÷Ñ~H2VkÍö¿cןò×Ö` À=Òl «¾O ÷µ¿LvH²˜s?ް³ý–ˤ‚™®šÃsz‡óˆ¸}:Çù¨_ 9R£Â«B­×G” —~&/3w.-g_LÝœ¿üȆg)N–\g›aÎK "^tæÛW©x=HFiáËjãÍžÆlfE›çóD¹•×/KGYý›®þ´—Ò·}1Ýr[È1±)‹S>zG*ßȹçvNÌù*guYºr>ׯPï´oše>á¶c»Ã¤mûr<ä>òŠUËôQJ,øzŽ¥ä)WFŠË”§ÁOq׊Ù'•"Qá£6„¹À§ýlf;æEeˆ ÉïRÈÙÆ©ÿܪF0ª¨`ºpR¡Ë2[":zdË”ùäóžM£­ªÎO^6Lý¼›ÝdÀ1 "Ë*ÈS.ëÕa‘OâXL’2YôSr†™°\2¾º ‰Cç^ªì“<”…ŒJk¿¢—ð×Ӫʭ£®¤–…Nø—ÓœíÝé7a6fŸÊU$¶Š„5×kI›JL¬º$ÇN§ŒQE˜ ÊúB†µ™­ .Jc ¥ãeÍœ[M´ºSŒÈº,dI³ŠÇÅ ­À¸‡0˜<ã>ÚTN鞦½ñ¬sá0¦¹ï–3 Έáã¦Ý½œ¾¼vÕ~ÔõèÕÓ“ŒŸ¬ø¦H›Þ«¶&´¡N&—Ž0•’—NK?%:’¸Ç³¾(ŸïÿÉ´¯£=âÅ‚Re{]tsz>ÄÛÁýÝjà ~´w=¯³»Ñ½º½½r‡o:*Ô½0ø{[ò¤¾šd;øÕsŒØñ˜00KôÍe?âÝ~À�ž‹Ç ƒàÐ]É>³<È5Ö[Œ÷>ÏoZk  ½\ÁFØöØÃ¾aœÜ£¹“{žû†?ÙkþqìúÁ€:Mï£Öþ½²ø§h÷?ÿBsÃÛæ9͇› oäÑ `ä?%]û�÷àÜýxûfñ£NÀÏ\âögÞø>ùàC€ì{i¿÷|š,p‰ÙjЉrŒ€÷¸U�_C7€hÜËžY¬pÊ?-ðĿҫâËêßÁÖдÄ�¿_¼€Ô`Ó9äðei¿Œæ "?§Ë¥’ºÙ÷©»íg3/Ÿ{ý¡$ß.ðe.¬”`áxÞ“v¤aa*ɧRÑìW±(ÕpmìWýT§pq ÊúÅè6ò–+s³ëŒ¿¿˜·ÞÁç«Ý¯/öŶ+ÕÉÿOÞ›öHreYbçí¶ûkF&“dÙÝÓÕêih0 $A€„ ß«o‚FÐtk4TR×2]Éf&“ÉÈXÝÝÜm»>DF1“L&Ù¥Ö�]ó>zø0³wï»çœ{.Q\ Òï£1ÊC¡NKøÄ†®Ù\šõ®Ýý æ‡u5/²WÞ¶#±&Ò& Ðí4†mû½Tld‘GÅbePY$Š ‹sÇ)!Qµ#Ù MH›„Jn¹šRkû¨µ íÐðÆ ¹ŸàT9å·ü¿¾sÏ$«q8 µñcšÜÁKÁ3›¦eš3MNQ™p³4‰pv§Ý7EóRt_ùS»=a%b–ðƒÀ fã>¯ÕŒ/Ëfrø-ó{úÏY8øHÆ®õb»¥!z5Ý—Ã> íÌÏŠjSš×Q¤µº¨áè•–2ê³…§Ê”=¨žÆÑrOâÂ%3Ë`È­St%1ŠˆZÄÀcª6ÒÐ2U*Kà©ï˜NIYˆ,Šza‚ }IçÉ딑ÜÛhikJwT3‘›n Óv¿Ÿ:°é¯|ÀåÇú`ž}Lã\øÈ¦‰ÄNO]=õ<r™JaKâ·šîá# dW¨×qlZ_^Rs‰Üˆe“Ù*u™¾~¡ç—†bJêuû›UžºéXMUõÕ¾ùõ׿ûU·ÝUI`ÿ’‘»ÉüI‹ã¼A’`1º�¶÷ÂÓ7²AK§M¢¿u0M {Û uÌ ë{g¶ñ<Žæ9 J€ÝÏ{˜ð<�í¿Š° ¿ŽoöòïûÇÀá½öéáhûòÿ+‡:|Û3ý®šæ­³cù'ï {ø£Ò°Öîõ‡¢p¸ï¼?Ç/>0JúÍ‹÷5ß;Ƈ?E+ߺý?²ªL£ž`@q/` ÌTµIÆ{é›9lG •A86 OaÏçéÅb¸inñhÈKsZ"ÁçXzåØê™IqGÑõ ÏÃzžÀsl3tÝ_U¨ªá *ž™bù³ÚíöÃ/oÛÑL©ÿÌå+9•¥XåBùkd` r3©Â6Ó0þßÀñW±He±"þ«L'R¥^hß ÞÓ›¯Ötµß_5éڀýü/G·ÐD®DµXêÆžv"/“„Ê%‰wÖ c{ua_­Ù^ا³NˆÍlŠ®K§Â‡TdNó68ߺ©k»­¬7\¤˜±³™µ†1ÏU ‰ Q/S£ÒÚûmÁo#ÍÇÌxý4NÛÔˆSšoz®ãÀ´·†‰nƒÚŸÞh©À1e Kxêfdú«×¦¼àø¹ÝHñUÊwy<¡Qt’ÃG¼¨„£ô¾ÚL~C{;籘]MG3²}%d"Ù"á§1‹^(ßtÊ ‰ eôE¼=Ì…Êny6úÿSñÏÙ¼¦áZzgüԳ¹;îÖëߎöTƒŠÄuµ §ë°FÕôý‚±°+Ø(%头²ëBìMG¶š=b,'ÑCÊ® =ÕBªS…g®ŒÉr¾HÕÒn ‘ Œp'Õ r¨5­!¦#ÙdW¹iîö:øÁùígc›m‡=Æ»Ú~Du—묺< 'þ qæ’Uki§_¹ŽôúZÄFªy2„¶îý°»P;šÞõ”dü«›g²‡ÀYª–ÔeA˜Ò¼äü|ß-ÚÛÏÚoFzRË DN»œÎ¸ó4š^XÖÝî¯÷íe±a$;Ùr½[Ì]Qû ®F{ 7#¡Žð81Áôo6õ³©åvÜ|õÖþS, ÀÆu´ çžwß;ý½'Â|¹€©Áj0`óWÀ`¿¾ïk{(;8п-bÊ~Ÿø‡éŸÂ0´þ͸3Ps{qTûî›é9Èßþ{ß>˜o�qêÔ﬑¶ýp¯Ã»¨Ô`~Bbx_òà@�È»¥\‰<‡€î¡ê«îQ*ƒxÊ ÅÁâÕaØrÄŸ¢ðªð‚\÷½: üx~NøSÚäºÜ-d÷8¼’í“Q›dÁWë(?±öh¼~…¦Æì¹Ÿ™¡%Ðî ýÏšíÁaºšøÿœ™›zOÛëÍ8δ¯äßÕYòñê#Ÿ²&|îGí¢Ñ>ÖûŠì({2‘™¬´6aë ©âŸÄ䔓-Äßí‹. Û¯=«5Îð 1,¸NÄ®9Ø-«,TŽ›` Ñš ãB3qÔ@ÉÞÙáµJ¾TéQ§‹iÔnL Íq$ÂÆqòwM纉LÔXƒf¤ª„“*A—ú6÷ ¡„‹ÒºAÃ#¸ Ù&t–îÞ›u¥¢’³8Ö@‹áΙ’4œZjšØô‹áàczÜ×°--æ }*Ù|!¢R‚±%©JL·Ì ÍMŸ"(¦Tõ ãµîlì^æëóå1—sF35yîâ(»^J–œ1Y‘/nôá×ü¿|Œ6ºÐºæÐ}J 3—%aXä‰9¸ÔãØCç¦"ùÈò’-ˆÿ"u[~¥Å.MO­ŽØ$Øõ*8ÉD½á0u;hi0´°ARÇÍ,!  #"±£¢=)R:+„JT*“SAMïˆ!.‘eÄn¢]½®Û¡?®bCNwÖë+϶ *„<øtGy®œZ'ù*ÿ}EŽË¸H™ 4L±žºÆ\5ôõZ Ä9>Úy+@ý9ïkî ëýêvÀl„®?êÓñx¼!8¡Úä¡„{ŒÛHNˆë>ÛÚ"U®|âýØoê}-vå’%©I˜ñʱ-tã-<ÐRiQJM&Ì p‹Áÿ•}ã‰ÆÀ<Av NÐÞ=o›¡~/°ç¼Î×à�MÈ=ÎŽoÌYñò Ô‘ò17ˆçÞªÜ^¿ƒ„Ÿê/÷ÇÈFgo.G Œxù}#ßíAûai“ùV­4üèTöûvôD!JÀý»weÂUönq·~pb 5àÝ!+À ‰Ô'¹]دvw&úhåãëãLåj$ˆ6-&Q’SAÇ‘¦¢8™ä?÷Í ž4/]ú™k á v—üº«°$²ˆÕÏëí7l{ÈYºx4«Ë-¶S}£.‹Ê¥nf‚túOZ·oûfèî®”¦gùáýlA§W”\i£x8ò*Ê`·Eswà»VEEwôó!Gmguû3M‹bëŠê޶JOû©¾ÞþÎKEt>1»Ô¬øx,ùÅŠÑDf\³èÛz.“=¨šüX…ƒ~ç6ã`Ÿ'3• •wag`T §U˜Ô¤9¹¥rI¤a[%í¼ïéû`¸ºc×y~›t&¾tz>’d¾’‰#lZFr¡µ!»W²¥™štˆl°|u–8ocç¥K¹8>ˆ‡§ ¹ :H«yçÀ´µÜŒu"s+º§—Å¥õé§z1Y$d¢ƒ1Ã49MRî³ ‘YB=›‡Ó;ÑŠžáµ-ãŸOãAË95Uˆt¹õØëô"´RžV“Ã91'nNÆ¿'ÝmÇ;*ŸD¤©X¦õ‚ó>®O‚L;bƒ¢–Τ"öcgÄ–‰ãÔav vçÕ:ñÈ žˆ4&™´7ÆXGddœ ¯€ÒŒš…zÂÄrëR ×5¶7–0Õ—ÉÅÉyùeŒO÷&íôEÞY9RëÄzp—1€éÄlF·ëfSŸ‡‰ðe¢ôDÝuk7k˜£™ðñn•l‡Aiœöíz·°±½„ŒÒZ•ŸWœÍ O:çm× Ñ8;M®ÛÑ*Ì¢7âdoL¬IúB貫-tøgØ{°ßH]œïÈÅ!Œ’X¶¨±íó +°%ü/€5üþ׸*‘˜·[ˆÍÛÃï[8¤ªSZa¶K<mœÉ±f¼x,ŸÏw0ámIËðSÃ}ãÔþGßwgÞ©ü$øø‰ Ç?½ÜÿèàlÞ”Q÷Ýî÷ÀÜð .¾·GÿAt�ïñ\¢7ºÐX�Hïq¬ö{m0¼ï°oD`ƒ[€¿å˜rŠÅ3ŸÙ¯¬3 ²×9C¦±%0í]yr’& Žä˜9šY½ˆ–¤¾<ãaHãþË¢›¿>Þ!àßÿÃ$’[Ï3UoGäl–Î>™¯ÊRr“c(FI7Æî±ËÛL ¯ÄuŒ°ŸeFÍ ‘rŠhy6I<KˆÇÆN.4›ŸÉËÃCã˜zÄѳä‘[ÆÍ¿x:%/ïfÝ4ñ»úf?ÿ«cÆ‘—BŸÕÍÉ4®[g‰½¦(é”>Œf߬¯e?èm2_Ælîx5x-g‚rB œŠ}ÉjŽÊ±dfmáLR·J¼S=ÇHœÑ»ˆH²1ˆ†Gcw—lK³ÃÀ™¤$§VªD 7:á›Àd’Z.W¯ÂiºJ$uyËÙà§Ø•Kl)œd‰‰ÒN£øB ‚wÃ!!P&klÕÇù+R<ñè[ª·S,µA7¡˜x¶ŒŒ¶Á4Ñd±2üc”yû|y=Y<²|Íô¯Nlš)±,Ô,Ã*ÉŠ²š´€ðQç>ºšuÛ䪧ûYå®Lå‰ë¹éÂJü<%Öê¸å É|nÄ…±y¹í ¹`ÄÌn _»[/Ô‰r(O A© ^H-¬,DÎ2¨Hóc=Ûu]ôØLÊÃFí\Ó—“'¥Ü/²ßäVdd%Ç$1 ºõ°º» 5y‘qîÏXQ¹¶³ƒy¯b®¢¬8ôd|Ðèðd®T^ýOîïCPÃ…Paæ¸#+„³bØ_cèÑo-Wfô,gGYv“oclÍÒì z2Æý¦°÷YБý5uÐò Ì90B^°¬Ë꫽¹^àñ ´ƒý ¨ ­±|ÂwŒ|SX|0„CövLP§0÷ô&–À°,Lžc—ycÌz\�ÏÞBŽ ÿ°¹“ß®äîpïWÈ,ÞEÚåOÉïEÚÿéåóá‹Ë�õ-¾öþ|Kùã6èï|yÿ ¿ÄäÃõƒšAâçâwÚ]ÚÌeoK»‡òær†Å!Ž×7£A T€¨gû—{­6ç.íp¾n/Ë¢éö—Ö¯oTw]‘’{Ò«~[Ey6Ÿ_ÊF_VÏôðqÛHÐGujkÎG· ÅÒfÆÓ+Ûý_nCÑü›\3߸KxÇY¦N«Ðö¡yòÚùŽ.flüE~Uì{²Ï¢+åqyh/Œ`íQÏÙŒj-ØP¤ÎWD™Tõ/}l;õ\HƒÔÃNK†£4-}>סAøæi[ñ¾}5F\¢-ÆDû¹POgJ%¼ê{SO{­ˆ°ê0g2÷,ó„iN 3,§è×ÎixN-%‘†àã”\“À¨Œžd£Žûf¸–|TÉ& “Â|åŒ$®#M+S/îÔtg™>QÕ,e+¦FîZ"£¯‡ýÐ42 O «g†òCN ©¸[î4èÒ L´çVÒÉ)’÷ébÏ Ä+­«/+R¦<MÓ4÷ÄK˜ëÄ@Ë>Iwý³ysÆSdýJùŠêÑÊÜKŒœ²8ç…œ Âi›g´SvàéÐ&‡K?K°¦¸´»ß ý8lyÐlø¸ ‘A¡£S´¡´n|2º¢t >7/†ú—TüwYÎ…˜¥dó„0$±`‹(ªÛ$ ²+²kM(qÖ³AhyÈÏ„OµNØ"„ÿuTÂ7nÚi‚0-¦‘«Exz Ï£<ºÂý‡”Ôû J=M|u0ðî3g\ä2™ÊÙáÔõå#Ö>µé’[>ju„ÖäLå*βB•<ßEö²ÛÞÆÛ¼vÚöÍËoJÐÕB^LS€’PJ¢Z%Í0kA;ÐtuÌ�.c0Ð�R†ê— «x»†~/Ë(5ÎG\Ô0�ÐìÛ m�3�ÀìÿÑ;Úÿ@ðcgÓ¶¼_½ù{ûà§ND†üãÈ öà?û Ó}SÉÅO ëe³„¹@Q`þäe܉—9 ùÎì=ý/{sû böÃûšØßMßPŒ„‰¸hÿu-8ÅGѽt5†ýÓ)ü90Ê«y•TÞëKs7M›¶<ê©VÁ¥ôº ÙÏ ú—™¿n‹_êê4Çí®<BZ¡sŒ‰"YÌ¢OˆtÛjjSÖ�ý¢ø:ÿ,ëý7‚¹$¹ÎÍ]:®·ö_RvÂæÅ_ü&Îyž1þÉ\öœÝÚƒ‹²øe3U§±¿’êKª?‚b rt“Ì· מ]Œwq;Yÿ¤ìR1$¹“=uΨ‹Ôök© tº5óÓ˜øvŠWÉ] îù™ñ<•Ö”ŸGo‹ØW‰Hnl> ®t4•å@¨ñÎN½íü–t*©5IôŽJ`Kè×q¨¤xœÍNÚ‰9ϪI«q§Ã«$Ï3QœÀK29e6™òý~MG¢¬ÌvJII8w2šN„vµlVùœŒèw,0µ'tÚ-û&¿ª"r3yÁ§#•$ÞKBîø¸³½´Áî=Üæ:dW»ŠùÇGcæ©Z"Žðïº~¨ŠÏŽçÇe‘pÖ=Ô;éFy$Ô$ô(5ˆºp~1…?Û¼8”bŽ1o‘XÎ{¯» Åg„“uÊê)šÒ–iëƒò¢ó¶w2%cÖJ…yÄt dÑá`Àz'ÇžÒ4¨’ Êè 1a óU7Ö݈;þ¹¤&Ó%]–ê0ƒs²gl“‹˜kЉ¿ü$þE¹°^»^Â¥lB+ºjÆÁÜugGøÙñÁ2ê­ÙLFñijžy¢]\¼Ö‹ËÝ+ìGʪ6Oå‹ÐFêóO‰`®÷w~ü&Ô!A½8uéámân¦~¸ì1ÇxŽËÁ¹Xh Úï F/nÞz¥þýø–ï’ ¸|÷ƒÏß^¾6Í~:Úóí½øŽgÒO“¨¾½ú?^¾á­Kàå»Í„xSLÈ·&²i@ýØm`÷½çK\¬`4Ö· oZX8`$ð‹h‚ߌﻲù»óær€íÀ€CüPn+ Ckd§Ï#.F˜æíª"Ùü!2$ÂýÄì L 2R®ÄôÈmöS>™ †½ˆSå%™Ã­d¬´>U<ƒºƒ3FŽz˜9Bu~r˜¤—žäv?ó»;ƒ»æOc¿Ô»äJÁ@6xeÏÛ”"¸¿bÕL‚ÈÁVnrö¢È̾-Ýá†/ÿ‚•¹è2Óçv=¡±v9jÈÊ}.•Ç4¢Ö²w;&w[Hý<™>Æ,"õ©w1¤g&ûûX­ãÝ€-éö¹m¢¿^°ÓÄÏ0±f“,x*SÅT \nˆ Î…Î#‰do\ػޅr¤•ÏÝÂĬ—mO~·Û½I£}òÈ5c°ýú½;6“—cH”Î&ZÓPKj/z“¸­\šus^$S”ÓÆh0"²:YÜVù^)ÝßéW$îµU¾]f5aÚÌc*ÈL±LÅ`¦sÝàÖ­€:éZvë•q‘»*ýRÙÈz¿�Q)‰JÚíG1KÏŽÿ›óGŸT«TNc¼íõMâFaÄ2ô„&©}ôHCŽeirÖ‰& Öuɧb‚Ù2]rlØÑdŒécBGÏeàŸ=r`Ñ#ìnð>e¤ÚçÝ%AH bNH6¡j\Ô1K”eQQeë<¶ÓD­ü»³Î\î‡ßn]²Ÿf9? ƒr»Ý$­îêqà^Ï“TïH2è#å*K@s?Œ·ûµ7Ò€tØ”Ť—³ƒ’ý©îû´£*âàq÷ò®<ïÈá¬/hìûÝFn·‹.‰~AD½JpxŠj%õÑùzuÑl äó¨²Ërwfºx¢D–U­ãcéÜ1fÍ1Ûm?óãþ$ƒýèbÍ ¦wƒÃw¦)¼t¾‡o§oÁüò¹ë ( n¿6}ÛÊû§.Å èý‘Y»ï}ÜüÁ�ý ýPeçè/~oˆø3þwÀÿüÎÜ7QS@âp‹ºFþÆ k‚~ußwõ ¨½øý×û ¿¼ÖôÝGIç  4`Lü¾� Ã½yø=Á•3`B|åvºÕ©ÛtûÚïÛ[ƒ®†âp%¯¸TÝF7±#ôú ücÇ"(9ÊíñüeAæd7¦[¦º¾ýüÅî°gØW°+t#¾$x¹#`òé˜dÆ:„ Ú¾¥í(¡A÷µ)Cöy8:Mرë¸7qt|Ëó«>9[’“Í]8ij½ääœ5WVT�� �IDAT$Ýbeù2•SØízÇn¢ C~ÀÀ›f¼áb(_á@5þéaeß­–weà*)z¢¹Èò°O9™)EYeÝEÊ¥�ÈÔû©C?øbœìvœv@I6Qg(Cø÷Çé;‡ÍvžÓoGiorEŒŒÛì(úl­§¡{Ýc\»ÇGVö.g)»ÉÌäÑKuï»Ráå”-Ý'qÊÈ%—]J/r~®ì™¬iŒ6ÎñÁä¥Y°ñ»1ÜÌS†n‰® 9Ý£Ú¥®¦´nåG‰UÓÈN7Yyvúç?ûøó£Õ“J(Œ;«¯ÝF?-¼lhLüÞ 6‹c¤IcR8"&*XbD2 }w®†òXH5Ë Ÿvcb„ ŽÛ!¡ä„Sê%‰ìm�¥z2”†*NÆD2…a•ç™beUͺᚇ À„ã¼{åãó­-Çp$â2´Ë­.úî ÊîÀôDvÝnnÆJxÛºåf[ì“c3?ñÎr»Ù»fÁyj Ã7Α)‰3Ù’›^lfŠÓ$—3¾mÃ~™¦Ü­}eHWï#íHªoìþe¼~ê²™’uK°0¶†ˆ‹%1nİ3ÈMY"§X(Ô%À TîÇ3Š‚½.OTR„A”ûÝH(²düþ9Fó%ƒÑ‡�î¾f¿·=Ï€?üÏð·#ð‹<³'@%±6ïÂÎo¬¼ßrüþ‘rá±xMAV€“pç¨ß÷‹H�ýF:%wòÝ«ó&ûAÀw"�f´À à¨Ý;~è¿qoI˜ßfu¬ÏYc 0È·½1Æ· mÞ1¾eöûwó¾P])زÁE½NÊ"4?c·: ë.#= d¾Oã‘e%•Ãä®/=kæHj”aõI’í^FûÌËqŸ3ÑAO†h`$-‡#øëãû M¹ô!?rëlzýwéßA˜ ‰s)EgälÑ&OüÁ„Ô·–V½Fv´êãbD=Ç¥f—]¿øû¯k\àϳxR³CÖïNÂt4iyk~Y]ÃE)ŠÖ³"ö‡=¥ úON#;…){”î6_ ¶$ÓF•E¦š™ 3êhr Fwõp1¥¥Dgyç¦;Û™Ô€¸ñ£¶mú^æÚ²‰9¨t³ñ?4%.m6ÌŽÕØ’£b™ÛI’½Mv£|´¬‰¡›ìø›uüxy¢¿È‡˜J¹.DŸÀø» †‘ÙÛ^‹^Y–y 1gL ÝSô†ì™âlæmð΢I·±ìΔ:H¸#ŒÚ„³¥tTáÈYQŪšy2/oUeXvtP>:,‹Æ¢³®ÓÝnß°¸âìÞtût7V)MÈ•fŠ..BHóDÒ\Vsq€°H2R²– ¦“¸G5L&i•&¹¢r|%YGíwú–ËÓAƒ4Ð5Q2g)d%+›2ãa£žÜnßm­î±¾1û›),ö'BÑAä^”jjy}‰ S½k†³m!›aº±$X!b.o»Ʊu»ÔÌ/çœâ¯¾¬³'·V'Âlýo/W‚¯óÁ˜Äô †LÈ|]êßø|¿ÒwLß®à·ûƒr1Ë¥ïÌúKèBfÁ” Ù°0xRb¶ÄAÀ•\¼’i>ÿ9ÇIò<ßÍbóïúM9æáu1 ¸ý–cP8—üB{ƒ xümÿò°}ØÈß²åí Ø;L5ÆÅ÷Dqþ>!iý0àÇQ ý[9*^}>êÿÀ`úG§aÍ÷/®üÁˆΑ] 0?÷„¬ñÞcg?HùÜ|€ºo‰¸ÿ_‡•4ÜÚ—ð ø?`b_«'B‹¥»WƧöªÐÒº© ÙŒ¥ÉE²|qÔâe Lùãy•"ܸÃõ„™œISóäÙT`C^‚Ñd/2{j…E†º<�9ÀTö‘تóKùJys)‘gr¦ÎO|ˆög{’Zý…kþÆwÿu)ذcW_'^{¸7¤¾wä�/Á �w;´7^®=ã2„ãu¡õdæ¬ÏÉÇ£œÝÊp7gÏDvæ* Kw9ÓIŽàNF>›R1ľ&ÓŠÂ[;ØñÙD{£”RÒ6d¯9< µöy7ÎyÕ¤&QÕ Ón»Kt}"Ϊª˜õf7x¶êŒƒ¤jëL£“êòZ çHµ_ZFÜns“¿ž§{"l¦Ç›“<‹eÆäLf#¡II2k˜á†-ˆ’ËQqJªìx䫜©t¾_Å”qÊŒ YÎ’,ÏŠRÎé,$âiKÙpA<†‘ß ¢ ±ÊsJ¬„M^Ä‚ ©‚àH¬K}œîˆB™æ*ÏTd3ç3¢´¢!"Œ”O¤×Ä{ŒÃ¾+*›¨’¡Ò:¬ÄšrýŒä)ÍAWž´VoGëõ0¹½ÝÔ¼šº×v+:1l~Eú_Õêsµ<tùÑ:Údè¤M±—†'¡ !vs_Y*—5lÛvýxóÉ¢Ç<‘TZ^eFÐÅ¡{¢¬Üߥl./W#È$«úSÈç$3ÊcpÏ®9®šùõ\¯%OêM•2t‹„ËλÝE÷°ÅXƒªƒZ.ŸÚì¿PDðxV^•=TRÚîîsà׈ ä»7,óp#™zfŽ,ü›PÔ�™ãÓ=žãÁ«ßIàñ�|¹}iÆs‚ÁÝh�óÃt¤dccìªLýÃsÃ?ýù ï¡æ×ßv=|Bƒ.0lPGô“Ö»Ž%ü;–&ÀøV'æß™G½�éAÌ}د�ÿÞ|ŸJè_ h`ûÆ�5wXæ¸óg×ÎŒ.DÆÈoA¾æºoãGŽ2#æø¬À|‡†=í×GÇÀ<ŸBòº)ï¤|T,ŒK{:º%míÒøÚêQ€/eÉ3DP¥ù…,‰ ÞT¶.ücÍ3­ û"ÏoáÝ7F«.ûU#À,ú~ánê»àƒÇ$eœ´’5†vaO×#Ñ ¿«ÃâÅlûXEÒ›Š££Ë“d•X&ÃæbÜ7tת£O˜üXÛ§Mó0Ññ7‘~f­ÙrºKéŽ"•zÇšî, e×1FS–ò„!;W£&<¡ž³,‰„{j÷Ã’ã+ôtØ™gû,‡’q(ƒã®¿ƒï2¥ ß.—"[³YIîú¼IàZrØÇ©¥û§ÑÍMÒ¸éRnl°-5ºbÁ“$gV§£ÉŽB2ïbæùÄ—Cȃ-÷Ò„|b„Ë@ÆZÄ1f¦8”ežŸÕe®ë3Q1ÄàÛ1 ©£$G¢ÌÔ|*�ãš*ÏKo†1Ñhu^ø£œ% 9UR2®OXpczëG.¬‘ð4³[âG 3­:Š® hCÕºp‹ ‹$##³CÛm÷Ó®¿žô«05ãú›ñåÅP­n²Ùs4wàËWûÏnE^'L¿“{ʰp&5̳ ?²ùa…L\¹å¯š >¸˜Âão<9Ú>>qí OŸÐ¦é>ÿºìZlg¾tk-·JŒ®²I™‰bÓIßЃ̲tufx2ÊÏ ù³ëôK…J/ôî=¾˜<úåqœÏ”µ¼÷;Ŧ$u(“‚ åÏòÝlKúD·@ï‚5N‚]at;©é9ÂE„Ù ›ÞÌây  àv»Ìù§ax¼Oèiqn¼WÉ[éáCÆ«âGŽ«ÿ�îâóîÀ÷sòïÝýûdßo+ÿ‡/ÿ]¶©ùöwŸC O” À(ÿû \ÀþØ3%€¹Á ¼Ì=Ç#SZ,nÁ€µÇ2>K2yÖÐÏv˜YT¢§ÇÉ xÜ'³Š!YoЬ…%¢£év,Ö8Fêj‘Ÿ¹£r0’?§M’°EK/ Ûm<°`˜!£[z±MŒÏºÊí"ºó.»¨{S’Z÷µø«òõ5ã>9)ú<Nز§TœïÃhn­ù$Ñ¢r;,ƽ{>m>6 Ê­=q(äìnç1+È4»›¦9·óÅv„Ä]ç÷ÆìšånæÀ¬K¯;· 2#•7/M8Y¯óWiÑÒþqÒ­âÎí·}£¶cžèX¦.21ã!ã*AdYÊ‘4éWœÖç¹ë¡ìl?¸û1›qôîÏýŒ”NÈŵŒ%I? bõ0æòXðÃ#¾¤ý ߈‘È”PÚÈË)öÛa3¢ø£ãê¸*²9YžÕܰyÆõhŸˆ£Ì‰ ”ÍÄàx6‹Žˆ"—IºÈ–e¹ ÄqÇüÎ弈!Ö+,V2å¼jxá ˜ã…› 8û5¢4¦ŠÜ&$? YRLž³£ÄHŠ˜›M3ÞI‚y!¦c7îªx'µ7âØsÚLQi£b7~jö–:ÓÔý¦6·»æÂ¹sæìöÆŽk›6æ`žú÷©•*}üëUg¢7­Æ@Aç £¡X¬±¨Ä"Û?Iþ–)d`5H ±‚YÝz7»«’ræ¸ìÚâ™]ñlaµ)퓾tX¸éÌ“îùqøx¥ž*õg](­9°˜¬Ïáÿ÷dcrÀ½™‰y¶Á`1ØÔLÂiOÙþ^-!ãt’Y/¬Åëz©÷™N ÷o)KÜà8$Œ~@¦÷*S¿�Ê?Ày›Î€Î¿‘Þò^ý^Ô"QÉ øL˜Òļ÷�}öÁÉnÿ˜«ù6G0`…»þ-sÀöûçó¾ï6sàè7¸•0àÄà» ÐeHÄ×òzqz“e="`?‰á°¾aI¡§åœ'‘w±`sé^ï6®¿dP"âõ—‚’“UnáPwÚJo 5NŽFšM—>ë'cõfFÛð €<ÇX É~É%¤„Zè;£Æ½ŒÖd9FðãD;9åÙªÔÇÉér“ÿÛ„ŽÅö+óå§XaAW¨ì#¡b¤²wRíÔôŠ$ÍvR›æ8ü?ÜÔ²{yóEWÿWÃJíÂ-‹ãÓÝöõ¸É†(×+’oêd£F·ÎG -KÊ„%ª¨”È OÙÍÓHRŠ„°~ž4Ä5‘Ùƒóãž&¾ê= %½m;mu%ØqvZoHQÛ!íyÚQYC‹š±ÒÉàíÁ˜¶[ÏùPa§u i("9óÆ$‹Bê‘i–«IpŽÉé½nIW'°Q$dØ!'$žÏ‰ã‚Í!Ò$`Ò3¬ç*r~PB§ÞÉTèŠ –r"££ 7%4‹”ï¹Wý¸jFÈ Ëäqr0‹óh\Y°TAÜÞ`»‰“rAEÉSÁ– kE™ÞDW;"ú^6šz>tC¼3ײQ*ñ±-é†õÓTÿýôÅSâGÙ„ÅÚ¿'FÉíü¸¼Ý/¡b+Êþ¼J/P˜§ ëSl*¸G’¿<ùBdõ^eÓ¸äRJk&ˆ¿ÁlAÈQ–~JÇ”ò.™ûÅØuyüš«ÉèóúzY@%F0Ì"ŠkäÌ$‹–凇üÈv9i¥vá{bjeÞl¼þaËßîå+kl{ð«=®VöYxù49ýÝ‹ÛLŽFK}ëú!ì–À1Ð�·àÀø†|ؤ¹AÿejѾ-s9�p÷¦@�ü·gÿÈ7ßÑÊü°äé=¡ï]€¤½×dþçÎ7|XÌkþÈ ?ÊÝŸ/Öðæ[sÀ÷5ÁÍøÀ/‘oÏï®olXÎ î FÀ�;Ä·÷¥‹Áì5¶0w$™@€eÍÎ-ã›|±¨È¿rbÎp¶-ÄκQ]ÔO.*õ‘âòe3¹µ 3·­NY×Ú˜ÏïööˆÝ>QËÂlõ1ÆŠä:EþQÛÿæÅÍW†æDš`ªŠÀ8ô»ß¼6 tÀî´Ëó1ËÈa‘{šuô_Kÿ¿ä{Óf×ã0ë¨ÕëøÅ(Ê ì|±L CGmo¸¹¨¶ôå‰ñ{¸Á ƒ‰³ƒ—åâç$¶ÛׯßmÉéõºªŽZA/ò˜¶Õ"ÉHÉ—=Ï;¾ˆâ‰ùaˆ rE Ì5Á&:È­¤õd¬cÕÉ”œvÀ¶üxd½ÃÔhùNt>{âùB ¥ÜIY÷Î9»È÷ ÉvÚcã°KÉ\SUíí7bXpq®H’›Z?ó2CdRs6D^0j7:¿÷½5ž%-2IªÌJ‡ VÅœ[)=ͬ/#)|Œ‘aÁz*¡†©<‹z=ÅàÇ^N™ãÈXGçˆÛU\ˆ$ã¢È•OºÑÕC¿7ž˜6Ømè.G*c"©*£(Ö‘ÎGtãëÞ͇Ak1ê¸1~Ëä»Y‰l)2¶û“–Æ¡eºöƒÛŸq&ñÍ‘mš:½Ž¾;%ý¬ô‹dv•]-1rôÃÓû¤G÷ìnD6—ügç$\`0XI}RŲl5î¦Øé39¬Ù«^[†ptj«X‹A‰Ið$B¦ˆ‹Ë¤êf±òf:kýkþF0Zƒ3¥Ž)³~]£¯±½h­× a,�Ù¯M¿` ž#5hâ8{ã©°�2À~'¼÷�5(44`ðä/~¯7À–}ûìÿ­ˆ²øVìþSú×Ì[‰á{�‰~SùŽÿètJÿIâO½g¿?_¼ÞvðäÊ^³·ºW˜�fÒ­ß÷µ7“¥îר><Ê z@ÈSµNÎì«Å+9Ž™þy]+6ˆ¾¡Dìg£ÕúŽ~s² ‡I¦¹Dw¹l‘•ŽÍm|T«{È&kñ連I„£Ä¬&!Á Ó ŽjÜ<uòÓ:*ì~M/ôˆ@Ö>tîKÀÌïˆ×ŸØ©ôÄUyÁgfúìö¦ª;_§ú²® 24ù'¿Ùq)g0b¸üH¿¤â $ƒð9v`Ž`•éh&@Cg¤k2–5XæÊ].œtãŒìXü6’ÛÑjåwzyàhJœeƒÑ|;M]¼fåoào7Óì’"5‚®q·¡–‹0Q[ò=ûUcžuU»ÏD§ï6õ4²˜üÐéò.oÇèo°·Ýlq0A:’”f•2p!ý>Š•Ã^-ÃÈg 1òҕ¬N‹jÜÖÝõ’Š”3–.½D;΃„䯗Â1²à5¦À&G‚‚ÒÀý$¢ 1dzÒº¦5*ƒ’ƒ™hx’eÐÑð¡õz?L¯÷ýÍþ¦Ñe,fœ(™I%G)8›ìMô·t?®ö^>s¶dtVlT Ø‹q_ž,ýŒRáÂ`yé#:ÉÌsJøË8‘h‹Þ•G]”ýö7liØŠuÚº,Y•Ël�ßQƒ¤Å‘ß‹YúÛý­Õx ÉC§ F v(èçOÌ9[+Þõ·I{e³C2TíüÅGå±þÆ™=ÙÑ â<‡MäßecCSÈæ.û»* @Þˆs\_,…­lÿcð»x y‹Ýq3´õ»:" ½‚–ÐÐÈ�d|7°Þ8 Æ÷á6‹#Ü 7¸zpÀ�™âÓö~×?ðhzÞ Êö½G^öLc>|Tÿ'Ÿä²Ðÿ£+þx™òéêÛ~>Þ}Ë–�ŽJìßmó÷ñª©÷²Þ4R$@û ¦ÅpRióø·âRâB‡dLÔÆ%®jífŒô”¼÷˜'Sî`vŸ“#Ynv°¡øÓtzJ›Ù<¦¦tËe^5£åñvìûÛñúM½ã?…Ya³Æ‰P>Çbõú“Ni›>GlaQAV¯ë‰×Ï$Œ÷:8½Ù/Ö±‡6Ó=]?—è¯ÐlwÅ_V¢IØ‹*…¦òV˜Ž O@Ï»Y] jàñ%€Œ CïýóS· ûãYsÈ6#Yn,â$@I:zb/7CTÎ lÆ›»ëËþ;¯:?6Sº’äÏÖIº‘íëä²DY§B‰Ü-Ò¶Æøï™³z†.¹ ;DuÄÊ-ówEWMÉt€¶‹7ÁVÎU)+ÑR1v¶»b—i×d2ë˜R2#'iz˜$íD®îè?"Ï=ÏM˜ñ%!^…=áŽHG©•ÆGâ´ÞÏ#ÎêAÁPm½{ØšÎNó~¢.ŠT‡AtîNn³ê!^ÝÕ×Û¢÷sáyáä|Æ“TÈÉ¹ÎØ×C½—›\~‹K1‘(ªÁÀ}"Asî¬!Cö1Î,ù8ç¾+}hÚ±¿Eû$ ù¼ýüf)k᱃øš-åÒÕŸÀüòe‡Õ DËû=yq ­_ó:gf ¸êó”þÙAÁ šY?ß®§¯¥“9ã“ôvUR&»m?ÜHh‰cOÀоb»–3d"³Þ"“ãBœaáU}Ž€Òð¸Ç¸ò÷¥ùÃÆdòSøô±¯f%¾–MK=zO:¯‡çúÛ1Ñâ݃µõ\ê`„Cx‹ª¬ß8¬¾¡©¿#\<î~ˆaHÞIÓ{bˆÌwƒøAµÒê«ËUÝðSA~2_ýA<äæžzÊ…\üAð×ôØ ž+˜I¿Ýæ P þ´ °)Põý#s H\V¸ä8 8D 1ŸóýÇ¡îÿèS¶Ù¶­w¿&Fœˆí˜N¹Ø÷QaNžÊ"äJGÑ0šõlêšp;tÐkd€’…SÙ¸úyb�٠ܧPþ(Ÿ’Õ×G>/Å4­—ý/©Añf;È5Ì=º›¥²%¿Ðæ×¿9ŸÿoçH$@¤îÎïnB—‘œE–ð;´·�…º=8¤øÙ{³&9Ž5Kì¸{„Ç™‘™•µ  (�—ïÂÛ­ÖXF#“4&™éiþïHfzP÷hÚ¦‡²&Ñ—$ ‰¬Ê5"c÷pw=T‰¥�‚K_õmS`‰ØàáßùöóI']Éf½×ƒn3OßÍ·¶î6©¢h(\.eiKÒ·j›m•~¡AÖ„fuIù¨­µÕ-F“FʹšžüwKÎçî>.“ ‘Ò"µ¡€ÕÍkþ¿KÿîÄGàÀý% g¢í ŽfRHM×Àbâ;¾ÈÙ^ “Ã?ž¸‡¡ûšû² ‘ ʱ=n,‹´QUŽÝ&÷©¦¦ÓjE´ïˆ±¥ (émäÌ …QRHÕ S×%°i#ÚF)çÆ”±v]pÑrÑËq‘FnÇí®kìt —tñ€çy¿>ßÐeëž0° §w¨çöÐ&ïøeiÍÈÜap´ÇT›µÝ‚ h0}n Kw¼3׫¾²Ží&ê—GBæ<*ŽÕ%ú®i|»ðUÌÇ5ü¥#KÜ ó†ì6vU"gÈø´æú iCâß·…=Œ‹Á~p慹…`ÈSM+¢÷«…Õc½k¨õe-lPcðŒpÈÛаÔÕ¿wDwèò5Ïô™Ä>0†0xÚBT€ð)ÐÕx P˜ïj{†À=ë)*?¡CJQæò—]ý…®;kÑwXØò¸Îgßj!Þ¬C¹Š" òFéûê]b›æV›ï;Ö¼WÐ/�ªk#Rþè˜Ê;Ãám¯÷ç¢ÄOU üçûVï<ªëì€êõVë`@ù>EqºŽù� à[×õ˯¼˜þà×ý÷Z„àÌ`Ô5$=…“€H5"dVC]â˜ÿ¥ö-t;}žÆˆ+'uæØkйvÁÛ\­©¨ÁÝØ¹/DŸgMw¶,ÖµÆÞ}èç°ü‘õL5i™#�îþuÇkH«YQ´ZèºýT¢‹’íf,_Í¥`°”¨Ý §í,épÊ…}‹‚£UâüEZƒ�{ÉC9Ö®ê¼:mÆ~zHáj¤:Ù‰ Š t-å·»L\¤nFaÖ¢Ä.…Xí6çÎÿ)íÿíA2&I”psÚ:…KÎù%½<ÖðO†S‹¸íe±Ú)§¶1ÛcV>'—HÙ2¶—û¬jwCG'woþʱ5)·¥Lê»öúd0ñ¥w³Ã ;põiG÷=ÓŠZ–ë°Ê6,YB-‘u­î©P”.5³¨"LI¡IMˆ`@Kd¦›ÆhÙ‚Z¾-:UIaÙWY‹"Ÿ|SN3ªö¶bäæ¾-ÊZn[{wö·"ù…XúîÖQ[ VŠ»†[žP*˜Ãœ¡Æfô–[Ô&½?ÛLúN­¹~d¶å¦[Ķaf¨:iM\™Çz&$s»©“Òºc˜t̹õ ¿!•ú¸õØ$Ý­€Gp—@ZVÊ0÷[–Á"¸”žïó}áU™¾Pu_uwšt-–u|´ò¸FxFçÞnnGÐüÊGcaP#6Å'z,:¯~D_VùËogywµ^•ú@¼�vÀbŒ®Óƒ£ßUùX@ï6h/¦B�ÙFÁ\^ÜÕ (7@#‚«¤´ 3hQߎT—ÜÞ|‹7psœ¾Âš÷ úU?ÙJ~ß…Õmí_F1%ñã#Ko/Çwñ8òKE¨`ÞjŽë^§ÚÆ•ÈôºÂîÚ-¤@ZªDýS*ˆ¿‹B®ù«…°æÚͽ*„8…ö J´;Ô ´SazÔð“6»ƒ\ÿª©bYBÏÀŸ•ñG©Ì<­wbEqëxÄ©È쫺Y¯ Â�\€<„l´-ÖAÚqð%à ”_ˆ~4ãõÄFÃ[l ¤ÍÑÿ÷¨™K¿Ô'sÙ¡—œµÂ4@‹áŽÑÎ`Û‚×aÛØUŨSP#Ó®ÕrI»Ô_Â�†¹Cd1XíSi:àå|2„ãòíW]½ßMbw™V=o7ù$îöΠ€â™]lj=ˆÃŒ™¼ÙÛ†ƒ=ÉI«|ØF¬l;i¶wúµw9iwž«Ýº€­“È>°‰Ïþ¾ÒÏîôŸøaà :æì†Ôù¤//yèCÀÍÜ‘ËoÁ²q KO{Juo`‹Ún¥FÞöMIW©¥z¹µXÌÄ:I×i"u’Ú–’–•ËþRЬìúžøvã)P»°µRõ¦mº²ªæ…ÓJ¯âÚ"…iºp"^š‚�� �IDAT{Kˆä^—z΢×Cç@ÐÎídêC[„È5éuh7ƪw¥-ZxžºMÖï[’´=Ê,œ‰î.D2®ôȶ4X7ü³l‹:î½Æ°a|à ÖxÑ“aoƒE[-{ÂKm3’Y8¡ÏÜ$%ÑÅ*à°¶9 u½5j. ¤ ÕÿbÈ/ë—"wK›ÓL8îß?>P3u.¬à lÃ�û‰ç×û^ë€5Û–?Ímôu²À°áRx”À<½a¬qð8¿‚ŽúÚ¤»æÆ¿„­a·°rÌ9Öâüû‚£í¯fv½=^io¦€÷®ÂV| tÀã[˗䵦{#4ý“­ä÷]˜ÿò1%ó*ཅ‚·žüÆ¿š÷^òæ ?VgÞºâf>ó/“í0·Y¿wÁ®§uhÀ¾AsG { 󞄪ï|Ï›÷‰nJ˜À!ß±8]‚î|Š–`Ç  Žˆåí´w9·Žzß·/˜Œ=âÂŒ*lØ¿mÙ¾œp‡­ YÃOjô­7ƒ³ê „€¿ƒÞ¢_s·pH±R¸Ø .j¬ »ïÐŽ¨Íý¥Àˆ¡cÐIFgûó¾å'å§¾êj<ÞX ÕñÈ=Î^¢W™„�Gnìcá�ÐÓáÊŠÝ–4iW£óns`À¶ºîSô%±mx6ˆ#Z.t}Õ 3·VU–fXã>ÁР:žÿêt;öýCáº;ŠªïG`Qø²gz£S2 =£þÔÑb-†ƒ¾%¹lªŒmÇ:®É˜‘¨¶÷WtöÓX¹Ñ•³L |K{}oÌe¥>Br8ÔR%Ý]P~×#‚ò°U;Ö;å­Z×–æÅºzþ’Ь Ý®öl™ïݱ1NJêÉJñ¾îhUrÛËÉ´NëfÓªN F¾ Ï4–Èû¶V•)š±PÍHç‰Õ6ãoµ8ô~O\nKÅ6®öðûèø©•,Hñë¶èx£t'*Õ‰åØQnu¹ìfog9Á‰}‚` þÑ3³‚L Rý~ELQ“¾êOîåX?1Õ¿ò&®=¢ŽÃéD³¦uW§1P©ÙZÁ³·†5Ò{@6®ÀÔì§Ôû»‰·ªdH 9¸8ßWmäE¤Fÿ¿ùÓ‡”pBþèÿßj.Õ…slô³á@܉f¡ñ«á‘4pI6D}à}zÀ&žñínÕ²¯S:–õÈd‹“U“)L¡ÃG4ŸÕ×Èk®&@^ÛÝß‹Åuƒq ´˜Ý^Èr-eÐPà.VWò)€×«BnAwq=y¾{Oåäëç-Ø"q8w¨ßžÒ#~žyýJPü½ýÖÏU oúy¯ÁMôœ¼ãÇ÷]%@~¬Î¼õäßðÅm-râçe;^?“Ýxo—¶â4g.Ћ÷•»y€ \;ů<¥ø» Evâ€F`!…KCÌK‡;ºOAHVKzÙ:-Ø^ïŽ=b<up’¶Åvñ•VNþ0¬³LÔpvÀ:AW·ÓŽ€8x  œfßÁž®€XŸyëK‡ì”M’œ»bàÄOfq&ÏÁÁ}8ue‰Jߌ¼Ú zÝŸ…p˜),GÀ{Š¥_ÔÆiHŽæXVUãˆ,¬h?P¡ÝT]s4ñ:÷‚8eÎȶ¦´Oˆ±\»8t̘Ö/Úzí‚-,ÛÛ ›„•Üʹ–6¦²’Ž®”—Io¸á#°á¥úÆð]̘P•S.½Æ³¨“‡DU¦²¼tí&4²�ÑZx~á[–#¹@]çâbm9sûÀ¥õóL=-l+¥TÏæœÇÔmzG U¦­6ƒBqJàåU]æ•7F{¶Ò c”×-º¦/×~µg<;²éÈ*:ªrˆÆö”±•ò;)†²õÝÜ¯ÝÆ¥NPv}eõ R3•éz³h6yÔ$›º_>Sw<a½Ø…q-ò=ÞSÃ^ýªuÿ–@ºº´m§½àΉg˜¯YBþ×£Á‘¦Eï¬zé —–»ã²«ØB4n¶z@xhžLsÈ¢á'®PúÙÄýŸÆv2| }c»ã®Øü„…wo…8äûÿÇd÷ÉK˜MØöýü^-íDïŽÙÀšŠ6齸æ)ìŒÈ‹þË´GYÖs®p8âwF„ÿl Ö^ׂ¾7Òà�¤º•|ó{)k®œï}ˆ•àäp}£ˆhXý1Ôìššözü¾×‹–ðhþMÔ?ãè��ävŽoë§+†[Ýs›[ðK¶Zÿ"¹è«<âƒÀ[°{wÔ?䩨skÔuÿËûŽ ®‡€¿9Ðü‹½êd�Å“iqîŽþbíªºVV3kº‰ :!ÄÒiÎêvᨽ–'c­©jyaÛ WæÅÌÿF{ÿÉÏð‘À1PXƒ—8�žb)0…í æÐX‡ ÜL9)á]ŠF,ÌýhNêS迆]"¼@ø2a(¤Ê*ž-bÁQØ=E! o¨¥Ê3Ø;ÜI[‚Іϡ…¹`é¥q% g0b»C_.`'ϧtß,[ËË.ÂÊz„ü lƒîbëÆÃÈŠ¥J§‹L熪ç„xr™iñ’z¨'¾ hÝ·¹'û|pð™e†$¨24›Ž~ÁøojKÚlJt7ýÕÐî.h˜6’r´sR‡^ëµe9d2ØÌe¾{fŽV÷Xïˆ5R«¬„e.÷è±ãe÷keWfµBÆíž½ätW•y+IãSÏ㺠sx½ÝoÛ]µ›4ëHIvÀ-»LuJ(»µŒå’Îz—’3]V»ún¦{~¬þ«(U‰»]›K›¥Ãà«¡¤q«ð2k¯£¨ªËnÀª]£[Ú¦‘äN(Â�¶ódèþ›Ðºà„1W³ËM_ÍiÝ kÿªŽÊUÿ †(Žál'à‰þù. Á è~ä »ÕŒó`ìÛÒ‰]+$µô;=´¦ÿŽwœMWZtð n­jÄØ—vT â¶ ²­ZKóùj‹/ :ç‰Æ ÅdÇÙÇJ<#Ø�ðmù00 Ý­í[Rvy­!�` xø.Bu‹°g€/ ^¹ƒs+Š[mS è‹ôŠ•ùŸ.L߃c'ÞEJý/q^ôk—·<†›ö´÷8€¯hx 8ïšÈúÎo9¸eŠÓ÷s{>ÀƒÐ3ì lñ:ÁÆðF«e¯¥A^Ã!š¾úÏ ù+˜ö9سÒ| gõ­´˜ï6Oõ7r®|r<ðl¾qû?øÔþ$v& biÿ¡v³BÀgôÕZ½5¤ iAs¸ÝÕäì³ F5âm<ž�†Â/PÃ|ÀŠý?ä–€ lð60¹ê5õÑ”â{²©«VÁ÷ -d¶ú€Ãh€`Ân€ /˜À8ìíº©é«Š<Ä`>ƒûD0·ˆäÆrúÎ(©¨–lÓWŸË<§Ü‰ØÂ%w»64 3­ò²D¹Aólƒ²ÏEÝlMؤ±Mo5±Ur½hsVí7J÷n¹™üÀw-Ãi§}Q©T5¥›U§dÙ:ßè}K»UÖ¹t‰Å¸e%NÉ:Ö¶¤mùºo(ëƒVu†tJf´ œÎÅ¡ÀaAüÞì*´Fµ¸Œéy—%«…t,ÐEŠñ^mÛÆXr±2߬kåm÷EìO츒‘è7N g°¨B«±÷$/)S§¿HL½•çÍ=o³´U^‡aq¾Gšˆ"걯àN욉!ZnD@œû©À7%ëkfµ#³­œ:àèä¨)Ö�Rˆ½íHÙõHù¼G¬ÊcNH‡¤'‘€cXcèÎëYh…L1¨½¼÷µ/=>s™±ûæ4ôÎŽ|ÝŸ=]<÷åÄv4e1ÎÁ¿“zãn=àE�Ëw™çÜzUy ü;£J¼)òÊ/æpøMLèVlm®ìýWÚüˆƒzKNÜLsûE‹?›w‚ÞOÒ æ½¹òC)„.ií×ʯþ�Èn¢ù¯zâ'.Û×=ÌxWšú= ¸oÔ¯Ç�ldr|CÓôVÆcdŒyÿ�í ®²ƒ»xÖ6|ò%Ô½mM'=¯Dü÷Ô½cOb±OIRóß•ÇóÌpÒ³Yª)C`ºÃê,w€m£-E}Ùîlì£&¨‹²‡TÜã¢P 2†�ƒå R™¿– J �¨9W86匋µÀ#8ÆpF"±×òdǺNíšOÓ.‚ û©êÉP¦p' %„€„cÂ\×Õp[³—~°w¾·¬Qeg¦ƒ›p?(Ñw6©4³´åûI®ö‘gn¤´WÃyæ¦/Ä™¯÷íâè÷HŒn}Br‹¬ëÎ*Úîb0˜�ï&rí”ÃÎìåI)í*k…wÙv<¥*j;ÁG>ü¾jÍDÚ=XÃñ;;0¥Ý­âEi¾&ä®U1.xÒj¥éÌW ^Ç÷ò¿eÕÑÂüÕ`üP°¸ P­ÙësWÛš:ÈÚÉÛZJU1áј2²µIeÔø¢X¯ÕéÚÜK¼dje¯7dc$Ä[Z-$6{Ð:ÑÓi9´jR5p¸älgÒ~r ¿¬z;5²Ël/K%à�–¦�¶À]àWVÕ'ýÙ‚=1öà÷^»Ôu [K»ô˜ *y¡²ÇÛΑ»ûíÎï».¨‚™§…A[\0¡r N:ëAÕ“*wÔ2’#&~²Î­?¬,�‘:ºSDŒ§„'ß·½®$GqM`wöñ^ÿ†<ú ­ŽÛbVÕâzÒÖ-öÜûòÌï0þ^³MoZí’›€ò+Œ;ªâOëS Ò㟸.¿Ñóãï,zñó»+š«©ï¨ 0øÍVo¯ÃU[ÅL^…žüÛ—hñ]î!¨Ð ,9zŽi ·D¼�¾„g»êžíöÊtmpW*ˆ4£V_{…=˜0fÖĵN±Þó±ëUŠúc58C‡»Ç�÷ \b�æaÇ|švŒ[`‰}@«$À°ex�¸Àx@GÑ2Ñ3¤"­o53hñ‰ÏGÖ§¶Ý¥¢®-sX;«~ÔK «Ä±y¾€Ø"x‰ u&UÒ¥¡°òÔŸ#zº÷ s™\Xjç \XDhÌl*é2`ÿ¶  BâÕü´_<«G}4V¿Êh º]¹èšßî‘q‡$Õ‹öDm|†YG sîË%«÷‰ºŸÖF" ƒu­Ö}žØŠwÒ~ªxŸ1kÓÎi\©Š2‹Tƒ]g/$K(-=Ëï=ÓÀݾ8ê…)ƒo˜õÔ¡a¼ûÆÏa]¦¢wü6çZ=tÅ‘`ê+±f2ý-Ô¸¯êцy6º¤/ Ú^Û|›FyöhM‰>ü¦wÌà.�G|œön¯çÈ<¬‡ Ç]›õ-Râ%Ýà œž–"øÆ¸]jgºÇk‘¥¸/ Î à > z è),yPà7@Ò7)k K@¶ !ÝëM´~¾Û¦N7¨õ—iQnV%{Ô–«‰zBvX„•6<$ë»!$mÛ•+ÎJú²„êŠä22òºÀ5}Š‹Ç(øDÔ×ůRJ¼nu¯Ëšþ^NnÇPÌ{Î ™¸x- À8Þ}«ïòÌÉmhþ.ãï]Ú"½aþKi�|ßMÞÉÑý½=û6QŸùÿV[|HføZ»Í/˜êàB¾‹Gïýß즞àõ%””½žè~÷E€º²wD„Ïœõd7ˆ¤èà@9ŽÿŸu 7Ì2dˆô�së,Iþ¯ƒIg@`X)t Ýí5ÒÅ eZsXßÍ´>@%á›Ú·8ïÇyO«U—^íóîj¿k°ØqˆAXH78õ5ÚÕ‚+‚W5 u™Å:4Žà_åä"¡ý¸÷ýÝ´Øz2Aø FËê>ÖOø"öÙL84Ykzo@xP §Öq`¡è\17 qÙÁdÃce}L„=ÎÏtý£¥ò`­=Ü­°Mï.ĸ )í³N—}*»&´-ËèéFK«µ÷ÀØ„íE¦´ñ\Qƒr~`×Kk!Ö»Þo”<<Zõ5HÍ}E¹je¯šÖbŽ`ÖË>°{ï`"æ,ôΗ-ø Uv ]ƒkÿ¸q‰èXJ:tò+´ =` ½rκQ(‡D8´½¿ÃdE}†<¸Í¦Âp c¹64ëöз¨}Œ‹œIƒ äÏqРɷ¥s|~è¡õÛsJJè¸ZûbVs¤ÂD,¡Æ˜h¬•�›)ð—Àh4Ä|X£©a³œîÕmDÛ -Äv÷Ç/zwÒ¿ÓGÔÛgUa‹¿›ô(3^×bWán|š&ŸPC«-yV²ìÛür½óðrÛ`dÐó‚ð¸QáïЧØ<¾Ú5À<ôâÕ)[â‡Y¿G9á4(:a¿)È"óÎÓ«™XoßÍÁ¬û <ùŸTón ÿpþÇst“w×á½…F?¡4ö'¹B¿hõ/¬ÏÊ7^É¿òúþ£ú>c‘}È:8î ;ñNmçS4…°š¹L A›` Á …ûÌôôw€†…^Ÿ´ÆìI³„]C^•[,ëÊ©:{þjÜŠsdÇ 3xâjo­õc÷%C§0íî ;E}öª!ÄbN,±gaF?3ñ)JÀIÑ$-ŽCX'…s^/a¥�(D�L#ØÔ²R;½ Ì:g¢µq‘~Žz ó1úqîhx<í‰U³F‚ÅO„A@8rÞ‚lõÅ"+II/] ÷ ød©CjmU_Úcá¹áÛÞ^ªË':ø×môQ?pêMæ&p:ì‡-g¼¶:%¾ªÆaw³¡ìUæžµ6Mµ²êÀUVh ‹‰FÁo¦ëÌò2Ù;[Ûm#ß÷øEãN6+²¶† Ž:t3bĉµ eœf÷^(ÏóïºïÕý·èJ8½ííŒü*¬d&:•¾ˆ\ÛAÝég$ú Èm®éÆ»kyÃ¥2»²A¯¡¼¨K"=j½híj8]èn¤"³–Ü(¯²šœT&µNwMH³UŒÔã('½fàȤت»ÖÜW<W#ênOº…ºps}œC·ÍŽzi(`Û§ˆ‚ÌWdÉçcT6Š…‹/4àد¸6bqpñŽíÞçdÉèaôå` <j;z ªŒ–ýšîxŽsßI3r¯_³à½rVùr]-ùœE’hÐð±ðSÛK8œ øõÄøðìnHë �¶öî(~¥¸ñò‹J‰êvÐz[Ü®ýÞR¢ûé`"˜ÕïI°�}È,†?U.š¼Nü@Þýã^õÃ&¼°1“ÿŒÃ÷8.¿S õw6þ8躄pÄ-†Ç핟‘�ôÒæŸ³T°º¥këÆ5Ž]˜QcÈyëü…lS\±ã7øÞ_¦@ ÔW0;Õb¬Qج€¨ž"õ°ß8s”Šmìl¤%P�xŸšzÛôäæÎY/€pžv¨b É’¥©lø€ßí ßÇ-™Õ[ÑMÿªC}n™䣾êÐ?A÷�„¶›ÅÑ8>býénáÈoY;þ ûíÓ.ÁòcŒO >‚KÂuº1i*~Þî+¹aÂ2Õ,hÃAœÄ{\×Ülx¾ÀÈ?âÁÄͨ‰[w\9.›Eó—¶£„ƒ.—›g_Éâdnu,•WŒö¿Š{!ôo&ã©(iïö&º‚,åØNdݱ$oŠþ)9ÙôuKZ·.ÇNµçoX5—ùQcyµç1›Hq¢D`L&œo!ÕÙÎ §ïµ© Š—`³¡íÅm$J—²Aú%µÎÇž#ÿÌeQÚïþÞ$øŸ}º¤M¬A4(ÄZ/ÅAØò¥Ø0r¦×gØÀ(ì3Ø@'uR¦ž AÙ1ƒ`bÕÆv£"˜5 ÿe©7_{É}3ÏÆVajAž‚²pØ�:·¹Ûrç~ç?°Ø^3šfÌr¸ó=éümU‘¦$áYç&»Ì<Y8Ȫ'žjÙÐ-›m‚ñ´G}ÓÛÏ‚H4l p® ¿øõuθå¦*nŠÕB•ô]­Ñ»Ÿ‡&òç)†4­Ÿ‹øïO;ÿ¨>üªX»_�Ïý[°ûÝ#–~0Š%^ûÜö÷Ò [÷CÆ…ÍMg686àáXâØ€L^ͽN¥xÀ�ghj 6ihí <ÃÁDlYCôÙØsÄKHö81u*ž#LG_A,Cˆû�m æxÇæ#éwËæ‰ A@ÆH ¤ƒ5Gz¥÷7�ˆn¬óbàӖÞ–ùþþYW?ÿlX=loÏ÷Û#/ÔY!Q¤°K6/½j8 Øà„î»d¤è¶k½o‰^B«Ö ˦l/!±�Ká�ƒêÉ6…©V‡§ÞnBÚ Ñ, D²±äÞÀöËçÍp ;0úEµ„ˆ Ö–*'œ2æ NÚEWŸû¶RCl“ {.ò¬+._:1¢=¿«÷.U;»è,=oE¬úê͗¶S´P2¸k^´ÄTˆ:j¤`V fÆ_KÏØWÑT±¢TF O<ÀwÓ]³·s†M7Z[Ú±Õ’¬ÍÈyæîtF&­ßWv6Çú‰áG‡zž x äTõ5YóÔI­ÓÀ?ë¾/”xNzÄ[4 žöÀ’9PK(¼�ŒÜ‡PˆÁ-PK‚ÔÂélߣ™/W¶Œwý84èE6tÎfG\† ím»2mF6õ½@ÑA>Á eBÊŠá>ñ&b8û‡#Û©RîòeáÕTð‹\ÖŸÑŽÜYÙ|›4†>Îpèð)Qs§ù[K`,î†Ø¨£W0õ÷Q‰ò&É›½¢<@¾srðUq#ûeúoìZ‚‰z%rÿV‡ù‰~χÇ]þÄ~Ã?»ã‡ Üb }óü£¯ãOÅrï–Wºý4 8ÄÃ+Ú( ,é ûÀb ¬€ëÁ‡GÀ§@\;è]9�¼v@(³c—É}×öYÞEØÆnŸc Xßq¬qí Šƒ—|ÀFâ ÒÈþ-%Ýï'“1q³ÈÁO$ÌŸ|k/æ¶F¬ïÀXhïT›˜ó#?†*NU4*Ç»²¦@)á€uâûüØ!èÌn½K›†¾�D¯¸ì%¦ Óbd’©ñý]MdÆ2À-b#ô%Ó@ ïfv«ß� Ú´B„K#/`Û 3«9³ 8u¼¿ g.}BìKJ{z´Â|Öüã¨9Ð`ÕFÕ¶Ó¢Õ"ú<'‡Žå1¡ÉjX§îuÔ{mßlõ„µseé²ñËK·qðœh:¦ðIC,-ÝÓP§ÌË|—Vi:”]µïؿԞ·m•]vq‡]?iäùVÇùX“zÊÏÑ u;<Фºô{ˆ’[Ça7k!¤š«�ƒ�}ÃÕÅ#9ä6å âŠÿk8-šM9ê´T‹zÙô㦎£JЦˆ€�ÌE/¸tÄe'€™€Ø³À';w’Œ Iš'«…ê°)|™Ûjë±Óv ·õÚg’` ^JÞÎo[-ÐëÔîP‡½èúH:‚Œ}š6ðò&H¥•·Í|bϧú¨Jh5ð 5ºÚlDƒxŽè¯Û;¶àe³Ù/`nÐSÒGKk1œ›êèþ•_ÞÊ"ð×É*øÏ´,àP×ïù=¼Ä€¹Il¿A?¬â÷'6ÿ¥qtÿ ð&ïù@yýN~G›Lz{—µˆ›§G?oòhýþÝö¶9p3us�Кìúôý}€ñw–¢ãà ¸¶ùe#vM8ظ2Ëö½0 ö¦ÔÒ•u›/]šÓbM¬šF>ªv®›ÓS Mÿ üÞÆé1îx#GÆrèݵã¢F­H:EÙ í‡páÌ&Ë,œ§´:Ðä\8wò3á€å¥mn&W­Á ÖÏ\‡ÉÔÒÜ™|ªlS¹63´c �†é‘Íl¥ä*C$uÑ"¤EÁgð³k®b§Ùƒaô­Ù€Í »kÌõâ!ÓÞ`"‘£(‹%šÍ‰¶½ðnÇÚãKïŒXÿÅèã§iЭÜG؆)ïö¨ŽµçðÐ%8àâ©-?ïUùLÞol×ÁjÀæT"ë@ˆ>ˆ9Xû®}Á–Ýw{¬‡\3&œ`XFÿP‡Ê(ùËûËtÂaÿ~CÌJéÙ.‰óY�¨ »û4ä¹Û¬’ºGÛ¥¶n]yCÑÝ©ÚQ 6s=ßé‚™o*NÊ~àõ^ ÌpA(vÍËt;þƒëžÛ7f`}Ð<­«ÕøhŽäf÷ºHzŒSîÖÇ9ÓÅPÈ)]œ”ê)Íîwå€OÎu Ú}„M²SoiùÞ|ÙŸäíñÕßœA`ØêA(º ©Ø¤/‚©ÛX§¢ÑæA×Ug©üö›ù@áa‡È ñB'ýXo«4-}© k¸;¼ÔÛºÅóW¬·õUµƒºÅ,�òº—ð&ßãP¯¢Ä´ÿê_½Þïà¼ü›_ $Çú—®ŽÙ[QÂ÷{Uü{Óûç?úÕ~÷‚ÿ×V‰·¶gx÷l®]è7¶ØÀ+pÑ�ÿx}‡j6%âX`-ÒónzTÕ€õoÊÞoc¯³ºŸy}ž§Nü¥Œ^®sD@‚ý ò¿EãZ‚ªiž‡ ¢&þÑ¿jœ<–V”ÿÆ­Õ…¿¾8· \L0e+´V8ì7¹ŒzËœwrçÖ¤ Ž¡gh¬EB!É®×S?v‹è¸Uµj§Ø|ÔbÏÇN=Ú¹{TÔ¢±NuN¶PÂ6É(U[ÑÕƒä�� �IDAT£¨óþi8ã;*ôÕ×}{VYÔá¦/Ñ¥à@ÞÀµ**r1Î2ЦŽ[ŠíyØó{g–<{±ýuîåwªˆÉº½7¬ùýpÔÉ1øE¬Aõ…… ¥ÝK·@P@P{7žŒ*y–È«¦H/G/†£$èi¸Ì½A8ü�ûêh°NÙ!òöÅšü.ˈUYr%BÅ]Rý3e-—ôÄçC&&ªûœc=ÄÇäDÏ‹%ú¨ý£Ö9]z²Ñ[覗6 lHù«¥p¨:­„}Ü÷¯*¨ŠxH„cÌ3X©Û'5Ä™E§B—¸q2Xµ§³ä¢0ê+gŸÏƒé™ŒóQ$Bûâce{Åe¿8þÆjNtã.àÔÆ.FÚ7~Sz9ÝÏõï›Ìå2GºÃh›ò.«Pœ'³¢v±{Ám<ÕˆZ¬¶–ɯF]½f½©Û[ ª·¨„Þ4Æßl†ýñUìØš+¹ûdÿ»ÔˆõƒgK¼5(TüÿºáuÀ{ÃÛ;鵕½-yÅߢä}ûÑï·;>Ø*a?HÅñÝ9( €[zp"`ŸÃ]A4/Ð¥×ÚD‰$烫R¼œƒ�ÃǼï¨ÿ©ÇîHžPL?º,’‹ÊA1<Љ«M ®@p´¿ivvК&w³¸ïu··Œ9“Œn{B\1¬%cM ’‘¼6§[F1|Àë?ò¯Àr8{ñkº8©´±¤Õ‹áUÅêé]ûÔ äv²]ëß—·I ØÚñ!_b*@ ÕaŸ9«YWuJƒSÄ|0µS‘)Ü“9#E}vYŽmSê¹*dõó¨pmÿ²5ÛÊ" ŸœJµ×^(ò„:›åšO¹“HËñ4+ÁÕÑoôÑš×ÙîlêÙ»©©©ï^Âʵ›o‡Ý~b±k÷³\á+3|Y›~1ïœ: Ž+3Ûµ@'{óìoj²jöî=ùw“P¸¡´<å<8Yš¯f´‡ŸJ¸@¼( –TÁRZÂ6H4–@Žyƒ¹ˆð¢B¢±«ûX½ ªKÔ)€î'öw/Û,Å OãÆwâUä}­øÉ’Z ¾>h¦‘j_´'bÿþ£;ñ >k¬Lo@.W�ÅWbýÐlÝŽ—þÁzŸ¥¥JÒb”Ë[¶“,‡¼ìu^1¸~¿CÜB�ßG­2 Gã%l9Ï·çeäÚtàGî^•8@&¤ ó­õYÉÅÀlqø²òÖ`K4©ÚŠwô”½“ÒîG[?îr¢1X Ò?@àv»örß"r–¯(¶ƒ~?1âýç¨~Ô7þà3¯ãƒoï¤7WV¾ë3ÜŒúy÷Æz?'LJ}<õݦ¹m‚j¦kýñôÆAà¯Ðÿq‚ÄÀš¡ºa6W›Ž×8Þaöò;sc{öÄ ÛÏÚö·|'ýX[¡ë²]'{ÈÌr³¸î ¢Î]Gj~ÇCT™o¸®×ZŽŽÛatÀtDlЬ½É ë4Q;µb8áÍÔøÉ=ú`WvƒFìé4tQPPPÀ:‚õžzU\Ð)”Æ«N¦Æóê2YV'äebmÅ(õSÞˆîEÓrhwaŸšÈA…Ö<iN0%JÿÌг]“Œè·ìº%[Й‡t°¶cGùÑ ûo¤­5:ýäÈæ«½¶79Ó Õ²SîÐ úª+c8¥Ç.‡þ°c”¨¦­ü º'ëX&Pî^G}x[r°¨¦²¬ÌŒ3d¡B6á;:ô±(8„ßC=¤$ðkaÓÎ’…$*;_t%ž¿Ú8¡ƒU7Œù4j—³=oÁÓ¸‚ T€¨XÊJEûga±£UZ§Øi�GÇ\zQ»­•—2n·m¹«q�GåCƒø‹Ä ÇÍ}xš‘=ÏwÝ|­ÎvŠô€äg½äÄÿò^جZÔÖƒÂ:j}6#RÄdÁ:Ý-Ü|Uáx‹X�ó 0çýÁ`<ÚÅû]]­7yƒª üT3^H± =žGD;ÍËSRŸmcX˜ƒÚ[5(ò´Bpr;“ñc€â&‘{àšœõœ×‚χ|gq[`wÞ¬otõ¦öên1ßû&·Xâ'z<žºáŸ,ë[¿¶“~¼/)HõƒÃÙÄ/¢Æ®Bý­ëP½w| pâ˜á 6ú!0Bé£û¬ƒæ×Ýp®F Ñ`v‘¾²Ô¸È`†K*}Dz«¾‡]Êêv.\=t;s2êlõ`ppW5ÚnLÕŠƒ:ã‹À“V5i”?¾ ÝaG\ôDÖƒš}Ó~EÔ ù6æõ›}¾­^�’ÃuV>”Þ÷E>ÖKZƒM Bj׳Õýv[‘T‘RG¬„soo ·b÷y°jršû!ÈŽË©œÏÇ‚K e ö"•þV&vT~ô”j¿0Ê—ú(èB»ù‘Ùsu˜êx¤<O5ê¥nK&Rˆ3U^"›¿\ò»Ó I—]Çtîס啯²Ö°›õwçÔ­¥#@fp!8Z&½› KÏØ‹µÈ+3E4ª |¢-K¶­1e¯f»úÍ ¶5šK�Ñ0Î͹.¸¸Û¬<•; mÀ#»zo$‡Zw6þ“í ¦A·éö{vµ¹Á¬‚šóP©ÒI¤ÖçÜ\,‹agQ<á¿;8xtð0&n_ö› ÄJJ[”xV✠½Tb øô±Ãœ³^¡yˆò.Üv¥†)8©í¼O¾=Ìæ¢@�Ñc> E¡5h}æD»Ç=Tz2ÏY)j*¶/QÊ»áÈ÷¨²Z”)¶ îžàä)l.àÄ>pùáªnL¤+Æþ'œ|�Ÿâ ÷zf×+-ê_ÍL+°¶·²šWsÔ��ÉûÞD½G™‰ûŸþyëñ'ij{÷ʾ;¤cþTKÀ€!ÄîÍŽ[m îB´.ÇÕ­ã˜B„È÷ÑïÐ&3"dè�ùÍR[ýõÍ]( ï1Šô¼âe ËGÝÃ!pÛpÔ­F¤ñ¤>‘GÚöºC×t¨–V yá+„­À­Œ»pÒa§F†KgìGŠ)ÍVN”º®QãaÛ"N*“ä1.ü( ¾‡2B»¨Ò=çAíßÙ Ëž')•pMW3^Oô—©–lz©œçMé5¹cWV­Ý DæÁô#eÁÖÐXŸóÁF8ÀÀ ±hD€ÕC8£M—T¬æ¼ÉœËY<¿åÝ‘ð“¶]ZuhkW§-Ü ¼ÃG_—隬¤šn8ë½HÄš2›a:õ°ÕT Ð!Ú\ÈW´T¯I “–²!u3…GÐ,ýJgX=˜dëK¶ùx׃gжkÁl>‚ î€¤€³ÆM¤î«‚ˆV´EgÕ"h›^M}oF„À•bðÈ�ýÙüÆ#0ÞùLÖX>‚>ÚÀ•±{úûä“O>>íLwnê´Å¬*wûéúÑWõ(` Ô #'a#·ŠŠ/k 'HÌeÚjcwˆV°+×ér¾ö š`6÷qaa‡a‰nžnäý?xG¶×¸Ü•ø²èEÞ{0ªîì®ö¼ÚþU µÿs{EnïÁ«àì‡*Þ»›ÚÃôö°ð÷âóJ-â‡�Î;ÌyÆ/Õñå[—'Wu‚&иʑ|�¦ >läOSfü†²éÏ;¦ô'hj{ÇÇ~çâŸ6V–^oß÷'3`�Ð3 bwÍú“‡�°M!+>�­êת5„º–̰7ƒmkˆô1šÃ_ã>;vËíä&Ö¬Œ½*Ô΀ò¾q¼r)é.DÙ~rßlrR¯ªõŠ â“,îT·íPdu°I×XÛq“sA�âÁ;Àä‘=eN”/çÛ¥C­ ŽHÉ‘)ݶ±ZËI¿©Ýªh!ò¦°í¯%mHñ?Ø09Œ8ñœƒ,/èëÆÉN/ù‚÷ne¥ð8øq.f÷ l€8¨ÈÝ�­&¸þ 0©Oÿ8°Ÿ¥ …ÖXÛJ¼Àtoß„*´«ÃúðA;ý÷p Tʵ­wá¸t]æÍIÔn …tJcù]¯gР~‹âãýR$á\ùOÖ=`Á#é§S–@}<Ov%j ùg­-ÔÇ‚“ö`Z^uöÜëŒç#ÓV×ĺ÷„åž5nREië9òÕ} 3 õq´¹Ù!!cx�â"uÿ_öÞ´¹l½óüåvrÅ’�ÁM”Š¥êººm×-OßvÏt8¦_LÌ|‚‰ùªýz"ÆÑžî¶§Ü¾‹Ë¬º¢X’Ø@î'·~@\DJ”Ju{ìº'B 3Ož|öåÿðZE)ÑÛÒYáÁØ7AÏ]MÿÌþì‰ÚõS-ó°ÌGùì"šä™5S)Çœä~…ÚìX†“”{ÒnÐ^kݺœ¶riÌ͙ݫ­²]aq°œ\–¹BÅoèÍ2ÒÓeßÀP§|«™2gzš½ª¨ýÖÞ,9˜ 5KÆv­óL]|þÓDHø{8ÚL×ÞÇ;“»ÃÉBá(¾V’´mröïª?|°,¾Ú¹|c^^<œëÅz<äèqüÖ³¸?ÿ:üYå¢?iتåO§¶-¬®Oß"5:׫l¯†t“¯!hÖ†þæm ø3Ô>¦F¦saoëÝŽR†æÆK¸å ‰Í°¼ê%åëiÛ-|5º§¡lÍ“%bÏ’ýÜPÒ¼(ê:3­2å²ýèhªGAWc¡õ.™„­—ZYt«½NãèªVõ–«2 B’Ž¿PýÚgþš6wµçKÝ®ÏË×—Ù*Ÿfƒ©–”v{‘5ÿdx-uÕ®ëGqÝ}¹ ^SÅÊ¢ë4{Ib5qt±§xŽO(¯K¥Æ ìÍôc/6õæ¤,ΔÞE.%ÌŽ¹g„zAæh°Õê.𥒶*ú%)¨?®êöy`´xÔˆN!óó°yþeäîÐ30/Iã"ü¾v¦RÛ¯„’.@©ú(´¾J«£a îtUf‘/:šûXW(…H\ÎêA&.lUsç"[rÑ’ÅbW÷¿ë(ªQ8Ç•ÚqΓ<ýMšúNÜè—«"bѦ )ÈÅ:QéCQÉMŸð"ïaxD Å}‰Ó5}‹Fïæ‡gMñÒYýïѹ5+YŠÕ¨šÎ.ç—#½îfNå“Ç G ¹]˜ ¹°ªBÓjSùe;(‡¦'¯vµöáÒÁ§0º…h%Q˜jDtJ¹_ÉøËBî(ú³Óê8÷àðõ$jH&ôã0épViÇ™ú‹UÇ_ˆ>AôoÐÁ†ðM§ñml;õõ†-dÅPnš×œÀ. ¶›ßÊ3?Ô±ïÔO·ñߺKüÖó»o'ÿ¤ÞÒ¢Wx+ß–ÑëŽÈ6È÷â°ÿ¨X™ òûFÛÞLŸÀøFÀ± íëáUù†jÛw ½I½iÐP+¼Ê¨[ð¬±É†Íµèv‚ ¯RÖ,oá_»øI[™š/¥–S)ÿZJ-0ZñT!wýiûÀ3,µî{M¡,doT¹us0Åœ\Jç(±’'©ÌóÊS'Ÿí¨«øå~ÀcèPöÜtP„²®ÚVGD Ѥ*ƒÕeÛ’‡YÞ•¾v.å¯YžórÅ/0tºÆÒ)¸Ü±–ú¾š(ž©õys‰ ©[ÄÝòÇÄtº ÉÊ!jù…sLÑ–+EÓ^§Ž6¯ÕÕIq:ÈèÆ5hX•£ïE†[=ESã#]ƒê·át¯(PÚj3ˆ°šáËålah#ûÂWÁ:Ü‘3µ®fè ³tŒÎ0ª”&]¹2ßq‹exz( /µ,Ì(ì¼0‹Æ9¤ØÇT²ý¼kî ì¢M/ÝqcÃmŒ²!4ò‘5¦ÎϦ ‘7ÏÐ\òùÍæ5u¡Chȶw-¯– ¼:Ö$ò,›¬c‰Ç5ÇPXí¹o.k3 ƒï¿¿|ö‡UÝ:UÜÚÖ3«½Ô¸~‚v€ÿ m06ÍE£Fdeæ³ /áiœÇq»°éN÷@Q¼P­ ³Ñ +Åž’B� x¿¬})ÝÄ?/R­Óó Oä¹FUÓĈ2òË>²oþÖp ÓBV•‡Ô£kæÚN9¹Ê÷"õ÷[_^§gM¢)$tÞT$ºPݬjîªâÝ3íïßr“OÍuÃÞO/ù°€¼þóV G0$~»IÞNòT0cOß¶>Y¬,¾÷•ä·áYæw5¹IIG¯¯¶šÂ·pIm^Ud™ò®©¶kNKH.pÅ6HeB®8g[‚3¿CÌçêÈõ‚F²ü<0ÀþKÂVd÷³U£'f•×íž& k¶¯¬’ܰ…zŠÜ›’kæ<öZäb+6çE—ª.ºúõ~ù¸ EøR ¾²i ”ˆìU¹ü;;;lÄÍyœG]Ú*ÚSôŒz‡¹Mé²?£LP¢½—^Ç ŸØPŒYŒÈ!tsz —FJ‘ïXœIû3%-3û"ª0š…&¿©3.ç,%M¯E­%ËNÕ¶Ÿ{¯v¬9 C¤VP‘¿š$1ü¥ò(Jö_f~¶ fÐFކKr´°Å‡‰¶ÊªÈùoM“]Š'n³Óª3®AKλ¥× ™¥a,öLåY½èwD4ÐgN;Ú1ölÓS3Kfr[Yý UïŸ-!—•$’Ôad"%˜-@tCûè²–Û&—'øƒ#[£|½, Ö‘l²MjTµQ‹ @ÊËqý-U‹êoQ[»êQGÍ++Uò¿PZƒÞ©wŠÚÚYñ·í¢0Õ'•©-õo¥ò¼²Áõ(†¯›¯úµ°j±Ò¢0™e«(X»Ÿû%íUÕ®’2&ˆƒIq6öWOÝÒÑNä²›¬Ž’xhqf±LÎ:„Z“ÄT5ª‰šSôG7%® Í',pä0ôÆ]sS—æmë[…Žd œÙ, ‚5ˆL÷­ŠÒÛÂD;¢ ¶¾ËpÓrk^1äò!6~ý4í#‹£ÞJ7ápÍ{1ºÔ÷Ï|}xoËòÉç;z°?,)T"¹ÑEqKÚéÍqoò!sŽ$Û ‘£M§46Tð¦låέÎIGÊYo·ÑžFa/k‚bCô£>´jA(7d¨A¨ÏézEQÏЖqÞ4†! ³•iZᦉ†3£t2í²¥œéåWe~¯²P”BQö¥¹›~žÆ_fu_{edAÉãÝ æäEWÏZUîÚ¬†!i U`õ8ÿ‚×µG±Ó;¥8ŽY9Á´iDî‚Ú0]‡↶B·ðX°$š±'Î<G r“É”‚·D¯7¡D×@8,+zÏ/‘írd1Z�N«•É´XVÿ/ÊqÔG=¯öäÑLæŒ/>û·´Nqú´Íÿƒ*[âyíÄFJ;಩œØ‰o6M«˜wL»ÐK¥ÌÜZçYŠÖWö4½­Šô‹ªqe¥ÆrL'¯”Q¤?ö…§UêÔöyqÃÎ*ÐÞÈ…ñÚQ@^@Ò1“îaÓîÄ´ûÁ,BæŒ9,Ûµá'å~+óÍ^tÜ·GQÇ“|ÚžÚú/­öA»óÄîÔV˜Î—™SJÖÒ»«Nú½JÍïÈ};¹Ô CZƒ¤­Ÿ‰ Ù„àÐ’xÂÂy>wB9Ö(Çœq&̳Êx¶H¿–³–ñºÕ¦“ñB0RA¿,Únã„R})g¬B´‚l¸™•»¡Û3èÒFTÈ嶘¸!Ö¯Eeï Ë0Ý|gE`o3Ë;,ËuÙû¶NôjüçÖ€« y–_´kŠ«ø±ÅQÍ]Få;êhÞ!ð?£û_šz¸¦^Uù6¢Ê¯ç¸' ØÜJ?ä®drßÝ[°Wq)·0·*äÖÐáKŒM*TyTÁ,`[²ŸƒƒðÛ5VBŸJ%¥PŒ¿1mQ˜Šxºl>ëÉÆÌWARïÕ³]– ‰3³KšɽùŠ#ŸÎáH1-õõ×ÍÄYÔ¾´‚0š§TS£šiÌ3ï0ÖÏX¹™¥µ4¥Y6yF¼bVж &³˜w©mÔå´³?ÍFHi|ë8Ø=b<yãæg’Ì\;I\J¹CRIB¨ˆÀƒrˆ–4!ÅTUÆj+hL¾éã˜nÇ¥(±ç á5Fa“¬òÈSq›—¥¹Kã¢e£D6š@´pƒ5Í”5£^pPwözj06ƒ°ŽwÖV.•, '¿v £Ú)¼º§¬Ò‰½´'29å_«%xy˜d –¾{ᔘ9c ¼1,vH%x I‡¢·lU“ös±Ê½ ¼"۠Ή‚`ZÔÔóŽ­÷ìQ¬®Ðh<Bâ‹‹Óz±,ÏS=MEIë²”š=·|3õlYŠ$чILYai6ØÙ kæê-©‰ÏP_iù|OIžö_*‡ò·d=#…TP&~á ¤gE‹ÈkŒß°›½:0. Km”óo66þmûfm]ÐRÂüЧ8úåê;é-¡}õ/¶²öùµ6‚;lóâ½ÅG ,o%2šjÌ» ,ß!ðÿ”‹¾©^?"—ð®Få}ÇWß/?±þ{Ë'(Q¾ÙÞ¦B® "X³GK’PT×éûìús¯ã°+HßTâ!\~ÕMò<™GLȶCá¤A2Æx4/[»ó¢.üFú©‘!‚ß§’²XÀKøl‰ëàµÈM¿ñŒÓ̸p¬ï”Ý3›3« (€_Ö˜\rëÏ k ìFzS¤¸îÅf^r®PWŸ¶†tHd• =Ðr.%µ[²ÈC}8T. H7s5ÂM§¡³1ìD\Ë5…P8¾àà9¹4/è01ÃÜ ƒ–xzÑÓ¹Ö’gm[VõŒoyyÉ|Ca™s¤xì3öÒ xÅÔôóV'é¨Ý20+š”ª9ó4<ƒ•Ëò¤ :Ž–ººÖ±änQÖ‹i`Gñ <TÕôï³Þß 3”jŸ_iäß4@ÿ)ή•tÊàEYhc ,!êÌÉö”©ªY/÷âՑа9SG:C)ƒ§¶<pyµMoÙM2Y9eNþ‘ÎŒú±ý²­y¥†:k ]ÙÛ­@¹ŒÕó°XD%V"ö­NËJ¥ÀJãÒMRÝ*ì'Õ‹R^CÞ cXB:¿Ö°‹jÚœR;Sôš 1Ù8?KdÀ#|“‹ðMæ“— ozòN~T ¿†]ú0ž•ðü¦ßð±+ºeÛÂìÂ]?SÝð)SÕ»‹!~d›þ'ͬ   ¼L%¸î%l*äV›êØ!HÚoF5ÜÐ.k7Y5ooï¿)ðLD‡Ž‘=¯Zò\ÆÔ!MM0µr;ÂÂÎØyÁ´@]Ä>¨>ÑÄ}ºVÛZàirלš²‰.“¸6³C¼)e°ÙÌwg<†1QÿUU¯‘Í!ÚŠjEþЉ +šèòJl‚¾ «ìŒî+#«:Ñ& N¨1ÀĈ’¡›” ¨Aá+0÷ ²ö©¦ÚžQƒÏ_+=‡©\!Î)J–%v#<T«gµJÖ…#äè͵óÀʇE‰™JŒ™ 3÷óU½\E'0”ÃØíÅÊPˆE®±¬¨Í6e÷‡¦_ZÝþ¡/dM"mõ ™µ…aï}¿lŸ ,™G¿u[ê¡;™í¦‰Ò)§Âl–VX™¬j©Êg8(¥»†‚4@ ;ÚÐñc¹£00ã^SúEjhcÑO—±Ò©š^JFŽå¯Q+Õ£TjMa©5Œ+Û<-ë@©!&[:v©Y†lü<,µ8—ó"ïÈ?ñ¨™³`4E*à@jG¯=/ÏÒe~’iÔ_¢jô&¢½ÜIÄt!ÍB¥:…ÿã5»ðå6(zË(¿«œðvÙô#yP~VþHܶ?é†O½š»èǾìOûv»`Ãù§ØØuSÈ‘^²é ßæ›sÌ[ I:tQçë>¸+í²FmÞï,ÇÄ1Æð©ëPÆ „€äü;Ƥ ><æ3…þ;ÿTs~‰þçð„'ý'eÛÐ3gðÚó_æOˆöšqœ ÆÄê|“Y’�v@‡¤pØnì}pJ­œCU`Kœá�¢7fÅdE€!0œ«h@v 0w~ø 14:Ä‚,¯¿³ðè—…ù¿EÐTÅÊ¢ZÈ=’dÛ'aaFF å¯Ü„ RÁK¹ÉtB 2΢*ôÛ!šÂÐ@æ!yecý é¦ÐëoRfބÃÎE×èšžÕ=¡¯êN½±,u¥©gzA©ôdºÂ©‰ùбbzß¡"Õ}µeWz_ ¬,‹2ÔÚe+žd\,•Ð@YÉeM£õÚUåµ¹(^Ïõ£dŒÌ»ºÚÇåå Á`z'VRŲ¡èX CÎD´›õº8i‹r’,¨DžŠ¬UfËÀZföi×i UÍT“T[ˆ°ÄÈè.]¯ òxY@úÌáª_˜]ÍÓ;ÌÛ²RbL°ÁeÓ›s?kklq>•iõ“Yñµà]¬ŸøÖdÿ)¦ôc“?ŸžÎ×ÍžOµ1IBçÛ4¶Ò$.aÔ™5õPC*È€aƒô¡g³rnMÒ¾þh›Š¦€j�5ÄáZ‹taZð¢!€�ǧû9…GÔÿ y»FÛ8òŠ]S •½Š–U+•qñºXUm¤+v&ÓòHÂVŹOÑãö‰UÊ¥E³v€4RX¬-Èiø¨Å^ÉüRœ9G¤Ch9„MK¦Ž[˜Þqž+'M ¥.ô±ã+IšË’]yt Ž÷UÝÔ’0’ßGÝ¢‚å3F\*ü]ÃÌ@ NŸ`oš �� �IDATè»/m•TPIæ 7ÿUBÞð¼¶ÓP!MÖÙÑgƒ-'D- ó„TÃÞCqž4æþêÈÌìñøE¸YN²î/ ëÉ‘•YV mÒØ‹—˜^Ùn[ý$¦<‡L`HÏ¥úKÌ‹e/ƒX­”NǵSøÕÊKPr . LFõÉ.,·˜ ˆ¥¢]çzó8¤lð²ÍBaD¹w%cÂÌçK•/f Ì,ÛJ+kƒóèðÜEZU'”f£¡‰×a]#o[`ÉÌÆÛÿ;ñd(Ç(ø­‘•ú|á:çÅŠ]° ‚È;nSbw œMC¸E©[Û k>pd1Ì~b‡þþÿÖë´ß§¶‰ÅO<÷íŸÑz^Õ½AÆ{Ê >NŸ?XЧ·7ÖùÑs׈‘qô;…;˜1YJÑ…TŽÓ B:]P¹T¼m|Õl&5ˆÀ‹hV QlÚ&Žt{¤ÖŠoA2 0æ_Ã.tÁ¤] „E½Ru-":˜–¼LêU—™¬J÷W89Ùïv.è‡ÏF 7ü…$WÈ †`¯æ—OYŒx=eñöŠ_^®)]«q—$¯×Gº£Ð39vìÓ<ʦ˨Ѭüqž­'žÖ_Qz ‘’W uŒ Ç¡ÛZYŽjˆF‰\Ï5ê8k>_¼²L¯¥ªþ¯£Õ°\<ׄZv avåëÍäŒN.Ûä¾¹3û˜ãrú›°¡·cÆ»NZäy7‚…´©ì®QhZ_mÓtƒ…W䎃²ÓÉloÕÈz.ç+ïåTkæGžý™W´Íj¹8<}™Îf~âƒ$èÑQi.ˆ!¥FÏÝ}Ù@Áq¾)&³‰/J˜Àh*…µ™”ËàL öóQŽ4Á@(ÈÕ"@ú$ÁUøtÂz|w‹ßdä€Wg†d™Q.Q@E6$”U˜9V!EQÊІ¸X3£@ùë¹êHôàÈéÔVg&‚n‰Ÿ£Ä±Œ+‰¢o{ü›_õNMA€ŽQßøQüpF‰Á¹bÀ©oR€oÈ+wˆæw—J®•[ç-Œç?’)ü³Ñ Õ{åîœmñ) ‰3$ù˜ ÄuÅà=�à]aÈ;¸Ä€Ó)€_“ÌÉ·ùð<¡„l¨³P®nýzK4®G­›$ø]Ìw+vFLmä6ž;ì‚Gah/Vëq@¾.z Q/èy”ý¿9sŸ•­¦s1Ù[ʢ̓nÉÎ À´Q “W‡Æh§ä8¥â»ŠALY£Æ¨16´ØíR<c¼‹¡ÐþTŒJìåZ'J˜êH¬^µë'f½JJo˜«JÁÊ£EržAŒ°ù’Ç}…zGZ­ªyâé]éEnש3ó{¦÷g´ŸåÚ×cWž!K¥­Ùª­ o÷yÕýÒÓ¢å!á.yD[úª±ÛŽWMŒž€Óä¾ÍguHGªšZKƒRÏgj•Õn¶öµÛÄ2ÌVËbe uâÙÂîwæZ—Nk!ÔQqˆ¦uâf×J::¶ö9–¯f¯™#+ ­ƒ1;SÀX!+°ÁÖ¨MÄ›1'YÊÙš¶mÚ©YU´`o%סd·¢Upÿ‹,w²Éïe¶`A³ž‘Q�¨B¬DM,)A@ Œ1>Î~©Õ¥—r^Ó.–]Ýoðk-HŒ˜bD’€fSÅ`@há{Ep=C°ÊøzËû˜÷}kí\¤7ì³æJ1|¼ßÜ-@Þ Š@ðá ÉŸŸ!úyÑÿ?É=”¾û«>ºa×¼¥ Ñtõ\õ]Øîï]*Ò`X ëé]—­7ìd Œ >Ä%rå:_”<§¾ù¡Á|Í£”HÝŸ²ÈY䳿×åë?1LpOp¡øKä¿9)ö IÅïñwùB¢ÄÔP>#ïâA]XZKG_R•k>^Út<½–aÂÔ§·‹è(®*èH=n´#Š!¹,#."2PÀF¦œìEÑ­ c±ƒ±˜;#éúARè¦c$E¦NÆÉÒÞk.kKSÕ¦•;ÝÝEÑÕMÕA(Jq¾×’f•;îgMn¨¾Ú}òÚ~U4ÿUõþ§sp¨÷_ø¢PFn{µôeV;ÙÔ¾@·1âRß­°ÜaÙår‘&jè«Õq×äøðÈP¬BÍÎËä‡v‘Kõ/Z]§ííÙM]Öó"¼¬93¸Ø_¦¥oXˆb©÷Ϲɼ/ƒ @ÙA¯Ù ,P÷å2åbIqE¥ùŠæ7öÙúÍÚ`A t(<&ó.òæ”#Œí\Ü-)úHCörìD¦ùì›7IÖ5q˜ Õ°‚bÉnJí~Is„ÝЛ$-§R; &ç A4u§6:IôB¬ I�TÓ­ÕlføúM zÝú)×;±(”Û­Bwé•÷sñD|ðÆýëx+ÄÎ~ä5õqŠá½Âý5ÇÍæÆ‡ŸìòÝÆ‹u—npÀ»1šêÆs% Üzëö6[¼+_žßÞöµž† *¡ » oF—^Æv‡N‰Î-ËŸ%U­¥˜Þs8„9Ù\˜°XØ, H¡‘¡QF+e`6ê˜ÞcÅðšðÿ"ð°tê Õ¥—¥Z—"Ÿ‘¾DŒè/Pz”Ì9·±Wz+>Œ— Â]ˆšêˆ²Æ^æ‡A¥ÓÌÖï3€`¾Òl™¹s «ÇÌ#}íà;»þ¸¤±õ<Ž|ž—/¯;q£Lô@´•Ô=¨ð²ªêǹ^Æ,7L×R»è½žzŸ]¨ê2o¡}þ…þè@¡%']­8Wõ9Õ‰¦ûô§Æû}ã¯2M7YÕdM˜êV;v1ØËÜä‰>mVS{–eÚg¯Ó9Å.Âv{a®;Ÿ#‰`Ä/G /Yì ÁºPÊÂ-Ù}„«B‡°$o‘-É6ﺣÖ-ÍI9Ìf®Ð†Ìãï;g† Gð X’4)6thÇBð…Ásé2ò6´§½·êÖ › i€ Z‚ +lŸç±LÒç­B**zÀ?ÄÂr„¢É+ q ß¼!¹[qÿÙUaÅc5ïfüøáÒI~¨àúÀ¨²ù~Lnøñ=#ò¶9_}äè×ÖÜù¾[ißý\¢¹EIëö!ñ¡^ôuÔ_G‚¡DΠxcàø×UN²9’ 5÷.R›=Ÿ¾c”YAÞ䇃#õr˜®½–èrêÖY¡EѤŠÖ¸…i§ŠWJ%]QGì$/§ó4ívâ^cŠõ˜D-•ý——\V2·Æ–‰ÞÊr§î½Ö.h ÔýÌ„VÀ:ê@ R6ºS ‹i ù9ŠA:…à2ÅŠi´€Ü@=.&£Â<IÄ×tL¢οÉ˪»?«Å_­ÒËYT6i`ÉžZÚc½í*ÕÀ¨Ò°J(ºËü /<ÅÉ#Ý*Š>¦r²ªè(ÁAhª¸¨d©BuR¤Ù êC%kÓ·Èí:Ñrö'¶¹;G;Õ/ö¬„n¤.Ó´.‚ÄìèóQ) '3…‹æÈÅ{m¹ÆBƒX§>À4ˆ¢„x|ŒI!R-«L˜½6ÿÎâ³¢k®¬ivѶÀ’´IV~ŒWQï Úæª›Kï¬2åKÍL?w´q^ßÖø] ¬«¹èmÈzkU»-Z5JÂp /‘íØ7iå¿þå™5,³\κ¨FÅ[H¨²zËÊþ üêǦ’ƒü1Òéý‚K}è]ήå®ïÏR<`|俼˜Ò§!õc~é“‘æïy®»(©øP‚½…ú»É¹å7­%¢)®ß÷9H I† çBñŽ Së²Í5ˆ`xEvRO‡E½¿ÄiAÃN!Dæyue:ñ®oÓÊZÝÄÍyP.8{¾NðÆ³†®Çþ3Œ†yZZ6Æü.ª?Ÿ«O¼z` C=Ç¡t1á·QO ¹d�üXÏ;²qÛ¬L´ Õóõγu R9“M‰Îê9“ÏÉò|ªE’<ûÍêãÕ‚¥’ñý®s©ï¼¼4¾žÉd–ÔMù·,þ=Ëô¿µ>ˆ O’ ì¯MD\0(Pky¤Šq­%eÚ¤ÇYaÒÏ‘*õŠWc%ušK¥jD<Shu­EãÏs¢¬þa.½å²•I9-shÐZ• ²ár!‹f{-’aN&ˆlL•(y¶zq`[¦°Z“FørœŸ4 çryxX¨­®R~¦-0ʺy.Ùí‘5zŒ1aev²]r^ɸI1´×ìxÎ*;\¶Q*cš=’`Òi(B©d ƒ†Èé:h̉ßÔŽ©PçÏz¬KÏ~Tä3*ð9nstr µð |•a~L½þ)ZGßaÛ/ÞQŸúѱø€;ï¿fõþ«üÌjXµÊÚ§œ?°PúV»yë*›Ø¯üHvGCéÛº§iîRQ‹ß/nÇd75ýWÁ¬sh]é[e“ÈD,d~Mƒ(kik0®M5)º³E©ës͈›\/gx3§o 6 ”"ôÙàŸè+if‹j°Ì´¦†ngº §&=¨”®UŠªhákxN$éCfó9ÿÊAÝ#Èù~+‰jÁÂ§Š©$Ö›ç ÁÆžmð&˜«Óÿ» ¿^×Ý'gi_÷ƒÞ8ˆLÒ%Õà·¼6(.^qìQˆ�ñ"Ê13èª"sÿJˆ$Ô9NL‚=6§§FÐ8¯Ði—T‰Êì{e9[³ è]Ž+ùr$õˆž/$Øm¬H( ÙÀ²¦»€¸ @G,[ÒPÇϵÕqÛ¹Ó±Ô¬…‹f!¹ü¼TOÌöË*”vˆg4-.ýCšcš’&$²”3Ó 4b‹y�˜®:ƒFÝßɳW…"ÕÆ]5Â4VÝa{Oš5Þœ,&M9]QÔ[:Ü“‘ĉv‚’N5ͯÅíSX®î¾“§Ði¨åý3wË1Ý~¢&†û&Eß÷ùC|ÂõóÒ J‹fõঘ”wùþÑ¡ñú#Vý‘³$Þô¼ Uvc0Ië.¾j@};[r%^·?ªÀa3�¾¥A‹NÛ :õ~>#LþCÈ¿‡6‡—¥=âhŽó’)8°s\Ô{ÌkÊ -¢ôWA‹"‘²Á�¿Õ¤±šÇdÔ •ÀÉÐYs@¬m¤×lû¦�WâIl…:À„|«>Ãá‘”Cñö9kå±8•Õ†o‡0ÊV¢úƲºFI{‚Õ‰AÑ`–IÍø÷´³v']­©Å±ŒÍ…RÈv7Ö1«ÉÄ-N*‹LC«† ûT´Õþ|œ¯VòûóÒ0ž¯´üûROW6h(%”„/DS5ÛI®ÁšPÔJ<ZõžYAÝ´SµVûÍ+E±W™:ô ¿À9ÄŽ[îÅò¬Cj"0´ý]ÌœÕÔ€îaqÙL;2Ý}Í.]dW«\w§ê…n&Qд_ô„£ˆÄŒœÅ"ØÝ‘¥ƒ()MòœÉòšbàˆó WyUg)é'Å6bSB‚³Ý«ðˆ¸6xG­Ö  Û/ëˆ=ä™ÜzÓvsÃ{J2Ãî¦Ë"¶Áé·³ ×?k‹Jû”H9Ò ê'¦Ò-Y¿Û‘{3ä.î­’YçÖ´…O›R>ئxdSÙ Ì 8ùµìDüù*·“‚·Xt³º Áë«Ýf[%¡@Z‘„¢ÉûËq³PÄ_Cú„c#¬ž‚h Ð|¬#2HWL_áØÌºË2�Èáb“o­ÎÅM¤a8 vϱ=ê\g¼Î|3ƒ'ÐB h¯ÈMêSTà)äð;¯Úδh¶ð97  Ü$lFo¼MiØ‹ÚDɉXH$vëÔÇó}h •µËàØ¶M'?{i,ñJÄê?AÊ ²=¨ˆ{2¿œÓékݲã‹ÒS/yø*^½Ö¨5¬¼L ÀTÉj¨dÄG2€’r&G]>“²Ý6rsg’©I« ûÖªiHÇ~¡Pg–ûï²/p:…Þ.–ºw¾:_žú9…߉ێY㦨ižªÝö£Â覷2�ÑOª¾·#úéªwig»ìí÷æžYͬԯåbȘà’:$µ1´·è°~;C®Ç8Ûà€ C¸„ˆ ¾Ã ¹*PðUyÁoË;ÊÐ…®•„Ô!È{äï}LñÁ†rû²¿½§\þ··úÝ>CÖ0zŸzp·i„ÿºáŸF÷GÙãŸrj›„:ï,%–׋‹’mþÃL˜æ=íâþNŽ{Wv°ãê:NIR¾…/Ö\ç+[°{ÄxH*ogó PnnôZÁßFþ¦rØ_ÃNþcÃSÒS.ñÚMdÙä9\BŸRÞÔBË£¼(r~O_`Ù”]„C«Þq5 ? $­ºø‰7ïTß(¯Eþ­™z9y€ä´M2QGR®l Œ†"€|=UO”ŸÃ�~çP@l#À5Gy!׳©ËÊXî„þ®ɹ<Ë}œ+O ª\'ŸÑ*èLxœòŠ8Lööd´û=qÿR50z(Ö@ëDá¢aY"Jc€ë^š+­²ÊÝÁÛÁ툎) e\5ž4ó¸ÓP@sy’Ô‡ëqÙiçM³Œm¦fïÝü¢Jð}ÇQv„jïé¬Ã#Wwž$šRˆ »—JÒöÊN«î»¦èô‹£¼WNCoâbפpl±i)í5“¤×¹î›>y¹ÃT£ Ñ·UÔɽµW/;ÞÚàå]­Å ²¼‚Î~7„¥| '¾»Nµx(¯ÝŽ7>ÀoˆÿˆöŸ)F÷9¸ÿÖÚøütT|Ðæ7 ó廳&-H7ª.ºW¬‘„Ÿßy#å@¥6ˆÄñ&RV½uÍí¿;c¸n¡2¡w]Ço)œ»Éü9x[äâñ.ÁŒÓ²„‹3tG¸ ¢³«ûO@¹Õæ}D±>á3p|œ–…Öud\-çu…×#ïüU¢>¥\ùÙEÉh‘œ’lÕ|÷wd‚ZZå:Aâ°cÓ^I^KXA ”õäÈ£k&y T­Ç%­ ¡HÁ Lw‘:;´l²Sô“X;ŒÝ}Ú= 0Tv|R˜î·c­=·æ½0qh ê�u¥‹ÇJË5„‘ɬc"›ü†u¢Ä¸ ¬F8Éaéi¨“phYA,~+í ±Wf_&Q®–8Ó‘±+ ÿ04f16µ½ßnhìÓ»_w´¼W;=·ëx}SØ-ÃÅnv2Ýë<¶=±¬œ±ê‰¦Ù/=_ÑR©œ¹Å&5EÆYŠ#mÐÞew@ð™Ú`Ž)Þnßqä6zs½Âucƒë›ÆšáCs¼÷g=ˆn\êŠ/~é,y3•ñ»v`òðù ÿLÖGת~Šè¿O`%˜4w—åÔ?róò=æCu6ð-­ã€fáØ-hÄéw¥¶úùás4y-,ÆMDâõßÚÝ»�u% ÎV"¨ÉK·5‹sÒ–Tʺ¨Ñòé ©¤µD[ Aµ$©y€n–ˆíltA@@âÕqj'ßMUè«ìºÕ™VùÓÌž?Ü ÞŒá[Ÿ•–B„1Á¬¶ÛLÁd›ϯÕÒˆøú¬¶?ÏY ÷Aîã.j›¨K´ a´ÈÛÈæZ€ŽC|È¿‰W]§Ûu sÚd ë²M¼£Kéu(z„>Kwç¸þfg#pQ“㘣ö<)‰”¹Cõ…|är 0’”KA0>» «:{‡¥§šv쮡¶4½×kçjÑnlSöZÞnÛöÐ,SQí¨«VõX¯>Sc½s‘á,x±,zE•û¥ˆËL²Ÿa/øý‹¢M³ªÞcxgã\²³ùwôu&`_é”úó˸*™{§Qw#ð{ÇŠn\ù“X¢âm¼Øæ¨ Õ¡ú:¿á§3Ò¶mŸÕ;ýÆ—bk™ÊO±yñžXçÛŽ|ˆÖI ²HÜðzØë~íh8$8TòZ ¦7ŽùSp¶cîJÒ�³ *öÕgÜl¿ßq)àÅÀp d>txm²›³' ­‘.ü„ ÉÑ&2‡¸0Í…ôD#°‡T’0PÊ ODŠN÷ sf/5ÒdoÚ�·›É·1´ì5çp±ÙóvfŽXàCv²> Ú¦Pò#©ƒ« —°¶ƒ¸cø'È;à@URms;Òe†žœ–Îb½‹dÙŠWýýÜÉv Í›6QÞµ:dÝ:öRŠœæ3æ‚´<ƹÉ:Àò90$]Ôë‚…‚v-®€^}ö™jÚžH=SV`L%_) ¥ûç=»Wµ4¿cìY¥‹²q<Ùwµ=Åi•çy*­ÔÒtOS÷M±³«Z‰–ãr<ñ:¾Ôý¥)ÝÆ¤5¡‚ÿÌ�¼æÚ¼ý; oŽŸ×CÆò]´±q E±m˜¸µ’Èý¨òSù)ÃmqÑþ4i¿Ê÷kü¬rÑòýåϨpU )î'—ú“h¬›Vo?ê}¹“[Þôó2~ vŒ“vZ­Öò|cL¼]igÃçÐîÉÔû8‚&aùÖ9Kîw\6’ãæÁöÙt!Ä’UÀ¬Ó%;‹ô¸áÎÑÆeåW »p�Dµš6F@gˆ+œâŒfµó¬ÏÁxuR¶˜æëTÇÛ¯à‹mVüù6~½Y­ãHbAo'6#á#¥*ó¿f¶ä¼M08ÊÄXAClB$0T–¿' ÐÀö rJ?‡sdÍX¥6‹8Ë|½ej(_´¨úEZòu%IW¤Ú#<‡0H¾N6z±1°÷¤gH÷Eevs_´úMYüY¤:­Çvß/µc]¨éy-O[P‹ £»wFÇ4Ó¦q•Ý*sºýîNW³êWq0-3M­U¥T~RfK ©f²êVÅK{–õã¶«½èÜmz>IªíØYDن˻¤óŠ:ܾ{0½›ÀüÊ ×ùݧˆíˆ€{OíFó0Ésý£ëŠÁþ¨¡bZ®Úÿ™ë>ÉHµæC‘nÍÆ 1Ýn„¾ñ…ú6‡ÝO›™w]ö-'7—®ú[®t¨!.f|ÕA±þþ:ß°¼ªàž‘D$ÿ‰»Ú´ßÕÂê½ò†©h),ª�µä×ìÔ[G­ 3(š¸I%ì®k-ü¬kaþ,‰F‘C½u'7£×?âꀶ÷m­'IH·l+·<&¶g 7uÄT¢ÅQÍ0Ne¦IÚЃ×PIâíXù5x­éÃ_¸¯5-aUø˜C,¨ƒ dïMáéü–Õé-/ÿÏøË§ñKÕNO¼dR'êù¨!7Ø—ôdFXmû¼PÀÀ¢ƒéˆ™%²äsÔÁ/…é:®åyаJu¯Ðu¥Û2È Â óÞ³ŒF?ÐšŽ†çµMÅ·KѬ¢^Æñ( ¾K'­Õôóe˪Da›ao®—•ÕšáÌ—vº2XYʱ?p=mªÅéH0•Œ ¤z‡h Ôòš [njòª–˜Å'¿7ŠðÐâ¥Û›tîDRxvùIâá7~ãx?¼ùÏX7üé‡w^?å({xß;>|‹ˆ«Û¯°…î¿EûÚdÄm–û+ð®ÁÔ<;w%­ÍF¹»Bïšñ7 Ýcè˜ëüº5,~8[Ú7ºn¬×·Þ”\GoR€9´a.Š]ÉD9Á ÈüÏ>Ö3”“ ºÞ#ý+Æ-2,ÅA=Ú4“_{_à?%.¸üǵm§ÂLXˆkã—°Åtµi5ô¤Ì€äW¹q7”U¸   ØyŒÝÒ ƒÜQ ±Àƒæ —�—âk4tN½@™¬þCq°(ƒLK{C·©§TðZÑ6 «Æ¢PžQ)«b\6§h‡F¹("À?Ä©;Ý:寧ÛgàêfSFéñØtçÕ“¾y‘¥å©žéKSv+»çœîÀR 5§ZÅI:o'?˜á¬IÆÑò©.;U¿Y™e“¯º…²×Ï|gO«(WÝÚ|l ¡hEß`Éhë Α­AÅ+(ßP‹E¾TwXr¿‹> Û>pöç5ʵ-}8ÄNò 4Ù=NæÏÈßVL|À(ýg¬>ì¸uèÞš x¯¿v%ȲO2–çQ)M¤Gï@ˆœÜŽÉŠ5h?<Ã’íR6t£0ë|x¹‰QÛBYy¿&[?ò›ÄlpýÜ”·z§ah"ý7 ÊÖ`Ä[?ìŒ-à+cx$0Ö±¶YE!``‚.Ø=¢i¡>!§4qE.1®$VYRÈx튛 „h²Wºdm¦#Àa‘`}Žmðdýap±y*}ƒj~-³ê|åw…6^©k¥$ˆåFñÔ‡íÁ/VÕ#:ZºW,ÍrfÏÊb”´25&‰—‹S%Z…0Q8õšy?ÿJË-µ:Ž[ŽÚÍEôˆ›ñ¯Š•9m·P Ï®!%I3-ÑÓ…ÑD¥™MÝËqùü|ècu?³ê&Ž”ÀXý¾)eûÇjì¼ÒФ)§ŠúÒµ/ûeúuVjwÇôÒ&wE¬i(ZÚÜ9ˆ–Y,­(©ê2©Ò²¨&óÕi'GÝ”'ÉV`mfÞ¡!+†ÅuŠr0lQdGÔCÖØ-ojx‡-õŒ#ѼÇüú‘¹‡?BÙäGå<ô7ÄÀÌš¤ÿüÃ&š‡wù¶©\=DÉOD÷­’tØ|À$LYçl“}HmÒT9ÔP¼#¢� …:¢œS}wÃiÉ+!®®ç¾yä“뼤¬Éwí!¿Þ ˜lÚ[ï •¾#ÂvíœKÜ ÐQkneìÿÆ~ÎÞ¯Eq›‹u}Æ‚êÂȬ¢ò©†ˆ+Ìϰês¹Ì·ÙŽRn,­0PL‰µOÞu;²EÞ¡ñPÁ]ßN ê e'(L;kí¿ä«-,†H‰ksð+·ËŸ�� �IDATu´*Û¨F°ã?õõ:ìj/²ïåœ×gÉøÒ2‹” „Ó$ôC"—Äâ±Ú6ÝÍúŒÈBu(õì¥ÖU›‹*)ÑJûV[­Üò¥qòRü}5§÷¥Ÿ–q—æ)êidh“âûÙ¢L”R+ˆW†5íY&ê®í¶­ý°%T! ª8œW)õ¤«Ž¬ÖR3?m›I'ÿp^TÃúïž/î°–2ð¶!PYÜ4ž‹äæ‹.>Àé·ïýú[À”Ÿ@n| Áý>¹lÜ8~ý–ÖøÊ7<\ý~ØqÇ C=ˆPå¨@ÿîYç×ê�gG7¿Û˜½$ ›Ö6¯B.‘C¬¸««S´9ê„ÃWëÏUp!¼3‘{ä0ÔY›~È›Hy¿ê½3Â&nŒÄª!L!WÒÖÚy¸ßã‚–›Ù~ï…1¡.9‡‚Qi>£È1ä6láCGÁ¶òçÙÚnm­½)A-ס­% >FMq Uÿ3#ðŠ·l±¼Ñ*(‰gå·¦ã“k×è$½B¯¦öŒË†•ËÀœwÍ®£Yª¦¬¢êr¬Ìÿ¡Yæœæùq‡½)ØÔ)õ]ÃtÉ-„…n£iV¶Èô2UklÉ«¨»PÝRiyU…}»pâÌ`¬M—Qš…ædK¨ò”C¹2,~—)"µ¡*m'°„Ú3Z¦â£ì•´b%%¸,•©©$™{õ¤”fb*ŠnÔ³~±ZŒ¾ýNÞ;×¶ÜLøp3è¦zúi-î¾È§÷>uvZ|èü¸ŸaLéÇ›ÁÆ*½g=¤–®ä6BËU Á¾Gm|È9È;ÈP¾Ù¿0öVe¼ÉÀ; 7¿¸ž²I·va-œ‘0”W†á»j–ˆòãî­4»üïíÛr#×¹ßCãD‚�É¡fF´Liv$;¶÷…S¹É är‘gɳä"÷¹ÌìTíÚµU±¥moÙž1%a8I€�Ñ@¯>墻F£Ïh€äÌú— 5»Öá[ßi}ëûhÐÝHS±šÀYõS:1¼×Žª4Zôg­K³W±æjµa¶ôÑ„wðÎýè ßV^ ­# Åè *Ç`ù3ê°…¸8•`àÖýÎß×HåTÙ¯bþÄlÔ¸kÒ¯[ê°+è‚.¼«æ1ãKãÞâgó Ú}çÃÞ•^yë(úßuóí¿8üÙ•^G´º´ôÊW“Ï~úžÎ¿£hN·aî+æE §Þh¼d.æ÷xOÿ®;=ûpTÕ¬;1³ïWÓgCóùgÕçøÆº½ièÀç‚Ïfð L£69Wßýóø/ýzïÐ8jˆÊ›šú¥Z7š¶éÕÀæýtôWãê;£µß¬WlåJ˜Ã+­f·žÙ­ùu­õ~t¶zæ¹ÂXrâúCKŸ¼¡ÄCózŽõR”ä9/.#?ñ³èô‘š'£À²Å"îê]¹Ã E zÉæN ¢¹šìq8í íßmsüj"ï=ia.Ý^±5Fšp -Ä ¢êƒŠ*Ú£@@|ú  ?dèfmøÜÛrBcpƒ˜3D«CçˆûÌçzk`]˜{Ç×{·sý<0Èš(àN6޹=äà|…úPÚÌÝE8…Á§}âÞwËnÁs*õcÄÅ*©¼†/Qè~Éå‹>Ã6S§)šæ´¨5TÓ9åC›¿íQýkpó×ê©MlCÐà �ßtõòDéÚÇV³ýÿš(/'ØFó~ÿÕ¸w°_=€Ÿ: [ÙŸV£©üýE›:s[W`á/ Z×/§½/Þ4ñ·ß½U™öíΗŒ{\iûr~>»§9iXÃ/¿kÛâkm¸×è;µË™:ŽjëæŸ4M¨zÏROuÇŠøö~ÌD¼üùíWoi¯yŠ…7r:Y\bKA 5Ò+Ð ÆZ—{Òj’é“òî|ë9õâÎ?ò]ʆ¼È’'#à1wB7vœí£pÖ©¥–‘€ëFÓÚþ¿ï¡½~¹)XA(<?s‹×¨fd%,íìiË4VŽ ¿wsOpYã{h#l˜ Îù©Ac„2B±F/9yNE™\1sûAEÇ|ï¡wLã†÷NUiX'kȯÁâ¬S¯ØÆå=Ú½;:Ã{ÄÈ• ]hPïRël…©oÅíÓÐøÜR ªpU½yqÓªOª}¬ù«u */qÜÒzzßT‹Ýe®Ã¬V=i7†3íʘô᪲LáׇV·ûêåƸiéUZ‚éU›¶Y­ìUǦ©)–P›Ûœjœ_Âÿ¦×»â««ö;Ž l›·]С¶×»Ù;y¯ÖÆÚô¸ß¾6œošÎó ÖD›ß^hð§ÊÁ¸?݉½¿ñþ†~gØ®M÷{•½¶}ª\Ñ8ÞÓfh'5,³©™mêT¯™.î¼XÝáꉑOù“ˆYô©ÒŠÇµw)iÇB’¨‡ž]—ÇèÏ®ÔÙ\óOÀ6=çœØQ—Õ¥lÈ‹aŸ 5÷zr03£`ØAwFôÛ€±|¹žC…Jaôf°�ÕäwnÒÓ§v�Ï—®Á|.rcï}~GP§OÔ9gˆS†#ö®™´¨M»áP¸r£QG—N¥‡Òz;®ÂÌ8´èü…ŠFë#Ëýu#ÈTf°OÅîÕÔ¦ú"ˆK…#NUõåÍi•Á”᜙6«M8G§1©ÜTæwzgŽ2ƒ¯ùðŠ»â¢ÆUµftºjÓÞ‰©‚PZ°ÿ æM¦2íÔΪUí¾v4Õ@©Ñ­N+•Ë[æö­ZÕ:3kvo̹B…ÃÝ#,h^2×èüi»N¿¯ÜïÛµ©ýbn g:üÌnªµF¥©Ÿ·Þé5®,µÚ©L™3åþ>V¿6Å×mÑ<}ÝûB4÷Zöçuó¹mÍÌÚõ}CÜÚ U.fü“ 7ÉÊàÓ°¢ wìQ¯MDšn¢Â¢H}¶ð—ªuÚF F¿§;é¡_Ì’OÁ—+Ö.Ø”ÈçÄž~ÌvƒG7;ÉR’™Õ΢·-2Ä3÷éô½kSÅ…Gºêø*ŒEßÜlÏ8 Kba-ÔáZÀÀLèÉÀÒ¹i,†ÓôÕ+úyfªíÅL~cPÝ ÿÚpí›)îNh©Ìç5ë¹?¡ù_ Áø‚ÖL½6ÍY“ç6ÍKš¿âªŸaœ£ukõ{C|æ»ÎWUÞªúa_¿µøá–¡Y…ç°6?Z^€æè­i8BEwïAm8lÀ¢]¥5Å8bÜEX]üu¬Y󹨷™!&. T_`0«Òº;úøö ³SîZ&­k”jÍpLL:ã¡£5m}ÊKÓêöjÂa¦w rˆuÀ‡JMÌLf ší?™úW×WŠb÷'׊fµ:ÖLqfÚ•3güGtæˆæÄFW1•é©!lktÇÅð^§þKKi?Ÿr ,Ä=—óþÚðµ†Ý_)í—cã„ô‰ S{q¢p�_S0âI\RoÇüŠë uÏ'š6NµL$\9Ê´S¶ŠN Ik‹`ðX†“G$ T³JF™®Æ0µ3_è/.ÆÜHý:gmÎÆœg½6Yõ_Ž4+þeæiZÜã ¾çf¹"Ý}*“Ex«¶Z°{=ÌìÂ?ÏPi‰ EÕ5¯Ð©ðïT«ôfˆo-¬}´>Üû‚Øj‚gGL°ܘL¾à~:«½dréë­Q >gƒ›žð\=•Aî1Gœ#à%¨4>âXÜ8ü´5†‡Œk4tœ)ú˜ù“«G í@¢æÙý{-¦s*Ý¢ý3Ú¯øªJmŽnX#‡½}ª‚š3­ÜM÷Æ&3›Iý˜Ÿ'CÆCÀêcU¹¼fùv µá}ø¡£b´yÓsøþƒs¬}˜\ówMÑŸwU 1ü»uP£ßeªþATÂzuù¬«ÛÛsÑG›Rô®§$Òa3°ÂÕ>„=ÿÎÜ]†H¡SÔCѱ˵f ­mñx9bEžný†| rÞµwÊïa.QW‰µ|= œê¹goîyyÎ3ímkiÞD¤ì²ÃÕ*b›²á½KƒË/‡“ Á|à˜F Ù÷òéèJhZFXÿÄt˜qtE³FË\Œáä<§þ¥G-êwˆ±È> OB:^mdtU¹9í;ƒ±!œ‰;=gpÊo8:eï—˜_Щ3›Òh´¿ø‚m 3ƒ¹ l_Z~À±&`›¯¹w¸:ªŽù‚Ög´ì}I]ì3éN0ÿ8ænáÅ„YàØèØ€û^øÁÝËóûù!¶â-P]:L»‘TCþu±v7pãmd*v(Múúv;†ÃèZœ‹Iõ ÄŒþÕe-„ø (Je&[òïNöÝOJ$c¾â ?Ô¡£UEœÅ%öpZ¾Ú¢pkÑ…Ûz›®†±ƒ‘(J#“„Å{©pZ ¹˜Ö^7".Q§Z\"ð£"Þ³'¸ù™£} ïöÌ«¹m*÷ ÌK¦Î�ó*ÜÂ|ÏX­hïutD,ãÛv,Ú&mC�n¹18:Bù¥bT LÅAÂþ9ó0ìKôr4àjµ¤àêu¿+ ®áF(‡_8N»ÎýìéÔt꾌94}Gx—&¿sèÁÀbì.wý[ž©L˜»º‘kĽç1Ù¸­åí©Â¡?´Q~n)„j±·)KÜádÚµ \w_Zf#QôQæèÞ™_ŒD·N;¬½š¼a$»×µpà`¢ ú•wv/ÄñVÎáÍ &ßÓpü¬;a)e$ÏÃ)Ô¡ÏMÚô9òž_ØðÆL¾cêß÷¶¿c†Ë];O½RŒ‰¨“NÝ~uÈáêúþ˜Þ÷#¦uFóቸŸõÌñäžÙ;øct#ûCºnÌôø›JC_J] Áü쟜‘Áé ªï¨‹þáØ}¦G|;E½A€ªr`x47 ÏÒê‚ÔÖbš5jÖZ˜œÑý÷ ðë[š/¦õÓæWðº‡ØƒËäð¹R®“/³÷.UÏ>@%Û/ª2†õ±Â(öǼjHèÚp–wUs† 4à&â!þõu£¡Úµ[È ¢ªì"ܪ þ—ãäy0wCnkŒ,®;Um(¢îê±3x»Ú·k[ÔP[ÌUfïÅ¢ºu…C›ih 6mì 3A ¨p×kÚ•ùýŒ~žµßŒ›-+aT*óQÍ•‚j=Ú=ŠãúÊø'}Ctà_ƒ–V7m" ¦¼Û—:«œe3JØ[¼‚ŽÚU”3Ž’-†=胛!0+e6T¡}¸Þú^ÝZ€_»H&¾øNöÁŽðv–4")¿‰3(ê1ÙÃJ>³8¥ú.ˆYþ«TEÓʦ Ž­m_ý[õ«‰U9¦Q½0-¡¸Ï˜§– ¼  µôS˜T¯ù®Æq§m™so:6Fkõ¸¯~ j³Š&® åå㾡VeÈÁ{Æ#¨ÌV9ïu°ÏNÅ;á‡@ñ`Á<ƒ)Uï®Oˆƒú.¬ÂÿšP‡ç*{q<Mq�{~™°h´ µÈÚ^Ðä½|F!•ÍTS£_vtkº¿¾Π–•ñ©"¹ïGçyÞÂë!oR~ ½5Ê‹0jÑþ«ð K m]%¶A˜ nÔ˜Œ3ng´5&Õ…g‚–ïLÌHÁІÞ"&Ò‚ª¹}÷ü´vr/¡/ÇÓ–áÎР誵Ï1¾ºq5×~}‹¡Ù87~1dßsOù‚Aõ§žRùf™mc¯ã{PY¹fuJ[Í/°¿][Ž?Ã�^Ãyb°¿;“gcúð¸‰[‘Ïá0𧾚DÕñOE¯ óëƒ,œn…d¶ã²¶Ív¢ˆß¿Ònز_²„‡«Û¸£s=];<L¸‹þ²‘CIòÜ+-TûŽõ4á:Û5‹W+ɆŒa JÌÀçPU¡êeËè ØMgxÚüRýt×XðFÿÌXÅ>5T=¸#ÀÅLïÄÛשƒnœ9 ¸m`,jÐz9Õgð7sûfV@KÐöœˆóa‘D*z7 ú~Ž–> ¨‹°ôíª'³¶øwÒe·C?î`E¢G „O8D¡MpçKç”=¢=uv”läó,I»as¿¤ZÎÕtÁ ¸Ž/̱ô†0ðÿËByá/Q)1£HsX'°=x•[8iìGnÔôý_sJ–÷+Š`LõfX}ÏÔ<€cèÁ1ü^b ðVpß禪R}á]òàvá¤W¡ß¤QcŽWâã8úô>ôO0T×Í D9»béÝ:^&@UH8UWiœ²¯z%u~*¯{C¯Ààó5F;ÌžÌÆ€zúñÒ&ž`pIôeÐNUÊ&i£„Õ ßà!eñ¢T‹GÀ@‘yX”Îù°²N5èÒ×8½÷8Ý0ƒ‰PÌsê¶yx˜µ©‰_nN¤»À¯ q {¨?Rq<Ÿ‘ã÷^éÈÉŠLu¯i0ì^ƒh§Œ¢ Ïö€w>wºèÿàió&cú‚óŸü8ToN0ôe}ïˆ@Kv“ŽC㎚"r¾jï zÞ¬/œ<+è¸FÏâùk8�Ž!è0˜&”À¬ @Dý=®:Éh¯™‚~ì±õ"$ÏX!Ñpëu¬}Púa@æ#±°Ò½y¸jY¯9îë9™ ›É' â$Í0öbo=.ñ°¥‡Wàúu†÷ �…¡“DjáeÑë}ŠûxmfL/wB«´tï¢ÅeìKVDŠÍ±ÿëD$X^]]Æê’­× *–W7:´„:3\·Ï 4Þa]„‹ñÏ–JäÕ¿*XbD{±éö=Êê´Ÿöáç�ûµEÜޏ–>S™…´núÄ<` ¨ DZ¶;­°€{HbxózS¸ §Ç_L ¹&» w¿‹×k­G•cåè(KÎV“vú²Á‰Î| Ø[Ÿ*Lï¬øœèkÛ"gèê¶é5Y=YûÆö,§·ÐàPG…KßåÚæÊá¬zÌèš=8‡ŠJÅ+E p j€ ìcѼÌ Ÿ/\Ååj,¿¸^µ-×”pyߨ‹¢2œ¯Oûxõ´¶ê¾½ è€ãµë˜¹2&~Z /e¹^lqݠʉ÷¾㥊J–!;5+v|¹·*!ÊJ!¹Õç{X£Ûm÷Jê╤ø×¢ç lZY5 œGÎrU>äMõšBgµÇË:zîZ5F=Q¿YT`T†_žz–¨ò¨É|$F}óUÎÅR0¸Þ¨`úý_0°þÔóyŠAwŸ=ºðð%üÃz‡5¼¤U£1Ãk0ÜŒRí@Ë—ËÔ¶3áè5£ÏÖžœ&{,U8e¦2…ëÜ‚Á_ÕÏšª/—ô 4·¬ììNÜIÕ fÁPÏ2Î'Ò [Ûο½-§”ìSzò(ñ‚»ZÔ­¿I y•ˆ|?a&8s"÷ªó[h¬UÒdã ²7è¾óùâiØË.³Ž+"‹¢žözl WP…=�öÕŸbØ’ôÁ‰&3;1êÞŠº¨Ï·zþ[)ǨuÄ»àrè"ÎÔÊjeŠT³>7y‚×)+¿¹PŰ™"‹›Ë1½Ûë(…Å­¤vʱœø³gí„àQ{Dy‚!oìDè•"ѵív2§Eu£rçF®fqÇœ1Ú Óg^:tƒ›gÕêp¼nó¨±VÑ E™GŸ‡:üná / Éx~±ï§gð…˜Û)a ëèÀu’`ˆ[Au©±òW±ÁÒ‹U)»¡>«† žÛ|W‰°üOk«îìÆ ›E&IÁZ:‹[\âQKò)eñ&=v?R ATã&å˘õtÓùZèzzì—=HûÅ÷b»’uõýï7Z #~uš0Ë•ÚF]á¿w!cÈà~™ÀpÁAÔå•ÐŽq“„ßÁ·ðíZdWß ›rÜ>tùD'å(ˆF:“]¬`è¡3¸N‰‚W3ó¸b|-ò^^ø§õ§ÅKr™%«§aV2É<á—¼UÓeƒ³†tûà#X½ZQ¦'û+ùZ´´f&Ær'ÑÑÊ"Ùm¦›d 1v˜E”Ôð¹àEԬ̂w˜ývÜZsvö«´ûp oà#ÍïŸÃ?"œåÖc塨„³Õk"¢�·rÊT{èÐ l¾ žP‚ë2ü ywM¿ äóºã¼v=]6(kˆ6‚Î"%ÑÈ( 9œHÞìïâmÂý½—kº×ϳ{3¡ix<ÌN; ì·Áâ03v€nŠ$+U­ó-´ÅB‹ƒcý]ͽÁpÖ?6ðåW§Ë[t^óBK߀z¤3îè(Ýê­yöÖFRN‡Õc yÅêü&êêkîÁ¦óùÒîE+«<]Éö@±·$¢åi©© À=| •­ðgfoÂþò¦ÛN÷d-‰O‰X£h¦ú³ë¼ªñrÅ·R[\®S7¯é÷ÐMfÅŠcÐqèÁ+ho_AN˜G»•D–7öœ{9úÓÈÊ=¿ñ +…û ¦­E/;õÖ3yqSðCvØ\ÅDB‚õëìo}4èù¿ÜÔ~_4#– ZÆP -õçVdÃû2ÍCñ-PrÎ@ ë”.}‘Ѳ*Rphð5ÜÕZÌ‚å‡6‰s‹|7ü¥³êjrr„$¹)¡I±."ƒâhgñf=o˜±1Ë+\mWâ\fØßâö\%Oì ›·U¬WuªVÆŒ~F¾¢›šæ>Σ"lË'ó)¥ï[DAÁœj1RõE ¢ŸG+Ù²É&ù�Z9µ‘Jx—nÁØâîÀ2±œ2U¿¸œ€Ã2öùoáw~:§ÁZE•H§LǺ˜h5MßEµÝf@olÀ—ðÌÍøÄ�~ÈÁ@ ·ŽÐkÃËMûÈO;†eȘØ 1¬üЦ:ïÍÄŠÝ];+=‰ K-i’/ó½álG$*˜~Ð’({[Š8Sj¶é ×_paqñc˜#çiq£ÂsÕêz™¥¬áØ Ò‡‘O :\x¢â<Ûl« Ds%)½ø”ÎÀ¥Ý°-ÞQ.*ÜQl¡3‘8ƒgÙ<½‹XÉþºÇ|‹ Hùæ]$ßœeËÅ…Ì'7Š?³M—Õ &6àÜÆfX)6'IÅ£¦ †È‚Ð j^eWO�.¾×#.ª ¿¥£ÞIf&eÃö¹y±¦Ú±×ƒÃ‡%v¦@ç“o4õGaf±¿¥šaó.ç ª±R+h ¬­ÅbceöM,ìC/©gÖ ²díßíÍ5‘VÄ›a7ß~\æj¬ ”ìzý#e¥lØ. FìŰ-æH9cÄaÏ+NÎáßítÕ—aÃÈŠÐ0£ôV¥dÒÏ)#­ØwÍR£º>B5OSY,Œõö_Á)¼Ú‚5™Ö 1“ùíÅd—]˜ÚÍä]`%ïQÎÀ·‰6”°^ÅÕY)6Q 2M½’›­3GŠœd-ØÐÎ%NVξêÑ9O,-§#—ŪÊ:V#6G»a„³2¨pJEÝx¤ ³ç&ðÈ~šš­3~L<h*I«¥g…¾Ïœº'Aµù2¥¡”²¡,ô7QÞ j.›Ø¼ñd=i%ՓЃ^˜hvb›W“‡–¯õ•K"¶ÙènÏÜLMA‘|a%òWFÙʯ¶\…ÞúÉMΘ†ŒÂÔDö\}8­|Õœj—°j»„S±‚” ©8ƒßÀïã%DÊÔ_?ŒqCÖ¹3»­àŒ6j (ö¤ZÂŽ5A\ÇË3†µfÇnñ25ÄÐkÅVduÖjÑñVÑW»s곩¬¶ì–H :ý€ ;Ü ý„€‹h嫿”VàõÇët*Ðí\¾\)bÑXÙÈ-xþ¤Š=$‘õ^Ö[¦lJd¥$Óp¯uÛ[±Tö–‹*"¬z;ÌÂŒœ®’¸‰2£¹Ì*×n NÖ•zAgP,!Rf®—ì*ÌÕ¾ˆ¯Ý¶­<hN•n”œ>­0¹ )’<�œÃàßÖ<¹O¸(Ð}Dýq>žddÒÔVŠÈG ¶ˆ^tGãmJÅZ‰àMv£šËh¬zH©W¦e8$_$Mùz ûË4ç”R ·÷$#…žtfÀUòKKÏ)eCõ1\S=žžÊP.Ê;flÁ¯ák?ÛA5kº±’‚³%(eÑóGU^/„¢š¯Y̵wk Å3MDîúõ˜~–¦pŒü [o}þE_Íà †ÕΧ]ŽÍÑ-eC£û#‘nˆ¾µysÑzŠÓsçe’ÝŠÍ.ò'"%jÏo¸è‰1QÁf=Î~ægÜTã®lf®å£Æ™W¤xÒˆéà)Ám Q¹¥™åÊ^þ4XVß«E&kýHP…}˜€JÐVx®Ÿ„²P¼Ÿ.3w½O³Ö¹¤©·Ž|ü/NãRþ_¨Â Tá$ùs eÃe ™ïã9Å]¯v—–¡oN mœ›[͸"P‚7þvD„�² '£œ¢å¯¡¾Ô�½`ãè.ܹõ]¿ƒÕŒh?áJ>¥@<Æñ'1àMÕ«Û”c Õ ©•JlØ¥’äQ™Úãô$68ÕK-eíÔÚØ¹f>µÙ°L7\é¹ §egp‰Å¬Èn>ÛkÇÈ'pâÆQi|ZÚ-ñÒÑ„>êOô¼aú„ûžë†íö_k¼é®vl'¥3bÄà&éÓ�„ {±s’…]ž„i|g�� ¸IDATÁÙö)f¾¹É²,Êùêtu›‹›UÒ|ÏÖ/bnG±ùÆ?(~éå,ª,OÐè~\®ˆOT6ŒŸjÇ3íál¥bËcK…WM¼$•]c¦é¡¼˜“WžIžÜÙ÷ëô·¿RÛvöÅÿS딣uñPPÓT »R‘)‹¤Q]»¥û€ä?Zº„:Ù l—Š»‚Ü#öÜBä.õŸŒSJW“‰I[ÜÕÉXjú•ö)=µ³L2ZÖŠÚPõpS‚;CŽš‚ ÑØÖZ§¹¡Ô¼ùZ’&¼ ÏáËúeÑSWóÎ$½ßú�¯ãÛlÀç±EÉ‘?Ÿî´¨Ðz˜½œ@{"êû‡÷/IÙª&<Ô"%Ôˆ/¦{ÆÙY_o§èŒQ—õµBLSJ–n ,èÅXj¢£¦ÈBÔwf‡1k§¨Éw/–Ý>^+níÀüÎII¡b‚uD-ƒR¢ƒ—Ï» L*ÛØ>1ù`¼$öŠÔU•²á øpxf±Yoü¯×Ò÷UTdŽVx8Ù'êÒ7Û³;?¶¹ß‘–ë•ÈÐ{¯ÛÍø<f6R1ÁÌÖ½wy2¦¢SF½z`ÞÚÙñÞ—²á‘2è’©P)È,Rz›æ¢My}¼iàïöh=.smá”D¡•Ýê}xµŒÆã긶/“mÍ|„­649ã`›±èå«ÁÞïUWu7r"ÇͲ‡Û,R6ìN›+ß¶hl§·\´â£[)±™È?-+~†ŸØ01v8“Dû ·<rÈbe»w¿‰½ µô…Ž^>·XH×s3j¥š©pkt<¹¤lØPÑÛŠ8a¹µëy‡ÿXíò¤`dºãr×:ØàÃ2îå8ž-$µÜÉ96Y¾Œ½{s©ùþÊ-ãØØbeu)žˆ`Ø´~Àɰ´gÜZ‹Æ®¤„ÖV¬œÄÛù‰~ö@ÆrEfž°­“=O+ ø�TíD/Ó&æcÆ™ù¾ìÜ+éHÙ°‰¢÷híÇèr]íòÒ”®8'ä÷_Åìñí£2#–\£!—ž®¾Eb@‹2åÐÒw»&+Ô¢”³·kÊ”˜ƒ¨„¦òœ‚Tb…ïâ¿ä/Éü@ò÷åþÖv=!Âï€÷¡ünÛ?åºTÊ’î¨Ël\ î51Úÿñû<M%H;Ðáâ+ë ò‚·Ÿ<Ÿºµé`ÓvßêŠ$ ¶]òj$¤;¬/[e5‘vL9„¹Eæéd‘ Ž¿&Jà#¿L}+u†¶ñ[;ò„ú ”ßífA× íÈÂ,ÂŒeÉM›eö ¿Äu[ÍD‹ÔF®¼ÌA‘‚¼ˆn”0Ø,»/°"É+«meA"©ÅÌÛP*ÍÍjvO«e0O'ƒÝà8Žƒã¬?«Ä˜4ÎÚE>£d³!vá*uU¶©üg'}eEjù«®gò6Ç{>PÛ´übЂ_Âq^MBlL™ç;wΤíÙœÃT6¢ô‡¬ZÞfå±,_*£.ìSR|Ds@'[Ü>ß,îÚŽóaçé±óàêöƸJIž¼‹KˆÍ×Uøfi <ÊT7¢d×Z*úí‚ý‰\Vu‹#-æÁæbŒ:`d’ ),~ÝTQÖú´ÞËìÂí©@‰ò&•v¶Žl]F,bù;AK߯Qbosïv[]´tí!Ü…VÖl÷1Säj)R³3Å>0-ØŸõeݨ[žáø$òÊÂbŒzÕÈ#ŠéþÃÇrwšyÊ·®•„1¢~ggëK- ˆ”ô•R½ü¦¼M_?×KSnâ½´É)Ä¡–{6µ…\?‘ýa‘óŇ2ŽÅN}eá64•- †HÇËCæ”§k$¹’Ô˜ÒÇOáE|)Éž`!YÁh€&\&n”Þ¼¶›èÒ¢*¼gE©?!¶6¼oVY¸eï}%w}çZ;™}/, Œ$ìK{+±Ìu„øÍU;óÃîZæèvÖö;îüFƒ[ÄÜRsGÏù¼`†³ˆWÍu€”åa+¾3ÑbC]<¯ìhrÔÒë7Þy¸•­oÖþ£$c‘ãù¼WŠÈ†P lˆ§+ÙÞJEd³þ—Šû/%Û[[2ºówÛ=ÆŒŽõÊÝíœ>&µmk3«c)m°ûÐÛ¥®we7l-´.VŠÑ™É#µ¹Û*tM§ŒÁ> bo<2Þ’£S£N ðtÙ ¬ý§?øß¸·O.§>[³Nôo‘øC»1Ef#nŠ v»Ìò›T³/\ñÁN–5½síî'±²íô,Š+Fg&e@Û|¤j–®ä¬‘?îð`Y‰9¶Ýõž-t¢>빊òÕ2Ì,}DÞó+²P)ìSŠœgEùèžW?¥Áf8…”c¯o·óm8*ؾZÞäd}~œ‰Ý‹ÄöÕ¤þT‹õ?)Ìâa'Ódª9'G(J#—Ò¶[²ßÞó™Ü™Û÷ZS%›¼ >ŸÙ÷PÐ='!!!!ñAæÚ“²ABBBBBÊ ‰¼Ÿ7ä=]‘ø:lŽƒWä§ü”ŸòS~~2ŸÒ§$!!!!‘)$$$$$¤l²ABBBBBÊ ‰M§ä(ËOy„/?å§ü”Ÿ÷§#í éS’²ABBBBBÊ )$$$$$¤lØ-âkÎË Vù)?å§üüTƒX¥Ý !!!!!}JR6HHHHHHÙ !!!!!eƒ„„„„„” ÛF| «ÐäÈ9’øà$ÉÇ‘Â@Bâcƒ¢(rk?‰ÙØ}ßâ~Qú”$$$$$¤løÒhx"³±û¾Åý¢” R6HHHHHHÙ !!!!!eƒ„„„„„” e£&§@Bâc…¢(Áÿýd£•ÖCø3óæ$Ô½­®ZäÀÝ/C?$eƒ„ÄÇŒO<z5Äg×yñÃÞƒ‹ìÞöV-ràò„ħ(ùm†]v/×oI»ABâ“Pœåõ7¹j‘„” Ÿ¢Öœ‹H| «–±MéS’ø„,’ŒÂFÊ ‰™ÈI«VÌ ‘²ABBBB" yÞ !ñÑÂqyýä¦e«Ý %n㋟“÷$$>->('a}Õ´ì¬{qÍÊû ™ eƒ„„„„„” R6HHHHHHÙ !!!!±)–qJínÿÛÿýüO9)Ÿ ÚÝ~„lýABBBBâS·> ^˹p¡8ŽóŸÿë“!!!!!áâ_þÏÿúÿ÷Û æ/ÏU?����IEND®B`‚�������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�014304� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/xraycontour.png�����������������������������������������������������������0000644�0001750�0001750�00000250257�11332353405�017434� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��<�����yûɲ���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ7“ìŒ�� �IDATxÚì½{”Wy'úÓOµt¤n½%Û² ~4ØÆÐmyH‚‰Í0†ÜÌäº%™Cq3+w¢1“»’py…$3s¯°îÍš!Mf‡4™¬óæ• ¯ ËÝbƒ –±e[²-K-i[o©ëþQçÔÙµ_µ«jïª]§¿ßòò::}j×~ÿö÷íïÑÃ�¶¿eð{¿<�ƒc½ýÎ÷` Â[lËÌÞ/Ï5nºåŽ·ßùžgœÀA „·xú‰G<üÀ`ô³gNc Âs i!Ä2=~ôìÉ ªµ‘•«[kÖVû¬„´Î=Ã~{èGß¾lMcÍš5.\øÙ‰áµÛ^"-ôÔâ3c'~úÄâùË_þó8Âsœ=sêìÉ×½ô¥æ<ü£ÀÈèXUÏÊI  öÛ Wo?shaÇÛoøÜç¿°ÿøá±ñÜ“çÏž¾|ìäÓ‹°éšíÜãð‘´NÑë®».Ó#×]wÝÃ?úÑÈŠ•U=+'­F’u†FFO_ýɹ¿zí«_õ’Ék~öÕ¯_\¹fpx”ýMóȾ‹«†NŽm[»j NðF£‘]Æh0(ÿYi5¹?¬œØtðñçx`ï† ë¯¾â’…ŸÜ¿éú7tž?~à‡/ݼú{½ô¥7â<ˆð«·Üô¶×¿ì«ßûñ'þî»ØÂKÒjæ"f÷¿ ž5’´"l¸òúŸþðë'Nìo6›kÎÞÿýWM�=|àEðÝÚ¿mú—Rë±uýšwÞöª«·m8FO?ùìÑÿö¹ï,ž8Õ}/|tç¿X?¾ �þ?½÷àácñƒS“ÛÞúÚë·mY;Ðl>säÄ×çùê÷~†��ÿï{ubõØŸ}ú›ßþÁ~f4�àÔ‰£'Ž<³fýéo.ß¼öŽ_zåÕ—mX Ç=xÏ}÷Ç]@ %°4`(òpÏþÉ¿¹]õóßûÏŸ5y6ñ3é—IKu)µåú×=ùÀçFá,�,-_[=6±iÍÙ§~tàðÖni4R[úÞ;oÙ0±ê™Ã‹O=sxbͪ¯¾4<}ìâRs``�®½|SÄX�pãåkzvph�n¹ù%wÞú*�ØàÐé3g_zÕ¶;o»yëºU³÷í¥½Åçž>}òøŠUãþ°V„ ”VüޯߺrÅð—¾5߀ð-¯¿iãøØÏ àRB ¥pVN5dQñýô÷_óòW§>û'ÿæößÿ/Ÿ‹>ÿñoýsÕ³*IKνƒ#›nøÅÃÿøwCÐl6ŽìŸonØxþâé±Ë·¯X•ZõukVn˜XuöÜù_{ïÍÁ¡‘Õ+GNž<9¶ö’ÁÁ�xíWÀ£?}Õ—üÂk^ñ×_ý^kÝÖU+F~õ§àž¿ýÊ'þö+ƒÃ£¯~ÅK>øÛÿê^uý}_ß{øt¯ªáÒÒ_|h�ÌþÝýo{ý £ÃCŸýævðÈoþóW¯[³ò{?þ_?û¥¥�þí¯¾ñªË6¶ÆFÎ]¸¸ÿ©ÃŸüÒÞ§Ÿ;�WoÛø›o{õ†‰U?|ôà‰N¿é¦kþþGî¹ï{�°q¢uÇ[nzÉ›†~úäáO~ñ§ž;Æ5ðÚË7þÆÛ^½~¼ó8+Õμeûk^veklôôÙóO>ö§ýõk¶mZ¹bøÉC‡ÿ/ò©«Ö¼âº«·mÝðâõ£û\h�Z² ˆH˦ŠïWÞý{âÿæãÌ©]úì|ìóô¿½-âªøs\ ÷¬Š´”Í[½våÛÏxàÔÙ‹áÀèXóÜáææK7m3iê §Îž9w~txè#wýÆOÿéçyü™±Ñ‰€ÆÐàÀöë.€Í}þC¿ók›ÖO\uɺgO‡“—o Ãðo¾ôÍUVoøÉ3§>¶eÃø /ÞúŽûÅþí?wýcO?7õ’+ï¸eú…SgòÄ3­¯»ñÅ÷Ï?ôOŽC£±~bÕ7÷þððÑc/Ÿ¼r꺫ûW^÷ÞÝŸ^½ºµóŽ7­Z1òÃG~vò}ãö�àäñç=pË%—ÿþ¯¿eíê±o>øð‘£‹·ÿâk~÷Î_øÝÿçÓg/öÞ½bdèwþ×7­\1òÐO?sò…7N÷lcn¸jë­¯yéú‹ß\96òò—^uò衳›Æ`ÝxëÒ­›Öo½rMk%�\uÙ¦‡ÿÑÊÖÒ(EÒjæzª!}vrêu*žÓ?û¾?ûÂGÞóV�à‹-0›!‹¥SG—B8¿hêááá¡‹¦Í>1ü³¿ùÖ;oÞþ²k·¿ �àÙ#ÇwÿÕ7=—_{éÊÑác'^øÁ÷/üø‰Ÿ›žüù›oœýÂÞÖØ(�œ9{î䩳›6\Ñl ;yfËX³zå™ST|ÑGÿüo¾ûý}ÿý?¾÷ÒÍë¿øõïíù÷½·ý«oyýÔeWßÿÐã«Ö¬ÿÃ?ÿò“ûZµªõ{÷}â_¼uãZ8säÆéÉU+Fž_<~×}lpxtÕÊ•S×½8à^~Í¥kW=þÔ³»ÿü¯‡W¬ÚvÉ–éë^|ö5{]lE/½ñêKW®9rìÄÎü—¡‘?yﯿâ%/Šþ424�ô…“O?wôÙc§æ¾øÝ³§Ok>ñÓÏ\½mó'þÓ¿€è~nÅèÈù³§ 5‘c&!DFþiB³‘ã©F£)VUZü½úÙ÷}ü¾¼û¶cÝôzÉ{¥¤¥q´:qèÑ G;¿bãêáSçÎ;{ö,œ{ž>IkÃe&ýþ£‡¾ö~²eÍÈuWoû_~éç¶nZwëö+?þù‡W¼æ†+à» ?j4æòôÏMO¾á•7îùô×èé³�0:2¼råŠÆ@³90�ÆDk%�§'—.^„Ëþ׬ßræB�?}ü©­ñ Í!�<wöôÀ`ã×ÞúÊ©ky劑ø‘áÆÊÑA�xêÐah ¬Ýrù³Ç{ú½µkÆ�àŠK7ýíÇ>¹yý8tõúÍ‘6oMk �ž<ø4›ë¶^qèè©WtùÃýOÍÿègS/¹âúk®�€çŽžøŸ¸ï™ÅÓ4ûå—nÛºqâÐsG^3}Ýk§¯?v‚†KKK ¯(CÒ²y§¥*Qñ)ŸýÃö­¬RñÿÜóEé{’–‚-ÏÐEºÿþS_4ýæÓ'Žý§¯6á"�{ä›#­ÛGÆZú¦ \ÿ¢- pqñä ßzøàº ûfn{íª•£‹Ï=}ùÕ/¹ñêK�àÖ7¾òÖ7¾2úýʱÑW\sɾŸ<wþÂðÐà/¿ùµ_ýÇ'›#Í—]µuóº�<øÃG$f /^‰:åÂÅ‹C#£Í®‘H.½öeW¾þå/>øÜÑ?ùØÜÉS§wýþ{šÍf£Ñ8zü�¸dó†áÑQh4·m^¸xâ4�8øìŸÞó™øË£ÇèÅ çÃp©90�'Nž€ kLJFÐÜ´®ç¯vþÂÒGÿêkçŽ?»uýšyÛ^;}Ý+¯Ýòùï>600òàOŸ½ðð«Æ†ëηÀÂÃ6† ¡¨^=Ø”«U¥%Ôƒ²g?ü¯ßËXÑ5ضo}ÿý²øÞ êÁ¥ çO>ö]h4¶¾ü–¡‘±¡ c¯yýéǾ=22<44ôÂþûGnx³¾ýÃCƒÿû¿xýÉ3¯zê¹caW_º�~ðãýáÒÅí×^68Ð<uúÌ?þ¨c¶~Å%›.Ù¼þ_;õÑ¿üû¿þûùwÞúª¿ò–׿êًмêÒõ�ð•o=øãýÖm½R~ýÓh2æ ~Ž*yñâÅá¡á7¾y{³Ù©ó÷9@OžÙ°vÍ®ßýÓà%WnŠYxäÉ£Ç_ضuÓ[ßôê§¼0±zå×lÛó鯽ðø³v |ègÏœ<}ö’Íëû_½õ\cä×\?~ý‹·Þþú—ýø±§NŸ9wé–M�püÄ 'Ÿýã·ã=uòôÙ›^²m劑oíý§}û¬Ûze3×LB ˆŒô“0ˆøÐoÞ¢úåþü+ɧä¾V’–äÙø½‘Vðþ•è›ÿë·ˆïU‘–äŧŸúþúÖðs«_±ºëu´ö²kŸ:º­u~hh( Ã'ŸøÁš+§4tîüÒ¾óðU[VoÛ²idxèȱÿðü«Ïmtõº×¼ìJ�øü?Ü¿ç|1Š.uÃ5—ÿ‡÷îx哃ñ…¿ðÑ'Ÿ|êmoœ¾êò­ÍŸ»ïëßûÛ/}kŪ5C#+@e´Ð~„ïüà±k/Ø~Ý‹þ펷á[?8söüèÈ�œ>{îî¹ÿùëÿlû‹·myð¡Ÿ~õÛßËë^qqi �Μ»ðG³_þå×]{Ó WÿÜèè"=ùãýO>ú裡ÕƒCQw>{áîOýÏ_»uû-¯›~xÿ“ßþþ#¯ŸšŒÞxŒžn6àÍ7_76:LOùâ7üÌWþ¿áUÏ-žØ>yÙÊ£GŽÑ¹ÏíŸþÒèØê¡‘ÍÁª„{Ö2Œº÷ð÷¾vÝÍ?Ï hⳑ„¤|‘öÙ˜±¢·|à¿}õC¿ñfù{¹‚£|Z?{ê9î§ž}ôòÑã?8@·^ÿöeáÒÒ…§˜žÜvñâÅã'N<r|åÊWhZ¾´tñÙ'¹xþü… gÃ¥°90°bÕøªµ†‡FŸ=ðȹ3§V®Y×Z»1J |öôÉcÏ>ـƦ½´ðÂñçÏž<qþìÙÂÁÁá«'V®^;08<<2úÄö.-]ß°µµnË“ûæ`Ãe׬\=þÔO~páüÙñ—®^·ùÈÓ<qtlõÚµ›·]¼pþÈ¡ÇÏ9ÕlŒ­ž8yìH.­¿ôÅëÖm<øÔÏNŸ8záÂùþÁoÝ8yåÇþòó÷}ûŸÖnÞ684|ì¹§NŸ¤çÏœZZZ]³~늕­H=ézâ4]¼páüÈèX£Ñ8sê…èÎyþÐãÏŸ —–šÍ‘±U«×oYqøéýgO¿^\]9ÞšØ004<<²WpãÏ?sÝu‰�è}÷ïU?¾þÕ¿Ø!°‡¼fýfÏÆ?“~=ÿuñ¹§zù´8<G\>vò'Žnzé¡™ÎK®?uîØäUWRJßxìäñµ‡o³98¾ñÒ¥¥ h4‘48428<ºzý–fs 90884242 �Ã#cÍæÀðè@8:¶z`pèìØêF£ÙhF²ÓððèÀð�¬ÙxéðèŠF£ ÆøÆKGW®ŽZ±fã%ƒC�h­Ý¼bõÄàÐ@ct¬5¾þh@Ä7£+W 4ÞyëM ˜~üÉg®º|ó“W¼pêô?|gaph  Ñh¬ÙpÉðŠãašF£B8Þ“|Æ7\2<¶jp`¨Ñl†aغxa`p�†W¬šØpI³9ØèV~`phpxxͺ-KK£B††‡‡‘±D9‚/»Üðš7›<%5¦°þ,÷¥Þ¹8ñ‡ž?ðÈ©ÅÑm7 ˆåŽ®\ýБSO=ÿЙ3gΟ?GÏŸmM«« c-9¥­^»‰ûfhdt|ÃÖøŸÃ£cÃB\ú/‰?¯ÝÜs[³®G˃CÃì#«&Ö‹å|þÄ›^~Å«^zùé³çö>ô(ùËÏ£'×_º¥Ñl6Á¡UãëõC242ºfdTú§–Ð@�X)˃@ ^©E®«ìYî»H=øÄ¡£ËvŸ;ðÈÉÇ–.^h6›ƒ#+V¯Ý84²btÕx/™DáÜ™S§_8Îiêôxøá¯Xµfxt¬ªgãoŽz¼§\ÎV�«×m]¹¦98™©4GW¬j6Ñ–@ô¢ôT?ücóGV¬Z=UÕ³Ò‹û+Zã+Zã8›IJୱU#c«êõ¬„´"IëÔ‰EQ@x…±Õ‚¤pêÄâ=|ö@ ¼Â»>xOÌ[xsƒ@ ±{÷nöŸƒâ/Ž;†Ý„@ ˆÊ1;;Ë}ƒ’@ j$-@ i!¤…@ $-@ ´@ÒB ’@ žb0ëÒï£?-.Z `(¾‹+<~#ûê"ÕŸeë`±iÅÛ^-TÕ³;¤“­ò~àj•µ>Ö—‰ùDuôj‹“Öu ¹Whö iz[Í÷ Ó‰Çu‘Ó8˜ï±27“w¹®OU¥WD¥©ÞÄÄÄÄÄÄââ¢Ý KÏ(>0–ØpjUy•ŠtŽ'^ÚŸv‡>žÌ¥ –盉sÒJ%O§ŠJŠ'Vî©•?«‘äTâ…-™OÓj±±ìÙï¹Ïe´ëìSÛeÒ®e}o[ ®‡s¿ÚúvŽj¶”\ÃÔþtÄ"ì–%mf5RŽÉ6åº&5Ï1”M§£.võmQušp=¡]4-ëMZVâá>—_ŽþíªtLÚ¥ï"ô™z»œe’õÕ.¦„¾s¤oÔ×°Hivý¦¡ú‚»¹¾uù&I…/Ó[ò å`ÁN/AäTѵjºW¢uVƒÒ~öGÌO=¯Y©j ÷y«ä““çz¤¬§ø¬ ÙÖ¤R]]zëŸÊ£*í%wJSõ€ÓëgGCéðNË£”¼ò¥j7GMËÑö+­„¡ñäj§’y¢oxjW{rð²¸ÜTggßZêzèm-Ãý¦'WÔ«²Uq1èƒ>Ï~Od?›¦ÒP÷ÙÐø&f±õILƨ_™^T?x%+K¯®-}¦)óGŽ)·EJNrµE½åo5͹S©‹3¬á2c›ÆÝšø¶Õ–<4ýÊXî:¶ÈXˆ×x>«X=?eͺô§¾“UŠ¢’W–ªóuì £Q7t+äSg¦?âyÛ4[5ájUÕД#õJ›PÚ¸ˆ]­©€~Œ,ÖYZ”¦ð’§±¾s¤ ¹Ú…f2ÇÊ©•É2;Pß{åô­É[òï7ÝrÇÛï|Ï“Ï?ubñž¾ 0s1@‘ºnX¯Þ3ñ(sñ±µc«'?µÿÀÃ`'QͶÕ7¦>Àò’¨�%˜£Ú—ÄQG òböa‘j£¤…@ ˆÚ�I @ HZ@ i!I @ $-@ ´±Ü ñÓŠÂf Ụµ{÷nì@Ô€´±á3xõàŽ;°Sá ÆÇÇßõÁ{ä’@ u’´&-„ç@Ý’"ßùßÁN@ ¼æ¼EÒBàª@ j€ÙÙY<SÖx§…@ ”´¢žv‚'Þ8¦“V”ÎYÄââ"æÉ¶“.G$‚øŸÒ!‹óšëiò8÷›"%[œ6ÒºéßbÒÆL¯Yñ7ÒßkúV³ôRGWe ÚÐHïVL%-\å µŸE¶ˆ?OLL°K÷Mö—æ³åpß›—¬ S½¥øa+µ£r ±XUéAÅÓÑãªCdB£ÑXNÍ%�WÛ æÆq°à¾ =º"Ãéö™@/ÁÄßhvü‚;²;é9S™úž‘Š#ñ®mX2G¥bßæ›ÒQQ\!¸"~#¨Q]íbÄ+Sª¸@HûGßiÒ¿Æ{ŸÉÖ!w…¥[9ȧî㙦“ªOToQýžû¾ü)©oYQ’­'á“ô惙6<3:2ô*£L}Î)‘²já >îN’c%sÚ+^ÛÔþÏ*ÙÒIˆ¼… ±¤7›wZ(`Yìo·¤"ÂV¦¶”ó–âý/æ4̤/*Ç<‰wä-eŽÜ;8h¹Ä·VÛ -[Ķœ+‡¢)Ç–äíVÖ’Ud /Çný‹P‚Ó3ÛL4¾èk™£UÊ#u’´š.–.¡âæ³Ú§Ì*ešNš_f-§`ÿ›ß>âɨ€´P½nÞ?ñg}§™t©ô7.¾Ì:ôšB&ä˜Nlùâï9ð¬ç'¶ó~Èú®|uÓt.:„1H¥Û)pÐpy¤ž"q͘w£æžÚ¥&$%|™µžYgH¦;$ÉFUá¬í2o‘y¤Ž©ù0!Z•>ÂEWž1ö @ jÁšf’áR™ÿ2„·¦zx\5H½uë$-D•¨ŽËó £Î°$ ’VÅÀ ÑJZµ­­w-BÒrŒ@ ¤U‹ÚNÃÞyØîy‹´Üb÷îÝØ „·flZ¶ËGÑI Å,bùBš± á³è‰¤…«XŽÐdlB8€(rôÓB ßvj¬¼JäÊ)„!i!„#Xyë0%-iÀ4iü´|AÕ–I˜]U`\MÀ\}!VÙ!ˆ²$RÃ:û%G‘VÖL²èá¨éFñƒ˜ÑX­<߸ $gâK¨ú¦8µ¯D±tÒ’&z׈©r€ø¥ø¡_Á1º”à5¬ÏEÂóè ‘ä­ ‘ƒZŠmI‚—…;-6ËFª|&ý2wò¡:ŠYšz˜¹Xö(_ËGÜ?â¢þ% ^H+÷^‰‚B&ÊQiEÆB \"m÷A‰o4~$¶zb–]‚qDÕÙŠun=ˆ6úÞ@ÆB êÌa¾‰€ul{¶b;ã~*¥–½ »H¥`ÄF >;h˜ˆYóå–ºÛeZ’´¸û*éþ›OÞR}‰“Q: 1«/AjUxA=gàL #$­ÅÅEdýUõ=÷”ª¨øûe¸³<£ùG E <îÆY”´T»aê©_ÿ”á÷ý!'em¬æ(l!%ê½È¿…aœ¢††‰j©%‡°XúO¤…Ælá=‚$¥�¾I%B“/ Á²õ Ò@Ø@=[£aF¦‡4oi–±0ŸV 1;;‹€@ Cž“%)³¶HZΉæˆå)÷È¡½k*†„a È]+ç»ÞýÍåh i¹ÅîÝ»±4رcvbÙÉ=éú»\[|Ø-9ú4>®(ǪÝ`‚‰k=!’ŠYUâØ±cØ „Í->„FG‚\å‹Ä“ZÚ½�s®'DÒÂ}¹ÌÎÎ"£#ýB™­übF Ÿ@ÔSrVéØÐé I÷ÿÄÖ«lç$®’@ô‹0šóM xkY—ÜH])¤%M¥¡Ši‹YH¼‚4C4ì%¢Ž˜†½JšitÿŠt¨¹Äœ`ˆƒ_¢¤…Œ¥ÈÍ…ŠG å¢à>N£f`NÍX$Á^JNÊ]“À¸UHZš¼$š»xºWýÕRvQ. îãwÁÝf–ÄRMHY t&iIòÖA DVA'”ü˜hˆd)©ªý9I ULžƒ•†QÌB J©¨dñ+°!ΚIŠ’–˜Ú1Þûr(úP7X&oáÙðF"ÎJNÀ # ÷ÏèÿÔ ªÄÛåæÝŒ’G6œ®/ÇNŠ›)XNbV©pêb™‰»î wàVlå‘7ކ5Þµ@Z¹Så¢q|UPõ0êˆ*Ĭò9’ÃŒ¢’¬–¯Õ¥1PgØ‚ o³²IZR‹vFѰ"þ†Ý¹[Ü7{X†é#ZšKòM¬$�´ËUñgŽÌHÚ•X©0=(îz"!¥ g¸u–Ï[&_"ˆ¾ìâ<Él3Ý_vhöÎw¾™éþ Õe²–Ï­Eçb(™ŒÎ‰ùS‰ðƒ èšWiØ0ÃÈLñ=hMÃ^&F{‹)9`d¯Ôz:ê$-¨’Ÿ £†-P?5“öld^ÌÃ@k¦¢owÁÎyØ@£æa{÷÷TVBîš•‘´¢dÆ?Ë!Ä´Ìh2"'2 Ó°�î‚I†Ÿh÷B‹³}§LiÅ,®ðüb>-ç˜ÅN@ –è-ÞôÁl-‡�À4Lì€)X˜„}wÁÝó½gƒiØû>øÈ;à³m {��  s{ºÏî‚÷ÏÁÞy˜Lƃ7ɘEÔþË­â’–s`ªC¢ï@Ê5¢#2+köƺ¾6ÀXˆÈi¦öÀÌtOÑÕÂ}pÀ'`ß4À<Lîé𠙆©»``zšC½QìçvHZn±{÷nì vìØB0P¿KEÖi/P°™‡íñ?÷ÀLæö�Ø7s�3ó°=RÎÃä}pÛ4LMÂ�ÌÃBt¹5 ûæ{Š»9Fh ÔoçÐÊÕÞ ½¤…bV•8vìвÂòÙbÄÒÌó}‹V °w¢î‚÷ÏÁ̽ðÎûà¶;àSs0Ó²¶ï‚‘P5 p|8z`nÌÌÃ$ÀÂ4LÍÃ$tødÈ*HZ¸ì+“r<!  Ϩ„°‚[L!rif�te)èÒ;ඈu7AаïA y˜œ†}30wL¶;Z3�3óSx°JTÖŠBëADŸ�Sµ!êÌg†j2‹¦Žýzô9rÏÚ; {ᾘšƒ™'á²÷ÁG¦a�DŒµ�S·Á}m˜c¶ôas5Þcn’¢OK -†@ôˆ"f<i‰ÀhÀ4ìؾ�`nf�à ð Á^Ø�ï€OÞ ï¼ žü¼a öÀÌ4Àmð‘IØ÷¸MàHVÞ"Iêe½ÇÞíi‰G×¢Žþ¾�� �IDATÅÅE.¢—јû1N:“f;*µ¥?Ã?jžâÆN?XúŠßW8èå¼ZiÓ¤&Ò…“õ)§c°D*r„!�4â,L� b[½kHº±*:âÔ<Ì@d¹> ‘¤uÜ÷‘Îí,ÀÔ3°ùð¡iØ÷¸mì» îÞ;£{¯wÀg»Ì7×µÔˆL3æ¦aj^'&’òC6Í÷UJé>…ùG ÷>:+µÙ¤&†–þÀä)ó¢*TÍÅ©2bÏkÆKÚ?ùžr4Öˆ¼È¶k7 l4H£‘¹dXHל=öyju &�&aSyûºÏî…íÂ�€@ð)¸�ÞÙûöÁd�ìƒÉ)XØ;»LÁB÷--€€ –¡ íÁ´$ô†´ ¥„~)ÎÞ—XÜÍì{3u2è=Ǹ˜?åÃ¥âÔ·T\&ýŸé©L]gÇ>à¹0”†obXĆé‘åE°�S�p|ã£Gv6n†ék¦¯]�€9˜ù|à1xÑÌ�À‡àwÁ$�L¾»`² s‘$·§o0 8‹@˜¹¨fÁ=B³½öÍQNlf »@jr?0ÏEÒ—‹èË‘ ágr2Ì;SS„ЈHHb¸Q‰ýYR,£1óMé]õà.xÿ]0ù™ûo÷#äÝéu þßÛ7Ã3o€o<xóöIØ÷)¸ã^¸oÌÜ~ÈL%Ó—6�4(„Ðù¯÷^b†„ ¡Ëƒ¹!·9jŽuÜ¢êµ"ÒA¹n‘ª¥Ù^âp׊âSÒ}6z°Ÿ4E¥é ¥„‘ï|“ï©TÃnÍößX× ¡ññî¥TK&WRa‹>RÐ�€ðn�x�Àg¡c p@Ç‹ën¶¨›�¢ÈìõÕ®ü°ûÞ†¼U¹+2ßiI— NÄšŠŒ€·Æ2÷ÙG=q¬½ˆ/¹ÿ7@¸ñŠ¿$ÌÐhÀM½Ñ?ojìýhcgôùÁÆÔR¢ÿ‡,5 ü„ë!ü÷p°±9Ü›Û   Òý'tÿŸ$¡øKiÍÃ.oùCZ©Ç=½"Q\eþsÆBîû ³¼ÀþAtA”Ö#§XÒš†©îõR” æa!úr&ï‚I€€™oÀš@§¯]¸vúøæÆÍ�_¸àe��‡Þ»ùSpÇL=ØS*Î,ôJîáÝ;!héÆ^hˆR©ª¯›VvßË[±D¬}*¿½¹¹*õbÌÖ»<#¯Y“#HÖ§ò(ÝKNF0¸ÓŠ¡f¢Ï±àÕ Ñ%uì`æÚÝ4áºÖ.xÿ>˜¼Þù™Gnÿwï¾{ËÍÏÀý7ÿ®©-7?�s03s7Á7âBæ™P;Þ“WÍ÷â9©ÐèH`:Xr¼enP¯ã6Û:שúPúÞŸ`�YÌ72Õ°Â1rQ•‘gUGNgÂøÕÛñÈä]¢�”aNÅj±%zÄ.“°o ¦aßgŽÜþøÆ˜€WÁ÷}|3¼��þà8Lß¼pèþÍŸ‚;f`î.øð4ìëf‰lí‚ó° y󰱶Ф©�ƒ†+$õK©™@?©‰ôb«pÃ>7“q1)ʰ†° ÜŠËéÉâO™Ï„{ñ+Ù+ÉmâŸJª˜îdºš™‚¹÷Á}ï€Û"޹n‹‚»_O¾ >ÿàºíámð lÞ Ï|ö‘Ûƒ½›ƒ™(êà<,ÄwÁÝÐqO[D."F ”ãë/÷¶{@ J£±T‘ÅÐËx 5 ûö�|ÞÜ ï€˜:W/À`&ájx6„­‘¯ñÌÜ×Õ4Û§aªl02š§{:WeRÖ <éD$-ðš ÷4ù9ʃ5¹«#0‘wÀ'§aß<lß €=03 ûæïŸÚ Ï@>¾.øÌ‘Ûça!r=îòVüÏH8Ðê:~±\E¼ê# ˜‹@ ž ÅÈ4ìO„ù �swÁä4LÍÃv€`¾Cl33ðþyø0�"¡ªq¦á}Ð ÑD"M`ôÈ4ì›ï¾nžOU êA$­þ¦ÇÅB Ò`B ì ¤¢y˜œïwó`ÍEb,�LMÌwãf¦a*ú°‡áÂ(¨.S ¾%I]HZË�˜IЂ*X$¥œ™¤¼¬1zd³ÙÄwí׃y ]×®HºŠÒ<.0‰ S,íÞoÅÑ:Zv’–[ìÞ½;Aƒ;và�á�-{´ògÑêÞfq戴Ë[Ië lÞ �´ s{`!JYìéÈg{c/€ yJ('[Þv’žâ«Då©îq€< >Q\‰_²ú:ÂXúua/À¾ø¦*zf+<åÁжöô¯@ç¡Õ²f�æ Ãgq¦.PT�ðN —ýrÇìì¬'„äù�õ#ô4(ÈLb ÑM¦E9ñ(™+2b©V÷7d Ku© UÒž¼…&ïQ!u¥ dTøž …t2·;ÄC»ù9èd¡Ý@M¬»WTK]ðDÒBÒB ˆ’Ae”�‚G”x½Äš¼�˜†½ñ— 0µ§'*ÅúÃ(œîÀ\Wœ¢É\DÆ‹Yùµ<¤«¥9‹‡/ËQ‚?1ÓÄš¸®; \žhîûÔ/õ¹—RŸJ-Ê”?@ª©j"v`jÐÈ~ e#HL[¨ÅÚ½ èX«o‡žQûd÷OŒŽó0Ù½¯"Ýgƒ$A ÕñŠ«2KZl&+B1¯OŽ}PEKÒTgb*ÔáK}ʼ¨å<Rñg±T½jØ“8@ý1€‘†Ãh3Ú¹iØÇØ£q„ÀiØ›L(ÉX3�­ø~«žPÆKE“"6GMHK³JUÉ´Ä?iRꉳ+Œ¢m²w@2‹˜ÓS­*Ê8dÎ59ô_Øï’(~ ²Ö<jþr D]%�&ˆmd1Ñb.¨:|Öý>ãæº‚×Cx¤kØbâÇ·´œÄ ‚^`°ø*Õ$ü—œøcé_õx²-²„ZšÞI¥kÊ÷ejù¦ Ðr@dªÞ¥“XºŠ=«b=ÞÜ|‡H4†ˆô|° E0”“YåBï%-1 ((pj •bD䬅ò°äl,R½É—ÒÇ¥J§~Ò)•œ>Êð\•O}×—„‚‰¨Ä~e·bÕz3I(�žêXÁˆ2Þ]Öxÿ‡,bVÒXæ;­‹Ÿ]læëÍ[Ý xòÅMd™Ÿ*<Ô j‹–@Ì%ã*q&…TàŒ i"ØÚ’#Â[T¹H<’Æš.¶ ÕÍŠùo"–ùÀX~U÷ü9j‚‰Øm ‡£s ÐrgþJ<š”œfºÁTF!=åadŸ ➉¢HùBU¤¥_r© T—Å)U“º«yÁnQ=Ž[¡Å³§‡°rØÂZ–ˆ cFA­¤'V‹±¿Hd@n'õ{Qú’ŒQÿ¦²+®¦‹¬¿4÷WÑc9¯ÞÔ.Êñ¥Åò‡Òõ@ÔlN"µ†ïêú iIØÁž„-b>ŽñÑOkÐpÁh¾Lýf£,òŠÊ·žÔ^rúF»_,Ês’¨ðæS¥à©é�!²“GOO8ßM)2ßK)KHðÁ_ªXÒB…@8‰c^$-‰‚í!¡Ijù˃´P)@ nX* 4:VÓ0�ÉÐ&3”íúš´08@8@LN¤Id2`b^Hé'胎À|ZÎ1;;‹€„@ô†Ežž�ˆKx7[®ú¡w;lN£¤ÕWÀLz8@„½-žh-Ô­gö.Ö;’–[ìÞ½;Aƒ;và�á�!,ñ‡>³I>*òN£ˆ¤…§ø*Qyª{ Ï!ðG å}ŠáÔ ¹Äÿ{/$-\öÕ`vvÖÂÀò|€jÌd TaBH5°Ôhâ°#D=ÑÊ.¨¥‚xÞf$-èWä` ú«Ñ_ؤOªê%.[fü½4¦¾´zæO¥…ä¢Wûr€Vi)0c ^ ãZ;l¡¤U{îä6ei*NUÐaó§*OÅRÇ3Mñ^ÅBØŒ‚Œ©ŠëOZñÚˆcH‹y'p_B2Õ‚ô—u·/T"fq‰1‰o„ã‚ðL ëd“´¢2Þ2�SÅ‚šn‹^©O1Qä”ý›þ%­"‡ÊþÛ1KËæž*f‰C€*£Ê ›S$põÑ|‰@@ Û?›Nª¡XPS8Ê­ž›±þœ*¤g.»±æK¢oõ\%¦s±Ê’­/e/®±% ×½HcÂŒÃjò¬U4VGy‹Ó8•¬|[d“©QUÉœ‘J(ƒ´D±Cü þÐ@Àv烱!†ùS8d.ÆQ úJC8h¸¹eé³Êd î»’ÍQu¾ù—ùžªïHUø^ DE0×ÖÀïØ¹zQ! æ¢Ö@ úAóe¤&A¢B DmHk™cvv;ðu ¡‹¤å˜IðuR"i¹ÅîÝ»±4رc¤…§øz òT÷8@ž¤…ËÞ ÌÎÎzB8@žÁ“@"I @ ÛHWŠñ,ÊgnëÒØuw#Ów‘˜½)Ó—~6ª´ 㺚ޮéÀ!¾HZbdñVµõøO‹IÔ}ðR»HŸKÚÛt‘U%*+Ÿ’U½]ÓC ¼´4KŽûÀžõ¢°îlú;.…kê Ñõ"TeÿÒTϤQe¢÷)®iâ”Ó"±Ü%­Ôã°xÖ‹¶xv»÷ç„(2–aõôBX³Ä²™nDÆÊ*Í ˆ~–´¤"EMO¯º·Öâ—ô{ä$I+e¿`¿É½eà^ƒp:1p‚!Ë”´ —¬{DùâŠYõ‚ Úãà@#}/ü´JK¹Lk¹%ÞLml]:3¦"eHZÑ{+n²ð¸_–ïû¥¯I…Õ³ó¦Õ±½q¥wZ>·(µný=puY;Ø u%-ým–øù_M¦…Ý©£¹ÉÏÚp R²G¦/½jK‘ÉV‹=±¾×À,ký,i!•�¯'î€Á‚‘´û jÆÖ±cÇ ü¤…@¸â-ìI a¨ÇB HZµ*Çq€’V €Êq a˜@ µ•´ÆÇDZSQÒÚ½{7v @ |ÂZ%iíØ±»@ ž`||ü]¼GIZP†0º÷A?éOMêX=U…+±,až÷U-År¨³·Ub1hø;ט…¼j ºü©I«§¯pÉrüøøxÜEÞöU-År¨³çUŠÖƒ¨ ´¤…@ ’@ –-ò‡q’æÿo³9”ãú”Y7¯ò<Õ(s‡´ß0iV_NËÚ,ÎÃ|½á¢ßûx«ªî }Ù™ˆå œ‡õ–´âÃûÄÄ„JÀbå0ëã--\¬'rÅvD  ­ªJþ³N0ªa»…­û=÷¹„‘;VUm»¯Õúi–µÓJ˜ù™†©ªåi^GÃm² Rg]iµÕ,éçj—ªþ»(ÏVü>Õ‹ãj‰j±›ØÂ¥Sм®ýo˜X&“Ö-Ú‚ÙíXÚÏîZ,¤…ëÿZ¤¯âF™L³LVÎÌ7¦ —gÖú8Z2úU ßLôµ­d¥çèsKÕäVº¨ß 1ʤ%é€ezª=Þ"ƒÚ Ó:×B›Êm âȪþZÉP¯†£¶˜›õ½Žú<ÓŽ¡?{U¾ÙZ©Æ ëÕUÇÂû¸ªR©«;ßçCOîÍË„\SǨƒè”ú{>gš-õÚîkºþ=Ù\"‚~Zø¹ªâußÙûþ«­4´&ƒ‹–Ë¡+LfKí:³YÂ^àn; ÷ö€ÉV•»ü¨©Ÿ£‘­d€ê¢Ô×3Lj”¼<ë5Ÿý©¼ùŽ·¢|Ëdè­tiÓi»è5iáì ¦Žº‹ÆJ‹­JBÏÚæòV -ªÅ'ºHf•ÔмJúÁ­pyJßXa¯æØL<\ÔžÌU“7ZY݃EêÇ}–~Yš*VCº6J¨I?”ÓWú·äûk µ-vég”þË2;*_=õu®ª’•ÔÐðE¶K%k¹ÂŤbÅk…aœ"]µ…ðHZÁ‹~jõàÔz@ êË[?»%-@ÔHZ¨ äêÁÙÙÙ ëTíÛý¬I«'b||û +‰}è}îÆÆM·Üñö;ßóäsÇOXœ?ºcÇdr@øsØ}×ï[=qø©ý~�Õƒ¨ ¥´f«ôcÇŽ¥£bû¸b†5¯£j%Ò Ô·Ï±æØlNjsRHKú»˜•V tZlW,SÍ륻º¾}Ž5Çæ`sR›Õƒ¨ ´¤…@ ’@ –-ú9ö`Žx—\tg6‘•ØYÒ¢r×3õ‘šÖ\LþT£>·ØóØç¹çy}›#­yŸ5§à2AIKÒƒ1jÝ–š¦W`G|Ê›ûèƒ}^ò<¯usÄš÷YsŠ/“¾•´âÑ$oÕü>în±§R`Žs–>liò«Ýš—)yÛª¹8êUó:öyê<·ÛÒJ&ÝW„ô‘"ËÄI˺dÀe¼M=­¤æ;¶ËXš£G¦sVù{Pi5·Û4ìsMÍeªoŸWÛÕ@àèô¹¤å3r®ÓIìUÍ­7­œšÛÇK«9û§hÇ´ÒŠjçy¼±Ú‘Òš#ˆš®é@œ`™IËî• W ¦ EÔw¸`,DÁMÙ"㊰2Ň£™£víØ¢ênþPÕlè§š{¾>õ}>Ñ…x ÃÙ² kn¥9µ^.–ɲ°´5Ý+/G¼ù+y=cÍ55ÏsÖUØçuÜFÌ›S¦ÑoU£S|™øBZ.d¬¸+ÙûÃǶ[Ó›B±M­y™ë¹´šO0À>w]sG†Uõy}›£yªŽ+ÂÑ@ô¹!ÛM©]¦ù±õ»\Õ» m^ «çâÚÖuÍÝ2”Óç[QfÍív{åó¼¾Íé³áb™ s1@ j$-@ i!¤…@ $-@ |‡ÜzpvvÖîk¬è´Ø>®X*ÆÇÇkZóúö9Ö›ƒÍ1Gã¦[îxûïyò¹ã§N,Nݱc29@ ü9I¿ëƒ÷Œ­ž8üÔþ?0Ø7m@ô=xÒÚ½{7v @ |ÂZ%iíܹ³Òš€ ùÁ+X¬Uî¢�”Û9\U¹R€VÍÇ"R.þ@Sg}'©†ÅžôsU–V½Ê›ï´†…§þÌ~%Ã0|×ï‰ÿÙÌØ*ׄ¥½:SõŠ×-ÈÛá@ë¥ÄR«¹šì˜´¬±(­´¾me©37¦q¯Z91Â}ît…’ª§{R$Ý’RVŸf’h^Dœ-¨ ØHñkÖd›ðù|TQràw’ìÄVÙ736v¥¬ÔÊ[s";ù¼BÃTäüȺ+È^B “$(6™8dç¤ÀøÇÒ*á¬ähÕÝBjØÕD+’9jȾie‘ÂI¹cÏäÀÁ:¬tÕp´œ-b0â™T5¤Äé¡â<š}-8?è4ËêŸE%‹‡YG禒ϼÔM£ÌÏ€D»$léªÚ:gJ<TfrP®ÈEJ\nÅëë±T±ÝcPjc]l€¤`ý›fåÇ¥î™ÓÕèî´NòÎT×Ôò,©hÐ-n­Ò''-½ÇŸ&Qÿ,pÜX’—}Ûlƒ4z&ùH+(Ö)¤>Ô·c¸ÓiªŸ+Ô›a"~ô¿W‡*s¥µQrP‘îÁŸ…™Ú-A¹s&p9ÿIá “Œæ¿°oºYZËŠ{Üíw³éù~ø:L³’I±> Œc`i²ÕRO=¹UDÜçZl†gk”&ð5mÏÏGˆ”2ÝÝmÄă#¿õ¹Hò |õâËÀã¢q®°Þ‡ƒH¬ÎáÒ˜ùZÎZU+M3¼Q+®Ï<š6&wD+†•ÔßsÏL5 ’¶ríîö J#¥\Å‘´!¨Ñ2)Ü?æFÄl‹'¹*@,mJAß;=ÒågrÞi™Œç“RõcboðD¿AmX°œ ˳¤ÀƒRjqVÖ[êÓ,Á/Š´Âî‰ÊUÚR J\eAÆÙ•ɬÀÊÅXq-.)}7ÈÿHÓýt±0"ȵ³ÔE™£’-ã‹Ò‹(^‚*ŽAÖÙš˜9HŠd¬êº9ã:ÌnšÅ®nÉ8;}ºX;v-LŽb.Eò:dUcšÔŠ”1!oºåŽüÅ7‚]Ÿ»óŸ¸ûî»k+mÔ·†¤¿BúbЉmí_ñÇiöWåºr3Éåßs»V{”pIìâšMY~†w~àÁ®ÏýòλoºåަÇÔç+ƒzôù¼Ð<‘ƒ«5 l̹ì³ÈÅÔ"Üx0|œ B ÜÇçÐ-¥ª­¸Á©âVÉoZŽ{Øä76µýMðåªBéþöþ¼°/)ðº"ñ7‰ÓϺ°¨†ù³¶ªÏ³aÍíöçt@³S±·`ƒ«#_<É–¥r<×X#­âvGÄÒ´Ly.7|»]Í[«ØÞšZ%GQTÜ]ä.ç†ù± (0v's+m Ì÷AÞ²ux ܯÓLe¶÷Þ"=YҾݬb~”¹YT.&¶*Z„bõrØ×ÕÖn±A¹#n"î66‹"þ'¤ÜÌUÅ„Íä,(\>5€‹ÃwàfzU¯M°î\\ÇH€¤ôÅ#‡²¶£üdý/Ü\A¤€‚ûôg.œ#ƒ,Çgâ&Œ,¸OÐeÎÒ„#R É5깋š›e2Á°ì\\ÇNÜÏoÕ€IÏÔË^ ê0XA•ÑŸ<HÚvOlÐLVy×â}L>zsáÙx3á5Þî¹Ï‚vCÛRfËø‘ÀXñ˜§æÍ¾®¬¯ÒÔrÌmÞZ¥÷*©tºçx/õiÎ 3<e[ŒÕDŒ¥.[9gA¦6,î@JÔýéÏÎc×p Ææá0Lx.(k÷ YÖ‘‰F.ÖWûi•â&æÝ+ꬥ¦ û¤å¶’Ó°7ËÛF“*_ãên£(ÿ¨GdG("„QoöRßÈùiùì\ÜǼâs<‹Ïƒƒ|%£fËÑäKâÕú/Öi·{#Kú«7Ê#­fû«^ÎÜh×2»`.4½ñUPâM•æ’Ò¤4ùÁÜ{7kd£ÀêŠÈ!°Qƒ¤ØÁ>ä ë³ÊØ^w™FÖ0ñ²í`¦ÛtRùú’V1Ì(øjf±@j£pGvb®½|K+ÕKÉ·L§âèZ–b™AÚ_i)Ϋ:íYªx^Ī\G¬Xý9©|…¤EÊzªUѪÈ7ƒ‹¡h®-5Ó˜4„ú±ö BÔ²…£@ãVöý|qa¤²©‰¸ =ñÐe NL59<›!šé âü:ÙÒ›ÕÕ#_جðsd]³~6±î”Öê™zú£Ú¢¤/-M×_¼¨ ;<\—‹’¤é-Š‹­ìÚæa¨|°•%¹f¨vù°ç�váPÛ×bƒ*MWé< dUÇ™EÝ×ÊŠ¤\$$sîm4È¢âHå9ÃêY ‘iUذšsUšc¦JZ¼z̤†Êá0x64æ¯hi—O X8-“™\ôV°*½ðfÖmêA†˜ô3utiçýÀ˜l³Ç ‘HOfÔ¬—üaóK»ÊŒ¾’ÄC3eæa»Ù¹„:n]q'ârV¨Åü ÷÷ܽ—©ü ¯$`1Ì[þ¥Ý´'¬¸Ûå µU†Fb=1sÔ¿¤Er“ÎECñQ¯ô+'îŸ]ut‘„{…†&9(-á3UÉU21K¥To9›öùJ U¬P°gùf7âCîÞ+Nœ$M+ikJEÓ@€-_º J|ÊEϺf©Ü†=ÅïÀb«%Ó]§–|ûZA«-Rø{Rxn˜”ÐRÉUó°ÝåQÉüª‰è¢Ý1Ëwm´r…ØŽ"£d¹ÔȤÃ(>ÿ³ ‹s±?¶@NꉗM®¤W‰—ezqÜ«C}ôOµA›–›q¾‰ê:<7õfvU9Š8~¬^Rb†¡|Ó²zÃîLRy“ÜmŸ†©*fQjÅò©tlöv;AuÑT(V£' ,IÄý„/árÔäWÚ]9"?voËÞº.8"Aš€U«5mH|Ö÷Íj¹³xV˜–%& ªè ã2C€Pœ0‰�Á‚u@…hXŸ{[2ô{2¨Uóͽ@½CÚ¹$y!]seWàLj7¼j¥ýIu8Èj×SrP‚ÜYj •EÒÎe#­À™ïdÉÂJi7»ž¿Ô“ÖMÃ^‰ODW  –ºô3¸ÌtÄÞZQ—µ2ÖÍŠ·¹w#ÍhF h2&Ã4MG>m¥ äâÂRàZI0m=þK‘ÝÓI«Z©%ÓOlØnú†–ƒnÏ3í$7üa��Ðè¾¥Ð�ƒ{…ùޱvgš¡Ÿ,1 'ëéÖûäµ’%¹ÖZ æE’¶+™Ê÷Â}ŽðŽCY¥ [±0ˆû¦å›·åŸû•¤åó,É.oê™iͪCÈz~7Ï}@zûQGÀ‚Þçø7.{õþd%ãm¦~¦¹Îzrr:y¨6F”õÝDeI³tr í+k¡üfEçà�� �IDATÞŸ5˜ð%œ-8i.Å  ÃQÎq’eÛÔH–Ul°˜šÄý!Å]i´¤j„Éÿ€*䪮A|èÏ(· Q3‡ !˜:Ä6]¹«C™ÑÜ;èzòÑìo¬>›W©IHmW‚Ýã#%ªîe¥«@#¹Zí™nìíü ·$æ\J¢û6k$bM<=iUsìD4K_¥Æ˜üYŒdþ"’÷†ÌÖ²gÚ`’q¾ìº&Q­ìm¬ÔÚ«ž’¦J+¹ŒÍtÈP$D«iØ›ü’ðTç¶rÓ©º«-º1ºM{R`ÿ%þ”ÉSæA³{‘<¥Ä:wZ‘´<$-TqøÑ9u¼‹HBIØUNÃÞÞ9,snx2aJKÊîÂÿ—zÜÞz>i}ú„ÔeŒüÏ\ôÑ v- Ù­£–‰,Ú!€°Õ±ko��ÙÓ½›#%aç�óáv÷ËÒD¯Bìu¾Ô}²Hæ$[&ÚšôWrÁ ¹Gæ´Í$Újõœ üX\v§Ÿ^–j¥5!(¶Ìõ“3SR£s‹Ÿ³A4´Hýg›‡f=B’TCs•Fz7U¬µEBØ5Á8›!„]°3i£.%-CCó>Ks Íò\ 鳋XÒ%8:OW6usHZ¾e¬ñgï+â„T<8tªCh ³Ô0?�’D<‹ A¡gÖ¾´%|4„á»Â» c”]µ¡§‚»*…M¾1š3~iwªZjøï¦ÒʘîËsjÉ«ÀH_°¹s®ºÛ„­ YÁq³YÃIPÉ¡#«ÁOiö„YOñ&3¯«7ˆ¦@‘&0„#Æ�€1€3!¼"Ý`£»œÂ4H‰ÂV¹¦{oÌd|•/åDˬ|+ŽŸ&9Õ w® E@/ ËÓ1Xa˜Ú°+Z6†µœ­© ¸¦~úiU-®¹S§˜ ¬e`òs.ñÿá^¸±Ñ¨JC˜ûn¹è#¶ÎY+Ìu”/š0ZW•<^}ÕáÅ 1*éŽþЉgMÅ]Ž(&·5z!ÉßÈZýß66¿> 0  @:]eïªAÞ†CÁ|}ÚÐÀTË©z®4ÖxÁÈF*ë‰-Èø}nÍAµ9U½‘M\—z> l5²ZáWÛ–´Ð­ª?Î6Ý®BhÇ"”LØêý@)ÃóÑ4·Xñgg,hååÎZÕVQ÷Ùªêµó”Éâ!.$-[„·Ü”¹$Õퟸ¯ QoR½èd{Â Ý �ð`c �Ð8ßÚÑ÷{â;0›ÇçM3Év!þ¦•iz—eV@ çI¡yã/¤Ê‚ù‚š›7¼U wpv!ó»AÆ×%·¨»(‚bÝbðxuwZ}/Ð?­äÐY§ZiS?‰!-ºþ7]áI·^ÇÚ¾K ßë7.¶ìlíbAÇõœ$Š·çðLõ¨½ ¸é·|¨Ÿ#©Ãª$I«î†eƼ!–¨ŸsHí&ÉZ®srUÿ  붦$©w¢Ž;6“(ɾªÙ8¹UeUOuJ+MoáÛÒ#BÅÌ/ICé)*'-âeçæ#¿’#ÙX$Ë´ã<G<&tU’Ñ`ùW&ÄRW³M*káEˆ”8!ÝÝj÷ç­YzºÚ¶Ó™,÷ƒ”Òðü?ë3Iky‚”QN¯(ʄƠí8 a, „Q¼-™V4ûy–º‚â:ƒâ''ovP7«E aGz‚ç°jº®¦&ïË™ZDXIŠš–_. 9-�˜‡h�4(„­=a�Ðêš¶ÇQ ­·Å\q§2 i?6ôú”F“ 2ÊR©3$0뢎„’ûr›µV|Z)Ü`¹ àmÆcGòF©Èí1]0Eª%Ë2%-âñ‹|cnj¯+‹ 6 óe/; ”`áâ$(ÙªÔf™Î¿šháúÓRæjŽ8x©jºd|+‰qWDR!VYÕîšÏÙ£ÔYTgK·Ž²] A ŠÜ ±j# e Ëg==a%½mÝŒ‚“ŸŠØTžY¿½fÜp´µÑ¼%SÏu•[¿÷çl⎴|ΣC|-x™ ’*ê©Py«¬0¼_©Ýs*å[ ²eh|áHjtº(ꛆ¨'sßœh­¿ÅSM%­òÍúã¸QÂE1)«òšC7©¨J¥÷T?°bõJœy%Ûòî*®Ÿ¤YJ¶+hú ‹sþ›–^‡ê÷çTCŒ|^èEîocûcŸé-°79g¯0ìÏÀ8ˆ\àl§(Ç" e<µ2Ý]+{¯¢0Ÿ­ ÍR½¹\´¨¹„(bÏKC)jB“Kí „a}æd¢á Ë|ȺpKQI3ýÌ<öJYÁ’–oôPiÌ5É^±Ô[¢òÓÉ;Äã©e¨î'$H“¶SæÿĆ'­�ÑÎ=RîºRõ2Üýle1µ³iX÷ÓêË»DRîã%«dI‰?³Ku9ȸà f%[%r³µ1[ˆ½^2/Ÿz¶ŠýÜ|ìg°nÐT0 —CÒ²~èîæóÙzÞðæŸ˜Í0ORw’RÖUqɉfJL«V•ÁB¦$‡ÀÛàýVRÔvsˆ‹¥ Iky¢L [:7“pm5=jX:‰›·c•‹•°¤¶ãâ´äL*’w|k½.ɾýFZNoƒòíA•_P•zEĶÕ"ÎM¦ß;²¹ÊÍmEø8>$ÖSOº&NÏ|“&8]bÞÆÇª„´ò÷€ë|Z¹àÔZ,_J!•¥\]$óŽ%Åjr5vû-kÞÞ@mÒfqÆ+|&ï„4ͬ9‚IÞæmiö¥&Fn-5fM f‡°ÔÎ,8‡MÌ}Ûk!“xÏ‹¦eµÎövTXÒ†“©ä¬Y%Èò=?ª•ÝÞßÐÂ2¾Žf¬fDLVPVµ^½ÂOÔѹ ï´üX•§¼"µíéI–¾zfu±{RQ ¤¬;†âºô¬‚I‹EÉ©’ëƒZú)˜i¬ˆ!¨«ã`ɤ•銲,ß4(+áú29Ø­yÂ!7m¤åçãMÜØ"–ÐÄËQË`·¬“_}m‹ˆÅ’zrª¦Ç\“–·£ÞDZ)‹ìn´ÒuHK£'Ñ¡<ÙõÄôÇrâÏÒXs™Œ8³©qÚ«E"]¹K[U%W¶…º6ÄÀp©_Kƒä¿ ¡þ›»Æo¹¯°&<UËjÇšX÷ÅÞe¸#·Š IVdóxlÌ$!P “øx+ã{æC±ÃÙ8F•(K çO«Øö˜y³jÑgÁÍ9°´N‹¢ þÂâuN`ï)[äg.!ÅZ—§²tG¹û-Hk,ÉR%+÷OìÔoeÝy(u¶k˜)Pt©j #m\³—˜Û¦f¡ý>«9o™øÞf5S’ž{ϤjØÃÛ6Å‘¢å„ûkø,êÁ …Œ #MX TcHc$¯°ïmÚ?ãZ,j‡€Vלœ(1=ØíðiثՑHo 39z×¹3œߦåò¹Óª]ÍIý[gKí–ûÚÀü¬@KiÉÕŠ¬o´øÀÄ*(¢L¹3ý—ÖÎ÷Ùi­ˆO‹Q5Áê·E›ÖrΧ陹°œv¡¨Ë(? Ò³ùÞZÐdÙðYZî¸Ñ PM‹„0.¹_”U!%F†,yYy| cö™€h±¥µ–’³óM²rhž²ØW%˱rR!Yú\¢z¼„,Ž Ä@fDü²—ƒ’e³ET³oØ%­:yVY:¢š7¶`êX”wsÕ‰ÕA·²C¼$³>s2·BØÊ͵‚.ªæ§“j^J{íÇFéH« õ û:?½ƒpaD›¨´UQÍõ<J´»›·LiÝ.Ð8R÷»@/.6ÕïÆ¬‡4l™m¾Òx}&>jÕͶcNÝÀLÆ„D;‚ ð)4] ý')}Æ:BËý+HöFUf=ˆ‡ýâÇ™r(xr óñŒfrâVk¢RÛèZ 5iÔ×ΤŠFQ3‹¡`dÒ ÄÁ¬vdcœIê-sw"i³—ä^G?î´r«úfG&ŒäT#ƒ°äáp·æ¹>ÌåŽfqf5w$|œ©O¨Uµ1pB(LÒØ„Ä`t¬Ìä2…†:c¤CEÜÿ ÷ïI‰·¤Ò…)ޏùž”’á©ø(êSzqh.Cä±ïo§9K qri1µ6eÔEàfRîµt>ŸôçCu‚õÓécÒ*Á«ÔÛ�Nijj{%­–FÌ™æOŽü‡¶NÍ.ŽD©ŸÉñ.‡|–zΠtkñ  ¿/Vʶ™,nˆáçxîKªh”Éþh컧 €¦56+UèÃðÐ\§b0‚,˧•Ö'$Ë«A«È r±¬h¶@Í~ÈÌaƒ Ì©zê7AZâÔ• º¿ÑXɳ‹®HŠ VW6à‘Â’Viægz•°L¼lx]"ßgX`%æˆÉÍ©9µ7êˆD9jžµ&ùÄwZÖ³¨˜Êèˆú±´3uõc9gû}&õà2QOÕH–§ööw$Gr­4sãêÍT±Ò·¤ÒК¶zÃÜÝØ¨Ø,gª¨)\ ¢ª¾u“~I*Ý.j¿©öÙVµñúH)Ž>ªP_ÇÈ„ˆí8ÓÄ FŒ+“ÃÜd‰úÎ,«»´ëHÓÔlt’aµ²2dïÕ:‚š-/œ‹-’V9´õ–¬„TrNwé±½=RÐ-¢VUöD+×fšEzÀ®ÍRf>±‰ù2Toëa÷?“ú„Ì#N–v¾­ƒªw†j#ÚÞE¬G íKëAOB¹>|‘*”z ÄÝ-jQlJY7á3”™rD¢²1uCÅKCÑ´BØR—Ó̤« #.Öî”ieÉÔIÒrz Ž·€j7ñâöl¾ÖÌ}-&.Ƕ›ÊÚeŽ”²/†^" º¾PûöP˜K!¨/™RYÙ\Ð̤¿µ²–KX׿L©†´jwd¨<Í uÉCÞ‡õÌU®£²f’ó £Ó’¼;¦È|$M7|QnÅ€A¨â ã8L…ïIØ4–ô!�—y$Ì·›Çó%êEêè⡊Èâ#ÖåTÒ"Uw¥Ï/타Rõ áÈm€X? ™B´»Ù™d* ÆÁ݉LŠ‚$÷$ =Æo9*i2dÌj•jx¥J¼ß2½WCÆÄŸVô_ìA¯„hâqë¬È@Õ’1øœ•s\„”é^CÜ©&Nímj:¡”�€ôB:… wŒ “ŸCW%¬<ˆ GŽÈŠ&Â:õc¨Á~nNZ¤òºZ½ðXVÂYi÷À–S7¹9ÞUdOlÚy9\Í4.«ÔÞÚ!ÙÏÔ25šäFŠf;©lC‘S“/MLÃ^ƒüÅæ)aCvgbð®27.¯9Ò‘¤EJÙ}ÊW1ù9–¤Î­¨ÜÏéIH^–(tP¤ÒÞà×ì(dÙ…ßÛé’IÜlqÒR¨ª•À[ªóx&9¾ˆ‹›·9²Ð•і⤅I¶Ê¤ ¯bC”›Êp/ YÌwWaë)âlG£ßçˆE«•AC©T=O £Ð¤!•+·•Oê÷BÕÙ«² dqÎS£Lê¼5Ù*³ú(ïÔ¸Þµ¦ÆªzbƒäCP"šáò#-!}ŽN ¶Õöü=%îS4ñ×Pô©" (—Ú L²&¹E´TõCìeöq!R[¹añ'UlQI«Ú³@Huŧ))·VùŒ‰‹/iªÝ2œÎÜöÓÎ.HÛ&ÝkÞ¥´XÛUÊ7ᛄA„B}JÉ^Y¶œchâE½¿Ú7ª¨ˆd‰›•8SxuOlß³®šeioß'$˲2¤&‰ M�rœ4­È¹±¥Ó3,VÏ4J ¤æ ¥ò%‘3®IyÕIí(¿ Óm¡È|Tööܨ•¤ÆD69Âáû"¹¼×™V¦“¸'Š×å¬N¤ýÕÈžqÌî½Ì/Ï‹Yu+Ïòªj¤Cs�u07(/â„R³rŽx¤*8*7LO¼…(l7¨$ìS¨–ùTÿq¿É|7IRæ Ͼ´ðr(™·ŠkGʻDZ"iy�¸ˆTš¨ÂRü©|®Z&¦`,ʘ¬ç¬÷(†1Ý­VhÏ–Añ6¡äÂYQ­œ§™çTö,MT#õ‘6‰ì¯B”^k›(GÞ†STåP—s¿ëz§¤U¤=Þ&­÷Y.4·¬%å¶‹ÿkZ _Ã…AÓ6Vs¹A ŸÏ8“f)ÅÍžÉRC%e×2‚ˆ0LD3ðœÔÛ¯)#öQ…ؔƗ*Ê„€EªÅŒç¡L˜K?Ù(‚"êÍî=¥‡Z÷kÆ©Ðîé¼’ï´.óÉRMÌSåТ73­ˆ \n3ZÞ’ËD«U#²ÃcÃËDxŠ ÒOBŠ22)w†7Cø^¦V¡$ ¡Ì§[¤OY˜ù|r9ª#L==Šõæöõ½!¹»=iõ«xÔ7u#¥×°ªåDm׊äʉ厡‹ØÖò=Z£]4cSþZ‹(bA±L¦°ä7&'†g!„ƒ°Y[I*“ò©„k¥Ò’n2¨½Ó ;?©Åß:骗´H}ˆ(ÎãÅëOýÈ”¥`´Ždü¸7$6†ƒ*&° ÑPbû�Ù¥4b(LÃ^¦(¹§T,`u?È ;¾É!„á]ax¤§Ì䛄5Ki'˜Xú¡óT;c^ÝÛJã …)Ç >Ëql>«=Šò¾<#bPXÖÈ­_5wgÑ|ŸÙA’¹FJ}#±:I Ú€Åâ§i„MEºŠ:¡ˆ+A„HTf Àiðô._´ÍÛP°L¦Ð1*T&Z± vö¼¾ÂÔ¢7ÂLÊg¡dÔXvT¼+ygjRo"3QÛ³±„°¾÷Ӫ〙Ïòòý$ø[]°3‹LPP¤ËGrŹ6«˜j"o]— •Ѝ"$„Œóä&pT-Tq‹O ZHdtÎ+'#në2íý>L4Hd @šÆTiO/7ÍWÿ_Åm¡; ¾ø#¤"ãƒü1?‘´rÈRÄR9þže\Ê ¥yì|KÖD™*i˜Š¤…¡²Wëe‘ŽXÃ_™$IKM;/cRhCªi!lsî…ÛŦµ%”LYƒ‘6‡(î€i,ÕR>Qx"h¨“eÑ„Išm­•Ußš0Ò¯’–SW$Oâ?^íš³ …$j6RîÔ,YÃΑ2{Û± dSl”ŠBÚÒü)!(Œ�ÅðÏššãsï¥ê-›$-2„û­D™z…³hú¨9IÕg±>”÷›–+³¬ì?µìTÒFdHZ%vs4<ý1Þ.D7âY9MGiž@ݤ,šMêŒÄôí¡H*zw7Q9&ö‘IB‰:$IˆÊ¶]F×Ç ‘4ùj‹Fì%±\¥çÝÞÚAVÿ8U““`vjÂpŒŽAj'ˆ_ÂýªÌd ]ZJ'ëÙ(¬ä‚ò! »êØk+6±¡ï¥ê³J„öfšhÌj*IÔ4ïêÃ.Ø©h$&¡²[%]‡w9OccB!aj"ù ŽÛRž LCÌ—¤¦'!™E/l‰ÝB;ɘ¡´¿…0ê3iÕËŽôÅ+*>+fâ¥6‰›Hó'.‘FÕëe=–ˆ:I.Õ²rb“Mê'‰úxA€·;ïé'Y C©ˆ&¸ k¦I»N“DãÂf µEºv’ÜqÁðœÆ÷£ý‘ûpc,HZ˜²„a¦zµL¥s.·Ìšã—* fþ²$eXl†Ö;P³7I5Z¢Ë­TŸÆ©¡@ð©¢b&¸=IIBjp‚$$þR9 b'´ù{5ÂŒ»”œ M€5—Ei�ò­˜+]×Åbq¥—àI`X›Ùk³’Vq“GF ¤º …§Hñ½Þ)™Y|iÖܾ¤˜\e.¥Qí¢É€=¥&PìA¡T·&n‚|ì‰îÏ8ñ޶‚„ÑÅõ¼+ñx;±§“®"QÜî‰Ä°¢W*¹ê“öÚ|™šm‘ȳ$'þ”¨m[®” ”Ä „ür�ìhÑÊW¢pfqtKSv9òÀµUŽÄÖ>É…™8Ø$º®4¯¼Â`Z‹ÁäPjýA_—ìF¢`i5¨hq×föú6Ï4©žU„qÛâÞHÕY‰Ú¼P€&Ç&þŸm1V–äH‘[I)ÎãõÞZK"-Œ/I­FÅPÞR]gïl"ïª+g¼ôJÿ|ö@}mcÈßf‡ 1U| “É\²$Û7$ô¨Fùƈ;Ä`g„¤:Žw NŠD4M„'?KTFó-:•ˆPCHóî’F¬ÒHJ’POÔ8%›ÏK¬ s1’®¡Í«jä0^ …•“é»­c©òöJMÏEa¢·•ÇôÀêñd!þDM h#s¦†Û€6ïhLÓì÷8?hMR¡gˆWe½ ¹nTŽNiï8©Æ QA6¢ GdV$T.(ë‚YÓ8ºíB6cô7i™°Gö6)ùëü%×LçÁ"’bê³ÔLÞ¥²@Ún¸V§âÓßÛQ!:_ï³ 4ÓËFbžŽ8aï±î…Û™ŸÆÄlóU5DTEJ,M8íe’iÚ™†¨¥R¹Þ¢-7îô“4Ç)Q€½µRý ü9+“ŠêPvH‹ Î!ß‹8ÓÐìj¢‚›ríø8«ÜC ¤,Z8å&K²ÚåñaaSï½Hr›& /(¢Ý‹©Ì¸NT©Ñv½W¥–dkBY#.¨®Ì2¾Ç=‘¥®ùL¿r#²Û2Öi:6Ih#™À˜TáLd —UÃ*I*¦M’™Y¤µ°P=èËÀxb©X•8UDAAdaH–€¹[­dAãHq ß­ ‘Y¢köJ’´Êëõs;!9ÎPû>G‰,û"{#eò¹8Ø–S2€Äà¨í×Å!£ÙPÕ³2á•ÊÂp™¸IS&C¨Š ¡W« ¹®{²Ò¢ÚÃ첂‹Ð–%Ø\P{vw¤e œ¹ Yª»+pBQ!Kñ¾ßVÚJ¤ªà@MB©çÎo˜h´-£ ·%R X´­ôÛ¥Ò’Åm$eÚ’«,I8(Õæ“¼l£Çiäb¹†L.—j#“"rB]\ÜÜÐÊ«´Jy*ãNÒò\ü4IZa­Š¸@9ŠA &±4k«R{Zµ ÿ$æ¹OOhIÔ>°Ta_I3š”äW™«¥¨ø¬Ë[Dá+š“:ðoæ'uÆîêô±-¤•]_ÏÛ,ÙàN‚"TîKýêPã˜ì¹ð”{¡Ñ|ûC-Ôƒ¤&…wh÷¤™†üÖO[D8ÀæsE’žpÍu±)S­;1ˆNÔ}’¾JªH ¿ùKSaõ4ŠÉ;0N¶àBðùåD"ÊQ`[¢êìø#3ͤÜdPĶïÕ¼ÍGRñŸxB•²µ4fGqšT-ŠïUç0*°š ò•[’Jw<âÛ®›´ü¡tR–­déÊn[¬$Űø–TI…zô©¦"¥¢ÆÖ(HC‰ëÖu†_¢°i‰“̈â¿Þ³ŠtŽTý:Ñ"ƒ T ‚Ø$ÚG$Z$V#iÔ®º¥B÷Af’O… »è‘FջɢBf?¡’Ø’NTE”4•²}´*¡ë±$29ÿRÿZ—{¡+W€¹Ý®eãBÈeübbËǾ‚ÊvFiǦš-plGe¼%R’òUß±– ø+¢žx” à”жqWw ‰äK“ÝØ«|2-2•ŠžÝßpöë¬!UÙÊf…4½meG"%IÑÈ Ý §øuå&ßÒ•-iÕHûgQyUÂŽ\‚ß±Ñü¬b¤:“³QsâAnT÷ó4¿ØÊ3¢æ€ÏÞH‰ié‰%?i'/±¸k!™Ã2©–ʼ¯(' ëb®,*“{@ö ˆF¬qòªl™TMoª _Dèj"Ð6U;EPíÌT͆’)‘7©V•íÛÆK ïTyòiÕÏž¢Iµ§<OŽ|¢[ãy©|ÄÜ6í-%+44~ZŠýNîM¬"o1Ò’¨Æ$²«&©)9l»©,ÜCÏ,B›DÚ³ø‘' Y³CNé¦à r¡ ,&ø)ÉdBÖ ±7…Ú½ÌX (EUQÐ ä^v¹E“êuê¾]°SÆgÒSó94q°nfEüÛ9‰žºúÏO‹xSˆ‡JÑLíÍqÝå"À<q6Ž$»Œ£7iÕø­G¼_Á2[TF‘ä¹A ÿªÊÆ+9C´§`uxYPÄå㲓�c˜À“!7õ¢´r)aóÍj;º²Îo¶‹ »'l"¤ÁeÑOHRm(%&DæÝ(Wdn¥H¦º¥fñöa[&ª«âRÅ㼆•ˆJ4K®e&õU˜Zm(^ÑÐ+!QQõQ‘ÈvX©"H£ J°”¸ÉB/™W¥^ÜtNÈVOÒX‚Éî…Û{t².hk†‰f&#†«">K^›‘^±¡Hó+Mî¡—H26‡&­QļÐÄv¢²Ñd~š0–•C[Ÿí0¥’©Cï¸Pýõå K¦Z˜¢Š3ZvKÍ5d¬Æ/).h}€¸µ½eé¼âvOVi&“Ø$:Ø$¯Hü«âËž¸íä=J;i[Œí@×s+Y&Kf!ç0ñl2(‘hYùxÂhË ©Bw ‚Å9£æ *Y*K»Åë½»ÍäÔ­”‘ïeZâ0uÝeºå5ÑÒûãoã*`®Eóhÿi‰ø]=ßøLÅa¤ð”MqcÊR¸Õ$[òĦÙ7’Ûp ÞbBa醫2(Hò1úº„ú½¹v>�� �IDATp;Ë%me®éEî=æªøCÝ™ÖuÊáÕƒ‚û‘•¥¢S«Éîº@å#Üî©.¹ÈîâM!‘]:jÖU+–‹o,†¿¤ŽÚE¹eSEüTz•ô“”8rÄeCªeq}ȃä]9¿æ €"fUO¥[U`rª^ÀT¦’âøI§ÆÂþ›ÌDÌjÞBàU‹!#è$«ëÌYðBž`2E1ïe 7¤–åª~A¥)%*ªðxã¬Õ³žç\¡ñd¦© áte@â”�Š›Ë=ln夵œ›Ç2±ûRC±ÆJ “ø4cµM 5¹s´KØþÂÔîã/HÏõ*hÎc‰È z‚‘ %6»{áö6Kl]æH˜BÄ„Ç^/õ.«–ñÝÛ²èr+¡Z”ŨsP. £V/*M/Ù­dŠ(Üm‘ ¤ ªXA m‚!q2S áIªeÕUï·â "b”Üu!6“@)Šú:ê‚OÔ‰i¯7A¢›ggB!²]žÊ|• 6yHêµ€· —Ç¿èU©§UëYñ1ÆU¢]1+€ÄÃ7aA¤ñ»•gß‘‘½ðIKIìä-Q⺠DÉRYŽ¥b‹œº”©dÚ|®/©ŽKLQ>©dNÑz‡”²32yw‘)ƒz³Û–?'JP%<v—%ç»%5±96³çT A›QE¹¼÷}[¦§j3¾®‚’Š›/± vÞ ·«í×BeåîsòžI¸úbßÒ-¡-q¼e8’# á‰"—D)Çú8'ƒ\$„§6£™ŒÍ"XiU F%8W‘¤ Tåé¬JÍ Ó4Šv¢¿÷›Æ«_ói‘:”Oü˜=¹}5Êq]$ÅøÞ(¿ #¾PuNÌJ°”Ú"‹Ï;Ü–h¨@æ�›ðxÌØøvµ“áþÖ £$ÈvÁNÖ^¿«r$,ß0$Ä:'䞨ÂTòAš”Ì€sæöý¶Ü¬œ÷¿n˃½AÈé!ÅT¬cµ÷VêYÏóJ›é ™R[¨MFª¹:59Dz²±Ø}/)´H ¿­Çõ‚JM.‰Á?•÷jv ®.„e~ v_DŒÔ¡ì‘’ %jÜ9D°.KxÚ*ž¢)Š«Œ˜dÑó` 7OL>xƤ;*-iÁÊXl&ÉHÃÆ‰VÌUSÿdˆƒ°YŒ1(ªO“QÕ‰,Dˆ¬½¬$×G.€![`27&´å5áåפù†èšÍÅ×à¦iËí,@áÎeâ\d¿J-ÐiÌiùf}^NDÚbñl*d­u¬™Ô=b3TcÄl2‚„''ñ^!Ôœš©LP£²S¼Êd'tÒ‹!PNå{]eW;a+¡Š¥Ûsà•–VÕÕ'º!‹‹è‰Ä"!týv“^Ò¬%abFQ ±Iè « >hH»[Nôì°15:¢aT탰9©í©+c"ˆ³¢¶–´%îqšÙe–:,s³õš¥jDZ•d*œˆß…*4N=S(}ÊeÉu¹ +3ÌREBH‹B1d‰B$ s8*x8ñWDS·0Ád¬§p›“ÄwðÆå\paŠÙÓY:á’oAÏ9,ÖU†¬ŽNìv*ëgʉV¢îQø^ì1ªöw–K„LùT`Ó0Õ•© ‰Ë}#µï¨Ëç;-‹î½Öo_há©PU²Š±R_JJâçDõ_Cñ\ "š¼Bâ‰D޶$˜}‹ÙÓù0 ÀÇhç}¶Ú‚•„<WØI{!-¨¬¨Þ?E󇈙.aÿÚ‘·Ø¸O'ƒk°‰ÍÅi”I^e‘ÎÕ]²\\TÐßÒ¤î—Êò³pÌÍÙÖçÓ÷hã<)•xu’¬ì`¶"b,Ow«ôI™æ®Q3Q÷= qþ77²0ÏÑE̤Ì4ªB]€A8]ªM¥’HTp‚`ÔæÉ 3©˜xH AfŒÃ^Tˆ£ATÝÿGÞ]Ý›'ÊpU">ET™®Ó1§¥, 07Lb¢/Ú©cÓȰ'!I¨š1t„XTÚ;ùˆ½ ér‡ ŽeYÊèAØœ”·Tâ,�Æžë|#iµñœHÚÉ›8ØCHöueoþŽ$­:Zªøl6RSATÝÛTL"KSÄT8T­R.¿TªO È”~š¸ºâ !—tvä.ñ´E#FÁÕ3ÕK†ô¯ ’6$i Çfw=)s $fG¤’\Ã!$\ÄÂ$÷„ X=P1–•„#äŒÅØñ÷Ä»°ÃIvÑH•lâÕœêOæ°Ååe…/9QÑL¯²L¯ÕÛ’ØW•œ›­ícþ¨iMvsÏy‹¸/YŸ¥—XU ÒÓ‰KXN¤z'õ~¡ñM&jv7V"3ÙUHµ!i•À3q2*kÏze†‚ú1.wI×v#Þ¾i2I‡ Û1” !ä)c+Ñ“¢O[2Rš$ 5`›u!ˆ5œ±8ö†5i…/ !—§¹d˜Œ‹8"ª ,¢㤘̦⾠•õj×uMZUåb¯„Y¥·µrX…Îj9‚¤98µhÜ\Ä‹î0Uo©‹Ý.³ÐãØKw<¡¯kK´Lb¨…Þ¦Ÿ4.gâ\07s¼‡l"Þ eb^pÉAĬ"‰kª¶ ÞÉjÛ¶ñãU1“æI#uÏðví1 †=+G!p”Æu½ÓLöO0—Aà Š—©Ë„‹òNóLé]¢Å¤b/X§™‹«M/[èYãhªÄF!.æYAJj—ï-Õ&”úfj”0ìÞ ²TT!>5ÙÈâÉΉU ‚Èœ‹¹Ö%m.R ‰o§$.ŸÎª'W‰×Qq¬ F Iì^è&ÁiIH ™ˆ–Û)³ó`Ò»+©pã4®Œ¨öÌ[zõaH½ÍäAfS±¯`äKªpçƒÄ³mW³`¯Y*LKÅ­R(U”éj’ÊÀIËÑ™éÁ‚Ueô!¿ ñéJL3TMù4‹@F…-€JœsÅÅJkNÛ§QHdREI Bþ'¾ùíÄʼnDÙæ34vݤ˜Úv_’++šˆ“Û5dg‰‡¾Î™å4™¬ÌD“‰EH»càÞø’»Tˆ]÷�ç^M|™?™‹8¶½ü°v»‹öþ™âXœz¦‰°g´ÙVÊ| Õñ¦I?Dq‹²€¹É¤Ï¡Ý Ä<fw ªÓÇ-JZ´ôíØ7q­Ž0—†Õ~¸%ë BЪéT¿dµCÐ* sØ£4'91::•ÕrB™Æeèê©«JŠ÷ÐØr±ž ‘z´A³Qõ˜ÏÝbC¨×ºkìfÕ?¹â´†|„O#ïÝ$³r’Í7Ú‰Jné’b"^"aSVözŒ ç! °KÛ²pÉÿ¨,pIçËdfK"¨‰ö@¦ÖUŠôœ>Q ]qê½ÐðN‹”ÕÂZÄ \ž¤HrIrE³¬òTšçÊë]Hà<õ†ª-C%'Qí‰[E¨¤-1K£ 1€hñÈ„‡ lô 62§Ó‹¯dÚœˆÆÂÑ„e³ù²lÔæm"¨ÌѪ4=Y˜;!nk¦Œµ!³ƒÈü¹¼_ÊÄ,¡«ÀLP`Nz ì djšÄ'�µŠÈrÁPE¾ÊDhÄõ^úE¸`_šK†1ÆH½¶)»†¤Vû8©U7ʧ}•ƒºew’è„Àð¾0”.`îFGðÍâ¼õ0Ug6!Š ¹ ›@6Ï/{_Òf}cÙX· »°:@Ö2¢›F‹ÄŒÂz Gó¼²$’SG‰Ïz=ÇJ³vR ËÒUÜ.@TüMâ"ª[¥D€ù8L3ˆñ­X›‘ÿ>`D:ÄÜK•"§"`å§øOICAP8Ûqr•4�<$}òˆâí –F3¦6&6"e¤”`|soí&¬ iõSÂ{R]=ëKÙ$fb6•IZ¸ ¢æ“£$aDÇß̃öÞ›/PT4 ÆÐ¬´—°”§Úâ�ßÖ«mÏýV|i;ñ!a;íþ¬Š±VgSËcÚÐÓCÆöî±u{,å0âN"xû9–?bi#®<’ƒiB(È…’ [‰Ê0Î×=ZeB~AÅÉÃYâ«-7RWE¾Ó%Sm¶Š¨”¦7r/âf~õØÊœš¼“*ÚYmn4âßðgMáažà€8ª¸3M¥UÓ¤dFÕZ>͘rz-½õ©ÍG¶M&Ó @BU(Ñ Ò¤¬Ùã’xÇgïœXÝ£œ‰ßdY‡âè©(ÂkË„¨ l|¨2I}$>AQ\àÁØnžÑp²±wÙÒbh¬Q¤Iá†$�’„øг‹²ˆ¤°ÈÉÇœ#ˆŠâd(E*ÄÂ�múGPÄP¦Â̧êÔ‘6¨Œ‰Hu»zÙ¤eECÞ‡"nìJ+ïö´`HaÖWÒ<M¡ºd‘&$éze‹\Å:T³DÛJ?$i;>�]›OZ¨:ƒ«&RÏ/˜µÑ`r‚°ÛPÏ©™Ýˆ™àC1¡Ò8|ÌU\î’$‹pB a¢7ñî¹°ôœýB2çHOšI8 'ïÕâxQÜÐs´w,+ŠõlOºVB8yv!³™É¤7|T¢!yGʼn'q�×M?*;«¹>%,„–³'{0·VN£o‘Òû'“59S¥ö,ŸQF¾µ' Ê ÒI ç¡:ˆEx¹]F2#Õ²>MjÆgðØ0½Í†ÕApÛâ¯÷»w6½Û#®&Ñ~Íhù Å’É”YãˆNNdÖ~5AL†DâÜË›§X¦ÕãÂØ[9’ªóÆ÷+ªQè„kƪZVCÈ ëì="û_›““ÖØOn…ÏÔ3iHÒ¸J!Ó„`0Ws솱çsì`7s¤•)¯„o,XaÎF¯N†¶&Z>i™T­¦Kõa4h‚„P¹"úÐ8ò] -_äT•Úr?'Q-Ce­—,X¤+ú®RÁv §CcX‡&sGõÒ'i¬#±,˰æö ”h;UEŠ#ÎÐ$§jHƒÄjLFc%cÊI2žËíDê," ØÑý½ìÔÂ({C�‰ã0/0©ó|ªîÉHRa�Š ÙÖˆÚÛ,ß.—z‘fß9•´hw^¬XŠ2¶55½5q`4´Ñ0X9PÌǨ ÇŠàITi7!‰&G?$P\w .G||#–´¾®mÉÛ{ÂklÍêТ ú^¸=¢„Øè޽cò:’¤“MòiKÌ⹌$\jf¢HJÒ¹cíýÚ‰ÛÊ)“"Z§s„©X+-czKr*kÊÉ�ö²ÓF–8ÁŽÈ|~9bƒ¤ˆyA‰.q]èôn¢ƒq´嬛‡†$Ë?u¨ÝŽ.ùš*ë$ ‰ìJ?šk’w Äfò»¤Â¥4þ/žLiRûGIK’Ô±-ÄÃMì€])ª«£Ì AƬүT¶ycqÊÝ1ÊÃdŠaæ–‹‘WbI®wUÃÆ}ËŒÕzaó4켉Y—©6£ð”æjs6î‰>dD*\/QŽ~böe]³“Á;z†”ÉB(3œm'È‘ £Ie µÅhÊ PÚõb+±ŸÎHe–_6$u€J6Ð0a|ln'iäÒ”«iT«~äîéiXbQeÂ_ÅËL q›Ú¼¡6çñÚÓû1fÀÇÍKœå)—7.Ÿå’è:*&’äEp"£©ã£²ZÁv2£|[®Á‰ˆu˜¬;c¸Ár<g—‘p>kó†—�²ëqá0ÊHXo&­(jì¹R>%/”K#< C¯‰ô¯¢!h³‡W»£VS™J 1H)ÏR÷cf—QJîØâëYùO»Z’øŽÈe)iô¹ÐDLù[p¨’œ…Ûb°¸.m$íͨP¸u—±­`Œ#hÇ"‘nX†KÚ).Šyl†À…Ɉóo1LÀ¹mAìj_k1ò_¯Q÷ÂíC0$ÄŠ ”³VßȆÓm'$0 |Ƀ1ùµùð Ó®ÉWTˆ³•ˆì‹‰½GºŽq\´§¶|–ªÒ"ƒ`7¤šÌÔ UËD\,4—ªƒºß±û„´|tŠÐLyÏ´ò‹îÊá–H2š±$=g5ÞWòk*¢Ž{M´¼«òHï·%wŠ|RS"ìDLù¼Ï,°†éí„æ ¬$ÝNI”]ɈAm>s.Mš·Q6 ;CcœÊ” TÏF’ív²+«ÄÿeëJÜc2ÎÚ>zET·¸Â §òz×d’QkJØ�Q ËûqÃ$UcšhÈùôÇ ^L¶B…“™¹e¦…¬ÊSZ½\åiå¾ù¨©¾‘xVÃTû¢ßÙ3¨8Rÿ”p¡•exIÄ­Ð/Q¢Þ8›ÑZpâÏI¢Dœ=.G;à ¬X#ä¦RÞQ‰Á^Åþ!ÒÜ%¬y«9Œ¥"�ˆx‘½×‰µv¬iG!m!ì^T,Ã"½àÉ.YŠÕÜÒXª‹ës/Ü®ë&×.þ}ÒŸŒý ˆY¯’®T„‰—ŸTóòñG¤i<{,y˜0YDXƒ¼R¡x»xzËwn&2½w‘ ¹–êÁšær¬Jt«Ô†BU9W›[×E æàÏž|~[ÉFf¬"cªUlŠ7ê¢Æ‰Oá(¸Ù2é3BvO„¤KæÎ lØßvÒ{ŒMÌȼ—‰H›È€w›¥Ü«“‘&ze2j=Ö÷–˨ÂeM¤±ê’½âbïŸXðÿgïíaë:²lá­Î1Ñ3Љ“š™c 0ú)c“ÝØO ·Æp(}eFƒ4`˜”½†L“ñÃ�N:ø&ªœõ»jÕÚõsι¿¼2F0™¼÷Üsï=§Víµ×^‹ÇŸ¹•Å#bV¼'Òˆ5&EU‘HÈfÆ‹"KÄ0èlÙܯêZòuÒJ út÷¨(|8—C,÷ øÖíww9§µ%œø ûínuάw w°æD ®sª=_5[–YÀ«Í :h~>L&›t4#¼ßgAvõÒÎJæÊ6X1/Lm'W0iL÷ „CÈxĆPÇCßñAã‡4ƒå`’˜É˜,ÖGÞ§ †f§Øñ–§<Ê&î‡i€Udí!µ¯ êÑ¡‰é@–ÚÇ X½Iýµfv0¢ÛÇ b‡Õ¤ 9[Ûi)A¤8ù°u4Js³L·'Ó˜»µÂVxésÞxäo²¨rûzbÑí.¯°çš?8<R®t|‡K”~þHÙ×ÉVëÖÎnèòRáS^­¤­p…ðÖÀ°ð€›îyºc¡yáÚ§õûç·Ø$w¨4:ÅVb2—½5qϺÊ~žÃ-½|íma[kYûP‘¤·PÇzy³G)š Vh&ˆ{6ÊôBÂÓ±šŠh)Tï[3$ÞÐãí»`…¸9“;Šs\íà Ü{öà´~Œ°Úõ‰Õ÷Ï>xŽ­s¹·xö0¾…ìéµÚ§Ñ±�¨õu …«MÍ›b Yo-….ÀÈ©M‹‚Íg‹¾TÓûU‘ÀjÄ#)§~µT*\©3dTàŠvh>Ýg› ˆÜH¿ge®VH‰—Cå˜bIÇzGÙZ…ý gjÑ–³M¯,И:‡0 ‘—Fù9µ®1³ªÆ„{tôœ¤f\ɇZïçÒƒÐ?›_ÛêÁ9Û¥9;r„œ$Ж©ZÖ/Ý&ÀIj"¥ûBÁî%‹a¬Ðû(æ Öζí7Ò1%¢b+Ô=ßpþæÔ®Ä¼ $²P°¡¨*S‹(~pm„•ÝŠ³3'Í:'' ö ÆûRöo°‡â^O8~ÙEk(Û!šò±üò)ÑÑaÎ,Ikv[øäq!2 ”†÷©¼€>RC™“­ž¨¸)€Ç×p•Ñ5’èím>KÁ ºJS]YMi»Û"1ó€í’Ö’‡[²¯uûÔÇZ™g[ÁXsåz<¤óyºÞ ³ÓŠGºtyÏÁ;ô¼œõŽÛîìÎ(¡²F©4ë¼sÏ\M ÖnšMÎèÕÊçÍc³C+žË26ôr|¢Gq¦ÿQ$Cx.þ~‘Sx+ˆ(?‡ÂÞ‰k5kÑõëÚ`cÓÛ{¢Oñ±p`Š}ûfØŽ ¢¤í2XE³Þø–ýÐ@¬R2”ŽõY9‘¡T©ÌVñõ7Ùa…åeùWÙ�ÛçÈ]Öªn¥µ~Ïÿ¸©}ßL‚bͯ`¤Ï,ãñħ“löºFbú¤â�ëÊÉ T 乎}.ûJDáC=Z8…SÉÈ‚…¢9ÄT@¨¨otùNå”ç`FkHȾž~žgžPiyQË7¸‰U™DîYFÏ…N&Mw tùä‹è‹Oh ¶DíRX°Ûš¯kZe-Õ¥§i1åZ©6ng2ÕÙ—6ïжã{‹*ô£ðn_W`·' µ¹þ&ÿì¦Oæ–Ùp-µ#[ûG½®gn=LÛTºÑt®FŸÒ*Ù\e¦ Ö¾6½ªÖÔ`ÆËMe\$•k”‡s Ó_º…‡‚µ‘u’õÍÅ]Ÿ«˜4X)þÆœ°±ŠVþg&Òr´¶ ÷ü¡qZqgsã0M\$yÒ·ï+7H.(sL%;ÞWüÆÁòœ\É84œkE«&Çk©ŽŸÏp =–´’N÷d«=ñºÃzO­ˆ56žûò1þéÍ|l°Ó6“î›y“¸ÑïkœtV7R`µ )„$•¶œ¼Í b'šaQ¶³UZ²ºF´nz× <Cch7[F1¢°<x9ÑReÊèGÔXàúPß�r V0a¤€H,ÞEÁIj‘²E òAS¿MXlRèã¹Ð,ÂS†²<õ•Í|áºäÉöÞÌ/WS ®3ÏÞô·t­¤lí¹öv“‹hp nÉL;©h·Þʼ½Ç=T¥õÛ¨{vPñÌðaÅ|­ù6ì¬Öе·¸ÁÎè•”TuŸû uŠ(_IBêŠçy (,eèG¬¶í:l0N¬ži´Á`Rü9ÖôÁ®§õ2Mš=ƒd…i;²›­ É @ÆÎ"þËý@Т¯^ç[âé…Å™ kññÖîß…/j/kqâ*nÍÛ¹®ºbsÒp•ô•Ý~íâß��kP9™}ê:r 75UÉôànŠ*¿dµàfü{é5y÷ µ2:é'´Nõð±3‡k^n†pvO¸,MQµšÂhmÝH—žÊ«jÎ6²¾ N,nÎâ}¡‰åmÏÆ[pÊI½•#b¨ŠÊÆS±!…¡Ñ°èsìcYC,ôñÂ÷B³^ÈÐ9 „=yÅdõzë{kf¿óÀs •_¡¨äÛ _ÇQ,:RF˜d"¾¢é¬­0Ûšx­"OYFù†ÂÖ¤ØÙø–P^F[ήÕÊr­JË.Çq$ÞH×ÃmµÒòºŽÿ6i5"xÙ÷èV½dGòãg¨uç|G¡f0l’l-ÿØ“úb§_­ ¾Î©zê^—·CW¦,¨wÖACn–›wŸ0âûEN F‡›­j=ôçäq’3D¾ 4Úy<ªð£˜0Cÿ‰ñƒ#?Æh¹^L†”‹ùe>=TÕaòµÆ¤í übÍòª¢ñÆ1”[_ÍHQ„Y]¨™†¶W—om©' ¬Ž ¯YQû…Z°B£a—ü“[)vkô`½™]é½ù­}^ËžÀÖã¢×û zŸ‰ßܧäW=7㦻—´ÞÄ Ù´”ÑIp_Yïô¾‘"Ð'š.Ÿ*Ј‚Û+Öx?0»HÁÈíµ¥Cݪñ:\¤ ¦ò¢ÈKô<z\t†Hç– À6œO²wòŒÇ(€�~)58kOˆ-ÌØ¦ÿ{Ÿ>:––p9ÈcàÙ\мí³;éAxªÌñ–¥HËdøáÉ6²x/ï)\?5ÿYÁaóöôŸÜö´MÝx0g›s§/›¸4§A°rð^w9ZÙÆé7ìø÷ çï6Ñ÷Z“!ÜöîaJõPWNaކFÿ‰_¥“ß(E ±C½³-Ë/¾a +Lil²$H¡ÅÐEpÑ(°(Æ9—k‹¸pÆcñs`XÙŽäËîë¶Ö`]9�·œñX3âƒ*ÿ@šsH­Äç¶°ª†Í>dBGaãÄ­Ÿ›šC%,bÈ3!Ÿ|Õ9+„#ñ4¾%²È¡šÃØšî& œ}äƒ,­[Y®—­´Ü;~»ÿÔüæ^Åíü»w›xnÕe óŒqÎÈË…V?Ýgv³{Ñ®Î%±êƒBLï[å3{&ŒÊêÎ…cAZÂKã`‹eŠ>Vr—±&Ö1]+6Å’{ÓUÊ$˜O( xìoË®KoäËp˜IÔ¥p#2JØ·|›L« CÄ,²Ç˜³XÙ=wÎ�J™âL±XŠ9Tþ¹ÜÙªôx6î+H–E˜–Ø@™Âh¿Yg˜Ë`è º÷£ŸËF¬»oi¶-ÛÓÚÌ2¸!ÆîÍgÝŒ5wÄ%ì£o€m¨û5óYS,\J{™@å°­”=­Ð o #»ÆØS+޽t™ky›ŠU‹Ç щ±.4 Ë:Ãx]bÙ7¨0Å®0Š \…øeªã¹¦¶P‹<} rxò­(^Ï}#aÅ„2Š6–HØuÙì3ºG¤HA™ZgöÅ7a˜Ü«â.¥¨«ð}nÖæ·Ù«`ó|…‘\NAÍÐÍpýbi¶‡M»+¬ÖLò›¨F€‡ûÉûƒ}ô³ùÀÍ:.»µOlÎX˜ï¡Q…4ÞR|'Lå—oÝ´½Á?º_q•ÿ«‡šmŸÃUf€Rú)}#÷�� �IDATÐûmfÌYS…å`!G¥BÖìYUÈü¡­]„§¦ª¥<c6dñ<³ÅCÍç–{„ª4ߺú¢Y…Ζme™Ñf6Þ­iÙ~‚Dz¦ÿ7z[¯B[™™–X+]Mn=ª‚ý“–8ÐuÚÿÍÛÇYÑÞÈÜZ“ÏŸ¿•_öüÇZÛóÀ_öWKMÛm£â\g¸¯nÏúÙ¸å¦6en\÷ceVñ”PÛd$£M<jÑ#UYãFÁÉ2!Õ°½®ÝžK­à¨<ѸHkv® Š+( ñ›3Áº‰Ý áE;ؤd©;­ê IïßÈ—÷´¸ë¯>Èc ZËEÉUIÙÆIõÜÊbœ*!Öx7“ŠHK©À£ˆ`v4%ÆG¾ HWìP7=«Z?,oFRy4 ¼½tK=¡56ìµu7ÛÂp³—šmo—7 ZûϤù•ep»©7²&OØ ’å¯ï¾\0tˆxü–bZ§á»#­»ãV欯ÆQ}špr†#ÍªÞŽïø¢‰ýwë| KÉÚnv’ec¤Â«©øý 1›Åk=Wi÷©ÛŽ‘§ °ÄùÐýâuY_šG˜Yâs[¥”R â*æÀI*ü(L2pZµ§·I.N–k5VZ‚ÑYp*÷+¬•§Ù,/ÕØY§SUîG«ºÖµ6g­Ž)”Õíà§úL²¼eÁRpåöaU,@ëwK>}±÷ u°µbvï}ä꽑Ëù„‘oðFnG¹˜º Ç,ä‘Þ¨"ŽÞÅBĉ,äQê=r"r#OpÎiSyEϲÄË#©Í¹Ó^ÈñùRäò4ïÇõP ‘Ëô~žÉSû¯D¼ÈUEæ,Ò+¼•Ëô“«AäVNNåNÏímzôgòNä2½#ÿF¾¶‹ËÕWò­Èå‹Èùú…ŸÊžÒÜÞʉÈÕBÜ W(>“ŸDä…|s*w/ä›c¹äêßÏ–ûU>äê|}Ÿ+Ïä/¿Èçoår!îgùâw"ÿ&¾•“…8}ïÇrw,w—ru*'×òôTNNäö™üå™üåTNîäø|~)Wƒ\½‘»yr*'ŸÊ¯§r÷N>+òF¾þE>×;‘[=ù;9ñßÊWƒ8ýÉ©œÜÊɵ<=‘Û·r9ÈÕ±Ü]Éå ùNOæTîâ>“wƒ¸rü;‘Oå×¹Õ—¹úY¾ñúùëÙŠ\ÝÈí©œ|"ÿ¼•“¯äÛc¹¹ÔS}+—§òþDnã¿ïNäVd¡õ‰Üþ(×ä±Ä/1¢Ú¿ò°Ð«e¹‘ã!Þ€‹S{wñ»(ñõ†:¾‘'7òdÈW]´ñ½äkIÌÃäò­,NâÉ]œ-¦p@W×b™¥i1osïfy±¡²a™Åùc¨´V¶:Ü+í¾ÌîíÉiûe.A×Ú¯I¹^«wÙzpV±hN�åT5*Ä˳\®Ú’c¬¸ô“µ­ ®ƒ ÁA«Ìf_ÝTÇÈ`BåsMÆvl{Ò¤óQãpŸ?Ãj•¦J<e‘ý›Í2 ?„#;J@’È;ž BUǧÁ Åê:mëDÄZðØ€x3Öl×Ëb{QÎÚkb¼šÍâk£™,ÜæÕûVÍÛ¤‘Ö¶Ìï©Å»ñev#Ù[ÜA¥µþû\¬z†‹Öñ+m 6[.¦68›ªq×™ú:°Ÿ›]†¢Ø2¿MKX*¹¥[QG⇠öï‘G’ö¶Oì.ñ~ŸÉ_ôUnäI:`Q¡œF6L¹Ò]yzG ‘«Sy/ru*wòH$,t;+'Wr)"§rÇ1Noäk#·oe!²äJû£üñTîNåî6"ÓÈâDn/åê©\ßÊɹ[¤!ß·r)âîäX_âDnõ¬>“Å}f´®Nådù“üUö;ñWrùN>‘AäZž>•ë…¸7r÷L~ÒjéXî~/ÿPðû³ü›“ůò©þû3y÷…üìdq'Ç"r+'"—Z“ý*Ÿþ¯Ãâ[~#_¿‘/ŸÉS‘ƒ9Yh™òLþòV·rò6žÆ•Èåµ<'‹·r©uÒ ùæïò‡;9¾‘Û_äógòô…|s#ǃ\iÍt*'§r§O<•»å_¿•¯D¹z+¢U¦žÉ‰ÜŠø[99ÄÝȱþ\«1ý®”k­i‰ïîÀ^W¸„Ø¢ðFžÄï=]{"— ÆÄ^f2@kkæ +Çwæô®ìm~¥‡í¹CUËÔ‘G³é9×U‹ÑÕuåz.?ÿc˜û uáúO÷Kþ|å“ñ¥0½¼»ªz(ôHy7ïí¸ÎßuóÉ·„¼·õ=ocŽªb~âœc±üŒÛ?ƒ5_`¤÷ —X¯…ZA¿dÊqîšUZ9q•ƒ¡+•öY»&îF’µŠâ~›r; BAÆ"E¾q£×C1ÇJ¶ôeA?¯ïx{*ÚL,g[ŒRˆ,Ø¡ õ%ËóðÁþ"'ì­Uô“šj@[¾74„âUŒ|µ.rß­a{‹Ïþ,ƒc•Öö@Ë}œ°AbMÖÏpY&›Q:Ò¸õKþ™¢ îq씌ZæÇ IaÓä×µFjê¹+×Á×4 p²“Øþ¼³Ë–qäƒÝYŒ»Â>•§‰�Ô¿Ù¥ûåáP>ÈãûDI4¨Ëº®û,ÂæÊþ"'°7ĈUB/Ozú|>0òZvò$pÀ�{ üÀk…#3hU ÏÎÉ_£ôdµ![ŋɊ,Li‹üIÏA-�ø‘bÊzCÌÆK®žH¹+d‡½Í–¹ž‡¶·SÇÞ0ŒÜznkƒ§~ùÕ`“ø·%ÐÚ1D¹½v¿y™0K&–…æÏ÷+'ßò­ðaRŽßÖè5ªûSöMÚ3gÞ’9M¹³§JËqþ/æ¢�3¨‡8sDKšÄâÆ˜×Ž@GÀr6TvDŒ‹�0vÄ€‰P­"îSsŽg°’”p` L7x “ËúHÄÕtWÌt¦´0 ô}ú‚ê6†®X:¶ Ôƒã˵²CÇ#Él›d½ðý`ò½Šš;žæ%ç[»1×oÖv‡ˆG­r]¹»Zz;+[0w_êWkew­ÙÓÚHÛÉ­}œÅ–ÏðAJ1¿ö[@Çhò) KOƒmoÕg W ƒâé Cs{ ©ùÄçpe»zé?Ÿ~åù)'rÛIò¨E’î‹eQÚ$gòÓ ¢°ãÔ…’ø}äd ™ÓFÈ©¼Yˆ@—¨Í¹ÕŸ«öLDžÉSí©¼ãôä™<½”+ΉHêKÝŠÈ[‘ÏåÝ/â^¤šÊµÉt)W q/ä»_åÓ¹äJ;aoENävy#woäkÕ¶ r¥Ý¯oå«kyz#·äÏäÏÚ‘Òƒ.ïTx-Ooåäqª\ˆ;–»Ïå¶Ö.åê|ù…ü,r9ˆ{&Ñ“ÿJ¾½“ã§rý;‘?É_õ‘§òþ­È¯òé•\ªó…|óB¾{*×úN‘Ï”køý,_|!?9•;=á§rý™,DÞÉç¿‹âþ»rü'ùër>®ƒ…¸;9>–»Ïä¶ÙNåä÷òS¹Óïî­È·òÕ©œˆ\ªb0=-´ø(¾ÑnYRu¼ ‹t©DP¿YýG¼Òµ´@S–.õ+‘ËJâ«ýªEC†š;X¾hŒé¿oä ë¹÷v®OòˈkXíu¶kC7›{ ×¢sÌEÿ…KÃêžõ´¶”ÆûÑeh-Wª÷·]®£Ç›óºÎÚ/ùN½å»•Y÷%æH]}MËØ_5ÞK#¥’Ç˶„ذSÒ®5ìÉ[ßrß( èÐg²é!ÂP1l„<±IðÚb³%õ‡ŽûC,üã˜G–Þñ«Û±-ÏE!ô‘Ù;ÔŽE2$˜IŽB¶sÓŽ=àS=ç BUKL-ªÐ³Ü /"B˜WD’ È®\Ç£2¶³êMƒöBêèj©ë­üôªd—Özµ—ŸWäªÛEùï—1¯YV¨ì¶¹n?@OkÏguÝ^"Ð’Ýf¸>7ëâë™ÒNâû—(Òó^ëJä}ë6s£·´ +cL}2�û њ/7LÒâ,àJ‡í+«\ϼ² ÛL�˜²CWŒÄQjXL�Eî 5Á ‚*DoŒ»\BZ Ö¤æ¨Ѿ”¢ PHÌ.‚l ¥˜Çé!÷Uš V;ö‘*<é¡Ñ,I+%éêˆåap<µ‹˜ï`XQè7üº†Ò¥yÁûª³[æ¾j¡3aäz«ÁFÆÜzð6ÒŠë>w>hí¬^ù t›æ×F²öøújŸmsƒÖ|cÊw¤ƒ­„æ¥)Åý™áÄ~P­Â±ðÔ)Tý¾Z²iê>ÃXyžé4BŽ÷Ê wÛ÷¢ ©J5,R3r• пµ8»IÊ£E„¯â¦îS/ XH½‚¦ƒMÑ=l÷ Fº *:æ5d2<ØÝÅÉGãöF¾ ç"Iñ…øƒ<N{ a‘–2Xèâü—Á À<žMFŠ*‡EѦzÎX ãKÝ ß&i5¥uÊhÓTPZ½16kö Ä ýªnÛ‹Ø$­³¸ù•Ak©Oa߀Ç-ÿqïk'%vë_£'fW]íJ 7ÒÔDd¡æÏk(*K(»çùÐLôßÞCYEÅXaòÚ(žXDðéÙæŽ}üð,VL{ÆÁÄFÇdã\x.x0lÑ•pc—tæÇ€[oä*œ›¦e ªtð(ïÀ⑌F,)ÄËMñ£¼ÃgËAœ-ÀŒ†‘£Íì@HÇL‹³…£å“MõSûZ�«wQeeuAöÄ®ƒ[2±ÑìÐ!S2 /Á·,hýfªŸÝ4çS½nmtëýP:dHó~hù1›êdùšò\ssí¸ñ‘näÉÖ«ó0C2ðl$ÒÀ<a£™6{ ­¨'S½éÃî©4„Ên0"rWô{l‚pžõAÝÌ#Ï áƒÃr" § ÝJŸE!^ùäá­Ž“T;Œ>‹L,TH¤x„NÏ™aÀN�*úXP&yž@i‹î`Q¹Òk,n­‹ íNì֧Ϋ,.Z{±õdA2êL]ÄKJ‡!”ñ̹ћtØm°Dk4‰ßÎ'»íòÑ/9<ÑBìa’Ÿ÷Y-+‚hìãv¼mT{Â+”§Ô™ÙìÏÈ…¤" ò°WbÒ“y!&ލF᪋ë,ÿ \™ò{Ed†Â†Òw¤áŽÙöˆ®¿QJ¥¤­÷¬Ç´ä›£4áµ<¸Q<cÁŠˆAÀ"†Ã¢ŽôEˆ põ˜3‹DP6é‡ÀîÀÖÔJÄê)8fÌ~G¦òæ‹Ê çßF�+·\…ŽÆ5ç.†2#­HÆ’~㪶cvýsóúÒ‰ ó!Ý6ñiSOo[Ü [›ÓZá¼w¹½<éÍ=Ì º5>g¿<¯èjõàŒ×jùƒaÃ>F¨ÝÂñ¯ !v‹íl¿uŒ¯FIJýÄPÊ@„eʃ óõ ¯ªüª<‚Z´‘8´‡RT¸Oö€dHïQô€cD' à‰cÃC¦:ú:ë‹çxÇS·l®ËDÈ=ÐÃãQÞ%¦ÎôA¡ ¤v‡ë<Μ'É&ý…å[>‚0¬,ÞÅf ÛÚ\Gßnp†•“C¬Íœªë¼ 3s›Î\½Ûí¸ñkä-ø.vۺɊä©Û°ÍÍ>Ô¦42®_½TN~vAìZ2­ºÆr­¼†‘ÎU$3§*õ…çµ[lî™Ù,>Þ {âÖÐøqø¡-¼ …òäëÙŸ¢æôzT Z(ãÈAÃ})ü§ïýƒ<– œ¼…òì"[ 3Åêö¤ >yfQÿAËGY—‚÷ÈU& è…R‰9å‹#•ì9À…ZSÂ9/68&!Y( kcQÔ["e=Í›ÏÕm¥’h\«•G³Ø®ØÈ¬U¢jT/0e kža[BþcÜÃ>Ùö»z|ÎÉu)õ0~Xgî«0O?ǵ8Ð%•—TÝ®e¿Ê°O,g§~‰•iXÏ:¬¼+®Ø"CŠ €;7ЈsÀ•¢$éàý vàÊŒy?­b&áÝ®p¥°æ;tÀƒ§¬X1¾XR<>B’,Ä�*žýB–1º\áP`ñ¶³@8ÒVH ÉÝDvÛbÔÄÊîZÜÐÐŽúöf¨$ýŠˆj߉d«Yôú C2ßB _ÐõœÑ3}Kîn‰s+…FN¼Ü–1æX‹‡’õ!g±ã/ªç^Ψ —µYt¾#þùbôr\´È÷…‘°ÈÞø¯OìKt@F�·©~Û§ Ô`ÂõÜ”k‘«ÓGïå‘È#žPþÐe4ð Ã#'á@är¹“ãS9y*×7òdˆ¯+?Ê¿ª‹„ˆ¼c²Ãp"òVä.Úa\¾ã÷òäR®œ,Dܽü(¼•“S9ùE>?–»9~› ,DDs°RR×¥“Åÿ9üî'ù£ˆ¼ïÔÂÉâ3y÷F¾>–;gÖ®äò߿ʧŸÈ‡7rw,wŸÈ?ßË“¹ýDþù‰|øDþë—G'ÏÂO÷äKùŽ.©«kyúN>ÿ“üUóù½þê­\ÞÉñ§ò«ˆÜÈíïå7rü©üz'Ç_ÈÏoåòsy—>ÑĬ¿ËN#Qyý‰ü×ò¯ŸÉ»K¹z#wƒˆ“ÅBÜ¿-®å©fqÝÊÉ·ò•Èåäïú¿ŸÉ»GÿíÕãã[ùê…|£ŸÉâ­\¾‘»¹Õ/åXîDƒ¸S9Q—7òuÊ$soeñ£\'_9•“y2ˆ{!ß½6í—òÈÝ„'7áÉùRíKn“ÍįÀ2X9 ? ½z/ÓEÛ”t&øs�gzbPui3ç.“1 ©ÕØ"èâŸG"4ñ`1ºž,ú‹óˆHm±j;£~ƒ3¨%AaÓ•ÖR…ŽÓ¯ý¡-5“±^ã0ŒÔ^ãZåË mQ¯'z§nw9k"дxg"¨xºíj@Xì`fàV(#ÓŒÑê�Öbp.w€˜îƒ À(ûÁFO¡Íƒé%I,œ2„÷©ñ «ÔןCqo§ Ø-÷>})ì¨%Z1nU´Í¨¼ó( âHµÅÓ^”ªd³ËÝ,!¹ @B †ŒŸÍÊ*zKž¹Øº—¨Bo¨ÅRCèì¥è+Çä¢}UFa%†³&ô\ï¶­rŠó@^¢e-´[¾‰.³G’7RÛ­“•Öš „ó¤6î q°ÇÌ!§ø¬6yçæmO\çÁó·3®M –ÐB[ª°¨**I[K0a!Ñîà…|W}q#^\±ƒËY_jøVàˆnä‰nN“a îL<JŽˆ|Lzä%zÐ]Šx¸¦²æRDŽåî…ŸÊû+¹Lvˆ1½w¹’Ë9þ ÿ¢qV qo£¡Ë¢SQ%ïå l5éJÿýT®åî|­åÚ•\ª÷ ºþUþt-Oÿ)Oåä…|óY¸}ôÿ‰ˆœ>zÿã£?~xôXÂÁ‹ðÝgáö©\ÿC~ÿT®'þùðB޵¤»“ã[9Ñøàï’Nò[ùJ½ ?•_ÿ*z'Ÿÿ"ŸßÈ­¾Ñä-y~z~z¿Ê§ïäópx "?%[#µ[õQÔúÌÅh±ËK¹º’˯äÛŸå‹åú©\kBqÒw\}q!¦ñÊj~¨ÑÉú%žFÁˉÞD_É·É%2ž‚¾Mõl|›?pMо:Iö"±F z´K ôº‹YÒ>ÕL—éå°u¸Jµ‹~¿è¥=“ŸøjL—âA‹ÉÐȽÍpÙoS³ÛÄG52^�¹>é2?éø`™5ÄY—Å5WÑÑ஽—¼ì=°¥|ÖW®ºü¼Í‘”û¾ -.¾Ùå’–‚£×µÊõ^q(UÈeL-Þ#ª(.ц1Å|î-µ4ZRØÓA4Ï…^šã¯$—,Î:zžÌ…`¡Í»·~ê÷$¦‡lÖïšN’‡‘“À† Q{*¤¸’«%‚(õT¯oÓ]ñ‚>jSV*rVQ~ñ' ëwÖn°¹;[d%©§£ÈÌô.‡x™$çA“¡ÊÑ÷U¥Ìôn¨Z%äG«“zôª!G²² ßf;ÂHÝ6²³ÜHÇÄo¹^Úå}?Aký"l¯\0Ö¤ñ·¶ÁŠÖÉ=]¿‰`°­Ò¬KÕa.‰;ÛÙ’¾ ™TÉ{¾µ¸¸* ²¦‡1eWÃÀ€$D4™D ʃR@+Wsì(*Ou/BP?t“XˆpT Ž•Š]<Ãô•>7Éäãå*A„u¡ˆG¶�¹{6– ÂÃ[:ó˜Äú]+ê�} )š 0ŸBÉ–íÂy’ C Y¦Dߩ¤Qа›ÂÄ„üÆ|G+ÖWN˜¾R¶ïµ¡A0Ž—DM!ƒ›=µ äpýñ²• §%Ûk€–Û' ØRÜÙjç<Á5·†Öñ¿ðË_7=Y­Ÿ²qªïjúUâP¬ï77†ãì«p,³Ð˜a©Ôé‰çFèUºïSÒƒ±n’xžãÛPaý�ø‘äŽFdë@>H 9P«ª}VîAˆ&–¾Š*Ôuž&‡#®ð whõÕù°7n<fTiZe|û„L÷ô‘²Xý6Ô[ì^"U?4(…Äýüe¡[V8ðt—kÍç««ÙdßTYÉ{}»¯)š0}¾FÕf.ƒn‡+ÞjGs;�­u:1ëcÒ>Û6p¥e/»‘ýÈø‡ì×<ù¼ÄÝ.‹Ìcæ„‹»Šë^_ŠYN[T^'&ÆBʫãºLr .˜h¶)» ÙšL˜Qĸ.å@f…=æ™ð€¢²ÑÕYO»Œê >P�ß&4ΆëA8E!åØ{}<²N 7×·¬Å\†Ùë=[QFQ‰D=HÌu ùo8ù"!%óŠŒ%ù»k w z°q×…¥¯½–\(ŒïËgv:©Æ™¯nw„Ù@yÆìc×£¹þ¹Ñ…Õ¨—݇/·Ì® Znù¹ëÝàü>Û²–¥¤ýìÞ˜[æ܈§Yè˜ÉHÖf»ã~]BöCß¹®Y†b %ª‰yvÀ�)“M<» Ã4œ&¬Ë+ê�ëxk\b9Ð$Y1ù7ò¥rt’*$�@".´¬ÑU4Es( [ 'E)tž�ÕáH`3¸bÛ'p˜è–éñ&¹?§X“çÆ8áŒ1›³†Ñ,Ô7b“ª[vÖ—"¹˜ú[žÜõªpdÅÎήR$ÒE›*ËQ–ÞYÚ°¾|ŸTþ8ps¬˜Ü—x½ËnáÍ­Yií¸=™M½º§Æ^¥mY+}7Â&‰×êc•Ü`Ï?OC*z½Ëñ5yNg%#õ·«RÒÓº@†yE•“+Dð$ÏÇ´„¡c÷?vÛc±fiµlBÆÕèßÕÔ:Bã p±û M¢JÓ‡iу3öp¸4 zL’?8<6µúÄphf“óƒ°n„ŠôCà W–ìa¨§Ñ1À5þ4¬í‹Iðоö¶©é:Ì/Ò,)RýmBŠL“ªa&åx{k¯_Û$ÒÀƘUÛ`nUߤ.oVîÓ/ñÄýbLz¹ÂQ·Ã#¸Ø&­üÜ‘C­zþ¡.æÜ2¡%Ü}-ÓbTëlx¥­r,Ð4':êÉ7×’º±J­à xH×îÂë¹ƒÞ ™$y¨û´pž àË%¨ø Š 18 a•6ðŠZ°'ˆ¾.Ë=´ã*zJ(ž´tKqɱk¥´j8¥ÁgB ¡Øy/™ÕäÌI”³ iAê›b¿Á:d’ )Ö|6³f0?ñC+­çVayàË\ÙØ¾ƒ¦%Û1LÄ3ŽÐìA«ÐkÝ»?ËÆ²ï;h­ö¶ÝÃx*ÇfÔ–U̯�`"/ôÞo}ãùãçã룱_ŸØf8°ÍnNsÐê?ÍîÅL{Ëd:b®ü`ԃ“¹¼Vò²È¡ïƒ™̓º?Êá€ÐË ¡ õ0¯æQeA`*ò´ˆA`éÞ§@©Ò£ÍR*ãÐabõ\œ%©p–U3!•¼Odcäú‚°†^A‹Uûúî §À§ÄðøTõ˜Å6¾q2á-y6B,±#ºb¿&_w¡B³TjÞà®eÈX¤H3NP[þžõË®~CëÒN €­Ýëýös÷±B#´[ÍT4š_¾)8§Øê¡ÿ+#åpð4 ²ìMД#ZJûý‰¡ê¨ÓD—kõä¥0?Œ?B†7Î>F„ œÁªA>@®žÓåµÊ‰w+“ƒª"Å‚æƒ<gªX*bA‚Ïë>*<^,ÁPh‰4]ªP‘ËUèï¡d}&’·r‚‰ºôêG¤žÖ*Z}0¼GÉ[TH­¯ÒÇʼ]LWÈ©µû 'UèI©›JIaÏ;£f¥µ±«:g]‚}2¯Î­±àìû ¹ç•ÖÜO³ÓžÙ%¹Î0IJœá6 ÿ]åé9~Wø*.¨ÙHóÖ[¨©¼ð}ªÓõ2´¬I®+Zy¨ˆ\À[aľèZñÕP6É|•câ9tQ´ôÁ¯XÂk£3Azf„£â,BÎ}^m½–eÀôÆ`Á~/¢v` „ï‘CÖ‘…øièJžõ©U¦ü^8bèßÐ(cÑãrÀ1ÕT[hž3$+’¢Àkdl²°zâ©sÎñÕ¶Ì€ÔDŽV¤¯'.ZO)ŠÍ6†�� �IDAThFiba¸¸'4mœ¶7ûû¥öènåJë£Öà¹ý>™¥&«– }·ò”þl®ßN³81Æ@޼ÍZ\×Xù>gCñr0‹!3;a3%Å[Ï™¬¥."áYíÆÛv™"¥œçá*„%~Çá(J€+,|W„`Ë Ì0·Â¹€Üc¿yŠŽò­ÒŒ =±…¬A 6ð 'Ñ9Ä…×Ï…%Î ¸@•#gš É„>"üòù£+‚Ç„œ9ã˜S¤«!bÉ{ŽPG”;¤ l|Õ‹u˜l?cw(­Pi…RÛ¸²q»…ýñöµî9|Ô=­áü2'°Î$¹[ï%Æ)>ó«éÈPÒƒ­ÄIÕZã[Þõª$¶¢ªÆŸuE3 x6xGƒq^ð”Xöœ$iøY ð€B¶<Y¹Ê ÌÃb­Ü�ŒÛfúCžÓB–¾®ªØ¹“¤eS†ºô¡éëÂÞ%»I¡2ÉEÅDh&!nä¦Þ¸~Ë8%ÌQÑ;ÊFMG“1ÍáÈüEß#R¤Y/zWœ‰Üº;üÔeïZôufƒ*÷[¦.}‡'dølñ‡³‚X×_Cv“›áV�­ßídéßÛÒm±ý÷~0ú¬…½= ›HÜH‹/º˜z i½Dï°j&Ûž¹‘'-­<ýýˆcöE¯0À÷‰ÈÁ<I%CüÜ®„œâðFnä8Ù˜d|zäå‘×c²¥á©Ü½¥ù­ˆZ¸ÞÊ ¼t‘¹U¯UÑ7òõ3ùËò¯oäË9~&¹•“ò͵<¥õTô‘Çr÷‰üÛ ùFD¾’o¯åé§òë§ò«>xw-Oÿ WCÛÓGï?<z,"êTûü¿ˆüIþúWù“ˆ\ÊÕS¹þY¾ø‡üþ|®/ñ³|q%—"ò«|z,wúÄK¹úDþëò{'‹òÍ¿.žÈû¿ËDäŸÿtóÿž¨wí¥\‰Èÿ>üéÿùï/ŸÈûOåWuÔýðèñé£÷òÈýUþô­|%ÿ"'r«g~"·zþŸÉ»…¸?ÈßÿÏáwŸÈÝÉñÏòÅ;ùÜÉâôðV­~¿’oõ½8Y|ößñ“ÿ_ÿ¼‘cy&y&ùT~ýJ¾äj!îWùôFžÜȱÈB?±t•8¼ß[9‘,®¹Ó/ô& ¿•Å3ùéDnOåý ùîFnSXÌåÜËüˆÕ|ö©\c“¾ô=ò<ys[®ØÍ–n^O—ým]z²°÷©‡¥rökŽû³;#··ÑöWlŠY4näÖþpA¿zÂBÄÍå7Ž{ãºy+Ïú+ð™4£ÒÚÒ\”[©mã7Š(;@ÖùÅÓ²¼Ÿ_ûUüÜ7š¦ï¾Õ=î±ðM«'ß3[+\'ðnà“kƒ•“žslŸ„\`‘EBnJãVÅîž&…a3!Ú¤ eD8eØp2áPÂYü�ïSÉ…adˆh±Â &<Yœ©¹#A½¢•S¡\Gù…¾ÆÅxâ ódzd¶òÓ²OŒi3´be#Ûs€#x»ƒØˆÈJˆU»A.¶ëMèå9›˜ä…\”Þ’é’È3pbç½<g­vi³•îú9ÅRYåŽPånoQñ„a²*š²g[zÝ{øÈ§ùôàÎbw-[m6ºå¿c·ÍÄò½87Ú�;§2S/ùÀa†V5_\Í>§ kš•‘ÊQ0S…`“Š(áÂh•myQQ‘÷ &‘‹Ó0¼)cx´'oxÖ‘‚œþQÂÐz€¾ãèáp&ÿ11DÀã¶C_Z‘Ç׿LxY ¢†fRö¥MBŒ{ÎÌby°‹úŠC-žvèªÐ¸;fhÙÍcÚC‰"lÏÁv¯Üºá‘‰«fV–´´c´<÷D›ÀS¸~tX÷·Ö\‚VöÞó{ÛÓr›kå=¸n~D%±²ûŸ_æZô«Ö^óùkטvlûuŽ\ˆ 5 ¹—–ŸXox¨²Q†jhT ×aö„³%<4É <£VÆR¡k`§;(ÙÐŒ±j‚he¤ ŸL,|Þ‹„3Ú¡]¤ÕÛ}.õb §‡™-¸Q@@¯ÇÄÀo8ŠCWlW¡¿UtÑÒP rvØ5…çÂý3øNaBy _JÌAsÑ9L¡C)²`T,Šˆ†É|½¡±Ý£ŒCkv˜æüPvU¥2ar…ì¾eKƬƆ®7´ë`ao_è(£d|Ñß[û¸¼?ÔÛÁwà6þAoù¥ý’v‚+¼V5f§[ÇYù‚è«îmc!ØúU‘­åXˆÿȤN¤œQ5Z/¦’ð“B .P„Å”éµl"«vÖø KÉ•î¦l!¨?xUÀ Öüü({/A1ÁÒŒäÐáP¡ša?\ÖBpXxAaºK•ú˜ƒ7<}ŠL\fbrøeˆ‚Dzó( &Øð—„-åt]!®á=Vvï-¹èœ²ÖI•s­úɵˆëÂf¥´wÍa¯"`œÀÊyÿ¥¶ÔnË ”ÛöʹYÐr;_Ç?¾mÂì¦Ýrß}“ ï[Ë»ù4S¦ŒøÇ”%Q=™ÿ.(Šc¶ F}‹÷9Q"áÛó´2Xí8«Ņ¶JÖŽƒ°x`䈧 °v³y|šJò9Øb:J 7I†`ùà¥ä†¢´Ó_)ȆR þ`Î%œI¸Èuž2~ìÎÜßÒÁ/ÆE­À¸lBß+÷ÓgG¨ìSE^·Åè7õ#î²~R*ë}; åêR› )½PGoŠ‚»fL*§k÷?kÆÑ»+][¶>±­ô„&ÍYaÜ&H¯ù¾šÄ.+-÷[6·lìƒ,ÿ¢“…‘æaüµ|‹¬`±¯¦¾«S뢾ÉEÊ=Wt×¹RyÝf·ÝkscÑB3KÉa�FV@B„aÜÝ+8…s¹OKdö&“P9W†!5˜ÉF$z(Š$cxÄ¢DiÆQ4®ÕQ08¸ß“¢´!O@g¨ø‹œ„ç‚Ðd GMÇ™˜Ø”ôQCÝþA“0•œS7ó8§‰cG›O’™l„aHšÞƒÆ®¢rp÷£‹o-Á(â’¥cBægØö®ˆµlÉq+ÛÏÐà$×k&}kïÒƒno@hþ³N£rN7ÒwýsƒÌNÓñS a-m(½�†Æì½k‘„óMs+k(½š¤J£aÎ ~Ciæ$ˆ±ÀZÆóªLõtT=«øPX(tÝÓ+2¦«s æá0§øÞ§TI-S ƒ@ÿ‰‡«øŠX¬×€ŒqpÄ€˜"ìzö`Ÿ®Ü¡�QúF™À sÇŠŽœ9 ý³3ûDZd9Ì,×IœÖèìзç8[y;ÒT¹s…òV"ÆØWãþU~‰%-G6¯æh6Ê‹1ÆOÑû½H„q†ÛÂÒ·¾^c…áQ·YÐZ]>®ü1YÆ™xæ6Ç­w•4-ÝòoÊõáÇÒŒóûgÒI±3l2zÑ…nØçp&S=EwŠ[­`ɼmg^‘F(6ù B­ŠâÚ’–`Ó98�ª ÀJÄ:ß9Ärpˆ,Ø‘V1 �–µæZ~ …£n°!Dc´í8“¬Bd>¢–ë€v~ êË{*zø$aáˆO•LžŠoÄ[uŸÉ‘AP'„£6¹X؈½IJóP„”ÙMâÚK锨¶å,8«9’>+h¦8*X~¡©åÈmzaܼqƶ+­õÏxLJú~Æ:¾´S·©ã–ë—Ú®0µ·EA!6ø _§ulK©Õ£SJ„¦ØY³uLj-]bȱj üŠOB0ŸÆ±#(¹êH4·âê-¨8eu&8’#KŽ„;RŠ4j-ˆt›à‚l@SJ1 ‰>­å5Ò_°QS¸ˆ¯pŠª¿à!-ˆæ5²Ê{V†¤"™ æq4ÔX8&,í¹öº·£x,Ê ßB3–çËPàGà © ŦÖf%ÅØ–ï@Bqà[l´²ß\uS47”Uj)¿Ð--ÝnÓh´Ü¡V­ÝgbîþÏüµÞÏ/l·Â†îÐrB›¼b|%Æ“Š6lNŠHŸOw-ˆ’ÚúšOÛ&©7¹A/ÙÎ\¨iáx÷ õ]5VÐJÞNíxc¶K~’�×¢lëDíUM‡[Ž·G=¤t¶ÓÅðÇsDIÅ‘ ¤Pà8TE@AE,x A ÈÄG‚¡tze;2ö¾Yâ‘2ŽOå}x)Z&*B6o "‹¢rÂì3wáÛË‚Cš„3µõ@[%î®$>ÕÁùÛ/†yÓr, Ú›#†½üÕ±H¹aŽZ3±!,µd­D2ðt{h÷ð=­É¤ÇîÏî­ ÝWÏT×,ÅB –“þ1µ†Âµë¤ö½mîv–kõ´²fŒíV‹5n0 –ãT 0Š` Ñ4¢ _n¿e=LeÑÉxÔ f¨ZÀ›A‹›—í»"Z*)A§ºs� §geÿø£ˆHƒDÃŒäq¸•f(C¨/ž j5ˆõ!1Ey*ïÃ…�#qÌ\­&©$¾Vÿóô»ß¢–B-(©ØÂî‡S"¹®jt\¾;·¸ª‡–ˆŽMOlñT€™³—}±jI¹sFå^®##lxþö–V¿õ†›±45ÆU· Z¿:li+9)“è¦fÔ›ÎI3nPß{tK”^M‡Pßy/…ÎÊS¹ãF¹S× /–\±¥RIAyag­„%òÌ\V­Š7œ2ÅŽE°$v‘Ís“BÁq7Kz-Y™i ƒ`¬â 'Ö âµðr*g×Ñ`H?`¹«¥%g‹è'£`†Z â@¥‘ªÅjöäÕÃrxŸK´3A ƵHÏb{\$Àéâ’¦‘,W¤da'Á55ðT" ‘rÀ¼=/Uyj4åìÅИôF’;m­&EÑ’o„ºSnÏÖv·‘Jk÷.ônWŸÅ¤‰Ãö˜F¿åOÀu¸D7䨮¢âOºQ#2zÇÖØæ+–ŸE_uăãˆ>,·ÙѬ²p†CMP&!1lË^‚ÔðpÜbÎqžJÔ@ÐJ@F¯eÂŒb’€þ‡vÌ) 4±‹³s¯’>´7 !…RL\xr‘w&á<~žÐÐç0e¬¿R½†*¤j´ÇÎŽ¢ZËAˆ-S„JVur³ 0ÌÅë`óÞ(¹XذŸ~(”ˆ–ó·èè] 0¨Íà+9««¶­inŠNj1V\*8†6ëè˶t˜¹âmjÊxK^z›bìÒ0ñ7Iº¾e¿\‰6í°Y€“«ËUU‘ë{aŒ Zæ»×–GµÝ€³™¯*6Ö†•€8CvðCÕ þ9*'< ó¿ ÷8J‘ dYA€�FX¢ê*Ô�€Š¢Ž %‘þ?W|‚an¸Å't¡â9 ǃ'dŠˆu…h§<Â…„—¢3[ñ…Žò2Д5‡¨ µ¬á|dL§Á¢—ã�Q0û�% ‘ÿ¦ƒPa-Ì+–#ƒ–F®¯äBÁÁWìÐ&\E\—'°4Ÿ>—鎸øòn]®³þ:¼»µú¡zZó ;F¾Doê¨Ï¤|¤µ«˜m{ÐbE,¼…ºË5Q8Ù]j+ÅzQíLÍ€'IÖ‘Ä JË´ÉØÚò†—ý Ä„pýw;¬ð ÏrH´Yí â!–ÓÉ_xI0‰» Áo„–#aå*9ˆYaˆ0�¡Xý:V„Ñ„C ¯Èºé<JÕñüVV,æ’âèåõAH©oTòJ–L�æ o }!— K;_\¸f³ $Ú4§µªF;kHEHA´î v=ÔŠÔ’Ž>Pª`I×Ð@…ñ郈Üo´fÖ {øÇoèç2¨d¢$šswvaC;¤µ:ZiÍéfLF7}b¼ÝÀ²¥i3•¸Ù‰õC ºÉ3‰GyÈzUlÛ̳/Ü@í¬XcOv´Ì¡/ŽQ|Ä)Úô1jCHeÐ>h…Õ_!$¢ÈET*_§�ÃZAFñ†þã|ž \0P*¢pwOc�`pûŠÛl¬Ë(hLVý d÷§/ÇÄpnÄt¢^ ‰ [¼³ìŪ í*Šå»2´ ÒòímsÅŽp˜§;Ðü»¦"ÌB74«Z:zJÝ ckÂæÁf)Ó€³@ë¡Ãí„ܲSÙó3_ÑCk?Åõµf¡BŸs“{«Õ þÇŸ>iS¿_Ó*h1-µ5Tjƒ› k“B  .¥ÆMŽg‡¡*„µà@vy­×PpUj.+A€{±k…ß÷BG.Ä1dÊž‹r•ÑZ ->ñu|�ŒwU^©!ÈC¸4Åq«ÃL-âYJQÆãŸ ÷Ø`ø¤çŒŸß§ouj)òwd}1ru‚O0j_eRw¨ÃhE©á [<4¶S=Ïܼ[²ÏjÈ‹87Û£­Û`¾‡º85oj?uû i¶ý®Ö|÷P•ÖäŠ?"ºÛ=¹m¾[õ"p*4?FGLÂêÀMœOèÝoyé¯Ñ¥ØÆ¶F†Ån`}‹´lh­¼ØD§Éµúh0=9o­-.î9 © Eœªé¸Š‚莅ìù¤æ{ !�'Tl@E€«Þa_«Có)ŠÝÏt &4@D¹¾ˆ=¯Ò1õñ1E…:n¥Ä ¨KÅ0­„ð-�T˜Ä-©"KPþâ#%—¦<˜E-Lg¿JgfòÒE[‚Š Â9×ékÌh„o]o¾Ã H{R*ý|h«[]g—æÚÝè ­M§Å!Ûo=žÆ­6nûËàÜ'î=¸‡«çË4f€})wªTÓò²žÒa¼ó$é?Ùœ4s2ûPtæk±É~úîxí°Zdg;Æ ×ÞØ^¬JbkÞn#ÑQÿ+f›8wCTºúk¯ ‚o•B@˜MÙ²»RF¦CA†=¨Z·6Òµ(hEàA©¤¿Mv‚á<ÖjÈÁ‚ð]‹0Ž�nõ](|j醔E•±òÐ*Wt‰–ÂQ*¾…Æé\¥/uÖÙÓEË-Ï;ŒrÓÓàå\ÇýÈUƵ®"½¥2y*šµ¾u7Ù›šÍ?§{T.¢éGuˆÊ]ª¸§µÙÕü¡RýGðK‚PïÒ/4—ò¬H¹`ÅaÆSê'Œnn™˜f_a›ëXuøªyàŠ 5\–fØ€d3y¨Ï…r¤�E©;•­.Øc·pσ8(vuÂ?PNñ”U.YRÌ£º:!7„½-´ï¥.ý;Î H¼!Õ=ÑÃ"õ·ÿÐrÓÒ )Y±ð:̃Sñ gù1x³Ì1jÖ ˜m¥"!y”s8£qƹÐnÀ!û‘­_{Ž’Êé_0„zo!¤Þ÷¸‡Z.¾òáåf°ov¿F]`:TàVèoñ§ÛWnÓkæ:ÙŒæn•Ö²úH·Ã\–ˆËBÚJ™&#¸RJÕ›¸5eÊ^ Ý Ž×·Þšïìû˜ÁËD Y šxÙòÁž[àãðêf$…”kå9Šžçs‹ÈÔDñ<‰•µmAì«ôZ,ÅR  7*'Xü0DJ=ÚNð°ÐÂ+Ï_ÏóâÊ1r`1j2m±Fý0XZ(ßTÃ$2œ ÁûÝK¶d<]™3YR˜g=ã{äa,8nˆ5>>1~Fï^ú #ÉÚ$¸f´[5è{LZ…FÅøT“‹ïm×ìðþŸ¦nÿÕWï½õ˘ Z[|>ÖŽ3·æè#–¦[¦Ñ›å'‹Ë·mú×Þ‹…ê¸É6Xk.²7çß éèì _ߤƒŒz80‘Â7¼·K¤9ÂÐà=%<1ƒ@HaˆÒµùñˆ’BÐ0\-"Tœ ­Î¢Á¨<Ê£»ú`ƒ8«{‘ðƒÀŸVOÜ¥(`Uöt?ŒrvÕJÄã ~•yËT*A¡…—˜Nú t%âQàsuÉ‚l…f¿ð!³71d…p†<27&ÙS±dÅKá«q÷¯Âˆ…Â'yHKªÉô}]íØòh ‘ ®“\,Ýhãл•ª»2¬°tŒ·¸vŸÛþð•Öî Ï­î&Üä¿ûл¬¹äd*±ëÜUªô&rÌ, ýÔ…ë;¤ÊœJÔu8Æ‘ÁU®Ñ´;kRˆÿ¤å/?··â\(B?­oÿáá™;§Ýî l8 …ÆÍ�1±‹ùå2±²ëRŠÎB‰3a½þ$jŠJÞcQ•8CEA>i]ÈI’z|8t ²ÞQṳ̀xË –¼Þ!íïˆ4˜[ì6ªQßžÙ mâÓn ·Ó³¤"�]ef(µ]ÅÐ@_Ã7ºSËEèßJAúQ 3É¡-‰×ÜáAèÁm‡f¹5>îMål­;«|hU=¼H#FÞˆñFª?.Ûm)­šsWÅ2á)7ÄÛž«6È æg(ß©çUf¢Ø~0¹$ˆÈ©%€ nÍ/¢bâ(û\€!ÄXUTëg‚!ÂÑöH w¿=à7U[�3´M ÆóT¥ fµÃÉ Þú £8ð¹ Å8÷´Îc‘."@ƧŸ‘Æa6ìÀh‡,#'E¿&ôð ï bÚSië[sÄ~¨Ò†2b‘/~ŸÿnËŽêâɵìMÐÉP^Ìc[Uæ“[÷…åÉgO§™ûÈmu¤ÜF¶ÜWŽ&Yj‰ß¥,pKP·Úoç'u.{|טPñ$xp‰^©ý³Ì0r5P9~A»–±›³-+©…òu˜ž©´‚4C›<˜‡7LjèÃØ9·H GåÁÑ Ê8ö£?,þÆ�ò== L vGf#Ñàáƒ<¯c;*ÃÛE¬g³]*z hÏSYÑ®‰ yuÞ ±Åú¦²4ÿ"ªêêú*h•© 濘èÒ%ÇÅ([ßd(ÌFº¤®zñmZg¦ÔRbý¯5³Ë‘'ÂZªÎ¯UeYU©ŒUø@f#†~wèÚI»1¯¦ª;»µ±þœ–¯„-»þ³Õáâ¹Zû c~;#Èù@|9üôä¶µuS§T!™Xœ›& }k¢E*Ür}ú(¶s{ X6ª\Ø©Äñ¾è½aH ûhІiñ<GÌñƒ0Íã¸)p_J…1Ÿ†¾Žöà·!ä(µ¯žGAxÚ20èàŠ'˜{‘ˆ@G±ô1GNEËÜõ)pj’Âç±– A z`Y…˜¦†cùu”Á­¤T¯2w©Ô\”ÁD8:ŒÊá…3“ݵ˜tS`Xa÷IVÙѦ¬ëPìŠúvÀÒΠdÃ9º-éŒí»¹Ó–aÖÚ;:ë6Ñ}— =×Ä·^i­-ØëkMLõ¥9E·HŸxÂC¾n¢b s¾;búÖàâ]¿AȬȜ6¯«\D±ýlX„Ø2Ëè9?žUì¡ÀƬl+ý:·»€"4--h0¼…i-‡¬V‡™¬2x`Õ0&¬ØƒÂ%ëúÎùèxEï,› b†B8\„—±ÞНò:Ñ}ñå3^e#ÄX0%«øxÌ—Yaˆ!0Ø^d©£ÜÉÓo Í9ÎJ¶ÞŒìx[Ï̹ªL÷¦]dÙ|CcÔ]êñ©j[“«¶å­­­"_¦Lo›@(­x9_…ùæšO8¬¶Xù%gƒKúº4ã>æ>8¸) u£KÿüWwízhÅÒÈN­£ Í&–ŸzE××Pˆu­•–µ ÙSH½©LÓ<b™W¨Œy6¬Ã4+Ù.ÀIÈ®î³9¡G0#«áà % Ff#(/¤Jj©Xëµt»OĆޣ3Óy¬¢0Ú=Ú/rg ’*,t¸8ü-&Lª¢ý³Ay'ÀÔ® Ë ¥ìæÜ‚@‘ýE⯔„¥ª¨ûÄʳ _¢ºl@´"4¥G.ºÞø\ä!V„Z>™ði(;LEîZÁ×ùI7Ôþ rÚ©ŒM/Ä.ؤea”Þß<Ì´îÊ å7¶€®Û�s{�{Ò½šë|ú±ÏÊ5˜ÉЬ{F>g?kÕË žf˜ëðµ‰_•Öè[öÂÐÐ N}Ã#£p¨Uv LÈôL¸‰H-×åwñÛdÙî¸ …Ö„hœ ’�bå¡]A¤¨*P—l8ÏFtIÖ‚J*"ƒ8üMY•ÍŸÝwAòŠç±C.$¼UX¨#ÿü(>^éÇòX]3¢ËFò-ÄH2¿PüA‚ˆÑfnŒ)b¡BÕƒ`£À›6 F)ÙãFW-øãûŠ Â\]ÕiRµoE¹ÊîÒµ’wj*Ûuôù6Ú´¦+¦3ÈÑárhY&DóÛW»I@\kÑ^¡§õ±L¯o¤$²ô¥Ð.\Z–b~Þ[p’ÈÍ«ëGG†kÒ2LR¦ñLl‚‘XöÆh.:Y ~˜(ãʸءt:0óÈÔ÷òC)�‹Çç ‰ X»xø�Å,¨T™±Ž@R DÞQžÅbkÝ(ޏˆ.Z<A"Eêgyì•ƶÀÔE!ßó4žu–ÿSŠÜà+Q”Ê}2mƒ=]4žDÆqœt& ‹ÐŒ¨ô‘=«Ë‚¾Œþð‚„9ˆÐpFªË›N}„[RÑÚ.[47/©C[…ÎÈ>ÏÛ«±~J3•´ya×–®¥°!祃;.ŒÖ÷àpK–zîAèA·GØø+ºÙÌÀünÖHùå—¯ÜG â`zfÕò||,öëŽt¹Wå›y(m³i,4§Pæõ ² –‚MJM”LQB hÁÀü2hî9,½MYu�� �IDATŒ£Ù3$é<ÔíðPG½{$…„³ks†Yªžè>t¹$Uc o9ë<Yñ)œ%xKúÕzÄêMaì"c˜ŽB³á“Ö‹9‰@”]†â(ªOýd(¢,÷Ñ D™… ¢5ÓÝPõ*º¸ÑŒ¡s€ã˜ÚuU„¯¼ÇDLêMéíÒ[‹i«']2̾§]–Eµíñg먖Ž&Ù ªms¯¸Ë`I?™\·Õ;ÿ0ÿÄüÄæ…µÂc[Ñöo;*_™ü¡—L˜zQ!^…>ù…7ÏÄsƒ$ ¦…Sq­ë·šf3*d¹<¸,¸g5ݹ`A‡ãÐ k4{#n‰.åè„E»ÛÃX]Ìf‡Dè%qD|שÌR~OÑèœZbgÆâ_¦–ØË8ž¥Ú¿xÀó\Û)ôjWO±”©~€hD¡ÌÂ!ÛòJ%–ñ¬Å°ìn*+&írMŸUµn0cȬ/F¦¤åì^€»¶c¾Ê¨G¾ÜèúÓmw =ÿš±ûZæ¹T¯¶Žmdhuµö•ÛFOk7³êr÷ßÍjGïåºYÚ ›ôÁ ½K¿ÉÂ×C*¾´ÊT»`!° gÖnµÞÛ»Ú‘d#çS HÐv­\BCÇž­¡lú°#§»¨§‡¢N`ÿP.°ý9œ)`¡ $ vèîÐ.R„ÄÅVS2¶€žf¸` ãXÕ+ /%¼JÍ­WÔåz)R>BTÒ;µ³…yç<kü:âœÚ8Ö á‘¡í%ÔO@)‰À؃¤´Fo¿/Røô`o¡%ßœƒÌˆ%•9Sÿª.—)æk–»#ÁéfsWB Ýoõ~I’fýȯ± ú-Ù£ï[rñþ7É6ëY2þB®ýºa©bkêúcÏ[‘?vs:Tƒ)U4Qí“í[=0©zà®±Ð$Ó.CYÓ˜¡m»‡”€ÛT»+Pá'˜>f’P×PµÏ€;¦na‹v—–_˜\F¢±d¯‹5GësÑåʳ_˜ :L¹$ÏSiu{`çv¨ë(uª^KøOŠé:LðöR~”?†"Ålj”z@VØC1ˆ~˜þ[ßX;£{‡”?pl#°cÈc°¦”;¡eézi�U%Ô0·­*xiAZSþ×3|)Ø×bïíÑfÍ«¬Üpoàíl£¿n=°hm/Èy{MB·[¸f«Ón=Ü(Й4"xßÙÝøÎ~­ç¼é[”àfÜ×s—–¬¯#ˆÊÏ¿5˜å-ÂÑ-W5Ù7%©$j îä9ˆÔ¨P?qc *p5%ŶG\=“„ìˆÁ6€`a¯ÎÉ 9/øHt|JµJÁa:*+2^¦~Õs ÿWbOë<‘‡Yv'·Î%†@&¿Œ(9¶iG~ˆa¶™O]1˜"É´¢ŸÂ0…v�hõ‰p)FĤh·×¤¯æs=‘«ýTóÅ ·Q úÖ½ã­à°Ö:é¸=Uš£Ñª¶[ «V‹äÜÆ‚ìvµ¶?Œ÷àÃÀïøSˆ‹˜YÃÎG>Ù2òµ*­O8ǶÙ×7I}owbˆEÊ–uáç¸EQذ©àPàŠ®ªcÈËf;nÔÁNwÕ&ªÅ#2Î�>‰Há~‹þ––VœA =·>3LºˆCLÁ*ðxøŽÆÍ*-Å?e! „ß`žNX– j™õ½„s /I^AŽ‚ñïC ß'áFjY…è‘Yì{ œ¢à†¥õ_žQK1ÇZŒrÌ#ó¨"Ù¤ª�Ήæf$;RƧ„â¦.T<¾B>³™£—v-¥†T¶™µ—fÁönX7#*Ï7\êIAÆZà •ÓȦyÍÝÿÆÁwÀ›íº5`olg…Ô¶FSr£zõFî»c•…¡dâÒŸ>iÊå›]1©åòº1/+6D§ˬó),t¥£Ì@H*Øô‘²|ã^rÞc´“x.Lp!ªƒÃ±îó*éÙu)R¬GþðBÂEºÒQßèŽñÙx)>L‹§×©ót˜àçBÂ÷©t;J¦M/Á"ñ1‡y*"{Œšü,ÆÔ@lrr |땽ƒÊí.èÆ×Ô11:=gáÊ£ IZ¥tBÈÌÂ^–¬#üyiCã;Í­"¬Ëw_ÙŽ´‡m `¨{]~s‹Û–ê³mi6Znvhg`ãæ9öÏ·_ê¥ÇÿøU¯× ¾CõßÌ£¸6>É/1T^QØVÛ)ê;Í-_©.suEsTf®™Sq©S•Ëî©àÍ¢Õåú@R…”b¨ÛйA†/l™68QQ MÑ0¥„�ö>ÈãpФ£Lú…×IOñ^I8“ð½D—s ¯$üðì< +~ðŠ‚Qyñ<—zñ籞ƒ>^¤ôé0ºUT¼!ÒˆãµE׌ɀ iû”†nMhBœMš×’ Tc©a+ ÒUW¬ïæ<ؼÂGÌÝ›;þ¥$“ì½ß&ºìž9Û<=¸†î«9»y`㶪“5««R]iYF;®³°­qß±‰ëÞ´yL×êFT/²í…´ÑEÊ0I Ê&(/j</ƒYÔ2× …`”{Ç¥ ¥«<Ê— Nϳ¤"g_¥6U6Lü[xµˆ#F¦î{‰¥X ¯$|ŸDƒ/Sçì" ßá·tñ,«/2\i»+Žm&Œ<‹`£‡‘ý‚‘$9Àµ$E´ HeÔˆªÅXBaPR áñäxV^iMG¹Êœ¥¤à¨Ø27ÈÐíyiw[‹.¬Ÿ"å\kÚÒÕ­¸V9åíÝê·³ oÃc[æ[2ÌõÛÛMcÆf?ÜòPºäa'ãJ›CõaÄ�~lz}&שÏjU¡Øš©¾K%böÜâ2a²É‘=¨'ŸÑ ’8œ;"ü—¤ØòªPµåÅ”¢ØíT`ð½Õÿ´¦AhˆQÆC—aý×ó¼p²\ ¯†¹áZÂßÒˆÕE "9'1!Ì2ŽòÀV6Ñ€*$Ù2¡JôB¨boGÑ´L ü²S¤±Ùc8=#è# Lð†‰Mœ±v_y ‹ç%ŠK±ÜUMÖZÈhÄÁ\²dè2„R,]€Ææ2lc½zàÊiкíÖnXÁ¥ø½õë³M‘¹“EÞd²T$aÿC(ü™BÞSI6_·MåãÃ}Wxõ€§/v -*ÆÙqã¼åDWl¨\ãx¬•s°Ð8Á@M­z¶t2(%>æEÇîœ_ #P‹ !QP~d4x°éO¾§Á,8\$:.ÚÝžE§vm_ÝK²„áÅ÷òA‡ÿHâKïF–ÂkëAÙ ; swõ›02éÿB–‚ *`tõ°ú³Úsrìÿ„"Ìzq µ¦Ä J\ÞÁ÷v’ëm™ï8SÔ…-¡Tû0ßr)‹ƒuýèÂâÚ®ƒ¡¼×²"#Ôéú§!›T¸µ—ÐMâÜÿÌiCà²è5g–k…ôß®¥ÔeE¦·K«&ê;¶i¾sW7~ÛÔ ·ˆ>Ó©¶··«Î‡íA‹ô“:Çy'Ç1ÄbF‘Óèkn±díFb½ Ð@)×ZU¥Ãá¼»Z õ óX¢Î¨­•&£cŹ„‹È%†çQ‰^Jø[vÄ€–=V]ßKxžþ¾ˆÕ›ÊÜ!>d207®Îrt¤J-rVò…€ØÔ3(SÇ�jj†3áç`ó±ôoxk¡úÁ'Ï× h=ë«ä.ɰ|®XåªI i]Ï•ÈÞ8¹ôˆ‡B‚èFe½¾,ïÂh§ L-a|ññ›^$·|›­1.KöÉùÐoò ÒjÿÌ)×êæ¶ëWWÙ¡€ E¹Ö¸CZ•\ó}ëMÜ ,žìã/'¼²$iuÔYüZ8Ú]lýW<2N“Ìm' ÙЂ):øÁ<0µˆxrNc’`äØâWÙ"|/÷"áZÂuÂ$å µêz%á:õŸ^Ų)JÞ_§†–º¼?O€÷½ Ñ82“/)Í‹ô„¨½xK '^‚Ä]¯8€ðÃEj_´‘%m$à&1DZ×ûÐH²¿ûLPŸLk:°'ÿó³3šMñÊA*Œî)ƒL0–af ä¡åaÖü9 õé×÷Šê]î¥Gf´w5V<5õÝÔFÌõï´6`eÁnôh%%B’¿fGÁUFsñ³Bzˆõ[vg¢7ïl:GW´£8.+âtªó0DÌöQxŠv†Y…¤ÇØ:ÎZÍÄûE•ÿ›j¬‹T’õíëHý}Ç1×ñoI@ø2 Ï( ò,áe³,š?lÄC$W*8+²>©c2‹Êë™<D° !„g7/t7™¡…Ñ~áÆ* !p®··»%!ð3—÷JIøÓ¨*fç›áã®ï|ÖEÍòaaØ´+-?J·¬j±ï6>§µËÀíGåçgc§k-Ü~½—n* §WQM;ù™;GßÙØú¯è¥1òɡŠTu3š3å ½„g˜ùCæô«9L?Ìò¶ì×bãè¡×:I’3;Rœ°h:Jª ˆ,¾OâˆïIÝ~–*-­¢þ–h½#bÿž'šñU:&;~ŸLß_FC&¥ïòÌVåGCÞ‹4|˜Ó)cÅvžûsŠØJcX¹íd³Ö<´òÄÓš!b¨*¬k»•W”-?êÐÊ–†RÑ€Mñö·®ºÚ¥7NÓj,ùÖI¶ÐhΤÊtì:=~·Çе‹h·ïm¿iI7zeÖL{˜µ{꘲wχ'1Ç‹§a3ØXÁ±ëO\ú*L6'×ötCi±“Gs@FBØ¢‰}Z!ÙàGb-Ö>bJ¢¥åÜ¿¾³ÌÂAÛÜÈ ’<ýŒ²ÕÄýUrm•ˆÁ ?$ñ:I-  8Š.‚·.²¯`.ïÎrü£R—±Aõ*yzòÀcÔU±yvyÈ!‰ÎÙ-Æ£\…g‡‹Ì3nmRçÒóØÜô­­Wqµ!U¾ Óª‹ÂŠI*g¦ñòHZxÖ£Ir;1Èhƒ´vS¸/³Ó›ø€–ÛšçÇ:O߸‚qlˆ}Éó^Èr€Ò la½]EÊç’øÑ·à­«[³»V´²]g‡Ë®íõH©—Ê</ÁDS‘YÌ3=6‘ıO.;<qrJÖħ!$ä`ç€^p2$®Ìk¯+Ž[¥Šêˆô/©eð,ÍQ)¹÷©2{þq'ˆÃ+QœËDâ…„²Ým|Ñ 1„^èlÁn‡Ha¾' ZݳE Í£l¼·€å GkâëàXΖۋï0Ò…~Õ“ùE r®®ø;¯Òبµò$ŧԓÑc‹òˆª"Œ7«&äu–e·˜­ïÒä&['ëƒÖÖ§‰GÅß«}ÊÏZs?2yæ~Õ½‚+�]Šo$þÑu‚(}oëZ¯,C9’åz‡ª`&ÿÊddO/í¹#RdŽ Ø‚\­À9¸AÔÎéMH†3†ÿD¼ªþ`ŒË%ZAhÁr^Á#·¬®mÕužþ÷PÂß’Æ]å… W?$bðL²ŸÓaüáòÇèŠ{HÕåfiq¦},=-é@fêË) ôE¤–²‚¬gAщV"fØ„½"  "›cA][_É´#þ¢3hì*VÜuºª®¯†•>§ç‡n ‰LÙÚg…úŽc2ܵ¤R+·üÚkìÖ ù°k‚Ö>7ñ6UØ-+§qó.ßšØ_jïӚ𨋤в}*_}Äm½¸ëó¡kæfU›Á’Q,†lŒ >7Ÿ¨0r\ÌÁ••`¬@\SÒm 8CÌoaÍUV3JÒz*Jé¯ÂÆ GÀHS”i¼Ê©Ä¹Ê9Ïx“G¯iÖꂺ\GIv^×E¬½"ëxN•Ö…å1€|Õ±¿u˜¨˜׌¢¬DÌ#[ÂcÂïšYÙb» cU ]Öf‰aŠ¡)p¥3ö×.5�rC›º;€ìíÿöB±ìbo;Øk]ûÜÍê94SÅÝìÕf÷˲[>çv?ç´ÖGi·¡Ï˯mFâVýF—ŒP -h Õ•Æ/w7ub¥ÔÂŽXù)”-?rcj4ÀJW7’ø“u‚T aYªV/ÈÀúvXØx¦UÓ‘#²Î²¿‘ãƒ_C­Š´Ä‰ˆuúO¯3–Ä‘¬‹8 ý™ø<ya¤æYTg<¨–ÅŠ áôßY^$ø_==äXIÄzþ°¤è‹@H#0ªx’?ÀÁJõøó¯Z˜^È"’/×Á¸MN–JMóuײäPF8º>OÞÓ€ôf¿Z0Õí2ÏCuƒXåbµß]¥õ1þ™äâ–"yÝlÚ,UXaaèP‚mÝu¶¥MwŒæ†±§Âj$rõ§ÁƒØavÕ˜'´²S#Ü•lãÆ>Lày*VR>xEýíÒБ•ÖX˜EqÆÃ(\âÔÔE4žàÚ(Ï9ÉHU×9))~Èn‘÷{…‹*DŒxë'{àÒ`T‘GÊŽ²1<r³l´X´Åx³£ æÕpÁ$£GVž¦¤êAÚ�ë\dx©„òÆpäq¿£SúV»Klkª·ì5€'¶}- Æø*1sïfÐ`é9Ƀëì&Ak³Ù_+¿[¿¡kÎÒ8Þ,+ ï]}GaƤKš ¦ôŒq;&1Í®˜ïoQ‹ãV`tdøË!,ƒqÔ-U‰ÞôíÈM©bZ‹Eƒ—„Ó* n¹ú\è ˜IC3L’½«4Ý1é;¸ªGLJ†óÅ|,< = ÆN±qu!á:Q‚¯"øÁ7ÖU‰º„Ö1žá™á‘ª¬åG·(Dé{ѯ0 65¡”pt ãqeµêrÙS ‰°ì0o‚ð]µ«ëuL‹ëÜ·.{gÌy»æî#ûÝžI®/9ÀT+o‹g.klš,[$L¼u*­½mb}Li^3Z 3ÞNÛX³™ž%KÚG5ÁÌ÷»Ð¾rǩښ™{®ò^ó%Wo3àÅã¢ÌAÖàC%ŽG9Å!Å@#LÐp«)Æ=i:X=]8Öed «òP»J˜R‚‡EÕziü–¢Óë¤T•àJx.ÑZð%‰à!Ä8#ç§_å" å³-¯"#&Õ»"4ñ0µÒßÖí‚\M±‹‡‘£Šú fíJ›ÿº*„@Zç¤Ú™·2ŽLðÒtŒ€§¸[™;#á[ny‹¸fçÌMÕUËR8K=qµ5ÖoJ惖[»U³UrÏÍ~ض ó—yŒ[é1ý%Þ¬õh9´û^èr½õ+_­ndhÆ>E:Í*©MÙ‡F)FN qÙƒ®ßI²á�bh.ðoНtTyf™?dÇÞh€tƒ`ÒÀ' Í€u!L"¢|Ÿ¹»¬Ë8Ë~íÑßö ?$?'Îz)ÈV0ËúÃWQm±ð5 â“׆ž@6ç=Œ?WLú–>ô”úM.b4Lž)¶ŸvŒ'Nîñ;R׌rM™Êf¯ÂÖ S¥Ê E½"6J¸ŽÞ6ý3¼…ž‘f¨š&œæOå"/Õäf¸`Œ<À¯º –õH¸m8šÄ=(2=`ƒÑbÉÌÍ˪,#E|®¬àª}¨Ðd\ÝèûrÒ¾ê*©†2ð^*·ì¬+¤àdX!¦Ô\ /9ÁÄWûn©Ò<kðŒsCe üܘ¡á#¬A@PdÔ>D]Qªž¼Õá˜5~‡‰Ð{™¼š^Kx.ÑÄöyr¼H®¸èÁ>C‘æu ~™¸Ç3r‹?ŠöN «úÅZEbE\¦ûXÄÄ,}S £D"Ào°e4 [(ªÑÛtù"ÀsÁ «I“qc¶hÅåê†FÀ[³5ë+O–±üØV£WZ °ñͽ뇭¼ó~H†iUÑü ç„ê‘+Ѓn·h±3€ôSà´ÚÛñK§W¨?B `õd±ëN·ÛieÁ4ôï–N¦C¹Ç¤U÷«ƒµlüyåõ„ Úífy*¡|åå¬u5™ÔG0– ±ˆgÍHršÈBÓÄ‹½¦ƒñ‡¯²g.¤ƒŠ1‰M,˜—þ“ôî/“ÎðŒ,šŽŒjø‹To¥Á¯hÓ~”\šŽ"™:v–ƒ¨ uœˆ›éÖ] õa i˜¡&ë[ÏžˆÜdÊ7~•Æ ×[Äâˆ+PÔßCÙ¯-Éê>7²&ÔL·$¤LyªÍLaõ3šèëÓ]3ÁoM-šÇYZò>Ë?4ê,;Á°YdôFêý¯«6}õ^lª´ï>r¤ÌšœóýÀb7Ec6> Û?ðu<¹ÝÊÝÿšBSW(ìÙÉÜø²ÆÚú±bU0f4På¹–ì¬Ô!;[4¡ÁƒP iåêŠ\—Tµ¨/”N‡iÐøerlÂÄñ÷Tf½"7BØ´/ðb°tžK.};yœ9%C²Ô“gÙÉéP0Ó¦‰bàZa‚B,:Fl{Q_Q©†¶öµv¯F{ æ|ú6CUÇ´Ó»ÜFš!s£Ó½;Â2x¾¼aÇhÆ9ôßÎ:¶;–o™†ÜZôàž¿ù-g«]ÇNû7Hü#}q­Àªï“‘ ÅÞ$yJfè1õ~|KXè«ô£‚ªvÄÁк8f4«6�ÉÑTˆ<"‰UPlƒ`d+E •ƒ+I^ 4uJšAãG]ø©C[O¿ð2%Ù«?æˆÏ e×Úœrc´"ꜧ ìŒà úõ³È.~Ç:ì[V™$„EæÌô'˜ÍÊÙ"!Ï·áóA÷ЬÌÄפ›Œ!4/Ï™R­zÏ6´0¹Òb¼]é`Ù¹Iù+É»éÅk±ßn‘Z&úaˬ9ź<øolNË­ô“q¤qÛù†ü4]Ž×‰¶,ë½Ó0âÈé›gÒkÌÏO‘8tƒ»|'O«š „ qM"&gË5ó׫n‡9 ³Ò=.¾ì3o=E&¤ÇB!…ö*`°#J؃—â¯`eîÏ“»Ò«)˦óÜôÊúøW ÛÎÈ'÷(oå8’çiëuv;ŒìÌs/–¸bšMa o`ðL«pqUŠ´ÔÞœ†eê'#^牽Æ(a!O/ÃJÒ0!ä\ãIÈŠVé;¶ø~#§9Âß›•týÎЦÄ\J-÷çÁAËmÇÓv³OñkÀ’LÑÜýžd¨°B›µí c/êËYšÎÏ&+šh_üC˜‚ ³ÇO¤¥†É·ís8$'Õ¬#\ÆÉÞ£º‚#D<2 Á¨0íQe¡vH¹Õðìãõ|t¦Hè¥`†?‹àŸ'—÷ÃdŒ›ì—P~Åʉ¦©btÖóXåÙ¬‹8 Í=ìzãèXÁó¬´~&¨·`Ý„èËÂB9Z)M†ŠöÜÖª ¤F:Jkç³¢áåÒî½%&쵎š!Åíηi÷†Ÿ|ňŒséó©?¿ŒŽÃ¯±®éR4“át­ Èr½ssë!ÓR幟ýZ­")Ô7Cr …ÞõM•\»Ö¼“ýÐáúí¶×uüÊû³"a ՟׶?‰ÎñZ>Ç…TP 6a‹WI( ‘Œ¦Vp!ªõqà™"87ÐnÑ`â0ªÕão—˜½©õ:–P±,{eÇŠÏsHc¶~?#9û¹@sŸ 8òhÏZŒÃü¬öx”-0´‚Ô¿Uj!!3ŠEZ™áÂ]Ðñ“öiòeªÎ(D4k{á;SRaL7®"CÞE•÷)){K‡F5¥¡·JøŽÁ®{¸¥uƆ«ˆ>6 ZûY–Í|J“ìžÜ ¸õÎvDnd-ŠT³3•ö/Ô\Ÿ77sh"\-ÄhÆH:,Ÿš*“º‚t€Ò±ð0KZ9&µEª¡å^H @!;Bâ‹Ùd<~°‚åÍP[Ü‹`…U ³º@îr!*rƒgQ g{’û¹ÄHâÃô“£l~)ÇC9•÷ÈÌXç‘¥DgK‰£ž*·²TšÏEYXOE_ŒTGÞÛ9nx\Yß,Ó2£oø®É37©'‚Øfg]Ð4÷7™ÐëtF{U”«P­ñ_1æQ!ÖHTg�‰”A¦½­¡›·°¬YTmcåÜFwÍ­Lºý€.·…GŽ€›÷õøÑ ÅÏ=Û0r5øÑ-›Ÿò!tS´»oµÐ|k„ËÙ o“ÿì&2“ÆÝ4Æíð­eâE4¸çÆkò±’8PØ©ª¥2æ)Ñÿ pJ( {»§Ñ¬Ôà$a¥¡ÿV´ÐéZ-Mc€q(ê0u­Ò–ö–T7©? Ãóéuš;~™ ³™SJ*‰Ì^šzª)¤E$;whQ2" +êøƒ ELL†ˆÑDðP¬øCy]ù<h¤"u}Õkn"Ëɼ"´Õ¾•ާmOÜÛçoËË{³jâºêFn¦™7‰ ßß.ûÝàÄ^ñj{Xi¹Í¡m¼ÜÊÓ ¾CJL#±±^¿=; <Å<™C¾…@<{˜`/­»›3:=4iÉ:ÃJÞr°ãŸ$ªÎ“1ÔÍòT'y¶/Ü»9@ËöWòayHsˆÃBºV†:GY¼â®–e‘0<ÌF1ó>¶G‰3<Lð¯âÏ•¯Ó:I1Ie‡‘îKàGA�df Â%B,õãB£Ž¯+a¨t­M~Þ.T.é¾´ä¯Ìº†2/ÛY[&g÷=¾5kլ̜lwU’d£€«F K„°Y¦ãeV¯¡5ÊÊïÝÖ�� �IDAT„ÌÉôrÛƒ½Ž&Ùå7UPºåÁ¯A‚·Dz< r¯¡€÷S<FjïÞiCãoæÃæ:œ¡—¹Çwßä…šê'ie/9�XäØÓ`up»«Ç„Ù˜œêªl¸�S-¾tΘîŠàqž ·Xñ¤ÙÞX`›" |]øÅú Êx….˜HaN9ÆK&5¼2rƒÈ%¦æ@ºDæ)àôű±:úOEg±à� 6Äv„$9Þªæ\Ê2‡fn@ƒÛ·¡9 ïWzqÛ]&c,CÎwî)ë;5¶]¹+¿Ë^ÔšG^ë g‚Ö¾u¶&¿o7›Õ¹F÷ÂM|2ÌÔMGT“=Ô 2:•å*:Ôºyºêv5v è¹½I#òÊ£¤;Ko$êèœ ×¶€b²ˆË/,»¤Ôp+añGôÃÑei&:c«ïK»>xÔ4ìÑæ8>õ<6¥rnHrËÍó¿/“;äéG±–‚ç!,nÕQ0ê;ÎMàÚQYÇ¡Pz± ò õF ìh!Îd¿vfwYö‚o™|›L«ðôjíuzïf£SUWR(ï;%ˆoÙ ø jÎJ¥Œ5Lè¼\¨åû›ZgÜzضoÜR %ÉÞÖq bÐþßöÔ=JÉ—è<fèô䊼à¡{•{{ÏûQƵÑc`Ø+eZ¶Æ2•h%»Âj‰G¸¬ÿE|E6Æ-–ׂ„„’[ÿƒlÃMÀŒÅÚ+ˆ$|ñœq*y)!Æ>ƒhM©†ðuÒ»&]Æ©vA®I¨•œŠ�Ù‰#šÞ>„cº�~°ÁÕˆß{e»îíd·gõ [ —¥m¨çM¬0·KûÁÁM?§òçó’\‹(Ñ«k0*ç Òê+ËXߺ”û/»žøU4·çàÔ;Ï}£Ý¶Éoe¾•íRgëûr NC5HɇQqìbE¨¶®néG·Ÿžðƃé/us¾íô? Ÿg¡l÷‚ÂÕ­ËcËŽ¼Æ…¥€hG!ªÐÓó8ÈC“ÔâO!6¼Ì3ÅXÁÕ>ÞðZéßY‘qý,bóé"æFF)üaæóPWú9Ì™`f=${QSÌ  É.MMFÂ2K´ Ù=K?ÒTq–yC‘?bË2KÞúVÆU±7òõ˜WsújèTZ}3L“ÅU\TtÕe–/u¡u«6Bïš7²[^I¸˜´æ&~i¡ãƒ€–{èÑoáó7+sc»¿¹×·+¯ï‘Áá1GΑya×IÏ“©9˜&ýØ´e’ÖkT‰³«€iÚ´¸(f°¯Ì×9„pHÞ Ü’ÁßP½KR´ƒ{„Ì5 ,èw †þZFDý*‚bj þIq(êe‚(A>d‚¨lçiÄø0O++tñ¬ mïÓúªP¿µD!¨F*CTãÛ¦Yz«4�”ŠK¬Õ=æºb×Ýæ:>´Ã¥Š¹q0¨ãý¥Öã«ø¾UÃÈíï¶¼�~,L Û[Ð_ëwcœµ13Ç%l|ûr“Ìž4hñåÒC¬‘$eÊ2Hª³õ-C¼/Œ¼ë™¶uÚi?$[Éñæ7EÙò|˜g…4÷XôÒ •D¥ŒØ¦Õ ¦‰ ¥€.ë@MXB’ª–0d÷÷ôM)0(§ÇZ�E]ûó8P¬E´é±ö:ËfN§ò^Õ*|‡±!ÄîœK™Å-£#X1‰Õ¤3OPRTÕ—BØŸ·Þ`!¥dc-G£{R_c ?¶ŽçhG_1{#2Wã9t·n“+×g”«"Eáåö–*à¶Ô['Ðk¯½Ý ²¹ot·Œm¨ôë5†ÕÂaîëV65±îú@k.}^k³q.fMŠÜtkþ bÓÛ¼_éžóf<¾0PàRìžZ÷$X÷°q'† ÍŵšÁë"ùœaQÛi¼> VWg9ÎÃË9gÒŒó¨$Ì©]Iò‡öTì°í€¨ø¡ŸRl¶¥Â‘µÖ «p²hÐú)±¿ßPqeƒ-ó¾ÁšâûÅN¢”¦ÐœéߪÆjÿÚ ×ÿ‡ïl¶|çèÞ¬îÊ©m®“%ôÃ++{Xum´öÍDd)ÓÛÕÐÈm(þØòröh†X˜V8)îü’!iPvÔßcÙÏ´e¼Ý{;Sñzª40äí•A»"U ˜}Š#ñ\±‘À«%ÏòQžµÝŠLúJî±Z!õÆrP2d:\kZpFàNsTQæ§RäkC¶Á¨jÀ=|}xã:áA¨2} á ºzÔ­d>PHÝîè3‘†ód’è3¡Yf0™¯a#5´Æ]l²ñq±Iª§/ªÚ½ÇNK«-ê¦öÍå0b9ŽÖ¾G sg%Kµ…üA׃9b<ÔŸÕT1+ïGÖÏX?r4 .Ì/±]µ™è…5ŒX·¹Î˜oõºY‚egÍãÉ´‰‡™0w‹ö¢uó˜‘ågìí ²p^ &Ž…DÎÔ�ˇ…žé¸4–„ð7«ÇŒzгƈó‡[n,§ÎòDíh`Ô &Q¢þ¯ž$>m=UmαP¼(9ÌfƯ’óøÂãx(=ˆA…y ÕôvƒÂt®7ð™Ÿ8^ë×óyíÛ°+ZË=¤cì4ç¾vSž8ÍVnù¶Ôqˬ`;C£µþl´vc¶ëW:«^ófÇ_•kÓ€Íi­Pè—c‡…ðý V7ÛóÞ‘AFÓÇ31ª’Ô­P…êElöa¯^¹¦z°üA Ïo­]=*1xrËš•8 ‡‘¿F|:‡rññÉXg¨ý¤èŸ@N1†C­ 0„ref„ð^rç ^‚Š”<šLanPqÖs!UçzWªi¼*lÚsÚ i½ùÛ*2k©e؂ʟ !j-B[Zs ÙÅ0Í#-­ÇxXks qÅüƼm®›±__ÍÈ­Ämjqs›[·ó1¶Òz(•‹_ããvKæóSG+‡Üâé&ŽÄuŠù_‘¸è:¡Éeo j`ÈèU´ÊFÂPb93J\òœ¾X¶nU©²1ÑMœûŽ_B„Ü7 û,¹„úƒ©°H¬¼Ú@BO öN¹ÆJš=uÔÅrMRðyl;Eo‹Är~£þ‚F¤^¥ŽEANâ’PºØ˜1 šyÖ&_Zý$c¬Å•VÅ*§â,T£ô…(#Ôò¢’Ƕ¥˜o¡H3sK¦‚k‚¡˜‘#”:Øvzl•[mðFFnù©§<T†äî*­¾ƒ·üÞdI¼™Ûoó]"®>R0„nŠZìÑô#AsM׸fÝÖlM÷¼à„‘ J@öĦ¦½iÎ[uÏT1÷*Öî–_±ˆ&‘” Źº…ððC\÷=Wf´ýÏ5 ÏÇüªCÉndŒçYgÓ DÝ£‹JÂdËtD.WþöÓ熂âÃ)â§ñ1bú^Â$IlîådMGÚ ˆÍ2vÖxó6éKœ¬‘JcjÊ* ')–Òx¢ ÉQ6Þw˜ü⦞ܠovHë7°2»¡W{?+ô‡æï¶çØ?î#5{‚¹‘Ðûm0+@ŽrþŽÌ5±§³é–z k…‰µŒTáÎy(ÖzéI#à+-µ³ýv_ع%jú`Xèaù1Ó–',ïúIA±Ír†Y4}’R•†ìD}J4˜')ˆ"UR–ˆ•¥éSR<òÝ—°êA·VƒáFãNªwã-D ÂQ†j£]E­ 펗þ¥a€ÛËc,Zb#¥9åK3Õ¡žö寑·naÒ`ÎV¸ÇóïíÖ{Çw{"ÄpÛ·+»¹/5±1³ðêÆðT”Ú<ÙO7ËàýiÏz1äRƒvØ“k,ßï¸jq”L÷•} ëø¡T9sÙçxšô~dß.ÖšA@ Aaˆ&VEv (.ñ ‘B"©¡Å£ÍPë¡ }1³Ùn<Tk^Jeñà-ÑcC› fíø->½rð+-¼ðîðl€K-Žj¬v�Ù‘¤¾8Y§Ž‡Yk®òr嚆_…šš<¢k£L¬œµ3¶URnÊ]×uš¾ý{9s­½ãÒžÔ«-ŒKdÛásLßW+3¿z(ÐrkƒÓÊȱÂK¯Ó{›¿¡³•V¨œÚ'¡«vv®s“Ìü üìO¦vv7 ÛñvƒE¸†­œYJ{ø¡k!‹Q(a©…íŠyŽ?æ YGéÅFg±,¾ˆâÒÆò='à70ìŠ{1ÝØ "ºO9ÀìqM›ôñ%ÒÐUÙÌCñto œƒÅ­2„J ¨,f @äVöõþ©1Ï^¹ˆýš¤ãùÔ¬½DJõ`¹]kq€Å%']†¼ÍêgHöÊ,·dƬla˜Õmè1ûÒÓzSŸ9a0“v£—È–àÙ-q)„~Vwhõ–Bë^²{ƪýÐ û[Ö½®o<ØÜKᯑQ$½_VC4£üìä–G蘆•.Tjñu£Á’•5BÂŽºsÞ`NÒB1$&CÒc`‹uÞÜ^Òag8P&ë@¯(óK:@ÕeÄÇ'WÃû8A%Ô¸Ê3vÐâs%|¾¶ØQä Þ;—b6«¬ØEõª?Ôª+¤âØ‹ÑÓKÏNe|õ°ÅY›^³9&¥Â¾¡Z &õ­Ÿ•µ1ؘtÞiyþÊTM¹²„o}8Xý û<§µY¼œYÆÎü(—J¾qË=2H)²’ÉÉ­æbQKK%Ñè½ ]§ö¦½›ë˜¼IU!¹Ê$>wª±pT¤“ ¶€ µü$[àëXgh6œ®$eœ„ý ´ !%B=Xf¦ŒAʱ1xE$&§¬áQÛZ>©oóž¨3 ŠH+áQcq†HQ˜r5fC¥]Ñö«Š$‘�Óþ1[+oKÕRyKzBß%,·˜ó\«*­ÚÎWÀÓ¯êd‹Ô9–ÝÍâ²KÄòmS+ä @åtéÞiOËÍ«gÝv>¸×Ånö[pS•ÜÔÏÛzwi‰bb¨ú{½Â‹­~ïº7Ùì¶°–<p›jh¡Ð©«,|\±½ŠAãŠV²•“/ìTäÍŸ¢7öÿ·÷î:¶,I–˜BK œTú;ª8¿@ŠC•àh¤Øýóý†ÑF(udþ«º5TF!-p�¾  Ær ™;ÂÝl™¹y¼öÞyÜqqqoæÎØö\¶Öš‡©mD +íÔ«¬e-Á}" ×æÖ ëød5üD ®«_\ ’Ÿ©X͵Q3Î{ÕÚÊ•_ùŠEVßub¬öµõ@w;MÜLV‘‚ü= ú§jËׂjÂ>¥’Úaȶ^Õ!íìã*'ÛP”NÌ7PÁ I�™£ ä3,Øëýî)žXñ;«ts (N¹'„‰qk©L°+q”—CypX[U2A®8Ú}„ºèÛÙnŒ „¬mé?¬mÈ´ÀPºa„Z²G}ìË7<ÊwT‘bÐ:œ¤\i‹­—J¾ëáHc*µ;Yy¤*þø¥÷Ó-­œ„õÀòj¯×êåš±­¿sXB¯¸þ¯â´­;pu–‰ÔxÌFö:ÍrŽh^ª Δ³©1>‹£hlŽ Žc²qˆ¡õµ´ "^K¿ Â¦ÉN«‚Æ{÷`â“cmßßi•Å¥<¹ú~;/Àîëâ¦ÌUÈUò.测øØ©òãêŠåò®N"ÉœæR¨‡‡•§V‡¥®þ}Á60EÓ``s½¢¸ +ן©�MÙ°N€”¿¬)‘>Ó¦u®«®~,=\TMNñéD?aMaUçOkn·Rôn(Cÿ˜Óìë \ÈŒ¬ÄÁj¬­r–ªÒÔŠ] ¶µD[µ–E3g’¤êvé’ªßx—€:<.'B뜇òH¹ïºèÅçßÒiÉklå ÜÚ’T'>£’ºŒT8=÷ïqŒBEǦñPCËVÙ [ñ@¾vÀS”_ªP½f\]À´r,¬�rRe!Ð7 8$§‰CézBki;C5(ucõ7Ö©X‹„Üœh=¿µzŽu8lͨZÏ*µ ÛãÏKøLÎ ÖNLÉTÌ8A%YÔu«)æ:Xt8¢Ì‚®3÷ø0û†²yn ¬f¸ÐB¥ÖPXòç1É¿’k¹C¯ò¥ô´n¹Ž˜rT'"ÔÛ@²Œøõ2ºÏq)ƒÃ²'£YT§•uKjÐjè¬ü}£G\å[uä^Ó½¯'¶„´ò[m±ˆÚK1޳3ºÔhQ®þrýp­Ÿ²öŠÖÏÔ•Æ–Äk¾’uœËŽÔö¥a¯7ÊŠÒc¯q€ZÐyiu·bl£‹ÆÍcVµÊ`Á ?·? # ´T/¨2¶13.]Zš’yÁ ÁR‰µµ29ß=Ó«Á7ò-îÀýÕ¨Ó’ÛÏõÒ¼G…ŠuÙp ½ÅUÚn{6ÁsÆNܧ¼/.o&×m» V’E¹u<Dž®Â6…5q�¸\³ûtûÆãð‰¾Û’<͆¥àË5í^“)VýPç-ÅÆVÇ«åêשº"WS˯ÉÖ_ZôeÓ–ú“5 }¬Ô½+5YµžÕ£±×œÆ–íµâO:ÍšÂTm{‹Õh@%RLuÁÓ·õF:ÒŒ�:{F#H<͇(S‡Mš¥¿PâÚ Ã}Qßä —v$…:y ÷‰™Ö2'¾ø¸‰Ͻå(3 A<B.ïº6Œú°Ê´‘fû^4¯ œk/Ȧ°c‹qiaîڻ׃AŽ{´vVáCó^Y|Hùƒ¦”„E…gÃŒnYçk…L®û^+6½b2¬™yiU9ii·d·:i‡—é_×ës^?¼å‚*×ß¼Níb…¶y/"´ÉRëδFEN™ºÉãa:î€#ØDW¦…Œðe8•á'ìHó²#é†\Süxuúž+Ò¸Sô'ûŸé:­+JœrìªN;87 ¸ãÜ$b¶Õ‹Añ ”û¥W^·¥<[W’¬d5ñŒl 0ªÆ`ÎéEM-¾ñR‹jŠ”ídjuG[îoú¥ê~Rº!Ÿ[Çcë®R Y4ô¿ÉœüFÕ -®Ðyz´Ž¶î×§—ýü÷ê¨T ±ž ªÉòW¸&O«Že[笵1·Pfc°mê¥bð¨ª2,5›×ÒÌ-ðII¥ïÒ²÷Z×Hí›Z4|öqFÄGIVð©r(Ïá|ñ)$§3ö^RHÌdZ¿Xžw¼—oÉ}Ðý‚ÆÐ1VÌR^¤¤wXs ÅzŠÆFœWÛ¸17H_<SSUµ껤ÕÍ" ¹±ÛqKÓÐx—Õ7öˆþ‘–Õ¨@†•ò¤TB”ROGÕRÈu¢Öb¹Æ\ÔÄQu£«&<\’’©4n¬&·•ýHK›C´ VÕ5,æî·$å H޹Ð@˜&OR. îª*tëCÜ©Âé8]R6¾6H•šÓ³$2ŽßJ2_ é†@må¸u3%ü“gÞ”#…r€™{^Püª:uÎ 9mj1S,®3®Z_š²/T‘‰„t)ûöŒ*µ׿jurŽF}^]ŇD•Ä;!5BÑ% :Õ|oÍIX×åÚÄ¥¡1\9œ¨’l”µz}]ã6hµTE¿¥"\tfÌu=v副?Vñ nI^E•+õx¯~T6Ù{X¯e!ÅTÙ+‘ÕÃvV©½w bˆ»@ËÊ£o÷ ƒ„`±ÔãÔæ]p¨Y¤E¥Á¦û^ç)Äðü:=­—UŽI2_¸<Lq‡>À¸ðêòù÷„}66A ¥ø1l¶ÅCÐ!PÒG  û«É«TMõ@u±!³¨“õße;þÒ(~QÝ6sÐw›ÏPÔéuÙÓæ@ë–6UZ†´¸M5)ë_w­ RNi›² ÒàšMóEœapià6Vž·à`!Ãʳq*±}h+‡o"£TÏÃÁúÇ)4N-8ôùƒ…>~Uãykyp_·íDüº$~x¤™FÙ|cSУOº:_”L0ÌÕ<¿âIv‰–¿‹pPŒ1àKÙ”’àÎ(4¶'ƒRj ‘fÏ#“–5p€6!¥È¥Ô¹ÌAVXüFb[ÛèzˆxýÛOÂÙjì÷ëÛk„½Qëhfœ[@9W’ÁÛüÓ ¬Ë‰+iS Æ[„2Í ]ÓZl®« ¤%$¤zØkUAk÷G9-/Á2u…ÇT½Õ»ŠbŠâ´âÍc6q†ãæÖ(¬œæeƒ~nZÆ~NI#®aTÇ„8­×qû£~Qî:I(n> E-^n<Wó!ÙÁ JKÖçí‰e¼õpŽ/X„âQ­ªZGÚ¼®Ô@?DqÍ)šöÅÌ;+åªFB·íi©i­À'jx¶æY_Ú6ۢЌ¬Š\uéoÝœš£NËêƒÔhŽêÃMMÒ–EOm·Z£‹Ö"M¸åÕÌ%°q-ª‚”ìµ­3÷T@´€ˆ ¥Z ø=Ú£²Ã-E³¯$~‘zV*ÆgÒÍåÁ³°ˆÊ…ÏÞ2I'øøÕE¥6B‘ é:-qª0÷Ò»æ8ÁeÚò yÕÊJ= r)i«O uVÕ!KShª¡ç•'Å_®”éQu‘­÷R°‹vK¹f”0m¶Å.õµèó†ë¯ÕZ ƒ5‹¼ª—ÚÂìêJÛÑ(-§«I7uÍj<N;øFÌL¹p‡*¥éÕlô^íÚ>BíÛ$(ó6¡!5sÓ‰$‰üF8÷¦3å{ê¥|êüÞëèWŸè´øºíˆì~çá; ¿.ãÏD÷€F@«£p*þ4±}sçÖLàJœÅÚn¹ÿTéˆÓ{0ÆH³nÖ¼Ec‹EЭzZufPâÔémÜëØ–S†bå{M­TC6ø“-¾%³×%ÍåKz±á¸R´°1 )!æJ.²Ú™G™Ž”wiK^‹½So]ן+·d¦¹+Î]h5êJ*ÚÈa[¬,hSYÄà’ãÉ4šåóôÂ\C_\M»^·)&‚’t=ðÕÒ&yv]¦u'#>Ô.غÛR?É2(1�};ãÉ-‡[i H¶l‚M[Eê`¿¡¤+¶yðѫѨ&1m{„UÖB >ÞêQµé·Î F"¬>XÃgæ´VÞêÜ®¾×nƒk)“µ)¥ëÁaªd*+zÜ•l^ŒÏÆ •ÏR”Þ&­©§ý㙤­*Û΢ÍzÉÔ~Q³Ëƒb ‘)‘0nãFwp§-&'¦P873ÃN)åeõ‚/"½Û ¾ã{ʃ|û&Ó59ð]QqºÍûŠ“ÁýézàÌüV±þw¤ÚÑ]pÚ‹ËkÀƲÈ’~`ÙʙԩªAÝJ ²¢šmàl(TcFL‰‰Ðp4“ç­w£ï°bÓ„úõdtë6ÄJ¿+¢¦jBY¡%k¥Íà[7Ó€,ªÜ´P…ɬëÆ+N¤ñK;Ae²ðÌT/û¾ªÛ[ ì©bŽ+c~\9‹÷„ÄﵘvÀÕˆó¼<Xð'2’]ñ-ë§uC›$#§½èA9õäcÊ¥&rÌ )‡¿z0>8\E<Áº×U¬ô*VVPéû`•‹•‡cDŸdô4!€Q,XÓ½Šñ›8ZZšA¬ƒ¼4ઋŠ×§f]Zwx´mó?¥IÚ¡ïaÝ�VSUI Ö¨ià×?\«‹FHS‘â“âö­u°Öqì—yÙ…ÚÂ&5ûlUµÚê(ú ñkË¢ZGU‘NÖ³ªyª§Ëú"œf- EàoÅ�#ÆÍ©• ~5û™îµ5ê´NJØÑý:îù y¼ã‰–ÃgË{Š)áéœj±^°&Éõk¶„¼í6J«©Aª¦y’JmLÉ‚êAã5 ¨ n+dF ä¦Q§TcŸê/ʱžØ]*&¤Z‚„4fÚánQN¨&ü‹›ÞmÉÍ:jÝ¢¤vÃUYÌ$^Åæè\‹1VêÃdÆx© à8„˜\3hç@C6Ì]4ƒs]ÆOx±åvJ…1õZæM—qÜâ_=êʧÚg¾ÙižÄ¾yoÚ;Ž÷„,0ÔBÝ—,'Êâ{”â•_œXÒ{É‘g]lÆ– ÙØDgŠ# ¶.¸>~XÃZî¶b¬ˆmSnÄ8@YOgi5]º§¢[qºót¹H¡ãŇou(H Pæ•Ï·"ªÕ>l%°UÚÊ*|i½,Õ¨?Ó[jø!ŽŽ!³­Rþ´ƒÌè8ÝøŒ@!¡POdÎ;¾4aSg–‹Ú๬¸ÉÃf"ìW53ìÇÖéõÙ·ÝÏHXÄ ‚»ä—fÅ—¨è‘¾übëά»¥ûÈ2V,^HˇۈŒ|Y¢Š‹–ê€Ú!<T½±%8à2KeÇKÅ´MžÕ†±ªZS^Côwdôé­‘•Zµk©„Œ=>À¨Mö*çX‹F®[¡ø ¥Ï»¡Wš¤°Â¸²««²è{-Nø)ÊØ(’È$Ö¬eÞô;s#ïÎÆ&älTí8\ªS±ÃN%�¯‘??ÓºÇÇÊ5‡Å«W0ŒÏó6v8fÈÈšÀ‘dv|s/&ÒñÙJ¼±nð8i·#j§šÀ–ª–ϲùYhˆ@ÕŒúu|HDÄ›¶dÕ}©¥³Z>\j©1ÈÐëm$¿58Ð2/Àô7³hÛ”ôà )ÝHS $8ºûu„BK5m]Ñá7Ïù‚ Ô»GƒNl»ª ´’‘ –G‡ŒJô‡*76¶ÃVW-álbè8AV'׫—Y7%m¯[bá�� �IDAT0\|)ü_%¹dü”‹åS¯¼^b?\Zt&KÒa ŠXÚu‡ö°é±?ä6tünº>Œx·¬Å*íÖƒDµáh]×Ú±_;7*%}€ÈIͯΩîƵpG¦ÍsÔd¦*¸1Q}Š+¶ÉLf2ºNžªÌ lâ[‘FLçdzêÇàâ˜ë#a]ÑH¸‘yN VH“9·ž{…A2– NeVzè¦ÞëÕv4kns¢"«Óу]â¾#‡‡Ô<wŒœ{ggÐ|Ì™IxùN{¦…bHÞ—Š)*ÚÚ½ÀÒûÎ( ¢ÇU*6roÊz�?BVùiiÌGCÿºAÎ cÚ(’¨AcU/U|ó Î 0Yü4@j¨)«{½ Ã.* 1“U¦ß×4ÌO5/퇭Ý÷@ØóØá'd¤Ê8P«7OˆÇù¦6ÿ“°–î½³l‚¿!'q…~áuÕ)>=0\±Üí´Î*wòÙ»“ñ×9¹ 6¿°+Bd ^Ôæ”ž’¥|6,·ÊZ´˜…Ti}?²Nªí_C“¿D4Jm ¦»!SE×TáÅí­ J;Ñj”lûSYAá×?¯Z«k\*ÞÅçÝòBMÑTï×yv âàæNø³:Ðû‘m¹eÑõ“/Å §Ý±EîËÛÖ¬ @ðÔæç¢Ñü…ÃgÐiæKå£!æøƒžïQ>½<ÈûíìΫ=%ú�6=ôâßwZ™³ê* wruÙï“Æ6çã(ï‘)j"vŸ9ö½”9ã–ŒÔ|�T3W8‡TÕ‘ÕWËr$-Ñ-+"ŒÊEQÕ®[$ÚÓ·€õzúW¦Œ-Vh8,”W3“F ŒÂIpØIb“£É'R¼ÃdàÚÞç…Ö–ËðÍ-:ÍŠ†Ž5ÿzÇûüԵ䥯0å‡k€Ý2à‘¿}³žÖ>•úƒNnèY X$Ž_&z+´aºÛcÐI•¿üê¢7 ù’õWôµNYUZ ¨òàÌ4O]Sì⠼ǨJiÉš†ˆº½´hÆBYZ±:!SèsE¬^§k6VëIÖX³º¥ÕeV¾NŠ ÔPÝo›¹è 'µäô Rgxi­î¨-®¼&3Ò'NqX¥S°‚G-Ã$G¡•>Iý<·}Íö¥+æ(9Ó\òÖOg4óvé Îþ)-«³Í;-8psî©¥÷ùÛ.î¼ØÀlc!ÏÍhuóHòªóZ¢ëí"}­ûSŸ.Á®ï°-6|WíOì&„¯{92 Fо—7ÔŠ\£Ò<\*+ß~û—;©°ò _X;UçlÓ8úlƒ¦ ^ |k.v…å#4˜U§¼¤§Aù ¸/ d!0Q†‹–£Û… /ÈáÉô ®ÀùtåYÕ¸EûjHÚÁhM5öhð¸<ÈÏó1W!¼A¦Åg4ŠÎÝ 9üÕ2x« ätCéž$÷$W•¿(]Õ$K°”Dl¡Iüø�û`GILÖÕ:é^±ÍQµé‘8§j¯‚>6ÜÝÒØkV|µ+è±Fµ”:­$­#\Héq †ÙUcŒ˜‚*|¼rì0RÖÉîVJE¤SªÃÄ O­þ@ @ÒÈúçdnõd! è{¹/&L)¸×³jvì–1 ôp¡ÎíÆ<’¯Ñ]á âMn‡\i¨Ÿ@ãtºkyà1ÔHìùË{TûFª=¯Æ¸¦áºÕÍî¨|"ÅÚéÕ%öô”¥å(jzZ’ V} ¶=#ªDYŸ¼}Þ¦Œ?ª U<-mù±Jt¾ÉÎgË™ªö7Å· zÞJ s-‘Up¡«MX³½5“CLHÔ2ÍCšÊ†‡ÍÍe#úL¦ª‹ëYR%ÈÝ4ÍAx³`3ª«',~±Nú­<ËZà¹/-²qŽæô•ë‡N‹/õ½hIÎèçwꀃ)qÙAzâX#e o‰ïðÄaëN(¢å%Ë3dH˜@•ÉñÚZ¨¦$×6nÑppxE/„oLd¡–Ç›,§a�bDeÄÍÀSŠ5‰Z$z5èZƒJ«Ø‰ˆGoþJq/©Û´4CcJÅÛÌæ¬Ê­2Êàó褆R}Æ Ù רNøÝb·•äàã)6ú ¿·R>9ÓÊ»w¾æÆìFòøÉpÚyDÙ¥KîW`($¨zn+æ`*)X‚/ã݃ЕN¾©²æ–,æV…lÁâŒÊŒ°ß¦øý,mƒ‡ƒºÍ-¨Ù¡¿SM îXQåÄ:dÙHžZj(ÅôÑPO-š Oµy¨¥=´n ©ñ®uÈšxýü‚çÊuYÕ~ÉðÕç×6 )%µeO5:6øjê}»~ØBO-¿zq™øë¦D]Ë"I Nø’s1£C~±z[’éQ¡Îpbi?=Áb[è»l²%¡#ÏBó$þýÒs²­õ;ÔE«xœš˜eZªm¢ñš h}¶áÞµUP©jDu£ÔaªêV•WÕõµ««ý_MáX%[ëß²H¨Ë”EÏq{PÖâÅà-j‰<ÜÙ[£E┑;\É~f/!óHç¦ ¼ì¾‰H¶¦¼1cèNw'DZÜï”ieÐW `Ýz Žì5•nîp±ÄCòZ3"‘Ûˆ’¯_K¯“‡›†’‡Ä‹ª6™ê?ŒÁ«±$²üŠž` ž ª§lûJUÉš"aQiA{i,_ #\¢\•2HÝ'k_MØ€ñìhsíkhƒ¥ç@Y;l°«ªù"KÐÞ¢"Ù/'Ú@l5XQ8Â2£áÇ ÚT²uÂ:6P Œ7?ñõ}žK†ô²õÃרuZ¯™¢îNŽ;¸Ï¢AÓvu­ä[zE˜ŒÖ ÆwIAØ¥²1l…†@‚{ÎŒg4n²ª=µÈMÇu6¹�X<¬ª‘íIKµ |Ü£¥-N6'QdÎ^‹ ãšÉ·aU€9l‰*ÚþYC*¸׿u`[¡R ,£™*r)[JU {ñ%OÅ_8ƒ¤yqCOñkòÕë£ð/årÛ¬ñPzðº3^CåA¹ùäx²¡(ƒÓ×hGz=¾¾ÁKp�µ5Q„4î‰8î9ÐĮ̈Åy¥§ ž�C{ éVA³íA PKÈm!$¬E‹ºwõ˜ªh…ñ=_YHi=Y!D× á'´*Û¯¨³I4ØD6ñÜH@æ_3:OqŠ„bbû¨ÊÞ8|ÑÔ¨2|DoY„âóT@9¤Éé ¡žŒ} >cç2§—(Ž–}”Vùœ ^ÿ„c}^r^!îU¸!¡ó'™˜.@´—|(IÖms»ÙpïI ¨…«Á!PQÇNïÍ&‹´`ÇÜ0íZ²×Õ +Ê%³ ¢™Š¢[¥ö] ¶‘ž &ƒ'lhÔ¸q‰hJŽq²[‚˜ ãH[Í*K•"-g±ä; 20;TÞÎí Kݰw²„:=:ê÷†øÏO³è<ÂÜ|í”BŽÝà$oSÈ&U(ƒÅèë”@O„Ý„LYÒB´uË»ô06pNrþ²£Hk+½:'ÎtöЊ{/£7òZ[¦ÅT”fR[Ô„OËÍÔcÂÎŒª ¸|›üilåÊI¨ZzÎYíÌT*)Q¡  CL–ðú{;Œ˜øå’*]ö0 †^ð}…di}j÷´Ä`H!“Ty0àvé wf§}#íá¿ºÖ ¾¬dP¬;7q>O•äùørëELhž³—å3åŠâH™œR!õØNõ3 ¹mcIW\ƒÍç*R>O~:ÆFrÏc[§Ú`ŸƢ‚ƒ*û\1«ü‡±*Z!1Ù«$ãËuµ|*µCrÒºä&%]LPFè7BU;½.¦Åš:4ä’(ã"לºÿ'¥¼fã·º` h:$,;ízZ*sãdG?eŸÓâ÷(/OÕ?Ú¸Þš$DI$’rX}Bã·li1 •ahÕ5†ÚÁÖà<l’»Ar̦ À“úêQ¬„§\+Ší·­Ê¢Õ¡¦lؤGT©ó†˜ßp JÄKêtM &›±hë¥6ÄÊ\9ôZ žPìÀþ“ìåÓ\cýÍktÈü…{]^×KZD¥yI±\ŠíÛ‡Ïóô<‰ý›˜q7ðäò‡>æÈûÕ•Ü#ûÈ'mÜ®–[éæd6yâÐÚBü!õ8c¸©oèoºÓ-Újx´eh–SÄ€j;Èî™jƒåí» ¿ƒ nª¶œU %Ý|ŒÒc´´5‹RËìLJYÈ2=¶Õ¹Z‚ž9yåD3ç éþ<µ‚‚­ÁÚ‹c>iƒ1~(3Û>ÔRŠ5ˆ=|&å€T‡Jgty’“H橯¶ø`¦uð’$÷ð‘¯Àt0ÆI–žeOÍ}ÔÎÆ 'á+éºU#”N jïFÁ„R+Ü'ø4CŠ7Á™üDMZT›é.6�kÚøŠQÉ1úÁ3cÈÅ+J@SÔ’–º‰Z’_ 5Y bÙ/ý”ÈZÌ9´_­”©ÇAE>À¾¾°jhAÀQ‚0pP2¤P±íãwÙgubÿ°|£“+s«°¯NÉF@ì_ó!õœ®|¿G¹Áq>«§•- Žô.ÚëD3ÌÄbÛÉk>È1ñ–q§-\à†ëi!ð'Vê´ÝGl@ì‚çJ{/°J•M³LRË}nÈ&p%J«sÕeƪ¬g^õòDžTCìÚ\­­W†Ôz)Bd}N)UoÕ¨ A<¼y^rf]S‹÷êñ¥HÞ:C%Q¯SjnFôRÈT+n™Î­ŽŒM_ཎ7Æîo<k]á´ÎJ„N+ƒ€8ò e~.Ùú¬®k™¢DwN¹#h⼄©ñgÈÂ@= 1Æd]‹¡ 7h®Í6µJ¸„H¡ØHrˆ1ôVÃq•jâ¸Fj;XªCÃè±ÎçÚåZúÒ·°LJvuÚg4ÐHµö¸uòêerx©Gwqk8ÌE$Qw¶â¯ÐYréÉhE¡'Þ¾Ìq’¦FÆÂbð;³·ÔêéœpnC=­$׋Tl»tS|à–ä/ÝÒ¹-µ»²X€›I®{jä®LŒ§Â'Ɇã5~3ÅÙXEŒ ªŽ¾©å ­½T£nÕp‹HMb[³IÕZÆ5J°å߃s“a²Ÿiy{7G¾€›û<ÕG¯êÅV+dÝX3-k+êcú²‡MÍ$ÅhóF| zWU¶-ê¼5Gì/ßï?|õ~I<áE œG&^Â)ñH¬¯º#¬sNÀëQé'Oúé`u6¾Sü&¹ÅP \©I°šsVü¶F‘KL °ñRŽ*® Ök?ð�¯WÚ]dܹë©ÜO=\ŒXY“k´ès+ùa§ˆAaˆzs%ÕHˆôH90HåÇ~q¸›$Yê)ëT!ËŽhú4Lš´ñ®W;6D<ø¾?e%³À¤C¼¤<Èwíòñ}IÖ yä8™óå¹G¥I³$¼"ô€–poK7ÂUŽJ³ª«!eDZØHx´.jͤå,·ªª»Æ†@³ÅˆxWšá*ŽÔ¬Z#K+²U±@5ß«TBjçêhbÕU;[­åÞô… &~ûçd›|0_�£.[¢'A§ƒ³Û€H¯Ö¿D¤°K°;š Ä´ŠÍÏýb‡ù(;ÿ>b0ï˜ö³À3 sdÄžÛ8úä³ïÁ7ÉãIÜvÇk>…~ß+öIÆT5üžnàl3ƒX² æUÖ¥î¡[q@+jÚÌÊXxÐÒÒVU õ ¡à–OjÓf&ÉõÃÈÒÔþÅõµbÆÚ¤e óÝÀA’fµ¼Zô²,XS˜«Ö fÙ¤h$§MåÀuâº+8°Oa)>2_wBò†˜Qé2ˆG—ÇëÖu©žÖéJÒ;þª ¦àÁÏ{/žì?á¦Ä!šxMEš˜ŸWœ3†&R,ž­l«Á³ÎÞFUF¡‘ýv^û^«AÙ¡aüƒÐ‰ 'b!!òɘ^(ê|bú‡b4®TIMx›[…£Ö½d ™qÐ(b@áêŠR|êí ¶=Oji>¢Ã.ˆô2´õëàAÞ =Ò)£ƒ¶¡Œ*ëHÑ`OáæÚÝ }û¾ô6Èû¾‹”+¿®ÂìLºè ôs#q‹xø]¤ÏQËúoq¸k­Õö¸ÛÉ!ka#¿D•Ñg²ÚúªÆH‹s#$½.9ªÝRUÛ)…jœ«nÿQyçÖQSHÈÖè+½ceŤöŽN½Ž?³Ãš#ÃI.ñ-^"ÖÔÌ ¤âAÿmRºª¼fWuþ ¡Jj Mž/”ÀžQ=Ûmš®SyŠ‘‹.óNåâ| ñDçÃ7†NRP±Þê2ìJ³tjú•ŽS—1sù‚+Š•GVç‹ n8I¢,ñ¬Ê‰5wxkm+…êÌ@våfdƒNhBöúvM‚Uê“g³cìt›¨rxÖÓ‹84YEë•!9YeN –šgÈIÂÑüÀ '0G–V‚wGÑÉz—’|5öI 'ãæ¼×”ó\Åý>ìÌo|zðYWÎ=i’Ý #Òµ¾’þ¼ŽþHÇ›ÅsKä°ûès3¢ÔîÙÌ-±s(® ^ìß8ž6£^Oˆ¶n†é“_“ݰùÙîKë!¸a|ØÄ ‰×\5Fè•ÀãB“{ÌâóoÕ|†¢JdõV¯:œ m¸`>½X)”CƒÎܸ#dtpF%ˆö†Ì7|×n6nOgË}|ãžM8â´x¯\Ö‘+9Qî„G’¹î4* ZlÞú¡@V•M®&]ñ‘µDæÐóˆ®ùñB56«Rµ'‡ ÝMofy逻,ûƒ¥¥XQ\Ýç—pÈK]™¬¿ÚçÆ?T>fKÍ®‰#àP×ã Ö—§Æ¤|éΠ„Àª¥ç™©W‚ÎÞõ›âÑÉ‹O_IfXø8x{åŠãæBŽ™§ Ï_WgZ|Æ®íÞëÄã¢)Ò}Cæà<Rr7Š,Ƈéó?ß‚µÁ}Ž bÎæ€' }@Î<2È—á[ƒË—HŒ<A÷g9ܺiÕ¼A-Á„ÔÊèÂ@ÿ½#<ÙÆu¦H pÌqz¤þP¹¨À©<™0 £–H7v]~þWºµ„^8[bÍ‘‹&pù–Œo´®O+›ÝÌ=ÈÇ~»¯âLîëTrÒ‹ïrõzC»dŠìÈ‘˜YK÷‡ "–Úbc]W´Í+5 ‰nƒ0T¬ƒ_ ߢí2¤“ÕXSÈ{¯˜´ŠòbTê+e6`Ô#¤°Hw²m¡%g”ÛQ¯“Ć¡˜CR.=eq)¾¤Gë=ÿÊ…'2æœh‘[´ï1Ä¿}î²£VÄN¯+w£“�Üé´øån<Ìi𠆙þhé€ûž¸­GùGëÿ:ôÝ.·‡ú©Þ.qÈ<$°2i‡½ìÔ­sªœ-àK÷±o@®ˆ- #0!ͱê—&‹µÞ‘=Õ§|‡)—ì´Üíløøß“‘­¡žw‘]ùMز*IVOJ<ÒMÖuô€¯Y<½œ6LãtQJ»o¦jèñMLŸ”|!ÑW|üÂ#+þòê‡Ð‚ ÌÃЊï9¼Ñzö+ò€Qw‰‚£-Sq(b!­’›R И÷¬„.Òë´fѬÁÜÙ-‰;õÚXÃEIPOÆ&Ùe$,"…•Wx€œÎlZnžŠ|Àà%1;¢Sf`'pɼz_¢+Ós·iæQ›ð¡<?äèBÈQ‡qõ^¤É~º“bœRùÕö f òÅN¦w8TÑK왋_3r–Œ&a9ìib…™|’492«1â\÷‡‚5“úHKR¥OcD„HÜí#-¾�•½qqÑËŒ!S0ÞÄ=zÙæ±Ypæ—!ÅxHØ&ô£·!£1šW‰óÄžbÜ“¸Œî\Úè¨ÏŽpÒíÎòàý Ë{ä’)¤¾N³.ÙW¾¥†çÂåÎõ+üL#Í‘®ô²4Ã["³Áþ—wiõì i;Rl˜s¹­ªI8Ú"‹f¢3ü+&iƒ3¦(~)#Ú"(¯ ´.•(IãÏ Öÿëo«Š¥[È5#bqòÝà0±¯›E?í•cñ‚fÎUš?_¢rw&LçGFFñM€§˜Ü{œÖ¾ÚkÖKË…œu9rÞ‰á°H4ŠÇ—¦e¯œŽ U•oÑÈ ÉMáØŽ)ô1AH¥ž¸Ü=ZüþÿÒ&XKúUüª&'d‰ ª‚$Á”µ“ÎÞý¢ñ‹-J¥÷èZŸßn c/Ëürh¡˜…Ç«5ûj<y[ÄN rºã‹?yö Óâ0ÜΜ `Äß–dz¾cäâŠ1xô'˜Ž;¶�ê•?w)õ‹m; ÿl>8ðä—^\S&lÙh½A‚’8U8$ÄÃõ² õ¨¼r¨8ЍWA‚ÌäÂßcÏAæ«Ù¹¿–)Ø…Pò O[• Ì?¨˜Œ÷¾¿Vÿö÷!ºÛ÷Í®n=Õ§�1ν‚ãG=%zÞ;„ÈŽû¡^yÍ_¸¢àì cÚ2 õJ‚d ×8¨oQmÈ0Ÿ«Ó¸VžŠJðzJzÁÍÍ_µ³ÕìSþè_·-ŸÆÐˆ,[úŠå'Y%t’VðEBc*=T“‰Ð‚±¦ÜãŸÌÉ;1νþAðGgAÒ}(¥ôcâ-6†¯ëºnžÓÚ}~òÔ™µÊ³Ôä¾®ÿdgI©ñ9/Ýk7¥B�¶.0«c_NB}aä„2òŒL'@ÕÒÙÍdëx*‚Z16®Éí¡T"¸8[LD] lE Iý­­ ¢…Çx¹y…3 Äï©Ø[ 5G2ÂrÖÝŠŸÝZæ0ñËÑž�:¨0R’o¢°ér‹í¾Î¥=%I:#<ÄòÞ­_]´ŽRC‰ï4_ÿTÉàÍóF¬‚²?²S|J'Å"_E¦R„õx“¡‚馴Ù‡ÍYçÊÿ, ö–É‚ZƒÕ°|ßLÐ {œ÷‹.'Â&“8ü d~b ŸÄòÖ/ ã…�îœegäœâ¹´Î ¢öÜÜ™+(^¡‚ý×áˆÁ͆׽*úuw߯r¸s¸øf%f9ðTeö(ƒúKîxÜJM\iãl•Püña<ߊ~‹i5Ø‘Ma‡z”B;ßd B‡êI¹Ì¸è$!6ÚÂ9¥3²øÉ*o³ ŠE$ôÖk2êöqKtKFaË™òaŸ(˜àD.•!RIVÃÔôS},†Û!ÂLDŠŽy×ÎŒš£K=GsÿdOyEyð×¹q(:=4]UÃîǃ”¸Œ©Š~ª jS^ r±öX‚\”7ÄŠRÃÆ,’C@çu,jàµâ~U€l˜*¼ÆJ_ +__ÑùRû§(޲Ƈàd¿êP t1º/Dcÿáç¶­%Êû:ü¼8tDÜ=&O¢šœâ;•äöȸž/ŽþŽ4ÓŠUt&ߺ¨v·Oê¨û1>é8㴎4Ny28QS¢ñ™Á³®h¡‡ˆ!a¾ð]Ô�úýgŸ›U¼Aοկ |¥W\m\£ßÒèAÆf”ÿ‘þ¡êBÁ´RSYÑa8\ô·È`-A|7 (“º$&߸®:t0˜Ž "<@ô¨ôšAÁ›Öh‚- >þÊ͹ûìMr™“žû‘c¹:ËïÆ“eMžK˜+'m"å ÖÉßâë5ä40T XÌŒ~+([Tl<¼Ì¶<æ1ÛÔŒ¡R Ç\P-h›c† ’bc—šgÝ™ªævì¬îÆ5Ÿ¯x. œ¾qÁÒ*:¥pd´ôü¡š0Ë<œìÌT‰`Ú8ã!#{ÎØk…‹1-%HvÔi2-pAïŽ0ù|h÷ØÁÀý&ª«ò™!§µïå°XwâsúþuoönqÈ>[v•QD²â96€\g'“c‡#sÕÒË\£&"r!Ò¿d³{5•øH˜¨ß®oå²ÚYcX4“Bm7ÎÐLa~&2°AÝG¥­Å¾2!ù`8&5¤§CZ’z7Î�¤K&êÕ<À2øöeŠ4ÉÇXФݥ9ïuvŒ2­}¸ÙU-„„å»Ç5$íŒóê$«ãý–› ̽–˜ Aérá÷Åѭ¯½ÞL(C(ý#ý‰0 }÷²+5N«Ýa›èå¾[a» ˆE$’àªvI|r#ðÕ‹NŸXqê ‚Ê°‚Ò/Ï:KóàÅs»T­U¶×Ðka¶ÌêJ2 Lþ­ÓÓˆûréJ¤ô‹8K¦ËswlD7p~Ê^_£W|7«¥Џ2 ðXˆlBZ×ÕÆÎÖÄ,8b³Îö{Q0ΞOmÑ*£¡Lí¨V7.„CTbßM%Ó› 4ÜžÛR+Aµ;rê¥Y²u&!<Ùúb>ët›šÛÚxt€‚%îão1›K½†ž„ΰ]¯âÒŸrügª¨<‹{pˆ-i´+Èž¡.¹ËLÉŽºã××¹�wÛåH¯ ‚l 0CB¬H=Žžº¹Ø‚X‹Û†À?0éb–<ÿŠ«ù,^—ÅLo^dqyžâ„Û¦AÚuÕn©¨Äš÷,6ÀPdZŒ¤R¼gIÌó,#v'¨ûuqž6œçá ¦Oñ7³ÞÌ0�� �IDATÝ4kwÞó‚À:¥sßøá³¤ÕÎ-UÇ¥K/y!‰ÿµeÝowk CìÔÒ¨%} ”d@™Doʘ ½z¦Ì"æ€ÔÉ$ÿ UOmsKÐ^yq7?À 6åÛši³Å-z j&tQAÀÀÒ0w,*‹Ò¹”™,ä '8áW±U¯äØý ¹‰É´¢cr{5^îæòÒEý9¾òŠîδàµÉ]õVßè8ÂÝ} Ý{]Ãw¦• I¹Ì(qì«£ý ýÝÈk ¾þoí ©•t’ÈÜæ ì#â@°4’x—L1ðë­à–ö ¨s¨ŽÁgUüÊ9YfÞšÝ:ª€=+Ä‚— ºR%zwŠG¶¤žjÁeóß¹À‡Ó]ܱú|ðtÛ’[Îḧ¹(WáÝŒ§œA�NËoâp¦r_ôÁ¹­<@cu¡§TV™Òtû–!)”{hÍh ìŽªgÁ ©Z;ö«ÜÀòH)|ÄCÓà ƒP¯Ãt]ÒÆïž ÃËGâ±ÏQ 5Žû&l1m6ã¶9Øy£Wl@:m©3 ¹€-ÛbJâêÛû ‰q¹r]ÎtnKâ5«sü"E§æ^áÒwm¥žúô“ô_§6‡ð¨Ü1GßhÞ‰[M(òX-¬ Þwb/˜~ƒ0Å–v²—r´5º€æ7ê–—#%áx5y€xÿÝޞϋÏÎÖuo9A§„Ó ÈPÖ|W•€P'ñ»s¤€¶§Ns±·¸©"÷Rë¹N+?Y•ÇÊ®oÌüí‰»Ž /¨ÔÃÓ-ôœLÝŒœ™PöU‹È!ä&ƒÛ2ã·ÆÊ{^ =ì�Iø@pŽHKú.o»º¸œÔŽIšë^`QÝt@š,ÎÍ×”‚& ž’6ÓEfêL_įa1eUL$mü¢Çç”eô–ÖŠÒ4oW—ÝòVî]r×Í´:¯túQ»T`-éDÅ1»¨´XP‘$²}¡ç«¾¢VìõÍŠØ]ÁŠÐXxÎÌÏbâc ]z02*0ŠC¨ïтԿl§Ðûù!j4ж,yì'[jf‹MV·¬ªƒ Ñ”ÄzÄD>J¦·nV•Úñ¯R»±ÞÓUò‰È‰6{ö¾`ú‰~nwë åÄ{ЃoÉhUsɇö¥Ë´&q•ÆypCÂÏÏŠö(©hWW~,›‘“µxÎÛ+Ö ÄvžK*–$ÅP9WQëÖ™ú<�\Tǽœ`´\œò²õ+„|…ª"â<f狦ßÿ ý]Å+Ÿ!+êÓ»øÿËŽ0cûy+&—â <ÂŒÇéwÃÿ}ºSy©yÖ[S´Û2­ÓGµ‡P¹Y«þHG†ü‚u›ÌÏ]7¶`bÄ· Uò\ +¦þý1÷J»ÜûmPFcD}Äq*6ó¨eGn¤ÇõgÓ/j¹táWÇ€LA®HQ³GÀÔ„ Œ œK¦ßÿ…¨ü—Vá*–Q× £Yãð5‡oVAtM¥ŸÑàûrµ¿”Œû¶¯Ø<a½8#‡ëÝž¾’©äúŠSp¢iè y¨ 8hÌèÍ÷ê?GÂÛ8{ëºLFÉë:-¤C3þµ-ë[KJ…M‹†'X0$û£žˆ¤Ïˆ]µºG¸Ø è1t‹ÔîLpG<žIÆî td¡2\]g¬$â o•�^ëå²OK^9A9–B|Ûáâît¤<”(£yá^¦Êw;9Oê3úDïžAÙÑf@ˆ�*iʳ2‚­³Ï K¬à�­Áeÿ´]òCÈ,åìŒ80T\óú^â3Å1ý„\&üj<Ù¶¸Ýé=Þ†ŸWŠ�Y—s´ˆ´…iV†û?j⯀6|3VÀûÎù½ ïCžL=÷¡c«ã»²£pG¡×áÞ¬Éà»Tü—J7±›älq›Lq3C1Òªz=|IÔ v•P$EÅäôf$Hhi·è Jfëu]ì«„s„’{¢á<ÅÏó¼¯]Æš ó<”Äëz`A1GA¹x¡%[‡È(Áç6y#ö•vëìÀW9•§xG~e§µ¯Õ™©³Å"@Òô„ …%hDôw Ö+RO§cù£¾¢êÙ«7·´Dp$ÖS]Їl*¢ ·ÁÓÍ?ÓB¸‰*$ZížÚÁ<½th3v³¦@½ ‡ÙyÔ%mòÔP3ÊTJœ|p(¸Ã!vr ¢$ínæåÍÖT ä‡ßÈãvLöšÓäU'¯—oãÛ—w_äe³Ù%S@‹+]žååôóÖ  å ˆ¡^ àÙC#Dà<%AÓ >q­{Ú‹ ò†·^Lz¤ê`^X£•°–J†ÐpF?±1Dgž·GÍøU–¨bÇ›E ÑUòïŠ ʆ!¶bÍ—ÄvÝ–�]šsðyð÷³ìðYâ^§]×Sœ–œñÀëü߇°à]ƒèÉd_¢h®& CÕBMöÚCáýcÍ ZkD…^ÅàÁ‘%p(÷Å=K$ ,¨[&‰0?æ´%Lj3¼ æ‰þãÖ9¨NâñÉÁ¬ ¶uàB~¿ITqÆóÍîjˆ˜´À¯øä³²9÷ȯÙÓ’ž5<…Eðø]çñsÌ–ÝÅ¡!N¾oŒr— ôÊ~FtóÌXד™ 0vçŒôéA‘ÍÑ£[19U;A*É[6Œ>OØdÇŠY„üSúk>ÜÞ¯€B°t70o.ÒȬC^á”Qåñ®¶Nßj½8#no˜t°ïàáq_å)øqâ¡L"øÙ/ßñàf +¤°ÿ?š|¥J愈ÿýk_f'–ÕWü.?Ø@8ác¶k©ˆcîvÆ›‚ÇãI?/¤ÖÑzOû÷.(ÆYHº†`ð– •š?ÓsQ=-Ç>€°Ëì'Ž=è$hs)ój§q¥Þë®ø¤2àÀå¿ zPÒ—Í'mú‘ªŸôX¶n@•˜‘ØûN1`ò Sì£Ù) ΡQÖ©a¥PL¡"…ÅaFîThͰW0 ‘›Ê®'\zO;·ÞwkΡ²gæøñ@1»0w¬Ç i ™ÝËŽì„ϰ§dNÔ‹fÒM>0ú–ÙØ‹8-ñ­$íÂÞœCuO{_"ŸC10¼BIÖÅõdC1wú%E¡.·аdT3bÇ£.r`ënÓÍjÁ„É*=ÈŸ'šCþ¬nô¥ˆðPµ|°¬É±P@ÃÕZGtJ’ã«#*o¤½ýÒ{¬ƒ:§óøí(ìÿŠì7øÅ+œÖ‰m²Ÿq"YTrš¤‹ùmñÚÔl )yK‹ º0e lSuJ ±ÊÖQ—ð®U©Ô©˜?µ-¾Þ•wó×mUQKÁI?uÒåA†Dÿkë *y\OX‹ÂĨz2 …ñrZø]cçÒym—Î+| bûˆ[úeÝØÑÍyÇáâŽê£!X£žÌsö‘ &Ÿþº¨Â=<5•wÕßQ·CŸ†sÂ%®ø5¥ªÆÂX sn`X}IýzI=$ˆÉÞc/d?‡ ¨ýé«x >˜5¦åÇoG;…M†PCL²‹Òâ¢S@}¶…¢R!x,‡^«|¯eŸg­õÉë|ÍøðcÜžêååÎøõÖ¾-½Êaw7Sí îeæÛëq`I€ á-Š.ל˜ÓˆMª´Ø3ö œ<w+诬÷â^ÿ€{¸SFDMf-äÏ4jȈZ—{%Docáдº# JÅq~2Ø'—ðQé¥J¶BPzoe€Z<Íå´;Ìçƒæ]gø²)ÚM¹æk:­ST¯+îÈÆ cØ=åîA³<?*N”Ú} Fªš…×!_†ÊÝF •˜’Ç ²RG®—2,$áÁðEzµÊàÏ%´Úçã²›øÁAU�‰ K{Æ^òTS³cëNIPø¼éÝÛR‚'¯w)m®ä2¤Sî\7°æ º™’µxV§#ù*(.ŽÉpeñz¾$H,Äq¥VyòˆoûïOPQP¬CÃg^ÁÐÝŠ5 i›FâX%p—‘l#¸¤@»B˜»tk�¥M'U ^œ³Ð¸cà]¿=Eò¸ý¹Ã ,w;›;ñ÷ýÏ¿ŽÓâç}‘Õ®ÍgG2¼®¾-v? áö™¯%0Cƒú+¥%y*„ò./ä¾Ë˜n´Á°#Ïoò²‘?IoBKÜ„µa±’Dh²9Ô%»3"hsòÙ=¸[Ê[²É'¦Ùš?Ô]áÚ tÉ_Îl€áq¢Zx@:uO‘°{§çI¯ èx TýÛ Óø´“\ù|ì°¾!ë¶| ²q–qì‚„²è’ÌKüôÑ&œ<8 -8—?PC*læÁ-EÇ�…¬µ›éw(²œ]*døý¸7Ï�½©w>ò¶Ä™Ü +¢…20„¥žb.ÊlÞVªyÍ6zrÆ.Íòàë&¶yÌ6(ñ? æyëÁÏhܵjéìƒÁd¥ƒÉÄ´Ì—aÇ/f¦ÄIÈ2¸ûE “ î:§^V͹Ɵé÷¡ç`¹ þõ’3\åZ(Íc™ÒWd§04ÌW»ÏsÐxÓˆßİPj¢àüˆüöá„áë8-9¼k»ÙoϺC1ô ¯!™Ök®ÁZæLâ[@å®8’éJìÆc& wï”–J’Д“ž+bçŠ •-T –`ÏQŸ ÕŒ†2ú¿°2ÙrLø& Õ®¥=IB¸A.X ñ¨P)xn•ÃߘÉç¨ b ñœÛ]^üƒ—K®´`ül;y“G¹Á;¾r¦uÊLû©íÙ²û„yä‡#zK…üŠM@•´Ùô?ПÌ:ù|áÐmlƒPFÂJ¹òó&Åaå?Œ–*`rËaAn¢™FÎ!Iϳp_†ªè´ÏaµÐǯ œœïbýàñä:]r{S,²ôDCœ¤LKÄîAm¼EŽ_ìäßÃiFä”ç¦Q_, JvåU ‚t Ë5kJ¦gƒ Y!îD » Ë!$ŽûÉà6Õ<¯å€ïæ1ä´¬’üÈì”.©.o)HK³cL}üaô·þÆÅÉ#�þel½Æ»‡¥×¶#[ÈßŠÓ¹ØØbÄkÒ/ì7ðX¯œŠ¼zð,P ûï9¹¤‚Ë8¡LFs²÷ºÄÙ]È\ÂdÇöy:$½íÒæõ zQ­µMã¼ ”¬ùоjԮѕ†J:†@6‹—ë>-ÒqÝ©¢R«êÃÁ?Õé!Á•§öb¯lÙÊ zä<™¡½¸Ù^_wÇ,×·Öø5VþÔ¢9‡°0ãDÅòè Dù3ñ²´.'“k ;]qp暌'&-}ü¶tÿ{Á:ŠŠPx•C2<÷£ /v˜ãÆA)EÁjÒPqåbÀâ“äºcAâåÕô‚¨ }Q!48lÑ7â¦kñ‹Á=öm|…5¼2Ã{§TæÅÏíÛ£÷Õ©Gy #oxýò¿Ÿrôë—&ƒáv>‰ œLcÔíxqnÚɦhq#!+ -L|ù¿^/¸®%F-%¦8¥àyƒ^YPU°­m–Ä„/Ö~ ‡å ùóòÁÑF§¬ºìJ©à,‘´eÞ»¼¾×=þã¶/z­õ¦N‹_ò˜ƒv¡·Ú¶PW4(F¸õ²4²díAáÆõQùqqDF”þô@ `Í ä¤gGØùó¨¯füzœ1(J-éDѱxY`æ:1ÀÐÇ™s(ñ lÙ§§zJ†¨eTh*eÒà\ÿÙà鿹™|ÿà>ÓMþ"™Væ†uûÉnX±Ö*)( b'jÊVÀH%Ô4ŠÊ¤g\»ZUq ¡Ý=nÌu熃<H¤¸—lU´ÅÙC¯óÉvjhâ“FâG{“”Þ%°üºkÉØPî§n%™¾ä 2±àYV˜söá‰#eϲ¨Ói™#gæw‡]^ö“ôÆ—´u¤Ð%Ä@‰€ (”EoRžä¾³Þ÷‚H7Ò¦#âw¤ ·c?]cGFÒÙ¨B>m`€‰'#ø›‰baA”‰¶;2>´äÒ—) êuŒj×9Œ<NLMø^ÃubÒÆO:É™iÝäÆòOƒäzÇ(Ó"D’T}¾@‚ŸDݦÀ¹N&¤å¥q«ÔÂ!D“ENDš¢ÐÒKv 8ÝH I³3ù]¦!½ÅíŸ8EÃUîU<WAqBæÍƒ•€8×îÖñ„øO²ó ³¼ÇFIu(ï°È·)ÿ¾ÊsZ¿ûIëÇã?Âÿ…õÏ…è§SªÏÿý³9Úoôƒ¨ý ?üøSûy&ú©_>èÓ¢sø‘1%_ßÛ|øj+þ‰þ¹úáO¢ŸTÀÕýý+"úü·Ù´ÕŽÿÑ? »±•eùù8òÏÏŸü;ú­Ú„¢ŸDòú=i,ÜÇzt/þH$í ülë{Ÿ®î7¢¢Å5|ÕO~V§DERíHP¾~ûyOËÏÍ”ÿ¨þùúü‡Ù½u7ÚRÈc2‚úQýäGFûái~<žØuê«+«cçed¢ŸôCÌ=kPèéjn:zt½ã\gè?.û.9ãB¸gLÞÄ·}—žW dà`V×edpŽ&i8;‹Sº¡^²È!÷/öh)wAþa7Á[¨ \o¼7t.ޜٖ Ù|Ñ \¨Y$£àüƒŒc 0ÌbWÒ#v†…¥S óéÕ5†^ó~Y*K>ÛÌñaŒî‘’Lßh¼Iþt­k–OØ‘¡'83$? Ñvÿ¤âÝpl_ôÇj$–ÂQßÜ/È5nCK¬zlÐöî€ôµ¾=&e×þ‚J£\nÅŽU¯ì©kÎ Á\¯˜GE1Ç YÇ!‹hÏ}^ÒN·Œ½ï™õEöç¥PvßûÎßÏiežÚÓïß(×;EžI›Kh$“ ¹ Ù–mNã°+åFѱç›H¿tÙT á2jCðd‹±Îvbº`ëX·—r xï¹ÅÃÎànÄÆÔÏ€=*b§X0F76øX&Ôë ¥&_R>8=ƒ|5ÇÃoñ¿Ôp1Ÿ'(À'Ð<7ÄÓOþlo?¾)Ö%?DŽõL•q`º øo#&Vƒ�,b›«‚¤8>ÃËÆÈås2 Sè?¤€ÚÁbK͉;…üJpž9b ‹ÇŽ OrÕ¶r,~uoí&x{¯ó>í_ƒGž× Ùkþåπµ1ÂÊ{Ý×» å½Ò;ÛB‘KöŒ`É<yžopèØ 5¹8ò�j–l]ãCå$o ½y&v¾ˆrê—”p6WWò7έ5 Î}ŒBº/oCN¶æµ¿w@Øù°%9Å(ñIß’ßÛ+¨ªîpœ¿ŽÓâ4ƒË)™œO¿Ó}Ä0ëIÀNêÌB‚ïb?xÿú9"KÅÕ¡?ПäQ´+–Mа¨ȱ¼ÁÁÞ]óeÔ°…v¶ãÂ9a 8̃©îu!a{䛣LÔ³NÆÂÝ ¿}º·»¥P¿YA솫à¯kˆÍy:­À¹oŸôí8¸'çèW?JÎN=޳D9MóÃV§",$Ǧ zW„÷Úð¾´ˆøÆTBµnW/_‰À/]Ñ5ØêÖ(à³t¼w0?¸Èßð3>vÖµÜ6önþÛgZ]Ónظ›êøÃ!~8£™XÛ,Ê“í`ÛùІ+fJ‹C;<1“BUf±¥½p{~>uª˜ ±È{™"ÜÂܫЪô—üü[ÃøçE-hÇ–±ð<„¼:ë¡ö¿Gç*lñkpÄ£'ÏäV ïšn~{§•ïåv”¿Î×G[Üc@h e¥õU0Ks«‘ås‘Z’e—ÿBØ8(§³+YþÖp¯bée„àg¬H‚“§6û)„‰< A/Ç¥‘›×îMtZé¬]\|ìüûgã¹·$1Mða~%³súaÛœ÷ØŸo洮莦9œ:<Ö™óŒxQqÁ @ìä.œ%BÅá°8ÐÑTé2{r‚^Ñ &|Ýn¤ ô(×)ÕÇJëAÐ?†VÛR†ü=¶�<iªrðÅ‘qàRæc2xƒÌ¶r…‘׳f|Ò9¼\gñgZýh;1t¬ãÅÃÿ)oá”ÊHƒ½2»¡œ.¡Â—ýme.•Sì—€w"~eF é×G®Pû иßë?&¯Kå#3óaÁÔZñöÁ³¶ �_˜Ijn©c§NaGð"#ȃù~:R§Àù}N~Ï¡~eÈûŽpI"ÛD;D³2ú7ìÕâ–ˆa–MQ«[¬‡’W›²ÔjΨ7áºR1ÕªŒÃ†-1ö”ì*:‰`;N`¹ˆÄqÉ0mõöÓgþ5Éà AÓ]¥?`µï l2y‚gÝÚéÂ}µ2ξ‰ofÜø²#ßí/§rqþñíFíZ†#£¶Wx‡lhÑÒÒ©R\¹rµh¬•âs '-‘;ÓQÈ‹(tI TYR’zÏ+p`ILÍÞ†Å+ý1ò¬2þ¼±/œ ÍA‡)ñˆäŸú'§˜u9öWø~ yÏg¦Óºî )݈ûH ij5îªüµŒ)ˆCé)ãi¬wŒ’-JO¶n›öô «I²Îw!ˆ7êO¨MXGÅ;ÔµÈ!™ô|‚ýq'2c|ÞäßNO&á…÷Áx½¡ï<UîA<ýÓKŽ×Á&¯3‰OpÛ3Ó:gsú=صÈìðþ™Öˆ ƒ4ä”â„ýE½ýÒFDœäxñ²Dèà‘w´yOŸRO‡Ù{í›]È"ÑżØb`~^˜€ÔÐPqSä2dždW‚ůg ï7Ö»D¾Þ?½úú¥1ò/á¥÷÷fzn¯ÇqçÙ´@L‚݉“4�wEŒÇNê (Õ9¢6oL¶[ºAZº ÜÔ=åÜÜñIMŸ,æ2WÈa—äI&ç1Ì­Œ�¨ù-âñ=ÜQ¬»Á£ðàHVç<{Žð,|tg¦5ôîùd}2O;‘¾oPŠMt8¢´•À˜85ßÕd”) !!$$Ö=OAN© ­½ÆÀ)šS´àS¢$ïðSÝ>'^õRïyPîN ¶w2”Šž·]Ú}råÁÏ:ÔdÄx•‹.(K§ÊW2UCíoàZÀð‡ÿ–~!OÚÆVUr,DÍ9 Óäxºãá݈~GÔo#ƒ<Bðw´gWq.vÎTzmv Šz›,»^ÌSšIOçÃåA³pP!E.3‰¯ƒžŸ™ÖÝ+‡¦úA[ËS-ñÒ,üž,©æ–$ün&à•DL-¡ dŸQÂÑàèdÝ··›js{l¼–nO¢8‰iÉœ…8õØ“ È›ƒÄºÐý€½ÉÂS^Ò›óªû…’åÄ;2ÖÛ%dùH–Ût·"©/Ú†C¹CðS(ÉJ//aW=�ù`=Ð~&°Ò3ÐNàù0w奃ù~‰Ñ”G{LïI1Èf˜ìL{  ’(**”˜ìn¶9 ¥“±‰’ê9F ±€¾Ë4Òéèö›K‹Ói½™cë¦G2òöæ}XrŒWÙqIÄãÐËr‡Õ´@'Ý-e'væ°Œæ E‰Cd^e9%n‰OJã°ÙAaØ åÖ1C,RLîÕ‘î5Ê)ön÷Ñõ42ò·2‚€b>q0åç·7ȦӺó6ð¸’ì@1ÍØPƒgœ6ˆ½¯Àe€ ÈÞ2L Þ— n,EÜç½ûU<u1åxˆI4Ï‹XŒqµÐO";á@3l(~‚Þe(¿­~Ë‹˜Åi»f¦õ+d]C@RIçm¾ËÁGPµ» R: A•ˆÄloœ` çA©¦ÎfŽ/¼ì0…Î,T‰ï¸»úH¿.{dI C“›n&ÜÌ8"1¸L«»«;RÞ…O¡g fMo:Ö…^ŠÏ†œQÚ'ѡެ(kªrmI}†Vhß;¦GbãU©.±¿Ï=V¤â»„BÃôq‘öʨùöF›)t3PŸ…ÞÄ÷NšÁsX–ôp¯áwâ¼# :IçDœ_ðÃÑu"Oñ¥ÞôV¿;VþæåGF8MÚGìÔ3µ%`© w ÿƒaFÁÊUÅ#R‚ÿMxжúÀÒØ\ïœÑX©þ Ãü¦d̨7-.`7:t·R@œâ¿HFK9D;-žeÊI/æÖ ¿t/?á/—¨M§u«ëz¾®ö|Ð~'gØV\Ç Jž<5¦H:»Ìàž;IIÀûPbÑz üŸoÁmfã]í-`¿Jl vɧb’ÎÈsÇuz ´­wÕ& éG`tªÂ–Üîc^Áòœ¸ä®|:­|Â÷´9¿ÄÄÀJD™ã6 !è #ê¡iËÙ7ÖQSKžä“ÞF9“Y7…ÈÕ®d®â™`6ä¦Y®Ë¢Š< |_b!®w?dÎ2wç:5HºW_ñ¨[ÑKIAN§uÖÎfªitoqÊ5 =ÊD¡íÐ61ÃÉ›(Jké#;Ê<Šcg‹õy¼hë?Zqò‘èÚcá>™!&í±Îžãô±=­kqCþàÈo“qdÀnÌíñ]–³ÆlÏ2⯘”{¿n:­ç;3ö}‡%ÛG, vj5@xÑ k41h­Öµ"Ÿ]Þ~£4qzû¥KDaÎ>„/i[Gß/ã‰õ_Â7\UnQ8²¡ç‡¥ObxÞînÖEÎlÈK¾Èû쯼`1íms»é´^â¶u)þ(ôJNÉ�º”w¯Òó��ÄIDATê… Aƒ3a¦´ ¦-$•Kcã¥D_lqö¡$ËeŽ«vÌ×ï™y;²tûiÂ\îå.2dsC\{N½¾$¯wjqDÝ‘_ìÿ6çðÒÓÍÓiž5ï¿19Yq J‰»ßìÂ=v§IÝê4ˆ‚Ö;K¬»h¥¥5r!Þz˜QY‰"L*„Zq0íc?•즧£>2º¿¡ò!÷\ËhZÙ Ä-W8Lø�—pEg%Iòò:6úé®î[! §Ó:ñfc7ö€- ©äm›—L5#¦çKººxi"úÂr—&[bìHÈ«jB¡dDŠØ)¬!YBÑHè´ÆF»´¦ò$œx„è˜ð9qŒ÷É+äèv«+¼‘ùæ79Ïé´¾©sg‰v¿T%®Õp.½ë‚$䟵^Ä¡ø'PºÐ[@ãœÒLA!”DÌ‘¡ÒÙÞ](^}Œ•­ôâ‰Ý]“ e">/ÉØc¼¨+*ä'7±ÛÐiÜ?~Ä/c7ø‚ûÎ>o:­+žÎ}<1>¤ªCH~ä®,¯†^Ö Õݨ+l¡*“ìÚ© r=ƒ.ÁŸÀSÞ–.‘¹GõÉþyOéáÇø½Ã%öýp”Ýñ±k?nµOgZÂv^Áóô=‘ Ói|ôå�¸Ö+¸<%ö3¶‘Ø6R̲YœÖÏ-…»ReEÎI&‹xz87—¡âz)ùM¦dóé¬B#¸&%Jˆ”EŸ7=->@µîKMFG8ÑøÊàÛD/ ÷ø¥‹‡Ói]ÇÅÒ|;ÊDP• 60ÄØ²Àå„~«ù­èœÆåÚ0b%__yÒ‘_AÙž«äkVíC,cæ¹½]#'òò¤G”lœÑ¹ q¾Å=õ4±ø.öØ!!®‹,ѯ¾Ncå)”ÁÓi½““³'ðGmÔ÷ã q®Yá{ñxm*K�A~ 0ˆ¯%ºÄ±1Ãbdy>ýe<šÑÿ%ÍÂ^7íJþÆeNÛ 2JœÍìn ñ©Ïí¥uº9Þ= xéí\Ói]›cI" 5™×ÆSr2H6È ‹£éX|RtV|oTöÕʸuZˆ˜È)÷Çæ>«:©É³˜a„ñàWdÚ8‘¦0NCÝ4î‰}޳îã äô@äÓ~[ûvv8Ö3酪ˆ¢K“7xÒA꓊K©­Lâ»2M𞙌F‰ZIæ7~ÊØwKÉî ÷48¨©ÄO0˜€h€2DM™¨<ò(ÔÆ œ@Ûçƒ*q²aνGŽofÐåÝNxfZs ?OgÈw¿Ç[OLé4´fÆ„OÛ.>¶u™œØgy/ù¿e$æ²µ!¹B?«+Auô”žJ¸ä”G“Nï.= 9Û8¼û:ä§Óz 7¶ƒ„jRZö+T*`çñÉ+0Ï!rf‘ßÙ´!ˤ’pºbê Ö I‚ŽFôÜÛWqrD§˜Üç>ÿ|½¾ˆïõ ¤žÛ53­ïvùÔ×L´gjÈýº“Ã'ÏÀßý‰4'YÇyfæ*{ýœ·¥ìO×—yXæˆ>µGñ‡¯û©Õn‡Á÷0…÷øo³Ôò&Æç]Ó¾é´^óÊp pç¸3/9qOÓl­bï¨39ÎïIB{PBŸÌƼq·!öüø*Ö¾’¤þz–ÙzkÑ)~Yeúo™M§õ”\ŠT·÷³7»Kdà¯ãÏYìê\j+£5“Å5»îÎSâ0¯J¦§Éç«R’• “Ô#6‘{þ£¡ºT¢?Tµ“³_¢ƒ�¿!‚’ƒØúD—ð½‡â{Nr:­û™\ó%(0ÊPÈ[ÁG-•rí³ƒçy<³I2Cõa9pÚz¢½%hÏgd¢ ¹þE›ë{®é´^Ç™uykâ>„Ǻ~Kæ+PŽlÔYy¡býêdûÍXð•B§@$îT²?’Ãñ8 þ+x»r2¾ñTï>”rZ¿›ÞãIëGû™Ÿèóè?û¨ â‡v‡…èU¿â0WøH|ûÐeƬ†É?dç4ØÙF^ôŸÿt®ègîZ~ëýñ¯êë>œÍ\MðdzUø>nüÛÜa:ûÓ ¹>F^@îϹ·ã#qÌcßûqÒÉœ·W=¶3Óº1©b?`ß?‘Žõ?×KÆÉh,ß©h ¯±+ï»;Pež'ç¸y½rY4êÍHñ®½âÃ[z„7Ú|«ã79æñ/½ö¬fyðõ“°Ì ±ôøñÄ÷O‰óÑøõdiŽê*4¢:ÖU¦ÚUvY,‡:'â«8Üížòò«D³»$·Ã»˜ŒäîyѮЫ¼ôÝÏwv¿3o:­ï䨼ùb¨~Â#¦dû÷:&üô­§ w ŸÂOZºúѱâÝ[Ê~פŠ�(àaÊ\¹&fTÄä”QÜS¶ôÄ<æ¶”èé{y†}x¯½šNëU<Üò*ÆÙÀ¾™Áª)! ¾B–!žèglFÜ«7(]º÷±W”V’¬s5ÙûøÁl2ðµrå‹pi,B ©î|x,eB§Óz3–„ Æ<¤Ý2‡|»-®:9*).òÈ›/ã„ûãüwµ%MHM;œIpËLq®Å?R_Mw·Åø7“ÜË©çÏgX•;©ûðtZ¯ãÆŽ+¬y^ÝOR¾'eôÜø$ÛJ½šÞ‘íò®šÇ´[õ„ûRü7;ÿ‚~½·ïÅy8åê&÷à/íÀ䌧' ŸõL¼$2­Õ|c‘É]/+•ÃJî˜ÞAFžúø¿ŽÓÇénàŽ0\.È9Î=ë×Дúè“|:ÓòÊ7D6ÓiýŠyØè$óB›6ùµÖ ãYæ|†wÕ‹q<¨Ïh*ÆD!ÐU$Ù4â[fÉ!åäuJö²ëVòyp~+;ðʉàtZßÖñxÆaÜÉ$dyF 6ÕoË[pnH~VOKζjDL(a®L{'®ø˜šðÉéȈlÊ ‰×7óOü'<Ö÷ôvù8}è™ x‡m+šý6K[΃q1ïz“Dï£ú[I{'ƒgÛUpæñƒŒ& »ùo3yCËñH®Ï)¯ÎSßÝõN§õö¹qöY©jw»q·(-�3ÅIV½8±m­Ûß®¤aåàO²ʽxÂ]Óift±Å7ȇ^âBîÍh§ÓúUÒ©ð·…Ü ™ŒÓ9A‹Œð pe4ÝÙ·ÙÎTw‹cš]N8ž<ßUž1ùIJÏ)í÷#íCž/û/væG/y:­·»÷Ü1Áò„<-c-à‹Ö1‹¼æïî:ÉéE˜Ò£Ý8=>Œa‚™ì»4~Þûõ¾W¿îš,ïO_ƒÖVñ…×aûÿâüyÍ{mi›?…ö;gýƒ¨ü¤òA…ÿþ$’¯×oæEýè½Ï5“úOóyÉ!jkûÓßðä,W"ü¬˜¿ÀÿâäeßÿHJý‰}`Ô¡~&üPþô.ÿýß©×xÙ_%‰yK‡=3­7¹ÇN[ÈUýMwÔô�sΔ«# qÈʈªýß©Äé`~è§+™D™¢wêõ9ø…áv7[Ì{ï²E¯å gyð-V²Ã5-^e†b€»c°JÒÑ 7•kyCº©¤Èì•~ck¨äP~Ð¥‡H–O/*y>E{ß »Ë¯©îqÖWì¨è¾úšNëÛeäkºJ€>¾„ÿ*idå<+/Žiî"0wäC‡£åzæ/Œ å¼³â´S¿è‘¸b{ù®4Ö7OËÄy冈à¸7,¼ûyG|ä ýå–/ÓÅi¨øI ÷ÿRÑú+|u²AøômyqÅ÷Á€L Æ÷ 0ýÑÀ> úo­Á…ÐŒuÁyЖÏwÔ†ßë}¾»<ˆ ôŽ¿¥¿å#<±ÇÞ~  ÿpx ¦ñãʧèܯ>ý»>N:·dµ  }¼¶}xâé]»¦ÓzÍõ1þùãl~kíòû‡ù¡¾]rïv®ö3í]ò‰W€…ƒñû9h $á,?ÒYÂÏö?FnñnüÈÇ®tw*|æÅoç½YGøqR@ÀOµÓiÍõ¢©ýö(ÿþdÌôŽ€ôgeýcwŻޮcoàG"WûHoµºÒŸçÝ©æþ±TÈ8¤Êýœ¢ œçnÇOt䓞ç3²ð«_Ï“žÕÓ Åß2ìÇõ_ÿwÿíÿ?üoÿûÿýÿþ?ÿçïÿ‹ÿãïÿþï§Ç˜k®¹æšëuÖ¿ù·ÿþ¯ÿæoÿóúÿëÿü?ÍLk®¹æšk®·YÓiÍ5×\sÍ5Ö\sÍ5×\s½þJýÿ?æ¦Ì5×\sÍõ"«”9­ÕyýîñïúŸîOŽàê?y»ö>@¿£¿üŽþòƒÊçÀÿÍüäŠ?9rÌ·;aÿ'e¾Ioð&ý 7<ãäŸ¼Ý ÃŸÌòà\sÍ5×\﹦Ӛk®¹æšk:­¹æšk®¹æšNk®¹æšk®é´æšk®¹æšk:­¹æšk®¹æšNk®¹æšk®é´æšk®¹æšk:­¹æšk®¹æšNk®¹æšk®é´æšk®¹æšk:­¹æšk®¹æšNk®¹æšk®é´æšk®¹æšk:­¹æšk®¹æšNk®¹æšk®é´æšk®¹æšk:­¹æšk®¹æšNk®¹æšk®ï´þÊùy!úÿæî¼øú Ñ_æ.¼øšoÒ|™æ:ø•9-õë¹æšk®¡õãÇ_ÙŒ¼àåßvJ§<à,Î5×\sÍõ6k:­¹æšëÌõ‹Wk^ðòo;¥Ó¿p:­¹æšk®¹f¦5×\sÍ5×\ÓiÍ5×\sÍ5Ö\sÍ5×\sM§5×\sÍ5×\'­¿š[0×\sY?~üøüëøwàu®ý¶ÛqîÙ‘,ïPÓiÍ5×\çØëõ¿á¿½Ï6äûÝŽ¿Hm`÷Ïgyp®¹æÚ¿~ñ©¬WvÉïrkJ)C§:3­¹æšë››ï_ð^\í´J)Ϫ‚N§5×\sMõ}®ë.½ö›÷a–çšk®é±¾ÏUû{13­¹æškz¬×>÷a:­¹æšk®7X ç==ÖtZsÍ5×û%Ÿ¶û‰]úWpfO¼vøíWœÒÕ_j:­¹æšëœ„#óó_až{íðÛ¯8¥s¿ÈþáœÓšk®¹æšëí×tZsÍ5×\sM§5×\sÍ5×\ÓiÍ5×\sÍ5Ö\sÍ5×\s½úÚЃý7ûÏÿý›ûïç¦Ì5×\sÍõ:ë¯ÿæoÓR¿˜k®¹æšk®Í´þóús/æšk®¹æzñõ£”ò¯þ›ßæFÌ5×\sÍõâëOÿãÿ72ók¢iÎ����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/index.html����������������������������������������������������������������0000644�0001750�0001750�00000021414�11555611701�016320� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Contours - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Contours</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> Contours are curves along which the pixels have a constant value. ds9 can create and display contours as an overlay on a data image. The contours can be copied between frames in the current session or saved to file for future use with ds9. </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li><strong><a href="index.html#create">Creating Contours on a Dataset</a></strong></li> <li><strong><a href="index.html#copy">Copying the Contours to Another Frame</a></strong></li> <li><strong><a href="index.html#save">Saving the Contours</a></strong></li> <li><strong><a href="index.html#convert">Converting to Polygons and Saving</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#dialog">Figure 1: Contour Parameters dialog box</a></li> <li><a href="#xraycontour">Figure 2: X-ray data with contours</a></li> <li><a href="#dssdialog">Figure 3: SAO-DSS Server dialog box</a></li> <li><a href="#dsscontour">Figure 4: X-ray and optical data with contours</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="create">Creating Contours on a Dataset</a></h2> <p> This thread uses Chandra data from an observation of the galaxy cluster Abell 2142 (ObsID 5005). </p> <p> After loading the data into ds9 and setting the desired scale, click on the "Contours" item in the "Analysis" menu to turn on contour display. Open the "Contour Parameters" window from "Analysis → Contours Parameters". There are two sliding scales which are used to set the number and smoothness of the contours and fields for setting the range of values to use. </p> <div class="figure"> <div class="caption"><h3><a name="dialog">Figure 1: Contour Parameters dialog box</a></h3></div> <div><img alt='[The "Contour Parameters" dialog box has sliding scales to set the number and smoothness of the contours and fields for setting the range of values.]' src="dialog.png"></div> </div> <p> Typically, you will want to generate between 1 and 10 contours; larger numbers will take longer to generate and display. A smoothness level of 1 will evaluate the contour at each image pixel, while a level of 2 will evaluate the contour at every other pixel, and so on. A larger smoothing will generate contours more quickly, but less detail will be available. </p> <p> By default, the range of the data scale is filled in as the limits. Under the "Method" menu, there are two choices: </p> <ol type="1"> <li> block (the default) - blocks down the image by the smoothness factor before contours are calculated. The larger the smoothness, the faster the result. </li> <li> smooth - smooths the image before calculating contours. The larger the smoothness, the slower the result. </li> </ol> <p> In this example, the number of levels is set to 6 and the smoothing is set to 5. The contours will be generated over the limit 1 to 100. The default method (block) is used. </p> <p> After clicking the "Generate" button, the list of contours is calculated and displayed in the "Levels" portion of the window. Click "Apply" and the ds9 display is updated with the new contour levels, as shown in <a href="#xraycontour">Figure 2</a>. </p> <div class="figure"> <div class="caption"><h3><a name="xraycontour">Figure 2: X-ray data with contours</a></h3></div> <div><img alt="[Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.]" src="xraycontour.png"></div> </div> <p> The contour parameters can be adjusted until the desired result is achieved. Be sure to click "Generate" whenever an adjustment is made so that the levels are recalculated. </p> <hr> </div> <div class="section"> <h2><a name="copy">Copying the Contours to Another Frame</a></h2> <p> In this section, we take the X-ray contours just generated and display them on an optional image from the Digital Sky Survey (DSS). </p> <p> From the "Analysis → Image Servers" menu, select one of the DSS server options (e.g. "SAO-DSS"). The server dialog box allows you to retrieve an optical image of the field of your observation and load it into a new frame. The default retrieval image size and (RA,Dec) is equal to the size and center of the field currently displayed. Here the width and height have been set to 40, but the (RA,Dec) determined by ds9 are used. </p> <div class="figure"> <div class="caption"><h3><a name="dssdialog">Figure 3: SAO-DSS Server dialog box</a></h3></div> <div><img alt="[The fields for Ra, Dec, width, and height are populated with values determined from the x-ray data image.]" src="dssdialog.png"></div> </div> <p> Click on "Retrieve" and the data is loaded into a new ds9 frame. </p> <p> To copy the x-ray contours: </p> <ol type="1"> <li><p> Select the frame with the X-ray data in it. </p></li> <li><p> Use "Frame → Match Frames → WCS" to align the two images. </p></li> <li><p> To copy the contours, open the "Contour Parameters" dialog again and select "Copy Contours" from the "File" menu. Leave the window open, as it is needed in a future step. </p></li> <li><p> Select the frame with the optical data in it. </p></li> <li><p> Using the "File" menu of the "Contour Parameters" dialog, select "Paste Contours". </p></li> <li><p> Adjust the parameters (if desired) in the small dialog box that is displayed, then click "OK". </p></li> </ol> <p> The optical image now has the x-ray contours overlaid. Since the WCS is the same, correlation between x-ray and optical features may be seen. </p> <div class="figure"> <div class="caption"><h3><a name="dsscontour">Figure 4: X-ray and optical data with contours</a></h3></div> <div><img alt="[The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.]" src="dsscontour.png"></div> </div> <p> To delete contours which have been pasted into a frame, select "Clear" from the "File" menu of the "Contour Parameters" dialog. </p> <hr> </div> <div class="section"> <h2><a name="save">Saving the Contours</a></h2> <p> To save the contours to a text file, choose "Save Contours" from the "File" menu of the "Contour Parameters" dialog. The contours are saved in a text file which can be loaded back into ds9 with the "Load Contours" menu item. </p> <p> The contours generated in this thread have been saved as <a href="ds9.con">ds9.con</a>. </p> <hr> </div> <div class="section"> <h2><a name="convert">Converting to Polygons and Saving</a></h2> <p> The contours can be converted to ds9 polygon regions for use in filtering data. Converting to polygons also allows you to select and/or delete specific contours. </p> <p> <strong>Note that the contours cannot be <a href="index.html#save">saved in ds9 format</a> after converting.</strong> If you wish to save the contours, do so before continuing. </p> <p> To convert the contours, select "Convert to Polygons" from the "File" menu of the "Contour Parameters" dialog. The contours are now defined as ds9 polygons, e.g. </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> polygon(3535.2112,4184.5,3540.5,4179.1154,3548.5,4176.8219,3555.9012,4184.5,3548.5,4191.9558,3540.5,4190.3926) </pre></div> <p> The polygon-shaped contours can be saved as a ds9 region file from the "Region Save → Regions" menu. The region file for these contours has been saved as <a href="a2142.reg">a2142.reg</a>. </p> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">24 Jun 2009</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/thread.xml����������������������������������������������������������������0000644�0001750�0001750�00000016360�11220740726�016317� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="us-ascii" ?> <!DOCTYPE thread> <thread> <info> <version>June 2009</version> <title> <long>Contours</long> </title> <history> <entry day="24" month="June" year="9" who="liz"> Original version <!-- copied in part from CIAO ds9 thread //--> </entry> </history> </info> <text> <overview> <synopsis> <p> Contours are shapes which are drawn on the data at a specified pixel value. ds9 can create and display contours as an overlay on an image. </p> </synopsis> </overview> <sectionlist> <section id="create"> <title>Creating Contours on a Dataset</title> <p> This thread uses Chandra data from an observation of the galaxy cluster Abell 2142 (ObsID 5005). </p> <p> After loading the data into ds9 and setting the desired scale, click on the "Contours" item in the "Analysis" menu to turn on contour display. Open the "Contour Parameters" window from "Analysis &#8594; Contours Parameters". There are two sliding scales which are used to set the number and smoothness of the contours and fields for setting the range of values to use. </p> <figure id="dialog"> <title>Contour Parameters dialog box</title> <description>The "Contour Parameters" dialog box has sliding scales to set the number and smoothness of the contours and fields for setting the range of values.</description> <bitmap format="png">dialog.png</bitmap> </figure> <p> Typically, you will want to generate between 1 and 10 contours; larger numbers will take longer to generate and display. A smoothness level of 1 will evaluate the contour at each image pixel, while a level of 2 will evaluate the contour at every other pixel, and so on. A larger smoothing will generate contours more quickly, but less detail will be available. </p> <p> By default, the range of the data scale is filled in as the limits. Under the "Method" menu, there are two choices: </p> <list type="1"> <li> block (the default) - blocks down the image by the smoothness factor before contours are calculated. The larger the smoothness, the faster the result. </li> <li> smooth - smooths the image before calculating contours. The larger the smoothness, the slower the result. </li> </list> <p> In this example, the number of levels is set to 6 and the smoothing is set to 5. The contours will be generated over the limit 1 to 100. The default method (block) is used. </p> <p> After clicking the "Generate" button, the list of contours is calculated and displayed in the "Levels" portion of the window. Click "Apply" and the ds9 display is updated with the new contour levels, as shown in <figlink id="xraycontour"/>. </p> <figure id="xraycontour"> <title>X-ray data with contours</title> <description>Diffuse emission with contours overlaid; a point source is visible in the upper left corner of the image.</description> <bitmap format="png">xraycontour.png</bitmap> </figure> <p> The contour parameters can be adjusted until the desired result is achieved. Be sure to click "Generate" whenever an adjustment is made so that the levels are recalculated. </p> </section> <section id="copy"> <title>Copying the Contours to Another Frame</title> <p> In this section, we take the X-ray contours just generated and display them on an optional image from the Digital Sky Survey (DSS). </p> <p> From the "Analysis &#8594; Image Servers" menu, select one of the DSS server options (e.g. "SAO-DSS"). The server dialog box allows you to retrieve an optical image of the field of your observation and load it into a new frame. The default retrieval image size and (RA,Dec) is equal to the size and center of the field currently displayed. Here the width and height have been set to 40, but the (RA,Dec) determined by ds9 are used. </p> <figure id="dssdialog"> <title>SAO-DSS Server dialog box</title> <description>The fields for Ra, Dec, width, and height are populated with values determined from the x-ray data image.</description> <bitmap format="png">dssdialog.png</bitmap> </figure> <p> Click on "Retrieve" and the data is loaded into a new ds9 frame. </p> <p> To copy the x-ray contours: </p> <list type="1"> <li><p> Select the frame with the X-ray data in it. </p></li> <li><p> Use "Frame &#8594; Match Frames &#8594; WCS" to align the two images. </p></li> <li><p> To copy the contours, open the "Contour Parameters" dialog again and select "Copy Contours" from the "File" menu. Leave the window open, as it is needed in a future step. </p></li> <li><p> Select the frame with the optical data in it. </p></li> <li><p> Using the "File" menu of the "Contour Parameters" dialog, select "Paste Contours". </p></li> <li><p> Adjust the parameters (if desired) in the small dialog box that is displayed, then click "OK". </p></li> </list> <p> The optical image now has the x-ray contours overlaid. Since the WCS is the same, correlation between x-ray and optical features may be seen. </p> <figure id="dsscontour"> <title>X-ray and optical data with contours</title> <description>The x-ray data is in the left frame and the optical data is in the right frame; both have the x-ray contours displayed on the data.</description> <bitmap format="png">dsscontour.png</bitmap> </figure> <p> To delete contours which have been pasted into a frame, select "Clear" from the "File" menu of the "Contour Parameters" dialog. </p> </section> <section id="save"> <title>Saving the Contours</title> <p> To save the contours to a text file, choose "Save Contours" from the "File" menu of the "Contour Parameters" dialog. The contours are saved in a text file which can be loaded back into ds9 with the "Load Contours" menu item. </p> <p> The contours generated in this thread have been saved as <a href="ds9.con">ds9.con</a>. </p> </section> <section id="convert"> <title>Converting to Polygons and Saving</title> <p> The contours can be converted to ds9 polygon regions for use in filtering data. Converting to polygons also allows you to select and/or delete specific contours. </p> <p> <strong>Note that the contours cannot be <threadlink id="save">saved in ds9 format</threadlink> after converting.</strong> If you wish to save the contours, do so before continuing. </p> <p> To convert the contours, select "Convert to Polygons" from the "File" menu of the "Contour Parameters" dialog. The contours are now defined as ds9 polygons, e.g. </p> <screen> polygon(3535.2112,4184.5,3540.5,4179.1154,3548.5,4176.8219,3555.9012,4184.5,3548.5,4191.9558,3540.5,4190.3926) </screen> <p> The polygon-shaped contours can be saved as a ds9 region file from the "Region Save &#8594; Regions" menu. The region file for these contours has been saved as <a href="a2142.reg">a2142.reg</a>. </p> </section> </sectionlist> </text> </thread> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/dssdialog.png�������������������������������������������������������������0000644�0001750�0001750�00000015456�11332353405�017010� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��È���â���EƒÀY���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ3”Û•��»IDATxÚíyt\Õ}Çï{ófÑŒ4šÑjK¶dã}ÃàBØ1!¤¤iH jrhsÚ’”“œ¤iÙÿJÔæ¤IC“ãš„Ò ) /˜M2Æز°-ËòhßGÓ?ÆLžÞ6oö7šÏçøî{wy÷wï÷ýîï½™+Åb1!ÄÆ­·��ÈŒ}OÜ/„PâªzÓö;è�€ Ù¸õ–}OÜ/mØòÉ›¶ßÑÝ;@��dÈ»Çv¶íUâŒÒ#��Ya�Ç1Øn|8…e´7¬¨¬*l^aS§žjÿÓüJ©²²rjjêOUÓ ÃBG"§ýGŽG&›/ú�C�²ÂøØÈøðÀª•+ígikoBx}þBå5V!IêÔÚ%ÇN½ÜrÓ.—ë‘Gëèïñ‡ê49'ÇG›ýÃïFDýÒšì��é ëÈàªU«RʲjÕª¶övoY Py…Uš©Œn¯o$´äW÷?°ù²M+–/}çÉg¢JÅãSŸ#÷¾-wû›ªÊ+ �-$I’R÷Õ$ùÏk&¬²æ@ \òØÙ½{÷ÕÖÖ,YÐøò[/Ö¯~¿çó÷w¾¶rNð¥£çæ­\Ë8�€¬ «œ–ÀÉïý+@^[ëù€ÀÂÕG^{f` C–åJ×xOÇ+u‹× !{:/‹^ïhZÿÁ¤íh¨©üôõ›–4Õ¹Wßàè‰îs¿|äùÈÀH"ñÃ/~¼&T.„øÊ{²§/‘qÝò¦m^Ý4·Ê%˧{ž9pøÉ—ÅbUüë]ŸýBˆ©©hÿðØ‘Î3ýñõc§z“6Àºm6/�²®¬B'U6]GMÞïáF³Ó¿ú“ÿ±“wÆi†‰«Ytîê+Nì}Ä'Æ…ÓÓýЮ¯ïjïìiX³E’]I¯ô®í[jÃå§{"]§{•åk—Ì‹öE§e—Ë-„XÖ\WU!ÄÚæÊÎSÝŠÛ'„ØréŠíÛ6 !::Oޝ\Ü´ýúKªËwìÞ—ðš5tîkn¬¿tÍ +›ô«'^{»Û¢Šâ±n›ÍKHŠË%G£Ó™ ³ÌK�(…P€He9äÕ—^tYÒ¼ßÿÂ_û·G⟿÷·1Ëk7p~J+Þú5×öÜåv Y–z;ȵu“ÑQóFOYyÒ¦WWjÃåã“·Ýõƒ˜$+no0àöW5*ŠW±yíb!ÄÑcï.^ÐxÍåÿæÉ—*ªÊ˼Ÿ¸v½bçÃ{þóá=ŠÇwÙÅ+îþ»O]³iõîgöõŒ7õ¾ß>õôK¯——û¿rûÍ›Ö.ÿìMW|á{÷Í™SoÖ€úê*ë¶Ù¹„ºpÅ'·nX± Þ­¸ŽœèùÕã{»Îô !v|c»,K÷íÞ»íòUBÄÞ<Þ}ÅÚEÿµgÿãÏ· !n¿ió•-z`ÏÝÏ·Ù,á‹­I‚'„@( ååüÍŸÿªþäþ}õJÝ0ï?ýôÑïþ͇ãzšøœ(P“7…P@°*°`ãxçÞ‘ñhÌåóË=òœyõMv.uhd|lbÒçqç?säTÿ‘Î3‡öûÂ.—KÉ­¸6®jBüôþGï¹ó¶úšðâÆêîÑØòæ9·‹Åüý³åáÚòPí[§GOõôÍ­ ­YÔðø¾Ÿ¿bfžÿ¿"\ã TþzÏÁMk—WUVÔ•‹á³ Z¶-Ñ—àó¸¿ö×[«‚þg÷·õž‹Üxíå_Þ~Í—ÿå¡ñèy üËk/ÞßþöØèè“<pÅÚE/ª{p÷³•Õõë—ÏŸžŽ=üÈcJ ôµ/Ýl§„3ÇÏi^´BÉx¬rZ¹$üË×]a¦ÅÖy¿þ³Ç¾sLJ„UU˜ÚÃ+5Ó#ç¦cb<æ¹ ¶Üãñ¸£v/{2ûÙƒÏ}zÛú.Ûx¡Bt÷ö·>ð§ÎIºhÙ¼€ÏÓ70ôꡎ—¿jýò\ºvÇcû*ü>!ÄØøÄðÈx}íYV\nWßðØÜZQ ,›_}ÛG¯9ÛùßWëžéb{G¢ñÏ•åe§O˜5`ʲmv.aýЦª ÿXWwë/~ã)+ojœ»~Õ¢5M•ûŽFâyrßïv?³×]pÉÊÙ¾Á勚*¼bõ¢¹~Ÿgÿëoõö ~ôª+l– xÊ¢Ñ)ÅíaÖA («,d)\’$ç5+-‘nž÷ë?ßýÏ_?CU7\iPoJ1V!ÄÀ©£SçÞž,« zF&&&ÆÇÇÅÄÙÁ³µóí\ì+GO=ýŸ[é]µ¤é/>xUC}õ¶ þè^ÅSvùš…Bˆ^n—d×·Þ½jýò÷]²öÞ‡žBø¼ž@ LrɲË%$)\BôWø½‹kâ…O ÷Ži¼×ºšó¯E†¦¦§y÷éö6À¢mv.¡*B,˜WÿðOïIœ<§&4xàèùŒíÕsË*B±Øôó¯½ó‘«.ܼnÙ²¥ó„O<»Ï[æ¯ í— É2ï 1Ö4b¬f¥©–ó¦y¿}û6u�áŸï}ܰ^ÕDÑÇ#ƒ/ŽD• Ö_7:Ð{îõ'eBô~Ö[q£W³$×áV\«/˜û²ˆF†‡žk;Y]ûæ-×o.ø"gÞm^²bí’F!Ķ«/Ùvõ%ñó~ßÅKß|çäÄä”Ç­|ìºÍO<!{å 7Ì©®Bìíp׹ї¾Ô9ÓÏ®›¡ï~ŸçS[× !zûÞz»«¦aáºåMÇô hX¸tÍ¢FöÕÎ_”¸Y\Bdh…¢ód÷wþ.Ñ€s}ƒÑ©Éøç‰ÉI?äv»e—òbû‰\uáµ—¯«¯©ÿÓ7ÊBu}ƒ£öK`¾¡€$¹dãP€Yi3BFy¿õ¹­ _5–ýöíÛ¾ñOèëM!0=59üö B’.ÚâöúݵþèÒ+Gßþ“×ëq»ÝC/z×\g}ý·ò÷¿rxlS×™¾XL,™W#„xõPGl:ºqÙ|Å%ŒŽl¼ ±¾qN͵›×ýð×Oý機޶©åæ­WnêŽ yñ¼!Äžçöêè¬nXèñù«·Û;ï¼íc[þj*ÚX_íQ\SÑéýòÁ˜ÊÊÿð‰÷ Mèà¬mÓSQÅ£$½„ýíÇo¾ú¦†ú½ÿ²w{‡ÂÁÀÚ¥M÷>ôô*:!I²ìR$I>}n¨ãÄ™Eóç !~ÿ쾉©hÈ_qðÈ©sýC6K`¾AÉ댇H÷|v‹Ù™ßüÅž™¹ŒßEµá±äMÔ�|ó{â)ßúÜV}½fÂjPñh×+5ž3Á‹ƒ5sã)Uó—öŒœkª˜t»Ý±XìÄñW+®³è ‰ÉéÇžo[<7Ø4·Þëq÷ö üáùƒ<ú´/X}ù… …þáÅ{ÿûñø7m×,mþÁ]-—¬]®Ü÷ØSûž8Ñõá«×/nnp¹äΓgv?óÒÿ®¬¼Òí-s{Ëf~‡LB4ÔWOME#CmGŽ=ðèŽ;ªŸ?93kÀØÄ¤Ù¡X,–è‹K›øîŽ'>vŲ k–\åóE‡uœ8zô¨ä®k^h;¾h~]üQJ’<)•�P"Êj3êÕöÒÓ«.ý€zžèóÆ=MÓŠ,ó&T5^Ë7ùä=Ÿ¹Î¸^MÁñßc}§ëŒæÀH÷Ñf_ÿ«ƒ «ß§®,6==Õµwýò¦h4Ú?0p¸?¨[`qåÓÓÑî㇣““SSã±é˜ìr••‡Ê«j=n_wçቱ‘@euEU]|#ƒñÑá¾î’ê/X) 1Ôv|x`r|<&bŠâ) †Á*—âñx}šZŽ·ï›žŽž¿}¸·,ªq{}O™$Ëf ÅìâñÚ¹—ÛÝw¦ktxprldzzÚåR¯¯²¦¡,PqüÐ!bµó—‚¡Ä ­çÄ‘¡þ^!D՜沊°Çë‹Å¦S*`ÖÓöôªU3~øéž2;yõeמÙ¶C•5sr‘7qšab<oâhäLןU£Óƒ½Íþá·:ÏÕ¯¼ZÈ3¦´ärM×®™è[¾xáàà`ìη‡û½å!³¦Ë²ª›7==% I’\ñ†·Wñø‚5seÙ%»Åíu{}B×/Ë.Ï/DÌçº÷¸?(I²ì’ãn©Çãs©$/AeÝ<¯ì=õ‰ !d—âñ”I.—ˆ ³a~H²u B•µž²þ˜$dÉ%IRLÄ\.·är…ê}þ æö[QÓà+?ÿ« ŠÛ#$I’\)•�P1Ö~Íå×ÙÉeø�*ëy5‰Ö_˜q`èlçᑈ¯iƒâ6P1_ øFïH×Ù7ÆÆÆ&'''G|ëÍ›,üƲ¬ª×¤¸½¾PmßC´>¿G÷{\†„ëÓh€V‡l–àRÜå¡}z•Ñ«¾eв@E&%� °Ðã‚å5ÖniÍ¢ ÖEù«&Dƒ,„Wˆ:Æ�dE¨½ýMͪܚ¶¶CþŠ$É…ÊkËc�(ñGÓmm‡ìg)+¯Œç*T^ca%„�ÒV¹×_^\yM=Ö‘�H0¬óX…ˆì¼ûVz� n½{gB[y;� SZ[[ Bjúúúè&��›ìرC“‚Ç �eV��„��a�@X��a�@X�V��°EÊ[Ô…ÃaÃôH$?‰díôui OÔ¨®:Ãfh²gý¢ì\i®«Ëbk³ÕTCS¦mµœÚ%C"éÈ·™Ýá a™˜9CìÔ•‹•·kÔKy>kϤµ¹hªs.ÜÌ.ykazC"?®�äDX“2NE'Gʨ¿¨x-jAï,dÒ†5j*2󝓿M£4­¯ÑN’šRŽY±j£çgøYø³¹¨Ú¬gRí ûåØéü”K‡œÄXÆÐ›6wÃZc m©/ßì¢Ô^Œæ³Í®P{ú“ ó&íÒLòfÅÜv`mJC0ë"CQÈpø™ÙE}‚&1§#߬÷Òë ërìw~ªÖÇcuJÇìÖg=! ‘ȰpõNc˜FÞB¡™o¦ÔkYAÚiÑ·¹[zkF¾fÒe>ø“–cqQv®7Ï‘“Ù ¬6»µ¨ƒnfNk†3ÄNê8†µcžF½QÕ¬ÈM†Ÿ™],®(§#?ºì ƒ Ûl)Ù€¯âØùã4Ì—™w…ºd³È]Òio8‚g߀¶o…̯ÝÚ.¹uek’yè,Ò,FÎÃLÈÑ‚ÝfœÑ9÷†Lº¢Py­Ù*9‹#D¿ÈÈ]¼ÈÚËiÕiÔ•­s,ÎL$–²¯šCaÍîB ¬BÌ|o]{.^R¿øbgÚé õ9/Éf7ªÏÏõZÌâQ[ªOÃRfV0|x˜áµ›ÙÅl|æy œêÐÊä‹3Ó¶þìFÚ°å“7m¿ãÄ™þÄžWì ��`Ÿø/÷Uùƒáž®ŽÎ¶½|¥� B��+�� ¬��+�� ��+�� �€°�� �_ ~Ý*þõ,��ÈŽÇÚÚÚJ§��dMXQU�€ì‡ZZZè�€”…B·Þ½Ó4���Ù ��� �€°� ¬��€°�….B„B!:�’bs¯U„õ<|9�¬¹óÎ;ñXS†/G�@VÖµÄX�²  �eÒ„ÃáÄçH$¢NLüi‘h³üTs�«ÇšP½¸ð©EVOâ4��<V[¾d$ ‡ÃápX­žêsôŸ ý\ub"ES,�À¬õX“*¯¡'kèç&ªU#Àì÷X“’¶"£�€°¦éÏÒï�€°:Ÿ�( Ò‰±êŸ/iäÒŽOÞe3;À,Vµ¶¾mOÀ0]ŸË¬¨D:.�”J(ÀPï’>Í·ÎEÐ��J×c�€‚ +ßL�BYI�„µta�(ŽP@±`ÿ·Á�ðX“cs��<V��„��a��„��a�(*x+@Þ`M—b|›[—Ž­ÖÂÓÚÚJ'¤Dñ¾ù‹­KÇÖkáiii¡JÄïÃÖøø+7‰Ÿ*ç‡# Dàáä\U5[ðà±&ñAÌ<‘¤'…ؼ³£I=5ýþÖYÌŽ¦ZNA(¢1 ï=;ã9¥1cf£T@±O´ü˜2ínI;»’aeÖ>H1šÙ슬¯ÅpÚ¨G¿µÛÌ¢?šF9ù×ÓâÚ_ǰ÷¬·tKc̘Y3Õê^s¥F¡ž’¶î˜‰…Ù†Wq7ÒhI~­†µ¤ÑcÙ*Çᎃs¦¢áM"1“ÒEi¬±œà—ºÕê¾2ûl˜]3S­(Þ?zq°Îž6rÚÃÎLUÕ)†»®æygk´é/GóYs4n¹8f ·\O'L6çÇXÍZ•´÷’^Žõ˜±pPŠtÍÄìS›Û01ìúnLµ"ÍPL»¹ $•3½¼æs”$–HY¬WsEšU˜áѤ ·RPU}L f‰ö£CfÀÚÿµo>GÙZ­YÖƒAã3ÚÉ’•Úó4àu«"˜Ï³@Uìaé=ƒüôÞ쳑ÙVö† a¤.¥[¯a̰ö ×.ùXw¨ÚK•30§ö@Uó/ _)몚tÌ$}—¦¨åUèB– ïjúŸMóiÎO5ìf^p„°Š|=ó±ßAêX5OKb³»aI½ÅÄ i4-Bá‰2óŒ4›¡€DÜÄ0€’·»¥þyQæ 0{†¨ŽçjŽZg±3z4±6Ãí—S@ÿÅQ#ÞÂÃJµ÷¬­™t�èkIc˜9­' #§6Õ@3T4b¢¦ŸvEökÏ«°ZÄïÍÞ(Ô<I»fRª(i!ÖÚ¿;å8J¹Šb%›¡5­SÒ«%ë/iå§÷ì_”ágûWm³ÃSý\ÈP��@î Å �N_@8<š”P��@aà kÑÀïNbk�BÙ„ßHÇÖ�x¬Ù„ý|°5�+�� �€°�� �€°�ÌFx+@ÞjL—b|ÂŽ­KÇÖkáimm¥R¢xßÅÖ¥ck„µð´´´Ð %â÷ak|üœBŒ��a�˜e¡€”6·“ű?]£ù}x‡ÿx»cÑïÓ',·îHãhæ [×(š…ÂjͬˆšßÖÍú^/àœñƒ­NVk‡T½£>Ýi£³a>ÍbAc6ô{§·ã1¶ÎM54çè·´²Sˆc7å«õ^`ú¡o"Мéœ^!ÿ‹;CëŽÃã„mÖ ©MÍö¸ÖÜÕ:k! Î %í4tE ÕÖúâ6Xýåa¹Ò\“7‹ÖÁÖù\°'}3›"¼ÇÊLËë”3ôL±õ¬¿ƒ–ZW§¹ýub§oQ„ìì æ^a}l]¤¡�Qò‘=%Ÿc×!®ŠÍyÎL+È„Ìdœ¤d2líd»;¹ú‚€:m'ÝùŽUø=˜Ù!†³+¥q’ÝA…­³bS3¿µH·³Î“ǪŸ çŒEFg®R™cYïF}—¦}4Cë`ë\˜Û¬í[V¯œ{¬�.yý�ä/P�0;C�yŽ!� ¬E ¿;‰­d~#[à±föóÁÖ�x¬��+�� ��+�� �€°�@R´¯[ñâ4�@–…µµµ•N�H*Samii¡{��R" Ýz÷ÎÄŸÄX�²  �€°� ¬��+�� ¬��+�� ��+�� �€°�� �c’ìÒ‡ÕF"uzâO‹¼ÖçØÄ¬��Eæ±&”1Ž^àòŒCš�‘Çjí?†Ãa½ÒiRâ稽Wýç”üÐxiI«ÖTš^]��YöX:¥v]Õª¤2½nZK˜aÆ4$Þ°òf^�@v<V½¶š“6q̺ ‰O �Ž$–Õ 7Ð,8†öY«vvÁQ€‡’—ÒŠ>m×2ªQí �š-PúÔ wJ2—¹{«¾a��äUXÕKuÃGRêð¨þI½á9jAL5`ÑŒ¤%ä?ì��%‹­‡WI¥ôÙì„Ì›a¿1��Î ��� �€°� ¬��+�� ¬��+�� ��+�� �€°�� �€°�5Ú_· …Bt �@6…µµµ•N�H*Samii¡{��R" Ýz÷ÎÄŸÄX�²  �€°�8Å!í(©mSÙ} �aͱX¬z\’¤g³à5¾¾¾> ‡8ÞfÃpP 6RœÖ;³Ø/رcG‰ý"5.†s¾áœf#<V��„��a�@X��a�p J16ZÿmëWîãçžcq È®]»Ÿo¸á†ÜU‘£ÂKõÜŒD"%;¿ŠØc¼‡Èà‹[‰Àiªzà 7ÄUO-²à|UÍ|Vâ±:ý†©N ‡Ãê[¨Å™š”„òªÿÔŸ ¹p$ô>lâLMCo7.0ªªž úib8eì'â±:놩±´Y0!¥›-wfçø°»víR'ž‰ ì̹i?µÎiªA€¤f‹;¶W—I’,|Ìô£&òì‹È±°š)£[œ™Sº=â¨æßi-l £)¬÷ZŠ}r)³À6 §2mïÕBpåëâ½æ?‰>âÀ:y '\×Ù1¹fí{¬ 5LÃÇ4Ì›•“Á¦ü%Ôs×®]i+©aÞL û+H;óÂÌe™“Kž•¦5{@iq´X•Ä?ëS’ ÈP[õ4ªìä5K„|.í ÙO$?ûþif³%†¼f!&R®µÕ,%Õ£I³@¡æ¦ýD<V�€’a�@X�V��„��V��Çà¸×­Øsƒq1k`÷öY ÆÅpx¬@’$ì1[éëëkii¡0šWø"� ���„��a�(F´1ÖP(D§��dGXýÁðË}âÖ»wÒ)��©â†=Võ��ÈÈcíéê /��²‚‹Å6n½…Ž��È ûž¸ÿÿââ”UEG����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/ds9.con�������������������������������������������������������������������0000644�0001750�0001750�00000231352�11220740726�015526� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 2.39617839e+02 2.71644106e+01 2.39617474e+02 2.71647525e+01 2.39616775e+02 2.71644112e+01 2.39617473e+02 2.71637275e+01 2.39617839e+02 2.71644106e+01 2.39625462e+02 2.71657727e+01 2.39625155e+02 2.71659682e+01 2.39624814e+02 2.71657731e+01 2.39625155e+02 2.71656428e+01 2.39625462e+02 2.71657727e+01 2.39589828e+02 2.71726237e+01 2.39589828e+02 2.71726237e+01 2.39589828e+02 2.71726237e+01 2.39589828e+02 2.71726237e+01 2.39589828e+02 2.71726237e+01 2.39634708e+02 2.71739667e+01 2.39634380e+02 2.71747869e+01 2.39633960e+02 2.71739672e+01 2.39634379e+02 2.71737391e+01 2.39634708e+02 2.71739667e+01 2.39626954e+02 2.71739718e+01 2.39626698e+02 2.71742453e+01 2.39626506e+02 2.71739721e+01 2.39626697e+02 2.71732886e+01 2.39626954e+02 2.71739718e+01 2.39597628e+02 2.71739873e+01 2.39597510e+02 2.71742151e+01 2.39597339e+02 2.71739874e+01 2.39597509e+02 2.71738631e+01 2.39597628e+02 2.71739873e+01 2.39637672e+02 2.71753312e+01 2.39637453e+02 2.71755799e+01 2.39637111e+02 2.71753316e+01 2.39637452e+02 2.71751706e+01 2.39637672e+02 2.71753312e+01 2.39629771e+02 2.71753366e+01 2.39629771e+02 2.71753366e+01 2.39629771e+02 2.71753366e+01 2.39629771e+02 2.71753366e+01 2.39629771e+02 2.71753366e+01 2.39624522e+02 2.71753399e+01 2.39624588e+02 2.71767066e+01 2.39623628e+02 2.71778460e+01 2.39622603e+02 2.71767078e+01 2.39622091e+02 2.71760869e+01 2.39621605e+02 2.71753417e+01 2.39622090e+02 2.71746581e+01 2.39623626e+02 2.71745433e+01 2.39624522e+02 2.71753399e+01 2.39628543e+02 2.71767041e+01 2.39628236e+02 2.71769145e+01 2.39628000e+02 2.71767044e+01 2.39628236e+02 2.71763138e+01 2.39628543e+02 2.71767041e+01 2.39599326e+02 2.71767199e+01 2.39599048e+02 2.71780866e+01 2.39599048e+02 2.71780866e+01 2.39599048e+02 2.71780866e+01 2.39597511e+02 2.71767206e+01 2.39597511e+02 2.71767206e+01 2.39597511e+02 2.71767206e+01 2.39599047e+02 2.71764163e+01 2.39599326e+02 2.71767199e+01 2.39592075e+02 2.71767228e+01 2.39591366e+02 2.71772356e+01 2.39590927e+02 2.71767233e+01 2.39591366e+02 2.71762408e+01 2.39592075e+02 2.71767228e+01 2.39633358e+02 2.71780676e+01 2.39633506e+02 2.71794341e+01 2.39632848e+02 2.71804596e+01 2.39632678e+02 2.71808013e+01 2.39631655e+02 2.71821687e+01 2.39631622e+02 2.71835354e+01 2.39632851e+02 2.71843155e+01 2.39634169e+02 2.71849003e+01 2.39633237e+02 2.71862676e+01 2.39632854e+02 2.71872929e+01 2.39632662e+02 2.71876347e+01 2.39631319e+02 2.71886985e+01 2.39629783e+02 2.71890032e+01 2.39629783e+02 2.71890032e+01 2.39629783e+02 2.71890032e+01 2.39628246e+02 2.71886626e+01 2.39626710e+02 2.71890052e+01 2.39628247e+02 2.71896876e+01 2.39629169e+02 2.71903703e+01 2.39628248e+02 2.71909566e+01 2.39627634e+02 2.71917379e+01 2.39628079e+02 2.71931043e+01 2.39628250e+02 2.71934459e+01 2.39628763e+02 2.71944705e+01 2.39629788e+02 2.71949824e+01 2.39630940e+02 2.71944691e+01 2.39629787e+02 2.71941545e+01 2.39628323e+02 2.71931042e+01 2.39628863e+02 2.71917372e+01 2.39629784e+02 2.71907116e+01 2.39631320e+02 2.71905967e+01 2.39631935e+02 2.71903685e+01 2.39631758e+02 2.71890019e+01 2.39632854e+02 2.71878623e+01 2.39634391e+02 2.71876335e+01 2.39634391e+02 2.71876335e+01 2.39635772e+02 2.71862659e+01 2.39635926e+02 2.71858102e+01 2.39637461e+02 2.71853536e+01 2.39638077e+02 2.71862642e+01 2.39637944e+02 2.71876310e+01 2.39637464e+02 2.71883147e+01 2.39635928e+02 2.71885435e+01 2.39635416e+02 2.71889994e+01 2.39634392e+02 2.71894825e+01 2.39633186e+02 2.71903676e+01 2.39634394e+02 2.71914406e+01 2.39634813e+02 2.71917332e+01 2.39635010e+02 2.71930997e+01 2.39634396e+02 2.71937835e+01 2.39633958e+02 2.71944671e+01 2.39634397e+02 2.71949224e+01 2.39634704e+02 2.71944666e+01 2.39635932e+02 2.71934718e+01 2.39636879e+02 2.71944651e+01 2.39636593e+02 2.71958319e+01 2.39637472e+02 2.71966123e+01 2.39638131e+02 2.71971975e+01 2.39637473e+02 2.71985646e+01 2.39637473e+02 2.71985646e+01 2.39637014e+02 2.71999316e+01 2.39637475e+02 2.72004438e+01 2.39638174e+02 2.72012975e+01 2.39637784e+02 2.72026644e+01 2.39639014e+02 2.72032102e+01 2.39639892e+02 2.72026629e+01 2.39640549e+02 2.72012958e+01 2.39640549e+02 2.72012958e+01 2.39640549e+02 2.72012958e+01 2.39642086e+02 2.72017502e+01 2.39642598e+02 2.72012942e+01 2.39642084e+02 2.71999280e+01 2.39642084e+02 2.71999280e+01 2.39642084e+02 2.71999280e+01 2.39643621e+02 2.71996990e+01 2.39644005e+02 2.71999265e+01 2.39644006e+02 2.72012932e+01 2.39643931e+02 2.72026599e+01 2.39643624e+02 2.72028554e+01 2.39642088e+02 2.72040280e+01 2.39642088e+02 2.72040280e+01 2.39641513e+02 2.72053950e+01 2.39640554e+02 2.72065346e+01 2.39639371e+02 2.72053966e+01 2.39639016e+02 2.72049413e+01 2.39638358e+02 2.72053973e+01 2.39639017e+02 2.72067635e+01 2.39639017e+02 2.72067635e+01 2.39639787e+02 2.72081296e+01 2.39640555e+02 2.72082809e+01 2.39642093e+02 2.72090390e+01 2.39643629e+02 2.72085824e+01 2.39645166e+02 2.72089798e+01 2.39645743e+02 2.72094919e+01 2.39645167e+02 2.72101756e+01 2.39643630e+02 2.72096373e+01 2.39642180e+02 2.72108612e+01 2.39642315e+02 2.72122278e+01 2.39642096e+02 2.72123798e+01 2.39641788e+02 2.72122282e+01 2.39641955e+02 2.72108614e+01 2.39640557e+02 2.72101031e+01 2.39639021e+02 2.72104079e+01 2.39637995e+02 2.72094976e+01 2.39638711e+02 2.72081304e+01 2.39637481e+02 2.72072202e+01 2.39637097e+02 2.72067649e+01 2.39635943e+02 2.72057407e+01 2.39635431e+02 2.72053994e+01 2.39635942e+02 2.72050574e+01 2.39636966e+02 2.72040317e+01 2.39635941e+02 2.72035500e+01 2.39634405e+02 2.72040334e+01 2.39634405e+02 2.72040334e+01 2.39634022e+02 2.72054004e+01 2.39634407e+02 2.72067668e+01 2.39634407e+02 2.72067668e+01 2.39634407e+02 2.72067668e+01 2.39633091e+02 2.72081343e+01 2.39632872e+02 2.72088178e+01 2.39632745e+02 2.72095012e+01 2.39632874e+02 2.72101845e+01 2.39633385e+02 2.72095008e+01 2.39634409e+02 2.72091584e+01 2.39635946e+02 2.72094990e+01 2.39635946e+02 2.72094990e+01 2.39635946e+02 2.72094990e+01 2.39635676e+02 2.72108659e+01 2.39634412e+02 2.72122334e+01 2.39635950e+02 2.72133712e+01 2.39636206e+02 2.72135988e+01 2.39637334e+02 2.72149647e+01 2.39636875e+02 2.72163317e+01 2.39636914e+02 2.72176983e+01 2.39635954e+02 2.72183823e+01 2.39635315e+02 2.72190661e+01 2.39635601e+02 2.72204326e+01 2.39634420e+02 2.72214096e+01 2.39633908e+02 2.72218004e+01 2.39634421e+02 2.72224075e+01 2.39635650e+02 2.72217992e+01 2.39635957e+02 2.72214573e+01 2.39637109e+02 2.72204315e+01 2.39637493e+02 2.72200896e+01 2.39639030e+02 2.72204301e+01 2.39639030e+02 2.72204301e+01 2.39639030e+02 2.72204301e+01 2.39638006e+02 2.72217975e+01 2.39638520e+02 2.72231638e+01 2.39638137e+02 2.72245308e+01 2.39637497e+02 2.72251007e+01 2.39636728e+02 2.72245318e+01 2.39635959e+02 2.72235561e+01 2.39634422e+02 2.72236223e+01 2.39633142e+02 2.72245343e+01 2.39634253e+02 2.72259002e+01 2.39632888e+02 2.72268122e+01 2.39632010e+02 2.72272683e+01 2.39631523e+02 2.72286353e+01 2.39631353e+02 2.72290910e+01 2.39630914e+02 2.72300024e+01 2.39631354e+02 2.72302506e+01 2.39631968e+02 2.72300017e+01 2.39632890e+02 2.72296284e+01 2.39633835e+02 2.72286338e+01 2.39634426e+02 2.72282063e+01 2.39635524e+02 2.72286326e+01 2.39635068e+02 2.72299996e+01 2.39635965e+02 2.72308687e+01 2.39636478e+02 2.72313653e+01 2.39637504e+02 2.72327312e+01 2.39637504e+02 2.72327312e+01 2.39637645e+02 2.72340978e+01 2.39637505e+02 2.72342687e+01 2.39637365e+02 2.72340980e+01 2.39635967e+02 2.72327323e+01 2.39634430e+02 2.72327334e+01 2.39634430e+02 2.72327334e+01 2.39632892e+02 2.72315196e+01 2.39631355e+02 2.72322473e+01 2.39629819e+02 2.72327365e+01 2.39629819e+02 2.72327365e+01 2.39629478e+02 2.72341033e+01 2.39628284e+02 2.72350608e+01 2.39627823e+02 2.72354711e+01 2.39626747e+02 2.72360697e+01 2.39625979e+02 2.72368389e+01 2.39626493e+02 2.72382052e+01 2.39625213e+02 2.72391822e+01 2.39624598e+02 2.72395731e+01 2.39623676e+02 2.72400862e+01 2.39622140e+02 2.72408046e+01 2.39622037e+02 2.72409413e+01 2.39622140e+02 2.72413968e+01 2.39622909e+02 2.72423075e+01 2.39623678e+02 2.72425172e+01 2.39625216e+02 2.72433994e+01 2.39625370e+02 2.72436726e+01 2.39625901e+02 2.72450389e+01 2.39625603e+02 2.72464058e+01 2.39625219e+02 2.72469527e+01 2.39624561e+02 2.72477731e+01 2.39625220e+02 2.72482852e+01 2.39625701e+02 2.72491391e+01 2.39625221e+02 2.72496275e+01 2.39623684e+02 2.72501165e+01 2.39622829e+02 2.72491408e+01 2.39623272e+02 2.72477739e+01 2.39623066e+02 2.72464074e+01 2.39622143e+02 2.72450412e+01 2.39621683e+02 2.72464082e+01 2.39620607e+02 2.72472061e+01 2.39619070e+02 2.72474835e+01 2.39617918e+02 2.72477770e+01 2.39619071e+02 2.72488014e+01 2.39619264e+02 2.72491429e+01 2.39619072e+02 2.72495986e+01 2.39618836e+02 2.72505099e+01 2.39619073e+02 2.72510564e+01 2.39619535e+02 2.72518761e+01 2.39619074e+02 2.72529014e+01 2.39617537e+02 2.72527884e+01 2.39616511e+02 2.72518778e+01 2.39615999e+02 2.72516048e+01 2.39615719e+02 2.72518783e+01 2.39615341e+02 2.72532452e+01 2.39614976e+02 2.72546120e+01 2.39614464e+02 2.72559790e+01 2.39614464e+02 2.72559790e+01 2.39614464e+02 2.72559790e+01 2.39612927e+02 2.72554673e+01 2.39611390e+02 2.72558098e+01 2.39611082e+02 2.72559808e+01 2.39611390e+02 2.72566639e+01 2.39612928e+02 2.72573465e+01 2.39612928e+02 2.72573465e+01 2.39612928e+02 2.72573465e+01 2.39611391e+02 2.72575425e+01 2.39609853e+02 2.72573481e+01 2.39608317e+02 2.72583511e+01 2.39607087e+02 2.72587161e+01 2.39607219e+02 2.72600827e+01 2.39607165e+02 2.72614494e+01 2.39606781e+02 2.72619963e+01 2.39605244e+02 2.72619629e+01 2.39604405e+02 2.72614508e+01 2.39604218e+02 2.72600842e+01 2.39603705e+02 2.72597690e+01 2.39602552e+02 2.72600850e+01 2.39602425e+02 2.72614517e+01 2.39602169e+02 2.72616037e+01 2.39601145e+02 2.72628189e+01 2.39600632e+02 2.72633658e+01 2.39599607e+02 2.72628196e+01 2.39599095e+02 2.72626832e+01 2.39598875e+02 2.72628199e+01 2.39597942e+02 2.72641870e+01 2.39597649e+02 2.72655538e+01 2.39597559e+02 2.72656514e+01 2.39596790e+02 2.72655542e+01 2.39596021e+02 2.72652811e+01 2.39595509e+02 2.72655547e+01 2.39594484e+02 2.72662384e+01 2.39592946e+02 2.72661536e+01 2.39591409e+02 2.72669230e+01 2.39592947e+02 2.72680406e+01 2.39593387e+02 2.72682889e+01 2.39592948e+02 2.72684993e+01 2.39591410e+02 2.72684849e+01 2.39589873e+02 2.72693836e+01 2.39588335e+02 2.72688033e+01 2.39586798e+02 2.72694168e+01 2.39585260e+02 2.72694877e+01 2.39584821e+02 2.72696587e+01 2.39583723e+02 2.72705132e+01 2.39582186e+02 2.72703429e+01 2.39581609e+02 2.72710264e+01 2.39580649e+02 2.72715961e+01 2.39579111e+02 2.72722571e+01 2.39578958e+02 2.72723938e+01 2.39577574e+02 2.72730092e+01 2.39576036e+02 2.72727591e+01 2.39574499e+02 2.72727856e+01 2.39572961e+02 2.72733894e+01 2.39571424e+02 2.72733898e+01 2.39570057e+02 2.72723962e+01 2.39569886e+02 2.72723158e+01 2.39569827e+02 2.72723962e+01 2.39569886e+02 2.72726695e+01 2.39570765e+02 2.72737627e+01 2.39569887e+02 2.72751295e+01 2.39569887e+02 2.72751295e+01 2.39569887e+02 2.72751295e+01 2.39568349e+02 2.72737632e+01 2.39566811e+02 2.72746747e+01 2.39566372e+02 2.72737636e+01 2.39565273e+02 2.72733842e+01 2.39564312e+02 2.72737640e+01 2.39564078e+02 2.72751307e+01 2.39564351e+02 2.72764974e+01 2.39563736e+02 2.72767253e+01 2.39563224e+02 2.72764976e+01 2.39563121e+02 2.72751309e+01 2.39562198e+02 2.72748157e+01 2.39560661e+02 2.72746758e+01 2.39560543e+02 2.72751314e+01 2.39559833e+02 2.72764981e+01 2.39559124e+02 2.72770449e+01 2.39558285e+02 2.72764984e+01 2.39557805e+02 2.72751318e+01 2.39557586e+02 2.72747901e+01 2.39556560e+02 2.72737653e+01 2.39556048e+02 2.72733926e+01 2.39554510e+02 2.72735244e+01 2.39552973e+02 2.72737657e+01 2.39552973e+02 2.72737657e+01 2.39552973e+02 2.72737657e+01 2.39551435e+02 2.72730825e+01 2.39550512e+02 2.72723993e+01 2.39549897e+02 2.72716184e+01 2.39548359e+02 2.72714233e+01 2.39546822e+02 2.72721263e+01 2.39545284e+02 2.72721719e+01 2.39545114e+02 2.72723997e+01 2.39543747e+02 2.72733937e+01 2.39542868e+02 2.72723998e+01 2.39543593e+02 2.72710331e+01 2.39542722e+02 2.72696665e+01 2.39542209e+02 2.72692109e+01 2.39540672e+02 2.72689832e+01 2.39539441e+02 2.72682999e+01 2.39539134e+02 2.72681480e+01 2.39537596e+02 2.72678443e+01 2.39536059e+02 2.72672065e+01 2.39534521e+02 2.72669332e+01 2.39534521e+02 2.72669332e+01 2.39534521e+02 2.72669332e+01 2.39536059e+02 2.72666178e+01 2.39536963e+02 2.72655665e+01 2.39536059e+02 2.72645903e+01 2.39534522e+02 2.72641998e+01 2.39534522e+02 2.72641998e+01 2.39534522e+02 2.72641998e+01 2.39535290e+02 2.72628332e+01 2.39536059e+02 2.72618870e+01 2.39536618e+02 2.72614665e+01 2.39536059e+02 2.72609696e+01 2.39534522e+02 2.72605554e+01 2.39532984e+02 2.72614665e+01 2.39532984e+02 2.72614665e+01 2.39532984e+02 2.72614665e+01 2.39532765e+02 2.72600998e+01 2.39532984e+02 2.72599631e+01 2.39534137e+02 2.72587332e+01 2.39534522e+02 2.72580498e+01 2.39534983e+02 2.72573665e+01 2.39534522e+02 2.72568540e+01 2.39533561e+02 2.72559998e+01 2.39532984e+02 2.72557435e+01 2.39532472e+02 2.72559998e+01 2.39531447e+02 2.72565855e+01 2.39530737e+02 2.72559997e+01 2.39531191e+02 2.72546331e+01 2.39530974e+02 2.72532664e+01 2.39530525e+02 2.72518997e+01 2.39531447e+02 2.72505331e+01 2.39530218e+02 2.72491663e+01 2.39529910e+02 2.72488247e+01 2.39529526e+02 2.72477996e+01 2.39529910e+02 2.72474269e+01 2.39531447e+02 2.72477997e+01 2.39532985e+02 2.72464331e+01 2.39531448e+02 2.72460060e+01 2.39529910e+02 2.72452182e+01 2.39529718e+02 2.72450663e+01 2.39529910e+02 2.72446108e+01 2.39530935e+02 2.72436997e+01 2.39531448e+02 2.72430164e+01 2.39531667e+02 2.72423331e+01 2.39531789e+02 2.72409664e+01 2.39531448e+02 2.72402831e+01 2.39529911e+02 2.72402830e+01 2.39529398e+02 2.72395996e+01 2.39529399e+02 2.72382330e+01 2.39529911e+02 2.72380052e+01 2.39530526e+02 2.72382330e+01 2.39531448e+02 2.72390531e+01 2.39532985e+02 2.72392782e+01 2.39533818e+02 2.72382332e+01 2.39534522e+02 2.72374419e+01 2.39535823e+02 2.72382332e+01 2.39536059e+02 2.72385065e+01 2.39536401e+02 2.72382332e+01 2.39536059e+02 2.72379847e+01 2.39535246e+02 2.72368665e+01 2.39534932e+02 2.72354999e+01 2.39536059e+02 2.72345603e+01 2.39536700e+02 2.72341332e+01 2.39536059e+02 2.72332790e+01 2.39534522e+02 2.72337232e+01 2.39533544e+02 2.72327665e+01 2.39534522e+02 2.72321287e+01 2.39536059e+02 2.72320832e+01 2.39536521e+02 2.72313999e+01 2.39537596e+02 2.72302041e+01 2.39537750e+02 2.72300332e+01 2.39537904e+02 2.72286666e+01 2.39539133e+02 2.72272999e+01 2.39539133e+02 2.72272999e+01 2.39539646e+02 2.72259332e+01 2.39540158e+02 2.72245665e+01 2.39540670e+02 2.72235415e+01 2.39541988e+02 2.72245665e+01 2.39542207e+02 2.72259332e+01 2.39542976e+02 2.72245665e+01 2.39542207e+02 2.72243712e+01 2.39541055e+02 2.72231999e+01 2.39542207e+02 2.72224544e+01 2.39542756e+02 2.72218331e+01 2.39543744e+02 2.72211498e+01 2.39545002e+02 2.72218330e+01 2.39545281e+02 2.72221064e+01 2.39545665e+02 2.72218330e+01 2.39545281e+02 2.72214914e+01 2.39544666e+02 2.72204664e+01 2.39545281e+02 2.72194414e+01 2.39546818e+02 2.72195552e+01 2.39546946e+02 2.72190996e+01 2.39546818e+02 2.72187959e+01 2.39545622e+02 2.72177330e+01 2.39546510e+02 2.72163663e+01 2.39546220e+02 2.72149996e+01 2.39546817e+02 2.72136329e+01 2.39546817e+02 2.72122663e+01 2.39546817e+02 2.72122663e+01 2.39546817e+02 2.72122663e+01 2.39548354e+02 2.72133595e+01 2.39548661e+02 2.72136328e+01 2.39549891e+02 2.72139972e+01 2.39551120e+02 2.72136326e+01 2.39551427e+02 2.72133592e+01 2.39551940e+02 2.72122659e+01 2.39551427e+02 2.72108992e+01 2.39549890e+02 2.72114688e+01 2.39548354e+02 2.72117195e+01 2.39547695e+02 2.72108996e+01 2.39548354e+02 2.72101540e+01 2.39549890e+02 2.72099232e+01 2.39551427e+02 2.72108992e+01 2.39552964e+02 2.72101019e+01 2.39554500e+02 2.72095322e+01 2.39554500e+02 2.72095322e+01 2.39556037e+02 2.72086027e+01 2.39557574e+02 2.72083170e+01 2.39559110e+02 2.72083927e+01 2.39559494e+02 2.72081649e+01 2.39559669e+02 2.72067982e+01 2.39559110e+02 2.72063013e+01 2.39557881e+02 2.72067985e+01 2.39557574e+02 2.72074818e+01 2.39556037e+02 2.72072543e+01 2.39554500e+02 2.72080517e+01 2.39552963e+02 2.72077102e+01 2.39551427e+02 2.72081659e+01 2.39551427e+02 2.72081659e+01 2.39551427e+02 2.72081659e+01 2.39551287e+02 2.72067993e+01 2.39551427e+02 2.72065715e+01 2.39552963e+02 2.72058880e+01 2.39554500e+02 2.72057251e+01 2.39556036e+02 2.72054321e+01 2.39556036e+02 2.72040654e+01 2.39554499e+02 2.72026989e+01 2.39554499e+02 2.72026989e+01 2.39554499e+02 2.72026989e+01 2.39556036e+02 2.72026987e+01 2.39556036e+02 2.72026987e+01 2.39557573e+02 2.72040652e+01 2.39559109e+02 2.72026983e+01 2.39559109e+02 2.72026983e+01 2.39559109e+02 2.72026983e+01 2.39560646e+02 2.72031081e+01 2.39562183e+02 2.72026978e+01 2.39561118e+02 2.72013313e+01 2.39561414e+02 2.71999646e+01 2.39562182e+02 2.71997692e+01 2.39562840e+02 2.71985977e+01 2.39562181e+02 2.71972311e+01 2.39562181e+02 2.71972311e+01 2.39562181e+02 2.71972311e+01 2.39563266e+02 2.71958643e+01 2.39563717e+02 2.71952430e+01 2.39564678e+02 2.71958640e+01 2.39564486e+02 2.71972307e+01 2.39565084e+02 2.71985973e+01 2.39563719e+02 2.71999642e+01 2.39563719e+02 2.71999642e+01 2.39563104e+02 2.72013310e+01 2.39563719e+02 2.72020763e+01 2.39564817e+02 2.72026973e+01 2.39565256e+02 2.72033806e+01 2.39565695e+02 2.72026971e+01 2.39565256e+02 2.72023556e+01 2.39564487e+02 2.72013307e+01 2.39565255e+02 2.72001591e+01 2.39566792e+02 2.72008422e+01 2.39567560e+02 2.71999634e+01 2.39566791e+02 2.71991436e+01 2.39565474e+02 2.71985972e+01 2.39566791e+02 2.71977769e+01 2.39567350e+02 2.71972301e+01 2.39567943e+02 2.71958634e+01 2.39567098e+02 2.71944969e+01 2.39566790e+02 2.71931303e+01 2.39566790e+02 2.71931303e+01 2.39566448e+02 2.71917637e+01 2.39566789e+02 2.71913731e+01 2.39568326e+02 2.71913428e+01 2.39569862e+02 2.71908933e+01 2.39571207e+02 2.71917626e+01 2.39571399e+02 2.71931292e+01 2.39572936e+02 2.71931289e+01 2.39574472e+02 2.71930042e+01 2.39575496e+02 2.71917615e+01 2.39576008e+02 2.71907852e+01 2.39576599e+02 2.71917612e+01 2.39576667e+02 2.71931279e+01 2.39577546e+02 2.71944943e+01 2.39578911e+02 2.71931273e+01 2.39579082e+02 2.71929905e+01 2.39580618e+02 2.71923068e+01 2.39581130e+02 2.71917599e+01 2.39582154e+02 2.71903929e+01 2.39580617e+02 2.71898468e+01 2.39579849e+02 2.71890270e+01 2.39579080e+02 2.71882818e+01 2.39577982e+02 2.71876609e+01 2.39579080e+02 2.71871349e+01 2.39580616e+02 2.71872045e+01 2.39581128e+02 2.71876599e+01 2.39582153e+02 2.71890263e+01 2.39583689e+02 2.71885475e+01 2.39584640e+02 2.71876588e+01 2.39585225e+02 2.71868176e+01 2.39586761e+02 2.71865192e+01 2.39587041e+02 2.71862913e+01 2.39588297e+02 2.71851727e+01 2.39589834e+02 2.71859487e+01 2.39590858e+02 2.71849233e+01 2.39591369e+02 2.71835564e+01 2.39591369e+02 2.71835564e+01 2.39592905e+02 2.71830302e+01 2.39593674e+02 2.71835555e+01 2.39592906e+02 2.71844100e+01 2.39592138e+02 2.71849228e+01 2.39592907e+02 2.71857425e+01 2.39594443e+02 2.71862885e+01 2.39595979e+02 2.71856046e+01 2.39596620e+02 2.71862877e+01 2.39595980e+02 2.71869713e+01 2.39594443e+02 2.71862885e+01 2.39592907e+02 2.71867447e+01 2.39591371e+02 2.71876564e+01 2.39591371e+02 2.71876564e+01 2.39589835e+02 2.71890237e+01 2.39591372e+02 2.71896443e+01 2.39592225e+02 2.71890227e+01 2.39592908e+02 2.71883392e+01 2.39594444e+02 2.71883911e+01 2.39595981e+02 2.71890212e+01 2.39597517e+02 2.71878817e+01 2.39598798e+02 2.71890201e+01 2.39597518e+02 2.71898748e+01 2.39596750e+02 2.71903876e+01 2.39596665e+02 2.71917543e+01 2.39595983e+02 2.71922515e+01 2.39595445e+02 2.71931215e+01 2.39595984e+02 2.71936527e+01 2.39597328e+02 2.71931207e+01 2.39597520e+02 2.71928928e+01 2.39598032e+02 2.71931204e+01 2.39599057e+02 2.71940310e+01 2.39599671e+02 2.71931197e+01 2.39599056e+02 2.71925733e+01 2.39598479e+02 2.71917535e+01 2.39598286e+02 2.71903869e+01 2.39599054e+02 2.71893616e+01 2.39599182e+02 2.71890199e+01 2.39600590e+02 2.71880797e+01 2.39602126e+02 2.71879252e+01 2.39603279e+02 2.71890180e+01 2.39603664e+02 2.71895645e+01 2.39604222e+02 2.71890176e+01 2.39603663e+02 2.71884105e+01 2.39602702e+02 2.71876516e+01 2.39603662e+02 2.71866750e+01 2.39605198e+02 2.71869671e+01 2.39605813e+02 2.71876502e+01 2.39606736e+02 2.71883331e+01 2.39607394e+02 2.71876494e+01 2.39608271e+02 2.71871023e+01 2.39608830e+02 2.71876487e+01 2.39609297e+02 2.71890151e+01 2.39608273e+02 2.71897966e+01 2.39607659e+02 2.71903826e+01 2.39608274e+02 2.71908139e+01 2.39609426e+02 2.71903817e+01 2.39609810e+02 2.71899260e+01 2.39611345e+02 2.71890141e+01 2.39611345e+02 2.71890141e+01 2.39611612e+02 2.71876473e+01 2.39611344e+02 2.71865541e+01 2.39609807e+02 2.71862815e+01 2.39609807e+02 2.71862815e+01 2.39609166e+02 2.71849152e+01 2.39609806e+02 2.71837760e+01 2.39611342e+02 2.71841331e+01 2.39612110e+02 2.71835470e+01 2.39612878e+02 2.71828633e+01 2.39613646e+02 2.71835462e+01 2.39614415e+02 2.71843658e+01 2.39614769e+02 2.71835456e+01 2.39615182e+02 2.71821787e+01 2.39615950e+02 2.71820264e+01 2.39616257e+02 2.71821781e+01 2.39617231e+02 2.71835442e+01 2.39617487e+02 2.71838857e+01 2.39617668e+02 2.71835440e+01 2.39619023e+02 2.71822620e+01 2.39620236e+02 2.71835425e+01 2.39620561e+02 2.71844534e+01 2.39622097e+02 2.71839730e+01 2.39622755e+02 2.71835410e+01 2.39622095e+02 2.71821747e+01 2.39620559e+02 2.71829349e+01 2.39619279e+02 2.71821764e+01 2.39619022e+02 2.71819488e+01 2.39618473e+02 2.71808102e+01 2.39618252e+02 2.71794437e+01 2.39619020e+02 2.71789877e+01 2.39619789e+02 2.71794428e+01 2.39620558e+02 2.71803534e+01 2.39621172e+02 2.71808086e+01 2.39622095e+02 2.71821747e+01 2.39623631e+02 2.71809780e+01 2.39625167e+02 2.71808062e+01 2.39625167e+02 2.71808062e+01 2.39626703e+02 2.71799852e+01 2.39628239e+02 2.71808043e+01 2.39628239e+02 2.71808043e+01 2.39629776e+02 2.71814245e+01 2.39630367e+02 2.71808029e+01 2.39630543e+02 2.71794361e+01 2.39631311e+02 2.71792404e+01 2.39632462e+02 2.71780682e+01 2.39632846e+02 2.71776124e+01 2.39633358e+02 2.71780676e+01 2.39629993e+02 2.71780698e+01 2.39629774e+02 2.71787533e+01 2.39629646e+02 2.71780700e+01 2.39629773e+02 2.71779181e+01 2.39629993e+02 2.71780698e+01 2.39617902e+02 2.71780772e+01 2.39617484e+02 2.71786631e+01 2.39617064e+02 2.71780777e+01 2.39617483e+02 2.71775649e+01 2.39617902e+02 2.71780772e+01 2.39592903e+02 2.71780892e+01 2.39592903e+02 2.71780892e+01 2.39592903e+02 2.71780892e+01 2.39592903e+02 2.71780892e+01 2.39592903e+02 2.71780892e+01 2.39616926e+02 2.71794444e+01 2.39615948e+02 2.71800827e+01 2.39615315e+02 2.71794453e+01 2.39615948e+02 2.71788072e+01 2.39616926e+02 2.71794444e+01 2.39598281e+02 2.71794536e+01 2.39599049e+02 2.71805922e+01 2.39599562e+02 2.71808197e+01 2.39599562e+02 2.71821864e+01 2.39600587e+02 2.71835526e+01 2.39602123e+02 2.71830964e+01 2.39602252e+02 2.71835519e+01 2.39602124e+02 2.71836495e+01 2.39600876e+02 2.71849192e+01 2.39600588e+02 2.71854318e+01 2.39600012e+02 2.71849195e+01 2.39599051e+02 2.71842366e+01 2.39597954e+02 2.71835538e+01 2.39598932e+02 2.71821867e+01 2.39597513e+02 2.71812226e+01 2.39596233e+02 2.71808212e+01 2.39596814e+02 2.71794543e+01 2.39597512e+02 2.71788845e+01 2.39598281e+02 2.71794536e+01 2.39579635e+02 2.71794604e+01 2.39579077e+02 2.71800680e+01 2.39578638e+02 2.71794607e+01 2.39579077e+02 2.71791569e+01 2.39579635e+02 2.71794604e+01 2.39611647e+02 2.71808139e+01 2.39612109e+02 2.71821803e+01 2.39611341e+02 2.71828641e+01 2.39609805e+02 2.71830927e+01 2.39608268e+02 2.71823066e+01 2.39608098e+02 2.71821824e+01 2.39608267e+02 2.71808157e+01 2.39608267e+02 2.71808157e+01 2.39608267e+02 2.71808157e+01 2.39609804e+02 2.71817911e+01 2.39611084e+02 2.71808142e+01 2.39611340e+02 2.71806433e+01 2.39611647e+02 2.71808139e+01 2.39593377e+02 2.71808223e+01 2.39592904e+02 2.71812781e+01 2.39591675e+02 2.71808230e+01 2.39592904e+02 2.71804020e+01 2.39593377e+02 2.71808223e+01 2.39582699e+02 2.71808261e+01 2.39582150e+02 2.71816805e+01 2.39581296e+02 2.71808266e+01 2.39582150e+02 2.71799721e+01 2.39582699e+02 2.71808261e+01 2.39639434e+02 2.71821633e+01 2.39640532e+02 2.71833014e+01 2.39640686e+02 2.71835290e+01 2.39640533e+02 2.71837569e+01 2.39638997e+02 2.71840428e+01 2.39637844e+02 2.71835311e+01 2.39637459e+02 2.71826203e+01 2.39636947e+02 2.71821651e+01 2.39637458e+02 2.71818914e+01 2.39638995e+02 2.71818903e+01 2.39639434e+02 2.71821633e+01 2.39625680e+02 2.71821725e+01 2.39626705e+02 2.71827186e+01 2.39628022e+02 2.71835377e+01 2.39628051e+02 2.71849044e+01 2.39628243e+02 2.71851776e+01 2.39629779e+02 2.71852069e+01 2.39630394e+02 2.71849028e+01 2.39630700e+02 2.71835360e+01 2.39629778e+02 2.71830810e+01 2.39628241e+02 2.71832642e+01 2.39627472e+02 2.71821714e+01 2.39626704e+02 2.71813909e+01 2.39625680e+02 2.71821725e+01 2.39605786e+02 2.71821835e+01 2.39605196e+02 2.71830380e+01 2.39603659e+02 2.71823948e+01 2.39602891e+02 2.71821849e+01 2.39603659e+02 2.71817941e+01 2.39605195e+02 2.71817283e+01 2.39605786e+02 2.71821835e+01 2.39580614e+02 2.71821934e+01 2.39580614e+02 2.71821934e+01 2.39580614e+02 2.71821934e+01 2.39580614e+02 2.71821934e+01 2.39580614e+02 2.71821934e+01 2.39573701e+02 2.71821954e+01 2.39572933e+02 2.71829548e+01 2.39572079e+02 2.71821958e+01 2.39572932e+02 2.71814363e+01 2.39573701e+02 2.71821954e+01 2.39636436e+02 2.71835321e+01 2.39635924e+02 2.71839880e+01 2.39634388e+02 2.71844446e+01 2.39634080e+02 2.71835337e+01 2.39634387e+02 2.71829868e+01 2.39635923e+02 2.71830769e+01 2.39636436e+02 2.71835321e+01 2.39589449e+02 2.71835571e+01 2.39588297e+02 2.71843776e+01 2.39587877e+02 2.71835577e+01 2.39588296e+02 2.71832647e+01 2.39589449e+02 2.71835571e+01 2.39607598e+02 2.71849160e+01 2.39606734e+02 2.71859414e+01 2.39606105e+02 2.71849167e+01 2.39606733e+02 2.71842331e+01 2.39607598e+02 2.71849160e+01 2.39587273e+02 2.71849246e+01 2.39586761e+02 2.71853803e+01 2.39585225e+02 2.71856086e+01 2.39584526e+02 2.71849255e+01 2.39585224e+02 2.71837864e+01 2.39586761e+02 2.71847729e+01 2.39587273e+02 2.71849246e+01 2.39582664e+02 2.71849261e+01 2.39582152e+02 2.71853363e+01 2.39580615e+02 2.71856627e+01 2.39579983e+02 2.71849270e+01 2.39580615e+02 2.71842890e+01 2.39582151e+02 2.71844138e+01 2.39582664e+02 2.71849261e+01 2.39643992e+02 2.71862599e+01 2.39643608e+02 2.71868069e+01 2.39642840e+02 2.71862608e+01 2.39643608e+02 2.71859185e+01 2.39643992e+02 2.71862599e+01 2.39623464e+02 2.71862739e+01 2.39622099e+02 2.71871858e+01 2.39620870e+02 2.71876421e+01 2.39622100e+02 2.71879291e+01 2.39623102e+02 2.71890074e+01 2.39623126e+02 2.71903741e+01 2.39623638e+02 2.71910571e+01 2.39625175e+02 2.71908698e+01 2.39625789e+02 2.71903724e+01 2.39625174e+02 2.71892795e+01 2.39625003e+02 2.71890063e+01 2.39623636e+02 2.71880960e+01 2.39622868e+02 2.71876409e+01 2.39623635e+02 2.71865471e+01 2.39624147e+02 2.71862735e+01 2.39623634e+02 2.71855905e+01 2.39623464e+02 2.71862739e+01 2.39576775e+02 2.71862945e+01 2.39576007e+02 2.71872709e+01 2.39575308e+02 2.71862949e+01 2.39576006e+02 2.71856735e+01 2.39576775e+02 2.71862945e+01 2.39573446e+02 2.71862954e+01 2.39572934e+02 2.71867056e+01 2.39572579e+02 2.71862956e+01 2.39572934e+02 2.71857831e+01 2.39573446e+02 2.71862954e+01 2.39648603e+02 2.71876230e+01 2.39648219e+02 2.71884043e+01 2.39647877e+02 2.71876236e+01 2.39648218e+02 2.71873196e+01 2.39648603e+02 2.71876230e+01 2.39642073e+02 2.71876280e+01 2.39642073e+02 2.71876280e+01 2.39642073e+02 2.71876280e+01 2.39642073e+02 2.71876280e+01 2.39642073e+02 2.71876280e+01 2.39599821e+02 2.71876529e+01 2.39599054e+02 2.71887922e+01 2.39597773e+02 2.71876538e+01 2.39599053e+02 2.71870838e+01 2.39599821e+02 2.71876529e+01 2.39652947e+02 2.71889862e+01 2.39652829e+02 2.71890839e+01 2.39652727e+02 2.71889864e+01 2.39652829e+02 2.71889009e+01 2.39652947e+02 2.71889862e+01 2.39614248e+02 2.71890125e+01 2.39614419e+02 2.71903791e+01 2.39614572e+02 2.71890123e+01 2.39614418e+02 2.71886708e+01 2.39614248e+02 2.71890125e+01 2.39585885e+02 2.71890251e+01 2.39586763e+02 2.71903914e+01 2.39587377e+02 2.71890245e+01 2.39586762e+02 2.71886343e+01 2.39585885e+02 2.71890251e+01 2.39577544e+02 2.71890277e+01 2.39577544e+02 2.71890277e+01 2.39577544e+02 2.71890277e+01 2.39577544e+02 2.71890277e+01 2.39577544e+02 2.71890277e+01 2.39641307e+02 2.71903619e+01 2.39640540e+02 2.71913875e+01 2.39639004e+02 2.71917302e+01 2.39639004e+02 2.71917302e+01 2.39639004e+02 2.71917302e+01 2.39638234e+02 2.71903641e+01 2.39639002e+02 2.71896802e+01 2.39640538e+02 2.71899525e+01 2.39641307e+02 2.71903619e+01 2.39620181e+02 2.71903758e+01 2.39620566e+02 2.71910589e+01 2.39621077e+02 2.71903753e+01 2.39620565e+02 2.71902902e+01 2.39620181e+02 2.71903758e+01 2.39582154e+02 2.71903929e+01 2.39583691e+02 2.71913036e+01 2.39584458e+02 2.71903922e+01 2.39583690e+02 2.71900888e+01 2.39582154e+02 2.71903929e+01 2.39574471e+02 2.71903952e+01 2.39574471e+02 2.71903952e+01 2.39572935e+02 2.71903955e+01 2.39571399e+02 2.71913070e+01 2.39570886e+02 2.71903960e+01 2.39571398e+02 2.71898493e+01 2.39572935e+02 2.71903955e+01 2.39574471e+02 2.71903952e+01 2.39574471e+02 2.71903952e+01 2.39556034e+02 2.71903988e+01 2.39556034e+02 2.71903988e+01 2.39556034e+02 2.71903988e+01 2.39556034e+02 2.71903988e+01 2.39556034e+02 2.71903988e+01 2.39645867e+02 2.71917251e+01 2.39645150e+02 2.71924090e+01 2.39644253e+02 2.71917264e+01 2.39645149e+02 2.71911629e+01 2.39645867e+02 2.71917251e+01 2.39589222e+02 2.71917572e+01 2.39589398e+02 2.71931238e+01 2.39588814e+02 2.71944907e+01 2.39589838e+02 2.71948320e+01 2.39590145e+02 2.71944902e+01 2.39590221e+02 2.71931235e+01 2.39591373e+02 2.71923776e+01 2.39592910e+02 2.71917558e+01 2.39591373e+02 2.71911352e+01 2.39589836e+02 2.71914153e+01 2.39589222e+02 2.71917572e+01 2.39564058e+02 2.71917641e+01 2.39563717e+02 2.71919464e+01 2.39563278e+02 2.71917643e+01 2.39563717e+02 2.71914909e+01 2.39564058e+02 2.71917641e+01 2.39651856e+02 2.71930871e+01 2.39651297e+02 2.71935431e+01 2.39650272e+02 2.71930884e+01 2.39651296e+02 2.71927838e+01 2.39651856e+02 2.71930871e+01 2.39624562e+02 2.71931065e+01 2.39625177e+02 2.71934966e+01 2.39625484e+02 2.71931060e+01 2.39625176e+02 2.71928025e+01 2.39624562e+02 2.71931065e+01 2.39570785e+02 2.71944961e+01 2.39569863e+02 2.71951270e+01 2.39568519e+02 2.71958632e+01 2.39569305e+02 2.71972297e+01 2.39569864e+02 2.71985963e+01 2.39569864e+02 2.71985963e+01 2.39571401e+02 2.71991653e+01 2.39572499e+02 2.71985956e+01 2.39572937e+02 2.71980489e+01 2.39573859e+02 2.71972286e+01 2.39572937e+02 2.71967164e+01 2.39571401e+02 2.71968876e+01 2.39570691e+02 2.71958627e+01 2.39571400e+02 2.71950426e+01 2.39572083e+02 2.71944957e+01 2.39571399e+02 2.71931292e+01 2.39570785e+02 2.71944961e+01 2.39562693e+02 2.71944977e+01 2.39562181e+02 2.71947711e+01 2.39561412e+02 2.71944979e+01 2.39562181e+02 2.71942566e+01 2.39562693e+02 2.71944977e+01 2.39640763e+02 2.71958289e+01 2.39640544e+02 2.71961708e+01 2.39639776e+02 2.71958297e+01 2.39640544e+02 2.71955558e+01 2.39640763e+02 2.71958289e+01 2.39625947e+02 2.71958390e+01 2.39626715e+02 2.71960338e+01 2.39627099e+02 2.71958383e+01 2.39626715e+02 2.71955652e+01 2.39625947e+02 2.71958390e+01 2.39621751e+02 2.71958416e+01 2.39622106e+02 2.71966613e+01 2.39623028e+02 2.71958408e+01 2.39622105e+02 2.71953289e+01 2.39621751e+02 2.71958416e+01 2.39584888e+02 2.71958587e+01 2.39585229e+02 2.71965419e+01 2.39585844e+02 2.71958584e+01 2.39585229e+02 2.71954681e+01 2.39584888e+02 2.71958587e+01 2.39575498e+02 2.71972282e+01 2.39576010e+02 2.71973523e+01 2.39576779e+02 2.71972279e+01 2.39576010e+02 2.71970003e+01 2.39575498e+02 2.71972282e+01 2.39659190e+02 2.71985476e+01 2.39658985e+02 2.71987186e+01 2.39658601e+02 2.71985481e+01 2.39658985e+02 2.71983656e+01 2.39659190e+02 2.71985476e+01 2.39655912e+02 2.71985504e+01 2.39655912e+02 2.71985504e+01 2.39654376e+02 2.71990072e+01 2.39653863e+02 2.71985521e+01 2.39654375e+02 2.71977317e+01 2.39655912e+02 2.71985504e+01 2.39655912e+02 2.71985504e+01 2.39631903e+02 2.71985685e+01 2.39632864e+02 2.71994220e+01 2.39634400e+02 2.71986387e+01 2.39634912e+02 2.71985664e+01 2.39634400e+02 2.71982251e+01 2.39632863e+02 2.71974289e+01 2.39631903e+02 2.71985685e+01 2.39626599e+02 2.71985719e+01 2.39626717e+02 2.71986961e+01 2.39626808e+02 2.71985718e+01 2.39626717e+02 2.71983766e+01 2.39626599e+02 2.71985719e+01 2.39560865e+02 2.71985980e+01 2.39560645e+02 2.71992814e+01 2.39560474e+02 2.71985981e+01 2.39560645e+02 2.71983247e+01 2.39560865e+02 2.71985980e+01 2.39639011e+02 2.71999302e+01 2.39639011e+02 2.71999302e+01 2.39639011e+02 2.71999302e+01 2.39639011e+02 2.71999302e+01 2.39639011e+02 2.71999302e+01 2.39589750e+02 2.71999570e+01 2.39589840e+02 2.72000329e+01 2.39589943e+02 2.71999569e+01 2.39589840e+02 2.71995014e+01 2.39589750e+02 2.71999570e+01 2.39557914e+02 2.71999651e+01 2.39557572e+02 2.72002385e+01 2.39557188e+02 2.71999652e+01 2.39557572e+02 2.71996919e+01 2.39557914e+02 2.71999651e+01 2.39652842e+02 2.72012863e+01 2.39652842e+02 2.72012863e+01 2.39652842e+02 2.72012863e+01 2.39652842e+02 2.72012863e+01 2.39652842e+02 2.72012863e+01 2.39633964e+02 2.72013004e+01 2.39632867e+02 2.72022773e+01 2.39632252e+02 2.72026682e+01 2.39631331e+02 2.72034888e+01 2.39630819e+02 2.72040358e+01 2.39631332e+02 2.72044911e+01 2.39631890e+02 2.72040351e+01 2.39632868e+02 2.72031648e+01 2.39633635e+02 2.72026673e+01 2.39634403e+02 2.72019834e+01 2.39635171e+02 2.72012996e+01 2.39634402e+02 2.72010516e+01 2.39633964e+02 2.72013004e+01 2.39629665e+02 2.72013033e+01 2.39629793e+02 2.72014740e+01 2.39630177e+02 2.72013029e+01 2.39629793e+02 2.72011513e+01 2.39629665e+02 2.72013033e+01 2.39572554e+02 2.72013290e+01 2.39572939e+02 2.72017389e+01 2.39574091e+02 2.72013286e+01 2.39572938e+02 2.72007431e+01 2.39572554e+02 2.72013290e+01 2.39569646e+02 2.72013296e+01 2.39569865e+02 2.72020129e+01 2.39570145e+02 2.72013295e+01 2.39569865e+02 2.72004185e+01 2.39569646e+02 2.72013296e+01 2.39554115e+02 2.72013323e+01 2.39552963e+02 2.72017424e+01 2.39552578e+02 2.72013325e+01 2.39552962e+02 2.72005124e+01 2.39554115e+02 2.72013323e+01 2.39646697e+02 2.72026578e+01 2.39646697e+02 2.72026578e+01 2.39646697e+02 2.72026578e+01 2.39646697e+02 2.72026578e+01 2.39646697e+02 2.72026578e+01 2.39620501e+02 2.72026756e+01 2.39620574e+02 2.72027377e+01 2.39620766e+02 2.72026755e+01 2.39620574e+02 2.72026162e+01 2.39620501e+02 2.72026756e+01 2.39662406e+02 2.72040114e+01 2.39662065e+02 2.72043154e+01 2.39661625e+02 2.72040121e+01 2.39662064e+02 2.72035562e+01 2.39662406e+02 2.72040114e+01 2.39656175e+02 2.72053835e+01 2.39655920e+02 2.72064087e+01 2.39655631e+02 2.72053839e+01 2.39655919e+02 2.72051679e+01 2.39656175e+02 2.72053835e+01 2.39647469e+02 2.72067572e+01 2.39646701e+02 2.72068629e+01 2.39646530e+02 2.72067579e+01 2.39646701e+02 2.72066335e+01 2.39647469e+02 2.72067572e+01 2.39642571e+02 2.72067609e+01 2.39642092e+02 2.72077375e+01 2.39640993e+02 2.72067621e+01 2.39642090e+02 2.72061401e+01 2.39642571e+02 2.72067609e+01 2.39628920e+02 2.72081371e+01 2.39629799e+02 2.72086335e+01 2.39630237e+02 2.72081362e+01 2.39629798e+02 2.72073556e+01 2.39628920e+02 2.72081371e+01 2.39665298e+02 2.72094755e+01 2.39665144e+02 2.72095999e+01 2.39665004e+02 2.72094758e+01 2.39665144e+02 2.72093390e+01 2.39665298e+02 2.72094755e+01 2.39648411e+02 2.72094898e+01 2.39648240e+02 2.72096418e+01 2.39647984e+02 2.72094901e+01 2.39648240e+02 2.72091483e+01 2.39648411e+02 2.72094898e+01 2.39547256e+02 2.72095329e+01 2.39546817e+02 2.72098063e+01 2.39546510e+02 2.72095330e+01 2.39546817e+02 2.72089863e+01 2.39547256e+02 2.72095329e+01 2.39650461e+02 2.72108548e+01 2.39649780e+02 2.72122220e+01 2.39649780e+02 2.72122220e+01 2.39649780e+02 2.72122220e+01 2.39649266e+02 2.72108558e+01 2.39649778e+02 2.72103998e+01 2.39650461e+02 2.72108548e+01 2.39638509e+02 2.72108639e+01 2.39637656e+02 2.72122311e+01 2.39637486e+02 2.72124590e+01 2.39637229e+02 2.72122314e+01 2.39636870e+02 2.72108650e+01 2.39637484e+02 2.72099535e+01 2.39638509e+02 2.72108639e+01 2.39563625e+02 2.72108975e+01 2.39563721e+02 2.72110683e+01 2.39563839e+02 2.72108975e+01 2.39563721e+02 2.72105558e+01 2.39563625e+02 2.72108975e+01 2.39558855e+02 2.72108983e+01 2.39559111e+02 2.72112020e+01 2.39560648e+02 2.72108980e+01 2.39559111e+02 2.72105078e+01 2.39558855e+02 2.72108983e+01 2.39645938e+02 2.72122250e+01 2.39645390e+02 2.72135921e+01 2.39645171e+02 2.72137289e+01 2.39643634e+02 2.72136846e+01 2.39643463e+02 2.72135936e+01 2.39643634e+02 2.72133982e+01 2.39644401e+02 2.72122262e+01 2.39645168e+02 2.72113145e+01 2.39645938e+02 2.72122250e+01 2.39640048e+02 2.72135961e+01 2.39639024e+02 2.72138702e+01 2.39638585e+02 2.72135971e+01 2.39639023e+02 2.72133235e+01 2.39640048e+02 2.72135961e+01 2.39554117e+02 2.72136323e+01 2.39553989e+02 2.72149990e+01 2.39552965e+02 2.72161380e+01 2.39552728e+02 2.72163658e+01 2.39552965e+02 2.72169124e+01 2.39554117e+02 2.72177323e+01 2.39554502e+02 2.72178042e+01 2.39554611e+02 2.72177322e+01 2.39554502e+02 2.72174589e+01 2.39553477e+02 2.72163657e+01 2.39554501e+02 2.72157582e+01 2.39555599e+02 2.72149988e+01 2.39554843e+02 2.72136322e+01 2.39554501e+02 2.72133589e+01 2.39554117e+02 2.72136323e+01 2.39542890e+02 2.72136331e+01 2.39542207e+02 2.72149998e+01 2.39542207e+02 2.72149998e+01 2.39542207e+02 2.72149998e+01 2.39541695e+02 2.72136332e+01 2.39542207e+02 2.72129498e+01 2.39542890e+02 2.72136331e+01 2.39633390e+02 2.72149674e+01 2.39634415e+02 2.72154637e+01 2.39634887e+02 2.72149664e+01 2.39634414e+02 2.72144201e+01 2.39633390e+02 2.72149674e+01 2.39627691e+02 2.72149712e+01 2.39628268e+02 2.72154264e+01 2.39629190e+02 2.72163369e+01 2.39629636e+02 2.72177033e+01 2.39629806e+02 2.72178274e+01 2.39629897e+02 2.72177031e+01 2.39630364e+02 2.72163361e+01 2.39629804e+02 2.72152432e+01 2.39629420e+02 2.72149701e+01 2.39628267e+02 2.72145153e+01 2.39627691e+02 2.72149712e+01 2.39648247e+02 2.72163232e+01 2.39648247e+02 2.72163232e+01 2.39648247e+02 2.72163232e+01 2.39648247e+02 2.72163232e+01 2.39648247e+02 2.72163232e+01 2.39547202e+02 2.72163662e+01 2.39548354e+02 2.72169519e+01 2.39548662e+02 2.72163661e+01 2.39548354e+02 2.72160245e+01 2.39547202e+02 2.72163662e+01 2.39539646e+02 2.72163666e+01 2.39539133e+02 2.72165488e+01 2.39538941e+02 2.72163666e+01 2.39539133e+02 2.72161388e+01 2.39539646e+02 2.72163666e+01 2.39643638e+02 2.72176934e+01 2.39643639e+02 2.72190601e+01 2.39643639e+02 2.72190601e+01 2.39642103e+02 2.72198300e+01 2.39640567e+02 2.72202924e+01 2.39639643e+02 2.72190630e+01 2.39640125e+02 2.72176960e+01 2.39640564e+02 2.72173741e+01 2.39642100e+02 2.72165557e+01 2.39643638e+02 2.72176934e+01 2.39643638e+02 2.72176934e+01 2.39650006e+02 2.72190552e+01 2.39649787e+02 2.72192262e+01 2.39649647e+02 2.72190555e+01 2.39649786e+02 2.72189414e+01 2.39650006e+02 2.72190552e+01 2.39551300e+02 2.72190992e+01 2.39551209e+02 2.72204659e+01 2.39551428e+02 2.72206367e+01 2.39551514e+02 2.72204659e+01 2.39551582e+02 2.72190992e+01 2.39551428e+02 2.72190138e+01 2.39551300e+02 2.72190992e+01 2.39540670e+02 2.72190999e+01 2.39540670e+02 2.72190999e+01 2.39539133e+02 2.72195099e+01 2.39538749e+02 2.72190999e+01 2.39539133e+02 2.72188436e+01 2.39540670e+02 2.72190999e+01 2.39540670e+02 2.72190999e+01 2.39641336e+02 2.72217951e+01 2.39640569e+02 2.72231624e+01 2.39642107e+02 2.72236168e+01 2.39642415e+02 2.72245277e+01 2.39642109e+02 2.72258946e+01 2.39642109e+02 2.72258946e+01 2.39642109e+02 2.72258946e+01 2.39640570e+02 2.72245290e+01 2.39640570e+02 2.72245290e+01 2.39640569e+02 2.72231624e+01 2.39639953e+02 2.72217961e+01 2.39640567e+02 2.72207024e+01 2.39641336e+02 2.72217951e+01 2.39626618e+02 2.72218052e+01 2.39626736e+02 2.72218810e+01 2.39626890e+02 2.72218050e+01 2.39626736e+02 2.72217140e+01 2.39626618e+02 2.72218052e+01 2.39540926e+02 2.72218332e+01 2.39540670e+02 2.72222888e+01 2.39540552e+02 2.72218332e+01 2.39540670e+02 2.72216054e+01 2.39540926e+02 2.72218332e+01 2.39536060e+02 2.72231999e+01 2.39536060e+02 2.72231999e+01 2.39536060e+02 2.72231999e+01 2.39536060e+02 2.72231999e+01 2.39536060e+02 2.72231999e+01 2.39537715e+02 2.72245666e+01 2.39537597e+02 2.72252499e+01 2.39537212e+02 2.72245666e+01 2.39537597e+02 2.72244147e+01 2.39537715e+02 2.72245666e+01 2.39639035e+02 2.72258968e+01 2.39640294e+02 2.72272626e+01 2.39639037e+02 2.72282096e+01 2.39637500e+02 2.72279479e+01 2.39635963e+02 2.72282906e+01 2.39635420e+02 2.72272660e+01 2.39634616e+02 2.72258999e+01 2.39635960e+02 2.72251018e+01 2.39636729e+02 2.72258984e+01 2.39637499e+02 2.72270937e+01 2.39639035e+02 2.72258968e+01 2.39639035e+02 2.72258968e+01 2.39639035e+02 2.72258968e+01 2.39628158e+02 2.72259042e+01 2.39628276e+02 2.72260017e+01 2.39629814e+02 2.72266841e+01 2.39630428e+02 2.72259027e+01 2.39629813e+02 2.72254826e+01 2.39628276e+02 2.72258237e+01 2.39628158e+02 2.72259042e+01 2.39540670e+02 2.72272999e+01 2.39542207e+02 2.72274241e+01 2.39542347e+02 2.72272998e+01 2.39542207e+02 2.72259332e+01 2.39540670e+02 2.72272999e+01 2.39535291e+02 2.72300332e+01 2.39534522e+02 2.72306189e+01 2.39533600e+02 2.72300332e+01 2.39534523e+02 2.72294475e+01 2.39535291e+02 2.72300332e+01 2.39533644e+02 2.72313998e+01 2.39532985e+02 2.72322198e+01 2.39532063e+02 2.72313998e+01 2.39532985e+02 2.72305798e+01 2.39533644e+02 2.72313998e+01 2.39530219e+02 2.72313997e+01 2.39529911e+02 2.72316274e+01 2.39529692e+02 2.72313997e+01 2.39529911e+02 2.72312945e+01 2.39530219e+02 2.72313997e+01 2.39659119e+02 2.72327142e+01 2.39659023e+02 2.72328054e+01 2.39658937e+02 2.72327144e+01 2.39659022e+02 2.72326232e+01 2.39659119e+02 2.72327142e+01 2.39641092e+02 2.72340953e+01 2.39640579e+02 2.72342665e+01 2.39640440e+02 2.72340958e+01 2.39640579e+02 2.72339714e+01 2.39641092e+02 2.72340953e+01 2.39532985e+02 2.72341331e+01 2.39532985e+02 2.72341331e+01 2.39532985e+02 2.72341331e+01 2.39532985e+02 2.72341331e+01 2.39532985e+02 2.72341331e+01 2.39646399e+02 2.72354580e+01 2.39645192e+02 2.72361422e+01 2.39644387e+02 2.72354595e+01 2.39645191e+02 2.72346677e+01 2.39646399e+02 2.72354580e+01 2.39639602e+02 2.72354630e+01 2.39639044e+02 2.72360101e+01 2.39638485e+02 2.72354638e+01 2.39639043e+02 2.72350730e+01 2.39639602e+02 2.72354630e+01 2.39630799e+02 2.72354691e+01 2.39629822e+02 2.72365327e+01 2.39628745e+02 2.72354705e+01 2.39629820e+02 2.72344068e+01 2.39630799e+02 2.72354691e+01 2.39532217e+02 2.72354998e+01 2.39532302e+02 2.72368664e+01 2.39531448e+02 2.72377206e+01 2.39530936e+02 2.72368664e+01 2.39531256e+02 2.72354997e+01 2.39531448e+02 2.72353045e+01 2.39532217e+02 2.72354998e+01 2.39637508e+02 2.72368312e+01 2.39637508e+02 2.72368312e+01 2.39637508e+02 2.72368312e+01 2.39637508e+02 2.72368312e+01 2.39637508e+02 2.72368312e+01 2.39635202e+02 2.72368328e+01 2.39635971e+02 2.72374631e+01 2.39636740e+02 2.72381984e+01 2.39635972e+02 2.72389962e+01 2.39634435e+02 2.72387125e+01 2.39633666e+02 2.72382005e+01 2.39632897e+02 2.72370829e+01 2.39631360e+02 2.72382021e+01 2.39631362e+02 2.72395688e+01 2.39631362e+02 2.72395688e+01 2.39631362e+02 2.72395688e+01 2.39631360e+02 2.72382021e+01 2.39630437e+02 2.72368360e+01 2.39631359e+02 2.72362497e+01 2.39632896e+02 2.72365859e+01 2.39634433e+02 2.72358084e+01 2.39635202e+02 2.72368328e+01 2.39628285e+02 2.72368374e+01 2.39628285e+02 2.72368374e+01 2.39628285e+02 2.72368374e+01 2.39628285e+02 2.72368374e+01 2.39628285e+02 2.72368374e+01 2.39627460e+02 2.72395713e+01 2.39627674e+02 2.72409378e+01 2.39626752e+02 2.72413484e+01 2.39625215e+02 2.72418855e+01 2.39624226e+02 2.72409400e+01 2.39625213e+02 2.72398212e+01 2.39625597e+02 2.72395725e+01 2.39626749e+02 2.72384003e+01 2.39627460e+02 2.72395713e+01 2.39643660e+02 2.72409267e+01 2.39643660e+02 2.72409267e+01 2.39643660e+02 2.72409267e+01 2.39643660e+02 2.72409267e+01 2.39643660e+02 2.72409267e+01 2.39636358e+02 2.72409320e+01 2.39635975e+02 2.72415180e+01 2.39635619e+02 2.72409325e+01 2.39635974e+02 2.72404198e+01 2.39636358e+02 2.72409320e+01 2.39632900e+02 2.72409344e+01 2.39632900e+02 2.72409344e+01 2.39632900e+02 2.72409344e+01 2.39632900e+02 2.72409344e+01 2.39632900e+02 2.72409344e+01 2.39618628e+02 2.72436766e+01 2.39619068e+02 2.72443597e+01 2.39619836e+02 2.72436759e+01 2.39619067e+02 2.72433347e+01 2.39618628e+02 2.72436766e+01 2.39636096e+02 2.72450322e+01 2.39635978e+02 2.72451689e+01 2.39635807e+02 2.72450324e+01 2.39635978e+02 2.72449080e+01 2.39636096e+02 2.72450322e+01 2.39630025e+02 2.72491363e+01 2.39629832e+02 2.72492731e+01 2.39629525e+02 2.72491366e+01 2.39629832e+02 2.72489412e+01 2.39630025e+02 2.72491363e+01 2.39614350e+02 2.72491457e+01 2.39614460e+02 2.72494190e+01 2.39614716e+02 2.72491455e+01 2.39614460e+02 2.72490405e+01 2.39614350e+02 2.72491457e+01 2.39532677e+02 2.72491665e+01 2.39532985e+02 2.72492641e+01 2.39533087e+02 2.72491665e+01 2.39532985e+02 2.72487109e+01 2.39532677e+02 2.72491665e+01 2.39620610e+02 2.72505088e+01 2.39620610e+02 2.72505088e+01 2.39620610e+02 2.72505088e+01 2.39620610e+02 2.72505088e+01 2.39620610e+02 2.72505088e+01 2.39528373e+02 2.72505329e+01 2.39528373e+02 2.72505329e+01 2.39528373e+02 2.72505329e+01 2.39528373e+02 2.72505329e+01 2.39528373e+02 2.72505329e+01 2.39609465e+02 2.72518816e+01 2.39609543e+02 2.72532482e+01 2.39609851e+02 2.72534189e+01 2.39611388e+02 2.72540160e+01 2.39612926e+02 2.72539298e+01 2.39613517e+02 2.72532462e+01 2.39612925e+02 2.72526770e+01 2.39611388e+02 2.72526882e+01 2.39610335e+02 2.72518812e+01 2.39609849e+02 2.72512957e+01 2.39609465e+02 2.72518816e+01 2.39538804e+02 2.72518999e+01 2.39539134e+02 2.72520951e+01 2.39539326e+02 2.72518999e+01 2.39539134e+02 2.72516070e+01 2.39538804e+02 2.72518999e+01 2.39619076e+02 2.72546097e+01 2.39619076e+02 2.72546097e+01 2.39619076e+02 2.72546097e+01 2.39619076e+02 2.72546097e+01 2.39619076e+02 2.72546097e+01 2.39616222e+02 2.72573447e+01 2.39616003e+02 2.72576865e+01 2.39615490e+02 2.72573451e+01 2.39616003e+02 2.72571929e+01 2.39616222e+02 2.72573447e+01 2.39533599e+02 2.72573665e+01 2.39532984e+02 2.72576149e+01 2.39532677e+02 2.72573665e+01 2.39532984e+02 2.72568198e+01 2.39533599e+02 2.72573665e+01 2.39623998e+02 2.72587068e+01 2.39623691e+02 2.72593903e+01 2.39623435e+02 2.72587071e+01 2.39623691e+02 2.72584792e+01 2.39623998e+02 2.72587068e+01 2.39614586e+02 2.72600789e+01 2.39614467e+02 2.72602156e+01 2.39614357e+02 2.72600790e+01 2.39614467e+02 2.72598056e+01 2.39614586e+02 2.72600789e+01 2.39611878e+02 2.72600804e+01 2.39611393e+02 2.72605931e+01 2.39610973e+02 2.72600808e+01 2.39611392e+02 2.72593973e+01 2.39611878e+02 2.72600804e+01 2.39600118e+02 2.72600861e+01 2.39600631e+02 2.72602811e+01 2.39601399e+02 2.72600855e+01 2.39600630e+02 2.72598906e+01 2.39600118e+02 2.72600861e+01 2.39604093e+02 2.72655509e+01 2.39603709e+02 2.72657613e+01 2.39603367e+02 2.72655512e+01 2.39603708e+02 2.72652094e+01 2.39604093e+02 2.72655509e+01 2.39538942e+02 2.72655665e+01 2.39539134e+02 2.72657184e+01 2.39539219e+02 2.72655665e+01 2.39539134e+02 2.72653388e+01 2.39538942e+02 2.72655665e+01 2.39602300e+02 2.72669184e+01 2.39602172e+02 2.72670551e+01 2.39601659e+02 2.72669187e+01 2.39602172e+02 2.72667476e+01 2.39602300e+02 2.72669184e+01 2.39606786e+02 2.72696496e+01 2.39606786e+02 2.72696496e+01 2.39606786e+02 2.72696496e+01 2.39606786e+02 2.72696496e+01 2.39606786e+02 2.72696496e+01 2.39599406e+02 2.72696530e+01 2.39599099e+02 2.72698809e+01 2.39598757e+02 2.72696533e+01 2.39599098e+02 2.72693798e+01 2.39599406e+02 2.72696530e+01 2.39575337e+02 2.72710282e+01 2.39576036e+02 2.72717873e+01 2.39576676e+02 2.72710278e+01 2.39576036e+02 2.72707924e+01 2.39575337e+02 2.72710282e+01 2.39540951e+02 2.72710332e+01 2.39540672e+02 2.72717165e+01 2.39540287e+02 2.72710332e+01 2.39540672e+02 2.72705776e+01 2.39540951e+02 2.72710332e+01 2.39557201e+02 2.72751319e+01 2.39556048e+02 2.72755225e+01 2.39554510e+02 2.72755422e+01 2.39553588e+02 2.72751323e+01 2.39554510e+02 2.72744489e+01 2.39556048e+02 2.72742209e+01 2.39557201e+02 2.72751319e+01 2.39566922e+02 2.72764969e+01 2.39566812e+02 2.72767702e+01 2.39566427e+02 2.72764970e+01 2.39566812e+02 2.72758135e+01 2.39566922e+02 2.72764969e+01 2.39556048e+02 2.72778654e+01 2.39556048e+02 2.72778654e+01 2.39556048e+02 2.72778654e+01 2.39556048e+02 2.72778654e+01 2.39556048e+02 2.72778654e+01 2.39569888e+02 2.72792295e+01 2.39569888e+02 2.72792295e+01 2.39569888e+02 2.72792295e+01 2.39569888e+02 2.72792295e+01 2.39569888e+02 2.72792295e+01 2.39560662e+02 2.72792313e+01 2.39560662e+02 2.72792313e+01 2.39560662e+02 2.72792313e+01 2.39560662e+02 2.72792313e+01 2.39560662e+02 2.72792313e+01 2.39489611e+02 2.72819583e+01 2.39488389e+02 2.72830148e+01 2.39487260e+02 2.72819575e+01 2.39488390e+02 2.72808570e+01 2.39489611e+02 2.72819583e+01 2.39626785e+02 2.72833050e+01 2.39626785e+02 2.72833050e+01 2.39626785e+02 2.72833050e+01 2.39626785e+02 2.72833050e+01 2.39626785e+02 2.72833050e+01 2.39625922e+02 2.72860389e+01 2.39625724e+02 2.72874057e+01 2.39625951e+02 2.72887722e+01 2.39625252e+02 2.72893939e+01 2.39623715e+02 2.72901243e+01 2.39623386e+02 2.72901405e+01 2.39622178e+02 2.72908571e+01 2.39620640e+02 2.72904350e+01 2.39619486e+02 2.72901428e+01 2.39619452e+02 2.72887761e+01 2.39619110e+02 2.72874097e+01 2.39619958e+02 2.72860425e+01 2.39620636e+02 2.72853352e+01 2.39622173e+02 2.72846823e+01 2.39623711e+02 2.72847712e+01 2.39625249e+02 2.72854016e+01 2.39625922e+02 2.72860389e+01 2.39534521e+02 2.72860665e+01 2.39534521e+02 2.72860665e+01 2.39534521e+02 2.72860665e+01 2.39534521e+02 2.72860665e+01 2.39534521e+02 2.72860665e+01 2.39501864e+02 2.73010953e+01 2.39500684e+02 2.73020982e+01 2.39499519e+02 2.73010947e+01 2.39500685e+02 2.73000111e+01 2.39501864e+02 2.73010953e+01 2.39626355e+02 2.73161053e+01 2.39625274e+02 2.73170521e+01 2.39623735e+02 2.73165274e+01 2.39623262e+02 2.73161072e+01 2.39623735e+02 2.73156315e+01 2.39625273e+02 2.73150978e+01 2.39626355e+02 2.73161053e+01 2.39750705e+02 2.73187052e+01 2.39749873e+02 2.73195525e+01 2.39748335e+02 2.73194680e+01 2.39747537e+02 2.73187099e+01 2.39748331e+02 2.73175699e+01 2.39749870e+02 2.73180231e+01 2.39750705e+02 2.73187052e+01 2.39586900e+02 2.73338913e+01 2.39586826e+02 2.73339632e+01 2.39586756e+02 2.73338913e+01 2.39586826e+02 2.73338366e+01 2.39586900e+02 2.73338913e+01 2.39549220e+02 2.73352661e+01 2.39548366e+02 2.73362152e+01 2.39547581e+02 2.73352662e+01 2.39548365e+02 2.73344716e+01 2.39549220e+02 2.73352661e+01 2.39627405e+02 2.73366046e+01 2.39626828e+02 2.73370291e+01 2.39626395e+02 2.73366052e+01 2.39626828e+02 2.73361808e+01 2.39627405e+02 2.73366046e+01 2.39526093e+02 2.73379994e+01 2.39525288e+02 2.73390832e+01 2.39524465e+02 2.73379992e+01 2.39525288e+02 2.73373008e+01 2.39526093e+02 2.73379994e+01 2.39710932e+02 2.73488264e+01 2.39711135e+02 2.73501928e+01 2.39709928e+02 2.73509459e+01 2.39709121e+02 2.73501953e+01 2.39708532e+02 2.73488293e+01 2.39709923e+02 2.73479900e+01 2.39710932e+02 2.73488264e+01 2.39531515e+02 2.73516664e+01 2.39531442e+02 2.73517423e+01 2.39531368e+02 2.73516664e+01 2.39531442e+02 2.73515809e+01 2.39531515e+02 2.73516664e+01 2.39606797e+02 2.72040497e+01 2.39606745e+02 2.72040623e+01 2.39606736e+02 2.72040497e+01 2.39606745e+02 2.72040324e+01 2.39606797e+02 2.72040497e+01 2.39603697e+02 2.72054178e+01 2.39603673e+02 2.72054409e+01 2.39603647e+02 2.72054178e+01 2.39603673e+02 2.72053993e+01 2.39603697e+02 2.72054178e+01 2.39600768e+02 2.72067858e+01 2.39601024e+02 2.72081524e+01 2.39600925e+02 2.72095191e+01 2.39601306e+02 2.72108856e+01 2.39600603e+02 2.72111985e+01 2.39600056e+02 2.72108861e+01 2.39599066e+02 2.72100943e+01 2.39598076e+02 2.72108870e+01 2.39599067e+02 2.72122070e+01 2.39599095e+02 2.72122532e+01 2.39600604e+02 2.72127991e+01 2.39601477e+02 2.72122522e+01 2.39602140e+02 2.72113177e+01 2.39602771e+02 2.72122516e+01 2.39603678e+02 2.72134914e+01 2.39605214e+02 2.72133160e+01 2.39605384e+02 2.72136170e+01 2.39606752e+02 2.72145518e+01 2.39607803e+02 2.72149825e+01 2.39608290e+02 2.72158472e+01 2.39608773e+02 2.72163487e+01 2.39609827e+02 2.72172847e+01 2.39610394e+02 2.72163478e+01 2.39611363e+02 2.72154850e+01 2.39612764e+02 2.72163466e+01 2.39612900e+02 2.72164827e+01 2.39613455e+02 2.72177129e+01 2.39612902e+02 2.72189437e+01 2.39612657e+02 2.72190800e+01 2.39612320e+02 2.72204468e+01 2.39611367e+02 2.72210994e+01 2.39610307e+02 2.72204479e+01 2.39609829e+02 2.72196835e+01 2.39608292e+02 2.72200666e+01 2.39607285e+02 2.72190827e+01 2.39606754e+02 2.72177856e+01 2.39606598e+02 2.72177164e+01 2.39605217e+02 2.72173077e+01 2.39603680e+02 2.72171037e+01 2.39603468e+02 2.72177179e+01 2.39603680e+02 2.72180248e+01 2.39605217e+02 2.72178239e+01 2.39606521e+02 2.72190831e+01 2.39606755e+02 2.72192906e+01 2.39608113e+02 2.72204490e+01 2.39608293e+02 2.72207038e+01 2.39609830e+02 2.72209942e+01 2.39610417e+02 2.72218145e+01 2.39611368e+02 2.72227429e+01 2.39612904e+02 2.72220381e+01 2.39614441e+02 2.72224316e+01 2.39615588e+02 2.72231784e+01 2.39615032e+02 2.72245454e+01 2.39614443e+02 2.72255131e+01 2.39613698e+02 2.72245461e+01 2.39612905e+02 2.72239886e+01 2.39612113e+02 2.72245469e+01 2.39612906e+02 2.72251044e+01 2.39614119e+02 2.72259125e+01 2.39612907e+02 2.72269348e+01 2.39612416e+02 2.72272801e+01 2.39612371e+02 2.72286468e+01 2.39611806e+02 2.72300137e+01 2.39612520e+02 2.72313800e+01 2.39611374e+02 2.72321280e+01 2.39611067e+02 2.72327475e+01 2.39611375e+02 2.72335214e+01 2.39611723e+02 2.72341138e+01 2.39611930e+02 2.72354803e+01 2.39611377e+02 2.72363009e+01 2.39610324e+02 2.72368478e+01 2.39609840e+02 2.72373498e+01 2.39609417e+02 2.72368483e+01 2.39608303e+02 2.72366457e+01 2.39607996e+02 2.72368490e+01 2.39608303e+02 2.72373441e+01 2.39609424e+02 2.72382150e+01 2.39608775e+02 2.72395820e+01 2.39608675e+02 2.72409487e+01 2.39609690e+02 2.72423148e+01 2.39608307e+02 2.72432104e+01 2.39607140e+02 2.72436828e+01 2.39606802e+02 2.72450496e+01 2.39606771e+02 2.72451050e+01 2.39605234e+02 2.72462281e+01 2.39603697e+02 2.72458716e+01 2.39602404e+02 2.72450517e+01 2.39602159e+02 2.72449740e+01 2.39602112e+02 2.72450518e+01 2.39601170e+02 2.72464189e+01 2.39602161e+02 2.72475503e+01 2.39603697e+02 2.72467118e+01 2.39605235e+02 2.72476451e+01 2.39606773e+02 2.72477275e+01 2.39606790e+02 2.72477829e+01 2.39606773e+02 2.72477961e+01 2.39605235e+02 2.72478391e+01 2.39604669e+02 2.72491506e+01 2.39603699e+02 2.72497116e+01 2.39602298e+02 2.72491517e+01 2.39602161e+02 2.72486070e+01 2.39600624e+02 2.72489538e+01 2.39599087e+02 2.72484118e+01 2.39598809e+02 2.72491533e+01 2.39597954e+02 2.72505203e+01 2.39598781e+02 2.72518866e+01 2.39597860e+02 2.72532537e+01 2.39598050e+02 2.72546203e+01 2.39597674e+02 2.72559871e+01 2.39597554e+02 2.72561642e+01 2.39596989e+02 2.72559874e+01 2.39596261e+02 2.72546210e+01 2.39596015e+02 2.72545531e+01 2.39595840e+02 2.72546212e+01 2.39594478e+02 2.72550071e+01 2.39593130e+02 2.72559890e+01 2.39592942e+02 2.72562901e+01 2.39592634e+02 2.72559892e+01 2.39592289e+02 2.72546226e+01 2.39591403e+02 2.72532840e+01 2.39590749e+02 2.72546232e+01 2.39590789e+02 2.72559899e+01 2.39591152e+02 2.72573564e+01 2.39589868e+02 2.72583785e+01 2.39588330e+02 2.72584619e+01 2.39587295e+02 2.72573578e+01 2.39586792e+02 2.72568001e+01 2.39585907e+02 2.72573583e+01 2.39586407e+02 2.72587248e+01 2.39585256e+02 2.72598577e+01 2.39584921e+02 2.72600920e+01 2.39584291e+02 2.72614588e+01 2.39583720e+02 2.72618333e+01 2.39583104e+02 2.72614592e+01 2.39582182e+02 2.72608675e+01 2.39581326e+02 2.72614598e+01 2.39580645e+02 2.72626710e+01 2.39579108e+02 2.72623359e+01 2.39578492e+02 2.72614606e+01 2.39577570e+02 2.72610753e+01 2.39576319e+02 2.72600946e+01 2.39576032e+02 2.72599714e+01 2.39575745e+02 2.72600947e+01 2.39576032e+02 2.72604422e+01 2.39577002e+02 2.72614611e+01 2.39576302e+02 2.72628279e+01 2.39576033e+02 2.72637853e+01 2.39575757e+02 2.72641947e+01 2.39574496e+02 2.72652142e+01 2.39573795e+02 2.72641953e+01 2.39572958e+02 2.72629782e+01 2.39571421e+02 2.72640968e+01 2.39569883e+02 2.72640517e+01 2.39568346e+02 2.72630354e+01 2.39566808e+02 2.72641242e+01 2.39565443e+02 2.72628305e+01 2.39565424e+02 2.72614638e+01 2.39565270e+02 2.72612459e+01 2.39564964e+02 2.72614639e+01 2.39563733e+02 2.72620113e+01 2.39562748e+02 2.72614643e+01 2.39562195e+02 2.72611574e+01 2.39561003e+02 2.72600980e+01 2.39560658e+02 2.72598747e+01 2.39560312e+02 2.72600981e+01 2.39559120e+02 2.72608689e+01 2.39557583e+02 2.72606590e+01 2.39556629e+02 2.72614653e+01 2.39556046e+02 2.72621685e+01 2.39555039e+02 2.72614655e+01 2.39554508e+02 2.72611196e+01 2.39553183e+02 2.72600990e+01 2.39553065e+02 2.72587324e+01 2.39552970e+02 2.72586805e+01 2.39552889e+02 2.72587324e+01 2.39551433e+02 2.72593796e+01 2.39549896e+02 2.72591306e+01 2.39548358e+02 2.72587724e+01 2.39546821e+02 2.72588973e+01 2.39546705e+02 2.72587329e+01 2.39546821e+02 2.72586233e+01 2.39547785e+02 2.72573662e+01 2.39548341e+02 2.72559995e+01 2.39547811e+02 2.72546329e+01 2.39548050e+02 2.72532662e+01 2.39548358e+02 2.72530346e+01 2.39548911e+02 2.72518994e+01 2.39549484e+02 2.72505327e+01 2.39549895e+02 2.72502591e+01 2.39550623e+02 2.72491660e+01 2.39551432e+02 2.72480875e+01 2.39551797e+02 2.72477992e+01 2.39551432e+02 2.72474000e+01 2.39549894e+02 2.72465712e+01 2.39549583e+02 2.72464327e+01 2.39549221e+02 2.72450661e+01 2.39549849e+02 2.72436994e+01 2.39549894e+02 2.72436439e+01 2.39551431e+02 2.72436684e+01 2.39552558e+02 2.72423324e+01 2.39552864e+02 2.72409657e+01 2.39552463e+02 2.72395991e+01 2.39552101e+02 2.72382325e+01 2.39552968e+02 2.72378287e+01 2.39553497e+02 2.72382323e+01 2.39554505e+02 2.72388523e+01 2.39555152e+02 2.72382321e+01 2.39556042e+02 2.72370018e+01 2.39556226e+02 2.72368653e+01 2.39557579e+02 2.72356622e+01 2.39557751e+02 2.72354985e+01 2.39557753e+02 2.72341318e+01 2.39558500e+02 2.72327650e+01 2.39557578e+02 2.72320367e+01 2.39556991e+02 2.72313986e+01 2.39557578e+02 2.72310962e+01 2.39559115e+02 2.72309873e+01 2.39559731e+02 2.72313982e+01 2.39560652e+02 2.72315097e+01 2.39560726e+02 2.72313980e+01 2.39561266e+02 2.72300313e+01 2.39560651e+02 2.72288963e+01 2.39560409e+02 2.72286647e+01 2.39560651e+02 2.72284138e+01 2.39562157e+02 2.72272978e+01 2.39562188e+02 2.72272285e+01 2.39563725e+02 2.72265449e+01 2.39564031e+02 2.72259308e+01 2.39565261e+02 2.72253153e+01 2.39566798e+02 2.72246317e+01 2.39566851e+02 2.72245635e+01 2.39568335e+02 2.72234394e+01 2.39568655e+02 2.72231965e+01 2.39568334e+02 2.72218853e+01 2.39568316e+02 2.72218299e+01 2.39568334e+02 2.72218047e+01 2.39569207e+02 2.72204630e+01 2.39568763e+02 2.72190965e+01 2.39569870e+02 2.72186275e+01 2.39570792e+02 2.72177294e+01 2.39571406e+02 2.72166811e+01 2.39572944e+02 2.72173186e+01 2.39574480e+02 2.72164707e+01 2.39575364e+02 2.72177282e+01 2.39574669e+02 2.72190951e+01 2.39576018e+02 2.72196944e+01 2.39576753e+02 2.72190945e+01 2.39577323e+02 2.72177277e+01 2.39577554e+02 2.72174928e+01 2.39579090e+02 2.72164383e+01 2.39580627e+02 2.72167471e+01 2.39581373e+02 2.72163598e+01 2.39580627e+02 2.72150330e+01 2.39579090e+02 2.72162048e+01 2.39578031e+02 2.72149941e+01 2.39579090e+02 2.72142232e+01 2.39580627e+02 2.72149010e+01 2.39582163e+02 2.72138386e+01 2.39583393e+02 2.72149925e+01 2.39583700e+02 2.72153631e+01 2.39584089e+02 2.72149923e+01 2.39585237e+02 2.72143540e+01 2.39586773e+02 2.72138001e+01 2.39586857e+02 2.72136247e+01 2.39588310e+02 2.72124396e+01 2.39588593e+02 2.72122574e+01 2.39589846e+02 2.72115502e+01 2.39591016e+02 2.72108898e+01 2.39591382e+02 2.72105044e+01 2.39592116e+02 2.72108894e+01 2.39591883e+02 2.72122562e+01 2.39592920e+02 2.72130756e+01 2.39594302e+02 2.72122552e+01 2.39594456e+02 2.72114333e+01 2.39595993e+02 2.72113512e+01 2.39597082e+02 2.72108874e+01 2.39595992e+02 2.72101775e+01 2.39594456e+02 2.72107795e+01 2.39592919e+02 2.72104668e+01 2.39592165e+02 2.72095227e+01 2.39592918e+02 2.72083003e+01 2.39594455e+02 2.72088930e+01 2.39595992e+02 2.72089743e+01 2.39597499e+02 2.72081539e+01 2.39597528e+02 2.72081193e+01 2.39597632e+02 2.72081538e+01 2.39599065e+02 2.72086994e+01 2.39599924e+02 2.72081529e+01 2.39600138e+02 2.72067861e+01 2.39600600e+02 2.72065511e+01 2.39600768e+02 2.72067858e+01 2.39594877e+02 2.72067883e+01 2.39594454e+02 2.72070201e+01 2.39594337e+02 2.72067885e+01 2.39594454e+02 2.72067000e+01 2.39594877e+02 2.72067883e+01 2.39584118e+02 2.72067923e+01 2.39583697e+02 2.72071016e+01 2.39583316e+02 2.72067925e+01 2.39583697e+02 2.72065554e+01 2.39584118e+02 2.72067923e+01 2.39604221e+02 2.72081509e+01 2.39603983e+02 2.72095177e+01 2.39603676e+02 2.72097753e+01 2.39603416e+02 2.72095179e+01 2.39603128e+02 2.72081514e+01 2.39603674e+02 2.72078593e+01 2.39604221e+02 2.72081509e+01 2.39611974e+02 2.72095137e+01 2.39611359e+02 2.72100611e+01 2.39611069e+02 2.72095142e+01 2.39611359e+02 2.72091773e+01 2.39611974e+02 2.72095137e+01 2.39605787e+02 2.72108835e+01 2.39605213e+02 2.72116896e+01 2.39604524e+02 2.72108841e+01 2.39605213e+02 2.72102458e+01 2.39605787e+02 2.72108835e+01 2.39582800e+02 2.72108927e+01 2.39582162e+02 2.72116220e+01 2.39581445e+02 2.72108931e+01 2.39582162e+02 2.72103259e+01 2.39582800e+02 2.72108927e+01 2.39614937e+02 2.72122454e+01 2.39614435e+02 2.72132301e+01 2.39613783e+02 2.72122461e+01 2.39614434e+02 2.72114254e+01 2.39614937e+02 2.72122454e+01 2.39613002e+02 2.72136131e+01 2.39612898e+02 2.72136363e+01 2.39611362e+02 2.72145436e+01 2.39610578e+02 2.72136144e+01 2.39611361e+02 2.72130976e+01 2.39612898e+02 2.72135855e+01 2.39613002e+02 2.72136131e+01 2.39571645e+02 2.72136292e+01 2.39571406e+02 2.72141079e+01 2.39570818e+02 2.72136294e+01 2.39571406e+02 2.72133899e+01 2.39571645e+02 2.72136292e+01 2.39610692e+02 2.72149810e+01 2.39609826e+02 2.72157521e+01 2.39608873e+02 2.72149819e+01 2.39609825e+02 2.72144516e+01 2.39610692e+02 2.72149810e+01 2.39603504e+02 2.72149846e+01 2.39603679e+02 2.72153477e+01 2.39603924e+02 2.72149844e+01 2.39603678e+02 2.72144397e+01 2.39603504e+02 2.72149846e+01 2.39576693e+02 2.72149945e+01 2.39576744e+02 2.72163612e+01 2.39576017e+02 2.72169539e+01 2.39574684e+02 2.72163617e+01 2.39575533e+02 2.72149948e+01 2.39576016e+02 2.72148442e+01 2.39576693e+02 2.72149945e+01 2.39617388e+02 2.72163441e+01 2.39615975e+02 2.72171833e+01 2.39615090e+02 2.72163453e+01 2.39615974e+02 2.72158611e+01 2.39617388e+02 2.72163441e+01 2.39614748e+02 2.72204455e+01 2.39614440e+02 2.72206512e+01 2.39614070e+02 2.72204459e+01 2.39614440e+02 2.72203283e+01 2.39614748e+02 2.72204455e+01 2.39564205e+02 2.72204641e+01 2.39563723e+02 2.72211673e+01 2.39563354e+02 2.72204642e+01 2.39563723e+02 2.72200540e+01 2.39564205e+02 2.72204641e+01 2.39616705e+02 2.72218111e+01 2.39615978e+02 2.72227003e+01 2.39615311e+02 2.72218119e+01 2.39615977e+02 2.72211005e+01 2.39616705e+02 2.72218111e+01 2.39562774e+02 2.72218310e+01 2.39562187e+02 2.72229799e+01 2.39561110e+02 2.72218313e+01 2.39562187e+02 2.72216184e+01 2.39562774e+02 2.72218310e+01 2.39617776e+02 2.72231772e+01 2.39617516e+02 2.72233278e+01 2.39616839e+02 2.72231777e+01 2.39617515e+02 2.72228010e+01 2.39617776e+02 2.72231772e+01 2.39566703e+02 2.72231969e+01 2.39565261e+02 2.72239914e+01 2.39563724e+02 2.72238228e+01 2.39562493e+02 2.72231977e+01 2.39563724e+02 2.72227598e+01 2.39565261e+02 2.72224392e+01 2.39566703e+02 2.72231969e+01 2.39560729e+02 2.72259313e+01 2.39560651e+02 2.72259591e+01 2.39560622e+02 2.72259314e+01 2.39560651e+02 2.72259168e+01 2.39560729e+02 2.72259313e+01 2.39556611e+02 2.72272986e+01 2.39556040e+02 2.72278912e+01 2.39554503e+02 2.72275116e+01 2.39554099e+02 2.72272989e+01 2.39554503e+02 2.72270780e+01 2.39556040e+02 2.72269245e+01 2.39556611e+02 2.72272986e+01 2.39614815e+02 2.72286455e+01 2.39614446e+02 2.72289744e+01 2.39613983e+02 2.72286459e+01 2.39614446e+02 2.72285674e+01 2.39614815e+02 2.72286455e+01 2.39563145e+02 2.72286643e+01 2.39563725e+02 2.72290357e+01 2.39564062e+02 2.72286641e+01 2.39563725e+02 2.72276320e+01 2.39563145e+02 2.72286643e+01 2.39558290e+02 2.72286651e+01 2.39557577e+02 2.72292229e+01 2.39556655e+02 2.72286653e+01 2.39557577e+02 2.72279313e+01 2.39558290e+02 2.72286651e+01 2.39554735e+02 2.72341322e+01 2.39554504e+02 2.72342817e+01 2.39554407e+02 2.72341322e+01 2.39554504e+02 2.72340226e+01 2.39554735e+02 2.72341322e+01 2.39557327e+02 2.72354985e+01 2.39556042e+02 2.72366421e+01 2.39555297e+02 2.72354988e+01 2.39556041e+02 2.72347126e+01 2.39557327e+02 2.72354985e+01 2.39555765e+02 2.72368654e+01 2.39554505e+02 2.72374261e+01 2.39553956e+02 2.72368656e+01 2.39554504e+02 2.72362427e+01 2.39555765e+02 2.72368654e+01 2.39605048e+02 2.72423171e+01 2.39604542e+02 2.72436840e+01 2.39605233e+02 2.72438726e+01 2.39606154e+02 2.72436833e+01 2.39605785e+02 2.72423168e+01 2.39605232e+02 2.72422054e+01 2.39605048e+02 2.72423171e+01 2.39545590e+02 2.72450663e+01 2.39545283e+02 2.72453399e+01 2.39544975e+02 2.72450664e+01 2.39545283e+02 2.72448166e+01 2.39545590e+02 2.72450663e+01 2.39600793e+02 2.72505191e+01 2.39600625e+02 2.72506219e+01 2.39600483e+02 2.72505192e+01 2.39600625e+02 2.72502452e+01 2.39600793e+02 2.72505191e+01 2.39551537e+02 2.72559992e+01 2.39552970e+02 2.72561653e+01 2.39553113e+02 2.72559990e+01 2.39552970e+02 2.72557260e+01 2.39551537e+02 2.72559992e+01 2.39548410e+02 2.72559995e+01 2.39549199e+02 2.72573661e+01 2.39549896e+02 2.72582950e+01 2.39550699e+02 2.72573659e+01 2.39551381e+02 2.72559992e+01 2.39549895e+02 2.72555333e+01 2.39548410e+02 2.72559995e+01 2.39565188e+02 2.72587305e+01 2.39565270e+02 2.72589484e+01 2.39566807e+02 2.72589192e+01 2.39567268e+02 2.72587301e+01 2.39566807e+02 2.72586132e+01 2.39565270e+02 2.72586624e+01 2.39565188e+02 2.72587305e+01 2.39544146e+02 2.72587331e+01 2.39543746e+02 2.72592071e+01 2.39543450e+02 2.72587331e+01 2.39543746e+02 2.72584487e+01 2.39544146e+02 2.72587331e+01 2.39588566e+02 2.72600907e+01 2.39588331e+02 2.72604275e+01 2.39586794e+02 2.72603411e+01 2.39586076e+02 2.72600916e+01 2.39586794e+02 2.72596127e+01 2.39588331e+02 2.72595436e+01 2.39588566e+02 2.72600907e+01 2.39554119e+02 2.72614656e+01 2.39552971e+02 2.72625593e+01 2.39552433e+02 2.72614658e+01 2.39552971e+02 2.72602880e+01 2.39554119e+02 2.72614656e+01 2.39546883e+02 2.72614662e+01 2.39546821e+02 2.72614876e+01 2.39546799e+02 2.72614663e+01 2.39546821e+02 2.72614355e+01 2.39546883e+02 2.72614662e+01 2.39586864e+02 2.72628246e+01 2.39586795e+02 2.72629511e+01 2.39586679e+02 2.72628247e+01 2.39586795e+02 2.72627425e+01 2.39586864e+02 2.72628246e+01 2.39562811e+02 2.72628310e+01 2.39562196e+02 2.72629932e+01 2.39560965e+02 2.72628313e+01 2.39562196e+02 2.72619557e+01 2.39562811e+02 2.72628310e+01 2.39555496e+02 2.72628321e+01 2.39554509e+02 2.72640234e+01 2.39553258e+02 2.72628324e+01 2.39554508e+02 2.72617899e+01 2.39555496e+02 2.72628321e+01 2.39548623e+02 2.72628328e+01 2.39548359e+02 2.72629424e+01 2.39548227e+02 2.72628328e+01 2.39548359e+02 2.72625589e+01 2.39548623e+02 2.72628328e+01 2.39578946e+02 2.72641938e+01 2.39577571e+02 2.72650976e+01 2.39576196e+02 2.72641946e+01 2.39577571e+02 2.72636006e+01 2.39578946e+02 2.72641938e+01 2.39566697e+02 2.72641969e+01 2.39565271e+02 2.72651268e+01 2.39564781e+02 2.72641973e+01 2.39565271e+02 2.72630352e+01 2.39566697e+02 2.72641969e+01 2.39557772e+02 2.72641985e+01 2.39557584e+02 2.72643992e+01 2.39557436e+02 2.72641985e+01 2.39557584e+02 2.72640400e+01 2.39557772e+02 2.72641985e+01 2.39570346e+02 2.72655628e+01 2.39569884e+02 2.72656596e+01 2.39569781e+02 2.72655629e+01 2.39569884e+02 2.72650150e+01 2.39570346e+02 2.72655628e+01 2.39567390e+02 2.72655634e+01 2.39566809e+02 2.72662275e+01 2.39565763e+02 2.72655638e+01 2.39566808e+02 2.72642959e+01 2.39567390e+02 2.72655634e+01 2.39564534e+02 2.72655640e+01 2.39563734e+02 2.72659027e+01 2.39563263e+02 2.72655642e+01 2.39563734e+02 2.72653008e+01 2.39564534e+02 2.72655640e+01 2.39561189e+02 2.72655646e+01 2.39560659e+02 2.72659885e+01 2.39560098e+02 2.72655648e+01 2.39560659e+02 2.72652724e+01 2.39561189e+02 2.72655646e+01 2.39560593e+02 2.72723980e+01 2.39559123e+02 2.72736705e+01 2.39557680e+02 2.72723985e+01 2.39559122e+02 2.72710885e+01 2.39560593e+02 2.72723980e+01 2.39488815e+02 2.72819580e+01 2.39488389e+02 2.72823260e+01 2.39487996e+02 2.72819577e+01 2.39488390e+02 2.72815744e+01 2.39488815e+02 2.72819580e+01 2.39624197e+02 2.72860400e+01 2.39625213e+02 2.72874060e+01 2.39625049e+02 2.72887728e+01 2.39623715e+02 2.72899233e+01 2.39622177e+02 2.72900810e+01 2.39620666e+02 2.72887754e+01 2.39620638e+02 2.72887196e+01 2.39619308e+02 2.72874096e+01 2.39620636e+02 2.72861550e+01 2.39620857e+02 2.72860420e+01 2.39622173e+02 2.72849775e+01 2.39623712e+02 2.72856937e+01 2.39624197e+02 2.72860400e+01 2.39501218e+02 2.73010951e+01 2.39500685e+02 2.73015486e+01 2.39500157e+02 2.73010948e+01 2.39500685e+02 2.73006048e+01 2.39501218e+02 2.73010951e+01 2.39625446e+02 2.73161058e+01 2.39625273e+02 2.73162574e+01 2.39624974e+02 2.73161061e+01 2.39625273e+02 2.73159446e+01 2.39625446e+02 2.73161058e+01 2.39591468e+02 2.72218230e+01 2.39592925e+02 2.72230655e+01 2.39593049e+02 2.72231890e+01 2.39592925e+02 2.72234268e+01 2.39592703e+02 2.72245558e+01 2.39592926e+02 2.72247464e+01 2.39593515e+02 2.72245555e+01 2.39594462e+02 2.72240065e+01 2.39596000e+02 2.72243954e+01 2.39596156e+02 2.72245544e+01 2.39596000e+02 2.72247891e+01 2.39595645e+02 2.72259213e+01 2.39596001e+02 2.72272656e+01 2.39597538e+02 2.72265209e+01 2.39598179e+02 2.72272869e+01 2.39598934e+02 2.72286533e+01 2.39598126e+02 2.72300203e+01 2.39599077e+02 2.72307712e+01 2.39599535e+02 2.72313863e+01 2.39599078e+02 2.72320305e+01 2.39598019e+02 2.72327537e+01 2.39598006e+02 2.72341203e+01 2.39597542e+02 2.72346599e+01 2.39596443e+02 2.72354876e+01 2.39596006e+02 2.72360583e+01 2.39595653e+02 2.72368546e+01 2.39596007e+02 2.72377732e+01 2.39597098e+02 2.72382207e+01 2.39596007e+02 2.72384985e+01 2.39594470e+02 2.72384298e+01 2.39592933e+02 2.72388865e+01 2.39592396e+02 2.72395893e+01 2.39592537e+02 2.72409559e+01 2.39592103e+02 2.72423227e+01 2.39591398e+02 2.72429871e+01 2.39589861e+02 2.72433765e+01 2.39589576e+02 2.72436903e+01 2.39588324e+02 2.72448416e+01 2.39587839e+02 2.72450576e+01 2.39586788e+02 2.72458371e+01 2.39585250e+02 2.72458202e+01 2.39583800e+02 2.72450590e+01 2.39583713e+02 2.72449996e+01 2.39583656e+02 2.72450591e+01 2.39583491e+02 2.72464258e+01 2.39582176e+02 2.72470105e+01 2.39580639e+02 2.72467238e+01 2.39580281e+02 2.72464268e+01 2.39579676e+02 2.72450603e+01 2.39579101e+02 2.72446674e+01 2.39577564e+02 2.72441795e+01 2.39576836e+02 2.72436945e+01 2.39576026e+02 2.72433708e+01 2.39575116e+02 2.72436949e+01 2.39574489e+02 2.72445864e+01 2.39574368e+02 2.72450618e+01 2.39572953e+02 2.72457061e+01 2.39571704e+02 2.72464291e+01 2.39571416e+02 2.72466089e+01 2.39570260e+02 2.72464295e+01 2.39569878e+02 2.72456372e+01 2.39569729e+02 2.72450629e+01 2.39569407e+02 2.72436963e+01 2.39569236e+02 2.72423297e+01 2.39568723e+02 2.72409631e+01 2.39568339e+02 2.72404100e+01 2.39567641e+02 2.72395967e+01 2.39566802e+02 2.72383085e+01 2.39566717e+02 2.72382302e+01 2.39566802e+02 2.72377995e+01 2.39567854e+02 2.72368633e+01 2.39568127e+02 2.72354966e+01 2.39568338e+02 2.72352434e+01 2.39568795e+02 2.72341298e+01 2.39568432e+02 2.72327632e+01 2.39569874e+02 2.72316636e+01 2.39570057e+02 2.72313962e+01 2.39571411e+02 2.72303309e+01 2.39571568e+02 2.72300292e+01 2.39571491e+02 2.72286625e+01 2.39572897e+02 2.72272955e+01 2.39572947e+02 2.72272064e+01 2.39573167e+02 2.72259288e+01 2.39574483e+02 2.72254875e+01 2.39576020e+02 2.72247396e+01 2.39576174e+02 2.72245613e+01 2.39577556e+02 2.72238937e+01 2.39579093e+02 2.72240711e+01 2.39580417e+02 2.72231934e+01 2.39580630e+02 2.72229879e+01 2.39582166e+02 2.72223868e+01 2.39583404e+02 2.72218258e+01 2.39583703e+02 2.72216079e+01 2.39585240e+02 2.72206487e+01 2.39586777e+02 2.72216662e+01 2.39588314e+02 2.72213926e+01 2.39589566e+02 2.72218237e+01 2.39589851e+02 2.72219012e+01 2.39591111e+02 2.72218231e+01 2.39591388e+02 2.72217674e+01 2.39591468e+02 2.72218230e+01 2.39597559e+02 2.72368538e+01 2.39597543e+02 2.72370320e+01 2.39597499e+02 2.72368539e+01 2.39597543e+02 2.72368316e+01 2.39597559e+02 2.72368538e+01 2.39595183e+02 2.72409548e+01 2.39594472e+02 2.72419990e+01 2.39593264e+02 2.72409556e+01 2.39594471e+02 2.72402124e+01 2.39595183e+02 2.72409548e+01 2.39567188e+02 2.72423301e+01 2.39567411e+02 2.72436968e+01 2.39567825e+02 2.72450633e+01 2.39566804e+02 2.72459985e+01 2.39565910e+02 2.72450637e+01 2.39566294e+02 2.72436970e+01 2.39566435e+02 2.72423303e+01 2.39566803e+02 2.72416766e+01 2.39567188e+02 2.72423301e+01 2.39579780e+02 2.72477936e+01 2.39579102e+02 2.72481183e+01 2.39578611e+02 2.72477939e+01 2.39579102e+02 2.72471610e+01 2.39579780e+02 2.72477936e+01 2.39560286e+02 2.72723981e+01 2.39559123e+02 2.72734051e+01 2.39557981e+02 2.72723984e+01 2.39559122e+02 2.72713617e+01 2.39560286e+02 2.72723981e+01 2.39622694e+02 2.72860409e+01 2.39623712e+02 2.72861240e+01 2.39625106e+02 2.72874061e+01 2.39624463e+02 2.72887731e+01 2.39623714e+02 2.72894184e+01 2.39622177e+02 2.72898676e+01 2.39620913e+02 2.72887753e+01 2.39620638e+02 2.72882281e+01 2.39619807e+02 2.72874093e+01 2.39620637e+02 2.72866251e+01 2.39621775e+02 2.72860414e+01 2.39622174e+02 2.72857190e+01 2.39622694e+02 2.72860409e+01 2.39559516e+02 2.72723982e+01 2.39559123e+02 2.72727386e+01 2.39558737e+02 2.72723983e+01 2.39559123e+02 2.72720479e+01 2.39559516e+02 2.72723982e+01 2.39624837e+02 2.72874062e+01 2.39623714e+02 2.72886300e+01 2.39623220e+02 2.72887739e+01 2.39622177e+02 2.72893315e+01 2.39621533e+02 2.72887749e+01 2.39620643e+02 2.72874088e+01 2.39622174e+02 2.72860534e+01 2.39623712e+02 2.72863713e+01 2.39624837e+02 2.72874062e+01 2.39624163e+02 2.72874067e+01 2.39623713e+02 2.72878965e+01 2.39622176e+02 2.72887523e+01 2.39620685e+02 2.72874088e+01 2.39622174e+02 2.72860905e+01 2.39623713e+02 2.72869924e+01 2.39624163e+02 2.72874067e+01 2.39623631e+02 2.72874070e+01 2.39622176e+02 2.72886572e+01 2.39620790e+02 2.72874087e+01 2.39622174e+02 2.72861838e+01 2.39623631e+02 2.72874070e+01 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/a2142.reg�����������������������������������������������������������������0000644�0001750�0001750�00000221100�11220740726�015544� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Region file format: DS9 version 4.1 # Filename: acisf05005N002_evt2.fits[EVENTS] global color=green dashlist=8 3 width=1 font="helvetica 10 normal" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical polygon(3535.2112,4184.5,3540.5,4179.1154,3548.5,4176.8219,3555.9012,4184.5,3548.5,4191.9558,3540.5,4190.3926) polygon(3545.7583,4176.5,3548.5,4174.0347,3551.0962,4176.5,3556.3318,4184.5,3548.5,4192.3896,3540.5,4192.2562,3533.5386,4184.5,3540.5,4177.4125) polygon(3541.8511,4176.5,3548.5,4170.5214,3554.796,4176.5,3556.5,4184.1775,3556.7483,4184.5,3556.5,4184.7649,3551.6193,4192.5,3548.5,4195.5255,3540.5,4196.6771,3536.2539,4192.5,3532.8727,4184.5,3540.5,4176.7345) polygon(3952.2509,4072.5,3956.5,4068.3292,3960.6285,4072.5,3956.5,4076.6793) polygon(3784.3016,3768.5,3788.5,3764.6165,3792.2888,3768.5,3789.9877,3776.5,3788.5,3776.9498,3787.4255,3776.5) polygon(3771.6665,3752.5,3772.5,3750.0922,3778.6915,3752.5,3772.5,3754.2336) polygon(3538.3898,4176.5,3540.5,4174.7377,3548.5,4169.1227,3556.2689,4176.5,3556.5,4177.5414,3561.8572,4184.5,3556.5,4190.2159,3555.0588,4192.5,3548.5,4198.8617,3540.5,4199.1539,3533.7363,4192.5,3532.6076,4184.5) polygon(3949.7017,4072.5,3956.5,4065.8271,3963.1052,4072.5,3956.5,4079.1866) polygon(3875.6625,3904.5,3876.5,3904.2537,3876.835,3904.5,3876.5,3905.2614) polygon(3868.1012,3896.5,3868.5,3895.7386,3868.7463,3896.5,3868.5,3897.3375) polygon(3819.1354,3888.5,3820.5,3883.0416,3828.5,3886.0489,3830.444,3888.5,3828.5,3891.632,3823.0234,3896.5,3820.5,3897.8024,3818.7446,3896.5) polygon(3897.7083,3880.5,3900.5,3879.5695,3902.5938,3880.5,3900.5,3880.9927) polygon(3769.1562,3880.5,3772.5,3875.0284,3778.8355,3880.5,3772.5,3887.5809) polygon(3890.1607,3872.5,3892.5,3871.2404,3894.1375,3872.5,3892.5,3876.5938) polygon(3907.5625,3848.5,3908.5,3847.1458,3909.8542,3848.5,3911.5156,3856.5,3911.725,3864.5,3914.2277,3872.5,3908.5,3879.4728,3902.7723,3872.5,3906.3967,3864.5,3903.675,3856.5) polygon(3780.9485,3848.5,3780.5,3848.2176,3779.9917,3848.5,3780.5,3850.4062) polygon(3725.1932,3848.5,3732.5,3844.6726,3735.9946,3848.5,3735.8646,3856.5,3732.5,3859.0234,3731.1077,3856.5) polygon(3921.5568,3840.5,3924.5,3839.3009,3925.5444,3840.5,3924.5,3841.375) polygon(3876.9766,3840.5,3876.5,3840.1369,3876.2458,3840.5,3876.5,3841.1354) polygon(3723.5367,3840.5,3724.5,3839.5367,3725.7596,3840.5,3724.5,3845.9584) polygon(3914.0096,3832.5,3916.5,3831.205,3917.6991,3832.5,3916.5,3835.4432) polygon(3904.3125,3824.5,3908.5,3822.4062,3908.8807,3824.5,3908.5,3825.3375) polygon(3706.4813,3808.5,3708.5,3805.8083,3712.5375,3808.5,3708.5,3812.9861) polygon(3908.4837,3792.5,3908.5,3792.4062,3908.525,3792.5,3908.5,3792.5156) polygon(3882.2841,3744.5,3884.5,3743.6875,3885.0945,3744.5,3884.5,3746.375) polygon(3700.483,3736.5,3700.5,3736.4766,3700.5187,3736.5,3700.5,3736.5536) polygon(3713.0054,3720.5,3716.5,3718.2673,3719.9946,3720.5,3716.5,3723.5914) polygon(3785.564,3696.5,3788.5,3693.564,3795.5809,3696.5,3796.5,3700.4062,3798.8393,3704.5,3804.5,3705.5161,3812.5,3709.9766,3815.6058,3712.5,3820.5,3715.1511,3827.2566,3720.5,3828.5,3721.0027,3830.4688,3720.5,3836.5,3719.0229,3843.7375,3720.5,3844.5,3720.7933,3850.7617,3728.5,3852.5,3731.772,3860.5,3731.9005,3868.5,3734.3797,3870.9429,3736.5,3871.1979,3744.5,3876.5,3751.5695,3877.2614,3752.5,3876.5,3753.1979,3872.6902,3760.5,3876.5,3766.7589,3878.125,3768.5,3884.5,3773.8125,3886.6989,3776.5,3892.0987,3784.5,3892.5,3788.3125,3892.8489,3792.5,3900.5,3799.845,3901.1298,3800.5,3900.5,3801.9886,3898.7946,3808.5,3900.5,3814.0096,3905.125,3816.5,3900.5,3822.975,3899.8068,3824.5,3900.5,3824.9236,3905.7452,3832.5,3900.525,3840.5,3900.5,3840.5163,3893.4375,3848.5,3894.5469,3856.5,3892.5,3857.7596,3888.8489,3864.5,3884.5,3870.2986,3882.2986,3872.5,3880.9861,3880.5,3876.5,3882.875,3874.7446,3880.5,3868.5,3876.8173,3860.5,3877.0982,3857.4345,3872.5,3860.5,3867.1354,3861.5541,3864.5,3860.5,3863.1823,3858.3917,3864.5,3852.5,3868.1823,3847.7898,3872.5,3844.5,3876.1188,3841.7164,3872.5,3841.7083,3864.5,3836.5,3863.7188,3835.0795,3864.5,3829.7188,3872.5,3828.5,3873.7829,3825.0178,3872.5,3823.3303,3864.5,3820.5,3862.5187,3817.1979,3864.5,3818.743,3872.5,3819.9554,3880.5,3812.5,3885.038,3808.3092,3888.5,3804.5,3893.0234,3801.3533,3888.5,3797.4531,3880.5,3796.5,3877.9584,3788.8751,3880.5,3788.5,3880.5268,3788.4062,3880.5,3780.5,3878.743,3775.1488,3872.5,3772.5,3865.5469,3767.4432,3872.5,3764.5,3873.795,3763.0924,3872.5,3756.5,3865.9076,3751.875,3864.5,3748.5,3863.0234,3743.2812,3856.5,3748.5,3851.0066,3752.1635,3848.5,3748.5,3846.4293,3740.5,3843.0461,3737.6544,3840.5,3732.5,3833.7596,3731.5367,3832.5,3732.5,3827.0416,3732.7824,3824.5,3740.5,3817.058,3741.4191,3816.5,3740.5,3815.875,3738.5469,3816.5,3732.5,3823.4107,3728.6875,3824.5,3724.5,3825.0234,3716.5,3828.517,3711.3015,3824.5,3716.5,3821.101,3721.101,3816.5,3718.2228,3808.5,3716.9595,3800.5,3716.5,3799.5234,3708.5,3796.0764,3704.9236,3792.5,3701.8021,3784.5,3707.8558,3776.5,3701.5417,3768.5,3700.9485,3760.5,3700.5,3757.9584,3699.7202,3752.5,3700.5,3750.6805,3702.2944,3744.5,3708.5,3740.1279,3716.195,3744.5,3716.5,3744.8631,3716.8812,3744.5,3717.946,3736.5,3720.7542,3728.5,3724.5,3724.338,3730.257,3720.5,3732.5,3718.125,3737.5329,3712.5,3740.5,3707.375,3748.4062,3704.5,3748.5,3704.4625,3756.5,3700.4732,3764.5,3703.7202,3772.5,3701.975,3780.5,3700.6525) polygon(4026.365,4536.5,4028.5,4534.4086,4030.4707,4536.5,4028.5,4538.5914) polygon(3527.5103,4392.5,3532.5,4388.3955,3536.415,4392.5,3532.5,4396.2423) polygon(4328.1093,4280.5,4332.5,4276.2719,4337.3236,4280.5,4332.5,4284.7281) polygon(3531.0749,4176.5,3532.5,4174.4749,3540.5,4169.3959,3548.5,4168.5659,3556.5,4172.0382,3561.1012,4176.5,3563.8911,4184.5,3556.5,4192.3861,3556.4281,4192.5,3548.5,4200.1898,3540.5,4200.1399,3532.7341,4192.5,3532.5021,4184.5,3532.5,4182.913) polygon(4410.0983,4144.5,4412.5,4139.4783,4414.9017,4144.5,4412.5,4146.8016) polygon(3948.6869,4072.5,3956.5,4064.8309,3964.0912,4072.5,3956.5,4080.1848) polygon(3843.8419,4048.5,3844.5,4047.0522,3845.5342,4048.5,3844.5,4049.5342) polygon(3874.8068,4040.5,3876.5,4039.0487,3878.677,4040.5,3876.5,4042.2928) polygon(3819.0015,4040.5,3820.5,4039.3761,3821.5217,4040.5,3820.5,4041.6831) polygon(3891.6902,4032.5,3892.5,4026.022,3893.1478,4032.5,3892.5,4033.0398) polygon(3945.2935,4024.5,3948.5,4022.4749,3951.998,4024.5,3948.5,4027.4598) polygon(3919.8522,4024.5,3924.5,4017.8602,3929.1478,4024.5,3924.5,4026.8239) polygon(3883.7802,4024.5,3884.5,4022.8805,3890.9781,4024.5,3884.5,4025.3098) polygon(3905.9601,4016.5,3908.5,4008.8805,3916.5,4013.7292,3922.5956,4016.5,3916.5,4020.3098,3909.7956,4024.5,3908.5,4025.4254,3906.3406,4024.5) polygon(3870.0219,4016.5,3876.5,4013.261,3878.1195,4016.5,3876.5,4017.2197) polygon(3819.5951,4016.5,3820.5,4011.674,3822.913,4016.5,3820.5,4018.3098) polygon(4058.8944,4008.5,4060.5,4006.8944,4061.8223,4008.5,4060.5,4009.7488) polygon(3962.323,4008.5,3964.5,4005.7292,3966.1932,4008.5,3964.5,4012.3098) polygon(3920.9247,4008.5,3924.5,4004.2747,3927.4049,4008.5,3924.5,4015.1398) polygon(3829.261,4008.5,3836.5,4007.2935,3841.326,4008.5,3841.3043,4016.5,3836.5,4020.618,3830.7348,4016.5) polygon(3802.1761,4008.5,3804.5,4004.2747,3807.4049,4008.5,3804.5,4012.7253) polygon(3779.0015,4008.5,3780.5,4004.0044,3781.683,4008.5,3780.5,4010.3732) polygon(4043.3864,4000.5,4044.5,3999.1838,4046.3098,4000.5,4044.5,4001.4049) polygon(4027.5746,4000.5,4028.5,3999.2043,4029.0398,4000.5,4028.9319,4008.5,4028.5,4008.9628,4027.4203,4008.5) polygon(3877.8433,4000.5,3884.5,3994.751,3891.9399,4000.5,3891.4693,4008.5,3884.5,4015.0822,3877.0951,4008.5) polygon(3810.4317,4000.5,3812.5,3999.0522,3814.913,4000.5,3812.5,4001.7065) polygon(4031.8522,3992.5,4036.5,3986.6902,4039.5985,3992.5,4036.5,3995.234) polygon(4018.4681,3992.5,4020.5,3990.4681,4024.3098,3992.5,4020.5,3995.5479) polygon(3863.9601,3992.5,3860.5,3986.5684,3857.5342,3992.5,3860.5,3994.2301) polygon(3765.261,3984.5,3772.5,3982.087,3780.5,3982.087,3783.3956,3984.5,3780.5,3986.3098,3772.5,3986.3098) polygon(4057.9602,3976.5,4060.5,3974.9761,4062.4049,3976.5,4060.5,3978.8445) polygon(3916.6268,3976.5,3916.5,3976.1195,3908.5,3973.3645,3901.0889,3976.5,3908.5,3980.382,3916.5,3977.0073) polygon(3830.4469,3976.5,3828.5,3975.9159,3827.1522,3976.5,3828.5,3977.4734) polygon(4018.3406,3968.5,4012.5,3967.3319,4009.5797,3968.5,4012.5,3972.0044) polygon(3978.8805,3960.5,3972.5,3958.3732,3971.0821,3960.5,3972.5,3962.0951) polygon(4015.6902,3936.5,4012.5,3934.677,4009.3098,3936.5,4012.5,3938.323) polygon(4015.3761,3920.5,4012.5,3917.1163,4009.6239,3920.5,4012.5,3923.6957) polygon(3732.5895,3920.5,3732.5,3920.4338,3732.3309,3920.5,3732.5,3920.8805) polygon(3659.3863,3912.5,3660.5,3905.261,3661.4652,3912.5,3660.5,3914.913) polygon(4020.0373,3896.5,4020.5,3894.3406,4026.978,3896.5,4020.5,3896.9319) polygon(3653.8603,3896.5,3660.5,3893.1801,3668.5,3889.3656,3675.0399,3896.5,3670.1056,3904.5,3668.5,3905.9049,3661.0073,3904.5,3660.5,3904.2463) polygon(4023.0032,3888.5,4028.5,3884.6522,4036.1956,3888.5,4028.5,3896.1956) polygon(3982.2643,3888.5,3980.5,3887.4186,3978.7357,3888.5,3980.5,3894.087) polygon(3650.1555,3888.5,3652.5,3880.8805,3655.0399,3888.5,3652.5,3894.5956) polygon(4005.6902,3880.5,4004.5,3879.7065,4003.8199,3880.5,4004.5,3882.8805) polygon(4050.8944,3872.5,4052.5,3870.4565,4054.1056,3872.5,4052.5,3874.3732) polygon(3625.766,3848.5,3628.5,3842.6902,3635.1397,3848.5,3636.5,3853.261,3642.9781,3856.5,3636.5,3859.739,3628.5,3857.2198,3627.9601,3856.5) polygon(4019.7802,3840.5,4020.5,3838.8805,4021.4254,3840.5,4020.5,3840.9983) polygon(3652.7174,3824.5,3652.5,3824.2463,3652.4105,3824.5,3652.5,3824.6902) polygon(3611.8522,3824.5,3612.5,3822.3406,3613.2198,3824.5,3613.5342,3832.5,3612.5,3833.5342,3611.6484,3832.5) polygon(4026.4565,3808.5,4028.5,3807.0015,4034.1195,3808.5,4028.5,3810.2291) polygon(3956.6522,3792.5,3964.5,3787.2681,3972.3478,3792.5,3964.5,3798.1056) polygon(3584.7537,3792.5,3588.5,3790.4565,3592.9956,3792.5,3588.5,3794.5435) polygon(3978.7709,3784.5,3980.5,3780.7537,3981.9049,3784.5,3980.5,3786.5435) polygon(3538.0538,3784.5,3540.5,3782.5634,3544.7253,3784.5,3540.5,3787.234) polygon(4003.6484,3776.5,4004.5,3775.0522,4005.4049,3776.5,4007.5643,3784.5,4004.5,3787.5643,3996.5,3786.5319,3994.7072,3784.5,3996.5,3782.8959) polygon(3986.4317,3768.5,3988.5,3767.7761,3989.4652,3768.5,3988.5,3769.2239) polygon(3969.2888,3760.5,3972.5,3754.8805,3974.1056,3760.5,3972.5,3762.5435) polygon(3952.6902,3760.5,3956.5,3758.8959,3960.3098,3760.5,3956.5,3762.677) polygon(3596.0373,3760.5,3596.5,3759.2044,3597.2198,3760.5,3596.5,3761.7956) polygon(3600.6902,3752.5,3604.5,3749.7292,3609.5797,3752.5,3604.5,3755.0399) polygon(3985.6902,3744.5,3988.5,3743.2512,3990.3732,3744.5,3988.5,3746.1056) polygon(3968.8681,3744.5,3972.5,3737.6902,3977.0399,3744.5,3972.5,3751.3098) polygon(3580.0681,3744.5,3580.5,3741.261,3581.3098,3744.5,3580.5,3745.4254) polygon(3936.8805,3736.5,3940.5,3732.8805,3942.1087,3736.5,3940.5,3739.3956) polygon(3598.1761,3736.5,3604.5,3729.8433,3609.999,3736.5,3604.5,3741.999) polygon(3938.3406,3720.5,3940.5,3719.8522,3941.3098,3720.5,3940.5,3722.6594) polygon(3899.3863,3712.5,3892.5,3708.7699,3889.6122,3712.5,3892.5,3716.0809) polygon(3874.8805,3712.5,3868.5,3710.3732,3866.5368,3712.5,3868.5,3713.7761,3876.4105,3720.5,3876.5,3720.5585,3876.6171,3720.5,3876.5,3718.9781) polygon(3576.7537,3712.5,3580.5,3709.6902,3584.2463,3712.5,3580.5,3713.9049) polygon(3930.8913,3704.5,3932.5,3703.2935,3936.1195,3704.5,3935.9049,3712.5,3932.5,3718.5531,3924.5,3718.1195,3916.5,3719.3098,3908.7174,3712.5,3916.5,3708.6087,3924.5,3710.2522) polygon(3836.6268,3704.5,3836.5,3704.4338,3836.4565,3704.5,3836.5,3704.5724) polygon(3585.6902,3704.5,3588.5,3698.8805,3594.1195,3704.5,3588.5,3708.2463) polygon(3946.8913,3696.5,3948.5,3695.3863,3949.7065,3696.5,3948.5,3700.1195) polygon(3617.1135,3696.5,3620.5,3694.5951,3628.1195,3696.5,3620.5,3699.8865) polygon(3590.8805,3696.5,3596.5,3695.0015,3598.5435,3696.5,3596.5,3702.1195) polygon(3921.1135,3688.5,3924.5,3687.0486,3926.0239,3688.5,3927.971,3696.5,3924.5,3700.6652,3921.3761,3696.5) polygon(3585.2888,3680.5,3588.5,3677.6902,3596.5,3679.8522,3598.1195,3680.5,3596.5,3680.9983,3588.5,3683.3098) polygon(3923.1146,3672.5,3924.5,3670.4681,3925.8251,3672.5,3924.5,3673.9514) polygon(3710.2975,3672.5,3708.5,3669.8854,3705.6239,3672.5,3708.5,3674.5544) polygon(3603.8522,3672.5,3604.5,3671.7802,3610.9781,3672.5,3604.5,3674.1195) polygon(3819.0522,3664.5,3812.5,3659.0399,3808.8599,3664.5,3812.5,3669.9601) polygon(3575.8837,3664.5,3580.5,3658.4632,3587.6344,3664.5,3580.5,3668.2371) polygon(3839.0522,3656.5,3844.5,3653.4734,3852.5,3652.5951,3856.9627,3656.5,3852.5,3662.1798,3848.2463,3664.5,3844.5,3666.7478,3840.0044,3664.5) polygon(3685.3344,3656.5,3684.5,3653.5797,3683.1522,3656.5,3682.9781,3664.5,3684.5,3664.6384,3692.3616,3672.5,3691.4049,3680.5,3692.5,3681.5951,3698.6377,3688.5,3692.5,3694.3146,3687.3098,3696.5,3692.5,3697.884,3694.1609,3696.5,3700.5,3689.8967,3706.087,3688.5,3700.5,3687.2107,3693.2301,3680.5,3692.6171,3672.5,3692.5,3672.2826,3684.7174,3664.5) polygon(3553.6601,3656.5,3556.5,3654.097,3558.9991,3656.5,3556.5,3659.3399) polygon(3875.9601,3648.5,3876.5,3645.261,3877.2198,3648.5,3877.1581,3656.5,3876.5,3658.913,3869.261,3656.5) polygon(3729.6902,3648.5,3724.5,3642.5683,3717.5797,3648.5,3724.5,3650.2301) polygon(3571.4658,3648.5,3572.5,3646.8913,3573.4652,3648.5,3572.5,3650.913) polygon(3816.2747,3640.5,3820.5,3637.766,3828.5,3640.0017,3829.2198,3640.5,3828.5,3646.9781,3820.5,3646.3098) polygon(3654.2643,3640.5,3660.5,3636.1119,3666.1418,3640.5,3664.7699,3648.5,3665.326,3656.5,3660.5,3660.1195,3656.9956,3664.5,3652.5,3666.2291,3649.8702,3672.5,3644.5,3680.4276,3636.5,3674.1195,3630.1195,3680.5,3636.5,3681.8433,3641.999,3688.5,3636.5,3692.4525,3628.5,3696.2826,3625.6328,3688.5,3620.5,3682.4049,3613.9985,3688.5,3612.5,3691.3098,3604.5,3689.2198,3604.0017,3688.5,3604.5,3686.8805,3607.0522,3680.5,3612.5,3672.7174,3612.8805,3672.5,3620.5,3666.4044,3628.5,3669.6044,3632.146,3664.5,3628.5,3662.3732,3623.8015,3656.5,3627.7761,3648.5,3628.5,3647.0522,3630.3098,3648.5,3636.5,3654.0024,3640.2463,3656.5,3644.5,3659.0522,3648.146,3656.5,3652.5,3650.4044,3653.1801,3648.5) polygon(3611.4203,3640.5,3612.5,3639.9111,3620.5,3636.382,3625.0515,3640.5,3620.5,3643.482,3613.8854,3648.5,3615.5478,3656.5,3619.9049,3664.5,3612.5,3672.3986,3607.3488,3664.5,3609.4522,3656.5,3608.6902,3648.5) polygon(3833.9179,3632.5,3836.5,3629.766,3840.0753,3632.5,3836.5,3635.8199) polygon(3595.3863,3632.5,3596.5,3631.4658,3603.739,3632.5,3599.3098,3640.5,3596.5,3643.3098,3594.8944,3640.5) polygon(3810.087,3624.5,3812.5,3623.2935,3813.9478,3624.5,3812.5,3631.739) polygon(3787.5746,3624.5,3788.5,3624.0373,3789.2198,3624.5,3789.2198,3632.5,3788.5,3633.0399,3788.0017,3632.5) polygon(3686.087,3624.5,3692.5,3620.6522,3697.9969,3624.5,3692.5,3627.4598) polygon(3655.0786,3624.5,3660.5,3619.4658,3664.2094,3624.5,3660.5,3627.8561) polygon(3761.9601,3616.5,3764.5,3613.7292,3768.3098,3616.5,3764.5,3618.8445) polygon(3682.3406,3616.5,3684.5,3614.8805,3685.5797,3616.5,3684.5,3619.739) polygon(3594.0951,3616.5,3596.5,3610.087,3599.2484,3616.5,3596.5,3618.7634) polygon(3795.2512,3608.5,3796.5,3605.6902,3798.1056,3608.5,3796.5,3611.3098) polygon(3699.2044,3608.5,3700.5,3605.261,3702.1195,3608.5,3708.5,3610.8202,3716.5,3611.3358,3724.5,3608.6902,3725.0073,3608.5,3732.5,3605.2888,3734.7478,3608.5,3740.5,3612.0951,3748.5,3616.0373,3749.2198,3616.5,3751.5985,3624.5,3756.5,3628.001,3764.5,3628.5845,3769.9214,3632.5,3772.5,3636.6902,3777.5797,3640.5,3778.677,3648.5,3780.5,3650.6268,3783.3358,3648.5,3788.5,3645.766,3794.4681,3640.5,3796.5,3637.9601,3799.0399,3640.5,3804.5,3646.4565,3808.9956,3648.5,3812.5,3651.4203,3820.5,3652.8805,3822.913,3656.5,3824.1195,3664.5,3828.5,3668.8805,3835.739,3672.5,3836.5,3672.6087,3840.0638,3680.5,3844.5,3687.3761,3849.5934,3680.5,3849.2935,3672.5,3852.5,3667.6902,3857.6044,3664.5,3860.5,3662.6902,3861.9478,3664.5,3868.5,3671.0522,3875.739,3672.5,3868.5,3676.1195,3862.6594,3680.5,3860.5,3681.4254,3855.5478,3688.5,3860.5,3693.002,3866.0024,3688.5,3868.5,3684.0044,3872.8805,3680.5,3876.5,3673.261,3876.8805,3672.5,3884.5,3669.4522,3886.2928,3672.5,3892.5,3679.5348,3893.7065,3680.5,3893.1478,3688.5,3892.5,3689.7956,3887.7112,3696.5,3892.5,3698.4719,3900.5,3701.1801,3902.9462,3704.5,3907.739,3712.5,3906.8239,3720.5,3900.5,3727.9399,3899.7675,3728.5,3900.5,3729.8603,3901.6902,3728.5,3908.5,3723.5474,3911.7046,3728.5,3916.5,3735.2935,3923.2935,3728.5,3924.5,3723.674,3925.8162,3728.5,3930.3098,3736.5,3932.5,3739.0031,3937.3098,3744.5,3932.5,3747.998,3924.5,3751.1397,3923.6344,3752.5,3924.5,3753.1801,3932.5,3755.5951,3937.4522,3752.5,3940.5,3748.146,3948.5,3750.0024,3949.7488,3752.5,3948.5,3755.7112,3943.7112,3760.5,3948.5,3766.087,3949.7065,3768.5,3948.5,3773.326,3948.1033,3776.5,3948.5,3777.0601,3951.674,3776.5,3956.5,3775.2935,3964.5,3773.2888,3972.5,3771.9485,3978.677,3776.5,3972.5,3780.618,3964.5,3779.3098,3961.0399,3784.5,3956.5,3792.2826,3956.4308,3792.5,3956.5,3792.5761,3963.1033,3800.5,3964.1956,3808.5,3964.5,3808.5895,3972.4105,3816.5,3972.5,3816.5662,3974.0219,3816.5,3972.5,3816.1195,3964.8805,3808.5,3971.2044,3800.5,3972.5,3794.0219,3980.5,3799.0522,3981.9478,3800.5,3987.2484,3808.5,3983.739,3816.5,3982.1195,3824.5,3988.5,3826.0951,3990.8202,3824.5,3996.5,3821.3761,4004.3098,3824.5,3998.8445,3832.5,4001.9478,3840.5,3998.5683,3848.5,3996.5,3853.326,3989.261,3848.5,3988.5,3848.2463,3988.2826,3848.5,3988.5,3848.8805,3994.5956,3856.5,3996.5,3857.8603,3998.4044,3856.5,4004.5,3853.1135,4012.5,3856.0017,4020.5,3855.4658,4021.9478,3856.5,4025.306,3864.5,4020.5,3869.7065,4016.0373,3864.5,4012.5,3857.4254,4007.998,3864.5,4012.5,3869.002,4016.7753,3872.5,4020.5,3879.2044,4021.5797,3880.5,4020.5,3882.6594,4017.5797,3888.5,4012.5,3890.2928,4004.5,3895.9927,4003.9927,3896.5,3996.5,3902.1195,3996.1338,3904.5,3996.5,3906.4044,3996.914,3904.5,4004.5,3896.5692,4011.7699,3904.5,4012.5,3905.9601,4020.5,3909.9058,4024.1318,3912.5,4024.9556,3920.5,4028.5,3927.2935,4029.9478,3928.5,4028.5,3935.739,4028.1956,3936.5,4028.5,3937.261,4030.5684,3944.5,4028.5,3951.739,4020.5,3947.3098,4012.5,3948.8239,4004.5,3951.1397,4001.326,3952.5,4004.5,3953.3656,4012.5,3955.8419,4020.5,3959.4203,4028.5,3952.7537,4031.234,3960.5,4028.5,3964.3732,4021.4254,3968.5,4027.1521,3976.5,4020.5,3980.4308,4012.5,3978.7478,4004.5,3980.0239,4000.7906,3976.5,3996.5,3972.2094,3990.0929,3968.5,3988.5,3966.9071,3987.5266,3968.5,3988.5,3970.0929,3992.2094,3976.5,3996.5,3982.323,3998.5319,3984.5,3999.2239,3992.5,4004.5,4000.0372,4004.881,4000.5,4004.5,4006.978,3996.5,4006.1195,3995.8199,4008.5,3988.5,4012.2955,3980.5,4011.0822,3978.1761,4008.5,3980.5,4002.6902,3984.0044,4000.5,3980.5,3996.9956,3977.6902,3992.5,3972.5,3989.306,3964.5,3989.7065,3957.558,3984.5,3956.5,3983.1398,3948.5,3984.3098,3947.739,3984.5,3940.5,3986.1086,3936.3913,3992.5,3940.5,3996.0951,3944.9049,4000.5,3940.5,4004.2094,3932.5,4003.0652,3928.6522,4000.5,3927.9601,3992.5,3924.5,3990.424,3919.3098,3992.5,3918.5683,4000.5,3916.5,4002.1086,3908.5,4008.3617,3908.3098,4008.5,3900.5,4012.4049,3894.2522,4008.5,3895.674,4000.5,3900.5,3996.8805,3902.2522,3992.5,3900.5,3991.7035,3898.9071,3992.5,3892.5,3999.5479,3887.8015,3992.5,3884.5,3989.4049,3882.249,3992.5,3876.5,3999.1567,3871.3956,4000.5,3868.5,4001.5342,3862.7634,4008.5,3860.5,4016.1956,3860.3098,4016.5,3852.5,4023.442,3848.3348,4016.5,3845.558,4008.5,3844.5,4007.1398,3841.5951,4000.5,3844.5,3995.3358,3846.6268,3992.5,3848.6522,3984.5,3844.5,3982.903,3842.3146,3984.5,3836.5,3990.6377,3832.3098,3992.5,3828.5,3995.5479,3820.5,3998.1056,3816.1401,3992.5,3812.5,3989.6512,3805.2198,3992.5,3804.5,3993.5797,3803.4203,3992.5,3796.5,3989.5342,3790.6268,3984.5,3788.5,3982.9049,3782.4719,3976.5,3783.1208,3968.5,3780.5,3962.5435,3774.8805,3960.5,3772.5,3959.8199,3771.8199,3960.5,3772.5,3961.6902,3776.1319,3968.5,3772.5,3973.4525,3764.5,3975.2239,3756.5,3969.7065,3748.5,3969.4049,3747.2935,3968.5,3748.5,3966.087,3753.2888,3960.5,3751.413,3952.5,3755.4203,3944.5,3748.6087,3936.5,3748.5,3936.2463,3748.4105,3936.5,3743.3098,3944.5,3743.998,3952.5,3740.5,3956.3478,3732.8044,3952.5,3732.5,3950.9781,3724.5,3948.0239,3720.3542,3944.5,3716.5,3940.8599,3709.9478,3944.5,3712.7753,3952.5,3708.5,3954.9049,3706.4749,3952.5,3706.8913,3944.5,3700.5,3938.1087,3698.4317,3936.5,3700.5,3929.261,3701.0073,3928.5,3700.6171,3920.5,3708.5,3913.1801,3709.0601,3912.5,3708.5,3911.442,3700.5,3909.7488,3696.7209,3904.5,3700.5,3899.7761,3703.1208,3896.5,3700.5,3892.4049,3695.8199,3896.5,3692.5,3898.9462,3687.2239,3904.5,3690.1195,3912.5,3684.5,3919.9927,3683.0015,3912.5,3681.4734,3904.5,3677.7516,3896.5,3677.1801,3888.5,3677.5307,3880.5,3679.3683,3872.5,3676.5,3867.6239,3669.5342,3872.5,3672.1195,3880.5,3668.5,3885.326,3661.261,3880.5,3660.5,3880.3829,3652.5,3879.9927,3644.5,3876.1195,3643.4658,3872.5,3644.5,3868.8805,3652.5,3869.2888,3658.087,3864.5,3660.5,3860.8805,3663.0031,3856.5,3660.5,3855.1522,3654.6594,3856.5,3652.5,3857.7956,3646.0219,3856.5,3644.5,3856.2463,3637.8603,3848.5,3640.0373,3840.5,3636.5,3835.5478,3628.8805,3832.5,3632.6268,3824.5,3636.5,3819.8522,3638.5951,3816.5,3636.5,3814.9037,3632.3098,3816.5,3628.5,3819.5478,3620.5,3820.1319,3614.4469,3816.5,3620.5,3812.6087,3626.2522,3808.5,3620.5,3805.1163,3612.5,3804.3478,3610.0951,3800.5,3612.5,3797.002,3619.5746,3792.5,3620.5,3786.0219,3620.6014,3784.5,3620.5,3784.2826,3612.5,3780.3732,3604.5,3778.3098,3603.6484,3776.5,3604.5,3771.674,3612.5,3772.9247,3617.2935,3768.5,3615.8015,3760.5,3614.6902,3752.5,3614.4047,3744.5,3617.7292,3736.5,3620.5,3732.6902,3628.5,3728.7174,3628.6522,3728.5,3628.5,3728.3829,3620.5,3726.9037,3616.7753,3728.5,3612.5,3731.7065,3607.6902,3728.5,3608.0044,3720.5,3604.5,3718.3098,3602.9071,3720.5,3596.5,3726.9071,3593.1439,3720.5,3590.8202,3712.5,3596.5,3705.558,3604.5,3705.8603,3609.261,3704.5,3612.5,3703.4203,3613.5797,3704.5,3620.5,3707.9601,3625.6902,3704.5,3628.5,3697.0073,3636.5,3701.1258,3640.6781,3696.5,3644.5,3691.1146,3648.9247,3688.5,3644.6902,3680.5,3652.5,3677.029,3658.7709,3672.5,3660.5,3668.0044,3664.9956,3672.5,3668.5,3676.0044,3675.9927,3680.5,3676.5,3682.0219,3676.6087,3680.5,3676.5,3680.3478,3669.9601,3672.5,3668.5,3669.9969,3663.0031,3664.5,3668.5,3658.087,3669.2935,3656.5,3675.9601,3648.5,3672.6268,3640.5,3671.413,3632.5,3676.5,3626.7348,3679.826,3632.5,3684.5,3635.538,3692.5,3635.7761,3697.1801,3632.5,3700.5,3626.6902,3708.5,3626.2522,3716.5,3627.3761,3722.9049,3632.5,3724.5,3637.6044,3732.5,3634.4632,3740.5,3638.4565,3745.9601,3632.5,3744.2747,3624.5,3740.5,3621.5342,3732.5,3618.5683,3724.5,3621.7065,3716.5,3620.0753,3708.5,3622.7478,3700.5,3622.7478,3695.694,3616.5) polygon(3611.0951,3608.5,3612.5,3607.0951,3614.9976,3608.5,3615.3098,3616.5,3612.5,3618.2291,3610.6268,3616.5) polygon(3736.2247,3600.5,3740.5,3599.0201,3744.7753,3600.5,3740.5,3603.7065) polygon(3702.8805,3600.5,3708.5,3598.2522,3714.1195,3600.5,3708.5,3604.2463) polygon(3666.4317,3600.5,3668.5,3598.8913,3676.5,3598.323,3684.1195,3600.5,3676.5,3602.677,3672.2094,3608.5,3668.5,3612.4155,3660.5,3611.3098,3658.2522,3608.5,3660.5,3605.6902) polygon(3683.2935,3592.5,3684.5,3588.8805,3692.5,3590.8913,3694.3098,3592.5,3692.5,3595.3956,3684.5,3599.739) polygon(3689.6808,3568.5,3692.5,3565.7893,3695.2107,3568.5,3692.5,3572.0239) polygon(3640.6522,3568.5,3644.5,3566.4749,3646.249,3568.5,3644.5,3571.2484) polygon(3666.6902,3560.5,3668.5,3558.087,3669.6137,3560.5,3668.5,3562.1087) polygon(3816.9362,3536.5,3820.5,3533.8696,3828.5,3533.6672,3831.7493,3536.5,3828.5,3540.0638,3820.5,3540.1826) polygon(3635.317,3536.5,3636.5,3534.4565,3638.9976,3536.5,3636.5,3539.7112) polygon(4139.0883,4648.5,4140.5,4647.0883,4141.9117,4648.5,4140.5,4654.5) polygon(4007.9783,4608.5,4012.5,4603.9783,4016.5,4608.5,4012.5,4612.66) polygon(4176.5,4552.5,4180.5,4548.6482,4184.3518,4552.5,4184.5,4560.5,4180.5,4564.674,4175.7,4560.5) polygon(3511.6111,4544.5,3516.5,4540.3096,3520.5,4544.5,3516.5,4548.5) polygon(4022.3334,4536.5,4028.5,4530.4592,4034.1923,4536.5,4028.5,4542.5408) polygon(3522.2778,4392.5,3524.5,4390.1471,3532.5,4385.2742,3539.3923,4392.5,3532.5,4399.0883,3524.5,4395.1666) polygon(3171.3571,4392.5,3172.5,4391.3572,3173.9545,4392.5,3172.5,4394.5) polygon(3706.9,4376.5,3708.5,4375.4333,3709.5,4376.5,3708.5,4378.1) polygon(4325.6282,4280.5,4332.5,4273.8827,4340.0493,4280.5,4332.5,4287.1173) polygon(3569.8333,4200.5,3572.5,4199.8334,3573.3,4200.5,3572.5,4201.6428) polygon(3684.5,4184.5,3684.5,4184.5,3684.5,4184.5,3684.5,4184.5) polygon(3527.7941,4168.5,3532.5,4163.5,3540.5,4163.6305,3548.5,4162.3182,3554.6818,4168.5,3556.5,4169.1061,3564.125,4176.5,3564.5,4179.1666,3567.3235,4184.5,3565.7308,4192.5,3564.5,4196.5,3563.0455,4200.5,3556.5,4206.5,3548.5,4206.2142,3540.5,4202.5,3537.3,4200.5,3532.5,4198.6538,3524.5,4193.3,3523.1667,4192.5,3524.5,4190.9,3525.6852,4184.5,3524.5,4179.1666,3521.3,4176.5,3524.5,4174.7222) polygon(3778.7222,4152.5,3780.5,4150.2142,3781.9545,4152.5,3780.5,4154.1) polygon(3937.8333,4144.5,3940.5,4143,3942.5,4144.5,3940.5,4147.5) polygon(3657.8333,4144.5,3660.5,4143.3572,3668.5,4144.5,3668.5,4144.5,3668.5,4144.5,3660.5,4146.5) polygon(4408.0862,4136.5,4412.5,4131.38,4417.62,4136.5,4419.1086,4144.5,4412.5,4150.8334,4405.8914,4144.5) polygon(3996.5,4128.5,3996.5,4128.5,3996.5,4128.5,3996.5,4128.5) polygon(3972.5,4128.5,3972.5,4128.5,3972.5,4128.5,3972.5,4128.5) polygon(3931.7,4128.5,3932.5,4126.9,3933.5,4128.5,3932.5,4129.8334) polygon(3963.3571,4120.5,3964.5,4119.6111,3966.5,4120.5,3964.5,4121.5) polygon(3923.7727,4120.5,3924.5,4119.7727,3926.1,4120.5,3924.5,4121.3) polygon(3883.0455,4120.5,3884.5,4118.9,3887.1667,4120.5,3892.5,4128.5,3892.5,4128.5,3892.5,4128.5,3884.5,4128.5,3884.5,4128.5) polygon(4068.5,4112.5,4068.5,4112.5,4068.5,4112.5,4068.5,4112.5) polygon(4051.5,4104.5,4052.5,4102.9,4054.1,4104.5,4052.5,4105.5) polygon(3914.5,4104.5,3916.5,4103.6111,3919.1667,4104.5,3916.5,4105.5) polygon(4100.5,4096.5,4100.5,4096.5,4100.5,4096.5,4100.5,4096.5) polygon(4026.6538,4096.5,4028.5,4093.5,4030.6818,4096.5,4028.5,4099.1666) polygon(3884.5,4096.5,3884.5,4096.5,3884.5,4096.5,3884.5,4096.5) polygon(3850.9,4096.5,3852.5,4094.9,3853.5,4096.5,3852.5,4097.1666) polygon(3787.7,4096.5,3788.5,4095.7,3789.3889,4096.5,3788.5,4097.1666) polygon(3772.5,4096.5,3772.5,4096.5,3772.5,4096.5,3772.5,4096.5) polygon(4058.9,4088.5,4060.5,4085.3,4063.1666,4088.5,4060.5,4091.1666) polygon(3820.5,4088.5,3820.5,4088.5,3820.5,4088.5,3820.5,4088.5) polygon(3747.9286,4088.5,3748.5,4084.5,3749.3889,4088.5,3748.5,4090.1) polygon(3795.5,4080.5,3796.5,4079.3572,3799.1667,4080.5,3796.5,4081.8334) polygon(3778.7857,4080.5,3780.5,4077.0714,3782.9,4080.5,3780.5,4083.9286) polygon(3737.8333,4080.5,3740.5,4079.3572,3744.5,4080.5,3740.5,4081.0714) polygon(4099.3572,4072.5,4100.5,4071.3572,4101.6428,4072.5,4100.5,4074.1) polygon(3886.5,4072.5,3884.5,4069.8334,3881.5,4072.5,3884.5,4075.9286) polygon(4071.4091,4064.5,4076.5,4060.1923,4080.8077,4064.5,4080.5,4072.5,4076.5,4073.2273,4075.5,4072.5) polygon(3901.9545,4064.5,3900.5,4063.2693,3898.5,4064.5,3900.5,4065.4412) polygon(3847.4091,4064.5,3844.5,4062.5,3839.1667,4064.5,3844.5,4072.5) polygon(3796.5,4064.5,3796.5,4064.5,3796.5,4064.5,3796.5,4064.5) polygon(3698.2143,4056.5,3700.5,4054.7222,3702.2778,4056.5,3700.5,4058.2778) polygon(3602.1,4056.5,3604.5,4054.6538,3607.5,4056.5,3604.5,4058.5) polygon(4087.5,4048.5,4092.5,4042.7858,4096.9445,4048.5,4096.5,4056.5,4092.5,4058.5,4091.7727,4056.5) polygon(3998.7857,4048.5,3996.5,4046.5,3995.3571,4048.5,3996.5,4052.5) polygon(3667.7,4048.5,3668.5,4047.1666,3669.5,4048.5,3668.5,4050.1) polygon(3644.5,4048.5,3644.5,4048.5,3652.5,4048.5,3652.5,4048.5,3652.5,4048.5,3644.5,4048.5) polygon(3733.6429,4040.5,3740.5,4035.1666,3745.8333,4040.5,3740.5,4047.3572) polygon(3724.5,4040.5,3724.5,4040.5,3724.5,4040.5,3724.5,4040.5) polygon(3612.5,4040.5,3612.5,4040.5,3612.5,4040.5,3612.5,4040.5) polygon(3580.5,4040.5,3580.5,4040.5,3580.5,4040.5,3580.5,4040.5) polygon(3679.1667,4032.5,3684.5,4030.2142,3686.5,4032.5,3684.5,4035.7) polygon(3596.5,4032.5,3596.5,4032.5,3596.5,4032.5,3596.5,4032.5) polygon(3707.3571,4024.5,3708.5,4020.5,3710.1,4024.5,3708.5,4025.3889) polygon(4103.4091,4016.5,4108.5,4009.5,4114.7222,4016.5,4108.5,4020) polygon(4084.5,4016.5,4076.5,4015.8846,4075.7727,4016.5,4076.5,4017.1666) polygon(3668.5,4016.5,3668.5,4016.5,3668.5,4016.5,3674.2143,4024.5,3668.5,4028.1364,3665.1667,4024.5) polygon(3646.5,4016.5,3652.5,4014.7858,3657.3,4016.5,3652.5,4018.3462) polygon(3672.5,4008.5,3676.5,4004.5,3682.9,4008.5,3676.5,4011.1666) polygon(3642.1,4008.5,3644.5,4004.5,3646.2143,4008.5,3644.5,4014.5) polygon(3515.6111,4008.5,3516.5,4007.3572,3517.2273,4008.5,3516.5,4010.1) polygon(4098.5,4000.5,4092.5,3997.0714,4088.5,4000.5,4092.5,4002.9) polygon(3660.5,4000.5,3660.5,4000.5,3660.5,4000.5,3660.5,4000.5) polygon(3596.5,4000.5,3596.5,4000.5,3596.5,4000.5,3596.5,4000.5) polygon(3588.5,3992.5,3588.5,3992.5,3588.5,3992.5,3588.5,3992.5) polygon(3387.0454,3992.5,3388.5,3991.2693,3389.5,3992.5,3388.5,3994.5) polygon(4228.5,3984.5,4228.5,3984.5,4228.5,3984.5,4228.5,3984.5) polygon(4156.5,3984.5,4156.5,3984.5,4156.5,3984.5,4156.5,3984.5) polygon(3537.8333,3984.5,3540.5,3982.2142,3541.7308,3984.5,3540.5,3988.5) polygon(4172.5,3976.5,4172.5,3976.5,4172.5,3976.5,4172.5,3976.5) polygon(4135.5,3976.5,4140.5,3970.7858,4143.1666,3976.5,4140.5,3979.3572) polygon(3616.8077,3976.5,3620.5,3970.5,3625.3,3976.5,3620.5,3982.5) polygon(3595.6111,3976.5,3596.5,3975.5,3604.5,3975.1666,3605.5,3976.5,3604.5,3977.5,3596.5,3979.1666) polygon(4093.6428,3968.5,4092.5,3965.8334,4091.8846,3968.5,4092.5,3976.5) polygon(3624.5,3968.5,3628.5,3966.5,3633.8333,3968.5,3628.5,3971.1666) polygon(3570.9,3968.5,3572.5,3967.3572,3573.1667,3968.5,3572.5,3969.6428) polygon(3535.1667,3968.5,3540.5,3966.7222,3542.2778,3968.5,3540.5,3970.7858) polygon(3524.5,3968.5,3524.5,3968.5,3524.5,3968.5,3524.5,3968.5) polygon(4118.5,3960.5,4124.5,3955.7,4129.3,3960.5,4124.5,3964.5) polygon(3631.1667,3960.5,3636.5,3954.1,3643.8846,3960.5,3636.5,3967.8846) polygon(3615.8333,3960.5,3620.5,3953.5,3624.8077,3960.5,3620.5,3966.7222) polygon(3588.5,3960.5,3588.5,3960.5,3596.5,3955.7,3599.5,3960.5,3596.5,3962.9,3588.5,3968.5,3588.5,3968.5,3588.5,3968.5) polygon(3546.1,3960.5,3548.5,3957.8333,3550.5,3960.5,3548.5,3962.9) polygon(3508.5,3960.5,3508.5,3960.5,3508.5,3960.5,3508.5,3960.5) polygon(3572.5,3952.5,3572.5,3952.5,3580.5,3952.5,3580.5,3952.5,3580.5,3952.5,3572.5,3952.5) polygon(3353.8333,3952.5,3356.5,3950.5,3358.2778,3952.5,3356.5,3954.2778) polygon(4156.5,3936.5,4156.5,3936.5,4156.5,3936.5,4156.5,3936.5) polygon(3570.7222,3936.5,3572.5,3934.2143,3575.7,3936.5,3572.5,3941.8333) polygon(3547.8333,3936.5,3548.5,3933.8333,3556.5,3934.9,3558.2778,3936.5,3556.5,3939.1667,3548.5,3937.6429) polygon(3523.7727,3928.5,3524.5,3924.5,3525.3,3928.5,3524.5,3930.1) polygon(3631.4091,3920.5,3628.5,3915.1667,3624.9445,3920.5,3623.9286,3928.5,3620.5,3931.5,3612.5,3932.5,3604.5,3928.5,3596.5,3936.5,3604.5,3937.8333,3612.5,3938.5,3620.5,3939.8333,3624.5,3936.5,3628.5,3932.0555,3631.4091,3928.5) polygon(4154.2142,3912.5,4156.5,3909.3,4157.9546,3912.5,4156.5,3913.8333) polygon(3554.2143,3912.5,3556.5,3910.5,3559.7,3912.5,3556.5,3915.7) polygon(3536.5,3912.5,3540.5,3908.5,3542.7857,3912.5,3540.5,3913.9545) polygon(3476.5,3912.5,3476.5,3912.5,3476.5,3912.5,3476.5,3912.5) polygon(3598.7857,3904.5,3596.5,3903.0455,3592.5,3904.5,3596.5,3906.7857) polygon(3562.5,3904.5,3564.5,3900.5,3569.8333,3904.5,3564.5,3907.7) polygon(3468.5,3904.5,3468.5,3904.5,3468.5,3904.5,3468.5,3904.5) polygon(3566.7857,3896.5,3572.5,3890.7857,3579.1667,3896.5,3572.5,3903.1667) polygon(3525.8333,3896.5,3532.5,3889.8333,3540.5,3896.5,3540.5,3896.5,3540.5,3896.5,3539.1667,3904.5,3532.5,3911.1667,3526.7857,3904.5) polygon(3500.5,3896.5,3500.5,3896.5,3500.5,3896.5,3500.5,3896.5) polygon(3452.5,3896.5,3452.5,3896.5,3452.5,3896.5,3452.5,3896.5) polygon(4212.5,3880.5,4212.5,3880.5,4212.5,3880.5,4212.5,3880.5) polygon(3508.5,3880.5,3508.5,3880.5,3516.5,3880.5,3516.5,3880.5,3516.5,3880.5,3508.5,3880.5) polygon(4125.5,3872.5,4124.5,3871.7727,4123.7727,3872.5,4124.5,3874.1) polygon(3492.5,3872.5,3492.5,3872.5,3492.5,3872.5,3492.5,3872.5) polygon(3457.1667,3872.5,3460.5,3869.4231,3464.1364,3872.5,3460.5,3876.9445) polygon(4117.8334,3856.5,4116.5,3854.5,4114.5,3856.5,4116.5,3858.7857) polygon(3428.5,3856.5,3428.5,3856.5,3428.5,3856.5,3428.5,3856.5) polygon(3489.3,3848.5,3492.5,3843.9286,3497.0714,3848.5,3492.5,3852.5) polygon(3474.3667,3848.5,3476.5,3843.9286,3479.7,3848.5,3476.5,3850.9615) polygon(4162.5,3840.5,4164.5,3838.5,4167.1666,3840.5,4164.5,3842.5) polygon(4116.5,3840.5,4108.5,3839.0455,4107.5,3840.5,4108.5,3842.2778) polygon(3457.8333,3840.5,3460.5,3838.7222,3461.8333,3840.5,3460.5,3848.5,3460.5,3848.5,3460.5,3848.5) polygon(4093.5,3832.5,4092.5,3830.5,4092.1,3832.5,4092.5,3833.2273) polygon(3500.5,3832.5,3500.5,3832.5,3500.5,3832.5,3500.5,3832.5) polygon(3451.6111,3832.5,3452.5,3829.8333,3453.5,3832.5,3452.5,3834.1) polygon(3404.5,3832.5,3404.5,3832.5,3404.5,3832.5,3404.5,3832.5) polygon(4160.5,3824.5,4164.5,3823.5,4166.1,3824.5,4164.5,3825.6429) polygon(3483.5,3824.5,3484.5,3820.5,3485.5,3824.5,3484.5,3827.1667) polygon(3252.5,3824.5,3252.5,3824.5,3252.5,3824.5,3252.5,3824.5) polygon(3387.0454,3816.5,3388.5,3814.7222,3390.5,3816.5,3388.5,3820.5) polygon(4163.3572,3808.5,4164.5,3807.7,4165.5,3808.5,4164.5,3809.5) polygon(3457.8333,3808.5,3460.5,3806.9,3468.5,3805.0714,3471.5,3808.5,3476.5,3815.1667,3480.5,3816.5,3476.5,3817.5,3472.5,3824.5,3468.5,3828,3460.5,3826.9,3455.7,3824.5,3460.5,3816.5) polygon(3440.5,3808.5,3444.5,3805.3,3448.5,3808.5,3444.5,3810.5) polygon(3380.5,3808.5,3380.5,3808.5,3380.5,3808.5,3380.5,3808.5) polygon(3526.1,3800.5,3524.5,3798.2143,3522.2143,3800.5,3524.5,3802.5,3531.3571,3808.5,3532.5,3809.6429,3533.1667,3808.5,3532.5,3807.6111) polygon(3488.0555,3800.5,3492.5,3796.5,3499.1667,3800.5,3500.5,3808.5,3500.5,3808.5,3508.5,3816.5,3508.5,3816.5,3508.5,3816.5,3500.5,3821.8333,3494.1,3816.5,3492.5,3815.8333,3487,3808.5) polygon(3393.0714,3800.5,3396.5,3797.8333,3399.9286,3800.5,3396.5,3805.3) polygon(4140.5,3792.5,4140.5,3792.5,4140.5,3792.5,4140.5,3800.5,4140.5,3800.5,4136.5,3808.5,4132.5,3812.5,4129.3,3808.5,4126.2778,3800.5,4132.5,3795.8333) polygon(4124.5,3792.5,4124.5,3792.5,4124.5,3792.5,4124.5,3792.5) polygon(4086.1,3792.5,4084.5,3788.5,4082.5,3792.5,4076.5,3798.5,4074.7222,3800.5,4076.5,3801.7308,4077.4412,3800.5,4084.5,3793.4412,4092,3800.5,4092.5,3802.5,4093.6428,3800.5,4092.5,3799.6111) polygon(3466.7222,3792.5,3468.5,3789.3,3471.7,3792.5,3468.5,3795.1667) polygon(3442.0385,3792.5,3444.5,3789.5909,3448.5,3792.5,3444.5,3797.0714) polygon(3422.5,3792.5,3428.5,3789.8333,3430.5,3792.5,3428.5,3800.5,3428.5,3800.5,3428.5,3800.5) polygon(3510.1,3784.5,3508.5,3783.7,3507.5,3784.5,3508.5,3788.5) polygon(3304.0555,3784.5,3308.5,3781.8333,3311.1667,3784.5,3308.5,3787.8333) polygon(4124.5,3776.5,4124.5,3776.5,4132.5,3775.1667,4140.5,3776.5,4140.5,3776.5,4140.5,3776.5,4132.5,3779.1667,4124.5,3776.5) polygon(3443.1667,3776.5,3444.5,3775.5,3445.5,3776.5,3444.5,3777.5) polygon(3404.5,3776.5,3404.5,3776.5,3404.5,3776.5,3404.5,3776.5) polygon(3436.5,3768.5,3436.5,3768.5,3436.5,3768.5,3436.5,3768.5) polygon(3409.3,3768.5,3412.5,3766.7222,3415.7,3768.5,3412.5,3772.5) polygon(4108.5,3760.5,4108.5,3760.5,4116.5,3756.1923,4122.1,3760.5,4116.5,3766.1,4108.5,3760.5) polygon(4064.5,3760.5,4060.5,3758.5,4059.7,3760.5,4060.5,3761.6429) polygon(3556.8636,3760.5,3556.5,3760.0294,3555.8846,3760.5,3556.5,3761.5) polygon(3428.5,3760.5,3428.5,3760.5,3428.5,3760.5,3428.5,3760.5) polygon(3511.5,3752.5,3508.5,3749.5,3506.7857,3752.5,3508.5,3755.1667,3513.8333,3760.5,3516.5,3763.9286,3519.5,3760.5,3516.5,3757.5) polygon(3459.3571,3752.5,3460.5,3750.9,3468.5,3747.9286,3472.0555,3752.5,3476.5,3756.5,3481.5,3760.5,3476.5,3767.1667,3472.5,3768.5,3468.5,3776.5,3468.5,3776.5,3466.1,3784.5,3460.5,3788.5,3452.5,3788.9445,3449.1667,3784.5,3452.5,3781.1667,3457.5909,3776.5,3460.5,3770.1,3464.5,3768.5,3463.7,3760.5,3460.5,3754.1) polygon(4132.5,3744.5,4132.5,3744.5,4132.5,3744.5,4132.5,3752.5,4132.5,3752.5,4132.5,3752.5) polygon(4140.5,3736.5,4140.5,3736.5,4140.5,3736.5,4140.5,3736.5) polygon(4047.9286,3736.5,4044.5,3734.1,4043,3736.5,4044.5,3738.1) polygon(3372.5,3736.5,3372.5,3736.5,3380.5,3736.5,3380.5,3736.5,3380.5,3736.5,3372.5,3736.5) polygon(4093.3889,3728.5,4100.5,3724.5,4108.5,3728.5,4108.5,3728.5,4116.5,3736.5,4116.5,3736.5,4116.5,3736.5,4108.5,3740.5,4100.5,3738.5,4096.5,3736.5) polygon(3423.7,3728.5,3428.5,3721.6429,3434.5,3728.5,3428.5,3735.3571) polygon(3412.5,3728.5,3412.5,3728.5,3412.5,3728.5,3412.5,3728.5) polygon(4073.3,3720.5,4068.5,3715.7,4066.7858,3720.5,4060.5,3727.8333,4058.9,3728.5,4060.5,3730.1,4068.5,3735.1667,4071.1666,3728.5) polygon(3486.5,3720.5,3484.5,3719.3571,3476.5,3720.5,3481.3,3728.5,3484.5,3730.2778,3490.1,3736.5,3492.5,3739.9286,3500.5,3738.1,3502.1,3736.5,3500.5,3732.5,3496.5,3728.5,3492.5,3727.3571) polygon(3476.5,3720.5,3468.5,3716.5,3460.5,3716.5,3452.5,3719.1667,3449.8333,3720.5,3449.3,3728.5,3452.5,3730.5,3455.1667,3728.5,3460.5,3724.5,3468.5,3726.5) polygon(3415.5,3720.5,3420.5,3716.8636,3427.1667,3720.5,3420.5,3724.9445) polygon(3396.5,3720.5,3396.5,3720.5,3404.5,3720.5,3404.5,3720.5,3404.5,3720.5,3396.5,3720.5) polygon(4132.5,3704.5,4132.5,3704.5,4132.5,3704.5,4132.5,3704.5) polygon(4100.5,3704.5,4100.5,3704.5,4100.5,3704.5,4102.7858,3712.5,4100.5,3714.1,4097.8334,3712.5) polygon(4046.5,3704.5,4044.5,3702.9,4041.8334,3704.5,4036.5,3707.7,4034.5,3712.5,4036.5,3713.9117,4043.0883,3720.5,4044.5,3722.9,4046.3462,3720.5,4044.5,3717.0714,4039.9286,3712.5,4044.5,3706.1) polygon(3501.8333,3704.5,3500.5,3699.1667,3498.9,3704.5,3500.5,3706.5) polygon(3478.5,3704.5,3476.5,3703.4333,3468.5,3704.5,3476.5,3707.1667) polygon(3403.3571,3704.5,3404.5,3703.7,3412.5,3701.8333,3417.3,3704.5,3412.5,3712.5,3412.5,3712.5,3412.5,3712.5,3404.5,3708.5) polygon(3480.1364,3688.5,3476.5,3681.8333,3472.8636,3688.5,3476.5,3690.7222) polygon(3364.5,3688.5,3364.5,3688.5,3364.5,3688.5,3364.5,3688.5) polygon(4076.5,3680.5,4076.5,3680.5,4084.5,3679.3571,4086.1,3680.5,4088.5,3688.5,4084.5,3690.3461,4081.5,3688.5,4076.5,3680.5) polygon(3997.6429,3680.5,3996.5,3672.5,3995.3571,3680.5,3996.5,3681.3) polygon(3354.9,3680.5,3356.5,3678.9,3360.5,3680.5,3356.5,3682.7857) polygon(3308.5,3680.5,3308.5,3680.5,3308.5,3680.5,3308.5,3680.5) polygon(3415.5,3672.5,3420.5,3669.1667,3428.5,3671.5,3429.5,3672.5,3433.3,3680.5,3429.6429,3688.5,3428.5,3692.5,3420.5,3693.5909,3415.8333,3688.5,3412.5,3685.6429,3406.9615,3680.5,3412.5,3674.5) polygon(3404.5,3672.5,3404.5,3672.5,3404.5,3672.5,3404.5,3672.5) polygon(3347.6111,3672.5,3348.5,3671.6111,3349.3889,3672.5,3348.5,3673.3889) polygon(4077.5,3664.5,4084.5,3661.2059,4087.6111,3664.5,4084.5,3668.8077) polygon(4068.5,3664.5,4068.5,3664.5,4068.5,3664.5,4068.5,3664.5) polygon(3409.5,3656.5,3412.5,3653.0714,3415.1667,3656.5,3414.2778,3664.5,3412.5,3667.7,3409.8333,3664.5) polygon(3370.6538,3656.5,3372.5,3650.5,3380.5,3655.1667,3382.5,3656.5,3382.1,3664.5,3383.7,3672.5,3380.5,3676.5,3379.0454,3672.5,3379.3571,3664.5,3372.5,3659.1667) polygon(3331.5,3656.5,3332.5,3655.8846,3334.5,3656.5,3332.5,3657.3) polygon(4056.5,3648.5,4060.5,3647.5,4064.5,3648.5,4060.5,3649.8333) polygon(3989.0333,3648.5,3988.5,3640.5,3986.9,3648.5,3981.8333,3656.5,3988.5,3660.9445,3991.5769,3656.5) polygon(3977.3,3648.5,3972.5,3643.7,3966.5,3648.5,3964.5,3652.5,3962.2143,3656.5,3964.5,3658.2778,3965.6429,3656.5,3972.5,3651.1667) polygon(3949.2273,3648.5,3948.5,3647.8333,3947.3571,3648.5,3948.5,3649.0333) polygon(3511.4091,3648.5,3508.5,3646.3666,3504.9445,3648.5,3500.5,3653.5,3492.5,3654.6177,3489.3,3656.5,3492.5,3661.8333,3496.5,3664.5,3500.5,3672.5,3508.5,3667.7,3509.7308,3664.5,3508.5,3662.5,3503.1667,3656.5,3508.5,3651.7) polygon(3442.7222,3648.5,3444.5,3643.1667,3446.5,3648.5,3444.5,3651.1667) polygon(3340.5,3648.5,3340.5,3648.5,3348.5,3646.2143,3350.2778,3648.5,3348.5,3650.5,3340.5,3648.5) polygon(3324.5,3648.5,3324.5,3648.5,3324.5,3648.5,3324.5,3648.5) polygon(3267.2692,3648.5,3268.5,3646.9,3269.9546,3648.5,3268.5,3650.5) polygon(4092.5,3640.5,4092.5,3640.5,4092.5,3640.5,4092.5,3640.5) polygon(4067.5,3640.5,4068.5,3636.5,4069.6428,3640.5,4068.5,3644.5) polygon(4047.7,3640.5,4052.5,3637.8333,4054.9,3640.5,4052.5,3646.5) polygon(3933.3,3640.5,3932.5,3638.9,3931.7727,3640.5,3932.5,3641.3) polygon(3426.5,3640.5,3428.5,3636.5,3436.5,3637.8333,3440.5,3640.5,3436.5,3641.5,3428.5,3641.3889) polygon(3409.3,3640.5,3412.5,3635.1667,3415.7,3640.5,3412.5,3643.1667) polygon(3331.5,3640.5,3332.5,3638.5,3334.1,3640.5,3332.5,3641.1154) polygon(4032.5,3632.5,4036.5,3628.9445,4039.7,3632.5,4036.5,3635.7) polygon(3502.6818,3632.5,3500.5,3630.1,3499.0882,3632.5,3500.5,3635.1667) polygon(3452.5,3632.5,3452.5,3632.5,3452.5,3632.5,3460.5,3636.7667,3466.7222,3640.5,3460.5,3646.1,3452.5,3640.5,3452.5,3640.5) polygon(3420.5,3632.5,3420.5,3632.5,3420.5,3632.5,3420.5,3632.5) polygon(3391.7,3632.5,3396.5,3628.1364,3401.3,3632.5,3396.5,3637.8333) polygon(3362.3182,3632.5,3364.5,3627.7,3369.3,3632.5,3364.5,3634.6818) polygon(4013.5,3624.5,4020.5,3617.5,4028.5,3620.5,4032.5,3624.5,4028.5,3628.9445,4020.5,3631.5) polygon(3438.9,3624.5,3444.5,3618.9,3451.5,3624.5,3444.5,3629.5909) polygon(3386.9,3624.5,3388.5,3623.3571,3389.8333,3624.5,3388.5,3626.1) polygon(3372.5,3624.5,3372.5,3624.5,3372.5,3624.5,3372.5,3624.5) polygon(3348.5,3624.5,3348.5,3624.5,3356.5,3623.8333,3359.1667,3624.5,3356.5,3625.3889,3348.5,3624.5) polygon(3324.5,3624.5,3324.5,3624.5,3324.5,3624.5,3324.5,3624.5) polygon(4050.1471,3616.5,4052.5,3610.7857,4055.3572,3616.5,4052.5,3620.1364) polygon(4032.5,3616.5,4036.5,3610.7857,4038.8529,3616.5,4036.5,3620.5) polygon(3422.9,3616.5,3428.5,3610.2778,3436.5,3611.1667,3439.7,3616.5,3436.5,3619.7,3428.5,3621.5909) polygon(4019.6111,3608.5,4020.5,3605.8333,4021.6428,3608.5,4020.5,3612.5) polygon(3396.5,3608.5,3396.5,3608.5,3404.5,3603.1667,3412.5,3603.7,3416.5,3608.5,3412.5,3616.5,3412.5,3616.5,3412.5,3616.5,3404.5,3612.5,3400.5,3616.5,3396.5,3618.7857,3394.5,3616.5) polygon(3363.1667,3608.5,3364.5,3607.6111,3372.5,3605.5,3375.5,3608.5,3372.5,3612.5,3364.5,3609.6429) polygon(3950.1,3600.5,3956.5,3595.9286,3961.8333,3600.5,3956.5,3606.9) polygon(3511.1667,3600.5,3508.5,3595.1667,3502.1,3600.5,3508.5,3603.1667) polygon(3498.5,3600.5,3492.5,3595.7,3490.3182,3600.5,3484.5,3605.0714,3480.5,3608.5,3476.5,3612.8636,3470.7857,3616.5,3476.5,3621.5,3479.8333,3616.5,3484.5,3612.1923,3492.5,3611.4091,3494.9615,3608.5) polygon(3999.9286,3592.5,4004.5,3588.5,4009.8333,3592.5,4006.1,3600.5,4006.1,3608.5,4007.7,3616.5,4004.5,3619.7,4001.8333,3616.5,3996.5,3608.5,3996.5,3608.5,3996.5,3608.5,4001.8333,3600.5) polygon(3909.3889,3592.5,3908.5,3584.5,3907.1667,3592.5,3908.5,3593.6429) polygon(3415.1667,3592.5,3420.5,3586.1,3426.3182,3592.5,3425.8333,3600.5,3420.5,3603.7,3416.5,3600.5) polygon(3372.5,3592.5,3372.5,3592.5,3380.5,3592.5,3380.5,3592.5,3380.5,3600.5,3380.5,3600.5,3380.5,3600.5,3372.5,3592.5) polygon(3944.5,3584.5,3940.5,3582.1,3937.0714,3584.5,3932.5,3589.0714,3929.5,3592.5,3932.5,3597.3,3940.5,3596.5,3946.9,3600.5,3948.5,3601.2273,3955.7727,3608.5,3956.5,3610.5,3958.6818,3616.5,3956.5,3621.3,3948.5,3618.5,3947.2368,3624.5,3948.5,3627.5,3956.5,3625.8333,3958.5,3624.5,3964.5,3621.0714,3967.5476,3616.5,3965.1667,3608.5,3969.8333,3600.5,3964.5,3592.5,3964.5,3592.5,3956.5,3589.5,3953.5,3592.5,3948.5,3599.1667,3944.0555,3592.5) polygon(3500.5,3584.5,3492.5,3582.9,3491.3571,3584.5,3492.5,3587.1667) polygon(3398.1,3584.5,3404.5,3581.5909,3409.0714,3584.5,3404.5,3587.7) polygon(4004.5,3576.5,4004.5,3576.5,4004.5,3576.5,4004.5,3576.5) polygon(3660.9445,3576.5,3660.5,3575.9667,3660.1,3576.5,3660.5,3576.881) polygon(3364.5,3576.5,3364.5,3576.5,3364.5,3576.5,3364.5,3576.5) polygon(3472.5,3568.5,3468.5,3565.8333,3465.5,3568.5,3468.5,3576.5) polygon(3380.5,3568.5,3380.5,3568.5,3380.5,3568.5,3380.5,3568.5) polygon(3315.3571,3568.5,3316.5,3567.7727,3319.1667,3568.5,3316.5,3570.5) polygon(4027.5,3560.5,4028.5,3559.3571,4036.5,3558.5,4038.1,3560.5,4036.5,3564.5,4028.5,3561.5) polygon(3556.9211,3560.5,3556.5,3559.8846,3555.1667,3560.5,3556.5,3561.3889) polygon(3495.7,3560.5,3492.5,3555.1667,3490.7222,3560.5,3484.5,3565.1667,3479.5,3568.5,3484.5,3574.2143,3487.8333,3568.5,3492.5,3562.2778) polygon(3425.5,3560.5,3428.5,3557.5,3431.5,3560.5,3436.5,3563.8333,3442.1,3568.5,3436.5,3575.5,3434.9,3576.5,3433.8333,3584.5,3428.5,3589.8333,3422.5,3584.5,3420.5,3581.3,3417.8333,3576.5,3418.9,3568.5,3420.5,3567.1667) polygon(3388.5,3560.5,3388.5,3560.5,3388.5,3560.5,3388.5,3560.5) polygon(3306.9,3560.5,3308.5,3558.9,3309.2273,3560.5,3308.5,3561.6429) polygon(4007.7,3552.5,4012.5,3550.1,4018.5,3552.5,4012.5,3555.9286) polygon(3989.8333,3552.5,3996.5,3546.7857,4002.2143,3552.5,3996.5,3555.8333) polygon(3970.5,3552.5,3972.5,3548.5,3976.5,3552.5,3972.5,3554.5) polygon(3869.3,3552.5,3868.5,3550.9,3860.5,3544.5,3857.0714,3552.5,3860.5,3556.5,3868.5,3560.5) polygon(3814.6334,3552.5,3812.5,3550.6177,3809.3,3552.5,3812.5,3555.7) polygon(3473.0714,3552.5,3468.5,3550.2143,3460.5,3552.5,3468.5,3555.7) polygon(3401.3,3552.5,3404.5,3549.3,3407.7,3552.5,3412.5,3558.5,3413.8333,3560.5,3412.5,3562.1,3408.5,3568.5,3404.5,3571.4091,3401.3,3568.5,3400.8636,3560.5) polygon(3345.8333,3552.5,3348.5,3549.0714,3351.5,3552.5,3348.5,3554.6818) polygon(3959.1667,3544.5,3964.5,3542.7222,3969.8333,3544.5,3964.5,3547.7) polygon(3944.5,3544.5,3948.5,3542.9,3952.5,3544.5,3948.5,3547.1667) polygon(3574.853,3544.5,3572.5,3541.1667,3564.5,3544.5,3572.5,3547) polygon(3431.1667,3544.5,3436.5,3542.5,3441.8333,3544.5,3436.5,3546.7857) polygon(3413.6429,3544.5,3420.5,3540.1364,3427.3571,3544.5,3424.0555,3552.5,3420.5,3556.0555,3415.9286,3552.5) polygon(3252.5,3544.5,3252.5,3544.5,3252.5,3544.5,3252.5,3544.5) polygon(3921.5,3536.5,3916.5,3529.8333,3908.5,3536.5,3908.5,3536.5,3903.1667,3544.5,3903.7,3552.5,3908.5,3554.6818,3911.5,3552.5,3916.5,3546.7857,3919.8333,3552.5,3921.5,3560.5,3916.5,3564.9445,3914.0385,3568.5,3916.5,3574.9,3920.0555,3568.5,3924.5,3563.5,3930.5,3560.5,3930.1,3552.5,3924.5,3545.5,3921.8333,3544.5) polygon(3854.5,3536.5,3852.5,3533.3,3851.0455,3536.5,3844.5,3543.7,3843.6111,3544.5,3844.5,3545.6429,3845.3889,3544.5,3852.5,3538.1) polygon(3799.9286,3536.5,3796.5,3533.5,3794.1,3536.5,3796.5,3544.5) polygon(3548.5,3536.5,3540.5,3531.9286,3537.5909,3536.5,3540.5,3538.6334) polygon(3400.5,3536.5,3404.5,3535.3571,3405.8333,3536.5,3404.5,3538.5) polygon(3761.8333,3528.5,3756.5,3526.3666,3754.3666,3528.5,3756.5,3532.0555) polygon(3566.6818,3528.5,3564.5,3527,3562.5,3528.5,3564.5,3532.5) polygon(3396.5,3528.5,3396.5,3528.5,3396.5,3528.5,3396.5,3528.5) polygon(3356.5,3528.5,3356.5,3528.5,3364.5,3522.6818,3368.7667,3528.5,3364.5,3532.2647,3356.5,3528.5) polygon(3328.5,3528.5,3332.5,3526.1,3340.5,3525.8333,3343.5,3528.5,3340.5,3536.5,3340.5,3536.5,3332.5,3536.5,3332.5,3536.5) polygon(4036.5,3520.5,4036.5,3520.5,4036.5,3520.5,4036.5,3520.5) polygon(3972.5,3520.5,3972.5,3520.5,3972.5,3520.5,3972.5,3520.5) polygon(3837.6429,3520.5,3836.5,3516.5,3834.9,3520.5,3828.5,3526.9,3820.5,3524.9445,3817.5909,3528.5,3820.5,3529.2619,3828.5,3528.7051,3830.1,3528.5,3836.5,3522.1) polygon(3710.1,3520.5,3708.5,3518.9,3707.5,3520.5,3708.5,3521.6429) polygon(3514.5,3520.5,3508.5,3517.5,3504.5,3520.5,3508.5,3522.3461,3515.7727,3528.5,3516.5,3529.8333,3517.8333,3528.5,3516.5,3524.5) polygon(3823.4091,3512.5,3820.5,3507.1667,3817.5909,3512.5,3820.5,3516.0555) polygon(3807.4091,3512.5,3804.5,3509.8333,3801.3,3512.5,3804.5,3514.1842) polygon(3788.5,3512.5,3780.5,3504.5,3776.5,3512.5,3780.5,3514.1) polygon(3727.4091,3512.5,3724.5,3510.8158,3721.8333,3512.5,3724.5,3517.8333) polygon(3686.1,3512.5,3684.5,3504.5,3682.9,3512.5,3684.5,3515.1667) polygon(3645.9545,3512.5,3644.5,3511.0455,3640.5,3512.5,3644.5,3515.1667) polygon(3529.8333,3512.5,3524.5,3510.7222,3519.1667,3512.5,3524.5,3513.9545) polygon(3463.1667,3512.5,3468.5,3507.1667,3473.8333,3512.5,3468.5,3517.8333) polygon(3422.1,3512.5,3428.5,3507.1667,3433.0714,3512.5,3428.5,3515.1667) polygon(3372.5,3512.5,3372.5,3512.5,3372.5,3512.5,3372.5,3512.5) polygon(3339.1667,3512.5,3340.5,3511.3571,3348.5,3512.5,3356.5,3512.5,3356.5,3512.5,3356.5,3512.5,3348.5,3512.5,3340.5,3513.6429) polygon(3297.1667,3512.5,3300.5,3508.8636,3303.5769,3512.5,3300.5,3515.5769) polygon(3932.5,3504.5,3932.5,3504.5,3940.5,3502.7222,3942.7857,3504.5,3940.5,3506.7857,3932.5,3512.5,3932.5,3512.5,3932.5,3512.5) polygon(3565.8333,3504.5,3564.5,3502.9,3563.8846,3504.5,3564.5,3504.9211,3572.0789,3512.5,3572.5,3513.3,3573.3,3512.5,3572.5,3511.1667) polygon(3510.5,3504.5,3508.5,3501.8333,3506.5,3504.5,3508.5,3505.8333) polygon(3453.3889,3504.5,3460.5,3499.5769,3466.9,3504.5,3460.5,3510.9) polygon(3433.8333,3504.5,3436.5,3503.3571,3437.8333,3504.5,3436.5,3506.5) polygon(3409.3,3504.5,3412.5,3499.9286,3420.5,3504.5,3420.5,3504.5,3420.5,3504.5,3412.5,3507.7) polygon(3329.8333,3504.5,3332.5,3502.1,3335.1667,3504.5,3332.5,3507.5) polygon(4016.0555,3496.5,4020.5,3494,4024.9445,3496.5,4020.5,3503.1667) polygon(3968.0555,3496.5,3972.5,3492.5,3976.1364,3496.5,3972.5,3500.9445) polygon(3789.6429,3496.5,3788.5,3491.1667,3786.7222,3496.5,3788.5,3498.1) polygon(3494.7857,3496.5,3492.5,3493.3,3489.8333,3496.5,3485.5,3504.5,3492.5,3508.8077,3498.1,3504.5) polygon(3379.5,3496.5,3380.5,3495.6111,3384.5,3496.5,3380.5,3498.5) polygon(4002.3182,3488.5,4004.5,3485.8333,4007.5,3488.5,4004.5,3490.1) polygon(3733.6429,3488.5,3732.5,3484.5,3731.7,3488.5,3732.5,3489.3) polygon(3662.9,3488.5,3660.5,3486.7857,3657.8333,3488.5,3660.5,3491.9286) polygon(3530.2143,3488.5,3524.5,3482.7857,3520.8636,3488.5,3524.5,3493.5,3528.5,3496.5,3532.5,3499.1667,3540.5,3499.1667,3545.8333,3504.5,3540.5,3512.5,3548.5,3516.9445,3551,3512.5,3549.1154,3504.5,3548.5,3503.9667,3541.0333,3496.5,3548.5,3489.5,3551.1667,3488.5,3548.5,3480.5,3546.2143,3488.5,3540.5,3495.1667,3532.5,3491.7) polygon(3355.3571,3488.5,3356.5,3487.7727,3360.5,3488.5,3356.5,3489.8333) polygon(3921.3,3480.5,3924.5,3478.7222,3927.7,3480.5,3924.5,3482.5) polygon(3905.8333,3480.5,3908.5,3479.1667,3910.5,3480.5,3908.5,3482.5) polygon(3714.9,3480.5,3708.5,3474.1,3700.5,3472.5,3695.7,3480.5,3700.5,3485.8333,3705.3,3488.5,3700.5,3493.3,3692.5,3494.9,3690.5,3496.5,3692.5,3504.5,3700.5,3498.7857,3703.7,3496.5,3708.5,3491.7,3712.5,3496.5,3716.5,3499.1667,3720.5,3496.5,3716.5,3491.7,3712.5,3488.5) polygon(3408.5,3480.5,3412.5,3476.5,3415.1667,3480.5,3412.5,3484.5) polygon(3389.6429,3480.5,3396.5,3477.0714,3403.3571,3480.5,3396.5,3485.8333) polygon(3332.5,3480.5,3332.5,3480.5,3332.5,3480.5,3332.5,3488.5,3332.5,3488.5,3332.5,3488.5) polygon(3976.5,3472.5,3980.5,3470.1,3983.9286,3472.5,3980.5,3478.5) polygon(3932.5,3472.5,3932.5,3472.5,3932.5,3472.5,3932.5,3472.5) polygon(3916.5,3472.5,3916.5,3472.5,3916.5,3472.5,3916.5,3472.5) polygon(3900.5,3472.5,3900.5,3472.5,3900.5,3472.5,3900.5,3472.5) polygon(3873.8333,3472.5,3876.5,3470.9,3877.8333,3472.5,3884.5,3478.2143,3892.5,3475.1667,3898.5,3480.5,3892.5,3488.5,3892.5,3488.5,3886.5,3496.5,3892.5,3501.3,3895.1667,3496.5,3900.5,3491.7,3908.5,3492.5,3916.5,3495.3571,3917.6429,3496.5,3916.5,3498.1,3911.9286,3504.5,3908.5,3510.5,3900.5,3504.5,3894.7857,3512.5,3898.5,3520.5,3892.5,3523.7,3886.9615,3528.5,3884.5,3532.5,3879.9286,3528.5,3881.8333,3520.5,3884.5,3517.3,3889.3,3512.5,3884.5,3504.5,3884.5,3504.5,3876.5,3501.3,3873.5,3496.5,3876.5,3491.7,3884.5,3488.5,3876.5,3485.3,3873.5,3480.5) polygon(3598.1,3472.5,3596.5,3464.5,3592.5,3472.5,3596.5,3475.9286) polygon(3559.1667,3472.5,3556.5,3471.7727,3554.9,3472.5,3556.5,3480.5,3556.5,3480.5,3564.5,3483.1667,3565.2273,3480.5,3572.5,3473.2273,3572.8636,3472.5,3572.5,3471.9286,3569.8333,3472.5,3564.5,3477.8333) polygon(3425.8333,3472.5,3428.5,3470.2143,3436.5,3468.9445,3440.5,3472.5,3436.5,3477.0714,3431.7,3480.5,3436.5,3483.5,3441.5,3488.5,3436.5,3492.1364,3428.5,3496.5,3428.5,3496.5,3428.5,3496.5,3426.5,3488.5,3424.5,3480.5) polygon(3355.3571,3472.5,3356.5,3471.6111,3357.6429,3472.5,3356.5,3473.2273) polygon(3836.5,3464.5,3836.5,3464.5,3844.5,3464.5,3844.5,3464.5,3850.5,3472.5,3844.5,3477.3,3841.0714,3472.5,3836.5,3464.5) polygon(3500.5,3464.5,3500.5,3464.5,3500.5,3464.5,3500.5,3464.5) polygon(3388.5,3464.5,3388.5,3464.5,3388.5,3464.5,3388.5,3464.5) polygon(3932.5,3456.5,3932.5,3456.5,3932.5,3456.5,3932.5,3456.5) polygon(3722.9,3456.5,3724.5,3455.6111,3727.1667,3456.5,3724.5,3460.5) polygon(3372.5,3456.5,3372.5,3456.5,3380.5,3454.7222,3381.7308,3456.5,3380.5,3458.1,3372.5,3456.5) polygon(4019.7,3448.5,4020.5,3447.1667,4022.5,3448.5,4020.5,3449.5) polygon(3899.7,3448.5,3900.5,3446.9,3908.5,3448.5,3908.5,3448.5,3908.5,3448.5,3900.5,3449.6429) polygon(3867.3571,3448.5,3868.5,3445.8333,3870.1,3448.5,3868.5,3456.5,3868.5,3456.5,3868.5,3456.5) polygon(3416.5,3448.5,3420.5,3445.8333,3423.7,3448.5,3420.5,3453.8333) polygon(3398.6818,3448.5,3404.5,3443.1667,3410.9,3448.5,3404.5,3453.0714) polygon(3956.5,3440.5,3956.5,3440.5,3956.5,3440.5,3956.5,3440.5) polygon(3883.7,3440.5,3884.5,3436.5,3885.0714,3440.5,3884.5,3444.5) polygon(3839.7,3440.5,3844.5,3438.1,3848.5,3440.5,3844.5,3444.5) polygon(3711.7,3440.5,3716.5,3437.0714,3722.5,3440.5,3720.2333,3448.5,3716.5,3453.5909,3711.8333,3448.5) polygon(3664.5,3440.5,3668.5,3438.5,3671.1667,3440.5,3669.6429,3448.5,3668.5,3451.1667,3664.5,3448.5) polygon(3639.8333,3440.5,3644.5,3434.9,3651.5,3440.5,3644.5,3446.7222) polygon(3426.9,3440.5,3428.5,3439.1667,3430.1,3440.5,3428.5,3442.5) polygon(3384.5,3440.5,3388.5,3436.5,3392.5,3440.5,3388.5,3442.9615) polygon(3897.8333,3432.5,3900.5,3431.5,3901.5,3432.5,3900.5,3434.1) polygon(3803.5,3432.5,3804.5,3431.3571,3812.5,3428.0555,3820.5,3428.8636,3824.9445,3432.5,3820.5,3436.1364,3812.5,3438.2143,3804.5,3435.1667) polygon(3708.5,3432.5,3708.5,3432.5,3708.5,3432.5,3708.5,3432.5) polygon(3409.8333,3432.5,3412.5,3429.3,3414.1,3432.5,3412.5,3434.7857) polygon(3842.9,3424.5,3844.5,3422.9,3846.1,3424.5,3844.5,3425.5) polygon(3756.5,3424.5,3756.5,3424.5,3764.5,3420.5,3771.1667,3424.5,3764.5,3430.2143,3756.5,3424.5) polygon(3734.1,3424.5,3740.5,3418.1,3745.8333,3424.5,3740.5,3428.0555) polygon(3696.5,3424.5,3700.5,3421.8333,3705.8333,3424.5,3700.5,3426.7857) polygon(3849.0714,3416.5,3852.5,3413.8333,3857.3,3416.5,3852.5,3419.9286) polygon(3817.3,3416.5,3820.5,3414.2143,3821.9545,3416.5,3820.5,3418.5) polygon(3803.6111,3416.5,3804.5,3414.9,3806.5,3416.5,3804.5,3417.6429) polygon(3729.6429,3416.5,3732.5,3410.7857,3739.1667,3416.5,3732.5,3423.1667) polygon(3684.5,3416.5,3684.5,3416.5,3684.5,3416.5,3689.8333,3424.5,3690.9,3432.5,3684.5,3436.0555,3682.2143,3432.5,3676.5,3425.2273,3675.5,3424.5,3676.5,3420.5) polygon(3436.5,3416.5,3436.5,3416.5,3436.5,3416.5,3442.5,3424.5,3436.5,3426.5,3428.5,3426.7857,3425.3,3424.5,3428.5,3419.1667) polygon(3380.5,3416.5,3380.5,3416.5,3380.5,3416.5,3380.5,3416.5) polygon(3866.6539,3408.5,3868.5,3405.8333,3872.5,3408.5,3873.8333,3416.5,3868.5,3421.8333,3864.5,3416.5) polygon(3671.1667,3408.5,3676.5,3403.1667,3679.7,3408.5,3676.5,3413.8333) polygon(3650.5,3408.5,3652.5,3407.6111,3660.5,3406.7222,3665.8333,3408.5,3660.5,3412.5,3652.5,3416.5,3652.5,3416.5,3652.5,3416.5) polygon(3441.8333,3408.5,3444.5,3404.5,3449.8333,3408.5,3444.5,3412.5) polygon(3874.5,3400.5,3876.5,3399.0454,3878.7857,3400.5,3876.5,3403.7) polygon(3860.5,3400.5,3860.5,3400.5,3860.5,3400.5,3860.5,3400.5) polygon(3802.9,3400.5,3804.5,3396.5,3812.5,3398.9,3815.1667,3400.5,3813.8333,3408.5,3812.5,3410.5,3810.9,3408.5,3804.5,3402.1) polygon(3737.8333,3400.5,3740.5,3398.7222,3743.7,3400.5,3740.5,3404.5) polygon(3634.5,3400.5,3636.5,3399.8333,3638.1,3400.5,3636.5,3401.8333) polygon(3460.5,3400.5,3460.5,3400.5,3460.5,3400.5,3468.5,3403.7,3473.3,3408.5,3468.5,3416.5,3471.1667,3424.5,3476.5,3426.5,3484.5,3432.5,3484.5,3432.5,3488.5,3440.5,3491.7,3448.5,3490.5,3456.5,3486.5,3464.5,3484.5,3472.5,3492.5,3477.8333,3500.5,3473.8333,3507.1667,3480.5,3506.5,3488.5,3508.5,3491.1667,3509.6429,3488.5,3511.1667,3480.5,3508.5,3478.5,3502.5,3472.5,3508.5,3467.7,3512.5,3464.5,3508.5,3463.1667,3501.8333,3456.5,3500.5,3451.1667,3496.5,3448.5,3496.5,3440.5,3500.5,3432.5,3500.5,3432.5,3500.5,3432.5,3508.5,3436.1364,3512.9445,3432.5,3511.1667,3424.5,3516.5,3418.1,3519.1667,3416.5,3524.5,3413.8333,3532.5,3408.5,3532.5,3408.5,3540.5,3408.5,3540.5,3408.5,3547.0455,3416.5,3540.5,3421.6429,3538,3424.5,3532.5,3430.7857,3527.7,3432.5,3532.5,3435.9286,3537.8333,3440.5,3536.5,3448.5,3538.5,3456.5,3532.5,3459.1667,3524.5,3463.9667,3521.8333,3464.5,3522.5,3472.5,3524.5,3476.5,3532.5,3473.3889,3540.5,3480.5,3543.1667,3472.5,3540.5,3467.1667,3539.3571,3464.5,3540.5,3460.5,3543.1667,3456.5,3548.5,3451.1667,3553.8333,3456.5,3556.5,3457.2273,3558.1,3456.5,3564.5,3451.9286,3569.0714,3456.5,3572.5,3458,3580.5,3456.5,3572.5,3454.5,3566.5,3448.5,3564.5,3445.0714,3562.1,3448.5,3556.5,3455.5,3549.5,3448.5,3548.5,3447.7727,3541.8333,3440.5,3540.5,3438.2143,3535.5,3432.5,3540.5,3428.5,3548.5,3426.5,3552.5,3424.5,3556.5,3419.1667,3558.1,3416.5,3564.5,3411.9286,3568.5,3416.5,3572.5,3419.7,3579.3571,3424.5,3572.5,3431.3571,3570.9,3432.5,3572.5,3433.3,3577,3440.5,3580.5,3445.5909,3587.5,3440.5,3580.5,3432.5,3580.5,3432.5,3580.5,3432.5,3582.5,3424.5,3580.5,3422.9,3576.5,3416.5,3580.5,3410.1,3588.5,3414.2143,3593.5,3408.5,3596.5,3406.5,3604.5,3406.9,3609.8333,3400.5,3612.5,3398.7222,3614.2778,3400.5,3616.1364,3408.5,3612.5,3414.2143,3604.5,3411.1667,3599.1667,3416.5,3596.5,3417.6429,3591.1667,3424.5,3596.5,3430.5,3604.5,3426.1,3612.5,3424.5,3612.5,3424.5,3614.7857,3416.5,3620.5,3412.8636,3628.5,3411.7,3636.5,3413.5,3638.6818,3416.5,3636.5,3418.5,3628.5,3424.5,3632.5,3432.5,3629.8333,3440.5,3628.5,3441.6429,3626.5,3440.5,3620.5,3432.5,3615.7,3440.5,3620.5,3444.5,3623.1667,3448.5,3620.5,3451.1667,3613.6429,3456.5,3620.5,3460.8636,3623.8333,3464.5,3628.5,3470.1,3634.5,3472.5,3628.5,3475.9286,3622.1,3480.5,3628.5,3482.7857,3631.7,3480.5,3636.5,3473.6429,3642.5,3480.5,3644.5,3483.1667,3645.9545,3480.5,3645.1667,3472.5,3644.5,3471.7,3636.5,3469.8333,3634.7222,3464.5,3631.1667,3456.5,3636.5,3452.5,3644.5,3456.5,3652.5,3448.5,3652.5,3448.5,3652.5,3448.5,3660.5,3449.5,3666.7222,3456.5,3662.5,3464.5,3668.5,3467.9286,3672.0555,3472.5,3676.5,3480.5,3679.3571,3472.5,3676.5,3469.6429,3670.5,3464.5,3670.7857,3456.5,3676.5,3452.8636,3683.1667,3456.5,3684.5,3457.3,3688.5,3456.5,3692.5,3454.9,3700.5,3453.8333,3708.5,3455.1667,3710.1,3456.5,3712.5,3464.5,3716.5,3467.1667,3724.5,3468.5,3726.5,3464.5,3732.5,3459.7,3740.5,3458.7857,3743.5769,3464.5,3748.5,3469.8333,3754.9,3464.5,3748.5,3459.1667,3743.1667,3456.5,3748.5,3450.1,3756.5,3448.5,3748.5,3447.1667,3745.8333,3448.5,3740.5,3452.5,3732.5,3448.5,3732.5,3448.5,3726.5,3440.5,3729.8333,3432.5,3732.5,3427.1667,3734.7857,3432.5,3740.5,3440.5,3745.5,3432.5,3748.5,3427.7,3750.9,3432.5,3756.5,3438.1,3764.5,3437.8333,3772.5,3433.8333,3775.1667,3432.5,3780.5,3430.2143,3788.5,3424.5,3788.5,3424.5,3788.5,3424.5,3792.5,3432.5,3788.5,3436.5,3782.2778,3440.5,3788.5,3448.5,3788.5,3448.5,3790.9,3456.5,3788.5,3461.3,3780.5,3463.7727,3774.3461,3456.5,3772.5,3452.5,3768.5,3456.5,3772.5,3464.5,3772.5,3464.5,3772.5,3472.5,3772.5,3472.5,3769.3,3480.5,3764.5,3483.5,3757.8333,3488.5,3756.5,3491.1667,3753.8333,3488.5,3748.5,3483.1667,3746.5,3488.5,3748.5,3493.8333,3751.1667,3496.5,3755.1667,3504.5,3756.5,3507.1667,3764.5,3506.5,3765.5,3504.5,3767.1667,3496.5,3766.853,3488.5,3772.5,3481.6429,3775.1667,3480.5,3780.5,3474.1,3788.5,3472.5,3788.5,3472.5,3788.5,3472.5,3796.5,3480.5,3804.5,3472.5,3796.5,3468.5,3792.5,3464.5,3796.5,3462.7222,3804.5,3458.7857,3812.5,3458.1,3814.1,3456.5,3820.5,3453.5909,3825.5909,3448.5,3828.5,3445.5909,3833.0714,3448.5,3828.5,3456.5,3828.5,3456.5,3824.5,3464.5,3820.5,3470.9,3812.5,3468.0555,3804.5,3472.5,3810.5,3480.5,3812.5,3481.9545,3819.7,3488.5,3820.5,3496.5,3828.5,3491.9286,3831.7,3496.5,3836.5,3502.5,3841.8333,3504.5,3844.5,3512.5,3846.5,3504.5,3844.5,3502.5,3841.8333,3496.5,3844.5,3493.8333,3852.5,3489.3889,3853.6429,3488.5,3856.5,3480.5,3860.5,3476.5,3861.8333,3480.5,3868.5,3488.5,3868.5,3488.5,3868.5,3488.5,3863.5,3496.5,3868.5,3500.1364,3874.5,3504.5,3876.5,3507.1667,3881.0714,3512.5,3876.5,3516.5,3871.1667,3520.5,3868.5,3522.7857,3864.5,3520.5,3864.1364,3512.5,3860.5,3504.5,3856.0555,3512.5,3855.1667,3520.5,3860.5,3522.5,3864.8636,3528.5,3867.3571,3536.5,3868.5,3538.1,3876.5,3540.1364,3884.5,3541.8333,3888.5,3536.5,3892.5,3534.0385,3897.6429,3528.5,3900.5,3522.7857,3908.5,3520.5,3908.5,3520.5,3908.5,3520.5,3916.5,3524.5,3924.5,3525.8333,3932.5,3522.1,3940.5,3527.5,3948.5,3525.1667,3951.8333,3528.5,3948.5,3532.9445,3940.5,3530.1,3936.5,3536.5,3932.5,3544.5,3940.5,3546.1,3945.8333,3552.5,3940.5,3557.8333,3935.1667,3560.5,3940.5,3562.2778,3948.5,3566.9,3956.5,3565.5,3959.9286,3568.5,3964.5,3573.0714,3970.9,3568.5,3972.5,3566.5,3975.9286,3560.5,3980.5,3554.1,3983.7,3560.5,3986.2143,3568.5,3980.5,3572.9445,3975.1667,3576.5,3972.5,3579.7,3967.7,3584.5,3972.5,3589.3,3977.3,3584.5,3980.5,3581.8333,3982.7857,3584.5,3988.5,3587.3571,3994.5,3592.5,3992.5,3600.5,3988.5,3603.7,3986.9,3600.5,3980.5,3595.9286,3973.3889,3600.5,3980.5,3605.8333,3985.0714,3608.5,3984.5,3616.5,3988.5,3620.1364,3996.5,3618.9615,4002.5,3624.5,4002.1,3632.5,4004.5,3636.5,4007.9286,3640.5,4012.5,3644.0555,4020.5,3645.8333,4028.5,3640.5,4028.5,3640.5,4028.5,3640.5,4036.5,3645.3,4038.9615,3648.5,4042.2142,3656.5,4036.5,3662.2143,4028.5,3664.5,4036.5,3669.8333,4038.1,3664.5,4044.5,3658.1,4048.2646,3664.5,4048.5,3672.5,4044.5,3675.5,4038.7858,3680.5,4044.5,3686.2143,4051.1666,3680.5,4052.5,3678.5,4056.5,3680.5,4055.7,3688.5,4055.4091,3696.5,4058.5,3704.5,4060.5,3705.6429,4068.5,3708.5,4071.1666,3704.5,4068.5,3696.5,4068.5,3696.5,4065.3,3688.5,4068.5,3686.9,4070.7858,3688.5,4076.5,3695.1667,4077.2273,3696.5,4079.4091,3704.5,4078.9,3712.5,4078.7858,3720.5,4081.2059,3728.5,4084.5,3733.5909,4090.9,3736.5,4084.5,3741.0714,4078.5,3744.5,4084.5,3746.6818,4092.5,3752.5,4092.5,3752.5,4098.9,3760.5,4095.1666,3768.5,4100.5,3773.0714,4106.5,3776.5,4108.5,3779.1667,4116.5,3777.3,4123.7,3784.5,4116.5,3791.0455,4108.5,3788.0555,4103.5,3792.5,4108.5,3796.9445,4113.0714,3800.5,4113.0714,3808.5,4116.5,3813.3,4118.2778,3816.5,4120.5,3824.5,4124.5,3828.8077,4130.5,3832.5,4132.5,3840.5,4136.5,3832.5,4139.3572,3824.5,4140.5,3816.5,4140.5,3816.5,4140.5,3816.5,4148.5,3821.5,4154.5,3824.5,4148.5,3829.3,4144.5,3832.5,4148.5,3837.8333,4149.6428,3840.5,4156.5,3848.5,4156.5,3848.5,4156.5,3848.5,4148.5,3851.1667,4146.5,3848.5,4140.5,3844.5,4132.5,3848.5,4132.5,3848.5,4130.2142,3856.5,4132.5,3861.8333,4136.5,3856.5,4140.5,3851.9286,4145.8334,3856.5,4143.1666,3864.5,4148.5,3870.2143,4152.5,3872.5,4148.5,3876.0555,4140.5,3876.9445,4136.5,3880.5,4134.7858,3888.5,4132.5,3891.1667,4124.5,3888.5,4122.5,3896.5,4124.5,3898.1,4132.5,3902.9,4140.5,3902.9,4144.5,3896.5,4148.5,3888.5,4148.5,3888.5,4148.5,3888.5,4153.0714,3896.5,4153.5,3904.5,4148.5,3908.5,4140.5,3912.5,4144.5,3920.5,4140.5,3925.3,4134.5,3920.5,4132.5,3919.8333,4131.1666,3920.5,4132.5,3921.3,4139.0454,3928.5,4132.5,3935.7,4131.7,3936.5,4132.5,3938.5,4140.5,3940.5,4142.5,3944.5,4141.6428,3952.5,4140.5,3953.2273,4132.5,3957.8333,4127.1666,3952.5,4124.5,3951.3571,4121.8334,3952.5,4116.5,3958.9,4112.5,3960.5,4116.5,3961.8334,4121.5,3968.5,4117.8334,3976.5,4124.5,3984.5,4124.5,3984.5,4127.7,3992.5,4124.5,3995.1666,4122.2142,3992.5,4116.5,3988.0555,4109.8334,3992.5,4114.2142,4000.5,4108.5,4007.1666,4107.1666,4008.5,4100.5,4012.9445,4097.8334,4016.5,4100.5,4022.9,4101.3,4024.5,4108.5,4031.0454,4116.5,4028.5,4122.9,4032.5,4116.5,4037.0714,4108.5,4034.2778,4100.5,4034.1,4092.5,4038.7222,4089.3,4040.5,4084.5,4044.5,4080.5,4040.5,4076.5,4036.5,4074.5,4040.5,4076.5,4042.9,4082.1,4048.5,4076.5,4052.8077,4068.5,4051.1666,4063.9286,4056.5,4060.5,4060.5,4052.5,4064.5,4060.5,4066.9,4064.5,4072.5,4060.5,4078.1,4052.5,4074.9,4044.5,4075.5,4039.7,4072.5,4036.5,4068.5,4028.5,4070.9,4020.5,4064.5,4012.5,4072.5,4012.5,4080.5,4012.5,4080.5,4012.5,4080.5,4004.5,4077.0714,3996.5,4078.1,3988.5,4077.6765,3984.1364,4080.5,3988.5,4088.5,3988.5,4088.5,3988.5,4088.5,3984.5,4096.5,3980.5,4097.2273,3976.5,4096.5,3972.5,4095.7727,3965.2273,4088.5,3972.5,4083.5,3976.8636,4080.5,3972.5,4077.0714,3965.3889,4072.5,3972.5,4066.1,3974.1,4064.5,3972.5,4063.6578,3971.8333,4064.5,3964.5,4072.1522,3964.4838,4072.5,3964.5,4074.1,3967.7,4080.5,3964.5,4086.9,3963.7727,4088.5,3964.5,4096.5,3964.5,4096.5,3964.5,4096.5,3959.9286,4104.5,3956.5,4106.9,3952.5,4104.5,3951.7,4096.5,3952.2895,4088.5,3948.5,4083.3572,3940.5,4087.1666,3936.5,4088.5,3940.5,4093.3,3943.1667,4096.5,3940.5,4098.7858,3932.5,4100.5,3926.7857,4096.5,3926.5,4088.5,3924.5,4080.5,3924.5,4080.5,3916.5,4078.5,3913.0714,4080.5,3916.5,4085.3,3921.8333,4088.5,3916.5,4090.1,3909.3889,4096.5,3908.5,4098.5,3900.5,4096.5,3900.5,4096.5,3900.5,4096.5,3902.1,4088.5,3900.5,4086.5,3896.5,4088.5,3892.5,4089.3,3891.5,4088.5,3884.5,4083.4091,3876.5,4084.1364,3868.5,4083.1666,3865.5,4080.5,3860.5,4076.0555,3852.5,4077.8334,3849.5,4080.5,3844.5,4083.8334,3840.5,4080.5,3836.5,4075.5,3828.5,4075.9286,3825.8333,4072.5,3822.2143,4064.5,3820.5,4061.0714,3816.5,4064.5,3814.5,4072.5,3812.5,4074.1,3811.1667,4072.5,3808.5,4064.5,3804.5,4061.8334,3798.5,4056.5,3796.5,4053.3,3788.5,4053.6765,3780.5,4053.8334,3772.5,4052.5,3767.1667,4048.5,3764.5,4047.5,3756.5,4046.5,3751.1667,4040.5,3748.5,4034.5,3746.5,4032.5,3740.5,4029.8334,3732.5,4026.7858,3724.5,4031.3572,3719.7,4024.5,3716.5,4019.1666,3711.1667,4016.5,3708.5,4015.3572,3701.6429,4008.5,3700.5,4007.5,3692.5,4000.5,3684.5,4005.8334,3681.8333,4000.5,3676.5,3992.5,3676.5,3992.5,3670.5,3984.5,3676.5,3978.5,3680.5,3984.5,3684.5,3992.5,3692.5,3985.5667,3700.5,3987.5,3703.5,3984.5,3700.5,3982.6538,3692.5,3983.1666,3684.5,3981.5,3677.8333,3976.5,3676.5,3974.9,3668.5,3975.5,3666.9,3976.5,3666.9,3984.5,3660.5,3988.5,3658.2143,3992.5,3652.5,3998.6538,3645.8333,3992.5,3644.5,3988.5,3642.7222,3984.5,3639.7,3976.5,3640.5,3968.5,3644.5,3964.5,3646.1,3960.5,3644.5,3952.5,3644.5,3952.5,3636.5,3948.5,3632.5,3952.5,3628.5,3955.1667,3622.5,3952.5,3620.5,3951.5,3612.5,3952.5,3612.5,3952.5,3604.5,3954.7857,3600.5,3952.5,3596.5,3949.8333,3593.5909,3944.5,3588.5,3938.2778,3585.3,3936.5,3588.5,3934.7222,3593.1667,3928.5,3596.5,3920.5,3588.5,3917.5,3587,3920.5,3582.2778,3928.5,3580.5,3931.7,3578.2143,3928.5,3572.5,3922.7857,3565.8333,3928.5,3564.5,3929.5,3563.6111,3928.5,3560.5,3920.5,3564.5,3916.5,3572.5,3912.5,3572.5,3912.5,3574.1,3904.5,3580.5,3898.1,3581.3889,3896.5,3580.5,3895.3571,3574.5,3888.5,3572.5,3887.1667,3567.1667,3888.5,3564.5,3891.1667,3560.5,3888.5,3556.5,3887.9286,3550.3823,3880.5,3549.8333,3872.5,3556.5,3865.2273,3564.119,3872.5,3564.5,3876.5,3565.3,3872.5,3564.5,3868.5,3561.8333,3864.5,3556.5,3859.1667,3551.1667,3864.5,3548.5,3866.1,3544.5,3872.5,3542.1,3880.5,3540.5,3883.1667,3532.5,3887.3571,3525.6429,3880.5,3524.5,3872.5,3524.5,3872.5,3524.5,3864.5,3524.5,3864.5,3532.5,3859.9286,3540.5,3856.5,3532.5,3852.5,3524.5,3848.5,3524.5,3848.5,3516.5,3845.8333,3508.5,3840.5,3508.5,3840.5,3508.5,3840.5,3511.7,3832.5,3516.5,3827.7,3521.8333,3832.5,3524.5,3835.9286,3529.0714,3840.5,3532.5,3844.5,3540.5,3848.5,3540.5,3848.5,3548.5,3849.8333,3549.2273,3848.5,3548.5,3846.5,3545.0714,3840.5,3540.5,3835.9286,3532.5,3836.5,3528.5,3832.5,3524.5,3829.5,3520.0555,3824.5,3524.5,3816.5,3516.5,3810.5,3514.5,3808.5,3508.5,3803.7,3503.1667,3800.5,3500.5,3797.8333,3498.2143,3792.5,3496.7667,3784.5,3492.5,3777.3889,3484.5,3780.5,3480.5,3776.5,3478.5,3768.5,3484.5,3764.5,3487.5,3760.5,3489.3,3752.5,3484.5,3745.6429,3481.8333,3744.5,3476.5,3742.5,3473.0714,3736.5,3468.5,3730.1,3460.5,3736.5,3460.5,3736.5,3454.1,3744.5,3452.5,3745.6429,3444.5,3744.5,3436.5,3750.9,3430.6818,3744.5,3436.5,3738.6818,3444.5,3736.5,3439.7,3728.5,3442.9,3720.5,3440.8636,3712.5,3436.5,3704.5,3428.5,3707.5,3423.7,3704.5,3428.5,3698.5,3436.5,3704.5,3439.4091,3696.5,3444.5,3689.5,3448.5,3696.5,3446.5,3704.5,3452.5,3707.5,3460.5,3707.1667,3468.5,3704.5,3460.5,3702.9,3456.2333,3696.5,3460.5,3690.1,3462.5,3688.5,3460.5,3685.3,3456.5,3680.5,3452.5,3675.7,3449.3,3672.5,3446.5,3664.5,3449.8333,3656.5,3452.5,3654.5,3460.5,3653.3,3463.5,3648.5,3468.5,3642.7857,3475.1667,3648.5,3476.5,3652.5,3477.6429,3648.5,3478.7857,3640.5,3476.5,3637.8333,3468.5,3637.8333,3465.8333,3632.5,3460.5,3626.6818,3454.5,3624.5,3460.5,3620.5,3465.3,3616.5,3460.5,3610.5,3457.8333,3608.5,3455.1667,3600.5,3460.5,3596.5,3464.5,3600.5,3468.5,3605.8333,3473.8333,3600.5,3473.3,3592.5,3470.3462,3584.5,3468.5,3576.5,3462.5,3584.5,3460.5,3586.1,3452.5,3584.5,3447.8333,3592.5,3449.8333,3600.5,3449.3,3608.5,3444.5,3612.5,3438.5,3608.5,3439.9286,3600.5,3438.7857,3592.5,3440.5,3584.5,3444.5,3579.7,3452.5,3584.5,3457.0714,3576.5,3452.5,3572.9445,3447.5,3568.5,3444.5,3563.7,3442.2143,3560.5,3443.1667,3552.5,3444.5,3548.5,3446.1,3544.5,3444.5,3540.5,3443.3571,3536.5,3444.5,3533.8333,3452.5,3530.7857,3456.5,3528.5,3452.5,3526.5,3444.5,3524.5,3436.5,3520.5,3436.5,3520.5,3436.5,3520.5,3444.5,3518.5,3449.8333,3512.5,3452.5,3506.5,3457.3,3512.5,3460.5,3515.1667,3465.8333,3520.5,3468.5,3528.5,3468.5,3528.5,3473.3,3536.5,3476.5,3539.7,3484.5,3541.8333,3491.6111,3536.5,3484.5,3532.7353,3479.3571,3528.5,3476.5,3522.7857,3472.5,3520.5,3476.5,3516.5,3479.7,3512.5,3476.5,3509.8333,3471.1667,3504.5,3469.2273,3496.5,3468.5,3492.5,3460.5,3488.5,3460.5,3488.5,3459.6111,3480.5,3460.5,3477.8333,3468.5,3479.5,3472.5,3480.5,3476.5,3483.1667,3477.3,3480.5,3476.5,3478.5,3474.1,3472.5,3468.5,3465.5,3460.5,3469.8333,3457.8333,3472.5,3452.5,3475.1667,3448.5,3472.5,3452.5,3464.5,3447.1667,3456.5,3444.5,3455.3571,3439.1667,3448.5,3444.5,3444.1364,3448.5,3440.5,3452.5,3432.5,3445.8333,3424.5,3446.7857,3416.5,3452.5,3409.8333,3459.1667,3416.5,3456.9445,3424.5,3452.5,3432.5,3460.5,3437.3,3462.2778,3440.5,3464.5,3448.5,3460.5,3453.8333,3457.8333,3456.5,3460.5,3458.1,3468.5,3456.5,3468.5,3456.5,3476.5,3450.5,3477.3,3448.5,3476.5,3444.5,3475.5,3440.5,3468.5,3432.5,3468.5,3432.5,3466.9,3424.5,3468.5,3416.5,3460.5,3412.5,3456.5,3408.5) polygon(3828.5,3392.5,3828.5,3392.5,3828.5,3392.5,3832.1364,3400.5,3828.5,3404.5,3822.7857,3400.5) polygon(3583.1667,3392.5,3588.5,3388.2333,3593.8333,3392.5,3588.5,3399.6111) polygon(3556.5,3392.5,3556.5,3392.5,3556.5,3392.5,3564.5,3395.7,3572.5,3395.1667,3576.5,3400.5,3572.5,3406.5,3564.5,3404.5,3560.5,3408.5,3556.5,3414.5,3553.0714,3408.5,3556.5,3400.5) polygon(3812.5,3384.5,3812.5,3384.5,3812.5,3384.5,3812.5,3384.5) polygon(3732.5,3384.5,3732.5,3384.5,3732.5,3384.5,3732.5,3384.5) polygon(3643.6111,3384.5,3644.5,3381.8333,3646.1,3384.5,3644.5,3392.5,3644.5,3392.5,3644.5,3392.5) polygon(3779.3571,3376.5,3780.5,3373.8333,3784.5,3376.5,3780.5,3377.2273) polygon(3745.8333,3376.5,3748.5,3373.3,3750.7857,3376.5,3748.5,3378.5) polygon(3668.5,3376.5,3668.5,3376.5,3668.5,3376.5,3668.5,3376.5) polygon(3521.8333,3376.5,3524.5,3374.5,3529.8333,3376.5,3524.5,3380.5) polygon(3474.7222,3376.5,3476.5,3374.2143,3481.8333,3376.5,3478.5,3384.5,3484.5,3389.3,3486.7857,3392.5,3492.5,3397.5,3496.5,3400.5,3500.5,3406.5,3506.5,3400.5,3508.5,3399.7727,3516.5,3397.8333,3524.5,3395.1667,3529.8333,3400.5,3524.5,3404.5,3520.5,3408.5,3516.5,3414.9,3514.9,3416.5,3508.5,3421.8333,3500.5,3420.2333,3495.1667,3424.5,3492.5,3430.9,3489.3,3424.5,3485.9546,3416.5,3489.8333,3408.5,3484.5,3406.7222,3478.2778,3400.5,3476.5,3398.5,3472.1364,3392.5,3468.5,3384.5,3468.5,3384.5,3468.5,3384.5) polygon(3419.7727,3376.5,3420.5,3374.5,3421.3889,3376.5,3420.5,3380.5) polygon(3836.5,3368.5,3836.5,3368.5,3836.5,3368.5,3836.5,3368.5) polygon(3732.5,3368.5,3732.5,3368.5,3740.5,3366.7222,3743.7,3368.5,3740.5,3371.1667,3732.5,3368.5) polygon(3698.2143,3368.5,3700.5,3365.3,3702.1,3368.5,3708.5,3374.9,3710.5,3376.5,3708.5,3379.1667,3702.1,3384.5,3708.5,3389.8333,3710.2778,3392.5,3716.5,3397.5909,3722.9,3400.5,3716.5,3406.9,3708.5,3408.5,3708.5,3408.5,3700.5,3411.1667,3697.3,3408.5,3694.5,3400.5,3700.5,3392.5,3698.9,3384.5,3692.5,3379.1667,3690.2143,3376.5,3692.5,3374.2143) polygon(3683.8846,3368.5,3684.5,3367.3571,3685.8333,3368.5,3684.5,3369.8333) polygon(3612.5,3368.5,3612.5,3368.5,3612.5,3368.5,3612.5,3368.5) polygon(3576.9445,3368.5,3580.5,3365.8333,3582.6334,3368.5,3580.5,3376.5,3580.5,3376.5,3572.5,3378.6818,3569.0714,3376.5,3572.5,3373.5) polygon(3642.5,3360.5,3644.5,3358.5,3646.1,3360.5,3644.5,3364.5) polygon(3596.5,3360.5,3596.5,3360.5,3596.5,3360.5,3596.5,3360.5) polygon(3536.0555,3360.5,3540.5,3355.5,3548.5,3358.5,3549.3889,3360.5,3549.3,3368.5,3548.5,3370.1,3546.9762,3376.5,3540.5,3381.3571,3532.9445,3376.5,3535.5,3368.5) polygon(3467.3571,3360.5,3468.5,3356.5,3476.5,3357.8333,3479.7,3360.5,3476.5,3362.7857,3469.8333,3368.5,3468.5,3369.5,3467.3571,3368.5) polygon(3443.9286,3360.5,3444.5,3359.9286,3446.1,3360.5,3444.5,3368.5,3444.5,3368.5,3444.5,3368.5) polygon(3705.3,3352.5,3708.5,3349.3,3711.7,3352.5,3708.5,3356.5) polygon(3579.5,3352.5,3580.5,3351.5,3581.8333,3352.5,3580.5,3353.3889) polygon(3516.5,3352.5,3516.5,3352.5,3524.5,3350.7222,3527.1667,3352.5,3524.5,3355.7,3516.5,3352.5) polygon(3498.9,3352.5,3500.5,3351.5,3501.6429,3352.5,3502.2778,3360.5,3508.5,3367.5,3509.5,3368.5,3508.5,3369.5,3500.5,3371.1667,3499.1667,3368.5,3498.9,3360.5) polygon(3751.7,3344.5,3756.5,3340.1364,3760.1923,3344.5,3756.5,3349.8333) polygon(3481.4231,3344.5,3484.5,3341.4231,3488.5,3344.5,3484.5,3348.1364) polygon(3732.5,3336.5,3732.5,3336.5,3732.5,3336.5,3732.5,3336.5) polygon(3664.5,3336.5,3668.5,3334.6538,3672.5,3336.5,3668.5,3338.5) polygon(3820.5,3328.5,3820.5,3328.5,3820.5,3328.5,3820.5,3328.5) polygon(3524.5,3328.5,3524.5,3328.5,3524.5,3328.5,3524.5,3328.5) polygon(3554.7222,3320.5,3556.5,3318.5,3558.5,3320.5,3556.5,3322.2778) polygon(3948.5,3312.5,3948.5,3312.5,3948.5,3312.5,3948.5,3312.5) polygon(3684.5,3312.5,3684.5,3312.5,3684.5,3312.5,3684.5,3312.5) polygon(3587.8846,3312.5,3588.5,3311.8333,3589.3889,3312.5,3588.5,3314.5) polygon(3884.5,3304.5,3884.5,3304.5,3884.5,3304.5,3884.5,3304.5) polygon(3663.1667,3296.5,3668.5,3294.7222,3669.8333,3296.5,3668.5,3298.2778) polygon(3528.5,3296.5,3532.5,3295.1667,3533.1154,3296.5,3532.5,3297.1667) polygon(3700.5,3288.5,3700.5,3288.5,3700.5,3288.5,3700.5,3288.5) polygon(3609.4231,3280.5,3612.5,3277.1667,3615.5769,3280.5,3612.5,3283.3571) polygon(3577.8333,3280.5,3580.5,3278.1,3583.9286,3280.5,3580.5,3283.9286) polygon(3982.1,3128.5,3988.5,3126.2143,3992.0555,3128.5,3988.5,3132.0556) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/dsscontour.png������������������������������������������������������������0000644�0001750�0001750�00000716364�11332353405�017250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��h�� ���8R]U���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ¼P3�� �IDATxÚì½y¸e6üÔ^]KïgÍÉ $$$dS”AÀåÅË×wfœqAG”]À nƒã8Î0"EªÑ×ñE¯a>DpX”°'Bö䬽WwUWU×òýq›òpNŸ>KÎIN’ç¾¼¼BŸ®í©î¾ëþ-÷ òú¢¿"ãcãý˜ƒ5?ø±+èŠPPPPPP´Àê‹þjãý˜Yõž|ðcW  º"-зgûÞ-ÏñøÇ®Ó¡     ˜”8)(((()ª•¢cN!Ì)©q=‘>¼Û6!N×±G¾:°õ™ù &‘Hxž·Ëӽ˚îÔ* *Æ›{Jo{7ý(PPPPPLǶÓX~ÒI“ßdËÖ­„IV׶͉“0ÌÈWÛ¯¶^¸ìƒ—r÷‹‡¹£’S’í£¶l8õŠÙW"KVÚœ‚‚‚‚‚¢9qZÕåË—Oi“åË—oÙºUŠ©‡kÛæÄɼ•ùI¶’‹ôãÏ9ëÌeK—ìúÍï|5Á‹òÈ÷°…×}M0•Þ´–  ŠÉ€afêZ‹C¿íxÄÉŽúƒšêèßî¹mmÙÅÇÍ{aÛ³+ÞEÈ·¯ì}å¤Îø†íÅž“N¡Ÿà/Þ³êç­ü͆×~ðÈèjPPPPŒCEì´Œ=ð¿Ã°í¤'жpÅ›¯üÎ0v°,›àœÜŽ—ÚF©æöŸ"xuGïéOxÝÙÄGß{æâÞvçÊÕú¾¡â÷~ñû’a8.ùÖ ÿ'›Ô!ûÿ¯?WŽ6<miïûÎYÑÛ•æXv°`üîù7~³áµ0$„o¯ù‹T\¹û¡'ŸyyÇú4†bE£0˜Èv5}Ï‚ÎôG.>cñü¶ 7oïÿá£ÏFKAAAAqŒ0'CE“”~£¶ýÆÕ—Ž÷ö[¾ûóÉlû–·5}±…â/IÙµâÜ}ÏýB&!$*%%®¤:Îþ­{sÝ'¿‡a¹ ¯tÍÇÞÓ–Òs¥ýƒ¹TB;eqOX/ûËq!äÄ`MBÈ) {†xA&„¼çíË>vÉ™„{ê¶sÒ¢Þ½÷íÝmý£#Õ[î«›•˜–œ;Ì „„„ÍžE4Eºå“—¨1ñ×O=Ïð¢óVµ'•/Þó B8úU¢  8fxsš!S2•pë›/?»ämgM¸í7®¾ô wýÿþ§«þ×xÛŽ§8›ó?ÇK'ÿYîÅGް,SØñ<ÛÖÞðëÊ‚ÕbL›ðÔ3 µ-¥9nãkþ9dX^âªdš¦’žÇó!äœSB¶ïî[tܼ Î>õ§¿Ù gºµ˜ôv:!ä‡ÿùØþó1^”Ï:uÙ­×þõg®xôwsõ?jÿ÷«—BÖ?òìÎ;Y…Ÿ?ùÊ®þÂßü¯³2 uÖÝ÷ÿü÷AB>÷ç/šß®+’ëù;öç~ôë}ÃeBÈâÞö¿ùÀYm)í•íýF­þ®UK~ûÜ?|t!¤=¥ä¢UËŽëxîÍ}¹ýê¹ýÃåQxâ‚öO}à¬lò›T÷uÑê³W.Ô¹î4úråïüôwKz;Ô˜¸o ÷¯÷ü¿˜–8uùâÞî¶²òŽ‚ÇZ]EAAqŒçL†[?ü™[ƾù?îý¡^šnûÅuýÊ€/£G;µíxÄ9îe(ñ´zÜjgïs–㇜¬°nŽíìéèÌ¥Ö,Çv²(üãŸzs òæÞá7v*rŠã8BçV/_@Y÷ㇿzý':²©Eó2Cõpé‚NQàÃ0ü_?©¥Ú´dÛ¶Áú@®ÜÕ–<ù„î_mÜ1–e>øŽ;û†O[¶ð#ï9½f9Ûö ¦ôع§œðìó›_Ý[! “MiOn|%W,¿méÂÓ–/¾öÃç®YûP<®ßð‘wi1é•7v™FõüÕ'BÌJ¾œïïš·à Ÿ¼(WžÜ´¥P,]úggßü± nþ·‡ÿOÇŽIÂõù.5&mÞ¶Û6kçŸþ§z­“u_röI{úsýêIU‘ÞvÒ"³8àt$ !™¤ÞÓÝ‘í^˜ÐUBÈ¢ù›woUõ¥N ŠcFq²ÓÚŠiºíÒÓÎk[oû¥»ùW¼2Š5GîpjÅA#XÅ $N(ߦ‰¢(ø“½ì†ÞýO}ô’ÓW¯<qõJB*TÖ>ø?yƒ0ÌÛNìQe±lÔ^~mÇ ¯íyÇéKßýöSÖÿr£®È„ÛqMËéh;ŽeyNàʦÝÕFqÕ¶ªcô­þã/½þýYÓÓ™ýÕï6Ü÷“G×\þwÚüöø³›wk‰ì×ø¯};6kšþøÆ×ðO't·§‰]8åô¥ZLÊ—*7~}/Êšªž¶üÙ·-éIÇ•Ýû‡Ö>ðS1¦õÎë:}ù '÷&6n/±¼€ƒž²¸GI…²qÃ?ÞÅ Ò7Ö|òÔeÇãO’ Bª5³o¸8T¶~ü«?8uËe÷¼¹wpqoçn»‰‚|mL–ŽEôÔ4>IG s²„e¦±ðͷooÑëãoû¥{ýÇϼ÷-¬¹ê¼&ÇmJœ-1í^qg#Ö-×uÇ!n¾šŸ§·ÍŸÌž´}à‰¯ÜÓ•–/îýß¿£»#sÉê…÷>ü/ÆÎ>y!!ä/leXîùm}ï8}é;Ï8徇ž¨ÖBˆ,‰ªc8–å8Â0)]%„Tªfàû$}”{ûÙ.Û !oîÞÓ“+Bw:Ç3Ÿxß§ø!5&E›ˆ£Ê<!dÿ@Ž0\ºkÁPåO±ÖtB!„×ÓñŸë¾½Ø™MVŸßÏv"²šÐBȾþa²™îãŠÖ©ÞùÊŽýÏoÝuÚ²ãV,9Ž2\4þå–ê__ÿ_'u*Ýí©áÂÙ§/?çôe£A@BŽöÂRPP+Šs&sœãímD¸uÜm¿vù%Ñ¿ÿãÞo|ù¾_5=î8Šsƶ«¥êŽg-Ÿ?þô ëF¡øêoXâBÊo<)é—JŠÞúRž[q|× Ä/™µ§¶ôgÚ^ÿ«÷ž£©ri¸oÁâe§,žG¹äü3.9ÿ ¼_UäS—Ì{}W¿ÛðDÿÐ…çüæÅ}¬Ä®\ÔÝ™Ñ !›^yƒãš”Òø¾ÏKÅó}A’Ù…Kaœ³ráyo;¡¸øu?6­úí_¸‚eY†aŠ•!d^g›(Ë„a{;³ÑKF²·è;?üYôb±\õ½F,ÇB Ó&„´¥“¼ 1„íÈü©Ÿµáßzð ·2ÔMüù{ßyÎéËÏ8±ëá?ìä8iÓ›CÞ–=š"^õ±B^زáÂŒ{ ((((Ž:âœV¨–mªooo Õ6Ûö>}Q¤5‘ýÚå—|åþÿ{Üqˆ³Ù¯aîüa˜î·½G¡Mñ—œWßùŒ$‰‚ Ôv<+|aëëþºÿsžiŸ¹¸†dqO–òòk;ÂÀ_}â|žc­ºýâÖ?¶”7¯c^göÏÎ9í[ÿþÛŸþöù^ræe¾è¼3‡|Â.êÉB{jÓk;öfº6O2숛·<#à$}ßñü W³ìÏù¥7öVM»-¸ýæOÕ=²laG´É oì+Vj½Ýï{×Y}…Z*®ž²¤÷¾‡ž¨í"áw¸y× Ywæuf¯ýë÷¹Œtê’žhó't_zÞÊ×vî¯ÛnOW!¤bÔŒÒÐ?}þ²rÕ2ëΪe½jLzjã«¯ïØ›é^ÈNë“DAAAqç[Št¾ú7ïïÿÀcoݪy/æ$g“m£ã"Bû÷<†WþáÓ=îxÄÙäÀõý/euq8~jü@Wbzþ’œUìÕ‚ „a¸oÏˉ…§µX ·üò÷[uÅ{»:$Q(”Çÿâƒ?!Ç3g¯\Hyøñgïûɯàxò’ÿ¼æ²3NYÊÿß_þvÓö}ûöàüÓ-èæ8voÿð£¿ÛðŸ¿~*¦%)FÆ+¤ašþ“üþå'ö¤V/?þs—}ð—O½l; Y!uǽãÇÿýÉ÷¯>¡·kÓæ7óÌK{ª„Ûõ¾¾þ¿>tN^üY.UÍ×vìÛ¾};#Ä9^ÀrÕïŽÿ÷ߟ¸dõ{Î=}ËŽ}ϼôÆy§-ÅËÕ:Ë ß¾\‘ŪeÿêÉM?{ìiQK —ŒÕKç«1¹P®þøá'~ðЯe%.H1–㪥  86˜s’.­[6<±üíï)TÇn ¥8îZn±&Žò÷ßûÍW?uaóãŽÚ1æqîÚ?<êÖÐöråå½Õîïy°0¼ýϾ´×÷ýŠa¼QQÕöãZ\yøC{Þð Ïs d9.¦%µt›(ÈC{ßpmKMdôt{†„§n–‡ö1„é8þ$†Z%ï˜FÃqBò¼‹§ÔxšãEQ’÷lÝ~²­[Ïtí{ýyBHÛü%j<¹ÛË^ÃI¶÷Ä3…¾¦QTâétg¯ï5 »]ÛbYN‰§Ìr! ƒlÏ ™L{ÿþ]u£èyo}ñªS–.\÷ï?úÌ«éÎ^^ËÃûëfµa[ApÏKr"ÛSu„j !aöÔ«%ÏkH²Â0ŒmÕpDϵó»ý†Ër’¢Å³Ý¢ËõípêµÐ8ž“Õ¤žjãQ”bôÛDAAq, ’\¾ü-ƒC6ÿá·ã½yÅYöGÝòZ"Û9ÛFokú"¶þZÞÿ§yœ£xØ­(涽Ŏ“Î'ì[T*ÃqAÛ Ë-/]´°Z­†»öî4+Òø.,Ë'Û{‚ÀcÃ0” /H¼(dz],˱Ï ’ É„QRX–e…PVâ/8JœaX–c¡!EQæD‰’hïåð„a’í=²ÇU$ÚçñœÀp!DOwÆâ)^adEOf熀ód5Î "!ÌG/YÅÓwï\´ ó”¥ÇÕ¬úã¿B†åmóÄX%dËp Ä$ä°ó?E�¸dÛ<QÑxN`X6 CÝ÷8^ „ˆ1-Õ6eyæÀÉs¼À‹b"Ó>Çñ؉ мHY“‚‚âØœ£5ÜÉg_8™­šøÌø¶£^lm€ð–?Ôò{ß°Jrï*^ÆîWVã› ÖþüfÛ¶ ·Ú°dýôñO™(zsZ§;F½"Hr²­;úOQVÄ1ó\€Tû¼èßéÎ?5•&2z4àqä&Z*;v?ýyã]o;îÌ“Ôwãæí÷üûÏËU3ÛÓŰ,Ã0/hÉlë["HrB’›þIs„µÙt7 Šc‡9§3Pküpë¡ØvÔkÕî(³7qxï¦Q|eY^ŠÅÓí‚“µ$K“Ž3 ×¶êµÊ¨¨iklÙòZLKˆ²r¸¶^) ìþS¨öX®L‰gºd5Áò<J§XŽ—cËÒW Š™Æ[nÙòÚä7‰i lu¸¶…‰ ŽzÄôdLOÒO3Å!âNE“íÈÚ¶ qBqZF‰ÞQ ŠQPâ©1Š“Ë(ýðÖÓÕ¡     …ßúÈ;i&‚‚‚‚‚¢Ö®];ò?ù±ï(—Ët™((((((!ëׯõ UœS�%N Jœ”8)((((((qRPPPPPP⤠     ÄIAAAAAAA‰“‚‚‚‚‚b ৺A*•júz©TŸJ¥3¼{¬Q;Ž8òÐsc·y3xií‡<òȨWÞÿþ÷G¯ãß³±saFÕTÏgÆ¿&“ÿ ÎÒ¡gðC;Ûg8ê-~7š®çAÞú™ºØémxÖöð~%GݦYýðÓÛìP®þdŽ5Ûçs¸>msüSä#<òÈ#¼ÿýïŸ)Êlñœ4×¾¢©TjŽpyD�‡÷”fqæÈ¾ézÎì­>̇ìf•”yÄ(ÎIø¬ µñtaôážöÇ{ˆ¶m¡hG^Ú$ŸagêªÇ^ìÈ#Ž|}Ô¿Á­‰çØ̸P˜ðº&³³­ùZ¯öŒÜ‹Q³iºé§ý,ÎØô„_´YOã­ç,1ÙÈŸ¬¦W×â>¶PZ“ù™:u2«7;«Ÿ¼±7iÆùc¼§ªÙþRÍÆ¥MõAµé™€-F2ÇÈ7âó‡ %ÍB»^›Ìuµ^ƒù±kzÄ)­ö¡ùšLõгñ‘h½8MØú fÅZü2´þÑïÖä¯yë«›Þ‡ä0~ðæ k¶¾Òé}œøƒ¼ñ‡àie¼G†ñ¾r‡%656n3#ÅM×yî<!Ž¤Ã¦šrF"·s-73öô?½Íñ˜ÞTÕÌT¿È3²ªM¿­ëg|ñ'äòñ"É£žÇ[£InÎøƒÔÌçd6S¬vˆomÓè,]Ú4®}ßöÙ;ÿ±9NrÌ úœ´N L¸Ôsíyÿà¿nã=¿5Êf’·~¦¾†ÓX·Öèÿð~t[ú™?—¿söáe.\Úx‹£ìÖ̵ïöÈó™P*Mæ­¦±a˜93hZÊ0ƒ·~JéˆÃ¦ñŠ®¥)A¶ ø™¢ÿ£>‚Òì!ø¡™¥'ÍÙ{–ŸäW}ä¥Ê¢r³wkŽVÖœ½…=˜{16­;—oëØÓ››šûHYÏÖ‹<^Àì(nM™êWlz7—Ÿ¥OÞXR™‚ŒhiTÁdëGÝ9{i3u&£Îêÿ„9ÎÙxBjz ‡ì¾Œ]ê'ÐúÍà97ÝU‹âqëÅiúE>¼_´É|ÆÍYMæk>v[¯ÞÜù;,÷q¼Õ›Ò:0«Þó‘~ìŠ}ÃË(ýðÖBÊå2¡    ¡…#géêÍÞ§nýúõ„Êi%žÊíß±wËsÔr‚‚âðülŇž�(%(qRPP­µT¬ àéPPPFkxÄ-Uœ”8)((((((qRPPPPPP⤠     ÄIAAAAAA‰“‚‚‚‚‚‚‚'ÅФöB+εk×ÒE¡     ˜qRÖ¤     hÑ¡ÚË.»Œ. E„d2ùñ[Ø\qRPPPPPPLMqRÌ h™Å„ q>JœoÁõ×_O‚‚¢Êå2]Jœô[AAA11Ö¯_OŸ­DÐ'UœG²¥‹0GÐ4=1q¦R©¦¯—J%ü‰Ž Ÿ¦½hc7ykÆîpäûGÝı/6}[‹wNæÅil>Þú´¾ö֚̚·ØýxSÐîAÓ\Ûd'ýù8ì\ÛšS©T ^iÍ%ÑæM÷Ðô­>áZ¼8Éç¶)h–e((f ÃàW^y¥$I‚ är9Q !<χaèû¾¢(¦i¶µµ•J%QF­VK¥R†að</I’ïû±XÌ4Í t]_¹råï~÷»T*åû~£Ñh4„A†$IžçaŸßþö·ñÅ/•J-2ÐÓ Õ¶Ð”e~ÑÆ¾ØB5Žw¬‘œ1 b¹É„Ž:óQïŸüq')ާtEã)é¦Ï#}Ôë“ù„Úv,mÓïÅô`YÇqŽã(Šây^†„ß÷EQt]W–eÃ0Â0t‡ã8]×Ëår6›5M³^¯ÇãñF£¦i¶moÚ´IÓ4ÇqxžE‘çyÏó†‘e¹Ñhð</BµZ]³fMAxžÇq\Ç…aX«Õ8ŽSŲ¬hCY–%I*•J,ËV*¶ Žã‚`Û6˲žçá•E‹ ×ëuI’°OŽãlÛ¾çž{Ž ;239ÎÖúƒ¢é/é4”ÜÁ¦èÐbÿ“üM?øwθ°›ü)µfÖñø~l¬»Å}iz‹Ç‹`SPL ªªú¾ˆ-™L–J¥F£!‚çyAH’Ä0L,3 ãꫯ¾ûî»mÛö}´d!¤R©‚P¯×9ŽcYÊ’çy×u%Ij4¸®ëêºîº®ã8«W¯æy~Ó¦M„Ïó MAà8Ž"˲ªªù|ÞuÝ âñx†'žxâðð°ïû–eiš†73 ãºn,ó<oÿþý²,‡aX¯×AÃ0 CI’n¼ñF0¨ïû„z½.Ër¢(†‹ÅDQWR×uJçÃ0L–e)Š"‚ïû ÃT*•X,&IÒüùóßxã BH,ÃÒ}÷»ßu✑)б*dlŒt¼'ÉšcÓGýuB†n!›¾³©6Ì>fÇ;Ðl?�Mx_šÞbúÅ¡8HH’T¯×†(еZ­Ñh(ŠÂ²,Çq<σllÛEñÞ{ïåyÞ4M†a®¼òÊŸüä'A(Š‚Gº®Ë0 Çqð ‚`F:vGÓ´z½†¡çy›7oö<ϲ¬D"âô<OÓ´|>¯ëz£Ñ¨V« È¢ÈqبX,2 9 ¹ ªªÖjµd2IaYV–e¨çF£I ÅlÛ¶$IŽã$ ¼ßó¼L&ã8¨eYÛ¶‰„ïûÕj•eYAdYÆ €u]/ ,Ë꺞L&ñèðæ›oJ’$ŠbµZ•$‰eÙÏ~ö³š¦!^íû>Çq‚ ˜¦II$­o;ùŸª 2F*ŠI.é¨ukúâÁ°æ!»„ƒ×ÄGÜÍšÓSPLŽã°,«iZGG‡ïûõzÒ°V«±,KdC-Ë‚°A×õX,öóŸÿœçyY–u]ײ,ÈVEQêõ:h£ÑH&“`Íjµ zÖ4 D;þü0 mÛÃçy˲X–Çã8t,›¦‰÷@×ÖëõZ­æº®mÛ¶m[–Õh4b±X­V+‹'œp‚ëºÐµªªº®kš&þÍqœ,Ë8±úàAùªªzžgÛv,sÇ4Í\.gY²¿ À}ß7 Ã4Í hš†“¬×뺮§R© Æå€z÷ýÏ qN‰\éÏÄ4~R§âRÐô?g[=Ðl°æázD›Fè•>JR<dY- "úêû¾ã8²,ƒ/=ÏAB,‚n¿ýöB¡�EhY!Ò0G<§ª*!¸Íu]Ïó‰„(Š¥RÉ4MÃ0J¥’뺊¢ Î9ξ¾>Çqð~P lÄq\&“!„ø¾ŸN§AˆÅbÙl6—ËAŒnÞ¼—–H$êõºiš,Ë2 S«ÕXeY–çù虀ã8ÏóEQEÓ4„—q>Ø9R­A8ŽRT%™L&‰-[¶X–…è1N©P( îH$8޳,«^¯C¾B4M“$éÐ'ÕSújlàqÚL3öÙeªûiqJGÙ˜ùw_Æîg¼46Å´Q.—Ã0D(Ša꺮ª*Ã0Žãd³Y„j ÃH&“¤Žã|å+_A •eÙ(F Ž ÃPÅE‹%“I˲$IB"жmäO8á„sÏ=R¨X×u: C(3MÓPÜ+Bgg'!{vDz,¨ÀF£Áq\¹\†ˆ„.Ä !(&’eÙ÷}×u‘æ%û¾ ."ÏÇår9×u+• šÛ¡. ¤Ž=Ïs§V«% <=0 5†a6›!ŸÏkšFdpAŸQùÕ¬ç¨(ý¥o}ÆölŒZ´©®dj¦tw& ÉoÞbŸ£Îó ?03²tSºkî¼é->ô¢Ÿâ¨„¦i¾ïƒ` ò†‡‡!Œ†)—˺®£¤1L°šmÛ¨ýéîîñ€–*•ŠmÛ„]»vA´Õjµr¹Ç)åy~ëÖ­6lÈf³È¤V*ß÷! ÁމD"“É ¶É²lµZ m-Çišæy¿Ç à0 !þ ‰+• ˲(¾…ÈÓu´Ç0LWW"ÌÐÖ¶m§ÓiècEIAà” wãñ8”%Ã0º®Ë²œË冊gppeÙL&cš¦4xò�›¶�?ÉŸ¦¯Œ×ºGÑb'\´ñVrªmÓ;ÐŒ¿8ÉË™‘ÝN~Ÿã-N‹Ežðˆ“¿v Š)çyžç»ºº 9Ž«V«¨/;"쉾L4eBá1 ³{÷nBb˜hkRE6ŸÏg³ÙF£aYV™L¦X,‚´À[¢(Ο?ïÞ½Žã t\,QY±kš¦ªª¶m{ž‡úp!˲ííí»víây”AµZAΛ7¯P(H’ºkêõ:t$˲…B‡€X,V¯×UUuG×uÛ¶sÆë QY–K¥jˆ8ŽÛ½{wgg'.gñâŃƒƒǹ®k²ž„”}=Ï{óÍ7Óé4Ž{HCµÇ ¨¦¤˜=‹EDJ%IªV«¶mã·©>–eA9ˆÊò<¬a¨¬7@~©ª*Š"â–†a G%²–e¥R)†a@]Ø\E]×EÙ¶mIAÌ‚ ¸® Š¿ï}ï[±bEOO,Ëmmm¨'ª×ë;wîTU5‘H ÐábP²aQ=-8J¡àZ­†äe*•B«(ÚZlÛFÙÎÄ÷ýÎÎN]×Y–u]WEEQp9étÚ0 ôŒó<ëEç ˲ˆÍ¢9Ïx€@ø—'Å¡ˆ(ÐlÅŒ]aîܹÓ4M4G‚~}E- …¢SUÄ�ž½yžW­VMÓ¡\.#צA Š(ЍšAÔT’¤Ï|æ3h¬ìîî¡««Ëó¼z½Žôa,cYõ5¾ï?ôÐC/¿ür£ÑøÒ—¾”H$ mA�K’¾TU•çùÈT²�çø�� �IDATÁ÷}UUál'Š"º<«Õ*®"‚r¹lÛöqLJêbQ‘’¬ÕjHX»®‹A'4z*•BÖS×uTØš¦‰ okks]7x"a½­ííí‚ P⤠8DÜI«Ê)f¾ïëºë´ŽT«UdìdœïûP“hº „Äãqð, PXë×uQàãyl†jµêŒP•Æaî»ï>twô÷÷Çãñ|>§Ãx<‹ÅÐO Â+—Ëš¦±,‹4äÍ7ß\©TDQDÁÔ0ºh|ßokkÓuç ­éû~Ôpéyô¥išH‹vww«ªºuëV´¾B@ªª‚Œ#&F2µT*Eî¨Êçó81, Çqýýý84®VGÇÕj5Ã0 >[€NG™uÐAÓF: !€ +D#Ñ’bT†aÀL0ªEÖ®xˆè¢(&*á1 #“É Æãq˜øà=„(¯I´i.[¶lÆ ÃÀý ‹¡§“¢(ÆãqÇqÐyR«Õ"C"²®X±bóæÍ°ë«Õj(‹M¥RµZ­Z­Æãq´Ç0 ×!´WzžW*• 5A¢¹\.dRšF?+"±®ëf2™¨ O ÑãÔ*J„|ßïêêêêêÚ°aC¤>¡5Ñ C‰óp‚N9   ˜6ŠÅ"*k‚ ÈårŠ¢  U9`Ph;˜À‡!\0¡óP5GÔã šf:årD‹¦ÐtØ+¯¼‚B¤|>rB¾“aUUK¥,~òù<Ã0 FrÀ6¯X,n۶Ͳ,”þò< &]Ág©T .ð:@1:,£?Á€¾¿¿Ö 0ð)Bd",ŠP©„À,V�¼[­V¹…œÝ±cG.—ÃJF-¡ uJœ‡k×®¥‹@AAÑM'>þé7šç> Ã^9HËÁ62j±J;°)¸9Î À`JBâ–†a躎}¢Ãó<8°³,[.—yž·m;›Í¢µ‰@°\�á›N§wîÜ VQBÀ”„ÞÞÞ}ûöaÀ‹,Ë–e%“IÔýFñ^8ȲŒæTèìR©tå•W~÷»ß…ao䊡lY¼g!µc±\†éb ¡_áßkÛ6Œ ÓñtŽ¢| 'O‰“ÊM Š9Ц#€]À‹HgFSÀ,•J0›E¶½½¼ˆ&Jlêõ:ìjAu‚ ˆ¢ø®w½ë±ÇC°·Z­bCP/BµÅb¢( !ÉŠš#L%Ce,Z9ÑÓR.—“É$˜±e˲lÛ. óæÍ«T*°¨Åb„†aP‹Ù,PÀh¤Æò<ï½÷êº^¯×ÆÉÃÆ2ô<44”N§¡>1é ±XÌ÷}"zF!+q-Gd‰Õ˜°8ˆçaþVPPP³h1ñ1|ÕËå2‚“9F­Š„ÎÎNhJžç12 AKÇq€Ìçó`M˜ 2 çŸ~3U`¡€&KÄ~Qm Zò<âU<,ËÂ9ÁHðaŒ Ä+¶E­ œr¡áR- (Ò€VUÖí8"І—V%¸¨î©V«š¦Y–…ì,‚"¿YEQ\×­×ëP®xV@¥q&“AõS&“)—Ë–e¡ ±p?˜0TK«j)(((æ. ˜¢y#ˆg&“IÄi-Ër\T½¢*'jÌ�Í@rBгˆWÐë ç(À 3ÈYhV¼ÎR©ZPÀÜ [Y–Ññ‚B_Ïó`æŽhp´ÃD"Ø2ŽބŠƒÒxž/•J‚² ì„‚fœ3lðž¨ò´Ž\¶lY½^G=-,‡†)•JÕBï¢h}8wßqÇ”8)(((ŽT R*IJ~0c-O+W®D{x<φaY$)|  ÕPà ò�ñ°, óü©Ñh€Sa€Jì-˜°æ9Út3?è6ŒÎÆ “J¥‚Gå¬h…ÇmÛ—_~9< @Ÿ¨-ÂÀÜ(q‚;öA‰¸+@ÃèaÅ41”/mݺn‚‰DBÈS„d•âl}ßG×ó¼n¸afˆ³©'êxÓ0¦a¡rÔ¯¤Æ õªŽgpÚtò õ¬¡ 8Z¢žT*U¯×¡¥ í†yá…ÇÁë—¨ƒEÀìüµ0(À‰Üò"ïu¸ 0Û’‚nK˜ä¡¬' XP)Lï"]Eá_Y–‰Ä]wÝ1 Œê!ÙºuëÂ04M3jNíêꂼÆÃªª„Ð9LþpJˆëâºðp€Á,ÑâD6aÂi\ xxÁö¨­­ îöx@‰ÔíÁgd†2™á‹´|ÂÅZ¯jÓVú¦“7&sS(((ŽP „­–«V­ÂŒåD"ÒêììD¹M†¨ÙA³ Çq˜šÂq¼Ô!1™kñâÅ't&”aî (ôK B%©hßÔuÝ<Ï£,vÅŠårÙuÝ… BÖݵ.–e;::0,ì¶¹mÍš5µZ Ü ¶Ãø˜ <«ª*xzïÞ½È;BPµ„«‹’»ˆ'Ã5çù•+WbЈŽàN4ç@‘C¿ÂRûÌ3ÏD2µT*E“gЄ:áM™˜8GYˆ5ý™+ƒ&Ô©£Þ6–ŽAB%-QµRMV((ŽV |½ü/½ôR>Ÿ7 CEžçE1 ~{ˆ:‚ó`Ô(BD Qš[­Vwîܹoß>X$ Z‹@MÂÒS½lÛVeÞ¼y‘¹+Ò“(‘Ý´i“çyÇü®]»†¹ì“—Ýwï}¦i %‰;¿sçÇ?ñqÄZëõ:dk"‘€%†W§R)t¼T«UÈkÔ ¼MÓDCŽïûwÜqèM’¤žžß÷kµ¬X–E# ¢»ˆH7l6 ÁЧ <m˜¦‹Å6lØ�%Šqi8hdR8ŠsBfMÇRBÓ§=<òh ÀRPP�±X¬¯¯ó2¡Ì~ÄØgň¢øçþçQÜREŒ®D…¬ǽûÝjkµ!DÓ´R©$Šboo/²’(ù·@£Ñhkk¿Bh¾ãï€R„,aëºÞ×ׇsCÎõÖ[omooGH\ÉDÑÇó[ø¡X $ {B,æEùâ¿xÝu×áIÂó¼¾¾>´lÚ´ L„B¡�úD…­ªª•Jm¦ÈCPâ(¸ºH[{žW,}ßGT|Ö‰sÚlw ê¤ú{䚌 ÀŽ'7)ÅRPÝ€PƒG9h‰‚QÛÛÛEqçÁDnªné¨ñ!Ú{ì1Ó4Á[Ø'(¤T*íÙ³‡a˜  Q™Hß÷ûúú “É$˲Ï<óL,Cý‘mÛ†a@M& –eMÓ Ãðó7~¾»«{ppðÎïÜyõ5W£þ¥…BõDhHEø“LLÓlooO$x2€nFٰ뺵Zí–[nAw ª|vŽS#)ÇMÓ, ˜Ü‚5AÈf³xæ „4B¡€@1BÖmmm®ë~ô£E<|v‰s2TA?ý£xqìÓC‹UšL–.2ÅQ øÇ¢Ž©Á¨´§Ñh ‡tÏó0Ó¶í\.‡<œ†b±2|ªª*Šbš&ŸøS¡?>Fš,_¾Ü0Œ… "ŠÛh4úûû}ß/‹F$ªë:ªx*•J__Êzáû< yû…£l”sE!’®ëº®#Ù¹gÏ4SΟ??jÜL¥R¨ÜÁ¬lœ0zG¹R”é"’ŒÐ4ªjXFÙ0ÂÂà×hˆ˜¢(===PÏ dUU|ðAìöp'1#Ïãe…)((ŽnÄb±d2M¨¾ð #¨ÛÎï(ÿUP´‰¢(x=2–‹¦}žÅoõO<O»mÛ¶%“I¤-aÚ‡·¡‘ôÖ[oZGà I’mÛ`qÛ¶¯ºúªûï»ÿ†Ï߀ŽI ­FÍ!Žã¬Zµ £FqzÝÝÝÅbÑqœ¾¾>ß÷ÿöoÿ–ÏäY !ð*ŠÜ !,ËZ–•Éd}u]7ê¥Ñ4çùøÃh¶Éd2(ëÅå`D Âݪª"ÙIœçؘ!ykxv2?â“o\¡”0™‡úBAqŒ ¿¿ÿãÿ¸®ëК>úh¥RÁèiÔ³”Ëe–e1À Ž¥aàh8ô« ÀMÈ¢ƒ¬£ù¨§¹BäyžgYÖ—¾ô%ì¬&I’¢(È_Â�‡Ž&]ã”lÛF-’mÛår9‚Í›7Gfxª‘vák_û¹„%K–@)"⊠‡÷,LtQ+ŠâªU«PL„Að£ýÛ B`ljDzb=*z©Ï€âl=¤wdgÅ„[·«èõc‡¦´>S½)G‰Äý÷ߨôÀ—Ç÷ýr¹œÉd@3¨V…Ä$ÜÕ-˪V«¢BT¹®{ÆgÀäcR0wŒçyh8 T&Æ•ˆ¢ëWUU…²Œ:# …Âàà ò¦H2†¶CJRÓ´ŽŽl…NS4ÆãqI’R©Ò–„†a Ã�©ƒ¼yžß³gÏóííí¶m7 tã@G¢™$ CØÓoÞ¼™‚ÜíùçŸ*J¢¢Ñl˜§²aÓ4-ËÂSˆ(Šªª‚Ag€8É8×è?NjĶØjì&Gw8·éÕMi}Æî‡†Á)(Žz 2‰Z ªÍårØÊ²ŒÎÉB–‰¢xñÅ£¾=-,˾üòË„„.1D Ƴý×-Š"üóâñ8Çqét*½Åb‘a˜d2‰"TA#2ŒzWQMÓ\sÓQ16@¨hEÒe®ÅbÑ¶í¶¶¶r¹|ÞyçAìʲŒòZˆ`4q^ýõ¶m‹EEQÎ>ûìb±ˆ +Jdëõ:¬ ‚#1úÔSO‹EéÙ¶í8ŽeYи‘.È6 PáÐë3Cœ‡ÐL<Ïçóy´9ú¾[€X,†48]‘_«$Iš¦=öØcJ¡=vthY1 ¤"I’ªª÷Þ{o©T‚i;Ä"ÌoA«¢(¦ÓiÛ¶óù|µZE ]bÅpÍ{î¹÷Ž;Öªª Ýûï�do ¼5¢àÿwíÚ•H$^|ñE×¶íD"áy¬t]gæ¶ÛnÃe³Ù§žzªV«AS:ŽsÖYg!DŒR ªmÛˆ6www˲¬ë:Lq¡˜Ñƒ'�T†‘N§áaMÉ>tÄIÆ3MÓ ˜À‘*Bº®›ÏçѼßh40‰ÚqD/«Õ*²’ˆŽêºnÛ6ÜyÐŵZ¢Ô(‹~FÚ „ÞDß$\ŒEy-2¦ˆÇâœANÎ…|$Jœ7£ã˜¯R­V†û"PŒˆ4ZY0tsÞ¼yÇíß¿çõ§>þøãä@úéREQxžO§ÓŠ¢D=3(ë%„à¯X<à$A[¨aîîî>¤ÄIÆ3ˆ(ô*Šb6›ÇãË–-CfÎ8(FžìŠ¢À<AHX¥7¡¡!T±jšV©TÚ=ûì³á¡cšf<G?(T,rpÑCáL:Îf³Ë—/‡-­ïû_ýêWVµ,‹òùÏßpß}÷£¼JD… [øåV*Ä{# $Ìű¢‰Ü<Ï;Ž#˲mÛ}}}8mžçÏ8ã ðq2™ÔuYU4¶âXº®ãê`ò‡‘/²,·µµ!= ¶FÒ7 Þ‚z9ŽËår„èçr¶±~ýzºÓ&W#ÂÙh4^yå"È ’FqÇaÂ%X ¡]”¹¢S/Z–%Š"ˆùùçŸG¦Ó¶mL o-h‚Í—„8 ¨ª ìºî-·Ü‚á'x,Â0„¬Œæ|aø6ÆVƒPqa–Ëep"ÌÑ4éZ­†Ñ. dMÓvîÜyÊ)§<ùä“(/Š:; !Åb½¡Ø¹R]×Ï8ãŒeË–ÝÿýA £†ÅS8ÉJ¥ÒÝÝþבM)qNL8¨–‚‚‚b<€ê8ŽS¹½0 ÷íÛ×ÖÖó<TÏ¢dM,A º<Q)ŠT¤Q‹âRü Dˆ’Ó4ј &Cj-%årÇEì×ó<!$‘H\}õUwß}CÈ„Àƶ CÈJ\¤-î¸ãŽo¼*ÙuÝ%K–¼úê«… ÃÄãñ\.Çûûûñ¸€P0ª‚ãñ8Ú[‘FEÈ‘í'Ÿ|òþçPõƒêªÈ!J:44äû~[[[.—‹Œ)q6¬]»–.B \vÙet((Z�ÁÃt:ÏçY–E/&Çq†a`èæ…A± ‚�¶³, ïAe,|¹ùxž2G"Ï'Ë2´v…Œ ¤dÉdÞññx< C$DljÇã±X ID4{Œ¼×u3™ ¬Õ#Ÿhf,‰Ä¾ð…Ⱦ££cÏž= cˆf” A £~¯Ãóížš¦¡W RÓ4HçhâÉ#“²8gQc±X¥RI§Ó8%N*7ç.Êå2] Š@Κ¿øƒƒƒ‰D‚” ( .aP™ì(Š‚BÙR©ÔÞÞîy^µZÅ_c±ÞÌ0Œ®ë`»h~g<¯T*ä@/&”b:îëëCP= ”!þ èû>CH8âeoe2ÔÁ?›àá·€‰Ü£8,àÊ ŽêYBº0u]GÎ2‚E‹aϘÅ-¬‹LÓŒ!¦k´, qÚh‰(qRn˜sX¿~=}ª  ˜°l…ó*Ò–ø•WU£¡ÁL Žã íÀ=¡]]]`J�ç¡Æå¯\pÁÏ~ö3HÌD"‘Ëå0ðÙ¶m˜Ë³,;44nFÁ-¼ju]çU*"yžÇ£ó7 –Eµþ 2C™.Xñg‡‘Œ~A@ ”"ºB !ƒƒƒ°Ø°\.㹡X,¢·Ø3:J1|;ò×E/ ª|¡‰[€öqRPPPÌ]X–¦ÁŽãÐÚˆn}Ô³  Í‹–e¡/cL,Ë‚ ;úF"+×J¥¢iì,Ëzýõ×ah€^$1,‹Ù¶ w:hJÔ»V«ÕHb², ÷ŸÏ}î:åBBB"G\djMÓD!+!-›µZ åBžç%  6pÙÅåCã=„8!]ŠB!tŽ"à,Šb2™Ä$hJT'2QµùÈtE¹Q %N Š#h´€öŠÌz’É$¸3û¾ŸH$0c Þ=‹hÌe©DŒçD2½"W–‚{�êk …!$‹A·¡éïAe ¶J§Ó%íº.Ø­¢õzý[·käùK’ç<dR¡ Á¾hY]á$£„kµZýïÿþoÄk… ®V«a®Zµ Ájq4b ÷AüÉdºUÄPçÞ‰fÖR©ä86Dá.²¿k¹7Ö‡½Å˜0:Aìp!5­ïËØw¦Æ€®'ÅÜ,Ëh#©Õj¨2‘`5üîCKaF òÈ)Fí‰p¡#„ :Š™—p@ºÔXTÌÂ�eY(9ÔÇ*Š‚·!Š‹Hï©§žêºn©TŠÇãÐs7Ý|!äú®¿ë»wAÅ’…¬ˆš¢ÆúrÑ¢E„t: q‰¢VY–»ºº¢é›Èk‚ìc± âQ-…Füý¬#Û1£ÓFG)æÃD½˜ÅöÎw¾=?FOTqý¬IÆÌ9jhöØwRÃ[ й Ã0ªÕ*~âñs€*b³ˆ|"øÙ €uP@„X.L�íô}ZüÕqEQ …BäÑšH$ð¶hÖ´ïûétŒˆº¦iO?ýô¿øÅd2Y*•AøôåŸFšÐ0ŒË?s9ª{©…Ó:´)ô!dÿþý„x üñ¶m»®{ê©§vtt`47Þï8ˆ¥F˜¸‚ªZÄuá>ˆŽ¸!àŒ.ã?š^ó‘ oww÷sÏ=‡ÕN§Óö¢LLœ-fеÐ(cÍd„ÅôЂóFM›iÍŽÔ.‘‚bå¯ Ã`ºH*•B³„$I²,C/¢ â ‘IÏó0c$ Ã|>_Y¼'2·CúR&- º®wvvB›ÂÆ6‚sÎ9§X,F§„¶Np8I’¤Ûo¿ùWØ2`H|¢|—=�˜¿#S‹£@:ã$ßñŽw¬^½Ú¶í—^z r6‹¡÷>|¨EBÆ”j‡A²³ÑŸP`ŒQÞ,ËîÞ½Cèé$ælW«Udp±°‚ ÜsÏ=³¢8[«œ™Ú„bz7eßIAAqØ^Éçó¾ïçr9P¬ `/‡_|ŽãÊår,‹æy! ™ˆfŒíDºñ„NÐ4M×õX,–$)ŸÏ¿ùæ›8®išˆ�ÿþ÷¿G ÉNt}T«UÄu‘tDVùNß÷¿ýíïB …ÂÒ¥K !h¯$„ �GÓ4(NÔ Á—�'ùàƒnÚ´©½½ñUôh±‚ñ,²,£" ‹7]0+œîñÄ€nÎÈ“wåÊ•¨§Å8“g ÚO<ñăUœÓP9s„5ÇnÚ”5)•RPÌM E†! ‚êõ:ò…UA”ËeÔÈ8ŽÓÖÖõ [sø躎'‚“ "Çq†‡‡‘k„';ÜÚÛÛ#-›H$`G�fÆðð0HÅ>õz=¬ˆãœQ†CQUuÏž=0¦Ïf³¨æ…3!„çy”ÑâhÖDkäBP( 4¡n£®MÓßÅÉ@æb} žñÖUr þ(•J=÷Üs¨CÆA‘pÅ_‘¦Ýºuë gÓñÔdDÜuª¿ïTkÎ5Ö¤  ˜³@v¼…X+• ÊAÑ•‘Ï硱 Ã@¨cLjµ™(®AIQoo/Z$+•J&“A) VK¥’eYžç ÃíœÑ0jEQPLÛ£±Ò|hñ\·înœ<¥’$-[¶ å¾O ÿß÷Á‹ÐʨÙAäÖ²,TG³\àˆ„ÿ„~E±.Ã0àÑD"ùÁäˆa˜L&ƒ ¤Œyj# ’8ŽK&“˜ú©ªê‚ Ð:3ŠsኻNUªRÁ:«¬ÙôÉ&ú7]y Š#`;T–âÿQ#Š"‚¥µZ Ö¬„D"EˆH&¢¯àTè3–e7oÞŒ°¤ã8¨;ÅëpmE×JOOªLq A@½õz±YX.0 ƒ¸(ªuFÜBBP¤*ŠâöíÛA„ 0Y–!û0×’¼ ãîînü¾ð.P¥§§bQëõ:JŸ†©T*Õj­,ñx\’¤b±È²l¹\>ùä“F2™$„ BåE££F×ud‹ †g€8£ŸÚ©þæÒƕű(´,ˆ‚â jÀˆªª&“ItŒÓ%?ñ‰OÀϲ,TÀú¾§!´XÀ®/š‹ŠE¦P’$>„RÔÅV0LÀTÁ^QY–/½ôÒÎÎNÈ5†aPÄ‹ÝFgþ©O} ¡`hÇ0 ‡††|^D°£Ð0b,™LFDU‘çy{öìÁÓC½^Gõ/t*Çq¸@ØÓc>Š€žþy†a ¾£¢'?ÚrP‚«ëúºuëÆd¸iú9ΈÿÆûD¯Œ*餺gVuç$ƒç´¶™‚âºMP§Šÿ¯V«(ðI&“ÐU>ø ÊmAèíí“Ћ þCÀS’$Û¶Ëå22‘¦iV*´»`è&Dx™Q¨OP8È)‚ŸýìgÅb1*V‚2®V«( ¾ÿýï#  ½ëºn*•rç�‡nÇqŠÅb½^‡)D3Jj¡/£ è¢E‹hEº7ârü'6Ä%C\ú¾Á ôŸ¶`tÇqæÍ›'B?ìyGú,qŽ ®Ž4MõÍÈ?'ƒ(fV\6]Û¦·©éÍ¢  ˜SøÜç>‡H)&ò=ˆš8“É$¢£±J’ôæ›o‚ ž…€`@\pêqû…Eu ^xa†çŸ>F”B ðX–Õ4 ¼‹8pÔâAwww2™„v$„¬Ys#!„!ä¾ûîËÂá´Äq\OOO&“’©¨HZ°`b¹(öWÌc#K÷W_}&ÝÝݨ¤kü?ø£È€ÖjµÇ<²½E.f„š¦sÎ9X/}éKñx|ïÞ½³¥8)((((f˜y‚Ave²,Çãq4þœF‘$ S¦# :œišË—/7MóÙgŸE›²º®§R©F£±qãFÌÊ¡¯¯OEhM¸Ì†ïr ÿ 劲ÕË/ÿ4Lû!W\ñYìß0 æ ?äõ×_wÇu]4h¨ˆ²wï^˲Â0L$p£#Z‹áèÆÙ»w/^ǶQWhdR˜H$zzz=FäeP˜,†ƒ¾ôÒK„ôç õ;¡ß%N й‹(<‹¡’$uvvvvv²,[*•àêŽJŽÂ±=šy™L&Ñ¿aÛv&“yõÕWa†�Û¶‘ËDçe‡&“Ér¹¬ë:ÆŒhšV¯×!7QÇ‹: B&HBúúúÀÜ0áÃA#2µ£ƒ3—J%hÖt:ù—y“ó[!¨ëŸtÒI‘%vªƒ}nDв,cJš(Š'žxâu×]'Ë2Æhà çÙ:Ž«z¬0[)qRPPP©@Ï%*zB”µZ ă*†aâñ¸®ë ¥ªª‘h?ä�� �IDATHéÁ=@–e´3¯'ÊY™*HøA;V«U4±D’ˆšBÅ"þyî¹çâЃnÏóÎ%„\yÕ•`Ó3Ï<3›Í¢Ògppm-(ðAáîu×]õ•7 (ÎHG¾üò˞穪Švœ„Ê[ô›Î›7ÓNÂ0|ã7î¼óN\ô1&`cŸp~�GF‹Å"lô[ƒÎãœu¬_¿ž.Å4€&Ìô„4óEõ«¾ïcò3LæðžÈ²µ³³ó¸ãŽÛ¾};ÚHb±ØsBP„ÊÇq:::lÛ^²dÉöíÛ1±ËuݳÏ>{ãÆ¸ù|žã¸­[·¢'™L&†Eõô¢mÛ©T꥗^joo¯T*¨•ÅO'!¤ÑhÜ~ûí’$-X° ¯¯©J´"s‰h3”륗^úÓŸþK±bÅ X½BPËq\¡P@Tzz``�7‘ÆŸ*• :Ä(ØF¸®ëbl%Îà :®™‚‚bz€×Z Q‹îL†a’$„DóÂJ¥ ¤…JZAÊår£Ñ�§¢¯£V«;£e#»9wíÚEE¶DHy¢¶P(¨ªÊ0L¡Pà8î†n¸ãŽ;DQÄlmˆ?„[à›îܹôX,Q¸„80ò£{öìAô"$,Î0›ÍBGþð‡?dX6oÞŒí>ðŸþô§`G×uQp+IR¥RÁ 1-ËJ§ÓhƒÁ�5Ã0°P‘C!^€”8'Ö®]K¡.»ì2  7ˆb<Ôëu$#E1Mr-*öÅÀjäáf‡‰›Xh÷„:ÕúyU¦PfÑä/„m5McYï`ßr¹ÜÞÞžÏç%Ir™ÅF£qÏ=÷DþòÝÝݯ½ö"¢Ø•®ë†aÀµ»0ÒƒLD¦sÐEÉår]]]°ä½øâ‹ýë_;Žƒœ(ФP',Ë2ª \‡‡‡}ôQ”aæ6ð( i°•J2½P(`e Aú†²ÇÎ)qR¹9wQ.—é ¢7ˆb< üÕ.𦡶Ä€Ô&œÐãZSMÓwŒÌla€NY¹rå† п6Bˆªª•Jõ>‘3€$IµZ ,{BüݽnÝ$Ïüvò­ûï»ïšk¯S"GK9õÔS_|ñÅ –.]ºcÇ T1M•®Ãà̛7ïé§Ÿ†› l‚€\†i­ã8…B!‘HÀüÁ¶møA;âm¸®\.‡+‚Ã-ž!`(ˆ*!”.GISJœô§gŽbýúõs„´è šã7èX†MÂuê == M„OQ‹ŒªŠ$IŠÇã°—ã8±Í¶¶6²"±;´g ¼ s¢Z­†7`Æ5JŠ!7®YƒBÌ Òéô®]»0†qÎ÷¾÷½äC"O×u˲Цé8ÎÆÑ200€ÝBG"¥Ê0ÌîÝ»Áx@&Swuu  _òú8º.DhÉ¡cˆQ«ª ëD} !‰Dÿæ8nÞ¼y‹/~ì±Ç&ª¥UµG ¨ÅÑ4 ¢£^¯ã§l ‘„œl6kYô‡Ò¢Lö&¦i‚–@{•Jã½àÂÓÓÓS(P5CÉårPuÇ|¨£U«Õ}èCèK±ßþýûƒ €'C£ÑˆÇã?þ8Î_UÕ R©TÔTË"!(ŠiÒØ¹iš_þò—Ao_|1Ï󃃃0䋼|ßÃpþüù¸F#£]L®Æ$ÔÍ¢ZØq4žJ’‘ŠJã A°uëÖßüæ7ðy ÄIq¬°&õJqô?ú°"„ 'Äó< ^FÝ,Çq¦ibd4Ä:;ñŸh^BÛ"¬Û‘Ï;ùä“}ßß¾}{GG‡(ŠñxÜ0ŒHºíß¿¼Ð¸P™›6mÂé! Œü%&‘³£VKðjp !£ !ˆ‹"7‰˜32¸7ÝtF~øájµšJ¥p½`tHgL«. ÑôiØÍã±�»‚R¶x='0<‚ /ºhòù|gg'8‹6á}á'ó“4ê•R©4ÊoväŽz?õr›ä  Öz ›¾a¬]p‹­Æã˜¦s:›¾anÎõ<4‡žÆJNæ^Oò®MõÒt+úÅ<"€r°&ü£¡%Žã ø‰a#Q€nìhsD»$T`½^Ïap&Ä_:Þ´i“¢(¢(æóùT*U,a<BÂ’…(ô}#6‰èr°Ñhttt „¥?G…ݹ  ªªjµZExB¨f‚d„~Õ4 vEˆ$»®»dÉ’mÛ¶!+™ÉdL&„xžwæ™gnÚ´)rD2 EÂhŒAN ‚;NcL7$i.—ÃÂH÷†ƒ"Î ¿fM+é×rª¿¿Óà€±¿¿cÍ÷[¿¡[wˆñÞyxuæ%kNu%[¼8Õ»6á'¤éV‹b"‹yžglƒ†Q%ŸÏcŽ4LÌÑ”™ÙFææ‰DÃ5yžÿÚ×¾vóÍ7kšV*•¾÷½ï<ÄÕW_'¼l6;88˜ÉdJD¡ìßýÝß}ýë_f|Bã˜b¢$Des¹\½½½‘kÊ‹z{{7oÞ̲ì»ßýîßþö· ùl6‹‰ž™L欳Îzì±Ç &‘I…½»mÛmmm°D1QÔÀ:<< ¾GmÔ³Ï> o‡¨‹4˜B`Ö&LÞA¥Š¢Dù`Ã00¡ ½4 3cÄ9IÖ<Z'ŸD¿zcÕöÁË£Q?©-ækNã&99uÂ}Ž|C‹ÐÂá¥ÏCóñ›ÒJŽZÿIÆcZßµ)]æ´gRÌT«ÕX,†ø'†J†.âD½k¥Rñ}ÿíoû+¯¼ц€$š8mÛ¾ùæ›QJ ÎûÔ§>ù³˜¦Éó|>ŸWUR¯P(èº.ËòO~òÌûÉO~JùY'Š"z4EAiÚ:eYîë닢༭[·¢‹æÙgŸÅ,3BȾ}ûººº\×7oÞ¯ýk¸ɲŒj^BHOOO¹\Îçó¢(¢² ±å¥K—ö÷÷ ‚P«ÕЫ#Šâ½÷ÜûÙ+>‹=ß½îîëo¸ÅS oEQâñx­Vƒ£ÂËQÓ&£AþÂÏav‰³õOüQó]ÅX‡æº&<Ö¨7àô&s†GåÃÍÈñv3®¥&|”™í{Ý:Æ;½)¹”Gôôô ¤R)Ó4Qãêy†nBtêºM{úé§5MSUÕó¼F£Ñßߊ\ÔÂÀR”¦iZ†ˆÖBl¡Z±JTð‚En¼qMt2·Þú÷äV‚Àl4n¥\.Çãq¸BFÆÔhr 8M±X,ŸÏÿå_þeooï]wÝ…­8ŽÛ¶mZN5MCuœðúº»Ö]sí5¶–e¥R©;wâ(¨ŒEÒ—’N§-ËÂh0\„2ºk¾&„DãÕ ÍaFˆÿÄ‚Læ¾ð3øÝûÅ>jÂA#ÉéP š‘kØT:Lˆ›LrJrsîß©C£z'¹’“Y´©ÞµI~Ëš~g)kY€qA©T‚¥\ÿ„?œ †a\zé¥?ü0( ÔE”ª‚5ÁjkHõ™yÕUWFS- !HÞyçwǞ̭·~õVòUòÍI9C!Ìmÿ2úõBÈüÏë>wlù,˪V«Ñ°n”Aù¾ÓÍ7ýëwþo¾éæ›ð�ßX,µ«^sí5ßøÎ7®¹öšõß_ý ×ûY©išaèmÅ€3ø•ËeŒ‘¯#.íû¾eYëÏ�q6ý¦E*‡~,éL—bªÏ‹¤YÜ¡O©Nã lì´yú8‚€:šR©c<ÄQA„¨Eïd"º8Pã*Šb­VÃäçl6kš&‚™ŸùÌåèñàyÞqþ˜%„躻暫ÁÐwß}Ot2kÖÜxû7¿yÝç>Ïw°¬eYº®+ŠR,Ágš¦õööÞ´gÏ¿ÞvÛkÖÔj5JUUãñx¥R‰Ôj†ÿöoÿ6ùÕø×ÛþÈ ×^w-ŒyQa‹aŸ¾üÓwÞwçW^alƒDQ„gP:îëëƒm!6I¥R(§B0õP‘ ðì†jÇr'ýf‚Êé-2½5ÓVÿ‡1‘?ƒ¥Ëôp$?â¨/Ey-Rz ½jµýÊG~èhÀ0 “¥Ñ¶¡( º/FÎäBèRUÕ¨6¶A½½½/¾ø"œß¯¹æj¤W¿÷½ïó›·ßN¾‰Ð(( CìˆÖ‚« ]×½å–[þùŸÿ¹Ã¡¡!°&N>‚«¯¹õ8Š¢ æLA F€¶m?pÿÇW_¯^ä‘^…^¬V«’$Ýs÷=×ßpýÚuk¯ûÜuA`¨µeYõz}pp0‚l6‹gô›âla¢„À/¼Šq#º3 ‡Žúÿ¹¯§GÇK]ÍÈ=šSO<­Wof³§”>@FÙ¸z½ŽZYØÔ¥R©J¥‚*Ô¹B Åâñ8‚™P¢èúì†ê\èQÃ0"ÛtÛ¶ÇÉårð±C•©®ë®ë^qÅg !än»"$Y !ñx¼\.³,ÛÙÙY©T-ZÔßßñœØám·Ý†z`\‚,ˆaàÒ‰F¤uwwçr97ÂË¨ë ‚àû¸êê«DQ¬V«vh«ª Ó cAsK:)F®÷™LÅJhßDÛ«ïû¹\NEXÆb1Xà¢SJ´^¯:¯Ú‘Ü9É•#KvŒz2˜UÖœp ›¾a’+´vò¼ü¿®É·WÎø½nz¬é}BŽîÀÑŠh>¸<†ô]Äb1h/øÆuttìÝ»—eÙ‹.ºè—¿üe±XD;#ŠkTUEŸå=÷ÜâóŸ¿Áó<Ó4!jA!(Ÿaæ¸ãŽƒ,Ã0ðÙTM$ÃÃÃ뺾hÑ"Ì<Ùºu+J‡ bÑEJAm0Ã0¥R)НÂЇeÙ‘®{ X°{£ÑøÂ¿Pð ]ÏóPÅLØ4J¥rÛ¿Üvíu×r÷_û‡¯¬ûʵ×]YFà„]×…c>Çq+V¬xî¹ç†‡‡u]¯Õjè|Rˆf,qŽ—Ýï•£òÛ8Õrƒü]žpÍ'yS&s_¦w¬)á¿G‡å@“Y©Þë¼k”&ÐPm<Ïçó}è?Ù³gÏ‚ Ñs‰ÁX¢(îß¿c,ñ‹_À!òH$¹\NUÕ›o¾©Z­‚Mƒ e­¦ª²,_}õÕ·ß~;ìà4‹Š\¸™¦É²ì'?ùÉŸÿü犢8޳oß>„mÁŽº®ƒew+㸎ãÀ];¿Qõ·àZ˲0"´P(  ÁdÔÙ¶ YÃûMÓÂqa:g8÷ÂKAUÕ?üápæC([’$ÌAC(éÛÖ –{s’$Ù¶­ë: ðã¾xñb˜Öâ?Ï>ûlžç5Mëèè�•¢•o¨V«è_D³&*Q%IBAP4EýH[‚P¿ýío ‚€ +Èa^ˆ×X,&IÒ<�“?˲pÃ0OË‚À`S�Þ+7}ìc`MÂ01ØâiÀ÷ýEQЋÙh4¢A+a‰ã¸Ï^ñÙb±gƒ¿ùôß@³âTƒ €i-5<ÏK¥R .„©}ÄеZ­V«‘áqJœG$@ZŽã`¨1áÝ ±…)Ó¾ï/_¾|Û¶mK—.3-]ºêºÏ<(3d@mÛ F>´ÑÍz½†!Žˆ"š zzz`~K´fbJ6”¢a»wïF‘*Ø$‘Dô}ÿï|'*{ÆücŒØô<¯T*a‡årÍ6„¸Ø#G‹ó1 F ˜ï o ð„Ñ›˜ô‚öx2À'¡­­- Ã\.‡‘,„TZÁ?‘Hp—Ïçãñ8%N Š#©TÊu]ô“@i¡#©1œ¤V«AðÌ3ÏH’ôúë¯'“I×u7oÞ|Æg d4êS„<¦F÷ôôÀ'áŒ3΀ÄDÿÆ—¿üer`(2© ÃìÙ³' Cõ ± SBhÆ÷}–e—,Y‚~Ó(MȲ,Ø DøÛßþú„0âÉ©T*£·†õ x$>!‘†®ë0©WU¶ò®ëž|òÉ =`$/Ëå244žàäçû~gg'!z×›N§ !wÝu8µ5è<ÎYÇúõëé"ÐDA1  ð3#¶Eq Z5@ È#Âp•288µ÷ÄOd2˲À (É ‚ ­­mpppïÞ½(ÏÙ¼y3XBsíÚµžçµµµ‹Eø ô´DÁŸðb6›u]wß¾}¢"® #Ôæ v©YHX 2Cj¶§§‡²uëVt 0¸Ñh ÜIÓ4™ÑQƒ°j½^Ïd2¥R Ï®ë*Šòꫯ":‰+ I#7ÜÖÖ†î¨êZ­¶k×.´ à¡Á÷ýB¡àûþÍ7ß ¥Äy˜A§ÓDA1=A€a[PE˜4Y¯×Q ú„1:ºG¢<e†p°C ìXY–Åb°b7M3‘H„a¸hÑ¢-[¶ð<¿lÙ²^x­,zˆÂ$Ýu]´¬ìß¿_×uÔï”J%Dƒ‘h4M…»°VK¡JÄÇÑÛºu«¢(ȉBËÂ;á5ß]p$J^MÓÄ®07GDÓ*è•G†aÀq0‘Hà”ïE •qDèøJ¥‚ bSâ<œX»v-]„¸ì²Ëè ¢7ˆb<|ðƒ|衇P´ß�GèKLÁD¾óÒK/}衇ÐL‚ÖL(?–ýÿÙ{Ó`Ç®ò\øÕp4ëH:C·{’ÛÆØmcê’"E%p}•@ŠJUBBsMœì0xƒ¹`‚݉mÛ!vع\78Éå ÄõE„ ùl'„¸ÀÁ±ìö žN÷5gÐ÷ãi­³ö¶öÑ‘ttN¯·\.µÎÖÖÞkm­g=ïð¼~ÈìA{ÈQ­V}>_©Tâ‰'PÍòƒü�=,ßõ®wÙ¶½²²6699 xÆ%¢Àð+»¸¸xñÅÏÌÌ îæ‡ã‘þ³ººú‰O|âž{î©Õj±X EZÓ÷¿ÿýL&ƒØ$Ú• É`ÆÜ¼è,)vä 6t6Cðãƒ=kÁ677wðàÁ'N ·¶Ýn'“ÉR©Äd{K¥Óv‡Ã^Yà4lf+õí3d&Șlßüæ7|ð|BÀ©1ÉdnXŸÏwÅWüÍßü >O #ú<Çãñ«¯¾úÑGEpë÷û‘„s‚\ƒÁt:ý¥/} FFã5¯yÍã?'0\µÐþ.//?ÿüó£â²™uÚVß}÷ݨïDa%:º<ùä“€çt:�À %4HnÂWàf‘F‹[FÙ%²dÁJáX†6=Î;755•J¥ …2Œ°ù€“–y§‘6]û`0ˆRWœféE;zô舀–™ Ÿ  ÙÀ„àž… -k@ Ç,BzO<ñª8@(S©ëFéóù}ôÑ©©)ÐPø'¡W <833S.—¡ŽÚ±±±þð‡è\æ÷ûÞhËƉ_V¦’H$ÀYÇ’v»}èС³gÏ6›MÐÍ×¼æ5ÿöoÿ=<�9Z‰!š‹Ú&ï€T#ð]ÔwB§• 8?rtãñ8‚»@�òèe]­V8�mB éêêêÒÒÓêƒ< F"‘T*y®ób²j3flt³Õja•Á‡o dzëЪÕjsssÙéà¿~@l}K½^‡|ßï÷ûý膄#" »—ï+훟Ÿ_[[RÆb1ŸÏ‡.f¸ª§Ÿ~š|Hüyì±ÇP₃›Íf©T[…1¥4þÄ}!H‰‚dÆ‚ ¦R©7¾ñðf#ÖÛh4jµÆ'‘HÌÍÍ+g2™Ë.» À0dî£Ñ(šf£Í6Ài̘1cÛÒe£NÉ?ÅãñR© …°Ö#¬‰D³³{÷n”— +µÕj-,,�ƈhee Ø@2 5 @Ò|s‹hh¹\fÙ¹©T §ÑìºÙlîÙ³=¥—––p% òÿk6› ÐÀc\ ÕœPfˆÇãò'¢ù²—½lyy¹T*1æ!T ÝÚx<þØcÈ4ð2™LÞzë­P¸…/Lý'?ù Ò”O;66U÷¥¥%ÇÇÇ1VîÖÝU+«f Ý{³Î0:Öº®ÂC»6aRx5vþÝ‘½Š¶•àûèLr.< »+}½ßØv4x2÷íÛ÷²—½ì_ÿõ_ÁÉšÍ&JáÉD®Íòòòüü<¤Ï+• ¸À F"dÂÁ‹¿–J%´Á;¨Ó‡Ãh.‡0>5>>®¸â "ºýÓŸöxñ¿ûá·ü~&ÄäÔWWW‘© ÉD4!þ‚ø¹Ï}°ý“Ÿü�Ö+(ÍD㩇" ‚¬ápxyyùŽ;î@_¦hÏ"šhÖ12~‘Ûl6[­Ö—¿üå>�§üãìK óÃîïêY{í®§Ú®#ÛÎ\P7AºáUÓÃùmS6<ñÄ€ÀåååJ¥2==]¯×á;m·Û™L†) fŒ R>gÏže2CL~-D i€bGxhY—.ð0”ŽÀõzêÔ©Oß~û¥—^úøãÃwŠ$#hô@!/NŸ9sŠ€¾Ž¤®9HÑü’Õϰ¢OD=WWWgff@£Ñfqq·u!0cœŠI½SG9nd¿ß"d ¡W($y‘Ó� ¦‹.ºhaaa÷î݈õR'ª«ù7¿Fð¿g¡ñ¯ð'ÝÁò_uoŽb)²-¡S=©<�ý7ä[ÞF ñÖNrÜ\Ð Èñ·Ðu.¶×ds1dîƒAÐGè@å(ñxH�d2999 }> Z¹\d"Ãhll Ê�`xˆ€²dpY82 YhMOO¯­­ÍÌÌ<ùä“àˆ©T Ù=p¼å-o™E�®W´ÏÄõ £²~¿Ò} Dªðx‰MÃoüÆo@Ó�»wïf'H…E! DˆànEÚ0`8 ¡()TÞƒú ô‹Å"®JIœ›N¡u×ß¼ò`å_Ý?2RKóV-Ê®Âåzºî?t˜þŽšµ~ª™  ;ù˜œßš‚j„åॠ›E™#¢z,ƒˆ6V«Õ&''›Íf&“™šš´¬®®Â]‰†_@`Ì©S§€Öår¼ ÞQDLYîR2™üÖ·¾…¡n¸TZS‰D&“AËk"BÖëÚÚÚ#<‚„aÌ}êõúC= z¤ •Ëe 4ŠI�ŸhGŠ@&dËår£Ñ� "ªŠ«Žb W0€€ß«_ýjÐâ~'¿¶êz)‘O=oÏGÐS:äK]äÌ}«¡<²ë©vÆ¢<j;á çÙð†èf×7GÓIc¬7K&“(7,‹pxf2™ÙÙY¿ßÿªW½ ¤øµÕz½>;;Ëܘ@ˆýû÷×ëõ·½ímÈkeu,Õj•5ÇyˆyFDÔh4�ÌЀeï�Sñí8!´ãQš266ö…/|Ø„7µÑh Dgáƒm·ÛãããP6@�òðáÃHqB©h&“5,—Ë—]vÑD„«]í¸2`¶¤V½ýíoÇ·/,,�G“É$ʽ(c}ê©§šÍæÜÜ\?SXa{óVmè'=úK€à ÜaÄhP™­íëÅ_Òs$R7A£ì¤1ÖƒÍÍÍAWozz\pqq1 Öjµüàè4O,òe¦¦¦ÀÁƒ!÷ è:qâD$ùû¿ÿû={ö F©< ËÄÄÄòòòˆ)°ž^øE@ñxJ~Ñh´^¯/..‚h‚®A©�­Á.¹ä$Ê‚àþʯü „vÁJÑS¢z,7H¿ººúµ¯}:…(årÞW ôSO=uÍ5×@Ûavv* „Çì3.//ïß¿®æx<þðçR©h4Šd¨r¹Œðg$‹iDD”N§îªuÙæ“¾…¯—Ÿ´z:"Ð2üuÊû~¢ë‘ÆC;"ÎÛ mÂÌ]8g&ËšAÂK£Ñ˜œœDœù>ˆM®®®B=î™gž¹òÊ+‘4 W*T~Nœ8±´´„ÊE¨ñ±ÞÑ~¿¿R© uÁý~ÿ+_ùÊL&Fý×%‚ØB«Õ‚\-á2ž~úiV¸OÿìÏþ ‚AHÀ6#¿—  ÇK0DÐD9‹Ž ‡Ã>ú(´ô€¦p>7›MÜJTÑãzffß¾[¯×ñW\ <´ §R)Pj"ÂPlpº¯Î^\RÛb§¬tYo£=¾ñæÈ˜ËŽÙ7c`ò‚µn¸aee%‘HLOOCÜ9>»wï>uê_Á8„³ôMoz=÷Üs>ŸåЮ¬¬À…;55ð�É{ÙË^Ÿh4Ê'Ñ ÍUž~úéF£Ñl6ÿüÏÿ¼Ñh€w"¾uº`0øË¿ü˨øŒÅb È‘ DD‰DÒ<Àix\‘׋Åà7^^^Dÿ2Ü «^M$p®¶Z­J¥‚6 H½¯®®Â}S"BJ0!q ™ÆL)©U­V ŠB@tpPÈÍop*ÝG.ð©ü«œUozï#æþ¦Ç©嬿3A}¡ªÍ �� �IDATr!ŠÚaè¨ÕjµNŸ>fË ^333èX MvG þ1¶ÇtáÁWWWçææšÍ&ÊNB¡Ðµ×^›J¥F(í»îºëÂá0 CQj‚ŠÔÀi ÀN¥R­Vë/ÿò/ѰñK"L"ç—~é—À¡ÞNDããã¿ø‹¿ˆ>ÕKKK©T ˆ$c­ÁX×î`0øº×½¿kkkKKKp±–J¥d29>>žÉd@¬Q‹‰P+_!‰Döïß Q-êóù>ùÉO2É@ÈÖjµùùy/Sô¸ ¸¼Ùõ�—%{3_±å+c×Qæôüæ†îeÛ-Ç[uÁÞç¢ë¤xŸ –;ÌVWW'&&ªÕ*ô Ž?ÎÚ†€Z5 8!¡Šà÷û———ÿå_þ¥Ñh¤R)G¢cccðC‚¢²ÙlÞqǨ…O U¯×?ÿùÏÃOËÚ› ÝD  á°l·Û³³³HäkDÞ Úùýþ‡zÅ!ð·ÛíÅÅÅï}ï{Íf“ˆÐptbb¢R©d28‘"‹Å¦§§Ïœ9366öÌ3Ïd2\RåÔl6á­Åu&“I$è2¼\XX@'ð'N€¼BŸöÈ‘#p/Q*•5gÚô›ÎÞܘƌ3fl“À‰—ˆVÂiX[*�F»ÝFl²T*¥R)ÐAtÖL¥Rhø…„¨ëÁ‹ bǰ¬®®‹Å@ €ˆ#¾emm-‘HàHxAAX"òíÙ³z ð¯âTs"Ö‡*®DE‹Åb4ÅMAÀ_GD{÷î=uêBžóóó�rl#Úí6¶xïBÃj `|ü~ÿ®]»ÆÇÇÑ€ )ÁÅbÍU�´ƒ{œš>»j›È˜1cÆúb—_~9òz *�Rˆ$ÕD"Ç‘:‹â t;AQãøø8z‚ÁàÒÒº]²*%‡Ã@;Ð2$ÜÂÉÉÊFWWWƒÁàÂÂÊ1‰ÒµˆhÖj58„™ìN*•B˜bëÈÙЀR’_ŒF£Õcx‰Ð©Ïç;~üx¥R©×ëår±Uø{ñ�~| þçR©„Ú�*سÏç›››Cc2ø´!éŽ=B­¸°­N#Yb̘1c}±@ pìØ1´Bz&“)•JPf¯×ëµZ )?€.H°"yöìYäû�±˜ëîÝ»:X‚[… ‰Á`f,//£¡X³ÙWÃa—_~9S…çÚ¶D„J¤¡‚z¢BzôËËË“““7Üpúcº …„Ìat#¢~ô£­V %4™LáU$Ó‚‚C¨\.CíÂ]à´Ð¶E¬”uÏ^\\Ä&�rð¸ tmÌ{™ÓsàvôèQ3f‚ŒÛ¨ÍÎΦR)¤˜‚½•Ëåt:V$L LUT(B6ö-oyËßýÝß1õZ(¾V*•çž{Ža$ïEÈAÄz½ Fo²V«t ƒÇ‡*T„�–@ €¤ìЛzuuõܹsèz šÛn·«Õê<�)AÔ–  2u‰jLÿàþ`zzznny¶ØI@°Õj½â¯xòÉ'Ñ>ìܹs“““�?Y¡„Æœz`WˆX,tˆð‰ˆéøø8Ú“àÜz3Ý€Í3Öã„×"®pH†B!ôñ@¾\H«YXX@_I(Á~ûÛß&¢jµ zšN§«Ùlöĉ(ê@¿h@ ˆÙ4 kàŽ,T¹gÏžùùyäÔ æjår¹R©LNNV*H € ¢Ôn^¤ïÆb±jµº¼¼ ø[#ôûý‹‹‹h7íóùJ¥î¨Õj<xp~~IL@àé§ŸFÎòòò®]» «N&“gÏž¢Ã6þ†JŽÜ‹‹‹¬§V«ÁWl€s‹íž{î1ƒàb×^{­™ 3AÆ”ÆÀ¦^¯' ”!V«Õýû÷C0®N$¼ shQ=‚Ÿ$d{êÔ)¿ß·¤ßïO$HÏA¼YBP£E2Ú^¢g$9sæ T뀨‰|ùË_þÌ3ÏÀC …&&&Î;GDn_XX˜œœåe¹µÉd’µ›ÆuâF ¥€“œ>}š‰ä=ÿüólL@ˆ¡Ò€ +˜1®iDè× �Æx‚ŒB ÚîPèÅîáÀsss p6³•ÆòÍ™ 2&0:vÚAˆ T*Á£Èzr,‘‰DàEЮT*ÒE£Q$þÌÎΜ@ÂÐq߈â–Z­–H$Âá0Ê<öíÛ÷ / r‰o@ÚíÛ·ï¹çžƒ¦n£Ñ…B@ ´ -‹‰Dbff"´H¯õûý¨§l4+++ûöí;sæ Ú¶ Þ±Räû@H߈Ð,dXj0o\!´ï#‘JBÑO ê»\`{ ¸HS{á…Âá0ZÁà4KψÚÑ£GG´Ìø]°†¼Vôüf ×µˆG")…•Åb1™L.--A¯gjjjvv–)õ�xp8~! ¿¼¼ l.—Ë ¬“““ˆ†Âoyüøñjµ:>>ð†ê<®HZXXˆÅbÈËe¤“ˆà#Ü‚ /,,À ï(+¸œ››[YYYZZ‚âÍÊÊÊž={ÐA¥ÕjÍḬ̀ô%Tà�PÑq¬^¯ïß¿ii) <y*€L"‚Îv¸T³ &Šä pw¤àz™¿y:3fl-C£g||œ• €‰¢%ÒDQ’ˆªb±¡J¥R©TЄ ¢ø \—H²­×ëRBÇÄ}N@Å¢Ñ(}¦§§«Õ*믉Œä ¡¸…:NTÆ&!}çóù ¨ …EVp¥RA2† H‰D–––n\XX N[iph”—D£Q8‡‘* àD"×]wî1‰¤R)øx‘úg/†ˆˆ€Ä�ìt: ôÅ`BÏ�§1cÆŒmW•ŒÅbµZ nÉ@ €$òƒkƒ#———S©T>ØL&ƒ`$Raá­…�"Žõz:ò¨€¬×ëP΃ߑѕ••©©)�O½^ß·oÈÜÒÒ|› ø+R^'&&Ðÿ„ª²pk¸NêÄáØ € ãb0@>œú(ƒAD²>ø`:žŸŸÇãµZmß¾}ˆÔ‚¿ò•¯.¢ôsÿþýðƒ@³+á¢îÖÝUk4 ¼ŒÉGIîò(¼©ëE#_¡÷Sm£‡a¤&H9º‰P6Ýìa®ÍvØÚÚrJŸCÜï8p`vv±:Ôw"XX©T@@ÛíöÊÊÊòòr±Xl4ét|¹£àXp`2ÚGDP»}ÉK^òôÓO#P ÇæÂ ò…^�%…㉸±X IL333Àr„áUFf½^‡Â‘ á‡¨'Š/A},•J¨‰D‚.ŠJƒÁ h%k^†^.Éd.\tIc¹H?úјôR»Ý>{ö,:É )Æ-â ãÜá&÷ Öµ9ëÚKµë©ŒÚ{°ÝµÓ¸ @ óâÒÞËùmGCxÔ ýŸWívûÌ™3èïÂG–"„€‚�œ@3µ¼E0 ^sÍ5@_P4V©‰P(Ò‘�~P¦è~æ3ŸAjJ\jEm Î?s$4ö åS¯×'''×ÖÖfgg‘ )’xQßràÀü¨333@MÔ¤®®®¾øâ‹Éd­ª«Õj¹\+edêHq‡ÏšAìu2™„êl¡«à19È¿Ñå€oÈ wÏP¶ÔŽw9r!I¬‡Ìf¼|]×#uýj\:$› êasã>€^ÚY VºêÅƹ¬ÑhÀe ùYô¬ž™™P¡ –(@„«“©ß!q]©¡+„ª$¦V*è|ûÛßFXôMozÀoee)<ÀÚP(tçw"op»¶¶vÏ=÷ 5Ô¶V«}+•   øFQ‚Hm,‹ÇãÑhtnn¸ I˲À×ÖÖÐPåøñã¬;&ÊL f¢}Œé2ï.b½‰D*zàÄÀZ >„NÅ@" ÑhÔãÇ¿Ñ%›ßÒzÙó²7(Ýî»ã-ïâ$l;¼4óxªmç˜Ý^d´£j&hgJ0ŸÐžmµZW^y% ?>øÁüP†ˆLW¤ !4ˆã§§§Óét±XdÈÔ …�H‰D¹¦û·{ñÅIE'“[n¹µ%p¢¶ÛmôÄFµL»ÝžœœŸCª-¾¾ŠÅ" ª¹ð©F"°[8Tï¿ÿ~$ñŽƒ•¶Ûm@>v�¡Pnj¤£7ÄoáŽÅb¨„‰Ç㸯z½Ž®¢È÷ ƒ@ÜH$ràÀö-ét:‘H@ãå+ÃvÕvuî<Oé–Üšà¾sÙµ(ìzª±(ÚÎFøðlxCt³ë›Æ©¾c œ/‘H@¾ X,F"äÑ,//ñ‹_©‚#”é´Ûí]»vµÛm Ôââ"~Õj5•J1QYêÄP¡ûÚl6'''Oœ8Á›ÐðC) ăjµZ©T³D-º€…B!à7b®,'#`¹²²7/+Ð+™Lâ¯(Ãn[T†€õA!ˆ`*êY‰B‘U�F‚ŽGÖ.ö@ N¯­­ÅãñJ¥òÌ3ÏÀ©‹h(¶íŽ 87ú»Ýî¿pÁ¸ÃˆÑØëlÕÎF‡‘½9i74A&ƹ“¬Õj]vÙeËËËP�¼5 Ôo ó«Æ�;¡ê‹ÅÐGxƒHáêêê/üÂ/„B¡ÉÉId±®¬¬œ<ym)™ïÿ"=)¾ÀBS"îˆlU #0 ýLÐ:òàǨKØ/..¢™(® ŽbÜ ã“†î ŒBö蘮Ý~¿?™L"”[,³ (ƒA¥ :c·ÛmŒá7Þ­ÚÉÉÉ-�Nôl”9mShþ:ÕÇ­‰ñÐŽˆóvC›03Aˆ…B¡'Ÿ|Bp©p8¼¸¸ˆI4G”išS§NîHœAÛgÔ±‰‰‰H$òº×½å’HmM§Óããã(>™˜˜ˆÇã1ˆÇãD411j ƒÐ|³+++HO…šy‘HdÏž=KKKp–B´obb" ÍÏÏC`·ƒ\_ð±±1ôZA- + EžÀá{©Ó€ ‘Kô¯%"F‚—Èœ‚÷é¾ø–@ p×]waÀçççG®ŽS·"lGÞ)¬\Ûno¼y#2æòÞQð0˜¼ 1KK¥„‰Dâܹs~¿~~`‰ÊZ­‘9bBßgïÞ½5wd«ÆwÞ ¹Z„*‘_*‹�žZ­†dŸ¥¥%6ê$¬Öj5hÇÃK±¿F£Q.—S©òránE±i"‘@·/œ*Nã® r} <}út4ö>Ñ‚ ŠºL”·®®®ÞrË-È* ƒgΜþ ãÅââbµZ­V«èʉŽÙ,Ћq†Pð“ÿÍó D²KjËãO;À)Œž÷7»žJ`Bb7A}¡ªü Íoj'´ËÃáp&“U\MMM­®®¦Óé`0º±±±t:ìPÔe3^|ñE¨ÖAHUÿsss¥R©X,6›M|*‰ »)©€¨L&ó™Ï|&‹ÝrË-pl"6 ,Ê9àS…(œœ¸Nh °:(öQ§À† ÏF"\"‘ˆF£�-d­®®¦R)€1g@&"©H/ªV«™L& ~úÓŸFn0¨'ŠPˆ(•I$ÈL&"æ|Ò£ù rƒA[»ZÐã* ü7ôZùÞÖ?lmáôüæ†îeÛÍÚV]pϼ—ß”ûy Xî0ƒÈÜÊÊJ±XDh¾YFû ”T•ˆ&''kµÚ_ýÕ_½ùÍo†l:þ„Ö•@e8]›ÍæÌÌ ú|ÕAï¶Ûn ôG9žÉÉIVñ f9>>>??-=à7\ÊLÎaDdq¨+ýD~S©T‚ÿ6 ^ýõú§ŠÖx<‰ûE0–„8n±XEìW…qƒòüÏh— U^ŒÊTÐ$‰H'„«ÖPcÆŒëÁ�hžuùå—/..¢¹“)G†N<Gt´ ]ÀÚíö;Þñމ‰ à Ó=1E<|.‹%“Ét: áxVä Áõ ¹;�$ö={öÀO ‰äâ×}>_&“a„ßÎÚœÿÁ ±YÜQ<_YY¹ï¾ûˆ¹H¨Šzyy¹Z­"ý'£É S{€fo,K§ÓècŠT)´[A:D+++è)†}$Ðò„u$€ÓxŒ3f¬C—’ÅÅÅ@ ðŸÿùŸ@àg~æg@Â|>_­VCÎŽÏç«V«P6�Æ %‹-˜+÷¬V«hê hA8“ˆªÕªßïŸE•' å((ÒH¥RÈÖ¦.--!ùÑDV<ŠÝF£nb¨KA'NÀÝZ­V¡g›N§§§§§§§¡£ Lϰ@à ½h½‰Æ&HÍEoj$%!«ƒ�y^FLAÁ‘R‹êOørqã¸wÃxìÇ9Œä m=k̘1c[bÍf3‹±–¡PèûßÿþwÞ b‹ÅΞ=KDèçxÒ@E“P‡TÈåÄÄD,#"”lbYN§ÓËËËW\q�ÄŽ\üõ0,–955U«Õp`“ ‘ÀlÀÛ«^õ*héMLL õ}1¡¢033çm£Ñ@¥)¾¡ÓD"> *¸#ÔþàïÅŰ =Òˆ K„<)À$T“pN¤PµZ-Gq¿H÷õä 0Oç íèÑ£fÌ3¶Q;räÈ-·ÜBDè² âƒ*É]»v:u nØd29;;‹$ d±"(ˆœ[4¸N¥Rº$“Ér¹ G%ºˆÄb±Ÿüä'ñx|aaù¥år9C*í(J‰ÅbÈŒEÝ !agii ³à—=öhêõ:Zµ †òx@àꫯþáˆ*UôQam®±{€À\ÖPB@.=øùŸÿùüÇd(>99‰kƒn0‹AêÊ´ Å ªè9Þ j€sëÍt6dÌXvÇw ¦èóù&&&ï:??ìÙ………h4 ï"RoX€*¬ðÇ"N‰ŠI$þŒAQU%à¦PÑÛ»w/ÚÀã iµZÅù›Í&\©À'\$®@&\ ‚ hœIDápøöÛoÿÈG>Òh4fgg@µZžžÞ¿ÿÌÌÌÚÚÚ“O>IDHsEºðàÈÅIÊå2ò›�œðúÂMòù<tªÕ*tçÇÇÇK¥R سgÏéÓ§1p#wÕ2¸`¸s3™ ëÝm€s‹íž{î1ƒàb×^{­™ 3AÆ”vîÜ986™œ ôíÀÀ àsâĉÉÉI&‹®Ô ãããÑh5!ð‚‚Ã2S©ÔÜÜÜÊÊÊøø8| ÎƒS±"ôt�·ðú"•\Üt©Ü”Š"Úh4n¿ývPC†ÜËËËÏ=÷‚ ˆe6›MÔ•"÷ˆ8??:K8r¡À@D@q"j4û÷ïÛf½É’ÉäÂÂÂfffjµk‰å›H£q[»Ýž››K§Ó¸5œ†ÍŒ´---™ 2dLiè[¦¦¦× B ôOBiøK‘/ >ÊØjZЭÞT`:Bãl¹\î¯ÿú¯‘ ¢ ½øâ‹ßð†7üÅ_üE³Ùœ˜˜€º:⦬ø9GPKصk.8Cx)q@¯P(víÚµ¸¸ˆìÈ5à–ádF OˆÍ¢'ªnÐrðP"|á…À€!+¯r</‹È.‹…3™íˆ Æ Dµ pš¥gtíèÑ£#Zf‚F|‚.XT«UȵCš•iÑù|¾}ûö<y%üD„$DÀÌ@Ë[W'Â{¨øDË­`0øÿð™LÎP(¨‹Åb333_ûÚ׉D(B©%()¸Ôþ „^%À'ˆÊ¾þõ¯ä‘Gp%�HZµø|¾b±=?ˆ¡û 2ƒ@¥RAÕ&*2‘O„Ý�jWÀß|óÍGŽ—Q†xË?Z]]=pàÀüü<n]µâÎG”GÆiY3fÌØ(ú‚A©y­çΧ¬V«ÉdòìÙ³p‡+%¨â‡š]¥R]¬Æàø]ZZÊf³H#BI%Ü­ÐF�lµZPç>A|�ÁÔ;ï¼3 ¢Èp…fdLZèÛßþ6ÊZsÅí°"α±±T*…k­T*@bY¢ÈýÂR©â‘L Ïs$Á ßwÜqØ$*d¼eG¼U1Íf®iøÀ‘N…‹GÔö0Ài̘1cÛ˜q¢ƒâ—(¦„uœ(É�¯BÆ,ȪMfff@þà“„£1Å`08==}òäI"B‡¨àêÀ½@Å % @œœÕ ƒŸúÔ§.»ì2–vËÔ|@|]\\âˆòÀ%»²²rðàAˆÀç<11P+½òÊ+‰rBÐF�^Bª~ív»\.Ÿ={–ñ]„rÁÙ‚=£) b·ñx¼^¯c”0D`Õ(/ÖÝU«T¦ÎsÃuÿnÕí t””w¡›;y`·p–7zSúà–Ü ËP+ðþ¦±`p½"¿tmm $ȳGDÓ$㌕Ëeˆ¡Š||n[ î¹sç ºÎè®]»Ð«„;¿Do/8EÑ®M"ª×ëÀà7¿ùÍ_ýêWQï>Ûp½²8+Rd—––‚Á ÜÂgÎÏϺ ò2ŠÓL]¨Z­þèG?B·là@FÌ88%ŽÁ72Ï6ês°…BµZm||uœ¥R©R© ¤CН÷œ^çðE Ñ·kÑiÛýwÕUÎPy³^Z^¨ìT±Æ®Ï¶ò�ïoÛÖh4�TPU…DÜÊÊJ&“YZZQ‘Âùý~¨@®Ùl¢š_Žår9”K¢€‰Bpx–J%dÖ AÍ w.ß›ì«_ý*RaÄpÀémhõé8‡Q‡ ƒz½þñ|Ïž=�T&<‹ne~¿ÿ§~ê§ÐÝ yF±X !Þ‹.º@FñY|0"1×V«µgÏr {µZEæ’§�Æèk†Ä–¢ŸÀ©\¯…r/$þM¹Õ†÷þƒXÐåž]/ÏËM Ó¼‹Ð¦ÃåS#ÂØd°9÷÷7ú€36‚‰DÀœøâEd«HXB â¨E hEF¯¼òJDøUûðÃ×j5&¿°AK8N&“µZ /˜€Ô…ˆ¨ÙlÎÏÏCÿqJðÝÝ»wßtÓMHðI¥R¨àCÉ ò~ƒÁà»Þõ.H D£ÑÛo¿ pÏ"é7 <xÐï÷¿ð 8ÿ;Þñ°Rœ è_J¥À¹ÑFmvv*€¸r\QåR¯×ÇÆÆÀ;þd ©‡H$â±gïÀ©¤òž­Äø¶b£³SPÓûFÞý¦vŒwD|˜Â?ù.uüõ+ßP1cÛÝPn_"±š ó˜N,þ_¯×®=E0òÇ?þ1ôc¡~P¯×ÑA¬ÕjµZ­J¥pB¬1HpJ„NyÑs¿ß?99ùÒ—¾tbb"™L¦R)24›Í¥¥¥ûï¿ÊvKKK_|1uJ¿ímo{ÉK^‚F.kkkßúÖ·B¡ Ry, ˜ˆ®¾új"‚Høn³ÙüÆ7¾ñÖ·¾5‹á®‘�…úÔV«w4b½ãããÈ$BE) Œ=ËÀGáÐ-Îf³«««ˆò"Y×ãÔ7ºœ¹7<Ü2ÚÇïºÐäæ•÷ëýÍÑ1—vZí<ƒÓ�†JŒH$‚T[¸%C¡à|naaI.Ìý…¼F£‘J¥PL#CN&`lP‘eÍ®!†¾¸¸,AÓ€ˆ*•J"‘@´õç~îç¾óïƒÁÙÙY4ZYYY9uêNuæÌ™o|ãìšÛíöÒÒª6¡„ÀÔ‰ÄÔÔT¡P@Ên,CºììììÞ½{ÿéŸþ) íÝ»)²È¼Åõ£’M=ÑÈ‚½hd†~a ¿È1^]]Ý»wï¹sçpÌ‹/¾ˆnØÐ°õX‹²àto Øó²åÅIKÎæØÆ.„­C¿€Ð�ª±ík¶m»üõæ›o��Qæê†×¨è‡k*•:{ö,P6‰ \ §ëÄÄÄ™3gðL¥Rõz}ffm8Ì@Lülbb"ŸÏ#£ x†ˆ¦§§‘ƒS*• R‹BIÄ�ägá.•J4¢pÓçóU*•‹.º~]–¼ƒ†-Á`Œx911qúôiÖ[»R© µ òŒ�¥è/ö«¿ú«_ÿú×™Æ=u"¯ñx|jjŠõŠépnÈí¹yq!cÆ…<òµm2Bi6[ÆvªÝ}÷ÝCþÆ÷¼ç=¬=µßïGå%äд^¯'“Ià˜.¢Œx ¾»²²’H$Àbggg'&&öíÛ7??‹Å= _1Š>ãñøîÝ»‘у<)5‰Ù¼LG Å£FÃï÷§Ó饥%„u¡Ø‡H§ßïÿæ7¿ ð¾êª«žzê)@5” 4<àÜFKù‚šÊȺ½jT ØM{ðÁ‡üßúÖ·Í‹„#ÄwÛí6ªhÐJ ÉGñ™û›u�� �IDATx|~~DÁZ¸¯™,‚šPŠðù|ÇŽËd2¨]–{÷Óö8aâ35¼PáH¥+Øý€~­³Ê/Ü· ØlÓ»cs¤ŒqŽò ööð_˜ê…lf6‡oø‡ØàtnÊïxÿk×Ç¢ïÏKvÉFo|ÈIR=O—é_éà¶m±&v½xïoÛf:ÅŽ¬‘wcÛ›4Ø0¶S͈ìà4f¬ÿ¤Íx)íH»öÚkMӜƌ ;Í 3fÌ�çN3¨0d̘1œÆ6`&Pa&Ș1c8y2¨0d̘±g¦‘µ1cÆŒ3¶ Ɖ~߯Œ3f̘1OÀyÏ=÷˜A1f̘1cÆœ6¡Îk¯½Ö 1cÆŒ3Æ,N¿û¶¯h“FÃ[‹”QóæUm÷KÕ]ü–W‰`¹ÆpÛMºùA™ëßF—Ç[Ðãqô£G2â;:I£yUÛýRÝ/~ ýèL´ÆpÛMºùA™ëßv—ÇÌdÕ3f̘1c0œÆŒ3f̘NcÆŒ3fÌ�§1cÆŒ3¶å¶YÉ=ÖÔ †NO4bm+Ø%ñ×¶U×9²]$·i®‡~˜ˆÞúÖ·v}ÓØ…ðÓvnÔjZÌöw”7žÁ jšGáRÍZ33il;šÌÏ8AÉd2:¢ÉóÑ>Ê/’/I žìâ‡�E.¬—¿l'(°é¦R.þzø÷…×Cž}™e²×ò‹!<.ó«›ô®ƒ9ä_͆¦r~æÞ¯MùKÐoßåärX×ÅaÐÛ\/«Ps1œ5Vùí}ºÞcœì»uÁ.Qè ÿEÊGÖûÅ“ä z|z›JM•׉åž_ú•ã?œ»{øá‡yÈÜÐ_û5†ìf½<–Ìáÿj¼OåˆüÌ7zmCø¹¹ÿ‚Ü(÷+ßò£‡¹Ä5lôÛû8t;?9h« Q9©ú”nc5Ì[ñ`4ÍJÍs»í<ÞÂr#Ͼî¯[þ£Þü% á¾¼|ÅF¯as±¡UÈ}¿8R {/)8œ_æÐ–€mg#{ÙJöyLÊvܨõ¼8zû®ó¸í&zhðsáü6ôDm÷å4¸cÖ‘\°à‡qŒFÕ6vŠ\°[7æ*t ö{y�LV‹ù-x¢vÀ ÉUËðcø_´-6Ëüe ®ï:„Ù\ð²‡íÅöš¼Üè¬máÏ|ûþFóF¼¯B쎶–kzy<ú8Ôþ! ý GSùEüÄw}2=ʯÏÆF‡×;ïòÝ !oÖû/V hÊÇrË'Ýûå¹?�#ò3W~ûˆŒv Ôˆ/#øl{ùö>òàæ¯Ux­|sKº|IÊßÕ¯ÍËø  Ý¿±·¿çÊRòéþæðŸ@÷7·j�{»f÷ë… Þò«õø¥ýú¡mùš0"‹•—‹ì×É=cÆŒÛ焇mj83flض]"5Æ”4C`̘1c[…ƶãPÆi̘1cÆŒà4f̘1cÆcjWíÑ£GGäúFçJFÿª¶û¥Ê–N§Íš 6—zá\ÿv^ßk¯yçÛ¿÷Ĺb­´øêôµ×^kvÆŒ3fÌ¿‰÷m_‰gfO/ü׿W­1cÆŒ3¶ *¡uß´´´Dv¾ á+úu‘ÛÝáÏĈõÎx`.»ØI7bînGÞ]àT·I;zô(s÷ýäCûŠþ^äöõЧÓi6Â#;Ô;ã¹@îb'݈¹»|wÌŒ«Ö˜1cƌۀà4f̘1cÆ p3f̘1c83f̘±-· W«¶me¡›ß›°ïZˆÊÓö|Í]?²îBn¹Mçb@3²3æb~;æî”7²³ï®_¿/Ã87<UÌvÌ}í€öFüìP_[½oá혹ÁŸÆNº;ùFvöÝõñ÷u2N6p.Mí]Žg³"Ÿgh̸‡Ý¢òTÃù… ç.¶ÊKѯ»Ÿ±í{;`:ºþ4zã[ò“ÚTó!” îæ_£Ë8Ê„ØP îVÝOE8¾ëû}—Ó†v‹[¸Æ ó.w›f.<ÞÅp:MîŒéØò»ÓM“™;Ã8·±õü@ óg0:w1ÐÛÎ] Îu1´»àÿ„uyw´µ? ¶|oë‡M7Mƒ^.†¼ äµ/÷Õ#p!€<²›Ac#ë¢ØîÊ QÓX—þÁm ÌïhÓÔÇÉò÷|AƒË‘áO»“ÒpFáÚ©w±~íîs‘阼‰4O”¹‘AßÝöBÍæ®_¿/“UÛ·ßÌ ~{=ŸSŽoáaîÂã]ÈûѺs¶ï\ì¤Ùª»ÛÂtú­š»>þ¾F8Í5Ùˆóaç6\üyq‘îù~ü_»ÞÅV-C»‹ gf.¶ê.†“´UÓ±cîÎåSý팇ð‚NâG³ëȺ<ÐÜÝ÷zÌ&÷x©ƒÎqô] '¡f8s1 ;æ]ì¤éØÁÛom¤ÂMÞ©qÕ3f̘1c83f̘1œÆŒ3f̘NcÆŒ3fÌ�§1cÆŒ3¶CMU{ôèÑÁ}å@O>´¯Ø¼¥Óéð�m‹¡6wanÄܹ»>šïµ×¼óí‡ß{â\±VZ|uzáÚk¯5» cÆŒ3fŒç9ï¾í+±ñÌìÉã…ÿú÷àŽ¤AÆŒ3fÌØ€LÎ{î¹Ç Š1cÆŒ3æ´‰õ—¯½æ·?ôÏ¿ýÙ¿=üÉ/þóŸ×ÆîöÚvþßÖ |\>Øîöí]ÿ¹Q³=Ÿ¿;›¨À½)h.’½(8³7rƒ¶‡WÞWAsŒÝí0ùSöF¦ÀvžÙÖ?ò·»‚Ëؽ>ŸùšmÕÔëf_û]mΈÌæ?óßÿ×n·òË¿ýÙ¿}Ç?ÿÚkÞé÷¼ŽXÜr`9ßçÍÒ¿ ïXª¯.°÷ÃTלºÁ³‹Yܹ€¨Ý9Ìêü—í¼Ès8juþŸw®ªò=f¹ÿoÔ,ç© ³[È9ï /²ÎÕßÒŒ^Vš}ŒsÒ#QpEw›;³% ¿ÉKÐb;Ÿº‚tñÊ+´TÛÛuŸa«>e;¿¨à¼~6büè ûKœ¼4†›Üÿ3fl‹\µú5Z^âEô S½I³8±‰rÜjÂÖ¬ȹØñÀ°þ‘&E5>RÐ’-„ÏòËtW¶¤Ñ°¤¥œÁ•uˆž:FW©Æ¿róÒw ¯­Î8ç ”å`PÊßTNs ä:Yò†‰½“Õj×y‘Ç9Ë/ l^ER³šœíºÕsÙÀ)0†©¹0M7é!ç§Ø|å¥3dÇXܤ í¿þë©h4JD333?þ8½ð DT©TpÀêê*Åb±õK³ÉŸ!‘H,//³¼H¥RDtÕUWÑÁƒ‰hnnîÇ?þ1<yR>O¹\¾H¶P(„õzÝå¯Âkf­V /|>ŸüWáz`cccºÆãñýû÷Ñ+^ñ "ššš"¢¥¥¥þð‡DôÜsÏQ£ÑPÞH<g¯«Õ*ÿíáp˜yX©T:¿°ƒî÷¨4vãüÇåó` Ø´ÊÂk‹Çã¸fvÎééi"ªÕjìvØ1ì«ùgƒü‘Â7ê ¿øâ‹1 W_}5Û™™"züñÇOœ8yÁSÍîK÷kkkòc ùâñcφ|<å‘HD˜÷K.¹äàÁƒÿã\³!à´K¿¥_ªÎÐùÊ%Ïî¬Yélyi‘%'ÈK¡A³z¤´$�°œßž—ÈM¾s˜­‡þ‹ø³‘óMê ¦r NFhIà'ÀOp-œ>뀬†±YÜ_- À`cÄ ÿÙœæqʪæÎÖ{2ò®;ÝŒ{ôg‡“ëNbå›Rk9‡T˜\,³*/¸xwÃb‡5‘Y2™dËV(â‹Å.ºè""ºôÒK‰èÀ'NœØµkW¡PP¬_Xhjµš;vŽ‚±]ÅÙ³gÙ›>ŸӃ̷³½›�„mÖ}Ë(…KrÇ­±ùùy"zöÙgñâáÄVcnn®^¯ckØGà =ÎÄív›ˆŠÅâ³Ï>K¤�N·•B穳9éW4ÙÅDÛéÀÌKçÜ‹÷ïÉ«­?°r´¤Vö©fU·ãpý…é0Žïx’³*¿qV…mÀç¥E¼à$@YU¸Ñêæ‡Tsš0›åœ}ÞÁˆd¾Ê,w…9žŠe‡ÒS­Ü…ØËL‘ÿ K wûÚ®Oû†Â®–ói”7sÂ÷f5Þuþi·]‚»víšœœœœœœššJ&“Éd2ÇãñD"Áo±yÈL&“±X,‹áȾ¯ƒµZ­V«­v, ™’nÊX"¿àm«yµZåi™@7£Ñè†VóñŽ “šÍf˜³P(„}Rˆ³V«µÌÞd÷Î@ãìbðþ‰ gýú¢DÇ�~ rÕÚX*t~çY=â kŸ—ݽìŸì‹Ù?¡¥â¯Y•›Q YâŠß윤IQ'ÿc'Ïy^Kuar¬Q�˜®»’ü«¶Ó šÓ¸aÓÔ¤‡8"ÎÇh³ÜÄe%ß~V5þ9½?€ôoÚNG¨­ß9Ù®Žh/s¡| Üü¼d¥''«ÂiKráÑo !\XØ@8Þ$©¨aMgnCžf1xãqd®ÕjÁˆÿ3`XXXà™·ì¡˜˜ð‚ýƒ0l†Îœ9ÓÛâÎü›Á†"7ÿ]Âð`|òäIŒ*¦¯^¯ãŸx>AûB¡ïŽÞ¨ÇÛ»%“I¥�h]©Tt_t]Gt Mä£)þÚ ª8hAò7Šër˜êä“WÙ®'/¦‹Ñ’ÄiHã ¶<ø®Yö‡$²Ò{¹!Ü[<œ9ÍÞÅö@ijÎkÓÑqKz$ Î;âç7«!y–jdòì{;Ññ¼æF.é‰ì÷ø¨Xúç_éÛpñyØšÓæ¥\ÜY—g{qq¡š¹¹9üÔáïZ^^c¤ëN,éAü’­A<vâ$­VK¨Çró‹‹ç³¿¶{÷nÕ333pùb´1þår™G†åü› é±ôoŒáÉç9»$öñáÌ‘2aºY˜ îÜ©Ç'\~œ\æ+èaÙåÃ3ëÖ¤‡œ©+ºÈâúrÐH±¬Î©xv•ãÒm=j¤°™Ò½l¹:P»Û2ª;sVóÚvMÀÉ{p`2G®­ñW뮪k–#ÄYUª­2d+çôY¸ò•äeïkgÛ”s˜-)½Hžú‚ë¸Y’»µë>ÖÂÞ–È•œ¥Zá‰å=7îì–ˆè?þã?@ƒøp]íØ±cDtúôiÄœÿÐ*3td6ï;ìõÖB…°€ÊæbÈ'Âr ,‰F£@œm aE t|—¡Œ43PÁ•ãÉAÜŽm§*•J«ÕÛë{pÑÝàÞÀµ•Ëe<HØÞ "¦°™YÐmÎdà,H‘¶¬3¥>ïô²…ƒ_Sä$¢õœX[³ß·UgÎj‰ü_ÝÙ•¥Y7“Õ;¥- XIÔ”Y›C}/ÄZ™$,ârÝ…õ¹Ì^KuU¤IxñÂã]2–…kÖͦK$2ǕܡîlÕ…ÒYÞüJ—ÇßK­”ì‡÷x¢N"¢Ò°ŒîÝ»÷²Ë.c„éܹsDôÄO(½µ`!øÿ©S§Üýºƒ¦€ö&{Ž+@uWT%ÝV¯×Ù`*§¡Ê#Ãá°ðOþy³2´O7Ùþ‰¿Fµ7Lõ«<xb5Å!zGzrÎ…€å†Xœ? —Q¢d!¶sYä‘XvZz¬àT.¾]+a§«Ñ£§œþ’l•s•\Vy×Jh¢§xW'ûk'S‰ô€JÇèçwñÔŠQ|– ¤ÌÁ!gÊuÃ<%X4ãoiæ1+í! ®b¶ó¦Ü·2¶þ‚ëÈVÜÖ�VUY$o^E;qâıcÇŽ;¶¸¸ˆŒ‰F£Ñh4’Éd„³m±L—9ÛÂËàg„7ÇÆÆ4tæÌ™3gΜ;wîܹsõzi5 "Íf³ÙlêÒ_‘¤³åC¼0ÜKßsm6¹aBt3 ²Á`å(%9kvLÀr9+mÕiÑhTÎ8ë‹yªã<¦ö*·çò bÑù¥\NHÖÓ¬+¤u¥w–ot%–Þ+›Õ[Uö®»àœäF¶\ ±ìVU–(œÿ+W jóå­xÍyÅQ9ú;G7ù$UþŽl.×ÉÅïš×ó6[ïáÔݸ¥wóÊQÅÕjže±ŠíšW%³äl·‡-§úR[z̲š'Ypo6ù«‡Ã(2AÍb©TúÞ÷¾Çü``“lY_YY‘ÏÀܳ<0(+Þ`BQ]9èF±üòª¬†tqlnÔXÕ¦ËDðÿTz‰qÁ¬ÊÿgD.CÄRŸšnL7hî4wCÁ]¿¶$ƒ‡­Ù\;2HÃTÇyšô„¯‚|Œ%q‚‚jGoyHô(H%¬ïy•?VöU’JDÐ’älxxV–Cä¤Óz`"§“ÜÖb[GL9¯¸}Œ®â/à]%‰e5›[ª‘Pztmçc#‰¥™)Û¹‹êš›uN™Õ©«•œ·ÚMÓ^v?¸ëGòR:p%éI“=´y/ñ<g]ïõgÏ>ûìsÏ=÷ÜsÏõP°¸QóûýA•­qVï/(Øè{gŒ3v~¾x`p¥)Œ ×jµ9ÎpÙCs_÷‘L³Ê“Mîlp6ÌÔ€8œ‹1êé~XoOEo,<ؽ‘D1uUbJ'ã#+Ñ)åùóÎú„¬žr¹;ͲîEæ—Ê$ÁË'«:XN•5A°-ï?ù uq2÷"“‚ž“Š3ézáªrÒ–b=ñª“õ*„®s— «’ˆ[šqÈzØ)ËQHù^Rwm2±Ö%¹T:Éy¹9MDÖÖÈk ÜÀGAùl ž½‚ìõ0Fzðûýl‘%§¶Ž@Ý™fÜ”§àˆ­V‹§¡Ã)Já°+—Ý(ï™U÷Ñ=º\Øá 0{£ØÔ¯Pº%˜4é6Yç*礈¡0æËQå˜øEî¨é¥è‚¼Å å,Éëw–&jeqÛKUÅïRk¨°Ÿ¥þ.ýXåvv)§Qž¿ IrfwÁ'­ï':‡œã™×«ºÔƒ$-3Üv•>.¨Bžä„(y?ä±HÎéå1+e9RØ:¶bŽÂTçþDÜά‹û<¹H‘ý‰·³gÏÂ;;; ák±@ƒA@&sÆŸQñ‚Ý¿„õP*3PV¡Æ¸5›M$£òɈÒï'¤Ìðï÷ûùüXœg@ñHœ¶\.÷…í-›¦†OÏýD"ÑU ²+H]÷ã¶¢`Šü”\‡¯^ ¢lÓ)#ÇíºÂ¤­©pÿ”\–§,Ô³;K›¥ÙCð2¼ºµ;«r±ê6ë'w.¬ç‰Èwé'ž¥Ç!Tìúñ’ Ý! ¨‚yž_ jÊÌRYÈ¢àZ¨CªM€Žë–°ñ•׃´ ÅW–?e5TÕ&‡¢²ˆ‚1ç/O™µîÉ©HÝ4c7oüÚÊV–-/õë9«HWZÓ_:Ò«V«>ŸOXÍå+  ߌ@ó+A‘Q! ±¿Òæ¤û¼ÊûHòGÊÚX[žôàÑò˜a¬“¼óý×é‚/àËêy€K]¿‹g²ë‘–6$-aäZøhIÃB*T°U9,îr²ëðé‚@QIãò®^Max³NÖh9½ˆJ/®ƒ I„É– @åLé¼äž•wsÎ:N[ÒÖ±ôSSpÆ>™Æº2KöCx‘¡pw(+_³®®õ¬D:•ï{òXòŒG`ˆ*c?Õj„‰×m5oc‹+µR‡A‰©Œ7Œ²¦+¦ÊápxKfÒ}òûx„„?±]^À“Áû6ÖaÆ)VÀ¼27­&ˆÅËÌÞÙC>¨Y&rò>ZSF²¾pY'$2˜¶´"øänJB\‡§såyq» ¹0º†9ÍÍÊXKR 7«‘Wu/1”_§ÿGúÜQ÷½©qyô,½§÷üVÆÉ¥\'P È4ZÎüjA—-§òÖæßCß~Pq¥Z‚ËÈ{ÍP~PxHøJè¼”'ekÂV×Îb2o¤Fr\6æŸûìç„w>ô»Ú$CêÁC;jÆFØ]f4FL+NölIÖ+Cž\Ž”ƒA~ÄF•ß�---á}pë@ ÀBÚ‚/}a<Ü ƒF£/lUÇ8³*‡›ƒñt9¶äåËuVF›ÈZ‡LŸíH9igÉÇwŽ,htb-oM¹º¬wc˜KFî>jžØå5Èš×gt½H—ýS¤# ¹-M†³¥)ƒ±¥áÍi:uä^å,çF¶TœÕæR£-Nç(ë$¦.O¹V¤Øªv:DDÒuÒËÎä¬4Å'¶ô Òðo ó"VîNÅæÃÍõÑ~iÕbõgh ˆ½ëλðÏÝú1âB¤wöî›~ç&ÁË7²ä'ÉÊT¦_¾Ywï4[yyÁðCŽ+¿¨7hw¯v`Ü•·J¥’ÍfÙ¥BV—$y<V‚"ì“ØD”J%@E"‘T³¹`èÕ¯T¦Í8á7ô£àÑ”…¥1€Âèž„®’{–f+¨d€²ŽÞ)l‹ãã¡ëü<ì«7ÛQò1Ypûüñ>\T’²†ôýž„(”R�ÏÅ_§x9QÅâôW]”oå’A9ÇÒj*¶5äLâµõ¾h%.²@^u=ê0¤„šòøèX%Å m–Ûú†£òû.ù´yÉ™Lª&¯¶$°žÕ‡\<9•Wé/áÿäØ4)ŠYkzà.TÏ=#_€LÁnú›î½ç^†DôÀýÑoþÖoz¿á”‚ììMeÍe×åž}„¯¯\.T^ÒæÞ]a‰ÍÅÄÄÿhÁ«äß‚çVçæ´±lä®N‚~eW i9³ôí,h=LÕvž¡}þœ?ëûçïÒQߤYòµ³çañÙÒjXPÅ«ø¯Ëj8.€ª ÜòàšÓ¯žY½ IK¡ìì•_Ëê6Š€¨¤ƒ/§ñ£!𹂞3)ç—¤T¦ן\‰ü·ë¼ JŸsNãd¶5ZQÂ#‘Séç$¢Ù•ôg=xe•’¤¯½‘ÓŒm•ž­-í;-™qŽueK.öùÏ}žÿç‘;ŽÈÇ?vëÇŽÜsäc·~¬ÕjɨÉV(ïEì#ƒ‹Ø>Ãá0ȃU^•y缡KÔ€ªHÏœ9C\'çžÏS,eª=ëêWðެìH¥{cËMöT«)e6;JoÖzAz;ë€@ŸM\ÛwÛ@ÍO=Ïê¡fNf¤Œ¬JiOèé˜sÕƒ-¨ÎÏwš”kü勱]ÛBâB¤üÇeàG‘RMJN3ìåºĵ“”ý®–ê~³úŠ9"«œ,åΆ:<¯ Í`ΩuÀ_¿P’•ˆ$ hk’]äú”? yØEºwEµTÙa9þOCKG+…¦•²\œÒî»÷> æG~ï#DtÛ§n»ó®;y•ÕŽÜq$‘H¼ïýï{ßûß7ÌÅh£«|¼c.­Iûn‚Ò„SŠòSÆjíyµ?öqˆ”J¥R©4üÌ ÖI´Ê™ÒîQŽ`ø†AîYìMßÙTw°ïµ×¼óí‡ß{â\±VZ|uzáƒü`·}·²,Ò^g™À¿¶õ³¾þnûªï´ÑÖá³muŸ:×bW³]aº¾ioÄæ”×ÑáéÚ¶44EÔe5ÔÍã€Mf²ª» •ŽŽ?9#.ž ÚˆÜvföz‘~õ’ããò ëfÊöðq/æRq+d (NΧr uñðáwS'åR }Bçg2ñâ× ßuç]·}ê¶Û>y›üu‚çöÈGnþÈÍXâù, wpe¾»þ#J¯,^"‘àÉ–Rï†-gŒÎâ,ôÊøŸò„îôHy;JSúŠY V9Vüv‡)9LNN²7Y€Ö]Ÿ§Åìvø�û"¹òÄá ƒ /(ëd"ÜxW¢É.‰ßÙ°{t¿´(@GwDT: ”ÊÊgƒmz„¬{gˆÚmz÷m_‰gfO/ü׿w•“ÐiÆæ®¶E[ÒCa:ŒàåwÛÙwø¾þ]õËôõS´ïÁöuìàcë)µ¹ ¡÷ÔȔW•czñHó$O×G…¤"„œÆQ©«eÔÉí š4YµºÚÍ<‡I9 9p”Ó¶µ>d‹ÈnÒ¬TÄÉלTø—åǸšK vê6%ºÀ09u‘ÞkJ® VI_¼QÔäu3ndîÆíNÿs’ú©õÇ€š7Þt#V“»î¼ë#¿÷‘Ûî¼íÞûîššÂ2ú®_CÊÛï¸]ÐâÙc¨‰¶Ýn I’¼1¿+@ ÿW*žü)s,jÊUØã½{÷N‹€,±ÁõèºÓànyuu‡ñÂÈìv¼oGFÜÜ“ƒt˜”s D;K>:DO=Œ¨ÙŽ"xùß×ÿªýËDt;¿@NP;ÛI ’áًʨíaTþU.‚Tö•TsM.WICy_¥CoO¥#À’¬'@R·N[Ó/Å}'!7‰#wÿ¤S^Yª,æ!î–eÖ¾~¤¤ dk×5©[¶ ;mÏZó–Žùéû‚¹Ôü¸‹'ð©Å¤VÖ,¹yàJå “ìIc‘¼ûî½ï·ßûÛDÔ¤f*•jÞuç]÷ÞwïM7Þ$|êö;nÿø­ÿø­Wf ]æŽÊ›G ÞÏIƒ©KI$›Ì[f™±[Gä)#{ÍqÀJª-Ì)eÉқɚv8$\YfNCJœÑ,Q›ŽÑ#ï+–Ô<ÿÆ•ÊíÆ�� �IDATïS;NDÔlGùž""”©p=°ln¸ûÖžôá+ú(OÈ,)Ó’8oª¸^»öÕ ®ZD–³˜D¸È¼”²›“ÚÅÄ#EØãZ€YÒ`²Õ¹ êÃ¥sŠZúZ K3Sv·Ö’²d¼°q¡&EùŽiÒp¹¨úéb ¶^úQ¸e¥›ÁEÔPxö Ò19×Ïʪ~¹Í·FÑüâŸ|‘ù´<j~÷‘ï~ù+_&"™Gî8²¼¼Ìá2äÛ£CˆËç´UÉȘÊBNóèHÄÁ‚ºz…³®a9è¾IK&“<+ÿê@ÝbÙ1¾OÙ†$÷€Ì¹Vòž¨é¦sÝiÓn¢‰ô‰<½ÿÿk¿‚|?¢cí«:¼ÓjúrçÖgi¶í:çI˺’F'ÉIË¥¥áyHtuÐÉå%.Å}ÀÐ7¯É}U.åV§Œ!ª‚UáŸyU€³àô`“kõ¡­*¿)¨4 ,}»M[¥’¿¾Q8FW©œÒ9'S*ZÒöÅ1­\Kµ®N]]–¬­ï.ë/f5 miv*¤ï&ë äÔ÷n>öèå—_îóùèJ ƒÿúoÿúúÿöú#wùØ­;rÇ‘»ïº Awßu÷͹¹‚ãwBùŽY^^Æû,Æq2RÈ$lÝYéUÒïû¥Â ÐÚ/y¸U¦³bú„Û�~4U™ð3™žžæÿ©„mvw^&ÂßÍqg«Z[+}_¹N½D5-"š&ºŠè7ˆŽÐÔÍôÿRÛGDôkôpÛvÊQd¾b{h2å´][H²¼Í‚†0)Üvª ¹x†É¹t:¾EŨ,W²^‚.GL ªá*è$ïU*@ºæT$ÀË«|ÊÛÌiÆ]°¬å[wÙÒ>I©ÿ è Þéà-¡ Ï&Õwy …vuðÚš}‰åâTÜÌòôècÊo~á¿€@Êî€O¦s6ѱ‘%s|Ê1Ï•à)²¿cË*SžŸuFc'4Zg|ÓoÈøtVeój™äà§š_»í*Çû™Ï4‹ïñ}©J7Ä?ü$]þÿ‰ÞBt98M¿òç÷ýþÝôka߯5i6쫟/è•Ê{H Ò•ÚšÕ0Ë‘0—/UFžrz?§òl‘šcúå•ËY-p95çl*¾…çyyÁyÛ¤‡8<•²Ï¶­W‚e9,μ0Q–ÖViË ZKyéÊùÑÎkü±òÆ.çœkg²0ûÊ`¶íA¿Ðö�¶Š¡Tºðî,në‹2ÉEXeˆ½÷¾{ý?íéK_ÊÞAªd£Ñ€«¶R©0ȼéwnjQ‹§ƒÃÇK½-50ïÍdQ•Î@™ÿ­®®‚�1þÍßø@{†÷×ÀêšÍ&ngøð&dÃâÒé4® Ort1ÂBFw…7uwÔCuSÁÎ:eefùÿƒíë$jÿÑǾJÿý8Ñ7ˆ^K䣫èöö'ˆ>AD䣿ººí ]ÖFT¹ISb«hœ¥ÇZR…Çrašæ´\š”ô<HWöÀÕ'ä¥ì[O¬y a3¢Lxª0P9Iq7«ÒÁ']¼0Lõ¦6ñUŸ¼óÌv·~œ–¦42©¿¹fä’rÿ§áÁÞû¨“FÇʽAžå¡þµwCfœsósòÐCxßûßц<†ñ²,@„ÜúîKtI£ÝrSjËñ5B›ñf{4Þ¿ÍS^6ʵž1?eJu$vNæGºuÏ5²}äå ÕÜÏÉ�v—^zé3Ï<ãýü=¸j…"礘¢£/Lu"»“"›4ƒ|ÿD¾ÿNtû÷éGG©x==úg¾O¨¾ÐGÎZrÙÇhwó'+ßq_ˆsRrå-8—à¬FÁG^ø²œcV×ÓTÎo²4Ë´{ojrVeÈ2Ý*Lu ÍkÈ·b„;òÅÊÎÛ$=HùnIÑÔ2õǬjplg¬”TåOYi$•“eéÓÖÜÓÙÜû¦ñóž£ëíéìÆ›nd¯™ÒMMNMMN=óÌ3Ï<óÌÌÌÌÌÌ̇÷Ãøï¤åQ6ËÙ Jç£Ëd2™LfïÞ½{÷îMtŒÏµ‘"ø7å?Ž÷o“68ý‡X,yôF£±¶¶¶¶¶‹Åb±ËCÊr”Xø©=øTÆ;Ò3ÛL~SW»úꫯ¾úêýû÷ïß¿×/ ”›zvծלѺ<©ÝqÆòœöyçaÛB«xkÖ÷ÏDÄKø>NDÔ¾ˆ|3<X-SDÖE8Ôxéè²»›rÁ*8Sˆ•Jè¤YmϿ̡†“Wñ0]ÊIÁé·Túió¼ }˜7µnCr•볤 ANå?ש/1ø(Ç>!\.ø‚žÖ“Ô šïØÊ7ßV:¨-:yy'AÏ;Ok¹ö·ÑN±·à_Ô¤œPûKé†Rf?²7yðÿ<ˆr"ºïÞû˜�ûÈëÿÛë‰èÿ¾ðßù«ïdo Œs”íСCÇŽëï9-)”kz³Ù„'™ç+ìMAùajjŠ:¹NýªxàsCí±z�Qözp…¿áp˜ ?JLƒï«Êx3sŠÀ› Ç8¸i«Õ’3Ñ6ã/ñë¼FMŠ:«/r•%öó¿ðöù|ÚŽ›‘þ~úßé§;®W(gˆtÞ1›?Ï5}¶>SÆîF8ÈIˆ'[ÎI;ÜݼІišÑ£NbŸëÂlne%g©Íåœ|¨àªT®Áê´ó´$)¾Bg4 ÜkråÁ–FëG™v”íÐÍ(?à\²˜­ñÙœ’‹…lÎkmu¾ÂV5Wqé=WPí‡ø0¶³y8qR6Þ2ËïªØ×µÍ59oߥ^È«=øÔ9l…w€šÿëÿ‹ˆ>ô»ÂsËGoÁkÔøƶª²•yÌ áue½cçÕW_Ýó(±¤'´ ˆº)ñ…Êt‰ek©Œ‘l¼H§Óétš½9œã«bÊë/“‚žb8–rÕ N¼œs_ï$>› z€ƒ}v³m¶£D9®ã&O»Ùî|NݶG˜¤n€gwëéhiÊW”¾Íóì>À0Õ‰ œR§qc;‘ÀÖ”dØ*�&'Pô¬®€DWó'ÔÒä‰92•$½3–¤} Û…d5÷e©¸ZA<âÈ%ƒ±¼’•PíZ&M•‹ð0g%·mAújþ.ò*`îAR—÷”ç.lc&h‡¾ç7ÞCD¬Žó×à¿ðÇ ›·}ê6á³·|ô–Oÿþ§ñú ô"úÃ?øÃ¾/I@€‡Øh4*ૉŒAçQäjÂm¸k×.È«n#‡êÜÜÜÜÜð²ïr?=lA/—‡mì™\°\ø p¤û>`pÎj_‹Åb±X|ñÅŸþù矞%÷n2âà"€`9=Hë‚ÔbßsÍÕÃtx]ß …Ûöü_}õõ躰­»³KÆ ÷:Á)Ê|wTéÉé-( äYíGç~szzÊ„ÓaÊKQRr0 YΣhkð,Ë?ëZ„c«ŠF,©ë–°²Ëå+¤ª«4"lM£7RÍ…|µB&mV³•‘[‰ñú6w×–ÔŒï&&o/,ºøUAú9¸kuÝáÉÑ]%Œ‚pxüU;™}àúÑ]wÞuÛ' ï·|ô“¬¯õ-½…/AA4H¨õÎ*úÎ?6á°éééééiaåy;õ'.5û#"wΆÌÏ ?c¨n»²¥ÕÍ”ì-䣂=ì‘ ÜŠ#TAt~ü>¢¶ÕôQ˜£ù(Lõf;ÊG:×¹æ:dvÕöSÖï ‘!žÛzèežLÙE–åŠ@lI $v%{-IZ('Õ`3Áµ ’#p©"åÙŠR •`N¢­yîl²H¯Ã滋á‘ÐÍ”­y–´ÚñšÖ¤²»» ª2âÝ–ªàÄêæí·¤@¦­ðœJ¬C¦»Ó>öúÆ›n¼ïOîcZµðÓÞuç]¿÷‘ßcÇäòC¿û!"‹!8÷)»>ê¼(½²^•ï“'OÑêê*r&OŸ>í¾pƱIáÓ’•{ æËu=§¾ ýÈ—ÍËÁËÆÇ5e å<v­ÒÐ#œ¹²²‚§ÚKtYî=°!à´UBt¶D¤ä¢”<]BÏóuP‡Lt‚äþŽ:o!©–?Çúë\4uŽ>]Bž´}­ÜܳN1tžìæ8¨²ÊÐV5¸Us¹6rAˆ#NÙTµ•ºx ¾\Yh© j¢b©:Q »9ÉÖÈIsš½Åùk>DOs<î Ò½¦¿ŠòÙ–l—ªVùÏvÛJVI—^Tà›.˱²¡«Ýúñ[ñâŽÛïàñòsŸýPs£¦ìD­¼`¶¤ví;- ²bµÅ: <~Ãn¼‡8nWã—u6\x6êõ:¯½Î®ÿ'û8ÆÇçÝðx™L&ù¯Dî«;Äöö w­Vcµ›»víêax»§N©,ŒS5ñ±fÔDd?O—¬&úh½‰Òù&bY×ÔÛ•¦&ŸÖÒH¼„7 –._$¬€yAÙ<Lõc먦¬Ä·U.²NžK¡'Ë"„y®Ú’$B&N™³ IW} !)¤À%4eE¯ƒÃð&OÇRaI^Ú8¾ú="í9HÚÕÙóžu΂ü¸Ê™D–¬rÈçõ»1a—ÀŸ9ëü¬‹O%ßñoÌn¼éFôH9üîÂÎÃdϨ94Ãeó}6€¾år™§qÂú«\gA§X¥„°>b0 %_ªDi]kcÀ ÙŽX5?h<´ÄãqÌŽP‰«T^äß„c–½ "‰DªÕê ô.Î; …ärá Iî5°ëç¸ ©däh=ØÙÐ4פ(µYɦËòM®–†›Ê59~Í’Së«ݰüR»Îf5—ÍÎiéѽÀE‘³š^ðVç7Ϋh–²«¨¬r ¤ðèà!˹smM3¯u8EJMW9QÈVŪ-•KSWk¤täõ^‡uÏs“fU‚ ¶‡U'­gmP9߉Ÿ$c<-ºkño¢.ó¯(ŠL>|ó‡×ÖÖ¼ f 7yXêyÝŸ››Ã˜ÔëõA09,ß¼ƒ)HŒa{W¶4ó×ÉÎã®Z0P2^<TÄãñL&CDLd&ÇvƒËÏâ…™˜ìiZÃ*/`w…¿¹WWWå$gŒ†G¹† Ü"r¶œËwA\‹}$BBû|/§,­Î‰ª¬ht÷¶4N3[¯D2=åÖܬL;ADTLŸ‰ä)„ ËºÐÆ2wˆ*ÇÄëÑ@V?D:aupå®<¯?ƒ’€æ¥²øÒ©õ¦cÒõÄ ªÎ0'7ÕKàÜrÒP¡­¬­E»›ãW~nmÍ>ÏR1oRMåoõqõáµgaÜÿÀgîþ à“%›Ûí6@ÿo4rDM¹¸ƒAÃá0ËRÁz=†4вšª \@¬N€såG”p(äÎT*ïP-£æ€ E®p¥†ÃaìØUŽìFOI‹½�§­ê‘“ˆKÓÏéÝ›äÄKÞGg»jÇ+}òar'[ƒJ—¬‹÷RÄ`ÎqZèÖ¦Q^ˆ•í²É ‚ƒ4{L½-pI®Y— <ïWór’‚ijz&Gª9ž­gI]HT¾3¤2ze5ƒãâ{PŠÊÚ’ÅÝ«Oz_½­9³ã{¤°%ù~ù=Gn£ÞZ¶&z/HïûÞÛù°È!ÖÕwºÃ¯æŒ7óñQ¶ZñßÎX5âÇ—ù7  «óàh_×¾’…j%0LMMíÙ³‡¸5€X\žÐ;…wu²çGpD÷Àªû@eƒû·ó{A/MÈ•À)TÇ ‹ÎyñRN¤&ßMÿÓ–\|î¼ÁÅI+,ë9ºÛ¶´xYú–TîA>͇$‘6]›bK#ëj«Üv·B5R¹CÑeÌ’|¹YÉ‹Èwç¶õñfÖýæ!]ž.ƒ“õÉspËŸ_IÅò®½½äôœ¼”B,7]ñ’¶ê¢ÅGú…Ì)KÕüÜæÄÿHåëÎkÀXv­“òjñ³gk~çJhé£U«ÕÍѽ4rÔ1 胵œ#É.~Kü“e61ÈáEØ™„Í æ¢‡!ê­Bcii‰ˆ€}‡jWÆÐá‚/½ôRLžœB¡@DÅbçoJàÍ¡PÈ£DûæM™”uušn9ë7”Iƒ¶ªGD^õ-¤÷\)A<0^†T5s}ÊizFf5̸ ‰¡;Ø!ç±–fåÙHŸm›R8¸rä.I'ÉJ; xJR5òäÁ@ g¶jï’m:üùÂÍa‰dë·Gºm³Ãª­FV?–™ä嬼!p~Vãó°ÑyÕ#¤|DݳlÌÆÆÆ”®üjºàeaU®×Š“F.|ó°-³±-÷Nèl†  ®‰Dò„8ÎŒtêDCñšÍÎÆ‡±‰ë”Ò÷ñ?sæ |à#ØqzCP½²²‚1çAT Á•J…@+;’ŠS¬ž‚sù¥¹Îa–* ÓvCË.±ôŠÞüÒ,`Œ| 9YI‰*JI< 󩲤z¾‚ÄH亻k>dG OrË+Ý¡•[µôç×Óá¾m´ê”kIÕ–’8ù:å`f5NKêäô$€ˆ”R³>ËñuY¢H¸Ha”b¹'á˜uIHñü¶JÈêèC oÊ,ß–žyRÅ5HõÕä¹JwEÝzÕi<XÊzr}·P(Ä ÏQ´vÞ„ÖÏ@%ßaL�c«‹ÎVTFœ ÄpLh&ŠñçEÕÛNc~ ˜êõúêêêüü<Ôÿ!ÏäóùÆ8cIq¸ìx<~ÑE]tÑEîÍ_å-]<÷¢„З‡PéªUB‘Ð$Y(8ËëyƒR.À‹{V—|+x8åºC%±°Tåºë‘µ‡x‡­ C““r…ì8¢—Ý)¥ ©r4ïDëu@j¶-òÙÎì-]í?iÜïäLÜ%=²5ÄKÎã•ÛY+s}ùˆ€ò{uz¤‰S{V˜ ™|3OûCªª'9«+¯‚É—päÒÔL¨)R–ÉÊx½è¢‹@qp8??Ošˆ&sÕzwn(­¿ïXÎ.Ué¦R4e’!¼Ó[ܹÊÒŽX4½ì²ËeÄø³,Ö‘í¸)³j‹1ócθµ…!¡‰)Ÿ6??¿¾øâ‹äLî¡Û׸j•ûë+Î!zƒT”¢ÜMóðf«þDÝ2eÆ Ëp»ô¯(Hü&ïºñ/t˜‡%ùâx­»‚Dû„š“¬ëv„ ÷’•w…6,Rk‘ó´ò9 d CYÓ@îBú¾Zü;=”朷l ÙÈÝæÅrÒAåºlM²šgƒTÞ{aÃ‘çÆª åÛNWJ~#êÊy©Ÿü¨8V|~­g”NI’x’ÇX>‚½üË_þòW½êUW^yåž={öìÙƒ¾Í{ÔÛ¡hRI×FoÖ¹ˆ•Úë×ßpýç>û9A%ã7“Éä®]»víÚ…ñ\/­Þx6ïÆ¹DeÛ8v ?"J¥R~ÎjµæšQð Ê6Ä8-ÿ«Î[ÏÆËK:˵ٖK´‰TÜT ж†/òàªìlL’ª¸°曎nYÍ:›—P\GÑ䯗at:µéÎ`I#,[Ž(ë”ü%‰ZÉý˰´4ƒf»ÎC¾ÃÍõ]‚›!/yÅ…¬Ð™DÍ’Ù¹9jgÉg;LJÏä’Œ—$”{ª@œè*Õ“ÉMKSá#ëâºdÆf5Ï­×òªÄc'H�vúî)‘ +++ü_™/ŒÃ›|³ïµíCN7%g±coA¾ëo¸~CÇÏÌÌÈßÈß8«•tØ»ž‰6èÄÂOhÃÆ_ø£/t½e¥‚ß6A:‘‰ZàÀªŸé—¹ ¯K'¯ç. #w‘Ìê÷õ:Bii<¤wÊë—¬¹ê^B àhGüˆi!9ÔÝȵYc×{\¿žjÖr¸<é)h„yå(²»sU–;°T®uŽë’™•Áé‚$¸#«¨+)lNzÇÖcOn=5ÁmUÅ°è‹æ}àÊÆãx¼ ÇÌK ëvi.¢»–þ¡u×d¶]wHý1dK:tØ€”E¬hÅbð HCºr,a¼ ØÂòzÿßÏ^_÷›×¹ŸS©ÄÜAÈÐôf‹‹‹ðCÂÉY,[’‰Ã#1@TðmÈŸB_;…aߌ߾gŸ}ÀIJ¥R_ÿ~W‡’ØIƒïk­Ìä%kAã%“3q,ÉqzX³|[*÷ ;*» \g-æ­ÛP³ âͤ9AO@ *8ýжSòÐÒøù‚Ñ‚ó$ü¸éTd0s–ðL€jå, ê²*6#åÓNÿ|ÒXósŸÐø¥ÀÚ­Ñ!ª8ʤyNò!ܹrv´àjÖùá…I#Ò·"pSÔzGèüŠ#âñë—ñ¨ID_úß_Ú<TÜ Î@Þ¿Xï3Þ‰Çrj”ME¢ÛÚÑCg›H$‰D2™ÌÔÔÔÔÔTß³Æì/Ú=lÁãÊû]øˆÒź©l¨Â—lÊÖß±uïŽRÐWîÛúÌCê–×££’rÖF¶Ù¥IgVÃÿ ª"¤Z¼Ö—þ°¯~ =ßQFUvÕDðj ƒ–Õ¯õZàÔþtiÀ¤’;`K¿XZ#¶~‹‚²¨Sh¬küáÊ‚%ù·•§¼Ø^V^¦²k9ÿt¾ákç ‘ÖLÛ"²ÑUîæ5 ¤*-8[uZ*R.‹*ȼiIÒ?½òe `3X߬,µ,ˆµbª×ëµZÕÆ¹äÚ„Ãa÷–ZOù¾ÿï]µýÞôLC½`O4ˆ/n°Õj!„ÆÊQx®É°\�u™ê±7½ÔìȬ߶z€%eî+„t:= «ç74˜Žf³‰‡W¥,ëòœ U­½¼>zIް=$‰+—T­¨dB2 ê[Q/ؤè1±Ü>¯o¹åÇõxûYv_M­?S^ß-’å%T¶UœÞ’&¶õÚ79Õ$r›uY Å\KʽBYj^E^󜾲¼U'7˜ Ó4÷ÌèÔÈY±š—\=+–F3RÙOñô:U Ù…õ.¹·k×.V,g €ÂiÏ>û,ò9g(SÑ­;�’ 9ßFFÇãq¬¿dAäÁËÝÍÍÍAa®ï~×ÉÉÉÉÉIæ–O$0\Tó"ˆ *”µªÊñ÷‚.=ý*QeP-l•zË~ ºnùºÛ©ÿb¹ÖèÖ_KCjmg:‰¢Ke§Ü‚‡4r%F¤W²õïîbi¤!+¤*LÌI2è$y}Q:Û¹c£kU®P×à|N²Íºr¥¶*Ÿ –çœùQ#¼Ó.á˪:ÌFH¬ ê@¸åŒÍ“j¢••¯.õ3Êg^ÌÊ:{àØ*-$’Ædàöì³ÏV*¬ªˆ±¡ZneeéXg½×ûŽñ<†å(ñ+»Ç”àAHÿ(±¸»¡Ð&ïf…+ü›“““W\qíß¿ÿÄí@ÿ;ßùNß÷I]i· _gݾH K#­©\.cÖÙ¬­5¿+í#©‹“b½8DO9õS ª­½íêkå×¾*€ç%Ä6è²Nlî’ȵPTá:¥’CV nåTk.I‚àyçÁ2¸fUžÃ¬ÞCË{©¨œwÃÊfòÅTvDa¼x•TzésÒÃɜӯ.«%8ªl9Ëùt9`ÏY¦’•¶n…8=$MVŸN>BA'¶CAz˜¹ƒ,å›b_d«*|´Ëo,жÊY<¿âŠ+2™ êÙqäòò2rkkkkkkssssss333‹‹‹‹‹‹Ñ<x°Õj¥Óé!�l^D‹† áгƒAÛ±LçøÒ÷› \1Ëf³Ùlvbbc«ŒÑޏ -É`|X?‡h4ªL À_‹Åb±X¬×ë|ÐÚKClÛ#ã´%“‹›Ë""._¦.äOgr1+ùÇrJ 9ö‘Î%¹(êe%XÍj(¬-y8³zâ+ÒD}"æšsv™–ýá.Xyn™¥Î+hëçH™¾ËºÊ"«"î4ô¶ô*wºâ][úkžƒº‚FÆvýÌM‡:ϰqv*Üf‰èUŽçýÂWä8¾˜wº£s*W9ï|ΫêzÙM‘>Ö`ydà ì{ÖÃòò2N^©T°µ+e˜ &ŠêæFãcœcccø dz• …óccc „²®w¦âÅ}‡r÷­F1IYÄ^3 Þ—¾ô¥DtÉ%—ÑàL1Å1Z­†bðËåòàà É_y�Ý﮺Î;|ÆÉX¼Áj!¼g»pYÌK Š|y‚š®åúâDìäcd&!–ósDA88¯9qeþrIbÔ¹Œ:èšǵ—ARZ–¥”™\䬱õ-Gäùå9“Ø×¥³M)HJ„Ä%œÙÑÍÍI–T"¶ŠÖ“QiÀ"²–®àv$ç¯í]ÕIß¼y§è/s!oã5cK’~A}P£÷ä ðÈglyâ«Ú!«†nmF<Eö;m­cãœTéØŠÊØ_Ù™}GÉŽm-\¹Ç½L@w9ë;“Éd2™ééé½{÷îÝ»óèEdÀ ãônýUÛª~áy§u+Ó”Å\ÌMv\Z\,U~V"O¶ÊQIªŽ`ät{*½dGIùà®Ìxršþh¶3<¼^ÅÑ!=Jáò¼F�›§K9�� �IDAT½ ±%¾è3ë æ¤Í‡¬qck¦© dÞ< –8“Rc÷6ƒÌÙƒ¶G²hbN˜”ó-ÒÚH©%—'K´at~H¿ëP9Xß=ðφ¦{¨é,Hñ ]v.qiJòp¹H zMâ©X,&(ƒ»H}Îb±¨Èÿb¥ƒãÊ  ~¿²üß{np±Xbéǰ7 Pp™†B_6àíÞ½›±1Nx:;;‹yÁ]0üãÛ;w¥Ý_>úåÿyíÿì£{@Àå;WwEÞaΘuŽÖA�gÖùã—•Í%U[¨4ïÆ5-}‰ˆ‹ÇØöpN¯Ø’V=nsNo*¿æ5õ^â¬$±$wŸc«ÑT«çFÉf7-ÀH•2cÿÿì½k×u&ø¥ð(Ð HPEJ”•RyVFmOØŽõ V±Ý Ïñä˜fŠ™µbÛ0I�$AŠQ”LñMH>`º”gCÑÿ8Qaý°±…E´1ëql» ‹*)I‰¦Š„H¢BâÁÜçÞ“ç>2»ºÑ B3sè®®Îʼ™}¿{¾óïT– ƾ’ ‹7´`ÂÙ§îì�,šº¢  ;ÀÀËO¦"wê„hLêÚH'ò%2 DÔ((UKÅÉt1*î¾Å³P+Šž²5Ô ‡fh;/šC8-t*tv‹6N:µbÅ ‹ ­×ëÌÇþã?þ#½Hv©~ø!¯;µZͻ OŸ‘‘¯Æò2…—sr¹n1Æ•×T‡2.\๒V´üµœ"މ%¨{U¬”ØfP\¶lýn5ØüóÑÎéµ|`a×ëEM¯M1  šÍ&±µä¹ñ÷ÿ÷Wr‰Ç<Q4on'öáNV/öÁXYn¯ìhð-II2 áøS­Ô52‹:fŠMï´¨bÝWÚ>tD—;ݤ‚î+óaHÃÒ¸$CÉ)=ƒœ,q ò^‘¥mûØ·°ÒÛ„9tö1´0Ö;ƒ™*¾Œ‘ÃìõÆ·ÉÊ[û¼oçgu4'˳CgÛÜ0¹DkrÚ¢ô%)ÙT1A]áäÍš‡¾Ý¡7?½p€‘§µ˜ž:uj)âQù)ìæÕµz_”¿Îg^m¹÷ߘçÃ"JN³;}A<çäŸO¾õÖ[÷}ã>šÛÕ«W„KøgV™ïÅÍtSnßv;­:ÃPß¿ó;¿³°K¸zÌžlÒ¢ŒM­aÂt œ¹ÚÞÝœ¼\®sîÁã„H\aªÉµZeø©™“ãÿ#_«“Ø\^¥cmÛ$<Ûb .ÎInY eÛ—<N|‹2Ùhuq=î][ ¼÷T:ðY%(Þú õ[]ŒÊ3Ìrè9†I¶¶Ì2æ\E>? ©1–g ãx˜[½Ä·e‰¿wZÊ8’ÄW'Z­••¢Åm H‹þT7ß|óÍ7ß\‘çÙ³gß~ûí·ß~›¼K½„eYÆÌXËêu–þ˜kÄDã*\ÇÏž={öìÙsçÎÑœ¿õÖ[o½õõã\/}û;¿ý;´k¹ï÷-NFêôM #7ÉYI¹šçùGÎ )l½^§†bVËîãÒR„’^öpð)™«EÊÌËjãRG"T±µ¯è‡\ÖåÝ#ì#³- GT°d8ºð?v(>ŽØRß®õ|dF0[ˆXµ¡‰Êùy¦×åleð:;˜ØW7énz¼üª[_Ä'fòÀAZC#+¢Ft&N'p“6ÈÙ¿^>lµÏÔ“Ðv±<C9¸†ÀÕ‰e GXnÝ—­Œ}‰Ìy7½ª¿Š\2¼ÄwMw9ñB&ƒB™„#«|Üsœo“›†êÄãÜ’Ò€4Ï–é’<IoœT½âÓ¯ÓÕ-µWß˯(çÂÇì=¼7ü¸páÂc>¶s×Îy}Üûï¿òäI�[nÙò_ÿþ¿.)k o®A>Õ|§è{Qï./ߣ2Й³‹}Ri0äUœ&Nµídã"³Š#)ÏÆ¾(6vÐ%uS”î�j˜èú÷eûŒØlsøÚOZÜ©ÅIZH¨ºþEHõ‚ÛžËÕÁk©Z–ZNJ:hB©«}•¾Sa–Sv3ò5çx=µ«¹×Ò/Ñ»É&tûRˬ‡-må)¡Òþ—Œ™Y žå™]ëqÊ7‘’ ŽËÙã9ÄA£ÅZÅ`¢Ï›ð£-F§OŸ^¬3¿ò3 ãÎ+£’õò tô#Ú÷PÄ àç?ÿ9Í̵×^{öìY¢îûý>�ü l¹e €‡¾õÐ�E7î=úØðÏ€5èCÿîïþŽÎp0XŸ¸fͪ‹]ðS÷ñFœ®§Zb.µñp09LoÞÔ1‡“Ò’¶“Q‹Y¥Y’ E¹í§ËËÖÍÒw¦´'”ɸ:˜¼nÛ÷¹n*Ñ»ºüvdÖkSäËí¡$E9IJ¬PlW2Šp÷·jhc5r“!{ÛÉûtŠÞVaÇ;8iÞÌZ˜U}NÖ²ö´ŽJ¢FiŒ\¤Æ3ô5¦ÖM)lì<ÉnnbNfÅÚ&b©ÛY_þ L•ÐâÆ „F—.]"P¤ÖY)ûtÃŽ›žqõ%AeÐì^ÎRÿôÿ'êÞõ+ Û šuÑ2Öd,÷6¯¦ÁïÁ`ðзðøGžþñî\Núc¹/@AI» ”ìµçÅÐZ¡|Ê‹°œé‚(Fô–*–IRy¥Úå¡vQþ/BÌ ¦:)i²f‘‰OúÛöÕHÀ´÷öeT«°›wéYù¹.ÁàîÚ¦N*Ûˆ¶Áp±Ó4 f8ÍMS}4Ë](î`£æ„¹ºCîr‡"4·Œü$€1ëÞGa¢pïS#!¥¶¦×Úz-Ño»šìµ˜(^n¼bœ+†  Xõ8DórkT¸d~I{)*ÓYqÓJ Æ\Îaw´o(»ºäùš5k–îB¬èí7Þ À#`&’*z©ÒKã»Xƒ˜öÙÙYozÂÊ XLæ2×]ÁQEý©euæÂÃ0JÚjhI†È_ºòQ™º+ƒíÔ¤Îù[u“¡pôËELî¹KyY@ÜöÅÄn„*k$¬™‰8f]G\n<+ƒÅÈüQè«%E‰!NÙF'Ò`ïNkŒnÙM Äà729áÈM?K"×,ù€'øÏê–j¹Ç>;%:móÑrÛe…§‘»ÝíBLÞ5¹¨àƒ>X jtéLæøÈ ËÎÊd^º/â°R¤×^{­÷Ì¥œÕm°%w$t@E"l¡„>vÿ*d\«£ÏŠLùò¹xT‹ØtYG”WqxI?”p§Ö/z}ÞëN¼èfÚʸÖuÁŸëMã¹Ç6ÁÛZ+ô)žd[o¹^ê¤<S3Òvâ¾.yœ6{ε0Öµyà9uX(Qxq#”Ðwþ.3iY&™)FNL §F(ô9Iyû¥ËX-ññü‰ü)ÐÎ ~>GI«"Y–®Æ¦%ˆ¬Ôtí„ÜbYIHg¢aÊy=xV‰^UÃZŒØÀ]¤?¤Šu0PÆ‹b¾²<ÜÕ`ù=$Cëšò,i?ùÉOxkõᇺ�Ì7ÅkìW­´’Ü÷⊙xëJe|¢dµr-IÃ’€Ã2Qó:êÅåPš–‡°±ÙàZ6|Ž|à §Ýclš€C£fEûC·äTÔ•y±ºû·0u*a¬_%ah.©²l?up"Öu ¡ƒ2žsk$Ÿz(Ô+(©= }ޱ9b¡5âK´Y[DÕ$•Ì#Y¬=ýã’›§¥­ÿd‰QêhµØßz8cg†%ŠÒ&Ÿ¡¡Õ¤çs¼Ææl~ž‹ÿ1æ32ßp¾bÅ ªs`öÒÛf™‹^È4ÆÕ«WSÛj*ç ’_™ã½÷Þ#›‹+0dïh»;o=‰Õ½ ¢à„ý’o\á _îüœì]\Ò]9©¬ì+YÜØ‰xÊ‚ÅD˜k·Å‚•úÎÄ6œsô;nÄ즭¬g Ú,Æ4Ç%bZW„ì•YÅâd¬ú«8Ç[A_Lc;ŸE"̪5r2Ë*F¼mÎâò! îç”ã†ÎÓè²ëÅ$t1"‡•ù(ÉFcp,ûCgcd¥{-ä¶‚W[¢ÌçcíºqÃJ-ò’ÁhÕ"{¯ËLõðú’{cþ …yŠ^Îøè£úý¾Ô¬Cðº5ûXâéð¼¿(™£­žYt!t§NŸ>}Õú�Ì9<tû¶Û­±}ª¹§º—¡/*zòð;‡¬ÓµÿÒTk^âM?*kWP.#²¨`—Z }ènñi.÷eŸj YL±‰%n™Dè¬dJ¸ªÏ¥dV®æ‘u¨Õq:FֆçZ²ÀL²Ü¡ëÄkòŠV›ë”$]™– ƒÝdgê„­~ò˜ùH¤ãÌž{iÈpùJ-˜¬~E" 5©—b‰œ­ƒÕ"Æow P<7NÆÙ•¦-ŒaLÞY×êÅŒ¥Þz8 ^Ü]¹r%%®ä;ÙdN:Ϲ Ú¥v²eÖô2®<íÃs›w½0„p7C´¹¡ÿéêÎ;GgBSMô… æË[:xhÇ;ŒšG^8ÂØ)”N’'°ÌÓx¾¬lõ/xîÀ|ëP‡¤j1„ã—7K7.9rRb0ëö‘HœU©.|\½ïJZCTþÁǹU׳'f{X´Áª‹°©ì’C“÷‹MžÓmü ß>@¬ËyØ.ù-ˆØ1ÑRlºùC»DÅfMjìkó’8ñ_ì4 “[–Ðá%[„Üàù¹uI n<"n¸^BÍ��²¼."¿ ç9”ÙÊp®ŠU·ËÿRøbŃ—A*°_v mê+Fúï})=+FžçÞæ'’Ä^¾|ù 7Üpà 74F£±víÚµk×2 ¸B îsA+äÓTѲƒ[fs´%bbŸ~êi&T‡ µù‡ºçÞ{FFFîÞ{÷‘ޏäùùò±D~à¹KEÕεç-ó1òo¾, M²ÎK £¤Z®¬zÄ¢p­3*ù­Š9"Ùn6´-ìÓ"ʨéu³ […Çœú¦š£’0@T8õÄ•÷+ôíB_|œ˜äjå.«`ÝK\^&d‰uÍÐ- ˜¤j“Hte)ˆ½Gý !h#‘ÇR½Oòz ´…´¾†©®ÞØUØF¾¿‚¸ð×-œ`ƬpÌs7ª6=ÓÕ\¹Èõ1vGñi¨Ä±àœnMçΣ˜IÐË–-s±ƒò%å]e“ËEq º{ïÝ|Â’êœoDxä…#›oÙ<ä›W¬XAÅH=;½OQÙYÑÛ(ð=0Ï·ÙÜò!®ÌëgÈr”¤¤¶• õŠé}™¥§e™ë~h*Ô.zË‚¼ÂœŠÑ2ÉgW¤d6ÏLòN zCq!íò6¥¶SäÏbs5ÍÍAâ‹ gaO–ÎËE÷êÆ,\—Ô%Â!Çúil €ÌŠC¨¢r¹NpNíJƺÚäy(ª$“’Ma(ˆkžüÐôþ9z+–‡µ`ÙOBh<0AjºjX쮕®ŽòÐ%̦z¹V/�ó;åO½\îkëâÚã‘lçúë¯ç3dPj®0*{³ktá4Ÿ–!"m5$¨{™^×XqåÊ•L€¨/ºüøÐÁCôÅž»ö”ýˆ¶ea·{ ãÏŸ}æÙø¶þùxÛÌÍ—ª…= œ~t9+ø,哟´&ÉÁÆ>|… ¬ª�ï¥*q87–’‹¬·éLÔw?4qüÜÓ’°^ÖBÄzñmû¦”£.¼…ÇŽ<Fj-qhÊyd«‘Û¾=е_ tÏCïE·ûÕqš‘bä+e‰9‡ÈãN:Í>õ™Ó{"‘ËiŒ�Ô‚AM+9‘ºmÑ› 3?ârSGÌ;ÿ·Å¯ ªµ…}bòðmŸÙ–·'¬r]üºáõ%¿J‰Q-nx^Ž¥°R~Y©Ýù»´ÙÙYɸzy×—^|© Mݱ€sxæég†|' PIy+¿æo/^¼x๞;ðôSOsçík®¹æÆo¼ñƉ�_³fÍ?qè࡯ßýõ¯ßýu�ûžÝ·ïÙ}² 9€¯ßýõK—.I²áØ+ǼèKÿpá×]wŸä³Ï< 9š\™û¾¼$à°)#Ó!Ö½bçG_Û\£ç4›õ††É\¾ ©i§×_Wˆ›Ü¬•ŒäR³$±BÍÁK¿ôʉË~½®ô‰ÙËNLvq¯óœ‚WoZ±¢Å›?Ø­a ¡ÂjnÊ ªLÁ¢ÄG{Øæz[pï+~mëL!ûçMªeHÇÑÓö{m©ëh«d'çs,>ƒT¥Æ¹F 0+£tHTTèÂL"$>¯«Èù‹À0Ê Éõýº”0^ùAµÿDô iÄ*‡·œ±;+ÞùÒ‹/m½u+F–êJËPS" p>õ©OY$Üd0zí½gïSO>Uö‰>ðà#ß}$˲³8 àÎwjú¢Š¨¿íöÛø=+W®<zä(¿áëwý™§Ÿ9øüA– qüçÕ¸rPhíQ”êç“WÂBkyÉŠo¥³*`N’Ók‰`eżTXêhI¬¥¢ŠßZ†*œnâ’öŸ²\ÒòâƒÄ0ó[^ïx ¤¨öa¾¡ïêaŠëÒ*£<4‰ÏÄé|‰õS™=¯$i£ “š{„SX’š.€.ýPÀF†¾Â'ÅÍ$µ`BArP¶+JÅE%ÈÃN`½§mšå&Ècmeêd¨Œ²œ@ë$“ù±ùœ{ýÜõ¥‰†ÞvùŸCZ¢¼l;ûRýóÜÊ‹ˆÌœ1q:g6´:àófã.­½”£wHå°÷*¼µínZKç•é:"g•ý¶Þºµ•É®ˆþ§Ö`òt™·‰b>oÞncûŽí„²ßzø[ß~øÛ�ö?·ÿšk®¡Œ#çqo¼ñFêGÍãùÏÓ™TpÔÏ<ý ½‡¿°°sÁò]BMVÌRëì²Øû"—GÓ5Òi{³Ê¨ÚÔHe.šCþ…»]ˆ] ¡•z”`ãí'\F,‡f$¾Ÿ.S M“º\®U`;°<v(|�Ô;uYKêtƒá[j¶3Öa[@ðeB¸ñ4¸S‰‘˜ÎpÖE%&þYWÁØÏ—j·ø, ­ká«DZ^þŠ ÚrŒã8g˜T™{6S8ÇZC$rcyœa²({Íõ))x+Ê(U˜$".LÄ“&ó¯±ùÐüp /Ö}�[(žÇ朤&þk£ª]®ÇY1¼ï¬;c™oxß°ZŒ_‹÷´ ÖþÌ—a>-†Åc[nD ¯^½úú믿þúë¿ð…/|á _ bJËeþð¡ÃLz?òÝG�ìÞµûºë®ûÜç>÷¹Ï}®� 5‹¸³$æo]Ô¤1<d²"ÚÅÎyM`YÚ•Fjz³]ùY^ͪ·qZÅ–)5¼tq[8¯z-ú`îëáˆed ƒu‘&¦>K Ë=ÇÒ¶XK|ê™ÀŒê¬Mƒ[’‘0µ(@±-’Íms&£’LmìtKy£—q°¾¯Sgljv_J|ÖíVÔ†·6*&9×W¤�úªà$V¯ ñ¨Åi'ñDÇ©11º…†H5faØŽ…l*`ù¶ò‘HœeÛñ<BI®4BõAyl>Ûð—l+¯ºQ¶l]¨žÓ2†kKzÐ{ÈUgY娶¡Ù¿oÿå\‚7Jß^᤬5¾õзžxü‰2è:xèàÁCÿý¿û÷¿÷¿þ€›nºé¦›n‚¶[¢Ál0ÿЋ߸ïô¶Uz�øæCßtQÓJu/,Ù¹€A¨ÉØÉ9fÊæ.˜ªfTX¡Vä#c3åãÕûÄŽüÇ¥|Qij´ÏB(õþ±©þhdvŒ›:^3V¢7q|kŸ$na¦+(h]zó8ðÑËÖ¶…÷Bßww¬¶Õ0m Š „ô‘•®­å~àí‰f•[ˆ˜¨Ñœk.S‰LÓê~שÞ7�HD‚¤T¶2‡fzõ]Ðý®3>±<Ö ;è\·È¹<-„ñPZRž”ŠúœÄ1ŒXíæ¦AâËd'¦ˆ—ïmò^xU÷| Œ×\sd;¯Œ?ªwTˆK­7Ìi÷ÃoXŠÎ\Ìu{›{Éêê@Sf@yÚéW®€+Íj½^'±ñoþæox÷ÝwÿÍü›'ž|âÞ{î%ìÜqÇŽí;¶ŸêÆ¿þʱWnÙ|Ë{ï½GªŸ_zñm¼-ÃM�?ö8€ïüÉwøuÂN9þä;R}ž.r{Yz~Q>Àeî;ùE¡®´oÐP›¹2¤™+ûÇu¥,pL͆V,ôuDEY›@«ü#5c ¬§Ù´ N¡º¤ÝÒrcn·¼5ò’·]ŒÊª󬂨Ñ^ÉËIMS·¨$[VfÄŸèzÓX††¾ƒD%ÆLò ¥‚Øä:/Èø¡…²ú#°‰D*=ÙEX$Ys>¬"oDZ¾Ã׫*RÀ©S]>ÛÖ=«IèDiÎD—{&>ëö´¤¯4èNèG¨í{tÕ[T3Ìf›ëؤmÓò?·¥]U½5!ÞÕÄ»B¹L1Ü0ëàb…†é8㋈y¼‰X·ç¥<IöA¤ŸÊ“Yµj•tI\¶lÙg?ûYh³ž‘‘‘õ¿µÀO>àÞoÜ €„²Ûwl·N즛nºeó-ò•[·Þ*’HÚÕ«W?þØã}ó!�O=ýÔÞ»÷>õôS€}ìÑûﻟ9[/[Káæ‚Óœó2'j‘Ãì)+"ÎÄۢĤ1W;k8>ÜvK(‘“À„+îŒX÷•–&¦È"rruÒˆÕ5Øs‹5=ÁAI+f”4Hq¥’©YçQ¸b(AñÑ"²2¬IáEž‡¢d0q(è2(UͶô”²½ƒìO©S†ARÉ =}o¨y˨ž·jGšYòcu!rŠø»eè½6*ø �Äq”lŠæ$rdAJ–%‚ïÀέ§1* 1!L£&+ÛQ4þ¬Èa&`æYQ^ËûßÔ`9L5�—+lòàæð¬aU>txûŽíK×ãÈ G\³',ÝqòG'ßyç¿[õwLK(W¼O7âƒ>xð}ìÑk¯½ö ¼`û¶íVþ¸U«V=wà9�»vîÚ{÷ÞWÿìUÜPGû¤ºüLç yŦŠQs[®ŠˆÓ›˜ô«”d(ãJ¾X0)¯l—WSÀlB鉱¯¹•—NDù9Ss‘%¶0/òy|O‘ŽÕ½ÙuñŽ QŒ­:Œ„QNlvÆÖ1"U*2+¶5 ²<®ÜóÎíhKQ®pŸ0ýƒ5……¬é½žŒc}'ߨêFêâþ¶höºYZšhs%g+À•!Þ¨Ñïàd‡N#èëÛ$·Da†~aÜÃÕŸAÚå‘û•ÛfSøˆ¦¦ˆLöÇNMI6un$*^àÛA¦úPv ”sçÎ-€!¼šAæìììÇ[TSi\XQS/£:É b>tx÷žÝ.˜Í xe› Fr=ü‚:”¤µ¿åq–ñ‹_ü"€Ï|æ3oâÍ÷ßae>öè{(õö;rô�øôËûᇿõð²e˼ÚZ 7W¯^-Yb~¼çde¯ð&ÇYíHg¡æâË*I¼´j2×ùÀ!Q½h Sú˜:gBœ­k“ú’|± §‚ÌîŸìMÜåÞrùuèDÏ|’š…)&Š P3ôÅi$¾âõuæaqã‚` Æ5äH¬†­ÁÑDwdñ焎&5"–ËæÒ$-¡5D…¥¡£é ®·. y×0h¢×EììB”QQ ³]{"‘Žì:pSã0½ ¥³UÛÉÅ 8ÎDnt»q·â­ºû•Õ‚±†l±à€àj—_GO eU‰xC@š+6¥o¯¹æª¬ ‰S§N­\¹RŒ+±{Ïîý‡öزu‹uÌýûö/�žÝAÕœä‚˲ØÁ` óʤª×ë„ÙÄ óƒ÷¥ÿíKõ×E*Ü‹/>ü퇱ª€ÃU«VÍ+g-Ï|Si+_½gò™¦[·Íˆ‹^V§åjG‚Øì½ìžÞy[1§:?W÷f†Ä’ §3Wb=u34 ͪÓÔ kà8¡Ku ÌàiP.˜ŠÔ:ëf ³Ý"L }Ò$Ã50Ãd-dy]P©‡p#‘ÇMJlráÌmˆ­`Êi!A³´'S°”hƒŽ#Û" Íüù½HRFÜ Çñ?×ÁwjÄÖä´3è­"o�ft)gêÄ—a‰J‚æe›<ýìù9O¾¤:¤T;ôPJåí×V¦²¾Ú¡é5×\#ó£xyÃËVÄ&^ë8™ê»ò"&ބ֒lûŽíÞÈr^`æÝôXi¹Ý{vïß·ÿå—^¦o·lÝBñîöÛ-9Mò»ï¾ËóyêÔ©S§NI¨ PÐ…ÞON ™jZ1VY,¡æ¿úýõꟽª‚Îo=üð·† ½ÿþûüæ‰?ž˜ü³É'Ÿx²zZ*Üû†ôX²Û»Õ¶år"Î2ê5.GÓÄ‘¿Æåëƒb[´•ööûô®ér¹o‹8)1»bÕµâ£]¹€�˜9C_X ßÉ´MßyΩɱÛzNŠƒhòåO'g¨ë€/5sÉr 9ä¸d}—!yú$]Œˆˆ*A ²ž„pJà‰œ__ H[çþ>©Þjô§U9ŠŽ¥IPC£‰^WyüNšù锎ŸarÖMåõ¿þßi7ïÝ�� �IDATךÛn0ª=uÈHqR@$âÅq¬W53Â3H2ÒÎcïºÒÌÀˆSõ>@ïoà³ùMÍgÏ£ª½š‡ÔÊ.)ÈUstsÆ üëÕ ÌE!ÀçðñÉs”OE[·lõ¦å$vº¿üÒË„ s~ô–[¶¼üÊËCž˜‘Ü]éÇKJs’-Eœ7Üpà þéúôïÀWÿø«ßû‹ïÝ{Ͻ<øÀÃ< à›}ÀÙ•gùÚkµ™EȸÐKÕÎw¼˜¼èMpž?Þmy¶ˆÀÏõ£¸’ã}5(iš1§œ—NM,CœÝ½åÊmIŠÂJŠ8*¡—SÓ+f­žE#·Ëyo÷•ÔéJí=ÙS8}7yËÐ'ç "WWd1ízaD§/*(z‚úúf'…aGÀZ¤TîW2ýxt1"HÝ>ï ºZ]Ã�ŠàGå˜áTŽüùÿó`ðGò‡Š@Φð1ô0Ý2Zƒ(ï$âN8ºžAð©Æ"ÓØ]‚´éˆ�¶1…°o$ëÁ Ì9¼6±o…zkÖ¬ñ®&–¹c[¯õ¼êsãøïŠùñ2')§š'SžFõ™ÏiasôÈQeJ'ÆÖ-[ÿê¯ÿŠÈR�ÿðÿÐ÷ˆðÁá&æÒLýêW¿úη¿CØyßý÷ sá2ê¿>™³ PóÆOÿÍßþÍ¿ü½ àþÏ?ðÝG¾Ë¨yùl‡b]ȼ5¾uÎàØ%„åo¹c˜^*iyÞ%õ­é¤%¢„ßZÓ­j×Ͻ¬ÊÅMѱ´óˆ¥*Òg›ÉBë*Ê,CA½†>{‡Pôžt£Rïäq¼ðpS³E32“Lt‹Ê´$^'U=rÝñª}BzQ:!ˆ9 ©Ã¥îmé ʤyã C‰&Š*åÝCQ#Z˜Õ6öË×u´0F—ÙÂ,½MgIå$´[˜%Umð òo@+˜aAú�RbzéDZ¾‹‘&Ș‰Íj˜0w‘vN€ótñÃj#2p k'Kú Õ„s*bܸرéögÈcQÂt wOMƒÇ®ÕjµZYúsNCö!Ç•çiçÛaêò¡&Ù·’ÀòåË·nÙúʱWÈ€|äÏ;Ç7âÀs>©‡×†Iú:Qÿê .jÞwÿ}wï½{aH‡Ù²ü³ßüg|øÁ§oüô/û¿ð7û7ßû‹ï}ï/¾àxàÁ¼†S—ߢ€ìéå··Æ·VãŸnr êS‡8½rÖj'wW(d¡HâÛ˧fš°íëV˜:9TÛ @hka‰2XÎjöº¢øº—À¡U#³¶=)a­­ÿ][Ò›±Ymb îPK£”‰ðWÄÖ–(vj`ÜΑŷ°¾S”©ôÕ¤‰À á×Ã&fº¡ãκ*gsuM ƒ ˜žÆ:Cø�i½®š¶@C ín³Ð]œPŸßFí;{ ú 鿣"à›ÔÄ~ÔA(Bùv¦SÔz ák‰¦XÛPÂcí„ ÊܰÔ<3C5”=o^0LŒ·…Í}¸àZ^qÞˆ=[X{¦+6(‚‘xÌ0éµÛµ*ß+|\Ý H?Ò¥ÊÐYQÇ‚ç„ÆÏ~ö³_þò—pº¶U8°Wûî¿ï±G{ìÑÇîÞ{·5W§OŸ–;oŸ8jqÃO._8Õœ¼ýöÛ'Þ>±ö_KqçþÛÿü‡ÿöñ{�ùß>òm”q?¶ÞºUY盨I¥™óêVmQµ2÷YIýDeH—”S£Ö›½­–ìe² ëÔÜ@¦Ø—4 Ez"úBCè/B«x¹‘ïÀ ecíþZÀ¿6¯‘YX¯^#v % ±];ÜT„¼ì§S¸ÚЙ¶ï’­ˆ9ÑíØbÝï3Báå&¹ÜHTFÒb‰<é`#²Ú÷5,à!G=óºd˜ì¡é$8£ “5Lè ,ia¬…™ õNrsi­³¶N¦RØÉ¢|üÆ€´…Y "Õûm›×ü"GØ*˜Kͽ·B‹„!0D{/-ÙÕØ¬îZ®ÅÆAbÂó¨Ž(Ê0I™]GƒŠó´j«B/­ÇƒüçØOŽ›Ì]yüóúÉ]…f³óŠ€ÉÖ@sØw^Œ‹/R°HÎm×^{-™Ánº_W8ü1j>þØã‰–m¤ÜîÌ™3;wíÆÓõŒ ›êÿòÿþúâÿíÒßzø[üÓgž~FZérMã£>úè£ÈÖñ#ßX½zõ®Ý»^zñ¥szì{vßÞ{öÖjµ½÷ìݶ}}ÊŽ;vTО;àMp™òüDe1.!Ž\xˆ… ”+(â)|…eA¨ùFé3n¡TZÒn,,7RÌî–i{™'ƒûbX’j•|u*€0E‡ÐÄc…[wâ|zì¬Ô0?%1ùÏÄt½OõYEN#޶S{»Š€¤¼¦ó¾Âr2J©‹ˆÕúÞÅs cZ{%7Cé8Ö‹’Œ(C½µ’jwõ´ÕäÆjCÚHZ)mƬj£ãèuq‚KY2LÖÐ`ì0W©Ù` .-·¶AºbG]ìláp«w„ÊzÕ‚™7M «wFÐb_ç¡0jÐd¬n¾m¦J›Ë¿„eG ʲeˈ[.¯õÒ%Üõ€%Cã2;G~¼ÃE÷k®¹fIÑý|åà·QvÓÊqî½gïÙ³g©äÝwß%A,y»÷ì–¢51.çlY;¯1 ÿèT{½^¯×ûÑ~4ùçÅŸíŸ<¢Ìö(Ò½ãÎ;>pλS=víÞõÂá�¼pøKÛ¶o³^á­Ïùóç9*eŒÌó<ÏszQ>Ü[t^TmR®úqéD˜nsð¥ˆJðرïqßÈ9±¶£M´¿š•DU ¯˜ú(e+A:à'©lÞ:ÄÂݦ.¹Vñë‘oeŒÌžÛVj»²‰[agØÂ,³¦ÂÎÍŠéÍ¥‡j<Žãœâ. å£Åñ 9¨òp_3æf;h'Áöx@Mà„éî$ß‚IæÝU 3=4›ëâÄ1\rÏé45Eöª)ɧ[ÁL7Eðihº84ç!‘V5 º�Š’ÐIS­­²�YÁÙJA$ÿë¨6U)Û"†Ç¦?àŽªmÑk%¼ÊMÞ½P-#cÂT¹âÔëuZ©*‘GZè½×êW®\¹è±5cçeæ8© èðÙM½ÜºL>=‰zÍŒ¸¶‡Õ=sNEcÔezÈ#mãæôOžüóɉÿk"y1yïðOïÞ{÷ÓÏ?=_âZî øs÷Þ³÷©ÃOí½gïðíN‰€%ÈäÍßòåËéŠîÜy'+‡]­–ÁïýÁý»‰Ûßüåg?üÕ¿¸öÔž={Lëê°ÜŽ.u\¿cŸËyRR»¾–}]Ðl©’\#ÊÀÛÁ‡L,·ºrJËÖÄL¯–9ëÊ8¸Ëš¦Y}ÛΑðÓvæÍ”ø ‰i 3]Â3­ß1»xš\t®ÛM3¦w»ªX¶Ø4Œc=¡¯tÒ–{f䆆҇uÓ°ž WT•¾™Qy(«ö7GoºÀ×¢‘j ³=4ùœM# Ú¶ÅEÑå4Í]QñSóŠ )®ÎÐÖ¦b×¥&ßÄcõ¨Èl•>nÛ6lyƒÅJ¹yDN_I]¬x—Ån¸A†�Þyç«Ë&­Gr >{ö¬8+0r˜k¤3¼té­z2†«×ëòüé –edd„Îgݺuu ôfŠðdìè:†Ë3¿îºë(Û'g•2”(Ñ|jZ 4½¸eëyG²,“óIðéÎF£A±× ýg?ûYŬzóš•94Ã+V¬  çd§<Žu¯inÉÏÁÒH{+Oø–ÑåУÅí6½Ê&þDïèÒ¥Kœ¼äD/ßz²ª'S@¾/Gçøã‡ÿlÕ5×õßz#ýÿ¦—ÏA¦¾fVÔ38KKÚ2ÃaAãò¼iìÃE¶‡ׄ%ÇLœD#|N.R—T¥,’ÆL}õ'¶È¡£õ°&Ó*ê‡%NÌÖ+v]¦¯îźAºV|ÜŒMØØÙBá8À4=·6*èß„ïOaÐîà$ ó BÝâddÝwKEeKdú"S®ÀÐÎŒܺðÁˆ[˜íjpê úúS�-ÌvÑî"‚öæ†þ¼sjÜŒuSE½)]ÎIyw2ãëØÓî»�ȈJH[„Æ_J  žËÀöÂ2uk}Ç?òöîf¼óÎ;øïfTÏ +TåÛ\Ôá©~þÀóÞ˜F9ü-ó»äÓ žöæ]lJE–¿úÕ¯±‘™{(/�/÷Nh*=4x†%pòM¹{ïݳ³³G^8òôSOSèÉ{,é8‹*ÒØ œÞž'ôÚ"ÒÄW㟚‹oⲬ¾wÆ>‚JðÀi‡³ÙSXï²ü$Ìl¥O™k®kc±\&¢FèäYÇJ0Îì£f~Z—4߆Їæ¬ºhÎö´ÔSs’L«¦%_“9~ªÓ„´ohLá”>Úˆé+g¯-Ð12%БïÂqŸÆÂƺ8ÁѪðœ:!o ¾„Î ‚Æ´@wÔ1•œðSØ m{å´È?‘¸­©Y>²ñï¬ï0 ÀFÚ<Hß‚D7Gó¶qý†W;C Óõ×_†Åþô§?¥@æ_9J«7 õ‹RMWærýî£÷?p?JÚDS¬ù[¿õ[І¿øÅ/fffqY÷êülòUPÓ«V­’ *E­ÌÊÖëuê5M'G¨táäÑCæìõz~×Jœ_¼xq¾µCsV³XAs²jÕª…Y2y¹°AéÕ #ú-cóc_‡äX¨U“Ê ¦É‹Õ$ñ­±™UX"Ä&‹¸¢¯g¢Å˜-6´0#ÔI)-ç£D”®ÆB­#èÈ|1¬aBX[bS%Óœn©%G½Q†º�Kí«”å™ÈÞ¼Ik G- ÙHº8A %“ͺiIÛLÝ¥šØœÑgÕ¯aPÃD  -Ʊ>C¿† ìÙîfÃ垅膶tƒ:hiÍ uzg£ZuÌ*\(ž¹À*uíãXÏr*]�ÚnaV¶ÅfNž¯Z49ÍÀ>ãYèM ë­"­†èUןÆ=iÑT˔ą»š²+”ã^æC.áŸüä'ɦ"cW*ƒjw óNÙHNåè™3gývï¢uv±êJ/sœ>}úùÏmó׆¤[aÓö¥ˆª­Aâ2«é7Mã… è=m³W*fùWHeÆò´«™†7uF×½`¿2qPR™&”e‘™´‹Íž!n+G/- ÇKNõ$ÌâwÝs1`ÍE*È=K¬f4™øÐK†ì@$U?…á‘„úú|"_×3KãÚ.Ü&NÜ/ÿ·ˆê>\€Wg HšèõÔiq¼0òM4nõœ´si ½nÕ…ºÊS%J[˜éàÄ8ÐW4i¨§Kq³ãèM«$%Imû›°nª€vªŒ¤ˆpD„‰h¢×à  •}7Ó°¤N [˜éb„Éáz]œ cj{ä0óC°ºPÈ02ÛæDäµ+bè‚ɇQdÔCS fnóa-÷L±^ÎøÔ§>EI¦÷ßßJR?mØeXðqaծݻžÛÿܮݻÜ-¬t!FƒÿçXÃÂÊ9Ÿ¥Ã²³kÙøÚæ¯-ÊÕQWj1×­[÷¿ñ:Ó¥]¸pá­·Þâl+Ù�},5Kùæ!\h´öƒÁ@æ•éëÁ`àRµ«V­¢M…ÚœýàƒÖ®]kaç3/<3ßÒR/pº–¸œ!„ÃÈEŽ2°í$“òܧ•+}nDmán5©€[È<¢Ž]ê>šN"hÕÂO 1Ík ®RWz@ü¢·ag[¯Îp¼ÜdÊÓr`·Ú€Ëòy™ƒ”ÍXŠp)ìÓ†Ó¬]Œ²E 3úÛ~'Ʊ~ºä(Ç€�ŒôШ¡ÙA½†}ŠåçÐÁFêÂ)q_6(éM ´µ[,E±Ç;ú¥¨+Ë„šûÐæ-ÌJ¶‹v ÐM¹;"rqˆ@=cñT€ÌN"¤¢[䈫¡3 ±/ïÀuR¤BÛ\Z¼3À|Dìó®îFb/7sn/^üÌg>Ã@B‹ÑéÓ§IUÁb ÂNK⸨Iëé§?ýiƒœ¼jFM¯¡.]È~ô#"iß~ûmZˆ‡1fs¯ñ±G“\ùä1<È%i˜™‘Ië5kÖ0˾|ùr2V¤ã¬Y³†’‹ô¹”μ’ûɸœ ™ähâV•\þàf¢<ÿ»÷ì~fß3V™˜2¾½,Ç 3/ˆŠ?éf»vï­Ä·””Ų0±!©dq“!‚cù[©UñÂßj‰¦ÕÕ$2Ą̀ÖHìæ!º~T(•,ùOêì<(dLŒ)Di+kÕe²>ÖÃl˰’s“(Œ‡Ñê’ƒ!öºKXÑJ8”¡ÞÂL%û4¤+ZN}Qêä)rs •d¨åvcLiÓД $9Eša’ò tu= €Énñ°¥ºGzîs‘¨,‘îHzJs `mjh­"u¡'‹BmA•H³‹ 1´bHüh»|Àê¾$T¡•á[ÜñÉO~’–oZÓëõ:Åp¤ÔðB…7VfP—?¥b»»vJ¨^Š1 æ•H{þÀó�Èý•OXê`¸kÏ]ž¯²ÈyóÍ7iÝÿÅ/~ídÄw_ꘪñ›Ï:Âo«Mô⦮©³›[£9'f¯\¹RÆ©Ž3X–5$°:§’n¹" ]^ÂÓZì¥7ݨvîšu{ƒÄ¾ZÌØÑ‹ÆYÑ(Û}]梬N™(q˜‹¡kìhSW ¸}±)TÎ22{bÃ,Wç ÓÚ4ÀO·/˜¹oP ž'U)|6ucRT7íRBž&z] CŸhLbV)ðbñj 3Ý•SÝÔŒç0ébªg`+cá´“$·¼Ñq ¥1I 5g5j¶&s’°˵çŸ2ó£‰MP°Çj×¥kXe{Õh…ŠXZfzh’gB½šß/­:6«bl]4óÕ℉¢?ÍùúZÄ”ðM1ù:ó´4Œ8ÛÇúÊ…ÌUJú �Ecô+Äõ•)3‰ó%ø|ã7�üÓ?ý“\¿¼ƒêÙixÝm¬¦Zj [¾œN•kxø½V¯^- ihÅ?{ö,Eu?ÿùÏ/ùº‚ Ø÷ì>îûh‡Àl®©*C–ÌÂJˆÞßýO>õä9œ“gõÖ[oI’“¶/çΣ³¥‹š¯3íÒÕV”V¦Ü¦{äu[´Ø‚Ùó³[®%ÊìÞ³»ºJjy98y».ÃqÀIl Ê{OzñŽžÖJg¶+ý`ÛVnU,L®Èˆöþ±V3 õŠk©aÐ ¨ô04l ã’,)„ÌÕ:‡P– ê~ÑÚ  r\²ÿÖ'H0}Ü„@q†ÃT”BRûI�i à„µ¥ •MK™Í‚»nmÀt)nÂ÷§.¦D c_Â^ÄΛ*tia¬§R€LÏ&:¾$ER\à+|…ÌÍ„À‡r¢¢Áµp9Ð>c]ÑL›ðž¢Ï&²â© ~•º¡+Zšgˆº8å…”Ôjç©X³×4ÆÑ£+ÒØL_D‚l*âˆuÚ]ñHKQ¦*dŒ?%­tÓBsÞÅÂug•ùǼ–­X±b‰úW— #¶Xáy£¦dAç9ö=»À¡ƒ‡ÜžÉ ™Eöôpwd[u´s6/ãZYMA…<}ìÑ¡úZÍ•½5+k6Éü[óE¸ø¶ø¹£žü´—®ð>ê²Ùç0‘'Ég™tnyI¸YÆ|ºøZ& ·8Õ¶½êA&Cß¡V%ý•ó½vUŒ0ªµl€Øðý1º]¤¦‡@èàb$%&0§¾~¢’»¹v¼+”>ZS8¤Ã4E‚hͶ5‘ž=ªÍÕ3ÙÖbdÐÄXM°aZ;˜Â$s¦;ˆzht1Ô»&_Ý-R†“ìZ°Óµ Z˜éj?ØMô¤þV$Vãi nÆëSˆIÐKD-Ì�³ÝB4&‰|¬àöy6Ʊ~ t]¯Ù.Þðù‡§BÇj˜è기k§Š#=ím¡•më‰Ü.´….=6¹XÉçð ¹6d=-.rõäå†ñ•V"Ǩ4bÕªU”ƒ¤ˆÓõXŠ Ù]÷oºé¦ßþíßæìàO~ò“7ÞxcÕªUtæ,qbØ÷ì¾=wíaø´�µ€Ò布&‚E Ù/^¼H·Fe Y@ÉÁ¥|¿æŸ°™ñ’|åÊ•—ß‘t^Ãòа÷%%ƒQMÊFFFèï"Ë2"?æ;öïÛÏç3O?ƒg<>GŸ(C«22ªDP $²W\ÒÕ²ŒŽ„§­ª)Œ0”Ы-’j’ÚT¸½3¨KÜŠEcâÆÂ®s`x“ÐØgŸhÓQ>+×5BZ÷‰ž_y\ úº¸ïq’¡®£Y:)E=äçëB‘†8¶®îŸÐÞf_z?ÕKh_½À8Žk‘ê õŤž&zœ$§òqô„dưã/ÂÄ<Ô¿Ò¤) <žaRûÊçŠê,Ó õ)l âý[‰N¤„‚¦@º­/“*Ž"wK^»ƒf†I­S¾3¥s¦ÓŽ?J|«㶨«é‹ ÑU(†áþ8ÖëÖl„¯#Žó©êzž¶™H€D%çñb郼Þë—ðÀ–Ëë{ï½GßZu)Ò»•~tíµ×Þ(Û¯{q—Q“Æ¡ƒ‡ü¨¹d£¢@‚Š+Μ9Óï÷ûýþ)=æ<æ“O<9¯sX¶lÙÚµk×®]KŸÈÀFõKì·N…1ôuà¹o¬X±ÂªEY¢Vn}=Ü?„•+WŽ8¦©!9!x\}ºÊ`Ìi—Ô«„¢ž$5™ØX�jâÄ‚V‡gåŸ.xE«£gbµ«¡az”ÑËayím‹ØŽ =ëGb&9Í)™æì*•Å6§­`F#¥ C[#GõÆi(}(¯‹ŒÔ3Š{¹Œ(µœl¢GM²¼>gf²ƒ´W`7ZâB9:Ü„ï“ÿ\ ãèiLñ)-ÌPÜÜC“?N»Ãˆ:8I/Ö0ÐGͼ)¥3#³Àƒïl[³¦cÚD>Òw1¢»‘ ³[þF5 Z˜eТ QúMK½DÑ3,öm™AvÄ)åMIBlÖªòn,¢] ‹4jª~œµ`�¤e᦬¢ãv†Äൌ[FHc÷+ oï¿ÿþûï¿ÿÆo¼ñÆišJ”]t _ܘõÌ™3üÉ#¡·Þºuë­[©ƒ‡‹šÕÖíô­…sn8¼%ùsŽS§NõûýwÄSͨY=ÿ¯}ÿ'œ!{§ðmRø/BBõ™3gè ùNn]À!5 …*PsN®!^á(ñ"(<B…*ÇËÄZvbn›}|!y‚ÔHyšÝEb§&ÙQ<Ã,#*î™û˜2—Z ¤#±ìŠIP+„ÐÍY+›ˆ5—¾P6DÀFé×EJq“j¦4äªS6¬$-Äm¶0Û  ÛãX?mˆ?‹ŽfT­¤S…v”ô¢MMF*!Ši ³ LwŠV'¡T±Rè¦CÒfMIp'²Âp§oøŠ©Ð½T£®ògçÊŸ­V<±Q¤ +# á©éü—ÈjÝõ%ÔÅ-Ò© v7aݔ޸ˆ*—ÂÃoÇ;[+'†HYsf:žªå1gùsY22óZ£ñ¡¬¼šõSoŸK‚¥V HŽzNŸÛ³gÏ~ö³Ÿ}÷Ýw©æ„.ÿ­·Þ¢|¤ cÔë‘¢LoßÇEÌ)º&/^tQÓ­ :þ<]¸e š{î½ç Ÿ†¯|Cò9c§åëËVÀÖNeÀ)Ë%]? Kª ½ô}¬/b3®ô^/^×ë>G ¬0 ÍBÉÈldÝö…’p€¼(Ûð 0™jaËP œô)µáëø˜^taQ„£púVH[TsZ­IéPíMX7ƒ±®Äž%„=©ÖvBƒ”v‘@µú ÉÇ€+CP8²†@ÒA³¦|p@O›'(½~:¥é®*U¾ôÑÔðd\ÑE”‚m¢×iZjs]+Ê<”¨u¦g0ÚÅ‹’¤| ³4¡I óí4!Œ›úAM¸°DF™¢™ û$m2yÇ@Ç!‹ABtQ“JÙÜ‘µ_™7 #M¨û®Ó«‘®ñjPÉÇ•ÁªùŽ4M%fÓÿV4Sz²ÐÆ«ur1ûàó‹D¥ã:xH¢æ“O<yϽ÷œÁUݼ‚â.ƒ±ŠÔ8Ý"QW¬XAï$ä‚`vvÖª?YôöbyiÜvïÙM9Îj+à ç ™YLDj'4ßÐÅ‘¡TÞ."0mRWŒwêh‰ $jx¸=8Ë:±Œ¨3šPš‰L§, ®±02ž“úvüo°w`(8ÕFf¤�É‚g`VAV˜Þ¼©(81­á)s›ôЬ¡I%"Eè#f›íï{˜h*/U ’ z …±®ØgtÅùw"G?˜š54š˜éb²««3i@Îì¤båbSR'néŠôgÅ�º:p¤lbO_ˆö7H:EЩú™è{m45ãÓnÁ@ï ýѲ1ˤ0`b«‡aC‘pŒ«µKŠòhuw›eY©à×`кL˜g­VVEì¹Í<tkl;.;wŽtIRòúÁ—jÈ�� �IDATC+ù:.»¤øCI|WXD…ôuY”Hnddä2gôÉ'ž´J—³­We½øm‰Î¼Î,·ÞÅÃLHuÄJÎÖWFâm" #3Ü´Œ3\ƒù²HN"«k":^*š“´(3B¡âº);q2  ¹ —YÓ–M‚Y÷©ÛQ)›ÀÈT…2ë‰@1äT\AëlǘØTv&qg€ 'ºGoZ¡ªM)­øÌŽfª†'2c%,Ó¥µŽv¢šP5‹ê’I4«ë5CárÐ.:yåEÂ/Ó{54€ ]lJÈ4J*Ö&zZ.ÔçŠLÂx¨ÏR)-ÌB{Áë(–I…£ÖèŽlÀt of© h”râ\ÑG²ž.¸"–ÂÙrÉ ;h68³ûÒáu[•+ˆ×ºløÁ¿NT-K±<¹bNFˆáDBÍ;î¼CBµ×yàÝwß-3Ú=öʱͷl.ûª.¥˜sÒÊâ-×Hë¦jùÂ+nAëw9cÅÐe–ú¸¨åýåΛïçç­º³Íð9N/ËZ¬ÎfW,#C™È;ͨmÅ¿IºÊ8Ï‚¢ÈÄòȉ)-»¢¶‰²¡IÊ•Ä,^5 ¨2$´T•§•‘í—·a‰ŠòÃú'Ñ­ãâ#Ši@=]ƒ˜0K©éĆžƒÔ\û ƒ*¹X×±¦ö™SñeÑés½Úº£5DI[ÛÎ,ÎE@Ò@_”—GšÐùÔÐèÐÏ ¹hz–£[Qa ý"‘œÅ-+šzNp¢”v�Ý¢5&ݸ™]}¯ió¡yì6%kõÆ‚ã†è6Ī_³Ö©ŒŒõ¼EÚk×Ê&´Ù>‰ç6+Úy*ŸŠ®AWðU'–¶h^Ä#Êä‚è ¼ø4(8`?XZ¤¤É-Éä’jvƒðŒàÓ 7­ÁÊøË—/'Ô¤6ÎÒ]ÝTè¹Ø±å‚58T‘"áÇË‘òñ]ÒÛBþš³Ú²8äܹs öiZØ£Èg¾XeÄ×\sôÄX”ñ‰:ÑýÖUúÄ0m26)ê,±c2¸êF¡N=N˜P˜¡'WCBTÈP/ñµµ’NªÒ=ô™6ž9J¨ AÀ²¢- ™¿ëÓŽÄåëÎV¹nÿ tp™jq¤…¤¶ÐÄF@ÔCÓíïÁœçsg†Mù® c÷”i «Bê¦9 ¤Un ?Žt"³‡&‘Ædï®£Æ ’Ú6Ñ#Ì €ž*.Ú„u”ÍíâD#|oRÏZ˜Õ¡[ß”zÉ}RÜC³…išØÂX–×µ`µN ä.NlÀt ƒ›ñºh´ÉS¤ß°…1½ùSVÃ@w1kwpR¶‘©¡Aa:)œkhè kšèѧtqBÓþYêÀÍx]ß8£§ ÆPsÑñj¾ºýRH¤úüç] ëwÞ!#B)¤&RÄ7Ë2»^2dxî�€§ž|ê©'Ÿ"È\ ¯Tkž?Æ©þæCßæmçÄà¶'4½²È„ÅÞ‡ºxñâÅ‹—û†TÀrÕÐGæXô+½FÅ:`uŽÓr·ÑT'u¼&é‘èA!!343¦E¨**:bM%>Í-|ˆ•øfë„]%p»*)›ë,`?6°³ÄY).2g9² ¶f¬UÁkˆÂðO]f ƒ&ƺ¢òã8þ¨ä!í.¢šAž[\q¡³ÍCÞÅÈ8¦¹ùeÁ'«èv²£&ù¤8CÊD6»ú ™RKyB‹eêÀqæ·_À$‚dë;šáìã8ÑÂ]%¡�q ‚lU`Êó“ތקpЦ´…±z|#Ê7'›°nJ';�ПÂ)ÎÓë€5aùÔSLßÂX×h‘ ÚÂpFËŽf¤U“ðshw‹´¨K·¨2­)#ï`yA¦vðÄqƒ”ÂòÞ\P 'Þ¨"‚+\B”,ùâ~ñ‹_”gEÍ:†K¨mÙÑ#GAnòóûžÝçJd™¤•ØI¥÷RTé%«ÛAËÇplJ·tvqsêßB³•Y 3ØÝŸ1jþ<gïÑnÂNâ*¼8jÈ|#$KoyFZVü-m" œI‰Ùºt׃Ï0ÏúõÔÕïhý$/èmǨϪ*‘ïteºeíÏ/·lâ\Ûiä"2 ªù³V½}¦bá·�Çɶ]ÃD–C¸ÃÇÂ/>ÝQGûr’3Lvu’fºœøkŽŸ2DbÚÚoÂJÇ’ˆ†z%àÇñ>]„$º&¤¤„Mô |VY« ÜTüÒ§LPM ±—›ñƒcª*¦GÝ@7`º“×)Îîûõ>MôºôÄæáÍÁ÷I—›åõ.Ð fºAÒ¾¡‰žn1Ý PS£Z cS8A½™¹ÙL%}ér¢.ÚÄrëh2­¡ÑÕ³¤=fg»8QÃÄ(¦{hÒ;én±B¨I“c6ÐnëÍG[`°zrjdÚ _¬€¢aÝÄ[—nÝdèe>sb²âвð¶PY¾ÈB¯Æ²Úû{¾¨¹0È„¶58¢þä¥_rS›;wíôºØ\Î(;àùóç-ÂV&w­”­5QÒöÐÁCäØ`!1ýÔÊSyâéÓ§“£IY"í¤3ðÓO= àöm·ŒŒÐ×e÷haS$낸]Ú•®—oõþÒk€à D“ý+Ø3ñ+œƒŒugàÐŒ,9:„IÆ"$…Y­ÑöûÉ·•5)ƒÏ8P6øŒD£ ‰µiñ‹y¬z_çü)ò|Bç°±nêôë:s™j’6î?r7Àí«R͸’%¥èM6”Ö¡ü¤v"¨ þ[+·7aÕÚ1¦Äœ¤ª Aœla¦†FMêGÍ`@ô,¹¨kO]rÃic½^ú)üíákø av[ÁL–×;ùÆV0³ÓÜòŒ:?sZ”0u*ÿ2rÝÙÔàŸÛú]eôÓ×6Mz™õ3%N]µ’)ÅS£ÈÔÆ=4ɯ†kò@} 覰A3¨–Ѳõ©{4O0A¿"u¶ºŽ¥p] P(•êI>ŽžvðˆF÷c«Æ=–Žw%š.Ïs"ñ˜”#•x?n;,¹YÉÊ=r”~Ä ôYsЧP ëÅΗ^|‰QW÷òv¼˜¼Ç°,–=þü;ï|æég’£É;廊×åÃeüýôSOŸ?ž¾å=·ßu–eÔj”îΕìî}€«-®.óOfy%ÞÄN Ó=.ñFf‡di*ë6È/r�gq­‘Iy…— µš<‹O7zöZ)«³™T›$<]œ@>Z‚ÄqÉ%ªÃbQ—IÛÎD¨UKçY˜ìL“8)zºª×Ç„h·)«/&»¦ÉÎN£ÇB\ˆNX²ax&”´=µ³é+<®ƒ “™v3'•Ðæàå×ð•n^Gv€qL“SÎfH»h·%^å·)&'j˜Ðö¨ƒ›ñúTþeä!‚AÚÍÃV0Ã;ŒfF1=…/³_RÍ,Pe0MnÂôNAdôœ£ˆ®ã“ª<FˆªtòÅE¯PYón#ôìD†:ÂŽc}éÍxýuÜÌ—&6Fi×ÜNá›úÒóÐjØ`uu±Ç —Ô„}ê¯w.©@úÓŸBô-¡/æUSqçÎ;©{ý?gZÎzåöm·+SžåÅ+—]” qƒlÿ&OÏ{ª¬ŠZ¶lÙR˜»ZHà­·ðþãX»ví¾Äp ¬žÉaÞÆØI¡çÎ];½Ýi¬ñµÍ_“§íb§w¢æ„XKì]v#è ¼€]FÕÂ1­EÉŸ´U•a9²–OŠq䶹ſò8”Ô¢¸Ÿëš*´ÍH\ÚÖì;&|ï‚bUÕî¹Û.¦ƒ¥N ^.ˆQA* ÖW1Fõ=7Xîê"Ý<+ÉÕ0ÑTzZfGD·È Žì;"Ì–=ãʯG z@’fµ…J.¶‚™n^§ü¢ì<ð¾’a’²¿µ`ÐQÓ:lºŒvóÀ¦àûSØ m¢nqnm-ŽM5H;…/Rvu^¹›Ò¹Îużu1YCÓê›­M Øf'/:On[NåêDò€.ú@»†¦.³!,„æW¹Ý7®ôèäéÜÄ;Ûf&ù©šS8¼Sj3êü¨Z/Gº€hfβŠËs¶ÿä½ÿsûŸ£/Ü”$¡æÂØZ2å¡DÝlíª¯Ý–Íùóç%éG?­×ëô…%H&ýØ+ÇvîÚÉó_¯×) Üsמ}‰²ý£nÛnÒ¸5¾µ ;©·åxYŸô5açE\¼šƒuëÑ•ß~ò“ŸtCLë–qep…4ÌδD\c9¤%MĬìfuü*…6ª¸Å€4"˜"X78ŽÄ¹¥æGXØÆªEÍjƒ¢Eo’^0Ç䈊ÕШQOLLåÍA]Û³¡‰±ž%9aZUçDU}(ª<¹¯Q¸‘N³)ÁÑfüà‡ø’ö f–Íb—“‡›ƒ—ŒéiP&„U¤Ø©â-bGU%Ldy½ÌèfŸ#Sy`<8ÞGc #›ñƒ×0Èò:ÕÞ@Wµ”g�lÂô6}` jæuãqm¡Çâ2…yB×Ã.Eê¡êa¢ôÐÈŒ&k¡ôóÑTnæ(X {ÔTXÙ’Z“Þ�šº’'¿Þ(è]Ž"Htïw³ï¦zØRG ~ n=A‹E¥V4F/r…Ò‹Üê¨Ì lß±ÀáC‡­M�Õ^h£2e¹BuŽSR®ÓáåÇ„šnv–¾ÞqÇîtFÓ¾ù–ÍX­—±“Mq-Ȥ9tA¥V«•Ñ ™VŽ|‰bk.oeuÏðu½òüV‚¨‰Ê6Ú.pºd‘å—˜ÙÁÔaD!7®)|ä|D`j›Ü MœŸz?.tpÎJ‹cŽÂîÎ8%a“HûÓFgi}&Â5I0ØlÞ­ýi™eÕh—ê¶S'¬Âá->Ë ý¡ä-@µ‰“_ÁkÇp ªµ$÷Þ"I‘‚º×ðsO±ÃmJŽå[tLÌVsèb„K,Ô9«Tb›_khPà«W´0‹`¦‹¤ÙAüjE‚yØ N hoƲcúŽ¿Ž›¡â<ýA ;-R¡¾Qžv5LˆЈ¬ûD€ ­YíkŒœ¤Â:`VÄÜe³¿?8†Kš}q*æ7dTÿÚ/JHUŠ¡k´_MôÐ�µ dÛm©`ϯ°´²DVƒIkµºœâ ^§>¼�š±V«Up×^ótyL}/¸lqÁÚ4‚(y¶^¡VE{îÚsñâE Óiê5%vÎ9ø|¼pÀŠ’¥”|/U•Ö»òøKÔ5¥bP]Óœ Šg[kyd‡%òZۗǶØylBeŒ›A$Äúe9Þ¥ÿLD—^t" Üë…qh]™€çìN`™¾ % m ýT"ØÂ¾£–é^Œãø4&zFGÉú8Žë§1è-€°ó˜ög‡PiR•EMiA U7áûS9¨¥¼0ó @ÂW%#ʹÙå@X¤]b¿Ž“¨ ‰ÂFuØÔÖDkŸÞV TsÐÆz˜8Æ�‰8£¸63¨¨k½Žf’õ´·Y«WÒ¸Ž°íß8ŽwЯ¡Ñ×kÁ@§f#Í^ô…˜�Fƒïwi!.5;SÒâcʬ2ébt¾ÿ:ú™˜óM˜žÒîHt™ÓZL¤ï¦Ìør"*"x#ÙÁÏŒ'âäÄ«|™“že„ ãœ;wnåÊ•K±*ŒŒP¦påÊ•VÂIox½ZxPÄ9ç8zäè-[n’ÀÍz,¬]0‹¸råJF/)<&7†»vRT]Ž·o»=ƒ½W°Ú¢É݆ÄKúZ†e¯þé« ØDÉd*íqͰÎk<·ßߘZy�öÞ³—¿¦Œ¦„R/àÅ9ï²xZ˺Ýóçe91 ]‰ô±3™%[Y ³0à [¥;ÌZÂÝÐì–:@ÑäËÊz†¢ŠÜ­¶ •êA‘HÒÕ<á¶ÎwŽ!G+˜A®ÂSýN·ošôç#m—‹Ý€6˜e°OɲG7Ÿjè~Uƒ6vt1eMvEWeøy¬µ¯ ù¤ ©†ÁTþeBêSz`©Nï©Öfd‰° Ó_ÂÕ «Ûí.Fzh~¯‘ó©aÙ=Šr–ÚÔ7ÖÒŒÇõOg¸›fº:…Ã}³V Ü‚8l•üv£d¿ #Kʦ5 h–”~8é˜Z{~‡$â úŸäHúZK<êh q¬'Ù0€Œjƒ Ý<5§pJäÔc½ùHô©N4ÑC³H˜ödœÈ²[˜OþüÆ0ª9,ië… dqúªU«¸{"3gÎÈÆO¤e½dŽ?üðÃ? Ôò‰_¬FŸÛÿܶíÛØ¯gÔ¼íöÛ^yù•W^~eÈ@vqGõ¶cÎ ±„N¤A%7€»÷ÞÍ2W˜ŽH,j%@e'n^Fo–¾ +W®$Ë xò½ú§¯¾ú§¯Ê0š\±s™¹aÊ[?·ÿ¹Õæ ÔÜ{ÏÞ½÷ì%Ç 2 OËf²•æÛ)/_ºt‰f¬B¼Ü—Îäx1ÕÒ•º‰mIJ²˜± Š^unâ³}c´Ð#²N¶"ñäS… ̨ÔlÌXQf_ø*éÌn>Š í’ÔV'Þ̈35éߘZ±Ô¨[œw(³Z‡*u+uù`vª’l¢×µ=%’<$ô)eF§åÛÚ©²HU˽ʫ0¨©òpÜ×S:ʤÕ|<8> t¨cø×„7ãõ)ÍPÊŒ£×Q17ˆLîc¬ ²¼Þ RÚ‚t1’¡¯âQ%b£WUI¢tIÁ@x©§zŠNRV{Òr \Ðã­`†ôÆú‘Ð…•º—²´ fºE6•.I§`ú �Íqï`D?{“ã8®p]ж·,Ïna¬ƒQ¿æ£P…=£2 …’zDzR]”RÆ‹.8ø9I+âÌóüöm·çÈe¬à­M<zäèÖ[·^Â%¥Zao$¾.ûÏ+²äºe2oÈû%@G+üuÝAõ'nÂø«_ûê«úêW¿öU�Ù'2:&*)Œ¬™ÎÕ×­žó´ùžZ*Ütˆð{¿qïG(nݯ¿@¡'¹8¡Rª³0Ôܶ}V/Ð)~yI¸Y|ÙŒb…Јçj…9'L[v8a|öè.ÎY’¢JZ)±V‰oY«izs'>1mTÄ:AbÆ‚â&Ê›&Uu™d'pL©Ï!: hI'‘¨3”–㬭vuñþŒp[-ª8»¦»E¶…’SÑ€ : ›š1 Xa¤1H©qæëhlÀúÿ ?~ QÞHw…I)¦%Ôla¶‡ÙÏRÓ’ñàx'ߘŠÙna–*&DZ¾Ã¥ÍXöš$Le»€&nÆëdh�ŸYªi ŠA3 Â]Vyx“ç»ÔõÔ0`‚ fèLÈ~ªÃ¾±.FÅá?à ‚HIy•$jt/žz_£7Oc”êxˆÚ)Pí«t£Ð E ÒD7éL�4Ðï©ÂfqÙþ‰7U©È…÷+hCZ•ˆbb©ª™¼ªÆð1Íî=»÷¿¸ë­[ÙEÈkUC/Ò¢lQ|,k"®RBuuË-i¨Ë/>22ÁðÚ™z,;wít+a,(µÆ­ñ­/&/ÎéÜKƒ\èè¾"¯üXêƒð°mÛ¾í¹ÃÏmÛ¾¸PR�h9sÆåZ·mßöÔ᧘¼eøôî¨8ú—û°jJà2·SÞC'&ì¥LLÖ0¤+ežB‘­„/)­ÏaúÅ%àm›W7 Ý<Ë2Š˜Î?Ú ö ø÷îñEÏ ÆÎDµÇ¬Ñ¡3bã@]Ï¥aRtrŽudœŠÍurˆ¥ù¬aB‹tH  ›!ªÂœTXŒiEO,8ÛIÕªïc 3¯ãæ “ÓØp [tF³Ïê˜&zºBc’ƒ?(ïøçãê=ú§yL^µ=4©&„lßk˜x _ÉP'ÌÓál”¡?… ;1•¡¿Ó54Th›‡-ÌPm ߣ “›ñƒn>Š<Dj¼ÝŨ8 å [hši ©wAÚÍGÉ/·…Ùûñ›zòª¥ßzŸfjº‰ÅDŒO)Ù4«úÎNêO'oµ³!»|ºÅd!67…"Iwè›,©¿ºB! .UµF fY†³X~´@ƒš´bR—éÛn¿Qóè‘£Ò¹æ2]ß<–/_~çÎ;ïÜy'¹1 ƒL v `$i#@|8½“=`™'—V®ñm1¿^†—Iï[Ì-tiŠÌ’ò¿—^|iDjKÂ*ú–H~ãX9N™ì¤—yG¤ÃƒõbY¸IyÙôz3ö5¯¶‚<õ6ZèÍÞÑ…Ù¬ƒ‚‘ø6*¯T‰ôZ9Qi™ížsh¢oÛéô™ˆ·¥"™…Äg‡Ä±©øhµÐ³Ș.7ÄBÆs„JUö5Lèy‹tqÅL¦}Õéªua[>2"'#õq¬'œ&ÕhÙÇq2Äia¶ø $ %‘Í&# $xÐ1œ¾ð<&¤l¢·ÓºðÿDÍ&Ʊ¾ƒº¬3n Ï!tÉ0yŽª\l0%�Åm›0ÝQÈÔ¨¶&”eRÒŽáX¾¥ÌŒÇi—Ð f¨^¥ƒ“:G¨6Izkb¨oDλM÷KôýŽ(X$ÿ<Þh F†Iª4åƒ ?}Híq c:k pÖÑŽ¡‰ÝDé4DPú¬b3[ñk0h}Ÿ—.Æ2g÷®Ô¼¨¹ö4Öû­*O‚"ÂÎÅEÍ™`\#†{ óCóå—^¶^Y±bõ7•)êø¶xß³ûΜ9sáÂÒ ËŸ¨³†ˆ¾]æŒwìØqÇŽ#/áWöܵ‡à„Rüú?Ïkr$& ŸÛæQÃûN£>û̳ôÊbµ€Eyw¯ƒ¹#„)u¡kѧãÑÄJjyD_L÷'7É’KÈšˆH4}QbAKH0íé‹q]7 º²²³­P¶€—m'PkÒÚMÿ² ½¾ÇºýHÒʼnd²£éVÒ˜°P?äp˃ÕO£…™†Îöi(¥÷DŸéüˆÆbÒ°`è.!„¦€’øH2J/nÆ6`z#Ž“] ³µ`ÐÉ7’ð‡¾ Ó-Œ½…ߨ„馈P3Ô ¢(î$ìi¢§TÄÁ@ _3ÔÉi¡¾ît6`Sð} ÒíPF´[a›¥· mŽ¡uó0~oÂ:ò¤àh7ÐÏPÇzÞdhn�-ÌÒñ3Ý@m<8®ý+vöÐÔ**zÒ)|™~ª³ËOH 3¢jŒc=÷­ûà ½.}*1R Õñ#1á™”Øx”%óµxݲuË0o‹o‹“£ Yÿ\ÎéQñ¨|åÙgž½ëëwYÝQvíÞ•›ÃÝfeY¶jÕªU«V]ºt‰¢çz½N1¥ÛGEjÖî¹÷ža|÷Å'bIx…ꌲÀ™ª´ÜÞát aj"¬IÌ×S' á0iZÅlPbà§gâ(dÙ%´Ý6Á!´{u`¦ÊkýJŲ(¿AÌV5\Œo–뀉bQáÜÖ'– è±Üvq©ÎŠA;52Lv�à$—B5¿ìwqj¦ûhLëÖ•0ÝA“d5\UÒ%3×]n‚º­}t 3½`@. ¬ï+ç÷~ c?F¿Æ#øt ÈÐ¥y 8í:‚<œÒ » ÓDÒ*PÌAo¦"]ßB"aê4"w)mA:H[hŒbz£]Œvs �YEÌz]œhéÜ¡žj’>ph}͸ª´q }ôZ˜éh ˆ®J:’¥ß?H-Œuƒ´ƒv ZÓ娉^7�[.…gdš¡?Žõ$5Ltµ.šK\(€ÖÙtc,[¶Ìkhçµ ¨ÈqNpCJð/sÌ«iè“O<IE)|ÕÞÚ|/ä,b¬IE5Õ GùÜV¯^MÉN>gJÎé’¯ÈÏ•6}êM%nÙºåå—^¦Þ&Ã`'—¥²û}[¸=»¿^ðD>}ú•—_¡ê ùVì¸ùK÷a¸çÞ{HWÅ©«.k×î]9 ´¦ÊªË¤ÚyÝ.¤˜ËûbNª61s„2ìs=𬾉©+S8 ‡ÈP†¾Â•X«[-ðKœ¼fìTÄ>¼·ÃV2ìÖœX%Ì‚4Ëë:Šg‰øD&<“¢Å¦DÁ™]2 «Ñ”{GÇÔ„Rp}©ŽGÉá=Ô˜šj\$g¤(AGúRÂÑNQ|ÖD¯…Y‚FQh«dÀšvÎò:±¾Mô¨=5…VÝ|”Lá»ÙŒôÐìà$m(H¥^tü†Ð¶dyU1LÑ®’j{B3nŸIµ®Qe¬ôâ8Ží.NLaCMíœjÑò(…ÂZÅ…+ë7`šok ³dc$a!Qâ;1¥¦%'+ùIr¥ M¿æœ¿d%3X?¥µiñ&¬BY $vŠmÚš÷«¥[ìR[ª§½þúëo¸á†n¸aÁ %àcʎ↋/I(+O.]ºôþûï¿ÿþûô5ÿÊŸrä…#´P>txÛ¿ÅMd®Y³ÆÍÕ 3H®uùƒ)PN"røË1ñöÛÉE#¹Zù°ˆîϸté›Â3~‚.ø´5+&ÖÛHà©'ŸÚ{ÏÞ µ1À«ô°èÙG¿û(œêÌ…q¿îàDì0À 3P Ë‘51eD‰Lêœm,HÝT0«±oÝ-á#ŠlQs’”hwýÖeÔZ@ÑAmñrSD�� �IDAT]ÖÙvÂÙH*—,®ìŽQS3†¦•=¢'"Z 5ÁHñå-ÍMô˜å 'ä k}R¬è¼icPi,§+Yc Åè×0Ðý¹&øléÿMX§6Aª7*8#%­Ò¶è2Ä×ðµ³ÉUEfé ´`¸UsËMAÒňng=B°Jͨ©¿XÍ “?Ä—øÒjЧOcÃNœ%œÎ´\¶…YÑ×:Ò²UÞ·µ;8©KJÀJié.Œc} c°ª “rÏOMÊ=ÖùlÊ46aòõ-^§þšƒ×q3± zªÛ54„™_¬ZÍw-æÏ*7g6B·%ê~<"Æ•c™Q»xñ"IQîÜyç`0¸sç/½øÿôwÞyçwƒáq½^§'ôµ—|caM0†Ü f¾YñSN–å;åé_E ùöm·³i߽߸—ÿ'dÝ÷ì>†Ø‘‘IYK~Û"`>Ћš~/˜ý~øÛ{_'Ô¤ÿY‚ôÂá5Ë4GK”ãô¦#>&º³R\"ê‘H3+›ê¡ØÉ#òÞÜ4MXJnìós÷v ‹‹Å‹r“ˆ‰ ‹Tˆœhƒt:ÜŒ¨9s ƒfDàŠ0T¼j¦Q b¡­xS’¨¢FLPÝ!ÁA)ûã·0–aRÂ�Ý:=ê&—¾èb„’š*k˜‡ìœ‡<¦þÏkñæ“B'ËëÈCÖ�‹ê#P0ªBU/ÜŒ—‰öÜ„é “¯ãæ}Ò©æ¡ÒÜ)oÆZíÁ“ uÒßöTňŽÚÙÃ($_Ák‰? ‚KNR’8–\#jhÐÍ%¬"F”.ª…™féz©¸“BØfZë Ù@_õùÊc:¸–ðpEoº/3›M'6ƒÑn>ª7 Ÿ ©è¦@°¸f#„X;8²›UܘI¢ãsŸûܺuëÖ­[Gûn ]þk4^zñ¥­·n•’n[]6øÍÃ(S¬°˜ëÜË$N„–LÉ rP!):zä( 0ÎÑ×nìEºë©•¦<Ž~ã¾o@èb¬8˜ZÄPÎ’ðÒÊb Ê0šÀÉBJpò{†/}qcM 7½sNcÿ¾ýûáë®»îºë®ûüç?ÿùÏþºë®³Z+Ð$…»¾~×]_¿‹²M„¼±CJó<eof…‰/fµR¤±ià²ÒLÀÈPêÂÇ" ÔÉHˆêL~›ËîBøÈK –l\\´á”ÞJ¿“¨ Ýly<8Þ)ÚuIHkCUÊHlÀtyô{¸°/ꪒ~´q²P=ŘÆ<ÞÇl'ºˆ »=bÝ[Ch£œL8Á²ô†< Žé5Ñk`ºþm ò͘*NÕ~cªef®D¡Ç°…fr£-�èð´0F)Ré8zÿ öUƹ}ÕÝMjg­ï´ßz0Aš Ö?DˆÐZÐPt+Òq¬§Þ,œl¡Õwì9óu4CÀ…¿ãÁñN�'€˜Úw·0» Ó¯ãæšÞœÝŒ×§ÄNÓÒCó5|egpú@Î%Ë.Ú´ÉŽ÷1ÖÍë"˜n'º�”p7ì"Õ¦ãÄ4Lm²G¨€ÏùæçÜlœ×ˆ•—ø²Òu/d0AÊš>úhQú¨T¬n^±aÌ�ƒ‘‘ú÷žÝÞpÙ=þ’6e“Kh:+ÚìÞ³›'íð¡ÃŒ»÷ìÆ2O˜Ì :L¸]¹víZâÏœ9ÃmתÇíÛn?ô¡wìÀˆ­�ª`¡üæƒ.\xâàœÑäŸRé‹°²çÁÍe^f©ÉýÜÿèþGå+d>Eu/àé^_¦]b5pZE¡¹XÎ>²iIj–xjçÕÂNJŠ\o©¸ ÝT¥‰v` ¨ÔÔèBR™v•Nô‰V±jü ®b½¶&@¤Ê4¼T(”Ü\¤~ìä)lR½PTP¢”Aù+ª…äD“º@þ-ú@sÖMدVíŽj›Õ×­}eÞ†Ùúu|lºÌRØÚÅH”}|" V_=ÊG60ÝfzhÞ†£°©é “›°îuLЧŒbò[ÒM˜žÊ¿Œ`B2«ì¢Gæ«ú´joò%üL…¨îb¦ô‚I{:8Y+ÚUNlÄñš´Q؉¿<ŠÛÈd §èÍ”º¼I–µ†ÆLw�ÒuЬ)o؈|Õ{hÖ€®rÁMé¬Zª+ËÐc"mÅ0ÒņZÑp S8Õ*l€b`¢>yóÀ&›1Ñ¢£w'¢g!nº¯Oé!ËjàQvÜ•Íh›˜þgëÏòw÷wüãËUxaf™_èe"´µVJQ ÿH 7øE¢7I׺㎨yR˜6\Ëqþüy7 %E%EfüµüÑð¤ëœ*˜5kÖÌÎÎ/$‘é:÷d†<½;wÞ¹zõêÇ{œ±ÀCß|H~ §‘H–eœä9'Œ”]nÜJ0/ÉçóçÏÓ/._¾« ¯ËðÁ{@âN &«ý%¼ƒ§›nº À©S§HD»vïZ½z5VŸÎÆ~óA¬Âœç¶XÀ ±n;§A«§…Ñ2)u27‰¨ìtÓ9©(kƒÑ¨Ëø]÷ý©‡¾¤£Z›tv3¢,W ÔWD"·7I$W©/*)ÞÀ@K¥)yŒ€M”$mK!™!¤Ýb¡Œ€ö”î²Ó"ÐidÚÍŽn §€±n>*ì“”7‘ä4TÃD7¯o ¾?…S}4Tð‡¦†* |}£ãèO¡YZ˜%ÔdEèNÕt¼¨;{ƒÅSMôzÁ`JG“Shák�õ5 Ãä´RÖ¨Ôf,;†zÉNœýKôf0ªšQ°ª…^WãE„O›ñÝà%U × ¡p_´EÑ/,ì öEc §€°‹d3–uñ¯©_ q ÿ?wïÛÖy®ùþX'fdË‘ët%Ù‡�÷¨[ÏìžñAÁ�žÌèæ€ðÌ`(;š´tâ8nÒÖmš¦ÍΟf·qš&NâÖL<ÊD€æb ÞiBØ7#Pa¸;p‹=›Cïêì…ò¸mÒ•:•M[¥c‡çâYßÇ‹”,ÿIš9‚@’)r-ri=ßó¾Ïû<uòls­ Lè÷¤GµN!˼ö%ÚÙ˜mSX×ÌOØýiôœøsfK×0/Q¶~LºòÓÔê&K\blSü¨}|èZÇ>ÉÕ·TÁN—wî}p¯¤’HÝ%Ä}ùõ2÷=¼ïÈëG^þñËûÞgq×;Æ~‚Ã|Fv�}‹Ìk”‘×@ÍÈk]µµüø·ÿÁßüà…C/lß¾}ö?ÍNü» ¥œ á¾þ¯ÿèÅ}ý_¿p)¼›eO±„Ür‹\€ýìïU©×¸ÿ‘ý+Ý¥W n¥­úuý“Þö?üPÙûï¿üá¸ê!]“éñMÎ"6ºÇ.éŽçl8AÁN2I;Z…n¼,v+ŠÝÕÚÕ¼\$n8g‘áË‚I’ŠÄ¶tåXx¨ŠöÂrh˜Ð™pÂC:ó3¡/ÝJ$g#4êX…ÇoF,ÊN׳젦J²:£D•HšaA«’Ìã´êLšjg9ËH……”õŸkk„f³ø&ÌdFæs*Û±Á#PÓ´E0ÊâÖ¾§©yŒ@µ+ÒNdcó•vÇúÎ'òÂúyªóP ¨Õ™É2R É1uYTÞ%2w†í€@:>“ªA(ú]iÌ1ž¡àù$—NvNAïÕiÌ“ fÅŠq&Ï0§,Ëü0KÆ\×RO²Œ”HÒQç¦86»b†|Šv6Û<x¥ÎLìÌs<Üaÿ}óÑOºNô2¹µVA-L¬J!Ί¹6&¡ì…ÑõÇ?þÑÕÍËPÆ~kwý‘~›{W²£xÖ®÷þå”O~­Q-´æ}Ç4¿ü•/k–ãÈëÑ<²u­\Gé[¸k_±Ï mìµoÝêh_ް±¾yáÐ ß<5Îþ§Ù3œéí}Þøúío»ÚÞ¢ïÒÔG_=ŽþéúÖwžüÎjï’õ6lØàÒb{O~÷IûCû—™ÚRûV…ÈVé:bÅzW¹g,Ä•ÿ$:Ónµ¶ã qÐ+ÒàŒ²RSÅêõŽ/vÛ¸´8GhËNvÉì�Ú½©Ÿ3t‚ s]•çX. ½ …*añ¶Õ±‰/vÆZpã&–k@”(£¢ k´|Ng™¯âµœ¸Pû»@=t4 Bò×.hj¢bŽ¿Ä¢k’Ï´Ès¼D&Àg®ÄÙ8“•p6t&ËÈ,™3Y¨p:Ř®SÔÒÔæðj¤¥ÝÍBÅT#•nV!™g®ÄÁR€/╇i N|qßÍ)ŽM“ŒÃ'§Ùg²Ä€ ’âLú`Š®ž)lžmAÃÎxl«p:NR.¸U2q2rZ¯Æ2Ú:Ø,&%+qV ‰JøA ¦h޲£ij2^PÝ[Lqºý@66ï¸ÚÍJ¯Ôù¼RaNjY Z8kTT®o>òy6^KECvºý„m,v˜¬¢ækïáÿú_ÿ+»ï¾>Xzýµ×¯:¼¡›‹Ë,EëÛ+Õ#­„Dw1—7„ÏG‹–Åãqûü›6mºxñbd¾~íåbgHý�ìÈëGôÃ}ﻎ²ª»úN ª(j3·×Àl{×Õö½�ÜqÇÇþñd2yîÜ96…œrëÖ­øÃzÖýIßž÷ÆUtÕ È53{[†«a¤«QZ¿öØrô_ÿú×À|ÀÕb´UHÿ6yk�g¤…éjèv³s _6ˆ%úõM{á3×éöZ(´¶c!1º£ªÍáµÍ }—©^ÁXÖ­´Ž#<¯[íD·Ñn‘XgÂÊAT§šÄô‹EGÂS®wFTl…ä;sR!°üÒtC“q’Ú7˜’æLœÉ¤7! M§¨÷€24tœªµiñ!ŸÉ<s¥0™y—&ýuz^ª!OZ¨ƒÏd‹“ü¼à¥hÖCϪ$óÌÑé2žNáM±aš]Pµ…Ü*ùÙV8í1’¢¹›’º˜­ðâ±á*gëí‚¥ŒµX0ˆ{!ËŒ�‘WÕZ%# hv˜´¢2G9éwê¢8ž™^M:+B:ØN£Âé8™98£}.E³ÞsiR±¦å¬fÜ%i…?&1TR¯N•^V†‘J¨L®™a¤ §ÓŸûX)Ýe.G*„런¼ýöÛÝøÆH-3ØÐ§÷s´XØ[(¾Qì‹Ò¹øê6D‹x½‰˜‚Àzð§? ƒ©U&µ†�—¹,,q) {Ž·ÜrËú}Ø×¹ÖàµG^?bÏú¦èŸ———wß}WïÛMoW»Å‰¾e�—p÷î®ôs±žmË–-nçÕBõÚRð}3;–~øB„J>÷ìsú"ҳד»Ÿø´6W+ž¯¦ªü '"˜g‚yéq*ös(öû×\TqÓ§Ïšsxd±3Kg»‰DHmq•s±9ÆN}U•´†q‘ çPÊs§ÖÚŠÍtõ2CáeC.õNV”MdlØìb3ä>iO*ŽW1BªÕN;âïôÃls4g m ucmŸÂ¯ëÖÜN¤b5¿BrŠ“uŠ5Ò°Ðb¦Æ$¦i(AL¿å1R%YgðI=ÇÝ¡æ6F–‘*™q¶ÍG Õ«,{2Tk¤ &‰2êz˜cœððròÒIUI¶|öZ”²$Ï#„{ vÂD¸�¹ÀHE‹eÌ›¡Z%LíµiHs\åeñÈivÁ ¡¡ ¾a¥e÷’޳âã3§~ª>ëd¢ÅÐc¨mµc¡E~Ýä†ÈÔIÕô>˜à°¢ÝE‰y§©ÕÛTc]ª¨w‡åI×m-¢úþÓ§OGîúBØ·Ýv[¯ÖcÆ 7Ý4.â¶jQóégž~ê{Oibá[«÷uuœwÝu×{ï½wS:¯š¬Ð×÷OÝϵœhoç/Â#û²ð–÷­F”8¯~õþ©û/}téº?ˆ—üòjÕWuûTx_mNÿú:͘ð²7Šo¬Ñ{þ¸—½üã—e¹÷Â_°x H4ûÒË/aä-»«¼xèÅoüÆMgœÂ•N²BYt´¬½…܆½1ÙA‘n ¡È@gq¦[t 6ÑÒíNC+ú[mˆ!Ûñ,~¥ÓÍuhe,2šsÏI ±¹Å@wšJ'Âô¯eS9ÃIÊ“gbÛœ…HWñÏ’›ê.oQ�5з²gÙv>v<À«„7ÜA(×Ûb Ï'™ÂWWÏ ±„%S^S$Ì çJ½ç¸%g[ /CµÄY˜ ó<¡‹xÒ'}&ë0“gÛ˦]ZHQKSc\¢ñT Zñð·|É| ÿò+o›q<B‡z<æ >P!™¥jJ»M`Šc‹¤>Ö3l>—¢Yaм ž'Ùb&ºÍ{Ì•ØS£¦âD˜×NçcÇKd’øõXQñg5Ò2Zjdcó¡C!e!7`”À9c—8hSáôk‹ :­±‹Ò4‘~|&Îù˺ K·{ãp™–½ÅôNelÙ²%b4Ú÷¦vÇwØoŸúÞS«‘N;з_Õia®oRÀ‚¥èæýS÷_韸‰3 8² ^Ò)Ô\¥õÕ(µZ-UU•ÕüF_Â$Þi?Óë¶¡_5×Ó{v¯™HC‘ø9òú·änjÝùQ»$Ömrml^ê¡?üP €ÕšÊ« ÖPÕºóšE'J°oqÕ•³– , ô@`ÙAåÉVU-Î?™±‹±Ž¤Âd³t«~b9#êITbô x¡{ÝÝ4º’4bædÛî\Ûú-ØÁÓÿÃ+•TÜ ™bØ:­„*éìNÂyúì­sŽq'";aIO«= q<¶Rï`èN « éwì_d‹“T¿MåÊ I̪2,[s–Œã¥™3RÛPJ3Áì"£†ùM–4%’¢™æx)*I1&`ßRSÐôüfZÐ)}·~møùŽéD”Ù)ql5¬<ŽO±´Äp…qV5%âr‹\–‘�óijsŒ§ð¡)> ù §ëäâddý#ï‚:3*ò—cÑrãáé)ÆêPfC¥M=6Hè¯ØXÛa[¯6»„2,8©Ú*7 X gilš¬+y‹2ÎÕøæFÖô[Ó€ÆÒÏ;wfèL¤ûµ¯MØùýç¾ÿðþ‡×ƒ[–Ÿ¹DmeeÅÆ§üô'?ýéO~úàC~´ñ£›8c°že車Ì/åË7n´=Λ¥ÍéãžRúÚI“«=Òn›ÜýÓÆ‡††ôöª¤üæoº‘dûÞ×î¶N¶›*·ŒyåÊ•¾äëè8FPsßÃûlÁvµHðC/ºÖ|ÍÞ¡¬kºÖ˜ãŒ¾bw:tDs[ì)ÌZ·b¿0Î.«wS-v›¹[:ëâkb•ªr_€´´A')z@Ž9H‹e†=*¿C:¡ën^pÎÈÆ¢åìA%¬Ñu9<¸¡Ó˜ñ¾ŠA;1$;¯ pŒ€3a建¿K"ú™Y{´vz²ê€Çé-LäHS+u΂ Uªhå³ú¡Ä¨5ÒãÌ• Ž'î5Í•)§Ù•ñµ<α xÌR䜇/Y,Ì”ÈeñýI¢qs:÷ØŠi[š@ÁgEs,†¶ŽíæåST+ä 1Ns†N¼z cÊßB»Ú•*Œ3×bF]ÛÝ\$T UiQt²^½Ý:JѬ’‰C‰³´â±íBZä¦Û § 2Ó K0b(ÍÆhä�Óø\°¼©êØ.»Ù�•».¼OñÚ´iÓ]wݤÓiàÎ;ïÞ{ï=ÝÚÖV0YË7·ZkÍÇ×Y§ ¬Åã¾Ü«—êmٲŕ5E¬ÃûŽ£¸·WÙôØæ¥½ÑÿèõÝ\ìì]ï½÷žËªulçÏŸ¿Y-O·}Mæ^yêæÍ›])¸ý€z]8"vY/…â ¨V%üð+‡|õ€àÿ–[n¹ªGü¬õ÷8# Ú€r6œUDZ(:¥Z‹¯P»‰±$7ºÁOãäá/ö!vöµ\øtÁµ§´³î?ÆWOT ”ÐW¯ËÉV•M¤ÆŠu›“E‘c]„»!0EHê¡B2>ÖaÏ*á&œÏÜvÃS…ÓÊf¬P¦½³åî0bÅ)6,† Q6%å`õqçÕ“Œyør^÷ÁãVR”çx eqš+q³ÈQ'Q§˜e$À¯‘NSó™\¢Ç+±'Ïñcs$“øóªZç©ÖHxiju³Œìä­ãì9È¡ç¸_%~³ŒT$—UÅ2ÉXÝ3Ut%œ¤Ü]gA$¸e´µ-ãg€'ÜÃ<ä~àCœÉøyj%S|¶ÁÚñØJÅ&Øè1çfPèÄœ™ŒkÅËÔ Y/‘±Â^èp´fËàÔ´ª:LÙ$f¿h'Žè™}¥÷vÓw_¬û”½=õåsÚ›Ÿ?þ­é·z‹Š½J™óçÏ è^öÊ˯¬'\zí%Ò)°jºØyU_½Oò™ŽáMgoÁ¾ç}ÑÅ­Í®ýé¸?´ˆø©-0¬VÆ´×ç ¶Õe% ¤¾c¯BM›ô¢«÷±¯=Æm«öª-N«!Á³]ð¶g±štZ[Fkt×fq4±=n|m[êl8wö†cÎñd/*bÂLLÒÍhËÝIÑQ°Œ3ÙŠPÏ6@ªËö(œ'ÁÙ »«ÊÖZV!*Ô;iÒEãng:c² á¥å*“N£ §°è×3T+4B–CQ Gržm¥ð}ùP¿Jf™9á·}-‰]0-ÃGgÌ�¥@(í‡CÇem)ÆFYT-wÇS Œ-ŽÇ0œ6ÎfAË ƒÆ7 ™¿ÇY ¨ΪhB£N:Ïq™™8³ò!Æa–‰¾§ßR«2ÀËS…mfø¿Ü"g²¦»x–ÌÙ÷°J&ËHÕ ðØÝLšm¶pÇ«C _J¥™,~ÅÖ}$mÈôÇï2i¦-=ERÛÖo¸õdz gÜÛÑnæbgâ¬ÔËj,ή„ÛPÃAejjé¡Î\ÃÚ²e‹[Åê] ¾¸¦¡Æ+W®¼öêkûÙooî=ñ¹gŸ{óØ›–±Åb±z½n‹iº¹³ûÙߦ­.š8Ÿþÿæo Au‡º¦^]/›YÿÛeüÏþìÏ€­[·êÈ]í’Û¦íÛñrèÒÍ›ÛÒ{ãÞ²e‹û.Y„îÛPtQÙºM¹Ÿ£ý:òÎÂp‹š;û"–ðÒ½Á¨Ñë^±/íþwÿ÷äƒÿïï–/žûàÿÚzö±Ç6w—d¯šúfíÑ<²¶µ £GìS^¥®Û[t-:莠D\�s¶>>41À¡¡¡+cˆc‹¨eÃùÆl•É×\pKÖšå7yÀÑ)¢0lÙHmËñŽÀ CCŒÝnÑ:Åw†üä9`ÚŠª‘jŠq‚ÙY&ä™'×òð…Ú é¡Ô¼4Yü�Ïž‹䥕%ØWFŠò;3¤VÇù¶6ǸmãiuˆåEF=‚a–4�j9¢°y™¡™|˜9h¬ò”Îm]÷ÂS—L‚Lò¬V¥4Gö™ëá¤JøE~QïmšZ€'­iîæÌ{¸¿å¾EöØœØ럧N±aºý€½¢Ì§6cÔÑw»S1Q©v·g[é¦Dï^ó9ó+@ÁÕæ¨s´ÿ#kÜÑìœÜjj‚1µå"ðÙ÷†Û×Á½áZö?ÿþê¦,àüùÏœ9s&œ¯½úšeœ¶$øæoNÞ79óöŒ8èc_{Lèe»eú¢º™=ǾS%}¡7¢ÒÛ¥ò²^"œ’ÑZDܸq£°ÓÅȾ°ýæo ;›Í¦6íË8ûŠƒìqÚsìKƒzsµw£/pöýLûFºê_›Í¦¾Ðû¯Ói6›î•Ó·PÜWb¶Îñ'÷aVpÔ÷ZµØùØ×ëûnØsìË8ûîì«oܸñG?zh·¹ï¯ßÞtûgƒ3ÿOã﫟Y¥ÇYî‘ö5Tk8š ²c\`E:…Ф-—”.¦“©Ôíi€ƒ¶õ¨O±Ñ‹ µ$t[ÚZ<¶\¶‚¢e½1ƒš¦ÎªÉ2J¨€ŽCw9,å‘6íLÝ‹N'ܯÀ¢¦ <‘Â69sÏ->1Xg!ŠE•yÒ0Bʜ閅ӟ)šÄ¨´w¦hêJì©3¸“ù³Ld¨ž`·€Á')ÔÌÇŽÇñ*œ®†âÒÀ'9ÅI{ë÷Iêÿb‡:Ád˜vé—Ø#ÔÔ½[wv@Ã'Rç&ñ‡YäW%3ÍfÀÔ³/Ó\©‘R”‚I°“ù0ŒUê#öC>Š}ZŒo{…ª#”­“Î2¯£Õ`«¦Eãx‚ÛQÓÔj¤5î録˜bLo©i6‡²¬,¾§–¸P©Ó)ÆòlK1&xË2²Äp<¶ö¶QÁ×´˜IÑÔ«Tɘ >gusVa'M¾Õû ÏŽNx½åSœt­ËÞö=¼ï&:é|ÿùïÿìÿøgÿãüŸýìg¾ïû¾ÿûßÿþ÷¿ÿ}ä‘b®v°A(VjQóFò ¯{%‰D"‘J¥þâ/þâ/þâ/î¾ûî»ï¾»?ÿöã‘j­û¯nLÊ¥K—n½õÖ£?=úÈG"a™òÊêµ^BJGù$#`õŽmܸñVg}hVäªÖzìk)‚Û½~¨É®± ½ùh׺z³3qa‚—‹=½´²[tZ¡8q`˜L®Éªµ²6ºs= æa‚¨‚Ù‰'ŒìP¡Ebn.fQrDsœÄY11&åî‚0Nª­„ØWEÀ�� �IDAT8Ú.D8ékŽÙíBÏ™¿œT*²k(šb,‰¯Û¥Ípžbƒ5ÿ³n2u[ Ä™TëNY›–N™ºh!MMï§ .CU€qˆƒfÐ C½&Ö°)"ÖfÖp¼Á4»ªdäak»wij:`hžj…džã-fv2 ÆJ1V%“¦6Î\Šf†ª<Ü5Í©ôéµ Õ,#3°>æãÌ ³”6oÔ!z&íK{” fw×Ê-fŒïAöãÌM0«Àε*™Qÿ5ÿ¹Î‚NSç¢Y‘EFKd”¤&ž½ÈhHµÛiÚ ›:Òb¦JÆÆSÇ™¬38ÎBq`TTÚa4 Pa§öu\7 Ÿ¤±×È™ž«•e•óTfn­]Þ!¸Êm¥cÅ5ÝÝÖƒ½7î^³{—üP7 ÝÅ À¹sç¾õø·žúë§þ꾿ZZZzÿý÷ßÿ} A͵u(ïXw½¾¦¯}ïæ7}Ûm·ÝvÛmžYwÜqÇwÜ¡Óá¾VÀ8òúkÅ~ÕßbV$‰,’þí¢r$Ú,‚nø¥Ë¿oʤÊjïÕâ©×S•]O–Ëú—°óš,¨"o¦Fë¾çë,Õ>Ö ¢|%g¬Ðn ݆ìÝi[IÅ`?ç[WøÓè²øÑB¯W³šèv¸5óf†Ä±7S‹4?ë;ÚWEg &Ñé°v=[4%ÆÖ뺟ß2Q¬úÉ𹜠–¶ˆªÛ’fËŒð«2l›²yª%ötéÃcpЙr)§3˜™úœÍì´_¨:ÁìÃn×ÞßÍXd°~ëN™±aTlIVDÐqœË’*8ûŽqà G ,I‘Qܨà¹3ÎÊAkÑáª(ZžbƒŽÜñ)´–£=ÇŠDU[>@é;ì»X =GTæUšPŠ<&%‘Þm=­êØ%Κí£þÚ°.µNä¸k¼•sí…×ÙÀ]S©Ö­®Mkܧµ¢·üÕjµdqàŽ1D† /\¸°yófëu åÅÀÀ€ô´¶ÒõÒ^²¨i_½ÕjõºÐ¹G~éÒ¥h ‰ehnµše´¹Z×ZªM$ÀŽ;€Ïþórt;uêð«_ýÊ-]Ú §ûæGÄAî.Ä&–è¨úV,íYX"Õ·öÛ+è”17oÞ¬WqO|µ‘ÿÞ:¤ýa_·¦¾I&}ÇN"¿®ƒé=q½´í͵šg÷ ìûmܸñÅC/ZÈŒ°®ØˆÆÊžx_'Â^›*=òÕW¯§Tëf Nb׌Snmôð9[•Jtk\Mõ5V¤0á½ô ¯;Т¯]Qb‚½¶,aÝÉ_tžÓ”d­Ž)ÆBmع Ã&;Œ3×M¦‘ØqßÅJ…{鸩²ø‰¸)êΤ¨É‘ÕšÈmgø>$ñ[ t|· ¦Í¹R!™§šÅ/‘FX0Œ…Û‘8“’^?‹gr”EÍŠLqÒh8Ѩ‰nåªq<à ‡f™PQTÈnº—£«|’·€iÈP`VÒ›µ,þS<-4â¤PßÍ@æÙ&N<Ê¢èl†ê'ͼ Êê )‘QpJ6´ô«µ8ÄÁx¨º ðZÌä©f™æ3º“³]ä3yŽçñœ™0I» Ö¨3XgPÞÃäÕ ­pZ‡-øÔÛ¢µøt½6¨Y4n|uJí=q&-ƒT•5ÎJЦ-ÛÊËÂ耴¿É¥hªx`®1ûç“ëS)qèÑm·ÝÖ7)ó:–’C®ïw/\¸ 8üá~øô_?ýô_?ýø·_YYYYY‰pÁýì·†|.pKµ"šú×kb ë)œFÊzîSàï½÷Þ{ï½×h4~ûÛßþö·¿=wîܹsçVVV\ -M¡ôí¿ª þÈG"9_×·n«¾jñöcJAï¥Ë7nüìg?{ûí·ß~ûíßyò;bœ>öh¤åiùëGβ¿Û×j~û‰oÿø¥ÛÏâÆ¯Ÿë.ÕÒÍçrN5âPÇ-¨hêúõ»)]Œî›B£AsÝV Åè¯wæ"òZ:¸k2ž Q^鸸µ uÒF²B©q ¢¡n9C(†äÜ [œÉŽ{@øT óE9ÎŠÜ T ôÂ\Ážf…Ó)šPLS“o{œ•N¯]°&öié£nè>I•pU·´‡„EÚ+:°ivM±AH³Èh‹ CUõ^ùçâ`‹`œ9•vwsBþ´À v <ÇýyªŠ]b8C5kˆéÛÜ×bf7'ôŠy¶©}Xá´N9ESò"u1]ÁÃ~˜³ÅoØ.U¼+$SÆåÇ4 >IU°Õ”MQ3|ZïUYuòñÅ8“{9J¬­Ø]‘ØpÏî䲌èÚn1 ƒ¯³ÐjTÚ;+퀶)q&Ã9 ã*8éâú°YYˆ‹zÏ­nËÔ]¦ú+9ÝŠþKûz•Lí½õ3Ίõ[¶‚© î}po„ŸIœ‘`¬Æb÷?²ß²É5‰]ì´0éb§þ¯NçjO²iÓ¦M›6ÝyçwÞyç_þå_þå_þå—¾ô¥/~ñ‹_üâ?ÿùÏþóŸ×[q¾{ÝÈñ©ï=eíÂ;×Ñâ m—ºq.\XçHI_€Ô“Üzë­:ñ¾Pýé‡ÏÈ9 üÙŸý™dÌßyò;×”“jñRÿ 2¿ýÄ·Uöøá~¸qãFUûUkýãÿøÇ?þqC÷Š|RºÔû^*}«â]5Œ~?Œ¤ZºŠÙBôêçU왪,w—psÝŸ‘Íu¹J.\ÅñZ¡S¿ SJW?Ñ‚A áàfÌ l1á'±b¿N…6\‰£©pbFS4Ò.Þ™Pðˆ©yæl›JBÙµºcДˆ•³P¡¡4ǺC+•ÿe´¾šêÐu0ÚØzISØŒãUñ4y¢KÂ@Íš‡Ú²“S½Txy€G™g®ÎÙ€1é]¸”|è@[†Üa6Á j¶£,æÑ)¶Ì2Q#ý<o¿ƒï”8›eÄZ³Œœg)Åh�Ò¬¦ð|’‚ž”Ãu£ÎâïàÔ)vØô.žÀ“Þu'ó‡8UÕ®ë`³9Õþ¬šj°\ õf©PKáÕaš]ò5Ô‡rØ\cSlX¤Y‡ f§ÙA–‘jèV?ØùìÚéÞ¾¸ñ‡ ÂvãÖÜ8çÚfiNÉxÕ–+ÚÇSvLžËu뜥£DÓ•™€vïÝk1d¿¹KwkˆêB©ÜÕ—YÞ¸q£ ÂT9 }íë_{éÕ—|õÀá×£ÁÍ7Žî}p¯¾pÍÞÿp$1mýëÝwß]û²ë›ú÷Sîÿáþappð7¿ù¬Î;gñRá—nƒÖZÉßx{õºùt¤nṯâÔb­ ² ¢Ûˆç¦[Ưao$*¿þYU·g,°Œ,a'ð×Oÿµîâ×íö·ÎµZg_<ëí}z NädÑÆ„[ùìy-3²éÖ`c.îÓ ÝÓ)Ž%^Gad[Ì…Ò±"1sÀá})Wïì B÷Ó_”·m®gгHhžÞÉP´-ÒPãJ3„êvèT¢Ç3†|ÅpV²]¨;ºE0;6ËDÆôë,àâQöÊ-ÖøšÆæt,Í\‰³¸x‚ÝV”…*™)f§Ù‡PID>…?Çx–ªGmˆe;ˆÒbf;ç7x9曘EF¡1M9£,¾Ã½W*I±^HÕ› ðægNÏ?ÅÉ%†ëF8¦wµJF€ÂåØtèõªYÒ`žFè;R•Ë+™=L^&ºÌ޲(ݬ-óJjy¤‰Q“ëPè_‘Ä ÂØ4 Ïsäî­œ ATvùQÔ4ã=8q›øfë1–î×½Néb‚Yq³Ê9¥ ›Ïš3ÓPêžN޳í¦SŠ5¸c_e‡Uó»X¸†‚ec6—±7šñð+‡CÐÚØ‰›¼o’ÛûÙtãÛ´i“|q·oß  {„Ê:»ßÿþ÷½·~Ûÿûðýyì/?pìÍcŸùÌgôC½v¬bóæÍ=úX¤Iy#Y’7²,¤õÅ3r,B|b›ª¾`Ü›YÖ œÖîgÈ$räJš³ßþèÅ­š7.qÒe¦ãùÝï~·ž7s5„ÈØåjš ·úZèÈÞ–g¡ûW¬ Ç*`Ë=.ênÁ6DDÇÈ bº$²Ã_±ÃLÊ<C§_ëOBo )ŽM³Ë¶²ŒT:´»#�I1æÕ–ÓiKQ«Çô¢÷AøV(äáOs…ö@%fۅñF¶K.”ËS­Q“G,àO„F¬{¦86MNLk– =FÏ*¿Î`…¤ñ[Øaì0ƒ)|eY+üR3”Ã,ùL´ ‰¿Ì*¨S,-2*p‚Ó2WRµÅLœÌvΜaû8sÓìŠãa´HÉÐènƼ‡E›í/º“£òˆ�|=IJú¬÷ðŒÈý}ž|‚}‚^û¶ˆV¦© ¹Õ@µ¹ßO‡ö=™-œÏ†íç2ŒuÍŶ•°fP4ú¬í„­Äñ2ÌW[(¡QEMN3£Í€šâÆd@/ž:Î\€W!ÅqæJì‘õA‰B/ãìeöVeõW½Ó]Çr‘ÃF’õEM÷‘ök½´nL—/_¾°å‚=`a§[¡]ÃL\ 'ÅÐÐе8¿Ö%ì|àËD~þäw°ªï~ï»À…K,�¸ªàâÑb/” tŽ}Y”­‡_õ“º‰`°†Têã.ÌÞør±Ss±›6mzö™gÿæù¿l¤‰vÏ<ýŒýÅ»ï¾[׆ôD‘ÃBµ[ƒ•üZ‹·ô“E¢µÊ´K1Vw2{†2û•yûfu,Îã[*Ý6~‰®_ ­ÊfÔ&Z‡éЄrÜ·âVÌ&‘ÙÔLk`öïvŠÓ\q¬òr•ÎnÀ«P®“Ká× ØÊ_CR¨ƒZAk<k¶*Üåê”ëähï´V…Nå ¹žŽä#aªá‹ K¼¦8¶ÈhŠ&4MV ê Ž²¡Br§lž¥KŒð5­Ñ‹Y&ZS,-†`6Pg®DÎ×é~1‹¿3)vïáøsýÐr/¨SgÔ’?AˆÞ[?äašô'ÅX…Á)NJÅêøä• nÁ'yë8{JœÍSfWžê(Çæ–¾Wæºqx‚y ƒ³Ìƒ¿È¨fIãÛz¹(ä„U)ÆÒÌe¯µ°f‹žú1y@ì.Ç„¢Óàö@+Üå4ä#HÇ*aÌz1jÉð!Ïñ92q0�yÎjÏgbpÊ«‰ƒ>î2ìzêl–°ºw™W^~E®:—èó<kß,j~ó[ß¼&“9Ïó"ˆµÎuìÍc½ø!³Ó'¾óDÕ#Åç^}ÕuÕi{âÞÿ .Hªÿ¯=zè¾Õ¸Füä>¾Ñ”õ¬÷ß_¨&À³dZ¥c©š×ÈGûî÷¾»²²òâ¡% r×÷Ÿÿþm·Ýöõ¯}ýÁ½þð…^DZÙ7߆‡ëðúÆÌ­Æ8Ž{7o#aš1ÖÐ5ѯÁ‰ã“ÒÉ¡ìÄC¢Õõ€H7×kok‘Õjú-¥KR«›œagð¼eÛ UVs ­NÁ¹a7á(‡mSJ5º„™? lwÍg2¦I7*]a¥Øäpü¿=@,4²ù!#/j@­³žW» -h–ª3”Íi‘&‰ÍQ5¢¾£G5C¥sLÂlŠæ¶«ëé“LS‹Ó;¨É„O½X1ËÝœ8AMâRS/Ì2‘¥ fS– F:θÆQt¾*´êÿÙ¦óCc° <ÌR••4suÎ.³Íœ¯’[¤Ü®ªf~œ=‚œ9Vd¯ V…Ã,yFR$Ô‡ EÓ†wbbÈLâfšSœ\b¾J|#ÐÝV &2)ü: ~Ø›$›·nJ"ˆ¢ÅuUÃÐnfš´]STµ BÁ˜'agœ•3ÅÌ9Ýí'"Ñîë*«~ú—îø—/_Žàè† 4Kð!Ft_tÑ]uyyYÏ#§…«Þp{I§ûí¡…A›¯Î¹Ys,uý«o­Õ- ˆ[_5\c$i=å\7çuµôšà[H¶_è3ºéPýƒßh6›:<a["‘à.þé?ý§ÿ½úßÿEæ_¨žïû~ï[íÖð{7Žz¤þé3ŸùŒ±ëN–ÜYÉ‚ƒ%vB#RÑŘE8kdÝ®ÙÙ,÷›¥#Ö sNÄWÌÔ|¡ÛÏH¸^4åÍN#6EÍïøäY¶×ÈS-uaÎÁ΂#ýP®h¿…b…4Œ‡\H…[4²±ù€fÝqÑ«3(¯ùcÄe§.fæTÌ«§hÖ 4j¢ÔÉ ;õ< © iMòÄë ê¶.£»¼I;ªx÷ñöÓ<Õb&`D¨ö$ïgû5SO°[c (©Rª¼”*™a–f™ÈÔðDa§¹'™¦–'(q6oZt5Ò”[¬ -ÔAÂ`foœmUUÂæ(3Î\šÚ9n?j<÷S4ÓTFšij"y)š06ê€÷;"|íä1ë3Œ‡¤v!Îd‰ÀÚÝ©!ª-Ešm%’yæj¤[ÌÌ…-̬?F¬áãµÏ–%Š}–‘ŠóGdZæ¡¿¿2;=_£ÂNgÖó+}ë‘ÛÐ'¬²7ÍS~îsŸ{ü[¿yìÍß}îwÀo~ó›O`øaˆÇívû¡})ìÚŧŸùÉCûj^jÚ;¦n”7nŒÌnêN-q¸ué?ŽÑ‘ˆIÞMWÕj&ú>44ôÁ¨Ãw—.Q{¡Z»>!«OWµ®péÀ#'ûᇊCë1·Ýv›ûç Ž©Þ?ÿÅÏÿž¿ÿ.­Ï¬Ùàlt'n–ûu:sݪœ²I œ_,tÓÇb—ŠÇ ïmœÜfº^½mË›EãZW&tÛŒ•í ¨ö8“ÆÒlEÆ=ÆÖº·”¥v±ÀÇKQÓdˆAM•…qV:†‚4 gBU„\ŠíD•L…T¬ž‚iv®¤ÃÎ3§‰yÖTHšlBÜ‘v¢nï¦8fÇ+5ñY#]!¹—£UÓ³T¸‡æ=4¨$ë“ÜÁ)©{âL³à¥›ggššiÉËiãÇ;ÁnM4x³L´˜ÑLËvΈ¤Ž3'ï“%2šÅLS“k ™ÄŸ`Ö')o<éTë¤[̈5æÙæ~.•9ÅŽ$¾=wë¨g¦M¼ûx»Îà4»ÔŬ38ËDÝh†[Æ•×Îè‡%ÎÚ)[ nÚWohª§ÄÙ,¾ŠÆF;]¶¶q<Ó/ÏY¶±Lh²Öì\‘¹<ñËz*GFWÆ ]_ðÊ•+[·nݺukÄz¦ïê;ÎØ;õ!X-³"yü[ÿà‡?Xç¡öuRí»6;KC/^üàƒ>øàƒ¿û»¿û»¿û»ÿößþÛßþíßþíßþí/~ñ‹_üâ¿ûÝï®z»Wj1ðо‡~rä'úV¨¹ö/öÜ)”Þ‰»Îž={öìÙ¾ f»ìbËYvXÈ}¤u›sù àÁfñ¿çúçÿç?ôÚ”gµº—œ›¬%“å.\øðÃ5Ñ»~ÆYènRâÌf 8ì°Ø—9—Œ:?/vÇD—mNwþIT^Tp9«É?q†ÊVc¢«¶Ö1ä‹afÌËæ®—3¦B–Áè&RI3™Þ´®åÉ0Eç(š²êLœÉ eHJYSl§ã±ë/¡¬*´y¶ÕðËgEtpš\‰2¤@)ŒBÓø`–ù*If™u€ Íþü({Å+$á´Â)åý&š•Åæä4W޲WÐ5Ë„)l"sW Î‚Â=ªdör4θ NíÒ:g³¡²w çŽúÁ#¶˜I' L {œI“?Zö‘ºU¢!í{ Õ&0n;’)c!¤ƒ¬±¸Ì¾õBéSó d¾ZË⛵®ÍS†´¾E!Ïñíœ9Ì£)jšo©lH L83êWØY‡,óÉW!=ΤG5 mëäž*"Í6œÌ–5s*æç JìñY1m×A³cdÉû$ï5/ÿøe}±§g¸å–[úVÝÛí Z‡Ë?Üúª-0º•Æ 6Üàä†NÐH}í¢¦Ød¯ÿŽ‹—JFsk˜½ÇOØV û¢½ºÖ«¾3úâž{îïÿ“ͽ ­½%Ù¾¶A7¸Ü ǦM›T#µU}ͳêësçÎõþº¶M?ÿùÏïÿ«ûßúo½î}Ûå½xñâÍ2 Y8¨Ü ibE‡©ÁÆñèàœ+*˜›]rÖ¶™iç/Ûtf.Ã*V˜DŽcv Ýu¬ Éeg2ÒÚ Åp:F4Ж #«wh±:Låz¸ 0™bƒ©;g̶e7Œ–gLéŒõvBMMóä‰ÙŽÒ$P³Ïd+œuILSÌSc²E.E3Í\)mÓ%+œÆ¨fê >Ï‘_ò…EFÅ¢¦8¹…óçÙ"}é0–™›cò ‡qp”EMF)öÔ TÞLö¶‡ãóìôvp*`·ç8þÈÁ#¨p:Nfœm%Ngha{…d ?Í6’ø;8àíæÄaò„¡Üƒuc7/¬=L^�y€’æg|’u#†Ò@K Ï#€Óu¨“S,¨õ®k1“2cÄ>ÉqæÌà͵+$5cÔ@ §À Õ€Z@P"“b·Aô™8eŠÍ1Þ"¨°Sõ Â€Ä­©XÍÎqêÄkcÑÚGûP!3gú—;³¹SÝ ; -ç_[Ìô–j?ŽeS0}ìÑ—ü²5áséæW _y£øÆW ]ÇóÝ'¿ <ûܳ+¬XëjèjÞzë­?~éÇ®;Ú:—Æ+UâÓÿ-ÜŠÅêÛ>úHßFæ7†|yÃå>Ë }d5úÚ­»¤S2¨›U#è§\Àûtæq^ºtI ìºmß#0¦ÏNøm}š´URöøCß}ÞzÌÖßöެõìÕz3Ñ]°Ú�u7/m¿³ÐÃA»©gÛÎ’Û’rÁrÎÃ;:Rˆ³Òjó„X£ÇöÖiU†lmfqfL1Å^[mÖˆº$!¡JHiu\=tœZg0ÎA>ÞNn³s ;óŸcE3uå…§|ø€9ÖA9_‰%ÅP§Ø0Í®ÍÝœ8ÊÞÍ'øó£"@ª‹æk­a–†XÎP=ÄA«— íæ„Ï^iPMX·wˆƒš×Ä>‘W58å/\ ðàìN`·€6Î84ÓÔžãþ8ÞQöf¨e¯\šuEL  nRqÒ#°±š1î²Á(Ëuïãgð%“e6˜5C)^¨©ilÆÈ‚‚%†óC,jGg±Äp¿NÎÇKSÓû`5Pb±’K‘äuBÅžQ×Û¡¼«N0ÅKÓÍV ÓéWÿ[¡ 6§ñG³–ƒbЦoÊæÂK˜‚ †¡Wn\wÇËÞïÜÐ+ݰ}ìÑÕ˜J5e#ðÄwž°[ègŸy6‚+}ŸJù'WÅξ˜áŽêÛ¢^eæ¢Pó:n²Y·ß~õѯ¾ôòK_}ô«W¸²o;þ¼[MµDðª}híÖ° ø¸—®ŠíÛ·[ï~ŒçðŸ|E0L¨yð›7 mŠ\Ú65 ]}Q3b½+>mßùkúƒZϧU°L§çWèáÚb׿ƌÇl—Ùl¡«WF}•»^ÚÄjʶÅ@ˆ¬1[I.ÚtGÇdLáÛ #©Õ0{®»; äõjXÝ‚M>QLßÊhPy&DC…T‹ ÅÀa5-Ò• §¡Q#=Δ+œ6s/ž¼’øâd‚½ f%ÂDÆX#ŘÄ/ÀaòãÌíæDœI‡úœÖrËKâ/1<ͦ‹F†ª†ç?ÃöÁA¹ÙË”eQpX'½ÄðnN¨•˜ÄgNœ^œÉólñIxGÙÛ"ØÍ‰yvjØC¯˜ÄÏ‹Zà»wpJ_äÙ–g›äK3û!s�E¯Äñt¾O°¯DF®¹Jnàíd>ΊG0Í1ì)NÆñ*$k¤Õ/ŸæŠr]ôþÌ1>ÅÉ:ƒ­@{uµ]g,”+$SÔ*&sMd]{­ö�$T*ã£>$ÿI1–Å7ã6½œãã¸bûßuÒÆí¨Ðm… š±¾»÷ÒåÑŸ}ùÇ/ë¿ÞvÚþGö¿Q|#ò‹²AxþûÏ//////_¸pAx¹6jÚ¨›žöî»ïž={VÙŸŸê8TÞvk^nâúè£VœeÛÒÖkж±íK_¸pÁm‹öíêÙçq¿Ä×|Ê—\j/^¼xñâE9;záë$|Ó àn¢Ùj[-%’>]è )vC©+ä)ô�jÙ˜œ‰€n*ܤ÷ q§ÖZ0œÕ9˜¶k~›ë±}w¢TÚ Ç!!¤{UÁ sûK(fÙ'i¼ôBR “XG‚.ó—ö€ò7D;RN»TdN=ź1c³&Ž$¤“~%L­T»Q4KeOYæBËço!϶9ÆÝ¤‘g§Ø°ÌP€w/ï¼Ã½ÆËt‡Yšæõÿ¢vZÆŽaØÌê½U¡UÇó/ù¯ÿ™­ç´Ò:(­hkÕ~õºú¹àð9î×ÄËnNœb‡^Ȫ[Õ@•”×f¼èuzKUdV]÷�¥ól1G’6F=NøéßÜIõ€ Õ IcÎ0cUcF>S3[|Ô^6½\EMôš¤ÒH@ÍL·ë–’ÚíÒ¹c�_þòWè»°ð¦<“õô·lÓí]é±ë´w%—E½Q|C¨)Žòâ¡¿qð6°BQÏözG­¿Á믽®¯]Z`oånЕÛ>´ìû¯‘&å‘×<úØ£ë—&õíqöÂL/pFÞ@ Y}žamVÝ›àŸáÁ�� �IDATí~²}ûÊ}±<ZbÝ79NŸûÜç4Øóÿø¶ÓÙ»úöq#arîqö…¢5Jµ*ÔÛ>¨ýå$e7ºä1¤¸•¾Y轌³÷ 7oÞl_TkAÖ•PÁÑûÑmþnŠNíˆB±û N´ÐÍG‹õvÚä_;/m–]Oö)SŒ+Ò6´Æ¡òòŽYw'n,¼%åÜ}€Q<æRŒ‰L5 ±þé ÆŽ:)›tB)³:móÅäq“ÄŸæE TZ& $L®&§ ÓKž‘ŽFijvÎ1®‰LÍl(®Ò#HQÛ͉c¹THVH* %ËÈ,sŒKU«F¦A‘¦‚©<Çk¤eï·“ù8“V4[#½ƒS³LìæD_Ó)bfsŒà‹"…Pže”Cs5Ò^žªüÜKddE$ žâ¤ÈëqöÄñê¤ÓÔŽ²·Brš+rŠØËQL¢Ë4»DÓãxú9føµÄY[jÅ?Ϲɧ©e™ŸebŠ“Yüc~ˆ”cêžZ)v.}¯Ò:õ€$>äîO<Îd8D /i›Þª [±1mÊH‘ö¸ÅŒÄÞºÀ²ÌÕ÷¤Q'ÖÈãì«ÆìûH«#½Žåº¸¨ië´ÖÜ`+Ÿ±~{r×÷O,Åb=b™õ<Cd}òÄËßÜgþÕ¯~õ«_ýêþáF£ÑX¿=ý ®«³/v]c—/_– {$È:bå/^.×§5$â7q}f•g/k¤»÷é4ÛVwƒaK9çÁ‰HmJqЦ…Y0 À"P$Å ´Ä´1ý¤¬{{™aÑU"Æ8+Ɖ»hû£¶GëÌqÒwÔYP:˜‘0ª¨pªRÇlÁR†jæ53–ìÜø4©3MH³ Ó5œTàW7ѤÅL†jŠ1%iè>+9h–ÉI2N!T67K Ûº¨­² d3#+$UËM4¶ìþê,Hg´È¨J—Iü*µH•·¥$g™'&o­ SÊ´Ý@8>y‰: >Ééa–vpê�¥*yà-2ª™Û¬Õa #§Ø ž`w€gƒB=qÍ£ìÕÞËQŸ¤Ê�-f|’%2ÊS Æîgš]6ÂLО¦–¡ªÁ9èê£16„˜á%RXÓIeq‡µú¶,¨Vê,t3­¸†6æHBÛdäR®°³jq56s£âºk¬†šö^ã£Úív»Ý¶á½Ôt¡BÖšõàC G{±Ó Nq§ðr k½Þ{bïÖᦄŸ|Üë‚Y—ú­Þ3œŽª©îtÊ-βáÕwãó:ÖÀÀ€òI>>¤_m=û̳ÂÎÕ6=«ý½¸Xûî»ï®g“Ô—qÿN6ïd?m¸ˆkd8 ‡>Z¾Xh9 0Ú JÈ=|¹v¡KsÔN˜#)†mQ_oiŽÓÎÉt¦?5é9“–p&UÄ;'Š®L·Ëº/wSê„ÁŲÃ6ìÉ&Dw’øP Ìt‰°ÄÅÎÆñâLVØé“2æìéqæ*ì4¡›;E[<y·xöù5òXgP_¨2,Ÿô)N޲¨i•^—N1¶›:Ta¡†J“øOñt/ÅX‘gâxz€BT亰ÌÐ}¼-båqæR4÷p\˜”e^€êÌ2q†íj‹º°”¢Ù"ÐQ¥¨ÝÇÛË ©Ø«Ö¦¥ø¶‹ñ³Õ廬Íi>²J&Ë|œÉíœ)q6Ë|‹“äq³$¡–gl 3Tµ½ðRŒ Ìò7Ý„¦i‘î “ŖpTú&v`ºÀtÊFU‹ÓJOÛNGoŠcq§~~ãðyƒë¡}E\Úÿã[ÿñ¯îÿ«xéG/¹w™o=þ-2íÏuDZ°Y÷Þj<î,·‚ú§µ‹»Öuά?Õˆ„YTЧùVKŸãùóç/_¾|ùòeû€¾¡i7‘n®‰ÜxµÕPó“|{{³lØaÎú㤨™øå^öY&Ö Vìa@¥aì„ NnN· ް êo -£° ‘OíCG[V>°CaËæ~¶·¢¤cuÔʲž>æ©<c�›KQSУîËFªTPµÝ8“b~¨ÃÐà¼õ~S]N…ß½U©V–4~H ;Ç#üKÑLQ›c<Ïq=&Ίn÷>IqÍ: ijrPSSäL ðrHó³LH†S#­€ \S4¿ÄÏ€%†pQýÂw¸WD°À÷&˜}ŽûÕ¹qæ¶sæmî3¸2V"“¦vˆƒÛ9#dµgÄW×0OµÎÂËú„K Oqx‡{E Ej³ø"Ðb«v¦©=ÅÓš¶TóÕ'©n¨C#«Ñ<èíœË2àém7Ó–>$ÕÄg5ô¾ À“¹`…¤ñ7X)q¶Î‚z™YG)N6ÇVŒ¼HÊm™•ÍÀÒŒÐ×ÀaÁ\™þ RÔ,YŸf—œ³L9¤qãJ–«Žö¯]àµ!'ÔŒøÕ}Âá!W®\q‰—å¾MgÙZèÇãÍf3MÇíóè¦üQ÷²Hÿq,QÌ-Ýkí_q¥CëLáÍç>÷¹OìÓ‰vn]s¹¿¢õÙÏ~ö6gÙçÑá­¼…{W/Ý\{ÝyçŸsÖ '½$bréÆÈ‚CÑ ÝÕ݂ӳéÖÊv”„’}¡o˜–0¾}žÁ׊n»�9Ó1 ì\©¶ó)ƺãÌ—Ë2 ñ´(‘Ésܲ„,#ÆY¦ì°“™iv™js8‘brN‰Ò²íÐ&ÞÖÕ‰LâëØ*K޲W§&•ÀÀ–øÄÃ⦴8Î\)l¶)$yPÀ°ƒSªÖßN UMqÌ1îd¨àð<;—£òŒÎ,²ÚÁ©=‚?ßɼœötî‚^Yÿ,1,!Eß�ï ÛUí¦h±¬¨Õv"=¼¤¹‹Œf1Šå¦¸¯0L Þégu0Iüì>ÊÞ,ó%2OðçC,+äDqÇ%^UíZôN{Žç¸[ša[ãÍSµŠY½b24LPRê>ɻƂ ¶Úii…Â};ü¸³Æb˜ Yy¶çMK…Û¾Ð'(ø$ë,ÔIg¨¶p.°žÝ^WwÓÞô·lÙÒËÖYÈ]›CXÄU¹ÕEÍÕš ×a}þ¿Ë²°ê®ˆVK^ö3ºÝ¬ ý–ž'âë´FÇúcÅïf³yÁYŸÚÏâÖ[oj~ÿ¹ï»ŒYtSÊÛõ\üvoq×]wÝu×][åÊŽ® 8{­lé5Ñ3åY4.?“ÝíCô*vûöY�.vWzÃdikZÅ©Ä&:Š¡Xƒpl#×y˜±Y0ß}:1ÕKËî‹–8+šbƒF;RŒÙß5Bß²‡Ï9íÌ&í„é5 l{ÆQ(W§±y[YÓÖ’ÀÒØÈå„všìŒ›¤PPgT# ã£3¸˜Å¯³Å?Ì&“¢•IåË^Žjæ¡Äž*™Í+j¤ïåÍt‡ÉO0{Š›¸¹_sQÓøÌ ºôàa–|’;™ßËуÚÍ [.–5]–‘Qïá×zWeSw˜MÌVɨæ¬GJʤã9@In½( Je¤—gÛŽ‹zú$�ªgÒ¸¡!“ç¸_{¦ fçŒe×(i‰³ÜÊf¯NºÂéiëR¤Š«rš]µpwÑY#[ÆOq2¬4İ ã*Õ$Tε—Y]Wv“d„`v޳Qá´³ -|¹(ë‘Ãìd¿È¥_"7nܶm› ³°·qÊv[eZ¤å-™îè»®Édnú?LG^±¯‚©¯ÜÆe´òwÞb§(²øV«ÕrqWò™ˆÃ¢ýÈbÎW‹,%’^¸páãêèK‚-¶KäRˆuûí·ßvµ¥ô·ç¾ÿœæRÜe#TÿT¥ÚÎÑãQ€£³UE7l[v M Ý4´Ðãj‹±f-w{؆´YF®§´!jbÍŒâxÝV™)jªÊ†z¢6´ uÒ®^ÉLËå£+­æ¨až¹3K×b ESÓ¦7«Û*f™¢¦IJ¢VÚ;SŒ©úg !gª¸“ãÌÅ™¬3¨†™¹œbƒºw‚"‘Ñ>‰QóT%ð9ÀEݬíKX­ìaòÏó¸Þ@)E³øØ�žæ©iÉb³øK ³ô÷æ©Nó€X£G°…ó¸̳ó;–Ò×GÙ{œ=ò40 2, /3t'¿³eÌqæòlSÒ#0}¹ÈV8­Z®FKãxª9ïæ„†Iê Î1þkîâîåè4»Š÷Ôyinc»È¨ÔU’^¸wÉé‰3©S6oØ&«>k̓šzlYŽã…‚vÂìɦÙe(~Qs™áçnüfµRû<Îd‰ŠÉå'µà èRŒÙê…óókëqZ¨¸)ÝÍõÈqõ0íý¯ÉLG¿øÊ˯¼òò+Æ|ã`3ý¦ãñ¸Å=ùÃû~£øÆ[Óo}ÂøgQym­Óµª>ŽC½|ùrïéÀÀ€ ՞Ū]Y™]‘šígÌÚ¼yóÍj”¾ø£qÂSW[}G€Üš~²uëV1N•ÊU^»“º6ã,ö/«FGMŠNOÔþÁL°aB.¶5ÂÿÚ Ç£@ºÜ„mU¶¨³`ó@‡ut@.º[mjÃ*›4ÎbÆŠ¶¥fdœËfû_6*^«­iè(47‚\…ÓêvÂ-¬é‘aŽX;-Y©‘Úb©Jddïže^#¡KiyT)•ûîåi Pªû(ÈQçRýΔlS-Oõ ö¥©©åyo¿æž: £,Z7ƒ f“m"·<ñ³e†ä–p”½;8%£Ú4µƒ Ìô¤2Rê JbZ#=Ärôå_ú$PÚÁ©9Æ­¤Â;8¥:j–cô'[ ìàÔ0K2Ý…ržª-í¦hª »—£Rü&ñ+œöIÖI³ÇS¤Ú(‹q&«dòTçWóÒºð¨Äª·ZW²4·êOs%CuŠ“Ê#Ó¦DvÙØ¼ÈånNdIÑÔôKŠ1›Ù®ßnCŒ™Ox.JÑf¹3VVV'§*mðÚ¨‘ºŸîbÚ†GÊ€×wKzååW\l[ÃÍÜ>ìà7~÷{ßݼyó5Á¶JÁëaœë_VÜQùjIÄûêáW#7Û ]›s¯ÿ0Ô*³:ØõOp^+|Ú†î *yíšÖÚO~S–­cGí7÷[âܺÆ>úè£gž}æ™gŸ‰€:F>¦µZKõ`œn˜´ÿoô¸"؇ÙQnm”ëí´Ñʺr!cÔ6|Ôx œ;HC[xç[÷¥fZ`L\ÁÜŒT¿-`ƒ)ŒìÖˆZF˜±<Ïlù 0 ˜s4M9#Œ²JZˆ…J¥c2é6¿UVq/«Ñ.ÁPVOßÊU°g2MMå´ÈQÈ'9ËÄÏø’?,›ßËÑ9ÆÏqû4»ÔÀ;̦*™)6æ…4µç9(Vó—|A…Ðc[8¯JibÅÕ–:Ãv)hžâéíœyЧm·2ÀËâŸãv‹ÙÀÎë=ã”ÿm!åQöŠ@Kœ¦¦ŸfSššuPʘùNà ÛÍP•:)Gy”E;ˆ©=LÞÖ®SŒM0›ç¸l ”h­gÛj¹Q ‘5BÜQS4å°oºÝgUn•a‚g|qEp5# åÃl’nH@tžãaa£cƒÜq˜2×my”E¥ñXϳM30ÚJsÁ´µ£ºÁ‚íð)­lDmåÊ¡æOŽüD÷c‹G‹Å£Eë_ãVØì=ëúhP/j®ÍBVCqWVóàCÊœ¡ïºêþG<òêáW?áf^;× Æjv^ëäè'3`ꎚô-uØ‹$ò‹CCCCCCÚê©Io—¦k¶nÝúñÍ®lݺÕ=*ñåË—•º£zÀÊÊŠ.ŒÏ8k5ëŒ[VaœeçÛF/u¢.‹ÝÄT²Ø\Ç”Àü®É$i"Øñî‰Ç&[Ìh(¥[pŒã­;ütV̆]_MSS&2^½Óy-8Ô6¶,|ÚVW6€rŒ¿LB÷Ùno ² `±‚©X£NÙñ”Œ3™¡Ziשׂ7úÅŒåÙ6ÄIy‘ËÍG÷_M_X2ª;ûnÎ ´Ô×̇9Ì“>HF4Áì v+)sˆåc>,1<ÍéHm(˜¾–Šø ÛGY^»"<¼a–äìó.wŸ`·œ`eÑž¢yoË6A:š�ï0›žä­ç¸¿NyŠÅ%†ãxIÆ<jª÷òÎÏø¡0x!`DO>ʆ%¼<@ ÙÉs Q£©gÞÃqªØàmçŒØÞ}¼ûK¾Pg—Ÿ²ðMÑô ‹:[–öÂ*©—¹dÚŸæóZ1þM>+°PbO–yéâxY£$ª“kµôÉ–Bg Y_¥Mñ3àdzoìÒ•oÓu4’Çk…‚ ™N>AÇBèf.%¨«DÉÞµÿ‘ýîmWØyìÍcëÉÞŠ€Ÿû<ökay #™—ö¦æ~qäõ#½¯²B<øÐƒôÛ3¨T+O{¿*B¬FÈÖón\¼x1R›ýd„?ö¹té’{Ó·¶8ÂrŒý8\€xðö¤°ºÒuwL¯›^¹råÐ ‡z[žk/)“WVV~ûÛßê'Ÿÿüçoœqö–CËV%o@+pÐÔQúHºÜaʰ9ƒ^Æœ½ã4TŒÛì‘X×¾Ò’B3d2£9•¼L½ËVJ šÉ3õÞŽ�Ø—&§Ø`LË'ÍLzašlè£ç„Ÿ¤hºgæ1¹)NÒNÐB„²íÅÉ€^ábºSO³K=¶[µ“!€¥˜–Ãl�lçÌJä$—UÓ1Mí»Kœ]f¨Î  H!YA?Ouœ9‰eô¯*ù Ÿä­'y+2l猄²K x(II+ÔÜεZÓÔòl“Ý<‰t𪠳ôn™b¬BRf{b‡sŒ—8+µ‘سL=‚=?Ξƒ². Ã,&ßbæ ÛŸæ)@Fùijš`‘êJ¥fà({ƒÐþ©¹…óIüT˜ž\dTVvƒâ3<ù7 ÛRŒÉ±VTXÛ”3Š«·Ó¶8ßbFQ£fëÖ0cÁaÞ0Ñ0KÇl¡:[L›kíJÒœÖÃÍGMáŸxd/jöUÆF†O>=+âÎjyöOòÓ×_{Ý­ã½þÚër]xô±GÝ^]¯)ÁÆ׈2ýTþMìjßÄuñâÅW_n‹q``@¥Ú;î¸ãŽ;îøìg?+>ªŠw ¹µé¡"3B?ø›¬6šr­ë7¿ùÍÅ‹×_£^-³áì nô´¡kn,I4ØeÛ6ña1\7öÐ¥3fºÐjœœÅ5œ –œs “wh#Y§M2Va!bL‡1ËÖg¥ÅÀtçŒÂ³ÓÍËXÑ4ÕsVéNê“4¨™åätûÝÁuo5V¥ 5Guä)Æ|¼8^X(Qs¥°q¼{¦8¶Äp†êNæ³§E°Ìì ˜Ÿâäy¶,3”Åhšº.;™Ÿg§íÛTãxÕ §ws±Jf%ùÍ–ÈæàÃ‡É BDìR4çÙY!™¥ª:!ƇÈâ÷y¶ˆ)xöç*Ø Â“øÃ,‰™©ªV%ì8Îá±O2kž0…/x€‹gØ.By†í%ö¤œ2µbμ: ;yWåÄaš]yª)šç¸} ç=yÛætÊPwŠìÆLû¤ÌPl7'”Â&6©Ng‰³„)7ImȪxÌNó@ŠšÏ¤íjÇc+Fé£bn Öì)sªÌOqlÚ(�Za3g.lëm«f|Ãý9Ö+¦z£¥2½TOs#b ?9òd„\†ö=öæ12×O:×X}¥1ë”Ü÷ð¾錬ˆkü¯°_~å°¾½ñìa§Ðpµ0«aês‰€®,¬½pßõÚ¬úÓ¼ÜS±Ï«N^Ǻå–[~ð7a‚ºÒo>äC—¶êºÒ_‡Õf»,ùÂ… ª Ëž×ÝEÞùդݫÍq–¿ä†ãX[ì†1[n5“*1îX$Öp6ÆÛÚÑë¶]•µÇ³‰±jt¬ÞÛ‘ækN=§8“NVh¨WjÔI›0ᢳ£/KBÇËs¼Î`ÖÆVÄY|E¸ÔÛiÁˆhJ„X#À³Ô?¹:õ,­&HË,óz~u¿<iv)-DX˜¢Y# i…ÄÕäT ™Ä?ÄA‰lmß.‰_âlžmrç9Ãvk>p€/ æU¼ÕS‰ã¦hÞË;šô§´X8ÎÜÎ_ kŸâi½bÚˆ‡GYÔ¤Ç"£*uîdþ<[ðÍe†FY¬´w³´—£*ŸÊäa‰á fϳ¥FºD¦Jf;gò÷&˜MÑÜÇudë ¦«‘~Ч% –’V6ñGÙ{Š’'Ø=Ì’zÌÖWÔN±Á¨ ÃAÏÃä—ª„n^‰ÌËšâ•zVóÁ€6F>É5c bEãѸÒZzf™k aÕÚ¦(bÕ×Í,#Ž˜§¢S°=r×å?²®ÃF EÛV¼ªeøè±7é>¢_ì{o6›—.]zéG/Ẽ"4nÞ››Ä²6vªf{äõ#6v»Wþ³šÿíõ¡æ' ‘Y«¶0­Õ诨‰I‘Ð+/¿rñâÅ?þñ®äØ~Lͺéga[žîënݺõÎ;ï¼óÎ;ï¹çž{î¹çî»ïÞ¶mÛ¶mÛ4—¢¯7mÚôÀ¿ /«~âÛO�ßýÞw¿þ¯ÿ©>[ú¡fÎl¥W+X[‘Óªlwò~ãL&ccõvZ@ÎÓFHd†´žj 0gÓM8øjÉ+PHQ«‡ÓœÉœ~d'€ÓÎYêîV1¦@¹jïqí„ò–Ã&e{@ž æH€rEw=ÃŒë@»ðÁ×ý½Î €M‚N4 †TëQƒ"rR•×AÊôüJdlH´æ/ϰ} ç¥':Ξ{yçs¼¿Èè4™,Õ §kÆ57EsïŠÃMqò üò"›žãþ,äÐ9n›û”šy˜¼Š«P‘PVS+²¦ÓøÿËSœ\bx‰a•1e9ôûT,U˶ÞN+ xÌ 5ü I%zú$ãÄ?Ïýâ¿â¿L³k‰aq\(ûLÊ™AýÅ f+ì<ÀËgØ®7DN뢶z]Ûnx +¯4MÍV …r1GqÆ4» L8ÈÛÔËt)ÎJ«= êˆ¢4ÍØUgr/G3£jGÝ\fŠË®‡å\là ¶N®Î‚ipŽEsÂdª®Ã6ÈÞÜ]ºå–[Bâ8ØAÐW^}e à´7)—_Zµíjj£¿É4 ²Çwt,X A_~ýeõ´z…ïØö8-Ýüÿ™»‘ÕE¾F¹ÕVGE#B3ýÐöJ]:nétêcÒÿ7oÞ,¶-§žmÛ¶9sfg!–ÿÄ·Ÿxþož¿&"« û:ä`kìêV+ÕÒêSªu‹´t;$4Œ»˜ SÔ»F6Ýø¤¢3ÁR&Ì;$[ !Ji'±p*ÔÆ¥¨Õc tÅJç hJ©¥¶Yü eŸIŒA0Xr•NKµC—è8+´sºV€v!¬ÑµC ´bÈcÄYiÅr¥v"[‘µlÝ ÆñT*l1ã3)iŒê¨)|‹—ª+–È©x8Äò0Ki†Jœ !Vå¶D&EºÎÂ÷�¿ä ïpo• ¡+PRz™ùéOyP‰];8uŠK ïd>Ž·ƒ’®O2ÏܶCy–Iù *’Ók«¹¦†5¥cRR´lre 0Ëijú:v|;g†ùϧءÖfœÌ^Žúì=ÅŽûxû—|A-£a–þ ÿ °ךv=Ξ,ÄPK §¨�é›TË“”ê'ÍÒ¾Jdpô0›`D˜:Ç8yª:6E[·˜ÙÎEÛÃö‘¤¨ÞNû±• fë,¨B…꡹Ў1LYOR;Ì&(À¤OëV1»C…²øõWlöµu¸µ™e¾ÒѲ•[äàŸDþ,“dÉ“MMrèR+›öu}mQÌ\ÊWýªÆ.]ĵÛ†×ß{³èè"™~¸yófÝéF:«që´ÖD^xyà«úbg/pFä0½*›Þºè~ë­·êP-`|Ú€ùª¨ùñå˜^umß¾}Æ "»JÏ@ Œÿí¿ù·¯y]×ó•+W¾yð›Ï<ûÌe. ¶#’"{Íëw5—¹aÃ÷oAN‡7~Øk‹ƒÒÅ)×,æH œ‰Fóø¢a ³Á/š*–“¢¢n¬ÑŽ´ÎNÐðB±¾5*J–3ˆB~•LhuÛeì^Ð ¦™ÐDiαám˜&¥œ ¼Ž”Éygò±ãɰ躒ŠÕdÎ q…d™º#k$Q kð- ¥¦TH>ÅÓ%2sŒ§ËSbY.tÓ\‘GìV¥h*AL7Í® §Ux”çœ*®ÿ‰'*æÜÍ»N{¿æž ÕSìPvØ8sÿ’ÿZ#g›5…W Ð (Æ]aŽqÕW÷rT}MÅv ŸrHûŒY&JdN°ûû¦¹ÇôZ¦(Ím€7ͪ*ð.2jGGÒÔÔ•EQ…Ó³Lìà”¾•y˜¥<Ûôrq¼9ÆåØ0ÅÉì†\% €;­Ê­Œå:$'ÍhøGIãš/jµöº ˜S2òZH(¶Z×’ÚäjØtk‰}Tf0Uâ†á— 34•p¶•ecƒ…S¹Ñ%'>úÈÆiËÿÚ«¯µÛmëȪi?ͺéa*{>øÐƒ‚O»é~íÕ׬FßVöÚ=ë¦ÜLíLB߬x§]}í1·Á)¼´ßÚ¯ÿäUY×Ï=¹õÖ[×p`Ç Z±œ)bò°qãÆAg}Úø®AQ]Á­<K´ù)ž�� �IDATiÓ&ý«*Ì]ºtiú­iàá}a–Î7~ó¦Ïùóç[­–ÞÀHÜ·kò`?¬ugΕtü€Ö�Å©Ö:ØãÿcîýcÛ¾Î5ÏÏ·®CK‘¬^7Lu+A³Le˜ ŠZÄhÇy·[­<š¼Ê�ר<U}#¥N£$vÜ8®ש›¶q’:JâFJõZ]àF—˜ÅŽÆ{;k- h@¶è4¬»¬Ô:aêY²d:u¸<ßsxDÉŠü#¹s`|ñËóœ÷}Ÿ÷yl{¥_Èñ!§Aô™¥Î½ŽÞž/Nkd $øî Rl0³ƒH2ùÞœ™ªªiP›ãj7ý*¥Ž3©%ŒáeBÍ š¦•ï¥ØÐâã4ÿÉRчçb…j«êÿ:‹ø PDÐ¥Çj=Ìp¾ži5rˆŠ¢žúÆ$[ÚÊx˜ùSì ý<Á:f’„ZïcAj´Í6Éɶq¦ŸÊ]œê£_vÖ-l£c'#i"’>ag5s¢ÑÉ/P íõL+d”YØ(À9¶gŠg„ô8­ÝœÞÁé*£~^ì‚Q©Þ÷ÛÏ1“#]geƒ†Š»“„$ ›%$þ­ZA¤ð z§•:²:®ºÂÖ|ˆÓ™$´‘«õL«è8I“H³¶�çŠÐ±@^Í6–±%Ñ16}-½Va˜_IZMé³NêÊpÞJùÍľ�dW‰ªVDµmëi³´ï‡æJíÚ_†Q[tDƒ2uÁÒпƒ«Gk×èþV÷е@»[}Ð6Dêþ_#‹E«÷¦êšæÁ•¾E•\þ¼«ë½ç±=n�gÇ^<VF r‡{¨+¢ï½nгv… ûNÁaYóâê p7Ù°úPíÙêoÚ´iýúõ÷­yübíì쬿þ[ŠÏÿðù²ZìË/½,ÿê[2µ U*ÊwqÚ(sÐùU».ÖƒK© JK< #tÞ`üL0 - ŽTB‰F!kCÕ¢ TìÄèä©Í<!ÇMÑM§fÞJæš§Á¦ûðµÝtI ÁbÖ7ÁHĹ&- Ë÷‘X‚˜,¡€·X‚sß©qXÌÛ¶è%‰Í⹦=“4Y!Ö€3Ò3ó‚.19w2"ÿdáÊ8­ýÄD‘n0Cp†¶›Žpø›[È MuÊYB5ÌÖ1³“um63QÏôU6ÆH‰•$ßÍ:5�ñbg·w²¿ød| ³IBÕÌÕ0{šRjãÌ,5#ìì`,JJA›å¾NÑ(Ù ýkñÆÕ%"É:Ñqó7s©™‰&&§©obRB?¢)‰ÕÆ«® ðûˆÓÚOe#SNïÒ¶•ž$“Ô£’&""•ü”ñŽÓ#¥š· ж-èÒEH±_ÿ+ör*ÓÁ¼¼’þêÁ[ôµ¥Š QRƧÁ@¬|7Û…ÓJNqÿ³nËAOÈï(´¨)ºOzJr½0«««ÿò/ÿò/ÿò/—¿íÍŸ¿éê Xìü4i5«t<ùÔ“¢Sö=ÑçÆ YƒÚÇßÞóíÂÒQ&gEjÜÎw}BQõ­‚ìW^~åVÝA·;ÜDº»5êÉÝ«%…ë'0þÌg>ã>ihÝ0"¾ýùÏÖŠJßé«ý¯¾Úÿê¾½ûžÿáóvã®äÓ¾§÷ ;WGеµ,OWLÕ€I8Þ íNgg¡3X_ÌAÛÔ¨ô©Db-½Óáå–J7øÝ)E[ÍÙðÎB²*XSŠ,Cd©¨l»ÉÍú,¤:#á]a =ç(¶‹åçBnúgQlPÒ/Ì| #ÂgÁX©Ú ”а—ö¹H¡X!‹fÅê³T¡N°×Â+_®´¤<CºY'7cµW†™—øN3ghsG¾˜rG9ÍA¬¤ïf©é`LiFEÒb½ôÖ3=TÜ­OÑ8ÂNáŠÞ|È{>^ì*î3?Gµæz±l¦©¯gZUØQH(+[ZR#æm+ãṳˆ¶2f›€°™‰ÓìØÌ%¹R:$K› ’— Jáé¶ÄHõaW”í²�3¨y^õT­Z6rUqªÔ™Û%û";ÂÎÆÇèÐ  K,¶*î×Á(y«#‘Òl7guCfŠ›·è`lˆÝ~îÁóËÞÉb«a®ùÖåªÂF I7ª1Çî\¨”±Ï™Ÿ†/tU Â”†?V~³çU¸9ôö•>lG£ûqM@ËÙ­e&Õoþü͵„›w<‚ÎPcß‘9þêñ㯙öÄ'\YD–Ex³éyäg¯üLÿÖ¢¾{[ÃÍuëÒ)D¶Xëʬ»ÔV;oŸ|ûVÑÏÞ}{%ó´Fâñ]×—ínVÝ™:ÙU$6VoüØMýôÅŸ>÷ýçžûþsî“ÂΗ_zùÀ³ìÿe;²§�ÛÓîÉVUUÝ–H«º£°TÁ¤ÁAÍœa1T”(²Vñ�CŽõéûî6KM¢F`,gެϺÔY§O´§ä2Vªµ›f€#±ÝµÔølÐ̪ƒ’í¶BhæÿS»"IHRy ‡Š»3ÅH–üAm…²@>I(Æ&Ûº ˜”‡†@Tór–\8ÔÕ7EcŒ”ŠˆÚTˆl=Óq: ¥¥' Ðp'#ÆÔÏa¦‰ˆ›#µƒÓê$ÑŸi"õL+¬fn”N…S“4u0Ö_|²Û;/v rösÌÂj5sÀ Þnïd¦™¥fŠÆ²ò¦¶à:FGc2ìx †U”½ÄæQ:ÓD¬_¦"T«ü§Ts?± ç3Tu2:FGqã×]ÕÇ‚t‚j˜ WuÖnÎÚ3JJék}eJMç *‚ßJËõê(1 ì±ZEý¬�DIÅ®1‰›W©8Jjˆ›3i[Ýx‹qùc{‹¾å€d ¼E£õ¯ÌAÞxÒõ˜<°·´÷îC£æ4ý-¹¥.~÷`(U+üÓÿn¸¹ÊЛ-v®(�{»ë÷e䪫«¿ð…/X=¿?¾ÿ»ûÅ:öâ1Å ¢ ÙlÞ­ÆS{ŸRèy÷M¨w_T[‘µº¤þÞ}{éyä­Á·T]½œ¹¢ »›w-‹ÿl€®Ì§ûñÅÅÅ;V<^KZ[K+W®\¹råøÃþð@>øàƒ>øàÚµkº=ôNEŸ‹‹‹Š8m§Ægxö€}Ò}ü‰Ž;œVŸuXòƒKýLJï—»œ¨ýF”'…[âß–r¿%ÝZ#øîa*‚Àœ12ÌÙ‰ÆÙf»Kß‘µ¤!öóäRFRi„Iws¶P¬{iŠ ‚~rØ  ˆ¾¶ìdز"é42%‡/ÅO; {ikõåȵ ˜m‡Iœè.NEHOÒ¹Ã鿤¶ÙË€È8ROš ¨ÃNÒ´sB£8W̵qf€^™nŠþcOSé_éÓªÙñ(µ»8¥÷läê1ö_¦VûŠ;íæJQHÛQ<*€WùS}5sJç ŽÒ©M]•$EM 3cS7g±'#ôFHÇHµ¤é m] OѨԴ¹‚2,Ë w?ÇÔÖ9Aóª¤ö“¼»P6Ãy¹lJ–]jJŒ…ÈJ^#Ylíæ¬ôÙ Eè| [â\IµJ³a/-ƒ…ò%õŸ2æûÈ­kƒ)¥/JˆÑYÛ k»4++”m°î(«—9o;…~ûÑ5¢¦¢R;o+O{7Cš¥6lxò‰'ßzûÉ'žÜ°aƒÂ ŸB͹¹9kRlo«@B® =ÿIÒZ:ltÆÚ×À[ƒo¹iÃùeã“8…‘øæÍ›Êc{ž§K­�ÚZ‚ëýzlƒrEÞúàG}$P”Hìûï¿ßø¥Æÿüýçñ?ü‹µÕó?|^и<+kmÅ<{àÅŸ¾hŸ¿ƒÕµÔªo¥Ü‘³ö ög¿¬ÞÂGÅJîù(Ûîlã¬Ùc«†JrZ‰ƒo<é«ËJ¢ÅWÖî`ÓX©bÚcÁ/S’AH„}ƒ_/4Ik€E¿ÕÄ—ý˵°%É0¾ŸÉ6… a/ ٌю‡E5˜J ¶`´¿ ¾®M$"l‚+FÅ-1D;$‚lé`LŠi(PѸÚN’ Ð0Kè {doÒBö ÁוæIsã©"cKm¢ïðp²ØðÃdÛ83Mý$M†Ólcv†ºÍ\’¤_²ØÚï}ç=Òx£ÂÅ€·x±&&“p•QRµ\nb2èj¿Öòº‰ÉZ.ä¡RL 1 ô†ÈvsVq­8H¾™ Al7g«™S´º™Kb'¥‰(íe@=62øÌêá¹0ój!$·:ÆþïBšO•�S“Z1(¹m¨ÎÁ šÃ§*Ì|’ª�Aγ-ÉEÉðrSd[L|Ù’' ª[EÈ Ù,¡‚ ±ØñrÐŽi:££`:ìÎöP9BÇí¦íاywsr„ÒhôŸìqú•WlGQpóæMýžŠ9¬‚ >÷¹Ï¹ó¬€puàüÅ[¿°EЛ7o¾ùó7]Ë‘G¿ý(wG±YÖç#u444`|¾ô¥/ýý;Ï&>øàMŠ>? Ë‘5ÒFÜ#×õ¯Õ>ùZÿk’Ãu©˜ÖÃÍZ1&t>½ÿé[ÅkI´~dZû•¹çx+Ñó»ÿÓÿø?ýDZø@ßò‚ö¢ïÚþ¯›äþûïÿáÑ~ÿÐ÷_~éå¾'ú>ú裟½ò³§ö>U`IBÛ§}àö¨h\¿~ýŽyE “=K$Êí9q)¸¾.óŠ ¥ìÐ5é\#¹§ù%à-:zžíIFåÎ×úÅ š2’›ÚÅw+—+Ô„&!!})»fü¢lÞÈ5`% t¨YOZ ¶Ù`Þ˜_vÅý™®+H>ãÏ¡=AF%b† ù 9ÈZ÷fÁÃ~ŽÓ:Ec“ô† fL²Qði%Uwqê >ù^N™zìó˜ŠoÔé¹òML*‡YÇL˜y!¥Z*ÃÌw{'‡Š» ÅŠ´—VP¨,îÁ¢Ÿß{iƒh›*¯Æ êWQ6UQl/ýÄ‚4Šû£ VÑ­h´zòûϱ]!2FÞ¯ƒ1­j˜µÍ£)¢Ri"rÆ*I¨“QõžJžð(߬儊ÄÊW[–Ôõ”u3/Õõfζ >É òÌÛÓT»­ê¬jÑWœ$„ÀÏ´‰·X(VÄ!ì¥3E-ÅüU˜ùŒÑÒ ’J–X?Û2TˆÐÁØWt‡}åZÐJ1çh[®•ò±*B‚=‰¸ZšO¡PP#¬ýÅ[¿ÐÄ=??“›8ÄÚË«³mçûr•öå3ìív ÿ›‡ÿÍß¿ó÷€ë¥ˆ³¼H¶q£ÉÍ1~ÊÍ”²-³Ø¹Êp‰?Òfzõø«/{Éry^yù•½ûö¾òò+.ÇguÚgñØÖb?¹óuyF¶¬è.k6lØ ê¬+uTYY©;V ~øá¿ÿßÿ=0»0ë.MiúE­å?ú_íWB^üjû`CÕh?…äp•í鬂¬·ªq¶/ÍͺFc²OJ;yÚv¿kÅ$Z¥OV*yºÌ bŽg¯‘û©€†¶½Äñ—èQ’Ðja·°Å÷ óiŠâû ßà+ìnü»bl+#çc¡RN¬h±üÊe±B4B±Â¢fÁŸO/Z…œšRÄ£Ã.ÄîQ¿fgvpZ¤•cìOJ• e–P7gÇ舑R ÔV /±9Ìüf.ÉAS-ê°›)^ìT£dÖ›˜ÜÈU úÌP'œëöNÎRf¾“Ñ)»½“}ÞñL1Ò_|R_“x»½“-ÞxÐwfF *˜ŽÍz0AóV.lçÜ�½‚*^JHO ïõL·2>I“„‡Nì—Q¶lËj˜MÝÊÁ­Šš²ÏP5KÍ8­4 þGéT,«Tp€ ¸QÖø³š¹!¾ž¡J [±¦ƒFsJÒö %U66¦:!UÁ£¤toÄHAÂÐÂ16I‡]Â>¸z9Ÿy xƒFúJFè øZQMª6oÌ« Çé´KO˲Iø¥‹ÑÛc�®H|éØK¶¥D–,_:öÒ'1±~ö³ŸuS|W¯^-„SÍíH9hË–-@ë¿lUè\YY©¬ jœ{ÛsügÇ˺ëþé_d Aݸm¹‹YYÙõ‰'Ÿ“VJÂÂNAæÇJ$®}(ci»ƒÜûgE®Ð­ê”²]1ÿi_ýX¬½­qíÚµýÑ‚3V¬g[ø¼-sõ{[ãlpšFz–õ`ÀKøZìÁ³2ž %qƒ?Ö„qÞ  ¾nΤRmA¨ÇÀÞ¢Ñ.f& ™ÆPeÆÔ'jy‰ƒr!6S®@>N§qS鑦ïYM>@—hz"=.æ ú8ê-šN»KRß‚!…ž·ÉIår •¦]s·¥ö(ýx„ÊSx%ÕÁ˜\7sII`9sÑ!Ù$ ÍÙNF61ÙíÄSüÛqZ/°5Et3—lÁRŠ}•,<Ì;âé³Ê„½ô!ïy©ùH{/ET$;0Ä׳„^ãqé43q­“4EIEIU² óº(Š=Z|îaÞQ%8Bz;ç´ß8Ñ:f2ÅÈPqw/—©9¹3Z^H·V*ÀQj›™°ÞÉh3òL©G׿ŸJí}ŒŽ²ú:’\T[’úʤÁ‹O² FHËÐ4@W’Ö8W ]Ôhü¶Ý\†ª8W X–\WýB¸Yä…Ù`ÑZîX>šUº— ™|RQ@$»Á(©µ¨¬]÷ä¥c/•%�o…·Ê®8„RŸhoÃïþ¿ßgΞ±Ïüèè0ŠÞ« é9X`«sÅ&Åukûuʪê•iÆZ°¼­p³l#_íõGzÑ¿{xIþðèÑ]XX¸•©¨Ë÷jw~ø¡¥ÛËh• nܸñ§?ýéOúÓÕ«W­¦•Û½víš[:e¥N\}‰OïÚ 1-ìS·Ôªu`r°T§)éûØ*&>»Ç·Øì2€Ú^âûØôo<Âl“b§AÓô„Hgý0ÔwPÉpzŒz§$ô†¨WsSÏRµ÷„aa”Dn[O–ŠLÖ#“OúŸ÷C‡bCƯ«ó8’!öÒ®tÐX3ülÛ|’‹ŠHâ\™e“êvS4&Pxœh7g‡øzÌ(Ó†™’Uì5FG“ÊÇîàô)vb—€A–)LápcõL÷SyŒýð\·wRI>ïø$¨Ö¨ÀÑš;^ðF•z%$¯Â¡DïN±«“ÑCÞóã´¦FHc¿ª}’Á“’{Ïõ¯g:ct Ó¥.L—\SZ?Íiçæ öÑÿpñZ¼ñd±µ¯øz‹÷0PÏô~ŽI9ï¿<Zô9åÒ­ “Í#ÍÞÉ©Z.Ÿ¡Mµç&&³„ú83@¯¥ Ò)¤jæ 6Á¼Ž$ÆØÝŒÔ1“&rˆq9Àd 63ÑÍYYdà»”ÑÕ2%Ε¶¤|3œ´¯ê.†šŸ·PŸI;$ð­wˆl¦ríF rØ4Gµ/5æìÉ0¨z¹ù}%ÊnI#™kWieÃÎÔÕÕÕ6çNóÈߨÄÔænp£,Å'‹¾.¸ÚŠÝ§¯§œž¢œ?üpsãf íëm€¬¾wè{v®/SÂQëý”Ûö]øÜóØžû*Ÿï}´× ò•EŸ‚Æg<sóþ›e¹M}D¡ÒÀ²¢µÍXÞ™á¥ÍýªItù–Cæ‰7N|ïÐ÷nwG«ÞÕ«Wõ5IŠáv·ü½CßûˆT$]¤¼qㆫÂ-­¬,›í>i3Æ«ÜN·2².¤?ë-±­6¾öƒZDç–VI1µL¿™Òš?;ÓŠË""òP‚½œU{‘•þ­µNÌúpÞÙšõ—ð­:,&…§ž ±-È–$3TÙÖ—¥¡C{œ¾í‰¯ö¤ÜMÒXeEÍl!$]Ã,´™Üo/¢ÑŠf2Än£+D¶@Þùnž¡­…l’Ðë8ûˆ+u©pSîÕ-4Bj‡wà`q÷!ïy!PŸwÜ·Î6ùÛ$)öÄ‹ýÞwöR0Bú*›˜¼ÀÖf&T>Ì,+"Þójt/é m{y%A»Ú:g©©aVôóŽBÛYjv22TÜ­‚ñ ÞÓìH[“€— ’R1U2¹:…Í\ªcæ(ßì÷ÞÛϱùÄD„t¼ØÙçï/înñƨlãL–Þc¢õ‹™ÇR`ךF]¶ŠË•-/j*Â6ríAw,I‰ ÖÌD†›Iÿ> å™—ÅXœ+PåW4iÀ°„dí™QîÄËÙoĹ·‡UnWÝúЂóÆæ:6YbsO&–þRìÂn­Ñ†Kù)ãGÜÛQ†¦úsž…[õ ­ÝÉHQˆ-&åóù®oø‹†KS—²Ù,ÉdÞ}÷Ýå³ü*UØ;ãþ|,Gf•­¼Ïö=½oàÍà›Ýß”u¶`RT&ö™Ï|¬»§MØ®R»^lËUv-ÝtßÓûÖ­[§žýßÝÏ:öwÿ±Ù¯ÌýîJ6#þFö=½ïG/ýhßÓû\6ͽW®\±AËn5ñúõëeJË·‚pU>µ(sõT­«uÐã,mñßx9gÒ5íòßé˪{¬Bºi÷]‚!áärs!²¦ËÓZX·›ägĈ3øÝrŠŒ¬|…4P‰Ôшo7Íš %QSDÃlj¶xã /ŒR ÆûI‘k•æÊŒ!dš¦Ï‹y#·$?FÇÖÉߌºAŠê#ÔaDH·V+¡¥°ªªÖIõfXëv*žSÚ¶‹áSìÂË->óF[¼ñþⓇ¼çU¹”)f [¤£{‚=½ ¤ˆ*Õ) ‹¥F}œZ˜jhƒÀ #S ³£c¨¸[àslÇÅQ*î{i‰C,þ$YlÕŸaæ­añIÕz#¤/±ùhñ¹8¡ï×1ãv¿øà°Ÿcò¾]9MDà=E£`¬ƒ± çÕÛÆ™1:ZïælšÈ’ÕÕýim«ÕÓ)ÖÏ;Ãl ³m'#2« L17€ìSesÝÁX†*-Þ¢n$S;èqîº|sMµ-uusV+B×qݪ?š{²Ý1²Î9½ÑŸìšÁ­4 î²qóއP3ñŸ‰ÿ”øíoûûßÿþ÷¿ÿ½&%€ „xò©'õàÍŸ¿iûOÖ"`…aíGn«í}•±ç±=/¿ôr½öþrè—ßìþæã}»™Û5,-'h-\¤²!À ¾üÒË’ÂWev7Ëå™ÜN—_zùúõënâzyÙ²²²ÒJ**¹Z¦Á¤ ­ýS¹Ù…[Ûò'°¨yÓ$–4°Jíü3·(pâi:b°íæAÎ)I6ئJ’V>EÔ©~uS2c78\$õ“œ7ží5–v¹õXX•ªY˜t˜y«ç^ði·˜Cm·¼Û!W`Ø0;¤†“ ‘Æèbu³NDJ³tH(Ô°tSCnÊKa'O°@E’‹Š)tõq\ôN[ÈÊ™ §5O°¸ ±‘©ý‹’’Ò¬-¦ê¥ùfÇi ‘;ç5àNt{'ÇèH[û¼ãòvž£z#W•ò ’ïç×»8u†¶Æf¨+èæìV.t2*Ÿ2!_ ³‰;Å£ag ³â%)?Ÿ,¶Š¸ÔÃsghÓ‰´q&CU·wRÄ¢=œÍuœÖYjyÏûA-ù<Ae’U Mí`L‡tÈ{~Žê˜7ª+3Gµ¬°¥yc ‘DÛµÍ0ÛâD!q†¶ùqZGØYÏ´Ñx ްSÈ#eÔ6 –?h–¯çN^ž$µÜ±Ù ݨ1R–årdŒtO7•0ƒªÍ‡ÈÎR#¯—õ&±J¶} b--MÛ&Vœñ]Õ7ÛÏþáJC!Îg–[1r;2o«ºùÉ÷ßÿÙϯüì•´ï¾ûî»ï¾[FªtË]÷¶µôV3¯½ª+¾ê&9÷=½¯ªªjàÍÇû·Éð?üЭ­º_ÓêÅNÜŠ¶n–Á{«->Ë Ó=—¡ærìô®îvùÉYxº×üÃ?´é_÷Éõë×+Ü´²ø®ÎCY)Ô:›Þ¼yóí“o¯²¸ËˆszL„çš ¦0“pº<±z[G4ó†’cßÓnAWZÅim/Pa؉=/ÛôO—‘hßæÔ“0ÙÚ.khÏ%̼9ì„Knj¶0®‰X‚Aßé‚8#ì´1$Þ¼A¥=ee¦¿aEÀaÒº‚~_¯B!Ýɨ´è¤i ÖÌéiêó«™³†ÕÇØ/†N“{8!1Ø©!nîàt¦éóŽŠÍL,P9Ec¡Xñ‚w@:;sTW3§öÍÓì°9Róª™Sh-—«™»ÀV«fÐÆ™v Õ�1z¤«—%t°ø“~ï;¾!È/º“Ñ¡ânÑ‹úˆ[ºÍ ölçÜüÓĤU×ÄÁüc³âÕÌõ2 Ôï÷¾s•¢éŠÓ;A³‚´8W²„tÀºìÍL¤ˆÊI´›uYB²š‘Ág7ëB†ÔG\ȧ՘S³l’²PŠò[Ø"'×�A…ž“Z÷Ãb/"뇞æðli“ZÏe¨Š;Þ¢~);‘cA‹/QÛ.¶‰2m•!qO¬QV#5øÔÿVîÃ?ô<ÏÒ)ÿ¼l” ²ËsxãÆVÝŠ¶fÙX½dkÇòãÛ=a犼⪪ª2vè*ªow6~ñÖ/”¤-‹ùÖ¸GWûÞ=~Mô–FTFkz­ÿ5VºÏ¿üÒËÏ|ö¾ûî³Ò»ËÕóW< MËŽ-NÑ.vê( ý¯›±œÆµ¸¸h…ÜQöÎål¦¿ðcàÙƒÏÞÖ÷µJÜ•2.Ãï5'&k4è”<KÚîïŠ �� �IDAT–ºSlTg2¢ óROã²é÷wö)ÎvŠ=&OkWÙ K+¬*š&Løè£¸Õ$bɬƒ1£ó©@3f›x¶rk1Õ£A1IJ[)6HVÞ^:»(©0ÛJúAE(B±GùÕ Ui"ÊͶ°Eè›á¼t0ÖBVH™&rŒý£tŠ€ª#ïe@}¢ƒJ \aŠDiŒŠYfÛÁâOyÏOSöÒCÅÝ’¨N±ëû›™PÄ á°ü¢«™[ ²øÃ¼3Gu35Ì^`ëÕ[¹PÏ´k'iû÷÷<^®¯øºT~¦h|žc{|Ì-+2ÅHšÈ(xƒCÅÝÖ,¬š¹&&wqjžªwx¸–ˇ9’&"¿4‘sloñÆeÊ&D÷ef‹¯OS߯™*“ÅÖx±Óê×3ÝÍÙ0Û¤Ah³â#ìÜϱ0ó“4MÐ"&=FG†ÈÍ "¥^ÛOLá ×†•Þo!›Äô×7žäbŠh˜y}M)¢/p¢@>Cĸ®æ ‘)F$ee‚È„ÍaXû0åZÃÌ«—Iµ!vë¼RDM±¿!N§…IÏéÎ\‹Ví]ªÆˆ*²wß^«c§ñöÉ·o% zW¡Ï|Æ&TmÐ\†ÄÀ³ž½víÚÞ§öêŸB„2ü~æÀ3Š;û_í׿@ `Ó¾íSˆ’ñÖ/ÄÆ*ÃÎ{8”h½•ؽÄÍmfõÙƒÏþø…¯ÕëׯWÛ¨üÞÁ'ž|Âu(vÚÜõrï7æ[žð°H©åÔ'ôE(Öì{¢ïÚµk?ýÉO—ë?Ø¥CÙBêÀ³î‰zþ­Rµ=K„ôJ 5h§nšX’º #—sH€ ª‰™bÄ6tšŽÏ°ÛM–8§L¬ÙKα'+m6FJiR#úZeåŠ, #ÉE+± +N§5òs•>ûSœëIòSv^®ÄöÃÌ;|(4Z}pùGJ=Ó÷itkCŠ¢” âëª&B»²¦R˘MÑx‚=£t>Ì;“4eŠ‘°—ž¡®žéNF%//vƼÑNF…CsTË„ä5ßÈÕCÝÈÕ4‘iêϱ}‚æQ:å|²™K§Ø5M½U’S¸9Cð&Ylag+ãis¦*öyÇ_ðdŠ‘NF[Ø‚—‹;3„e±9GõejìžfÇ•[¹0AsØKgŠ{ ³Œ& )ÿwÞNÕP§©÷ùÆ^ZrzYBýÄFØik½â‰ñ{”çôM)`¾èES™ŽH}Ð(ÇÒ¸âÈ,¡>âIBŠ,téÛla‹tRD“„BdpX«+Ýaæ)öHšQ÷XcÆÃ®Ëå£á{˜GZ‡ÜOf›ã†=èüÜÚ%‡' í®Á‹›H\Ѭñî§f›¬Ó|ú­Ýß²ìÜå…Ÿªª*MIµµµµµµÿìŸý³ÏþóŸÿüçïþH$™öýCß~xô‡R‡YñÏxFð¹<÷hÇŸÿüç……Å»ör¹‹ µË�~ùð<O´™ÃŠŠŠ_¼õ‹žÞk¢²wßÞoœ( ×î`ØgY¥sì´Þ ÂÎç</Ü´i“ø«eŽžÂNëhæÌòî.ÏÈúÊ}ö³Ÿ]wZ$.1v—Je/½tì%¹®ªHÿHÏ#o¼þ†ýu|¬°”Uæû$ÈAƒKcJk„ÒîÔ—†¤8¶*¨›mÉÂÙ·ªÎ¼E£g;h4²KVšÂZ£ïÚà4‰ûF(ŽÎ{¦ò4‘ÙyzúXP>YYS}Pfa*¤å;ð[¼ñ,!uʆZçbáMáÖË…½ô ü×,¡ÆÅç,WÍLH©z§°Y-íÝœUMÔ0¡3†¶F¦º9kÍ#¯²qŽêfUìlb²—…›}ÅדÅÖ˜7*øiêÃdBdULQm¯‰É:f´OÒ” ø_S1Op+vqj/¯ô“†~”©óÒ³ÔLÒ¤-WÙhó¿Tlz„ÃÝÞÉ£Åç’ÅVõM>È{Û9'žZ.+%+õ¢SìÚÅ)kÝ•$¤¤´¼½¬ún¡X‘&¢th†ª‡yGHf^×Mš´‚É~bú ” NÒÚÈ”"ES}lïæ¤¾ a§B[©óôÊîÛ8¤.f8Ÿ¤UIÑ‘Ì]':OÄÜ“6Õ‘°­é‰ªpèlí¦:<gˆ¤Up]š’Ñê0'J=k/Ë•¥˜$…jánܸq«4Õ¦QXóêñWŸxò‰'ž|âí“oÛì_ÙÆïXdÀ%‚®>©={ðÙg>«âÙ³Ÿýþ¡ï_»vM±uåÒqø‡ÿàð§l• ¼90ðæ@OoÏòëiSÜ+æ¨íÔïÖØlÓÊ}OôÙ ÍU‡v¿Ç²úܾ§÷ýø…+{yO†ª§wàÒe ŸnöS®—»ð•ÆÇna-\³oèånÕ Î6ÜlªC¾-Jñ çÔ~ªL{IÂ×C(6¼Aȼ`Š‚ò·%{W*Ïÿ›èmØ( •´úl,[ Ýqm̲ ª­‰�]½ œ¡-Cäð穜p%J*¥îobOÁË«%G|Ò?°my(àgÛòÒ’KÍв%O6H>Ï< n ±@5§ˆB^h$Ží’»“ÐÏ( Ló%£#2*< z“€>ŽŸ!$?@¯¶ó‚wàÊ‘ž`OÄo‰A6)C|]Ø$¿™KÇ_‹Žt”oŠÖ«0ñhñ¹¯5jÐÜË+9ðFãÅ ]ÃCÞó3ÌÎP'œS M·wrŠÆx±µßûÎ$MÕÌMS¯½Ë¹S¨œ'ø¿ðŸ.°µÏ;Þ_¬{é¼ïÿÜg8Ld€Þ>z›É@ØKwòË÷xPÓçV.H¤0O0é ,„0î+q¢aÒ#æÒ™h¾ #¶WÃl/ôFIY•(ebýŠmI…x1I†³t|ì ß®@[+Vø÷ª—3ÒBÃlË0l¥hC™ïS]ðe1röÎ 3Ÿ!QÒ§4Y™Œé+øU¹{2ƒœxãÄò–Dz¹þØËÇ´=ñä :Ÿxò‰YmÙ.²† r}ô‘fyÍGì5&è,º»OºÍ!×®]S×éåéïápÁXA’úL4zí½¿êþ²lذáà÷r¿äw¼k5à–=ùôþ§­ÀÓwŸù®¸Ø©HñÇ/üø‡GÈú%+-žÊ8P}Oô½úê«OïZ*<÷™ï^»vMM“Oí}ê#>²Õè;N½®Òß©iÙ³cقϽ8z¼Èâ#=P…[¶°‰„O®¯×ÛÚö×ÿ[×£¿ováê?þ÷Ÿ»òÔSO9¡dÎI¢r %0_  ÔUR¢Ñöh5½„gT2³ïl_šª-¥ îZM†„üFL#JÂNXøž6ÇÕîȇV9‘+½›sÖø`\¬¥Àp [„‘²CQV!…rzQRV·o'##ìTͬ™ !V ³CÜŒ±É–èô)eAõ¤PViÌ!nj "‘¼z¦¥C«l§«˜ßÀõíÒ3ÔMÐ,Uú·–Ë—©•ºl=ÓÒa<Ÿ¡­“Ñ«lDJÚÁé*Õ :èýÍoøòÕ²•ž£º‰Éyª.°ÕJÎê¥+¨Ö‘§‰(ÔR@}ŸÒ:A˜žWûŠ4iÅB:ÇvšJçŠm¤mf IJÂ6ÆXY"«>o[]ƒ~Ðo Ý'Š5™š 9ÃyûEˆMf¿GÛ¬©HÑ¿͊9W¼ÅY—l®Áƒ¶º!Ç•~&¥Oµ»·ŸÒ3ºW¡ÇUÕ$Ð×÷„&ʲºfðHµU3-¼ >WœõÖ­['‘q¥ïŸvÚreÍ×­[ç6b>ðÀÚÑûï¿_vËw´bë¡KZÞh'SõÌ<öÇïnÚ´éÁ´{Q‹§ø#eU.·¼üZÙ½»{Ôe¿ï¾ûÊ€S}&·Ú¾β#/Ã6»wwld¦ó<¬8ï¯H¶ÒŽ6mڤè®®ž››Ó%š™™Yñ†¹ï¾û¬ü…½ëׯ—µÈcßyì×ßP³ÇêuSíÑ¥UVV–åÀœe1œNYï¼ÕRC«+½ª»HxiTykð-wuµ:pº·½˜ÖÁ=ýúû_ŠEvýàTåÆ¿ÈOÿ6÷ÿ¦>³*¬&Q=·³“¬:m-Чüô˜bÏù%},*jú¨ÙnüÅr&~m0¨™S#] ãY%õw^’³–”ÑB¶€/æp+|$΋Ò|z”v¶Ò€¶ë¦…-!²¶œ KVŽ‚Æè‘Ñ£ðOVVb°s'#16©MP}úS4úD$3TÈ<Ê7}e¢bdŠÆfžÆØ¤õG3õL ᔳv¾ÃÃ*Ä �$ ÛÉèÕÖQ¤“Që#&PÑ;±ŽêIšÆèx˜wN±k†º˜7úŽ÷W¿áË“4 ð„IçØ~Š]ÊÏQ­=ñõ4‘ š7qE†ØV{ÖšhÖ1³sÇØ¯#—mK#SjýTÚ6H~§O°GÇù¼¥Dè;ÕÓÌ„tf©Ép^<UKÓÕÚóŽÆØ¤2¶A óVuoˆ›"B+«¯B€R÷V+Ñ’c™êcÁ!Êbt¦²Îǹâ72•Ú¥JšA¦«¤Ý|ÖíÑTò¿ËAÍ„©Ë¶ãûT-]>®ÌAUo™Í¦Þø‹¿PO/=ùÔ“Ò¨[]MíÛ{¾ýí=ß¶¨ù©×ú_Ó?#§²j+õœè ¨€wgJ:« Ìd ©tßêË€öÛ¹ƒ°¼»ÖõRÙŸ~ˆ¿zÖTT#[“¶ÿ{žWYY)ËÒÏ:Ã[i|´ÒX·nªb‰—i ßVWîǶuZçú%`¹$mðÃM>E½ñÅÓ¥Æn̨é¦o®Ùîø{WšIÓ}h¦ami×ëJRÍRóZ€.•< TÄH)h°Ú³-Þ¸8´!¿ý`0C•^­ñêæ”TiŒT’‹¶P;R4Ô¨¯5ƒ´p'h®aÖ0l#û9&›åíœ ’—è«R©‚½ h N[%b—äâvÎ1o4M¤–Ë‚qZ[Ï<ÍŽœþ _¾ÊF%u¥·>J§¾ËÔÎQ]É‚¢ºvct(ôÜιÃQ� (µ+·“$-ô*{)‹Ð÷xp;çdÆ9Ec5sã´63ñ'ê™nfâø½˜ÍLÈI[BBò0™¤IåÆ4‘휳<á¼CÅÝ 7¥Ò§+ðSž}7D¶—ÑbÕÉ'Ú–ý·VÛle\b÷ÒYBŒÆ‰ÚP2BZef)æKè@ õ¶Ff^‰ }"ò{¢¤FØÙOe7ë T¼EÂõq_?Ù[Tó•ó3i÷³»þB°&Û‘³\tÇ×ÝMä$$“ë¬ïYGÊ7ö<¶GçàÀààÀàòHEã;ÇŠ²–‚4*++]•vù)¾ûî»eÒíeS˜kÓhïã?;®vLI¼ÖÿZÙ‰.[†g·:ǵWÑV´€^¾—åûúØpóîÇŠ‚º«Wæ\v«–Á`ð«_ýêW¿úÕ‡z衇¬_¿Þ­ ß*¬á:YÞóQ±ÒX=k½üI75â>y¯Ò]‰®²ú¹•Vm¡Æ×Û3D!‡‹Nò'¯+ìTVVmjyëhmJ;íj_ ³-ë;&Ì6‡ª{;$ZOú<  'W\ú™ bCd3~)´Â¸ƒq:}{m"ç ª™á|¦”[Îñb4L™ ؤ©Ví"DUÉKVè‚\ŒTœóèc²‘©)Æù^Ûúho!ÛOL[Д ^ð\¦¶¿ióŽ7RÝW|½Ï;~†ˆ|Q”­ÝÁé#ÞɈú/·sî{vqJ¶Š½”Ž=Ä//±YMœ ÚÕÚø5~õ+¾f=¿sdÊyOº y‚‡9rŠ]y‚ã´62%ÎQ«‘{U_éF®JávŽê~^|[ÿ _V9s;çÞãA Ý G뙼‰*ÜÁØivļ­ßÊ%ñe£;8-;³9ªc¤ê˜©fn#W­Ö„M>g Éž3å[…gòÍ0ómœÉ Ч"LZ%[Kꉒjfbˆ¯+»nH:¾¢P ãÉbÞ ¤‹Â^z„Ü,)3ý¿¹Çòº“•Ñ-0cS¼¤·Õn:¡sÖ«ÇzmR’“L˜MIØ–¥"—+ 7I{»ÑÌžÇöüùÏ^œ·˜å9á{2ŸûžÞ§$°4{z{t`öðñô¿ÞïÆa‹,*“6==m““×®]Ò»ÿ[l«¨¨¸]rŠvýÆëoèÁ‹?}qßÓûæ™ÿ„°ÄÖ+*ÛY„¾cÒßþö·«,ªtaopãæÍ›v_Oí}JÞ«Ë¥ìV< —(k³Üz§WUU©‚ ¬þmÕzÝÄ5ŽìÑŠº·;–Ç—ŸûÜçäzæ:Ù­Ô`h ¶"¸‚iƒƒdö§>è‹Ë6h£IWñ@µç-ÓÇ,ÉKîœLšj«Y¶û#Ʀ8ÃYºŒOõyåx¥ûêO±hñÆSñ;aPÕ Oýä8 GbBÆawUÔsä‡%nž&"у,(ÛB˜„$!™TkÞïæì7cäõAmJÍ$üN'û©ìc®Ï;.ZÐ.ï€(©§ÙÑÅð~މÔ$‚=AòG8|˜# äRDk˜­gú m}Ä„MLª„©üêóŽÒ¼À%6×1#R,¯/±Y Þ­\h w…MS4ŽÒ¹—W k3—¤? þÎ&&AÎR³s›¸’!ŒÑí;Ê7U ­åòÿÁÿú& ˜¨œ¡n–šx±3í¥#¤[O‚Q @~¨ZÌPWÇŒ`[žbmœQíÖ*i1!•¥£x?•-dS†"¤ò'FÖ'ÉÅ$=0˜4Â=³ laK²ØjZ±7 ¥%Ôy[15åÏ`ˆm"ra²0 Hír.3¢ÊÁ®C€jœ=¿š°-ãÿÐ !(ÑÂãG¶Â4g¥Ã]à\‹Î+©x¯>WÄN÷É;Ð^QæÓ²R–ÂΞÞ·œf†w£ðRQQ¡k%G­åGn±öç'~ÞûhïŸù³}Ãõë×ûžè{ùÕ—…"«2-~ñèÚ‡­qê›ÒŸî‰/—Þ-£_ÉÚ}p¯Fmm­½Ö­[·Êš¦¬é†žeŽleÕqm|,î»å;ÐUÀw›rˆ3 §•3áèô8U™ehýß±gß\¶|nwy,•_¥GÍ]Žø{n¢$§W¶ÆÂðRž-‚I¢!߃¼\Rµ0_Šò?Iù,ÕA·™ÄgB†Ù–¡!D:N4@Gˆì)v©›ÅTO³ÎEIu1ü8¯‰?#?Kè-§šj˜RœÔÈ”¦æéqZ»9;16E9·›“a¯-Bú`±³Ï«½Lm+ãóZ”Ô œ¸ÄæÍ\c¸LmósTñõ)kÝËÀ®¿Çƒ’q—±×9¶71)ºÐuÌH‘.FJ¡¡’¥—©Ut;K Ú²§›³*Ö1ó71 låÂ{<¨ldê*Ãdº9«>ÑjæÞäÑ1:z8Å.1‰¬2íi"1//væˆtø$O(®Ó(ÍL42¥âq-—8Wú˜ž¦>h${òlú‰…™ORc,Ïø4yqŒMÉù0ÛähÝ⇪"|¥3V ×qtsvÈ»i]24XÌ0Üâw³Èùü|†v|–lĬê%æ—1n'…’¶F‡²ËD®U‚eÏ›�´'Iß5¯\äý­Á·výÛ]«§˜VŒ ,d.ï XqrÙ+Ú#Û'︾Xv$6â\˰2o«OŽê_ƒI!ÑåË—gggoõ~1¤VEÖXù»víš½Vî—rãÆ ý©WË€¶Œò£XM ¾°°àÆFZ[,,,èk®y£,j]-oËzùÐñ¯"¿Êw±\HYðyÇa÷­n`=ÐóBñÅÅEw%ºÊRé3+Ä‘E¿ud©äÞ µvå¤}Ô,RbÌz8„ óRQi« ™D âŠÔ &ËyjŸŽšö øýa¶YÚ¼ChÌJ.(=#Õl#åWL‹ ªq¼Å4Å.’çÎpÞP”wc3Jú™6ƒªiu‹¶2®~ù›:K}…½6£¨Ù_Ö`y‚âø(S*LRŠRæÌ¡fwsr'#ÍLÔ0‹—ë/>)ƒ(©‡yç[‡¸¹€_¢ˆ’ªåò9¶×1sˆ_Æ‹ýÄvpz'#“4U²p•uÌt2ÚÉh“:Œ:fZ·[PXÜÈÔ¿ãa2ßâmÑ—6si;皘p*5#né¬sToæÒejÖry’¦iêU(½ÀÖ=œè'¦Vq‹tš:q]g]+Œzí Þ6ÎHüV)YÉЇÈqó ?ÉjaË$Mq®Ä‰v2 KÝDJÕjûIBr·ÖuVmRµF«“ ˜äb†ˆ)¥ðuÏë”ß¿5ÙЧŽ�rΔÞ‚@·ðoí?}ÏWß;/+ ‰X¿¥*"¬˜ª}¤ç‘S{j•’Ìò—Žÿì¸PÓ–9Kõ˜ÁKžŸ!H)2!¢L½ôxßã·¢fØ:ßw\¾|ùcßSÊ”¦Oí}j•:ëò!É‚å\§ObÈüòþûï_XXøãÿøÇ?þ1›Íf³Ùwß}W¯l»ìxžÚû”ѵA'ðìÁg%ï°Ü£ô.x•*€ÅK‘¤nåCpg;½±­KÕú½k ¿Né“]ÛM+§köÀ ›×2Q¦QÝ,ö,y©h›/sQRÉWGHÄMFw§?ÑÇB?1çS9gšC,ÃrÌ+Õ–'Ÿ%¤ˆ3Yl5Š£UªŽ cˆl†¼Í¬¶Àf.ÉÄZµÈ,Kh”Î0óIB¢½ Œop†¶ ±0{‡‡Õ.’%$¥7@Q—DïÎÐ&Í:äŠu•“4µMÂ8­j”ü!Òi"ê$©b^O^eãÚÂ^gqU=[ÏÑ0M½§ý¼¨Ã¨gZÉÒ&&g¨ëbx‚æÑVÆ7p}˜® ùvµ\V€8Ec32êÒâ ‘)õÀ43q™Ú6Îüš¯áp/ÍßýþõF®Örù[ϱ]û“ wŠFáîºþ5ÌJAP·Ð+#%ôŠø±~°›‰EG ‘‘ÃQ¾c,Ε,]ŒõS‰cÌ™$3mš2Ù‘ÍLUrµ…-Iݽž…À®‚ïÛf>[ê_ò[¤ ¥ZƒŸG1ù‰ž=rªú·Mr1©<±ÿÁv½ÁpŠ.Û—’-‘ãœgâV5ÎÕ#β)Û–6ËðòVqž;¡Ü–=ÅíŽåVσƒëÿìF�Z%¬Ø�ª¸áþûïWQ- øÃÜ›*\%ܼ{^ë­$n+V³_„SÚPÛí�±RBDÙ7oÞ¼vt®^«¶ô*k†m]‘Ï%´–>»žyöà³×¯_gÝ’µËÇz±­>>¶ÔmßPú»Y«§bM¿c$çH¸=ƒ3¢?6¾ÄÝžNÇêÁë±²IBpqiËì·Ü g+Ç% ž~"3s=$E· )1l[©åeŠ xéysR=²Þb� T ÀbºÑdÝBv‚æ�¡ c§ÙaäfBz)eÈ&Æ `šz5zŠçi»[`§O³#o˜œjáЩ)ÌŠy£CÅÝ-Þ¸éLµÒ`LNê™>Æþsl¥³“Ñ꨼ÀÖÃVU½iê•(:FHÒù'ös¬ƒ1ýÙÉè,5ýÄúˆ¿Ï4ïçØU6¾ÏÒö{Ÿ`uÌLÐÜÊx% i"j‰ÏHPZÍÜáŸW²ÐË@””r¶Z"ìdD¢íÊ߯‰52ågƒ½ñd±"âfMoIgÚ¼ãgh;Äîo°½ ,£gŒŽ>ÎÐ6Ascª' eˆ å"+6µ½nªkÖ0ë¬Ìüm¨€t€`ࢺ3•7Îq=xƒ€ˆÉÉÛ BÞö‰* aô M¶f8L:ÉyÓìö ûœ�“¿írW1Fã\YŠ +øqžúÛSô<RuÙŽÏõë×[í›T¼ñá ›é-‡Òϲç±=Ÿ½ï³¶ö) qh“ƒƒûžÞGõm|ÜÅì<kŸ,y¿Ý!øì}´wàÍ8]T|,YPwáÙfôªŽ_”×»†;}OôýìÕòZæS{Ÿº³[¢²²RçŽsË5ÿTjUÉyyYaÅa/æêx©Õ•û‘k×®©�ñ±QõJu‚Q¢aYKÙ`ÉlË“én…Ì{¡=ÉEh5 ÛA‡XßãÈ”„‡´ÆwPÓ]k—0U<Û$ƒ1ò™’,Ù¢a˜Ã¤3FKH; ã»OSlðÅi%4oX¸aÒAR)¢Cì°€$‰°¯|«ÌÞ°UÄ•}˜:q¢‡8vŒý€7Hr¶©º$ßÈÔivÈód?Ǭ²Ðí¬cæhñ9y8Ï1•"J±â¨neïøÚÚ8s¶sîÛç¨Vー'¾OñËﻯ ¨WRU¼ÊÆNFO³C(r•ÍLT²�â—¢Û´q&L&NL»àýyñiÕ»!½‹S—©•¨ÞnNö2�läª(¸@†ðƒ¼·ƒÓ—جÅeW3§¢¬¬Í™Â[cÞ¨V*  Û83@oŒüë´ÎüÐAö##¤Cdå6:As†ª>è1VÃl„MyR IÑrH2$b¤%·`1C^Åé>ú M<_‡u2ƒZ¢a¶eˆœìK€®Æ à -Œ'9 K"Dæo7L·v#�‰¡e3´›Õa“wYy¼5øÖ#=·t·VSt®rµì³Ë£OWWèúõëîd´nݺ²…v °“ÑŠNÈ«gÊBØ>úè×ßpEP-šÞ͘››“¤åL©&žäÇæi?úè#Ééõ oÛ$�� �IDAT>ÚK`IÚpE€`0˜Ïç?!<Hhfß°aƒ1+€«¨¨pk~+jV\¿~]á ¥G­ˆÐ 1ï-È][¬±6é¶Êذo-áï'7Ö­[g…Ö�œ’Ç3b{ %}…ƒ‹ Á^Ƨ³šL¯­ÓØ€uЩ †Ù–)ÙyZË{ ¬æÌ<e»S‰¶§™78êÒ÷­Ò‚|ìÅ••Bz†„%åŠ/‡Ñ —ÁÓ„ÈÙ’$ÒÂxT ³C%*Ó&Œ |œ+-dGéÜÏ19“LÐÜÈlidB­²ÇÒtÿ+`êe@rê*¿ÉEk¶r¡P¬°²±W!H>Jê(‡æ¨VF””"ÛIˆU$Ðjdª‹á÷yàÞ¯fîAÞ‹’²Þœ­ŒK-h’¦œ¾Lm„´@T`¹@e;‰­\8ÍŽF¦®³á¿TŸ¨6®eA=ÓØZÃìNFÚ8ó_yè£ÿÿá«£tâè¯øZ3òDóý±½ñVÆÈ©úÛÈÔ×øÕ�½­Œ7yÇû‹}Þq‰T1?IS’Ð!Æ­ih=Ó‹?Ÿ½qñö˜¾OS˜#Øjå“‚Ž„F2BwKšyeP¡Ë»TMdé €"Î Ù wÛH4îßN43‘Å'c—Ø�Œªa‰öˆj§{Þ2ÔL5¡Ëð‰}ëÿ‡Pa~,·ÛsQ³Œ×*ßé¾'ú®qm5Ä]Ï C’4}ç±ë\wŸQÒNë.[„vƒ3¸•Ñûî»O ­ÿñV‡77OëökŠÒ¹zä +**Ôºà¾óî+šš¯Õtÿý÷ÛÞ›;†jAãŠq­dö^|åÅù¼ÑÎÚ’¸§é.¹ts®X®¾ã0t\_ÞÓY&Z´:ky>cEA«5§+òž3….ÚŸw΄†ƒ6Íå8 ö, 7ލŠ-”Zþj"`8‡øÊÚ¹¥t‰„$=õæ0Û²t©B™³¨WVyÑdÃ*¤#ÞhÜïxÉûÚî TÄêælƸgˆ‡A+­ ¨©vÌÌȪkJüM³ü7„‚ä“„R~ï&ct†m"» ž•V}Á;ð�‰aºTé¼ÀփşôyÇÓÔ§‰$‚äÕãñ5~u…M6 ÜÈÕíjî\ RA›ŠŽj\¦«•qu:ªB©¾à›•n•ˆOg¾ÌoTÚŒsE5ÝIš°Š¹£ˆ6H~#Wë™V”ù6ßRè|Ží’hX ²ŽE±sTÉ7{'§ Üoø²"×Ëßþš¯É‹¸Ôâ÷[µtxSD[HÉ+MñºRÖ‡¼ç¯29@¯Me7S­<y3j’Qتëßâ¹Q¯ä[Ø’ôU¶ÅÈÃXšH¶$%á‚á,]ÝŒ qS¸èÈIg}»éÁ!nâ7YùÉèŠ3l—}ƒÓa¶e€ºô:,—ê3[ÔL˜„m±œµW((YÛ½ùó7ýö£�÷ÝFœú±2¶Ÿ4v.z>…ý*n[ž„ì}´÷#>r‹[ý¯ö{Ï·?d‰£›EÖmllt£+Kvż{Ír¨¶Ø¦¥Æ•+W\ pçz÷Œ–_a›:Ƚ9ðæ£‡ýé‹?å]Œe¨y7íU«ÖPYYéªR|æ3Ÿ±§¹üÈí9¾òò+5-EvEà¼'VB«g#‹Sti_*wRªwúq¡š,R•B=ðé gË%6„!käcÀ„ .E('‹`Ó]> íâ\8íq~ÂV«ø ØU†s;L±'ä¥#ŒÆ‰†™ag˜lœNùT@¶…-y‚0/ê‡U-Hs%Ì|¬Œ!“„^àˆ(9@ I©§T°êj Âb¤f©ÁË„nΊ€š'˜)FbÞè¤iú”Xü®wq*CXØ Q¡¯ðëJ.±¹–˪Y6r441y "¯ö2°‘«3Ô¥‰Ô0»• êÝ¼ÊÆ/ó›íR-ø _’ßÎ9Øž&(Ùw)ÄFHÿsþË4õí$r4T² }ŸþßüKk碬¬üXš™´l'££t¾ÄÓÿÀ_)v¬gúoù·uÌ(á¬ôlÒçj Æ© “Õ…R 8BºÆ; ÀÌÕBMiÖ«‹FµÏ y«@+¼”Ïv ³Y {VIÑmY£{P dW‰4SBÊm>ÙÍ#Ëb””«~¬‚}7ë¦hL9}ÌÊâÚž¨,@rºÛÅB2«É£Þlö·¦Ò€_I½'¿í7^c-¨Y&££· ÒW¯^]»Ùç=NW uõTá¾§÷ieg꟟øùŠ Û»Dˆå´°Vxl¯°¾ý_WW‡#£*Ë—/+ÚÖy >kjjÖÈ‚Y}<óÝg„ˇU„_%źzõ×fJ\t×Ç¿ð…/444hY399YnÞjiµwßޛܼWßÔò›|¸]œe$ ,ÖA‹à%Ìᅧ%> †4DÉ’Ìçù=jŽ–J…Si=Û7¬yD,Ö�!ã>á:šaÓÅÚ”áqœ·¨ojZóY#àŽ—3Gƒ¦×,¡0é)Yp„™?6B:Ε$íc¢[R„Ô_"$­†ãfÛ!ŽÐ+†­º>ÆI)"ÔÖf¨“Ø^?±0Y Ô© ›'¨Xóü¤xgÔ|!=FÇk<þ¾¼‘«¿æ+—©¥æ2µŒV²p *aŠùÔi/l5sRüQ|,Å¢*æO°g'¢¤Ôâ"’dâ7séÞÿ)Ïô2£A¦Öb´FH‹·tV3×Åp% ô61ùe~ó>è`‚äÊ3­Œ[BS3¿áËò<éeàW|-æÆ‹j=Ê“Wq´‘©¡âó(µa¶)1›%cL˜*~ ORD[tñLå»™³ ¯Àì¶ ç ~X™·%Ʋyæ3 ïZM™2ÅWÔ£@E’\øåýÕ[ûsÍO #äjHÍ h\í æe–z–dn½tº¥‹«PcÊ~ᥠs)=öÇnpÃe•óƒîݰÝok‡Øûî»Os¢=ÎO"Dû䯭ø–.RZ qÑešnÎö6"¡¥í­ ¿ìÒÁ½¼6,ÖÑ®[·î­_¼õÈß<"xvËÒ¯¼üŠl,WÛî€Á«ñ…/|Áý³©©éOúÓï~÷;»M¡ær¡Ä*FÕÊ©Z£¥gƒ?ÇÃÄ>C"ãÇ ƒ¥Ÿ†3¸4~µ,_ÏÅê ¹nfn×à~Y(C;䥯žõoƒ68ô¢ö0ó™b$êç fœx×ï<1=3-Þx”š`Q¨,ìÌp>@G?ûûøn†+š×¥#ñõ€�‰ç¹:ãݬ!ô ~#&˜'(ýØ y96KØ=Ìü~ŽÍP§ùz†ºd±µÅO”r¬¶¦fÿ÷x0OðAÞ;Æ~%`õ¤ºBõq‰øØ&f&$0KÍ,5Íßý=GõN(麃ӛ¹ÌSuˆ£)¢ÓÔ‹·U¦ÎQ-Kj NLÁî×øUýó3ˆüWRp,$«å²Íëxæzs¤Ê,A6sé/øGIÿ�z³KAI±æN‹lœ" +C¾™ê 𣆙¥ë&77ër'Úb¾Ç!nB4Ì|gèÍP¡û-ÈéQ Ð[ "É`˜` [’Teˆvsvˆ¯g iiµ´Kª=Àb’aL/P0w~Æ¿ÃÓG=FÓ�hO’ ©wø9›jóÎ\€ Qê©mí?àG¿ý¨jœËQ³,[{mò«p®‚›¶=‘Oí}Ê¢æÝõë×/¯/®^Z³ ¢·©f6WXrjÕÕÕ÷<×·ú˜}ñ‹_üâ¿Xš™7nÓŸ÷ÜðòØ‹ÇÜ^š2KíUðÒÕXÑÂÅ&ÉÝeÄý÷ßÿÐC_úÒ—ì]TŸÖÒª,(¿cw³O8 ¥¢‹›¤,«8ú çgb iHÄüRÊO»Õ*”ø´ÃÎ^FÛEÅTÿ *gÆØ'—u‰êg3ŸµóN±A®s̃‚Ó#ºG’*I›-J*hjNR]È“:Çv Ʀ<Á$ù>_ËmK|†¨¢ Üfò!:EV#1â5Ì j˜a§õÆw”NñT/°U6[AÒMLJÃOºw§Ø%R®pW%Ìꪙ“ò{ ³•,|_ʼn‰×#¦« ™1âz^a®C›˜<Âá_ó•¿â$³!ÜÈÔ4õà‹’ ’>­pN„¡æ&®�ÿÈ_ôèÊMÚ/ñtóóTýš¯LÒô0ïlàºÙËÔªˆ[ìxI¢5%hïdôû[¼ñQÓ"ã {à'-Þø�Q‘¡6sIͦ"ÊÙ÷ YRáY=0ßÏ« ÚŒµN*Ȧ8á¢ò0ØÂ–$‘£a‚AnK¿¶®iîɈZ—ÖŒ_æÄ´~Ú¢fE¦¤@ÙS0j‘aÒ0¯—Ì62~v7¸“‘ Ò@†¼Oj[)!f#wâX¢ùBe냪 pW>5û*"BÍO§®y[c‹˜2 FTÁâîŠ a}ª ¹­â’»”Qh¸aÃAæ† Êzï!—°NGm‡p rɪHáæ?Õ8ø½ƒe¬7{'»ðlW6Ëaµªªêcïs{5V„üåcÅ7•8«Æ¢+g¥«ñ ØàÇÅåµ–Rmóެ%GáÇGBè’„J ãÃlSIR¦8˜Nv£„„L-\Š¿ÄY\'/©ÑjY?QLž`ˆlž`œh€Å²aæãDUÅT{@|€à�½Ð¾ƒÓi"aæk˜M•‡zQ™’­ñ öŒÑ‘":ÂÎ6ÎĹ2A³²²šñ›˜£CL™#öW�ÅÈV.œ¡-NLiIål»j˜¥f'€Yj¦©?ÍI|…_çh�.°5Hþ ›àýKlž 9N,Oð[ÿ#ÿª’…Z.W3÷þ;¾ñ¾ØË@“9ÈÉOû}˜¡î(ß”¾A3UÌŸc»ÊŸ¸.š’Nö¯ù;©ÎÖ3ÝB²3?å™ÿ“ÿùø+©S4Šc¬ì±žlfBŠíã´>Ì;À u¯ñx²Øº“‘4‘:fâD»9óF›˜ìe@™Û#ÎP¥È2Ãy•0µ 9‰‡ÕÁØ_ÏÑí¡k·'f›Ê™ò˜Kr1À⪒„bl’™‰Ucpñ”}õ}Q´h“†‘„® =zÕŠoØ,K˜t˜ya¡a}7¢A³L̰S÷¿o)™`IÜS6Ü Ó •¹òžw@åXîÎQfÙᦗ2q™2Å™2÷•Oa¸|ÿJc9v~ì6¥¼³°t¬±¤ºÊ(c-mذÁ:dIÖGû•jq¡PПëׯwÓª2K¹qãÆr•œªªªõΰf)šùÁ‘åuÄOú;’>QMMMMML¾>ÿùÏë?ø½ƒ/üè…ÿõ+²ju’D”ì ³ÍúÔûÉØbÞ )p–ŒM¬>Œ#Jƒ]ªL›‡ ø†&©°˜%„ñS„öÆ“~r¸Ç‘ j7êØ¥ÞM‰³[KÃy¶I´(L²AÆS³U¡ ’Ï3Ÿäb€hÀ/ƒù}ôFà&ÒÂøivXÝŸÆÒlKC¼€-L$ zišz±jcl‚´ «™S <YïWVÏ´Š|UÌí$T Líb8Gƒrª§Ù!c/éÁnà: ¸°ŠyE·{8qŽíÛ9WÇŒµÅB_¦v#W種åróÂÚ÷xPÌ à_ó~Ç„iV ,nm;‰í6Þ­dá4;ëúLÒd ºbÃV3WÇL% 6ƒ Ô1SÃìu6\e£è¾¢ËI ~!o9‘§òe­ì±6bFÙ–¤µ…q•¢ã\h˜l=Ó °ØËÀ¢bʼnfˆv32E£Þ¯lm†JK%Ëp>@—Ú(mœW(V„½t¦Tz<¯èБzOäK ÊDØO¶¥ bd|èuÙv¾´¤YžZo‡m¾vrPuuµ€AÄ 5×™nTq—ê·5VL/—ØŠÇó±ùÒåyZTl0ñÑG=Äïþr/”,«þigdå>øààw¿û[qüÇüG¹ÿ»eUɵàYFÙŸŸ_Ñ‹ûc3öÚïÚB_=þêwŸùîãêå†;Ë#NkÖ#ÂŽ¢CÇÚ/—Ô2sfÖÈ[AœÕ·õµÎ™[;ßÒû…¯Žg¡ßÐ’¤5@0Ì6;™Ð³Ý hÂ鼯^D;ôDHë02ÅH–PÊo³£þ“¡êÿgîý££.ïôï×He’tB�™4têHh¦Y ']6éC6Ä=gáì§Á¢Û`µ¦j¥ºVkýÑV‹¿Ô¤UZÒ…³L÷œ5’¢žÇm<³tó…úLv fI2&çùãúÜw>$!"ŠýÞÇã “Éd~|r_÷õ~_ïëòR_IÔdhøé#Œ¬&¡Æ&U G+è–E€R«d\®úgƒ1Ê׳½-»¦){]gWgД½î–ì=mÙ5‹yYC|WÂÔòv³j=Û5©Òâò3‹yxŒ«2¯•úC`Ic—ñÔ < nèNÖHöRºŒ}~RñBmÃä2p ÏøHËö½’�É yér~UGÛÖ½Ìbé*ºnåniw$ì¤àÈgxûôb º‹9´–ƒ “¿‰æµì”xêÅûXVGÛ2ö ¿å1t¯ÑŸÇÈÃ\;HAƒåÄ"Ùš:ϮմoÍ^ÙýEƒÊ)'ÖGÉf¶ “_J¯>£-l–'ƒ yT8í¦"D:H¢™Mù Çñ•Ð'b·•/ûIéÐSI´‰<]uŽ€6Û!µšv˜D:q=cð“2ÞUÎo4ã./š¬3©é¥¾š2{… ’­ðçä†!–ë)©$2IJu) N««§5sæLÁ§ÐåcèÉÍšjþ?øÀƒ¡wèé¯Üþƒ;ï¸óÇ÷üøÇ÷ü“ýy*OT7³Ÿ@ÊÝæ®Â6›l—~ü4«tJ’ã›´l‰xŽYçwÞyç'ê922rÇîØüÝÍúâ®;ïú\vµ”ízôèѹsæÎÊŸuüøñT*eyü-ß»ÅM‹ßyç·§Z¶æ1á“:UšéÙ`œ¸"6ÝöÓÚD ƒlpŠ´gzÒ|KðÖRMYô¤[Ð!ݪ'4 "fDÿaW“ã“ ‘mnü¤é7{gÐ%Ehð2ZIg5!b Ïh&›+h¬cnŒDœㄽnbJÐ÷ê#¤¼fL¾–=ÝÎ×RËž&òª‰ªn¹—Jy¬&¡vfu·ò|3εˆfȃØ<YàyB¤*’­iÈþ~¡ºb9±»)ª#®FæZv¦ñIz#™O3›žàJ)€&>*„ I•Iž!ß¡4¾bIš;ĬJ¢… ä0–$ÐAXÄn=ËØ÷4—^Â3G˜¿“µ?á»#äHæ1²‚½ 8œ$PË“¿æf Ž¶,YÊþÕQY¬egœè©\mÛ¨¬#ºŒ}ó8ú$WhJ¨§µƒ° {Û¨4l4©·òe¹ÏoåË!3ÁYJï RÖo¶Ž¹±ñ‘MB¤eZëÅßDž¦•¬å“)¢!@–8Ôyvµ±†l  ð$õé+,E“f¤¤E?Îð¸MœböõŽs–‘ˆg\öjÊ"M[´5NCÜ|›Àã“ÐjN“g¾¬ÈÖ½_¸i¥ guÈäŒIçûjŽ>$j­¿nUY¤õ×­¢t×_wýYåšnìœòm·Wý_ ÎcÇŽ¹úzhhÈÝþÌËË›|ø8«kqìö:þh—Å`7¼sÎ9===7\ðïÛÿ}æÌ™5>Íí{œ~ÖÙ+Õž±!àYV»îŸë¯z}`pdèÍ/Ì>výõ—¹\ñLì‰g2+Å©ÇÚDÃ;Mu+ì2’í°‘¿'|†§Ê ›`¼wҲɺ›*rªŒirÃt¤Ò¦ðÕ w•àª=&æ‚Õ´K^«±½Ò:#»Ç™w¼ÆFžs²3 ëÙ¾•/+õZúÛ|†E=Ÿž‡d€ÐKéOøn;«w±ÆîÔ·zîÔå9na³µ¢ÝÎú'¸xž•J캋Û2xGÈ{™ÅªÁZtT9WFB„%’7ŸáJ¢Ílª§uŒœ4¾¯ñë_óµeìÛÁºb…ˆ+ïz{Óø$•D}·G˜ÿWKà£\C)%ô]ÊÓûXÖOÑj¯æ±4¾Ý¬ZËÎ óÙÇ2M‘ Såâë·†û°ÑóÄÖì• ôî£D ^Æ¿Ê6ÒÖÌ&½½*·*ÓK}Љu«×¸­>Y3‘™¶víÂÝ<«PsI;™¯¶<ëú›pŽk•D#Ô¸âfí)-5)~ lDãþI¢\¿É‹µ£Ÿa÷C¹Ÿ­¹ÀZ³Ùo¸d#�W]õMûwî®ÄNÈ:N§Ó¤ *nàœò�>!×pš{NiÄ:Y¬äN•òeÂþ~âÄ )~ݿіø¦ÜÔÜÏç½÷Þ›Òb"3pghØqΜ9ßnü¶ŸpôèQ•@mЕôT*!ÞO2:å»ê~8íŒÙH÷Ô}|>Ÿû}H§Ó*á 8­ fJÖî.–Ú¢¨\ï•‹9cÆ ½ðÇ«|*ˆR½ú[×~kš~ún±S~|îkÃçóÍ™3ç†ëoø÷íÿ®GÖQæ›W}Ó]BŸR4¹Ä=Ნ%6¥JkúKè±Ç²Y6ü`[Þ¬9©¾W“ÿ_tr§ß¦@xñg²N°‰ÙPD@]¼ÓÓ@×0IC‚Qœyðñƒ³r+]¥à– ¸h~㥪¤w<¡"lC€½ã)Ê”R“*æä,â8åJßÄ“Œdx’ò‹/`ÇÝ[^/ûP³‘ÑD�ÒK}%eØDójã¼Øe,âøª‰¦ðog}5Qõa c…1!O¬–=*Ø 6¶°Y_˜îÎ~_EÂ=ÔVÑ$Ñâ|†Wò|>Ãϳr%ÏwQ5HÁ¶a¾zù ÷°¨—RùÔ²ç%.¼—à†5ìZÁÞcÌ•GNEôË¡‚îòîãÆj"qB²Ô8æ"zrËa,JåZvöRºŸ¥óQ*b¥€Á§¸¬Ž¶(•qBø5ì’®XŒùÅ—ñT?Eó8ê#]Ì!µ<%VJo©ç‰­Ù+{)­ötnï÷ê.nÛÁ:ű 5÷P»švÃGÑgçuäÓJ…sÒ)cOi^§¦ê°z)uŤ„sã¶žë-¥IÐI,hqãÂR½yñCÚüäÚácÓ­ìð:óÇõrƒÆ0Yð Ö_¹˜UMQp^xÊk÷²¿§Òþ¼oño²ä;ã~’À7¾ñó–ŸŸfÎåûök§ÜÍ݈%pš3gÎÞνÀН­ÐÂÉ}µ[¾wËÇP¨´: ÉóÆoA-*25‚b Ånàœ¾¥'¬ÒøÇ_þò— ßµJœo_÷í30˜òp6e¤ëëDY^ýu}W¯N#1 MÕˆ¿a¥ä”=NÔìÃ=IH:éÙÀÉž>ã©„d&}3yR!×AÓ°yäå¦cvU€Çmlã”»³œŒ‹JX»¡ê·êkÖ1‚ÒOB‹èÙ€,Ýë<»ð$õ_[vÍølL6á °•+EF½ø%¹j¶QYE×FžGYÆ>Ý^MBC™·Ò_NLlL’Z?©M4Ëa¼˜C¥ôI RÐI”´âšåÄâøÖ²s;ªèª »Jõ>«=ñly%ØVAw9±Ëxª”^!Ÿt°Ø&¹PŸ@¨Å„U ¼—›€'¹â>n<Dqc½”Ê©`-;—±/@r=Ù¢x˜üå0&ëŸUì.¥7@²‹ª<Fôœ«‰ 1ëewS±m³ZDO]UtIj¤'3Hr³£TªÈÜKé¥<.ÀǸzˆYšmí£dCáŒ÷E²5¥ôn`›·qWŒòí¬×wíèg†”~i _„"W­€h#ÏF8XGÔÊm*‰VõR/ɴʧFÑŠ—Q/~[À0ä/`Õàq^4½Ié`nH3´¹¦é3"Û{]ÉnݸcÍ‘ô:áb æ&ì¶Ã:\NÞ[Ï=÷ܦŸ6}çÆïœ{î¹rHoúi“MTƒçÜsÏÕÙüñŸ=~Žke]˶EÝ7NÖÇ~T[Ìý÷Ýß–ûnÜ|ãUß¼Êþç†öGytجÿ0^\s=§Úfn‘ê„–›nü„Yî{bt¤^ר”ÕUsQ 2Mæó‡Y_øÂÊÊÊÊÊÊfÏží¶Y˜P²vwIß·û±µE'/÷;9á“:¡<a–»-­V}QQQnnnnnî©DàSô8ã¼HVòK1“.ZwTLÔÒÇ–i£}m1Öbã¶)Æi¨õd xÇðÝzÕ†X7$klǧ»ªaí¬6Æi©8>G£‘-÷z¤NKÉâp{F­mAÛ!†3„îsí†a5,UËͲ£# ‚JÈðuí¡j‚®aËÝ|ßÏ.yÙè÷Ö²§ˆþ[¸ºš¨cúêi)äÀFžmä»´)9¤‘¶"ú×y.[›­‚ÞÁí·sG ÿjg1t!/©+)»ƒeì[DÏ›Ìé§H_zVEô×Ñä1ÒIÍ–�G™WM¤‡E_ä÷²Ò$IU}© [ÕúdÝž6oÅ1æs¨› IpKé p„¼Bö²"LÇ9ÛØ°mR0ÉNV6{tïeE rÚÀ¶úór7‡(VÝØ&¬Ýê¹3ž[¸àVÉ ·u U$÷S–ÂoBRËtøO^7ª­3…¢ÿÚXSMg„ƒdu1ã2^n5å÷z\³!gÚÒê^TÍ:#Nˆz:îjÚýû�� �IDATˆ€Æ«Ô™?6蛄C[ºz눶ёq"?-auWq™2#å¡xðІ$ìœÒ=à#ñrcç” ”) wök}÷þûîÿöuß~÷ÝwGu×ЮùÖ5¶<ŠõUϧ§³Î81ôÓŸþ´¥¡ûþ°3gÎTÉÎ=ÿ'Ôœ<Aè^üÖ?òh¶É¢¸¬íÝ oš²¶*ùï¼óŽHžÔ[‚Éüüü ‚X]Wß¼ú›oóöÙ¶pr·päž¾Úöÿ"ÆéeÔ™ÑtbÅÆeAbœ^ê]Á™…lƒÅÑ8>/£b™q|–kŠiÇ×ÄD5EÞaTµ¹Æ¾Ü˨QÛ&íÏÆÇæÿ¹ö÷J†“Éæêù‹‰ê1+‰šyÓÀFfdhí¥4΋fºŽ<«nYˆ´·/`Pz‰fu‹ ÝÌÑ C‡ˆ · ¢Ü’½GV Ãä§ðWSÖ˜}¤—Ò:¢¥ô.c_%â|o2'ä‰Å(Q¾™- çÚCmŒò'¹âe2PE×NÖîcYoUÝTôS´mAà|ƒŸ/à°è¯h¥î<£Ïqq_ý1ÊWò¼üüT;½ˆFÈ&_'#äõR:Hå‘… T馢“š墰sx³—Ò5ì!OöP ÈD"Fù³nàݬê£dŒœUì¤`ˆYƒDªÇ9Ĭݬ ±¼“¡f•Œÿt=øImg}ˆå~R!ÒR)GeMÊñø xñ«xÇ¥2…¿ÕŒRi2ò¨&᥾Zú©lƒ†,+‰ê"Ñ• è¥^E[ƒ‰p0ÂA¯ $W¡%1n™2bÚ°½†Õé0W‹.Èr´³ZGÉ8å.ý]ÇÉvÐSY?ðà“ÉÜ-™G›Æ|à­S ;~ ööÓ‡~j}‚ÜKÙüx³»ç4aâS§þÉO@4ZäFJËœœœ)Yµû§¾wË÷Äk’É䲿_vªg.1ç¿izæ§*ÌŠ¹§c§$Lóšè=¹eëð°NŸê5ý´éªo^5sæL–Ι3笊’˜Jc|*m‡t§ÀOL*Õ¦D"M±Á¤Èœm@:¨ ÕžNʼnˆAÊ-ÅŒ²ù\)ƒîÜiLžIʵM´nЉ ¶éÄ£š¼ŒâWgȸåIýñ¢L^âøD,âÙ€×3÷ÎNdHI´Õ)‹E•›QGT —!Òå´›çÌjÚó^î»ùz#mÃäËÑ­Údsªð(ÚTËUªƒ˜Â/ã%šs¨œ˜t¤5tŠ´­`ï öîdm#M_ãוD+èžÅP€d'5õ´†é�^fñb^ÖÌe KÙÿ —�õ´¾Ìb™ÐH¶Q'Ÿaò×±ãóå¥7JnœÐ!Š/á™g¸dû’ŠèŸÏ;‘©ªï\ŽÅ ]ÌsXr)O?ÎUa:òé¥t€Â*º.áàMæ,àð½Üt÷¾Ä…… „ˆ' ¬g»&gº©(`СöQ²–›Ù’Â_A·œvÐVÉ£UtùI©Ç)–,Yµm¬ñ2ºšvaájÚãTê”c³PLƒ@²ê 9ÀÙvCKsÛñ§Hª¡™¢íqˆX¸ÚB ãtÙ…|I[œ±ÜO"2. B‡±«¨8¹Zpßû´jü)2gµBþŒ#/ÊìU{ûn/ˆ î¿ïþ›ÿífK‰D;¥Ãä“)±óÝwßu»�NÀÎs]sõ5>æ xÝWë¤ r»¥»•Vîvš;üdiÌŒ·4Ô}ûßÐ1NœR O î0ÙÝÞÝ@ýHXµPsÊöê4“TºqšƒÅ„RÇ4²²³Â8Íx@XZ§pd½Æu=&b̃Z†ÆWLZ¡ŽA±ÍÖ0jØn}¿Ú<G“uÌÕn¨ÁJã{ÐmŸ~<AÐÒÓ”¢žª©åÈÁj2dHá—?_Ì8¶Èå\¼$ޝ5MäÅ(¯#ÚGÉVNläÙjÊJé-'¦ÄÍ:¢t«¬ZI´‰º ºSøoÉÞ£|Írb»X#¨hñü«8e /¥rçéa‘Ìÿ„dÂÈ$Vê;Ñ”yõä1"Ÿ º»¨&_ÖqBß㇥ô*‰3Bõ�…Wðäk\Ëh€d>ÃûYªè±},ó‘~“9+y¾4>ýÞÙ—Òǹª„¾$},»”§õ|žá’¬K8ÎìRz÷P{!/¥ñI4ò]A¬>y­¡³Õ½”na³FKéu�;hò|KmÔ.ª ´IœR&IèªcW¥‘\­g»jôµ½ˆ´ !¢¤•DjD6p«çNk"ÅOjÂ¥!h®Ï$$P6 ¬y¨°¢¦CÙ!¿!²n-nCÆq{¯W^ÐÉVaýiÈ<H5¶µ_MÂTsÕd=„ïßöý›ÿíæ ßý÷Ýß°©a2j~ êv ²¼MdètŸ¶ç:±¾uÍ£<:%õ|Ÿê´‡ §'>ðà÷nýpüøñƒ<xøñ=?îïïµý¹3¶þ9Í•k–›qžsÎ9îNÛ9çœãq-[§}gª¥ÏhB‹ZmÔÓ·júÑôQe¸?‹i*´S ²>Ì/}ðÏ,õz2~óÍ7§2žjŽÓ™ËT&®¼0WËÓ1s»�8åf¬³ÁÕòIÙYL£BÔ£IÖ˜2Gõ¤kΤ¡—šãð×°‰FŒSì$c¶QA~Âc=»[!¥2„R!–—kw˜ †­:³€Q*ÍlC‹—ú¶oå„—zhUBˆ~J¾B¦NˆŸ”t­›Ù²šöã’m"t’$uYÁ^…tK8ÐÃ"Q4ÉS•ÿ,Cö(l£NN:Ïqñ,†ä´ˆž~оÈïÏËWtçY å1²„Ç™ÃØk\ÐM…î©)OñÝ+xò).ÓJ‹òÑk_ÌËEôW9Âüq@„“úy!/í¡6ŸaõD}¤®¢Qݳ‚îÆ^fq%›h.¢?¯„¾8¡]¬‘ã|v²Öxå,á`5)½iåÄîæëÒ9Û"p„ƒuÌm'¾.ÒêwšB}JŸ‹¡›•™lžäÝÆ™: Ì%£•Ö/iÇKLü@«™¶ÄpMMX9˜‰:P2ZÒÆ§Û$›Ê©K=>®0o±ª7õY£L†]+aøôä¿ËÁÁAµ¸¾Û÷ï¼ëÎF& æwnüÎ0ÓQóêk®æþæKØiƒE-ñ'³=<Q„t:}úÓgcÙ~Ûé éä’rAAÀÃý*Þ{ï=½ iï¼óÎY}içœsŽ úúúÎ=÷Ü¿þõ¯"ÐV“åv3žp^„Øl²s¯]§² š9sæô¨9ÍüÏi¢¦¾x¸éák¯=ÛÆ”a£­w'¥4ŒÇЇ…u¯ŸŽ“ÅZŒ¼Þù–ö#U¨ŒŽ¿Á”v­Ô¨Å½¹à€bZ1,Æ¥¯¡šÎ(•ó#&¤GëŸÍm3o°™-²…ÃÁëvÅÕÒ'éînbf캨ª&…Ìè¯==JåjÚ…dô”:Æyïèh¥ÞëmËæ Eú(QCQœ*ºº©…Þ Oq™¦JT -¢7«ÔƒìaQ€äyËØ§\ÌC+°óžÉàõ‘þ— ¨šhl¤i)û3x%,Êc¤Ÿ¢|†oájÍ•Ê�¡„¾™¼}9¿z…Ï €$çsdCcä,áÀ–Ìãè>–¢xˆY ´´Ð h|’+êhó’y‰ õø¥ô^ÌsmÔ•Ð7L~€ä9G™'6YD¿IŠ*ÛÀ6Å_cÒfº©Riµ"ôšà,'&q™Ÿ”äB®¦¬ƒ®Ö”=lÙÓ›ÁÈzqJ·i{ÝP¡µš²H6�d<úëæhµoÂÈQs/7K%eBž˜[ŸÞµ«ÁËhα/é2î°¡ÖŽ†Î‚hÆÐÓ)ƒ¬GFFN¥ˆy¸éa«ú0\sz1yÇ<Í-ÞM#þõÿú7Áì¼¼¼ïÝú½ÞýC¡”»â'®é†=÷ë²Ø¦RíÝÊiI=}üž²oçUMaMH"ûhpåŸÖÚ‹VÏ\ ázÿ'|ºN¾wë÷¦t·w_üöÒe©_d/­Sµ–?àìȘþâIƒáNy¶ÅDR‡Ý±—®{&]‡7¹4EÝ–“5„ÂTÙ{º \‰q»óŽ@µÀ˜ w¤8O ä‰ùI¥ðÇý4÷nZªåS! ‚Õ¤"´&¨_M{3›t£,ÄŸd[#6$±•^‚&PÅWBŸ$?â1ÙÉ·sÇ66$ D©\Ïö. Ý{RøïÎ~_Z›x ‹ªbÅ(/¡/ŸáY 1«‹ª­œØÈŒEôHàs ϼɜ$y:k°¤™M«ØÝDc !âÂÑ*ºnâÞQrw°î žH¯äyé¹{š=/qá!Šçs$—Ñ1räÛ>Ÿ#=,Zƾ…¼ÚÎê‹yî*¿•»¥¿]Ê~i¶°y;ö³ô2žÒÄËÖ•ëa‘†RÚ¨“«‘!T­•­t?E:�·pA{5»É=»Jém¢N„¯œ¹‹èÙʉ:b1Ê7°m7«"Ôx…Ü&¾ÕÈw[h}€$m­¦,Åò¸“f¢øWÓÞæºnÕfÖÒ r׋˜F¾±GpØžZ¤“úë’×úlÄ&´¨ÉšÀ¹Z"€SÃè0æÌÄi9Cœ“…î¿‹c•e;ý)Uµ¶½t×w¹·ìñóõLç¼o·ªˆÂ”€ç¦A¶ ;aTœÙtŠ…LÛÝÌ9MÒfŸð™ÅfY¤w£àîøýúßnþ·jg6hãÖ˜;w®;ÌPëMÖs{çwôA¸_iNNŽ8ßG8tª%9ë›o¼ïg÷Mî>ºË­† [åÑÏûÙ©È¥jég¶ìÅ|úþ^—ÞêÓÔôžò¬1>øè1iüimSÓª~2Ù\ù$H@dMv*)‹RtÆKÆwk¤âe4CØ`jÐFUË^VgrõŒ¸Ü¢Ô{©””ß±‰7Ó&^üå´{šåÊiªcn;•BG? õ¨ª!EBÝ/ùÄ(×ïê¢JÊ‘(•²ªIP¿‰æn*Jè«s9É« »›ŠÛ¹c7«ÔѬ$ºˆÍ´Ìb¨‚î„<±°AÍB†˜5‹¡B(¬&ÒD]ˆå½¤Š9$›…ícPÀ Èè<޶R¿ŠÝ»Yu÷fâÃnåî­l<Ê<Uk_ã‚j" >Í¥‹y9I`6Ç ¸ˆ窫x<ÏGú^;7ÞdÎ [Ùx1Ïýž/^Íc³9.£‡˜ÕHÓs\\Àà!гÀOj6Ç¿ÇÿÄç$5ß)@ù1ævQ%פeì¿ì¦¢†Îò62c/+–±Oµk%¯5ÒÜME3`ð®öâO-'v W×­¦³‚æ>v=Fy5‰¾ßH›2g*èn"¯‘‘=Ô&ªZÂ_?6Š@ÁѺÛ¨d¼ÐÚwX¦sP‹R3—âc|T)l†UÂðRyrjÞ8ȹl­#—»PØ5Ó,‹c˜5yNš/¾1™qÚ¯¯m¼ö-Þ.žª*%@}¸éá†M Ä ÅÀoÖò{Âþ¥ÒŸ6JÐd ÖãL)ôxë­·´÷}ïûò6™‰>>øÐƒC“iÙ—º‰Ž¾8•ŒåŒ¨S ô»´ãO€„i$6êaŸ=áÌ©–z¨ní®}Ï5m¥ºÏsöêú0öxtM“#;=pºó¬8W‡2|Réɸ y=ÎêˆÊ°;J}†Ö¸©zí~NaÍ*;Li×q¶“Û™ºDÑq/!çW»ÆàÆuŒFôK›™i Ó&©pí+4©Š/bâ_jèßÂf=úM§-C«²9+‰“¥2BðV~¹…Í^ðU<µt7vp°†ÎmlÐ>¾…Íu9¹/cŸôNÖ*>,F¹ìà›øÉ¼ö—]ÈKÇ™­1•0/³¸’h„êJc YA÷K\¸”ýë|ž•ªšúH+Û$D\fë²t?Îì¹{šKij£îRžÎg8ƒ÷w|Iñ)€<ö �ò9ʼ ‹èW–õ>–å3<FN }£äþ7ÿ¨.&fÔO*‘$ݬ’â·€Á©[A÷6?̵z½j¸V{:IeHí¡V]L魤؊pp#ÏnåÊj:•ݽmÛØð#»ƒÛ!ZäØÞjU ;Í©‡zœ´“”„/ši+Môú3ŽQ”zçbвñklÃ2c,~LÞ±xLŒõÜ)fšÙÑ“kÐ9N rwºÒ“[Üò¾ÛÓ7r¦GMË!¦dœ–üÏìº+–¶zvªwJÛ¶dM¹ºU0S*brrr‚Á ð•Ú¯�³gÏ–·€µ°9%âyóæÙ‚Á;ï¼£6¡~£p"N먡5=Ãv×!gÏž­OÍÝü0æ“é&§ðós/{DГÖ¤Ðd,“ÉÏÏׄ’H§®5®»þº§|9n @[§ù€ÀéLŽç?KÐozHÖë iX2%‹Ùø0Ú8f€°Õ•µBCf|÷|6Lµv绂V=‘±ýK: £šÎ”³¿8¡±¸çEãsäˆA‚Æ;^¶€À8B‹â‹õ×3£‹Dœ†-ŒV•9À0ùâÂòºTTÍ6ŽO˜ YÚ–•¡°‘' 7F¹Œ³èõnô<Ñ %ôY‡¼Y Å(4æ3¼“µ ª|ŠËVòüe<uœÙ‰ê£Dà!¸-¢_é›#äeð& 2PJï|Ža¾=·põÓ!/I`)ûßdÎ,†ú(©&2@¡¸ì2öÉß@”#äí`Ý"zdò'”LjTµo33@2iæzãj9<¨Œ<F Ö¬rdä[Ì!ÑëÆþ‹ÚÇ25†û(‰gËk=í¡VöLÍlRZŸõl¯e¤’j:5f£d›Õ´«ä"fíõ#„z¡¦,)âÙr¯g4â\-ÊöñRoÊN¯¡š²(@XnÕ$"'Y%‡U›…ht<2¯…ñ&}kÆ ¬M'ºTo-ÊÐV³ nLÛYÇ‹öÄ™!ìøYf24Ôyvµ)†,ËdÆ9<<ÜÒÜ4ljx¸ùáË¿~ùC§J#j^Ûx-†öXõ±Ñ‹Ë¿~ù#¿|äò¯_ÎE;Íë¤êÊõã‚– è|¡ó5^{ßû[�v2&4>§,ª =€P€g“R´SÿMvNµ¦œù¨VKsËW^ñäON(Ò 2z7s l›žh~T|Ô­¿úš«í$ô4¼óœ)覃-®à°WÔ‘¼jý®‰ï<¶1Ù`ûC6ûוµÒà¥Þ„c+;bÔÞÓ¢lˆ´v«WSfÈ¢“'lB,·!Ø^Ï(Ù@QM°87R߯±àx„“B³_ÔÐa†VTCÄLZ²O"O¯×^J·òe=¥[R$QN¬‘¶ÍlQ굚£ƒh¸b;ë…š·zîÜ鹬—ÒRz`é'5Lþ!ŠSøå;L¾x[>Ã<ÏÊãÌ!ïnW—1LGƒŠw#§‡E 8,«zMã;Âü^J/çWîåk{¨}™Å’ÏpÉ•ßD©,`p6Ç¿Âo5iê%ó<+_á³³9žÇÈ:vHÊcïbžSÙLÞ>Ì‚Ù߯†RzßdN]ÕDú)’(‡±!fE©\DO1‡z)-¡¯—Ò<Fv±FêÙFš¶±a=Ûg1Ô–]ãõŒj.e%ÏkøDd3íjÛYÂßDŸÔjÚƒ$4Ü’!• 8HA#m)üuÌU€¹~V6Åb™Nâº'I¶Á¢¦‚¬å׈3 ‚±ø ˜’F«‰¼FZ“[Å~AK¥ãíN4õؤäfúCˆP§Üø¶w¸ú—a“²×â”mL‚B[v „'©‚Æ·ž†M §_w=u™¸7 ;€o§ÜùÌV¦?å,Ä„_¡,-¯×Û°©áW¿üÕô©mÊÛ½ó…Îÿ³ÿÿL¨ Oéöðá- ¦ç£yyyÞ@›®2ëç§1ͱ|êSŸúÔ§>ä÷î»ï¾û &|vÓœ™N3ÀõŒQxò‰'¯¸òŠŸ>ôSÑM}á§¿­í¢õ£p?¥i´uçL]ª5@hèæ¨!šV ØêêÊ8FBfˆÍqfWÔ¥«ÄŠ©Íʾ£š2éþÎV"­q· ag„ƒ‘lM&›K6`}a¬p#álj-*÷zFÛ²kÌö””g„5!x+wI@CU‚2v‰ã³µÙ:¢UtÅñ­¦]†v&s#7F¹fNœmŽÊ>JîæëÚÐe´‚½ÊêÊds7zž«{2O|–¤`%ÏKp»‰f©iBÄ›¨ ÓQAwuG™·™-… ¤ð' ä3,ßÚñ|†3{ˆY€â6eô£péßóÅBnã.¹Â~ž?^ίÎãßò•Zöä3|€%G˜'4“·3x{)í ü—Å P({<,z)!ï+ü6Ià%.l¢QZ=áj"9Œ}…ßjš%Hb 4´º‡Ú:eä'õ2‹«’ÏðÝÙïW{:7Ñ,õlu~R ‚|w»Û¨lcÍjÚkÙ“¡5΋^üW]¢h©šu‹òÑ ØÆçÏÀ3ÇgÚœ ÚÓéõŒºãwÌ  ±ÜåÔÑb&ƒ;··mp¥Æb Ž<;è|«Ôk3Ó,áO®©²äÚ¿Æ:?­ÁNd“’ˆÌߤ̖æѸÓYvßÏs­¿ËÜ}×Ýwßu÷éä=Mƒ“ŸªLSý~¿ßï/1«°°°°°P¨ð¡<Œ¿ýÓ¦Ÿv¾ÐyÆýQ»¦|'íw­+Ч>õ)‹[²:úä'?)¨+(((((ÐדE­g\p³ó)×”Ž?5Ýs¥SÞÓ~×ý€ÖñÕ¾-ﺖ½çW^™9±ù3gàÔñ!K&§i½«'&öyšÀiSM.×±VS¼ÿ‹pÇŒµ^«²š*‰ÚﺎÞIÙj+Ê ·H‰#Ç>ëgf:R-“„KáË­v8Cn„`%Ñ'F–i…]Ë)­ÍÌ™Ä(—ç-ãã}T“P³ð[.B6ýª‘6QR!“Qÿú6ò¬ðR(› XCg#ß&ÿ–ì=ž‡”RÀ ŸÔ,†¶± pkʉyÉôQÈŽ®ˆþf6ÝÊ/ÆÖ±£Ÿ¢Njö²"…ÿÅEô5t¾ÀEÕD¢TV˱ ÷³tË–p Ÿá|†}¤s󓺊LJ˜5L~%äó‹è9À’>JÑ3Jnˆøs\œ$POk }—ðÌWùÍjÚ_á³ 8<@á–Ñ¿€Ã¿å+‡(þ¿Ž2ONF·qW‹Ž2ï5.ˆR9‹¡ l“ ÐÕ<VËž<FäÕPB_ýåÄÂt4e¯“S7Utm¢¹€ÁæÚ:¢=,Úȳ<ÔÎê=Ô†XbùjÚ7ò¬AG*‰Ê´=H¢‰ëDøš¨“lÛZYéâ ±ÜÉ'ð´âØaÆœ4m™†Ž8åæ×p²Ç®p»L}E÷ ×xÅ›”»ì![ %AÐÞnMøF¥q^TÔxŒ$ñ$­VÀyÎ'/!‡úpr•;KÑö§r0°ß}àþ€¾sÆŸlúê†ïÜp¾Õ«ÐûöûxïOîûë_ÿú׿þõÕW_}õÕWS©”›:Oà|6­Z.í>nçSQ½³·Äésssí¹¹¹h6ƾ?÷m¹ïìqMK7¯¸ò ëñãÇuì»á;7̘1Coò„P7îZTžŒÙ“iú4w8ƒ%Ô<´OÉ8A;lySú…©d aw¦˜ÁQgÄ3J¥QØv“ŸÝ•L“3�nL‚ZM” ¹ViÎìÊuª7Þ¤£îž« WLÔOªš2)>¼Æü¯JkD8$QJïNÖjAwˆó¢ €€&òÖ³} »Ê‰•Ò«YÅTi:Å‹¿€AUz7ò¬Ò7÷P›ÇH7ÛY_À L€CWÑ5Ä,AÛF£ômÜ¥ô®.ª2x«‰uÖ°«Š.éǸºåÏpÉb^^ȫϳr)ûÅ•³ ˆþaò÷²bŒ¥lÖÑ6“·óùó öÚt°\F(,d`„<yÁ08Lþs\üyþø†Ì(,ð+.¿„gãêFšFÈë ¼˜—ÿ“ö‘ÞDz¬\ÌËâ©EôocÃ,†„÷ÛØpˆb‰‰4¾)“÷&êT —Oa>ÃÅj"¯’¨`2Ž¯Õƒ”“’Öï´  Ç<c-;Žs‘l ÙÀz¶Ç³å¢›¦;˜¤+7—:A!b÷Ÿ",k\]9š›2—\‹b 4 "¦ª¬ñ0Òœtca.ÅQ—«; §ìÑáÜ-û¶N[ÍÓ3Ë}£õn š={öŒ3rrrôÝ É*ö¯S•øÄ}Ÿɲæ®bœ ,X°`AÈ,ýsΜ9r4=ƒõ“{¼ñÆo¼ñF,‹Åbg!rÌr›M0�²j½ÿBßwß}W_è­>qâ„›«éC±P-“££GºE[gcf"Ê4¸®¥[ž|âI~õË_f⌗u9v;1Mɤ-<ë>zo'�ðé3N¬¨öuÐ&C®½Åý$C¤íÔf5®é·°•cؤhu(…g•D­Q{5 “ÜT¯ï ¿ó¸'òļžÑj:m&¢yJ­.:ëQY½«¾g¢£¼Ü{“<м¦,¹õ8Õ”­g»&;|†Q£¼‹ªõl·EÂ:#• &qì ’Uѵ 5tn¢Y®@)üB‹.ª¤ÓQçr7«b”Px·uNP›së†É—^më4�� �IDATÓžÔ7¢¼ËØ7HA#í¬¾„gzXtˆâFšÆÈQjXms96Bž\Ú¨+d`‚Ÿó ¡¬ŸÔLÞ.dà^[Ê~Å­¼ÍÌWøl.£ÿÃ?ü ÿ1Bžàü�Kªè:Âüuì¸$‹Mø?Oãkgõ öV=Æ\͆j¤UãåK8 :HÊ¿·òKù¥ð« «¬™ªþ¬~p]­vVÇ(÷â_Ïö6*«)³­ñ }Fú•i*Ʀ ð´X©ªÚ¦1Ù¡b©.Z–ÈÏ–“m0Ýôñ£š²Œc¹àD˜a•”­ëÊ Ò#$06§Iœ$mÓÝa½óG§3¢§ešlÛ¯¶M¸ýƒ’¹;~pLJߛÔmmØÔ0:iMY?¼âÊ+}äQ÷Ý„¢J›Ùf ãOœ8144444tOor5Ï=Á üùÏþóŸÿ|øðaõqϸ‚m˳Ÿüä'ÇÆÆ&¸´‹ªNoz§é3;môõõ‰@ëú@5Ì)ùÙ”G¥3†Ow…Vÿd^þõË?Ј”¤:÷ßwÿô…é+%gL:?€8ÈU³Âëµ¹»Îq8ðâ7@Ð¥hŸüêL%ÖïÈ1LŠg†\í/j `|ᥤ8hû@~ÇÀ¶ÃÝ%Sž¡Uò ƒÍÉ ‰[é·®1ÖêV4BáÆšâ0¬”J¢uNF‡ÎûyVžA²ßDsœ…pÚ²‘¨'APšµ?UAyj£²‹ªårr¤`1ËKyzˤ-¡OcCÌZƾ½”®b÷2öI+ÔÎêC/c_>òJï¦"@r.Ç$Ü-æÐ\Á“¢žM4HÊEh »Ä …aòÒE¼�\ίþÌùðštUG˜ŸÆ7Ÿ#qB7rß›ÌÆÈñ‘^À᧸ ø_ZÀa!ëy]TõRÚÎê9¼6xPCg?EëÙÞKi3›Òø:©é ÜH“î°ŠÝ1Ê/ã©rïª ÎBD¾kÙ³šöFÚT².`И!,ßÎzɬªèj¤MbÔ ‰¶tX‘>+AP*\Ë@عä<I<-x’^FMŠ‹gË׳Ýö„ÁÕ$¬€HA:¹38£Tš² òeÅ<ùn†>*\3eþ@’¶ìij˜¡/«b›5ÝËm•.Ôœ;'ì&7~çÆ)±s2E8ч!%§¿´â[¶¿è޵²&{KŽk‰nŽŽŽŠ[cÄ>³Ù¬`O¤ÜVÏÆ«Bëã fppPÿÔ«¹:~üøñãÇõÏѩ֑#GDûúúúúú>¶ñô‰(3§Zº¢ž|âI{ØRØýãOüâ ©É&œ<žøÅnu«;Hç}¯Ò3{™Lf‚FéTØ9ŧ˺lBL ¥¦åÙ`Ä„þÌxÓ¹Ý ¾÷ȇOZÑÓå~:# ±\^hjöY.?Ï6• ÷ÍŒÇewØ É:ï¦HÔ‰ñ–æJ“²@Óq~#ÏöRæ'ÖF¥—JÍHÓ1H&Ô¹¬"N(ÊH‘€Á=Ԋݶ³º’¨¢<äû3Hª®~RqØèyb%mmÔõRZCg#M~R Vѵ˜—5õ1‹¡ò”L é%£Ìyí ,ÏôEôô°¨‚îòpXËÎùyŠËä=»Œ}#ä]Ä Xò&sžæÒ–ÁWùÍ0ù¯ðÙKyú/|&‘™¼½—ëØœÇçòÎü;ÿïk\¡Zµ¿ækUt‘3Ÿ#Ç™=@aˆøE¼ _x ‡E>Ò¢¹’ϳR³+z¶b¹»Ö° !¯–=bV/¥q|·zîÜIM„`©aò ón¥^3?:îÈx¶Š.ù×ÑsKØc>…¹ØCÛVN„H·q Ž™ìÕ€¹fœHscøÉÖàIn¥Ç“ÖI™ŽdkBÍ/…+‰¦<1 n‚3Í æ(ã>|1Ã5¤Îù]a—{Ÿšu¦\"æçÌ›§áöªœ<Žâ>JÏŸ?ÿTP:oMößqÇP|l 9gn/ÜU2ñ<Õ`.\¨U)=ª!K7é´öInQîû¾–›n¾éƒÖúÜ_«énsžsÎ9/‘ýº}VòzÕóWÐÞ¨æô{ï½§×û044t–BªO¹œg€7§ó#D9Õwzð¡)'8ŸøÅnܲA:în„R{mè²wóé'NL&£Sþøi®Oœ²Ç)©Âøàf ;š‰+q·ÃºÈ†œÑÉgSó8‚F¯œ\œ™6Ùµ—ã=”Àñ* 3Ê[̦ãXlKã£Ì•uÄí¯6ÖÛuD5¢rëvÖIȼM4BX{åæ1Søa"‘Ñ 8>(Q'¨4ú€¼âÖ°KLÉR¶fkz=~RŠq.'–r±¡šÒò$ ô°h;^à" Jª/¸ea:Ž2O:šY uS‘ÃX/¥ù ×Ñvw­eçòÏÆ(ogõ6‰ßý…ÏaþaœÏŸÉ׿Äï–²?oûü¤Þfæù¼8ŸaÍ}ªvº”ý%ôí`¤³µìdúH/á@ ‹BÄã„æqt„¼•<ß̦Rz7ѼŸ¥yŒHp{ˆâRzå)¨Wª¢1ÙÀÏ(°‘íÅ:Dq/¥V1ÛK©Þ+6¥ðë-ÍÐcy_µÓÕB½Õf+–ë[AqR!O,ž-W†“‚†6çøeò<IáŸf‹½žÑx6ORÞ^*3,ZâN¶3âtßsCÄâŽüGg¸ÜŒsÈSÙ#·šÎ¨ã"dÇ7Ë] ¶)C¶ Öƒ ³NÖ%T•€‘“ƒº&0€ ·5?ŒRqJTv”Ox¨G~ät~ÅÂ… Ïlßw+wl_ЭWºéæ›î½çÞ Ø9¥ é4³0ÏØúgÝŠÛ‡AÉ_œlÈ0½+‚Þ[M­Lxž€m‚ÛâYBqŸ¾}Ý·ÚüS Ê&_ ² šÀí®ü×+½^¯[žÓüxóÇ™C7=šNN/“n%…ñѶž×¸þiWÒzÎצ<LÀ¡±eOjg‰"k+r¯ŠGá²Ä h™ùqéøGǵ³Våžd5‰6ÇwæËBÄõlßÊ—µU¥ð+([û²,)PçRäU9V‚Þ8¾ñØ-\ ±(XN¬ŠÁ.ª:©1Æñ©FÚ"ÉÖlô<±‹56cK¶|yŒìcY )½ò˜†É®Ä(—~§•úµì,'ÖA8L‡ÒK$ó™Ã›kÙ"žÂ_Ok’€ì~.â…Ílé£$N(ƒ÷"^øê¢ê‹üþ Îû#ŸÏcd=² ÊcÄGº%¨Èâ`M¨ay)Oÿ™ó$1·› ±ÕEôì`]]G™×OQýtѯPéżü�7ÈâGqÙi|êz*¶ÚVΫ~Rl£r#ÏVÑÕÀ÷«ITÐ-£à:‹9”bŽMʹBµÕ]Søã¼XM™îã'§<®š§lÜOª”¤œˆ§Å ¥è’+ÏÖ·Ú<�™lƒ‹G&q9>†ˆ%¢qí8¿Ì˜¢®õCpýÉœ| ¥Aó f~´Å8ö5¼¯sÐ4r,T¨ÛDþÙÝt¤¥ÔšVe Ââm .,++³·k¦BUM ‡BDZ±1}aI¡A¸¢oŒŒLÖ¸Þ{Ͻv×>ÛËÒÑJ=ÿ P!PTv•Ý£õÿÐ8~:8cÆ Å‰¸¹»ýzr½Úçó¹OÖjÇîödàžBQ¨8pý ×?ðÀI‚2K]wýu=øÐ4ÝDaçé×iOs}ÈIâS8Pþƒù;WŒ‰ÎÚ fGȵ5ÏŒëFç0•ÑZLè´ßì/h‰Pcº>˜\_LúRG‚z¡r´BCÐØ‡?îVg€Ýq,Ãë5Û\?»¼Ôouà9"f„BNüu5)]T©Aµ•/ÛFZsý¤ÄxÄf·±![)¯c—ÆT¬|W½ºFššhf1TçÙÕ–]³õŠÂVHH/¥ÛY¿õâ®äy/™Eô,áÀatÌåX3›jè‰,¡ïeßÀ?ç•Dû)šÇÑ çsjžÏŸòjU~Ž?ý¿oÈþâGž›¿Âo1¼ù³¼roüÿr3÷ü/_°õlŽ[ÈÔ“9À’Zö$ ¼ÀE*±Êœa>Gö³ôB^ZÉómÔ]Åã/pQ‹º¨Zî,‘mP/¥ªÓVÑ%·#Mãlg=\YçÙ©嫨ÝO‘ü€ µŽ¹[9‘Ïâ<;HÁ0ù²Ò; G~?Ñe)3ÇYM4ÂÁÌØN%ÙšˆÇq?Žâ/æ{ÂrC”o_Ä1@ÀëOŸâã@Õ¡2ogWk\íÆ{v„p\�Ó³´6¶®»%õ§cò7¡ë€q»Ú8fŸÆÉ-’†É¥ÚGy´ñÛÃ#ÃS"§0™ûø—…Lë·w‚žð'?ùIÑ;9­…ì©â_>äé|_íõzU:vsÊ ÑÍ£££Ö<Ï}ŽÑ§Ú‹/^yñ ‘þVŸˆ{øuBxÙõ7\6~㩈¬ýuúí<òˆjÅßnt‘ÍÅDÑé–7ßHþIßu«”íº–tã釹~øRmƒD‰q« 25¥ ËmÅI¹`ãé†Î–0z§Šk<?̦jÊ"$™gʤ¦äFœáQgr<îì âá:dE¶÷w¼=³¹ÆAWé‰a/TÓ©ä)/£QSž‰äb“’wj†ÝOÊKåjikfSÌĤˆ€Ê AÍqó-ŽÇ^l5í²©SͶ‡Eš²ØÅ`£ç‰.b“ù ‹¢UGÜÂfÙÑ¢Xî?jvjÖEÏMŒv)û÷³4N¨’¨@NÒÙ#Ì_‹yî�K)øŸk£.LÇœ×ýE“ç[Ù{þÅÆhD$Nh5íÿ˳@*Ù¥ì?ÂüÙ%×Gz?KCÄӸ䯷”ý=,ºˆâ„Òøö³´“ͨ¬`ï>–uR³ŠÝÒ_Â3K8ð$W¬b70£òã]ËÎÍl ’ÈdsoõÜÙiâKw³JFöA~ÊÚ8XMÙüöcÚÈöí¬_Ïöf6ipVá:5òP%!–o51œdq9[éOÓÀõÛVS¡Õ„™íÔ¤Ïu„âžd›Ó_°9e6¨ÁÚ@7Ú¤—ú¸SPÁ´íS Fq 0N¡XÍ~èh3\Ö:MZåÑ”Œó}Kjv±›£;tÉ®óÎ;Ͻº¿«ûO0Õ¶kqÂ"Í£p‹šã‚É>P7Aš¤î¦{£œ={ö„§qš³7Ý|Ó;¼óñ�•}nzÓþéÒjûMÛE_½¨í7m‰Åª¥�šP\µtÙ~1¹8üÖ[o¹áð >ðàEM7²Œé¾–š~Ú4á»îD9›®ùÖ5§Cû„göYØwfllLe {¹ÃGÝ•ÿɬúô{œÎ_Aˆå漜ÌϦæä?ïp»Úñ¯ç‰.l$B:Œ;÷Ô̸þ©8°“ëWÝ—E^üò‹w ‘\b%gfÜù[ zb‚^*WÓÞF :ü”E©„ÖŒ±äN±\µÓAˆH%Û̦ ­°\B!5>{)•AL9±Ý¬R>h;«3´†¨Å œBú#}q4dÑèyHyaÝTÈļ†N9¶ßÎý©ôª~g€d€¤ ³2žÝËŠì}“9òÒ–øH' ¬cÇùüßó‡?ñ¹óxã¿ø'™¼ÆëØQÀ †aær 8—w.åé8¡ÏóGzXôOü×|Žü…Ï�á3çñÆ0ùOrE˜Žá?~Ç—ä='£¼‘¦>JrKã+dà&î} .àµçYYAw#Mª‹èßCm1‡.ä¥ìmä»Õ$C-Þ¼šö¶ìšjOç!z1¾ÁåľÆ=òs/`ÊdϤI3²ArC”PVš!"Ö‡”;/އíxFMýÿ „ÉÌTà÷tÚþwÔ3jrup¥Æ6˜f¤Ã;+‰¦œø€¼‘ÔKûã¥ç°8^‰Í8VŽ­ÈlÖ¹P“æLÙa¬(G#t`4ä'çѶLßà<ƒ Î=bq6̧t minQmÖ2`7ž1c†v|UóôV#£•reU3" š<ãWqªRí„bf*•r¿œ÷ÕOS­•VVÿTÛRÿŸ ìš°ÎlüfJŸŸ¯ Àý*$ʽû®»o½íV>É[o½5MÞœûÌ$SÆiN9§:çé1ÿÙã¿øù/&ô懧Ód½æ[×L™²i?>tOÓÈ9ãOó43i­õâã͘—åúm=Ž«{ëV°‡5×–ÅO|üd-âX¿§[””4¢D¾%WÓÞ6CAå éÌVUÙ(Ïæâi ²¼c&|*‘!UÇܶñºªaÖÕˆnYM{Ì„mX‡±ÚÁ5/XJo‚àFf¨{¹žíÂEé?o玆ì/€n*"ëˆ*›³™MëÙ>HA5‘ml¸•»£Tª»™Æ'ÏôuìˆP­H“ìÝËŠ+xò3üå8³Ÿgåe<õ?üCc’ÃäÿŽ/-áÀ¯ùšÚ!â~-»$'íûƒÇ/—ƒÕ´¿ÊÂú~Ç—þ‘ÿ–îË,¾”§( ÓÑAøïùü¼Ä…²=Àa°t7i|ý¥ñ-¢GÑ` »‹Ûšh”ÖIqÙÝT”ë¤&ÂA²k=•²ó1®ö“*'¶Œ}ÎIᯡs ›e”p&n[S”‰˜ÊÙGÕrfäoŠöH6ÒÖäÈ»bçÄÖ¡v¦£)Ë6¨½jÕàAq’¨c.ìjã˜5@HPŸ!·’2UPC,‡XÊш¥Lb<Ú”…uA¦ \M"âjvÚóßÉÅØ° ¶±£_¶,ìŽý›,¿ß»j»|ã7Ngâþ›WógýÌ5¹Áùa–àÓBl&“¥Ðÿ­¬ÆMѼ^ïä:í”ͼl6«·Tïĉ²våWº¿~âÉ'Ä5?¼ªÙ]° â>äåå ª{{{ííj~¸5%M©~Òßn´oõ£<*ȼæ[ל8qâmÞžðÌÏ,ušuÆmãi°v2pv¸N¾ã˜13—î‚’+>i|ˆÅ¦rÆѨ9×·˜þ¨ýu)¦2l=Œfh­6 $v»‰Ó“ú”‚°«_Ș¶S¿—`7Ñ:¢í¬†”þ¯§g9¢*™AÒ›H+$4mf“ªµú®zf1G^K%Qu+KéU/S­Ä_óµý,=±»‚"•IeT{ ldPéϳRs™r¯]îC?Ã%ÅJá—^˜ŽQr÷³´Zú(ù¿ë¢ê·|e)û/àµãÌÖ”ˆ$¯27xÕü¾¸Ç3³6ûÜœw!/ý/_(`0NÈKæøŸ×¸�ø<<ʼ·™yŒ¹_âwG™÷[¾òE~ßFÝ,†v²vÍb–¢°—ðÌæ«‹)3Þ7™³–i|;XWJï:v<ÎUëØ±ƒu~Rò|'[Síé,b÷c\-Ô6ÛýþiÕÎAkØÕIMÝÍlãׇe¿6™6þŒ3LÒÚÌ&¸ÎÔxËMŠС³Ç9ÙûLE¤¥J²'– (_\ðAK„ƒ^*¡>>~5¶ÊîÀ6õ¡>CîÉÁœRÛÚoëÉé{¶~ƒuæÒŸÍ¦5B¥›}cJ2!³¼d (,,´=ðúë¯[¨xë­·Ü[öÙJ™€”?{ìgSN»»÷ýd2)¨›LFq…È#lÕS<¥Z»Ýë­öù|úB›û”}å¡¡!wìèƒ=8ÄÐÃ<|í·®•«ƒ»Ô)>­—ìõzsrrÎFm ´´Tàúå‹¿üèc2ÜÕvJ‘°>½óÜÜÜɆ'ÐÍS­û¶Üw:ZqíìÙ³UŸ˜0y2áGÜÇô‰Ö§/˜Ü;•O5ª øìp¹q¢thûgoíWŒñ,f�¼UK6bÌè“önêi¿«c—ë�Öȹõá3}&UÌü.â+/4¿º³JÛˆŒQ.¿½J¢º¿ÈAÂD^hˆ^¿Læ5³¨¯¦yÍ”q{Ю]A·îPJï ëÙ^À Éñh”ƒ¹†5‡Éoàû öRê#ÝÈHUŠ›^Éó›h.'&OƒNj¬aBo%ǘ«(éòÞfæ«,Ìe´‹*%bþÿro|Ž?õRºWßf¦J¯Àð/_âw!â{= P(èU(X.£¼%ôyɼÓèZŸó/òû�É>Jó² â“Ćs[È«G˜¯šmýX"¿Àn*ú)’UÞÓ\zOîg©Þ±=Ôf²¹ž‡¢TîfÐEUU«iÏÚÌPÖ³½–=ò²�v±&J¥©™;M“'BP‰¼2¤ª) ’på¢ëÕg¬õ“Ò"?<L|ú¸5U6 /x—*§Ã¤÷`b ’° ¦Ùjн¶¬Ú`¥˜/Â'[T6ÿw\®{)iî\ÍzÃt?úõ¾!VÖܵ¸¸¸¸¸¸¬¬¬¬¬ìüóÏWgT¾äÓG…hfßmI3GÓéô4ö¶výõ¯=ƒhMÆ?éZ“gQ¦\Sv¼>bÙÔÏ[NçnÖÑNâO6Vœqòzûí·Ï´ >ó™Ï|æ3Ÿù»¿û»¿û»¿[¼xñ—/þr﫽 .\¸p¡üåß{ï½s¢÷}×}[î»qóÓ\œétZžr®(((8ï¼óÜmûpy½Þi"e&gÀú¼{µýHŽÊ¨Œ6g#—ñ!îsÛ× ËQ(ÄrhPø‰K¾¯ûw„ˆÙ=”ë,¯Äàz3I™Ì2.k!–G88îs„_:Û8åÆÎ” ­ò¤Õ}äÓ¦ä²8>;sÒFe”J;Á¢mZß­$ª9Šén* Ô=•rÕKéíÜa£Ê”’ÇH1‡êˆê÷²b˜üZöøH÷°(NHÑò ŠRYGÛQæõQr%OÔÑ–ÃØ\Žý™ó“Ìé#=‡7Ån/æ¹WYø¾ZIôø‡8!UY{ŠnÉÞ3L~ Û×GI!¹Œ~•ߌ’ûyþxoHå›Á{œÙK8PJ¯^és\ Èia€ÂA FÈSPöQæµ³:‡±£Ìó‘î§Hþ ­Ô+T1¢³:À’!f¢ØO*ž-ÿ‘çæn*2äjàGuoi©:©Q´˜C{¨µæÀ~R›h¶ˆ¸‘g«I” 3 Ît†V5Gœ"9ZSÿ »®Ø†AYÈꈥ2DºŽ¹x0R’ÿ4è>&\³A~q^´wºÅü"„q l1ÁIyIº‹ºt6ÿ´£½aW$‹ÆŸrÍ2kÊï öþÞ¬OúÓŸþô§Ï`ã˜7oÞ¼yó,X`£1Ï0šß0R©Ô믿þú믿òÊ+¯¼òÊk¯½6ÙloæÌ™sçÎ;w®"SÎ?ÿüóÏ?¿¨¨H.}2 :•ßú÷³±„gÌ~E7¯¿îzàÚo]ë>[Œ¼¦1,ä#ò“›_4¿÷ÕÞSuF' „žß{ï½T*•N§§4 rã·5 ¼qóòú Þë§BÍ3¨œí5e:Jƒ±e—Ç쨵â4¥$ë¥'ˆÕ-æ(ÝbŒñô…†@wþtÛx&½Ô+#Ú˨Ý2¼Ž:QíU¿kgT™ÏoÜõ^´Ä¢’¨úZ3nvj³SµPÏa<}…?©j!ÒëÙîůAϱ’ XJ¯Ê¹²5¤@›øjÚ5¸r Wod†´9ù 1«Ÿ¢!fµ³úiœlØEô¨ È0¡“šå3¼šö$ݬ’-Ñ1æ.àpœÐQæÉ èküúmf¾Éœ?ñ9½üBÔÝ\Mû?òß¿å+À=ÜüOEmö¹¸ç³³9>HÁqfa~ƒ¼ÿÃ?a¾ŒpòêK\¸‡Z¹Éë~–W³àB^ÒäÉ3\"…mˆøË,þ¿ÛÉÚaòeÝ~÷>À ýíeÅ,†ò駨™M‹è‘Hi0&ýƒA){5tê}(w’j k3›.K• â¼(c‘~ñûË3´’m0ñ8­ú¸CÄL3Rdq4CÊÖÛuðJ”âÌ<=5&ZŒrÊ2Bc<v™íÙÂl½õÅžT;$µÅ”d1‘f´ a  øóæq¦Ô¾÷Þ{yyyŸp­ìÉëÎ;î<KÙÈsçÎÕžø¾=¡üü|·c™»ß9Ízóäõ‘w¹¦QÓh¹¹Úää“sÏ=×¾çSff¹ñf¼ ö‰OXì|ø‘‡?föæõzuôñûý /Xøö;oË.? ƒA}kúTÆ„ô÷nùÉ–Ô}Ôt­ÉŸŽ#1c†luŒ8zôè‘#GŽ92%»×ÙÎlƒ¡ò7 ˜¹ª)óRo|…Ìÿ;\5Þ”õ’5 ¯%H"ŽÏ•߉µãÓ$e„`œrÕÄ\›WÀ r«ëñ;ÈÌô[�¨CÇa¥ãõŒ†Xž!¥‚­ŸÔz¶kSÞÎz+ëq#ÏJÙ!}P‚àV®T‘¶Ž]^êkÙã'µ…Í[9aKµ8 ‘ÖŽ¯@±:¢jOª€¹‡Z¡‹¤CMÔ0(›:ÕfUºô“ZD=e>°—«ØÃØ–Èi6Nh>Gþ“~›™sxó8³ Þ8¡ÏòÊ\Žý‰Ïaþ?ñ_bÆàï»<ÿÏ>–g¶Ÿ”×�ä3¼—jp®äùWYx!/]Àk^2‚Éòú(™Ã›{¨ ×/!o7«”ú* 7Ñ| Ï¢¸Ÿ¢Ã,¨eÏ0ù¢×úñ Ô­¡³œ˜Î+uD)ãLá—Ù¯þ/•×|¡êºÊé:¸¨¿˜r‚9*‰ÆyÑÊz’¦°ÎdsãÙòxÖɃSý?C+Ù@$[c‚.‘N2Nyˆå*„TSærvt{ÏbòRœ&º©å¦lS_¸kl:Z#4$µÁpPÈ6‘ÿF;�� �IDATÅ$ÀãFhÛレ~°¥ ñûï»ÿwÞ9ÿüóe…:888Öœp­ÿŸº÷n³<ó½?(v˜¤Q6¼ZÄ:ÖÊd7õÁ»QC§‡¬³î™9ë†y‡œš’¥Èl�(”ò£…”áGp `uY·x'Ì\í;sê6l§¸Ê÷¨9ÇSÈÑ*7êê$hÀ±±£¤Aïßç¾u[v‡$ížg¶,=’Ýßûº®ïŠa¤&£6ÐCëæ{ï½'0Óƒ0N:å¶µšô8'Go—!âa¶õªºS÷ìÙ³…j§nv¦ýÛIŸå¢æTcŒ¶¿¸=¸µæÄ—©Ã ¯8*l+b2'†£]¨ãœ°sëÓ[Ÿ|êI5ÌkjjžÙúŒþ©¸›åýÖŽ‰P:66¶íùmÛžß6666)Öži{t&rŽ|Í®qˆ¥È#*P)fÜøloÖý²Uî<Íô ¦ð8>.¹—dð«F‘xkÜ'5Îy.))/Aža0‘aÄ(ä–¦Œ»¥ØoÜþÔ([™¥&K $»¸U[„žnç~è†|Šd4à±ö n„p/Ay¤Ø+µú« )Ib‚cëLAƒu ö°öf^“]íß²YÚ~ëÉlá–v‹9ÔI›4$×󖤽4žŸÎääûÌßË õKÿÿãoù p5ÿ™?ü1_\ÄáÏóÓ…¡¦ŽÁ<¡_ó陜<Æ<y#,àèLNŽPS$ ”­fôv^~ÅU×ðÎëÜ%•"z¯«s»e7ñúOø‚p>ïLjÿ„/ØNlš†…ÑÀ²•îç¸WE¼ ްp1‡V°÷ÁÒ“xùÝŒd©9ΜŒqt R¨c°‘þ~b˼©¿ÝÅé9½¥Q Æ÷xÚð•*dý>D>ëì*ÝŠ—7>Že#=³¯ÊÛáyy'É®*ÀX˜•Yß�Á¿üRþãǬ×GÎ7aÖSÈèGê¦ÓÉ›¥ŠQ[:[¯«¸ïiUŠéÜ X†ìWÌJB­Ttê%À]å-ÅCndZXÍ?¤‚OÏ‘#G>©çœëu` ÍŠ5«-ÇçÒK/u×zûçÒQöÔüÍo~#DQE2þü£G^¤EVÏ^]]=)¹–S• VGèj.ÏZÁ‚ãÔ©SÕÕÕW^y¥eÍ™=gxd¸4³d{ÅÓ)ħ¾ð,¹¦¦Æ’n„šîÀrÒ·”ÚOö]Ôùd«u¾Òùõû¾þì3ÏÚ—pn[¢3üÜFrZÐ2šK‹šþ&Ó×ê¶;në¥×KkÀÿ‰E;Û“ ‚ŒWêÍs…,G£H!ãïôåŠÐðmöä»mÝ|é[Š&|—ZÙ»¤£Už´ÏújËÆFúwÜ lç~¹À§ ¶1º› Öw MÃ&¶FTñ6²s'ë²ìi1Ôž … K—°ë oó^j[HhL¤ ã½FúŸãÞÕìîcU i±våÛ2 x‹ë›Hj@ø ·7‘”ŸÀí¼’%ò?ø!òrùÛ|v{ÿœ¿¯eH–³×ðÎ^V/‹æqìæ^Ã;?çsŸåí1ª²D"d›é›ÏûWñ«kxç'|a5»USþ  XÕíÏòöLNþˆ/-áÀV6%XÛζeìÓæó~à½<7—éŸÍðBŽìe…úÏêD½5©Rhµ·­‘ÙÃÌÖhSee?«Ù½–ž¯ð¤«NÚŠ4ä@Lf•ò5[ípZ-\Õ ]Ü`ÌÜ}%RQ^z~ú¦.›L–¤Œœ‹¥˜ñ§•(9ï´F­¶ÌËo÷-;Rþõ™qëQÅuÅ:Ü·nC+ReÒpœ,“¦ÊŒY·0+³þ×çÿ9§%@žÏ>óì×ïûúùˆ„IV§¿¢}ê2õíXñœ¼×ÏçP„ˆ=+=׬Y³tÎ. =öøc\Ž‘B…¥â%¸]D!ß'K›fU­ÝÀôs°-z¹oïÄÙ§&ÄÞ¾ôíÙ×Ìþ×ü¿ž>}Z• {X σß|pów6ß}ò»X–í2(Ÿ­ Ÿ÷Ü{ÏÄ“·5©ÆôBEU 5?y/áL}‘,LÓÒ”§¥d¢íK<#¾ü1Vôÿ³ÐÈüºÉ¬)>×IS)@,ë[½7™-|Òv}³eÇ f¥¤5)ÅÞXÑñíËP¯µ5GPú¿Çì«"Sìõ¼ºˆÃ[Ùa¤‹Öófš KlB§˜,rêâýDÖiZÓ¹€£ú-°‹5©Ò*¼¼œ†2Ô7Ò¿šÝËØ·eò‚O†p;ÃÌ¥º†‘5ìz›¯ç­eì»’w•ù ®ýKþÆÆ’( Ô0ò:7}‘ÏfXšÎS\ ¨*Swv³º™^?pŒy—óá·yô§|þ¤qs™ÉÉ4 «Ùý6Ÿ­ft>ïÏçý-õdŽ3§ŽÁÑZ†â±éóÅÙ ëU5SD—3p”ßæÑ6:k²æ‚&ý»ÅºÎQ+*PÐHP ;ÊÒ4­»É5V]„‘Å’^SJ!XU„œIu¹(g¬ŸpÊ‹+ó5ìer„ñ•š1K ‹°2A `Û1ór‹šq£Âì¶Å¢âË–Öp_»žÄO» “ËÒ!“óñ¯É™wÚl–xY¯ååuJ“Óª3vóM9ÂøäÛÒÄN[åh¹ñ<Ï¢¦vжûg+NI5¬Hñb~Êôº¢h›¢ìòªªô²Ë.ÓkTé3EõÈÃ<öøcçÿºìShsàZÌL\÷]‘IEyªŠÓB» Ó–¡ÉtÐGŽÑõ ZíœfÉîøÜŽ®7ݿɽσß|øÆw¾15ÍGØyÇwp—ä¤;³Š$Qm5&-L/»ì²Íߨ pY%·hÒÆÉt€3iœöüMqJ”ËjZ¹§¡I©¶Ç±Vq—**â l.Šík…}¯ß4J_Êìúõó¬Ò#'ˆáQ,UE¼L–nUœÒäE)8²=Q–ªm!Ô“Éé7EŒô.n °®àGp°ŽÒhQ“ϼ‰­=¬•c{3½»Y- Íð!§J«Z¼ž¹Öª39D­þp€åËÈPßNBPežtÓº†]k鹚ƒ?ãºnZ—30BB¡Cäçò"MN2S¸¸€£5Œü)ÿôÇ¥ào½kpôsüüç|nûþ´˜CÿÂ(V1!{9ÎääOù¼Œ~Îçj9Ê‚…ù×2'ú?9Á,±g¯à½j–±/O(Kd6ÃQREËØ÷>óßg~ƒGY�<Ê·…6›á!je¹·ËëK•BA¯g˜ÙƒÔ 5 ¶a=;ûYYG¿}çõ&g¨ï %@ÐIxUoS½VŒYü+Rݱ®%}èºVe£õ•%êõ¥J«œh“•Ž›õ&3ÔL¶0¯—`Ñ— çÂäL/·Éñ¡H^—}ΟÊ[×ø8ãÝi©ûN—í¢¦³š¼WÌ5ËE繤BMÁ?Ôz:)ϨB WQ®=õäS~óÁ'¶=áb§ªŸ9sæ¸%ø™æLî\=_,<ñ'6có(£{TÔŠi<kÖ,Û´¬ªªÚüÀfÀmWžgÓÕÒ|ì›<sæL·×=222ñsÖ[-UO©Tzcÿ¿¿ö÷“ÿÄDg«^¯¨ö¦C¢yaÛ no뎭Ø9Íã·j§>jjj.l–õtÉAQ¯ÏAµ&ç¶¿~QŠáY™vÒ°ó›´æ[§u?ÐŽ—Dý Ü°õïc’OÊì‰û5­ SÑò{ýÌáòjèÓ”šé…˜$9ãížb¿<ÁW³;ËÕ‚ò¤3v5»[èÑmÊr½‚Ú†)Âi¬B-ŠÍzi–FE #ÕU±e9CÔ6‘l§c˜Ùu bñͼ6‡ã«Ù½…[êLÒT x„…ê…a7òFƒ5ŒDÈgN5£XòK>#²Oc³8q”ÿÿôÇ¥¬÷™¬÷™¯”vªYºŒ}¿ä3¹Úf¤Ìä¤Ô,Y"À¿ü’ϼÍg²`'þ^ÁÞëøÙ_ðw@ #ïpÍQœ`Ö aá f‰»{ˆÅ)¢´ícÙ.ÖÌçý7¸QîB{Y1—sh€å+Ø»‹5£T¯¢¯ÅëIp¬ŸFÍ5k…JúœÕìîâô*ú”†¦6°#ˆiK$­²ÈÔj„É)/ÌQk$+®1SÕ´WIg>S™û M‹¡7BÈ®“”‰Üi2ìn+D±²f_‹iîÃø7™Xu›nퟭvr®µ¤àÜðl›¦ÿn»½­"né#s …³:L,ì¬Ôò\%[ßrþP1‘árâÄ û<44$å¡C‡Þ}÷Ýwß}÷èÑ£Gµì§ŠwÀ}ÌI³—/à±ùÍ~ëÑG¿õèæ6ë|F';*þJ\§+¯¼R„šI‰Kú•8±.é霎Øý?™xmœ>}zâƒÛ÷í’K.±¨yÇw(3üþîßúôVÏó*ÈÆbŸÍ8óñÒ‹/MŸìzNŸšÍWW[ûL<óœã|ÜÞŠÕ7ýçÖÛÿÏÑ¡ÑãüÑåÇîÙx©&«Æûá%M‘7ZL¿¥BÓ1ywí°íÑdîY¥OÝ9ûçqjì<IÈgÊPœÈÏš#A ²RÖ{¯vqZÖoÌÌY± ššMjÝTÜ#å83µ l´µ­„¤?E‰ž8:ñoMýZ/×St—3°›Õ:=5i•&Èd§žLˆ¼ŸÀWùÁ¯ù´2Ipt'4V”·ûA®Žý_’!ßòÏ€©8×-àè¼÷¾p5?ͯͧ5¿T|ʵüâ_ùýw¹²›Ömlüþì [Hüwþ¤†‘yËQÊʯ¸ ØÇ2õZßâ+ÿ?ÙËŠìÝËŠY"Ç™#k{m)d­gû±2ÕÛRz¤ÝÛ¦½Q²Ö“3þ�Ëí@ÔpVWê=wjSßÊ·ò7ð©GK•Vùa†dHd!›œ£‹Ç7Þ+Õ;�ì_fQr&¢'4> ÏFãÙñAÁß ã›(MÎÀÒ¯DM”l~<W€ñîðݶ­2>zÅħ”b%§U«ÙÜlžØÛ<uêÔöŽí·¬¿Åå”ÚõÈ]˜& ü'­8Õ*¬p‡¯ sži(<÷¬Ÿu÷Æ»uÏ—w¼ü_¾ò_ÎTqN=ÜÌ™3G|W.¹äõN]õ©S§*jåK/½ÔÎ}+ŒX§30Ó»jŸW°§6¬ÐÅ>£-pÕ®tiMîÐ'ÆåÍœ9S% ûrl²‡Þjñ}>úè#wä<22ââ\…Ý’cΜ9÷oºÿ…ŽtÜÚ«¨bc¤ÏÚ}Q*€òÈŸzЧŸzúþî× Îºâ^oÖÞÖ“B£}êIí)\³[÷OüóŠ×¨6»û˜öž“¶j_}õ¯R‰›¿õZõœ¹…Cÿ’ÿßéÊŠÓ�OÁ,"Ac 4áÅ£,5©¸~n\gåûãË=ÔŒYÜͲ'J_ d!’ŒÙ^Ë´Æ6Ê"ŒDX y«M±_Q/ÓÅ­ð©PÈD:¿"Ýi¤ÔŽ^˜m¤/Ý ql  µ™Þ,5†:K?`DžãúU‘ÂìPwq-=‚½,5=¬•¯J–– Er„³H•h7 QûŸøo×ó–€m;¿õ'ü÷Ù g¨‘?Ê‚÷™/“¼¿á/?äòjN2sû>ͯåûó?ùã·¼ÏàÕ^·òmÿ,o–·Âd˜p9Ö02Ju??ãº÷™ßJ÷IfÊ÷àù+Ø;‹—óáaÍåƒ_qÕ fícÙ2öEIuðt‚–Fzi>ÂÂìÍ’ØÀŽoò õÇ™£ÚZ;ƒZ†¶”Ñ}†¨íàiY,U3ºŽ½4°\o©ZF"I½ïÛ^“ Aánar-¤‹ðâª8“)öû´ 5ãòet®:…¥ËÄ ©ë§Åë1}‹¥S‰(}V¦Rþ0fÌ€ºMTu·­mBµ©ã†"—ϲ'BÆ–˜ÖB¤´“ª=9/À4Q:7ñÆ-ëo™¢c)ª½»FLZxY•ºeê»}W/Q!§Óaûà7|ð›ZÔ¼P pÇÇ*@Ýs;+­æ¢*O™òMqXa¨j;é)¯ºê*Iå¤VQú›ñ‡Å9·TÔmàþM÷_Ø—yÇw¸.íÀýÜÿôSO 5§Ùƒ½ØÚSz]=ÏĶJÀ9¦5ã4.²>i¾è(´GN• Ê‚ñiBII.9Ö ?Á—†ÔRs¸y1!³þ(#”BY/o,jë#dCÚäÕ§ôÚn/Í-ô&8VÏ<X™¥>ÌJ cSõeаjYX #RA„ÉÕ2 ˜&aÈénaž<lu¤iˆ¥z{eq`ÕH–Ö{¯v•ªê¼We† ÿ¹!j‡¨­e(Jn{ G¨ÉP/ŸtaÆõ¼õ/üÁM¼.Uå—ùá&¶þ‚k…X_à'?çsÀOøÂæÿ;ÈÕŸç§ ZN2ó]®~ŸýW~ÿ0‹>ËÛŸæ×‹9T ø~ò ®¥ºšÑÿÄû¯ü¿WòîA®žÅ‰kùŵûXö~¹„Xr„…ÒžV3ús#d#dUX²ˆÃ7óÚ–¬`ï5?à«رƒ <ù[¾òW¼Åõ@»·M5ÀòAUáêmX[ŠpÀŸÿ4Ò¯1°IOjÞ™eXÐ]†!“õçÙU¦)R€d êÈ\™Ý3üØ*7ß5¾T•òâöRb)/ðû¡ñÑÓ>3ÖJ×ój—Ó>q\÷Ü^ RCeÙãlói‚n¹Ëž3Sϱ"U~z¶::Í�ΖŸÀd`ÇK;6Þ³qŠ;hœù©O}J*?-ë¿ùÍoÜjÀÖnåjW|·¸,‹ª½TbÚÑ#Xö3±uDž<O²ñ¤™)øAS£££ÕÕÕcccúósÚaœkSÑÞÿÛ}ûC>ÔÛx饗>üÐÃ~ëQ÷z°È¡¶(w÷6'\“ÊʧŸ{Z7¦?³tÇ|Š9¾ÿp[ì¶Oün¸Åâ™0oÒ/….¹?þØ}Ø/íЦCŠ;­$™0ßpáe“™*a¦JõV‹a$ ’K‘4nyV£¢^YÆŒ3muë“,ìÌRwˆ’óƒ¢Èç*˜Z[{HâÏœ’ã¿æh-Îùz> ª…ž^ P¤°šÝ*€Ôû­'ÓO£úrëy³ŸÆ(@é²Ük£³ƒ–>V¥iP™ú-¤—p Bc#ý]ðE~ü‡üó‹Ü)†jWéV=kØUÈæš+Ø;Jµ¸©à·¸~1‡–±ï‡|ùø³‡y¼ŽÁ/óßq¤&ÊÎ<ÈÕ‚¿ä3K8 2Q¶¹ú W7Óûw/cßUü*Kär>\Ì¡jFßãŠy@ôŸ<¡Ù–7¥ú+ümžÐøR«à©QªÄ—Ô£n£sÇÃ,–30Hò[©«'SËPé×¹Iõú@ïÏl†³¥úõÞ«]4�7³×åc"ƤWIp,J!Gx3º¸Á°ÀöX&3ŒA.àe)Z·¹Tjäì¯Ï.ÌÊ,ñ+ƒäêxµ‹[ñòi‚&Å–û·`¶SîÑjT|Q„L—/š’8ÊþÖŸSšT²¦ˆIÖsZ¾!sñql[3°7CŠÈ ßÙa× I¹9î’:ÍÕxxøÂF;¹ªÞcÅbêF›YýåÌ™3UÝÿÀýS‹ô˜î¿*Ü×ÍÎ>Ýó·è¥ßŽŽŽ t{Âú­�ÏþPŸÎ¿ýÛ¿}/þ½;î¼c´fÔ>àßyâÁo>ÈeæÌ'íÊNz=¸òû6Ý7rräö¿ºÝ¦£Ìœ9s¢%ÂÔsIaÏg+é¾uÛžßl¸c°c:ä óÕ ÉlÏX忱LÛM5ÙdV¼Y2B4Ñ›ICʈÙN—zqúUiùöiÄ¥Zñ%¡^>EØøk‡ŠŒ°Ýò2ºÍ�¬‰ñaLškªYWOÆhóò´ Œ0ÒI›¬Þ£är„µˆ«6•j¥àx»§iRÐ|n »Âä2Ô«sa¤–¡]¬ RHÒô„·ù+¥\XÄáŽÒF¡¦Žù¼?BM#ý‡Xü7+­3BV³Ïì­cðÞYÄáÚ9r«³è$3/çßqÝb%h©e(O¨Š±¹|p5¯æàA®¡ø_üÑM¼>—fr²Hà]®¡f1‡±2¼Uüg‚–‡y\BÏøÔ¯¸JQÛÃ_ž`ViE»H{ Ìfx‡¯æàBŽ,æÐ6 3{1‡º¸a »l]n€4bq»·mˆÚÒ‚²Á½ÎdÁ¯TThR£[B (Kƒ†Èƒo}W¤P,U‰;–#,¯vëtaªÃ‚¥¥ØßÅi+ ,–,Èa/—x²�ŒFYZ¤*@«ëo||ÄñÉkN!¨6$�µj“@ÒPŠb檓£BÁp¸èh8wžo-t&J­]RÝnÞÉ“'§è&©k7é*VÑ›:9Ù1ñ¯´ŽL}Lí"4<<\áÃ~Ö¬ªª;ó1®ìÆ{6n{~Ûw¶|øÎ–ï5Ïç˜1cÆ%—\"攚ÕúNŸ>-ÊL…i­Ûq=}ú´¸Nº$ŸÏ‹åTú:.¬Få¬Íäs:ì¼súÇ}›î“7Â+/¿2±<ÍrsйÃ4ÛÖVz<eì|ùå—o¼gãÆ{6îxi‡_tN85EiÀ6ðÁÎr"dl8>8PKFS]˜e™]¼ò;ä©" qÙªAl=o:NÙþ‚ØÂ¼�cÂcó€­VRŠE¼ ¥˜¡#êÌcnðµžËX¤&•šR¤`21Bí$R„Ãä,åRib6ÄJ0ÐF§ á!¾/W9ɵ“Ð<O†é×óÖ^VD¼ ^^Ó¾‡¼Ç"^H”ÖvÓú7‘kLXÇàl†;i{‹ë›éUEØKs5£µ }‘ÿˆ/½ÅõCÔÎfX´Ûaf·ø)Ÿ—7ÐÕ|—+?äò+xo fqBp ïH y‚Y?ãº-Wñ«Ù·ùì{\‘'ô>ó›Hždæuü,Oèïø ¹ãÞÅvYÌoá¡ÌÞåÊ5ì:Äâ9ÏPÏìbÍ�ËW³[¯:ÂÈ–¨5­¹/ ià�ËeÌ»Ž"ìHóögc‚¢OãÛ4ÊË"œb€Öz2†¤=–*­’iä‹¥ª4 ÆÇ?ií.JèU‘j¢)¸Œã£ä¤¤J°6À˜þLNKÒvYeaU’&Q d.iÛªµŒ¡˜ÙeæÍü>1Á³Íãs:%öKxcxyJ1‡s4žzò©§ž|jj6àŰ场]fy:É;ïºÓž¤í¿¹#áÇ‚ tã\}À]ÖÌô­ƒÂÎû¸ße²LçšH‹­vމµã…=&F£Tl *8«öžLpõÓa'}ºiR©Ÿîy[q^( ½çø7]nýÚ­·~íÖigÜŸ¯xA1Ac@È(5“¦a›4óÖ(}fOmq+¦ÅȘåRÍ_›T@XÆD·ëöx„QÓœ)@«j’–´‘~QEHûþ, µŽA••úÖD§Œ0ÒN¢…t”\„LÕVצA+µŠT!eš†¬ë Enï[ÙÔKóZzÄ#ÕÏ1¶8;ØPËP#ýQrQ¯/âe$}9e9«Ù}ŒyêseÁnV·Ò}=o cÞ u 8:Ÿ÷‡¨ÍZƾ¿äošH3»™Þ¿àï,>P3›áƒ\=—ò²µeXRÍènV¿Ç_åó8¶€£ËØ÷S>?Dí5GYp„…5ŒôÓ8““¹Zi'oóÙù­lÜn`‡¤/ï3kšHfÑbÝÌk«è«cpÇUe),g ‰¤üi3Ô‹þ£bQºØ.n¤Î˜ è*ª)ŒÒ'–VéÒ2ÐkQpX‚W}„ã®W,UEÈ„ÉEX)Kd»RŠNùŠö ÂËK’"œ`­ñXÀÌ5»Í„²ÆŽß¼UÅÙBÙØ•Í€šéõ%˜¥™P†L ^<Á1SžVäT'­Õ?/~¦§œí^ÜþâU]Íd‡³e}D/ø õòŽ—u†wÞu§=CëÆ7c"/æÔ©SCCCnU166&rЩñ‡ëÕ>±æÖ±áŽ ¶hv^Œã¬÷8fþÂNW¢Ùb³[kêöÔØiÿP"–W^~åŽ;ï8×=Ó';¦(ƒÁàïýÞïýÞïýÞ5×\sÍ5׬X±bÅŠ .Ô—E¡ÓNÿ[-£žõ•µ*”²»ž5¶Vc*Å*³­nв4â»ÈÊ!ÁrkmŠ“•ÆræYBŠ4k¦hí|±]AvÞxyhê§±4^>MƒÛãRÅ#]¼å÷Z»ƒª"¦ž›Iål ““.Sr ™(S,J®Hw?arêÓ&húCµœÐq!GV³{:é×°+G¸–¡.nXÁ^`Ççp|ºjX"3¯`Ö6$h¹šƒs8~”Išj’Dd&'÷±lˆÚw¸æ=®H-ü þn”êŸó¹*ÆRDG©.ø×Ö1x„…²YßÁ†ƒ\}-¿˜Å‰<¡M] õËØ7‹K8ðS>”Ú `IžP;÷/ä0H]ž†¯mt>ǽËXƾ׸9D~:½d`},OÒ4Àò'¼Í²ùU¿t}b,Ë•I3È.nhg†´¬ŠÆœê±S A(E8HA[ßÙÎóÕ)^\TÛ,{²Ô2N½Å?»Srg”>[ªh?3†hrF•¶<Mšçm2´yÓOnJÐ!cHC1È·0ÏÇx_¯…pÄ©F±"Uâ%•·S=håÑv{Û©S§Úno»«ý|RQ4�� �IDAT®»Úï’»íæiIª­­å¶4¹Ø~4BM×ívúxùÑÙŽß9„œ ùNMvLºp+ÔßòÉßþW·ŸÏŸ«<ÝòøW×këQÙ©î´TÛigº³ËÖ¶¢Uw{W4Ǥ†ìnvdÇK;¦3bø“Æ?9§w¦89‹ Ç|€V¶óic oHóK ~ˆQ¦tš†,{æNÜ€e“éý&ý¾j(ÍI–= ¤ Ðj�ÛìU1§åõf^K.+å áÅ‹¥*'¸IÚ† õëØ©Yehé#vÀ©jC™SÀõ¼¤ÐO£ ) …yR˜d©é¥Y-Çfzoæ5 çv±f7«…]ܰ—ÍôŠ2:J5ÐǪù…9ÂÂû÷±ì X¾s8¾›ÕÕŒJ¾¹œ,Õ1XËЕ¼û´¸†wrõqæÌâÄA®V¤×å|XÍèŸòO 9òçüýgyûf^«bì\[mlSäþó—üÍ>–%iZÂÃ,:Ì¢YœØÄÖå \Ë/ZHR}”QRª\<¡Õì~‹ëeRßM«Þ‡<!Ñh»J·&JkS¥UrµÊô(Ks„{X›bUà uv ìfµà­Hw‚£'‰J£I‰#)ö›xßf¶H!àQŠQŠQ²íYyì¹£Á¤Ý¦Œ †.$mMGÏ›¾kYXi�/4¾²Lš©D3•=LÌôZÝèØ¸oAùÛwÝü¶‡ªUï,_ÚíÛ·wl?'ZìÇ<wîܹsçΘ1C‹ŽÛ¸›¸TUUU]n·,°Õ›"Sl¯õîw» bnMì çz¸ŽêÓ`þo;,îV”È“Vc‚®ŠûTÜS™$¯¼üÊùs[ßrϽ÷TÌ2ŸÙúÌíu»T¿=kà‰ÍåÖgô©O}ê·Ó•m»½íLå¦vEm±¶¶Xp饗ê-õ<ÏZjˆ%4í§{¢ÒÓlÀ“FÁ2;è$ål¯¼°Çô¸Ê+‹Yƒ,¯Ç7O1±sZ÷>R„Å’j%ÊR³ÁOúñR^œ»X£.œ¦›Š xcòû¶h*€v²NaRa*Û“åiªÞ¤æ—oq½è?´¤Ø¯Î^Šý¾°nŒf/+TzŠãÓÃÚ:£äj’9ízÞ%5UZõ÷ ;×3C Î%hçþjF;i¥Z¾µ#Ô„È¿ÍgÈ—“ÌœÉÉå ü’Ïü”ÏW1¦ “+xOnGïrå(Õ/r'ðWtо„"¥iXÀÑ«9øW,àèùòŽ·8À’%(eGXþWÔ“‰Õƒh`©ðêC,–!­¨³‰ÒÚ-¥G¶”Ñ •ƒ/'¤ ŒRƒÖ}AŸÕ%±Óhe¾ú9çj›«ë›,–ê}8)ù»%]<Íôú®³Þ˜¾ •€mXýö»f¨øä[]`ñ09Ó,Q5™´éÙö:7©¸™$í-#ÉÎ)5õôïæÅ#^Æ"ñ8áfYp¢ÛyóW&ÈÅ;;j긫ý®s]w>Y¼âô»7Þ-€Ô¤ÓÂçǼᎠê0‹îÿÑG}øá‡Âì3•k Ž™3gZ>”›hf—cëá~NÇ™–ų"ôÄfìY§›FNöoÏ?|ô¹gŸ«øh¿»]ZI{yLº²䤼0¹Aé'–Ëã’zt•_»ík£¼m™ø;Ü—¸-úŠãÉï> l}f+Ðð¹†wÞyçÿñeUˆŸ0 àô\ìŒû±rQØ4ÞxVU`<ÁZ»·p«ž˜ŠH—¸¡ËÚ÷¨® ; ´(KåYjV±¸HÆ3aÚ¹x¤J«Ö{¯ŠÇñ2‰ÒZÁ¶ø8Ú¿‹´iœöäË-/G¸ŸF5ßRÆWAeÊNÖ%8¦:J.ÊRi×3c9Zñw².Cý*ú Sìo =D­¼;Y'3{y.@PÍ[©W³;MƒÆŠõdnâõ׸9Îc»X³»€{yî Þ«aä³”…¢Qè^V,äÈ>–½Ï|EÈ~ÀÜw¸¦ô•¼ |•„ÈËýîun ‘/\È‘£,£ê nÌi¤ÿóü4@Qù µ Õ18‹_æ‡jÀ&héaíQ¨¯ ,cŸÚæòããi½÷jÀkñz"^¦ÅëQ¥ÞM«„(¶7^Ç ­ù›é••„o<ëû êôe*^>@«évúÄÔˆ—1ÐKÐ`Ì\“¾M‡ .²ìÑe&WD¼¶&ãe‡ñÉ�­Yê[˜g®dËôN›6o,ÂʨoYeɱeŸ ,õÚèu3>c†^p³Ã„‹oÌלø/0i­ËºÃÂ;#„lïØ~Wû]ÿ>+'—ú·½a/M›ÎŸÔz¦Ã3G…W€×—˜ÃþüÞ¯ß+ªÑ%—\rz²ÃöZE¼Ômñt†‡‡ ði¢&pï×ï½÷ë÷ÆÚbúǵ˜þæªãÍLì¬Nì�í¶¯Mó„®® ¢ ÕËè™3gºýaË2sïðÉdNÛ;¶oþÆf¡fg¼óœþv¢Ž3ïjlëɽs“#3Ç 4Ÿ™¿”Âþa莰2gÌÆäTtGª~A ÈÌ‘aŒ»‚ü ²„rÖï xcY‰<ºüŠ3ÙH½×“(…€¬—·:„«¢ô¥üsk2|N¬“Ÿ ˆzÒ«˜¥^\ øDu †Éídb±#Œ4ò¦Â²ÔhXÅÖÃ,ê§1Gx[·²©Î»Ø^¤ SVµ=UºI¾ÙǪ>VåïcY`?;Y÷*·vÐþ0·Óñ8«×zœ9K8ðW|‰‰Ó;‹r9¨eè( ÞåÊý%Ÿ¹Š_óyÿ&^ÿ{þ\%u5£)¢mt&hYÁ^Å›4ÒŸ'´ˆÃoq} üÙ5‹½‰×æñëøY=™–˾—æ6:c2še7óÚ^V´N°¶@¦H!Cýjv+ÍÔ„´$¡UI5ÂrYu×K´xó2ŒtqšROº´†½•ÙR}–z£Ý”^““ ±wšŽ)G€1I<#d‚äRÆNÖ˜P¤!£Ô'{'–0€±,£*ÁÜÈ;ÎqCç‰9¿’§²ƒ7î>«HíÙ ;­ˆ/9ÉêN›ç¶‰_rÛz’ôÍ%ÐÚeqb£òLŠ”I ‚I•-###Óo¦Yì,ÿïK/Ú]¿mšŽŽN¤nZɤíVýð£>údÅåÅ8>þøc³çyºáÖöR1m*—`ÇHÁzèën*F­a±Xœôµkpž‡Pó•—_± øüsÏ 5-Xê>ç97½H‡°sR‰í¤?ÔêÔ©SjÃè­>tè>Á“'Oú;Ô™Ó›qFÉÙ†RÀ³æaZ%Íö9dŒ÷0&5cc9?v¸ÉT�bóDzÔ[…‰±èkˆ:£¦x…w3½F«àç:éÜŠ%ük¦.N'8V¶g3–lílK±J¥j i¹ž7s¦…(-RPœ¡>Á1ËU©ûìd]”œ AaÎí$HÛ*¶™ÞÖ†ÉÉ^ …t«4}È{,QZ;D­L”½‰­‡X¤0›áMl=Ƽå üŠ«êÉ5fEGY%ògüC€âó?g3üs³DþÖò}æ¿Âí_æ‡rÿ¹‰×¥ÝœÏû,¥º‰ä–`É0³ó„4yæñ#,T¸¦èE7óÚùrˆüŸó÷ÖÞ¨£´q½÷j‚ öôÏkÜ,ª”^~ éá–[ÃB]º~ÊMN/¯^k¢´6[ª75Kë¶> V£"Þ¬}[áY%’µæ,ù¾Œæò0‹0b× ivÜpÔÙ jÌ?f\ôb®+ä#dÔËuÖ‹º„#Ê<»’•£Ä $7éó´Ú³gª5ÏÕý“q,Ý œn ¬÷÷™e.³qã='ðjjj-Z4gΫQ¹à/aRåè½_¿×úëž'è¬ZÎ#KÒ²ŠJ¥’Ë‘~yÇË÷Ü{m\»_[ÉÙkcRµ®-Ä­ôâ•—_ù^ü{2ñ™NÀÖÅ;¦¾ª‡ã<ø×ïûúùDrV§Œ "^Æðã1Y%áñœ‹ýfùˆ9V>–ÙjažOrtâþ†:BFëE,³¤6Ù§�­âŒ˜sð'¦Zp)É¢ÁP*HJÜ%'=\»·M Ûª-AÃ’i³Ôìd]‘ÂCÑâžà˜(²arôGXY¤ÐH¿äëØiqêLÓ ÐH)ˆ^´Ž`¬fwŠý6DeKé‘õ¼™¡^ýä>Vífõ,N(éZ ÞafkÖXÇàûÌ_Á^k]û%~” å8s®æà?ñ§´¿Çÿ“?>Á¬+xïŸøÓÝÁ£ïrå1æÍ僽¬è%Oh »ò„ºiv±F²–yÞã<¬4M)L°¤†‘å <ǽ¯s“ŠQ ©“×›ÖÉ·0¦÷'L.Å~õKs„Ûè4d±ãt$ÍVÌBKÞ!‚µJkõ!Yê‹tKbk>ú2Ç;ÀX„×ëÑàY¾6ÆÅ RˆH ðô¤ö‡f#XV[ á4¶4'™T[X× ãD&þXÔ÷ž5èkJÏXùb.áwËä;WèY‰šo1šmŽé`OEßOœØYÁR¹)1å4ÏS°zV’í¤z† l–XTv;œ;§%}ñàá\÷=²¸¨£Aá“P9ܽñî»7Þ­KE]q;Ÿ¶�ì6-,Ö%»Š]|úôéŠvºn|‘îY¯ÛIÉAö ò»Ojh <þØãú¹mðL8õ–’ÒiÞÚ¸Á&ã³Hãßd°¶ â2†uf¢!×0ÅŽ­~Ü™hVlüã¶a¤HÁè5ƒEü¬–-'ø0¹›ÕÂ?±jõ,í$ÂäD¦Õ"ØÇª …fzÛm #,ï½z2F¤ñ`ù u\ÍîÒ]ÜP¤Ð@ºžÌV6­¢¯—fù iºÙFç�Ë#¬ìât#ý©Òª‡¼ÇºJ·®fw‡wgª´*[ª×`2KÍa©b;Ê‚~u9Ÿ÷ëɤiø1_ü)Ÿ¯e¨…ÄUÀ<uï 5õj¯à=ÉHsh.\Á{¿àÚFÄWªfTÅ¥,Ö°K!$'˜U ¸‚½ÒªŽRÝUºu€å;Y÷7^Á{ké©eh/+dõú”*ºœÇr„50Vé©1§1ÕS…—/Rè ¥HAm^ –Z ý ;/¯ä§ß€„i¯„<6z³*š~¬®I“¢wcŠt£ƒ=†­ß;P&y ,ó <nHàX‡ á)¯búÉFõ$wܘˆ¬q.„|;I/^.m=7¹O}ÚÐIœUUUQM“Žˆ&õ^wxñ˜A;ÏI»ù»š ºµæ½_¿÷Éï>ùì3ÏVÀ§Kü9S59)œ æ˜ã|NujªêÔyÑŸàPÑ9›æLG¼3~¡Îá’K.ÑnÁøãÉûÛ©ùe‚À‰Ø©A©; ös­§·U̧ØÃeCDé+8á_›bcE«<“¼=áe,B&Gké = “­a‚9ã)bfIê6žÚãB†Í»#d²*U=Ù„‹^¼Xª’ûAÄËäŒÍžYs›rͤ 9ev³Z·S쇰­M[8%­¹f–cÂõd(¤Ð¼9QBY3½µ uq:ÃUQ‚[ÙÔÎýƒÔ¥ix”oïbM#3\˽:‡™½‰­-ÞõÀ—Jkò®S÷ßßÂ-<¤ÐǪUô`ÖäÀW—p`”ê/òã“ÌTõϸN•èQ\Ë/€ÚÛè¬ad„š÷¸b:h¢ö�K®ãg?㺠õ‹9¤ie””ô J™ÞË )Y·” xc©R‚ÀÝŠrjÛvÒü÷|€ÖFúS„åßk·>r6HŽ’ÓˆW}‹vFX.«}?êÄËÛX·l)V$–U�5�J lf^ÂW§øyÑYˆ°2G8눃#ŒÃwÒa ózýkÉW‡É9—tÓ¤ e®í<„èK7fygɸÿ5£ÊñîÝVÚ©<%ðb·!ó ¡r²ØE;&Z ¹åÚ¤ÃEËÜø«¶½pߦûd|zߦûžÙþŒfœ·Ån+âÏM;ÅܤÙgö¸ì²ËÆÆÆ~“öfµJ>Ùñ¤koKÀ“'O^¼X•Iû·ú¡$’g²µk¿»ý$'ÝÍ}¨I™ºÓœUßúµ[wüõ8í£E7Ÿ¼5cm1þ½Sonÿ«Û·¿¼]ƒÛÛÿêvKz”>8}§iyUÇÍbç7 Š>£Ê&ùýØly (Yj ;ȼkU§FÉ¥ÊÍ´±Ò)ŸIÑm–¼ žÂ,[U"kDéK±J¢‚0+s>¤Ê"_Š0„ &°SçS¤©@0ÂÈjvçhƒœ u#¬Ì\ÇÎ~µÜ«5ª.tê˜ÑONt!jr-HêÌ�ÍAÒjÌopc‹ñ‚W³@°ÝÛÖQÚ(ÍÆl†;¨^ÏN5<Û½m[JÞØ:vgÎìP×·–!açøªüùpt/+ò„¤ûTï´™ÞŸó¹Z†°¤Ž˜;‹op£²£ÅUyB‡Y4Ÿ÷åç°€£#ÔÌáøÃ<ÞHƒ 9²–žM”Öf!àµÑÙémeÓܨ å:v*5,K2ES éÇ"åTZ˜— °“uÐ�Êá—ñ"ÝAæh’N±*B&H–vÒ ÉeÑ¡ªêÈ–b*CS¥U6o5á×$¼x„•õ^l³~¯"ð-u!²ÔPŽI‰GXÙKØL |Q–=«p;ØÇ£,Mš’¬ R€Ÿß‰cŒt2;Ç| z)†g º‹>3.lz$¶¯#ø9#Œ¸½nåýɆ‘ç4Qsÿä<y7SK6í¹1)º}úôi¡LàìºïÞÓfi¹âα±±sUªÖ<|>Û1.Je"ëÊþdjÊÕ¢E‹Ü“œÎŸ¸‡ÀR†vÖÖÎÝô\vÙeñÑt¨6ä¶Øm^ðî)ÉñØìxiÇÄa¶õв$ׯ/\<!Êt>|¶¿´ý¬ô™xOöª;kÅÙd˜ ~6µƒ”Œ÷ð,DÈäüvV· ‹9äC¿BM”&-@¦NwÊçvBV`W¤*B&kTzv Ð 9¿¾ôe vmƒ\€`=é, ZÛè<Äâ 9ÚšéMÐa¤…y(ÒÝÏÊFúeéþm “KÓã<N‘ª4cmtná!`9½4«‡ %uÒ¶Ž)Âí �»Y]Of-=Ç™³›ÕQ¯Ïèw¯gÆNÖ鬱¸ÅëI”ªº¼xƒb·Z¿… õ×󖨕5}Œys8ÞFg–ÈûÌÿ _‘œ‡Ûé8À҉d4Ìì÷™/óÛ},KVÃÚ–?ÎÃïqÅ�Ëw±FoìÞf½üaf‡Éí`CÐ(#w²®tB#3º C} ™^ÂÐ]¤)íC Eº×/¯´®cgkŒõÒ,æWÖ€ŠCsЫË«¦xeÉ©mPޤö2 Ö'ؤ„›9³iS¬º³…y½þÎL8ê{ô¡ˆO 5ò˜ £<Vø]˜r¦XÒ±jr @LôÅ5ˆ!7T|™¬Wo Ó&w×n¾{Æÿ¼¼ÀMQùýNŽI9AZIm¹ù;9$`°œÛ£Öüìã? õäÉ“â'»;7†Líñ IJï¿ûA̘1ãš:^è˜4uä“=ÔYçS€ŠûÛM÷oªØ͘1ÃePOz'L …=Ó=+´™“šc¸8ç£fÇÙQS„ásb OœÄ†œ‘ä¸Ô@‡á·˜dìbh>õŽ?Yù¡Ìl)oèfÆc,ZÌ#‰¦è³-J!Jå짨ÑóEÉiú•¦’Q–jŠ©3‘y›ñ8 éî ¥@p=oJ\%×H‚cZžr„ š½©,0ËJWއÉ}…'s„•j&%ad-=-¤Ûè”6Ñ¿L©ÞÍê ì(ìcÕ0³eʺšÝ‚"%— 3[d"µ^×3c[¥  )´ 3MÃ�Ë´¼Åõÿ‘ÌYÀQ‘c5ìú×.áÀqæ)‡™ýe~¼ÏüÃ,`ùÌÝÀyæ0w–3àWu^~kÖ±s-=ÚCˆ#¦÷D¨¤ )oŽ°Æ™ò¯°úŠ�­]¥[5­ÄGR'7ZD…U‹µ$›Ù•zÉ ©a+K<kì^þè}*¬½T,‘[°¤j²É¢¦*~³³ Ù8síÅM&oU‘/a¤`v“6óÎ /1®Œ·û±–@+æ²_|VÙdåa§ýNÅœ®ïyaÆD¾ŒýɤcÑ™“âtè¶Ø@;^Ú±íùmŽgêÝ}‚ãÿjëŸ FÒ©S§&5fšôþ®u\Ç /tÜqç§Ïv(úô¬U”µA˜48ú¥_’FhRúL¦^læö…=¶wlo»½mŠÝŒý:Xì<§ÇŸTÇéO\"d²eÔÌ;“)8cŽa^Ü‘²4”r(yõåd` úµßϬ6è¨~<¡„˜!È['šû4´éˆé©c°ŸÆ#Yb2FŒ­cg?#)ö§*&JŸ‚«üÅš|€` àVkhiUfª®jéϱ®™^¹ºsÔàV6)¬gÈl2ëys¥)jÔÈÕ‰iÝW¤s'mÀzvvqƒ¶½4·{t”n}È;¼€£oq½jbù$,cß uu R·ˆÃêÀW—3 ”%HÓ0ÌìEþ{þ\ÿ+סòåÙ /äˆÈMrÃñ}, RØÇ2 ½ôâzïU�Þ^Ê/Gë:vÖûÁ¥XlŽp„`Öˆy”é5Û b)†‡_B‚†9Œ‹ZèM”ÖF¼L–'s¡àØjÌi0)MCÔWû¨¦yd”¾”·_æþ&G=¤M–X3ó2ÔgË}T¿÷i2ù¯IÓ,5‘œì±äµ(KSþõlÛ-5‚”ÓQšLsx܆Ϡ¦O ËÉ<E²hpÔÖ:^y—]5~Ûÿw¸ ɵ@ù\¯¢ïjãÇO¿*fGÅJ'Ã÷ßò‹=×ìëIi:TAšN{všv¯Zî+ªaݰ>}ú{ñïÝ»íôÌÓ¢UUU͘1Ã…=…H—(¹è¨Ïkã=·½´­âƒ˜´ÛQ!Ûýć•”LßÎ×^xî‹R*Ôô9Ž1vÁ/’)¸¿yím2›â¤XõÚz‹mïØaR#’†$\ÜúŸi?® ¯‚ÙŒKÖ©åCÖzªW$ÄÔseÙƒ—Ï–êµÒ‰²«`§Í¼-ž¥^ÎAZ‚g3¬½ÍãÖóf€`”œ<uµ(×1ôÿªJaX2äËPßÅ ¤4ôÒ¬qo„•"â]ÜÐKs€1i=õ ´¤i¤n-=BåáÕì^ÇN•q-¤g3,ŒŸÃñ¯gKéÁ­€ö‹r¤ŸÆafP³#Ç™s¯ïdÝ uÝ´.g †aüçùél†w±Fó»X³ˆÃ´íe…¦¶òj?ΜNÚziî(mÌ–êÞ˜D)]ÜÐFgŠý)öGYÚ@º‹Ó"ÚB|-=*ô•É%zTBy çÅý_t&Źm¦Wé4/“-Õûèb¼…}~¬q§2F‰Ý¾ÿp)$Ûá ?áÛd:˸6ú¥¼X¾šZ'd]·&´®É^fFµÒ¢`Šýã›%13¡´rÌåâdY©Y A\[=cHrÛãŽï|•Q§XahÜ)Uq-Š~‡‡$Vy¢,‘‰åæÔ Î rXUâÔuC…ZÑÊL'’-§vyu±ó¾ >Lª<~þ¹çŸîùé›ïLç¸-vÛ÷âß:º>ö¸ãÎ;„©çÓO=½íùm¢×º¿zaÛ /ïxùå/Ûó·e´[ O´Yÿ\îšššóLMé|¥ób|Žg¬8#ŒXÃX˘0,‰Ö0¹¬ùzgýÕÊ,{3@+—Vcí]e¹Z³e2‘M\‘†Oµý T`«Ñ^/.ëMj%}9‚ÈÈnJ±"D¼Œ˜œb‚hµ•ýz�ŸôŸ1ÞOc–=ZèIP“eO …E–`1Á±(@®ŽÁ.n V)ßF4>®çͬk¦7ÁÚ =@/Ír´Ø¤-™0È`hGZïÕŽÒ­jrª¤ÛÅš5ìZÂQqPr¤Î…ÑtV³{Çßâúz2«èûˇ™}#oÈ{Ag_äÇi:ØøÙÂ.àm2VG"4hm¦7¡ù"Á,!–æÇ=¬ÍRÓ¼^Ö±ÓæxšUXçÍè§F²Ô¬gFU@‚8æÓ_ï½ÚUºUŸ¬>Ö(KSøQ<o¬™ÞDi­5Ixú4CO¬¢d„ŒiØ&#¬Ì™FB„ ¬ÌR€|eæ¶®UQ E_dâ:çÅMã¤É–ªÖÏ:¢\“ØÞT.a}gƒØø¶MÒ4`º]£ÇBEÔÚÍ;O?+9ãðÆÞpovÞ3)ÀXäp¹?"ôO¥¸ÿûÝ—|óîw¿°ã7E‡å Ê—N‹ï…†ßFÝùü³À†;6Lʦ™”ª}†ü䦸·ªã͹-vÛÔØsÇw¼ôÒK~ÂZM¹àûæCßühöG²ªp±SùI?ñ‹tˆ[äš+Ù³âR×;_*•�6­gÖ¤o‚% Ø1°Êýi¼·bõMÿ¹õöÿsthôøtù±{î¹áw(ö‹sÐ.ätÌp‡nMÀDª­J@“Θt²‚±ž ªoüÕ¼´6êõùä ²ýJùˆz}b©Ø™¨ºoÌŒ£´ö‰â¯ãÖ{Oz ‹£öôPººŽÔ]3ÂÒ6ÛR–äs+jR;‰NÚ¬œ±@0ËžõÌ¢¶–!K®‰z}«è“52åy�� �IDAT¼’>Å?¢v1‡±x{÷²B™eËæ-×óÖ6ÜËsûX&ù¦UÎö‘×{¯ª‹k­‚2Ô««S­eHÆÆåµ`:œEʤXÕBO/ÍÖ*ÖjÿÇmü�TÕÐÆš¸Êl­‚öóŠz}jÑW\åú¯2-Ð¥PÀåg•½J+f®F[¾&ÃB—«ùhª ²t\+‚²)`â˜ó-pǾſÞ|ï@;æ,[Ešïœ¯–xžýH"û\1}ÿ ÚÜyç]ö ?‘ý?5ÃÐâeŸeâ=Ýçµk—ûç/nQk“]¤&¢ŽnØý¾î&xp;ºvQ›”¾¨ šr–Ÿ9)+Äž¤»JÚ—3é wïi÷îg̘aueÝP1>pVÜÓÞvßs‹F“¶g'ýt*ÖtíN& £ž~‘W!³ÑëýæCßÔ{nÏÜÕ<yÒM‘«H”«¸„*Þ÷1]­}3uæ555º›Z¸ö1'ÝÁLN—¤7>þøc ™ÖMÐ~/½øÒm±ÛôÂwìx (•¸ù[¯UÏ™[8ô/ùÿ®ÎÎ{þÌš¸–¿í^Ü ºJÄõ*‹·Á‰ÖJS¹î±}]‡RÑäü›2æ.Ðf¼ºG'`ðÏ_ûšéUâ˜VÏÊÔ_/.¸RêaÔë³ÑÂÎÒª–RìW¡,;\é 5†”®1Sv+ÝóG4ÔÄ×ÌøÒOYíH»)¢¯™ëyS6­zœ,5눥ŽÁE>Ì"É(7°ã n<×24HåG¼ÌZzdh÷ß—¦ÅGh¯G¸»œC,ÉH^ €z°BDU™/#ßZAoÕ¶Ç®Ÿëdô¿]œ¶;˜"…¨™VZΪ݅”7†>­ºÞå‘S‚P„ŒáàTµÐ“`­í X?wC:-+†u-ùNN­l2\}q™sK©, N%‡óCI·a†Èüx6œ[‰úgèìC~›7.ŒW­$Çï>'vbó΃øô‚)€Sz3§]àÜÑã…NÍ´Î$\ùÔ§>¥Ä {X!ùððð÷»¾Ëú[¦cÉ­Ýí²N¬Û&Ý%¸këèèèD*ò9§Š rî8pæÌ™nïº"FcÒ%^O­G³5é;ùÛNU™sçÎîn¿û[ßþÂ^Ü C/Çvé+ªÏ ˆu hgN÷½º€À‰ãð\œBM¦&ÝÖ¸;†I³²Uk‘¸óMƵAolíßÁÈ4± ¥ ,,³‡dÒ%—*#n>J.EØÚĄͺ™µ•«‡©«(Qô ‰ÒZiS4EéK{ N†r³ëÅÑ xÁ”yj¡'QZ ôzcrr—}€pfå�…"Ý-Ì3æ«þŠßBf‹O8Jš**] (dUßÔ>ÙÃÚ(¹AêÔñnd†ú·]Ü 2«@PüÕfz—3ð7 AIT[¢L\·Èb°TµÅÔ‹BV½ /ÓBBä[ArÉ<¡A•tyeȨ¨v³:@rYê×óªP_ñdE 7s À£Æõ©ÐBZ¨éhu|Û¬³‡0¦|€ Ä6r9ÂbiáKV Æ ¤£ô¥ œ›¹€ßÿÏšÖ…™žú<4æô“ŒZ©Æ`öÙ9b4ÿÃ2?LZt,šY»\�¡ßl=o›æ™ªˆéNÓP'¾4Û2µCJàﲔʈˆP”(sk}XÅ I§³ä] C×é08¾zËW_üþ‹v/¯RÒµYÙüÍvõ<u꟢ۻÊw¶5ëÅ;ç‰àjAÅ­í¢©ÕÜÖaÂxÍŸzò)Ûsþëïýµ ¥;^Ú¡¡Ú¤ :±7{®¾<¿…ãîö»W:_9‘iÝãÝ礌šxçI/à 6™Þÿ©)ÄîÞ¨ÂmC—ÖÄ]Ȥ*̓u[Ôªs"ÅÓNÙ¡ÅM*“¥ºÊñx„•ÎW=)q-#7éØ)Œ9Y‰{,Ã0Z#¬´-Í09Ÿ»X²´ŽX€`ŠUvŒ¥¯<”-UYJ„JøHãÅ‹¥*³þ¶66Ñ¡äßÈ2È DUo3½ &k¦W vŽp–z{æÒÝGYš¥FT …yƒÔ­fw7´–K_Žðqæ¬cg/Í»Y-M=›ém£³—æ õOx›e b+àµ{Û¤]ï½ñ2Q¯O´Øl©þ+¥ÃÌþ"?^ÀÑ!j“4máuGŸð6fQ‚c‹9$ö¬-¿Œ‰?¥'ÕÇ'#!ÉB"ŒÈöÏRŽ #¬DÉ%_* µd£ä$ÊPßHieúyÔRîZg/nÌÖ›l˜sÔ8¹ûo¬I«0¦®@„éS‰YNò±.ŒæâÌùËI'–ÄšêÉ</i¼ã› óÖß±¹“~”–Wz¨qçð¢ºþ}9–—wt)6DÏ:Ꙣ³äܧTaÂÀøqé„ïg[¬¢Ü5Æšç£è¨ ËT˜ƒË¥Ì–85§óÈO~÷I÷žÊâ>S§wêcúºˆIÝ?ñqç]wªÕ,Ôt}étÛþ¤ó•ÎíÛ­'Ü,sh¨|ç]w^rÉ%ÖØuŒ³Éh“šÌU(RôÃóß?}ëÑo}ëÑo/tœêµõé­g½…¥ßBNõ'¾¼ïÛtŸK:s#ÕÄ™šš4QŽ¢Lé‚Cß7ׄ¸qÿ±-©Û’-ÒmÇ–ã'1G£VQ†VR~Þmýe‰eÉÃ~¼|¶jQd˜—7Bx‘ƒl7n$+qJ1ÍD9þàÓ+7Ö4«K¢äê˜1›ÎݬÞÄV5i{Ë4M ’ê£ä3c< ó}³˜"1µ²¥ÅŒìâ†õ¼™åõ„w³’½~c0h§§ëØ©æ­ÍŠr4‹z(³SãÛMlÝB·Ú°_ag€W›é]ÁÞ]¬‘ñP?]¥z¼W—p —æMlí¥Y/¿†‘.N·0o7+uO¡`#o)tÒ¦ ËÖI†d‹éToaázsž’âhs ¨‡‚•Ar)ÂfKV*x^Ï`aß1Çne¼Œ¬‰Ã¬Ä·þQY†Ä×oÈŠÏ̪õ êL¤Ø«Œ)žLÅ.$Xš¦<ØÖѨÇÝÖ¨ªj‘‰ŒÕF‹\®&Œ%ÊŸX˜•Ù²ÿ{’YÓƒqŦ– P,Uøýaª/·v*5 ùó_#\´8kjǹm··me»þ}Ëú[�·Ž´ÿªª*Uu<üÈæol¶Ø9i¡©EJpXSS3Q…2|4;U¾˜äœŽššÛô³æ wצX,Š?åþv [¥ói!L|[FGG'öÃíhÙÞß"ÜýÜ_]]ý0>ÅÞS-Pué_ØþÂúݳZ.œuW¤j»3ÎÛý£¢ñ>‘*5éíi§6Yûžá¢CO¶Óš�cYBŽU ¦›7¼Äng-¦õ8ëÓ=’%n¸'û£,-°2ëëÇ[‹tã™’±Êâó0³@ž›|ÛRLT”2Ÿhß$æ^¾…^9 ª2k eO–¦ÍarkééñE5+5>Lùo5~¯*B‹×#ˆ*zlá5c#Œi¬n”B\=Ñyrf’ª¬u·²é( t7º&·€£pKô&¶æÕÐKs-C)Ârý4)½¾®Ò* Å[‘¡ÞŽ6ß (l`‡ÎÊb¶z³jª(}A ^ÏŒ!ÿ•Žhí¢ >°uŒ“3¢­\s„ò’�Á,ɈáUuqB–²Už‰c)TYÿâñ»©2ÙRÕzïÕ~Fð2¹qצ?¡Œñs7½LΰR&ü5ëè@²ÔDÊÛzœºž·›$ë“\tFÞF=åb¡®ädvèæ­‹ž™nƬñÖxªŽ9‘µý+ýûiâY vWö¶ÛÛÔœü~×÷'¢ …L¡¦e Mª PÑ9¨Ó L#¥ˆo ™Ï>óìÃ<l»²SÏJÝnž~kKöó©V­\Ç'£n{ÉðmAæžÏyú HJ4ÅC ÞTO³"´zÍ;ïºó4SÍP7csÕ§«ÜË@ÿ™ÔyÒÂÝ–J¥Ol9é´ø¬æøö=9SfÙDàŒ!ëlÍZŸàf·íy§<ÅHî’“ËÑj-ImBEЏµ43¢‚&MÑ œ"äHÅó@ =/hè<²¢ÝÓ¼ĸþ[Sé ×“(­-–ªRãϵhM©å›ð4aE†´ÉŒ´™ÞÅ:Ì"ók#dº8-ñb`š†�= .8÷EŠ^XÍîªe£*eÕ)Væ·Ðk‡šr5Rhç~=‹œåë,R¸™×X®Y£$bE Ñ£Vj`Šp„‘¯'QZ«Sj÷¶„éï§1MC‚†õ¼)zÔl†S„eÅ0H„£ôÙÇ´¥)Èi¶hHÈDžR//Ú° lí&’9Za€±¢×M)¦ªÚÐ_óã#©Çùæ¨n¢Ö' •ªð,˜©èe‰hmð–¦Ø£“±”Ÿ,…2¹ ”õç #Ƈ¶¶KÊj«¦2æßxéš” ɼn³5Œ;rueÜçr¢å±P™‹[‚Ʀ9Ú´„–„ý­ ù³ò,¦_w–)è>UUUW]uðFÏ7®½±‚1TQwN4‰­8\]ü¤¦wö¡žíxxø‘‡ìñ¿ùà…Ý@hu‘¦ *h¨÷mºï™­Ï2ïÛtŸ Ío/È1Ñ:Î>¾«Yj¿»½¢4´m‰éØ D+Þ‹šc÷¦’w<iΛâRŸX­º¢‹VG ÐPt ~3ó7˜³gÞa!V|ó]&¡Ûž²²9Lm¿³=¯7»ò‚‰¤ˆC¬…ž„I-–åzÖ_Žý>X˜•Yò*:"ŒDjô•#ØÎî–±"KôOyñ�­F®ÖÂñ2Z$Jk%fðƒÉJ¡”篛"ÓŠ¬” !@³Î*AM€±¬aÊhéWuå[–{})ögKõ/“-…Â^f˜Ùpƒà'EØ8ì$¡)H®Þ—~ROÆ%îÊrAj–ëyKDÜFˆ0²—f�IB–úÕlKù\$½á>ÚÕ2$_ÜáÒËh£³ƒê2I þÛbÿÊ?@°À xîâ†(9È¥ Ëž­Æ‚¤éßé‡Õ¬Ìâ«D(…ðzÔZ·dWÀñÜ!ÊÒT™äw§› ½(îjIúÊa«¶²2K2[ž R„a¿ª´"ù(KSTA<[Fâ¤Égǹ(ãôcmÚ]½C|ÃÕ‡ýê³É2×({øÅåþ°RŽÑÆ9 [ƒJÓÉAWþ·o€0sæL•Vžçiu©§va²‹£»<Y?X¹�cÓ}¾¯iïß÷Û_Ü>|ø£>r™DštêU¶ÝÞvž@òð#?öøwŸüî7¾ó a§[8Ž#.¹(™ŽþÛ¿ýÛYïvÁ“¿*è0îîA¨ùÊ˯TtõÕÖÖº|¨ö»Û;^ê˜~Bê4În£õÓŸþô¯ýk—‡u.øô™¸ãvé£Îä}?‘$Ú*çÛÛäLt,ÇÁw?óÐÔ¢³’¿–%&FY!ÓKs€`€ œf|þ˜åGˆobÉ;YôX¤ªHA´kC£ÌjJ1±QRì· “e¦D½>ßÝ­Š0b¨FÉz2ÆOu$Mƒt‡ë™aN ¬9‘D.ärmMÓ�Mª8ÞX¶TßUºUÑ’ö1Î5!yÇ 2Ô÷±ª—fM eæ—¡¾Há-®ÏŽ’“ Å*&üt­±C,–¹`Θѫù9H²6å8ßI›6‹9 8ÈÿOÝ»ÆÈužibÏE‹l‰V˰c¹<(Ó5íùã`Óˆ6]àŸ±S÷G¶GãiO¨Ë!)R¼‰’%[÷»,^$J¶ÄcS=ãZã,Ñ`§Š½ùATcT‚uAjaÅå=–gd—D]ØT±(Ò'?žï}Ï{NUW¯ž|0ŒV³».§NÏ÷¾ïs¹Ey…Ûðö3øŸÊXbž6@!ç1Upi\S—±êL龊Ÿ‰[a5mÊ£ ð¢ùøŽ2¦ˆŸ;9A¼¤´´í 0ƒe¯Õ‹óz;i’¹8ßúe´xñUAä°ÄS'<†¶jóXA[3O„kɈ}b’µ×…”¤ƒÆº–’ú“r× ”Â&ëé}.ì¹äï%pbŠ×XSù"™n _)."¢«º®§ËèÓO=ýôSOøwûï�lúï6õW™¶F¼ÿýJºÿý–› ãòc4yYÖåU…?óÔÓO=üÐÃ<úÈsÏ>÷ܳÏ]£ Ò«Ë|¹ìDëL­¹mû¶þÏ 6ôÿ =3¹ß •2KölZ«‘€÷ßÿƒ>øàƒôM]¡Ðð5Pà»âÊÜrvèpðÀÁå2Ýú³š¶ ò$ŽáÕȺ J]¶ª‚ ÜlO ¶®£)~Ñ1‘ÅôÏÐÀFVue´¤3\oà”ŠáÊhÉS¸Ðcg﹑§ÃNøâÍÈž‹2¦[˜¼ o—ІÀ‹È¨ä¯Ð­m3Ž«É;�g¦ì¨S)HìÔÙ^y}Z`xTÔñÅm D.qSÌ`YJª›Ý|¤¹+!Æ6ãxKì—±D”½oá„Ëåðmüçó˜šÃE4‡ÙŸá«[q´€yÈ!ÆÉdóöŸÇé 9Á2\Òw¤6L€û ` â ãI’l “LС•T!9M·.Aéßb±á˜A0Ç•›UÁà@<ð\.f§hë¨,ªPìqG>ÇHe‚µ…fsè’Â-g¤½YÛì¶y]À²šÃl;¹Ó‚Ì#Ý‚ÖÉe”ü•±^Gäþ5öwU¦£ôScVËιnK7Çû÷ßÿèc¾ýöÛ‡_> à¿øwÏþIgŸ÷￟áχ_>|ë­·Þzë­Wþzžzú)ýúÅ^T2ꪾ5ÐYÊçÎ;wîœ~“€Í¯Ï;Ç_Ïøã1¼Š+Ã\ÍthwìÜñâ /ê~æ3Ÿù¾ð…/|á3ŸùÌg>ó™Ë&»¾öêk£”›+.F\û‰«gV®oõÿÊr–Šá3£ªâ<~¹˜šmÜ e,Óa¶7•¨÷à÷P%O2D±ç¶ÛãÕ˜°ÅÐyj;“naE2ŽŠôaÅ?¨�̶e›¦ –YvÏ’Ycã7ecÞ¿zŸ :Àt{^�!ÜòÇæpè°sXB»€‰¦+}È2o‰ =Dr:‰V -ZÑJ¢÷ŠÑD…:-LÒøž~LТQQÝ‹6aaw•Ñ Å´è-ÜþMüèGø&¯ Kó9|&D,Uù“4- MjU “lY߆·`†å{­6 mhÑ^@‡ êðUü¬³P èÌãt�ÂØw×Ê#üJ^+Œó “~)æâ»àÝD!&C ‡î#xé|^NQdÌB¼É’ Ô%JТ8ƒóèðLc Ëo$MTwQ 7ÕFQ†h_´¨LŸZ¡SFuŒ©^''¶P:›‡¹ÙtЦî: oŒ7‚8%®©¾kâÏSg3õP“FÈ哃†æ†8œ={–[OÆÎ{ WŽ©uÙÀõêk¯Þ·ó>bØ Ï¿°œd“\�{÷ìpøåÃì.^ ‘”ı립ÜÒžðÀÂׯe÷ˆö›:á#jjŽ ÷÷ïÎL7_|áÅ.µ—Ç6Ò¡æ(ñ{ï½7J~ËõYÌï¿Ô¼á­èV™Ò:€?ÿ»ó£¶jéÞ.ó!š-ÊfäÚ°ÜþŒá\�Ô©Øãî#½2H €¨àŠ$ŸÅÛ9̪+77irvBŒq?êÅù^œGŒ2Z"¡Ó<²Yr…B,бž|$¸öŸç¯4P"�°æ`IÊÊlãe,Ü vŒâE}aó8bRUŒ@õv¼ÅlÎN±0šñNÌ YÆtÓ )^U|²€M[ðÓ ó8ÝÄÔ<N7œ÷«m4pнÜœ¸o•±ÄʲÒÿ‰fz8µ ó?Á×{è°Heyº€M,ÚÈ�bñG݈ÒbC,¾„ø¼e,-`çš�è¦Û‘!hÓìkáNˆušN/BÌ¢¶^ÆK¥]xYË»:'p nž$Lc³CŧFnU0!íÓ`Þ•ÚìÌûé[¨®v}$²Â)—e¬ÈO6L"tùì$‹¬³Kh‹÷z±‡¼À¤/²ã(CêÉ¡Ð×ø­+Þ'Ê+ZľpˆÁžä¢ä¼®T–AòDžp‹âQœ—!Ù¼Š}EZ˜’ÙoÓÇ”iòÎ;ï¼óÎ;¿üå/ïßÿc>öÑGõwêÖ¯_¿zõêƒ>õôS7ß|óÍ7ß  ö¯kŸýìg‡´jGGÍG}ä÷µYë§sÒ]úõ;vîxãõ7X¯ZµŠ¶8,Žã8æ‹ùðÃ?üðClkÑ®5·­Å–Úº´¶¾Ö¶–È7™5:j>òè#‡^¿~½Þ¢™öìÀ5Ü—# œÆ$ˆ{PUvÝ,œ£^5ÝŽeCß(²Z/‰VøtAæ®H)ô'ß„#O±[k±‰7…¦8¼G¬{Ä}­È›š±1´¤Œiõ‚§GA²çÆE~ß}GÎô ØDi£tÞV·UJøõ: †�?r(0ÈÓÅ}�9¯Ë•I’†�Nû&sŒebˆÅ]ø„¯–*~¶FgÐÌa¨?›ÇÔ¾¦)˜›q|wlÁO98l 4ƒq&}æPhI LˆÅ)4jT’ÔC%)Ûwá“ð?MRÀ4š›XK«Bæ&,8ûR~â"ÿ„zÎë’ÁKU ¼àH¼‡ÁƒÍ^bm§o´¥ _•è›É†ãÑTy ¤d[~–£Ç N>›ÕR ê@]}ì‚Úr»jx�ûáEióFfš 3È�1 3¶n°¾Ä¤@bOø.tÇ àÊñA\tC ±Џ}4$÷OBª²²Îk¸]!jªØÿ‡?ø¡užËhN´y;0¨ë…ç_xáù´§ª”¢Ñ_ÆÀÖ(¼=üЧŸ~Ên¶ž0øŸ£�0»úó¿—¾÷ÀÚÎÎ/¿÷Ú÷ÎÈ‚ <QúÏ—�øàƒ~ó›ßŒBeºò‡žuìÈ63 %ò­´ìã<p03ÕqhMÔäê™§i¿†CÂGÕ,p*ǯŒ%v±Ì؆FµÎðC,öÐá~­\%vRc[·¥J¨›çrKÁjº‰©+Z̺uFånhèˆd¬Œ-`SˆÉŒÃ‹XëTpÒA¯ä«Ð8>yêØï¡Fxë¡3‡»ô…ÍábSÎð=.ƒV`Shn‚thQöZb.–k´©6YÀ¦Š3œ«•±TÆôÌÐfA§˜œla’~=?Á×s(Ì8~�|„ 9tßÂíªÍ 9ÓaÃ š›° ³ÞfÉZbã¨Îcj§g0Î#Ë<¦r˜=‚â=qÔ~¾´kHæšÈ;Ò/ãh<WìêQ©'õ}yõ™êÅyjCú š!(±sPÁDÎë61eH7$àÒ�(Js^3ŠÒ8M†¾ï‚ BÊ­k_—ÿ/ï¢ØF©Œ–<Z бe’ÅckÙ£ƒU—å®ùíÀoÁOŽÊk ×YèBÓd]ç¶jy€à¤çÝ]º|ãyÞ@—»:ά´Ô׿Bz2èº È¸Ð‘ôÐÃõ«fÿÇÙ÷Þ{#Æ!ûÝ¿;ª¨yÕÛ­Ì<é_û®ý£èÕ«WÌ 8À¥Ü(Òß±s‡Õ™P£ÿÉ‘íðºêŒYW‹¸tëRý¤N7[µjÕ‚lÛ¾M¿óð·>|èðÅ‹:|ïŽ{W-¿ì-ÚO³<ãÌ¡�tµýÕKþÎm»‰CŠã 6\N5 (Õ))7ÄȦXÈà'ªE+Äb­Ðñ€Š=D—Öòšx#bñÈ• ùùh‹÷Ó9ªA0 t·àØ\b7¿Ø@µŒ%Çzu³XÌËHɵÅbÞéèKV_èP?Îs¸5ƒ-'Þ¯7P/ÙÍ's’ð\rÔМü:~r3ƒUâ\­BA’Ñ&ÑZõ [¯m”Z˜oÃÛDZ™^BôX/ ÓÂdè Ó@iÍ &€NˆIyåØRÁļ]BûëøÉÏðÕê@µ‰© N615ƒÎ<j3_ÀlˆÚ¬šÃŦrN+hÚŒT`>3h¶œWítÛÅPs^·„vèqñ¸×-£½à¼jÑC¾‡¨o¤çp(ŠÞò¡KèˆÏ°â"HœïO.Q '6‰Fç‡ÕUk)(óZÑê ,ï¥.aA?ŒØÌù,=hu.1ÏK2Þ“8n¯.š›äS7Ö–ˆÁËhF¯‡ÅÊ2‹Ø©R~©©˜j¿²ÿýëׯÇ7ív»<úÈ3žátÍ>ùä“;ïºóÍco²»nÝ:vV_:ð‹NN:—“ujbÉðNéÀ˜Žkº®EÇÒ>æÚµkIò´ín%Ũäfÿû¼r�¢„ÙÿÀþ'_zòñ'‡ˆGõ13t˜ë¼†Gú\ùÒÌ“‡¿ý°–à£Ù 9Ïóœéd‰$Y)ŽÒ6äu“)h¡ g|vh xJ/¬†I½XTDl£Ðp|¢0!Κ¦Mµ…ÁD$ˆR "õh+Ä" ÜéÈCá&-Ü$Â"˜As>éŒEa\Ìy]8f÷åŽ8i%;uóN ) 7´¦œ¾s©’˜Àµ‚¯—±t;VÍa1‡ýnÉô h‹qnˆŽ´^óœ Q€ÚG/ £„UÍ)Ëó˜êLäÐB³€æ¼KïªQ"IÁÌ&,ÐZfô%gS^ka:‡°@ç¼9£ `úæ<àà0E…Þ7�� �IDAT7-]V+;@Ô‹ó¡hkA¨Xpù_qÞÐyºÒÌ*˜h%îy ñßp"NÀo£‹äf+ªrÝœÜÀ=G"#ï,°¡¶åM, L3c:4wšœ¢9:TûæZ˩Ε˜;œ‰§A/‹Ðõ¿>¨9Pˆy+ˆ±ŒµÎŠÌ”;ïºóõc¯o¿w;Qó[}ë=¼ÇºÇ¿çã?>ø7¿ù—ßäàSÕè–,Ê~õ£Ã7_b¶Õ¤^S$ÀòŽ3W¾Vì4*dxéÀér2P¹8œ˜j߬µªXñLp­ƒ ¶mßvË-·<ÿÜó;¬[;¤I0Ê«ºaPÅé Â7cžŽÎ{B,Š(Åm¢ ÄSÛùÇæœÐº+Ž?(GC'=š>&Û+3žf¹Å«E8Ûkt\£ôæăòDZ¹’2Ô½âÞš×eÇ5çu·`Õ61‡DÿµÓ)¾ž# ˆÔG Z¼' œwЙA³’²<HbÍ4…&ç© œº'ˆyLhÈèf¿ o«­Á šìšöÄÕÏl½nÆñ&¦(‘…«ÂÓŒ“‹KbQmŽKi‡ÄË2/E°Z®svËÙä<¦Ú(q’]Æ´\®:ç—¶ö’‹Ü!7§\Û BOìËéį`BHF-ÇEòZ}·_µ’³GOJ[hÇUØN< Ìà„¸wu"nÞTÒð/À¹Ö…S%UÕŽ2‰G=gXJt¢³F©I1ZÓ1§ äÁ¬ƒüt¥!3’ˆÒî—#â\®mxíÖz³>ûÙÏ~ùË_þò—¿\.—Ëåò3O?óÌÓÏ Žøâ¿8Ðf]ùÛïÝþú÷_ßÿÀþýìç’Á?þøý÷ßÿÓ¯ýéþúGý`ÌJt¹zt¹êÁ<4¸ífÖ:Yœq²}­íñ‹C× f.„}-§)Ÿ^:pà¥Û¶o{ò‰'Ïž=›éµŽ^nꇨibW«žVÑH¦ÎÞþ®øè,­]»w=ÿÜó—|0úŒ3’´ç€LÆÖ§%ÞNE.㟈;¯ì/ôÌ›M§RT©Ò“ý+ ¶Á ,C,’?²Çz¨1“D&CÕTÏMú`a< }E×&g²Œi󀨄x‹³9|˜Av¨!xA#ÞÈ )aÄ>Ó¯z¨Ñ Õ'} JhÃ#o³bŒ”Iÿ�PeŠçÛ¸ÓÁ &è¨7‡¯•ЦWÀ6Í`œY²ihàÀJ”¿Èž-%+œN¡y;Þb–Ë<NoÁO‰²Äã:?ÃWÛn¾X]&èªN•±Ô@‰@®µ¯%'—ÐVÆ“ä„ÀÌë„:ÒŽhAÐÄTf>׈7²ÓbŒó?C«™{‰,îbzÄX-cZP3’“\Ãì<NçÐ¥RSš¨Õt#4߆¼²véAQÆ’J­–ƒFwÒÎ"»ý&^»@vR¿1žúºö¯‹ªŒimQà6H“êiÈ 5¾qtþ‚âÇñˆûÎù‘—ÝL?÷¹ÏMLLLLL|å+_ù³™?ã?mõ·yõÈ®ûv]Zñ �øWñ¯~ü7?æ×ßüËoêHUKØ<£áØùƒàiÊïqõ³U•°ºœŸƒ®×¿ÿ: &û»0‰Šî$Dzâ´pग़¢i”—´®.j®¸†¤³]êؤÍ#8]Q{c_«ÊÍ/ÝiZÇN§ˆLÀ¯cØ£ÛsíMÉ«f€¶h~¬XF ˜“ÉhdÎòh €<y÷Í*{wšw¢ÎÔ-ò3iz çU‰aÎà~Óëæ€yœ¦;9c¿nǪ9Ù6�ÄÅy�^PB;Œýœ× ¨WÕ@|ÃLj¯=DÀ›´ñóCŒœW`-Þ@i~vcìm–ÑænÞF 8ÕCg§©0‘6oI¡KLt°ÔF‰ž1.`Sø*~–CŠÒ9LñããDó nbˆ#µ™9‡‹®=^Ä€ê‹\£2ž Á�ðS„2¦C͘‹‹e¯UÀI Ý€_F‹å/ëþ¶‹V…†Ø˜hh‘CùY<«I›Vj•¿ÇçÔ«/L4‰‰­š!:µž]Éÿ‚œÉ`¼ô4Pf¬ ÔE±Ö«*UŠÀ&µ3ÈðÆTMÏ,‹éÖ®e´õä¿"v*d’Ëz÷=w_ÿ`ÎåVx*<þ<|Ó÷MÿÍÿæ/^ø ¶aÕŸFßó!êð�€}Zbç¾û÷}ŠO<´uÛÖ%,a}êÀ¹Ý=þ=¬8ïØ9“î¼ëÎÿ¤9°m«"ÅÌ:ðÒ;wðÊ\ÄE2‰¾÷Ú÷ˆ;v‹–›êy^†kmA…_ó5Ä}"ãþ´ðË[¹²öUþýž½Wwe+Ni¥úCÍÞ¦Ûûb[q&óJµúTeºTl©Ò`l <ø¶Õ-•q›ˆ1ƒ4 "VÉV[-¡=ƒqZð0µ‘•+⢋ã«õR=PžÁvîql¦Ø†-Ü N6pʽM/šÁ¸Hþ‘¦Cj¸1¢Èš9Ô„¶S3h–½¼¨‡Î#xŠÀa'÷h¥æ–Ðü ÚÏáG0CIIKò–C,61Eu)=ú<¦¨¾?‚™MX`KV̓&Ñ:‚™9\졳 ÔÀð\Æ4e9|ËMLU0ÑF‰EjˆIWg{Q…Œ;TP“&�^Æ“l ‹×ù¢rˆØÆÏIËÚ‰ˆ¼HZTOÖ+N1R”N>¿HÎ[4,äU:ŽÍÖŠ5Ÿfvòbƒ]¬ãlQ£©ir‹úfˆ=e½Æ E¡¾‹@JÛªéÇ Ýh­š_W€¬rÆ_O'µ¦{¨•±së¶­[·mµÙ×g-—ÇÄ5>>>>>^*•¾ò•¯Lÿ7Ó�þèþˆ=[&<¤¨9¼v±E'›·¼åO«„£o½ÿýý=Ò\.·ó¾™d’á…øšå×µ@ÍÝ{v¿yìͨ¹ýÞíýuy;3ß\Ž ºcçþïZܼ8J!ŽÍÒjØv³o¼ñÆ 6lذ}ûo¼q iÜâ9ériÃ5¯ð†ÝrÏHʤù& ‚îo¾Œ¥Ì¦ÀN¦RŒ±KQ¶u±(sÊUéq£ùJìSZ¡ÎÇw„ñd í‚ã’ˆT òDª@çCKüæRèDÊâ7íc›Ñ%RÅÝFæEnÂç9—¢Ô ÆS{k\dIDÝ=]zè”1MOÁ]˜/c©…IÞŽ·xõÈÿì8¸š˜zóíþÃä.|¡#Ÿb›(TAS´ó8ýneÿvæ9Ì¡° Ÿ�E½J2Åt.;̽8/#äã¾y¹*h›+!öÃxÒüÒ§0.†S÷`^ê¶‹sR"Qå:õ›çü§&¦HÿQ ‘¾«;là9¥6CVêC¥ÎÚA)Jü1ŠBʵ¦‰Eé‚D†7K ò‡8ææ, òiJ]Nf‘Ì5õ‰êÈV·‘iD'¾Zîœj…(1êU¸q°Üä®qáÂfaæÍê7–[îh¯MÂá¤|»‰Ü»ã^5=XqýÇŸýGW"G‰y¬üîñïþ‹ê„ÁÎëÅëÆ]Gí¾?кa K¢–kd÷£æ@^ÿ7;¯:.ÇŠú½dVgf̽^¹åÎ-[îÜòÆëo,wÊ¡,çÆoìWmñŸ¾ûâw‡ßç,÷ÜñܱO£4Â*l »dÏ&âÝKé˜B³áXEhR¶Ò¨¯‡šü+Ú(1Fc3Ž÷«3^2ôZ‡îe¯‡¬K läH’0,oþ š ˜í$™ÆÕ†hUª4Wý¶×Í=qMã›Ãlˆz³9¾µØQ(CŒ‹t¤ü Q§ýÛ”ÊXšÇTN¬�æp‘œdF…«ˆ…'Œœha’±‘<‹´±•Ï.B‹Ú<üº!Ëî1ÛLÌ»t”ú;¸˜Z@¡‡ÎÌ�3H§vóÚÂ#öÐ’°Faë||­ËX¢q]@ÀïØ\|—›Yz‘ˆ¯ˆð\B'oj]Ô¦€Ñ7m€ÉQ.I¶V,ÈÜÐ1LrBêÖ<Yd’вhL‚ÂRmm×T$+¼—,8Ei¡HÕøÊn5VOæùt¡ óçP•î´ŸJDIšu“Ä7› <EÙâ‚oÏÞ=KXÊ´ÔF÷B»¤\5׬YCéä§ñ§Ä‰/}éK½^>´üÿµk×Þò™[NpúçŸþbηÿýŽÎº.éÈÝí&hÿ“ÍUÍ€TÔHñ˜Œ=pYþçrÁý£ß¯˜¦p_Òu~é»/):²[Ë–AM}Ä툗{÷íU줂¢æeH>ø“סÿ¯·+Ÿ+s݆¿à‰fsoÎ sŽøÂôD²k÷®ßýîw¯\qvU³‘æi˜C]Ø­’³P½”[[ÁIò .$°ý« ÚÂYù|•Ž**™Ã×=ÅÐe“ÍÊ`µ#\•xÐÀ)&QQO’YêfWqžtžòÊõPí¼8¤×Ë^‹ÄÚžñí›Bs Võ§R m툊µ«xhn°ǹ{R­_@G˜™.dTÜ௴Á›C—>pp»ÑÔ ‰H…c¦†¦ @•®~ShÎH¿—¿Î²rãSh&âÂØ™Ñ÷ЙLJÂÐe[Ί'"àEsø¼@;á@••=ôgWÏa¯ÓƒVé=t„nqö E¤XœK„–c5Ë8€îóÂã°Mll}i´Vsè’µ$øZ,£Å†3oEi’×­#¡ðôOé£H¢uŠRa\#æuàD ï<ªcwê_Iµ Œù­êóð×ˉ1Ä�AQ3ó}¤9\»ƒ?kM;[½¤•a©,g¡ÀºA ®Ûïݾ{Ïî×^}mÕªUûØèà!ËV]ng×Ro uœ%Ð^£È”!.]xðN1ß<öæÀnmÿzøÛ¯_¿þáo?üG¾aÛêóªÔš£�m¿‡Ãr¿5Ї}à/®¨³r:d¡I{s΂F‘oZˆ%ÊyåÈr÷ê Š3Î Ó¡®nï9z±ÏíÚšDš‘LùPº¯ Ô¨ÔöfK¡£P¢ç+ÞɆkUE²ÅW…ñ1Flk8£v–õž+_JSh6L,¨¼`T0ш‹“êUf¼ Øiò¡¦0ш7 €é&¦r˜* É))ëÝ’7ÆÅ†4/©TA§éè<I%ý¾ÿsüs¸8‰ñ DZyæêG›(Ì ÓA‡nJ@;DµäªÞj ÍyÜ!¼˜{›׃í†èä�W¢”ÃÔãxòÛxATÿ,ñKâ)ßQãk»Ççœ ˜ñY.D3’b×µÑY ͶQ‚óÛ£j6*¡=éXÀ¦^œoH( ] $ç™D!ñ—pd1eñ�(¶ÑM ‰¢#h£,J¹™o£ Ñ•vP [J Êf{ bhP”L¶Ý׋rÍóœl˜4s¦§Â·ÎP£t1jg™¤ËEâDµñô`òÒ›EÚ !0GR÷b¬4K'šç×$Õ�;·Ë1WF1â˜m”hÆ—¿¼g磊¼ûî»�ècÀÿÿÒ—¾„ Æoÿ7Ñ¿á7úÖC™'ÊÌ3IËúôÓO9¥dåÀK®n3–Ø90²x¸Íý@J‹­˜Õ~ÁþúrsÊr,9ˆP:p€—ù±óÙCÏ^ZdRÀ“ô‰Ý*vôõÜ³Ï ¼3ÁÚ+–ÂÄN�GÞ<Bì$KhÅÏq`…z gºUui…qž­¤‹i‰'”ýO5…™KÙyŸD‰Åy)ê¶"¿RUWq*§Ð”ß­RÌ×CM2œ«@àJø!隨e,±‹;)NLḨ fìS˨:üÒO’·o™ã‚øTÆô“xü-Ün¸—µyœ¦;ß $ðrŒãCÖ  ×$¿TŒËóŽ—ë�©Cß;¶”ŸÄã¬Æ„\%d5°‘"ÑãØÌ •\ª9|Mu“hÑÏ=‡BÎëê””5PÅ;™fAKÏÓsY"ÈÍ'‡!>{¡„6Å!ì:*Qˆâ RˆI–ìe´6a¡oHiM©Z0Þ=e,±–‰©E/}ûÎOgÞn©‹•ª7ìBKI`Ì}|óøËsM†Eóÿu“И·Œ– f$Uxd“; )0*gÀDéÐìÚ(;þÔ±VГ>©:KI-hDpå4èüùó4 ÿøã?þøã_þò—¿üå/ÿîïþŽCM»T†OÌÔ´€¡f»÷ìfͺÿý—áÄvõâµ³—£†ÇÖÍôUßyßN-…M>Âþöë¬Ô¤õk[Æ>tøRÕŸ£,ò~•4ûlxO‚¥Þ%U‡Ã‘¨y-¶}G-·TÍxˆ}V~öÜ 8]³±°Ñ%O¡¢Fu#%l·öbŸ3³·q[ÃíANÊ&Îஈa)¦ Îí…Å_€›tVÅÆ(˜B³o”AQ=túËÅfáê¶)Înj°çUY­Ê ãÏ—\<Ù,‡v¶‡Ú$Æ nŽkËkW%Ì; É){5QP·šª,¾sÀmøiSmI+  ŒÏ»úõT'¨5Åà·‚‰"`i­66õÐaµ‰) L”оo}„ñt hÓ¡ì¹´¥õ{@4öE³VˆIÖ‚ ”r˜â“²fu”eo©àLe–éªÕ¼êwéuŠ'%´«&Pš¡Aeµ26´j"¥›ÿœS+Lz½$ '3³ICÿŽOcÅèä»ÒP™Aü"±iý7ÛK¥XÛ:ÕÝîûmxÊ ð ÿ’YfMEª†j„ôIt…]íGµ«¥r#jîÞ³[mö–[£”¤ºÚí6€‡¾õÐî=»?ŧçÏŸ§×Vc||œ>´„Fò†vïÙ5ؽg÷—X¸;_>°è^­Õßi\ZZº¦Ó>[BñÙWÄ¡/xìñÇ2ß|ìñÇ>ć™o’ì-ÜþzWkåçš#΃y¨ÊØ3ÑÚ‰Ð8P?ªGLõe9â™f×î]çqþZèRú€“çÄjÎ9ÄŠg šq+eÓ}Ç–¨3A™`Û%W3ʱÆ“sñ]9¯[FAôõfÅu¯º nBɨ©Õ–&4/5�M’5Ñ%~‹ÍžOcñVÌ¡ \ ½�±_ò¦CL²A`­í5/@\œòN61;Z›€â{b6{;Þ’°ÒN ,N:7ƒvyT+hwÜ™`X5…fWú8§ò6ÛÅ t ”Ú¦›(ùIœXÀ&i6:ž”öiC ‡M:UËîQF{ãór˜í ½ÇçP%W¨ƒ¥6º4Ce¡Ncá&ŒÇžÌ`|>žgA„^”7{ÇæR®=uÞ9=ÔÚ‰*©¦‡0Â[ ×unvÔÑrÚ&:×é“=T%_b1ÁnG þ>úAhB'²”ÔXѱêÑŒ.qÉ©9ÂhL«F¯lº@X5‡¯©Ñ•ÐÈE£[òy¿XÓïÉùOŽE)vûml³R¹Œìdë¶­dØ^9|²º\«và¸T!ÍÚ‘Ó=üý÷ß'kôý÷ßÏTZÜ"âñ[n¹E ܉šûîßwnü‰ÇŸ|Ây«ö¯ûvÝ×Ϟؿ=ƒ3ã{>¤›—AÖk©cccË9iíþÔKOe¾sॊ7ú‘ dÛ^‡•áÌEcAi2÷îÛ{àÐU£fÀ5à ëÿ&oÂýv>×uNðÿ³ÄF ñá´?ìŽÒB*@tN +Nº¾HÂaϵ.OÒg6àØ\|¼`UjJÍWШ²~dëIlÿt¸ØÀ)`£táª�<2 õsènÆñãØÜFbr'æ±QÕ÷¦"‰q^° Ÿ‘íµd¦toã¶I´BLÑ‘'‡© ì ¾S„4m¾Ñ”@C(N¶X…kélÀ⻄vˆhAªa Ã—wN<ƒÏ—Q€›7wLût¶€æ$Zœh¶± ¨ñÍáke,…(6 f¨ž–"Èä“tʘ^@‰…;]&„QÍ%å!°ª˜ÔóªÒj®Š™@ЃD Ô¨‰ºpY:Q Å’Óø*;6M˜”þU©!sMšd žyuñŒõéÆÝ·bqµO+äÛjº"ŒDAšrH¸JÁÒ_ݧ`ÌiM™«P$æ‘4Û¨c2™©j‚”¨ŽÎu•Ä d � ¬#mµÏÚõkîPW‹Dc“:èoðà>ûܳ„Xm²@ÉçóËy¤ ÄÎßË‚£Ë%œ,÷¦2`Ùß§µ®­o:êñ;ÂlW†d;J7ð4 `¼b©wöìY~”™ºÓŽßxý~߆Ç_IŸöÂ… Š| ¼‘¢&ÿ iËý4-*gþR†Ï8ë2›ô¹‡¦Î1dN£Âp_Ük©zÌkê²A8�E€úbE[>Ìcj.¾ËL›"³1Õu»>K¤ IÅ$êØ(Û–ïöG¶ ãIVŠ4Ez·õgXÎë"F+q„IšÏb öb+P¥šS経®œÇ©­9™ƒ†£Yµ®nŽ}IäöõÄ ƒÆ%k™>:Ø+ÉicÒ6 Oà:áñåm+h÷§ëžÉ›ôi¤ >A-Í7Íy]º[ðìÂ<P/ Ã‰µšNè^Àh¶ ÚòQº¾«r€!°a>ÛûÇôfùURUž!¼3÷[|›:Íœß^\4™ÏºÐ�O<ðÊX²Î´î;ro]*HÛ•­êá@±‘(jbµp/fªL÷͸(UsúiìTÔ †ø¼Lñ]Ní~ÙËnîìw‰S ;ìüúYÊâÉQ3 àÉ'ž\³fÍÍ7ßüà¾ðâ |ðo¼QsÍΜ9óG¾“¡ ÄΫҦ~ååW.ÉÂpÄùh?»gˆ±>Å6 YÛyßÎ!vu©hÄÿ©ã«eº2óÿÞ!ÃÑ–{®Ë¸Câk8æÜÿÀ~[ /--Yuïex©Ú<€þõâ /¾øÂ‹—ý·ÓœÕ &Äš@œ¬=Ñh{¶•x^›=Å™sJÖ£ëµæ0 DÒ˜t³(c:cÚ"m«ºpR(‡·T”%e‚8¿=` VYJ…ÃP„û½8¯Fð¦9¥XËí˜dm–kfWíÌ»6Uo¡Œ¥MXAX¥ñ¥Îák|‘!Æœ‡�+¶‚§ø“3×Ô0ª*Û(Íàœ&²Mî ã©Yºàh±' ò­"¢ýŒH·aÔs¾Œœ×­ ­æ�Ô…ñä‘xb¿SŠaj:øVF"›]=ܨa½V¼OØyéQÍÌóèàˆÊÈ6Eë=Ô*hËùŒÚRö…MæË *G"*¦=å –~%‡÷^$åfGQ\‰lfbZ/£EÑ”ž r'8*åf`ðOÀ>Î0¡¶¥ÒÏëòwËJ‚ÅÄÕ’º÷‹%NW‘&óÜóÏضuÛ¶­ÛÞ8º‚½‹µža1qîÜ9ÅìÝ{vë×ñ ecJµœUì'd²K<¨.oýð?$Ñi9r¬…L•¨ò:뛿¾â#Œ²V4q ›YšªH|ñâÅï½ö½¿õ Li••¶cç}ð±±±½ûö^F¹9<»ÔþiX±ÖpL…Öߪ-6]<S ‰ä#ì¼ Œé¶ƒ·@6YÛbª‹ÁiGæ„U7büwÌÐYwé†a *Ì®Z™ÇPýRÁɆÍhètâc�t¼‚: 1V,ttsÙ)5é›ù&v ”ÔjU ¾ ó¨r|z\ÌÒ$NÌ#"hcV˜>N…¨–%e³„i`©€NÃU< Í,?êÛñVˆ1FƒcZ€–ÐæDv3Ž— 0*hÓ_ÇÑ#˜ Ps—ÔŠ„®ê@I¯1í„..jŸZìÒrõ”bSì¹ÏÂîqChÖÄL�ÕŽowÛxQ…,Ì#è �œÊ9„1¹%´ë0+vAºP (IbOsÚ´‡k¤ MÉ9ȃ#Ĥú çÍ’¤moZú4ÃU‚¥”Úbhg¥nÌï÷Ò¬ráœm‡9t£¢wùB»³i† ØnÒ7Þh±sÄetЇvWh@ª¥¡Ú²?úØ£7Üp€Ä?ò;ëÖ­³ù Ãó«û9M—÷ÂöÝ¿/Óå«qDj/ËØØwX›�zñâE«àõ£¯ð·úÚÔ_WÞ̃+XfhÆ+.6ÀìÕëõhü›ßüfÅ9ߊ~°£ŸœvìÜõÃØ:DÇ{ÈC– ‹ïºû®L“™tâ{ü{Îã¼Ê±øIDºò³fµFêÈGÊAl0†X„ÛÈì°S³ a³â4ÔIÓy¸»ÍΠ9/p+7S=G8 È4É¡dæLâ"MÛé7ävvGñ蔽VF<InŠ/O]‘æËh…É>•±Dßs þìTÐn¸1XÔÒ×#[¸U@§mt…ˆAÍrõ˜MÝÉiIç4è0ƒñãØ„D•Ø™Áø<î艥¢î1 Œ•±T@§ƒÂÏðUÈ“²mH—Ø>â<¼ 1˜u•YÄYò¼›¹:Ò¬ž-ÜupÉ6…ª´ÓøÌ^r0šXÕ˜¾ÖùD²ZTæ„( -6qT"w‘ÝGßUû~`¶—aB:¢EC®¶^êÊÐIì~fp"Èz5$JߺùÉÀŽ)µc{Æ‘¦h:Φ@Õ«âu`M\{˜å÷høIÑ=¦cì§Áïþ%ýõ<�� �IDAT^ö߆¸Á‚LkÍ[§-;tðÃo2·$ŽM À™3g8Œ<xÄEšdðiÈêOA9úÆQ‹”úõ@³x}‘!piiÉßêGƒC]ÝŠóØ¥h [}�ÁÑ 4EZ½zµŠb‰»ýW­ ÇâëÏÈ{»Ñ2?ÿùÏóÓä™Éd¯Ï®QÃ?Ó£vÞ¯¹ì»W»ô÷×ëñ‚+|²ûºwßÞŒÁúŒ82óŽoþå7u 2|â‹A±b<’ÓS·ÿŠ /LÂYÍ8*ã<g]ž"TÜnëÚ¶Ò» Dõè6,Š)¥Cëòžh+s2·Oõâüšláj(&Å‘m”š˜šñNè¤Mª¢ *(hÐCKU-v9òœáËc '{°±ÎS;®y’™”„œ tfp‚ó×c|(‚æP༳쵨OÍyÝ&鿣¨3©-8¦ÎD=toL›As-Ê(;NÊYl`£¶F¥Ùzé!v£MÎVËžku² ÍSß{§5e²ë*žf¢Ú,ò<ÁOЉ§Œ¢”ž|‘n>ÔtÊEž¨ MwYiæõ°Â{ äì‚óé$׺dq·Ô¢±oô-®Z•[‹oÇÉ"ç%(FÄ Ó2Ôô©ºf¶ø:Ñ·®@„SsŸ>y7j jkÊ:=‰\4Bl;´¾ØÁL:«™îîÕ]7™u-Ÿ]¯Lï«¿¾¹o×}üðÃ?2‹CMŽB3‹Ìuy]ZZ²,7úÁ^RTµ¿Õ÷·úËYÂ^ö"Xf¾c \µ¼Z«P(Œòc¹ôZ»Ìâçb¿hv?÷æï+mÛ€3vq/éÌ7Êt“¼°{wÜ{ïŽ{mÅIøTÔìÿEÖš–¡–a ôÿ™ éÐ <ýùJÍÐΘK,qve‘Òl\§Ašï µè# r»ç’ýTw ʘ%¶‰Yh'ajˆ¾S«a$Œ'{qžIË-0M³nJœ¤ßHŸq¢©¥2Íã4±¼A`ðNéb¶JÜÙYöÉû­mÁOÛ(Í㎖ãÄÜ@}ã0‡»$A¥ªÌ”f°‰ó3Zܽ…Ûiòî\×eªÊdè&{³ML•Ñ2f:¼nõ4é¼ZöZÜÖÃxžN—Ý0Ò‘˜â<k_ Æ“¬ÚKh‹CoAÿŸQÕ" ’#ƒ3az¥-8&ñ«tÀ¯º°”ÄRp¶‚Ó2¯´Ú“Î-kQpÈ®Y(ͬÁõ¼\ ãL¿Bx++/H·L 2eá¥êBùÇ6ò%5(Ã÷Q¾R^>nßøåÒ7|Ôט"hfÏR®Í?…ŘÌL¿šû+‹WøDV{3ê26ëý.w™ë¹{Ïî~TDzymLm:xh9Ô´\¦|ŒÈ”!-‹å£_O¿Œ1öˆ‰žŠ|"|Zwu냸ïþ}7¦‘ûôéÓ.\xõÈ«ÛïÝ~áÂ… T3@æ{¯}oÛöm!ÙÚØ*'ùj¶jÙàÚŒãs¸KÚ˜4ïˆH5,¹9hÚzÆiXOôÜ@®cF¡E�â¬V”ÍÚÉCE§¨In²šÞlÏÓiP×I&„ƒÓöº$…î‘YQ¹vÙ&,Ìã´î_dêV¼“43ÇZŽób8îôe,±¾,¸êÓŽ1ƒº1jX%:9LlÁ±9tœíNì÷à‡^TqÊ™iºhŒ%çm“h…¨†@YÜÒêÛh t˜k&ó3ç&8/ô«˜ñN0ã…fÁjò1y»ÇîãµBê…\ «êˆª�¨W€¦Œ‡õ6 $—Ñ’\U¼…Ûsig1ÛCuÍ…Ù€¥ò»ðò©§#±u N™‡6Ùü6VpR±™– z‰¢©(*?PÛ;­ÚpY3_ DÍ‚t ‰E»Ç+é§3´}@D¢±~hTúôšÅ> n}ˆBf)vÙõl£r¹ €Ã0]ùŸìÄAëŒ?‹ Ô}ˆ†Ä›6Çt¶k÷®«%Z}\Êáâ¥V¢Ç~xì®»ïªd¨¦mðóçÏï¼oç¡Wí¼o§¾G«>$_F#3ùÆ­ùÙ]£¶½‹F§ZÔÔéÀæµë]\Û¿Vl ð–Ëçó|#™Ì€5kÖxí�‹]|Ú7« ½æCÆ Þ?ûúÿðßÏnûÕo?úäãþËϜ޻÷Ïô\ìvXªÇí¶¤8é6WƒÙ¢Ù¤—¼ECÄ€�äF:Q3Ã*þë©\b†À,ŽÀê™–ìœk’êVø ®Év«Ú5¡¦˜Þ1µ\®ëûuߺ&Ü˰ § ¯’÷«ßW­'_ƒ{㱩0<cš*1Ñ<ðríÂ'?Á×Ùö”‚OÞl2”ÍKùÞ¢qAú²ˆל�J€õ㘴YN26ΧçÖ¾ùϪi'�‰^È&v%ޏú\w%äÄï#—}y–U3uw¬ ³F{Îö §Ýió ý2Zäp!‰[™t/#AMÛs äÕ"Íå©h0hN¥éH¾éÜÚ7˜|ÇÒL¨Ã¼ï¾]¶[•95÷§2VÖ®]Û¿]*Kh¹ñáš5k´òÈ” gΜÑ}G§PºïÛ©äÙ³g­ØT·-în¹\îÈ+G2o¸á†~HËçó¦Ï¾û÷ ”Ÿü¦5ò¶Y¡äæØ'ZNÔ¯;;Ñ—‡Œ~àì œ‡‚8i\>ðíðù\Ÿýìgœ;wŽç¡å”£0ß)`íúáp pòEò£×ŸÌPÀx­~:¼6CËèJùWÃ;_qú˜öä18õPh)x�x @ã›OühÝÍ·tÞù£ÿ§9ðr{nÖ%!½®²©h`ƒtajn—¤¿BÔg0>/¾qÒÍK¶`£Òsdú ÈÖƒ4“¯ª•ì˜T2û¹ÑF)Lá$x½Äf–àU Óùû´ãØ Ü¥ikBæ HªduÛCtN¼„¸³WÐl TA»NëôtšÝQƒ»€P.2…&Ð™ÄøQa3‘]Eϵ@’#H aÒù×x-c¦S QÔ=ó4ð™ö RèWiÂbŒ ½8_ñN6QØ„q2}x­ìq§ì|þò•0Ý–ƒN­Ð¹ðÙà (å§³hŒ¨�PáZR¥“IK¸¾pÄ¥Sp÷Rò‘…R_–“"Û—_¤P R”×C@¨ÔÄJÝkí]Çï„),”bTÒfà)òE–—› \¥‹ã÷í Ìu)²¸¹èa‹•+äÊ^jûN‰—±z½ÞÖm[éÙŠô·úq‘»aoû½ÛÇÆÆô}z9 ïÂuZZZ ŽÚ8}íÕ×´úäoõcçzh¹zú©§—K‚j›Ë]a{*"Ò\ÅNþ@Ô$ñãÅ<{ö¬=i{ƒÿJÈ\nMü[î5¿ôÝ—F|©|=,ÙZÔòBõ?ÑÀ§¾$9J=ë4– ixâ¶n|³rÌoil–í6’ÐÍBÕyéÐBb{ ¥‰?jXLÛâÏÆ2Î6ëìÔS™&B2ª¹b§Qx¶äÂtä"ÌjÓ¯£/O”œ¡Œhø¼nç‰/áÚÀtˆz¨¸_„;š—ý½CaOˆI}ã9Ìö¼ê”À­ÔC;·@ɼBä¼®ˆyг6@îò. „H" jeIÉn¸7Â+S'á€lWTyôõ=œš—T"PÃ_Ð(±6ƒñqâ1Eš¢A ’~©ñI/:ˆ»ÐF ªàdCÕP)M•&MpÃrƒZ n¦³<mÏÖØéÍÝn:0ÀŸÖ¶$°3 àƒyØzZj’ÁÚ„¤óW©ø•žµÜ³»ÿÖm[=ÏSÒà@¥Ýš5k2ç% ä./G'w Ü­F”  ,wÞ·³¿RÙ½g·ÅΗ"¨¢r¦´Uæ°þ+ß™«ßþη±>ÁÂÌ¥¶u¤>ÏëÖ­E›±åÎ-Ã#'ízï½÷®©Ë®­§/‰uykû½Ûí AßšžW˜-sþüymïÀšlQžéÁö·F¼h RII/Q‚”%ƒÔŸ¹•iâOQv´¼gœÏíxË"L줊Ï%d°‚!1u—÷²Š>5-™»’Jì­}AÆ]¨‚“¬Hz¨‘âÛF‰˜¡ð\BÛ1o½n[ãžä%Q‰A« —G†Y8«Û1 - ³?¥CÅ;é2GQ¯`‚ï1É¡–4Þ˜C¡Ïàóâ:´DwjQPd|æ4\Ú¥ë 9¹*]?Ädyé´WÉd–žmWRÊ]ZVló™ý6Jä�' g`3ŽU2„‘¤]VõÌ‘-M¢r˜µ•‘¹yªœê"l $ó¹«VJ�ÖÛIBQ`Î|UKØI| `I°AÚŠ½žnÿ|÷ìÎqI38‹‰G|ì8ÌÔ—~z>ª6ÔFÛº½V]jWÜÔ.£¶΄´¯©Ÿt®Ù¶}Û¶íÛ,fÄnpFÄ2Ê¢ŒÄnp|1ëÖ­[oV¿R3³< ú°—TM²b®;"µ&Þd ‰iÇÎDÍ‹ƒy4üu5²øàƒ>øàµ&àêŠë¹ôÓ¹ÂìXƳ¼òò+wÞu'!SÓLuppy¯pDg¥Á§™¹a!€^b:&ÏHšlŽÝc&Xtèówí’¨ÏÁß‚cs€Œ¾tGKR_ëWMèä(.‡ÒÏÐ4Ó.…ŽN©å¦ÓÀhŒ7tÎØX0‘·Ò@M‹]ßû9¯Ûv0PÒÚ+tM`µÃ œcmìà z òÕçMåш}°ô ÓQåhGÒTÇyör_”’Ù1ľXh ª‚ vk•nƤ\•Œ¢_Q$¢Òf>V³ÖHz­“ÎlÖ} S;À´Y;R©˜Cá8�Ç'ræ9S©ËƒKÜ«ã;föÌ:µÅZVŔ̓1…)$E€ÍÕj*ø,©p’n°ÎÎób1_O; DfT¤‡”\­´šÌbžoÊS߈2­÷^�Ók1ma;6.f~f8vÂ[™å‘iÕ®¸´—{¹—Ú¢Tè=òÊtj«öµ£â°ª_dy±sÇΧŸy:ÃxêŸhî»ß(õ·¢¦Ö.ÁÑ S }‚O2_†ƒ÷(mX]£ W¼¼ÄÎþ³˜ªG[Pê7ù“–Ä»víZþ¤zéñgz£·C‡¯7½© ¦úÅ‘cG4†zÙbqd%ñP_näkáÉVh·H³=ÕÍL ßã6àˆ—f¬…ºsâ5#ÜËNÁÁ€Òké®e„£z²7» /ÁŒ°W¬ïvPÆôíxk_ •ãã¦b%ësÛwJ–lCæ—t™¡ëú<îÈ¡ Ïe_äPh¢cðV< ’QÕN/“*Ã'òN²Ù+ÙX~'C70 ½¥¥'•¦vo$Rò ÁS‡”R%Ó*›°ÑF i¦€añh#!‡B(ÝrÂ^hü`§Ðä¥8„f~qz*>ˆìâê¼3±Ô Xà—Ü)AoƒI�aÒ,UrPÔs™t“é¯o:½Õ5ÕÖÊ•€Ú,¨m³M¶ µÍ+Ù„UTNz×:¿ Ò¡@v©H´%G¶lÍ´jÜ!¦U»Š(¤qÃ"Ô­[·î²[W·qw©[¡nÜË%šiÛíà+Y3„åÎ;<ýÌÓ>ò([¯‡^€[™îùóçû_¿z1ò¬Ûí2m‘JüXÑ$}ÅuImØ+Yv::„Œ¾ˆš´¢¥º†›ºù|ž=†ô…m{=5mÔŽZƒ£Áö{·#—"Šó'»Ý®&½_»Ë88«Yúƒ „DuP—"€;Ît˜W«"K(Òý‡[É ÆçMˉIº>æ$=€8•ÃT Ó!jÌÑDÂÕtc0•+q¯$ámNa¢!N~¡¤©%MC𲃂Ôn×kbŠŸ: ÔËž«áɧ «#dRÉÝVØ=TM@Ó=ù²ù¦¤«QCܵJ+Fªò ¦ƒv[ì 'qBŽ/îã¨`¢@Ny&©iÿÀýUcį÷\íèÎF‚ Žõ£¶AßÁ*V;ùºQ’®k}Ý ¿gœâ9åK‰âž'ÅßV-x«ñ > Á˜”'¸,SÀÔ—½®\Êðí‡ ¹ †—Ë6(M|šì(40X›Ð2¼Ü~mºSpÕ\”ûK.’]—––l­™öq÷Ñ=Å—Ê•µ‰«V­âVk[¯ú×tÙ LQÓ>¯âß-·Ü`û¶íý£¿!zú™§i5·ó¾™ú’^¹2l¹YÒ×ÍÀ0™êõWùsoÎí`?Ö\ZÅOظBŽôUì±è? õñÁ×ÚO¿xI˜‘½:Ô´¬+/;«V­²0<66f)ëG›üë8sæŒ5]Z8eC ¤kgãv³¡h)S ]1ZE’^RÏl[ó”Á!¦Bn7I#ô¤­ Ï(ot{:KžzÍ&ާ àTLº”¾ÉŠê¨ª¯S@©ŒV;Ƀ\œB³áa<[¼csñ$;«¶0¦tA¥-Þ±¹¸ŠîSJO·G‡îWÜFì|\cCÜòôuVUôâÊVW%»?QZ¶*ÒÌ£¶«Ž£�téÜéfËkIBõ,DD¡ãΖÐ.x'«b,ÎasµÈú‘¶-gÆUs)’ËÒ@Éà_Õ@fU—5Ó­¦ >ìÂṵ̈  ÓI«FÍ’ZäE÷¬æÒY ¹†Aí†+Ö!«ïu¿„ ßMb[è&4ZÌ)P5¹{cÀËŒ$5M¥kª^KJÂ2ÖÁ uÊe.»S \Æ(–XfõKH?úè#nF£ÄTíØ¹ãÈkG�|ç‘ï<û̳™Š³ýÛÿåßþËoþËLÅi¥&ýHf›®Þ蟔›W°F!(íÚ½ëJˆ<½^ØÉ‹©å»}Lí3+ʬòû u~¦#²XqRJtðƒ�ú#¸‡·mÙ''pê=³ïþ}‡¾ƒT¶?~q´=í’V¿Žs}JžÂȺÙû|³#Øhë¢q»­i¦ý]Ý£;Ú×UºÉÇN̉¤3ììÔoÃÛ’=¢ØÑÊU\[í¤ÆD´žªR¬K1mp}Úä\g0N? â\Ù=hì¬ØÐãq.[Æ’ëâê_ˆ÷ò̘LˆšjÚýˆ!»af:½,_ü¬z ·k*‹)ÊU•¯5®_F‹|Z¹tEY¤s,‘Ôk~ VÍábZt˜4ePgë¤:R¬æ¢q̨¦½Ôë} Úšù:,•ÚÚÙO-NÏ5wÓi¨l¡iq]z°Ùß œRȳ`ùI ø„ùO÷\)tD¢…U¤\î½XLõûuœ»víتµ‚H­8ûKÌåÀÏnŽý”Ñ'—ûÑ蛑¶ÔFN-©¿ûâw¿óÈwø‹¬TºÝ. ¾ý›nºéý?ø,÷í¼ïáo?üÉ'Ÿ¼òò+Ø;þ|†é³{Ïî .¨e-øõ¶íÛ>ýôS¾TâhÅ9°8PÛ00úQÏUžËýz†U”):‡gÿ­œ&õ~³ß̸4dB×µm`gÕúÊí‹øépDúâ /Ú#H·ÛåO*3ÈVœkÖ¬!KyÆ zñÿß<öæ@ŽÌõç=ϧ~ã×ѧã`€`‡RŠ‚69+-‡Òµ]Þôx«&ù!b›TJ¨ºÙ1ýAžªyºQ»ç¨Hi è4âi—ö&yÒL’ljq(Vp²ƒBˆ±4ÅQ¨j\Æ ¤j z6£;Λ^.*˜¹æ˜ººø\ªÅäC‰|ݽàxRÞcBxqº�ªN%µß[B»à’OXøìeaÝ@TdŽAîˆ ­‚Á°'f ·¥n }Q䘑HZ?w󪂴¿AÞÐvì¥ÀÞÝ)emG0,2¾ä@é ,wš$]§«ÃºaixóÓ†ïQâØnp7À,kÉ®án+§þÀðÍñú�ç@Á\æûS§³CàsýúõÜþ>÷¹Ïé^vþüùßþö·úšŸzò)� œÿðÿ�àùçžï/–È:o³Ùÿ^¬UŸ€ÊÒG| f`¥ÞŸ“|à 7üSÎè®ðúôiNmÕ~ïµï;W¯^­Æýó•—_á•´fk×®U'dÅN½W­åÂ… üý­Ö™®üº;û.gΜœƒ”­Æˆ —•‡«¨NûrU!SÐm.dïºR,•Ä4ܱ%{ =²c5 ¹T¤‰û§{q õ„ÒÉA‹Å¦¥ßÈŸ f0¾€Mê@¤€WF«E¸xÎÙ\b%X H¨ÚVvO,UËhÁkótym£DÔi¢�`BL5iÑG+Z SB^ËÌA] I(·ðªÆçÂ8ï\ô�éHû=S†ðCDHrÖÆr®-Y•&sREõœÛߟÝÀ=ˆ Ua g…Ç4k4‘9BÕ™fÌ6\ÞxÑž„øÎ 9;zîeg°ÐyæI$¸=Ÿé=co3-+ë.BÇ35eâ4›p‘Œ•ÞðùDv)FabjAÏŽ0ëÎz>9âÔÓ¬:'Û RûÂ… ŸãáÙužcQÀ¡q[á‹¡Í–;·¬¹iMæuÒgõÈëY¦èµ¾ûî»úõ@ÔìŸ 5õ ê^ŸËÜpû' —šüµâúÝï~§c鯕‚±<=XTî÷°UàÎz½Œu÷=ws¯ÌTœtê§þXJzñß<ö¦¶^‰üŒž{ö9š! ÑT>­í'ôã¾ÊÛöm#ÚþÝtÓMC:Òƒ'´”îå0Ëp`Ýþ( ¬ -·�L¢ø37öî‘kEá§!P]Û‰äI¡¾hB>J¶]±V/ †õ“«—;Ƴ(´è¾¹€MfKŠDÚX“´Ùjêå¦ô¨2¦ËX2’ÓZÎëæ¼n…‹ä�³âdAb‘¿ÞCmwè¥cI!yÞEmº–ÑÚ…ù)4+·%" ¹Œ%ªU¼“DMf‰XÙ«\¢ Ý àÕŽÄ-].Iþ ã$ ¡ÜvÖ¨!sÁƒÇõJ2ä‰Óì,Cc,­LÊÍ"“·Ìã4A¢„6àó‚ðÙËX²ñ¨ieäeó ø™{U:·°lXÍV3¹ÓÅ´5_ÆzéªæŸãón«CGMêÅyÉí±óÎÀ¼ÅT;ê«É°>…•]ÿÕ¯«]fw©²9êä>üðÃ!‚9êW¯^Í—Q,‹ÅâÄÄÄÄÄľð… 6°åäì±Ç» ‹;£åõ\ö:ðÒ¢æÀ’z÷žÝ—š×ÿ�4\,{îÜ9õL¿`V.—ãý ?—þµÊ,}Þì[¬(Aάçž}nÄŸÔשÍöï½ö½‘ÔšJv%«¯âz‹PZ¢’ùSÑk’˜ÌyÔsè.�0çe) Æ¿5­µÍ^;näOUUàtBWV*; 1FaQµ óˆÂT×1ãçW·³e·²ÅÚˆ‹aê`ÖJ›©VµAš<Ž!.–ЦG`;¡òÒ/>¯L*!,…@¥£Øê:·®F©“.ÛÄZS]͆2>À<j Tp²Én°‰ê++<cA\—6ƒuöqÒ©ÂuTR©Å“_’O¶—rógØŽe±:ÁIhü€ø¤éǬZûy™f»/lÛš»{=ç­È#ˆ0‰:|ö2–ŒŸQ`FªÖ¯±˜®­¹…a«FzÕL×7m¹eç¬þ (Ðbº^Ïô½³Èd÷î¥Ûq—a)°" .×3¼é¦›víÞuäÍ#£{e(Ž£üÊî]©Ú±ù4Wü•ÇŒýÛL‰¹~ýz»?þÄãšrbš©ð˜?¥—}`ý7Þ9„ìšù/cÙ©öõÌ×¼¼uô£zoŒ‚š¼%n¾ùf�ÅbÀ±7ýö3¿Ut$�ëgñæ±7I>ÊÜKì_\uÑÞ´Û¶o{ãõ7®<¥gpz2ž‰O‡R‘LÔ\ÀEˆ:\ÀEÝn :(ˆÕm¢ÞF Ž7K3ÛS"E¨ÊHŒ?¢B”C¡àpB]ás…Æê–¬&ÉÃ$aµ„:ëöS±)¶ˆó„©‘nÜ(û¾¯¥RÛSS¹fð¢ÄGè -ÓYȺj’‘mÝÚm”*è4ÈL¦\e´bƒg;¡à¥qªã‹Ÿ•qì,€¦zÆÅœ×m ”ÈàÕ¢\¯9Pì åÜP,»°n‚ñ8pÍÌ„bÇØ2ç¡¢ÐYí£Ñã´+¢þ™ºÉÝLj8ù™@y¶¢õ\4 ±Jp7³Ò‘BÍ—N?Bòzb3¤©¼R»ÇÚeµuj$´[Í6 `ãßSe¨Zñ)ˆZYg”.ñ‡ ‡¬|>okš³±áÜ–ŒÈ=S'Yóë°ž}æY�¯y¥\.s3ýãÿêÿÃ[ÿÁþÌrz’ƒ´ã— âÁ.\xè[=ùÄ“�yô‘þBS'dýyȗʇÒa³z¨*– OSC]ö]û£Q›/‰ìzÕ—,Wä|©Y?¡1s¡ý“>Ú_~ó/WDåß×\{Ÿ<÷ ¯þõEŽ�œ<†{jÈÂâo±—4ô¢,£Œö€?£ªsˆ ¾#c¬ŠjÔ�~]à”hà"šŒ‹†–Rï9Rh·ƒ&p‡Šê”µËmކv ±t·5Jˆ l5‡BÛl|=AkaŽø6t%‡‚óÒóºtX0q/.‹R“ë‚Ì”Fë¹Z–Ó»j5¥œ Ð Ê„j϶™ ™ÚŽHÏ€ÜR%IÞô6‹ªÅtJ÷^:¶âé¥Rs(ô…É!Äd]¸!kä^Ra#måï„ÿaB¢öE´Ñ�LÕ&}í�� �IDAT`"ƒ"`™®ØæE&~µ?/fP•ظª[¦€Ç$á$ܨ^œ7†ì‰½ƒ°©ý>r ¸kÅòî¼~½¦Ò‹ª™þ¹™Sd¼à¦OǙ٠t‡²R3«m¿žkï¾½qq`uµcçÎ ¿õ‹ñññ~tï׳xþ…ç?Á'dÅqüãÿûÇÿüÿüûÿ×÷W¨S%ç„ù̳Ïd†y/¼ø€‡¾õÐ3O?£oÀáC‡y@É@¦=+è†;ð›EŠ<plÛ¾íÚMyW¯^mû —Ѷ¿2â¯AëѳŽÿ¼ÆÝÒ¬5¼õ¿¿å}Å믶W,µ—kìÝ·÷.\ù¥îÿ€ýd_ˆ‹‰;+·]6*‹Hüƒfé�—h–o]v^¦ OÚí£„6¹Œ–ɬv»$ÍQé¢ÐC^ÝÒµü⬄6¼^$ä#v̪%´Îë@݈óeLëH•“NµœUyà šŒÅ&í¨t&bºrÛåZçCŒ‘îKW[†«M 8bR³e¯•óºû™ê"ùÏ‘úòäP1VÆ4=f ™¶œÔØçººM‡ã{ ±hmЕ®µÇôCÔ«$¦µè%ñ«Eyت%¿è•" Çží 0×j:àLëÜe, VEcȦžÖƸ¤©ûfx Õ©'VàQµ‰µq7 ÉpÑ8ëÆÅì¥B=}x0Ú˜vkR/š¾o^jæ`ÚMÿn쇉8—c©\£5pD4âZ.RøR×Ãß~øá‡Î|óÇÿóïÝ~ïÙ³g™Y½j™õèc¾òò+O>õä“O=Y(Šf}îsŸûÜç>·víÚ'ž|â‰'Ÿxð[2:|÷=wŸ5ë*š»²Ux©×?3i¶¯íR‡Ö×bYs×Oe?^QóÈ+Gz½ úMÎóÍùóç×­[wË-·ÜrË-·Þzë­·Þ àöÿúö›nºIc 8IUÔܺmë5Šh½tàŒa„Ú§ª9"O 'ØOŸ¡[†šêÇÍzŽÿo(™GlîUÐ16ƒ$îV;(äP =GLˆ�øÂ¾ép£çÆ-Ûœ Š!7aAöM¢> ¤žªŽÍE%´ÅÕ-L¦/ÒjªeLÓÆOé*þŽÔÙ“½8Ïgo£Dót:ïôP«  /r ¨{;¿Ç4±\}ØËXª`"3unà”டþ\Št’c•�“sIpõ9Ü%6ëÖîÎÍ}I}2¥mÑnëž'P'_:Óó,£¥¦óì9§opî¬9Ç4†œR½Ð0i?Å«º¿ú 0Ïy]7hŒ¥<õú<zb©J=yfMó~óloV©°‘ 8Óú>²aS2rè´—+0Xnµ¤¾y„jú‡ƒå¶ÝÌnµzõê'b9ZÍu~™õO •iä}öìÙû÷ßÿðC¿óÎ;ï¼óÎßÿýßÿâ¿øÅ/~? _>ö¨~ý?ÿÆŸ|ð[îÝ·—E'WíGµ!=mš•[jÌðë™ÏçóùüÞ}{‰ÄŸ|òÉïÝ(ñÚ-µÜrç–þ>­-4™Ú¦£â=»÷è¿þ§è? |ðœYñ|¹!±ù“ò YµæO7§ˆ}ÉÔ}-’Z³Ã:UɱâlÀ!(«Ìª”h1ä« K³ÎZj§¹–±¤5bµBb#^Š»ð²"¥” ö´Î­Ü…xÌcJƒS¤Û5úú:7zÖC9Ì:çX/Bì í¨žCa‹w qÑ%“8’ªª ‰¾AÓÔPöbg†0ßÁ‹VNz>L!-Ñù¿þMüȱxb—?3ƒ& }! ;ëv)©l€ZMÓÙLÂFD=¥E¾)4uwN—€¬çŠ=ä{ÈKíè§)Ш`‚¯_ߎ͑¦Â q^j–˶ÈÊXdºµymj¨‹²|gp"],Šn$¡ŒÙ¢­ªAab§ŽƒIަcúÉ7`¶â×À4™‹}ug |« î~šŽ[p úžÅ_1E‹Î3gμ|øeÎÿbç5„=4dßÏ|“€§[ŒÝŒô›ú“çÏŸÏ|sÄ¥S=bg¦}þ¹çù¿þ_´\Ð|>ÿøcoõ·¶þ¾õ?ÿÆ7þüò'òÅ/~ñ‹_übfçU;…›o¾¹ö£ÚŽ;,vf~rݺuëÖ­gÏùƒ>¸¦'Œ\.Çëowv­­'k¹Iv?ÙõÚ¡¦z%îÚ½‹Ÿ íÙê×VËÅ‘óžÝ{ºÝn·ÛýÇüG�_™ü P¿Çªz„§£úfäSìÅHG@(1U$ÉyœSOãgVÕQ¥9¿»ÙO({n톔;b½æ¸ ML '¨ G„“imù´Òetɬ:ŽÍæ)ЧÅt±=tHZ±ž®@‘£ÍŠw²‰Y�s¸ËIì•ãLy'ÕgGøG%‡”äâzâ"³ÏÊnä6©>…ÒÍ[ÓÂåqæqššE à Ì!ÐP”ôÜ‘cãªñï­åÐmˆ >°s1Åj޹§H¶šâŠPmëÕo¤z‰¾m:e,Kaâcî‚£ù,tdF©ö*äôR¸pÔOªŽ£"´.îDj©$ä±4cIèI¦¦§îzýå`Ê8ŠJÓ\!ßPd‘þhô?û̓² ! Ý3¼è<öÃc{öîQnÅ'HÙ ßGþëµÈé¼ MÉø}2_{ü±‡Ÿ|øáo?¬@N)ýÁ¿ûâwíR‡æ>ð €ÿ¿ýû ¼á×ÿðë/þg_\ñõ¨žáZ¿ñálûIõOõ†Ó¾®|é)G{¹\®Vm1xíÚµDÚgØ}(ëpæÌ™»ï¹û¦›nÂ:ç¿{Ïîó8ß?xþßú»ð·�êÿk½úßV/ûª®È0ן¼Ô<Îe|,…a˜óº=·¡˜XAÏ’«f´©~댶ž S²9n²Õ´“-÷Ǽp8#Lˆ&¦ÒöèÕ &šâ*×såKÇ8ÅŒÕ9Ôáülj¾Þò‚XüO Kd-=tÊ^«‘2Ì+ª÷,¯Rps(Ð$¿†Ý×и‰bŒq¤ä‚N¢5ïØ7<h^›ROãÜKº²…žór›í¡ÖƬ¼ÁSp>ïQb0Ä& V½…vº§ýpó<¬Ñ‡7v‡+L4QBÒµ³)Ç;é$O¦çsd ÕC!v…‰ÄeÖ€«/ŸEb*ÔqýŠ[0ƒæ|ÒVå¬1*c)ŒÓ¨#þAF¢ap;ÆŠŽòÅ€ iËÖ‰ÒcH?Ý’ Ò©m9¢SCî/+ƒ´^eð)ž_Pñ½ó¾/¿ú²þ+Í<•“Â/–«?~¿««}=öøcO=÷Ô@Æ7bæ°ÿzèð!�º÷OùŸ¿þ‡_chŸÁEŽ<‡I5b¹ùû¢eõŸ{¬ºÿZ†ôžd6CÒd›Ã‡ë'BS¡½ûö’º¥E§zÒö„Ïþî»ï.--1î½÷ÞË|@ºR“ôÖê7BºZãêAÀéi"D1áM¨ŠK¹rðcÙì×!ªb¤Ò_a ìPªDSh6^L]& ñ(€ùÅbÔ â}ªQŽàÏ#ª Ý€Ï è`ØÈèP  §õ„äL•×|ÙÀg%ëëM¿—‹¢F²qq±äµ(§ÔLŽtJCº±Yl³ ûöMUŒò«Ûc9ÂD5¹%>¹0“_�àÌ 7Qõ¦zÎ4ŒÓÄ9\,;SûjÞ¤_H­¹˜éu³ÜÁR m&‘ …”K±Ü™%‰©…&{]Ê¡$º ý‰f¼î“¸é~|# Ø„D@Yd‚t˜¾!å_ë¦ô ’ŠÞÕôç‹ÙÐôh}àÅò¢B#K‘VXÓeh×~—öÌP3X¦EŸÝÄ€•1I!X¾öêk™ìˆd “6oÓ-†D\Øt‹!ó>³Õf|Dû§}úó×4Âɾ*­clvø/Ið±×„XRû×µ?üÃ?ðëܯpG®¹vlšþÚzà¥^nôkk¾ŒFåR+§+ïÇyå!Sá“Yëú¯wßs÷œ±§~Ak'sXózûÞ}×ÝÏ=ÿÜg?ûYû¤êØwÙëâÅ‹6¨UONVù3JMß?ã,Õœ×MW2€ñ!¡8[ŸÚ¢FŸ••N¼ê’JòCÉav-o5pJ<Z“³öš:è†*áº4¯xVåb]E%ß’q*$—ºælwP›¼ÐafÍ[(·F;$’i1æh,.ÜÛ刅ñ¤ËÕ)ÚŠ›q\ž¢žC?`¼u´”‰„QRWØKÈJ†+ TCLÒP×\ðzºî¯“‹[Á¯9…u©žk!·`•ð<#ÃŒ-Ò 0ʰ S>D:X%(ÊÅOtŠ=ä3¦zôÆkf²XÏñæ¶‘Hz<qË‹-¶Èb4 !‰5ºž49¼�^ äáºÀ(WE¹P‘ù¦oÞ…ýÂþSlu2Ôì C_RJFÊõÿ¡n¿wûMfeàs9ÞÍ@&i)ס7«~4½^¯×ëÝxã7Þx£ÎØn0k­,ϬŒ+ D‡y|d=èvÌ/†¢dÖÏþó˘5rd{öìÙsçÎ;wîã?æF<fÖµke_*<aÖŒ›ÕÏ‹yíÕ×V¤Œñs!µµ¿èÔŠS¿“1×›¨iE“Ï=ÿœÖì¸v»]>Eæ¾=#kà'u%´ðáë†AS–ºrCHœ©`¢Œ–H‚dèR<หŒ%!  û”ì•zµyL”)ÊÝJt/DSŸp(µ©sì„îÔª`qePAöë6Ò#2Z@cç$=Ôœ°ÄÑ;}�-LrXÈWK0Ø„…ü¼^”Ãì š¦©[¢9\dðˆôHëJ$–Kç TC#ÂS%ûwq MÕȲÙK˜$Õ¹‡Î ÆÉM>ŸÿÚÀF•¦ÈÛ¯~!q=Cf4\E…®z®K‡ %GAP-iÝ—Ñ>32ò í Á‰³F2á 0/¯n %r^z‰á¹ŸuyeAéF•fð™¤rFis>wH2ÊT}?›Êâ©{‘?ˆïãÒPfù†é¥"\›Wþ"fÍ5YNÁr=*¹ÿŸ®8Žé¹jwßýûvïÙ½jÕ*n¸tÜýðÃýë_ÿú׿þÕ¯~õ«_ýêÝwßåy²[é•´Üï'w°W}ÓÚû—kÒö/ÂÿŸBB&Qóî{î&Î)*¤³~úé§O>õä§Ÿ~úÑGAˆiú°=YWkˆ{U€Ó7  ˆ³«6Z“<ŠX´‰¯i] \ xHt,V®”eœ5ñÕOKýªÆ‡})]ŸAÄòf‰»Bí z¨IúŠãQ&˜Ãl'PO™±–µ!­š¾¨cHœÏ@Õ_€sZ}¶jÙ‹^À&7ÃÛjK*Æ5·Œiº1ˆÄSåöU¡›&#7N1µ›*x©~oU >Ó|ûvШZ MXàyE®ùAª8„T“ù´ÁMUŠø@/_ªôU.†‰nÇrjêVã/§„bú6°+’“‡–bu÷Y$õef²¨5®©A•=ë™ægì›ãQÞ^=™}š<T–ª±ß×PUwÙÈV¨iäë_õ4 Øý¤y1A‚ßËSj/éœÛÊoû[{Ï0f-á^\wUÛÎú'¾ˆ+‡ZZZ:tðÿwížN驼È6*u)„:hYŒXÕ]ì–Ŭ#88ÔµUÈtæï�LªIÿzú©§ìqýÏû÷ßOÂQ¿B¯×ëïÁ ×¹ÿwí_ÏFú+d‰9d ˆ3T ˟̸cg“˜°2¦ÓdU!ïŒif$RÒre–Õ*©=L4°‘ù_t8% V“&(Ã:Ð6aÆî3'IUÑQ=ld'vòà°¹f2 «ýä½[Œו%ºB$+•dQÒÕjO·ÃSw³ÄÆôÇ`.X£ûsë;·lÿô�Õ¶$2ø~?$êaQ¶õ )ñÍ"%¹kp¿4<€.蟫I}A pu îv¡ÃcKfZj‰,2•|(îÇ>{Ÿ}ΉÌÊ*²(Ù7`ÈŬ|DFfuÖÞk¯eÀ$ âp1zwkpI;¥­ëf.zZÊžd|ª.yÝQLѬK–šQ© §ªn¸›ð¿6›õ é´p-Âß5¤ýÖcÏÐÝ嬺Š]çÕÄ ƒŠií“2a]w©ÔßIqˆ…J ƒ`yv³Tñ™¢Ó‘Ö)›Ô›O­ºéUbuR^=Ÿ‹§J]Mrå‘(K«ª5!eªv_ô-’ýÐC…m0o5 —eè>œ<‰¤jèå¾’ŠÉŠïå[ÑÔ‡–uTbCoÕ¨6IMÉSÞc©UFš)Œ\½z•ˆ¦®òõÞxo‡Þ]¢ëׯëbøè]ÃÏ®?TïúíŒIÔ•™ŒÑ4á#]�ù¤ô÷^:šr£÷ÏnWãÍ7Þ$AÐÆM=Ç#¯Ùµ{—Hœ>ýôÓÏŒ.†À½ß¸§'’ð2->¢ BòºC‡¢X1•GX*«ULj²DZc;¨&2³!±¢ˆŒDH¡«†p×,6#Çð`˜üÇÅú‡*Hêâö SžN©_@AöèëÑT£k`£)ˆ€ÕÀº'öè"mÀ¦?²uN¤ï¡ 3C# /âbi gÁtÓaÊ0Ì%%4u2¶ÄlVè5#´Î’4¸ÕPfu#˜khÙœo6aZ¢Ìò¨lÂÇѤ«›*WÖQ¶Åbc'Õ²a)©ÄY{©«‰µuÄvC¸¸cm[̪d8lT¹‚´»ŒÊ\•.©Ä]‹>ÛO<„ãÌçï&áÎe&ÊäÏ+í†*¡bV…YR!öÌꆔ•ÊÏn#ä=Nð3O“s3‚qÈ™ˆôPÄôÀÀ�7x%Y&-Ž¿EdZ>Çy< Ý�Èß1Œ'ÓÓr…½\OB êtãù7ÏoÚ¼‰JDDÊõw[§U‡üõ˪gôSª•J—vÍž¨ª°IÇ.WËq›G&ê\ ËØï&wÛ?Eõ¥ºH<IÅfQý3cÏE¦DÓ /Çô"Ëñg﻾6 išØ×FÐ%¯a¬ÇÈ߇l¤¼IØÏñjÐ!Ì#˜æZá$DºcòœV–sñ9%}Lj—÷ º€¹LDLÊ•Pÿ·`h,œ¬®™$í‹*KUFZ±¢9I)˜›ÍCú-(ÉÒr”%Ë‹L=C¦Ët‹ÔðÕûJ¼Š45‰]]Œ]LJ´T³µ¤0&Í5jNl-¥y‰‘h%:eÝîG®‚cîãi|R)SZžÜ Kuw6à ú/(T…ÏãÛwl¼¤"’.@ ÔÕq›*I‰šÿ+Û]ÂÇ— T½•¼³%s¸åË—/_¾œª|s3yøÒkÁqõêÕ>#\ÈDPÌëg 9ÿæyÉß´yÓøéññÓã�ÆOoÚ¼iÓæM$¹ÉO¥“"]dúnÎGÔóÐfCÒ´¾“‹Vœ4 gªµæoÛE©Ðµ'å[LGíÜb¶…ÓE­‚\Ù˜%©‰7aëÚi)“ª²„yÃ=¤±RfBr«95j‘¢¶Ù„zBi."5jX8P†šh‚Ÿ8"fº¡$¥qÁŒ“ĺÉ,×c´r+F°ú¾kM7ÁµÓ!BSòBÙÖä,"7à–j*Ç<g’òž#QphWjùAÀG…Š·,RÖFY«l˜þJß”~ë[¸ž°Ëî Å;cµ9_ÜŒ»§±ŠýRµ…åVq]yñd¶aYH›XIe!¯ï˜¹ÀV) JªTB‰{I-u&­2cÇ<~¬~ÐýѬפ-ù3Ï>3‡M Õ±`ÁÒµÐ~öÙgŸ}öUS—,YB÷y衇n«£ä·m>~+bF»×y…ç!¶·®µVu„mìù~;±ýxð.]ºtÇÎçß<?~zœ¾`{÷íÔ¼÷‰´= %ÉØµk×<>mÿˆ‚[ÈçSBÌÁü/×±šSN0wCNÓœp<I CMnà1ßJt©­†1ÎÉ;@Ó)±.ƒ$÷"\™B XÝÄà”i§µ`+¢$·¡f!N‹¬žÂPÇ–s ±Ƥ`9‡—‘sM#©ah.µ0Ô4fF-Ê3jÈ/˜ª/E†ÑV có° ØÎ‘m!%ɈÚÖ8ïÀ:™ô4 Ëì˜'œÐz“¦ÓŸ³ žÃJ3’™2±k‰Êü6Þ½€OÔ¨«Œ‘ˆdTRhüy‚ÏÚ[„ 7F°ºÁÎG\ÊösÄtÎ3Ű GSÊ´Œ¯¦—¬üLí¤†1kÈ¥®}”ÑA¦”ÀÒÑÏœçú2Žâ}–¡i‘m¬”ÛÖéɵ°OÕÏž3QZ5»§<;V¦}à~ÿ÷?†ÌŸ?m»Ý–$,ý*zz’ºË—/'ý$§ †{4ð¼ ¼;/³->ÓøÄÍ›7id¢ÿZ÷òåËçûâ{8Ýû…tY•¼–¤€O×dÁ‚T`ð>G]Ú5Í=¥€×O¨;w,Z´èð¡Ã„š_ dVnªè3ê!è£Tk2@R™aPÞë†Nñ _FžàlvšðØe¼ —¸rÛ®aŒçcj-Ã Ê Tø_Ìä#UMVŒbj«G±B%@%ÂÃXÚ“³\ì‘-BMp’½ø*\âç±Ã!M\¤Qš÷ oôQ¬Ð–o´xÌ[©¹Ûв…MÀøÈXjªÄ,…º©¬-Æî0nï-•!\$>ÍÏL¥Ô•ÔG±‚U¯‰gËN—H90 ©Ú Ñ3´$÷F˺*‘éÆ.Hé8WÅíTØ6ïr †óœá+ùþ2¬™T´Û‘Ò>ƒ¿“½’¦ö±òÌEÙû¾L¹4«ÁYiFÂ_ÕI\ fšš2í£~•+Ü• vÊ¥…ÌÝ\ÆêkŸ©û¤•sœ÷Ø=ä •òůԡ—òëU‡æÍR÷ é]·K-4Žˆøï°Eû<Þå=|è0ºX®W²s9¨H+Eu¯O?ç¿”YÙ?…Œ³PÆx2,Ç‚¤ZýHK¡ä7¹èÔà8FqÑ#ß8ñ„cÏX›]Ìî6¶>ÜÄà&›ja%+œ¦ï˜:Œ‘É-ãÍt™Š‰Ž‰‚E“÷ðma® ‡å®ÇhÈÇ. &F0Ùàüm©é¹‚£gá&h¼¹PšUáîEGÍSò–"¹„U#j*‡š)´k@Ç¢KÊr¤„ÓSFµÔ>˜Âp �Úlµ/W>åוˆX’Ƀ`gGØÒÁ£vÓ¨ã/C•Õ:‚É&ï?†. °I–…R [‰¯ óš“eì#+‚‹@«l›ˆ¬Ý-&™æ(:‘Ö¸)·ߦ pS<3±<T•g-øRÕ ®P¹Ö•" D=ÛµzX×ckLË=á„çÓ£õØétˆ$y+ íµ+kz÷ ÐGºßåË—Óò'5^" _ñãúõë·nÝ¢Ê9}(=®¿p¯þ•>!™¾Çƒ¤t|õà]IˆÓÇÞ}{:,¼óþ5n=@ž¤OyZ…å^ÇÚŠ‚pnÊzéQÐô„ª¤å\Ë•¹…‚íai™“«Ñš6¹F L5#©ä³cM�ÈeE› 6S]5ŒÕdù&¥WY›(Dâ«p]ä¬$E¡1¡³ÒmÊ:†fM6Q¬ha¨É¨É "zù+T!”JÄÙãø[2‹"&…�0ådXÊ2·p ㉻ë!Ÿ¢ Ôìðy9™Cv!ËÌÞˆõšœ­¦v�™°0²Ž5mQ¦S2!l¿Gd}%í”ÙEÜR“Hòeƒ(ÝB«üçŠéª�»Þëú93εfG³(¦s/`ï dænƒ3íø³iÇ5Ã;î‰cy[yh­jò \w‡ Á]tOÕƒž˜MµÜ¼=QåM^¾|™ªÊ÷†ÆUn4æuÛ1Pé’ÐþÛ§Æän5}©Ç°ÜHnJݪٕ»«Ê*}pív›Êã§O¾sìôz™™Ä;¿"ÛþJË=0AlSAOƒp:‡Rˆù HL˜TòK Ujâ¢ÒÍÆšs°Sð‰T¹EHxŒ²«ÀÂ%®ÂÉÆ?–\Oá§3JÇÆ L.a•N×Åûü¨b Þ¥Ndé!p’tRS-czW†Á$,Áê¿ÃŸiuÕ0¦È1` ÃZ Ä:^ᣱҵ¦L¤Æ\¥l®$?I c†¿#’ǵPQº&b·DÉ Ìär©â а°¥`YW±¦¹k²c¼(pTŒ‡ÜÖ °ðºWJ1-¿Š˜ˆG(­H!E¸RP>ß"_BNõ[§ûÎv}%ÜÓˆ½Ÿ©2OßÿÊÑOàÃï+æS’kž»~@ž‘P¦Ü'Ð%/厎‡ÕÑCñ¥ËYéxþ¹çg~ÝŽýö´1Ðo©öž¯~­òšßŽ[·nÉÏ‹ù ™÷­[·ÆOïñïŸ_°`¶ƒxrí“O®}rüô8Y=è6v?[º¯ p– z¬Ë UYJɵ‡–êÉ …R#©R`ÆìÅ2›åæÊØVšgÔ=‚[3ÌF°ºc²ÀK¤ íâ—ð†E | «(Ôb)ö¤Œ™ÇŸ£Öצ'±’Ò¶Ù+'—¶+-¬M ƒi”±Í¬®Ô‚Žl§Þ¢ÿÊþc•ñÊÉY¯”ð QA5á= Dd+ÑTAeÓ]k9ô6n‹žˆ°–»ª`}¬Ðß!8BÌ8™õb±#Vv²¬Ep[.»2ûuÆ-¨hì©–$‰“S]'M¤o”í|«±¢B5Œµ’6ã ǘýÒFd呸ˆ6<лì�� �IDAT¤h§‚$(º€O8ssÄ<ÔLeT‰¿öõ.ö`¹¸7èâÙŒdÝ ­öoT¤ ¼rå É÷½ÛëîQ%ñåüñÏ~ö³Ÿýìg„š‡&/žÁª£Ÿ'$Û 7²7f{&ut{ÅÐU� ·7Þ¼:ÙöÞÝù®ˆ¸æ] YûÞãß;yâdxû“kŸ ‹z½.èÞsAºåÙÛƒÉko?ðÀ<ð@Øç¾“'˜ÊÔÕ_u®õto²a`¸i&/µPÆŽ©ªY%Ô›N++ã ²‹J*~±¡Lº4Tš|TÞË€õ’5ÍSI5²$œÎÈi£È¸J,Ê0„T™i\%ƒjæM("Ž ™ðн |�|ÀþNÐã&é¦E¯É&’&¨gù8ο'•ÓõžÁÎÀCŠQ¥Shƒ\f_É}ßzÇùÁê¦ú¤xT4}û°Ô¨ÅVfÄx£gB ‘‡Sc5StmBõ&IÔ6Ë•üˆ›.ëÕvH¸æ«B¹ª*‰³0{;óäé(ÞoøQbÞ“{³›‰KR3·Ó™Æú±yÓ÷s§ï§vLçu=½yó¦4„¨¿HÕQ*ëuÛïÓo=ÇŸJe(|ÕÅÃn‹¸;ôÏ!¥ô+jîÚ½k•ê{¯{Ò›¡Yuéè2Òå9¨÷AèMÒóéÍ[6÷œ4š €"cÉ0/]ŸÖ–Ö�<½ÿéW¾J¿ÒYXxß“{ãVA³¡wÆ89{9ÐâÛb Ú“í¸-*Òo‰¨J,TzIæâ+4‚ÕDò†1Çþf’ÑK¦<VE&ª)hž¿†±5xW­æ9‡– ¹É6)ã5XFçÀn�cT@f=KʬK¥”HFJ™2³Ì¹ò6¡jËfm¥w×ÁÄ(¦dxCù0èå² ¬%;{Ú…° ˈ3Åœ}Órþ,hžu5]L&¦C"m% ®†ϯ_í<r—3Ê[ŸÊïRìÎ U×u(mR…š-®¯‚É¢ÙˆÈIj\¯a̘Ӗ0ã6hSUAi.ÙÉí²ñœ"asQ.à °eJ‹[YéMƒZ®×òô¥ø*½§9õ²~Uw²^HLʼº½ëñóNÕQ–%Í3?vÜ ?¡C¦NõÀ¢$«èñ;ÊœšW¯Zïúß-ö+|Ü!�÷sñ•¢«6²Þ&T• óÆëÒuôC·ÍÍÀÀ�ìØ¹ƒz–ÇŽÔÔˆ¸cçŽcGyÏÎeB: {œ¥—q‘+\̹pµŸð|y`­ ´dÑÓëÇžÉ*­ø4¶O86 bd•E3žÂð(¦8b"ç@®‹ü<b2«)©§&I**.à>3ê ~7k°Œ\È@@8\ƒô8j#2ïš­¤$Hð/Ãï1Y¥‹q` Câ/x/WIIuÄî í.¯7±’¢Tõå.cB-LqS ÔnA¼-È% ›bXF°škÝ ë~[òÅèX ³§M\”"" ›§*·Ú™Ý†ù¦E…u¯5æìªkK¦Š­D™i^F” >鲺\úNz]”¹=KÝ1õò —€*rÉÈíbgìVk² å.”(St›ãüÝkÂyØ¿mû6A5çc÷žÝ»÷ì^\ux…kBh*ÖµÛmíMN­èC;HTΛÎkÝuÉ’%ÚÀáp²ué:*}Ë•a¡PIrÚºmëÖm[i¯ö ¸qãÆ¦Í›Ž=FZVùíÖm[ ˜¥�®‹±2‚Réü@¿zøá‡ÏŒŸ¡ÿÝ[थ”òl"’ ¢/ÜÉ+Ü¿v‰œ¤5k°Œˆs…‚ YýMa]qJ¦ó5§5ñ-:¨7ð˜p_£Âl¸År^ÆKRd#˜$=­jȉcq¸äV¼4›ÎèÇ¥É<böm¼'o„,ô”g+Õ"^[==V¢ÄEAc€¥@⦛*ËÖŒÞÑVÓå·#†–xSî@E¬œiDÍFÛšU|1­1gD=S «QíêLU¦ éotb­Íö"µL<öÄ­ÐìíÄÖ*‚¶æ|ž•‘¸ä{Èxwè™í¥Ê² RPRÕM-dªÂƒà¶÷üÒ¿×<uDuÜ—®8H|Ø?Ñ«‰wx;½ê!QÑ ãKñÙñŽCÍiæ[�¥!¶òRW¢²N$õàœñ“Ó~5ßM[ðºvzeÛÓ§NŸ>uzÇÎav¶ÕÝ;9Ž;þòK/ƒõº=°Sð»[ßTÛ.ö×㤥*Ò5±ÂiìY§˜LÂ(Ø‹�BnÈ(Îaš²˜y~³Æê)¯‘¨Rg5åÒ±úLcû² —fÊ%¡ø”&Ę ’6mºá”©Ò@¤Ê¾ÜĶ aŠ®Í2V̤ƒú”qWæû\`ÚaL« )›¶ [€±¼†v »Ÿ'ür OhˆU!ù]¬±[i UÒ$N?Ñä.,Ï{LÈpç%¬¢³jªíwã ÜkmçRMhèx5Z÷Môa�Øvò:0/sÂúÓÔ>ïÁÈcæfãð·Î#)€Øô)mŽŠs¶pò¹â*GY Hásˆ² ¬îoM]§C·[½çˆŠÀ,®‘– ¥\_YÕF­ÆÎ½ûö’}yX¶½ó‡V½~îÙ ;Ãõ…x˜§…™±…)wxðÁÃ^]Ÿ¨9ÛcÎ…ÖË�ÚRønýðÅ_ÐiS ¸eB÷.tôÈQáÄú4¤÷¬o|à(‰…¦Né%–,Y²cçŽk¸&Ø900@*„ fRe–æ¯äU+ƒ(3úÜΈšúŸŽy›z ÅA’-¬áMð’ÖÓú&Ù¡ ®ªÅZâbEƒ“5•2縚»O›ÈÖ`²…bú#«¿@/kjÆxÉNùÁdyƒÝ…H"Ôáî) ³%áÖÙQ!eMªW“ÊÒ`ŠI¥<ödȼ՛N:ÀVP’WS%y±^‰¼ôèuÅ AlêâDȃª /ÐCMß….ïX$#aKN@>…a5çjT»Êþ7îX,Ý,6‘ÈöèÌ]³Ž6"ƱY:†­®T�Þ© ªä¯—VóÅ;P››d¤ ÐS 1hWÆ�:Ñ„‹Laæ—×§¡w{ô2éiãŽýmîΉÖù;\G©3øÒ*‰lØ(MÕ”*\4Mº…¥ãœ1eÎÒ«Ÿ_ƒJå‹-ìܹk'€›¸‰`6ñÚµkz¤’�~É’%*Ñ+Š¢ßÒ2x¥šizzúü›çïâ«HFÊÙâÏN [–å¦Í›Ž:& -ŸZ¸ï‘ë/ŒyÃÆ ãgÆ÷ìÝ£o„šîߊý‰'Ÿ  rüØqúc1ØÙÇ¡…µ}î¢|à¬a¨ñœÊ¤dŒñ4hbÆcB¦Zzdô™ `CM¶¢ˆ0!¶ÎI. ÁJ8S(™NëäJc9;‚é¦é̵›&xËœÃÆFŒ»lLcªÉŒa+�4m`–íÑ0UŠ~Ä´X³ FgàÁÏÄ{µ0­œq†:(iÈr¡Ð(ÌdÓšåÊ)×Ð÷Q¼ßàm‡Ê΄ðã›6åfÌx,o¶YWŒ™45›6<5W{­Uq¬:’g V¨–iP•‡˜ï1u†ØAuIËæ˜ZYkAgœÓ;Žýl7_ž \d-tªB=Àœ½ ÇÃ'dÔkI:C”º]Ùç¥-Tï3vÛ«^XJõQ‰š‚s• ‘J¨þñ¥ØÐÌ îý!«§ÆTª+//™†‡øQy¨ NOOwË›œíA¨ùäÚ'—-[6«ò¾WQ 3_¼x1õP©’/ŸýVTÖT®8|tŽ6@¯~mÏÞ=m´½*Ø÷‹/¾ ï9êÙ3g7lÜ088øñÇë?ú €%6ΓN',)òñitÊ>;à4èÁÝ¿ššp¯à™(ñd¤Mf$MNîT{px· ïd@u´¸‚Ü¢Ú§üjžd�ÏQ¨$Œ"†ýp·ÉÄyªSuFëš¶jIÏ*\"‹öaLNÉ®‚Mvh ³Ç:†TahQ]IHb. ë9H2Œ,׫¿ñ5l >Æê¦­NHû¯ªY‚Ù,ÑÃU(îØ•T)ÝYèkºÃ‘5ëÀž(8LU ´T) åzεp`íù4#�YGÆ3œ\k›Aƾtc¤µ}•öRÊ&ËRÁVW­m»=ÊP’p 67±‰X#ã 5ªMί¨®¿ûÒÀ޺߭Ç9\S»ÄEQTiÈÞc{Þwé±÷@8sÑt>1Ï=Gÿ%uŒîU{; íÚ/Õ`ùsgÏ)¤ç!„ó,„¦§§{“l ²þþ ß×7ιYyPšÊ†öìÝ£= F7oÙ|âÔ �?ñ¸÷(úAn¿‹‡ì{z#hXªµ2Îào›þ¤Û„4œðL¬TuÔP “ì3³‰(­wô<‰X¿²w2‚iª1vT ®c (oú…å¸i³§›–´ån’¨LûA:X0˜1¨LÙ\Â*Ž&@‹F/Èí–îy «¤üËóŽOò XÍ!& Û““x&½@®Ðj|­k›ûZìig.N cM³ ÓéÖ#6š‹v`Ê€ÐR´aUOÁê&Vv”í8gËH@´7˜aâÇÝq£LÌŠÝ"-wÊ‘””¡Â¹Æ:ðRM²&8ðN›ó9ÎŽ°½k¢w/”ßáꦻ8ã+‰ÄY7ÑýT‹6ÎZ÷†Ç:~%Vÿœ=ÔX=‚{fó=ÊÙg[n>fT4ÖR/-,Ìzźn—Cd¥¤) ê.¶x’9ƒw­ô†CÏ• ì]¾|¹Û¥¦§÷?íõg;dBœõnÉYmß±½[–'…¥­ 7 üàø¶mߦñC`wìÜA5s݆ï5 üèT-GdÔ{?bœWqU£&=ăÛ>k­¤…¾óÆs%¨fAd x"#s5 oà16_ɱƒÏá#žœEŒz'>!cp丣ĥà2#å\N¨Äé\´©4›H²XÝ„#3#ƒfGý˜. Sôæä¤ÛG¼Š"PÖà/¯20*c6é0¦ZtÚ6…N³�5í0�ÄJþjˆä¬XÎÚÁªLbPµ–EOô$’å"3ø‰Z‘3wp?S“giIXØýÇD`ªxI¿É˜œYÝš:‰ÍQ¦.‘n:z0³êUZƒ™Ï²¢PÙA¦0IÍka…ÙšÌe.ù3_’ åwø«"™'…{5�$ChñÏ1"Œ!o”¹‘vòŠ’ÏΫ ‹ P £UööƒšzŠcþìâæÛãæÞ8éÜÿý÷ß?)QoW½ß»H+µ,–G=_ú æàÍôü÷Ÿðê+¯Þ-æJ‡'–éÿëmÛ·8~¢ò>á&f)ü&ô†GoܸAmìÓ§N˛ΡÓé<þÄãÛ¶o£Ülªî†ã(÷¬]gâz|¹Mˆ¼SH¤zlü.¾¬fäc«Ý±œg@¹Kù¨³Ã€éQ¬[WJ¿R.¯9M ¬òJj$¸«pI¶öd8° —d´QåœÐtJ:‚Õ—°ŠÆQx.3gÂXò+èÖ`™Îêò øDHÏ&Ù‡O­Ë llj8ÁÒ¡–sò¦îæ€t³XƒwÅ�ÏõŒLsRW5Å • ] 2¥xŠ{ƒ2ÈUP”«¥ –…ÀÆ@Î f¤Ü»]­ž§àMOH¼à~‘ÚF7[ƪ§h½ÚÅÅÞE—D^Ú= ©Ö·³È?s2v Cò17ã:ç ÑLùe¬ªÓ†–¶© 惚'Nƒí©wYf=Þ{¸­ŸCîì­4lŽüÏ_9ôî>?™<ܹYDÿ Èh a6Íœ´ÝC@ýÙçžÝ±sG?öoᬋ\+Ý"=~ìø]©íoÛ¾¾Ï>÷¬Ì¨>t¸[Ù–Æ<:\™.3'„Í6n ûxC/„¤ >qü„7Ý»mû¶={÷h’:«ƒ Z‰zßyû™]S­M+Vô—»«†®ÈŬ)ýä®Á»ïqÇ‘«v2~«f’e¨¥;‘—° ,¸ÁdÓí éðv ^’·°šKYfS¦Ô-^…jU¶0ÔÀÄùF¸9J¥WÒ7mSJ¶-Ϊ,¤­XÃÐ*#&ePª<w†¶õ•4ç‡1•OB¨Ì —dÛLp²´Ôf¡v�qÐ?+ÈkXÅ€==…áŽ%O:Ì9SzfÊ“1z`ÕµP¤Æòàfg dS†±†OØdNÆ9d×%b™˜“sR `§‚ º1i¿™ê«5 •SéêzÊÔF‰ÑíÑ„K-;¬¡Ý‰êfÂ$BÐoÖì0óôA^‚Šû̪l»a#S£¯Ö߮×zèÁñÓã"§”ÂÝŒ}²nBás}Êd ›­Üw¶ƒ›aÐôÜׯ_¯¬H÷xHŸÇÉ'+ÅD$Ú²uK}°.;et¶÷±{Ïî×_{*çTUÞ½g÷mÜÙ' –Є‰„B÷Ñ· ¯•ã‘G‘K!ØyW<1æã¨G‰Ugâ&ÔC%…e®'ª(2Æ8CjL&;ƒ»Ä¦€iu@ü©£Õi˜>¢ZîÕ6‹;ÈxŒÒtûš¶<hRÒT„…‰Ö/Âz‘q“,O¹ÉC2ðGñ>°¢áxùÆótòÃf~‘š¾¢²Ñ:IǤP*™„Ò»Ú—Vr_ø‰ÕG»–=„(vÄV ¬'�÷}u®–ÌB œd¬—ÎMÃÕ –èƒÌw†ÇpC¯×ÌÝœ!¸°±Å`ÛbÌLOTT»¬î”zz„MwK 亯GqêºÈo>îHd¬2øM/¿:œ-É”²çç‡*3ÛÌ…áô+‚šûžÚGKm/}©êt:ÒꇂSÕ”P@·²0+°!À<¯„Ç—1 ÁKýŠýH+}Ò‰tž;{nËÖ-ú9ï¼NF†‚šrÑ„A.X°€NŒn—9ú§ÆQO×ýè£øÅ/~A×D>‘Í[6·o´zè!ÑÇöÈ Ìê¶tï‡W|yÉS+‚ÖÖC©TêBÒ43)‹Pd4.`•›” •0,x™ˆw("ë VÎä,AÊÕ,´&ðgø»)üg•Ð fN0m-¸Û:á…'¬{’5ÑŽ”È%j >‚ÉšI%“ cÈ:Imu3ßsL)ƒôŠLO>¦™}Ó1{£÷kIvƒ¹¬Òïb ŽZík¦6)QÃØ·ñÞ{Š) 1kœ¨Em“ 4£Bùˆb. òà£bQ¥´?5–È9\tÝ6txµÞH%M ´QFuûðR´6TCfw!UåV ÏŸ(®‚+k8¬~›T5Sݪ¯™:˜3Uš»" ¬"/Òס d%ãÁ@ïÌÅJ*¦Ç!ôö=µà“t¾³u5d±zÝï? ô.¢uxbrJúFOk#ÍNJäÖWøÌøÂN/„Ü•yœ<{Ò«Ð× «ßò³®ucr¤ÙÙ°qƒ|(ú}¥ëSÒéèŒþzˆ‰.u ½“‚. ýWBÎõu y³>IRl}ñÅz‚¥’j߸qƒ>ßYgw"Û<SKü…·F0=ÅvwB²’MøÚ�šŽÜQf2fKI�¥¹©¼"5ÕÀ0‘H ÅTÃgø®7ÐŽk´Þ`Æë á+™¢SÖ°ÑN2’o–‰Q5ì¯(Ï„æg†:Ê¡—æDí˜Ñ ª]ÊŽ9urH¬3ê¬té8»•®±ŽHdũŠ—š$©=M);!u“ÆÌWÒðæFYpA KåQVld2p3Ã3K­ÊÔ±²cÅl-ÓÒâ¦.,kCgö1U©Ýâ7›ˆ‚I ¹ŠDri$²ÜQUDd×¢•º¶y•ç~îZ¡§6á—ñ+‡5½Þ*Üvƒ0à^t“�o>|ï;޶l\X¤—ÑÊDåÞ«=Ä#S9N† CÖýÞ^]G­¤hrJ äžboÔçѧªÖø4ö¸24Äb×ïÀÈsN'd=qòDX,•ã왳ýLzPéµÏ÷^¹ýúÚ×¾&?ÿæ7¿éñð¯ýëó] ·ª³cœRYbþËŠÃö7ƒ0 ´Ø Ðê æy4¯Ö3Z(PÉu«™T¹„68? ˆÎÂSOU¨GzÑ6{ ‹¶–g˸iœáà.£ÆëN*i7£q.5°Maœ1ÉeaíŸ û�§Öa3w¾P)0)(>‚ÕÀÔÆšl-¤öW}c)«1Ö‹°Ã™— ÙD¶;jÅE£Œ·EÇ~ bz›šåJs[×åV"sÄœ ÚN”ÁÒ¿–(ÍØ­Íˆrnj†€‘éPóé›ÓÓD0W¨™©‘boJp,aø$/ f|áBט ‹Ïq ˜ÕHìÉ£BG¡°?] Ÿ•Êá‘z£í-4Úbtÿ3ûÿàþ@þùë_ÿzÎý¶9ív{``€“o¿õöO>!,je£³ªôh­´µ»uë–79þ®=Žp¡ß¸i#YwóµñœÎ=çA£ÞÙœ<qRþÞA ó»ßûng ÏÏH§l8f¼n^;ÓÛdÈÏúîz.ì½®ŠS6åôOyXjùÎy:Eþà wæ=W#ç™ZUsUÅòŽÜ+E²u8¤5ŧóò— xñÃËkh`Ra*íè)yk¢w‰Q51ÈÎï…rgÍË)ØÁg‚º,2ªa¬‰•bW«jׂš±RÛ¶•û¹¥§¬F.¦0ÌÜ+iâ"Ɇá„6¬‰•E¼hbPd·ÜŒ”|;%b6‘î癌èÚ´³9Ń¿þð¿61ˆ(S®:¹ú&L9ni[Ñ'+aóIDÕ0fF;Êe¬¾3bPpìT%“¾‡"’’éé‚ñ9h[TZð°¬7qaÏKLƒ«˜…«žÍ‚Nd<$«zq‡¯DÍ´ËžµBUK:À|ðÁ|衇zè!O[©c Qsó–ÍûŸÙrÿÒmÛ·jÎûJwß}÷ßÿÍî‡d“UÞX“¢À‹-¢xdÒ3÷.ôuCÍÀ­ß°¾‡£PoÔL×§éúô»ßûn·’,Í„tû­w£ÎËìÍ#û!stP’ÚOúÓŸþô§"¨ö†|è‡9h­u Êüg©GÌâÂŽD«¨ ŠŒ'($Ь¶ëo™º ±^¿èŸ…½”\è œ(ׂ†#kk`È×`™Ôý8Ø9WJ~Ѩ¸P~‡cž†x¦…¦ì‡F0© Ç@$•,$Ï)ÄMÅ8‰OrÂÛ°|W;+i®«ø0h—�¹bZEÀ#¡› ~Rm¾oXNTh/r¹´LÐeÚ,W^(¿cÛ̪ÎlᮕU½ Ûk©ð2ÙoÑ÷¡SÖùòJêNÌeX§³ëŠ»€œÇ=a]ñLSö:¡§OÁc£Ì C¯VÉfê¿\RõéxËG¡BÇ PÖûáî3÷þu‡dÎ+ºŠÔ‚~Ȥ1€[·n}òÉ'¢Ñ¯|NýtwQ³Û¤àK—.í'å®Äšv;nݺ%PMÁ¢6n j-ýSRP$¤ŒZÄ2å_|ñÅu>4lkìœÃéQ©¶7vž=svéÒ¥K—.ÍÎeKÕÑ£`{òÄÉþc5§Õ1¯Û&íÔ{„¢t/ÕZm¡Q(jÎk¨³Põî0Œ)j>M¡ ¬T¡Ä™×í#ݬpÓŽ™.ÏkŽq¼hUÀt¨ƒú(Þo`X l)¢DÙæD…Û3C cHÛʼþ&ÔWâݦ@ã:µHkhcuÓ:òhü3{ vaS@/9S½±œMã ¶RŠ-ÚÙÂø„AVCòì(­j‰Üé”¶´ÖîÆF×ã÷a¯m¤½a†sÖñ™PÊßÛÕk–$¤¼¿™6jXR'E uQ®fZT·JÔ¢±Ž3ïdEO޵¬=%UéaZÚfJ..AucÊ?w¤WLŽ•Ÿ¢jÜVØÍÃ5‘ÏÂÙ·Õ]Q‰¥ Y4ÅΦwyPc'ñNã¦ö‡ÕwëFbfÛ_Ô0æUS…lÛ¾ífíf®a9ýêNÄA½ÕªW¯^­ÜÈ{Ñ $•…Ö‡~˜:vt’¿þõ¯+›v=:‹t¬Kg=‰$–Ð\‚gzË¡”ìÌøšò¤ÿ?n„¾ºÈõêÕ-[·œ:yêõ×^æÙgàŠe¤“JMòµÁÿoŽ…]v»á¨IÎrÓÜ®\‘LS5 5Yë/^<µ¨Í³ózâξ©i-jw¸KGíÒQ¼ß0Vs ÏÂÿ>½+=çŸãBk]0„nM%¶Ô9Ä5 c5€&�dÀɰgGaâP žj•U/×í·¦±fî‚"*ŠÄ¿)/�23aÉSÖ—<qŸHv!B*Xã¡ÌyË2‡§–`ÑTŽ>g!ÊÙ,»ÀQ«¾fê’­¸i}qc¾ºè™ �Åh4ÕÀcÜ‘ÕJÔL®­…X{Â)_ŸÔ=‡\³º[ÛÐýQùn¨ætìî{R7,O—RBdM•ž+Vy8A@?9}Áæ2ÇyôÈQ€ëqlÞ²¹^¯_Çu�SSSÏ$ˆ.xØ)Ô­’œy7LÞ3ÃOÔCÿ QPÏ¥ô?Þ0©G“ò‚¨¾ª½'D»Ÿ [¶nyà^~éånw¦VôöÛŸ>%ñ=wÎtj団7.•uìÊY£°Ã:·!“»Þ¼¯°Ü«¡=ŠØrWºÇÄ­´�� �IDAT¤f\`ü\œFQ®ö¥Á6¤€ÁÊCØ$¶nW™(#E«v%GªÐvÐÅ Æ•ÄtÎì´L|;ø–À%¬âê+•7­›Ý(Þ—U,pÌÉkšÂp c5Œ ¡E(´- yW1Æð?Æb¥œ¼ô¨ÉV>‰B/¨®ªTq3e(CwØm¨äH¸l(· rÎ Úx¤4ŠcN’MþêLXø15[ª|¦pf6D2“^À*U‚®;ep‡9Å,—MóŽSÒ v@á–ac nÐük$õOÛ_¼d¶5©²""øLø!IpI¹Ô47VßO=ì ¨dŒ‹©z~TM¤Èu(ÜÄÍX¤³Ö°ÐiǦ®J<«lÑÉAe=O>CN+ýøÉÉo%'™ª»zåºÃpÄß½CZn“¨FeÀ… R“:ô-Z´¨ 'y*\ïܵ“6@odoÐÿîÖ» ¼§ó—2õÞ}{C¹¯®uãÔG7»DÒîÞ³{žüªCjÝt=Ǻ}·¯\¹BßùR‹ø(«ŽÞB!È´Z¯8µ /lÛÒ”aÔ$%µ£å—UY˜àT&³^4ív>cà¡v¦2|7Ìo+u&›ŠÏ•TY.æUFÜ[çöí Ø?A—;˜h˜·?¤le@åâ„©C‹…<-åìÓ‚£Þ´C MöXèpÙÙÍì4N~S'€*{q¸a#vˆÖÕv *Ôõ'•SÁ%b)\ƒÝòb§V_¦#ÙͱŽZàæ%µ*\Ç PÔ‰t–‹ö‘ãþêôóeÆ©Tû¨Í΂íNYoJC¡ʸ)e{&>±ëO”Yc•3šžÓºžE©4CpÌÙ¹¯å!qê’`¨Î:ú±ÜóŠ–¯~­Ï~á "û… ›Ú‡"ܼy“¸Žvœ‘Nª¦eòü•2Î{c%ªÏGÞFÈiT6ƒ{Ûwl?>~|žÎœ>DÚI[úô©Óçß<OæM½)2­òoë‰'ŸXÚ5ûŒ°ÿÌù3ôÃ7èM…3 úÐæ·ÚÏnß¾cûçŸNMY°OB·‚|{gL‘›×È»[ªµp¢Ë’v.ÂiYé&A8åŠgPßÌyž¹~+²àÆ*r²¥³JÔö\¦!³Æ<óдF-Nªe8®^C›ò2G1ÕÀcô~%{ÊŽoÖ˜fbðö¢Îã’•!Nm«–¸ÁÑ„%*ó RÍVOhö à ÃdÚ¤†ö*¬¸d¸;ôÈ\v‰íìØ€ƒ°Lw}7»¢f¹81í¢»âÃ=DP Ö?VÔmwàU,¸ [íö’爢L~@P[®ò}MÕgž>Eàé¹åi¶Ýƒ¶j/=4l¦l(Õ?ž•Búx¶–{dx}7úñ'«\€ú žCŠoº W™3Ú;é‰b``€0’RS~øá°^w‡A¤atñâÅŸ~ú)sÿöF•X)¶{€'ØÙO˶ÿw!ýÎÊž:€—_z9|ˆÄªjîÝ·(Ë’¾K–,Á@¯ï[Ÿ*³ù�¸“]¯ÚÂkã7íHAjJ|v’$e‹W;“®è˜»$5 cªiS[ãoß6+ò„«»‘ŽšxøQv•xñê·-wTQ·ÜŠ5¸DLAÄ–-¨Rÿ’œzÌ4H íoã½÷ðíêShÉ^‰µ-oV2j²«j”(Q¬ÈØ£¡•TQ¹þt)¬L'5ë Þ@V3Ág‰*qÛ¬G6.¨+;ø$Ø…@Ù&d5Œu¢ºÙ•±Ji=”|âD…cÃöJ�¨ENq^}ˆŸ¦ëY‹ÚVñëD”hyšªI”^#®kF/mµ1¡²`µ#GêÂ^êv^Qe¡w3”+d-\EOÄŠé košÅ;ân¤‘¡eH�†’•6lÜ0i ]š³¹ëïüñÊ˯ÐÊ^å-á—ÚhB.5-©fb.ã5Ïh–¼æÜŠ«lKŸ>uúɵOžó|ïñ·Î¿€Æ{„ΟD ·ïØ~üäqim8øêAá—ÿ6nÚ800püØqk8?�Gû9ÓÖwêö—Å8Õ\—ÈlÑ̔ݼá ]5å*Åš,f¥÷Ù´<µàmÜÖ˜m_uíðꦴ´†1¶+êXlðÕ‰ðnž™­}Ó!(zØÎC^À'0^¦l$äh¦F°z mž±æG°RØÄÝ‚änZ¤-Ö5qQá\ÔE=ï\iCÙÛÂ%è"ÝJÖàÒ{L@u‡•КϜ½ô¢Lâ'áÊt¹Ã­í×YàJŒÐ  †2ü3Vs¤³Þ°¥…L.Éz_E‘ò&.®8;¼Š²•#¡Ê\¸-ôÜ0?OPCTÝ’� ÷*™eLÅAMý—jüàÅ�سwFM} Þ{åA€¡½ýôÂDx¬W±Y=ù—uÈ{9zäèþgö_õ/å4z_½âKõX³BÍn”èÆ4b`r©EMm«Ûœ^ñYãå©“§Ä™ï©§Ÿêf€@º=®ùoËá}iW¤uÔý�g¦—l‰±´4¹J¬ *Ù:òtô b Ç5Ð’„U/ý‰k?Ì>æj‰1†AM ?ÖÕVñE’l9×`ç7/aœ¦›Ò_tê{æt¬\Ö¤LóÎÀmGZ +Eã„›‚«WbÍf:Vç©Õ­©¢Màèl½±Sw®»²RsÑ.�£¸Ôà,n6J8õÚ†I=Ј›F±ÂäW›ñ$‡Öð!ʤ?jäŸæý‚UÐ-GYðssî;oâEw%õŒlÈØ< ½¸ fbUZ®g.y ‡+m=ÒÀ«Ù#»…ë:Tœ$¡¤ùb3”å+¤sÚ7²7æ0üÐ'BÐb´dÉ’p6ÔKVéMz;ÎôÕûŸÙ/ŒÓ;NŸ:-C®Ý^]Úr•¯H\“\ª'Ï6›¥ìï}lÚ¼ ‹|`“Ž,%A©‡7nÜ qY¤ëS]ß&v^¯×{téW_nÁÿ®¡os¿ÀÉåÐDç]°€žDLiñ\›Që‚•Ÿ˜<Q¼ß@N˜Çžã¢òÛϪ’¦YƒFñ~ À»%&\‰×J粩üâ9è1FDJœ•ÊsÕ Ñ@ÂÅRÑ‹¢ã/š~X•j\Á/AdãoßVô—+Òu=Œ¨¶Û²ýº${L(_ò‚«‘‰‡�€2àƒ)ŒÙxƽÝ8§OÂdˤîèmÊ®‡ ׌&H4Vl®kë®#Ñê) w"=Ž¢ 9ÊÄÚ×Ý„I}ÞûZ¶]‹|¸%P»ËQ#˜º·íÅå£&Ù&U_û uç$µô–¹ Þ�§Á]z"€3=œÎ*Œ“R ç ›èG¨©o÷¦vêä©Þú”\AÇlé.£à\»ÝÞ°q1$í@ûæoJ'•Þ2�ý÷®›Ãõsͺw#58ÉcU²šñÓã•…YiL v8>î3Ñ›6ê°°;9<ikx=ýnGäÓ¡Í ý—îàuvçÃiopp6=´òzärÜWUà’ùqÒë'2C¢EKsu”±.¸©ðjpg&<¹¤Û³†e™c/Œâ}Rê’«Ë0¦T‘0gÛ¹ìVI(Ÿ’Õ51Èd·Å 9ÓýÆb°g+hq\ƒw•ýú´ÆÁj¦ŒÒ“Kd@v82Sù!nÝRÌäÊTU§IL:£‰Lò;Êyî"wiMñQrÁ³LÙáÈTþ5gkæL¬ |¦$[šM’õ²‰R®<úÁÚÔt .¹Ÿ�gt›72M6Ë• ä–DÖ0&æDM¬¤÷2Š÷¥$Ë'Ÿ«@ž”ŒéCWo<ᯙX5eʼ) %»º©Òâd«§b˜+DZï‹À{A6މKI3×A°[­d¶GBy/Ùó[¸páÛo½ýö[oŸ>u:t‰«×넚ûŸÙ¿mû¶7²7êõ:©ùÉãÆã7ý»ÀÜ9jBÅwÌê Ñ{ϽÿcíºµŸ}Bµ˜ËÈ!Ä‹61GýÑDñ2.G7Ç;ºñ왳³r5šÑúŽ<r+Þ~M_e‚(ƒU•³=•7zYchhhhhèÿøû,Õʪ!å5ñµæ¥nn™\0µÑVaªb%j…× Éú€û¦fчQ“&°Ê—¤c×è!´’¸y.Y4ŒwW2K;?JL«a:”í fp$MžKq/í•ÈÖôD¹ælX&ùEþ5Å¿byo+ÌBwÔh©dÎÄ®}®ë¡£ã'KŠ÷lžä> r7ºê ÇM'¦ÃX S²†± ¶ ËÕȈ®0§^Ó»ˆTÓ.Êœš„c†`”¨\”Öڢĩٚï’Ó’t3Â7¯-Wû¼JåŽþ§×‰Ôè¨inê¶' c˜zÜ4³áÔìùí‘1`+iå‰ã'¶mß&…ÄB\b™[·mE N‡þYÉÀ„@h&A?_¿~]/[„+äþª{«¢CéÁ8{“¿­Û¶Î¡Ã*x¹vÝÚ°4:·á&Ù¹kçÕ«Wß|ãÍ7ßxS?9o¿õve]sͨK—.=vô˜ªâm7m »7m±kH7çð~ÃêÝ=t)åÞ 2õ„òî”S/†\=Y[c®‘¶Œ'¸ÍDÌÜ%[Û»§€ÜMC2/‚†åL/œWdþš34‹&9Äò©æ^qOGÈ´{ cf*?/Ó‹ì ?Avö¬âÑü›ŠºjU-‰b6ã:Ê‘<âÒ&VšÒhÄ› 5ç Ì2~ªÜm’eLmswg ïQÖªÂÝ=pãP¼îT×ÍÜn¨ª‡.±æh·áÄÁq5*cÅû/u6Ž™͘pÃo(–2J3ÎÇNø" oN«î‰ &,å«×­é7°ƒzi¡äÊp«ñqÕ\ ”ûOâvCÖËA7pOï.DXoÞ²y]º®÷Ô¼÷ì=úyÏLÔžzú©§ž~j×î]¡9€¸ŒVÂ'Î=Gÿ¬œ‘¯<Òú§›ýÄCȤƒB»BÆ)±Ý,dé8vôXîHé+½™¥¾O%êï]jM¸åyô'%žÝÌÃ:íWéø“?ù“J5\%p’Ö1f‹“„èÔ_¦5ý2©¦TÃØ¦¹UÆ‹B U[ËG°Ú¶åK[k[ÃùþX?ŒÉ $¥ 0Α´lÞmg3š¤qZÑÄP爟 Ý™MçíL:çÃ@ï†1åVe31Á‘•´†¶\·LŽD“o\Óó‚‚Ó t~u™¢ŒÙ]ï xï"pÈ‘[çBØ<Š÷ÄD—øÙ„U<ÒÂtLtù±SÖ-ÇùZÔv;WõU ³J.Ô¢¶ÞÙÂ>aj¤Á; lz˜‰ŠÃQWikáö5u5­jU&b6ui(ÂÖ`£ bcõØ8°†Ð Þo_sû¶íŸþy½^§ÊjïrÓºtݺt݆4´„sFÔìá4¨ŽùX³óÑçý_íõ9¼Ê¢E‹ÈIgÑ¢EKøDZúÃB‹3ãgÄËé~uh°ºé9³vVJºèÆÕ^!|êjmHC1m¨¶Ȥfs?esÓ1=v!f:ú,±öù*w›qê…¬4$ʳœ\¨Òh´vŒØ•s˜áP–È D1³ÅOíâ¶ —çËøLõ v&}e%³¥ÅAHÍ!ÉÈ%_ÚRÁ³‹£ÑPŽæ´–{¬ mâ¢j°% ó Šâ}vÀGM r([*fñœ$šò"+–œ)ªîSNxâdû©!…1¨33iæâ}&µ™Cg#áèC¬ý)쬡ùtœöÛ¸m§nŒS B—R#ñT¹1ÂŒSUCFP 9"Œ^×rV¸`¦q.U@,šUå–xY%iÐ΄kaèxÆA›SbÒÛ]r™¸©Ýi96ÇÁCŸÚ÷Ô|öÙgamv¶Ç+/¿BIWÝK#Òpìè±§÷?-]!–•ëڗŠȧ¦·MàÝBz¢§‡§Oîvý»iu¿ùvpPûóñ'§ÚxåAs)ô–)2¥Î”½»†jP†8' J`9+‰ÖöÛÅ áwéX°`A«ÕjµZýgd~à"aÌKs¬+5ŒÕ0䕘6ÌââQi\¥Lν.ka »¿Ú¸1ú­”jup«yÅÏ×x¬\{ƒô Û9‡”µD|Äea1ңбi8£jÝ4¥W9±\@}d2fØ1*#:ÿÄúÌñŠÌ§'ó²…JÊLÜžYlÈŸêÿ±Ú¶¥—ò–±jñ @UÔ µ)1¥øLªJ@Ƭ4³ æ{Bᦓ |¤W…‡˜ M•8¢Ì††–©‹d‰Gá%z,*8±5s‘5wÍËÚŒõæÉ54@—�N'E•ëó©gËìUbÝjDÆy"[Q°m·Û^<ðÔÓOy¨ÙmŽ¢Ç±mû¶ÞC‡Öžjw¸µ'¢ðÉ'Ÿ|òÉ'!†’¢h"(ôN~U©õ¨ ¥šÃ">+ Bp¸vÝÚn_îÐãI*+–34¯Iä2´µ#À«„=‚Fr- ûxª1¢˜„‚„â7mìF:’é ,X°k÷®²,=5Ó=È—ž­xín•I¢ÿçõŸÆ6üâògׯüË¿{è“;ÿÒjœ h¤œT¥íÌhš¦ÐúÕØð×ÈDY˜L’AüDy”»›÷\…^yÅF'ÜÊ(€J²´KŠ “õ‹†8]³!§ §Ò-¬Ö†ÝeY|d¥Fʃ޸i½³2W`®ŸÀb'°Ú!d‰Ú»ØaY•ï¡ìøIÄø‰H<ƒruÑÀŸãE·Àï1B œ!+¨Aûш1Béµ]Eà“J¤‰v5rÞr”¹e m蚨«]¸+!ü$ŽcCT¸ÕÔ´ŠÚ¦Už´°O¸üUל‡³¡úEY~C­°�°gÏ^°UÐÎ]; *BìæGK›Î ¡‡>èÄñR$Ý M8È4=ÜÓUŠé§TD0éa’—a¢Y^åáz"PN@#M%»Õ£)ôÃÞ}{åž•‹¸ÔNõä{¥XHx½K7[ð~€³ÒtP®9¡&íi:¼{ÏnOs^B>ÝÅ$•7®G€¼«!%Üt``àÈëGèç]»wy;˜J_@z;=ö|RçøôÓO÷æå£y }敯ÞÛüV†é¿ä°sç�e‰¿>ð7‹x¸õ?ÿ©øé¥@U[ÆAŒ´ûÔè^eÓÚ4ûëÌY_`—ÑÇ£óoãc¶§Àe½&ƒu(˜4¦9ØRéö±#˜„M¾ãuHü5C…ÕobP¡E1…!˜ññ¿uòÉ~½†¡UX!ô±ÉY¡Ã˜jJÙK=k7nkàÉ•*XÛ@|‚I¼ÊóÂ/ ‰V7±²chx:®¹5´;†¯nZ#Cí±g#<åQ¼«Ð—ðWºIZ7µ×–yHáNmªW,uÕA2®wönèXìñ{2¢àmM„qÊ‹ÊùÐØnæî®|Zµ I=³!¶}€U9U "ªn×»MSoÀTz«e  Š˜»vbÀYMDÎ xæ)M5·mß&ÂKÙ(Oõ%Z÷Í8Ñcù#ÔÜ»oïáC‡:ÜÍsn3£t„Ë}oÞOÛ‘é+Çd+íò iHFK[ BÍO•ÞãíÛ·»… ÍmøÇ;víÞ5ۇЛ[½$dÒgÆÏT~a<Ï£ 彯ßíÛ·Éî¸ò¨G1eÊE×)‡`ñˆ½ò RËe <T^¦ˆŠ·²5Xƒw' M‘Uxˆ\ߘÉiÆÙÁD“WR²â•¥hry³†±aL5aLMÑç&–€­ûj‚fò§ æg*:UऔÂ5©1a&¦³(ÅÉH‡0gLCë×Xº¡Í`ýíØý‡•ÂŽ`²]DIšÌŒH(yÚœsR'WbÙsÓaLòœkÖŸ FMÇŽñ&ãmÆvƒC�:¶›ÅRF÷R“×ܵ³WÃ'‘ÞéÚ:QÞMÇ=Ø'‘2]£ïÐñ=Üa½¬Ç…g¤ì/ïÄÂM>éá– u¹IU/6’D+¢›úØè¦ýO8xÙUýØÁw«ÑIéX—‘Ãý¾œý–¸`ÁBîܬ<<ˆ“fv¬;Eü"Yšw;¥Êv¦dƒ‡ ´@ãÑ#Gï!døäæÍ›Ä‡A½xQig@›ŒÁÁAººxñbÙ:ÈaÌ8=Éœ7ó´mòè&|ï¸råÊ<pwO²8;eÝTØŒþE›ÌIGÂF©c†¾XÿRSb>]œ¼€X©“ª O5±b…뇥æO€i•,¼-é`‚ƒ\u¼š›Š,n±Y+E¬«_ÝÞ“îi¡ªÄâ-'³‰«ÐŠHGxÍÂàÅðoP{ã9c}_ ä¨3ËøbuÖŽõ¾Ã™*-&ˆ™Ú$®üG¸fj¹²5©/40L¤•pøh#óB¾,6Å|”n¸ŠìŠÝ2͉Ó*ž—Tq¾Ì$9½HßÓ©£*`.BŽë¾iÉ ÖõXFíŇU6/½Ð1¹sµÞž½{Ð7Є¶$£ÔÞÖguñK9d¯¬mj®¬±™t+Ûwl—{Ò?—<°ä™gŸ!à©×ëÝ4 3ÒÍÉ«d¢••gúàäcòF6_úÑKýÍÞëþ±°òž!ÄÒ-ôE’·VY?}êôÚuk;èÐg¼ý=PS°3ìô>zr…=Î% Ãè%¯“”Ø/”<RwƒLnFÛ-„"(¯åªëÖ‚±â»¼º5ªu‹«©äb%…­X^ä•!µÛ;«*±WÕÌ×`Ù|¢ìóŠÉ ®f[EŒNѲ�“Ëù¸;ÅwËQáÊ#äôxñ«;8œºD¨Ð<ë· i(¿Á‘Hlr] (Ý„¯ÒßÁêf¹Ò"¢Ó;Oü_½f¼ŸµmaˆX ÊØ„±D^y¶è’ÓÙŒý§žB©ìt†s¢ÝîàÅs¦eYz=N”­¤a„äàà`¸BFnظÐQتÄvnÛ¾M;ÏUl «Jµ²îèÕ­2ÕÒ«{8'˜­[iß8+_šzvj¥ÖË/½üâ^¤S%&5ºð9;®QS'¨x%G¯SH(Hæˆ^Z~öÚÒá§Î%K–v’X>)¹Víêõ:ag7Æ©[¡úyDcgØLÕOÞ8oÞ¼Izc­:ÖÀ)L]Û¬{—È#•ÆI•5ò—Õ£ï=üäÉa3ÎÒ¥c%ß°tJ­nv¡LõtWÉ $Ö^t Û‡>¦Ø¤¶-Í]ÅGÇ{Ê”ÕþŠ¥@"É©$ðÕÿÜ«ãÒ1\¼Ô’%ÉM««`çÔÈ kÅ5 ŸLË}_)»ì‚)Ÿ*­ûÒ¤,í•ÅŠ†1,Ì]IKµ o®_9Ħn 6L‰H¥çš¤a:9Gƒ±~*³µRô+ìâEtyH_ùy¥=l´ 3U\EUœµ÷l©û ÅDE¼ Ÿ6|†¬ ïtv“e¹ÎÎmÛ¶WBÅÙ;wíôV(ÓÂdÁ ¡¦¬Ý¢ûŸÙßcsÝ?pö£»ñ–¼Yç‘×ìÚ½kFàìF ,åúù™gŸùæ7¿ `Ù²eÄ8?üðCÍNºçéS§÷=µ¯Oà„«‡ª¼ò)Ú *ÂÚCÎ,X°àÕW^5_šõ©÷ÆüÎðè!äÍ´}Çv œ(†-ORØö:>þøã°XùX‚ãGŽJòh·C{Eõ¸nèCiÕ8+¿xòðsçΆÀ P 5Œ51ÈÿŒe *Q<£RøMAFM1nåa‰Œ§BåG*uªHx ,’… ’p CM‘ÊÖGî71¸ïªgËT­Ub 5íñ°…QÊJÍsŸà¦Wªb¥§õ� ޱ>¨4ÔXÃûààÆ”*l¦âÈUb'(­†±c[¥„§ S·©ÂI8îû¢÷A#âÑF2TòxØ‹Næ” ñ¢§Š;˜ ý0Qå‘6Ê%jf<Ìÿ >Ô�©îöóR3©™“™ÂåˆÝy’Tmæ$z6鞚顎}Eð´–î»Eò¢Š}¢ç+úG?^íjÊÏÛ¶o£iÎùö#¥ÙDoèSÆH wϤ†D›G^?²¨ê¨œQévx¨YyŸþà‡3¢&x„¦wéxV‡Þ»ÈkmÞ²¹GqøéýO?½ÿiTd|÷{ßõn¡A¦ãÇŽ¿uþ­Å‹ Üj&ò‚ظi# ¥ÐåZPu„¨t;Í•Ê=ÞéÑÙ{æ™ÜçgÌú šXÝ °ùû„ê!Aa›a$$f¼2’\FÐÈ¿+Ÿ!§›˜»6ÜCi/QÃÐ\ŠQ¼¯›OáÔkcª‘ñ:… ø„õ,-·1‹Y®´mÎh”y¡QŠz¦ìPðHÔ2íI+Õ´Ë•)ObzÉîó+\òê±–bÓ|eHCŸH¦üÙ%5w÷æÃrëÀ9&]JŽÆFn$št7.¬‘±3$…91ÇW!­¡m„?äªé˜*ÈÑ' ~@±×vëØ™—oÊ_§Ì5ŠÒxÄ´Y©Em׬�®C^ì—Ö}ŸÛØýAÏtæÊ_"ë2£RTü¡òáͶ‡G¨ýѨ)·Ü‰Dèž„šdÈ×ÿ£È�<úéÑ Í;5ç Ô×C¢ÿÔŸ#øüRÃׂCèf7ì”{†×t}šËæÕ*<ô¾§OËõì\¶eë–¦B3þQÌö˜1‡ü¾ž¿-*MLÄCÎø¾–¼Í·£,…çPŠ¢×}ª�� �IDATŒ’2FRwÙJÌ™6%®G«q±¹€ï°+\ö–(¤7áaÓNdtÂ^b;Þ ã¨©~­ãØ Æ1¿hw�'«*5 ®m¯öà•boÑ¥ðÈ®rRžG¶MPÆSØÖVˆ,ÿIUœ™á匩àQ"MmC«ñ$óˆÜ| v$ƒ? 2UØ“òÙÚù%r‘˜ÍÂ)S¨©¯L®fœýçÂÄÝÛeÊüVË}µ3Q8Äf#Xˆö4ÚüÏŒñ‚3½ÐÐT™Á‹V¶o‹ ·:‹£Ýnë½ÿæ-›O?qûöíûî»ï왳›6oº~ýú->$ƒÊV'ŽŸ(ËRÖ/=À.Îs÷$„Üê¾zPèÝòåË—/_þ||ãßøÆ7¾!H©¡‚0ïð¡Ã˜Sòšwh' q¸•²ªk{¸4xwÐ7 É®œÐè‡U‡„Œªµº [é ´k÷.ļ“c©:úÇþ>Ÿ¼Oÿ?!ýò["Çî}ïëR€Êa£ÁRg]JåÐÍx*µÉ8x5L-TØúgf·Þf…5ƒ˜EbI›È/ðÂUÇll›Ë=G0ÉŸ1å‚›JˆSB’Úˆ2r¥Ñ*b.ü^döã¼tË'±€3Ò†vòÆm^2ÔV³�9;ò ` Q™zFè”uF‰{Ÿl8 U±´ïz ÃŽg“Œ]:Ÿ{æÌµs’²gÂÙÝu%Š9±ÜØ×0Æáh°—®Ÿ¶ggŸªzlø°Çªá¨¸1zÝØúú.QU=-SQ#U©¢©z㱫âI»¨d=£¢4HEÀ¢ïµÑéz„ÖqÝ ÁÇOS{¬Û‚[éáþÎÛïôðv¯´J—§/¾øB¬ÈÁõfÕá9Áž:yŠ~¸O[¶néGÿY™Bó‹á£È^>úè£Ï>ûljjêòåË—/_~þûÏ?ÿýçÃç!ѦvÛ ;§Õ1[ì™q®±3Ò)¶|?~çÇ^órËÖ-éú4]ŸzõpzÎ#¯ÑòJ?ý{¿mò°ó+]ª•h@ét:-™H¼å2¶MO—ëå#WIL‰ …•¥Ø�D•XÉß.•RÛ(Þ¯aH6ï ÌtC+'Ãw~`bà°4ÉêQ9š2i©; •SJ˜¶z%8i‘‘=^ m½ÙÝF†pÝÌN…ËRÇÎúϱ<‡Z˜æF“å™±\9W<,S6ë;Á©g-G(ue]îípmñ™f•±ùÈœñ›ÌÀêt}8IfHݹ0V ¶°×íÕXŶ¤ÜÎÌŸö+cuXRÕ),Ô×»à’\{X?íDõà¼÷Òi@F½_e &áN[! ¤˜UFJX†•u¼wF# 2µ¿ë¹³çÞyûù^qÆO{ªWâa¦fE´K 6óðÃ?üðÃßúÖ·}ôÑG}ô›ßüæ7¿ù͇~˜ÌZ Èi¡?ÿæùí;¶{Õ¼v»MKð•+W®\¹òé§Ÿ~øá‡~ø!¹’ö�¼Jÿ<êA†¼³Ÿã‘Gyä‘GúGÍÑEH'6ûªðÎÝòUı¯Ÿ®v·R¶%­ÜôHVùêþ§L+os؆©MäìÄç‘ð³1½çáN§Ò“¤U—e¬êŠqhÚîfÄ—¬]Ý.vB4ÔQ¸é›<ù. KÄ(щZÊZ/³–HF1%j^éü)Á*·¸¬ûOÊÉ Æ ã;Äj5,jÑPÓâe¢î F +%†ß©­ú™Ø«"ãT þ*Ð;We�Æ£™Ž¶ÚÓ<S[”gR ÒJm}§5À:V3n @³hÙiô:ð£Tfl”ŸóqåêÚ&^Ü4}7¸—:þhñNÜß_Ppܬ r{†*TÕQÞÎ.FºVòú9üÚáÏüü‡?úaçáXäIKÿºtÝòF%nUš¡b}ïñïéœ'ÈkDÇß¡hý†õ3>ÉïýÞïøÖ·¾uÿý÷ã¿ñî}·ònÆ+g _¨ð0I_êð ˜zúÓk×­]»níÙ7ΆÁ&Äø‰´8~âðk‡Áã:¿úÕ¯p7¨[I¨™®OõïgdSß¡4ÒíO<ù–V_´þ­yîä¨ä¾•B$‰Ö©|sø«>]‹ÃRm®:j‰ÝtS‘°Ô›ýÄÕ7B­ò9ÊX •zS¥,öÉ-e\Ã1³L*ÀÎ(½K)â1Ìö†´S¹}VVC­µ˜…¯©…ó�ø`“ԀƷ]É>Å 7I4QQ‘paZwVv¤jÑÐV¨*œu©%2]sü’bí6À½À‚ˆ¾ -I‰€rÃZF°ÚºkeP#‚*¯}Û­ÇZ¹2¬b®øwƽm*?š/r阫ÇDú §LQR'87E{SÔõêÕ¶³ë|d~Arl\V‡:dfÛ±+£õÚŠ¹KR3—ÓWf–¥nwSÚ±EÐOõ°6ôÎíÚà<vô˜#õüsÏËu;­ª'J@¨)üïÜÙsaY8l¶é†PﲞÌÓã6:S"ÌBÆ>ú(€oüá7�ÄqÇñÐÐwŸÊŒI’«=ÞòMPp f·ûœ8~bÿ3û÷îqì^~éåí;¶·Ûív»]™$ÚæCÿö·ß!Z&­èõÖv~ñÅ¥:¨™]–¥Hr²s™´<uû“Ží;¶WÖ·Ÿxò �okFÜg³S³íþó ó¤fê³.]d]ÂÌø•i-j»ÃpzÅÉ:e%Õ?‹¬V„’Ö¾–S*e…Êug´S&S&W<®…®ÔrP5°_À„bæŠÎº‹¯Yß .rÊÔ©Ž¦"ΞqL•[»¡ó« |&fT6ÿ,µ–²Ñ{WŠ™º˜LéŒ îr]×tòDÀÜÄÅ5XfôArñå}ñœ R³\)öO(Ã3”MŒQ-©86>³Ï(S×. A”Õ¢6H½zc^ÃG‰tXŠÄï¤ÁC õƒÛÙµP䙨*tïYOÅöJI%ó>”40ñ‰Ý²pVu·ðÐcÇqy]¦„Êp!¹+|>ûܳŸ¯¼üʲeËžîùwÿë»{÷ìýÉûÉŸþéŸRSßÿì Ò³„l/lajŠùÎÛï‚örÙÞõ¦Í›6mÞ4~z|```ÓæMÇŽ»qãÆÉ'×oXãÆ AMoF…Ÿºx+’¥UÿË*® 8ñ@Ý#OÓÓÓÙ¹,Õ˜ñ˜qÖì9ÄNÒ.j.^¼ø¿³wÏ^’5½üÒËtiz¯Ý'ŽŸX¿a}¸É ÖÛ¢¨&LV·™”–sß}÷ Ö ÄjÑÙÂ… ½.©>I êòÞ²&â|t>Ýü•fü\zìfÂç^{7Kµ(1M6Q×ÉPl¼bÃu\‰r«1ı å#ãdEåÖl%²ž¨5 utÙ6ò´ø:^ƒÇðK 2ÕH¥#×–Ç”#Abj›+ma¯¹Ïë ¼M©úšªrV´v øÑÈ «–L&"(o£,\L\zJ?S%ÜéûŠ­Ìdö©ÊÔ¸ EJ™ØTU/MŒLTÒâørñ%RZ-+Òé%�²‘ˆÜ î/‰Øu”Í 5Xq Œ<cB¥={´L[d8Cü*^‘³p½v=âØ­øìAlÊg•w©”ꊮw7]:öêÛZÊ›Ï×ê]¿Öºp#üêÁW<ýÔÓ{÷ìý‡æ?<ú—~øÑ‡—ÿõe�ÿøÿ衦°:ÂNéwnݶµç¤H+¨¹~ÃúÁÁÁ×_{]|*±äÐÁCB{GOhø ?;®+´ýTk|ëß| À¯/ÿú‘ß{¤Û}4éݵ{×¥v¹×M!‡}Âuß#{öžÖØI•ÛW^~E_Æw~üÎ_|÷/~òß~àÔéS¿Â¯úìkz•ísgÏõyÅD»vVŠªæããM<k{:­â–XÝ •õĈhªgôå˜7àŒ\ïì(BM�S®YÓ5é‰2RF^ÃILPSÕ$›PTšoS˜üÖ]p˜Çòi¸V‰ÛÓ2XÅJC Û¹ñ õJ§0Üqæ7¼jª@,¹°N6qQÒEœU”ÚŽ]T± rŸO[jõ/¤²-ç£lÇ/‰ýL+:3€] `Oð‹uœ|iËótè·"Áæge„Ĥ<Ò3‘š¼fŽ=ºv#Bêyº¦QÚX'vnë:w¿vêB«gfš#æU¨™îKP×UpèÍŸä.ŽV–dÓ.È= ÷êê=ú—þCóð¹ñ¡‡ðá‡Êj²æ/×Üzà¡`­V»Û’™µió¦Û¸]I:×oX®\¹òWÿù¯Îý_ç}ÛƒÖ¥]#ú硃‡zÇGψ´î y¢“ìÁ·._¾¼`Áüü÷Æÿ�üäÿýÉ?áŸ~ó›ßTÞY,Ï!ÄcV‡ˆƒè-‚ž=s–ôû/|‹ 3û—ùzÈ_üŸ ÕjݼySçšyÇ矮±Gƒ%1õÛraÚWä¸+“0]«© ±²Ómm¯×ÐmW4pVæÉ2ÕÝÑ´8 P^¯ÜÎÌÙÏø‰³ŒmRži#ÙŽø´E\:6K¿3SÏfS¡>5Œ)`3ÿOæ«TmZì„}û¥r¤³®÷PÕ6Å #¨ÌÂ¥P ÓôÌ5¼Í8­eiœ©'Ó+´xÊ-ååü®És uœŠùÉî„QÍ– �D±KË$üRW =ã:ùÇ$6ÒžP°§a2v¿-Ž[/‚pŸÓàkWTbj²®[\ÚsS8)5ª¥Þø“ ¨qÇÎÂV""‚€¸>p«»öݲɺ”óðëË¿~dä�âC�T§]¼x±üå?øàƒ•tJ×l{ó¼°èWé¨~òÄÉ;wy¥slïsÈ\»ní²eËÈÂ^'tÖëu:|ûÿö{ÿ÷{XŠÿ0úˆ´õ8¬×A“ñ•¾€7nܘ›_ÑÍÁÁÁ븾|ùrºqçcšsìø±Ûw¼xàE°O,M:§í^yöÜÙs?ñ¸|è²mÒë¾ýÑÔ=£žú )ÒYÁ§äœhþ}otI½Kµ©ÒI*0³±Yî¢cÛ~C -¬]õH4é–@ׄ]VÀbÓCXÑÀà$a¨#X=…v'j±´*DSs‹ØõyÉu³Ìà‹±­¸ÄMY¨s)Ki;µâ|Ä“-ôÜË‚V/™}ÂÐÞ^¢„{œ©JõB€RÔû¤3O«ê‡:ÍM}šPž±ž”¬Š2µ9€öå1y–2 Yjë6h˜ÖÐîD`U^ö¹ÛÎæW¨FæVt¡>¬¼Ò VU¡•>9 › ±ûXöñ~•Uagø–ÃOÇ›Hɺ§xÎ|L_›0øûƒ~ô¡×�›‘íõÓ̸ªÜ°ëj¡§Zš5½èÝ–óØÀÚ'מ9{¦@±qÃÆ·Þ~ëW_¸vía¶çÒ®×ËNñ„Ñ{üÚ×¾@¨¡Dß¹×Òþ§÷¢è—ø¥¤RKU¹Gš·Ë!Õ˜Ñgqr>¢Ü¼ïÐÖÃVÍ(VuÙv¶>Ms<•WŸq±°êF¯ö¥œÉL\"9Œ¿ß€T\c0ÅAKcÄáYМµ¦Pa¶iD:† èYkf8ª ˜wÌúÞ²ƒ.ßMßpžç÷ ¡åFO#U\SªvÓÜBLÝ©Ü%R–Fñ~Ã<ž˜*†[J§mô-vÆl3›WM;h¡M¡üRe/g`²i·^;9QÝÊB%PB ðÄxݱ¬-wxUv¯áÔ£”s‹.ÆuaOÑûì’€á9„¾{]4ë2—â}”‚v Ó2žÇB˜Ô­ZK?ø=Λ7oŸ ÕüÓO?¥Uòüü|ýß~ý+ï{ UiÃÆ ¨ù ¼ééé~4«s;t|Gÿ¨9~ÚJéÝ%föÂ>ÂG/xñÕƒ¯^Æå>9®_U£™ î=r´rŒ’–Ñ/سw°gïž×Ž¿Fƒ³Þ©öÎu¡çét:^8°ï©}×®]k£-¨000 eäÞ~|TZï}²Î«‰½GswáÐsè\V¦µÈ§C_!¯G@㤳Î,øÛv3.� mȪgã–d—$ 2‹—MŠn–<êDUe/`Ö;ÎÞ‘Z¥CÅ0¦h°Á8µ!P‘¥A|7kLϧQ¨n/ÜqÍóŒ`ºéë>$…#í¨ò 1™b¨jÞÀÀc¶djé2,ÿö"Ã"ÊXN”/Ü݃:aÛQΤH.((+2]+ño2P#J¸;Š©†æ¬¶ÞŽªreÂUåÔ£ÈMŸÌY”Zƒw/à;êûæ¹óÄ ±b÷«Wùd.Â…œXWP³0óKõVCŒ7µhu=ó*�΃mM%Ìã=/ô­štR'ïþèôúoÿ4¼§(SÂl%Ý ›d•KLåšEuZ¹g,èkö>};zÌX=,Á‹^|áÀ ¨Ïq Ô”c箢ꤥŸ<.\øÔ¾§¼x`Ú˜RUÛMèç‘æ±ð~!©^80ã¹ÉÞ²uËñ“Ç+ç/>7oÙŒ…Î¥¾ÿþû ´èbÒ ã<@ØpýúõyB5ïøÚ×¾F—Qº³÷ÒxènN§G¸›Wmîúñì`äM¤4“ÀSw°‚R^¾©ÊF²�r޵rB=¹»Ê_T¥ÝDé3eIŠ)“µVOÝÆg½Y®äJæ•[yöѳϪB¯Š!¿ñ–«0¥.·ØÇ ÎïÚ[Ü 3cZÆLéÈ¿Wr²ÄÆ\=è©V[ƒ•KM؉ɭê”u”Á4;ï˜½Ž¸!òØ «˜çoà1š‰&ùCÏU3Ïëüy4ËdŒ°I!ªÒB2FM=Y ´É«‚Dt˰Ð[×Q6U~¶º¬ý°ìç¡©nÅRQ…kLòE€íõACç[õ‡j£`zu:þóŸÿüç?¿téÒßÿýßÿ«¯ÿ«‰ÿ21ñ_&Èøæúõë$éܳw-ñçΞóhJ¥kÏ= ›![¢3ñܺ{Lѽvøµ›7o~úé§BÚí¶çx‚qqmoKÒžÞ…¯~¢fBf|õêÕ£GŽ úRQ— óÄñ^8pýúuJ";tðP?c‹tn§NžÒ'¹~Ãzù_ŸJév;Äï°[Q·÷!“'4¾²pá¡¡!±yºÝ帻_¿{ßàìœeªF¥—)$ÌÙ£ƒV cÖyÕp1¶s¹‚µâ5n²$e®ãL¢f Í2ªŒO¡$3ª… ¨èGwóe²>òc·¼füßÍ«ZëÆT]Þ~Hµ5DfFòí„e¦/¯¹8‘Á¿f¹Èebdï›"m$Šš™vÎ*Ê I‚eÍo“LJX³\© z´°Imë`‚;¸©×ÌS]¯¦í¨jh3gjú(u'Ñ…°ê¡Iç4Ü:O%ëhq¹@ÎMŠ£²•ð¸ÌÒRUNþòú—Y€¦áÏ™À’jõÍ~ý-º”|*¸d ÷ÏÿüÏÿñÿø¯|õ—¿üå/ùË>úè£>ºq㆞T£VƒVÿ£ w÷ éfoSÀ9”‚{„Ê4éO~o2äwôÈÑ»vîܵóG?üÑ~ø£Ý»vxjßSÇOÔ¤íˆxº†Öqk×­%‘p,O:ö=µàóô©Ó3º–Ï*¦ÛAFÁäGøÕ!sÝRÉȱÝnÓϽA½·3Ÿðwý-„ã(Μw+c1?ãÿ:#€ÜkL#˜n–+EˆÁx(j&ŽØJî(R 4múV/ºz¦ÂI"]JÍÔ$FZC{•‘ Iª¦‰ØÙ˜…µÔ£úyGôJ¨“,Üú-=dL½‘Ô³PPS•ph"R”hÀ›f1ÅILu¬Ô(•aY=YKt¶) -3M61è[ç—@”T…~g\ß^ÍŽöƒPúUÝÀó�2ï‚ Yà㓪RÁ„Û‚Í‘jXY-Üþªîæ¹ w Òž?gÝ9(£ÇŠ¡”¬{Q·ëñܳÏÑXgx|ñÅżpáB§ñ³Êîîô¸‡ "s¥šž¬5šžnÚ¼©2¹O¢¹~Ãz­kñ•D0!—ò‰k<A¦†rò[¶n!Ó8*$M”\å瞀`§”X{iµ XL+4w箇Ž’Júáè‘£vîÚ½K4®ò؃¯ü²¶;s;èªÎ­÷<}ŸéªÒ·Bζăûgà »Ü®ŠoF¢’jrW/á&Y‹›ˆaESu4œàèTS !ŒëÊE¡°îÞJ×£–ݬ’41ËtY¬7�ˆ!@ÖÁDC71ÚŽïGcp%\î;h{Rà3wÇ1s«Y­n˜™qR ùQìöeMy“VcÇ%#ñ@ÐAy³Â¤Ý–HMí:‚5»a¾Ž¯qµ*Ó¦�ËyŸ¡ÕCY0!šº½sÚ‚$j 3WEþШ½p˰^÷=už'º€t>þyxœÛ]G©<Ã,p ¬…/·®Û_ìG}tþÍó;vîøxÑÇý/ÂíBÇùg¨ÜÑX;~zœFæ{2SH =³¬ûÞÆë¶­X`o¤F)i…*+«FASEÎŒŸ¡‘MšÚ #*gŒAT#$~éå—hç±}ßöƒ‡¶Z­¯0ùÙ3ge¥òùåþ¥¼Y Õo¹ÿQ ]妎9zàź*Kl[L\»•ˆe;BïâÎCÙ~÷Ž…•·J§hÚ§â EâŸÙ°%"Y9cl>ÀöClTÆ(ÓRDÝn,,ε‚‚ž#�©¡ÝáõÚóœ±â‚©£30«É9_{‚Q¼ß(WšaÇ(uŒ‡À~@2Èá0¹Ø>¹RÙÙC@5#˜Ë¢Ì—È MÃÉ/S¦‘}ÑšuÕŸ°Ó‡¥¾¡p´0—¦˜;nJvâãÌÀȃró(rŠpUµÚ@G—å½ÒhR~û³ÅÅ/‚ WOd”uéâg.¨ÇAW²ËÖ‡k°®'ÜËU1,T™eÖGïæAà·{Ïî×Ͼ. J^ô_kèà *ÔpÓæMÓ·§uåsÆ—£ç÷àSP“ Œ´¶hÇÎÇÞ8Öm:åÈëG;·lÝòÚÉ×è"šäçNtóø±ã•0)MÁ%T ÕN¯Ý¸¦ùI—-Z´ÿ™ýO½üÔÞ}{+‡b5jz¤Ó;„Ñö8ˆq|õ �n6+{ ï AÐ=8•?ûì³_±ò›#¯ ñÃ*¢ÜË£›Ñôïÿü¯þÓØ†_\þìú•ùw}²sçNU¢,\ÿ3›˜È–Ú™SUtžp¨OTÉÌ‚FÊaÀ¥&I°ÍWFB˜XƒeïáÛìþ3጖FE°–%Ú±HáDážwJ°uà°RUo*#q—cø”Ýsûƒ~*¨Úo¦gFoâŠÚ#ÓMzw6ÇÍ>•‡4•~r²Åáy›êiÑ%µ#À0»©„TBN‘ªs•ÔäL tU⯒í"ÐEPŒMÿ„,àšqÆéU_g41ÈúCʬ,-㤱…­[·Uò6iu+OÉAø¤Yã믽.Ø©)¦FMÍA+¥¶•Æ+ÞùvVz |­$/M€�¼ô£—5¼~D¸Ú©“§Ä‹\/Çá‚ë] BMú¯Ç±¤H: òÉ{ååWh¼=}øÎŒŸ©ô¤®§¼–FšnËô¡ƒ‡žÿþótVG^?§@Hå$ ”s:í ä¯^½:#ãô>eÂÂã¼!òõ8·þ.¢Ü9�çŒ_ËÞ_`}yy@Yâ¯üÍânýÏ*~z龞äÄHtÜ„x�‰¸FœÒÆØ -Iµ¨YÔ4±Ò¢F1"—”%9tíÛžs›ÓŽiL^À*ÊQ:þ\e>Ãí®iU0·è¬mnJÄ E%•„¥J ÿW*„9Tô¦ÀÛH4YU¦c«„RA] ¶Ó‹u¼ k^bv±핬ì)8hCZo†RÃFẜS+®e!ÙêqRWÛ¢ç_ÝiÅÈiÑ‘VˆÏÊ!¡7Îåní>¨Æ yüÿÚ{»;ª,]pE:Ç'3mlÀ¸€&Z@KB­©V«§Ÿ(•æ>ô„æ¾Ì­é—Éu« (üoSü™ l .ü½ù«ÂRÏKß~¸O1%J}¥inuKƒ²¤âÒDC7`cãŸtæI;óÌʽbí½ÖŽsò×6µ—JŸ<'Nœˆ“ûÛß·ÖúVÎ*QpöñÛ"Üë•åšßzÁ†äxæ…y€’‚ö™‡Ÿìqî`ÌÉmÀ OkÝõÄ.BM.çj>ùÔ“£££CZ¨Ç'Ómzþß÷ØÑcrNòöÛ½ÂÎA÷îÙ‹ÿ¡Ç½§[ªÝ=;å›'_^¾|™ªg·nÛºï•}?yò'?ßÿsü¯áÈr¢ˆä»ýǹsç¨òèÔÉSÜ<}ff¦yæ%Þ ä¸là ‡‡‡ùq®Ø¸téÒÑ#G÷½²oß+ûn"ÉôøÇå Ÿë"ÕÛŽ 4î‘Èe Öwœ½<Õ†ÔËA§ª†ŸÙT“ÏÔ¦?«Æ:ÒD&+ƒÈx†iÅàù”Ús°â[ÂЧ¦\cðàx]—DlÎ '¯Ìî»J(Ák6lé™ÑÛ¼`BöCEmÀˆf 6VÖH.îºi שXK —RÕÖF#zóÚÙ€sñÄQ˜-¿Œü8¶ò‹™)ÚWyÌ•ÌüÒš^×·Æ1üó <¢ìɹÖêÈ?Ï<Ü[™»Æ³ ø°+Ùu?¬Âåûæ}h°R×-COE»ÅúãGÆÉ³†\¶}|Óã°x Q(?Ÿ*�� �IDATêQ ü?ÇN„L’jçdÏ&;P9j"é$B†-°ÕLÍ!@à þ*PšGð†uóAOàó±a6³ýk¼ï½ûý¼ï•}Ï¿ð<X»W*ë)Õ‚mõ61üÃÒ3‡††Šq$ÝTQs±pNͦ83èBeNä îS<M€ØHžAÌ”—H˜ ÿº)# HqtØQ§$˜ÊW6Á#so7L䬧CcRÚÕAºi,qä@`±Í-šM8Tå06k›±4¤ÇWR­³\ Âª]‚|6jªKþ¿Æz«1xp<a ùrVVS+–cðàx×/HvÜŽÆÒõ„"/‹”}@pMïø\èÚ+q<©}šÜh²§g¢‹aSHék³¾ã¿œZ>Œ[R”;¾ +ÑHÎοr¡1Q7 ¹Ž²:§Ì5ÅXjÔ)@·§ų/+V¬˜kcû×ìzbµöKìTa{®–î¤ ¾üÒË ðI)X‚±z0²T¤Ë’CCC—.]zû­·ùêéééÑÑÑ'~ò—UÉ®ÏÅ÷ä›'wìÜÑð’’Ú³µ´!ÐÕ¡àüá~¶'²ÓéLŒNb922²D¶ `Ü*‹û‰ÎÊŽ„[~dÎËûœSÝ3„T‹ýN¿?ÍåH[õ8­Ó¶ÃÒ¸C˜3¯—®m¢Mcð [S숮Ä3ˆOò 5»tLšº…ÊaÞö<h×<çÓl 1Õ‹¦ìü½¾ $šF#g¹{AhYÏ5-k¾â]çùºŒJ�²F²²d Á‡lPvuI­XöŽç�b†5y(Ý¥<³¯õ–õÒ7¯A;á6Æ=[úNÓj‡QmS€%€sÀÙÙ;b'kÚÄéÜúLwøZîn_Ò@ù˜aO(Y‰µÓ4Ë@Z¼l'‘‹“áÏ—–ôÒG0—†·-˜dÊöB—$¯+¬iÀäää×lß±}ff¦ÝnË®öüð¨ãq‰ïð¡Ã»žØEr+O|öÙØÞ5ßô8)óH˜gnг’¢y65sÿkûñ‡æêžùY8q•»Ab•À°ió¦;wx/iµZo¿õ6v16 •#-.Q»¹bzz{[£' Õrœ‰·2¶SÞ¸íz†¥6iQ(ÜBœWßX' ãúªä8øì·�PVÙ>«O¢»ÛzhÜñg ›[l™RÊj:JÆ53;Ú¸i°¼Î·%Þbg˜i_îºÕg $‚âLi× 7€ü;ð§r‘µhjØ%͘L ‚ÙØ“I@ H­~{&y¶ßß“7•Ê7Ú²áÔ^(n&º<RO]&Þ4Óó•M-.Rínî✱eyü]Ò@ŠÑ£ò<E ìÊ€ÆY½–›†Œ&Å*s}VÊœ‰zänx¦9#nxy;ÞQÐl}‚¿†éÖÌ´š_¹råå—^~ù¥—w=±‹ðõÔÉSmø¶–ÎÌÌ<úØ£;½™É—.]z$¬ƒÁÂ=h< ´§Ýü<¬ã8…GH†ôö[oSqÓœÕétV®\š@ ŽÀŒÎ!K¦~Îó›!:ì—0ØH.�fvìeæ9›Á‡ãÉhE×f ¨[æ‰Õ¨`EZ«&FàDEl"ÙÉ–eÌ»'VïÊÓccðáxm1hl%íF·¥CBŠŽ£F2W2Uï²FU ¢y½3—&cJcÆJ¥��þ ~óðt¶̘ÿ*w'`ÓBœŽgf‹ëóPŒuæ‡*YY5é«&œÆã]!·o~NÂæq' g\“߆VKÐ�LÂ“Åø/üRj¹yàåÅ¢0N=ݵ¢j6äV·lÝC½‰£žF¸ —±`U7yí>öhȇö-óÖ#ù#ˆs‚4¾¬Sšshh¨ê²í"«‰ïõŸ¿ŽU²äÇ„7ýÓ͹¢&íxHâ¾pႇšpCNÖ¤‹Ì™±º³!w{¼e###SSS7î†LÞs>aþ8ÃúÖyþÌÃ9Þ}€µ-âà­Òâ€M5ᇛÚä3¶ ½Ê-ÌAïu¦æ%«.‹jYb›F’ÔÂyùøøƒîwÇ’Ç™CM-<vs¬õí@»ã´úåZ²¶È©áÊÖ¿Øcr7€Ô¢uZ·ÐtSHŒ­]²åW]Ÿ|üŽ¡‹u OX‡“Hvru]ØHÀeQ^!±q†˜ÒÅq–û‚ÝVÏ”§T§£t‚VA™Vóuše[ÕvOÃh;®-­û¡ÒÆ#hÝ,îp=§·a4˜ø;r~• ï…RŒ$ò±2š˜›ìI‰ðZùfffšQ“†B`í«šÚl>‰Ö±Õäð¡Ã¼çÄ{Ω“§Ô¨GòGÞ2o!vöùî«W¯öôŽ;¦§§‰«5ôVba­%633#ûD©ž–Ãê¦Í›Ž¿yœ¿ ÞD¼ÂÔïèùQ{ãçÅ‹¯^½Ê;#‘k¡Z+!4}CHŸ¼.ƒ9¨¾r Ñ¤üAµXIEw|fƒ nˆq€¼êǧ 8ÂLÚ´”¸]z¦v'O*̳¨“y(˧t¡ \Ä,lZ™›¦M(›XЧpôÌn IùA÷»€’ûd…M ñ»ãk8ÏÜ¥áê´Ó}Xw”v»�ÐeWÒ1XÈ¡’ù”1Çê–dî€JbÛXÏRÎð<emÉÔu‹i�t¨pˆ¾6¾#·µZžwAê¶„B Ü eu×)«÷—=çB,-:¾ÏƒjbPu´-4Ž71Z§ ØMÈ:)Ys›ö\pTõÁCwîØÉ‰ ôáãJÈ7'ºÉº„:mÿV2ÔMñƒþ€ë8´oÙºåØÉc5‚ Ɖ«yd¾yâMµD]ûª¢’NçÔ°Ê= ¨E ›4\…0òÍoÖ> ÚzCw?  ²uÛVD²}¯ìÛ²y �¼óî;ô´ááaoh3m2®A ^5 ¾„9 °[·m]¹r%Mq‘°1'V½èAˆîQí¹†Ü3-nˆgÝh‹`»Àz ÑUœrNà”3t™ïZ7‡¤2—=#465švô5¿ü�~Ç“á«l Rnë’ê® Û:™²ŽˆúµTÌ€¦2t…Ä0_op¹¯ ”GÚþNL¦êí9CôÜÅ¡Ó;¬ßÂõdèb&¸.»õ—òÄzÐwý¾ «º¹ŸÑ¤‘) K&’’ùQCj]€:ºS3Á%jÆ~UÚ¬X¦F¦1xÐjI;€nÊæ–ÈŸ”•b•®3{®er7çjÜþÎÒųÌšMº)[ð‹È|¡5ÀZïåFûR÷„½Ò&ýóÀë5·lÝÒÐÙyìè1BÍcGÍ_¤õ$ß¹Ä~øú™c¼gW»eë–S'OmÙºÅkôl˜—ÂQ“�Lm6]ÉB=‚6"š;åH2ÄK„LF-NƒS<Ô|ô±GéþôOÿô¿üÅ?þ·üÇÿöýè¡¿ø‹¿øã?þcõ€£nÌ{õçä’Ow‘Õ^ü^Hgv>&Ek6øljŒ‰‰‰%:†Zø#kÖ¬Y³fWÐðò9Iµõ ´`c‡<êèó&4˜ð #%£A™%=™u'ÏXòÏxƒ#:Õž5|ééæ˜ïÁ­ÿPpŸa‹oÉÓ~ãuF°¨Ì亩µÂá@ÎȪ„dCn žºÜÎĈ‹–ºÜ×ó]3̃Óz§q)ÜüÒ•8S7A´Ì,fÈÔ[°¾“x2²ý¡ ºÈlLAf¹cðàx͹«Û7^Ÿ-} ?ÁúO2oÂ>2ÔF‰•ý¡×!*½×©)EÎãôÅUWüH]´£ãdlZ Ø™äRÎ5‚Sæþ—GQ¡9·æ¯•ÙVдYU1®ƒ<©©<‡ð졇ẩø®ƒ?ò0´­T 3sEM°Õ–~°óïýâáG¦”´ ásíuQÅRX9¹ozzzÍš5û^Ù÷òž—¯®½ �Oüä dŸ�ðƱ7$jz'püÄqžƒÄ5zxxøÅŸ½·Àµk×<8uò”j6ôßûßû?yÄNN 9¬6h°¸9èi ¸<rkƒøÁ÷=T²ÔlE$ƒ^¸Äª´Üa¥°j¢È* é´W+¥ ¸¶jüù…kVÇ\ñȶ²_8ã¨[Ž¥\úøÕð]¨¼ÙFõÞsÇÿDæÓÌøí´»¨Ýœö·ÿõ•ɼ¬·ð¹F¦ÞjÆàAê^j6©ÛikÒvN \Ÿ<çó‚2d41ØôRYÖEU^ê4`ÑW}öšýÁÕ*3>´¹–©Ì(¸LQêÿÐh#à¹4ÛÝõׯég(Aü”žøp .‚¦b êGãΨÕ½›ì}eï¹sçäÒpåÊ´}wþ°“õ:,'!3UY®¢.Ä6ê €CIlÚX éå¼Tdpp$_zI³ƒ }FÉTHœôDZÕ÷®!ÅÓ`”û|yÏË3˜_$ìäÀ‰gî½;f É» Î^;zn<%¢³/½üÒŸýÙŸÀŸÿùŸÀ}÷Þ÷?>þ¿ýíoÿùŸÿ�¸ËüÈȾ5[µÛí[n¹…¶Vè²{áÂ*‡‡‡ l8å#~8äx…<Þ3ù7G­¼åß"‰|êÝ¡gòyaòÌù;òî‘~î²ê7ÿ9rú°ÜËþßɇµ`½m¹«V+™¬ ipmÕª…¸íÀÁÍ«Òröà¶¡¶º­òsÀwñÄÐRjr‘PA"3.ÍÈxÈ6Áʶ)2•Y¹ÖN[°¾' ¢ÇæL &É$äe”Çá×Uamb«p=»×Ä8«v7§ÞS+t[‰'wVÒ±axb’Íø´s@;Ý6CÍR¤âØ}w´Q”’®å¦Lª-Yïo!\ëj>Çv2nA1תyKí e9q§[סɃOo ¦a”¹FsMðÎÁ„[«8{öìeôø;o¿Ó°p<üÈÈš?òðc?~ìä›'ñ¿9í¯IÄó8(Ï›’G< Ò`>ÑÏodd¤ëF§Ó!eo•A-fffÞ<ñfþhNºbH,mZO‘)¢?-�¼ô³—ðôöóþPþñã?–oºió¦'ŸzòøÇ÷¿¶xxóÓïýâ½uëÖáÏ4°óùŸ>ÿ½ÿô½ïý§ïÝwï}ˆšÍ)À9é± S-{AŒžn‹üF7lV¾1¡1N*FM<Êk¥HUsó1xpF™XÚv\P¯ ¡dÜ.kÁú{áãñî®í;0zW:VìJj˜¨8ZWù. —smb”[cßý;ð«àwŠssyçdJ—X{–ëv%‚Xwï¤~m38v€<­8­·¹‘å-™«g‚Fż)Ÿ âY´{0#ß1wmñ!Ly¶Ø#|^5¬|ŽHE+Iª'»šq,ăM7 NŸošmq<xhçŽ[¶n‘vØÇŽ{èᇼ” 1Nz„ÛâpàT¥B+ é¼víš—òôò¦8e*”¶öø44 ðJ8¹‘žytyÚ©9e8ó¦ì¯š— å;Áz, ÃßÎ];åtI¯ˆx'±D8Þ“úÞ/ÞCÁàÓO?•gddäž{î�ü?Æ¿þë¿þË¿ü çXxØ+Vì{eÖßÞÿýk×®�<øG}�_~ù%reõºõÏ8¹=^·Šƒ«#kÖ¬é“q’¼|ûí·¾rå òKÕ%_¾õ20N‘㬧*‚© 6üÙzéUT²F Êå 覺)Å66T¥¶õªÁÍó:pz˜øÉ§ƒU ZÔk Õ¹zÊù8ët´–~®a·/¢î*N›¥e-˜üÀ™KœW*13ë‚@o¥æÜš§×wãÒÄjº§ý°-’L¿!yM-¦¹l|¥Î4ºS2ð“ *m¡ê«÷‹‰“àîüvIf›PºnFxî÷„ ª©CTN å¹y¼B£nr§cϾҒ’† 7¹ÌTÀ¶dÆ­oØ@?Ê*:È€˜GÁW ìŽ@˜ä•/²ãB-o‘iH™7%=qü„:MŒÂsˆGHÔôQ+xû?,BæSO?…ër5TCÍÍ[6“Í/ýLË4®þ8\óµW_{û·g ¢ÅCCC_ýuh}çšç¹sç8ÒÐͽ)|Ø ,oÀhhGAl¦ÝC¨€| °e†V2i‹iÙàÉÊD¬BKÒS‰Jþ Ëœòμ§±ª“5‡¤Ì`Ö6ûÓ„Ë.|~ÅÆ,—¶[£p=K‹ª4´Nªñ•(­Þ±Ëës·Ì²à bÂ"çsim“T´r¨˜b×[ ý¬§S6Y×UÅV\§Ï2–|Ȥi’de—ç»äþ3)Ú +‡ægKoê•鬷Ljbf0Û¥/1N²—HùBÓTé$+M›|ؾ'ä$º÷1wÿ3îÉÈÑ`|^:¸Ú»œ[’ žjXY™Ñ&±TãbèLXA¯„ö za•,áþ×?6Èþ ” Cn2¤Ó¢Tëé´4SSÆ£=ŠéI|Xº}Çöý¯íßÿÚ~,–á1§z ¯ŸÒû'RÏy &Bþ zÊ#¹|ãØø|úA­@Ù°aÃÁCkÅÇÂàç_xþùžÇrÖU«V¡WÔððððð0ú1µZ­™™™C¡ÅÒÊ•+¹Ÿ‰·¼ØX-`^þù—ÍÁ­²®ï™¨×%­’X•Í õÿ1ïõ.ØyËÀJ±ö5·]wv2³+R%4ô#·æìÖ æ±tÛÀo௠rÍÍÉß •ldkœ+lVXÚ¾ä˜PŽÐ%|¼É)"Œ•&¶''É]9jO¸ºÆ's-ôòzˆ˜GVìÞš%”LÇ+;ßœ<Ëœb"_Ìĺ$°þû|‰'Ãú”;ʺC§Aˆ¢%$|¨?t“Œ2øDUÆwù³Û-5Xàå9ÂIAÃè5h¼ÖÓ�ròæV¥B›™Ô]-*{. mQÛd¬â�Výóø1éÌÎE-¾Ê LzS}P³¡2hËÖ-øî¡ù£ ͦžG`rÑœ2˜zÄ?4Ÿœ&ÂGc>‰ò*SÕ0öûÿùûïÿò}`s³Cï¾bÅ „Luº]vT,ñÿH›}|fsÉ(v:þþ÷¿ÿÿËøûÿò÷ÓÓÓßúÖ·�àóÏ?kÝpôäÑyÁæØIÞIœ¢ñe…?sÜ]ºtI-äQ'böOç<…A&Mø'ƒ%W=OCÎ1øp¼jÕ?m…Áj=í�›ÉÜÍ!©ÓŸLæ*­­96Np­¯¨ŠUÎ︂Û%µ’CsrPm›DÕÒé"¢‹„Ö"ÕÔ¤dæà…e„^k ° nÁª:5(­ pdNŽ{èðô¡7 «ð3¦’ë«”Û<qáÃCõÛLL_WnåmX¨ãG<-:ž< ¥èÈ„/«a¦Î{Sp«F vñ}ó ß ùö™tÎB3¨xªm*-E–7Hœ\sù;ÊΓPÖ³è5DLõ*µI¢~§ÿäääÈȦ|иçòåË8s㡇:ñö ü?a˜:OxÅŠÓÓÓ!˜”ãxÏuš âSÈØW¨={÷t:—¼ŒøÔ¿©Åæ-›U¶7¿Àã´Z-´(Ú¼eóÁc7oÙÌ›pC™™™ ™2‹Æ}d/ŠD5”a{Šçõ—õ‘üïÿËßÿÍÿñ7÷ýÝçŸÞ§}¼Ô!or‰¯‹söt½y5òâ«Õ¹ê3çgø àÿÇp¯mÕ/ïU•‰ÖØ™Z-øÌN6>n¬è@ÛE/ò²56Ï:—2kŽJä]èXY©ßwŸÓ9J®=ëYÒ”K|ÆêÃÅ<h—Ý\¤Ñ@€¹ˆ$™ï›£(Šœ°–•d—ÛlZÚéÍ”Íp+sK:swêHÁfÎd®½Një‰J–d½CŽéñNö¡ºžÇÎ]Yo9ha 4?B5NÄuÀ/\üãšj¦Íç’?H;â©§Å»ö^¯yð»,ó¬©x¾J7Uêl\½7<jÅï⡇zçíwzø!µ´ÕÛª Éuázzº¢Žwèà¡'ŸzÒsf§.øüð'ŽŸÀâú?óŸ>ÿÓ +íTì$ôÚ¹kçGӡТ(D%%$jNOO#jîzbWÈ®‡N“ÖúÌÓÏ�ÀÇ �Ÿ|òÉ'Ÿ|rùòåÉÉÉçú<%³O<uõêÕ%2XºP È—(ð«;55555uþüùóçÏÏÚ >Ú81yi«óS†…Ævã´]={+#ëµl¬ônΊe¶ëŸŠzJÏ0Á&ÕL¥V</·F6Ì–ÚWÈ´¨ ÐM­WQÑ‚ÉÊW¨›ÛƘŒU´ºý$ÝœM®6-ØÈr„…m’I!)5ëùÌmÛ …¸d#½ ÎüáG¨¼Ôs‘ù+í½8íÎÂäC6Œ; t#O%’ÑR…¯U†8µÐ[ÔØßѰ‚Zö|î yï8Æî–ÎÐqØ: 3•sWãÍÞËD†c<‡#±o«¯??¾‡ˆ*OÍÅŒ†£ µ?eàÌçƒoz) œÏå‘Kù5«€;ð�ž|êI~@ Ïè¨Grèmtàõ˜=vôwœÁLçs»ŸÃÁ)wÝu×]wÝuûí·ß~ûí«V­ºõÖ[o½õVbH=“„gâš›·l&Y•`{®Pü~˼µÔ‹5ú zPPÚ0Æ‹Ÿ¿þs�øÉ?éçÉÓÓÓ4žL¶†yÐæÙgÍ%¬r‹¦ª£×+îµÔ$Õ¶`}§JÈU®ŽC¥ÊH²Ã´_·6b•Û6Ñë µi�¥ëœ¢M7ÃÄö»9ó•µüŒÊdhMO  Ë|<ù¸Ÿ’tJj™‘ 58V'f3¯Ù|X›Ôêeê¶²¤µ!{ÂçAB§®µÉDn/)ÃTˆ~¼Ð—R˜žÿgZ†áÔfu‰×eA¼9sßZ~.æØžÝÊÜéâÄ4sß±®Á±v¾™(úå{ˆœ%¦P»¥" ÚlN#½ô'„)£Ñ è¥Z¶ irWÈÜ ÌO ÔëêÕ«¸ÿEõû°v¢Zûø¦ÇGGGêdý*µó{"íÑ7b¿ÊÉ7Ojz 9‚O©ÐV‹þÉjÑG=ùÀÑU"ö¤RFôÁ¯?ø§ú§)˜òuß«�ðô3O_¾|9”GTËv;gffPÖFÛêQéé„0<<|äð‘mÛ·MÏLÀÅ‹¥�‹ÀœŸ¹«š}¬l\Ûé¦LNNR×éÙé³\¥TÕø 6�€¬é]º ì¤Ù*¢ó{Ñìu×ó½–‡[jŒ³¶_÷›Û ×M”­IaËnqts½XØ‚ÜeÀ0/ç…Žcðáx¢ ‰Àé`N[Ól,hÎ0²V˜Ùo[¸êñ„ÕÕ •p7^¡°ÞÖ”±L‹+d._yɲž¼‰ÂÊÈ ¸ÉÂÜíµ¯'‡¸UE<«ÎiñýŒKÖÕHçÀÕ KT¥ÀžD¤ìoÉG¸¸ŽK©vV™•@tìð#a’Ç‹ÂRíírwì‰Ñ¦€åZ.ìpY¯Å4zy¹Œ�Ôì UEó[)ÔUûܹsè{°ÿµý2OùÄOž€!1³Ç~üUÓÐJ÷ð#ï«Bâõ,48Gà¿óÎ;à¾ûîƒøö·¿ýÅ_ðÓÆž~æi.Ÿz؉•;ÓÓÓ µ9$‡ž:y [Szºá?’?rÄÙ¶}Û<´¾Ðà= ”"å ‹ù½wßã8zùòe$F«V­’Û—ži¹gž}fÞ-+\œœSÆô ‚j²© å˜éùø}–ÒsÎÄë[à=¼…ߌÁ‡ãÉÌR5«Ú%»î–9)¢ÒÖÌÜre¬Z8Æa@LÖLÈšu’,\4;h —L:ï¥,¬µhOÎäÇÔíaµí‰ý¹j¸ÜØq’¬¬´*áÉ ›ºÎyà^I~ÀÂí�ɘÑ7–Ò#FÜ'u+YJxQé2kz¹aÝ>©ðÈê9ÛcŸ¨‹·»ÍF–Ê⯃ÓCýRä)Âìë1Ÿ§™wr4õ0˜Í)X qW%y-ÅXºÐÌQÉ­Š~öˆ Äú¨)è&âeóI<,yÕRŒ·âó³ÚõÄ.Ò—æõëׯ_¿lYÊÅ‹?ùä“•+Wâb¤SM4šS†„Yü­ºÒQñÑÇm·Û8Ë Õ€ }¢¦ÚJßO¨tê½wß›T#–155EϩʻVT�L„[žý ënEH˜Åþ–e€½Õ«WcíXÿ 'óf¨‹Ì8]³Ö3D¿Z°žídzªì‰f‚!›‘Y¯ž–^tÑà»íø±¦wWîVÓtS>’ÁR9�èRä:°ß »ƒÇMc“IXÑ,¯Er†“0TåÁ¾ýØÖj»ä;ì¤dÈÁ‹Y$•ñê]9(zYÒÔ….6™ÙÒâ¬ï(J#¸$Ï0ÚW¸¬Èí¨¯R*ˆW*ö ÞËB; pkjøÖÔ%¯ ‘ZÙãs®k¿¯©@À¥O•^saȳ³ü‚¤®›z"¼vþJ4OÄD<ÃÁ>9%ò(£ŠdÜÊ¥¾——«óÈ9Íïôèæ«û^•E³XïÊÿÉ?Žêj;==ÍÍAUª:×^Ò…Ç{ï¾×³•v±ió&ºƒó Ï¥¿<êÅỺfË=٣¿øBf»Ý–†MKGO8S»ñ?SË ©¯™»î°"[§€¢`†/„1¥Ži3y +Nqò”É*±1ÔAˆÑ•”5ã2©;²ƒ*­‘.gþYé8)Õ=öí¸k’ß N.П£Y8cjj‚ë: Ö¶±™(3áÔÿÒg�� �IDAT³lÁzKñ©sÔ+±Ém{®w’i/“<±3°EÀ÷ÆnËL`泼¹ò®Ù;<À«º*ÜÞ³²ùîDýà™‹s… ˜xaáªîíЯÔX±bÅ‹/¼øäSOî}ÿöÛ¥s).Ûwl?üÖa©ÐªR•·j#vÒâÛétÐç¶§6K˯Uë\0GøùçŸ÷l f鹪ßzt³™7ÀÇßa'þšñ9¥9Tsàõ”‰ u§PsØIÀ°wÏÞÝÏí¾¹DWÙR©úˇ¶JR?—b,÷ÛšSrt ¬b±XU“I)ú €.vGpKêiImÊ*­g|ÒêƒEªU• _û¨º„û•¢œË„ò[);C»ëïz]y€ dcð ¬)µæ/ü Uh+™ÈÙ«œ×Õ °.Ïeº?wS¦ƒ½©mõi³ ›Ö¥:N+NÚ‚õŽ•o©Eî¬r{gÅÒÕ[wÙX›ºö•·izÍõ§`…²4¯”^EÖö9k"rÊ…Ür'~wR ;ÍÖ&#×?(em»ÜPÞûä9'àòTãßG£�^G!ç2}þÝ>ùÔ“r 'W·ÔjàºsôÈQ2éÞ¶}¶y$I‚ëäÃNÍk×®¥W‘!;� âŠ¢ëSO?588è­n÷ÝwþðíÿéÛó^X›ÛEz6þó2Z4ãsé€sq„O®ºcYò®'ví{eõ¥`5lG‹†œ%~öîÙ‹îB &½Ë é6áFH‹^·UÿŒX¨mfO /�A»T–>,[ rJšaDZ‹‰«]NmÝvÉD3ï"ñJxA¯ªÚ•Ž1¬?ÑSåOé8¸V�V›ñÁN])jêÔ• áúN=Z‹ëü3’ }ÅËíU­Sƒ¸°ºìDŠ–2¿:· cI5€³š ÊÇav™)|­ÁM1æN1ûtnµ©lâ� ;7×p€[^¸¥!0¨+'Cæ·R\5"'jÜbé<4NQª^žk#É@bšºÑKªÀáááž�^üÙ‹Wà �ì~n÷Þ={é o«%Ïž=ë)´=cÛömG ýVµ„ÅÒÓf@ò€-Iß&&&° è?þoÿ�~ÿûßÀ… ÐY›ûÑ×6ⱿëÀ£q$ —£¥Üü–NÏÃ})0ùåe¸LÚ&´‰}^†ËsºC±÷•úÛ‚W†ÄX$g^Z‘305§KOPŸé© Ÿ[”ÚWÄN5ý?::º¤  ê<ÎŒµUT°aÿ¼s, ­ø¡ihâfXåÊžØôRÍö >yúÓ_ëœN!k.ð„ú—ëÜÚ_31:‘_vÍüªO$O�hþ‰­.æ•P¹ó};=•¾„>”[äì+ÀR_LþI=%4QçPz›!Pú[œ·.4¨3Z²Ð&9{º+<íÔ “D8ùüɦM'“iãV ÐôÒ0˜3ÿüKXv»÷0¼Á?™Á’§ °ÊfݺuÛ¶:¶}Çö$IÈ-o¥C+„ü™æ”Aì¤Ý7ñ0;ñµvräAŽÏ øê«¯ðãPm _ÙÕ?'€óÍoþè¡y•#\†mt6=ÅÞ-[·`ŒgaÈMè%øÖž«ž9Iµx>SSSd‚Oª2By؉O@JŠÇQ¯†Šmk×®½ë®»��ÝøðZ}öÙg¸»ò€³AÀ Ë¨*Ÿºè™jú˜±:G͆ö|¦*ÕJlV§~ªÏ÷±‡‚ÞÓQê©U¼$$ïðM:ÏÕusè¦z©Í\ß5>Ê8U‘nJIÇN*+¼6P\ñY#Dµ<ÓÂHÍ[ÍS·VŸrnYÁ¶chn3¢S§c‰uQç»� :öU…Qcpy ‚[ÖFÂ[)θ¹Û"Üdb\ªäýßãâÆ)MRš`ʶ,.‹êæãÕ4›RÀ°W&e¥Ià-çîQ1ƒ@+cÍ' Õ¯zH@`¹ÖWê|r;fÎC¬¼ã+"ò… á¢Úô¢©k¤'[r8ùÔMvú–{8¹ë¦ñkþwôAÎSO>…*î¦Í›¦Á)u¡¥%A¯ ±á•½¯HƉÏGHÀ6Ðf’ ó²ÝÁõ——„,°NçÝwÞU¡“—ÍVÕb·ŸàŒÜ:¬V«…÷¨Õjaj™ƒâÔÌ� ºœ:y Yïÿqk´EPç öâ[EŒžÕª´™˜G+¥—¨ó/]u¯#Ÿì=¥ZÐì¼!‚€ÀÜí…àÕ‰¥-àgí¨y¤4u<q¬†Iõ,¼�GRC°u³Fläs· ÔIYuêÄ›×ÂY©aXËuWr;Ê;5ʦãµÈìq”jWáÚŒÞign•r¡ • %Ò [íÌå”ìVE[Ý\èÀy@«Ÿ gæŒÆYs´Š@£³9ohI-îBµ<œŠ0‰µÚ–Κ7~¡Ód@M×UXóªÅí?Q´†µˆ.\ºt©Ïz}‚Ìgw?Kz¯Gï<¢Éy*7—QiÍUæŒSýDœÌDôÐÞ}çÝj†–Zz’yñãàõÄÐÀ,^Dל_|ï36Òbn?IVdó*z­^½zll �þèþ¬ÿûùóçñÉè bcøƒ×‚/\¢ÖNë—h7°X!Šƒêl"_<{OB¬Ì]œ;[òPX7·ämR [É$óV­ÔW»‚  ŒÁ媸&†¢óú[Z%yuçÖSÞ! ¼f•èÔFŸ²FÙ»ô[ñºlhh ™TóR9ÐÅdW‰K¼JÖ3Ö1µñ¬B˜Èæ)®u¥-Û)mòt…¬ oüð°„ óÆFà–÷3¸ƒÆ@ Íε*-ãÖÄò§•®«¬ìB #^ÎÌ=[`²Q7ìó–‚d§Ž,á+¸)EÀDwAqÉF?ÉÎmÛ·5´Ð½þóש Ÿ¼ˆçÙÜ’1-xÈ Z|W¯^-O¯¹P–ÙºVg,f^ÜTëoûÛ…½§¦¦V„C}!Õ—ñ²&zßÜTqvC…4@P“|¥È¨;w¯A|F‡q‹/ìó`ž8ÀY”å¯ödº0@bÜú Jœ´}FØ @`Î-¿T‰‹WHÂgc.[=ãV³\f=^Û›;æw""óf96Τå€*÷Ûi¨»ðærÊÂõÑ&ðx`LÛT«œ@Ëû$ni¸–ÎFͪ¸&�xrà—ª]§´e.GmkôÑ»8iàF€˜x Úw)”Ü•º>è3Nd9(c’ú„?àƒ###¸Ü{l@å|øäR³³³­VëÇÿ¸J÷ÄOžàRmÿÀÉÁ˜RkœqÎoCÐSTä'yäð‘‚qMYû4bBÏb±^¯¤Œ…£&~=ð —¡3r‰±S5÷¡'Ýn~ÔÿˆŽïÕLyÃòˆúIÏù„ÞհʨˈºD_ ®–rg$VÎ€í´»NeoRQ·5Ýd‡µÕO)[[‹Ú‚–I‹| ÕÝÍ6cÒwÁ*QKm„'ƒúœx\¡\&@@ ¥Ê°×+Wws±ïQÍ+¯³l¸ä7.¯•Å>¤â†iØÜ<k޶{´!оò¯ 4bLîiòðF§§).@}™“j”Zã½ ØÄ!0yy䨑Í[6£¡kC†¬ÿôÒÍ£GŽrsùÏÂV´Ðt>TlEëæW_}Õ°XºŽ)œr0èÿ®^½úïÿþï`ýi/]ºtþüy˜‹/Ï¢ó€±þ™$ÉR˜yPÝKª­–Ú‘2rìµÞ2Wº»oÞ¾ Bæ²ËzbÜIŠÞ Iç,\ä�·eÐáÇßI~Åé‘ë¿j˜çÎiqn¹`ÞyÕ™p…–k’(G—¶ÑÓSêRÆJS1l²:C;eE-<ÉÚ§ ¤ýrM/ uPäìj«A\¥ÜS¸w¶áå¬Áªë›ë¦Šëï$«avUzÅ]Všy_!¦ ž&,§•™ÀÕ„?gþ¨‰3§–gÓ¢ŒÜâ s�€©ê~ÓZ ÚðïÖ¬Y³fÍ<ææ-›gff$9^”ñ“^é)Eó ×­[·nݺÛo¿½ç[ŒŒŒÜsÏ=÷ÜsÏ·¾õ-¬Œí?ú9~óvªÓéœ;wŽ „=Áœ®Àtc¨û€Å ¤›}f"–RªU–µ–¡Òo]wuNÛ¢ê|}„¿oöKËóN»çPaóP9’qmÛ@k¹+´ó�ø�~çºÈVäÏÒ¯¶È@Õýòk×dÜ"[ÃÌ{¥¦ÇÛC½Ù–²ŒÓ'=~ƒÚ¯¨=ÆkCjªƒEsáæšjû!¯Ji�ÂeÝlH}…�þÖp™iŽzž.n-[.tûUOÃL1Õ"ýÚLL{M\è‰vH;•ž¢ßƒ;£†ªc›6o‚‹|L4šZ·ö•ª`î¸ã°u4HÑfggqEöjeñú«³Sè KaÝw÷ÝwÀ… Μ9ÓóÉXá…ô”¾ý”Œ.‡æ8׿ñïÐÐ7𦹦Œä“y{ Ï 8Á­›¯Ö#öHíºÇüÓù"RðÎzrÇ# nÁ`2³nvm±¾;°å×lŠE°3 G]¸öösÚT:Ê_-jãùàh]¤dÑ‚õÄNM<7óB”ÌÅ0Ð:G¹xëùÄfÂ�á´+_óÄ›q×åò;ðñõ•QµºÉ5ÊáTP\ a^==”}»¤( .ðg‚+54Þ(•FõU~Lp}øøQ7 eàqåK+Î6ïUÙ;ÿÀBZè¹8611ƒ6qeÁÕdvv¶¡X”dÛE_z$dzC@çÍÁí" 2,uàEöÆzsÜšœœÄ»ƒ ‘`¼Ô¨¯]»öOþäOˆ>"lüîw¿Ã—pia~£Íþ@¢Óé¨ÏJx`ŒG¡ÝÏ@`‰)Yk]¥[Š2–¬.ªìVëû|Xiz•…[ ]`fª9«qÍܲ´ÖÃ# —%ߨÃÇ=cÈéh­©Æ>‹ZVõ×t¾ªÖ 6ªv‰VçB+™„ÄÔ΂‰aV¹-FÍ™g·$º“2%––fXR3ׄÝúRJg;ÅðÝ€/2¬ÃÞ Õ½6uI=~Ÿ Ñ‚›Î{B® (Ì)»,*Òç¼l; ü6,Ô›';s[­ u¡úsUPáY>^í¨Ø7¿IÁ£PŸpèà! Mìm?"÷þöˆÔB‚ÎøP¦£“¤ªW.÷)t3L5xôC19Lâ? öhÏ1::Š:êÚµk¿úê«ùÕsöÌì.z‘¿&x‰hrøÅ‹/^¼xáÂ… .ÌÌÌ`‘êµk×®]»6lc- zpÅL n(tìS'—/YÆYL½UY5%ä@ñjäHåSƒÿ瓹Ô%ÌŒì�T|4qRA¶pÔ¸c¤R—jðEß›É%%P> ù'°ÊpÑ©sº|ºEáš(¡ìF Ì¨Õ‚çlñ¾táÜ»¼³)(„á;¸å¬à]Ó>-‘æI Þ΀CNæ æÚìhÃf«A CƒW™ª2ni•3o „ šÇˆ’Ÿ4ðõ>~&þÉ•ïž7P© Ñ¡Wy5q¥{}R;„dUíœâÀëvìܱûànrY«‡ZÀ“O=¹ÿýØî©ÖµÒR‹kÈo³ØëµtªØ‰lŒFtyFÞo™·É6“ž¹råJ$p_~ù%ʰxÀ«W¯¾öêkÞè8@»ÁrrÒ3 TãÞ{ïýö·¿Ô“(æÔÔÖø,C2»9ð  ^júnpª§n)H?W;€ñNŽŽ.â&OýÂÏɇa°QÔªþ°íèJ/ñY{¹1ÁKU­sil4´L2geRºyø˜uÙÕý€mÞ½géõAÖ&‚þ‚XCB¨q¾^g«£™ååÒØ¡:6ˆª{εE°î”P~Ap¬J7góÃ!lüæ%ªùgñÇ…Z¼Ï…}Oa?2¸Ô_•Oew)h’)„é/¦K7=dd´ýÔ$RöaO³”A*ÎÄ—ßçž< ÈÅÞãÊY/¥7¨)y°á‰¨èc€ÎÌÌ ¼ºïUôÁ™^1¼p÷s»÷¾¶wûŽíx(BJžyBÔÄšš#‡<pp®à±ÔbÛ!Ivó–Íó˜ÌŒ¨¹yËæi˜ît:k¹|ê¡&ÚÈå˜ß;BMO]Ñ?Èqé›*�¸j­*ØtøoITÇ‚êfU@Jµ…¨»á^±ìÚœ\R|ziK€ò¯à7î¢Vh.á.d✲DIÿزR‰Ó¨&¶°Ï—j㼇¬¥ÝøÉX)»²˜ç#SLåáÐå m4x(µ×Ás(Ì…èŒuÍr÷VBcåª'Ëç½úAƒ«4œÃËXf.6aÝP2«†)fÆ­ †°Ã;„u¥Â Xj˜[EÈ;)×n«Q]ÝÙ/qAÛL8Ñn·½lY(žÝý,°AÐsÊ­^½:I’ÙÙÙÙÙYÄÚ#‡´Ûí§Ÿy=ÿh¼Æ,‹ . �xÕF’$Wlð)½ ivv¶A’å£F‡22~¨+W® žùÅ_|ñÅgÏžœœœœœ|êé§¼×ö BÍ…]d¬+Æ+†WxjjŠÜ—ˆÉyáí®H¿Å¢œ~C¹=Hý ŸZÙ5,–óô‹Ôl©›Zjz–+)ýñ¿]è$m€ò¸àwlÞµÑ8¢›t¤ÑÖuû&Í¿$Ì+\ëÑRè±ø’·Ä´?€;¶BúÑl{alQm¿7¿¶"­×’Á >ÝWîªï˜ÅC`áv+SOú.´RU£5Edn 3/Þ9í>³¹ªXËûM 7Y[¸¦WÄdÂZ¨Ñ\m!œÑløgNyôÑÁIw'ÜÊöYhœV¦Í Äž—÷àf*v^ºtiddç¨�À±£Çzø!ÎÕv?·{(ØzvÚk#v¾zôÕ§Ÿy·ö{^ÞzÓù®þ|•W‰×ÀÀ�òK\åñd<ËÖ5kÖàã;wí<xì ‘c|Zå4èè²Öt×Î]`]õŸzú©PãcheoiC+ïÔ¤øâ‹/ÆÇÇà–[n€‰‰‰>úè:êáxý'&&Tî®ÖÚÌ#–Ƚvc ðxæ.è@ ªel¥Ælr¾ˆÁe†¡Ô—ç{Çà-ñ±ÈT�äV:6 ¥7m‘¿Qê6•¦¢Ë“ÌTO ;oûa»9³Ê£Ñf6Zq.¨§îä“¢:VQ½Â®ˆ* ?só‚à+½ÕÒœñ2PÃͦÀX¦•»Å; ;•¯ƒ;&³å<¥ðÙQ)“‹Ÿ ‰švü§aD¶ tç®J\ª’²Ø%¨Ûþ…”ÓZŒÖ…l\ã{ДäwWg»ÝFÔDôÚóòQvðUïégž^”Å¡è ‹g!ãסÂÎéŸÜi«]ÐÎmÒò9dœ=úØc>†OÞ»g/’<š9ŠÔxv—u^c±<ià‹,æ¤u/é`Ë>ƒFºbqh±—/_æ_o²ëSKÆðŸÍcJqëo3u[Eâ16¹/˜?_ PŽ;>éêF»k(Îñ° d’ â¥Ò‹‚—æBC“9?#êcAË ª€‘µ`²“´ýqT”Çu\Ý ·ÎÓéÚì@»†ÌÈ馓¥£‘ãeá*Øè›“ÚT´ƒ=ãµ° ¢ƒ"ä3^XË…õÂÿA¦N¥áœtqÊ\¼ÌÅe7.-Sñ&Z·(Wå*\„¿EãÆ<#'ÃæÔiÛÐØ‹bz‰ÉÁ@Ô$æ7 >EÃ’$sêæT¾žmpCCCO?ó4 ¿X›ÊÍw–naòbýúõ6l úˆn8dŠ611±cçŽ ˜à¦;wîÚÙìOËcbb‚ê¡È’74‘¦ÿ˜™™Å«Šl^­É"R‹€ÌøÜ¹sø‘‘Àu:ìÎDÎJ*+—[ñ-úöÿ0C ÖLµ{§l†³œUSæz6�$bðù!ÕÌäz›/ÝÚx}kìå¨ôÏ·'UиVæeØ~Ô¹<@,xEnæ!}G)V²öFÝÜÝÌ›ÂjúXRTÝ®]�H;Õô±¶¶{åB5Ý´†ºåx0½—º<ÕJ“<ÿŠ í(Ä „b)wBêΦÕ l›^p\¿õÊfak=ï€FŒØ¬!ÍÝ.„DÔœu|z›‰RƒsdèûBMîÞBkâîgwï}e/-¸D½Ø±Û<z>YESu…¢ÙR cž¨} E¦¦¦.\¸€‰ÉfŠ|ðÀÁ9Ù½nÛ¾mdd䕽¯ %/Á§w’*K#rÉ;&''ù­9VÒÎ/Bµ-\A¥oŽ:uGÕÌñAdí¤Tã~eÎÃó U*W¯Ûü,æ*Õ: ãFØÍYMr¶`*è@Z09£ŒÁHZj%eU#“VýX²b“ÒÕ�¥ô QÅ£VåÀ!eþàf6ë Kñp"u‡™�×lmÏ „sˆ ½ŒY &«Á/ œÖþ±Þ]â Á‡R­²I°:™Ë³ø‘“´½×ÒåÊÝû’†E]£eL5럞FÛfyhΤZ9ÏÄh÷]dÖEWEµB\.nõל˜ ùíAà«ÒWì~v÷œžÿÎÛï4?á² o¹A[5¯3r)bN8àÁ‡œ„Îù *\"8ÁÁ/Ïî~v)Üú³gÏž={ö£>úè£>ùä“O>ùäÂ… ¨-ß«I’ °˜m ºA«V­¢Q\ +ñAÃ�–~”á¥jsß°a˼J¢™ÙÓøˆ5ÒË©^†Yñyd´&Bó˜„aK¹7ÑŒFá.p™à²N/cõqpPÕ+y-’À$жK›rw0gM_l5 ­Ý¥XRqíæiä¦úÁJ¯`Ç’¤VHœ¶;FŒ—üÒCM£éŠÍD©ô‘œ3B§Mè€Òk.j®‘Ú\Sã›ýü@{9„]@ó0R¿ŸêaNIŽOP¯áfŠa›f«ÕBâE#3ùš‚4èñMŸ8~} øxƒ?&|ù2h j†HíÔÔÔ§Ÿ~b®!Ø‚êüùóK—…½óÎ; Û@+yZ7G_Ü—ôã«0117ôƬz½bÅŠœæ"â/2éôL•«åi [“ã,œE¶kÛ$À`¦»¬¤¶ß1w9S˜PXï¯-بjdβ_܆&·|—7J*–Ùs%›V2éú·¥ÜeW›2mÜVºžˆÍ­Õ‚õÞÇï@[4™¤še<XÛ‡_‹ÁÚ”á3šŠëí-TÛ÷ܵ5ÏËËYæ.ÌÝIœÍÍÙ—xc¨@©,@Os÷9y£½¤³*ªîêR60®oÞ‹G*r‚ö‰ l@hDy—·Þzë­·ÞŠ"m»ÝF‘@¯]”ÀŸ<€¸K1Øž÷zƒu;9DjÒiZûú7doxùý÷ßÞëØÐ²¤79ñÅ‹ñŠyÞëóû8ĹyMÙõ%Ù7K4às§swJ%4ÎE"ÓSÛë8ó±1?äõ¥¤ÚªGµ©©}‰ˆP[ñ‚ñÈþýÓ¨Ä2­´±ºt{8”.ǪæÚÐx¯ÊAw·Á_"¯mPÿ@kÞHµ•:cTþTJ` ñïöñ©2²B§t_nz¨ÌÄ õd‰\s´—ý*y * XAPháá3 Ägh Z¥7ˆ-゜ƒÔEüɧžÜ¼2 B#¡ÝÏíFëó¹bô=²ÿÀþKNL Òü ¤.\�fCÃa×úÛn»í¾ûî#ІêØLžgȾüðÀ!¼ÏíŽz‘‹€6vá¯è¸Ë—Çç*{òÒ­{äEŒþ‹×ø¥îljBµÜ+¤7[F3ÕÐ Ø“@íH—ð“Ó&¹â{½€|Â×ûî™{žtÀR¸†•.õáÊsឪÎ4m3õ,|…ÎfqYž<™›¢+„WwO» Õ»S™â%äØëàôe‚ F˜ªÖojl‘—:æ“&_ª²¤ìýH½~rpÓq¹0ëW!-×<+Ë=ÍAKÒÔm™Ü±U‡§”»þMú²‹BåÎ;›‘ò…ç_�ÛƒècçkûñgùÛyÀ'‰Ã‹2ß1”\¬á—ïÿò}ôÛó"Tc‰Ò«§`#¨#õÀ¥¥Zz¹'•£<{S09~‘›'9/à©Ø<::*+àè /C£TCé#ÈTå ´Lt‰S²¬a¹BÁ-¿íR^¸i! ]Çro w ó²€2æ!1UHn¤”^Æ€:+ÛfèåÂü¡:y�¬?J LÚ8ú–ªaÇQ eõ²aƒ±ÀmrVüŽŸ¶4"áç õÀ7OãÒéɆ´ãLa“P!¥ã,,§{^¾™¶£jCÕ£9@åfÖùARó, ÏæC‰4À‰Co}4&íèù`¾‘ ­™Õsöìå船zõêU¸ ÚËPv¡œh622Â]l–hÀÂgs#AÃ[¿ÿË÷yÕ6ò¡¥«¾‘Í|Ø–G‹½ÁXø=8Q©²ó¥óÈ5GGGÝï~~Á¯g?§$3•,p —¹¢.‡UOI+\FXŠÌÓUYaÓj² ³e>ï.ßHå$ Ú *]Ô–>;+#ôê"°FóÓ6Ö”KÓeó2jwÄtyÕO*L 1 &sa¸°¢ã>²d®^Þh’.±“{¬ç½z‹¯ úÕ㛀§O®)çê÷™î²ÊÕ±š(eb<ÝpZk·ÞØ4^–\TSRªÝ°aguÔ‘Â%&BÍ={÷Àbàè³Ee,£Ó��1IDAT�„Tnê±1DGÂHµšÃ+À¹í¶ÛšO�¾ÿŸ¿/éKC žª7Ž «®]»†·€_dâ@Íä’ƒ\sCÎâp£ÁAõ|øçR…SÚš ž`Orý–NAzQ†„ÏIù=¸tÓ­”©s عÓ|MÉ ážì\Å͵“2ìÎÕBhÁd &­ƒ]© t¹—š’ÀàjªÄ<2wŽº¢·µf>oH™ëä<¹t‡£TÞô´± ‘Xrm--ýMÙJ÷‚äl�‹¬Ûôê€<›7yÝrV÷”»·zµ‚[íÜÀóÊ�ׄ€Ö ZÒ×½J½gÏ7™äÙ|Y 3‘¯uŽ&:nýëLßÍËoª§m·ÛXrÊœ:eN©ÏùÙK?ûÙK?€çv?÷ÜîùãÚèGGíóåK_}õÕW_}…=Ÿ~úé§Ÿ~J®¹CCCèyôþ/ß'“ºä2Cf4ª÷)UÐ>tøë¯¿F†2®]»644$kÁä—ÄÀ8uÞ!=Åììì’d̓qr-˸Â(‹Tâå&R[­ .Óüz€³ld¡f !O‹%/P…xžG“‘×wÜ¥\["[XëBoÂ0¸#±L ŠäâµVŒ.]rnj é^—E¨ó$DÖ³ÀH£™Ê68+pE0a0–e;RU_â5næÚ—-Œ½+’¿z*±t{�÷WͶS©F!PmÔT„Ô “‹N‡\ ˆ÷ÓçZ-R+ƒJoˆoáZæeõ–Á4Nulè?)H/çÙP’mñST í‚[øN?ñø¦Ç?¼}ÇövΛ>6Ì·B¥}‰dpd#Q›ß,Òëx}Jñ pîÜ9¾CjdíyVôüŠcuÕ.~‰>DYÙ* 7­{£¾r±fÖ̽-V@ð�ýóÉ]? ¹"—,I™àFnòyx1•HÃ÷žt  7N¹Þ"›Õzr한àî@;,kÏ](Ól8Œyø¡d=4rë›À-Ùíiš#ëz¤µ²yn¿“ë;úÇm«—kÀ ZQ˜÷L9bÌû†{6´‡�·ð؉»îº K¾þúk°5¥N‡;« .EƇƒ§‘"$sp¥Н;ÒäC>¡ÖGÿ\º<ÖBPóú¿ªžš€×¼áP‹r‰^óZYš:¾¤[¥¥°Ä=⢬õ œ h3–Á…°Œ¥mH5N·‹CíjױХ‰©öBis#ÍäÒ‹“±MøÜ*Á%½ Ôݨy�;s·ç$$Kr¦^ Áþüæ�X‘`m÷œfÕ•®ð^ß©ÜU5A0'n´²'„뜪–›†ÅáRxêNºãú÷—ÝYu*'´â±ÎÃ_W<˜kö{ Á¼§ÃÏÓ½ —¡¸Ds`?�¥6{ŠR*‹fw€˜®ì¡æ<h4GÍí;¶/.~¨u¤ªÜÍñ@¢à¢×î¢|Ú… ßzŸ[ò½}˜Z.»ÔŸQåýÐh]©îìŒ[úHœ²Î&ŽÁƒ`‡nº):o.†d¹�’’-ÖeÀò7Ý{`Å<Ü¢Ù¬]p*-¯*ÅG.Ã:¤q;I<o^’±\¯a&�ui«v–6%ð€nþÝ¿aiÎÂ5~m<'ï¯hÁƒö ”fP>Õs(µ)`oŠ€N«h'7DÍyÊœ„øb&²¶¥øÊåã…pÕ®¼Ú “¨Cí7Í-¡zUí† î¸ãŽ;î¸cÆ 6lÀV÷ááaž±£‰|x§ç'· ¡Z÷q5xù3 =ƒ&™`¬bAWuó–Í'ŽŸ8qüÄÀÀÀáC‡¯‰èŠ¸Ê‚¦¬Üt&£,–çíZ,(÷Ì· ¡I¢hȇSnú¹È^Â{ŒÓYìx‚X7¤Ár!wæF):ØÀmÕÈ\¶tÉ“g­ì9^GªYo;k±e„iG'L5üÛbÝÌ­®OÏöt‚6ƒ$A>½’·–zPQ<)k} 3=÷†­,u[ŽZ§*ÃAï¡ÜÁ¢RFVù¨7ʦh¬¹íÙ%šX jç ;`Á.oOÛ4,_C@‡ô1–¹i@Û�!þ77¡æa™DÂmÑ—_~9¿…©ÁQ¥2<zUÏõÈ«ý&9Ñ`…Ô< ŒCœ¸2gÀtý¹dMŽö\â¦Väè^ÿŒw寋 ûM­V o„W£Û°Q £fÈh&Óf„–$K]Ó2ÐüáÀµ/0Z{Ÿamõž/ŒäµäÉNàä­h¥tɱÕÂÆu°"d×ÒèD½2ÒJÉ» ªoÙÌÆë^L£MƱnÔèâ{>™TÕ‡9?ö/&27( ¸ @` §J+ÁÝ'©¿J©#oÚó/ÃæAз¯lOKÛ\Ó¥ÕÒß"<LE&ïçnªì�¸å–[°ðÔH\FU*Ùl}—×eu§§§p"– *o:¤'¨=rغm«” ùŸ7Z÷cY§¢¦ZJÃoN¢n·ÛHž°­eNï»À@Ä¥SR¡š‘<JZ_½zu``Àëñà´NæMKñAT±ZmÖZ,!½Oàl(eÌÄÚm4ó0ïçL[b¤[aÎÈqÏ¢réØdªqJO‹KÝĤš<cü7g‰A™”uXf{nYñ”NžÏ`ñ8¾”[ÞœÚÑ›y ðUÅÈâ?E§.¢vð/`¾Ÿk y!È.ÀUEuh—äߥ;‹Tå¬& «®–]ÈFûrªlµll2ñ<(Úa—DÖgœ¸~!HÜhRç<V=Μú DÍ­Û¶|ödÕ¸Ehö‘Áë‰Õ1«V­Â—à¥ÆJ«ÙÙYÏ—`9EoùÏ›ˆÁ{E^œòà©eeDÙU£cÌ/ð6õ ö¿öUЩ¤ m­B,óÇ'‡LŠá‘9{aÞ‚nÎÕØt¦êðnõ?'.ÀÒHıªi õ¹%%�Y–¬.4 ¸žr³YÉŸ¸Syé‚_Ù3væ �t ÍÒ¨¹½tÝîO5A©èá[ŠÜ½’¹ûy½½aÉldi¨q¯0>²ÑjVK—óÓ.\‡ú\sA2`†ÀŒ9…ÆÒ…*†ú g˜šöU^ÊüÌvÞ}÷Ýwß}75Ãar3Ô릦…úÏ]aŠn©—Ú³rd™*jŽØ¸Ž qU RY‡‡‡©ïÞ)ÞªOLŽÚywé¢ÏXý¦F§Ó¡Ž[~½„4¯�›ìœžž1'Æ™‹Ù#^Ó‚E†©¬&ÐuGFŠBåîÇó0ìyÉ<.ÒB ×Smip†mÁ‡ãþ'¢ÖIã ÓÖM£¹ m+à-£¥¶h68NÝÁUÞ]5Ÿeà½<DáŠBxfÁ{c°ˆZÌ8ó¦]z\J•mCE¹ ª¯!,ó†&vÉA­y€kª>s­XZ'B/ƒˆB£ä£ìßî¸ã”×Ο?¬‹ƒûÒMMM-zwʵk׸¬7==çC¼avv–�ÃãFx2$«Ýë¼OjÑžB+¥ÂÆí·ß~ÇwÐõüâ‹/`a–­ˆ…׫O_Õá ÔjXžy%ª·X^Á×7w8Á@øï¹ƒ5³ŒÍL6î\ÌÔå jdé­>-˜tk_å? /7Òê6oì ÏÜE³:“qxÀ‚fÄ,h9Z Cjà:&¼&J^%¡ÔÔ—­gæèÖ|‰ àï•·¤*_¥Àyª;<G¯QÒ®Lƒ¯4¦-M£™‘zßKVO[ŠÏ î×X¾ ×jÂ{ö¢¨7ÂûDYøvÏ€ƒqË-·¬[·nݺu·ÝvÛm·Ý6Ü#,$mžZµt„oåʕȪÑ}† _UªçÙÐàƒêÈ3b·üügff–Â.K=¿úê«ÉÉÉsçΡÉÑœŽ°ü*±¼HãæZ‰*Ëbd|Œÿ Å’4.]º´meӷĵ‡Íê‰Ö5ÅfÁÜVñÐ\낹 x<Òg3|D3Ý,¸ ¯Ým¶ æ$ÙÂ]Oyò¯ÐŠ<M ì¥a‡g›¦Eª=8Å)5¢L ²A³ŸBŸòj· 4¨K=¢©â„È"{ìWY 敚±äÓp„÷¸iªñ9/ÃÊ}ð›Ý! x^á·b+>kf¢˜¤øRÒñpECÂtõêUôIÀgz¢ÓRX%ŒŒŒð<Ö×>.2/Ö1ûÄ ¼Œ<¡+çÜtn8õÌÃ9jvÄ;%³­+V¬¼1}د{x÷ZMîª)I¤û/ ŸãñGž1[ׂå,Á>X2ÚCŒù«LP4äL…ÍM>£áÂíZ¡ÅWrŽ<Ð"™1$3ÌE–XcC¿©¢Yº^H”µÊäðe‘Ÿïé­ë¦c®Sí3šŸ”¼Ö>(ýç*×{–`öBz½‚/î¯|š¨>Èî`P¿ óRw;âMCó¦Ö¤êÇ °O!—@«Ê�jq®Ñkãî›i4´`½ Îs¾p÷m7¸ó'1¶æ#¨´oš_ònØ’äšøñÛíöÙ³gÏž=ûÙgŸ}öÙg󠆋Eïèq îø:£…úrõ%+V¬X†©[—X|#A]½a¥[ƒZ¸éŸT,¾›[)§_Q‹gï b I¾ ¦á: ¬™ïHðVõiXvîÄf~<ϹB脞!œsõ<Ë!{Í3¹Ü‹BYÙ,ÄmzJ^Úñ)µw•ê©àbl§_ŒB\sf´&\€ â¢ËH­òõ¾6=©îVÓª÷ÄŒ\“mËÆwɵ0õ“;Êõ Æìì,æÞ8NLLàø$ äêâmÀ9aZÄLa(úÇN\ÙéùDÈ&&&<? >hÞ±ˆÆ!Í'˳øråŠ:Ó¿? ¦æ×œ¶YÈ¿ñÓ©ToÅŠ«W¯^´V…Ù%Ò*Cp6©ƒûZymHF2ì@•¤Þ3ö'@@lSñ “yJodt)ô:„´Ü2iãNinhœÈàä]1ÏÛìÖŒËspjæ™!ÞV&c„Z';Îâ.Yšºê¢yíqÙÐËý!e¢7&u‘,dÝ®ºHu½¹54zÕ+™€Œ\êÓm tIEz155…2,úŒ/¼;åùŸ>ÿÒË/õóLT,áæ©Q±K(iǰnÝ:�¸í¶ÛðÁû·CÔ”v}NG…g|N?™¼…€.Ì«ã“=®—,<<<L²*¿Jýïuš‘ëçò^,ºÂ?¨-¹‹1œK˽eAtY;Ë™Õýº9¸\¬8SÅ$nñÃ…;Ã*•ÊÆÚWYÐQ4.šü9¹[ìÙ¨râåL[cÂçAzŽƒ™¸ò!ÀËD¬‡œô”-öÉG)V"+)¾j¸Ó $ S£É¡2A˜äÙfçz/ ÚÇ—{ˆ¯lÙøéT0ε'hFêhñ¹ÅgŸ}†R-.”¿$ãÁËDñçÇ?¾éñÏás\aÕ·[n¹«+‘„-C]t“nŽô ©•moÉæˆ‹) ¹³rtçÿ:êÛýÃ3¿ªjÑÐm&ú¹*^ÒfH)ÚÓ¢q‚¦‰Æóä²î9†×Ú!Øyý º $™ësZ,ô5¯²¨©®}Æ«mé ë»g³'Q ´gääŽËðzJwb¨§u«"üjVèd5ÈeYMá²üÂòÚ3.T@€2†�Ì„q(׎֜DMí =9„èê"Õ>ˆÑœ#e2Bý¼¥f§%_k´ÙAE?¨900€ök×®ñªÂU€ë·ýÇöÛ?Ü0÷]o< «øÿ=Tèt:¸*q”ív»ˆ¼X©ÕjáúÛϘë%‰û￟®'êŠKà\ÄÏ5==-7=Ô§Èoʵk׌N‰ß²å4:¾Yb°¿í³·/δ¾up«x*9”a[#”ÃRà ÏðMº}œ™ LތƼ—¨(;"ä KµV¨t«C¹Ñ1†¥§š'Ù¡aX+y-†¡ šFK¯:¹£Èž Æ€7´‚¨Ì>Š1ˆY©u„@ÅrŸ¬1ÔŽé ÂêNE~o2@˜P‚�ò4ð|U †^6¶ËGàhå¨IÊž7çONx¾.Al€Ã@§ÓiP­¹JI/Ç._¾Œ]›×—$õ£µ6«Žü™²hh)tZ®x«¿%æ·­>!Ò¿üÀ™§ÔE8(l N¤¹kœ¦>ôé¦;µº›‡Àɸ|!Ï2†èrÇ‚ðè±pZr·C?f¿¹[3\ôš„Ü<“«‡Ÿª†Áͳ´$yÏ%_l/<ïÜ\¼$g]I¦‘€ªFî2}8c@@ÓnèÍm àjyšzã gY¶£t»]\Öƈ cÕ‘ãT®°(ùžS'OmÚ¼i±–!UR¾‚“Bé+ïÉÕòÊ bvvÕ”êãr1üfìKá²%Õ†††¼éA.]xš9þŠ0GÛ⟃Ü*5°j¹ç¹±ƒf§Î›ˆ?þLr¦7zf)ëU¯Ë%0ý‰•Dî¡@ƒÉ,@ü³bƳ¹6ÝÚfX#Áé-ìÏ™XpK±8¬U&- FÃ�ðüðÚ¸£Ù$¥.Åäè¥7ô´yà+”özy®¹1�Ôæûyck)hæ*®›@'‰q/iƒOSCbÕvà*çö©0áG®0'Ó»ùµi6ûºaç8ö¿oݶ•› P ÷às )‚8Œ7�½ûúë¯?f199999¹üŽ?ƒƒƒ¼udV ÕÏ\úø]]+øâÆ7»dÚ`ʱÀèt: mTƒå,´‚s\)Åœ/%ߣy…ƒ  ™¶='Q1·3OÚ‚½¥B1+µÌbÈY» «š ¦‘ðœñ“a^óŽ,i{H$úöÜi‹©Ê®@XÖyÎ ù<8®\å8–ˆ—a¶ ;­ŸnŠæ©Ñ=¼oNÑ]y¯L8zè!÷DèõÚÐ4oÐj‚cňDâ8o>¸ÒÿåñDmµZôA¸ö«®S*EM·–³Ìä#¶ú¼ÃÃÜ@S¥ºñâii©Í^½z•.¬zËp‡´ˆR*AæêÕ«ûÑQn½õV�¸óÎ;ñŸü1�œ9s&ôüK—.mذ¡OàTþÈm{_PX͈šo*ˆÑÔ0)’ ˆÙ‡|•,4ïÐTÓÙÒFj˜5¤²Š€P)=ÞR�ÓQ4@é}Zj"^¡•‚æ€èw´`}Ç}иB“¦(r;wAkÜ4KÄûÈT´ºAñ~ðŠA“ß¹­®š/Õ:r³RöÞÕ:çfÛ'Ž¢õÈÛ¸ô›ÔœššBºIîe<o´jÕ*�—³ßœ¿×ò{ÂÍ5øÂÊ}RñªòH»ÝÆgÒFŸÌ‘†ðXBõr^u¨ÙBt×¹ù¢09OJ‘®°·‘ÂÛA¸Z‹ø+üCqìüµ}?Xã€í¢«r\YŠ^|B5œ«+K®ut„�Þh](žSùâÊULžÇ!21 []š3·È¨,AKËÍB,ÐàO Õ8M'X"OÐkbe®ÈÝC!Žš˜–~H¾ê*)TkvB]%  KÍçß±>}9€) zrÞë‚Ï-pÕX¹r¥uW¬X,„/7²”¦ç¢O¨³¤‹Ë9K:/&]d„µY….»×3ª²j¹=ºÑf†«=¾×ËEGÓÐõ¹í¶Ûp'„9fLNÓFçªGGGƒÍÊù×»çô¯=ð_7¾ðËC‡…µÙÐß³ÑÖPüÁËJmºSéþŠÖ|~88¸¹+õ|d«ƒ p5õ·Ð˜¾RŸß3kXj4áÇ„ž ß¾}ê“%‘õîT¾t¡+CÇ)µG¿5½¾E _€†æœ›dç]·²ñþšfuºñ¥ùoÇ4Ǻ,�âñ¿øßuþ¯Ûín|á—ø¯ßÛqè/ÿúo€3´ô7¬;êòí¬ïÚ¦â¨éåÛÙÿ®Ü¸‹xbK\aØ—ÚZ/?TMV¨¥Qe#H¨¿-{¡>„¡«yMo†gù© ›â¢¾)¸ŸEB¸éc‡ÔðÅk�3ÓkCÓ°27úûÞ6½$gü/þw#gò—ý·ÿûÆÇþõË W.žÿ‹µç¶oß1bĈ#F ßñýá5ëÎ|úQùÿýf ^Ž1bĈ£ÿˆÀ#FŒ1bDàŒ#FŒ1–&üv^Œ#FŒ1bÄðL3š\w Dñþÿy?¸ü/ìçh7æYÅÏx½žs#ívË–ÿ3Þ˜'.³7ÅÅ¡ˆRmŒ1bĈ1‡ˆÀ#FŒ1bDàŒ#FŒ1"pƈ#FŒ8cĈ#FŒœ1bĈ#FÎ1bĈ#FÎ1bĈ#gŒ1bĈ3FŒ1bĈÀ#FŒ1bDàŒ#FŒ1"pƈ#FŒ1"pƈ#FŒ8cĈ#FŒœ1bĈ#FÎ1bĈ#gŒ1bĈ3FŒ1bĈ1Øð»n·ëý#FŒ1bü¡…‚ƒÍ¿ŽãÆŒ$Iâw5^ù?´OwOoÞz)Þb‰N;Jµ1bĈ#FÎßôˆt3^ù?ÀOwOoÞz)Þb‰N;gŒ1bĈ3FŒ1bĈÀ#FŒ1bDàŒ#FŒ1"pƈ#FŒßÐŒ— Æ I’à¼nƈ¿Zêñ>ËÍr‰BÝ™ÞãKwæ8cÜ ÉôóŒ#~µB{ˆ›î©g®þjIÏ<Jµ1n ˆP#~Í–ç ܤ!tæË¼›‰ÀãFç1b,â÷ª²Äˆ3FDÍ1üïU·ÛØWŒœ1âß@Œ½#~¯âбX‹ƒbDÔŒ#ÆÍ½n,ó3FŒ1bܬáu•,ÏÎ;gŒwóˆ<)Ň«÷ù`Œ ÿý!|µ¾a—hIÏ<gŒtóØóñþŒcáߢoÞWK~¢›åõ¹P,Ý™Çâ 1bĈ#gŒ1bĈ3FŒ1bĈÀ#FŒ1bDàŒ#FŒ1¾¡QWÕ¯Y÷ÿ~ ßñýxQbĈ#F ÃkÖ)Àéý"FŒ1bĈdœg>ý(^‹1bĈ£g$Ýn÷þ_ÿÏx!bĈ#FŒžñÿüß÷ÿeDƒÆ(VR����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/contour/dialog.png����������������������������������������������������������������0000644�0001750�0001750�00000021126�11332353405�016265� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��ö��0���Ê8ÄB���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚþßõ�� �IDATxÚíÝ{”Õ}àñ[ÕÕÝ3=3=Ýó½A $F²Ac°0ÆA(؉a7‰mœgü ‡<vwäøì®“lŒíØ>Þ=kO6ÇÇqlÇcpp–Ĭ^挱È`¤A è1’Fšîyõ¼»÷FM©^S]]Ý]Uýýœù£§»êÖ­[U¿úÕ­êÛR.—BlÛù1�Š}»ïB(ùø~ÛwÓ"�Ûv~lßîû¥­7ß~ÛwŸ9?N‹�@`œ<6tüà^%ÿÏìÌ4-�Cˆ�Sc£³SEtrDâMÍ-Õ× ÄÏÍΨß}sð—+›¥æææ………7Æ#-«6šIŽ>–š_}ÕûÙ�ÌìLfvj¼çÊ+íÏrppP­‹Uk^ã/$IýnûåÛfÞÜß{Û­¡PèßzäÈØH,Ñ¡™s~vzulêdJt®Û¦™�‚â3===EÍÒÓÓspp0ZßP­yC¼tqŒGë2‰Ëpÿ?¿çÚk6¬_÷ÆOŸZlhV"uêiäó‡ÃS±U-Íì �‚G’$©øüUR©ü¼f!^Ö|Ðì<uôÜÞ½ûÚÛÛ._³|ÿkÏvn¼Qˆ·æ;þ›+»âÏ ®¸òì�âeG¡V¾ðW…ymeñyí—l<ü›§ÆÇȲÜš9òbÇe›…#Ç/MŠ=/Yµå·íÔãŠÕ¿sý¦ËVvÔGãcSûøáî}‹Ù¬ƒÿÂݺdYë×þé‰_¿z¢Lõÿ|æ#Éø[ýY3sóC'F~¸{ßñÓ£^Øá*°ú�ÔQS肦ÍtZ3ïWþôV³É?ûŸØ™÷¢É ß4ÊâeÕšüuoÜ~òüäÈÈÈøøøâÙC©SC³ÓͳÇ.Ût£$‡Ìf,ü½çªËþò·\µnåôô쯇¦§3;¯½23~NiÉy þ„Bœ?}|63édvÝ_H .bèØ©½/šžžÙ¸vÙ»sGHÊ:/ÐÅ?G«_Þ*ñÇ_pÿÓÏkqF8üÒ³væýÊŸÞZx§pÂÐÏ« ¦5y!%ڹ馑_? Y–ÎyAnï˜_œŽ­Þ©o\òdV ßùk$IzüÏÿ¯o? d9Ž®]Õ5vþl[,¹¼3ùÑ›·nXÓÉÇN§|êÅ—‡N !þúY–îßýüMﺢ¥)ö«'¾õà3 ‹Ù¯þÙmÝmq!Ä—þüBˆžØÿð3ºZã½y‹¦X]äïÿûG…w}ùþÙ¹…?üím;ß½áág<ðÄþBù÷=º÷–ëz„Èíêÿ‘$´à_ýùÏ÷ìloýþWwÅcí±ÅÓSRßí7]¶²£)[X<2<òƒßwòlÚ°À¾Üh8å½÷Ü)„xøÙß½~S]$ü“§óÆ©óŸüе­Í Ï<úŸü*›Í !:’M·ïܺaMgX >1òƒÇöŸM®¾á”ú*}úo¼}ÇÖëÞqIS¬nzvþäHúïxjlr†, ¨XGÍïÿÑgõÿë?|EÝb8ï_~ó¡/ýñï !¾ü'*¼.¨™×8‹·8Åâ- k¶år¹©™…œcòÜx¸+ѹÊΩlÚ®X]Dñ­>5u¬¼<Ù¹êÜŒo_­S>Û»só+=ùô¾—/]Þúé½EkL’ÞŠ·;¶^öËý¯dff¯éY³ù’¤$Ä3/IO !~µÿàƒ»±oß¾Åé±ÏöÞl\ˆBˆ“C/‹\.ÿïdjd|ôt¡üßtõ«G‡_zeèì±WÕçÍB´oL´^õÎMù×™ÌÌÌt¦-Ùøô¾ß ü¿Ÿ~£çÒîÿôûÛæf lK˜L)„â¶÷n<vêlC}äö›·üçßpòÌh6›ÝþεWÄ%!ê£á¿øøÎ-ëW>àðÃ?Û³~uǽã·êƒÕ_˜NN©¯Òʦì-×]™ŸøÑãÿìW¹Å¹©Ñ7s‹ €%ÈÅÿÌ›?ö×oÞ®ùÓGvÃåþÕß?’ŸRß×oÞn4ïÛ¹ÿY|^63šÍ‰Ù\äÒöÆH$^”${ýSñÆz!ÄÌì\z|²cÕ:IVY’P”ð5W®M6ÅΜKúo¾¡Dëåò¾wmܾiå}»_ÌÏÛ?ðàÞ—K¹Üm7]³²+ùä ¯=òËÁ«/ïJÄyò¹_=!+á×o5,äG?Ì’ËåÞ^‘ìb>MB|ã¾?úÔÞp}ƒ©_\\P‘‹zÇþøöÂëÁ¡c¯¾~¢¥{Íç¿óï'_?ØØØô³}‡¾ÿåµË:ZÄÌy]®/ðsßzèÍ㯙Mùµïþëž}﫟YÑÕöØSÏ}ûÿ>ú™»>²óúÍ+;âÏ8zÝö­-ñØÑá3ýß} R߸jy÷–žµ›V5?ôó—4«“É”û†Rš*mßÜ#„˜˜œ:yvôL:sÿc{f§3ÉŽºˆ‘xà0MÈe!Kæ’$Ùx^³Ò ï›ÏûWÿðèßüÑ.Šï[¯7X®áíV‹ÛÇßZ}}¾¾#ÉÌÍÍÍÎΊ¹sç–7µ¯\rMÇ3³Bˆh$œˆ7É!EQÂú"-Í BˆáÓgåÒÚ½æìØŒ¢-Ù<‘>—ŸæèðéæÖ®l("„ˆ(ÊÜl&›Ë†Bo•Pß”ˆÔ7v¶µ29vÑÝQYV­ö…}qðHSkw}S"—ËJ²¬i¡c§Î¦gf燎=ü³gѺXCcï¯Ù²þ÷ꣅÉ"!ivnZS ’>þ¡ë¶nø¨Ù”GŽŸjnëžYÈ !®oJ,Èa!D8¬ÌÍN'ãõBˆ5+:üæç ³wµ%&^Ò¬~W{«Ù”š*½vfê…Á76oX³qÝ!ÄÙÑñ¯~ÿÑÓ©iuŸ�£û¦N^&]ðf¥©:[Lçýâ]·¨»wþÇ·3\®qˆ—LÎ-3©‰#Ïf•K·ì˜??úòOe±(„H¿út´éÖh¬ÉzU_;12=3W_ùÔG>ðƒ'^Ì/eMwˉ3éÔä´byg›‰J’´²»Mq.5–]˜9!$±¸¸¨D£rH)äã"—Ëße–%IŽÖeæ )|Y·!V/„XÑ‘Pß!Ï››ŸÄáp¸°õI ß/+aI’#M­±¦äõW_þޫמ:;ú•oÞ?•™þßq·,Ë’$e³šoÜzÅ ›/·˜2¿jùM¸°¸ŽÖÉrèÂjfG'2Bˆã§Îüݽ?.Ôi4=±¸0Ÿ“$ýêN©©R(¤|ퟟœ;³¬­ùøá=[zÞuE÷C{^—C2‡1`âe's½Õk"ë»éͺï­çý§vò÷|÷ýïºå¯¿³[¿\“o´àìÂüÔë{„$-»êæp4n-®»~úõ_F£‘p8<yäÙè¦Öë?3·xߣÏÝõ¶ßrö­›ÖIe’ñØòöæO}ñ¾_¿v25>ÕÕÞò??Ó;5'ÞµqM6›{äÉçä ™þ…ëI{Ǧf„xëo95úÌáŸ2,d>+ÎŒŽw¶Äÿü“0› ­_Ý!ôi¼’$Ë!Ålš[¢ q‘RHVB‘p8’Αpä};¶©® ršeI^rJ!ɪ{¼{÷›\µ¬óƒ7^{òüd2ÞðÎu«¾ý£''ž›œÖ¬¾Ù”š*õ\ºìw®ÛðÊëÃÓ3s+º;…cã“ã©3­]k$™,0 Ö… Ïòf³)?÷ÝÇ/žËøÙvY¼Á¼…åæûg>÷ÝÇóï|áS;õË5 ñ ž~±­)r6~u¼­;ÿNËÊu#™ÑUMóáp8—Ë8öRó%›­Ûè¹C§Žþíý·Ý¸eÃe«7¬i:—ÿñ{޽ܽö_þþîß»~Ã;Ö_Q”¡co~ï_=täDë²5Â4æH={¨3QwÅ¥+ׯ]õÂÃ''3f…|ï¡g?þÁm[7­Û?xäéçß»õJÃ5µ¾‹ÔÅBrü=Ž]ÖßÖséé½í‘_¼43;_ n*›S Éð¥˜[øÒÀîÿ¸ýŠ­›.o]]jbê•#'†††¤püÑ=‡º’1õê›M©©ÒØÔŒ,‰ïî‰ÕE&23=ýü&Ò˜Ìf”P„#0‹ñ6{2>÷dϻ߯+úyóÙ·é‚,ç-Ä÷üR>÷?ýü'v/WSp~¼ø7†Ïj>ÈœZ]7öÒñ‰eoP/,—Í. ïݲ~ÕâââØøø«c k¬W~nfj2}nfjbþBz´¾1ÞÚmh;óæt&=?ÉŠœŽ6%Û£ MÑhñWž"×¾r]C<qîÔ“©‘ú¦DK×êH´>52<1zfq~Aˆ\Û²Kš[ÇFN2zöDfìüââB´¾Ai63ÑhMv¬ G¢ox®P¾þ¼wlp_6»˜h_ÖÔÚ­¨®*f2çß<:7“‘åP,žœJŸÏå²m+Ö6Ä[ îSh9å^!D~Êá×^Z˜ŸMt¬ˆ·v?ùúÔøh,ÞÒÒµJ GÒg‡§§&æg2Ùl6R”h]sÛ²ú†¦±ÑÓÚÕ?wÊpÊc¯¼ ®ÒôdúÜ›GççrÙ¬,‡¢±ÆxÛ²H´^sŸ@ÁعÓ== Âx`Ïfo¼ö¦·ÂýÁWšÛºÊ1oa2Ã7óó>M~{¼xÍcnâüêØÔkÇG;¯|Ÿ/Š€R(”mߘ™K¯¿ì’‰‰‰ÜÇ_Ÿ‹6&,š)Rß…£±F!I²üÖ•pD’CÍíÝÑ©úœ¤P(—!\“CJ¢sy],ž¯Xc²£.W"Ñü™­)Ù©(ÑP8œÍ9I˜ÒÜÖ©kP”°$ËBä² oõI’º|ýÙ²¹cE¤®^’dͧu±¦DÛr!‰|÷}]C\ GòÝ,š­¦ìXQ×ðÖ”ÍË•PX …„M-]õñ¤Ž !Ir¨¹}y¤~,' Y I’”¹P(,…BF«o<¥¦J‘úÆdûrYV¤œ¿l)a%‚ŽÀ¼Wýâø°éºvæ2¼eêú¼š7-o·^üÁä¹ã¯fRu«¶*ᨾܺ†øó™ásfffæçç&æ3uM[¬ëŽÖ…£uFÈ ‰výÛ-« ¯cÍB5ÒY8 ·vj¦7,$­Dë ë£._/ٱܬù“m¶ ´˜²ëí)›[ß>åj²énL” GBúÕ7œRS%%ijéä ÊÑQ£?3Tm^“QªÞ¶v«uQ±–esb™,DTˆö�AkJ Òô™X;xð•XSB’äjÍk+‹�ä‡_?xðû³Ô76ççªÖ¼Æ!žï¿�€A”5Fcþš×4‹ÏŒ§Ø¢�àk±xR—Å ‘OåÇA�ø×÷Ü[ˆò|�‚£¿¿_ý¯¢Ÿ"NÓL�à;šwÈâ °ñ�@ˆ�â�„x��!�@ˆ�â &(ÅÎL& ßO¥RùR)׺Ñ/KSxa‰êE»R õ¢ÍŠr}}Í ×¿¶n ‹×în‘bË,Ó¢.Ðþ"ÊÔDÖ5YrA¥×ª¬»%‚âÛ¥°³¬òœÉd2™Lz퀩J}4±Ãï-C!¾Ôl¥LÇ’EîVX®ãè£)\Ñ,ÖHÿ©áF¹s|Me4P¾üΰqŠm1w[&¿î…¥h^[ï3.ÖM½ 4×@fûÌ’΢µ9oA£,}ñ…½MÀ¸{ [¤fe ©†kdñ©ãu·¨¿õ¹Í¬ ã—ƒ*å“wýújþuÜbîn5õ"̧i®ŠÕͰ —ÜpÖ­]¦Ú¢æ²xMBTþýâü²C—ÒD†ÙœÙR¬[Õ-¥ò•9ÅV¥WªF])ª'{»ñ®ívníj¾¼p.ÄëÞ°%w�o£%OcÎÚÊ0þŽáÑ_³Ñ­ò‘Ts^ÅVUW`ÉlÑì) ¿ì!6Oc®D9FPIrâBY{3]Oõ7¾|‘j™U²Â•wÐ\žjáä.ÆßÂI±¨pÖ&\ !ÞÝKÝ¤Šºp³b—œÀAý­×ÈÝõuVU³*¹Xõjj2zýêë95|€¤{H‰ÍX™­i¶û»·aksY� iëÍ·ßvÇÝ'ÎŽ~»•_}�?ÊÿêÓþtK,ž>rüà^0�€À"Ä�!�@ˆ�â�„x��!�@ˆ�B<�€�𠃑&ó_�-‹ïïï§Q� €!žø�A¢í¨éíí¥Q�ŸJ$ýýýÅ5¾ÜyϽÆY<� Hñ�@ˆ�â�„x�@y)EM­ÿ…åbçu÷çƒýR&�x=‹/ľÂϽÓ|�„,^“Û^èóú”êY “%“IýB3£a!ö“kë’ dv]RÊU �ø)‹/*¯×„r͹¡Ø ûW E•l=1W-�j:Ä[p=ç-„ZÇ•ÉÇèb»Ú5�|DñE-ÝÚ-q≰�ñž>%ä{ó ƒµuì.Ü(t=€_Øí¨Ñß5uÜ7íbÏû’åÕ‰¯ï‹'P+Y¼:º~ ›é°ú6¬fFõŽ{Z +©þHÿŽYý­?€@…xaÒbñŽE—ˆaÄÔ?”¹äiÃæ›®Ô�ü… �€ÀçJ¹…VÉ2Aˆ�,M¡ €Oí ¯ðƒ,@Ðâ;~âÔ ütÔpõTìs<1~âKº,ì=ì:@9ÒvÍ; ø ²¿vDv |é~Åð}(7ÌÖ~⫾S²ß�¥\Û|Óì#üðÙ/»&Ob@0C<�€�ðOˆça[�pÌ·[ ë�ØÀ1žPð‘r¤³„x à¾þõ¯ÓÞ·k×.!ÄÀÀ@±3öööâÀ»úúúò!Þ,d ¾ŸH$Òé4!¨uÖ¹ª(‘H”8AÑ!ÞÁÅ�"5Ê·ÝÍy'!¾2{R)§&kÖW.€Ó=öíšÍñÅä�~õ©¿¿ŸÝ°Àc6þR8¯;è_Q¼S{ }}}6§d‡�ˆïKá'ò `�ÔV|组>Máe±„x †ßý›Â;Kä ñ�àÞA"Oˆ�¤ðyB<�ø&…/6‘'Ä€oRøbyB<�ø)…/*‘gŒ †Šç7vü›Â•ÈâBL÷û_Ñïëë#Ä€o¤Ói‡«~ˆ·k˜Á �ž»ã3V9ÄÛ¿ap1�µ“ÈÛÌzwÔ”o¤_µ%ë�p9‹ïííeXj Ô#MÚ¿ûªŸR3£ÅèffYT£ð7‡Ëâ5¾«ãfQOZq›';Õ0{ gøê�×Î6?²Rat{B<€"‚fÅ $÷‚R;jœõëU,¿ÐÔÊkµ5¬›Ô/õÔow/oñªW²Ø,ÛÅ.rMzî  •Èâ Ç’~O­ú¤¯Œ×jkX6©_ê© ž­dê‚*V²ØøžR)½’ù¥˜ÿ7ë€êgñ^¾õx à—Ý×G‡Y>(xv»{gXGO";!>P|1 ϱ¦%ÉŽk ·[‰ïE\§{ùÚÈû‘KÝ5Q­–Ô?­¨ŸÀ¬““mJ`Æw_´$ÍXìeDQ''³»££[|d}»•KFB<ñKD.^mxa‹/¹t³ Š}Éeñ´%!&'‘«Pa¹”+uÏ÷£€k«¹\õ`% «ä‹MïµJú·%Q»Y¼¿½òTm\ùzªªžÝôš>_ZµŒ'j�€,@P8è²ó�Œ(æÙ³Ñ‰õwP¸Ê!Ä("¾4mŽý+ŠØN_%÷ÌKDG @|_‚ë㎕uY Äì jtÔ�µ:¤Ì¥<Ùi˜Âó¨(!@Scg?ìgs.u猾£Æñï ‚`éHíñe÷]A_<�â"…·~²¥Lƒ /9ˆ1Ê„Ž v£¼Íž‹± ló·[Aˆà$Êû‘³±K1˜¸ï :j�€� Ä�ñ�€òâv+Ps̾UdñTëÒ¬g1ümH~ž› ,ñÝâSÇV¿£ÿñtÇC£(tÔ�äïÅo¬â49£Ô¥Ø VÊ]9ö0g½‡Žk^¦µ�¼“æu(9ûžªÍ¹Há+â5‘Î çgMÀõH­€�äø6%û¿ùgs.ë!ˆQ®¯ ¦†¿¥«Ésõɯz[ZÌhXHQ鳿á †I„Y­„É8J«l%^>Ó D%õÅ"š>jkB¹æÜ`1cQ×kêK u… &Ð,˰†oêÏjf'*Í›öQlk�>êö)žìØ^﨩îyØzt$u”¯V–aÑêSŽõ›@%ñõîWì!Vúï:ÑïêÝ_áF¡“Äkû„áÝ`Í ©*g)Ôl7‹×å»qª?6 AŒÀ†x;i…7ï̘åû;=™ ª•-9ûÔÙ°À¥Œ3 ûä¢ö u à8ž:îy÷ZJ^ÔŒ…ð­ÏžÈßT9Ä ó{›6#”áOÃþŠb;ûÔ·tì_]Úï0qP±¢AG €2)®£F}¬ßÑÿš—Ík7ÃçXœ]ÚymÿRÔ°„ÒAXPå,�ä,€ß¹þ(‹õ5v.Ö©k\B<�'ñÝÝQ|­6{BÁz.;%À&:j€âìiwWN'îÖ„x�>8¸~’€5@ÍY²ÏÝ~ ïì;± Ľ³²‡Åæ×¥â»äûï‰KB�^߉ãºtþî‹çë �Ø_ô¥Œ™ÔgÝ/ê6ôwÔèó"£¬w¿údQ ë£æB<€R#û‰â.eàbâ¾[|ßÏ•#�3Ä�âi�,ø¾/ž°� ñ�ŠUì�¿b©ƒAˆà•øn'î[Œ-ÌÓÉ>ÂíV€ü„x�þG|¯5Æ54 àA½½½4J ñ^Ø“‰D™JN§ÓlxøQ"‘`ïEQj®£¦¿¿Ÿ­ Ö³x°“³ ôõõÙœ’M€,�@À?œ ðËØ¿„x�>àx€_ºOÑQ�„x��!€7ñû9„x��!�@ˆ�â�.óúsñö‡`p�ðSoÈ0€"²øòåk___[�\ñ½½½ K �~ÇíV� Ä�ñ��(õ¡ÉÊ"­çÚõÂË·:úÊ—c‰•\ЦL×d] ‹;CW‡¡ØáÑ,¾p€å÷Ë rTÖE”uu’ɤ¾@×—X™¥˜•YŽÕ±(ÐÅ TÅÕ©üA²xJ&“š_ŸñÃØõ”mÉ0áÖ+“lZ,ÅÝ¡Š«CÚB|墰: ®ä±WÖÞ§�Ô¼bí£^P™ö³+°ŽœNjon·æ³¶ÊÞ¾d®X”4ìÆñc|/ÓΠYP™öÃý{Ž!Þñ=ØYp9BU°ã{ ÷Ô ßtÔèoµà ÆÙR\߈ï ÄW“þù?‰šåß]> ñU¼?Y¦ØQ•Õ)÷cÑå[/MÍË}²Ü¥Ü«cQ ÆÃ£Y|åwG_?r )¿L‹Ó[¦§3ËÝ€K–Vîg@+Ðnt”��!�@ˆ�â�„x��!�@ˆ�B<�€� Ä�ñ��B<�€�„x��!�@ˆ�â�„x��!�ñ��B<�€�¨>Eó"‘ Q� ˜!¾¿¿ŸF€*(Wˆïíí¥}ŸJ$di~—N§]ŒÃ �ž:O»X!�¼•ÅÛ™,ß™Ó××g=OÔ�€/y;ý9„x�ðY"oÿ~,5=ëÖÂõ#mà6G%woë­oó–,!Þ5Á~’aÉ.?Ú¼FÚU?»õH%!ÞMA}äÔËù2mŽLäíïöôÅ€oùb¿Eˆ�?]ÌuåêZˆO&“ÉdÒú;óÚŸËY­*¦ZË­.MƒþµÞnm&}!É –|ð~"ï``ƒ2öŧR)×§ôK˜c׬ð&6lód2YXnáµá›€—yu /öæ“Rî£.•Jå¤ÂA¨y­™R@º&ôe*`ñºØpF 7Üô›[ݼΜ6G-$òÎÆ&“+v„§R)uexLŽmM,pñ�.G™pvâ7KºÙ(€&‘w– _ÜnÕåòu#è{lEà:‘*¶É–ììÖ7,M ˜%òއöôsñ…ÈK´õug7­áµL>åì+ >øêSᢞ›c€3|QÖï'cÇ[л!^}KÖ°ë¶'Mw0g” l_”Û®]»víÚE;ø%Uww`"ÅkÇ­>Ôj¿)±V…òK,¥oßÊœ¶5ÚðÍ`78{]-S*°'©?2|­™×lz·jeV¦‹Ë­ÙCËlSZ·­[-oó.Qµƒ PQ|­ Ä#ài>OI•Á`¨N”@ˆ÷=¦ÍO¡£Æ5<zL›dñÁÄolÒæ�Y<�€� Ä�ñ�Ps´·[y ð;Žb˜†øþþ~ð5Žâš×bâ:�ðÈ5Ü÷Ü[ø—¾x�,B<�â�„x�€GThŒß=Åå»ñOjð99?ŽQã—ÍDÛ¦…Éâ ðÌÛˆ¶E0Z¸¢#Mú"5 ±eÕìf¢mÖÂdñ�X„x� Ä�ñ��B<� ¼<úÛ­ÉdR‘J¥*6c­É7TA%[Œmäl3¥R)šŽ¶ B_hzM‚ëA6¦öþfbѶÊâ5í^Øê3­á›f©"éE­~­Im,ÚÙΔfÓ䬶¸š��×IDAT_è.6ÙfÒ·•a»Ùß|´mém닽Wöfëþk ߄멦­§´(Íð¸"QueKÙÙ(p±m}±÷*>jzÓ¤Ù™3Ÿ¶äù‹ªuûÕz4µw6Š»ÇK! ÓQãf.²‹+'›É¬Û‡Í]ÃĬ%‰ïn)ú|Ñã{¯âÁ]VÓ|Ž[°È³‹»˜ ÚŸRㄳ¬[Ê~ƒ£”"Tý–Þß{ýô\¼á^Ë®ìJænذöspg[AõÀÖ4ÛLC»•¯mõlÐ=»dmçA,šžôpÉ«N}>bçÒÇΔêiôw\ÕÝš\lÛȆ™58Üm[ë7é¨)îÂ_³§.Ç ôΚÚâªÓ¬y­§´?/[ÇÁfr|,À•¶õQ#|�²�µ,È!žk�5ÎÏÅ;»D"¸ ‹�â�„x�€T´/Þï?îî}´0›‰¶¥ª“Å÷÷÷ÓÜ´0ØL´m�³øt:ÝÛÛKsÓÂl&6mÌ,�@ˆ�â�„x�¨MÚÛ­‰D‚F€ …øX<¹?-î¼ç^�ü+Ogñê��ÉâG†Ð�0R.—Û¶óc4�̾Ý÷ÿü‰’Ö����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�014240� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/largebuffer.png�����������������������������������������������������������0000644�0001750�0001750�00000220163�11332353405�017247� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚAášq�� �IDATxÚì½yÔ¥gqX÷~k½}_«uK´$„@-`6,$Yò82 7vìçxb!Æ9¶3bl'™#uÏøLðg>°Mã‰ÁCƒ!6 0` ¨Aj--©Õ»z_îüq¥Wo?KÕ¯êyïúU§u¿{ßåÙªêWU¿ju:"ºî¦Ÿ!—¡”{>ñ!"šìª«7ßú—á”ënú™{>ñ¡Öµ7¾õÍ·¾ã‰=}D\\\\\†S}è÷Ý=ÙýãÇŽúˆ¸¸¸¸¸ ³¸ÆrqqqY*rèÀÞ㇈ÚÌòU+W¯ìoëÄñcõOw}û Ï[ÝZ½zõ©S§~xpzÍæ%/zdßãs¿ÿо“¼ôÇ})¸¸¸¸ ³?väøáƒ—¿øÅøOîûö·‰hfvnP¿Mk,jµêŸ®»äºc»¾¾åÍoš˜˜øÈG?¶ãÀî¹ùõÁ/O?zÁÜáG÷цK¯ ~îââââ2tëÈ¡Ë/¿\õ“Ë/¿ü¾o{fÙòAý6­±Zg«œ©™Ù#ó—üé‡þüÕ¯|Å‹.»ô‡Û?{zùêÉéÙúwÚ{¾{zÅÔá¹ÍkV¬ö¥àâââ2äÒjµZzï¢U“þÿ6§±ÚÁ–/lxìÁ§î¾ûžuëÖ^ráy_ÿÞ—7\ñz¢g~`ç·^|<°÷ü_åë +?}ãµo|íK¶å;ø›/ùh¸¸¸ ŸÆj›4GûÙÿ à·Õ•u]ñýo}öàÁív{õÄñÝ;¾±þ⫉èÐîÏ_ /ýÃŽÍ×ü„ø›Ö®þÙ[^qÉæõS“û}ø‰½ÿù#_Üwðȳ÷¥;oûÇkçWÑ¿ú½ÿï±Ýû«^}ÙæŸ|õ›7®™h·ßsð³_»ûW¾Óéýßïúé…Us¿ÿáÏ}á›;†h5P‹ˆŽÜ{pÏã«×nL~ç‚s×¼õ'^~ÉóÖétî}à±Þõåj(\\\\z­²(Ò ³üöwÿÅ›r_ÿõÿ篑ߞõµä‡Œ• Dm¼â5ßý‘Y:NDgÎØ7·jnaÃêã|{çîMWÞØjOˆoú®[o\·°âñÝûy|÷ÂêW]r~çèþÓgÚSDô 6tÕ]uÁ껞˜œš%¢äE·Þü "Ú±s×ÑcÇ_|ñæ[où‘Mç¬X¼ëžÊÏÛ÷ä£GX¶b~xTVW:D”°bnæ×ß~óòeÓûù¯µ¨sÓk¯]??÷›ð¢ ßJ...½WXFtŽ4ÈÞ÷¿ùåK_úJñ·¿û/Þôÿñ#ÝÿÎ/ÿ£Üos>VZñNLÎl¸ò »ÿþo¦&¨ÝníÙñµöºõ'O»àºée+ÄG?gõòu +ŽŸ8ùsïúwV{rjfÕò™Ã‡Ï­9orr†ˆ^}ÕÅDôÀƒ^|áy׿êe±ý++ÏÙ´bÙÌO¿á"úà_}òõÉÉéÙW¾ìEïù•rý+®¸ë³÷ì>úÜ£vΜù“÷n!¢Å¿ùò_{åìôÔ_î[?|lÏ/ü£Wž³zùWî{ð?ýõÏœéÑ¿üé×]ü¼õ+çfNœ:½ã‘Ýú·÷<úä~"ºdóú_xã+×-¬øÖ|úè믽ôSwßÿÁ»¾BDëV¾õ¦k_tᆩɉï?¼ûO?~÷#Oî^ð…¬ÿù7¾ríü3?¯û³?sÓu¯zÉE+çf?ùèîý¿÷Ÿ½tó†å˦Þµûÿüƒÿ²lÅê—]~ÉæMë^°vvÇžS-òÔ—^k¬&‘½·üÒ¯Ç_þË?ü]ªÙëÉßþæû?úÛÿü]EUý»º`ðÛœÆÊ¾ÆÜª5Ë/¼îøÎ»?Ý™˜kŸØÝ>÷ü ›‘W}úÈñc'NÎNO½ïöŸÿþ®ßßùäý>>7»011AÔššœ¸îò ˆèýúè{õç6¬]¸ø¼sž8Ú¹ì‚s§§&;Î_þíçV,¬[1¿î{ݵ{ÿÆuóW¾`ÓÇïÙïoþÑ+~ðè“W¿è¢·ÞxÍÓGŽï¡ÇV.{ÍU/øò×îý‡¨ÕZ»°âs÷|k÷Þý/½ì¢«/¿äWÞòšwmûðªU+o{ëëW,›ùÖý?<|ðÐë®»’ˆxjÿSm<ï‚ßxûMkVÍ}î«÷íÙ»ïMoxÕ¯Ýzý¯ý_>~ú¹{/›™úÕÿõõË—ÍÜû½~úu×<— såÅ›n~Õ‹zl÷‡?þ¹ås3/}ñŇ÷î:¾ažˆÎ™_yþ¦ k7]´zår"ºøyî}ðÛËW.¸Îrqqé½Õ6ýª•üíeW¿&§äøßþëßÿØûÞñ“D¨«úu™u9sdï™ïL?ÝŠééé©ÓèkŸ<Ýùý¿üüÏÞ|Íu/yáu/!"zbÏmþßw=uZ­—¾ðüå³Óû>ýÍïìøúwúÑk.ûñ¹jñc÷¬œ›%¢cÇO>r|ú Ûíɉ©‰ý‡m\G«W-?väP|£;ÿø/¿ôïþ¿ÿþ]矻öãŸýÊý×»Þõ‹?}Ók¯~ÞúU_¾÷Á«×þÖâá÷®X±òïîùî~ç›Ö¯¡c{®ºæ²ËfžÚwàöß~ÿäôìŠå˯¾ü]×í¥—ž¿fÕ܃<±íÿbzÙŠÍçm¼æò\¹yõ=ìkONuozÕ%ç/_6³gÿÁÛÞ÷'¦f~÷]oÙ‹žßýÓÌÔzúð£Oî}bÿ‘}üKÇ9Ñ~èû;¿dó¹øÿ;ucrËfgN?B+ +ÉÅÅÅE£|ÚÔn~ÕjµÓ¿Í]­ú<ÿÛý‡w½ï—n9K]]ûÚÄ}“‹)¨:¸ëS{prÙúUÓGNœ8qüøq:ñÔ¡§Î[¹îyÈË~ã]Ÿù7°qõÌå—lþŸâG7m8çæë.úÃÞ=9½ìUW^DD_úú·[퉯}ïѽæ²{ùUôáÏ:zœˆfg¦—/_Öšh·'&¨ÕZX¹œˆ:|æôiê„wÙ±ó±Õk7;Õ!¢ï?øÈ²•ó§ÚSD455yâøÑ‰ÉÖÏýä˯~áO-_6Sýdz¢µ|v’ˆÙµ›Zk6^ðÄç`½5«çˆèÂó7üÕûß[}xîÚùC_{`ÕÚs» Þê•sDôðcOR»}Φ wí=ò²g¿ù­|íÛ?¼úE^qé…DôäÞƒÿþw=¾ïèo/~âÅçÎmZ¿°ëÉ=¯ºæòW_sÅþƒ‡:gΜ¡Î„×´¹¸¸ôÜÇj2Ž•»Z ÙËþö·~ñæ:–øüÑÇ“÷ÍøXUyìоC;¾|äôäó¯¹áèÁ={ÿa{›NÑþû?7³òM3s+ùWšœ¸âù¿N§÷~úó÷=vκïþÌ-¯^±|vß“^pÉ‹®ºä<"ºùu/¿ùu/ï~ùÜìË.=ï»?|ìÄÉSÓS“?uë·ÿýÃí™öK.Þtî9+‰è«ßºb"‘§púôéÉ™™î œ:}zjf¶ýlVH§sæÕ/¹èµ/}ÁcOîýÝ÷èð‘£wüÆ;Úív«ÕÚ{ài":ïÜuÓ³³Ôjo>wmuÁ}ÑÎÇžø½þ·êýû>u²Ó9Óž˜$¢ƒ‡Ѻ5ó“S3-jo8繺´“§ÎÜùçŸ9qà‰MkWÿ/·üØ«¯¹üå/ÜøÑ/ý`bbæ«ßâÔ}­˜›þå[ßLD_¿ïÖĵ²Sàâââ2`T°FsW; LýößþÓ›*ïªúú­_¼ùßü§OÄ÷U ‚gN<üƒ/Q«µé¥7NÍÌM­›;}ékþà 33ÓSSSOïøòÌ•7ðï?=5ù¿ýã×>öŠGžÜßéÐ%ç¯%¢o~gGçÌéë^ø¼É‰ö‘£ÇþþÛÏd¨_xÞ†óÎ]û†W_}çŸ}ê/>õµŸ½ù[ÞrÓk_ñÄij_|þZ"úäç¿ú;ÏÙtQ:äÓj×òÎRÎ݇<}úôôÔôën¸®Ý~晿qÿÎC‡­[³úŽ_ûù£§èEm¨~òõûÞ{àéÍ›6üäë_ùèž§V-¿êÒÍôáÏ<ýàÔyæ‚÷þðñÃGŸwîÚ_ù'?y¢5ó²Kϯ~~Å 6½éµ/ùÎ9zìÄù7уOÜ÷Äï¼sËþCG=~í‹6/_6óù{þá»;vž³é¢¶i%¹¸¸¸htÏYïý…sß|÷òì_¥kª�+ñÛê¾]0ðÝüÉî'ÿöŸÞß7§±7>úÈ7Ö®œ~rÕËV=[]´æy—î>²wóÊ“SSSNçᇾ¹ú¢«™:qòÌǾxßÅWmÞ¸afzjÏþƒ÷Å¿ÿó~fvÕ9¯zÉEDôÑ¿ûòý×wÉ£®¼ô‚÷®-/¿ê²É?ùا¾úÀÃ?òÆ×]sñ›&&Ú;{ò®Ï~å¯þöóËV¬žšYF¹,…VòŸôÅoþà…ç/\wùóÿå–7ìóß<vüäìÌ=~bë‡>ýöÿéºlÞøÕ{¿¿ý ߸é5/;}æ ;qê·?ñS¯yáµW^ò£³³ûþÎŽ‡xàÖÔª‰É©îp=~jëùôÏÝ|ݯ¹æ¾á÷¿öê˺wÜèh»E7üÈås³Ó‡Žûøç¾úß>ù?¦W,<¹ïàu—=où²Ù=û}裟ùÀ‡ÿvvnÕÔ̲öÄdËQA—«,Qᆵ|æòùñºkÿ¶ëeoÄþ¶RWÝ»¼û?oïÏß¾opán¬>òdð‡#O<pÁìoî<´éЫ߬sæÌ©Gî¾æ²Í§OŸ>pðàý–/_!óægΜ~â¡ûOŸ<yêÔñΙN{bbÙŠùkÖMOÍ>±óþÇŽ,_}ÎÊ5ë»­=¼ÿ‰‡[ÔÚðü·ˆž>ðÔñÃO?Þ¡Îääô²U ËW­™˜œžž™}èÛ÷œ9sz~ݦ•çl|ø»_#¢uÏ»tùªùG¾÷ÍS'ϯ?Õ9çîyô‡î[µf͹›OŸ:¹g׃'Ži·'æV-Þ¿§Ó9³öüœsÎúÇùáу{O:yçoþòU—]ôþ?ûè]_ø‡5çnžœšÞÿä#G:yìÈ™3g&&&'gfW¯Ý´lùÊ.*Ø…÷ìzèè¡}§Nœ™kµZÇŽ<ݽã©ÇžÚõàé“':gδÛ3s+V­Ý4=³l÷£;Ž}ºsúÌÄäÄìòù• ë&¦¦§g–ùnrqqé©xêñË/?‹ÖüÞ/}*÷å+^ù†g´×}ßY½öÜ^ü¶úZòÃîo«¿î{ò‘çúc ðÄ¡=ÌþÞν^ü:jŸå—µ&&ά»âȉý—]|Ñ¡C‡:?ÜùƒÃfòe¼íöäüúóÏœ9Õ¢V«5Ñõ}&§f&§gW­ÝØnO´'&'§f¦ff‰hzf®Ýž˜ž#êÌέš˜œ:>·ªÕj·'Ú]¯izzvbz†ˆV¯?zvY«Õ¦Vk~ýù³ËWußbõúó&'¦ZD´r͹ËV-LN͵fçVί=ZÔU6³ËWMNMµ~öæk[t̓?~ñç^uÙ…O9úw_üúäÔQ«ÕžX½î¼ée:-j·&Z­V‡:Ý‹?çóN̯;oznÅäÄT«Ýît:+OŸš˜œ"¢ée+Ö×nO¶ž}ø‰É©ÉééÕçl<sæôÄÄd÷"SÓÓ“Ó®®\\\úàb…^Ë•¯ºùU2{¢ñßòÄgýáé§vÞdßìæk'§fâëÎ._uïž#<uï±cÇNž<qèä‘Ù•×䙿V¦õÙª5‚O¦ffç×mªþszvn:b›ïÊÂúóª¯9÷¹â°Õç<§“'§¦ë?Y±°6¾ÎcO|ýK/|Å‹/8züÄ=÷>ðö×û^{þÆV»Ýjµ&&§V̯å§djfvõÌlòO+£$¢å©¦/....à Ɗn`¿ >뢂íÚ»d'ñÉ÷>¸ÿÌéSív{rfÙª5ë§f–Í®˜o{`ÉÅÅeŒäı#GŸ>�t¼Üwßw–­X==;7¨ßVŸìÙõàs¨àRû¯:gãìòÕíÉÉn^J{brvÙŠvÛ3÷\\\ÆJºí¦î»ï;øO–­XÝýÕ ~ˆ\A<ö²låü²•ó¾š]\\Æ_iÍ­˜™[1Z¿Mh¬®uäà>ŸQ—ᑹU ‘Etä྾çm>:.....Ã#o{Ï+¥åÑ—!•mÛ¶Õÿs2þÆþýû}˜\\\\\+‹‹‹Á'îc¹¸¸¸¸Œ†¸ÆrqqqqqåââââââËÅÅÅÅÅ5–‹‹‹‹‹‹k,×X.....®±\\\\\\/“Ú,,,$?ß·o_÷Oûö5FNß+¸xuÇú­K#þmý|µòw¬ä¯Ù5\l‡à©´ÏÓø6ÁjnÝà¢íõ·`ÎäxN}S/kûa/Æ69h=]~“¶ŸõóÔ@îÕëçÔ)9TZŠy¼………………}ûö5ûÀIeÔUüâÃóT¤’Á’ŸÏf§¾ZÌ}›¬!?Lz«±DÍÙS×$ç U«Ê¼ºW¨~Ëøp9Ç¢)oyëøeëw¬ü»ŸS“ºfMcñ½Ñèµ—Ãv#sŒ°ùÖO88¹ÕÒç'dzG*¤~d%ߎ™GÆÅAŽ©ž¾ ò؆yl÷tÊãÑiüLÌÙ½^ͽx5­i–|’º¯ü»ÿÏèþf‘ä½øÑ(9e’wTv¶‰öÖ½Xüà$ïÈ?aɈ1'h䦾ð4çßζH¸ðð[Øæq²pÄûàiætun­‰!‚FÌÀä8w/Zj<jb…J«ÏfÓÃGZû]»‘›ZT¹puÉÔ7>ø¢Í–‰–wh–YãXM©“>oû$ÚÖ£W3¼»a›õaj†$œ3u¿¸8ÔCbu5¸Ýr†ó°½i¯§¾©mh7^³6®ws™)½˜ñÉa^úCâ= ç«åPé1›šas°êÏ#:È«š‡¡ò’“áê§^µ¤+åaXBÕ»$5£Y›Ò»}>gÚ}Øá=²­zg½‚{¬þjA¤dØÎÙ>O͸ª«Þ lÉ\Ä¡»ažÖøñ†ÓË•ñä9õsgåÐ6ª“=šòø4oD3Uú H㻡}µ¦ž$xªAMMüÝä+ôm^â¡f€Ÿ£Ÿ9y)æâ}^Æüà$7ò`7²ÆúóTÈ6½>Œ-r ›eߺöÆ·¾ùÖw<üä#÷}ð=o#ïAìâââÎô¨ àXBýÝÄ_ß¿fnÕÂîGvì¼ïngirqq̱56¹à�–ˆ¸Ærqq€ô!SÜÝÓñ“IŸr—*-—¥6†%Ïì>–‹‹‹‹Ëhˆk,×X......®±\\\\\\c¹¸¸¸¸¸¸Ærqqqqqqåââââ2Þ’¨Çêc¸¸¸¸¸¸ µµmÛ6—a×X®®\\\\\†VBTpË–->(.....à óóóo{ÏÓ>–‹‹‹‹‹ËÈøX. Šç°¸¸ ³8¤äËå,ùÕ_ýU—áï^ëËÅw…‹Ë°Ëââ¢[“£(ÇrqqqqqËÅÅÅeÔ|/„!‘d”QÖXݮ̱ìÛ·ÏÛ]7.ÈV3RMAõŸñ”ñ&ïÌxÕÝ<¾ZýO%ÏÐì !wAÞQ5øÌ¦¨>I~Ÿ[fëñ¯à»²D-IÆSPË7@DçXUTÿ^XXNLäCÕ“tÈ<özªòsw)·´ê¿Õ^‡Q¢ÁŸ’öANIw.N« "­VËa€g eœ,<’F««7Þ¨g¼Þw©>Ñ÷É/'MõÞùͪkò#“tDª#¼r Gã±µ-é‹øŽpqiDšÉ¼¨¶eòtIŽ?hÉ¿VŸí잤 'W}9>ŽtƒÊ—SnLrwÉ}?ø¼ÿKZ5¶u'²þœ..ã-“ªSƭŹ<RÔÔ˜#ˆ\�=5ŽÝ™}Žºï‚ë¼ò§Ç_ëŠ5…FÄJË7š‹k,ãVt)œ¡=JÜ,Õ»ôç.åãŸtãµÄ_ʰN*—Ý•–‹k¬&=‰%®® øRÿÏ£Þ)Hí•sš€¿N³Ï_2þ=5àê¯éÙ.KGÚ½ØK¾Ê­YïªÙIé§i¢zræ›Ú뎿9âèfŸ‹KÏ}¬ºñ뻎Ÿ “4dH“ßÁ?ld*µ·C¢8ÌÏ»ÊUÝ%2è€8͇ı‚!òMçâ‹g’G‰&8ŒŒ.)Á?Ÿ¹/x»òt|ävÈk2¯ZÒüðçT5¡..c,Î+èââââ2.>–‹Kï$[~ïahó<„ìâËÅ¥W2rÐÖ?°C….®±\ŠÄÙ ]\\\\c†8´‹‹‹‹k¬mÛ¶ù ¸¸ §$;0¹¸ÆrËÅÅeè$ÙÉÅ5–ï —!¦Ó(ÊmtÇVº})Lœ×c¹¸¸¸Œ¶,uåËÅÅÅÅedDÝ‹ØfÞd%Ïû?¹ºÉ&k‹g¾…±êCŠúüŽÖû¸Œ‡,į1KÛÖDñçF8dpüÅŸZ!Íû¸Œ¨Têê6º#û¥ðÉñ±â~íqkÚØ:VYÊÕ'K³+]ì²äÆ–¤nÅ`ƒy\ÄŸ óû¸Œ¥êJ¸_-¢Q«¦®ZKØÇϬ¤…‹ÅæfB#'ÃÐ|/èü”k¶?ç>¼‹Ë˜Évº^p§X6öÒ€Æ*éñãçNòDÖ6`Tù¦½Öúÿðq#+—‘–èÓŒ*â4YëY$p|,êC® Ÿ&*OÅ Å{¥æúÖÕÃ×ãg..£(u=zWÈ¥\c(~¦ôÁ3«þÓÞÅee+Ý^i@ýTQ«œZº­uÇÖÎícì`A+NŽ 6³÷´r.7‹aqüãTòÀ&`Àáå©áyx÷à]ÆCK%ÿ“ù<©´êßWg ò±rÁùê¯¹Ï ŽóWŸ/MW¬>,ñ ðãO™jF–Èû¸Œ’ ­ñÅÑ âäY ÚÅü¯ÀÏÇØ¯Â¿�N.Ë\û¡öa†êá]\FN+nÉúlü},—¾ùL±“Ä»M·ÑujUÃ1­ nXc98ãâââÒ¬£%YzÕå9....ý‘Êñêê³Vkl]«J¼?VÏeqqÑÁÅÅE«D¿ª›4¸¤Ü/×X=oCìââúF+ÌÏë¾Öu³Zã[’å«·²mÛ6F¶lÙâƒà2~Ò¸ßÃh)z\ž–k,w°)û÷ï÷Apq±ylÕç[éö;»u¨EãÍrå‡ò`dqqÑչˈ*X…Ô?i<¶”»š*Ž5/×X....:åÁgŸ÷S1T÷ªÇ®Z” o ¯ vqqqá\“‘y˜ÎøO‡ ±b¦Q†{ÔiI‡D@ÒX[;+—%èT J{uïÔ]qÒzöÿ;C§nÝÇr1ê*j´‘£‹Ëq³ré½Ö—( × ÿ=~¥Z‚ÆbZ0zÐî(ø·õ½“$çþ¡‹‹ ïfiÿÚk/'pÂÆ^Œ>–ÁBw£~hÝ2r*HØÓªGаÎH½BŸ4–[è®®\\–š§7¬ßý´ßy•ëudÃ÷tuåâ2¢Õ-tW Ã=×Èc„õÇ«+³ v8¨ÁZB>V iˆO뜹‹æêÊÅeÈ=ªXyÜ@Ÿæ[ã*©Žÿ]ý£Ò[ÁÏ—„E@¯aþXtOËÅÅeÔ=­äq?(•$\€šr;]¿T|¬¤ë*ž8“¢ú$îƒ^é*·î‡ÄÓòìM­‹ÓUI=ÑSä-� ï*I'ØýÉvºþ6ºã.ºeÔgeiJ¦G#å¿æÒ IŽs.éââÒ 2ë©›%^¼ê6Rõéþäú4Eæò±\\\\Æ^/*†ÚrnVãîWpÁ³¨[‰Û-Ýìv—±WWqb^ìèÄé»_9²º`Wk_ãéz]c¹¸¸¸Œ0ûì»l¥Û™$õ*‰1øZücyáÝFz.‹‹‹>..#ífº­© "·ÛE6Ò#XïÑu ÝU÷ÿ¶Òí[›~×Xc(Þ·ÐÅeÔݬr=ÔýŽYIl§ëï¢[*å´•nßHOŽ ¸ªÿP«e]c-!Ù¶m›#[¶lq÷×'hD=­€Ö×[6 Q]3Nöo·•h<ò]c¹ƒ5,²ÿ~Ÿ Ÿ QTW5­Gô–ÙÉë^tÔêÏ<aý:®±\|Ï+ü›!Ñ>AC>AƒÄ»2h»ÒÇèt¶½óìït?imí¼³úSýk·µîÔ5Ü>ñ\A—1'ïp鑪±øO+†³.Øj¥ÿWûÓm­;«ÿ§L¬Ë5–‹Ë�Ô•·^sé§•ürÒÇ­“,ë©í³L"gAðɾ}ûnÀ 7qðe_ôÈ×*&id&%þanÌ“S#Þ BäR½–þÜ·pÊr{œhÛò†Ù9ïJ[ |Co2‚'ÙJ·x`7Ó½û§;3ªôìÕÆÄÇbº„$·œ·¾Ø ›5'¿€bõ©Aî…?� ®ÇteE ç”åŸfÛ8áì¸t¥Ó9ë¸;%j—®ºªÝh2à¿8p›TWÌ¿åc©ŒÍqåe¯vxì_–; WÊßW<¿r†EƒO8p¾ËOuâ#ƒ/ªœFÆÖmGƒô ©Sÿ!r ÝugGøaì0µZ§(Ñå ùœúi ÝuVf�� �IDAT¤´{q@ŒY <~ÍAAOM¹Ì)9l’:`'¶Ý™»ÿ0Þë§qAr ù]?ì OÑ;[\ßÈz"{Ü7+øD¡[Dgÿ'~­_N׃XÜlx86J«û:]cyPêʆ²V¿b¦¦Au5pce gqsCŸ™²à?ƒ@” tuU¨•“;ú“¤´"*˜üëÛë?¼³s{‡ZÆØýüÎÎí-¢­Û»šfkçöî¿·vn'j=§ÀÿÕý-Fuµúç©ãXf„Äe8}—f½«ñ3VƦ饫+ƒ”'R¥ nSü…àÃw¶î¨~øÎÖ-êTŸÔÿ÷ÎÖԢ෵uQ§ûŸ»ZºÆß ÿW×I­¼NêÔ<­!ÑX"€.Ãv²Œ%ا­<hàûÂÕU¹Þý0ÕÞŒ•êêt  õœf­h2ºˆÿýZ*Lè¡ÖpE³Úlé±÷´ª„«*ŠÞÿ÷µzýüÕÌѰùgæ_匌ä5ÝX}Öx‰nחŸ„é0ÙåÒ­ÿÕ™ØóUx`_ܬf*ˆ+¥† GÎÊ®¿]ðïžvÉcÈ6È̯lÀWð«ÁN}¬?¨bˆP]¶ä^cƒpöMr=ˆ‘°VÀ›þÌñ®Ìn/XñVtÿQ’Ü¿cæCÙ~Ä“à¶?¬>Kä¡§‰‚`Æ9ò ̼ˆÅ ¿û æ¨ÿ÷·ISSf»—ãøȮˆª‹]%0BVàv+…»©ê¹ßÞ@Ÿîþ©ëlÕ‹š{Òm¤¥wËîc¹¸¸¸,— tMꘛ!Ï0÷µn¥ð3>VçA²`õI÷7t>uCçSÕ_okÝ)êÔá×X....¨Ë…“É&QÁB}ùÜ–[à%ý$]c¹¸¸¸ŒªÞBT‹ŠB× ½–ÛztŠ/#iwïÕsñF·>A.®ÒÀfŒàeãB±ºc‚UÕcŒmæ…K¡x[<Ÿ F!ùÕw˜/w•Ð-tW7‹Ýæ ºÆZÒ²mÛ6F¶lÙâä4¢Â+dßú¤Ë…h‘ºÛ”CŸ½Ýv6S{ Òª›ŽbÏ×Xn¿RÞ±Þ'hÈ'h8e;]}š9ôŠ <˜LL¿…îÚšÒˆÝÿì¦ÂÇZ*©GGE{¹Æò=?Y\\má4ä4„R9%µQ¡–ó±ê…÷Ð]7Ч«Ò«ä5»ê*ÐRI=Šƒ“ÏtqqqiFp|ÏF­[ýê.º%À·ÓõuJ Þ9KjБa×X....IÒ¡aô3)É XuŽYD Ñ ‡È¨`’×®œÀÍp…¡êHc[ž- ñ«OJ<_øâ—Ê]¨¤ÿd@~*Çx‚–ˆ¿…ô¼7¸\1¸‹6lÌä»óš’Wo#ìc5Þ§±°}ÃÒ”dw¾ú¤ä>ä§Lu)Ç&XM)H|¬â ¥mÒè4l~U|諲Uº0øw—½‰¤êàÛèŽnÃ:cD~;b‹Ù«¹æXñŸr_NRJ3Ïtܬöl@ŸTùø‡ã-}ž |„Å'qKn$”“ÙOjV%$yëw ˆq“¿[Uo/¢µ@KìÓ¡:ŽUæšJ8(Ôÿ‰�‡Ý[~Œ®ª¥daV嶺Ÿ†ÃŠÖ=ÖjムÆ(Ó„"P99ÍĘ#aiö³ÁJ®#WòˆtPh &EŒòÅÀCÐÑ8 *¸V—«Aˆÿ<pªr갫ɺ¿í¦È[®`IïðúþÄ7äðoà�tuå2“‚ß5…ç2ºª‘Øê ü—ë åáÊ€6w„hÝÛ½8#r†?~¾#Ù0¨«¾2¹( ««Ñ÷¢ÆF’}+}ë•\;cJµ-6ûdUbE|£8j•d_Z‹ß¥ ¾?çNlÂ÷îÉc—IR×z±~ôôH•¯OÐ(*0J¥áÖÎç˨«¨ÀÇŠi8ºÅÅñç*]8¶+×±;§·’­èP â{%c'8ÅOÿ¡Ká�Š£ê4ü¢Eöâ,>›v¬çVÄ×ì"~T8Bú)–Ip72Š_`6aÉ-~B‰£ÔÓ[çÄᜠÃêíÛüp\'h¤UÂΞüÂVº}+pY­ 4“ø„Ôè3Œªå΋‹ËØK=|• **çTÎY¹ªrÙ —æRâ†5–c...KMo!Š! Í•¨(!aîkq’ÈÓ55Ÿ+èêÊÅÅeiJƒyê ²Œý!1Å#þ~]o 9W“÷Çê¹,..ú ø¹Œ½¢²U5•øÖV¹~ÚÛN×ӳ߿¤ ×X=o‹çä2Þê*—àÀk£þ¨‡­§{Wºm”+wêºÎ¦N½å«·²mÛ6F¶lÙâä4ÒÂ$8ôçÐOv®RN/Vê*†tûÝ%-ïXï4ä4*Þòyî^ÿÿJ UÌÈCŽPÛ×X¾ç#‹‹‹C¢-|‚†|‚†VQåÔR\+„Dã6ºãºkë³ÿ཮z–àªÇrqqqcžÓ<Ç^X§¸½‹n©¼®êûUr`%8üDîc¹¸¸¸4ïõYwÖ)Ø“D·”ÊÂ9®&YcyQ02&½¥ ÇRîØp$þœi\"^¹”Ox߀ 2žµ1ž 1VN}ÓÝÜ í}q…:œé‚Ž Ž’‚Û4'Û˜‰Qðëo衚 f|’ÊõÓò Nì |”érÈ-tÁmM†0ÿ¢­Ý–u¦ð¸éb@%^ÿ0ØÃÉoŽŠÇA¯íw“È÷Œ‡a‚˜Y Zt:ŒáR¨2+�PT¢õîÃbRûÈûXÝV*£/Ða£n ¤­ƒí^Þ¢ÿΖí·ÞË¥\pLj©[L¸¼+0~eŸ›²ã§aðÍ¥‰õ_OãmKã^<u<Е–‹VEœñªȈ2™ìŦíÅ—‡Ö NžACe¼/Y©<ûaVW..…‚d Å[#!“=Ú´ˆ6é­÷üíušŸt#±´†ZõŸ>¿..¢´û¼«“Ÿœ³œPCæ¨ÀC úïö ÌLù¹”‹J6ÙfšÁ†ãXÃÿ#þ¦[—¸*ªçñ1¿™üþ¡Kr‚lÇ'È¥)Éñ0UÿØN×׉“Í‹‡­*kÜNÁêWý;¹mFz/åΔ¾ÝN;°â‡…—¡™êó]À?-Ù ré…k³ ”¸Ýt3Ýo¡»¨Æ—!ª½ññ±Ùpqqq¸ºÚN×ÇZ'YƒUé­Q‘žk,‡)\\\\ú#uç‰ù w¬Aj,ÊP¹¸¸¸¸ôÂÍŠÿ“糡4wçnï¹,..ú ø¹¸ôZQ%[[ y¿+×XC'ÞÏ'ÈÅ¥ÏzKüÐ5–KB¶mÛæƒÀÈ–-[|‚|‚\Ê¥›pqøp[¸Ærû}eàë}‚†|‚\pïê†1ÒL®±|Ï—,..‰¶ð ò r}¬¥ðšÞÑÑÅÅÅÅÅ5–‹‹‹‹‹Ks"£‚1cE?˪š­;ε*é)䇨þÊAÇ,äÃá|©¾-˜^¿ 3Ú#:q..Cácõ¿ ¸ôNûΖQŸ<qˆø®Ðâ‡?ÍÇ•ßKí8—ÁûXÌ~ þQ·òºdíõÞ?q Þ6ìõÌuóby©~ÊRÁ«ÅKŽÿÜ—%íc‰†plåuÏ÷úY?<¶a¬®ÀÇã_Ê¥A+þÏzóšX]iý—±õ±’ÎĈڭÎÉ;ÒŽWòsWH..®±¸Ã¢þ‰ù¼ðƒÆ¥§ Ø‹ËRÔX Ëbë¾ê–Knv p|¢]\ÆI†¢«o]—ˆºZj]4Å—•ñö§..=÷±ºQ„zÙuÁ7û_ãÅ?É�¯AÁ_mß·zædk˜ßH|¶ñž¸‘XZ>£ª±øVü þWdY4»t˜Ð½öŇ'E;ª‡ê]JÛHœ‰£;qc&Þ2mœ},—ˆ‡$]z$NìËÅ¥y7Å1—feË–-ÎåïËÅ¥WJËÁÅÅ5–Kc☸O‹‹‹k¬ÑÇÄ}‚\\\\c »8&îäââÒ xGG—Ñô±æçç}P\\\\\F@cmÛ¶ÍÅÅÅÅÅehdMVcmٲŇÇÅÅÅÅed~~þmïù`VcÑà€Án |`Éáy’Q|¼Ü$‰¼k ùXÄ„ú¦X Ï<l'FM‚ßëµ,..VîÝ`Ó·†çIFññøî³???_ ÑÐŽÕHL¨oŠ¥ðÌÃöHõç©Äs]\\\\FC\c¹¸¸¸¸¸Ærqqqqqqåââââ²ÔÄÎÒ”ìäKC@§]ï†\=O?Ÿm¨ú6P3Žä¸y¬±\–#7³¾m£Ñø¸MŽñü êñüPËÁtYÊâëp„}¬Êl_XXȹVu¬ñÉN^<~ŒÀÙª¸Gú€ñíêšóü×.¹iЇ¥þ õσ÷afãÍ=v³·Ž~™i­+_5MƒÚžøóôhº‘] ®º¾=-³’ÿìVåïØÔYâXÕÍrw­ž)ÍǨ~ñäúø×.N/ÆÁ6Mu5–|¶îù[?‹“ãÜ»7ª¬ŠäÅù¿–ŒUõRÈ2S ZV>>MÜžÚçéÑ–áw˜ðO;nó^lUäŽåC4n™ýÔIÉÙRýj ðݾšŒÜ öô™GD Î…xfsÈT–?FÞ¹¬ö¾=sÕ‰Á^?lËc²×[k/>Æšô·Æxð‡Ùâ1Ÿ\ˆfçh$&±§:`¼×³jµŒÐq79¢›HN–.tÀ¯‰á<s ø¨ëcoUh”E&×S –ÂP «e´³Ý‡ƒ wgA|ñ¡5-ë<F4£¯G3; <NÃŒôy{ŽÖzž‡ÇOŒê-úï]!S_>¤ížŽo/†,yñúŒŠSÞ‹—M^vP޹vqO«o4@¾ð¬ˆËl Oˆ??¹ÜžÉ;pT ‡Énê!Y«ÈËw÷dÉÃÿN~Ø7Ç3~ŒäÆèÃó ãП±âïbûkž¶ÿ«‹_Qü‡ý(ÛsòÏ<¨‡È‚7jj³ d/ð`A¬ð©œ¥ÉÅÅÅEF´\†A\c¹¸¸¸„NÀp‚ù.“>....±ÒrÂ!uËÅÅÅÅe4Ä5–‹‹‹‹ËhH\\\à3 öîÃù$£øx±ÌÏÏûXùCúÿ3í0¶®½ñ­o¾õ?yàÈÁ}WÏïݲe‹«q—!1sßöžέZØýÈŽ÷Ýí¨ ‹‹‹‹ËhÈdR§5réýû÷S€ ]¶©EP¢ëXáŽîbð'÷×ñ×iêu•üžV+€±üj½¾l³6ZÈêüü|5’C5¤£»üÉýuüuš}Jtqqqq qåâââââËÅÅÅÅÅÅ5–‹‹‹‹ËR“±å4°X„ÍõÆBb%/e~Nñ'#úäq'§óGÞÇܼÎG÷u’O>f¯S¸MÜÇ ‡¯’‘~—m—PŸNöŒÝãcÞçu>Ò¯?ù˜½Nù6O«¦+óýj¬ãëôÔÿ3XX|S×¾y®Í>y?}<^?£õä£8æâ:oöM²øG}G$R²M†ÂÇjÜ'׊vŠØ¶¸YuÅ* «ÿPßž¼ÙWó1gž¼Gí FwÌû:¹‰ðÙgk˜Å<µ=]ÁCõä¿Zž¼YG¼oO^ÿS÷¸lä-»Î«Sµ©éÛë$'bDwDr" ؤmP£!ýᱤ\†ÁáÅeÐ uåRx"7¨€}G42åÓÑÖÞ¾ÙÄ„ú¥F=ßaPKaœž|È7'?æ ÏJlùjY‚OÞÈëŒôŽèÅ6ÿ\Á¦ÖúÀ¯Gûú¼™ýÉ™'¹ÆAóQ<Fð×égŠï f§|› …Æê…wUc=`h0Xê×iêÁøÄ§ú_Å'ïçfîÛ“/ÔÄǼ×Oޣ̋Aùè¾ó«QÜ=šˆq쨑8^Ì—Þæî¦·‚׋8m¯Ÿ¼w™ ýóߢŸOÞì°|îëŒÙŽèÅ6ñ b—Ñ×X.....®±\\\\\\\c¹¸¸¸¸¸ÆrqqqqqFIç ...6xf¯ÖëË–Ëüüüˆ®†¡Rrr¥ü:•´®½ñ­o¾õ?yàÈÁ}WÏïݲe‹«q—!q�ÞöžέZØýÈŽ÷Ý=96þ‹‹‹‹ËxK¨±¶mÛæƒâââââ24²æ¹^{ã[ß÷'ÿýŸÝñ‘[ßý­[·v?ÜN×ÑmtGî·ÑÁ_ëŸ0?Ì}¡{Çà ñ]‚ŸÇe~ÿŠyñ‚âCŠoÍÿ¼&8ñë׿`{…øßâÈ'y‹`yw1,3p©€SŸ|~ˆrOÕ}Áít½ö뿇BuñܜƷ‹gªd^ˆhm`ÖÿüñÂŽ'(wÚ ×̽&r‘úä¡~e|i‰wç'"÷ú‡ìf#ƒÿ©ÓéÜúîü³;>òS·m½öÆ·¦5VõíúbÎxÔ3KÜÛªqçBð¨åÏMÃçÉÿ¬¤ZŒþÀOUd_Õ¯¼;x¾óÊ.ÚP_èâX!G'¸ÄÅýƒëZ| ]"ÞФHvݹŸ7Y@ÃKe%Uˆ¸ÌÀ²zµ«ÁÚm#|êÅñ_!>ÊíÂä&å¢ú_eÅ«ëœfMxPÿ%w hAˆšxx@ë¼B¼÷bË<îsNoÑ‹ZÜöˆMP¿c Æ/ÎX¾à£>§ÂE%Q?ÚÛ1vOnî‚£ ðÐÉ­ŸÜ«ÛO¹ù \@3–,f…ŒdU$mƒƒ’³Ü…9Dó.�ºÿè.×ø‘pÑàÈ3Geü!£5ªï@>Vü@Ìbeæ;ùˆÂ°¡ÈšãÝ›-#bnâ9¢5ês '¢ªã¿vfd|�± µþ¨êPf)Æ µ–)3S±bflæ@´ùj¢¾ )ðp<G5wüí´Š¼Ä¥VAͪ½ÆÄºÿõAò ø®1M¸5Ã,κcÃ3Ë;Ø&üÑ­ÓXÉ\('Ap$È”qqY¢G Ìmƒ˜Å½®ï:…âðâP2þ§äxšCh| Š:T#+$·£´WNš/ÉÈGü¾¼Õ%â™ünâñóÀjÃ'ÚÓ£P² ’˜ªlšñÕ¤€Ûˆ£ÆÌ]ìvz¼žAµÍ\SÐXŒ)îÑÔ þ§U'¼ÂGqÄd Ü.c†›Ç ?½ð ¦L’BŒÿàjÀ8æsÆtˆX›*Mbe ÊÇ«°TÃਊ‹ .A_Ù²¬.ü}Áà‚hr‰†êh®+dÍóGMÖɘQë!p{ªâdªÉ"k”´+y &Áœž³\p°.ȧʭ€$ªËL z3õHŽb}Ë!IfÍ—C–Uã#Ž9ï€�ä�â‚*´É좜d³Xy4Éœ\j”´k)Hl# øšC0€@ˆ‹–ür Woã!öêr®›x~j“\ÀÌUæ Œ“„$“ÛÔaýWê8–ÅEÎÕEx`Z =Âo¹°üÄU¸˜Û!Ʀjù‚3¾µ@ç _ÐøÙÊ›YbdQ•Â*¦Û¨fe‚iý¢cÍÌ—¸yÉ©1Ã$Õ¤9ð†6ü#øU}¥åLmdØsY]âq "™¢¹¦Â$K¬gÆ]îþÍ´) ՛Ŀg.¨�&käÀ.-±æäš«žP‹ekg7—{jðÌ”ÛWæø™rµ' -jR¡A®\îÐ'O@ÿñQœ ±Àíàœ¡V϶a•LNÿ ±É…ä?7’¦dX–ÌD0Ф ULÔÓ¹¢õX¼U½ŸRÉ/Ú ?â®âà>nxâà;>hÚ³7îÀs„‰‹F ä|þ·f£‡”¡éÂ)(Ù„ >!žs›¬IÈÅVmh›ùyrQe©11‚žs.™ÈELù]€�Ú B:14h8ÇTË#E=VS�4²’´7BŽòä¸rgñG­#Ô¹!YdFÖÊð䉃³Qà¦7?tH¦¯Íe ’ÜA-ð„%•‚¡|¬«¤$¹p[!nw2ðœ3ûĬ3‰Žv¨¦L5¼ñ­EÀ@@>Æ“ÄB=fÀAm1²XÁ{#8>'ž?êÌ $dÒá´Éu€¤À©bb¼á6º#(Tâ·.Ÿ…ˆ$çÖ ³—÷‹ØxnÍþ>¸ Kþ“YBÚ©Àd3¦�c}3¿5ø^¸m‹ŸYHY(ˆ4ÚèèÌV±Gʤ_>�žþ|zp£dE¹*Œg®�Õ9PôÒJ|n…E@j;bèáÊà¢zÛdrDUÊë'3ù¨¤›2Ï ® oÊ«Ö~-™üÂ?*mê±q" Õ±›+Çá_™q=ÅìMÕþÅ¡$‚iÒ@[¯¥!,»¹ŸÀl®cËL^âGUµärẜá“.2ëÙP“ÔÙñOÅØ_úD@|•€¼£œb0TÉÅê ÕŠl¢A Ç ;IŸ/PMnÑêÈr•Æ,• {ñÔcßT´r–CI…O\®‚ ´l±ÞÀxxUÆN™Ä-$I˜j”¾ñ9Ëlj•FQaËø]„3—Š-à§µ™*à8’§5⯖;(ÄsÛ`#*PAq—Àh!Ðt3Á'؈·SÍ.CøÔ»(ˆd`@EÜß_$ÚUgËì§FÅpªÚ0™œIÊ;Ü%é0¶ACâ:x–"DŒEsœ×Ùª«â™³Q‡ðC‡êKL+ž%€Tœ|ˆ;çT‚›\µÂl*Á|©ô._uA02è{Ù lmàd/°>œ–ž±I„W™áÉb»r½س†S•çäLºHŒYõðZ«Yœ¹þÛ$Ûuò›ÉÝ'–‚Ù@0pñƒ´ÑZ4µpûk‹ˆ7?[Ó¤”ó¢~û˜€ 0ؼŸO0“q$º…Vv.¢ R~å–ØòJµ÷Ä8¿¡òLÏ)´Zš²£ãÞdi ˜ð³´ˆ0—6M WÛÎO„V“%A§ä-‚“!¾‘Ø Ççù¼¤z¢ÁÕ�C!pφ€´ö l*ˆwPÎŽ¬/”»]˲•s&r¿³žpê-Þ(ž;MMd9—’˜dˆ§iMlÑaçí�Ñ4-˜B½‹Ôžk½Õî{1Ùž¢Ï¡õ˜Uô¸ôú ÚÔDÐlE¶6^°‘¬JT1‡ÅjØæ‰ÚÜz²ò`[‘]¢ gŠKÈÆƒƒ jTÐìl&§™?ÑzÁžZ@|!ˆ¡+ E�¼ '^ßábž:SFJ“ÞG§&ožÌ­Aô Iî()h‰}Åô}›1T_HüÙÄKrø˜jrùv½f€º¤ò©<b”¦vXTð9_œ¤â_•í"žŠ¢ŠÐÍ0'B™Vÿ“±£#×%ZßÔ+n<AäWˆË¨¥$iaàG/¨6GîžL )lOšd\—œ³�3ãƒ'ø"M5Nãç¯8|Gð^ Óñ$xræ´µÀ¶£i2§íè(.{[’aSF›è j™òµ6+ò^¼æ‰øÙº—UûX|”¨mý@ó3ÖmȈ'ëDˆC$wá}#Ð#ÎRŒfUùp*öE‚“ôTîNð$*&<W±\“T0„0;€TÎ%Y ½~èÈÆÓGÄî(_‚šüÏûÜßmÞ‘ëE™Ó‹ª‚Qœå–?T¦¤*›ÌÖ£§A°=@Ò‡ê±Ä_้Œ—–MLÁb�ërÆ?©Ø3—ï3­B µFœXùŸü-BÜb0Ãñ-{¯d ßlo‹…ä€hã¯ÉWà+½ÃÑ o|Âê2UÁð-ŸÜbH¬ <²9ÙžIå|ƒ ùðŽÀ…œ�…d]u»×» &\ƒK„ëgÍW…÷ #OÒôõ;æ¨ñó·}æ·´™S#·Ç& ª*Ù1q Yæðp¸¶UIbè•©jaÂꟴe”*-Ò`xUßK±l‹²´É™å1K&t’‹Åˆ4iIƒLEQXäª�¾Ç^ý r=Ž™–·«Áó/êo“¶Ù\1•›¥-Óá=Ô’µ‚ÞD|É–à®jd ž;íˆ;d6±wq ­Cl¨‰ÆC˜¶®(Uæ$Oe;"y´_›  :¯Á žTZ€×ØûKÄÌg5=0ñ=fÆ5àc™Mo^Áýo¨8Ë< þD¬T-6eCÛpË ÙK,˜~fHh¦æJ,‘)ÀKÔ™Ái„¤nM3ù¾ qªÙGÁ‡Z…kñV’�­Ý&¹°ßcI¹:4i}kówø¥RNch¾€PùåàíìÜíZÖ)ƒ/‰N5âÒ‚Ç·jŒM­ÀíHæPàMZûãÈkk�ªÜ0Ä=*¯5©žDêOq¥¹© ŸõË—A’Î"rŽ7;k†& æ¢o*À‘É:ƒ"e‚‹I."”kÄÉ1mãA¹¹ßÔ+ä°1qYê::‚Ç×jít[E„Ú´ oxçªzÞ’Ÿƒ?bÖxaffÎ2Br¢J¬<Ðj‹mm›Ï¤¢~7 §€™óÉ|ñ)òM™Gªv âl2<LH‚;XŠ“›w]4­uXŸÀÀncbx^Ë.†ó? ¹x‹”ªdœ]ɘ‡„ñÅ fxÃyÿ^[ü~Ð6ŽŠˆs½ÛŠšÍÚnC¹Ò1Ü/Ìá»`ç˜úTµ<Z(úvHu‰:!,Ú:1H¢Sãû\fòR•»ÃÚ°äææÆé�� �IDATE…›+ÄyМ»˜Ä¢Øòѵpbò­@¼›¤iÚÝæ2à“Mlþk®}€Ø®h»¶ö®N4WcÓ¬ »Gù‘ vl1ðp‚}C*ÎH<ג͘½œÔÄ ú‡ ;øa jzhÜ9–E昊³ë]gùsÆÆ^ˆµäˆÞã)˜_uKl€‹!‰¸A’øœiÛßJåTÄ råO@sƒ [“=ÄÛ3[ÈaFüÁ¶åà¡ÏX£ø–æÇ$¡a‚L¤O—oª†Aë§jb©om‹ÍÐé&YE'‚@<bQÞàƒ'HãON[V$ø+ÐÓš¤øž£q–Ì <…,Ù<éˆÈ(3×REë‰Ì“j|‘ŽP¢Vc¬à’¾*<ɶîYÚЖ!G*ß G{ðÅ6oI3ÀàÁTŒ…<Æ(ºÝ͆UDàÔá‡ÚÌe,…LÇç�ö`Òy£¡QÑãøD9ïiéÀà)„‚ߢ¨ êQTÇ™*×Ðá)™¶g«Q…ä«RóU°gn÷ÈÀEfpêµÜ]Úvõƒž92ê_h¤‚‡×¹ƒ8Ç~Ýl—¶¯©ˆ”àØ¦-w9ÙpD„)ÏãN¼ãK¿LÒjª1îï6¥¶Aƒ†”%‰f0@{¤C>3p<b!3éÙ4´Å7Z戸—A² §ªg j)ãµëåvF| Üµh †‚æ$¤Õˆ!A9éÌ%6KÀãI rƒü³*/¬Ç/o9ˆ˜}9C[x†q KˆS›ù>Òý\•ƒ  Êx/I ­®¦fÂåÉâʵ´E1„µ[×ÀqPR-¨ÉÜ7ãOø {ÐêáyÖ+A¤Kâ™÷eT¦4E@â+ª¸…X;/žDŒ2ƒh!“…+¦åô1ÃDÅëÐGDòÔpÕFâ£*ùÏù:xr‡Á$C3†ÃXê58&DŽWƒÓ£Ey¼H[r‹?ƒˆ;ñ0½¶ñŽA‹Ä¬[ SyÍ ø‡ŒÇ„ÑŽ*°šAÿøÓlbKl1@…µVÚþ2 V©¸YÆr<j-†�º‹-öÛ’-T%´`(WDù@œ /’­ fŽry.ø:„ê±pˆß!D½ñY!,>$Rgò‹Ä|Ti–x|;7ªj-¤Á£¸ÿA·†¹,^ÆG,©Š*¹êIƬ¼¤ 1¼ê«Ú¬UÉ;¢­iæ¨OóB}ßDoH;b¾\êyT³ñÌx«lP£¥êšjÛN6DµÈJy‡¯Eé6Ô?æ|‚\Ïž\ƒX»Jù8e²è- ã¨X' ø¸ ÀzïAžôˆ?[SÀÀy$ßó<ÖI›Š™liþeÁò2$¤:û@Ó¤· 4¬“=- „¿"˜š„`bqR–Lð=‘U°m<t¹šKu=~âãUî K!Úø üˆwµ`ÒäJ4fµM¹Æ-¯‡Åí�•÷‰ -äKì’ìÔIA„Xæf¸uE…„HJ¡ÆsLTǸ±’´·¥’<¯rÎTÄÄ6oð`Œ‡‘|jŠ\«{­cppÕËÀ*͘ u¶YüÉ`V lè#€;U…(Dnˆ'Úó hóx *º­ [¨J©øÖl£ žÑ*ü¼°i*ã§2-yž¦f´Š?ÄÃÊJÞ´~î'ÿlZÐLøR¥˜šÙã'á=HÿïþVÇÂOy•ïi X³ËJö@9é ®Vs@ÿ¹HI…w¹DÀts»™f38D\šo#$ö¸£26¼×'à‹Ê›âäÍ•Ço%\ýƒÚÏ0LjÙFº áðC9Α<S‰¯>2�Í6êäû$Y¾œÝnËÔTA^APWéd*¥×3ÙÄ)Çt :—A,Ü*¶ Q`a–¨m^Z8^/Vœ¨Ló6¨Ôîm-­”è›2DŸÀƒRõÓ †—™¾8A{ò¸dNO‘|€é.KùÀ¤ØeT•ÿÜTB<cØ©¶’¸åsñ*Q)*º4žî¬-·Öâû9Šwg·­à•ã ³Q§–rB&"%ÒgÍúž0†1±¿Qƒœˆ[©¢Le2•Å:§Bºda‹øLnáá5~ÅDl+™¡iÄÜÌ»ˆ‘”ÓpZO=yÁ¥Þ ’Ùé )€‡ßrƒ Ö‡)r™×­-10Û– Vü™söHJ¼VKˆ–Ö‹†]ÐZ^">Cl×�~0IqÈT‚Éo¹_iŒÄñ4S-”ç çp°\ˆ‘™šîé\gÓ°aGxUC.'‚R„¥$¥ä´»¡ñŠ·À *Yæus2n­zw3$XØ©y·Tî7&Ƙ<éTŠÊ€&7nÅçÞ|x‘³®Ø›?ÅÌN¢ âÂ,gãè¡…ÖžS`¨UÄÍ*¥¥]Ò|z·¹ÿœÈò Z{ ÆàÓª]àS¦zÁÌ*/SüòR6‹®6™¥1r « ŸŸ.,Uð¶3£ƒÝp^}Òd~k‘ C pf`ÏðÖ6Ë×r-†Í}zpÆB•ÍÄÇÀâÖ£ˆ9ÜE¬¦`Œ?íem£]nöñnIg;€" ÝàÐ`|þئ&QÃÐFRXèOô¥rŸ¨{'ÏPðG-¹*èHâåA¸bV¹& ‡›aehò“ˤˆ-߇àõÍAUVn\SaË÷IîˆíPæ¯Uãï·2yBR9আ™Ûœ#&\¤ò§qÍʃŠÖg²Ô ·ÔyðF‹]©¶¹ÈŸW7FÅV,Ì7¨`SΣ˜gˆ›-xE½ª]’% ‘¡°=eqñ!]”rÊ’ êR><“bàxº%ëÀôN‘yNfU$¯ÃXÊ|ɪ¶¼W5 ßŒg•ã.f_Y*Oõj`Çó¦B ÚŸ˜ë[r+ŠïòƒZÁÂÒTîRØÌ(Õ]š*'j¤)SºñW(iyPâ¨:HÈ¡ÊìàM]Cž˜â'i"?8A-B5$àF^1)6Sç;É1 q@Zbi®LÞŒ•’²VG„æ¬.œŽY \isâã×4f^ˆÀnœ–†¨›ÛKš +Rš® /•[CÉ·àbì[i\šÇpS, =Jý; %Gîɵ“6Ä»cPb‘qŽqÙ‘„X|úÄÄz[ ‹Ç¯r„^ oWbAÚÊ4› ú–·óPqœƒ }fÝ&õ\²È]Uiän/œ§¤Adëà vÈ-qÏù¶2�U�`SýIñÛ‰GsŽ0Æp4$Ñ?R“ÆÌÜa�Um-3h3ñÚZ‹ˆð&Îà!0΄§Å#Ðkl¬àÝ!xõ¦b'Ðmç�vUañ Šï’´íÀsim É î:Í'˜“Œ˜ñ± ‚8ÁZÈ^pbw`Ќբ7 Hp?{ñ0REpÓƒçZ-É€G€MÞG°AUQNr-•€*¹—B(!bþ¾) x26Kg¬:ÂTV“–sˆU€•¶ ž6Gø·T¡¯ÂÎ|T#)-�и бrü Œ¦1ôÖ1ÀáL@ÆŠ7!ï‡à‘‹\ %}¯scŠtËU)9«?oGãZå§aî´ÂékUa82t†mª|<¾“G-ŸÆbpúE‡£ŽLð-QxSì~Ép€½<z|°Ÿƒ:×F´ù/†^ÀbýHÝ M˜1íÑÍdTjâ¼0€xd"ÌFâÀ‘ÅO(Ä´QUòFb—R]ðV!®àù½Ä(ìú|ÕÍЍ‚æR í(ñ‹JK$“Ücæ©Äû i“›«ÙÆn§õùJ¼ÐÀÏUt¨®ÉÄäb[¤ Z6Õª®óŒàkX›¿®U–"¬‚D ©öEœ*½e�ñTq…äÞNº†àò*ïÍXÂ%ÿ2¡lÃi…ãà8ˆI€I¾äLÏer_®gâ6…Â?å¸V.?å“f‡êá‘…šËÌ‹£U±¤#ƒ åz¿!Ñz„â2‘~ó à•×)åz "±^æ?Q ¡¸W¡Ì ɱxp›í¾’¯%í‹Üdó™p}Où†Lqˆ¥¤LÍœ2n�l™m½%‡ÿ[tŘã)0“mÝ{ãÛåÊÑ@êRm(¢œæŠ2¤”%1¹MQWÝW¡Ðå2sò XÞ|w¬K,Tf×ì8$«…yH›ÝìÆþj{¤£Íd�ñq1Ž‚§räøÀë~DÚ·\N<Þ>‡­D/W5,GŠ7 fM9äÕ Ô˜“tžˆ¥Ê=¶n”R)g¶+Ü1B}3q­­{½xpkÁ±îD ÕåI¾·\ë)0(ÅÀ9H!-€Ù�¯ h„"I)Z0MÄU‘XÃCƒ7¶7CÆT»eóAÍ‘[ 9|¤gû\¨²öq°¤^5xÌâçÓŽI_(¦†ªºÀh9Ÿ2^ÒÊR¥®ÀߪX4mmÝhŽGÍ”ðÉ\ÙrÐO[­h›;þ' ÓiÔXÚ샜mèhÎ[I%”çL,D<Až¾àºÝ\ Sµ¦Á"©ãcÔ¥ä¸1kbínI‚xËLÛG I §Ï=ÿ¾`/óä¢EöV}Éu›»B Ó„x‚ï…´ìÉ)*~Öâ‰7ÒÆ¾Ì'͉äyO˜þœLÒ“‚ W•šœB-vΠCŠBlÇP20�§|A šäÅq¯(·’pœÅ8Æ‹bEÒ€fØ´ÉÆB†À8Hæjó¡‘#L à4æ7T‚#á–ÜQhŽ ©¢¹(@nïh!V$û#“øÅ»diû‘â…nÉ ;?)ê bR¯ou¼‡©vAˆF¥Íd` mí0ÿŸL×WªÕîàw±P¿‹‰ˆ°[ÒñͥŃux%ÀØ^|_mìA´~Íenƒ¶‹Ì"$hKÄ eò°J—ˆ�8®{´ 5�'À{Ï%£‰ƒ`Æ´™ÕÄ&Äa(Z-Íp·ƒBÕˆÓVŒÆƒ„Ú¸š¼Àæê§ c11þ\’ðŸ$:HÑrB3¶u´ÅE̬bå™–,Ž€¤ 0¸×H%8WÖ#Úõ´9ºˆ+fÙ¢Ew3ù>_À–XPëŠV]yÍ;;kÍV[ (Æ`lxâ[7V29Š­1Ì(*X€à›¡wrn".—ЧªDy#>+Ž€ñðzLÓŬÜÅãI9ÿ�×| ~ÅŸD¼Á›£Öf@’Œ†ñb„ŠÉEVBÚ,L‰,'çDj$a­Í0"2 Æö’âO''.X*ýJS'­ákéIü:²ÆÂÓ¸ñ~q½4Nã‘›9œµHeœ–w_åÓ%ª¡`LàdXÅð$æ6,J- Ñ”.álÕ•ƒª;$ Ã\aÛÛP¾æÚœâˆ¸ÌÓ¼$¯Å‘¡˜®š$esÉ,%ÏFDÙ—l¨’¥¥<ÉVÄì_‹…:€ˈåšT*˜U,O!‰(9²u^dñ‰ ÝRYj9M‰ÛhV\‡i ÂdI5bùò³l0öEO.÷²†;Æ©2X*æÑãù;ð {pOÅ´„®Q˜jÞÏY%l ¼QËd‘¾[cSɺIË,W­[²õrš+h.Æ4TѺŸ ²Ôr3ñÐg9ñ¯DúpFý4Rû¥µ “Y¹¢–5”kCM ]Â|_r¼&YkK¶†–Ue*©ÐªÜÙªjpÊó±ÅëiÑd8ßTÍ0KŒ°à}s !^ªÈ<-ÓKS B2؉6K<ù'”ó‚9ymS2‚h1:b®H™M$nmÆ35G(eÐF æ.¦bãM¹ÀIÄáV3Ñ”í;¶Ú²¤Í‘CœbNEqñgŠ¡("y ð ¹ª=G’7Aã ±WÛ¨‘ò#~÷Qa±o5¿ÀÇË1ØžB ØÃ9á¶—Ôv'b¾ð`òޮ؀\Œvàº]ìD¥Â0Ë÷ ÓãaùŒÇKJ€&k�±¸ƒE—ª àh-2Dyb+qÓÚB%&ÎoÉ_<n×ÄgðQÀʱdÞZaÓ8ñàªB>bÒ˜4¨"|ñCð5qÞÂ\ô_9¦7Drxä &ŒmÅ`×ô‚téh`ðA&“UäŒÇŠonÔ”ïˆÔÏ!$c¼5cha#’çUr³±f%ƒ¾IÌ€éQ&OâÀO7|l+2=ÊWz$Ù"@õoäêFT:@¬ßBzý”l½œî{¨24†Ó;žµ¤ÓlaiÒf!‹ÞU!†n8˜úVÃÕ˜DdIÏ}ÈŒª¡8†9Ùñ*c\Íà`Žž\Q NÄ~µ‘=I¦ÅÕ6þ``ñfü$u(2¶i´Q7>v¨Äx‘ˆ)0Ä×ó(42ûZGÄiÀ~Œ*£YU^Í¿ˆF¤¾ü) &ÒXId?‡Ã€ÉÄL:Yaç7&ÑHUóÄO‰Èy Fh´‹Ñ|†í ' ^1uZ,„!¢§ŒÍkl<ó7«sU86ªì g ­14Õ$8¾ÅøÙÉB~1Õ„ÚXK<>ñ±À#F`ñ_u‡*{·æµzKË}Z]+gàÙYÚö²Ì¯ÚÞÉ㾤!Eýj`) î°Ö» äÔ€X±V†&}†­…T†3ès3Ìlª”TCø…¸E™Ööbf$ž¤\õa’ýK„ÈÀî‹ZÈ‘9£“Mµ*„ñÌÌöÞÉÚ@A  À#Tœ†¶Ë¢®ÂK ÄT¼Xr©‰Ê ü4áÙãè:¾‚]f†.pAPA>z! ж1ýð~ŽSQªS‰ª)­AQ!À¬¸½Å]mÓ̉`†s� *<Cl—ËB§YŒ ‹„#àñ eò� ix2© ­&8 s™GqólÉs¸÷µM¢¿™/+z3‰ËæF‹Œ$Î%ÓƒNäÃNV5V„8òqؼ„ïK•ëhèþ©BÉÅ\óBJIUU½ü^d°Å SÄf`Éo â}ðø†ª¶5$µÌ Þ~,7È*®’4„œ7‰‡KU&ƒä#®­J‚[ =òÉÒ<?˜Ø¨]lSB*–&0 @åfj›@’¾Žª¼4GÛ…”¼ ææØY¸Gڪ؉Ö7bÚ.à}â™<¿Gä&C %#Ÿ;§Àê‘1 öÁµÕýªä~� me’„™%„ˆ©øƒT•˶èªIA»Tƒ¦ÐX`Š\òE!£9¾±U¨)³ ÙêDÝ£ý•Ê\0�}�VªdâòÝÎ7b™¸ÒÊÓLÁ€XÕg@Ìl{J¤20ÅimVäa˜'LÖSúƒÄéÝq•X΄*g6eàÜpa •{¤=¯’ÃËä^)úcåz¦1àÁa$J2´®7tÄ@,‘/Ó )m†0Ò¯¤p áàa‹Ëyu<«t°ÆpŒÚo¤¹ƒª¯4¯À´õU ‰p ]RÓŠ£è ·d£áV}™/k³5|à:œSD€™äI¾Ï5ƒa˜»±h={&#ÚÂ+¨eÆ´¥äá¨.ŽŒÛÀ°±™TZ$5ŸO-Ñâ$ˆ]cˆ`3ÚÑpâf oÛŠÇJæÙóxuŽÎN¥Bb¬B[I¦2iqÒ œÆŒ�2°:‚Z)~fZ Ž ‚Xöˆ7„Ùò†ýËÛ‚%x#>ƒ¥8|Þvî˜a±d·ÛÔ€¶Q[áì‚1•`yá卸h¨ˆ¼pTÕ›o9# |Ý7˜ü3ë4²ÏA(ØÐg€/9@œ*¾{€ˆ["í@"4Ê$p"VfIùTÓ6•Kqmñ'¼}Œuª4˜”ת©±Üœ£†7FòˆV ‚Z½e[‚åÔé [Àç/”<¹Ø—ÏpþІ•¶²½²jùwgÈAlqAå8O©…V@KEõÊ Ëž¬ºeÖ“‹ÈÓin§ë“Õë ìƒ8¾"ÿ/iâ[ÈÝÍDõ†U‘;%@Ï,øÐ²äÄ8D—%6—Œ—Û)c—ŠÉ’ùñü™#Z† ‹…¥IeùjQ~Gæ½–Fsp Vg“ÈÀG’â6tH%s%>A¹à*o!Õ D¬Rê6ž3B�žæxƱÁ×$dÇ)ìèänâÇ-YØkîÀbî2ÛzªD5ðèÌ ^m«ËÙO`ÿnþ²8ºˆT©«^Iɘ¥££á¬Ñ:+|â\2D$Ö 2ƒÎó>ˆCg¦±d!1;Ùй€1… ÉDlmÒÄÉRÕÃ#-¾»8Ά~ʤ/’’%±' ¤8$eáùÀÈèáà63\`)7˜}ÃÃõñ;Ú*Ͱ ‹‘«ô"¬ÈÌÇEõ;Í®±xƒ·Áލà`Ùªxªw+ÀM•NZž(L¦P¢¶‰è‚'E gkGË÷\ÆÛ(€(JlK•W¹ªhš aë/y •ŸR0à‹!9)ZT Ù‚8¨¨"âß DxNgñÄàë:À”òä-J}¬’:Ä’:SqWˆ¶›¶µ<Ol<'hZÚp<Q‹›ûRòh^ ’‰¯%U• â@LHH0õT‰.â6¼>P ß‚Ò\cg TO».'û7ÃH%±üXsðqAæìq)<Ù�‚|¤ŸüÍn× `Rr!iE]À¦œÌs"I}ZÆô8ÁÓJæîˆ {ÌÕ’]ì Ñ‚DUUl0Å0e8™ä{[sm@1w/„Ò[,ÈU‰Š&ŸÞ†£FÈPçp6äD•YC‰Ù˜f÷Šl¯�’µò ‡[MC(Á¢±@s¬¼Ï‚áeÊ™ ¯€Tó'úã©Z‘$=d¬Dið<T98ßU#Ô81 ½”›Õ"­ª¿¥h»0™Ê6ï*·DÅ:N¼öï—Ì©cè§KêëãfI%-¬ä í«¢�xäIEoC×ðóYÐXuÛ\FNî:>W¶ɵǟRàKášµø’c8j"sóÏÄärÚÚÜ “�d c‚¸xÝâyÉ*Ü2^õãÌPêËtamÄ.QKðn6´*âyÄ›éPCmÕT ¨ÌMãAІš(CJŽCÌÌ<vfh”ßD9mZäc• gb›i µ€ñüîL®~÷€  A Ee/‹ÙÚ` $Âÿð§¡�”WûÙ&BUIª*·ài<ÅŽˆ¤!¼h„²A5¸ÃaT˜¬H>Ý�<(´qÑ+O˜rÉ�FNÂûªÊßFöŽ*ÏPÇbèg‚ƒ¬‘— |ð\»m73¾žßYµ1‡ªºÂà2‚©oñb#Ð0¤ið‹ÛÜÜY‡¦ìÇ$ÞR?ðì!æ ‘²kVdæ·æÎ_( «à°!X}%šP`¦xS°ßÀà@ý$Éúw’n_³üÔÄn*q_(8/V\[‚pªX±ñø'Ø0^ Ü)Ñb5åÕ{•øx•;ØUa€¸—�>€Êñ•̇£ fG®ÿzòhÈå ñ‘;mÅÎ¥¹oKLàK\™kªÐ0<4›ë_%R€‰y¶uKùæUȱÌÓ÷€x¬™"ÄâczÈÖÄ–£ŸÁ!Rž™ž×¢w-‡7a˜Z@•7b_Aõ:Ú³;6�“©%ÝÿÅLELq¥¡þ7þþ.Ú 6¼Æw~œ `˱ÐÚ(·Í¨ ˜Îj :´m=mb[ÄÇnºiÑZ&ʹ=•´„xÆíHz„L¢ƒ®ÛH.' ÌçuŸ™Æoou)IÏÃÍí]F­O@@ö|IDTõv]†433ŠšØÖ1ÕU,DŒ¹ªMóÕZâxw‘уY?q‚\î|×Ò/1MÊfÞÐD"‚ZJh­æÄÕ˜ªÿª¶¬ˆà w!-Ÿª*Cícå²Q Õ¢I¨j)­ºHy—aüü*Éàä1L¾‘`ܤŽ0FÔ¤=•<¤xãQ VƒþbÒc0w$€Ì;^9Z³ºi•; ëO¥ê6’¤¯Ám0;<x-…8¶â/†Ö´¨@’Ðl0—*¡ëe˜ÉT=Êö[ºD5e�3¼EÌGħÏÝ®á\AUg6¼#Ÿ*#‰¡ÜT•¨íVa2âÀ~T¹SR‹Þ4’ œTZ¼„¹À2û\v»ÙäʹóŽ4\I©Âl-r<ñ¢Ã„d™Ö’ Yÿ”gˆ ºÁ­—‡ŒÁ9²‘DksMc$‰½%5ÁÜT¡±’©;8Xa˜cj.Ã0·™Á³'Ï·õÝPÙ†¹^Ì`&UÜe¼${žÉ‰ˆ½=¦¤/yG»$çë#\·ÃÜ·^…+òírlZÖ^¾BÌ­,Iâ§O¢m¤Lߥ&ò™Åµ ¢jôl.42éÉ^£üA¢é†¢xí–9êÀ^Ï^A1âÂÓ‡$«mÄ<`Â’ñ ëy©€ž§Ð'Ã[Ý#U,HCþÔ»|Åe³ŒË/œñªÞóÚùe’}q0SûH|¶aÝÁè©°w¦Ë‰9%ÄgÉ“¦;†h˜‹‘éØCø¨ÄV8ZÊ浚èu!5Ë`  Ù3«11IŠ¿”ìc™ s‘/N5gF¡U æÒÜbÕV­2K·/Üœ‘XŽ^&µŽØÚIØ5xê0ž 8;³©š%Bé€ñòU|ã…AqNè2h6ÛðL›xB/˜á…d0‰— Ïž8ø@‡hhm‘¥!M”`vÝž“Fîv°ÞȦœÙÒ¶c˘ãØlËóyP*³]=©²ãT­sG<è”0[HkDƒx¸0r�fZç*k#´Óˆ´ž¥¸>q‹›iG)¦$—ÏçÊ�Uëgž ô<�� �IDATP¯«b¢É¦ÒZ«—q°Ì;A¶˜sR¥™@¢ãnÇ—/hãäŽf‘à<W†%*Œn&:Î.óŽKnœ™Š(s …I*U$6ˆ䊨ÄH>žý Ö6j›:Ö×3’L«Z†Š:Ä„jÊ…CIðŸ±>2uʪˆþ  aûàeU&ˆê™sÊOk»ˆÍ²‘ó*÷â±û¨ð±pª >_Kë10Y×Ú*Ny`ÈBÌÛZnóŽÊdJxAVÀXŽ¶ë¡§±) ¤)ðRé~| õ§ÉÜw¤f_µ„‚C³[ZÇ;8uˆèbœÝØXd*= Ý‚_$dbðIk‘>;yÄMGbWüÑ«¦åÁ=móf׈äÝ2w;¦¶¶jkÅ€URK5B g»îùª ÌyÉ|7a)ÅZ?ÍA§Ñv¹MS`T<Ä`Võ…Ç$—ÛJ¶mÖ¸ØÂpp˜ HT™oÈÁhñuB¼^¬«@°˜·–’>"ÎE îCÊ«*MTÏ’ê0™Ù«%bU­4] OqÁsl]qãóK…Û2袖Žÿ+ßeQk äzjà›-Y‰™DnqH]EëΛà΋=mغ¹K½ªð(羈bp´Š‰ÒçÙäç]=„{¥¶�;ž½-žìÏñų́ Y±tDky”t–Â:Ì“±yåg`a65ΈÓXÐ\Á{-Š[:çEüƒœª°M[I|Bë91V3¾ú™|0ñH;Nå”"Ó“Û–w$¶¡Ò2ªˆ ÙÁÓòù`I/®³™<…\1\{–'ÌŽkzø•cˆðkëÖc ©Tþ ÊQÕ–áç$ÏJ¶,i¤Ï‹ÿÈ­(¤EËä'£‚¹LU 7H-¡rà T‹ð‚f,hiòô‰±YÁ8CÈnQµ›'ÂSõ ŽkõÀ´@üûÄæñèS‰7©uЙv*²1ÑÊ6¤Â„7s)Œ3!¿â£Y|Šñ]´¡x&Ñ`ijÌ´ÄKá3ï;"o r#rY•'­4ÐmD|¤ºB¥ÿmÁmñðͺ"+@› Ž í-l·CÊJä`²Ù 8ÑXÔÅÌbE!]e‘éN&Å®§*u-ø¼3ƒÖBñ!ˆg£ûc.h¨7Yb½ÄÒ’W`ì�`$e³-ȯõDÅ8Sò'ñ+T} øb2U“k1 {:^AžÒÔܸÙEL«i åó‚CÕ¢K$ÎSŽY—ÁPð}E·ÆüÖ|Ö>ûZ¬?9‰ #kƒkðu¢zƒ¯&¦T.)2é {ïOP¾¾‰Ø5H3ˆ#]Zö5>²b1lë¸Vjcà;6L´h€“áðä¡‚wRò.¡¡ ¤8|INØœ¯ç/!ǘ>ÄgQÛ\¥ØX+ÒÅ�aáÞ¶9šH¤º>’+¬Â“<ôH½xX‹4€É6T<m<¸üx´Ð–ÈâÕbÓ[2¥ò‹À»–ƒÍV€œó`â bÒ€ækòÀ�âÜ‹öŸ²N4§r>½"DÊŠä8é‰Ë �  øFB;f£¸g(?ý"5‹øCåçs2èËò®`¼ÒÅãL¡(ihD@N,D)ò'ßàA~<‡éwÚ¿KÂÀl‰‹f¶=>qž’)08âgk§ŽØ—ÚYã<äÎ$ #JtmøÇb7m©“ŠÓWd—¡‚—Â/‹Ôg†Ë2<³j!msqm¡mŽž£«W©=œ=™÷*DL¡Õhê,GFDÿ˜„ô¥Ty·Z $ëÒºMˆ3E![ñ"SDh°5esˆ© žñ’¦¦õV0á2ü»|Â%š‹<]¹¦…*OY$<®“†‰dÍ´\™ª C¢G¹š²Æ‘NÁAZ¼Øñl¾,xÞ)-Ýà c‡1…”Ïb×zfß+×d5 F2X ÁPÄ%_8´ Ú¸ÚòPÍÓ-S\êÚRUö–-WÐ Tª@QAð¾"Ž¥2·µ™ªõ™–#¼¤ë¶tUÅÀï¤EzS©. ¢O«  "ÞÞx×Ý\=PÎÈ�ë „~Ä Á2D\ ‘s| ãz&ˆœYøÏv¼ºØg÷Ø£‚T!cL§D°š ¬ñbj)_5n«à!æ‘ü Eùý¯òòp',AFªÁZƇÉTÛ#™< ”C~p®&ñOHÏ3ÝÍŒÚq³1YàMX@L’q=ñÐ7¿±Oš ž¦ApRÍ$ †?ÍÜÍ1ÅßS¯»âO<°ò¤¤Y0²žùM‡ ßÚ ŠÂø…¢ ™HI㱉—CÌÌÊI;¬<e™–c»C¿ÎI¦<Cl#(5J2_ߟÄ2DØhxJ Øc9—õì8~Ë]¦Têpìå0]I/–Iå D‚–»Ú±¥<©Jà·‰Yj¢Zý1‘ñÕúÁHŸesO Uì \f…åeÈ1‚r^ˆDœ¢Ýć rêA•Ö‘ëÜ!zšñ¢ÌE€¡çÿ+¢$e “ÊÛ‹T@/ŠÎŽí3}`Á&AU‡7ꄉO”$L'ûbÄã�ÚF8 š\ñˆ±Cï721;0Û<—Ы:vKp$v'rÛƒ–.X¬–¼>XP¯mp•œ>>ä‰�l¸º®Wp·ƒŒ™ŒJÓæàåÐín…¶¹Â@Äʱ’ˆzÌhâí©äqÏ—æ47oA04ÑýÅ! >š’€³g¸–KÈt›«ÓbfÕ¤×Ih¶þ2̦keø„¦ê!Áîáø^³‘½j!ÞÅÌñá2yOÈNL>F@h$2Òè’mŸ­ [U®˜¶ܪ …£Ò<Aú|t>{$>¦m,×MµŸÇò9SÉÝg†´:tr!âTÎSm´ üä‘(ÞçÐN+reÐ%R¡µ8uˆèi15È9çUEs•;}bn$[Ä‘1þDe€lj<vžÄsYÓ %ÒæF«Ø c‹§Ýаª‘L**1`V¿#šyAÊ,)Á(éb\hÙáÉÉ„fõhY«Á”îàÁª§Â”ÜøãÝØ3É)À­éÍô=BÂ?Htññέ|š^—ÊÓß‘&A9¯sjÎ~6˜­¶s¹¤/+²q.%ï;“;£Š%bQ†<Žd&ÓHÅÚªã¼mO[/¸¤+€,kñ0ÂgH…à•8[ȲÆo•UŽÜiéMÊ\PF52ùTæFÏüF²‘¾#-ÞsaŒžø ;×R’E—©íÍi}<}Ñ08*rwÑ}S0©AÕ=Ò\çôSG¤ÏhD ›½>ì<)ž39X`[ß ñ®v„œyÁŒ8I•¹Q¤`°”$E ßЄ_¹ßj3¡qóŠÑÐf¤§ÚÔÎ&Òº÷,#èBJžÑ¹Œ‡"Iø‹cJˆ{‡h媱!ÓÐÇý«aé¼…:×&˜s5m¹•cÈ4A– H,ì\?Ž\ ƒIôÐx©°2ÐÌg¨ ‘0¯˜™£�ì! ¼M’uÐD>˜tp©ûc1(h¨h¤ÌÈfƒ'³àˆUåî…)òªØ¡x !è–Êû 4²ic*CŒ Ïk7ÔË«®½ÕyË3𬀩k»8}\4]Kjbߢî^T)Q ¡ væÄ×6åÉÀJh G‰±iD8QÄØ“³Ÿ»NÌ*‚oÊ”¯Ù‚ x߀`³èºàzKužªØoùÒÀŽcž¼]C48¢¢Õš|."èŠç>·°´®½¶\QE B,×CdcLdÜO ÉR?ÚS=‡L0¥9q;(¦ÙŸa\O¨C‚¾ªÖ¦¢Ñ¯ƒ‰YTÌ9®uC‘|%m$©wY—< ˆLMID™Q6&9ƒŠÌ ° ‚Êë$ef'’ZÒχì“k±>l½HrFOØjÛ ¹„¨äÐ0À N+.¾i!NÌ~<•âdbÉýîw•MŽè!htóòÅç{®ºÖ`#Û!FórYø>ÕÖ1¯FXÉc ðªÀ†ÂôíÎE€ß\sZ°³šèF«<ѦÜ÷œèz'‡Ã\tÍcM"(,V!z¶†ÓÖŠgz.Šƒh\±ˆãåxN0+äÜëüs¢ÀT2r´å’w)ÕFyÍ$8VyBqh0çã2]`D¬axL ÕŠ†˜"A–ˆ¶P@bCò:Ÿ#ÞBë9‰F®+! ’|xYcÙXUÃn*$´\ÛkrO Î"r"ÛœÆÏ³uSµ-â\5ŒîÃ�­U,¸ 5Åbå¬<ÀÊ=¹jêïÛUf»hCçíÔùJ’ åž'i’'aÉÜÞÏñ»'u$ØN‰àdt„@�iæ€ç, ¢N"%s)ÂÊaN ñ@ð ×n‚côè|,›Wž¹¹–¦ˆ¦%ŽÍR†D�Œ‹§žÊÎLI¼yeç–,îÐ$½%¼×sòv†žuñ‡]½R’ÊÐ'ò‘$hÍ%ÇÞFwt>AÎ?ït~¦ó¯¸rx°·^}SFª@1G¹ÙÂ*î&6¡êéƒ MŸ|Õ9âQŬ+¼]HY« ñà'ª±˜˜ªžFõ&*°Qß*ñ½ø &~Ûþ4˜¹Ó¤Kh²àuŽ6)§UâèiYÚÄÛ19¾Ú2Ìø±c*¦êßU ·ít}çBê¼:ww:g:û;ÿ㙵WOÁ)Û ÔDx !<ÝW…Ðâ)ã`J”¸<‚@Öô 3ͳê’9„âÙnîUMyš«<nɼ }R¢9µŽ! ã Z"s®¡Æ…Gã\ çŠ7ˆWNLµ¿Øû l²¦{äf68ó™oõÄÌCñ~›µ“†â™1®«Ûm§ë;Ÿ Nç×;§;íÎdç¨ü–QZ „Ë€ n$²±’ë ,±±Rå>gŠîm8DS)þÌ¡<Á)næ–{] Û£@ñÊ!CÓŠM<Ýìñ–#~ž’¾<^Û÷=·qÑtÅó5Ä3Nù:0ݲìHQ'²¢r¹|î¾ølÕÄuÞBÎÍÎ/u:“k©3#´Lbミ‚dˆí8έCs#(Äá/¥=IšÊ´ä…pœ–<SÕUƒ1|Á‡TøXÚ¦«±ˆekZí…:Â#xœQ´`Ñ$[ÒÞüÏÝPŸhPy ãÀD¹b¤Z Ç#<¹¾’*9‚qO¬Ùüê¼—:×RçÂ4ý1bÙä¼ä2uÄE`8²sN-„R¹•YW±†dÂOZÍAð4n¤Ážö}s%ƒ†žòdæ,i¨{,²Ù_ø¡l{YðáA+#ç£à6gœL¡fÄY±A¸ª¨XÜ1ˆiS6pƒÇ|½Åôþ!¢Î…ÙËn(«NÙ×ýϸ|wø¤!-ÐdÈÞ®^–) @ ?|EáÌŠ»˜­^˜_6ˆI'b6ø©¢:fy»!¾;oCkû,çÆS§±’ñá¤`pµ-9œ'±yƒ®€J+^Ù,;>\”Õ‰ÓPá–C11'†]4øwl•׫nsv}Réæª&sè?CŒ‹øÁÚÛEêµVÉßÖ÷`•4X ]@¿KRŽ;ÂÌÅÅVѹ•Vÿ0~TJq13‡š94ºà!¬–Ò·„Ó€¤z^Õ¤¸yµ­_‘D*öäþXüЋE\Êg>©Í­šã“Q 9Š„ÙT•þ™¹—j-â”SÛ"iR&nu>jæMáÈIŽü-W‚#öP°ylev$OvU²S›ŸÌ cÎk0 é©yˆAS-Ï‹ªi2xvmº ¡QþT!=‹ˆ¶NO<¹<ò\ÂóÛ+:%ÞäÕ"E%ê†4V¦·¹ˆŠ��ñC¤Ï´HÎjA0ó¯Ã‰\bˆ¨bÄïˆÍ l’IR[nIÂÁXÂßw?aòÖð:Bà"ŒXˆ4õã9£á“µq“';®å,oÕ]x—…ÁrÄ\…Üh£n [#` hä•V“Ä»Êàuøi®µ¤Ìñ[îƒ1òÌ­8¼†¬$·dëPa¶óTT¹<‚$ax @SIÆÍ^± Ñ92-Ñç@‘™/NC \“ŠOGÌm ÆK6¬!, <I‘…çµ"•þ¹Zy<|;ý—”ç‡ËĆŽ×T«:1ª¼1m8 ›Û•œO#F@„æ§XÄG’Ádp¯:w\&Ó‡êgb#íS„à”~¦Ö̱ÚÛbßOr³Š{±¾5ÉTŒK~ˆ4õõÉE¬œkT…?‹þ„ÁÓ-ä¿`Ü2[]W|¦©ô–öF¼¹†êÅÕe·#ØîC€É¹S•Wïbñ\‰¾ˆÏÄýU‘žå¾‡XëL·\/‚˜ÍrQ.3ψá@¤ 9…™V^ŒsS%ŒœeÍ'§ÂéU<IÝT=BÚ{F'ÅÎ~˜à±¢$;“Q¢ª]C—;ýüU²–¯?Ð; „¬Kœ`Õ!h؇8›Hyð1ø¯‰v7‚*i§ËÜD® ™É-¦uà1°&?™þ'¦5RPÁ`qÉÀ‰ª––I$˜¶€‡ÚâQŠ“3A£$gæš­äöYf‚^‘¸Ý´¸Â@Ž| W«ZÀÜ.“@´]L‰Y_'Î |±2â×(ƒnÛ@ÂÕjp²ð<Öt‘‘ð Ò¯™¡Â >Ïj³õ*ãà\î{ò‹•:Ÿ¤—ã}Põæ@R–rˆ"¥j¶@ˆ†Ï*ŽÛH‚bÎðʱ˫ªSöàBb€kf­Æ9„HÅvÂóþs·`² rýÏ N-3ª¾†¥¹‚Ä60ã½Z÷9YìÂÿ0îDQcoC»d!8ešµúÕ\ªm©Þ à»PQQ>¸˜<Ü“ÙÉâÇ ÁÈ’ñ%ZÁªg^? æJ²pÚëœÝÉ÷ëÒ¶7b:µäèb€*|wÁ +“×Qˆ¸K[\oü&Ú—âZj W0|ÞTI®Áƒ´xàaz•›_Bk-B[ K Â֌ƴ¦&R7Uê/ŸHÆ~@c–g ˆËä™J©$ÞÈÄÉÁî´¼«Ç3;ãµ¥1û-ƒ×! £3ˆØäLå‚Äb7êµ5È”¯ag¸¡ Ð:b}&)U¼P"”oÁ3^Ö÷ÊÝnkZȸ۪Ö×´‰ãµ ’| "уÿ"zŽTVÜ8´­»™”VuÓ¸™ N4˜½9+`GÌñ¤å-ŒáSžGƒ€LTÊtºa¶CÎѬ(6x/DÌd"*Ä#„6Ì\›µØ`·¿\r,a”Lª¥ÎMä�y½ùy4÷~*B ÎÈT™™8Ë=n·|Rm‘2˜²ˆ#¶ª8¼¹×ØãŽGÏruHì„iØžMHж˜¿®õ´<ñ<»yÐfÈ[sehàs¬âYÌ RHËoü$4åÚ˜ˆ„°|bë·˜˜âWÛ–‡FIÚg˜zÀà‚ø´ø |¯\ÊM~¼‡lÎyäçO2”Óãë¬)yx•ÔQñ±bûõK?>°ÏÏT  ž�ñÜ*âË�ˆòe¼Ì,ÔéÕ“Ý^ø€$XóàDÒå XƒcK%§ts_éxëz¦ÜBÛ®Pël‰èxŒÄ¾lÎCŽ2†‘R;>…=žº2/‘ïd”óã„—à KÕ„›÷7Åþr⋌AŸMÎKpIDfÀ)≖Þ@KÕLÈPÉÄ0t”¨½Ø¥ÈyZ±FLêÈ ËxR€`m2½õè88üBí>Il—2½sÉñK%Íгp²¤ !` Å8 Xl7ÞŒ(,„WAv¼ÏÃz<ÂìA•‰\ßbÉôWFdÎ [4¯dÙ©B*Ë _‘d/jJÞ[/¡çÐj—¦è X³ƒÙ‰ ’À”÷ºéÇSØå6ØÚ1PrÁɘKèÈÕ¿ÇoÀ_É)¢GÅx¨Œ*Mf"qœŸ Š#ŸiÅ2éÈNÄRøsA‹*$2qˆh‘²RŠ4Õ¼·»;Œq,¼ÚޝÚCÆBÊýh1vUÙø²D”™§SÊç@ 36~mÀÁ?I9²$%’=Éy¶¯kERÇ“\ñV ˆAæD¨ºX!Ps]#"­4rñ-ÆNïÌ$Þ«û X`KR‚»˜mÎÝÏuÈd–_aªªÊ¬ÑFtp®#œ Ì+ ƒ’UU,ÏÅSq$ÊÝFDðÍl\ØÌ“úÏÅ~`å?N#¦r/z¡ÛøElàÇ_ /k‹¨êÕr¼#˜ tûÄçp?å9ó<Æs¡8^]Ë›œlm…T)%=ÅÜùo„ÎŒ®rÌž à ¤MmÌŒ\7/À\â$܈€ÉVH‡hõáës“¥ªÚMC>šjßÙÔ¼½1ØÞÛünÉ©e²†D‡ M5Âù« “¦ô=W¬†ìŸF¸;Ôli¤êhëÌPçê\«ÛfbÞˆOL¤áK|S&Ä•Œ¹Š¯S÷´C°ü‚ÌþdhÙÐ÷‹'í«b Ï 8rÇ‹ ŽË­¨\M~6ùñá=`Æ ÏÙ÷ª¾Ï¼ ’ù2‹AÖXÈÀ .SBpņРR…@âç±éjˆéÄ· 9*‚G&P»ŒñÁ§¿ÌÝCž‚°¤ah’K)—rÍoû˜ÇˆiåÛ’‹'ÉÝÎooËÍ%åÖ” 1(ëí’µ¦ àÌŒ‡*bæ”)¶ËêEQÜ ª²eðÄíx@gˆÒ©öŽ­ís±�°‚´8âÕ� *ž ʧ0!V‚;áq;±Ã)X»£ÍGç‡(—£%š6aÐàU\KÏ÷c#k‚®ƒ; y@0†« ®„úK&žðÅuK¥3sVn$SU’cÎM†ôÄ´[þðƒ mhWo Ý 1R·/©×R˜Q;³ÂËUË1ÎÀ3øŠ Wuèˆ~ƒ¶Y.„€ãÈÖi Yå8oÿÓö„]Õžcm89ÎÀ¶×<IqŽs2þ&êWWIþºîÙŒ‡‡ðdçb?H\3p§ߎà’-@\q…ðh¯±TâGU­|Æ6å³Õñêipƒ0(2†à‹ã™ñ8 ÕhËpa#îÔ&D"ðh®LÁдI›ö†�VÄR¡ƒQÆyëç)_¸JÊܤê…cËâúц͙ŽSüùr’ÕKqW®ä6öcbë’!g¬ û£ŽÚñpe}ùÕc<ZŽ$$}žû�,a´"5ŸŠs4åÁw^…¨4·6Ù’*s³f±ËLœX÷L5¡– ì"º;bè5 _×67íDb¤Ù„¢r„J4Íøƒà¥ü×ÀdEU?@ÞAÔZa8% :'ޏUuè×ÿ³‹³åâ…ü¹PyfàS:zóÛÍ¿‹áUÊ“Iâ9 âF`úF‚kƒaÑdªÙø¹Žx†0ù¢¤·ïW ,Ã`ÚpÌóBú¼b…ÅtŠC<€œi ®?„e“FHÑäKåw¦áFHŸ\P1ð¼bR/¯W@wA«r¦O®b—¤ì,±[R.í‰^ÄFwu¾ÇäFI|/ø0N¯¨~XoŒLP2£/HKb€”©*㉕c•GÅ,¾Q�¿ßùâ0&v^ßÑ “\|ž0üÈ<y4¸ xÿÜY`G’@5榮«e”~3‚‚»D“ê·©BÊ|ƒ= œHJ‰ýzí_µNHn¦åÁÞÁI|™±E~3±mJS>H©âsÄæn˜µ2å›öv«—45Ö»Aîoýä4ŸªîRD†sEQL‰±¹NˆÅư"þhñF-cšðažÃÓLe8 ™Nñ˜V€Ô!ìÕxš"•5VÒÛ þEË…¡S#kmxzæÒ™rÇc“!UÞLSŠo'OR—²äygÖUª÷ÒfZ&X•1Ÿ¼ƒtõSP*÷0xaxe¦Iq®r¹ò‡bb„BWÄ]s^N.Š ÐI_3IHÏh…\ˆ+—™«{ 6¸ªr ¦j?§×ãnG %éTL÷]ƽáªn´p+ÄÒÑ)¹ÏY£æV8Û‚ÖØA?ü5sï®jîÇ#Z„Ñö r¢©œ'd*µE—%L+b%£–u?)ªÔA¯«à‡:ÀÈdâNÈ’EgS„TQ·\SJÆ}ÑvA F>Gçš<ÝÄ06ï2âiëà˜ó”»¼Wjhºˆó¹¦q³Ð’Æ­Hî>aMbñCõ±Ê=PÃIæwÄ»ˆa°Õ%¨ü¼S5›âH>â+3,vª]×”w2[óÍmŨ›?ˆ}¸«ouwõS÷ˆq Á¢ð\¦ åf=5ÿ¹CáBJ¾Z0øŸû'ÖK0ýJÄ×Oεª{Òc·Jµf1Î7¦å= *ÊÁŠØh´{M1A_å  >–¶<ÂÌh—«`WÍk®GÀ•çõñÝ U4Z? E0f8ÞHñU¸5G÷ÀdFió˜ã];RbeˆÞã<®:XWGüêZ°^çTGÌ’M2¡�i‘“D³ùµLýÁŒà¹ÃW4&Ä(ˆ §J¶c&¸ $ãP!ö Ñv#a•“À,!1{"g àà3?q¼+œÄà –¦déΞBûÄ¥à�� �IDATú,~$ñ$6Æ]%ÂqpUZâah_)ìo$f†÷TéÆñu_g½ã!;Þ÷­ñ<<Eg“JT«dÔ„!ãÈárqûŒz¢<¿$øO&w1iH‘6<oá‰`è†Å^VPØ žº˜}Ã8Ð9…T÷AiÅÖ§¶ê‰ØåœþdïP-̦‘¥ ¬*l­ :ÚÚn1 OƒÔ~ñ<¼=˜k»ù±Í޶†öð9Æ?-ÿØWžŸ\››Ë¸ÌçQ]KÕû† °d. ¶ªí­ë˸!ÒÄ=P-<xά´n’ Â …2\M|Ä%Èá2§í¨"ŽÉ•)Ú: �ãl©Ptm|„Óœestê‹A¥bÑâL>‘T憃)là[ðG0S—Œ-—ÛD`Hɶò7‘¸‘¡‹ ØÒ%�Är+ŒLà¦eîÕbj¥\þEÐ25YU/Xßí:E V:×Ê[¬{»˜y–É×EL„ä& ´)eRùù¶,É‹ Îs^”œïŒñZÒ»G¬-I&X‚çªX ‚Ÿ`gyñEe¯W’bé6¢-ñYã≜äIäÏGmœM”+öŽ?œ¸kƒ à5V)%)c8¹ÊcÛ\¥k™ž¿¹‚°$< &"OKùz¬œ§N%yÙ“.f1b˜ÈÅŸclJ@1 ¿êxvf†#.vO‘u"Â’¢Ra*å[3gòâñ-�ƒÔÕÚ˜mÁ¥¥m’i(I¿–tËÀ`AN½Åû¢îvÑ”�Ë ‡Œ �ª†OüSAX 3…à5·Ù¿¶¹&ÄV2˜¡ÔXç1Ü"ZûÊLztÒ5 L$7`r5vÝ)&<;aq¸(—þÇ ÖÙ1rälŒ¥gÇÄ%Ò¶Ã@ü¨*ò«3ƒ "X–Àg$©b`Ø‘&U”€HÄGƒÌè”*¬…ÖcáI ŒQ‰e¼¡*í€6¨�Jú[‚ÑuÕÃhCKÎ ’úb¨²üEl¤1zr}¥ êgwð!`ÖuR™&®»ªZLå³iSýâ9“H,�Ol X©‚/ç²ÑDŽ¥\Cädˆv¡‚·xLiˆ g R>‘üDÅ Z!ÉQ2Ÿ<sòLi:TªùRn|mu]bǹ’‚8 û,ã A’^(7Úª¬¿ ”"’Ê€{ a3A¬QF$Ù¥ÉàÇØQUG¤˜×Ç-HܯóávUQ¬äê>V÷É69Ò?¯æ±”ØuNNS2Û¢îÆ|ðbp4I„‘#`ýÚœ[  RØ0$´ƒ,<3=C RÏeg8Ñ´„jGå)N0Hc‰™‘¶šèaP¾xws°Õx°Þ¥à›‚88ÃËÕljwNÇ`�UZ‘Á, £ÇÀfP;•cà “*ÓýGÐ1ö"ÁàWIfw•þ&¶Y¢ áAº~óÓ²øð̶Éz;pƒ$Cƒ1ÓÒc ?4&$*ÈfDB¶¢éfcÜ& ’ͼ³t“¸B½>”5¾OTÝ@“çDQ ¨6ë/çŽ_9Ø ¼î=¾ŽÏ\GlJB€Û<F‡XëŒÉrÁê *—ãðv×3¿sQ´ÀŠã‚u£8  ²K‚cšISÎ-Ñ âÅ0‡‰Áæîd*%[N”ͯ²¥DvP~­2Á!o(@& ™Sîî¹4œúÓÆƒ[G‡ âG°*µL´Ùâ}1eg‚ÑúU|äÓ\V‚˜ÆŸÏÀwçJÚ9“Ÿá‹‹VæÈ.Jâ6Ãz²‹h¬Äš&ˆZ¥Ç'—ìLs†’&ÅŸ‹sßLdÉœ@ÇïÜ\pIš/D«ä&¾ÿ$å +q%¤6˜òv[H»¤1xb×kùSHäÚNú6–ìvÃkàjqDÊÑU­/¢…ìˆe4e6<SÄ‚IÜQ @.·-pCs½ÇrýØ@,‹yåÀ ¨ó’ Ï’wVŵ´®ïþ?ÍáTOùeÀ+± ?g“á½�Ͼú‹Ä¿ ¦/èø%2‘Æ×¬#~å ’ÆJ2A”¡xÈ5©h$Y ü>¦åm!+½ñ‰†ö`¹3GÇÝ®"oåݤŒ\kðeqb§V§ŠxiXò‡Ô*Ôà?ë|kæî×Úumö?²â˜aäªÉ‚§.yyR»ÄD‚A¶E÷‡aD-K22yY±ŽÉéÔ¸‰‰*u;Æ<ƒDüôIâ~ª‚¾Þ¨s¡b)æúLòÁic~˜LŽÐ¾~_Q#â^ïŠç˜‚ó‚ïÉËœP w/n0[5èZ�—ý™OÖº2»±¤Î,× •1‚r1 &·S|¶z€ÑÓHç—Üîi (¡Óÿâ,ÊúØVq¯¸…qõ§dba Wêþ„Ș{ÇúE’I€¸/Â$‚'•VnG$û"ÖñqDžؤÓ\C;q©àu–ªPB2M_ûGX¬•· â˜[EÚlÿB•sÙ�w;Ò 0J`QñØÂQ±¡ òoâew”ïKKRÖiÈuªäfi4ÅÌŸç<• 9ÆUž& 'ƸI¦"’zP÷¨êÁ§$V¯©ªŸÈê\xVÉTP€¿N=ë=Ë]‰MâÊ…£(_…’\HI\Ñn!Z$åå’‚V.¨irå6£9IF@Õ)Xøÿÿ¡‚mͽôþöÞT·tIï«.lÌŒo¢vb8‡ŽÌIŒš#0£à P AgvÐ0†›êâÀt0Á '„ÍDÂECJ&‘A Ø@ÆÂ üGÆX`˜Y¾Ýk¿û­ª§~Uë뙾f-šæô齿?k½ï[UO=õ<ˆÕj2iļœ»yz—…¥ÛåÐÃÛEê-‘ò´„g’ÁÛž<>Úñ¯íøÅÛqìÉ“­úX»]˜%K÷´…•¶¾~…S+ö¬Ã6:{8w¥Ÿ¬É³·çã.É~ÂÏiXsa£rˆš,t#ÓcÕögi%r¨àÜ­rôJ6f¹×˜mQøÄU7‰éõ±È>¹hMrðÿ®r@x ’ëÛ¶×3Ípæ·ûÜ9îïì«ãvŸã¿=Ž¿µZÅ[BýÊ佡3YPw½ý¦}´I2µ…m¬ÊIBQ]?ŒÕBÿÂ/+ïîÓ„ˆtyŸÅ€­]È^v#ýwåÿ¡ÛøL:®ÜÅeN/jqèÛºÕ!9l…–5.CN+ÛÛ ® I¶nç•RF—¥YK³e¿Ôm{–‹ \y³AwxŽè|'L„\´×µÌØÉÇŸÛqü×ÇñgÇñŸŸ|¹°1æ Ž–ÊV ´(þžC±%§f’ES›bÓv˜®ÓÄë †m³rÑfž¿„D7)QrNÛŠÊ€_ÿ¤tŸÕ—•<éÔç<ëNe´L.ÉÁ ãy«^ø£i4“ÃäwáÙU65ü/ö¸‚Ù*±¾‚Q«3I ,±d9ØØ•Æñ‡x­m;üËfrÔ¡‚ø,y‰ˆ·ÞøÎ¾:þ±ÇïÇ×Çñ׎O*ÍžiÖÜp9‹m¿•EhO…Èu››ð®la®‡ý¡Õ/\ÐÓ‰€™0ßÑs»<å¿’H…ßhóY6G}$:°ás/O—) òoÇý9Ù94È%*9ÐWˆÈ%8óñéÖèu°–£#ט²+–ô„ù~°Š3žµžAš32ˆ¿]Ðᛆ¢Æ£¦ÝAÅÇ©}|mÇ×v|°ãc¡¦¸I¦r7Šrµ¶$ÑÊòZ®á‡\‹°ptìä úR¬…ø“»Wn(í•ìaf—Ãõ'C¶}EZ’cBLOc Ð}´Õ,Kœ@è·²^öñb®ÕkMàu÷¬Óc·‹ü®<õ´yk–Ž%F®ä>årÙÚË­f¸¿2ö?ló–kòYE9 *¹m7a%µ¯ºG:ÆkÞÃÓû3è=—aSÚüöcÙ„éÊÎØ8þÚþ‹db«;%ÜÂûvªo„§RxC´õ°7dº…PA@â™aë`-QÊÚß=ÓH'ÛÝ ×ÁÝ^éì~²?aé̲¿Á2§ç² †wY@I­ZDw’Êü¿è¤ þ|Â_"Ÿ ó¬í .÷RH[÷ƒŸ¡´] ¯‹¯°U?¾zŠ>¼rÙ}ì9±ÁÇY¿®OaýÕÊ®ÊÉ­­þë–˜\FDØe‘R¬Œ4ð|€cgP$" ´Â4yŠ4h30ޤ‰‘Ð2‰ÜÒŽël8­ }Šˆµž>úk[%9Ñ*3ˆc­h:ï.ùõ‹Èd¹§âZliVh>*‰ã›ž²ïsˆvŪÝWz¬ˆ¡ Ïø'ïcHË Àù3Õ¢bÏŒ'Õ°èÕ‡‡ÖŠÊ^Ð?ñmðYµÛY¿ þ†– ¯g=ZÃ4ëq[–WÆ¡h*\\ø»á ñW:)WÜ{¨`ƒ‚ÚÉ™J4!¬P¨2Ëðñèƒ%¤8!;ÐFÒ*„ž4H!_îOv|cÇÇâÞê�£šÂ1̬r 7ê¶CÃÇߟ_ÇÃ1aŸƒŸœ OH)§p2•ñP 6dЬ®üÐÜŠiù/«WÔ¦š‘Ì-éçLß²¥­pE™¬4ü+Ü:“©¥‚”¶C›•q¤I¡oŒjƒsÛÆ\Á­6$i›Òø½&ºs/Øuƒ³Uã 8ýjÞo)\Êe#:s­}­±>Ùñ µö ç,rg7ÉNÖ¦º½”Ý„ãÅŽoí8~vü“wL³UiéQS®}¯SºbEAÿw fBÖr}ÍpgÞ]ð€Ö­òÒ5«{¸¡T†hY}=ëÍ¿©H.3ˆ¸œV·=L›º£œùÁÒâK•WC K@u§¡¯ÖX~ç„&$ò¶,EWŒx¯‰4!; ÃeJú½P˜ªüÀä‘ ˜ÚêIjdóx8È*ª^ækEÚcþ°VÿÖ•à'ÌŽ;Žû8þ“ãøÙƒè¸«Þàúñ™ŸÓ.*þ8^ßB€™žWºÄ À™ðqdÅPH¶Ï³õ>} Â’Ê$ʬð�ñ€¤I‡‹+5ήˆþK+•Œ© tcU×H–À*¼,yÎ<–¦Ï@LŽ™äbð­+_¨Dšä3®Ü ×ËS l®[kslÒpsVÔk›·µ|<+<b¶“îQÙøX¸þÀùÖÿu|¶ã_Ùñ§vüI0¼¦k[\YZáh°O†^CÝ‹=@ÈUj}Ùðü Õáä)©ÉfH¬Ò¹ØúŽgýêŸæúEH2”5Ì|«l<2Øt°©ÃÇ’ºB Ž2†sZÁ ºÀÎgbvØóÇ"ÍÞaêú‹ž™v¡ Éè… Å„=<Ñf€Ù¤A¢íä9‘Ðò¾[ߨl)‹£?K8Â1d1|¾ÎkëÓë†}µU3wû±PLos[ùǧWõÅ×Q¶¶B®'» 6FµÊæ ‹’`8ÛÀ–߃b"óâ„é 'ö3g&ÕÔZÓ¢åg(;à øìÄèo‰ñ$¸+ì4È'†}¬+Ö‚°úÉ*ªrä z<ë?žÝXç 0º$g?ríMþ‡<(M⫝̸2ô–ŽÒ¡XN8Áj’¿öäB?Ktƒ¶víQ="‡-Ì‚•)ž!›É}8»æ§¸ŽOv|~%­lŸù$+ 7òÕë™p@¬é, zìÿÇÝÖÚ\ Z%WÏûCž{r+â t?väƒN¹u¦}ZLlØØniéµQÁV§îÊc&Ò¥­|'4Ô!A7ãmwEÇRŠÙ§:þ‘ßÚñÙf/kÀº…Àˆ)$Fûb.$èokÝçìg°ñAB„LOÜ^_c’äØbÒ«DÈ‹­¶#'ÿP4Ʋ’1¤)ú=Æ–CjŒWøõ¾bYé “§¬aãÓ5xh–«‚Á“ÚjU–Ä´AW”ÊaxëÚhÌd]ç\Á®W·?oÅêÁS!ÕCWhDÓŽ»üIÿi¿·/_ÚqüÇÇññøåEɸ%&ÐêÌiµ•óh[™™ÄË6ðdLú,ëYˬ¬Mµ™ ‡ñ,SŒ$n)¯0àG;>½}’GÜòÌ{í·i‰L”5'ð¶Aoí@‘µ‹NaªSJ8Ó÷ grËvD/¹ÓnÙ2Ï^?œ$kMh <…! "c ŒEïÆé{©—ØžÇÒT‹™ATÈìºâ]v}Zªn×ûŠ´|2é]fñbÇÿjÇñoÿìµÆ*3€Ùœ„¸çÙ¯^k%;6R¸g­ñÞ½õ·Ö\xíºJ–ó’3åur¬?Žïãå |ë뛞b¯·ëƒmÎ[Ù„µåFÒðÅkˆ,'ØŠª5î>dûWBføfjÜr«ÒæÝW¶ês±“+),LhÔõ ;ŽÙ©Èå¯ ã=­ÆºR'ª+ ŽLZˆ^Ñx*[ d!³5bò™8¾±ãkˆ9¤-óðI÷ãÔ>I¦³~$1–ä ³/»ªçmrö^ ÌÇ<n3ø®}õáBîãÛÇ36o‘Eê q*qçaðR%ÏÅû0•½€l6€ /ÙŠám vA¸È˜Ó<¶Q Øã×M“qïFÌzB b΃£5áb¶PKÝjQ*78¨|÷®+èX6&{‘–5œ?ô3¡ÃD–¢Rv×Cj›X©Ö; ù{“1^mÁ7´üq¿îêóní¢ó·Î:Ϥó,ìÕm¥Ï ôv½aÈ?Íãƒ_[Vù•©›?rÕY)‘']e«óV«,ò]FÐé�# -»dŸ@Xú…¤s}ЭÈØY0.[¼°ÛÉË ¨Š€ã-4V?QÀfÓ0uâ`n‹øG> IEË1díòU6öÎü üf)Ô»�ëÑ.K,-Ññ$‚í¥V§í£†?_Îe‡rüޝíø;þ§ÚÿI¤%ìdÑ ÂæÖö�37¨vU¯/#VëÔƒŒ;Ë­~×~ïø%”ƒÖç1YŸ˜& ¨ m}}¯Ù­ «aâÝH©±ˆ` , ZÁ+ŸPÖ Î&ÝÈsU¢8[¼)=€•a¢ê£BØ®óê±cÉæÌ2Û$ßvzü³âoÞ‰ñ¤ œ"La«åÉu£hE¯zp¬_ç¬ÀŽ?|0n~ûøœl¡"Üþ«uSf/²î»MžÊ-^µFDAºÑ–ðÄÄë5\}cÇ·T­ª÷£Av_yæ½ÃOÖɰea·ÖJ¯áè…qíö®¯y« Î$ ˆ][Y9’ncLê V$‘OæB‚ƒhWVQú,Ð8d8a¶iœo®%âë™™%\/¶§öI(_»JÈi ×\ÌfY>ŽºZge5–gÇ;>Ûqüöñ‡¶‚¨úô ]˜EµApx/&²Ò,7~ch>éR™`eO9à ¦òšü–Ùú¬lÙ6$­<‚´› R‡Æòëtg{y¶$E}¬±r µŸw_8ÃA+²ü€H™HjfŽÏʲ4㉱pBÅkg”íñ×söÅ6…:ê­>[J¾é—kŒWˆAljèÞ¬rC¿³¯c°¾©~khôƳøôNábÓ< KÿG·ïøæ5\µ gî…L¼–I|sñ\'«~‡?æÂâ2«Z¶¢³›.íø•ÿ ²^D>HÈÔVv­ç°œù[.õ9þFÙß·¹‚ZÅk\œ Ú7ùªeoܰ‰g™Ý„•tzåëRýÃ9§®r¼6¬ÓdXúXdì–):EXr“W΄vÂÅp4!Ä´ÝÃMKÉwà¶§_Š.z§•Ѿõx²dÎÏ̆³b-¹–,«ÕOd{q¯á»µ¡X¥Þ"töu2¸n¤yõ—ùüšX„v�¢„È-‘»³>7õJ¸ÊãÜ¢óÊÝÓˆ.õ cUé`+Tyº÷Nh"äêj—æC]Ãòò“'D†¬VÓUH C bZ!ÞF‹Xæšäþ§EMøõ¯ÿÐeßds7|ò;ûêøøTV¡¬x Y¡üàÛAùPÂýæuèêñFî»×•7)¸­L±i½“"GÉt¶j{•Xô…KØÓ‹Ù;@¶8¤©ãcZ] ‡ #½É.ž–qD–‘£cÐÞ³¾ZüâèØjVu,'ìÊ×·:Ìå K Ä0IÛ g!JTJÃs¿•©•RT`b>,,\Öäz $[W-nDu¾)­Ê›¾û)…wª%y8+¤Îg‘X€•Œð:˜õÑÖ ­“¾¾éŠ¡­Z!™Yhˆ†•pB†1x”Ø›‡ùÆ!éE “ÌÒ³kz»òЉXÙ]w$½ñ‰YiwyP$Û'”æ2ñ-ûUÐÄ|×R kÐsëÛ–t¦@¨ÍJtz×\)¾®A�ßæ7-Óîì42Á+Bò˜OÒ3NùuÎk#¬¯d9«X!Ftâ“k<8Ëšïì«ã[;þµ¸©y1½xó¼§ÞúïG‡ì5h½Øññ5tYäÃbnbÌ›°„ÈG¨¸Øò[}Íéîë0‹¸¡tVØêQ3kò›Zg ÁJÍ’(·´ Ç­,þè5˜òŒZé7¤é¾ ˜üÁŒ}›Ê{WþýSQº=98„Oj#íÓª_¼t¤ôQDð …,t¥ 5àCkÝ,Z¬›0 %”¼zÅZ`/vü¹Çß8Ž—³Ì2'BH9§P¾º|óªiôøGÐ겪Np"Jù;X—s‰q«\'üòhå!€¹&=kù+tsBD†ÈIUÞ™.»„Ø‚@f\–(<$ër4ÊW{o8ÿôuÂ$}Œçú•§‰R-]Áîg}!èaÊA¬›X’¡ë#'#eÌ‚p[n3=gí²Úþòæh&±"ZÇg;Ž—ãø7Žh¡}vF!}¦íÜß<8êgÕµ126Ñ&Ï„’U:e“cûûSI+ÓôLï-„óËãe‚íIX‹AÏJ76ölj¸aoß«^ΖªÓL圼&ª± TeWåû¥×­NŽàê Y-5ǵ—5]´[ËŽ¨4ñdÊkólóª«Ô�9½¢R¦þ'>­gâ­¬ñw"¿°ã[;¥Ó[¦3ï2¾in{~£3�Ÿnjç„V£ 8:l ¢r¿”Þ ”P† ,\|Ò`NÐ"N¬F2yÓ…ä…⇷¹ ”eª˜Wü¬)ï4î¶@YÔ^eL;›ß„ž±H-!SÓ€³-!;”ÅðÊ”:³°Ñ-ÎZè(džA^)"¶Šø¤íµBã±ÐsV£—k‡ÉœðAfdå—„VÐ…ÀEžTîØG#ʯ¢,áXɇ›0‘ÉתkÇ+lbÁªkÓ§Ð¥¤—gõï¸uÝD­Å«HŽ/Vȳub)¾åS3,ü- Ôñœ2WÚËD^µx€‘ X£‚¡‘ZéÊkí.VkÉ�“>¼Ýªe0×*!Sˆ|ø™H̆t‹¦k©ï°MçlÅ“`´ŸgîF»ð:~Ñ/7}8W»ùoóU¥Äíö7™$kløýb¥Ä߿וúe¾,rMÁ6 ¥KØó¬5W–¦-tG1©-Q] ¦…B©(»6ÒRTQO1 8iR˜Tœç-NLC½¾2£‡úÊS!ÍU’ktÑdñ»¤¬„á&q<Ôi„$#Jd%o˜Žm})sºdú³mšI™3ÈIÉËæm×ëÉ "½ÍäøJÅáÐÒ ˆm±?‹ IOç) sK”V^é$/ÇaÕ¦“õ¡0?—„&ù¨8ˆRšX'ƒ¦5,ªÆ’TÞÒ1‹M(ω>}‹–rÉ‹·—’$þ«–+–AÙã¬;NRº•FÛ `›ýn—º•>B}ËÖ·ÚëTž=õ)Î*$œvÊØY¥µYÑoü–;"ê¬6|»0W ÕVi‰ÉW!,Ε ìÔ°æIÞÜ)?˜w"iá_XÂ;{9OÝj9‡*œ>f}‰#ò“-cŠñÑ=k‰]¬FôçïE,2lt¥+KŸ®ðe–k…¬°V2BfZ°Îe,Ñ;hµ�-÷QÌN|Ïë oÂCbUS}XÙnM!à½=¶&_6Øë5–Ä®kùúø_ÜŽ³µñeG9¨ ×¿óåÙ½é–&[>DÙâ‡'ïüuììûâõüÖ''ûlb< Œ^¡MÌK‰[Ž Ž¸Yð CˇMM*´r”ëˆbyZn…=•¦+iB+$è4Š öòóg‘Qr¯·¾²ù’rmð‘Æ=ZO ¯¬CEÄÞÓ¶¬à{ìý¥¿²ãÿ¶ãk;9uºÉ·¦ï2ý”G·4 îmòc‚˜)êÔ5‹1[ÆÀS½¬´ÕGÞÉà?ÅDÖ’:Œ"¡4"?XÃJˆS9®œ³áCìNvšt#Ò8ωyL²Ä$ªÈ·ÒŒsßó ~JuÉ_ŠÏi]/Ý<vL1ć £ yZݸ˜1¡3Æ-O/¼àÛfuQ2ÂÕÊËXªãƒÇÏŽã¿;Žÿæøß‚·墷›ÓUhÖ¼¥;'¹ÜrnEhØèœ2ÞºúTÀó¡"¸IÏ0ÿgïÑe˜P°¦wgûNÊýŲ^£8Xáü{0J\W7˜»r@‡Â¯ü>t3é1±0܃­* æ!‰‰ÖXÙ”n™ ‰5^$¬‹V—/[Æ*‚\kå‹ü õÃÓžØ*H¨ã¢Û ü2�·pxjßÛ—Ç·vë8þéq|wü*  Y¯&&[!¸™ƒdÒyÝÕ¥q-sîÆ:üdJµBpSæ“‹$&y¯a œö^_�� �IDAT¬Ÿd[¯²¿-Äi×”î l¸&“‹r<6ùÚ²¥ƒttwÅàÐD¼E«ª^•–Ü¡.­±J é20Gש"¯<Â6&ó ¢×¬F+¯„³®wÅ™*“z¯^Fvaþ‡Oí¥ãí8þ£ãøåqüüøƒ¸’Û´n-çÖûÒ7|n赚´´ïæn ú/k17ˆ-‡ua–A’¬’~U¦y7—-D­É8€<Ž%tÝëœònÏÆªùÔ1¥ùJk¶u[}²l§ø·hô±Ê[Ŭý)æÐ¤…^ †­KøØÊ¡]MA†Ã[ÚÚJÄïÐm¼Â"σ¢>¡;µà6ØíødÇ';þ‘_Û*¦^¶(ì½”xx~e“@aÑYæ%Øædç¶U+¯Rdè›A¢œºw¨k¯µ*òTxŸ1œóã nJóY’Aœ½ºæ#Û´²ø-¡?µç½1˜_’ݪÛZ͈òH/•Ä‘ÕRxò?Œ"Ö ¬öÞE¥¯«Hš`oS«h‹è š"tRøÄˆtéŒÀaîì^m‰ÌÝl!Á…YÛÏGÛÝXÚ©{€HÞ†-äÊü͉>|2Lè.:À¡–ü× åÏŸ]1}N…^Ï~(*t:~t!Ê}áWTöã» å1í,‚ªoza$�vþÖD1g6,ÆÅ8Ñâ1+‰æŠ{‘néÐÞf·· T½ 8¸Ìª1XĈE‘u‰³Ñ|»ç éÂF tUÎâoõÐ'ÎnµŸßÊsŽŽ–[Ýg+–óžW½"¢¯g«dâ‘5´Ýèªâë¼L–ždÙbØËoUwÃ{^Ÿì,‹7‰ý°²“23 ŒRý”nÝÐ âùD'—¿KùÊ3è¯õ»DáÚê¶ŠK±fèg¶…J_™.ºú-€wy·]z!Ì×¼êAÙ[n5ØB‘ìí­CÎëvo†Š›:»—B8…Ì9Q·ÙÊŽ.,U»­¬–Çéö@E„.ÑËp+1¨ QØŽ¡í?‰²Æ#n½š>¿XhŒ)¦©ˆ=)O³'˜!ÐT½l®kin)>h”´D/†®±ð®¨ Ù¦AæEéÞÔÊèK°2„žž’ ]?ƒ Éf·«)ªž‡Ð¶Ôj I -ˆ9œí]µÉ·Òjõ__q†5dfÎåNFgz?âÏÂLLÔiÚ…ŸcXYøvÀÍnÄ-Ô=adMJNýÀ <Üšs¤8.ÝV$±œŸøððøyIÓ»¸\¥pºnLw, P'ú)…ÝözÌ‹ÁS«¶ `œï0ðÜ‚j§¤ +WvË Î¤t·áŽõ/}š»g°µ÷g:Û·[A¤mzÂÞß…“CÛ13:„Þr ØZŠx ®³ù”%R!›Q Þ•j–ß„¦Æ»v°2vÀà,‡õ•„`K»…Ü `è\ÕBõ33±¤ýTâ 6k%nÀ Ë/Ò¼2/`}­ .µ:Y¹,à’¨.•¬‚Εjª%È#¼J0`Ýæi‡[ˆòª<+kn] Û¨ïÊWhëi§í'ý±Å HæˆJóhÂfÛ‡Ö”bíykùí95®2 ʬ¿Mò§ÍÀlýOﺹ…Þ´œÜv92O4#ºä‚¬þÓ+$«õ/*»?±ùÄG¤9hDj8ÂoÛ¨Ù«ûX3¦yÌáNÖâf$Ð÷ôâPÅ� ls­Ùäð@‡¾;e+Ø7Û·Ws›HÏÖª9ƒÖö.ô䌰óK¥e–êáØ2Ì»3¡©põnõÇœ°ám±OOd/ܧçÿõÀì;·åæç¦7^"QT(¢q§Aga[¥ÞÌ&ØLŠ_@ÊÕŒ[(Ѿj·ddX,9‚é>eøÃgNÓÖôl¢ëéÀ˜ª £q)û–uï[ÏŒ ó÷ì†t?Œ×ô#½ºL÷/k›oopg>¤iøv×éu*¸›c±Ÿ²u^Áhã#„ý9RIB$ëæ–ûíŒ@õnã gl@_¶†ÎÎ%íóbê¶w^ìø ¬Æc[Üõ·å¢Öxwg•=.­…ƒE(õ:Ñ„ê5À‡>‹î¢)Š{ý¾„™rU ²0,2Y'¯É·\)%Éë°ísðÇúÄÁðÇX…ݘéŸ_úëQëä­P8£H)W¦û†®#ÆW MuuÙ§me ÃF‘žQó·ÅÓÊÃ}~šwlŸö1µþÌ�#"´.ŸÙ¼â~ìtŠY—ÇãÃdc!¬Â[Åb»µèW³4zÜ?;1¬hùó¸*-ØhʶDº*‚º š÷±·û:\ ù0¥sR¹’ô ì·ê*cÂWe'¼RÃÄÇòaUÄø·È|ƒ¶6ÌÚ¶ QÁ×Õ—€sï*k:¿=¬µ¡µ©Féµ$:Ìå´ã¶l¾æ9zS1ÁH ¼2‡|ͲöÌÖ0¹Å­µòÛ 9C–ãªM ÷W™2êI�½E²_¶¬ºô+ ü@ÆÄ�Ђ£îð‡ s÷ Q<ÃB¾³¯è<ˆg'»Ï…Iœ°D?BË£•’Ø–»²ÚhèO…]¨7„›àYú”—uj& ‘ …øÞO¦–´J'lʯg⧸0Z_0 ¿‚2 ®„–#b –«ˆú5¼ö×›VvAZò’Ù:ÐÖU÷N¯äƒ#gŠfù´]Ć.ÒåQG“õ%f3–i‡Êp„?jäChõWb­²œ&³Fmív~^gýÉñÃËtKy¥b•LYé‡0ŽÖßlIa^éY‡½:0ÒÌJ‡ŒáŽ=œWìÞÃíáf–¾âƆϽœR„íîLH~› ÞÆ®·/²zjưVâñ_MÏð•Ýû¬)uÎ]=¨€ë—=“•µXª3„®Íew¥G®.QÖЭ‚u îÝr.‹ÈÖIÛºWÂÎÔr7¾W—q»%vT—¯5ÉoDˆ­z{‹ÔÕ�éq~f±~Á²¥­ç´b˜÷© µØ}±æ.{›à9‘¥M8Ã"aY² K_…³kÚ‡L4±Ö>“~k/\Äa–ò ÄB|¶lr>èÍId}¬+ï6NøAq¿1Fp/ñáqmi èL7›©ï†ÃLª¿…ÁrU舫“›ùq+goAºpJGoX.´ºÐuÏøCåSĵ‹Ìpˆ?ó¥Õî¨þÃl'£÷ŽòÔg±çׯ‰7¶€M»LξH¨àuÞÖ†œöœÔg¯ì·#8‹LaWÒ«k±y·Xµª1YDÿËÎúm´«{Œ´ê®,ÚʰÍytT˰a€YC«LãÄFÐD¹tÇ]¶W#õñ[¢åm¥‘[Žvð{͘뺧JV W:g„ædaGj=}x„ /s¬9/ƒ²þÀÙ+dkQð6’îœûŽï¸ñY_®w@˜k”ÙhˆBCåº,œå‹à C|;¯$ m<QÏšƒ˜?ºØU—oI­_ñAK×�sg ã#ÆïZȼý±øa:H—ŽŒ–ôç ¡XxèßJVà}UÖR5õC¯þèôVèëNƳ9õG6½ 'ÙÂ4³Úø¡0¹çâf4-éf!‚ãCxzz Ïî2W ‹S;¼91~¦Ú+&Tü˜æJìôKL,üxW©˜O-±¿º¿…ŸÀ÷º˜è‡­hQNð ÄßW0£5[nhd9MïyËÕƒ`vÚuåÇ%vkóùó ùÑZMZf4ë¢ì1“¯]EÙ7wá ìAB‹X­êxÏiÅ«…UH9ö¿~‹°Ìîm6É®ùîe¥›UóÇG;þÔŽãß9¾¶ð›fa&[fáÍ×Ë€»i«¤È,³Ik „ Y´U)^4@‡ŠÖ¤p¦e**ûðôxÖ„\jüF´Û»§vœË)Ÿì )ü<‚ì ›ÕPz9«NôF*™O„QVfáM0‚¶ÅZ]­êM~hÑìŽ1%@Ͼӷ1S¤&Öæ\X§xGÙË´Ü;Ã÷K2äÖ÷z-¿µãøtçø&XÌ^_#ÃrWä3;¿Ên±5çˆÅ¯pp…drã3ÇFœ ô²qn°A2MíAhÐÁI÷ Q¦Ã­’åb7ÒrÆíìÔÎR§^Tv^‰ +3Cº�SÃaÚëÓä5º˜óø°È¦ÖÿîzR¿Ya-ŒS2Õï„-~d:ªÐàNpĉnKúiݦóg¼�DxâˆdEkgs¾‹¼Íÿ³ÇqÿéñË=�‹:>d`fC÷³z"Ë äÕ¥�@øW”\ÖiÌ—kO�EPc(\K^Eиxçá�šÖXzÔtP‡n¡?[ÅLøxÒy¦veM!†uz†z•÷Mp2Có ‹†F…¿F™í†Bï! ´Â-PéÉSâŽZnÈÍÓ+;K6W(›ÉêØÆ^ ×çö9Oµ¤,Aþ]û½ãì8~~iÇ×FìK¼,^æú¨æpVÔ]1@y\̧[Ã<OÄ<Ç*S¢áRžó¥ÇºèûtfÂchÂðQ‰¨j3Ð šã„(>dI®×ÇgJÛzŒxPYåðºLeoçÇÑ×Òl÷nêÝ›…Õj‘åK@}0DAßêu@Zµl6_eѨMÙÀŸ5DKœ$< 6‡-ï­¯öÚÄú‡vüâÍ�ZP«ßu¿_Þ9M‡ÙØV4C‡Ùëä+Üð¨EšF×±ýq³†;ÓÂÒ‚ßê‹_¼§+KøõÆ_cHRÍÝØã³HÑ=q7Î$;-bjm^Û›ÔÍVôlv~‚x%^¸:lÿò„½ìÀ ޳¬²ùB•؃ðKë&ï¢]ºù8?BWø¬×:òÉžŒsŸÏ’E˜a‰šô´òÝ¡4³ufü¡Æ[¹0¶Ç—yîŒÏh±ÈE𺳒ž2.5­"Ç :>V‰5"֕ܧƒŽ}_º-­Q0Ò+÷•®} Ÿ-’7…ßNO¿šd{fy¢·QnO^2÷y21­ô×¾‹Û€”]P«‚ÃyâÆn8§.sý¹/TÞßÔ’^Þ‰‰dR/þ‘éæq‰ A_‰°CP !Ûo#‚náf‚åÖ¾„‰£OÑ2Íûò“pcôrɉlÏg¥WÚ`Àßå’!»½Õ6ì–Dš6LuÖÐf*Ùƒ­”ǘκ1RF¸íÉΙ٘~ÄYó&lDŸ.ÛžÔå–+[è-íçR¡cÐѧ‰—¾,“ô8!úš¥Ž_3BôDcéYížÊZÎcFŽà‚�äøÙg)áË ’<YäÐ1BÖç0\·º WEKÅêR•ñ8TÕªl®X´‘æþ¼r ¿x–u®É¯>…‰kxkÞÙW¢JËš%[Ð:É~¡`Äúá·îW&TV¨-K6=À[°%Ö­¿>&ûøäwÃrÃSFüÛ â‘¨ÍzëIg{Bch[Ñ->:'‘‹´»,ÜÇ“[" ’¹‘pû“”KàÃÜ8ðM²òŠJÓS„O®x–Ù3å’ü( š‰­[êÁ—Ü ­? ¡‰.Æ·ýì°`ºoÚ<¤Œã@>AZ РgfXh ´19 ¸ÛHïjFu¥)ë»tz%‹ßrcÌMû_Ã>ipBçÆröy=¿§,÷ñ!)ÏôýÑ-¡4ØJYH�~NÄ*£N88©qvÈÙ#Bºþ€€“Rzʰ²VuØ=\Â/blAP«àß׿ˆUÙ™e¹¶ØÚäÈÄ/ ¯t9Ý*›„¸-©óÄÇËÞ«”6ÞŽ°u4{­º6“­PdK¤qâ f¢*%>Ù:¿H&Ñ-AJíð+})Þ,GßJêÐàKAc}0‹ÊD±)[Tí>V·¿wL‘©ÌjÁÖ‹cà2l`ôÇ€DM®ü+—ÂÛÜG`‘yk(qÌy¥¥2)ÉVèÍQªõtQ¸rBœ%zÄJ-[>×¥ÓAa‡¸y@g@±ÐÂÏR’‰Î ,¹Þ ;ÙsiÒëÉnÃVÞ(½V3^$È\N5æ9Þm;:ÎÊÁÃiñ³°�‘Ú$Ó %Dí \Ãb¨ìœ‰ïYZÕ†—`EOp_ÁÕÍ¥"ÜQY 'üLr¨‘™ r{íý„¯Èa‰M6Ç2gç¬úÌœÆ|±ÁwïÀ?&íàÚÝÝ<äpKë]®¤ KØ" W©àãõ‘9âMT’5eŒ}š±ëk»ûÛœl•ÛxÖÇÒLq “§-<fk¿WræjJhØá÷ éÇs UÂ4Áw]ôY›.aøñêA‚ùBDùx &wŽ єزî5¢öpñ6ð´RÛµ*i•3˰­H|`d‚x]i ü,[“‹4ér$\¤ på´¾ U[jô‚”§Å 4$Þ› †Å .¨ù/r`BC³w÷:@âÀê²›  $ϰ8´ÅwøÙù÷Õþ°ØFS-™` ÐÕ%+´CÌ2!2Ê6°ÎMë·úKù¾òÉúVñ:ÙýZ×~´ãë4q\öä<Î\ŠG—˜Û¯ëœ; Ï|ˆ¹…çC Í#S]*¼]ÂÉôqÆŸ¨Ãd `è5(ë®#¤]±ÝYJU”ïU:F_WɆHD¨¥0µ‹‡-°¡äLjVâ™>hŽvüÂÂòŒ:Úˆñó�öx9"Áõãh:ÏCNemâ–ßÛ—Ç×ñCÙ–ý*©¥]Øùî#ÇÜ`ƒfßZ`/7`mðm +OçåÑ %çufÏS±p¿%’ð·‘Ö5VyoqºöWYƒÄšÔ>“ z69ê26^ÍWŒnSYήÜ>üéиýúÖðô§‡`ëñÉŽ¯mud×ÐYW\«»ò}kRˆhºoÏ”§Õë[dÈü9H°ýç«„àÇÀõ*달•´Ÿ50ƒ¶ÏrD:j½Å:Sä¥ôš/ÔR'‘´IèB•€ç`=w;‹|$`fhY¾2­±BÝ m—0WŒ:}` u=a¹a•8o:ê—s¸¡&Óz,zúÍF}cŠC¿œY¡ÜŠñâÏ›¬¢0 OÉ̘T 0éY ¬µÈ�hBÚ,~hìKî„Ìt‰S·ƒï¥WQ+*C÷H¾»ý­ ÓMÞPçx›1>p¦$·~°y ÖR¥‹±€Î€aÙ“„V›µ#ƒœ- ¢°—„G³WpÉCí -ÂF(gnÉÄ••×\£°²)OÃ/-s òÛsfYÛâ´Ž¤câpèJç|¾\Θ‡Ù1 Û´ƒVn Å!¼>_-Ù” q%OíV۳̦„:ýZ¢ã%lá<Ä*@Îv«4JÉŒˆ!Ìk¸äD+©œYý†j„WZwÛlY;{8›84ð¯°væ·?l·dÔìY³ -pƒgÐÞ[/û(…çɔŠa“ ke•ÌBlÙ2kÊPŠpC«¾·/nźÒÕ“d%�îAž›4‰o™Q´$q¡‰â˜ÂaŒüPžPM6èƒn25ž ê*`r.¸.ã²iÖ²,ÍBi9˜éq¦V²Ÿ…“V|Ð 1$“"Ýé"ËrljùãE€XØbJ̤:b˜ávC—POaOZJÎOs—B'aöy¼ØñÑNñø¬6¦eq]’+.B%F2KJ©ˆ:’¶È*[:ãQó£i–ej5Ÿ¬XDšá"&š½Œ¥O9úyÇ ¶ ³yçeri4Í”CCáÓéÖ\¼*4 öÉx—Lé¹5Ùzo½Ôº0u\¹‚YŠ�E³Bìn€}‰8šeo&í¸²´~å¯tznqMKKBŸ‰bŸÚäÕV Ê.°U3ŠV9Ú‚+6sÖ†ÙÑJrú´Ûæ ¶ŒËL¼ukZùHwÿgÁ¸|îvà ØÍñ¾7,|u2.úêm/˜µâ,(£{8ìü½}y|¶ã³êWRòŒ(u?CÜ bPÛtÎ6Ìw]drû0^F=«Šx·,ìÏexWÝ™⫤ýŽËÜTd]ÚªB+¥l# 9 RiUÃÖÜŸ ;&¼ªó#ë §º‚ÚE»6grãáNÇni'Ï5jùèOFN-S9g훓!?Xg¢{b>á,äúËS/Û!_:>ÚñÉŽ_¢'ß$]§=Š” ÄðÉŠŒE’y²¼¾ +•ÒJ^Àiýs(,°÷$á;ÞÌ tr:C‚Æ€´\nÜ 1L2Ê.àlÝ>¥å7ìP»][ŸÁ’¢«q†„©O€:5TФ[ëûöåã }¼BaŽ2~¬ŒçðØ]%ˆ–Ë ›UzÌ=ð%X˜ò&Eþr-<]ao† -Ð#K)„ÞM:Ë,Om=pR"K!>ll~£ ­Nj‰=3ªûÁ#c$¼•ÌmÚ1Â_‘l«ô~«×ØŽX™ú¿ee¨‡ç\:¥¸{6¯NrR ]¤çñ2s¶^I_ðeK„Ö{X@ Ùlö6³y¼øñ1VG$ÚWDå–$àá×7§õ×:Ézðfl¥„¨îÀ"+Ü봂 W½Ó2õ°ËÌ^=ËÑBh¹Ä”¦2ÁS…çÖ­z®•–AZ · +ïjo«ôF³÷œl(ÜÇ»÷­Úy€ð’š† ´˜+`¥Ö$Wà%í–U[½|F%e6Ôb!)U¦xÔÒqÙºSküž0øéž‘ 4ù0+\H Q¾²øœe›ö¬#³¯“M§‘ã)Å/y†ã)%ŽlØ$‹Bƒ[0þɾ»‚Âu«nR • Ê_¤Ä%lJ–àÀ=3ëÓd¯?xº]—+PRZé>Ç,ü·º™�à DVˆ˜Iа{vX„:£·½òÑøVSØ:&G'ï‰ÂÙ‹„'f¨u¢ï$A 4˜ 0 Ä7KùI%ôØ8lî¿xˆm;ðÅå¨;!·ÆóIdip5¶™ùˆYH-…´–îÌS ´ôÞ´<G—a/–Z ¨Ì0¢Ì”¶<˜t[H‡ØP?F¬’üý"‰vx£B•ÑYÌn¸°F¼^‹g%l޵fùEp夃YXmq£‚ÈRœ†.ZWi„›ßâXà•¥G’µ¸6?c3¶3¤[#Tp ¨Øª(ù¨À’¿G>íE¥Ô:Ÿá­W΂®(‰ X¨»ÁÉÚ.½‹otsp’j”ÐD˧5K$C–¹~&/¸KJNÙo†X‹Îðf�k½ü¿Ä¢5Ä‹¹n‚[ =u^ùÁB…ciYr,|ûzÄ<éh=0x^w‘@‘w—g:,Þuè%™H¦ì™Ý"¨Ã¦?öcAø‘C?LSΔÀVVø‚%Ù}%bð8XÞÁ†·ú<g³á'¸øaOR]¡Ë^¦Þ]ÑXËnˆÐ€J0 ð’i½ûÀ­êJ7ÁF’"•܈?çìâ nÝ~Eå~L@'-1O]ãµNCôñÅ»S°™·a8™6!ʾ ±—Í•-?jy‡ >´^E<ùç…a:Óô?V¢žéž¥™YÏ`yÈUuøÙ„ÆÒùc¯„èÚÌ¿Õe)—ÍX«Ôׇճ4™@"Ä÷đÐ<¦Ýc7s8Յ®ç?êÕíí‡ë¦û9µ(ËÀc&Èå ÉJ¶H—ÒÊKÖV7%UfÉGãV8m] $çóÜÎó¸=Lìž} #M)ñv¡H)¿BÒ‘õçCQàJVÊlzéîᬟD†t}=u@‚P˜Áõ9ìc=±»sÑþ’ã[}‘AWs‘µ ÄÛÃxéMðtÙYºöòÀ`i!ší4BgäÖÁÅ Œu¸ŽcËl¼•}£,_iEš5"žöòE”ã]ô IšP£Õ¥&0FI¹6,µ@ ò.³L×Ù]‚›öÒãkipæ™PR¿t‚ ŠS•‰Î€W‚øé5Gº½*t1ã×]tÈÝš¨!úW~;ϯ#znâ{iÇÂ3S+…3ÂÓ\h|´*'ÿ‡Y{@ùWjý2²ê5Ð]E­HÀï’XTüÏÎŒ»;ð`ÍÈnÜŠõ`#:IVÄ—ÔžU[ Òá)w]cÍúOÊ䣯åƒ÷4ˆø…A”¯Ù�P¦`ËB.‚®Ä„E�ñ0Ën¹e†“[OnËǺDºW'˜o­ØÓ•ío¥þÅ�ÑEçxú^„ç–C’.,®8‰Ƚ¥Û©L9Z~YXNÁÁاt=´Þ.¡†•cv°�m-˜’sîÿ<QÂó/ÊuÖ†ïΙC€({½=£¹\¦B6&ÃÊ ì›‘VývºÎt´Ó,rozà¢aÑ9n”róQ±‘1 æ3ÙYÑKж:.R¿¸,7<àJEó’ï R‡,Á"o]ƒõ4|ÚEɹGJÃÖ/…T®ø•èšá’n7Ç!‡lÖ3É߃Z½á{e~᣸ò,ò·†CBÇK¯ðé¡Ge¹xŒ© ÓFgÉE’nÝk)’rÑÅîWñ-“Eµ–²Ÿa ûŒ²¡ëKÖ(ך3©=1V-…$lÀŒ¼•“…Πƨ%°Â›Ù /\ÿMõ1Á'žÆ¼RCó@¨k «ã.p ûŸ·Äª*NZ%cOÒ…îØ©ùIJoQ>¸s/:4V1k®4“xæ‘Y(é™ënm´q‹!ðØ,ˬàÄaÝE‚¥$‡—³Ñûx“AÖå±¾6§‰@ûņ_ˆŠ¯)õ7çÖvðËÞgIpa§'D¬ò /9ùëdÖÀ9T7ƒ‘åõ>‚ëDc ¦9!G ‚õ 4{,g-¶fºËìøÇ°%§akA��� �IDATÃxç¿©Š3}}ý7kÑ$ßr«æ7Û¶°Ôó-RzòÇÝU ;fq%ëleyX¹­„ûÝEb$®èÓ‚üÒ>VyÊ@À¡ëjcý‘{ýâ]Aú–•í“Ì€>,@ч™_ü²ùÖš/B²–­*åv  áShe á¹!D²/›òÖgÁ9„ÀJ¨*28à4ëÕ°æ/ ŸžUÖ‚ CAHÙÚ,g{ z`ÿ„4om짇ì~fš>šdk Ç¼(OQõò]¿€œ-e°RŸ¢/¢ñz€C†Þ ‹‡µW#[òbÙAÌ™bÛ<Ù’o 3˜n«FÄ›Ð^{†én×°PL——‚µn¿"Þå)-ú0Y™‰Lв©••q¨«ÐØR-] ý\fSž@ImCóX¤á©“ý,® žz‰W”›¤UÀ¶Ä^¡vYDœÛ*¸"»éQ±ù2 ˼wM$º±-#ÐÁ·ñ&̳¾ôÌ W¶”ô»ö{D£D“Ü¢®3@7_ÌœBà ¾µ@A»�¸á–X«t ÍqJˆ2#—Á 8³ú,ejyΧ‘›ÖÛ@CÈÅo€²¼•±"m´Ë²~Ùy6‰+yyºÍXãã‰HX«qO¬ð‡C‹-¶è[™ÏI£¡u븎œ%ÚWø>ÄþV Ö?ïk•U<:Ë­Õ²"Í$”AÆ©#»C;áÊe:ÌøAGö…3YÒ�øy†š3õšpEÎ^j %óÄ` Q¾ú »)Ù×_—Sd•_ÁNõëëò³ ‡c-�³{3×Ò–›Ä[¥Õä÷jF^È`ÛPŠW× D°¸…¦zŽÏ˜"8Ãüõ  "kœ_—•ºžË¶˜Ï[µìÑ·2ã{^‹ oë‡zwqâ‘M鎉%åSô RÊýñ TX~‘rüÓÏðŠ5 ÉZ¤…“ý§7ŠÿÌœX 'íËÃ}{SÞ”òTÙÏ·‚ÌšÃq`CÊG •¥åÂwÖCjdPË9N2•5#¬[‡e ƒŠþ±Œ|н«åߟ¸Qc „*ô'híÃÍÿÖ¯TQóéÖB¥Ò1’gµä8ù¯‡¬Š1´rž\™ÄêZ@|g_Ì÷¬1ˆ¦0áÈ2wë¸#’íPêÊ“½!n"Â4>[³Ô$LeBÄ fÒ3¬lF%ÏO)¨¨Q=õÅ9döcìz(ð¸IýT²ÿjmæéÖ˜”*™°ÆçN}Âßèb»5ë™sœ‡8 ‡ ½\XºÏIj Þ="¸ÕœçuN‚Ãñ1r›õ«Âªu HH4~µ”fÈ…»Nï(Pim®=,~ ”/”læ³Ìü踢ßÍÙ™’K™ZÁ�–V<ü—ìñIÎÉ<­ðIR|}“+±×N'° B)O´ù&:€~ABén)d¾JÖìr_?8`(‚ D©y¸î¨UwÛlYàãZ° ½T2hWCœ?’Ù<^W÷è>k1}EÖ'tšÙa²@Nˆj~éX‚1hÇúÙÓÎŽ./Œfc׃¯<Qiâtâ_*3а¨W,w ‚{€Ç€ñˆ¾›'žåY~µlù^ipXÂk«{ï÷öåñbYóƒtUC6yƾËjˆv!€2®Ú¥O½Ò¸YoLÍ©k9>·Øó%p]DµE³‚ß…ü|¦+Fôþ­3bQJ¯g$Ê–${ÿMõLd«‘ÖÒñ%õDó"Üÿfý ÃùæòÙýå}~‰<$w ˜ž\ß~ãYla<ꡪ™€^xÞ©p%<CÓ„st‰<A›Ô6$QWæÖ€X§dó ź2¶5ŸtË„‡ä±‰ rŒçgJ^Œ0€Å«ÐèƒCëü$ý*ë@Ù’$äWÄWhp»lm=ð˜o¡Oãªóú[dëŒc†S~åÃÍ ùÉdºº'&µãˆÌV‰žùð6³)sº‰êb…<Êrgfñ•D'ջʀò-º[»•Ø‘òßf†^]Í‘Ü*–‡ðå"ݲëðïÅï’á ç¿o£ÆÒ1“ˆsdÖ|¢úáêãÝZõY³eÒ`cöäDrwQf­ 3rܯeŸVægéù`®í«£ÈÚH"—ìÊE–#&!fÒÒRΚ.Ìga6]~;ÍòÌØÌ ’?™{ß³3n×शj.e ;ç«y2űêÏŽh1–ØÊñ+ôwöÕU¬§È1ðÒ-Ä‘y¸îÎ?r˵.ø æA¬µl‹tÀ§ü<âY¦WŽ8C£>Õ©Õ¸ðg}6Ò´‰ŸB’ŽO™C£ñeÍŒZàƒ OÖÄH¹üf¾¢3t¥ ¸èaÈ‘ ˆ¬ˆÒ¶K41¤Õ@âO¼$W“ùëò»“O‹j,ñfJS¬œu¹J,eLåä OW{2¦ü)ÜÊ ²ù§‰_‰ýδ$²´qc ’ª%‹£­bË¿iÖBã°ÒVýâ6U WpoŽ;¦ïðÇ]Þ¿L R\ùÏp¤ýJ3B8ìŒïŒ¶‘+Q“ëØ&ÿ^ð¨o×Xa£ÂןÄS"ÖÁë‚Wä[[N›ì"ûd‹rtNsÄ ½ÁŸéŽß…té¸ó�ÿ<BBع!YNX«…s}oÃ[ý½}JOùñA³Åd¯þ r¨³@cfH3/Œìs‚ *\·DÊ-±¾k©ÿ µF2§¢ß¼hkõ¢ZG4ÿ•ÐTS|#4 …ñ£jF#$@0W 7o8 SžŒ¡Às1vª§ß´¨@ÛH60(.³¦f¶oÃI¬0#9>Ùñí[¸Pä¶–òV´Q-âÙ­žXŸveßHb1Øb`+SÎÿœéì•¿«‰æM ‰¦àŲ’+ŠAL[$Or ³[2‚Æ;ŽÝªó€*8žêÎw³­î�‡Ö¹Ñ¿[š¡‘ŸôÞ8@KûƒÄ3Ö‹‰WÚ†ØÂCÃéx±ã“­«m‰eM#¿6Îh5Û ‘á)j{Bz…žÇ ×í ó…xNùt´r<´ÌBáUµD]ËÒùJÇHïQ8ê®R9ØZ’ 5[}6¶lÌ0bB—æ±ÊöÌ€TÝ:¾}.ŽÖ€0±$~–»Ò•¬úGp fý"|:휂jÚí ùú¢*}]ÓÞ tvá‘<3˜AµB«L›¹h¹­-Y®R“O®gtZ%ÅZÊ”ÚãqCáÊÊf`ý3`+\™ÊRÂR™™¢eÞ‡üœ)¶ÛW˜h^dšÓdüÞ€FF—Ùúáq—˜8<A :uÅYJu]aüp’š•“ö[=䛎<НÜB˜KeîÉç+¬‰QÙ<h žû¢•õ&Q*‰¹tòŒt»ö®Ê®RV‹š‰+òYD—/á–ðe3`¶üÖ"R–ˆtwkÃy$«d¨Z|à–÷•u¬z‡ìör»Bù‰+ð—ÆöOý`¥O ýÈ[®ä‹qžèµpWÑ0ãÏ‘×yj»A„pá§Â¢ª|âpvxË`¶^ŽN¹„¥ž9I0mZÏ¥»ÑN·ÖaeÖ?åO<+òD40~IsY¥ÞZä<¹8…fŽk·ýI ÷b§qö‰Ç}2-@Nô#¬I+h=]¢87{¯‹eh+·è&\zÌ@Läš–?ªøžñÛûQ¨…ɸIÇñ©(^×fó>r¬ ¼óŸÐÉ…¬×2W“wZ®î_·á$BŹб‘|ˆQHv”­¼Óqû¬:Jð]í$ÔÇ€»€¹¬êj„zVŠ]©Ûf@“í~ŒÉÒM=<ß*;7PS¶„àÓ–¢vYçg8¸²º­4€Øº§ÛÜ9×/’M1‹>S‰+fge™*yÐ2ô0$&L-ÙWl·™â—PuÒ´xÙ6é–Ê”B½°kCÀ3¡ ]FDÞØ{‚ñ,rB¼îYŒÌ§d\8Š×…ÞÝXMÚj¡eb÷§ÀÁ¡2l]ø?dÄtñ.ä&d=׊ÄãuÂXˆx˶ò÷ðKmUÎj†ééïZ×UpRÊ=+ÂLö¬½\}Ë¢b fÜA8]@ÓÏÒð>|o_>¦Ë3Šdob«¶¤¡Ï¬2ó¨f·ó;N¸¶ã`þó-°ìZ!”ç–A­&™Ð—#R‹ëÂ×:£+ãáüœÒbÏàÚÔžÌ1æ3…‹Í”kû$ç"Ù2\íåS-t½‘AZ€•Ÿp Œó"#âÇęÐ<¬%ÊwЯ\¾-³•qöl@nq=¬ü“7tÁáë%¡§ÁàÞ¦O»j•Š4yVÁ6†aRù&4„Ù|bèYU§|Ý‹mÿc€åºç^A$¡žôV9dÚhšn—õÒ´qån§[94“ijÀÝ·†G1g¼ZåoV; U½øEǺ;Ehº] ÀòÊÝ Ãökwçy—ìéûløyÈòà“üÕ ó"{$Û¹aÙ‚Ñ(€r>·4fé¡t1‘™ëÐåõ<‘cPQâ�„Ý Ö‡WI¶ôŒv‹t7à÷ù€ÎÌD|Õ²çgóù÷cË`:¡ä;€¯[êS—;þn‰;éá!¸\ïq|”Y‡•™¨= ÁAcÕ¸q¶\}<.'½ºWæ{‹4Ÿ.VÚDà %‰ �•~>ª©uEy^ÃWvFZ»è“XÙwÆZë ÊÚ7ÛÉg.¿šgöò~®•Rf*kõ¹!a/pë?•}‹ÁËÜ´[;h`„¶ÞFÝÕ‰yKÓ7EiÕ2ànm|ñ‘’¿Õ©çÚ€ë0±Î(…aÅßõ<‚Ã9!h)Äú7l‘KÜÆšóh­XUcZß³ «ù Û*}1Lêp·Ò‹º=KN-"5ØhlΧ~›«½E3.žðr¼ì–ÐÄ€µÜÕ¥8½žeÅ yôd4°| .ST~ò¤‚zt¢Þ…A±ì‰f=BëH¨@؃#Yw­|‚³B³œ®³ŠÐTæÙ&Ö{ÄD3Æ.:ønç mÖ èžÈODyžò 3ÉÙœ î¡ ®èQ•ä]³3ʃ6z(n!Í7W¼Œúú.«¾ÆFd|¼GPôŠòþ[ø?‡ 9A÷ï‹ fä™Üú…ПÖiË´üIÎ; âañŒ6ó3ãû‹¨3[äßÖª„8ÀóHãÆ§7y a>ž'=,H²ÏG±ÚÊBëcáS’ë#Ò¾›iÃè,WNƒêm:“âˆÖ9Õ†)Ê[)^Òp«(g?ðµ²e³‘÷B~G™ŠŠ®ÕB¶òR„b+3›½ãû®ëXQ ¤Nºž˜j}2–pp¢-Ÿ¢¸å—j•q-„ÿü±Bß9^·ZsZ§Éð—mXX=t+‚f›|»V×”Üá�²ÉëÁ‡x¥Z¼By2yºÐPx%¯‡e?¾WŒþU–÷ÅÖ´UráÂüòã¾—èùëÈvÑãîÔü�nÙ'f…õ §$*z¨f™p|Ž®kK¦®šùsqqø#bÂ|åS¾´—ù™+æª]µ¤+ª}ú,(Ùe¤¤ &XÝœh èú©ìhr^ò�C(1É^ö¶RƆfMÇP]^Èã® ¡ç”‡¦*$(e�…•¨.[ËWðgrc˜I‘­üìˆVñ³É\8;¥Ao(oÖR7÷ŠO{ ÈÔYSD æ=šÌUÒGn#P upôÌâ9)Åfø›6Ô Çžf-âV§ BùWúaäÓr33ÿv+øFXž>Ãu6“¶3âŒ^¡�îövžâ±}�ÏlÉÄ”ßNßóÌÈØ€Vˆâ- øKc³Ø™)L™þ•6Øä0ú,ô"ã©•vÒ„ÞÒŠµ¥íœÁ â.�jr¼ÿ"4\æ›ú$%N‹Tm®Aú\U&æÝ=£ ôÅÇúV©8ª{6:‹¿Âîñ骯¥<]b}—Nð~c!zfÄ9×úg âYqœ?–K4¤µ‚q ØÒƒ(ô™šs Â^F÷Ë&VËá‘Óh€—DǮƒ–@W÷5K‡2ÐëBmp»æè­ 'þ“Bz€Cσٗçzìv­áh»Îb¬£ÚÞ-×¶WUÃ}÷%œLÌvu6ã"æÜ±önÏÅ=ÐgN ¤¨ à›aÛðVèbÑH2÷ÜGs™[ï‘ÁÓ‹’¢Uxm?°é>ˆf›@õõMæƒç·Ì‘ŸÒ…E?'J¹Ò³(µJ¸3±óðgÈ8!ÉÖC^(ú�kmû,î;Q„´Å‹¿]hWñÄ×/w»a)ô1”j?ÌêZ¤5~v³¶Zäüϼ°÷„x‘/û"feZBôÏ⊠ˈ/ò‰õãeYÝ`h²TMìbq]»ÒhX«=i̦E'&2Zƒ”ýbšÛ²u69>+¦Á®|„©Û¤ÆÚл<=G:4<N”÷2gØÈ¸mf#-“LH¯Âl™¸2òJ«Njåp¾�ýÞ¾<^ìøðÀò6çLÕãçZ4§¹1,6u¥L„B—! Þ"‘Ãl„È—n¡|Î )ÎFÓt$ ‡Yèü„-³aˆ>åBA egÇÈ,šfïj[hÝ0%*Õìy­Ãú-µX{šO¯F…eK è¸6fûŠ ´DÄ–DVN$ϘT®z‚Ö@œUŽÏ®P‹X)kì9>ÚŸÖ£s壯‘é ðk;Ê÷®QÐî\‡W<5¡L+¡^ñdч)çC· ëÒ·Ú˜) SÒ@"-%è×�Ϲ» ûh&£A!բѕác¢Ý~Åü¸ËX ‹Ä+¸]ª4?[ÒáKqP›xl’MØMú´ï#ò¨¼eè\ û5/{±ïíËãk;¾±³Øz¤G Ëp¡µäZm^×~ÉÌ<©aÃ�É(º¯¨2„D"íîí(•gG’þ.ÚÅ0ZˆEyzèºf~a¶ºQjÃoÍe¯ …´vú¬ïET ³¶â›Èç•Kÿ+™ÅEíz˜_tEÁ3˜¾•Ie¤²^ BÂý^^_§Ë•âšueàý«H8?Q»ã³ŸíøÖŽ_T‹GL:yí+Ê÷ˆ7'ó¢aÄðé¬Åzˆ¯úÞXˆ¢„ð"ñ�¦Ic‘RªµÔ‹Ó²ëeËÃ_!–pc–:LÂo›C®ó|ݸën­vCØ@ !·p/{¨ vèÐg©Zf™ÑÌÝ•¡Öç'\Þ1mÁúS_­ð9ˆ|Ê?ÛZÙo óøí•O¥ 3;>¼ ÝŸÞ|ο\égd:Y0â¾˨êY•Ù"5èH“yC‹9 èˆÑ¢&f@_º¥üs)HöÞäﺮg™k-ÐYwàbË&üùMðHƒ%G›LD&ûj(b…mÒ+G<ÑZï€ÏöDQ]Xöú$T 1.s`Œ­kxAä pH“š´⦳~‚W'"wþûx±ãó®;µÖ[èµE õÇ^Éñ^›aÛχ÷ÿl’Ÿ$4¹(gnV6c¸BŸ'“‚å"¶ZvV8|a7hee^b¤]φ25·ˆìaØú]íRîF—p‘M|¨‰áFöšúõ‡ìöÁüG÷ë=%~<Km}<® ©G­d¶äãòZo]ח䢙ˆIø.¡|¿œÿ¼…™¯•Öù—¾euÒ(6õ¦ïíËãÓ[´;Ë2¯Ø½9rmCÖ%¯D{#ª­/¨#Êú2Ð’àþg<{mÏd3õü”ð²÷¾&¶Žþg˜»dä“,{ƒTÞ:C»†I1PxºdÆÃ‚”p[Ê•BÙìJøýê²±ñ¬,)$e‘ÜÍPZʳ¡mO×*l;éf)$w½ºðA‹n€·Úèä_¼¼ƒïŽé3>­eÖYÌ@âJ—_ñ WgÄÒ¥dV”l³Õ¢Ùþ¯YðBÙ\J+C׫K·Ð2àÁ¯ö àÑá¶ô7'83<1ˆì\¸ñ3 È´gª€á#niI{"¾O ÃÙÍ’>Fì»xnÔX°{VfÊWÎÁVç©[o’ùü‹"ÝW°\è3û^úÖb ·´õÇ7nBé«­æ-ér{õ£L¢é•øÙŽ_½…½·0öá­ð:ÿóŠ/~|m+̸U`êí4ÜÚÞ4kz­_gKÒËš;£`i(Oœ)"!óúŠ­úÃ?ÿCGZ½›DÉHUa&— Æ‘êDèAÐr0÷BÎ4!!´ý0‘;/ ¨_å,MÄnçZ‚’Á”„9>5�ý4ëdPEyS­7Ã+ü2†òC5&‚Ó ⡜M)¾+¤AèÁüðz[N`pÅÙןÃ_ìx±G5vUǧ·ùú3Ÿ^i[Åæý„ÉA'fçcX1„©€ç–¦%Xg$º¤n!]m@ˆhùIp~òfð5ÁiDd놴Ú 6l^”Á¸u ©èaÅùëZ‹Á¤Ng |·Ô4º_AXPà bÙ ­ÐJ†ÃÊJ>—~Ù2a:iaó¨¥^'ˆ¿¶ã³Ÿìm룭à:ªµÒ.Îéã“|±6«^ãÙÿ¬:„«‰?–Lëèw5ËBF{IÏ1̑پ¦×à(»_å»Õ(*q]ç³%E&¦ì² ð€×ÞB’.* 0±üÚÚíÝ"€JÎèé]]ç‹·õú‹—®NO1EµÎˆ É}e‘§/×±þ Ä(Íéí=[ïä\øÂe¥K¼þóÁÞñ _Þ” PÉk˜üø&0xÖ^ŸYãýŠ^f©å6zµIË[>/Õ¢ž—+¤LºIq  [ªä'ÒAúé,ijðiýVH†ˆŽ>C´/AÎDž]‚O¥Y %Ô3=A5/.:Ï–BÑ3ž‚èU–XW[³L÷¸ýÜð%vÇí†ÍÁp}ÌÌÀ°µ!WŽVh<Æ¿Q¹Î(²õŸÌY-¯ÃXе†íµy g<ÿó|Y¿6NÔqë`Y2V¥õ„“ÙžQ"œôòpbØÌ(ß»Š{³ZD„p>IFà hˆj€&SbŒVñM´yñEzoðûߥ\AcnO¬OÇVc¡[8µ^†(Cˆžu¿(®X"E­šuœF&.Æ[í²µôÎfÕ{±êQ6½‰ç.\ ÏZüξ:K·•—‘ÍEnbNÛ@Õ:^¶…ŠUÂxš†9xÙ2€º…Û.ÓK½dChwlÌ:V—~T0ù+ƒY÷×u!KZb%œhΉÝUÌüxÛç‰"–¨iZFÀOê~¢‚ô{îå×-׎ÓGÉÆãÒ%dôCXˇ RÂ�, ·~’W<:ãÖ9¶õÆÑxù¡kõòv Ÿ”³ûÞ¾|(?¿´ã£ecÈa3/»Ûmô²‡iÐRd¥“^~Úe0Ó:¶Ê¾o+žÁÕ86ÕRëâvi8Aû*ÀD3ݸ¢ÜXBe°´Òt„^Ä$;OéH=åK ½ûÈÇìqºuŸþbÛˆ"b+²È­÷ÃKÞõgV¨ÍG…s—nlÀ3lõ·Ðõé­Ö9>¾û¾ßÛ—ÇïÛñ‡v|c¸u¾µ øû }ûœzÈ¡•g£m(_’q²§ãM;­r6É�vx†ø´vÊËÐ’Ue¼,1•’a+dÉ øÁç|xIÜ h¤ñXÿ.=%Ün7ÓÞžµdIõ0KâÊ o6Q«ÕÙEK;¢ìt€nüŒÈš(ð Ÿôe$[Е‚±j n´ÃµüZ=GVA÷ã“ÿ¯Ç_?þÈNŒhl;kKdÍB¸#¶WËœ$ýðéöŸk·¯{Œ†kOpPáÔã˜>§7È�é6˜ºÝ°Êá·B…F¼  Ž.¸¯$Ó¤XÔY²fÍ4˜ÝJÆºÓæ¥Ën”"ÞQ(Ð7ÉÿõþËP§@؉úMÅí<H Z`¥ S ¼ Od?íôH›fàÚ%Z£×Êñ;£Ñ)~q|cÇŸØqü»ÇñÛǽJ@uØë­°õ9®Ð3S/­Ò>X¬¤ÊƼÄß„H³Àc˜Lѵ³)Ù–(Èpž| 䓀̺šämúÖ]9ÃáÉ K@ ÛXk‚˜×}Ï *¼‚^,ƒ¥CúRâÇê–<Ý󆧄Mv¬ßÛB½·ûZÊ5HoBþ3¯,†3$œ@ßë„ÖËÛ©zF©õg5fïevÏ*êøÖŽlÇñóãŸÙñ‡öÆ8ãÙf\¢»çÇxšÒ¹”šõ]4{Ï-ìªæˆÆÉ`l±Ûƒ9³ ½ñóÄá!ž¶Î$ž¡`M¨îÑ<rgJ¹¬=¡[ÎDL+»oj×]•¦‹ÚÆOÉDB%Ê0Štó œ`NQ®fk²x}lžþ”Óš”\¦á¥ÖYÙ/,-oB«ª5bóR[ésþØ6SµV?+5ã¡yqü±dÇÛñûvüÊŽ_¼Ó|Ú(y+ÄÌ6;ã-bm³·Pu¢Ý‹Ášr¡j&LéMò C`³œÙÒ7J7ꮜc­p5N[#VPÝ£ûi¹Q¤5‡†ŽŽP^¬+^ÐŦ/ŽÜê4fj¥Â 9v‰T# -Ý-´™»›œœóÓK, ù?!§N܇rè'l:Ѽó’K^'i-ÅÌÞu¶¶5s|´ã³¿°ã—v|cǯìøÕÛôñë[¼ìŸÐk5•KÂ/}[H;Îxâ‰?⳦ZHa-u.ÊV–Þ¶^å}–n†rìÆ†E÷¨E¸»Ô’H6’êÌæâb’°‚š�� �IDATZ¿8ä þxbÏ !~ô“^Ô?M«†í3öT™Ý„Ýr’s‘m,„Åêá…Á“õ’Õ[M†ä“ì·úúR2¤ö­EØ›Ìà/ìøÚŽ_¼FÁ•à¾ò5„Gøv›‹±çÝA/ˆÀdcÈÛ}Öå,déóÄK ˜ÂâCüc•Å;mÍÏðžmž]¤Î¾§›‚]HÎÞQ|—Fu…—-8^ÃAÜÉFCc­’ßïá‹71´Ô÷àÆÈtcÃ;æƒŸŽ—â �”èÍèÄóAlfTfo> gðX5}„XÏ—UÍvu">Ÿþñù‡õÙŽö<>ý`yüiÏv·¸%ô™|öCÔ'lËeÛ¿of å˜`c‹æJ˜Ð¬žÎ³lÂ60Àt+§ å&…ZËB¨¼!hïÇ'ŒÍ~iÐV›°gÇX!§‹7uºeÖ B|J4"C¸­¯)æÿIû~â–Vn6’ e,R•ê=ÃáÜÇ[Ÿìøæµ´.÷³*ZcÆiäxž˜çK­}£\%'¶˜÷N!÷‡�vþ˜U3’ºä:¿ÂñÙŽ¯U“ilûw~â¼Å¨9¨e®ÍÅø¯ðÓÈì*´æé¾©¨}­–ÔźfMâ.ø ýž¶DPÓJ_ÓP^c•ãxW -#Ñò‘À¹}k*Ku3&íµáÙ@Ïõ)lß=j öøÜ9Û zË…Âúžo„…ã—v_Çxüƒ·´ýœ^)‚>:‰…[pªßz]ó7/ÇS¸ýÓ=­¯íƒß’ÄR7+T?z}ý_ÚñÙ6œÐò‰]þ5 X`BëÝ{TjÞ© ×Ow²\Àa¤‡}ñ±s¼1â]Òº¤Oßš³lyáX¨ ˆn‰3ø¡<L8$þ/üÊåßdú ë\aW\²ÜùÝÌ@°$.*f³eâ¯õWÂÞ·vü©Çu_?“N¹ÛUÊÏCp¢…¾:oæ#ç/¾M¶×>¾úce ÈðöŸÊÞËžu[™} W{ú”â„æäK¥pÒá'‡5éØÏT¾,LÜÄŽ»Çß¡¥Â,éóYäó+ÈJå9Pâ=úaév©OVÊÆDvo¯ª4m—&n©‹¿îæ-<ózÅ)`„°R’Äš(%€Ã@E,݈ž:OhÂãòøü‡úŽã¿<ŽÿAï²®ºÐyd¥óy“‘³´zÓÉ}±ãï¬I|Ù ­ üÞ>¤ÀÛ­*ºí²ÀÚ1럭ÙFÙ3Ô.ºˆÑ‘¯Œ‚¥Û–&¸¶«’QLØÈÏÂÀÊÃ×÷ÚÍ»ò½>VwÑü¡…¼‰’a" 4ó»±á…ÌÄx%…T1™¯ëúäD÷ŽkFèz×àù};Ž¿v_Ç_?þø‘ ÿY5-ÒƒØ&|W-Œ³¨:ãÖiGòÖÁúl«{–È Â§ãK±sÀù,»µ™ÐjqÂÑ…,rpe 0Iïr丸—H¿t• Ò)‘´…ÕŒað™þYY¾t5ãgcþ¥!ÌÝáú±Šó£D,^s„Ü•ð»u…é,'ã¶r4¿jg.väÑ–:{|à¢çéˆ_|Ö| (ü¯Ñâ[;þ‰lÇ·o…ŽOB·ùž•2r…W·‘³™tÊal\Ä-p'ÔxH¹,K uÖéu›hSm€¤F™xw¤Ë>×Ë»ŒÁ%¤L¸�¢‹HqvEVµ. ׿·ÓRO;”u|æ¹LÈô‹ÏÙí¼…3øû²áÏVad•yö™¡†Ø±ƒV \ðP»…'&õê¤÷ØÄ(ÉkÀ8 å? í†ç¦NÜÂÎâ›(ûË;öüf¹ŽI­¤Ä¬~i½Ÿ/eò7[HÝd]êùÐáúM L+ꢧ›ã—•]¾–ÐÁÌ Ñ¯cÚ.VWz3ëÐ#E˰K>,4:zÍ&V³£©×ÇúKÐa°él‘ Ã…ûøøÔàV¶•Uë —Üí>©,¸– xËÀ¢Äñ·aÒmOž²¶-ÿët*Ô½SizyÒÝPÙ¨—VV7q&qZ……,Ó9�ÎKvÃ"g¹”ô„8Cj¦IQzˆ“ƒ8±»m”îyËŸˆ˜°$Ea·‡Ò:·KD­¡+xQžàÝGÒ È‹—v>°—¨»ßB/Nø[—cÚå‡,øðQfÌ:-/dLdZÀhâT¡ú*d{A]ØÙ2-»Zœ?vÒújýerý0¡ó‘ù§n[¢šJSrèor‚gmX–Vm¢¶Ãjœ P*”dñ°ÏëWËé²dKòd]Ÿu’$™äóHOècuCÈ•ú#UžØX‚RMX ýÃRn•³+³§ÌHéÝ“~‰=,”EµÙ¿(MÝÊKóž^îöœÓÊ‚â¦ÛdΨ0D•C¸ rd͇>Î\†W:  ¢ Ãâ­gZ‚“eZ36_†e \ÄH gà°n“—åf·àÓlFïÅ÷ü±®+n]oF²&ºQ} ªN’£òŠV&Ún@ÏóÚ2k×!“œ•Ùs„<xÞÛ€ÄËöÒæ(ò¯;êZxë¬Xy<,ÓõjZ£²G)e #ð†™cD0¾tüê6}gö¾åf'[ž¢ZéØœ å&›ÒBD³CiÐA°Î°¦OÎ.±ÛÇ*Ög9ºspä­T@Ÿr—û"ú¿YŠ FJÒòpšÙ-àwÐñ·š»SZ®®ÖÄÛß{·¯¡=(ºy…˜ô•ÕÉ<ôéðÖ/ AÚlÝòÌFw+Ǿnå¦Xy+Y`[¼["WÈÓA'¸+ÇÑ9mÖ<–ÞèÂBëà=*Q…ãh$z”dÔŽ[[’L‡Ü5!15ËÐ¯ÈÆŒÊòT%Ëý=«ÍáA HÎæ3žp‰·ÄßÂt„ÌŠê¬P¨ÖÚž]?¶k³¹Àd»¯,&²´Åtä©Ä�¬‹1ŠöXøÝµ7B9X&è Æ”ºàŽàB$ÖÑ!VΤšô>8­ª£ä¿X—Ý^Vµ-³µ˜í¦<Wì5g?PîF—g2K]Uˆ¼•¨Ú¬‘Y uüWC„sjâkŒ)w]øhBIò Xˤ¤Nl0D9Ösÿü÷Êéð™Ù…¶¥[5"*çäÄÌèÔWNÞ‹>påÌ_&)Àk>ó3`ê¹½x¸e叿ÍleÈèax˜ôj¬Á<ùIn=¥;4a>(¶4-gˆˆC·Œk­9Hó+±én¶¡çZ¸ù¤†ºê\­´#ó®ÌúI¾ ó<· Ô ƒP¨rë#49Ç52ùDßpn5޳1©,Ãi¹€gxéSŠEÃlñÜCqH¢hhd³Ò¶Š 3ƒR²0d·wnhãf£…™×"!nÀaº± ¯�ßÈJÕHœv‚椂ñ”µìpág˜2‡~ê3Ìøô¢³¸Ý“uY ’ê#RÔš"Y.›…3ø®"q`…¸kkeßš0ªxÚÔ:‹ZoÁ…çý“ í.¹yU9†Ø‚sfdz‚š†âsäí„ðŒd­à×zAî/\>?AxÕžÂÖdáÛ ö’àÇu} ·NÆLF»$[×F*ÙÄyF«í–E³–Û,7c˜ûhÜIëO†}Øm"ØQŒy$(IXoµ8D@î ãi€ðC�šT•ha÷†ª’Ä^ÄoÛFÄÒ3t3™»lå ä‹ † ú™K²~lЬˆ˜sâ‰~Y—_1Øho—K?|ÓìL'£cÂåË—VÞƒø•hûAõ*tQ+D¬Uwꓚ¬(ÿ‘ü’!tÞ·(E.Ƈ8™ŒÌ€)2¨AÂïQ„Ã2rIk8lSLMÐh Séž‚¸µJSùrB«$ÿh§5qI$Íê,aß,Ø­OÚÑØ=ɚłƒ't<ÒµÕñ"µT(=¡Œ.ðXZ¨dE<÷u|Êÿ¡‹•‘ÊÉxv¢ØtáxF몷”ߨ¥ÝY²§Z@ á|y•áÌL@$ßþàê–ÎåYßmCøçµ¢Ð~ÂÚá=œÕ<t‚žDðgEЪ!Søã†�ݱ4è6rfÝ‹Ô@L6Š 0ÝÕ‚ ÷$‘6n)j[%æÛÅu-o¬zýKØíðÙÌæf–Ép±øHÖ‚Ñ=CÉxþtÅúN¯Æ0ã(ˆuZγÑàzQ}BÕ³h¾BTٜ̠WÒ=aZ™G{‚˜ËÈZÓk ¥yhtDc˜eTnµU®4ÞŠ8cIŽ,ýôÁO´|ø rצ¼EZèÖ/ÑLA’ÁUóÉ'ª–P?BrZÜoÖŽž.o 5±¤‰k`¼Õ#Ü#-r¨COø`  ó§Ìú)ç lƒµjAS‘y’VqÜýåàø±n £ÍŸÎšk£ù»ªÏvÐ]`ç—]Ólé‹,2T|àå)ŸùФ5‚¤Ïüp»§�ÌéJPÈÏú¤5lôà§÷lô?ÀÕ¼,§ªC#·V[‹Kñ†'—Ÿq¶' Nàvûüãv‹MÙ[[ㆇSúY3Ò°^©ša•.—nÚ½z5ÌTšº´EËMWy«“€äŽ<וq€.òÏÑÖ¯‘ oDƒÓ„wFÙ×Ù¢7˜ïV Y¦/ Óõw³ì>ËÁýÒÕ͉ÐI™4 Èr •ãµí= Ã.šÈÄËîò† �YYtâõg¡) ?Ó»1²‘‚TF.¿Ùe¨¾õ'”‰ð7áK‹¿¤K‡hÿÍ9Q ó\䣷¯Èf~³]Ïb†V{„YðjN10t(+!q¤†½@"VD–AVJ–!×i^�Ñ˺âáÅJ¨Š$¬Z½­†Žè%1(VZVD™3V+£×},¢r+‚âZha˜5–º×îÓîä­à1ÐâßÖâ¥Ï9~çn#$;[Àõ© ,KW­)fâ T2Æ�zV¾ ¬œE–jýÖ1´º€ø*œnÑ;j@Öçf‹b¤¿Ä¢u¢æ'X³n[c™rÿƨÖ0­µÚ¥q“®É:<ßO•¬î®ŸläöÐ.9 J S³ y ×¶¥Æô3ËfäãiØ»Yÿ¦Ç”Ÿ³U›5ìväÇ4Õ‚Ôjå‘WNÕdÞêP­2«óʤ ªè_€hm>¡'/ÄT†-´rHÁ°H«É7®Ê_ÐR´ÏHæ.¡ÝÄ£ê·þÛñ#u6Å88­<«ÆÂ[t]žÄ2ª!BˆèÜg0¸H[éålwÿñ[»]c•ÎåNë+š€Gd‰¼›Sî°þü/ÇEõW«e‡ØÞZâ1lz[ăÐÁ=`x~Ž(%j3 ͉‚uëë{{-žâøŠ¹ti1g‰ÂŸ‚U*>Ð1»!¥W5ÇÏ!`íSXeÇZcb&P00Ž€lÞÐZv�ÿð!Tއ‹§¡yá_.SWë"6úk º9œ‡'²’åþX¬6‹÷¥øEnH ]‡UC×¢rîO4l[é®™W-_v,ø#^ ) ¡—ötú[}mØf•|e›”õ¢97ÀôÂ’® ¶ù¥A˜iÈÍNèÛÎíÐÈz÷ŒÄpnAË)œ^í jöŒÏÜõ#v9×Krµ�e×2.$ž•Y?iï ¨aÜK#zk$×ÞÎ÷°+QZî·PîAW smÏ+NùúL,9åP$WädúøHã‹ç{B¬- Dßgݧ)5ËåÝ=s„õRn£›ˆëÄÈUO8œ•:3†ðX6únô±àR+ÝzcÅÖçA¶ÊêØÑX ™[$_9k×—íýVšI Á0ö™×–4o…SÏ\®„¼Ä¿-R€ZÄÒn ìå^I­¢Y[vhtm §¦Æû®µH Ö::ËaAt7s`]ô&s†;ÖÜÈw¹É£|'æYê Z³#Ê«òr2`‡ͦ®ÆˆT)-9PØ&¬Wô�ü@(–G‹l\©l³uÓü,‹/ –<øéá»pà1ƒ&\®"ÝÒ[É2÷,—Lî¦Tl=íÿËRk*�’ÖÖãû‘åÔ¬¥ÒâÇ’¾cÆèëäˆ_/[!ZlÝvrÊÁÄðWz¨ 9MÆZË­ØKgñ\<•YÔòÁë~T±Ï}HðÇ A¢ÂS»è4w}ANG¦¬ŸíLMZÙxÌ!§¹ì(hBÉQ2gÿÝýl5aÐ33ü)†Áo– ëB°d”´¨D@‹FÝÀWAü€ŸÜÏF-}5Þ:Áò÷øy¦áù Í‹ í$±Èé“!ãP 3Œ(;Ñœ‡+>õ-þÆ‹y‹´%“EéžSW”¡ Ô^YŠGœ‰S„§g«¶+= ºé9iŸlºÝ4\Sõ6¥(ÒŠ(‡au`Ö@ˆî~‘¿JwaúB0sýe’ÿ%À8hÕÍÈ1Ur±À*BsÙ»<€ùñ—Ô‰ ¬®ÆÆ—ÐÛMc²ù°–"@ÉT†å3E$£þþ+êT–„f­#" Äk©z–í¨,œϪòhƒÊ„¿ÚÍë[ E¹f®€+3:O+.éZ3‹ú,–s FÙõ»–ÃA#Ý"t¹ó ‡åÊ̾ˆXå§ä-ñ4²Bá®^íö¦â„Í ¿ „\Mí9'X¼B¨ÄJÐIûÍWœÅÉl¥ŠÒ6ð[2 Eõ&.ëßC�6LzÎ×!ÆI­‹–ý<œ¬âùYÉÒÊÈÆºÿ—QduÚ‘U„°Ãç‹õ)¿bËA—V;“DyíAÊî–TºÈÉH!q©ÆÚ¬t»B“†y’2ð•'ŽM&…òèYÙ¢ìÎc᥀æ: ´:3¢õÔÐìxÚÉæ>Uš­”0„Iõ5ÙóÞF5¶ya1m®@uW è Èó”Ù%¯ ÇňxcwËdš#Æ,¾HZ©Ë¾s[•Žw]¦†±ÙÊpfš-ˆèKJ¤Ý^¶ÄŸrµmØËѰ^«¿õ],b×VЍjd_ôº ¸¶ë¨9S;µ‘Xרµ’cH´ûºŸ'Ð^#ÖãÏeÃF[•3›Èö‚¶9mñ›ˆŒg À/Q»ò­Ë¶{"¬‚C”pwspÃ佌Ê?Ë+·ó•ü)§¿ª„»¡Óû1­Ü­Œ Ö§ª §‰ðúœ.„†BdÀ$µT„“R!‚2é0›Ò+ôàuB-q…÷¶{dWñÉî¨1ön)iCØðë“‹I‘!½ŠÊqfT@†, p¬­3AH Zð†æq”–)ÝaÄnŸ»…Ó\I»^ â˜ÒJc5»$2b'åZhÛ æwïÔ,['oÝMØÉiEò5¨/•±Ñºµ¯'(‡yŸžÊ*Ê@lÍF@™•ŒÃŸ/Yˆ"5&ÂÄ\ê­ìŸÍÊÊL^–GÙMƒ2}ä\¾Âgæi¢bšm4q$jy@1é˜ÅÚ2“Ö£ýB–“Ï2·ü]¿¬±<òö$¸ï­H*ÃÑí© Ý.ÊV¶8D5²Fð|öº:)ÌœD²mÓ¡¿ˆÑe§L6JªRK¼€¯4xÖpÀK/Ze-Fò­òˆ|| ¶r%vÎì-ç‰~¡.>2?cÄÔÒÀ^c!ÄÚcð²YEKÊÓV)²m—å‘B *|ˆuKëg·ºð‡Å(8ì]•ˆó ºÊöF9~x±0‡V¤%Ì]â⩉|JH½ÍðkX$YsØev7ƒRh(èÞ!W3 #âiIOØß‚·+Ô1iäWÁx[Ø)ÁÙx»t°¾çhm6RF)aÃMÚ~\ábІyÌP»½4´0ë ß+-,a™)zÝa;êY÷½;ÙS¦í-ϰAN§3k!‘Õ=O[NÒƒÌÒLQÁhïWÑ iédê¾H–Ÿ>Jðì˜Ó–iÙ3ê‚ðd¬G¿'…o?ãå”63öêÚWß"’õ’˜ª³Tvwtƒ­ärC†!áCv{=Ýx?ŒX¥ô?ÓKxªDf6¦Ã̇#]qRˆ«À>?çg_éØ>P¨Öz±[f†s$êÌnQò€Ê£ð<@3…½ò¼ö^cX2|ñns.ÌBH ÒûBs§£D¶}2Öõ…ôz#Ü}è0`}Û¨o¢Í?Ir¬1ñ÷7W­±à§WkæE8×¢!fÀl‹kÔ“5ÄÊdŸ4N¹à#±[4@hžÙ.“aˆ—¬s«é£¥ær‹ØvñœÊ2îK'L3õÊÏÜàHúõàÂÀ«ÞÕºsÆÅÍŽ{x4—-¥–Z–Q…Éœ¸óD§Š ç®÷¶Õq€•\vç[X:A_¹�Gh€6̆ìöõv” žb{ëü®…œÄ çKû€06ÎÉúÓ¶tº ·Ó3´!Ü!|º3|â›Ñl0Fʰf…3:eH ðØìhóR áoÁ™<(ú—-}Ã9nl o­e<OÄg ¤ ˾îFÖb"­ePÆ’YƒgÝ›zt·ÛaºÒ‘²É>Ózî¡‚dD¦[Eêsvv øìÏ/,’”ð£Î)± éf{ž$ÎÖ ÕÍp±sÆôr»Ä¥î žÆ‘ÛLJ±5D˜ñ¢÷©Eñ}&Q¢„gô”^@wwwåõ‚×7PD2øìüƒãk¾ä¦‹§D,Éž-Ÿuøy„÷´Iµ”ƒü¤Æš=P ´µ„åO.h‰?ñ¤LÛ3Ԙ½F/K¶.)£‰÷Ofç±þåª1C6a—-¼VË �zŠ—G†0;¿¸v$!›ûq‡@!«¹g­`'ˆ (ûÁÎ4\*¤8SJÙ.›‰'p:4ýáí¥2д¸ƒ<é¿ —¸‚-è†1Ôf¼äƒ‘W¾ØöV‹‚QÎu…©M™ß]‡¶ø§Æ ËC–ŒÝ”mÝ´€§‰UŠ_zú‡w¿ËÅ\Îߌ×ÊÇ­ üw)kÍ.õJ•©‰1ºTâ> ã¼| HÀ3D¡v«Þ2á.wÖÔ=¤ëúÿ–OùtGvDB¤©¢­ÙÌVê 8ï[ô2åÌä ôñ—&e6”Mnê#FÜO½Ü[M©2„Ÿ/îá^‚sNö\Â}‚5•G9œÞË1ß Íd a⸠#ƒ–Ý©¬@ߺÝoJ(\€¦U•ùnf¤y"ð¤ò's‹#F'ˆ†ßKjŸþZ®Ì1…N®ŠËsƒyÑ`²wš °x­»1 -„¬ƒ{èûˆ%#‹«£G¥lúBóøËûl˱²»ÃÍÔ K·ú,²C!D(:ÓÒ,…2¡2 À˜r£enå9v2æ-Þ*T®Wf‘›2/ZØ]¹æf³8¼;"ì”ëÄe²h8þõ²äÍ8r|—úL–ÛÖ@Í×™x&РCÝ9Ù¦]V3»&1Ž36ÑMuªIë,½¢øÎ*K.[è5-Ž©¡$¾–¸­¤‡üðöÒ Õ0Lå/ih]=OŠ DB¯„%=ê!* QÞñÌ=<z®L³[“(¼à1÷,ý˜ì³‰3KÌá(ô`&Êm>”#Ï!lÉ×ZÓjYC÷]eE‘w>«íTæ ò63 ošpk†«¡Äx9eágóE= çÛøl¹Ö]¹ûJã+.•ÒB¡uÉ>‰X³ ÙçdXz ÁÃ8”'(åMKÓqä&',éêkláúÈ…5)”Û¯„tÄ2KåÍí0«²¯TÕVIïCATt}Ze–‡?ÚLö³[Ùw9…Ée¥J¨„% ‚WF‘™$4¨ÊlLˆYðÄw½-ã½V¶ýœ«ì‹BHTÙ6%ò]Wf´Šý² y¢TKφ40àÑ<ÈÔº‚1ƒ6pü2à%,,‘³ZvÝÉ¡Åìµà;%¾{Oj>ssÇÏe-sU\xø’jQ.Àm(bª¯–V :ëDŠ™¿R¦®äÙk$v“>heŠW`-ˆ–‡‘¶›|>ÝB[¿)òÇÒ‰§Èâéž$\—üá]´ºÈÒnå­#ž+Ü9 Ù’òa»e‡#r ¢K& þôgcÈR#=†²n–ä×ÃBfE#ibû¹ûÌwClƬ19{ãLþ%LòÆc弚À'Kí6²Ñ½äNØË~ÕÍç±Ä2Õð”àÅ8Ìõéé}°Ï•ÁèCA6Õ&^^6™H¶‡ɱrEëĦÌ“6q³“ÅŸ-Ì^µÃ -lÑÒ›¢tǰ¨'DF,÷ò.çm[õ½ay’””™zwÀ+ƒÄy(ʺb¥˜rvp¥²‡GÚZݚ̺š%“v³¼S²p@/¹Ieg¯{…s©e•Åö ˜á¶™[Ê(¤9/ñQ3ñJNÈ’}2ÑNÛâZ»Ú€ÊC²â,dÁ”S«áQNë‡.«K‹R# fr(2bå H¡j¥ü&“¬Ú³aŸJ“‰NŽ´Íºha8DÄ›‚G€v!tÒ˜)gl»½¥ò>ÂÙ‘®•èZ ¤NÔµáÝ& xø 6`Z<JÍ«Ös”Dz�ñû©F¨íK*²{Kí"‘4„êai!„¿BNš~èbûC VÃô¿‹‡tÝZXB‹aqýëèš;4Z"ß,VÎéÓú]´gé >K±Û:m=r††™Q‰#{–PóË™p"sj1hÐ c5\Ã÷XYÁlwæÿvî è7Èm�Ãs¶áZîÕ²=}H—ùyÖOÑêÔ –3³»³å*‚_×7"+¾ÃFYaƒÞ*}º` 8Àнž3Äk»óBú!Þß}Ð Ÿ·~6&9p"ÈbUÉ"Ûê¢b'°MqCŒ™ý@¿ó.:Ñb6¶ØÞúõÉ߇NÄ8î:J�� IDAT…çA3Ïh˜ii¼[‹h­RÞ·+“¼™ž·UzÇóœA|p,ìžEiPnÀívÃ帮qv8„F%±Žð¶k¬9¢ÛéáD;Â07+5ç)¡FNà*÷!­œïÓFéœ!­—‘?¾…Ö~GHœmý¢1¦¨Žúú¬›‰By¹AºZyZ9Ó?DÞÄ*GJpÒk‚žIjMúwMÙ7g8Q0=K9zÕ”¬–mA×údÁdEw>{4ß-# 6}çƒ7i Ìä0jF|˜ÁMÖw—!‰"‚t�uŸòèjÒ�§Fëá¶È÷O4ÊÒgDY¤Î¢o×2ª5eØ`W<²®6T×Ôg¢v%Ʊ(‹˜’é×jjðùáÙÖ:ý£äÍ­ˆ¨hÔ‘œ8üœ<«(³þ[K4NÆÞÖÑ–Ïj—Pd-¢Ë¸³Rž#¤“ÇIŒÝ0fl¢6tDlÉMéD• ¹’àDZ <³Éf† >“4p¨¨eIC*<.ê¡ûCãnЕŸ/Mª`®@Ôž6¥Jq»ÎrNû^çJ”Zw™|àÍzÜO—qlVïP˜‹g´~¡æE¨(Ú%L‡@“ÿs©g¬†™M_ê†Ê üd TˆI™!ÞŸ'Á l]”Mfˆ–ZW‚¦˜^©ƒõo•+¿ëä¢'3WL²&7eY÷^œò¡.—¹!½^íÕ bp¹¡›s&’ITY¯n@׿–­GF�9Òþ}µ.¨„YžØâ uu†×[]¯„ò“@} ~‹³œçàpê°…xÝï” Îâåí‡n¥K3Èٚõѣ@h&¾zæ`cÖ¡,S©¥d"&ºÑ ‹ø²¼Xƒ¦×ÚHŽ¡œ0ã1©+WÝjé9|}}’/ž Ô‹,ü-O°ÛÉc ][d‘5Mž:± „ãå¬CæŠL“„á,g±Îȧÿ™í¡xkÁŒžyuÂÀÁUxXl™ÑÂ$Ô-2?ÕEƒÒk<es»ÐPK§ ¿á”ñZý@3ÖBcy¯ÊhT’Œ`Hgœ°BXò^q£dYûÜåtä!è]œcý­‰® X¦‚—pY¸*áTÞöì ØX4€ NWÌ#ÊÉÙ LߢR-€äW‹¹;¨N2Ï*¿`²Ø–Õ%„:N;Hòƒc)«8>„¯T¹b.‡°BFO˺ëŒc#™²E°ˆ`o?N×e–&‡…àTV+oÝÉì)Cÿ©™à™½sv»(B½rë†jÎ:ÿþzÙÁLľÈ$]æ=›1FÏ=ê®Ö‘";|­'2•¶ßñ Îòår9¥+ÍɤoÙÙp»£RF²%!?aût V•„¬{-4À`¾Uv›º“ë²;é‘¥¡Z»¶ì8Œõغ�¡ê |¯0A‘É1MtÃņ}Ùž=f ª’gu¾¡Á.ÜZÙ§ÕT±.'›ËO„ñìŸYoFLjÃƲ(áGçZxЇ±I¬ð°˜­4ëÐq/1ã”XÜÀtÆ7º+ÇÚ¶ß-Y*â™òªnsvõùå™|”} Ùbë„$ì ëó ÈtÚS¢`È©k,>x¥ÍÓ2MÐytÆñ¿RÞ•bÌY¡Ð]D—Aoþ㥧”<¶Ïà½qsº/˜ý/’Í=tZ·ý&äÉ[BÊõü¼‹ÆuaŽ; ;Ý„ïRùIÖì› e¢U¦Dá%bOy,K_ˆ¡•˜ºÒÛ‡‘·¤’´]�œYQzAøù稠˜8€˜5ub„RÚB’G« µrxÈc8™«…žWð«A_ñÌ…8‰¿±:×S,䜭¤j}Fëj\£×õü±¨–qËôÌ]V(’7º Ò³ªLž‘|b}šúî?ñiÜk§‘lo“ siãy2¾È×ÕHj5ÿÊH»}l!:8³¶¯dÀšKÛR\éëB¦âŒ¤;ë—´ÎS­é~1ýÉ0%=[FÔERÂMZ€v‰t †4JC/h ´8^Þj,òMa-öf ™C«s™­®«§áÑ—L&-[·­xIvhù °IΓ+M“²'‰ž‹ˆEÄd?ëðú…~â˜ÍÒÿÖ–ëŸA®dº>üËu~þz†;8þfŒÞ+¾Ý¥S{)�&§æÊ2âuU„öÞ†)(.Ó#†…4àz‘¶„7ºgZ‰—Í’f_ñwY`жÊ:\a² ËMƒ¡M¼Ï€\ÿYëÇã±¥QV£ÕÖàÕ;ˊ§…k‡g:Iº¡6 œá$&ÞÒß®ŒÖbϨ†¥ð¿>åø¸>}‡cp°j£¬.–ÒªôéöˆXÂ\QG¦Ònmû²0ËáõbùÈ86tÑØ­ÍkýñG²€³»Ï¨ :5PÙ`œÜ·Îêõo.i^p9K˜°{o ÈÜ][•0µ Åh–•ˆ$‹ÔÑ0 Ž“Mȸ5,ZSI]ªzö9ÇöÓ-ÑtëH”=y(~š½ÎªVîׯJÇ !,¤f5=ÁKJóÀêC>@é± vKi…œŸ¡B˜^“¥p …RíÀk—Ĺòs>ÇÑQ¯ ¨þ©1q“Éò2›ê&ŒÎÖ‰ìÍ ÏAŽN¸(yF)ö”¸9‰kM¾,¬ã9к~Ó#Ó’áfë“hœ´ìãƒmäìõ“w‹ÚòÈ’ål° FÓ±ì&–K±¤ØÁ"|zĪþ±xw}“ýðßÀÇŽD… оo=v;O¨[M}@è<B«?øÀ3³Š(åMÅíîƒeL<žòûóTXj z·gÛJ¾Yi|VŒ¤Í{iFuvWõ¼¹¾‡Û4!µ’åA ?^ìøTg?c} #w’´«S õŸçŒÙ3®¶(.‰«œU“g*µØõHC¹Dù.¢#�I£Æâ„¢-o‚Åò21W'û�oåNH-ÅëH³À2Ž,—§�8›<(±G"ý€Y'@4]H¤ ;²o´Ž"¬Ôy“#ÉezNb¶B?LªN0Pè+Zs^ذz¤^Y°ç¼ùéƒ$Ž%䧉3¶m·ã%hD‘ÑšJ‹Î²×VKüQnk•K#5t e‹#!D?PG R¯tÓC.µ�OðrÅ“”¼µ'¡I(TÁ°DY h÷Ð-Êmä)NÖqbÕË Û«$[,“ª K–#÷øÏããG-ïç‡Úç|xKà³YBIú àï›…%ˆÚyW”’‚¨ÿW™ùi¡›·Z6R''q‚šðnfã‰ÚíÙÎÑæ³ÐPg–€[nôàψx.÷Þ&È•hÁÑ´lCrù]ýÀw»¦IS&æÝd…ä=bÈF$¼j/ç= áeœ2†?ã[ƒÙŠj Ý–›xYA+%h’–¤Ò“dB?¶Xf°PÖ¯åím´+,=³r‰‰¢|)2ÙR²÷îk«Œ±3dö¡õ0¶.óðÓ:×ZA¥K˜i½‘n“è2¢ ì `·–_xëîi*A–\‹¼RMq:x ‚™aÚÓø¥8{S·ý‰L†®¡5çPÔšzÚº\0"ØIëîA)ˆ÷ج¤ R‹ó¦�!u¼G÷0 ‹·—gƒÝþ„69‘]o½9.2Æ-¥²CV6…ˆixðOµeÓðÜ×’]8W+°¬´‹+tÞRÜKüúÖèÒ†HÚÖoóë6ìriÍ"­c9é÷ –œUô%ݹ,û™I×§QT¢<$#}P@•ב^‚FÖ­ÈöÎ%æÅ€ÄâÏ…LìdÆÉžÍÖBluÔBÕ†ÌÁO×(<CÔ¿5­,§Ä¸/­x³/¸µ[fÝ>žÒj˜ÍrŽÐ[¯…þ•Ϩ䔓é|-Ã<„¬ngȰU&eg%ûüºIV#ÚœTɼsaÌhÖy*"Q —aT WDTN™ãE�iGͪæA« KòБ´Ò³KuÉl!ð¥ÿ2œœƒn¼%£µÆÈ­°;)‡xž¸äf‡u¦Ç#2™7`™Ï ¯ÈÁ¥;ß™h ‡”™V«V†õb©x[êÎp⸦¢–ä‰²ïÕîcÁã�úÔÁÑQ>qR*r^iYuW¡õ]!Ê<E<Ý•«ùëÖ슊Ñq&Ñz}TÌÄtw àdL<ºŒZk±|¾Z ^_·QžEw‚2µl—¯p÷u"Ë0H®Ùýä)?pÖ͇ÀfØÛ@Æi}ßK*M¢ÀïÝz\ŠÞ†F-ºYªþ^¥d\èZ ­›E–èY9Òj±ÎÊYc]åÐO?kÏÌæ7a­B:Y—»Ï»Ö׈±ŽÇÀ@¹›«qä‹Äë"&ãéuÕ$“*V´-|ì_¥ÊÉlèÅì­õ]HɇYs*ã½Öð †q¾›¦qq3XHÂ,LÜbMVôl"x[Äš Çqvªn³Û³sVlrÿÊ~褋E ‘˜9u³TBe‹µÀíõí2Þ°Ul mÍNºÝžP¹Â"¯k–]Vd‘g%<H“Ù� ·–“ÔPsŠtK+=C”ý¢‚½Ifw5VæÚíWh‹§GI¥çð¯×-éÌ.vaØùëÒúÙc¯ÕòeCKœ?Кƒš¶–KÚhÓ­Ø=ý8K«êïåáB`í2‰1&¤I€]·Ò:€ï#m¬:›‡…ΙYÂêáëjÒQßÈS‹\"a`ëÚÔñpKk,Âk©Ð‡¤"jyÌü´…œ=Î:!¶u6mé‹1kÕð¢¥.AŠ'«nL»:F>Ô.é‰ä¸å¢Ï\ « Û¶z áëèBP„Š®n$<F ‹ˆ°І˜ÔžÎša\LîÊà›$G±¦«­x¾-eóõzš¥·÷�ñéy·;w1¥80uk‚™´„ÈJG˜‘Y®GW¾¬.%Æ’ Ç\Áœõ„ QäY—N˜HM™=ýrÈ‚ä™àKÑIçi¶à[ÖVžJæs³zE/ N™ŸJ×4†Æù~+“dÛf“õtm)HðĽ­y›„ ŸMË¥ë¨ò›BDÃJ¨dÖ@‚�«Fˆ²AfÈŒï¢|Žmö¾ýÈÝÅô]ò::Òö¸^™ý|Wö[gÐ3ò7©È[…~–[p[ýE66–êæ²{ÖW"F¯!I$´’á%,ÏÏHˆ…IxÐ %Ü®X-ñöÎD®º¡kL^oµè ¢Z©9Tj­^‡ ­Cñ7)sN4ÐLRH`|þúÃñ]ƒY–Ú(™AÁ™å‡P›œ­R‘óuÅeººÉÜ-úz`·£ÊNŒå¾ÉP9ɘ–që0´|({Àl)/„‹žÈÖÅ:2É•*áf8ÌXȼ5k —Nfô¶r¨,j¹Ÿ@U‰fG?ßT‚©¡ŸQ(íq½°h¹¥”'rVâ·šÿc§Aq‹9 urêsuÊL±¥ƒÅ1aÿ<"§ ¬Ðò{´<±±Žæ�)nˆ€h‰ù÷ÒM_Òqìz’Ôgv24”pÇ];ÍdáO†q»Õƒ€§uÄT΀}žt–Ð=Dü( ï¯ Ðmn°^ÈÜã,SýgâçDšd]Ô(ü¦YÅçdwÉ?»:O ?íòÌ{‰Ä’£­”&à(º¶çëjÏX÷ÖVP6 –VƒY ¨×<ÝãÙXIê™i®ý±Ê´b6ß[]íEq`uÅI¹OÝ-)õ§CnV»”Éš–Œ e®ˆô <„4Øf‘¥š’'µi6»ÍÝ~ ô;¢<ãl‘0Öàá¦mÔ™×Ï ¥œIÄ=å wºùPXÊ—Ô³R`ó)*ne~P\C® |’½Îz’–üÌÌž»#¨K-ž½÷èã@ÿ É…™—%³k¤<~ùf]£3 MB+…EÊL¼•ë ÇêÖ ßXò!|T¶�góõÙecdᣄa[€êœÞÒZ®Àb—cû\Ĺe ®½Ö—òŸ‡óŸŸçúÝÁ|R›r >ñ†Ûˆ¨'²½z½ÚèVlOñ)0,“‚áNÓÞ•Ã#<u–ª‘·ëÆt[Ûàø&5[+›1Û§ xØYá…ZkƒµþRAA½ÿIL6ŽžC0Læ$ÇôñÁ6iüÍk£»w¸=GXÍû`¦D-!·Ò²´m{ª›h^¤bé„Ï€ú ïp|jG¬ÖÒ@{V©¹V&8¸¡)Ë×›bwÁž20øGp2�Ïv|x×#»ˆ2½Lñ"ÐK¯¨rˆ²4]}Š¢”½ÈpžÖ�~X+x½ðZ"P¶6ôÿ÷‘gŸ!MSÆ.½¾báÓ±Žéböï5}JBßUÿágûDóBlþÒi"DWÂþ ÉಇWš™’ìilA€µ÷4i¥ÔüßÚ`-W·Ç±uþÖmÂD�òܲ‡•õ–ºJ˜3 }LŒó¡Ö Z>³vQèýGDx·[ì LK¢¤?o-á’–® >»5˜QÙA¢ÃéûÃoia\5åþ2ȥݪ t¦~Á–§�LŽ ’†Ô¬b ·zZô'”ÙlÅxuA¡6[¾¿k¿w|Øù $•öcUÐa 8VBÖ$ÔI•ž¯ÒdNçý?Æ&â eÕfÍ4/ZÈG™#j=Æò[\t3ÈšCÇ{,Zb ™«°øëÊ”v!Ú5jÛÝÇ(ô—ùhØŸ¾¨äâ@=%ܬ¡2öÖS:ÔuUŸÍÍKéþЕ;NðýA^*V¬Â<ºãÕÂK3W\ª×~UiÔ] åK‰ÖB ™®nz­Š—*Ý™[uOVIgUH– ,Å3ÙÏ6P!àÛm{µãƒ=@ìíFeDÊAS�~A"a5»™DÛSoØ–ÊßmDZÑëßOÜFàS„Ó‘ex±§kü¬Šê-|Œ·vZY*?ܵÛ¦ `×5änŒÛ<pÀ³Dh»§*ïQ“U=ÖéÏò¤Ö�_( V]E –Ky ¬·”âµçúˆXklÀ5ýìî‘Ô™Lý{¸R|6QMf» Y—UckØŸ 8³T¾ˆXš«3k½èˆÊÁâµ+íb ÓÌ Ù!ÊÍ|)d…`vO|NMÒ?Ïím²lê:Ï ÑK 1® ¦Ù=úEJåxÝ#á&ƈË6b¬ ”0»Î,pÒ®+Þ¡ç÷ö壴:^ìøC,]ÞiÆzÕš—;?ܼ¥/ÏuZv‘¡yã¸+¤gÕO÷¼9›f[]cµ¦ËnMˆÝkþ[kÆ[³\4}¬RÅ<LëºÎ“¢Šjåƒá/Š–€'Vœ§ªw½#Bm%4o@ç¦/"S¼'s”ϰ–ÇÖ$¶aN½oH]Xë *Ë¢Ïzâ?¢Ôñ­_¿s†Ÿ¡U »5Þ‡ëbÏkh›²4Ïj•ëˈÝ€g3•¦ßaà2ûû’±Új_‹(Š’;Е†:¤h´AË™o/J( àŽLÔoêA­;FȨ‚àðøa­•U¢íåi(¬ ÅmññR$s;1Z6›[ç´*yž¡¥Ç×›|¼¼r.2^>TXÐ,³Ö+±ën!exzw Ïë?Òù¥Z2Ávy„ã9K“U~ŒžÛ¸Üáx¶2ZŽ”¢Hš©•§Cwî}pß÷ó¢ûß`úĤÃù [õ¦cùzc7"ùÌÝÈD‚ôz†)¯J ” Ï­¿Et%ˆ,^XU¬Š‹|ê ;²Æ“à+»½D"UoëÃÈb¨†Nt%²P5xldå®&4³­n% ‡†`<»¹—û‡¿²®QZùaŽéÕ‰²»w¢Xçÿz1¤•H=éíe^û‘_Ñ ‚­ ü=­Md- 9ƒ9²W–M!lëÅþ^ÙoÆÖ¢k""q– „‡R9d3<âÄÐãí­øQ’'f·ÐŸŒ?YQÝ"v» ãÑ›x€êmùtí]Ø<lùÝis¯l“lŒ[Ï €I÷ŠXöúî3-2®7~F–Œ—µB·P :´’0nåL2*Ѷ̊H.Ï#„$¬óç¦ebç1«²›ØŠ‚¢ ]ÂîšLO¿ÌͧÄË%Úý<KÕð¶^”> µB›ÿ­¶?V·‰[#«ZçíÜpÕvÉÄGØ:Œ/"0è ÆÀ±&þF€O.Ö…‚Ÿ6Û~ÄÔVÜ×Þ^ËfÐ_i=Á‹IXf|ž”(™Ò|Ô²N.GÐD°1Éï ˾+µû¬#¨õtT-1C°·µ×N ¾ü`t‚XP`f:île„C~;ZÄøì!šìqÝ?víp&·ÓAÏql/¾Êƒ¥öô÷N&@ ó®„ö€).òeÞŸï-f<àºZÄËK'—ÉbF’*{ð$ôêZæXÝ®R©®R>ÙÖCÙ4Â2Ècû!b4†õ­{‚ñø*Ýž ¡r a°¼K˜6aFÿ˜x U†+@“ê¡»dKƒv8 †uʤµLVZ )” æ ·°öX)7õû–“|<[ÒÏ:›X…µÊèuÎ`IAöµöãP¶×¯j!âdÏJC‚Ø…y›Rb†€ðc ®lØ|óèâÛþgao¼ØFº²Idþ¼›Ç/(ÊÐã)?Iš´+$Ü›$klŸ*ÄIÆ#Òsjm]Øß‚ôeK¤k²™¹R§|V ·‚.7´4Ð ïF8ûÕÍɈÖXk¶¼[P˜öAÖ£èå$%ÃÐÒZ*¢”(plÿEBcR3U¼„*³á2:"T0,ƒº>ž°ë3va(÷*éBÏG Íq²ž#=$’ƒ_l9ðJôâ}ƒÇÍx²"œgt³{âÙðcK…7ÿMr—Z]½¡¶ÁµŒÖUvþ„Næùâðë·ÀyÃÜÝîH“Îõ~×[äТ—¦'Zvp‘´xU- §u‘÷¸‚vAœÃštÒë î'KÀÞËœÔ-w³Õh†? gX¢^šÙý¬1cÀ("fE\˜`KÛý) Å)üC)ƒUtY(Î6aúSXÌ_‹L‹¤ÛM‡C9êÞŠe#JÛKú-/P ž=ûìdcˆc§|èëðb)kæk ·Yƒj¬>üT ív=Âë­p)2‘-¥µg_Dƒ@Oq¿™.rÍu„[Ãz‡OõòÃå)UZø"6 ›óå LeÊz¢£-yï2ï¼ùRºÚÊt™�4`až}Ù¢ÞÏj·ž]áÌêií%Ö]DëRà®™¾~Ù?ò?<ÑnçN‰0Ë"s³J„Ẋ’ÖÙqe"ï [¬«»‡–Y{Ég'Åö¾Ü:«”À)‘ýZ²d <Øá¹6(X5^=�ùŸì—Çw ÈñÍ9½ ºýÞË[]+ÈÌZ´Pìo3Ä'Y[é`Ÿ® „!°)úX_|üûoþÿìù—ÿêÿù¿þïßüßçw~Çîë¾îë¾îë¾~×ßý{ÿ7ëçö/þùŸþÿýoÜ·ã¾îë¾îë¾~-®;bÝ×}Ý×}Ý×±îë¾îë¾î뾞wýlûï/¾øâ¾)÷u_÷u_÷õS¸ŽãPëŒ\f¿ñÿ×ó—ó+å‹|ñWýžþ+ööç?_رþçìoþª^äüÏ_£ÏÌ^ä×m—”óůÛ.!/Ò~ƒ_‹oþÿ›5w£‚÷u_÷u_÷õkxÝë¾îë¾îë¾îˆu_÷u_÷u_÷uG¬ûº¯ûº¯ûº#Ö}Ý×}Ý×}Ý×±îë¾îë¾îë¾îˆu_÷u_÷u_wĺ¯ûº¯ûº¯ûº#Ö}Ý×}Ý×}Ý×±îë¾îë¾îëŽX÷u_÷u_÷u_wĺ¯ûº¯ûº¯ûº#Ö}Ý×}Ý×}Ýë¾îë¾îë¾îëŽX÷u_÷u_÷u_wĺ¯ûº¯ûº¯;bÝ×}Ý×}Ý×}Ýë¾îë¾îë¾îˆu_÷u_÷u_÷õÓ¼~–üýaöç÷Ýù‰_aö÷]¸Ò}]½ÇÝ}âý$ŸÍq¨ˆµýïûº¯ûº¯û:¯/¾øâ¯ö|Ö˜½ü­òÇôˆÿ{£‚÷u_÷u_÷õëqÝë¾îë¾î‹^å(Ô³>Àìuào•?¦@üß;bÝ×}Ý×}Ý×]cÝ×}Ý×}Ý×}Ýë¾îë¾îë¾îˆu_÷u_÷u_÷uG¬ûº¯ûº¯ûº¯éõ³ûÜ×}Ý×}ýÔ.?“ôÅ_<þ°þ}ø—×ß¾QùîO|©;bÝ×}Ý×}ýc•`çŸÃ¿|b¤ÔoT¾û_ê¼nTð¾îë¾îë'tÇñW8õõÄ·þ1¾Å]cÝ×}Ý×}Ý—*¶®—ŒÏŠ^wu_÷u_÷u_?J¸:KÆê¼#Ö}Ý×}Ý×}ýTÂÕÓ¯;bÝ×}Ý×}Ý×óÃÕ³êª;bÝ×}Ý×}Ýׯßu3/îë¾îë¾~ê×Ú :k ð/Ÿ[=^vöîü·ø¹#Ö}Ý×}Ý×O1D•c?ƒ<{ÁÙ»óß‚_äFïë¾îë¾îë×ãº#Ö}Ý×}Ý×}Ýë¾îë¾îë¾îëŽX÷u_÷u_÷uG¬ûº¯ûº¯ûº¯ŸâõÆüÍßúùÿðÚßý{ÿ¾)÷u_÷u_÷õ¹~ó·~D¬íÜ×}Ý×}Ý×}ýk¬?ûÿü¾÷u_÷u_÷õS¾¾øÿöÿÿS÷¨Ñ€£`Œ‚Q0˜ÁéË�¦Ó¯b•Ó†����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/defaults.png��������������������������������������������������������������0000644�0001750�0001750�00000213404�11332353404�016571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ7Š÷.Í�� �IDATxÚì½{ÔžWu¸ßï®O·O²dY²ñlc°Á`Ën)©)ʤaeèdHc¢¤7¦]L#›qW/“6iZÏ’¥N×4MÒ´‚¶4Í ™‘D(P˜°�±ƒF¾È²±u³.ŸnïüñHÎw.ûüö>ç½}Ú{yy½z¿ç}žóœË¾ïßît»]"ºë?EFFFFFFCIÿÑG‰h¢Wï¾çý6#FFFFFÃIw½ó§þ£v6ÞýÞwßóþƒ/µ12222Nzúûïô¡‰æó§NÚŒ 3™Ä2222º\èØ‘ç <jÓKW,_¹z°¿H¬Óó§Üo|ãO_¶²³råʳgÏ~ïèÔêk_½é‰CÏÎýÎ÷¹îuÙ¶‚‘‘‘Ñ0Óü©óÇÞúêWã?yôß ¢é™ÙAý6.±¨Óq¿]{Ó]§|eë»|||üãŸøƒ}GžŸ»Òûå™ù“×Íú­»ù.ïçFFFFFC'±N»õÖ[E?¹õÖ[ýÆ7¦—,Ôo㫳PäLNÏœ˜»é?}ô·ßò¦7¾ê–›¿·ç3ç–®œ˜šq¯{á[ç–MŸ½võ²•¶ŒŒŒŒ†œ:NGn]têÿoSkÌûÃÒUëžyâ=ôðÚµknºþê¯|û ënû¢ ¿?²ÿ믾jÅñšWßnû ¡Ÿ¼{ã½íµ{¾øÍÿ÷ÏÛl ŸÄSIޱ‹ÿ à·ÕÐÚnûÎ×?sôè¾±±±•ãóÏïûê•7ÞADÇžßÿòUôù¿Øwí%;Ž kVþô–7Þtí•“ã‡|òà‹ÿþãvè艋ϥ·ýµ5sˈèüëÿ÷™ç·?¼ã–kô-·]»~õøØØ³/ýÌ—ÛóÅov»DDÿ÷rÕŠÙû±Ïþé×ö Ñn 8úâÑž]¹f}ôšë®ZýÞ¿ò†›^¶ö|·ûÈãÏ|d÷Ú©0222êµÈ¢@€ÆŽ÷Û_ý{?žºüþ?¿üvÁeÑ/+ˆZÛ[Ÿ|èã34ODçÏ94»bvÕº•óO}cÿó^swgl<û¦¼ç–=ûü¡§ž}~ÕÊe·ßtM÷äásçÇÆÇ'‰è•×­kÄÝ~ÝÊýNLÎÑÝ?ôª{ÞõF"Ú·ÿÀÉSó¯¾ñÚ{¶üІ+–íÚýpkçzîé“Ç,Y67<"«¡.Q7¦,›þ‡?û®¥K¦þðs_îP÷oÛxåÜì?þõÛQ222ê½ÀRzçHâÙûÎ×¾póëÞ”ýí¯þ½ÿGÿæãÍçþwÿjê·)+.xÇ'¦×½æÏÿùŸ§±±Î û¾<¶öÊ3çNÎ^w×Ô’eÙ¡_±réÚUËæOŸù™þ‹nglbrzÅÒéãÇÏ®¾zbbšˆÞrûDôøOßxýÕ›ÞüúßÙóÅåWlX¶dú'ßq'}ä÷þøÃ¿÷ÇS3ozý«>ô¿¾é·íþÌÃÏŸ¼4Ôîùóÿñ—¶Ñ®ÿþ…{Ûkf¦&ÿ³_ÿÞ3/ü¿ú¦+V.ýâ£Oü»ßÿ³óç»Dô÷òí7¾ìÊå³Ó§ÏžÛ÷Ôóÿé~ú¹ÃDtÓµWþ{ÓÚU˾þø3G_:ù#oþÔC}d÷‰èÊUËßûίº~ÝäÄøwž|þ?}ò¡§ž;ì½à+¯»òç~ìMkæ.üܵgêw½ùµ7,Ÿ99æéçÿëßùÌÍ×®[ºdêÉÏÿ_¿þ_–,[ùú[oºvÃÚW¬™Ù÷ÂÙYꊑ‘Q¯%VMÏÞ{þö? /þÝßøUrôõèoÿñ¯}âWþ·kUû¹½¡÷Û”ÄJ¾ÆìŠÕK¯¿k~ÿC'æÏuÇgfÇN??vÕ5ë®E^õ¥ó§NŸ™™šüåû~î;Ž|gÿs=ñìì̪ññq¢ÎäÄø]·^GD¿öÑOüÒÏÿ̺5«n¼úŠƒ'»·\wÕÔäD·ÛýÝ?üì²Uk—Í­ýö³'<xýÚ¹×¼bÃ'Þ²÷wÿðmß}ú¹;^uÃ{ï¾ó¥óßþþ³«–/yëí¯øÂ—ù‹ýG¨ÓY³jÙgþúó/~Ý-7ÜqëMxÏ[?¸óc+V,ßöÞY¶dúë}ïøÑco¿ë5DtüÈÿà™õW_÷~ö«WÌ~öK¾ðâ¡Ç›ï¿gÓýÿêcóç.={ÉôäÏÿ¯?²tÉô#ß~âÔñ—Þ~ç¥d˜×ܸá]o~õ÷ŸyþcŸüìÒÙé×½úÆã/˜_7GDWÌ-¿fú5nX¹|)Ýø²u<ñ¥ËW™Ì222ê½5¦úU'úÛ[îxkJÈñ¿ý'ÿö~ùý?JDž¸ro(˼péü‰Ïwi¾;õòµË¦¦¦&Ï¡¯}æ\÷ßþîç~ú]wÞõÚWÞõZ"¢ƒ/ÙùÛÿãÀŽR§óºW^³tfêðÑ—¾öÍ}_ùæ÷øÎ[þòݾë^>;CD§æO?1¿níõccã“㇟Z¿–V®XzêıðAþÖï~þ«ßúÿòƒ×\µæ“Ÿùâoþ×Ýü[?ùηÝñ²+W|á‘'–­\óÏ~ëžÜ÷ȲeËÿäáo}øŸ¿bÕ«éÔ ·ßy˲%Ó?8tä¾_ùµ‰©™eK—Þqë+Óíu7_³zÅìOÜù[¿3µdÙµW¯¿óÖW¼æÚ•?~hlb²yèí7]³tÉô ‡nûå3>9ý«üÙ׿êåÍŸ¦''‰èØKÇŸ~îчO|ô“ŸŸ?yâôØ÷¿³ÿÙ›®½êÃüDÔÄä–ÌLŸ™?AËW)v’‘‘‘‘DøŒÑXGñ«Ng,þÛÔÝÚïÓ¿ý'¿±û—ÿö–âjãÛ"ÏJ,¦ êèÇϾøÝ3K®\1uâôéÓóóótúÇ~põòµ/C^ö«øô/üúú•Ó·ÞtíÿüW~xú+Þu× ¿ñ‰‡&¦–¼ù57Ñç¿òÎØø—¿ýôßyË_zÃí¿ù±O;9OD3ÓSK—.éŒS§³jùR":rìøùsç¨ë?eßþgV®Yêl—ˆ¾óÄSK–Ï›$¢ÉɉÓó'Ç':?ó£o¸ã•?±tÉtû“©ñÎÒ™ "zêÀóÔ_½þºƒG.¹õV¯œ%¢ë¯Y÷{¿öKí—W­™;öåÇW¬¹ªqâ­\>KDO>ó]±áú/žxýÅ+¿¾ï©/ã{w¼êúÛn¾žˆž{ñè¿üðîgü•]ôê«f7\¹êÀs/¼ùÎ[ßrçm‡ëž?žºãVÓfddÔs«f+u7dz—üí?û[ïr}‰ÿço~2úÜ„••§Ž:¶ï 'ÎM¼üÎÍ'¾ðâ_ì£sDtø±ÏN/ÿñéÙåü«NNŒßöòõ_¡s‡Ž¿ô¹GŸ¹bí·~jË[–-9ôÜÓ×ÝôªÛoºšˆÞõö7¼ëíoh®_:;óú›¯þÖ÷ž9}æìÔäÄOl~Ëž?rlzìµ7n¸êŠåDô¥¯?6>ÉS8wîÜÄôt3)gÏ›œž»˜ÒížËkoxÛë^ñÌs/þê¯}ôø‰“ÛÿÑûÇÆÆ:΋G^"¢«¯Z;53C±k¯ZÓÞðÐÑ“D´ÿ™ƒÿú#ÿ­ýòÅÃÇÎ=Ó힟 ¢£ÇOÑÚÕs“Ó[wÅ¥º´3gÏ?øÛŸ>}äà†5+ÿ—-é-wÞú†W®ÿÄç¿;>>ý¥ï<ûè÷—ÍNýÝ{ÞMD_yôñÎø$u’K`ddd4`¯àXÜ+˜ºÛ¯`ì·ÿôo¾³µ®šÐ×?û[ïú…÷Gás^ÁógÏÿîç©ÓÙðº»'§g'×Ξ»ùm'¿û§ÓÓS“““/íûÂôk6óï?59ñ¿ÿµ·?õƧž;ÜíÒM׬!¢¯}s_÷ü¹»^ù²‰ñ±'Oýù7.d¨_õº«¯ZóŽ·ÜñàþÔï|êË?ý®7n}Ï;ßöƃçhìÆkÖÑîKßÜ·ÿŠ 7ÄC>1'apnyîܹ©É©·o¾kl옿úØþcÇO­]½rûý?wò,½ê†uíO¾òØ“/yéÚ ë~ôGÞôô /­Z±ôö›¯ýÍ}ú¥'R÷ ùÞ³ÇOÎ_}Õšüõ=Ý™~ýÍ×´?¿í~üm¯ýæwŸ:yêô5ë×Ñ‘£/=tðŸß»õð±ÇOÎo|ÕµK—Lîá¿øÖ¾ýWl¸aLµ“ŒŒŒŒ$²gAÄ/ý»SWþâoýñÂ_Åkª�+òÛö¹3ðë›oþéß|gøÜ”ÄŠ<øäS_]³|깯_q±ºhõËn~þÄ‹×.?399ÙívŸüþ×VÞp3A§Ïœÿƒ?{ôÆõ+®]¿nzjò…ÃGÿäÏþü·?ñé™W¼ùµ7Ñ'þä ¿ù_?Ù€G½ææëþÅ·¾áö[&þã|êK?ùäS?öö;o¼nÃøøØþgžÛý™/þÞ~nɲ•“ÓK(•¥Ð‰~¤?ûÚw_yͪ»n}ùßßúî?øÜ×NÍŸ™™ž$¢“ó§w|tïÏþOw½âÚõ_zä;{þô«ï|ëëÏ?OD§NŸý•]ôo}åÆ×ÜôÃ33‡Žÿæ¾'üñÎäŠñ‰ÉfºNΟÝñ_öþÌ»îºû­w>ºïÉ?ýêco»ã–扇ëÐæºuvfêØ‰SŸüì—þÛÿSËV=wèè]·¼lé’™ûè'>ýáýáÌìŠÉé%cãó õXdˆz~ñÓ·þÐ_vM³ð·m”|ûÛV\5OùÅ¿ç—~nsü¹Þ›þXß{ê9ï'>~ÝÌ‘¯í?¶á¶¿ä>¬{þüÙ§ºó–kÏ;wäèÑÇŽ,]zåõÌ›Ÿ?îà÷;wæÌÙ³óÝóݱññ%Ëæ–­^;59spÿc§OXºòŠå«¯lZ!ÏŸ<~øà“ê¬{ù«;D/ùÁüñ£gæç»Ô˜˜Z²bÕÒ«Ç'¦¦¦g¾ÿ‡ÏŸ?7·vÃò+Ö?ù­/ÑڗݼtÅÜSßþÚÙ3ósW^³âŠ«^xú»Ç¾8»bõê«®=wöÌ ž8}êÄØØøìŠUÇ¿Ðíž_sÍ+®¸âÊgžúÞÉ£/ž={æÁüwo¿å†_ûÏŸØý§±úªk'&§?÷ÔÉãÇΜ:qþüùññ‰‰é™•k6,Yº¼ñ 6.Ç|ÿä±CgÏž™ž™ít:§N¼Ô<ñìéS?8ðĹ3§»çÏOÏ.[±fÃÔô’çŸÞ7ò¥î¹óãã3Kç–¯Z;>955½ÄN“‘‘QOéÈž½õÖ°æ|þS©‹o{Ó;.H¯G¿¹rÍU½øm{YôËæ·í_=÷Ô¥þXž�<}ì…ëf{ÿ‹ë^ýv[`—uÆÇϯ½íÄé÷ÜxñcǺßÛÿÝãG¦Óe¼ccsW^sþüÙu:ñÆö™˜œž˜šY±fýØØøØøÄÄäôäô MMÏŽOÍÌugfWŒOLÎÏ®ètÆÆÆÇ«ijjf|jšˆV^yÍÔÌ’NgŒ:¹+¯™Yº¢y‹•W^=1>Ù'¢å«¯Z²bÕÄä4QgfvùÜš«©C°™YºbbrЍóÓïÚØ¡;ŸxòÙ¯»êö[®éÄÉ?ù³¯LLÎu:cã+×^=µäH·CcñN§Ó¥îxsóK6ïøÜÚ«§f—MŒOvÆÆºÝîòsgÇ'&‰hjɲUk¯›è\üøÄäÄÔÔÊ+ÖŸ?n||¢¹ÉäÔÔÄ”‰+##£>˜X¾Õòš7oF~Íž¨þ[ïK¾‚xÁ^úÁþÇNš¹vãÄätxß™¥+yáÄS?xäÔ©SgΜ>væÄÌò;ÓC¦Ùåqy¶bõ:ï›É陹µÚNÍÌNhó ­ºòêöóê«.‡­¼â’Lž˜œr²lÕšð>Ïüàè¼îú7¾úº“ó§~äñ_ÿÏ¿øØñ5׬ïŒu:ñ‰Éeskø%™œžY9=ýÓòà‰hi¬é‹‘‘‘ÑðxCA7°ßzß5^Áïxñ²]Äçö?vüèáóçÎŽML/Y±úÊÉé%3ËæÆ,°ddd´ˆèô©'_:â9èxzôÑo.Y¶rjfvP¿m¿yáÀ—¼‚—sØÅëg–®›˜hòRÆÆ'f–,³Ì=##£EEM»©Gý&þ“%ËV6¿Ôo=ÊW/zZ²|nÉò9ÛÍFFF‹_hÍ.›ž]6Z¿H¬ÆÆ:qô­¨‘‘‘‘ÑðÐìŠUEtâè¡|è}6;FFFFFÃCïûÐGZ¡eÑ####£!¥;wºÿœ¯8|ø°M“‘‘‘‘Ñ`i×®]Þ7fc™Ä222222‰eddddddËÈÈÈÈÈ$–‘‘‘‘‘‘I,######“XFFFFF&±ŒŒŒŒŒŒOÒ¬Zµ*úý¡C‡š?:T œ0|–wóö‰î£K†þÖCÅW+÷ÁRjxu÷@t³ |¼QIÇSý˜àµG®¸i{=Bï ߈ÎgáÒ×zYÝ{1·ÑIëéö›Ðý¬Ÿ\yV¯Ç3(.9TRŠÞªU«V­ZuèСºŽ*(à ®ÂžQ |H%“3$>:Ÿu—¾ÝÌ}[¬!g&½•XYÉÙSÓ$e µ»J½š;´¿el¸”aQËÚcÞ:|Y÷‰î÷Þç~.MtêêªÆÙ÷Bf£×V?ÛUÖ›aõ£«/89©ÝÒçfç³G"ÄeYÑ·cÖ‘1q6ÕÓD†­XDZž.y8;ÕybJèõnîÅ«IU³èH\[ÇûÜÿñ{²¿®'y/~6J¸Lô‰¢ÙîÏ1‘>º[‚Ÿœèù–ÌÃx¦‘ZúBnοn“ pãáЭãDáŒ÷ÁÒLÉêÔ^ˆ$tTQ£ó<<Ö}VS«2Ô>Ä6 …VŸÕ¦!wIõwéA®µ©Ráê’¥¯>ùY!šrZz*Zj*žÐþl³Ʊj‰“>û¨·­G¯¦xwÅ1ëÃÒ I8g û„ñìT‰ÖUñ¸¥ça{Ó^/}­c¨˜7^²V—»©Ì”^¬øÄ0oý!±†óÕR^éE¶4Ãf`¹ãÉÈ-V1:†ÊJކ«+.½hK·ÂC±…Úw‰J&F²Ö’»}æ3c}8á=Ò­z§½‚gÌ}5/R2l|¶ÏK³XÅUï&¶d-ÂÐÝ0/k8¼á´2Ge>ùIN¹ˆúy²R¨›Õ‰-yÈÍ«H¦Vxi`¼r7´¯Vk$Þ¨µ4ý±w£¯Ð·u §š�¿Fǽsó>oc~r¢y° ÙcýrÌà äg¯s‹<B§Ùw6ÞýÞwßóþ'Ÿ;râè¡|è}d=ˆŒŒÌ˜µ \”®þ¦ñW¯ž]±êù§öíô!Ci222 ÛZ4¹à �.2‰edd4�êC¦¸™§‹&lÉŒŒ(´Œ.·9,³ÙXFFFFF£A&±ŒŒŒŒŒLb™Ä222222‰eddddddËÈÈÈÈÈÈ$–‘‘‘‘Ñâ¦H=VŒaddddd4Ô6ÖÎ;mRŒŒŒŒŒ†]b™¸22222Zò½‚[·nµI12222š››{߇>·±ŒŒŒŒŒŒFÆÆ2ªH–Ãbd4Ìd.%“XF èçþçmŒŒ†“¬{­I,#;FFÃN»ví2mrÉâXFFFFFfcšíe“0$2æ%VÓ•9¤C‡Y»ëê„Li»"í´ÿ —Œÿ2úDoÅÛîæáÝÜ?•Œ¡î¤!OAÞQ4ùÌ¡h¿‰^ÏÌ-sôøW°SYBæ-ŠÆSP¯à¡€lB{AÙ¹mÙ™Ë]n%ú2ÅÝçÕ—Â1ôNä3Oq¯Ñmf÷'Òû¤®Ê3÷2÷ŸÞ+€â֤ޖîí<xoçÁN yb{2¶Ô5àM˜¿‚3søðaËbLÇ¢œ«%Ûñ©Ióæ'ü2üì}þ"Aý²wŒO$ø™qÿéÍ (òC±dÅ–ö$¥ ’ÅAÛh;rÙºoÝ×Ï!OÜA÷5ãGÆÖ^ã¾ò6ÚÞ~Ïߤ}–7cîJ¨NæEÔçEàëÃmŽè_]u»DÕÈþ<Å©WUEϧh;¥æ$õ”ÔõÞ÷ýßÒ¢¹mGÊi£~Ê-ÅÏ·Ñvþ¯å‚­ÊO‘4?ô$_-A>†s³Ÿzg^¤.¨Ëþëù¬ª¯¸Úæˆ ûêOQ̿ԫåp×ÈfL™ÖJ¹v”3FFx}c*µß{,Ëî¥"Mz}h`¹C­.,+H,ÄSo'§¢ÈZ~Tbf‰‰úÅ«ˆ+|þøTÊzK]_2·Ñ|£^˜SŒ[Ìãã¼q%9î2†‰»HIÇ–öЦ=´ ‘ ©› r+uMt6ÊmÁjK$ÕÌAQËTê??ꀔ ’”$àïS7nT2ÿ=U5Ü›Ûq‘æšb:ÏX Òþu3íÝL{£Æ\ÖÊñ†Ç ±BI e Ä2K«â¤á1§þ/J?Y¤häÌ•Òûο:âhâgHȳ1À|zÆA"òL*Œ§ö¯ŒS!kI¯:+ŒÛŽOÍOû™Ÿ4dJ£×à_VYJéã(ós÷þáõ®IT’溇-ŽåÏ]ï„–TäˆXs g|Œž¬EÞ.*³>LZ%o~Òx6²ú£|<;¥|ŒDúev ÈsÁljvHV¦JmšÔ€¥ï…¿>Ù5-¨Q?)LÚκÚÀ4q‘È‘ÊWoح݆ß$|ñÆE©3.ûmc-&95>@«ˆ¹¬ÏÕZ©!á®Ëm´½5žR‰$ý$“XFƒ¤U1‰aÛÀ1¥Ì &K°ŠX’–d)dFªð‹É ŒOÔ÷,Á† ×h4r®­!°¹ k™ÕuôEÿäF†ðÇ1®È=´i3íÁaÐ…hk”ÈРŒ.Ù&‚÷NªE‘}bÊ„*Ù^¼¾I¬ž“AA\µ-Æ%„k*õÈ.Á3A¢c�¿ôÒߣ¹žWÅ3‰Õ[b@ˆŒŒKÑL!Sn®÷}´|ÊåÝ £M%^°н¨ø#sàeÍÛÙ3Ë ,###%E;0…üw3í y:bK!Œ>uŸ¬`SpÿP ¶øÝø„~&¾UŬ4‰5àSaddÔÚµk—H› )•0q¼°·5qB)˜2­˜õzÀ<Yv»‘‘‘$]Ôóx²|«ŠÕ‡áƒ‰&Vdqÿp{ËûÜë¤A“XFFFFE&B(r\ô¿¬!•ÍS-!ióªèðÊ¥ ŸàÞ‹"-Ô+èV&z€Ö`'=äþ‹¸šÄ{Á(àž{=ÓRì Å,ò¥{·Q¼‘Q»JZ¨ÄüµJ ‡ÉåCr{1'xÎaŸl,iOXcˆàOÍp8Éàüg¢h…¼hodT׮ʲu’$š+†äzwtÜym¢®řðíû‰Ç¶¯hlå%V´_{ª5Fô³½~~¸ ؇Áš2h˜nÅrkõæÃ<x#£ºöV-QW…ƒ/ðvÈQ›»{©£¹¡—|úuéŠÎÅE6V–g¥Ä¨«› •4ð­( ‘Î á8‡pðFF}¶·ê ¾WÔú©+h½!¢êcÅsËqë+H,5ï0­9Å‘¥€°ˆN{uÇZÿ6¶72ª(·@1“•784_*QbÁ=[3«K®Å˜‡hrM¢,ú»÷š=Jìy® q‘¥¢â"Ž_¨‹ áàÝø™‘QEʦ¤Ötƒ©&ŽvADŒ!‘Ù§†¬uM¢ì£¯é ßI¬CÙèµeÖþÓodTnNÜ\ýÐÄq¯är:¾…S¹,I¹£oÑC‰å9‹²™Í¸¥•úòr0³˜ÎΘJîé)å@ÔÙ}$o¼Ñ�-æ¯ÒNW)¡˜$` Cꯡ£²A¢ÒÍF41²}ÄÚ­{}½• ηM}Opœ¿ýþò4ÅÜi 'Ÿ|ÉD+r™ ÞȨ–±Å°oünÞ­B£¤u¾!)ƒá›QaÚ:‹x=ý¹NtMˆ¸Rê˧à~¿ˆí*üpr¼,sõŠH3Tƒ72ê3…Ø}Ç×µÎI£ 7édðyHx“וLÞËfoø�Ý¿M‚[XÁÆ2222º|(L®ã &È„U©’[Ðév©Û½t“n—{ (A£ÃÛM[¢R±äj‰«úËœ3FFF£Narï1ÃSºÁøS/Òã)…¡¯/å]Œ¾Ž{±‡ QŽÁÊËrŒŒ.ó‹ä²EÂ%‰ NÒ´’’ÒÅX¡ÍÔ~³¶{©"AƤfHÉúcõœvíÚe“`d´øÌ¯ò;¤bWaûã˦¤¦+–.¦,.°¶ÐîÍ´7ö.ÛÉÉÙB»w¤1ŸLb #Yb#£‘6ªty:ùçI &¡ƒ1³:ñ ù&Ë»iK¯ÚC›6Ó}[‚´û¨¹ÙŒ¿‘»Œ×Ñ$Ö°ÐÎ;mÚºu«M‚Ñȉ«0£h9&,ôÚŠbñѤ‚yÚM[haæ};þpB¼}×|”¾µI,3°I‡¶I0ZA…@•£iâÝ.í "º÷â/}nÿé})¡&ŠÕé´‰‚ÝnN€5toìû{ßÞëZsÙl×j3›o˘òpÑ®]»Lœ 'Ú:ÉŽ·®fÇFZ¹BªÓášG|ÿÉ2&!]!´‡65E p­²jA”¬ËÈÈÈH/-xÑ…g± HWvˆ e¥î°‡6¥ÜzÞ•á{…Y‚ yÙåïnËÈÈÈ(Éܳ°Õe’>Á½éU@�� �IDAT¹OXÛëþ¿3Ýt‚,öšæ;è¾&(ÅÌ rˆ¿rFb…H£ ö¨Á’-é:W]ÎMIðø5Ò†#äÈåB.¬Ì½d^Ñ÷ÐjFëzí6ÓÞöV¡‘”­wöÝ›‡òž±8ñšb³±. qE•z6™ 1tPªI ¬¶HË•Û:Žhì\°kEµâÓõþµŽ;Wö´–ÿâQKÔgjàJzÞ¢ÊNTFb1­FµÝkwä}6MßÈÈh„(kðé<_Í ÏÖ‰ÊÅT5nÛÚ£½ ±¢¢‰|ŒÑÃ7² ML×HrïÙ½ž¼J¬(dF5¯`EµÝ4}##£E`ZÕ½>¼8Z½äɰTZÄfÚ۳7ôÄCô枌ÜFÛ»ÿêÒ稇ÓÒî=ï}b{8ìPôâBK)± ?ÐÈÈÈ¨Š­F9g`wú’°q &Ñ»âd=¤´ßÒuW¸·ÚA÷Ýû÷/%µGa¥²uÖ)“Ôû2Û íAþSçß3— ‘‘Ñâ9:sŠ÷¶æKg>b…æÎºïÁî}îŸÂ¨Ök%“ V•+HáTTpz×·Ò¨½ œOÞ)°±<Iã¹ø¤Æ™™hFFFÃ,™ …S”ïI`ñ…?iÂT›ÈЦ6„öäVôq^n…HÐ2׸v˜÷tÏ9©›UHbe{ 3rÎ,-##£Ñ¢”$P¨ÞíõB r�î6ÚÞ¶œw3)@Òæš‡Ò«Åôs¯÷<žO¯‘”^æa(›SXM®²¤nZÇjO˜IÑ~öAoe•ÙX}#›y#£¾gŒ¥”¬áìM8*äþa-0%p½FÀȉš;Mž¡çÓkoÞˆ[×ÈH P°EãUѲ­:+ôã¹Î½Ð×çýÉû‰1Íþ -›y#£r9Ä_Ƨ³{2€/›å3à]´$÷ÊœÉkíèþœqÍE­7·¥›:ïa†¯"Ó»Ÿ[s3:3õm,###£ËDP^¬T™‘Ç¬ÃØU*í",¼ yºkî¸X‚÷v¸v^èz)ˆ÷ÓÍÚ¨` …Ÿ 6èÞ³}“‚aËÈÈÈH@H—w7JäæÂ¹lÚËJH °xDÊ =oÑßò�Q^õU4o¾õLzâ“Ø:ªæn¡Ï“q"’Õ$–‘‘‘‘X€…¬¶Íeðì ^DQ¢³¢+ ¯l„ÁÚ‚ÞHY~¡E•aÍ÷h]ôžYéŽß…TtÆjÈúcõœvíÚe“`d4¢”å­)yÓäãQ̉b(O–¸B%Ú°˜iã›ÂnçûTy"v=Tàöz²0õ"ФA“X='ë[hd´ÈL«ð×ãç™\%´™µÏR2¦åõ­üóìP8y"„é€Ê?3‰Ã…µÆ¡¼Çå«I¬ÐÎ;mÚºu«™¿¶@ÃiWׄöDÌöâR`ƒ{hÑn×®bL4þu)Ø6F$tÔž4ª˜»m¡ÝHwÜÞ2‰eÖ éðáö@¶@Ã,ºˆ Û¸íá]ü¤èO¶Å8uÖªóÚYm£í䤡{’i í¦ IýÁéûvÌS;È=´ió¥HØ^‘xŽf£„%Œô* e™Ä²3?0ûfH¤…-Ð/Pÿ Qü=î–Ö¦<`L8ªr­ÝãúÓ¢@Q^¿›¶¼#HÏ»w~;]JOßņJÓöŸ[hwkQ5boÝGt/pÁÏžsÔ®%Ë4Z4d­×Œª[Wî?ÝÿˆM+o3ÝÁ˜'ùÀTïVÒ¸5OQh ¯çVô3/M]!ç~ŽVSyЂ^™ 7}“XF—…¸²ÖkFÅUè×ògSæ9àè%pº ïºÏƒ+ôÄFsŸÖll8×&kEWó¸ØÂƒwòäM˜Ç-¸!ßǹBæExþ:ä!Ôy½‰½‹í� 3ìNTÒÈ,JøÃÔœóKÃüavØ} þ<·pÉRg|¢b{DO±=F d!—9çE¿˜ì8Ïû‡DwROq¸ÿ‚Zc¯þi3ÝGNÝØBËiïÅ â’» €ñfâÂë÷òÒw®`˜.zä Åwd¥æ3Åk¢à±èÒˆPöS Áõ˜nµ¨á\²èäãKÆ4úcÀ’:¡ú¾˜‰)FÜ~îvübòöG]ÐC¬ˆfm¸UÆÞ•!Ô¡û,ïn»iKÄìëF>·x»Ù+R+?À …qDE‹T6€Âù2ûÜì¯x*µd8n؇8–è5ùÉ:ì€ ¥š˜Ü…VøÏTÿ_·úбít¨Ó¡{;Û] ÀTÎÂýô@#çìÞ-dnÄdÊŸÖÆÒZ¥kÌ¥œ{—ž`éz¶]hü-´Ø|H]‰�>U“X©Ý¿ÈbàákÊõTWôŽÐ°‘‡0Žös©;ù&{zGmP'*œZX?¤’‰GÊ?·N¼n—®êl Ø;8òž‡©á…¾¼‰æ²&L&hxhDD¢î…ÿ\¹èË×ÎÓjG÷>êÈæÙÞ­™+6Ïù°h„VÛ9…1Gú &Nu„i—¦î œäÑ)O]vò³†Qju²ó=°&ä@ £/žyá¥Ï5ÖŒç‹ö?lüv/´·¥Zø×Иú¯ùa‡.IšK"§{_óasw¯÷}ó_ûyÁwß…?Å l·u¶S—<qÅgTº?w-Åj+ê·Ô¬Q7S™¸ê§q >µ¸¢Á 1=«¼Ü‡¶ÛS˜®íÙ@­W°q †ißÛh{{AèKtÿküŠîç{;Û/8;DÚÖÙN?gÿé~¹§³éÒ——Fpñ‚(Ämc]u¹© ½‹¡¥ØþX¡Ân'd8ù~ji<v¬^¾Åª¿WÉYPŸ‹puÌNê1=C�Ù0 Õx\;L”h3ˉ.É$rš ó½£ÞK0)ÜŸ_ÊËï^l©t¦)e˜Ù ¾÷£ërPåÚøy›“6[ñP$_Ãë=¢šÇ Ö¥wK–ZݳLԩͬ(zz¶5”{%¡il2/„ÖZ]^I²+ÛB A 3 CtZŠ%=zð†½ÃÑÒ%ê\¼¾‡)Ç`è2E&ªNqËæÀôÈiÙž‹¦Ñ,Æ¥›äŠKÃÜjP>4/“{P;$5€êç¢úö0U~¯50cñ„‰Ýt1LÕ„(V&Ü@4…¡¯$¹m̈¨ðˆb±»ò£ýì–”…ö\v¢¼9ñ®9[š�OcöKD u¡Õ£ŒFuc`Ö…€È>$ä›®QÿŸ•=&º%ÃÏWöY&ºJƒÌ—!ºÛqÑ¥ÆÅçbæ¶N^›+7�¶l7žò}ÞX +”7ÓÞmñ wÑŶ÷” ÜÖqêÀ: nvùj%¢ÛýRT¡e(MFFFFz vÇŠ&hd!6ÜìDÏzkÖ]kɨ))>(åÏ ›@Fïé¹CƒÌ•åLÕšI,#### …ž7/Ôôàt[/ô¶ÿôî}(ˆJ®Qåy]d WÎ…V` ¿Ã+R¦…¡¯ÊÝ»2,1ξo#¦Èºq–‡÷M Á×üµ3OÄÂãFÚ)VÞK‰;æÊÐBrÅÀýôÀŽ@rD–ªám”xæ×nÚ²¶ìHôÍŠB#F³ ·ÐîÖBˆ&±@ÖèÖÈh‘ 0¾äÈmrï|™lxŸêýè‚ØRˆ–ÙÍçè~ Zmy6 o˜’jî£Ùv/Óµ2j~BÑ¿x3í=dk°d]nmŒFŽ\>?™N›⣷ü=4e¢Ðæa¶°vT<6|(#£¸áÑöÊd÷yÃ3é™±eMbõ›vîÜi“ÀÐÖ­[ml†Ù–jPm[˜^ávJtóÎÃââ”=-)æÉ O€¥z£¸ßl¡Ý¤¶»‰ø»÷ÚB»7ÓÞ-´{ mÚM[vmsÚ"{wn'Ç»³Ûˆë�­[O½±¹¦^0O´{3íýú9“X¦¿) ¼c½-Ð/ÐÀåV´»cËܱáùëx¿_ÎÊ›¦gU´V{óFºxR-H—ßÖH5ÿos7.~yI"º¢z íÞ±Àïwée£éòm¬ÎWÑ×Ü­ˆI,;óƒ¡]»v ‰´°òf#¬±~¹µ7Ä#ç­ŸTp4­<•æZ`ÑHR˜ÑŽö"¦Æ¥Ÿ»iøÑny†ÒÄÒ%Ën7222JR“ÉÊØv™xc©x8IáO¼Ï®Doн>…ÞÖï²Ðô>»r—.V‰MЉ.víâCPL.»‡/Å´06‰eddd„’ë÷ ­"¤?V´N+Ê£ùš$·…U(–(xèšGŒUÇtð sÍ·Ñöè~o`”+Ìò$_´¥2©íÄZÕ@JUÜaxàY£‡Òµ=úOt.‹àžºÿå°Qÿ¨p³³ºÈh$¨e»Qär"jî0’Ç@ñ2TnŽ_ÔgèeIDáþšË¼ÚdÏ…ˆ^2…+b]iÔ¾ËZçSo^i+²±ª÷i†&ë#GŒ¬ò–‰é«”úÞ[_üK£Â ÌΪ-ÐÀå#i<#L„’‡¸ÔR&Q´&÷bÒQ-74/ßÇÄõò­Tžd›7èÒt{+° ñXùYM5Ç ÿ”ºxäTŰ+õiÔŒçE~UýòQú¼@¸úeŠÚèz£%DQ31¤Bø¾ÐÙEÝMÉ Ïí&8xÆ_#xöЦGè¶´.;àm´½IùódOc$yK× åk4»$[š]Ab¹íE¤¨BNžh=Œ<%,»¼+m/ ¿™åózb,e1!¢” ÑõŒ¥ì¹¬ %«‹ ±‡6µvÒnÚ²™ö>@÷{×7פ7RmæÙ{ŽÄÔ+T³±\s'Õø *rR’‰×@GBígƒ‘…t™XƒR)<‹éi®¼Ñ]ŒƒŽIÉó,$÷‡!¶z0)—N‰ˆ‘{}wú’Ãð~z I líªv<hëQôrS‚ÙsëEÛE¶!1ÞŠE–@ÇRœ|÷(â§q$ÂûÞ‡aWÕ>êBk€V‹úÈ µ¾,#{ýùl7¹3fÓ°ÃË÷|‰M½ûÏ‹X½î°ž uÛhû#t[s7×M×Ê/Ÿ"[ØNÅËÈðFuN†öho½‚ŒbK鮀G ²aW}Ó‹Ã(`?ndt™‹+/[/ä¿7ϳ$Bó(Lþæ3RŽÁðéî]Á ‰èþ‡©ùáƒÓÓø]›/kn¶Å[u+º¢ÆÙÚÍ·ÅêyæÎ.IâßrŠzG{7òÐÀå\¤~n ÐÕw¸îËQ?‹žRê4\”²Âë£�µ<÷â^n«*× ôʇÝ2áæÃ;6^Š–uæø¥ c»i¶°QVJRº"Ó ÅyÅÑaž}›¸®E}‰•êž’[Ñ¿º_šs¿?Þ3$Àrz1ÙYµ¹•5ƒ²ý CÓ*4Â(èݶ6¹V`÷g“5¼Íe÷~éÒxк6½Ð+v%«‹=˜M˜Lµ É‹–ei<Ì—Ù ˜CXòˆs¨ì,õáÑÒ‘¤fYÄá\ ÅîíÛƒ*~¹XhÔ]…«ê¥x?Ã{ CÏk®i! i!b¡‹ŒžÂ ìü‡H¯m´ýÁéû:ó ’ú}Ûh{©Þä¬Çʧözï6è ‘yÃÉñ®IɼÙXf ]&âÊ£°¼K ,ñI†}Ó ª6 >lgå~nGÒÚODôìü:ºÐæ‘è"¤z÷=k)½ã_îZ©|w¯ƒe“ñ‘£*µ±âÊ´<##£EIÉ’Ê/ß@’/@êviA[{Fáûþÿ/|¿9=°Î wípn¾ãÒ‡{Û+Ûë;ìÜo:D­Ëpu:;ùºÛ×_O)Ñ6,l_Ù'ËryŒŒ1µixmà‡ÒÉè Øw§þ·­ó`ûyOçÑk¢×è\ýS{Á¶Îƒ{:ïèÒÇ›Û6ÿßÖy°ù¾½¬ýÞý²ùÞû× ÿÅl,/ÝŸìAoö¢0ûgc…´k×.›[ £‘¦h‡F†½‚(y¨yØÑ8ÚSŠœ‰QÄ£&à´…6ÝÛy|Ç#ow{«¶×âÅ6Á{/&»_•u¯§Î{ÛJd/ E‰FÉÞ«m¦½Ûb¹þÞ?]O`Ó1Ò$Ö€ÉÚâÙ:µ@|<m˜…Á$„i n¶E´×pª!rK˜¹èŠÜÝþd9ˆ½NrÇrò,š¿~ê‰Mt±]VØ¥}Û, ›laN3Wnº‡I¬ÁÐÎ;mÚºu«--ÐHÐæ43m rC^ŠÏ`JepìH³~ÆþkÙ ©1¶к¦:8U±Û&RÂAšY›é¾mNòÖ²ŒeNúsVe™Ä2ý}4ðŽõ¶@C¾@#a~mYåZE^¸‹ž4¯27•ƒµW\+§ÉÙF[šdt·Ä*Ú¿ªÁýÛB»wÓ–Æ"eÛ¹¿ÚC›î§uëé Ÿ:‘–îÍÁ|w“XvæC»víia 4ä 4œõæ¹|¹±“˜ŽÃŒñš5^«ûð¶KÍK£÷® ŸåŠŸDÛhKSæÕÝH/¥A~éBýr2¯½¹sk}’ƒ·ÛHP]G±1ÛyFFFF Ó*üçB¿Ù^þâÐ[HcÍëtÚ"!Xm4DÔ¶ šP¶m£í¸ŠBu¤˜ÜËÚ·ÉýíngE±I,####™u²òöóÚäU S¢!Vh± ua§ÇlF¢‹šD^ű'ZÂÈSê³;¤lƒ®P‚ºòR'«P‰epœÈœôy–V-¤ðËè•Ù[)¾´ÒÍ*’»(hÔ­+ãÜÅ¢mdCØ *ZQʆ(`RÖÎóŠ“è7)óŽØ°SÔºJ™_áã˜Ð¹-»ÌÆZ„ä"²ëZ9㿲®ƒ"qÅÌU´i£OØ 'µèGnœ&Õ> A¥¬´(CÏÚ4Ñoš_u¯‡ì<·¥Vj`aBª€:û^Þ=ñßdpT“XíÁh•8‘êçi‘#­zL¡ÏØT…5ä E~aÆpÙ¶Ü9g`øO· 6‹¼ž2q¼¨UÈÐSå\CHò¬ŸÎäÙ‚îÝš/ÛÁ©‚å”èrÛK†¯Ï×®E%håþXÍÑjÙHõódبëƒoë`þŸá·´Â½a«¶hD——°ç¶ª¢ Åbªìwmre›%âí°VØPºÙGXðë]éâäFÅ_bµ;j±�M1që¦)nÎ+%–BµôXüâSäûÿj^‡F—-7•"ê° µ43°F…<>š\mvC´ßU”6_„–H±r×ØÈ¶VÂy¹ˆaN„ûy7m¹Ÿh»�·wsR“3õø…÷t䣿QôOQ”zÄy؉%U!G½[úh€Ä„Ö0kK&®FWz¹Ü6 »—2ÔZˆ±ä\‰Há)q5î§ByÐŒöªéƒn¼PÕ–·Ò«1t¡›òm†UÏžèþ¤Í§'â¶�(·Æê?’À·‡ÝÜGN\ ıi†Ôˆê7|*àPi?F¼¸ŠâÏ6š.P.;¦†ki…n=¦‡ §ä•v=@÷»™{î�:óô©/m"¢«6|Ç<±5×¼øSëÜ‹]5γwoå: yó”$ˆÇúyb ÿõMÃM£É¼!Y‹Pi3ï”-µžº¹ïQñ²ïÔ5žõ �÷›Toª¶Ø«‘ ŸúÒ&ú ¿jÇé`ÑFÞÑC˜»µ¢Ü<@~6 1³*DZÚÃæfg„Þdz˛=üËÝÊH1«ý\k£Šäú£|<•Jà…¢® I•ë†H­EåþÖ½ÉtÛФ3Ožå¢ü¹^GW¤yY!!´GTª¹Y¡ôrm¬:H¸Ñ`€èsôðŒô‰J±þ@ýeá­Fn¥†mDgjñ-ÐHÛX”Î;g:H¹xµ·%§ïF´ùˆÓéê> 0swÓ–m´%tWÒE$@„—6=q“£ÙóžL ÇéþvsØ /šî¹WÐüFFF—ƒÕzÃRQ+Äúk@›RÈ|.C8*W~xi~nù0S‰¦]D‘×S˜™ŒAÂÊû!±ÌYaddt™H)rBG·Ñ#©ð]ô¹VKè1  15ìÂ\÷Ê6oÐCDŒ‚9µâgó‘ޣÝ]˜s–´‘¶K,ñœ@###£¨¬Š2ë–A?B·Eù~+$¼¦S»iKT°…àOQÃ+jlµ¦žÕʆ¦B+]Qaã=Ú æ¹b8jAQ“EÉ´Ai%4CÖ«ç´k×.›[ £ÅD©þ¼ ÿº£I}Ñ&Šn©Išp½p®+Ïë[¿0µ7°.ÈªÝ ãj)Ç]´·r8Ò‡‡ùÔö oÞ4“$�¥É$VÏÉÚâÙ]>,ü’ÉüN‰À(Ó  ¨0 ŸN *…/µÈÚAD á”ÙéýÕzJßè‹D§k3ím³ELb ’vîÜi“ÀÐÖ­[ml+…Ù}aâ_K®‘äbR„×·}Ýž÷ÛœRªTóâ&ÑÍñÛB»7/Ìîóäh r0Ú:™I ‰Ö;3ò>Ew¿÷Ý÷¼ÿÉ玜8z莹mƒÖu7™þÎÓ`;ÖÛ ù jKt:…Xò¾läJ›SÀiÂtpæÎ¢a„‚ð6zÄ “Ðè¶½wÙ¾ZT°ï’ð¡C‡šUhöÞÜÜÜû>ô‘Ù«žjßþG2ËÎüå.-lLœ—PÔ`jcE k^óF^ÓÊ \’EË¿èR1¯è}nû!µ%_aG>…Ýž® ±ut4222ÒP›,ç%…‡lšé;L DsZ˜D½À5¤¢O 1v[xÜZ·r§XëȨåDN<Å=ا茅з|·I“XFFFF¬«6Ï5/\DóŒ^ŠA3ý¨Ü^+EåÈÍ>ûTQ T—ö+‰bD!u`^rcTV5#o¡oS½õkU@ýÜuŸ¸*F£~lø·`ºB#_çKõmÃôú™ÑŽèÂ]†f–Ëj]Psr`/<{%ÌOÅ„BÛ¨åøŒCNíT4ÍÏ5’Â܊ݱ´½Ðœò„høÿ¨¤tƒj¡LÍjcõ¿ ¸'ðÐBZܲŠr]¡³_𽼋Œ²³=¢ wŠ+¦'-l¢ÁÀ·§À #Æ5×¢™)ÁϢ߸Æ\(¤³ï’‚“w'GÔ×q¬„QzÂ6?î—Rݰ×B%lÝ›òRý¤E #â½Z¸åøïÍø0êW0•hÇô‰÷d@ a6”[ÑXëÖsÛ{—!À}í¨¼7rû¤f ã¡= ù¬WSbEáT;p·ÛÈð膞¸ÂUWþ¥Œ*Xá?Ýæ5î¥:%šñaÔ7‹—g.Ee@X®Ä ·ñUëŠdq…ÞÅö‚îô‹'Õ8•Öá½f*{ÂEÝuE²×ͤ²W0ª«Ž¨‡Í0yG×ð}odÔ+*NRpDÑhPʵ ‰6-ÂEa§D¦#eÝaÜ;á·¦Fk{µy%®H ƒ…a³æƒrk³-¢É÷T1W0”L¡ÓF¡ÆšÇƨ§Ã6˜Q¯…VÖ¬qE…kR´²Ç…9gÌŽ«ÉKâhðˆmæë¥ZxòÆõU6×´¶WûÍæ‹x”M…àLÑwñŠÀÂAVXˆÉ¢Pu’ÐaZùð›¿î®(9Ö7À¨wÄcy D¼L9ºP‡Ëõ/ve!SÛܪ‘gŒõ’ ]Ñ‚6¶—7þ(<#fvÓ–°¯Š¢‰†¤«oŠðe"®.7Ã"û²£•òn’`„ ¬¨‰Ðþ¿ ¥ŒÏê¢tŠ`x[5å]Ó /‰#ÚzÑ‹lEû1º? Û—„‚ܽ›ç÷ãÛg©JSúvÃàÈ©ó®ì§ £qáH8¼Š„¿Ú(¾o;æhòÅ0¿Qvl‹{áFbkáÿýÁÆÜeþ5ueû}ûáPz‡œ/ÊÞ%ür#vOïOø•E+zœ˜oð¿"Û¢î …îë¾H?OWvlø—Cõ.%›m$xâè.Ü"#k™6´dH¸F£J’4ê°I,#£úfŠ9ÄŒêÒÖ­[ Ëß$–‘Q¯„–M‚‘‘I,£jd>q[ ###“X£Aæ·2222‰5ìd>q[ ##£ŠdŒŒŒŒFÓÆš››³I12222‰µsçN›####£¡¡ÕI‰µuëV›####£a ¹¹¹÷}è#I‰Eƒs 61ðapKÏHFqxC5à‘˜«äÐV4ªöh5†p݇mHabÔx]¯i×®]­y7Øô­áÉ(o¨<s5rƒB7ÌÜÜ\;u£’ü9„ë>lCrÇÓ’å ™Ä222222‰eddddddËÈÈÈÈèr#=JS´“/ œ¶Û ¹O?Ç6T}›F¨GtÞ¬ ֢ܖ#·²¶u³Q}Þ&ñú jxÆåd]Îdûp„m¬Vm_µjUÊ´r-°ê‹½y8 ÏØjÜ#yÀØvîPS–_ué’Z¦pZÜ1¸ß{Ÿû°²áĦ†]÷ѡÀßfÒIëÃÎ-Ó Ž'>ž-7r ²»®o£eŽCôó`*ÿÄZS¤‰cµK=µS8›çȽytÿáӋyÐ-“+Æ¢ckø¯Ë‹£óÜ»7jµŠèÍù¿–ÌUûRÈ6MZv>¾L<žÒñôèÈð§€g&ührÒsÞ‹£Š<±|Š[æE?eRtµD¿ˆûîC#·‚=óH8Q=¾®lê¯YÊòaôè]ÛJŸÛ£9@6�� �IDATq ^ñ8³-ÆD¯Ö(Þ|5jo-âÉfG͹Éš]£‘XĞʀŽŸE»e„ØÝĈþ!á,ë€ßÃÉSNðQgë‹^j½ULPY\K%¸¦Ù-£5™c}`½ãá͇Vµt‡ê<F4£¯G+; ?NÅŠôùxŽÖ~žÁã£}‹þ[WÈÒ—OéXOç·S½¹»¢Ù%ïÅËFo;(Ã\:¸¥Õ‡7 _u‘²Ûl #ćÄ/î�gô‰œU3ÂC=${ybùéž(œ÷9úeß Ïpучñ óП¹âŸ¢ûkFÛÿÝÅï(þË~N”nœü˜5ÈŒ|P­Ã2³<@Æ‚ ¬pT†Òdddd”÷h ™Ä2222ò€átæMØ…BËh§Ôl,####£Ñ “XFFFFF£Aq¯à®]»8¦Á>}8G2ŠÃªÄ\Ä çæælý˜‡v;ï~ï»ïyÿ“Ï9qôÐs/nݺÕĸ‘‘‘‘ÑhHïûÐGfW¬zþ©}û}ȼ‚FFFFF£A#gõGéðáÃyóôAÙÑY<T«6Øåæ! áÌ\n/2Š#_4ÛF÷≽n˜i×®]­3³ÿ#wŸÞŸêÜÜ\ûÊC²jƒ]ŽaÒÎÌåö"£8òE³mJ^¼%ó ™Ä222222‰eddddddËÈÈÈÈèr#à g3úô!Òð¬QØbjD·Ð`_¤|•G·êp;Û&t¨†mËÈ(IíA Û<O+¿<$/b4Z»hä%V{ ²Ü9ò¤÷@„ù0(ÎflñCà •‚Éœ ðÃðlï’UN½2õ¦Ÿ¸Ž]à_p’>œÚEàz…‰(Ÿ/¤±ê“]àö¼A{?—s€£5­ïÏÓ‡jHC²sÞ3 ™‡áœ:õ*G¿LuÔà_ƒ®£ØEöµ&êžêpèÌ+5×7s1F0¢Ž^?}‡4TÁ@œiÈã¢×4C¶YU¿ŽyÒz=`5Opùyï¼ýœ¦!ìEmí±G‚l™“0r½t'Q-><êS:1¨‰óÄ2 :mÉÎÆâз¸RìÕÖ1üILàÄŽ§q¼†ÆªOr™í¿!QyRŽì¡+Û9øjŽu¥[ån†Ëm+‚/ÛÊÂÆÝ‹íWAb¹£T8(xœÂ°Dÿwá bxÌÓ;$|ç\VÃ@öª·pÑ1§«0;ÔhÚ@B‰È|­?VÍñ­Õš¨8Òo†Áí3@Ù9À¬§ÔÓ‡dHÃ¦Ó |ø`¼ï‡<³&ûFö%ðù”2À¾ ˜™Fž [«ËT'»½Ä41?‘‘‘‘QŸ$V‰…8¢€+FFFFFý§^y{ýC###;GFfc™Ä222222ÒRÜ+¸k×®}ŸÁŽ|nnî²}wÒ¨ÏÌåö"£8òE³mÔÔÙx÷{ß}ÏûŸ|îȉ£‡î˜{qëÖ­&ÆŒŒŒŒ†æææÞ÷¡Ì®XõüSûö?úÐÄPY FFFFFF)ò%ÖÎ;mRŒŒŒŒŒ††V_ú¸ñî÷þòügûÇïùÅïØ±#¼vm¯òLð>µ—ºsÿöOî5hÝ6Ú¾‡6¥î½!ûÏìûò”üµÏ+ˆÌ|õÁ d#µän›>¿Kt3÷b áfw;¿ôÑ ð GF.º9Ñ© æp&£·:@ëø›è8 ?ÛøVç§nmb.HM`·Û½ç?üw¶ü'¶íØx÷{ókPAwZzļÙì3»”¯?¬¿o“°ø4pQªfè…G€áMRuP:€”àôDfJT€.ÔQtògtÌ[© Õ–Rr+üÒ“šÞÍ_Û5ʾ>/®ò«ÊüöTØèŽhÉ+dOHOE…â|Šæ¿sù6”a$²qû3Èìd-•ÔÈ‘·Îš€QÅŸ±Ô\-›1 ˜)JÝ0ü>ÊÁIàíBéb2ŸÖÇS¢.ðüß])éŽ<øÑÞ¡²U¢,”û‹ª0ä`H·ËV÷¯8ÔÞÐ"îØ‘*[jaÙg£Ó3jIìIAϲѽ/o„ñ 4|zöAÌ• MSÑ–u¯dTF‚z?a¼½VÊ ©¾W°â1«nÇ(DŽbœŠ;(îÖS>ÕO¡XËYxŸêê®õtM³ž·>XÞàÓ=.ŸŠèDy®(D$2+u|t„üÓ{gßóö1ï¬SlÎÖÍ!¸sô ÙÐŒ'´ü”ö'R5ŠÁŒEoÉ1®y©‹¯Ä–*T†Rû?êR6ªSûô0@’b¸MqöÂ5ÕSd!ÂåÃU~ a 3žpJ=whŸ•Hðô5ƒlìÂìÛiâXµ\|RÿŒBë)t7™q�öZ`T”÷å¼µÄà®¶4<¢ƒÚòÌõ)Ȫ•H #ªµÃÕ9x$LëMy)]‚ØÀO­d¨\ &\î=´I'áÊIà)Èg^dµ›Åj‚l£íÝi:@ëº9Ñ•Ýôø²ñºêâ›çºL™óBªpse³“½i? ûãyYÈEOéu’*²d½æÔHÀ ÉÁñ¬[Ä•UèÀów+<*Mð¥‡rÕªz•À#x Jì9nj6S÷zêþu?0Ôþ·º•�ñ˜)k]._=C²Vཊ)ŽQß_—þ ¸¨1d A×€Hý$”êX)ÿvîŠð^SF©U.ÝÚE¤"…ßrÑí§‘XýL€ˆThwFwšº×S÷P÷ú‘±rFbœ}6øù©n㊬=Ð|‰Úm"»ôë<<¼s,;!Hb–‹eŒuâºU²Æt–S3…YÙùqßÑ{ÙÔm­O€Dk™)!¸Üëd^à›¾bÝ_ßxåkúª#^Áª‹AIšZãT$k%н°GK"[= bG#C K"Il,ú[¼tW Ù ž¾ž¹›Çm½‚!Födå½Höî´–—–¦œu¯KmW>´£_ö£«d–«‡pSW©~ªè­%ˆön0¸2«V˜úc"#æç!`OÝ· ™K6W—FµæY¤‘à+xБ7˜öMùIAy¹2ÊLoéJ9|o½‚—¡¬nmÖо×�Ådù —WŸ€EN f¡ˆl+Ø1_KË ÕZˆ4Ôæ¿EÓót›SÁ%A$&“BÄý¥Åy¼ZÅŒÁ$n0?°2AêÄoUAb P€)XaÝôb…³bøa^û,Þl·Gå·ˆ_·b‡ÑÙEÕ¾HÊYè¥ÉZr PÁðí‹Â˜\.‡•Švй§ôLNPv—â‚,,rñEQ$4ªíWÞöK‰„«†°\Üì~Ñ¿KIa/Î\ªÌªZ½P×HUŒäéàZ@ONØÐ�Ô-D ³ˆóªnß‚O"�bbI ‰Û~™füK¹¿ÊúE¢ª 4 •K*«¹èxÓ@àPGXv úŠâ­K`7qõœñ‰•’©/³ØE Ò²’çË€è±Uœœ`?eý Ëf–gù¬n·x[‚I® ¥WO �ƒ‘¹šIå/.õ öº4jØØhß¼ñH• ZQôn¢¯¤Ìˆ<HåÐ*È.Å<jäA—µˆ÷1¾PŠ‹’ÓHUÆ'|—›D`Že¹À“ˆYC‡o7%bk¼~€ôµ’ª#8c©‰ÒT£õÛ´\ñ¯›Ÿ=rI…«ËeÄC݉ÛHÂH9êq6Bâï…ÚIÖ<Õ‰h÷ZQR‘ÍWâÊnÞ"jà2æcjiRZEy÷è¶€~øfe+0'£Ñó€»Ð0¥ÏÕ-T§¥ÞMW¯%ÕÎD¦•wJ«À|DÓRÛ Açc\ÿ©›TI>ˆº©. ’]b)º.^í÷(µú©ÓóPaø!Ò4u=²ESi5¡Æ£·±\‘F3üQ™þç€ô§Ÿz4¿ò•rgQb¡ÔJæ±_ —ÉS*A Õˆ^Yîd‹&:‡ÀqQל¨¸tT"ë‚wQHÙ¬Å#Ò RÊŽ/¥8¢ôé’îKUBH¥VrEÒ«0„>l¾µ!®Y›]Úf{ ¶xõªúÔEqÙ´‹Ð›¯h@œýg‰©ü¡uBЦlDê•KÒ.HÞÕ‰_©z„tÿ’Ôópìy°z¡Jc¶ðWP]7 –ÄH˜e½pTLg*¹LšÒR÷XÖ:-L³öÉuÞ[R¥ãIÔµnTDN0¨¯|Ÿ3…äˆúúpq.zë>$Ç㉩`WûÂç2³'êL]¢8–J¬>à-•wô¨õó*ñž ­’;÷ºIU¡€A|x{‹”XØxIa?eDêf¸¼#Kº3EÊP*jØÈ`]¿dÏ0�·½ÀGàžÀÐY*•”¢Ñò.D¾n¿›.ª�_­€yAXÍvOSŸÍØ»‰UÓý¯W«‹†¥K‰»ÍâÚ˜"ä)2&¥ŠmÓX†ýé:â!:ÞæCJÖìžäY jG+¢ã–÷é¬v·K6ù7<øª‰cõBؘ˜¸R aׇUœ:ÜÃÃÿ oµ 2ªøWøÏhŠ#˜ðÖŠD0yÙˆˆ"–™¬*ÀC†K]8U:®1ÅÈ¢°–ôHêŽmS¢ ƒ&;ÉKZ@K¦ªo(MRßHu×SîÙ«Q—ÉY-[”SÃ4ª«èà.¾¿(m]”ð&òk• É!#)/R®¸¬j+_j‚—o uf™4í¾ÊqV<:¼^gê…ËÊ×ö)³Û¥>„º Ž}öGŠ‘ÔA;T%e…gUšk�ŠRÙºAò¨j¸+¥É]YHª’ƒ V¤…Ψÿáù` Œ£Ï1ˆ¨ù¨hÈ™H}HˆëN÷PG§Â â^0M(ý ­Áv°D\ wsu’ö<™D)­P¤ 8„<áà|½ª®êEç™Oá†H‹gy8ƒºF¶TuðÊ·KšÍó>^Ä D³'%«µà…`í©ªÓÀ~]{hS_ãXUØîð÷zxUœ„àa«îðÁ½)'¤UÀ©œ ]ÑÂ]8¨®È¦‘¾c*«¢–ÕÝ$)-!*¹³Àð¡Èt›BñžeRó‹83ÃÔ›°”LºÆ"÷®²o{Çê:ÀpÊ•á¼UßÄaÅW«Þk7³Þ9Q‡½’‘#xµØ„´|ŠrÉÙœˆZÇä_H¡Ó¼ yMdl ´¨aG³ið.Æ”;¢¯xÛ) ´Ñ뤪pW»ÓK¬ŠAûrµÊÝHˆÌ*x*ÇÛU�=¨í˜T[9^AúšL#†¬/QôÖŠn¹ŒM‘D®å¥`ÔOXbsYüË)dÙ&–YEfËRˆ-:ù•WqŒï¢þXˆ¦.ah ŽÅíi¬âÙ 0ž'›.!Íz¶E¦Xúž"ðçQ”©4∢öÜLÇá’œÉìö5Ž ¿w—;”ßÍ_^[¯),O'‘\¥z~fóeÂsWÚ«„¯•+°C.*Ê_-íTtµˆÖô€ª%|.²“ðÖy8ë©ÕG  ˜»¡HÓJ%Ñ™¹bš=ŠŠ[ÁtiRþ6ÚîÉþêµ½¡‘‡Š@#E\(t� U¼.7µña˲ÛûS.Š›ó}ë¯X]`—'¿ájºi“â&%xÌ5¸Èñp}x—�£#ƒæ—(­1«×W faauésüÚyó êÙHª8“¨`¹Ä‚ÉŠüòU _Ì#,f†O/SqÝQ *­ëÁTE±Âï\] õ(®Øg_ªËxγB¨×ÕÇåºs9:ŸÔU˜µŸø†ÇED]\¥oÍ0z*FH‰ry¼w ÒðTÂðã€çÚe¡4<eÌV/oõO†’ÆBxj‰º#Ä›œ:k ¶ÎP9 {1¶B_–(l�r±ì®ÕY ß…øœ{„–°QÄûÚ2‘”~-B<RÈòì}tȳ ,÷©®Tuä¹èá SçŒÉÙã¿h§PP«ãK,øÅ-©¦O £‚ÄÒ…"úÙ·¢›®Š/»zÓº¨eYÐ6ã¨Î,D F¬ë%!ªÄTKèlf£é\ºI˜Ý™'Škª±¸p¯¨º(;QL¤P¡‰*¿¤âI¿Ütv$Z¾š«×f“®–bàæWŸû†è‚.=‰nºÂÌl�Eîr*Y U̓´Y½§ú~ÊÚÃ…žOéXKª”t5RÕûOf›„õÈ,óªæ,à%¯pû•—2UˆC>/±YþÞ0 ¿ÞÙˆaQnÌ)þÒ/ùè}¶¹¸N`è*¢¾Ãðie¡®:UÄ#x1 ëéü„€²Júvê‚qµ|¶öÊT> _O‰ú*’ƒá[4 A=°”Ã9£Zý±FZ> ¡Œ)ÌéRë\8‹¬R’)uvá݉ð”ÂZîu³=ùy.äD”nPt1›‡¯×ŽÆ]ÔXþH˜òµÏY¶Ë«_äDzGWŠ©{K¥‰wI˜c• |*±Û 9Q ‹ÅA…ÏëÕñÊŠúi*+]ñšÙ -$˜”Q 2/}¥óŒ4h�Qb‘ [y†UñJ=yÅ“IžüÝŸx‡¨kvsA¶ÝuÆ2BHz< 3e¨6¾?Vaÿªºªëðg*Šl¦^w¢V€ÊZXu›ª»ÄcËêùä+N@~WE¬GVW‰ï4*3WmaÂ'¸ßt9Óå‡Kš’õé‰äÏ0zWÎU´ïÁÚ,<•¼‚#í�¬"­««=ò•�žúI­¬Q™*âžMù ðr¢p о´êV÷"¦6ˆg»èP ¥œ1…D'å§Q¾,Eêâe ¯‡eu¬h‹™ÔTì÷¡–÷Ù”%)cá/H¬žöŸaá˜qTˆ¾¹4 Óg¥èaŠ‘è�”ƳÏ Ï*ÕøÔ( $LZÃÍPi©Ž×®³Ë«8!õBQ/¹Gì<Æv•3¾„ìägÁ2¢ù¢ÙÃX7Å1݈ÒfcU3JJÌõ`tÞd°J¿<}´º²'³¤3aVS®e KW¹°é{”"…kUÊ„^S+@ŠY‡Ÿõ1,ñ—3s›Š“eÁ¥Ù@j €òu_œ«ŠM ÿš½ÕÃË�[­è ÚŒ�Å èèOÁéòÙäà"éa). žäh PD•—“–à N?›*›¼ s"!Ò¯SaJ!ž¥ù„µŽ3~[ÑÙáÎe*¸æ²³±Ô&Há¦Ñœ¦ø…b„ŠÒH‘—@'¢VRæ J\À„Å^"[SªY«{De!|*Zóá«¥@‰ó]tt±CEl•°¼>ð´‚•‚Èöf´WHùöÕRPÑ4•ßee¸þ¤ìÕŸŽ´TÍZ'‡šÊÆKD …m¤p|áü4%¥IÌånUÄ©%‚€b,rܲ‰öå#L³Q£“¯;†¸EžX6QBd=(Zš!åÌ"E-ì-úmvHÝq©ôwÆÉ“UžÓ>êÃ/É3r7êeac!™3}n)©ˆè”ë R_µ]¤'fºYRÈôÙvPLÙ¿Bf»Z$ßeƒá©´‘Zý}ð&©ìD6mèQf9‡j8£+„`½k{Æ_ì•ú–è©‚ð€QÏž©-µÈBø•ÈŠ 'ÁÛ9¨ÄªÕذÿ®?†7èoQ¸›¡cÓRZö/j³} œ“^Î@ÓÕ´X!åéd䶨û1õŠŸx#F´Üjßû¤à}å YÖß}>Ã-”e&É€'I IõyI€£¼´f�Ùí嬤$ïHª—©agqÿ^¡·7­¤Æh ¬d›2:²õÂRZdg€y\#%@eÙ̺vu+áÀ j Žø©£„�^0™«å+\gÍš>$OëÍê©)œb¿)V9oü)%Ö¢¡!ì³¥óá(6–BG–âpg3zE-_E ‡ÔË—*X;R¥€‰àTæèý™ 3 ƒ³Ý‹z]Ý�ßÞžwQÝ3Y2E?ß*éˆ;].rMsue˜” ¨µÿ¾J¬Zùx·uжÅ=$º`XÔ™[N÷e µ-&\„gp ùÍH5>ˆ§±Ã'|ÆA•N¸GTa”GY<ox‰ ÜOf)š+X=óVaòå%Ì€Eh­ÑŠu]fot‹êÕøÅmLÞîf 5�~éi  çƒ_©a±±îr¤ªhZ¤Êç‘ú¬ª[xˆ¼LŠü`õUJ؈–)ë:ã)¸„( ”†FÞÅ£¼69¥H-Eo0©üf&á‚àd^*)˜ÅϯŒQçl,i”èPÝÔýWÔ}OÆåÀ„ RêTh dAÔ˜¢ˆæÿƒ‘X}9…+¯Ì­À' ÷Kñų֌´Á¦è˜¥,àîtÆÏ}J¨¨VÁ¶@€ð©@òàSq&‹ìWÔÌ*ãUÍŒÔHªUé¯HÓgŠÙV÷ ü’î€èÂÞŒU—ÕG»›©û]êþzQꬨ´Zîî¡M†Ò©` {¬×5XC2²þÌh؉OÒv U˜¡LWºè�¢ÓÕÝ蛢Ør€ëVw!í Aõˆ_Y¦&Ëš«3 TùZ·«¥ö‘*XÈ»§xK‘ñ¯¶Š”4U2›Íáé7íùˆ`÷zêþêî¢hƒ.]Ò–4Ù×z+±úÐ ¼wpæR ¨G<Q ¼­5/P /H§KäA ›‰t§É{5‘gŒw‚!–e9„ïÍ:X˜Ãs)AU‰á&L—¿ÂÆ4jÈ+ª GÀ{ ¤ Aš©KB(Îî4Ê©RN—î4u?@Ýë•Ü2š¸‘M´ñ õðÓ4`«ÏîÁ/"r1ÆpL fwE&²îf¼{^ʦÆÇËTƽv=.ßuºÆäRGœã üŒ¥$YO5ZPc@²±ª€4F©ÙoÑ’¸pümö)S*'R1™„žŸ4ƒéNÓ¶‚fЄ%}¤ fðzÄR£Ö?µrFE0"E* ¯$JÄDˆœ¢\)¾Í{hSΧßl ]Þë›å f¢0¥%Œ²$ùB}”í³®ð@òA—”šœ|6~àE¿¢»´$6ݽxηµµr\_:“F‘rû—CÝë2ŽT$±¤ü}¦òÔ>»"Ça[Ú¤J—Ó0,Ñ‹‡ÓÈ{Þ˜z#…s\aݪ»"VcÅmœTyC’N`ݦ38”Qyˆ4|¨4 ×)+Æ;²qÊÂQCÑJÕK §’X¢¬˜òÞµ%ÏI-lÀƒZö37 šW~g†›šÅŠl´è›ò‰”U„7âKÌžiJžmA±îÆuÇl.’ ™÷ÊJ¹¡Â{‘E~"ÚJ­Á3Î,_çINå gcœ:¿B¶Õ$3 ~Kä%V-ï|/ƒ%®„}¨} +%~²YìÙ£˜Àn²Æupõd*¦"Õ �.A”¥†H¯Ö„ÜÔ‡˜¸þâYÕÉ=AD’”{óOE$…c?ºâê_–P±M„” ¹ÙƒTP/¡®­V44¨âsF¼ÞK‰m¬ŠâgàR­¢ÝÃûÍBý7ë"càétÖm¶vä#`ÒmˆÍ͈¼‘Ù% …9#Å:)9ùLæX6}Ÿ°…¼¬¢2Z/@ítª†´…Ò¡;Æq:¢Ü ¤*®$zD’|zDU4>ºÜ2¢\ÁŠ-Û{êú—Z R_ïXW§¦‚ÒúEèJYsÿ†Ê`¤ADùlâ¢NçÀ¨%å±Ù2a3­åà}³åRÂD›Âö»…'E×É4¾8 N`~ 3KR@N…Èqpî¤Ü£‹â –c(.È–ÈH7q4±²n» )w£2P‘†¢0yuߢ˜”¼57 ä¹k±º ÜW|%“ºóµZywëXEíµð¹¡èŠNo¸§X ‰I‘+…Vñ¢ÞÄ SPúJ©ŒÄ*ï ¯¢Ê|þþýGÉî<©º¤°öøM új²÷äS3Êå®Ô‡¨8Ѩ˜´ËI-·X¶1 tujuBBnÈt)WóÁùa¾¤#Ê8/ÉjÁ9¸´¨–ÇJöz`âE¾„%õ*òÏ1ÌSé,ì¬Sh´)ÊÈ˵rdºÁœQ¤'U2(६T½EmÂñ<l—݈Jk˜ž]_^ø•¬{•þxÑc’ŠÛI}ˆ¸íÑ‹¢F8•ЋìÅRVÍ3º£6©q.ñ“)vxÿš6–¨Š¥|÷§n÷‹Ð©AS¬GÇ�Ç-DŒ-ÅŽ—f"‰‚=Š)J1zõp1lj#ÕPU<ٽĠ)ºpGjއ›'òý"É« j( úºF›¼ Æ^qRÅ ¶± ‹Iû£Xáç>UýžÝ1%ièxvFÊVÁÎDºg!Oñ¯ì0@GŸÂYn`ĆPÀ†Vz\âc—&ªàƒÄßo½–ª‚pŸžê]’uÿ€{˜Ïfñ»–êT# ˆ6µ¼v%ý’˜&Î~AN‰Ä¢ ¾ÚŒå¾Ä^d[1Ži£¤âB1\ 婱øóÐ.ÒÝXýèðÿ ‹Tï%0$®x„(b”:¢¦0xžÈöâ²€ù«j‹D$/Á}´!£y§ Ÿ¥FÒeÒm3ï·•3/j¹h«ä>H]U \áå–+MÄCwgkòu=u²­umw¤øŸT©`a¶KY :0nHU Ùf Yé +cÌÊ�� �IDAT›ê6€­?ºáñ€:ÕËCÏ¢eVÄ ‰~_"¥R®ƒÝŽ·C.l`¡³HH…c[~ªu)"'gžÉÑ&º9[Szí‚ò [Œ\ÒÑ1åðÉòk^µdrpÖɼ» OJ®¶Ýy÷oIttÂq‡?^É+C¢¦0j3½VÃlþ’@Ší¢'‘ñ?ES±J%ø ‰*ŠUŠ ˜]¡Š V6D«)A>Q©Á)¼BiH}tRÄÌl0<tbà«ÿèòq©RY7*+<)8ôbÅúnã@ý,‡%eÿE bId!ÁJ<ºŒD©>!r;#‘ ’N.¢‹Q‰UÅø2Ž)Ž«áˆ-FÎÖ=H!ÕIÛ¯åA‹%£L9T¤ÑT|Štmx§¨(¤§®ï.9«YÇZ3 BÊòð“ËÃEâþÒlÇ5’'ñ“Ìô¾{Xó{oM®0JðýÀò¸ìÌK;쀞�öZÙmD P_®X©›9üÀ¨zÌÒ6Hj¹Å³u2E‰SŠ;Z‘$À^²[Ï äÑ£aÒVP„J˜ÇîñöÇ =ªè°Š·1ŒÚè@Öâï©%šr‰v³X½ÐÃ@ÙwIv/$®B°é܉àD9¬……î”ËW¼¾´Í³?²ŠÚô]v¢[µÍë²$¢b3Y!Qàs]ñY‰RÑ¢Þë{+b|:E[¶=BQžˆçD‘¬™ä ¯Èì& $hãfƒÈî-‡ËNo{Aµ8–t_–$dgýÈ"èCï>>Xq°q_®´ÍX¶K¢Œƒ {­"Þ~EÒŽ—µ¥p/(ÿG’¸\ò0ã³^ÖZÉ,jEt±¢E¨8o ÄegðpA 2´ÛBk»\ÒóûYÝü‡ì+;‘fßz‹ÑòÀЂԌ@’Ixw%3ÂÔ.g/Ò+Þ9–(bÊnܤ¾è}øîy=udë¥þF‚!óÁÙß º›—UkâÙS€K¾ZëÎh÷ âÈø{™;d{1ƒ®$–=ˆ’Ý‘Ÿg[¢ðá@0^ ÚŠ³–Zßl -ú}Q«D-RpÆg Æ–mT××#ÅARx”YƒFÔm¡½_º‚L¨ õjL2a’!IŒÒÒ(Œºt-·$(u<ר¢æ&U—Êã/_Jo½”™ZxŒ ÏôØGÓR¢¹ Q6¯ä–LÄgùò~…Ôg<\*k×%‘UWÄcÅ=Exïi¹F¸5A (²ÿ¬}Y )?ö—’F RÉý½†O­-–Eú8@ë>–ÈÒP®ìLêBr£N<²XRfÀœ2iJ‹.©áéH‹�†‰ëò¿ ú¨]îê]'2³3S?»‘ Ùæ¶Òn•Ù[!F’7†§Úù„¸¢Dl«â¬T§-IÏ+ñz>ÄbËê¿ M¼V¤6„ÈË]ÐõªÐ'¢Ùê¢\V0 ZÑ™ÞM-á]Ô®FÆÊžGf½Àwgð±j5ôÂMEù8Œ¬OUÚ5B‰yÑSØ|ÒFÄÂDb Oæ9]¡…§ë %bÑ3χúÔ†T UˆLO{9ÍDÙçŒö—-“P'UÁ™”úp8sb±SRªX’ñ”ré—]ç‘G¹L¡ùÑÅ䦶—OÂ7[VÊ"ò¼Ö>"›‘T”+X ÃB¤ ˆúêíâÐ+-âãLµÂL¬å õ@Rh©|±TÉÇßÄ!Î*: qk^*³lÈ<RTÔ7U®X´)…x>4ãk qßñù¸ØVL…ðËV|"òµŠçF”¦uçHå: Ó³³¦|QGÇÂêiL›‰÷ Jn)ü RKœ$ Îwà;0á*|•¶uü©kƒÀ ‰*¢²_JC ( è-ÚZ¢Ne!¥\Ê 3“»Dd¢Žò ÜZ*ð&íŒLX)·îà„©dœ?Ù˜Ò"âc@œŸu“Q£€pz«„÷)üNÒ.õRÍ·¢_«"€Èõ¢Š§kç¥Ø:P+ƒdµò®h© ·¤‹D8Ÿ"àŒì.Rüê‚f:MÝP÷I³F]ÀË÷e–ºîÕ&‚þ'Úäå Öyç^y£JÞñø�TV‚-ráŠ4-$˜ªŒc‰˜ˆÇ�œ¬èz#EÒ¼ ¾il¶Ÿ[Ö핯|&B ø€éÊ*:¼V ŠœB_ ¢ô© b‘PÕÜBç•Êã¨éRÀ{¨Ûî~L€ÃÉ‹giÞ<¿²¢` ©ò²i±¸3‰Ñɰì¬/7\jR§Ÿ!V5Ò….´£éEˆ+›_ (»]áv,‰3!åY?lÜËÆA¥†Ñ"‘ƒÊ”bHMxÆ•-s&¬È{ÃxŸ¥Æ¥buJ`~@_´Âè³§âsÌžÉ&D4;¿»™ºÏP÷ÛWZ EmH-V¶ì)Ûy »vLèEmÏ¥2GpˆméCq€¥(+hxTÖÄä&òZ#"�œ:¦öKÇ*ñA#CIIïl­èæÒ‰.W“Õ~ÈTŽÏ’'„µ$©Sí¿ìF£_:‰ŽA¤ÛÖ2§xåL ~Éû?MÝb@&Å›ö¢aÏmë&-ëV,âTË*± Ü5îypç3IgRÔvÞ2‘űx§"˜E£hiŠç á;¦ŠÊ†¸A¤ƒÇ‹3ÚoÚŃYHS‘Âjæí²E²"7r¡fM´CíöØ#u æ®˜<ìÁ˜AL}´¼MÔ]„@Q·WYÅó.Ì|6,ÊšòLÌ•¹ œ!­3Ñõ—ÙX%é¿êÀïUÀ]Xêb—Š[³?õ Eö»(û¿0ï °—ka¢šéƒæÅCì¨Ùk(’£ïº•A¨p„–lÅ)@œ…øÑH«•4›Î]YENr¶°,Œ•P‚mü•l¬#Kµ6�M{¼Çn—øP“ÁD•ðê4-\aDÒððvv…£$å¯ÜÅ”Ð#8µnj–ñe½¾|#T”ñödH廂°÷xv¸º½œÈüe\mÙéÊ…ŠRý¦ÈwK /ÌÓ)ìÆÇ;i Ì i$,/Õey–p…ëŸñ!öˆ- ‚YÂx+kÜÌJ¥AãXŠ ššºè¬Fí<~+êàÞymJeBY Ó)ïBÊà+©WA¶Y–3‚v€Nƒ©î¢ 0‡š—"»4 ž-K/·qÁ~C ªÙXHr]º gmO©NW¥²8[öš2 Û¢$ÃPzÚ\á9,¾ï ,å‡6Z`žP ùéÊ˘«¿âÔ1‰Ùvw /åJ‹ð\h¤“aj»ÓTÞBºäšÇ‚5`¨2›c)zýÖ¤Ód·ëô)È4ãw÷1¢,«õ…ÂÄ *}QL”´Ë*ÕF„bìéÐ0JÅ&Á¬6uðFMáÅa =ˆ7ªD›G'þÕ×¨È ñ¯Õå €5€\¶[ÚïazÞOùŸtÎ�DQæ£Ìná¹¢ºG¨ë뻄~*ÄkW¥¶BFò:”"5?kSG+ù“†aãã šKE¼E–Ÿ¨‡©ÂWSØÈœbUz"×¢âÕ²•v)˜p„IÚ(–G¹ n©Q}™…`ò @÷Z ï*ëûÊ"‹Þ3™ìÉQª‹XUª Å[ $–ºŒ‘½©*“ì&+t[gwj4j-õd–¨Õà©qX:»àÓ:½¤$ØPbR„/ò©¨Õ¾2EèQQ6÷²‚^Ü(U5j†ˆÏº™Y«BêüO -©—[TÎUÒ<]}IB<Fj÷�­Ó÷Ç”Õó¹¥Éè iחΜ‘…§¢ˆÎvóÁ‹©ˆš (ìþ®sû×ð8sa‹ °ø75~-W2@€p…,û¥ûŽ`Z×õª/ç-N[¶Þm&ÂlÚÛÁÓÓy«ÁabLˆ*'BÚ[ÜKÚ$[w©Xª¥ÐÁy‘–MÊ3à+Ê0l"«)§0žÕI…NE@‡ßÔ±”‚ÔñG¥Ä‘Ep"óv`/«¬ø/\_ÄaÅÃ(`Ÿp‹³w•Ž¢2#Ы‘r³‹>ˆŽ3ŸÅëw"DV×R‹fꊺ¤„PI§[Š¡P祤³ Ò DkÐy„tr1ôâÎni§8Þ£Èpgü¹U DÑ’Hs0/Ámᯀ4¬RªzKñ˳ÓËà>à®`ÜñŽ¸Ëø(5¿[—2o‡QÚ[”TY胗·ƒîß,‚0H¸ &UâyW3êC~fÕð ½èØÍ{¥ùÐ=•ÌâÄ¡Šûy‹D‘9 [‚ÞŒlÿˆhj{aí` 0%€J¼®;kI+8^òéÀ$q[;¢Q‹ìx^ùeÀX`ª-µ4¾’ô8S•Õcá`h ÍÖçW äHÝDÒ`IEïß\¼ d¸Ô0y„ï|¢Ö kV*§@ hXõ±(æ_äZT¸ªÊ¶RÓ'+'²X6:c ye];]›ìlS(ª—2žJÄtñÀx3ß ¬÷Gm,…5Z+®#rK*8&©Òðp8T0wt¨2®ƒhƒG…ÿ —¼P Ö,"»Bî¦TBÒ& 3cÂä3š è0á÷-ÏÙݽq€ÖE]|H Ó/ÔED&T-n€$ÄB¾ñ(n:O•È?!J™F„–´¸"ûælf%·ó1T³M»q&…Hެh”Ú(xfŽ¢5»Ú‰¨f Ü嵕øUD1¹Tkƒ(“½ b©“)=Ãwø¥ âD€¾j0¨ ˜>бP£oÆD‘dTuA%ò!y¶SÒ'E‘n: ¤ ߣªv‰ *•â~_3ó"k2J®=LÑ‚,ï� ÂJzQ’<—,¡UǪ¸#¤šWȘ²V&nmˆº}ªw‘Ô­—2a³èQK:<Ûa­.ÃR¥HL-¼hòÚ¡:G”‡…çê´¤qD6nŠ¿ ¨¶ÕƒF¼ÖGÕAlgÍ}1JÂ@£G'tù ê–½¾L½e3+^Ä5³ÔÏJ•¡Hï zäS:J ¶*)«(+ÉË¥,·WR¾—ÛQgŒ2sz²¡¢ý·RÉ*Ê‚Æ]È•.SÈþ DèI ¾ÅWŠ“èteJ“Âq”íwP±@¤P6 ‡J1¶TT©ä¶z>±®n¨ÈºÄ«wAÛìλYj5¹±l¦¯„HCœ¥8~ 2÷OÑŒG*‹ù•(‘àì!œ=õâ%¾°-­HAPHJrJA\ºl»,dGñ™ R@+È×m¨3 ].Ùå—bVŠØœWT‘ÅCBò0‘7r¼+†mDY‚x^µZq=`º2]Ÿ8j3 ÿ3~댸%ª0¶×} ²LáfÖùix‹ ©«ÕvÎ+ä’J&àˆ´¹ RÅÈØ0üüè%ÁyÒÙÒ0^¯”úßDaüÔORÓó™yY°\árÄ[(š'ñ½VqUN—,Õè ÄŠ¸Kvft‚@T´øÑù@{lÙÅý’º²EÁüHfû ‚û<j§ªwxVœDagCUµÝU"ëˆ{P_Ñbf6OQ® b‰úÎ)<­›pg+·J´?E8ZÚc-¤A˜uX Æû¬¥1vĬe©à‰à)_YÛIO.q_31�i‡F´Ÿ¯Ô’PÚƒ 0¯T³1\iv¡“UDê ®wJ󿤩Ñ)·|ô‚èÁÄkx }GGPP‰TÝÂýQ¥ÜAÊ+½©Àa°¥íƒE‰Šm½£w‡±­³Ö*¨—„Ù;ð)-:HˆBeÙRUFÔ¸/«ÕöJ•óN’hS¶ÓR­îº¼í’mL%uöê€ÛC­¥ÄU[µ²Õ½dÄ «B‡WÑû\ÒÇs‰ˆžŽç†‚/¨@ÀD "¢ÞÞáƒ;ͳbÑ„àZ„4:ÑÙI"þËû@=<À˜×¼®¢ÖÏŒú(ÚÆH I[Rï‚}+̸– iÒH:{¸ÄjØÌŸAv{Wy¸qôt¹SVØw™÷â¨õ½�rNuÉÓ!–Kk¢DÉ A˜#ÀÏÑÎRŽ[Z ¢£¨‘³kõ_¤½}ð†G÷ Dz·ŽeyŸ|˜MfÁ"ªL¨ñûSM™–RîÏ'ìˆzɧΠð :pw«TiYfá•Õ0/J¬"DgÄ­b#:µ|ƒê• |­¶©{!¶I±$ϰWx>½)¶W‘÷7}œ(‘k1›ž2¤`Œ¸ Õcð�OAÙ« ¢£Ô#¨Q¼+W©EÐ8Ã,<‘JÇžm€¢ðjpœEzkJ³×"˜£n™QØ)ª\:JAÿt•ž•P nF£¼³I]‰epµ3*öH಺x&áVÊ:B $êRÈKwPr耤6+Žj!ZGÞ°çÙl ¾háÁ©&±(–ÞÚ#碕Hi¤vG”¸¯@ùÄuIÄÉŽÀìFcQÙ”N¾2A]¼¬ó§ë8£&ó¡²Ü§V�lkú?S-.ÿT!ªåÊ®¤Y$…îBBô¥Rï˜ÕH¬ÔM^ÍÂÅ*Œøp“‹$4X°¤8àÙï•ý±Ü¼£Z}¯)ÖØWtJBÃŽ™Rø>ð(ª5hFíöTK³Ë ™—¤ÿá÷ÁóëRa ѯÔޤ؋?qj{HÊ;jõ¾á½¾Èl(ôKƤ# þƒ0‡”Ó¸P¥ëÑÏE…h u<ë“lU+Ɖ] ìÍ,²mkAx1a ‘ ØuQŒ/ÁØÃÙ”\D6‹ ²üïð No nNdÅ*\ˆ¡Æ`Pé4k¼mU Æ›sWyD»pxx-—¨q¶mfa(šéûÌ´*–b8… eÝI.-¬ëp¿—I,dO ª³Àz R€0œÕò…rø/~7Tt³d¥®dMá.µ«§4FŸÈ›jM;~«×šµÂ¡¶{å"½­œ—!{•ïx‹s�E2\ v]2~)¦Ø‹´µÕŒ§ä±5m,]ä¬_®ü0‹r1=…q ÒÂÎî¡®$’v¼¬U‹j~Ø)³Àý¯U¥ñ€_ \VÖâdkf‘TìT˜Ê[bÄ .åi’d !Æ´ú°‹ (—ó¢CWÑ9–ðWV‡6@…šñfµ1EÌ‚I„á'’Xy˜5«¥(Ðí Ûg…@2YzI[)&§V´×«Wdy4« ¿âü”âÐPz@šÑ‹t”VNZØÖ¤\g×µ$-Ì‘Ñ�ª—¨èù¤‚Š b†íd‹ÍEÛU£/wW„ÏåQ.y§z¡o,…÷¨Œc‘6Âé½M¹Æ?H6¼^× @œ*Eã5^…))ø~UðÁTn±èðx=MR ¬4ªÒàF¤K•Ë P‹–LÚoZ§’�+U+ªb ®¡FÔSw×I»ñéöO6ä#j%“²ÑÕ?©û¶0:‡tïI]âìvÝÙ®˜´ZœwVDci:ó¢>zEzˆÂíÎd1HÙ3¤ÐБ–³H3Ô½3—�Ï;H­dÐý‡La-ÛþLÑñ#Ýa9>ߨ¾|›Iñ«êi XAÖåÈkQ ª–T5‘‚z»„¢4)@öp6P_FÚ4‰²êgÖÐVˆm©£Œ·²u@ã ž¯dŒä4ÆüBòÚ£í<vg] ¯òV)ˆæ.uá¶ÒÅU¤±€ÆPvOê¬[DØdÓ—Ê“w²ÊY*òM~N5.Ô›E�­îÿSù "­Z_U˜•Ä_¹µ³+ôze£Jˆ£)u“l®º)§\i«6v™$OEY’‰•äÈÅu÷ÈÇ·dÅ1^¥PL…Æ7⹊J…l‡‡°À9ìÕ©kR™ç(vhVñrÝtÙ1FôÖÍœtì+ÅŠ©¼Ô5mÉÆtdÙí ô ì—:Î[‘y²ÑÍW’ÔG§cåm~ õ>~<Ò&¿ÈSÁÝñ.,æ-¹>ZÕNH­^¦¢‹‡¤KÁ#õ¢—4Ì1DÐ` ÏkÆ¿u™j€ð·r±6Ôm’xs<ÚF©ÒÉc·#nú¨žÝèºt#dµp¾¦¨­K|СDi•–"‘$ùq›àa˜Ëô¹ƒnêèÈ£€ÖÙGdÕþ`«ÃŸÒ,gÐÇl'°ØGAÝž Î7_cG‚ý’&±8Ïaºt–ç=F]Å]ä, q¡¢›¹=5"8ï>àíØ"KÇšÕ HØØ9-ŠÈ\öƒÜ ÔMDí©ÓË”MˆêŽE½h5Ê¢ÚiKL¾Á€{¢¶¸R%Ê»‘Âó”øKA,’lr xÔéx6‚²XèÖS´ïÉ*FàYÆ}•½";‘‹+“å F¿|M5ÅLT 5©ŠBžy…¿±d²¥µÙ×5²(G�;3,ƒ—v”ÃÆM H«3&x„\ÊÆ‡ÔÀH!Ñe{ó± þ|láždúTyÛ˜/;­NIúkøW7¦€»CÕ^2”qŠ@ŠÁm\âVå1‘DDM¬TÛ!d¯ u¢Úi¤ô�èlmÞ‹ &žáSq?!sg¦]“ŸFáÙƒŠºªÈϪPQ)­$Ó•ú)ÌJ)êGÊ쫈ð¦ØZ%ðŒÒ ”H(R® òjÒÖ?`²òc )fc "Äa„qñÇ0º¯ ìvü4"…oÙüœBÇnˆDp[[DWëÅYœÖZî`œéˆêED˜¡Œ‡ö‹”�ÆË_÷ä+\pY”2~—÷a¨›!ÐYHR»S1åEªq ·¡Ô¢%yaÇâ€K³ºø*]ÿ‡¬E!º-.ÈSžye渴Ñ5+éW¸É(VqþI‡uËûšEÀ£‡M$áø¤^ÜTRó‚uÁ@§ƒˆˆ´(i— )HÝìvƯuaµÎæwè­åð uĄЄB:ï©"E'ÊÇÔ›9”‹ˆ†„?RÁ © ›âë¤hNmŽðU>"#@-Ûš¸¸¢´+O¸ŠY´*u›ó¬û"†Ì‚/0«›w„v8vQIW]4Bç�ÑM;f¤VÄÉV;0ðr¨, syÍÞ•-»||‘5ÂúÀƒ™…=«X¡\Ö£‹ÚP.}‰ÒùëQ­ÇYÖ µ˜êdШˆÔÉÔò1Ù|¢³,)Ïv¥²�u¡¢ØŠj¤¤)ëïMÕðŠª×þÑ$ãu ƒ´›ªJë ~#éÒµD6Þ܇w5§ršJ)}qÐpcoˆŸ�ç]%¡=n¹„@<ÎÙ(TöÎ 0s|„(Jžè¨H¼²g 9”(Œ õ¥õ¡<§Ã¡Óq7)2j›>Ú%Ù´å6–®a<[*IÅõÅ(JlVH…Õ³3Æã’Mšå÷ŒÔ©Èg჌ˆéÏ’É%zÏñ4¹‚Òö*!¯T øñ®|©>«vÝj¯|¬ ©åL-*¸¿ñ²3¼ôMçàEÚÖñCÊAD«É—�ã9T`÷/ue48Õà°AÝK$Ú‘V ¸-U‚  W°ÊÏ\ð<ùRÆíúÛ³9#¸_]—U!²\ùЬLUCB”˜,W NTQ±ßt î/¯¤§C¹ùåÎÞÌP}¥®b7unAoxvVäRP[?¢\Û’ ´ƒ-Á™ºýf”û¥Vo9áYB"ïh¹‘ŠO÷¸(€±(ø„§áQå@ÊK Íh<ÙõâOêÌŠ«4X«üƒ$û‚ Ñ)_É‹gÄIÚjwœ¨ëŠ:Wáæj€Jfuø¾ÆH„,eaDû FïÍŒéü.ÅùJ ÝðT7¼–(ë›Á³™x£$[š*Ú~êò¬è&Që"Ù¿–ó@H-©7^­“!w×c)Tc^êŠ|P©@‘hG2zQBs Ÿ41ŒÀÍÇ;p\¨í…Nšò=OqË)Ûï·ÉpÞ'ÍäÇB®–£vðRY’“™Uβðc¼4fèz\1šq < Á‘Iý¤œ¥ 2kaÐ(¼ñÄ&QGo(μHy‡<ÎÅÇñ²yx×ì®Íúëq- léž½Æ<g\d:£34ÿ“T ùœB�ˆdË_¤2ŒÑr²�Z¸ß&ep66äߤ` 3ƒq�d—ƒIžT¯T¡QX%¸“EÔ·>¯Ç»=¼Z†Óª+À¤uQÓ™oîNWJ†žy¡žq‚;‚xäºbû”˜Täæ !’C{)VWö¥ãWÄoJl,‘)& M«S›tü”€z³µÃ ‰Å»((צ‹¯W´ÃV»÷Áõ*±wy1/ò¸d !¤[°‡m4U2:*¦¥ ‹°Äº¾d6–®V@ôWQS;5á-'¦¶Q«“Ià ÖŒŽ=áu± .Ì¥½ñ>+¾P/«ûÐZ©ä4Š2Å£òx 2îÜ.’–vÕ¹Ü{FµoEÝK‰,Ìæ\¾d›][$'|S„¼Z@ºäèVD¤Š1šGi ÔËþòÂ@ÐI5rïÈ{ÃùúVd0ÑÔ#Ä *íúªîÒ‚w R[´!v¸7 Þö*O,Òíö¬)“~<³Èjý:쩨cÒ¸ø&#xáQj3#ç]*ÌDXPj¡ˆª#ñ$Ý¡f6³— ‰ë©{¦@½5¹‚xü€7¤º!Óç 盛@îÐå%ƒì8ÛB ì?„óþ¹Ll—„Š2!K,�¼Ó<±u¤È�� �IDATÿ¬ÔÌúLx;ô5I&C1ÀxŠx~Q‚#ÌX“©ÝêO ^pêʬë8:±Hé½Z=­bÂò%É:7;èXR[xa'ÒÄCã”ÖHgµ•è™O`{YJøFD"é—U„‡*ÀCuY�¦Ô%–L(j†¤ ÌÏuX$)= ÀH eå,Y–'òRH;TÖ¼bn‰-RV`p€zIö>…œ!�|œ,eªz5›Ú.…¡Ê:ó®DiŠj%j·žèzE—OuÛM…‹CÔ:ð"ˆÑ¸ŸVWßçíé”…­>o|Ò­ºüqK±ù³‰òá{IÁ¶A lbp­¿bÂ"ìEmn𓛺mØÊVíÌjTYcÏwHý×@=/[b[+ÀûoDq„=´IàÔa�ëb§Ù5ÁÁs\€‘*è¿T–ñ<ÝwÑuÝm&E€,—WøèSÍE"œG–+ÑÊ9ý)W³ºF‡&'õ4d;eƒ¾¬,U”]‹ÖÂë;,rnãz$?“:øâ¢j-£2ùPŒËy®.ÇÕ”è8&8§ºFgŒþ+Ý(宀Âè‹gŒ7Ž{¼>CײGý£bG–ßÛÙñYIÃtˆ&mm{¶ûβy˜ ßl3-0ßš´ùY{Häç½ÖHZ/}™… d6™2†Z¸8“O­»®õLMìv‚Ëèx¥ q†€uæ$)QJmú0~Vè¶Y?pÀ¿‚ȵB9À±è¹ã ë¥z@-ç°¢³†¢±!ËÍûjp' R¡¶óŠ©n'»æ‹¨|Es*/%&�Ú ´ž³Ð—%@<…5 W“ñ:TÄäCp7¢_¢6‚¶ r(‘h‘FD¨^‘£¨&N”Z£h@ÚŠcv©˜|*KÀÃÅ|ºÈO‰ºh ™¢¡“mÁKÙ¬àÌFq¤)µª‹8<A«hû‹Œ\‘‡¥ËŸ*,~gj?Dª�R“”™TÄ#Rù>¢ðU8ø´.£U˜bE^A·4²5™b 8²·Ð†@ ÄAd¶¨) ù"=àq¬EÊ!+£Û‘72j!²3¯¦ËGB+ÉËçÎ<ˆI#Ìê¹üzIÛGéœÀ·£ŒüD!{ƒÑÛBlv#U¬µçSý)Úq�m ù©bGg¸p•½‚¼v hÄkôˆê‡k©Ø@ê8¥âQ›()Ææû¸ŸGjŠà@Jñ^S¾J¤å¶h§á¥¥‡VýúÌ1*”[ÿ xï2E&‹ÈåËøk©Þ:fMšm3ž¤­Yñagu¬,À&j)€2xžü—®™ž}¥)ë²�‹[ÕÝî @Oékˆ™¥«nŽÚs¥¥àºxL*ý Ñ.CðͬÁ*Ú²Ù3"Öë+¯±f}ëº|BQ� åxPW2ZE¹¢ j*xñ{¶Û!óRR^M”×aüölbl&‘ Wó¡Ù¬Ú¤Û9¢xÀÆRãÍ lH S"ÒEפ‰¢®'€â6YI�L! pMMü­p³D§lI‘MXÓiJžÂ[²Ï=iäy‡/e¼ý$…s+tUn{¼Ï2i»jIÝ•jtvdMy9ÍȼºØü)£Hæ,Ï /Œ¸(xPÉnµ†cªкî{4õLêÃÆoÙè{ñµÀÑ r–<¶X-ˆæÅJ÷hòâUSˆCÆ´IÏ'¸.k”ðãGRã²â‡ü—(š"ïÄè[Q°cÜu¯ùƒ•ÈÒba^áÇGÍiÁØP*å§B,…§‚°<Ž7š®|JÇO ë˜xV¸†€¸¶ÎǺ³á¨ú™M#,Q$™j¡’¾:VXqÀü½rÔsi:u!ü&Á ÄuÞ<‚óâ²2 AÛÒm]‘0ËFF‡aQaNɤÑ5ú«ç|Êzh ‰•õŒyQßX'Qtf@§ÈÏvÿÔ}u§ÿÿöÞçu»-Ûîš.¼äÆt,;Âùäø vl‚ÕÓ(HZ[&ÍÛ°aÓ^bZbÃV¨†;*Ú((¤ƒDÄ´rÏ{Ÿ³ÏZsŽùsí7÷”ìMQœóžïû|÷³÷ZkÎ9æ˜c¬¯óp¢kŒ>EMµº«Îs[&î—µBˆl ϶Žk3Q qv´c=Õ‰Üú°èr¡ÕQ¿RI×Zx‰£5jüŠŒQŠÓ¿ŠXgÄ…úÌ€+¨»Èœ€îNU/‹ʶ›Ä“y¬“"Wÿ|ËCåÉ2y'§6Ô,ø]üüõËxý&^ß'N9‡u´Õü»ËBÂ¥ÒŒaµ²÷ã™ÿ4KÛ³u=;ú‹»E–øPàv¯&NØ Šð}]#MeµGV±k¸l#Q^NùGœÕr^ºâœHH‹B¨šæPæ_KièÛÖnw‡(­Óg–4êt×m¬ºO~ã@ᤑ�UÚøýXm¡4OŸÑÿHrjUEB|H +Hê^Ý©åèÿÜÀ§â?,ñ+–©x¹×Ÿ\Æ=oÁ¬Ä¢Nx’îëÓQ¹må1FJ`§»ŒëH+þC¬óeDbïÉG馴)CtГà‰ÞxÂ?¬ö0·U<‚!YKʧpõUDzËüd9g?¶Ü°ªžƒMëxåcª|%EA·ªvµÈŽ»Öˆ\á÷\Y*Áþëöúe¯;Û³ðT±Æ:5Ó*%š¶Œ\4emH"zKœÛñ ^¥OBðÕR[´j?¶V¿÷NÌŒë§ñ"†‰*êÜßdTAoÙXŸôù¯7?xÎ$ßÁ-j¬oÆBÚ]åŽÁ¡Ñ‚ÒižäúÖ©Ç"÷—õú£xýïñú'ÉÙ]Šzœ*·qÜeÿ@C»Ý%Fp¤0Ôc"7V~B"ýdíÞ¶ÃT Æq+—Ú뢈-UÝbèrr¹åîÑjrŸçü”v?ZÅ4wJGݺÐîÉ˲ïü"ôÝýN~?ýíxýÝx—Yc™WÌJ;t—Tð†t½qŽNÙí–kû+íQ¾Ú¥GOxB„—nIáEï:€Í‡È:…ù±(›A"Ö)§ÄÜ:#ŠÖÔ-6’ガr”>)2Ú›<±WžeN#öVßhÿ¦)ô2[¨­>œÕÝŸ‰\¼!Á×w9`“6&]ÊŸ>C–b ‘FõŸl¬ñ"¥FJ2©=ÝëøŠ’¡¿åàþawW„ŠEÅ<=,¯¬ 8Fz}â5U’í×äNðUfvŠniˆî@ß-½:7¨ï¢Û­Øt*sîÂ_–+ãÌÀ–gÉV'vßû-š×¾‹“i¢A_s^céé<ë‘¥A‹xò ‚,e«R<g|ˆu?Gœ ›ùîœx ÜÀªn”ÚÔäfA‰¤ ”nû%:r§ë\öú±³Lœ÷ÏgõèXŒî–Ÿiû7jniÝyëq“ž´m‹—8NDg2Åo/½<%\WN‚XØi¹*˜°ÌJuhWÃ'™ÈÁ}W7ëµ·F(\Ÿ°n;½¡ƒ(ǵ„’Hº«$Ìnãüñ+ªˆ¥|�dbk2Ë Ò}½×v¬•pIá#Ùºvó¦K‚�?DÄ‹ïîRŒŒ¬ » Öÿ*Øæõºèž),ñ,nYRIY�ŠÌWµzðú%USœýÁQ%:ÜnÊÜ®õ´ž&�,RgÙ ` 0.-úð¢Þc༪žýÝCrv@Á!ÞS™iíWœlÞ·¬ýAr Å>Ü5CŠ«”ޥ߲†ïAÅLO:¾÷þ×V\R'/.IüX:]ï¶vÄaš–ÆâEÓØ"ŒZ–Tç2t·„0‡ãχŠ-0†AZ«âÿa• 2‚­ \L̽n%å"o‚÷?¨¼³g%£æJ´TVÓ]7hÏÏŠ¶l˜LE}]u¹ÍÉÀÅëù ýÝ-7³èØe¡rMË¢‚û8Í}ðÛ8JªC¯„1±sŒ7ž¨ijÀªÎòÇsǹſuÑÔvZ¨’ä'7$÷Ãí É&\mµÚ>”50ŠÛóû^¥ v>ɓ̗ÁÊGFt¸" îdH‹°?Ä3O«Rèïeá®'Å{ë$@Ñá¸J;jãê¸ÅÁ˜økAµ-Γ¾}R¬¸ñA¸«PB–é�ç|‹W¹;Ý}Pc°ZWQ<3kgdIBvWc;¤ ~ú‡þXE^X°·]ÙÁ!€ Ê Î©má¹\yñv ¬aí:Ýn­”¹õáÒÊŽÝòŸ¥âÄßRÈòÊÓÁËõñ¹£Ç¾´(0ùŽ 0ÐÒØ¶^¼u‹Ánš·è-G—M•¼¯u2ß{ ²íôšë žHbëÖ‹+FÀ]!WÕB¼JyBÚëlôõDêæ–µ¨Éo¼Î4?¥F›èì˜>´³eá æ÷jµ{[? þ­[¤*ÃsXÚ!w!Q¾¶<¬èˆ”3LoèRæzò´sñÖq Cy³íS5=Í .FüXEs(ðÄèLÀpÌω‚:a•wcï.Y0ê¥ú^Ëß=bo]"°I`«'÷âébVhêX'iWÜ9A;]{Ð…ú5û«6 íR<™Ð¯Æ¥oáÝåS:hêW&2i~#ð¡Ôc–'Ðwy‡îÙXVDz=¬ Çô6ˆÉØ @; 9Vÿ&õ©z®ÓÌÎg:F–Fלl±Më<:tÁ¼¯jØ«m´=?¾¶wuÈ™ÒWKy!n’–°¶³Ö¸·‘™Tom±t±–.~¼N 8ûªÓ×<©J˜v²›ÔåZtû†v»>‚Mì[åÅ 0À6 Ù–é†lýoàÞvÓ.K‰càËÖC]`8ä1˜4"¦ú±ŒS¸œ²yÏ|fSq"ó;´îÞ']†±æºûKÛ„øÐgÜ¥ÔŽ·Q/¹{44bµàÚ*°œ¤o,™É¯{ãäÌZ¶ „mY ï©%Oê5 z­h'B÷«4µ„,n"BØî½ö™Ä-¾Ý_M¾¾u"XdbòoL=þy¨Å׸¢¥C5‰[í$òø}YjX\Z©= >9 䬟 ©ìÞG¬vÁhmæõ+'â%ãÁÛq}`½$î+#$…ö¤Ø%[£ªÚºíóÄ^e|Ô!‡›—h©Ô²øgM àNóV¯Â2÷ãûN´ÐÎ}S—…¤ø™‰Äì$!¥Õaøò°Œ˜gP9é.Lj„9Ônçf<‡¤8NBs—‹æy  9zÒŠ3ý4í¦qW¸usAŸ(äž¼ñq‡ÜšJ†AZ/AE+@!ÂOè5ÉÿŠð"gkHêÇ’–U;t¶ì¡–±5UBŠuÑwº‘0¥°’WQH6¶4ºôSå¿´5ë'ˆSú„mgC¸P:ïF÷ÞjPŒòèÆƒ¹—ÏÔÞ]KžËÑÝ„€sÝw«Ó©A‡tbt­˜ÝAìpº¹.Š#–5û¹ÅǦéš;d Ãm#­íÃéšDz4�‰lÀM‡KE0 ¬±‡6Íâ»ÎÝÌ‹ë7ù ‡[È@EçÝšŸsBK;7Wu§4f2 íᬱÍðEÄa¬Z‚‡` W&Uܵ„|2Éå­Êé^ÇÈñI±#Ïm'U7~f»¬Eh*¨_LP¤ty‹ I¹VÅïznmšŒã¹L.‘Ešd„’CÍ‹“ˆç#:ûàÚþ-sŒ¼ÚtZÅ:/¸<<„¶¬§Ê?P'Y'^„²N›â6)à`-`"D\Åh$¥îæ¿ë„…y’œ¶�7¾`¶ÁÄGÑHH¯ß',}^²CwšXb»ƒ\¡”H®¤Ýk#b Ú­(m Ñ@=‹6鈑„8­Q^$€ƒŒ˜@Ïw!®müþ6’:!þÌΫ'qÂ’mÓ¬L—û3»1×ô”ƒÄÜnÆlª¾Ž•äkë/¬«F™¬¯ú;gØÊiN¬kot_¶ªçè8èC„£g5>Ô\ŒuæÔ~râœlZ(¯jÀlûc36Q0ƒ»Š+Oœ‡Åj‡ýN(Æê~²DÓ¬Iû>n·Ç(t¸Y¿{òšµÍåÛ呿â•å¡}6ÏYu›yŒjê£[o®t˜:}æ–*º'Ì ²hbdE1hx¸‘cæ&px¾hÓ?!ûë²­Èá�ÂnU$R]¾[dÉÁÊÛcä=iu=Z?å¨ r‡é”(qø<q]+ðì O#„½2Û¶¤Ë ¦—’4x2c&ý2;5ÓšÒw¨ñáv¢iVã"TJŸ\ðól×(™õ²q(¼û-Hê³ih^|À&Ðø!T²“·ÛKŠ*Ó5ûH×!Ôl 0É;íé` ›A-Ñ‚7&2±?o0Ël Ý+:Vç;�[Ÿvï‹~*á"pB;²|GAŽOïߨ±*Ï.ëèÔç÷fm'M 3tãV¥¸óù]W$,ÚîQÓÏÿÔc\¾•„áwÇ Æ“Ñ.R¯OÉ4zÉè¼j¬Î)8Æ.¤xÙªG©ôˆE+YÒÙ®uH{¸·ÉA|3‰êý¦Ã£Uò$ò âõabª³Õ–}WPç ­¸½n!¶:ù<õã-™ŠJ3Äæø ˜!×°*:ÑpÛÓ"Èš¡(|ŠÀ;ã’Séßø¥:SÎÍSB•,Wóü´|f¼•¶@ás5ÕÓÙVIZAV.‚¢¿‹Ivg¢¡ôs›»ð. Ë #áæÁÈAFbÉØ–}\„å|¢bàUÒ JX¶ƒV°îc‰Ì4Ôú@Õ,Žp…C‡q*Û‚€"|Z¬ó¿Rf4ô§‹³AÞMì^ßE[(ì�iU¹k[ëéÌ’ZH¼²N2’Ñv£Ýj’H€¶[ÀÓn·tÒÆê&<m¹‹ã´Ì[.¬>ßù†Ü7<yn°–:WDµŽKÑ•ÑàG>I<«œZ¬Ðªàám ûDíÑl5HÆ%)GS[ÅH8¥n Ï_ƒÄÜe Ɖ}4kpX'íâs]ˆª5X‡¿À*>fÌWMuP ¤¶r³ÁÁCp‘™ r±$êõj† „bdÍÝiû1×òQIåQ :Ì€/±q«X1@}%16q Òm ²+Ó$‘8rѪêÚÞ>g ­êêy¦_œO£ëÏA(R3Ó„(à¸Ð·¡„ ½áÛ/ÆzλBòÞ¤;*ÛŠ"§ŠŽýcù¸í±+MîáBAÆÒ;.QXÃ;é{Wƪkã²ìë>ÿ’g3$Ä ŒËRœ#0”%n4[1å*¿Ÿ¡þšV»KLò~ŸmçH4¤EâbU«0kÙÿë°™Â5ÚˆûØn®˜±PÑh†öФ<ík†ó¹Â[– «‡m¶¶d$˜3ä!ÅB]nÂ9¶õœ>Õá š¦"ß퉘q:#ÖówúyÂÜ%@|5.2kY¥pk;‚ÖNX9GUN‰WO*û «p£¾>=ˆ¾D›†¨à9±d ŠÓF twíóü-V3SG†Ì¥ØÆ¿¹¡û¹´Òì8RàôÍ@oþ²„ö£› ýå²ø‚ʦ™=G2ฌH˜`ÿJ¶YJ•Ô„ÀA—¥m¾ºóÚ+÷ä8µÔ)ÅÛŸ T’Õ8Ë€Û•ã>Öàur¼ë$O!ÐüùZû`«…£«ŠC=$‚˜ `J¤iƒ³úݵbš2}zûÁjæªG^‡èíV¶ÔôÓîBÚÁÖZB'b0™G©Aß:}JDý6䨏ÆcÄ?Ò÷?y:ip2=ÞýœÒ﯆&ˆïJÿa&¢±¯Ù{=¶II}#¦r\÷à‰Ç÷*XX§±D0¥:tIH@ñ]J¸Ý‡ÀHp´•B¹v*éì\¥‡ç]úឦMdÜtA‡ÿ0±Oòï®p©ª]ªµ¶ÇÁ~Ÿ ¿RšÝÍåêÃÕÕ×Xœ4±n9&`¸j©e‡‚äì³ê-]økú_‹‹¶évÚràkÑZ!|)‹ôyŸ±ΞÏxÇúxj-…› /:ŸÒsÎô gd·"ihÜŦ#_í<Üüé3eÈy}ƒ´L(Gk¿±`œY ¯%C w0›…%ö�Í §³·¯¤×Õxàͤ œ©óñn0Ü?¤!Á­Xøý“OkåvB2GÜìä\ „ÕówÑ>öj´Çˆ¾©Ö•P?H•Â*\­çÄ/-FÜmQϨVŒt@tÔX±•¸¸-ƒ±²´® Ãæ B(ìwçwàI… à]EòÇ i=õ —ÎàúÐ Á?Êù_±†3ÿ¢*¶xZ KŠsÌí¸fë<¹ž#:%ºwôø +¹ ¬ó½Ãû­÷æ9öc},Oà˵„<U¨}5Ë8=T°UY®\ŽÚP©÷“‘,Áq‚íåÁ_›Ëµ'†Z0‡åê3ÓS£Ò7ÒüL!i!z!â°&²­8Ô“‘¨t¦ ¤ÕQk‰ÔD¡µúá±hi .ñòWp9ò“*š“™n‹Â ‚ ŸACB>'6G-YËåèx§Ã 2ÊxQ2†>]áT>u8Goë³ý¸!‘ì*âN„fÓÄ×ï¾ë&ðXxb¿ëîX‚_ñ²Éu×ûBøÒ¶GóìI Þ?\�é�þ�HÀ`Ô€^5S‡ÊáëÏ\[ežœfíiîª1 ßC„foôÌz“:Ò§J`†æÅ ¡Ö¸­°h ÔJ€ì ®/N„C]W¸…<[¾" @wÂ=ט9<8tÅÉ•f4THòVî0;“ˆÔ °ê]_«“ô?q¼ƒ¹Å¸yéb‰ [4?SJ ´["e¥° x«J>,]8º°wUý3ḉm8A|å’q¬‰±„dz™d8ÉZáZ?ܾË5þôö´{‹xk©ÞZE8LÅ»ÉÁU`çi¶fñof€9`³Æ5¬³SÜÕ*Ы…½7žäE|à>ýúNR+MŽå™Ðë‹§U7TQ–#ÕÈ™}_ÎÅKÇÕOÄ ìˆ%‡ÔèÄ­ØJ`I¿ÄòÊtÅÚ×öΘ®+i×e¨¬ÿ¬Þ`Dð`!H‘Iâý’ˆé–Ø Žµ Çhgu’B1-9qQ +á#‡YU‡Oˤ Y˜®°ƒà¡?V@#p œ×Ðí¢½E[ýdyK Õoo 1/\1ˆC-æÒ ¸°R%É‚€Û¢8€À¬9AN´*´@%òÄȲæaþ8ˆ7B‹í˜¶Õf‡GÆU‹ÝúRš­ŠnTH:ñ'6“¢ÖõYäZ~0�#ÜMø„ç–¶^(ƒ ˆ{ÀÆ„ï·=ˆ*E:˜è“gõ»ø¹Á¼Ðâ’­Æè‰èí^/ Ùcú¥ K¨n»(üxþ r„ªÄ:‰óo•¤uºöEœµ²ÎÛm¹Ì»ÖÚ•#í*·ƒSƒ¾G8‹²Df¤Î3�ó„+|\¹k· yÃz•ª™K^gÌéAÄqèäN\ƒá¹=¶9Ô`ï7Ô<ß ú_+$wŸ Ëê™^*Üç3{7}â[­¢óCõf«®†kÅÝž}ÚâVÿWKCÄÍT7K;ÖJvÍ6£è_º$:¢J¼ˆ|~è:— É5'%27O8쯻ÛÇMòÈxÀ –˜V ®ŒyZ©Ù®±NØ,O´Œz-š2ñ¿ éŒÅ ì¤'¶ÄÕ(y6K0f"¸r�‡Iº™)}€à´–%‰²ƒß;ˆsz¾ØU2„øíŽŠ·_væ4È R6¨´Pa;:2S&#«…Vƒf'‡.luv ¸µ¥2Ìk,ÂEq r-UOk¾‘_§%´ Ò&ã| O5îyZH©N¨I(º‹ÝÎË}‚“ò¨z;PÎ*°9 âƒNmè=™)ŒÚÏEèDW� |Ô·°7ÛçϽ¿ÝÖFÔä¯Ù¸BÔx¨Za²ó e=—ÐåÅß\¥‰ ·œe©1…MÉp˜†ºÝ¬!1Ðþ‚”9—ÞFDK_Žc}–za(à…ÔÊj`¯yýÞ. ˆ»èÝ1ŽËžžŒŒãÖ”«Ü‚‡fÄ–lü]–Ü(ãé«Í´fô®Ô±A¦âq¯§ÕxL¶(fÿ ÊÒ|nþê&.ªÉ}C.V.ÐäæCäA” ƒ<Ž.ê AWÞ~°¦ßΕ; ›‘°¿Æ³c(­ \ž7áúxí„õ7CÉÂçok>Øëª¦ÜÆ ÷aø™U®d¬M¯«j ÜÒ/h"qÓ lïbË7®Û"'“­—ó "qE[`6s#2)]ÃñîÅÐ8u…X‰Ø`9 ŒK½q A¼Ã'T¥—óæÕq7•(„´>m[<¦jË03ÛUÑBñP~Üò},x|Áëé¸6„ÀÇ’usT0Ž 0øWùÝ '‡ Ÿ“°€‹}óTŒ¦R:†w4‚“Œ.š.¤;H&Ê ãK¯Ö4¾ ÌR ±ì÷<FWÕ–ë"&«ëì±¶Vš3¹6§.2¼·÷³²•auIÞ$εyØy]îF&XX‰l… º@ÈTE\æï ú[àÃLìüpÆ™ƒ ‡¯-‘ùD†`§ôõîÙ½Ýâÿ6X?ƒFö 2”e|ðFæ"ôérua8œÕÚÏËý6ñ¤—E‹³éYÃëpáìíÚ®QÐÖUÕCHû)v¦J¸{×jÖ{ÁP‰,¢y0Î%j0¶Þ ºRi%×4ܘyÑŒŠ#sh©%¢¸”"áDä7°È‹¦ÿšþlb &íM§ª5Ýt\¸!ŠÜ€èFY3Ç­ûzƒg¨�� �IDATÐÒ/ïJݤ9Ý*º…"Ž#ê5øzOêªBŸV®Çåyò[ÕŒ}šéÜ›DÏ@EU·5Ž žt‡®¯:šjEðCiÿ™DH«]¢ËnÈâ {Í“‰“±Bò@\O~·w”äµ­ ãøüè%Μa·å”B*Mb>†‹†µé6|¯ç§ó¬;J>9 'Sùz¸’¶Ýƒr6ªA¨j1ø1ÜwãÄf? *ðÙÚvsg²=«‚u¦r*<@öüØ…FÇtDÒ˜ùEcpü5á¡ ÷Yob‡ÊÝ™Ï5ñÇr}f‘yœaµi©°ªXìo¢Âî4ŸtËÚ&ç¬ç+õÄ U”/„çÙ> A¹äf<G†5Ü-8^úiÇшˆ¿qü�&Ým®&Àa2LHù$“ ð&NêóÊõhvÑÎ<ëÒ(H¥±ÜR Â-=æG‘Ž…( ÆÍF÷¤†:è3øññAyÿâè×àa«—RfÞÄéõ>¾u§êÉ–¢ÅEnY‘Õí6†¼æ€ÒàD|àò]€‡U„ilàp¼ýF¡ÈAô1äƒG7g‘îcºQÄ:iåE1d£5=g`÷ ¡†d<˜t·õµåX}N[xµå0åK‚õ{­YQ8MgÑ ýdw ´Æ$ÚTÀâÙ õ£Nçþ,PògÀÔÕYóØsg�ÛXiå`ì‰øeì�þ€±™ÒÿøÒâ>¯/¯iÙ²lZ•2Lnçk=b˶øÉPíþK"©«~»ŸVüŸg4b®ÍE0¥ôæ÷ÒÀc·dij¿«k¸TsÄ*ˆ­–äçÙ>œv„Sø U®KÖd%ÜþC)qñõ¯öÄ-ˆbuѪ²€˜nGiw+s•2à2^¶…±C bìÔ* Å n#)¨ ÐV¦c>©Ù£!$Æ»zÝ Ü@Æ©-:¹r±rˆ0J*ÞLj Ë?b�¹è¦W{êö­5´U"¨»j}÷¶7ÃëoX”ß’Û‰?wybbÉO’ö¶¯Råp›Xë636Ó²xO]m#F˜{v;Ì×ZÇô½ìmawÆÈÍ[u»ÛQã‹’±ÁàÔ­¦ÔÁ4œaÔŠðZfÓ3 XÐg Þ E^Þ?ùšÚü‰°¢9öPÕ%<SÜ­*ã6yŸmó}ôÙ¾s?pG۬ߧEõˆôL‹=wö&x™¾ì 9*¨;¢ã©ï“‰|éàäÌÑçüëXã.´ØZ_ &ˆž¢Æ- &l9ÜbJ”-aÝ]NÀ›º ÍCuÊýã«ÈíG’@Ë?íÚ’ÀÜ÷0A(Ÿèý&Tkrý×Ê;ª}ò'¼bË߇Ã|µ/Kw‚'¨`k>ÁéFuñï±Wo«qÈ0¥·neµ–ÌÔ`h¹wÈi\OsåˆÀž ר [G–Ù�'vˆr†æ R·ÓÀgénmaîU=4ˆÝñ>�pd„£Í]û d4H‹w‚%öa¡B'ˆ­l—“­«‰¨YrÝ**‰†^|ƒ>ÁèÝ]§m‹­$Ô%0ch“ÖJ2€ðîf¥ð¹^m`Fû m™·”ªœ8Ááêc»‘¡î¥^H¢ýYUŸÂÊBºÂj:w¢!±äkè»ãz3_lˆ4¦ˆº»my,w±¶þ„¶xب*\2Œr²mfeG5ÈRº›KWŒ’¯®C8;%?Í›1îšž†B}_œZÄO”ÅBZ~Qm‡…~ûVæÛê¯ÕŠZdnT´Lø‰yã²äñf¶>!Â6Ë}Åݾ¾Äë;#<ÌæøæÛeo0/D^öʼnÜ~ÚÛvÅNT¹„û†“3ÁJp ¹«¤Òõ”JßZËÀtÛ$‡Í«¢½qˆµ-ø*Õ¥6ËYÎY^6-Ÿ«þTç/Ï,×ScÝ%ÆjWnT„xdíwû»øùë ‚[Ekló6KbŒË Âîo“Ö† ƒ‘.,’lº~íÄ]×µ„ÎÓ�ãà†ÅòjÃØ”µÛŒ›õ¹Q¿új|I :²¨g´îù·Ùz,êžýh2«‹ìr¢Óà‡ ¤äðÙ�2cP5MΑpN·Þ{++Ak,×;ñ®Œ›ÿR:G1ªd˜ kKº%¯!Ïb·§ir;HþìTš±.‡»ÎZ³×ö!»9Ðþ®«¼;=EDZÆZ›‡jâ"GíÚŸ¹~šeÝŠ>ïò+wI¥h~ÿI8«èîß]¬L(¢AÚ`–é êÕ‚ˆÁ¾Z \NbÁ~PxËuÆ«pm·ªªT‘D£TǨ*-ÞÏoA¶êÙŠæ0©Ü[ïµ»D¯]A—f]uƒÚ2‚ŸòV 5Ž']]#Â6§¥û0# ñ¬ûÂq'‹�u(áÖf Éœ:³½ér*Æù ŒêæçšÌcñƒ›‹(/OÏ]¶ ¯µè»lðŒÒ¬\i`LR¹=µŸò'p¥»ØZ¸c7ê†ÑqÐM‰Œo)ø¹#ÞƒÂ3­¸¶ Ù?Y°·ÅðŒ53§ø~\ÄaõJØ…‘Ü#¢Ú\®ð¹[‹»ï0™ƒ#\×N“ûA{ö$— *Í µÖˆU+CRuãÚ Üœh LXª¾³ÒùÐ>$™b�ˆìbr(Òd2·§§Â 4öØÔb»H§GãÔf¼õ`h©e™"X^?wXåpŸ¾¾4ïT·ÉÅÙ"Ò h–Æ›,öñ·³¹r{P«‚ä\–*þ Æ÷öx¦XŸ­X©ÞDŠ¿¸’Õ]zYMm™g©3ï4±ó+™Tý‹fÍ÷ ºøá¡R 4À¸‡ë0?«zá´õìÛŒ¾—A‡XPWê¬Ûä Æê¹‚ÜA¹:ÓŬ®€\^_’dÓÂgH%G†cô &Ü‹F‹ËX«4(ù~Óz€'öÍPþØBMa)ÙÎùŠ OðéþŸþÖ9{åòp†$4„Ü“n¨úáB pñ@°ºJƒZC,U6˜ §Âž³\-$§&¤>Cйœj Ž¦Ì WH‘o�ÔL÷)ëºKù®|˜š¼<KÅŠ)gÏêäsnù[®1.ŸºÝy3‰ Ž’ öud·LrŧUì¡jLízÏPÊ¥kW‘F<®Š 5èÁXÅ:\K9VXýÀbWŸ´,bª¯yu­«žüP¥I¿ƒvZ¬Š` sý.Ó!äoöÌô¥Æ)ç ÀÌÐÝóY`>- 2×´åÛM\™.ò6FUŠàÝVó'–oË^€Š!Vð¶Â'?”O‚¢«R¡×^º „pÑx’éœëO Då0x¡<0úXnmÄ­9—"wŸ °Ä¾Èä]ûÜaXu‹³�BÕZüÍžö9T¨ìŽJÍpÚ(†¸Å±î�Ç¿m [ˆÿ9«ÅªðÚÒGGPþ URØjˆ<Æå‹‡OüiG¿u²uâFk i‰üfÜøw±V}ó¤¡MÐ\WÐÚá1nÑ0«P ,¦¢;aNƒéßÂÁæ¦ê¨Õ™O ”ãÀ¿>‡Ö€‘VT޳±ž7ˆe¾èQE{ÏJ*{.=~h'oª[r-©YëØóš‹U¦ù܉8i÷•£u5Ço ¦Â9šF¬C·Ãʃ’lòYgŲ°#€†&½?ïeâx{Wh’å?Ž÷/OÇF|næ4ÛWäž[zΡ$ÇrùIݺlF²º\¥·p8–iÒ6ÐÅà:FÖ‡óÓÃͨڻMýÉø¨ŒŽ©DÒ=¯Úª4 ½d6îºÎäØràÄ\¥HzõpµqçÐs¡}†°¾>IWg"Xív35kÎIO­’m©Íë9é´é僭qœA˜t7ÖòWÀ3?>E«×M„g*J Û,¸í\éò(Èêå` ynSÎ\þYXÕªP+m�ƒJÛ&£Ä(`ýÚŠ¿Í4‚¤Wš„­ÈÐÞ²"ŠvrV<çAª4›œe‘¶ho0¸7OHbéÏ/üx7X’2K²]Ô.˜æ@;¶Uõ ®~3¡¯Ÿ 0ÞîvRÚU‘æ¸E¶ÒW0Ô¼¸ÑÐÁÍ’`9"REØEç*mVv)+·þ³,qh�ùF³qžüúI=TL‡ÿõ*+pâëzbûi[¤ÅjÛãF;ÇkÃUóNþkÔÑ$hAµÙ00ÎÃÏ�j¶öšžÓ"ß×ðØí‚etâÅ™Þ\kÛÈóÊjêm̶ƒËzZДS“‹ì[¢%2 ºG-EÛm2i^õ‡ä­/·Yâÿ)}žwI>º?ÜJ¿#9 QÌ>9M_ÒÎGE7(‘’ÝDh/'‘~ö nTur»³ma'¦'õó„ï£t£qQjQµJÂrgÎ'm¯½Q‘@Žœ•Öx⪭…ȸ¥ù&^_;Ò7Ö+ã—XdžÏ:,ë¯ý¡Ù1›¡&¦õÕ3'`5 Ãð©Z¢Aáè´‘z€?Y:„ÁºûJÓï¢-y¼Xâ™^ó6WP¼8ÙߟfîÍ�"’bPÙù˜JfìØÎ~곩=§¢32Þ?°›°ÇŽÐUÇM‹1ðólßf«dH†ÒfCú|=úæ-!«`h^ÅžKp¸^;Uřή¸} wÍη½ƒØ¦#mÖ•ÕÍÛÄp“ ºSp¾ÄR=iw&QÑÈ>ÜꤋKÎëC40íBO'’š©Üܾâ­P×îñëH²iõ-ÆSe3!nŽ58[ušu2"Ú鄸¥:]­LHëo kK—L%[œšÁ0L&Ç7rDÌðÝ©+ý^sb˜k Ü¡é�b¸÷"E Ôð½«á;0']œv¤<°‚»@ ÛÂHì™Åÿ÷°k Ü“Ó0nu=l¬ŒÇ'à¬krØ¡!Ÿ|^ЧÄX¿’d—tà,Ä‚çÁU¢våϰJÁ)Ó_a¦1Qir“GØ>щ¤û9Ä>ÐlÁPÓñ jæ h6Ò ñ´Ô“áCsÏ>Üqp»:Â,³J € ÿª™ÿСsÍ9Yƒ ýÍÒÿ—çdªÕ"ÆhÛø~¢v·3ˆì/a¬TÇÑu.÷³åH¥)¦J°[ÚqË3‚sÚk ðÔ‘ûtÜX@ŒõT,…ïkÿ`Àå·ú&þé;Ÿ…—8RÈ– 0aúBñ q8 $³ÒtšwIò§½®“‘äÃmEÊî´ñ\¥}\{×Ñp•p-iøw…:|‚2ü±Âoçº?F4ƒ‰~öLä†Ot~;+éoêÂ,û: 8«·Ñ¾¾¿ÿá2¨ÄMת< ÊsEº§÷)¿ôò«NsÒ%åz'ÿÀ'‰S™=ŽY* ²oñwÅ‚¡e›• 6ˆ4Î èCøgVš[¤ßÖcœ0×äÕà BúØF¾ÇZÚ³®õŽ«�S(‚¶]W{\e‡ÎpBwÌð$›i)'¾S{Q2B\½·‹so^½+êÙó™‰ãœœž;<ÃKQzrjòÛêª%õ¸‚¥áÌÒ„3Ô¤ÿ–&0[¿Â`^¶˜¨NnÑ*%Èx`¡™ÒÜÃ"ÿ"èS€þj�Þ±±�Ï ‹«þ\¤·[¹‘�7Ò¤Ös­à,_T'ÏD‹¼@¨s¯M‰ïQÅÇÓž¹äÅ Åqò�oÉÞ rsõ*K³^(Û¿À°ÄÕÖ•uÈχO3nñ3ë¥LTšNüñnÙÜá‰*vV‘À %÷ÓîÒC"€©ëÀ"ˆcÄAF ËÜk Óë H® âÀº°½¾Hs#³SìÆkpª’r‡ƒÉºà>¡ÃÌCâsZ‰ÈÙÙ¸ß^ßÇ‚¿¬"v·#÷B–©"Õºüœ†Ë±˜.#w\<&1Óæv507¹µÂf!a|þT_p8b•ŠÀÉoõÍ,\ƒQ–hW:lw®ïàTÕšœi)@p~ëæÝë^œùúwSµëô'õA]EnèSÁ¿Í´ð–±ìƒÓý0.#ÜhØz&—GŠ­––æÖj×ÐÖ´º8̲+P× ~‡Êb–“„d"œï¦ íx͸¿r’»1ïºg+ïS}jï*--ÌåÒªÙvèS #YJ`NÅr2쿨uãø¼æ%¥âs<ØÀVHû96*èÖ¤Z‹È-w„žgàœC|Äa&rϵ5¹ýn{FŸØˆsç.Àç\K©%r ™›bkY¿6h•·Ú æ0î’Ùs·Z}/­nÃcÏápä úƒµ‚KMäÆíÖæéT¢¥¶‡á±Í·(ë=Í‹{u%à|(µ¢k=ö²Šƒ™G½¾õ‰ö-Ôó`¤A®€¼‹�¼PhñºÃ[žº# ¦¤Å ;·(yk1·{1ƒ–Üq2ÐÚv¸Aµ5® IŸÝ)^RácÖËÕv½c€š<sÎÙÄìôù¤‰ïQĪ`Ív|l ƒVUWdDPWOøc°IË|«ád…„ô h5AA@¦ ŽÏj,..p%õYÇDJ 94‡ ¢9A©ç@5»:p]‘†§\ã÷Þž?ðï Žï]µÇ“jø'jr`ÜDqÇé¬zÓ8™NÎ\Ï+F#ŠísÑ<‹ø±ÜÜI%q]vÚÑy&â�Õ7‚ñ,nñp‚–ØKl#OuO‹*b‹0*M“’~]­(Ž€)Ú•ÆaÊ*V/ÚEó«i! ‡©šç¼€\Ü6�@)çV‘׃…rŒÄÆDœ ©Oõ¸DÞVi|ß;N÷ú’ävíü«50ºÿÌ‘JTcÒT㺎ÚDû �¨! êc]–TF«T=„([ –�¬ÏÿlL®‰¥ `¼(´æ^Lþxþ]¢à~éÜ•6Ûä¶X„âö_Ó¯ '½`£hŒ£ÜMÉ\¦e æúN~ )¯g"±Ëë#–Nuµ4¤Ø$ÚB›àQ³)·âN•~ZOë“rW±Í·ÚûÁē܃þúI}|è½ËñÌq“«'œÎWv£!=÷f¨¹éGgm5¾àp:AÔ£sisÍ™ ‰"÷ž`üÆÚ±­ô‰Á™hw³§yª±Þ÷Ô‚0"nUˆ°5»ÚƉ¨%ÇM+=Ç¥ðªg•¶OÀÀpø×¶‡m›•bV™åŽéè õôçhÁà Ñ÷æN¬‡?A<n¿kèÉ‚Ïÿ|†eX±¸Çk�ý”êÈúÌ[Žkä»h´¿=ØÇÎ5|ƒ§¾—éNÜF¸/YdíÄ`Žƒ™1©“ë¸8›:O*X5Ý`ƒ) QhÌÄI9AÛx…Gv#Q‰…ô³¡9n±„¯€¨‹‡s‹>È5›s#pt\£ðGmáZ-[Í]Ã$?H©"Ðïñd\]MþŒ§yAÚÔº Û²˜–ë3’½,å0uÛEçÈÉ-¢ŸüèqGkO„Ïó\mÕ¸‡ÿe‘¤ nÒ:Î{NàܶŠú$s.Yiv¤B©'a Wä¦Br?ëÛÎ!ÜV«HØU[‡¸ûÖ& ã¡o pdòª X%ñŸÑã�ƒ¶äþ ívxøò¢8|ê³ÖPt>�…¯±˜`óm§Ïš(mfàÞ¸sÕ•wDøÙüiYã‡Ì̪ö"éÑù#éq&^3YÒï㣺p5ŸÆÉ™¦Èß•Yv íÛ:L„àúö<$Ä4ÒS÷"V+g@ªfK…sPŸž—Mú¹úXPz“DE^)ÒÃ`ú@×4‡Ì ´Ã·?sHÀ‰Šk½Ï†šÇ ·‡ZŽñü'¢]°«,Óêh´°­íÈ�õI8 Öm‚E !:ݾïà’‹—Zå¾(Ê=GÇèÄÍ*Ø4¡Ð­Èj5ÀY}˜Úalë‰ ™8YîêEk#ö¨Mfá[˜? —Û˜ú&DF·%³Yºþ›éÍjýURRX87“˜AaʇRî‘T- "Åy)Ãh”j¨Š½œFbþtÇ‚²‹ïÊ)”yñ-Òm«ÙÀ1ëY—ÅÝ“ƒ®»ËBlןի6›Ü˃ÇûY¯NŸ€cƒŒ™É©öÆÙƒ…%¸ˆ?´-wAAà¾tzÇ¥º6i¨Ÿ.× ƒ[§º€HéÛÙb8ݤStdÚ•ä –¥çè˜60¤~7‰Ž;¾õ¯kákÖ!5Ï%Žˆ‚ïë ¶ßÌàœ8BµQMdÁ'¾*ÔGçÌ=Ëm]賌©Ú Ç=øöa3ÀåÆ,ÅB1¶e·å1.Ó¹aqë}1ó¦àñ;åVˆþ‚««2’ô—µÛ­$ÎuÖ‰ƒ©:«v£ÊÖ+?ñºtg¢->îÀá©’Lµ¨BºH>Ô| ö¬vï̆ü¡Öòç¯ÞÕîrí6®}; )Rlw‚Gǃê ^(·#çíÇjû¾6œ[‡øšiýš¯Ÿ_žÊø˜ä£•(ùx@±Û­÷¹Cq;×Ir‹pH`(žþ GÀ9ë» ‹˜ª¨éN�æ»—Áûæë!·³ ùpPé0ÏÐ /\è$ÚµÇ%yeÂËjWŠx Ž6%ð~T@¾wô…pœ¹7=�yùBêÁÚe”yAèR¢âÍC}´‰þ;¦:l|ÆMܘu²*ÇlQœ»! ŠÚD|KÂÔ •òÙAn³)¸!"Kh%Æ[KµtéPUc `Ò_£`lq^»¶Ï€ÊÅ-,ܶ™¢­C:( ÈÄ5ˆBg•< ~ðì¹  O}»•^ѹí)Ó:¡­ )¯V9W{ƒ¼û¤Èh¡jî‹Jn æ¡‹më ú?AïºÄäµnè›ÜŸ‰ˆŽX-ö—>=¡ÈŒØ2€.g­\‘Äœ¨^µ›…ËiÔºm,²Ú‰iù´;Ǫ'Ös?™vtË#îÈ#ë,+9iæY¨7IZ qQgR\ßb>ÍÒxƒµ‹H‰#rùvÿò¦mCÕsA}¶$ ÒU7#¿´üÞ¶Œ»ESJô/8“¦¼®rt%4ãjÔê<ÞÏ zʼHËR¿›´V,ÕörW$Ön·TâDpxºY73Cä¨SÉ»Y~3p‚Ã(B"¹’‰jgW£îS¦Cošpë͇•¢¥k—zjÑ#}¶ŠT` y˜ú¾0vQ_Õ@±pwÔ_Ž—‘VU÷ÃÔä–² &Ö©§%üm"–nÍéÜÿvµ½ªË©d²gypŸ¦+A-ÜþÜÆpÊóJâŽ!'îj!è@¹jŸž[МGÜó?žXÕ'i6 ,äOò’“2`RÄ ÖØ ÷¨ôo$.-ÇÄš8æÉJšo‰ ’žW•Ù%LL¾ u9_¯\ͬý“AßJD“ ê”¶ò3çaÑý‰²‡gîŒÁl .7ÌÍXEÕ! Q-†vâÄ=IC[ãV#–­©ûƒƒ­¾‹xJÖS…g´…Ÿš¦Š:UX‹ºíÆAL§Èõ™ÐV°Ý ÙF=W0åÈ‘Þß>çk¶!mFÕ ˆx¹¥@�"ù‹ƒæÓ]!ä\ô…‡Õ ˆÓ½³¸\¶•\Lù–q7ƒ£Å¥[ׂX¶ô'>îÄhÿIhv<[ÿ'iœÞJ<üÃhÁ†i”½ÅÃsæE°¹.ý'Ä^I‡i»ÁŒÉ² MÿÐ2g‚LZ¼»Å‡õcV°_¼Ðnq8K!# Fºi£ø¬i”,bIEíñÒjÏ÷ªØj‹³æÙß­šR$ ´j5d¨–K(qü)= vxY£G–¾ínüD-1="¼÷öÆ$Xc6y+kñ¼B½V˜§~/þù' W©qñýŠPqvXVй´f¸·wSïZ7ûY¾…VY$òÁ'ÔŒö�%h¹ÿ´8˜hŸ|5²°ÅJjÉ!.R(«ÇV-†ÁJ²#·¤›ÕùL’¤=ÂÙ*M¢Õaåû®©•5’f9À’Ææ,c j݉Â?¬ãlΗhgÌTïCRÆYéEk ÁaXÛi|&6^Fቚ¥}[ý®‚Qû<ÇR çÎ¥VµÅ«yŸÎW5 k5ò33EnÓ™×}YÛ•qÊ»û-Ü#ê%€)AòYX°Ë UE¸Qž—êD2¤½ó¼o¶ßÒƒýì@šˆì[dñÕw7ßjÖ {ëSl\„‘`°fÁ¼Jè-j¢›Y ½"Ž®‘½,Qà¶Ð …½íé?�W‰H1—€M–ý{5?à*1~‚X_UP« añ ÒÁlxð&¡Èô²š·¯/ì¦Å×ùÜà) gqb.ìí o׬_ã*b®z²eh2P2L9™0²æÖáÆ‡3ƒìöÛ¥}U<Ój¼³påŽol™,˜~ËÅ©f° yñ–1³Îªö]xŠG7(³HbëJhÀ³˜Lû»P•”›ùID%à)#+æ›é|»W%ÒZØü®,Oç}¦âÜU|ÜŒœ½úñ÷IY™–ƒ‡jË<Õk[[e€€¦`ÍÄ#«ýüÏ@õܵ€JHnÿzÅ$á%ðli¦pP »v$'IVË3äi Ÿ¨·ÌèD1Zɘ¶(¬Œ§ÝrÄE© –•OJ›Öþ笤«˜Êé­ ¹Ï¢Ø‰6¿¨eùÁ¿¦Å¹Ûµ½%@’£_†/t²a¡ãù~!·‘èÓAûÆìéP¡V!ðøÐN‰càhFY¿å®q¢[<¨Â¤tó¯pbypRXR9´ÒŽ–²ëö\` f–<£…¯ƒ³…‰ÔPÊAÐ…£¥õ¾¿Êöþß„ðgz�� �IDATá$' q ,N0굀ߩàÞ<¹ÅÁò09аr”Pd'Z‘ºX§<ÄPàas‹B¸�,Q¨ö·Wb]ÕvâO±œÕúá¶5œ(Ä¡]!ÉQݹû² !NëŽ1@‰ÛM*JvBˆå¯¯%XÍ]B½Pô)`mw’AÎÆ4ïmúz}¬[Îeqpœæyš?®öÆsWnÆú9f>ÜÐ!÷ÄÚUýOxÒz¼1A±`¢V¥†›EU!æ·Cég1à5‹LºDæ³_cÜ%#=O¸¹º)¤ÅèuOV¸;„o÷N+µ:v0×ñ&ˆ]qŽ n¥Ò4:×2 A´:­ˆÒ—Þÿ–ÝÜf®O,UŠÑ€ð�½5b`?ûö0²: $έÕ<6uN°Ak(']K'9bõ¥ˆ$Ä®_ MI¬#⮬—(/ϲ¡ïSÄ|Slð\ØœèoY­¯Yf¨4‰)³Ä êW]· yµ«ÌCCºARŒô°kGÖÏ ¸ÄÇÄ­qã_áó<«<š hŸ†ÕiÅåkǸ…ÐŽã%õ]ã;ðøNZMc™-ºà¸"Ú¥mí÷K-À½<È<>Æ×73ç.Td«=óÂmBÌœŸ¸ÎÂx¾¡•ºàoàæÆEø�ÉæSQÛIÀ ׇS¼w’—J]è¬ÐZGÓRmïåЬPDR Š& Q‡Ôåbî¸6©oƒ1™}tÉMdûC%—Úï<‰‡“æh|«: „°‹øXÊtA$^" ªÂ[µZë<ŸÕ˜õ]òçDþäüùkY´4„ËëÜ›ñD)ªþ­ìÁiÅ“9øÚ¥•êý3½br/?¼žã‡ƒöϹÄÊç§|švX7Oj…ñ@:AG t“8:ªçCÈä»oòòQCÍ‹´P…lc«Ñ×r±Ü€g9Ý#È_ÐüôXXkWs’÷üXÚάà¦YÍÄã}Ô†Lûz>SSÆ€m›ZͶ‰â¹edNT)³àDOy½ßo"9#.]˜åXI@«l0¨Þ–FïûŸ?­5Xr5yÛ"g¨„ëfñÕ‘ª4ž[–Š'±þÔâ³âRŠ\}‹—8cmˆ·}"ž6àÈé'Àç~ZÙ·ŠÏíy’D y;¤Éq}ødxsÖœC^7@$ŸàˆN{°húI;ÎÜ"«®üã¬0"…þxúh\c„;ÅU«Ó€O,Ý´ éIM0voãyº—Á$TŒˆŽÁ4ñQÚ!»’6dOcmV œW„0rTÇJ…OByÖÖçÂbís°J¯ª@±øÓ‘² !cLšÓdµ±-ìW#ð'äÃ{³Õ0U4ÂþJÜRú ób Ù‹ŸŸq–õwÒ‡¼rÉÚðpãù8^¬)9ØŠ mÕ8<½öL„:P¾ÏJ•Xà zu0Æï¨ËÉq3ŽÄîîKA¼Afæj}d:÷úûB¯ÎÑuF½ƒ­IítÝVŸp¢4Ñ–bð{Ëž*Píoíæ bý ´‹«XÅ•sÇÖ!øÝ\üjé+tŰ«„Ž …ÌŽ¡´1�“S=PaÀqÁA¾8¯ŠöU÷ Z)éÔU1Þñ"KÖò®R-¡k©c¡«ž ¨|KðÕ6 p™ŒñL‚˜"­¬Š-†A÷¡ê\÷Τ£®€õ*ôo'ŠÌÚ‡ÞNm‹ÕZÐ#øºÕ¹‡©û¥Ú¤rÖ¨Ž;;Üú±éC¼’‡I,xJ®‘} »i–“¨Ε'Ç) Î¦ƒõÛÚ:Ɔç…4Gá±&@+zPf@Ɇ‰hÀ>-À Zc+ÁðVÁX-P›W]s+X&R‡�7WlãËn{ÄYiõÕâ³Rž&´¥ë¹*ýÒ¶C0¥ƒcŽUcL¸ œ^ŒU?ÚÉ3W>4�iBÇ•´\ O{ùØ…¯¯ßÆ/^_Åy»ImRn¦%ÿ˜u¯ùbÛżÆÚ{ïÒÿ®–Ñ2úI½­4Ž…ÑYÕÍ^gx±®hϳ-¾ ¼sȹIJ.—ð2Þ¤få˜;ÝeºÄz€#Þm<h›Ž®ÍÁ¯ª4KóÄù®'R1Q=ì•àÇ’•°·6)‘çâœdFâÐÓ\Ÿ0-2|³±ÑçáŠÌIÀ¤£ºË™“áиyÈO‹H« L=™à#µ’Ós÷UM—ø< ‘§m•ÁŒŸð€¿ëÂ)wÅ]d[Ÿ¼LÝè~<á®Û�"a"[j©FÖi.0Ïñ’༳´€hY¥;C [D÷óÿGóXm¨ÏÑ•±°ð‡ÁÙ”¾ã“3ºÊÉ`õu,&¤hɨ¼âwÿ©ån‘"Œ×¾°AU-éÖ¡b•Ëç[”¸qcæ«ßò`¯µ•\õe;qJ 2•»L…ÚdÔ-v«~ 4Ìt)1-`õ}Ò#k¦bG,xÚ¦=ðeK@¡0WϾrbaiñUÍÕñ0æ`Šþ<*d韸Y{èk{èÈèÎB>\¬“»œkHÐtÓ6Ê’'·Õ$Pèåû“ã5U­=Ù:XÈÎø«Úd™Àhm/*]ŸKس¨¹õaëxÖX‡-.æYŽ:|òü‹3ÇHº={…®ÑÉ@†œo’Ÿtá¸ÃËàÇÑH`î-››rÁ—ÈáÖ±ÐÔìgf³eiÎQ!N»¦b»‰„?o Òh!W=2¥_eªIÐx’a|EäFc>ORuáÑD,8`ïŽR ò‘óЭïávR–añiÑáx­ÙÎö’n—i¨\Bæáž!0=oó ÎåYVäÆiÁ ÷²Hu¢Lwñª\¶µiÛ!³ê$%rusª?\z±»,²Îö?÷ŸR[´„ÄÁõ‘zxÿÏ«± ÕÉšO† Úvº5üÎK›`òÚk67{ÈÖ®>¿%r(ÀqC!GZ]ÁýYis£»jG2?GЂÖÀE}+!y’ïòhW2ÔðMq°¦•“8Ü£‰<ÛˆkÔ“i.Ãÿ MÐŽíVk˜úcaâ°ª–ïžY„/¥ãÂÊV:—›"•yŒ³™˜»N1ß:ø4ADæHzõ‡Ätl›£)cf8$XÉ“Ã5P„i±_·áѪ‡2-ÛüÆ–MÝÊTï;|vXÛ͵z×gÞR`B×kš¼}²‰P ÊѺv¥©Ú‰3%r·–:€j…ÃÀ¨,èd‡Îo‚häò3 ClPdWʇhåò`‡pŸÎ´ !@HVm*‹E ýošÁ̪ƻŒå`T¥78Èt?»˜¬ÏV]“eüˆNCËŽT«HLÂw!:åû±"Fž® —ßàpÐç%Gê½ÛUP­9v÷eóýFFÓÜí÷'†©”—ÀDŠp=8ª%§'ádhZ£µ: Û±mù@‰j,o—´¬± NR5Vx�1ûüaªþÕBdÐ}Ñ…Š0Óº#«bà³Óæ4ЕðzÑ>–k¦"‚“V Ÿá6Û*ƒS�¼.¨â&SüÃS‹Ât;‘R�vMÏM„õÑ@N„YÎ~(CÐ6´gJ?º®â8UdN%'_ØÇ|º§ Ã�ÈOó4ã”þ¤îw!h"ð-":?ZÅ?Ûk ˜}/8 4Âů¨œÆÂI?Š[ùlU˜¿®îªÕÃN§š‚ ƒ½mî N¶GïÍŒ+{N¼QRrìû“C X•T«­Xú“‡ˆÐ4<-³äf'L?4n?V=dK…Ëê׈bµK- S ùÈÑ1µ{©î{ Øñí š`RÓ¹‹-ÔÍý\4né ewÁ¹ö(aê&œˆ@¦’–Î iÉÊ+*˜OX½·6ú$®Ú™PQ"'o{¢AÚ`îá3•¤üqßPù�±_þ¢;Ýo‘_ôØÊ¤‚™n¥h°ÛÐ µÏ;.”ÍÜÓÓÍm­­%È‡Šæ'±Ÿ´…á/=T«kcû·¬ta�ôÝXYdâ[@Í Ùï!AK÷¢&¸h_T§…A°—ŒäI’üõif²XâW,¯ìú[„—æ`1E,÷8è‹»#MB¬¡ý.Zég|<í øªðçlr4ëPM «ðj Á“*s¶*ÎûFã}u’ëT‚R$LψjqŒÚíeÂ\›@–¯´`î|„XN䚈 GÑaµ4“á¶~XµÍ ®?cøc ¡ÂdͼZ'Çý£ÐrÅç£<:18:Cþpâd`(`mlA¥%Ô|M-qq’öDàÃ::NC. ¨Ó¯v‹‘>Vʳ×xu%gg…«p'É™ã¢\Æ,€Ør:½L¼Ö1Ö¥Ëo¤"¶¼ÑÇ‚síÝÞSÓ‚„S '…c"3Ãy‡9ß*<7œÎƒžÊò*ù8*ÐÝ…@!'M�&XÖ¸$se2ÚÜ®|ôÈ)ª´{@‹[{(„“d™'ãk°©6z%5Ó¬³ÃícZ¨s®„›þ2N£wÞÆCQ¤˜ò9Txí°úiQé¶,Ðü…“;o}ùç¯Å<ýÊ„&.’§#n™×‘Hƒd*ÖW†in:u+Ö†à"j9Í߯/Òéõ(¿Ð¸¤•] SÍ ýí' D'@$$“Ƈ«’ãq¯/ư89¿ô{"Mµ¶ @„Éoi¹ÁÚåMI½&Z“ë[»\£ÏÙ$ˆ º“´ÛÐ¥ñ%AUU—Ýdº�BÄVPŸé,Œ‚±&@8­©Ê]Ô 3ñþj7µ~î¼)_Õ³>+QÐn£i›”ˆó–àÕË¿¨à #•†VO·;sLÄÒ’$ÖÁ½ßÑ "`PÔĹ´EÔÎ ŠsDë>´ÃëKÜEnA]î¿¥Gà Ðß3›´öeYÒÚäE·ß½}Î?åðû‹ƒÃ¤Í'Ü.²hJí@7zÜ V}£áúý;Î&cà6Ò>SM+¨~žHŒŸ° uÌ #ùù \¶*¾e«ó®ßHŠDK ÂÆVð Z‰®‰,¡ódáfv´ÂqøŽR‡Õó)×>€µà‰ZÿÉ·§3]ÅÁskâJ Šo·scu\A²òÒEÓŽ|¿ÿõ ÓŸ¨’TMÑ·Ê=¬ u2‡x¨F¯wE›»¹ÖòZØ‚Ü'L-g8^ÅǾ”Í;A2ùZ²æ¨`Ä‘ÌHXzê¤ ×ùb¬¨-(Ç3vAµö4 Øõ¹ØÿÉÙ>d^Dç:?š¡ê®*h‹lXo‚Ì…œ;î|yV5ÎlÏ  Ò»w#„\¢ý®_í ÐD%HHÛ•„ÀÔàLäû™¹ŒÛP¬~—>@uÂ*($ Óô¶Ys¡e' cRJŠ’ˆG­OÔq‰/°(±ˆã!hÆ2n<ú˜2 ¸óÅ-çH‹„œÇõ0y‰ƒ÷ëÒÉ,@˜ˆrBö¹Žè„ÔÀA3ñ5-N ×»º¥º£Iëå$g×(7„[Ûø`3 VÖ.�A˜Lçø£Ó}¬TöIÈOŸÌ×ïfI–8§Wcñ ޲í“q×;NŸyÕM–!¤»ë1ÂS,Ýuš+1Ûäîñ7€´Pô½_úl—B ò\#XßÛÒ“«¢õØ 3€ˆ�y†»@ܾn9/ÙÂ-÷å¡[ƒf$7¨ gìÒÒ•LåàɜŶh™ú3ýèqæÄCÔ¾'*M)=¬MµN / Ä“>óÉôCtk°@™ñ28ƒœØuÖ vÝOÈh0:~kˆ ¿ûå¾›/·Љ±ÁŠ—50£ÈžTÒnd„:-Ú• e<[GÄp/‡ú9¾Úú]YlR¸$ô&Dñ6€}^Ö$bµ'uZ"ÓvpîÃ1uBÈž–êLðû£ÐÝ8Ôµ»ÖàÖšØizžÖY)‡rÝÏ\Xú–ÁT`@ÓÐalîÜ>‡ÙX½>›®Wx‡Ï^!c×rÜ*ó¶Æ­ …²  ß@In }Wr3¢f{1/„‰ç^Œ·Ú‚eƒ)WVXpŒæ–B˜¨ûÔ{ p�W¡¥ŠÍiÐ0¾}|U¸XÍyãÄú^'µtÉ ©˜õI¶x•�oÀª{ hÏW²nG ÒŽçB@‹ßF5ÈØ:—V ~ÆÒFÌâ3-WÞšMWþ5ÆÛ‹ˆém#¬:‘ RºsBð¨C3O zy\{~4&ȹçõ@èÝÕðÆÀtU±öZÁú:îÙ}=þÒÑ‘ëÛߕЄ¶ç`þwÿùßÅÏ[Ãkž¼ë‡ p*~Ãð˜ªThŽØƒ„¦ ¥3Tö¼gþ”.º~Óy5�Ù!ÂsÉñ ðlôÊuŒŒš“ùÜmìÑÌ4½½êrBÏãéö%£[`ÏŸ4Ÿ­o÷úr”3 0°Ä3X’ª[C)‹ÜÌy‹¤ËpÚrF%ëg'ÈEݤw9>Á˜cÁCØt%¡y ¸þ š &ëËŸ»ª¦D-†„>8,į>„ì9˜ÞhSB"ýÂÃ!iÜ8Í~"BãèŒw“º`Ѝi:™R"y ©üdÙˆ,Z Bþ@ÜÔtÑlÛù‚êT'ì²¹H·5•¯móZ؆X¾‹+aŸm{Ä·­5H%'”Ò:‘ë#CsæÅ Ò"ºŒ-¥!VâZUYNÜÛ¶Df ¶;¸³-öc¨rE: 3îCŒ8èGU’.zs 8 .Þ a.Ûèdk0éÜnvw3¶(ÜžøÜiÆõ­tâÛ‚ fùÄ’¬ÿAã-¨Þ<½~Âd«-Øy3pÜñŠ+Ñ-ž°Ž…c†ŵñkŒævg ³ÌîÄΩw俭ܰ’_LŸÝeü„ª#8{µ'FúÒßµKªZŸ(¸ୠ»­J‘À}m ÁÏWÈØÊ2:}úm “¾wð™Ûµ-ÖŠX„€gå¤úÈÞ3»êС‘HÚ¸¹Û¬Â³:.ZÔ2¶iyÀÁÈx‡ó¼q ÏsX“q«{RÜC}êA—¯}lVtÛ3­q¯ôs»³Èïg߆¹X;÷„|kºfmˆHPt,ùë·°&Wµ¹ñˆUk…ãJ–´ç0UÂ…ƒc1%5œ‘ =ègVÒ—ª[ÖÖ<õ@/ÎE/­És5)ñÀg™Uõ ܈:·H‹ìô]òKz¼ž¨ƒó¨ ¿¸�‹Îk®Hºyùø*_Æ¢ç$þnÛŽÝÙö ”m9¡2¼ƒi!^¶ EI3#~Ìo ?p© ¾ü�ò²”&´ÊÈ9ÓtœÈĽäQè"`Ü•Ñhó¬’ÈØ·¡¢m´çã‡&78I¢[øÄZ©Âo«ÞK:Ç *;ƒ=Û™T–íúä:ŠÂ޲5OI—‹çë…DÔdªàcý ãº^?ÈÑ‘ßtHòÏ£Éîj!…Ã|m¼v«­—/Ìqª¯ß œWcXmÀ¹‹>ÖÏG»ÚÂ¥zÎb"jÜhRß¼¹±ã˜:iµúC\ìµMVNL¯ë™i­µ1˜¨;9RÜ6:‡ÆüÙ§S'’%ôG.H_´íÑ<ÖX.šU ¨ë-¤ß¥•½º5\êBóµÜŠA°®Ý)N‚<©­uµžï¨êˆá¥ý¾UÏæ "¨ÌLS…!œ¯ø?ö'¢±õ±Ú™}k -ÉÁ{´N\:¤mt‰bwOŤÇÀ-H—_P _ôàÓŒç¥÷L;D2Æ£¹Eo*ÙR&\ ‡”âåÌOÇO¬¬Ò(u‹4ÜìCxWÖ"ŒyÉšÆXoÅ‚àøi‹Bí*lm—ÀˆnxH`V×…'Èå³‘í±¬š^lD0>2] ‰· è ?ÖZ"Hë{¾þ× Ir ÌöŸä=]„ êA6ŽŠ{…Cšƒy¦ö(tÕƒÝ&ÙÃiQ»ö8ÛÛøÕèâx˜Á}Ε:Ì„z2Ülé$fŠÜò Ï’uoñs‚ƷÞ³A¥±K½5xT•/­S ?C*RŸ(dÓ?Ç!Ë×bÀVm«v^^ÿ@søb'²íèˆ{®./¡‚Vªhõî\2’Õ‹ä8ÄŠ‹ÜîµHŒÁ‚Ùv´õA*fXÊIÂ}•"kæ:‚Ö.Z-í/€šâß3ùv^U·¹iÔ#¥q@|‹Á©m9X%®”{úîÒ·LLªfàöLΔL ÁD|‘@rcû±WÐU6j9m²r*yWÿ¬ª`·ÍPMµ‘¸}D°©N´ÙÄõj‹¶ñB ¶.ª%$øŠ37òˆ\¯/’ä Fô®áTrÝš ìFѧ“jÒ-Ѕ݆%6–†s7�‹´83—Ã>ù[º›¥)NúÃ?¿ž)LŠ–”pµ8?|35<¹\Ó^®@HúÆðWÆn±ÉX¬ò²¯t%©ŒKXq0G¥=ÜVâ@É JÒA�C@¸p óx¬§«ê¤šW­^:Ü#¯/tJ7„f ÞLîO| 5ŽB\Öv ŒkH¸†–ôD ‰â¢`¡µt‚øüh7 ?yF•vYR×?ýxXѶYP!ƒ¥mÝ y•œïBÕ\N¥%GµvÕU힢FÄÏ:E™ÂìDÎ4oøâÑZ N–ÕavœÀSÐàmLÅ ÌW$»•ºqû‡Vßdl¡ PW}MwÖ'¨ µ˜Úû»V»Ä5s`d µA‘�Á×;©èX••|°&vj)æsóÜR½ê À1{«ù׿7šiuUog™š¤ òù|¶pãt“}{X· ÞÔ†JËÆÃå§Ñ‘âÕûƇ:L®ï%ai êiŽr-O»µm‹Lgæ^uâì^µ”`“ü\ÔU·Âç&¹6(m™?��gÀ7i파––x»[Zi–ö/B•#®ç4ˆ—ç®`:èZ�»HŒ¸Œˆ«MlA¬•F|·a«OèÑ´rk'™Ä@Ù’gf¼ÛGÒ=C¦Ó ¡¤S·€Ãñ¬£%ÞE?üÄäP)®ö²2Øx°@•`†i{‚9žq9üa®lÂ?VÜ‹l“7Bls-ú’eŽ^)G[a«'ëªB—VÁd5foa?+Ú'Ó¢b_J«º=) xß:÷Ú– 4¬ðüö Úíä¬Ô‡ˆ°B ¨%>­IÃã*x —òòsÚA™V§«ÒÍâùotÚ²Ÿ7+p?r@T¸™Ž»é˜jÛ #Ý£E<{\ “²x™ómÁ�½rRje«d’‘lAз(¼ˆ<L FÍbw+³AíU90@U³åI.‹ayûȇÚ×È\ ·L½ÔQÄ{"õc5!uF¯+†´²Èñ 2®ò e;3¼‡£Íc†·6%r§ ]Ï{©.‡¨C곓ž€dЍ%@Š.·6¤êW¿ÝÆWnPw8+ÝZ7@^%9Öø_'êÜ ½õÙá[0)È Wð[8‰Àq}wóßuŸî¾5yµuafOëÆYû[q ‹±};’©Q  ùáZMí"žg8A†Ê]¹N7&¥ض@*s·iÔ"çzæ—D¦– ¼ã"±°I1ÖnÞ%¾´§(Ÿ» Þǚ‰zÇ(ßÐ&\i7[·¸ÃéĦ߈¼È¶>ã_JI€ÜçE\ÊÓÕØ¾%‘çÂÕ cÄsô6*Y–‚rƒ‡¬hëܱ^Y8såûpÂÎ@&Ï`×é¢MIb¢ pïµõ7>dÿ·FíÚ. Ùïz.­ê Xõ'Ì è+ IZ蜼$t´ù¯UQޠΛàwwáûV½—´|öEYu€n‘çÄ¿`C”aÎ0YÕRUTü¸·/|`¡IàõC*}–AÊ"ú'„éÔc#½M`ʵß@;¶8ð~kÿôeh3ôct‡úI�µííˆÕöH!’û­‘œY;èߣR¨˜)BšKú¨ÐíßÅω³Àø•iô R� ùT¿%}‰» 5`SeÅ0u¦!ŽWWSGIˆÔr‰¼îñtÚ®¬šV»PáBB› ¸=ð(¿ª¯A÷ð{3;J«­Péá ÞÙ‰ém¤"|×ß8GuŸ“ìØà99Oµ‚§^‘"f–�­')’åäL+LOíðÐHÀÒħ‹§kR;‰uÝ0;GÙiœ§. Ú?5¥¿ûZÉ'sG:ŽÖré¶Ò3ÈUñjÉ\Uý‚]iÖqÉ_ Ȧæ½óc¬XÓD…Òf^h3KXšøë|Vª{’qYbÚVûêÄÅø0³ãäŽÔŠI 7î›…”îåÆ>wÅ”êù·B>ÖM8üàpSoá{DÚ?Ľý‚Üu^ÓÌø\j{þ¸r9ú¼®n•Oû:IƒsÃ*•, °g|×ÛŽŽäfÓ\ÅÀÅýøZ¼elÖ*éf^pB¥ž(žÝ"‰4°.›-²¬­!n+n[8¢ŸdqAEh|ª±Ñ³N°f¢ïÄâ½ú‘ôìwøú>R]1ÛÛÂEPÁÁz8–¸{›ÁÚÔRçáýÔp]Å?1G¼Ðg¨æE�Ii–Å—i£+·è®¼�nD3ÒOÐ*æé'9šP½lù KI%j´¡ ±e©Âça“,ý(í#3C¡ê ã&Ö½?j|—§n£êP¤‚¿S"å‰ÊcCáàÊ%q?åõ«x}Ÿ(V3mÕÊ0MÈRË®ü8vë5þçV]£ŒöÜRmB¿îˆ Zï<#à6BšÀ Ofa©KÆh”u<p":Gl|Çx#w ¢Û•á[�� �IDATš¯»� |ïVï°=†øâX¿ï.·é“ߥt¬ýëÎÓ æå‰Ïï’o½~õ5Òý§% Øéã-„p(pÉö3ØT ¬¸„2ÒÐjíÃÃáÞS¢­€Kw!\3SåBUiCE0Ž&»]ë\>9O-õ[MYò¸ô‡Å¦…×u2Œ *nÔÔ\DØèÚw`5?炟®cˆ% rô°ÙD*nN jÅRo?Ú–T½B&**idvPÂìJ7\ u܇ȥ˜Uë<MâEÂ$UÅge(á+¹ÆÄ¶qÊF%ô í: é+ù,ЖÀ×$¯‡&a2A,±y®S5+ yF’¾\=d͆¸ÉT€sýpÒt^׸¼ÃApú¸Ä7=Ä —·¿¿J=œ¤{)Gÿ}Ãï½\ =\Ñ»‚ïýJiÓn®¼p¿ÞÉŽæU, ¾O¡9–¨¢›0©Þ—¨éØpHo1"–Iómpé±'hð:‹‚ƒën̘Yî=C©®ðIA⸙%Îî¼a{¦W]uªa/ˆãUº f‡š[b'VhÛè²dr´¥šÊFŽ|ÍûTB{k°ªq… L›ÃÁ‰¡c"2TkàÎïÝw¾8o5ÈéE,«º «¹×ö Z@2Ex—e¦Á*þd¦@BÝ» ŠÑÙ™wKUSºÔv!ùÁ‘[ø¥R¦Ì]ÖŽmã:†ºî3\ÐÚ=ÄÂ8˜)n;(?â~‰êέçpý¾¬åõëxý&R1¡ê~R¦U KV{¿ÒwOÏ+h`˜ŒNˆ™ƒe%¯D¢µoD¬J£W¼ íŽzxbÎü]œ [·:ᤄ/oSYš’,ŒK-T³tBD�ö‡ÛSÏÊsÛ�s€wåBZ]k_ˆÊ£MÒÓ_gE—ÊÌåWNØ¡B>Ñr×Ä׸¸Ü¾þ^¼^íõú+¯?RãðíѼ?™”^/jE*°U0¹×AØÒþ½ ËÓ‡ ÕåÍc¹¿ió`&u¡O·Jô%}©! çŒÂÙ·ªgcÍÓXÍ*+¾Zý­C,ñ)Ð?ÛŸãq½ý4y Aõn"5CðÉ8­•|´O¯ÍŽÝsSˆ¹bûmïRLŸþX¸ý6~ñú.^¿Ž×ë?x½þäõúŸ^ÿÕ×µw¥`´’íi"n!Äé¾B iYüxŸIv(»=U¢¼±W!~f×/%mUN ²Z^ßÀFÑÉo'h·�Yá4º`çvP‘Íç‰æ¥¤ƒ“ÈxZï+h²éÕ›ÕieuÞ]ÿ¡Ú¹× Òšµ‡#ñ,P„ϯûmüâõ÷âõú÷_¯ÿçõúíëõ¯_¢ñ[´„+@"§Â“¤+]W°w3S¥ªþ\ Ý/ÐPÂývîéÖg«±VÇõsru»ÝxcÉyœÈ2µ ìà‰Y˜Îùy`<žDÐÁÔÚ’½µ©+çk´gNõA·f »&2X{PW-)w¿½·Ï‹{ý*^¯¿üzý»¯×¼¾×—Æj U0Ù“ý Ò Y [­Cw²¢­¢ÆŠ—ü½ßVcióò^t{56óG ðú¸dqMW÷k7Ã& ï,ë±°#þµ,Oà¹Ùjl·-¡³7[Eıâú¢að ÏAt¹v¤*ÕÂ×$ˆH:ž}È¢<Xk‹Åý6~ñú¯¿¯ïãõ].L2›ªJ>S'`€ÐÈp”eû1­Fà™ú Çö"–«pu0,+È_×C‘îÜu·Kù¤*jG(\îþàÞFÃ<ˆ,˜!\Þžc¸Ì‹•„kuÅv_Ä¥äR6x®¹'ËnÕ#.¯ïJ‚廕u•ì{ÿë>>Ì‹Mâ*‚ð@ƒ=b0€@|EqeÅE]l6/œ~…¹.ôt˜a³‚qÖÐæ=8/¬#Üž ZC¬!Çò!ܧAÎévñW$p @Ü=<G^²N.Cŧ†¡DÏI¨‹îÒ—U¶—}´¬†åÓ®â4‹^Q5Ñø‘)¹ÎZ¥÷º?¤ÁÏ£Û‰Wšã®[˜U±µŠ®VÚõ÷[L‹YœxãÖ ,ÁI‘ãJú*M×{ÌÒ¨µêGŽqYþOätÖ¥[k¨Ó&û(ßø¤`ï'£ 9¶‚Ù¦Ê`}6¶€Z'î-Ua»m#“aíV×]+8J•—«6O¥ó´èÒZhdë°¼P-ˆ·«!´Þµì:dOí]È£mšº:/–i2Ì2+¥¤ÛPAKcÊÂ4,<äü(ÑmªªÓËK0ÍŠ è-O5Lr/à„·Ðxˆ*€ @û‡-Y¦-\x„Ìo>ÇqËŠÒF£±áŽØâÁ¦J’VòªS7bêhÕ ä&¯M>Ë© ü»" û #Á› ù©ãZ•yÇT'È@ý¦uÁH¿[Z‘Xï2̼µj[æ1Tj!‡Q+‹R%z'­…[šjçÜ3QÅjåV¯C�Â-†j|�s|ž¶Á£â¤LÚÖ–—Miz'àÊêÑU±SD‹JL«­9ȼøá¥hØÕ·÷Ž”"ÔtÄjSˆ$¬Â‡ˆW@*‘Åy­ƒƒèH ·ÍÔäEÒX·›IºcLã¼ ErBPP¼Çºá–¡;Žy"­fÝèŠÎä×â ÞR¹ L†WÕÕq™*Ž_ÏDWÓMASfô›"ÖÌ{Økm±–ŸOµYÛ=HäL—c!}þúdà%6Û…P|àÉBž]ÁIóA¥«7ÑÄÑ‘OW\œwöôN³p0‹vx^»´²=ãèÂOUÝ“oMÄ«ýŸÙýU‰g9Á÷H¶.Ür-]Âô…yérÙ¶ƒ€H9……•—(ÎvÉ¢4 ªRMN;„Ó?Rñѹ1X¡Bö^ĤÔJ)œv !*ÅËÀä©Âå<̘ÍcEtøVI½�ÚmIÊÛJõ«Í I‡Üúšƒá†+/±`çã¤ú;F¶pŠÙ³$nI†ngK¬Õª÷ÞÒ:xJO¥ô¿–BvË@…ÀâÒÆ‰5K+(‚TKCmûSÚÉ™0)©òÂV—¼j/¶½Õ"ô.‹ÇíÀMj¬ô=t—8̈Ì× Íƒh)²Ì�´µ>— –q7†Õåd!MA«ŽtbÝ>!~Í-a§-2tÕ³Úf^eú®¸ïé¶uMÒ«t,oBYªÅÈf¶`§@k#í6’ÁŸUâU©Ë“DN ¶Òˆ\­T�×b­îÂtå«=ÅO¡ê²A�ñÝšsÄ"OÔþ[H‹zWÂò9vÑ1é_Œ½vÉümBÊ2–ñu<êZª¶£ùÍX¿¨j.jYÎjЪŠ.Õ'ë·®na179‰KõõS°Éâ²×Õ1«ýº\ÑŸ”›³œ ËŸZb ìÀë;bÁ‚Ž0,Z˜H0µÊNÛ1š©›ë€M\t9ÈËëk’ @V[ûx[ð ¶v²Ö-´KÒöìæqa=wP7]ËPŽC@Ƚ*t’‘Šúì“R)Þ(¼Ep’zÝ‘4¨=O*4Eô®kÉ=pÚL´ÝJ–.Ú"¼f©+èãb™hCFï5nZŒóe×3bPÃQc@PBä˜{efY_°‰ÓQt —f�‘ j—VÛüoÑsâ»úÑ>hû[ð¬ 6*œît2«gº«öÆá®i ¬E1­9DàOÑÂ>Õ:˜¨Q8ÝhS¡ô9|$6tÒ>Ì”Èc54B8ÃÌ]Öân96n™ÇrK1+S7°“P7›’ßô‚1P£s£ •øàPÓ]˜.ÀŒ’Ö]¹¬:ÑîÒô÷jô¬šë$½aØÏ&BÑnùën äêÄkuóÐâ­‚… |¥šÑ6x–÷BiõƯæˆxÓT'µ»I0¾OÈù-Ñ“ƒ.ƒÁ=ˆy Û–‡Ð•ªU‹š¥)Lãˆ5>ã4ý¡U×Ë«ЬØ$¨’y¬TÎ…ËD³ß¤6”ÑAѵ!Ý,RùÍêû¥�Ò€ú‹·Š,6Xõ^÷rõ®òê©Û‹Þ„`­Á‰´äZTƒ÷L¥ ºÕq)Þ+‹DŒ[¸#¤n±Õ¢;ñJa†á<ÖøÀây„k€ø¬RÈ¥Љ üašpkЩõ—kcUË`üüÿôsõ¡¬{ÚQ ®b–¥xÉýÌt¨ã �ëï¶´7¦jÈ}ŠnoD¥ZïUäŒm ‰Þkw>½PßwrÛÂ˱"Cî_*MC«³(u€œ!b°’!ÀIòøÑ‘æEt‹cK˜JÇþužžD!x U)¯'{5|78M\˜‘·"¬Ì‹¯HÙ·‘R+óžÈs¸Ñå.9ÇV Ûãû@¤¼_ÛxZÂÎòŸÛ‡%È-'cEè¨æß÷o´À_©C „úÛty‡"£–N¯¾&±yÒ”ñk¡²†Þ‰\!Es|f-Ôƒ¸µ«h>éR¸Ôdø"÷…{nrqrüž}n§öÈo·ZY0i{W‡Ý@ä°Õ}ÑrJUs®=ùI�©´ßîˆ/k2GØ+ûQX oí9ª/Šì‹š¯‘XiTý-‘㿾$ßëý'pÀ6:‚»�9µ7‘ ã&vK„EÏõ3ô˜)âlE~!‰D°¢j1ˆÛ''fÛT€³eV5KO®½õ³€“ÿ\FÌ*/¾El@ÊL œ¯y±\"ÏuZN‚i{àí_á~Õš¿$=ßñê§ÃUHÝäÔÚŠL)¥•bEþÜ7Âë‹7¹Ù³‹º.QCÝ•‘¯éä§hð-$[}-‰Jϯ«³ ²‡ÓíçÎà Uø“06ªÐ[b0጑ާ` µÅ+iMÝ¢ù;ÓnO„+–x"Ý4NÈöYbÆ!°ÙVfŸ£íõ%^¿Œ×÷žn–˜,&À~b¥ìô¨Z\iϵý:× ÉÍ–å·0ûÓÖòÀ÷K‹v¶Z¬Ã3rcP€£:^Èέ¾È \Á0íº—´.î£KÍŒ_ujÜf|îŒtó('6,?{ äçBHºšˆZ|3ð£%ð(u{!’vàj7TÏP R#•¼$UEÒ¿±5|ÚuŒ„•óÒlKOªÝ®ùÉ-–[‘r¯ÊÂE$ åÕ.ÙMMÀ•D…ÚbæQLÙ·cõm½Øî¤ÒdÙ§ÀE8ºúíñ-^øô˜˜XV’«ËtNžXyñ£¼¢0œàN¼o×:œÂÙ—NRŠ£Õ¦3a˜œYW!eà[q–1Àné'¥y@ 2 Ã¥T…+áºÅRâ‰(¾f*¯/?âFŠ©’ê¶"�ëVSÛüƒ²‡mZüùÖ\¸î#.âf°†;o*´èÜ¡Y˜„±–pwähkm�a"=Ÿë îÁd°í=„Óÿs=aaÉbíù1ž--Wjoï0UÅG¥9¹ÿ¤PÕ»ŒT¿îý¯ ›CTxÕ‰ŸÎ0‘æ« æ_ïös‡päÀ’Ø'®ˆŽÑ@öú–Le¿Ukå·&À¶îl˜Qç€ZÈóVr´Z�–>^Z ‰¥B¸˜ wºSÒIÁÛ²:>Í9ÁGH¡Ã®Œ(ž=º(l/²þ5?›+}@¬Œ¬˜~ím§´Mµ ¤ejìÌ !/²…ýqEí4\y]~pzL£å„ˆ‘Ö4Ât &¸ã4}'Ù�9e÷¨ ±Eoç Îd5LuÉÍ †´7fuV¡RK³¶áÕ†{äÝN(:G¨Ú$Tï‚—êƒdÅAÞSˆÜÅf¥P·0-8v?ªÏ¡ý×7ÎVõ u øTfð®ŽÞËûý8E4Ò«T‹IrÎB»„o$\BESL³é/NªCCWž.6Zíî"qèvXoÿáG*€ª¬n×ÊB�>ºF.ìj=¤¡ <Ï0«çº-©&FmOj"·§FåòLTÚìêŠãéîÅžt_€vPq¿¥åwzÅç/^ ‚É J}i#-Å�£˜*ÓÂÊ{Èß;‹z+:£�½ßõp˜è_w´k®[Iõ‹4ëÔƒ¸ÊPªï––íƒA]!§Ø¾Œð™o‡Í*Ëy+åÓRÖ#Ï=[NÑQ¢a]ïþW÷ÙBq³“|Bã½ûA,ò_M—hÞo¬ô¾°ús!¹ã¨5yê=½´ ©{Ü]¸:û©"”â…Èp5%FÄBrHÆ&T yyu{:©©‰n+h OÝôTšÚõÚ6{+Úf¦B™rbŽ~¬pÔÓ3‹P™Ûg%Ù]D îC¶z¾ü†¿i:9{Ú¥Œ$[<VYßËeZ¦7l1æÓhÁ;>-£r?�ƒß­Ÿ,†aªÉåO=´k ]Ø)ÐtBÒÅq‚ô"*T-®ŠYͽ¥$mÞø ÍT÷ᇫy1Ø6í‰3SÖâ`ñ-RL–-z›¯ ä>>8ã,ß2áXêv¹Ú"íÛÃÕ¨­`²=b²zŸÁ¦Ç¬‚ ê'J+bljšÙ§d…‚˜6HÞðÃ`Ì@ž}òãå l~ºn•)¥(_ÜŽFš‹Z‡P öõŸ–Œœ¶Ÿ¹–ÜU)BÇŠêÈ@U£ˆ'–Ë['¢5â9Tn{ƒ»Õóm›d€îëÀ®/lá’ f›ŒÃ9‘W®ð™ê¬áÖA½È«Ã–»«ÙLK«Å$Ûª¢ÒA¿nÀw|ºê‰¢-pÑí4q¼Ró¨�¾‹ôKqÐBàcºÕÒÎK¿’öë§ïÚRu ›$+=Õ¼¨†Ú*mPºé–"ƒÌ¨ß%0èŽGŒíª v7`·oä–þçõ ˆ<L2[­‘†“öFzÄX•܃ð”ryÌ‹ŽCZHµCQ½ïüÕ+XwEü®Qð:çtEÌR`J( 9)šV*)|Ç~„’Ó ïœ²’­‚Q$€2'<Z… ÑÇÒ=1¢u-¦ÉZiÁV i ° á²öè¯üO#“”æ"Z~›ÍU>¥iÖVâIäü¡ô¤Âp¿ì¿¥gÆ=¡Ü8ÁWÕ; ÙéÚ÷zÄkx*~,*ñi\ ÕPâÒû¹Ý>ãJ”×KB· îbšH-6Î$:Bn¸õ² aC*õ–}# h,fК±x…4†h`´ÓGa 1pÏMQùYç„­ua¡Ýʸߴ²D;@U’¤™8{ÎNÛ=|¥øçêoA_yýrge®(;Ä ZΣk”ºú†X²"Á~f{¯ñr·"$¬ã%´hð\¬´· É2aÆ[¡B«IÈiÆÆáÓv¬Žcº2ÛCx`÷QÒQAË‘T‚Í»e«“WB̤gº%M˦´Ù -ô ‹YÔJéñ5å-%’ ¹Z‚Þ$}£‹ ´tY�±j%ÀÎ<2´bwj­»ÿõk–°Ï™^gª®Gÿ¢†›ÁÊëû~‹½Ý®<+øº$EH7ÑM£ òk[–ôç]‰ƒ´Þ{U»»LマËõ…'ˆ-§Œ*Ýk³ãÖUȪ ´®1RtkŒ¿-ÍoOä=ÿjÇò]*'Ò¤˜J {?§NœÀªç³ôlÄ×ÑÙåž›[±VxþVa)]ffän£žÇªò˜}„#ÕeOK̽c$”ÈÛ_)6¥GÍîY¬WVg~"{yJÖI K¶AELÊ‹\³Jy­RÁ`ˆ¯Ínww*\^÷*­sÓ¢ííZÂõ§ ´q*aß6ÄjÿeP9ñÏ‚° 2…‹9vµ­Ò$ä$ÃJÝcžÐ&hѽVôè4?[RT0]ïrJ´gö"loUô?-0xUǨÈÀ"SÜÙ1;DIl;N0'r:ÁéÌ¥‰Ç4#ÉêMÀ¶Å¤Æ"ó’öå_Àm¥Tiá¸?I¾Ž.äEÚnjWufL7·7€KØ]wט›‹âÞÚÃbù·Ød]$=ÕAÿ ׳{ùC`^cÒ‡*yý»WÀð ÁU­mº~x•µ#À à©—E•jùáŠÐØÊúT†È)Ä]¨°àn)—@Dn²XépÒ˜vrâû>î$·ŠÝV à–º"sÑ-¥ ¾›1Y ›ÿd”M<ëÃy…dYC ½ƒ—VJ+*L¢fB²Q(#’º4 *à;zƒÏâÊA¸òÚ—Pô¡ù½CÑä®5Öû©ÍG%úײ‘£c)/3û_OÙ×êp׃o›£©F%ÀØÖµç6)fŒfŸò…×D¬qߌë,¸…NŠ{T£$çÙ±¥2P kAMpøLZ •o­A »ð{xÕ̦ëÝÀåð™UÐJ >§òËìT¥À» &}bÌûĽ>B‚ËßJ•Ý­øÒ,‘W¤¸o› D¸5:eÛtÞn´5¸+]1~hTrûûŸÐ+�…†Œ¿YŸ'ô’Á”±+íÁÏ;Øð³ÌÀRH¶úɨ[“™ö´“¿l¯Á½'Úxq0L÷ÒŠ¤\«¤i­PÖÖ¼óU©9jöâOG¦tm©Ÿö¾`\4‹äàÂ.YŽi‘ãVKtéx å°¶Ù£3ì–©´óY3Ë¥ZuP½V…ÌÕ OÏCok&mÇ]éZÞç ®Ü¥²jA=ƒ.k{œ‘¹4ýŸ„äsúW¸Œ[Wi ·ñX Ig¶8n ÄݹÒBKɤt¸ý`ÿ@@¿ðø(¬§,m²²Gš¥kµŒ/•\êLÿ‘nj±&]‘yÔ*6}ÑY¬ÀI[¤¸¦S[ égjÿɨ+yˆE¨à-ð…N(Z†:Á²Ò>äÞ>IÏû:ƒ:Ï 3¤¹ë+ðZÄ…ìB:�²ž©é3{#:í(¡#PqÛ–2´ò«üØ –%¾òR‡-Òy)$¨Uò~D ø>~¿xÿüXÃé:›Åµ°µ@ƒ>gÓöÞ‹µ‡Þõ‹ìky}‹ãW«Dºæñ;74H“•” *T6*“Š[ÈJ(bµ–‡].îË¢¿Ò˜¯›±:a‡"§–x«.; ûó€&ÓâiD7’3ô”ž›!ê›tׯò¯W½5W7k–››&*‘yFÝç×ûtY~oñò4ºìB‚ ÛâýÁˆ½[¶ÏÏíPÛþ_÷ëÔFR¸‡´Ôíó\ˆ$üüIq?kà¡‚F¾ê|g,ÅÊg²ºk`4:W¿%X.wEµÛwV«%ß;Hð[M—Cèoá°B[7gÑyq{BUþ &6vÛE‹· ¿øâ鬫Ø'sf•AªhV= ÁílïíÚà!qš8¿T5b›Q¡Ýé;‹òúl?}¯ÝÂøóŸRbáW®õD«¨á–ThkÄ<> ZÕŽ¨æD¯á.!I§•¡]»Tøyhµ<æÕXßJ r¨Mí¿õ[jEJÚd_Hyr¡?ý”ˆÈB{VòǾ'ªPr,«LH¿µv´¨­¡K¨Ý«jÎíÇÃPLáˆ"8…÷ ÜT©(:oâå®Õµù”‚`×™ªëÞ|}‰×w?™Z°ö¯se½Wý¡vÜ5ä\mÕŽŠz ¥"€ÒeÕ¼3ÉHÎ;ʇ-®‡ ‘’jœ`ù[ž£#Ñô_kÄ$€äŽóm«vï¡ç–ÈúÛ&“FÌ]wJ+OwYø'í\—CTÕjß;„_,Ðfcoq¼×?×ýp· WÒŸÓ)v`S›j,}§-\iëׯðÑŠýÔa =»ÒoV|ñÔåäscüÀ%ÙOzŸ&.R*‡¨ÉR72=9Vm¿Kë`ŸK#ÏGX‹y+¤±}%×v2Ê£¥=%iG†­£Y¬žpfèÈ>9´¦]*ý{«ÛV/w ’»·mÏ3Ípå·{ï÷oã¯?Š×ëW¯×þzý[W«ø(¨_•¼7t&«�jn–.¹O›¤R[Xƪv"I*ª»cYÐEúámåí¾M‹«Ü Ú¦Õ¹°3®>v!ý»=è6>;ÌÛ]¬sú‰±8¶ $"y‹î“�Œ®w"T¸ÑPžþð4¿ž5“„ÝF<ÎJÏ\ “¸¿1üp=5A ôvtt—›kÙɯ¯×òzýã×ë¯}øricl/8¬ÎîR Xÿ½½$Âͤ(Ìá®,öå0½N_?0m›µ‹¶òü%$:¸I‰’‹pZVTüîoJ÷Y÷²’')bÐÏóï„ßÊþ±vK È<°"¤¥Ž¨â/V£ûЄiPî ‚nÕupŒÚS†€õÁ°“z:Ío,å_mÛ±l%G*ˆÏ’G‘ˆìÖ¿_¼þëx½þÆëõë×ë_zýRe Õ;­Z€ .Wà›¿We °£XW¨pqI7æ§I²uMÌ„ùŽžÛå)ÿI"•~£Åg96êc ¥TïEp®Pmz{n•2ûã`öÑCÏ cšÊAdž}[¶Šú´!yPcBÈ®DÑæ¯ :DZ¯Ç Òœ‘AöÇÅÍÕ `(j,¾bÛ5ù>µ_¿Ž×¯ãõ]¼¾oÔÉTîFÑ®Á–$ZY»–kz“×",ûð÷RÌÒÍ!O¯ÝPÚ+y„•]ןLÙöi±$ÇÒ®ÚJº™äN˜¸Ø Á ú bRúÁö¾;¼&²ª`2Vc»MØô5ˆ6R5Ñ¿zÈ‚@5k%Ö×jƒ@ùä3+ö?ló–kÚ³Šv&Ur[•Ô~Õ=Ò1žÏڔĽ+$íÝå]–bù±jÂôÊÎX8{Þ¶08ö/RAˆVwJ¸ÿ¤Ïí£¾‘öóÒ¢­‡wC¨[Ø–é-$^éBP¢”´ßã †ÔwÛH;áÊkÊѵœa”ÄãYv“Áì¼#ý9'ÊNk›:ú ˜kd‡r��1IDATc’'ñÏøKû¦ÉþŽÏˆjJ[ß?Si»¶ÿ*¾ÂRýìÅÐBÑw_¹ì{ìù`ƒï³þº>…õ—•]µ“[Kýç–˜\FD°”I)ÖFx>À±3ØõH­ðZ‚ÛJp¸ %Ü`âÖn\áu�Qn­F;ÛuÏYàmz{Ë“°:ÖŽÁ® â°–HûÅ-Íx ?¿ˆüG•{îQ\‹-Í Íw%ñú§€¼÷9D»âªÝ×z¬IϽ–è)|Y'RÓA®…jÙ@ñÎŒçLºÔSŽƒµ¢ªLŸ4EÓ2.ËÄ´(°y½êÑBpË‚¯âÌ¡æ¹1ÜFZ·{ˆøY o+7‡/†”ÅU·I–pÛÆªJ¥ šXƒn\3RÀ¸諆ü¹}e;«Ä'‘ÏŠUòúe¼~¯ï›g«Œ6jJÇ0«Ê5ÅÒ—u˜ ¾ÿüõ«¯ãÀé˜ðžƒ8;!¥uë¨TÆSÚ”mhHQ›//‘ Šií_V¯¨E5£™-é稬d÷iQ˜ý<ÜïîAÜ>z!8´—»¶B ιã”ebHhéöõWýó oò¡¢ªïÍï¡íºÁÀiIë¶"ËZ¦²rƒ$$c±l>þŽX´›¥ø¨(Ž}W‡Û¶¹²<„×—xýq¼^ðúï~Ä4»*-½kÊkßë#]qEAßÿu fBÖòú™é2®¼»à-:â<Q«º‡JUH€–Õ׳Þü›ŠS®‚ˆ[¢€xìiÚ$F9í> ¤¤Ï¦µVá6>„kÚR í+@+¬}ç¤/&%òZ‹ºShMÝ.%Nu@§Ë”ô{]æD,-€T‡Fmõ¤ µ�c¡ÕêT½Ê׊´ÇöÃ:=X÷øw] û„ÙëK¼^ÿÊëõo¼^ð&:^‹‰«ÞàõöÞÙ>§%\Töãøú+˜¹<¥EgvàÔª_GU Ud¹Ÿ¥÷¹•¢SØR™ÄÙ• ; ¹„î¡ÅûdivµÏ¥5VÇÞß›µ[lͽyö´¤žî¨ >ÄÛ!\ŒAþ¡Ç,\÷™ˆí`'œ—§z_·ÖâØ¤á8æ\Q¯eÞ6êñ¬ôˆYNºwe³ÇÂë|¾Ñõ?½~¯¯¯¿ŸL_Óµ%®\Zéhðž } u_â B^å ®›æÁ©š"™˜ G¤¦š!‰Nçbé;~ê×ým^¿I†ª†ÙÞ*O§ 6 2ŒX<N¤_;\Æ5Ý–ƒ‹b øB-nNNgò­gÕÉÒ3Ó.´í(7‰¤¯s·–³"!"HƒDÛiç ¤?Ÿ�¦Ox%)4Á¾PÂUàkë—_ÿ5í«]5s—KÅô§±+òõ˯ê‹_GÙ¾‹Åòz²ëêr‹?�P_T¿À5Ùë†EÞLdžtÖ¹ PÕØïDßðŒ `¯¥Ã{8tpñ­ )ËŒ”8K"ZG(»ÔvVY <�»(+QsߟۧÛoÕϤ#2{;ç*:N†ùª{h}{+<Ý«¨º¶zOíÇ)Óž\ªã…nÐrÂ^{TïÈfÁ•)ÞŽÞ/üÀêLüZyü2^¿úJZYîùCV@n:ä«×3ငé,“ z}Øÿï§'pí®Ç£“«‡ØÉž<¹çÒì?}Í]WPÉ4ïW´Dcays”·Ç,tÍ¡ ¶F«xÛÜóm€…¶Eçoã¯ÿ2^¯_ÅìcX·˜¢°ˆÑ{1—ô—U½çìŸ`³ 2wràòù“ïzÿ„¢ã¯ã ^ŰY5ƪ’1¥)î·=Æ–SjÌ®ð»ûŠU¥g8¬©Æ<¬‡D^«Ÿ /Zvœ“$¼Qµ÷\7ÁF®V•j¹ž–¢î Ew>÷æšKUÇ"É.ILKIåIÙïâ篿¯×_~½¾ý­ ŠRq1ZÓêÌ¥yá¢Ô·05*­Õeà)€ëw•œ]ˬªMµ˜ §ñ¬RŒ$›ñ+ ø}¼~ùüãÖμ×~›QÈD…9·²´©nÕ.úS}¤„+}¿t&·mGAô’ô–NœGö< Bý§}¬6õ«~%”nlÏÄ`LB(ËŸ6 „¹§>}Hs^S-fQ)³Ë2á帨ØnIq4õdÒ’²/ñú_ãõú—_ÿó׫}³ƒÁA—¬B÷QªmµÂ8ƒ,Ÿôé]ÿÖ5¾ö>ºJQó’+åur¬¿ï×—¯HàûX¿þÒXÆ×Çõ],Î[Õ„uÔFÒðÅkˆê\ŠªkÜ}Ëö_ ™é?ì`¦Æ-ÓÃM€@ãóá�&÷vûÌ•K Ãt•Lbæ†Tõ»{:»¦Pný!œ¨N™´½¢ÑÈ�ꜭ´Š(}Þ2¯ßÄë×Q ãéx®ŒÞâ–»«H:\ñ>µ?¤ÒYHoIŒ%톊՗½ªç-rñc%°=æq{ µ¯¾û‘Bîû–ÛH3¶Ý"‹Ô"àÎ Âà-¥J žË•# {Õl�A_ªK\jÛ€ê:ŠÙ5V…#ëøf:BX²µDƒ‡Vë©nf9ß«gÕ¦XÍ?ødˆÈž´.è$­i7Ën?ô+¡ÀDKQ©z†×Cj™X"xÆ•ï°Gˆ(ü;*ŽFdt§khÿ<À¥]ôù[Ÿ:/¤ó,ìÕ-¥Ï ÜízÓÐþ6_ßÅë×QU~écO¹Kp»U€Ø'Ö¾³ë³½j\U ÐÞe�0B°ÑRÀ±ì’÷"üé#b‘9$^NYç©û«EÔ©²x¨ˆ(Ò%‰õ9ȹˆ)ŠC‚àl6AV§ÅÁµˆäNH*Ú¶3µËWÛ [:óWà·Ò°¨H¡» °íŠÂ’1 MD°|ÔUÀi¹ÕôçÛ¹"ˆÛå£þ:^?^ÿcïÿ$ ‚¥Ÿm ;E6¨°¸µ½Á̪½v(ÚˆÕž$QHÖòO[ó€_£„rÐzhyL,]I¸²Õ0 !b@Á’ða’8‰TÍ€`,RØ=XôŠÓsÑÕÖÄHálâF&˜íÄÙ>áiÊÀ? &ª{TH·Ø®«1–jά²MÚÛNïÿ]ñ·Ý‰ñCøˆ0¥®–'ׇ+ºøþüÔƒãúu>Øëï¾7áõ«Ò¸`÷Ý7ÂþÕ¬ã~G}—}·ÈSí÷“v•axŒ´JÁ?ÊB~¯?¦jUî#­Á¸K¥ÉÝ·{3öä£Ü2W®XαõþˆÇ+E=2öƒÆ˜Ô4l‰4D»¶ŠÒgÆ!Ó ³Eã|9p£_¯ÜÈ¢àz ´ísjå×®ÒrFÁ5×¶¨Õ8êÕ:«ª±öxöú.^¿Š×ë/¼þn\AT÷¤.Ì¢Ú 8ü.&r¥Y.üÆÔ|rHm‚U½å*_‡˜Ê×<àoÇÇ2[—–m#)TŒˆÅ'ÈÚÃòµ gø³V0!šÑ+]l*Låj?'x?ƒZ-ð Y|û€ŸökÒsGx:'ÆÒ •ª©Ù>º+ùm—‡þÜêUpv!þÅfÊGàëÔÓ$)ßeý¾öc¾û¡á$’R© B¾Vr¿ü‘ÂÅ¢y˜–þïnßë7_ÃÕ§Ü™{)&yp§ìëüsÛïG·C»×õ¹—œÈ ñ|a‘Ž«¿¾×¯ÿ,!²"$dÄtÖâZ3%«6ã¶tSÆ¿½]Õçh¯AŸ¿êXXõJÛ¯x-`¨ #aµ§Éö¢:çäÊ€iÃ:]A¦¥Odƾi™¢S„ëO.òÊ•ÐNº>M 1-ÏpÑRÚ;pËÛoEw§+£=¶)”4™ÛgfÓY1K®¥:sôÙ“é…y-jS±J!¼DèêëT>pn¤ùê/ó«¯I@ë Á6ÇuËP®`°Ak~C0ÑR û&LÓ¸ICÁ%¹U±ªu°ª<î^šA%ºÚ­ùkXÞÞIÛœã­Pݧta ”ß#ý$ö¨Ë\“ÜÒM›ð×|þ[—}‘Í]ðÉ߯/^ß *W¡ªxMY©üàå[ ÷7_‡®Þ¿èÍ}ßuåCÊ.A«Rlº>I‘£T:aKµ}•XÜ —´§óî�iquõ/Ž©×÷eu% *ŒtɆİŽO˜ê–~•€Cµ¡8Óyâ(âa)9˜T%ã„Ü]žGͶÒ�w®d]ý&¬Wç~8SDí«˜˜K —kr} $KWÿZ܈ê|Q º*.úî)¼ZÒg¥Ôù*‹�p%#|Ìú>®Zvøõ—^1´«VHeš¢a-œPa ;J¼›‡íCÒ‹&•¥§kz»òE uDólæÅá¹Oˆ×©Fuº¤Üœ÷]…Šé$ŠðFÑ Fr¥öõi³ÍÙƒŽ\­øz…UmñЪΫKШ¡¾ÕýOÒZjÿËm_£Î§ÆZëW²\t¬#úà“×xð)k~¿xýq¼þi¼þv⦶‹éåçΗæÔû¡ù»?-à~o ŒwèŠÌ‡%¶‰±Ý„%E>RÅEèP½>qR-ÝÇJ„0 ³é °Õ£faò›¬³…à@­æ@›(#%Ü6DϤkxyÑþ.7 &7`Ùq¼;áåMÔˆ#~(§4›½…¤RiŸVýá­#åEøÜz…¦¦®T©|j­[E‹+Â& S ¥]½âZ`½¾ÄëŸÅëõ—^¯/Ÿ2+6BÈ9…ò«ÛÈo¾j½ÿ'huUU—þ¢4¿C¥º.‡OmHK—‡•ÿ¥�æ5é¹–¿B7'%àXG·>©Ú'c«4Y"%ð¬LgH4†ý èá+ )òó•ï¹—`›Ì&¯«bQ¥,]Áî¾ô0@»»èƒ~õÐõ‘£TÌ‚t¥-3=ŸÚåjûË›£•@ÆÑzý*^¯/¯×¿ðú/"µÏ®¨"¤Ï´œû‹Ç[½âSu-ŒŒE´igB):H½„§/?Ȧz€;g÷€ÂùíÍì2Áq@ÖbгÒ-˜Víò-l,ò%¹í=Oä³MÑ9Ͱ±©øHpøJUº*ða¶^·:9‚«3eýk5˜+K¯·0µÀÜ­Îeºw%…+œª!@Î]Q©Rÿw»3ñ®¬ñ‰þQ¼þ8>Òé–é̘ß•‰Ýİ/?€ë[´Žª~¾–Ã)PÄ Ï•”ð’y/*½â¨Ù“†Ø #ãÄj$“¤’¼Püð27¢‡D+UÌÒ£„ë ’ŽÅ¬“ÄKÝôs]ù¹E´¸Pf`ò›Þ`g€v!:tµšÕY@¤êå‘lg·@Š^Qšø¤íµRã±ÔsV£—×Sl•‘Õ¾$´‚†p9¨ÒDýúÞ¨}U Ç•|¸s™|-Jyíx¥M,Xu-úº”\Œ‰Ó߸tÝD­Å«xC¤½Rú¢ †ê{§ºQc¥¥ÉF­äòÖ\ã%ØÃ0º¸U=XmQm0«’€M)Øn$eV([U2·k#o‡#)_¼"VÝé¡ùáATÇÓçÌ]h»Ž_dôË…@ŸÎÕ.~ÁË|U+q›¥ê½ðù×3p {­³T-oOš4Õ”q:^ÍaÏO­yeiÆ…î(æ#õ¢…~"Wƒi çX� ¤Œ]Úº‚'²¾úùÎFŒ¡LQõž\ Ö¬ZÈ0rõŪKÏŸ°{µ°' Û¼qE*7©qKÿ–hÞ†:TD‰ªäMù]K_*6K0}o‹fRå ò¡äUó¶¨PùÑ,|îô°&YÈ~©TU,±¿Š IOç)IsŽ(”V¾ÒI¾$‡«6•˜¬O…ù¹$4ÉGÅá@”ÒÄ:±šÖó>–u>ZÅÐáø‹›PWÅ"|Íþ:¯á„ÇZ«å2àh3°YI7‹¬nótËut‰švAØ>ü¤ÅÑ—l}©½>ʳ}ŠO’N;Ul‹ªÒZ¬è—aÞ¨[ÓþëÒ\- TK¥ÒÁ5m\¥°p%±]a§5ÏHzôƒ;åw±;“Y¢Ä' };xR‘mœ,í"Vúò–ÜÇ:-#«tp5ušÑ Z=².–&ô”jÏÙIÌ ó?¾ÔJ\’ß4:›Z#¥ó²6¸E§>_¢öZ[ÖçÎëKÂ[⪦ú¶²]š BÀûJôXš|Õ`ï®±$5Z­‡•$ö%R¨“´úÚõ¿‡ùöì^ô [“­=DÅŸŠ~xç_ÇξûQñúùÖNuob< »B›˜—;·m ޏj#/ëgßÿ¥ûßüwþ½ÿåû'ÿïÿýþ«ÿâÿñ×ÿú_çz®çz®çz®ŸÆõWÿæßùóøÿñ?úÿðøoþÜó8žë¹žë¹žë÷âz"Ös=×s=×s=빞빞빞ë¾ë–ÿÙÏ~ö<”çz®çz®çú)\¯×KE¬OäŠøsúÿ×ÿ þäŸÏ_i?ägÖ7pû_‰?òùßÏâuý×ÙŸüY}Èç_î™}ÈïÛ.iÿäg¿o»„|ˆý ~/¾ùÿoÖ܃ >×s=×s=×ïáõD¬çz®çz®çz"Ös=×s=×s=×±žë¹žë¹žë‰XÏõ\Ïõ\Ïõ\OÄz®çz®çz®çz"Ös=×s=×s=빞빞빞ë‰XÏõ\Ïõ\Ïõ\OÄz®çz®çz®'b=×s=×s=×s=빞빞빞ë‰XÏõ\Ïõ\ÏõD¬çz®çz®çz®'b=×s=×s=×s=빞빞빞ˆõ\Ïõ\Ïõ\ÏõD¬çz®çz®çz"Ös=×s=×s=×OóúƒâÏ_ÿìy:?ñëO"þäy ÏKz®Óë}Ü='ÞOòݼ^*b-ÿù¹žë¹žë¹>×Ï~ö³?ÛCò®˜}ü[íéÿõAŸë¹žë¹žë÷ãz"Ös=×s=½þÌQ¨»n`ö9ðoµ?¦@ü×'b=×s=×s=×Sc=×s=×s=×s=빞빞빞ˆõ\Ïõ\Ïõ\ÏõD¬çz®çz®çz®éõÏ#x®çz®çú©]ûLÒÏ~ö³÷?\ÿ<ýÃó_ QûÛoü¨'b=×s=×sýc•`ŸNÿðÆH©QûÛoü¨Ïõ ‚Ïõ\Ïõ\?¡ëõzýN}Ýø«¿Å·xj¬çz®çz®çRÅÖyÉxWôzj¬çz®çz®çú&áêS2¦P籞빞빞맮n¿žˆõ\Ïõ\Ïõ\÷‡«»êª'b=×s=×s=×ïßõ0/žë¹žë¹~ê×µô©Ò?¼·6zìì·ó¿Å¿È±žë¹žë¹~Š!ªý“ø òêg¿ÿ-øETð¹žë¹žë¹~?®'b=×s=×s=×±žë¹žë¹žë¹žˆõ\Ïõ\Ïõ\OÄz®çz®çz®çú)^?pÿüþÅÿþÿŠ¿ú7ÿÎóPžë¹žë¹žë'rýù?ü‹IÄZþÃs=×s=×s=×O±ÆúÇÿè<Ï⹞빞ë¹~Ê×Ï^¯×¿ö¯ÿ•çA<×s=×s=×OùúoÿÞúÿyÓ�u¥œ¥«����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/filterimg.png�������������������������������������������������������������0000644�0001750�0001750�00000132270�11332353404�016745� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��B��"��� F;¹���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ2úÚB�� �IDATxÚì½y´]Wy'¸ï}£ž¦÷4<Ù²‘m°G d38%ØqÒ¬tªÒ¤b¢8I…N­t…^‰«+¤BBUõŠQwV*áá$T*+Ðp*PÐ`YÂàc lYž$KzšgþãÚGGgØçÛß´÷¹÷û–<Ý{Ï9ûì᛿ß×˲Ì9wÓí?匌ŒŒŒŒºC~ö£Î¹ñ {Çï¶12222êÝtûO=øÙön¼íï¸óÝ/ì9`3bddddÔ!zæ©'v<¼m|ðãÇŽÚŒuŽLŒ4Ü¿÷øá�‡ÜÔÒËW®Š{m;qüXñÓçùò+VöV®\yêÔ©ï˜\µáÊÚ›Ù÷üÌÇŸÚwò¢×n²­`dddÔ9:~ìÈñî¾ê*ø%?òˆsnjz&ÖµõbÌõzÅO×^vӱ羾ùoûÄ'?µ}ÿî™ÙùÒ•'½hæð3ûܺËo*]nddddÔ 1väàÕW_tÉÕW_ýð#L-YëÚz1Ö;WMLM™½ìÏ?ú—o|ýÍW^qù÷ïûÂé¥+Ç'§‹¿éïùÎée‡g6¬Z¶Ò¶‚‘‘‘Q©×ëõÂí^ô¯mcýÒKçÖ=ûä‹Û¶=¸víšË.¾àëßݺ8÷Òõûw|ëªóV<ðÄÞ ¯ºÎöÁ€~ò¶ßvëkî{àÑüíý6FFFc}”8é¿ü_„kAÖØ€Ö^rÍãßúÂÛûýþʱ㻷cþÒëswïx圻ÿÛÛ7Üð#­ãX¿fåOÿèÍ—m˜Ÿ[<xôéöþé'¾²ïÀ‘—ŸëîyÏ?]3»Ì9÷¿ÿþÿûìîÅüÂë¯Øðco¼fÃù«Æúýç÷øÂ×»ïG³Ì9çþï÷þäÜŠ™?øØ¿üÍí í×sÎ9°÷ÀžçW®9¿ö7·ê?²ñ²W¬=“e=ñ콟ޚO…‘‘‘Q9æ*‚h•®ýÀ¿|{ÓÏýÿùȵçü¬öC5ÖÜ:ÿš7=½íÓî¸sîÌ™ýûfVÌÌ­[y|ç#;v¯¿ö¶^¬õMß{çmkç–=¿{ßÎçwÏ­\vÝefGOŸéM8ç^}Ѻ sÎ]wÑÊϽ0>1휻í–+ï¼ãfçÜöÏ=vüªK7Üù£·¬_½láÓæá¾]Ï=¼ɲÙt䨀2ç²:Í`ÙÌÔ¯ÿìK—LþÝ—¾ÖsÙí·Þ8?;s÷~¹1;JFFF‘¤Ò¹çBƒsëå¯}}ëµø—oÿÿø‰Áß¿ûKÿ¤éÚ&k¬^O­»ö‡wÿãßNŒ¹~¿·gû×úkçOž>:sÑM“K–µ}õÊ¥kç–?qògÞûï²^|bjÅҩÇϬº`||Ê9÷Æë.uÎ=ñä3—^|Á½áuußËW¯_¶dê'øçܽÿÜG>þ¹ñÉé׿îÊ÷ýò?ÿ¡›¯ùôÜ}ôìP³3gþì·6;çþvëÛn½vzrâo¾ø­ï?»ççþÉëW¯\úÀÃOþ§¿ùÊ™3™sî_ýä›/}Åüò™©§Noß¹ûÏÿîÁgv-:ç.Û0ÿso{ýÚ¹eßzâÙ‡Ž¾åÆËÿ~Ûc÷~úçÜüÜòwÞ~㕯›{üéÝþ™m;w-–^ðÕÍßõ¶×¯™}éò¢åûS·ßô†×\²|fúèñ“Ïì^üý¿úÂåÖ-]2ùôs»ÿÏ?üÏK–­|ÝÕ—mX¿öUk¦·ï9Õs–#cddEŒq:â_üzõÇýGp;öÚ»?ôÉßùŸß6^ùßù K×6‰±Æ×˜Y±jéÅ7ß±íÈñÓÙØôLÿÄîþy®Û�yÕCGŽ;qrzrâý¿z×ãÏí|ǮǞ|~fznll̹ÞÄøØMW_äœûÐG?ù[¿ò3ëÖÌ]zÁêŽfW\tÞäÄx–eýw_\6·vÙìÚï>ô¹Ý‹ç¯½öUë?óàö*ÏÇ\ó½gv]å%ï¼í†CGŽ÷©çç–/yÓu¯Úúµ‡¾½c¿ëõÖÌ-ûâƒßÚ½wñµW\rýÕ—ýòO¼é½[>¶bÅò÷¼ó-Ë–L}ë±ï>pðÍ7]ëœ;¼ÿÅÅŸ=ÿ‚‹~ãgo_µbæ‹_}xÏÞ}oÿá7üÚ?ôkÿ×ÇŽŸ>ûì%S¿ò?½eé’©‡¾ûä±Ã‡Þ|ÃÙ¬›k/]Ç®zêÙÝûÌ—ÎL½öªKï}îøºYçÜêÙå®_·fý%+—/uÎ]úŠu=ùÈÒås&ÈŒŒŒ"Yc}ÔU½Úk¯¸þMM’Ïí¿þƒO½ÿÝ?æœ+ɰâ ÃR<ŠtæÈÞ3™;žM¾rí²ÉÉɉÓÐ×>y:ûƒ¿þÒOßqÃM¯yõM¯qιöìßò—ÿý¹¸^ﵯ¾péôäâCß|tû×}ên¸bÓ-×-|êÁå3ÓιcÇO>r|ÝÚ‹ûýñ±‰±ÅÃÇÎ_ëV®XzìÈÁêƒîù“¿¾ÿßùð¿ï…ç­ùÌøãÿòé÷þÂOÞ~ëõ¯˜_±õ¡'—­\óÛòÙ§·?´lÙòxð;ùÝW­Ÿ_åŽí¹î†+–-™zqßþ_ýON/[ºôú«_50ò^{ù…«VÌ<¹ó…-òW“K–m¸àü®~ÕµV>øÄ¾þøÄà¡×]váÒ%S{¼çýÿqlbêïýÙ×]ùÊÁWS郇?³kï ‹G>ú™û=r¢ÿÔã;ž¿lÃyùÿ›snç[2=uòø·|±“ŒŒŒŒÈr¬ïú=ÄU½^¿þÚ¦»åŸ7_û¯ÿèÓïÿ?zŽ »ñÖšçÖŠ1Oá×çž8µ÷{'—̯˜<râĉãÇ»/|ñ‚åk_yÙo<ñÜçÿÍž¿rêêË6ü?òë×­¾ã¦Kþè“ÛÆ'—¼áÚKœs÷ý‘^ìkß}æn¸â7^÷ÇûüÁ£ÇsÓS“K—.éõûcc®×›[¾Ô9·ÿàá3§O»¬ü”í;ž]¹æüc§2çÜãOî\²|öTÂ9711~âøÑ±ñÞÏüØÆë_ýãK—Lå—LŽõ–N;çv>·ÛõÆVÑ ûÏzW­œqÎ]|áºè·òÏ[3{ðkO¬XsÞÀ¸rùŒsîégw¹~õú‹ŸÛ{äu/ÿò[Ûw~í‘ï_åÅ×\~±sn×Þÿþ#Ÿ~~ßÑßYøìUçͬŸŸ{nמ7Üpõo¸fñÀÁìÌ™3.³Ú;##£8Ögl¬énÇ`㵿ý wäÿõ}àÿøãÏÔ>·ÁkŸÇî;¸}ë‘Ó㯼á­GìÙûíûúî´snñ±/N-ûÔÌrÿ«NŒ]óÊó¿îNï;|èK?»zíw~êG߸léô¾]Ï\tÙ•×]vsîŽ7o¼ãÍ¿_:3ýºË/øÎ÷Ÿ=qòÔäÄø¿õ÷ýãÓý©þk.]Þêåι¯~ë±±±š„ˆÓ§OOM &åÔéÓSÓý—ÓO²ìÌ_sÉ­¯}Õ³»ö~àC=|äèïýÆ»ûý~¯×Û»ÿsî‚óÖNNO»^Ãykòî;pÔ9·ãÙ~ÿÞÿš¸wñàéS'³ìLlÜ9wàð1çÜÚU³ãS=×_·úlýÜÉSgîùËÏŸØÿÂú5+ÿÙþào¸zã«Ïÿäýß›úêã/œzø©e3“¿tç;œs_ø‰ÞØ„ë5.‘‘‘‘°C9ûõNŦ»ãT¬»ößþüí¹6§ýö/ÜñoþÓg«Ïmcu>sêäáïÝïz½õ¯½mbjfbíÌéËo=ú½/OMMNLLÚ¾uêÚ·úßrbüù§·>vóÎ]‹Yæ.»psî›nÏΜ¾éÕ¯ë9zìy)iþâ Ö]pÞš~ãõ÷üÅßÿÕßí§ï¸yóOÜ~ëÍ/œvýK/\ãœûÜ—¾úèö«×_RFêõ ‰çHìÁ OŸ>=91ùæ·ÞÔï¿4æo<¶ãàáckW­ü½_»ëè)wå%ëòK¾þØÓ{÷Ú°~ݽåõÏì94·béu—oøã}þГ/¸ì¥>ôýç=~Áyk~ùŸÿ؉ÞÔë.¿0¿üšW­û­¯yô{;;qáùëœsû:°ï…ßý_7/<røèñ¯Ü°tÉÔ—üöw¶ïX½þ’>j'‘ÅØ9©¿õs·5ýò7ÿäsç^U_û°Æj®ÍŸ;ð%þæŸ|nðÉ¿ýùÛ«Ïmc5>ºók–OîZñº/WA­zÅå»ìݰüäÄÄD–eO?õÍ•—\ï™ 'Ï|ê+_zþŠ ç¯›šœØ³xà¾òùÉÏO¯Xý†×\âœûä?lýãÿò™FÖµ—_ôïÞ»yãuWŒÿÙ§þþ«O<ýôη½ù†K/Z?6Ößñì®OáÿÝ—–,[91µÄ5¥Côjÿt_ùæ÷^}áÜMW¿ò_m~ǧ¾ôÍcÇONOM8çŽ?ñÁþ·ŸýnzÕ†ó¿úÐã÷}ù·¿éu§ÏœqÎ;qêw>ûãozõ×^öÓÓû~tûÓO<ñDobÅØøÄ`ºŽ?õÁÿüß~掛n{Ó oúËßxìÖë¯<qñàÑ~Ͻõ–«g¦'9ö™/~õ¿~îÿ›\6·kß›®xÅÒ%Ó{~ô“ŸÿÈÇþnzfÅÄÔ’þØxÏœŠFFF1äMðá>õ-›ŠF\õÚÕø ïµ¹ <å7ÿô¾ßºë­õÏ-ÝxÐoìû;w•¾8òÂMïÿ掃ë¯ùÁâò3gNíÜvÃNŸ>½ÿÀÇö/]:±çÍÏœ9ýÂS>yòÔ©ãÙ™¬?6¶dÙì²Uk''¦_Øñ؉cG–®\½|Õü  õñ£‡_xºçzë^yUϹCû_<~øÀÉãÇ3—O.Y1·tŪ±ñÉÉ©é§yð̙ӳk×/_}þÓßùšsní+._ºbvçw¿yêäñÙù W¬>oÏ3ß;|`ïÌŠU«ÎÛpúÔÉ=Ï=yâØ‘~lfÅÜáÅ=YvfÍ…¯Z½zþÙß?z`ï©S'ï¹û—®»â’ýÅ'?ýåo¯:oÃøÄäâ®G<yìÈ™3gÆÆÆÇ§¦W®Y¿déòSqà±ÜóÜSGî;uêäÔôL¯×;väÐà‰§N{ñ¹'OŸ<‘9ÓïMÍ,[±fýäÔ’ÝÏl?~ôPvúÌØøØôÒÙåskÇ&&'§–Øi222Ò§ý/>õÕ瀿?tÿß7ýøš×ÿðK"íáGW®9OâÚügµ®Í¿Ý·kçÙ~c%©xâàž‹fwÇÞuW½ÙõϱàzccgÖ^säÄâ—^rðàÁìû;¾wxÿTs r¿?>;á™3§z®×ë ¬¤ñ‰©ñÉékÎï÷ÇúcããSSÓιɩ™~lrzƹlzfÅØøÄñ™½^¿?ÖØW““Óc“Sι•óNN/éõú®×›¿pzéŠÁ[¬œ¿`|l¢76æœ[¾ê¼%+æÆ'¦œëMÏ,Ÿ]s빚^ºb|bÒ¹ÞOßqcÏÝðäÓÏ_zÑy×]qñ¡#Gÿá+_Ÿ˜q®×ë­\{Áä’ýYÏõ{c½^/sÙØàæg­ã±ÙµLÎ,›èõûY–-?}jl|Â97¹dÙÜÚ úýñÞ˃ŸŸœ\¹úü3gNn2199>i2ÌÈÈ(–1V¶o®}Ã[!WÕ¦i°_[úÐ_þ|·^ÜñØ‘}ÓnŸ˜ªÞwz銇öÙùâCÇŽ;yòÄÁ“G¦—ßÐ<d7³¼^È­Xµ®ôÉÄÔôìÚõù?'§g&+˜üš›¿ ÿ{Õyg‹ØV®>+¨Ç'&‹—,›[S½Ï³/xËk/¾ùª‹Ž?ñàCOüá_üÍâÁÃk.<¿×ï÷z½±ñ‰e³küK215½rjºö«å•tÎ-­ë—cdddKŽaZ”4;5®-}6p*>õÜÞ‘]Ä];;|`ñÌéSý~|jÉŠUóSK¦—Íö-Xedd4ìtâØ‘£‡ö—ü{~zøáG—,[99=ëÚü“=Ï=yÖ©8Êù+VŸ?½te||�ÓŸ^²¬ß·¼A##£á§Aû®‡~~É’e+Wź¶DíåÏCOK–Ï.Y>k»ÙÈÈhD%Ù̲©™eݺ¶FŒ ¬±#öÙŠ%N3+æ*Ö˜sGì»÷}ï²Ù12222JœÞõ¾{sIf ####£.Ñ–-[Šÿ¯þbqqѦÉÈÈÈÈ(AZXX(}bÖ˜‘‘‘‘Q‡ÉĘ‘‘‘‘‘‰1######cFFFFFF&ÆŒŒŒŒŒLŒ™32222221fdddddTCã¡ÌÍÍÕ~¾oß¾ÁWûö±3VŸUºyþÄâ£)è^[ã«Ñß=.5 wÔn¶èóPUèxØ |£ =šqÓJ°ôߨOâÒs½,îB…¹­}ÿ¹,£Ç]¦ÉJ Ï’O,Ö™”èò onnnnnnß¾}¼®ÕZRaÕOgTчD™œD6|í|ò.}¾™Õ+qfAŒµŠSQ#¦ÉfÊ·zs î_ë±öšL.»ÐóÖÕ—->±øyéoÍ¥©:^%ºõ½ ³!mùg›e-J3Œ~4û’'§i·(°u>…äJ‘eÕ¾g=v„MÅu2A\k@ê‹îƒê”±3Ê&Cz‹K¼Z¨W;’¢UTú[ü%…€×y/ÿlPXOíƒf[瘄>ZbKø'§ö‰þRfÌÃüL£ié‰ÜÜÿv¸Mqã™'nqljˠæi­>®é�Dñ¢T= , cí<§ãhÕéX†ªæÓGK2e]*qïS¨¦z¹6USœ²ôì“ß*Y›|ž%½­i4¥r‹+ã’1ʼ ÖY'ôjˆwGœ=…¥I$DeŸø_¼uªQÅ[“6Ú›J/=×1DÌ›_Ü*cל#± ÆS>‰Øi¾Z“§{È–&5S¬8žV3²FÃ*û«.ФìéÚ8ãÒmé\¢ ¶Pþ.µâÊ#n¹„q r¡¯pì…´09=xðНVо¤Æ|•—fXe˜ÜÄRÖ¢LyY«ÃKÓíÊ|ú'¹É™ýd5Í*nªÇ…öA•ųˆ«\H”’Ðüj`²¯Æ5’Ò¨b-Že\û jëRjÏ�ükÄ8æÚ[yn®¼ý“S{ã4ÈÓä˜W'Ð?{±æò\œ лñ¶w¾ãÎw?½kÿ‘ûî}ß»œu6222³»kØõÙƒïA÷ç¯/®šY1·{çöo30*##£8lkh’>R�£L&ÆŒŒŒ"N¾œ²£@ã¶ŒŒŒ"J2#›C⋘5fddddÔa21fdddddbÌÈÈÈÈÈÈĘ‘‘‘‘‘‘‰1#####cFFFFFF&ÆŒŒŒŒŒŒä¨¦nl�õadddddÔ=klË–-6)FFFFFc&ÃŒŒŒŒŒºEe§âæÍ›mRŒŒŒŒŒ’¥ÙÙÙw½ïÞzkÌÈÈÈÈȨÛÖ˜#Y²Œ‘QçÈ<R&ƌΡ_ù•_±I02êYß`cFv*ŒŒ:I ¦wv‘,6fdddddÖ˜‘‘‘ÑðZi6 ‰Pmä²]Œ šdWiß¾}Ö?› Sš¯H¾ù?«Kæÿ°ö‰¥Ï›ÍWïVüŠ2ÞIƒ<òŽA“ï9ù'µ¿÷Ì­çèù_ÁN%;™³1ªÑ@­1;:Ô:ÏUù‘ÿ=77Wb£ƒF2¸Ð3žÐ1ˆêMO¡«_ÅkCï㑬¥¯j•†&É=¸¼uYÐÔëõl"2FOärœÈ)jÕ[“y~õßc7ø­œü“PPûãZ¥^κ§fjM–œï\®Õ¹ÅméÁ­J7±ad$G<)ùY­åŒFµó㟴Úosnˆc‹ö ´ùòWy4£ÁDßNMsÒô”¦ß—>×ßÒAs[47‹ã42A‚Zcæs5DüŽ&®9‡8ôJž+v×Ú:)Z9pAHmëü‡m\~‹ª$³ƒfdbŒÄˆÍãœd™Å z§Ðç¿ÖàóÈ*ÿ­û$7îM’™·9F\†!ÜSúLJNj†Þ¹I<øïÃ;~Êü‹juÅ×´´£§¾Ä³CEŸ4^;ŒwQ4õ• ‘{~zâü££˜¦ űƊj²Eÿü”b<M“™ÒÚßÀ?dYÊÐÇA"CžË_5ÍUÑxB†j’!d¢ÄÆJSd‡ÎÈÄX˜zX«iÚ)‚O£GUoRH þaë Ï>Ž^!�yä5=ƒÚÒþÀg uMƒÔÈhÔÈ0ŒŒŒŒ†Ú32’£ÚxUúvF²i–621fd¤JóŒ%>`ó4™3â'ƒÇ622221Öa2ll####c]¥-[¶Ø$uˆj;Z™3SÌÈȨTÛÑÊÈĘ ##£ÔÉÓÑÊ(e²º1#####cFFFFFF1(¸ß˜óöVwXˆñ¡ï™ÔÔ¼¸v†¶¹¶¿ytЇ®Òa¹[ƒ7222k¬†¿�»ñ7hM3\dàü·^‚hB=4ƒ729Ê�ŸŒˆ5VR½K(àMztN2š­ÿªÆMÓܺ¶>Ñ­FèØZ/IyðFF#M=ç2çzÖak¬•‘ÕêÂpõÝœ©s”B‡ÃR'­¦6ÇÕq&8x####†„{JÏ$[€Zã&t~‚¬Ø¢Ü*Žªvv⃯¶Ý222ª1Ȇ×s ucÆb‚lDŒGÎ[Ûø*µÁ{ÌG###³ÆDX¡‘´®Ð-†ÞéÁuÆ ^jU³0œ7Ùº‰UUÖôá(dp#¦:ÿÕìöb– ófR�§·ÕäJdðæQ42’£­nãˆ1לÛô¹'䟦õVœ–ê$øç¾dA+2"ƒ722j’a·¸m*Ô©XË Z5hÿUÀχ؃ÿ�89M‰ï¡†&©ÁC(bWd˜30*###£a¥,sYvÎ?k­®Ò#f1f¾###£QnuÕš_mÌb̨ŒŒŒŒÒ¡^¯Þ ªN¸­ß˜8-,,Ø$•)S€8±\”ÕÈ´[$$§‰±!#kÄgdd‡ãgÎõz=ç²lð5O¬ÍHÌæ]oW²²ÙĘ.mÙ²Å&ÁC›7o¶I02b¤XzÙU¸Íó›—­±šß eX$21f¦XLZ\\´I02b§pÊ^¶ÉzçšI¹èò‡•¾J¹ŒÌĘqê8´°°`2ÞÈHH€-6Ï_å¿H¾XducFFFF]¥­n£'Õ°×;›ˆØ+ÄÅJ’‰]Lš3222iÉüv`å‘°Ò…Ù¼sÎÝ’mC<%e¡,ƪЫ0VÃiM–æ d³ad” DŽGräR§Õ ˜Ó»^T½—ÿ7«¿O“H*h`£®Ë0Wé¸mdd”•2së*÷z¤W5XuŽø)&Ø÷êïÓtó®À*¶ˆ1O—‚_ü°ú·ÙFFFFÊcWƒÿZ†BAFXÊ–ÒC(øfA.3jY5Î2€ ç—)[fH1f؉FFFF¢ÖX­ *ýÓSõ•ÿoõn¹ Ã^©YfÐîÏÕâ܃æQ4222‚Ȇڨ˜/ V±´^*‚ÎÊwóCx´^]­+‰Ÿ’‡0ÔŒ3cÎÈÈÈ$V­l€¤uø%Jí‡7g]íÃÂ#ÆZ»<{„ŸÙdFFFFM«öÛ Ö_Q„°«”|øØX.ª)ù'Õ¶ô¹�3kLl挗g*VU….#±Š8‡M?K0׊©Xå}UÕjÀ+ÉŒŒŒR&®|+¢Gì :gæÿ[®fƒfó®·k[WæÍÊŸŒŒŒ"ÄS×䊬E¢*ʰ³b²Wó ›çkRHªµö)&ÆŒŒŒŒŒÎ[MR­IDÕ&ú%M5ùØZŒ‚&lbÌÈÈÈhøM±¢„(uù£bÙ|ÙN*YW£@ÖoLœlŒŒŒü¦XUVA  Þ.çν¼ ÏÌ ©­•É™N²æFFFU ì€$k¾¶& å‘…ÕkkoRë½L ØÄ˜,mÙ²Å&ÁC›7o6CÙh4-°’\i’7US)4ó~«Ûè °y—2øLŒ™)fÔH‹‹‹¶@¶@Fµ¥(É<"ªÕ’»ÅmËL·ô†&ÆŒ¤K ‰ˆ[ Ähˆ©Uü´þ²jÕÝ<¨Y²d™ŠFCBÖÊΨ‹&\Úy*·j„@áâ?=0"µ&RFfbÌhHd˜µ²3Js­< µrISÍà¨Þ XCæËþ‡0ˆÒ'ûöí+¡ó•ºB—~l{2ÃʼnªTz¥zaÓœû—¦éZø³Z‡­@:Ï%.Yíañ¯šçžžWn:˜v*WÀœ‹â/ý~¿lÞõvÕ—£ëÒjïVºóàVÀ1§ky¬Ôž%ëÆä†U-¡µMvíàþ´Ú¥ñô"�>+nwï\µJsÉj'²Ðž[µ¾¯§³’¬éP–¹,s7gÛ´ºþJb)ÿªèôÃsÓFŠw¨ <¿•VkÞ½üV Çc@µtX1Ô‹qÆ�L­¤oÿþç¶^åWꃖ,hØÑÕvy Mÿä·.™çY­KVí/a:e²Ôë½ôß½zû¦ Ì1yEyS”4AFRÊ~Þöì阵‹I[cAîŽ! ¶W_3–çŠW¹¶ lòE•‰ÎRíäk6бf=‰S­ 1wôö¿¶�� �IDATèmuÒk ÀŠ˜¿pjMÊx`×Ù¦5EÖ=ç²—ÿóIæ—9ן·qø€pðR´ TÍO–o1ð\Å’a¸çÖvÌ)5ŠƒW F@\.©æ]„ÌRëäû¯ZZðÀ×ÑH“Š-ÁŠÂé¥àÓ®üÛš®j7øÜKr¥Õ~ 0°²âÝ$YOcƒccµ§Â6búvŽ!¦9låµHÊ»€–aF ÒKA¬ÞÙÿj%Jí·Å«ªÿ=ÐÛxÎmÃÿÛÚÛ¸µ·qðÇ9_U¯YPe›,1ÖêN)y-ŒRMKSâÑèåVo•'¹‰>ùDÉÚ´d\kj$MÓ§è,ʳ¦|Ò!®Ú.0MUb¥ Æs™¹³‚-곜ó¡?*y >÷YEñ\! I )òèR˜§‹k”š%‡S,ÐKVûÓ/;g¢ùEÝ@˜Õæ V/o–TÆÊ50é›»{]ÈT,$DF@'ôñ’¯FÁoãñeá&YçªX.¸R {¬Ò4€Úh–¡<˜CCyâFÎñýà~TGÓo’j=<�­ÖF³‡É³äŸ®›{îƒg]\HzâYÑ×]s�þy†O#äCÏ{ÝßDWšTM8D·k©þ ·ë¬]•ÝåøÓ·¸m7Ïos»Ê‚×_çŸûÀ…{ §l¡ x*íJRª÷§/}ÒTË |n©\ÚW­E&ÆŒŒŒŒ"ð!k: ƒ ú6z´‰1###£$$ãݲywóü6Ê=sXý#5²~câd-†mŒŒàÂ#Hö4ýþ]õŸ—’é!·VD´ÉLŒ‰“õ´22BÛdþ6ÍULú*°}õ÷­­ŸƒÒ=\l¿¢‰1YÚ²e‹M‚‡6oÞl d dÔjÜÀM¢Öža¥f©™V&ÆLÓï-..ÚÙy¤PØ´þ¬UzoUì=–ˆÀ31fŒ -,,$"Bl_ Q#¿»/È>s~H”EØÛåJøÑ…™e*%a„•FM»¯ð[•>dá—Ð=ò¯ZÅdm—¼Z V*£‰1###£$Œ°’* ³&‹§Š8åIÐH Rü ^û\½óàé@w¥µ;k1ýèÈlˆ;¤W‰fkçm·]Z¯*psSÇaàU­·Jô¨:-0Ìꇭ#²2ª5tj…AQ˜ÕÃïòÝ­øÏZï_é«ÒŠßÖ^ÞšQ’5VÄÌfA}µ®êD^ ÄA/òÇÖåk½ ~«\—Ú©kÚ祩Τ-Ð(Xcµ&QQ˜A�«²ÐŸ²ïϼ/^ž`tŸ~€›šU¿júq-,zjí =º°Ž)V‚Õ¯åµ#iÕ†õ\yü3\ê m d$ÒŠ–@k%JP)˜G6ÙvÒé.‰±bg–P]ÕÿmúJeÊ/jÅëP“U:d“…¶³¡/«ÑQµËeI<T‘›~ï°­X ¨‰Žj4?BEÞ¤TŽYíŸ{…tBñd‰âL±Ö ̹^msEO+ÚtÔ +2}…7ªáÒÁMõP.\ Œ¡ª÷¯øyõ’›ç·åZüO"TÅ•U Ö¥•;"Ð ÝS­I¼±-Š\qæŽ3:ÙVÌlº˜|Q’…yø­ÉÈË#sÅoãÌúŒ£ÉVƒ3ý’S1Y¦æö¬F=?ÃÝܘ…ζ±2‚S“,ñ‡Çšnå\ˆùSòØ�•±øUõÑ ‘NŠ1ÿ!Æ :ÁŒªÊ¾ÜÈ«¦ph¡BíØŒ9J '¢ÏÙȨê3,Ù@pùáÉH¬õX6‰¨ÚÖO:&Æšú»7 ³Úo«a;ÏAÖpÓdÂw+›vÿ´à&ÐȨV¨´ ˜’=W4È‚Z<û½‘æ8ðy>lý‡uRmµÎ’£#aYÄ4×±{Õ4Ä3ÒÑ2j¢"/\ÂA ñ›* ýX >ÑßF™ø­13›ŒŒŒŒˆ”#ðzL¥ª]•§Yr­uÍÕ¢±À;¤Ä˜¹2ŒŒŒŒXÈ_ÈœÍ;xUUæyÄaéB ï18þLE“aFFFF æZ«tñ瀴P¹„;>Éú‰Ó‚M‚-‘š ‰µØ¾Ýjâlb,]²Þƒ¶@FFõ”e_ÝÂô#±gblØhË–-6 Ú¼y³--Ј™ãW­´ê'Ù¼{`WMӳƌLÓç¡ÅÅE[ [ £P‰/Øz`W9T6|žFcÆâÐÂÂB""Ä(ñ2r禉" þpPßö‡‘‘‘QúÖX“—RÚñabÌÈÈÈ(]é•K t?Ì¡ÏWlw*ZE3dNbÍRµ³ð€jû Ô~Uë­l<#©¢ÛxVmèȈ×~¾¬ ³ÆFKš–ØePmøUé÷ãN|j;öÙ©Š±ü´äøÙÕΖs*}èÎm<QûË®P‰SDÑôC{iŽÀJÊ T¤7³ÉÈccÿ9ʦX°568™9R[M‡Ž2ÊDœ®Ö¡£ÓF›­šQ•ü`‰#.ºðbŒ¢ïßÅ5±Òô=šAw­ÞîÊuˆ)V=8æ 42Š,ÆB9f×ykÉgE¶ª£)É\òþ^### óž^W—5”öYée•9WizM‹OVÅ1ÁfdÔ%1t°kåAe˜{9ò§ÆªjSÝ‚$™EbôÈ…”ØÁ©Ï~z‹ ½úGõ—v\Ù'ßáüó ¿Ê–LmÕlŒŒ˜­±Ú�CÐßµ'ªÓǬ‰ÝÄ |žéWuw¥lŒŒÌ £Ì‘322221f¾#####9ÒHñ0ÑeddddÔa16â´°°`“` ddddb¬«d½mŒŒŒLŒu•¶lÙb“à¡Í›7ÛÙ™3M¿«´¸¸h d dddbÌA÷haa!b ”øùÉÚf™322222ŠAíNÅ*‡>”;×kñDº^ÖæŸ¢â+翘æK©méôÌvGÎÈ(]kl_ÔÎ9;ŠÕ¾s©ë‹×:Eþ~Ü­Fgñà cÖ:Û]8#£D­1Ï!¬íR„´Ï?/ý Ñ"¥eSw4Ïð /¥IC̹J¯VÝrþÏÍL122k,Xe®êƒ¦_�éh‘µ]  Ã󿔣)Výg±ïkëµffŠ‘‘YcõÌ¥µ…D‡\:¶ü]4Ñj?7)eddb,˜ƒT›ØÒUo##ÞaÌÈÈÄX˜qÊ5ôM"3źe(3}l¡Œ†ž’¨Sk­9"2lÔZ•¶¾lW&ÄzÌűÆ‘‰b¼rK¿Ô¯Eó$âð þj]|ß|̵±±”ߨulýp%›Û‹1T¬ú ü[ȶàÝ:žÐO'Õ%t9‚>Lê](›­<±» 7 d}é†Ù32ŠBæ4Ò$J61fdÄoИ?ÍH6oÞlmLŒII2›##cF²d.u[ ###c&s©Û™ë$™KÝÈÈÈHš¬m¦‘‘‘‘ÑYc³³³6)FFFFF]c[¶l±I12222J›V5Š±Í›7Ûô%K³³³ïzß½bÌÅó+‚í)x5ÓI‡×4àXyíÍ,ýéêʲ¦?ÎΔ‡à¨ªiYãÀßIÓÂÂBnÆMKg$]žÀú¶þììl>K)OWW–5ýqv<ìGURN–©hddddÔa21fdddddbÌÈÈÈÈÈÈĘ‘‘‘‘‘QáÁ¨j{(»@Ç‹}¨óñhŽ-©>XêcR;oÖTlˆ7gG—Øö$eN$fo|ˆ2ÖðÒ™–!8oÆ,ŒlOñ‹±\ÁŸ››k2жûª×Þ¼:Œ’Y–XHHx¬ÀâP›lDv‘Ó´LÕi)Ž¡øyéo…•­NlÓ°E7•gùšÖ´uÞtöÐbI/%ËäÖr"Zw æ€=§£öoý“ÛÄkÊ8Q˜ØXþ¼¦çêÎ)ã4o^»á–^Q‰yÀ-SQ¶ÕŽmÀ‘‹Ü¹vžåÞ(W5joîÿ–8]ù{AvZм©íøbI/%ïäÎŽÿDø‹ÀQN=næ…/ä¡,5l)š‚ªvÁ‚®ŠâýÛW Î­ ô˜»â†-1ˆêú6}kMé#‘{ÈC-7óA ᙥÀ~YF2.}Òºxó!j­e6Ä“Ÿ¸&Dáb‰ÛºR]YJi©0ô{;hÛtŽŽw”¤£f¶îŒ4Ùb“'}ý(èF¹›Ëî…,±e+ŒÔ„@¶M§´¯ÀDýÚµÆu‚¬ª8ÔR¥£ù„B+q\G܉þ¡"ÖEô*Ü?ÆÅ´je ù‹D±Ã {€ebû¢³,1qµ7/®këÂK¼lím#òAÓ·ÉÞ(®\Ÿ{™ZwZ¬AÂGå_béAÌ^ܹE0–4x:ûòP–ó>N_éïÚÕ¬Ôê0j‰Âx ó 3Wþ§à¾Um”ÝåßTþ•ç 7Tÿ°#Ž3Ö Ïâ:8±Ž¶>O}`Fedddä³Îm'cFFFF>##͸€QNã6FFFF~If”òÄš5fddddÔa21fddddÔaªw*.,,DSܧ§9’.¯J³³³6]6Na‡òdön¼íï¸óÝOïÚäÀ¾ëg÷nÞ¼Ùd»‘‘‘‘QÊ ñ»ÞwïÌŠ¹Ý;·ïxx›9ŒŒŒŒ:L㵂Žëî‹‹‹NÀ•$tÛ!päu \]œöNï™®ÞÞ¨ÓoÔ"Æj‡ ………ÜEÉrCÑÛñÀ‚FÞ9¯òììl>ÛÝšöNï™®ÞÞhÞ('s*u˜LŒ™32222221fdddddDÃŒ©ˆ@ó,¡Y»4± €ÕÞ =ÎÖK::òj[¬nM;ïäÛÌS6|§ß¨vðÃ÷Fô#cÖXÍ$æÔéwéhƒ‰â*¸Äºî¢õ!›ù(¾ëoTüð½Ë‘Zk,ŸOë[Ïïó¯ÞGÔRDè_þFºj6.ïÈ• t®ÁW·PçßÑ™oÝðì/å Á騽„xdR±ÆØ­‡R×àV-¦µg4¯ óè#Aú—2?Ò9û«uwÚu/×[«Ó3÷š–ÃÖh$¬±” ½ÀÒ[9‘K¼šÎày­vÍÁ¿pO®‰»ás&˸.joT»Ý=µËAßiÁbL(À˜”ªe]Õíè6’aFtÍ+˜ítp-Ë¢ôƒàÍ€(ު뉱6Ä0<ýSêŸö¹—©ª¥ÙžåÁ³¼Q×O‡Ð‘‰LE®}ý>Õ¢òÁîîÈu_Uò¸8ŽÍ|R’Lᔓc­Ë‘IEŒIØaùlC‘u¦x®ù³­Šß¶Ž\ó`«|®@|Gg^.Å#ÖÌwú<WuôtÈ-ǧxgªuÖ<?fu7= ˜e žDL[zä¢ù:ÓÞÝ=#¤JFÜð~£á;BGÆÊŸŒŒŒŒ:L&ÆŒŒŒŒŒLŒ™32222221fdddd4*TŸ©¸°°ÀûöŠÞvˆÖJ³³³ÝÝÍÝv¼½‘½šz7ÞöÎwÜùî§wí?r`ßõ³{7oÞl²ÝÈÈÈÈ(emû]ï»wfÅÜîÛw<¼m|˜”q####£Q£²Û²e‹MŠ‘‘‘‘QÚ´ªQŒ½ç=ï±é1êmuoqÛšþ©öôê0œsƒO²y×Ûå3佨'ª4Ô|´ì÷§\UœÆ¸ûJáB£Pʲì]ï»7ÿ§e*¥"“B/È0Äm=w(þ}‹ÛV{ó[ܶü« Ë$š‡–þ×Ã|0M/âV6\M ìLã@zwú¢³ˆ¢­ncuôÝhTO7ÞöÎ÷ÿÙÿÅßûÄ¿ù‘~ðƒ6!FÃ$ÑŒ£Ä†¸â>­—ÀïYË[¥ß"ÒâêCÄaDÜ£lÝù›ùÅßûÄ¿çƒ7ÞöN³ÆŒ†r…¢Y{Œ*„†^” Õ;iú@ÇÄK™›_ÀøYjõ&žß7=肊^œõÃâºD¬iÓ–³“‹#cF#m®µ²­²¤"kn’¥»ÕÞ$¿ƒÿч[é5=l´:'­?«C U¼ÎÜs©çƒËÿ.ݼÕpÌ7Úrª҈̩h¤,6y´HWX­ë²É&r •Œ?¢7Ua™ˆ³QzADToh6ö(“9"ú a"MF)7’j]—ÕÛz2)Т´Éà«R6`ƒK} /šŒÅ¼„ÞP4áfMq�­–7Ñ”G2MRÈĘQº¦„ =ÝÏžòoE“âZóÑKü´é÷½]íb#— µ¿,:K›LϦ©¨¦kÖþ¯çe›4ˆÔÌ€^Ž �§gcø_‘/jt–Ì©h”¬wí€j êømJ†41»º³¼Ht->—¡R-–ÆœU W6ô[åtÍ¡'s*‰ˆ®VÓ!èØ¸$ÄqLú*åéÕÞ®õWó>J¿¤À9ÔÀb��BÙ·º¼¶º%Ë?Hø<%R¶n¿¦çÞ<¿­úÊMîYÏ8›îd>ZºLŒá‰+Ù¬úƒV.é—XÕ?BcµG¶éìC›ÜGEG"Mß…äB$V‘MW%kIQðJ—Ô‹ÖùošüÒo‚ò-k‡ 'ùîª}åPŠêfÄIæT4Ò±Øè~ k`Ii«•X –.ãäsy)‰É)ôͪ\Z©#™SÑH# l²jù£û}„®E…£è˜YP._ëMàÞTˆ/´Õj ]©w ˆ9‰ÞŸþ›ç[íè–åñ’‰1#¤Ü"†—r‚'’9œ8‘^ð(Žçn7ÏoŠÏ’+ Δýñ¢œ´â+pÕ~wDˆz–ÄAÂ]Ù~7&KZ¿‘‰1#~ÑE‰´Æ?€<½*ršäV•!B’æCÕðüZ¸0.I¸PK"t«¼UçÈg^@M)¼ó˜tp­¢U¯ªm>j× ûÖw¯nø €4#cFÁzýnrUyºßW*€-f†üÚ=üZ?›Ã¹"áfSÎ@›ŠÀ€b²–›‡:ô<P^%Yê„È’ÚäÃÐŽ“:ž oÈ÷&ÆŒ˜O BTsÂú5A0”ÖÛUƒì  ùŠ»] ëyD•RP'<zF¨íˆž4tð¢%„*p¥P.¢i@­­ÌÕ|ÀĘ‘‰ºòÉ”;ZÀÐZ%ÀÇÿeÞŒˆe´´ª¿¬õ"r5.DÚš0ºš¦=hlM{¬øÐÖbƒÒßì*»JaQÜØàÍŒjÈî„L+â/…F( Ñ‹~w\^-šz*Ð2^ûœÆe* ED™Z Øèœýf ÷Ã'9p¦ãdñ‰râs=n(`¯Ö¶ kÀSÇ[«M!7àH-òd®ª’€ˆ[X5ΊÆ(R97¿÷µÕ´5y–™ë*!µ&qÅÃ,¼ 5¹£È qo];ÛANUî O.:¾J®Â\�_’n^u¬ù¹¼©uBÖ¦øSWjÑýq¥lt]b©[Í5•Ì©8ÄVš²˜iåYQâØì–hÉñÄ–BŒô;·Ú:\¡2ôåþmƒØTÝͧ0Q÷Ò4§âèXi”’Û¡±„*,š¸x8åH{rIpH%»ª)U½Ô ­øYuTzziº:cm6:#Íp=N<¿AYý¶U"–oCÞ¥éÔ %(Φ21ff™+ñÜ*¶BÐJÙÃ9—©õGQš°à€w›d� ø“¨)Ðä®v+ŠO 𖵺¬Ù‘>à9„ðßê,Äó¹�ÇMY3U²ÉïÚ´rÅæ#AæTì®g }hÚZÖ„„vy5…þ±I¼¯†!¼ŠÞ_˜«Á[jg-ÏTÌîwÙÇ]W$.[Õ|‰åóeNÅèÄ¥X¡KYåÙ4†¢rêlj(éÈ­J=›£˜LXoƒ±ñöÌô˜°E” NÕ¼& ¬­ L]Q°š ËšzzæçìoÜz¾+=ÃȨJ&ƆÁ,óŸ}hÁaÐU%V1,GñúMœœ7!@q\&—pª7\Þ#DQ­ù´žéuuU‰ÚÔÍåî¾[–¸o€¡À@CŸ˜FkdNÅ¡lQ<�ÌYp¨,mÁ�á_9Sö?7ô­á¯ÌÞ¶­»½µ“¸tÄÚO²y—mrÙÝRÚd¨"eC•œŠ&Æ:#Ò‚G+›æÕ[åÄsð€Ã>I¬p]Ø'ªh-IÇ~üÜ\âí âê"àØ`&¨LŒ @J¤d*ôh±ót9]^ˆ5ûgCî-”™c6¶X½îµÝs‚EPk4мË!J܉bbÌ(¾Í!wÏDÎWR‘;×&Ovn)[Y¿ç¡Õ:îìþÙ(ãê‡Êu^ ›~®ÒqèŘ¥x¤N¸*‡Šö‡†ý)ü…7æ4ŸUl=`Î'q<À�~ñ)µ^b`p«”ºR]åštÊ·ûF‹ jÒ‘Ž#Ü`M“M(Y³5ÏcÂAõAЙ5Ö ;,Ô?WSŽ–¨Þ²{ ýRþè”UæÚ»q/AvŽZàVwÛ™ƒÑ¬±Ô¼pæ^L@oÒ¬ÿРK«µWßÄöÖjÇUÃ%èEª]:=“Yz5âBˆ²¼¦ž“æË@ÙìiË 4ì<7¯-‡ðFùµ«æÉ‚ÇÀj»WŸÅˆr`†—Yc&D1fD«„ˆúF‹Xÿ¢¼Ë$�3&RÐÖò˜4S.áæ=UÒȬ1¥sÂh¬0nèVEØ£{:Q•¨D\róü6ä€wöt‘†¿u­í_ÁÚx[(«…4jqmHÇ¡.8œ‚R5ÁÑZN<!=¹¨[Í;×Üé͵ÀàZ—™ð3k,‚ÐÑÍÚuR¤äy.Q•ÖÑ£y«¼ÑcN!b*zÊôQÿ°›s–pŸþæRÍ ‚8JÇ2¢£‡öË›QÍbaCæ°) ¢i)‹Åa¼;“E‡KÈ&n‘¸‘‰1Îm”ø.„`"@Œ-8“Š›d¨³=ò×äÅ.вÏCaYpæ¯Ú®+ §ãrñF^­O´‰1)ëG‰^²ãGwŠF4Dü‰Bs…›LöÕfÄË:Ñ ¥ŽÏ±O©ˆ€ˆ%†‘åâ›ë¶'½ó(ùx\ï2Ä$* õÅ:;JHøéÇiØ]ˆ¼aBö„Ã9̨‰±¡ÍTêúÈ’ƒÌPÊ —¦ž³ˆ‘ùKmúVS­Rè,ù«…\ &Bq>óßgŒØ/gbz²ÓXm‘,ÔÕº¶t1{¡éµþKàÉŸžóØZjšÉÙ ËÒ:¥F-dÖX1)—&§Ù^VÃÛÃò<\B„w �‚ýWÙœª)A¿ô‚ìù\{8¨¹IP?ñXN3³ä¬±‘c¢…ºô\ê¸B2gye¹ÐHPô(]JBTzY›„bþ!$'³ISZ 9­¤¸œ£l5ñ JÔÄXW…V:-éXò¿g•XO y¢¿‘|óe‘¾ôK$zp­~j–±„6™>ì!3¢°71Ö [ª+C¼1YÃÃÔ€IS\îG¢èâjÚ$V³èÄ…n•©¡ Ÿa@I š 9ªàÆHÊ?3³Œ]Œu Å£5æ‰SµèéIð!‚Ò5M4À¬Ùyz»@az¨yp¼sÀ¿ÝÖô| ëR“,ð¤ã´¢@m‰Öo›Ò1š.lú¶ÚΣ*Ø‚P£€˜XÕoCãC ì¨]¸~[h ¤ÚߘTk¤Lñ訌œwÅïèÙðte œó°MD›Þ-ÈM­ Gt…†Ûˆ½6Šñdò‰ht¦"c_\ý¡Òl7È¡Çýæ óЃ‹ì;7G€n›r%Cu–¢.àå¼QLöÌ2“vñŘ&+ËÍ… ÿ™Á5=вj¡êìë[äÝP,A4E— Ó&>›Ý<B)!íi€ƒh`Q¤½Øß¤—Ycœª®Ú†n 'Ö—¦Ò˜ ÀFÃréÚÀ4ús~·Ë6!õÿ 2º¹¬¹üRF}¥ö,ózGY¼‰‹1}d^‡ƒNÈ*ô>A¦ï+觇©m!¸ŽÏ•²Èë¶ò'FékŠó4$«N±íèlŒQcü™ŠµMÇå¼ .¤_¸ÝDäÿ–²éý2©6aÏßD±énÕΙ~èO“ƒà÷„NBÓr0´ßнê*©}­Q­�EM{‘xéátÅ»UæY8ÿš]®ŠÆ ³Ô¤RH˜tµYˆÄÖ~ŽÎL6rŽœ©ØÑ9•Ó°¢OÄwAÁàÐ7•(ZBr±h1ÂtŽX/LQ1Ù§QßÇ( ƒ¹Š‡ÓfkŒÇ©ÈÒÃ0Jà‡]žµ–-ežPRoþm-Va ÜgËIbº—µ*Kˆ³K¾÷뉫§‰`řե'Æ’­«w!m‡"&vŸ áà¡9xÒݘˆò©ªï+ký\ !ƒPƒ¶zD2}3#Œu\•¤Ú¬Šª–߆D•¢5–ŽzÅÒURÙA²©VÁe°\¹7.QîNIŠa_JÄ”ª¥Vò*øšþUœxhŹÆ$Ë�M¹î&Üs¨Ëm\ºÁ¸%<´•RÙš‚«Dy6ýŠJVÆ'Æ¥¼¥®&~äÄX¿+샒@ˆûeè˜[³¿JYd8˜>Oš™kηô§hE»…ÏÁÀýZ¡ü4ñïêŽßÔ 2 ‰ùlž Iÿk§}N œ· u°i{>lÍBªEt$r’Ò€w´”�� �IDATÙÓ&ƒÎ»Ê>ê2’nIÏ úNèSï_mÓ1uÆ2=›âXIÃ’õ§¬e¬‰:»Øu…9‰k*)œÄ;&nÕˆ1¹ŸÚbPÒÛxù/z7!Bi&éI;p%zš-3([% n$»¶G_µd‰WßA!×"ƈÜ$–CÒËÃÎXš…Ž—‘Ìžf)¤E½#à“èñæ*BÀµûjŸbhNG±Ø¨VµÎƒrý… V^%>ô\›ÕÅfuHsño¹RYâAŠR;ܪó¢…Gô¢‹ÐugÔë[%$ £(ÌŽE¥@Ì|Q 6a\Ñý“R•ÌKEŒát@!‡µ4Xdɦm)z2KP3:_DýƒKWÍÎ t\èff1a-¹åd­‰1þåÄ©ÌIi4±bСÐÙöç’˜ßM¥r™Ñ¤n�H ß/V,( E3˜=à °Ô_;ÅF©FbLèhóƒ5]ú*’¿,—Ëþ£Ÿ4¢é†¦S®ðÎ/¶¥Û7#¤ 䞈6r¼]a¹à‰æfeˆ¨˜Ycrµ‡Äx@:µà߯>Ò,º”³Í`rjÆ6Q6Ôøä™mÈÆ¨•ð‚0®L¨XÖ0eß2šMÅóÈh óŠd“sH1–mŠðg¼a‡ºIgè %tIƒ,ˆ‚ÌÒ'B&ukïcºj(j9IW€ 1ú ð!DÑq†R//ÆZP<zÿ\B_Ûi‰’PN¬·ç*×W j¡Š¯kÝ4h|¬ü¶èÕ4Á�ÍÇRXÅc…´Î‰;ôÁ„Ñ|ó| *MqV›ž^}ÁÚY‚Ä“š~oæ‡TÅGÀ1Ž=(!”VñGšz¶>½uÕŒØ(4Å#Šq%¥[Âݧ0«@t¸tD£ö¹¥0aGa¿q6t“/±v~j“eX b`3ºÛCÓgGÄçðfœ¡­1¶Ø‹CŒ±ð ÞŸ1v†Ëî˜bé¹×½Ï[ÔIˆ�yPëÀ¤*R D;žÐ!¡ÃlrÀA1ÂV͉ë”ñŠL"7°º1ž„û(øoBÊý½€.ÈÿÆUÇMÛè#ÍØ KAsçJy…´àA+ˆôßjNÍvÈ[CtHZ�;Þ£CÅÄXC '·‚ÆÀ’¦¥ß·‰ ¹Wæ•§é©î„ë’ݻފ…!±XqÑjDÇÓ¤eúuôÌ›¿Ñ/Æúhs¤ó,.:ª iÈÒäÚj ±¨·‹ÁüjJ7hÝsM¡òÖ3�y¢@ÒÁ•€ü|Æ «IIñ—z”xz ´*éjíÓ‚&"˜‹›¿õ ø—žóÏÊAï® ÓÚi>˜ÚלÖ1øguæÓïT× ¢ÄÆ‹“ì<«ª¨+ég‚(ûX4͸X¶¸ˆÅb£èU¸jºÅ� jÁŒ»‰ÄÆæ »rÑ£½åæKôXc §"—†·Ú_“Ň&£§³Ûà)Y^A ^] ŒG‡æqpŽÏël÷ÇA%ššªkµžJ©ÜÄX„¶™!á‰mÄDt%–¨hñ‹D×ãÐf=8”¦¤Rƒ:=‘‘ê)—›Ãóe”;IJØî”Lë7ÖØo ]˜Ú|!)Ãáüáz¡û_í›ÚŸáf^¢I›çþ¥’gÜŽ…;–ز&E1n õ$¼iAiBu3Z‡Œ¾"zµYl ÖÄ{3àDS ^ùÄÕüEb»p¡×¨©Š8€æ¤N’Žë4t†«zBú§\Ú3Z.Nº Ââ8‘ÆBKG«6"‰1Æ .‚a<ðAýjSPBs;£ÍÁÅ( º?|n<˃ÞË; :Žô ÌIÆñHH59S_ „¿‘õ|‰&Æ,zi+$…¦æ qlÈQñèŒKq`:T­iR³çQ)/š/×5Cû¤C´vðe´Y¯æÅIä, ­5&$Bè:,ÀŒk~¦i ewImq‰`²Nl�9“óÔm¥>Ì>…I‰X9 iG&äÄÅMhʧ¼ºèH-ËŸØf‰ø"­A ¸V9x ÿÕhg×pNxZ] ›F‡iÕ’lGG扈1ÆrQ(ªèz³ #ãØzhÇ) ûX ›xÔ)n.N!}ac`õn—m™dHŒ9Jwït¬|£s…OlLÍÕ†Î/×d+A‰ÎÍš®ÍÕN#ÿ>èì¡Ï$K›‰êõX?Då¢Nê¦Ð²²k$ÅRé%’&œ­1®®ðA9šëš>l¨? mD*ÛžÄnœØƒ¿$’‚,®,~Z­U!/=Nã`·RàÑõ4„bL‚cF”Bž%öÂ) P‡Ì¤ÚäuϢ˰ü™„8AY• …ê rÉ*Ç]# ?è"Èô¹ £þÚÑl#1Ñ*Bl}ú‘J,` ,È’:ÑÓ´ÐmYŽ+\*Pœ–¢ ®A‚ŸMG�yz^ˆ‚Ó,°^ÄEIGIíªÃ%JñöxDŸ z Ÿ†'¦M/æ¥O)£=œç êœb ‡ØX Ræå h ÁÚШT¥ß ¤~Ó´èÀ^CV–݌蘤ÜÁ7k ¤e$uá÷/)§®°'XãÉpÆ'úÅ‚=6‹Ñʽ½ Q­*à¥[fÀ¾š±�b—9/üV”ößìcr1&šR…8~­½V‰ cWjÅDý·CŽ2çwAS ™±oŒ•*Y'%¡‰²WC×לŠü)”ueѤØÕÒtÎ3.2×] àT–V+9“’ª+ℎ•œÂñ$ò%éP·…Ç0±1.v̸o€®.s.Â[®æIŒ+(±B! o,°éÃ*’+çò¸þÐí­Ñžsv31œqâi‰T%g¥¿Þ96DsWÞ|ìm %à(qb5ºè’n1J\hQu¨–eÊ@ºª¢_qKÄ‚A ê-Ž®™!vϱØXÙS+—ACw:\`^dª¶Ï¸ÚY±˜¼zƒ§1¢Ã‚u†¢~ ²‡ˆ[çgtÔs ZÄ+S̿ŦëÚº¯€åüFlÖ¯õÊ•zª‰¹!ô*ÝN¸2(êB\O W!9•@¼yÕûà (Œ8ñ�üTêcî°_Ò•(~·Å—o¡5çÒωbW¡-GFä øªAR><Ætg„­ãçhQü´ìS„îÊ-Ä‚ã²KºñT¦#ü7œÑÙÇAÕßf±ù¾¸ôÞÅS`šþ¤ND­[Y°2$.—ÉNÜWžz¬®$#Ôª8:›ˆàîÒè3Õky=‡†pÿAÍ©á,mP¢Wf4G³Wº9º‘bM鱓j;qÃàš,#z-eÇ ?O ©K¢ÝRМQz4QAÉõZ–ÓÉ ƒ»½q—\¹üœCê1鎯Ҋsé¤8VÂî¹å³t J¡°w±xSG‘ëì&©%}ˆˆ1¹cÖšÀFá;pÿfBŸŸì.É gA•Cž™wà¦!M¿×GÕCDU%4qâ™ 2vJ†2$œnûJh–[1."ó¨‹1¢¦&ª"˜N«IÑšUA÷æ5 [¡ãs+æ=±A¦‹X®±RÌbð ^È„9r6„–Ê!zØò.ª‰1æòg§ZŠÙŠÛ@ŸÚ%åéÅ8¥ÊUº”™ŒBþZÑìö®`¼Þ`ˆ¨5Ü(1Kêcö<¦ `ä–fÀˆ14c¢$£³×5,\tWÁ¹A©€†?: …X!@„¥GË k¶I£§/21³ƒ…A³ôfSÎŒmÚùèrµÒ¬1fm3 Ù(8aL·‡¤S™«ÎRxBµáá ÍQY k®EÄu©¦¨GržL¡ÔD4ì8‹Ý¦LÁji1EÁaQŽ„V7ñ~zôZ% t×P‡Lhú¾rK9ºHã ûÙ”ŒSÄb u´×Œæ¹6¿b˜ãíOOw@±Ü$Vs@ªNËD�üÎCÙÙÄ€Ö×d̳çUѸäAh#lQÇ�ÝoI9Å)èâhf%×gøÅ˜Cõ¹¡L%® cPÙ,£tL3³Ž.„(•�h?$8CD¤ft†-¢.ŠÑIb¢Àf/›AX™\9Ér%o½ãp˳v1FôG±Š TAÜ%ou‹±ø¾(RŸ.«¦O5�&Zz¯¼ü@æ\0uâ\ÕPÓa£úUÒn*FØa¶ÆâšhBqf´4Ö?çÒ:¦ÂëPªèØÇF7MØã¾­ ='aO .ÉæÛŠB¬¥°Õ-Å£^Œi"{¸¿føJ´»˜Ü\±»Oõ•G5e¹‘Ùmâ¯ôÐWèø»à}ÎäÞ.¨ë…Úæ.6†ÞAŒÅʱUEƒÌmQ©LÌc–sp+œê ¾nŒb�Q<@œð ®ÊƒÁâÝ<M[žk#‡–K ÞûÌåvê ­�<¢Ö‹:ª3Q-xµfv¾Àn`EtÍEfƒCWIf¸€fÄégÊv!¢È—1ØS×HÏÒŠka#z’™5FB¸/Љ>Št͔݅}Õ!‚î^FÌ«¥BD, Mgó½ ‹½ÔæF$žÆ£ïO­±Ö‚·ØÅCOLN©ÁmJœ¢„N vbyBŪ:LÄ¥Ô½>â½uÃà*[-éå Œ–bRøÕY³üƬ±8`T ažMÉY*¡5:SA<$ @鉧341GZ#ÂO ,hÙƒ(¸·¦ˆ"´Í± eÏ3ˆŒz@§åc‰ê™‹Â6Å!Ér)eµþXÞ¼v?_DŸh|·£Ï7î1éþÎhYK/ÿbñú2>Ѥ›÷¼ˆþȇ‡ÏVƒ"ÜÓëpoW‡¥€÷P4@«·-™§A¡å¦ò\‚MbT¡bl ŸÐÝ�’R™ýÌÑVa9¢ø]‡ו‰ŽSËT”:xDÄÚß°¢q“ŽúOy„°æù¡àdÓs [H-±ž7¿#º``4þàýÿ§ŽÞ É%†Ç¯,ÆúknqÛ¸vUoWû:•~ãù0t ·¸mðÜÜâ‡À§ûwR>Åù¬Æf(^ø[ܶÒbµú‹jGEd%ô[5ªÕ’«}t1* žß]ƒÈ2÷l¡êàƒîÜú:U“+¿¤:*GÌÕþ¾4`Ü[7mÏ/­Ú๥ß&¤ôaí ×þGM{£v„þmÐtÉ7’²ÆàІ޻ÏSÂIñI»D(÷ï”E©Ô„•“P{áÙ,µ¢¯<P%X^–dñW£KE‹ý_pø¬±€tÑ¢&ŽuÓ¨„º›×ÆZ=ÀZ©qOi‘´Pĺ[±ªÑŠªt‘»r5×ÍÑ‘@~Mï¥WïÜŠÊŸ¦zšŠs¨RƸïáI¹×úmXò„brÕø?PÑAëÝ­÷‡$ná’l‰y_7§?M£5 ¨)Q+z ^öˆŽE_8ër™„/­ÉG·®‡÷ ¡«ÕŒI \N›X,Àoø†oÁùHʈM¼2›h'1>×/Ûö¡¿ì§0y"åí'ô]LRrZcC0Sì,F£¾µ±‹ÿ“V`Yvǵ«Ó‹"Kh#¡Y›WÒšTÝ]Déègñt|gŠa$n—ëÍ-a$Œ‚lKºßX\Ù†ÐÔ臶»¯$¨Ø{‹H4ÅÆ n¾ØUgL‘GÑA{AÆ0Y1È ×šUèŸÆª×)·Ð€M­ÓoÇÄBo²B¹œŽI\dïäYõÃÈNX@óôMUº²ÜÝ“OÙK¼Ë$ê»F#Ý Þ:(½K@t&G³n ™â!´Ì\7Ia-ÙO…—½éIhZp”zhWb\[¢Î!.V…±ä§/†6ojÝr«HºX;èŒDÌ—é°cYæRWÊöme4ôeÒô…²yëc ·ÕQt’‰ 7ñót »ª«2˜(6+­¿v’Cõ-F”:–žmuczGT«›‹S³k¸À�5—{«U Ë‘ókÄ:]~ˆi`þARÌøIó¦D';”sèVoMz"ª‰¹ÐälÚðˆYnx_q1Ü£ðžÜ©y–YÚzÁy}Â$㻣Ó7bÅÆÐñFì\ŸxbEÿ@ š{þ¦@öáĘZ[Q¸FKIqRVÖÑÚÒÈ!Ü^e…<'z]Ôät­P+Pq…¨Ê ÇžAãY_®W›bGlÊìá:¸*pL^‡[šé8YhÈÁb,Y9”ZÕj+wõÄDZùÜnösÌ ^0Ò³Ñå¢Ïk«æqÙt\%Q‰ÿ§rn²g&Æ”VíÇ CPÔaÿ€Æ=êPÓ®l:ç׋Rÿ‡æ‰ÄìGƒ‚ ì®\#Q‹áÀñ ÙÅ••‘ñ‹1\u‹¾òBD}¥´Ue‰TKÌ•õð/iËI:Ý·sèJX«öC1MˆJ#ܶœ¼O ­Q(‚;‚ÄŸ©Ë­T[Êã@ó°iFoº¿Ô£*Â,BJ°çùÔdR­¡¦-ð÷ ž(– %|þB53édFø{Ú¹.4ÈNTŒU>Êe©¦³Zv£Ö¹XHGÏ2§L4+®óUO#}éq Dùí¼^Gt#¦+®÷zð3ŠADcBaF$@ø©£Xú\ ./&ºÝ$bxޤР„(¨¯\÷ mˆ½+ÔÀh-ạ <%T–¸}™–5ÆÎÙC{E_!sD“3µ–huè/¥¢Û\KéîĺDÊI8…þÚ¸ø4o ¾fýñq­iÀ†,&Æp3NJˆ^¯Öš­Àž…·+}}x8*¨ëðÔ± Û2„!|Dô±×šÓ%…¥„s›C€ë¤“¡œJÜ«ÚëgT¬1øSp¤À}Ç¡&±ÞY¨>´6>J<)bꇜ% _µ Ë,Š+R¦–åøã\|:ñ?D¦(1# ée1³`1Æ{´šÊ/š2ë¸ðÔE½(š7EAfÑjZ‡:DлIëËrÒÝKçDhvÿ¢Ûý\Ú*®34:XòÁ·ØƒZcèF¨©Ëò3º2NtâÉ.ú©\jž^:Ê:®¢_ŠÀõ3ôµ±”­t q‰‹Ž˜yÏék*IŒ¥w@ŒÑ—œ×í‹C2e¼-W²¥~ñ/ú‰Mn9'Ëäx¼²¢pˆÀRE´¡Àrˆ¬°5kCG‡ë dqÆ ¢¿:]ºg±¨!¢¿ÍÜåz„gë”:'qIt…KšF®s¤)ÍÙ3xÁ8pû¡vS)ÈBöSämƒ84„M…†[Þ$já´9œâtDV¡NüƒÅ^aé�©£L¤Ið<iÇkþ²ˆ Qðx'Ÿ†1íZhœHNP—ÄX¨¦Ø’ŽâBa/'ªý'.Ÿ¾z+ ó’Š‚¶Øï šÆu$"ÂBÑ'Ó£ˆPÒRà ?YΑ“ŒÎVWíZ«åµ¦ ÌtCZcVÅåFM?…'UC4ÜšÅPlxZAmij¬U� &îJªK¨óYŽ—¡#ÖAŠ&ÅkMg¡ß¢µä”Eép£RþÌÛDzû«"!¨uºáˆ~GWézQÑw„°Jõ½( ù±AÞ{…%Ã"w¨ ”ZÿPæ5ëE“úR0×pH]£héì i&•`oY »”ׯ>áwö¥×é8La÷ìîöu¤ŸšPåËrEYÑoW§<ZsKŒTÌŒ3á^"oGMS¦»×éø Ò›©6n‡¡'þïã°yçµEôB¦XÓ~£«AM“ß$«Å\ÁK¢%ÇU9ІJ Ï�›îÚZèû0v‡ŠÖýY?相’³6D÷|ƈ–:ý=¨S®C)]SaÉ0¢o’Xá…<%tsFbE`ÔáÂ7töÒéY»=BÑ»`àüB"6]d7šåzàRïظû TÖïI˨ѳ ÞcèÓe³´ZÂòEq !”Âac¢m·j77WJtWð4Ñý bi÷µž‚,AŸ:\{nÿDéç%²'[—«^3"Ê¥´Yë ñÎÄ[cN,}@…‚˜Å­ùÊ_ÐiR*çµ`éü”s—žö e?(KG0p%¾ÓUXcI¡§Wjn³­1àÉÑï&­©ñê8­rEYº8­6ê\j‡ÐVM5"2¾èR‡…ÐÅp¨K„þ‰e!ñ*…éÄnbŠ1t§W䘘B²éÅÉ®=Er·Ö²wåöÇ~€®¼ å)®KŠË(aœsú„­C× %0*… öJYvwNŸÅîÏÜ–"]<UM¡ç Þ&œËL¡+J:ö¥ÿL¶¦DÖ–— õƒæmÍÌØ²GtKÔ¢49rn!o“XGh Ÿ·"îÓU@ ,ツ€ç2$U„„{Qîg@pFͨRºÚ U‹ò‡CŽmÍè‹xÜ(J§ŽÅCìGÈ’W‰€"Ò_;…p»‰1ßVhm\D‡ Ýd>LÿE³rvǯD ̯/=ØÀ’Þ„i.‘ ñÓÒM"ŽŒÆAbp{‹x^"–jtQÙMBŒu²û)În\!.¯ ›¢ƒC†`×V¨ùŽÞŒmVX¤—E‘(ˆ©–X°À¥2æ©…¬FD¡†âá.í¢„Ä:Ö €ÏoAÙ–Â3Dp§•ÜÕ‰Ìâm}A¹V«QʱníM É9Rˆ0¢œ®Ó‰uÑìX# ܺ¯ìÍ r×Pf× ƒWû°²Ô¨QËiVå‚Ò;Ý(_<•qONÏð¿‹Ü‰1+FíCLJï`ìA•8Et%1*­¥JÚÁ¤ iâÑ“Š…ž˜,®P¼*gŒ£YòÌlEŸ)Ñ»‚pS63c¢pô«x]¯‰D¶‰‚¢&s5²tÑêKz}ë+peu¥DÇØLî8á­øZ1ZS‰°”EÃVHåfZ.�> x+ñ\Ѩ.Âx:¤Ñ*!@¹úEœ5„Z’ìçÒ‚ºs šœÃùÍZ=$,X·jfb‰Ý Ú±HGöW ú9qMYr÷u¼SÄeÓãBµáÄeŠè›'žpÕ¼3ú âÖ6È¡± ‰5Æ›õ‹k³ áË,ãDè•,6;=&”Ï ¤I<½pL)DazWø»e†r[^0QFÉúŠU}X]&ÄZ•︪v,Ìën‹1ø–ÓwBÇ�çj«=î/ÿ8)gIÿ¢zyPKYHÇ¥eÄÛ¥4e ôÇÍ¢•»8>#Ôw½Cm¸=0lÖe@tda.A+-è.Fµ+Ôùøƒ£Áy7Z¥hÚØh±ÑÄ+kË­$C ‰* ©UšJ𖎉1'™6#Ê÷%¢»,oš·†`²¬9J©¬\ª‹ŽÞ ‚Età Èæ/™~À{ÙÀ"z¹œ–Díq« +Ào— øŽª“xˆ=«Æ…”Vœê'w ¶Kþc.�Mgµ›3‚.⢃¢Öƒ?)\ÙùÁ AXØèìÍ a–¸Â§'ÆD{p…‚ËÂÉ?ÎrrÎe›\h-=ÚG7n<Qti¾oc4eB#Æ ¬¿²˜ ,‘�d©p¿(ñl– Íè‰õ¸WˆèJgÆ’°ÆJ–2 ß RvjyÝh "S¢ÁAU#ôc·Z‰eÇ¥¡Ï6½|˜±¢‹È!Áf¡ú?‡íÅ%ä?EKÁ1."gàÍ KZŒu‚ëÉéøNÍéØ}Ä(û£S­òÑêÖ#OEt"M€iÆ%ÃqUÈ�€ZQÓ­<AVp/ˆ¦ÊÕ 1&×…D_ì¥Ð=›GzQŠî#4Vo\ !9êüDɰo*“HÐsU®ÐŸ0\(^bM·‹É»-YšA'¥ ƒ®4®™V‚Ó­ÖÈCz tO® ä¹A·ÕDÅåò,Á³Ãøy ó žàÊØ1�g„AÖÒC5q+ŸË<&’ÂT¬nnÈi25‚âr]޵cøÔqµ^¦ã{º|ÑßHÔä’0¬0Ã,7•+9†¡g0H™ ž! &A5Ž­XèæM”ÂÊÁB±«!“s<bL"<†VGˆÆ™[ï×öBß¹)ÞÚ”'eç>…_4! K§†!Et¢•®æÝÒe¯èa³Œ¶[@‹ÔòçVΘSÞ-–é°€²û·¬œ«¤¨0JC½yζšÒà—+î\…ùA ™D ¥Ì|mœ²·ýY6šj.û­‚{ç¿‘°ÆÒ©9¥ob8ÓŒbëÐE”Nµ´Ž‚6åK»‚7úûbcFÆW…ç²b3€Ð]D;8ç\CªªÕ”g÷-.Ýa1ÆÒŒ#ŠÚ¢ ÙµþXSäqÇ·† Oµjrè,YkôH"W…Þ‹¼Il´"% ¥\yꚣ€‡BoC 5S@gî!­±dS·…žÂ(³ý¡féH9 ¥JÌc—(]o} ¦�eæ!Õr@[ q0Ùá"ª‰ÊN ¹™ÑÅ¥lKhˆ±¸Îe‡MUº¹ŽZpz‚aI1­S9£Ñò*Ô¸¬a‰frιìn—e²ì ÀÎ)ÒžŸ ˆ/ýâ‡è>¦=“Tú~j —„5Ö¤J³ˆˆS¬à)el/¤£#…ŽtÀ΃ڰEY†»+ª0‰ÙÇ]–ɲ•P7¹¸­SÍÑwœ°IQ†Ê¥"Dépb*¢] =f �� �IDAT±ì6®„`ÿƒö»-˜ˆ ×›V•} ëÖ…`: ¹|K7Ïæ]vWyS½äQ¼G6Ÿ(T§”ë×KøùÁ”%æ6¸RmfUäC%ÆÐàîi×8úˆ=ALÊc*hHª&Y¯Hå­Õ¥ÔÆú_¶©RÞcí±$tÔØܱF³èp´ˆ§ËÁÑ2¶#ò.^G Ý’dâm3ÓÁC’'\bQÜh@^ÌÅ)Æ ±¤”W·`é14-B‹ž„=\Þ‹ÌV˜PF¹¥#ÃxÙ E-fïÓ4<bŒâCÐñ§éy$»pÚ+ºÁM ‡—ø úmê°*t]–�˜´ê­ çÔRõRƒ³‰5!­“Ñ*Æq4ý=䑈Ä>¼[œÎ|yÙw‚½x¤¡Ä!x+ º-’îêlµ×=zL6ßž‹›^8°o¨m1ð±·òeÿñEcáò¸øQrx=.£’©ÈèK Í,gtÖ±;9á—&žR=ÀšÍ¢<”pÐÎCH#崷ИœSlé Í¡$z¸ %.\’ñ:ÜX„´P¡±­|R+ÎCŠ1zsq#Œ‚!ÓÊüDË!QtWvF\›åÕ ÒÊ‘¥£¼A€#,nzJ¡# Ã1:Íèf(4TÐÔ…}Ž íE²ÆZ\¼°ÔjHB‰(J[“CðØkà<P@t“¥5ížEUÊN"öyáêXÏØî„W^ŠZHA:¸œ@K߈6ôÈ 3æØX¨Ç€ÅŠ‚pé½H—1@¿¿01ÿ®b3ªt6JIÄ'FÚ¸ÊÉÙØ Ç;á}ÑÍ+Vç-¹Ò‚á¶®TÅXëÜW±ÈŽk Ksª¨ápnÕĸÒšEñ „*²u^ÜÏ×àð8;añN`kLÍ%« çøq¶(‡¨gãJgP³ðC8ÇŽÕÍC[Œ±¤f0®åHk®NökºÂ=í„Ø±#àšUFÇc†Bë©+r©˜h ˜w�¡âÞFQH5kø>×µù@bL¹¡%n~ÕÐç(wÍödœyx£á ¸^܂ʅÓ]sš( ðqëM€Æ½Ìƒ’ *-уŒ^3Hù?çêT—B…²²f¯!Æì(¦ÙãŠØ²2”×rUi¨âRE’pïdûpTC!çW´«Èåž‘ä.²ˆP¹A[Ô?{%0¹ÎcëpáEáš²‡ƒ2Ë4åKÆÏŸŠ5–Î{jÉÃ¥fÓ§˜V¼ÉñQšÆñöÞ¬µœlQéŠkÝ)—Ðw5M/½";è}!Q8Jv3ˆÅ‰Åuy5"ˆs¨v»ûs—‡ÀrÙUÝ­Ÿà­uÂ"’+~†j h@6„ö;à šH¬\ûâ;E{wCSÛå&Ñ$’î"†«wD¸I@()µLcÀàf²ýæÄ’X¹¾0íÚÖ&L€P´èG”U!üTú5‚@ŽÃk¡²¿lkÐCh|,W„ò’ÓUˆuiÁbŒÑèÖ néþ¼n ã…ÌàêöÄ~ÎáIh¸xð,To†@ ¿v–‚ ˜(ý8b5¦‚+(Àá!ðõCÅv };qªÆ¨@#v€Ä ¶FG(fSÄœ.^ÕþÐЂ¿V½ÈõB{ɳà%UóЏÒÞ¸6ïÂ1âøðž!/…Žhhd’ªkÊÉn’(,¶*1¥¡*‘yÅ^”Þ÷BÅâS+m•¦«‚1g/ˆ§á­)*l“o“]-f v2êpìJÌðÉ3d¦"”‘9íP î¡VÑ»%-çàÑ]‰1h¶Öe(Jhµ¡6$„LÁ&W3ñN<F CÎ &ÔêVè°Ç"b–cZb,HÒÄ­›áR="ˆÌuà\î‰PBC¹'£¿7µ¦0Œ%á¬ÉbˆKtÛð³ÅyÁùñW:¦ w}¹Û19?r…ŸQ:r¹†à‡rK ¼ ‚Îv¥ýû¡P:¡XÒ3\dˆÙ]l·-]5h œùjù6Hb8œTAiîô¬BCk˹õJjÑ[Äcì†!bn†æà~åHÒŸž�”Cœ7ŠoŠW~×& Ãõj?É> lh¥ª*oxÓ%°—t¼Ožs¹@1èè½é„̃ò郪†F#á©ãÝRŒº3 g%Xt!G²ûR(Úq6p•ý|–}NÔ;%‘ÍgÕœ‚ã$Í<…(ÌÞ͹ÛÐÀjkgmp€j W^Ý™ ,bKQL%4³à58ÙC[ÝÆl§Ë²•욥„—ADWïxÙ½Î=¢Ï5ŸQt&eå Š¨CŠ1â™ ‚-€H,ö ÐÖÜ„P‰ë¼u¯tTFϵArËS ª¦¸!ÌwOâ@SܨUÌ32ÆÞlð-¡‰$$�9n¸Î#4i•èNG$9ðŽtL4†òg”­>ZWõü·fmàD‹œ»w[\-Q¨«³é÷ÅIÆ1» ­’mrÙÝ$[Ù¯s”пÐ2 QKÔ*q¬–Ž.xñVK~Ÿ”³ÒuÔ…âKôÉMEŒ Ù@qꊼ#£†FH–QÁ±ôý'†ìnA )¿söa—eëóÌÃst£M‚òƒ~Ô²gy+8¹Þ±šT"äNxÉ0:°¢“O,=êDã1†F-@§œÇD`épnðè¸K.(ÉT­Þ U¤ø¹ Ñî”(Õò{ØpHƒAn«ì.—ݦ. ~Ü*b!©§¸Ö?Œ“ŽUF”C –P¨lÐÏb'†i%ZøÆ’mœuc~ xH@ ¯3ÖFd7Fƒ4 롦1Ä]a—K,"BÁÒïÓ aRÀQUÈ+g†f.½â&NÇ ®w?Ì3Ï@«Ê‚îp…ú½н˜ÓQ.‡4µ‚×QiŠ„ÆP˶²û\–ÝQ-ör¬mEmœ6ï£äl Ūm*VÛ¥(¹›Oä”^óB9­ø+û}©Ãõ¨¥7mcWö=cÃ¥{Ufú[4Mcë»'Ø©ah¾ŠXt¹NuM£ªuB凧?/Ä`,´ lv›gCÃûº±'ÙûÓš4 M–Îôk¢eëÆ¤Q<¨Š¢Á‰2Él¨\U£L;´H@ÔÔ]áœ{²=‹/Èé \ŽAN |³yŸïW³ØŽwÃsõc÷ò­a¸QÞ]P1*ï¼àʇáÆc‹H¨Aî,D¤ QKTr @Ró; ‹Í«Ž‡|Øz«b�»°çÊÓÙê6f÷œ-iÐoÑ®­ˆ[ø´pú}$¢ÀÛÆ´ÆtÔ(ö<‰Œm`ž!‹%Ê{Zè7ÄõVö¤\ÂÛF02£l¾¼XÕOœ7Ãç&%îÞU}Sû&Z„tñÚq‚Þ×[“óà¶®ŽÓ+e½–$ÆR˜#¹Ö¡ùµðN•\8ȳt$p'¿âëÁÛRCnU‚„ÏîvÙ!ÐëÔ~žÍ;¿Oú¬éôàNJÓåºIhÑ:º,7¶|ƒá‚d,¼TׂÇ«fÐñZ:š‘O -e ÂGÔ?€ÞT0Pà®ßÊ+½Jóœek²ìWµ©ð\GîŽF§wã¾¼‹%·oYÂÒ)@]H#6¤I `T¸P6=<Ig„Ë›O1&p*3±XŠr\!N0:päéµ1× ³ûZ’JJ@ŽÒX>Œ$ôÑâ0bQ^Ñ+ô8DèâPkž´5¦&Þì Ywp­ ŽR=Š€~gHtFŸ>z³IØî¡ƒñ”³Wj…±´~-$–tÒs„.Ôoç+±X¼Œ¢«bŒeÊ_qUÄm‡b*½pJî$C–î¡…hßy¸k°�Df7Ç)ð =÷RÔ‘Ó<‚T1®Ä?v(g‰›t" _)ÅR"®Y* «ÅÑúç}c¥Ð[ˆqÑC¥NvÒeÙ—³ûEö\¢§MYÀÒç…w®â6&MÏ3öÂæeÂé‚QµjÁþéàBÂÕß‹ à¶¡û ˜pªã ZxWAº$>_Ý™Ù&—Í»,û,{4»³yÐõÕ Z!NØ3×áiÃ\n¡Úæt³á›Æ�´à­ü9².Ϙ`Ͳ“š%ý‘°¤Ÿx¼ ôÛö­—Ë>ŒwÖ¦-DŒ Ä‚=Äe¨Kè‚ðГÀn¯@ºUPÌ€Päb5­=Ek ±Qè¨ÒŒóÈÞ; ê®Q:¢á=Ùqë¹�e/Ñ š(P‰·a¤ÈQÞóŽÈ3jÙak̲' ûÓ¥¹wã"²h…ì©.¼¥]­Â%øàþo[A¥ƒ�ýØ‹å¼F¡`ÄDX ÜWÄ1,#\Р ¹ÞykŒËí�gÁÀ>,”8 Kªó6ÅYè³Y)“U³cØÛÓˆê=B¸ðîH¼8ašÖ*Z`�û‘¶ž/J…«§ö‘Åcçr.“Έ1Í·î|C4­ö‡!ö7¯Õ%m­J×á"Ī&œ\zNÉeLB‘³ÉjÕŠ´ãj¤§†¨K)”“§ì¢L¸õÀ°HÖs�¼çA}šŒ– šK Iâ:áðMÀ¸MQðÉXlnœ4‡"A¤ŠÆI¦‹‚ N¶“RI1ߣBv•[ë7¡VÓ‚�PÂ:IÄJ.=· §"&y;¦‹¯‰“ìQãšâ1~åC¢ î«ÖÉdìr٪ܨùèBËüé°5š ´ñŘæK¢s¢ä yx›QžÂ¨Ht äšaÄN @•EãÌ2{\†E Ñé1¼0:æ~I=¢4Hâ²ÉÒµÆDù)ˉ¢»Ô)Ïýô^BZ^ð{väïP¿K…5<SF?—EòeßrY¶&ˆ7±8"â #‚S#¦‚÷tsq.!Ú°-š“Æb©mEH7pI†roJÔ—é)jðc@·†Ù1Žév‰ß)´Í(¨á„sûóY%nƒËÙ“«Û“ƒ’bQ<@šB\NnÔ àùÉÍpL1Æ•äÍÅÈ€p/p_ „q" '©V=Æ:­=nº&ì^L…×ÌdËîwYöϲAk>§,õÝ¡Ú:¯å!QÄ ¬Öئ2=%‰©c*2vÐh ¿s™±ÁãÉÎ ½mmŠ#b˲ÛUAk‡Ë!Thg%͞⺿BÏT¶IЄU D¿j—àt\µB zN5ÑDPÓñ¦'Ætι&z)×råœPzÐMèçmÖŒkZé |$6‘šÀ±8[ȶ¼NemžÛ…°<šö'0gbs$â†!*åìkÕvTruc¡‰§±ÔHÏbQƒRG“@¼-—Þ\hÆpAM®×ñ+%ŒíΛÔ”¼ÀÛ+ÔI.É~”ò— ºÜh’ìƒÅX£g€ÂÓ‘Ðp,XèÔAø&ÅÈ`y\²OÕÝ„;Ï,…“a×ðà„b:ÐO×r9U îYàaÄ¥¸!+fä­­»D+.íR§N�X:*Äg£´&¢xä egEÖOï8Å>9ÝVp,SøVaÔE›OùZ(öJ8”ÕÙN÷Üàc¼•öB[<–IGL¾JÒ‘õ+7êÞ‚ók÷3büB.h “~ÎÕw¦•«ðã²oȈ}´å†=bLG<Àu õ&—Åäçïô¥·5Ü8c‰ÐàT]ôB‹¶âu1°eÈ“r«ì½g[ Õ)ù½ˆv”É �väPX%HóÅ{Ä•k%¸Ò´x æ¤ó܂ޑÒÛ¾õ¥½QøB”¾w¸Ë‰—¸ÍÉ[AÆDïh¡ããÁ9´)È,Ó6¾5ªßyÂéŒÝ{Žt¦\t¶$ò‰úG¦{kò$È<ô†À™J@(=· ]T_Ð͵…d†P8ÜÏyà3 Ó£JÚ¯ ¡‰j�Äu*²ÃÛPQÊå~B»7ÛŒEQ¥øVr/#ìì¢ÜÊ69£d­Ž²4m»¸-%7 âqÑyî¼ÞvKuUŒñ²Kx÷ŠþEÑRYÊZƒ4ÍÐ(¤ SÐ0Z%:¿|0Kè,E«Uk¬CT‰‹ÂÕq”ï¯SüCQï‚$¥¦;±“b }†q¾—œYCš‘GY!–âb`²2΃Ôôc´gòv:Ù˜:éïŒ ‹ÈÇEˆ…ô‰ÖMˆ3kÅò'&—z†ê…&n9ö<{ÞßG{abL³óPË«—Z”ÓÉA”*ìÜ©àz `vI“ç’“›@F8iÆÐ,\¡æm°" .±†,®:Ë›@ßÚ§Fí/éLEvÆ!··’5ݸÚGEÑÍCaO£*bCm¹(#üMé§B ¤‘ Sý3›[fðM«f°{qSð¬òˆ1Mï Qµ”P <Mâ¹ ÷qe=ŒŒ’XaüP¢±zÒp8Ä —¥ë‚¿_P“¶Ö¼S NºÏ5\É® ‰Eè•N2*ìíåÛï%FÅuR“NÖ–r%?¯A „ýe4¡$1 ¡ŒÒ/;SëXÍ¢7´úÇ”Gßðe·[ΡtìK19f¡é^ÊHqj€ñÛ@]Û‰+{0nÏYC‡±Í.Wê#]ŸÎ ½?#Î�ÅÜd‡ÁϯBïJWéB ML­:6Ž5&¤[¢ˆ$T¯Úašü4V=åº:´ØHMÎîjüM©º€Åz&‚¬Çâ}:¹6‰%v7IR„Lñˆ[°ŠÂ‡vRÓ™/ˆâsPÃÉÆy …C)ï›ã …œ¼¬P$TŒµ¾¬tù¦‚Ó%Šd Ú´8E ]j’œ“vjuÅ;ŒÈïð£Ùc�­™èAL±­£ô¥ãµ¹K³—`wAt« –w!VeA†$­%ÇmlÍ~!)Ò-æœ4ŠGõÀPò°#Îrh]ú^ Ú÷¢b#hÉ=Zg¾É#ÇÎ;Bc<¢ÈËK( (c`"(•œ1âé‡Ç» këk;a3$'Æ”p¸˜.dEì Æ«íR¢nˆT£Iª}Éàœgw»’ÎÄ’U|ÁÁ³ª(bô!êCn0—ŠÈ‚Y–8TXJdɦœÔÚ1†sgÁœGQ"‚êØ<Mu}ƒ¶>:=Œ1v(}+–ÜwÞkÕr‚Î<CX´¿šBÿq‰m�7Ùõ,v»“å}ª"‰±(‹M'Œ!;’‚ºËåj#ns-·Ž1JÔm›2°Jž'/hB«iÝø£R2/pš\, 7Äø…ò·“"kL.)“=Åhà2Ê^tþøîX’ï!?H9FÚq‚ûwó Ú¸¯´·7›§Î°B¤†1ýÜ Šv ÷«‡NlPZ�¯TîJçL%§"ºQ=£^¿ÕmÌ>ì²C.»ÿ¥ø‡~fâ¸tV!W~ /¤ˆ#§nCXLö¸Ë²5EI†ÓÄÏ©ëº;šRLÙoŒõøAž 4/bwJ›õ¦  p¨Ñq“Ss¹ˆ™ŠAQ¢-ÖÛä²»]¶‰ÓІKh–ÜÍ$1w P’|�|HÙ¼Ëvºì>*þ“D™<e®X"% !ÁL \‰ lÆ”‘þéýr»‡âA)gvÜùl,)³ÒuµÑ=-B-ä^á©+uª«Õ—[•žÐ V+ÜD©G{§3ß ÔyáüQí¦ø16ÅJ .Hàb§f%a5m;Š÷‰ÅÛ�x,Íý(z´#{ÌÕÄ¡Üãt€Ý²»‚%:;R3— †'Ú§³úM{»˜ß“›£¹ƒ¸™‚ ©Uƒ‚º$K‚bÌß Þ"]8¹¶46®¶Ôì.5„y.Ñ?žñÕýìôhG+ãnJsõ‡÷)/DE™Cñæ»rqv®³A}j„˜@ô÷4K§UŠhõ+Æ‹Nãõ0H”` )‹j56ê©Ó"‚È1¶ºÜƒLVúÛ¯¤K7,öOIµ2¶u">´&ë3–»%‘dýÈNEʹ%puõ%FËCeäR¬Ã ÷éK·Ôl ƒ§?Þ#ú¦¸ìAHÒ<ÕE4+×Ï/!6t<=p¬ d“º5ÆbÌ!� •¹6—c„±“ÄžÓ‡B$ µfLá\O­I¡f. gìw‘sI4U%„OEßBtk'eJ ×v^Œé¼¡ÚrÝ10š•7ˆÒÛŽÃIÈNÀ-G”"EâF£íÉ/†ò5J•!o®ru þ¶8qCjÆ\·p“cé  0¢þ„v+‡Z©õGÈõtº˜‰¾gÜÊmÅ]THäóX'rœkÀŠX´.¸ÎÄ9$ PŸcñc,93UN-TÞK¬ÌÒ&4”“² ¾5=D.÷=TKHAÏUØ3èD.«š.¡‰»¾íCc«E×|”ð±w÷•S­”Y„¶5–N“7„š@)MSÈâSNX¢ÏF¨˜ Âçf<¥gÛÝÝíüü®Ø•> –?I±ãU¢[z²(”Õɯ=xhÏðDšh6f«~Æ[Ê&½+(Æôó,‚À.…BÇjúWS \Ô^„$T$ª–f÷¼T ég»hœ3ƒ&Î^jž|¸ Ó¤Óψ‘tn!­1vñëo¤–?Í…æQ‚ÚñœË9µjYjÑû„v²{˜ÑWµµ�¶7çbóªÛO:‰탥°Ü(Péɉ1Þ9tÑØÚ…HîüSÊ]#@¸Eõ°C–;´g©ÿ+&ºsYè¨(íIá½?( ³‰4‡„ÇÌ]dý=V€GC4› Wn(áþAïÒÔÛfò25¹r+Ä)•.ag%h[ÈO…D3:Tgo}¯³ˆÀóõxN%ˆ5˜¤6ZÓŠëÉPV2PÖ‘¨Y*âÚîIŸB"£‡,:äG*uc@P�æ…ü%»ˆRa$Ò)m¨­‚ô>œþ Éàxé—›8'–R<ç—â+ؾÎó¢Ï:Œ•Ñ,è-kþ /^BÔuFŒq5S€gs%DxDB#ÊÒ”èVÞ•b5W(-]â:šI¸ã«5‹›7–ÚÄî[‚”Í8uh4ÊCÙÛ‚§%Æü±q¨lðBªƒGù™><6ún¡˜AÏ ÊSm–¹w¢§Q™¨Ï\È'F‰ï-—6Ôœ8æÚN@ÆEó bžµ`(tk5Ŷ™Q `¹¸€¨¤ í%1½©›Ò èUhˆÅ‚ƒgwY¶¦VZ4ùZÍúª£RA�ãö,¸´ÀºÀP—¤Yš\¬QÆ9š:%YHÈ‹2É¢›Ç²rXÙÕ®“ØMñ³]‹à¥Ø’_¿ÎîvÙ‡ËÌÑñǨ]AšÎML¿ð —àÞˆ˜¨Â‚aÏ[À‹�Óa”gEÓ èç’s Ei±±(¥-CÙ«›2rÞÁ7!&(Ù@¿wÿ/«/çƒÜöÖ¡i8¡Û¾1éñ®�c ŽFgD/(¤”Åó:A^A®VP:(h]!-?r¦"Ð!® UxVÄ~ár9îhcH¿_mk3ßlÞe÷¸ÖöŒzCöqÎåƒ ŒÜW%Ë ét4)UÙOwÇÁƒúþRTú’…‚¦[6†*É*úlÔ¢ JP<*éȤÍ\''(+µQÂmrÙã.Ë>–}‹ôRð>5Ù]/YEÄÈjgŸVFœ;ŠáÕpûL¡Š( Þ—ÄþâèL"O.7<2ÓYh}‡DŒ ‰åx€’æ2ï4Ù{€Gan³»]–ýj–½'»‡ÃÚw³./•ZÏ3œ®vqÒåu!ÖýÑŒ›˜éÎÒ2†%õ,Ô6•:°Qbc,.5úŒ}¨æb†$Ë µ²t*øñ¼ ™¡Ápˆ¶‘Ý㲬?À³:–Œ]ëJ™5Bú,Ü›ê¿:Û`>lQt4IJvÈÓZâÍUÀJôdrMïp:y1œZau”;G§iŒYWðݤñ„†.€Ü“Ý󩬢Éaç+4¥h‡:¾E-K1‰húF¬Ä=1&×L9bóFчFiÉ«(QR ! …õsá‚Cj¢=r4›vHxBSUߣæ.R@EK;å&Ÿt©Æ‚‹3ÊÕtÜÎ$ÜKLtõέXP)§?° ØÐOÚ ªÊ¨­ q·òÖìnþ‚¶ò¸Ãj@A˜¡QƳT Ž«ëÇÍËç¢G¦cÖEuBÃì&^yÍ.K ÐŽ¿ðg¼ú©\tÝÿ H ‡ø"ƒLÈP¾ÆxH™:ÏØb•Á@ŒZeĈ'©5y'<ŠÙ1&ÇÊ)Ö1¯S¢Ó%ÒÀ†ÆÑ-?0´¸¬".Ersb¼ñ¼¨±…Ú‚*…žÑr™5M{¾6;TAŸSž4f4†Dî ¸«¦~Ô‰ý*·(”Âdzc Ò}àuTèrº $FÆd`ˆÖ‚¶bqµ}-$îÁhÀÕðîy¥÷ŵ$ÔfJb,}¥µ™!…åE×§ u­§"ÔéÏ XÅe=ÐËžBg†Òe˜ewA²×üüªó iØÄá wWh B’\¸:°¸—Ø@"Œ=­„ûPo‰ཎ¹™(€ãó‘›y8àP­­FLjÊw@4säø?ÎzSS­t\ÁnîqÙ»]ÓÍ'ŸÁϨvXl,Ìk$´´­}1xú¹©$}Q¤iRnÞµ¦7”’³“ä4w“eŠô oµjˆØ$¹#è‰8 £UbùQÊ’Š@`!^«áéþÌn<uÂî8ŠûF:Ö˜fÊ>c¢3ãÒԺ逻 bë˜xìo¼I‰Ò �Œ¦6osç p¥êÆx}&r&-/,»”B…<1Éí‡&%€½7`h%/€Ý€8ƒÑtä9tÃú!¥R„�� �IDAT@ÁÚQt, “OÈ©¨Ð‰Nálȉ1‡Ê‚ƒg0£Ù7BÁænª4‚p1Ü‘“Ø\ݶÛ$ú/¡çø ³®Xjà¥,•‚“¥šS?> kŒÅ‡Ã¢•#.šy.¬&ªemPêC% jˆ8ˈE}AH›+'ãñ÷¤¨°k è¢+¿kK¡FÅ%ƒð6³œÙ ÄT – Gw%gQ 0Ù5/‰·Hg+Ôž(´—5ô0NýÑÉ$QíÏÅèü ÉR›ìHš1|-Bï¢aJI©6Šêv•%¨·™‰±äÔMÜaýmáoå¥Ô�ñË•8 Ð1èhÙq\|bØÇN Ÿ=EKHµH™WPö9Î'$AÑΘPã>îZ¤"ƪ—ÐÅ~uÒñopj±ú’W¢Ó…D++‡÷|)9WÙ³CÁ×uú†„J\\g² ÂÜ“®cjˆ`zrbrX£ ÝFQ‚‚8¯?²ÊèŒr¼Œ è¯ø Ò4ÙS B™8uWଶç;©¦Æ¤ôû0 %£s‘�tôß7r¿±Ö|ª”箣‡m´Éðeåð‚÷H`SY­/ŽhûÙdÑJtãõ$Œpé‹ð¦¸äõÚ©V¨”À¥C¢‰¢A–&×{•K7¬1ô[IÔñ)ËW\Ìœ½ç=Ñ%^>6ÛÄà¢Çp;Þ¦YÔ»@?Âðˆ¯~õ ÿiM‰jÕ$¤ËÈ<gÊ¢BhTVctõYÛB-QŠ·4.T$ŠM’—©d^ôúJD—;„0>Ç6ÚŠðâS°üØ"”Äðœ:.Ÿp™BÝ<¸8 †ýÌÒA¿(«åÏ:yƒAŒ28%–yèDg¼ Ô Üz± S Êé*¥‡Å¾d”šˆÚ¬¦¹O)Vån­¦›tT5Vd—Ëìk¯gˆ+ÆÒ©¯Šˆ²Ø•çêäâ3bÅÂs‘›þfwm í|zEF8Ë«IO¬­Ùb)—†´—UXåì §ŠŸ\¦b'€Øõ #¸u¢Ù•ݯ$ÊqÒ´£¨èTU®vV­¦b„µ—�;FÕê1æÇ*,z‚PR¨›¼ª40â*Q°D¸v@i(®l5"|8jm⾬4¿`·Ìñ�%À©J·NQ]×sÙáMÈš>äJ²` ÁfwÅYš˜ŠìJ4oÁ£ÉÈÅmy=ZÅ\¾ˆº$Ä’ Ê-ö„âÑ*ñT·Ž<µÅ](ª¤PŽ4 串7äʨý—dó.›oÌ–Ö‡ŒŠ×ëÂÒëÒðJ8C ! ©œès¡fJh>§“GDÅBy¼4y…»CA× íhˆ‚ªŠ°n[—V¼fÆš9ý¶ºŒ}¯Š{uج±Xò ÎP„r—+ʾ¥d{­ÎhjI%hÈv‡‚8’î@êòe4F£o0Æu¢€+(Ê!Æ 4¥åpІ ÅCôMk¨­7¶$QÂÒ9¦ƒ¶ Uqh|/^¾ï‡õ0tu¯S}µV¶‹n¨¤Ã—¸”ªVL€ $v•k«ÛXëQ¤„à‹ôÄX ázºñ!ç©=x+M ¬¢îy~Qã’§E»÷ò24K«T�*¡f‡ç["X'0É‹÷A¿Uâ0{ƒä±±b±¿šc©ÛÖ]Ô§Ï€ØMÏB'OãNÐBR€ö¡,£ƒÕW`%,•æÕ%F#Z¡Ï1þªUÐíã¸fF:Œ±“±1¿RIw(øß ö>ïÓ[³þ<G ág#¾‘Z¹nH±Š ‰õ;Þ)ÁEˆÎA°~˜qÚ¡&/ï8ýÞ—Òê]Á¡W%'ÆÐU½ð¨l‚hôéÄ«$"·½ïŸ¨±ÅÈÜqhR¼Ö0 _’Ô*;ÑIX\ø¥8ÙP«5c8xhʱM?ݬÖ îx»ƒ· BÄú•eçm¯³±DÁ¢$r¸…4‰Ð�g(cʼnL¸=ÍnಜÏÈ%’!½åDsâó ÷8–DyÑPqBbL:&!„gªª ªÓˆÝÍY7º ·N÷zÏAüþx¤y<æ^í%ƒ@:KO€ê¤E1|qç(J{Å^Û­…SÔ©‘¶Æ$¶‹¨@çÙ#4;µ A 7*Ÿ=.CE?h²%F•m:ï‡åÕbUàâÂŒn® SÌûÜ(†{u%²Ã»Í:ШE™qK¯´¾pŠ( æä$j“>ŸUË X¥Pë“$4u€¡-ÐsÈ•S*1¤Xü'"lªêAð ´[…Q¨‹‹1F$1"³Öñ  eaÐàµV¡Ó[¬¦¤Ü–ž"íd—µú}t`ÍG9_šˆš\«‰N® ù,tÑ5]r%n Ѳn;!®Qœrp+ž7„KQŽX6t,-˜ÉËÊë|n⌞8+pÚƒ0 (óÉÕ˜¨'ñ¦±ëѽ8š†#]¥èLùs·*u:1¤(Uq.°––¿+Á¤Ð‰0j«) mçGE¢Ì'±‹7×̧ÓeIbÇÒM7ç8óŒ†ÍãJÕ“VX@ö4g•¢„âµ uÆe%ÒѼïNÇdAßçºG«áø¤ªç–Dp$ H°ŒUÈÍãøZ ¥n)”¶ˆ:«É©M=x7qt$›zÞ‚ í…fžk‹zZ§Ã([‹·š<ÆBÚ�¯y]UòuÙ)¤Ÿè'¯¦.ÆôêHp1MÛ_æÕêo^6Ô‹/6wá¹Eˆt¯Ð�ËJ!’¡<R'¨.…#³$ á˜�"‡™¢ß€pUz1i²Xr]²Æp§Ñ<—ÃÒYΆ<ÀüM ŽåÏ+ìÑ]Bèãaé¿tÔ%ÂãˆÆj 1¹#–*ÌXÇÆî¼…ï% mÇ;¯£{b ’ÀÛËQá>¼ÅÄQ‘‚“‹æ¡c@ ˜ˆ‰aÒÍ>¸êIý=Ì£\188*HÑañ7ÐoÒŠÙM1Ùéù´€UL4ÅC瞸žCÕ4©™Õ.É,G%”ç¢!vèöA(û#*‰[ÝÆì>fÁ3 é³ éì…ð2yČӡsÿ8}ó z 0N™÷��Ý݆kV•ûbwÃcoÂù.WB[Ò϶ýÁØÕÓ:Ãw±ñe °õç�¨Ý½ÕÞ¾¼ûDâ˜pÙ© ¿QVúSkÎ7äbŒÒw’}QJ7¿ ©ú Ðb¡tÐ ñDãk‘Ÿ(/Îe´q5\nM>Âm6¤ÅV·1»K# ñxç.8 /Z¹Ì ô|Ñx¸&|&Æö®ZAi~¡c?‡ôü –6»è› s)f¨º &ЍíAŒ×ª5ß'z5„$–ØÏÏ—Ù=KLóܰ¨hòzƒRc¡1Fº]LÏ<–$¸ü:â>Ʊ4ßáÊ $†ñC›KÁë7Ì>™ðÔpô„Ô$¯nz X¿rÖo×ri8%‡€:EÏyçl):“I½n ÍU)ûÏß ’ESÛs:…br7—ëß¡03t@(y¬–Y‹Z;»U–%À¥5±ã"U(BVœQmEÜY³–4è¹Ã©˜8Œ&Qõ úˆ„Š<Xæ¡”SZ ãw‚ùy–è¤]PÁeg•ÏzrI(Žqœ HÏ çR’è~¦™'Ą̈‡Ù»Ýc­:@AZÝc”"¼;Œ}¿êHDv·°P¢&¯¡4ì !éÀCÈYÕpÜz¢·™Ž®  â&RjZ#)бD<Âß4—@¥èŒéFšào»*1õ±_CwQ)!“RË ½É WgWiÖ!g½¥ N”1Qr†¤ßXý»Í°!¡ÖeA)[¡‡™±å’ƒ±"†Íb½ÉÉaϘ!ÑÑ­©LZ¿ÔT;€u2¼ø“±ÂÉÀj×ÿ¿½kG¶%¹}'Æ¢Á:o'š{íA† ®Dk‘¡=hÔ(B;'‹r´ñÈxÔ™ÃÓÝ( ‘‰ªî„BÁ¹ïÞþTWá›Hèæ¹Þk¨Buîé¢f k[Ç9ÂFz× ` ý+À”£N UmñPöh4ÔŒ54º'¿.eiRDc¬ÆPVÌw½ÙØ3H76)ð$׎Æj2 X@Côs£;ÀHò”чpžÄ´’Ô×IöŒ‹¼ç7õ3Aswu[ ½ž§†–¼šgõÐí¹z˜È<y+3†%p ß_WÓ†á*Ü1¾X¿!6ãÓ\Ëšl´ù•Ä,¿4 ²áˆpðêÌÉ'û縻âp¿íË5Ø”#\ÖjX©}R¤ooXsþÝ%Ϙؚì«È_ï:¡+I4št¸`ø+]."m’šêňl¢Î„ìÜ rú±>g ÛLGöíÜ?Ÿ˜T¬iʶ¦³Hò‹¹–&ïÉ›ÉÃ!jXp%¿{fJd4”¤?•sDƒÎËìaÏg=d‘çõ®$uœÅÙÈ5Æ×ˆÆ�mî wò´CÜ:T5Œ‘ÄØ¥>”Ìøï�Ÿ= …ëgàÓÕ‹€é¡h†ûÅáoY_u"”›+¦7;²š ë&é¬F œG<›Û)Ujç@D]¡æJ {sprl5?w9M„³{DÙ<ÑΩlW_$¶¨S¿¶º˜âfÌóæ$º<k@~¨ñvŒ¹S?NÛÿÒÖrྠß›æ 4…\+'ê*„üÄ Q‡äG%¿5eé•ÌX&ù œ2ß~¸éé$ú‹°ŽUËÏÃß<d‡Å†‘4<ÜTGf'Ó1lý×7}AËéP²zIçF“DÏõôã.kư„x(¶( "3ˆ)âÖôS•GÝ:çEXàÒÝàp¢<°áæÙ!žB”eJÒ“Óq°ê^Ýô¸ZSÙmÑFúW×~`¤yìk®hƧL£‚¹©jMÙTå‰[ˆÒ�KŸ©(å2V3hÓ?\þ :|n_ L’TEi&¯:Æ0€–î4z’‹hÞh<:$ª Ù*bÆfï–ñbÌÒ¬@VôàLÃzæCª*¸ &°·#¸�†ÙãE(íë]ê› ‹Õ+˜?þE%û¾Ðjœ™¢JõÒe€^ùa9…Ä넲¦˜‹óúÃÖA¢u¤O¤ ] óíŒkž-W%#Ä™±E!ûò·Ó Ft´rp N’èî4ØÉ×=š ˜›Ã•ß¸$ÃK(KËSÂܤë<lµÆšRèãé 4‰ŸyõS̘ÈWU7·%?íÄù¹Àúw2nH6l&‘80žÛ©è39«?m?9[&æ¬èœ/ÄßTœŠÓF|S.›«î« ›Ö1c•}]!ÝQùšvˆØ ®XIçsú«‰”Áz+ ÛV˜Ïi«9»M‡Zí,gÂy)'¼žn¤]t\Ä€îP°ü9ÿÂ^©è쮨'NÜ~Šç2G7QBSÆœ0+Áøø%Œ‘¶CÔtü¼¾Â÷|`&ju>*çBBξf}ê fãz!ꮀÅf×3c°a“&Ðécˆ¹ÿêôãWÜcW°’R…»Mí…àÄEÏ_�–1º�k'’}èyÄcôšÃ¸¹€úŸî{ÅÚ˜Pª4,û¾F3ãs/ÚÞ´V:q•¶Š‡×PT›ÁŠ£"`× ²žÄ˜½Àš½™áÿ‚!îÊ!¸ÆPòÊ=ü †å£À+=3f¯] ©å¼Ø<qå̤òËXª'éׄ)Ü\YýH:w÷X‰a’s˜ÖžE—„#‰Æw„âѥ͘tÂ7•ß *Hø™£#N¦ÔüXaq©ý‘ë:™‰Ê»E.ÞO2Ì1äbSÌ6\Iñÿ¹t`Þ¢f,?¹5ŸmКè`9„BtÙ2jÆ<u:„ž3y¦³V3Õ›#E¼¥ç»*L2–¤¤[œæ§ V”q¡†ýà™g–2åý¼·¿½pßX²T[ÆMÑj ¯:\ÈŒØ(ö²£Šû Û韞ãô�ÔežÃçô{{{$¤_ÏF·7 Ža® aãÍC"–7àÃO*‚°c(òâfL1ÖaFyðÁ%ŒàÕY%4éþ×äÊÌ6QcZE{¯]p¢l¶äPºmD†²”’Üróü(¯“ܨ×fñ�¨qD€(çu¿ JÐ߆U<oŒ¢¦¯Òžœ¼Ñ”éP”ø&SEæèOÕ·°–˜ˆuÚ á´” `\ÓycÄ¿€;KkБûëg@H~–à¢$©è Ô†6D½‡²$¾=c‰ëÍèJñ\=b,iÆ)±”C´nXwø êXC XZ2+ÃjÞ-sFúæõ27œ8á)‰w¢ôØKg8˜1?,V›üvœã#F¡¡ÅaD’™S:Y˜å •é¢ÄîR+ŽÒ%̘'iF$òЕ%çâªC¼:ʉ¼u÷õBú¬?ãâS´ä\½F×¹Í(ú¡+@ D ýFËnHzF÷žÔÀ ]ußQp‘¡yXh54·[:¡ P'癦¸Îˆ²ü4ÔÊh#Ÿk=ôŒEd]@¾ä¹»tho²Žk"¤Ò/‰T\Ö«½.S'7ß  ‡Åè0.5”GQ–!ií@$ä}DJßÒ°ì2cû åÔw}‡nyÿÃ+Ø%Ò�¡ùɨg>I —ÌÑe8i0âvÊQ©¤ *û”!«0€Q'$]ìç‰ö«'Î&R,Jñ€®áàÍOº ùy±A- ൎƒ Ì¯a!’§Þs�ºLgäà?áš½¹~ÛæžŠÂ O¹& ƒé½Ûð&ÏôðÀGoYËV;ábÑVh©ÁbÐïb§}<8æÕОÐÅš=dq †(úß®€Ã"ŠÅ&%zœK§¿EduÔaÐëš”%$£ŸLªîcQ3¦ ÕMê :~& À¬{¥"N("Š2-NÚl‰¹‹e¸ ð2·3H>’Lê°ÐÔRÐcÍtxºy»@4Æuä)Ÿ$¯vém­ô+m›„ù…²Ãx‚5ô(déŸÈÚì\pÊ�ñ|hX0À?]O­ÇX•‚|w›Ç\Z&WE*Âm•v•ˆëìÔŒìËœmºvN‚w̨ÑÐ] ÂYü Þ€X¹c“ó‘‘Óš£Ì£Ž¯tnpt˧!ÞÓŒ´³PšHò>8vAé€+}0—¨mMEi¾1)rsD�&ö? Ë6^•—ò犈ÍS¶œKü¨x_ÏP!cYNsQ—0c”*w46ªéÆðSoLW•¦ÑÈÀ„Œe”¬/zÓÌЙý(�….ÎŒ©Ëz¿ Fõëƒw;Ä ß1_šhóðÆ²¬hÆ zWmm’¡œß+¾!Œ‰Q`Œ€R$m#b!çé*îÔ±Y¤'&ÊœNäálh#*qœÂ…�€”Þ«ãŒiò6¯€ü!¤I®¸7Bû•…PØŽ�¯¬ö£<4p =àIç±O%°‡WkŸ¼‚s2˜ˆÐ¶QÕ–Y Ýï¯dç®)Øâ3&A±òù¶½\†x°2lXÅÛ;Œn4oæ† Se"’èŸè¨ÂŒö‰ü¬Q–£ÐÔÜ®[µ½¡EQ@›†×Ô ‹P´‚…ö¼}…'@,ß„@Ùê7ÔÂíP™E/Í"Ôð÷ÿ;«™lòK…Ÿò^ŸYk?ò[G3æW$¢³÷ƒÛ!Žõ‡Õl!J[äÆfɲW“+j-q 3†MêÏK¬@ñÛƒP:šÌä=¶–åyDi‹k8ÝY‘«ŸôaÈâÆ S¸º;Yn G]€Ã$b~Á> ·Í»ÑÅ8‰ú=S°©Üгzõá(¤ØÜ†.KÕ @ØÀ9±E¦©øô•z°XTj 4Ë0לÐ:4?XÎÿW7¬I#?ØgÁŒ‘<ÐsòóÐ) IK¿ˆÂâÌÖÊ`Ãü?u=eâ3+^$º²CšIʿݔ-tÿh,ÿÙÔþBh»`Ü€º`hÍ‘Öê¼Å ¶5#ñt#ÊXœUpä=½eÍÿ‚³æ>G­c²Ö _VÈ;ú9c3§7ÀcãžévEMØ:eWü)W ˜`ÅCgM#ÓwZ÷dˆBëIYêY«õ²®KªoSÀ%ŒzÍ"ýˆQ ¬ÀPú§|¯EÈG'Lr*‹|cƒ:•G?:¯óövo=# Ø(;Ed6 V½‰Sô¡ö€{B<(.¿�<üQH…‹¥è+¿—Ó``϶ :±,+~gVŠØÓ9™)ÞðæT[¬‚0ΙÀNÆ€k˜± Ý!bg‡×µÇaéÛÓ¤ )¦ž \iZ20ȼ¦Æš(*GÊ%ÝšYôöjÊì‚ãó¶æþÆ.HíÎј'üÛ÷‡¬¬¬2@´‹ù‡]6:ËnVµa„ðpaº©`u¿bq3‹Œ¥¾óÚp¨™µ'r�Ë‹Á=¶ø¨°äí§vÙU1¥£ÿ’f,Äûgħy6ωGÎsö2c&¤3¢¡žHaA[’ï Œj„è÷„ÆÈå3+#É2ߪïÎ5'úLž—Ê{ù™fDÛ Ø{T„T¼D¹Ây†³‹@0·Cø/HÂÇ#a+r¨3#%ýÅÑLNø¦Ø]jØ °·3 ž‡_ ÞHSt]æ!¯gÆìЬb¾Ä‘c£ 2[GôÞ¾NL1+­„9zÂÊ&²–©�¹›y–_¾*)&š Ö§­@¶¨#Vã+¿ìæK—N׫ø"4O2r¶V¡:ú$ã›Hzè•XVn3eÿÜQ•†mËÊ »&N*F‰kùxXC©9?À,ƒŠ¢]í‡<xÈWh+hØÙÄðf"\Ã%F×ë0è@UfñéeÒA-Ø¡<ɬӛׯ¦pI:Ô™ß£Ò XfZ}ÏEBú?ô›ùO’“)ÆmÐnÀƒÊ"¦ÿYæ!ÓJ1x°šQ<Ë ÍØR®ëi2÷[ø“‹žžóé?ó"2‚30 p¡ìSŒg] £½.ƒ}G#‰¤²o×)V\R36%çdÿÎm£±Ðñdc+™™K™jM׿Iû—×’«1Vl9Òá‰#t±·£Œ¶‚•ÀmbnR¸ UçšP.Uß¡ïÒ<wªMÍ6ú%”Ó‹zvþ• 9´‚ƒÜÆY¬€ÜÍkX"š€‚ G6Ü/õÚ,_9†Rîš^0+ ’ i�úÄ ºH¸[ÿÒÑX™k0ÔJjÝàñ<§]ˆªÉûqŸH5D÷"¹t!¢M[ö­éW3ø ò;™eltŽh¦ÆÉà2šz o¿¥(/dÆè9%½Eêtã«ó¶aÆð~Ä¡3´'æ²ú3k¢°Üe&?„~®9ø*³ØÐ–üçΰg)xÉY9’{Fc"¯ÓSéÕuø&9X¥.d=‘v”þ#ê²HˆŒY2 Œ”�qCzÅ9Æü÷Š62¾ý[ ~ü29ØÍ N4¬ß3þ¬¤b4ÚØðÎ.ëßÄ0ãueuÄÓ„tP#Ê›úVOĵš )IŒ�BL›Q,â%:íÔy£dÀŠmº»÷£9EXSÆC°´'¥ãÛÉCè'ר”Yþïv‹ÅÜáxÑúÛ¡Û²UĤκ'‡~ÑÓÑ[°²•Éêf¬†HIJšbG$ö Yg¼s³ŠÈ8°CȪ›æ‡ùJvHéˆÈtE“–h—ÜBž?'LèC!Úmoúq¸I4&U¢nÇ)‹@¯KÍ}G»•ef^SÓžhÛ£[k!^K­Ã" =aMe—>îy‹@‹CÛ‰øÅ‰v+Ÿtñû—.ßÀŒ)|�T懜Ááy¦ —÷ã�‡÷ZÔàÓˆ©*‘L±Æ:I,%ÏQYL™Æ¤ °ÄÎi½Üû îÆàÈ&ëóOº½¡”]¾¾J¬ç½éôb¹‚”Î6"2§GE늫† mð7~MG²LW Ä‚åüúö xà᥇â&f,9§£€iW4¸xf•t€º(ÆJ_¨£)ž®'Ò“ðñÀ ó¯àŸçžyÍüvÚ×ÂY»Ë<ý-+7¿çN>©˜™i¸¨g£I2_W Ó(þ’­Í@Þ#éØ?ÌKFÏ;|Ê8£P5@î5Žÿþ¿g¥7õüþó§Ou—ºÑgqÌl7â~¨ƒ¿¨z+Й®ììý:o¿y¸Üü™<0ZÁL% ò)¡Ì\(ì0 àNOµý¶hy¶j¢ÃÂêdU¿NfìÎ!ûɵÇfr7ÇðØ‰”òñ“ê=}<‡.­áüÄÅ`zOF´ -åÖl*"¯ ¦ë²¾³\œe;\Ç_êŠfŒN¡–¡¶|oâ›ö¦À©Ît#±0Ù\MG,¡{®Sƒ¸ógŒ04JçÁ͹åÃîè8‚70j�Œy<™(žŸwÖïÁÅÄo£š%ì œB¸/aƤ(ƒJ?ë0®È‚· äÝ©ª’´Uÿ£’šÏ©žl¬|ôÅ)@gbØTØÞM0W¯X¿RLJcqz$ªú]>el¦îú <Lÿšwü®_´½ìYZ+®'é³’ vÜ|7t[íäRúÏ’ñSÔÔ9›a3I ýáûå<v5îÊpŸÑV0:+vŽêe vÌÚpy£è’®ÑÅc!±J_êl|=ç‘×YÅfÕC>µCj㳑¤À·ž;œ3ãc¿ÿÑÔÀÑÅ2†y³&(ÔÄRÎu¦e§˜™PDæ½B¦XÕ(cS´_©1ì¶£k!"ôÍ'Ü= kFÞÊÐÌ9L>ÑŒÁã—ò à|ØQЋâ¹k�� IDAT&ìQúa£¯]gµ’8Ä™^ju- |¿·Ž ûaà{ON#ò7éç1îÀøº¹1üÊŸÑ+4hS”,`t¦ÃFjHk¸ñqsJ´q;‰MOnH 4I>öp ñÙ§ô$µqÒõ¡+Ï2`DˆÓ§´?'éC»˜*B1`‹$²òLá\gÓ(R:lûG—`zS±òùÐØ�ÉÌ䥒ÞÞ�8Ÿ¥Hž ¸ùa"™þkÅk™15x†H3î‘\«}ÛÀdgº¿3Eì³èA1Ö/Cš¬&·u¦¤Vë±…#fxoœ©È¯ËCS2w)2OØÉÊÈ%í}cxîêñáÀw}ã…bU_Œ36ì1Êëw5+JtÎ'Ì'Éš†³ Úq讳â~QjZƒÕ7‹£•¢š’“9é¹»™18ˆ•pD è²äÈùµ C”÷,ÃZ[¸x–üÐĺ&+D n¡ïôcl‰0%Ý‚äìŠÇY°~M׫~¨n26“˜²)K£cJðaäýBÃMÉœAIU%ë ôÌɬލ•Ç“F¿F”êÜäDG£æ©wga¤ œoϸqg#moÁ#$(Y‚ L?;rØØÌ²à Kzpd dM4¤ðñ`âA”5÷ÓO´ˆ®–wüšÓ§¤wÔ$ÇA$½^€•ñžocÆ NÚ"l[z:8%Dà’<ZøŒ(¹¤y§GŠVU@œãY‡ZÝ–GYv ¢~n‚Ÿ„S1?úþfl¢3˜Œ‘‰“´ˆç2¨Òê—Ñ=‰åèH¶E†(ªe¢ #¶Ò{ L(æˆÆ+þ·°áH¬,`<"w3õ‘6c®Õy‡U–|ûg&¦©A]r¯£sZϲ…N›”äÐK>§¡\(Äz¢iÔ™ ŠRgš>K¨ o³0&¡K}îØLúá¤xˆy¦œ } ³ L*fß1D@óž¶D�΂yIêH±ì€„<ãÐ/Ó'ÛÍâ ¥µíÇh|ÇH1Š+[&ÿ.T$ñ2¦=sbán3hF± ¥ƒñ�ó¦˜ÉÀÍ®³�DÀXyÌEu¤d0™tEhåï9ýYZm à¤m½�[Ø+°¶¤Ý|X�˜@ÄÙò¤ãè}Üð‚gF,âc‰hw(çˆk8‰åéÄKxÏØýNoê·ùÝwŠÆ�–nàÕï¹ ç| çsX@diäZ¦›üĬ,ílhcORÊþÀg]Ê,ù-=‘½)CL =RrŹÞÀôõYhN9<,uf�n+ñV8„SG�‡_Ñ6†Œ"ðÃs¤»‘x  tYh¸((Dï…-– Þ‚˜dl‡,õmÍ<.a;ªÃ{ˆ”èˆÕ¨²ð¤ÎBZU×Ô’Y½¤ŽŽfØ`M­nâêzŒëy i–&åÞщ^ý„’‹bqvo…ø—7c5ŒÎ‡aVoµmV±4&Ý°Ùæ‚–¬áM)¦žQ�Ncç(ÅZ‰ŒßÐÇrîXƒŒ{$'Ž.ê-M×]ž° ûТ‘T$füf9w¬Ì•bÝlÂå þ«¿ž‰×7tðÇÐNG½õʤÀMxDú³:b”LZ$ËZÆŸc“¡†D¥sM«C›1ÕX¡6Nœ×·`à„ J礛¬`Ø”J!Ë·sJŽ’["%¥®�ù³ ’Ι·8,Ð2×ÏfiÔ6c+z.QÏ›U«МßÓ¶ÇÍ…Ïlìæá5ó£j*[úBÊ]d«^¿T24ß é¸ˆÞ›b%¥N3a<Ps*ž­¬”sÿ÷!ÅÊŒãÄŸ³òþ^c˜Ó£ B¬L_¿n³ü>WL>SÜ:4–¸Ó(Ñ…VŸ2†-„‹® .lÆ’yáPõ…‹§—1¢š¨>š‡2ù«éë0üîÀEþ¬Yª2„1‡E1ßê¤7ºe¨rßöIˆ) ³š!Wì;SÀÉyÃhìÆbc´’¸€JŸ7jáìÖ¥YìŽg®5Q\®³tåþ•é\Ͻq1p&ca%̹yEñägà­9U`ˆø¨™äP9n £o¸ÏGë\Sý¯îØ™å^áX&]ÊhõC3¶8KÑÐ: =N´ê’ |m+¨ójˆêaØÑt7iõW "û«>ìÚ|’g¹KÒaKDóÈt´%µ²šÇ/ªUã‡ÎjîtÒT¿µ¦×Àœ™’<[QûŸ5BïãÚŸY9¢éM9@ G|6g£ôð,‰¼H:èñ,ÿsè/2CNúÑÁè«y'ÄóRÖÃ@ÇLÖ7êîõAјtÓÆËÔûûlB”NF¢e”Ìœùž¡o§ ‡£}Xã×JÏ¿&¥‡ë“ÄʪK°žJäDýK,»R0h\O¢Ò™ûб™”%†ëÞôª�WIù} ›2c' ž!ì]ìviŠra¡W8©x‹Wû*Å[Õ|—hÛ¨(dzldö‰dTÑn¤;ÇÃf8¤3»™R`³Sjú½D‰³Q„g“ d(Pš°ví¢^‹L–2áéâPҪΑLËNÓ’ÈùDˆÖ±!ºµtkÍ7t]ï1*°3¨2~nͳ1hȺä›#)Á¨´½Áã…¨¿²ÇSŒöûat}Š4RQq¯Ó°ÏpL°NZ¦öÎ5Q0@4Ã$Üô,ypFâ\O´˜ß •ÏŒa�|ð@9ÑBcÛ[¤?—áhdžE%žB´g &1GxÎ’^¨ýVÝÂAÁž°4ãk ô¶JÉ6G®éª¯i•yoÓTGc«x‚‡ 4£fnY¦.•165Êhº6›> •詌l¨èIBý0+’_WØž„s,kd%ñÄ]ÅþÝÍŒ-ÂHíw¢ÏÌdä¶Âþ¢±ó-\ù“yˆegYdz×ñë.s?±V„iFÎ%‰rò¬†ŽŒ?CÝ;Ýcn3v ³uزé^-üâ¶kYÐPjZ€#§ಟ×Êà~e5<et=q�'N”K$2tpó™t‚º“aÍp­!„oLÉTrW×øV¬‰yùe\Íy 5˜GÿCG>Ë.‚Eª§´'z6ùr N]ËP}®›2ÉBÌà€g7Dc¯!w~(×&θAärËòº®pŽ€¯_vN'’-aN›ŽiþfÉÆ{š±76R‘qRl¯×-n#àRÁaÚ*”`ñßR;™¥±zà¸Ü<5¬¾°*¤Ô,3ó$‡§rGÑIxY'býúz›1ð«„*eId®ãÆR@€ZI·ä´2ÝÐþ«qg®ÂVÿ fRRŽÖØD‡e…’1÷’Îð!øŽ­Y<†s˵",”þÒ¥,üÅí‹ôÐóH±�[m¡ ™åê<Ì å®¹ËR3­¦ÍØ•ìÖ õŒ=÷ÚÄN'МÂ&É>j¤ Îy¢<›ŽˆËœréˆ(§Y'4•R2rSfJÜ&—øqÑÝ÷z÷å®(Õá¾æçl +F<bu#Ê(᳟¬PuÓñqxJ•~çi«$ð]Xã‡Bf¬€™å£b©6c—1™Š¿RpmÀŒõAdärö?lߢ’Êþ¦gæ6`QîÅñ9Ä€ƒÎ/1ïßGÍÔÕKCØ�D,Èù³ û¹MbIÿ„xE~‰5ãôÃ3¬d)lÛÊ,bƲJà7ɵ»ó™¯ÙLX7–?™»û¹à1"ES”3,ÔYB3æùÎE[}KNÏOFí®mìd�œPáŽÃý@›×fŒƒ“m¸³"YÆiõÐP&-fãF!Cô[ÓФ‚“œ xrÛÂUŽ‚<<”8œÎUí4~}h4–Üê’ƒÂÕÂ4i>)gÔ32¾gf™(]üöOC¢dºE—6fyö¼š:º·÷¶SææOåý„mƊ̘s\=Eµmh† _§›ùé$s€¡xÙL/e}VF€} 8-ó·k‹ÕfL¾l%tï‹î›o¥Ÿ ëæN~î¡ù¬lVƒú[& †óÆüT2ÄCÚVg3öýßöçíW8l:üÛŸ·_ã?ÎègBäÔôB}ý9kõÜ©ß×ççí×çBe÷+ùú“èšü¼ýúõç¿ù+ãú‡¥Ï}÷×<»ÈÛožmË}sýs=_Ê4 ÑLëƒYåýöûþ‚Ʋ¼þÐXŒ5²/»­7+õ¶ÒHEÅ•‡ =؃̰¥€�>þ¦yK³/.HcϽöí(ÖgVæy©þ÷J4ö¹HÅhÂ!s,)e¯ÐÏ&d!W}pá Î%*˜åÙžø~òÌ;†Š¦jÔøULE›´6cˆ}ºÊ}龯 )\“Pླ£[c°þ/Ø!*>9ÿ|ÊpóM‰jãÔfl¾[äÄ‚K]Hy¶hŸܼ͛€s;éñ A“*Æ¿y–†ãôœ+›ü–6cÓ €º™ÌÿËC ¿“3"4ç…nE’¹ÖYºì¾Xî×ÿ Æ×ö ;Gšåhг"ÞÒfli#g ¸{¶²VòÇûþÍ‘—0úÿcLê,@‡´9k›ê7ÕØ¿lðSL­DãûbÔl3Ö ÷Lc9£Ìª–3 Gÿ°�¨f¨3ŠFÁð.× ”Òé<¢o+¸¸û¡W$H^•ãkÃÓwùÞjö¼ÔaÖŸ¶ŸþíÏc|ù°OeøkûóyÖžµQ“uû~»Ý”úÖH´ÿ§Ç·¿¶£}ÿ™­büyæÊþWc‡ïòý³z^ÙÙÂeßzß–o;<kû#¼Âçh9•ÛDc!NîèøÊÕ¼`¢¦³Ýä=±ÅàVÍ2ŠI@ßw÷†¾ÂV5 ól$؅踮µE[nÙ~Ù[´ÿO{/J#ã]Bc*1?×v“ßbÇ|¸0\Û;–ιxcñ0Öáðúg‹ãɼ w¯?ôô\0.ŸÝèí¯¾«}BÂð æò\o”Œï[:+ÝÖ+Ó*.2mÝyÁd�DŸ"fH'g˜ýâ¬xØL»Ð ÂÉ:Ï7õ÷<¿æÄ¡e-+DcT”(Ð6ýñœÊ®l‘¹#qó+Ãzw'¢]±æC]Oiàî@é¼±¶1ŸlÆî“T„w6.üõì½æßì4£Q"ÎÃ4ÎÞ÷°}v;¬êá24µvÙœˆ¡ð,¨ýiûé5ÓÊ«hûOü\s 땚ÙßO6dÓÞo†3rgøt;÷sË=å¢1E09{$›öpøg©î›Ö0îÓõ”z,= Q$HíÆaVI²MK 7»¡c¹ºv¼u•³J|Îdd–\@Ø ¨Sy ªϬNÿÊ)¥„žÓÔ¶­¥Í˜JCÙ';<ñó`sƒ][ ýÒPþ27EaM/LǧÁmÌX·?ÿUŒòÕÜy,Öü_ëžÞRÃÙ?¼‚“éø°¾r8xÐ?ÿ0£&ŒJÉÙR&ÓÉW9,ÏW£Düº©á^Í\Ÿ "7:Ó3þçáõÑ–«ÊçDcÑÁ8®P`¬ÿGx¸yl›“ìfjÇtÑ…'²ß*žg8b›±×QKË%¢±K*:3 dž˜�«î°¨àßô×·\ÒuA%›Çh„€žYšŸÜ/µ2 OK›±™V ¾¥D¡Ë “Šð#ˆÀ4Kõ÷µS¾ù™#†[£ ýÓÁw {o³J\-mÆÚŒ·ŠÄœtúÉW3ù–­ÿPõgØXL XχË~+8k\K›±K*N¹ ÅŸ Uq2š:ƒŒ‡ãÅÍÝ¢®øLtâ¨Yšš;pëŠí€-Ÿ`Æ~Üÿóý—` >×yh.þˆÿíƒñ"öe3Ëû®çcö&Þè±äÙYä^-—–Ü·´´´´´kiiiiii3ÖÒÒÒÒÒ’÷ÚØ××W/JKKKK˲ò†áøñä×¾¶í‡ÿÿÿÏÿÓýgͽ¾Êï(_·¯í/?lùÚ?lyþŸî?kîUö:…ëöè#u‘#ÕÚïÿÙIÅ–––––»H›±–––––6c------mÆZZZZZZÚŒµ´´´´´kiiiiii3ÖÒÒÒÒÒÒf¬¥¥¥¥¥¥ÍXKKKKK›±––––––6c------mÆZZZZZÚŒµ´´´´´´kiiiiii3ÖÒÒÒÒÒÒf¬¥¥¥¥¥ÍXKKKKKK›±––––––6c------¯òãÉÏÛö¿½:ëK§þT-ý©>î =–{ûç–––––ËÉ×××\eN|€á¥:©ØÒÒÒÒrai3ÖÒÒÒr7™žW#>ÀðRmÆZZZZZ:kiiiiii3ÖÒÒÒÒÒÒf¬¥¥¥¥¥ÍXKKKKKËòòc/AKKKË¥åëëëõ?ŸÐ¾çÏuÀÅ}S×áM=Oòv)ã¥íÏ-----—“½yxU÷Šnè73cÜtø$‡—¾ÔS:©ØÒÒÒÒ‚N–iL^ª£±––––ËKAþpÙ—j3ÖÒÒÒrùÀèUõßÃ’ù_ª“Š-----–6c----×–3ˆÄ‡¼T›±––––– KׯZZZZ®-Çc†8üᅞĸT÷µ´´´ÜÐ’9¨¾/ü$ð¥:©ØÒÒÒÒrai3ÖÒÒÒÒÒf¬¥¥¥¥¥¥ÍXKKKKKK›±–––––O‘ߊ¿ûýþã¶ü§îEiiiiiYY~÷û?˜±·hiiiii¹L4ößÿõŸ½-----—“¯Çãñwÿ½-----—“ÿ×ù?Ri*ég`/����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/block4.png����������������������������������������������������������������0000644�0001750�0001750�00000526125�11332353404�016147� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ�gØ�� �IDATxÚì½{t×y/ú>DI)Q-+°[ŽqlËŒaFqÔ6N¡Ú'®ÚsCWµ+¶0N®½zÛª‘r«ªlʨj-­(:§ËN‹ GŒZÅlW£º±#äÑS%Ñ…áÐŽó�‘Ä‘•ȰlÓzQYïîfcÏì™!Hâ1�¿ßòò¢óØûÛ3û·¿Çþ>O.—p×Ç~ ƒÁ`¸/~ãË�|DW>üI–ƒÁ`0܉»>ö;/~ãËž÷=ôàß|û„Æa0 †;ñÆk¯f3#>úÇÅ çY" ƒÁp3˜± c¦àÌé“ÏN¢Ö<Û?wÞüê^kÁX—.^¾õ“仿yæÍ›wåÊ•_jMóïµ¼é¹ñ±Víàkã—oøÀ¯ð«À`0nÆÅ ç.žÕ‚ï{_ñ—d~ò�Í-­ÕºÖš±àñÈG.¿ëÂ[/¯{ðã _}ök‡Nkm[dºòòÅó7´ž}c‹o¹Ët9ƒÁ`0\ÇXç΃ÁI] 3?ùIó¬ÙÕºÖš±<FÊiln9×¶üŸ¿<Üúà{o½å—ßúöÕÙó|M-ò9Þ?»:§ñlk`þœyü*0 †Ëáñx<“×.<*­cyM?Ìn_üæáã##/.\ر|Ùõ/ÿü…Å]«€üõ§³?~_§ÿ{¯ž\ú¾Ûø= |⾬|ÿ·¾÷Ó/=—bi0 ÷1–wJÌáÕÿ«ÂµEéX„…7vüñ·5í×ë×pñØ¡.ºù�gŽeßÝŽTúPàÎ_Ÿ°K:æýîê.,jô5œ:sþõ·Oþï¯>?®ÓŸ‹òß;Úæ�øôßýû›ÇN‰ ï¸5ð½]ëæ7x½c'´oÿ•o}ï§¹�ü¯O}¢Ýßú÷_ùnòG‡\ô6ÀàœvR;16¯ã:ËsnèœÿЯ÷,×Âk¹Üè«oîÞ÷‚ƒÁ`”›² p@‘ÊŽéÚ¿yüãv§ÿÙ“ÿQ̵†Ó,:èXvލëº>ôúÈW[pÀµk§Ç[ý­í‹ç]<ò“ì±%Ý÷y¼ öôSß·°}ÎØ±ñ#cÇÚç͹mùÒÜùSW¯y¼ç†ÅDW�n»a^ö­·}-�î»û½‡?àPö­ó.¾ïæÀëï^²`Îо…ž7~ôógOÏšÓæÊ"䀜Õ"`NkóŸõ‡gÏjúúï{ûØÊ‹ÚZÿü¾ 4ð§Ä`0ÊOXS´Îa2–½ƒ?zá–„&¼öoÿø¦§¾Jo}ì¿Ù]k§cYoƒ¯yq÷¯ûÁs ðz='}ß»pÑå«ç[o¸«iÖœ ›¾`Þì…ís.^ºü{ŸúÛœÇëklöÏn>{ölëüë}¾f�½·Ý àÕÃoܼìú_½çöýÖ÷æ.X2gVó'~íN�»÷~óK{¿ékj ÝþÞÏüáÚ_ý`×¾o¿xì|¡©¹k×þé¯Özî…Vv·45þÇwüË7OüÁ -˜7û{™ÃñÿxþÚµ€?úÄGn~×¢¹­Í—®\=täØ?ýÅ7Žž°<°è-lŸóãWßÔÞ9¿jÅ-ÿ9òÊî}ß°¨}îC[ñÞe‹} _?öω‘#GO™:øžýþ¡Ž¶üå²>û;»ëž÷ß8·µåüÅËo;õwÿúí[‹gÏjzý­cÛÿáéYsæÝ\X²ð¦Ž–C'®xÀ¡+ £ÜŒUJËÞoGÿL=ùßbi½nyíŸáÙ¿þ¿ ¢‹š®µc,Ûn´úçÏ^v×Åìȹ‹Ws -­ÞKǼKŠéê;ç.^¸t¹¥©qËŸþþÁ·NÌ}åðXkK{CCàiô5ܼÀ¾üì_ýñï-îh¿ùúoŸÏÝzCgS£/—ËýÛ׿;§}᜶…?;ÿÖ±S×-lë¾iIâÅCêôþà‡»~ñÆÑ;Þ{ãC÷Ýùι‹?m¬}î¬ÝvÓ ßMgOÃãéhŸóÝ|ìä©ÜzãÁåøÛúÔίøýsÿä¡Usf5ÿø•_žÕÎ|ä®n�gO?uüÍ뮿aSÿÇæû[¿ûRæÄÉñÿÚ=þÕÿó+¯ž=«¹ñûVÍžÕ<úóÃξó‘; Á0Ý7/ ßó¾×Þ<ö•Äwg·6à}7Ÿ=ùÖÅÅm�´Í]ºdqÇ’çÍ àæw-=ü“ÙsÛ™³ Fùu,ï”®òX^{ë²#9çk7ÿý×¶|ò7�˜èJ¾áä"/d\;wòZsMï^8§©©©ñj±Ý¾|5÷÷ÿvàwÃwÞõþ÷Üõ~�xûÄéÃßyë¸çïY:»¥é”öÎ~zè埾öá;oý•»oúÚ‹s[[�\¸xé칋‹.óz} §Î^¸n!æùg_8wF}ÐŽü·Ô¶ë‰O-íìH|û{_ü—}Ÿzô[yÇ»ù_=<g^Çgÿñ¯3gî½ø³/m½iÉ¢ù¸pâ¶;o3«ùøøé?ýë/øšZæÌž}Gð&RÝ>pËÒùþÖÃGÞÞùÿÚ4kNàúëî ÞÔ˜÷â«ã^_#=ô¶åKgÏj>qJû“-O546ÿͧúoï»é§æÆF�gÞ9ûÆÑ“oŸ:÷åDêâùs—¼¯ÌŽ-t~iÛ�ä“›ÕÒ|ùâ9ÌmŸÂ›Ä`0“!/¼ž)\åñx­¯µ»›8níæØ¾-ÑÕºZ±Òâ¹–Œå°¡J{ëÕ+'qyÖ"Ó¹K—.]¼x—ŽŸ9~ýÜ…ï*¦³?|õ­ýÿpݼæàòÀoýú‡—,^¾ëÆØ³#¾¦Y÷tß õòO<Þ†ïÿüßyë½=·}ñ+ûÏœ¿ ¥¹iöìYž¯·¡OûÜÙ�NŸ9{íêUäÌO9”}s^Çu®ä�<|dÖܶ+ÞF�¾KÏ7ø<¿÷=w¼gÍìYÍâ’¦Ïì€#oƒ§aþu7¼}º`Ö›?¯À²¥‹÷~á¯ÄÁÎŽ¶3ßÕßÑIF¼ys[¼þæQx½ –,{ëä¹Ûõ3|èÈ÷òË;Þ»¬ë–e�ŽžÔžøÒ¾±ñó=ô÷u¶.YÔþÖÑ÷Üì½³ë”v&wíÚ5äxOƒÁ(»ŽUJ?–ÝÝ$ËžíµŸ}4,Ûÿâ‹ ËçÚèX6TyáÌø™C/œ»ê{÷=¯8™þ–Wœzå»Ís?ÞÜ:×¹«¾†®w_÷2®ŽŸ}ç@æÍ ö;«{çÌn?úÆ Ëß{Ûòë„?ÒþH?»µåö[®ÿÙ/ß¼tùJS£oÍG{¿õƒ×½ÍÞ÷ß¼¤sÁ\�/ýø•†‹8…«W¯úš›I(W®^mlnñêQ!¹ÜµÞ÷߸ò7½yôäß|áËgÏÿܦOz½^Çsòô;�®ï\ØÔÒ7ÐÙ!n8®}óí¿ÛýŒ8xòÔ™«W.çr×¼ >�ÚÙ �Îoó56{à]¼ °/íò•k;†÷_:ýö’Žyÿ×ê{{ï ö¼çºgS¿hhh~éàÛW2¯ÍimzìἜyÕÓÐí0 F•­‚^k« ÝÝ VA«k#Ú¹¾>ûhx þ õ¹“° ^»rùì/Rðx–|à¾ÆæÖÆ…­WoYyþÉææ¦ÆÆÆw½ÐÜýQçþ75úþŸÿ¾òì…9z*—Ãò¥�~ôÓC¹kWïzÏ»| Þsç/üà'ùõe×/¾¾³ã×zïØ±ç?ÿõ?¿ÿ»á®ûí­üàÛWá½yi€ox駇² –Ühíòñx¥ø9S#¯^½ÚÔØô‘ÞåõæÛüÃW²gÎ^X8Þç6þþù+xï‹Å%/¿òúÉÓï–,þU¡7N¼ÓîŸ}Û-/~eÿ;‡ßF.ÃÑ_Ž=ñúÎŽ?\û—<Í·ß²T\ÞuÓ’¯|ÿOqäü…KK¯[ à´öŽ6þöÖõëN9wöüÅï ÌžÕ|àÅôÏe,¹Ñ;¥7‰Á`0&Ã=†ˆ¿úƒûìÎüËü¦ñ*ë=UEèX׊ç’1ð/ÿñ›td0ò1õ¹vŒeñàóG~Ø1·é¨ÿv¿¾»hþ»n9vîd`î寯Æ\.÷úk?šwãºtùÚמÏÜ|?pÝâæ¦Æ§´ÿzþÃÏîoñ/¸çý7xö¿^øâ¿$(yT÷-7üí§ÖõÜv«ïŸ¾öŸ/½úúëGøÈ7ß°¤¡Á›}óè¾ooï×Ìš3¯±yì¢<–âùýâ=KÛï ¾ûÖ=øµ?ºpñrKs#€ó/}þËÿ§ÿþ»n \÷ÒèÁo%ø±Ý~õÚ5�.]ùë¡o¬ùÐ{Vt/ÿpKËø™³?=ôú«¯¾êiô7øI\ç/^ùüÓÿç÷ÂwÝ÷¡;3‡^Oþð••wÜJO<uæ¼×ƒÞlmi:sîBâ»/=óÍÿ¯iNûÑqí®[ß5{VˉSg¾üìþ/}åë-­þÆæYÞŸ‡­‚ £Ì”UdF½Ì÷öïþY5S¯%ÝÈöAŽ× º¢§üåÿþÖ_ýþG­Ÿkº1ÕÇúå‘£¦νýê -§”=³¤ë^ùa¹k×®¹óÖÀÕ«WOkÚ+§gÏ^´Ì¡ç×®]}ûµW®^¾|åÊÅܵœ·¡aÖœ¶9ó65¶¼}åÒ…s³ç-˜;•B¾xþì©·_÷À³øÝïó�ïœ>~ñ¬vùâÅr>_Ó,ûlÿü_SSsËk?yñÚµ«m —Ì]pÝë?û>€…ïºe¶¿íÈÏtåòŶEKý :O¼ñ‹³ÚÉVÿüù«W.Ÿxëð¥ ç¼Þ†VûÙS'r¹kKoZ°`Ñ›G~y^;yåÊåþØm·Þø…=ÏîK¦çw|M§Ž9öÌå ç®]»ÖÐàó5·ÌëX2kö\² ’ÉñÄ[¯?3~åÊåæ–VÇsáÜ;ôÄ+—.ëðÕË—r×®y½ Í­süKššg{ãÐÅóïä®^kð5´Ìn›Û¾°¡±©©yM £¬8}|,4¤5Mý§ÝÉ]¡_˳Wæ§ó::Ëq­8Íò ]+~?z¤PËD€—Μ¸¡õìϳ'¿ï#ðô2OCõ…]ç.ºõæÏœ9“ûeögO7Ûoãõz}m‹–^»vÅÇÓ@º¯±Ù×Ôâï¸Îëmð6ø|ÍÍ-�šš[½Þ†¦–V ×Òêoð5^lõ{<^oƒ—´¦¦¦–†¦f�ó-mj™åñxáñ´-ZÚ2ÛO½˜·èz_C£§¡ÀÜù³üí¾ÆfÀÓÒ:·­ãzx@dÓ2Ûïkl<¿^áÁ‡_»ù†ÎÛn]öιóÿõü˾ÆVÀãñ6Ì[x}Ó¬Ó9¼žÇ“C®n^ÐyÚ^ßÔ:Ç×Ðèñzs¹ÜÜ«W|�šfÍi_x½×ëóèoð5úššæ-¸îÚµ« >ºIcS“¯‰éŠÁ`T@Å2k-Ý÷|´˜«,£'J~­é óbÃïϾrn¼%°Âר¬Þ·e¶ôĹ#ÇG/\¸pùò¥3—ϵ̽ӾÉhkÍgþù‹MG›[Ú.ÿljimR²ÍÚ]/þžßYØ6oA“}Mò%sÚ;Ôû¼y\[õe|ß ç/^zqôÕØó§ÎœíXzÇëõx< ¾Æ9mÎCÒØÜ2¯¹Åò§¹J̶*úÂ`0î± ªDWµkMÇÈ*øÚ['gì ;rV;uíê¯×ëkžåŸ¿¨±yVËœ6/;– FáÒ…sçß9m2Ð9#“ùé¬9óšZZ«u­8râ­Ã«àLvûû\×2{ž×磸oƒ¯eÖ¯—#÷ F]ÊMe2?-þ’YsæÑUÕºÖ„‰w×=fÍm›5·ßfƒQÿ¤Õ:§¹uNm]kÁX¤cÓÆyD ƒá´úÛ 8§ïþÌ#,ƒÁ`¸|f· -öÖ0 åعs§üOŸzÆ©S§XL ƒÁ¨.†††LGXÇb0 Fm€‹Á`0ÌX ƒÁ`0c1 ƒ‹Á`0 f,ƒÁ`0˜± ƒÁŒÅ`0 Fõá›ìííí–ÇÇÇÇé§ññ’%'TŸeº¹x¢üèé4C½VnC »6ý¾WvÍ+í;`ù²U]¦VM¶=%ÿLŠQËôè¾´ån¡éó†¥<§9ô¥êìÔ.,‡l-…VÖ×Ï7µË*9kó¬r·§Z³¤«XÊ¡yííííííããã¥m°åÅ t¥vÜ=­ªz“¦#—¼ð–ò,íЋ—¹bƒåòɤ¼Œ5!s–U5±Ó„Ä[5å÷€î ®uÐáì‹Ri{½V;+?Q>nú»’Cc)ºÒ.'ìW1Ò(·–ã,í’Œ…IÂS~tɇ¬HáØ½-ná„ò,…ÈS–eïÆÑAÅ)fš*k‹iöÆÑ[Ö!W¥Sò9ÑnQî·¹]›ìÒ̲%²®cú»òí7qi-9ÅôËYÓ™e,Ÿ8)iWæ3™ì£ËñJ8 Çò‰Î-œŽÄfçIÃnè§9›;÷nj/I_¼â1µqôMSâÐ4í¸Úî]¯ŠD5”dh)g÷h÷®ÔJÒÔ ø6¦IZ^6¹Ü|4Ùõûd?äR½Tvîêé }É…?!‰Ú-MK4; ”ð ­ÌkVF?V©è¤ÂŸ½¥µ­L]›Bß§ð™U`h\âΩÊ{âÜñ Eí’UW ?7»…³ÛzZî¡/Õg8¹93kÉy×.2¥#îsó«ïíÁ]³³J×ÙиMÁ’Û3¡rPÌÕ+Í«†WiÉ–îêý¤^iASx…D_,™ÉYKÅ»žg¼øÂË´¶*ßêµÈoLîšÉSâ¶y¶ÂCS¯tU>ÁNg,T×›‡Umž;µÌZ‘§³íLD•ü²ì85©úÊ4äêl^f|` s^ܹ¶k¥j‰©UÕšÊè»–]¨Ø¸¨¢vh€ó•°Í–·r¸y…_cgáX~ÈÕýЊyÇ*Óªb>sU€ÎÒ«€l‹yÄÔVöž÷=ôàß|ýèésÚøîÏ<®AÌ`0X™®5Ö¥©Ÿj¿|j~«¿ýØ‘CÙÌgib0Õ™¶ê&à 0CÀŒÅ`0ª€ DгzZðñ3Œ*’c¦Ép:mf‹Á`0µf,ƒÁ`0c1 ƒÁŒÅ`0 f,ƒÁ`0˜± ƒÁ`Æb0 F}Ãb?%Æ`0 ÃÕ:ÖÎ;Y( ƒÁp;c1]1 õ0[×­[ÇBa0 †ÐÖÖöÈgv[ëX ƒÁ`ÔŒŽÅ(!8†…Áp3ؤČÅ0àÿøY †;ÁÕk™±üU0nÇÐЯ&kìÇb0 ëX ƒQkº Á%°ô2NÌXT•YÅøø8—».9Š©1âŸê9´|¢iÄEusõnòOÓiCi…VÌSŠé㤄ïðQˆ#–ç;ÈÖáÓsî•Ó[ ]KJ±:�•Á„rV©BüÝÞÞnš1‹98©–Ð…í™lÊJùvO™þJK¾v²÷q QÓO–ë;’¦Ë'VF1ðx<,„*Î^Fß4'ËE+Ó›ó¢ÞApÖ]Ä‘ÉN÷–'[.Õ˧7OêžÎ’±TDÄ”]äM<ªÊvj¯4ÝÊtþ"Œ’ 4‘â³´œ–òqšå¯bâ›Ú H3i‘šœ8YŽK¨Mÿu²“‰ÝSìÎ7¯ü+=)ÙÊJ¤ÜN£¾á›Ô,ëÅ2©Ζ¢Rɼ‹œÉôTrÛÝ”uYw)žó¦ßÚ å?YU¬TÖ•´øCc0cMñSdLS8®¦£fMª/•yÊôåo©Æ9Ð’ó­¦ðž•I‹ÁŒUJMb†ÓÕìK•ŸÊG“½³8ß§´íŸŽü˺€“»ÉÑŒ™o9¾%þ~¦/´ÒjW¥”J.M&Õr‡3'{ŸiÊÊG^ö1e×±äÅ/uÎò1ùcì„VŒH-Ï)þ`I†r²+Æ‹ãp9ýd'+Y%š¨a~ÅÈ¡*~,“ˆø£c0c9g,§–f‘btX€O(Òbœ"Åœ° Å<·ÈÇM?¿˜ÇÓM‡ÆOê•v>¡x L8¦“P£ŽÁy ƒQ/:ƒQ>Xú–ܯ=¸60]È f,£\¨9Ó–Ë̦B3cZàlÐ ƒÁŒUàTÐ ƒÁŒUعs' Áp',+0Õ24�!¤SèeÆb°‚Å`Ô,+0Õ8ü@Rg/?3ƒ¿ £æáP©†Ô)Àh!¤¤ÐM?¤ÐB2U§¤Åû± £VXŠˆ ƒØFGȨӕŸNþYo`Æb0 ÷"d´ò b3  `#ý3…î’9ù=¬®0éúXp,æ©&Ï®û?v%t-%Œ©–xv.a<©ƒPêüÖV㌺PªÄpJןBHW…Lé„$ÅYh�"ŽÃO<—š™:ÖdkÂòÄQ ñÛIXr‘òŸð’)”B®›Æ35ÁOôGIâ§ÒqDE ýC$ŒDiÀB:„$rd'ôˆ£/‚X*'L…3LÇR뵫¥iÕÕñ¤VÊâÈ̬J§ª,v²ÅDÕŠ‹,0_<&¼ÄÍg0j‡«üƒØÖ‰H;�JwPuéJU7©PQì öÒ©nx´œ?äI¦à´x. Æ~,8L7ê ·øEñ”‹ ÕÜP|ÏTùɮخÚN6žÁ¨uë„ìÄØ.ôǰžŽ§Ð h)ô’=PSÕOèN¡7…^ùɧå7êmÌXÓ^ü²ýÐnFžlÆIé¦å3¬U¾ñj!+£¶´«ºCH§ÐE<…î(vèëšû—7Òù"æBDFñÄC ÝÈM,dƚʢ˜QŒ¦2/Ÿ)Õ®n½«/ûÏŒZƒß¨lùIa¢`Šb�BH‘¡?" –t• Ž($_ý­3_ý ì;ˆy*©ŒfæðOn<ƒánÒJb['Æ‚ˆEÑBšâ�3’OKXQ ù«@¿ê^.„<ÉT®—<X!$É®XgÞ¬‰u,58Ž‘ÍÅkZvg‚šå á 密’›ô ‡�‡"Åë¬H¹§ñ¬Á3jZ ÝØ8†Î ‚²þ$QiQ}úá^}“–¸C/ aî~]¯’ÿ?c öÎyñ«ÝqíçÇg¦N&‹E‚³ü‹²IÈ i<ƒQu­o�Sè&•(‚áÒa$Œ|ãGa£U·ÎF~)ÈB“o(ÂßëIV¾IÍJvíf 竊<^ÇzUñ')»(óÉœlc\Õx£¶A0‚á8ú3Åó$u ¡°ò!ˆLª`ë“ý€F&AòiÕ%8KƒÁ`TþzuŽÉûœ(ž‚‚×MV¾8¢zþ‹¤þ?€\¹œ_œœËåïSgûˆKÌXlœa0ŒÉ£Ë.üR{ùuƒ¡¦Ø 霴8Y6¦Ð+Ââ™±,ÀqÆ ƒé‡þBÒ"áLW�üäÁ’¸ zÈŸH‰[Hu1ˆÍzÌE7€G=±çs½j9GcªÜÚ×Ç*;†††X ÆÌp>óñè"`8ƒ ¥cO™Ã+4A]t<„táA@ì)Ž£ï‹ˆF‹£Oª<RW`Æ*;¸ 1ƒQ×ê”ߘúÏ/˜& ŸÇ¶G\h’ Èo%ŽK”ø©f#m.& b›Ç£årþ¸§Op',Âå™±6عs' ÁëÖ­c!0jS‘JJaôÿ´Äa˜üÞ|ö[™«h³p\Ï!ò¸ë»‰ýq „`1 :€-!„ª[Ò¸û˜‹Á Ö4pêÔ)£5*Éd2è :!ëûóÑ{ŽHá@œ–“Ä¥ƒ�âxxT¿ )ÜóED‘Ë¥àñ€‚\.¥_Äù¥„ÇÌœòŒÀÐÐÓ9£F( ².®ë@ƒØœÍâЀ¨à­Ò)IU*b~×$Õ*OrºGŠž;,y§d%,M¹t‘CÈó|J¢Åçya]¤ÓJQ—¼‹Á`0ÌPcüBHǰ>ލAîÀÊ«$øCÙV•Ï:A6=GgXZÜ!Ž>½V:ލü“ú·ÇSˆ‰÷�&wD ¬Q0c1 †YãéÇ®’ ² "C¥@ä@)•Œ&Á^9Ý_ñƒ)t‹]YtmÃRÚ@-„d1Ò«¨m…6uqU¾Nq]¸OÀXj¦Q‡Ü£œ–Ôµ˜Zå*cÆ"Ф3‘EZÎ^<¢óJ¯)ÛlÃ"馾J‹`Xß’E cqô‰ÛRÂ@⿺ãˆR¬`A…"»£GC.¯~Q�ˆÑëÆ:ÃÝt…Õld0fü¤T‰]P4ãodž"Æ´I~@Ä6EÄ–©ÞAl–ø,VäƒãˆKÑm)%nÉ8¢¤„‘%ø,‚Xþþ‰< fKa=T™ ò‚ò²‹„ܦ¯òi–Sdñ—0 †{@1 ƒ$ò5cqtýÀ)œ€@§ýˆF^.` íÖÝ]Å<”’B$ b8‹�µ‡î&h5®SWAÆ’º¾%bååÄN5OZSÔ±¦°lç•~µÀ%9ŒÉ"žOj …ê > ÓtEJ“ÂBc+r/•pÔã5’€?Œ±ÇňuŸVššJÎ*zJN×¥ðzú¿?‚áZ7 N‘±8` × Æ$¡…$ÅE„í ¥Gäý "£gHÊ[eë_1â˜â}Z”Ÿ‰¬‘�BH&&&#£`w:M¾Ä”<—È,„´”ܽ _çŒeWëhjž|vþ3 ÷Cd?’ÂÜ5¶GZ ©DbU}”‡By¬*³�� �IDAT¨>¯¡„i8À/+s)t‹À ù¹zóüú¯”f0Ãúçs½‚ÉdmŒ´«8új=cS±:–‰iLËöÉ*g¬¢1 ×BÔWÜ‹GhÞ׃ôHÅé• UB±M¯bÒ{LÕ¬^¹ªˆÎ1Â#%Œ„:eú‰½(¾ùœþ 2"LƒZ^õˆ‹ÊyAñ˜¼ Ä!ìPa0®DÁAlK ¼»%"!à ±y�Sfúñ�!„SèIüôÝ»âÌ"4Ú.Ú“Òõ39…Dc鸒Ò"Ž( VÄt Ýa$ú±kW!:£NËŽÃñ˜409ÂP7ÆtU1°äŒITä 6½ÖÓ6à¤c‘Ñ™)"˜Ò#Ρo™’H(¤Ç®4�=˜B·FÊ9œ RÜŠlIg@ÀCxú æžÆ¼=XÛ]µ[‚¤X« jÇ“{ª­Ïô“éž4+OZ,y£HPz¤0Ùh”ðBœ“B7™æPÈF‘Ž b9Š*üQpŒ‰“WcPˆ`?²R¢*JÎôEO„Ø+޾lìÄØøôãxò –gCgqu&k™± c†`ÛRèÀ–0Ä V ÃØf,4¬QHºš·©xsŸïç_ƒÝýØ%ñ“_cÔ"ˆQüE±{<ù Ä(vx<Z™†÷â‘1tÆÑFb °=ðŒ³ 2 F½b�[ˆ0ò–7Èa)ô’qOyߢ›ò’d-@w(Ï tPÖŸ&Ñ Õ‡¤ä¤wv.S=â|cÈèÃú(vD0 $ÞÒAdz0² ýÐ÷/'îÇ®QtmÀö55;4¬c1 †IË)èL!$EÉ=¥¬Øå'-GØèbˆQ«AŠ’—oXtCüAd(\P„°Ú^<BëƒØÖ‰±.ŒRÛ2nÀv�ýØGt9¦ÐM^®AlëÇ®UØŸE`]ƒØÌ:ÃCCC,£† g=Ï+:BUÊW¢Ò wT++ž7ýõ¥€v&$",D†éæA“" óQ=Cg™Qt… Û‰±1tˆbG ë;p| žÉ#èÙ‹ãã�yãÂH$_}ôˆZÌØÄŒUvpÝB£Õ¬ 2qt‡"–É«Gi̺õ=[}¢X¢Doy%Œj…Ä%*š$òÑí#ˆe€µØ3Žvâ'�¤Kmdž 2Y±­ÇGѵ�ž¡sŽ£ƒ~]}+q`žÝ€í£èjG ‡_1c•;wîd!8`ݺu¬þò�¹ ƒØ<7ÄùS…‚X¤iåù2Hi‰mÂA “fFž'Ú½Ï]lE„úÄ|™A°»FÐÓ]{°@F²$¾Ï/†‘È"0€�"¦ã«±o vǰ~pËi7tUøNíÆ 2c±‚UMœ:uŠˆÈm  ºõlÓMjò,¯¥ ÛŠ‰cÒȧïÇ’ËÛâÔí³åB/ #± ýä ëÁHq  ˆÌSx¬#ûñÀ¬| O=†§žÂc�Ǔϣ·ãƒØ6‚ºpVÝ…~2 Öhü3óUÓo\Â<@. j ¯e)~Al½Ò“'‰�¶_QÌ^OTAç߃¢öc Òê#Av¼1t&Ž#�©PÝHÁÒƒXžEà%¬Cg�Ù,tí¬@vö?‡ÖbϬM¡›®c#èE°»æ\Y+Ȩp‘eFéßG%%¢í!=€:? ;¡f¼Ä/Ǧ‹Û#5cÍ*'ìÃêl¡6tàx�Ù8ú¶cÃrü�À.ôS;m K»žwb ÀÌpË{0Áð¬$V[‹=+q #/˜±uBW\N…QRK$¢í Êu¤¼‚Û±ÒO˜vDZªý!g¦ð™W”j !™E ‚Ø(º°ð÷c×~<0Žö0QÄŸ÷õîÅ##èÉ"@„Dq]=Œe+q`ö¡³#+qà1<5‚žX¹kk±V–¯˜¹ÀtDMŒkWhœÅ®¸ÙÖ$¨ ‹5ÛàœbØrh¦ö¬©Ýª¨Ìs§9dSØÔjy[¾œ‡º›žî—‚([EJ� $)‚œòFŠ¡oìÕK…( ÿ„qƒ)ôAíÈ>ˆÍ]]ƒ�"Î ¸þýJû(º>‡?ý|‚®=Žrbé|Ù'vŒÑñ.ŒR„á@½êX‰é,?�ÎbW¼!ËNžvƒå ÅÄä¡™Ú³¦v«rUež8µ!›¦Ä ýy•óA†ˆ¬è#vàÒÞ^¢+QÚCè^”rBT·ÊåËáù\o.GA&@�ÙŒtàx'Æ:p<‹@ñíØ°Äí´­jÖGG'ÆŽbÑ:鉿<d?‡?ý4ž â Û…Ñå8˜Að1<µÏè~¯i«Y9›¿«¥cMj±Y¯Ë7SúRõqRZ©ós'¤»…ÅT–©Ýª*ªO™t¸"çý© _ý¦L5Š|´Êâ–v*€L~#°9$}�C뻲¢(DÀC®6""/„6C™j‹t `ãAÜ~sî�!lø-|¥»Ž£ãi<”E€¼V8¾ ‡`éJ üšgø~Üt‹öcUQ öi<±«�„‘8yT0…l›q*òÔ Up D¶0Í;U4=•–z'5^v°ÉÞªL²\"þ®°†7aßíN˜Â@s혊ñÖ 6ÀOÅDÈ ¥›õ’ÈN¦t·“´KÓKøM— ¶A§0÷\®@l÷x’1슢{/9ŽŽ_—cY7ÒOã¡QtíÃê/ú¢hî€Y8ý:¾¾ÛcˆŒ!{sGГA0ˆÌ¬¥ód´mGÒ™¨Ë£s[EÎWÚ/Ä4yU~î(ëÊš&¦jÑÕÔž+—z±š çzSc¦s«º1ÚÉGî{1sh;1:˹øƒŒ‰¬‚±<'uÓö¬ ‚¤Ee ¬Ö­¤½€ñ±m�Ÿdc`¯ÇcáÊÊYÖžÏõxuèvüÀ_œj¹ä®�g€Þ5u zÉ.B4¬D‚ŒbMGÒrŽe÷ÙÔ-¹P«ãƸ¤ûeRh&Œ”™Â™®J-PÂ@�-ƒ´^“€ŸB$âЄR%â,H‘�€Ï¢`$:´°Èy<Ôõ¨'FY£ˆïǽ{°¶#ËqpN?…ÇÈ¡5Š®•8p�+âé'ðé�² „ÃHp][…ýitß0Hž-�Û±ÁVÛ+FÇBEu¬éF·›Ìú¼!Ƶ 1µ¡± 6›9£\’b˜Îñ^(_Å?ÎtÕÔn5³á7ý_¸ð§Ð­WN†Œ#@VÇÓ"–Š:Ò‘˜éžÊá-Éãǃ{<I�_ÌEÉ|Cä –¯Åžå8x�+çâÌjìÛ‡Õ£èêÂèRéÂèÓxh5öuat+6ubl]Û±²7¥Ñ½«_Á{(úq;6LÌCwy³¼%ù¤ëþß¼0:UÅô45Êq'³‹(›ì³ªNcÕ—ò ™eiï ‡Ì® ¸z©hÒB1@£íP!$)×Q$ŸH´¨-qDÿ ¶Ñ%z–÷$ô UÊïGúÙ„)0Rè~Ôóx´µØCG–ãà&l݃µYȉEQ£èJ£û7?ÿÌ_,ØÒŽñãè™s·bÓs¸ ÇÑу‘MØÁp'ÆRèmǸR¥8½ÊDl0ú½Ê†Òdi’̓Ÿ kn•­úÊÝ5cÔÔ„lyÕdCÄô7å[•{ŒªòÖMØw‡&ku¬ËOÌ͆A½V}Þܧ;¨HÓ’OË#¡gŒ ¦ç,üšËx&�~Ýå¼1ˇ¶Pâ% £"@ö~<÷8ž¤ÆìDZü7}Ï<ú'±A |Ä÷WVèÄØýxŽ" ;pü8:¢Ø1ˆm÷ã¹—°"†È8ŽËlê~øŠùBŠ9Xßk·éG@/açøõâÏ)ò*çƒÅ?¨êC_ɧ;˹HáOY¶SG÷ S-"Ž(éX”Ê]JÎTU×SÜjÒ®¬Œ”º @îORˆ×7)Oéîߎ$%q'²¡£”úvÛº0º [·bÓ®|`5ö½‚÷Œ]é\‰ñ}ç³W6ÇéÇ®xé9Üÿž>ˆÛŸÆCÏáþ,dÇÐF"5ZYžÉ«eÕµ 2 F‚æq,~”® �¥h5ì„‘ÚédCH‡–¶÷Š-É1¬iŸ&Ôóhßá%¬x =Ž'©âpFÛ1NåHcÙýxnÖ>‡û`å¿_yÀýxn=‡±¬ £g07î,]íÁÈ�6:E·×¨ŽÅ`03œ·hû¥;Jåc¼›*B3‰ìz(|w Ý1ŒE’ñ|ÉGMÏ3ØWDý±l$ÓßzVc_�Yèã裬£èE×ZìÙ„­ýØ ‹Àãx²»öauFFÑ•@ø+ø­8"Y"^}ËpùhÆ�ëX ƒáy·¯Èi+¢SèÄfQK§§[¤EééšÈ¦Iùp‹ª?BêÑUA UÏ"°Û3îÇcè\‰�º0ºkÉ„ #�–ã €_‰a$žÃý+q€B9FÑu¾[štM¬cÕ¸Ð-£–A›«D T.´ò:ý!Õ"ÑR:Õ…ò›·îÑÏQ«>N�ò~‘vµ{ÆÑ~d÷a5€MغÛ`eF)tp 1ð[øÊl߃µdÛ1¾ ß akbÐ0ز££èª•Ê#ÌXeW¹åbÔ2ü:oõJ"'BHf ªX>CWË’t²G¶A)¡»VLaâŒD±ÀZì!¢ @–ª/Ãáe8<gîÆ /àî}XB÷ ¸»»FÑ ‹À&lº4]B¹BHÛ;1†é_0cÕ vîÜÉBpÀºuëx€x€Ü¯fézU:ˆLÑT¡2–_¤»¥"ýØD,Žn‘±)ˆŒÎXþbqôŠÃ ÓfÞ Yó~t¢3‹ÀA, OÑÑÃXö8žü ~ëÜ}7^ (öô<†§ÈHVDÊŽH*€—°bÏá~:‡(­VÀŒÅë÷j¢êëy€\>@.Q³BH†‘H LÜ3ˆmØhzV\DË ™H’˜ÌŸÑ©K7öIõ±’z°û ²Ù€í£èš‹3OàÓqôíÇOâqRªÖà™½Ø¾«ãè#*úÍ9Ïì{gõ“xü4î=ˆ±8"°}ƲpwޝÁîýx`žĶ¢Cí™±ø›Ÿ‘r [ð�¹|€ªŽ’Ad“¹/„ä@¾¤HÞeä“ÔšàŠ C�@.ƒ ¾ ™~¥ýÅI‘iס AdÃS/a€ýXõ9üi�ÙX¹ȧA¬{z0²û(iÓ߉d|  `ãËøðKX± ý:ƒ]QBòäº+È`0NœLZ ÝäÐ’ ûúõ„Li(ýÑM$‡Bc?mÌ¢ƒ"×»sâˆÙ�X—þ'þ¨ £TÄd=´­jÖÒÉÛ‡ÕËq°»(Oî:cXËhËpÃd !M7I ¼ÛÝ?ÌX ƒ‰£/…ÞAl“^ ü¤g» ~Òèoâ'Ò`∠fÒcß5##:!ŠDo‡±ŒŽìÅ#›°u-ödìÁ,>ŽŽUØà�VÒ”&ƒÌ€ÄgqôeŒ`x+6Ñ^æº'HŒëLlTÓn–¤ع³ÖmÅÚ6aÑgË<u&¯³¬ƒ<µ[¹• IÉÊ¡1VI­ªAøCH&�äëQùCHÆÑ‡|õ,¹NqRÌG¦ÐЉ*¥Gd¤ ‰á5©b¤-BH“kVO<O Â[±é�V’q/‹@ñE`9~Á0m4&=l�IÁ"ãá<œŽb%›#Q?VA9ñsIÒcO³|ÃÌ„,yçòHY,r”§|«8.ÅÈjÂTú“ý y€*-…Þ 2"q; ¦<,„Ä^ÄÈ/E—@Ú;¬ŸF» zX1-H¡{]Ø@v9~Aâ `åA,§s¯Æ>bS ¡s(¸#†õƒØ@6ƒàìÀƧðÙŠM „Ý¿Ø;ýoÕ®8–ú“ÝÉê¯v]µ*XÖ³¦„ñ%¤üú«ÙXá*~,Ît(0Ëjº‡´(ë’à£Ù0*êcQB�1DL™ÑÉ(™ýzìÆÄ¤Bºc{ñ €†ÃHˆÊ&8žE ŒD ½dúFâMÜ"ô° ‚äñÀÆ 2¤iQvA�«ðáN«mÆߘ3©8¯ûjt©(—-wùlRdS]»>¨!MK–pÉß êZIgB¯LWBÊ H¥¾ !Eœ¼_ÆÐ ƒ¥Qðœô;«w=DH«±/‹@'ÆFÐ3€-£èŠ#:€¤Æ¥ÐMd6€ÁAlÛ…þbOâñ�²qô‘RG”8,†õÿ/þ6‚˜m¡,7ÁWü×"Ï€–¡©JÛý„KÑÚ*YRÞÔ,ç&Ù­ ĬçPßÄò„U³*\GÊ$á Å^üøÖå�ÕÈÿ$ö-黀5ÂN°BH“ÇH''m�~`#$'ViÝEöº(ŒÙ í@Ñ}Q#ˆ  /„p?Ö¡“RÜ™e$#Šün0ÐN2` í0‹#º IRÅŠÙVŒ5/dj‹M÷¯%e£SYgIÝßÒ?3QÉ%EÅÆ—Q-è‰n{¥äÐéÊÚTHi2ôlLy=)dÍH‹üE¢»(Æ]ÜHþ~Dv¡?Œ¥u§L¸Ô$"B‘\#„dÃ$³ÈlÀö}ˆH E<‚˜ËIË[ò96f÷Iͤ&« kéªbvKÕ Xs£Š¯“Ãøò�¹~á7"šÑ z…#tšžÍ=¹nܬIYF‚…þ+‚½ücèìÇ®0a$âèÖ<¢¨.ŒfÀ– ‚qDE5dÊ^HÿQÖ(ºü8:âˆä 5ÒØfc9OˆÒO­|™¦î”›´Æ%8«¼“ σ.¡|»ñårmIÄÑG‰aUGi@Ž%ŠübÿÖ 6ë»wóîEÆé `c;°1pÃk±'޾AlŽ£/Œ„vA­Òý -…n"*½/þ(vˆsˆ€]®c•>K“0Å˜ŽØy,•ZúfÂw&lÊ·yUåCu,örÜŸ¨¬ªdõ‰|€#ˆQ’&‘cP×–ò©r3’Ùè$„t¢`!ÔH{Ó½_Æ ú÷âÁQteˆ#‡Fi–±­ £ôwé]è'¢ªÇzËý“f>·aZ¨ï/2—¼{Ëò¥7…YOx•å,9ÍGTw†*FJxt‘-)É Öâ$X­qq~z‘A3a€jÄâðgò‰-üŸÆlÈû·4ÛD ­$ò™s?+kQzFþª]E‹è) @a)t£ -‚Ôa�T›X¥FÌ ØõQì©è¡×P¦~°y�~LÒµVÛ:+C £~¡Åè.¢’äÉc£1ï­&åð§�à³TmD×f Azþ\è?E'RõòylÈ`c‰l åKvå‹›P"‹ë¡Œ@¿\þX»OnŦ=�€AlîÄ.׿q/1cñVGƒQ×n'ˆ\·Òß½úv`QO„8)™Ëõ§œÎ÷Èÿ”þpBÒø¬|“¸t“Táø£Ò³ò?IWa¾­<a¢fx<5ÏXÌU £¾u,è¹!R‡ô\ì9,ȳ•»ðx„iŽ6HI¹Ûý¤Üd +EmØBŽè;—…#JЪ\1’r ®Á3ƒØ,vkÑ…ôêmØ8#t,†Š¡¡!£Žt,͘B:ˆ¡¾”xI°‘A±Œ¾8޾ž½)„4‘Ü@>»n1¡zZˆå=RÔ$‹¨‰è mtScÖb€•8° [ÃHô`„¶peÄ@�=AkK;2c•\ˆQš–p>E‹ç7wÓn'½€Vº~#¶ñR…­ÖG7é@F××ĬIâ†dÃ@  KÁ‡Ad(¯àZìÙ„­!`“ži0ŠxýÛ€íqDH»ŠbGé½xp žaÆšqعs' ÁëÖ­ãâª-è{› ¬|(dÄè–\YD-´Ã©O*4¬E±#„þü@Lט‚Nã×9!¤É¦GGO�xeC'€(v bÛCxúìCç�6îÇÁ=ÈìBÿl§*$Dra$¶c°Û…š3¯ß«‰ªW¬çrù�¹rÒ ÚêɧìóëDÒÆzWTwX“L¤N‘ pJ›ŸüÄØFûˆãˆÆ¡´Y‚È<‡“›j�÷â�]³�hÏÖ&lá‚BíÛö`-Õxd‹¿yFCCC.a  —ût,±*-xKRª4)zPlÀÒD ÝRµ!“§Ïî­ØÀæxn qôK­Äq2%—Šaý>¬ÞŽ ”Ùâ)D~]tÏ~¬?€•’ç:xùýc0ŒIéX0n¢¢íÀôwÃBÙÒç}Q©Ä_Ú6ÀÊ,/a…®oõ]…g;16€-Y¯Áîô "# @�ÙNŒÑîã 2QìÈ"Ѓ× Ÿ‹Á`0& MD¥G£ì·!$²Ó ¢ª@S:1¶{È$H飓•ŠÓi¢$1eËíÀq�äå !@¸#d!Œb‡â.LläMÁÅȤÂRR37:7ÌtšÝ­,óë;ä*~€¦&Õº ÚG^‹¢¬}º§*xEZF¢c7qËãèÛ6a+Uk’{q|‰ºƒÈ©˜lgÔóntG0¬WªÔôd‰}(®^ëXŒI@Nøm™,xÂ’(Å€vUh÷ФÊärÞŠ£¯´æ¾â1€-cèL¡{;6Œ '„ô¬ #`›ÃHw*†õT1‹L‚cè|÷ËQd#ˆÅ !Gt›%3¦æ6‰O‚±Ä‡!&GµŒw»ÓAÓ¬jyf ÍD0Vt¬üú]M‰k™wf®µ]8@”ÆͪY¨nx…¤Óß)ôƾ+:Hdˆ£/p�Ù•8 '!¤r_þl‰#º ýDc”qƒ,œ¡|úyÁ7ÙOQ­î\&\®bùI×hðª—u˜Ô£Ù´[yð�1*�Šªc3åmêÀ¾"QôÑ^f9}{ Õ傞ÿp�@>“FÙ¤ÂØ,ò3étå®”¸¥´ :/ëïkœ°¾b¹mMEÚfælh2–V²û<@ŒŠéy/ãÃ1DHÊ ¸»)iE ½dE‘Æ’ƒØBR/JH5”CHGK¡[/Y©‘ß+…^·©YeÉÝ^Ž“Ý¼ˆv³Ž8“gC“ÞÏĨ?Üï~`ô¤ºƒØLÄ“@˜t©‚AdÄ?%ý, ôEòµH�Diã³Ø­EI=Rn꯷ß^‘ŸŸZ,¼æèª*Žîâ<VëÝàbT +‘Bï ¶šîÄ"=)_q˜rs„ÔÝWZÃd!Ì 8˜7*æ÷‘++…î0µQŸŒ55ªƒ/LMÍEgÕhÀ sƒ¡À/(Š\PDNô‡¡¨Š 2!$³„^‹=Y±-…^ÝÀÃú" SÂÂ!7•$.± JP†éõL^cNGÎÅHÏ!,ÓòVÅd?@äbLvA~)aúJ Å°>‚XFÈAÕ]±<€la*žGqU0¡„‡`w W%ôùù™¾IýmùñÔôeG^ÝX/æ´âG§‡¬Zm.R€<@Œéƒi󯮥d ½°ý8"»¦M»ÐÝH}ûð“xüq$ƒ¦¬:´,†õTô[ÜÓÙ²gÂåƒÁ`”Ÿ·DQãÞ"8¾Ú½6J?"DWAd¨ em_‹=ãÉ0jA©òV@Qå%+вû±ØXÁ`0å„?‚a µ Ò'c褄 ‡‘�´]èßGèl p§Ÿ¨àHa‘«·Z)<Ü¢c1K1 Fù¬`FâyNÚAlÛgÜ�<OoŦ=XKÇõÍÅ…b]5®Uv ±x€Œò!„d‰ô ¢s�}1ŒDÑø#=€•dÌ ¨§œßR£=eÆ*;¸,ƒQV¤Ð»÷®Â³{ñÈ ¶¡À~Ü» }�±ˆ*Uû=eÆ*/vîÜÉBpÀºuëx€x€ÓǬ¥*ÃT" À*<KF¿ v•*f,^¿»U¯XÏäòb-€mãDÝæÇŒÅß| chhÈ%lÁäòb=)RàŠŽ ƒÁ`Æb0 £t˜Ø*h—ë¬2(í¾cË좵¾]ÌYDr—Å9Åtg§*ö”»ƒÒ®Ñc0\¡cU¾2H9ÒWQëƒ7¡ˆ,K¢°ê³y½æ/ŸPÚ5:p Fõu,‡ïÍô‡¼Ê£dírápµˆ¸óÚ°Ü_ ¼/réZL§*‰:ž¤L]S_9çã¬|03ZÇšp!¬®òh~—çz÷¬ Uº*²yÎb”PÁRÿ)¯Qéj²z ƒÁ¨[ËR™¨Ñu+˜u˜N�� �IDATçä­iÅËò8ƒÁŒå4Y˜JÒ•dAÍ`”öÅàŒÁ˜‰ŒU¤Ê2Ù ¢òŠ+Xµ¥þN3�‡šÁ¨'¸b?V9Âg2]ULžµ¢ÕŠ@fÚÀ1Uбȋ »Á‹ùêLgV~—sKªØ¼¢ø®ÕbE›-ýXnîÑ„m«ï«‰W‹…P«ŒåìÁRÿk1¯Ei_×ýd;îž”ÉǤºª/ÓyÙjbN¬Ý«3pÉ´zÖ±Œª€]’Œ2S�3c1¥WSØ Æ(-Ö­[ǹü™±Œr‘ Á`Æb” lçb0ÌXµ¶‰ó�1 f,·ƒmâ<@ £„àŠŽ ƒÁ¨M«­­…Â`0Œ`¬;w²P ƒáÌ·e¬uëÖ±x ƒá´µµ=ò™Ý¶Œ…êÉ{ZR‹Í³kpU‚ÈiærYÕÄ€òG1Úì¶&©Q¾"Ï+7†††„zWÝð-÷´¤›çÜà kðmmmBD®•UM (3¡Ínk’ÜŽd0 Fm€‹Á`0ÌX ƒÁ`0c1 c¦aêYš,+ùÂé´åjÈ¢=•l›«ê6ÕP1K¹q¬º|-kndù=œš4J.7__µšÇ“B] “1“Áïa ëXbÙÞÞÞn§ZÉXÉÛòæj3LÊ–hp™øÀA·“›j§ù•œ]ì†I‹Üù¸éï Œ¬*X»f—öѪÁÀù5›¬Ð*ðæOj˜ªõyßž2 w1_Á„o]ÅZëð9Xþ]ÝOÕù‰¥ÑTüXâavOmR¥YBÉ7·|ÿŠop¹UœrÈajÃ$Ó˜eÛhþ•çbK9—¯GbUaysç_§#+Ñ©b^³I ­2o~ñÃTÅÏs²í)Ó'ãü8O&έ­Ê—>™—ãS-æ‰ÓQ½E^T’“,GkRWUÅ|7.¡æF°¬m® #ªi^PGÖîת åô›Q¦¾sÛÉ>·L2ŸÔŒá¼ðªúd;ýføÊýiÕâÍ븩–úV ßÍ+ž)Ï\Å0ë„cTƒXV¨ï÷yRoK Mw¾ýø]2³éÀùpç$hg¯õi½î×@ÂZåà”-fp9”`&ˆ¢˜·¥¶„é­ÀDP¾¹@½¹k—–rSMè+ÓÈVe€jÅèÜÎ)ŒH…?ÏÚzŸÝÓøâg Ñ‹ÊkWÅ ýôEê-«|Ë!2Ë›Ë#:á—£³–·­–b>Y1¯iU GU¤ðv¾fUiañMrÜ*~ž–O¬¢T§0™¸ð£vÉ»Z̧ÿuû¦Ó8Óß–+¦xªÍ°ü0*ОbäPY9?ej¿V µ•»œß(烕ÔÔÚéÜæj5²*-,òA¥úXªò-Wqb)¦aÓlgib0Œ‰-Z 7€‹Á`0ÌJ€;ù ‹€Á`0TÒb¸P¤¬c1 £6ÀŒÅ`0ŒÚ€µUphh¨ŠmªîÓÝÙ’ZlžŠ¶¶6–7’eèþ6»VŒž÷=ôàß|ýèésÚøm'×­[Ç4Î`0 —,sùÌîVû±#‡²™¶ 2 £6à³ä´’ÜúÔ©S(ƒ!¨L·­ã†Õ}ËkÑDÆ ~[¸;Ü »3cYž7Y ãôïVîÛÖqÃfHËkËšÝÖÖ&DÍo w‡»3awØ*È`0ŒÚ�3ƒÁ`0˜± ƒÁ`Æb0 ÆLCÝæœBKSÂf¹°PI’bYÞjÊíœð’m¹ZÉ©†d^Bɳ̧üž×nw,[^gÝ™ægÂ:–Y|5Ý—-— j§’½Ãº‡e^á÷¼¦»£¶¼Îº3ýϤ>u,!‡¬ç Y«÷)«þ7…–sQ׊i®¥my%uîRµ\}j«åµ(ó ßóÒö´*/­–—Lç3q…ŽUrÀT¸vÂuÊ„e‹KKW‹ŽI­°*?U¬å¥íËÜ¡åe*U»2¯nwì‚G§žu,7cÊC[Ö7ØU-/y×*ÓòÒ*âk¹üM—%éEußs1«–jD*Ö˨Ñ/Âr ¦ù‚ù¦ö ¤.}÷¬¤nP¸kñ5(]1¦9#—€ù‹(É@L8¼“}|iä[Õz¼Cµ^…zj¹Ë?Ng™·ëPWcü¶ÌÀ–—¤;5ýE”ã3©ÿXÁR½ëU¿êí«ðÇÌ-wh¹º˜+¹‚e^‹ÓHñÝ©dˆoµFgúŸ‰+«Ú•£ì0œÂ‚E¾O©æø$ÿ:aË+ù1W¬åíXæåny™"/ª%óÚíŽÃUµøE”i ê9òB–Ñ„òr8¹äÎ[»gÞZdóÊá§-wË˹P™—°•lyiÅ^õ÷¼v»Sg_D9>ÞAÌ`0ŒÚ�3ƒÁ`0˜± ƒÁ`Æb0 3ƒÁ`0n„u¬àÐÐP ŸQÚ»•û¶uܰ:ny[[Ëœ[ÎÝ©×îxVÜ÷Ѓòõ£§Ïiãw´\·nÓ8ƒÁ`0\²}ä3»[ýíÇŽÊfF|u³Ve0 F}ÃÌX;wîd¡0 Ã5˜_øsÅ}mù§ïüÏ}õá¿üÒç?ÿù™' Mù§ „¤zf1é|-„¤~>ý ùýWèÇų´’úý5㯚tgD£›è·Õ¤k5«Æ‹›äÏwP.Ñè¶ânâ¹aòMBHb³ô«& DˆB’ÄOR/ ½·ÒCé#L7‘ŸBÄfù¹Bž¢ãÒXÈ’×ô n¥IÃakHcJ €ü ù¹âˆ±ïš,Y2BÊëW 1 ¦&GP3ý'¿HR›M²5>ƒQ}är¹‡ÿòKÿãs_]ó'Ÿ_qßCÌX’™íÌ¥L4Pæ‹;(Ó¢yÒ”g‰« w4ójÊã4«ÇÉL&S¬ÅGÿß‹cˆÐD9ˆÍ–“¯Df0ñ®©U2ûšèY]FPS÷âAßH|i¸3ÍÅ2?‰Û9;y er‡º’É@p¤´¤€é¶â?Ñfc¯5ËÊËS×èqâx Óê$„$”† êÊCé i€ò4fG¦.3– ÉüqÊÓqíiÐÔiÚ4/hVšªCXN+š2õkVd`âHÍ´ú6Î_š4uÚ¬/ºÍÊM»ÔMšËsÍ8Ë3¸A”Õ)Y’/7±‘‰¶Šš¦(OåF–Lÿ¦AQ—r{ŒR2葊¨ÉÞð¶²Q´duLÍÊœInVïŒx-7¦—Mê£åk©)¯4ƒáÆšÉû±üÆÄ/fÀºõÜoÅmù °%…^érºCZœBÚêZ Ý)tKSÒ°~‚_¿¹Ðèò†SèüÄÄñzÅÜB¯ñ¹âVП’z ñ8jó ¶QGt•"߀ ‚!¤ãè‹£~AOIú›ºF £3CH‡Œ#JBo ½ô¬º© qôeŒ#D†GŸCjõ…B’Ρ_ãˆÒãè†)ôêt§Ð øG“Å«w™X!Áp�Y@ü‚Jû±‹n’AP’§6ˆmqô‰öè·õ‡N¡;‚aéÍ¡Vùérj­4¦Z;èYÔT’˜ü‚‰1C)øƒ$ ÄK#%]� „ b›.ð<Û‰1-žtÉW¥©GF¹ùõ–0o1\¶ Ú†¥¨¥šeÔH ÿªøf4EÁ‚½*fðÖÈVÕ3!,N– aÙ¸dT5 ]³s‰©><zœ¬%(‹wÍÒ­bt’T@¡4ˆ6è–4(Wµ.Íd%õ¨_HƒØ¬›ò`¯h–±Q‹arÉjœIãTÿý5Ý_¯|š rOO7¿É1DŒC¦UR;ƒ¶Æ†A[]n„Écor¤Û›J Æ«øÍ‘®T¿L±²õ ºCE|噋Z¢_h1DŒŒù4ùL£ N6!Úf²^ªA Š?_ pP­vfŸÜBÚƒ½ãÐð·‰dÙJ¢¶|+4Õ×hc¹…ꮳ4ÊŽ@ù†ä2´º–òQO£¬,),=°2¢Z† 1l¬²mÐ`œÑÍq1ÝÖd¶¶‘G%ö“,dJ¡›,?ôÝSú›nè7rž?î•jƒØ–BoF2F0Lw!™B÷�6’aŠ D)t‘&¬ÒبèºÉæCÿŒbGAj|2.ÅÑG–ºÒdÑ !MÕ­ˆiÝðEö¢$'é‰!$±¬—ô£AÕ¤‰¦uÃæ°nôËÃу“`Sè#F‚ì{Ä‚ÈP ÉŽG†\ÑT«©V#(Íã$FÝ®1(%MtXLëÂH2'šn=ÖôqIëcZ0µÉæ;]2²Ý/Î�6’U¯üY„ÉÔN©.­41dô™j…R² æ®dò¦WÝ.í×¥a°³šÅ`« ;5-X†rÙ˜Ë ëS9 Kœ#Âb©+ûÆe[¹'‡XÍS¹¬o—ù&Ë$Ô sE‰ÔLz†1, JŦ®ÜMq€j8¢¢šnkT BêA}ÖŠ”ˆf[“ˆd=UØÊLzÆÀ÷Bä…¬„é6Y+²T /‰Þx \hx²ÖkˆI:¹ÆiŠŠ´ì”)È^Ò¡Ɔ(º5ƒÁVAw[U›¾Õ<KçŠ) PxŒ»— Î!Õ¦gj˜Llzˆ¹&MÐr¬va45O „³ÜU³kʶ-M°ðÄXIϼM¦–Î'“ê`œÁÍíªe2ê\uÉVSy6¿Ê‹�Õ=Ýåfšñ­6?hªñP¬EÄ ÆÊ¤Ù› óG^Ær7b?î•îíS o‹,+˜fåIe0˜±Ü¨cYìÍT70‰ÉTÕQlbÓÕý¹°¢:³ MU&,¯R@T…ÍhØmœ2õŤc™Â7ä°rS˜µJœŠ—r €©aöžEMÙ •å‹É]p†ŸL3ñœ©Ùv/�=Â(aÜ3gxÍdÚ3R ¬HH3‰1w#.Á'+jF§)�6Î`ùò›†Ò2úƒÁ`ƪ ]YÆÚY˜DLŽzÓfúæÕ\F¶0烶/y63¯|7Y?WͲê@O’'e•ÃŒXØ”,7H©†SS: “ENÙô¦Ù韺yÊð9ÒÄÆ©é©6OÙ,&vC›Vr/LTjh°ãÉÛ«-d˜£ {£Uˆ Ôì'4Rq“jK´Úõé…lvCY0Õd,޼€&ÿªig¼eG|½’k:¿ 'ƒ ä£†ô‡_ÿàÓŠÈ/ùû#¦›Œ¡Sìõ¡Ÿ‚ÈÐ(=Æ!IwË"@· "#þ–{!v `£ÞЮ#Ú²£·S‹a½ØùD›ŸRèQÔSjR=4 ¿‘+Œ©塇™ßO ÷!…Qä#>dNH#„d ½#èÑOöG0L2Ï"@·B~/‘ˆS­ŸBHHPƒØ, „Ÿb(äd�[RèN ¬‹šöºA—¤§Ó_†ÂhBqa$BH`#nHQ*yŽÑ·‘åÃpÄ–8)Ž£7Џ¾ƒÍ/o࣠i"C¡ËqȤÅÑG­’v\ù•èüü+M§‡„@I›^QãÂ`T¬c©Ê–jw²T’䕬j­R6ñX§¼Ó]Y†È˰r±WWñ6®r ]Çdž>0ùZ›,ˆfŒj;2é¦&¿-Ôl<”GËýRfu¢ í¼ÖµJvH5¸Fuù˜=IŠ0¡¦Y²:ÍlȵÛö${Ýdó ÉÖ·š"M¬È2i¤¥ƒ²yÖrËëX ¶ º«,¬‚VûUeS›ÅFT% ¬b½òO1mF6í4²Ÿe4ÅÐWàBcXÙVfbV)%`µ5X0eMµÙˆ eÂlœmV¡qP2HYdT‚í.ZØ%ÕU‚24›ì‹ ­¬aŠ 5eà5QÌUBtÂ�(ÿ¡nG3%¨µJ²láË4ýgÄ¡:¨dg›Õ@0îµ ÎÀÔ¯ôÚ¯›†ü£çï¡dEâ¸0j²iEL"qDuSômOyƒÞ�6ê§å2‰;dÒÑ·A7‘ÅŒ¹sÄv"-޾8¢�¢ØAÆ4}ú¦»Qj"Úº$vE±CoÞXg2Ó™¶ãÕK7ZöÒN Ò”"È4¥R#ÊÌDs®xn‹Qâ(j*Ýœ,~ú>0Ϥ-’!‰JÂ&Q”Ÿ,œúœ70Rº£l !=ˆmº¸DfÛh,(©Ré0d#ˆE0¼°QÏ›…0"¥“lÖW*ÃÔ£Ö‡îÁí¸J¡;Š8]¾ ýò Ò­â詼ôÔM0>%oš–ö{„/'ʯ–¼#á‹×€®¿o"¼Â¯›^!ï>döb°UÐ] –Éa®nB2Æ›ir¤œ8"‡ ¨å-äL¡ò"W L˜AuÑ­&‹2:ö¡ÜÍZFÉÚůr0½q‘Sd„z ™ò8Xi›½,‹žØ„ãk–6OY…•5*ÙæiJ"4T5ņɂg œ“sÀÛh6æd]dÜ“mËâ 1f”·´Q›í–ªMÏ.-“)’B<]Þ`—cŒcÜltuY¥e2φ¦jU6üa›gYB°—Í–a¨Éðc†=š¥7,’ YÙ©†2M[ÌãJ¶¤!éÆ4Ø8 IÅV'‡j ²™Î¦ý0¹jLÞÕjÊ€nS2Ê@ZVý5£™TsH™/ÓÉ^<håº+¼–"Q èWe®ºÜL¯´±ºL¦HX…aíŠÁŒåRM˸ÁªWß´QTiVcÁåÙMlž•÷á*5 ËyYQSVÍf5)RJ¥ ÓbY³Ì]kõu¡mÚ‘ªY¦´Â$•ÂrÞ„¡ˆI¡©ûq¯ªSSW˜§T5;Ÿ¯@©À©Ùç�´ˆ W®2$§Pö8kŠ[Ôb—´RšÒz ¥Æ°ØÐ!,uquk¶±òˆY£µ Eaà Ã]Œ5c_G“-ÈÄX¦ùÝœ­UÝp£X{d¥Ç"Á¶<Řj *AhšM]%ƒÉÎTßV-¥f‚Pkš’w(QyP³*¨a#V)‚`“õ¦Ù™8X)vlg…åÒÁd#µâ“ñЬSŠ3EÂy¥bʶ¥îŸ³ªmmaá4em·LeÉavj–²°d\µ4³™VYÇb¸„±ÔÈ‹»ñÂOÞ{QSj�[(.@ò]‹ì®~Ú#¡Ò†(IEõT­Ý0î}‘’«j0Ô¬ÒRèÍ H®~=Ê@lWJ‹=I(#XxqÄV$ÚÁ°‘‡Ø2}³—p¿þ0´ãJ?¹;†… Pœ‚ž'7&Ç,èéeýqDõZ1"GT?_“ë~I––=…ÔëôP#±Mç�!½Â®8=ž…¨bX$ÌÕÛ¶J0‹ëQ åy~©ƒÔ0=Ű¿cÔÚø¥—+£`™h ½ƒØLy~)ÔEªƒ•O†«R¡˜Ì¡.ÓAT¢Ë3¿ LUÉ âJHòúirâcí¥£¡Ñ¡qŒa½\J-ލž^)ôưRº^ž=Õ‡UpæjZª̪œ.„9EvÈv0ÙOà~PÙsSQ`“ægZžËÛ€L÷—£¬âž!»Ð”jLæO¦� yi/‡G«¡Òª%›C-7–Yîß²* ;UÆ”@VM÷gÊb2½ª-;õr-ššZÂrO‚Mñbͪ€µ9ØÇÊ“gvæÁ*¯˜]Ñj5S¢š´Å”jJ’bÃ=VAÌlÒÒÔ¼Ú&k‰¥] °)y¥YæÛUçw1˜Â­rBfMSº[)6Á¼Ê2$̲< M g瓉ٴUËÄߪïÇôš™xEæNS\†ÉÈi*¯¸a™>Ñf·/,£æF² 0Ñ$Û)L©¶”¸ƒxå8»ZV‡5×Z½“f“ `V!@‘@Ù®¦‰ÔÃ(õŒ5ca±8µL{jŠÒÄæ½xÐÊîo½Þ—µc*t5= Ù{/ê$m 6ÙÓÍ^Õ=#¯²M d­ÒB®"'ã Æ˜¸Ä4ñY%\·fnØV+6'TrÒC …·|SÃ.¾ƒ# AñåÄüR¾Ë¥‰f™9E­`âËĪÀªj%d‡œƒÈDÅpcyÍb3~ÉHâ#A~Ú‹ª§¡Ëú%_”?ðì»Gåt‚ºÓ+­—ˆÌgÀÓëj”æŽêb[ÃØ(å¦J¡;†õqDãèÀJ…'*%-fi1}KyGTŸãÒä è¹õD¥G9¡é KpFÐC'Ó¶hr·ÄÑG³¡”ûrQã„(rÙù#ÖíQÃô };í0•ޤíÉT QßzÕdä²ò[¨ðŠ,ˆú£{õ)>-äCÿ—öåA.± 2²H°úm5rÂQßéæQìÐéAdG„ž—ÒOm ¹ée'»u·¥Fïž8"Z(nŽB>C b +¼eä[ FÎ9zÉ0!¥$Ï™m,"ƒQI8D^ÌpWV>‘«”ã5)¨-Ô!­X!Ž@š4=\"ŸöTÙ5,˰…Žæh 'D0,%Šiº%2È'Πƒ1¬§JôKdw•ó"Ï•¯¥ ½Ë~Sßõvn7¤;ˆH„†)/‰BLyrAaùVz ‡FI((: 0µg�ãèÓ3hD)WQÍõrα€Ðê–í]”4D$É#$#ê6’P Ý1tê'kz&Ž|$­3ä7‡(„–,r" qšFáz…~Ðpè)9Ä¢'/@}å$*)bmô„Åríìü`Q‚`c3òO—"Œ@«4½¼²Ÿ®•ÞO¿U‚£R°‰nŸÉoäÆ4µL”²µÖ: ŒåEL‘&s¢U1,sÈ®ý¸W˜û·adå-½–ÑêN,eó¬Zj«`ãR ¤¦s F°ý¸×X¨×bãªã^h‰)ןhžRDÝ1¦©¡ü–q ²èìêX½Hšìþ´,ï¢^e³ ¦j¢’CV&PM6N* ‚ÍÆIñh2]ʆVucÕ² Zú±˜® F¬©%çM¥fÅî]µô­:w½¹ÊTºÉ°—È&glâÓ`™ Þ´EÔ2#”I JtXÖ>6mD3ιB¤š•·Ì,:Ùs¦&z—‰_ ƒ”'eSp‡šÂncÈ¥püHt~Ú{åÑ1Úi¦Í¹ª]T #4F=˜÷«Ù$Þ…}ÊvˆøCyÉ"Î$n³¡7u1Á`0c¹KÍRË·¦?%Ý5LS›)Ž]º9™ç,Ù¥¬K†µL3V„gXž«Äc—̪ð‡¦ÄîêÇÃ"œ!¿º7éyjèŠZ»Ò*C‡¦NÐVìn®/lÉUB;QªeBSÚxuY UÚIÒf·¸f©d[Öžñ,êÎe+­Ôœ”Ý.¿)HÕDx¦D_ªöÆ`¸±˜´ÌËpËœ ŠB Ùhi°:G“§T5Û‚ª ¨!é––šHɤ�(õÔÝZV‰õ¬³Š4Î"²«e)C›,PÉ+¡’ê ZE›­J‹i–æM9±©~±q¤,^Ël¦ã6ÚZçÌ\mY¨nJ5ǧXYdàU"þ5u} m›3)” †[‹U~Ín»•º Vö˜&bÓöL›`e(*`“ÆÉ´ýVVÔÂꦒ}¦|KF³¬,–&~‚Z3^–Ò^<(ϧÆT÷Pó« œöBYÔQ4ÎìšUN&ót¯*Ħ!VóîÃ".,_qyc²U~¯¼nªìíƒqcµi­c¶'+¾1‹Äö¢”¥]2FS¦](•*m:Ë`¸†±fö Íá¸ì‰1éX¦ýIJŽ>s’YUIRê"¶™hC-¶k™eÜh0,ð™pfØÔÔÐT ˜eŠw+µ rþxu#‘|Ž© ¢jú“ÿ³3±Êº£©N£©mÆ]nÖ`Óqyˆe Ë;…•”š¤Ò™aJá³ûÊÃÐ*¤s­EÍ9å Í®8µÐ°…”—³ ×ZPÓX·ZÂh‰²(=.{ÔåyÊ.D¾>=L?©oŠcÉúhÊ/%þ)B•\A–i`J«‡¨lYrš0虂 ã›Eœ¡e|Õ¾Ws59¯Z*Ì®¸—€´O%ei;-@I¥¯)c9tSÍök ŒT×— ¥Á´JP•`3™/­È °)bÂ`T±¬¾=L+}µ¶•ëÅàP‘K)Æ@ÃD¦¬ë5(ÁŠJ@˜æ2“ÑÌ*+¹EI™–d•1L.5Þ1ÐC3yìÔ¹U™  ÇbÈFQ•]L6@5+ š»D-H¯8Þ`é„“‡Ì*y”ˆp¹È§A·S:n08‹”–¹ -´ÃÖfÖ;Å*DüS=Ù”ÒÑ4Ê`TÏ*ÈkGS¡Á|gôÓ@Ý®d¾¡Y•¢Ðìô⑟I-C¥š”`3M-Ë«z¿LY M]@þ*%Æ]31UÊ4µL l"×a{¶-Vú D;…¯Î.›°¥Q>M>ÓdxTLpšcmhÍ”é8÷ÿ³÷ö±‘eç™ßO­?¦Z vY– mË´¹–f¹„(†wœ5T h·`ˆ f¹âš*/ºƒj…=6Ý&ºÍÝ!1H7º°e1K CíÁŠKÊÉ:Ì —CƒhäË€LÙi”ÇBEân£¯dGþP&<¼o{ιœ•ÔšÐ÷`0`«nÝ{îåyÏó¾Ïû<oã¹A.H]æe,q› Ü�œÃæÈNzZÆž%~Å”0ÙP¬Åø.É O¡? ®çzVG.­Âxãniû$oYq«/†xb\5߯×̈ …§X0 ÿ‰G¢ó¶äîîÛBš7†�� �IDAT²”qò CäP…ÏC*9IZb«m«™c—$AíPÚ<l ‹rb•¼òa^¹@úHKüF ZÞ… ¹ÍdD<h2!Ïó”äª÷¼2ƒÅ("ÖwoÐrÿ>‚œ»<ù>ÞjnðÂ˳Ù~Ö¡p‘™»8Œö$«úJÈðÖ)OÝ+A¹‹]³'¹›v£Á#æ‚§ œÄ(Ä2ŠI(è“øõ¯RèRÉÝ4©»S È2xÉÀX33™_¢üÊ<_¢ì¹næwU'yì˜Sâ½-ÔgÑoÃ=Y(rŸóÅŠQŒ×9b#®”#„K­9W®6vŽUnrŠ&w�Sˆu­cºc8«aïôÆ`šWvõĪ"ÆDƒXì!ÛÆ‹!QŸy­ÙÞµxkº]š·L{œŽ0?öjf1I^ºÏ{[0iIÔ:‹ƒÉ1éårs¢H¦!»ÛHò9XŽÝÚ) £"\ãõ‹XäfÛ‚:Q öl¡Â/Λº­¼nWMX…òÒ±ZH|áN<[¢Hò¸Ë^ÁI‹£+êã.…A9'¾÷å £Þ’±maKS�(3±Ù†/=í¥P²$ÜĬ¶â¤†(&óÎ0Ë@ñ©^ãš·iÈRu˜‘€Næ'ó5D’ìf+¾ÿ(Ö‡bë»3bE:–bÜß$p}Lò=qõ„Âå8ŒdaÅËÓ"Šƒ îÇ­°t‘Ç«öf#•»=QRðŒ—ò2Ka5È{1¤D=‰øüúYÇhÓq4]æU†m¢nÈ.ÁÁõE$h¬S 1ÅŠ$T)Œ¶R…ŒžÐU+|,ÝnwÎ]¦pVÉŠðÆd/ЏUŒ×?b yÕ/¨ä•¬¢K§*ãE².aüÈ9šÇšƒ_/˜#‘§ ¢D|#I»Á)›¤òàKDG<ZËQ²Ï,µn2-*ò”ß¶‘Ä6(½¡£¹-Ãn8#1,ÔåtÅ%±215[?ç¦ê19ÝÔhH̃ŒÑþ÷ünëè.¡Åøn‰X©hF+üã÷Œhc «ÌÑÒ›$&žMîÆ?È2%u}/ ¨Àå‰ðv.»V�ROK7Œa¡î_(UTBE»Xƒ-ÑàʺGEbØ. ü3G ùY©_?}ªa&/•Ä"’Á.àö Ï™%$OzMî.¸Ì™aB±œDĽ#'_Œb|7d‹¸úPd6ã®C|ž>é)bâ’ç‰'ûäA¯0¶%¹HQqŠ€ÇQbÍJw÷æ!Z_9]ñ6ܤ‡~`1եĕ; èãD)Þy Õ˜IÕiêy9UL_¶Ñír‹ÖÜD}´K»ð<Yý<~G’Œub³ó²Í!‘'š ,V‰b¼~+G$´xÒ¨ 9R‘»äu¼kÖÉJá–R¼XU"P5%¬Æ©³L%#* ¥G‡ÚH‰1‡›Éކ„X35A�óÔ%BŽ$*9˜ ]\EÈ£ót1¼†OgÒã(z>[§sľCŽCXxsµ*¼¡×¯…ï:>¡[£¼½ÙŽQa‹QŒ×4b½Ñûµc¯®µµeNð|nõöö„R›ªãUßÒÏúm•v›j•¶~¥9\àš¼É¹nfí5¶«´gY¡•®¥öôâEž3_syœÛiUißáÂ*WIíÒe_ç¦Xº$µRou²OdëÞ`²J[Žéé…hµÚ¨ÒÖ÷\à†®È½ÞôÄN,á÷œeYÚò€wmÝõó7fÙhSÝgTŽì©ýÉéù§uÍÕ,©»<æao«Þ³Èr•v•¶ ïÓ·•²p­•DŸÚHïã¨{ &÷\于ߦ:B ’®¹‡Ò4ê´©¦'Y7K{;'”€:ôÆ%ö̲¡3Og¾4B«KÙªôidŸA=!mª‹\׽˞UI÷}„–ŽÜ`Òn® ¦Lêt.“ZºMél�«¯ÓÈ©cQ¨‡y»]"®»qŸ¡°rî¹ÅZš2uo‹ØÅB¶¡8äžâ#Pþ|±Ý°ZððPè¶%ÍŸB÷š¢ÜöꜬn¢2V7ò\²’°—˯@‰B=¢êûÞ$8äº$PEò¹1¤è={I˜eöTåd/‰æf]qçP:+ÆÑ?}q(¢W1^ó¬`ñäEƒV–§p’<qxq„ý¼žÌ¾®D’¥D'1#Ää ïhŽÎã^çø'Ñl[”4HLæ5OXÁI7å På8)ãÕçð›y#‹81QGo© SsÙÄ,¡—×S ç§³KN\ÆJÀï8gåï9œ” Á©æ&�=m o“í«Ë<$9V¢…p{1¾‹"Ö«(³=ª On•YÓîsß"³¨Å­›‡ ÛT ½H´p-ø¼žåh,É¥‡}B‘Ré¼Z¥-\þeÕ‹2V?ËÛ¹ûQ'§5ꇒx-ÞÆÛ ¢ºJ1!ŒpÂ}ŠJ@;$Êûðê^aŠ5TÝ�AV~ÉkNˆi×f˜çî–WYŒî$QÔ[Œb|‡"Öƒ7”²©êRvùxÔjZ½¿C+Õ¨RÕÏѯýÀ9V:T<TrHC+Æ«X,²\¡Ó¡¨Ø R»î4˜TM½/¶Tͱ2ËÆ7 ×JÿYÒ·[ ÄJS:Ú>£349)ù¸‘¸•&â–!Q¦MJz¿J8ªŠ¥|Ö söHè€ÛÔ¬d¢ëaOŧ0vÏjl«n4ËFZÂI¬Æã’îT‰QÝ˽#zÝ…)i=,±J›[7ÚgJY›e#­î$éõ¢²b•ö>ƒéfbÃ}æU»Ò1¸áy–U§|˜¨ ¤Ï6¨Û+i½³åNZƒÉ}FÓŠà ÕJõE &U‹JÏŠôG÷­ÐI^Oç¶e'l%ºt~Ji¡®•Îáà65¤¾ÔŠ¬Ù‚_bGK_,Ù#íü³Åø¼~¬Â%+Š–ÜnÜUf_âÝ&Äî%r4�} ä’¬³{b¦ˆ®¶…«‰nœóŒ C»°éÕÛ¤GýÝC†´K¥ó+ð9÷qi½ª\H6‰šxÊî^æ3š^‹Öi¢Žša;³a»ÐåÒí ˆæŠ êXž—´Ç& õ£ÒõäŠà¼àÉÌó4¼f>WN>œ ïy.ÚŠ‹ñze!Çu´ˆ[ÞJçšz,ß4Äͨ„BéÙp{Fÿ¢®¡„A°ú默E=¡â‘Wñtí¼S4pz•’œ¦ÏkÏ7eÆ]dÝ,«;QzѫƄBÃÊýü[¨ôݬÄÔâ#myÙ÷àõ„ÍËy†“AP$¯m\ÿ½òf´ëŠž›+’cºú£¯SÄ*Æ)Ã+¡»âžpZRžÉá{Òè󽾇¯§@è|x=@§4$¹‘2&·JLr—üögWÚƒÀ•#¬~Ð o!Ñ¥¥xB19ÚSÄãýçÞ¦€hØ…˜|”OþJ±N°ê½’M‡îE {špÆw-êNâÝâ;\H$¢xÎ+­…$ ¥ÁbãuXÅî)ögŒK ©zîBìV¶½VÓ¨M_L5<ʰ÷{HÝI X3•H²VÑ<˜},Q™d¾<÷Û$Ê7Ái¹Åw©ï’€Né N^JÓW;ô¸MÃŽï¨0„GĈ™){`4Éú"šÖ¸v ø ìÞ.ÊÍf(§H7Йu0‘KpQÅ(Æk±"ÝÅðVûÙöòž€“—?ô‚Š—­ Ó}¶††Ç÷ÖVÞ‘U@ÈÆÈPh# k$AÈIòÈÓa§T…~"¡íˆg‘K&§°ðÝP=¬#VK¬w*\sÃ&3_8ÌÑ…ÅE¥%qCNfh1ìEÜZ‚¡¹šŸ‚öBx(oöÖ1Í‘„€ßóî"'$£¯IÄŠŠáU)bevrÄâˆIõà& ¢¬Öí&j¼EܳˊŠ?¹çi :¯˜ŸÇ\jŸÝÍ~õ%Öë§lª-#%‹jQ¡w¢ªµ !Öq£ ‡A¨äw|»'w+@ L¸D]H¢0%¦¿•û]+N/!œE·x—!`õ²Ön?\V`0‰*oVð”§ðÑ|.ýídÐPœx%d:x®¸Y—¿èšÛëdI‰ éú‘ÖNOûÎu<Š^iŒqGX1 %ï¼E?Lzgèzd„+rPü'´œ÷Bi˜}ùFFjr1Ÿhß?Ì­yA+¼wn|õÒhy~›A£n†ØâñO!…†R.ÀŠš¹¸ÜCØA6;“ñnP1Šñzds0þ£» [Jƒ-g’_Þ¨æÄ–€ÜfÌÂ7aç¯'÷0>’ =–ãS8{™E6K6ëMW ,Ê×ͦf•Ú“À˜1ši$t[;íŸî¹…Ð$lëv¿1°å…\Ç)¼°"³p'q*ë/qlºˆ+rÇ¢ ¿ä¸Aæé]Å.¹´ÅxM1V¨âA+VEÈ�/OW;ïoþTim¼Ò”—ç ãežD¨ jJuDËZ±0 EUœž°¶”T!L1õ$êFåâÙ9Â‹Š²H¼|4bT?0&‹Oc³#‡+Ÿ¸4 ŠyX- Ä ½"cF—IèŒn€òó{I^á*ª R4nãu‹XÅvéÔÜ`ÔÁ6â6íf « y𮑠‡*R¥ÈÚ”S¥Œ’Ðb1ÐÁ#/yDÓ 9^g²ÃÛex˜E6¸ñÉ㪸•¥ÅG HNÚÓ¿º0³zŠ3™—û C¸„¼:b¤Ü}FèãÍCX{7»Fhn¨‹–îbd ?¦cÉçÐc³È ãuÆX¯ºL?²‰AB™,…ýÑæÙ½Yõ¸[�¹ ÜFWO#$ŠÄfº²À OÃËåøç“C í¾âÊ^ÖÑ]IÃPÊdQÅÓºµpèF¯i†ÁÄ‹µdê|é­ìny2l?º¼óde¢N‰½ÃãýfÌäýb6•äëðêrd#uEq1^·ˆ•#0Z ª)QúƒËMw]'\¬3Óëå¾¼Õ6–—‹pÞBÝ[â.x™Ìš²ïBÈ7D“ÄRÊI@L?}ŽÛW†Œí¨ŒS¬u:Éxõ¾( Ãjëα•‰Ì€G’ óº1ËæÌD9]\q÷ ë©J‚‡!ÒÃm¯ö˜AÞc“cABNq±Åx­1á6íQ~(³üþüx¦½9€ G äm»IÅP)–ˆ‹4{FË6yÊÑÚLHöËZ]0ª“˜G柰 ÷=†/3ÂçYŒˆYìW¾V…Ú‚d#§¶úÆcsH‡ñ¤m\\ÍFÿ³@ ’ _ê ü'XIüo6ŠþĤ'f@Þ¤@WÅøî‰XIl»]Œ0éR“C[‡hÅ;ÊtȨۅÏož@ÜÈ­`y%}wuöVº`ןl:rLèýd]ŽxOr*1¢Ô‰€zN˜Õt+žŠcLL( f�æ’¨-ùÞ•!SÜCW§oÂT[ˆ£b(Q Êæ†-t±-ÎÉû­#Û{ÂÝ”lQ¥Åx #V¬ï§HrJ ·ÕßZ€cª?DsSÞê¬ã^Tˆ¬ÂäD¸»È¹bðÑØÒ¹ty*Åd|!v›–—x·×¢Â5wB‚ ñ†0¢½º1x”ä]…g…’Ôí{̳áJWÓ+ð¬ÂÛ©D©wn<ö¶DQ厨ŒH´³*e”‹³}Çž/±¦·bãµË FVŸâAôò?yõ|¥’Ç|ë3u”;\0ÃÆ ÙrØ`CŽ¢Z¼,\äæ0âŠÿºxÑ«Òå(Wù­caO•R‘y¤óD›œÒB³K¼*c˜<|Õ6ä˜1拦ê(i"*Ó´ô*¯÷9ÚQ­ z5Q/‹›¯RŒb¼N+öVŒÈŽ>ÔYð"D°ÍdîuT¸œ}w|ÝÉcô) Q“ Dä-¦‰Iä…¹Ù‡$ ›ŽcY£ 0¬¢å$ÓzÓ¥÷Üá‚› Œ‘3«ªKê³oqäõð¹—_õ°lxÕ¤#¥¹+~@5<™—IÀÎîBZ¯yH4 ”“â}c°ééM¬Õ5]'î"%SŒ×:+øÍ/Ü`¸J‚.ÔÈ̸¾N¥=‰Šô¼šãQ¯×*Hå™ÁG<i™c¬E~в·ìz«³cfÈ)—5:qºÄâÌ·€@L@(>Ã2«ÿ‚ºKa„ú™§8tø;‰èIž*,SGX Êa®Gá]`bÓSÌD\,•½G‰çãÕGΧ/F1¾ó+K^¢Ì»ðS*QóhJæ ÓEôj½»Mã¸|OŒÃó%q¿.ªÉäºyM9árfPc0=šž óT¡-yé8 E¯¼‹Wž"H£årܽTmè=‚G]Év,xdKB‰ú¼Ü»ÓÞ—¸©æ g9£TË"†JÁ½™6t‡ÜÎX¶9 å‹QŒ×!+Hð_5z¹¶ yqž€zÌÙ6×PÊ[ ÃÀ¶ËxnIQí¸ he(*­{¡ÅýÁ Qo_¯™:f‘œ™/“+“D¶¼£Ã™ì}DYP|Û—¨_%§ a³ÑŠ¿÷d¿O+ îäà;OT"q]ó0ß){ ÏîÄÓž|FØ)‘ó £¯aV0¿¸x"£�"Ox4‰ñ¸NqÂÍp"<5¹<C¦°¿'”,ò‚„·qöâ–{4ZÅ„üçÁ«ÄL¹B¨šA¢nÐõÂŒ»øf«Vœ"°*5í~ËzJ%ѵ;G1"Lݸ„}Ó^Òm9p7¡‚Ÿ—; Á“‰ý;ža¸•?{1”ÌðDRb~cIŽ‚Ù½K1ŠñÚa¬hpJð™Ç4´Š®¼1ôÚñù‚±%5êIŸ©ÿ ¤qêvC#)\âOI~GQ1ÖðÈ<òlºòÈi±nß<¹qƒgÅ £¼8$£ ë´;Ãõ§æf½ø*Á»h,Ä‹!6ÊA}á«ÀŸ%ñŒÖbLBŒG*3ž[‰Â¨•š÷À¡«¯ ÆÊSz-1À„ z²oÈP°¢ò9.nŸžt’‡áž¤,Y¼7bߘ燒axŽÀ9ªy‚ªDùÓ¡Ë{J™ Û¿âe0/ÏÃaI ïRyxoœÀ" 5§ŽX_³ÿgM톻¯Öè‘9Sÿå8ã?f<Ý;í@Z,žuöäôk£ßùˆ[€òïE¬òËïM¼œ‰§…“q¢ .^QÊÝ&‡MWdõ“Br·g㢷ØåôŠöäsX Q‘ <â{4ÿu£ó1™ÇhÑ˼Cæd,õëOYu’ŒŽ{Ö-,ª=ï?Ñ,nL^=‰ö·yNâNÇ.9Þ'¸G;"<.¯Û/HýeL[^ù6i1ŠñZd“!N ¤•¯²˜DicÑÞÛ}Û$ô¶Ï&Óò<2â"HÄ%94nò ”½õ1Ã4‹éú dyiÒ䔓ã™i– ΣØRprC»‚/& ƒŸ"¨‘D«b÷3{Qq¬ }åæ /…Éç(XŒz—xÉRkã)uåXGW~€—xwAÄ(Æk±ÖÜ"+[a§—Ùs-£+W”NÓO“Y ÝV„¨Å­‘£Æðy÷ÚòK1…¿:hø…˜úb˜]tŠÃÒŽÖö<à}o_·t¨ëúô×@¬/ªO–¹ŠíºN¹}áö%ÖËÅ)6fžeZˆ¤³©h†–gáS¨’IÎþì4#ÇžxåG‹}m1^»ˆ•ûŒÏß)‰×c7Ç…¯Ò\³·³ŽZ^Ù‚VŒà­>ŽéIfM =Ž ´*<©xò«¥õ˜ân¨Ëó ©ó¯f"•Dóxž¼§óäE»™vbÀ1¢öÃh‰²# †ùUrZ¿ó„tɺ`“·IzÕm„wü<ƒ•°p›£–YŒb¼&YÁ¼¢E1‰9œu²ù«èšH°vG°Á7ßÃKÑFJ‹Em¾!¦PçØÂ Gtq†È´Ÿ“åÂ%aŽ‘Œ×QѦ¼óŒ*ÊG/ÍU öÖt¯ åy=»UÁèÖÕ¼XcÙ%¡ÍXN<�Ji„zÃODUþ²ÉÏÄqÇö7a9Ï1è™äÝ£SK Å(ÆCŽX§1¯ ³Çœ?à8†TºýÌ¡§?ËêDœ ݆›h%ŸÐïËÏYEº‘¢ÂH!;.ð@I¼~£mÄÒÑÄô>’œMÿ ¦É§œÜUÛ•f÷xöÚ¤äBEÄPËØ=U¯Š&÷Ü¿8÷¾‹ÝSFÛÑr„ 8%Yš·ËñtólÏŠÕ¡¯YV0”s%VÝ-²Õ¥¥˜Ck$Åäe<6¶kÜÊÁÙ­Ùá‰PM'GD.Aí°a@©0~„*aèÊi,MBQ%›½fZÃDÌ|Éq)Ì3â"LZv*¸N†ÑDeØÚ†XQáù@�)£uìp55²ÉIâ÷rž±@°Óz¬ØN"ƒž ºÏ±¿…bã;…±È÷Hò¥bÙô`žÊ*9Õ¨\z’åÄA@èD4%S<¶HÙúÙ|äÈÏg,€Ãª›‡«¢®Œ^í'ÌaW0JVN‡¬?«Y¹,¢@-€/INkTÍ’Õv t("N7z¡ÔÀì²úè¡VÎ$¦gƒ=VD‰ÊÛ}ÆÌ3G°³iaÀiÒ9Å(ÆCÆXYøSòÚňêñDÿz ØwùmÏ÷/TRÖ†Ÿ<¹ÛxîÃQcŽXR.ÉÙ•ãúwxËV–öí3³qÞÌ" ;yºÖèãníc‹o’ŸÚJ²(!Ó~¤Ã†Þó±Ä`4ÉÄzG [@…ǃ°n”ÊÆ¡$æbC¾ A26šèŽ´vEgÕÛ;xƒG1Šñ1V¬Æ€»1/bUö/?J Lc<á†ÐåÏÖ,*í¼�ïž|ï.„€8æ©‘ä?B:ƒ›üñ4ÜþÙ<K07œ¸ w~b99Õ.+®Ï”‡Õ<U§@)ɇ„IÈP=O–>ÈFô¶ÛUÓÂ÷ê”Ѷ-²b»/ìP88ªÊH¬sËÝÖxO©g2๦æ^Iޣ߹¬ 9¦«ÔÁØRëSŸíoس³Ê·ÊôÉè±6d‚ý~o5ô˜1ÙÀÌ¢5Ì =‘Ž˜þzž`R ¢Äú0„',øJ"ž¨áƒC¨qìD8bŒ˜ˆK´±Ú lQ­,“gÌá¼pÄ;ƒ–'¤MÚûE²@j$£èêíZ1Õ­ä¹rYö³à²A+s&³‹%¢1b½1xCInƒÉ}F‡»¤Ÿ÷ußæüðˆÆ*ÍFƒú­Y6Y¸¶Ïà- Áäï™eÃU u³CšÒn4¨ï3ª×ÛT³³Zò Hzwô: \Fh-r}ŸA`ŸA-:û jeÑ1¸6Ëj•vPçHölPw@áò>£UÚ5¶—˜¯Ò¶c³l4˜\dJvé%HFhéLÒÐÒ,í3ªSJ¿B?'mªšœ6U›‹” &Gh¥(dCß2B+½p[sK)(\Îáå£sp×}]ZƒI}µû~; ½a„Vm-ýú”ÞÖ¦Zc[sâF){ƒÎÖ~hSÕC²Ïà,ú•¾˜fM_½MM'œ~ÖÎ0G™¾´Ï¨=-é_«~HÒ›[ÒlÛqöMXKçÖ¡B¶6Bk›Z‡Šf@Ó¾Èr›jÇUÚÃÌÐìR®Ó˜e£ÎÍšîãTŒb<„‘Ãn´S䵸?Ê#OêÍ^ôÊ3^}Þ-ŸXÎ-”褀Ü3‰Ç�Ì%Qy$KÝx*v.?[_q‡ Nñ ¯Ã7ªOáÉ<p“)вDÄ;¼âV”ª•ÈŠÑFˆa²PÑ#ª[áºÖf8´ZÎ×L!;oQ£“ˆ„GVwÑ¿õ^¿š×uçíÕ ­ƒÍU Srø<•E=Ìz=f‰RŒb<ä¬ ±7y °En0Oç”úGˆVnœŒQ‰Û|ûANa];–ÄD)6A?lmQÊ!‚{ôwïÄ’ B$Qãݰýè”Új(³gz[8$!‰‰’à¹V†w6lQJC¯–â#*¦f•£Šõîž)ªÇá¶Û¼éFXvÔ¢Žö+^ºOâxÌ:ÃÜD±e¹³½ƒÅ(ÆÃXIN‘&/'öˆKž®jŸ„¥šÀ•ãs×ýŒzOx•-OµÝ«Á¸¸0ÊK&°‹´3qe‰£�NÓ“M¢Æ¸á“æUòÝTjŽñMTd!É1ŸôzÂü Ghä†p^Dåˆy‡ýê•%®ÍdžJT!zi!¤óŒHDÕ1|¿Èõ´•QôW¬2P¥òUöÖ÷öw¸`¨= ¾£!b½1öž’÷ï“VÇrþ-/oÅ­GyXìii.¢e›9T<XåªfuŸA+j2Gh­rU5�§Á¤E´ Ti«2d¥ˆš#ìY•BwME#•C¼Œ¢ i¦ÔØvËUÚ:Ÿ´‘ŒÐj0Ù %}ï7ô<Xé.„d–u]oZ -éêt¨ltlér 4žjBz]E-²û Vi»„7êúX%Ï,i} §v¨bí ¢YÖå«Ìce'ïf«¦¥*Ô65•÷¬léü•Ò›Þ‚R…Ž.ü ÿ·*F{iÙ¬d§äüŸlñØcI”œ=óóè={*hUiWiëu«Ò©þtÈÀ M»û 0¼Ãs¬Ì²¡RÖ!À7V˜«Ò¾Ä³ÛÔª´-¶-²<B«K8Ë}M޾h„–¡ÛÆ*ÆCoÌANîž´”®,-ï•"Peg>¹}�� �IDAT×&+³»¤öÒ7 ¦¬ruŸA-‚unZL½¼S•¶Öè40œ|‹hZ‰ÒEaÏnG›éÒÖòn\•v…N¢U]'åk¤a�…ŸY6fYU¼ñâ\zò{é·”,ˆ‚adŶYVu¶ãly¹8[”«´ÕŒMÀ eRá6 %ƒ6UM‹NÆ¢”¶©Í²¡óÑñƒ+t€u]Wº¬ÛóÜ£$¤L‡=MÔ*Wm‡‘~ääv[@ÕÙ…+~è‡4FºÑãÅèÿÆìHÃvžuêÉ™Âeý(,é&êd Чt’d†f•¶ÞÜ¡R¥½Àµ>ޏ6ÇJ™n›jƒúyž?d`œ­ ÛÛÔî0­ iS}š§D²èRÞ¦¦€·Ä<0ÎÖ<Ké#M›ªÞ™>W¥"hã;±J9‹r,Чdƹa;z-(]ÊF[eÖ8x gI_{)'°4ˆ-4Zš…EM„Q:T,_$x”.¦%·D”®ž'˜Ø¢Ñ>£ \S�KßsrÓ¨èçõõ”<Ö‹U"५íhJ/œ´Ö§ádTó ƒÌ²ºÅ¸…j‹ë‚& 9ÂR ¿.±e] Ð á!ôÑ7jJ5!*û v¨£818Ùg4%:öÒkŠpš((0¬WtzîMWí†gí' õZ¨°ÐB†õWJ¯"CB±€”¢R¢iR!K“êº ˆëÜ´cÐ6¨Ó ­Ð©ÐÑÚb|„Ö s]Ês¬Øfë"Ïé|jl¯0·Ä¼ ä0ãlÕ¹©½ŽÞ.cÛÔ.²¦�¦'°J»Ád“ƒ}ÑûUŒb|ûËý¹”ÍVí儨Ò#œ LB¸¹À5Ûkk¥pW­tZ µ´©Vè’°)U=@‹QšÕIè¶¡/JƒÜž“˜róx“¿ËìYZÉ…iÏEx'4ún(™>nfx0åÜ{™«’¥(Óh'6üI€×„¥Ò¯=áªb˜B©~›b;· W²óqÈô-¥àt™)]~Ђ¨¾¢L7äà•¦O‹ß ÜX媛u¢Èɹé*tÓôfDó’›NtB¦þ’;‡úHš6Öû¨ûZv#Òdæuåõ<¨•b‘eDÐÓþx·©-p£Æ¶‚Ó-®X¤YåêÃêP¼fhγ´Äü­&3À¦wxR9CÅi}¶ã6UÝî E–«´u¨ôQ/F1rÄ”tXʦÚóBÔ£ ³J^P·í¿t ~Y J«’w H F,pÍ@Uºú—²iØA;ŽÞРîD¸RZIj¥‹éI*Ie‰üˆí¸Ý•W Ê–ž4gX²¬—$,r8À®ä=Jôe)%‘œpÒ4× {-²ûŒÖi4˜´Pš}[ïiLWó½4tD‚nxMNöO›Ì: ]ˆ[O²¼V6’†­³ØúϬ ¨7ëfÙÉkrœDh)»¹nÞpNf4 ié•ÒÝÀ Ý#m;¬@¥˜4ÇŠ¢E›ê*WËtÕx(;(HërT|ÚdBqè†Ó¢5ÛÔ*t¶©Õ¹Y¥½Ë˜žœCXgJ]Y*—xvŸÑ&3+Ì)Â-²¼À5á°6ÕÀ¤­Åx˜YÁEÕIšûñ©_‰­ÄY˜ӺŨpŒÅ÷Si<(9±ºšeUä+¢¤ë£AŸäÓéÞ<q*ím{æ ô‹_}ñûGuV.ÒǸ¡8ª ᦌ²(ª¥–dw“â§DÅ’}F+tômD ÄXíljg-ãmÁ Û®x‡ˆ6™8 ¶úÞX0°à”XóXˆÖÊmì !]í*”éݦ¦£Ú»–ít¢l)›Àœtî#Ù~|O/JÙæÒ65]à‘u+ÏÐgë"Ïí3x‡é*í>Ž»” mw)ÏÐTýIp¶CEµ«mjḴ;Àa…ÎOް7Åzí1vghŒcWQªLwœ- íý|NwäWæX9`x€C`‘e=NƼpFÅ(ÆCË :ÿ™Ú~�§JEb0{í%—RKNî„i–föl®/'{…aRná¨áƒtïaŽ‹©>‚>«]¶ÈZæÄÁ«ÓøÈÿ¼ú[_›µ•Ñ)™œ”ÐL¦ÅxáÆƒ”ôØ[ÄÝj™! …•p:Tµ…Rدæ"«rÙnñCyB}\¤ Õó5“îÒï�ͽì¿•í&n¹¨Ô1}ÊŽé&èôƒÊ3n@²¸¨ï5|즋c£ö2»[nR8`X¥,d—òEÖV™eCì¾-Æ;TfÙB5§†•¾SôR•®Æö.cGô2СrDÿ+ú–ó|Zð«BgŒÝó|z‚Meÿô-.6­±}…[[ŒWèÓgiÒõmj‰±T,»Åx¸ËÒD¸I¸ƒæGC~‡Z ÜÈæyJÎÛ2H'e-7ì°Wç¦÷ç=ÇÊ"Ë34ÝO21PåæÄ´¾hÍrP‡°žh)tÀYÉ"+”¸¶Êl¶bT ®«$à•’ï'³´6 ·¹;$gJö(ÚÆ<”R œ“tËcƒV81Äé2M,"¢²ùO‰‹£ÎÉÐ/bKÉÀ=ÝUf ÿ¾œþ-›º’[$44.hí*ímjJ ZÍi›ZíE–ÅèÓo+t8Ôц9¨Ð)Óª^an˜ƒ®5™ÑÀ%žíPQê˜b½ÉÌãgxP¦«™¬±½Àó|z‘åœéRVlëPKPÌÊꇆ5ÃÙÒbã¡×±H«ýÖºßrw‚ÝkÔ+Š<ªQÊÍù¸jr¶Ø%Ù€ÔòºDž¬bäRôÏ}F/òœVGyïdëjÚ34õâÇÛqŒ4h ±bªV‘Ê”ÆI›“JF¶(Ò¥œVt6²ä‹ÄIåYNÌ -÷Éq+|º´BS²:J:‰Óh—@²ÂœÍ¡‘õC¡ Î:¹GÕZîäXÌÐi§4™^Öªe)^ts}&XÕÊÑ‚I²Åª^B6yò`¿ZÕJç&Þc›)¯ ]·¸2Áf“™®2°Ãi€§ãžèP™¡ÙÏÑ,i!““;œOw6­®Ý笷¹ÜdFYp;TÎói}vœ-7#ªä-®ˆt:ź(¯ Wi»»b[Œog¼aèg/]ø'ÿüÏ¿ü௒û¿õ?¶?ú}iq"ªrëî©“Øû‘FWÚ“¦‘f4­ô :Ó•8…–’Rm"RÛæíCY fš`¶e~DtaÄ"×M®´CE w›ê Í: ã¬Ärzãl]dM$xuÕ(šf¯{ƒƒ·z‰Aï)rÎ-C@uÈ-KKÁ]å£ jS¶õŽìe>+tÒ©&mp>¹pë(HÙFnÅ¥äîK²¿-¹x:{nIJ³²Ÿ¼_%¤éU²Îf5½wuÍ|ícw©6Õ5¦Ÿæ©EÌv¨ sPç¦(JåGô×iñΧyJ¡n€Ã³ÜŸgiŽ•‹¬Ýaú˜>Ãß"\èWôØ7{34õž6UË2P¦k_ªw¨Œ³uLŸ2–º:N:7 mÜb|ã•W^™þøÚ÷–Î~åå?í´"Ë–'záa”Š‚ŒG=tÁéa墄 Í&3±âsÉ–T±«Ó@R÷‚–ËÞvBãÉj6bE¸\Z®)¬¯8ÿT½‘]‘{çl “B Sç™IÜKV´³e7Àš½Ÿ˜¡p»¬Ö1;¦Å6Û°³349yËP¥ñ¯nï±g;ýÆ^rçÁAcvuƒAý)óÌ[èÒÞÂX3!«ÛNÉÍ…º|]£ÐÏwosY¡h‡'è×+S¬Ñ2Ý>ŽW˜óB`“™ÛŠ"ƒ´v8À°u ÌY´ó�±NlŽ•cúú8V…L´ ©`˜žý×vxr—±2]ÿ€a½Ó¢Z‘,ÆCŽXýè/nÿãž‹!ŠÙ<5IØã»HËÙŒ³Èu-Ÿœ®´Èu—׷Ϩ`“³ºöšŒÂœWûRX,eƒÖ !Õ‰Ðù‡ÒºŒ èr\ðí<PºYG[å is’x×à\i"ƒ}.ÎsÏÜÍÙ8ä?ö) ó ™Xå¡®;\Xa.Žw˜ÞbÜâ½ym(+°¢È¤×û8ÖÇÇÙ:Ëý#úL~B£K¹CE1LÁ£ÉŒ é ·`ZanŽñ&�}ж_F‘¯sS7QKÝîU®Š(¯©3ÔöKHm>Ògf²HÉã[ŽXqv»¸ËN[~¯¸bRu|튠\áz‰‘ò¼'9éOjYH—Ë=ËÚ©z”…eú;ÏäýEnÆ!HM#Ë+óºz[jätI)›q/+äºÅ—¬Ó+uíj‰ Æ`ú½«ö-!í>åhŒ¦Â^­Þ#Z£Â†¸…Ùp5iŽM¦ÉäÆª”ß{8]/㎛#—(…nùÐM¢f'pÏiåöâ™÷6Ã"'%Þ‹¬¥¼žœ•ŒÓŒAªì7ÇJ“uMGzHÊé5˜œg©K¹ã&3YSi…¹u¦$T1Á¦"J—r?GMf¶©M±>Àa“™ †×˜¡5Ζ™.sÛþr«´·¯±}È€§ÛÔú8n09ÇÊ*³¦tU§¡M i«õó³l¨éXõ˜>¼*g Ü0F~®Šñí(»½ätøã¶1Êh€ ó‘[=‘¤ì2§WêZôÉȤ–LÅ@,m‡‡]J½¯º½,¤ÂmªFãtÕWõâ"×êZiŸÁlŠlÕÕ/6\’ma6O÷e‡k3ª¹â¨…ð>£ &ÄœžŒ‰<Y‹. ꩈªËÅ()¦ (¤ÉFɦL’«†n@ßvQ.ñÏé‚JLH"›Ü+ÙVŒŒ –ë\r^I‚]]¯-!eE–êݪP$èP¹Èš:sµ K:Vk³¬ÎÐÜáI53mS;¢_A®CEÀå%ÞLß MÑÓËt¸Ç9åËtç%m,ÄV¯Ò.Óæ Å òx[Œ0ü8/¨`Ù¦:ź†" Š|x‘çFhéôÆØmS-Ó]e¶L÷3|�˜c¥Ce—±“ãlíðd™îEÖž¡Ù¡"§GH–˜7F¨ùš£+beò-ž/F†£SP J\.êrÚ­¼&м&¤Ä 9ÎÚm ½¤ÉLÚË‚5ášÌh*ñ7š2ÎOº\¥¬“•¤kµ©¦)¸:Žÿ…«Š»Èu#Ö«xk)øKTιÓ×s3l®Ù±3!¦ôjœïÒ,«WT°±Ð¢÷+yeíº:Tª£zrQŠg&]hx˽jcŸ[@Mt¤ü’,yìÎ`Ô©ÿõ¨†v³Œqç`hœ[ŸH HØNz²Ã¤x—6Õ&3»Œí3z‡ ^un®3eÇ?`X Aœ*íÛ\>`¸KY'eÿŽéân—òÃgø ±lú9*ӭЋý,÷gh*v*r¨Uiϳԡ²Âœ²©zÞ„¶w;`øí¼¬sVÍìwøªYVqÜb|ž%ÓÌÔÛjlë=»ŒIÒÉ5¤.âV1Ær {²µÞZ°xÉò}é‘•¶rùf¥ €Ÿ˜‘„! ›v·×Çè×Z•º«Þ %ÉŽï¶!›Šyêø¾w‡ ¢/ÊQ>Jžè©xÒ`*åвV!ýÿ"ÏžsDðN¬Oœ¦¥’%ô,�+ÄJäÐä-Ì:Ä &b”UL¨´çø@&ÙLu’fäZ’‹2Î]S‚ÄQÖ(¹ªBFswCò, ÜXdÙЃ£\µ±ÊU݈6U[¬¨ÓPcWèY½joæ`•«mª[Œ+wgyާxúÏ6˜æÀô–êÜ´˜t›Ë–oæ`„ÖyžW<ú9:¢¿Ky„V™î M½ÓäíLÖØVŸŸåŸ—˜Yc‡óŠŽú”š—uÕêÊ2ª}•¶p›@¤"t™®…áÔg°PÅ-ÆÃŠX!Ø*3¥¬ä]‘˜Î ÇÜgåÝ A•ƒNF I8ÌéÛ]jL 53]7Ó,}Víl¦‘}FW˜S«Ö¦­^µÈu™k¸ºˆŽœÒžãz…(!Öþl-Jii­åÀn˜^J)Îa@¯±ÌzrµÇ·†$§ØÈ~¥:7Ó&¶=gª{Š©D“O r¾.qÒ§£ìSšéM4¨Û½S O,u8™ÔV›j›â#Ti¯3%%‘mj³¬v)p¸Ë˜HtZÓ·©³uÀp†õ;w¸ Ý—yûWyLAdz í¸ÒDªK²ªšcåÄÚÐ9|˜ß.Óý” Ö×–˜ßá …–E–'Ø6šcEiäu¦*t¶·-Q‡Š¾q€C“Íœb]Ÿg«ÁäYî+a( q·Bg•«Îž¸` ãáeÓ*½�ÈÚªºÕ$æ_ŒÌŽÞ6ÅNÑhÔÊûNk¬Þrµ…<o7né«T¹t GR/QQ*Í_íYÓŠ£•7ÕÍÐ% r)KfR{Žb/5¶M‰* *'¾ˆ.›€´Úõ§ŸeÕ‘å=áû™)!)—H/õjÜtWCç`Õ#G—6 ×¥ 15"è¥ÇUŸsu›³%Á§E_R5$«)VèL±¾Èr“™*í)Ö¸vL_‡Ê -1#TÐÚb|˜ƒ;\0:x—òYîï2vLß.cBQºq:²AØY6$š^ç¦æó÷Ô uD¿ÊTOð<°É„Ž¿Èò}Îî2–æ]¯m2Q¡Ó ~‘5ƒPÂpKÌ[k×¦ÆæXÙ¦fÏö㇠ŒÐ:¢_g(;.}©¨í¦KR¨ ãab,çïÜ}%ü{N<Œå‰8<’*Œè%kCzPII 1sÖpDÇmLCš‹Øz\"˜´yÉåè>šÆD*Ûj·R²ªnÊkÔÍ’9b}=8hJðv²®°½³¾TlæÔ®)£÷o”?½ž’ÝKÆ÷Ùg´Æv`ºhäˆ$E<.ÃEÈ£À§ø ëPœ}\KŽW“«&^2¿MûÙv³lÈÜ9RÆÑO”첄^ƒº~ѱKY*Ò“jÑd¸Å¸‚A†´TøîìP9Ãn qwŒ]å»”E2–˜WòP£Æö*WÅïØdB€©Ky©ghŠpxŽ{âYœãž¾Åˆ<ÀO¨êVcûWô†y–&Ø\gjŠõ-ÆEåXaNzírqÔµWiÛös4ÎV‡Ê¯½ùF“¯ÎWd‹ñp"–+CVkÙIøôb•'wímN±É,yý�n¦Ë|iÅñ¹N;eûx–IUr…ïLoÉHvSŒYn¯8Ðêd.;G©1™J¯›òÊ*µ’éÏm95§.>=MñA·íÁâ™ÞìÖ±Œtjφ}¶œJiEí„gá¦(é1J®…·ñ'dš3TærbE/7*7™1§1 K¾9”„e‡$š'¸sÀp“(Ôf;ËÆ×V¹zÈ€X Oñ´D㣃·©Ñ¿Mí%Þmõ0Qù6™Xeö6—èïã¸cÅ'É ®3µÂœ"Ó0lªR¥6,‹|:="Þe¨CE:¶zÛ Í6ÕnŒ±;ÏÒ8[ª’^áV›:ÈÎ4¨ “éb—˜Ÿeui‘Qïp¡MÕ ×+÷9«^ã7ü]"?6UkŸ(¼²Šñp"VÖv=“}ÊZ'xN†!Qð‘Ö¿Òô¥”]Wë¨ìÛ•õJ÷=§Râª<$®°'Zá4!¹ @=Éó$VN²M¾¤Ûö @4>BjË;¨œ[‡Š%]7¥r­}µH9¥¸“ƒ¯2»Æ´Ø ):±3êJõ㓦·Irœ“,Þ%Rr¥Éô“)»0éêEÍÐTV(JÑbkZ©ä%?CU}´GéçsBZ/óvM©‰m2±ÊÕ ½Ò¥,ÈÕ¡¢ðÖÇñYî¯0§^«q¶¤o²Ï ’~ýÝã\™®«hÞÓ#´>Äï(¢ôsü¿ié“.eåŠïsV‰÷_ævmm°DVÔ}ÉâWÎóé“Ó¬éùQ U…L¡QYÇô­rU.ŠšŽÙt1Šñ0²‚¦†àÆ0cd9}*&À >ÊIꈋŠ.Ö ¤¸e¾!âÎ¥ÌÀÁ”7‘8n¿= W7ظt8‡Ø™ÑqßÁPŽE ÜsÜK®u½Ò‰:¥´Õ7s½Y‰Ý°* ¢ÅT\D:7§YK5nØ÷Úl›< ´¥pÛô4mUíw]BÔaæjÞ+VÙÓ>ËÆ¦S&¤±OÓ•Ý PmêÜ0š`Ó÷”f´bÏK¼_òGô ¥ ÁÌÐ<|iS]àZí aúùÜ0ÇôÑ/za•¶Ú¤Ô™{žO±{Ÿ³+ÌÕ¹©sâ­²_¢<ÇÊÇxF)»y–*tþ€Ÿyœ4KJ9ÖØ¾Èš¼®pëçtæS¬ÓwŸ³Š7b^áÖK¼‘åÏðU®p¨ÎeM è‚]Ê"èÛëŠÜ5¶ÓžôB·!b%ÁÊ访™>Ê@(Ì=‚íä'Ž}â¼Ò“r0bžËÉ–°«9k«³“9ìY,¦jë'\pSF7Åñ4 «¢d.ÃFúH ã{q×)e¹¶#˜†…m–omXÊ"Z õ–§_Û½ñ%~" ™×\Å#—çî–ÈšZE½ËF¡uÀ°]BÚ¬}­B'Ugo¹Zïjxšbý"kvKÌ»"ƪXbþ"kf*¿È²Ü{7™¶r„|%AÚƒÕÇñen«£Nå¥M&¶©)¨£~ˆß‘¢D?G‚kÛÔ.s[,>cy¬3uLŸtÖ+t6™H®ÂÏx)£¯LWéÍ-ÆuäE–%NX¦;ËF“™kl‹òì2Ö¥,‡š…;Tjl?Î eºà3uàPS³â«NukOñtm¡FåÀ•ò :gŠQŒo1bešT¬ ÆVI×âÏÉøG‹ É#´\Ìj�ëÇ*~ÄIjÞ8èXèº%µÀ˜´*NÚÙê• JÂLv_t´•´Šd ®N<JœŒY’F É,°ÆÈi“Ö ²Ä¦k•¦ÚJô: K'Šòh0+ð'gBWi)»=*¹r·YøÈ32‹ÓÎèe¶HSÝÕÌË£Bg©;Lßá‚öGô/r]ZJs¬ s –£ó<¿Èò8[bFª#J»É5q›ÚÃ:ŸÛ\–úÃ1}w’ »¾w€C¥FëÜ”:í6µC>Æ3:aQ6DÛ»Íe… 1 €q¶¤æ7ÌÁ�‡F5Vú s»ŒM±®&_eÇÙwQȯceüDeÜel…¹>Ž'ØcWœFe>¥ß¡ ­,®æ„”m¯¹šcåÓÓ¬Ùù˜Ê³õ•ŒÁb<„¬ ÇéJDÄ¡J² ªäå bÇò(9‚x‰ÑÍ]zKÊLk™]“M¸õ´ê/<­èôD4lÙMëX' ·[вÑ îȺŸ|µ>­5Îi»åÌÄñ]4ÛLòSg’í MGù–íoÄGxðõkÔú´²šx]hYcL·_ÍH†ƒ¢rHtJÕþ´sBîŸeCì8k塵Ãâ(„2°Å¸¢»ø~ÇôUi2 µ=Å<Uk¾Dù ·¢Ô‡$¡}ŠCUÚúRž.eÅU¼Ô2¬æ,cìî3ø<OÈþMõ2·IÙº~Ñü!î0½ÂÜ9î™]çOêKkl—éÊRd÷9«ˆ»È‚ÜFÖ™ZdYÅ-*ÍIƒI5o1~…[»ŒÉøJ @i´bE޳e„ á¶šÇô2 yÝÇÔ3Ó¤"(F1¾É¬`6%Ù=«ÀFÀç.Îäž›SJ]eO¸|w˜6ï>£³§‡^vK …WÝ܉ˆ£i\9‘0ðôÚà=·´&Êb¶<q\IñtÉ=¾ú™=Fmp¤ Kô„šz;˜´ïuÔ!ï$é4#D«ß®2«Ðîz9jfô¥¶à¦|ŠIN„ÔEØÓJ:Cs‰y%Ùª´W˜gKØEÿcw„–ôdËt/òܦ/²¦X2ÌÁò^¡}­Ý5¶ÌZÐgKðE@DAmX}K¢NCû‰y–Y¾ÌmñÈgh>Îçõ]û Ñß`R̽.eùZwÒÕI0IRiIÅàE®Ó×dæ)ž^`ñ"kòfœ`Sq‚Íq¶×Õ@ÖDZ"ð_]b¾ÎÍsÜ[dy—1Ew…Û!îJQPôW cegi˜‡ŽS(…¬Ÿ@1Šñíd“} IÙ_£AÓe’Ýü£g NÆyvÐÑS8i…’þ’§Ä]ÍEÓÐß¶6þ)Òê5º:8Æ€TâÚˆ¤µIó,ny¼D¯B©¨%¸—,H耆¨ê4ì=n`6„gIE—¶“Õú*9ô·4ÕëhVä0®ÅNãЋ—j–\‚_™®ùÛÔV™cŰéÃëLY|’ŠyÇ q·ÉÌhÂËt‡¸;ÂÞãº_¢ˆ#7À¡ •PŽTeËt¢'uM©œ£T¤èéÞá‚\]ÈD®SØPÄm2#Sž<ϧåSsŽ{}רn23C©³KbŸÁ2Ý[\Qt–˜ŸfM XBWñÕ» Ñ¿Àâ1}² 1;G\±»Ãù]ÆV¹z…[–·bŠõ» I¨Pô×&3[Œo1Þ¡ò‡¼WÔÑ@ÜnBÉ‚+F1¾}ŒU:¥MØöGî’”%»ƒbdºÙÌŸÞÝ ˜bz¶Åµ•Ö~HCÚ^Ú™Û£·­2k¡1%e$ÖÉ” ~ƒ^O‚ 4V‘&RÁ§UÏOÒOf&’Ò=ZªÌ.=³½Ü£—÷+ewN½Ð¥@5BKZ|"R &¦¥µI…ž¼¯®¥ÎMsiéçHÒ ¢HX¶ÉŒ ‚J5wšcåg”þ:`XÅ'}D á)žîRâîEžkPWAH ³z›uøŠØ`r€C5»Å¶CùˆàTÇÒP&[dYrMŠvªúGmK�� �IDAT±½ÉÄ sJ$JTb‹qéÛêmunÞãÜEžëPéRÞeL·@:€ÜÅŒÐTÈ-å˜>¥þDÙâî�‡CÜÕŠ‘¨ÝÀO¿ùù.å“ê8r5:»ªw˜.Ó]aNRiåµT§Ó)F1¾¹:–«Tʶ³ô–'ÛCl]*¸@.f5?=×NÞ)ü”LjH<`½Gu ծˤbUóY8‹\O]K^Ñ=%S4¢GZ$?I?¦‚O'”IB¤ðqÐц@-¨.÷AÚ»©j­»:ÉIºÛ#GÌ»G #ÃTt¨\ßBsú¡%¤¢|—^¥F±Ä¼5*)„Ø’-ìu‡iY=‰õP¦+3ªy–Ì\qˆ»úH‡ÊÓ*OóT™î=ÎͲz‡ ŠˆªŸ ÖÈŠ^Ò|W¸¥ˆ²Ë˜lÕ%¹#)ÏJýÈâ„øâYÜçl“™aÔÆ«ËQÖ}Îj·1ÌŠ^Êa*Ôi2ͧq‘å[\ͤÎ͆…~ÔM5Æî*WW™µºæ�‡£ì]á–Ò[ŒÏмÌíM&:Tú8þ½¿»0Æî"Ë÷8W¡£~jÑO$–Ø`ò"Ï‘öŸ5¨‹®™í«+F1¾õ¬`)èÐ ë4-'…£'Tl—r1–kl0v(¡§v[Í=>‚Cä«»Áæ,±ÓòR²²–Œ©Ü*‚k ©r”Ãz/e´ZMf\Öƒ™~9ÑtÐþéˆØf6.)§ž•¦Äašœ s^2O÷Y6ê4ÄÊæ@-·šIõb+Ñ*À·À Ö*_¥}žOK(V–¤¤¾-Æ¥B$5<±à q*×'†…Ü­v8¯~)¤q¶ZL©ÏduÓ-^Štnμfh¾—…·d"[aÓ§8ǽ9Vú8cWÔùY¢ð‰à°Àµ~Ž®pËÚœMüB§­²–Ä,ÀÔ¶<Æ®R|Oñ´\"%ÛqŸ³BœJ'óB…N—²D‡9¸Èšd·©Ó·MM¡zž%QB€ž\eV~(ãléæj‡J–£ß\ÄrjƒA~Æ€Wâ ­ÞÆ¿0ÊŠÕöpø~ƒ&(žuU7ÿßÄŒÇäÍáÐÊOÊWV|reÒðlS3|fZÆÖûåKiŠrÃtÙU޲Zšö¬ØàÚYµ$ë8U2’·¥gç¬ mÉ)bíYd5^YŠünH`¢Bg•YaPåúK¬Q̘ZT;Ô‰¥B‹VRkq­Ð‘”2Z ü&t¤4 ªDÃ4d`?Àá s—xv˜ƒu½ó€aUz óUikž¸q‡iå!®s³Å Jb*ž-1/Æ‡Ž¹ÉÄãg¹D¿B²ÈR¾àp„Ö.c34›Ì(T±ÛÏÑ siëŠÓJQnSSÀÛe¬L·L÷Y.©¤wŽ{Ò—à°L÷ï½ò?ýß=¯Çl€ÃK<Û¦z‰gÖôÔœ\dí2·ghZrRý^Âd[ŒéQBY)²b㛌XYO&< Qg=è]² a¨{”5]Ó&Ç·äêTk1ÌjTc뻲ìœj׎‹`IR{éBV·_RæÁèHü º ^²Ý»8ê‚Mf ¨eA•é&§ää<G'$ó�(o™M;³ÊU×vÒ‘œ8Ú¦Vç¦Ð• ‹õNI"™'ý! \+Óà°KYJz/ñ~X"µùP·ï Mñ¹åR/Á 9VGª´ghҺȚÞ&åu ѯÞiÖº”GØ3­¦® x p(5,u¤Í²ºÅøOÊá^g%*‡ˆó,‰žþ,—º”%>ÏR?Gš Ic¨ó÷ ¥vgw[gªJ[R5¶Môv“ ]‘.ÜÍ—0ü€3Šâ‡ L° -~ó_‹‘qLß˼xš§€;\P®²Æ¶ÚŸgÙ¸Â-Æëêk0i V!všØÂy¤ß&Æjy”-·ÃƼqüÔöá<Á·G:UmBæŽ=n’uß8™ÉÛ&“¡UÆD%Œ¨i¥£ E -…R½³†Y×§ú–5»HÆã²ôc–ëèùÇ»ÿ•â¹j`‘:­_)kÿÄÈÃ:^EN™cÅ’i‹,ϱ¢ -†ö¬9WP@(J+û,ýÉÑC°é6—=ú92Øgpˆ»#´†¸{D¿ B"û)[¨È'ÚúçY>Ïó³lÓ§ûHýï%æ•Í›cå÷¥ôE+̉î!w«aÆÙ’ðù}Î>ÅÓ"_ôs¤š¢Q—ò%žUø™b½Æöýê6“Q½*Fºje,-r+A'¤(ˆz½ÎÍ 6ÛT‡¸k‘²Ÿ#Q0¤#u‹+—xVô ø×Ðì}C7e˜ƒAZ*ȉd(P¨0Ä{îsö"k+ÌÐgK~•’„¤L7ÕY-ª Åø–ëXÞ u²#vvÍ'*ðÎâ3O2ƒGc‘­ÒãשÕwc•«ûŒ*×§Ÿ­¶¡™¬Ò^à†:´\1rãÒk™¿¡“€J™è{®K¡e#µŽ›÷U6ûçÝÁRŠ“¬‰T†‰nÏ"×í<¯ÕÓz­Œô¡*šÄ‡Dó[aN…rÎ=¦¯Á¤„'„~¦XWTÛb¼KY"~:ìenßçì4kòïèçHËý8[nI©Ky–{œ«±}—!¹XmS{/¨÷L±Þ¥¬ƒˆk>Áæ,«ãl zŠ}°Ãù>Ž/ñìyž—|ß!›LÉnQ',Ù\+E6ÇÊYî?Ë%•âÖ™ÚdbŒ]Ëy¶RÙxà×~àÆG>Ú¸Ãô8[Gô+’Ùÿ–¢<ä1}"Œèa aÙ» Uißæ²Ø0Rm×u)?àÌ¿ùOã«È{yì*}ÿBê‚R“Ò=êãxš5Õ®ú8ÑÇô p¨É_åê>ƒŠýCÜÕÕ 'YEõo q1¾­¬ cX~²nºh)í&ÉTMõnó¾ó´vÑ‚VÔ„%Uþ/©sÓ˜–)é<q„“Tèg+¾’zÂzÆvž‚‘£t<hU+ûxöœ{•KKi�:ÒÔ¥ú“ýJÑ×ôåÔ#5Bk•«ª»(`+ªÐrÀðó¢M÷q¼ÊUõKI”èˆ~ùÍ7˜¨±½ÎÔ››LüÜ…çԜۦz†z]<‚*m eð„ðŨsóí¼¬V-ñ5ÎqO);eáV™æ`‹ñ:7·š§4ó*ÊÚͲ¡XÒ ~È€4/ú8^àš€È0‡ ¨’ôï?â=¢KÜç¬úÆÆØ=Ç=ÍÀ}Îr®qÈÀEÖšÌÔ¹9KCdÂæȶ©çÓ \ëRþ%~óg¤>Õ¥,=ø&3J-êb[Ì”BTü½¿»ð,—V˜ûõ¯]ߨS\b^Z·¸r–û ÿŠè"ú¯2«è%‘&3êGnS½Ç9ë s´’‹"V1¾‰ñ†¡Ÿ½táŸüó?ÿòƒ¿Jî?þÖÿøÑþ‚ 2]VÙÉn«Mùm0–|DcU³Õøé56™– føDy/sz²…3­6ÔvU]¨Ùö©^­ÑõÚÐ;é±fB´Ä)?‘Ýw™‹M¥NOüJ´|Ë?¾ÎÍU®ŠI¡ ÙáIã‘k¨È!Ǧ*m±ò„´¾Ë~~‹q-ñçÙÙá¼$€_æ_þ6¶/ÒÒ¬~XÅ¥ÈtØašÌÜâÊ]†D¿^äºØ‰* ÉžÊìçXmÝŽF*K¨j$ØklO°)Àcút²àPV¿èSs•ðÍÓÓ¬™T¼Ø}ΊqL_?GŠ‚šM¬Å�Í•&¡Ÿ£#úÕv=BëS|ð ¼ë ã«OóÔen_á–NòçD”h0) ±Òï0­ ­¼Ÿæð)žžfM_¤Îe]ï§øà‹º§Jêê5ÕVÕS´{ì‰hð£�¯¼òÊôÇ×¾·tö+/ÿi§}g·›n A´›Ø©Ð”²=Èò(yNN‹\ÎpçÇ‘Ô;a7ˆãî6Q¹îS*b»o0¦œÛ\¥˜õ;ò†æP<™ãª—ÄØ¡½°gš³R<ÒÿÓ®©ëVˆrEäD*‘C‡ôÂER×}‡iiß]æ¶ ‘¸y*\ÉÏ×vå* ¤´À~ŽZ jU]àÆ�‡ÿ’_–êk“¥ÈêÜ´�£ÅW$ õ ÕØ¾Íe­¼ê¬Òêl«­p˜–%!ÌaáJ?A Ñî;Tç¡(JpªCE½MeºªE©%KÚQ/óv‘ Õ³µÂÜý[ŒO°©¹ÎÔ»V¸Zdù)žV6U9·.eEî]ÆêÜ\KÍSXÜeì ·úùp—¡%æ8|œ”Ÿ/㘾 6Å«¼ÈÚã¼ ¶½ŽY¡3ÍšnV“™OñA!Èš ,6¨ë”fhJÏIX}Zβ¡n9Õ&Ývõbi.Æ·VÇJÌñ(Íf~wÍõtƒŠRj6t1BkÞêŸÍŠôzî0íå-CkDUÚ‹,+yhê¦VžÀ&½Ó Ãótû¾3oK£`É%w82ƒ".ÎÐTpÒ3°MMµ.A.©zÛöYë¯ë_¬KËîÛ\ÚÐ÷2`…ƒa$†$éqI•éÑ–ûʃ­2+µ!-âkL¯3%Û‘愮γ3Ζ2“BiBT©MÔseºǪÐ9ÏóCÜ•ÎÐ"ËŠgÂ1ý©à4Åúy>}‡iu Uèìð¤D˜T»Rü»Ìí!î®rU–ó ~©ðµy–¤Â.íÁ5¦»”/s[XM1õˆþy–ÄÎèPéçs ðb*³ª�³ÊÕƒ 꺡:±êû8V,43e‹C fmWd‰MaG=x+Ì]áÖ+ ,JGJŒA‰`)…{›Ë ܘbJbÏkªå@Ö >À¡N,m3/VŒb|‹YÁž¹ƒ÷¹âª^6)ËRM‚ºý£¹Ü|½>’÷[›Éôm½dìëä�]žËž“ßsÛé"̈Ÿ8Áç'nÊQ œ%æÕ+jž[ú­¥ìL GŽV€i‰y¦)Ö×™RÆI á2·••RÓ®Á%Ö>´Ü[FNl‚{œúÑ—s ×µ¸ K)o¦ÌÛ+yn•Y•jæX±DŸÚ˜”à²�¦zŒÔtÚʃ)*(Ûi¹2]»R”Šf®¡ûõ<Oì1ªƒt)«Ø¦ºÎEÖV¹ÚÇñEÖ,÷«I°oÔÑìè‡ 6Õ2ÜÏ‘bù0t·<¤%0¥ø~s–JUÎÓÈ÷š »p…dýV¹GÝÊšš]È%žÓ½ÁäK¼_ç3Ä]]Ú«·¿ÌíÇyÁ Ëè¦IòÒ#îZ^Œo9+HV†GŒ #jàé|;¦¢‰#~ZÊŠh<ŠÃ$”Ò–ÉRƒ#H*£ÞC·Ö&eíÆ©N„‰M”‰¶ž¾”R˜â…+Rcx+“¥ bMÇvn‹,ï3:Ï’…+A»u“ÞQ“¬©Ð µ˜’rVZ°vxò"kS¬7˜|œ¬¥WL?ÈAj‰y#jÏÐ<d ÎÍ» =Îçõ)Å EÍM&¬n¤È7À¡ (…š%æu(ÆDñ0ãAáòú•¡Æ<KÏð±&3KÌkù^b^”nqítW„´Ä‘{‰÷³µÏà&Gôë<u9Jôãžö$x(ë5>7˜ìçH@s†¦¨í:²rkW¸%…R~`“™#Þs‘ç,\)|^dí6—¯pKqBzµÊp¨› %½˜ª_§ºÈ²îÂÓý©±¬Ÿ£®ípÞ²Ó›L(|ÊàXdÅsܓץfRpM!–�Ïšð£ßÆú¨³Ìr(<tå,ÁI˜ +öMÞ>Àˆ”. JÛf'­deS$cKÙ»à, oÓš±Í€-U/²Õo·ðv‚xŒ£a¾úRU³ôµ1Y•Hûz:"&ˆ"ñ,—ôNA%‘¶„²Êw!­1v×™Y@!JØKÑTzB<.ÚÓîÞŽ# ¥k.„&d ¿ÂœüGìSB‡–Ÿìçè nsù)žÖbmì Ci’ÝS<3@Sç¦pª%6IÙ—x¶Åà9?ý~F¶ övÎFîP$¾Ès"òhÒ¶©‰<b$‹Âs6™¤Zòö•"½nÝ5)ÂÂe¯¥Û§³´ú¢h)̽¡''}Npg–FT,Åø1–oܺ‹5ÀšÀ««ŽQJ­Ùó’tW–Ë¢tY©`)+à”¸Lw'Ø$ûz¿@)ÕâËäX¬Ð˜Z>¶Â²–Û¤¥ÆÞTŸpÒVñ5LÚyJ&Nzr>”x ª'‰t ž¤&3Ïr‰Ô“°Ád†rPŠ(ŠUZš›ÌŒ³%I¡]Æ®Ì+„ÚEI­Zú¬ŒtÍÕ‰TŒU?“P Â6]ÊëL­0'‚úœôÙšëLͱò‘ØøÈ5€#úEp—ôƒNø ¤Å§8ý8/,pM¯¶÷îð¤ÎÊL¤4!Rµ�î2ôüŒ‚bm5äªAx˜UËt@]ò*³æp?Áæ>ƒj)“ö¼ÐŒR|äS Ws¬(öTiO°)Å^qýÔ¦Y·e‚Í)Öåt¨¹JD1õu½uª]iTè4˜<ǽY6$( Üá‚85ÊH´7å]sÄMŠQŒWo<¥îât'ÎŽþD8Çi&í‘ ÝíR¶ÓâÑå»»>–’J‡(€%Ø„æ6]3Ÿredƒv¯GÊÕ.ÙKÓ'QI<Ó И‡SklK}ÇÜLJfI†Oj?šeC!AºAg¹ßDZòl’ê‘<Ä)¤*«ÐxÈ€¶ç2”àºmê»”ÕÇs›Ë*b©×xŸÁ-Æ_âÝRj0`6†ãl‰ja[û®)fÓw™ÛcìJåO4 ËÅéãæ·-¥¶Â_€ûÈ>øCüÎ8[ëLIûü>fÒæ:ZÙW¹ªooS½ÏÙ†ÏóiÙKÛP÷B˜L§Ôdæ˜>‘¥‡4ÇÊ.ckLqW0HרŽ4»åGôßãœu݉‚Aʳx/è’YÄU‘ˆ.MéÜE®/²ÜÏ‘:®ÆÙºÍå]ÆV˜3J¤ÔFžæ)q#ÕÑ5žn“æv›Ú*W7™¶{^ßþ)>¨ÆùnÔ¹iŸtËUøã[ŠXò½µb‰¥,ae–tn„ó€TVtüÑ…üN7nÉmÔUbP2íŠu ]Žs•kR ÚJNþЄq3nœ.=]pÊb’Ö5ùNí3ª,@•̱´¶`gµÊU­òÃHÄA–HÚ°×i¨kJ{kRÑ^|n•gÊtUzœYV7±ºS…ódU¡#ô[·ù´:_dí÷TýjS=Ëý}F•¢”´î—ø ‹^W¸¥&âž_C¸ç6—…›[r²Æöç¾öîßûé :áð…"É}€ÏXûm‡Ê8["VÌÐTêRRœoáÉsXSš‚Pí¼­¡À Ã_ÀÓ<õ€3çy^¹¸1vW˜S Oåº>ŽÏr_œx©¿/², |w)Îͱ"´×ÏQ—²DÿÄÂïPc·Lw—±ÇyÉüºÆØ•]¤iª·ZarŸQkö"í»°<ÄÝ·Ñ-ÓÕ=š`³ÁìS<=Ä]«ª‚ϪÁ£ßLÄJuSlùK²¤A×(«§ÖÓ¦­RvÉ.ŠX˜{¯3ÛƒñAÜŠ€ÿ’›Ð$ºzFòí°¥t®ØðÒ¡ ­â–|öRñ¤’8ëS¬ËùPÀÈrqs¬(Õ£µr– 寤fT¡3Ëê:SR€}œÏ“Ú…è‡;LO±¾ÂœT‹,S×Ï‘âÓ0S¬Ï³dÁFÔ�UDÔê¤eî2·Œ”E¡µÉ„ä Í#ú5]ªµ,²,±ó}»”eŸ1ÌÁ»ø‚8‡*5=ÃÇ”InS5«L÷6—ÏrßDÇU�ëRž¡¹Ä|?Gý)öH\J‰¸*mñ5ä=V§aª†¢­kõïP9Ë}M‘Nìˆ~q)…cŽè_eVí\gx0CóWLu^U+“óÝâ&¢Q¬3¥tŸtßL®3U¦;Ï’ËÔ�·ËØyv.ñìÇx¦CÅLCT'Ó)FWz‡ Žï3‹,+Zë=W¸µÃŠÄ+Ì=Îç;TžåÒ]†”F¾—̘z³r*âÅ(ÆBVЩ�‰¶´¶ÍSéÅ\I7eK_IÑiáÑO\÷^ýìÐ]úe¶¿­h&¹²O‰iº…«Ûn;—IiŒÐRY^÷Nö»i×NbŠ´‚€‚w˜Vêì"kâ§™]ï!"|‹1Ζùz¨gK ½–9)ï3(_%•LvÛeLéG#jk±›bÝD€ÆØÕû…ö6™¨ÐQ~¬L×Ê`/ñþ&3Rj2£Ö¨ 68«^磅ø/ù¾sÜSIi•«ã©N°©/ è÷9+µ$̓*=:ùu¦ÄâNÕûÕ6û;|ˆ´¿M<À>Žw{–Krß(Ó½Ìí#úÇÙúõ/]?Ã6Õ†PAnˆ»º •Ä6™h2#Jäór=Ö·Ïð± c–ï2&_1`)m †9Q õ*m}öY.}•ÇC•ïÕcpLŸÌ—ïq®LWýjÂÁЏ«ÌÊ@Ò€´w³8šöfœØp¸ÊU}…p¼#èUP0ŠñMD¬$ÛÓz¢êù[›~eºõNÌÇÝ-Þtîpuf5'.ßϯƒéo[N9Ê…¶%×kÑŒEèùjž”©$5ä”!{¸jŸQ‰þ¥À뙩‰Jñ`ž%mµjŸã^™®oÅeWùJ'1Æ®É7h– “"Úo…çÌÑJY/™2kÅÔÑÖ™‘.‘¢—¸pGôW訂Òdf›Ú»g¹/š†‘nsYŠ‚ ZÊÞæò!–%5tßá¼i#Êtï24ËÆ»’u¸ÌíCä£!·‘ •‚H»¦D™Ó"nÁ½vxRñc…9]©äÛœ!ã¸Ë©ý „©ÃI‰Ó#ú•y3PÕÏ‘œÅQü�ŸÑ÷ªJ_u)Ýšê–ˆDªêÜT+ôc|õ·þËzíËÜž¥!0W禬X$]({FÁ³ÜoP— ä0wR¸A]‡À±61#ì-pC¼9^ê¾[}±X(Šñ-D¬’'4NϯhÏ‹j¯º¤Ž"G_u4ë¨ô({<–²€•`BBÅÏ$ÏlÌfUí½æ˜%È+økDî÷ÝTÕ_âýªµ¨Ò£M·, Õ´dj—SùÄèøZ:8ÜeLÖMZ(e*hRè ]eºº–>ŽÝ´p+Á5À¡*1ÊŒ‰Ð±Âœ5u –é®3Uc»J{i©?Hë¡Bç ·DR—ߣ‰ê¬tÕºÔÏ$ü´À¢~¾ÈšÖS¹‡<ÅÓ»Œ-°¸Åø=Îý¿)Ð)ƒ]3oÔÄ 6™áb›šØã²<^gJrì²9ª|¼ÏÙ>ŽuzBxý¡QxNÓkŒÄ6Õ 6è—ä xÒ Ô +Äêz·^a®Nc‹ñ†çX¹ÏYá9‰'Éßëoÿ7«¦(åÜ+ÜÚáIRyx57™ÐÔÝçì*³ÛÔV˜S–RQ|–Õ§xÚNFUÌ*í;\Ð?åx)ø»ÊUsÓ4áŠQŒÌxÓÛÞ9øŸÿÔPò—ý·ýõþûÿïïÿþïëÑy™þöÞÁ/¼Ì¿Ò+ïàË/Ó¯çé|ùe>ñ2?ä¬ÂÿHßl¯$ð+ð/ôÛôçG478„ÍÏ,?úoø›¥&^æúç"oÚá…,£ýWàWFh½Ì¿Zäú×)½ƒ_x™OH†àë”^拼éEÞ÷oø™:Ÿ|‘÷}€÷¾Äú×)}€Ç9| ¿üv„]ÞÁ—ÿ.>Îáu–•ßP)èM|ãë”>Ì'ÿŒûc~òqðÖ?æ'ßÄ7ÆØ½Ë?úß¼…¿â³/ò¾Ÿã¹Çøë¿àGpæ,÷—ŸŸ¡ùÇTŸá;üxíœù(ŸxÀ[¿HÿGhü;þ«ÿŸý�ïmS}‘Ñ*í¿àG&ø·?L÷Oø‰yß‹Œ>à­ êóä—úùâÎ ñÙßåç?Ï{þ–ÿlˆÏöóÅ?æ'‡9ø]~þ£|â³üCiÅ>Åÿø'üD‡ÊÇù~•ßø ?øv>Ì'?É?ýaº%¾*ŽøŸñc8ó^¹Ê'fùÑ7ñ~¾øFþ¿7ñŸã¹3$ïäÏŠ?úA¾üe~èÏø±-þëyß3ü÷?ÅÿõE~¼É?»Îò’·ð7Ïqáëüý«,.ò&àûùÚ{øÜyåEFéFyñßó_œáÁ¼‹/lpiˆÏþÏõst‹+?ÈW¦X¯ÐyßPDùÇüïßÇ_¾‘W>É?ýg4q~÷-¼2Á¿}/ÿ5où9ž»Ë?úA¾ü×¼åEÞ·Ïà7øžá/nq¥Ÿ/~ï‘÷)7»Cí1®þ"¿õNþ›gøÅá+£ìÝeè ¾H·}Œgþ'þÛwñ'ßË_!Ñó¶wñ'ÿ˜w‡‹¿ËÏ×ùäñÿ´øC|öÐú ~uŒÿ>ÿÃtËt¿Æ÷/ðë_æ‡V˜Ó­ù"ýæ“/2úa>9ÌÁ÷ðõÿ•²'‰ý 6ðÖQöTN+ñU½>Äg;T~Š?zŒ«/1àîðŠQ üã¿÷þÑß{Ë÷üUrÿÁWþâ§Â‚AÇŠ¢äõ�á›`¹%«<DõH?‹nϯã’±ëµä˜£¢.·“Iv¥ß%<ªŒŠÜ•¬¦(uZ}c…Žêùº¡s¬H·Pi1+þ 0)EÖ¦:À¡ UmR5^î·UÚynŠu-»Œ…øÔ;UáŸcE 34§X—õ­Î_˜I5½²Èuuí¨ò¯¹~Û¡"‚¢¾Nös¬¬0'©µ®ð–š´ÔºtLŸŒíõñž0áÚ~ŽD%_àZ›ªº²ÔI&Ç“iÖþöÞ?¨²û<óüÄvYq$Ù [mLV{£YqÔ!l“^$SÞÉ BWÚôzÝ,3Ä$wH vJåÖÒÄlûVíšRO´[ ¹5Øx íñŠéIc³“e$Òî^Š´ì¼LoA�� �IDAT+_»–a‹È$,HÊúGïŸ>oè–ýw¸§T].÷žó=‡÷ý¾ïó¼ÏÓϘìüQäFêÜ(UÄ«–^Ëz3KLIvðÐ̾“kÁ¹!†+Ù±þ«fs…†%š;˜`tš®]*9ÕÃä1¶:¸Ä}Ol€Ñè¸ö0YÇš7EÚEžld9ÏI‰~DÓ29›Yz…ÇjYïåò•Bƒ:W\•Oh-kmÙTÉŽ•ŸZ«Ô[ØÉ|:˜òMÂ(ÙyZåö½ Ótà¦,AŸkÁhn—ŽÒñ#ŽÃš럸ÿ fÝþ½zY#Á,ôSþX¦´;þ#÷<B–,•PZº×:Ü‘S:ä3’V¾På6lG aöáÊûo–‰´6D«ÒÛWŒj:LÓ¥ôÀçBÝG†›}Â^.‹Ÿ;ÃójdÄû$Ž!ý,¹Ý£ Üàä,§¥º…èŸÓµ!N¢v †¨`xs¸(áO!Ä7”Îg¯Oé‡f–ãVíÌÙÃ á §í@ç%%ÃÊèbÚÁáJv>òÓWµƒ @?7NÅ2†ª¡Ù]«{Q‰x¥×0Dˆ+*"W"´cH¬Lt.’ @•5ì‚zýÚ‰çæ¥Ù¡]§vŒ~}[eAüC/#>Ú=[Ód;sòz†—ã¡Êqñ[TÍÑž¡ØÂ5Õ.<≘w¨]ûôOÄ)¥Õ¢KGéàÇj^ÜeBQöSYºhy\_ŸúþÉP!:È28jO¤ãÀ½©ä´ŸöIa„aêxˆax{¬*ÇùûKV·ßs‚¬š„µ¬kü¡s`ó³tËê–ÿ&OZΛ_ˆ6‰±W°+Î!¥Ðx“St‹]Y B�æ¬Û²L($…ÝL ù¡ݼ( ùZÖ,5€Ê‹ °"‡´ü¸juŸe‚ G~œ¾ç7¨ñý­¨ªÙÜ£|Šn‹0«½Mª[¸ÏäÍ“ô4°2OÛ?ùË ž¤N‰žL“ÂQíÌ™„z¹\Án¤«Mª‹d¬xªØž¢ÛWú]L¯Q'ûQ€­‘åYº­B*ص±Õµ2Çù*¶Û™[ µñZÕzoa±‹é v7¨ifIpË’Ëaêþ—²Ds†¢Ù·•3·¥•Sk dH¬gUqŠvæ,­ôT DÓ¯EZ¢ÎÛ¤z–Ó÷óæ2Ót9®§ôÉ"§féöñP2CKg Ï¥9Ú œÍq~ÖRº*?úxÛ[4ß+ÇÜÆHF;w™íÞ‰È%Wìƒ Xvˆìž+¾#Œëßsp["¶F‡Ðx¡ï”„uù2ÍLfœSÎu‡JñsV‡FÃmK5Xu+Ô‹³ÕÌR–+j%Œ0hßFUžFƒÑÂbkÍ,92e_q™Æ®jÇîGÛAJ£E0Ï‘¸¿g¹²Iµ§ÝƼ™OvÆ<mŠ,„·…a×AÝyÚhíàjñ-ѼJ½<{°ù"Û„´÷e>“ acv:ur½@#]“PžK*Ûv1m»²…E_¦Õå®mÜ;Y‚à u2#]*¦ž#ÛTíRF*Ö»s´0ÚÏØ0CN,-Ò2M×4];T1¬¾”¥[ãºpÕ³UZô÷´'vņ6‹”³gCïiž^çA¥@úk`eï²ZJ‹<¹Cå£|Ó­€wª9©¤Ïñ´KÓy.iž>dOlÕܚ܆!Ò}é(—ŒÅAûíâ)ùo•;B !â°3FÒÜS¿ËA«â#~ìjF»o˜¡)ºulòea`èëyÒÜ&|rƒzû<=LÊ=“>gÙ!!-Ò¤d§zgé–{¦×”U )¹‹éMªå+›Õ†¶˜3(s Eá<m½„šfè\£nˆa1•1úÍ:y.Ü ¾ƒ)ë¶eÎqÞÂB†º ¹j‡?Ë3bKú~…½½a×£‹éH*Q£¬Q'�–àvû’ CBPC©Z•ƒr"Ê.RÎ[+StûVVÑÂòZ œU|È”W ãŠ`-кD³ó¿dƒ•îÇ­R߯|k’é«òŠô{4GšÚí£ªT+×Nn}%;¾›^ŽUloPãÝ\¥^Âú(f”ujGÔÚªñÔW²ó<gäõ*¶›X}ާw¨t˜ºÀÙZÖWhX¥~” ŠŒÉlSõO ò¹W]¹AÍïð»êƒØ ´F´…«j—£Ð*7ŠÆ9œžåJ4Jš¥ãÿÆJÄån r ŠÄá+˜ÔUõ q`?„½ö²ˆèœîƒùzk?äÔjYߥ"\,˜ì­Ý ~‚sP&@brrý[YPW»—ËëÔ†}TLóMùµÍ·ENh!}N¸Þ1 ¹,ÏrÚèõi^»µK#ËEB·rºÁIû~Ôˆµ8¤¬ËpÈ7˜8—h–8 9áÇÔâ{Š´&ññ R†å ’€¾À _ÉŽ,Œ:ÖšXµŽ™¦k–nÉž†žã|“òº”«OU¦"ñïQžáeOÆ*°‹i y­kÅÛÆé RœwÖ E£³)ÄåÍPl`EWÆmªv¨œ¦Kr‡ŒƒZeäù'm¥V²3F¿9²¹œ«`w‡Ê¦Ü2®Q7Ê€žYY¹0¤•å êåYXVšŠŽó/¤@v†Î^.˶*Ø]¢y–îqúLT=LîP©ñ¦çãºà¦*'Ò5רëcÜ)…a†9•hࣸK… ¾ÀYǹ³m›4ö“9âRˆ(÷>3/þå'Ó¾‚wÑêïeHÈ‚¥m&§»›ŠGT7å^=Ø}éŠÖi䌆¨º"ú¬Q'ÔƒúYºzž379¡þ^^ѬhŽéÊÆ¢ÜvŸÂ/cŒþ9ÚýD£'Ép«…—©.¬yÒ“bØñá´Kˆ])?N‡„‚˜ "lDÂpDǦð³ˆÓƒÇàMȉOŒ37’ÊÄkfi—Š*µ(tA|+y%‹œ2mµ}gy"côç+y.Ȍȓ»É‰ \s!<'= ãåMŒRIqôGi;’¹àNfîçÍmª¬`¤6ÌrÚœö’2b d½–à¹øqVá^Å�£ª4U²#eC¡©ðlô$½Em!ÃâR’Žã_¾^«—#óíìÅòÊŠ 'Ow´³œöæúÎÒ‚¤æÛ &Qé(?†yq—I.÷4ÈH¡/é‘á“•„öï%Þztk¬„BY–ZêU}ÿ"¯'òW¬S;Ëé(ž FN°!Xe#·ÿ¶Y"]Ù‘3aˆ�YgHk6Vú_ÓÂ5ux @z ú~PŽ‹š†�E2ýÔ‹ª%š[¸V$c¦‘©á�²„¸|½Hú :»Ó¬êˆ÷0YàìýJfÄÞ\¹tÁÿ:Ö³PýÁfšP½µçåÜÛ+“zçôn—A~ó êY­aCétÕ˜|Ííúzج»É ëHyÛ®O#ËÌÈd±-)"åPÁ #›T;•¬ø¬” oÍ2 ´ÎÓ&±Þ‚©›©9ÚÕÂSÉìYž‰íË,ݦ«Ô?Ë3‚CAq�¼žUÙŠÍW°{œ—\I%¦ìF8ÛÌ’é€QÁËIzÔÃuß ÈE4fÅœµªdGO”ËiºBBEíÝ ²cÅ…›c­¢u(ÑÜKÇß½+¸0ñ’×ܶS:H,$yWïJQû%ŽÜ‘n»Íýs M!7¨?äzg‚±g5F¿'J3K9. ù7ßËeÛDáµ@ë­½\>Æ– r"¢]SÅö-žlÖĪ"²éò\haÑ©£yÚîQçT>¡üÃy1y2Ì4³t7±*Y\ìʦ“Í.Óô*¶M™ú`mS•çÒ8}ÎjλDs–‚Ž&Ë*aÒnc— Ù&!YjÓt9ä5Ê—óÂ'éQ'IÅ©:ÖÂq xçhfH¾‰2z3K”kY—ŽAb´¸Iuããó¢bRس|Y¥>°%§åW ‹¢tŒV³9Fÿ:µÊïªÝ¾K…dñyÚf9mÞzŠ|Û4ý]ED¥Ö-+ÝšlS•áeo}5›PV$Säñ*mÍÅ<_‘ǧé§táü–š{ mªÜ¬˜½"©;¡å~%^é:„x®sfRf¬ø}Âuöò5!úõQ¥t”Ž·T½“«RƒVi¦,mp÷ž(Q_M[”Êü 8à7–ŒX­ŠA츷5¸ ü·HöMi³â^¹Xß*ËNƒ¥m{P-¾9Ú#öèü8‘­:‡¾ÁÉ6æ•Ú¡R¬(CQ-"á‡a†ÜPoS%yA`?H¹mJ{õ8/å?ÌŸNÒãæ½–õ6>uú¢j„Y®äÈÛV*íg¬“ßD~;ý¦æi{”oŽ0(«Þ¢Pþ½ (k)C§µ¬½M§µ‚â/¶äÒ9ëjZ•'åšXT–‚á«6æWh¸ÅñNf¢Ô°�Íq^¥¥®ª-;Á¹p˜|§4rìc|”f–‚w®]}«^ì"§dTZY¼z¿L½7¨ËŒ†gTE’-Xq<Ï…mªº™Z¦q…†6æUM4¡J )·P2ãÝ… ­›kwmP¬-žìÎÑ>Ȉ XñtmRí�™"2/Ô€‡¿D,ÇŒuÇËxÆk©n€¨¤—x@ÌÙ %¾gb;’Ië4¨ÇGTŠË)µÐȲµË2s´÷3&wÎN”-¦ÈŒúÔëlD¢^a˜P¶@¥;Ť®™¥¤të¯!üc!5F–‰Ð2°1UËú4]f>CðÃcÓ=K·ò ~Ói¤ ²šÏV³ù Ïú>j ü•ìhBÑǸRnçG4#6²ÜÌ’C?²ŸâóúƒØ#uŸã¼´oSÈ-žÐE5^k¬f–êXSpv…†Mªs\3ËqÞa&•;€,à ÏÇ(ÕçjØhgnˆán¦úogn‡ÊAF܈$azŠnAÁ0¾Åq[gÞË&ÇãÆèï¥kîGw2Sàì27nJTÿû?gÝÜÉŒlß-dÍ…mÌKšp®Îôo5ÙÌR4“sœW Ñ|Lâ`âq2d²-f«‹d<1{ª1±°Iõ"-Z-Óè¸g̳·pMÝHŸí<ܲèMù씎Òqç8̼xýž)[¬²»ð§{*bÀ½’tuOY‡£Yo`ùë4ŸåŠ4 nkÅ’VX<\|Þ¼Bb/ÛÅô.v�w+JÑǸ‘E|ûOX^ˆ|ÑDÈ,&¦érŠ«—Â"Oúæž­'p½°yTuR Œnbìþ²<‚aÖ\¡!Cq—Š4û c·9¡ø(ID%äضòb®oc¾ƒ©<—‚Å`1È ±bÁ› aL¸q¶ì>Æ+ïåëI¸R-,®R/í¥H&Ä&l’¨E8b:rTK*’iaÑ.¢Ú[ ‰#ý~»— ü«?8í7åªÄ‚+Áî¥Yî(aw.|î£kBr\„ ±8»È©cl­RßÁTú©ˆ7´?|7Ëè`XÈh•ì3AVÍ7O{_‚Öáóà½Žï› U?1i•¢séà.æÅáŒõ‰O|"^Ķ”/Æ~Â<”ÆÊ¥+¿¶ßõÖ¹#™½ö£éE§D¯¨*"Kç3¿ËïÈS¡Ç¸cÈ6™ù,,ü"ò–á#Ú‰‘¤&Ñçd– »jXQ(!ž7¸DôŒt’Η¡$$’4Äð0CC aÓc­$¾´BAÇyÉÊLú™)Mê„1ÎtÄ$]]ôÌ#˜ÚŒÏªcÍ©&VME€´À v ÜÌÌÐi”—Pý=@6¹á{ÚyrŽvß3Š˜8Ÿpz”¨SBÝ<ë9˜¼j5¥´³RÃɘ>Íâæ$¹”}ŒïQn å¥å¹¤…¾ÏÁW &¤ï™–}räNáÿgyæž=¤¼eºŠ÷‘çiúwàã7IÏ0Cî!:˜Zä”û˜*¶{)ÌrÚ-K<±z›¸žVº ]+Ÿö”1ÛÉ#JÇÊXo»W<=`{°¡\�ÕÁçiÿ®ÆY®Dºº«øV¬÷ÿðÓ•š ¦ ‘mû$7¨7úy èÛTý.¿Cb¤ëŸ´Ûä¨ÒB¾@o–Â-žçfÜ ¥¶ .#k”í<ZYп܉T§’3-Îd…øë ´:b“¤ÌLÒãäº =LîR1À¨¸‘ª¾x›* ÝY>ÎW\+¤VLn´[Y‹^¡¨h…l…NfÖ¨Û¦ª•5êz¹¬·ïç¬Ø„…–hîà*ЋօZdU°;Ê€T #NMà y_†z’+Øõy–á"â%¢sƒz©}E2Âx¦ Ei%n 2â £½™%E4<s©’ú,Û îbÚ)]‰‘¦«ZÁöô3VͦƒnN±ïq\Ìž­£ZRuò\S¨"´-CÜ6s Î\å„uÓîcZ¸æ8v‘Ç—hncÞ¶ª]î0z6iÁ¾)P”+ÇùiºÆèwZ|™F-ŠRíÐRº*'ëðS=å ¾+)” Ý)°’]gÈèðÆM‘ìƒXf\ˆ5bBÆ{&v¥œÙйK…í f4q]>´Õ€Tø ‰;ÜÚϘ0‡‘­] sY®(Ÿc}¶K…ÐE–+Æb}Í[¸Vͦï¼IulÛ ñ‹´Ô²^ŸìNªÙ4­:Õk>:µa½†e'ÈzÕZÜŽÓgÌ2!Øæ�ò�£L9­Üä&„ ÛT­RŸã|ŽóΓå¹Tͦ”Š1ú] ÓÉ"Ov0¥ £µÔ6U.¯ê‹}Œçɵ1ßËe¥†6©ÎR(gÏþÞ�£Vœ ¬H7ئj‘Yº§é²Ç«ž½užäF„A嬪Ø^¢Ùq´ç7©Vä^X.–h‡ÊñysÃ1¶rœ£ÿ[üœ ^7áÐûwqº˜V;QQ2…)Gþ§ï,W"¤)Ň.Lõ©s{¡]Ö�£s´+]á"Óe# æ8ßÁ”JN9ÎKl饡Xà¬\ÐP*QWPK3)BΊ%ê‚¥£tü2Öa&ú]LÓ;î©zë¶ nÊ™­,äšî²%,yŽÜfµ˜T`Ò 0OŽÄÖµ§ÏΉälÿæÝóZ¯˜Š µŽ¹ÈçÎsI9ƒ˜ptIÙ½dÛ{›dØÇ¸6çFö*Mcf-eUí‹t›¦†[mèVÜÍ”Í&ÕvÆŽÛÛv5 ë+4xJóe(Îrº‘å j„¦z¹ÜËeµ<Ö¨ó2õ3$11ñÍ-§ÌúнZ˜ª«r’‘4Ï¥mª&8—ã¼ÈV–hvËUÅvì<mÚ 2áù†¶Û¤:ONûrö¢Ú¡²ùNf¤çõ0)d‡ÊyÚ‚sÿ¯m œ]¡!Ï¥ujgéö°>Óz±’r^uÍÕŸ]¡á Ï—³·@ëc¼âüÀ6UΛËA÷^´ð¢:X;Tš™9¹á^¦±ƒ);ö�½ð öÁ˜§M¦_àmëÔf™hc~‚sY®Ø¸ž¥[5ÂYN§+òa†npÒ=“ï ‹Ù×Ñ‹”¤NIÚ­tüøŒu§YwP?p55ªuÈ 7mÇŠÁõP·,©4Åòè %Ð^TÔÕyU¡#1�›fn· á(¡èŸá»‡IÙb½\ž¢Ûš&ÇE»…ó´I³‚ í%+$E÷(W®»—‚»içI“İLhuö–iÜ¥¢“™®ºg·˜heA^ß,ÝBPá p‰äR†bHÇšc†vpÕ—­Q×Äj‘ÇI&œ|Ã%š dcôG{_ûo‘ÀÔxícÜÊLbžý4?Ë´½È)W{ƒËÍMªsäëX“µè"ïP©9ý󜙦K)¬WxÌ „h“5JS÷ó¦ßÉPÌsIDªñ®I¢³èÉGŽ4%¿—¯w1=F¿ÒøƒŒ¬Q7K·£l½\•¿qúÆè/_W×vŸhñÔ仯röZX4IK§´ÔÍYyõÀSÀs¸¸ÀYUÕmï'C]˜bpPÎHÜe”½´Q4ñI+’ñ”¬Ñu4Îð²gn;zZEjË[:JÇíãnâ%?úô¿—ågo1 Ÿ~Š·øåÄ•øas³\¹ÅµÄ?÷Ó@|eâu:çþ1†Onñðg¹r‹_NÕ^GÓ’x>ù>^£ÿ·x6ËÏV³ù6þö |ô=l¿Ááêc|}›ª‡xíðGOq¢‘å¿â§‰¯~t1ýÞ%«ê_úù¿oqü |ôstä¹?ñeNö0¹Ãÿô¶ÿ1ÿQ»?Å_—ûªØþ}ºOñ¥6ùT ×?˯·óE›WŸáãïa»…'êXäSgæ8·þˆÿæ^}˜Ý ÅxªŠí?áWøórö^ã¡þÝÈœÏîPù�oü[>ä÷ã•À?¯íñî·óE µÊýÍðïPÖÎ߯UÈm狽\~”­fþì ø &ÿ 9 jâÛßçcôß ~‘“òï_å‘/ó˾ÑÅôüö�o|¯–³ÿ5>PÎÞ<°ÉûŸå·~‘ÕGxõŸòßk.ü'üÊI¾|’/oòŸÜÇ÷VùùóÙ"™fþìW™˜×~Š¿äŸíSö¯þþçÿ‡²y~µ‡ÉWyäƒ|õ7'èýOù?†oW°û6~˜áßá'3|ÃÏ}ŒWÞÅwNñ¥Gxõû¼ø+~úÞÈPÜæ=ÆÞÂõZuRncáû¼s“÷[oMÒÓÎÿŒæÓÌoòþÃÑÎßàø ËПä»Ô<Èw¯rú¿æ ³œ©fsŸ²¦ÿšŸz?,g¿ŠíÇùÊÃìîñîsäOñ¥òÕ=Þý<<ϯ¶3÷üv3æ¬cí»Ü·Iõïþ,¿þß¾À¥ïr_†oœäú ŸúÇüÁƒ|÷8kÇY»ÅôÿÀ?=KáY>ù<ü½Á÷ñ½F–wxï—9ùßÖɺ“™ ~Ö{ñ,¿åŸüåêw¼´3÷ÞõoùPãóüêçè˜àÜ×øÀ·yè÷ùoåÞÇ÷þ˜4qýùÈÑv-/ðc=ˆS<‹}(‹· TJŠi?‘ýÞ¿ ñ*K^_–r×½ýßA¨£Û´º:ÎK’7©î¥ fT°k5Ê€†¹¡zWà¬HûýÎ=Ê7ɶ�Z£Î;ªEîvÝÕ6°2Á9™]$¾Ã‚ª$4³ÔÎÜ(* X¨I¡ý®ûh ” BHsˆ6£»i9ßZßJhfÉ™e2ímªT4Á9«.iŸf–]ªdÇ"2À?A”„R°­GâSìØ¬NNö´=™‚:–¢Ù3lñ-ÓØÍ”[þF…�w¨t®yrûŠv5ƒIßÌR9{V‡«ÔoS•¡8IO/Z+oñ*õ"‘B\µ¬—³'iùÄ<[yRÿýó•1Ö-ÍÝ»ãomRm!¥B‡'i±(•¦™¥ ÁËŒZÜ6ižKÊìÆ°Á P¶AMZC+Cq˜¡a†dˆT±½J} ‹úžh+ÜǸê>ÆÕSqœ>G÷l<Þ ~‚¬=€pzKà†ÒQ:Þ¢+xHç?8~iPÊ'é'í¤XÁθíX˜~ÚÒ:„)!Œ#}V’'ä/h6¨ñ•#¥Ò¤üÙèÏqÞ±Ð:ÖžâIÜ,‘mQÅì˜ÍÑ.gOiíF–{)T³ïÓti<¿HK#Ë9.¸+ØfÈFŸžÅ²ŸÒ¼ØBÁSÉÂQ_­@„úgé®cmŽöpùòC•ýndy— ¡ujõ¤ßÛ E“í/Ñ— Å, ¬Ô°é­‘å!†w¨¼Ÿ79UŶÿ‰ñÆ8ÛÛÁTŽ|  ïv2£&‰øÐ(ÓtÙ½4ô{/ôIY¤E±DƼ®† 1¼&ó\ðBè )á6d[¨È^ ÷A^—¸O¢˜îÄw#ËêIŠcÍÑnêu?!èèÝÑLdÚ<9Ñ>­T&þMª—h–(á›·3çx >EÍ,É\Mt2AV_J¼væÊÙóù,’‘.TÃÆƒæ3½:Õ¾š§í8/9$4°"ÅìUŶíÙÔkÆmã~I±©tü+I9wj¦&®¥"íà~ˆøž.ª²\9¨¥»ŸÎ…GÞÿ¦ìõ®Ê¶z%/•L�h·´kÔ…µ«¬ ‹*M¡ü]!.ùr$de#¼±“:Ö ¯Ë46q½ŠíYºÃ@DÒÄ2“ô,ò¤ˆ×1¶,¹ZYbx‘6æ%.Æ%yñM: œ•ìþ‘ú«!ü\5%6ªÙ´m¨4â2·x„!J' U$## –uu›ôT\§v…›NkÔ©˜×Ê‚NN1\¥†L5›‰¸b°BCW§éZ¥~‡Ê vìR$¬H¦y™icb¿&ݺmPcù¥:â(ŠÚ )зKEÓ–×¾í6Uy.lqLÖ¸užBJ2Ô9e Â}ÔÍ^©à“ —=Ê5)’Y¡Áç$d]ðZ¡l–îsô9”F¯˜¡ô>Æ×¨óÑòŽø¹\ígl…ª—‚þ±–IõT3îþåj})ÞþÞ÷@9.Y ÒÒñwűÞ÷¥3ÌGšhŠÅ[LÛ�Üâá&Ú·xʲÊò³̇›XÝ"ŸÌóöïðišô ?½Å¿hâú™&Ú·ø€ÿyKÀ/s‹é#¿Ow–Ÿ}–ßêaú*§…d„1 ¾Ì/ÿ“oã‡cô„«oãoßàrö¾Ì/ƒLŽA E.~‘Õ_â«÷ñ½þ|ò‡ø¶lq£Šd®rú=l?ËÀSœø~E¢¹gùïâÛÇYkc¾‹?Z£þ,W>ÄÜ 'øs ÇÅÿ‘¿zFŠñ!�� �IDAT‡çiÛãÝUl?ÎË¿Æ ÿÿû¯ð¯z˜~ˆ×ŠdÞÎ6©~ßy˜Ý"™“\ÿ¿^û{åì?Æ+?Å_ŸäËNËfø†À•ØÕFwø™òÕÿ‡w7²ü>þýϲñ‹¼¸È©¯Qû¬ÐðA¾úùÜ-~±/nòþ7x Ã7¾ÀGÿ”ŽŽïPö¶ßÉ÷>˯ßÇ÷„—¾ÀG¿Âãí|qŒþóÙŸâ¯Whx;?8G~‚oÿ ¿"Ú÷]îkdù[¼÷kÔ®Ðð*É4ðç_çççå~ék|àçøú»øÎûØ*gÿ>¾w’ëE2¿Æ¿>Ëc³œùûü¯g)tòü¯ñ¯ÿKÛùâ4]]Lÿ<7fwÚþü1^ù�_ûvV8)þWÉÎk<$ž´ÉûƒÉwò½ß柟wš–žå·eëk|àUY§ö=lç8ÿÊ>ÂÕGxµŒ×Whð?ÈW‹dVùùã¬ý<«_£ö¿w‹égùä>e5ld(þ6ÐÁçzùì"sòÝröšYºBg+ Ÿ£ãøÇß SÅ_ü€wíQþÛüóYÎä8ßÃô ŸzïîQ^$ó*ü6Ÿw~¯>««üüqN½Ê#,ÿ¿í£û8/û¶çÈ÷òYã“|yw_åô6Uïckww1ý>¶¾Ë}ÞÍ/ðчøö-ê®ñQØOc䥣„cí}ûÕwúq‚W•‘ÔOŠ\4¾Ò$Wßáëd'ÍÜ&V¹­”¯\MÞpÿGj;­#]eªpcGÅ ¬Ò$267Ì£–u·ØÒâmÍÅ€pÐÜm¼ä¸¨y•q³HFOÂJvÆò\€ÍPoÒ»ÄžÞ n¾ÉýË4öRÐ@K1žYÖBIÈ6 3¡Z«~$è5ÌÐ1¶Ô¿°'tBöÜBh—Š®©××Ê‚¡ü7÷xDQ’‰TwñÂ0!"%GQâ¾ ¥ÜT+ŠJHI©ænãN ÏÁXWÞ.œïìèë³<SΫY®¨>ŒGDZ£5ÚÆ¼Ÿ¢fÒ•Þ©]*9åkÔe(nPSÁ®5‰‡H¨‘hñ…ÎÅç,z”ÌØ¡2ËËqÏ'$”òäbÝÞË×'8—ç\ ój6GP[$äÁBAc–p…íH/Ò¢çõ(‰mÑÑmdÙõ ½.!eV¼ï ´*bÒKa‚mŸp]»HÜ×”‘µXÍæ×o$!åF)b”ŽÑ䎓Ó/’Ñ`§†ï¤.å ¾üŽ“º_l:ï§ûŠi¬+~zð‹£vìC™%3Ó8}ŽUMÒ£BhÌ?E;Ë<!Ø ¸Î,ݶwðlíb:ËD ×Ä]¤zC™X}9{²Òsœ¿Åâ[:khÇ>G{†—EžTÐÁ™Yƒ¬ï)Äù*¿³õ:ÚY ±¢gyư¾G¹|q¿oBR­\‹)+Gþ9žîbZqç¦{¹,$b~ªbÛд3×Ǹ,òº¦ˆòÎ}\+ØUN"ÆýcôK­Þ¦ªƒ©½¶þ>ÏÇnñij<SΞz"òøÇé{×%X“˜ûÇéÓéø¼KÅ.Î>‡\l+6êPH™!Q½Z¦qœ¾0œ’ìa²ƒ©Jv4g æˆØXÓ…dû½|ÝGKX‘dÒÜ çÌ€®Š¥©*âÙ:¡]Y%;ÞâFóä²\‰‰r #6ou9Q´¥¹ð{Ó‹ÙÁ,§{)ÌÑ^Íæ�£}ŒßखÇÁ¸ÑéMŽO¼I`–ŽÒqŒej©e=èQ{‰Í&™lÕ'ÌÇëýÍ„í"4)-Œ²pˆOͯ¦p/ެ*®ë¨ ]2¬Œ×²>IO†¢c˜$¦ºaÊ>E·L9I&E1 ô:ì@®Q#O®¹~Æf9m5ÖÏXŽó*åè£áDT«šNI‹ø0š†¬übˆaÏÐO u ·ÛbKž¿ÔgxÖïcKÔ*l×;˜š¢;ÇùAFâr<t“*Ø] U]‰ +úÑ-,JJ꟣ݲïu\¦1Q CˆQ²HÆ¢ác|~œ¾9Ú­6€Yºy2X+4<óª34²ü;ün»ëÔÞÏ›j–¾(ÛP·ÃÕéè1Kwã-,îPÙKAýC|[3G5›ŠÄëéUÉŽˆŽ+åÊ•êðö1¾Ce/—abX•,¾<žæ9Brœwæw”'‹Ýú4q=ÆæäÈÔ²þO)G9Á¹*[¸æþã Ï«æ®ð OÈ¢å‘RË•ì„"W#ËÎÎÓ–e"Çy±ú› +}Ñ;_7=d0ó\*©â–Ž]c•è=8|çGéïè­e]ÛÐÄlô65ã^ŽYõiƒ¨#_`•…QVüAª…³N­*;ÊDÆâïåžÍÐy‹_«ß¤ºƒ)¿hfi”$=‹¯Q—#o΋÷‘%¯¢`5›‹œjféõf£pó&Ó©`Û/ÓèØn˜‡È™ùÌV´.«ØÎsi†Î¸.;]³tw3•åŠôèÈ‹V–côK¡´³'ËCíÏa„ÁQTOhfISÀI€&®k²K…Kdpœà\;sŸçcvI v)e:Hw캎µ?ÃÇ—hîaò ÏŠ^B³u5›‹<iA£ùÈ•ýŒ-Ò²L£êS–ƒVÕî`^á±ïe —Ëy.XÈZ~ɤ_¡Á¼2À¨ê\‹´x-§nq|˜¡Nf¤3„h²2®jWÓ¶&mÌ¿ÆC>!Vÿ–òLI‹.TveÕg±]¬ŸË nö1®„J/—CYÏ‘ þ8/)f’·³­,¤æjÊ6©¾‹äU:Žîñ#´Ûïá-¢AÆÁons¥d/Þ ¸:@8<Êê<ÒgeÂø˜b?ºT„RN5› x2²Å±´‘‡XEZ[½•*Ù±'ct³R = ©P@W‰< £´!Hˆµ‡’·Dð^Ì2ÑǸ<4ñª v±¥Ñ†-Í^ ñ‰"Oá!ÒÄêݪª×³ªÿ!)/ýGâÄdsÄÀà R‚‹ÜÆ·±B4=Tä·©’ì÷4ϽÉýor¿^‘$)$ ½ðòèbZqz›®Ô¸ìÞ¦@øBèˆÄ…Ä{¾-ëÔŽÑ¿G¹.-5lç¥èî÷X‰÷¯™%š#ç‘¢KogÎ7Ì““78IÏýò9%GÑËI›7ª²_Ïê"-b­,t2ó:ö3n�¶ýW@´,,¥:¸ ûBqžƒ­N‘9VžçŒ6›ñšÄoï oé8jÇÑnOQÛË’nUYXGR ½À¥ö³L¤Ú}w^2z•–+,+=‚|¥º´²0AÖ Ž»˜!}¤Õž\öô<S³u¬ç¥F–i±Ó¢P¬–Q ´ªîãÌéq¾²M•“FNŒŽ2 íáY%|g§›Yr`¶™%¥rgé6³Ö±f”ÒСÑH:AV Ú>ÆçOpSyÌW²£®°<—Xב¾¿H‹gÒ͉T Õ‰m4•dµ6*2k}à’¤[©ëÔvpuò*¶÷(7÷¨"/!¢ŽµÏ󱛜xƒuT9mQ¯N 2»ÌÍÑþ(ßœ§Í¢a‡JO²–õ EßÇŒ2I©Èy5a­Vú3uíP鬮‘®©ã·GùGþ«ÛõPó¶phÝ FÖ¾-¸Z®ëgl—Šj6MWË4ŽÑ¿AM5›M¬¶pÍ”c[RÐÔêYͪ:'éñ­Ú™aÐA½eŪÕÛ}–g,éÆé ïÍ Î2`ãQè.,ÄlBÞâ‰gÍ‘·›NÐM\¯e])wG‰³L”ÔÝJo1A|§0 9Ÿ¡$'Ýñ I¼‰m$Ö' `¢û¸é|V¢�Ý©\á®´F˜*a“H…ÎÒÝΜ÷E{{2€¢±ÆJUqõÚðw§~blÒרËrE=ˆ6æ<Æ–p…¸”6¦‡%šm9ЏÌÓÖÂ5Õ+rœ7×FÏǽ¶ÕIÛAv¤ÐÉL8-/ð”å‚WD;ó´Y¸”³Wàl;svᬱbRU?Q¥*¶Y Õv¢5Ç­Ã å¹pœ[Í5êz)ëçiÓˆDj† ™x9.Jnô »Ê[Ýšçl~f¹"+!´ê­¢È#q}ìcÜ lg.äÕ]ºYNÅ\¾Dóþ/Ù*¶Û™s0NBJL1lJÈrE#1Õl§érË‘sѲ&VµŸ^¦qƒß¡† ½f¢Œ›¥[­KÏ­yS‰œã-Ž;¯-åX˜¿+³–õyÚ¶©òÉtá\—ú¿±ù°µàc“ày±9N4tJG)cÝ£³w»q×”â©Û‰º‹ ¸Ÿ<Iû‰I$<;Ñû‰îõÔ3·´9‡°=¹ e W÷r9ÇÅ]*ÜþË ›àœNÖ �Ä­ic>Ï%¯Œæò¯bsm»¦…Esž ÛMFÏgw¨´K9 ,äe Uv Û™kgn‰fE’Œ5y.YZ5±ª F»Í,I+µ*»TT°+V·Å1–Üì“GÍmÊ•&Šž§ÅG–+79¡<UkC ç¸hÂ^¢Yžgžá›Œç+ ϯÐ`®bûÇ[Xty²Hfˆa;±·ø…NfÔ¹ˆà"O®Ð OÏ_†âýöÁæh¯gU†§·,íÛ²@ëÓ<§å•x˜÷±‘åú“okN v¹ZºH’$ÑéO;P—³×Åôç*ØícÜíÎ:µ‚|ÖǶ]Uùô,‡ÕgŽú­ç¥½ò}¬~Ü[HÆ1ùb•Y¦èYzO@Ê(æÝ:ÖšXUµ„D“Å¢_>ÆU3ñMÂà-Ï…,‘ïÒQÊX÷JZ©¬}¹ o¢þ`Ö¹Ý0LåªCØþ½$Û÷ï²59šÇÌ]˺É&:øó´Õ³ZÅv%;* I7ˆ_®eÝI®3…øž«šYh&²Å1Gh-p6ðJ/—ýþ:µ{”¯S´=£ÞíýŒ…‹£<o3ŠTõ¦»Td(ª E2l”¡¨í¯€]*Žó•cl™Vh0.ÓØÏ˜T‚6æ ô6³äO-È,­;mâze‘<O8Ï…5ê&Èæ¹` ¶ï´Lc ×DÅ,%+*“?G{7SvüÔ ÏRX¢YåC#>ЋýŒÕ±¦öÒ*õzþf¹bdËγúS>,__PкJ.¨/0%ô1aÚAMu¨Iz:™‘ ÞÉÌ åìõry—ŠqúBšÝ÷WÁ½‹igãÒÍÒÀ¢<CyíÎc™øCËʽE ©€çú,æé //Ñ,u~˜!VÔã’ºïl*r­v¨œ¢ÛëU­ÑÒÊ'j€Qõ6Cʽ”´Jo¡Ò´z‘*KÍT…óHY:æ¦G†jÞÖm2Ÿ¥z†ijû»¼ òI¦p1ÍY§v‘Yà†õ EùráTÆsÛë ¤¸#~…Çt|ئJU;f-,ª@êÎÚ˜5ÌŠ…¶ZY˜¡S¦œž ¥IzŒq6åÖ©•èãP» íb:Çù6ÊÙ3‰JŽX£.ËăÎc¹Ñ6*]ØÆü næ¹1´y9uì:Ya-“IÀ*õ“ôÔ°aQRÉN–Â-~aˆag‡M·Ú© 3CÄ.£`¹í<’6”ÒcWÌ4]'¸ihV”ÈSfH*æ<mV'ÛTi8™¥ KÅ:f‘S~?tãô™WL$ÒðnP¯dŸ#Æž‰9R‘Y…¸Æé“ÀÙÂ5µ w©·é~BÐQ¿´g±µF] ÂNZ+;éâ¸&=Lö1.ÏÅ7‘Ñ3À¨CZ>Ÿ»TèKéÑÀŠ‚U _Åß:µŠ*ÛÒ´Å5VWýsÐJÿ¥”ŽRÆ:@Sí¤Y "µŸLkí'0Ì…ñS C˜ô.Ð+Ý3¤ÄJ×£®†T®Ûucô+9¶åK40*¶¤ê«Þ1’¥Ç¹©¥H&�ÿP”®›”'ÇÅ%ší:ÏæÅ2¾DÔô±Œ³‡¦^Ü�£*8zY¶:ëarš®,WQlJ@ðâ½ ­¡úkaÑúF9»›œhfɈ©€º8ÐÍr¬Wh°¶³Ÿ6Ew?c-\“³—#¿G¹1z:çŽE§]¡a— ͯîar‰f%ï욆“¤Šø†þF{˜”°p†çXicÞp%õÊÙËPT?‚ÄJqÈ9Ú‡õú^\äT'3ó´Å S€^¡Î·È)‹0QF`ƒšAFšYš£]è[vØ€ Îà¦;{’mÌ{Cc²øOlq,ÇÅp¯¶›çûç%5…¥ÉØídFªK˜z»½¡£ ä¹$ÑTþªa*FºÑ—Kž…ªŒVcòn’v÷¾z›:F¦ÌÍKG)cÝ Ç:T4q=F¬’i­Û®9ÎÇD‘Õ˜-ă;£ýCoîðV©ØU5&8+J´@ëíîå=tëˆRf‡Ê¦ò\ŠøåWÀ'æ_,~ ½ZÖ{)( n²ìå²)dJI‰ô";é•5¢-éè’·Þžð1>¯Ö­Ýž›‘º™¥VÂW¥ƒ)³ˆC`«Ô‘E°Ö¨sSz©’D°ìty&¦:‚Ã0C‹œ Ξ=+Yˆ¡€5A¶ƒ©væÔ€ˆ¼îOkYcSd“j•—h¶+vµMUWoP?Gû<mœëdÆÅ§O‰t\ÞŽIz*Ù±)7]ÜclI¦·öŽxE2Î ôãô-ÐêDš|™ ýw1½Iõë<8N_hÀ¿Éý³t;’ÜÁ”so¶ÝÔw÷$ó\ÐÁDßÈôÃiªó×5‘Y¥¾ÀÙÖu^¸™%©+>½®áíÑ<tTÎ X®•…^.g™°äígl‡Ê¸•À,§}Øì –¦²JÇ=j¬„¢s�kñ=Ø$euÛbX¾Fšûž"üìsǵdÿ ùçè&­¬Îq1\Ç4´µÊéå²£²E2îÐí¡ÅXækÃÙ0C!¦ý–zVVd (mîachô½|ÝaPÕíPás¬xV£$d+Í@bSû/˜Yrmc¾ùÓtùM_ÜĪbÞÓtMp®† I$žÅ£ Ý¢Ëä(´¤õe5›Òß+صu¶KÅ4]f©hÑ÷³¨ÒήX/—op2ÊV)p¦®ô,AÛjÉoqL­YN›¨l$nqÌPÞÅt3K²f&8'3­Æ0Cªo¨«”¥ÐÍTÓ̘29åR´² ‡³šM-•­;™id9Çy«Ie#VhÐ8x™ÆV¶86ÊÀMNØ'¬d§ƒ«r‰‘¾ã|ež6í¯¤íÅnÀÖ«:„öœ• ‹Z°‚Ý"·­êbè¶åj[%/ÒâXžwÁbK'3 „š&W²3 Ê)7¨wøOóÒ°;(Gù8<Aü/?ÑèøÞÁN]Œ—e™pâ5®ÀtA–åŠcFÜ!eÜMdßëä£ÕŒ2K\Áy´Ç¼‘:<ýì}-Ð:E÷*õ‚NòÚi HLÅ[ÉèÖ7¨Ÿ¥[`L„Lìj;™‰ÉYRÃÅ~áÜñ.¡‡+‘ÚÿÕöÞÿdäýü;+ ñZXaÐ�¤†‘Ý9Üô„©A?&©9å¥9|:İ[oqÂìžùëþn \ ‰ÈJc:¸:AÖU ™]ç©-Â\d‡— ‹ \’ñêГ9åf–ŠdÜLøYè´ä«Ùz˜!e5<ŸzVWüÒÓNOé2âÖ!²ˆÃÂY ΊÙ8õ© D|Äf¯k’>+?xšçžãéç,ö¦LÓ5Ȉ׾L£Ãé9íEŲ“Pl<ôú(ô½®Ð½õ ô®ÅãÏä”,(ÿá?f‚ØzWËî9B®šX×AA÷ïI\²N¦²QÚõñžÕÕWËb1 œuP¦@¯¡Gö`%;ÊÐ À£›©QÜÛJ“[ìOÓú½ÊÔpèÇÁ,nJÉÎmfI¦œ8G3KŠàùzJdgƒ„ Dé±%• šÍ:­ü¢ËX¨ÞÛȲØÏ4]¶Èä¹ ë²ä'8·K…—’»,KÐË,ÙÌ&’ÌiçœD³$ì)f8AV¥ÿ$P\) þ„^溚O>ÞkÔyÜmaáâ4°â€]†¢o¢VÓ(RTÔ–-’ñœçi[£NJ…Ö—ì ªiÈ»Níƒö~í­ôù E“„…©UQý(ùh‘$ÁRðÌo8p–ójŽ‹M¬J>ô¦(¦›eã¶-ßõ’V/q‘èËѯb{Šn$eHV±}ƒzKÒ¥`d¹"…G†ªr…¡Ø;¶<—Âò´"”ŽwÜÕ¤: �z“ )T*‰ÞnF©•Vž 9ö1úÑ­°{훎\•† ä¸ç©Úd½’,WXÑýÏ­txÞë±KÅÙfÜ »?ut‰fuÙåKÖ²@ }[¸V ·‰á"‰| í?f9½Ææ­78ÙHÖ. Içîǃ«-_±Ž5 ޽0ápè6Uö¬¬#MÆæ`£pãòå4R iZƒ& U/´Ž”•r¯"T5›Ò»=Ÿ%šŒ5“™éµd´Î3ò¦­)kYoášg¸AQ3±· Üa¬{Ô€¶,�¡˜¥[uÁ(ø¤8ʈ1[X£È_7(‡ŽŸ7+Xûfj6ÅùœHOD¹zÞ5ûV«y.Õ±¦º0K÷qn‰êàfð_²\‰uèg,Ï%‹ògyæž]¢¹ù=ÊsœÏRÝÇøåù„H"¬¥L³*ˆyö>�žXÌKæ¬eݢͩ…Ý NÞ`_3”Džôº(+°Ÿ…B©Ò*áXw5©®' çþAVzd”;¸T¢Ô^–”Y«w‘¹Ë£„T™U2¹Ãõ¿ÁI£¹ak:…hàÕøÕøâw†v?Â`�<–&ViÇy©Ž57õÜ%šÇè—‘e,Þ¥ÂpéËÌ"Bb¶+eÍy.¸ž¦+r °KÅ:µ-\§/¬FjØháÚ$=M\/pVmx³ENÙóÑ×£Ž5CmÛAŒV X²‰Ð]ÛŽ[ä-rªŽµ ²rUôëc¼Žµ j@V…A­ »š£ tpU¦¸²åæ0ão¸6«¼n3­ysªVÂN)ýá;z»˜¶M'ƒÜ¾V#Ë5lÔ³Jâ+o>ËqÞi0ñ?y}kÔɸ³Aê\mð,Ì^±ÿØ F4.„ÓYV0,қ˨]ò<m¦Æ6æi{мÌ3<sèëÔª·T˺tÐMªUñ·[¢y–î.¦çh/’‘>£¢ O 7½‡I•YÒ m¯hVµê»˜ž¡SÁ”PåÈsa‘Sâdà MMƹn“¼ÒÈ¥£„cí÷_½þ‰¿tÇçáTeª$ÚO÷�Ä«>…Wqh¸øn ÜdÓtèWý:ŠG˜¼Ø VÞ•JWôrYeØ /'ŽïØbr0Ó½¼»ÝÈ=NDey¡� ¿Nó‘P_ /Mª-}¬íܶ‡Š®ªƒ¾Øš@ÙxŸCÈ)H€U‚a¨h^´ÌJËþÆ Y䔘–àÊ¡ÏÊqq‚lÔ|¡îj™xH8  ¨W\ÿõs7š§-O®@6KAêDhõ†â°w¤’66¨ CK³`ŽJË §÷(q½Q¯Ü6õ1nŠúá;Ê~ùo® bEW-ÔlmÙYÀ‘ ±‰0)×ëÊ+Åkµ7«¹y·ƒ«ÖµÆ…>¯9ÌÇÕ[ãÉ 2€ë¡@ýå<\ ϪžÕ×yPRŒ7:+(©»•p¬;‡ŠAz­Š œ 6`hÝ6%ŽÃQE^uP÷ö@DNdœêC>ãP'ð(»àŽ•ç’ܰe;¸ZÉŽzq³t3´J}–+6…bck¤ÈPT±mŒþcl 1¬nžM¤OýôEyhÆD½¯ì}ꋎMpNF»9EäHÚ£¼‚ÝENIíãŽE$jX 2¢'Ü„!†­ŸTÈ©cM_`k÷øŒ6³`rÒ€1úÕ\°u¦Ê‘[u.$z¨èÑÌR'3½Ymg.Ë„Í7G˜uúO_ΞÍR ºŒæ"|-Ziø¯€à“ Ý›Üoõæj¬Q7C§(‘zŒaÜÓ¿Þc¢G~ŠéÐ%;Œ¢³’½Ž‡Ëª·'©¤ˆ¾ÒyrýŒÍÒ=Á¹ô7b¥ –Îø0„N’wDÖ~äãujGÞ#á W²S «xã<m·ø…¸A>cÑÞÔ,{›*=̺jcÞ9qi2Í,‰Î†¤Ö·¨RWÓQè5êäè·3g· Ï¥ÔÖ¶„c•º‚÷‚‘Z$Ù+­pq{N«pôº~î*K¿[j‹T–²'¦¤ÊìŸbXÝç8ïV– Möì ɼr$È@iÖQ³®…ká•7 2_‘Ì¿ýË'gèìbZíœ(G€òÆGm¼#u¬)Dë©áÕFÜ4]=Lª¯ã`ŸØÃäë<8Àè-žp¬H¼Å@¢ƒ´AÍž7¿NÒ£ìo ׆²™©Þ|ÓÔ8Î,d"ûCo;oÆPO¦Hf†N÷Uà ©ßê 9µAr–n…Û]Ë8·ÿþ·Å1sƒËÕǸSJRÿsœß¦j†N)æ:q˜üüc±Ð¼Å/x_m‡Ú°mfIº¦âë$.'áé §­—Ëî²L8ÞÌÒ nZóÍÓ6M—,3<¯gXTca#â[ä«ÞZOpÓ*Óp}›ª0o\¦Ñg ]ó9fËÑf¦¥¼–@'3®­óéÞwSà #Ë4š’—höQ_¡a‘Mªorb‚s…+4Øuë3Äp×C#ªt”Ž{NßÙȤ¨¼¯…JRÑ~ÒÜÏrå®â€*Øâ B.G¾Ì/KX¼ûQqF¹SŶJçÆw%-ìölR-€±È©^ nlÅùÝï;µÚÂ5wñêœb^>�� �IDATV±­}­Å¢y›ªENY'9z¾'ëÔ VMÒcG·‹éà¼õryŽvE+ì}i‰ÒÃd“½\ö=[¸¦¡»òNf”¼;ÆVŽóy.ÉL•Ðxƒz™÷³tG6 ™Ÿ$×™ Q>*ÚM"FÊ1(Ãáðløð1ÜÎÜÝrßíLmËÙab¸’=ÊÇé³î©fóOX!ù“ZYܱD³R¿ÆÜQÆèw6.„géVXÄ5+KL3æ“6îòälÿ.Ñ|†ç­ùÌN_Õ²Ói&ª^.tä´œU¯b"@޼/™ó<›YZ䔲,çÉÙÛ\¦ÑÑ1ŸŠ:Ö¤«xJî�œ$ëfÊz±•…ñþ:ÞÅôå}Œkmú_¥¾qkYYšŽ¹3#¡>¶²ç‚qãnD¼tñŒ•ÖLû¼[o)áh¬&“Xw Ý–ÙŒN~7ˆ×K£Ä‘¨ÌèUlg™ÈqÑàmªœUpÝðª{H#˯ðX/—‹dÔ„Õü E†o»@«Šb9 J#d¤ŠmÇxå*Uè?[ÃF“Stç¹d q|* Ÿô ’êíw$…7±*ý̱ÓIzh­`w„AA¸•œX¦±—ËÍ,©Hd 4xµ1¯°½‚‡2°oP¯sØ"-LŒw7¨—¸¡£¼ùU9Ä�ÌjY_¡!ÃËÆkO^1'ŸçŒ?RFDvÛÇùŠ$l›lmÌ[º5²܇væ¬`Ô°°ˆÜ°F]†bžKþÈ¥ScЈ/sCp“¡"oÝ£r|8{‘˜Î´1ï7…9ݨK«””Î,Ê*”<NŸe™ÚƒE2æõmªÎð¼ŸeïÑŒ¸—ŽiçÌ%š}>Xq(m†Î[Yp«d¶HfŽvæ}s‰$Š2+Îëå(ë.³¿—Ëî$|’KÖz¥Œu8]Ýàd2`qHÖ–¨«HÍT¥ÔÜï¶-.K÷ýRZw µÔ¯åJëÎjÜ ^àd"AõíÀôrYºèB^}£Íâ®\lã×uÎŽÑ_˺5ÓÓ<7M—M$ã{“£ Œ0hA¦¹‰±¯ƒ©1ú9%t3%§@ôF•ÌhdÙ}ú #²ø<s/Ç�'?Âá'Íw©ðwý\G¯l†>Æ–›n oÛTå¹äµ;Ê£€¬ (c¢|¿xk5Ãw-ëE2µ¬g)h;YÉ”ã.à„|æh£_SN ‹¾rŠî¨ æi3oSõ^¾ÞÉÌ.a –åJŽóëÔv2cÏÐÙ[U*¼‘› ESà(ZIɨ›¥odHHX+×°¶ ò&¤ ;éc"§ÏœZ$ã@˜79áfÈz«ƒ)åíúsFõ›&‹T—+¦{˜ÍÊqÞRjd‚s.Â8}“ôØSÕÒÏ}“û5ž6C›™‚%oÁ­u\ÐhöÖ¶”±S�ê¹£âµz—3Í~ª<ºƒKÙ Lø‡‡‚Ó‚L ¬“w=GYMö·Y-–#½ CC k¯ç–˜ ;Á¹p‰S±‘h×ܨ‰Õ4騦ê›<jub{ͶOtÆz˜ÔºP=Sƒ¬B±n…šœRO\e <úÊÙ[¤Å®ZÞ* XÖnùCò.ôñT¡u¤-è]²Å1K@9 í̉¨ùV$ãb€¹dœ¾`xH¦oaQí+¥`or"rÃ"O’RLѽG¹CÁvðdÉ[?å8ßÍÔ6UM\aÐX.ŒÑïÍÒ=Â`SRÞ­&87ÌÐ 1ÛÊ‚¤÷qŽö*¶?ôÀ‹¢\$ “nG$ÔÄØ²Yd…†ôkbU‚ßíÚsT°Û¢ OþºòWN4Ña{¯Æ¿=CÕx?Îg®µ«é÷½ËÒkYwq‚¹F&~“vª#žåŠâRmÌ+Û¨?€˜™˜ò†‹œ 30MݸM”?â[Û£~¼ã­èa¬&VoÜÉ.ûI—Ø/܆^Î’<ÞÕìr°,±ÜM—Z‚Ä GÒ²åú:¨SîfÖ�¡&‚|¹:ÖÄ«C.h–îQ,œ2¶©UÉŽa}‚s*»‡‘¿XÇš<é,W$[Oó\jgî8/Ij�Zx1Ku-}ôïQîìQÞKAm‚"Î$îY!"·K…5Ù²í4r"8ü�+Ù9“V –#Väx©C©æÕÇ-R4òZº˜þÐ;^ü‰¿a‘!ÏÁ×{&îBx)8{ƒŒy\ͤ ve„;ï1À¨4˜úvE¤,mEå—»æ»TX™*ÔQÔ÷rš.ƒøFÖîœç0IÏ-žðfY+7±*OR0ÒŒh“MZ)LÝâ‰=Ê¥ûËæðëvæäu{€}ë°åB…^ßç”eš¦«HÆé°„lS`”\á²C¥¡—9†;“m·ç£­Û¶8–¡¨›¨O ‰ cŒIÔ°Ñ‹Yº)ëaRÑçÖ[JZ¥+é Ú÷K!œûIº’Úw%à–ƒ(Ô}¼»-¯œõ×s\LKèr€.Xv„XY>NDB¦Ý?o®¦V›Tk·h¿(&ˆ1’ÚÁkáÚ•öv4Æ59I-³Ó¡ªq«"?tš®púÈR§Ok®iº†–â¼N­¾nÏ‹dnñ Î6²ÃIϺ=—A¤üIzޱeKM(K^›T®†°;9îºW¨rîJVK}ŒgxYb‚ëö³ŸçÂÃöÍü\*ndºU’C\j†Î /»2’³5ÖR > Ñ£AF2¥fX·5°"ûÎbÂÕ¶zPKI´O²_5›“ôü¿ÛÂâ&ÕºIÙd³2®acºç_à©Jvy×Ux:έ`Xø×gá%ºYÃÆ6UÏsƱß-ŽIì¥.”Û5±ºÈ)ÿ®…£Ú˜w'áƒä$ƒu¼’Zö™cœègl‘–.¦…»Ü[¸V>QÊ7{³Šd¤³»’Nˆ›®œéÞ FPÖ?^.OpÎÌg;'jJÇÑ:î­„KR%‰ª,-†û#g„ÓÉ/=b\–â¾—¥^PB;â÷#ËDŒWGÆE=$iÐM«öŠÉº³–h¸‘US±$*«ŠÕ&"O·çg+Ø-gO:€Ê Öˆ¾Ä6Ù×ˈŠÈÓ3ÊhEèÉÇü/ Uf„²¼žX»Óty-!ÒJ2¤,êãK4g)Øßó{)yt•ú¾ö£Ò£ƒ)ûK1ôš>gRS–\ÉèôÕYN;#lÅcq ^­Û…Жmaq†N×PèÎ×HI˜¦+Oî&'\ö*¶XÙ æ7婇їÑÜŠ3Æ¢ãB¤:½«~GŒ ïPiÍwHºÉâÏ6o¼¹ÉÀïçV9¯†³WêÀ² L ©ð7ñ$c[–ò¾2Ka›ª=Êcúã|æ:'}J­ðV©wÄ®ÒOÉD„nZÇÙè@})\…ãÇL§E(¢J™cŸbÿ ší=œ®$»G-•ö)¾g…‘8Féö Ñ\DЩXUVÕf=4jT·Ôå5™édÉb•cŽ qXißC ‹¢;R3M—aÎÑÀJÛ™qÔÔØ¡]LûM  5ê´ÆÈr¥ƒ©(wÄüýߨ™tâˆF»rö"YÚ²Ú[¢Yˆn—Š:ÖÎðü<m9Î2PÉNž ‹´„J½Èy² vÕgeÀý¾‡9Îë)]GI™9&5N_»y.Œ2°Å1óéJãf’¬HW«Ô+àHâ=$úR9òÎ?ÍsšBu0•#oÕ"&ˆˆç3®O³¶(5 – r‚›­,Øõi­ìglÖ^ ±Õl¶°X$£üñ•ê46±êW‘ÌçùXL‘›-|%È8,ÕÍ”óÂÞYAw¨´PÇš~Êi¹ý뜔ÿb.\¤ÅE•ãkZY(Ðí„yÚ ôŠeŠœÙøñºJÎ#¥®`:ý¾µU•Î%©Ú‹t½eKT–ËÒš„Y®8­Úƒ #±ìu¾Ô¡.pVÿò%š³\Ñ+ÏØ§cVŽó¶ª"pLpÎÆ‹ ÉvS¼¡âë*õÅx/ uMQ‰˜8ŽÂn’ž:s\Ôð[*ˆß ¾’5X×±¦_×YÉÖ·xBP¨`÷žŠý¸o.û±‹i=ãöò {‰¾aÈg´² Kp:çpoñÄÝ£ ¨×7E·8“°³St/Ñ<IÏ݆oSN%;[¶°*ÙQÂöà4]ª¤+5«T¹n¼f”Q–hV6Þà.²¸J} ®‰"#¡ñ4Ïu1=ÈH#Ë^Ës<ÝΜJöòÈ3CÞPí3|\ùŒ,WÔæ?œvænrÂk©b;KA÷g ëZÖ'È:q%¡f•z—e—Šeçh÷iñ^÷rùc|Þ»/›üßM¨æ›„ÕŽ9Î-4°bC2 Ä Å^ÔŠÚ'6^õ*^:Ô!Pm°EžLTâîl‚ÅœÒq¤»‚ŸøÄo&%ÔmídH­sÐõ*¾sXuð` ,»‹ø~¨ÇXÂQ÷#69}’ƒÁ… ƒ+ûHF±WˆOvrº›6ZáA•.ïBÏÐF¢_Dßo˜¡röÆéÓì*Ä÷¤u(˜d›.ÚeÑÒ‰s&±çùDR¬ åéØU³tkJ.Ò¢‚Š^ú¡‡>¢† Ï„0} Wt3¥†zlüãbí’µp-–Q .[p ׺8Ñ:ó›¡ßèÚ†øžåã6UíÌiÄìw¼±ò¶I-”Çèß ¦†~Æl÷E7rž¶>Æ‹¥6‘Ä ždlMì@ZF“x-ŠyªvYZYD¶ð¢T©ZÇè.ŸËtpÕÞ¾´ˆ´.etkpÉq^{ú ÌP<Æ–mFXtS½L…MZñ øH„'JÇQé ¾%Ž•çB¸âþt·ÓcJc° ˜ ÛKáP~ÒÒׇÆî]¥Œ…£‰ë­,¸òFŠt¸Ñv$PCÒ0CÎi6±:F?cý-ËŒÝ ž G‚ Þ1'ßM±WƒÚhØÀJDO¡‹'û]}Œ÷3fIA")kCÌØJÂÇ‹Tâ³^‘G|’è §Q\#¾c§¡ KâµçßÃdš¹gè¼ÅÇùÊÙÀÕôÆLg>sgž °Ùý“/pZø Z±‰!I¢‹ù ¹ jü1!±ÅŽuMÌðÍEž •^AGÅ…IQÉÅ-¶Ô®íg,4pE’rä=CBm²ˆTÁ/Ý‘Ž;,ž]*:¸šçB$Úí„꿱£šà\ØEúÜ ¶‰­Š‡¥QC/<6 ¾8m Àaº÷S‚²J8Öíº»‰ë9.Þ«–:ôoYâëxû; Z^–êõíÛã²\[§6ÄV]¥ã6ލç“s©B>¶¼Vh°õը䍖Ú9ÇyÉn¡ƒV“ôlPãnÚÈn cÜ.¦'8'ºÓÅô ꦣ£_Ru³2âœ^£.Ë„V„2¡qúœý”Þf:™£]Ý(ì:Üêc`Ñ ¥ä4]Ò€—ie`ž¶[<aØrã_Ϫœ½cl™ÒœE­fS‰G‹Ìj®úu›Tÿ¿[äq©h~\#Ë=LÞÏ›\] UëKË,›T˜?=ÆVãõ¬*ë·K…±[Þ‘Çó\:ÁMå›^W¼kåìU±=G»×+&4 €Ùc¼âHÙƒV$‚ŽBe!³Ý9%wéyr;T*“h9âUlS5ÈH$ÔF–çh_¢Y´I®à R%Æ{ž3µ¬Û¢4‹ÇM™å´bHýª|!—}€Ñujƒeê£å“¦T®µ£ë¦Í£ìÓt‰š“ޱ哣ÔKäÑ,õ Ä¡,…²—Ž£u¼ý½Öÿ½6ì¿ùÝï÷;ïùÉÿ÷K_ú|z‹a²Ùâaø$|> ŸÜâak¦[Ô%ß>ÝDûØ_ä$|>ÙDûûøÍ-öÙz¿YËú}ü0yÈ>ù>^{¿¹Å索«O'ÿñcÿ>~h<ºÊéïóÎóÙYμ<Àó•6¾ÌÉFâµ=ÞÝÎ?À×~‹g;yþavßÎÞÆß>«ðê9þÙk<ü6þö§ù«¿â§ßÎ6y¿ÖJoã‡5lü ;•üå-Ž¿¿ý ÿG=_ÿï}œ—[¸ö9²ÿ†¿Ÿá_à£ïãµj6ßÎ^ã¡væþŒæj6Orý1^yßi`å/øÿØ{ÿ°:ïô>óždE•€!f4Hf0f”8;CY)ËDÉÄP¼#KÙJ”,5Ýcš m/7šb9¬Ìf±V±D­{U¤Eç*)EÚV²&&0™FA6aÐRi LWÆT˜Á2£Ae8Hñ‘™ýãÖùú 9ÛÿË—/ ïyß—ïó}žçóÜŸ/.’cß?§ñßò÷·pe7/³õÒQIßm8Ì?YÃgÿ0JÑÓœÛÂÛÅßÚÀÍßäb4|Ï“ù}Ž¿†Ï|ÄÚµ|\Âð(Eù¼ó¾láÊ4œ`ÿY?$g„âïðõ?aç!Ž}–Ÿà_ü%e?fã³»ˆñ]ôþc~q„â¯òý-¼}‘í[¸ò9þú'|þ5êò™L'þïøŸ6òã‡xoެQŠšùL£¥|÷E;9áí‡xï=z”©g‰}‘ë7I½ÀŠùüøÊÿÁ7«9s‘íÕt‡ßø_YLJüÃEÒ×ñáwøúmxˆ÷þõ>ÿ~ðE~4Iþwøú¯óç'Ø_Ì÷ÒXÚÉùNþA/·’ÞX›ÅÜgùY„±·ùrù¯ù_¾Á·¾À7r} W~@Á®à_˜ó}ÄÚÍ\¥èaf>fí7øÖ»ä¾Â?ýSþîŸókƒü~~ã'd|‡¯ÿ!µçø{·Øp'~›ù~ö«\(çñ¿¤¬„áÿÂ/ÍSC÷Z^(廟姛˜‹0þueüå¿åïäE³ðu|ø ¾5JÑNÎÿï´TÐ÷]~%øZ>~ˆ÷Šù ŸO'þY~úK\}€'É/ep/¯÷RyŽ]9Ì %VÒûY~ú ¾'í=Ú•¯òýFþÙZ>®¡ë7ù£r·p%“ù*þôòÓ‰—ñ—HíZ~ö$Ûÿ!±RÝüÜ>~ï÷~ïõ ß_³vÝ_ÅüÞgÿ¦>J¢FœÜ¾Js +Á°HKH*ÚïÑíÜñ' ÑhˆH໫­¸g|ø“Ù¯û ˆQ_°slî.M›ŠQ¦rÌf@ QNÉt(d¼žãr»gÉÖ,C€:®À¸¡xŒÈ"éQbõwžTJì5¾\äÃÖ^ñžýÉM)fDc]!B~棋šnªÓY´!äU÷9PÕΊ{©Ôê"‹¹ ´&Ä]1ųb´&Ú¡Ix„¢0àÆ¿•ƺÔJø†ò ¤"…ïUN¿$Ã&Žd°pš½½TŠ·Pd1MîöxÚKn Í4±6G²˜›%;hñe×úW+ÎPœšE5ZÝÈu÷ódªAˆ06K¶fž5tå1eõU=H1#:Nùüir«èÑq„bMªjè¥Èdt”ÇϳSõf?åE\å±ài¢_L;Ñ#4™õQ±DªÇ˜ìª ±¶Dª_AÞ¿çd?'z©TªÌ²†®q s™¶5LI?O™4‡€ªEA'ÒëÏR(½]Ôˆá(f¤…c–C5ûþcµ=>E+F‚ÑëTÐï%,H’~IòBM sljáb’k€+ÍJÒô}e¨»_!¼sІ)Yi*v'Ìè2åè’pXÿIÝó<™öºH¸XÕÑa‘J”ŽË¢I¯Ùæu§TÀ„-…s2 '(¦d;cQN©>·ý`e‘t G€|ÕwjæÉUGnuë {"Œ…˜ÑAýFZÕ”§´`eU𥛇lhG¹…+Ú€mgl’üíŒ5ÒšèÂ6K ¶cäð¬Ç¶Hº«ášJ®¥3EûaÒÕßžû¨ˆ0#êiOô·ŽÏc=-“ùrúuÛj m˜’QÕZŽáI>“•ôªÝw{aì4{G(Vâùo7Õ–­—¾Ês­4.QÂðzn-’^Âp>—|~+Óä–0ü&;$b˜gðûÔŽP<Na ·MeÉþŸ¾-ƹtU“zØÚÁ¨¢T°ªR£ž˜¤^*ÕÖ‡Á ÍÊyÃÆ•ŒùŽ…>¥‹†Z’Pó§Ðû³—ÊŠ¥=‘PlN“ÛG…÷Fp’[i~ÿ±ú"–ðõ¾=ñ$øã“PLqˆ't;$¦¯âÉË®q( uWfcñ¤d‹»0«û‘–|EŒ€^*EB¨}ןâ G%œf2¯Ç ŽNu®€$Y.¾>_q„*¯Às²"ÅU4†ÍCWàËÙŽŠ±/O(é¶]á¡çêVZ#Ä|.ù4ÛnÆ3X¨¦{œÂí ,h«£CX‘¤]õý% §³#*†.`>æÉìgG#­1¢flåô÷P•Ë´âEFÙ&ŽÔs¼€‰6’¡é…Œç2-H·ŽŽnª«é¤ÚÑvTÒ+­#2Mn}m4þ"…‘íEÒçÉÌfvžL!IN×…ißLæÍá Ø¾­=?õ)b2ò™Œ l˜ktsdéÝôPÕBó"é…Œ»A4±ž'3ŸK&šŽ x`ÝTK¡ì§<èeösb€2ÿj i¤5“ùfZ^á›3ä˜Êh¡8Æ>½Ä‚±–»—R=NßßÑÀ¯8¾†.7C&ñɨC©ùÞóªi! »¼ÍNFçܬƈš™ô­ô1À§àxb|JE<É}8- ‘wÇFëo6ÁНüèxÐh¬æpåÎ1ì ê"Žâ…;g²6G_ké,`¢“Z-‹‘QÂpbUC– fïMôi’[E˨{y·Øf-€<Ó0ûå,s`~ ÔSª–Î „ZUóN(axš\Ñ|ùLngL¶E3Ï;!”Îb9oŒQHMB,P̈•¥::º¨Ñöpެªšy>¨±7.ˆN\ |#2CŽ9s%EBü4$ ß KÉBÜs¼jÒÙO9PÆ€,%³)G»9gEKUç‘zŽ—0|ž>?˜úõÜ ( ódîåt Oo8×FCs&B{e$[ oáŠWPë)ô¬ Š‘À«A—2ñ\¦Å^èé冣žXÉy™Ìç2]Èx>“!ÃoÊ>OfŒ}SäY¨ô=‡)©'&²$—éJzËé—¾¯½€:õY²…¸›]¹…¦Ä­ƒ&[Aè½]GÇ²Šž^*3Xˆ0ö ßôë$ÿýÇ*||ªºý^8IºöOæ±x)ÉOëΫ*ö@¦ä®¬=Þ;•Oúù*ÜCÅ“/A²´ ½˜%W['Fý«6W:'±œ•q;ïF;yFÊ_aØ,ÙA­ºOµ´²u+á³|•ß*³}CÇhÂy/yº+W8Œ&jè*çͳìRä­À=yTÈ¯ì— 3IɃ´.…É:i%ÑlY<ÜÙ3ì™#KÉv†\(I92åG7ÐÖFƒ_§ŒlfÁ{zõ" ”©cK¤Š\š#+©oòÊÉ õ'oFðIÔ“ºÿ6jè*bôI¾íÌV&ó&ÇùL:  hž‚<—éànA‘(*—Ä8{¬&´·//ŸÛÃ’g‰$|pК[ÃôŽòJ ˜CÉóa1ö¥v7a+Ü-ž÷=^,¿µŃOxpw’Pá—~MûþãçíñßP·‡Ò_Rª¿«ÄZP‰t5î!»ÓýN†9ùò¤üì®òW|eÜZQ6¼ç%«"Í2ÒDi7Ì[q63`aŠIÄ- \˜„#”̓f‡NCøý׉¸•F÷ ý”‹ëvSÿtʹ úÊy3ƾ"ÞÒsÖ6»rFZMŒ%””‡*z*è3Kk ­•Æx97Di ÃúGÓ‚R KvJ¨-9vP§M¢6öá $£öê9®.ÃÆØYj}ÿ=œ"r‹õû9‘ɼdŠV»¨‰±ÏÞžYšš9œÊ’ŸRIopv¯¦û‰ oÊ ÂÃU5Ý3älãb?å�/²mšÜ'ùöÉÍõüÀÉ õ…Œ?rn#×…3-’>AA5§ÙëצdŸM‰oúyª†.ÃáJÏû2"Œíç„r‰ýÈŠcD-÷RiÉq‚ër‚ü‡)1BWÑÓGE=Ç…`okáýÞ6–ôœ4üX´Ìgr7çÜC¨Ð‘·äÝ(Ê$œ·3&{^§1ƒj§ÓìÑ*·\å9ªxê9î[câ!" ¾’ú÷«´*Iò¾ÃLP—â!%hL§’Z¡$ü ’B]²&ðŽ+|’¹Æ½0æ´d9âêÛCÅ!-PÆ£œš!g7é, ½Î`¡ñšÕ–ó†ì5f$åû¨€x!ãŽR)«sŸ«¥ ¢®0ÀÊú¨x}yW!ã-já˜-.!ñý<åbäž½•FÅoCDŠoˆ±Ï2WÚ&9WTÈx9ýºr´p¨˜‡Ælûg1·@†ý³&ôKìç©jºëè(â­&Ž(Œ4—�&{Tî…Qå€ý®£c;ccD*èÛM§‹à›ì(aØv ¿ÊIòûÙÑMu&óKó™ôغ©~çf^1#š˜tQ£×W=òΛiïTNÿ<™Û¸x†='¯E/¼´£œþK7[YævOÚÏþ©]Ôh¬UN¿Ä¿†/²íÒòcé,zz»¨Q&cGGUÅ<™K¤š_N“kÑë¨e}õÄŒÜ~/î8Ká¢oE1•¥ úFy\;Ó¬>*¼Ù,#‡:KÞaŒkdY% |Å8ÖícñVm·M†Ç©p7Ͷ'瀗WÇWS˜Íl=±(§¦Éµ‘© çØ �� �IDAT(yoØ^߬ʈµ2fÜÙ¹$JyiÉ Òî¡W¤…¾¨:øärVÒ¿*ï‰'åõwIqëSO«ë1AA3‡'(ˆQŸÃL Ç"V læíy2#Œµpìû Q$Ê ˜ÐÅÕ†„T‚€E·Iîà§ÉJŒ}}T¸[±'¡²ÃA];–Î ˜(ç ßg?'D”vPÌœ:¨S‹¡ `7z Ÿ”*„0ã\€ôfÔ„â(ë9î½ÔÄÓDß¿‰#6Ø€jºwÓiÇ+0¥0˜†J>tŠö5ž™#K_f¿£&¼ÙÌšeº]°ûåAŽé¡*ÂX£9:@Y%½F^ᛂr4ŸK{9}‹õWØÒAݛߜ%{š\®Àì,Ùm4´ÐÜFC>“³d+Žw#²Hz ÎTÒûmžŒµ×CU}öðrÔ*™Þ›ÕtëÑlÁÍ1dOlríÔ Á;Lª`,BZZ,`BŒu¼>*”Þ4qÄÜ:ƒ/÷E¶ÕÑá¾Áñ^qÉe >=Û^èIò¦J}Œr*F}mQNe—ájœÂrú½±-Î3F¤¨jø3ìñø³˜ `îûîËÜWyÄJ Âô¤tûN"•p¾«‚ww$³æf°BJÔKC�K<ÿ“±­ÐÅI¾ÇW«WVià «´Îd¾žãódZè3,õSÞG…šõ€ûè°[ÖST-”ÝÕ<l½Sx(Ó.ËÖ…‘nªËТ7—éQãÜYj[8v–Ú&ä6é;e£€ ]þÔ+ æ0:3RÂðQªôS7Êã% ËJ¯¦;!1Åï¢d2^Ö?èµDªF”ª*ä™{ôs²˜ÙAÆ`öɬG-QKç�eㆯ_EÏF®{r^àåY²_å9íFÇ“)õ×ÙXÆÀ^NÏ’ÝÎQŠú)_ ãM\Ç:ÞÉQÖ|ýýϼtê-4oáJ:‹é,š17q$E?´‘Öœ?Ï΋l«¤·¶(15÷*à3Xpö«Šž~Ê­ÝŨ—ya‰¯•ÆJzÍÅóIåB:‹´6s¸ ½8³\é9¯ Ï䉄d€²Ž9GáÏÙ×ÑÑ@›Ö,_1dUîcF(® ÏLKÄmU% kꦨÝ;YE x©°Ïaæ"Û4WSp_Âð}®àýˆE’Ÿ}ü´»”îIáäND .p-º‹u»Ò¯„¤puo[+MKɤè¸:ï˸²Kµß¥¢´7ó¼j·Õ–¿X¢Z‚í@ƒÝMg †-ÕÝÝÛáhçÀvÆšyþûG(Vb¾›N«a dôSî2dÓÂâ›Ü&Ã’«ŒÆöÞ fK~Ъ¿Ziô0r˜1BèT2M®ùDcDìšH� VOÎ+¤60;œÊRÈØô›"bÿÃ4QcIç¨V ':Dn{«é¶ƒ5GV Säyh³ëa¬‹š(±bF.,ï#2@Ù(E d<Ãk&”ÆJ¼½œ²“óÝTÏ‘õÒò¡[¬·Â6J‘yØ"é©,Í“¹ž[À"éòjs™ž"/—iiXÓäöPe"eH[ £™–::Iòñv¢´Zž5õl¥±‡ªm\ [“fž÷.§°ŸÞ'žÉzbF²^*ÏR«­Œá3¹æ¼Hº#kÎQtP7L‰{&]iÆ)´ü8CÎ$yåô'Ú«ýódN“k.e²®ó‹ 0æ(CŠ?N¡Ÿeô5ô¶ßÎX¢aqÿ±Z#VRïNðHTBJ¿§Õþìl1öù‡Dª4¥}ˆÒÄèqú â¾j݇ÿÿ2-çZH( ZiÔh*ô4{máX=Ç6†ñ KÞdÌ“©(ÆÅZ6«*ƒrÞpMW.ÑC•ó15tµpLA©‰Ë?…jNWÐ×@›¾ò¹L¢š ÛlGhj£!pNƒ÷Ä 9vˬ…6Ð6AA@ó½É›ü­t‹Éaæ,µbtî§ÜÙ[õÐ dÔ£ÁCD„ÀZOKž²}â:ÛFC?åsd™VªË7jzê&ÉŸ%ÛêYUé,:„[Äè6.¾Æ3Û¸XÈø,Ù/ó‚e7Ïs!ãK¤Ú¦ÚÂà‰ßLgq‰ÔbF㳂¾ʦÉUS3Mn*KÆ'ÛrºŠÁEØ‘2>AA.Óò ‡)qû\ÍDÚ9‹rª•ÆEÒƒ2ô£´>Í{C¶Ñ šQ¤—ÊrÞôϦ¼^J3Úäá¿쯤÷(ó¹TÈxG9ÆÔl9 æ%háXŒ}Vz½ó½-’0ÍÄH:Y¯ÑýÅb•F¬DQøEÂë!ž$¼+µJ”΃®/-™‘‘@6ÄG'H9’¯;À§@Ú½ ¿:/Ï‘>*,¯¹úql›[ÊbÎÀfª¤ÃºkŠÍŒõÁâ( Q¹mŸ&×$fˆÒ(±Nju|÷‰õµut˜0‘—WÒÛă–«sÓäz0ư¼y†=&(9̘í•0ì¾¾ŠURQ=T9}e1pR+xúF(ž&×nÓ0%9oäë Î€\¦Uvˆ¨§p”ÇÝÚg°à·kæy{'á+ø•UµÙ€)§?—é úÊé?Áþ§<7GV6³yLõPõ¯ë¹UÈxZÊÒY†“§7œ+b´Œœ_ÇyL¹ ÷P•Ê’/yôÁ)qö+•¥m\¬¢§Œ…‹ÿÎ’=LÉ~NØÍ ý¹ŠÍ9LIEõPÕMµÂa%¡fAO„·Ó�e9º@†ckzæ7ÚxZ¹06AqÈn í,»Üß4ó¼9´i«Ã¾Ï 9Tß±^*=’>*œŸ!G){²Ê•s˜L£/ýY²˜Ksv q¯cKìÓdÆ÷?Ÿ»ç±–~ç†÷M¨'§ÒIXûÊ!bî‰++~ØÂ¡$3›œ>ŸäÞ×®úG<d·Ž©ôS‹¥'S˜’DÂ7$ ÁXš ƒP.ú¾Ü킦ŽÁ@ËUÛ@¨(΄,ØÌ;ÜcÒŒ!‚› §Ýƒí§<¸øžÉæ)aäÈxÓÄîBYÄ[N§ëw¯Šƒ}W8†pÀÉs<¼'-Ê©š›iQ¯q£³d‹0¿ËâD»)MÙ+諦{‰ÔªªèÙú[—9Ç…›; Ÿ¥Ýq¨­)—ãË©¯òÜs¼zn˜ºtó±,æ®°e’ü|&Kì¡Ê„õÙÍ1>‚ˆßL"Ï8䜖ožËtS§Ùë75q4MÔðÐàW{G®ò‰ÓJ°ïò<‡IµpA}+ïÏêYþâòØÅz`::¦5Z0@ n)z—XvpM×®p …)@_no‰0>ØAuoo’ìÜ’]»¼»‚Ë·‡¾<É ËýUãçìñߘÇR î€í j¾’*­C’w4IˆŠfÄþ¼™Ã+¥íÉ–Z$y—|‚ÏXÙ![ÕEÂäìÖýµè ¬Ð~ˆ«'¦oH«"&+§ŒÕ5µ^…Œk"¦>KVF<@™ò° †ˆÌÓB³Å:cÁ&t°È(ç Y±ÝTûYÏ’˜t6,uP×EM;ÔSL’ôÙ&¡¦NÄÿ/’n¨¢g˜’°úþ¾Ü"H ”ÙÞθäUÒ;Kö…Œ«ÏgÒ¯?Na{9­~RÃÅ/ðòůÿ›]/Ý<d˶ßÓœ3Tѳ…+[¼ÌWI{péÅ-‡ÓR–L]ºù˜MµÊŠÉfö]Îe:ŸÉrúo_K!—Û7S¦ÈÛÏ ¿ ›y ´^å9¶XVä²™õ‚N“{”ƒ¹~†=N8™–Ù~SË n¾˜‘#4ÅØ—΢uŽ2¼O„þ‰öh'z–]û91LÉöÌ’í•:Áþ&ŽTÑ3CŽØfžo£A'åþ6±¬gzž…»Û°y–Ët ]V&(hæù.jLIUî„™w§Ç�á)V)¥æ÷Q!´,Ð 36÷÷»«²*èâ´‚v›’}i¡ÂXBÒ·0¨®= [�L¸ÚÄWRÛW؇yä•}²Õ|#¦Ý‹Msk†œýœ°G5AAU-ê Î ÑGE0+r’·“Ú†EÆõQ1Na;Ì6üÍ ,F½U5ÿêB™É|9oH›äÚ…]°žLvGd¢·pÌJ£¥ÈBÆÃ ÕÈdîœ1F ¤š(§:¨["µŸ§lÞØçãPÎ,”Ó?B±2³fêè¡84!PÙ¤!­’Þ!"Îm8É”2ŠËˆr±ïUžs×_Âp3‡çÈzgÄ& ’Ÿ$?›ÙºâWSIÌ_dÛ;7òÞÿ^›ød°5åò»<lñpšÜ\了†Ê,ߑλ<l¯ÎFã4¹.⃔näz!ãUôÌ‘µ“ó*ú–Hí¤¶“Zs©ÓìõätQSEO>“G9h•¸‘Ö|.m4L’ï¥i瀞«m\¬'æ5ÍgržÌ!"'7×_a‹�C ˆ·:©-â-9‡gس±fj誢§•ÆrÞô™!´ÈVé×ÏSÓäÃ- Ÿ§"v˜Oå§è¬*z ÷V1_´§LÔ͘D ‡÷K‚«7b¹gY Ygå˜ð1¬d§G°Ìб*R´¤ÌlÅ»%M_¥Ýó‡ûB¼÷4QâåÃY«NjI0ÎÐ4D©²+qÕtïáŒÎRçRåZÐMµ�Àf·uÕÚ òŠVí–c\ ]†WÛÀ#Z;ð}Ì“ÙK¥˜ƒrÔ"ŸŒŽ¦ŒÖÖbDcÔÛ뢦†@ir»}–ÚÊ–Hõû*ãkbÐFJ³µ£´lœÂ(§œKí¥r”"y˜¸j£aŒ*zúyªŒ#4ýlCÚ0%gÙeaM¤S}ŽñÎ’]Äèy dlãâÖ-—ŸþÕs¹¾iÃpûJÊ;Wó˜€<6r}'篳1—éóì|ŽWkè’1‘ÊÒí¿Hyô‘©­.S8@ÙY¹LO“›Íì$ù×Ù(9~†œÓìõr,’>FDÔa ž¥ªÊy3‡ù“:8ûœaJš9v$;9oNv‹õíD•}¢úyê䵨ٌ÷,µG9h§S¥h0n£¡“Ú³ìÊaÆN؇ʽ!˰ët,ɇ弩ÖÔÝ•©X=Ç…ie°àÁÛª´ëê@†Ã!J‡)‰Q¿rîóþc•E¬Pë Ö!|Šeprös—½È'Zöäa¥—q¤ºÝ§5±â|"ñ¸«¯³Ú ƒƒLX é¥Òí­€¢fž?ÊÁ3ì …£í àMèpŒ˜!Ç–0\OL©åÁr¶3XEUD«^š€ª¬Š»õ¨‚Ó±<òvlã¢Ñn‚rU´‹R 2G– Ѻ&aÔ™"Øõt©URèrlÏ,ÇfÏõ¢´‹šLæC¯Þƒ<Ãa¸»9—ËtŒ}AHb*¶@Fo2%æú.GJ`®1éõ›»r˜Q¾1I¾|E+uÅŒláÊ«<—ÅÜNÎoúÕ92à*i›—ø>fÍo,?ºaе°QŠÖñÁü;BñÓœ»ÎÆt·peŒ\ø!ïÜÌÛúàå(±2ÌGgÉV7Kv”X%½ùL–0,#X+d#„H°q·8ªZ¼$ó–0<I^ ]gØ“Éüiöš å`=Þj|Èeä2-µÄ9,ŠH@@7Õ»é4’•1ÐÏSÞ!ZL’ßÏS‚ÿ ‡™ÌwQÓÌóíDG£†Læm»…Z ãûȯ›•Ûfž/a8™¿s¿ƒ°z#–ˆ¦!"ÉÖ!Ü1ÊKð™ÚïÁ®Ë¦[âI.¾²;ªþ^r`)r+öªËÀbÔs¬äÔÖM±yC3-6r(W!Ù/@˜Le �Û¸8L‰µ”Ê\Ð%Àîጯ*ç ; zV'ØoKÉ=¯1Æ,ÿšÉüÎ5i] #ð �­4öSÞÌáIò[i£Þ¶“ý¤„ä‡(§^æÍ–\1Eÿ¹È*Ýnç@ ‡bÔå0GV9ý1¢ðZ8´Ÿg©*a0°t–Úy2o±^zao •7°yfªé–1h*9Bñ"é³d«þx1åð¦ß˜Þÿ‹¬øÅT€_†*ØÀCð\በo~Àºwyxެ—®ÞAQ\aK=S佯3¯/ïz˜w/ÜØá?¹ˆ+yßÈõ"FmJùÅ­(O§œ¡Xs–Žíå´Qê G­K9’Né{å`G.²ÍŒ6¨l6óv;Q §g©uÌ\ÜÖšÛëÏUô¨†±O~`=ZdÉôjzwrÞ»H6£ín:'(háXHÓ5óÚ‰š~/•Ö!J‘.zë˜ðUÐd´÷‹4«4bÝeöá¬ÃviM¦¡¨( NI’ôH•¹'1J»§MuoÒÆ=,íÓ’­UØÐЏ.{uÃMA¹Íž*zœe©£#hµ'(0ê8º‡3*§uòm£Áºœ#Æ¡÷ÐH«2q5勤÷R©ŸV ÃGhÊfV‹#£K ƒP!ãÆ?›\‹Û‰ªpÔ&J»„zŽWÑÓNTäA%½ÁeÃ…Õ-¼ðx œþêÊ0¥P «w‰T‡¨LÈiU\§¶Ð4% {™#«—Ê(§¬û=û§±­.WÑÓFÑ1"Ú]F{†×Œsd R_NåmÒ~siÓ׿Ò6,Q ¿Ÿ‡1ø,ÁGð!/Ý<4Jðâ†ÃJᕳ¿Æ3=T=›Ë`aÍ×–›8²‡3ÙÌ>ýà¹cŽ9O‘—Î{#‹#ÏÅŒ<»Ü>LI¨ žf¯0ªY²ÏRÛB³mŸÛ¸ØA]mz•T,ú•0ìÞ Ð<™m4H^ž @8“UVOæÅR"ûyʆJ]+Rµl8ÕÐužî´jé,aX»5t«²þÕr«ªBëè1,9&œÏ¤òaU‘£ÑGÅYjœì~‚µ#V"µú„WëÏ-@QZÀDiÁdeGê.±éÝ£÷˜ói±-¹sª‹«ö޼s†íQ…“ïö_æi3F” Wò.ªG•—mªàŽq–Zqà™ÌÕ$…n™cX™Ì/QI¯Ô8!ÝT[8:Á~£‹¨;^®€ ´2žÎ¢³¨­4*[•«Ž¹/`"›ÙV ¡÷îKô6¬¡+ŸKCDÈ0Ä.’nŸÏw W4^2fË“ lªirý²¡ÝRÂðÙÌžŒÔSùSžd„â“)õÆvrÞÜ,ÙŠÅ5Ù×Ù¿šÊ—¾÷˜U0–áßÃ<Dà#^¿¹ëÂòa‰ÔøÍÔóì#rš½Î!e1÷ÎrÞ�e—¾÷˜goŒÈí)n˜rC°Hº=žR—HÕí,J h¡9Æ>+užL…]Ô†–qe;cZ_:$g5˜„X1#r­”á�âþü¦ÎTœ`¿ÑHžzué,Šl÷|Zì"¢Ô’u5>¿…cC”†I²(§‚½™·« 3øƒU£ÒÍFZËyÜÌÿwPçæÆ{;¼íýnÖªíc%ËÊã+ÛQqëT e`<‘”†„ìÓ²¨äfX|%8#ùãÒ’èÁ•­²O&“Vm޵1‹{²à žÏ¤ÔÝÖ•Q3’¬ôs•¯¤WlÒ 9Í<_ÆÀ<™Z[)¨Së¬ØA,¯ÒMÑùYRï4�4ÞŒP\Îþ«Šd:þÓn:ƒßü öïçD Çœ$u€Ôˆk¯hžÌffÉ>BS˜uår¨ÖsáúÕÂ1ÊűŸ§®ñe"z5Èð%W’‰š82I¾Á{/§ëèxôÁ)~ƒøgÒù6Ô]Z~ HÛ¼TÌÈNÎ1êË>û`¬›ê´È¹lÝ|™4øE˜‚"(ƒ«¼tãP.Ó[¸ÒBs)ƒêõÍDõÒœ$_¡‰W1#{9Áš ËïÜÌ{˜w×sË–’bEK‘™ÌLjN“ÛLK;l7¶·“˜îwï¢Æë+nÃÓ+©Ý •ÅÜÅ d6lñ–ÀæÜsd¹Ÿ!™P­¦³ÃêÝ(;K­ž�²H¸B«è« ï,µ¦×PúyÊÆg5¢ªÊè¦Ú «R?œ´ ï÷H¤KZH–@âÆïgZ«-b¥qÎ"©TøIJ”´Š‡$ äæIqeEdJ4ºÒ’çˆ? ˜–ÜBKŽR÷t¶VE¸ WDð¶©p”S’ÔÇ)tŒÉõwšÜfžoç@=±y2[i4„„"¡/4C²ôg0\¥û¬éi"Èê£B¬x »é lŒaJœ®¦Ûí¿kJ1#õ?K­sNÔµÑp„&C5³[r“ “¹7^ C0Õâ÷+cà,µÕt›JØôÁê¡ÊЍӕn7ÖgÈÉd~?'fÉŽ0f×J¯´ K™Ìß¾‘Ÿ1EÞ…›;êèØúàåGS¦Þ¹–WÈø:>¸Åú<¦Iz˹<¦øˆ9Ì‚ù €üg(‡ø>|Ÿ7Þ»¼é™¹M)sk¶,?Ì»×Ù¨«oð ¥H¡Ëñy¥ ò¦LS˜öàÁ‚9'6—édýd:‹ÊgÄC(žTÓA¿Š+d\WEó*ñ†))çºäî›Ç‡±Q!“ùIò Zá ÛRùâ®% 0¬+æ3)zÃ'¨nw4®¤ß½œ7ò¹$6Ìé®rÊéo Í­ºöf±�ÞJ£Ø_SÃŽÙh¿ßÊZmK@{ä®b]²êïyÅAü=M¬øJ÷0ËõIÙ0É×8ˆï*®Î(u÷ÃdQNmgP›æÂž·®ªºm�´Õã;ø›/ŸB·C£‘KOAm­4ÖÐå.;‹9í?iµ=v£íPýáºVGG7Õj7œÆ-âr; ý9f,0Ô•¥ P¦fïÙ›íWIó–(Mˆ¨…Õ.Ž. ö± ÞöÉ:¨6¿@ÆÉŸ >ý;ç, >7~O“{éæcódöPur,ÚFðì†Ø¥½³œ÷hd ¤ôëo±¾”A>fðn_Má)xú[äÿ³TÞãÒ?ìÂ_ìxçjÞûËY<y_…™'s#×Ý<UAß ¼ì¼@†F ·n¸¼ækËü=ø*#³H.ÓÊíªèy†×ô"q^[)|*Kjö¼Ê'ØïÌY3-† \œËbî"ÛÔ˰SFXIïvÆÜ(TÐ'!Étܪ£%AÏž = ÇJx‚â Ÿåô›�yÅ•·¸ò¢ÇØWOÌ»Å%¥…ce ñ–®¤•ô:»6B±ËÈ<™QÚ·3ö ß´r�ñ&ú)¾<÷ŠÕ˜c%˜Lwã“¢×]ñ, ï*&½0-±’d•à'sÇ$ü°ïÑÓ³j¬-rÇ¢W3χ¾·¢dÿ,¢[‰¹"_%‚VV‚5@19gØ£NÏ͸VÓ²™m ­™çUL8:cC«–N{ Á‡"ø ›îä0ÓN´ƒº~ž²™a§H}Œªä#ä2Ý@›̆¿Í°ÐWsnW]YåôWÒ%¶›N-‰…;XÅRCaLÕ{7Õ9iþ£wþ¯< ‘gȱbæPsSöÊé?™R/£vë†Ëîšâk6,Pö膩M)skR–ß¹š·fó2XóÈ2ïÃ/À i,ñ![¼œÍl7ÕÙF6üï0Îíï¥ðC6ýì‘´ßXzýÚ®xYûÉ õã`ãNÎS7á}˜f/§ÙHU­4>»!6Mî»<œÎ¢rPã^|ðð£û¦°%á7VÂp@øŒ§òô|&ÍŠD3=-f$t˜,#‡¡½P•=ÈQÛlÆøbFÌðäqX– ›¾ÕQÆØçÔ™œ·œäÓßYÑ„‘Å\G¶3ÖB³‰—ø ½cÔ÷{{œfï˼PȸK„NÜq8º¿»]}¬´•å¸OµÂJ»÷ù+͈IRO„ì­ý%Å ¤§FrL²s³24®RFÍö÷Ö4ÈúË_AŸbq FT,“áA–8Ts¦#4Y·QS£ë  D æ76 ú)Oeé_V1!B¡¹çrü,cÞ ö‡ ”a1ÃT+ã!&(h£Á;6}Aò'GnšÜtO°ÿM®ŒG9˜Ët3-Îý2-6j•ÃL9ý~¢ èAŽ–1ðìKí³d+ Q/À©qí¬ªè©¤w#×O.G7m™{ÿfká?ÃZâ7S_Üp8¹½½œÒO9ø|a/|Ä¥åÇøˆ‡y·šîc¬ƒ_ƒtÖlY~9‹ q§SέٰœÊÒ8…ïÜÌËbî G½ši)Kü€Ÿ¿‘z‹õžÀFZoßL§p–ìEÒ«èQ÷8N!ÿ7TÜI‘±3­4VÑ3ÊãÉÓÜšaªÙ“$)¼XsFZ뉅:°<q!×ý¯‚¾Š›8bRÙŽ­8'çu0ÚuP—lé’ÃÌ5¾œØ„“½bæ­‘´qñëµ´ àÄÞ<™Ú9ª’5™3ˆže×ýì¸Kç|ÿ±z"ÖŠfR’⮕vWž”LrJÊ¢>Qƨ.‘ nÓÿ�ædmÅ]ù´Õ™`%|Ün„…A7¿æO"�T™‡YAá dcCi]ÔtRëzàÜ€‰Q7Õ1¢LØi÷­ú¨há˜u7ã ©uÇ襲˜{$gØ3CNŒhP@$×m$¢êŠÙÌÛöχ(õÈõÍÒÊeTc w]Ô(ð[ˆâ5ø©ù.dÜy \w#?@ÙÉåh&óýìè¤V^â0%“ä Y8Ïνœ¾}%eÓ†¹÷odů¤’JZÕ…PÄ^NSø ¯19ÿî‡Ó\¸¶#•¥øÍÔwy¸ŸòõÜâ?Ã7à·`™Ìóëp÷—³.Üܱ‘ëÏñª2‡~ÊÏRûôæsü¯_ÝÅUø.çÙ¹éÁ]|·è�� �IDAT¹ ×vÈ©§ðŔÓä1*“×%ûõ»^ú‡Œ ÊçÔ|ELUÞú@:»­$O}¹W°‹·,gÙeúå-äì¹A¥Š{`Öñ|yà`=É·½²Ž÷Γ©n>˜‹2™!GwÊÀþŸ!G²¾Åg­–Îýœè¤ÖäÏ=™)s)í»ò™ÜËéû‚^¿€‰»FHï?~þw³Û'~g}R‰ï.Èzüž(Å=òô{iîwXNÄO>õöºëÍãŸ–É­ÆæªçÐÆ¸×(Ê)9Ŷ¾Å¥Ï‘%—Ý_ì`”u£®’F A;é,.’.7½šîZ:µœo¤U&·°s×#×>Ù¦bεD@Wð]”îÂTEÏ~Nœ`oò¸Âåp`’dUN“+SÜNfÆ Y·ÒÕÏS¾Ä ž*zä…K‘7Ïð»ûä@g/§_*Õ]-Z×¶ÐF®§m^bmâ¾[„/Á#p>âkyF¦¸ iܾ–²æ÷—y‘—–½¸áð³7ÛhÛúÈåׯîÚÉù´¯-1 ùheõÎrÞüÛCU„±‡y÷5žIö¸ÚºùòûײttL‹.Ñ ÂUâ7S_å¹(±‹lsª,ÔîÆ)¬¦ÛË]E¾’“LIÀò='æ£þÕ{F¯5ï™î iç€g¦œ~oOl¥’;Mînε­¢'FÔj5ÝcDÔ †Bqð‚<¯²TÙj¸9+éu7æE÷»lኄªðEÜv˜ z[g€•«÷õ?7ÿ»=¡½ P›¼nŽÝ3|w°¹+7Kíʼ!’„lO»WÚ¾±„™äßT„\…™CDŒ¦Y¡›UÂp?åVêZ8v„¦Ýœs9°EÔMµâfWBÆËy£ˆËå¼iá(UЮœ0-§¿†®FZ‡ˆzAJ®žfW-ÚΘsŽU¹UÓÝFC#­Žé èb:GV>“*ZiÜÏ KR»é4\í¦³—Ê!"…ŒPÖ@›_Ü—X†›TE1X'§::vsNúª»›jEùÂÚÍ)Ý­¯çÖÖ”Ëóî(E·¯¥Ü¾šÂ"¬…Ëð_þ€«�/];´‘ëdÀ¯qûZÊšG–y×—wUÑóþÍ;祫e°0EÞÉïEÉäý‹YüñåÔõÜzg"Œù€u{9=Mî"éþ÷ε¼‹l›"/-e‰‡àY¸Éí›)žaͽÊe hãk¯ÈŽP<O¦Æöur˜‰±O MëŸR%ÝaÈ 6B„â­ç¶޲ Sr”ƒ9ÌĨh ðŸÛ¸h«RCêq «è©¥ÓYºbFh 2Ôpª(‹rJwc{T6P5pbÝåIò¯°¥qûaV³ËyS0Šˆ´32Aá*±b¤ÝW«±•$ U¾´Ä4IÚtV–’£QrpJ[IÎLHQÃxV<9tEi"âÝbd’“äê}èjñ ÄËêÃkÒ`ƒº™ÃŽ:©¼ˆr*°v†(uñ7ÜuG±†ÜŸVÀÄNÎ×Ò9@Ù<™ý<%Éc?Oé ÑHë³›c/þëÃÔÊT%¡Åˆ#RÂp/• dÈ@ÒÀÉþŠ+lLXbrhì¾aÌ`ÜÏS»9Wȸ³baJTŒ¡B°\ ý×QËbÎ!*³CÃç<™“ä{rò™Ô`·‹šël|g9oMÊò®¬Ù¼¼fór|9•_†‚_‡¯Ä¯¦òC^L9¼Ž.½õ?äÖݾš¿’º“ó‹¤oæm±ëŽ. ³` yçÙy‘mUô<š2µ‹£醕ͬ‡÷hdêéGÎå1ÅNH…L(åÖ­ãk€M±:@Y?å™Ì7ó¼Qß”k˜’&Žh–¸Ár&ÙcŸLsVßÁOt´ÜûG¦W!ãßæÉ|&eÿ¥L?;ÊÐÚFéi´îáŒ)W=±zŽWÓ½ŸþkÖr…])YtÏQMw3ãê`ÒG…1F2ï=å0ÒÂÜ©«§p;ƒýì°bi³S;ÊйH€ßîW_+/Œ++xÉ»¨+œ®”b'‰,Òü!ŸÐ4îäX gü,;^*ƒöé^ëÕöˆrJWû(§\H K S¢{5þVog0Å::´ê¥Ò±$ˆS’Á‚3˜îš !F²`foQéç ¨#à~Ÿ—Èç’ý0'Àœä |w÷×~®«¡B²>*Ô*”W š½.—Ú\}LŠšl…Ê©­6Ð6KvÆ63†)Y$}ެoòнúBÆËé—ɡɩ¯ >`]3ë¹õ0ïò%6m˜ãA("íÁ%–áéÿÀC_¿ÅúÛË)–w|Àº,æÞÿ^VZÊÒ˼pš½§Ù›Î¢”y2ϰ'´…n/§<½ákyzùc›6ÏÝ^Nqª©ˆ·Æ)#RÄh£\…’¶y‰T¸ =ð¹ÎÆwy8F´“ZûIb;†)™'s’­A‰çI6~Œò¸*•Y²•}ªPÏa&ƒ…€ùðŠ×‹Qo-nœÂu| ÉÂKlhY £‰#6u ÛPñ’-jáX>—i5ˆz´ÞQÚ<Z7–Î*zš9<Mn}Ghšdk‚µ¬Ü *,dü_nçÀYjåOz•åKMP jY!’AËïý5}µE¬»aHIº¾´•ü$î¡ÿ%ú^S¨ ãÎ? `µ ÞÂ!³«Äÿ?> ‹ó·¢€‰zb+?tõ-çNBSÁŸ´pÌ_]d•Wd1WGÇ~Nèôèr¯Ba;cþ9ƒß'€í „d¥žãÙ,+0Ô(ú&ŠÈO^‹ž¼=K­¡H&¡û íÛ5å•ôùß+›6Q• É× žAK\…’ë9²örÚïbHÝšø"ëZ9*ݺ“½·ÝtöS.fI¾†JÂ2®³±šn{HĉßLxŸÛ7RÈà—Ù´anÍ–å'|sм9²Ösëõå]öz;9o0¸Â–º2™§˜y2)$~#•}dŠXóµå5)˙̷s@úiö^gãK7ñ ›a6Ab/¢Ä>éE·dçT“¾õ9Ì¡ÉVÜ�eÚ"WѓɼéQb>|¹¥…C-22þ.{nËPd!œÞ$^Mã�evÑÂAQF”S~yZ„n”10AÁ~N¸Oê£âûÛh˜$ožÌBÆKì§<‡S𺺩 ™ÁB3-ÔµÒè/¾¬¯4˯’‰lMX èýªàêŠXÉÊÀ9’:[ñd`È¥¶3ØNtˆÒÄKÒ&(cUA»QÏq˃C”6s8уIv."2A;&>™)ü„«êq'®Û!wO*UݼAºpëaJŠñ:T«ñë<™ôuPWÂpG;™Á˜-ÕÑá¦XÂz}²3 aÒ çÊÜ«˜;k¥ÒþÜXÒK¥£¯»é´*¨±¤IO€0¡© ²ªõCk•îÄG)j¤5“ùirh+fdˆH1#¢æÈ:ÊAÑAô·2™?Km°VQúáðÐn:gÉî§ü:×<¸üþ¬´ Kñ±T®°&²Ì5X‹PË…+;X‹“^çÙa,E}5³˜¥(›ÙbFÒYÌf6ÂØí‹)™Ì³À:>ˆÿEêûW³Þ¹‘wá{;âË©,¥¥b2â7SÉ…q¨†9y1JB»o—(Ê)rî€cúÒE å¾~Êýs/•Ê1z¨*a¸“Zá~z†MPÃL5Ý!ÿî¥ÒF¦ï³›ÎÚò™TkÞK¥Zù>*"Œiu¦„¯‡ªQí4Õ ËXñàe;ÕÐÕηAŽ(a§ÐíÁš8¢ƒå 928œš÷³Üm(êѼÍS䘗Ü2CÚ}ûÏñ#åSÛû®1€}Û"m;ƒkæùd5ÎP"x :8ûdm¥…C3Ÿ¨ÚÚ'(ZlúÛÎ %r¸Ú‡(ºs$ñD\L8# ÝÑq¬æ=T¼‚c6f²˜³q€Si‡TRå0#ÿ{;ƒu ?bº¬>*lJµ˜Å4«C’à]\´Î*fs{8#AqZ=ÇÝsØ{Ó¸Ö½y>“m4TÒ+#Î}ñƒœž~¹L‹ wœ9ƾQWX$pvžl€™"¸…ï¥Ò¤j;cÁFÄcEÂy2]‚çÉTAWC—ÛyY-+ePk÷odmÚ2wáÊŽ'¶½ ð�ünÂW¡lfo_KÙôÈÜûW³z©ÜÆE[t ´]d[.ÓK¤šó=›{g9oÍæåøµÔž+;U[d°ÎâçÙ)•q'ç·qqS|®:­{‰Ô)ò¶^ºÌ{Üþ‹”y2Ÿ}0vûFÊÖ”ËÀð²Z¸}‰ÑþA yû)·ó§Â³‹Ç„Mƒ,—ÉèYíÌu€Ô ©µùL}Ì/*iñ¤)›Œåq/_Œ¨~i^—EÒ»©6vùYÊá¦å#RÕëçÜý ÕZ#˜~Ê휹©JV¥ cVô\–DìŒWU>ßî#}ut$Ê6Ç:¨‹R2‘Ô€¿ÿø¹¯ ÆW¶.Ó »ÒD¸"ÑLêi¥Ý‘‰—–Ä% CÜu- Ó:Àcp„Ü5tœÔß"Éj½XwòÚ`&+S51ði'jBÅ ý¡p]vrþûh›'sˆÒûd¾UÑs£î»Ý­»‘÷…"ÛÛhØÃ—!é‚ZL9ÂlüÛÃ)é ´e2¯ˆyœÂýœPìWȸÕ«éî¡J§%W+ îôÉw¡8—éLæë9žÉüNΛK©/d¨‚À¶QÖ¤¡Œ£¦£ÄV55¼wÉÎ`¡˜‘jº×<¸œÅÜÖÍ—7¥Ì±Ä®\ºø˜5B6Ã׈ŸKå¿ø€u®îXÏ­ƒõmIzÃ9%[¼œÉü;Ëy³ds)òŒdã1jn÷tʹ­.ç2öàÒ¦¦9RO?ºaŠ„Iüfê¬Û”2÷ÒC/óÂÉåèKˇ¤(%¤¡‡*è%<G–ˆ€Ìb.¤8¦&´î¦3¨ÛÓ7Š2>Êc/óÂ…Œç2-–Â!t7ž+’ÁZBãšFyü¥åCƒN/!Ï©ŠjºÍ¤Õ²VÒûmž4¦:WMwmÂM‚*Ä›J"¥,fÇÛ-'jïYI¯¥7RvÎr˜Iàâî?V‡òÂßíw x‚ÈþI‹«æ=Û ¶îwU‡ˆDi¬ÙÌó1ö…£¡®Š„ê}ðo*=ßüH.]®ÂÂ`<aÜwSY°®"L´pÌ.T5ÝZô:£éâY¯òÜ4¹m4Ôs<J{P~÷P%ʨ€ Ë5¦b.s®Ë–'É·¯nç#4üi-aXu²ú½y2µ2QÊè¦Øç;dêêæÚt–Ú�5W=è°Nuû9¡cán:O³·µzzuS­g‡u0WÞ~žÚÆÅ2ô±uúUKbU×Gh²£3Mî©¯ßØ•Éü¥k½¿œÅZ6m›Ûºí2À-nÿYÊ;ÿ>ï:_ÛÕMõ-ÖPvš½ý”G‰ÉE ì¥›‡º¨Éföõ»vÓ9Fd WN.G 7 ®¢çUž3{àKð$Óä¾#‹nØ¾×Ø<EÞ¯\¥è:ãË©b«Êé/c@BU ÃÛ‹ó”öRÙÌó"©*éµ¶æœê˜û\ÖGy<“y%-*þu²n¥q‘ô2N°ßªïö˜ ;C‘ÐÌIì½HUBëœ&^êæ"¶*x”ƒ²EBÿ*ω«¥8ÊÁª4ö6ðCü;ŸÉ¼¹”J“ÝtJ˜”-éHµ §Ðù¾bpÕ(/Œ=Á(+!êûDìÚ¶IJ÷ h'F¯î¼ÐçHY%á/6wˆR5oAŽXA_Ó›]ùœ¿A ²s,ÿžT2/´ô=BS>S.úši Qjì p£bpÕ\‘ÐìÙØpŸWEõ·Jzõ5·ÆwZh 0HËfÖAf÷Å“ä»Ä¸®…\ÊVŠãDât•{x‡¨mk M-™ Œ¥%àC y{rTÍ!¬q©s3–[)õ™ÆQ¸©,mÚ00“p®°&eYc{ó€õÜRË åGU.ô}T”0|”ƒ;9¯hÐQ³×xæë'‹ËdþÅ-‡/]}Œs8°|áêŽ wPÄ3¼–ÊÒ ög3kS-ŸIýŽý‚Úþêí“c�:Œ¸{0 Ñ?L/ôEÒs™>ÃÏí�ebºÎ°g€²Iò <Ù¶™·3Xp&wŒrúUªHÌd~ŒˆwÚæÐV€U¥T¤îš¹U2® uÕtLjÚCmâˆÄËVµÚJÀ—ñÆ+dÜ-‹‘عc“Þ0áÉÍö7â®ÑÏûŸóª ±'¡½[ÑžP�Þ)ñ)C}&ï•„æbÐxc¸R–Í=¨mRŽSCÇ Ìë]´ÃU[$1'ÜE$Jû�eíD­Æt÷ :ÏTÈx-¹Lkëg5)“yâ‰Wø&PCW=±0ð+äÍ9Vý/ÜÚËprK¾Á°e>Á~åR]VZ8aLó$KUâ ó™t>4~s˜Ö®†^B®³_FÙzŽ·Ñ0ªèo¥q„bs)qìãf°É¼=6»1"”¥³¨,å9^5´�cî½€GxÿF©\ºùØ;Ëyi¯.=úÈÔn˜ZÇ#ûÎæO®–ÂrÔ2 ƒYOlx˜%»=T]aK=¯_ÙeÈ\óøòÖ?¾üÄ#of3ËXóµ;¡±–ÎaJfÉÎfv’üÀÍ2¨¨áLgQV–é—¡WPS'µ 5Á’§^žË´ú:g´cD=™†Ø\¦µ.S1Názn™»±èöHb²™zŽëçb·,—i§�•Ô{تE>õQQKgsÛ¸XÈx#­/ó‚ ‹ ‚A¥„ ¯™çûyÊÚ£•â_G‡WÙzƒÀŽ…JøýÇÏßãs›ó"¿üÕâø­nôá¦_øàÏþ¬h;c³|q”_ cÂ_âz=›ûy+JûÙ8ËÀï÷Ó¿ ¿ï_áw¿Äõ!Já÷-÷Í’¬å…?aç—¸þÇìž%ÿI¶ý ;áw]|gùHë§x’þQ ·3¶‘RØÂ±?æ�~7Ê©µ¼à&>n•Ê.§·´…Ï­åcÏm1ßû‡t¬ãÃð•ïðõ?¤¶™£Ÿã¯gÈy…ßý6±6ÅÏòÓ_çÏ?ÃϾÄl?úüí‡xïO¤³øÇì.b| WÎókkùx‘ÏÈïÿ˜›˜{…ô$ýßáëçÙùëüù‡¬›åKÀžø.¿âsJùîë<]A_:‹¥ þ%'—i?ô .ÄI+fäUžû<?¹ÌÖÛ<°‹Þð•/óö)ªóOÞ&RÅŸ.òùr£Ä®±ø/üÒ?æ_e°PG×Å¥ ¶ÒXGÇ\øcßà[ÿ'ÿ[37IÝÂÛsdR´•K;9ÿ!뮳ñ_ñÛߥô©=Î ƒü*z>dÝÿÈŸ|†Ÿåòî˜ï¡j”¢Yûïeñ£õßú¯7~1õ¯n¦þô& ¬ÿé­9²6ýùÜ…ÿºã,{Ò>ŽÿÏü›M̳öO|Ž¿®æŒÚtâÆ?fíÖ-—óoL^å—þßù)ÞøgüÓïðõïR:GÖùÂC¼·@Æçú“Ô÷nò-.ý×Çþ€ßùÒ®ÿð‹,lg¨ŽŽ¼ßºúîzøcøøþ”¿»–kèÊaæsüõ ?ÀÇéÄß!?‡™¿Ç¿Kci WfùÒ&æZyþ~;•¾Ë¯<Kìg|v†œu|øý þןñÙð•WøG“l½ÍOpá‹\Ÿ#«”Áël|•çÞ!¿“ÚÏó“ßâ_Vsæm¾ÜAÝÓœÛÉùþú¯ø[ÔläÇ5t}žŸÄI;Ç®fÊÜÈõY7I~:‹ðñYöó½EÒÓYÌbî=úߪâT?üßz—Üb¾w€–E¾ðk7rý³üô«|?ƒ…ßäqÌ÷)ep„¿=BñG¬Íã‡ÿ=c9Ì<Ä{•ôùcžù"¿ýU¾–=ùLnáíaJJLå#U©³|ñ~+ëçãñ{¿÷{¯_øþšµëþ*¾°øã÷îU·­´‰[Á³:¬7yè©q„X[“³BðNÓ+ çV& iZ'µÊÒbԫѰdÆ×CÞ–|T÷6·VOŽeU“1ƒÚg¸ÙtB%“ùxÙIÝëݺÊ0û ß,fÄšávÆ‚iˆäà÷aÒÓH«)·ÒöÌ ˜°I^K§pø)˜€2šFÛHAÑÄ‘::Ô³M’ïAöP•ɼJz$º ¹è N)co))œ'³˜‘r¢Äô ²::&Ù:Kv Ãé,îäüE¶-‘šÎâ‘aJ^ÜpØv” õõÜzéæ¡ Ë;^_ÞuÀ¥åÇÒY<ùVý�eôY’õ»«›—L_M÷,ÙYÌů¤^g£üëll íû+èk ÍR[ WØòúò® Ë;I¯¤wšÜ)òn±>-eië†Ëódòé¡J^»í;ˆæÊÁœÈf¶—Ê"FËéׄÌÒˆæ2fÞ’Pi-c ‡™QwÖmšÜ½œ615Ù²‘9L‰©X=ÇëèØMçyvʲ’o»ŸA¡ª™¤5Ië®þ¡™çý« Ñ6¬E«?ì£b;c5tY• ŽùkÑfi3äXeшÒa€³ìrê<ä‘ÎN¬\£¸ßÊúù¯ &xícwù`¢õ ×ûC¢—/©ó÷î ïcŸÃf‡rsB"xg!«'h6ºbÔ¯D4}ªéÉjI³œÇ*`¯o•U.@möHZi¤Tß"Þr]púØÖK+¯òÜÅõ¯¢Ç…‹ˆ… Ý`ÃYÆ€À:iÜ9ÌÆR!ã'ب AsQÏq1¦®’*.ú6OºP†ÚŽ1Ò1)u 3ä8sv…-Í< Mµ;¯j©MH¼A×ydË}]Ô86dÄbe{% æf<øumáŠð$}r—Hµ¢¸H:¿zG|¸ÁBÆ_á›o²C˜PŒ(ÐOy:‹sdg§äøNjké\$½†<ÜC•*Í.jœÝd”ä2íÁ_XÞqûfJUï_ɲ?¤²ÑI¸,æÊpœÎ{&ó–aϳSàHàøe3«QH“äûΕûÝÕh|“WÜ(yp ;àþZ8–É|”S6ŸÜ ”Ó„&=¦6mbåsI.e Ç4'k¡Ùá3UÆ® dÈ—24jÍå}¨ÄÃu]³½((k¥Q ¢7žUß�†Nฟf­†>I9MüÞ¿&É–Ácþ"á*‚@Bgñ‰H}ˆÒ%ÊÍÉ Ü1E†!Rй ôi·àjÜFéA¬Œ¥‘V›XÊЛi1µ ,aF|`˜’ צä {<ùZýºÎ3I¾XB2™ÏgRçr—­&Žœ¥Öö˜M”lf“Åc dÀLæC¨Ó{"ÂØ3¼& ¥È—΢ÖY€Àº&Ž4󼆴§.jÎR;M®Mµ@eUÒmŒTŽá¦»€‰bF2XÈaFm}肘<›ëç©wy8ƒ…½œ¾Âé ¹Loã¢á*F4›Ù×—w)>ì¤VP…i«Ð&© ÜçÉ|vs,›ÙG7OÕÑ!ØðÂm3™·¾gáKù~NL“+ÇV‘HŒh3ÎeK²8ÊAgÈüšŽÓ¶Òx‚ý1öe°Ð±ºä%æ0ÓMunüˆV•z¥z©<Áþºœ [$ýM*k|ƒ–à% ‹ÓÝMçQšÍ;:m#P‚­·¥—RPaWØb"•Å\'µ:|ªÚØÍ9³gHÓ;ÍýJ ÃÝT;#!K,‡h¤5‹¹°˜„Ë›  ÅÿýkU(/Ú.À UÅ`¢`˜–À$ë¤6Ê©!JWÞ+ ƒàä?´'º¾L$Pÿ{ïõ}çû>“ØDeeqüEHpž ÓDJ8–˜Y·]á1îÝ®r胆Óé4ö\oô" kçnˆK‚¬žzN¡ÛéÜÐÃb¶«qã,˜žuGC‰J0½nu´!Í”LB4M”ÄûÇ‹ïǯ¦çì¿7â<òÈa˜ùÎ÷ûåóþ¼ß¯_W­­µuÖÕÉ*rnÛ@Òn5ç¶QFWCGˆMëéÔÎÔ@КÎI7“͘þ/þ‹öÑK8­µOø¶ŠœØ ˇd&‰&n¢]TÉàU»ÚPØ6Ä#"†Eq›²$½§Ö;ÉfCl2HøÙ</òx §4°Æp6Тµ[§œ^‘׃l‡[~Kô¸‰®§SÇPÈ \-d·![úA «èª¤» •éGSŽª§”%‡r1h)dðÙ™íêÒ™ZÃ!ùÒÖÒnôÈ"ß^°c>[x@]‘dÂXN‰¢~2ègw §(sGίŠàùÁy_ÇËl,b@•&À6õ:Ê?%GV¼rè0n„ÆçBƒA ×”Õ+kAýT†&£äˆ.¡KPO«F|2U§ÜÈ·d®ç@-íeô5h§VZ‚­ìËc˜|µP:Y2j‹#Ýn„µ:±ºX’ý-c\¯TÒ­N}Ò$éLuPSÈ`GOe.F"¬­¥]Ú2qÁ zh‰á¬£­ƒ ‡å ¡O$B‡NB Ñ(nE¹7¹é¥\´~K=ݳǚ +-„_uÈ‹5kñ§ž~`[5&¯ÝÖŸ]™¬†)i’2ô æ%ã7³A›!2jò2©Zº°QW}mós Êš­Öê°èX­ÔWÑ%†ž–6“+/HC³À¢2‚˘µKؤ¡V“a¼Ê›XÏ-X}”ùÙ-”</„@Tг‹­ë9 {í…¥˜ib§ƒxˆMb ¯ [FqûØÔv�� �IDATÙ¯v0ÀŽ|†ýì¢ù’°·(n{•2JŽôË­Ô?ÅóŠi–+‚'‚§‚ž(î#3«ThÕcÉœ©›ÊvjåUÁ3JNuã,«§U]Ž<×»©|÷‚ã"óO¼ÿ`)ýÂädª«SDZžÎ0Þ¢êb3IäqJJçJºeŠï&šIâJJÚé}”me—À3u3>B2ŒãXÍáÍìQ/è#TIw&‰ŒÁÇ(9‚ÃxM˜a'ÕÆ(ÒC¤“êVê#¬¿\ts½cŒÜ0^Í–Eº(ù ³L†Å•twR`›â<T°in¡A¬?EÇqTÓi¶,<¦²¤Ó¯+T;ݨ4R(Ë+ ¹dÊ>ñî:4ì Fï+º¼Œ’ÕÎJ­{RB4½©¸¦6£ÿf›uãOíh“­¥º¥¬Š†…©[úŽÝWÉ6ñë7Úd{f:'ÛÐ/íÚo¢I£Ý±IÇs]Jä\{X.jQ•ùò1Ð@K;µÚÝKG\Ä€(²¨Q¸–vùÊ„BêL%D»¨*dPF«" ËSN¦Ú¶µRßÄÎaòeK¸†CV™›ŽÊILt!)§W:á”⦠衢‰Vàòib»t¯fÛ`‡µr告¨•zµŒõ´®â¨‹A­h²É&?‡Ñ.ª<Tl£lØ&EšdF@¯š ­ì2RÒ÷»©ÌåìíKfd* Wè³J 4¡tôœç¾F§ÄGÉQáßašÔÕ>1ó`)ýâUt"OÊ'MAÕ{9ˆïaóVvéÅÃx§IÕ4„_3R׊p?Ï}šãµÐ  Aeã,«¦Óň‡ƒâ:áE ˆÿ2Î2ÉÄ­+]’p•m_äHëäD-ƒºëOS­• ŸÝ/+èÑI¢± &«è%G.'X98Ò˜‹}#ßwÕ'1Ꭰµ‘Ÿ“ZÆt¦<DŒ³šu])ùšÁ`“mÔ5±SO+§W`ÄÍ6ë{\ŸAüä“OÚÙf$h/HX Âú¾œÚ­ P>ɸ:*ül± ¥PžË<Í<Sƒé"䢫4-B>Ãë霛ü ›ƒ°aÁ$•ȧ‰NšÎ•ÌFE»ÚOµþÈ%TÒŠæg·1ÚQÒ«Ú²fû(H)ØÆMTFv&›XÎuÊ`ÜOµ"hå:(Ò—q RF­8Ú5KÕ¤VLÌHMÌ´Q§¾GÕ¨™Fõ.éL…ñA½‚“X§ô+… *”DŸ¨Œ¾N­­úŒTKÎ\K{;µâ§éŸ†¢½¸8Ngöæª Q 7rÚ}lP[¶šÃgÉ5“±bŽ/á´Fs Õ=N±ñrÔ™×FA—ÃCdœeö´åeŒ·Ð ‰¨­&£YgUY×K¿cew:~#êŒd€C<˜Ëٗ٨[E à)¥¯Ì¬3·‡ñàW]OiîÅ0öQ&4KWAC`cir¢í Ñz5½…nKùi©[2M¿ läå! i¶›QiH#ª…R¬Û8ÔÄvÝçÓ²üo>>—ë2ˆ?«Çz­„þ5D†xx ÅC´ÄU‹Æqú¸gˆƒÇ ÉåL¨† ÑÏI•i>î¢ ž.Á»œ‰q‘¤éëq¾O‘¯§óq ‘o×iù¸çUâàAŽ�– ë¹Öîâ[J_æ±9[®|‡è*!êgÉG¤-ç~^:Éý…¼¹’Ë¿‹Sùx—“3ƒN‘Þ@‹›ÓK9w‰y9Œþ‚{Ų[ʹïóŸ¯pË|ôc¾"ÎÇÌsræ'”M‘¾©|¼‹ú1þŸœI'y’û³“ l5}·ñÉ­|š`É.žx‰ÿ°…ïÞέ^Âò³ž¥œÓ²õK²'Țǥó•,ÞË㔓ØiÜgp.&žÃèýœ|‘Çó8ý§üãÇ|á.ý34Ez§þœ04ÎòKJyãY.Nf1‘ óK§H?ÇÒgØz÷4i ¸Iâ®ÜÍØ‰N’1Hῳ…¦â;‰ë?ÒñÊT’¿ÄÑíì<ÀºEL,åÜJN|‘è|4DAÓgX±Êý:÷Á(ûÆ7|™¾—·3øõ‰šWp§Œ|ôénáJÉaòÝD_¤æcæåqÊÍi7ÃIÒîä£EL¬àLNbL>΋?áTâ8Ü ÿßý+žù=Þsû eðÿþïzÁï󄗺ļs,ý1_ÑI«àG•ì»OªèÚÄþïñŸ2˜ü1_YÄÄ,ŒãXËÁQîÉ$±š¾¿à»ÈH~‹Žÿ@÷bâ^°p ÿå4÷ýìÓ)ÌãÔ£9ÀºÇyéküíZ^»‹s¢à?óý#<ªžæ^`ÁIîOg*‹‰™'9ÝN¶Åpžci çùÊ<.1ðçüHç-¯µQwçœé$l{ˆŸq·šÚ<N-g|-pq”{â8þ'Å—˜']àvv1p€uÅ3Kyï þ!>“gغ–×ñD§Î±t=ó¸b“YRn>>§C¥ð_ ·œý§m4·Éˆ¨”bK ¹jã4‚˰6 ÷Ý.’°JWš!Ĥ1¼íäg›63–ülš×œ²Ðîòn‘ǤÊÒVô_ÍДv¯)¿“Ôˆ©%ã†\ •8N±6ãºL¥øöw|û­ò5ð%ˆÏÚb%.Êy]ÛäzZƒlib§‡ƒBVÂxÕ kBeÒ›i†ßH³ØÒB•”&<@Qm}”i€)s&á4~j¤¦AŸŸÝúÔ²Hh¦±—òjrí£L.®W4ÄKgJ“%©”ò8eÜ€—p §‡£B€f¿ÿ6„!F&‰­ìZ<ûè=Gõ 5täqê݇"¥+h¡¡–öÍìYñ‡g œÏÅ Î.c|šTÅti<›IâÅYüì[wSÙLc¯DW𿹉®ç€èprwT{*g“™MìÔ�V8™þ:4À—tA©."V„ñúÙ2JÎ1J¥ä$'PÙP$¦bbdKØCE¯<ˆ¥Ê’_‰9íšï —Rè¦fÊ €ÚAÍ>6”ÓkÑ.öª9Î`RݹJ£,.½„%`p²Eá)@¯›!a ^šB 5Ôå›YY7>Že›4Åd¡J³ÕÅ0UÒì¼i¦z™B%ìê:m„ñ²ªW©Á«šØnù™àcáï·qܱyºÏÍ¢E-¶i DÍvôg,쪉‚— ÷W«†î6ê)ì£LKs‡xÒïÎ8ø—L¤p—˜iZĵ‰è¡ò#Cê"'ÍÁÄP”‘–T{eùéôwÅ+^£?½¸\qÀdo*°­“j•dyÌ‹õ §‰}”Iû,"ÉÙëét1"êü~։®s2LþqŠÅ3Ô<N±“X„UH²óy÷‚ãÌ…Ü#﯒çH¾ê!bdd‹ï‰/N‰ƒ**Œ÷e6žø—)\œ?raUO.gõü &w±U§K„·L"ƒ0$Λ*“X7•A|mÔ©˜©$gE/a/a助*"]M¡_"VÓ)ÎH& 7QÁZÚ%b“·“Ænªè:ÔQrÌе™FÙP4JNˆMÚg`³E–[±L,÷°¹™Æ &eà+ ¯™Æ�Mª(z 12&ÉXÆxG¯kS•Ïðé 93IÙ"òøØ[Ok-í“døÙ}œbÑsšØ.»¯›Ì‹9ļ°�ªdˆMNYèQЮ&E‚·î‰Y¢„ª—Uo îÅ1ÜvØ’…K­b´y½—–5Fgú§¹ÛTŸ\Œè`,ãœÖwPcÎ|-Jbm£.À¶�Û$Ì4Zã$ÈÀBXK¯ûÙ­u§ƒ%š zåíY<£œÞ:Úô‹´&ÈÂQE—ÄÈu´¥2mLoÛZÐ"ØGY] ´H‚£ç‹’®H«ž •Ø"”‰É&«I?¡j:Õ/Š_ …¬cÜ Vˆ‹éº�q©å—!r¼9*õ(ZOÅXé¡ÂÃQÙÅŽ‘í%ÁÇ!^»ƒx£ÉgR³zœeéL=¶àÀâ%q~ _ mÁ´‡H:S¦õÒrÇqf&7S^ÂgÉu}ŠçM9:A–Lu‹9ÙÁd<Nía³š†eŒg’XƸr7´±p°Mœõ£!|íÔÊMÑÜRãꄨK¹®“ê7|¥¢–h?ª`iÑt·�–X UÕìZ†É²E-l%ÝrÓP9ôQÄŒxü1œR˜ù 5Ò¬ línõõ´VÑÕC…“cd7±S,ò°P”š2eì�&5¦‰R€©žé¦U0¬†@7ëÖô¸Ç ½¶ž[Î7,Ôª+—_ñ0<=ÄÃ%x_eµ1´âB¼‚µài[÷“ÖÄmJçqE8ÖKð.ç‚¬Ö ± ž†§KˆŽóqœËùF ù*$ÇY¤jdYò/l¡i9²cÁ`/̱ ÷ÜŠ X;+ÀJÞò³{9.Nޱb ‘lÆrùåùŠ“3+9ÑHóJÞz†­ –üÇ]üÙK|½Š¿ûc".bßç‰'ùÎ\J’öÿÌÝÆ'E Œ’ó î-£o=ûϳd%' :£ð³*þî�ë¢|ÑË?}ê5DrxçnÆQ.«VYQœci]—˜·€ ‡(O'™N²—ò²¾’}‡(ÿ?XCñOyè¯xæ!~z§åY·˜ø.,àÂb¹NÀñ­ä­_pïÙY¼WK»‹“¥¼QÏ߬䭕¼u¹ü2‹÷hYÁ™»øð�ëîàÒ&þÞÃ#ó¸´‹§òÁ,ÜB“‡þ2~¢hÄlÆpa”{nã�·òém|r—îâÃ[¸2ŒûV®|È]—¸ÃÅI×—Nþî»,åüm©Ÿ’Aò½Ô“—îçwpù æzñ—dŸgIÕ¿[uùõ}ŸnxGγäw,bb†Ûõé¢n*WsøEjþÿú×üeC™ç …ð³3¬ø{6~™ÿ±Ÿ žíçnãç?Á ‡(÷Nc:ƒÉ ,xƒ‡›igùJNŒq· $òÁþÏ\~™ÍØøj§×òÚ——æ £ïä|ÌÒHžæ¾uô,à‚‡È‹œÄnáÊI\ºŽY¼WJ¿ú¼aò_âë‡Yý$ßù~}š¼[ùÔC$ƒ_ßÉGoò¥FÂø¼Ì‹‰g1ñ6÷îgÃ9––Ò+Ÿ&øomÔý”‡øöG¤ÍãÒ“|çó>ä®Xø§üã)b ”7~‡__`A%ûNâJc:‹‰,&$¶»—·ÿ˜H“ߣú‰|ĺRéL¥3õ#¾êäÌ<lyœ&#”/çkˆ qðæràX)¿uÿ®Ðá¥Ì&Ÿn²�ÿ(WƒÉc6m¦…¶˜G4³:F©`hVÔuuˆÂÏUN¼žà't-v• ‘þ >‹.Øo}{Ó6×FQPBÔl?ÅC“äV~H*´E°˜d]‚¸‹‘)Ò5Ì©§U%ñ#´³ž"]ÍŠ!¾ C’Ã… õ¦†|(ÅlÌ MZ%khÌ!Ö¬áÌ{²Ùc2CZÆx·a‹ùÙ-ËAëcöw€@ýÁ …2¢Õ‘+/Jì;)Éô‹½”7YÔ>9ûÅq(Dr{Þ±°"%&Ók—Ĺ2žè§´ñÍæC¬¹ýž€åN~³rá[—ßO¹ý‘™Å¿Š“ ÷ý³+‹ßb33¹Nb"+RÎ&gRÓR¦Ì¬ÒÙ‚ž:ÚÊé]Íá! Š9žÁd§6°Oâ0ñn*ÕôˆÕ­îРYšJßf>ˆwfö~”UúD?8ï85]Z}U>Ãê ×ÓYB´†KˆJ! ¯°Ò^ʧHW²°^YX£<Ô5ÌÔŒQ+#i×\±†3­.ªD‰ŒáT*Š2Ž…Q‰aè%¬S0´•]Bgu;鄘fˆGR™Vwî"8Bô£Ôe xn>nÀ© } gÌýôÛ,nÖ¥Ià¿Ý]É.¥R-¹..Ä ËÑCºàd6cË£ßtc‹¤Ÿ¥ß*½îÕæêµK³ç�i²¯“_O«b#4h¯i’”LB€i6eOêZ­Î‚ú(k£.›1¡÷âÇ(U^‘Ö zZ]ŒŒàÒLFk­,Â4Ql¤¹ˆ €Xµ†CZþT0°Büœœ]O§ø X±ªZ÷±¡ˆ™<¹‰ã•ƒl"¬52R™ù Ô‘~VsÑ*<”Ý¢;1³Û©-æ¸2%wUVlÆ”yˆå&ÕEÕ!Ö¤Oó1üpû#3—ßOù w2Ä+§Öñ1iK¦æÈ̪)gû(»›wÞqœ%÷Ù™í}”y of—p£Í4–Ñw–\åR¨lx±Zé«"ê#¤fKª,}-¿¥^ÊGÉYO§rË”á¢{@ÆÔˆÉ`›,uQ4QTfñ�EM쬧UŽ$:Œ*ºd>ÙE•‹¹,JÝ%©.ªšiÔð°–vmqVsXªj†E\f3&™[VµkÑ3¢ÖIum5t¨&ías]šõi�¨"* ۜР[ †öÐ×Ü||~×ë±þþÉ"{¥R¤x@Óô”\í´ì| £¦Rœà²eIµÒôK lÔ~m¬ËÌ}mÕ.yÉÂ.až“Õëû|Õ� íf.ýJ9½âM´R ÷~ªõ‰Ÿ´Õ•�Y¯î!"í”Ú  «%r=¢W˜$ÆNª#xœÄTh‰×?Õ`é%ÐQê¤ZÊ!íúeL® e´eF¹eÿ¤j›ÊèSŒV]:~Á`Çpñˆ@}:6µq»Øº•]’:uS)Ù– ƒŽß|dR/áy\œ…gÙ�àmxn‡/ÀÛ�É7SÓÜÓ—£) 2SœÁd)ý·§Ì™Y¥E¹€¡;ùM?¥ÊotKgJÒ(É’z)—Ɉd"¿ÕÓ*ÀoŠt}LI£ Ôšî!2Mªè‚ò’7Íq}rŠ2'_Àü4©T¦[h¨¢Km¨Pµ°º”^ÂҜɕߴYù ?¶ðÀ7ßÚÓ°tÉÆÈV­2ï«;PZ±\Κ†I—U7j=­º"z5uiò4gK¨½‹ykÓ;biÝl ×ÍÇçòqë·z·c#D¸!ÍRw¦Y’áR=cE¯oئVI_¦ØØ;'•7$6?!Û1+«‹²íÒì¾sõv¼Úej„RN¯—°ðs âd©gÔ²òÖÓFA>Ò1a­ØzªUBw4”¡jÿ0ù¶)Ä]&âÍ+×£…ÅÛ\@m\-ª7r÷‘ñn9½NÎÊkµ–v5@&²œ^Ý:È�Ûü„öS]Ok€mFü`›jŒì¦Tne?/Û\¹EX›Ï°ŽME·Š®­ì¼¯Å1›±t¦”©*¥ê®E6ƒI5ˆ^Â+òβâ¿w½XNÚ‚ir¹ýK3a¼-<ÐGÙ;ÜýÊÌ:‘3]x4-eú7Ü d11@‘ÊgÉ-dp’ /añPò–ë|]jò:©¤°‹*Ñý}ì}œ Õ¢šÎ:ÚÚÁ£Ó""b#ÍÃä› /aýÝ‘­Ÿ®¼ç­ù\T%ÐÓt4Әè“X5!|ÃäkBXC‡ººaò¿ùþìÎRM‡:l½ Æƒ?êLVУp2]hÙHæ3¬lÏaò%èVo¤°Jµz™$Bl2Á7Rè½”¥"{—¤øCl (À6o2/nØkäÉùòJ·3ËÕ\_Ç&¿ÎðÚ5ÔÎñ+½¶-0Ølgf‚ý]®ËÙú_uZÒ½Ïá=”ÚÖMFÿo:*ƒHi‹­®ÈìUå; ìG½…ºœ™"NNÒŠ&°D8–vÐr¸PÓö¿™ÆN?!!Žr"ÐZð’1\ÐÝxUØ?ŒÙS28H¡Z4í£Uù°™b<ÃÀÚúèûÖRE£r²ÇG-¢ù s1¢ýþËlô³Ûà[ ías>âÏ"/†ó›KB|̉÷\ùä[l—áç° Þ…{á—pç,RG! >æÝ÷‹Sâ'f ã•ë‡©Š®GSŽþ`Æ'ŸŽSäM’!‹5L©LwS©ÞÔ nò¼P]Õ0„ÏKX>LÆ:D?Ía´€·"¬’q‰LŒd/)çu½^šji—5¾ ‰Îj!ƒ:{úE QÕuéBØ¿^O§i¦JóÍ9Õ꺼zJs*6Oß×'§±Ž¶C¬y™R† £Õ¢Û8Ÿá &="õe62‹ˆïÖDÇÿøo.÷7`e_ “­ïÁrDNã*ËœýT[ج6k?ÕvI„E0U¶Ã” ¸ê‡¤òGì‘"Fªd‹ùÚX2[n‡þ9Þò+@H© âµ·Q§åFüæFšsACŒáŠd–ѧ%~’ Á<L:‰EðøØ+HI>ëåôjÿ«wT0’\ÛiT4‰ª`„U"£+p²†Tè›2fÅb6«DUÒ]F_€’FÅq´S+tDût‰Éd,+'ÖþrzKˆêÔs›Ñ¶]ÞÒœšQg]²úU| ÊTä¿«î*†s›7³ÇMt”œ0^-µÏžßþìûÛó¾ü_RðA \ðü ÁÏ  î†>ˆA:| ™Ìç"_@ƒµq–©$d3¶Œñ3:‰Åp†ñ>zÏÑ &kißÈËã,«£mšTirµÊwQÕG™¬ ׿8ÅÒ2(±­ŸÝÆT)•éý¬SU_ jv5H”ºxjIu¹5Í$! x>Ã"ïè&‘vb—ºy,~|„µ½”2˜Ãh¯kÂ) –n<•·"$‰k¤¹—r‘;�•+:Ô#N‘Æ[CG:ÓJïÌfL¦—u´I ¡“ÃÙÄöì–A³Ž*Ä&­*7q¬–ya`Æ´Â*³íÑgº¨~HÓí¨Ý´*Üz:m!i¶¡¢éÏ’V‚‰[ï"ÀÜd\N¯:*?»õâv'\=óÚä‘9×`é<(eQSSIsBøý„ äÓN­â|ìU;åg· ‰è¡¢‘æL¢fh5Ô  àWÅ&©Ùò³ÛAÜOhŒìc¸û(òïg·¢”%XNo-~v«‹:†[*]¡Jeôé>ÑCfzÛI‰¥~ËdWØ!5±Vp=A…œ|?¬Rq_ÕtöR. ³ÙÑ2éPàB5Àl¦Q¢WÍN5ÅÚÃæn*‹9.‹‡ˆ’ŽÛï™áv˜ÀI8 cð�Üÿ,>˜Ç™÷sY¤-™)4eRZ¥ù\Tu,dðq^üæÛÁI2FÉÙÃæeŒ+NÓàäïî%l|cÕ^˜>Õ¸/Êb€"«÷P¡‰¨|ßë:ÊçBG%6ƒ¸¹+rm¥^sæbŽ÷RÞK¹“X#ÍÚ$5Ó(ë/eR«ª¡CÌOU/}@Eµ …*æ¸h¢ù ËîD”kÕ;‰É¸˜ã™:‰éÞÈ$QIw¼u ·ÒåkÜAË>öf’á—HQûâsóqCU,‰TiŒ Šb=!`›¥)N9Ð*HüÙ~Ñ69¼ú}+’ëªiél³cW¶¾Þ”½´9oÄ’4£Q‘ëd¤TBÿ~Ö©\i¸o°C}d‹¸!üÒZj™“øT,²*Ì9XUE—,3‚øLRÌ0ù4CZ=­‚Еk•I"ÆJõ>ö äÈfLÊS{Õoà ‰Žu×é u?1`ÉØ/1“DŸÍLõ´*Zp€¢c¸lhÔL£èŽÙŒ‰˜`[¯“˜¿FÉ© '‡ÑI2”Ï+Rœöò•tû]d¾šƒ(î¤ø?¿}á ÿ~fà¿Ã(ü.@:|úm†á×Ê|.^ަ\>žrù| ;ùfJ¨‚E“˜Õó¹˜ËYUÓy¼Z èÄhW–t=­ßL ©cè¥|ÂFš«èª¡ÃMTÑYcd{8XFß2ÆáVE7ô¼~ÃÉ,£ÏI¬A¡kÕ{A·iDt! x½žÖA h ák£®žÖÎrzå×ÞG™‡ƒš[f3ÖN­ÂSÜHó$2Ó'Rë£|Î^Êe8¢-Q6cåôÊ=Ù„ª�šR™ HET•[péŠÙ({x±Fe³"2ˆÏOHù5cd[ÎÝÑ›+þV±¸>ê7ÙAX†7ÑK¹v÷–ÏúìtÎX](¹Jß×vLMÕ1JMŸdš9[µ3ÙÆ“ÉT£YßBH[³•4VsòvL³×ò�;Ô¾ˆ× ÉbM÷ÜÄN­Z>iâ“™ˆ’ŒŸFC%ôg3ÖAöË“d4ÐRO«hzŽEÇJÊ´Bìs9´Ðϰº%!ÍŒ¹Fp “¯¡¡~hú§kºŸj?»Õ'™ÃÖb§ ˆ,ã§u;µ ´ôQ&ë#!ÍÓb¬4ÌŽaòWsXI`9ŒŠ×'ÔD8J ™ÁÓL£“˜›(—«xêU\ƒ8 Ãyø,‚_ÁÏáçÐÅ™S¹Šd¼}ÉÌíÌʼn™K90Eú·Sv´S«¢5A–Aò¤÷’ûŸƒøEæWÒ ™YUAB?»;©öpPîM+RΪý ²Eù&>öê\¿’ ¾.ª|„¨¦*ŒW§KU\ Ío5”¦XªfÏÙƒŠ…‘Ïð(9Lz Ëp€"/á\»Ø*v˜ù WÐsœb àtãÉv]“FµkŠ’‘€ÌKXWª‚žZÚÇY&Ä+Ÿá¼¬«ŸÁ¤R7Õbª·.£¯’î^Ê+é6m™6^!üBnR0nÈŠu•4¡nZE"ˆïZÅÕ’fÚ,3'Ô-RN¯~ª½›*ŠB­®#\(¿aýºÁò®�� �IDAT\cóSý§žÀ¶X'¹ÊrLν¢5;°ÕF¡‹*-ý‚ ¤kѬÆEXQÀPaqÍd†ñØ¡4,QÂ0ļPJ©‰®ž¦+a­ßt¦¤i<¸žJ±jb'$µØÖL£4æÊ;gÖÍk›ÖYHŒ‚lѧ°mqBÔ´R¯®H6?2$ì FÛö$ÊáTv{!ƒŠŸ7-ÝYrE®“áì$4ïcC:S¶UÑÅí!2IF§²˜ ÖÅ7ÿäÝ×É7SϼžËYNœ·á˜oBü g.äN“šI"•éËçS’¯§¾ûgŽ)Òßq¤3udf•q9ŒFð¨„P·ŒñA »©Tb¯ôÔzæ>6tQdKÔ"•ä3üƒŸ¨Nbëé ¨–öZ”ˆ(÷)‘MBønÅp*ö³–vIUÄ@:SíÓ‹ïa³þådØAÍ(91œëéÌa4†SäýýŽ’ãbd+»D ”Ÿd‚LT–Ö^ûÔpëGz‹:Ú´w©£M(]ƒÆpª?K¹‡ÍÏš&´NbJòl¡¡œÞq–éŸâÆqøúØk­'7iîŸïÇõ.MË_;ý*«á¹q^Èåkóxj ‘!òòÕúÇqÊÃIA$MÜ¡žö±wˆ®qœðô8N ïY¯õqœEúO¾M6ÎwlÞN˜ŸêW”ibL–ó `§qr:†ÛŠ2ù†rI i²HæÞE|žËåk!6³è ^_Ñ<<KX÷¥q…¼™Ã¨Â> Ngj—¶²ë Î" úVŸäþRú_f €áWy¬‰Û~ÄWß ô‡¬O°Èâ½þE<‘Å{¯²zW\Œdñ^ïÝÉGXÐKù;äÜ•gØêç¥ ²rùÚm|2AÖÙÛÙYÊ/ñõåLfµÒjÖ±|˜ò›Ø©l‘·Xé埜Ģ|ñK°nŠß©¥ýW,#û,¹q ÓGxôN>j£®€¡ &Oârr&SêþW§ûnHy¥çÓŠGx½ˆ[¸ââäŸðêqJ–pþwhéü÷ ¬ä'Ë™˜Ï‡—¸cŒ %ȼ@j“ß"x‚•Ÿü·Ûþaèϰ.…O1ññ§óp!õÓ ï9R'.0�çà4ï|zw*Ó÷òöÝ_úå«ïþÉnu¦œ™ù4eˆ/ý>?ŸÌ$鋸Õ?ó啜¸“~D:É—øú6[øî%æäþø™›(Ü2Îò¿æ/ÿžOòC”™ÿq†'qåqêV®ä0zž%'qyèOgj¿úÿé6>Ébâk½q™;rM¹”s°ð^Þ~ˆŸ†ñ–ñ“Lã,wûÿ5y™;ªèJ’ö îí¥<‹÷þ”¼Ó/ð,ÞSºˆÉ?ä_ŽS¢ò³‹ÿ«™ÆýlÐÆh=ÖP\E×|Ç!ƒ¨/óÏr×üLNNS¤/g|)ç rû;΢ýTßʧrçÚÄÞïò—¹ã¶>ÄÏ>"íÏùщ¾CÎ<| ÷3üõÖ‰D£o‚¬t¦ò~–€“3YL|¿-!úC/`í®÷ÈÒº1'—ˆÏñãßHÑÙ¬ÅMÖh(jï©­¶)ip& ¾2ŽMýfGc‹%ˆ #Ö7Í×vh”͘F‚ÆDCm™žiÒƒùØë»Æ‚eÎuý%DmRkâ8d†]C‡Œ”ý*H«Œ„·ÀqŠdvQ¥U[L:RwåbDÑõåô†ð7±=›1Ý'.Fªè*b@¢q14ù)!*5˜Œv²×J}‚L½T9½Í4–U¬ÜQ¹uP£˜Zmü5Ϭ¢Kp5dFò5@‘F|ŠE"A¦š¹Fš½„žéï¥<Œ7Š{Šô™šD–¸ÕCd+»‚li£NM'ÐJ}G£éL‰Ÿ SÙÍÅâ>Nñ)ò^™YÇqùí”wgÜÁ»3Ž•yo­¸çìâñ3oæ+¾udfÕ|.Ê*^ÄúeŒ{ O’1IF5 2•Õ¢¦Á g2Ë^Dî!"ý—Ñ×GY£‚|¤v’„Kw‚ÎñòW¸‰øœa¼ƒª·[ÍáB»¨š"]¾øƒ2(Ÿ$ã×UE×.'1?»•P,ج‘fE>Læ0ÚÄöZÚ»¨ h3{ŒøO±Â2ѹí¢ÊèÞ‚lÑ…6cû49W¾œ^Ãx+èi¦QS_ÓsKÆ(¥ZKV“–ÅW2„ßÅȵÒ›‡yá±ÉGP9#vèzë?C+·'†˜tã$ãdK5ÜÈtŒR+ðÞ b«aØQN¯}Vå³€®~;p5‚ëZFÆœ»#ÍÙAÆØ»ÙKšâ*èÑŸz/å‚1´âK‘*<à Išä˜ñËÙ2àWU(§W~?â8ôPa­\iX)!Zy]ŒÔѦUIßÔòª$ª:ô´FìK‚ËéK¢†EËÿBùZœÄ²SΖ¬»uÀr[7y%a¼*:Î>ÊœÄäó«A™P·28o!$FæO¼Æ«�ÑÁÉi™²¯Lyëö%3‹óâœå"ó“§Rð¶ïò…”(îÕfÀ|.–Ñ'BüDTlT«$`òé¢*S jѸ(渹šy jÊå¬JZ]:žZäi¨+Ч’‚Mj<y)e09FöEæ‹fÙE•|ñÄD(×}2H¡ÌìEŽPM•ì!‚g¼„ ’Y†\£4ó¬ G–"šjÂb“f‰.FhÑì7ÂZÍE?¡}l0 ‚n6=M)"wŒàRæ™Aª„´É ÐݲžA¶ØûnâX7ZŲ|•6Ùj@2„ßò§˜Í±å}¤Θ ÕQ¥Ù=œL“$ðã:ÐËV·’2*¼Ö ,i{ZÒ„f£´œ^;Ùý³ââ¹e‰„¢&I¬_¡ÜÚœJŸ$Å®l‡Ô~…Ødt¸XÒ…*ºä‚ZC‡èµ´hª ÇG°ˆ)d<!ߨÝ1PB¿`ÅY‰¨k¤oÊ™B(…(j}”I€å#¨ãIgÊKX~ “d2èá Àc£ f¶ƒx5º[”K":œŠ¢Ð~}³’n'±ZÄÑpK)ýYŸ›hC‚y$xÒ×" ôRþhÊQó^íÔÊü¢˜ãš^äñË3)Ïžß~æT®*“öû 2s½Èü3çsY<¬Ly+•i5OÆÛÐ纩l %@“ƒ¸’6c8‹ãm§V§Q×Qd„—ÙØAb¢tÌó¹ØE•¸ïeô•u•ýU]9Œz8ØC…€¨ZÂxS¬j!ß#•ÁcÚŒú:ˆWÒ-:Œ y3IÄqh д†CÚ§ØOH˜b1Çu³™Í“—pŒ•E L’QK{7•.FÖÓip©2ú‚øN‘WN¯6"­Ôg’RÂÅÈ>6TÑÕJý>6ÈDéYC<b“ŸÝâÊ:ˆkE â“›«œÙòÞ|ÜË*?i6V^Ô.Ú•b×&nHšS ›ƒû,/£„¨¶f¦7×[ˆmwÒj+å­iK»ÎÃP•IT{[וfÜšK«EZ<#2ý“?¬|Kµ­§sŒl™bˆ\SC‡f/vh¯} · Á�;¤ã1\dY.í§Z3^ k|4@‘‹GÕC‹0½ŸêúM0®<â„äk‘ÕðP³Á"d*_G›6ÔZ#¬UÃa1œjÅNô±·œÞZÚÅ«6s*9zL’ÑMeUªs":‰y8˜Ç)ñ(î=l oMÕ4“ÄÍ4¾2³N±–rq%G-Zy¹ŸÒ^ʳ˜à Äq¤-œÂxs9Ç¡7UC–œIm¡Aí”"u<Ç©¥îJ˜‰ ãÝÏ:Z‰Éz¨ˆãPk;L¾˜F.ÝJý$ÇpwS)û«.ªÚ©â½—‡HÏ㼨¢¢c0‚¬tÕ*èÑ(O eé¥4t­¥]ÜôýTËÈÊG°‘æ*dBh"@dRèä„>Q¯Dîû©V]”!½Œ¾€ÆÈ6ET»¢SäÉ yû´URzV¯é,•tSOk!ƒz/{ƒøÌ–÷æãsúHù­S&[t}ÐÊî?v /ja]Æi)íØU «´„þr¶÷=Fé18FÒ\KfýÿÝ%ôfsŠ]VjIZ‰õ|½KÛ{g_ÿjeÞΔÌcV•2cÃ9vSÚS1û•­ ¿ðzZ=|T©T¨sµËãÔix2À^%7ŠÜAMÛ×ϦƸ}ìÁ%œÉÅHùÐ+×ö|†eä AØ«eBw½‘ªšŒvTÉ̘K”EU S5õ„aò4éÕú(‹°v’u­–_”0Œ.ëÓÕÑ&‘²zÁýTà’Ð~ª{)áÜÅÖ‹ÌãHgj?Õ!|Ò¥©wÑìbë6WÒ=MªÌœ•UÑ%Þ¼,”ÏLÃÙFÝYrâS¤¿òþ:鎕l)Q¶—°¬ž$žÅJÊœ`Û%~·ŸÒÔÔÊ3I­‰º.v]E 8‰ÉJjŠô�Û†x¤Ú&§È3eL}s-í .Q2d%œÖÅ ã¢)`ÙO1 þòkä¾(oÀÕÎãT¯Ž¤Œ>]ÍI2TÂ…s| §‡xD}³Ò®åG,ë&Y@éÐ8Z-µ¾–s˜~WwŽüÇÈ%§œÞ�;‚ø$1D§»Ky˜!|Ín¥¢G]]Ün>>ë}Ÿ|òIÛxmÖmÝ™"aʆ¹öÉÏÄØ§] ,]0™W0Fï¿u!¶•ŸY‡rëÉiÿ à*yíÌ) Ƭ ¤10@£<ßt)™Ý1Ìš  ÒFX¢™ëh §”t­ ò,ÐÖÛ싵Ü{8ª™¡‡H7•Æ30À¶ [ÌR«1‘q^7¯`žiÌu‚l ]®B%D²êyž2~íÚë]¼„…Ý.¶®áÖGµÆzNO–-žq¨Ó’ÇQG›¬e¦>JŽ2«%#DCSÑ š Köó:?Z4ÝD•†u'¿yž§ä¤®a-¦j>t¶±2¨T}íôfVf| õ=_îJú8&ô9†S†÷: cK(‹Hƒý¥TMó–W¡*«Ê›ñÑ‹ËóPú»U¼.Šüòeóh^Y5¦–vcíhöI1V* ˸°×Ó*.‰ö²4Tf\íUŒ Gã:ƒ¹Åër+îK;-ýHª˜¹·£ý|?þM_Ac`A˜lÃ7Qû®š\ˆª'.™EÇHÚ¸…×Ìñ®%ÎÂf’àX¶׬¿6ÎálëfYèšWû¬ùÊÜÝ:ÉS¿‰í¶é¬ºÑÈN¥6ÛÙ4í‘áî FNêɤ€ð®Ió¢>Ê”®Â_O«v¾ù [ù2Û5º©¦ÓnqÛÄN{¹Rñ“Ǽ$Vù Ë]"ÂÚBw±µ–ö&v2(´ßIl?ÕT×ÒnBåq.$_®z]T•ÑWÄÀVvícƒú€áIeô È‘o‚Ì™š4ÒœÊt€&¹X Q[ÆøéÅ?K®ú0¬tGÍ{)÷ñpp+»¦I•AÆ$š"æ0:βwg‡YÝO©¼¥úÊ$ ILÖÓ:I†€%U&õ—B°ÌeMgJâYyô õñÁA„Æ|†Ó™Ò–Âp^²˜P}ÒëÇp>ÅózM™bˆ„¢s¢ZRFßéeôùÙ-3uóÐð0‚§›J'1''ôšªúuÁ¥²þSV—ÓNmv P¤MI;[hÐX«´R_G›’æ ¨õpT·¥ÔWÆXí¯î.@¬’©\1+®÷_gÓsóq#àX–Î×o盂ÑÄv]âû » ±)À¶�;l)$ÃÄg/'&˲,¼a¸×zÚ¦‰ÜaœäsaÈ z‚ ež;—ݯ¿|š¯ŠÎ§Q›„º¶)ÉBI.]Ti96D»aò;¨ñ³[N-F* €ˆòA‹&`‡æNÚ¹cQdÊ–þ/6¼±¾#;—³bº÷PÑK¹Ò1R™¢ Ž¶1²µÍw:Š[ãJ†dž"O=Z¤t„šÿhÒ%£ñ�M~vçqª†™ P4Ez-í!|5tDq+]°‚¡2ú;-á´†rÃäËH oá(<:u£äˆ ·šÃân¢ƒz8 i˜üI2´d{ »‰**Œ÷q^LgJ'<È¡G]Tmäe%qÈ?I„Ì!±ò_ªéT¯y · æÅ«°¤‹®ß*æ¸Nškîb-ª_n×A¢#û(ÓfEÄ<1ËèS‘ÉSçYdwYmi#’Á¤h#•t7ТL]¹‚*(’H@§®ˆ¹"g*Œ´‚îu#uPSB¿,•þ%¯:åžHb¬±d+õÆ_CàV¿ 6¸F½sóqƒT,û|Éòª˜uK*¡_ …lEm“@>Ó?¥ùÙmš3mm$Û² [Òr…w[¡$IãïnùÈÍj˜÷µk¹d®aµ€i×ÒçèHYY[ÒÅH€m"¾k §Ò®¹v�òÞÆ–BTFŸ‹a•™c¸ÇÈ–R ‹Jª¯å´­ÿÔ~™ I-%i�¨k`[-µ´ïa³*JˆM’^ láÔ3º`%=®§S^MS¤ïbk&‰t¦rÕÛ5Òd‹xöÙŒe’Ðâ¥Ù"£ µhôÈZBK° ³�•>­ÅËWA’´Y¡Ì*ÉÊùU0‚ËMÔ°üì–GÆ%~·–v-ß/òx§æsqœe!6’SFŸåuÂuœš»N¥~(ŸaGERØC…¼nÕkj86IƈÔà žÇ)ñ…<IuœbyÅqhÿ·•]jÑԈ˜P;7Ñ\²Òh×CÅöéZd0Ç1JŽ\—€ýT«ÀÈ�·Ž6ù)Ò£¸UûÝñjœe2®¬¢+ƒÉ^Wë &ŠÛOHƒÇc¸u“d( KÒ5…"Êg3VAÏéNb§È“¯¿á^š‰‚<÷³NÜZÖnÆŽÜ@Kë…‹“^ïbÄRò–^š¥EÐÇ^{>ˆÊ™+úØ{ŒR3ò4ãDͦl\«#Ç�;¬â”¦î>Ä&º+ Êâü$mÄw®5!œk#A “Ô^Rý–þÚUcr¯‹(¦vj5Îí¡BAéڛ狼 ¸H1­;¢× ¨ƒšLûØPN¯EŒ’ã!ÒFlîŠÐ܈â)N’/{û(Û‹‹(°DB"™©ûØëco=ÊIÙNm;µ•t2¨å»Z¹ë®§Sîvf:š s3{dÃ*e®¬ënZÅ@¬î>ʺ©&ßKX(W5E ¨E«¡C9O 2Õl‰«=DA;dN“ú<OM‘>JÎ$NbØ·†C“dœç¾aòÕMVÒ­›?Af:SM’aX…ÚhžYAÏ·ÇÏn1ÝCl’ ·•z­Ú*ùʧ%Gê`Í]WsXŽ\¢Þ‰XÁ#{bRªÊ1œÝTÖÓ:Mª\üki¼”͘‡ƒ¢EÈ ¾˜ãâëéË\%Mv‚²¦>Ÿá(n1 5ðLÙHs §X‹Âº2˜ âÓ|ÕÇ^ßdj§"Ý•X£’F½“+ü$mÔe•‡H€mÚr•ѧ Seê’á–Ûf®}óq#ôXi6ªÚ’¨Z\·8B²ˆK¾š´è‚îkmÚÕ†{)ob§Èñ’^i¨h?ªg²0°¤%ô?x#U¶5W)@Ÿem̱ǬY°,0Œ3ˆ® N•ø”¡Ÿ#“Ù!¤Z;_™þà’‰€¿Âib8iÎfÌ0¢m¸ÞNÔðaòœ-àuMÒ„çë ê!ôI¨ò•Ó+û ?»çsq€"7Q9‹of†]Š¥ÈgXšÙ›¦I­£ÍOÈðrUnE€ÆH·ƒš! ò÷A†êoÔÃõR®vS¯2éxž§Âx¥*dP³JlZŒyBmÿEÐ)-æ¸æi.F´”g’Pþo QÜ€<me*¡)b-•t»‰… >šrxøýþ &Õ©8ˆÙ"× m#ôNbý”ªT'ÈÔž#AæYró0™Á¤Ò³4—H&"Æ�Eó¢�?uQŠÖ²’nqpdZØJýöIê4Ez5 ´h´è ^À[ù ‡ñêN¢2Íou>Õ«I9×F"WLŒE¬—0f=úuµhÚÐè¥T¶)¼}ÓÌŠg#¬ÂÚG™öÓºtEZ©ÿ,Wöæãó^±’fÎfKI³µMW[)L­šÑo’/ì) ñB@—ýÙ]3ì}º-R+i"Œåñj·À0ý™Íì"°¹z5Ót¥Fp)ÈŽYÝÕÝF9½28fVW*Uœœ³uù(j¤YYæâw‰$­åL´1²ëhk"PC‡Ú5Ñ Hï%ì#a­Â)Ä5¶RYR*£lx)”HkŒl-¾>ön`_ˆMã,k¤9Ÿá! äÏ«]< 5kŠ¥íÔÖÐÄgêî … Åq ñ ‹‘Fƒli¦QSD'±ã÷QÖIµd[â9Œ«!!@ƒ %r—ðHÁ†^ÂíÔj­W›%k"¹­1 Šv`a¼Š‚TcZI÷*ަ2=Ä#»ØŠS)Ù2Æõ²wóNw7•z…WfÖIÉ«2©5:“„j€f§¦3B¬#"eÔіèÂ<ÅÚè¡â)~éºDÌÓÁ¿ÃÝ}”ÕÓê¶þ0GÉi %Ÿa‰º²srB/ÞF 5”*Åml“ö³NTޛ䥮ÈIL¦õú¤ÆK~”Ùìv«ƒø1ÜyÙÅHG-eôuP£ºÞBƒ‚(M\r!ƒ|æ1IF º¤¦÷³{?ë‚l±¶ÅÑ9¿JÜp8–(hy,õ«jb»É¶c'V”f6ò æi*Šæê¢,4 ŠÚÞ4jEpÍèmôú«Í“1‚²Vj· ›³YŽŒHŠÄTQÑuÑtÈL…E駦?–ŒWOSk%èK¥€×M³  ˆ±2ŽCßÜÀ¾†ÄY0„1aûê0Ò™’ÆS)¥Ciœ¥D(!ù>öÆpÖÓŠå ¸ŸubÏ‹ˆÑGÙVv™m»¦—ê”›>H¡JH!ƒ²òʒèø{ ‘ô¢Ï^Àë²ÉýOŸKZÁ±r.dØ1Ha ±ärTÄÀ2Æõâ=TÈý=‚§†Žj:S™>K®ÔBš¯f09Î2™‰ôSªa �BÚkÕIL!)ê‹°6•i -w±5ŽÃ,åºLS¤;ˆŸç>YDVÑudf•B”z,ÚEÈ„âŠ.?β**é¾¥pg '}ìí¡"AæÙ­Ôç0ªk­mMG;ÝDK9 ºêS%ÝL–Ñ7@‘œ:T7Qm§”×d‹®£8–¢œ¨$k%U–È)+¾Åøx–H"Ø5ŸaÕ§Vê5N0¨ùµ´²›ÏùTÐjeÒ,bEÒ4[²™°º¨¤uù±çcckï7ÌuÍ óÂjé6Ù‰̦Nìð´U£R{I3†¼’sÙØÑëÖî¹W®Ò°\ŒUŸ|åKkNή >Å«,ùØ»Ÿjý—xV!6 Pam€š§Të9ZC›·Ð ñŠÍËll¥^ˆ²²´…ÇŠ»m¦Q™~‚Ó…Á´R iŒì<Níb«ÁÂÒËé"]íéÉgØD¬e0)ë© &õÁ½„Õ VÑ5JN*ÓNbmÔ¹‰Ž’ÓN­ 2Î+èE¹‰µ´Ë ¾’n-©e0¹šÃ<’.‰N-ï"#—T9¢¸E�© G@‘hÙåôªh©˜éå(b›¶â«Ì{ˆ˜X^7 IQ€a-íéLEqKGµ‡Í›ÙSO«Ñ)wRÝH³“˜„ØReÉÄö¥1œa¼^Â5t2ø<Oå0ºŸê�ÛD÷P™‰â®¡#‚G‘]ºdÆ~I_h‹ ´L„O/á(îgg¶êŠÌ™”Þ¢?aÅ—(0ZÏÑf4‚Ê?“!²6OªvjãDNI¾Ÿšü‡Ôo^êÆp·™r w ÂݛةuÞÏwóñ9zü±ƀˮ¹3ß±­vÊCÒrÂ-õ´;PX¯‰Q%«ÂYŠ`®“-› dO½²Q g×e;Þö]óÜD³°Ÿji³tQLè”Ý-BÂO£cÖÓyžûBøìÞ&MQ.é~´N ¹1RbÙȖѧ±„~ ÜÌ+Œà’ÞSªRWC<RG›:*u†A‡¥È‘¦µŒ>É{[©7¯,EW5²ßÌž—Ù(oß&vz §2ÝBƒÞZaÄ 2% ±)ÂZ‰võ¡Œ2×àmú¤Z.5Ôd2‹‰³äª9›$£•z-” ´ˆã7‚«“jdHh<‚kÿñ#ÿu•1›—0KOm4°úàeôÉB'Gôô ²Zh0Bc#–ƒ†. –î[ð’A‰šF…Dï2Fvÿðºúæq–‡ j!^²ÑE÷–?¤ýÔvÓˆÖõ¡´ѯ Ã3=®N¾˜ëz¦D܃ö©fÎj²u)5$°ÃÛz¦^_¼É™õ}ó‡pÐ~³üÿüño*ˆ¯${*£Y m jʧɞø„–õ{Òf¤4{—ˆ¶nü, 5io¬ä4»rÙüÓ”RƒÍZöƒI›+îœHçF©Äö”eƒ=ŒXKƒí륎‚´ã U °C&â²H×UgZpÔF^–ë (m]Ts\!î5tìg¼Øå+A–É Ý5ÿÑ×=T9Ñ4ÝR{!ì$âj7Óh 8Êè릲†Ž"¼„×pHÑ'M쬤{Šôn*ÅyË$±Œñ &eçÓ@‹ÈŠ ´ˆ\'@Å”I¥D2˜IB÷ª ÂE·;K®&:{Í4Vѵ‹­-4(Òň¬õ5t,N‰ó¿->úí¢ð†7�� �IDAToí&?ƒIuWô8ˆ‹1o.g/åBÂt~4ÝÊ®q–éˆ$²žN/áj¤Ê%'Ä&yÎêu”,ÙÙqŠõ5º”¾òeŒË¾l•YO«ˆò+i¡Afö:Òk„(†žÜOŠ9®¦SçM]Q>Ã<rþU©bÜA&~zfUbo*šR]—nÅ]J,º²Ú/ÝÌ@7•LŠê¥VØÀc63ܨ5›¹‰f}þq,S9‚l1™U¶z”tÜÖÖ¸-‹Û«ˆ—©%¶J­U®^Áƹ0“å¤}¤>ìºK”ˆÖD±ôZR{rŽß‹úc¶S7EVõò³[hA !üÂcDžöTf¹È ¾•Ñçä„öéZõb8{)™Ò3i‚È‚hŠ¥Ê³—ZHÓ6õQ&k•:Íʶe3æ$VO«&?ƾŒ>šµ1W–LâËé•wb&‰Lªg¢°Š20IF%Ýåôš xÓcuS© Š[¶Iåô #;ƒÉ*(%GJX©YUùô}5bÜ©<œ%·Š®óܧ‘ "åôŠwdfU=ÜÁ‰ï?è#TJ¿Fd€8ëñ¹‰Ž‘­è ‘îji×qªØÈµH>û©¤PF½z© [ÄM(dP¹YÃä;‰i‚ZÌñ &åÉ«Ú,ó‹zZ%´RrWM-£Oœ#»Øª™¡¶%D×Ó)’.ªÔ¯›;AµÖLVdúÙmæbh>,OBíiÔ4«u^¨[Â4ëÀšØnîÝE ÅßGÿõtZ}W`Û͸¬¡b©¨‰žaWÛÙ}6iw®6aׂU˜è,ëg3J¬·‹šÉ²@/  ÚÛy[+v5 ÄÜ…6ˆÝípÎ% y@ˆMR1`Pz‰«‚lŸÊOH‘W½”ËÖÏäŠ ¨ô&Y¹ë~ð³[‹H3‚R´Ê¨é¥<›±Ã¬&_’ÞjôjL*£D„J…q…�öS­Þ.A¦‡ƒê9d%— yËšéVUzëúµ¶jh¦Ð¿rzUÞdŠz'‰aCÔÓj¼ÒsÕº)Z£ŽG9Uâý‘í&*_†*ä$” ÓCD‰S­ÔËl¾Út¦BøZ©™â)ž—¿ŸP¨Ù$Ã!ÄS<L~ŸôFQÜTg0ÙN­’MN‘g¦…Òó®§³–va‡ê~N‘§.Q­Hê´\Œ Rè&ªfE*+Q©k¥¤n§¶2é©U×M¹5 ŠiŽÏ’«ElQº‰N‘.ÿu,6c/å~B#¸T’Å ÑïÖÓª9¡¦‹*BºÁ¤¸h¡Aûƒ z$ë£,„_Vñåôªdj— ƒÔÕTñ °Mwîê1²}ìµÂ"LÂßÍØ‘DzY¤»í†³¶ï\E›|ì5L °džŒA¶ì…Ä’‰.¸W(‚~]Í–±[e–˜fÃÉìo‘f0³ÿ­Cî\£`˜-È^3†50sá ò«Üe��5i j¥¾žVã–+Ö²Ý ´Dðâ\!¼G(Q#ͺ”Úk7Ò¬xU"4 ªΤµ|:´­–e‘Z q¯[hÐ'2(½y4±Ôr¦_W¹ÝOµN„‘ôÅø«ª¨‹Nrˆ5déCirå&*¨l×!Ö¤¥Lß2“¼ÄïÞÁú+Ð'5ÙŒùiLg>µñ5{ˆ"ü„𨮮%GyC?‘­­“264¥Ú ;¢™L‘.ɳêœVsAG:cRC«ÿ0¨˜±%Çnž+ç',9¿y£^×É,dPSD1h ¦”þZÚ ˜§S§¯™Íœô˜÷Õ}h¼zUð´s²Ö–k±½šiÔ £NÝÜÏÕÕ×=£#Ôy»V!Ã͵âs‡cݶ$×ýû&/~|ùãá7¯½ö<]‚÷¥ð$á9ë;n{‡èÒ=´œ‰qœCt•]ÎÄ8/Ìã)SäÆyžö±÷Uç�žVu™Ç•5¿G–õäçæñÔ[¬|•Õã,‚´!º†ÈǹŽvQ_ÀÚ!†d-ߣz§9É«<¦ã,Á;Î Özm~>žÓÙðóR:Soððœ?d}€çÓ˜ž +‡Ñ™w’û³› +—_>ÃÖ5D yÓKøî,¥?†ó§<ü˜¯,&þ³†ˆ“X:ÉïóÄ<.iqy‚α4È·¾Gu.ã?â«oPz§‹“3/Béãtg3¶”sr$†s!ÄqÜÉG°p)ç.sÇ<œÍØ9–òæ£ÙÃæ'ùÎ;ä”Ò?ÈC_$ºˆ_5ÒìäÌ<.9‰Õó7óÒYÀ£9Àº›6òŠ Òül‡òž ë'”-g|5}[øî -àp×—xs”{.° —ò�Ï®à̇Üü)ÿx WœÄîàÒ;äŒrÏ�E_åþÿúþ Áï-& ©ŽïÝKõ­Ÿ~º“í¯±ÆE,Skyí^æ5"_$ú8méüæ .1ïV®äqúV®d1ÃYJÿ‡Üµ”s_ã¿gòþR|ù g0ù×üånõÒSÉ}K9§rå!RÏ߬àÌF^QˆNæ}œ¾Â­j_æs1Îâýlø‹긜qC–Ùφ<N]`ÁIîÿ+žI’ö‡üK 3çY²”swòÑ�E¿bÑYøóþ÷Rx WNrÿéO°è2w„ØTC×V¬åµ_pï£%ç JÛ¨»…+Gxt=ûÿ…Õw3ö<OïbkïIî/bàCîú¿išÇ¥lÆò85Ê=q/ñõÇyé.>\Ïþ¯ðÊ+ÎàÔ¤znã“ÿ½÷‹©óNó<?ÚMϪUmÔÒÍ(KåŽT±ŠÛ")67É/b„–-´§Ð.\D!ÂDÈuÔ:c¡`¯²\œ:5¬ÖšŠ¹˜è¬ÍzˆãªÕ‹5úÓÌ,Ûܵ}±‘v/>¼àôôåÄ‚£(²ñáœ÷¼ï{~Ïïû<ß?<ªåðþÏÿ?ù-¯½MåSþÛ_óoSùÿªÿðø“þ÷?åoF)îórÿ¶‰Åׯ¿-p£ûÇ?ob§–£ÿ…Þ«,ïòg¯òõ>/?áO€"ÿe…‡ÉZqþø>þò/ÿò×ÿÛÿñÿÕþ?G‡ÿ×ß<ï„û(aèzÔd¨clT"5]¬d¹À¹hI¹s)s=Ñ­?si5[Jz‰§|+Ž2á±Oüåç˜N!¹°ÜFA€u¤‘’Ý¿.V¤ôòÙ ]Ž.úYp`£=¨;S¥²Ž²ìøÙ+Ë®>ªˆb5´åë¯Ð5ȆñêR‹Ü–Z½N»Ó¦ &Ç™¸/žaD––}ÀžêœëKtâ½—ÏŒªÒ|ƒ6埖éÖ¸ÏÃ{¯4@RìµN{º4ÙÑzÂÅMZƯ~þ‹òmFœ8]ëa©Ÿ=y}É[yJml\à©~QBHãLÕqPË¡luYõì÷2/¤Ó‡°‰zö›Ù~Ê…šò”›Øù¿à.r5f~B2·LwŽª°©žýš6hËS¶MÑb¢UßÂ6é!µÊ¤41Q®ë…N œN€l®¸!f*3$™SÓ¯^æ5¶è`5ø/‡Ôzùl½Úlü„÷|q‡‹ó 8VÔ‰XÓ/ùO¸(9hŒiC>×i×vÄÓ.(lg½JNn‹]ÓÚÎsoŒiMú½?í+H*¼Sà†â¿°X¡+ëÙœ¬žyÓ £SÝÞM¹½Æ•!>!ÕN‰ë3eUjß^ ‹&2!KØ[xZÏt‹'#f.D÷NÒO©ëáWtVù5Ùv!f9ÇKqWèRXCF7·µ’ b¬ ’Öi_äê}®IFÐ:A–„Rþ’ lÄ…+àWü«Wv¹'\”¸lg–aMí¾àíMZg™b|Ü$æGÌ0⊼Lwž’ïÕÎzë´?æ'öµêØ¢EVˆfNºðYülImóZþ_Yk{ð/¾ãïicÃÜ^à/ÝZ¢Ç÷U(=Ä›¢–1IÖ¡66 éБOÅ®m7µ,ɪÐÞ¢‰ú/ñPgŠ×þè·¸b˜²òd/¤ /S•\Žj3ÛQüì/^þ¬™í2y‡Iìúu3Ú¦Ù~?щ ˜g@;DéûÞd|l‘™iEÉYd@jL‰Q‡‹ÊÅ6iu,'‡s—ÆVc7.ûËt7ó›I&z™aF÷[ß}—ÆZ¥ÿ¸x>©eØ)é sÞ–Ëtwò¹^‚N³ ÆÒ¾I«•x9£$ôk,¹@¿+ŒA—©–ÈGñœ.øbW¬Ä$é88Ñâ…LêQ1UJl™N QjR™ž÷‡Ëh *9ndȬ&؃þa….¨id7ð–ÿœ²€â‚*rf/jªç;ãÀ[®MO¹à7_‹&Ûý*@݃;GÑ*IûÑ2ùN>ogý ÞvTu ˆuú¸kPo‰Qܯ¸^[ÂS—EÝf¶“Ê Ÿò®t~ŠÜ> .\6ºYvXeb½ ÁqŽy²9tòƘf¬HAEð sVã”N0ù‹—niñË¿Îÿ»ÿé• Úö©/rû§/=øåwù66t‚wøïªgê£©Žƒ<e`‡¦mš/ñØJì-c¦|u° ½ÆßÉSXd`Œéš~ý÷W/òÄâ¤àZ6¿ O2ÕQ•ÜO_ÀOù¿}ÉoÇ *'™0FK´7Èœ6Á=,éšèñ[Å­7V‹Ù0³­lº{Ð{¢›eÝxí"›Ùvôd™66‚yßκàRžú=1`{ÌL.2`�ã ½|æÀi–aÃD¦»Ì£àÔûviT\¡ŸHž{nƒzXje3OÉ›ºô²RJa‘[§}‘=>üPñ¥{¹Ôàüñ¢b¬D_…”³l‡X“ÖsiUV–RÝî18ka«Ä¨¤µ,ÈŠÔ Ðýl&D'r3¯[#DKaé褻 wÞÑÉút"Ýñlš4‡v;Û…\Ù¢Åͯ³z£ÇN§ " Y%Q¸ž}³½>àãh”-2 }{ž’†æ"œš:ä×Mì¸íѰÈÕš¦ ø\ñ7iµå¥'º 9‡T;WòÎ%@7²«1«îJrñÅd헚ؑ¨ýËïò#Ì|Í«TªäÚØ°Zÿ滟„}¢”ú2×Wèz¯äÔíÑ jêk^ÜøXQ—o´J‡ˆDœ´Ms™üuý,lóš85ÈúÀS.؆µÎ™úHFó2mÒú·_5üí ÿÀj\ÔÊæ%Ô¢éí=yÊõìWÉR»DÏ sKô(¥ú˜ì*:žfLæçžÊ5—'b‘k`O½ ÏaŽª^!’ ªru‰‡=,™òåÖG*à!µ]¬Ôqà鹪¶Á¥`ŒiqÚYWä) ît„Š®À=›´zW›ª#8kd·Ìõ °Jìäó`ŠÒ„‡|þxQ+Ö±ÿºÓ)/§ýb’d¬ì™WÂ0)éVóë·ÍkÑ‚ %¶5öóÜ;ÙSŽiYMjlq2Ž«F‡ÜxG ¬QüÔiMk4W»XQÓv@]…w”Ù)L3¶B—µÁF- K”Ë®Æz‘÷a³eŽA³øzùÌ à¶\³ôfuR"ßËge†êÙ7q~Gh‡ÔêÝGf°ÔÍò4cFŸ˜B¢µƒUqá ¦ÊúRñ1[Ù”ú,wÜ(Þ1¦í‚ªo•èÈÍÔ «µ%Y˜^¡sŸúf™ëaé—èÑ6ª©î5îK¸_¡«J®–CE¸:*\SÒ›’3ë8°³jµ^ €ùI&ôz_¦û=>!sÿS‹ÝIE0jiì¤ÒÇ]?àïù‘ZÝ/Ómrc`²V6 =± ô‹6ZÙœgÀŒæ�¸ ìM2au±`7°§ñc+KôìÑ0ÅxxŠtŸrAú¸Ø3© â":Eù|aâ-u k\™aÄBµKcÄN3K„"‡-Z¼+Ü­v³2a_6\Þ]:Vèf¶=EŸ»x\JŒÚcð}c¦ËÝycðEŸcÕ@M:â ½”¥YÀ™“ú){¤÷ì¦ éIèë¤"o¸tèBfNQ–SŒãÝV�>áW"y®II"g|Qæz [e† Ür»êÕɹ JߦöÞåÓuÚE~ÕmÚ¸ŽD"I4Ü\ñ/óÈ´ß-Zì)ùúÖ€=¬šÊr5\ðõ¨»L54Þã“MZǘ~ĉæ†h 2·Mó·ü¸À ó´lÊY¬©½Ìkî@æ”!EÛ§Ùtiîaiš1a¢¨¢½ &žcPå²\m^³rh¨qx-‡mô³ ûÃóeI‘Яø™m(AŒ›�³¦ìyz´Û4ÿòå!±Ë'¼WÇA�;‡ VfM1nha…Î66.ñØ€`s%Ñ1,T@w³<̬…ÍšÔÍò«|ÝIÅ›â0 è´}Í«‡Ôìkù´/êÉܤÕ}À2Ý—©®Ó®@ÊËÝ̶³4ñ÷wò”í¯8ìaÉ{f›fŸ)òЧMÎaf•ÓùsO…ïâ5òpÀ©@¢…-/Ç9?~7Ë—©ê ÒͲþ÷ ÝÅºŽ“/^ôŠu”„"f)Óÿ^ߥ1¡ðÝ‹Òu2óÞŽÜ#·Qu’–]MB²8"É!Ìn ##‚^ÎCAå-B ](íg&]ͳù¨ ¢¦®¸n•¹î–V*;kOÚ—¼Uæú%ªÒmd·DÞ=r“LnF˜)pËÂÐÎú<^V÷ãÁš3*£ –BýÓ̶«&vƘvJÑÈ®=FI¶wd4Ô³¯íÉLÆl¦íÒØÄÎ4cyà¯uÚç°gu—> ì¸!ñì+^OgKúwt±òÏø» <õ<H‚Ø¢e€ùZmÊuò –Ã.VôG×y–ÌÊO‚\øó~ÈG5³ÝËü ]Ñ *„±ë´ÿòÛ¼ «Ú^‡y–7âDcÚÔ]½6šÙÞ í>Ö-B�ä ªŸ…iÆ~þRy„™ú/ñx™îK<b.Ó}‰ßÖqP&?ŸçÙß ‘õ6Í;Ki'Ÿ;"3…ú-#>k·Önƒ"‰*Ͻ%z¾åÇ.¦![o<óaÖlà¤5I(&1œ±Ò®µTQÝ,Ã!s6µËò!µš†X¥bó­€ÝÛÞCMSÔÏ/pW0Hä’jR;A§V¦'ÄŠš´Bä)•ȯq%£QÔ¤C¬dB6” ]ÒNã±Û“‘áò”<°ÄQ—ÄiÞÖeMƳ¿’XIÅGŒ%O¹iÕqG¼E‹ß| ƒvݦÍ0ÒÊæwÞåS—õ³3ŒŒ1WYËö¶l"Ùà²H8*(R˜aĺXÇAŽªùêLljd·ÌŒ +Ü2Ý‹ DĆþ:r”ûYf¹ä•¹¾D•ÒÍJ7ËSŒ7°÷” q„Y`J±@q“ÖyÜÔ;téã®üû»ôée·F.H¶—é~ÌOܼÿˆß˳¸Äo­»2ìµcX ¿½_ñ³/xۥߖl-‡º¶Û›gÀ”È~Ì3´`8=²ŽjýÞÊæS.è^o¶ˆq\ºÎ #¶hñ¨Û¡é"Oέ‘“bÞͲ¦…"Ô<¥Ÿ¾ôàC>’§§óSKZ4ÉD×ݣĨ'^ABiÂ#[Ø: ®‘Ý£‚xCL–è±›çÒ+ë§.1*!ÂFŸ8IH¤ö@‹/K£Ûâdc@ö„N%î‡üCKL:mgݲ´Ik™ë‹ xØCÜ‘4ø}ÃïóÇúqÚóbëý¥­¶à;D2E:Uʘ÷’€’G6£2lt%8îË"S¸D^™HÒî{”𵓍Ü%ö„Ñ{lŽþõØÑsšö3§l›†Y&–+²ÆB3Œ„óº•à”‘¹ú¤€°.Faà ?¼±ÈQ­’s¿¬‚NºÂ]k ÿIÓñ9çxÂE›cZt‡³Ã<wé³<ˆKê8èäs™ Ú~û©Íµ²ˆ)‡™=¤6üj}¾¡·áéyR_ŒCj/òDðÑÇ]Í :©x$¶ˆ­Ÿ…N6¦õ»ó#̸Œú²áLaQ?`SKtY®F$VÖ*¹×ùÊÁ’çЃ.òä)%þ¤–à <ý¿/Pfv„™¨ º™´Š†m˜¸[·4¡Ó­Ot”÷Jy¢¢‡ÜÍr;>Çf£~é­¶$FþqKÄ™ô^õ¨–éÖ{¾“J…Î!îhÅü~vÓRœAÆæU\·8:¡xü+teɧœz®œƒæãŸðn„u—¼ŒÚ@[e†Tþ&Þê¹ËTuHÌmÓ<Ƭ¯˜N¡Ž†¸“ ´N˜ØFêZ2ܪ‰ÖbFø©&ù#ÿ)¨‘`²34Êò•¹î7|œQd^_ÙÀ#Ìxùܳ¹-åÝlr+ñBò†Õ¸Ì1è È'¯ÐUà–Œ>×w‹¢´ÃAæšØ‘¬,Uϰ§ŽÊP5ó³뢿b⻑‰ÑsÅÏs¯ iAÒWèZ ¿—ù°V*s}‡&KW¨²¤KŒ0ãËN2ÑÅÊ #Á“ôùyR¡Ó‰}5ƒ_þA*[ˆìP—§äâ{H­ ã• ‹"q‰‡65ºr¥[n-‡&[º·jÜ¥oš±¯yÕ5=–? ®Jnƒ¶wùÔ“f½¯Ð©\tØÇ]M+¼£Òvš±×ùÊÞì2ÝÚ6ºÄ税1=̬ÿog}‡&A¹ÝZÕ{¬Àë´YæôãÇ•ja«ƒUi/QV#@ X£ö÷LµI8̬gŠqeajºXQ^¡ÓlëY†½«çœcÐr•n³¶hQ58È\•^M’öÎ/&Æú«÷ÛÃýh9ý¾È¼ÅN¢«+1UrŸ¢RÊîÓ©=Ë©©RB—x””·c<¤Ê5¥~˜§õ}€éDªÖI¼ut2òŒú_¸-u?+'óÌR¡Yñ›b‚ˆ° œmÖCdA‘9_Äæz‚I+\øF8“}.mn”µ´„ ‰WžSà–ž{–ÕKü¶ÈÍ˜šˆ·¢«–…@uõì¿ÎW_ñºZ¢:|GÑÌ/þèÖ/ÿ>/n €Æƒ&$nqÂûηH#š¤k[ç,ê@ T¿J‚ QT$Z0³F®Â;ú൰5Ììmâ¹>îÆœ,j’NƒMEÀU 9 •‡ç+*&ªëgá?åÝSG–Œ>g›æ�+aôgBÕ�ók\)rÓ[ÈËím 0K ™àì¥yW€à;�½›£-Z¹•¸yçxÕŠ ãîÒ…½D~ŽÁû\“d™jxTÚBtFà»K#L¿ b¯ózðâa,!Ttç¦+pKGÿ©Èmô$JU™~‰yå G‘›{á†g‚ß(`Ï´ ÜŠVa0 Óò(íT'Ú…#sÇHigvšUÕ›G¾ßeª:*¹˜Jgؤտq'¬z.(u*1:È\¬2~É%ìÐ¥aþTÖ­ïNv“\w2ᤤÂ;s Ú´\ùî^ÄN*níÒX"/ÓLŽëN+ª¯ÙÕ:h•±‹{ê^æ‹Mì\ã¾øìu¾rÅߦYFß/ÿ>_Ͼ#·1¦è_ ÿOͱy¨û=¼MZÇ™ò‹ Q—µºt±2Áäu3ŒhC%SÑ%{…®U!ËžšìlK³‹•ù@F~…NWü &åDL0©@¸Žs É<ÔCý-—Ïáß syc•Ž ÚšØqгM³÷°¯Ý¥1¨ÿ¡áup%:T½ë6¢Bç #±oP­}°† ÞZÞ' ›·ml„.˜adš±-Zô­¨g_uŠó¶V6M‹©Ö<Åáe [Þ±À"W=’2y¤-l9ÈÔÛe‘«®K»4²#p“GÎËÕ‹òxéùeàéÑ:[î¤V2>E9+<yîrL·xDw;O©œågݼš5€£uÚu±SõåÉ´Üd u¬6ª8ó”¾x”ýÁ$x"î˜Vè‚[yÁ¬š³éМ$Â<kœ¸q™®¨@Ì%qU¹:;²6½^EüœÌ]C÷mší(*øuÚ¤Hk—Æ ïüô_<øå_ç›Ùîäó°ì~ù.a¿]¡³Hì†æ4öã>!–Ë<÷Ü€;4Òg¡Àßó#×A9FGN`Œ¾~ñÒ­÷Ý+O¸ØÄ޹ïÍl‡Ñ¸oçPjŽÁ5rßòã¯xý)BôÓÂV•Ü0³R*&˜œaÄa•8/šx‚×M]áسê2ÚÊf+›ßðÊÏ‹eþ5û°aö»ôE#wŒéKü¶Bm-‡—x,/C^{§‘ö‘Pü_¾ÍÚ3ŠG‡¸ã×ÐZž£Ú˼8OP%Â>žwY¬¢ì¾I&.òdŸzÉ ž|7F´Txç€:±`‰Q{we†äsùW+œž[q®â¨¼‚á¬_ä¶ÍIw–É8ÏN˜<Ùò‰É=sP—ˆd.~Æ;1/Òã¿ø>ÎIà/!èÑ7b®Ê ©šŠ‚án%scº~²Ý÷ÌÁ6ÛòßR÷çð3 X#Sþæ²Ø£Ä8Šç‡^ ‘½&qÂ= ~GèÆÎàÕ_æ‘P5R %‘ëçVæú #2µŒ…È×Lô]f,š´–%ñ´Ú&ýܨs)tã_ÇÁ[|©«ìee@¿þë«À*º— Ñ\z.SuÍm`O._@.¹Èbš8¼�½Ìø+ïÚEžpq•ñœ½J2cV1„jß_~——î¡ÜØ%¾‡%Ý$>ˆQf)1ú5¯nÒjÊ]ú<5±s§~vy†<ÈSŽ<Ã"…I&šÙÎQÕË£ú;©ˆh]pë8hbçµ—Ëÿülºµ§Žƒm^Y ÿ¾ù€{XRte%¶d:³4Þw…® <mbç>Iûó=,W§"…*¹<÷äs:0Û¥±ÀiÆ,B$¹r ÂS�� �IDATrü&˜|ÂEuZMìøa‡¸ãȳÄèýûÔWÉõò™ {àÛÌœBð“â¹ &EŠnØËuþ¤‰°Ko ÏD)RY¼GC•ÜÓ6 ½©äÚ®$3јg Â›+tÙé9ˤâ¾b9 ¥TZN¦ý’ -’„ûjâÂ^ãK%ÆÇÏLÍ2·õ£„ QîY¯@—÷+IDÖñ²•Nå†$â­G)+ä¬=²¾ÇçY eÀm~3ÛJµð¡N3ær£wC;ëcL·°åoic-tAO×Sw¯.‚Û4É[“LÔrX"oná&­ af%m“ˆšWégñxk6¬ÿõ}csIºD7Ëvµ­óìž¹¨õqWf¹F½Ì±è N0©ï¸±žýCþÔAÔMRBVèªÐiTŸ—ïn–¿åÇÖK;W: oeSÛßkÜofÛHÜ2yð:cŠÓÍòø}”ßÚÃÿ̯ÿ׫5/ݹU:îÒ×ϧ¼ÛÈnâ%k§ä3Õ$Ù…+s½‹• ;49—JíBŠtÆÊä=3J’í÷*Tha« ‡¸£¨N®‘Šï»DæXEn·³>ΔƒL»²~ÇV]ã¾°5è?ŽmP7³­yà>õòÃÃB®åGã«!î(ŒY”Nd¢@oÝ4ÛSߦ»ômÓËKjüvþxÁ˜[ïÿ(RQW2ø|”rÐÓÈÇ„”Q]Á”ωö]MÆ.­1õjˆ²¯qÖkN:\<:ùÃc"F°çƒé^äv2A=g^pJpª·&˜°dÿGLŒÇe=øÃè/¹´-2v}Ћܔ.ÃÂa~Ô³”¬,CZD{tr¯e¬Yê©•ïÈ ãL;ðod7%7Kzžb<eyx~X?H«’ã¥~D³1:Ûv½$Áû[­læ¨>ᢼ ’>üPòQaÈL‘Ý-©þdöq¦šùæ[L"N‡GçÊ?PÎó`¯2xçVAißLþ›—®üú»«æ.Co …JÑŒ•ìñ)rΫ¢ÀISO?kŒ\’¸1Ht±ƒ‰vhðœáM2a[XÉŠÅØ·ÐÅ´‡%ýòcŽh2¢#ƒîŸ(¡A¦÷Ñnm™¡ o†#~;t^^<æÅ-±Ìå)ePd-rUE¶HSê3¶èñH)3<†naN‘µûŽq˜å*kë=«LµuR¡U“ª†91©"› ¦aÇg\X“QiŽmø-3Íé‡ëVTpà~˜Y;3²bÅwíòªÜôÛÞÀÅH&b´\hæ”ô%DÐ'^úö¨âŽY¸uÚǘvæ¤ÿ‚¸ªƒUýwi´#d§¨=…|‹úŸpÑ%RÕª‡­›ø yÊyÊæWíÑ ;†3üvÖûYˆd&5Ž–¸O¸¸@ÿ,ÃÆ‹Øß»È“66"²¹—ù&v¤rXþþRy†eº›Ù®ã ™íN*Ý,0ÿ˜Ÿ(.ÓÝÇÝ‹<Ñð•Í~&˜ô¼•¹¾M³&îÍlKÏ+pÃrÕÏB/ó}Ü5Ä“ÜÅÊŸ÷Èó?ÂLŽªS¢iƪäB²m­ÓTÉ 2çP°™í £k•«6¼›e[‹rI–é¶žÅ@Tv»*Û•e®[c¢rxb‹Üc:Ï=¥žïØI¥L^®W9¤ZÖ¤MZ™ÓÍ}™î»ô5²ƘcLK˜t拈òFÂÑ“•­N[”ÙŒãüñBu½Ì6Ö¶hqß!³ë=>Éæ5'C=jNެˆ’£”l¥qVGQ“R݈gÌ á£¬à=J¥TûÞÕį$žî5Ïç@ž©‡¥E;„µL÷¼­·m“¼©1’‹‘|ë9%¶¹nºî(E’ëUäv3Û²ûbÒ §íÓ#ÌÈõrP¡–K[ÕiÆ„ký,ˆ\’^ç+­›Â%(„b6ˆ¢DÕ³ßÉçdÖvÿm-Ó 5Fˆ¢®qÿeö Úèãnžr'•E¶hé¤2Á¤…mŒé" ,Z Ž3¥Î):lª‚úYðl¹=ËpX6²ûëï®6°7ΔËmš-íj¤\©Äï+t:Z›fì"OfùšWwi¼Lµ“JTýeº™Ûæ5™œÔ•­’óÔâ± ÚÁê¹»ôuòyžò9ep‚ÓXl9.Óm»u“ÖZ½=ôZ kÁ&v&˜,sÝP’af9­‘sR¥kŽAÏOž{º#Z!rTõY~3'˜t/¢‰e/±gÕəΊn8‡ó¦j`¯»:CJE‘n Sá`ô·uFfÌZ¶îªÏK V±L› ãó<%#m:ùüm¾ˆAWâgQò9޾b®€§f*ÉÞ?w’È5/ô}€`Ƨ® ð ŠÁéýQ@Ã3‰Ê e ¹c™ó K×§¼ÛƆ…¡“Ê#®ôq7B(ZÙT][Ç:P Z‹:ipe\ ‘«rÄ%sßçš ÉèV µŸrÜ‹ô¼ha«“'Ê\ïãn™¼;ëAæ\IåÑɇvU $8kes‚I÷f1×£ÈM×)V­l¶°eì“®€Kô<á¢\GYyny¨eòŠ\ ²²Ø„9 ¤2&!È8Sò'ešKr—>«‘æL½ÌoÒúïù3¥¸_ójKª¦™³ ?6ÃÈ.Þn¹O¹PË¡AÞ 'y2ÝU=_¦ZË¡fHyî•É« ¶~lÒª½d8’ÙUàÆ!µæ˜¨oëa©—Ï€K<cºÂ;üä‘ïÐ$eË¥$À¾œ)-úGuëœZ%»×³o¢µài×d/w¹N*vÛØXd@ Fä`5óÍÓž<e;ÒÞŸd©oŠÖ»YvÔjS1†¯»4žñP½µb q'‚*b»$iÿK‰ ’Ͳ)kx¥ëxä9I HM™ ö¨4Iðcn…®„ÇQÃ3Êâ3JEøn„¢ëTBñIåÖ™{d–ŒÇçÇM¥n yîÁ>ÏÀ Íüf›æf~ãtÊ­÷.‡Ô*Trñ]¥£‰/ŸÊ›ö©w åØµØ—«ã ž}•Uv“Öi·!¦Hè1?1ñHš_x½»¬Ì2œ£ªÊ'($¢“põV²ºIë*#̈ÌÞã—cVÖÚºŒ:leSˆ$à vM]Ù¥i8Ìsí`U±QÀšºÄ@Ô™D¬Vœ¡ílxï®ÒQ¤°ÈÀ{|â�f•Ž &Ï©Í%7ª¶‡F!k±±N»í´-ѳD§Âª¯ÅŸç_êRžž=دyÕúaïÑé‘ ¦“Ï%j¯;F«#̨q´ìFav_9F\’éŠ΄!`÷B7³mëoŒéCj×ȵ³®4Mš¥6É„,Óºf®gßµEË,Û´.2 FϬ,K^} Con!Ü£a˜Y»nMÖiʘœ™Så?ç%ác^üÕûí©™…̈pHæL5'LÍI²FMBÙHSKjžãh<3ªHLÉw’á ;ù„Á1”Y¥”„ÄqÖ1Vj â¹Lu’ É‹ ô2Ÿ²W¤W8Òp£+E"ü¤H1ðç>Í ø“Ò·&™£ÂØå¸4Ĩ<L|bšq¦ä‡O]újºW�—xü%o5±cIÀŽ…§üúVèºÏµ`:ÑRE×z²Àû<åE?ÿ“ É RH´@”:a¢Üz2‹wLû>K¬ž#žç89žð!îø¥s†P¤ð2¿Óûq˜ÙWøæKÞ²b‰wƒq,ŽMîøFa·¨åã<:-ºÂްaü‹—>ûõwWO™R†±Ÿ'@µzµp±2À|’fþŒÞâ™ Õ]j“ÔŒÐÆ¹3^#§ã¢'<¨4¯òµLËô^ s“¸‚ãLy½<c+tœYœ?^(æEÂV?NêŒËÉUÏ«NÙ&e®:>µkRÓ ß1ééLJ{v$5p”¥pE§QˆŽcç‹S$ŽG'Wð³E¾°¢[®=›õ—àÚcC× R”«˜Z¸ÑÏ‚kß*ÒÀ^7Ë6sDcÆ*FT¹ÿT¤°EK‰|#»E õ췱іåj‚É ïD¸Ñ�óJS%¡Ùáq¥ÖÐÝ`ßOxoŸúK<\¡ËØ'wë1&$ÁïÒ8Æô×¼*@´2ÅV}†êj9t¡—>`FI{ŽÁt ™a$M pùkes•Žf¶Ÿr¡B§z¯8Ã`Ħ“LØ#mbÇ/‚ ñ0³ÓŒ½Ë§En‹Æl„:Z“\𯗵ýµCÓ|‘Tâ]ev^Ä·ÂÏP÷ þ®>{¶ëÙ·\íÑPfèWé¨ãà_~wÓ¹µ^Ú÷=ìçjfÛ E»sÓŒie™õO‡øæ™fÖ»Hù” s³ºXÑOÀ£fÖFM[úYð„Gä#Y.I ºú—èif[tk™—ÞBeª‹É(Wî§“1ùùãEÃX?zKd+~æ˜K8ašžKÐU.!òYˆ'$ÏêGÅNà¶{,¨51늗J͘ã•O*-ÎòîéøT„×¾@ÁÞ‹›Ü�R~™6ùû®J©åv@‡°NðÉÓù :ÆAØ ŽrZ]ÓãÉ>3õ¬‹…,ÈÜïñÉ—¼euqùós9›fì Þþ”wm›ßM÷“Zz‹{R'ÀU:l�ꑱLwú¦I4ò08øÞ³w§4êdé!H$ñ÷°²Ý<Ã3Œ,Ñc±q-neSËözöxó†Žì)” G|_0®ˆX*(é©@3©m¿×Ðɰ“ÏM&óšjƒb'c†‡Xqí<ÿŠRwÊpv¿Äãmlhú—âT I�Poï_DÕY>@ÜxÛ¼ÖÌ7Žf¦®]“L8¶Ô3U8Äà*ýøNyOªhÎÁÖ ‚±\™p¸¹;©ŸÅí©Ìªcs&w.1@r“¥^‘â*½R2÷ŠŽ“­s¡2i¥Y×isɱYB&Ä*˜<¹æ$À:s0Ë(XË•]»5rú Ùa+R˜cÐÿo^º"l’ÿÖÏÂÓ3×åHŽWk®Û–7ìnÌ#=–ÌŠwŒé2×—é¶É–MZåR»pKdPÍÚÎú+| §ø8Èî–Š<÷òÜ“*ÝÅʧ¼»GÃ9RÍ0ÒÄÎ:íËt_äÉ.Ö³¯l….{‰â ­ß}Ó>î2§Óy+›µüÍ'¼ç©°-6È\x–¸qÁõcJâŸeØl-—i'1“LìÐd-‰‰Ú&­KôüR 2§Ý‘Ëú".Ö»4N09ÄY—ý,rè�ÏðhÀ´ûAæ&™ê­Ý†åŠÌv¯JÎcç2Á¤”E'FcLëÒk­’7Ä%¯DC?KÂ>õ³ WxgöfŠÜd.\Õ-ˆž{ùlœœÓŸ[Ùl`oŠñ]{XŠƒ´x7ó› oN2¡³»Ç`Š£Gb+Õi\Ü*&:¶²éÝžEO<J3üÎëÄ Ã¼aoT”ðL±Q˜Â,`GA|O¬o¯ˆ–‚‚ ÉWÈhÏ|¡Âú6+cÕD'üŽ(`Ï ½©»'yíGgoÕ¸wVäO&™8¤VOñkÜ_ãŠ{ä_wµ!ÊòHb>ܪ;É·,¶ëÓ$õÉtë£3‚UÄUo™î£^_—Â^æ}Ž|­4ö©7LÒºâëÊ»!%¶šZGg™`²HAdfað€uX¥#Ü5hX¢ÇB;À¼¨ÈPĶä8ìÒ˜¨cß©)Æ›Ù.s]HQbÔRT¤ -MZÁå�:ê�ó ìM3¦ð8S”vÖ;yà{©¸ja˲mΈ¯ç^à0™^a®ìð;¥ÇG8]íÐô1L2±I«ê«mšçÐé¼»ZJªÓRÄ&»Aû.ßzŒitÓŒÍ18À¼ôiÆú¸Û–6K²6œäy†ÛØ´ä«©ÙÊè$ãt³¼ÈÕ"·ÝkN36Á¤n•vh ¢Í:íòÔ ÄÜÑTIQ²óNÏa-‡²»Ync£‰'d±>©ò<¼ +YÍ#ä÷Yç­Ä¨=À4¶ñ9õc—÷“Î$OÏjL‘Û)žëb%#¶GdÀ*rÛ°®ÄH¤à[<tª+xêåÔÑ“ “ÇüDO#7­]¬TxSîÜ4c‡Ôj­ä¬ÈÌ\9]¬ä)Dd”ÔcÞpqß Í•× ~»=l‘SÜSáMlÛYÌ$­›ØËSÖ]©õ2CÎÌ´´ª5±s@kzwe„_ã~ȰÂÏWŽS§_ƒÌ¹y÷i®ìoñ¥ ôí¬‡šj‘ØÔ[è_dÀÆ`'•§\h`ï÷}±W‰¼ª5‹|ÚýyüO¸èG[§½D^ ÒÆ†ÎÏJŒ†iˆî‹—©Î0âÑí×¾"£]¿v­ÙÝ.˜&5ÈÜ>õð±gLô¼GÃ]úÊäwiœbÜB2Æ´O~Ì.ú‡ÔFÇµŽƒEVé˜g@E— ­…-'CBê$ ì±Ç ÚìXZKüPÜó”Ü,Ó=͘H(Où ÞV–ÐÀ^ˆ(䬇•”r‹eº“©ñJ-Z¤ád[Øí¬«DœeXI™þË%ò±ÿv.%~*) Ê&F%½eZ˜Ò’€:a†©]Šrìã“b—Æ´­Ð% F†”ýÄNfE’éO�/_Ð0C<Ø"§úŠgj”UàV|ü5r.Ê¢÷žÎäM0¹GCKé> ®›å£+tI[w™s‰/rÛ IÏ‘�éÓBA¥Ñí&­¯òµë¦täZ[Ù4ºwö—ù«ÿ ‹\Õ AŒâàÇ9î«wéŸÍ02Æt¨‰{X*1z‘'‚û`êrj9ÌQ-s½™m)ÔŸòn? V7ò&\(’õ¤u°êÑö.}³ K‘°Ìx¢„A ìÉ]´C%gÝJ&&³Då´¢®^æ%Î)ÙÖéÃyÛ s#Ì´²©ð3šÒjÕèAZ]œv°Öøs ú^Î熸 ^7yÊmlXÔ×i?¤vš1Û˜-l1}™ê*bÍ'\”h#ú´éê[»óìPËßlÒZä¦Þ»vJõM–â¯Ò ‘]ýGBÉ'ˆWý韵<V¥îG¶4ê´ÛÏB;ëRlè÷SØ…º5°·A›S®£cL›#~íe~ˆ;æÀQæå}>ò‚T¬Ì-âèTéŠáˆÿ𯉭;aë®KÏÕ¿Ÿ™ (2RõÍpË SÝ"·£!ÖPêšíödZ.’ÒX“éÆrÑ]ŒXô3Œ÷k²>êu2aãÃÈüµ%ÕÂÖe/ë=ǰL÷ë|µGÃ$/…ÁÁ0³¬F§KÔRæz? V5‡ÓŒ™Î·K£5/vÜKô„±…ÓˆðBmbGš™kqŽªT—!_¤‡¥q¦tHrÜ"©}ˆ;Ú�ú©­í¬Rû” Guò¹Ûv×_uHó 8k‘õ0Çà-Æ1+©ö}Ýæ»|(ܧ¾–ÃN*mlhªTàF3¿ÑF¶Àeº{¸ÑÆÆ2ݲøÚY7óp†ñÊ,ÃÆ%×q`Ìæ¤£©0"rÖ%Ê)p˶ªZl5gŽm,BL¹šk‘ë×¼jö‡‚¹êÖÈÙËu†7ÉD“k9´ÅºEKKòDð¦ð®Žý&t°uÎçfWûokíaZtÞHÓŒÕq`Ù+kr›Hè€:õdî®”'[u´ÄÆ™rzJf<ïåpˆ¨K¯…Yc'9î3w÷ž†¦bI²ˆú*à´¤Y²ºî•Ö Èb“=Sí»Ì“PF͹¨%ª""þØõ%[.Ó¶Þ#=vƒž”¼ÑQf])ϘúÒ:»3U{ª"à7ºY¾Ì#±K0#¬4—yäÎt…® o\.“WåJòšY†;ù\(£}†iX)þ/ݲnmÑR¤rN Ø.C”{Xr•y•¯} ã †¸³A›öáÍüF±m´9MƪÐiê GµA[¸L0ͽ5®vhºÀÓV6¡¦õiƨëaI?ûô Ml1™xÒʦÜ9Ñ¡ó|s³ƒé—8ÇàMO¹°C“ØÂX–ËT·i¶7»I«>¼Kôô³à@%fTlìà 0/ ÄlŽ×ùÊ/‹ â]­ˆÞY¡kœ)óší4^¦z‰ßŠn•×q þÚ–cÓŒM3¦‰‘ÝWá2Õö.òDüêEoak›fÑù:í“L\âáýml¼ÉhŸyŒieVbo<!ì'¼·Móžv³üÿ½T#c•/œ ^L©{SyÃúä½êœ,ÄÈý,,2 ­¥„{÷‹  `Õ´]©‡ç-ÙÈïž‘–ÏGY/HÅjg=ÆB‰½Å³a¦ˆª ã¨ÉĬ”zÞèDíÒ(¡ëÔ|%ó ªaŽÌ8<¢?K<‘»˜Å”Hô¨Ú–LœœJ‰í!ÙPízLÚÎà•ÖT0N‘¿óÆ\é¾åÇ3ŒÈå›g@îC‘ÛÃÌö°t…G­–>æ;iÆRØÇ#3¸ÈƒÐýËïnÚ´ò-Ó-gOߊFv/óh–ayŠnhd·ÈÕËT¥w7³]ä¶»þ`W;ªŽ35̬A*›´–Õ–Iˆ6Ç`…7e1,Óý” ӌٶ2b‰YN†Æ˜ÎQ SAùåFpíÒhÀ•žñö©$LûR#Ìx†bS©.©~ ä‰xÞ6iµõZÇAK9ªÍl·°U&ßÃ’õ¦@±õ5r6âl|yò×ÈUÉùú¾ræF^âmšùS2M±y€wùÔ.®ÎL6è´ø“¶'ÝÜ+¨ Mýœé\–7"/£L¢ýèÖÎú‡|4Ä»ô-Óýçß=²ü¸a{Ж²=ëÖMæ¼83cZê¿:˹9Ôú†?oÄ<¦ßks™ë½™¢¹‹—/çjçtÁ¬b…öÅ&ÛIéUL§BÌûü¥­Y#ç*“I´¼gÍ(s= vyù(«LiÑ:òvlƘ%ÜÅã™Åb?Xd¥î(s5guˆuª7 Yxn.Æ*¶³^&ï¿›å§\(s][¶š6hf6(Ú_òÖ*æH‘%ìéhÞÈ®ÙzFGÊÚpÈ!ñÁ%u„™4MXy)Lj·u\­ã`†‘ÕE+ä2ípŒé] HldwŠñ <¾Bí¬oÐæHæU¾ng½‰쪙ú(ÂfÖyÞ&­îë·h¹È“y¶y­‡%Œì^ài;ë÷¹æ+ÄOž^Ì1Œ Lbd :©XÕì›y$›´^äÉm̯Òaya¦Ÿ…N>ïgaöǼ±M³=Àn–Å%F{ù, ƒÞÈu.èë´¿Í>¿ÈmX%|Ê»¢7Ë›}W¯”}¿n–û¸[àÆ&­"$µÁc$ã”îÐÔÉç~´Ç¼±GÃ< ìYW–èyÌ:¤hn+ 5ÙrŒi+“§qˆò>õÁŒ5Êe;ÞB%F]X”dôoeSç*g„îEÖi_d Ä¨Ö*»4.rŽz™Ï”<ç�ëÅ©X6vH¹ú©'‘"F~"ÕØzêe>ÚƒÑ<L‡a‘⣬.V2}Õ ù^5â±­‘+‘*£xë”÷`VØ®§uôl—«èÐÖÄÎÀÆÔȳX§}ˆ;Zâ:nÙ¡ÉuÍq·þl›´*ôÑ·ÛÅ=¶ýá4cŽ¨Û¢e›fW@{enäEH±8† Ioéy‡Ô:¼ Ë8צeºM©(pcƒ61ÇS.¸jK©šè¦Ûz¬)ŸL±”õï÷•:Iíó˜cú ›ùM•œã}1G•\'•—ùÝ0³ÖY1öSw¯ ¡*(A§´”êTÅzö¤çù¾zèM2¡³_ó ¬Òáà­‘]ÝåþF o3Û%òxÒ€ÍFv{™w7`7ôKâ†>Š™:e©ð{4ÔqP%÷˜7 ܨ’Û§þe�ºï‘J¾@¿¬B²EªäŒjô9&L õf)pÃ#QádT +°Þ}§˜U©K<ô¬Ú0D{›f!ïG|¸Lw' §®ðN-‡CÜñ×Öêüö©Ï\O9Ow|Á*–-¾p›-p+ã—_ n^RÃj²Îᑸ2CQc2Ç Ü½Ì�>WbjYeØë”pêÙÿ׸’çÞåxýèL&œÃšlVãÀŒÓVîg±1"Rc‚S"ñ1øý—•çD$ î6hÛ¥QɪQÁ?®ã`Ÿúê\­ZÙœgÀZ¸Ù·àEÞUÌ?~8:²&¹ŒÚ+sÞ®E™ÏÂ*Ña[#'C$§Øø%]tÛØê³¼G9â¾õßH¶÷uyC“ß�FæÁ¹mòˆšªÔžCµ¯t²äŽI&‚ðfi÷s0#Œhg]¿«mšg–Sð„‹ÂÜÈî’hÐÁªgc‚I�R4ó”KŒPç…{Ìv,ZíÑ0Ëp˜Œt°ZfÈ¡xZxºGƒÁÊv ¸³ —µiü%oé ![nnzÙäŒüß &?æ+Ÿ'°™íuÚ7hSöK–æ¼Lwf¢xÛëµK£»˜€yo-Tú¸k{9ThîQ.óÈ�šmš7h»LÕ�62¹t0vi QÍ9Ìza*–$%+’Ó‚Œ¶wLgx.§êˆgK5En«ð”'¡¯¿GCJPLHi$cM<?#+VSr‡û#å**JŒÊÑHß+)Zg3ï±ÆS¤›Ý˜=:ù\sÉ{Æ$º÷¶7Üq÷³Pbtœ©f´ðq™îäs»pûÔû_3ßL09Δë~'•iÆÆ™šc°»dÞ¦þA.ƒªX£Ù‡(¯ÐeóGÈÒÃ’k™K¿ô‘ß ‹ 8f÷€_åëꩨÉãK3ã�� �IDAT@ú 5³í0LpÙÈî%j…°L÷m¤‹ì=‡Ô¶²y—¾º ÍÊââX¡Ë2ã!Õ³/ñ]ž¡wµó¡mš/òD \¢Ã°MQ‚VnòòÜ[¢'jÀ3‘Æ9ŸÛ‰ ­<þÌjq˜ÔÃ’ä=/œ¬âØ.b'ó§q¶vXzšXxZØZ¢G.¥!dú¾«”ò3Šç$L…˜l—Fkü #Ÿð^0wÔªPÍ‹à£(2«ðN¤vÝçZ [ÞcSŒë/v\㊨Ý3™ÆBú.j/;&Œe$I“8¯[?¸Çi_Á÷ß?\Ò½Š Qð(‰±?• Tõö\a0øœàPú‚ÙkæNŽ[NÀŸŒy$µ|¾?Ô£áÔ¿žáö೓Ö–ÖMAROÝÜ#B"œßz™×Ò-ÔOÏM«¸a›×žrÁœ ½ãÒI¸Åo›×ªäàëüæzý1è®r¾‘Y$Aìá¡î_õŽó™nº¹¹jÁAî{–ûc‰$³¦ Ÿx%Dž¨0;wc”RbTç@¥Ö¾µzgm�ÉœÍ?ŒH—p,lbg–aç+žèUà*1Ö¥¾»:=T?lhÚØ°Di宯ÖWSÅì_—éþ˜sI¿y úd©XÈý,ªþ^ÚB®q¥Â›©A¢×4nªËT=ìð4Ä$Сþñ6H#ä>*Š™�1°Œãn^¦êóÝLD´±çJç{UûX,¥±Î,2àëëP¶Šn}ŸIéùã?ÛãŸð ¢ ¡œ[´œjNÉÄ8Ê›>c™?›c5²›íYŽÆDMŠ·<³®š0€ÏÌTŽ�™i¿k\‘›)¼3$ÞYBpñ£Ix†ïÅšÔÔJFœÿ-Я۩èJ:µöqËt¹m˜¬ ¿n`Bu±"´rþ” ³ »[×ÇbPæºà Äh…ÎÕ%zF˜±EæÁ}Ê»zß••ÓQàÆ>õó ºYF³úYpB㢿L·}“Ö2×å|¯Ð5ÂŒ†~„fêÙWYå’j¯L—< >L4Œª‹• HPŒ%/N ŽøÎodi;çaƸa]¢è–’hîva™n½£´ñçMì¸EPq¬P¡³ SâTª%z –¨OFÝkioÖâ7¼b/ñ.}%ò¾¯C²=.òÄ@–.Vœ)~ÈGƒÌ¹©L[ ôq·Èm‰:óú.Ö˜]Ø¥Ñ<- á0³Ò™ëaIk…½LêáYro1Çà"ºÜîÒ| ÛÅ=,Y®CÕ=Á$îl¹j&œw—7p‘Ûí¬¹mž¤ûé¤Ósþøac¬¿z¿=ÙŒœ»JpÏép,w.En¸•–"7Ý”ý#pŠç³Ž2v/”È)bû¾ÙLêÑ^sŠòœëü•Sxñ Â,ªá öánÒ#W©½!ÊEn~ÈG¸ÒÉçi†Vì¯EZa·K£›âØ;kû»“„¶ødÁyfQîãfÙ«öoÀÇa²@æ…:ĈG‘¿Gbï$ š¿e×3â??£žî¦§ó0ü\nò§oó…¸ÇcˆÏ5ÏÀ..Ð?ÎT•œxH )õƒÊFñ×#È*Ìüà‹ èŸÚ«÷³ R\EæwÞËg‹\ @–§¬ýRèÄ‘À/^ºõóïJÙ‰ºU"ï«Åå ùH ŽC=åñ/ݦYš†×”,�6 —õ¿gªB§o”ÒÍý‰3ÔÀdA$YŠÈlsMPSá>ô‰vû©Q½Û¦˜wrœX`1çý<øLåyåܾýÂXüG .)eó¾:J®hº`“lR?ÀÌ($ÜšKEõJC¶Båš§$0£·‘@ž¹¹KML•€‰KÓ£ˆŠOÇ`g»\!»2m¬Ù=³O«3[Kïñ‰žo ì}ć«t¹~á­l^⡼‰ø¶Ë �.ð4Þ¬“Ê2Ýkäœp<æ ;„ŽÜejuò@ÿÓAæf®Å<µ‹•ZþÆ¿ê,'ÝÀM·¸ÊÐ,õdEnËÏîå3y ½ÌÖåÆ|Ü,Ãâ o3«‚® 9mЬvEnÃ+ƒÌu³ÜËg¾¸¸j†‘»ô-ÐßͲô9§JKô¼Éƒafý€žd)yF5úë~5šØñ46±³Oýƒ:’(Ing]NÁ0³Á­Sê"_ÇߎI&z™ÿ íX¶°¥£¼ç\ã(KEn*rêf9O9(0õì¯Ò!RTä…uéÀÉWnÜÅÊw´×ò2‰Zj9´\µ³>ÅxX®ÓÞÆ†�q˜Y§_i¿T¶…-Ybâà£Jö“‡©�™LIæYÕÐÝi™½¯´D)pÃVPè̼¦1ßMŠóQÖ›y‘9Bæ"õ#½~Y,H5Å1þP_øžÊø ”0&ªá×nK0Z‹e†Tn Ï‹Üt* ÷= –¬Q†åÍ–¸a„ÑÅJOÞ‚5§ìtÏÔÖý9·¢þõÛÌŠm‚ÉKüöÞ+sÝÌøèbõòÙeªZ义ޣaœ)7§1“ŸbÜ­qSŒKAìaÉî\t{tÇhcc›WüW—Âaf‡¸ÓÆF…w,„En÷³ ›x=ûnÿƒ„fs„™q¦\zj9Ôdv–aûr¢™úÝV;Z _%ÓyÊšF]o`o‡&wßÞÔÝCNÝmzÉ4±œè§ÐÂÖmö ûY°y5ÌlƒÌõ³ÐÁêeªº)Z vhê¤bØ£øLû(e¼BO¶yxþ QÔ­£Â;oò BaÌɰÝ-¹-63-üžÕ}ê çìaIª7P¤ 3aø!ù˜cÐqØH[“E&˜ÔÆ·…­<euWò0õ¸’È'NÝ¡ÉÍ\˜`'¶²©íò&­–C“P‚ˆ¡6+¡[=$eýØÖVŒ¬H#e¬qÅi¢÷À-4K¸È"7/S Îy‘øAW,5:Q“žó‰8:5¾ —&2ïsôÐŽI8aƒ[ €•šYD‹ïd„ã}SVèRJìë§Ñ�Ö¶Ä5ã¸XF]b+å?YçÎàõv|yH<sƒÌKRoaË^nž{’ÍLèX¡K„=À¼£g6Tl¼¬¶ÔIF7Ë9ª.¸-lÍ3à"(kaë+tîÐ4Èv‚‡Ô>暨 º¹›k‰Ñö‚Ü’ßçZ ±*9_ÙÅÝ#¹Æ}ûŸ¶žó†­!­‰^ªºü}Åë½ÌKš°_:Ä^æMÆ: ®Äh'ŸÛ—³édd°¾y"WUbÞm‰ífùe±»ñ×<PhYÕ Â_Œ“cŸi­ÒO¥s;ë ôÿ{þÌŒãI&:Xd®“Šuwˆr«pÔÁj3Ûò‘}~Ï€2£gÈ”à׸¯~9°‘ç§…­9;ù\R¥­?Ïã4àe~Wæºc¼!îøEs„éçŠ2#ò•{Xêe~Á±˜©‡%ÉA:vRqo±Æ•MZ;yà±i:ìP*"ÜÌaÑÚqŸú£‹\•øî}â5Õ{××q¬¨¼,ó8ÇX?ìŠå]•¹+Õ¸ºY$B¥+œŠô“ÁGšMˆx"‹Äª£¡mê¦qj|¥UnÒÊ;JcïÈÞôèyɰow2×±æ$)±&]¸OF!Ÿ•Ç)gyΜíY!ìã)ÁÙ¤Õ€ ¿v‰ÔÎ6hsJ4͘Lt3JJŒ6±S%'Ó˜b\½§žë±¡Y¦û'˜,p£“—xØË|/ŸT!Ïm—ÆNèño[&¯q¿=}Z-f=, ãz™w…U@jIPЪì‡|䜋–!Ik(Ií–}Ì’Êt�ò×{ù,VÌV6Õ ¸‘²¡×ÈîmïñI;L‚¢,b³ah{3ZjŠÕfÞ¦Y‡ÜðæâÎ�ó~–7¤ÈûâUrbÖ‹<Qº4À¼hc‘«L–ýé?ðÓÿæÁŒçâî$Ì<0ÙËm‡Í>ª==s°mòµ<ÌbENƒÌéÁQäv…w¾àmí-ºYÛ#ݦYL|‰‡b £Î6hÛæµV+¼éeÒ7‹Œú?Çàã¯óU{¦´,rµ‘]‰ì:ˆnݯX'˜ôƺyÛíŒZ5È¸í¬¸•¶‚Î1Öyñþûÿ}ŠÒA} œ2’ÅŒ7q%:„±˜¨™Sóû}#Un‘ñ,žy;%ÌõSå­&£ô<rê+U$£ã_XT]s5zžgø‘ rÒ«Üj„aÄ«|ý¯ §Üì»ÎN2q‘'SŒm=hÒ êÙïå³"7eš 3»DOæý-Ûtïñ‰Œ†2׿åÇöÇ‚ïàÈgŒiŸ,]»‡¥ <µQÎa„á s‘`g‹=ÏQ›½‹Ø ª$".Ó]¤ð2¿“ŸK¹‡!Ã(xNPH’´$µRëЙ7TJIªEó¯&dÁ³1Ìì,ÃVw rðüFP}|¿žA¢é`ÕùŸñ«?Èǯùåÿ_§½ÌP…7%Í{êÆ™ÒnÃ*ò*_(ð(Ù¡—Ï‚¬á le3GµJÎ]‚ìŒ`aH!ÞâË/yK>'åR<ç¬+eR„¨@Vá{|ò˜KµRÊ ïHÁ Sõy0¯óÕ5î§Š…ìÌ\_dÀ+2Á¤OðR†!(<R„’ÀsƈyñOW¬øsZœÒJæš]ÚC~²8ê“qÀ5©0(Ê•+¦ô­dU=zîHNTĤü=_h³·HŸ™¾àÙ¥ ÆV@‹j×Yå/’\ûåHE³BXxzùÌNoŒô/vÁú¿úˆ¥J,´`¸LΛgà.}J¾‚Á9 »f¥Tx:Ù˜ªO’×Å}´¬?ÿâ$$"CSeI‹ì`gEZ4ÒV[ðÜ,ÉAù{¯ •:ÙÌTÊæü€!_M×>WØXÓ]µ]Žmˆ…6TEq:ao`ï]>µHôqWéÛ+|ó‡üÃ?ð‡ŸðžŸ%.:2NÖo­“JˆQ7&/ÑJF¢ó54±À{†ågšÿ¢Q½5ÒRá¯í+-·=,Y¨¬»)ùÓ)lpPý­ùÈ[ÎóÅý–OóZûW™«©æÌëk##-Ÿ—NÅúG3ˆcðÊ­b•Òöâêr´âXh•qù޾¯I¥´ëHGŒ2C'ËÕ3ÇhK¦?ÉîÔ£L¦^s’Çx¬7ä¤ÇsGr/d^¸€®Ð%ý×ä&™¨ðŽ¿°@ÿ$²Ú$qù°-Õe….÷àVŽ_ñ3¹aÚã†ã­3Û_-l¹ö2ÿ-?6RDÞœU;õì×q Ù¡Bg4'5qæ•éÑÑrÊ¥“l1ÝÙõÈðƒè/®o·¯)KbŠqËUW+™N² L¼´seIÛ¤õ+^ÌÔ›^¦ªÓ]‰ÑFŠ.ñ0Ž_SÇ]´ 27ÉÄ“.âTrT¥fhkÚ5SÊ<*C/­Öð—¼å’]¡SÏŽÿȿɃOyWg]ÏÍ‘¤`ÍósÙ{L}§l~Ê 72û [¯zˆ­Ýµ„z÷Ú‰mÑ"ùPd³EK[ÚÔj‰ëùì`u‰žmšØsÖØÀ^½|æ~År [¾Î.¿âgB7c·ÂÕWáYܶY9—©Î1¨ƒÉÓ._yè6b<Å)íéùã‡5ÇJFñ׃OSú¤ív,J}rOmF‚¼Ç3ÎaMÄ_Eò$­Ë#\RFF)†Y×QfHx¬/N)Az ¿ŒX¯“ØÑsƒ´³Ó<^Müλ`™dapÆ*µ†zf•‡\j›Ù®ãÀéTìÊ5’Π?a+ÁÑÐRÏ<þñ‹­lnóÚ5î÷2?Ç cŒ9SNÄ“¦~}QnÞw ô¥"É©õ—ùݹwùT7ØAæ|GÃŽ­ Î]t24Ï·Ž-k垕ʹ³.™Í¾ÖÓ³ ;®—w§›â&­1t‚â¬HëôY†—è©ðŽàÉ¥‰žÿ=tElÓUèÔ?é€:˘Ç6Ád3ÛR3ÖÈ3%²ôEšØñêìÑPËá.O¸¨ ¯AÀ³ [³-™23Í7¹ÀSýdm?jîn܉4ý<¥eºUìÒèŽa›f­ž š‰½‚·„çÍ�3·}Ü 9Áeù„-Z´14XRÙ¸Ü!Ê „Kähg½D^f–Œî?¼ÖÈùÑäÝè–i[ä§· &¹L$ã^Ë>r8pž?~ —þÓÃùp^—³NÝe­Q³–�)Ûú…g?¬áØýB¸[)gpg-Auk!¢‹ÛÁþˆƒpп¢ÇÚ驌odÃð¨œtÃ,ãäûžå±j·Ý@lé1͘ò[»^’î<áÃÌîФ-¬ž§"Ȫö©DN1oÐ ÇUÀT\·ÃÂÞèF1ÈÜwì†{…k¢™ ô»úD¹uŸîë¸5qÈá\ÄÛæSÞ•PLô Pº9±—Ei¿Zª/q³pL>"zÎíEŠÖ’õM2±B×0³xêX¥…­Y†E- ôKз׊é´ej¾Ô*N•\d‡9ÒÓÏ)Âüƒ®µ@´y±ÞåS`„©4Ñsëg¡–Ú,Qþ¢X¶›eQ¯˜8úu*çJ4›=ïm*šÖ_Êz0É„M</„£P{­:·hÑ¡Q[Hë¨�q†û¥ÑüüŠ×½â‹\¦Ë'Ës±÷f`2)òÜ Ž{4'íLÚñ“kñs³L·ªÁt[óŒÒ|>ÊúAb,ÕK >áiQ#v3Aññ3½Å3ÂÞ‘Qi¢«ð ‡¥à,R¬ÄOÒ‡N62ëŠ^A ´OèHÌ#ÑäJ’·NÇ+ŸÙ‡_Ë0qÛŒO›c°½yfÞ§¾™mÍ�È[®¤iEâŸNìÆº¶Kc¶‡­1Çd†N*®Å©äËk*W–8ëÖ8SÝ,»¡‘ð 3›çÞ$Fý # ×PR$kªÂ)ÛMÝ,+EÒ~×'øÃfú¸[á_g‹–66 Šôs™²O½Áöª¾Æ˜–µÿ5¯ÅklŠ„é�9ªz¨«ˆ2bQúß=vÕºYþå õ2/1r‰«l/ó.ë|ns‰QÁST²iÆÚØø„÷¼LÞie³Ä¨„ºê.ñ0GU;ÚiÆôèJo�Í™"°¸“ÊeÕ³_ázöÛØhfÛüÌ(ió L2öíQÕö©·Û6Ÿ®WþS/óáp¡x‡¦afƒ[è‰õ~ðþtoäÉ? NјåŠÄg²Ìu_Y8å¬!îX‹wclúKId.Z>çD­tÅ’3–çÙ¢lš'ëM[Ia8æµ»›#ËIʼyòêÉ}²m=ÙÜ‘˜Æ|ËÊÃA¸ÔãT2¿îñgFy ¹i)ßW«ÎÜéi·\ 3ëI f°ÐGqYÅí¬›º«…y;%Fïsmˆ;Ú–Ça¦­Ûbf-Úc K-Ó"œÿû[â6ÉÖB1 `Ñ6i`rŠñ:ŠÜ´Ix—¾!îlÐV¤0Á¤ÝH¦ÕMZ i4!ňwAF,s1Ùje³Â›ë´÷°dæÅ sUr<hbÇ>Ò=ë´»Ôº¯rLb˜\|õìÛŽÓB@¦rËvC”‡(ç¹w@݃ºè ÿçÿ(ªų.Sƒß M|pÄw¦“”íbE³¾Pz5±ó˜7*tšˆf™¡í»|j«³À çRs ÅœßöôÖZ§}‚Éf< ¶¼»örTË\w@¢ph§Øa’ìÍÝ ØYUóà‚c©“Æ©îMt«#†'G“@­pVéPº§eÒ.å·ü¸‡%û·aí›ÚÉä´rôüñƒx|?WP‡À ¦Tõ.V䵟lÇ¢ª=Çâ +÷cf¼› úœ*‰«á±Ñ¸E(1†vT’”40Löi):J9„‰¡ûß=ÚyS¹¥K†ý"»X2}½èöO Üú–YïvZ,rÁ0&³Û B¹M˜èÌÈ‚ «u2O÷tUJ™ënH�Ê€ÌzNᄤ/™lÙ5ó›@lÁ Œ~Q§>îÍl;~—ÿÖÎz'• T¦×Ïç¸ð¹Ê’ðà Iýƒ€Lž™ yèÂÌ>ÐIèR·õ gÇç³êñK…ߣAf£|<%ÌÚ‡(§ô} ¨t’î‚ga«­–C_'È„áT¯SÇö󺆽}8ÒÊîóùÙS‹—ÀÖq,á:è}èd«Kü¶D>½ôš@žâʇzÁeá>×lÉz!¦ #A‡£^#ƒ^h™"7CºsrrþøÏðø'ÙíïgfûßË#'ÓB]O‹P³²H*ÂNðT°HT”Ltªf< (±pjXyê9§,ÞÓ·QWJpç4þæsj[gÉuG740"fNQ¥œ…eª J°®×È=æI Í“Ït*ЇduÇOÊt±ò!½Éƒ2ÉžˆM¡ ¹ûOJ»ô¶èg!hú±8Z \1}©p}õ0”6Æ`ìÖ•?²–8É~@kŽˆôX’‰g¸†YÃδRR¾v®¾{”7?K”ðŠUæì$2�‡{‘wùT¶}P £Öú} ¡UìT2£ú;Ââ"·½:ž.Ï­s)'yVâ°÷Mý‘ýÈA‚jÔÃÒËü.}åÐáycÄñ[¢D…ýnübPó=~?»dúˆƒ‰Ý­''F"LÇ7J¯Z²;?ü *Ö÷§<·¨n(Eo0ëE˜VÖ ;î&‡í…ã1Zaž”Zcœ ¯ºLµÀ­.VRÀ$£ä˜�’50­p7eú´ðLÜŸ'YÈçž]ûøò»”‹:/pÃ.;tÇ�føêÍ+­1qï/c¢‘ÝUQ!íڢŦS%»gÁ¡7ÐD ï#®ÈŠ–m’¡í .VfqúÕÌöwÄ7=,éÈ•Õ, W1ã—:Xg Ÿ)†þü¥²¥ÈÇc‡Ób¹DeIndZQФÚ7±SàF;ë+t Q–k@¬MZëÙߠ͘c‰ˆ€ìÊúßã“Fv£“)Ë1G5R†#™÷2Uƒ1¥Òýü¥²çù?òÇ«tDÖ‘«À ËR ¤»YÖÆ"¦˜%F¥34°gt:æ`ÞŽ¨žþоn™ëž4ù,£­”Ç\&/°Ž«c,§ÇZ7¹!dΨh}…®N>·É¼N»-Y_Jn¡å*×1 ïfy˜Yƒ¶U]<´Ü•#åü,{¾0]Á“`…Lu{27„“¾ÏtÁ¿B0˜ØR|O|ID<‡ŠNå1FŒä©¦b*O>Ñ™,‘Ïô^œùtÇÝÚ€Mi0n /¢““™>ÜÐ ÷y ªö½ÌoóZ°ÎÖÈmóšYˆ&•¨NõRény(é=õ², [@Íl_äÉ]úBaš¤Oßl®¿§°T�8wÜ[´ÜçZbÀDŒPFG;?K[‹\ÜD6`NF·ÐÖS`»Uáæ@füe;b µ¯ ?µ¿â0O‹Ÿ"DG÷L\k§N„aÛ0í@ àüƒS¨à|¦NŒ@Ÿ!ªdÖÚ=¶‰Èʰ®ˆ&¤m[Írâ·8Ú‰i,H 1²È8<;Yj«ú߃¦a¤6½i#¨Å¾¢YÌ6‡g‡%i²Pœ#­(Æ:•²ø(›@ FƳûÌ:iÙŒ½dSØÖ“£þÄM¹ædy&ÎXÇ!™uÅ£LÎd¿µ‰&¬&µ<UM9Ž˜;U¨jÎGY±÷ÔM<O¹ƒU;zž ,ZÙ´OÕÀ^‰Ñ`±ïSåj…®ËT›Ø)r»J."HòÜkæ7>ÁHyÉþçÂÝÏ‚+»Õ«MZP"fN‡Ôpßn›æ»ôíÒ¨}\´ãÚYwúåÁÊyðd6N>g91“½ÊvÖ{™w­ô`šùFƒùm^ÑE·‹•£Û¼ö/ Z…,¦–L3&u"¼6´„wu]–}[ u ;@êå3ÁÖ s ô»ô›Æâ;Ê€pêÖÊf™¡9½X©ŠHÑB+—xèéÕNBëwa‚I›áËÕʦÊå´\Idˆ8ÄN*bDqä6¯\¦ª&×¾Gƒ·`ì‹r7-êÿ0Å˧émL1è÷x­}›í¬K/4Ó飰LÂ…À7GÕ1•—»ÌõiÆö©ïäsIËt[®<Õ»4:RMNày­ú=þÑ®`L8Ì©JmÑ31o5z7/›»5re®ÃQšu$é9ß¿£DÕ¨î™ùzÚŽN¦ODRY3žq{NÜj%òÙEòQòß|ÔÄœRR¯nâŠv¶hQÆdáqýuÁmcÃÐÛ-Z¬Cs ºd¯‘Kç11^zÌ®Îù£~DÖ¢ÈÉ'[BÈB\@í ºæº}ŽÑ…o$>s­±rØ‹Û2ÚŒM앲K£:$AÆ>õ¾‹XÓå:í—y4ÂŒ|ŸkvJ)Æÿö»†q¦LÒÚ£a“ÖuÚ3oˆœà@L"nØÚŠì`ñ“‹¯šëö¶yEt8Ç`;ëL¸Çè:íUr9ªEnzðžÕ8½@;Úõ’åöRë«5²;ÄÛ­ž%OxL¼þöÞ/$Ò<O÷|4»ìöéÈuÇ ·'‘<ô:}¡]I”ˆU+ K+&äXc"+-':vÑ‹¦³ÐÄ‘%N"“J }¡1‚¤³PNAŠöMãT‰XH’ÕÊ¡ÇmN®›§Wví•|{zö4Ì^|â÷Ä7š=WS™‹E’e†oÄû¾ß?Ï÷ù>Î9AcÚàìLk _1”û©ºu2®u=(k$õkÿþÈ—¯—M8H¤ |^`|Å“i†œËÚ·4nÆf^XÐ�� �IDAT›.ébɬ|±|¥Ð#;uöLTÀ  ôûPy�L»ñ.Kš:M¤â«^²7w'c5Ê kR0Ž2B¸ïQžîÀ{QW_.ø`5ä”Òpk3‘;â`©YG#ç˳4~b¼ct¶ÄTj°”rm_\ÒºöeT½vŒí¡üž©sESwôêDÝÖùFªGÒ Ý#@sf±^ìUí\=¢ö'‚ÞtôB÷\·igH;÷ôâçúC²ªJ‘Çßià„ ò@pa­˜ÆîDݧê"Rã ¯“9¨ý‘Nø¹~�³¹](ŽkÅxóG*°_Eö^#µ,h–HWS~^eZLT*~¯o¾Öm$¬ JóuU5й I÷Rm,_[<q´ƒÔ9¿ž«£K_ÂøDuétZK¸F±N@Gr©¶1mìhhO»dD„) {r¸¾Ð=¼µºur¡öªF/ÕF×Â1päŒaäkÙ 2ú¡ò·ôfR«  CÚ†̈OØ‚f‰uét@{'êžÕÂßèÏŽTèÒ)ÞG*ôè%2ñ½b;bBkóšq‘Á —?,÷/0¬õæG´>¨Ý%M—´Ì^ÙN Vs½œ1”*W¶tf¿`jÞ2øH[=7w4cåLjHbH Ôðð" /õ[ÿþ‰ÖÍÆTõ=ªAí:Ó4Sø¼¸—¥·ë+ªbë²]Hf¢ùk¦~”ŒÚÚ8ü“®¹ŽGŒ>û€A–‚ª@øþDÁJ¿§d”ŠŠ^g9T-‹G[°#Õ®‹ÍVUb÷M—ßÒïrßýT"±x<GðBÇï}äuS�èfNÕu¦NX$t¦Ò8ÞÕ/‘Ú€bD(D“‡ x Ý̉º‹ªNi…º»Wµu/iše)²Â¹:¾©ß#aE–Ô.ÀÝ–Æ_éêæd\ÛŽèÓUMnhlP»]:¦›Õ™:êÙ½ÒÊU?ú úWÿ}éWúî†ÆÞ×̇ËØÕàºÆYÂÈŠmå] véKü-×4±§ûU’ƒBäD›Ñ`'‘ ­á0‰rÕ¶†¬Ÿµ‰H#Tí,u¨<ŽV^ÆbÔ7 çãZçD hBÄ™:!JÜÑ«-cƒì$Åå¹:̆Àq‘sçU*ÎéˆÖ·5Ì>–“ÎX-rþ –³¸&¥Ê8çÔÅß©Ã0c©´Ù¸üÆ%ë]e^üO?)4¯=e¬ÓÇÙf3aý+$ÕÝ]%”öy_” J4ú¾ø:-ë\þÞ¢(Ÿ5oƒµò¶›Y$-¤Ák=Êr[ìM5Ä2 �ÚŽÁs~¯³Ð͘ù‡ç‘ �°®¬ùÿêÎ%ýÝo?dnb½á²hPBÑÍáEuëñh#£õ=}Èš‘EÐ-¾Nˆ¼£Wwõ¹ýq¼^VTõ ½oõôÈ䯸‡å»úü¥>˜Ò Üî«»GÄDtC ;(©áˆÇ•&xñ'š‘~+=×_ý¦ˆ÷ GRUéTßÙÓ€—·ÐŒ‡ÛíéYŠ\þÉô¾Ã6]è3ó"ß„£m9ôUÉâg’…W£|ϾÔ÷è½¼Å7p¡ö’ª6µaé3"ÃæGX‘=.(-0jŠ;p\c)¶4âLŒ*Tf-:–çã@aºvCmÿÿó"Ú-RŒ 4åO‚>SÃÕ7z<†LÅ:%ˆ¾gj¹0ØÜÀ5I¯HYDôˆÏ™Ì>#jÒ’o‚¤­8uÍAj”/¬Áo¡aÜf×4^@¿ý ôÝ:ÙÒxIË& 3RÆÙÒø˜6Œ ¢Û4¯™.Žiã÷úföÛo}ùÛï]ª™Ö™:®ðL/S8_¨}DëCÚ± †§,˜ù.hvM�G0ÔOÕ忝¬¹=¿«ÏÉ| ]eÍ£„Dæ›Ò …ÿ‚fi‰ìé“%M#ïtO/né ÏÇÝñTïñ.{ºÿF·hS<6;Q÷c=-®uDw˜ƒÖökÝF»ˆVUTU?¨Óþö7ºtŠÏ/ýÇ–0¡YÒ4R÷ßÔï!Ž›ÜQTµCç/tÜy[¯­;Œ">ÌîAú³%MŸª« #w„G*liœ—¿«´.y[¯ÏÔÉSÖbY‹½:XÕäš&P.js^Oü H‡ACc. ` B¤O¶}Íí4¬çes‡Ê£ƒ ÿ&)¤+»ÎªªQað`Üž³ù€g HlK±.¦ß<ÞÁ9–œ�¸8ÐÝòv0”°‡lU¬$KȯçÂT)WUéªCšS÷jTcŠsû”2ëh!ú‡nø’\áA˜xQt×û°Aí²WÑ’ÕH}MùAq?ëU­¬¹‚Žöô!Ro`ÃôÉ*k‘ –òÁ"QlDë°»u2 =�+ôú˜^PÏja_ý5å?ÖOA™ÐÒÀã+ÞeA³Ì6XŒOc*VŽªx„K―¤MûíjpO÷°9}[OÔ.è(¯t�F/ŒIztÌ|Žü'i[ÃØÞ“ÀFôé¸ÖašœªëRmôLp¦µ4­¥×ºM»¶§û$àcõìéþ™:ÍL¹¥7V»@øLUõ¿([øÖþ¡‚­s—NÕGž#úÃrDœðú>=‹JgêüBïÓÉ4¯u›·kÓ%‚°ö >Q7„ÆŸëJÔJ¦z|]=:F“ “‹î§–î#&‚to¼#­ùµSg½ª¹%õæõ‘ +šBÇϵ­³µ6àU*mk¥«“)Ç@Xž Õp½P.kåø08¯µIˆ¨ªäÊÕã¸Zq9ýæñΡ‚?ùÉOâÕdO-‹P©Ö‹Å¦e©fCÏŒNDá -/BÛµš"¦çFÞ®¬9©956ö±R –¿A››­V)° ÏlêjX –6À”%0¬¥ nFv¹£Wö¶”‘ÕÀ Œò]ª-¯Bv «K9x‡  Í?÷‚ȇö¿îrG¯¶5ÌÁ( 1�÷E-pâ8ʶL|¨g–®ˆK¨`wâà-½¡ú^Zˆ™‘RËt4¬m„…¼ÆÄçBí¿‚Ý¥Wn�I#–ÖFbÐ’í.Þ£(ûÄÏýpB>È›qÑØÓÞ‰;²§ pJêþ¾„Ø7çÓqåx…Ë2%œ\Åþ¤ˆqpI2I†D›–Yâ«V³ÂœC®ófqµŒZfWâÉÍãÝ@›Á¬eðØ«š-ûôNWn˜)\€NäWŠÚLÝÛA$µÃ†˜^]·‚_L˜U¾9Çä`Ï'+“¬W ‰>ˆ]i«*e©Ë]Å ¯ù#¨zU£ÐF+#®gÉ:lØ0xgÂïJ™(³¤éUM>ÕcÀâøÒ÷õ Ìœ”ôkÊOhmDëø_”µxG¯è?ІÇ*‚ æ=;` @hdIËh¼z Hó2 ”#‚çaž¾^èž5 ÒGþ †§Ÿ=!>5fPãܽ:x£[®ÔꎆêYU£íº˜WyZKÐ( bö4€™HU%Æ„`§íºÓƘ6¬WB‰À´Ì€ç v£?a[�ú v4[UqP»4v4²Àªt–ÀqèüB‘¨jÓ2ïc±Á6¬mÚ~^Ö\U£eÍÓ¤"ÀOÇE ëPjÓ3$Ÿ\iœ\®1ƒÙ„ªMûŒÍ˜`eý†&a9tÝ{u�ºPTÅ&EUÊZd£Æ{=rJ»¿xçPA 3»¤Ÿ4&IÔ_Pòš-‰óÑ¡Ñ;pð„Ö|¾™„‘·,òtEù"G“ºõ\ Ķ©1H‹}½°… ØŒ7fjõ&¾¾Ø é‚y$,.hYë1mtéK¢MÆưòC#`@ÏѼŠ‚'ç,B)I ÑWñ÷[ú÷Þ<Ch¼¬Ext:·ˆ_·NöÕoO?]„TöFaëõkŸp¼¥ñ=}H î×>9ÕÌÈÓøð’Æ:u¶¢)Žv@ÏTЉ§K§=:~©H“e-rµ#QÁç%…OhmBk¿Öw4 ȇíÖ DÄ[z#iU“CÚyªÇ¿ÑŸà¯á=hòè®aúaÞÈD¿®ˆÆŠ¦,e¯]cGùôÉC=Ã=’íÛCÜØÓý1m éçæ¯Cçð3½`î.ÇTÌ%M¿Ñ-·ª|QÿH`–´ç ²ñˆa@Ïw5Ȧ=ø0Ô®"ç‹ûúDÝ=¢h¦ZµFÁ¼žp_ǹ”&6RNÔbZ}»ÃYYs½ªÙý«(Ð7· þë–^Û4›Ð$UÒ:T“ü¹UnÝP‡'4zöi]Þ HÐ=¸õm¯×6xŽ’ZnÄ g" ¯Hl ‘j5±¼nȺÌ'óLYŠ”âšŸóCªTP¯’–´‡¼ù~J6ZÖRbÇ@3Àe| ,øn$J¡ œJ«„r’Œ%Nh zÛ¤VÉs‘‚È{YÙÈRñ˜ß×t$]:Ðó=Ý·8,ê«zþý B¾ˆÝ’xSK=)1îøE+-Y—½…cizTäAÏ"ÓÏØò­WÄ—pG¯@ÿ¢<RÄâ"ŠF"_]—¾äƒð.Œß�Zgµ@!‚ “±Ö=ÝÐó(‡o'(qÔg²Z•ßÚŠºÑ=€sÑráqƒóv¤U šÉÉùfÆr#”ÁÌ7æ�Vvçw"‰],Ÿ…øp ¾s¨`Î1IóÜÈ(pÝã*N)±N 1]ŽQÁfW‘\špæ\ÝÄ­äô¿™[·p¹ä¬Š[Õ輞°ÎUÖ"O�¨DÀÉ­ƒ3¨šät3W[×ø’È™-ÆiÔêÐyYót$=’Ä+jž¢p³Zh×ÅkÝ6åÜp¬ž²'´vWŸwé´]wôj^Oîês'I­²T÷}ý‚FPîÒ)mºL"E[óófµpG¯jÊãʈñ[;ÃÚfLEˆìÐ9%ôŠÔnU£“Z…/÷+}E¨KµUôÛCƒœ·ô¦Wµôɽj×’_‘˜.¢AÐÉiV kš8U¡™t5 =àAI%-CÙ¸£W(¦CÇ“ë^z)†j+šbÁyZKƒÚ%nkæ$+P&Liç¶^÷këHfTxÌïhè™"mìá[q´A’öÕ¿¡±­ÄÐ ‚ |HZ.%ohIõl^3@¾óš!Ó¤û½^©³¤*B´Ð’±ÔŠF$¼éêH…CõAåUo–FME­uy…ªoO÷ùìðé2§µÄ‹°@­: yÓüÆ+ÅîÍã]ê±Z¶£BÒj|eÕZ’—W 6]=^a:y̲ÚÕ¦êªÉÈhxf«S—ÿ7¬ ªný5Ó²Ô\µ®m•ÅVؾdmûDUNÏaC&Jrš0ÓC&ïuI²˜¬í¯è*L:%͘®­$ôÎuća£~’ʰ¶;t^UÑe»í*8BïîØ9Þ¤G'lpÈ{zaª‚Krúï< hïµn[ –`G+c.ƒE]I?¦3´ìK¹ŠÚ“ZEžƒƒ<Q·÷ÌbºU°%# <ÖÓgzh¿’ ñ-s bëM;3J >²3wO/8¹œPÎŽ= M­WšìRæoL g׺“ˆ». FíºŒâ߯d:‚4ñ Í Ú£ÖÕ…ÒÂ+k€kÒ ÍžîsAB8rég.ÆƻļHÍ{ }ÉÕ^/DJ¤ö†ó:üˆ L‘‹&Å ‰n¨ùYÏ¿]íS²‰C¬úbD³ÈµLÚÜ&zE J½Å/¸CR_•sœŠÝƵ,£r†õ=`- Ú•·ÎÔI8žÐÚ·ô;ôFKªò‹óš!º1dBu” aÃ!:ÞeKã¼Úކ°Ö-k1Øè‰1ôz~RÐOØÐX¢ng~kt:ð¹à­!ŒÐ‹À³çØ$ÝÕçKš¶‘‘îûúí Ýãµ ÙšàKºb©ë©Ÿª‹¡gÓ­ _ ÒA'ê†fBÿÿ~^3ýÚ¡{¬…¡ ˜È˜6ØåZÕ$ߘËAæO– \Ðl¿öêÙš&,ÕXÐѸÖÑgZÓÄ¥ÚëiQ•1mLk饾Ǟݹ¼Gǯu›y$YØÂ:}6.Ìì?*ïI… ƒ=6¨è´P>WÃyÍ ®Ô¡ó=Ý·ÜŸ‡ß‡Ê'¶K¶«Aߪ,_ÆË#V·ý8€ªFËšsy]Ö"ñ„qݹ:È[ðw~£?ÙйÉVjsäìŠ1¹¿IWïó"Hí5 ‚È–\Ý .kñŠ¢‰ ã¹UO¤Ò͘ Rfj¼‘µËšKé°FMù fáßÊ ?†Ñh½Ç Ú¬6i!†l×z^Ë⌈0¨]Ÿ¯Ãv#Lli|H;UÎkfLçꨅY4ô3vž¶4¥‚=­NU¥T©ª*õè˜U-8~,&ÇIÒ„Ö¶4~Ko4{¦Î6]j—Kèž^­2Bœ© £¢6óÉN^±íùm ï2XÖâ'úˆe#“Ô?ÖOI<dŒ—64-ƒÏÕñRÐ,º :8«…q­ŸªkXÛóš7q¨üˆÖi/@V;t.åôYIË%-#úסó7ºÕ©3È,Ïô1bâ,|Ž¡GÇ%-CB™ÕÂkÝfÎñÏAÖB‚{(èˆâ`[óZ@PjXÛ|?ä¤ß![òjè£çUÃN¬W5Ò9]cIË?×´·«Ar-;mHJ²K‡¼¬)]Étª¶«Á’–a^˜LamÒÄwðø ^ï"_›DkÁ9¯Þ—³€L(èѱ™Dî&=q,k ≺«*‚*ŸTŒûÎÕà/göª’ÎÍãíg,KÓz\ÉvaU£#ú4ýSJ^TÅB&ë‹fÖ¿È ñÃ4dÊKZº½:Ž$‘¹×Ê^ïåügY´È,‹]¶ì‡¹wŒ"¼WmJ®S%悜,Þ?Ó¦G´>¬m¸¿PÔ¼#üRßÛÕ âëô;Ð’z=:®ªÈóW5YÖ܈Öw5x®Ži-•´¼¢)zÄaÕØjJ+ÄÖ ý7½KOPÕ(ZG éo"2¯Ý‹V´\3îh¨¢Gv»˜Ô*ïNo7©UæXü7¤v]`ñ…L0/ë•gøÜ%-#\Ñ£ !xýrM8}p‰–µ¸¥q§Rxçê yõ^ó¥Ú¶5LÐÞ…Úád°ÐóuhFzçŸë/‡´Ó¥S$6hn¯ÙS&Ok ±+pK¾Û6]"íñLYµÒäz¸¥7{ºÿRw_ëö véÉL"Ås„¥]:-n+A0(JƒðÍ n©i-•5çß»K¬®F€âƒóç´–(RùBؾP{’¨U5ʗ̅̈́ϲ„?rm£ßß«ª[[“ð†ãþ®Í±rQýtøÊÄHHZPÙB‚¦œEî_ü­hf¯¦Å½¯fûk5]yB\Un¼µÍå<‡ [ÃÿBóíÚ²âHRÍ«µ¦ù»Íjm:F2–ª#Ø1f�~q[`t‹…V8u’–4M(<V%ãÜô˜)gVˆßÑ>l ‘27'µ:¥•³J–í`" Ç¿¸êkW{3!=«³Û=°Õš&V4enTÀ=O³<æ–1̹•´}历XQb¤ç hsö¢N iåJ«»¸;šyµ9_4®hñ=ßSë‡uÉ~½šw“+zÄÏ¿ñúý3Yцô¦ïzDDbà®ôh$cP»aå?ÞòM �‰à^nñSgúhÆøÿ远Ԫeâp‹5gÏä<ñR2ÀäÉR`¿ˆë§U¢à;6ÇÊ«ªDAÁmãÙRÌÐ\ñ?¡›žd•Ö~£c&aMN% lŒ‰I˜ÃÜ$h*wm6c#ñ¸QˆÜWažµæ.í ØE^ÛÆ?£¤µ½,5B$7öª&Áñ°XĺR¯?pØbíºè×¾íBGÔîžî³™{¡v2Üc=%‹ î‡~?éÔHÂzÌ¥ÌgëÑñˆ>-i‹H˜„,Z¡KK`b)õ¡žMjuIÓÈëa¢¸§ûçê�UcÆÇûÐs¬¿¬K*¥‡›ÐïB¦á0ÊZDq¼¨Í6]–µ¸¥Zc3×kdôRj?Q÷¾ú·4Ž~U‡ÎåúµÏrä@ÔâKZ¶m#ߪÛAf~›ÖÒ™:ô·á¼f¨ùøŒ4eÍ¿j÷µnÓö¬Ç´Á2·Éš&¶ôÀ½ì€žOk žoNW|óq €Á] Zr7*ˆFòE”gãOKŸ›Yy.Nö œf—YÚ_ë‡:3l€Á vGôé™:ïè‡Äö1Þ+`¤ÌÌ(nP¾/kDÂoïÚ˧ºÞDÄèXðZ£ëâ–†¦Þ¹åïA¥©éQÖb8eU¢¯Á Oi/ïÑk³ Tu‚¡7%[\ªð<ÌðzRúè»ÆŒÁF"·l¶CÇê±/m§ÎîéG>HÒ]:­èaúBíPF´> Ïˆò`V%-SûU±üÛ­Ky@ET"Û±\\Òò´–ø'ÞzCcÇꩨèkrGChœCYæ0 èký®>·D=N€ÈÁŒ¨èÑ…Ú/Ô¾¡±I­ž¨4¯¢GJ¸:C{[Ô1`KC׆CÏD œ©‡z†Öߊ¦ …ó @xÈ_¸Òzò¼fƵ^ÐjLõÌ.‹€ZäHòÜHke-þF’P¹%ýÛk^3³Z¸«_"÷WÔæ¾úA}íóKUAÑ« .9iDë^®:RÁ;x`‡Îm?ÄÓ•·.;ð]'×E NÔpFÔé6%ÚMºÒ-=`…œâ‰†ØÆ³¤É] O¾£_“«¶4NÀ1 çkñþÞc)×–™õg,šÍ‚³fÿÆZ*É£hE“„DB?rØ’¦–Åå>Ó1\”ÍëIB·siý>§:W§¯¹Ìœ0 (sc«¤e³ó]¬¥ú®ÎÚ0ÔÜ{]ÏG.-¦ä(¨£}øc=Ñz¿ö§´RÔ&­ i©¬E‰˜ðˆà{úðPyŒÞ+zTÑ£=÷*+¥ªÔ ’ÖŽ†îè @œ­oh š’v]„èTMÇ] ™‰N‘xˆã;¼ª]Ñí}LÇ ÈšÛ^×8“- K¶ëé¼fØ»B\cZKàopR0{döFBb&Ô¥Óßé[KšÖö”Vˆ°4|´GÁÕi†Cb¸TÛžîj÷ž^ðI÷4`K*–|‰àwôêPy¾œ] "©Õ¯ýô‰Å øÓ/ž©³¢G š-ªb’ý¼fè>ÉRä!Ë^�uÒ'‘™èÓgã‡Þ'ñæ¥ÇÞºs{ò+x\)iž©SÊQ�íjûr¶}yþ¤VÛuÁì 1eŽgXÛò¡*ÂeÑ쮹xë^Õ`ÿ.˜VT<T߈>uiîÜyóxW2VîKk¹¹ÓuÕÎ#J%Ålh  \TþN¹�ª”Šš塪QPlfªÎånŒ<µ ªfÌÅVÓüÈÚ€<rEãú¢‚TÓV„CPx¦‡žTOjµ!tá`Ö4‹e-±’%STYÛu±¦‰-ƒ4ž«ã»úÕ‰º·ôà ½ÿS}Lš™Ôê{ßøå‘ Ø¥·ë”fWƒtxè0Á!¤S´%ãŹØC'‰Æ‘?’‡êãuÆ´A¶€»ÏÄ®_ûÈÞÕçó@Ÿê1;:ð ÷Õ¡ö²æ¹¶É󚩯´"¶¡± ÝÕç’^éŽ $Íe [ j—Ù Í"ß*~0JPOçHè\Ûu1 ç´\SZéUmGCñ'ØØÃœëÖI—NiGèSÇ´±¦ $²Ü6miœ½æ5M¤AQކƒ«bIÓÜíPã„Á滬¤jyʼ>å"2R-p%¦u®ª„uÓ'´VT…nâß”V¸ØˆžryߎZÄSp[&1#<TUIàâH¿âÒåD�Ÿ2 ðæñõXM²{¾ˆ[D•’ e_à,ľªÑ®ÁXh›§»FrZd5l8²¦ ·ádjê–Œa.bC7±kñŸB™åßk;ÊÊ!ö˜be}Á�1\ü)64v¦Îm ÓX è9LkÆ3\�8ðb‚Þ\Ó÷õ“x»ÄãøX=Kšþµ¾STõ\/tïË?|ž�­XÂ1Z/tÑŠI­ÞÖkZ „J`Õ‰Ü@§B'Çî—Óñè§ú¸ #JõsuLjÕÞ·õš®S½÷ý Jƒdt¢! ¤ºô üoÆië±JEt¢îUM’ãB† Š·Nxk/r±¢KÇCH…à`!Ácõ«='I]:E­ŠSðW(B%èÐù”V :‚¥v¤ÿsuœª L’—ÂólIÓãZŸ×Ë @ÒL+j“­jo=¢tkÇÄþ­13?ÿpÚ`÷“_Ò4ÉždCr¢1RRƘÍ?™ÐÚ¡úñL‹ÚHÒ¶†h¦öå6‡ëý}KãbQLöQàq‘ <}c^O®¹Þ;˜±2[O%¥Ú¬¹É—5Ç9NÏ4"rrW¹þÓ—ÈWî§÷U‹¢`zBFÏî+Þë‰qd©§Rêºêª¸*9<¿¾áÄDÓ¸¦eT m·¨Ê–”5w®Έw’p—`FM¸‰ é»úÕ¹: ehõkKãEUæU&`ºØ­“v]ÜÓ føÛæ íºØÖ0<…m Ã[cLbh H—¾$”´<¯™ŠŠ/õÕw W´ë‚þ†ézá"ÿFFzžÔê®_è>–A†UÏôð#}ÂÒÏõ/2ÿÅ¿|ba@=/Â6R¿öÿñrCÚùBïHþ¥þœ¹_‚‡."¶5 ÌeV76F5À³ƒÚ%e‚Ir97c:�� �IDATF²ûê_Ð쩺hÝŽT€.Ø® ·{ºoÈš&Fô)À/˜÷Έ>õbœ®iDx;Á5MpO™q7¯™^Àw0vÂ_âx{MžF³8œ€YX8›PØp0z8x­ë·Æ®»@GªUCyé“Îx&G¶N“*%øQÖ|âÆ+eßì¦ÙzWz¬WéØÇd<´mLžCõ…¥Ý¸¡å|f±¯*h’ú„ÖÂ,K ¿±t”‹ºìÑÔ±yœæ·>°¾»û9@K³fU74)57š×ëa[v44¯'̱'´†òÞ˜6˜ß0c`MØD�xkÃÚ>VÏŠ¦ÚtyKoèZp‰,iÙíÅŽ†Ø¯‚è…("ItÄôÇzÊ‹(OÕEc±¥ñ#64¶¥ñ^ÕŽT€1ϱÁEd‘豞–TÝW?ÏgUkA³%U4ûXO_è‘ ªSg5å¿­¿V#'êþ…¾_Ô&áþGÿPqeÖµªÉ ­á‡²¯þý¶’WíŽ^Ñ¡pˆÜƒÙôj“Z¥ÑAÇ¥Úª%ªzû  m´”_ª­K§°7QLÇÈŠÿE¥•÷nôêÀ©ýP}G´Ì1RC1½„m^OОð5c…çpÜbøt8»øk´õ"}³¡?Þ‘6Žß‚2­¥y=A|rXÛäÖøNÔýT-ŸèŒÞˆÎÏ;˱rõÞØ‰º—4ÍÇéÖÉ´–Œ»Ð„±SÇU 1åÜ uð]a^¤óZ/ºi¤¸Ä˜„Q@Ý=Ske©1:㥦SèÉ2)gUÿøúÌzЃq&»!ÇUDî7“2Z!wfÊš‘}çX)~=¢vµ¥¤–´­adXÒ${14ÚW?›¤˜E½Ò}õÓ=Ào>VN²Œ…Ȉ'µë‚!f@Ÿ krü3=ħ£¬¹—ú�‡Æ1m 8KsàÏЦËSuv锿<Õã²æØ…'ÄèÓKµUTÜWÿžèBåÅUl“Í"j/訬9žr5¦WºÃXèH…i-¡.QÐÑS=æ«Ðs†g8b0÷¢Ý<S'ÏéÐ9âO§êâ‹êÖɱzzUC…tƒÚ-Óøb‰Â’qvV Ð:8Nd&¶5‡Êö=XÓ=á :K¬0×áÂ0`h~“Ú�ÏÕáE¨n €[qÝ:á®_Ð,i†ˆî*Ö©[zЯýŠáMfâKC‡…;E ú¶D90>E† ÕcFndðF,ç™c’r[fg8ºÉ›ë]ÉX‘AèK°.øÓg!%üSÆóÌEL4:ˆd–}^òMsÎÈ™mèˆ}TaÍy«±¹)޶(l±‚Œ²îWèì×Y·ÎUÁúÒvyöVÚ´Cð»¤åI­b‡ˆ(Eë±zv4D›Õ£c¢EºuÂÆk´ÌXÓD¿öé‡Hô_èÞ†ÆÕÇôžŸOi:49€;Ò*ƒ·õºK§e-UÅŠ |’7-kqDë·ô楾‡ü<0Ñv´Ç¶Ùm½f2D¿‚ú®ƒ yŽªüÉÏ™™U5Êì @v€üíUôèÛúûM-hMB´*ÎÕQÑ#ˆ$Œi;Ðÿd„f×Ê÷õ‰jO;"Oød¡IïîÖ–¾L—Ýä%"øA,ÝøW2GYs”ºu‚ΤÓ�Œ_ Îz–iüíDÝ´¹ 1—jc†Ÿ“»x@Ÿì¤>°LÑ&;Vψֱð‡r'ÇàAKw¨¼wÂ"Á8%`«Â\‡.VØ( ™ãõ=–»y¼ýŒåkè–K¹™‘5¸,T¹–T®¡¾fžE$fAç)ó"½]3)#—8²O#—$-‡QsNF\±àíÌÇmîÀrÿDö½>Ø`>j w˜*I:Õ{Þûaúí{U“[çi$˜»úœ=!€)ŒwÝQ ig]ãõlEShÚvé´ £¼jä‰5Mté´SgH¸Ò<a‚è߯ô]01Xçêx¦‡·ôwÖ•,8RôVÑ£7ºErêUÍ4ýq­óšOõxDëˆû™ òN)l¡×0ƒ{!¯Ã7^èЖ”cÈtª÷ˆÔd#TQ®¢[eU &á ÝãSßÒì"•çÛ˜W™SæñžM§œ· Y²?Ûx8»0Ö5Ñœ¸ŸZŠZc«û€3…J·Ò(Súf¶q•ôH•äÇ´!å–4Mf…†®¤oK­LSËn„f^OÐ/ÝÑÙÈŽHœP¦q¦ |ÊZì×~ª’s Øé~¯±•ä‰ÞwMÇêawÂߘYû׌y—z,wÄfÚÄsÃùV4¹æUbY4,ì5ÛÞsKKÂqL{ EÝ8—²!–ÊôÖ}W3hHcåù@N•Ù^Q´ökÈv×úŠôªø„Ö�IPO?S'c×;h’”d˜mD“^™_Äðð›ú}MyLá—´Ü¥/a~¯kü–ÞÐ~! Ä,ÉiLüÓm½f%ö¡žAA$Š1Zã€ÑNÔM|/iyV >¤}õÏëɈÖYO¦QãJ@u—Q À)­°ÆõI¯Ã—PÕhUÅyÍ XÕèºÆy‹?Óß«‡2ˆF¡¦üÝ*kî•îHÈO<XÛ1Û·~XÛ šå[:W‡”CÑâ}IAG¹0Þ{[ÉþÔ}³4¸fØsÛRrÌÆrä0kƒÂ·Nhçp´Œ÷¸�ôœ²²SgU•ÐËpÊŒS¸‘q†¡Ó‡²æÈˆ‡ÊOi¥¬Eò< .ZÞ9vžlv;fIÓóšAE‹E«Ã¯ß¯}Z^>éžî»ø¾Q|Gz¬|‹>ºyáf´§­©Rj¤âÉ«‘’IqÌ!—®š9„¹æ¶L€‚.}‰1É\À®¦±ϧHwUèÞ?6dæeøã_[ñ KÚ£I…îàRÕ(žôè¦ßk×+SȧBŠCú0ŠÀ`U¥ô VñV¦@1–ά¦¼5ôˆ¤4^¤OPi£]µ´+úJw˜1êÐsBÇÏ1¯kܽc¿ö)ÉGôéˆÖiÔ¦µ4¬í7º…}%X¥ ãïèUEÅCÍ© :¢?@LklOè_|¬Ÿk{Kãè ’c@5Iáø :â«XÕ$zN|óz²­á }¤O€Ñgfƾ}'§>i€Ñδ–0ŽqÑi^ýô±z˜UTtÙÊ�›|஋¯‚DÈVÚ@µkš(knWƒÐ[V5IŠ"=‡v5ÈsèA“FvŽåÄIÉ•5g ÛÙ Ã8q0§@ŒÏÔ¹§û°Ï–ª*uêŒzbOz.«†JNmM(aÂÔ�•aßœ/áRm^»õM¬Å)âæñÖz¬ZH <sW_Í©g²âQ-9WÕ *¯D ¨AÇ8BöصØÝ%锃æ¢&òJœD²¸Ñl` Ü­á€>3d eÍÝ4û©ï¬W�ÐŽ>·ù®~Eál1!I;bÁ”‚XÌ–’…³¨d^#¤ÖmöAIÎgGC_è}˜rŒµü¯pêàC÷hÓ%‹_'ênÓ¥­ÕƒÊí¼fsºt¢îšò,$ç¹`ÊÁulÓå·õ÷—j+kžÅä j—µ§Wº¬„É Ý-ÙE—æ ‘CzP¤+Ð}—DFgeІ¯GÇd—.¦lñ‰È%-Cœã›¡]�aÞ|¦NÄœŠÚÜÓ‡/õÁŸþѧ?úvuESž?qkÏëÉ™:a�r+™FáüÄ:fê`ŠÚt£Ì²3|÷#Jªª/e\<Jôè-¾! »Ðú)}**ú­Á Iö¨ràŠ™JÕ DNè¾ú 2Œ={c€:«…ŠŠô[ÆT&´6¡µ µƒ ~‹$>Å|·˜¼GQÜbª›7­·ßc‘¢LL»uA#({Ó_êöŒIg¥>Ùþn1ÊJš’ã_5Û<†ñ•'LYÊ-Êë™-EB’k1/ŽL÷Ì<F ›£30ÈÁµ×b‰ƒÃ,NDúµß¯ý 1=sŒðŸ‘Å8ò 0Ö4ѦË%M£{»®q0§zoGCõ {Cz‹!í0!sÝsW¿\Ð,yKI΀ ¶¡±}†VЩº<ÔaSxZKìi)m§(Ù cu‰=0< ¡up|¡÷ïé…5�&÷å)Ãïê—mºdæAy®Ž}õ;yª¹ ô ÓCš £û€É,hS% n/úúQ[®˜½M(gÞÓá½õKýé[z£[21c69Ò5Ì»¡A!?Á=^Ñ#@ÚŸ±˜rŠ .¬�hy–ùæ5c8Ôzêóšá¢Ÿ{®{Ž„ÂâpÕ¦$4²qªDéÌÈJuÁ‘'=b²µ¦ òè‘ RŽk€gž«c@{G*té¡&Îò¬në5xé„Ö^鎧¶$Ús)pÝ<Þ^Ær“F¬ š³4¡hˆEmâ¢Ã|)èçâ¶`óPªv% å¸h"½ÇÞ"©œÉeÃz¸–{¯¸Ž ƒµ¸¦îµh›pÇ…3æÏÜ`-³½k… º  TGb€»¥7°ãfµ€«!° §þ\ózBr2!%!¢ü©º•ÇÛâ©¿Ô šÝÓÀ‰º‘Bm¯K§j§!ëÑ1{WRkœ7¢Ä¶æEEE˜]]:µ.Ê’¦ÍŠ~¬§–t‚�r¢n6¥Lb4s}IÓKš&¢NÙ¥SæRV¬°º9+ºˆÎkÂÅ™:{u`J!æ ´_àŠ,SÃ8�–ÜÑú­X<ïhˆFªª©BÉË HÍ5™Ý=PÂýÓo|ªÿDz)ý{]ªÖ!Òwý/›WZêW¯L&¬j”|Ã7Ïê½›p¦Ay}íRm&;liœ%6òŸ™ 0!Ñ-¤]¦-ÃA4K:uF{mBƒ½0&&´VRµ¬9ÐìªJXmÑ=§¶lÓ aOõxR«H\BdçsÕUÁŽ�ªoD~¥Ÿ»Éo?c•µuý_�â�¾=êÈ'–:™‚R~ZúÏóy&µRéT“1¤@¸Œ¿’¸CMé§y«ig™¶É>Ü¡{h8· Ñ(ÊÄíw¿†£,ÇVŠ�„ì.Õ¶ªÉ3uh¯['«š„–Ý©³u33—2<ñPç£ÝJÇŠ.CD—»úüRm´Axd%oë5yeMwôjGCõö[8\«fO��úCˆ€þ‰>Â�eR«( c Ìü¦['/tPeSIcÚ`›R¾‹,xÁõ°Ê¢’ôß™:ùà¼&ö€[z@ßÉ;Jbß‹,W¾ #œÀ0m=„Eák»¬9p¿4Ó-y�ãÁ33*‰ìßÒýmõÁ¿ù‡¹÷õ… |ãlxBkQšàÙg•P€Þ1ZÕ@‚Ç܉e͡ބ6Ù L•òbK"¿‰3qÌY;!o H»LŸfÐŒ/)J8S%U±„-kqP»¡á©�ƒþý™:A¹Ëš¡{=:†z : Ý”Š!î$ð'©:øÝ ‚o5c9a˜dÑlÒq`yJ·GÓpW„¹ª;$Õ· ëùÉ>÷ŒX¹dÑys©˜.‘\Ú Ë»-K8d´9VóI®E¨ÉëÏ!ɹáËñóf­ú¦¤u-Áœ£'?bËŠ$ñT‡´Ó©³7úc"ãkÝF*‚aL ‹ªNhmA³‡ÊOjsÂY-°Ê ¹œ Y«§SJ×”¬§ ÜÕçcÚ¨)¦ÎSu!¶Ô¯}B'¢ï¶`ç‚D-3‘Ï«|¡ö#þëïRmÈ¿šÂÀÉcv„*è·¶4÷d_ýÄBÚÞÕ BºÈ%œª‹zM4—ýÚ§ÇÂßOÿdë# ¿)©B@¿NÖ�@"dÉ•ƒâ/€ÁºÁüßèÏôB Ÿ“2b7ãɪJœŒá§µDCy¢îS½‡-}wzQR𵦠¤DŒ“‘5M˜vÏ Æ «NülÞË¡{B=Ê©¡+²ÿ§¬ ïÜ}4B2+¢þ­ª¾n•ƒ‚hûy͘¡”M2/Q>$Êá.Í…‘ü*û‚ÀÛÍã-3/zÖú‹SŸ˜œŠÚL5iS­ qµ�I{‹YmjqVCC½‘- 3‚X*i…›‚X†Š †wÏY-ÞÉï }ãšÒ‹ª$ÙÇÍ'B�Âêë§ÐÁ z²r®ŽªŠÚC¾}U“DäMµ;L„@ëxâ]SgV!Q—jÛÐÃy¶—žïé>0Î+ÝAÐËDF_÷ôb^Oˆ³h2 U€‡ˆh pѦË1màþµ¤é^@©·„9ÆÊ;zE<]Õ$1s8÷zèÇ\ Yޱw°±•è¸Ì‡0LÏ›¦Ñ¦Ö\Â*²¤Ÿ™õê�½Ç¿úmqV 4.�ìI~i”Á-:~ð¿w4ÄHIž&´ÜtjP¾à–Iºò¢$’G"——tŸ!±á2ŸKÊ646¢O7Xž× °‰!Nð<‡ê¦Ç–º´º˜š„¶ùÚf—{3fØL7]à‚X&å_%2k \7·Å¼ˆ›ÂõdYîf¨Åš Ùr�ZkÙÃ5oPIo‰7ò£%6â[`æõÄ—;·S’áhðCžSÚˆ¬K÷‚é7wQú*t1kfjè«þ~-z,Ï)áóÅÒ%0-ç°6€f9&³Dó¼jѾÖmt•Ä,ÀOÕ5 =v9§µÄê’w†€•PÍXÐ, DHwæ=#;„¿É€žµÉ» ûàƒÕª&‹ª|¢¼ßJ8#‚c]8¯',ÛdGC¬ø jw@Ÿ6VUZÐ,×*zöÝ:Áéƒ%§%Mã°EÏELïºÂÁcxà7m5Z%~Ñ£J4à Ë:Ãb€­`Q%òž[%-›/Àë $å**²óÄP‘+<T>ZvqÌì*Ík†´ÊËRX àdz‘€? ¶{ ’ ß£c>ftüqvA…ë°¨Mh÷EUÒÁ7=¬k?#`Cô¯o2 eÚZÖ\AGì3äXõsY†Å³Âf´š™“!ÂôÝ ‚o9c5K%åÂd(ƒ, Ï‚LVT…póõ`RúÉ…“ÝÚ¯Xÿ"áN¹�Ç×¢{ˆ‹nEŽÁ&&û9ÝnéAâƒP =Ae§Å³‘’ʶo<Ôkv†Ì5/ _‹Ë¢!V³¦ š>R8¸¡1¶nw5ˆ;Üî§z\ÐÚ}L×áigH;„’q­Ãn8VÏS=fV7<<xff¾ÉR¤0´wê¬GÇtœ\¨8Mìh¨M—eÍs`DêôI*ºÕ©3vŠëé’¦×4AÊ$ÓXGœÉ_„ÖÚuA+ÀìÄé$òPy,ET¼¯‹‡•´Ìņ’/_sæõĬn^пÚ~7‰½–€×ÂÆ¤Ëµ\¯ÌV05‰ŠsWƒ|Eè\Ðjð1Ù•Žù‰®Ú³º ÑYZ]f<“*¥…–] ÂR1¹ÑS®Cå!»WUJDÇ\Â� x0M¿{@=WO@}?&>ÂvNõÊ[dß„ô;¾yÍÐ2,\ÑM!l{ÆcéDäÌ2s³h¶½ïM ùšÿâÞûðÁ÷?ü¯ÿû›ÿ+»¼û_üŸ?ùÉ¿v[Í8<‘¢%wé9,ð²+DóËT7\ëÍœ½†DÀ}ÈdcàW‚¼al sa –5z/Eß›X>˜°vme8Ì+.ìB{G¯p­µ‘«•Å=1ZÈäBí÷ôâ®>?Õ{ÏôÐoÃÅP֙ɓ¤I­¾Ñ­=ïUmA³·ô†7Ôê Ý£ ðÉκé¨ð è³-=€Ô€ññ™:ëé3=äÀ0Áµ°Pù±~öRwô™×³`�>ÖÓq­GT#«SuñœÍè9Hƒ?šiDi Ò¸Þ8f5üy3Sà¸ÈËš£MIwJ>Þ&ÿ0U·òáÔµÖöwôëèç-…#+k\ü<:tÎ Š/–w§ÁBß+>TnmŒ„u6…é;¹y‚ßôP}[zÀ/—T~Î ‡´®ññ”à‹ÚÒŒŽŠŽŸq#ß0WWàc=­)82™ÌŸ±GÇ#ZwݸÔí¥â#IŸ4‹ç"…µ›Ç?ËãÿñÇÿÇõÿ<×ö¼þõÙÉÑW::fÞÛå*´ºRBÛóW ¨ê Ÿà(djWQô™¦ îPY‹ÑªÑkË BA†øüʉ!–Eéåfì.Ký¢¢l¥¹Ž‘ûîç·&F^WæEãA°ƒ© &Œ< Šæ šeU…[š ÕÁë¬ xƒ/t¯¬Eô)ˆ, ´0¿8VO».Éf=y[ÃzNa¾¡1ÒUAGwõ9ØøR iÉZÌæKªnh¬¬9æmqÓy\ëà;¢1:RFa^3¿Ð÷Y8¥µ"Zya<9€PÁø`�ÍšeD 2®CJ~ÓX˜â+!àyÉTn£jž¶úi XÌ’r|K[§?†ëˆÖŸý3 Ÿ'¨?ϯ©ê´‰ýÚçÈ¡ésä¾O i’Ìè2cUJ6rƒ‚á|ÌUòÉ+Hö+Fk¸r&qHãZ÷rEU£j§åe7 1F¦tÌYaýQ@ŒkýŽ^A=E÷öP}h/ÑòéèS‡ZƒÔcÛId;R|ð¢g_ó:éÍãm ‚itQI(mýîb}8ê¡ßxz\õõíd‹CåKªk¸ŒyÍ…Gš F†Ò^Hèäòvn¤ÙòB7‰ßÂnÙv@ðš°öNx|4úªy= R‡ºÞPu†¸\*0G鹆´å}@ÏèNÕE„‚§ A¬†Nu|KoÌ_tG¯žé! šIÌ•§cëÔY».¶4þcýŒñرz¦´2¢uÈÙÃWTdùHv˜à(",î7©UÚ/^¹[ð:¡fµ@§hyYŽ’ቺáöªVRµ¤e‹zðC2¨©¾½: K‘Ÿè‡¸ÎÓêa.¹Ð•2¹zS]b“Ž Úw‹¯÷žîohìªmé„;b@Ï12—‰t%Ûv]c˜P‚Œ¥Is] €Ä@4¨¨ˆ€XeY‹¨ÑW5úR$'Xx|>/c0JɲÙj [³î†= v¤Â-½a€³Is_Te@ÏAŒ}ws®_ëöOõ±ÙzÎa3ÂìÑ1“‹�¢P‹Q‹VIë=°Ãn¦Yo ü‰q‰ÀeÈšÇR`±GHÖT ë¨-ˆ\Îx=pb(Urª‹¬<iÞ‘2˜!ÜÒ ô©Lf%ù@ŒËW 0·¸|µBd×êâàË¿ –²:J¸tѧ �âѯ}�½n°ÛK@ŒŠ‘[œ)èh@{41`Œ+š‚XÁ¬h Â!Éc^Oöô!l kíºØÑ2»þ GH— úx‹i-]¨×1°Ù¥S¿‹ÑïNÍëIEEð´4.Ê"Îl,b€H ÆÎ>‚-¾Û`]Ì#/>Vо¬˜.AûDhªÁ¹çŒ¸ Ž` ›IÿjÊd? ¤õ»\w$¡¦~2ÿ[Ðkê®êßÏ´–îèîÏŽ!€«85bì«®ªÒ–Œh;ÄÒµ¬OŸù#Qo7( ŽF¸›ßõŽ0òÊ)æä<¡¸µn_7*H™|ëûš÷vëbK¾Í’ qcŽE³XyY`ܶÈËÆB2Ž13èCjH:9]ñ´7•o»c´lhY¦,5U9þ7½Ò§óvÅÍõ§ïJP-kŽÎ‰‘50 àB혶°YŶX41…£”^Ь”Ã÷]RIÕ§zœ"NuBk«š¤¹aÒ¾­aº1ÆéEUÀ�ñ;RîŽÈøÒalá¤VѤ¸£WZÒÎS=öPþ¼v¼NÎÕAèdF ÀH¿WfRDRT{¨çÖS’úMìûÃåZvzìNÀ׫a~ˆ¡¿ˆ—#Ä6´!Ø8˜–Ô+ŒÈðj´ƒUž@}�;©¤*7oä5ð©ÑÛÅ×”¨ŠŠ0°0̤øˆwPU£<Ÿ{¶¤ªÓ‡ú¾¾x£[œ2ÞKL`º‚Žhëí àyU¯¸ÒzuàUwxƒh;)™™Ác4´ÈÂS š]XŽ6õ¬I§qGºG@hn€Á· Fš©§PìÞ‡b-‹ådÄÖB¢ÊÙ–FIÅtö°æ•õš+aÄYt1´Îßuõš®ãVÓ“pTYØY¶’ÓA˜We.B-r2î5ÍaI˜ D ¿â–ÆYž×ÌvØÕ CþQs(éÉI#Z¯jt$µPè¯Ó¬ÀUÛÓ‡8Ãv뤪"B.œ÷¸…VÉc¼6RÈ�L!ô8‰f«G_«š\ÓÄ’¦¹hÙäeð¯tÈBD¬C¾©¥m½`Ã4ÀÎÔ­2=å k,5- ZAFdb@°´Tq3TÖü’¦ùbt‘Úy_4«HH܃•´ ™›U\4ì¹ÑX`j‰ÅDjRo2j�";`‚\_Ò2°g¿öKZ¶+‚”Áî+j“ÖÍ¶ŠŠ{ºOj)èhZKÛÆBÓŠn®3h+™t¶ë‚OD‡Çõh|¨>TÁÒVߨ—gLgZiå'|¼–P². ~_*|ô¾sÔœË]{ŠÖÛœcåše1Åfð-#¹tÿ¸Ój’5Ц$‘[‘øè}>±tÒ¼íBòaLÕÜÕIîͽÂÕÂLYªN”oi½WÑòé¾êï×ëaÑ}ã0Y2%äÝÑ«3uîhñr¦Ù$ª3uŽh½¬ù>ôèøÂE»�� �IDAT¥>à›<SgQU¶wÍßÒø¬îês⣒«9i_ýÒÓ ús¨<ÚK¸!{ÔO Cö 1$.c\¦ l°/•®›»ÜW?*h81²Æ+XT±­3ñrXt=ÇÇ =£g¾“ L¦ gM ˜—p}Bþ&Ét4¦ ôqäú•¾Ëjt�¶Ð¸Oj+zD„%]yõ¾¥M1™´3*Ín ¼TQÉÄ9¾B¿Î†´A†¤ÎÐkWƒø[rjv4„rî¬ȵ¸<c37Zû‡Ê3m:Uëa€”o×ò%4»&ƒxÈÝ\ˆ×%ê¯zZòµ° €æ=dG^ÇfóœÍäo9w“KÞó"iÈM W0—fh„`ýYvóª`RÙ¬- ûÌÑÐ¥P³VŸßÅòð-=8å­U¨ _AÌ11¬ÛT»êWr…¥Úb¬|p-“VÞÃù-=(©Jè$¾¿Ð=%›]ª{û=[ŸWù¯õà ÝÕ/„°Å Z›‘’u¼ˆÔt$(64Fà®è‘ÝΖ4ýPÏ:u†uMifDëH¿¿¯/ŽÕóXO“¦wtüŽ”eKšfß6(ê÷ÔݤóôJZ¶coôMQ,GÏ5ÆÅLFQÃM4ã~·N¦µD(ÜÒx¿ö»u‚­óš&ôüP}wõK>ìÄÔÆmV5Н ¤MvoKª¨¦‰ï-ß!—:_T…ufÒí vÑ�ä°™ù j—ÖŠ:#mdn’Æ�ÁH :ò,­_û&§ð é÷ÕÏŒ“vYuÝoJÐÛCiAD ý¤¢6/ÔN¤BŒÖœPÀJeˬúDÝ{ú¯á4 <`;Ð{ô¬�3‘V¢k9…P×­/o€Á·’±2»b«É§*kÙÀµQ Ðv[Z“z¾‰fÛž[Z¾3¥´|°lÏR \ \Á¬ÅéÑ‚žì{¹8¹ä¼iOv´4µ«]?Í’kA-¾©á»–½}¢Î²Á’¦‹ªLkiJ+gÐÁ :O5õ©Þ«è:r)1ípF‘4¬m,µˆËȨ#˜¸pö1äe6 ÏÖ4±¡±=ݧ‰ù¾Õ£cÆcJ*—è -höH…_é»®¿|¦‡^¤…›ŽÞ‚ ÍBã…±¦ &óˆ%|,ç<º`D »ð9_áèïA?KË‹yXÚ:Ñ:C”cõ`1<¢u,Tìlv@Ž­‚HZ]ÓÄ¥Ú àNk «Ä¶—÷OfµPÒrQ‹Ê»P›ÖjÔ¨¤óÙÉ¥ípL§Õ€+XÑ#ïl!b‚ï3ø*n^|@;]Íë I%e¯úEBÇ ñ²4[|ÉÑÒšY&úñ¶?W}*]&±Â .fÎæU¡[«(H XˆË!ȃOo‘ÞÈ5}=¯Ü vÏšù0Þäí»"]œ53Êâ¬+g\"rö¾òõ#F¡ÆË2rÓ¤Ú„%îë7Q}ðIs~jÅ ½ š'-kË×ö‘EÚKðÖ+½Ô÷¦´²¢©WºƒÙhO÷Ñ¥mŠÔµŸêãŸéÇ lù9ëÀ]:Å0i^OØ*u°€Õ†2/§Éd?{¶A~óÂ/£):3ïÿZ›cV ñ ‰á©…Sê¡NEØZUƒøWjÞ[WvÌêF´NivN µ›„]Óã^`ÒÍk"%Ú8Êe™ “§úθÖãÂÆ•-øÆÈ9ê¢KH¼…ý©¹›¼8½ÚÓ‡|‡JK»Ü;laÓMâC-¢¤eø~#úÔ·§ßC5`½ô=—LÒ£bði2¬KC||ÃÝ:ÒB×[06áªX‰#9´¹óšá9œ{—Žjå>Â7,­ÖÇtƒ¸q×YÕÂ7°çɸffD”óIc§zv9Q7ˆ %R°L¬×¼¶/Ñ_G{{ÂlWIÒË’ˆÁÄÏ’ í–IUcNfÛ‚®²tAÇË1»†^Y ¶-Qê²6[Öܶ†›#‹Þ® 8W§êÂVjBkUâ¨Ë|ècýQQ¼ˆë)?¡{(¯Möô!¿�EdÇzѧïX=ø\tè|A³°þ`suéô§ú¸Sg«j”þ ´ zⳎ˜I—2o ‹„Y DîËÙÄCÓ°2ÕP§$]9ÈÒ`Y¡ÉÕ‚ ðÙ`Í…Õi㱞¢‰çäJCÙ¥/ñ¿0iBaWÒ2N »Œjø\ç–äCE/c¾O¨ÓZ¢ƒ8«•SÌ—Ù£cUÈ)JBïÜþÀÅôè®9xGt¼ÈÁkš€9ÂE¢À°÷„kŠæ$ÉÆi¬ªÒ±z@\8=:Æ8ûO¿ñi§Î†µâ»õ‚É:»deäÀöÉAÂ4ïâ Ù â|;Ì‹E ŒHüKÂ}yÔtB}áÝï\\ŽÃ*nþx¾mÑÈ£™Áhrºþybd5=|aÁƒiƬ>míä"‹$´ö‚Et™ÐΘ››”°#çþ:ê6¥´žhF´ŽÔ,)„fw(¹^ÕÚt‰06á!^ÊBMíºx©^êjá -h–UPä ŽTø©>«ªD†9@ϱ¯þ_ë;Ì8›Háq�à{IW¢ä9˜W;›®RÖœ”YÖ7E4âñXˆ^Š|ÀlƒÕ{®%VÇ´Ñ©³UMºÎ³l]jã2Ü)™ºõê`CcÏôÑwî®i¹€É$]€|W „ܼz�rz˜ä¼¢)ÔÓéHW"0ÁX‹oìX=8­à|ˆ0X1$Füé9é¨ÒZ9¦3B(ˆFö¢ÄÖÕ·«ÁyÍØá3r©Xfð€AÚûúâoÿPwÝ´IÛ–Æ“à\]6“4 KYsÞÙbºÉµ{S‹b\s~ÖÛDO~òM³„ �*¬|Æz0Ê÷]®2²+ÿ¤(hÛb4 v5v‡#o!ç µÿ™þ&÷G¿ûŸûßé[«šŒêmÍ<‹"~¢–î>öûÍuîZ2ݳ«§ •em=%I7À¢I­~K¿CÇu×I­² HEp1šÇ¹³K,ëÀCÚICoqÒ!wà¦Áóc¨>‚5<ÕŒdNc´Þ5È·æ¯\Ò­š–¾â¢n*ãêMX™·_Ùk†ª@æ�Ï,i™•[ã¥>B~2¤ôñ”œŽ­ûöy;^Þkö§3©ê+qõ=}¸¡±I­®jRiµÖp¤ Ë÷ñð²·’ýŽ>0þ•_´3ƒ’v>W»nÞ.wÅi?o²7¿H„÷d™Äæ¯r¹žê;ئüÅ¿zòwÿîô´ð$ñÅš´‘niÓå€>³þ€¿"ŒÍ×ÃhˆN7yëŸüÿ˜c5Í{Z›™YËä銻U¨ÕUü÷ªèm¼‘bz‹‰„[Yá2~Œ¡7 pèÊÎVÖ¼žspCoôJà¾^ýN3Qó‚üA½lQ€i-Y~Â"@D.23§”WžX¼ÀµQº‰Œ…à¬s›T1è3>Ib¬rÇJ¬ž�Åé—Ò~kˆ;YBóJ±j)kÑ“§æ«´žÅ÷ô!z»CÚ±|»d¯F^¾(‚Ü0T ’“¡ÙáMѹ.ÜðOl­q¥2Ë,¢ÁïZžƒAyË*´Ÿè£oëïßè¦ÇkÀIËó'¾gŸ…TI4þ•6××RLðWjÄœ#Éåßœ™žùE9J‹övéô¿ù£Ï$ý‡ß~ãC}¶ Y\²|møz‹2ß± cˈÔ2¼¼YÌz s,T5™E‰³X™z¡ŠEàoÖ®žÌzKž„)Y§R}.ÅŽ«Þ‰¹@çË%Žú5 D3« ŠÀ©Ðë3QX”Iïžk¡È{—9J:fyߢÙòøÚ=ˆ°˜Ð*ËゎPš8R¡K§½ªmé$rXBêfPD…XHt 6oÓe‡ÎÑ«-kqKðET"UCd‡Ä‘2¢Ðe�•²2/Èð#²þ¨åc|D(/…¡Ñ5M€A¨»¢b”l HЖœ©³¤ª=“@±P±¸—ÓˆÖá¼QÑ'ä0G!Ïr´’xü¼f :‚ý‡›m_6…|RÆË¢I¦rpÊšƒ;ع(å@M$±¡˜SZÒΡò{´­á²oéwJ*À”,UrH™²pí½(>fIÕ¸X¢äœÂj¶™½Œ‹Ô´Ár`–y*kNWè ªneÒçÆž–½ƒoëµþSýo¿íø¿õŸMk ;Pns®äNY§¬Eo"ûúO_aQ[Ñ#^í†.øvæXvâ±V1+\úŒ£]ˤax¼Û3'É9y´@…I_²¥ A0<Ûl!õòúI™i‘×AD.Y7ef{[Ù·å@/Íý‚Éd.¾~à¾7-o]Ÿ7p²×ËÍjÁè5M[;u6«…AíâN;¤’–ö²H»°£!ذ*PÑå×YÝÑж†;tØ‹?ï^Ðu‰«ÇÄGm–™î@:ÀíÐ+>µ&öD£oÆâ=¬ºÕ®A¹†’`EWØ´ °;uiÛ¡­mTàÊ)èÈ‹YN·[G“‚xÀ ŒqØFôÜá?:]n' ² ßCšØ°";KñÏhgIËSZ±]$‹º°Û{u€®Ä®™)"Î㩤eú?Õ7Ï ´ÎDj²8ìŒuc¡ÅÞÒP<Ÿ4Õò´At9kšXÐlQ/o!>àíf35Pd¦ú¯ÿå¯ÿÃo¾±­á_èûjg¥Au=â%q^Î òc–]ö2bØõ¬¯x2¼‡Ù˜Š{Ýð/¾æŒU/—Ôp ©…}É Ýnÿd*%-ÇRÎ9ÆFsͧ3óô;f¦npã…ÕË×G3DK>â¶=Òv©"#±"t~dßÚTéBlä\Íë×|Qß‹£ Lu­õ‡0¶6]Â×"µtèjCMyˆ…ýÚgÓ%ófZ(æ¡¶N¿E4XcÄs'y»„˜eÑ/†‹ªEª?ð†êí¾7Ÿ Æ¹e,kqESŽøÈm(ù]qÒJöªf¹ 8ßbå ¾%2WÐöø8ÇêñGc{z@Ÿ±IKdSžŠy»+éè»̨}ë‘bý„Í"¥A°#0Ý6áh¥ìBíœPš]Ûïh_û“±œºŸM€àrpzI3pdªѧfù¦•±©­<"Šhÿ¬ø6Ð1)赬é`z6; ç÷nk¸K§ùFLëSZU6åI<*aaî8SXEÃûàãv0Gñ†‚ñV2VVÒrœß´0BkŽz/’˜=|#Iý Õ­-z¸Y‹TLì¾"Ó›%— µÀÍn¤<sv%¥`&”ˆõŠKïiP‚¸y¢§I3©=w-˨œ#Hˆq¸í‡´3¡µ.}Ù¡ó%M㩈ƒm§Îëé‘ ,ù«ÙÖ}õ;1œѧcÚèѱ‡ ‡ê[Ññ15%ëèø0ƒÂ´Ò6QJg<‹OðµM¢JòH*è\hDëÄÄ „NiÔî?wz8T£(6£}ñ=©âÑÛå3ÒùA«Kpͺ®pÉ.=B M Cß.Ñ"’Á_È.œ¾NqR‚a•Ð#¦cf ̘-ß_e-bMbÕ ²Gј­ít·Žº”LP…¥]¸ÁIسž-¬æ:J[àЊo³rH𻼧4ßQdðâÀB#Z/kñT]\rãZÐ^"$c<”'!%õÇ~wrL’DQ²!.] t7÷¯½Ç ƒŸ,b5ú‚èV.ˆÆ¶ ?³(ÊÆ^ óÌsì ~;0¸ˆÞ$ªÔ°/èˆ+É·«í¸ c¨áWëÝxtýMd‘5gèkõÈœ´¬.ä‚^û¹:zUC§çT]@+·ôæL{@ýÆ9ªKÖïAñ(ª.s]¯ÜÕçIË oH;>;ü WWÖ¦Aµ9¢Où'â‘/¶pežoÑ0±tE¤cÜÒø†ÆÀ¾ÀŸËZtòvN‚ÅpG¯ :ò2W Éßô+Î%…àr¶Ë*©º¥èJí�ñ˜ç‘Þ¬×À‰Ê ­íé>¶ÔíÕu˜¢‡=:#»<U—w�” ÕƒEIËmº¤…%Ûy�Æýu¦NKF)®¾Ôäl¬ªJ(iñ[°!ìÇÈÉå±—ônLôtåç£憫*%L²öµ‰ˆ.È3Iú™"ÖìLcfå2QÈ»zÞ"uöåïÄ1ù®Š6xóøZ2–ïšž–HmˆÙ7<UªGDž<'Â&uÚ+ÎÅ}FóY^‰c†ØÖÀ(•Äœ¶¯Ù‡-#n†„g­[5kÆ7\œœ…þ/ç†,~üëzE6}jÜÿ˜]Á§è×þ´–ÊZÜÓ}‚żf^éœ@Ó©ºœœ.ÕVÒ2ËÅp(ŠªÄÉŠÃé¡WÀY[g—$ŠùÊ–Æ¥ŒÑEÚã)²ç‡,·—¢ÔliÍÒî½¢ö÷Ä‚#¨‘YÉ‘ä6âÉ»¢G‡ê#'Iº«ÏÑ@:T­¡˜01~ã8Ó>~ÞM “ü—úr¾é«|̬èNkÉ—´) %-S1µIÖ$ùyïž½lˆ!(š³|6¦ £CçlÂcì«?Hâ>bqÊ<¬Ôõf|{ÜËSZ1A†®: M9¬šT%MsûS"ÊšÃ%€ãgÔ„‘ ý®U²b¬ ;+íðñO nîIi Vý[iQ‹*\ÉÍrÔß0c°f—¥›Ç?Ëã-ÿ_UI µ(é—¼µg¬i$e Ó&ó)Z J§ U/U�¬³ÃF l»ƒÃàD\Ôê]ךjENTî"5–o›·7$*£œ×Õg`|:þ¤�œ Ïc­ëØf›ì&R ¦‹Àe^Æ:UW—NýÕC+fíÂÌo I´¬õ9›WNš±¾ ÑŸüÁ@è4¢O{UâÏ>OT÷ƒiÕ¡Tl0Âsk:8WGY‹ýÚÐg©Àà–Œ’Þ%7¨9H çêXÐ,›=kš(ª°”†©¦}—5ס# 0²ª*Ià‡eÍÍk´(U“¦3Ûi?ÊWõo5ø‡]gw¥½¥¤Æ»É:×…Ú™©°ã¡´AŒ#·sYs,ÿºàðL@Oé/Ž‚3È 2ÜÂ,9ÕMÿÀ0™<d‡õÌQéÔ¢47_÷£çZTژד^ujn>åÑrf;Út3G*U`ùK™ô(õF¹Ce€«Þ¡&GŸ;!Lq›Erë®4ôâáŸêHfµ—,‚ªîú¾Ä“°³Õ$>w“Z¾>T0嬙�Óèrì¬CUÈŒ "FÄôâ�,`z9ªéïØÇÄ:Æ•˜]¼‘U£¸J¬Ùbz¾,ͨZ”9à$·c®GÃÅ/›zʬùõ¯ÝÃNc(™Ò !rM“Z4CWPÉŸ¿ :$‡ÎÔ û.ÙÕ™2Qö‹Êòä B%-Ó9Ùj-"Ês.?êb “¨’ªP ƒ¨4gÊÀÙíÕA2ÙZŒ4¢‚Ž˜À{µùT]¼û„ÖàõAgèйM=PýPÒ¸š× Ý@IË`Ôn¡P…ØÕ`IËúwúòßó>V\I¬j”f®WµI­©€rÒ¾úaÓÙ >qç2{¦@w´(¾×�Hr[·^­Oú ¤ó4¶¬Ër*S^å´šÑàFr Çlô—|Ì-=°9'*øžVrå1ß|H—£ÏŸ´´cÊ¢'d ÞeH;Ö¹¦Ïc לɤ@CKŸ.o¾|È+ÀÏÍãkg^DtÎç¯Eî/®U¦‹¾à‚ÅÃС˶ñGÅY‡hÕL¶É𾆏Ÿa òeTÇhþÅú¨ ¡©ä·ÄÁälé²cŸØpyÀ+ZÄ™®óX5Ëó€æºuòB÷pDÄûŠî t‹…ú¦ #zâæQÇhM=ñ—A3®“„ÔE2H)ÊwD &‘K*k„вûc$_m—•fò3É÷o^3DíàÐ!4Ëùˬ ¼CÓçófk¤‡p<i–VcÈàÒ‚f+zô/þ!{¥;±D€MG6ºP;t>”)€Äê$7~ ‰E»=q `5b0JÀ²©!̽Œh<é°Ý]_Ž·È™›ÅÖÙg0^K0•ŒÐ"Ú”™Å½ SÐ%l»Ìæ8ÅŠ™YiݳþXÐ,¶¢øHP×F¦±¯¢u§7G…Ôòlq7‹oÅ×Ýc5«Yç,ÿš¸¹à²IЧMañÅ"lº‰áDšÒFCê"dÇÖ>Æ‚¶ÁÎ87¡µh>·¸Ö4‘@ç ”¦WéÒ?ˆZP>Œ¨:x¥€Ê]Qœºv¨ Ñ|BkP®Ê34gÙbt²‡—«Q*ä|”\¦¢õ8Ä0hñfõ âœ]Í)M륛¨$#½ªÆ¦pÆñìhˆ¨d:>%¼‚!:F8µ§=›Ê–ÆiP‚¨Ï(«Çª£‹}¬IFm‡®üŒÑ/Ÿ 8ž#NÕõCýõžî/iûJ6—#}£]]:5ƒcKãÕ”‡)Ç—6¢u|:ø_JÉhú½‚ÍòÌœ¬ mŽß¡òCÚ1CÄnd¾GØÕå{ö]#�™ƒˆdSTŰ׷-[ž”ózRÕ(’ǾÇ!µÇÌÊä’•PkØÁu%ï\¡Ç5ý¸eeX‰)Æyݸ¹²?Ho]JíZßu¼eT0ç ‚ .‰\ä#ëÀ™#ÔG äÍÂt`±jkQ`sþ0új™¬YǶU:­–TQŒR¹Í-Q½kdéÊ}•Ö[ÒÖí-ª’v;úš…0²+ÔüëÕcQ4©�¸¤´ê�WÐØ‹§áìçHH‰hóF ™—áv5ÛÓŠ®¡kÏlÆÆ™bu!g™àˆ1TuZÊsRšŸc#ö­Raý¥1IVUiDŸ’§w5ˆóxíu•EÑÐ$ÆK9š$ã`gꤿDÅœx¤Â_ë‡ãçëmמ;ÚW¿×`w4TRõBííº˜Ö’ÁO߃ޮµ<Xç¡úæõ„(j“å3hÜõHÅ/i}w>Z@bûâ”Hià ©–šeê:~Xó ×…U•RG›QÑ—«‰·•Ç>Ô /ÈœIµ¤nqÇý>¯NM‚‹T@Ïø'úfó°ø\_XrÍ-W®…8z“·¾¶ŒÕ`Xpòš;žœ2KY0Û–,|Í`aºà+ƒ×q?XÔM¶&ñ�,¹BXÅÅ”?B‹ÎzHQõéhЗª›IÂM"v’a¾ùÀ²È6¼†mV:ã9{sÄ)]J ø€N /’WX2%ù|Ù!΀aU`î4à_b(›³&&Åö¦£ѧ¶ $Ž¢œJÏÔ¹¤éˆàÄ4{¢nÆ?i’Iº§ÓZÐgðT`>Úì[+k.èfI=¶¾ëF“ï ÎÛŽ†l¹{¤Â˜6È :ŸÒ ¯fÿLÜ=Úua.X’X `‡u ·0f›tœ´ƒÆÐoeld+aãÈD™.²¾Û‘ ­Á%¾·8»–µÈõ@ªvùÂ=ËœLAJ4­ÇØŒSÃa˜¤G\JšUž~(•Jh´¢â–Æmªt hÙ,\£ fqØ É×'ûé® kY=d7c­¯{ŽåÜCûÂÙ 4˜,túÖA\ÜBiS8Cð)-ºg-¨cð~¬WÙ±`IP^Ö<yÎY;'íù6öC‰ïeª´£­lÀÁ.V©3È2}®™ãÞ^çQÖ¬8_ÄÁ;fµ`ÈÜö&CÊ´YDÛ–êÕ .o²’Ê%=­†FŽ=kÈš]:%9Ù€¼9I[«*i±»–9@ÁTçB“V5I«´ Þ2E5®" Ø.²G0ã#�¤ä-Ì ¢û!޶=m–‚ø“dš'!-QCzƒø‹†=SŸÕvy_ž Ã>«Þú‚CHõ »_/©Š¢§æøIêѱ5A<`ã«KvbR»¿ir ™Àj–±ž@ʬ¾[' "*©ÊÔÊŸ×ì!ë›(ØÍÀªˆß’ÃôK.~‡ “ÅÁÁõ3Ò{{=Vs±MåFÅá#-‡×RãœYÁ/l+T ¹æq®!ZDäš§Õ1²8sBJˆDδ1˜{&5ùagÍy(sö¤óëÑ t˜Å麴2ܑ֥ ”5.·!Ø;×õZ5õëiXµi!¥æâ4ÌãEèâm'$-4KÄmŸšVjFiøJª²7†âC=“²'ø1o¼.Í5ë(w ”Ù•;QRIضˆGGpëíÎ~®Ž~íóùç ü=ÿãOàÄ¢6{tŒü)&yÖ¥“=‹½Çêé×>Ce¾„¤ÎPš×4/,Ñ«£ÒœCS˜¥âÕRI£Aä³Ïæ–A=_®ÌZl}yfy¨<£M{®ºc³»Šòùu¤ ”o&½©Jª‚¦zÝØÔ <3­6…Übòh@6J¸t½"w@£A'ë{¦Ð<‘²>jV»yü³Ï±,{q ”‘¥Ù¡ê E:ÖW YP`Ê¢|»'–æMÙÂÑ>nÔ¢¹íSºQç@ ¥–Ï’K�£—Õë,vTÂbî FŽM^WVÓð9M*D(ËȦþ;ïµ’ªA׿†šqœà9B8l—£GÎ\  $æ”6R ‘å 9h58qHN°]4®uä?· b(žÐ¸îqûuÝU»uÄ*›oÀü ¤r¹!ß}‘ßE˜ÃÞÓ}ÄÓ¼!íUAd1F´ÒÁB;t¾¯~â,‘´¤¢ù�� �IDAT4LV2sŽ˜¡jhz¡'siàT_k©jtESžû–qójÕ4ÚÊD*YäKn¡2ùÃxåÿmïëBë̲+W…~ê0ßÄ =MC0y=Eˆ¸8…_z¨£'Õ˜6ˆ¹Ü„ê—´A*0B ÂÊ"î§®‡ËžÖ“)Ò…Ä<™j#4MwàZÁ4d”&ˆ‰ˆ'ß¼M<ëÛë[ç|WÕõãJWµÎ¦($ùÞï÷œ³ÏÞ{íµ<‰çp˜L]iRºLÒy°¿ø Þ<Â<Å00ϲIWð¡…;㨮Aë óÏŠ,™/eQ@…í¦{l“¸P$RfhÕ¹DëSŠX_ž}£û§ôÅvû±€z„*° gT' "£6(`.mµ„Í#+Qª+y«ÁD¨–Æ+©P Ñ`´ˆÙ#ô–‚NÄÛ8ÝÂÝ# ôÖzÑëZKø1TézJwðvvq<H¸j"=ì;fám˜2€\ÞÄ KÍbOPu®J<a•2Kì>Œ]6¼Òàé©>†£¤T¨ætDÉs¥zƒ*4$Èw·Q>“{H Y“ ÀLt"ðcéÒYC’ÚqdÎbx»%ÉÉ+˜`  Uu oaÓ'ñ’¡b|Ch%1–÷pçßãŸþߢzïƒl²n$A„D!‰3®âçÊ_1+Kй;•˜¿‡¡Þç“á»8x)Té¸ÝaXe.”>F’‰¬™­cçSº)z‹X Èût€ÎWãõSúX8À,wztíÜp,âp ÷™Ï”ò¸ùiܱ59þ[Øècf„U`/vZÍ»ŠÍs¢³­f,€z«MP×Q"«š˜’+Õê¢uLbÁŒÓYN¢x¯/×cÕ# ¡Žš #i&<j9aÍ~¤¾ÚzqŠ˜@8Ü2]ã%Üçr­£àV‹˜áÌúž¶kÜި٣ݵWyöy'GÍq$ñç¶ñk ·0Š+×6qwu$KW¥Ôu™û-ìåöÖÐçÚJgCD�÷¿*„8¥70…~ Å ÃÙ@–žbèê‚kØ=iÔgz¤6 qÆ2ö]>c§ÛØ<ÅÌ}éü_ËbcëØy†9Å­V:} g°¹…Á ·1=³A(À1a(Í‹,=ÁÛO±™u/EÝk#<è #Äf¤<#ÊQ¾Àr…°õø‡[˜#{7Åÿ5<½ƒ{1oWL&]yŠ!úÌ3ö 5ÞÛômâðo^͇�ÇòRÀ0îeHð:;íXã8j¯¹FôB÷é8·±I®=WXâxÐLỳÁž•²äTéô„ëgÎ`ó�K$¾A´?ËD3rK{¡Úê¶1qŒ tf«Ð¼†kЫӔC-ŸÇ]r·è[ìË­c! ‡j•‘^sk)n7K#ÀYÛ;Ì í:?Ì…g 4`û”“œ²*¦9]Y oíIp koÕRQ*’Bì> i%Zçï¨LgxéÇb­b W¨-Ü%FܺÂ3òâ*XæÆÌ­à¡;žml.cŸûq²ä±s‹®ˆë2QmûXf5žo‚ÞÅ,ö°ÎAžx‡¢Qßdgg·´âdÜ¡` ã3i—î¦"Cîv¯ããÀßKલ\zÓ®K•/Ò*®a—€Ie,I½HQRyRº'ÊΩƒÈ]‹�©Kí…{ÿÀI5$U,à1ºb¬é²ÎGè=ÂM'¡FPðÑõÃK±VÇ vg+xÈŒ+‚œ+ñ&êœó¤ŸêšD¸èqIÆ(B@'Óµ¤YèJÆô²<2KMb¦ZXꯎ�dSЯp»¾0Ÿù¼m‹L¢LëI׌®øª/ËÞøÎ;wÿÛÇôçùÝ?ý‹üà‚ ¤à¿ûQ+;ÂE__éáC«u!4íÁR ÓŽ†ôàÿ”ÁÍÅ ßOíq¨:ôÍŽ£:ªÓû¦ò’†Y|bìZË^‡=j¯.âK?ó8B;Zãß ìâ ÞŒŸ¯ÞƦ¨üÖÀó¡îgÓÿ®«BÃ~èg÷Aâ_¢ßÇpˆþ}Z‹8äõsýícøoú~ˆ‡%jCÏáÛØÔ¯¢· Ó=hþ{ŒÛØÔ-ûuú+Ðgt×:Tvƒô>³GÄç©Ç®âw%‚•M=R}’ÿÊ»öq"F%›qµßuwÊ&»Uç€uwIÑ»ðÛñá­çï^:#¿Ø+³—/_~÷Oÿâþü/W¾ÿƒ7¾óÎdÎ n:²Cúeå®¶]&Ó4ëHÃ�Í`u ÑÒѰÜËú¨x®ˆ½Ôã¥íÛ¡‚toâÉ$¾Œ|UѤ:6œÞÛú?¼v%7yI·QŠƒ½Û?MýA|€‘}Ý=Å T}T,cŸ˜ìiœ q›u¦eìS—„}9‹_ÇÇ,R mÈ4”vëÄMð[lQ`ÀÁ·IÖ¸¬ÿ•|vMKͨeûQ•Y•N<G2‰Ç i »CÜf@Fé,fÕØ—ö×p<Äm’3‰6iˆÛËØçÏg˜ë+[}…xtÕ{úØ»‡;D 1ûz¥#G‹ˆ‰PuvJ©ßõJHOEî|Æ—êòfˆ#Ñg„*Jíî3‚†Bâ.ïÚ(°U6nZq)ò¾ú’Ú#•}¨«d6fä-ˆuŒdcšã Ž1¸Üæ#%3öµyË»ŒÙ H“Aø§qP·´Ñ§Ñ·7,?!S^[hXB«sä…J>G)11Kú5XÞkó‡Þ;Ŭ4ëRQ¥”`qÔ{ÁF`1r#‹8<j>öqdÀÑâ³€óöO0ÓB]eì·5PÍ`S)ÄŦJ‡4tÛS­µKÛq ñ©#‹OJ| C1Äí]¬Máü¼û¿ðȼNp„Il,ãD)&Št qû Ó³.c¸±BV ¨UиhZzëEÌÎà eóìé!÷®pkØ¥·ÐàáŸcJ÷r†iŽØàø N�žâÚ)fHW(|6oG‘›xÄ Þž ÑßÅ,;·¢ÔÄæbðÒ‡«Ø#Ž`�qk?` 38}„›Ëа¯µƒìcˆ�L²ÎDì%ÿ²†ÝFûñ+xH-–»x§z¤KÁ&Õ»ÓŠ¿ŽCôØèc89B½„ûlÅ;jeçÀ~¯ð7öÊó .2K P‹˜¡Gïx„ú¨Ay D«Aг|‚ùðY]<ÎÕtûmcó ]:jï&̯p¦j›ØŽr„E•Sû2êXµ§ïµô“ƒÙ¨Ð‘í€’ŽœÇÖ‹[•d¿S~&¸š¢g*( xHñ‘Á¯¬ÑXÞ¥R³H(TÒ玙sè΋X¦‹Z¡£àu)³œ·y€$8`�Ä~جa÷ðW�~„w(sÎ:„³ÔG2…ÌR¢ž¡À î`]!…ªG¬¬ø%…âX´î”Ì`7‰h™È5¥øŒ>l÷ÏäF·Ê·L/Åá3L0¢Ç&ª»l^æ-èªîàÞ¦IÌË6þºŠŽs ŒÄ–KfaÅ©¤ ÛÁº:šy.=µ«®&™+1Sð1²6…sFºriCÜ&ë s[Ø`˜ÎÂgÈhŒ0qæ0w°.Ü#BhÊ­EŠ£EŒY¶äÃanÑ•(QÈGå‰D9’ \êÈ^ü¸cA O¬r9’•'Æz¼H™ƒÛ ÖÔ%¦J$X®ïšr¹%ëF–d*öíµ7¾óÎïþñßýïú—úÅë¿óßÿþ÷õÜIUG€u×_†S§§ñ :Ø XÃV›W$Ì!úµŸjÐðQm®$Ëä_?¥¶{%M•”‚åP9 qmd×lé8 ŸWDPUÛ]â$@­LÎ(Ý-àX¤«ìºŽ'Opý Ósx¶åð@л€CQ×và›³í-célis-`›�ë†?^e¬ÆñŸb›àºëêkËØ'.ßCF]$mÏ®à}R !hûœ†èðà Þþ]üòò¼jÒDp-c>:¥©?I~E7%Vx½¦L¨}=IŽRQ(Å,®3¬ÓcÜ`¤åŽaè¦ ( 9¨ÐM ׎¤Õ;Ò\ô?ü_]y\fhZîú"£ÀÝSÐ û|I—6ôñvšô‡öI {lå5J÷²5'\Ú0{¶ã/©Â/TǺõg¿Y]ù‡_þâôäx¢ÚÈa( œFV<#=j›é"xßã¦)ÚÂDZmij›-ÕŽãØêam;ºš•dŽ¯Ú¶u*ÃÖ§Ï%<4ýô«.ÞrÜ ;b‡~©¥X´„aβxi³‚ÊÏp©emŸmFK8¨ëÎÇA‚ńަ¹¾ƒ1aE@á>’{1_§αÓK ª„cŽ–³,IЈc¬½c,„XTÓõ)ù ‘\Dj±fNò&1È‘ûw–‚‚ìcùî=ÇUº+¶‘—’™½>†¢´¿ŠŸ«mË;Ü9œØ CN"q©íŒ}o¾nö1dé—LN«Œ¨ÐÂbÁÝ@CÔ.ãB*?Ñ,É1Üá"0ÄmvOó¡‰�‚õ9¹6’“ËÆ+ßáõ« ¹QÂSŒÅöðà„«µæÈ°ÛÒ;aÈÒ$/³‚®ê·˜t”ÖNÅ2D?eÜÙâ³ÈI‚/ʬ¾¡i$-ç­ º@Ûÿ²‚ Í>+™¾v0‹bûˆ„lPGžYFÛ–;vÞ?Ói¸ncÏ>ð ,4uª"z°RF(DНVáÍ?Ìa§ ¼²Ô³ÆCšD¾riqAµ$= 0¢Ô:kE[Øà“K\ ±@ÝÌòÿ�ÞÇ{XZÆ>ÕÙ¹ #-!DÐP‘ð‚‹òs\åúHÅ V¹£˜B.ؘìDí°dkÑ5<e&r‚Ù§¸öC|®îüˆaÖA²=-áà*ž3_÷>"`Ú…çðlcòP„°4„8Y¦Ø<#*IŒ4ŠÉCæµSŒ­@Íp8~ß?Ñ¿*¯È�O!A;¯ »Çš%äÙÁœwtÃüÖ4ÎúØ`ÈuÖV¥Ãó«©´\·UŽv26­ò§pÊz#ìñ¹T4 ™Õ$ùaº¡¬£1Ö¬gþe0Ÿ¼Ç¬¸î¿rÌÒ“FÁ0yßRAu§¾UìUX†n÷¨Å0ßu–ÎÚ­ô•è_•çm ½Ž,ׯüT°]þ]´ë~µiû×!RXªW¿Ò›ªÓjÿ®û$ãzϲؗÑue¨nÇ”÷qí0î.0:èÛ[<4áÑÖç0aØvü7殟¤ÖUŒ®³?Á›qã Þ|ŽßòžÕ~€ðkþ¬ô�Ù¼ZžZ€uݸáÝÁÝÆæÏðmÞÏ"P¾¾«çã÷.´½¹£Þã†îÑžam¤}ÂCôÿÓzAü.©³è+ž·÷[ÓÅè9Øê¨ûµ© =aú»í.Y D¶àL3þÄt|_R¼;²v‹”†-›þH¯Þ€ásÜß‹uŒaRSÍ%ßÚ¾‚¬ £Û'Ö±<»êy^œ,¿/$¢ªt¡Qj»…�u»6¬â™aÀTW[M3àyåLÒÚÝdñÔ3s8ª¦¤yçÚÓ_“Òô]òªKg,-pgML ×EãÖ3ÌMãLmU(YI·…—&5µÔ:±éªuyYK_a�Y ¬*1—ÀצY#žPEµaj+”ÖsºØ�Ó¶~ˆÛŒ |Á(*-ÖŒ]L<O žW°ÔKÀKÚEO^‚‰»)œ¯àC&¬ôØTñéeµ@Þ,?¿„%KÒ‚bÏ爞O¶Jx„‘ÕϬÞÜS°+B #=jx×ü¡u&råjæYI,¿PÇá!"“á€╹Ÿ„º…o-jrÉjW‹îâSÜÏ—QÇR §JE§àÑq(d7¯SŸLSmµpzCô£ò10Ñ#®T]Yƒgce”P²ä^ªøY¥¼75;è¸Ü€L2¡š¼—¯œzÀÉ[ÔûeùYCbÅ‘é8f{ža޼‚[Ø‹¨øB³ªJw<«~#Á±8Æp¬ÑÂ|à6î›®˜ÑRÞI%‡ÇX–€â{¢V:Å •GØ æ²¶ŒØ(zð«FÌÑ”¨]É,å fŸàmÒ(ðÚLѦ&Uölñ1ðÑj@ºç9Mãì1n1o¤ó<E´ßÞ'ÊQSò ÷p‡Íd¨»X;ÃôÖ¹ÿ“ê)fHWO_ž”™1)ëñ²èUáy¹Ø˜×5ß©´=abóQAªCÛØä׉ aŠ2$izwo; BƒxCŠ Ø«%éP%]_Æ>Ð|7¸ç…â#‹G ùbAmÂ|ÍÊ–ØâåA‡¸[yï-5ï/3+8)cV§‰ ÎÛMĽÉ<ë0ψ0Rn‹:Í/e‘;º]îžÉw–ÍËcp¿rgÖè$ëŒV# ð³ôHÇW]ZÇöÍúË%+„1S$i"=L¦Î<k$Ú…,¹§ŒÓkÎR‘10sõ7˜‘ÛÆæ¼©œÏÈô`FÕÑÇ CÏêóJe9ø0¿Ánþ¼N)$Ú •QEÔâ¼°;R‘¦½N‘kèvÒlXígÑõ8GF*áÿšMçt·ôYZØù/t)Dfí2>”<KŸrgLH8w1tÙk½ˆ“Åó‡“&u¶,ÔžgNW§¤âÐYdн²¬àdä…Ã]Bkh™FéN|ƒë«¬Ã|•¿*âñ™‡öŠ“Ø¦ü«çë9„ÏBoÇjð²Í`m@äD2˜÷:‰é*«²lD í•â}ë~GZb½tYA'¢$ø-6§ã]¬ 0²_ÍøF o|˜ÔÆÝÅÚ6î3AÄQs-<©ùë >t¤b@öH[G*¿<|?!€ânRbx„5G�<ÂÍuìð¤ìL¢šûuü˜G ¼e ©ˆÈ$ Õõ|/Fè~pì›RcÅÓ Œ™B™°㎯J¡‘_üü"ÆÏ0'jsJ03?¡‰ö>Š<<•G†ÂRyJSýÂÌgð ˜üfÛ¦c¾a@d·c¢Õ"Š8NÚà/xL»’v¢±1Ë’"Í´MYa˜¯VxÈX“+ql—f+±|ž×Œ½YZD+ì m½ß4 ke•> ;vÁÖ¶Øç· ÄY‘I8=¹Ï*M§”t·†âP±bíè5Ãó´£"Ûie\¥ÔP4�¶[ÚTd²îô÷‚aelʼnµVöFikc¬lj]Þxß±Âñ *“n’Nü‹€…M,6$ß½L”’†Â FL>Ö-lX0ݬï\Í… '�ý ÌÑ`ö ӄΓTwòó 8¦ÎW|Ïx,]ÅsºØ<¤2Ó–ÿ ÚdzP©Kµ(> uV±r&—;ô1ÏEDå.Ö¸m§d¥Šû¡šAº[&÷ÈÀ€~.Á5… CÞépãðÏÅÑN ߎš‚ð�K|Dt„Lc†·Ø°æÏ“iÞÛÑ”üôÒNš9¯bk»¡È,4e2@ B÷µŽÁSEöµ–¯âú.êP;¤€/6Í*Û&EÄ“¦¹A[kÝ‚]F9CrSÝ÷…KÊÌjj1¡; ®LÑçH$Öiu¼Ø—“ìpÝÖ“hH³g¶Y€Ÿ¡k²¨?‹µ=`OIlóôB'#—3¸g´•ìåDHdž½€T·{¿—Ó<Ùåi½:(eÛeZ ¯ôÍf4£-¢ÏÜ[“Í˰mÊnþ§Í<›�uú¢rY‚ò/ü¤g&3ˆ _¹ã~/: þóéãƒÜªÓãFch8À$kÇfF(¬”`–ËqÂ꿉éú,A—&ð'æÏÛ´­gíœ#x"Ÿu'‡Œ ¸n»1=Ò@ÝMûgÐb{#ÈŠžù̦¿?%Ç wøp³% Å]}©YÁ*ÅA¬fe ²ö ¡’&'¶_ˆ¼«KƒÄȥנѬ n¤xü{—ëöŒœÒƒÚX #¤6 ÃnhïSiǤâ-·QœÕe°3:ϪKO¦Ýô]m±‰‰ˆˆªµhdÌ* ÖÀÚæô®ù±;¸Ç…o9ÙíÄ?›„ÐÞxŠkd,|‚7ûØc^qË‹/c_°*.b¼…»38UzêSŒ0"zèi¯=…sæ2eÄa?D_:¼ž,qĪÉ!×Ä.ÚǸÅ6^ª­‹ñ™T¿Œ«Ç?ÜE•¢1 . ¨Â:?sªJIix3 ”Öcvî+æ© ·<¡G26±™Ø†¯IHx†ŸÑŸ§½q ð@ivÆ"1…Å$&嘳Më§ÑÐäÕq­9*l㾓Ý0¦d,§Âä ÿ’F?âþ¨\þ˜K¯„‰V>ÝÊ‚K^Õ66ÕÙ®,Æ*~ëËŠ±ÐeÝOA€È‚¤NËB&P’E'o¡»ÝCګщ󖯈„ë_t`#ÈZ=&é•ÔÙ¼[ïÂ=.w×E}ñÖdº+€XÁ?ò/Œ™ôŸÅð,?EÄ´¶@ 2 H‚÷þ 2 +ÉF¸.Fm[Þ•…˜Y|ÿ’©øåñçxh¾©¯í¤pHÿ’ɯtg¥"›Tj¤¦Æ’áÔ’C':J=õ$Ñ<¦ÌÂ:Ë…‡J¹rMÇœ h›ä&åfò¸?뾚nvïݻөÑYÇŠ½¢KYcO1‡ßa 7¨ÔB/J‹,~w†±¬Nu¯CÕ?µ)SžG¦i¿ák18FÏ™ob÷ÚK#¹y•¨‚Â3àÜ“.bL¤27ËÜ|EÝÜw+‚4ªø$ค1–µÚ4ûh± _ÇÇÂ6Ì=GèsRMŽ RõÎ@ö JL]áÚŽŸàMÖ~XÕaõî­ÀQ4ÄmòÌ+AÒ *1‘eƒàéœÒ[ƒ{=‡g¬ý°7ƒSE0;°HÃêc)áȱÀ؎É‘ÄHÒ:Àh€ 6ŒGâ*¿áŽŸâ!û*Ÿ°¸²…]¬±'R”ŒqH I>P´…€,\1†Ðë#ϯZHB¯RYFG˰) r•ŸÂVmOÇ¢Œa 'P¸T^#ÏÑ8†J„µ¤6<¯Ø­zö•p"]¶*FÃÂvª ¥®SÓxl±—´Oà¶âWCÃÕ­±Ž^ÉîF³Ð `Ü_=ò"Ô@æÓÝDåÀ›”I³öÑF<• ƆR‹/ÙëóÎ@È ÆÜ`äÝ î/  QÇ8>šÃÖÍy &ooâø�zTÌD…"×üÜcþ0œqÝ7=o#ʼˆ×ã2V³Ô£œ‰xʹ‡ˆ'ÙÒ+3)§òµœ a©ø.*t®Î»X{Škâæá~YðBÂM©šÁ£)Õû·A\îù3`I$(zI6ü ¤C4cäÖz™<ñžqY×êIXc$?ëVÙ%2øh «ˆrÜÆ¦xÙFF „¸£Øž¼ˆ±(¬¨•uŠeÆ‚$¾"Ç« ékBlìÐÖ÷AlR›öJzúc­ì>‰¢Éº‰D™á´nÎJ˜eí2&Ù ˜ ^a.´3ÊÁ&-}µ\cºþ´šÂ‘“Éi¾‚ÉǘêEôĸ>‘±L(Øq x!lišað s“âÎRÓzÕ+¿ û—¢-eEñÞzaD´|y«|…CôÕ ‘ÐØÓèÎ /P&;"™ßã o»þÊ{«-ܵ«v >·QFœØöÏ»÷õfxFÓ誺ÄeT&•€^êm G”‡}ì‘Ê+ A€kؽ†§që ÓBÒ]­c§½ŸáÉØÇð Þf §=¾_JÔG4Öֹħ¾MvÎr(éÇÐêîÂþ0+°É)¤Ê_éÏ1åÕfHe‘øFâæ§p>…s‹Ñß”gN1C®¿7ñè³ÑäË2aàÁCÜb¬@¦MÞþ6î«ÕZ°xŸÈüú:vxû,¿ioç!²ÔM‚ÂØK×!ëS«µóFCS[Qg3`â•jHkØe<JdÿŸf#a£‘2YÂAè(¶é zÍ`&X`/n¡mb‰Îë&Ë"}¢·›":QP¨ù@»NF æ^'0“µ·xûBZ¬W^ÇÊÃoáìä‹?¡’ B“V³0é/“цݦ?—ÙÎ*U¾‘±KÅ$ž1tqnY3©ï³Tû$ãå´:uǤjâݯ^Q­Èu‰ Ôcg'¨ðZùy¯îxmfˆ> TN$¨j–Vì@¥ÚU·:ˆb¿Mפwž½¶×BÔç}Ǫ‡9ä¬áÏðíôÆ‘ÕSu…ê#ΦOV'öêì$šM¤H¿‰EÊ Ó|bQÊ'‹w1{]9|Fàzbu<=H‚WìLööìÙa3ÂF'¥¼¨dÕ™œK¡KwЗ�ë‹Ö±.B·ç1lƒÁ=‘­ïÙ$éPm&N%[Œ²Ñ<©ÊÚ'@¨HÏ›×WcÅÉ|dB‘éÔô8±l\ZäÅ„}€†ámІÃa¢pn -ë\Áㆼ:ñ®;”i¢}§r3¤«p7©ïŠ"¶Ë~Ëc4‘A<2VÇþd˜oÝ”a’qè3º¯'x3{>>¤}9ξ˜4¤®¨¾ˆKÂ]f6ñ»ëuÊõPw²|uƇۥØè¢Ÿüh„øw©jܵø½_Ôs’M[ßìv°Xz»};Yt;hLB‹”ÚÁ—é±|ã©'î¼,/X“áCÝíLfe‘ &$aÒP«;[¼zÒ˜Sñy3s«¶¹Æ$ôc~®ŒhgÌåuWzæ¾”(\ðpĆœÝ#i5Á0Ôð=„%©ÞÐ�� �IDATÂ~ÆAƒ¾Éð>ªlk’ H}XÿyD¸͑¥ ž¼ «3È“Þ †}òµi+OÒX&g)׿eäUٸ͚:x¼¯Ûñ:µGœ©cä…]ÏÝm‘ìò¯g·Öõjæc’ýPFÿ‰Þ â#[j-™v¤! }㛽ètL`ŠéÂR|Õ+ðXyËÚ° œ/3ÔLú3Û;¬™’É&^ÇÈzÖ/¤^ô9µåH©ÑJÔWzñ±Ñ¶l«:·®ªZóQ”®ôuwŒ}¹A<d% WKO/g)k•HµþPÌé=öT±MG�0Êj°æÀ~©œRÇU(JA»Á<38àA,G=ŵ!ú$Ñ`±$쥆>TïâVD‚“¥·„“XOâWˆ×XÃîÎ÷±L={IÎûIu öTÔ±"(�P¦òžUˆÜ÷X7"«€;¸'þ>4qEKP‹æ•à²ÊÀç«ð¶'Ô_èÁWB¨GJ+lÈk ƒL½geÎ\ƒYœ¤Bca1¢\gÓœœd]SòÁ!g\{d&7•c1'å¨B`ˆöõôŠÕ‹Ôg˜vÜG´OÝÊFÝ¢,vrÌHÁ+îº2‹òÃB v8òEœÏÁ@›ÊtÏ‹ßz¥È £è›:bóÄEg�Óì´½rAÝTu¶Zã…’ãÑcú54É\ÂÒËÓqÚë$<Ú€°{ÖX¥›£ª“í„ÉÀÙbÐr5­F•¡<.7À½}¤Ò†f“ÀΧqÄ?-¼%m?o^"WU¢Þ)¼»‹µ]¬ž®¢7 ïìáåéÈmÛÅš0o»Xí:=W½×ñ¡ úØ#c:ZÙâá–Øö»„Bøè`HˆÞ8uÆn6 J~wÕÛÂÆcÜzŽ«dcâgôcÃÒIÀz{Tb”6݆Ég·Mµ„Tª¶!8çѨBP"hy µÊÒòÉ+«ö|ÎÓޭô‰˜o5ãûÌí°ÃÔñÝ–Ts\ÊÔzIk¢8Bå,3âAX‹1W vˉҗpsk+38Ê1¤ cC…xà‚&Q…«qKí ¼ ¾>¿µ€ö{EÈ‹.Ò]uuÚÁ×&¦³üuZЮ»ð 8äIö. ‹²ØVК@3?±Ò†Fe¼ïÙê4䟩ŸX©¾ärŽ]»€ï?Éûé ŠøÜ8Úg€×ÀÓžÜæ“J0v3EH:“Óeíá:xF0¯ RÖãÜi­Uó –®M¨¬\çÏ!ý§¶›eG?¡š’±.yn¼KovQqÚq ^%JÛ«ën¬[#ô gOdµmãèó餞ТÛíÏM»°ën:ZCBSÕã´Ï:Y4À2ÖüI-ϵg†ývLuå¢G±/–ÜS3ߺ%:šRM­…DµÄob›L’ÓZÍ€LA¨yBû>ßžDÓIÏ3-j$t"Îì:µÛâ0òе'=tªÕ.£N©-Õ÷²#V•kšÔx€÷ð>‰øØ1ñr†i5º…ÚP˸CN&«cAÇ},a~kþÊ”í9Å é „°àAä·±ûìaº†§ ±@¹)ò?±ù-¡8(`ÏM[ìHè5”ê®38e88…ó÷ðþ·ç1æ©•‰R¸ïÄNJ‹õ1 ÂÜ&îtyûˆ`æÕ,aL|þŒ!"ßÐ"ªE.à»E-‚}7éÐèPì9BO†ºø-ÜõK„œfPR ³eš4ÁJNATÓmÂ%ˆtY:£( \¯Ki0Nr©FeöØ6 EÉâÂF+úˆIE¯#B/^ª¢|…qúû ¬?Â<Û N0K2eß.t8Š}Ѭ`3FùšI½ìzÊþ«iCWbÓF3ØöŠ+ÛÀùz«®IjK¥æeÒðJm³K#ºS‘68·;GÅ÷Œq#©˜.ê¼ñ"¶¹>‡L³aÝíÒú­y$„÷‡‹Oãì}¼€\ækØT̼|RJ§­ÂÌP±ñHœåêñ2æºy®t$‘ÛÆ&ýV®`*i¼ +^T¸ K<é38ZÔ‰ÅÜà4Îxý¢JáÅü 8DgüúÖÿ<ÀƒqCÀÑ,v"2·dr“ÁâÑ '2ïqXÒWq³ÅÁÌ~&.¸ô=Ÿ¢{ÈG XC¤Úº‡b‚7Þ¶6¬ü¤Ë®Ñ÷†büz2Ñ”ÝìV-…Û\› B¬k²A›IÈSÌ8J#¼ãâ3f7^gùj®ß“rÒ!RǺ�&*o3Þ’ìˆí6êTô*ari"õ>__{Ü÷,áà:~]©¢T…Êý‹Øko|çßýã¿ûßÿô/õ‹×ç¿ÿýï+¹,=i$šô ”:U¬‡í +O+SUûhÿŠj­8½>Õ³¯`µ©ó¨µi5oïWO­"Š´è4ĉ* nûʼ¿K½oâ[¦çe£&–]ÇÎ r•YÆ>é­âjw•+r‘{ýjÒéÍÛŸÁ©¤Ö}dJ÷]×¶†]aøî›ëËîŠXv€Â5PÄD!ø=ÜyŽ«…â…ñ¤³8¹‰Gwp#WÕÇh„>¤~_º 1€ðÚ¨ßq>†M¨¶Ûk |ÚÙt0ÅúžÏ‘x2Pԥ閉ÇûVÏ6”œ#«*5ù½ðàCô¥ÍAòJœZ|"E|S *¿…>}31Yò«õ×´†]^ƒbS)âQËïeˆþ¦§qÆ÷®oéàñ LV3–0Š^7»¿ÅŸ­$Å~eVðÖŸ=üfuå~ù‹Ó“ãOÐ ®»Ü¯™z‚þ5ÓVè*}x–<+>¥Ä”èô4`"1¥oë: ^‰P²×Q²*]¦…šuYu䀼ǫ‹Ð½ìe-‡D; ½C+Ü-xÔ&Ú–d4ŠR!vd¢·^Z: ß¾êXªN8®î=ÔfWîR úV·wÕk«ìèRe%ÃÄ{‡r¦gá£WU^#üE†½î”—Э“]ÐÕ>1WWAJS;Ie‚Bw·‰Þ Lm Éi|3†CóöðîéV°¼¯@ ‹ûš“å'³‹,ué2Ó]a”¬¡°ÛÙæE¾LƽÈ<~‘:Ö…œi‘HRui›““5Ûw†xâÈÚ$}Õs¥¥t€f5ᤩùb&é¼®›5¢f^v’§tÏ”yÍKê·:M?uª–„ay‚Íñ7î³½|¨½$Þmã)»»±­kl;Ƴ†kP¹u/•ŒØæ,4GWmÝ ~mñÈ7‹ŸHé’{¦î«»EHçHâÌ=áýˆ™Ü”?OïzÅNxqQ¯ÕDNú.`Ä! +»Á¬C+õ¸è(`!cÖ÷§=±1<Ûa{o¸®Síç‹7v™b_y‘A"7X‹/Ëö‰®—£|‹à ‰p”ªP‚ÀÚÖiœFå •-Ahz_„ç*áÁ¸’ jÃÑ^óTܯ“µhKMî½”ÆQV#µê±Y)ëÒ% „ÛaÖ O Òb³8!˜¯lˆ>é\Uƒa‹ÿQþiÊ!¶‡`T•^÷},oá.qÉìµbþá' (HÓ~Ž)Uû£ÆÃ>‡šà{3<D{?! < NÑմǯ>hˆh�P› =J}踫¼’!݃†\¥¬ž]ù xÒ(ß6\Ï}j³»üJ™zê|âéFR£¾‡;Á@_‹q4:áÒtÖ½²£Ž”¨p·ø,U¼x#l~Ú‚—Á¯¯a—³nΞJ\â°#» fFEXsâ«!‡q§<…v'Zˆ°`Ñô³ûXîco›„ÃûvSŽõñïæØg¶‰1V–Í@¢+Ónš2Ôrš@«'Š]eXÞ,j™ôë≠Y>‰B ÃÁN°XO<—,“òcvºñ‹!…>w\œ)£‹ô¼M£hï¯ÃFiÝÕö뙲7f&ÓfÉê®0U—¸ÏSRé~Æ,Òʤ§<˜ë¦ûüqM’ÿF§#¥N§'²ñì8òîf"@ü"¬Î온9žÐdìSÝÓM$Eó؉,V¢ƒ¬³“=D?tG]ö`v{ˆï¼\Ù@R<͑ӥŽ-K䥓ÍǤ¬L±Ïc¨(µÆ==CÚd=ð-§{È(ˆäXTcƒfH ´çóPÄÏÖ¨ØÐ*‡HR`-¨ZÍž½n62“{ãV¾ÉåqL} w±FÏ\]í¼t¦ýlà‰kI‹Ñ'6OBÏâe`‹®Pd&ÝcÓ¥Ðz¶®÷±¬¬¨N1³Œ}…ÎKP˜@ÁÛ´ÖÅð·¨í«ý¾@ˆóÔk¤3Òh|,âp DNGô_…^mM [—™- lÁšCjæ%x?†tjS¨L)clU[r™÷B1vÙÆ}ÏnùK4¨…²•:÷ùÌ5ðÝN!ú8¥NJÍ `âªá!öø³"o›z\ºY‘•0ò7ùùëøqà *D/ù·O0Ëž_…žl?_À1ó@Ô?£ÐÚv© vŠA:·qŸðœFW¯?usØ_ÁéàŒ¥•øsØDÕŠÍd`ŠxÖƒiV!5¯7¡(°»xP8ç Ÿ‰.&Z\6 9“Ç6ÉWEŸ¡¦.´�MÞO`!§ð0½Jí[*¦ ׫õBpü ûz%½˜É‡öKiÅxÂwÍõˆ,M\g N=6Tw Ž'Öy÷Åä´„ƒÐ©•¢áfqB² „´•–K‰†(­D³… ¶pèÔg˜>ÇÔ1´“ !‚Ô¯â Jà-|Z{¶­iÒÔ<×V)R¦tcÁ¯C:N ½Ê=¢Ë¥j�Ö®–~¼;¿4ü­ƒ¾ánôGJïJP=¢´5Œ¬æ<_w–÷p':ؚ݃uhp& •¬¯ÎY0”,ås#·Ö N%3Æ6Í>†j¿ãÈqmIß Ñ-Õ�£Yœ¬àCŸä^|\<ˆ®¸æÎàô Ó|•ª5,à˜ÍK8m§38Æ·Yqk÷×°+�'e3Í­bŸ;+ˆ®ˆF&aà�˜,[8I¸“¯Z·ž„’¨'µî£Cüœd3:ü¹µkŸw‘]†ÐnªÊM6Å.ø"¯™_¾¬à„÷•ê\$]Oñe飯hAiq™¦»¾••î3X®Ç¹ä³4`7±œÕðÓfþÉ,‘(Ò^Âé}3pRÙõ³—dö<'ÙÉ(ÔÌãÚ[Èà=?és?KÊéáû«Énª›;½€§¸%qwü…ãn„ü4Þý.izÝš6ˆ ©Ò8ßn6̘Ós4s[ð¤JêÑ/8Öt¢ÊIq@Ÿ5+8¡Ë2Ò¾Ú±šcŒ~ðÐÚ˜ê´+ù•¡˜òÖQ[Ôå>Àûœ¼æÜÊé�Rµ´ºó]°ÂÁéŽO—Úã,²†ÿnНòí°} ê¬q—6̪;oP­šµw kS/¢¿!nS^ízq‹¡o{Õ¤ÆEù[ØØÆýiœcaûûXæV]íbêÙâ6#*ÅÙŠ<»Ŭ&{‡è0zŒ+øP=aüz4ýˆQb5œY#Ûr°=X[\Õ"æC݈h¤OLŸΪ§ó°)&h"#(¼—ÑÏ¥ ïÚÎË^:m›v(IÌýUËgTCôw±–.)Íw}v«CÎÖ ?4»v¡Ç_Õ™çÏ€ž’Ó¼�Xש"HFr# žàÍ縊hgÌtŽ©3L3}Ž©«x~÷ø-ކ\g˜f ޶ªÛ¿ôKÄgðXÞÕõXÿ5^ð`R×!:£¼»H¹ÏÈ]šOƒI>/_îýÝ8ÝÛ–I®AÞÜ'/®•~ÙÞd¯¢%KŒ»g}Ÿ‹oÖ×™ŽÅËËe=—•5.àX­¦òËØòÙfA÷î]y¬ ÅGGÅebÇS8çay(oÎp¿q]‹ßÃV>¼SU»ÞŽ \½]î'u'ɶ†£ÑgYwOfᘾ“²êG6?QMô=t´éÈ„·ÞgÚ=‡Í/w`Ý6äÖÅò3roj›Õ Ndz€ãFjÑ•²"P«¾òl,ùc¤k¤c oæÆ4mFnÉ‹Õ~„ù!nïbm »ìf/~›=Á:v®àÅs\UbзPÞöη#ÒdV¼˜)Áéž±³Û»›‹Çú¬ë·&V Ô»nåÐʈÒ+#ÚÚêܺ+å»™û°C£0±êZõ†."‹„X¤õ ?Ù\BÞ¢G¤©ÒËØˆÄ]©ˆ¿ÙUE ·“x\i¥;'=‹ê©.vá—y,&j2תÏ…&«{‹}G.a²Rå @ªRˆ:][cþ°e2‹S‘dWðá>–ÓáÔS«YÞyö;¸·ˆñ2ö ýÐRÉÃû\O0»…»~G¼l†e,äoyò1iî&R½xLjž!ë£ò=,{$Ïá¸g2cÝ+¦-Â@l73`ÚàÂû7²9ÿ”P¦É»¥ÂGÄ«âe3zFC+ÕžãÉW¤.¤»bvq„Õ5ì®c'º£öX ZÄ¡:"T®æÀ ë?Ÿ ¹TSŒ2ÕHcfk¤%¼†§ÇX"Ÿ•0òucê÷ñ7ì… c€Å1@ ;qö7ñˆ4üÇX¸†§'˜ÆÙ2öùÃ>–ÃÞ½Ð5½ ä…µWšQŠ6Ô™Á1‘B›Z,,qY±¦ ¬Œ<öí+Ϥ"€°êª)Êkjâi*ºþˆÀBœ9+øPXg¹Þ´W¬Ëèn+GdxeÞåWÒ@ªò2u§±ú¦kåýü›ÅÉý%<Æ­5ì’|V O ”µŠ1«3DŸ‹)WÆSÌÜÃ)bॗYÆ>¿(E(Á‰ë“À’6Ur9)e;Vð!—$ž…êY}ì`ɹÁ”èCK¦W…Ö×á«ìDä¸UÜÀ °¾ÊrV¦Gz­ Pb»{“Vš–)açjãÁ«ølE$(À¤8ˆqRpæÉ17ø,BG`){ú|À¬äÛ½¤‘PÃk¼€c2ÒÇ Ä1…ó¬3éz‚Ù3L󤤚$†“Ñeì`IÂc|ûÂø‰‹š¹‡;×ð”0ˆ¶¼'x[í˜S8_ÂÁ[øh;ÄÎáý%sŒ¼’Uò~_à ƒ¹g˜cú‘¦Ç^°‚¯Æc… NO;2!ȳÑìnƒúlœØÑ€<ˆ¦yw`Ž›B Æ­ÍùÕ…)bÝUaŒKžyVX¯_EÖm80È4kÛÃÎŽÖã­*‹êö¦=f@¥›låÇ ¾l–öÖ„€Ìcá�K+xÈì_doæéÏ´óµîÎURºMãŒì´'˜}„›Ê\‰wŽ9œg˜cý€5'¾;v›¦‘4¬ÎÔ¹ЯàC9 4,º›ô^¢…ÕŒø!¾g{šÊ©,òW¡%Ü#_ø@«•AÃ[l'…Ä0·°aà¦J!T¬¢ñ£–¦ekÛ7Ì¥mT‡•ЏN`µ±f00ÚÆ¦4W9‰8B†ñPdzæY+5Ø®a—û?¾)QìcAßåƒÝ† 8PKóóg˜^Ç ޵Yáís Qösköššì;ù–±‹œ>æ:>~†9…PËØ+¶KÆøé3ÌMãì{øá9¦è¥Î1Å8i Ó8»†§ 8f\ÅŽõ¬cˆÁ)œÏâ„YD–'½ ØòX[Øp¶=»öÍ]š¸¨¥—¦×!ÎfM`ãÅ€Òn±ÛºßYJÚ<©&¤5Üf�ܨjFþª7åÈ™™œñ|œ´Ö„´Ö“,Ç•lrMM®f¶'V®ÞeUÂ(«oa§ÎÆíŽ|ª“+á¯g˜^À1!«;|Ý,<0ý+’u] ×8cõî  òž)þÁâ°&+.¹ƒh7cø¼›áw¤ÐÇžôÉ´ â¡D\eÍœAÇXPÎ@âf †k÷2öõ ¸Üë~½œÆÓ±åHa›ÊÄ*ô»c/Üžb†þ€ÃÝu]åu«pÞ’?Šàü üT $Ñ`ÀÍm oDApCF$Ü•rcº…¬kð7Ô®ÀÈì3ônj浌,c?$š‰L.‡£å&-á`Ëd¯ ;€ïᇋo]Åsz,`‰[®Ìqû Ówpï Ó/pE~‘uÙ9<;Ær-NíŽ+û\kcN³Î£¬¼R•ÒÆ´)õÓã‹2¸&OÇd rü^“sþ•ÕŒkY;”¨ˆô&ÀºÒÀõÄ€ÀU�&òZ ^“ãdK‹Õ]aÉËé·æ-«<ªiœI]ÁTÄ÷Ë~[~‘s[ñô f¯á)üíPÒWù�ß±îb-Öbµ÷µ;¡(!Àå¤Õ2,}Þ€œ%#“בÉzÏñµ¼*îÜíiáŠj.|žAeºrˆÛüz ¢+ï¾PÛ×úg˜ã3‰LFÛ³M}M” rÜzR£ËÓ*ŠG•!{�_åÏmOÔ)#<êÁ¨€úuü5›5ˆïÑgGÇÍ hÇRcå@-ü5$Áª<dß7ϲ…»|¿|Œqj'­d&ûº‚¹ã ^Ð31´aÀ#ðÈÜ’î`ýwñËVéÕ�<ÁÛ XMãìî�¸‚ùËØg{ß fp<ªXÁó2Œû-à‹/à±|k)¯*/e½o’«Qê,õ• ¡iË8rnµ•‘àÈIËX\UYÆÞ¤©R è2}u«ýgE~¬´yK¿“ŠÿP sl‡i,8¾´YÜ,ÛN|ZŽ à NéÔ|M4ÀƒÌFOÌÀuüØUÞõ±·ƒuVGFp¸^ÃS~LjÊ?k㟶7#.÷L*ÆÀ«c÷v¤|„$´>e«@}??ÅŒâ!o) U¹^¶s~AÞšÕ/f®Â£¬j˜±zÄl˜zBx§\ʽLË1Þ˜Ý�èl\Ï^*\™>a/-×5h=®ò†ú«3µh—ò\ýGx‹p¾-lp¡ç=Ò{ÅRPdÈ�š.‡¿ž`v§¼ æúnzÊ÷�KOðfd «g˜cê˜5¶EÎáY€,ª¸’jÛ×¼¶#ôÖ±#NÈ߯?qû9®Îá€G¸É,7÷/på�KpsÇ<ò9¦¶°ÁˆŸ˜â¢daRI[äbŸÚcÙÔæ´öjS¦5åßJïƓ‰Q4TìZm_y#çe·úVð!y¸žŠºŽ°ÈêF©“¨E© øÆÐJ_™ÀZí›Sn?íÈ´«Ê¨ˆüB`ËK¸‡bò*%¸jü?³+hÉ›mÄ>–ž:À æ–Vm4¾›jYM~¬LðPOð&iOð¶2ÆŽs1ìÜ<)zEÐ�³f—£Z,aQK8à'¹®E´Ý¨]ì¨2á¥:uWðíNP%ØÚY\yRU¨`i ¦,‡_3ù¦<¹éI6‰k¬¸ýÏÞ €!n³+6艇¢×bÁƵ}ùO»Xc¶–Îå+n2®á)ó„b†½ƒ{*)tLJ9DŸ4=®>ÏO ÑÇÈ;ƒwñ}‘é<¸Oz?º‰GeäYœ¬àá2öyLV¿žàí¬Kô1n Ñ_ÁCúrþŸvŽ)ÕGµó '˜• Ù¿R'óŸ‡XÊd3/yá3Ù7:©;ˆÁã,‰ûÓ$×ç�tÃø å št¼RmuZ—bw¦Ý.ŽR ¥>öF¨Ú`Q=Æ•ÖÕö* íù[—¼ãÊH¤êγÒz^eïÒ’4s5…_ÂÁ–AÏ•a0‹!áÈKØÜB5M6Àá:nq±„^Å Ç™ ’YœœX£žjZ×ñãEŒGÉë«¶� ÞÆé–fZeÅJk`¨G¨€ÁISkq[8Tä±Õøvû.¡wÔ ${™Bù&}mS *ô15®k¸…ÕŦ{½íR—¶ò–á #à›N"�]M7^Î@Ö6>F±…£&JpŠr$�³Òé@“ºì5󽕌¦ûû[6C¹îßÄ£G¸É0ˆ&-<=Ë÷K9Mnõf°É>¶( ÕÀlô*™j“Û˜Â95BE¿€ã«xν €'¸Î ¤ki*¼žÆñ1øáHêbëôRg˜žÃ³¬³ak çWð‚oÍu,ã¥H>Àv´Ç¸Åîõ£¢žÂ¹vÎÒ%W‹}†˦eáѹAÈx£m[WGÂ}œ–Ö“ˆ‡“6ââªä‰µ´çÑÛz*åaüÈÞÑÅS¬àa*7ÊÙ°=ã_iJ/ƒå}ä O‚à_„°¨g|‰‹XMHÍp¦.á•N† ÑÐßðc+øP»oC¨¯ðÀ˜…m‘yVÚÑòUŽ-&EPÅm8EÙ}G¢˜ÃôºÆöw¨°á#Çÿš¼Y.%ä!±ž€!Ì ýÏ*Qй®zÍ m_ZÍ2ŒH+Ô#¸ˆñ:v‚®“ªÎ•P0¢¨Ž�®Í·“eCwJ8xPt6$²ÝÄ#aš¢vÈ'4]ÔæéEßáÍì^À1õY‘СŠ$B7³… ]ü>–¯ã‰ZôB#f“ ÆSÌÜÄ£3L?ÇÕiœ±rÆDh*›¢þ—繎0Š™kxJ©š3Ls€�ˆ¡XÁÃëø8²ˆUDÞ‡A¼RŸÂ¯\Á‹x/Õ.ÖÞÀO÷±ì, ^R-öù‘R÷/!vWiç/b§Y;ãµçø’´0¹““Û“wh”¾[ïâøÃ€˜‹ºŠ–FAŠ+•‚ë5ou¸*«9qþøÌ7²ŒÊs8ÖNQ¥‰S¤m³—v8¶øšŒQ)Ô›N«ªÇÎzcAmŒ£B>ŒfáÙŽ�� æIDATŠDÛØ §jc¶Rάš0¢§@Ÿsqr¼é28„ŒV|Þ�m÷‘®áÞ*VÎõ¬¼q„‰ 6O VoÏp˜xx ¿â](¸‚‡Ö˜±gYîVÏPº\ n‚ñh(lº¸*è3˜Ç‹WÍ„“®âÃ[艰œgdú”¨¶Ö’c‚=Lôå|•»X›Ã3á Xo3$ΪÞõމÇy¼÷–±O³€ã3L¿…®ãÇ„˜Çë)*Xð Ò“Z:[S8_Æþv•c¤{{„›‹8äÍ.âŽ}ÄL-šr^ÃÁÏ�w » ¤ãÖ5<ÝÆý;¸Ç;eQíuüDÕÖÕuìiJ+ñ§¶néÀ:hÂEºR¿]u«IWÈ4i2FNWîÉhU3™¥T#8'úìü½Nƒª®žr{Á.Ak÷zjA¥b¯H#¿K=}ÌdRX™ˆ°­þ]­Xdzê.[Üa=®SÖToŠG‡ò¸{©uWûÊJ³ÃLªÊ4N‘Ѱz¶3Ar7Ê8]ð_ÆB›<Ftˆ»hU=oóÏ8g3=ß®^°ÚÂ2(TêÏ]a<J<ÿ=¦ÇÖu¤È*+Í*±Üf:ô} Ÿã÷‚2¿v9`ŽG‚UCôýóº¯Ç¸ñoòÔb%Ö…ý ßÖ8ù¾-¢aÝ:Ùq&¦ìºÒιÜ_.|¸¿Ò>>–ª¸UäëšÔÈâÒ½±*W­,P,W{kð0_§ÂrJU³�+ÀPAmÚ’{®fˆÛ.Ìcmѹ÷ŠªC/öh­âQ`v딜°ù °jSxë2šÃ"Èí¹JÂ|’W"ÆŒ(’›(³C /¢HÞæî˜ŽczÊ™BP|/)¹I5I,QÚ‚‰ÙY$– È<<bÜÆä=é¶„­#°·ˆÃëø8Í¥#Ôº¡IÇ»9ì·Å È'@Á'ÜF~M0ž%Û›nKfSY'†Mä0X,€kxªDHHüì  Ïò«’ìK¨äIÏ0÷7ø}b ©;³„"&N0KðgÐ=Üa$tŒ&‘wƒÁ÷/ñ»ßÂßò¬c‡ÈEW’æcd»³yÓ8{Œ[T[Ãî௘·|†9ïSæ3ù�ïÚ³ú)Þxï`釸 IÏ8‹!Ÿÿ:v8B‚¸I¯c‡º$)¶Æ¾ª³¡/öëXÑí{è«¶Z;-?³i0'ß‹='اŒ‹sOHbÍoZ4Ný¥'þM¿ ¹ei<ðâÄÈ6בú“÷ª¢f (v “Û\¿ø ´ÞE$ƒz‚´§Å÷RŽ®Úv͸"þ[3œuš ,¾/HZ|`-Ô;]‘˜ÑE‚ãÓÒ^*Zµ`ØŠJÊI¾‘ŠãôÔóg]Æ•í$ϦM‰7<XC(XÏ`3•E—T*u¨†á�GœRÃII?©vÉìbÍIxG°YUiL$€´yOÔs*êáH§³¬2Ë+ø7‡¸Ír=вèÛ¸Ï"#k“§˜âv´`cgOqM¢+O1óÞšÁévçðŒrš}ìñcLúqw²ûWñœžæ)®}„·Ta:Å̦Ï0½…»ê)žÁ黸à ü”¹;�oà§óó[\y¶°Í«,:ÄmÒpaþ&M᜙€\ÅÏ|„·8ëy³–²np[Ôfc}A6A°×ð”u²÷ð~D{ û, -‘¹&a‹b—Ѝt¼i_àuí3‘›¡Gi5åßÕ´(©Fs?"lA üV&Àâª/UÖI#‘½»f´V’±ó¾/âpk~ ‚•4 N7ï[¤¨ÊVVù¸œyêÊXÇ’QàíæWrÈê3F!Òh ÷�­P}åá¸P;Xs0hÔ,Bpåõ0PIÒ™P´UWÌwQ!nÐ NŽOGÊ‘SŠÀq'Ù‹ãž5ØÂ(aް¦—’Û£?fµIH®•$‡"êõÑ«yM÷ÌŠÑ2ö3iSñæ.Ö¸¾3bSÅš½G‚¡ëMÑ#òQóQGj¦k6ðŠ]¬­àá3̱àă+üâœ%`}k\÷YaZÁC†X¢Oøâ5<¥wù�ï Kõ·øÖÿÅ¿ã@`4À_rÌì¯ rËê:>ÞÁúƒp·ªrì6ÂÓ7ïQ%prk  SK¹ƒ{�îàÞûx/”_ X±OeÔF|ЛLQÏ„�æ½; ¹VM›Ç“ò‚š][ZWœ“1·{žêâ-|å× =X;¤ : ÓñlRŠÂHt:8õLÁKŸY5u¥L7ëòæ'áwkìPKÂÁžÐë¨Zl(¥Àë\ã&3 __¦%8œ”“ä,C#£r±˜~âÛìŠuŒ‰®²!-Âßî…¹, Œ×<SðŠ´y+ ’.¤È‚ µˆ ‚+:”d;|j»¬× f×±ó s”>YÂÁ4ÎÞÀO_Ç_ëóÄ©#…Hb$Ýœ¾ƒÝÂC]6)ÙiËUžn‰—D¥ëø˜°ÀeìÈ’ÓÚŽÉãdzPT~ˆŸ4q¢yI“øZeð”’n$Ø›çPá¹èƒâÖUü‚QRC=Æ­<|Œ[Wðâ®èé¹àÙå†hýê:Ö'écýÉŸüIyFÅŠ+Vì+bŸ¤U¬X±bÅŠ}5­x¬bÅŠ+V<V±bÅŠ+öê,ç|íµ×ÊC)V¬X±b_{ùòå'y,y.à·âÿþßçøË¿ÍW~åA^ûu_À+ÿ ~ ÿªÿ^ÃKÿõóýå×uýú5ºæOw¯Û,ù•yíë6K>ÍA>ó ¾wþ3æJV°X±bÅŠ} ­x¬bÅŠ+V<V±bÅŠ+V<V±bÅŠ+«X±bÅŠ+«X±bÅŠ+«X±bÅŠU¬X±bÅŠU¬X±bÅŠU¬X±bÅŠÇ*V¬X±bÅŠÇ*V¬X±bÅŠÇ*V¬X±bÅc+V¬X±bÅc+V¬X±bÅc+V¬X±â±Š+V¬X±â±Š+V¬XñXÅŠ+V¬ØWÓ¾qÁß_ÿ¯<¯¸ý+ð¯å)”—Tì‹—»²â}%ßÍË—Ÿä±².V¬X±bŸÞ^{íµ_ã*ú Ïþ9õé¿ò+?yÑJV°X±bÅŠ}=¬x¬bÅŠ{eöëMS½Â³ŽC}ú¯üÊO^ôⱊ+V¬X‰±Š+V¬X±â±Š+V¬XñXÅŠ+V¬XñXÅŠ+V¬Øçµo”GP¬X±bŸÉ^{í5þà¶OÿÇßìé¶R½Â³U¬X±bŸm•×zªŸ?ýƒoDþæË;KÉ +V¬Øg°ßHb WrS/_¾ü²NñXÅŠ+öEc”¯õ]LŒ¾šV<V±bÅŠ]^wÅÀèëâ´ŠÇ*V¬X±Ëè®ð5ÌpU¬X±b—Ñ]}­x¬bÅŠ+öõ°‚n/V¬X±ÏfégÆ[^ R6ñ_ûô×üEnäÕž¥x¬bÅŠûlKð§ÿûW<øé¯ù‹(‰¼Â³”¬`±bÅŠûzXñXÅŠ+V¬x¬bÅŠ+V¬x¬bÅŠ+V<V±bÅŠ+öU´+øÍêÊÏþnýÙÃòPŠ+V¬ØWľY]™à±²(V¬X±bžŠ1Ö?üòåY+V¬X±¯²½öòåËÿôŸÿKyÅŠ+Vì«lÿóü÷ÿ[O1º•‰Þ����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/index.html����������������������������������������������������������������0000644�0001750�0001750�00000032363�11555611700�016257� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Binning and Filtering FITS Event Files - DS9 </title> </head> <!--THIS FILE IS CREATED AUTOMATICALLY - DO NOT EDIT MANUALLY--> <body><div class="mainbar"> <a name="maintext"></a><div align="center"><h1>Binning and Filtering FITS Event Files</h1></div> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> <hr size="5" noshade> <div> <h2>Synopsis</h2> <p> When an x-ray event file is loaded, ds9 makes a virtual image for display by binning on one or more axes. This threads describes how to adjust the binning and buffer sizes. Interactive data filtering is described, as well as binning in three dimensions. </p> <p> Note that the terms "binning" and "blocking" are used interchangeably in this thread. They both refer to combining pixels in an image. </p> <p> If you encounter any problems, please email saord @ cfa.harvard.edu. </p> </div> <hr size="5" noshade> <h2><a name="toc">Contents</a></h2> <ul> <li><strong><a href="index.html#start">Getting Started</a></strong></li> <li><strong><a href="index.html#buffer">Buffer Size</a></strong></li> <li> <strong><a href="index.html#basics">Binning Basics</a></strong><ul> <li><a href="index.html#basics.block">Changing the binning factor</a></li> <li><a href="index.html#basics.cols">Binning different columns</a></li> </ul> </li> <li><strong><a href="index.html#cube">Data Cubes: Binning in three dimensions</a></strong></li> <li><strong><a href="index.html#filtering">Filtering Data</a></strong></li> <li><strong><a href="index.html#history">History</a></strong></li> <li> <strong>Images</strong><ul> <li><a href="#defaults">Figure 1: Data loaded with default buffer and bin size</a></li> <li><a href="#binmenu">Figure 2: The Bin menu</a></li> <li><a href="#smallbuffer">Figure 3: Buffer size set to 128x128</a></li> <li><a href="#largebuffer">Figure 4: Buffer size set to 4096x4096</a></li> <li><a href="#block4">Figure 5: Data binned by a factor of 4</a></li> <li><a href="#binpar">Figure 6: The Binning Parameter dialog</a></li> <li><a href="#detimage">Figure 7: Image binned in detector coordinates</a></li> <li><a href="#binpar2">Figure 8: Binning Parameter dialog for a data cube</a></li> <li><a href="#cubebox">Figure 9: Data Cube dialog box</a></li> <li><a href="#cubeimg">Figure 10: Viewing a data cube</a></li> <li><a href="#filterimg">Figure 11: Filtering data</a></li> </ul> </li> </ul> <hr> <div class="sectionlist"> <div class="section"> <h2><a name="start">Getting Started</a></h2> <p> This thread begins with Chandra data from an observation of the Antennae Galaxies (NGC 4038/NGC 4039, ObsID 315). Open the file in ds9: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 acisf00315N002_evt2.fits &amp; </pre></div> <p> A small section of the data is visible when the file is loaded, as shown in <a href="#defaults">Figure 1</a>. The target of the observation is partially visible in the display frame. </p> <div class="figure"> <div class="caption"><h3><a name="defaults">Figure 1: Data loaded with default buffer and bin size</a></h3></div> <div><img alt="[The target sources of the observation are partially visible at the bottom of the frame.]" src="defaults.png"></div> </div> <p> By default, the buffer size is set to 1024x1024 and the binning factor is set to 1. These values will be adjusted in the following sections to illustrate how to make more of the data visible. </p> <p> The "Bin" menu, shown in <a href="#binmenu">Figure 2</a>, will be used to change the setting in the following examples. From top to bottom, this menu contains the bin function setting, blocking factor, buffer size options, and access to the binning parameters dialog box. </p> <div class="figure"> <div class="caption"><h3><a name="binmenu">Figure 2: The Bin menu</a></h3></div> <div><img alt="[The blocking factor is set to 1, the buffer size is 1024x1024, and the function is sum.]" src="binmenu.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="buffer">Buffer Size</a></h2> <p> The buffer size determines the size of the image generated by ds9. By default, a full-resolution 1024x1024 image of the data is created. If your input data file has larger dimensions, it is clipped to 1024x1024 in ds9. The buffer settings range from 128x128 to 8192x1892. </p> <p> Setting the buffer to the smallest size, 128x128, illustrates how it works. The data was centered on the sources in ds9 before the buffer size was changed, creating <a href="#smallbuffer">Figure 3</a>. </p> <div class="figure"> <div class="caption"><h3><a name="smallbuffer">Figure 3: Buffer size set to 128x128</a></h3></div> <div><img alt="[A small central portion of the data is visible.]" src="smallbuffer.png"></div> </div> <p> Setting the buffer to a large size, e.g. 4096x4096, produces <a href="#largebuffer">Figure 4</a>. The display frame is filled by the data, and the panner in the upper right indicates that more of the image is available. Clicking and dragging the viewing bounding box in the panner will display a different portion of the image. </p> <div class="figure"> <div class="caption"><h3><a name="largebuffer">Figure 4: Buffer size set to 4096x4096</a></h3></div> <div><img alt="[The frame is filled by the data, and the panner indicates more of the image is outside the field of view.]" src="largebuffer.png"></div> </div> <hr> </div> <div class="section"> <h2><a name="basics">Binning Basics</a></h2> <div class="subsectionlist"> <div class="subsection"> <h3><a name="basics.block">Changing the binning factor</a></h3> <p> While increasing the buffer size loads more of the file into ds9, binning the data makes more of it visible in the frame. Binning combines the specified number of pixels into one new pixel; the new pixel has a value equal to the sum of the original pixels. (Note that if the bin method is changed to "average", the pixel values are averaged instead of summed.) </p> <p> The binning can changed from the "Bin" menu or from the "Bin" item in the button bar. It's also possible to step through different binning values with the -/+ buttons or the "Block In"/"Block Out" menu items. </p> <p> In <a href="#block4">Figure 5</a>, the buffer size is set to 1024x1024, but the block factor has been set to 4. A larger section of the data is visible in the frame. </p> <div class="figure"> <div class="caption"><h3><a name="block4">Figure 5: Data binned by a factor of 4</a></h3></div> <div><img alt="[Five of the CCDs are visible in the binned data.]" src="block4.png"></div> </div> <hr width="80%" align="center"> </div> <div class="subsection"> <h3><a name="basics.cols">Binning different columns</a></h3> <p> ds9 has the ability to display any of the other columns stored in the event file, although it is generally only meaningful to use the spatial vector columns. Begin by opening the "Bin → Binning Parameters" dialog box, shown in <a href="#binpar">Figure 6</a>. </p> <p> The "Bin Columns" menus are used to select the columns to be binned. To create an image in detector coordinates, set the first to "detx" and the second to "dety"; the block is set to "2" for both. The "or center of data" box is checked so that the center of the data is recalculated for the new columns. </p> <div class="figure"> <div class="caption"><h3><a name="binpar">Figure 6: The Binning Parameter dialog</a></h3></div> <div><img alt="[The parameters are set to bin in detector coordinates about the center of the data.]" src="binpar.png"></div> </div> <p> Click "Apply" and the ds9 frame is updated, as shown in <a href="#detimage">Figure 7</a>. </p> <div class="figure"> <div class="caption"><h3><a name="detimage">Figure 7: Image binned in detector coordinates</a></h3></div> <div><img alt="[Some bad columns are visible in black in the detector image.]" src="detimage.png"></div> </div> <p> Alternatively, one can display an event file in specific coordinates when starting ds9 from the command line: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;"> unix% ds9 "acisf00315N002_evt2.fits[bin=detx,dety]" &amp; </pre></div> </div> </div> <hr> </div> <div class="section"> <h2><a name="cube">Data Cubes: Binning in three dimensions</a></h2> <p> It is possible to add a third column to the binning, creating a 3-dimensional image also known as a "data cube". In this example, an (x,y,time) data cube is created of a Chandra observation of Jupiter (ObsID 1463). A cube may be created from any three columns that make sense in the analysis. For instance, you may want to create a PHA or energy axis to see how the spectral characteristics of a source change over time. </p> <p> The data file is loaded into a new frame in ds9 and the "Bin → Binning Parameters" dialog box is opened again. The "time" column of the file is selected from the "Bin 3rd Column" menu. The limits of the data in that column are filled in automatically. The "depth" field determines how many intervals the column is divided into; a depth of 25 is used. The completed parameter box is shown in <a href="#binpar2">Figure 8</a>. </p> <div class="figure"> <div class="caption"><h3><a name="binpar2">Figure 8: Binning Parameter dialog for a data cube</a></h3></div> <div><img alt='[The third binning column is set to "time" with a depth of "25".]' src="binpar2.png"></div> </div> <p> After clicking "Apply", two things happen: <a href="#cubebox">the "Data Cube" dialog box (Figure 9)</a> is launched and <a href="#cubeimg">the frame is updated to show only the (x,y) image of the first time slice (Figure 10)</a>. (If the data cube dialog box doesn't launch, open it from the "Frame" menu.) </p> <div class="figure"> <div class="caption"><h3><a name="cubebox">Figure 9: Data Cube dialog box</a></h3></div> <div><img alt="[The dialog box has controls to step through each slice of the data cube.]" src="cubebox.png"></div> </div> <p> When "Play" is chosen, ds9 cycles through the bins of the time axis, essentially creating a movie of the (x,y) position of the object over time. The speed of the frame changes is controlled from the "Interval" menu of the dialog box. Any of the 25 intervals may be selected with the slider bar. </p> <div class="figure"> <div class="caption"><h3><a name="cubeimg">Figure 10: Viewing a data cube</a></h3></div> <div><img alt="[One interval of the data cube is visible at a time when displayed in ds9.]" src="cubeimg.png"></div> </div> <p> The data cube can be saved as an MPEG movie from the "File → Save Image..." menu. Select "MPEG-1 (Movie)" and click "OK"; after setting the filename, choose an MPEG Quality Factor. The Jupiter data was saved at a quality factor of 15: <a href="jupiter.mpg">jupiter.mpg</a>. </p> <hr> </div> <div class="section"> <h2><a name="filtering">Filtering Data</a></h2> <p> The "Bin Filter" field in the "Binning Parameters" dialog box is used to apply filters to the data. A filter can be applied to any of the columns present in the input file. A colon is used to indicate a range of values. Filters can also use &lt; (less than) or &gt; (greater than). </p> <p> For instance, to include only the hard-band photons (2500-8000 eV): </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;">energy=2500:8000</pre></div> <p> Clicking "Apply" updates the ds9 display and keeps the dialog open for adjusting the filters. </p> <p> Multiple filters may be specified, separated by commas: </p> <div class="screen"><pre style="background: #cccccc; white-space: pre; border: none; padding: 0.5em; overflow: auto; border: thin solid black;">energy=2500:8000, ccd_id=7</pre></div> <p> The resulting image is shown in <a href="#filterimg">Figure 11</a>. </p> <div class="figure"> <div class="caption"><h3><a name="filterimg">Figure 11: Filtering data</a></h3></div> <div><img alt="[Only the hard-band photos on CCD 7 are displayed.]" src="filterimg.png"></div> </div> <p> The filtered dataset can be saved as a FITS file for use in data analysis from the "File → Save Frame as Fits..." menu. </p> </div> </div> <hr size="5" noshade> <h2><a name="history">History</a></h2> <table class="history"> <tr> <td class="historydate">26 Jun 2009</td> <td> Original version </td> </tr> </table> <hr size="5" noshade> <p> Return to the <a href="../index.html">DS9 Users Manual</a></p> </div></body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/binpar.png����������������������������������������������������������������0000644�0001750�0001750�00000020246�11332353404�016235� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��ƒ��^���è¦ä´���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ"þ1ûg�� �IDATxÚí{t\Õ}ï÷9óÔHÍÈzú!Ûƒì~”@M ÆIs^÷f%×ÉÂWIš.ÒܦvšÕ®$m€¤ +í*ѽ]½Ü4áF¸ ´iÃM1!¤@(`°‚ÁÄŒ%?dù%ÙšÑkôžécÆãóš3ÏóÐç³ôÇ蜽÷Ùç·÷ùîßþÍ™½¥T*%„ظåã� ât?󘛖¡­÷Ü‹E� òlÜòñîg“6ܹmë=÷ž¿8‚E� òœ>ÙÓwp¯7ýÏÔä�«@‰�ÜÀèðÐÔx3›@u¸¶®ÞÚ¼J4=5™}ôì¡——ÔIuuu³³³ÇGüõm×jšˆ =›YzÃïÓ�¬bj215>Ò~Ýuæ³<tH†¬Ê«­DB’²6®Ü8yv_ÇÖ»=ÏÏžüyïð`(Ò¤È935±44~:&šWmTd€Š*Qb´½½=¯,ííí TU[•W[‰¤+¥Ä&"+ðØ?ÿÞÍ7]»zÕñg_˜«®óúƒÙiä‹oÏÕøÆCmõ5ut� ‘$IÊß²¨|^=%’'ª£ÍgN\Ø»·»±±aå²EûÞyµyÍíB\Ê?Ü÷Öu-á×z†_w}ÁæÛõÀ'eYúüßþËÐȸU%�¸B‰ä‚A~÷Ï‚¼¦|¢Ks´åk޾õÂÈH¯,Ëuž©ÁÞ7›®^'„ì»**öü¶·mýrÖãñcÑpH‘J‰‰©é£§ûE÷™Á¸¢§pnfòôñÃÈ"×[@_‚fU…“Ó3=§¦»ïܺÚ×î½kùÂýðWo9Ńê‡[¨žm“Ή"»[/ù—þá§fò^‘Ló O¤èi]³éÔÞŸÅ”"™Ž…¡hsÝTÿ¡¾Á…kï”dÉ[~ãPÏ™ó7¬]uýÊÅ!¿üÕïüÌë ~ý‘Ý}ïH²Ç/R…EšŠ/ACÝNžЬ\¶hÍŠ…±}óçÿöñ9aê6=yn.YÖþvñ\ßTb<P]k2}ªŽž‰|fXG÷¿ºê†›sæ}ðswùÿü,ýù›|—^^³³³K]Ùh^{ÇàOù<B–¥‹½¯ËM3s¡¥ýU5æïù¿î~ñõ·7o:÷…Ž»£áعÓmW?úÕí²,}îo|ô¾ÿ!ËÒcÏüæŽß½¦¾6ôú‘Sßyâ¥Ù¹¤¢ë«÷ŸÊYÂʶ¦OøæÆhÍ[=gFÆ&nß°êW{ìÚýšfUÿu÷¯Ý}°¹qÁ£ßÚ® 5†æÎK;¶Ýqõ’¦ÚP`zv®·ð¿è>=ÏTàŸvïýà-íB¤vvþxÇÇn×L¹ëþíBˆ®§^ýð­kƒ~ßO_|ëø™‹Ÿ¾ëæuÕ¯<ñ½Ÿ¾’L¦„MÑÚm[6\»¬Ùçõ=5øƒ§÷öÄ¿õ?·¶6„…ßø³O !~ô«}O½t@3¥ºJ_ø_OlÛ¼á–ßY^ NLÍœŒÿý^›äéev¦7ÃúÈ}IøßþñÁìÉ“fÞ¯<üä7>ûá´�e>g TäU”/«ãO BáúêeS©ÔøälJÈ!yzÄ×in“Ì‘Ž,}à¶_øôG¶o}¿b÷ {çæfRÉdúÔÅþ!RéÏ›7\ýò¾Ã‰É©›Ú—­[•.ÉgŽSÆ%„‚þÛn_ØXw¸·o|$ö¾õ+…ãÃâÎhVUQYpÃõkÓŸ‰ÉɉDC´æÅî·ºþÿ³‡Žo¿ªõO>²ivz*“å£wÜxäDÿþÃ='4DtR !„ØúÞ5'Ï TWù·Ý¹þó½íôù¡d2¹éúk‡%!ª¾/rËúÕK~sàèSÏíY½´éÏïyÐ+^ÚßB¼²ïàÏüGww÷ìD\3¥ºJKj“¼åºøÈX×ùÔs¯¤æ¦Ç‡Î¦æf%prþyÓuõºMŠ?µ�i^÷/ÿïÏÓ)2´zÝ&­¼—]ª>Qšdb(™S)ÿU5~¿ß7'IyNJo¼îêô‡ÙÙ¹øÈh¨öНÛfggÓ:»žØûÛ£R*µõŽ›–´DŸýÚhSÎSÆ%¼gíÆšªÀ…ØðŸ}ãa¯?XS]½®}…"•L&“IG]úÒg·e>ê9y䨩úÖe|溺©©}®ûíG¿¹baS½˜¼(‹ÒÉþáŸ~²û…½¾ªj¯¿ê¾ï<y¶ï½”=òo{Þ|ûûßúââ–†§_xí»ÿ²û‹ŸùØ–[×-i ¿zàÄ-›6Ô‡C'úÏw>ò#UMÛ¢Öõí+Ö¶Õ=ùëý7®l‰„«þüko9%{}wè¤ìî‰)ª´i]»btlüôÀÐùxâ±§÷LM$¢MA¿×/ñî…{œ"YÈR¹$IÖΫWZæ¸~Þ¿üÇÝýGp… m¸Uãºyʼn„#g{f‡ŽÍT5…ý‰ééé©©)1}aôÂ¢ÚÆ%æoùÁ‡ÿ÷WöýÎê«úÊg?û‰»öH$5‚/'úÏÕ-hIzüB¿×;=•H¦’9O—® !úÏ ÉSߺôüpÖÛä’Æ÷œ<sa(>95}¨çäSϽêóCÕ5ºiýêÿV]È$ó{¤©éKE½y¨·vAkUmÄë‘>y×-®ýïz){ûÎÔ5´NΦ„GOôWÕFfeŸÂçóNOMDÃUBˆe‹›ŸxøLö–†Èèë=/ýoUmÄ_UÓÒ¸@/¥¢JïœýÐñu×.[³j™b`hä[î>›Zsu NdðÖ•3,ݼ_ÿ̳çtõݧ5¯«'Ò‘ÀÉÑØh韛9ïUë7OŒ\úí³²˜B;2:½Tr]Ckl.”L¦dYªó‹±±iuÒ¹¹9o ¿ë§¤R)‘Jå<e\B|$!„XÔÒè…$·µ4(fÊŠª¦ãD²×'I²¿vA¨6zë+ß{ãŠ3C>üØxbâï¾|¯,Ë’$%ß OÏÌøCŸÏwû†kn[·Ò eºz鯛›ó‚ò»QÿT*94šBô9ÿ÷»~’©ÓP|tnv&%IBY’„¾@p81­—RQ%ÇûÐ???=|~aCÝGÿà¶ß[ßþ»×´>¹ç˜ì‘y€Ý¥Dr!¹.M•duI/´dœ÷k¸%ã ¥CK_ÿÌ¿ú½gÔ×Í#bœ?¶GHÒÂîôB¾ÆÐܪ['޽ø}>ßX﫵›MÞÿnÛ¸á†ÄªåKdYš™™=vꌪ×÷%•Žå:¥_Â[½§GÇ'ëëþîÏ?51+®]Þœeí¯®«T‡EJHÙëñû|þ´ˆø}þ÷mÞ(Ë™,©ì’=^Y’s¦’|9"%®ö½Ý?4<Ö¶°ùC·ß|úâX4\}ýª¶ïþøù±ç‡Ç&„Ÿ¸ûý½g†^:ÐÿæÑ3z)Uj¿já¹åÚÃÇú'&§·6 !†GÆFbç´,“d|"wF¬øôz)ï{ä—9#Öæ|"¼™ë¦'e÷=òËô‘¯ýáõuõ”HãÂýo6ÔúÂ7†ZÓGê—¬L µÕÎø|¾T*uêäþºåëÌlj¦gfïÿþ¿>kªk5iä‚NeÝÅÔlçãÿÞñ¡+ÚZsàè³/¿¹eÓsÉdF5sùƒ¡LiÏ“W·†7¶_õ§[þû'§f‚Ÿf#™L)tätjzö]Ïü×M×lX»ò½Á`ltüp艹žÉÞ½çí–hèš«–¬^Ñöú£§Çz)UŸ”%±ù=í¡ 41ùô‹¿ùÉ/_ò×D“ÉY¯ÇÏ3ì)29×>øÚóíïùýlWJ7íËè^È0oF†ÒW¹ïÿ=ûÀ§6k_WQpz}¢ãýЉó=KƒÃûûF®¹-ûb©dr¶ïúÕmsssÃ##G†««›–ßüÉCÝÉä\¦^_ &Ú¬® TÕœ8¸WˆTã’UÕáȉƒÝ™Ï΋ VÕFê[–úUǼfæ”^ áššþ¾Þ‰‘¡ÙÙ™‡¾òÇׯ^þðŸÜýòoë[Ú|Wþ„%]ÕHãÂÚ­^ïe™LŒ^<{bz2!ËžP8:¿˜J%¯¨/8yèòE%I6L¹W‘NÙÿÎþÙ™©HÓâð‚–‹§ …Âõõ-m^Ÿ?>Ð?1>:3™HÔ½`]êêÚá¡s£Cççff…H5,\^]·`øÂÍ”'¿ž]¥‰±ø…³'æf¦Sɤ,{¡špÃB ÊëC‰\Âð…sííWüLýÀž_é%^só—TéàẆ–räÍ$Ó<˜Î›9迼>‘BئG/. ¿Ó7Ô|Ýû„|…%y<ÉÆ5‰éøê«—ŽŽ¦Ž÷ÔD ÌT״جÊòÇR’$û‚!I–#Í‹‚¡pºÙŸk¢MÁPØë¤E×ä)½dŸøÀz‘ºñÄ©sW/m¹~õ²±ÄÄs¯ìóúBŠÉÑU½R샡ÚHÃ"!‰t*XöúüéìÙ’d”²iq°úRʺ¦E^Oòx„µõ-Uá¨×B’dO]ã"ÕpJ²ä‘$)%ROòxj£Í^oÀãó¥-™’„^JE•üU5ÑÆE²ì•<rÚ óx}^¿ß¤S NŒX¯½esÁë’çU4~³ñŠcúŽ$bÁ¶ ^_@]n°:|àb¢ÿÂÉÉÉ™™éÑ™D°v½A¥£M‹ôNÕ7·i~ÕÔ‰¬Öš<¥—ìôàðí7,»éº¥SÓÝz¾ó߯GÇ·J²r†¬[UIª‰6ä¼…)[.§¬[pyLPø&¯¯&¢Q‚ì÷ø4+j¦TTÉëó×Ö7ó¸2;Ó0ËòjÎÎNžrwK ô‰'çfeYöªÂõM¾@U°&"óM68ŸéÉÄÄØ°b¢”#`tðpUM?²*oæÈų'.ÏÎ\ÿ’[xAk°ºNözÓSÙã VÕÈ2ßdƒH/÷sðàaóYªjêÒ¹¬Ê«=;sýKnUµ‘ªÚ]\+F¡š@¨ÆYy5”(í%Fb´(�T†P8ªò‰„HŒÄÒ¿�¨�Ûïß•#%�`³³lâñ8f€òÑÕÕ¥8‚O�Öƒ�J�€�J�€�J�€€]È{çh4ªy<‹¥OÅb%ûñšúZŠÂ3W̾t‘ÕÐÌž³Ìâ+PLµõ U@™¥jÄœmg%»ò¥íQà%ª|ç0s-:k¶¢Ñh4µƒMÌWI¡€%ÕÀJdÒ‰(“L¨¯¨pŽÒGйnvvÅð®¾5½‹j>]êG´2œÁÕõš©uÓtTÛSÏæåðÄÁäòuúX,¦îF%,\³ØL,S×Ô¼5Í‹*ž"ÍŒÆ÷Rîj7S%Ÿp…ÿÔ³Üv»ûD•œÃëÛå~€ãsY'°%¹—büÐ|ãb¨’ àÈ8Q©dÂ’®–- j™°çPìè8QaÝ "N4/+ƒ/ ÝÝ-Òâk9Ctæræ2y9‹-òºŠ˜…É[+좖;Yê{)GŒ¯$†"6„å÷ g:M‘£Y4‹ìÂõŠÍ™ ·f¾VÙK[Uµ•L^]¯™Š#u• ¸åÒv'°'—ö;;50œYÇš5 ¬¤×lܯ…£ƒý½}÷òk�péì ��%�”��%�”��%�”��%�”�  4~‹Ÿ~�À2Ÿ¨³³£�€•J„ €-fg�ÊM$Ù~ÿ.ÝÙ�€Å³3��”�P"��”�P"��”�P"��”�P"��KñœS½5hö–¡ymÔ™]”^F§ïÿYrs9z+TÍ[Èd¯Wcû Ddì’Þ,8‹åk)ÅÓeÚEÚ&¨ÍÅ`h`%À'*œ›â4w—7ö’Ê•¹DæBÙÕLiòBÖúM&kèèq2[‹³o3¯.änÏHÓ>š½Bó¹pÐÍʳ¦zz’SËòʘí‘)>ëU¦° •Û!7_Ãyò|Ð…æÉÜÍMfñ–Ä(>…­ž=¿¬€Ie™Ìe¾òî!…3ËdÍŒ}ô´ô”ß¡F“‹¶«ÍÙ5¯Låm®² Ćò²Oô]4Ó;ј|‹/ô¦âލ¶ ä EÎ×>ŠÙ™:¥M*ÛêqÊË7)ÞÜ™Ë9b Ñý$§o‡¨xû8=x$—äñ(æyVÌÔ3&E±Ù1éRé`ÅôÈÀ\š•ÉYC&zóVž²_qA6ܹmë=÷žNŒÄÖE†XÇ�*@zëP8:ØßÛwp/q"�pþì ��%�”��%�”��%�”��%�÷`vUH$2omÇé(�øDVÒÙÙ‰�ìâÍOï ««‹.`;%wÌXõF”7½_ƒc%3VB‰˜»å`ÇŽŸWÌ�°RÉçI(‘]ÆûøqD軺ºrj V2c%ó±�ëA‰�Àzl4;˹„«Íלvî/–[LnÌiœÆ­FP÷ö6æt ‰•¬?ewÄ(¯ÇxonSÓš‹R¤t‡ ½¶j ùÏÞÿCÝ–Û驼ìVÌ/’ŸÓ8²¡l“Þ¦¹-º¦ÐØÜ¬8D%·gÅöÅ´PtŠ” ã쎰¡l«&©|"Cv~J]¿e®ùMÊ 6+6xdC¯Íɸ§"C0ßfmŠGÃ5sX¯ýížSªì ÈPùüLQ°‰ˆ•ÌÒsG¾÷.ôZ³H³8ц+‘æÖÒz1 îC]¾¾Âƒ”oÓçÜhÛÅΑù{4HiÐñdC¯MCa¦œ¯E˜Il«¹$˜4šÝZÖªž£'ÍùæuŠ ùµ� D��(�Ø~wV,îÛk€5 ±Jä0\¹v b%”ÈI¸oÕ¾ŽŽ–"ÄJP"<R�(yD¬Ùù �,ö‰âñ¸³–Ž�wúD��(� D��eÃlœÈ}ï¯lð‰,†o läÍOï€÷§�ì¨DsWDÓ[³åÍFﵬdÆJ(QEùö·¿í¸:ïܹÓà,?§23ÀJ%Ÿ'¡Dv*C$1V"A„^ˆ®®®œZƒ•ÌXÉ<D¬ÀzP"�°»ÌÎ\°sS&€ÍêúùZLÏhŠï\iX=#hîá¡Né'*YÊîˆQ^cOzó»\¸Ûšßɤt‡ ½öi íWl÷ªÈew 驼›ìVÌo&jrŸdö€5ÛÕ4÷ùÎnÍmÎìïAIìéâÍ,Kµ3¢qvGØP¶O{6hØJõ‘¡ÒöŠ Â¥Ž›ßT]¡Y&eÈA6ôÚ¹…׫!¨À€­9‡púÝymntƒ¶Úí*Ÿ¿€) 6q¢Òx@¾(¸øé¢‰‹4‹mh¥eæ®Ùš­ÃS'¶›ÒG³àÉ1ßúzãv©¢¹Ž6‚™”ÏA6ôÚ¡%6Êë›—ID©Œf¦'¸ÞÒœo^§ØÐÁ¿öÀõ�p NU"™�n©¿ö@ƒ�P"¸Œûö`MB¬„9Œ;wæ\xÌq° !VB‰˜!ZIGGKb%()�”ƒ<¾;cç/�°Ø'ŠÇãÎZ:�Üé� D�€� D�€�”åwgîûí�8O‰xi�*E½®ñÒ�T€H$²ýþ]™‰€õ D�€� D�€�ÁJiÙð.U6z‹a%3V”¨(x*ñÒ¨XÉŒ•�%* Þ¨2ãõ`%|ÃÒBœ�P"�€Âfgêm Ó»\°/kvQùn•Q™m`£Ñhö%2.ì ¦]°GV ”HÑ3¢Ñhº##%™Bìö€é=o™Ïæºõ¹ÂJ`¥(‹úCN&»Gê¹Z åRwk3óçÕ`Á’íJ°”¹Ü}Ts6—SËÔ¥)$Ì8£…O©ÞÕ£ïBÄJP”O”3ÄSÚQ®˜Ò Èk~ª¨çhÎA4%Îu°X¯Dê8Q™âEf,« åœZº~^†•Àb%*÷Î2©aÉd׌ðX ¯DiwÝ –d>̬þ³¹œÏü}`°ØB‰Š÷±3b”]ˆúˆy-3™±HõT\ÂüÁLU5ϺI¡°TB‰ôº…ú+y3j’׃ f™ÞF1¸b¾Í›ÅÑþV‚à×�€� D�`XŸH ëÎ`%À'²VáÃJ€Od1¬IŒ•�Ÿ�P"��”�P"��”�P"��”�P"��«áÍF ºººŒØd/æ2íø–sU œ×­ÌVt€¹Ÿåî×;u÷ßwñ{ƈ D.yŒ³ ã=×4×½¬ØŽozé…Îb¯ÂúâD¥÷&L™¾b;¾i¦×\uS‘^]²q!À'ª4ù®¢[XšräU•×òÒ8A€9C†ŒgyÅg,«˜©*~ DóB¹¬r@4ãV¤ Nd 4w7¿%¼zÇ·ò=óy•Œô�Jd#“Qœî‰fú¼ ÉÞQ¾$W7y-ÍBÔAkuÅðŒ€Ù™5³ªÕÛñÍü®dŠSzÍ÷3�J”ƒ»ßø>F�@‰¬¤££ƒÕš* q"�@‰��P"�@‰��P"�@‰��P"�@‰��P"�°Êw¬#‘F�‹•¨³³£�@E¨×U"›ìŸ�î&‰l¿Wæ_âD�`=(� D��(� D��BÌÃ5ya  ¹Ìé|\=–w¦�JËŽ;ð‰ צ�l5Ï N�Öƒ€õ2;Sïá©Þÿ³€B2E©wRg»>�”HèIFFS²÷.¬�@‰JCÆQÈ+»ÚoÒÜR]á4á=8—2Ɖ4å£0I!:êb ¾�8Û'R»'̼2…ïËà ÌG%Rlj*#šî20O•È*�÷á˜÷‰®PÚ£ý�æ»O”3NT*({ö—-@8G�óZ‰ô$@ñU—ÉÄÆÙs–†0;�@‰��%�( ót}"VnÀ'²˜â×—�|¢¢(rµ]�À'�”��%�”��%�÷¢üîŒm�Àz%bT�¨õºJÄæ¨�P"‘Èöûweþ%N�Öƒ�J�€�J�€�J�€�J�€€}(dõXõ6Й Z…é­óÚBÖ¸d3EåU·Ê£0iaõ̾G›ßo^÷¢>èô»+·}æ—O{—lä%CŠìE6IñEYŽ;†‚yíå…œc—f72Ÿ]oÈ|0ð’4‡h4š¹\ö¥5S–{ØI_%]%Í{ѬL&Y&£ ÆÉì{ɶC]Å­ž‘¦}Œ»={…\3éðéçMa‘ì'J! eõ’ÒµÍdÑÌžóŽÊç„笌ZŽ-©°µ$¾¤s' r1w«)%æƒz–RøÞöQn[!f*ã!Ý7ŒŸ%FÆOÂ3²§ÿXÊ8‘ûžvûô¶ù9ÚÛs@r„}²uÓKs:«ÃÍÛaÌÛG3€(ôƒ‰Îö‰*6ȤTkKR¬M&ùÆF3¨¿›Ý´pˆŠ·ÍƒGeŒå4Ÿ™0SNñVe\¸Éb­h…­y/ê/Œì|kPyyÒûÖžHîܶõž{O 'Fbë"C¬cío¹G“^Ç:Žö÷öÜ˯=�Àɳ3�€RÁwgN�à� D�€� D�€� D�à>Ì~‹‰Dæ­âñ8�ŸÈJ:;;1€]|¢ùétuuÑE�l§DÎÒê 9óy’Ž•Jk%”ˆÉ]vìØÁt+UÀJ(QEqÖB+fÆs–ŽÁJ%Ÿ±�ëA‰�Àz˜U—-íªØŸ°Jä˜îèJUeñl¬Äḭ̀•;�J�(��J�(��J�¶‡oñ¡@2Ûa Þ”ÁJ(‘ãú%·C£³3�@‰��P"�°'ĉʎûVðcMB¬„Oä0̯YÇa%|"( îÛ€€ —°’-”ˆ½.�ÀâÙ‹„€Å>Q<g…p�°Þ'�@‰��%�@‰��%�(#ÊïÎxE�¬W"^€JQ¯«D¼4� ‰l¿Wæ_âD�`=(� D��(�ØJ¬Oä¸7œ²¾ ¯\8±Õ×p•1,>‘Þc Õ ò†­ÜšŽ²œ¸+:t?û7\% ‹O�Öƒ�J�€�J� „=÷;‹F£BˆX,V±Œó„´}ÒÄb±’›+»ül×¢™ìÖp(‘‘Ñ£Ñ(µLúFõT£xh5‡6J¤Ý•³%É`\Õ„PXX=êê46»/U=Ò.gÃé´² í®ù¯fÇÕ<w÷lcj4ž…åå1)D§´W¡áÌ·&>Q |~=iO§ib\-Ç$Ëàl¦—osZ­‘Êè³³ÒxF`•Ù "Ð¥•Í !CE7 ¦Æ(QÞ1…‚m—q‹èÓ…9 ꨜUþÜÿÅ•ßüØÙÎŽyŸHóaÀ{ÊwœÌ)ñ•üvF¤A n8µõtÇžv–Ô$jû‡iM:íš§²–Ö3Ê”–@Å{-GÃdvfÖEW<�9å=ÊËÂy™ÎŒõZ0ßKÓd%l8§XÕÍ¿öÀÕp ®U"¼}�á€÷‰ s5Ñ �|"��”�P"�€¼¨\œÈ¡0Ø KÃá™…í¨0,ÐpûDñx¼££[cX á,ö‰��P"�@‰��P"�°9ʈu$Á(�`™…ÂÑ}q±ýþ]�*@(ZçOÅ���'IDATÕö‰²O��TÚ'ìïÅ�`R*•Ú¸åã�¬¢û™Çþ¦;½…9����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/smallbuffer.png�����������������������������������������������������������0000644�0001750�0001750�00000106502�11332353405�017265� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ. �� �IDATxÚì½{œWuçû«~Tµ^ݲdY²‘l°Án ~@x…GräˆOnâ\2(Éx.“ù„&’ùL&$!aŸœQ“¹“Or;NÂd<!w+ød€À ´ ,Û’ß–­ÖÃRŸ*=êþ±ë¬ZµwUõéîólý¾äÓuê±k×9ûwÖÚk¯åÅq àæ[~„BÈ@rïß À˜‘«·¿óÝìB!ƒÉÍ·üä½ÿ1ï¦=ïxû;ßýôs'Ø#„B“Ç=xøþ/™?Âæ"{„BÈ CÅ"„ …“dž§–áQ ÖoÚ¸yKÍQ¬(lê­O~ëó/ØìmÞ¼ùìÙ³Ÿð·ìzIîIO/<5qâ{‡Îì~ù›ùQ „A&lžO¸ö¥/mÿû¿õ-�Ae¢_Çæ+<OoÝvÕÍÍ'¿¶ïíoý›»þöàñ#“[Gž wOœz|Û¯¾Ù:œBÈÀ)Öé“×^{í²¹öÚkïÿÖ·‚uëûul¾byYÉ*§'¯ú³ýÅk_ýª—\sõÃÏœ[¿y̯è}Fžûι ã§&vmÙ°™Bp<Ïó–o]xŠÞ[¤X#Öë§¶?ñȳ_þò½Û¶m½êòK¿öÝ{¶_÷& 9þøáo¾ô’M_zðèe/½žŸÃOì¹é­¯YãKßþ“_doBO±FV¤#­ÿúpl[6–aÛ×}9qâàÈÈÈæÑðÈÁ¯_|å �N9üÂ)|qþà®hÉvìܺù§~øUWíºx|lôØÉÅGŸ>úÇó……§[×Eý|ëä�ÿæ÷þß'Ž“o¸f×¼öº];¶ŒŽŒ<õ܉Ï|õÆ—¾Ç�ð‘÷ÿÄÔ¦‰?øøg?ÿƒôi€àô‰£'ž{jóÖ¹ûì¾dË;~è•W½`Ûù8¾ïÁ'îøÄ=Ò„ÒmÉ‚£m;Ö±þ×o+Úýÿ÷_·slf·Ü%6VÑDÔŽë^÷è—ÿ¦‚ÀùóÇ&6MLmß>ö­ÃGvNïñFF—¼Ó÷¿s϶© OYxì©#S›7\Õeñâ±sçGFGǼx÷v#W�®ß½ùð“OW�ìù¾—¼ó-¯pðð“‹Íð¥Wîzçß΋6Ì}â^±óžy|ñÔñu&G² 1çýØ0|àgÞ²~ÿwŸûª‡ø–×ßtñäį~ôo€Q~•!ݬzç°ÏÞ÷¾qÏÕ/õ’Ç~ø_¿íWþëߘ׿óóÿ¬èØ"+_xGÇ‚íÓ?x䟌bdÄ{îàWG¶]|æÜâÄî›ýu–lúE›×o›ÚFg~úýÿ>öFÆÆƒMëƒS§NMl¹tl,�ðÚë¯ðà#_yù¥?ðšWÜÙøÒÆ‹vnXüÄÞàŽ¿ºûOþêî1¿òêW¼äƒ¿ðÏàU×}â3÷YL›Ÿ?ÿ§¿±ÀÜ{ÞúúéŠ?þןýæÃO<÷sÿìÕm^ÿ¥ûùoý…óçc�3?ñÆ+_pñƉ :{îàcGþìïî}ü™c�®ÚuñϽõÕÛ¦6|óÁ'N<¿ø¦›®þ‡/?pÇ'¾àâ©ï¸å¦—\¾}|lô{ù³O~ù±gŽY7øâÝÿì[_½u29\Û³?yËͯyÙ'*‹á™Çû½;?sõ®íë×ù>yä?}ô¿¯Û°ù×^µkç¶m­|®Bº­XôìýØ¿ü€»ó_þᇡ~¯çû«¿×oÿ«·¡’×rBëØ"Å*¼‰M[Ö_~sxøË§Ãsñheb$:2rÉeÛwµs«ÏŸ›Ñ™Š?þ¡÷ýì÷ž<þ½ÃÏ<ðÈS•©ÑÑQÀ½ùÚÝ�~ÿcwýÆ{zûÖ©+/½èéÅøšÝ—øãcqÿåß}vÃÔ¶ “Û¾ûÔâ“GŽíØ69ý¢Ÿ¼÷ ;¼¿ýû¯{èñgnxÉïØsãó§Ãïzjjãº×]ÿ¢{¾zßüáãð¼­S>{ï7=öòk®¸áÚ«~áÇ^÷þýß´iã/¾ãMÖß|àáS'N¾ñæi�§Ž?{ìÙ'v\ºûW~æ–-›&>û•ûŸ;ºð¶|Í/¿ó~yöãá¹ôÚë‚ñ÷þŸoZ¿.¸ï»4O=ÿÆÓ`˜é+w¾å5/=ôÄ‘ò³ë'‚—¿ôÊSGŸ ·O¸hrãe;·oÝyÅæë\ù‚í÷=ò­õ§¨Y„îÛX#+:ÊË=öš^W$råÇþÛ?øÛ½ûG�Xr¥O¸¼È ÍùÓGÏÇcÿ…Û6ø¾?~®ÝÛ>s.þƒ¿üÜO½åÆ›_öâ›_�O?w|ÿ_üã“Ïž€ç½üÅ—­¯øÇN<ÿoüÚ·}ÿ×¼ùû®ŸûÛ{7NT�4ÃèÔépû¶ËGFÆFÇGjîØ†Í›Ö7OŸt/Tÿ£¿üâ׿óÿü‡÷_vÉÖO~æK·ÿO¼ÿ¶Ÿ¸åõ7¼àâM÷Ü÷ȆÍ[ëþþу÷mذñS÷~çO~çE;/Þ‚æs×ßx͆uÁ³ Çß÷Û¿?æW6¬_õ/2¦Û˯¾l˦‰G{zÿÝé¯Û°ëÒ7^û¢é]›ï}padlÜ\ôú«.[¿.xîØ‰_üÐ>üþŸyÅK^hÞ ÆÇœ|þÔãÏ}úØé}ò‹áâéhäÐ÷?uÕ®Kþä?þ�3'·®œ OcãÔ >I„²ñÁˆ·‚£<o$ÿØ¢³Éöâcÿí~âCÿò‡3ruÓës®›«X% ªN<ùàÙ£Ywñ&ÿtEa"zöä³—nÜö‚vnöë>ùé÷Ñ›ƒk¯ÚõüÐ÷ïÜ~Ñ[n¾âïúò˜¿î5ÓW�øâ×¾åŒ~õ»ÿ×¼á•×ßþñOŸ\ TýúuÞèÈÈè(<ojãz�ÇOž:îbû*?±yëŽæÙÀ÷ylÝÆÉ³#ã�ÆÇÇ¢pqtÌûéyå /þÑõë9ÄõÖWÆ�<öäx£[vì~úxêÖÛ²yÀå—mÿ«ßÿ ÙxÉÖÉ“_}pÓÖKŒoóÆ �>ñ FF.Úyù“GO¿¢µç7>öÕo=|ÃK.¿îêË<sôÄø“O<µ°øÛsÿÒK&v^<õä3ϽæÆk_{ãuÇNœŒÏŸ?x”kÚ!]·±:9Ut6åÙ+<ö·n{‹ö%þÚíŸÌ½nU •Í“ 'ÞsúÜØ o¬.žxîè|cç�{à³ÁÆ·Ëou|lôºîøÎ-œzþs÷?qѶïüä¿vÃúÊÂ3ï¾ê%×_u)€·¼ñ•oyã+Íþë'*¯¸úÒï<üDtæ¬?>ö£Õ×6þéÑ‘`äeWî¼ä¢�¾òÍFGsâÎ;7¦SΞ;7TFZQ!q|þµ/»âõ/ÑÏýðïìÔéÅßý•wŒŒxžwôøó�.½d›_©ÀÙuÉV9á‰E�‡Ÿxú÷îø_²ñ豓çΞ‰ãó#£c�Nœjضerl<ð0²ý¢t]Ú™³çëñéèøÓ;·n¾õ‡ßðÚ¯}å‹wÜõŇFGƒ¯|ïé³÷Ú0áÿü;ßàk÷?èŽÃ+|„Òg¯àH¾W°èl¯`Þ±¿ù/nëÊL}ýÖmoùwÿíïÝë.Ã+xþì™S}ž·óå{ƃ‰ñmç®~ýâCŸ||üùƒ÷ÓÕòû÷ÇÇÞóã¯?Õ|ÕcÏ‹c\uÙV�ßøöÁøü¹›_ü‚±Ñ‘Ó‹ÍúV¡~ù¥Û/½dë¾ö†úŸÿÃÿðÕŸzË«öýØ-¯ÕÓç0råe[Üý¹¯|ûàá‹v^‘?åã¨ø…Œ8›Fž;wÎ÷ßX½yd$ió×8|òTsÛ–Í¿ûË?»x/¹b»òµ=züù];·ÿÈ›^ýøsÏOmZýÕ»nÿø§ŸäiÄÉ ï{ø©S‹á¥—lý…þ#‘¼âêËäðë^´óm¯Ù·zl±]¶c;€ã'ž?±ðôïÔö;yúÔbxÓKv­_|îÞùï<|ÑÎ+FVôI"„åhO&â7~nOÑž¿þGwgÊ_SÕ†•s¬\×8ýî6[~ó_Üâ^·H±r.¼øØ×·nôŸÙôŠM­ÕE[^põ‘ÓGwm<3>>Çñ£‡¾±ùŠJ:(:sþo¿pÿ•;6íÚ±=ðÇŸ;vâS_ø§¿¸ëÓ•M½æeW�¸ëS÷Üþ?>i’GM_½ûß¿ß+¯¿fìOÿö¾òà£>öÖ7Þxå#‡ŸxæŸùÒ_ýÝçÖmØ<¬CQ”‚—û_øÆC/¾lêæk_8³ïíû¹o4Ã3•`ÀbýçýïŸÙ{ó‹víøÊ}ßk|þë·¼îçΟÐŒÎþöÜßÿèë^|ÓôUß_©,œ<õíƒ>øàƒÞø¦Ñ±qÓ]‹áÙÿüßÿ÷O¿åæ=¯»ñþƒ~þë¼þ†kÌ\ñPý¾k'*þÉÓÍO~ö+ÿëîÿÏß0õ̉›¯yÁúu•çŽüØ]Ÿþ“ÿ]ebÓx°ndtÌ£WÒeÉj3£Þý_úôµß÷fmš¹ÇÛ¨ðB¥ÇŠ\™«üú7~ãg«ù×µNlêc=üØ3Ö§Ÿ~pwåø7ŸÜyÝôÅâóçÏ>öå¯Ùuîܹã'N<p|ýú‹//¹óóçÏ=}èsgΜ=Æçã‘ÑÑu&7lÙæWž>ü@Ô<½~óE·\lJ!‡‹§Ž=ý¨oû _êÏ6<uâLÆˆÇÆüu›¦ÖoÚ2:æûAåзî=þÜä¶/Úñèw¾ `Û ®^¿iò±ï~ãì™pòâË6]tÉs?têÄщM[¶\²ëÜÙ3Ï=ùHÔ<=22:±iêÔ±çâøüÖË^tÑE?ñØÃ‹'Žž={¦þ«?ý5WüþŸßõ‰ÏÏo¹dר¸ì™ÇO<Ó<}þüùÑѱ± ²yëÎuë7¯ q9>÷ä¡Å“ gÏž *žç5O?o®x6j>ûä#çÎDñùó##£ÁĆM[wúÁº# ŸÏ­¬ŸÜ8µmtÜ÷ƒuü6BºÊñgŸºöÚLZóû¾øE;_÷êLÔëþooÞzI7Ž•Ýr7šcåÝ…gKëcY|n÷Ä©ï>ºý¥oÄHÆ.óFGÏo»îttìš+¯8yòdüðá‡NŠ—ñŽŒŒM^|Ùùóg=xž7jlŸ±ñ`̯lÚºcddtdtll<*�ü`bddÔ¯L�qebÓèØx8±ÉóFFFGŒÕäû•Q?�°ùâËüÊ:ÏçM^|Yeý&s›/¾tltܰqË%ë6M€W™Ø8¹õRx0bSY¿ilܼŸzËMn|äѧ®Ü}Éõ×\þüéÅO}ákcã€çŒnÞv©¿îxìaÄõ</F<jNžÚ¼£“Û.õ'6ŒŽ{##qo<wvtl€¿nÃÔ¶KGFƼVãGÇÆÇ|óE;Ο?7::fN2îûc>åŠÒ˶Z¦_Smç¨Ü艎km,_Aœyãùg?pz¡²ë¦±ñÀ=oeý¦ûž;ýس÷5›Í3g¢“gNW6ÞXÜdLlÌ׳M[¶[[ƃÊä¶ò§_™ðl󆩋/•×[.I‡m¾(Õä±q_²aj«{ž'ž=ñ¦—_þª—î^ £{ï{ð£þ×ÇNžÚzÙodÄó¼Ñ±ñ “[ËÉxPÙTrßÚèÜ €õyE_!dp¼‚®ÐõíXk›ñ zòèûŸ9üÀ©ÇΟ;;222¬Û´åâñ`]eÃä'–!kˆ¨yzñùã–ƒ®œûïÿöº ›ýÊD¿Ž•-Ï=ùHê¼§ý7]´£²~óÈØ˜‰K«¬Û02ÂÈ=BȚ”›ºÿþo·Ⱥ ›ÍQý:ÖbéÄkžu'×mœä§™²öEkbC0±a¸ŽÍQ,cc>±À'J!dp˜Ø4åØXÀé w|ð]ìB!ƒÃ»>x‡ˆgk!„ (û÷ï×޹{;vŒÝD!¤¿ÌÍÍY[hcB¨X„B¨X„B‹B‹B¡bB!T,B!T,B!¤ÿŒ-÷€©©©Üí æ­……Ž%'t¯e\®¨/½šf¸Çê6tðÖVïý¥¨yý ä~ØúÞV«–ÛžŽMÚÿ véÒüÐv»…Ö%JÆÜþ\å£ïÔÍ®ìÀnômn§uõã7¶²Ãz9j´s­n·§_£ä@©TI󦦦¦¦¦:ÛàÜ(ƒ WîN«úÞ¤Õt΀|àsû³³^>Ì={X>˜tW±–Tήš&E–|ªVü90gcKl¸"âSÖ^É]»7«¯¨·[¯{ùhr»®³?—¼¯vz£ÛVNyowäYX=¼âKwü‘µÙ9EŸ–·pÉþì’„è!+÷îJžc‰‰ÓÎ0ÕÕl§Ù+xŽ#]}änït|L,úÑíOs7nm¹?Ír[¢mëuïÛoig=9íÜWyo¬f”ɽâ²z»7_“å^º‰òÎɽby WÓc%#Cù QôèW9š—ßÝÊ>$}ü൉•=DZUöx,Í"­.ú¬÷Å âº:ò30·ŸǺ_ò—ZGšÚƒ¹UŠV6 ¸ûh¹¿ß—ûEîÔ‡ªhºz5¾ã¿¤ˆ9-­ŸhE=ÐÁoho>f]œÇꔜôøkŸëmëÒ­­àÞWð5ëÁ£霾|NÊo|É®_]üºýp´;íö£ïÔ×pýV®¬×ݢȔn<ñ±Aþèˆõ0˜·Vä•^cfÐ ,Ýž%ƒvžÑZ•y×ñ0PVrîtuý²>Ò"+øɽä*S‰²vJw{<ÎŒôàÞ¥ßVÝûõÚæwLßš5S2hãlÍZ•«îuìjž…;u7ÈÕmÞ`Z™ÃÒŸå\ä"êå7«¨WÖ«c]zäîhÞe=°ÂÀÊÜ ì­uª%V«úõhzcïæÞBÏž‹ÛÕ% (Flsî©JNÞãqyçä~‘ûûEkç3Ö›Vµó5w;°¼÷zзí\be¿ì½›ö¼ãíï|÷£Ï?}bᎾ ¬AL¡1=l¸&]ý¦ñ׎m™Ø4u䱃‡ïÿ2³4Bú3l­™XŒA€ *!¤ô RœæéÚcŒœÒGÑ"Z®¦Í´±!„ T,B!T,B!„ŠE!„ŠE!„P±!„*!„µMÎz,“ƒBhkÿþýìB!ƒ®X”+B!‹íÜ·o;…BÈ 099ù®Þ‘ocB!Ccc‘ÂBº”¨X$Ã{ßû^v!ƒ «×R±¿„ :sssü59Œp‹Bm,B6Û‹0 äÎ2.­X¦*³ËÂÂË]wœvºTžˆ<ùÓ}dås¯h=q©nîžM¿µš6t¶ÓÚ¹J;÷¸¬Î/ùRÈ–ÜýKú¶ä«W~ üV®z „Üù”v½‚ ìÐn°dßÊp¦G=Z-kcј¨ŸxùÏ—U¶¡{’_r½ÏÊ>Ìúåž§hÿ\=Ó»é?­[hSnI›xžçyÞç%/öx¡„^àµ×æ…þ×Ý{ì­³™-òö$WÄG’=­ËéöH#s/­Á±ÛŒ=Þ—;¹Ís¯"ÿê}roP6ÊÎr#º¯Ž;V’Ëbl5ƒBÑ÷_›òõ%Ö@¹í"[¦¦¦–Õɹ;çŽéÝø–uÎòžÉ5DLŸ,ykÿ¢ó¬ø#mNe„߈ᢠ¿‚(¬û@ÀkÀ¼·*ˆä5�óoPÐHOT£fï ~ðr*È!MøA5 ~Q³áQ0…3~²Ó!ÕÈ"×ÒíiÂëék9³Õ’xÞ ¼buƒA5ŠÍ©h¶¯ ’ É‹¸ ¯‘œPo"4 ­Òw'W‘;ÕgÌF8„°î›íA5ЧáÕ6üòG3ÒÁá¸Û?Ÿ×€¯¯}›#÷]ýs{eÍhs�jQäõêªçsY§¢>)ºJÑþÖöÞ¤—Õ·Ò*«¤#hÊõnz¼Ž«hÂ7{z TÅUˆÂ™“˜-–\™³ÅU¹2ªÖý°áË Íæµœ'¨Eq-’ IK¹ª’Ƈ ?þTÒž°ákù ª‘––&ü`6²tH.Ý„ï5à5R™t;Pþ“}‚j*„Þ ¼z¢¦D^˜ÏéÒ•+VÑF:âë+Ú¡³ãQ;ã¯å³êø_±Í‘+ö¿Ê úJ±¬¯Ò*ûV?#~1;ncÉp/C¿|­Ýä…1ÌÐl¶›a]6|9gb]Á7ò”É6|s1àŒrÕÄX1× ë~XW'¯§z)z#§­ òÞœ´GTSHëbÊÔkÝ`PKuHöÔ/Ün4Ò—?`{3°ÜÅjÇSÏoN%`Ç£Õ˜YË’ßxGäªýþw祊¬·¢ýWÓ·¹fÒ)Ä’°Ä)Á«‰Øh‡¡9Ê5È´NÈèÔ"­^úl‰åÑÒ¯¸†¸–Ê¥gæ_˘-‘Ð 3í1G™×F5]Ë)¨EMøÆ 2g“»0R$mö‹¥eÙ^q-µê´LêŽíºWpɯ"åje¦RïÇ£î är…¤H ÊÏÓÙy£ÕôWjè“óëÖ%¯ ²“C2ƒ%ÍHm21cm”-Z-¼:0Ó�ãè3£¿±¥šðúïÕSI)o¦ÓqßøÍቢԢ`62-Ѻ%¦O\Kì?Ë)WÖý –œÐrŠ(½¡EKö1mÂ÷ꉶ™ýÍUä;æ/êÚ¶Àr·td<êìCé幬–—ì¹Üó¬²ÿW<ãHù@é;Ʋœtä…° e̼+óUbOˆψAPKÌŽ ™9í`4Tz&)®&1 ìEP‹Âzª”^#5¼â*‚j„yàPb¥"§îÂxeæÌæºíñsÅÛ%Ñz.Íl}JL«Zz›®A–ËX§†0þèk³t,YI§µÓ¥¹û´¿±#r¹—k'�¯äpóVQ_‰W­Sa~íôÃr¯Õ‘¨Z«‹ø¥ëÖO~¡—DI¨ð9+‚Nk›ì)6S%݇yT5[s&ü/¨E˜¦–Õ"fZÓZ͆o4RýSjafÂÄè ~вÃâjä5ì™9q Z:ËêÊÄfgør{Ìk ™gÂJ4fûŒµóÝhç÷#¿0íwcÉð%»´|Žd¹—lC;×mór«ÇoçríÜfIã—õ‘^2šfe`eO„tÉÀÒº%ÓWhä;²t$º Œ`Æô½ðf’±;‰;0û7|( #9ݪ‘WG\0 ¯žÎ5[η°¡L±é$X\ëbŒôuÓ}Ô"Ì‹¡“HT ô1mâÝuh{Æ¿']* ×Qø"¨Ú´²œ‡–¯êØÅ{ !d Xn( Ž›ÐQs²³ ëqWAÏ&c:¤^2ñZa{h^˜A?¬ûq A5™ Jü“Ó-Ë©y-…ÓsHP³Jæ_3sæ5€½Ð>:O™€–÷OGÀëØz‰×@+HD^ËŸVD†Üšt”Ž6D¡í`^AÒ_rç–ßzXî îþö'Yg –˜Pî>jKúV8ƒàÎ(¼ÕŒõ¨(·¡XT– .[j©—ø ƒZ„½a/‚ùȬ N•Ó‰«ÍXT¢-#&˜pÆ×.>cúäÚRî êÅ-ïh“¢=„q ^=ÙÓOÑ&)²îSÚXd@YÈc(Ìæ]fV:AUËl´ü~îQ:@xkf™p<‹ Éj_+âjÑ•Ùǘ ‰¡6�¦¾Ù×Çšˆ>±´’ Œ¼¸Gwù”„Æ5X†£6§´))/¬I/}/z‚M{ÑÆ_²Fmzé‡B«ë04!CmfU™¥H(ˆApξuÞ �ÆÄ‰§aR%…4xA&É‚j«y/váÕ“TÆäjMqEf#?©Ù¾¾\•5¡çîíKp¼¹i›¬•n6ìôNnÏd®Òš?Câ9L&ùL`HP‹©Xý…©  F+¨FØ o&³æW;¾r³ æDßÍ’Ȉä_#]ó0Aí•Fzx<m16|4W£°¯xÁmîAX÷ãVªÑÞTv’Žeˆkv#>Ù'Q‘F+¡™YÖ˜åÿÔq}˜ÄwTF&έÜ%VÖâ6Y¬6üJ#Zø5*Vÿ(IBLé/¹˜dÈne‰õ]5r—dYñNèàÍ ¥&äò®D%éòêÉh劘¿C†o”L‚WÍkDÉÔQËk5/²äVÂó¬8u-·q ˜O’ù–Ül"®ÙÈ.ÎäÀ­Fh ¨E¨§;i‹!$!·–¤B—n8>@;å¹3ëP‹ÄÏvgäÝšXThé¥â1“¸Ý’ƒÓ‰Ólˆ& “ÕNf-WSeNµ$Z0R­Ï$­×wgÝl®ÔíOµ|8•UaØNS©X}ûVBúÅÜÜÜ’¿&_K2P´&]2¶TÑ`­ÃÂFFºŒ…„iàÉÌyZ‡dâ/Œí…y`^YLÃÌ~ɵDÒ’¶üŠ±Ê ¯í'Ë(Ú¦ãµÁ”«@Éu—ŠîÓ«µÜ®³$?®¢|¸d¬ !„؃¬Dßš5ÜëÛ„Jœ Ä:ò;“ýÉ+3¥›ÔüªEZ®¼0 ‰4u¤2¹ ¦“lOzŽÍì q®ƒN‹¨%f: õ–Îí$žOköÎÊ\$W® zŒn'„e¡“ #»X­Pr´B´:R€�� �IDATª99P¿ºä‡H‹¶0¼Fš¾Ý¬ó f“¿É|X==§¤�ÌFF®0Ÿ‘ wÖMî¢RP 2s Ópc1$2ÞJìkÅú›Þ^²ŒN8 ´eñ€µÚ¥]¯`I Ý6+éµsþ5¼Ž¤¨„nnc¥%žËK/k#œ:¿ÃÕxBVLI-]m[Há`m[„ {²'uŽÕ"ËàÕSO ¸›c“0¿*†ïͤ¡tª—±fö"žNJkS)/l/²’¾C¥±–4ÕZ`©n¬N—ÝÊí"]åËLƒÅUèð 1: uáLšƒª3+ˆ—[–G;Â_ÔÃn'·ÙÿK²‚RÈk¦ñ„¬À1(¥~µ·ÍM›;¡eY3RS­©ÔCØH“3%ÆÇmîŒÌz^­²î8¨FÁlÎøfÕ°w70Ÿ©˜åÝš,RD[XwdY%kÓ·fó}¤VÙ{q®Z~Åô¢3ùÓZ+W¬ÜzíE¥1r_[I¦Ýî‹ PƬ¬EMIµâv2·v¼øÅ 7ž•¡kD¹Émuö ktNÖÕÖ"×5'©Œ’qyoâ{´<ÉηúÞ­ÀîdÄkIÉ œñÍÔ€ø}ðîVIbÀK½s¹‰9¬|†¹NQ·òˆVš"aÖçÔ.ÄÜ…kºÊs;ŒtdÀ-’±6¯¸˜Ðбš¾HÝíVe’†ØxBºž”²²ê‰md鹤Va=Míš Ùµ´IðPÏ;=0K©ïßlfžÉh’™ãIëŒÔ"m–%ŒJÉáZE:۬ȃNP‹Vu`]Þ^ŸPkLy±`+Y»TÌ2²R‹å§'ú®X«©ñÃq'wD^nÆe%fížc­÷o³°=!ËÂ2§¬VgTÒ)kÍЬj‚¤Ö‰Ñ°x¸{®¨ã=ïÀí*¾cºuÎhÂf“«‹­†Ý©æ‰÷/®!¨)=ó�S\$<{î-žmÕQœNnÐüé©„¶Fö\ƒÏ ƒDq4¿e\ŠÚYJf© eÕnîŠbµù£˜´c©¬@Å»—G<·PÓ 5ž¹_IDZBãÜáX[ZÚ9–êJË7(‡·¦s~¸¸Hq)&’¬:”f’ >v;9Ñ~úïÕ“´E¢+&T8“Ô8ë¾UÚ# åŸNõIÜuGnæ_}9­g¹SeºŲ„J4ÜÿèöaÉɽ6,³"‡OȲl,+Ü:—y-2V‘̉eÖ“ èMøØ q»%cý[Ü|ø'HL´¤pT=)foR°KÆtSOBÏ%Y0”T$•±¼ÔÀ2¶ö"~Ál¤m—´Ù³©«Ó‚IQ®Yh—ÚÈL!Òh©ZnÖä¾TŒ†ÉµèN ®D±,gÑ’‘Íí[ZE/3«¤‡—ì7”ÜúMPôã }{·ÜœÆÓ‚'ÝCäÊXNòŸ±lÄD°_´*T…3©i•ŒõÿxøCøÈGð?õêÀtbWi×b²jÀt+óE-)i2'™å\:FP‹¼¬b‰‰D½¸b‡Z…<nKÔ%É¢;Ójö^ˆ¡cZ¶V\Y¯Ó¾šr§£tH­[n¼bl¬¢ÉyËST4–µ3Ï/Û/LSLw‹Û åýßþ#[Ö¹@OH®Å ÇkcôÈŠÝ\¢5K¡)#æØ°îã.àðÝ–a1Œò¥¬§ÿš«ëUP2ádFJ„ˆ’®…2%>½0*‹Û•*ìNCøLàŸY%ÑüÈ.DÓ¥³´½%Ù• × ¨…Ù²·rU°ˆ±eJE‹FŠò£Úܾ†íªöwh³s¬(ó?‘å6f OHG¬+7w­¬í56Ô²_¸“‚ñ­5Â&Mmšëo&²Ñ45¤†ˆLné|êZ9Zmƒ§rŸKáxBÉ¥´7ÂÀ€yijÀ¡(-t2áPº”XnJ¯‰ÖJlšÚT’쬀ά¤v×]•,´²’‰,®ÞÆ"„ ÐÆ’ì|P ‰r´f}t†Ž —4€º ”$§ji²AYö$É’eXUä.­µŠÓ'¶WŒ8NCƒ8Â!`/ð8pÞ 0`¶Uø¸ž žñ1êea–§NJGº±‚F˵‹R§·TJ–^YœµåÚëÈ :g!ÃŽ¸°tš¾4Ö¼e$é4¯: >¨Fñlš0YUCØð±A-’|ð^«ˆ T|»ì77цñ=Z{U0nF¯�þظL'º…½*uÅ0sc²,ÌòÚ‰¢Ÿ¡DpèdÁ¢Lº»´¾¢5×e•´²ß¶ãì°b1&²6µ´‰Ñ0Ÿ U·†i=ýã5Ò”I=øÙ( ǘO7Ä7(¦Uº”¸³Iæu=;e èÚ1 ô|Ü �x`RöÕ}´ Ïšt…-m«Á»5“*P,'ñø™æ¹@,J§ƒÒ!–Ê™ŒK •ÀúX]gnnŽ@ÈpÑ*HŸú¯ÂbU#Qªýš™*“KÉÈ’Ø"R^Ë”g4H^@›à=](²5A•DÕ§ãs3󊪙)¥@¥Ì0‹—+­BÆ’x×k ÙÈ™š€Û øI#¥Q®XZmÓóXéTŸ*P™«[®Õ`ŠÕ_X†˜á¢‚­êõq@dœ{^+òÂ(5òJ\ƒ×H’ ›º!nnt(úç“٣ح[Z˜8*Sõ;¼Fd¹Ý¼Fdò]xâ8ò<Ä1Ð ˆ0eú–¥Ìêf}Á‘[ß Œl 6ŠÏ’L-Hz,lØÅšvÓÝ6á/R±úÈþýûÙ %ìÛ·@ qÍ! ¦HÆ}¯‰<XÙödŽ'®»£æŒï5ÌTS¤™Û o±).< 4²ƒøíiÐ`¢…4²ÃW×úIM®*âixõ(®AÁë‚#-ã˜b�[oþ ðy|ôÃúM@d5#lµ¨YO‹2[«­“Ù»isѨ«ÄŒ£bÑÀŽ;ÆN ƒ‰ÎÚ®µÁ˜M•™IÑ&ÅŸ™ê…^q5Â4âi�Q2UkÉXq+Ãʱë–8q£U z�1< ¾»%œ�æÍ¢®V=|±ŠZz&Ò‚øNàá¯âŠÏˆ¯$ûëP@mƒB©ñ=ê@Œ°á£‘^Ô­`éFš†Ñ+ÈAy™››£œ“E Þ[ňÝe°féZ ‰WPòá\Át„yHyÓ ¹ ¸Çb˜Q>©èˆ¬9’”d¬¥ÙŒ\%vïá]_žX~I c=]¬×)K¹HÜ�Øñá.x·"ž…7Å54뉓SDIÖ(¯žL¹Y¾M´É ‹wƒòû€ë±!d…–çmåÇKêŒÔ"LÛiÎuED£ PñîaÃÇí0éÑÊèfÝ’xt¯]ÂÃÚÍóTã|¸#Ià$yuu.yi­HE¯܃pÞš¬w6I7 A-O©œÓ¶½²hÉ×¥F–U‹ŠE!…è:„Z®ôò)…µajc/†|*­/lj‚hÅœ'¨FÁ§"˜š÷³‘Ù"’`•×Ò±òélY’u7Y›¥í¬Àn`7âÅdÑUP‹LJÜøëi A¹_³XtQtס$¿f«‘k¡êÕ]¹’–ëÛ\m b7ÓhIîQ¦%døtiY+%ØÉýZú‘äM79–fü`6Âd™pš6·†°áwFØ›¦¸ ßܪy?“JTr•i{(×µ¸ÐŠ!4ç7 ‘˜;^bdyw‡€7�w[ÿ|_Kr~)I*hÖ„%SkYЦìdë¾$ ®t¥I\›/©•ìÌ~‰inS×™\²,m,j!d Ýòf컺 ‰T–LƒA5JŒ›y`q ñ,‚j„yñfüøoâ=×é![jP™ó¤é!Zzé®Éd¡×óB-‡ª jzÊù?�w�WóÀÑDµÑ¦—Ÿ¡i³ÜQØðEÕ©eì*)‰¢sþºÝ(JïÖ2^2-Óò«¤ÔHIÁY«Ü‘õšha"B–…15‚Z¤³ê@>« a2"דr!&³­×€WG8ãcÚ”óxð6à6“3I…úf¡q®ë,cóÍdþ,¿ïV`7ð.àÅÀ!�ÀÖÄ–Jrõ¶þÕ5½†=5%b#¦uÈäv’}DÀŠB0PÂnγ¤Kpå6Ö J­w°:;!„t‘ݰj½[C°Y!+c±Ñ«Ì•™d2ÕñV�ë€/�…CÐ&TrÚùœT~:º]ç-t3_è”Qf2+ž…7üð<0ïÍÀ³Éä–™ZC6hÞ8�Mƒ3v[Vft'KÌÜe^«R ²ž@©$ÙŠŽüÙN¹ g’rVºÔ¯â/ËŠ_€ÌUwŸ±H‚j„+F€á#ÿ ïûG#NVØ‚(Pù -QÜYâ¡/ åd g|“E0ÜÖÂ'y„3~R+ ©ÒëÊ$t·ÖŸY‰ ¡"PlSE·•¼ÒQ”:R1ÑÈI'áÒ뱤`£ü©m¦•g„2ТÕÈ ¦VÙx !˜¼z’÷È‘2+a3‰*¼óq툸Ô\¤5‚Ã5›ôŸñÖìŸÕ4 $IW¨Â½4[Ù¡âjZš+€$””5ñ° 8%Ÿ“Û"¨™\VºDVFÆôÒ4ëÆ½Öš³Ö½§s„Ç:bcY“O–‹o¹ÆM4BÈÀ¢VR *4NÊsȘ ž ƒ¿%]ÖcUųv@‡•I¿•©�òaØe±ªi Dªqrˆ3:ªùLüž‰ÂG¶z¤å™”v¦¢^O»BV[kA5V”ž¢Ó}(¯Mµ0ɯÕ+Ö’µ†—kQ1ø‚2°¤+d¾Q&×3–ÈÀ©9%£mw§¥b>£a8“�BB´³Ñ¶êvÙ]KO5á£J ¦ˆ0döiMÔ™¬ó»(oicK—at×N¹‹š“hŽz+_Tž}™”«ûz©Yl¬\ 3ÂãFRÈ·ºhm,BÈÀbªEGd�oMÆYcLhIÈŒà{“-RÞÞ6žôz¯º½º6Íù¤bõµ»;GŒ¥e&É$âÃZÝ¥Hi†ØLÆF”CÜ£´¹¦§ÙDDõ´œêÆÈÖz.§Ý¼‚®À¸j´¤YF•ê#ì|BÚDOÀ¨h‹l=ªiÄóÀ4ã«ÛU¬’JQ{£p&)4eÒ æÆûåF„ÃÍ"Ø�œô†­ÖFØÜmjŽÀó¢x6±çš ?nåƒ7É5¬�H¨\´^ë©f'R—QDI½h&¢<•Ò7ÛZ¸¡a#Í܈l°…nØX„²¶m,­úµjúŸ,ÈOL( œ-⦲"Tb+3¡Ì¹©Ù‹Òåùõ<e¨™ä2©:­#¬³JšA=•UdYÖ˜YO¦>[1ñ–ue|›zý²pK®3£bBHãtêJ®<{BkÆ>Ðü™äM7Ñz³©3ÐMý€–³NÖ,ë‹ê ˆ¢u¸¹)tµ‹Oo¯ f#]LÌ k™”«âùªÃZ àÚŽz6Ëš …Q”T,BY¶É%}’7ñ€M'sEb@$U-ÂwÀ6¬à‹dQTÖ†Ö,¦øC^ZKÏγ,³ô¨©Êf*)7r*W‰%$’lŠnÞEËÝÒÙ4,‰Ò) Ëa}¬®377ÇN dèбf¢È ÇH–1eWnÉk¯5³“LÖ nê]¹9ÖÙä¢i«¬ÑcÙ4qKš­‚[Ùhµ¿é\Åòã© o’Y2 gñÒÈød+w™—žké€Èk°¢c¿aÝBB†Î¢ 0±HúdÂI–Íši*(Á0’†‘¨Œy¡ë4ŠPIEywÆ()áXÍ@n¬„.Ϩ×öZzÐÒª(¨©\ï ?P:ï¶®L,†‰4 u~^'®ÏÄSè2ÇÙóØ· ã;Lg£ý‹T¬>²ÿ~vB ûöí£ùË4ÈÒ•,QJ —¤\¯•=]—åÕƒ²ÑkUX‡¶cÌ,—…×HÿµÌ>Ë 3Æœ»³1¡´n! ù3zœæd2ÿÊÒökýnd’[ÂÏ&953«(Õ×wjz&µäêéÌ‹ÖàrìØ1> > AÊß‹¡ [~’EÁÓfüEP͸´Ï*WŸnlضHQaC+ð!·ü¼±¥Ä“‰–ë/»CN¨a2´ÞŒJ,'IÈd™P�ÂßM蘆ÍDØQPš ã2M4L |næx*¿óýgnnn@Ô‚hÀP¿D+£4ÊA'ƒ8ÒâR@š—ÈŽ­È˜>u[¬ ~åSY¹ïZÍŽ•½¥'–š ?+‘ʹnä-EÓh6ÒI¬äZªš¥ÕQîŸnŽA ³„+m³Y¸6q=¹P`é5ÒAšðM D J%xknÉß³"Ôs“—g4¦š I!ÞU>7“Ûli¼yI¹d JL:ZËŠí6ÏC/…–ˆAq~ÂÉ/eÝ—›Ù]™­fè?»Um„A“+–^#$¨Ef••19d¡r¹šFn9€ÜUÀ¹’±Þô*.ƒ ã—Óf"o–¶Yåe¦M¯3K²]¬3šÊ“:×­dxÊŽKeW²âà%¯•¾µ6ŸËX;cµEêX•GrÇ &j³‡uGå–w)z(îE}žûh:u­ÜÏIï;³7]å#[Mç·ÓÏ+;ŠhKÅ„3H·´.ZµE0Î]YÆGQ&§–G&R—C:”žDMÈávš 3[ג艤’V&|ÑÌÅ5`¡ÑN©å8ÉŸælÁlÎøA-2ª,ÝÕ×ÕqVX¼þÓ-žÒ™èö’Ïwî(ÉïCû_Iê\Ãå;´oX©Î*¯U4|÷L¨ÜÆÎ#ë`ç/ÙÏ+;ŠØÂxÀ £\É©À»gl‘í¥¸iñª(BÏ^ü¤gwlÉÉÎc¥N7óXÈÆš'–Phé²Ë¼LñÉ UQ¬Zbi¬  €IðHÔ„ðZ{Æ<À‰()R_#–¢mæ$‹]õ –[kLZdޤƒ“%¹uÂŠŠ‡•_wÉ£Š~X´ÿ°dçò£úøèÁ<Ö²zleßæ]õóÀ>!")%<‰ N¼[â(ƒ“gÏ­· 7¥žìç%yÿ$‹„žÝ±(ˆ£8ÎLé3ç&?4Í6¹þ€4ã»™™3îMIÈ$‰q­")•82ÞQmÏÅwfœÖÍ"/}”¥R×eVÊöîfi*úô¯±9p÷6ûåzê¬ôºCäðdýÇj³’NÑ÷¢KOqZ9óIÑ^«À )-liGm~¹Õ7\K(S±‘3Лƒ8Ñ*£sV|‡•¨Âzaâ,´ ˜©2‰A—,ò¯dé5Y}ã*šžÞï¦>䪑w+�ijª^²ƒX¹^VwzÏû6ŸÌز>ýK~,çCo5=’zæzê Læ–}±Í’î¬6Ÿþ Œ’Ërvãaénl§óWö —ìçܨamÒ•$ÉE<ŸSý=ž…7“†‰›ÌxÍzžà5·ÊɧÖO‰kÐó2™Ÿ’Xó�‚Bw¢Fùf^x�âÖá¿«¢õZ;äÆõev{Oºs«ð�ü8à¡ ²þI/BŒ¦ç»ÙÝ�}÷¢KÚU+±±rKÝ34kˆ¬«Ž¸Â.Àg=¥–Meê­UÀi´›ÔllÉDo$½…xºLÛÌd’—þ'Œ° ?ôüÐ󽬱ây0ÍfÙ¢ßò<ÀCÓóõ¿Öð�ñžœÝâ=0ÿ™}Rái¥ÒSiEEÓó+qaIâ\»Ð2°¬e^]ñ º¢Å1ƒ<ŠñѬX­—5}ÕfçS®=Åɦ [^µÜaº|™­¬­]ò¯Ñ!al,· –µëY´$ùak‡Ô¼»32K²Ä9éf]ò0ì¢CF½¬ÂEeˆÝ 6kZÎMò¤ÃUŠ’}tR±.KKæÏÅéÔ×Ó .Z~TÑ»+¾VÇÊ~=—?²ß Ž"E^A™×Iò0e»k]eî*ëWDQ9+±<tÕ(¨5©¹æ!ô|ke1œ ÷™–ì†ì ¢èÝ ]ÍÄ\×*#™ ‰ôàšS²%í¸eyI°†d‹w¥oª¾\®æuW±´hµ9=t¿²õÝY¯{ïŒZY'çµä©†åêŸM½oäjº±ãºÎÌ =R7ác:)H(qwpÖ£Ÿ-bfOÆZ’ÿZžìü~’ýAŸGDÂ]Y §ì¥Â&…¬´ÿMê£ ÚPö´jWZʽ¤+O×8NDtF |-²Ì¯%m¬±6¿KnÌd^K®¡òéÔÉKÎßNJžKû²#×êï3êýµVÐ+~ÐåÛ^¤+‹k<or@Dfám3§ÈIdnR¾ší™ªží?”}Ü•OR"D{ ÝZ‹&,ÐȘ®!Ò„W“‘MøÍléŦjFn¬„Ié+a„r³Þ9µÌ~Sû ½t7=‡¤Lï:/Ëbw×cBÈÚÆX6q˜Ïå+y9&$1’ylV Y†¥­4Ë~2³h¹“uT _kŒ'Ùn¬"ì^”öPæÕPx©(êOŸYûTM{DõÍLU<‹à¡È ZAA*z*!„,ž£’_”Úwq×Òš?sÆŠy¡m,mÕi‘f¸Õ‚gµYOŒ‰Z¢ˆÖl“(™uBÐá¦´Š­ÈÙŽ·0¨FÁ§"¼ç=¸â¯ð1X <É/‹BrpÇw½¦Ê…UÖs¬‘+cÚÒÓKn €t&©–¿ÈdŽ5ÎA52E–½(j$É/¸Ò©…9S¬2/RÏE™SÙRô¦mÀÏ�¯Æ†´¥“ƒZ´dR]ÖÇê:,tËD†  nª¢86]ÕËÈ­¬¨ÎÖJ§µ­H-)Ò‰›ym°O†™r³ë@ê4†ÈFšŒˆV�¡eH‰èªòZ€ã,5©ß¥¦¥™`~¸ø.*âÚóa=SLÀ¤bõ V¹å"C‡=­ØÌ&QnÙ{7œÁ-Ho+˜FX—(ŒÈU/·¨£[ì1 š˜_¢–GˉåÚvq ¢ÖËKÚÙHì?ì6yr3·™IÀø»×7�Ÿ>‰gŸU~fÃo3ó«»ìß¿ŸP¾}ûø€ø€löV «V¦Ö˜nB Œ¤E¹©ó¬³å*_b¯´¢'¤¸‰>•§[²DÕéÈ”/AAlŠ+¡h['®FrBäÍ·… ?®FØ‹p&©Â¬ƒ;‚Z„zÆ? Døô}xÓŸŸÃÿ<Þª7üö ‹¿ßûIß+Öó øéj6ü&ŒÙÑÒ˜zš¯È*âš\%æ—Œ®i¢¯n²ʘn¿[…®Óa ,m¯èö…8Zr•¼h$:›º"§ià@Ë»¸7­! @Œ¼d•tk#æÿ‡’K…_tïT,~狹¹¹Q > @ýºέ/lÛ ?nÕïÅXEÃq¶$cN |88•M,µÓí´ÖZ%ºÒ°çÕ¬˜rý–Y‰dciR 4M>öF8¼k殼F²RMŒÈ¸ HlV®"³Vz†Ñ턲* Ùù$+¯«%c²I¯¶N¨c¸ÝKäšS(vîIh¢®Ýevª‘ä¶@vÅ•^)å”3N±* £•�*M°.ËÖ}Ww“·”çÓT?Aq˜ ‹B–'W²pªÈ(ÑÛ­¤´a£¬(T‘:º)Ï]É,:\«…Å0ëNL܆yg(*jl]B'Z4—döºCÜ**ÒVê[´²F•„ej–ö æ¦;[}·•¥JÃ`$›ÉÍ×›¶-YôY?/k7kcÑS.?jÉS ½@«ìÀ í ÚÉ–›Û²ur½[Vp¹.EN07Á¹aX$ZÉ‚ÜZ&’¶Ã—»ÏDvH^% YL }ÕÒü‡Ù[H‚*+¥nè Z³tÆ>kǺZž¥ .t$·æ*Ë7\˜èž//`¡ŸTîÆ•µä©.äç²âä4ä·¿Nq¤sàZÁ~VÞ#}ËÔ(¹\îpŸZ{5»ÌG‘e†VvÝ´ÎH5“®Ð½´Ñ #N:q”ìoNhùñLr É´kºËô’Nã«isʸÛQâåÙXíÿ˜-ùùïþî+wÀ*+SçªïA#u­°œæ = þöZ“¢62ëj‘Wä¾’;ÐN[#*×±DÙ9'˰+’=kñ2òêÿšûm:®ÎŒ…×ÈLæ%“XÉÆÄ“ü¹Æž³›Ô€DdÄUÀ„NGaÝO¢"»š ×–õ t•fÁ Œ‰¼2++)B:õ“bÉnç t`…¶Ÿ¬Ä:ƒQ‘¸V”°|Œ¹K}s 9Ö›Qв·¬ (NÞ'¿”ëå“$„VÈ»º ³±½2¡ðÖ-T“Ò‘aÃ7ÁîF®ÜW¨XºÖNQ]ƒ\É)R¦rWáPø {Y`¥ÍŠ\ôõñ'E÷¼‚¤÷V\Mb tuÇrß]‰2•W~r-KHô>fŽJ¿e¥ÜÕy›`eÈ&ðµ¤×òpJVÀÄÈkøzúMiö—¹(I~(‹¯‡a-ã'4+²M˜»„Ñ»NË•+Öjj‡ë¯bû߯Á¯G'mëv#{P@r ‹­²\Ì0êÕ“ùO­gÒ`͸o2á"o2&7rÝU¯+ªšci©ä{e2‰¼ 8áòVšv¨Z!¢I®~È&Ç®hŒ±¨Ì*« 5៊‚#‰ † ß«gÂâãjr#‰/Q½èŒb-÷‡-Š ¶3¾·c ‚\õìw±¥ßüNH÷±UWÉ­!Rd”ÔÐrýu®ù%ÖŒkétì–'í17ÜÃÒ3±É¼†-™ºúºR… ÙŠ$ÆÒòêj­5Å{ó%3“qÌ¢Æ�� �IDATÞ¾Vï«d´mç§î°ùÎõŽv¯å®Û!gIõއâ´dIÜ´~m12ìÊ,Î’ °ŠÖÛê·$JÐ’ Å 6|‰nùÑÿºÖž“;Je‚ŸÐ*bbén\ƒ˜˜FÕ’(Á½À^à'“ÔM:ÈP'Âr’ŽÍc­Àã^%¶WÉ\4û+°q—5±Ïžu;ÐP`M\éJ¹ñåRÿI×Û-¤¢uÁEE~ÅÎÓáãn"ykÐ×v¡›l©H€á»:PhD†u_ª8UóÀ4ðaà@Úl½97Òì`<‡åf¬ÍocÉÆ%w(ù®æ}¡–ì¥\ºÍ–tä!æ³XÁ§·gêàÆµú€3ÔÕHWo1³YázªÆ*2âNwe–L5–0ûZ'4áh¶kºR� ÊÏÚLõµïê™[ ËRY×™<°á›@vwù°+{Ú;Ô¢.F·—xÌ!d¨ƒnvZkÄwÝwÈ á+)DUoÞÝÙ¨¦øñÌìšÉÿÖ3r•[Æ~É9!ˈ,¹)KcôDWbØ©i3ãQÔ¦§H"Hø†ˆŸWÒ]Å¢/‚2ìõzä-*“XrNw©Snx¡,c2þ4b§ÙžkĘÍtš¸ÜN0žFtCºDk–Ë\N‹™ñŽJSå̲~K‚Gܲa½P,æ^"„¬+wàv-¡viåÎܘ%JE"áF–KzY;'J>ר’éîÌ™•0Ém³5‘æ:9ݹ7#cÖ\T®Y¦³ÚËô›$Á*õ±ºÎÜÜ;ˆ¬õÊ5›Š¬%w7ô“P¤Dd‰ù%©iÍá&0·¾°ÖB‘ËÔ’ÔJ­™­¨»ÐRk¤I+ÒK˜y2kRjIýÎ-[ bõV¹å"Ã…•õ¼hipQ ×¼@6üÁ’KlôhnB-Ì»º8¤..lÅMX¯u~?)G¢4ÕB¨øë¾Ü~†Y—p«…Y Ó²›P‘6V?Ù¿?;¡„}ûöññ  ]¥e ýK2¾#¯º•6¶ÜbÈFå¹±yyš‘ª…)ª!©µÐŠ Ñº˜äž˜¬ÆXÖ˜Õ?nedó%êfç¦Ù•ý©Xüý>°ô½b=Ѐ? ~6ü8/ºÝB['(X_ìXÅ‹&ºZ³GQ\Ô’,{ȹ¯£éhm®áå6Ϩ]ªmõT-M“E52©Ùµä�éÚ�'¯²z&'JžŠÅïüà0777 jÁ4à¨÷$ƒlȫШ÷ÑÙ†$Æ/žN3D”{ºJÞ ~³5?ä8ý²E@².;£%’0×jpn†\¯5³´´ã1÷ö+År%:šÛB{}[¶øä’Œð›I!Eñ[®ÞÊæ‡¬ã.I¡[+[}'Ð<·ªHŽˆ¶Ì/}©?’1ªêö%hеltÂÝ�Ë|lGW*ÅQ!¹E¼D®ÚY@FÅ"„”˜ püuå…€õú$w.*>¢ËqåHTÍ ÇÈ,6Édõ©ÜE»ÆÇX"0îj3Wµ®¸ é­›2áûr”;eå Ø’Џ´W‹‚Û链÷’•j¤¤¸sÑQåÕŸ¹$ôÐ= ö{u­> a±±Š<o:œÁ аÂðŠ<{ÿl8²ÙosËšœÔ 1§¢e¢ÉF듉±F™©¤Ë+ç9e*ç#÷¨Üulå!—´±Ö,:Åû’õPXr°÷ º¬^åê²”U¦n²%=}eY'Wäé ¾¶iôâÜ¢Z‹zˆ7ÉpïQ®¨SKh`®éS•äG^‰d7`ÙÅXrSºÖ—[÷«Älí€bÉwC2C»E§ÖFd«'äî9DÂ�§¢cß¿»Ir/ØßÚƒö€J~^P3ÔZŽ,1†Ü%G¹•éE3DTô 3ãUä`Ô¾AýŸn¡©7¯‹}¤‡×–N‚.'7{ZŽ;]«Ü²<{nR(ž1wi³VÄ×Ç2µ?d8XÖ¯?KÆý'á�–u(ú@¿î€›_|@ëtÃ,Û«eµ¦5/w¶Æ-"œ«7®•ct+)I¥Üw&O®®5•¦+¬EV{tN?60wa¯Îx+±‘¹†WI’@+U;™®ºâ,ÿ͸ö¾ƒS”Ý*ù˜ûãà‚5³¡¬Æä~kèÊp²áãù¥ÍŸnôDÑJ#7�ÏëåÏ¢é]Y‡H˜º®àIòÙrk&WoÌáâß3Ze:ŒéieJÔ$P™ ‹Ì©>Ìc-ËÑ7ì%V¿†ýþã}p~R ;ÅH_œÜaW4Cê ç L®ueEÆë%bV®(P3CZDK$Ç2€,ë°dâM+IÆ“ðÑ3­ÖÖJ²"sª(è¿»Šeùú–k £\ Èd: é –?Í ÇŽá\hrGdÜ¡È#çžP˃5 Ë¿VÆÁ˵«rs�êºV(È¥ïB:§¨lJîÕuçä–¸ì‘ÕŽE²,-K †Ë«3ì¦íšã¹?)rPß‘H?K·Ü)ýgQ%*w嬾Åb+Ivnþ"^^¹a}-í”Óç±v³ÚlÕ¹wm,ë-×3iÝ‘ëBA¼bû…»:<%ß7¡_¸{ÒèlÏÃY‡TäªÍ=ªýd•hÉ^åêq-1³r½U¹¯e‘¯k©äºUB÷²@Œ\‡žn•USÊÒN‰qÓO%BÔžŽltã>r}zn¸|Ñï�iXû)šÐÎ âÜÉ€e½Îýþ õ—ªhpŠ&=¯lÆ'5P-Yrãš@ƒ‰I‚·r¹Êë9™­ì±îÂ^äŹN°Ü:¼®Xå²¼FÔløå-l6|ä©BQ"Ú •ÿ×\Kê`¹Í¶Ò´Ëkí5ÍMíØ™võ”Þb½‚tqB† ɨGÞÜX/i²¼[nJ¤v®[bl¹ ÚZÒu§ô²ª¢`Å\›IgÂ5ÆŸ®Q"V£›‡P.§#Jôî}É…älEÆYO‹þ BÈÐ!qê%2ÔæFºëàòÜÐ ËÜYRÀ,ûÆcižH)Jky¤ét³«†µüÈi̸ÕLrÛ,QïnêxK±KNÛ;ÅÂÇB.4Ä<rÇP­aÖ»E9ÑõP^®LEÁu‰}S³§Áôd›ØCÚÄ)Êž®£ûôíèŒFHJ"J,Ù³lM3E—+B9%¾²º^ëcu¹¹9vR3ËRݹ©`+ª¢¼[(©!‚‚ü°éö:š­£Ôê];NÙÁP`2G…l½ã 5iª\cÙg˜0“îiÙg®•éî£k7Û01©XýUnù€Èpa•´/Ò7†;wüÍ-C\bÞÉÔ‘»^*ÝÞš² @«0±ƒµ„¹µN$ˆ{¿º,dægÁŽ«9ëv—©Ö˜H’›¼ƒ5ˆûÏþýûÙ %ìÛ·ˆhÐÐ…ä¥Hn Ýòâ¼V•©vÏÍF(6“ö§Y‰qáC¹aç®\vÕBj›–˜‰Û³hþÉÄOº=«î"Z T,þ~Xú^±žhÀPߘGPÐÈHÈ’U¯ríªË]ªåÚvß4*ÌÜU\MJj¹žÀÜ*Éî-”Ø@Fœ,•²|¤úŠA55þÜEw.mY9p©XüÎ÷“¹¹¹Q > @½§åþj…`ÜÜŭ؄ܲX‚vëYº…ÒõIº¾‰ŽwЪÖ ‘y&™yu)ºÑ6¯‘o ZöŸÕ ×jÔ­Mo³äåø°ÔT›€®¬öy=!„ 23�[V¨BQ™ ]Y±HäÏÜêõVå­ÜIké•ûV®=' ÓëEÂéŠ b ‹Š§¸XÆŸ­£@û–‹B2µ4à;løøpZ/Ê òÎM£‡¼´¶î^”É•ɨ¦µLJ×ùµj| ¿ž›3× ùÓ§CJbßÛ‰A/ýnÑ/€"–ö å£ë ]wœ›}cØW‰•w‘¾eÙ§ýƒyS=ûÀtûKz{HÜÚ ‰¹¨Eñnà€‰>(O‹bÖµ Q;úôŒŽ8ÍŒVŽ¥VÚ$4WÓœL–:†­xqíÓ»™KX ¡P°²¸¨FeØð­ÌUÈ îw½‹Öí ‘QÙI«÷«€»‘Þi!˰¯–ì¢òªÐKnìûh¾Vó{-ÙÛCúàÖ É ¾8XW¶VµKñêòÁlº×õži…eUZ$ôœ–^•[XÄ5r³"™cÃF~ G*l5Û¨ÿ•˜u½ÀÙHtçírªÜÒ'°±J¾oÖ ý+Ï$k—íÖëv~vû¨Œ·ùÓµ›ê%kx²nÍýÈ•o§ñAVƒIÿÎäWÖУR°«�„™Â!ØšgÒqnÉ=mfù$-%ȵo¬Æ:šUSÉ]Ô#X‚Úȭɽ[ ‘1Ô"c³¢`rνØXKþvå™ñ]õƒóÛЕ«6›W~S¤³î2ëO]¼Æ•«åÚ1„”#uƒj$)ûr#³ÍEË›r3A)™\ÔýÝ˹5·r(´q#¶‘¾—°ž&$´nMª5ºþC+¡9¢eL/"v ¯%›½BÅÊ­±4¤6æäjëý턬F®Â†/!ÆŸ–» ØL‰óP‡}[öYQj¾ò(ALaô,×=h9Œ>ÉÉ?S ‹ ›P‡lˆ锾îuÅ ´ÂI\)Šk@i½•vžË²ç±r‡‰¢šm !¿¤K ~ÀÈ ‰;θˬ5LVR ó®$¥uU'wšÇôÅÊy0ÙÍu¨žD Z¥OŠŒ6'Ó¶àÎ(¨EZY͵´J¹ÕL,M-/o¯}žnØ¡éLÙÓÊóÛu¯`‘ûe¹¿š{ÐÁ_åƒoþêOÅj$‡uÈ Ð†”®õž»Žª ?¸3Âm‰$�j… o-{µ¥àÔ¡G¶ä•¸ ád=·JAJ£áïIÒõub‰"±ÌA¢¯bå˜wÕ(×´LO+Í|×kˆ~_ ru¡KÞì°t-ÂA—ä£Dg˜Õ#rP‹p5ðãÛpºÔ’™k“¥ÚËULË j0F’œ!7ÖNúòZŸ*¨F^˜‡U&Øu-&ºX³gìĈ,ZA¬(,mÎ-iét›t K“™úÖÓàí|ë¬={¿Æ«¼%}l^iÿÖ†ñ~¥Í¹Áƒ|GK¶mm?¸Ágqáéä…<`XP¥£Éÿ~ ø5, ¿–³Û¢:ÉbëÅ1uÎ…¼åÜÖ8Þ‹ÚùXÞS%wôké½»m(y¼K,¹OÇ«(î¼hKûï¶óíêì7pYS÷½‘®ËzËÚ8P÷²šÛ�ÊmùÆázpk –LX˜ — +œ’$]‚ý©X„tÞL¡CŒt–}ûö1—?‹n‰;*éô‰óB¨XÃ}â|@„*Ö CŸ8!¤ƒ°¢#!„á´±&''Ù)„B†@±öïßÏN!„20l)T¬}ûö±{!„ “““ïúà…Š…þ9Íø ¸%§%ÃØ¼¢÷%ˆÜüð¾ŠÊ/Å…ÐæAk’5Öæ~ÝfnnNÌ»þ†o NK†±yå î±?99)]4°}5”_Š ¡ÍƒÖ$ݱ‚„B†*!„*!„BÅ"„r¡±ò,M¹•|1�é´u5diO/Û6Pu›†¨Gn¿±ÖšüXÝ“åçpe½Ññ~[Ãϯ_Íã °&;“\Èðs8Ä6–ülŸšš*2­´Öñ‡{r·–±% î’”Øvº©E–_ÇÕ¥è1¹Ý¢Û ·[¯{ðdÝŽ-jvg/í: Ê?fËí´|ò—õ˜úõõl¿=]zÜí| –üÔõ¬µ%_‡Ü×ýýª–_±S]´’y,¹XÑU¥Mnov°ôÉs?í7¸Û&N7úaeIËXnÛÌø«ÇâÜ~îÞɯŠÜ“—¿»š¾’›jçc¶¬NëÍ'¿ýÇÔǯçrÛÓ¥¯Lù· |0)om_¾é+èón|UÛ¹âê»h­E^ôR“rŸÖ²Žê‹ûnA1tO°«m 'ª5.¸O¶èݾ<ÊÕ7£K÷ÒÎi—{Ý.õù²FŒò^}lWߌ±nµ†ñäk¸©¹öÖîüAþų⑫e]ò ÅC쪬íÏó²>-C4Ü é—@Fã:(ÿL æ Xäöa}ÍÿoUɤl;—¡BW´ói®ÎéÁ@н±À=ùÀþ´ÔMµ&<†4¢¯KO¶/hXüåí\Áéñ×s¸>ÏƒÓøöG ¹‹Þ[Wí<úÕwéHWû·]–{rýD—|äݸÙÜÓöË0_n7¶oiõàŽú(áS-–ü˜õ¥…í7©üáöñë™{Å>öê “üRÈgµ+®þÛ=¶šÆY¯s7öÌðt›‘ûÅèA{Úé‡ÞôUùUVönZÛûOWù'ª|c/;jeí,os¿Ù—¶y¡N}Yúò]îãÀÒNÃVÙ*fi"„¥=Zd bBˆm ¦3ŸŒ± !Ä-2€]J‹BÈp@Å"„2ä{çææúئþ^}0[2ŒÍs™œœd_±‘ìÃÁoóÀv£wÓžw¼ýï~ô™ã§O,Ü0ytß¾}”qB!ò3÷]¼cbÓԑǾÿËô BÆr5­#§>vìºàêÒi;Õ°atJÃz�»tx? l9o‡·Ó©ÛYB±r÷[.sssâ`\ýÙº}ÚÎ6l¸<«“““Ò“Õ¥Ãûa`Ëy;¼ÎÞŽ@¯ !„ညE!„ŠE!„P±!„\h¬Ù¼‚+Èbi%lÖ……:’+÷T+nç’‡ iËÝJNCÔçìyöùŠ?çÃ{;¹-_c·³Ê¯ m,»û„¡¾—!-— Ÿ†§’}Éïöy?çC};nËרí¬þk²6m,鎒¬%ûK_»çéªý·‚_XåE]{f¹v¶å½´¹;Õr÷ó3\-Æ>_òsÞÙ;íˇØ¿¹‡¬æk26VÇm«pí’¿S–,[ÜY¹*ùѱ¬_X½€zÖòÎÞû¼¤å]*5¼}ÞßÛ)z|:kÙÆdVüh»ú ¨–wüÖzÓòÎâ=k¹~Ë —¹‹þ~ÎeTíÔéÙíä>ˆ!ýFä>ˆU~ÀÆVö9@G§ôç—ƒ{?Ý+²Ê¹ƒÌoDGÄêÇÈr/ßÙÀ}ªawè×Ga-µ|À¿œå}>ÕÂý5ÆOËØòŽÜÎP#ºñ5Yû±‚ú¬÷ý<îl_¿ÌlyIËÝswB°Ï‡qiÿvzâÛ¯§³ú¯É@(V7¬+éG=a¸‚,ú<jXyà“~wÉ–÷òËܳ–O)ØçÝny—"/úÕçÃ{;%G ã7¢Kb-G^è>Z²¿JvîøämÑµÚ om³yݘ§ívË»¹Ð›>ïà]ô²åíö¾·÷vÖØ7¢_® &„2P±!„P±!„*!„*!„2ˆäÇ ÎÍÍuð=[·O»z&''‡ôÓ0°]Ê–³å¼ ùvï¦=ïxû;ßýè3ÇOŸX¸aòè¾}û(ã„BÄ�x×ï˜Ø4u䱃‡ïÿòØš±!„¬mlÅÚ¿?;…BÈÀ°¥P±ÞûÞ÷²{!„ ïúàò𱂄B†*!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B¨X„B‹B¡bB¡bB!T,B!„ŠE!„ŠE!„P±!„*!„*!„BÅ"„B¨X„B¨X„B‹B‹B¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB¡bB!T,B!„ŠE!„ŠE!„P±!„*!„*!„BÅ"„B¨X„B¨X„B‹B¡bB¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB!T,B!T,B!„ŠE!„ŠE!„P±!„*!„*!„BÅ"„B¨X„B¨X„B‹B¡bB¡bB!T,B!„ŠE!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„*!„BÅ"„B¨X„B¨X„B‹B¡bB¡bB!T,B!„ŠE!„ŠE!„P±!„*!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡bB¡bB!T,B!„ŠE!„ŠE!„P±!„*!„*!„BÅ"„B¨X„B¨X„B‹B¡bB¡bB!T,B!T,B!„ŠE!„P±!„P±!„*!„BÅ"„BÅ"„B¨X„B‹B‹B¡b‘ ‘Ð <Ïó<ïó’{¼Ð d»çyòÚ¼Ðÿºû`ý¯u6³EÞÂžäŠøH²§u9Ýidî¥5Øãá#v›±ÇÃûòo'·yîUä_½Oî ÊFÙYnD÷?„ŠEH»T5áë¾Ùâ5PATAÀ¼%¯Í óoPôy‚jë< ¿ ßk$§’«˜3ÄÕä<aÃÌFaÃ7¯qA52—6§²ÚÓ„/lÂ7ÿ¹-‰g[—>�Ù9¨Fq^^==ÜœSß)€¸Š "Ór½Ñ\Åì, ÓH{d7Ù9˜0°áK×Å5˜¾â'P±iK‡ôvk£µƒ×€‘³§Ñ3ÜËžF¢D‚j$£¶Ù9œI®T£°îµ3'4š×rž ŵ´ÍA-’–ˆ´à�D;ãO%í ¾–O#"ØMøÁldé\Ú°×€ÖQKõå?ÙÇ(œiª7“(e<Û’Ãùœ.%„ŠEH[6–îeè· mpÈ‹ÄNª¦úd†u}`ØðåœF®Œü‹G†ì°ák#&¨&VŽ1ÝÄ& ë©™eþ½½‘ÓVyoNÍ)m™‰üˆÄíÔ7ÔR’=õ WûÅn“KÈŸF°½X &„ŠEÈJKÂ'q¾±±Œ3ýõ8®uBFç iõÒgGœ8åââZ*?–ž™-cN´PDÂõjš£Ìk£š®åÔ¢&|c™³É]ˆÃÓ´AÚ/––õkÀxÿÌuµLêŽ%„ŠEH[ˆ®èTÆtmiYSSzOk&É ÐòZ®âÕéœ6GŸý-e¦¬¼z* "¥âmÃt:î£9<Q”ZÌF¦%Z·Äô‰k‰ýg9Eã*ºÔ’ZNB±¥7´hÉ>æ¢Mø^=Ñ6³¿¹ŠÜ#½‚„ŠEÈ2pgªÄޱ,'=ã¥ýlbi “ù*±'Óª%A-1;‚Zdæx Œf‚JÏ$ÅÕd#¦½jQXO•Òk¤†W%1JL¢TäÔ]ï¢ÌœÙÂ\ÏÑuks”DOè¹4³Qô)1­jémº!T,B–¶±¬2(kMÒÎ@‹%‚Nøzà6c·ØjÉ>ó¨ ëÉLQŽTZgÐv›Ñ6#QaÝg|Ñ-2û•¼5ŸÊ§Žã°lÁ\ož–j³ƒ¶Æ´¿Qv“sÍP­‘„P±錱¥Çtí…Ëudɼ—ŽkHã)öf\j¢ Úþe2£yâC›†W‡vÊYη …3’£C¡ƒaÃkdËœ*Ù:c>ja¶ºBÔQß‹ØbMZŠnõ°6I­KBÅ"¤]KË5¶´Å £ædg%⮂(žMÆtYe­pÒ'Ñf,¡°á‡õTi̩̬RÆÞ²$A„M4É«Ãk�{ÓÛ=3ûXÞ?¯cë%^­ mc™?­ˆ ¹5é(m†¶*!+3­ô�mÍlYQmzË,KæufüàÎd]°˜:Â۲䴳.U¯ºï5`¦»ðÕ{ÓàÀDö¦a–åêÕ¾ÆØ2vž(k8ãk_¢UÊÐq£õÎ"·æO‚¡÷kéž®cP_Q„œ*!˳®äEºö¨½Q¯+r×z"<·f– dz©Ï …×qóf° 剼Í€i„oöõ±&¢O,­d,'¢-<ËJ¼y5X†£6§´))/,ÕÑ÷’;M%÷¢¿dÚ4?}„ŠEÈ*Œ- ް,0ù37“;|‹̘8â1‡˜N°d|}ñ,Ü AÇÝîV}-õÈIÔ¸ ²H/Z[Z¤£§ž¹}m ™åÃPK›‘Ÿ×Fª{ËДI>ÓfZB¨X„,ÃÒ2Æí¦ Ëh™&©õ£,*ãµK¤kaÃÇtÆ)kªÂ†Îø©¿n/‚;“\|q&U„‰h—õ¼’AÃèY€×ÒDz’Ild£ó-ÊͲh®(k™µ[OŸßý)`9%ÄšE#dpcÁ4­Òœy.;ä-ɲ× ¼�æTðêh¶bÓe+‰D¯E^=Ù&Wì!�Å�@ ~\ÂÂzgŸÈX#Škðꑘb­æeZ€¢sJ�� �IDAT›lT~Ks¬%0q ˜š ¿üfó(ûÙÂúÀ ¡ ¡žî , ¡EÈ2¬+Ë£¥`Ö´;K¤]^®‡:CàIŒ_¶^OLIëÖýÄC2Çc¼j:Ç eÿsJò3µ©:3Szó™<‡V¬`n']N»R“LöuXöåŠP±Y‰•fÝn-²èY¦Xî`­Ã,Ϙ±‡âðdf4wãé9•¸ç•+rÚ΄dÖlIK$?“¾ºµšJ¿ÖkE½J èÜóíüÈ]†¥…Ùy>B¨X„,ÃÌJ+ZÕsÏêÛÄ5È´ž”’ V»Ybeæ¢ÒB!Õ(5žjQ*WóðÀ4$nЬ&Î䂚N²=é)"+¨ÝuÐiuMLÉh½¥§¸DÞ,U¶²»Jï¶!7;!T,B–@{ÿ „ 1H2ÀÖÓAß-½¨_‹˜‰´h§¢ sz ³É‚ßd>¬žžSòϬ'Ú–›¢ÂòìÁ™‡³b“§áº@ųûZ6b][Òd£6þ$š‘6¡b²<«¤–®eèü–m‘kv˜qÙ.!µ€¡ÓR´*CJí(“<P7&9ù^ĵ¤Tqbº5Ò\éÚ½™¬«Ú‚a¥±Ðup`vuG·‹´–‹Á$¶šN¥U3©\·³èBÅ"dº%)ò¬üîô•‘­:FN‚,´<™ñK´ä6wFf=¯®ô(QòA5 f“èŒDZæ3³2‰—ZY'Ì(Èè¡Sýj©s•I”ŽÔ’Kþ3ÁŠæ¢3?!ã/‹åaE"è¡V­– KLYk9Ê2N¹VŽ%Ë™ì|«ïÝ ìNFü¸Ö²ºZù„3¾™ú€éT¬zÇÈ[å–!ÖïJ“ÜÊ#ZiŠ„N ltsYé*Ï„P±YR Ñ*¢U™ÐÕ#rI¸y=uñ%Cv-­4<ųÀŽD$¢¯‚¤âbj¯ÌøA5)Ú+¶‹)¦%fYbÁ¨”¹™&ÄÞyÐ jѪ¬ËÛëj)/,]§;éâ&ÖáFhõd?„ŠEH»Ht_n1b‰¾ƒÊþ'æˆÔ*Ô¹nEÃâYàîm¸¢Ž÷¼·«øŽéÖ9  ?˜M®ž¦,Újžxÿâ‚ZFÏr‹ÿš×ñl«Ž¢Z×%.»Ä^œÏXQÚât-¤"o¡e\¦¥°²Jf© ÕN¸<!T,BR3Å s‡cmiÉQÚ–BË7˜É �¿ÜÜŒdò²› Œ$*áPšI6løØ ì€ä c+¬û^=I{QtbB…3Iã°î[¥=ÒP~U=RÜÍ,š¥Cå¦-³¢ÕÁ²ÌÙJ4ÌèvBÅ"dˆ kè\æµÈXE2o$–A’r¢†&|ìN õ†½À}ÀGÂÄDK GÕ“bö&{¦ÞãŒ'¡gÈt.ZphIK0a/â‡ÌF™DºÒìÙÔÕi Á¤(×lº§ž+)l/Òh©ZnÖ]ÇRú ySƒ„P±)Cw�c9ÉƲÁq7vO8“šVÉXÿ_€‡?„|ßøS¯LC×F+nPræ&¾ÇZR ²‰¤ì½™ÊÒÆ\’¯]¥ØHîâ À#8Ô*äqdŸ –´H <CÇ´Ü]1ífåЯӾšr§£tH­[n¼"!T,BÚÅ*H/ÉúÜlCz@·Æb)4%•ãñ„»€CÀw[†Åt2ÊgPOÿ5W׫ dÂÉŒäèÓ)6’¡ß”<~ø<ö¨,nWª°; á3fQ”Dó#;¦Kg!›])c°M«DÅùó‚ZÆJ¼Ž„P±)-=€ŠƒNÖöÙrïª.k„µ•äú3ùmoo-@6K©ØæL¡¹Ê!ž:Oå>—uW Ò„½ÀÀF`ñldhvj¥Ù4DVÝÂöéöºouDË#j”rI/Ï“ åŸ$„ŠEH[h[J„ *BAŠJ&uI˜&A¯¥áãIðzkù”qýɘ,{Òž=QG76Oç÷³$VB&a/ð8pÞ 0`¶Uø¸ž žQ²’´ôrB7VÐ$BÔ.J´Þ’(qCûµåJ¯ ¡b² t\¦O—Ç•,±¢g: ^—c\CØð±A-2¥°d€–\zVÌ2PÜpã{DÖÃfTÁÄ\xuà�ðÀnÄ5`:Ñ-ìU©+î„™+IôžpõLŒ‰Nle»G^žx³³èÙÿßÞÙ„Ê–fezE‘D\ )²ÆIMì‰ÅFÔ‘Xtà$¥G•ƒ ZHÄIˆBœŠ5 8δèI ®àÄ;рꮒ 6Êq$¨$5È¢±Aèæv°¾XûÝk}{Ÿˆ“çêó$çgÇŽ½#oî÷®ï{×»Ôà~‰�Åx¤ØŠ¶ªvò'{¬õ¥Ç´.â­c$„WNVÛì÷͸+xQZ­ÄÛÓæ®%¯ëÂcz ë ©âçÍ~`Ã÷k{ßìU3ãyW–_›O<Y½3‰ ŒÊ),ˆ~y5$•P¥–Ф²s%#B(ÀÓñŠJ£Œ"¸¡=£w“?ÏRŠz"VÀ|1Í]y¾Ô„áÆb¢• ClP¹O=4OË”ê ×…µ–`ë[JïµÈŒ‰ª½²ÞõÀ§ØššhÌ»6|0Éþ01÷×î4›Æ j­–’ »ºkÓ..þìŠp)þ!¹^ yÝ{K>$jÜqMžŸ¤‡ùËÇi[÷-!Ðõirªw'yºUæBXó&â MDr2¥åqìÛ@MERÁhòùÁɾòËö毘äÎ‰Š†<MjÊé®X2b,ÈÅ X�WOÿ±¨Ïý4HÞ¦®¹1?éî!¶ºæûa¾â}Wù!þmK–¹¨`¢KÕIÝqGm7Nä²ép/í•öÐaköæ5û ³Ÿ±ßk·eÙDØv'mÃJ¾Wëa×Vk�n÷+xμÁG�ϱÆÚÙQlºõât<؃$3EmË$<L¦®ö6lOvcÙÚ>Öîlm?Øp6b¤ŒÝ:⤺Ó‚asÃÝixßÌÌ«]ðƒ­W‡Qº†ó^f¿€á¥Ù?ýµ}éÏÍ~ßþj\fLºøÂN¶7 cýM NT#Æñ°¶Ãø¦u‚euú… üj,€Kk¬ýX¦¤ÂBMnaôö¡1ºj{E­Hºãˆ|Ipóò´Ùµ¬?è˜c[0ü.wïZ™<ÊØûf_³˜ÊèE“v`½Ùqxã{feöð«öG½zdž»ö¾Ú¶Ï£ò¥N›úÚ­´ÛÔ_KÃ:*�ÅxíüMF1åQNnrÌùD½öã£Ù;ÖömóøA›îW¥‹q?ºw€-Ø,¶‘v'{Ëì;bô°Ñgag«z$ÍÛy‡lµ7{ÏŽ?´>¾ÓúcqlP™¸ uNqW‡TMuC‹ü@@±�>t¡Ê•¶O©Bø³û¸_ÛÛv<¬7ßç û>VD(…Õb³=m¾{²³÷­mkmO! i¼–zåãÝ[ų;ç$í¤JóN¬·ÌÞ²áÿ·¦+ß?ÛlOÃߌ‚q¿¾]ºh’¬B3âï²%¢ë~°Ie­·¶ ðÜ` ž#›mÛˆZNÃÝ)Ô"…ûù"X³£KÎízsw²WÑæa}»Óq¿Þ¼<Ù÷ÍÞ·‡ÃÚìtüò¤ó·=Ðý]n̦³ýª^Øi8¿Ä¿µ½=˜yhá ;™n½oö5³?1{ÓìwÌþÞ<~óëmò`fçwv¶ÚŸ†YGyÞRº±Õ¾(ô¡Ði÷­²*?q çÛ<Åß6ÛóPc\ŽF0¬nóà]B.ö¶Muc›í©7÷f÷6ìl¸³Íöd÷¶~ľò[öõ·éfUäò…G1Âmuhuh¹ÚÏÇÄÊñ6Þ53³ï˜ý˜Ù½ÙÿmB¨E›nùš¡_³Ú#cW¯©ÎnRWEâ¢fþ¦Ï3 ôiê ±L€b|´2k×L€š ¨F¾4°=‘Âñª= W{;Þ®íÆÇy|Ãì¿›½ë™Ib;\N÷i±¢ýHX·ËB"Veö5³ÿbæ¦Á7ϵÔaláÒÞ¬¶6¸_wU<„MuÈ»ªã˜°dÁ°^W–’º³P,€‹ðaŒiÖ{z»ƒ<žÅ) ÃuË7™Z@û/™Ù™ý…ÙÛû¦%T;í}'ÊOÝíš[XÝ52ª%ðÞÙêÖì×ÍþÕìÞV_6ûAÛÜŠ15Í{û”_p­ÛRó¯6k�|jdV’¿Ñ¦Û1IG X�Wà¡J¾3¤ã?ô¿:ïý¤§sk×=gdxE²ÙžìKŸ3ûmûÝ_³o|ÏÅ)Ù¢@±’a¡š±yyšKŽð‹Yšùðx»öÁãÏBø}³{;Þ®Û¬,IxjQûæ!Ô›MÁ†&”\b&9RÝrP]”êTly»f‘ž-8/à¹ÖX3¡K‚ZßxdßÙ,~jN„ýúÁZ'¬UØêÃa÷A,©Õäü·Z6é·Ã›Óo·£W~uné=Þ®í¼Yõ Å[ÿùh¸x8—Pj$©MTçŽã,Wæk§ç@÷á|¿*cÞÜug¬Î΋ó½—É�ÔX�—  V1 Ä$ 6ÆsÄ3×Äž æïð G?Ö ; wÙСáO*œ9ôö›–Æb¹„híXÝYªá\Gu¢•w€¹ _ßNK+½�­Ü¬áÅñ°Ö^æXMSZô3Œ¯½lã €b\$WÚu{h‘íue¬ÉÀ˱œŠ§móÝ©TÜO4Ì^u Âz ‹¹ª;ät>Î¥n½[{QSBT<b£ÎÍñá]Œ_i±¥c«y½6577Ç~ŒØ¨õe ¶_k«�ŠpºÇ£ƒêµØÅéuœ{R?×õíö“6IäЙ2ö{íswm E=CÆWaðJ« 49;>b4W:^«( £òœÜºý–æë%…ˆ¦ÔÊtc›Îz@±�.®±¶“lÀ1?Pì›íɽïfç6,³ã~Î…(›lmo·=¤˜nlÅþg½n\5jcVšáN0}ÄÁÞά#†]®Â¨ wo1VrûNf|¤ZŒç.ë™fã†>Å"jºw2/�Ÿ²Æ*‚äÌv—Äq¿n ¹÷­„²éÐ0ˆûdE“9Å)™Pg*¦Fà¹X£¹!¿yÔÖ«IT‡MçkJaÄ êVÖ\I”ª1×*m|NžøT]¹"jÿrp$áŠp]åk€µQ·º·òB’œ4ÍÖ…ê<þc\ ¬Ñv^¬‹že}S5AÌõá&UH+i­Ò˯(Ë´ JmRé-ª¨D´nê°i*‡Ùd7+í Æz&5 X�W×XUÂÑy¸ÍþwÓöŠ¢€ˆ¹Ž“S½ÊåQ2_´¦¨é2šÉGoöš0zæ²U]ªÌÆW½UVOU§aÅIBÛºcuÙ0Õ‘þjšF’¨˜¥‚»P,€§{Q±Á3ÙÚ gù¾¹ò’]"–È40præ]^7«qæú¦5?©.ß…ÿ—ø\~¢JK×o6{ZÌ©sRß½ãUÃv,¹Ò¾]\ªªièæ @±�®CmßÑí4Nžv‡3"|áÉnçËb}Bs=R“w¼ÒÌ‘¹½+_m‹ê$.F«4¿ÔpF´:lwJÑS©t ÷ÛqM/n'¡K—Qê¯Ò-¨¿c³;u—aP,€+¤ËÎîA5j§ôtÿm4Ò¦›Ô}¬a²s³ ýq_U¡n€E1—n ‰ÓUÁ(û\ÀÂFŸ6½’‡Ð÷†­îV–w+×½¨¨®Â—?jØnrÀqß.‰–,@±�®@óý´bЦ쩻ÉÃë:^+}v§ä<¬µÈ\Ñ]Zì¶ñÆJfE?—Të/Ñ 9€Ò.ænÈúñvÖý’¶År¥×R«s¼“šì7»™€b\A(S ¤¨_Ç¢V(“ïU_¸V9 ï5LÖÊþPmêŸÌ£3pÛé8Ö$\/ÃôhfvÓG¢—ôè”áÚì[k“ÍkÁ{¼‚€b\σ­½à—`L‚Ws]jïÕ¼¥Úd½&Ùx^w·²ª·bn!1 ‰GÆ%ëÍvÜ©Òlø(}ò5ßçeÏ´{g%_*ÝWMvײ5.C¿Å+(ÀÕlv'/8b‘Ð3d'ªp¶<tã*jÙ‘ê§Ó±ñ©^Qa01¯{b…M] Ú(¦S†ãj#W{ż%˦íÀ3äÎRÖm$<Õªtäƒ\+½5þÈŠð”ê*ì :ÆIå4¿Õn&/Ô #…V¹ ©P§xšŒ• —î”úr•Ÿ¶šws.évmñêV¡vMW&ñ÷“8Á[oîNž¨›¶ÜRm” Á´;UóU¼P,€K™lPÖº\Vw˜"^VëuÍu7fR‘¡mL]ùÔZ¤Ž¥×#ueÒ¦»Jn¦wò©’aiÃ'oFýˆ¨Àh(n¦öÛvË©ï8¥C%GÉœúz w#¦�P,€e¼÷ÈsŒb N•¦ôª`Ôú¦–O†"nOª‘*U#ë¼+íÃvvôy%G¶1]w­Äñ7Š©–X‡¤HÿYÛB{Ù‘RëMóšûÛ€^³‹hÒ6þŠp)«ƒÙ}Ú[S4ìµú÷êôäËCwFzaí2NvÁ4 ÑÎ>‹Tñl¶'÷ ›¤­›tnµÓ¾Ý¾õåP¿ßv^Úf{Z½cf6ÜM.#]U¥›O_KL� à)¢åŽïÙh̹“d}õ,*­TÓ¸H¨/#µå¦‘"*cãá­%ÁSR ó+‰¢-Ä5%b2¤†šxùܲ¡ƒ"›Â}[ó¯:ñNÝN¯jЯåÔ‚Ô X�K$Uð^«ØŠd£Õí¸¾×Öô$u)Ê—È"Jï’ÖÇêÆ4E>ubÍ „Ô· ›ŸIÎEéÚ–”IÓ=4•J}’it¤Ít%WqK¬×=<Š-@±�® *]dÓÁ6]Uë>¦Óó·ÛóÛØheHÇÜÓ\ÃdUÃ<¦/=å/OÞ’e’o« ›v¶ZLÖ*ï-©Q꾊@¤FU’U˜k“uj¾@±�.ª±¼•Uì©)¸öºÆÞ•Ö1݇xª<tj”I°>ñuˆÉ×ñWíë·Æ Q\½3ÉšŠÌCuɧDÁZNÅOÒ§1'ùµ¦ô=°9m£Æ àjôIíMWÞªÓâk/­ÚµkÔS ±µ2C$ò�cuΦSçkgqU{¶d¥ëoa©°™ý$ pÒ:/)w·”¬uädvÉ­üî”Ê/j,@±�® :×_ØÉîmµoÓ:¼¤x]¬‹­£¤jšÑ§éôÜ})?O’®´@yñí°³ÕÞŽ‡µöT©hI47ËXw¹â<QÕEeÖ]Êóí=½°æŸŒ§,&;%Åx:^Ù [óM9Ï›É2W<¯«ªiœR´ai•–ê'—ÆjX°ój¡Z*¢£9~®B-ãjì¡ÚùºÙª7Ýb(´-*E­2]Þ†;Ûüã)™Vl&Š�ÅXBk}â‡r¤}—ÚK›ÆMYñêò`JT‰Ë¨oª‚§jafº1¦)P*ŠvÞmÒ2HO¨†Ž9XýúÙ"èL›íióÝ“}ýëö¥?¶?´ôXÉv@±�Añ|WïC~ Ocœª–Xi¥òâC·—j€EÀ¸“´ëwàÚ4)zœ7Û–˜êÅP£XØ´éÆ• djÓ�_ë™!S€}–¢_ø¢Ùÿ0û9ûáñŒy³;‘+(ÀuønPjªÇØt—¨þ6¾ÿ·žÓU°¦E¨[abÉÛw®¡àÆÅ{q²¿«(¦\ “ÀøÚœ48*k! »ÑÀr<xdðWÌ~ÂìÿÙ‹vÖ,ÁdB@±�¡=»÷“!îÝQUa|¨rU§C¥_i±q…fÙU?7Ô1©ˆÖI›í)‚n»CîM–ûjކss]ÏidÔvÃÎ6wÅdwê[?nöSfÿÛìÚþõ¸Ÿ_€b\!ZZs´1;Ù4Ú5ЍÜîüF}jÏ)_+Ô¦SŒÓ©B8ë„bm GXRaZëK"¤µÎ3Xn*>™ak>7²Ma~5Þ²¯FÆúdÛ0û_göfÿÍþèwŽ_Ì©�(ÀÇ ]š Û4f?qëéê\-¹jù¥ßFfR Õ5I/Ôñ%zmuNGMÔU»®Ž¦Ò­M9L²šR„|Ëθ1{ÕV7wÓ-¨û^Òà½Ùï~Ͼñ¡}»©ZtŒuç§� X�Ðͯþ@­™RHDm1ž[õÒ‘ŒVŒò¶>Þ.5çêLäÙ^«›,W “A´‰J›±Òmuá=ØÚÞ¶(°bwª³(úÊŽ·ëXn²2ÙÜP,€+êªn!¢‰šèR¼Pô!ùÀŽšÌ”d »òÖ½Œî©tcLgwÙÙ[¡¥¡j›.j™•ÜzUu(³«ŽŽeñÝ©*ÿfFÌßJ눠X�O©±´qª»ÿ”~ž\y:½·ûï*ewžˆ-î“åÝ>‡ç¦åD×°î–íŽz=±sÛ{u£N—uùÔJômT¢ É�(ÀãÌÇ­ †©É7mG¥“tl“T$«î]Ñj°›ôr-‹®ÙXîèzfdòÚy­Oï:Bu½ÌJ÷˜Œõñó.Í÷º X� n8ÒzÍ÷«+Z)ž|¡ºªN¼zIÃ.ù˜«ÌªŠÄõ×E?-€|ƒJƒ£ÆEñú'Ãd$íúÇ埒æ†èè/-§Ì,f"c»€çÏ|ð ‘Hí«ÍîVúR>ì%η:#ª[ˆ$²éž“¾dAöªµ¡Ö~¿SÍÎ{uÓñ’m«ýðä-ÃvÐ ²ìÚ-X[·< fvs:î×ínIÂj,€+k,5VhýT;™¬·Bh‹yëüø…:¬:ú¼Þê& ¦z«N6éŠh7_ª®dFaútJLa6ñÙk²Æx Û6:òxhC#]®êÁ�(À#eÖ°g‹¤vZ›7Ì)Óòä§Zl%!Ñc|˜ˆþ*m¶¥p©T„uU¶»Â©ý^&q‹i¤}iÞ¡Í×ê¡ë„«ƒmvm&rØèë¢%�а„Êçû1š}§ °ÑN;·3—±ìÊKR‘į†ïuG™ÔßVsD²xè¬:%½ÐS-Bc¼¢ò.+Ù|÷´ù  êñ°ö‘]qyöÝH[K”/�P,€K‰p[“ÙT©ÕWßݲ`a†–•õºZ~ikp*Œ4Ž=•qqQ v·…’žEM7’†L¶Å½Ýäv¢ÍK_ë•–¾l=Åo÷%óxXGuSÇŒ‰Ž€b\KÚÒÍ•å"&»±‹óhÖÂ^m®ŠƒU*lÎ+xXÇxßýw­öjvÔ˜;u7†&Ýv¦©T›Ý¹Oëm³·Í¾j«ÛñLHT®ÞM‰Müñ àRbo&Ä¡Ôõ—Gß’ÎÛ]¤¹¾à¹!¿Qç©}<éM¨ZÍ›÷­¸¹ZÐKÓЈÛTœ÷“�øÕÞV³³oš½/[™»~H?ÀWù(À–?j»]Vu‡IUÍd¥Nœ«‡RËÔòU¹ê´—ÜŒ)·iþomÈÕ¿”ºTS£jµ§Ûx6³9yñ½ëè K®ýú.sk�(Àºe3½Mõ`ý:Yøjö`}jwöÕÅß]sM:îÛ>Pš€ÕõÜ/Üã…7•DN7ºZa'Ûf1ëdŒÌØö/ ì¡m u à:æžõµlºäUú¬¯XsA…¾µãK]§{ü¼[ÄøÁ¾Vm×~^jèFšVì»\þv*f^ðéÐ/“ôßlÓO†ä @±�®.°ºîZ ]Ò¤Õݹñ¥9‘¨Îòˆõ‹Á’éùÞ-ª""½îœ¥À¤zÍi#MwÂTµ|tK{QݲL—.cû-B°�P,€§XËã/)°j8…¯ì%×_7#ô&â =W¢FohüD·(4Ù%ª#¬½Ádë3‡ ÄÊ”ÈGõ;ŸH\@±�®.°ºAGÝÇîòvQªB´ái®ðJõêJäJØt¸p’%•—ø6Æ‘„¶iÆ’Äýå(©ú9Ä…¥·¨á i·,%ävÓP,€+D«;t±{d×Åž\ã5]¢«sêÊKƒê­óÒÈ’ÒW5ßWcx%ìœ=“쫊W™¬ŸÜÕyØŸr‰[�ÅÈ}w{"íų8i•†ÆšL„ê�ª$¤q'Ñ’¥«‚.<6Ø5æ- ú µ‹÷Õ¾¨äB…f}6íiëºKê°.Ž�Šðt”Ôœh…×@sÍ»‹ê3[LÈu]S£éBß\F»ÌF™µu¤ÁŒ-?p? w*­Zºuåʤ§­–˜¹VÛ!W€b|4¹êÖ ©²’RáOêÕ~RµÌU!éçËŽ½*Ý 2™?2)ªöùÕÄ‘*]3Ô  »õ†¤ÌipýzaˆW¤I±$(ÀE«>…çf_YoJˆV-ÝSÍ#%cB"úQ?¼Ï§ªkƒîP_˜åŽ:ǤÒ§›òú)^µlå˜ËÅ�@±�–ª„º¹’ž°ª ê�´© oáù«Kz¼žMóúª4껥qVU]Òõç)„¾–Js3!ªF»ï¼ªÛÇva€bäGpxùÔ PÖ’[Oܱ‹3·ÒåÎ-€âås³õïú¤þ@’bÓ5À®é©òã­7"YuHKϚήNê Y([P,€‹j,Ô¦¿ø§¦î+á¶Z*éñ.õÝmºS¥ÿ¨Âù¼yö1¾|wQz¤êéÔbnaØŠMgtYYÃTaî®@²•(ÀÕ5Ö\‰ãÏ÷¹øönfnÒ¼5(Á�� ŸIDATînMw™®+¥©ÊqÝŠõÀRÏÉÕ<ø1®p—ó24ÓOý÷Ý$*M¼ÕTŽZx-,Ц ªK’®�P,€~5÷œUûxwKIc#l?8g¬ÓŠkSWêBitE1^âºUð"|v¹šéêMøà}}¯¥FÆ ¦d©W#‰IïÚ\9…\ŠpuUƒÆµzˆùÂ]éVWÉo%Éb¡Ô[ÕØR]œT�¥êpaãM•&Š$¯Ã<!×÷ítNqRS›&NÙÌÒ"«‚€b\A]O‹º1S‡ÚÌ´FMÁ˜[‘«'Ty˜kŶ­ê>ú»uUݳéHe+Ööz:ý²–tsïž’™°`�Šð¢bHÏ_-ºy¯s“¨jç¬>¾£b[;OOÿêÝHÂÒÿº*h=ï¾Î¹¯5VúU]™Lw¤ÙóÝÊÒ P,€§ð`k‚µ™Õªî×Ñä[+•îò º/1’<TõJ¡ºI;Ã'Rã'º¬ÒVS YïîÞ™$htÕ7ý= .ŒN,@±�žÈ ;÷ëH­õJÝòôØnYf‹ý³Ý ˆK¡Æàú婽"]aX0l±ËJK¥XßóPÁn•f3YV¶ñ¼IäºËª�(Àã5–ÆOij8}GKSZÝêf¨?*– ÅV52Øt£JEê«+oÝšIUÖ‹? Þª±æÖ9[ª…sMÖ&æ‘…â �ÅX’ð©/ Ò�Æô\Öêg¹†˜[[øaÝŽò¢PWðBJmjå˜+¶jpT]¬Yò ×®÷úªß2f¯,œ�Åè }õª–~;—‰®òeeš3×µúf—·Át³M£:lÆvŸF§KòΪ± ù°^v”$ÙKµ¦oÑuEÈ-ŽÝ¥QVŸ‚ñ—|ÕF8—enâ5˜ë™]˜0R½ˆ:@Äeuu˜¤4Å[ÔT/˜tF¥ÞHT<‘L˜ÂŸl½¹;é‘éçÒè»õe’1T P,€§×XQ^$\·$JµÂ£‡Gß=d*œêkwÉió·Öõ>ąŦT÷JjÅ£aƒM/o›`§fµn+XÄÚŒ‘¤†wÍX€b<¡ÆòÀ¡´•ÕÝ šË•¨’Ö]U«/¯íɾë£Ö†Zšø5wÃÔç´v.×#c±ê¨šÓˆ“|/û~ûóBÏ�¢(À55–‡ãݹyöX§QeÎùÝ=,¾žK)—Ñn²³<*žå|^]0¬ËwuΤŠSR)-1u§* ñ6“œµ*ògP,€+k¬ý.ÞÆP½´ÍöäÊ‘â‹:‚7Q·Å©ós£#Õï »>ÇýZ«“'µvßH¸[ v+˜²éÆ••6²Úf½±XZve�Ÿˆ¨EF{ú›fg«Âܘ ¬8'Hñmwz}š¼Õ5£§Ö«ú«ôFzG.·6öV¹­Þ¹NçÎ_ý²raÆ#�Šð8/ì´Ù†ïãamßçE¥r¤£g½XÛúŸKcª’ iLêW }Jis2Ð!9ç÷‹m°H «á£•вðèoçþ�€b\Tc÷ëÕÁ6»Ópg›m±kNfT¢Òb œU3º‹bUD× 7éu÷‡Ü1¨ÂS—þ"«"Ég·yyn–J$W- YÈØ½®®„%A@±�®# rö–Ù«q£¨LoŠ£·.iGm ÉóØ´5Jw°üùòÓ,RË£®ƒÃ_«.öd—o¶›õ7ªg=î\þuÙ0¥¼S`Šð‘hEÏíºݨ­ÁáKœÛNáUuÂz>ˆTEéó½{LwI× 8gtŒÁÁ>’QÑù q›Çý:½ïÜb©ƒð“ϵ`#Z€b\É»“çµëi©àÐæÚ›º“ «’é)ë¹ÓÛÕ™[]…7Qé½÷“Hx=OLk´ÒŽ–Ò“sDãTkáõèe X�³ßi1EÇÃ:,¾žOí”÷z<¬cñ0ʈºJ6Í·ìT3…ëYwy0-<šMô)Nîë™:OD Õ²R¤‘¾õ}£ Lv’*EaóóV�P,€+p­j!åûÉC¹*á¿ CAUî6OzèG•òà> µêÅÚc}2W´…8ùµm^ž6»“*k$<UùI_w­í •¢õr˜"ÑJò€b<…(84=yÿÒ³xóòdï6I0³ÍîT-y6“ÑžNee½M›‚S¬Ÿb"¨¢í±½7¾Jçÿêœâp‘ÔìÚnØR ¶ÅYŽ5ä"D¹ à)èHŽ(J¢œJOäÍîd?fö•/Ú{vܯ7»¶s“úœ’è*ŸIbEm:Ž\ÁÔ¡œÔ.…-%÷àf{ZíÍîsTî\b“‹®Eä\qü*½uW¡SÊ9@±�ž‚RÝ1N9½âg;gö·øcÝCžâ$a[H¾;Bª[Gq6ÜMZ©êŒãºKTµAõÒµõØŠeQG,º!Ц)š¸¼ÐÂ<gͼf€O™7øà9ògÃFLþýßš¹™žaî$釛oßñëòÃÞI†™‹æOþèaÃü/ÜÅò}-t@��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X���(�� X���(�� X|��€b�� X��€b�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X��€b�� X���(�� X���(���Š��(���Š��€b��Š��€b�� X��€b�� X��€b�� X���(�� X���(���Š��(���Š��0ÃéûÕjŇ��Ïa–+”Ëìsçë?OøÉ§ó’GO²ú¬/àc‰}Î>ŒV6è·OûÉgu’øö5ºæËNòºý_òèOV¯Ûÿ%—œäê7x-îü?ÌŸ9V�à5Å�� ���Å�� ���Å��@±���Å��@±���P,��@±���P,��� ��P,��� ���Å�� ���Å�� ��àyòÆÌϳãÓyæ|hö!Ÿÿ‘à£â;žxÏò¿Í0,)Vú5��|\¬V«Ïðû1¾ûNuùKŽdU��^P,�€O‰Ïvëc|÷'œêò—,‰b��5���Š��(���Š��ðTÞà#��ø$X­Vþ…šßº?üÏy#µïêÑs¢X��ŸÈS>»ñu÷‡ÿ o$”éÑ7J°*�ðñó2?è㺩ažv* �àSªQ^ë»èFŸ2(��rõø] Ã𙋊�€\-ñ|îÅ�@®^P,��x=ÀÝ�ðI•Yñµ×[ºôºT`Ýkþ$nä’s¢X��ŸÈƒþªŸ¿v÷òÑo¤žáÑs²*��¯(�� X���(�� X���Ï‘Ñ+øù/üèÿùûÚo~‡��ž ŸÿÂv+ý��à9ÖXüó?ðY��Àsf5 ÃOÿâWù ��à9ó—ú‡ÿê¸ïñв����IEND®B`‚����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/thread.xml����������������������������������������������������������������0000644�0001750�0001750�00000025306�11222161077�016250� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="us-ascii" ?> <!DOCTYPE thread> <thread> <info> <name>binning</name> <version>June 2009</version> <title> <long>Binning and Filtering FITS Event Files</long> </title> <history> <entry day="26" month="June" year="9" who="liz"> Original version </entry> </history> </info> <text> <overview> <synopsis> <p> When an x-ray event file is loaded, ds9 makes a virtual image for display by binning on one or more axes. This threads describes how to adjust the binning and buffer sizes. Interactive data filtering is described, as well as binning in three dimensions. </p> <p> Note that the terms "binning" and "blocking" are used interchangeably in this thread. They both refer to combining pixels in an image. </p> </synopsis> </overview> <sectionlist> <section id="start"> <title>Getting Started</title> <p> This thread begins with Chandra data from an observation of the Antennae Galaxies (NGC 4038/NGC 4039, ObsID 315). Open the file in ds9: </p> <screen> unix% ds9 acisf00315N002_evt2.fits &amp; </screen> <p> A small section of the data is visible when the file is loaded, as shown in <figlink id="defaults"/>. The target of the observation is partially visible in the display frame. </p> <figure id="defaults"> <title>Data loaded with default buffer and bin size</title> <description>The target sources of the observation are partially visible at the bottom of the frame.</description> <bitmap format="png">defaults.png</bitmap> </figure> <p> By default, the buffer size is set to 1024x1024 and the binning factor is set to 1. These values will be adjusted in the following sections to illustrate how to make more of the data visible. </p> <p> The "Bin" menu, shown in <figlink id="binmenu"/>, will be used to change the setting in the following examples. From top to bottom, this menu contains the bin function setting, blocking factor, buffer size options, and access to the binning parameters dialog box. </p> <figure id="binmenu"> <title>The Bin menu</title> <description>The blocking factor is set to 1, the buffer size is 1024x1024, and the function is sum.</description> <bitmap format="png">binmenu.png</bitmap> </figure> </section> <section id="buffer"> <title>Buffer Size</title> <p> The buffer size determines the size of the image generated by ds9. By default, a full-resolution 1024x1024 image of the data is created. If your input data file has larger dimensions, it is clipped to 1024x1024 in ds9. The buffer settings range from 128x128 to 8192x1892. </p> <p> Setting the buffer to the smallest size, 128x128, illustrates how it works. The data was centered on the sources in ds9 before the buffer size was changed, creating <figlink id="smallbuffer"/>. </p> <figure id="smallbuffer"> <title>Buffer size set to 128x128</title> <description>A small central portion of the data is visible.</description> <bitmap format="png">smallbuffer.png</bitmap> </figure> <p> Setting the buffer to a large size, e.g. 4096x4096, produces <figlink id="largebuffer"/>. The display frame is filled by the data, and the panner in the upper right indicates that more of the image is available. Clicking and dragging the viewing bounding box in the panner will display a different portion of the image. </p> <figure id="largebuffer"> <title>Buffer size set to 4096x4096</title> <description>The frame is filled by the data, and the panner indicates more of the image is outside the field of view.</description> <bitmap format="png">largebuffer.png</bitmap> </figure> </section> <section id="basics"> <title>Binning Basics</title> <subsectionlist> <subsection id="basics.block"> <title>Changing the binning factor</title> <p> While increasing the buffer size loads more of the file into ds9, binning the data makes more of it visible in the frame. Binning combines the specified number of pixels into one new pixel; the new pixel has a value equal to the sum of the original pixels. (Note that if the bin method is changed to "average", the pixel values are averaged instead of summed.) </p> <p> The binning can changed from the "Bin" menu or from the "Bin" item in the button bar. It's also possible to step through different binning values with the -/+ buttons or the "Block In"/"Block Out" menu items. </p> <p> In <figlink id="block4"/>, the buffer size is set to 1024x1024, but the block factor has been set to 4. A larger section of the data is visible in the frame. </p> <figure id="block4"> <title>Data binned by a factor of 4</title> <description>Five of the CCDs are visible in the binned data.</description> <bitmap format="png">block4.png</bitmap> </figure> </subsection> <subsection id="basics.cols"> <title>Binning different columns</title> <p> ds9 has the ability to display any of the other columns stored in the event file, although it is generally only meaningful to use the spatial vector columns. Begin by opening the "Bin &#8594; Binning Parameters" dialog box, shown in <figlink id="binpar"/>. </p> <p> The "Bin Columns" menus are used to select the columns to be binned. To create an image in detector coordinates, set the first to "detx" and the second to "dety"; the block is set to "2" for both. The "or center of data" box is checked so that the center of the data is recalculated for the new columns. </p> <figure id="binpar"> <title>The Binning Parameter dialog</title> <description>The parameters are set to bin in detector coordinates about the center of the data.</description> <bitmap format="png">binpar.png</bitmap> </figure> <p> Click "Apply" and the ds9 frame is updated, as shown in <figlink id="detimage"/>. </p> <figure id="detimage"> <title>Image binned in detector coordinates</title> <description>Some bad columns are visible in black in the detector image.</description> <bitmap format="png">detimage.png</bitmap> </figure> <p> Alternatively, one can display an event file in specific coordinates when starting ds9 from the command line: </p> <screen> unix% ds9 "acisf00315N002_evt2.fits[bin=detx,dety]" &amp; </screen> </subsection> </subsectionlist> </section> <section id="cube"> <title>Data Cubes: Binning in three dimensions</title> <p> It is possible to add a third column to the binning, creating a 3-dimensional image also known as a "data cube". In this example, an (x,y,time) data cube is created of a Chandra observation of Jupiter (ObsID 1463). A cube may be created from any three columns that make sense in the analysis. For instance, you may want to create a PHA or energy axis to see how the spectral characteristics of a source change over time. </p> <p> The data file is loaded into a new frame in ds9 and the "Bin &#8594; Binning Parameters" dialog box is opened again. The "time" column of the file is selected from the "Bin 3rd Column" menu. The limits of the data in that column are filled in automatically. The "depth" field determines how many intervals the column is divided into; a depth of 25 is used. The completed parameter box is shown in <figlink id="binpar2"/>. </p> <figure id="binpar2"> <title>Binning Parameter dialog for a data cube</title> <description>The third binning column is set to "time" with a depth of "25".</description> <bitmap format="png">binpar2.png</bitmap> </figure> <p> After clicking "Apply", two things happen: <figlink id="cubebox">the "Data Cube" dialog box</figlink> is launched and <figlink id="cubeimg">the frame is updated to show only the (x,y) image of the first time slice</figlink>. (If the data cube dialog box doesn't launch, open it from the "Frame" menu.) </p> <figure id="cubebox"> <title>Data Cube dialog box</title> <description>The dialog box has controls to step through each slice of the data cube.</description> <bitmap format="png">cubebox.png</bitmap> </figure> <p> When "Play" is chosen, ds9 cycles through the bins of the time axis, essentially creating a movie of the (x,y) position of the object over time. The speed of the frame changes is controlled from the "Interval" menu of the dialog box. Any of the 25 intervals may be selected with the slider bar. </p> <figure id="cubeimg"> <title>Viewing a data cube</title> <description>One interval of the data cube is visible at a time when displayed in ds9.</description> <bitmap format="png">cubeimg.png</bitmap> </figure> <p> The data cube can be saved as an MPEG movie from the "File &#8594; Save Image..." menu. Select "MPEG-1 (Movie)" and click "OK"; after setting the filename, choose an MPEG Quality Factor. The Jupiter data was saved at a quality factor of 15: <a href="jupiter.mpg">jupiter.mpg</a>. </p> </section> <section id="filtering"> <title>Filtering Data</title> <p> The "Bin Filter" field in the "Binning Parameters" dialog box is used to apply filters to the data. A filter can be applied to any of the columns present in the input file. A colon is used to indicate a range of values. Filters can also use &lt; (less than) or &gt; (greater than). </p> <p> For instance, to include only the hard-band photons (2500-8000 eV): </p> <screen>energy=2500:8000</screen> <p> Clicking "Apply" updates the ds9 display and keeps the dialog open for adjusting the filters. </p> <p> Multiple filters may be specified, separated by commas: </p> <screen>energy=2500:8000, ccd_id=7</screen> <p> The resulting image is shown in <figlink id="filterimg"/>. </p> <figure id="filterimg"> <title>Filtering data</title> <description>Only the hard-band photos on CCD 7 are displayed.</description> <bitmap format="png">filterimg.png</bitmap> </figure> <p> The filtered dataset can be saved as a FITS file for use in data analysis from the "File &#8594; Save Frame as Fits..." menu. </p> </section> </sectionlist> </text> <!-- <figure id=""> <title></title> <description></description> <bitmap format="png">.png</bitmap> </figure> --> </thread> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/binpar2.png���������������������������������������������������������������0000644�0001750�0001750�00000020550�11332353404�016315� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��ƒ��^���è¦ä´���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ/€€‡Ú�� �IDATxÚíy”\Õ}çï{µvuwuU«W-- !!h)€–`ˆ0&FÈŽcЙñ±GöA#ÛqŽg<ÂñÉÛö8''¸gr2Œc“4Š ‰3Ø`aŒ2j##¬¡n-­ÖÖ-uUoÕ{ÕüQ¢(½­^­o©ÏçôÕïÝ{ß}¿{ß÷þî¯^Ý+¥R)!ÄÆ-Ÿ��§ç¹Ç…Þ´ m½ç^,�•gã–Oö<÷¸´áÎm[ï¹÷Â¥Q,�•çÌ©ÞþCû¼é¦§&±�XJàÆF†§'ò˜ÙjÃõ ÖæÕP¢™é©ì£ç¿²¤Ajhh˜››;1êoì¸V³ÐDì|hôØ©ØìÒ~Ÿ®�`ÓS‰é‰ÑÎë®3ŸåÐáÃBˆ@0dU^m%’”}´y審sûwl½ÛãñüôéŸõ …"-Šœ³Ó“KCgb¢uÕFEv�¨¨%Æ:;;óÊÒÙÙyèðá@M­Uyµ•HºRJ|`"²òÿÓïÝ|Óµ«Wx~Ï|mƒ×ÌN#_z{¾Î7êh¬k +�Xˆ$IRþÞ€”Eåóê)‘¬8Qm={òâ¾}=ÍÍM+—-ÚÿÎk­knârþ‘þ·®k ¿Þ;¼øºë 6ß®?-ËÒÿꟇG'¬*ÀJ$¤ò»ä5å]ž£-_sì­=££}²,7x¦‡úÞl¹zbl¨ÿª¨ØûÛ¾ŽõÊYÿýåODÃ!!D*%&§gŽ|üç=g‡âBˆÞ¡ùÙ©3'Ž"‹<^o P| šUBLÍÌöžz⹞þóÃvèj߸÷®å <üÃ_þæèi<P?ÜBõl›tNyúÂÝzÉ¿ò·?1“÷Šdš |"½@OûšM§÷ý4(¦…ÉäH,E[¦÷-\{§${LÞòo÷ž½piÃÚUׯ\òË_ÿîO½¾à7Ý=ØÿŽ${ü"UX¤©ø4ÔíÔÙáøèÊe‹Ö¬Xøß·oþâ_=1/LݦÇ#ÏÏ'ËÚß.ïŸNLjëM¦¯@•Àѳ3‘Ï ëØ×VÝpsμ}áî¯þŸŸ¦?ÿÅŸÜ¥—×ìììrWöZ×Þ1ô›g|!ËÒ¥¾7äæ–ÙùÉÐÒþš:ó÷üó_õ¼ôÆÛ›7ÿÒŽ»›£áØù3ÍW?öõí²,}á/Ÿ›zìþÿ,ËÒãÏýúŽß½¦±>ôÆÑÓß}òå¹ù¤¢ûë÷ŸÊYÂÊŽ–Ï~ôææhÝ[½gGÇ'oß°ê—ûŽîÚýºfUÿe÷¯~Õs¨µyÁcß¾/\jÍŸŸvn»ãê%-õ¡ÀÌÜ|ßÀÐ~Þsf0ž©À?îÞ÷á[:…HÝ×õ㟸]3å®¶ !ºŸyí£·® ú}?yé­g/}ö®›4Ô¾~èä÷òj2™B´Dë·mÙpí²VŸ×sìôОÝ70ÿöÙÚÞB|ëO?#„øÑ/÷?óòAÍ”ê*}é=¹mó†[~gy}(89={f(þ7?Ú32>ÅÓËìLo†õ±?þŠ:ñ¿þÝCÙ“'ͼ_{äéo}þ£iÊ|Ψȫ(_VÇŸ„µË6¦R©‰©¹”Cǫ̀¯-ÒÚ!™#YúÐm¿ôÙmßúA!Äî=ûæçgSÉdúÔ¥^!RéÏ›7\ýÊþ#‰©é›:—­[•.ËgŽSÆ%„‚þû¶Ý¾°¹áH_ÿÄhìëW !&F.Æ/žÕ¬ª¢.²à†ëצ?'SS“‰¦hÝK=ouÿ¿ç;ÑyUûýئ¹™éL–ßqãÑ“Žôž:ÚÑI)„bëûל:;X[ãßvçú/~ü¶3†“Éä¦ëW¬Y–„¨ ø¾úé-ëW/ùõÁcϼ°wõÒ–?»çƒA¯xù@_|tBñêþCO>÷ï===s“qÍ”ê*-©O~ø–ëâ£ãÝ?þÅ3/¼ššŸ™>—šŸ“ÀmÈùÿiäMwÔÕë6)þÔ¤yÝ?ÿ¿?K§TÈÐêu›´ò¾çRåð‰Ò$ÃÉ”˜Nù¯j®óûý¾yIÊsRzãuW§?ÌÍÍÇGÇBõW|Ý677—þÐÕýä¾ß“R©­wÜ´¤-úâïÔG[rž2.á}k7ÖÕ.ÆFþô[xýÁºÚÚu+„©d2™Lz<ÊèÒW>¿-óùpï©£ÇO7¶/{ðû??süP]]ý =o?ö+¶4Š©K"°(ìoÿñ©Ý{öùjj½þšû¿ûô¹þwôR>üè¿î}óíøö—·5=»çõïýóî/î[n]·¤%üÚÁ“·lÚиÐõèü5u‹Ú×w®XÛÑðô¯ܸ²-®ýÙ‹¯¿yô´ìõÝ¡“²§7¦¨Ò¦uBˆ±ñ‰3ƒÃâ‰ÇŸÝ;=™ˆ¶ý^¿Ä»îqŠd!Kä’$Y;¯^i™ãúyÿüïvÿÏ?þƒ+dhí×Í+N$„=×;7||¶¦%ìOÌÌÌLOO‹™‹cÕ7/1Ë=òÄ¿½ºÿwV_õð×>ÿùOÝuàø`"©|99p¾aA[ÒãBø½Þ™éD2•Ìyʸ„p]P1pnHHžÆö¥F²Þ&—4n¼÷ÔÙ‹Ãñ©é™Ã½§žyá5Ÿ?ª­Ûñ‘›Ö¯þµ5L2¿Gšž¹\Ô›‡ûê´×ÔG¼éÓwݲáÚÿ¤—²¯ÿlCSûÔ\Jqìä@M}dNö !|>ïÌôd4\#„X¶¸õÉGÌdokŠŒ½ÑëñøÒÿÖÔGü5umÍ ôR*ªôÎ…‰7ŸXwí²5«– !‡G¿ýØîó±I¡5WâD_a]9ÃÒÍûÍÏ}8{N÷?¾÷¬æuuâD:85ë{-1ï½jýæÉÑKÿ}^óBˆøÑ—õwBfB§—Knhj͇’É”,K ~1>>£N:??ï äwý”T*%R©œ§ŒKˆ&„‹ÚšýÁ ä޶&ÅLYQÕtœHöú$Iö×/ÕGo½qåûo\qvpø¡GŸHLþõWï•eY’¤ä»Áà™ÙY(âóùnßpÍmëV¤LW/Ýxsóó¾@P~7êŸJ%‡ÇBˆþ³þf×S™: ÇÇæçfS’$„%Iá G3z)Uòx¼ÿÓ‹3#65|ünû½õ¿{MûÓ{Ë™Ø]J$’ëòTIV‡ôBKÆy¿ñG[2ÞP:´ôÍÏ}øëßN}Ý<"Öɹىã{…$-¼áN_ äkͯºuòø+€ßçó÷½X»Ùäýè¶nH¬Z¾D–¥ÙÙ¹ã§ÏJ¡F}QRéX®Sú%¼Õwflbª¹±á¯ÿì3“sâÚå­YѾñÚ†Æ@mX¤„䑽¿ÏçO‹ˆßçÿÀ沜ɒÊn!Ùã•%9gJ!ÉïE¤ÄƒÃþ·†GÆ;¶~äö›Ï\†k¯_Õñ½¿8~òÂÈø¤âSw°ïìðËÞ<vV/¥¢JW-üÃ[®=r|`rjfq{«bdt|4vaAÛ2IÆ'rgÄúÁÏÞ©—òþG‘3bmÎ'ÒÈ›¹nzRvÿ£¿HùÆmQ_WO‰4.<9ðfS½0|c¸©=}¤qɪ¡ÄpGý¬ÏçK¥R§OhX¾Î|œhfvîè‰ø—gc£ã- í&\Щ¬»˜žëzâßv|d㊎ö_<öü+onÙtã|2™QgÍ\þ`(BÚ{ðÔÕíáWý·[ö簾gƒŸf#™L)tätzfî[ÝÏý‡M×lX»òýÁ`llâHßéÞÞ^ÉÞ½÷í¶hèš«–¬^ÑñÆÁcgÆz)U™˜’%±ù}¡ ,1õìK¿~ê/ûë¢Éäœ×ãçv™œkzýÅÎ÷ý~¶+¥Î›öet/d˜7#Cé«Üÿ÷Ï?ø™ÍÚ×Uœ^ŸèÄÀ âDâBïÒàÈþ±…kn˾X*™œØ·~uÇüüüÈèèÑ‘ÚÚ–eÆ7êpO29Ÿ©ƒ×¨‹¶kë5u'í"Õ¼dUm8ròPOæóų'ÆcC5õ‘ƶ¥þ@͉ƒ¯›9¥WB¸®n ¿ortxnnöá¯ýÉõ«—?òçw¿òÛÆ¶ß•?aIW5Ò¼°~A»×ûžˆL%Æ.;93•eO(ˆ_J¥’M‹WÔ†œ:üÞE%I6L¹O‘N9ðιÙéHËâð‚¶KgŽOŒ‡Âm^Ÿ?>80916;•HÔ½`CÓšÚú‘áócÃægç„H5-\^Û°`äâYÍ”§Ž¼‘]¥ÉñøÅs'çggRɤ,{¡ºpÓB ÆëC‰\ÂÈÅóWüLýàÞ_ê%^só—UéБ†¦¶räÍ$Ó<˜Î›9xo}"…°ÍŒ]Zšx§¸õºù ?Jòx’Ík3ñÕW/Kè?>1¨‹˜©¡e±?X“å¥$IöC’,GZCát²?×E[‚¡°×H‹®ÉSzÉ>õ¡õ"uãÉÓç¯^Úvýêeã‰É^Ýïõ…“£+ªz¥ØCõ‘¦EBéT°6ìõùÓÙ³/*$É(eËâ`íå” -‹¼Ÿäñ!êÛjÂQ¯/ „$Éž†æEþš‘”$dÉ#IRJ¤<ŸäñÔG[½Þ€ÇçK[2% ½”Š*ùkê¢Í‹dÙ+yä´æñú¼~¿I§œ±^{Ëæ‚#Ö%Ï«8hüfã'Æ/öMÄ‚¼¾€ºÜ`møà¥ÄÀŃSSS³³3c³‰`ýzƒJG[éjlíÐüªkY?¬5yJ/Ù™¡‘ÛoXvÓuK'§gzö~÷‡?‰M4-n—då Y·ª’TmÊy 9R¶½—²aÁ{c‚Â7ñx}ud¿Ç· UqP3¥¢J^Ÿ¿¾±•Ǖٙ¦€Y–Wsvvêܰ»[j°ÿèÄh<9?'˲7Pnlñj‚u™o²ÁùÌL%&ÇG¥£CGjêüÁUy3G.;ùÞìÌõ/¹…´kd¯7=µ‘=Þ`M,óM6¸ôr?‡1Ÿ¥¦®!˪¼Ú³3׿äVS©©ÐeÁµbª „꜕WC‰Ò>Qb4F‹@e…£*ŸHˆÄh,ý{q�€ °ý]1"P�ÐÕÕ¥1;Ë&c&�(ÝÝÝŠ#øD�`=(� D��(� D��(� D��(�Ø…¼wpŽF£šÇc±XúT,V²¯©¯¥(<sÅìKY Íì9Ë,¾ÅT[ÏP”YªFÌÙvY²+_ÚîQ¢Êw3×¢³f!F£Q;ØÄ|• XòQ Ü©D&ˆ2É„úŠ ç(}¤˜ëfgW ïê[Ó»¨æÓ¥~D+óÈ\]¯™ÊQ7MçQa@µ=õl^O,A._§ÅbênTÂÂ5‹ÍôÈ2uMÍ[Ó¼¨â)ÒÌh|/å®¶q3Uò WPñ¯A=Ëm7°»OTÉ9¼Þ¸]îX1>—u[’{)ÆÍ7.V*Ù0P�ŽŒ•J&,éjÙÒ – {ÅŽŽÖ!âDU1X|Qèîn‘_›È¢S Èx˜ËäAä,¶Èë*b&o­°‹Zîd©ï¥1¾’ŠØJ”ß3œé4EŽfÑ,² ×+6g‚rÜšùZeg,mUÕV2yu½f*^ŒÔU*à–KÛÀž\ÞïìôàHfkÖl€²’^³q¼1Ž ôõÚǯ=�À¥³3��”�P"��”�P"��”�P"��”�P"�€‚Ðø-~úEl��Ë|¢®®.Œ�V*2�¶˜íر£�@¹‰D"ÛØ¥;;�°xv�€�J�€�J�€�J�€�J�`)Þ‚sª·ÍÞ24¯:³‹ÒËèôý?Kn.Go…ªy ™ƒìõjl”HƒŒ]Ò›Çb±|-¥ØcºL»HÛµ¹ ¬øD%s3CœæîòÆ^’B¹2—È\(û¢š)M^ÈZ¿Éd =NfkqömæÕ…ÜíiÚG³Wh>ºY¹bÖTOOrjY^³=2Åg½Êv¡r;äækX%Ïg]¨Jænn2‹·$F1ð)lõœèùeL*Ëd.ó•w‡ )œY&kfì£÷ ¥§ü5š\ü³í\mήye*ïhs•u` 6”—}¢ï¢™Þ‰Æä[|¡7wDµ] g(r¾öQÌÎÔ)hRÙVS^¾IñæÎ\ÎcˆÞèè'9} 8DÅÛÇéÁ#¹$G1ϳb~¤ž1)ŠÍŽI—J+¦GæÒ¬LÎ2Ñ«ZyÊ~Ä@Úpç¶­÷Ü{zp$1[fk�¨�éu¬CáèÐ@_ÿ¡}ĉ�Àù³3��”�P"��”�P"��”�P"��”�܃ÙUA"‘HÕÚ(ÓQ�ð‰¬¤«« #�ØÅ'ªNï »»›.`;%wÌXõF”7½_ƒc%3VB‰˜»å`çΟ­* f�X©äó$”È.c‚}ü8"ôÝÝÝ9µ+™±’yˆX€õ D�`=ÌÎJ Ûºæk®Ìgƒ9Ó¸Õêõ‚ ؘÓA6D‰JߟÀ¼ÅÌìBîbq×4‚f_2HézÒH6·&+Û—µTæûRNã8ȆøDà gÓ•’Tª[Ç6ôº¾‘ÀÑ®AæYre .¯é•Þn€2ä ÊŽè‹È@öVæî›ÃÚZ‰½».ßú´{1“2gÙP¶¿• #@ïF펳!k°l®a¬†@¡ù{4HiðJ‘ƒlh눵ž}Qg(Ì\Nl÷rôMi. ¯Slȯ=��%�@‰�À±.÷í5Àš„X %r®\» ±Jä$Ü·jߎ;XŠ+9@‰ðH ä±fç/�°Ø'ŠÇãÎZ:�Üé� D�€�” ³q"÷½¿g¾²À'²¾1°‘OTÞïOØQ‰À3V½åÍFﵬdÆJ(s·ÿ`ŠŸS™™`¥’Ï“P"»Œ öñãˆÐwwwçÔ¬dÆJæ!b �Öƒ€õ0;+%®Ü§´¬æÊ|Ö´›b«WÚVÏê½Ì4SºÆ†(Qéû˜·˜É˜«Ê9·œV¤t‡ ½Žh$aû]wٲܠz0ß—rÇA6Ä'g8›U¾ób1ŠãÊvn¤Œ«vx¬fbY¸Õß4¿åzö̼ 9ȆøD�Nšµ)Å5ƒ´lÓãUí¼Œ¸[1“2gÙ÷‰�r›YœhC»ÏÎô¾ÔÌ5Œƒµ¥Šæ:ÚfR¼Rä zÒ`ÔÓ•Ï¡ñÁj°§ù7€Ìq® í>;Ã!¨l­DĪª[ÏÎÐ �”Lá¾½X“+¡DÕk÷± !VB‰œ„ûVíÛ±cKb%()�”ƒ<¾;cç/�°Ø'ŠÇãÎZ:�Üé� D�€� D�€�”åwgîûí�8O‰xi�*E£®ñÒ�T€H$²ý]™‰€õ D�€� D�€�ÁJiÙð.U6z‹a%3V”¨(x*ñÒ¨XÉŒ•�%* Þ¨2ãõ`%|ÃÒBœ�P"�€Âfgê¢Ó[$°ekvQùî³X™b£Ñ¨âšG4oARÓ€.Ø`Rq§šQ4¶ƒû¬%V"uJwÄb¤$SˆÝ0c V<„™Ïš)Ýú\©­¤iõÁœv@}P¢Â{d,SÈéÑhŽ“ WK¡\¿AÆ|Çy½bÍ™”îð†òòmÑP#—»æõ@f$CQQšBÂŒ3ÚóNãz‘Rßµy;Tƒ• XŸ(ç0XÚ¡¯˜Ò È[Ö©¢"zâ\Á òñµÌc;¸ÆJP^%RljÊw(2£ÝdÈÅ.ñ)L eQ¢òQp—-“–\˜\£tzÓg“wgœ’ñ�%ªÜd;SjwÆ|˜Yó®RÍæx°ØZ‰ŠyH!FÙ…¨˜×2“Ë!©f®›±¤ª–øJ·¬y°z¬Å*‘^·Ð|I$ßFŒ5˘ȷ†ÇÍ›ÅÑþ‘IkÐÜàbøµ� D��(�ØÖ'Rº3X ð‰,†Uø°àY kc%À'�”��%�”��%�”��%�”�Àjx³Qƒœ?e°ÉÛ}eÚñ-çª@9¯[™­è�%r?ZÓÝÝíâ]á@‰\òg;Æ{®i®{Y±ß ¶rÓ\ ¶àBŠ_Þ\q¢Ò{&÷\ÓL_±ß4Ólͪ5ó…T �Ÿ¨Ò¿ír…w|3(*¯å¥q‚�%r† ÏòŠÏXV-0SUü @‰ªB¹¬r@4ãV¤ Nd 4w7¿%¼æfó:AxC€YìÈdT §{¢™>¯B²÷\-ÉÕM^K³uÐZ]1<#`vfͬª€@uÅv|3yuõ)½‹æû�%ÊAww7F�@‰¬$»ø-j�Bœ�P"��”�P"��”�P"��”�P"��”�ìƒò뜋É�”]‰ººº0 �T„F]%â÷V�P"‘Èöveþ%N�Öƒ�J�€�J� D®ÙÈ S�å £DùÁ;S�¥eçÎøD…ÀkS�¶šg'�ëA‰�Àz ™©÷ðTïÿY@!™¢Ô;©³]�J$ô$#£)ÙûV� D¥!㿨?ä•]í7in©®pšðž�œKãDšòQ˜Ç¤u±_�œí©Ý“f^™BŠ÷eð†�ªQ‰Ôq¢Êȇ¦ûƒ T©Y¢à>ó>‘ÂJ;b´@µûD9ãD¥ò€²gÙ„sPÕJ¤'НºL&6Ξ³4ô€Ù��J�(�@I¨Òõ‰X¹�ŸÈbŠ__�ð‰Š¢ÈÕv�Ÿ�P"��”�P"��”�Ü‹ò»3^´�땈ýQ R4ê*›£@ˆD"ÛØ•ù—8�XJ�(��J�(��J�(��J�(��J�ö¡ÕcÕÛ@g6h¦·BÌk Yã’Í•WÝ*¤…Õ3ûm~¿yÝ‹ú Óï®Üö©.Ÿ(ö.Ù&ÈK†Ù‹l’⋲wÜE% Uíå…œc—f72Ÿ]oÈ|0ð’4‡h4š¹\ö¥5S–{ØI_%]%Í{ѬL&Y&£ ÆÉì{ɶC]Å­ž‘¦}Œ»={…\3éðéçMa‘ì'J! eõ’ÒµÍdÑÌžóŽÊç„笌ZŽ-©°µ$¾¤s' r1w«)%æƒz–RøÞöQn[!f*ã!Ý7ŒŸ%FÆOÂ3²§ÿXÊ8‘ûžvûô¶êíí9 9Â>ÙŽ‚: é¥9ÕáªvØóöÑ ý`¢³}¢Š ò)ÕÁÚ’k“I¾±Ñ êï¦G7m¢âícóàQãD9Íg&Ì”S¼ÕEn²XkZáEkÞ‹ú #;ßT^žô¾µ'Ò†;·m½çÞÓƒ#‰ÑغÈ0ëX;ÅGnÀѤױ…£C}ý‡öñk�pòì � TðÝ™S£��øD��(� D��(� D��(�¸³ßâG"‘ªµQ<§£�àYIWWF�°‹OTÞAww7]ÀvJyáÜÕ9ô^ã®æIºù+ྠDåå;ßùŽãê|ß}÷1]ÍÉÎ;±R‘VB‰*гZ‰D"ÆJä¸;*“•\ÖîVY)kÑÕÕÅX Õ Jd/öìÙƒ  ±~væ¦=”ÍÜ©ÐÙ!Rqÿý÷;ñvônJs»rÌœ²I/²§• LW½J¤ÙN®”¡ì^¨¹ß‹ã¦fƽˆrej>üXɼéªW‰Ûž˜ßZn9툇 0NÎ”ŠžSåærPôZnSƒMu4·(Ph–"³œ#{úÉÅÌ7‹™›ç•Rspr«•Lö¥âÌì¬ZPt…$9+N¤¨|fã-µ?¢ç¤¨ç æSæœw¸ÃJþyrÄöS^§?ØÎ•!×Ï4§Ï9çÔϾeÞ¬¤ØwÓäÍ:Å&^wtz‡Ê£µÉ†•/ìYuœ•\9¤ÉöìFùfdët;7be¶eaóQʼ•ª§c[ï¥gÂù~å‘Éå çHír+®Îú_3flíÁ*±’™¾ä8ÓymÒZzL~vîDÒÑn¶q Ç’ƒ6´jÉo3¯¾”¯é˜@õ‚�JYìܹ󩧞ÂP…ðfcÙqß ~¬Iˆ•ð‰Æ}÷Ý'9œŽÍjƽÅøDvÁ}¯Ÿ±áV²…±×�X<;caS�°Ø'ŠÇã¬�ÖûD��(� D��(� D��eDùݯ¨€õJÄKC�P)u•ˆ—†� D"‘íìÊüKœ�¬%�”��%�;P‰õ‰÷f€SÖ—á• '¶šã®2†Å'RÂ{ ´TÞ°•[³ÑC–—‚c…@‡.àgÿ†«¤añ‰�ÀzP"�@‰��P"�@‰��„°ç~gÑhT´YXÁ«„´}ÒÄb±’›+»ül×¢™ìÖp(‘‘Ñ£Ñ(µLúFõT£xh5‡6J¤Ý•³%É`\Õ„PXX=êê46»/U=Ò.gÃé´² í®ù¯fÇÕ<w÷lcj4ž…åå1)D§´W¡áÌ·&>Q |~=iO§ib\-Ç$Ëàl¦—osZ­‘Êè³³ÒxF`•Ù "Ð¥•Í !CE7 ¦Æ(QÞ1…‚m—q‹èÓ…9 ꨜUþÜÿÅ•ßüØÙÎŽyŸHóaÀ{ÊwœÌ)ñ•üvF¤A·x¹���éIDAT n8µõtÇžv–Ô$jû‡iM:íš§²–Ö3Ê”–@Å{-GÃdvfÖEW<�9å=ÊËÂy™ÎŒõZ0ßKÓd%l8§XÕÍ¿öÀÕp ®U"¼}�á€÷‰ s5Ñ �|"��”�P"�€¼¨\œÈ¡0Ø KÃá™…í¨0,ÐpûDñx|ÇŽØÃ g±O�€�J�€€ÍQF¬#‘F�Ë”(Žî‹íìÂ(�PBᨶO”}� Ò>ÑÐ@¶��«R©ÔÆ-ŸÄ�`=Ï=þÿ¼U]¾ˆé����IEND®B`‚��������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/binmenu.png���������������������������������������������������������������0000644�0001750�0001750�00000013420�11332353404�016413� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR���²��5���ýÂ7v���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚi ,Ž��IDATxÚímŒWyÇÏ\ßØÎÆöÞkˆ AlZȦ€‘Ý´‰&Z5ΤªT˜ %(i$!ø€x‰Ó¤ j%´BBPP𮑌xRZ%^­¢¶dI¬UkBã @îbÇÆkïîí‡IÆ'çœ9sæÌÛ™;¿¿¬dîÜ9sîÞó›ç<wîÿ>'ÇBˆ½×¿K $ÄÒƒ‡…ý˜‰ß} ïŠaXzðp´çmyã»oùå³'yG⩟ÿ¿£÷ã«gË;‚E%:õ›_¯žÎ€·\²cûôÎfÛ°8·z–±,K«gϬž>9{ÕUîMŽ;&„زuª©¶ÊþÞóÿ"þ•õoõÌ©ÙÙÙ\MfggWÏœj°í…r´ˆ^xŒŠ+Š"÷3’T[ó$E½úß¾CwÞÔëEøÇ¯üúäéÉ¢ç5<½þ5Ð6 ‹ª¢Å§?ôÃSBˆñXüvõÜãOþêð·–~ñÌŠâø‰gÖÏŸ}êgm\¾©ßŸ$.„Çe_µ/n{ÏmûÒÿÈgîsiû¢ÃŒ;MÑ¢úÜB!Ä‘cÇøÁO=wúõ¯~Åûn¸fmmUDÑ]÷>pûÝŸ;½º>ãIÊ-¼¥·µPôøòº´½ç¶}Éž2½mZna ûÐý™ˆï?pÈåJøÖ¿.ýÛ#?¾îMOpnߥã§Ÿºô•W.~b¯Ýö_þÍ©³‹w¼§×‹?ø£kÿà÷vnŸzä'OþÓ7Z[ß`yçû?¢üõÏß#ÇxcÛ~ö_þîÖ?BüýßÜl''TÚæ›DÞsç—,ÉΕG£Á³þ\!„xû[öîyÃÕ»_;#„x௯ŸolÄO={âxúòxûº=W>ôècrÍÕ×̾jéÈÑ¥ãÏŠæÂQyäjÒÕ«¶}Íß”F’½íÇ>wÿÝ·ü™BaB>¡OʹsåÑLƇ£†{ì‡í¾êÊxcmm}åä©©íÓò³kkkñÆüÂ7þ¯Ç£ñøÆk¯¹âeÃï?ò?Û‡»Z.z¢y´Š¢ž¹mÚÙ’ýém?öùî~ÿŸ¾ˆ‰=o6ôkÄÂxQÎÝuXìÜ›ùçŒ޹ç³_þÞ¿?úº×üΧ>zë­uÃòOufc“~Ø'žž~ÉË66mBlî÷Ï­žÙoôz›:òU¤¤ig“&‚Ô¶wÝüyêùø¾iìלr^˜›Êþ÷ü,"ÄôK_>ZŸÚØGQ4½Yl¬ÓÿÎõõõþE[z›ž‡u<‹ñ¸º×VÕ¿(òl¦µÕR‡´ýæ~&’å®›ßaî÷ÂxÕxßâíoÙ»ç g~wæŠ^/:~í§Oþ"šÚ™K#95iäžJ‰)çý¶´#ï¸÷Û.÷¢…¡mÒoÌÄ÷~;Þó·ï»^ï·îûrnqîüÚO~vâà×¾9:ùܮ闻‡äÞ·pzÍGøýÙ?|«vï!Ò?t¤vdm›0÷rÇ¿sç{¯3÷[ó]ÎæþŸ[ÚØXO^Cÿ¢-Ã]Wlê_tó'¿þÄч…_zÉe7òkO]Š·ÿù¡c_üêýÏž¹xû ©;°…£Å…×|àà÷þû?¾k9XŸ)Êm{õ]«ïTÚæH9ËÒô®WlÞz±Ô÷8ŠzmŠz½Áe—oÚ¿�y{Ûp×Ö©ýÍ[ܯ¼SÎßÿãë¼SÎÒÛ*;)g“Èp×å©w>.{¥q{jÛ´Ø6Ýæ›ß‘Mµ­yé ¦¶ŽûñììkÝ›=úØÔöAõšjÛLÊÙ)m¹ø’øworñ¶é¸USmÈ-ºHÆÔ¶-SÛÚÕ65Zœ99bD»;÷íjÑBˆ3'G._™¢IÕþ‡2È4‘BÌÏÏ›r I+++¼MÒ‚²‡h  ¨\,ôu‹G2†Ãáp8äÍd,2ÉH€€ŒöªïÈÄÜÜ\òpaa!~˜¦Ñh¤óïTÊèÈ{F£‘²!c<Ìx6T~´P˜7Òb†!ì#Q}Pu¤äcŒÄXΆJÃBg‘ {ðP"‡½U"û™QM“È`0¸ýöÛEÊϹ¹¹Á`oÈu¥–Ç»øÙP9X¬¬¬Ä? ôOcBñG’øŠO>ž(—¸ýŠOKˆÍL"É'Ø™((¿Ï´iMø„\aÊ©“Q„‰ø:–¯æ$Xù˜d[Ùp?*çª<›è¸dðÌù"ïždÛª6Z!ákwæˆæ±QÄŠÁ|Ñð$T`¾+Z °@,X °@`À…‚_°00¡lX4|±x‹'‹\_Ù9‡ynb±H ˜Y\žY\vÆ¢l'ÿ•÷cBÇBfBÙH#Cÿ+Ó|%ÇbLèXèL¸“¡ÀZ§ ‹ï}»oÒŸY\Þwä`¼m±ä$óßvNH´H;~Y&ä 8‰¤‘‘'2sOÞôv§œ:.s‡òBvö2¡´;·ÉˆÍ½r̰lj´×ݹFï.³O î[ˆ -¾¨y,Dx_Ôð$B Z ,X °@`À ¸ w91þwD–š»,b_ê‚Ò¾Ó`õ!DnÀ ,X °@`ÀMœúåžNÿ‰©²^aÞS¹¯M„BI"ZŠ(ʺ¦ÊN÷¨`\µ&·°¯kj 0î#-¯WÅÐ-Ь^¬Ÿëê'H[ @…-°x~ÖP €Œ ÁB/’¤±±„RZ&íN93+$ ç%L]ÖÜά·„&3·@`À ,X °@,X Üj·ÅWï4óx\}E‹:m8và "Zä(-¾ÊþØâ;:å§°`¤Ðr‹J-¾.aÌq®!ZÔòŽ©�¹âjþà[]Ç"—ÅWyÊ8ã¤!jucQ§Å7­mÚÊ«¬ÈÚ@ÊY³Å×±S÷S¡vä,X °@`À  ¨ ±jwÅ:¨È,ÖAEä,X °@`À ,PgÔ­uPÓ~wšù"Óþ.°È!¹ÆM€¿öô~=Ýù•b‹‹$é<Ê­x×OÒW^Õ{—Ë5)Ç8þá]É-J,’¤ÿ8]¨­æW?I¯¡ ×VwæúÃ'-Z^$I¿d‹4œÈ™…Ü¢PCy÷µ`–~àØÊ5C~z½ÇVg²²j¹\#—¯þ‡OµI2¦rÞéH‘úIrïî1£øknÇ$R‘¤\Ù_)½¸ìq6ÌÉ‘›ß,X °@`À ,X °@]E’º+Š$!³(’„È-X °@`À ,P·±XXXà»°P™P6Ò4Ô$ïÏõÊ›õÓÍa¡ à3F/HTù3_€h ‹‚™Åå™Åew2#Š}§€„<T+2ʆ7%IB `¡3áN†¥ãÍÊ\È`0Äfœûvߤ?;³¸¼ïÈÁxÛhμHòŒÉ`'Ã/ËÎD¹ ­]×'‘42ªf¯Hª/åÔÉpd¢¶"I¨ÖÜB&c0(1ÃÂD³E’PM÷-t0�ƒ…ŠL0‰‚Ñ!°@`À ¨ X`ñí”úŽL$–*¢¡uPåŽPMÑ"d‹¯rYÀÉÇ"`nn.‰X|;…Ì„²”Å¿g}XèL¸“Q§Å&êK9‹¯ñ‹Ó¹¹¹Ø›#š¶øÂD­Ñ"ìdøh,L”+K:  L"idTÍßÐï[$FÎÁ`CàÈ„åvB² ²ü¬q§±•þ·.êÆB!C$–¬Â²¿,‹/4vßB`ñ‹L2`‚ID$ˆ ,X °@mÀ‹/X˜P6ÒT_ïó£BXkñ•™` kÅ"d‹oò_¥ÖŠE[,¾¨>,Zañ%TT¤[|a¢îhÑ ‹¯–È=ë˜D·øŽ$)Q U˜rêd¸[|©â;¹…LF°_÷gQÉ÷-_°È$&˜DA‚hX °@`À Ô,°øvJTñE^Ñ‚*¾`‘ÊD°_T7[|3]¨|,·ø2‰Ôr¶¥Š/ª5Z´Åâ‹êžD¨â ®deñ%å¬;·ÉÙâ ÍÜ·X|Á"“ ˜` ¢B`À ,P°ÀâÛ)µÛâk< ßoÑ"d‹¯~r,[u`²ÅW±÷¥ÑÉ—ŒU|Á"› w2j«âëòPi)gÛ-¾²q‹0SZ´Àâ "X|»žr¶±Š/¾ß s ™ŒÀ«øf6Dåß·X|Á"“ ˜` ¢B`À ,P°ÀâÛ)M`_,¾uD‹vUñÅâ[G´P¬{ñÃ̘á2œ¹.qËwôÆà„*Œ­°ø¦Y+ð[T‚E[,¾F˜`¢’I¤Õ_˜¨*Z´×â ÕN"á[|ù%H3ŸDd#g »Å7í£Áh4’‡3±øê;­OhZ+n]TûµuU| ò¨Fpï…ŠL0‰‚Ñ!°@`À ¨ X`ñí”&Ðâ›ë È3Z´Ëâk•†EÈU|uåã UaA_°ÈfÂŒ:-¾ÆÀC•¤œ-²ø*{a¢ÂhÑê*¾Jü ÷,siiß‘¤´®¨PÊx_ öÖ[Èd´Ëâëþ,ò¿o!°ø‚E&0Á$"D „À ,X 6`Å·Sj·Å×x¥}ëˆ![|µ¥}«Æ"d‹¯bï³ìDebÑj‹o.?rÅ¢-_—„ƒI¤œ”“*¾D ƒ¨â "[|Qå÷-¯âëþ2Ïr`!‚·øz† Ý·X|Á"“ ˜` ¢B`À ,P°ÀâÛ)M`ßÌ/`ù~¤„hÑÒ*¾úkÀUZ´P¬{ñÃ̘á2œ–Kܱz·ñ¢ÏŒ1„Š¢Ñ¢-_ãOEXj»,ZTÅW>@)ÀhüÍ£î9‰´Å⛋<¥Þ/cŸ;Z´Ââkd‚xPí$‚Å—I$•Œð-¾.n^,¾%@ Ùâ›ËÍ ¥}@5B€{,T`‚ID$ˆ ,X °@`À…/Ã]NŒÿ‘ÅkÀ"öe¡.(í;¾û¡ˆÜB`À*I†O"Æß† ¢êæçç¢E,î^tAiw´‰¨�IêzÊi 5.OªX˜”ÅNƒ‹îE’ªX˜”ÅNCÄ"×:¨&• «¦°ØiXX”[$©Š…IYì´n,ŠIÊLŒ?︲Øi)g‘"I™ cšâB~I(ª/·(^$)׸ɹL„ˆEýE’˜Úqß»H’% ˆò&e±Óf°ù‹$‰ “Z )±ØiX¹… HXd’L"‚ A´@È!Zð5:ÑB•ÑÈ…:-VVVЬ"ƒZ'}f ·@¤œ,PåX`ñåjjJ’kÔ²&e±Ó£E.‹¯({aR; ‹â_—…I»žÈ²øºŸ•…·Å·Š…IYì4,¼-¾Þ “Z,¾,vDÊé½jÁ…I_; %Zø­ƒZ|aRÝâËb§aM"X|™DRÉð°øV±0)‹†u;+—Å·à¤F‹/‹z; ‹/XdL"‚ A´@,X °@`ÀjX|;¥ -¾ÂTÏx¤»Å·¬s¢¢ÑÂÝâ+‰Ñ¡©Œ_®ïЫ8'òÄ"—Å×h™q/Ãk´ø<'* ?‹o.7¥{ÎÒω|°ð°øZœ·.ãg´ø<'*3åô¶øº+mv(2®0Qm´ð¶øŒóF‹/sG@“_&‘T2rY| wÓ>—–~NT ‘¿Š¯£#7Ó k©è›ëœ¨’û‹/Xd’L"‚ A´@,X °@`ÀjX|;¥’-¾ÂÙykÿNËå[òÚ:"Zؘ0>TÞbGç­ý;t V=E3‹Ë3‹Ëv2ÜM¶–#•‰î¥}óZ|©Ð艅̄²QVžQE g^¨ ‰ÒÉ0&F…±´o&>)gbñ½o÷Mú³3‹ËûŽŒ·K´ø¦ •»ï&ªÉ`'Ã/« &äìA1úê¾ßâs‡±#”=‰¤‘Qœ {*gŽrœ(Ñ÷kì\SN &ìuÿK/诜3oj‚œng%_9fØ™°—çu¼:×±ÝÓ›«Þ¯û+!ZdÄŒŠæÔJ,_&ǘˆ, ,X °@Á`Å·Sª°Š¯‡ÉÖ¯´o¥-2˜0>4¾ï~&[÷ïÐkë,2˜p©â[…ÉÖÝâ[°#䊅__ák²õðFÔÖX¤2áH†·¡ÒÛí.ž;BÙ)§wß*L¶F‹/nÞ°Ð+r*ÐaBÏ]LyŒ+êeO"•Vñu7Ù ø¸yË¿o‘·Š¯ñæ{Þ‚{«ë,ldèĘá»ïןµ›3¯ø"¡|·³°ø‚E0Á$"D „À ,X 6`Å·S*¿Šo¬L?­‡G·ÙŽˆf&Œ-C¥ [¦×ã;ôÚ: 3.ßdxŠ_ò˜¥-¬]nGÈ o‹/šX,ü,¾ŽW° ä3èÝâ[zG(;åô³øæ5îêù2ñ¶nñ­¨#”…ŸÅWTã§Õ-¾ãnS“ˆ‡Å7—q×q Ó~<RzGÈ5åÔÉð°}“÷¹>SÔÓ·³òY|3zÚûî¸3×yŠt„òÝÎÂâ dÀ“ˆ H- ,X °@`Ú€ßN©Ž*¾"edýÈ‚U|«èˆh‘Á„ñ¡>TºŸÖ茜·µuL¸[|¹{hGZ,¾åv„\±Èkñ-ËÇÙ¼¶ŽÀ"›‰L2܃³Ýy+´êiúâØ¥w„²SNï*¾¹&=û3•±Šo¡Œh‘fäTv–ûm{ÚPɹE¥¡ìI¤Ò*¾-¾Ut„\ï[ä­â[J]—; µuÙdèÄ2‘gîwÙ#Ò¼¥w„òÝÎÂâ dÀ“ˆ H- ,X °@`À _†»œÿ;"‹‰ß€EìËB]PÚw}÷C¹ „À ,X °@`Ú¡~¹§Óð©”È{ª"¿�K{15«¿„îWqR¹v@¼’”Ç›RÖû¨¿‚A3XX®}Ãølf“´Vy£ˆ½/åy¿²m?³Zóë½¹…ñ=2îL{ÖøæÔøìÇÈ‘OÙé˪ ðè½õÑ"v…¢ìE м˜Æ“cððž|Û”[4þ^ÛSQýHïk4ïÒðzï!¬°×“ž¾øS$Þ8#‡ î[”u6òªÒjûٱĉ´¥U‚êU÷¦Tå¼Ï¯¡%Ãu9Æ~f㤠g‘–7g'‘ÌÚEÆBGöyë$¹¿ïcŠ”nª­^T'Jè‘[äˆØ¨ëŸD@hÀjGnÁO“‘-æççySÐ…h1µc¸ÿÀ!!vò¦tSS;†æID~-Ä3'þ—÷%ŠÆãñÞëßÅ-=xøÿž$2ê®Ì„����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/detimage.png��������������������������������������������������������������0000644�0001750�0001750�00000410274�11332353404�016545� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ8="Õ�� �IDATxÚì½y”dWy'ø½È5²¶ÌZ£JEII¤D¤¤ Ìj°)aÙAÃñ¸åÁmá²Ýrc÷q·QÓž »'’ /AÏC1žilhz°i[ÇxVцÃöR@ª�!H¥’*T¥ª¬EU/k½óÇ»ï®ß½ïEdDdDÖ÷;uêDF¼åÞï.ßýö€1�Óoú5 ¡'1ÿ…À`Ì®Þzï;ˆ"@èML¿é׿¿ðñàλÞöÖ{ßñìñÓD@ ô&ž~òñCÂÁøóËQ„@ ½ âXpµàÌ©çÏ6¡QY·qæͫ{/±.œ_V¿=òƒ¯½`S°iÓ¦K—.ýôôðæ=/Azn©1vú±'—.^ûòŸ£©@ ½ŒóËçΟ=}ËK_šý–?ø�ŒŒŽ­Ö½8Ç‚ P¿Ývãôò‘ïì{ë[>õéÏ<ull|»qçÅóѵcgŸ^‚7M·¡ç8Ö¹3·ÜrKS·ÜrË-~ðƒ‘üºÕºçXÎr†FFÏßø7ÿ»W¿ò/¹ù¦Ÿ>ø•Ëë6 ª×äŽÿèòú¡³c{6¯ßDS@ zAÍK‚îßëâX9ã‡u;žyâ¹0œß¶më×]ósÇ­o�à÷Ÿ:ôý—6~ëñ»_z̓¿z×o~íËüÖ?RÿQƒ@ ôÇʵÄ9rÉ¿U¸7“ŒcÛõ·>öý¯œ>}0—Ëm8ìàw·ßp;�œ9vè…ðŃ{îø…ÔvìÚºé×ñ7îÙ>48pòLôÔ³'þ˧¾¾tú\ò^xï;ÿùÖñõ�ð¿üåÿû̱“âÆÛoÞóK¯¾uÏÎ͹\ãøé¯|ûÑ¿õCÆ��þÏwýêÄÆ±¿úÄC_ûÞÁš �À¹Ó'NolÚº½æÚÂæ·ýBñÆl»ÂØ#?óÑÏ~S‚@ :ͲÀâ…ãÞÚ¿~‹ëòòÿýÉ,÷j—¡_zd,—!jç­¯y*üÔ(œ€+WN-m›Ø±éüá:¶kò® 7ÚÓwÝ{×¶‰õcK‡Ç&6­¿íÆÝ,:yùJn``�^|페]Àm×n:täÙÁ¡Q�¸ëg^rïݯ�€ƒ‡ŽDËç_zÞ{ñgvmY?÷Ùy!ç-}::{*¿~¼wXV À°CÀú±‘òoÞ½.?üù¯~;�ö¦×Þ¹}|ìÿúS�´”BçV‹Ú9hF³÷Ø÷¾yÓË_™zoí_¿åþÓ§âÏþ{ÿÌu¯KÆÂïÀàÈŽÉ7[¨ @.?øíܶí/Gc×Nç×§6}˦uÛ&ÖŸ¿pñ7Þõä‡F6®9{öìØækG�àÕ·Ý��?ñô ×]óó¯šzàÁomزk}~äWßx�|ô¿ø‘üâàðè+§^òîßÿ?ÿŠ[?û•ùc‘l*»råc³û�`®þÍ7¿vrtxè“}ÿ§ÏÿíöÊ-›Ö}ëÀÿù“_¿r…À¿ýÕ×ßð‚íÆF.\º|ðð±¿ùüüÓGOÀ{¶ÿö›_¹mbý÷æôóÑî¼éKá£ýì·�`ûĆ·½éΗ\·chpà±§ŽýÍçÂÃGO|ñµÛëͯÜ:ÎoWåÙ_{Óô«^vý†±Ñèüŧü˾rÓžëòÃO9öüõͯß4uË{vm{ÑÖуÇ/@®+¡Ó«š½_ù²}ñ?|°Êy½÷?ðé?ûÝ7ÇŒJ|4îuq,g7Æ6n^wÝôùCá¹ó—ÙÀèXî±\a÷Ž=Yºúü¹óË.Žýé¿û­ÇŽœzìÐÑGŸhŒN �CƒÓ·\ �øø§gÿà7vl¸áš-ÏFìæk ÃCƒŒ±øüCë'¶­ßöãFtäØÉÛÆ'_´ësóííý­¯»õ'O½ý%׿í®;ž?wþÇO6&6ä_sÛ‹¾ùíG‚ Ø:±þ¡ùï;qòå7_û-7þþ¯¼æ]û?±qã†w¾í ëó#ßô§gOŸyýô$�œ=õÜÉçžÙy͵ô›oÚ¼q졇?±ô–7¾êïýù?|ÿ'Î_–ïÎ ýÁÿü†uù‘G~üÄòÙç_‡t†™¼a×ݯzé“ÏûÄçZ76òò—ÞpöÄ‘ó;Æ`Ëø†Ý»vlÝuý¦ ë�à†ìx䉬Û0A<‹@ t^ÆÊµtW€Þ{óí¯q19ÿ½ÿá¯>ó§ïø%�0Ø•úÀæ</T\9wâ ƒólø…ÛÖ]ÎÚí‹—Ù_ýÃWýî;¦_öâé—�<{üÔþ¿ûGž; Aðòï^7:|òôóßûáÁïüðÉ×ÝqóÏýÌmsŸ™ß06 �Ëç/œ=w~Ƕër¹Á¡“g—wnƒM×-Ÿ;c¿è½þ‡o|÷GÿÏ|×îÂÖÏ}å[úûϾë¾_}ÓkoÁöß|ä‰õ›¶þɇ¿ðÔÁGÖ¯ßðOó?úÈŸ¿h×öͰ|ü¶;n^ŸynéÔ¿û³ ®_·îö[^‹n/¿i÷æcO~vÿ‡ίßsÍÎ;nyÑäžMó/å‡â—Þvãîuù‘ã'O¿óOÿÓÀÐHí]¿9õ’Æ? À™çÏ>}ôij'Ï}üsß8»{ò±C÷>ò¿ÿ{�ˆmrùÑ‘‹çÏÁ†‰f@ 4Ã|r Z¸+rø½®§‰ïÝ÷þ‡~öOç5vuçk‘÷¢ËPuúÈã—Nüäb~ûÆás.\8þ<\xîÌs×lØö‚,ýîãG¾\ùë›Fn¹qÏÿô ¯ÛµcËÝÓ×ðÓáàpþU“×À7¾óƒ 7ðí?ýº;nþÙâmúÄ—ÏDç`tdxݺ|0Ë @LlX�§Îœ½rù20ó-=³iëÎåK �{âp~Ãø¥Ü� ^8 ¿ñKÅÛ_üËëò#â–á`Ýè �>r ‚Í;¯}ö”TëmÞ4�×íÞñ˜_¶ŽŸùöã·b%Þ¦ c�ðÔ3G!—Û²ëº#'ÎM%W~ÿàáoÿà§·¿äº[oº�Žž8ý?òÙÆRôgs_xial×ö‰#G¿êŽ[^}Ç­'OŸaW®\6@1m¡ã2V;íX®§)š=ç½rßݪ.ñûÐçÐ÷:d,«\>³tæà7Ï]|á{£ÓÇO,>˜ƒË�pòчF6¼edlƒ¿«Cƒ·¾pçwàòÒÙç¿zà™-Û~ôk¿øêõëF—Ž>}í/¹íÆk�àî×ï~}1¾~ÝØèÔM×üè§Ï\¸xixhð—÷¾úÁ…§r#¹—ݰ«°e�<üýG?…Ë—/ŽŒÄD¹tùòÐÈh.ñ aìÊ«_výk_þ¢gŽž¨}àãgÏEñGïÈårAœ8õ<�\SØ6<: AnOa«xàÒé�=óì_~ô¿‰/Oœ<sùÒEÆ®äàôÙe�ضy|ph$€ÜŽ-2.íâ¥+ïý»/_8õì®­›îùÅŸ}õ·_¼óÓßøÉÀÀÈÃ={éÀ“ëdžïÞ·Àw< Aà@Xe­`× ºž¦i±{«ÿòMBºŠM_rßÝ•ÿüû½Mh¯\ºxö'߀ Øõò»†FƆ¶]¾éµÑO¾622<44ôüÁoŽLîõ÷xhðßüóמ]~Åá£'ƒwo€ïýð »ryúÅ/È‹–~À=Ô¯»fÇ5…­o|õíïýÛ/=ð¥oÿúݯØ÷+ozí+ž½ ¹vo€/~õá<´e×õ¸É'È)þ sŽyùòåá¡á×ïÎåx›¿ûè¡3g—·mÞôø[Ñ%xÉõ;Ä-ßyô©§žß³kÇ/½á•O~bãºÛnÚó¡O|ùù'žÆøÈOg£ó×¶þþ¿ø¥ ÁÈÔM»Åí·¾h×[^û²þäp´|a÷Î�pêôó§—žýóû÷<sîltþΗìY—ùêüâÚ²ëú\K3‰@ šá=šÄìoßåºræÃ_ÔïÂcª2ÈXȽ⽱2pæÃ_Œ¿©þË7Ùïuq,äÅÑáïnÝ0|tãÔÆ$ºhó n:vîÄž ‡††cO=ù½M×ßî!Ð…‹W>óõ7ìܸg玑á¡ã'OÿÓ×þîÓ_ݸåU/»�>ýOßüÐß.N5yÓµïy×¾âm7~ì3_zøñ§ž:üæ×ßqõ»r‡ž9úÙ¯|ë?ÿÕüúMC#ypy)èGøú÷~òâÝÓ·¼ðßî{ëg¾ú½åóGG†� :á}ÿï¿Yš~Ñž?ò؃_ûî›^3uùÊ�X¾péÏæ¾ð˯yñ“7¾nttéÌÙ|êñdž6 ÅäŠÎ_zßýï¿q÷ô]¯¹ãÀÁ§¾öÝG_{ûÍñOž‰rìý™[ÆF‡Ïœ[þÜCÿ·/þÃë'Ž.ž¾ùëò£ÇOžùø§¿ü‘O|~tlãÐH>70V@ t˜eęwà[_¾åg~NÍì{cÙÈù"b]Åo™ù/ÎþÖ^ü½ÆƒãúX?=|Ôøáܳ_;zê{‡ÎìºõgÕ—±+W.ï¸yÏåË—O>ýè©uë¶_çéù•+—Ÿ}òÑË/^ºtž]a¹üúñõ›· >{èÑ ËçÖmÚ²aóö¸òùèìÉgŸ Øñ—�ÏŸzîüÙÓÏŸgÀ‡ó'ÖmÜ<08<<2ú保\¹<¾m׆-;ŸúÑ·`Û nZ·qüð¿wéâùñí»7n)ú'gOŸÛ¸ysaÏåKyâÂò¹\n`lãÄÙ“Ç»²u÷‹¶lÙþÌáŸF§O\ºtñ½ü{·Ý|ýþöÓŸýÚâæÂžÁ¡á“GGgÏ\\>wåÊ•ÁÁ‘ÑM[wå×mˆµ‚±Êñø‘'£3K—.] ‚`ùÜóñ/]X~îÈ—/^`W®är#cë7nÝ5<’?öôÁóÑóìò•ÁÑuã&¶ äi5„ŽâÔs[nÑÒš?ò/¹.¾õ•oäÜëÀ7m-tâ^qúe|¯øuéèaYË`€Î¿vììØñÒ×CN“Ë‚+Ûn=wáäÍ7\æÌöÓC?9{jÄÆ›Ë Žoß}åÊ¥�‚ ˆeŸÁ¡‘ÁáÑ[wær¹ÁÁ¡‘¡‘Q�Ëå†GÇ�ØèØÆÁ¡ócƒ —ÈÅRÓððèÀð�lÚ¾{x49‚ñí»G×mŒ{±iû5ƒCÁÀ��lØ\ÈoœFÇ6Œo½ˆ™Í躃CÃ�Á¯ß}g�w<ñTã†k ·Ý|Ýóç¢úúw‡Æ�‚ 7°iÛ5ÃùS,€\06?\ʼãÛ®[?80ärŒ± —/ Àp~ýĶkr¹Á iüÀàÐàðð¦-;¯\¹<00?dhxxp˜Ø@肈eJ-“¯Ú›å.Ô{¢í÷_ú#ˆµžîУç–F÷Ü984b?wtÝÆGŽŸ;üÜ#ËËË/^8sñÜè†;ÜM†± 8?Û¸y‡ñÍÐÈèø¶]âÏáѱa+Û|Œ‰í׈ϛ 28lÓÉ“‡†Õ[ÖOlµŸóÌs§ßðòë^ñÒk£óæyü¯ÿö“'Ϝݺ{gËA008´~|«H†FF7Œ¢?m°:�ë°¢/Ð;ZA›Ñ­Ú½Æw±VðÉ#'®ÚA<zèѳ§O^¹|)—Ë Žä7nÞ>4’]?ž#Ã@XC¸°|.zþ”¡ óãÀæ×o[­{Å7Ç<!µ‚W³Ùã–£ë6åc¿”ÜÀàh~}.Gž{aM!.7uàÀ³ß’_¿)¾kµî5A¼æ‘ß0žß0N³™@ ¬}¦5¶~dl}Ý‹p¬XÆ:wz‰F”@ ½ƒ±–ŒpîôÒGßýv¢@ zo÷GÓ"k @ zû÷ïWÿ´¯8yò$‘‰@ «‹¹¹9㒱РŽE âX@ Ç"q,@ ˆc@‹@ ı@X} 6{ÃÄÄúýÒÒRüÓÒRÛ’Úï2.Þ¨¾z%ͰïUÛÐÆ®­¼ï« WóÚ;Ðɶêt0ZÕl{Ú¾L²OÔ½º“¶Ó-4^áÙ7Pz®pèÛÕÙÖnìmQ¢utú ¶v[7w,ïêt{Vk—ì).åiÞÄÄÄÄÄÄÒÒR{ŒPz]ÙïV­z“VBœ™ð(=Û;ôb2wm°z|3é,ÇJåœM\’˜U-σø â^ ç,Ú%íyzmwV}£ú½ñ¹›Cƒ’®½GãÔ~e¡F§¥?µÛ2…[~uÛ‡,#q\³¥Ë-L¥g‡Xˆºe¡½óŒ£GÄɲMu´ƒYšÝÂ8æ::ä6uÚ¾'ºÎžÍèZ³G3´%ª¬c|î~û Þß^MN–~ù©±’]}cSÔîÎ2iöÕ˜~â oô·p%óì þMÃ5ô+ÜÍý½km’¬âÄËþŠÖÆqp…éâÕ®¹¾*j[EЖc JçÞ‘îSOjmijl+dZ]>6õ¸ú¨Ùó{³ ¹]“Êe®^Éзø©LÔ¥´4Žh. ´q…vgšuÐŽÕ.vÒåejÛ:ÔµúÞÂ2ëÂÐôˆ9gU承㩤î‘SW—›ëàÜk=íôзk¶@7?gm;ßuy¦tbÄ{yê÷ˆôЛ]si¥×ØÐôš€¥¶'U8È2Fk•ÍÛŠ‡ž’’Qsu‡¾©)-˜G SHôåLÎÚ.¾Ûå}&×…Þ¡³UçN¯טÚ5ÃRÒkûl—‡f­²«Îv%ca›îzyXíæõ¦”Ù/ôôÙ¥"êæÊr°5ªvhÈíݼ-œIðà ̸ëÙ®µ«%F«Vkhº#ï¢]èڸؤö4À?Fml3ú(Ïû<ýÄAòê.´,s¬;­Ê²Ìmú©×ÚfyEk'ûàλÞöÖ{ßñÔÑSçN/}ôÝoªAL H˜î7®IU\ƒø;'7mœ8vøà¡!ei"«³m­_Œ^`�W ˆc„U@<ÅI<]{¤!'«È´W WÒf’±Ð ŽE âX@ Ç"q,@ ˆc@‹@ kH<Vœƒ@ „ž–±öïßOD!B¯s,bW@èY˜ZÁ}ûöQÐ û»?ŠËX@ ôŒEh#ȇ…@èeJ‰8AÃüÁ„ÞU¯%ŽE UA ô:æææè4Ù ;@ HÆ"„~“½ˆ=ÔʘαâªÌ6–––¨ÜuÛ‘…¤bDĈ?í!ó‰¾ÑqQÝÜ~šúÓJÚÐ^¢eyK–>6E|Ϣߠ×{hëYzþ.Ъ\ H[Ø#@í)Ye,Z�ÝA*mV!>OLL;f–/›jI|£§=Ͷ¡£,ßõ–•Ÿ´Ô{›}އ‰?¡ç“ŽoOVBA@DXÅ=Ðce\ᦀZ‰½ùõiÀ/»ˆošÝîыѣzç俦žé§ *ˆˆ-;ã“ >jÓ¶µ)?Êx­¡-hç…X–è&H@éã'ú«ØøZÛã4£$'.¶·ã6ŠA+ŸN.š¸ÞâºÞø¾ûSº)ÚªB¤ÚNamc°©]†N‹/üš¢vÑ<‹FÎP=µ]wײ̡Ê.ÙyÞÊ[›JÿfE±vi#l¦E @«Å¥HX!qzv?Z‰˜ÕT_ºó–•Óã<lÉÿ¨æ‰Ù‰iˆcµS’¸ÊÙU ú¥îïGcÍ>ÙÅ üÏioûWBÿŽàÔn’·áêA®k‰ÖÏʉÖ^骽ƒÒÍ£IS-÷\ÙìsVHÿ–-Žtì#:.c©‡_Zu~úöѲ½&û—mÊf_—ÅŠã¹=þÉE+U$jØn~Yè°*v,ƒD´èı|Êt+!jf$£ç�žJÒ,F‘ì_¦¶!Ë{3¾nåîøY^—¥›žÆ75¥ýd§@ê˜65 Âå$ÂZ‘±„ε-õ¾ôгŽydB&Ç":…¾SmõxƒIUH ŽEX(4@ ÇêP*h@ ŽÕØ¿?@èM ˜ıHÀ"=´8­ ÐCðT`"ô2(‹@ ı@hš®ÞbÞÐjòì5_ãÇUB¥0´ZâÙ_¸©/ÁªóÛ_'W©ŒÕlMXÚ8²0~…m"g¤ê--”B^3'Ö2X†o®Ë®×n—¦µOÇM”Å7WgU:[dqÑÒªg,0Ÿ©·ôrã „«�v\Å2Vêž…žp³Š[.&Ôwè…â{Få'W±]»=ØxpU¡ Þí+©ñC€Š,ÍÒ§)ÙTeQ†Ê–ž{¼ñv™(áj³Ö®€]ˆÇ¢Ý¤)I¥{LçT©®ºõ=ÕxPH ˆc‘ ÕÓ’YßíÝ}Ýx¡Ŭµ‹t;–í^Ïf×®d_æúòj³²‹&6ýmWrÕO¼É›*HõHãI%H \UÈäyá2΋_]ßCf;¿øþê”ÉT²ØDðÓ?û55"WIã B!«VÝ RÏÅþ»2~¿†åªìd$ŽË˼Ù/›mLO5ž@¸z¬ñþQ–&@ \•‹”3@èŽE)šÂÚ�«øþlîQaÊC2>œEÀ*æÓ+ØÏa•äWãâ °Pþ/¾‰¯d°+Èç„ÚsÄcÅOâ!òË(ùWAúe©¶9T«ã˜››#"}Ç®‚ªöMü§ý½ç.BP�Š)7¢?Å;¸ø‰U�j�%€:° AX0ÓמSVâ `@_À� A+0hȇד‹ÃF̃ uù+«$7Vx3øÿj÷‹Z³YLo•ÚÑf?qˆcuT8Ž@è;¸6P›oÅŸ î"¶oãFgò¿NCsþS Ì¹Qò8`3Tª ãÌkB oØLƒs 0y”�f,XLÞXᯋ™%LrËLjïäÅÀŸóKA:›’Ú-ıVû÷ï'"x°oß>"¡ù™Áf„H!¸”Á½�¤\Wz„MØR䧘]q¹gHd/!Õõ–Gœáqy töƦ`~·Pås³˜ç"”5öÃXæF¿$¯"ŒÊ%¤ž$ŽEVÏâäÉ“DBÿ aª &¨‚С!EÆ��¦¹€³ H��³ÈgíPžcÿÈX Þÿ?+ŸÆŸ9‹?Ÿß¨´PÞ5<M|’÷W *uÖn p`²a.§²B4–ÞI‹6åÞÃÜܱsBß­�œj1uÿ±)F²0±Í&*©ÌNÁBÂ6£ó µUŠ'Ÿ)ìRÓ{aþÁø'P,pâúXä9?ÛêæÑõý埃F*ý)‹@ š`W†wœvA$ùDüOܨ>ÄxfêKù3Ö""‚*ÀlfïƒÙ)˜Y@…ÓPTÒžÆ5xeŠT!(Ì<(_[­JœQñëK\[ȱ˜pSÅl?“E�eÎ m U°+Ñ0á—H‹@ ZäR@}(ø6]S\ÆÆ&¶fÃeÃËÔË䇒ޒ:g¬,Xn�œø]�MÍs(qñHø¸ó'Toõ –¸ª'7¹„ž&õ]Q6&þ3¨L*4©'œlQò6Û|¥é“®¥z ¦p,;Ó¨'÷(¥%íeÐèíe`Ú—u)ÍKðÁœ …¡mò1"@üg9ñn˜‡ 0ó@ü”�¸20€`Z¸ªCPL<>ª ƒ)q¶T¥Ÿô9œ.H§öرpXø+Œ6‡š|É¢äá‰Ç‡ª½4X²Æþë’7{@v¬«‚W„Ö`ûPê,Cû‡J A•;8¸Ì`.'oóíyE. wAHØUÂTb“÷>MPeÍé\v¡”x æö³Üì–??vpŸ-�4L¦k“{¥Â°dza€åi0-–a8Rd,O©‘ žã¼ý™û]%"!Ú‰’ÜjU–ƒ²+Äã²lÙ.ì¶T'qU.Õ‰¨^r{ÿ_4)T4{êóU£QÿÏ"þ̘ëÄ™fýšoM£íaÁ¹cœê‚TaÎðËPÅPµkY‚ˆ[´c Ö•½ìl ·BÏI]º!VÙš…Hõà°m<ªÙIefœ?U…žPô¹ÄSlT¥,Åù“È—‘°"ÉÆJ CªÉϦwÉdò´ºÞý?\“KÜëçѨâ°mZYÐ"Ç¢c;@¸àó ¬h‚‚-„¡ò“æ骎ïìñO‚3AN(K¶¡ ^�‰Ÿš88óÓxO•33Ʀ¸‡špº�ÓÙòÏ‘¡&?TŸãò¿Èެ5ˆí?[Óï‘J@ ô“De…Iæ+ÄTSôyi»R] -ßÂrbÁÒýTY”¬µ±Ø¤úG$§ –´3–Ÿ±ð)áQ˜Yà-/)-ŸiÀ|#ö¹ƒ0[îòU„³ªò¥–Z·b²óÖe,ƒÓ*¾f…3ÑBï‹V(kñäÇ4ÒÈ¡ ³ÃüŒ¸¬S‘::Îj\6²õoÒKQõäŽÍVø�� �IDATÞ™¡]„Ñ�2¥ùE€rÂNêRŽä:Iជ AЈÝåUKúÍ+²)o¿IËH3ZáX©µ†=|Ž$-°6X*“´îÎŽ§É(:tb%éË`Ü(tt†6Ò(,¢Z³„Ñ+È”8Ï‹Ý1íâθÁ,2¥¬�5€:06%ý>@+Y¢¡,yGò&#Dn¯u,‚Xu´=)Ä7vtÁ«HÆ"= ;XJ|iÈFögÁi\N.' ÕyÏ6zÉ÷–eð÷)¯&Œj¶`^ŸT'l†§\þ{A¢î[T^W—R”æëgÖ()AW …ñ-"üIcØ%…PuŸ«d‹ËÖã©Ê=[×güdÜBìªû ²+aZRÐ)âXh> [ï'Éø\‹/ÊoŠf厘µ@RC„ëë‘E8éq§ö²LZÁEŸ$å’h§ [.J!O$}W•²ƒuK¢ÒsÛ¶:“Eg¨VGd,@¸˜–±«lvåqv›µÊbÁja_�ÄA˜Ždmª¼,/"ÌER•7[�à*Á ŸÔµJ§Ï›dfŠóÂìTüU0b¬ Ù›Ð7N&)+í´«±(¾vaµö± ”ó‚@ šc`H¤0êRXÂ] ®&uz`—ÒS‰’¾,J˜Pů¬Ìêï­6â»`X˜äY£QYÆ ‹ƒJÝäY(¤œØÀ‚ y!.ÉefEµT˜ú Ð q!Ö<ån'„•ÁðÀv]ƒÈUuó–8%„ê‘á’ÆìbÇRJ—ÿàaÅ‘ƒ@O§Ë9Pž[§b;“ ´ õ8è:Ïœ+ªpᩦhÿŠ<a¬“äḚ́Æåm’ÊfO¦+IÆê8æææˆB?2*©° ¹p`dÇÇ«šL›ôâñRÁD7D')J×ÞPO2ò©™dÅg;y`Qñ�,ébÞÌ¡.“Çדèà’RO+Î{»˜<<ç0”åµâ_ ‘TP2Õ©8V÷@u „~‡T¾9 Ž˜‰‘ì­ëey*G4±Éc3]`•ç=Q’môÄç ‘T c¥Ä#c2IËTGê:ÆH°7(L,&ªÅXœbZ¡,–p)ÎðJ�Ó6 _ “jÇUà$q¬UÄþýû‰ìÛ·Ä_ åRU.FØEžRŒ–‹½„¤S·ULJÌÔM%‚†”ÉòÀXª Êe/¡ÊµZV,–©Ž‹5­Ö"EIª ËqW¥ä]…‡ü )ªÄÍf0ÓpI®¡@IB¸ôNâX$`õ*Nž<IDÔÓ¨98ê=QŸæ%ïñ-”ª?Àd,ÐØg`JY˜V¼'ªŠô,*,g1‘ÒFïø4Ì48ož”Òw),&f­éTZøTQò-^°¸®Ð- ºR›&Z•µaB’±hÍ÷"æææz„[Ð�õø�õ‚¤•ú½]§Ñ•6ÐØ¸m¹ÍiÙJÒL��L*·”õ2öâ]ŠéH”°b¬�ËX8cQj�³Ã|f \$Z”B+,cS<p¸Î¹÷�é (d;ãä+ZèL%ت*xùe,ò$¬Pé5B¡%(ó3ÊÀTÇ?´ò“æsQñÕtÖ.™&jŠW^Mˇ+x›ðTTÕn�“0:ÅØ,7b§‰˜ÿ¼NðÅ8â ùr~ŒÌ¿JÐO!XGÓ¸I\DcPrû¢¹³€8a°+*½Fh§hUô U®â#YD4׆펴J$¢­KÎÁ Þ×õfëÕùe��wÂÌBk…LÁÌŒN<&ø4¸RÓ± Ö›Orï*¶=3†LˆVù‚˜Ä)C"ˆíõ¿´´dä4jÓìÏH^ƒžYhˆ&iLÍÜØÔ]©-ôÙetç½­ußu¼ÚxW/ P?‰Yg‘\—ç…çö á"ÌëÁŽ4ð* ŠÉCª2€—3$U˜+›Õ¹�ÀƒüW¶7žP^€å-@9qUOØ!c˜o¨¦&Œ`¹Á�Ðc¶f Po¨Ù1¸Ä–pA�Ój¥ñæçpíÑ zR¢+‡òfßø\ÂA* Qa"UÂhê.´…Ù¿ì&£êÚ[ë¾ë.³Û{Pð–E®jŠŒåLVWÄÙž/¡^>JÚ~”ĸ<©’’66\I!¬${ÁÂ8Üø9€ €Ç```¦£…8‡¿>q9‘ÊÆXݧf¦¨C0´¦Ì&y˜êŠM«.ù–Ýk‘*ÞðBì”VÐ#l­1Ö"¶‰NK<²ŽQ¢ ½Æ–œZ¸ËsjGRÝ^8 ô Ëß$ÑÔ-zåì¤ã©×ã<¬ä»Å°i©¹þpÔe~tÎüF% |ˆLêñO<“…Èé7},ÀV€‡`~ê�ÓS<uE^Z‚Y�Ø©FSI×ùÑ‚SÝW˜žâ Õïë8¡Dí5:­SË¿·®™CœÝÍ.¬ö¾ ak:ɵ¤sÒC/ D T¥Ê>+ªD’uçîì†LSñ=‡çô™ÜGIÛý+È`^Ðj”pö0[ÐB€EÐñü0}À$ÀNþäåî+LßÓ(›‡�‚Y¦µ²&ŒMÉ@«R¬Œ» \õ9³�Ë  èR{áa³œš«Aœºn åášaZB¶È(ެð]( ÕsqvQ©µ»²Œ~ï°+{¤zjæ´Ð$ã®Ö¨Š.Cò¨lu¤Œ=€£ 28Š kl¯&Y‚Èén\¹Ç×|#v‹åB’è«`‚Y  ‚iˆÿf£LC�ðÞ�âïƒQ~}òS#¾L65¾kX0¿ 5)6Á,@ D×dfB“9Í"a©.-­p,Ô¦B ñÕ:n·ÀxÚ¢cݛ쪣:½ÕÚèÛKU²c5%f©ÌC¦”ÕÔÕ½Ôˆ~eå½U·rç+‚×֕¾%É·8“€Í�›€Í[N¾™I>@Á{Ø2°eþƒ)¶ îgp?›6£6=¹]ÍìyºÌ[Vrl$ŠÄXoér&´KVt>n,v•ˆI Ñé wì/QŽÒì]½¬ ìŽÄ¶Š]£Õ | ôÜBö¶+¶c#[ êh\^Çwƒi™n’—ÂR Ž€È<Ëô�©º¬eq^Áé½�Ïü=À›aôaX^ˆkSE€éÃ�»az*˜^ˆ™–™kª¬å ‚O0È”h⺼EÞ^Åò3U}i]ÆÊ¸ª×6‰wst£ïæyßUñÙþråwõãõ¬”Öµ»Hï·r š+­Eˆ®úµ^.§A޲¬ßó‘ÌIò Ð,[œQ…‰ÐS€ç�¶ÂòÀ0¿�5`,Nx1 �0ÿ�̼–ؼÎEÔôKJ{€ƒ«�›‡`4Q –e3Œ:aš·} !è8ÇR·9{—\Km¿Ah%OVÉÕS4ô4fBÿË~† }xk£¶’am–ª½?¯úNÀ2T…¨ºš÷Á¹•â hñ*óúšV³X¦¾­j U›ÊÆd¥ã™… xj�ËÂtf§`¾T!”Ê5%Ý{œ§ ñ!vSœi¨ª¿8ÄX†—yN)Á–´Ó@I«ÎÕ†btf»äZ] sÌHÞ–¿\ù]ž±NýrµÆhUÞÕÚX´¼šüãÒ›cÔ§Ê@HK¤„Êê.ì‰8¶“z´ˆ2}ŸQv«¤_YTêŒÄ¡N³˜l°X¡7[`¥Ôc~Ó�hH“²’!w1á^Â3°ž¨'¥à¥ª=¥é+Ñr½_¨E7«¢•OMy aE|Kt¤wV2ØøÞ£KT…0µ¼!€©+Ó˜YQ/™XIb‡ëJ}áÓ­Ì*IØï"@`¦“Ü÷=ÎÔ.3Öv˜˜. –¶|r™îôarè<ç["£ ÷ž¯ ’«ô›ïB1@ ¬UxB¬�Òs,Ù"”LTá¾Å¥94¶x©å«c¢aЀX¡WÔ˜M˜‚E€åF\™»¡OÌN‰"q~&þ–Ù)UÍ(gHÁKÏ‹!{‘‡ AÐ@ WªG8&Û¡$„«YÆr}ƒz z‰ S—Xt²+»*‡Y†¸œ8+.P˜-À|C­EˆÂŒqNÛ:Àô 8¯å¥C$ËIÜù”ï'q¹á  dðrUa“ÓR?Éf q¥.Q K­?b  %<½E–¼‚ı:*tKDXc¬K<´/àtÝ)´¹ìa"Ëð§—XT¾™-p)ª¢Û™�`ZÖóeî Ϲ”R‹D:뇉߹Hî7-ΙӤ)e :pwö™†ôV9gål©l¨¬š,<{ÙâX•Å£"ô¸èàð¼Pëh àSw^Ôó®˜erJáO±œ” ¶¯™U¾,+YKJvÚ¸°}9IÓ.«gÅ×$ì§, <rþ' ?–8$w ªœ—�L&UóN¾®Š•Â#ƒj¯&öïßODð`ß¾}4@4@½ˆz¦#?XŽìhƸڈ¡åÞqܽ»lÊm`{N&ÕèsÚlAƒ;_”…¡G•TÏŒ;û%…í›á,$àDè•È !Ÿ6­<’öŒ‚j ©„RVkMœ T’VÎkU¯XOÔã´Zðû²K‰§®›²JÒ´cê gÍoXÈE. ÔÌèZóÕu,ä«Ú€ÄGœÿ?›(÷ꉋy^¥l”äÆ ò ÓšÔÕŒBô •Ä57ÕÊÜ¡#ìj1afº;¾§ÒŒEk¾177×#Ü‚¨Ç¨× †=™ÂPQJ¦ÊüêVb'p;" !,ñkˆ}üx]`å^.%R—L˜”p se‰–Oy²¦© %§”?%Q“ÆY”KªA®D…ÑTw;@ lÉ_"ÄþÒ–Ð̶ò§:ªÅËŽ ¯P BÅ„ÏÕ”'ÌäCjÒ„QÆEE8߰몰Héþd¢Ù«(AÁ£S6³á¢X•»ËKçû’IXƒ8K&‹@ ššx"5…Á½| ^±T{2öÖ…’Ìnääe�H´y5€Yy¥‘Ç–‰B\!¢¯ƒÉÄ)1VZÖFRæmc‚éF_ÑRåòd¢–±%DšOß%Õó"]Æš°�íHµÙÂz'¿'Z,ª;m³ë_dÌìço¡=ÄÐc™×ö�¡ô_ÃÔ2`Ù+R³Œ«ÑµhÍ!$Œ'“œWOÚ0»W»Lˆ2³Éÿ3‰Ô’Ôr”Y-D '¥¸&d»8ìWãÜ5€’4}Å™,PO .Ö9ÏsÑOH¾šMp¬m¯ÓHu»[Û ÏÆ ¸¾ÌžAÕ¸7Ëó + ”þ4@="ii &*>—ägE\P³39`S–UF8ó`,rñkxЕucM‹–/­ki8‚*À¢¬°%sÔõÇ1Fï19P¨ˆS¡éµ'Ä­V%y±‡»·Â±²Ÿ(36ûú¨˜¥¼a'vC#Õ©ÿâ‚Ô+×^2ï^ fùœç^ʶ¾ŠZA5*Ëtp(9ùŠàs.·#““šZÐeB3üÅ7q@™P´°œ¼b¶À?”N%’P]áa¢VdUí®Að€+K½H¥¹×Ī™&QÕ£Úl3Ç2 9¦®7ôâ>=*öNí†v5€TI«;mRéO´*ŠAècäk¢ �ž¢ Kh²CîQrÊ’Rt¸ž°F¡©›I¬’’cPá<×m]ãœß”1+JX ê:QF8´ LVµja¡É칬¢ Xaûò ªëDT54vIµ1º ³ˆƇß}ºÆ®\çwO9àì ³÷Í5pœ³±;3*#ÑÔñ¤N¥ÿš >³T†áâ^.ö–îÉ]×¶~Ï•Fž$áÑÀªâ}`ZyˆÁ$JI&u%âJk³ˆ‹d² ÝUU’ÞÖ•ÞÙUNdî S–Rc¨¹ýL§.@›ªØÅj›Ú;Z¨lÛæ}›¯:»2ctý�D,äªâafePÑkaf'›i(i¬Ë¾Ë¨i"[ì+ äj*Ë”K\H*Kw—˜iÄìJá"åe¢ðU‡añ×%›á:êÖ~á»gæå[âm„æ¤LÛµ‚¥*eßß ­`ϲ«®ñ—°-ô!]S'¨ô§ê=!R¤è`o–7 ê^¡ªEr?Õ§ÃŒD)eíÀáÑ”¹J0ÕâÿáIå"ªwŸd“5GbÝ#`Žþ²y¬ I‘0Î h°(©3RÕª l˜³ÞŠ©9ìÇò¯·Ôíµ_V¦ÑN3-[À%FÕk ÐÚfT€ªéBSÒ¤ e“y¼ç=¦,¡[“O( !²”¢¡¥YçâzT”¸ºRËdh°&AÎ4„gŠt5¬È,… ›ôŒ´¿jyLË•†ÁN¬^Ûg×cQ@U¿4. ؼSÝ7[0Þ¤ÿKB§©J´*\Ê•âÖ£é0«ih?åSRꥤWbxc®#å­bRíw¹‹29…æÒL%Ê\ieA”$î"Ç.ÿi¶'0”™v“L¸RBН¬j¾¬%•™FתZ Û»ô†›uê]è"\á+Vw3ÊB¥Ž¾ÚõÆìß7;ˆý¸ v¿µm¤êÕ0@= —„ÆŠNçuû.Û«{˜6ªŠ7ÉÞ¢&¢õ´``¾;b¨ªE#'¨%Kêx³…g¼Ì—¿JD2xQ+‹7L$ŽùS gÿC%¿ÎjI"k‰uz?Õɱñ„¦̾°%éÍëɆ>[�¥€=gBµ„U,š¯ã1êIÄn=)A’øk6žù"hhL±,’&.3z:¯É[‚]‰°eé©›ìªâ4 vJ+H¡Žam�õ/w©òøO%+Å‘¸�3�Ì"ÿÈÏÀuqÀâ*?M'·‹k’{‘Å¯â³æëŒȇ°äuA¨’\^Š_Òâ%<> ±O7n¥æ¾ê”ŒE¹—š‘®\ßh†’q\êÍBËß/âl>ŸÕlF~Ÿµ –å¯òâyþ?ƒ€AÀ–¶°™€rñ¼ü ½hY{¬|ì4¦Þο™ÐêÉ0[à6­$®ó×ô~éÞÃôA¡ÜíÇÜ܈Ð2VèL]ad=‹¹E¥1ÓþˆRìe.Z¨%‚ËdÂbª†˜Ç„w+'šºH)̸¨[¼BîOÈÿŒ”‚â¡‰Ž‘•%x}Ë ÁXU’Wµ ã8ý¼$”® lƒça… ²x4@„¾DÝÁÉ*xÉ 4Ñ­V ˜jÑ_ÛÑ•Õxy_ÁâÒÃ00 PUÜè{ˆxlçg‹œÓ¨Î몤( ‘HÖXÒ’êò"53  ‰ÇÊ+\z*(.ȇ»óÿÕ”œı:‹ýû÷<Ø·o  PAK!áHÐ(Å|] œ|¬+TR¡š7²hÊVk�³²RpœEPóå™ÌÊš2S¦}ÒÓÚ2½Ù²…%0XQÜ�­(óò‚&€V] ‹Îï=ŒU¯XOÔã´êœÉùkšW[jÍ_‘­"ò©ß«"¿²Ù¤n=ƒ �6«‡TsR5¶ª>MþšG:h:7ºZˆv'ŸB õ9$cÑšïEÌÍÍõ· êñ"rD@X;¢a`{ÑÇ"¡»H× RPpšt™JvæF°r z®t= ½Ëÿ% ÐJÈNs• ¡¢ú™d,B¯@Íî¯~âªm–½�tïW…îÇJ-;GD 4'c©‹GÍËn|N=ú{ûú<¨V[^­ó{³o¯6VÑD#E tPÆR‹|ŸS~*‹ZçA£ªr÷÷šì5š{¿šóš‘@XM+ã&î?ö®½ƒ|÷Ù•ažG{D¯¼ÚĬîËñÍ’,a84_,¼ßѪèÙ#b cµ¡8–ËLÕšLÖìJÕ ’‹@d':Š\——1ú}ßÉÆ–Ô Ö¸¦ÈHö•go4@BÇ9–-pØì+é4º:‹?³Ù¡GZ j7Çš@X̸fŒ5ÐÔgtñôõŠrmý«Ø€–¿\á£ún¤h€’±|JÒo¡8)+Ðt£Úq)@ ôǺÊ177GD "ıú�Tˆ@ Çêìß¿ŸˆàÁ¾}ûh€h€âXt~ï¬zÅz  8­ùÕÇÜÜ\p   Õ«@PÅ¿DjêÉ�øXA±ÅçÇ÷:ÿt<ÓøÞ™‡&ÆgõƒÚÙ–IG á%1ÐÙ¯C~ÿ?DÅ*æ“çˆ_cƒ¾%ñ½òEu¤;ê7v Þ£5¬ ¬PN¡‰øÌ¯W:ÁÕ âXÐP"e.ò?ùÿE|w±(w´¹Qö.ļÁ`?ê¯1 ´Y©`è½A^þi°j£wædðÅŒÜ+]+hg¬èf|U{ãŽÑìý.æ'‘§*t–/{³S]›0î ‡Ú}:pkUØ2t\®‹³+Öl‰G}ÅÊõ‚}Ú¯Ó¸š. ‰ÿ Öh·sµ:@]cÕ®©²OõQMu6«Œµ¤ kKºíé–tôûrJ%‘¿*tê—«¾›¯Õü^©ÔîÓ[“ªìbGèÚ…]jF•o¡¢XvšÑf!HhŸëW‹Þò–äE]×:ù½«å-ðæ\këM¬õƒºßVDÜ¾Ëæ.Ý9Å£-i­SÝÄÚà»YºfO9ÿ÷Y&]ÀB ?._vÖ"ôfÆ-Æîïb\ÌÌl@]¹½nÊvâõ¥û,šïB^Zæ®"Èí–M û2­u;–±Û§<QÍÝþ¼êgC»ødÆæù;Eh¯ºÌøS-^£ŽJ|>+°\ú={ç5¶æ,ŒPe{RÏ?¶è»«YÇSä2øM)i@Qc6eDþœš|¸m» ªˆP% `M!—}±Ïª}ªa£œ¼ý+x5õ=°éÊ#cy„žŒŒwå(:Û#˜*“¹$C*]ÅÇù‡ñÒî%a~¥teð$ß2y|Ý©qmDz9“­´iáKBG'M0ÂJ¤+À‰\¢O.(¶{TÓè{Ì ´_ÃH~YÒ¤7ÁÃ4«Uȹ¦ê†Ž><¨*y\jXæl ‘öÚȱ²ˆ,-uWÅ¡ƒNå½/þª³b%,g-9ÚV…oùý)R%[3scËv¹-øŸo°°ŒLª—„!娱ýmsWÌù�Ó ªmžŠ¡É_m'ÆŽ{^ôìšØÕÕ)X¤v¶_BaïÃ`-©òß$…§¢Éü"ˆ*¢©‚—ü\Òîµ­S¸æ^¡Êv*çS5£ u“¿\­Y1« YšbÓ·jϲêŒ+»ãåoÉ*6¯ÈÞµ~ì¯h3ê|ÑË=JmÛÚ¸¾˜Z®ŸN¨?žXzgÛÞ?M<Óø½ØßNãQ꯼§ïD~Š¿„´·‹'xš”Úx[áXèrò|“ý×,««½+°)Ó}{;ÒÍÕ•Ú¶ì_öT_V2ÙúbOìß[c ’i= Ê„KèWI’Ð!P `âXBûÅRˆÚ‹}ûöQ.âXB§˜@ ŽEhH'ND ˆcõH'ND ˆcõ:H'ND ÚªèH „þ”±ÆÇlj(@è޵ÿ~" @ z›kß¾}D@ ôÆÇÇßþî:9¬žb0¶÷‚Z²wZÒÍs5xUœÈãXÓª/”ÅÕÐæ^k’í5˜ñºNcnnNˆw«ë¾Õ;-éÇæùÜe ~||\¨giÕJ‹âjhs¯5Im�ù ¡?@‹@ ı@ ŽE „« ­giB+ùB¤ÓV«!‹öt³m=U·©Šq t£"XkrZöÝÈÒ<lm§Ûà¿Õjm k’˜„«4ûXÆÇö‰‰ —h¥J`mlôáv3 aK4¸CüÀ#Û©MuI~mç.®a²É¢¶AýÞøÜ…‘µ ëjv{_m+ üÓ¬Y¢uaæ75L«µ<³·§CÃe¤Îº®µÖ³ÐÏ«»Týol‰Z±c‰—¹Þ*ÚdS³4RŽÎ¿ì î´ˆÓ :´6L*CÛï¿ê^ŒÒ¹s=§ ôáþ_WB+Ñ©,Ó¬)¢ugæg¦U\žÍ¶§CKÆ¿ ü›‰¿µ«²Ò[ y'–j–7®œDkÍó¢›< ­¦îZõÝ’‚¾Á޶¹/”¨Æ¾`¬ë×UÊ•7£C}ÉòØfßÛ!š7µcø^«¾Ù®¼ƒ^Zýøð5ÜTTÞZÃÄïåOË;WΚ:F}1ˆåk{>75[úh»ìÓÅß#;K¬:ðωÞÜ]Jð~ßÖ×üHh«<FÙ,ƒK®W)²Ì–þ"f® Açöûá={´T›j<úÔ£¯C#»*Ô/ú@;[‘./ÏþšÏ½Óøì;†èE÷¥«,C¿r’æ:JßN }¸:¢©Cމ΢]-Á¼Y2f—´ºÐ£Udá R§Ùª´0{“üƒ»ŠË}ã*Rµ…ͤuÌÕ,o\ùê\IãŒÏè—]<íf  £ íÉB‡îÐÊÿ–Ö~íBk»?»ü3Êÿe7 ÕZ;ým^­F®J 3¾¨]‹eUÖò*n,Y¶ÂVQ–&@H×hzıÁzS™O$‚Í´=HR’±Ð ŽE „þ�®‘àb�� �IDATœ››[Å6­îÛ{³%ýØ<ãããD+j$Ѱ÷Ûܳd î¼ëmo½÷O=uîôÒíã'öíÛGlœ@ =rÌ}û»?:¶qâØáƒ‡„¤$B`åimyôÉ“'¡Š =v 7,cËûQ«ú—æÔrêu'µ;) ½®YÌÍÍ ãÊŸÖéÇ®á†5ÕòþÒ R÷/Í©åÔêNjwH+H „þ�q,@ Ç"8@ ®6¬Ù¼‚-d±46«……Ú’ }TËíL½¥O[nWrê#š·‘òDó–çyÿvmùëÎ — ÉX&ùúº/}Z.AèŸJöžsѼË󼯻c·|ugåËdmÊX‚ž¬žë­íçtTþká„å/êÚ5ɵ½-ï¦ÌÝ®–Ûó§¿ZÞ4OçííéªLþ~_è-+Y&=!cµ]&0 צžSRË·—]yM°º¿u­åííÑÜÓò•ƒê_š¯nw\A£³–e¬^FËCÛÑÜS-o{׺Óòö â]k¹úS¼]¶¥«;ÏŮڮéZwÐèÓÄ 'Ø`kó�ÚjÒï“¡î~œ`W„îÈmdÀ´"Ú2+Ž\³¯o¯c‚ú¨~÷wX­©°–ZÞã‹ÓOó‰öiŒfËUØò¶t§¯WD'–ÉÚ÷l×\_õçØÖ¾./fj¹§åöa®íJ¢y?n#Ù»ÓMßÕ•/“žàX®Uƒa õ9íj˜ßñIý5µåÝ\Ì]kù„¢y§[Þ!ϋբyÿvÇsW?®ˆ ÄZö¼Pi”J/ÏÅm7޺ޕѽ5có:a§ítË;ç¹Ðš·±Ýly{ɾêó¼»³ÆVD'– E¡?@‹@ ı@ ŽE âX@ ô"p_Á¹¹¹6¾£½Oëôc×pÃR1>>Þ§-ï_šSË©;Ôìî¼ëmo½÷O=uîôÒíã'öíÛGlœ@ =rŒ~û»?:¶qâØáƒ‡„ƒkæ”M „µ “cíß¿ŸˆB „žÁfùñλÞö§ûÿê/>uïÌGÞ÷¾÷e|�«´þ+z}–¢×Ø_ŠoXh~°ß(/v·ÁÓ¶ø.ãŸvAèý³âë”ñ?ÿê×D)ôlv,ŒFω_'ZÂB`ózþeE)$ •'$OCºl¾ùÆ 0V@)&?‡È÷¢ üí¡>¦âÏHïWˆÌ(Ù‹ŠsR1¶×žrÈf…ø¥¢§êÐÇA:Ôº‰´*Ô¨a’Ô WEPIC¥ƒŒä°†ÚX q­bÿo‘ÝdSbPìYªÎ.mŽ½Úºh‚é¸E^þºHi¼:ç+&yµ»*€vS¬AõQbÚ˜CÏGdÊœ¡õØŠ¤ÒM}S5æ²r#爋¥ªÍ¨H›ÆÚ¦Áؽ3ùWñ©_~çûî¼ëm¹ÔÍmwPõM;ûWµ)JÍqõiâ]bΉo‚br[Ý|¦¼¦Š7ÛÕYcúUÙø Êÿ©]ˆÛ nMâVqJÆ_Ê®)WŠ'ð?ó•PúgGP”< ¨Êž² yeVLÔJ�um®ENq/Ôj�%GC€ï—è8Ͱ0ù³$·l¨[ih27X AQylYù©®MäÀQâDŽŸT!(LÌ.¨ñ§“Šï;ÁƒÆ‚ÍÐÙüN(ÔdO%% ¦ Jê©1È'‰)ÉžÆÑ&³¸q¶ {W—wÁ$ï «@4äÌ/rÂB`¾Ê’¶r …æVÀ›QAv>íƒ,*K²0³ÓAL ¹á–”R& 0Jfi|AÿÏø±bnˆ>^Ý|@˲I|É— ¨&ÄI¾á=-‹’iO~…˜|Ե݉Šä¾Q’s/^Æ”ˆ§ÊrƒS2älÅêXŒ!È'+·,‰&ÇW_V,Òv!I¨º¹G™üiQ?r%ýb€™FL1>mê|– ÒqbÖ!Èc3Ü–±Ðs®ÍºROñÈa*L—R„­0åEæ©eòŸ´äï‹q8õIøñ¹’•7§ £¶˜è¢O³ïB$Eût©ËIæéÌ8qW¹M;a…Ø©?tw³¢Õ—¢Ä‘r’Úæ v$ä©Ö| Û+¤ãH«I)˜Ü(ÒheÈÍÆ±‘-‘E} |W¤“Tï‘y}…‹,¸æ@o¤è²)"‡úP,ÞžÐT ¨K`õÈǪô`ö(DlÊs*æŒy¢m»–Â@Ð#lSJÄkãt>…BKÎcsÿ‰LQÌÕó²äQö‚Õæ[ˆˆ¤fûUiIŸ!ƜԺá ß–I  × 6»ÕâjŠæõQYƼ÷p,G46Ê.ej+×ÛSû›Ê¼Q™M ´…Mq,M'fÊÔ’ad4·ì?ú˜{Ó©8™%®ÀIvƒ“™»L¤¬F›“¡:ÞÑ! ÕG¨ëú"ÓDæz6ˆ/ÿ4öµÙ´†È§Šƒêe§Ñ›„œbCd¶ã;šA®HjÉì¥õ7>èJcƒåG¬ ªiCˆ¨þBsù¨³WãÊMAgö:Ä}F‡ ¢.CتÁ*Ô7²‚ ²éEÁUŽb]-NcœQPé%’#ídÔ"÷þšœRãš~Žåڳ졞5õûTQÀž²(Ä]l£ ©í]˜IÂ[9«vM\à¨41@™˜VE—$*ÈZ2¬Yæ:ÇN5Š˜GÚgІÍ\�ò“!R²ó†Öš·Å5e›°êö!Q>*ÄÏžb²‰ãŒ,Ó”Ý ß<‰üÛ¡\Šl’bjRѶÝÈ9*æP9«ÓØúÎæ¦áÇRO¡ÖAdXC‡+¸#Ó^Ž6Ã%êiÇ…Ða«æ¯›’$Š0)<Ò,gª‰È\PÆÄNì‚æÙQ7©9}9L™ÚÌ ìZ¹¸éT%~³+ãö‡®ãàÙ,ï±åÖ¦D@T›äÚI¼Í«kr™ë\ÊI§ÌèT’z>ðЧ ¤}7'V¶NF#E¨Ÿ_#Ì £‚ˆ‰ˆ"">Ä%N øÞŠ ÁêjG„¤x_°…”)âyP ­0þ2Ääªñ¯Ñ«p\t®"‚JÒȹqÛzK̓ƒíµ÷q[ól’nš°"Þ%&²t˜¶Ï®ñ ­9ìõÁQy°)Z…‰ê8tðûЭ–¨`ÉðKBE®Ð<ioÁ<†4jDÃq´"ñLiÞºDnh8ͳKÅ<¢!ÓÃÖ+f× f9ȼ¤59Æó.—O†šñzœe†ˆäŽ.€^á3¼¹§rF½kSd÷û¶Ø»§¹õG™Nâˆ^Î:S£Â™_JF˜™zµyR„l¦†;–GI¢í‰ŠÏ8E™A@dVD>§$T5ŠJW6UÈé»™nŸššl‘¤¹oJãªB/ÄÅD‹*&Uçfû7¢Ç).xœBm³b¤ =Ëš1êjb!·¡mÚG¸‘ÒöAEgšêp0TƒÁTý„sšEÖp‡úy+tî<ˆÂãd:Îß©Ëc½OeYt€žÝÁ³Mà{V¥E_Ô*“uOSIš’DýôAͰvcRE·¦Ü.l³ÿ™.ÿ{Ã\€ëМ¦T±^ÑOvª„íe0vcS|E±½ŒÝ#\ä’Ž}(Ø}ÒáVkÛ¦måñFáNÿ¦F¥‚xÛ¢ªqòEiå´x…V3BËGßaM±]<L9#r°®PwNÑu¡¶šÑd*Á…[¼Çc9ÄtÎîsa3U«fN¶È>|ª-Œy¨„õÈ—ša²â+˜S=8Ô¦HY²l„‰§Ì*Bv�ÛÁDUáú´µ‘3þÇæÇºÎ9•cUšÞ×RÕ C 8"o<[$n³ªÅüò߃ŵÁ¥hØ*­°ÕT V g‹¬‰†šBñB§²²UíuIá†ÏÅ}^O–q›±cdì�cO1ö~Æ>ÏØŒÝÏØŒ½‡±÷3vcdìÆîg,dìýŒ}±ŒUTµ;*˜íŠ.iUp¯TŒö©‘CœM"œ#t‘1.Ŧ˜`¾:ôŠY!¾ëÙg|sGUvÉÖŒÛçB÷ö9üÍ"'¿téóq1ÝCB‡Ò5D"Û\çÛ-ÅSôÐ`œ?ù¾âÐI„XD—×Ów|­˜GI¿†@³Dˆ¾ÙØuŽ…dÂÅ£©*È÷q€…�!ÚªºöåaõLÎrjˆŒ†b´GF&aí×"Z”iñ"IìTcdÖ�èá;X¼J1A(-¶©êdÆèõ(‘Ñ{›Ó$šxÇ•`—†JgA1ÙëEŠÊŸ”­*ÈÔ�ÊÀ"‹6s”€|_Ó… h°Šò!‰ba�0Ù€Ñ�GžØ ð]€s�g�Ž�œ8��ñÆðf€'�"€‡^ °`'@#¨+ó02€INÈùdÞN&¯.5 ²C `’ß«…L•8¹X`¶�3 6© ¨XöàÆ4ae€º6Õ({ª‹u!ÆÂ;SW“zoL[%¾‰dSe°²¨Õ€$K$‚¢’’’Ü2»fOƒ™˜å­íulVnjÛjÀ*�eþ 1‚<ÜGpQ¡gÙ¾Xü© Ìe+ú.w¿x½ÄlÐà/U.©]çC 'L™·9¨&¬›íÔƒE’¬Pæ_ÊW,*£S×—g)_5j�VMÙ:Šú¼²"ÿxÇU ƒœZÎÝ5¡ÔÏŒÃ.µ½º„-�Äó¯=KžRø~¿‰,Þ}©æ«tƒ¨ÚªY™Ì>veTй¢ü/riäPçïætƒ˜.Þ6™šA$¡Ï¥ÅÚ\I"ÇÁßÖÂkÞ´÷3v_"KU¸q%‚DXal*¹æ~Æîaì>ƈ¯+´ÈvCðëúísºsV`â ê†Øü•È6ĈhåtÀÍ0ºËœjñBý ÄD§…ˆ‚ž:LJzwT˜és!gDׇٺ|1p!*€g²¨XÖÇ(ÅvŽz·šI\ ªE4îµÝplK›™DØW椺õÀª%ÂÄÙ –Ô#Œ֑Ãè"ŠtD"Ìây‘¾36£Êb"J}`vèÒ `;l%=-#ãiÖ“uóõ[³Pzú•‡­ei½éB_tKö>42ÃÖ;Ùê8S9©¥¨‰5~÷3öÆîg!Äf*Ʀ»±÷pûVŒ½Ÿ±Jr}AýÐiµî]„òù¸WžìƒÓ¢cXzÔMÊs\“ ñp"C…J$Ä€á ´°ÃÄ>kÚ‡BÓ9 ÙvÑH»Ðá=¡²·ÈѻзÙ>åxâ%1›!ÛV2䘥º±°{ÔìSÚ¸DH°¹kí˜ñ^ÆObªD¿GfièHÓ:Ý^$ýmï WZ€Èa¸r»³¥diò[}<:C;à €.Õz·Q;ÛG&+ j0¨ky_´&Õ5H¬„‰[¨f 2Ô’¶ÎMx]Æ™™©ŠkVÏBg Ñ–ÖÑ–åsÒ’]e´P ²ˆŠôK‚\ªAÐÄdE%m«’]Ë'Ù_JšJ–÷«dŠ5ZZšé‚¦¤bSP‹›· àË�S\8},à9€#�OÀòÿ ��¿ £÷�| àÀn€õ�¿eå]ŠEdÙ‘ãºT Û jò´7"C•‘àJî•uÇÈ+J¶ ¡¦ãâ“-˜iÄ*~}¢“·$'¿Ð2qÚÖÍå ÒíÈ5 0³ 4–ññ-)›‹š™,I^³…XµÅIkù@KG'²bžkJMrë¦T[�o™™q.Ÿ hˆ…Ã5ÆA§žèÇJñÅpÄ” �™ž i�Ì4´”N1Ŧ qÕ!·0 A>ÑtÍ<�e€™Œ`vJMrÆóUùÅ`guY”ç9¢*R#ÊUñ{—¼G5SçiÌ@LO‰/Í„vEÅ:PRJU�æ¹VF§øb‰•{5…Q’ª¢äc«óaEӢРŒoYY</<vrÛ»×%y’6¥*S½]çÜÊvNÅc„g×µ½˜2j8WA…K[öD4WJòJpÄœ8âÎâ†^¹¼ìT@`g†åÎ{{wd÷0VH¬Bòù~Ʀ•à¿8LSÉVœ²‘g¾y¢Œ0�3ÕqšN]VÎp1Û™0œ#,ùHÅႨçFBƒ„ð¹)ïr¤Z°J€9ã¾*XÊ P’TiÖ~#urètJ4zÁöêtäÃ5óŒ„Hþ'ã!öÌ·51†·…|>›RÜ‚¦Lis¯°ã»ÍD†£|„-gÌ:`O`$n½‚DZèî¦i2–™úÐåé ž­”…2skÕí¸QDä6;/§a6–“˜ªš“‚q„÷x€;‰¢Óƒ£¦›åUñK1Ú‹£±í÷᡹A@ÈJ,ω€ ‹ÍyaLʬüñÑÌl¼0«iØEÒU!*‰LšÆ@£&Ób~+Ó•ÎâèKü'¥– €<À>€I€ÝÉ“6�ìxÀ�×lxàa€7¸¦§¤Œ"Nô%9¸´rÛ5?†—ôý«¬ç´µ¼Ì¹ SMNÙ“ÒE<Q©1£„³€¡*Pç’ñÁ¶å97L„†¼´ÿKÖRSæusÈ4ßñÍüÿ¾œ<°®É^šé>RNú‰œ!…w~q’YퟳÕß$~£f–+éÞ¢w‹\<Šÿñ£b·¡'›©–¾Y™Ø2k°q¼ªh"2窎ñ]A‘o\+*ò;ëŠV¦®ˆƒ}rNjr¹Hbäæb· (%ù‚Õ4/dÂÙdøT/ )e¥t»¢hY}AÑŽ”4Ýo[’½Wúw(jÌ8¿0ﵨ͟š¹9å|û`Õ\0©"Ž¡.3vsûÈ =¦2dq5·9‡&æ–ª´uâêÉÈx²ê¸‚:ã™n-º;Ÿq>µ3‚ûY‘-*×£‡L*¿4±¨yÙYê%­f4Lˆ½².ŠŒ4áÒ÷ÉH Š7]’景“Ø‘Oø ,ò]OîG°` `à€I€3��°æß °à1€‡�æ’¿àF€3�K�Gäª(,*_YWì$Z‘X5'i>]à*©râeªª7^%×$+ùä8\—J#݃¶Yë´ä[%¹¹«iéå fvJ´A;¶×ù.#³³Çf’©\Š·T‘J_U_â¶¡ðÝ­ni†kÚaT°u[j® hp>TJö2Ánƒ†PjÉm7Q¢Æk®M±ØËR« %€ù†zŽŒws®§J4«ªvWõääÇ2EEÌDZ¤KŠ“ÊÙ®¤Ÿ-J²ƒöá^Õ¼ÉÓš’%Ô´­jœµ«|]có‘â2ê›dÙ:’Š©UO^Ò¶V_NáHžtô—ŽD{Q{Á>î ¥r~ÉC=¼» þ61RÅ™œJ±‘§H”9Ù‚ˆ]ãÖQÔñF[øs¶ÖSÜ«!”Ú©Ö;Û˜dßhˆ›Úíz´€<ë5%]é«×¤d(ëÀtAÝ7åVž|æ;#Êz•ƒ­æG+ôãÉšäÂÁrb·˜L–p_�X¸`À€S�¯�˜¾à•�G�vÜ™P¯X�˜øy€0[ £®ì>5}”cÏõ’Üwxƒ &ÞSÕ´J šo$Sn'c˜_C6[çî2çšjt8bB4sqDP¬îA° ·ÈºäÄrRÕ¹ Š×jµ$ŠJõ Y—Ê õ̧Wµ*<Ü@8:¥6€gj°|!—ð–O*¼¡"OÕPW fñ‹˜bòÌËÖŠj#*ËÇyÕ`©†ë¸ª@ÌC9ë#‘dWM€“œ¿çln“‹£f ±Â>©Ÿ`JÖzsx¦¡,TÌNÉò%YÓ„ËŽªYTôwRù\Ö9‚ FY âÖÓ¼¦®òq]Yàu%z¤hªîð|1©ÞíþU4 K;ìñ‚Kɉ×Lb$W¶,¶ì•*ý³,9AR<¡¾4ÐdÚ‘ÖÜ Ï(Õו5{@jžF;¡xÅ]Ä2ÒC)µ˜Óû/ö8óÅ}2áEœØ‚ÝÃ32HC×=ª¿–Ñ[ÕŽ+ñ]ÅA<Îc^QŸc˜š7-—‡ÛÜÈà€8š‡ŽÒ‹!â“ àL®Žò6Ñ�Üá^Euž´—â ]pùÚ9^C¼J'šúÝÎVnÛñÕŠ†4¸ ˜ùFÚåÈW Fn4ó¡] M•RAŠ A±ô͈ë¯ci¸ ¥¦1¯©œ©Žéȶ¶auæ²Ëœ–É_Í+Õ5#{h—§À14S‚ÄŸ!•w®Üµqj°³š†¾Th‰°êk˜»X¨Ùä5ë´•=ÝHž«ú0öÆ*I¸U!aZïIþ¼'‰Íº‡±÷0vÿPÑë2Ø¥‡#,vhÕ¶ˆœ-wº¿ëÆÕ…Ý5‘l›?žîªƒƒÍ5Co. {LѤ¶7sˆñ9#$+R‚{”Â+ø¶åÚøµšL—P£:ŸÑôz�Z½„U ¡Kh¸‚ʜԟp�‰¼õw<•wBG§ÔéaQ’Xr,;û:c]»"ž“Ó*÷cú÷‡>^eîüã±²lÙö‰Ã¿ŸfŠâò Ùsœ·"R8Òßea-ÙkŽxfC&™!¹åüLö!È—™Æ®xf¬œÜX4’‹Œv ²•„ÀX…±÷'ü)þ|’Z0ùW$Êø~~M¤G8±pfÅfÊÍ7ÂÎæ‘£³‘3UФD‘¹kƒ7Ó`9±@«T "GÄÈLH»·yrá+™‹= ÅA/x'ÿõÔ¬8�ÈcC‡¸‰åAG˜w„9@:ê@"1yz¡,³/ú1ÂSnJ˺™¥5’.¸dár6ÂS17T×^jfµ£¿CgEÇœkCtUæ¶ýôbu¿:Zf®,2 õh�¬r³ªéNµÇdq”w]¦ª§m/—MHF®8\aså^ê~Ú4Gjlk!?“m“žrº§ªtŽ– ÷!¡§VÃŒX`´ éâKHÔ‹|”Hþ*0ƒx‚"À| 8° ày€G�ÃôTb}zà:˜xàÀ€-�OÂè^áT‘�$…|ìŽQNúUWŒÞ5=¹×d’n'Lìùªu½¦c qVoÔ"~Jšƒ_ÅURÖlIÏ?´˜Šñ“øTì†À‡u’Û4׊f¼át¨ô‰Pg`M±‡éÈØULz£é¶.9™ç4×1Cj¦¼{ÄÅ[¶,i_TNúÓÕMF<Vµ«IÃH— ¨)ëm˽á/šUOó­F,aŽªË°BéÒR×åƦ`¾¡­îP±`•%‘…£S¼ú¤KQæÓâ-)&n2ÂU¤¦x^,jk2&¬ªû‘‚’ELõÌéøªš±U·éÌ)(6;%½9âY:in ¨ËXγ¿«(êæ§Úê…¡OtØö@e±ãûeͬçö_ð{u{\íQ'=ÃóBÛ”£‹_šáƘ‹”§µv¨²ê6¢žl¯OâtÔL³³ÜþJæ0©Û–Ë×C˜ÇŦÆ=ëê¡»Ò뤮­ és¡0<Þ¤I�øÀ4ÀN€Ã�,¼àk�ënØ ó �o�x#��än†åeÃf š™]wH‹×¼ôÊ­#Gq BÉÈk®x` _ð’¶õð‡””°ßR²¹èr»¯ë ýª2ó¡ÜŽŽ ��GD¦AþÈQÐB=€Zñ4\j%³©ó}‡›çjÀ€L”Àö‚šMnRw˜oH~V––éF4d†ÃŠÜsX˜ìæe݃£ž¸†—´á ÷ø‡äÞ˜óÙ‘üi‹üa$<4Üùz¯é̯¤…pº•t™Õ±ˆ>"™{0vÕ‘^$‰_‰º°»·H¬z² CÀ+BæUß7;vB]ûbFÅ©>c¥¤d”2©œ)gNÙë™9…JŠÓlUs‹3L�S½×=á©ê«mÿ‹Z&V1l¾ÒRTœée "•ëàY‚æ/^4û €Èê-¨Pht*¨j©c³@ª[­ý^ßEíErÉex©p™³£ÄôŽgj>PfœEô̘ªWÿPÓݽÊrk–«¢jÆL~WIÿ>^“³S�·¼àÃ�7,\°àf€1€Û¾Ó÷�\ ð%€›ö�l†Ñ{`z àAVž`·¤Lc6Ë šŸ^`¶�Õ†ìu¨yu ?ò˜ <Ü$Þ¹–y¾]¾tu×;0Ïro-ñ¬Ájv`y¸‹0c¨6äQU¡Tú™†¹xK�U§rBî€uKC€jìk¢ò¹TÓ%’ùFPlhkQ6ƒû¾ _¾ÅD°¨i _fôHÂ!‚ Á”%Ó… ÚPy†|B¤’´¹å„Ä×Ï7d›#€E™Yæm©hrc<Á±\Dµd€jЬ»×Î4´oê’ÈBi!G­¢xožÈ¢k¯…÷l¥íruåä]Kä*ÅïÜ q“\º…™F2ó¶—2ŸÉõ< 0ýÄ ·Äº{÷®L{}¡µ|©©•y›IÁÐlù¨Œv ¿eÎ_Õ×¶NÛ2YªõÈUÌoKu6A-=Ù­€OEŸ·X„§¶sÕïñ½ß¤‡ä¨ ­âÈì>ƾËXÈX…§äöªøs\ëýŒ=ÀØû;ÀØŒ}Œ±ñŸÐ,¢–{˜ßÍ­–¤UÛC£ú1“‰40D¸kêSj× Á¸ášV�� �IDAT‹óV¼å¦"˳#ÄKy#£RO½`›s�µ]0W@“GTÌLzRá ˆ¡Nª7’ �,§Ó+\ÁsLƒ«öMäNOŠeÑE½…MÃ[<9#»Ù %˜C«<f_�ľ…¤ûK*dÚ#¥9=UÜÕ[TÃæ•Våk÷¨I_ÁÌ9Ñ=%&}|"Äfs%Å;ÎÇ ÂôHdûC*ïiÍ©$ÝÒæI¦Sµ5?øŒî‚¶zFq%‡5êjƒU×^xà¨PŽxDIjQvcße쓌}R©u Añ!|€±2ö1Æ~ÌØÇ;ÀÓ5…Hmxp§y4In¤çVÇÒ–#.Ž«òžMÔïÃ2tã&FGBÜk@­ò‡–½G Ú9ã+HÖZšZ«µææ¯¨7âÄ"ñ]{ â/!¾û¶ X)ɵS…ýØñS‹ã+ÀU¾@°¨Ð¹ØÍ2‰!¾ ¸ú î”Áæ”TÑÚ!F„Þ@—ÈáìƒUÕ2Âÿþ ™p §¦Òq92È 4ÆO‘S%%•Eë]uÜãÀå1!潑uוlBõ,�,)­?MŸm…r%ö˜©�Ú<¡êf¡—%ψÈΨ{t)‚D(uŸp'”Ù)UÑ$, RÕn„Ævòš®q*ë&ÀO}+ wAîÚ0ÿ�ÀC�¿�ð¼  ðo�>ði˜Þ ð÷�ß�X„™{�*�ï…å›�þ=ÀÏ<GòÊ„ÈyMYÇUR%i^ÆdÍ$6_/7T>×þÕµîpS|³‚n/Q3ˆ ë(±Õ¤%\Ì-Á«nS䑼Eͧ: 2²4ݤi >2_FÅÌÐ#Mî"GQ]&Б«‹ÜÂ!@ÚoÌ,qE$·Žjn‘Q´ÂœòT)¦[áïSSF¬§)³WõøàjÆE-­‘iÜ­[Ékf¸V°¤¥Ãà 'hpW€¢é€nø+I/‰¢™Ð@ÍÆk¦M©˜©ïT%¿ÜaêŠ]0™á2®|¦¡µÇ2vH—%ÝÞ©9UAb?®[UÐjpjQO‘Œ)k!C¾×ÔÂóùϯ3t)¾À[Û~…’“§Î^‡x#3 sM…3§ªQÅ/Û¨—0é–<rbµ ù„˜ºÀIcÆÒ:R¦jN½=¦³UU qá�L_*…$"]õ™•ÈÓÝ”mu¢ûr²íc¾w¥o$Õ=DxÕ%PãXC¬Z®2aì. j+[RÇ °Ù²©«¦—-€=qà”55#Ôâ¢<ú$T­>j‚ ¸ µT´ì|¸Æ"Tt}¡“Nòºb„ÑHÊJZLº~9Ä¡¬2æ­a§‰y3ð„Iþͯó‹¹Ûew 4S#b¬BÍc»‰4ã¤àPX¹„6›vV'°²@á)*È£w•š²GjÃ?Pd‘‘9ƒ†)yפ@¦™åGûEÓuPë¾8â-*ÓÏÈ™J~?Cì®iÇI­`ʤҵтôªkz<ƒŒxö¦HJˆ]ƒ*ÀÌ‚(Ûû³É E€™÷6ªš}"ÔñI"&õò¾šOœxÉֺégQɼ·è<„©"¾Ìƒ\’ª`‘ÐHOª]ˆ½ðUk%Ï0[Ô’«&™´œ*AAHŸ<ílE÷±îgÂ!m¶`œ`dš·¼5¦e…J" W))–8©ïuÅ©ô(i®•<GßLCаEòç^šKwôr-ZrÈÑ‚pLà²û¤HJ9‡RÄ DnY‘¾rg�¦ ±1IXA°�Ó{¥—ÛgÊúyH͘jÔVýJ„ÎLa¬[3¶¤hÚòNc|& áŽØ=W©…ŒF;x­) Ü)!R£€S-CéÆžŠÏz”šð"cíGOOq·…hE–6Ûh2‚H³˜Å°S¿óå=ë™^ ¶ð¤ØT³¹í�‚g Šë±'Ù„‘Û"ÂrUD€ÇáV|¾eÏt˶mÅ1©äSFePÔ÷=_ë5‘§l©Zš¦BD"A}L³YˆÄ#먮Šãz!JP 7‡¸G€™î!²¨Ã…¶F0áÕ6?k©¡"Üt§öl-Ö#²Z„óu–B_š.U‚4…þ{·K“1æÚõjð¾Kb޲y^ ¹vœ~çîãJBŸÎ-Ë>žîè.ßî«”A±‰¯·&SW�VÐ:;K¶ƒÌï¤Q‹8à~ƒæ×d§ Mw;tsGÿ÷ýäN]ˆ¼74=Ü >�3þ·ÆG˜û“G¹!j.—)RØÊ¤*'ÑŠ±x²wñ*p©B“졜Æé…h«§"l †:7*x&¿£)ê>hËwÙE½*P_V¼j³+óV¨û †8Û+™™ÆkÕÌŽ‚sZ_Õ%�žëÒή‰Í ñt‹�à9ó¹¼X]kA·>¤å¼ÒqY«ÚbO¨ßîJo¡¥B¨buIBÄ_� ª¦‰uSKfܲu2h°3nºSâ(Ô¨ã†6Ÿê¦ÕÝ%zA¦¾Ñ’f„NÌ£˜NaWu™nÜî]\ò@«…j•(“QºmŸ·D¥Ëʤ*IŸTyéjT£1 |ýLZÇŽz¢N±÷¦š6“¹É·”('»1/§: )Qúª_R~41)/Z3jÒª&•èʤsÄLCUרúO¨LOÙ)Z¹:=k–Tu“²¿LiåTÊš.WªƒêºgâC¡Ue@t¬Ԧܢ^¸ž V¨-Õq{¹b(º«‡jY$€2”Ú6C8]A;ž±‹VÙHÓéÉÄ€éB\ÞET@æº çEã¹ÓPI¯ ]Ôj—ˆä)üiBÍžçaÔ`$1(a¦„¤DŽÐ‡‹ebfÜ/êúùº6|Znõ’âà)‰çQcDÙò¡›ÔÅØaâøhNåè“U+èO¦ŽÜ©�­ˆPY.È’‘Ý%öyD7ªª5ç \éáÒ†i®¡SãÚD÷šš4¬ ›ˆ ;‰›¢U„«m¥žÖº¢iflW]—$mê ½Š"Ü�Z¤5̲f4ÆTªX 4*8’Ÿ:ýþ]úLqø0]_ó^©8%Â¥dÃ_ìÜÿó0n3‰äÆ)töª^-–ÐŒ0 Èš¦.‹´<ñH™â¼`Ò¤‚Ǻy$<t/ð:‰D–¤º.‡Ø¶ó^Zijí ‰)ôÈÁašƒU—•1MO6Ï Ô]5rÊ×—L«šjôl>‘¢ŠÈ|Ƹºø¹KJsy„«š("¢˜Çj¥9}„ºñtC% Ž*FÕGÛ9ÅH5"YWñ-õÈ#M›`Qj?)‘”•A¬ËìAª_µj×:[âbЧ@qaWO¬uÍö‹Èu0+ÅåÍü.¬’Ô3T6MYíS=Û¥fªg‡Hâ§*´¼D깾㨩Ž¢†¡a¬V«êÔ¤Vš#r¨$—«ð’#*'ÑrCÊ vXERLæ#(âûHìAÃýPêÊP–eÒ)és1ŸZÌ'+¥äÃrèŠ+7–`~©%+¼á•ŒõJʼ-'³¢˜¨CF ÚAª$ëŸiUÔkI %Ö)e0³ ž¬y”µÐHL]”’q]ºY®m¶Ö'°D&0!²kûjIsm—“Ví®šÖ*cPÔBëʪLoªóY•Å –‘QH¬R”­@Ò6Ëb’óX§Ô±5ÿ©{ahÔ •öÙ$¨âŽRC£<¸ªGþd°Ôàd'Þµ¨r5U|¶Å2Oý§`—¤¶hK««*{±NVíæ,ÐŒ†JæÐŠ,Ñ«Õge³öv6ö­Òêj.&Ÿ•”nê¶Îk[ÉUõ£Ì ‹e帰¼ ŸYÓÂAä[f šk¤èg 󲢸C&jQª’¸¥Q»]!ÔrAñaZÔGY/xÓ1¹N–H.iÕPerÂdé)µ°ú"e° …I]VUgH Õ#æ¬]Ýåãì|5¥ÍõDŸœOè9Éýõµ‚×E™õXžÄKºFφ,g²)ËpQ9º*[vÙF5õ°HÅËÙC]_}"©RYßÙf œDŠË\Qr‘¾2.Î+RMJ7ËÐ<…{t3r.òI¢¦©5œÝå$œ-˜ó¶d©=A›f†;¥ˆÔ6®É$.6)ô*¾Ò¬cyêÙZòHj„N­ êvባBÃø=j7gvS»¼_qçWÇyü÷²ç1jJÉÙTUö|þ$#.Êg³ÌG¤¥,•‘m­E&Р ÃÊðŲëS˜Ú•3ÎG¸Ç£á]âò5P Àá" XÙ!³væÌ­(ˆÀ#|ž©wþÚÞ]G–¥[ µ…1tŒÚÑF!ºß ±ÒÀú% ð¶„û¯œhºòÎC`n;½ås´ÑF N  bz…‘‘ãòÈÈêuZKSsõ¬K^"cܾ M(ÈIJ< k”ð2èQì:˜„EVÔYuþ[9dj›ÇU�åØ_ÿX%$á®2!á Ît´9ü;)p G`B_’Ö{|óF£ž­¥ZÍ“XO™Q>Üñ0üŠ$gvŽ0±Í)ÀÑ ª4E‹²7¹ÉÁeâ1#`ÆHè—ã–Áã$Üe ŒâC ½Þ–:¡é*‚ac0ОXÂñu…²°ž·§ZÕ2�&aD>‚&{GDŠ)Û&jª­<»iô–5ØK-ž¦8+¨Câ=–È(ì‰O¶vy-¹DRä`d8ÚÁè»0Îá¨Û”«3»õ¬sù® 7×`û¶á'+X`¤-`974ê…t‡"g+‘@ÌóN8*Ë9Ÿ™ŠÕ,A'4^)­ êÜk |D®ûAußSÂ&õé×ìTE#5Ç^ÙˆqPÃæçÃ=«“z<¶¿Àñv=”FÃÌÞGqLŸvŸÚÑÍÌíaù“+­“b“`¬mØÓîBɵ¹û‰¼p'YH°8ò/7fÄ’‚(ÔÐ# Âv¬yJdòPÏŸ;–rHhòßÉ‘¥õí*¦@Ž”a"OwÜž‘9rag‡ÔOÈZšCÒ9 \|'7'²>Ô�²‰/ó¬,uÍs€eðÑWÜ"d?mÀ ÷¿ƒÕ3†¡Ëâ8©Ò*LVþ"Iˆ?;GÖ¨’‡=ˆ;{n¯„b34fÜ/­6à‹)|ºúµZö[�¬ÏWÝíǹb(ïŒÄ1"?êãQ Ðn:¨Oš8C­qÕñË.Áä8eÉÀD<j~©G±# ÛAù|謵s4=@˜éô̊yg|׈bè¬#t°“Ï\Äï;Þܧ˜öN¥.4sm,yŽdõ£@KÐU@ŠÖ¯Ê¶DVëÝ?t°;¥$ç9Të¶|ñcûh,·Ož‘[*Â1*æK6ip¡kÒ°3b=V4 ê¸ïÍ뿾WoÆœÓNõö@£¯S-õ ¬hÏ<�/ÒõÀµµŸ™™¾Hp 6ÒFâ‚'!Ê߈›Y ug pĂȚÝß/›Eð:ªöAlÖŒgœ`yð $Ån¾âC>TÜ·ëD(_àºÃÖÜgÕ}ôbPÚ.ÙÀmã Œæµï¾ro0U®þbâØ¹„Ý)Àî°X´R¼±Óö»åPŒßo~p%EO@û]‹•ññD5Öß<Üšóvíi /í$êQ"”"Þ±Jê'À#®ø", ÎVÀØ“O#€b¸� BJ¶S×4¹ž ˆfK6 g; ‰Øã7zA+Ú °4UÏùÔ´®Õ‡L9æ ØÕö­üœ ß¶ˆ ~´R4OŠz\àpWo<aéy5Ÿ­îï7{IÏÍŵ¼å"žœg ¦šÚq–£:7+U/g'Ñ›0-O­ÐEëá­@¸åìòÚPsË5o$ßI[¶;hg]ÍÔµIîápSŒÎ ~T厹H,Ö{­ðÙ³’'m†³/Gú8v«Ê½ßèåTàjWaV+}G_›s¼Ä¿UÒÅ‚­¯¬Õ&¦'ÖŸê©©V¢$ݯJ O1a–.ܹÁêŒòaùä'c~j†‚BüºÕš¦àT³`d¿Ù$Pˆ+ÿ½¸Ͻ4ºá÷rCäß¹ñO¤Ê¢O} ýy.Žáõ!*¸Ê÷æ‡yxÒ¾áËϯ£K2®ë›XÁm$[ì@÷½W¦ðöñã艷‘ó‡S¥4kð‚<0MômBºD ¥“±`6ÑП°R‡DK•;+?KþM±Ûd$½Ã]ö´ŸÛÃi‘[4ª?÷S¿øŽŒ£6}ÑpÁÄÁ\ª*òɯpxpÔ—‚9"£ÿMˆZÎA'™±,è\å%‘ñªö†döeB„ž¼Zy„Ôý´§�¨ ÃRl´°E™¼-¸Ðìú1Œ)½av/6÷Kt2±¾p/ì‹1óž®à ïœ}dŒÔ…Õ¬Í�9ˆJˆšWQ{pÅÞaão‚V`ÈìCïF¶ƒý@Üvc´•#õÏ~«=lFj˜l'´›“6£sê]ø`Ç`.„|CJäàp‚ãæ<NOê’8Œ7ÛqJmpe9PŸcü¼�ã‰tàÆ1ƒ¹—ŸÏÃUZg¬^P©FH ²ÒmêÜdòÝ� )‹1*ºfÎ=qDh ‹gK<È.[þ)c›fŒrмHØ1Gö.XÁ`)DàºP]c±ÌF°>Û¬#iK oGÂö&r$Úp v¨Wbv\Êø§FYpkëÙ´w]äýîÖð�W¤ÀÀLÈ9ÞhR ýiÀlkéƒeC¥g®ø;Nü”"oâ@[¶c€} ¥›Ê ‚Ó|=A±Â²­üœy<‘Je-9­÷È Ø`8ܦ=Œ¢#ž yHXã˜ŪSaƒ šz¨‡N;o&K.âL¢„>bÔÁþÀïbF°½–‘ðÒ$ v!ʵíö±îÓc ‰M�÷Ïñ{é_#}¶ÞFÇ«ÒA®Õh¯5?¨¢Þ©Üò:8òŒ1cÑ™D8ã]•’Ÿé“ȧ"ê�c$w!E  cÆõ‹Fcï»»å®*¹q53Éu:ò_ÏÀ©o|l[² ÀdW"'äjë’–Rv ~”µˆÙ"b2è0{ØQ§` Á r[ÆÅ"úöŒ¸ÞÁ£!?E� xY�žÂ…+»òer^‘ä Aí‘Ö(‚cüPüÔÅ ¬èš¼�e08mBŠGF®Iýò=ü™J{4[kÎjÞ®0¯V3ÞoL^?Ê*Mt$cÿå¡ðvCÚó:"^%¨ï÷·U˜„9úú½à¼¾n-„õëë*¶ÄJ_Nš©·ŸÄT9«ÂEL.Mc~AÇѦŸ&wá¹!&Té°‚¯D/o–©³®©½Ý†Ï² ¼ø÷÷2”.@€ަÓRÜisnWµHhó*Šx±&$4 ì¨M¼¯D¿Žôþ]ìÏ«»£Þ(›Ùy]ö_ßRˆ«é6]`çãX€*UDjnV“êIyvÉDuø\5þal aç]iŠM⟠¨çi½žOîâUrm,‚v+?NmyØY¡ ¤º| Ï«áEc¦ÎA0ÒÌìYaÙÊkΫVçç*èþDD[Ð(³Å´×†]²:OB>¿ÜÊ*ýwÕ2’Ï ¥RtúÕûwXªn–U±)^ņùZ`5H%=$ÍŠXZпGÆ0)6(c@™fcÒdQ&øA%ÜhT�=‹m¸šzà@_¡CÅ¿Š+Ÿß # Ûsû‰!`þÁà:8ÀöNZÊvðçÚâPùö‹‚f^épø£ž¹­3¯dh3ž‹!œVÉË©h£µˆRÒY/Èó*Úö$Vì˱n.Í\Cx…(æÄõ-–BN´ê¢¶#ÍeÞÿ(€¨ç&Ø\›g÷q»kõm7nnØH»´>…nçáFZȵ cVæj^Å‹—GR"ÔÒ/c9Ôò-¿odûd÷ý¶8/êLËî6‰-þs­ÈW—^UÝN-X–-øåTô§¶]J‘Òrا^]‘É“8้ Ö •ú–H©6‡±Sößg%ƒÙ~Þ¿ÛU½èt˜CÒÖÆ«¬¢Ä‘O5”Ÿë' h$…ÿ,ÏãE� åi!ĆÁ3"ÈOn3\kµwMB`vuôn‰ ~qÃsNÅߤÉNBHúUäßÙŽ)7™Q¬`§©5Þúì1d ýÀÅx×Ìæ×@ŒŸËI`¡#Þ>¤(ÌG#´½È ?¹•¦ Dáp‚3&l‚!lØWÉ]nŠVoSÉlaQv®“ƒIxì³ç°ýL°.;ìá!Ì‹Íí“7¨ƒic¿H1/cP ß¾nÕþ‰ð&CnËØIg�l#§Â'Lj±Œe Œ(u‘-^±½åŒG¼Êô„A«³vJíu`ÕJµ¸AHvLxÍS¤W™uÿ9a7fÖ'eä †pfoÜpttj>ïì¡ÆªODs btBv¶ø¨”¡‘žAóÆ]PÍ̽m³{YglP© 0#³¹àMTûs»vÜü©5J]sÕ†®Õì—&¸®ZUK[ìãh|"š&ºpÿ»ß¥5q½Ñ™©/ns?–dù¹í-ƒžÅÉvÐÇÑv~.­÷ØVQ•ý®<³§&^©?Í2©¾Mm6Ô'Ю–«®HDŸ§´€´{gcðL: Ÿ…ûâÚJmÌ•Kÿ±ÚÞ¢=® Ä_ÇfÙ÷ªJFåAsÕ}ˆIåìÆït­l¾ ƒ-¯Ep®Œ/ÇÚ ÒMKÙY-­µÐE«Ë_t=Áª9&éqvýn‹ô¸q–iV„ËŸï·¶Õ>kfÛ¼–Pûœ¶Žè¼Æ­ËÚ|U} Zz×GQQÝ”-ËY° H”æYÜÊ‹êÊú¦WžÙ±öÃÕ%]Ÿ÷[³h:ž(júòyx³âZ©Ãkw¿ÚttÜ‹;½ø?¥Öé }i¾CÇyDÓyG�ŠH:‡èÄoI{äêÎ*£XòN! ²KHWHN†îÍÀ" ¦Cü‹"¦…Wð´Ï»5ÇÐõ;Š[I—f„C㮦#(ZòPWË5§.EÞÐ8"ÜZÙXp¨¦ª·ŒD+²…'ÔŸÌ 2ƒØ?(O0–˜"Œ(Äjyúu5ê°2Åý¤ê¤…D‘€,,жðŸÖDÚ.áf ìbV&Ó4µšxÐÔµ2¢39äÁk‡®`„²‹A lt¶>Òc„{D‡GÍÉÇþ‡á3íƒóùg/œc¹­¿sS"ÿ‡3 �í Jxlœcç³q]‹ÏªÍ+£]ŠºVÅÙ|`çÐW;ªðI¡­ú5¼nkÿÀØC>cj„‡†¾*1Ò$sVx•΋xÇö˜}ü†;òªP @nEâ°h3 v¡¹ùy›p/ßýO½_R"–Hqu‰2mÈð'gtul–!¯žë ’ö®1RgO8Âý-$ê)íÝnÄòÏù‹¡>нÆkš‡§cÛÑ£h1ópù’ö‹ã!s|”Ø©ÆÀ¦¸wƒ$€Q§ž‘’^Â:žLæŒQ 2Psì4¼€ç2žÇr‚)P€µ&"s'À„§¬°Ë>®ÛÑyP…„V#.g®ƒV#„»Þê˜;wÁ”ʃ‡uÛMYMqò†Ê0Ì€±ÅL0¸òQÁ8–I2»‚¶'5ń¤͵+53�KZâ6"!YÏ:P·FÂâ3V'ª±ü2Âsþ˜äÞ¼¼ØdÏ ¶Â:Š£ã®`{г‡Õ›"lï>ê¢b|/r(¼ 1ÛÔoPóÉ'O€3ëÝ r,‹õ  šEAâ®]†\œì®­®ƒt™ ˜ªÎÊɧp—Y-;¹ŒZ‹ ¹f ÈnE†bet̳vå…-¯Vï´äH»àN½ú®Ùü#¡ÓAŠ®×$‹Öm’Œ¨§=mʯRuqØ�“^Y„<HÍ’ XÒ>IeËA$$ÍE„ä6b¥½Ý›5VG (*åz˜½;G<ÒØeRÌlÓ›ó¡ŽA‚0É*>`7¼Ùá|Dµ=þ®!ðo ô<½px8q:uÆÿ›Â!Ÿ·6†Bªÿ“>ŠínN}¥F§É½[l ú:>b·™€¥ž¹¸ÁËa}cG5Þ܈ƒ"Jí]¿1ꑞG¥bäªT|O¨UÅí5I›6Êihg“0‘šÅ‚„&ö;àzŽo¯:ÕÆþK\¦€ ®+à5æpbÌ›öýg(œÑânîõœ JÓ?�P‡”ø=¡qð<Ïa‚¢é�dø$pt;é¬+êÏ«‚f:Ô+x£W¡ŽþÉPd,Ø/Ötï§|,%4^a‹0ŒVÉ~Ï¡"þ8VX&º4F'=¯<G`žé> @———F½\DÐ˧­Åûª]>á~<n™»’|éZ¾Ha´*2íSã©Á) {iùs�ÈOË_¾¯Ôé‚psá§J}Ë+_~>›˜ˆî+ÅøN A'ñ„³÷Ü>¯+©Ìýëxø¼-ÛÈæt#GÂmT'd sØ4à%úk9ë©ÂÚºÕJçæµßg!|NDgQ¬šRZ ³÷ûq9‰p+×6)æáõVÖ Ý …h]œËñß%¿{¾5Hž@ÐIÔœxq£ VŒb»›É±0_Ë¿.X¾ú-xΪµooý$’&U�� �IDATóùÖîÑÔ0ÃôõG‘Kj+_@½J¾Øöä3Ñu}(>˳\СQÝÊ–ï=ßïGz¿v×e}6?Ž‹.;½¬Y–Ó§bÎ5Fð\ðõ‹ÚÞ2Ýh"ºªEnR–vâ¬`ß =*,vÉ„÷õ^;e Ôy|Ø?Íhº6Ò·ŒÆ‰[ GÏ[Òa•VåQ'½Y“9r´!Ä6 µ"éÒæpx†±^iC®ÞÓ•  ‰i €aSÓ3‰¤¼”Ò²¿«½8|ð`W–:úú^?uÏ­q-ß÷ëteñ|.mÏäñ*¨E©~^sÝ  j©á…ìè…ÛVH,S ö“¬›oÙΆ)šôÄA«@¿:(ð{ ŸÙÔÛ‚@€Ý\0… YÀà öwÛMGÄ~p;` ³t÷ppク9νJµ ‘[cޱ1öãnÈäGâ|#èßz<^¶ôŽš_ÄxÝà dL;ía|¢¸’â±JÄéhÓ…€uºŸóп§x!y¦ ;õYÚ:¥@€‘ÃSPá<Ûm×›P´)Qà¥ÙvÏ1÷ƒÐÉ™Ùcà"o4ö=M;òJѠp⨈0ï‡cT×rÄϹïuôÅ`yK„º½•yÃvèê 0$˜Õ¦ÏJ°ßd-#XÁˆA¨û†>ù©¿›SWC}ä7{-;ó¤q”c'yœ’Ç•õçOð‘Û,Iaå¢o"êo îÀCÎaÁ1ŒË΀ø4YÓXc¶ƒ®"Ûo%³`âØX 8Îøñ(ÎÀ|)ºÀŒ+Q m÷p\†fíðô(D@ˆ P¬àؔҽ ÖñJÐ+qVáì­)RUF²Ëí4=((G83ˆšf%Æ¥'M&;BÿSÀP8)á£îò8kP¨iô  )@8â.Ø:쌿~ÚÐ;MÞhœö;œ 5ú Á.ú3 ÉV¯]cœ@t‰µdú£x¢¡ÈŠ)€F‰Õü™ßcÌ™÷d\â„-²l‹9ƒØ!j¹6W4«·§ÌÁ‚dÀÙ"Â2Öà1jšÊ r‹‡bêk3 ×ÁÜ¥1¤^îÛãQ%ÄH¾oï);Ä[-8Í,j©û_T†œ­ŒbO�ˆÅç#D@>šC¶h›ç@†-Â…j\¾iâÜ|—ÛÈȾÙ þÜ1D‡ÙãømÄÇd<TthË?'çvRì½pù°üP>~  hð–zº l˜µø®”lƒt=Æ`?Ç>Ÿ9Îj=ª-»}<£¨`øª¢eçûûñm(»à±ò ÌmU“Ç« z*)krLíòøO#a€Tý‡EAÑ„zé 3&ÑÊ(;¼æ„D¤dˆ-‚}F!ÄË@(€«î^ø<Lޏ<$4ÃäÐt%}ËüNøð'[ <Q`œÖ1ÔÖ–%Ñ,c¨ÆÚhìFŠã)Üzö0Q©x6«ºMÉ8ë'ÙïY4ÌŒîd‘JÆ�ÚbÙu¢äh`˜œ¶Ã?Ebµh•“3#·—e5;œ†•„ ¢5ܼÌþH„üPÿ…]mc¼×9E¦”}(P§1 Š0Z^Ðþ<®y¡“ÀFvöüô›¸÷´wͬQ[ÏÆì„“È'óå²–OÀ J¸É¢-8Åå2"-(Ü?Û´€"îc xj”•mÑo&vå§p*©”qFü±¢-Æ»7‰Ûæ£SõC9Òä‡c´7ÉZ‹šÕ> ^(VšN‘C…·Ê¨ëRà¼Õ¹˜ðÚz:väZ—2з0Îþ±PZ]cª êá© \•.êT@´UUüòÊcuU0¬]LÖWr. êrFGi‘µø$õU{¿µW¾Úú@Ñ�ä­÷= ?¡ÎÜ|UHø/h•[»…þ/½œ¤{BùØÕÊÄÜÓFZ8ܤÇÒrÊ"5Þ{&úX£ÕVãÜàÚJ×|’Ä*²nd+[@JT7£…‘òÔ°ÚŠÈQÕl7Ò^Vþ9ªß^|­¨ØkµÞïeÕ­Þ"sC~‹^1>N λ`Ü_õù.Hús‘l.vMb½•t»Dý„¼ÞY±½–+šË‰4Z“ö(åÖ<[7¥Åm®ª97w®åH>Nò*UÙeIn)püÔ\ÜÊu{^ïã™aÿñJôq,VÙܧ‚ƒ—vw€rsnŽqt]‰׿þSÌ}XÈÝV¹Þ¹m#²ì3Ì…ÍÒ¶ù3Rcm6£jtdÙñ£¨gß%ÿÊmô§q`Å‚#6 Þ”ëÝwŒ(† ÂC W@ÈAÓ#˜Ü„–çºNèy§Œ`Û8aÄVð%PÙ¶{}¿ôÉáUÅØÜ[ÀÐg–_!Ë|fÆŒoUå¤PÎ�â8à´Ö( F€„´!z[uÖXj8ÿóÚ ƒ¿J»Uö¥3Jñ•lSã%ĉ–º±Ÿç 5e]TNàÜMm]›œìÔ&e#1Çk Çc׎(¥™ l|Ž5B3¢ÛéKäÝ}6€ð‰åY‰°º h ÈkÁh‚ ö4m· ãÍÉÇt {ú{΄HKH„ˆ dsÀy·{]»ŒÚ8Œµ £ŠJBúÁw#ísýŸŒj@RO–¢ú”w"!·8~”22¼ç3’�nD¯ Çų®ìÂgÐ+& P‘ÎA*=àèéhRÐÝ\¸øaë5j•{™òBÉêgp¿pT@.à”–7ä ô9ƒ#m‘§ê@»gŽÕij…†c®ƒ5Dïë¤MtC¿S7"ß1BÆ+ÑÍ1Þà‹ÿÜ1[_áÍΓ"ḛ́äÊaqÓÑÜ,½ …Ï…CËÆt=…3{\F5ÓmŠ2ôÎZò›£&fwp9Ú>Âò:P¡µ¸ç¾Û@Fǃ"¢„œÙ­0áÓÛT2:vä$6qK€(pÔ<q‹tpÒÃþž%Ô2Z™P:…© ¾>ÁëÙäö?d%e _B¢£0¸ìA·§ž2üOTò¢òe³Å· µØ…¯ãѽ¾9¯ûa{» ƒ­È½pAh Üiay¥¸KƒßÐx¼ß"ö‰°ªÁAØ,:Õ€'Íc°óŽÆwøò¥“0™ïõC{Ÿë�O\Û Ë®_Ä)…tÎô!ú”cu¨ïg™§G…œ4‡äØRÄXßÙV@1’Û؎!òÑîü—Õñ·¶gtf\œE¾k}#¢ì›¾BvyFõŸc›€æ;܇oîõÇŠF,ý7’5Ü»“vä0:ݹΆùùî:¶H%óOêu¢æ®TàñKê„ÂjÀ9Áë¿4£î®o0¨"åj) „9±¤^-¹´¦õì·H'ˆHù”ãÙƒ ÑÀ,jëAÃÃŽ¤ —ÉaFÀðÕêÚʇ4‘2n˜{X,ÅdÁcGk™fÔo·dµ;¸~ƒŽ UÂ@YûRê"ÙüÌ7o¢"˜´ª,Hõ¤ês;d_ØÝ»û¶ J¸³¶¨jwzvÔX€rŒ6÷~û.Šƒa/Â&Àù ëî#„M«AæÀÞ Ô—Ãx¤+ȸé«›T怑œî;ª!(°* ú6EíÚ b¿‚±yŠwO=«3ŒcØÿ¤€ÑB±¦\Ȅ͸5݇]D³4‹Î`•Ã6,wO!Å[dÆ$¼c˨××÷¸•Ç¡Ð>!Å–Ðê%^*·"Û‘/K®V3ŒÏËf-&}L¹˜! <‚†¡ÅÚlÙû1žÝ4r<#ðmÅj™è›…`ü¸® hSd‚F$#€´Íí8Â/õË‹ž9Eú3·ï~'p¤9é%¢q`$[µÙlìŒwŸrv vvHŒ@z~sÜ)ˆ^³j@­Ç[ÖŒÙKÔõxS×\ñ+ßêsE4Ð]ÉxÞ!�h 9ú†¡·AÙÖý d”¡3,è¹\t=¥ DL�… º“ЕŒ¬Ù³v)CÀªEý&#ð+Àž½ø[3]„rÀê˘Ë,…§ñ‚I[¨4ƃ7Uúp›Á¸W–nÒM¡ˆA>„ðäfƒœG°‚<ºßuäŸ#èÄf×±^‹Ú}l!ö¦0iÝDß E(¹ þNH§'Š”›]Žãt `& U'FÆíŒ †2•®ãÜ71@ òÊ®%˜ñ˜gâ¶=C'IÙøâXî9áaø@Ïv(K‘¡»íçØ[99‰qè¥éÖLäèÀ pe ]£`¿§#Áú‘ìœðaä¤G‹ 3ãÁ©jvèðìC»€‚æA æx kÐ<‘r+&r-nogê³T”ß…¼ ꉗoìzÜ3ÈØDôx(PÄzl>6G}¼A”ÚH ‡úo#RR›@•ñ2+ê´ØÎ{¶ÛSTY†FLxÞ‚ä00Æ%g™¥ùˆb3o­Ñ°Tb=Ë{´OÒs�B‹7G pHhpÈh(bPy¥=u¥LnƒŒr„v‹H× ¤²BßÕPʽÇ<5Yar¯ÁÛàa ÃÞ‰ã)Ê`OˆY•8Ô5Ì„œ>ŠÒb2°]©^*°žÈã»MŽPœÓœõÃÚíÑ·RC¼±¢‘àv´`pM{¾Aƒ#"Þãî1L¯x¢æÕÈ m“$°¯+è;9)Øô«ìªq<;d<Âíì¾¹O1g4=üØÛÏ Ä”¿óÙetÀ™×ˆ B…º *Å(Ó7R~Ñõ!Â0nß{ÄSLv­ª>ø<ÛÁÂT:*2ã8Ft4"¼§«¢„]{Cât–§½÷ ›fLAœ]ÁλÞx äpÚÂ9q ’¼û RG€u¾!°ƒê˜ä™Åa Û¤ Ù}LWpïÈf[½‚#÷Þî¥3µÚäo:âlNæÆÁ„ãðŠ],àÇTíGºl8«{ 1˜zʼ°'@]…ïA\Åš¼dÐÛH6Ô<T[×ÛGº'°Ã¶Éþ&"�ŸˆQMMÀÞ›k@r’²õc¥§îÁ`�¥òô@™Ð”ã¸ÿ–››Œa‹L=; OÄÃ%§²¡æ7ÐÓÝ„Î:ŰOtƒduÑ$p]Å1Ùëê2*Úr÷ðV;Ķ5ÀÇK0§z`«Æâ!f4(Aý ¾¼%£œ=!'p4ÞÀ¼;ŽX“ì%n¶û6“€½ôíþË|Ac ¦Rñ(?¯¢@ÂÓªàvôæm?½ êi0 ÖP " ÊJ¥üÀ¾ÑÉ"h‘å³]ÐJá¨ÉÌJýT/ò¥%­N±Òú ±é[$BŸ:ã<U2wV„Vø°«½;‡H ï<bZÙÐãØ÷«Û¥Èb±1Ž©ÝC[ àrÙzf’຅2 =ò©§PšÞÔÍÎÄY5Õý:E^ì4‹¢“Ž~ Û>uºRÚȶ¾1ÙÚ?$Ô ì¬xžtúøÃGjDT9ùf,î¶3htZ Âç§ og ä$ êÙdõTۇРêŒNJŠŒk;x<Ms/Ç ¨’1¹•õ-ƒÌژɪQÍjëg`¥ d ’V¯‘°rÌØ,œñ°‹…9°“ï”Ñìb3,à$�=Û šújv¼å•œÒ7Óˆ.L$&â;Äš6µ‰µú&ª·øŒ$;(M§IÆúc…8Æ ß~dê=êÚ vf 6$”TØÉpê‰â¤^ïçT0 ¼VÃJ4Æsž{÷a‘r±í©¯z£¼•ð¥|ßÀàšð Á°šœ Ån#vsçm$KÈõ@J™Æ “V«XÁ1*Эé•/ 5ÇÒèÔV% ÷“¡» â�!²Ÿtd¤nœ±€†?°íWÛå„Úzv´cJ㥫lvшÈÃgz×e“=d<—Åå ÄÑÍI"gåí¡b‹œx‰îqdáÌqN wI¶Oä‚ñ .}ADøO:Q#’ð+°ï/5b/ùóIU42è2yÜf‰ÙAQþ‰?¸ JÖœ—bz©ºz®®´pˆW4-,µé#Ĺ¯³¡h èÚÉANÂgØñ‡x­¾¶‚â{É¿×ЛÉÔkCåS( ‰P^žØ¦ùh¶á!*_ÊÈ1…òù}Jƒ×€°ÍºUR¨µ©FÖ�“J\åx„iÊÇ &p¡ˆšÜ “Qa‚Ô}¶V¢*)gÆì�JR°vS~UŸ8jM12M…‰¬_™ãXÁ]âR€¶,ŸÍàdý1~l‘›É&"c3€= á{ F|XqÑ–M9\E>ô¼æƒíÏ!ßàx¦fjéM “4A÷’& `Ùæ† ·Q»/¨ˆre$x å`ÏGk¡¨+Aý‚Œ`DÁ+9°š xmÕBº ,[o%Ž b †²³QY M `L·Â FÊ4ˆÖž# ?cÀ§&²Y ¤ ŸØí°‰WgΚ¶ <îóg×>5Ñ4£ÈÍýŸ‡‘›}ß%ãASxq;Ã-hçá×+Œ`>þ@îİžè@ïÌöÓ�pèåc§€SƒÜ`W !‚Ù¢Ý|¶ØAÊõŠ!Ù©>Dwo<…Þ ¼Éæ}?4”r…K´ä0+«kðUr.ìåY`aÎ�’°…½8=i‡Ê&% ùTöoš×Ù a=ƒ "Â: õ#'ÆîIÊÑHx¨2úù"o0^àr%kz;L €ö%Û9´5wûçYçmv äCøcm þöÏŠ:@ƒñØ:q{–6Äá0“~f8²vP‘›¿½àFøÐBBI©u4Z{$;]0U2ªC„˜Í“«„RL X¥ ka7Û×;¦ÝpõR½WuMäÅ=[5ﺂ-"«¨Ká 4‘‘RÂê-D]§¾öÀÃ|¨£yÑç™%�tô¶„PL/|ÌûÝXrPe’ Á´0 Àggà Á þ[²êFôgÏ&$yÕ ¦ðB„¾"w˾Êísékø§½Ó=‰=â>l¹l{bgŸ Õ6üÉ<lÓÈq…¿ ¶¤®ñà WŠËzÕ£þ¨Gö£®œ„Ù%=´¤Iˆ¬10øÙ§€´ç� fîN°8€t²«…;>~â4C¢RØÖ‹Ð•Àº°cQÆáƒL^2ŠÛ“éÇâI*‹N‘´Ø`|ë;†2pÉ.’èÊMX!ŸQIò(FÕf ÕÖÀÖ¯Ä�t<[hF¹ëèE:RœX02:É  Aˆ>ç9®%FæX›³þ|bq·¡”‘B¹¼pŽÚ6ÜAôu*›ÍéÑ8‚+º ýá_ÿ2îF z‰6Äæ’F001µNd¢À'êÊ6”0ÇäG‰Ï=¶)Ü77;·°!‰{,˜Ïb˜¢”š¶93× ByöÍJm¥Ø#!7ÎŒ‹<N:¹Ãª.¢¸Þ è©Eä`DÇ.<èáÎt¿ÿÃö2È0ÑzW8Ð ÞÁ`McªÿH/²“àb<Öò 3ƒô,“2a@`tã²ÍÀM¿÷ùc= «ÚÇ÷Êð>›ƒ3˜vvrÀ~ · ØÁ,<p}6/¨=&÷BÈŽp%-ˆ Br½„T;Ãr9ƒ.”šµEIÂØH4Y£Ô úŽkÃãæÀfxŒþðÔòFe›Š L¡`# Ìÿ3‚rE”pÍ'd[êÙâ ©@y¤»9Gò ìŒÀ ¹§‚4e 6µ0ÆI|ùoÁ—N:MÉÅA‡ 3ÀF œ6“uÿKà |)Í›ÑW¤‰t4 Í> ±þ¦Óº':|Òás{%__ýïá³½þðéžöãá•è¢d^ÿõ™¯. Ì_±ƒ9sÌ{wüÃk(oνÞQy�Ë7.÷Ø\vy#:"‡W:<µ­§0-iGr¸^׫:‡ú[Ë¢+ÑÔþi9�zV· ¼8é³¾–?ïL4ZÌò ÷,îï…èJtn‹¡^ÏåPý¦+^épø£ɫΦ3žÖŸ×ïúý}x*GX¯?–ÒXOßÞå¹d¹JË/§òKh—eÒãUýÓ=MDï7µÂ'¢çõO½ÒŸDñOâ]3ÑD‡W:|Òáu½ÑúÁ¡³:‘åø—ËuODï7"¢—ãrT÷D‡'¢çõ•çò&«X.N]Ëõ§ózïßË麮¹Üúü.êF/·fùÆò½Óú®çõï_7š×XuYWÈýDçõNMârMâúÌå-ËÛ5–Ö„Å=ú8.O¢z×Tþ<nå0f¢¹,¶åKï©\±öÐÍ k·Ü#¿i,÷èÎå-2,/;«ÕrÏDïßNm_ú~+7ñu}¢Í Êæð½¡Üu˲<\粨Úzû8ÒûwùðOñÉS[Ì£<ÚMt;4eà=�K¿„±…F˜ úê7»`uny˜#ìlKB àÈaÿ)ô,À;á`¾-•¨h¿¯KÈXË ‰¾¨T1ý¥N«'jaáª×tóö˜Ð#MÀ8:((áü™´f‡Gj ¶ÜáÁànðý ú³`þ³oW0ûɳe…jܨ÷6»6Û†ÊOPU*-åxª”R1vàu!3ðÏ‹GTÔCF{štyÎÎx{t�MJÀ÷h\%Û„{Ïœwò±¡w‘R4úš eÜÆõ{(|ìÃVïkcvV¬rÌÎÛovm¯ÚÔK6ãÓOh�Ö±‘tç¢gRî`$ÕÊN¼gmî)ÀaVn­@刑þ, ö%[Ýòn)©'~úõÆ 3£¾JRí5Š¿øR‚¦$9XoÜhR ϽØ@“æœzåº ô:©lF3åÆ9ðÉÍ|.[šQ/<÷åü‰p·°‡TýjÉO èŠ9AÁO9dÜlÔ¸†c811½PÔY챌(zŒx²ßÜÆ ö!m»Æ6{ý;:R-_MŒ›…mßÜ­yÉ�-:r~Î6{¼ÌÊ6c @m]R'96 ˆŒÀ�eŽë9vzŒÙµ†ÌF}ÑR—Bv0Òw¦;Ô1oëT–†7ÍÁ¬‹·€y ¬[(¸N{hêÈnX’ccO¤kó†Œ9Ýønæ–ì8ä ¢"! •Ýa]b1G°èOðENÞײ¹3† bNn$ßÅøjaÆT²`i2Ÿ2~TöŒ§(·�Nã9ÀÀ7±tÄ:ü³þ/ÿÅ¿ú7ÿé¿üÏÿý¿þÇ?ýÇÿý¯ýk{Hf×0Þ:á—ßËV¦Ùò½K{}éušUBfQ¹ôRq x äÈ€&ÿËÍ/Š.‘ù„ÎËú—qó+6ëÅÚ¯¯çý/Mm©”÷>«¡£º¬^¼Üe9ã:ÿúem”¦ü´Ÿ‰~é÷­iîYŒ+’š÷Ôa€Õ\×á‹ÔiJp:jž1ésY»Í–OÎj’Ô.¦^çíLõÀ©|Èýx8ÜÊANm„YŽä¬çg³˜uÍà^È+Ó.×Dôr<nê É^IuyÅP×áåH_7ùOõ‚›/Å,®¶8f¹Ú둫玉žéð¤F•fi•¯`5’Ǭ֛¾;í/Ë·ëaªúWqGäCQÎnνé÷­\‡å†.'þ±^.ywÎjS·rZæZn™9Ù¶öÜ¢²WÏŒäÍóx?ÒûÍ\.œ(—Áa{q›#_ïW»>no¿ßïÿúßþ»øþÉýÏÿá?þ{ÞðÇÂHkÆH¼>öi¤«ÿ·#î;^[lÔ[iÑ0>yÚUƒnÂÖaµTì[©î/BÓÅÈ”™ çÉë>@­å…uYLÈ'BÂÕt·­ƒ5˜.öïk[^÷=…¨<ܦÎjÀ•¼D=/L€ ¹Iyw‘ôWdðÀ;$é¼A¹fáÝGHðã(«’åié 4£Lå«¢Èh ¢ÀÛ!,ƒ*ŸÉxø1Z{)œUËûâ™Uörå › ë<U‰} §V¦àZëÇùf؇ÄhVÂíÀ(¼UåW/ Æx4*lÚÒã,¡( ‹M ÎÆb…ƒwŠyH{Ë,;CÖT¨ÁCD=M@oÒ0‰”Dtè3ɪ³‡#®Pú–u E„É.ÞDØ ÚQ«Üq8”bò=gȯÄ,³_ô•ßoš¸ÿ™FàHqìwœAªWWì‰ÜëÂÙaFJŒŒ!ZXû*£1¡×qÈáó•;|Æ/iÔD=Ë ¤"°£Z_D$ÓY¶FNÊËê'ì´à·ðsäŠ}t{5.ÿµÂÖ´˜.í7¾c p̯a;Å”Ï\nsµõßO¤6¦¡Ð(osùöŒº:Ô;‰põ½/xîþŒìg¾ÚÆ üdƒÝW˜æŸ Nm%ü{iìÈŽÙ‚f.øàºHfÄ_ð¾ú—ÕÕÖÕìÆ×méì-xÙò‚¥­ñqloYþþu[Ú r¡¶+vYáËuÑ >ûJ‡O¢÷ïvÌ_·²,'}ý§ÒlÜd>-]µ‚ö&<Qo‹€òWŠÂý~¤i%�PD—Ü'Ñeîß*¨½± &}óz 'ýTž°[®Cµ~jÿMö”¦òµçÙ*Âõ ODݳm]VÖ„éøQÅâ3]å�Î冖3ײ¾ ±;ÎⱚÅ#ó*¸ Ïmõ–S~Õë3«ÆliÐ-7èâŽÍ Æ*È{Vµ ÊY¼R]·íº½¶V³Ù~ÕvêùóÊ*™Õ^öVø�� �IDATþ\î”iæ_Zx(ûÃË©,¿OuÝj ±´ g½®¶Éúø”ûòq¤c9že™}ÝÚœÄS :ŸË‘´ÃžAúâ"ÖlC‘¯ Úúx”Q.Ù¬ÞÕº˜°×1¬²àÈG®0ˆÈ0»žü:ɧ¤®p.õŠƒ™<÷Á"² HüIù‹¼ŸX&SžJéh2•ej6Š1Æ*-Xzëõ \²*E0šõ™>¯ŸðQò²¶ -ßþuk{ßûMÎBÔ8Úþ¾<’eÒØ*³Øô–afKËÃ\F¯klþ(l¤²Õò#Ÿ×ÉÁ¥õ÷Ë…z-PÇ2¸6–OZcžä¾LqA?‰äz<¡× ,±æ³W“ž.gT óºw°xÏe ´Uñ¼®§vmË?]ÔáyÄM{&=ê¸"’éEÕî6˜D*ð$VÂÇ[}½j^‘ ÖUoë÷·åQÚè =hçûëXÂÉ“êj¶!+‹°ÜµÏ"'~Éߤ¶ø²§6ï,Ÿ0µqWÍä–þ¤ *µ½®Ñ…Ö¤í¢wÔ©ÅøöøŸ×éãe]]O¶}8Ü–´¯¬çK ?-š\nt±­ùËöÓŸcõKHJí»†=ñÏOzwƒ#«q‘õŽØÚ^Ë«Î`l“×eÌh?¶{eÔô«cáÅ4Mj´ÌÁ+ShÙ±²´DÀθ}ªÉŽe·±  +³”Ñ0 ©£6!Ÿ®&$Ͼsx.Xw*­Ä,C òTÄEÂŒÀĦLª‡DÕIšüR ³ g; ¦8p|•…HJ¢Yp¼¤:lR…/j”!I' \ãÕÏ‹~yž†WgN@ÈQÂâ£ít_³]?pâ‹/ò.•¦ÍÿxúÓÃÙ¡*6ök$ýÀ‘÷Eþø,eö§Z;b&Yl¿#µM·×SdA”ƒ O­9À‘s(n:õDâœ=A?\î^¥€æÃTNä4–=•t©d» ømÝ>Ñ$”€”ðÔDÌÒOä�åD]½GäˆwÀÌäã*äõ`/ly²¾r²ðtêa ù†XgÑ 49žÊvØlO²¼Xcùyø°%èŒÒq¨ÈŒÔ�Œ9¤ !A²‹öÈŠû©;QoÚ<R½íb2Eõ\?�Gî5Ôõí:žÀt¾l›SÌø7l§Ú²÷È‘�£ÞØÂ2P ñ,a¥g²Þ;¬FLjÈ8¬’½â; oè+ªÌ4»pÇ]n(þ¢U“rˆÉ@q#£‡ î¹ÖZ,IŒ¶öê‘Ú·OzîoÛ57> àQ]­p�Þ! QÌ‹o [¯gQ Aœ‹‡ê«íKÕ!œE¬Ó‘b »êŸª2.†«ûã€Á¾%Ó˜æið¾Ä:zÁ>aÔsQX94íˆUô(i·/Š1XôDÇß·Jêtú„ù]çaÇ[,…À³çq±¶©L{•—ùfì3­4Còm+00_ÊØ‹ŸƒŠŠ±ÔèË­’HQ[„¿p´Â¢N¬ÇËA#fK‹ú¢D¡Lp¹#uÓϱ¢±Ó[¹‡ƒC,x×7º€j€pUƪó%k¡ ƒš‰ÈUcŒÂòø¶Õ’†‡ךÀ"5‚ËÙ}¬ÆÖ‡Mõ½ëÆàHûn½ýè¤j³Ìê|E%š˜pÏÓzp&7‚¶ï˜¹DV^?ìƒ(9 h¹Ñ0*h2V¼¦5›ER¼ŒAõ Üx Qvl¨8Þ¤²Ç%ìnIê ãÑK¸qàìì¼ZüËÌæ^ãªa¸ lpe-ãÍa+"’T™«SÍ÷*SÈz¹effºcH0`'çÄLãˆÀ¨ V™¦è½/•ºëÒJZ Âñ0BŠ&œë¨å!SOc'$ìaU«€Çº‚á,aÀ}Ò6wLÆḋUÔð“¹Z_Sj#kˆÓOxp³; Ó#‰EÏò*0‹‚ýŸ~i;fx6mð ÏT•3!vŽõp2Ü/r`�‘¶ó Úèõ™¡«=7š-nÔ$T¼2’½aà^h.©oF0ƒÞ¾õjò=Ûĉ˜If[Ç`nlžÛ!¬§3Faõœìqë,SèçËö•°aÚïpð#Ó2í/ã{¦`²ú~Y$ Y{´šd�D¨lâ ÞàŠ¹d1~‚ ëŽFtÉ­ƒm±¯ŸÂõ8áÿÿ:6½‹B}„M™`ÙÇ�ÂNlëte÷bXz>Üf\„ìM£=px=µÀà´é‹¼‹@ï(K)ØSX>æ¸â¨}q4-‘è!ÇE$ÃDþÍt‡lo*¹˜ÄT{5jVõk¡øØ–à°íì Œ¸L6M‘qsŽk#ß¶ÊÒ숳CSW/&´Œò [_£g z ¤â³+¤2ÒŲ̂(÷³±ÀSh‰¼8²ÒTx€³Ïº¹ÇXá>তۼzT¼å5¢wgÔ‘òq»¢`¥.5^”öbÙŒ[‘¼üøQ¬¬ûuÊZz«²ÿ­AxY a&lD\5^_þÒ=Ð,o?»ë°H¢Mëìáý¶P…÷eeƒo€;«Ü°vYµÓzË&Eº<|½‰þ›º­ ?ñãØhÅ«QÓR£Æ“-$’*wø.$!=cSŽPÇê?TɪdÈ–/}/”çr•Ìb[Iµ•@*ia" 8Õ­öðJôõÈØîGu$¯å?LÑ;·—µu5­ÖVõv¬a¦1Æ*Ÿ7k#¨å¿níìfqÍ?‰ž iéðD4½%)µðйJRÁ*Gm!TU%CÕobt•ÙsùDô±r-ÞoÒòªm#Â爵]¡lÏj'„e G(eK¦}žŠ^ý®ÆI¿h¢ç¥Xyݹ¼¥òÆÚr}Ögqù,–Ù×­Ýq ê|ÒáðMçÂö+öË2ÿî¼’Ó?Þ*Z*�¬ukÿôrôVa@°<Û¶¶.§vy_Kü�q/˜÷Oz+U1„s_-µO›B=Ùh�æi³ Éݬ6`b¯>áþ]}fqu”$hyÑ$ñÞÜÅ]ó'Õ†N|%'–ë6‰?W>é„R˜†$»*—è¥Tn7›÷nmû»TI‹S *¹Ñi›œÁu%ÏëS½ü¼+?¿7g ÓVãòüO‚Ýù~£_'©ŽZé´•I*Õ1Š2¯¹û³ƒ2MMD@½rјˆ~ßjø—«Ë>"yÇ­¤[ìãX‚ÊBm¾ÒèëšÔËõql&~µ¶Ûv\©ÇÑË[as¿ª€]e[˲‘’»‡[‰”BÊ¡1‘QCU­óy=ìÔÄ”î*£PŽsq}ÿn⣊whÑhÙ|Vh~ÝÄ[€¯R/g¡x[ÃsÚ(—èŒ6R&º®ápZðYŶ’yT­‡c“öxœtÒëç~,¾£+±½Æ•vŸ]±ÁJ.Ù ‡Ï Ñû ºüœUüSËÕ{HÎÚ‘\„Íì¨ô„å§±JÓfEÒÔ­RL9 '÷ôÆJNF©Aúðz‘k%Ì8èÕ Üoa›™¯t1~r7ìs»àƒÁÃm2 Ù¤võƒÓ.÷¶¾®QyvOಾ´� Wy«T–lÉå'Q#ÖMç¼~Ȭ@9ñEŽú뛞…&÷á»ìMÇò §5§~¿µâæ÷M>Uö©”û³2‡-ËïY¸¦Îí>|}}›æY'ò¼Šnͤ»[ÚÖ¶Õ‘Ò¡øUíDÊ8øU¤É³*˜ªpTݾ‡[yï×M•>UB麞׵˜M‘ ­†P¢ÂÜj‚Ã+Ñû>9“"Im㛄¸Ãsð®—¨ÕX³Ën'·ä²NZÞ󬚊mï»”õÖ ÷¤Xªñ¢ê¾‹HDR›lùöZØå5¢$¥èÑJóy½“ˆÍÇjʵÖâ ’ðñ&ÒáiuÎkµª/W“e9ÜjNÓVݹEÙòÆ©}¸ÔZJùåÖH‘#©uø$zÿ£TáUËC ÿK!©üTo™ÊÑYøz³~ 75zÆİ“N±„„Ÿ[îªl"2ͦ-}4<ƒì×>h"•ÀQ*õŽ íú#´mxE=îòaPb¾SÐÿ¼5´f…| îŒ=sÕ� °ñ4è ?¥£ÀsÙÿ=ZÝÂÐðÏW2 ¢l…#ÅuèMƒQăIF,œhdhH‹Fг°åžm7�²ó°È3Ó£±h€:#ÚÜüD’ Éx2xü14†ÓÀNÑæŽà2Øl2²ß²[´µÑCÐÀ,Ü48sA¥Ï‘ èQäÅ8޺ߗDÚ¬6¡›Ò‹¼Ó±ËL$rŒ¦ª¾<ÙA¸<¬O½áUòðê “(/»²µª&-1àçÃÃðqãìÇ¡ãpvaFãèèçy˜´"]Dj¶°É„6AFìœÜ£Xa�[ O÷Œ±(«“äcÑùžÆ+a–ÎÓƒA"#f`Ù‡ Kee#c˜W©;”Í8´Èˆü@ÂÚ€5vÃ)»q} Ò >qv2ÄÇרˆ<Œ6ämPܨaìº=ÿ:Q-Ã>‚WÜ]"NÑÆêÜ{`¡j_ K%ÿ ÁLvÞHÐÏ®ì�WÖÓ‰aäÐü5`º ¸>Ù:iYMìä|² þÖãÐ’QÆà‰S‘ÞArÞWɳŒäŒ~Ó‡¼:.OPjkË�ÒЛ Mõ·½`Ð"$¾É*oËXÓÒ§ 'ß.Ô¶°–D $¯а Þ"}õl#YF ?OŽÔLÌßïo$l�ÉÉ`©Óc bˆoIE!j;v&ÓFpoŶÝl DÃÆö®xÜéL>VàîF°Îcí(лÓ$ž(Áµ2ÔÛíð‚Í/ õ„Áþ%½ûÌfJ„´æË³>3bþ ƒˆµÝˆ‚ì5#e&íƒN†Ö“±#«-Y¸+ËÛe“aô›rÖáŒN®¨2`©ã%‘QŸ¾Up²¶¾vôXE²ö‘btéX¯ºÀÍ«?«S`ÁŠËpz"¶Ï6û!Ít´Ù€q­Ìh1À&UyΡYëÐF¬~ᵿ~¾_o†˜GÛ÷Ý"oÔ(>Ò¾„&ŽTв ò¥¾þ`õä®—nŠ;œ¬vP$åXëH¤`jTÆn'bì7’Sùä»" wórÜþÊhÔ!b¸D3,\~PQTQŒ Ü@¿�´†|+2>Æ©gØÔ\Rv!’ýV_$bi·kær¤c�'CªfB„6ÐÃÌ!/ÓtÕ)|BÕÈ ±i¢xÔû±f¤¬ÿ¸¿Š[¦°Ñ#MQÛfðÓ\!Ýy1÷•pÿf<l¾À§i.‚ò1ìà.ÜŽ50éCãL.`øRÒ¥I§GslàÈg÷™qPô Ç€Ÿår}*2€7÷ªðÅŸø–UèZA"‰Ù@áÍ2—I™yVÒûmÁ ÈÓ\@Õ]vÕ¦I Q¿n ”¶¬ãkƒ-PÃ4¼€ ¥™2»fl‹·V…3-ï*@OÖ¡´Ý©ëŠUãæGWý<¹aHØE5š<€³ðÎ+”++”Z{ˆÎ`b_@VÏ‹™^1Û¤jùÙðŠÓ[‘èò<45Ÿ°Bš˜»¾æåXï%= Ô⤟‚·~ØBà{¢Ã¡ÝC4l~DôûV.ã¤ØfÕ’­ÜÙÁ_=$±iVP#H=­ˆ¤Ñ¡¤€m »Þ¬å¿Êš–˜Oea—¿Ô'÷¢v¹¶iÛ¹|ŸÛ•,^n~x9 ÓÈ߷¬²ÖÛ˜ÕƒF/§å] ìþÎD/oÖŒíבÎå^«[C…ˆÖîõÔÎe¹ém“¨ÈÙÁ'€$/Ëã¼…jèAõë-»}®Z`îq%øŽ]•ß ôûO€kÕÇnt ßíoÌèærˆpñ üèCž.ªˆlQ¥ð`‘€Þ¼/­l¹ct»Xª2Ë]’µnl!àÁîÆgr(Þ_1o­ø¨Üdè:–« ¶åf´DíDjZd4óç …›°—èŠGÃNg¤¢|ôœAµº»ªÉVå ¤R3ø· :Æ@«7ţʌ|CùQegøŸ8%ýç´qÁÅ ã¶7“¬J¶Ò*áRÀ+rè#Æ•mÇ÷ô¨· „Ý€ó¡0:À‡‡Uä®Ò7RÙÔÅÂß#9l�â!‡ñ"€m<»Ofô$$ìÔeºü°¡­�‘ìIv£xÈçÐ� Šî�m¦YÜoÀn¤1m Ö ´� {ÉFe<lCÒéäí"}0` $+ch?vw{ß3€°Ú>°JO=+Nh˜ Å8èË€dfc13„¼ï¥iôåU7c™G‚•À‚µÁ‘cklzoIÖ*PŒæ>i,buìEB®=B´#Á&âßDpÒ‘ ÒGÀw„Ñ‘G±'ãfcCQ3ò^ú ˨Jsˆ)ˆ~‘ç/¬l™Nuî]Ôû¶›©Û)àlÉ>ùl�܆ÕÓÉUªì[3ä PI'BŠyN‘Ùî’Q&ÀumÇlét!Ž®ô)€c¼?8ðÎȽ$ÃÞ ËNÛ¸ªh‚¥\ƒM."s³ú 1Q�ŸuÛZ |ƒA98ú„Z¨)àf¥>ŠQ=öø#eòº½ %BÃQ†˜cÍNcÉÜÎÙÎršœ`—<kÔgÞ+>¼ªñ›ju”Rz¸lçI–S= ¾ªÒfµ£Œ©Èé*Áƒ—²02É+cĨäÿª 8k)Wû®]‚åçý¦æâÔÚ *n–å›Wòg«<b…_ÛÔvLbXr.¶1óh…/BM=t\5Ù _GDûâ©ÍÌê|L¡·¢M@MFHýœ‹(Üáð‡µ–¹Î¤æJW*%>›¸CQ"X®Þ×­ÌÜFS$„yšÚÐïì³RªU‘hQ)r;×€í° ,_Ëå’Û~–Ÿ×û»üëá¦$:Ÿ× n'u‰¤2žOŇïr[Ÿƒ—qÓŸS 8W½nßoRö¢d°GUe–ªg¶Œý–¹ÑYètȽh¹PåayVãLôþ]O°Mòª×ï[•%l*‡}麪k¾‚þrmí8ÿ¬ç‹ëY·9úÜ™¦÷ñTn\U·Z‚(, lѬyám™jÏø¹s,°†ÚËm¶G8¿›}È‘·ŒãâFxƒÖx3û³«‚³²E-2NÃ{”Oîö9´À•b Øìœ¶5¾–¹<8»¹•MÎjbnø.äý“Zˆ»¬~™U‚L³ÂØ>rC¦ˆ©ÆÈ‚™ÕŒ³³ËPçÍß †“6朂ÑEÎRŒÊ<1ÎôÐr·™åò¦3fÆ~Ñ5†&ÉÁkû”2(H/­�2`« Ñç£A ` &dO#k²ìºY£Ï½Ç¦³Á#Ò†ˆ¿¬\»d¹‰”‘÷IMnÿðÜ´_rùWFoQGçѶîƒIíM¥>6mX00�ðÒ$®Âq±fk¬W] ~nÔjµâÃUÐ2)örjRîç¶Ôоâ Ò…æšíyU8Pˆ•ªrƒíQ _PyK¾\Žçi•ý–àÒgQdL­µÒPm©Mù”ˆ>Ž«ï7½ «–bÕ׎ êL*„VY2eRÜ3(Ý¿Ï&ÔM/' "-è¯Ëª–ûÙJÒòßš—x¶W¸öÚ‘¯x¶ei¯¤oKør$g>p8Üè½”•UïxAi¶<„cE½ uùIðÞojñ?}ÝÔÎ{UkÞê¯Uô‘“ÞCž„Ò †±y]Ó¢Â\ÛBOêh—ZAIJžÅ:œÅ‹«ü¼Dþ¾žJ™nÌs©¨ÌNÒä —%ýñf³ØË*y¼",n-Û#_—è¥õ –kی޿ÛCT+NY}žÅÓt%úº)„Yo’¿•™@ƒn`yhz$ m/ÿlBÇ‹†MœÞˆ "Ô†Ù<þqG±ŽSÇ^ëèÊæÀo³Ì STÞòbÎxœæsy9Q'(åë¸0ŘU[¥PêÂÎ!м‚,]Tze¹tðW¼›sƲOà8`³e=bÖæ)ð†ìæ¢=É« êp¾Ô½²b<œÃ�™xéáˆìà§õÐM'(­¢ŠÇ6Ž÷æ‰ÃHÔ# IU§’5?R—î§bÏÈê'Ù¡ZUÖ%)‚_¡ÊlŒ%S#g®ÍnªÚxÂ*È@ŠJþV®\^>mŠ gy.&QêMÉŠÇŸ…9 8³ÎÈ>{åœ?E߲цeW5~îh-~ š Vȼù¸&UM'kêªzÇJÚ[B”•¾I;3©)Úd'”ªØšÄ9¾Š'|²ðÜ–Ø> Î + smÐUÞ(‡:—UD|nu ½œÊ}Ý Áë¹Ð›šÓ aoaÈÔ˜7çÂ+*¡HÆ—*ªèy×DõÒjÙæ×uY?5Åúò,<Y§7úúVÕ�Y«ŽòQ*C-Ü8¹À^ŽK*ݪ‡³xšžÚ’hæº]±PÐhZõãM­?ƒý¡ù6MnK¹èüàã¨Òüój!6)‹&UPµ¿Ž‡Ã·ª¨&ûÕ§=ª'åøëÔÚW‹ƒÉG+sÛtjfZ+ñðZJ:+-ÿëTÞrè'uÇŸE·vå}ÿ¦¯ï:®k€†—£ÙgÔ.½.oeúó~“CÖÅu¡9‘‚ÀÂÃF,9ÓS†@š{Ûøcã •äžAgÌìÔ°†3[­1õ1ð :Û|_Ñ\ëhgߤh=yú—0T{7øÕ›2Ð0C¢±jõ/PЕҢù®K¹}¾ð(²ÊJ�,+êp“K™Þ¿+ÞÑý$[1wnF{ûT:]Òê¢]ê«êÒø%T7޲_¬¯/}i›“[À—çõ,zžK+éãDÏkÕr-[´`P‹ó ½ìž×`ü¼’¯+ûÕø8äÖÇSöƒ“Ã, ÄG¹°Õ¦ôý„‹èuŸmœÎÍÁÄÐðÛ}¿I³Ä% ­‡¹•Ë!©½(ó@ûʑĹY¥ÈýTB·Ê"Ybí×MnÙ%þ´T©VÇŘj±Ð¬†–ÀÉï÷M¦¹ ˆ‘Z¯¯f!*Q›Âëð]ò˜§•¥^ŸÄ¬vóŰ­ôºïÇrãôí+÷úý[%7TTþj\l äKË8ÛºJ$Ûàôrþ«u….Ÿ³0š¿Ö|E{à\6‰QvnÎ"ëDSˆLk#Ÿ' ·“~}TíUê‘ùó|Òqh˧ØC -þ j=LvÈ4beÆÛq™ ÕÂáÌÕ’š±µ]ïU¹Ñ¨ü‹V­nʦ«'|Ò{&B»õ‚VŤÍâðÎEF¡md×5Zª9§ù8–•úD÷û©ö»›·S·²daŸß¥²|×'ÝÓ­ê\³ÝDOµ%çr ôr<¼¶Nz'ÔɵWJ¹“"Ÿ¡a¥Õ¿•>urðÙs3Òý\q€ù›~ý…¾þ¾n ŃqÍ4Ëîül.Ô“u ÖçEì¶l«"é<©‚‰èý»nI¥ì;ÜÊ5?·£*M•f¸Š¯¨^Gúö•Kýq¼“À1^€Ê Ñg“̨1ø^oÙ§7YwdsqŸt?—³¸“ö½<‹©ØyÍîÏ"¸¬Ç|±^K‹Ÿ×aä×Í\„’=­÷}mNܧ›²FœÄ(kuž+ Òs9æö”-ór¼§›lOë³–×u»Ä¶¥äý}[ŠÑ¶®&¥”Q¶a¯´khžŽ¹íNm‘Ï-­È5)ÀíT–Dk¬ÞxwOëËéž¾Mé,-»âÖ^éþ±…¤¾…`àÊM7Å ÇWôD¤Š;RšôwƒŸ0b¹2‚!„C8.ù̾xöfÄê ú(P. ®x‘³´€úuiƒà%™L�€µÔ²¢gFÓPÁ:mèp—§ÅÚŠ‘8:TÐð~+n¤&sú»—3ªêÆÂO­Ôzd/ujæ%øÓ‘U=ŽÏS'ŒÈR˜U7ž±Á•�ã¶¥|Ô8çè}ËüìL£¥6qF®†¼"@]‚îÐÒÈ>ÈYó3àçYrXäåÆvÁc!üŽË [³T(Ðnÿ›~AQ‚¦;g$æZÃ$P 4“7Kö#«Zœv¦_Qc 6Ð|™µ ‹ð½Ê:3 (kõ†˜Ò¾‚Õ@Q•eLBþ"ðäöÏÔúcê>žÝÊëFJåCIÀ"c2+»=WqjuŽõq2ãúââú©Æ(U½ƒåcg¢_Ç:ï‘æëª)œ[Kÿ“ðà¤ÊZZ,)wYë†_GÛ9¨Çÿq”êmmôøäsBy7G<|®3B¹0®ª7U*óɉ÷)ZˆW±ÝÌë‡×Þ×Ó*çø~37bɾ«uoÙÏëˆkjG(w€JTj×6i”cmjårO[W–œŠàEÝ8é×Ü6¨imájw麤\s¾*ÂV[6S3¶·ÛÔ{yc›wN*´”ä .]J¨–4Lzꦛ÷û©>Œ5 Ôéo…–VçS«ò[ÃmÓ„ky}9¤º°?þ"'D¥¼›õ:¤ÕpñJ í™mÒ­­-©Öy+ø´ì'¿ì�7ÿ$ÈûÇë<¢ÝúôÛŠZT•nž×¬P'ß{$w„MR ½fDcY)²ÏÎÇAjùd¼rl=ä5Ñ3ª; å~ò…ñÇ~�� �IDATÉ8Å o–L³êk’Œx3É•¹ÄúZ­/Œ ÍAJ"E.áP …dCBºþ)4;µt4Æ7Ø,Ð*´HÎf"U0 `Ȉè;°eQu˜÷†fô^®”&–Æ Ô75¼®ŠÒžxƒhÉö`Jû+_©"R¶{ÇÎuÛƒ­¿¾¡û& xÐŒª¯ÔªË´Ï:ftQ+¯SÄÀ¦YÔ| =ÿÍau݇³„^_Qò(¹'èûT›mFÐldÐúÂož×œAûKå sTí¼äŽ`PÅ"ÖšpÖ:„HŽ(†Ôç€pšB+K",a×öDág¯B]t%•ÈÉ8ûQǃXi2T#h)‚³}¢ÁuÄÛŒr¸>Ù¥AïÑ2нþgO'@P¶R^])ÙäÁúÙCwFþdËʺt—\ÝŠáåÂlYÜwDi'Çï¶Ù¡á„$g›É¡Núâ½ÅÐ ÕiWѶ9¸ú³ê¿ÁÊ£ß-üð%Æ«ïƒD”™¦Qíǰêæa0ή•¨'D¡!öP}ÎÈxK' Ÿßßd=)e$b׌Rìû¡å£/U9–¸MÖQ‰:J€„:áqNïå9j‰zc-ÞÒsvô© \¡+Íý53KŠÅˆõ¿ÀuZa†™szÿ ÔcÕea=ã®|Ÿ“ó�fT÷¿“0~¤çÙN€ˆMºK2²¾„ý’pº¬È—G?À¦@}{¨Æêã:EÕHÿªWRpo¿Ž‚åæç÷UÌØ@Û�t8Nbd×ÇAøK´]_òƒ:*˜¬û_êysD}3˜c†æ{Œµ‚ì°šçòÀvÄ÷="hƒÝ€2hÐÉ ×žl¤`yÏ'ôíH³ Ÿ2À†`‹�°àoí£æ hKÁÖ//WmeµsÁUDêéô]¬…1”üg�WªN‹sp¿">,4>f 9sïE`3 ”Ú• 6*aŸ³CX&çQ¶IÚ6¦œl‘6,lÔU} b#÷FvÉŽ°7ÑŽ&Ø<Ï» †½]_´ûaxWõ)݃ò푱KFmnFI.o\%èõ@ZƒNõŒ¾µ"3åšlM (׆­j ‹®YÔI‚ÉPF}H€Ê mé1Ö"áÙ‰G$Ê è± „QKS;¸ã¢ÙÃÞŒ”œëB‡-cZ œ¢r`d‚ÚÞô㺵{f (~î˜ð5´Åk¢ç8Ëx9YŒ÷BBÇϨ¼Ž Ô¸INÐÄ·y R4o콑ñvWpoM0·úžô4`ïä+Ê •#Æ-ìºvýò±h7M27Pi÷u~|š%]DW½3Ý-/ƪHËÀ2›z OœNˆ ŒîÏHŒä’ª5sºÈ»E2£DÀ¥bô;ÞÖxÓñE#çÀ`Ž…K½ÉWÔ6ÜS<Þ÷bT¦Ð@vF½Êɤ”G¦hu`‚ò`0+(`é`< £¬"ƒˆB†™1&_´Ö!°þ“wZÛȯXÚãŒ:"­"<Ihò7¹i­ ÃwA2àø½š¶ý± ¥Lª2’×÷á÷Â]2ƒýôUäÇ¥åG¾ePê~| ׿ÐUoð8}' ´þr¯-,Ÿ.Œðì/ž OJÖ§„¨ì ÚÍÈ·ïðཛª=Z´M-¨«=œr&¤êÍ8ñ—Ë.üÝ¡ÀßVJªo¶kÂÝ–ñIák%Q ÉæïÑ(ÞÏÞ,ÎÅ[7%`9¨wÃc4L#×ïíÅ-Æ.½°M ’'Æ‚ú~þ·ý§B$›`P[vócãgH[$çñ¨³¢¿�ðKRý•…Œð±(°­2/ jDkù”Ú3,++Be8=óh€ä'˜›G·WÓ0âòóí‹9œNùo)r,h�W 8ø{dŽÓªÎÎçÎå^4õ„sû§Êª‰´ê‹xÝ“¾’“}!Û•W^Ö+ö$¼š®b-ÍD_ßô~kLšºõ\šò^Qm˜ —¨i ’Z¿Š5s±ü6¥.ÿñ¦Š&}mÉêJ¸9Óáp+²âI $¶Ë;­ @õç²2“ä'Oz4©Š­’±¬PËêhUÉgêfÁ:+g¦vvW‡oœ,âCÊ>I™Gª’Z³†ÿº-&^BÒð¦6©²˜›êcyÁý¸ÈäËKq¿Ÿè²ÒÅÂßËi‘ûª ¼;7ÍøF¨ª®]~ýW±«s[-Õ¬]íi• L@»®IHˆ…WϽʠ”óúÔöQF1粊4^4ñ1 B˜Ùo?N÷û‘~ߪ�JÑl\Nêå­:,¼7µ¯Ç¶jU^£äNÕ»_,èÎjÅÒ×ÍhhÝÑûßK5"kåñZ´©ÂŸ¨+Ø×*A t ðQ’Hæ¼pºEìAlÞ¶Å0Ò·êæàRìÁ©oz‰V®ƒeV,n•ÂÙá �eýˆˆd‘ïW×6… ô" ÐbxˆQm—º:Üá–må¸}×eÿvüRuCŽEå}Â.¤²}›«3TÆ^ŠG,Á^p1¦ÁèJ:Õ¾«ó¤*T9Ï'>[öë¼i™ÇFÅ2ð‹PD¸§^ƒ v‰¤å¥ïɪ~#˜RbjÚ†Ø\ØŽKVõ1Àz@/:ר�ÙYS»¶ùXAˆÚ”\Ú}õp†â‰º²)öáA ¢6°‡³«©¸y%û`÷?q‚ÕvŠ ³f`BfÚ ÂÉêwùR˜bõ/¸r0Ü@Ô2n)ãñCv5ÆÃd"¥¼õƒßÊýH/z(Œ‡!8~ ذ¸„‰ubGnhœIfÄ1`ÌÂÉG ˆJlÇŸ"+:ÁÖ™Ï ì¶ËèF°Û@A¿ëÔã -«¬§Yñár>3HV¯Àvô˜™º^ìö×jÇØŒG6ÖðÞŸEßÕ7±)`Kªƒ‰X‡öÏÿå¿øWÿæ?ý—ÿù¿ÿ×ÿø§ÿø¿ÿõ¯5iR…š³þ• äq±2:7ÏØ1+ÂPX6a¤ »Ù”ƒíÇAaÙ¦ÇzÁí‚λ:ŠSùŽÇ㎮àYI·> )™.)ÅÛ^3‹¦ÇËi`­�ṡ5VÓškªçæþ^Z%sûS~QΫüëÕvÛ¼ÃzE€œ ÍDoôþ‡é—¯à&Ô+{­’²Ðl…RÅU$´½1 Ø}}ËÜïÂãc^™¥±s?.]¸v�SS:®FïJ‹kZû<ÂÒXÑ s“úr‘˜æ¹”ëõ· }õºfª^­ú1¯7ø±^‡³h^ͺ{m-n¥è=©©tÑľQ¿Â¨—•>v&úu¤¯Ûrõ”¶u½2¢³W>YH·Ek¤Æ«‹<r±ì[óó¹™IVíݶ8óª°uY;ŸëcÕÚÈ´úà3©EáZZ ´Gu6°j‹87‡³ìåÅi«h ><Ñý~ÿ×ÿößýÃôOþëþÿñß3@^lã›y8nÙå+ª–ØVqä3{ê—/#Ååt‚ÃÏìô!ø{ÓRrWð�¼3”üè°•”)ä(e–´Ë E *!O<D–†²±�;œäø@Òö[ ½«2¡YB9 ço f¶}QŸÕæóAh¬]ç%ç×çã 7½A#‘`ƒ†!ÔJÎT,îÑõoW½˜ö“÷ÒdÊOa s d¦¡c{ò",llJ90ë;]‰¨*‚š2�5ÃÆ)8ÅàâDç† Ô—à¾v7qq!m»«ä4h4wí>mp4†Ø7FÆKtÅ¥a¶uØpxHÉbpˆÕá(íá À]Àè'Q¤¢fÚJfà@¼>‡!ÁNjwجpã+ÛAJ@:ÈljH¬ºBË*%…ù,ÙY‚§`DÓ®„-7O"ÂC+bfYkD±õXòecžnÕ(•±3€ÚÐh=;\%Á9Vî!�!úô{6Ýî¥ÂI+å¡9+œž¨¾wV[Ë–0•¥Å­UEMµÅì° ~ žÓJæñ±:L4ƒÍÊ‘)ÑÅA”ÙmC!†Ñ {+­h4 r±™n—­ƒV, Â#ÉH¼’qÞ©ÞœžácvÖÉy¡µ€è5M¶S:`AÞÃwzö>®H}ŸÛŽcµ/—`v79£ò „ÁÈtM=�NüuD@˜×4,I-` NhÊz‹ÏÖµ  $0ß#[ÿ9輯CÈ ƒ±Tõõà[.gòIì-A5HBDø»¥ïoQ™ˆÛ:«ØQcu6—N¯g™¢÷‹‰Ay±~×Î\ ‘€±+Òx³« FÁqy:#(¶"¨¤Ic£æÖJA™ÎHŠ"…’6×59&w/TtÔÀ© 38l”ÜŠ§yFŠÝ Р TçùR¬Nž™dSuŽå Û“§âbñˆÌ˨¬ va/ni;NÊ˶@]†AFé#nUª‡O\(.»h,›áAÓ5sMEédµnÓ' ä IIâBš?¨ä¼¶xv½÷ŒŠŠŒï©ï4¸<l‹Õa_Õ¿ã×¼ö*0ù.ïê[íU)çUüÞ½QM’É:Kù0©ŽÿUÚEA!Úëç}¥•7Êê‡%ï8 p5¿–`í/³øº \ü]YuµÕ7¶Gâ¢Í±iáNw¥Ê’nI&¹›dc.œ›:-oFYSù¢F:¯·ì°ÎÀ':<­ä­OK¹7÷úpø®_í¦_�. ít}`Ðêi¼ŸèºÚS]‹¨Õ;%'ç‡×•Îâãú¬Ýåö:­+D Ã+í¨}5ÞRu¯—tnŒ¢j»^øI[ÄU.Zq]zZÏë¼:ö.¯ºs H°ÆBl*l¤û[û–\¾b¸Ê-þlfêËç,œ¶…'DDôûÖ<ØÎ+ãê¬l·Ê½û*ÞÖ…76µc(—´¢¥&Ík\ñ>Dp¸-¤¬±ëz„óJÁ¬kX’'Á¢›-B¤P£f›:/Œ¥oµÌê‘þÒa¹®á3Ñû­Û¿ªWÊo¹ž“HLgñÔ×Ãøu”þ×eÕ=µ·/ŒÉ†Àú¶yójÂGä©rD±?VT…알ª ÓkÚ¡ìÇa“mHQÂ10:qŽp6æL £FÚž}1žÁÊ,,bvéáf•¿û™\Ø[K±T£!“sÂ%Š™U)LHm)£A¤‹Iu¢d„pî)òkrè^_¤¹º*‘ñn°Ç ݃iÀ˜0nPGÍdYšø´åcŒWÞPs0”Ú—Ë6U''ŽÕjg„@í/dËw53ý#�ªgv!B¾Sì•^RË5«É)õ4dá¾609 eÐ �ÚÎà´Ù9#ö­Nóá›5–P¨Pëõ9ö£¸Ü5m|Úè¿E½G™/˜×X 1,WBµúðßìz¾¦ò3[¶¹\ ±ýd A_Ĩ\•¹ÒòXV~p>dªÉ¾pIó.«;êáV¿½–DʲyjåÔòuÕá·¤„kŠZK„åeåb.ðÙ‰èã(Wˆª'Q¦Ì«†Â+^*ÒšvùörÑæ’¡5£Ø–8¿ßÀq•�¨Àîš«ÖÐ*U°ˆnÔÔ»–_íÖá%µ”Ùz©�.T3úv &}CWsÁ ¯wÝÊ‘?·š[Uuû>¯Ù–C9Úß·–ì“ònIÌe½,BÝ $õ¯+®º.ïg{.ÒV»ü~µ0¦+-ú -˾¿±R…õòíʘ¸–'ûø_Ö9VðH¹à³°Ù•OÇs¹Du]©vά*Œj ÜÊ—¯[9Ú÷›* äÆ5 q¿hvOÁ³n�m8UÑ™m[g“î'¹ïÕ`Y»Õ«ºás¹àŒN3ÑËQÖÊå:Lë‘_›ßñòFõPL¨euV5bÕéÐ~@µ ,0(ù:ˆVØ…£ëCxhUÝÑ #"½2q '‚qÒ<TMþPn±£á€ª¼•Ô;{ãdØH„Ž_>3u“Ûœà)B6áuãt¥eç°'`Ø“¤ƒðÎ<–ƒŽCSã:áW‘Tqô‚nа›qM¬]zÊÃJò¿alEFØzƒýóê…Á|û tÅ—¡ÓШ„,‰%ÂHW[±e$D)„4í‚7ö¡³šÑäñc»ÔŠiÄ,’ô.‰lí’µ?6è»Él(áònY¦Í tÄ”Ä7Oö‚�ûMÂqŸtìà1ô1ëñÀ:­Ññféæ©ûÁ¬7Í®ÿº1¾Õ #€çĈçšxê‰w`™P ¤m¹9àpÈ ÙYu^Qž ZUÆš¤KÁº1A ·1a%!¿±"¤¸ŠmÞûØ£œ“E”Àÿ|"…Q0Œã&B¨N5;=\H¢`m¼›œÿoyÁÚÀÖ: ØøóðDÓõÍ7J–AŽPà~Ž¡¡ææ:q)ÅâÊòøGë¾ô–v{DËõlˆy Z 4 7?ad“¸•†ÙG¾p#ßüôMŸ¯Á›Ù  Ñl}À3• E:寰5ã!í¾Î°' ×q¤5œ§„c°­)!ÁÙ[›#±;ÃNSŸY]¸Ç~…ÐðÈœ0“î§ûýdG€ |ÉI5bÕ» „» ø ±Ül±ŽÚ,<¹z% çhYI$d.•® ãm]ö–Pȸ|' q³=·{Vqd“ð ${ÁÉÙ1y}ÈóFgÌËyÊx´a2JqLˆÝ®±˜X£uC`2ŽžØkðØ!Gýp«ÚóÕ㢋’¨ßh)¿~èøegøï€u°ؘ8,Ò¶ÀŸŸ·ÃŒÖ&’z/ø‹:óä!ÐNɘ€ÕËšÍX>ã‡ËXy÷ ·ÂbN²­úŸm×$dD)„}9 ÚMÕíÅv­å®ŒP+™W?§äˆh+š¿ Ói§ÄââÈ;ØŠ zΡe¥í"†bXÙgÝåŸýÒìzª9‰Ñx}û¥òÊÔ+æ¬I@ Ô |Ç}ïW³’½˜G� 1ˆwíãã=ÀÑfWÚç¼q<[§½vòŒ°_ÉíêBØà�ø±‡ƒ^=]evZ�×¾¥n²§üQ*ãÍè¼Ï!‘s¹5ªR;¡x„i­Òóý“ÈWWE‹ öß¹£¬I®}«^ì­¡rੈê$ò„'vñ,»¶RFðKT\‚½6ˆ–®úüfa!h]Âm82À$ÇHe°ubšTDSc@²hÕÀÆ6¬eõŸï¨û̉Œ.°Vàõ"døÏhŽÈ@†<ŒœA­©xr9èîz<¤´Çëc#ÒÏò¹Ò §Ã8Á | ø™,¶­~|½×ÀõH?¥²Šp}£-2M0BéÏ$.Y×®­‡×þ{ÝQ!yd á®yŽÚ>,ÌË©ºRTÏûÍ`&‹êBºúº5ã´¬/¯(&ˆ“¬$¡÷[™M ]V˜C´"Ê^J&X0Çr¦—õõ/G9*‡Ï®¥«Æ>e¢g»¶ Žë¹œ{…2ÚÅ0 D ÖÓúû¯[yvª?ì$äP«qÚúƉ|¿‘ÔH]>ÿåØÜ¼ž‰Þo oV±¸gõdµ#÷ìŸ,¬Â>Þ–ï½sQ#-o¿6 YÛ ˜Ä ½ 4ã*[þé,ðxuQ½×›[þ¾|Ëû·Üh"z¿Ñ•èëV@kÏ+xïåH/Çzîô~+ˆ»yEýUë,ýäV™W¿3H¬fS^!mB¼ÄƒÃÓŠzÛÒ*W£Cî¼àe^p°FÍY.T9jä¶Å0¬ìQSak•ßÓÊS\A­åà_N•ò%5¯éZ0%²>;i㧸®Š¶ï½žYj"_Wêä¥\Ÿ‚'üT›g#Dѯթë2†Ü,GFJ–Më Љðé):ÞÄ~ÈL[`ðõã…¦ÅðÖ,ðš)ïžc "3ûVÅx¡õ:¢^ÓÎH<s%YŒƒÐHEÈ”ýt&Xâ`‘·„+]Üke­Ù y@å'ví£„µø ÒAÕÁlño`Þ–ã¦zä ÖQS Ìì“i-¶Tm Q£²í)Ï.»ñ‡Ýu ©ýà j3*z ·’qƒÝ\aÛ3hИSÔ´°EdÔ“¥ªYF~ö9/ɱÅLrb†k÷’ãÊ z=*éIÍ59³à(µ¯vÃý·GjöGz+hGZh¢­‡Ñ‘+…‚úO×pw–šÂ_ ɨǑ/!¢Û§ª8«fÒÙ«he´Ò“·û–’FÃà{SÚ. ¸‡ä–Ÿs»ƒÕhÀyxd‹úUFÃS#©”K·R¬*¥¼`Ò‰óEŸé$ŽJÚXraGÜQŽuA¶ÊŒ×ãaûÍRaRK·Ì&÷0é4m€ÃMά8‘íÄÏEÄØú”Ë. ˆË¾®Kâ«pàªÌd&µ>ÁÇ‘®ÍØ¥Òìê%*•å¤Ú0¥–Í-C?nÍœ÷©Ñn”›3•2¨ÐªÞ¿—£Uz2Zœ‰V±‰Ê"*»ü×­dè×r}ªü„¤<šÖK«!^›VË"Þ±¬½rú|1kÔÉZÔͺ>¡¥`š›Ê¢ì÷žt5v•zqìý®ÕT?(œªß·zšåª®[$9¸\Å�«DÀk»•Mtæ©ñçRȸ¨"~©áªÉUío’Yp+³v{ÏâŽ,æ8“8Â~Õ÷€êºÂ¦»¶ËȉÀ ^ó‘ \à‹ú�®d¼Tê ìÆ‹Â]ºJ£}üÅæ\ KÜv°O Nàeš (ÇCu8ŠÄ�õOƒ:¡Àé8šAÔPŸ³ ·Uäf¾ Ñ@¾có 45÷Ìn°õ°®í,òöð2ncx±`�þf‡•¨ÚÇŒ¨¬È˜‡ öf;V mGÞ ]iõ¼–pDUekVi,l©”±|;ИкÀ°\à)oG)1“ÙÒÂäƒLäýìµzĵÛ!=Ð6‡ûÖlÎqèJ¶{3ÒÇ/ÐÍß=‘7öô½üxÛB¢Ò.¬`¨ ušÂ¬‡& ªMÎ@Á Æãg;BåÁ}nA†¯×õ2Ôô=ÅAÛ'ˆ|D(œ{sˆÓg³¬Xì`2óì†áÆ „]k‘íþH”㛥9dCþ.‘ƒ0dçòÅáߊsü24Ç(mt[-ª3]%ûzd:l ¢ô sYûDÖ<PNÞ�F`#Z¬Bv‹/M=i=)m –+ïŒX›Ò``{ŒL;…=®¨ë`©pÜdMmÎó {ºž„ǹÂwWWŸÂé‡VUŽL¯A8`ˆ8ÂLÅg÷f¾‚ë?H25IzÔë×x@ÝĵìrbÇÒÍŽ££%·#¯AC+œO¤ž#Q`¦.¹´ *zÏ$9Ï“F\y cmDâ‚8€ã³sõÜBY~9°‰aÆ9ŸŒ¦°i:Iš‘•©ø¼VÁSL‘Lñ9YN$ཹdÎÔâ!Sy®âRg$bÑ0ˆLªp°eMÒ©]@Z1`I[~(=XAÚøÀM•Žé%z±²¨ï„™ÖŒ;´Î@Á#Ö»äðòöla#ƒŒ“_{éù%ÆÁ¯%}Féƒ{=gBb zË>Úý:c>ßœQÍY{_î!­A¾•PG1ƒZÙv}s8 �]S Ä÷j Ð1¶ŽqrV1KV< y‹u«Ê•V2ØsÙdœ)6è"¸e‹ì·Ó#¨‘—Èò÷‹C¯_Ù”¬Mȼ$®ïŠgP[.¨KÌÔ 4c+ $í!ÌîMÿAà.èëD)ÐQÜÛý_½ÕÍÛýû½@AÆJH6}F´v\10ê;ÉTš­»ècÀNwFŠ�Œ· 0…Õ:m¿ËØ Ö¶D¾UL°}D€Rà0 1ŠtÞ¨«K‚5Î 8®p'-!ôftYõ!aN�l‘%×Un”JKðG(ÄOÊæ˜èx5Œü«R(Ï%ó#-"ÌÃõã ”À°ÑuŒPÍ ?Z‘Y³�—G£ž·Örôî©B²£äåó‰bÔë&ƒxhÐ W›ÕÃÞIÒàLˆöÈRÀƒVǼ+sØþ7Qô¨Ÿ E20Ûy€ôÜœs §`ÇÉŠ±vg;'è§Ê3Tn‹Ôñ-Œ5'­Dr ñ(EF,°UeÌ‚z1[•&,t›Ðü ãÑçKŒgþê3ÅìDµOs—B›µD…‚5µÃ_ÈØr²[HëÇ&IÙ4üE[ÓŸGàr<’„!P÷A$c`ë,‡…pH!ƒ‡/µA\ô²¶ ˜ª×]¨-q–ªê¢eL‰¶ÙvyÕ‡îš]è?QWÐ÷"ã6„!Ð_Ø%ܾƒ€ügİÁ2ñ±ˆ¾ Ù€srÛÙ`´"»¦JZBH?Þ¸¯ú3®9˜·ù~J‰°5˜qö›]šN„û¬±N.ÝoÖpÖ 8ìCiÄäKb/Æ“ÈlÁl ŸŸU)éU…rìÍo¾ò³¬ =Ü‚kÀ\®hž*jè7“]ù¼0Òƒ†úÑég“¹Çe €²£YÑ ðQ´© ަ²ÈË�B©×ù·Æå&@@½lòbdˆB÷ÒÒƒZqñ° ùÞ»ŸôK›5ë&“¨'rÚ‰Ó]."l—nj[A1:òû°¬Þ@å"ì¸8‡–„¼%-e5`ÂZÒkÍ5l:éûŠÙ5ǤØRŒÆ i«Ù9YpèK€‘ÓθÒ¿z€‰egs,ýÎ�¶¥QííhÙ÷©Ü¸laJòu¡˜×д³Ã(ÂjGz?1çú�� �IDAT›DZç7j2˜€D6Hz™Õ›ÏHAØÐ}—žtIgg`Ô;ñ)¬ì+hAüçfÄÚ x@¸ Ç‘`P‘Î éŸ|Ú`å×óËàÝñõq«Ä] Gå9ÀݲíÚG‰ˆé´Dv% ~á|¥='Âw8J´;Þ”CG €û‚_Í¡™ €?d 7Uºe¡\ˆÎÀ¸‹+δãµàrpvðÛ„E…šfe4âò’äí½'ì+HT‡öúG¿þî“7÷™ã¸©Xç[of�€õ�p±*ÀßYXëEC”„= v¥ªT¬Ð`¢°7 òÈÇ™ñ®`o.•†‚V_ÃÉk“t>¡Iè#DFú{4,\Û¹,D½ÌwoËq$Æw.£7_„7YAP€M3@xýcO(pφQérw3ZÑ Ûcb™¢.Ž"ª/2]dnì™^«'‰¹¿°¦˜ÑÆÊ�çÙÑöÝè‹´ŒäD^88²RÍêüÈŠ]†žE]U“Œ%@ÊVi)†´1˜¹zèg2ÀF¶-ÛáÜÈ;XfU|ÀœÛªÎùv‡r2U£-Ų¢FE½[h6Åᬡmß² 3²zaÄ2L ÃiCZ Þ[*Mõd¼Îlý¥Tïˆ~šŒéú¿æ_ÛÏEýF¾¥ 㾆ROõ¨:úR‘Àü_¨`Û„”ÜïÍŽÖœÚ]€‡Ò½FwU^ç*%ƒáe\Ä~ÌðoôçÙƒú¥Í‹}ù™‹MÕûiÎî$>íá-š7íPëÛÍÏÜä|êzkÞê2HÏJx©ɵˆ¾,:FöÞMV¬y™“:r¹Œë£Û\ê'±OM+¶ òJå©Ñ\$‹Þo‡ÃMEˆ‹:G¢f¦^-ê›éûLtY÷¬÷›ZlOBS絘Ç× +•„è娓æ²ÈÏrQƒ­fE¶ê¼èœ~ßïÇE°ª\üå3/e›>¼ ½×û©(U%žß·¢5¼ÈònERvùùµþå÷­è }ÝèëFô·ôr¤_Gz¿ýmyÁy=þy½J/'z&zY‹RíDôr*©JÇ«pmÓWÃ<hå/³Phûº)èÜTŒËR¤U³˜VI§UF¶ÝÖ§¢l[nÙ\>¶,‰ ÑÇ‘>Š0U•&½6èåHõíw^…»d66­ι¨:-Ï ]ˆÞ¿¥rUSª‹äBíêÕ‡q¢{n²p娮ë~u]ÛW¥ÆT¥¿hn;˜ü uë®­®ImXUr­Óì‡4ó—ºY×gi¤æPñƒƒx×^‰ª}ªÈ12îªo‘RÜ&øE½­E±¿—Ïɱã¬Ó¹)=ÿ\•>^“XœõY¿êtmnQ?¤*’©+üŠK¢*Ù^6ŽY_¢¤Ï¯„ò-󺼊[\Ué^µvå\¹ªŽ)IlmÇ*”Wþµ ·?¯ÛÓkÑ\—û”L«Ÿt¿éåd²®å8Ë™¾ßŠþ·¸†íŽLZ÷šDðžEqs)Š…Ezn‚ï·òQç¦Jל.«ã•ècUr:«gQá£SË_4øÏtg%ŸxÏt8|—ï}&ú8VaøšŽÜïGš‰~ßèåxx"ú}£ß7šè𴆙g:¼}}—¸%dÂé×q Nôñ—¢ÇOÿÑ×7ÍD/oEDÿyýýŒ¶ƒq¸AËU¯ $¶d¥®ÃC;ßò‚¹Ù´zE§YªGR³ó¢I(Ô›ÞoMÄïªüÚFý~+"I¤©-ì¢ øòÖò§Wá°ÞßòDP[Jƒñs}L>Ž2’•³;»0Yo÷¢Šyû›2(€ÛþkDa¡ãÚ¾| ø%áÞ®fÚ^(Ħô. E¤‚ÑÓAØJìHvX’êf H@B ÊÏ?l㋱Uf#رiÍùfšRà0ifép¡ƒŒš-ŒƒwYC°ÛN,Q¯­J¨Tdð=@ïQ gûþ—­Ý);Y›.Öžž–N°x3V2}P—]¨½­ ÿ+€‹ …¯Äû_@ã Ê ÁÁd¶Š-^Ý#ô dÉh_a ¨,mÉ­Cózާ¬g{ÈßÀ-ÀÁh#hŒê|š'úþ½�ŽêRy�y±WÏo¯4n[œâpµ%ñ·1ûÙã[ÿ§@w ¥x]¹+îb¨Þϰ0ÒO�OäœA"~QOCCá½bgKHœÐÃs<|JÈë69¨ÊB°0რhÊBÞ ôÅB«Ø~% ¬ã¢7;ÿÓÈN\’•Ç%/Ì£ö #92´°øå@¢žÿ»„Ÿ: «–ÄÒ›¸Æ3ù^VÁOaÙ¦_D˜A,#Â,Äåb.ˆ¨ÂÐ9Äè*sgw<PZØÉn;õ~Õ¨™{váÞ¡Fª-Û‡È}Í`uk×¾6*Fx²ã„NÝñHàx8DõZÛ²UÜEít†ê´øúä?#3Â;%¤â`ü`MÙ«ˆ˜CÊ”yȽWr„Cñ±„ˆT–Í @$Ú¬0)?™úìcŽÍÅ‘ˆå:cØTÇŒY`8P“[÷z‹Až³ ü@l§GKKú”ƃ8»T¦F©†ÅX)Æå“OJò¿Ê5 8»a‘ñ3T$½á‚6ëŠP3¢åaS¢ÜÕ†Èd MÐ!ÈØ²kÅ2œ¬´1;µõ<ÑYƒejb! £þ2ÚZ0Ûîèº5Ph_ó‚·£Ñ6ƒ#ÂE{E+AÞÓ–Gª´u¨Ÿa ¢ÿ¬¢°z1JBDær KP ·ñ])@Þs$@ßÜ ^d·M×Ä\m^Ǩƒ—ƒ9´O‘â­=c‹ç¥•VŽÌŒû ¯+Qm ë6‹÷®ìFV7Am3¶�÷û›R Ì¢™é~ÿKk?.m@axX 2^%S –k¸_åÏ3æÞÉ`/·oIG£¦¬ñíJò–1'oC“l£žÈzŽx¬¢š¹OP!<!Ià z •—ö¥e+hLßájpŒ¬^i^O±Å¢Zø¯†û¬„lþ44Äkrä{¤"øLýQm€Ù ÒÞï8#£/ ¯ðHN龸  lAPD§îÒ"ÍþµÙ`6HËÕ‚ô¢„ ݤK¢çШà‹z5t‚Ûÿ–³>ëO‹~œž-0?ªNt‹ÅÜŠª(Wàp Q “�ndá >)L ³ÍjØØ¶¡Š&x¶Ý¶z¦åªÎÍR²^Éåðšq_µ4|²°bB/ðˇ´[iðцž¨¾õÏ+jqR zÿã~?žˆ~ʹœWõ ±à5ž‚qA-.¸Á†Ï»ÒÇñpø.p‰3]éýÜøu*`Â_oDÏôëèÿ¥_oôõM/'¢ç‚!¤‘ñûÿ¸˜?ÚÃ;­`ÂÔÀoË­§sq›¤÷ï†yÀŠº$ÊêZ 'T¬â¼eSR@ÙÁ˜´ëæv­¿ŸÔfR};›u½\W×Õhô¹À© �ç³­Ïæ*~ÏÖ¿qqæ\å•åý_my¯K¨á `{`ëå}ÿ£â•ZèÛñüN+è÷Pù0[¸ù§¸“ö¨í@åFSo‰‰d5„ô…9–ÛÓG3BL'z‡_¶Û öµæ¬Õëg{"íÓÿ"(?þS�»¬�uW•–ÄËŽfàŽrã–ˆµå‰Uðh¿œV,V xWñ0³~°E¾¹¼]]®k»’m‡’èÇYùË,†³¿o†¿Qá‹yØ0ú+�o³µìjñ;~^m—Êìå(óZAÕ埈>Þ²ÝDäö°Þ†QœíyÕà'a ²Æìvî³|VfB…}ßóŠØ^½n[ˆ™W0ØWÙèdóá‰èã¸üåp¸Ñ™èב®+‚ñ~¢ß·ò–_G¢ÿV°¿oô~Ó”µç¶cþþ.q¥˜?ÊVýr¤¯o¢+}}—Y^üëHÇr¡ÎD¢—·rÑ–:»çå¢vóûý¨öÀW•ÂÒÇ[¹ƒºê¢¹œ{‰Ü—vÇËþþ,Èkø\~ÙÂç¤ÖžÝî–ßœê#P^|%º®yɤíÅMeYçy×c€–ˆ~ßþmob[vf®[G !œT߇A ƒÛd˜‚aßÙÕ¬; nº QàIwÐP19A¼I<0˜ÊQC&4E'ü "ïÀð(!³#q ¢hI¹UXMÞîβµcvzpöÏ÷³ö>çÆ“I/Þý9?ûìïûÖ·¾µ¤úêuŽú{Í Ü©”±0~¥e¨Ý(îÕbîE™ â0ãpØÁ–XcÐDÛì /—rXr„}áŽOîQì…øä >yöâ R¥¾a-!ZªŸÖ†Ë�&ý5^G ¥TÙ!òol6¥´(®šd×–)ô˜r6¼ôQׄ…ôÒ)-èQŠá4D†Û…0»²ÀllXpÁ§“+g-ß' /V@)}éÔ² ZŒQöWTßem`' ¢”— LØ"£‚Ä=2´- ‡.¿48í+¿{N`~ÇšÕÒCàþ¯¦}hZ†¡=n™4FTöò ,oøŠKý±B“Qݤ- óN¾GmÙ/îúô[MÀî$ýîQ+úvœJæM-»fM—>a‘½wà Îbsºì vìÎk®Å?$½.ݹ¥DÁôE3àäû�2Q¯SàMŸÇè»î>BXù†ÈæõîòXŽ~“ß?¸mbh{š¦kš¦ˆ¿­rOP—Wƶ"à;8vFtÒ>µ÷ ]3X‰KÚ‚?õØ ³®¶µ.•¬øÄ!Œ6„Ôc×i‘èÐç:¯:CF¶*Guž-;fè©ðP'wEçkûˆ‘°Ú¬–.ÑÔNDÇ]ßU=¹ØÎä–ë ö‰m}¡ô÷´ô-ôþÖ̘.."0úÀ Â@? v8“ Åv;y@'6W¥ÅÇ”zÌ3šýLR%îIpo'KPŒ|k¦Ÿï? hnÖJV.2É;j|!à”¹Öì:vˆ¡m\@ÃO 6ʘ°w*: .Ë´õó:^}µnp±qƒ‚6�”bÎɲ¢à¦I¬MµJä‹+¡<´V,q[ꔜþÉÏŠ1Ùbõ™ÑѤnSßR9Z]%UAÒXÎödK eΜF½ p³n&9òŒE— h{¬zK}ûZSÙs*®áñ«·‡†—`Y³Š…}oÐ%ø‚©²%¿³Lw:?ñ‚*Xú93rïAäRúyñµ&»ŸLò«Ó«·ÍaNŽ–^Ø¿G\åÖŸ`§ŽÚÀ>¶܇ÆyáÂj£±-ÌÈ Zž¡�É[B[«7ÉeŠ®Ú#§ Ê&;E…ñz¯oc·o_ªF­Åô8í cË×·­t®Òוƒ‰bOQmkó’èÂØ\~Kú#´h,›<‡¨­4Ã$Ð.s&Ùvž¼G€ÄWî'AÔr­píÚÆ›H À6Ú“lÝòÓ/š ž@a86É~³½-×£zrÍ.B˜¯Þæk»Y³ã0wá÷võzÂÕô¯A%鯷Âî×^±Û;ÿ sw·íZ4¦%f´wÝ£Ò©sQj ƒÚü:0”’–z•°°µŠ$¦Úio¨|¸ßY"Ûþdä‡qüÝ8~<Žãõ8ãøñ8^ã0Ž—ãøñ8¾Éÿÿd<Žÿi2Ž—Äe1šA‚ ¨7bürT+G q|cÄÅ•/)zËVÐÜ×Ö.+ºØà \ï°e�7 â99°§ÃMÚúizU3WÎ[We'q êˆf¦¬´<mÝû³>®§Ö›OíÃ9%\Jc“ZŸþ_ ‰ÜKuÑüŽP¨ƒRv¶Ï¹ðmñÔ={^’‚*£·Aü“ ^!—PówM/"€|Žúù¢Oö8RäÌ‹9¦ÍbÚ…ÑÁK fu5!6X™Ü;î¾²õÆ„8 Ï«’kwB÷^\í½ÐåÜgÖÎ]œ½¡ôwIä+ÅòúÕkàáQÒ'ÆW½#盪4Xž½3%“h¨›õîv8›yuêR}&£ê™V1ºó5¤øíA 3œ õ¶}jKAqŸˆr•4<TJ›\ÙgótFw›Äךˆ[ãºpÀÒ5<•+êwÀÿ üào�¿�þ øÇÀ?þø�ÀÏ��ÿø�ø?€Ÿ¬Vo™ùhÅDž©RjӤ᭤xyûXõ$Ÿ§Ÿ¿ÂóŸ%‰ÛéÞp²Áù×wœMd¯ðàkœl%gUo:Ç“uZ„{ÁŒ•\V¯¢°†Ì�¬'øUºÑ‡ô,œ¯'ž¤”©¬bƒ{àn3UZ“7â¶^ègó.’OU“71'w‚ˆ¸žU©/jÝê}•묜ûùºe%O,óéõùÓÌ$Y¡àõÅiš"Í0À*ž+Ã,>9ÆÄ6,Ç9Ãì[ñ.túè—~ôËüA(ôá¹!ë_Øñê—>³XÓûôÏ0'oȸ>ð{£‚D¿§ëØi¹�(-Ù¿¦«Ôîˆ%ݲõÃ~7Lž¯ŒÚDÊÐÆè«\ÆŒ|Â:4ºñѪRõÛ±^hCÛG­[ÊXªÖ©…Ô„ø½‚~R¸ïr/Çñzߎãm¿':BÔú…ö" A RÛ �‡4¨J+ó,r+k;ŽWB¾O1° yg ¦ÒòâØÒyÐ$":™"îˆðÑpѾ‘вI0fÐÁJÌÀ»~=É;0XÛŒZS³ÖÀfÕµ.eKéê8•¦æ3fXàË©£´YÍÖÜý^ qI}èʼnξy¢Ñéß‚^¢0wµUSQ!šb--"¯ 8âj0CPÝ ×…ö|3BôÐâ¡-QZ þæ¹æÁÌoGí\14dmm+±Ñy2\2h7Øžä´Wz”?ŒŸŒã'9hM[ÿ¥p«ºÌ<ˆËqÜŒãg™Â·¶¶I*cBž£tbL`Ô¥vdÞ(ñ@ó²qÇ·±|“ºnãecÛqÆñ*ÿuÂ3¯UÏL†É{ 56ø'‚‹OJ±(:00ï«–kW[¯`ÌUÊ!,ÑÔOP ´ ¶ÛE¾þäÙ÷Ž\A£”wµO_˜Cåsef‡¡GY=V}%°ÖÚŽ¥D_­µ 1«×ª`4óÞT£6Z ÜÚ´q†ž÷X¢�ûî” U¶WXÜìƒd. wb’qï|­ ý5P]B NXÇWwuü|YHŸ|®¦yêÈê¾"`iUìµD±Þ¹ÛLŸVÆä®²N”€´ž•îSEÑãÌæ¤Å¨…ÀàúZ½®IÅ0ÅôÛÍ�xºh·›IÜ­ât£¿ V¶S z�§Øù}ú¢ôÔœÖ˘üAn|$ç>£:åzO“»5NÖÀDàÏx>�ß¾…ókœ À+à§ÀŸ��¾ügà»«Ó XM3¼Å`éá€ÛGÜ&X/›•<â«Õ!MOï|™&‘/T0�Ü>&E’2Ÿûüçkà�€o�Ÿ�‡“+àï�ÿ�ðO€ß¯Äüó/€ßVÅŠb5á~õQÚ·^vDÁ­rµì ]ÃÓ¬S Î ›lÀv⻨œÔÖ©Ò^9ÒU“òçöîš÷Þ¡"ÉÓ½ÈK¥¸mM'Ó-Àíçë¢Ä¡›Lë"ÏQEî¶é[žóÃçë4„~ÑÜýÒ Ñþ€vJ–ÀJÖ«ðÂöÀê¾ì—‰ã¢è%ø”Ót}¼Ì„ÅFY\)vV)`Néƒ�û§ רÁvæZ},0+&ë#b/³ZA÷h †Öæ˜ÀôNg±´ ü²“è¶Z¯û¼+A»eyˆÓk yyóù~5)&øSN›ÝR‚f]¥sV?ü^ô™Ê…½©½±–ö6ý’=]%t¡t³º´Â ¬òñH/1ódUO¿ MwÂd¨ìOùHvÂîòd=…1ëu¹Ë^…ZÌ;K1ý)ðÿ�ƒ‡ÿ'[<øø%ð+à+à+à‡À/€/€Ÿ¿þ øh²KG5mj7¨2»,]±Ç8n§Æ’l_­V8Y㨒¤—=js+I`üGàÀð ððçÀðo€WÀÏ?΀¦8‡ÏÓ8ÙJɆÒ$«h—ËŽéŠÝm”í…pÝÔ¾h©u·¯÷kr/“‰uC{~Ä>ų’|À™ŽÖ`Y¤RNÓµ­ª@¢NzJת¾±Ä³ÉÅêö€“õ8®eS¶b{݈½È}Ü=V«wéÈÏD¿Aw²©Ì-Ìz¡L’w³ u,Væ)ég{â%2ðžX9×^: Ž›E&`™‡ETø…ÀiËH˜qi9–ѲÌhõ <ÝêÃY“ŽöH\a,ޱû$&*œÄƒ–06¢|áå}™6„„ ,q 1" ¤æZ8åCÁbþ) Žé´ãh&@+]ðÇãx=ŽÛq¼ÇMþa[Eië€Ô›q|£hâùž’;­¼vÙJ Bø®°ä&ñÚ'¦x‚./-·>ýëv‚1!giÍÔ[ü„5ê…¨yg®À(ÒÒ¶e½JÁMßB õƒV-F"¼Ô‹œÚ6ÃÂF_?8Ó3#›Læßïê’Îh·Ï-µ}ö–t¹z(04vN9 m©’Ù¶Ðûüéð�[Ä„%ßÞê‡ÑiÞ뼆#Î…@çs„—eÜH?4¡ù¡M¾ˆ. ?úê·iÿˆdÕéHyj¾íœ™MÐu쥦� x¹zïÇáÝö¼À<³¡®€2ÿÍüõB"¿¬Œ†j²Mm¤ñmµÞH¬‡m‰Fª½!C”iR¦ÎÖ¥âÇGÑÖ’®�͹ÓWëªÕ¤L 7�“/Ô\3aÇDbG-åÅ68Ù0ÒÒ²Š+ᨢ·•—˶‡KþÌ3R˜b~V¯?Ô\§-4–\eÐ,sYBCXb|Õ¿%&´NÇ<½,xÌzË(i¦-/ìZÕUŸùb%Fî)܃­}­ÐËÀÛû"÷ߨ‘=ö(è^k›ÐÑgU'¿d–60±£éG…׆sUÙÊr`Ö‘“ý8ý•ù£ÚÃ+NQƒ;ÁÀy•D ÀiD‰ª÷jßd*àD¯x“#Ê&—2Sùò&B†pňk¥œ2£–£]Ñ:xQmü¸–‚L9x\‰¸u™ð•àƒlŒ¹p“àÐðœõ2!98udCµÔ ‹3rBi3Sô.Y­bhºVÂÖÙ¬"B.˜Ø‡ÄäÔ§£ü±š¹èE¬YDŽNƒ.gëù‰Ñ¥¯½Œ×ûSx5sÏêeÜÅsÇ[7™™Î&λéPPÑ*5Dry-"Ø„¯QP•RÔ*t•Ê‚C´º…ÆŒÄW Xf?ôí*E{ј røõj§Ü:Y†FOˆª¦Ö¤d;Ž?ÉxàºÕ«êj“Xãã: 3o_¥áªÍ¦´]Vd´¢²ZW|ÅK¡y±VÔÄñ2Ó§ {)£m àq`°›I’¢p6ÀðX€Tr3ÛìÀMª¸Ø˜O Ø.EžZ½D†Ž´û<//¶Åš³ÝšcÕÄ;°á >¿ßXê v­­ÖK õ™ú³:~Ë/ú嬹 yÀ‹¡B#ôÙ|*ZV„C“±jÉÓAey¤—cäy'À:´¥©O9“>д—5UpLƒ€3ºZ[йPI°ŒyÊãwÒéDU¨5Ë5pñ òuAﶉ~™FÒèÕ:Øo+F—~Îô÷²Å5g£kIFÖ­ŒÎ¬Òh0¦>Ö¥¢—ªVéøñ}csè†ÆîÐmp"Á¹-oí½1%¾­=š!¤Dêlƒ6heÛì± /ÕØð(°>2Ì>¨n´}â¤øÐÈé_ ÒÔß =rTæ_4tмc;CX ò×Ä61`‰þá|5QT¼ýÁQ¥ØÑ±ÊõrÈ?E×íð3ÝÞ2#4Ôu¼©" ¼3Dš *»Ç¬fÄÙwƒv’þ¶ƒ×¼Ž çL•ŠB@$¹Žì¨¢aov Ÿ=ÐS¸OÛQKc¹›<e5Íoôo6ÕDxüd¯SÜ*M¬AÛ%ËæÖàº/Òê"ê­Y¡|BB0æîÚ $í1çjL×ô›&ƒ û({èŠ œê‚¢)´ n$ô‚­·2Ô*¤Ð @wð?2Ü¥­ÆI‚·õ“*Y>e<V¥Iþž°Òµ¶ÐÄó^mµÚ-Õ,‘Yö§È§9õ£NLõ¬q9dVÈñÞ7YrÙÍ.Ó?l¸ñ&e›ùZ¹YÖÚ·/Q|ovûÎNÉá*õ™÷î»v:ùºŸS|x/Õ5]í{I›Öj@÷šæ{#hEû4¦SÜÓkžÔíV7èISÉŸòbx8Ô�¼ƒ}÷ùÃCr>T i_utlH¸IŸ/o‡å"ŸÚ‘Œê ™E€Ì ]u~7¢˜fq º†ïõøšl|ÞäÜdîu¬FÃ’®VäÓ žoV£ùÿxÂÉ%ð| |�ü�ø6NÖÀ€à 8ÙßþWà�ðüOÀí»:„´ËÏ'ëä,<-†“í�|- ëU˪ T$ÈMúÀçÇÕétg¿‹'àù-žß“-äcðð˜•Þ_àa’úy !IyÝm’zÓù¶ºý¬VESªÌ�¤?Ó%½['òº¹ÂW9±ÕÒYŸ¯Ó0ßM]œÓLRµÖÅtïÒ ™ÜoÒ3dôr7§{-g Ó MƒzpªÉç…z*ËìŠu²Á�� �IDATAõ é9­æày#1~§1¯¼ºÉ ûûz<€¾ª}v;¨'ôróÈÉ„H­ã¡ðž\>cSÒaÏ7½BïºûáG‘ /¼ì ŽÎÍ,4:X¡QzÛ'[xÀ§Üž·’“ùä& ?8ºðÐëe¶TƒIÙðG†ùõIp’ØîTE&geL@Æ­Ýc£˜Ž¶a) £Ï2*ø‰ê%À° „›¬ç´5”èÚ|Üð#ŠñG¡BHN`iYóªU:mÛÒ }ÄL·IóBz|4êÛ îB1fÂz7*PR¶?0ôÐõ–´`ÚÆºç4\Ù”ÚEl”Y¾º’5kçAŽWÒ'Ó 5¶1WcAÿBÌú™G«ZÅ,­”9`ð¦.‘ÿ§EÉrRô¨©*°þ½´v¬™©†¿ÈXñÿ(_°–‰n¥Ã;Ø4|y¤ñÊË^šö¢6:ÓY¹,.ïSÒdqðà,«-\hFCcÿ¯E¢-а4ú”5a‡ähž#K”éZ¥ÄqQËb _J·txOµžH>è§äÒ¥LóL¥¢õÖܨªTj—b׎ߖÌ÷ö€»¤ˆJz7iÉUT=J)ë³´–.ªŸ½7>­ ûô¯“ƒù]Š4\f-Ó|ñ îÎM}þ%ð;àߦU‚?>þø%Àoq²>bzA‘C-åÅÃcÒ_Èñ)íp†“-N6x~—ægŸÀxxÄóÛdu¾ÁÉøøiÒnÈj³¸ðkàËiåàö�œá|S‹¶éHž§êêŸ�_?©õñT‡oÓ³p¾®»Ši#¦×L‡­Pñ›*O\q£}ŒBé.¯N³>Å™(¡žªèL*þ¦Ï¹}´Ïò™Ð}~^ƒ2[¬ê{*F㟰:EÑIbÇ÷UW¥Ì2§¡ø› ‡ŒV«G©0, ×=ö4/ï§<ã|Re2VñšIí}œ£j¬%¸g™x=6]ø=¹gŠÈ°¨NêŒIÍ*пÌêe)¿#¼ï¡¸´¤ö¤5€ÚF›ÄÚó-%%Ž7;÷ƒ Ñ4Jƒ+)<eè¢'²þ¼'Í‹LØ«'†œƒ±ÕÉS$$ï8L›”|~6‰É†qüYÒM|÷ëqüd·ãøñ8¾Íâ~Ÿãÿ5Ž¡öä%ºR ¯TCKëªú8º mK-¨€›R?%.»÷ 7“¨ "%AìR|ƒ°.t” rƒJïm°Â¸D“3WH�k=š˜;Þ|ÎùH©ä¼Œ{eýÀ„À~_“õ<ó", T³3OÜ‹È~ïm¡mŒ;«ÎŽÅj³³ts•C³ÍÞÁN_L¦?&AœPŸ|D¸$ÁN>šn¢1SGËO2é(îëØð¢Dcº€8yÆ|™ï8±]5[CÓ"<f $2n —Rõ{k°NWÜE74DꞸu>–—ãøŸÆñ“¬ÝþqÞô‡qü,‹\l²TîôÿW¢ù¢¼T+5Û•D85ù»&RQŒñMÐbȳY™”¡N<EÜ+E£n®À Ga´{ÂÙÂÙ𯒠áJÄÆšQFò[2ŠÁR+µÜsή´ÀD.¢‹jQá${kx´òTÕseGyÄšåR·ØtKªßýeZã­.³š粇&ï|iûªÍ \Î5o–ba¦ø[Z`Ñ) ¦{Ô#ÒfO }2kPÂÒ.G‡ÝÒYÎþ½ ­5«ùd&lbC)4ÆxÝä“ßn¼ûŸ=6IÖÍ"L5¸ÍÝ DÛt;ØzËÞ¦HzÒä:ç®ÙŽ‹ qúo¨ä@ÓÀ¨ƒ½—j·Îx­í¨€t NUÔÆÎÒf×’º®„ÚÅ¥©°m3L™)_ÃÌÞÅÆx†Nh�-ˆe ¯Ž«o#yž­‰ÓèX¨$FÚS÷nŸtA¢a»£ž”HšÊü%4Dâg¿B—™áÍ5å˺—áK Â“ßÅàØ¢0Ó7âê’géŽá}/ ~$õß—V“Òš;oSâÁ{ìÎî+ØJjç ĉ•Ô4±D[><�ôqH›˜Án÷‘¯pó¯Ð®W6Ÿ£zƒ±ÿyKªÀ&£åd u=H™hé¥H*,ó@ð(yÇ¥]²„¬@!ÍDJ@’€Q£yÉÁkÇA“ݯ4ób›_üï,ܹbœ"GZ9œñ´ˆÊ[å9â' *ØÑsºG ¼,‹½mÜR| […[o-*]áæ»%ÅI JÙüÐDÅ1/$A …5S@± vM·³ZEöו)e¤©°ß’$aAÇ©¬øJ¡?NyA<sÝ[ÓR…uϹoý+[F”|èccXi{&n¢† ;`#—^ÈÕKZ8§CZªN³üs{ÀÝFRGvê'ß>ÕõxuZÛàSó¼²x {^’, §c§ïÅ}äN)ÊEͺ^Šûê§“~s{(­uÉHJ?Ÿéë9µ¦ï«µnºA㦺Kœlê‡œÖÆuÉÞÕ5V,N&¦ÀĨTyîòÔžê­QÜúÉIäö1Ýâ• Yï Ò·e<eõñ½àÇOæÎ÷�>H>Ô{à|S;ùx•¾ôn3é”'Ó“ó p6ýëê¸}—ˆ�ðyZUab¢ßLßõ*ýþùhåÅàá�| |ø9ðsœ\ÀÉ%žßß«7æd"büøøßÒIÞd²øIm ½ùrGÒo&ó$;à4¡q·Æùºúhœ¬“–ùícå[ÙSæ)SEh>iŽb'ŠïÛGeä”Ý…EÝîÎ×vïZêÖ4m§ÙêyÒ£~ò}]ÖW‰|_içkÜ¥I€ÄÙg·š§*åž¾ñFp¦Î”s…aÍ3/~_œ…Yá‰%õAG©eŒ; ¸-×Ý0]™Š$ŒxySpž—–ÿË®<eŽEAê›–V´§*ôd<Þíë#œMK"Di&6й¶’E/ƒsÿ3òKúlaš‘ÆÁêZÙÔ58Év'ǧ2\)ch榥Î)í FîŠi0^¢× ñ±¨ûU 4ÛTiŒ¨ó¢~«”X¯ªc¥olx[«rC¶¤¥ß"Ñ<ÓTSå—×g2—:W«¤uçÔr©Vú`Åm‰ßæÐ�ÍñGAçiiLT)VÀXòéå)O³BJÕ©]ŠpŒq‡§0ËO[‚zu::­¹ã°NÁŸ££c˜o¼QqÉy¯Ïû˜¥äu¨•T>ò®É©a‚^C¡¥¹à­g�lc u­ ì#÷V­F¦jèC45™¨Œ›U7:ÖR°54æäê½²©—“,svþ}´EÁeÌpðQ½Úà^ç^4¥ÔÍ*aIòߊXFùð"»$¸Q¢ÉÆÖ¤ÌlÉXnl>(Z˜ÊeàúÅpã.FèÝÜž©*GtZûVâhí;^­É' ¡_<8ɨèÀ¡M¬Võ }M8´ ™6#Y›èk™Œ´%úÖK˜4ÁŒMùí>5Vj¦0ãy^�ŽêýôõÑ[‘µ_Ÿ©óÍ~éR6üâ@ÕÊH:´‚æfÊÚ-*éîvz4¤Š{rPbRuvç´(V>úxÖ²…3 ?šê¯'©ŠèØ�Ý…=Sc`ð®ÿ§NѦýa›œ ¦ð2ÏÊèÄP&WQ•—(‹­Ä¿¸Î$õËJÇòŒð ÔÜ£øÏL+GÇh•{´É9h¦Øe¬ “+))eŸ È̈́( ±Üý²«H2ã#W]ÀB, $È™H©jnÙQ‹®/åß+5«Êõ,g1¸Š0ºÕe:âj¸eYÕÒ„]2ü?K.?6ß_^¬ÁA_À¿ïïã­—u`ºY[?Äö0›.-á8÷Vjð¦½)§$ÙÝ«¸̆'@ìAkÉnPTc'µib•§†Ûf[gt–y]<‹íëL£…ÜbŒ4ƒL?Å–áa“Ç8!nˆÇ¶BAlð¦37ƒ‡2jEÁ/0׫ÄAX[j{€PΕ<Ã$ÜÅZ¨°¯UÔ”Š…[\:©WζD\€°-`´Ûåùz}ˉ7¤'êìM‘uL’¨œ Ï <*¤«é|‘ l{Û§‰7�öJ¼Ð a|®¢9Ϥ*uÚîfÂÉb:8˜‘ýœþPËtñ(^_?a±ʬ½ÈòÙ¸%g½ÝÞœŽM&ß»cSÔÇ$è¶A´ÚíÄ'—‰¯M>éƒÎ£÷³¡ëÐÇ ŠpÚ/5®Ñ-l!IeÏóéÑDàe—Å÷H‚Ûé?¼»#í?E1T[ é}¥òñ"¯~™ãÍu•{WúL›†zÓºøƒÔ¹cZbêJB„ŠKÅ~ŒyH÷ÁÚ=[a¬uˆ©%ÎA­ ;:–AQÓc �TUr$m-â3é{Õ±Q‹{âŸQ~’ó ÑŽs)¥ÙD*.ŽX³]œ#À¥÷?òáö«^Pu½XϘ›-¤T,‰^¿—xó_ŽæÞ¹¹¶ºj9OÊ͘ïQKoJ¯p`£éN3Ó¡‡—)€ï2­*ßZ{Ä¿cŸÒÒ¼Ò1ƒë&RÕÙ¡‚­.9M`hp= T+åõZöÐÁi–§P´QXŸì?©`#ª¥úË7y›¾¬ºR`°rÓ‡2\µÞëdØF K MÅ|‚Û‚Iªø!Œ`›ÀÔåæ\"é,êÞÞ¶úýìs°œ#èNŒíÍ»uB2曵²ð¦ÿGëÈ¡QezÑ÷¨aOcØ-¬*Í\…e&¶½vnšªe<ØÁ¸ZüCÍÅ™°Ô¯±Že@ÌwÈ0÷ŽRÓèÉò@¾¼Å_÷ó½õ[!NžMx-’>@¦C,¡ÁžÈä鞆fw–»%åÄ ?½–÷¦ª q\ƒ$´GÊ”H'©i–M³ÙŒQDÁKë/œô&D4*6%yˆê*Ťêx»UH ²g¨`ä.ñ7OŠ$’˜Ø0h)ï:æ`[’ÓD®ðÄ‹ŒR9Ejsj]L &Fq”£ê¶àŒŒCWŠÚúQb"Cdƒ¬ È> j¬%ËÜCp¼ÉáÂú©#Qñ‚éæ(Ç·$(r¸Äláµê@ ¿‡šÌyü(XlëúC’=¤¡œZ‚UAçl„™|²æ¢gã…·žŸØÈLY¤íŽÕ=0þH`-À¡Ñ¨ðÀNhŒ ö–ØÀB羨î;¦ÕW(yT,Êïe’Ë—ºPWŠG^~SƒÙe®“.Å'¶záºÖˆíƒæõe˜úÒ€.'Ϙuï€eªE¥Tà,E˜±[šɄ=1¨°!"mˆÂgœ–ò04µZL¯Zd6B,qk{TÒ—2êR•¡‚GÔXhi² GG—þ€Q‹žî€’˜gÛi˜“ÊíØQ¶–´Ê<Îjr8:®Ïs/oeµ”÷"Ò<`‡F;'4ïQv ÜQE¯ÈMu‰¯nhöº|ib… îSlr@1ƒiÕh¨ „¾Ä(ï÷[RËÄ=º«JUt½Û²4á là!â¯P$ ¯r^…}«é¡õ7IQ\WcFI”N„XŸ¶Š4(ƒ„K–#NoVT´N… NÐ6ê–¡iY ÊyRævVŒN¼±^Á±ƒŽ²‘°,Xç`gµÔ¿åÀÔÈÚ#J3LÆ6jkÙX PÁ~ÙdÒº~•°m›*êì’á¸8ÚD`‚ã ÇÅ’–0öl9¸œ?ò2æý<Q°±3mRhdÔmßû‰ü™'…«ð8k#LÒ~`ÔØN‹“’õI¢óʶØÄÙ€cƒ&–\AÃ"ëSá9ÍÝз¨0/ ƒf¦é¹7Û³‰L}1:K§A7x‚žè’föQ’ ð*ëê^×á B,œÃ ¯k».ꨠ»Î¨h0�¹#[�Pà„þ^x==˜Y4qëUÃ5XaxS [˜]N•‰½ž-£Ï(ÐOù4É ßÐÀ?Y €”tÒF+8÷¯h)¸¤w°P»}‰.. Ë¡­Ö<Ë_èy·Ïiï.iV-ù×%-¥%¤ö£àSzRïY`MQZ‚°F¬Üé"WÿCWÑNñŒNz’êÜ·^"yõ"΋íF×g’ʤtôE’HÐ"l˜d›šAfÎèj’ÆC”‘e»‘aÞB³4á£îŒK-™Á  ú0hÞ()A‘ȉjp @=·õ†ò²ËÝ<’–ži›ÙaÛ«­«Ûšß§îoŽ)ùžÔ‚Ýi›¬y@1¼Ï9ëQË·$fŒâ{ ¨©ÌäŽ@—tà;¢G™5S¼(hÎÔè@\ˆ(ðé>ì9¯µØŸ¥5·ðz3ÙáȈ5ôR&ƒn @¤|Õâ¦2›ð@†„À¼[䨕Ü:Ruñ‚¶vÌ%²kxým°;Ù™#5›¦‘Ì>­c˜qK $ºkfÚFIÊFXfv€ côKV[­]‡aSl#¦².+!pбèú(‘1\ŒrGô&^kUbM¶›•AŠzøL¥)É-!ÍGfŠÝRN‘:Xå!x¹BÈj-ee 5àUÖD/ÃúQÖM¤Ü(‹©Ësªá‡Žëc½ù§YüðÅ̺ØçËAO?ž¹÷>xÝ iôÃü´–åÎ/¤´Üâoh6£ªGû^¡É mÏSG;ãÕ%…:e£5í¥Ñ)`Âû Ž’×pfá9ilDßÈ×¼–-XSQÓB§¤|*ro‹K-«¯ôò£ÝÄÉ…´ÒDp­2II¯½úëZ“%&Å:°Kå?2hpIâ%¢‰€!™™\ZÅI¥™„ä=•@ïéJ‚]¾qpz’sËWžÓã(²4Åb€Ñ‰¶èl©õ\ %3š3$ªì‹ÊOÄž±©€eãîóXaQ$èP–©YK¿Æj2FBc“ bZ¨|ØÑ‰h!oKÅv‡yFâl…ºD€ªU³£ë§µ0QàžéÛæ™zjñÓ ôÏÜCì|khkÚÒ^N€‘|¥e%ߌkÃà2ÐÀ«;ÃZ}^{Ô‚'̰Øà‡vDDŽԂUhYGºœƒ ¬Œ¦^PN\©öU*•jhŸxƒU9p«Þõär%® Uìifirú*êæ–ß^"cÓEç_l&´—FQúLW °Š9*HrêÙSø˜¾%AA£kLJùÚBixÈ‘Óå–‘7œî¥mAŽa·ÏV0K´—¨…9æ†:›È[˜—+<v›n±©êëòYà…Á~¦ÙÖ¶Ýê t䨱‚¥!5q?zÕVHY‚Ûœ7ê&ylVü„4H|—¼H„í^ßÀñìÅ‘‰dЙuËL–: ·42FêÙ&œw´Ž<Aw5ß‘ÇÖ¤g)c‰l¼½»hÎXßV(\\ZGÇÕPØw¼è<ÞV¡&/…eäêÇ•dµIùÁ"ã—]ÊVÀd GÈ«DÍ|xˆ ñ´Ürgê@&:$ˆª–Jd¤Ü蜱¤nPÍT¹F۾섥IóYô¹‚a~|¸3 ´D¬o!å½ù]¡ÝPy?™Á¥“d¡IRÀ2½öc—׸ï9>lzï-ÑØ~K~CƒöìŒÁÙòz>ÁxyÑ"ëwºY�ᔓáÐF—TŠmh�•Îùe+ŒËäó{ãØÂòm9Oñ¢EÑÆH[ìF'¥(q­¤°Wd�·"¼m+Í¡¤+79,jQ4ü;ïJvacÃUÐ<Ò‚ˆ†¦é»U…(!J!v%3¨ GçÖábÉ`êé{q­±6–|!;©5àF÷"Ó´ÕäÆOt~As8e0 ÔJuY̼è÷ÛÑU¤¥RÏÑ|Vao˜g*ö­FZÕrMô‹¹7«–ÄÝNúž-±œ4LK©Õûñ ˆïßj8Ñ1©èÌž®­K×d$6pg#0@t•‡`µ?ü8Q0tL2AEù,h G :Ldbö Í{€x´«ý޵¯ ñL%Ôƒ’nRòµ5ö\‹k£Ãr7¶=­m&ÁoAÍêJ{,ò Zž”/UI2TÏÇuÃ-¬ô#P”ãÊV zÙ ƒ^ÈÐå,fîÑHWGÇulgE¤2S¶®U¬YlÎê¥ Ô7tp–¡‚¡‡Dõ8ësÌøåퟅ ™‡›pŒGÂê“�;_Ú±°š¯¨ p1±ÞÇm«#½ö+—ÂŒj‚‡4«"ih©zÎùšá êmØãÄ.]CÅ¢HÇx°CT­ìŠrü(›‘GÛ$ U†Õ†Ø WĶTK«É'+2ó•Êoƒ W % ·~жñRd¶ŠÛ®k#ªÖLo’†ª«ÖUÜ!Jå§+;=fxrû·Q(1à™/Ò Zu7’Õn@Ï?Ù "l'­žÈ@*{>¡SüfnÕR—µS£Á>Ýv@-²ãôñÕs+´j0ôôú{ÕX¿Ç?GðúâL—h!ý½£w,K«¼,fG‰hÌJ¸¶(OïÉÌlެȸ „ îe •¿Ñ7c 33�s¢k‰à~x„/™ºD ž&Í!ëØ€Çã…=™yKh%¤”=šÆ›^,NTÛ–Ñ—7#±%ªE]~¥fÆ¥¥ŒWYåv+D/s*¤Á7é•jújk]Œ ò6h²ƒÜ¾K‡l°¨`er;2‹ù”*¹8å á¿íÍ™Äm°c‚¶F®‹õÀSl4•³‰ŒèdÈ>ÿëÈ�‚yô)WÚêzã«p>w1ÓÇŠóÝþt_(ãnIKiÉ ¯éjÌwÂ4Æð¢9Ü…“Îý(¾$ð+¢xÔ‰pÌ*8Ó†D^/z d[Ä© GÕÀY J\ ávºÄ§LÊ4¢*ì¾µ„ø`ç´8K"pº®Ê-n1i4šOÍ ¨†‚7¾¿ã‰.zì„¡cf³’ ÚumðŒW©N*m­¤+XJ±­â1T…¨Y…©((^ W%òQç f–\’¨ç7¢Þˆƒjí¤T jm*£C!•pCÃĨ%;¯`C—O({¹Øx|‚cêbQÿ-ó8�œ°Æ3ËÐmšÄcØí³ŒµÎÖ³dWíß_Îöá�®¼°„zÞ->áŒYQ˜ù‹$íÿ ÔĽFËœu‹nùÇNÚÕ§„pB¾4iYW·HŒœÚ½„òg`4“6ɵØqgsZÐ#«„UHxà,ÊÀ£‘ `‘µú<9›Uo$Áʸ_-”½ý•šœ•ÊZµ )P$ºå53"‰ê®Ià…$"Ó¡Œú*‰¼µ2”Q9°´I’èÒÙ]jC©-I%e\ ãšJ72 b‰u¤„³Å1H)môoÌà&1ÌÅ ŒZBÕ¢}ãqº‚³°ž÷æùýn ³“O}H­åkI*¹Ðûö޶Zâ{ c9K<²NzYw[— ¤ë‹¶ %L[™Î¸bhì§”O84ED€|M�3ÅbÐy?ª~ÕºpÓs½l)i~ÙO§¬iVtlìМc£|}uËt%ê}¿ˆKY`Î&Œï¾®¤ö)8U3‘ì:=^&!Á‚ã¥2k[›ªIñv?.–T¦ªh{šSà©ÿŠa¯õô)l9ÃB’Õ$Ö¥ªü ì)FÍ*ùB›}®Ý�lÄôà,IVlž$‰!ÔfÅ´3%„04 †¢³S㥉¯­Iyü #Ö±[^K ·åL±$ê´ØºK}eº/ 0}p²#Z¿¤ÁÖ'•,‘ó˜OBÓ Þw2(·Ð£Øöc£_%wmÙrn6ˆU«–×`:#a«“AKƒƒÉdÙÌ„å^¿Ø¼PÞp’(?Ŷԓq^ŸSYT0 !ˆÜ? hÌxQË¥\?YXÉ”*r·i›^§VV’À¸T‚¶ ¼JBMEâhÈ’ÂêBÖµ•[–ê7àÔPºó¯qR~][a,²®œé-)‡´¢žêLtÕàñQ-6�ØûÃI‰^ ¡ÑX~M…Áq¦(ç>özoÌ+v1Wı¡ôÌû@v8Þ·waØã€[œ!\4¹ÂÃѧI)à³ÕØ’«ýûªkmÉâòèß­óŠÍf!i€–OÁwOƒwiÇHϤÇrªäœMxÓ4éÆä¹ïé1>ÍÖ ¶ðU4;Ë=§v4ÇÏ„6Y#¸BJ&æz”ØêüÊÒ'Q-J º–f©›5!x '¼o¹Rê´FLapL¿Ø`WGK þ¹ ýVY½©‹YìQ¢àyG^­æ®ØVµâLwйGJ6<¹éfrÎ /‘ÇAˆ\P�ÙÜG²Š˜“q iJ¡\À¼ŽØî߇ø^ûBá¥Y´ÚÖ-g®¿8Bxÿ¡£‚qLj¹³‹½¬Æ¢Ë‹·ñ;"†ÞÊj P=ÙdÔ±k•iIòýÚÊîÁNõÓê‡ÒÄ=”jA6×N#'æ'óT£>¸…ä]íÍF)':Þ`ÞøÑ{ cÏ( Ú‚dÐ ­‰p±ìökÑâºÔk]·þj丱ÄMª´Êú¦ÕÔà³²ƒ¯6¬¾”&ÛÔ]})ÁΊÔï&sOÖÊš¤eIÇ×a�ç{_W"¨Æ.ÕšH œÐ-u-¬°k<z¾_@ø&³šïÏL[Šï Kc朥Z<‘Yq¿Y×Ç÷aŠ÷U9:pâR%ø°ôŽÊ$¨··É£iñ’¥çÍ„Ë7í¨#8ÝyáÌî|ÿÏŽ}Hi]·ùlò,ð Ôls¾,³½îvZ§æP-ýz`.|L0x‹Ä¶;» HÒÂA¾\ê¾4ö V'çŽcQ�� �IDATˆ‹¿p±!¾¿œÊ”Oê>>®ÓtpÔˆY&ÈÕôOXP¶H4ÜÚF„°iÙ:G5nÇñ­�9‡qjß.…äëü¯yÔL(’À+Ç£°·V¹Y™¦n ÆøX³#w†ôW†à{ZmIXõà;D^뱨÷å Ú‚z1L÷2|¯£x6[{5}˜ðÊù~¡Gÿë´©ú´þ‡pa¤YdVòb¬À®Ul$ø-Ø-8+Mõ††r³5­2ÍêXhr2 Lß4ûˆDQÔ÷A¹%­ mÅÏÖx»l•i!Wgù·¥ôµi`w‡ÅW«Jç}Ó¢à{Q÷¢„ /“z…¤³×!­M­± 1ÏܦZwnmà½LqKÇz˜É¡£X‘†™wÞfÚÈÁÌl5Y"qÊ›q|“i#Wz¾X–16[YÄ õž“Qq:|û_2{-‘ÏËßXG¡ )˜¨oœ¸_¼ü]è6²Ð´‚Oæ‰Gu¦C^ÖšêG¯¾ðyŸIÑîë‹kô/ëKÍj ½À œ‹Aw^8FoTA¶9ç�Þémö˃¸žf ùñ–]¤eNª#u¢1"mš…M·7f[t‘´»:ŠÀ–·9=Ú§¤„2YU…2 Äß‹X§ÚëZt­ hvu›t¨h8 EeU]²104‚SÒ·*y’Z²¡U¥¤¦ƒ“ÿ¿Ç!w榺jÈ/û8³·5�׫qIƒmÁú‹Ï[ìA\[±áxi¼O½F{³„ˆN„Œ1/ú¶Z]©:\±úÂBž¶÷>Ùý’ïZ¹ÿÍK§€;% U—wË!œa¾<ö"4•™©€Å.B30Sµ@J{#—‘}¬G °9ˆÔ;°‡jàÅŠ+"; ¾gL*Úœã _dé3ÓÈ¡œ :›aëÈÈ:[Á¢*1ˆÁ ‡æ(exŒ&w©0ä%bˆˆµQÕ€œÓ*EIä‚ôªãÛRsA©0XÆãàÔÖ£”4rý4ä*êã¨.�(­¿®òËÄŒZ§ÖJƒ¾,Ö*ryä-v}j¨¨w˃­…uGV£ûá°ÐÝjwÙõ}¬?ðŸ²z ì›ûõê5V¯óώʼKÿJæûûê¢)·z ìÒkf˲éeå•ÓïåÑ.¤”·LoŸ~#ßU®½hà¿ôÇàßE¹ò]õ¼‚ý}ú뎿±�ô"˜Ï,gá1îôË}Z « à^\Ì'{ÝÒ‘Ü�ȯ̯ÇÝZ.'Ÿ:”+°:U[Òju Xeú.±’qûnuìDÙ§“­K¨œæ>-æÕEþŠ¼ë©·ì±:ö)TL+v:ÔÕ)pì1†|wž�¤ÓŸŽaúƒÛ¤Ër·^½N֦¸Ç8¤ÏY½žê»Z¦¯«Gx·Æ¸¿ÙåÿŸoV§õ¤+¶Ë§?-¶SŒx>L7nuŠÕ)p·€3à,¿å,ßÖóÍê5pûˆ]þ¨{¬^çS¾¼ÅÝøÏà œlp²Å=p²ÆððÏpœl€oàö8¹N‡øpÀÉx…'���¾;]œl°+§,ÄoÓOõ‘‹*•é÷Àóc:ñt"ë1�÷ù]µhïÖÀ+<¼>Çóøð9ð-à¿þø%ð[à§ÀŸ_��>¾>�~ üøð3<?âáð Àn8_§Ur·Nkþ «×y-M'x{ÀIª“¦õœÏôÚ¬öùPÅfµ:Õô™S¶ÜçÕë6ô�îò’¾É ò)¯ð}þ´›üžó˲?LÏmßNÿZÖ³|ØÍ-ð4ë'›T1KHîYùÒÐV>us¹°.ƒb+®”€Tn’ü‰:&SAÂy;Nä§Ù²o7C™ÕÝP'rÁ¿ÑüF†d¿ž¦£Z"#Òú“Ž!�çk{_vb7GÚú}tŸvtü7õ²×ë|ï¾ô¸=Ô¥"vù´5ïì0¼ºA7â¨`#AÉ¢Ò1ìÅÛoÈ‚¯OÝ^/%—älÚDò~q0¹×´Ý§3:ߪh´ ßMÞîu¢3ÅžÛCzñ©x¯ùÓÓ‡§GCÞBúd<J˜_½Æ룺Z=Ö»¯_îBÝõî1)zððˆ³tHé�¦#¼žÓIMßêqºÈéDžßáá�|�ïO¸[g8ßà|“5ðNÖÀ÷ñüwkœ_?JG²ðUþá ·ï€/p&"Ó&Þ¥ûr£°yƧ«|µº�nIJ¼îSš‚à|ó öÀÉwë”�ÀW8_àÀ+àÀçx¸~ œ¿þø;àû�€_ç°ù]à;À÷€/q²ÆYþœ)"ÞðpX·‡¦lLæv«CÚrp¦…ÁD¸*QG=ÈùáÅ.§POúñ”5ýx–å†¼Ï ò 8ߤë³ËËøØcõ¸};eKõ!ò¹»µyTËú¯ÙäŽ×m%ܰ´´¿PjoÖ•¸éÜÅ*±@wÉyQd´åw_< ÐáÜ7Õ’ºÖÆGù’p¼×ë²Ä%²)âtR<êhá9YìHÛäéãìNyk˜Ÿàì‘ S73zŒÆ˜ÁIÌï[2¤Y aÖ±âôL  +¼ölàW¿àB£Øh1À+a긩æÂ¬Ü÷’> ¾™¿&³PCÃ=`pò`Q‘ÄqÖHœÚT‰¯ÿ‰ V|,zZ-œ@ÂÏ* #æùhƒ²ZŸ‘ ´{‹º·ëY3rÔ=ºùñhe3 ÒØ_ƒís?ØÁ®Lƒç7»­a^üA»Ð˜ÌkRyø  ”Í@^–1xÔ¾&ø|ÿÝåßï ’Y¾±Tf­ÞL«ÚS¿<%‡*ϱ*Ù§5Ókh`«ŸtÕÀ$Í][XcyÖœ„ãdª•~³ß²«÷¢ Lõƒ¾Ý÷éQ‘/H™oÆîp·Æ¸=Ôœò»œ„*öQÉÄÔ=Ûúw®±|#òñª_+ò2˜à²‡Ã”§ß»5óœ0%CÓPÕö…ÈŽ¾=A7SB-Ÿçú$ž¥HýOêÑÐñÓMeY-&r:<Õ«×À™9*›._™´ûì€Ý„®q–ê*ì³Üz8àဧ騾¾¾Ÿj‹çÇ ]~�Ïoqr™Žÿd*~ðº3àá€Û·8YOàju˜ÀäòHÖåö€§\&ždÀöÎõ#ÇuÂýÎ7©[y²Á8YãálŸJÞRâ�ÀÃë ðþ Ïœßþøð ø#à¯?¾üÏŸ?qû6['< |‰{àäºØSEÞpàƒ1� ^s8GÚÖ÷"!»=¨~Á}]� ¯:•Ó}.• +ª³ú]*$Ð×SX±TPnP« à|=¡ˆã˜ËJèòWÂø;b‚8Ãn_.Äpìkfv_Fõ^b‚ìYp}æE‹§¾„ŽHH}Ç)—Ø?ö J€2P¨´3½ÂDà²ÑJºš­Æ*pÍ!zÉYKÒî°0ü<Yä§ ö;×ǶŽA‘Ã�Ö4ˆ‰$µ$û¬Ê\àW€{ñEgÉ8hrWý‰ŠVc…à¨&½1.G[lìëtmá|_«1áD·ÛŒã ¬Ëô ‰¿°!üûP¹�©8 »}МFi+lœÆ¤ÜF¼’TK]cÉ<g6‰~6Ž×ãøqæ\\§ÿòHtsr’š8 =êT‹) È(¤Ñý³…%ÊG7šì+Éó®uânNÚ,}c¶Æš=ª+Ðà˲†îÔªvÙÏ|µ Ô¯Û•ÜÀ[AÌ SEÉ"FÞ<Ë¿¸àM³èÙë†ÓЄÑÌîVé¡W*ɾ‘ºGÃÑe)p!z» %MJ6äde›"¹¥$ûUS-•¦Á+jÙ)Ï2PQ‡ÝØnm}ü¦”s<¦\2}{é ÜXh¡þþ ¸{Ü^‹{Ô$qW“Ê);žZ>WÏÜf½¨Úu»5œ$AÈc{8Ô&ìŠ- ~z×”Û¦©•õ:3 v¹wšüL[˜Úþ…V“Vo]FQL§<uÈJ‘—.Tú̯pw‰çwÀTl}øð%ðð‡xþ4�ÿø]*Ŧª _NeððÓļ¸[¯Rq?UTÉBÕ»O¹Z2=Ô'`‡©-”^y{ÀMþÿ.ÝJœM%ÈO§º#Ý—�âd|| øCà·8€¯Ï§’ø àKà·Àø£ü•¿Áó¿Î\’w8Ùâ<E¾tx·‡ZßÜd¸âT'Sá¸:¤ÿOç;-ȇCzåÃaZÀÓ­OW©°rî1FàáP¶ŽR«É59µ'%-`ZQ „ËÏÚt­ê>ðTWf}Fö¢ öZ´µnDu¸kôÎ[Ì Âåc|9!’ÍqǨ& ð`Úø‚fFF¨ëèÌB—ôã€ä…Þv/f‚ålÈ÷ÐPå_=ßÏà´­ÖT!¼¢G<¦´2L¶`dL«MVô7ÜgöÇÝÆ¤‡ËÊ">³'«XC÷šµ±S¼&Üçc¸É7ën“ö ›ÊSÔÁŸ»/GÓ1TTmú¡ð¦SJ†U~hIò>?Ò™ a�íra=uº×Ó-ó¸tºË; – Þî³¼üV‡Ò¨/Œ…^Ôݪ²:K2ºKo©€³ ãŒ8_OÀ`­WöérMèb �‡Õj‚õ^áùÏŸŸgÊÜŸãä ðAâà=ÿðàKÜ~ üç[<< àì ÏïRT¸}à|+‰š’õ—.þ=ÙþÒ%Jøó¥ºª÷)Hqññ|˜B߀óKœl€/€¯ðüø%ð€ß�?þ%ð øÏï€ïÿ��žß?Çó§ÀY׉’óðÏ8Ù”P”Ù:› eÇJAJáCŽR7Š)¢ï3îsäØç‡z¯ix÷mr€¹ÈO„ õ&¾è½Û|drs¾N êóëÛ‹]ýFå)OÚUÖU‡yל žÅ ÞÇàñØmÕ^^QñeC?¡/ƒ{Ô‘/’¡ =KøÙÉ­Žûí þ4m2¢¦BœâªÔªh9Ûæns ñ³"fÔt'Z­ á¶åÍëB1&­ij_K,=A X°Iáaf.^rÛ®?AU|øüVtÈ¡Ttþ¹g³nÅË )#PÁÍê* î*Qª2¡Ð¿Pš~Ì´8gl\^ãkf´/ešŠE½w:’O´øÅUÆèÞˆQ­«jž%ëdmí?Ì$¾§BDr79i (£mh[pã¥`W‚3o´|ŸvWÅê×x¿Jîymß~¤JÓ˶þþ'Åa[ÈϦ̅…¶ÂËÕ~²M¡Öò4VÝgÕÜgm g?Ü ¨¶x€*,E7ºZ58vÏ MDd#𹙫'QĨFnåeÔhÉW�÷à�f ½äI¢ˆî‘k7+‚b &Ŧ'W®!÷ú*ßUÌ–d»Ë«iDnz�9®›ý5ì¹G—p¤–Ï¥Vܪ)ã*ž»®°¨¤UÓo«–S$tM»lœB›™ØU†Ëé�aDyÏâz¯ÇñÍ8^å06ŧÏ2“ð㉇t¦‰ØHé‚ÓR`Û“2)ñ\>/P)– QÓj&€S¯Žn-Eí]¯ÏÉȨ¢[¼,bɧ¢³±.·YŽÝd;ËÃÏò ˆ¶ýpƒü}bÿò¦ã >Ç÷]áôôü¯L¢áŰ©-õNtõ%ç,„^UÑ”CÏ Í&°ít`âî’xíÅ#Wú°Uuà§lÕ:Boj‚4Ã#K®?¯W!œàé å*LNÐ7B4‡^xïÂx^Lü©e.õ•±4†a‘÷M¥è¶¸’/2EB²6%¦ßTþýÕ8¾É Cö¥,ÿ“ÿ+âLC5÷ Úy2h IpnÔ¡Q<ÑÐ]ø‘fN,Ƈ+€XÊIæQ«"'xXd:Òb-Äqžy!É¥f›Ò ÖƒÂ_/R—€Ó 1m3ª Ôi&Qª½ŸÆ54 ùC‡mXÚþìZ„ z䉷°Á%M2¯�k'a‡£ …é¸�÷–Kpç³üá¢SºZ=*ʬ¾¤+—“¿{Ý@ráJö5½b/ˆ°{{ÊwU Ž x·åÒÝ‹¹Ý‹:S)çÓKK¦ò×wBìcõˆ{à,?)šÝž†jw¢9$'ë/2KåBQrjSº\ÌI­c¯:OVÚj¯Ú„õ ÜäáßÌ Iã̇tT«CjzŸ‰¯>ÍèÓÚÐJýË}¦é‡Ü£:Oa¬tÑ~êÇLt€}éXþ´|û“-žiàôdƒçC"Ä?€W¸ž8¹Jý’©ï5Ñå“:F>»Ò­Ü;àù`æÖív1qǧÖÑíA±Z¦qæ“ žß_ã|||“m"rœ ™¤þ øKà�¿~|øûÀ�§À_| ¼¾~�'Üç{Q:=gµƒµZ=Ö§àTô™J¤ß+Í‹ºŠ©uZÛ«•ô¿Ç8®SÇk§w›ûÖ( Ñ“ö‚µ‘{·¥1¬²–{Z{[WáöÑö×ÏjËMrz}, çŒÎýUA C{±ÿVŸ Þ‘RìÐÖ_ÜÉ["TØ:�zÌKdà»\ÑûCÃE7ÔÄÙƒæ´ÿÔjÑy@²¾FÚMEÇ;wÂá`ndªPÚ(|è4’.”a )U* Øl 0—mr²þì˜í€bЙ -j³Œ—®¿ÚÔBãR ú¿è¤˜+Èñí8~–íÛÜšþû$ËœokOk|«¬²J=Mœ÷³q0€R<Úa«VWÅÓk¢°–…n§ã,r·…×~-üW¹ðºç¥á‚¿fÀõ)£õþ€°IS¥v˜q©¦¨‰íÛ±ËjiÒ!´•¯#Y–¾Æªï]Ân7\m9S,ÏYÎÉ.¬«<£Ï³æZÄÂVkjÑ¿oüŠH‹öõ»FéøÜ±Ü8šó¼;Nq4cÂä2îÕý"«pД¿Åáj"‚O_Qùl¾;å³Ïï¦O¦oU ðBŸÝέº½`'"²Ó¿ž¦Tºâ]÷bìW&Œe†q¯øŸEаT9幪_½sáaºÚçÛò™rËHDüÕ!‘¡Þ©ð|Séé©úÙqÂjLª÷'Ëh-r;e˜wúðòÌæq:—óõ8�wëªZ4‰NIúÃ#© {>L©7«Õ»1Öðo*³VIRMÇv¾I㟥ò;ˣ߻LΞfßJ‰ñ�¿>¾ ü àï€ü9ð+à{8y üÀ/ÿøN’kš¸Ý÷BKP2WñÎ×­ÑëÖ£½=Ta§çwSi•`†XÄ stªœ¾¾Àùø_2)À¿>�>þˆÀÿ ü øCà;À üx•Oö{À‡xxÎðü6]R—O???VRëi¾ÝOZ“ì>#Ÿ·u|~¯he\D!;ø>au‘e3§[üð8Kq¿ºH©žœs(_W»H÷uËÍEöºVW»t.éž-²¯pÁ`æk¬£Z,ó å¡W™aN¾Ç‹ãQ*ËQzH/ktÅÔ˜vj©ñ3õès|a¥E|«ƒ¥Š’h#‰4"„‹Ðt+´Œ³-àf^S<på!Â0¼­ð†ükhS™)8ù½œŒ¶ÅÕämR{õÀ¼‘´g„ï7ÓN8}wÒ½Ó;„ŸàyzÖÌW²ûÆÍ8~6Žoti’‡…Ó”î!‹þca¹æÆQÊjCJjêL?_ÊBTIÛè \»2I¤H.¥Ãþ,{9^gç‘u¥c”6X1 / >!¿-MbxcÁ× ÝR"|{Êö“Em“»¥ ཇ,±ÅM¸æÅË<ˆÑõÅè‹ ÌîûDzò ½}éXºõwt4p<¿9ary­¹ü²4‰—Â×À³·-¡©e¾ûH‰g�i)sRÓÀ‰ÁnµœÍ¸Ö†f7l,©×S$ªù¦6í±Á¤‘†;]1OKRõBNÌ‚sƒ ¨Ó0ôvtãøRt‘ÏÜÜL,l4K1™nW·™yq5ú&Àðã&£)a&RÈ‘x{æBÑ×ûäf áÑ%öÇ›Ì],6"W¾ë:ÿþRø‰Äø:Ÿ×ÚÒs´Œ!ÄǦt&çYÑ%šÁ2x=°.Ž„Š9ü•mÛâ`¹¯„‚4±†—Ę%ÿzleÉçp·›Øã ’<·á€>K@75A+œôšd¡Y†vŠ×޽òû”ƒöÔŒÉzà^Y„æîž1Ncm{BþÛa}°iâHù"ÓL_>ª$ÔBj5Ooì›v´lêd~vì¬Q}ú‚ ;r؃ÚqÔ½ŽŒFO!´rÑ%ÝÁ­“ʼJý¡©”™öú*€»© ½q;ŽoÆñgµå&嚤Gâ�å—جR´ÎΪV{×Êë+ÅÔièêãqm}+Ü–×Õ˜Xºd…¦f±¤Î$3²%[ÕÄzŒóÈñ ïmoÍ®¼Jrlxº¶5ÃÔœƒ^™é™wtœ3E¤Au&´„#&œxÌèw‡&?û¨zeœœÅ ûf`3˜çœ¹eÿ»šŽ·áˆfËyQ»4ב' \+/°cŽ:¢t ˆ)'Þ2#uÛ³®ÕÓ•·lxgñ°H¨ ª;MaÜù ~H•¼3ŒÍj`‰Bû{éxœ*YåøLA]€ùIbýlÛÓVþqŽL×jÛfîx1óÝæ cƒlA�KZ|Tnîêðdä.±YÝÓMöä Y†õ¤L4_çðRÚY/mQ®lˆ×~„ƒ¬ í"m³FYǸÊŽ „»A9Ó Žò>4‚Ó b’}c˽6Yc-ßñ[H_¶¨|6ݯ´f¸>oI¸šyAX[G1v_`ÁÜúó ƒ‰»w0.îOÁ’¡–·}+M]�Nê˜>6�À§)[½=õ®ÈªÀÐhùª±Ó¥s M“—h¥„}þk‚1ÇWÄGVUìy£°¾ g°ÊðµÖº-ò¸—±·èJ ΫwÔ}SU-¢Q³ÝHY –¶$7ƒƒ²7!JÀr!Q ¶!÷±.ó©]çB0^¥Jk[ã\Ô–(ƒ‹@N³bº¼…B·:”¤¨òP¼©Yc Óa/Ê(–m‚@Í%˜Ð1ÄaÑ^6‹øõ÷Ü£ôW Kìê;]„f­0¼œ=Ïwða&X>[Ã[³“Ý/Ô¼ð͛а‡7|k ªÇC&C3H ­CO^-#ƒ0Yº½FÎ5l8„3—Ϲi¤„Ul“úÐÉ B„Ã¶¹Ex¢ïDn�wx”ålwØ´¿Ç7Žo…�D™™½ÊTõA™‡Ü»Ê)z])ä­Ð'J¸ÇOR�0»?à ®j¥åÜF‚ .«(¿®uÕ‚*sÜEó¢Vg¶ý'yRø:×…ŸãÛ«>®ÿ9 r¼:0ÆŠV©—Ìž Ø'ðŒq® £AÓë…”W‹çåÃÔ§E—Ò…fSF÷Œûcù?†­ãÞçð}sÏØÞnޏ¦_óÃ0=!#å)ÿÚú“¼‚^‡ÈÑc6G‹†ÉVá›vhñ0nÅzGN„ï=ùpõâÝq«^gª¤œ¦wiþ7]äqSÅËŸEV5Õ 7I!;ðMN›HqgŽÏjìµ4û½ÖPv$æv(úÌM‰NdnÉúÝÛº¹ŽßîYZ0ÍÆÞ’ƼÐz—Âÿ�&3§4“»oÎ-¤ïÚ‰áè!Sœï³Ëó V‘z�÷vB?)ÐïòÀ/ªŸ²ä.'ª‰É-ìè¤l¢Î‰Þ}å^¯Nüðÿÿð‡�€¿�~™¬å>þøKàsà/ò§ÿxÂù·àÀ·€ïãÀ÷pàÛ�€oâüxü·Àv�>€ÿø�Î’ =�œ¯ÇÜ­A|Ÿ$z‹Ã/±_˜†”÷b‚øiºŸâùÔlo¸»Âó;ì|çk<¿ÃÉø.ðM`ºåøðÿ�~|øøßÿ| üSீ¿þ øž€;‘âLŒðóõÄÔ¯ƒ¯ÅúM¶“~­”þ§Ç­Úƒ]è1ö}]ðÓ€¼r".—"³ç¥In«ÒîƒV¯K÷.³{žò.zšoš†>«D|鼕8îû<C½·Þ=ÍY©%þX-@:óµ×î|`«rÄe÷%•ÄQ€Û [2.êN½€ÙjPõoÄQª¸…‚EH_úi0Ó!, š3œÓjRúi\í#µé) E"q6Kv ýЫn;ZÒ‡h¨X)9Q¡Žã ™~’Nò•òbfs5£hl) ©4y£q¼‚^UOÞijøxßÖ!⊳]ÕÊfjYÅBß ‹©Ü÷’üøÁ>EÝŒLIY, ù²Ê IEØ•R5¬Ý¬!˜ Û”˜çµ8—7Ù°øªRä£F&¢¨§½ •ªì·„µDÇ‚îªJV”ábx¥ZGb´+³õûmJ¬ìëuYæUš¨õ0EiŒº `½}å‡ôwÌ’6J%«ñÓ2Û½PõAǰC‘Å4ë¦YÜXO,fbRÒyûù§êÔ–hòšoœ^å¢U?¤¡­ ±?ÞœÒí½Z÷ÒfL­¹óuÊ¿v¢sŸ§n³V¿¶ÕçLœÈTœYìzÅvúúÜ×_V»“\¬V“î”bOf Õ,õIhní…ÕÈ>I•Ñlå¤k6Z¦’¹š$qTwlTߦâ¥ÒrÓ–'5M=§zqŸ~-¼'n„AÔùZÎ_+§º"bt¦aŒóµ…"µ¡W:æ‹|ü·ˆòúÊ3�ü�nßa2ñ}~¾>€‡·ÀÏqòõS@ž�� �IDAT1ððWÀ¿Çù6ÿsà[©ðº}�Ï<€_ádRHú>ð5ž?~�x¼J ûnçG<?¦Bd—¼öʇ":UŸˆ'�gi C;P§òâmÿÏÀÙjõœl±ð5ð€?ÆÉw[àÛÀO€? Aü <ÿð[àߟ㠫Õ[<'›ä+¶:$s“¸Çê4O£# §Z¹äLï äĪëÓ©xPow:ÓÉ[y¯7ä“uµ@–0öxgi¤ºTiEKíÀG‘ÆxÒ"<È3‰ÕÇö)½²þ_ÿùƒ&îš r­ûQ|«^ÁœNè¦LwÖÔmrhõceýîyFlN³¥¨ Á™ØYëý×Í ­vØ ]þÊ¢1W`¹À`2Û bB¢² @ZË·<”¤ˆ°ø+ONZˆ»ºñÉ%ž´Èö ã¸VÎFçy©%WÓ¹ÕÞ×CRö¡guο¾>V¤Ëk¦¤£½W~iƼ4ÉëÝ£:(=À] 9%d¦îõÅßC F†žy8|*þõöPQ é6$Wæ“þÀÛƒÚ¡Î*œ¶ž}»>_—·¬N'ŸûOÀ‡¸Û$áÉóp ?Éýýoòûÿð5Î×Àð×ÀÀ÷àn�€“78Yãá-ð}à—ÀOàdü1�àß'wÇ»Mµ´Ÿ¾î,ý?å7U¸ÏžE T_ã6©~¬N' Ã5΀“«”TlÓª;Ùàö]…¼n�|ü ¸®€o' |üx~”-(‚“ß�ÿtBØrõ8-’t`wk éIŽ´D3ò&1 eæ)zuÉø*æ§oøùÝeŠ“ÉÙí¡f6%æI•ËØšî»uUZ‘rþILUç߆öÉ+Á²<ž*ûlE,i`êßßÕ_w=¼«…àÛ—]¨výR¥Žê^@-‰;Û½wYTŸ”P)ÿÃLAÃ| èõ«ŽB iä^¼¨¹’\ Oy{=SÈRÊ[Ïô»¨ÒDUho¯*1šÛëT`Ÿ‘úrAVÅ#ÑëÆ*Í­³º±VÅ—è¾ &íÓ)¤¶ÁtwkU µÖ´€ö lÜë~RéWYÕ¨´eÜ0ì û??zX}ŽF8ª^sîI¤˜7ãݦîGfæÛšúRYÈjO_TâÕ*ëÛ¦ÊõëÔšzþø ç“ÝðWÀ·p²ÆÉ'ÙÆ÷·ÀWÀ/sèz…‡wÀ7àù-ð]<¿>þ p†3�ßž€€'<?|3¯ÈWÀWãx…“K<‰H|û˜ZYgÀÉ{ànSmKv2¹ý&¯H±88YãáSÜ�çëdºøpHÊwëÔí{šJ½¼ªyÇóãt")Ž>¿>Jíá-ðopþ&ÉSM©É¸©Ï…PW–‰; &]ˆxƒl{=õ&oeݦß܈Ä"Ù4¿MÔ½¾7 !œbU¦/þÝ·ÕÐU¯K=OP]·)ÎÝÀ?–ux–_–R=®ÕGÙíýb¨3(ÓyãB½¢%äìÎP-Ž™ZHö›õÀb¶ýQt¾…¬zÚ?{ßñafÍ@¦k¦Šï¼5ú#ÛB…Lh ®ŒŽQÃfSó‹Ö–­ÚF>-©Ž`›jõòF˼"-RjÆÚNZº–‚sž$L°Á:~IAUBŒ8?VYA¿d¤Pu¦²[^µ”.×n]Å^ë d;êhÿ\fŠ]!Á¿¢EWâ“LûV^$Á¬I;˜Á Z�¢p>£¦MÆ:h/’Êt¿ÎÝ»ËJͯC`C>ÇmUÅõN"Tj+¨~' ;OL×/@ùgÚ…dìµäŠMù%ÞšŠk�d±¤A¯š±D —b}¦Øâ☾Ú5y†­ª¨dI¸²õ œ›W^v£xe¤Æºè ùyÝDí¨óHg†]ÏYbší^"¨Ææã<…€ÝÛï­øþ^“únôÏ×)¥ÚU¢]CÊË]HPõ3¬‡CJíŸÔÕN‰¼ˆ)qóêY%Í>ªæxí ù âÉnkjÝïs¯¶ O•{ý8®[«T.3%?ºWªú4Ý>\HE µ`Êøg:¶ÌÈJµ÷:^Þ(˘t„ûÚßÂÉZB…©Su!ªÒ É»?¥Õ)ƒ~~þø)ð%Î�ü&7¢>~*ž‡ðkàÛÀçÀ€ß�‰›)!ÿðà{Ào€�ß�þçkœlqr ||“5p |ø{À7€W• x¾ÁÝUÆqƒómÌM¬‚VšŠÔI*÷d$}Wœl“ÓÇ$× �_áágǵü�8¿®Ÿ�Ÿ_áù-ð/€o¥âø x~=•¶À·–d|Ïò¾|Ÿ¡¶AäÛ%mßôàœÕ*§<æ©Ò-mË©v¹ÛNxrBÞŠŠñÉ:Y{ìu§ê"·ÐÄj/«wuZÙ€éc_Ûì0yДúõ&£²¢Ý ün3½En³¦g4ŽÛmi¡‚´ïÒbúiߤExt®5/U# N†alØ|È):*'øþn°JÉݧŸ`Xþ­:ŒB—Vß}P”e›:\:»ãÍûûÕ9ª%},ÉÆNûã©è±Ÿåõ]Ö²Êk7?He .ŒêâÞ¤Z§Ë–½Ìí.Dpò±yOV£RX]uÖSx;½ë»5΀çÃê5p¾)Çãé?“ù8Ô°žæë Ñ�§€xŠ=lî‹lò B¹$8¬^Ϻ"IÌéKO+÷}õ¸[WB æ¦ÉtS¯ñáP`Lã7&dÙ&¬·u—Ô×à<øu²€Â—x~— µÊDøxüQò^ß6À�~ |üsàïßþ°ËÂç?�Ήï€Oðüˆó«Ôjðð)Î×ã¸ÅÝÀ×ùÀ’ô¸Ú&<Îp<ê¾|û.ûçð*Amû‰ñª4ùÒïñÍÕê¿Çó#ð�œ\áá_ß>OIÀÉ'Sà|ÂÃ[<ü ð£šÝ YsM$õSe;€Ûw5Ÿ»×Hï}†Ý&RþNضݾKL÷ ˆ9È«ú¸Û¨‘ Éœ¥µ7lZ�· ÎÔsšö¥ á0·n8ßÔôt/øÅ÷kRȼÏÈEm÷¦ìm`Í—–?–!ŽÏ"uÐXÍu¾« ¸E¶Ë7Èëô{;ÈÒ,Óý(šøK8ë/ô<¸÷â°’*ÌÀÛ¨À¡R•&)‰ç/Ð4¡7à!=B·,p‰ô»ÂåùW«+Ã,qát¬†¶ºç©–¬ì-‰¿†1Ró¿–~C¸„;ÕÅô¡hœOh[+*L÷ë4bœ¶OÆñ'ãøVøÍ_æqã^åßLV¿Ÿ(Æу—RƬ+:ÜIˆêÃÛÿ2gDc—4ÖZðŠÜšàíǵ'A-¼‹­—€þü²‘ƒ½�™‚ ˆ¢|ºËgÆF;À€„OsÄë¦K–ÄxçuÛ<ìï¼}L¬ß¹Y"[¾DåË4´fÂ:¥@ÚK"å4ÒkÕìê…öùŽxõ™" !�Óeš^$¤gffû[ZPƒShV¬ÈÖ¬…Šaf$œ;/ø1Ä¡íîÁ$«f µ×*4µÀ…B¬PoÔw'’{Ê… ¼ÖŽSä}ÁªÙºj{k%5T=æ×¹u-‹\ìu–é+­¬7ãx)´3.³:ÆåèXÚf*^®µ®Ò¶ôçLVmEKäª�.œW¡È·.óé\Õ˜‘ÆÈ²LÆ4•eü3¢VWu°Û=éiy~8í£XOžÃ!Zk?¦· çë(Âç•eD€Í@ºÒ,SišÍý;zá­²”’ÀÔWûŸ9S“-¤ï“Mæ£ÑðÁ¬Ù‹<­û¢p/Í6¸íVPO‚}eÔévc2¬•¤£e <Ää¡áèCÅl†ÆŒm`"ƒÓ÷ì:QqÂV3RFkBÜðiJ ²³´@$K.¸¯3#Ɇ˜9V¡ÚþQ+º¦Ùb°»©¢‚QǤÅ'ÄÑe„KãÀ—ÂPj#ÔÐ×u|X 2§AÉìŠhº&›˜WتJð[›‚xMôâ’%Ee©WF›ÓŸÈ‘^ø£«Ý¯.ϸŽmK߯kdxÂØ°šã6²¢’‘ÚF\°ñ$Ž%Úí³þK6Á¾ý’éy̲þ^„k�6¡È~@ 8{ðKÊ\À¢jAkèNáo÷ëH$kÁ¤©<Äð¿/¶Z•Ì^¡µÝ|!á@aÃLh�zŒ±í�ÔѧwñÉÄQÀù'ùª¨!jµÃ‡fêa1Àż˜Õlkm±®ÐVö ÊQg›«¥µ*ø&l-ïÄ*ú'"ÖeJ£vS…Øk¸Ú*eôh~«6Ê´¢õHQÐKáÕàz-J¨µá•¡:hwíwêkq—U\Y9i­6b–ø¤Þô`¾*ï‚. ”•Æ0@K$¹i“ˤ«Åò~QuTª>koÑô1ê &õÚ Âò£âb‘{âÂ_Øá{q”}¯˜Kêû2¬E´«“rÇ#<;ŽÓaµ‚N«€�šMZµfy �ѽ&4€Ê¡í=JªI'}¼'¤|EDÞ’Î¥l ØN«bö½ŸŽ ¥.Iä š»JTui–Œ¶ìufo«S”ì—”7&°q[y �–«zhå"oP ž:÷Ý>»›Åzq"0 Å笱êR™,ç~^eðS7d–E5ó¹A P Ö“šø–M§e¬ª%¡¦ÌR¯«OÀRòqð¢Ï ân°Ûg˜r§jµôÓŽ-°–MÔÓ} (÷2s^š†w:^¼v ¤X™”x¿A«åñÛ£^•jM/ ½¼eóh«&ýÞ-624Ǥ�× c˜Äf’Ò!EÆ€*½å§ÙÊ1ò™3zÇ%€žG}Y:lòeß32†ù‚\¥É$ã´T›UÛâ?ŽCš©’›ìTÐ ÕM1oµWYÄýJ„.(FE°v'¡$1TpS ‘¨]ž¥.eÁÐôàWn° ³Qz£l2Vy•Y'—ÊsÒlè%rH_ÏB) I`¬œ@HöÖŠ8ìÌ®ˆ´¼—â4¨` eí“ixö˜«3¨‹öp"wgŽÎî_¶/©ðšÔŒ8ˆg²L÷ÌÀ.<;†/K¦ª›„͆à™) ¨p¢ã»Ñhç´òÿdÚ£ŠM–Š/ýelÍü’J%6)yhØP̰EµâLŸÀª«è”pÙ (¿ ,•ö µ,TãP9_\e^ßÉgv_‘‘½ŽÃ?I`—s¢Q.MÕÍd«¢‹¢c¬m‹Qù¯‹iÉ%é@x69)Jé3íûõ¦NR§qéAèü^ŽãgªÉY[:Xf«g¶p ŽtR#x°Þ­¦k ~f ÌtÍ;’ö •.²K=øEµÌƒxF`XDCXh68Ë?¶š -4!%­þÆi¾kb§×2Ò¸Ó|«ßÞ÷ðHÓž©¤ƒzÛw«LÒU,ÕÍ·Ä=VF~ö.AC/&ùÊÒ<áÜŸžrS&6«Ÿ�c‚®`ª­^œŠð×ξvè­jK.axÒà³I°ÇŸ$Òy Q…Ú7¥ó¢q9Ž?“ TØFTùenA{Þûê*³-"6Ô·ðŠÿ¤§Û寫YŠI×µ¢JèߦòGRÈü¤‹Ñ¹oŒécr…Ù"xp¥¹) ãúΕ¸`ª¡é‰ g€@�?¬âzf¤ªSpå‹PA´=ãß³ÛØxÿb¡‡Â0•’ÑñÙ;R8ÊßÅ…ü‹&5üHiA^061hfzMhk`K°Ã�†¡î[VÞîÄ rª±Üš^ ÌT~àx3 ¤?G®L Y-A]ä³è–qk÷ûpH«ŠUd“ •~ÌBÐIw•¼)&µPñÒ6Pò#¢&yš~•„UVXSð¸¢gW¯°áF:‚¸%õÞ£êGnÔ{%7rÁ¸†Û+ËâiyܰI¬Â~ôo1cÍ…˜[w`ÏEÔg§›^4û±9kÔЂ†UMKÛ? Çõ±:¦“8~¢–¢dŽgh–}Ì­U,$îcµ·ï…DÖXØQô–4g>YÒ¦ƒ³Iš¥^ë.ØØÓµLmñkü hÃÖV3¿r}xsvdA¶e‡n£®¤ö~DNГývI ÙèF²"»àCÛa94¡ZÒÀo3­íÅ¡µ‘M——Æç^¯•ðsº$ýšÄ<ܘRÌvdõË §kŒy•iÙU[¹¢Ð¯1Uíý4ééÑ 2€_;s¦bΧ¯ø)C,!S€AÛnµ¦ èð¢V —báñl³°ÅB[# ßµ¼Eöǹ÷r6A8‚bnI¿2["ž‹9ß,`‘ôû n}eä#>3ã_2uˆŒfkbŒÔšÜµ$?0Lß­ÆNÀxG—W΢Ù-²"íšôÓLlŒªTx3õÖä–-X'ß÷-ø3š#ÒvS‹ÍÎ A®ÆBDÙt“É ?ÉOSÂ!ëÃÚaå󂌹`–œ¢ÔVýÖïM´64›fVR K ~äÄ„Åcû[™ ¤aÌg #ÁÌ·n£MŒÔ/ž FWÁ}¦ÅuL3 ©Q(c9Iä(ÞÄìÛíFÌΗ”€G™ 5’õJd$¢ žb§G‡†xëÍx/»^evgÐ-Eæö¦×wcëÂFs‹ù!ùNu´Wà*M€jj/3tÇù­">•„\°ÊÝ'ëx ȉˆr%èúRÌfmdSʶ¬dÇ.ál—DdßŸŠ rœÆƒ8´EÊ)Ñ?2˜+ØÊFe‘‘8¨Bߦ€Nø†f'Þ6«ÜŒM }åÄ]¿¥Â®¥ ó'“_f~žåô#ÖBÑ>²Žà6?9, ³ áÿ4ÒØYîC¿o×S9Ê«>Ìg è*¿õzáˆÃðC-‚"±h™Ô'»a‹VË(”²éí dqêPJX$úéjÅQ.rèÔmêu87äˆ뛾£ vvºV`W~Ô03´ÿHwDtGLi. eTM`ÌãEöÂ>—4B9&!DÓ3yC`ó‚‘kIð7p’›!襯 ”Aê§ñÈÖ:¸úràMS AË(Bçó"ëM²rÓŠ¬F/QÇq‰yUç§±Œ+84Hg÷D[ .GêðÜÞŸ¦ÑÇúá~a†•·h¾=ª<Š yìÎÌÖì5‚8ZAAf8ÛPÀS”°4DZI!å¥Bƒ†äõ“üÄhh–›„ÍÕ‰èq1è vljr<(0œ3¸¡™–.Žkœøtž´sB½‰ðÚtN¹3ǹb¨Z'ZxJˆGl•”àG‹r|­&±‚¿¢eÊXuЧ]¶1°•™)$¶æ 5‘di­Fls$|psë2ØG ÷™;b/Žï®Q¶pt‡á„r(wQMD}< •pé“¿|ÇœUì„ÀåÎX6ÛtTÁÑë$9kÁ%q¥Õ:6uÚ?³ÔÇ£ê<µ[JT%Ì£O´Çcaq#Ê9h¸†2­ãL÷¥5¨GÚlÞMÎ åXÀ$ètÀ–i0l$sèÂŒ¡ÑÃÈx™§)šˆ¨‡.íÐÇ¡Vx6í“45=õßÀJŠpȾT¨`l¬îßô– ü+cM§=ÕImopneÈDèÂVMcl³+…åovv?bL9„d†—†aÇ—1ź§ÝÒÂôDQȃä~8–y±|ãXÿÐèÜ6äÏNÏ’wgIáÔ÷ýÉ„GDÓ0[¼ƒ£¾ýzžÆJKº“&¼@mFºŒéF ÁÔoµÐJÁá`ÅÔ –ô¨r^OÐc#­>“­‹j^6»Bj3€u¡lØŽ.…§=žÈ¸šZÈÔ¶T’­‹@È5˜’ZM¡þ@è3rvXp üEãM¨T9`¦‰)wT´[üËÌC/r/?*Úi^9^¢íAƺƒCY‡†¬Id{QlR}>§%=7½ð“aðjœCÙVKÊ9ºÄåNPgUsªÅ<°ÚÄ×» çÌ{QMáÒ¯­C±ýkýÆÐ°H¾¨?›eT­÷õÅõàC³Æò¾ŽrÛ•gáÿê¶zÕ¡r/lØ`š­¹ºèf£^ù Þú™þ)§™®ÉÃÁÞGaÂ;¹ñU¿Ý›täé„ÙîêÅhNÚ%OMŽp“Ñb6TMN²eQ݈ ¨ËMœþjãÇM²†KdÏîѾ:=JŸV Ü;D{ÓoÍmª7úöP¶¿äfYlgoõ²¼Î¦ÏùÔö|¦C=«öÁÕ:9ÛŸNFºÕg6¯Ûô°Œëäf{£¯öt�«ƒf!Ý2‹#åí!a6ŸT^ÏÓÒ}ªn„«Õ!6² á °Î&Wåu2á÷�'ŸI<?¯¦WŽã'›äRÛÃdªi¨½2Òœ£ØéÖ?'ëä–ûð˜–úd8(Õôg—¬/ÓR¹Éù̱vÉ\8=¨{Îd™>ùᱚn‡êhºZ½-Ï™L¿[Ï䃚Ü&ó†v*–Šô>Ý KUY3<‰ê 8Ëûð.ûË¿æ}{ Ùwq\£ØÀîĦ´ËŽÆrQ=eãÇ}ÞðCÞ²M(öùe÷ʵ5ýñÌ‹…Ì‚%$‚Ö\X¿>;–¨íf–TÇ2 _Râ´É^)œ[ï,¶Ÿµµ|££‡§›€×«¥Ãù±)åçùN”5` mªU³Š d¦åxb #TàÜ$øѪsi¡eh‹ˆèiÐ@“ ®£îo™QÍüoÂ? (–fQÑ‚³„é4Û+Ælë¥ÛÒÂWšCÚ¦]Ìòu§:ζ— œ÷›¥™DGó“r¡¡™ä¸Àú@‘X™ôèÈ—ts–T„c–4’Ïð,y™t í�VüQ^;¨ôB®à’¾Nç/èóÏ’ Š{Ks™º ›ÝÙû1r!K¢)>K<Â)Þ—q.(BšÅ* 1cËÆ•M rêTSN>6ÀÀHT´5kg9£ë(ʧÅгpli·~”fí™͹7áÆ5ö’zÁ#-c˜Ê.öº]+÷BŰØ@•¸zSÁà&‹LtVÝ….NöþObÐ0 Ìn$T‘VC‹j`’amc‰èŸ_WroØýHæÀù‡061¡—˶=f]qåÆH‡#4/ú¤ Oʸ!:eŒt&%ûM²£†š—Ëû Gñ÷f}gÏbÑA-°ÑÎó˜hQHxm=«+†  g]7+øÐd¢Ú`›ì >mšÓ Mš\›¼ç÷x«?ðkR‡FöZÄxspÛ±§¶}/5çb#4“.¿?xràVæû–[´3Y%l8IÒÌ™ l°²Lª¯Fýؼørl,ÅhE¥*‡j¨6±•A‰öe i ÄàæØnxDi·M¹²Øx‚¤ ›gަ´}E6F…¯yÑá\5­Z_:âºr|±of¾býë°Ðfá·¦€ùÙˆ»|v­—(øÙ‹†Å5o±üA%èÕ' \©Uó°mÍœm<Ú‰~Z ™'•0yS S9p )Ó�0v“  œS” Ð4“žó©Œÿ -Š5”™aŠš ˜ ‚áÕß’mÝ%OU6MS@H¥Ýk—š™Ê N–…¯üà‰éiN𡈴M&ÚijlYŽ”DÆoŠ ]7ç³Õ–¢4Q h$Íÿ,Jh^´¢¿Žá%ÛbÓ_Xß,Ô@šaÇêù.±×Z®n5;|ÔtAK¶ê(Í Ÿš1ûï­Þ±Íïh¤I=î˜=#Ç%q 7&~„‹†™”“§š¡¤ŽDMc{¢%ø8p‹nêw"RÑQâЄsÉ÷­¬Á8kM?fÊœopŠÉ fâÇA›ÄĘ™ìÈ ù¿ØóTcÅD‚v Mšat¾~ æŠ�ìüµ0h˜Sê 4q˜¡°P*¡ ægòˆ"†`_àµDÑ®ßèšiP-ëŠù�ŽÆxÓûˆEu”Η‹âøùª¾©Xß ev¦ûØ|‚Û3F÷ì5¬7(®+-3à((Æ$¸—/SÛ®áRÎþð4Imx^?4 ¾èØ„»|NP/š”am§ Ô•ØTÂE_ð:²Ô'ðmT‘õƒÚÔÈxlP…¯çƒ‰ŠRR”O)Ôm•jbÐcXÛZò¬.¸i¿Ÿ) áLŃ? ˆ–h��[|G¾€ I•ÝÛó³´ŸdÕ±ÑZ6“žÅôÜ,ê`¦Ó^0µpzwVô¡_dôI€/æqÌþkï¨ÂÒ`ܤ¨µÕ_úÀ%/Ãq°ç±áÓjìÑÌh­ÏzˆèÀE\¬òÅÀ¹ž”¸lŒàNZÁNâ ü(q$¦$¾VC{\í;s³á¤M¸uE/ÙŠ|x«–,. ™GpN²§’Lxךþ·­ñ›)à)Þ„Wš˜fq€ ]C»˜fÒS€›Tk甕ÄHµK¢s;”ÞZÁ`?°EjTÍ9ÓR„Ì­D×í£Œ›ô®z€Û‡†{xhÚ­”Σ‚~kžy±<Ò4i»‹­¡È”_˜aa,ÔŠ¯ÛB´Y o†^•³´{4¼W¼yñ[l°Ôs©všaÛÀŸ-y[Öï-#y’÷ySŒB>n šnyl¸ Ç\0¬Ÿ/“lþÿY{wI–eKÌòà ]Ž–÷#YIÈ�� �IDATJ(b:ÿ G Ò(Ú�Tïh©xM•’üj)‡vþÀ[(¡@‘ I€  A ô­åá{,³ðȾ…ƒƒÞõˆŒðpws[¶l-[ˆ‚´�Rð‚v‹£`ù]S›E/fÔ$›‘µ<$ÁKgò´’#ß œáÁ‚“±IÝ tM÷<Øt*åäÆâ ¸ cLnüsù> ,Á†º—ä4Û©·}ÅjA„/.ok2Bjÿľîž"­wäw›pü} ŒÓH ˜q‹ ß—èhTØéˆ:^$›g‚L¦­O0Á±´ ^x•l0_PY…—2B„,±;»mä¸kj1;]f,+/·ºÊbõ22îµ²{' ÕÖ½xC°ÙˆKð9…wEì†`‘[÷Ê£n[ˆˆèñøÃK ÷å¸ÜFë°VŠ™ífW†_wŽzò} çÕ™ B÷5“gWUY¨;R(„dð-!on\ƒêCà';È”° $8v#Vä‹ú[ƒtï(„Xrt‹‚ó•°y…G¹öN¯QTËJ¶ `z±cžVÂô,ÖnÔoäAùŠÇµ_VñåjbtšW§=B„WÔ½2Ùq%MŽl  kŸZžC)Veôv–„¼Ž|‹m�rJÝ ûé¶®.öhn\°¬‘hΤœéµ  A)µü JIõƒæ$ß@ •JT a¼ °] DS™f&‘Õ…˜08^$p掸» ‹Há9ƒ{õLḬ—›íß(âít‡gú±æ {AÚÇ3Hfä*"¹9'î]¢ÄQù¾?·¶z‚Î7Ëù³* Žˆ €)Z±„Z’Å=(Õp~èfGlX¬‚�z°b¡ú™ÝÙÉêm‡1Ï£>{WÆbŒVgÝÓÌVªw†e F‰é†c¢ïJ‰—g½T6HE6Ør㨂Í]SJ0:Û° *Q”>ò¼ÄÐüpàÏ]„5׌°_KRv$Ù±Å)ÒmÙéÁé&=¾ö‡�˜ÝZöoÁÍתG˜¬ 6Êñ 1³ò\?Ö ËÜå½Qs§Ø /¹lº'Ôž« ÍSN%.3ÄÈ#Á™lìyòÒ,BÆìÝd|Cˆ&”¿UχҊMw1kˆ`ÅÅu|×… dKÖÐ/£ž:§§ T€%‘r¯,Ú{qµ‘a‹‚à¸5FÁU7•(@6Í€é†Iã £˜Ø¬ -)cøŒ,qáY‰rDBö.\ÉéñŒ¹yžábEÕ–OlÎÚ0 ƒ^Àù�œ2¨"Ûv8í!2©=†¬ð´Óyüb–r“\Á=Õ€ÝúLµ&n¼ué iŸ¾Lg*Û-Ž:ÁïCðçh¶g+±m†vËŸÛ:m*Ñ€†Äö,øÖ<ƒ]Xò…wÌ\ðvœì6zMcÀÓAí;Ž‘Îˆ°è˜-VÈ a¥ 2Zéä+B$S¥SDî\µ•A[ÈÈx¥Háöf4¬AYÛzÜ3I”?C›D+úø® ½wÈÐ53©°GJmÄ=v\xÓge#Ù§;…³–oç<ìÅѰ€Lò5X»÷Ù KÙCüL 3þ$.®Ãä¤?Ö!nÞ¤¡îUÆÛÅ÷fÊNO ŸqIÏ“¿;ÊlÄZ[Óª¾’Vªâ³‡[º>~Û£{ØGæŸÚ=!EÕSeä]áf’†b2zÀý^ (™ ^eñýŽ 1ÍâfŠÚàç±M¨y~¿ø<¬ìMŠT‹0}ÜV¥W¿,i tu³ëþ.²Ì¦ói/î“&ǰ#£×]Oϼ t‡aþ —…ÌX9W‡ÃÂê…§;ú0jXN ¨gÔº ñ|ʱ )НŸýBw¿i§¨,BòÝÐ÷Y~w”m2  )ŠÚ}ÌÎ’ÂM©Ð8…Æ^G“6¼Õ¦‘«DŽiVeí%Ӭ׌ë*™°)°'{*²bÀ•©Uq1Ø™D޹×åFäÃ’i IzèˆüqIöºåj)¥èæÐ>œP4 ݧl€Ña¦€¢¸íbÆA ~²1œLþÊŽ@¾-´fD@ÝC·ç+ˆ5 CO$å¼`;°™€›-\ylX Õf¡‡âd¶zÊžîˆæÅ sÌ£$Í—¸¼(›åýÄnž7¿«¦“e¾Ò[ebžôü§ãˆ["©ÙýcA›BR@5îdŠ0+e—Ñ É†U,ñ7¥õg©pžP¦J’°�²vÎÔ*=V<8 3Múi½�Ù!SŠ#O›ª°0MŠÂö)¾aq“Æá9òw02ªEucrtÁ‹SnÌ¡éOvJeUn²ÌÈyö“„~„.ui‚áMBr$ÀœÚîSsÆNž‘ké}éM¨¹žÈɆQ®&dº2aUmò=D)a<Jjˆ³Š�©óøZž*+…K‡$ÞÉ×ñ :užˆ¾“!Üc£N’) Fð¡^.Íâõ¸O “2ˆv@9½ÈåÝ!¹žÑ1(!h/yŽ!ƒÔÐsW»§¶ Wʇ)â\hj™ßRfÙ ét–Œb‡÷¬ìÀ¤›^{·Õ¾Ã]Ž}$|ÿ½ ášN;{€b¥¯«²«e7ÚP¢S¢¹þ “ËcüoØÉ`õ¢lk°´Åy<~Å¿þÉhéfßi%;G¥„[’ÝótÑäýж–•Qi‚æ+ÐAñh©Éãáåûá :ï¤Y󭵓ÍI»)éÄ"ŠÄ™æzìëñwFÁA�".†2T&˜TžP‚ÅÄ=KOëÏ"˜ý!iD×'içÈ*´t• Îå ¤0‡Îèì™4@D¾Ò¦-3è²Dß„x†½g=-±&ÐIME!D¤Ú×®€3¾&hÀ\†ØŒd/²P6Ò'*yÿjÄh¶Tæµ”njóœLÑ‚Š› p†¡Å*I¶ŠÛÓPVKØÀæµâL£ìU³ë° H:› Ù2Ð3J¸ôT;êRCàq0KÈãPŒ|†€çÜŒJ!|3Z½D‘ÿËÌÝ5H",nC¸Í¥ÔF¬¨0±Æ™Ú¹È÷¾Áùää¦É5Áƒ, TQÈ2ÅÝ`–e¤ç‡ÜÙg&Œ7à–†�%½¡P؉2à%ꤼ�µ: éÙÜd™ÇPÛSJĸ¤WÜÍ*+*´ăŒ!2…³EŸiôäLS$+؆=_D®Á:¢@‡š ˜bŽ(ö¦=z§%\}œwðغäËÂu4¤cg’¤]ž|ïÆ0OØÆ£\N ÌO&g3}Ü"VÁÛ«wòÂ4Ï>8¦®r®{íAxÀ Ð,Ê·¶ó\‚srÏ †Oäèñ˜ª8ÖÆMÎkò˜žvƒq†´WÓOáõ†g§û§ Æ2ʲ-JÈ·Â-œpÍ æä$º”˜iYÀÌŒ™®âTÄ}G.¦Ã Y#ê4½0\±óMœ4 |5t­K­% ¹ä’E‹>Ò‰g˜€ „‹ gW4R„Þ2—cÅ)ȦŸwâ–N}ÒNig~[ª ÓH“wï#Oð,ÈcŒ `¸G2c‡ø'’TÀ¡°ˆ[lãLçiÚfW@ø÷ÅÝûãIÊìÆ“‹&>x ¯Ä.¾ÉÈû‘¬xá‡ê䈂‹äµ£û%`”ž^ÐÂÂÒbXÒO>Ì~Ò$ÏlÝL”¼¤…vJÙ·‡¶ÖY’^�Z�ð ©(ï¹IéÀYB¥ñ©"ã\ƒIm}Ä ò¸’bíš–¢šÐ¦wjÉA>a,É3ãˆõO8¢¬DD§O1SOŸõ;§ÏúÍíýû´¶ÑmLˆñÍí:—ñWö§ü¥öêç}ñõkÂëó+o?å¿o¯V¿¢Oñk§ =2.à—ûm«ïÀëס¸D¡Žÿ~)u�Í7ù[8}Ö·Yÿñ¹±ÔÍ÷K= ^èôIÒ^îB§ ÑçˆN/ìŒò~ß>n{¨zÍv…1Á¢×ö4.ø ¢… Ñ:¦âöÓG{¢ÓeüŽÞ‡œfjê«üùëtúÇ#ÓãJôã|:Ý·»:]êSœ>éA÷í¥ÓRorû)øÐþŸmdê÷¿ÛwÖ:[èÆ{´úÓmÞïõ»gú}$:½´‰úx£÷¯ú˜…N§¯G"º}­ux·Ñ;½´QÚ~ú)ùtä:˜õ«ÝaN§ûãñö(_t#ZÄZ¦…èçù‘îõ?·'ú}ä:JvðûLض¡íGÔÞ/ß.^ÙÊz©C4j›Æ3ÑýôBÇ™~ß·¿Ú¦ßée|îéóþHD¯ão·ùF¿¿Ô^Ç—^ßÇè*&Òøú³ôt¡Çµ½»þ>,Ýëóæ6ñVz<ÞN§v¿ï<ö|<ÞËטù×:úwú¼¯õUŒ¹xM™èFt%úq¦ß÷ñšVqÙVÁX’…èÇ™Ö{ÿåzëW]‰z<Îô×nDk]òôZgc ï÷ñøßí ~¼Ñúµ½²ú£ÑÇù‘îv'™Ï.»ÝKŒ< ð ïÁî|ÈRÖ“f™Ê#eÎ3e†k@Ó½M3lŽ˜{²oE–¸¤Ó|sdÜÑP‡\Gœ¨a®ˆ¶ÙËqxÀ ÍléÅ:œz6»~L€jÁ˺âe‹@›;Tb‚xs¢ÆØ/Ø' ¸¦D>—¶Ý]“·Í³D]Ì3„)¯ ŸÊ–¬ uÖ9œ2ß2}Êî„/€@L‰L?²ÖÉýž=;ŽÞYó,”êÊU°Þò2$eTד¦ÈF@=c~’(¦Ÿ¬LÉ·ó¡Ìùc¹’ØyŠríM…"\ŒÔ­Ä¦µÇG˜¬ć/`÷=ׯG ,{$ãB±TwŽ ÙeÒ [12¬ v(ÑŒ' Œ”¢nÂ8"—•k+:ªÂ#3TÖ*+S¤,¶dCr1|#]JP’� ŠGV)ÈÙ b_ªâBÖå¶� .žYk˜ìZ³c§1×PªêpY ë ÏÆ4<Öó0 ™ø^r _ h�…@Û‰%bá›ðõmw$›°š>aóé$i‡=–ëoÚ� ^]�¸—Hq`Ðî¶”ÛMJ,’62Ǭ£ˆüV;És¤Ï þJâ7ámTã#P>÷ã·Ýïê‘ÅgyÕ2qÍÜòt¹giøñ2ÒÿÓçlÄÚÐ?ZÆíÑÂÐ9ör�‚¦Dó¥á‡l´r«&ÃéeÃêô=î§Ó½ÞÿR?} ò"Þi…8>+ÄTïg¨Î#Óétßî­ÞäÇ/õú¶§ÞÖçét×[g‹aoÌ™e [õš/ìMÝ$¤C ºé(Ûñ%~¯€dGÀ®ó£ôRgÈv«§Ó}{)ìýnÿó\?%݈¾Û4èˆe° }ú¯©>Ý:†w›`ôÚ†úfÑ‹,וqñÓ¥!‡ŸcFm·}z!Z*Œ6¦ý†¾60™CgK ö*·¹úó­æöÔ7xì…ý9ÿºÊ üû.6Ã¥î¢Ä«Í™]¢+ºâ–þþ‡Ø—1ÚÎ];@÷V§ßÃÚöó ÑBô~›^{ úë«Þd¨e€ät5ØÃ†(²m@²玫èõ÷}¼ˆßw^Ψ�#\JšyqDUö9LŒþ˜&>Ïc üÄ‚ŸÎç[§=4`bÙåtà|1GtŒ'Ò8"i1n³„l€Ï5îÀnËa2ÇŽ4>Â#V•Xóʜɱ¶#¯ýÈ"Ze§gT9´¶+85l”\@*ïj}åÖêË{†2~YXc¥€¶nÅvSd}˜ÁGÎöOrÔÉÄ„²AÛÛ@軫+X¸X¼>ÎnPMKEÂÚE7,jSM$ž+ÈE¯\—žž¥€¥Æ$#` yI)¡dL¨éf6~u¾¬ó~Ž¥Îz¬7ɃˆÁƒæ½ÍÔ£Q@¾CLQÛG?úub…Mãøâ ¾ÉïD}4ϫĘçñ¡£4-ÿ\gf-u¨1v(ë§•€Õ½š÷; À<ÎÛ•kÚÄãã7_Û³³Lè†tO×'÷é“è¯;?çŽZ÷:ÎéõSÖñ°<­é/®¦}}éþ¾‹Œ°¿þ «½~È£±Œé#}7’B£]ÔbçwNDêt’Iôñ6¦î‹ ðlI8o’ÈÅõÑ~%ú®¹ˆ^¿mèùnýôgzÿŸˆˆÞ¿ú{Ùþ¼~ôÚH%m|ê°,5¡¬w~jSåã¼¥JãäÞ‰ï÷í†ë~¼qÆGÓ'ÑÏsOĶuÓnWôÈr¾G.rº}ÝZÂý×]­•eK瑾¿ÈLýÊVëïÁDè·Äâ÷Û–Âöúta‰éZù8c»x©¯žþºWÎÂÂP„ ±Ž)ÔßKå˜Xâí³––qö§»Ž%YGic—$ Æ,ò4¼ý¬ô–G&úùVé Ñû]€.=ñêžÆ¶Øø/ÖQÇüÖ°™µA8’ 2¸H&sø[ Ä©0+\Ìš1&lT@ÚUöƒ±Í®s@Ù„Qp@‹7@*øQ•ú,À.ú?ÅIÀÁ¦&*¸ê™Ç§+£© µM£Š }¼=òXíœ'V5$g1·‘t(â0i‡ÅèUˆÕep;9ã÷û>ë5?ÞÔFßñ“A>\Vsk[Ãe€ácxWF¿LrÑ^¢ò(#øÕ`ðÙö‹môN_„Ú•À;ZE°WdѺƒ¬•÷Èu‡}”º1.D?ÕðüÚ‚PCYEü6§ÝŽu i{F^«¯#yº÷™S—ÿ¢gr¿¿80.&íû½BÁ¹a‰™‘Š/ŒíÉ?+À°ÕTøVG~!ún[§Ú‹^‰þº î\¿7 °×ø´0ðö›èJtmìMÉKªáA¢¦J&ô olv´s»ì'‹[Ÿ Æøq®q®O¤+ûéïû˜~?ÞľôÝ( ‹sZZ¸ ËÇÛéBô×ט ë&ÉZ”x`Ÿö}0ë¯}œGìäk³2*σÞ9ÜWÀ›9ÂGP^à6’§®� ?ùùC”2êüÍf$Ú·ª‚¼ò%}cÈ®¦ÆЫU’ z]=¶ðÌö™º55»Öº ¶\üOÌ€ú…KÇZçæŒEŽf„dZÃ'K¥ó,1í6vJ˜gÂR°Ì#žN ê!2H¯�¬CÀ¶¹ˆÖB ý¶b EJ¯*%CCq· ŒÜmb‡ëâ°x¹¸%ÜãÑÉs)x>±%Èjºô,â%ZW”ÀÞOa·]äD X`Útñ Íz§"bÚE½}ÆÈçšscÓÙ8”f3</躄Æ¥§øRÀLÞ –Ï)ès¡„ì2»TÌ%,zq¼AÒðyí¯£n«yh…ÏÕ6·1¥…Š:*@Uˆi«ÚË—cbÄâЉ¦Få¸È[o{X¶ñ(v“êm¤P˜›êÂN®¯´xö" m/6T·$´77�#£/¬\ƒ„õt•. Mt]ûTÕš"«¡F¬W:Õ,µÍ?¯M¸…µ+U†ÌR4Efâõš "3{È…wþžò ž´7üsZ˜:(¯ ä3vÃꌪžm]Ò7_ö¡Îç8#^0‹c Ü@ƒb»—ºm\ÏÎíÉE*m(;––Œ-™ é8åŠÖáÉ2A×Duxß 21‚]AºIîAØ(®f( $–>cƒ 6­�!êzõq* %H²ñø€NÖfßל âPR¤5£dÝ1´J†Ùœ�T“Œ(¾Ÿ?ÅÐj2J»‹<¨%iK¦$B 0Ï|+)^£ZÊà9&ZPLhg~iÓèÔ³®‹ GG¸Îwq?­ š¦ºVãêù$o^ý°YT:’ %<ï's¾IöcÜy÷?0þèŸÀ¬7€ö˜G¡1¶CE5»Ïñ ÒK…’ì`É}@*CVñ䘔’#Ë î°iqU¦@�waiLEPPæ6eþOÆXÄ=æCwÄ Î|@@ËòE ¿€Ø+2F·´i”_{á¼^Fh3¯¤³ƒð^.è0YïêM¥ÚzLà„/’÷/ Ø]‹+æÄo’w¼‰kviA¡þwŽÌ KAŽlóøWðÐ º°‡åø‰èm :³Å-°¶§^Üæß„öÇØË†°AÊrŸY{·ŠC¡Ú¼Àè}J‚·¬ù&62A•)ÑG"¹‘1ªÓy§œ6C¼ìe^W¼¾ÓE<õÖËRÿ*W^C%G5Tm ùÅ[Ѹv´´^ƒ=]*©Œ“*‡êSÖ~[—Iç¼ÕêtiŒŒµñĶíUÈfÕC¡cÀÂ^ÐUsv*¹ãe°ï*Ëî{§dENÔ¥ÄTÇ|L‰o|”¡•N§¦ñó*zòô<ÔµñÎx<}õxiJIôÊX^7ñøœRQKè·vÿ‹ TúbÚh wbÝc£¹§¿Äe“úÇèD¼™7ò]߬¸óÎm{¿+É¥JÄøF ,.–=õ»Ê\q¦�AsÎ¥1\nµ‡Œ_y´%½Ñ•‘QœG#ã_÷Jà¼T6cÝĶKýþª]\¾´©1ñ%?öóFœ©´Žeð€¶›¬ÌÛÒh¯õßÛÿDéëý‹‡†v3÷ª–X7صí YO×Aµøf¤\ÉÓývW°óÁÀ^É^FpHïþ*À‚oZõöª½[ÐÍ‘À mÎ…DÇñ+ú³ÌCšz‡ÿ©Â› ã^\f&Q衼Œ+@ÑeŒûäv°Ù~z;éutÔVÎÞKÝâ¬üF]²i,¤UÒ<{:"††çÜÿ½ŠÖÿ2¶ qva¤önñܶ›±b©-3£ŸÉ¬ä8rå¡Èwpó*õ+ÖA±µyŠOªûþ¸«‹üÏÏÁóíESÖÞÛ]oƒ Ç·õf·³ÈØ _ˆ·—ÎØMVÝßïã$ñ-f (B“ð“ms ›Wâ²x@Æ·™èãmì-·ß¶¿×Amu‰¾‹ •÷75øŸüLœÒqŸ×æÏ[€Ûàl$ÆÁZì#ÿÚšvàd T¯íxôY9¢ôqÞîA(U²6êÚ•q¼QQ»V¹ÂÞ Ò{êE~¼‰Vuª{ekm­A±ï<ãÕÿ|›ØÊ:…ûÉõ&N¢ûËVSøfÊŸÁ&Ô$Aû.#fÿ ’9¾êøz’b5A6p¼àKÍ«Bˆ¨=0Ók#³ÃK>u^ùEï)¼«Lþ•‰;ìæX\ 6±OS6fê7Šâ »ùÖèóizƒÚ!·žLןòè6ÛúiìáwÌø¿îâ§7‰•­ƒÎ“±WC´iÛ‡ör½j‘q&»6líÊ´Zä«*ºRy™®b˨7¹êÇ™çp#G„<þelX5ãùë«f“™”6qÿ«q´b}T¼E¤ÞyÑÒ-"}üÔº*UAã*ÕmVœå×=e-ŸGƒA?ÜXõ–1EyCÈû×Xï_|W£÷-åW1¤|Çìä½í5 !’»…¥JÔRª™bÏõ·9Ós¦.~ñH[ŸÜ½}@½´LëýÞ™÷=¤Õá¶V Ô�óR£EE/”jy»Ú@PxäØ&gbÎD?Î|-שns’EWÁk_GßînòLÉQçžæE”¹BZ�µa¼‚¹‚‡Ê- A×!ò\5n¯ ò=KÚS;)¹y[Ú³Wža—Dk”Í@­Þñ:n³kž°O•ÜÊž»uÄŒhx ‘Ê”æ£]—X|ÊXG# ‚9–÷mHUqÚ–C&§%ÑÁ:%Aåef×âº<i˜RÜ¢8`©(®‡í1htJÁL˜G{I±¾3AG˜ä[»Ã^qrx M='cLŠmzÞJŠ äEå²c½M*4ÆöFÉß3ægÄò)♦?qï߬‰öýƒ<,þ £ º($ﵔф¢Ç€]"a+Bïq¥‚`¬ ¿d…Õ 6HŒ"DFœ*×+U?À°Ýó „qªu—çk¾ "/¬ÕC秬· ‚¾”kABÄeÔ$DP>#Öt”ÒA¢>_|ÎjÑ3¡ašœÛè^YîÎEÏ;¶Ç/ Ä´2d"ú¼Vݯ£„ J‘HL¤§5ã@~’Hª%—‚ ’s'i lÀ•+bòkê‡&ãœ{C7jÜÂ-]>hybËív_þn7‡8œæó˜IRß~Hš Çf/R>•ÿPøtOå ÷]>ñ¥ˆv`yä2!9ÝÖ0·°Gc"ä*RÄéôÚÎe*½: /Æú†j”P’ì£Rû^Ùuw$Ò`Žaæz›/øh¹9Zj«Ž%ÈÕ‚w¼lC¸E6œPA@û1öùãM°í‹/W›"2æ…Z³DÀnM¡FeBGÏìxdË>å1&¬¡¾ðì-¿¿˜TÒ\²¡_$¡˜µfÉ·Å0Ý¥£Šnfл+?ÓÊâfáIò÷7Yç=`óH†´›N…ɼÍyòاÃD^ªEhÇßzÜ…‘3"[hˆ÷j?ÜnJdOâ$ÉÍ�s(âDL¡S ö‹Éxç")$ =ÈiÏLÇS4Ì‚]Ãõäž½„÷|°Y·2h­Ëf,._‘ÑACz6¹TÑLhÂ12 Ÿ”7¢¥ÈÉšÈ7NË`òÃ$ÞîÅzÃÉø´¡ 1ÈRV˜ÈU ÐY2Ýp<Çó3vë0’ÐÂ3ÒAØÃŒæêüõÍ®&E+ôIP.ŠÐ j Æë�� �IDAT7Œ‹»=9Æz°ãg2øÍ¿ìpvÐ"‹[´í4cbNŽùº<Þ‚ö/‚šOYŸ.=¬ÒV7ºRÂÙ!iÜT0£÷ø¥­ðüù�”ò?*…âŽCwÑÓúE𤹺mû°Ê®»Wé¥2(…‹E7ªƒÑKnÏNKŒŒi PºË ~VzÛÐmÒÎ:qà&– ÿ´†÷ű Èa«b…:0™¡qWòÕ×Y¤ [BïÂ~sÅç&#Ö|ãfz’oU7™æwäÚµ£@8iB¢y Í×ca§C1ì0*‘"µ_À®Ã²ãx6¾ �+€ åQá ÕêŸÜ“2Ì–<))³!" ¥:Èó3ô0Ì¢‹X°èñ†´öR’u‹Œ«bPy‹÷ºÚÅVaH�P§í6›²îÆ…›¢a|QU¦ÉЦ8K)cèhÖŸ Sáb¾™±Y ^S¹ö$—œ¢³d댌tR”Et…TcÁ¸‚^l‡B®írƈ×ãqžc^Ä'÷<…•ý95c2¿™‰sÞ k—/çE‘€a±›}EK“q÷�ºx„©J5àB"pÒÄ /ò\™ Q’j½¢ -狃Þd|Öuˆ‚¹ ›"°%¤ob*=új ì5Á²‚õc(a@V”ˆs@Lm#À”‚D|§³* ™E!Š~4:„tOˆ|t (€ÓIîa!�td3 iܹ§uz#rg ¡DE6+7# Ušf)Øœ óaã‹ARãÆ%Ó&!³+v€Œ“‡}bÞ ¥·HÖ=g5ôæèwÛÙn_¢)% {õþŸö;8çËÆc%t$!cJ$*³NIt?ª•hÊxlRЉ·sMÆ­ñË+ûÿj­ò€xaÖ\Ö*Ÿ‰¾‡û—èÒë]ÀJ€ʬo—áæ îöÆ,¸L«<w*áÓL¤D7z¯¬oŸõÇŒn?î”GlPXtópxZ˜SFbø*Å>d†1z¼¶¯×Öé¹ýûãÌí¸ª}ðw´­±æã<|Ë”}Cûóúͨ·@×¾WÓÈI}u±š]b%úYå<j‹[˜jïÚîY‚šcžßľÑ;¢z{uí6ûnIRk¼­½«7âfp™ô!jÄëpPãªÚ:<×;T{ˆþ”—1jsØã<Ì·˜ Èh’{i[Ç*m©Y¿×xé|ðù²m]ºÝ z¬‘fÂB¿ïÕ뎪—²j’½ÉôûÞ ´†ýÆÍ1t?Ú¿oͼËÏ3¿áGÑ]‰â+èÇÇÿ<e—uˆ}€¹Li* ²¢IØ "{3|‡yØp¶Øö¬HÚó;–fIƒQ\V±Hvª‡iì«X5Â_°ÓNS3š®(!óSM‘2F!œFÆûÀ#Œi½æŒ˜Q¡z¡WñµàLy!±Ðc7Ø&¼ jƒ+ l|y^L¼¡|Š,WÈ—Iä©a줣܄á&�³#‘wŽä\3(SÁR±†¼à 'a":ÌŠF#™Œ0×ìÔY‰¯ê-« Z&r9!O\´€¹€lBFÙ¡žÅmÏEŸSŒÅ\ƒôäêRû²rþ„ ·[<Ûõ³'ÚáwÄàŒðî€ü¹K– úžnkŠ«–ÜSˆ×ž`«äôÚB‚_ê'2º×Ð6%‡µ#$÷Üfé1$« ¨òG2›ZEB°¤+^Dn«6>ç‚­ EŠÛù«·-«`µ[GÄ1t‚Z¢ƒösOñÏʪ„VpI’Èñš*¦æ8Ð' „Š‰Ç¹š•ÇÔÉ ;ÒòŠÕÒäÒü˜ å÷û@¿ä3Jœ¨2¶#ÊÂDN\,FyyöPA2¢|3•‹ãAX"á-“Å=q#.ãÆáʧ÷h€þ-`Ïåº\´wÓSð)DùXA]G|Ù z ÐÈÝÝc7ÇúM5‹Çß&ÙéĤE;<ÕÄâTˆÒØé¢ŸÈeRՌٰú›7v'M¡‡+iv•¹Õ¬F5xBÌbþÜšÔ^aÐ_+e•ífEoja(Pa¨Ñu¨‹v¼K ŽÌvCK†y–6MGŽãi›8Sĺh<m|½ß‡óéÎa«ñRnbL4åñ6žba¶¼›HÒh³‰Õý®¿6œya ä„1³xËÛ?FAôãW5žç’Ù§lŸÂÀ$Ow ß]„ÒcÅEY©æ»*C‰¬…ÙÛoØróÖ’HkSêúù¶]ꑉþúªªQ#&YYLJëó~6Å©µ‚oõ×þúª+1Igú¥M€Ï!H}º X»ÎÕ·ŽëvµÌ±â^˜Ú »I£¾‰VsµbîR=§š+·ÐÒ4_ÿlô^M¨¯®ahíï­v ¸ùÅ \V•ïh|kæ*gnlûte¹¿»úM[v²’£Á‡Î0¥¸Q–¡9 ÿÆ¿à…îÆ?"¢­×ÿðÓDµÛ(P*±r‹9I QêOÀÆMþüuºü£n-2Õµq%ú®·¡^Ç£Í.FW¿>Çt² UÓñ¢ŸçÓåNŸ>Èv#¢û&›IßôèO÷Ú¤äV¢óc¹-ïÚ*Xü¤¢´\¯ô¸²½»U¤ø*£OaO^k¹m—K —öʾE8\Y鑽…‡œZüT1–ÃÇ™~ßÇ”Hl¼Ñ•èç™W/·¡í½ÔùSßæ'ûGÇâñ£ «ëlJä ÑÏzMUM'Ýy᪞0>Îô×ýÁÑ«9­cJpÔ!¬—ëmœ.ôè3§°g"úù¦*¬ãßmdÆ ·x¼Iýž._c`W ò¨¢)‘L9ê"‹z,÷¾³ñ úC®ÍªkœšB.éw:}= =®M¨÷Ú´˜_šêô Óá½µÁ/l2/²€}õ¼¾ÿ+|¢w·ŽåQÚâ2Ïœø™*ÔŒKVÀG¢žÁâC1p7ƒˆ´ø�Êóžöã±1Q¨CÒ‰°g6.ÌdéV•1$ˆ­Þa“@Ø5’ÃFœŒ}剰Ë@c2Ò*˜ÇO¶u_8ûƒaÄ]±9ôWt˜ëb(rDGô<‹ZójÊ�sÎ勘oð?3hí"㵸#¤äIþ$¬¥ÜCþÅ|SðrÁ^Ž�Þô{Ô%=†Ó!𚔑;¹²¬t'^vÝD‰L=LirŒ÷ñwhÝG²¿÷$dCÔœ÷ Þåì“ÔQSÂ~ù$ìFr <y'¶‘gP6!c 5ùõþpžÕ£ˆŸ/ìAÝX1M߀JXAÖsÙ)?XpÜüÔ“àF«pÆ*A©®¥ /I1@šOƆ®Wï0 yjÑN AÍÙ=]£Ú›ltí°ÔkcྂŭìÚAS5yèÔN„ ,`o1–öÚÈdã·pÕ;€Ú˜ ˺ i$;G¢ü`S¼mfpc†Š7²‹\hø&|ìG®lÚ-XÛƒ>yM2¾méT˃¿l¨·´iÚñ›3©  È-©ŠLöqøõmQÍã©q×O÷)Ë~;zXžˆö4’Ö¶êãôoúúÏ¥›Ãá‚„‰CçÑnØúéôUoò›YÝ öxEÊ^+´R§ø:ŒÝÆ$¾Éª›BÇ[î7ä𪵽Gù¤H6”|Œð¢A0UãÀæ"þ¿^ù›ù#¼ß·®¶¼“Á_Ù½ßà믩£ë€» ÖÃdTlnRŸe!ú}ç¤ùáry¥;77²­Ô=SÆÔZÛë>5_Áï1¶b^€ÿ]ko°6ʇ͌CT/8F÷*ÀvaîšúToìç¹ì: N{TYï:®?ìrÓ@Ã5J4'-î"­hX‡‹{ãÄ:ž½[{p·ÏѰqcØàmzõX_M‡Œ5<ز1¯Õ5¬»Í÷{/âr�“T×ÁÊ̺ú=·)ôû«›u‰e£àwbý+‹~¿ª„¢‚ŽRg²èÐ!,Ξž&á¾LïÐCÑž¢kÌå‹ïgÿÎsDD Ì/v_Ó!<О!áåä ¡–ˆPdß‘m¨dè¬/.¾„¥†ø‰^çd²RááÙÜeTædO P ðÌè?í9ü@Lórh(|W&éà6¥ Ò"FH¿Î粨"‘«º»£væi.(6]ò!Ó, oi÷Á¼Í*M{ÒÒ0󿻏R/âÝe÷ø‹aX›ýÈî+‡®–ÁEøk%rÜLžC=ø+ÀÙfz¤fðÆ™ú'W†ˆ°`ð˜ç€ÄŒqƒ§u~½Ï ÄÚŸè÷‚d_ÏÿÆ“kƒ.2 éË06غ—Ö½.u—’º×€XŸµB‡'0Îm 7ZE]²/$–déÈbDˆ¯‹O(®Û>^»âåL}猥]²Ö ñªqdEU¸zPÆ.-–o «ÑÞQR¹®X·"-ˆÑ‚š(d_”“€RU� –"Ö¤H4,Zä–±êÏ-Üž±W…”ÿN¾Ð †ñ;ÌèÈØ7Àä]]AYàá¶^1Æ*›íÒŽª=MÁÊpåÿ«Ð&a> xÙá°Í±Zž†¡(¸’Š»¼•æ˜wÆÄ¥àŒŽÿÒ¡ÎÊ‘cL Põ‚³7»¡Ø£®ÕXòR%UkÔ)WFS×5âÙo˜äRHí¡š2ôë/7£”¥€ô‘7¥‰­9K[¬p9Ø… k<pKµ:– Žž|]AU†”¾kúP›EÔ$ÇEÁS#§S*‹æ'"cÈB^çŸ“šƒ›‡þ[ÅP‡<Û— Î÷Pó^ÿNq˜53ÄAâ²ëå·Óóaf&ƒÙÍ®báá ˜§á$QoÓ„CÿPÁ݌͙¬§ð¤Ž ~ƒêü˜}dÜ(2"#@‹<U±WŠI'1Ú¤ª�€Åb¤zË3r|Ðd J :\ÑðÝ©­ ÐWº %,£r$ǺvÙ#ŠŸq„NçÉhÿ-BÏz[ê·w�0uUg1—VIàæ7±W–xêðï{š�Ž%çÌþ± `N²•ÑF<Ù2ÙJ¡:{ÖŒòäeÄ:ýÛ÷_ÿWÿÍ÷¿ýŸÿïÿÿÿý?ÿåñÿË¿ü‹ÝUa[+9]J[±7x{·ýCøq‚G°híµk¸ º£lG³½gÕ ´0{c?4è¸â?òAü΂©+Á; >tŸ%Ø{2.£†\+±×*G¦{wäÛQß|äÚ"Ö¶,íönñŸ¬Ÿtë§©ŸûqÞ(Û-ž­Û ðÇés’tý”WÙÅ*ù¢»èZ»pÄüìí•5i.ãa]æÎÒß`$+„kú-¢ù‰Ï1Þ‚c%:-Ó­JSìÚƒßõYøÄ£GòÛ#ó=’}rã/âNz3–ÀÕÜÿІñ£HŸ®xÕ³Á1ýTm>œµ¡ß앵y½öF«z{[Ÿâãq¦÷;}ü:þ¡ß_eöûY÷oY¢–àãðííb}’«Ë.`]¹”Á[Pô ÞwšqÛõëÊê˳¿_¶Nû7‡.Á‹Ø‚èçã¿ýÿãöŸÿ›ÿëÿ_þ×ÿ9ïD¬C»Þs? b ÜßãûÁªµYÊ­Nc¸1ËUöðzÏåÝŒj¦Ÿ"{¢û->@€*r—[Œˆ"¤4:y?ÍFü:ZåuH&&ðÊž¢n«àƒqi]°5¿6²Ùµí¼Ué÷†–ú ëØ}F+‰µ="\ ]u'’û5Ÿlb÷ÜVc!úqî ×õ²…±§ZoæÖ½KÞé8’Ë8!®c¦„å—ÖA» †XX¾Ñ¬âàØ·˜)óø«±ñ3å«Ü¤LD‡ó¿O]tAL²óð:öÓ1ßd4SýÛ„X‡ ]¹yÝûœÑmé, ŒûYÐY¹=§Ž°ô8o ã:–ÃóÕ` „²ˆC6ÓP‹×2QõQÒžxŸKøÙY:Þàu_Nz<DÄÂ\A·ˆ•qá`I&pü#ŠrɘÞ#‡.ÄWö‡¨"1 %u3ÖY»(_LŠ9T™ó¨JÏv A=4ûÓ6Ìà©é�9t HÁp™0 飅ÞÌ¿Ó{ÆID%¿Hù]§ýYq51Ìï#Và+‘Èú5“cêRaaÕ¶15KدMAKlBöIc†¼B¼wþ;φËЭ*#Ô7›bjrÝòˆ)ˆ›÷öÃìÐLñÒ+‹G`ö=439m¯ ñ<ƒiNSr.=Kš¸Kµ@©[ߺI@eSÒ¿ Õ’úu¸d oɪ’V2Ã]§GkôÓúß.hS¡c—íͲí8»ù¥B#½»=!“ ,Yƒ•ɯ‘ö]øîó¦ÇöÇÛ¦'&tù¸HÒÒú®¾‰z<Îý§cÕ-f<‹8/?JK•¶SÛ©Iã¬zlmCUù­«½=gWrÁ…ö‰Ç×áx‰¬ÖÕÔó8Z2”o®ì<{#ú¦Óé¾yCtB¯½o;€ ­È&-Øû¢†¤Ûçè•Ñe~”~ÙšáÞÄüY ¯%dJ§±ûk \è¥ýí*t> ¿ÿ±uÕQm²x[{wëèË�ˆÖÑ_5Æç÷—zû›[M×êØW Û¯¬{솚;SËÂ_µ•7OÙ’WÑ"YÆ„ä9V½á<ôúDBOlˆ¾ÍNÕïj'Ügk|ä ymM]”>½Ô:†zR–Ü^ýg#UiÁ/W»`¡ žßSoì{œû£××ûí¼y^Eõé¾å¦}q¶nyáògœâ!ÆÚ$YNqW¢covy;2ä2V§]gbF̨ô<'!Õ8`ªÃï¡Ü.z¢ìË0;}{Õ> `“«U!"¤*ÌÌ„L°‚¤}²fŠ"Agô‚‰*вÏóX!òs¬lü>B“_H¡„×aÀHEÀÛƒÊC°Jgvr‡#P0I$WȺƒÎ©Û¨Æ>ý‚LaW+‘c “Lní°NôDʮҹ¨ëA;‹Ýfl2Ùòã$tñ!¥HgðáµàŽÌTÃ8É ¢Ñd[ë.Sn–àò¹ŸsEqÓÂÁ˜Lò݉\M3™&›Þ\ Ÿçœˆv¦·S íˆ0죷­ì¨ éH—¤2Ø™T ·[íïÐä;ƒ(K¤ÉZðÅyz9V? 3»20e·Ô5"Ôt…‚} úêœS<Ù¡qà”Â,»p¬‚\àϤŒ9 ˜�¶~ÁoÉc2«MÜÛÙ°¸cÆc}¯ì²˜€çÙㇲm"“Xo)¹û t5#îMƒŽ¤àÁ Ð6´2TËmƒ<ÝALsæO±-î6Ïn®p¨¨ûía˜™aÞ2¦q j<ÙÍÛ‚Hæ)ZR(™ÔüL¬òÂ'9Ý𧘛ÝIeAÍùÎÀÊJùEm.Ù0ÝùŹÌk6y@ Saµdt®,NA"#rzâL£³9n\Eäf"§ªTœ-/ë¿¢bÈfw..0 jŸÙ(+nyö0�Õ]NMjÈ¢¦4‚ôëlÔLRtÓ›Fqݪˆ·Öe”¦ç½Ã®ˆèÄ#rDnRUpB¦Î…Þ±žT‘Ëå÷Û ÇúØ’®.“ ®� ¿pÁ4£Ör1ý�&ŒÝƒ*ZÊ^ÓSõ¼rfÙJÚvüˆ�p/~mJàʦN6nàJVy‡’‰–£¯ÆùP5‹7 ØÃ2©x}E ’¾õ"¯â‚J#n\ó[º õq^š‘ÏeÔu†ÁÄUT:+ÜßÕÿnÍœûu8VŒjÊJ§Ó½WÆ×÷(½Œ Ó'X½Ð5ì»nL2N5u¼ž7fŒx¿w¯)»¹÷)Ñ›avoX"]ÙC]ëývåRM§† ý<×·¹²"Í" 0¿ï*$÷GàŶñ"nmúšäìÚŒT^Z‰7B|Kí+Ñï»0“ûR/q’ ®µÐ²¸j2\PqhÜÝÚÝ.£®sº°þŠ+«Z]›SÉ–Í/Æ5æ»=#…öq®×¼ C¬±Ë-D?Aµ, QôñVÉmð« Ý"lçÿþ.3ß’c¼Šh:„4½£ù3/» ÿ æÅ5ð FAdæjQqœÀ¾;)Ð7{5܈žŸÁôvµ�ñóan¯¨ìMzJêbù„j:›ÑÓu„‰òØ‹“‘«Ïj ÿ !1ݬŸä»x_"l!ÞfAþ#Y+ ¸ˆ+ò/&9̪­˜~U& ÃK­Ð¸ªjdcëŽ2"\èR9„·Öxg+ù‚XúK‰�‰š#\¸Hç¯,m;yÈ‘ÕæBJ >ýåÕõ<Ï(Éãéf¶Ro~×ö¹þÿæYœ¤$ßÊ*ÆûËNë«Ò F»uÌ¢‚3å õ>,ô ÃÂIþ<RîF X0ŸÜ¹JQÍo20C0ðÀ]=kæÕ6”/ŽÅÍ�ÿ¥˜ªÔ‰qd#<]¢H©S©6¨›ñHÃ=w÷£¬i&3¬t1! ~á/c߇×àb˜ÒâÔ¨JD)Rµ‡¸X�>¨àå«A=F‚‚^=Ä*ÓÕe°0`ˆ4 qÔoÅQ(1˜ÏÙ×™LØ:‹ÈEnÉS•E\ †'¬ ¡ úV¤-‹²î˜-M7Ô>›ð˜Ëñ™©cMÖNb¿Áyr>§ïíõqZ°ùâxüô0þMFt÷¸È÷ýñÍIêdí*²dL®ä+«²þÚ!O&\õ!ØþeÞã ´P3®åM!â ^/ý(ÝϳˆÁ ¢ºtÄ¥E[ºC¡¢#P*¨ïų,?4cB Qè*é•ÄPº�°8"[Èí¹:Å^-Ü+¨‹nªbS¶EIŸ¯(:—ès|qg‹>¢Ø£Žkø­&¯ò®ÌX¨·Nl«Ê• !Û¢G,àÃw„yqˆÑ犦é]>¹¶­3!jçR”$EZ×)²†NEF»GÓÚåΤk®üp%÷)½‹ãd¨t]‘¶l´¥¦ÙÀ�SwåiŒf±ã€]²ÔHéÑPUÁ>rB%÷ŒÄ‚ Æ„A½� n3°ûSä»[Aö#ä~¯Í #¢~?Ú-ÝKd°ÓŒŽö\Z¾ <Óó1ñ@uÆ"yç–‚Œ0Xr@„ÍŽuCwÆÍׂìÀf,ÄŸ­P¯÷k±¿6V›LB¶Øœ)Ïnâá9ó&ëâ Ãà Ñq%ܲÛuvŸÇëflcë,àtP¢"ø«]Ï/ûÙ5Á²`ÜPòç:»¯FmîD 8{>`q¨�Ø’¤ñ¹!;&gÆVÊ"W°-ÀFHÌ®â;Ö[õ÷¢ ?j‡µY‚Ë0t,ÆÁ&‚v®@$8?eCƒF©Y• ÈÙu“-˜ÐÏûáDcPвHËÆ‰)ªyçEW»=cõÊpöÀÛŠO•Nç]g tK–'\öKæëÒQ¹$Â-eDò­¡š.9]YEïb%Öt@bv îzÃ]lP×>Å»W®Áó„4»òo* 'wÙ]r0^.ºeºCîŸ÷WBL¢‹Œ‘‘¢•×$«‰' “ý‚PÕT TbíñRF’�÷¿6–Úéî²r—aPKP|dÑÅM£‹hôOáí÷• ø)XLƒÿ¶ÈH#ãÁ“~7^s>­ /íÿ©Ñ®šé¦b°QÔª]l* C†£‘;ý¯^ð÷]¼Ü×¶—F~[$‘r‘’¸<qYŒÞÚ>å*ù™è÷]“*™Ž†PÌcÖÌu9.~e[Iw^¾‰õUÉŸÒ,øÇ¹2*/šZVå¿ño©L­¶!¸í ºÝ¦@Øw˜eÌÒG2¸ŠmÛ5 E Z´ÈöŽ8¡‘˜r×j©Z‚Ä”)–¶ï]Ú4x“ª¾Í[»øOiËÒ˜™\¸’[< ½•uL†®ëv3N™¶ÛÔÏ·ÁÑ-zç3‡Y~wÑË®R/Å\¹9{¶.Éu¬Ó:ºvöûWåmæÁñvØŠýÒ2?Î]û§Ý(E©J7†;£º¦•/â²4x'"¹~ЕÕeÕ÷yt±*´êâo/î5UÐê”kx3:(fM…÷" µLR¾¥M ¥D>/C,fçU,µ°rTXTò¿‰>Ç-uë÷®9KèR#X²­ðÁî¡FšÒÔw>ålKK*ß?ºÀO© £êØ’Q=çϾí_×r>Û¯FÖ¨³x¿ÛõÑÇÛéô¥gõj&yg÷ndè¥nõÝÉOãLƒw¾=‹’H¶ù=x?äå±€iÓs¬—-Ø,"võt’ÍÒîÄ‹h¯ò‹mmª¯Ÿ÷>ÄešúÑ£ý%áJDµË qq[=Û»âð_÷‡€ïƒóû.–ÏM,+¡wÞ†ºî�U÷9 tËùµ=f6ê½]L¶6|’¹1ý|£Ï/~ö­²RÛ Ð—ºsžuœ.B�—¸nø Û>-þu¨+ÕAxiÙuk ¹o¯ ÏáØÀõæ_Ç8õá>{oDt'"ú)ßDQÔv©t;�TÚqÝö�À™ Î i3¹vÌQœjrÿ³D2T1œè 2¦9µ!N¡õ\Æ=ó.³K‘ã3ú>cTkx]lDy);¬ª &˜¥ˆÂ¸'Óì´Ô4*áb¶[õÅëúMÆ7PT€§mñí‹2fmÛk…–â#¯Äj¥'!°kJû6rÃK™ ~¹W%ÂŒV"_Ĥh2½F²’ª2еŒ…q×$r׸5f#ãF{–u–õÊ+‘ ¶ç…ÒMYðŠõN²ßAL8õñŠ@ö© ÑF\Fªm³—!$&Q*˜¦.ov¨«ˆ ³©›r‚à¯SÁŒ 6®»Je"O8{…IAÞñhW¡?»¡7:Ÿ~ÕM|ø8�� �IDAT…õ§ë·~•¦P¹µs¾ßû9Tù}ŒSêkýÄŠ¥¼4EN©$Ëa€£ uÎu´0×µ]çªÕÿ†ßÛ*æÀè*mJ©Åbzµ}ZuGyǺ«\ìeàxÃieëb­—ªç膖JüŠêÈÑ…®3Ë{65°¿¶¸ÒñŸµ½fxVÉKíÌU‚°è–¨Z•ŽíKé÷W[P5U?5ÆÅß# [ÿé@GW‘ô©"ÌÌú>ÎïUó§ƒÕàøÏê#›š6ý8oPáø,–Ikìn©KþôB=Åï×?bmæ=ûx®¥6•óNÿšô_ôÙ–x„�ôE&êH^*úÍçùýŒmóUð¶T›Û¸mýó<`Õg±ßڭúÀóõŸgT3¿'.;.ÆÓv™ –´f9µéc—ˆx”~2›b¦²eœŒî&XDÚÚCØFÀ^ÑìX„dÿøÉ¤BIuø§¯0»jL„,ºËCÆ®»ª�©•ÐJDAÔÙ°|‚’jpVòtä5'•hîݬd«E_sÐOæØ‚€u½$2fßSZ÷ÿeD>t>…ËÙyÄ.Ü{WÀ¬†SäBŽ>§{Œ8 ŠGSäÓeÔº Ý£à*œùÁßTÄ×%j–¨Û¹`§„£K~˜+ø¯®™xÅ¥ZîÒó&Q2rd qèÊaêw>èO’¾V4˜%ÙW9®„kÕØà"tÅ¿‹ Iy½6²‚¨Pô¤E½æb¨mt` Ô8¢Ýäô*YØd'Âu쥈BßIë0q¢DSÅÝ “3Ú¾£•»m-Yëþ27j*;’v—÷€‹¤¹']+ÕX°Â´V�ßäTI{>@EÌœ6 VØ;VÚ÷® Þ¶±/‡=?IŸS=™˜ç¸‰„/“ÑÅy® uU,5ûûÀÿ7í\™W¬·:üiÃQ ܪ4CïÓEÕ8õ€«rnŨµ^Pù–ò7A9üÍ ºóOÌ…±¿Ì± Å ™a^œ.U<MM_õéj÷©Ü³‰�,§U$¨ñrWöïkûóësë,Dßæ÷é³C?Îõû¨bY™Aë`mõïtz…ãY] 7F)¤ S®…I&¦Á‚«pcðQÿÚ´òó°‚'¥¾®Ò_÷Zúþù&_K£–,l&K.ߨ\>ÎÃ@¹3*›ár ¯­ªÐázá “¼T_4úyîeùÌÆç¯¯`2oâjx–Ç'a:Øåág,–æC-8¤Alá˜õŽ$¾® !¿>Wn¦\ë=¬ qã ÒÊmhQ ÆãûWí…‘;Vf?vmÝúúþs^§Í¼Áºuˆg™±|%Q¬å,Lõv”‡¦bð,[Wtmç¾Ï»ÄØT »Ú¹Wl(_¾ åÌLjÙxòÌ;÷8“c„:™º20d“Y`+)d|jGÔ<X-ÄÈña­_A�df€lÒÝêM Y7°çÙ^–£Öãª"! 5Åfðû Ïxœ54]DRâb•NΊm‹£nÀG€üU“ÇhX–’<ÅûAŽ3ÀÐ%ä!¨E¦Ù&mÞ7µA—í O@fÓÊOX ¢}a6‹ºcKª„`Rhý\<v·­Úò2è¶$(g –¾¹Gëî?¨+è©ãÌSï&K) DÜY‘÷‚î$^wÈ l7Îíÿ¤d8/iè~J‰Â®'e]²©m$ÐGéâ͇r!ò<2ªo´áãÔU°ºÚP‚pl¢” Nd\’‘lc ç|ÐÓjíÌc¼ÎXu€·¿ @L2M²Žn9÷Å~ˆpsnˆYÇrEƼ˓äÖ¹…ç×l\ø+]³LØ%óEÍàƒzd$ñRüO,‚9‡ÅÃí¨µ%P¬»9Ï£‚æªü1„zA<Pü.;èàŒ¥‘ÑÛž§È¸+‹¼¶UAê §«›;¬T)® ¢ôˆ^ì¤Y:Á»ˆ1F"ÐdFd𜰎UÛA8ˆº®ð*MaÖaÞ¡z€” FGÛsUõ,AÚΩ«³4úo´L&z,>GŒéq“ìЫà‹èãÒ>C‹ø¬Íªc�24nrtIóÅÕš‡†‡QnWÆ6¼¬’w sÂ!ßìFËs•Ç wWù?zkÚèünoá…–y¤¤þjíã7WA†iÒ ·í êøR‡È:©¯â«[·ø:&'à›¼ßwÅjjfiôB‰SòûݶWÖá=Ý9©˜—F»wÝúmë­å·1Ÿ/¨âpcMå4šßÇ|aÅ¥ÑðníÞ¿:F:pø<ÞÑØµº¿Éë˜êÒ^×{f³w›œ§¯ú¼+Ñï{%O¾ßyû¿Ê›‡)Lñ]ÃŒv{l:¼›p̨óí2yêrD:ò0Ì£I̼âû®@ç<pW�7P>FÌX?Æj#AºŠë<ðA|bÁ5s ˜íK`$K½NˆIrP‚†„Ž˜™LcPs."d[¸Šî!K”°z€ž$[A–†FDâ±.¢^rÈ’?²>ÂA¾Õò÷-AOBÅ ëšçôÅßJhrm…h¡¢•š`\º`÷m0†*‰Y3ÆGƦP H?CŒÐå29§†ÈW>4‰8Ñœ®àŽz^öëFigŽcD“=Êb KD¾Iˆl¦¹x2´w¸[…š©#îÞ =Ñ�Ž*7D¸ô‚ŸÔh΂œF uÅ:N.@’’ï³s¶(˜X ±MàîQ�g1Ol×ý‘ýwúHÕ9 ceE,öo‹N°Ëö½" ØkÔ´ÉñÅŽ_P”ÍZ3×Ýû ÿr‰(©àRÊV€ªÞX!ÅÜ»¥âG-aL>­ššŸk³—Q)ÑÔ“¹ÁaÃe¨?Ù¶ØÑAªÀö *ptH»}7%òËîÞZf#ÇŒ{ý!&Èd4ÚmÛmðr͹çr¦cööejXv0CñM}ª(¡ž·9o¹š§¸ •ta�Nª‘R(Ár^Õ`Þ° ¨«Ê x¥ëï(o{ä* ŠÉÖìÃó;Ï‘ehôQu¾epkö êa4lÁj 29óøGÝoEÓ¥.¸"h™ãŠ‚šÌƒq™’}AÚøÖëÓXÑDöèjÁìbõ-1’¥¥ÏsÅ9Ùcž¯ƒÔã{ÜhOˆ%@Ÿa¤‰3ùÒªò§¦›´s9Ö®ê¹=¶ì‡ŸƃäÂz‡r £D™h±ËÐ{ŽšÐñf·G*ù“ÔÊ®lêI"9m§ú\‰rÁžð{_�(aw€ënvMpt¦â$+q*ÒAᙡ¿|/$-* ˆû#ÎÚ+3Ÿ {ÄÆÑËð<±L»È,¦'ÅENVp VqN¿ìdÇäÏbNYÏ…ÍjŸ‚ŒJ¸:4ŵÒ{zí8ɈëËâ–&ÁJU~|BJØÔ¦È8¯Í¡kIžŽX»;o�Í$ßõu¦ ¶› E�úk?vÓ9R'ÙŒGqKx ?·ÆÄ•†C8DŽÙ•FX}ç ;ö.[j‰NK¶å¹Ç¢vÊ„É{ ùMÓ‚&HD•¤ì¢p[!k"ã8Ûb†âzÒs·¼'€æá’áÑiÎ[15’$\:AÌËÀ¥"fdµ mãDAGÕ"ÚÏuòWÜå�à댰qŸÔN„Å?EÞ_ö8™Åd“Å©bú¥12¸ÂÎñàD‹†˜+¨¤ù@Gpß寧ËòÓ4»æEóa¬Dž¥#r–¹?%à¯d$P…>”jŒ…œà=fЗ=ˆ˜94á™ÒÄmÇ#%oä¥róõHº`ˆa_M®rÕVÉrü}'bzÏÄ(v$¦Ðx‰—T'Mš]Ǻ¶X¾°áº¬^í¦‹ùÄ”°+M+5fìÒ8T0<¼ßëŸü|q¢ßž"€5ÑîÍL¡~-æÿiôuÖ;ùaFX–ôOyaK ë"®B~³ò¾~ßk×'›¢AþÒzœiH¤oF$üöè»ÞUå~·úq«ûUÈ'vÁokˆsºT±DmòR»k+ý¯yšpÉóúßš„Ö bÆK¿’ÝëºÎäøóÇÛh7–Â.©%û^v#ãýdžÈ߆»Ê7˜…ÿ ßÇï¯ÀC¤ªüñæåǯî×3áí½ãûseëÝÚ`ö ùñÖ‡´Së®l ¾‡.h_#Ziaëß_åþ¹Ô7;öêEÊ6Æ\ÁÝÑ:n=û{™Ó}nºÇÖƒþÝáQe¿£d<P7ƒÆPê!òað‰¶&(éAÜ’<aº‚¦aaÜS²ŠP�̓ÂN6,H°µ÷ ž<3úNöX¼.ΰ</(qÉ 7ÓP3ºìðD €Ó¢s&2f¸D¾zÁÕ;a'Ÿ}¶dÒ ÄN�˜ý4Ë2îŒy4$(BŽ˜ûNw…@‰¦`HÃRqä@å±ZÁ§8\§ŒX‘ÕÜ2¤×/\œ†÷yâ V½†Œ÷t¸fžoq�›×­ ÇHwŽ›ëãò OÇCä‘?Gq!ך¹ÆˆŠŒP;(4ÀwìºM;Ò6ÈŽ}ë–kZ>)NnD~9=9AÈ+›qãð„¢KrN B¬· ·€� }mE#еz±’Þþ¼�b Ökð»Í­¸ˆÈŠùMz»™"hH�\Ï ûf 9‡ê¶g…ÚÁÁœ …ÇgG®×œ$ ˜´!5¡‚]äè¢w~³’îA3O×±¼ªàÌ^éiHM‘°'3ž)[\Yr÷ö‹õ¨óDºÓ—€÷ñGY ¥ü©ª~àsÊeº'Ü䄜¬é|ä÷Ž€œÌ>ˆ–'x³°ˆÐØs,G™ ½yìÇçúlä Ðq[µø€‚äÚá4Â'‘Û‚$ˆ¥‰€ñ‘EÀ†ÕkH-Q„|ȈyáPσº»%%ªÓ­ø¦é@Ì2JlµÅ.ö=*¾+~}¢læ;cÙFoÃÑdýlh& 1)Jt5=[’IU½mvÒÖ£*M»÷ÌéÞýÛiÊûs±f3DÄݦã€!6~ž Rî¤þ‰é“ љT¿‘ÄÊ{5ÿqÔÍ;•["äÇ‘±ßŒS€Ö»Â^@`+&ªeÝaJ29®Ð\ÂÇØ‰ÎiºóB$Âþ^»u£ÀÒV¼± 7 x(áRRYÛÓˆdŽ5/ƒS‘9Ú‹àC6"ÙCš«¥2b(;‡}Áy'¬SˆwçøP˜÷àÊìœilïpIu[‹õžâ†zÑãûà6ð]¼þLCbBà.90àæ‘¯O?Nçøå‰x<sc󥲚Á78wU„Dj Á)êú)BºQ·#oËuhT´ÛžUœîK§ÊâG^ÞI$uêœB‚k°”¤ „:¸` –ˆ:ªbÉm߯OZÀ¼P ”óÀÿ.;3SŸdÁ²Xu¦RpšÓqDÌ9Ì å‚k;Y{NÄÒE!Øê #«F'�"×Rm1ø¡¾‡r¬CM?“†îˆy¨› »ÆZ“à'ÎÊþsíFüD»WCÒ×È Ñ–?-­À+ÈéÃÕ{ÚÜ·ÅS´‡AþnrQSÏq\÷uÁ¸ËpBò5ÑíÉT¤,eOòµ ÓwFræ¾zt?%@°ìoŒ±“•yUÏ›Àz’Ç ò…\-¢Ÿý*ÑhŒ}³ZbVÄ Zq›(Œyݶ[+*Š«jï7TdÏ1*Tl!äUëáØ°àçQlÜd.iSSákÎ@zJ—ƒu¬]m¤˜s1ÅP˜`LØ~˜©qÐhÑ+kÍû"z„”'1Ãt ||Š©O/®s+ˆÙ­„+ú~.–è-Š+3ÝÍ„”ËCA@$ÃÑÊ>Í,;M©°¼W\\Æ9ŒUf€ÆP؃Õq3×VØI:!9Lw-˜Þ· ‘o£º³Áet*/QϾ¢Ÿ@F~Ͳ ËñÆ/´Š+›‰ãqÖŒº°š±h½çÃi‹µú4fæ¹Ö?,.mÛšUª“‡fp$†òe—v—Y'”CÄ^*³kù1³{®0‡OœŸ—Ý%žzè¤òïsß?4AÀUMõžzõûä0’w¶ŒŒ4÷|3- 3 E:Š‹z/½UeßÕ;!,(ƒÃ¸¸jàUÏ6Êâ´÷–bÕå–ìÔɲ®c=*€D R§šHFJ_;ª2òàA†ÔªùÿºGøŒ±ò]÷x¡Þc9ÁX¬â0{¶ÀíÌž“àS¨Fo+l n,ù𥥼øTW¨80¸Tžf^€!KÏXOídù™,'>ÉNÆ$/2Ù³áLº3™VNÆb@ÒüÏuy^õ@éÀQt &col¯$&=÷ ®0yÇy<VŒ,Žܽ@•ÜPM¡Î!`÷Ìá¨àa¡nà²èS0ȣ췢¦Jg) £8«º‹A”…þý¬ÓBZõ;$À¼#ê:4“¾dɧÈûòÂ[Ág>MɱÛ+€–ìR€©ªR—¶ Œ7Ù­ˆÃ*µeß`eÈ2±&k<é ügJ\.W*O©Â?‘OÄ¢M38!"Ùˆx= $’ïsø(z„p„m‡&Þ‚CMh" ]êÊØ(EsT´H½ÇMP|\…éo<’ Þ¬êrº³<ILNI¾E^¶ Ü잫ƉXeTŽx $GÀÔŠ Ô™(d²$�La¼+a4Œis›(’¨÷\`,°LA÷EFXnÖTÅkÀ#êf�Sœ¦À‚ Š’ƒóÆß”­ƒÛ.²‡=W࢙€Š±˜ºA/??¯ƒ%ì×±ö”ƒÃ¾Û%Üšg¼#Ï3ÜvŸ¼ÿYn«VÞ WD;&@“Qvê÷MÈLýï HÐõ?ËNß:íæ¨KÙ»Q/x³Ôz‚À’yÞä¿»dý¾£ÐŒˆ0™´ ‡V`åœЩãÌÛ­/¢ùÃzÅŒ£® l <+<+_öíô>ÕöPBÆÍðI­ ;f—8îq`¬ŠÛÉŽ ·=#)¾µ[î0Þ‹¶Ünd*ÆÈÍÕLK[>,áÂöíÇßqCHÁòùàH…·é4ɼˆ¨P{Û«eϲþRDUxn ~º¼4uî ÀÇ}]zñ@´ºìÄW(8û¯’rA§ ôe$Œ‹öÙfDØQÞ¥¤'òÄ ,÷š´Ùˆ…™{iÏàÃJÔ˜ò‰hr2Û0. +qé.kâ€R¼U¥lÍÍã‡nK, ÒæNBî)yQ‡Cð/|›Cd ;Eb¸iâI¶ á ëY‰èi@aËï{8AÆe ÏŽ¤2ÖÃeÆ (Be` ’à‚üÆå'c·‘¿ª©.³y©0KR×RH[¶XùZþ¨ÊÕžKg*%Ä®´IÃFuY¯NàíþÊ$»ñ{æ¿É!¡Ànw:‚¼/æ¯VñŒJ£Ö~©÷¸Ÿªv*ÄwýD¿Ÿç*$z­ÓætiÊ›7¦�»ù‚ߘîm·ïröÞýù«W{?³n­¶ñÔ,Ã7“ïî×ÞÚ…n­4°5Óãj–ëM­Š�¼YѯíÄnïµ."õéUhø•]m½ ÒúWë֭µ·ê˜Þ%JO§;?v€¾9²ÿþªAëã,†úÊFìFGýi·6ïwØ÷&-Ýïÿµ]þ¹¿ëG®7¬V‡ºËsC®…±HoDïÿomÒÅpõ¹ÅÕexÉ×o^‰~‰¥WØmw(x­Ç›—|Ýý^ê¶9ÙøÜ[Óf¢Þõ>—ê"/6R®Eûq®µ|sXư R‹}òÚdS±‹8ß飱ⴛ^é‘«t2W¯î/òë.qmoùe¬ÖmW©÷¶ñb"òÙí9,Må¨þAÇ{³ði+c&Eü·Gñ±}Ù§„€DÇrG:Ø>¼Ë^ñ vÑשB]hÊ…9ê×(bvÚS †Â”„Ôˆ²K‚”\yñùåŤ›ÙG8÷¬ µÒG8Œ Ñ„¦ Ù”òTû”¦mŠL¥]ùÄìØSe)FÅÛ¤2¸=€Hûj³:-.ÀÁ’&èû»¨Ù¨ñR›£Wìî$#‰âéA¤HÏŒ3=(ˆ¤²‘ôÁÜè<•« ^<¢l g WU=ªyCa3{hÀv›vŸhLŽäݲužmäÚiµ+þfý¬ã¢Gº9/3€äN¬õEÌ ŽG¤©\^)”¨Ý*vÀä4…R#_n¼´¾æŠÖÁ‰ÑQì¸PPŠÊ~„¤óì†^ìƒç1âP{)Öî+�MÒG“8°]±L}¯.î³³ÑìIÀµYI¬Ï¡³în2 ½]>] Åc¢c–â&ˆ§Kî©(èüµ¶ŸÚºLíþüÎ uÅj&YJ$ÌCD£•çYúø;yðRÀEßCì¡cìö�öum%³ÿ'9ÊZ±*`CâdtqÏAs»|¼=Á’,îcËSY A&÷'u¾ÉÄÔuŠÓí[pù— L±:ZDØAÓƒy O÷˜aÑêp¬àü&ö¯‚óoïI‰\Q8-ƒ›Ly,IuÕ?[œ¾ ¡m`̺²Û7¡æ¤Þ!«x3x³´§^¨Ý[…uÃ8ÅÜc"91†Ûµ°ÞáÀLÇnñ0¡×‡"Ð츸æ�ú4S0›ÃÖG¹—‚ê9c³ý Ið.Ç„ê…\4¯„oÚutäÑÖ§ÇQŒù4šOáHÌÍš¼Á¼A™1ê2�ÇÍÍ>®>¥"­a’¦Š4ª!µÊħ4d7ÖazÔ¯î•IúUò‡êµïáý¢\òjG:;¤ªÒÖG —jî6jKõ‚y”ú{†o5tÓ– O/£"5Ž·Îþ³mßç}.L1oðbŠ”V‡ë…®­†qúêæ“§ÓW·àSµºZGy{šÆõColÑ1¿G~«§Ó½ FÝ÷tßk­k«¾²;¹UçÌíƒø•ù"⥵z'‹˜}묲6Âã½®SšMâû}TJÖñh|;æ~’ý u7(f“Yǯ?zmß|­s¬ Î?oŤín{Åt›Bzüó¨öX­2O÷G"úx£ß÷îsXoïñF¤ ÏôÝJmNvgÑ^ˬ֗×Væ\X ‡¯âoV¯ún¦› –¯¦/­ÐM;ÕžÙ—ööË¿ïuŠRÖ`œît­e9» × ëÒ¾¹Ê=ç÷l³/rѽj«ÛQ75×ßpà‘>ÂÏéþõº™bXØÏ"f>«6îXÒPYýz[¿ ÊEh­®ò­, ¨'×_Åûæw*«ä28x¬ÅÙ^¿`_ù¨ÕS5“=]e9>WGµ¥°2u±jÄï«Y97Ư¹Ô]¯.lV÷&"zÿ¢÷/1[^Æ"ÑÌ”m‹¼1wà~ÿÛm ‚næ[ËÚŸ¦þÝHÃK QÝç÷fܳ>±ñýôQÚöñ-Iw {#W1ÇxÀØvŸ:˜ß¬½¶…¹šiöbæ«9•/£¸ ²Ïs­{/2°õ+¿ßŘ7J˶kwé×¶í^EÌÞ*ó8ÓâL ¾u\†¡sß7ÇIH=òï/uD®Õ¯ÒÌ·(®-´³ŸÞîüãítú:]ÏèÚáôÅ8g¯m÷ïáh¸5p ¥·a(,.ò)O?Ïõ;ëXG§ Ñ7‹7i͉èç[÷&’îí×Aù©7ðñF+3ù»‰]½ï½Ûœç¶×[lëá}²Õ£ÌgnŒÜ‘ÚÞåðÈþfCH¿Í Ê8#q¨Ïo~)~…À-^°ì>]<‡G8•[¨{SЋOâ$²È®0¯q“ål‡>Úë‹D|±|îð#T‚%~tÙ‰jš÷=]]%‚´Ž½R,¾ëátÄ!¶«ŽCeja© ÃJ'¶}³í•½ênu‘ckUëwgô12WAÒÛ2³qý…Ùoã¹Æz^ªI|ÍK^‰^h¡`å±<£†—‘�õ\£?ßúÒíyRÝÝújZE8ÄÒöãÜo£»Îó€øÚâÐwK‰qŸ“9G$àû#[Mc½µƒÿ•íJ½Rµ:hÝþäËN#•/ýµþÉ8,f€ô éϳZGNüù ËÉ~ñ ­Å~·ýæ7Ö¥h—|©8«‰×}æ;ÏXׯí7ßï#M_Lê¹�<fÜÃÚÀ€OpLW“¼þÎû-´ŦôãÜ¡ƒ ¸Š <>öhõdùÒ&0?±±›§«ÔšZ'¸‚nEÔWœTš-SùÔ¸ùëlFšðÙ7èÛã=Æ·:#\³<fJ_O;á¦Û–o-ShRcÐpò;{,†Û!sØìYDi àé¶¹ÇÑŒ€5yQ|’Êpp e�5‡éÑV*±®ÞX|qÙ­‚$ |Gá^?»'០k-&£Ø›…™ !вUš°ì`Û½r”§3äLG6EÆf‚æSB7 ¤=¦Vq|³ž®JFGáÂ!GåDMc»$#:[Fo|+ý*e–"šA uªËùâ]S*�Vô6ë>§ÝÞa˜%œyðn [ ŠÝogø„¶$Ų Ùy­]¶u”hó0‹º­]ŸS¯`÷]‹#sk¹XyÃñ7 dê™�-b£Ü`U.²½ú—~i‰Ý…ma¯ìàlj*ö¨QÊ,fTýÇ«¢UWu ²cG$à©QQ ‡T°!V…b}i/¬ r••*-k='è™Ö¨n^­ÂÑAÔ^½HÄâª_ÛÆôÝ2ža4Â�� �IDAT+«<- :{¿×…D½dLÎJ«ë¥Ž9VBðLti9=ÃyºÀ·§YšZ[uê»M˜›)�o 'äÀúŠ@žõÙ¢°Œßœá.º=ÝsŸ6¼&=Å÷xGbÃù¦Ó‹€”rxº ˆès äò©x2±Úáe@—¼È§—Æ‹î‚í‚ÓK³[PÿbÇW>Ù¢ÛàýÛ¨/V`óôeÕ¿ÐåXq–+¬ïʱL†Ý_óXËö6 Z~|œ×D ŒË<+åøÒP3JQ3,G»£­` « ¿rJØ®¦ 3-Æõ Gç¨Àd-ƒ5m·ˆŒ8{] õŸÌº‘Œ÷±5g(|HnœÐŸ_ÍC?Oå–È5¬"ÒÆðV²Ó—‰Õübßçça~§ ІŠï6S!ò…ʸCe×파±$בçŒUÌïH‡åè¶MçƒU/¹ ]¿Ùµþ¡]‹¤Û"èì†Óï!OæXÝçœl1)–Z°²xq"Â)–b qáO';¼`²Æ8¼°¹2Ü<Éãù:jWø(Í‹L »æâ'’ÌÓ÷¨Å°9¹Ã£î­<JýœÕ ªb&¼ß뿲YµŽÉ ¢\ØÍÜêY¯s1jµÃðî4·Ѹ압Ðg‰>Þ¶u½æ­3Gµc5‰qÌïEÇ…U.’œ²Fžë¥^[~v3Š'‹˜-ýxÎoUQ ëÌCÁý¹°’�«R«›>ç3ÒOʵRxââ®^ØG¯²Æðóçʽ˜_å÷ V‹{¾Û™{5!¸°„Îê­øwSk˪]ÊÕʶ‹µ•‚XªöüÇå6á­c £2gjHC£d©´I­´‚‚tÿߣ°ZÚkÏÅÿ¹/½òkÒfh¨=S¯ ½A X)f›º|ýŽ·³Šò¼Ø²>GèR|Xȯƒ¹Ê4ú[Þ9ãâ- Ö±&;¥©ØÍŠÃÇó9aÀC:}{PL DüìÙv7¥PxÖólôŽe¹OàÕªÏ%Ç$‡6¸a¿¤—[¨~#qÿMdÚÓY€H Ja”­-îOž–y2ÇíÀ™>TÎÕs$S‹óãìË£(M‡bzf3R%(X…Y?²î:"«—Ê‹UÅP7z•}߳߅V°10ÊÉF¤éaâ‹ìMo¯ôK±~„£ëO»‚ÝjU”÷-%,þ¶¸ØÐ.÷#ön¶ Æ*÷‹‰ô„?V\H6Ü'œŒëPØšŽƒÝÐ#nìøNª§ý‚tëƒ÷9/λù2(;ƒöO_¿ÀeCW,H’÷­¹ã!Pœ»8<{Dý•^ÞïµÙZÚyR÷–vÒŒXƇá]bõ,Š+B{&ãP2@ ¾M†~7-õ+û‹’–°éšgi/öÜíÊÅU ™Ù+´&2ÔFÊÑ¢ƒ¡ãp”§=9íMC\ÈøSa”þ"”™}v¥~áÆÃ0V1ÎÈ·%ƒSŽëöP¦#TO9”xíxÜ9¿6y5š0`œ‰.V“-Þñ‡@¯R[L†CÌâK;ªTÏ}ûÚäóë ’:qÑ»OÑø° 6]ÓemaÕrÍ€mˆ…ø ø[½ðŒ¡5ƒàJñÏ(0ø2zðeY‹¼\¡!‡å‡JJb4²;÷€1cå°¨ŒwVÇ [¾ÒãS\óe¸œ£vòä8g:qE¼ÔA¨ËiX™#Ï4'K*µÄ´°àÒÿ`I%Ðàa³QGô’Q©çR«ìc'Ú.vt̳ÆNûŒ�'²p™‹0Ìiâ=ás¨ÅŒÇèœiÏB%Îb°ññä ÃIøŽÿ­ÍŠ `åJ…=:ì–„<Ý-ýÁã)Øs±ëé—Á=gß笸É(œ`°¨ŒHÿÞÛg]Z9ÄWY´�öW K9´» ­*]Bª¦…0Ó:÷êä‡=c$öz‡¨B„ç•·Žxx°éY;f©ä´#’™œ€—]G¯3»6[£"¹0,¢r'ÇPÍ‘�K­,¬–µúWA( CAŤm)1óbjõª·—üŽ×.š` ⪳¦n\Ø t40ZqóK˜VÙ{ø5ÁÄ0;TÕ$­öOÀ(Á$ŽO µ‹Ó’O‹ßÿZ gòÖªÁ·QVå•í^g>î½+vL€^Ô½IÕ&šÅ)•FÑù«p¢.lù ™Mž€±½5GæÖja¬nÖª¡$‚ê}‹M÷³¿`™¾—JX¯ò•详ôóÞÿ]ÿ_«¿‰ú+Ý ¼~ ý¾~m õúËßCÇ’ ¬ì™W’©ôúÞ˜¼4á‰Ñ3ýüµÝ§aêæ&!þÇl íYôôçW9E¹²Ã:ÚN«¸Fß VñZ9¹|Ìó÷»èIXYOÈR§ÊènNÒ‡ÁW¼IV¢ÄÖz±° \ƒ£Î¥&0qnÝÃk†?å•uÙo øÎ…Išÿ2VëE‘Œ«­lÌW9ÔÝu¨®—•è÷}èruÂ˳©bJu[_D=ÍRfU˜yá10jמ`—ì0“ÖÄ9ptë@y*óp¤ÝÛóx+3¦ÈkõH–ùtC7Ð{5GKÏð0¨Šö:!³þžvu«…xo ×!·7J¼ü† ¯o”ÈiV•³Í¬žß3Fu¼îl¬HëÉÀ uí3F;E•Eê{yžõ§ˆ èú¨W ~kU¤³S½/.gÇZ `l<°%¬\\'Ž d“BÏšziª9£«‰¹çYÃJÜY4p®Ã!JÇ‘C5&“5ɨ¿ÉÝIâ]­kÈ;:ºŸÆÖï B3[3#H™l–úCñ‹£¨] 9Oä–+E,ÌM‚6ÞÅ!AHNÍ6kaiB +„ìzÕ®§§¾")©FU…¶ÛqvüÔ-F c˜òËH¿ŸäÆ3ìK” .mîœTŸâè‹›V0è࣠ˆñ‰0!ʃѳ€R ZL!! -Z„§RBbç¼.‹Y3ŽMv¼.ô¸l¾LÖ;\2BæýÖU+·¯ÊNýËëÄ_]úRñƒ}ÖÇ?â î—UL»˜¬ñÀ`÷¿”aÄŒŽaá-)MéÓ\Á @òœú€­ä“_)&Ŧ4_°q9Üô¸Pêed,—”n )º…nmªÑÒ"ìd€î¯Â?p*@ÑJÛºóÿïþ{•<UØìž´Ó"­­ª²Î @í*ᢠ· `Ò¦éjW’`MלrÏAÉö�Ë‹#NÆEë wqÈ/Ù‘1ão9kW-rÄ¥À)$ƒ&qqZJ ™F¬È³a½ªãdˆšaxA§óy*ʼn-9°sÚœ8Å$‘dÒ¹ø Çy· tgYu}œ*è(æ›>×gC—*ѦO¤;~8¸Süì¾5%ÜÄÅnEHȲáÍhØÉ*eLLÎ!7¹@DÌH&Ñ»â6;Þ Ÿ1EÖðúI³>רfê9oH ›¥<`ҙDZ4j‡ú^ÂÉç›ûPÑ8Ó> n3×Mîa³²?’æëÚÙá ¦>4¡ŸrYüBö¡òL`å.Þtž3rœ©W=Îû _ŽŠdq|ŠQu°LÆ-+) ±ØG™ÈEÌ=3\`—T^Aq´8>¿É?pà€L¦ã•Èi7ÙK Û˜È=#{ œN°®¦1[Ö¼éÁYâLP�¤u³$îgq”±mª–š@­"r"•U·ì–gq0¯ ¢¶`•F»K#,Ô8ñø«ÇÂT[¼ 2E)/êÃ.ÆdIÍÚ:§gü#í}šü–¬Òz+ ¦¹»QðPk¿µ§z>Y€?*¸³ FžR)ºlàÀÒú’éšÚmb‹¿ÿ‡_¶$�ak»¤‰�ã�VA ÿÛ.*¯rkÁL¼Ì¼­ªàÆ8ï”í=©pá³<çf£=á˜ÞâkGbïk’µŠFŒpxôµ" ?ŸÂŠŒÐÕAgxòƒ•3c–°à1 ËÛO­ò\j&Ù JÅÙÁÓPW8P2LŽj~Ö¾ÆßA4%&¡Q»ì§]ÅݬQ¶9³P½çA¬ µâ>¡Ø"+øŽ¶¿ÊÆÚjóS¹€¿å"ZBðû¢´«­§l´”‘qwioâêáD˜7l×’Ç8ŸÉ¢‚˜d}#Ÿ ë[¥Î[;ç‚ßýûão_¯ZéC“'æÔ·1‡RYælõÏ«Ã0—³É?€Èép–ƒ�À„Îä€s ðN¿¶¸Í˜»h[#¥L¯^ÖP™{Ç î«„(ë'¾¢2ÌæZDí§Ì©®ÿUKö‘QžìBšÃMøSÀ˜ãM1KÀú9%úµýt1ö+Zn‹XGúö®Dï÷­ídofáÖ¨—ùæƒõ=ÌÛþE<o;Ü÷Nh�®uâ ó§+ºÕ"Ú`8ß½ŽüMþÕ&Ïø:|‡EòÒ›�ææ9Ùo»NøE›·}ûã­²ê×±HO/¢GBs»ã66-Äe<ÂÐ?¼°¶ÅøtÔ¹]/hÇ(lWi¾\Õ9º0›4þµÛòöá¸É¦ãéúÖä}Æùâ ?Hbâæ_HÙÚ­Æ¢Mq©ï á|—+è —@dãñËã_Ùg׺æÅýK˜å 0‡dÈÙ¥sR1 q/g6¾G°@•¢ÞUð²8Ìâ‰Ê‡M©è¬ú@~œ}׫‚|•2A”Ï¥w‡äu­"Ù…6“é€J¥€Ù$4R„"%Pè(ÎM·)Þ.4íPTÚM„:ñ‹~5º1 hêN ÙêÆx¡vŒ‘L#ècàà~ Ûð~ÿ�»h_Ô]{irólï@´4�=-]GGH“‹PÚªŸ‰X3ád–ÌO/ˆ(_­¹|ƒÅ@’Yu ¨¹õsz"ry�™”z9 þX�Ö ²ãD±-ë.—®„2šrÙç_¥z" X¨>§É,ýoVì$Ÿ³.¸òJ×êñæaƒ6æ)²™Eˆ€<Þö€´×¦‚‰y§ãÐÃZcQDý¹9:êþ¤Œ5Ò‚31@ .õB`ABÇRŒPã&–æJ¸–¦ÑÝIæÅ<»lÚ x3»'ù¼ù(ÊQ@:Jeœ”BŸÔ]œI='õ=’<mz‰®*+Û=®Šç*ÎiòN­®³³sÁ÷N„Z¬2èÿPû)ùºšX‡;;½ºæˆð×E÷n6^´Éw**†“ŒlÙ±ˆÃ´Ìéñ“Ô~×Éæø’¢Â³j-‚§É: ²),XÔA·eöwØdJDŽwóÎìõxÿÙ‘-ÍHtß’é ]Ÿº¹âñÄlʬ ªše}°PTROXKï'vlw#Öþ–§Ò è½ÆžÊØâ?9ЉÁ³ÿ|0znvÐyõŠI8ñù4+»Ô8±†{ÓF° 5xT‹ÞðkÉåÅïvÊQ£]{x›.íòÄ.œÑød%§ÁËëïޮ̸ï„8¢ …ШeÄé š#•j®{«w¦¼‡›êâôKe Ë“DG§{:d½g—ø@¡º7Ø73 D¹rœ2ƒe ‘õ„´n Ñ©1» …UF¶qѾz€BœjÁè§MiÔ7¹v”³¨ G›©äÏXîzRÖAš0÷ŸNgà¾À×óçbç8'RSÂNåOÙíŠá ¶Âäiòž²;œÍŽ0ßv×Û¼ Ò o?¥CºÚàY zÒ´ãX¡ÌSà̽2Þñ‚cƒi}ZkA<θïPäx{d}U| ¢” D¾Ëprð·‚|«“k×àš¥ym° ˆ[÷¸¨sÑqpI€ãµ¾iíZ~“þÍN%X¿ŒË´;|K#ªd¶‰gŲ ¨°²G˜c·؃}ÖexØå®´D‰n#hj™iŸ:TaŠ•/ð^³—>>G{™‘ó8ƼÈ�qAªV “€5êH ê«fp÷)³ü— Cæ‘8*ˆÌc€´Q‡"O(fGÂ*G’n€vQ¢s†­ÀëèÈÈX|¹™,Ê€%cv‚–©ó!‡ÌùA¢Gp– Ô|‚Át¤æx{’ßz%rܬ»?Áªt Y@Ž€ýˆÙil‚dºhê˜ŽŽºo½ü‡uÝC.jäžÂÙʾôøs©ÆdŠCtøv!Ê o›'hx2 ^U&†éHë[œfáSž'›öxÃz):GƒV\f@á3²*nýÒ£liXÏóE>{¨i<Ï,C/»:Ë-Ò¸O‘Ê^Íjð8Á¾–QÂ$Í‚¤³÷c (ŵÂ?–I!Ó8!ƒâ¹µÊÈÂì0(3ã^f˜1)0†µ4ã`´­áŠÞ¸ièRÍLÎ0²lþç�8­0`9v […z+L§Ïƒ¾(¹Î«Þ~­9œ’?c#"–=kf fëžBšh×�g4€÷JÁ;cï1Rãã]Šß‰uÝ!s!Yµdu÷‡c_ßí5õ–ˆí«IV¶nŒß_âqrkÔXðÁÂÝD¾‡ƒÉö¡£¥éÖüÔHöYñ]G¬»E<r3qP TÛjÍËð=_ý®rðWiércïèÂðïûöY£mñe¬ê¤°Ö^ñ¹797nÕG¼ß+mm+µ£+ œm8_”Öèó-îÿôB§:î¢Á‹wѵV³áùBÕt†~œë5ßï›cËö¿ÇãL}ÑMö/ÒøO½WÜZÓRóਠª¿ß[s„ÙîSŠbô™°õl!•bE, ÌYÛníGWf‚ó Ô­j³à§öì=‘—áhÃ]]Æã‹pýèóalw—ö£,¶¾ÑöÄMF^Å‹ÖXîkbnîÈëc¾½°Gàcøûη)Ñ¡ø2fÎé…èýþHÕØo_l“…qŸ!¢cJ¸1ºeù�î <6®¦=ª÷LÉ'¨«ºÃÝp‹é@FÕH2/`×-I:5Hîj t6‘Ì yf»>Ê—Ç=jÖgK@O/Ðâ¸ß"›Ê€ LëÛ¢82TÙ­Ž¨R«&*U©ô)»8jxÒ¶8Æ3T¹Îsš'G CŽÙÝâ„ÖwÈ®ï6a)�βå@¯€m1X‚­oèu xÀÊ�îÒÇŒƒåñi{êUŒ„Z òœ’ÓE;ÏSÚí!ÐsxÚ¡ºK`Wz&‚á.ìbnå€êà.ob&�G¿_Žéi% íbä°8<õìn¬XÄîIktîЙ¢ ´=POXÄItþ—î:*sG+¹Šßéˆkvà£;@Žà ªþœ)Š)7Á§Wè"VqíE/„\ Œ1ãBˆëVt¤È£,i¼+Š:É)…‘Œ}q—¡iö(“ßÉ÷q²k@áãŒ$¯¼ê’h²S+˜]ì=F;'#ÖL gRtuLj$OíÝ“qh×Ök·gBù@þ\gþ ÿ`3g¹´’Þm•d­×Éø•ùôŒ‡:®<»‡¤¼—ý5ïü w57t5 µà(E Õ× ®<ÂapzóY\§ÌQB)bUÁÍŶŒáÂÙ¥‰zÇb›ËÛ—¤ŸÈMŒRäÌ)GÎæ/šÈ -T½Ð¶‚¹]ɸpeL@ÀÉk1þgEdi:â2ÿ0Ld•Pˆú„ u¦‹_·‹ùý ­ÏGÙí lg÷»½ç0-ï$5#¶?Ž[qƒ¶G"Ñš.ò©†3Ø#¦™…Q½eFÑuã‚@_ÜmÙ}äw"ÛÓ.ÌfvÔ`3J3F±f¨tø`×39]Dú"À¦òíõ´àÒ=‘išÙ­x''–(§ŒìJÚÑwap¨žÝú1Œ04ÈÝc7à ,»L„Œ%“HˆÅŒ’ ï*#J˜â;„X Deƒ`ûÊR€ó’¸­œÕ°*U1J(¬_Swµ ½çIô$*x¤‹–¦ !hæú»L¹yX2!‰"aü™[ŠÍcˆŽó¦ÑE:Âç ^:ÜÙEæžq›ymÿÅ»ç x8ÉáT@·c ”=>Àvƹ¹†Ã«AŠçˆ?ÁM“È)_1Цެý÷7ñ$EŠCŠˆ ÃYKÁ¶^ù`º{6ƒ( ÛÑÚð> RI÷ÌfaÛ5…Ã@=²8[GÁ@„³Dù=>ÙƒˆçL?€.[F0r­n³›ÓCù,Ûi¡‚;û—ïg§î^2÷VhþÐÈ#<áÚNû…«XçÀ9�ª¢åýÌìÚEB2t¬ùÔ#¤@T“üN ÚeÙ¦;ŽŽVKR»$¡¦ [yÆÀl‚¶æ2Q ”ew„‰v°V¤Mv“Ç/hÿi,6ãĸbz¦ÚRH!»·1=Þ h샢yœç‚e'Ý– ®’•1K·Lt‘©ÐzµF‘㨩= &p*òtž9ãÞqº<ɬµ§•Èï:‘‹ x;©§ª¹O‘˜‹m»èüL&w”Ñ÷¾c’»Û·WÂñê4a‘õ„|;$2xH –€KÚç ¨«5ã%ˆZdÖˆÉzÌ @Ê(Ø`~§ï5»‡V@¾‚bn&ÒÇ57¹»ªDá¹RÄ1ËO h5eà LŽ}bBù_�óòJ7 gÕë‹m‘fù4…ò²ªc%KÄ.»|ö¡ÍÁ9Û#ˆrïäïH|hñ=½¨ïBßjrÄò „zñž¸%ó½~¬úµŒ!è^ß¶[Âôî+¯¸ÊýrÄ¿™å’Ç‹­ÆEŸÒÈ uP©oö.™C1ŒÈØe9-_1¡6Téî®|z}Ì‹t³M3¶Ûlhûɼø:ú¨6˜?ÏÂÊHöE= kÎè¿ÉöqîsƇH½Ä­o¯·ññ©H´õšüsÿæx®ofØÓ’Va®3¦Í¥¶ËðI5þja=dkÿP"bmR¼A­5¸Ôæ˜Ëæ3t4¯µqt8-fÎ_Ø„ll}ðOŸD?ÏDD¿ï£iK|?ÞFoMëÙê1VÙ·ÆÓ…è[ؘÕ?ÉlV¯bÚÔçê·}Ó¶aà )·éº°Q¥a¾%Φ ë Z廦æM•‰nõÏOÑT?ý›Ý[s™RZõC—$µõEmF\s½«×Ö •FßRýÿ÷ûÖCvúlYB‘m—:½ £¬zàø6혧{u/ÛÎUlƒµ)0Ñãñ¶Ý^Hk»r›ç§Ó½7üѳèÀ»3çœZ-Äz»Ø6Õ¯â|vziæm¬¹Pl•Kíùsce³}[à§;ß«ûÍ×NJ¯ú¨•pó±¢ÈnUæ ŒÎ3²$_)îOŒwcV¬#½þ<Ešð~-(‰=-~qøE8ª3ºþŒVhnÏnÖn”¯½:Y6´º¬OÇDNI?ïxnáº7A£w¥ä”]ý@8n¶< Øhž|’¢Ge†YNÙ)"zƒã±û´s®i*"B²O°“)‡J¯ @X$¥“õ#=í‹/&d ã³ÉE²¬!%,ñƒ•9³»éÙ~AÍhp&*2EË®&͈Åqd–œ#KƘκ2Ö;À¼˜ÒnOû¬¿ˆæ>'ü¤®^4¥=EÔ?w”ßEêcîQÔ÷ó7d–¥’È^XÔ…<!Π‚¢éÙÅ?-”§|Á¾®jÖCo†ÚähÕèÖã—¶ ɦàÝÜQµƒ¤îðÍ7–üd¹”J~° ¦ï¶5ããKÖ½±¶àOPnØw3€’á‚ ™1fNŽÿîqÖö9"¨­{–±Uvö'²Ö¢U®âJ\ê~¸¤ß”u�²Åð„JÐG&ï¸ÖAÛF¢h'Ñ6˜G#!û {L#(<œ÷­°füJ0Sh¦£û óp—¿÷ç1o2îÊš£ÎÞC™XWöÈ–qü D Ë>¶]Ûœƒ+æˆ-…*Ì aÞ·‰Ü'KãWØL†|‹äò¡U/4=°ºäÐí”/|w±#e8o½jÈ/ _'ÂúרT°èÄ‚‚öá„öVÕDeÌ$#?h^UÍ®»Ï`Èô™‘o5ÞouArˆ9†šã«[îõ ·xK{qçŒ>õ¾{S…óÄÞãE¹´¿ûÏ$éô”îÑd œÏ(4LñF&qz�;8H¬òtHÃ="Źç‚Ñ'”ðlú¼À`ä!pù,âÈÄ"zYÿ§ì|9IÀƒj³çÑEPo±0"H ¦®¡¡�àm`J«W3q’ï°¾kš}dÉc*Žh9rtÄþ“§e˜á’®.{“{ç.ÔÔ‹dG“âJ8´ÛÓ X˲€º>Xõ9j±Ì‹‚[•Òvìt†¡I •døCøŸ£z層Úëô?LYüçå\û}ȧ𾠥b\ü«Ö _FÑ5^WÍJðÞ•’‚þÁÙ$3F@¯Š_+30>^Æào%Üú·¯CÖs<ûb˜8ë"´V\ceä×&¨zt›~?|Šn%ý1«oÿ©½oבdI²³¼áÖŽ–?‘B¬úƒ!•( @\™â¨©Dm¥Rÿ±…•S!øÞ�[(P\…\!ÁøèWá$…ðp·Ç1ìÞ¹Ý 3 ÷ÖÍGd„»›û±cçȯøh?üp!º¬ÿó*ÈË^Ö”[ù�¾†ÑG«0ÅdV™‚ÈYü§B˜ Ë@OÌ™1S®LÙv©`×'²Œ½*~ú®Mö ÍVbÏèe½¶s½ 7íúÃò�� �IDATþÊ¥®~ÏDtx¡;âmÕŤ~TBWö½W aÝx÷ãBÄÐ:ÂÝIð•„N«ádµŸC«&ïÜV'®%}x!ºqä…ÎÀ?Ømàq!×k<÷u+xYÙ?ˆ.TE„+‘m¹†FFx;Ò/·åÔj¹Èß©‰×™ØF#»ìòl„ßëZ´èÿòþùÆg\}Fe6ý|$º ‰óku ©BÆ\6ºÝóIð_Š<ô“^1󂨯mjuRå 5�Ju ÕÍêÚÈál¯FâàqóŸ;%±¡¯H½BÝÃ^\n16ùä`P–?íËŽ@q`IîYt½*‰ɶ œˆmÖÝû€é“·]-DéÈØ(C¢ykÄODnð™¥ýÓ1/†O™È—`˜%À‘M²Õx¬GgÿN›£&Ýä–/½†$KÀÐnB§ô]½>¥Å•¯òé&ÓÕ`›ø%ÂÂ}¸¥$¾ VKÙªPlÔ“èÇõ3‡î´¯ƒx°ÑïaÄ©ƒeï K S ›Âqý4<ˆ|B°~¤´¶K„v6cá[—zÁš‘õ¬ó ¸\Ä;Kæ.8™%’“6ðROóBe8wC釤›Ãz#6¡"J6_Ê«>á&brtÑ<Ù~Ü„›7ÆðÐJ«”ÆŒk6d]:W`ÝQ„Z¤­5—•PT [ÐOKЭ3Á6ê„Ø³‹XB{âNõÀé35ïUãþù½š¨R´Jò/¶™/»ä£VUíw=w¥)AÎÛ¥yGp§)ØÎvw‘Í;@ØÇÖY¢}V›GCϨîÎ6IDzôÍ‹»[½;Fxž žÝ‰W£Ž"Æf«#l¤õR‹ÝsýÅNnMN>².•{&–lJÿªõ¨rZ‡[eO¨P½ÔõD‡T±´4{ªÆ¾õic©M)-•ŸB`‘ÃrS¡ÚÊ¸ÞæR¬Ky‹:‘´Ï!PI ÃYu%{¦Uê)6Aîìh3…|•¢2>»“†×¥Ê¤;âu„’ie´ÙA¬n w;ä=˜| «¶P R{HàûŠwû¥,ÝI꯭õlmIµ‘z×SË^e¨–Xàkêm±_Ñù(2Í¿¼Y»N PÏ#LW¯wc+ø¯+5’Lt^{3‰èõÆÛEÅ„—ÍK;°(p>J^)Lz°ÚËæ-í¼—\=b:‹ÊÐrå­Þs.§¥±G7Üw*õ¡ò®¥e•;éqŸFšˆÞŽõVÜg¢·£ð´üü·ôvlõƒé`Ú¼På%›Ý«keíÀ-peU¨óZ•Ikõ‹Û3®¶{­Tpj]ÒÕ-pinìE®Ìñrí¿.C嬟µêý¯=¤ªSÇܾˆï'Ê•\ÍDþ|+î—X¾jÏx¿nÝê—ïºJZx×O+]ØÕÒ³<¾ËÂ/˜ÛÈl5ZË6ÌURäûS3½Ô%Ÿkéa§w¢³8*•9u2il)­½Šâ_é6ë¹²ÞmŸözkž¥¬×~Ñ4¨Ïm0¬_}Ñ‹­2‰qÅ;ìŸ:k–XŒ®l}™K|íx‡'ªMþ<Ô•¥/ʳÈ\3&-«j¡ÖL™dIVšázÜ K—ƬI”‹K§úEŒÔ6Û_°hÿùÖ!zAÍìw½‹®õªи0k‘|™Ãu}i—÷vT¦Ž|âµÂì þõpiª†Ä%9ä#æEoΆ¨I«\Ï´®/s¼}aÓ¦êeœËš¾2ªüDY­Nk[Åž‹5p•6(Šk½®ë2}–sõ—/ezO-ù‰mßjdÎb3«F`™¹œò•4ÌÑÛ±n;Ê”Ïl€ÕüÄ\žëR[’Öû:éžÁꬃb@NëÎý]L¢òdW7çÆ­`ûÑrsž‹üO b%™ðJÅõAÚV{b{åv½~ѽW‘•—ßx -•51ˆ|sjÛ÷¦!R­Õ\®Ò,­"Q1•ýSe6•±ýÑÄSªðŠjcâ,—F ¢·ce]•ýD÷\ödå>_Kžn)#µ‹Ô?'°ÈÔ Pˈ‰ † ,P¿ñØbÞAAÉ4 YßùšeÿÈ—$þuŠ«Æ—KÆSÿÊi`Š‘Â¯Ä^¿{yâ[&ºO…þÔ¶ðc™À~²¾�’'y€ƒçBËZ¡knó$ßåZL…ÊÕþø¡SNÓãùåÆÝÖ/tŸnuz–ÚÕlÇ®bÛ^O÷™èõ Õ ¸°o?¯D¸…Y4Ñýþ‰^¿¨[W.faFÄ¥®¬O‡Ã1®Rs£i/56]™c'vñÏ+uma^)¾ÙrUoÇ;•”v¿‹´Ò•1�Yâ¬C·16+SñÒquäÐÇz‚¬TÀ3[ —øÛ'zýÒÞ2­³K9w65‘ž¦ CeÕ+‰YQˆÏbäpž˜†‰ÞObØè$M‚jX÷ˆæ¡¶S¹Ï7°s=·S~[š Ý´Üë„"ùž×'µòëÊ翳¥ærk·}´êösNRQarÒyÝüÍí–ª%Hl¯pØ>üE×Y;¿ž ïÎöíš_oúÄ“Væg€Ä]jJ(­÷jfÀÃå¶Ü½ºÔmñáB÷t«¼Ö ® ÷„¤�B$ý~5hA°i.¼I¨óúOGirÉ¡í¥ÑªÒ¦¯üã`ÃVðṌs]õîŽoýŒt¾“ïèãˆVôüN¦…(›‚V"H(°\,ûÏ‚pÿ#TC°ä10x²Ûx|¥ù,Pa—?PýN˜0¢xe€Ÿ…ê“Ë”ñ¯=Îð¨ÄHhÅD|¥}ógI¬˜»fÖŽô­­Á§éUµmÛ–V‡,Œ¼±8�6R´J>§iØI•P7¡rÏN—1’^ó„©Dµ2ûŽ\Á>#n9ÍrwQF^¼IÁÄ]÷3NÉÞ´¿ýß»¦ë:÷©›{uEÕz$£ÞäÐ]^urY*€Môj ½Ì­c/ú¶^xvô÷&,®Cäò/°y‡áz@ƒ+ØH„üY¤1èÍÇ òV^îDæpOŸpBÉ! ŠAîz-úžÂƒt*Ë­õ*ª'6IHÛ^ß7¨g/7ú™ImÚ2pÑT†sBLí~xþÎî#†î\€Ü”±G¶º$"옣k†Ê.{¸ƒØÂz#@S¯Mõ´M€ ŸwðÅêv¢êŒn ¾=Ï&!KÜ"áPxn©ƒ ™¶‚‚pÀŽ%dWÂGƒæ ÜüTþ¿b �aпՒo/þÐ�`íyäŘÆ;¨Ÿvi$…TdìùH§[CÞOëýQ×Ã{$ål Òè_ûoÇðiZÔËç?:¾”Ò#ÿÕÃF¦S%Þ.woÁ/¢ÉWÔí'­+ß:OËÓ¹-˜Õ=ߊæý ãFMt8|áOJ †óª‰Î»žÚCi8ð¿¼ñùH¯7>eʇ,e³ÃŽ`Ó™è—[c<Iˆû¼"«»æLô±BñI•W‘Ù¢†Õ=\2ƒˆ~‘ô,ðj`ŸA»¼;‡1Y£táø\Ÿå"‹j†}Іe–ç…›÷{’çÝ«èC/H;CË7¾ä³=©wSŸ äCÌ©¨NÍ~¡�ªŸoåi®°yÅ¢Ë\{gÈ6±ÞçëÊcꣂ„l%û›úúµwæ…-&CG4Œö»'oò½Mœçâ ²4ÌPéBë)¦}2¸ý3¢ëÞd-Ûz™¥ÎºïŠéɧB(+iq9% g{›@GKr"Ÿs<»»{ ñ¥žE@§£Èš$GÃÌší–œÎ-a!½¶3Ûÿ¤¿NZ—H0Küê~¬*yz¨TȨÈÌ¡PL‡ì ûy‡ ¶‡Ä(Yp0J¨QlçÚÞ$rtÖ1j’ùÁ䟳ӓ�Î4+÷‹Blsv%£jÚÎ�Øw[Ó÷{C™ºÖŠž¢ù–ŽF§ö˜ÅÈ×mæ?êJÇîÅ6i@sÚûÆMk×][X¬r?<ùÆR­®çáu&fÿ†§máG¯¯ ;M#ÈB 3Êà1õË«EÆRßÀv ©V$2+¤Ó¡Vˆ#L›·\M¼.jUŠ7¹¥Dk�M‹“Ôõ«…¦ÙyôVf7¹“ZôäÍX×\Ø»ÌȬ29­ä’r‰Î<ƒ2-q1\«íü‹Ši65¤ÎmÏr«QX6ÍïÖóÅZ¡&Ó,Eë-<¢Ýî.ÊþyhÄ»Ÿ:?$yœxòMI–Ò迃þó¾cS‡ŽA¾VÖWª¹{-„`pŒ‰¡�>ص~mÕÔžª&D¸·”ëºz<\@žÈ®'Uv„y’¿Iø zg¬Öéœýrš7UÕ+{zƒò⌕·ÕëÕaN­hê˜òw•$Ÿ¥ FWR·>|o¿üœÄì›féúP2ÊëÉ(•p–Íý¾øŒIòÖ±›¯þ+92ä‹ Ã=Áæn´d=¹ ŒNÀut9¾+õJÞr9¢‚1´©Oþҹ倅ÿ9mêÆ”p’N=̇|¹ÆE;‚Ü›Éf$Ø©f»be©+Fœ7b÷ÈK¡5PÈ¥ü´*¤K �òeν]šçN„m ‡"³M«gÆ! ?áÝÉffâ—„¬ŒìAV㽟ƒÙY—÷‰„£€¥Š 8í!Q-ó‘ bœ]š8å(ɱä¾^1E-§ž¡=Æ#8ý/ ^ÕèBlxš¶gÙ¡,ή©¦ö v•^— æZ\žãÉŒ¨:Éá ž±zxàðv¾CûÁÛkvl!©‘ÃÜcXDÀ:ùµbëÍá¼QrÛÁNL(-ùIÚšøõFHêùJÃË€žÅp #ž¶á*;³SIx*^ÌÅoæžm  Ýs°ñþoõ>3¹T:ûPˆ¶lŽ=«ÙÊK½O®`¦Ídú)W»êûQ”m6]8À‘£l+’­•erxá3:¥%-ÖG„­„-ÞàŠ+ÎØ‘—Q‘³u|P3¨ãê#rÖCPŒJ:Ò -.¯&{Š ÛkÄ‹†»£ö)¶»1òÂרkuÞÞÿØ]ö•Ї~¼®¶ù[¼nבWùÖC$ªçú8cþö¯²M'°¼œ1m¡óFW%ÝG’^…›ª=Xn±§½i鿪Ԅœ÷ð–<÷–àαéÖ“ï�™@ @U nŽ´i×èS×ý¹e÷m¾íÝvSÁ³ žÄâF;£a”ð²“;Gfw; ÄkXªî$ ÀzOè’„iƒ€%³©üÍ.á ¹íŒ•w”¦:'ƒ‘œÑcËx ¶y¥Ü͹d³öö£wŒKâë Ê~ÑT0£)$j¿)²AGÜ–|-ZòßûÛ%ûa!îÚ¹àRž{:ß¿š|äÍ ½•ήÌ.ÆiíAùbØ-¼~eÆô¯ß¶¿­ö¸ ƒÊ¨ä ý*“?ö2*¦¡"¢î¹¶èœ²ƒñ–£¬OÕPdÝ+ÊöN´¨e |iò›Þ$¥BOÏŒ´ê—ÍhÌÜà�Qtr¥“™ár_ ·êÓ°t¸¸¢·Íî¢ï§r«T…îjâ"$µIÊ[žð'.Àpnxƒì3ãçw›V/&<Ñ}Z/MÓ¯¾¾5»0ÍSbj„Ä¥-/_AÁx;ÖÞ©f.Ç++Ñ/ÿ‰jpiã !9H\fíªÿX—™Ð~ȪcÉ]éÊ7žÌ#{‘·è½HŽVå>Dë4¹&ÖóqŸ‰ž›¦—š­ZJeö¾Kmª ¯&­ÑgZÕÿêݘD‹›^ˆ¯L7¤Èdmêšäp½6òñ^½K“É©÷ªüñÔÔA›Ú»çOëÔ; :LÑÕ|‘bÓµlÑNœ¤Ê”|#¿É÷܉j/W ~Y•vO$4…I*±±%¢ôåU]‘?äµYÂíBQw½…‘æë­æò÷³ÜL§Uˆ¯þðUëR4‡qD6ÔÒ$”<WE«àW„ Þ™"èr…Ló‰D³`¹á‡/M*–H4Ãñô|äúOËÛÛWWÁªs‚Òâ2þ…à܉ýƳÿÓzŸU ²Û! 1Âåój`( #ÎŽ(Î {ð °¤ò°—oX„óа*` ‚ÃÊìn*û7JS]|âÉC40è¶gëpÀ&œ ìÛ;<L›[ŒI…_{? ï?M_Ƈ$ü— n©³‹*uX×%"Ç0>Ë%"RZɺì‰Ðñ«É2-›Å½R²Ž Y})Çyûï¨2ùÊé°2Æ·“Oˆ…ÃÃJmetRDk´‡è«¨íeÍF!§[Ñ> j+aãÌ‹A³¥Ç¼nGº~Åžö´" -¦6‰#­`»ŒÄ¼Z©è¦UÚÃÎ߆(³îò³¥l›`•Þ*òle,?ª•ñ Å ùþÉÂ8^‰B@Ég!9¯–'éRDÅ6êvè ¶-¡Ï=¢#tŸòöˆxšH&7¬â²GÂJz�ÔM]óXª5w›ÁñVe™&8x2}žm˜.ÔIj;Þ]I]%àR–zœ>š»¤Ú +6yÃ}Ñ>”¶;1êSp7i¼¯Žæq•éÓ6*¨p¶¯IEý9àå9�<òÓåÕUH)æeÊ}êžÛŸ¬½K.øc•©˜P£Oýó’1”„¡Q{â*ãÜÉì±V±ïŒZD›Z\…ÍJ Ê_ÞÁýiR «9N©/Uæ# q,x½УƻH™ C>|)Ú0W¦ãžÙ5LÂÊa€ªpQ{ÍÇkÒ¨²€4/W7ümõºå_ývôÚ­€žÛÅc¢ú’TôæMÕ0Õ·#‹ìú™YŠ˜¯¨¿÷~?òAE«;Tuœj8•Kü¬Æ.%ÎÁ“‡’2Blö¤ñ±æCvmž; c¼6!¥ŸT_¯¨Ï_ŠÊ;Ÿqg†å.ãíHÊua*ž 4›VÈîõF\ºþD÷D‡ÃmWÕõFø†T—œë:‰¦ýÝç†éU/Á”;<³R‚<W•[t¸5 ´kóŠ*;˜Ó:Y^ vG«Gæ•SWÕ\¿ÏÅFŒù3ÑÛ'’BV.þ—›.1¾ÞÊrqbÃ`/*H{Å=êà†ÞùðÑm„’7’hGŽPý£Õ.ŸGg<Þ=vlúš“†a¤ñž Ãß%cÝ+ørKV÷Kë.Îà{ÛvN‹¶uпº^t+›MhâÖºúmÞØïrUÅmä$Üè Ýü•|j–\ƒ©­<Îzc 2¡¹*îý¨¸'úDUų‘|õpQ'™˜¡YcËD=‹jŒqmõ¨à.‚ á”<1ø´=C1T3cà„¸[ò!õ,Õ˜¯P\¢í†n{4ïÁ6CÚí[pÖ¸8Ó×äÁ¬Ù¡Åw4x6k]»òÐcùcðӯ坾ÄXðzH¸·³ÒÙ!Ò®8oA|r´^¤º¹X%ÑÏÁ³(¹ú~l­ØnDÀ Bcƒ2wÚõ¥- µä–]ñu¼%Ê.LJq P¡ž½­sèÂUÖe3ÿ½·Vÿ"áš.|šA•Σ;êæ\Û˜A¿9`?úýUüW›!ËÍÓŒ»:�Pï ØÄÌØGjjÞ‘W¡¸Ðë¯äȉùN:J³j´8•Õ?æžåІg×MHÞ_¯ê"¿N!'í5ÉÀ)g'M€bgq» ÀiŸëa=‚!äè#ámT^ŽPÃ~W®â¶Ö,W¹^Üœ”Ô–ä¹®äCjˆ.‡+ìÀaÏ•#Ä…ÌísÈdňžRJ´Je×¥óÊp˜I¬eÕ™·®„B9Go{Ö©Ý"~¤XüÔËw$9ðÚc·lÞ•ÛäÕ»vžVLVìèÚiWW#é³DóØcRå•$vm¯ç†«/ª“â\Dôˆúθˆ×b?_%ÕÛ6­,µ³t(þX1½'æåÈ<j9¶Œ:gšë‘\%ÿ€ôçc…­ªäyå</n¿‡¢Ï·öh&¢çcE½Ú01þª¹.ÒÀ™_ÏD¯_ªiu¹QÏÇJÖìÁæµ85>ªö&¾Hö]£åÙe`ÚÎK0b¡›Vê¹àœ|ð”@®ÉmÍ<¯Ï÷Ú,³ €y2øº>qh–Ûg^ æÜÆ?ܾÚoCÞL�ž@§fÖ¡-lþv×e'ï8{m™ìt¤ìK{}¦Þ6žûùíb.|ç€]ú¤6ƒðÙÈéÕÕºŸ u&e´ ÌæÐz2ÇZQE` yeˆ†�kÚùñH‰ötˆÙ_m·Œ>Êèyƒ§ŸL÷OF.’BÖ`T2gÔ3–ÔݬèÎ{MÁpTx"8œYê#<›*²‰>ë'$8»Ø¾+ÖLºÉŒËjPWNƒóöÀÄä17tTÙ(óÂvM¯w~k–ê3Ú_{«dÇîÝû;¯‡‹uÿªO?|_o)ÂS„Õͬ©b#ƒø#*! ÇK;.Ô¢n¿iŒü¶6~mïù2š±„ÒŽ€­ì¼tr¤uë”á,7ï÷£ú´Úå÷½m¿2jyÙk º„¬Z‹#Î$<¿yï­ [åÿëR[ùïòTD­e„OB~ˆ¯ÏvŠ’Ü„òùŒæðb@¶«?õ•÷û‘>—î:—½yy˹,Ú žz×|5Œp ôeö°f}«§@»:7Á;;ïV¥çcù‡i½Q?›=ØýõPRW¨6PßÙ™€Uû—ÃVs¨šä:Põïì•“n+T<ÛsÙ.ï6;·áÊi|é+§¢,ž&?¦ˆY¶.VÅžß«€ÊéŠã,Kœjïã#‰ûQ4`Q™2¥M°öÀ‘h™jž^êf²>¹BĸjϼÃáV($É=]Ô™²tzÁ}öO}<AómØž«u,ðNéþ Þ9=X|Ìî Åã¬÷ú²‘= ž drì‘·m*ì´Æâ«‰Bºø´±Öˆ{‹g›Inû½ïâùÚ6g{µÍ;޽÷ðB‡Ã­ *$g'Œ½+áª|ã/Õ<Wém¢ù”Ö•šyô•éz54³«`.• ö̾‰µî2l°¬°WI--½zDÕó$�ÛŠÚFì%å—?nË —ìƒùL’àˆÒóñð$ #±!¨+ újO´N?W°U-ŸöÔ5AÒãÙÕY£�Ît8oÌÃ…èóßÚm_Ë=ÓºLóµ›õ#ó‹‹ÏÜnBÉ:ë·+†¬Ìµ™þRŽeçqf4× %9>˜?V mb9ŒÄΉoýy+´Xeުû™‹Jù~1•”Èè6Æ´ülv³îЯíäån\D )"!<{'c‡{•ôkÛåpâqÛ]ÇPÁˆp<pœ¤óYOâ/íS ±™÷Ú¡6*miôÇvàGî >?DZD†¶mÖ—eOLv'WrÉsL·Ý”éAõ³ì3nàŸÙfÙÂ’{Ÿã -O­Ž`ë[¬òû¬Éh;’^$(ùcyŒJá©Æ OBòñFÎáMrsë‚Ü–^ÿ’SÝ©›5Ž^O[§q8™6²ÙpÞLçœî§öÇ!�KgÌSÅŒ¤är"p+±ÇHL.BDËxUDÐínÉ×ñÇz€÷0÷ºƒnfšA†ýH"ìðñM#7çÆFA.mïÞê¯lèî°Ÿ<í_ó•øXsÙ}.ä¸ zkY—ÏÆpÆ%(è &^–ß²šäÚÝz[‘g—”ÙnDx1ò†lµLH˜ã½…b6[®Ýö/Ri’߇ŒåÁ(kî"ɦ½Ž=9ZìO+a¤^wƒ›{…sý•³ã¾M„©ƒä›@i±J§dè¨BNpf`-.GPöëû“ͽ ÔZÇÝ“±úKáˆSƦ³â×$¿ž÷˜@í®4Ð7M~à¨ôÀAv/ÿ±–…Nt¿ÿ{Ü!s#=6bé{¹f‡2Ü“œlÖèÁ’¿ñr€tÍFQ·…¤`9‘kæþ–-õ[è3"Ø(Èm>`kÇçE žBbWÜÈøþRë!rÖ1>2f ›\¿7Í0)4TX]±dˆ<JcË¢³³£…c†Ké{çN{X'‹¨ø³ÊšÁÉIõi鯾;IaŸJ“‡BÙü ìkÞÎ4Ôµàˆ\ÏÐŽ5¥}ã.z¸Wi41l~{ÇV@iþ§^òý0¹ÿ‘¤!ê±é¨k�mqB ‹%×8H‘5.&Ȧ­XϱEÅŠ %ƒ…vGÁ5ÌÒ²Äî‡2hkU‹ÔM'Õ²:»ß¢ ¥<“$(û$n §2ft¬I =N¿u•éñÔK}5<°yÏÈPtîI zGv¦'y``ç„”äöÂÓIrŒz±W–%¥Î•Ü Y{èFìÑ»r.uˆs¡´cíôqƒ”‡3V©ܘ«QµwÑt¹ÚóvQÊK~ý·cìh§ŸÖxo´ù:¹e2Ým爔ÜÈ1[òª/bò3Y³>Ø‹m³k P—¼!8‚sXÇ}õJƒzòœt W@¬äu×&í Ëäôä"³»%'ÂgòússWFoÅ!Ë[± " ¯j™î^-Ê‚«bßàû¬Š´1ƒ½ Eä§oÓ@ɉÙy^ŽëÍfùŒeÞ—C¹¥Ø’ä„ÊØ¯NLHýw‹Ç°îEf%vt$dM4T½‡­FÞÒÉFI>žw!“ãµÜ‘ ×™~ÞÏÇÆtónz(ceß`ÍÃî‘ê êö"3§¾Z¿JHp¤,òZ_Z¯‘î¸ÍˆZdÈ9Š“Sr.Æ.’<œ8ƒ ­/ITfØ6¹9š��‰IDATôë½âM3öK2¶Ž¸Êy|êÉù$Wy¨WZKne΂‡ê¬Ðñ}' ¿¬éЖ ølL Ê*ì¹ZrÚ(½z­bÁ°ºÌ P0Va•o–tcàwH¥iglç‰>–EF’„Úõ›‚áJ··ÄÕÏOp¶Œ†úçËq ª]u»¡„š±Þì°¹²Yv3úO}ïvˆìÍ®„À‚JÞnNÁƒ¨²wÐ ±„²ÎŒìR“sÓlî1=˜ ¶»x¯çÜØåmËþJY.kÌ;ë‹”14G$ªn ¯dçh•œŽãÚö¦Š¦Ý?©¤ë§(ÄŠíKö}&g—1AJ;Êß¾k׎Ûû'Hû`;ª<aQˆÓ$×eB¹‰êßû5k×NDÔ3æí*Úæ@O9ƒ‰½öZ»ô2Î7Ú®¤HeÐp¤£Ž!u!0‚‹gía“(8µˆÎ΃H*I[—ŠjÂâDvÍÚá{w9ö²‰Âÿ f¦Œeî0µ„;bd— €Ùð¹ç×ÏdDŽyôì¦Ûªì'ø‡Ð`ºã5c¨lS²S+Í&[dt€+)þ6å¸ë[½žûôakQ,Ì’‚‘ÐW;>;ÐÚ2{1ZAfâcŒ³CƉ@;õ†5 wjÉä•è{D‘y$„ñë?þ®-`­¯æÞ-GðO¼š§¡\ø@)K︳¯ä[ñú5ûû¾äb€Z�©/J-Ñ|@ðá/Uóúäjö2%šAášœÈt€äìên“ñç7üÍÔýV}ý¯õd륷!ã wWjWÕì²!6޼Ygzˆœ³õñHä–úÈ’Å3ªz–Z©WÔ‡êÆÐlÌS³Å ¦KkY%LÓ€&® [ϸÚ×/l‹³Z§RQiâíÖK�éU¦ Á:Ëe“<¨1 õ+¤D¤Eá¥j-†§ 8ÑcåqU_ý-Wàn}³  Ø…ÿI ò’£4ARÃÓÚPòNޓ˜Ò;“ a ÕMÖÖt®¥TDŒžŠ(ƒòƒÁúíkQmÔgê uä´Á=™±þ΄ H MÕ±]­Çù\®üð$Ü’Tž;nJá·J-,÷¡®M:¤>…U¨bQÁ©·W ïIèNµ´ý¡õG„òËÏÇò±«cÓ*œZ>ücU£8Ü–R.EÑõùS`JŒ£çd­”Ú†ÙTt¤Ú¤~¡ÃáË"NQܤ”¤K³›ßI.Æ!t^š$•Ðk6Ùå>ˆÎ«Å‹³»=±9þËM-Sj€U ˆòx©]F¸0ª?¯ÂQä"õ)7!ŒUå¹ ˜ ÕïÓ:ùIqj_ĭ˪äDŸVQ˜U–EÈénå^›`Û᲎çç£Ø|­ Èå:ÏͤmycH?ß„VˆÔ× m<l?Ö¸ý¼ÇÑØxñ¼‘Q:’ßÊ“~°4EŽcÓÞNêø®ƒƒïí\ÞÕœ°{ ¹Îˆ# ¿~"÷O�R€Ý6¨ŸÃÃmĉ$kؽO½– D]á�Èc” ¥î„UM-Ç[Wd§&šPiaÆg;=Þ<?bh¹›t?ƒ†ƒ²ÍŽï0ÿ´äôëÌØ·ZcÎ ÀJ–í½·ŽL´g©<›zµ.`—E­N<tÛ=b­p’8L""¨‚çõJot>´ÞwåÌ‚H(Šˆ*šõcÁSü®¬0¨1®ÚNŽȸÑ׬雥¯^>a̧í[·ÉÛÜÅÑÇD†YW˜ е$ò°2‚²3š{›~äYD‘ðÈÁÄŠìX­KÚŽ2Î|ý²Š^â}$PAë4îT³öçÉûYl»Ã6š²Ñéõ,s·Ê’5Òá¼1³úÌ,×0~�2جÀvÀÙaaÀßâ@©Ø!mì_ ºXNf®Nø •J™(¡›)udÜÝÒ8»}d¥a½wh›ª4š´M¸ØüR¯x©’žãâ 󰿤™«Çò1ä\x,.s`'•~}Ñ7úpX@ª-Ž'ɱQ0Mø æ?oØ»ð}tmîô yFÌD¥bw“”zg&BDÁþSæ¬<rd5x§|¡'žŽÀA2Î äoÀHˆœ–ñN¨³%D°¶%C\¬’\ñi÷?�IŽŒz®-+§®û÷On•áJ± ò/vå@ ý . Éä6Èéö *×98|Æê’F€µÍÕ³³ˆ{RTð˜Òc¦¦nü"¿ÎoÙL$x¾“1ñX:‡pŠš¨ÐyàªëbÆR4înÑé^ r={¨+Uà2Ó”áwÂ"žÞRëMÛG -Xl÷0jÊ@PUxFLÎ䜀«í;3é³…ÚM£Û™‰wª&çÅ ¯txS˜Ü3º¸Ã«è%\Ði‹DNÌÝftÏ.¤Ï‚VéŽ"Ã’õ|!} Us€ÁЂp¾¯*Ò-#óüŠO»PAïtòÈb ë i4ßô l‚w”Á:G®Ç`´ÎY­óšþJÝiÃÚUÃ{üç¬ø¼øÅ�”?µ¼3DU˜µâ=D>ùÊáÅ’oCõÅ7êÜkëØK’ß9„ÿ‚Zw *^{’ à™â™ÈÙÉU®ÁgǬ5xð¬çâL¨ž¡ó«!dB]G’z¯í™ò‚Pê•�0t ù~s¯Á«} ™të‹çHâJçÉÝjõü0 é.9f›+3ž‹3$ß*è%ú¾ñÞ´å@kaÕ®Yz¸ ÂÖ»WÏä6+l:ÿÒyßkÇUÞ=Ù‚Q!ö4z8Á<*. òÙ-vD¹ é†u!È¢ž1`â¡Ó–�B}=7µ¦/Àfê½Ð”–/šDXÀ¶pš6#»·Q)Ùt%¤†º†h�²È7ÂÐÛüËôÀ-mõ>'WÀ‰½(v„k{Ù¿æn?–µ¹±2ZIŸä°`¦D ð¹5æc±àì`w©G$±š�fOÜ 7‘˜´’A’¶º_øœ3âAÜØº xtIû2”_ØÃÊž˜Ó¬9Å–×™zãH^´„ï­AæHŸÊ¯¬ÕÔÅ+wïRÍqV¼7é'ÅÿU\ü•Y©>t^¬½u pQåiÉ­“ÝJøÄÜùž€Ÿa!|'æ_wi&‡ËXÒ¼ƒû±ZÙ¶Áùü‰žå&ÌÚS´²·U;ÇáBôùKù×òù•Qݬ~?Ö_ú½¸îŠGö|¸Ð©ñ˜›µ®¯·z‹òFoåðq8Üê·,Wh»CýL÷Ô|£En»Ú\ûäð+?|YdÏrNÍÁOØ!®.Ž|Î.ëQõý+ÐY ÛrqÖ—´Zœ7‹Â©Ýùö²·£0¬llé+È»_Ê9µ»¤&QqždŸP~é»1¼R5Þ,m�ždÚâ(=3çhö¼ª×sMżq5‹Ïaûðõ)LëËÎmÖð.‹’eÏl\Õ¡»þ?Ï…õVóQÚ®<Úš .›}ŸÔõÖUgHaÍ_öPváúÉ[³ôÇ©Iu5>ô/z ­ëšv—'a:n3%‘ìh¡í·æEû#›7¶tW½J^׿ïÞÒ/¼egmÍÜy þ]g×äd¯$xâæ¤/T³Ôµ†ôÔ†°I½k/—¸° *KËöç'ñëÚªšÙjéÚYÖâ‰èçã2Áî‰èó—ÅG¼ÎX•èC¤Ì³óW¶ú¬ÖºôóQdÞ(özKí Ñë¨/],Õ«·¼ò]Œä2žW«Öz“—O«wöá)kóò¼¬uúTÖGÑ‚sAÎîk†ký7Wãm :¡Êg¾³¡{¦äâ±’Ìvl`´¯fke œX£ÛµµC)SÏ‘'Ö²¦6Ö©yòB÷Òx”ô,É£zìžõˆªïÒ[«t¦çð²fܳ{bM8‰%–ߥ!ï½$BÝô¶îªWrrWÝÔXFÔ»ì“>É,¿½|ûU.t¯7‘tÕúŸšñ7Æ–@?Võžà뱂LJ‚újr BãEµÁ”gGF]±êA¤ÑUDök~ƒhê.ÂgÿŒEP³<Ê–”TÑØ{jPæÙ-mÎcž~Ž>š3W‘NãŽ+ÓÝjV§Öe…Ô¼‡å‘µ´“^Ò•EßK.ŸEÜí*7—š±u»&\gj[àyq\G„H“�Éá¬ã·äjz3K8t$·Û ÃŒÒäЃúqãÚòÆ…‚¨}Z/&õ<¼¥•+C’ßx£ 8Žôô�"BL}hiäÙHJTðð/þå¿ù×ÿîßÿ·ÿþ¿ÿïÿùŸÿüŸý?ýéOñ}Ä_ýõßüöw¿ÿ‡¿ÿ»ÿú_ÒOq;"""""~ˆˆŒ+"""""âÛÅoÔ¿‡¸)ßCÜï÷^ƪ™‹è§õÿùÿøË_æ-›røµ/à›¿…~¢?×ÿèÎÿõ±¿üZRÿõºæ±ùÑfÉæ_?Ú,ùÝ_ðCüò2c.PÁˆˆˆˆˆ0"cEDDDDDÆŠˆˆˆˆˆˆŒ+""""""2VDDDDDDd¬ˆˆˆˆˆÈX‘±"""""""cEDDDDDÆŠˆˆˆˆˆˆŒ+"""""2VDDDDDDd¬ˆˆˆˆˆˆÈX‘±"""""""cEDDDDDÆŠˆˆˆˆˆø>ã7ÎßïDÿ/îÎw&úsÜ…xH_Ër+Þwùlî÷^ÆRÿ9""""b0‡Ã¯¸„~Ãoà£Æß²ùÊÎ Œˆˆˆˆø1"2VDDDÄ·‰_£ú†ßþÀG¿eó•DÆŠˆˆˆˆˆ3VDDDDDDd¬ˆˆˆˆˆÈX‘±""""""ßÄ-ˆˆˆˆøAö.‡åþ±‰‹ð‹øö]Ÿ+"""â‡ÌUýöÚÎ ¿èoßü FDDDüxq¿ßÅö¯oõÕ{?'ÎXßà°õ•çőω3VDDDDį–®êy✑±"""""¾—tµ+"cEDDDDü:éjä\+""""âÇ‹`^DDDDü ^ ú‹õcÕïzàÛá[:Ÿ+"""âNQ›ùË|ïÃßßýX?vDÆŠˆˆˆˆˆŒ+"""""2VDDDDDÄ÷+øÛßýþ?ÿ/ú«¿þ›¸)ßIüöw¿Ký‡ˆˆˆˆˆˆïñŒõÿwq/"""""¾ç8Üï÷çõoãFDDDDD|Ïñù?þ‡ÿÍÂUܽ Ø����IEND®B`‚������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/cubebox.png���������������������������������������������������������������0000644�0001750�0001750�00000011265�11332353404�016412� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��u���¯���MÙb���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚ+‡íCÃ��BIDATxÚíÝ{p÷ðß¾õ–ÖÈo0oc0ÛIHȳ“4 4“^Žäàœîrwe&Þ´Í]HÒ$Óé\Ïm§“^(=Ii.MÚ^II˜¤¥$LL�Û¼l0¶1ø¡‡%[–dI{ÈYZÉ’­Ç*þ~Æ3˜õþvûÓîW¿ßoõ $I"„ÔÖ=B��R¤iÿB —›·¡E� UjëiÚ¿‡ªY·iãæm}Z�Råò¥ö®Ö£lð?÷(Z�R ù \Î!«g$‰±… 5èyÙ-+“/^;|é•¶Oæ)£Ñèóù.:ø¼²¥²uÙ®jç/ÙÆæ®¼§@jyÜ.ψ£rٲċ´¶µB•&[eåó…PTøÒüŵî+Íõ70 óÇw÷u hL%Ç<£s5#—m¤°¼6¢8�¤ _\ÎÊÊʤŠTVV¶¶µ jm¶ÊÊç 51 8Aå2-~cÏ›·®¾iiEùÅÿì×Y^¾m9ã×q#š²<§@ÊQE%ÿÌM…É|ÙXùBGüA+öv=Ú”Ÿo^<¯´ùÜg…Ëï"d¼üP×ÉeE†#íÖÙËVäú£¸ûùÇhšú—ý¯Õ1‚s””/ô”®súÚOÊ&Ô%Í_~þ䟎š¦Œg ã‹‚E«!ή"9|ª£¬zý¤õøé· BˆÏçqŸïêßwèTçKüR/l{`~ɬÿúÀñ³ÝIä’¹…÷ßVµhNZà¬C#Ígº³¿ÉLZ°¿û­+bX§5('`HÔ›`G"¢ì+Ooˆµúwþ‰”°šìB¹þ v$2?ÅË×\¶  8ÿ[o»gÔiôô´ï,©º‹¢™X¯ÿBé¹:ÐÑÕ«Uq7WÍî©ûoXX”H)ËÕ.kxò]\û¹uå¢ï?~ïÊò9££žãmí££®ºÕË\ŽAB&ß!$ I‰ï ?øI÷Ï”E—GçO|–HÙWžÞZJ«è²—UÌñQà …U÷ ßË1„¦)KÇçt~Á˜T3·–WëÔ×àã#§t:Í¿n}è¦Ol\óô˯sjÝ·¾sÑœ½Fðúü=oü©ér¿ý‡ÿ´±Øl „¼ôÌã„·4ï=Ô"»fø.Ô·å¾›(Šúà¯Ç~´ó-BÓ',,+²ô—åî|öï![_Þãñú]_[wóÒ½‡ZÞ:Ð*^sÃ’ÍßXŸgÔ;ݵ뇽c>BH¨ßTW³t^!Ç2ç»ÞxÿhÏÄäÊøè¡§¾½òÛ¯½>|‘-ûýWß}é¾NyùýÚ`DÙ$ÆGACžv^­§ë¨Ëã—•†öÐE³ Ë>Üñõ¢Y¥5þúƒã7­¨È3ê tÄê ˜EÝÁ¦“VûÊŠù«*ÿóCk¾ÝðΡkkËMí§Í­W¬MÍmÃöaÙ59áú”óÒyEOù¯ßì4zc~ ‘È ;`ÈŸ-QRpËí§Ìs*‚;lpX¯gkøØCëŸéª^6ouÕüÁÁÁßþå´Zà¾÷X]žAsðX«ÅjÛpÏ-ßÙüÕïüä7Ë có»ô”JQ²e+V­‰IñË>û‹}?Øö5BHD¸„o0¹ùÝp—5 Ä/È×ñ<Ïù§rØ„†å.ðw£N}µwäÅ_îï¾Ð¢Óé?j:ó?//,)È#nËÞC-_Y\d2h÷}|䋳Ý4Ë ýŽ×Þëí<±&JC51èÔ„·Çkw ”•S4ËÒ,¡ËrÃב$Éç÷]?®€?žïz»éä¹[n\±ãéMwÞ¸|çÛn½çö<ƒ¦³§¯a×[¼ZWVZ\]¹°ªÌØÔn£Yg?¤?`hBSS(EQ´|ÙX[ -]öÙ×ÞûÁS÷M—šÛdö+›/q^Àâ¸Òî³^Sx—×ëõx<Ä;è,ÕçÏIþÈIyüf¶Í1LÑÔ–ûo¬^ò V-„VáÊãe˜ñ X­7ñjÀó=°ºzÉ7£×TãÃ4‡ËCxÎdÐÓ Ë^‹�†å)†™Ð˜4ݽºt¹Ï`.vxYBˆ^«ö:E½š2ováï^}>´z‘Ùäü¼Ý`.¢z1þËTî“Ó.±¶6ƉYöÅ­÷†ªþmçû²ûщln§ÍÙñ™ËÏ.¨^;ê°XO}H?!Ä~ö  ß hôI ѨøGëª !»ãÜ…ž¿¾þö• {û­¯¼ºgÄ5úßÛFÓ4EQ XQš¢!œ º£zq¬5)j<ÏuŒº½jÿäÃ÷½qà‹àÍ+Îëî³û¥ñûGZš2»À>C4·¤ cplvq>!Ä92êñz-v'!¤«·ïg»ÿZßjwú}c’ Üi¥ŽhùñQ¬­MÉ•}áɺPÏ%8eóâÖ{ÿý—û£÷›Äø(à¹p˜PTÉÊuœ áò5þòÛF/|"<Çqß Uk<þ¿pÝßúü¥…³x–ñùÿù«·%B±<Oñûý<Çß¹¶6¬[! ¸ !nøjG¯õPKMѱÖ$×ÚÂíõ¿þÞ‘­ßXsïµ5Uå}6—hДæŸ|ñuo€ë³: óôÏ<ñMÄTÌ-ˆŽ¿g¶þÍ©ó=«–- „|ôi3MÓÇÎtY‡†ËJ ¿v×êË–aÑ ]Q^¶ó‡;ûˆD¦6BH&)&̳>ÿĺXk>·ëƒ‰¥ä_Ã’@ÿE¦lh¿ÁaÑs»>.yáɺèýÆÊ™ö|aÖóý†¯ÌÅÁ%ysÊ\Ö2ýÇq’$u_:aœ¿*‘–*)œåóùmŽáÖóo¾ûQ{g¯©pÎ''.,-˯­\ð­úûþzÂíS ペ÷>=]hR/Y0§baÙç-ç6ŸYTl]3ØŸ þ~äLoçOöl¼«z颹KçémŽ?8ÜÕ~ªxá »ßÿ|KÝŠšªòæ¶ŽƒÇÚn¯YqàÿýÛ?mzàncþrääkoîSéL¯ï¥Æý®YRSµøv•Êæ9ÝÑÝÞÞNq†å(¼%Ò0 ¾ó¦õÈÇ•7ßÞí‰.ìwÄÜQܲ¡p îå¹_}øüãkå÷±áàç¿\ìéøƒ«¯}®jèD—³dùá;“_ÏÑêŠ2¿ß?äpœÒj æÅ?øKmM€<â–ÔZ“™T<¯óº-W:½nM3ƒ8b·HRÀ<{¡Ö0kÈÒë´öùÇ|„Hæ’ùœ ±\•_3|>Å붺GœcW@ 0 '¨u†YÅ*Þrå’kÈâ÷ûµ–ÊãrjM³Ä‚2Ž.¶!D2š‹‡‡>_ðöÇ«XŽ·÷÷ŒŽ8ÇÜ®@ À0,+¨ŒæµVñ¤ÛÐàÕÊÊ o-n9| ÖÊËWß3ž5­§æ¢t” ­&»0X6ôW[Ïõωˆ+¯Ó2W3r®ËZ¸ìNBOèóP È_îòÚ+Íw:ÒÅ® #C‚Χ™Œ³y•úZßI"„Ð ËójŠa–3™K E‚—«Jk`9>Ø)Ñ‹…,+0,È©Ô±Ö ¯<¯ÖNÐèEÑôøÑ±O(Êh.æUZ–å(š&D ø|ã·(ÊTXªÒ!¼ZK3,EÑ Ër¼šPĘ_Ê«‡$ŠÐCQ”D$†á(†Á[:!óó»U·¬òünÊËF,Œ;¿;ñÃ]g]6UY Ë ÑÛUi -WÏ`‹Ûíó:Ç\*}uœJ‹¥qH'šeÿÂ0 7«0|I¬5#p‚*üu1×£GPó‚Z¶H^ì—ó0,§3™q®ƒ’ÇGѱ”µ²1òeB'ż°&þ¦4y%^RB"R€ó� 4zS[Û™ˆ¡Ê$1­§5zEÑÙ*›Pÿ�².øq*­­§/¢Öƒ¥²UV>_0›� ÄˆÑè.·ÊÆì¿¸6<¢�0­aAŒê¿ârØvïØ‚Ö€éزcw(bð"T�H™††™ñQ8»q�IkllŒX‚þ �¤ ò�/�€|�@¾��ò�/��È�È„¤?„MEÙå6›-ø'›-eobštƒ)ßcÆ6€|‰ W�¤+_&}žïæL?ŒB»ßWh¢(F,‰X'T0¢>²[Cz¤JZæ_B×mô¥;ÍÍF¤†l”DïtÒ ¤©Â�è¿L=A2üT?}…÷Y‚9Rè°�((_¹ ³Ò Ý©bk €|ÉBw#}; ö\"FX±&b�`:Òþú—ÐÅœÉnKfv �YÈ—PG Ý/! í(|jvÒFϹ„—E/ kã£èë6â>N G‰l9þNcU#þš˜îÈñ� _��/�€|�ä ��ò�/��È�@¾��ò� DæýÑ_R �‚þKCC�RŸ/�Hãø¨¾¾�Sc2™¶ìØs|�–ñ��ò�/�€|�Pb¾àÃú@Ö´¾ÿ±�éê¿„¾� -ã#��ä � _��ù�€|�ä �|‰°ÓßnQ�ú/�€|�ä ��ò�²@~~_Q L¹õ Ù1ïmß¾=M»´Ûí8K�¦Àd2åÖå“éñ¾`¦’êk466nß¾=Á5Ñâ�3æw�ù�È��ä � _��ù�€|�ä � _��/�9“¼? ñWôãµÿ�Dÿ%ñ÷"â]‹�\ÿ%}Ñ��37_êëëñ)-�Æñ��ò�/�0“¤àûEQ$øÇ‘mL´pJZ5(¼ѰŠÎ—ð‡ Rx  …ÓÙ¢(Š¢h³Ùа9/¡Ç í8}²‰NUÃâÔÍ Ì¿ÀŒ{ò�á‚|@¸�ò.€|€Æ¢ `æôb‚Зɥ|Á£•Bqn¦BÊÏO4,ÆG�€|�@¾��ò�/��È�@¾��ò��ù�È�@¾�� _��ù�È��ä � _��ù�€|�ä � _��/�€|€/¿Èï'1™Lh�HK¾444 Q�`òbæK}}=š�¦Æd2mÙ±;ô_Ì¿�@º _��ù�È�€ 6z‘ÂoQÛíöœ¨çÌ<䜨j¨’¹Õ¤9Ôª¹Ú™·Ïsès¢ª¹u åJmcÕ“M*²«±±1'ê939'ª*[ÉÜjÒjU‚ù�Hä � _��ù�€|€ôb§SXEÙå6›-©-$¾~ªê9Í=f¦Ú©=êPm•VyÙGG-Q¥©Õ0cÇ5Í¥ªžìôDá—™ì&Šâtª­üC޾¦yÈ~t”ܰ¹rÂç|ÿ%Îië—ð“)´$+Yâ5Œ~Ê _¿Tü5³ØYµyœú+¤‘øã¢ÌFŸ`Ù )Ù30­&±³9X{ÙóC g†l ©IKMmûÓì„ú¡ýF´yœZÉP;bJ¨LôóPR5Ìî /[Ït_˜l /QÙÚDLèH²ÞÕ–=-‚««’'ÉL¶@tÄ(y ÿÑI÷ã’¦ŠÙfò´LïüKô³eφ8ñ'{–+êjŸþóm®Ì¿ÄådǤ•T`öźё¾Ó’ÎÊ9¤Ø <[˜8~å·€Òž<SÕ«?£¨3'bè­Ø–LëiIgìØâŸ ŠJœT݈˜ÎPþ³™’{ 9ÑÛ =Ê“NÊ('tÒzaÒ™|<¢&´<ëW]œŽbÄÌ褥d*Ãã£ðÝÅióøG­„@ ¯aĵª¤Nê‘Íð /†‘mÉt_˜ìô[6΄K"‘Ÿ†Ndæ%Á‰¤èÿÆßø¤kfeF#ÁZer:Á&õ¨¥µž‰×*NA%´jZ/L¼?�r{j” ù9.x)­Â±hÈÖˆãK_I@ÿ�/�€|�Š9ÿç3Á%Wê93gÑ ¯­|ÿ%׿uåK _‡4ÃϢܪ-U³nÓÆÍÛºû‡\Û*“µ¾¾:�˜“É´eÇnAèéèj=Šù�Èìø��ù�È�˜y"ïO›L&4 �¤8_4±ÙN¶ìØF€)ÓDùþKø��RÓèé@[�@jQ’$ÕÖ=‚†�€ÔjÚ¿çÿ¸ãšÎg����IEND®B`‚�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/user/binning/cubeimg.png���������������������������������������������������������������0000644�0001750�0001750�00000047722�11332353404�016405� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������‰PNG  ��� IHDR��;��ð���þ›#{���bKGD�ÿ�ÿ�ÿ ½§“��� pHYs�� �� �šœ���tIMEÚÑ^‡à�� �IDATxÚíil\×y¿ÏIIÔBj¡¼(^*Yô¢tqŠ6ñ’(M›¢ŠÇ¨h `Ñ$FÐuÑ)lùS?ñ/Ó¨HóÁ5ÐNжŠVm<¶ãØH"'mT×nŒ*ŒmRÞ$ËÖf-E‰EÞÿ‡£{tænsgænçÞç‘P3sï=÷,ïï}ÏjÙ¶-„xøá‡��@.yôÑG…U)W<ò9��ùäá‡~ôÑGûæææyäi��äÑÑÑo|ãUù .#��gP,�€²pìØ±“'OFÿýºuë6nܘíµ>Š577§úOÿôOï½÷Þš5k.]ºtë­·nß¾Ý÷¦¯¿þú¿ýÛ¿­[·î‹_ü"U� Ï|ðÁ'Ož¼å–[¢_òꫯ !Ö¬Y“ÕµþŠeY–þé}÷Ý÷÷ÿ÷µZ­¯¯ï™gž9xðà 7ÜàºòìÙ³/½ôRÿ}÷Ýçº��òÆ©S§n½õÖŽ.¹õÖ[_}õÕááᬮ¤X+W®¼÷Þ{ÿõ_ÿõ#ùÈæÍ›÷ìÙóÀ¬\¹RýÀ¶íf³yîܹ_ÿõ_ß°aU� çX–ÕEtai¤­¿bU*×7Þxã/þâ/¾øâ‹ëׯùÇüǯ|å+êú§žzjaa᪫®ºýöÛ©’_|qÿþý·ÜrËwÜAn�@Þ¨T*](GÅ!“k#ÅX’_ûµ_{ë­·ÞxãJ¥2??ÿôÓOßsÏ=Bˆýû÷<xðâÅ‹¿ÿû¿ß6|ðÁ¾}ûŽ=º¸¸¸bÅŠµk×Þ}÷Ý+V¬P±Ú¿üË¿ÌÌÌ!î¿ÿ~=<xðàOúÓ÷ßß¶íááá­[·Þzë­òqÿüÏÿ|þüùíÛ·oÙ²%ouâ½÷Þ;pàÀÖ­[}¿=yòäÿüÏÿ;vL±iÓ¦;î¸Ce�@Ò1–W¢ÇIúµßüæ7ƒ~ÿ‡ø‡Q®Õæû¡oŒUñÆn:_øÂ,Ë:qâÄÙ³g¿óï¼ð 'OžüÞ÷¾wüøñ?øƒ?¨V«V(BˆgžyæðáÃ}}}+V¬¸téÒ;ï¼³ÿþ‹/Ê?~\Ê•â{ßûÞ… äç?ûÙÏž{î¹£G œ:ujß¾}ßýîwõwxå•WŽ?nå ™°K—.-,,x¿½xñâÓO?ýî»ïŽŒŒ¬X±âí·ßþÿø¹¹9 �À(BîÙgŸrí7¿ùMõ‰Ò¿kÛô J–/_þGôGñ±°° „øö·¿½qãÆS§N}á _i+ÎçΛ™™©T*×^{íàààòåËçææÎŸ?îܹÁÁÁJ¥òúë¯ !çççÏ;wèС›o¾yaaáÅ_B¬]»V÷ÙÙÙ7ß|óðáÃ/¼ðÂÇ>ö1•úùùùÇ\q÷Ýw¿üòË ùÈGÖ¯_ÿüóÏŸ;wnóæÍŸøÄ'ä«=ûì³GŸŸ¯T*7n¼óÎ;eú;öüóÏŸ={öºë®[¾|ù+¯¼rÛm·Ýu×]Bˆ³gÏþ÷ÿ÷»ï¾»¸¸¸qãÆ»îºËûÊGŽùá833#/׿zá…^ýõ¹¹¹þþþ‘‘‘OúÓGŽ™ŸŸX½zõ† ^~ùåóçÏÿèG?úßø¾¾>@�0¨Wð¦›nòþøÀz§ïµ_ýêW¿ño!þæoþFý­n躶ƒ^AÉ5×\óùÏþ[ßúV___µZ=qâÄwÜqâÇòåË«Õê¥K—Ž=:66¶nݺµk×.,,ô÷÷[–µ´´ôæ›o !Ö­[wìØ±………C‡mÙ²åèÑ£—.]²,kÍš5›6mÚ´iÓÒÒÒ±cÇfgg>üþûï{ôãÿxݺuÇß·o_µZ™™™žž®T*ŸøÄ',Ëš™™Y³fÍâââììì»ï¾ûÄOÜÿýÏ<óÌÜÜÜÊ•+Oœ8qîÜ9!Äáǧ¦¦¶lÙòÄOÌÎή[·niiéÈ‘#ÿþïÿ~ß}÷­]»V=ôâÅ‹Ï>ûìÜÜÜÐк\)ÙþýûW®\¹~ýú‹/ž9sæ'?ùÉ5×\#„XXX¨T*£££—.]’ºxôèÑM›6Ñœ�À”^AÉŽ;\Ÿüõ_ÿµ]ûÇüÇò—.¹ÒoØÙÌ ƒZ–522réÒ¥eË–---E|íO~ò“?øÁΟ?ÿòË/ !V®\¹cÇŽ‘‘‘J¥òæ›oÎÏÏW«ÕåË—_}õÕ‡>uêÔÉ“'çççUª®¾úêÁÁÁeË–­ZµjvvvqqQŽl¹´aÆááá³gÏJýXµjÕÜÜÜÉ“'=úî»ï~èCºÿþûÿó?ÿshh¨¯¯oß¾}sss/½ôÒµ×^;77'nõêÕo½õÖ| ¥hzzzvvvpppÕªUrtíôéÓÏ?ÿüg>ó™e˖ɇ¾óÎ;òò7®^½úÍ7ß<{ö¬ê”ÿ;88xýõ× ÌÌ̬^½zxxøÌ™38pà€, Û¶Ïž=»¸¸ØßßO‹�Sb¬P'<Æ’<øàƒ»wïÖåê3ŸùŒ÷¹ÇX/¼ðÂøÃŸÿùŸ?~üø… æççŸ{î¹›o¾ù¶Ûn‹ò¶7ÝtÓÅ‹:433óÁœ;wî»ßýî}÷Ý7444==-„X±bEÿµ×^{øðáÙÙÙcÇŽ©ù–eõõõ-[¶Ì²,¹Æ¹¯¯OŠ‹ÁÁÁo¼ñĉsssƒƒƒrÂýÉ“'mÛþàƒFGG÷íÛ÷úë¯Ë¾MÉììì©S§„ýýýƒƒƒ·ÝvÛ… ¤b gùùù·ß~[]277wèС­[·Êì’¿éïï¸í¶Ûæææ”bmڴ骫®:vìØ;ï¼óÎ;ï }üã_¾|ù=÷ܳwïÞÙÙÙjµzþüùÙÙÙJ¥²¸¸¸´´Äš6�H:ÆŠw†z[Å ¹öë_ÿºÞ—ø'ò'QRÛF±Ž9òÿð###_þò—>üWõW2�úÛ¿ýÛ?ÿó?×»È|Y\\<tèÐÏýÜÏŒŒØ¶=99ùÆo\¼xñ•W^ùð‡?|ðàAÙ-vöìÙ×^{M±´´$ß××·¸¸xêÔ©ÅÅÅJ¥rðàÁ3gÎHy«V«¾Ï’ñ“úûôéÓò便¥éééW_}uùòå7n´mû½÷Þ³mÛ²¬ÙM·lÙ²J¥rþüyu79…o```ýúõêþ¾¾ùùù………ÁÁAùH­X±¢R©èrØ××÷éOú'?ùÉéÓ§Ïœ93;;ûâ‹/ÞsÏ=+V¬øå_þåÙÙÙ™™™ÿýßÿ•§2ºB±�À¬^Á »µíüÚ×¾¦B9ôõõ¯ýOÿôO£*–ïƒçççÿîïþ®R©|õ«_]µjÕ-·ÜòÅ/~ññÇïïï¯T*ßúÖ·|ðÁð) O=õÔÀÀÀ† lÛ>zô¨´Ñ—.]zíµ×¤© /^\XX8{öì™3gn¿ýö_|ñÔ©SO=õÔêÕ«9"„XµjÕàà w´÷õ|3wqqQ¾©êTܸqcÿÂÂÂk¯½vâĉ÷Þ{Oýøúë¯_¶lÙÜÜÜìììÕW_=??âĉøÃ6lP¢7Üpƒ¼ü­·ÞZ\\|ë­·t¥ÿéO*{ådHÛ¶ß|óÍ·Þzkhh¨R©¼ýöÛ +W®\¶lÙðð°oü �\¯àÄÄDÐ/ëõzr½‚ê¹²3°^¯ËO¾öµ¯yŸÛAŒµgÏžK—.}îsŸÛ¼y³üä£ýèÁƒßxãþþþ¥¥¥f³yß}÷…dPÿí·ßþ³ŸýLŠAÿÐÐÐðððêÕ«å¶Q«W¯–cHBˆ™™™©©©óçÏ9räWõWÏž={ðàÁÙÙY9ž444´fÍš 6¬\¹2J8¢ÿfË–-8~üø‘#G6oÞ,8!DµZýÔ§>õýïnnnfffÆ r¥”Œ®~ë·~ë¹çž;wîÜÔÔ”œàwúôéM›6É^J!IJeË>ùÉOîÝ»÷Ì™3¶m_uÕUJ󆆆æççå*´‘‘‘5kÖôõõ ½þúë‹‹‹Ë–-Û°aêU«Ö®];44$§¢Ð¢� ½‚ßþö·û·;¼gïÀAš¥WPÊ•|ÊŸýÙŸýå_þ¥ïs£ÆXÿõ_ÿõþûïoÞ¼ùSŸú”~Ùç>÷¹F£±jÕ*9 âÿþïÿ~é—~)DÒï¼óÎjµ:??áÂi¾×¯_Í5×lݺõ¥—^’ƒL×]wüýæÍ›§¦¦Î;wþüù~ô£×^{í©S§fgg…ƒƒƒ7nܸqã²e˾üå/ç;ß‘½p_ùÊWž}öYyùïþîï~ÿûß—{wÞyçêÕ«•RþæoþæäääÌÌŒeYwß}÷»ï¾»´´$„¸îºë>þñˉïR®ä"3ùÕ]wÝõþûïË™2<Ò¸›o¾yqqQ^¾zõêk®¹FöFŽŒŒÈ'^¸paii©¯¯odd䪫®Úºuëš5kΜ9séÒ%™úЇ–-[&»�±tSÿÐCíÙ³'äÇ®8)ökçw~Çû¡ëÚH1Ö¡C‡öïß¿´´ô{¿÷{®kúûû?ûÙÏþà?¸îºëffföïßíµ×ún ùÕêØØ˜\2¬bÃ+V ÝxãÕjµZ­ ÉM W­ZU­VW­ZeÛöÚµkûûû×­[W©Tdßc¥RY¹r¥aÚºu«Ò­[·ªµ›nº©¿¿_Žu]wÝu£££rjߺuënºé¦¥¥%Ù¥¹nݺÁÁA˲~ô£]¼xQ.;{öl__Ÿì{”“>¶lÙ²fÍÛ¶•Œ ôõõ]YÎV­nÙ²exx¸¿¿¿¯¯Ï¶í………˲†‡‡·lÙ"'¿|ùò+VlÞ¼ùâÅ‹ò72Ó7l�H-Æúìg?ñª®u}ØÁÌ‹ÉÉI!Äç?ÿyתXɺuë~á~aÿþýrþÞK/½$wo Jñèè¨ïWÞýàW®\©¯J[³fw·y=¢”è‹Ãn¼ñFõ·+ñ¾kžä4Â………jµ*;è×­['eipp°íJ©•+WIŽ÷…W_}5-�òÜ+EuÒ¹Ö_±\T­V ¿×ØØØØØXŠðW~åW,Ë:vìØÅ‹ûúúV®\yýõ×Ëa3¦B�@‘ššºù曣_òÚk¯ŽŽÊM2¹6RŒU*n¼ñÆõë×Ëî;!„ÜT‰m“� `È.+¹”("6lWeu-Šåãwõ[�‰ááá B¹½6P±Ž?N‰�@®‚ ·bI¹ :Õ �� ¦§§•h1¹���rŠÚ-×c)ä~���Òh4\Ÿc�€ X��€b�� X��€b�� X���(�� X���ÙSíô‚‘‘ßÏOŸ>-¿’‡ðÆ‚÷Y®›«'êî%Þkõ4Äøj½¿{¶%/Þ:à[Ù2ÏWª:MOìÍ$zEMèÑ1VÚ¤SèzDˆÝðÍÏ‹>®—íîÂ$òÖ7Ó­~Õî.KÓjDyVÒéÉÊJæJ¥B’722222rúôéxìë äA®¼/žŸTež¤^2''Þ7?ã-zU™S+¬œ“d«­r&šEBªVu]äÔµ!1\P`W´òÖÞ—ÕŸ¨îú;Í¢ñͺx]ã¶ï%7’ŽrÂs;–²påp׎½È"fNPmI9…mó3! ÑM–ïÛ…”cHˆÅL%ú‚Q’ÝE9V-roîÄnƒüˆ¤ks¯Ö©kæ›=Öqý~ú]ÚoON”÷ Ï^¬Œï;ÊítšI§N¢J„gŽïÃSØKŽ…X†p£Tô=Zóð·ë®’dXñ¢?¢»r¬ö˜ã)DšAZT×3éñvÄâúæs~¢û¶žZ,IMal£GÑJÙmÊy÷Q§þ{§ 9®J4\ÝKÑÇžùmE4¨ÓÒå¢å@Œ-4j–à8V\r’r³÷ímKèÕºx÷.šY E““áœLêIø‹·Íêœx]16· Ç9ooštÑÇÕ »È·pe]wƒf¦$QâÕ<WýœDù|µ ^é‚MÞ,==mƒƒ(eTT™÷v<ä*Jö®Ž±è;ªÒJ<º¨Bê]|•)DYãÒÝ”íL%…žo•œ÷±é¯æ)É›M¹hŠ*WÉel/eáºËs±z“—Ï(Ó”ü Ïä .¢4[VPv—«Õ„ŠÜkÍcQ&¥®i`áÎ]n_-®”¸R•UѤïú¾BjåâÍê„—QŒiö½UÈÍS®Æá™ãÛ³mhQêX:©ŠÒ̽ž{)äm”GtçÙ[=ôÐ#<²´´tüøñ­[· Î �‚iÓ2°]ýò â;vŒŽŽNOOïÙ³‡]š� ³U˜¹y€’€b@¤0Sœð´xT)r�ÈP´ lyØKš‰±��À P,��@±���P,��@±���P,��� ��ŠÏz,¹1��@®c¬Ý»w“)��wÅB®�� ·¸{ÇÇÇÉ��ÈÃÃÃÓÓÓþ1��€11ÄsX�ò ]J(´ðàƒ’ �ù„ÓkQ, U�äF£7i"Œc��1�€i±™|GÛ+–<•ÙËéÓ§9î:v¢d©*UêŸQî£å{yȇ¾ÿìô&ÞÔÆ›iQžâªÕú‹t—ù!B}âûû¼ izá¯@«ìz s‚ïxJÔ‹móÙ+êï‘‘‘3çµÔ!—»>Ô/q¥0úMÂz=¥wOK¿¶Óû„ˆ¨ë« wÁWääåm+�DÁ²,2!C2ÊXíÑ(øšBä-\*B¢ðØE}bî}pý*߯ÔÝ’+»Žîž3¾ˆ2ÙïìÒQoÞvW¥å­\7¡E�ÄB<3/T³ 1—È•+Â3Í÷ÛtE÷Ù½ŠÅ…okÄ;ªNAyô” ß»>O¿Jw”·z©§ ØT;²2x‹ …á=E±äyPXæ[²ÉõÝusè±KtÍ‹%Ó"ŽlE|b\½^Ñ¢¡ABØö˜eM™¤X6Eè1sâµGQz#ŠS/aVGï’ÎSzÏß0.D–ÂoÕE=Q!;¢ ‘¹ñÎn§ÁD±¡™¤í‘o¯cV™Ð]uRa–h7 0®ªØKþ'šÃúk2Û‚§<T’hK´ŸÞ3-ÞÞžÓáîE”âKÓ5é¨:…ü²Óûô˜ÿ]8âöAžCœ‚ÄXºóK« Ï×xLP¦EÉÒ³Ý÷òNïÙéM¢Œâ„\.¿ Ê+=$êB¼Óü¢äC&ãX®,¢ÑÅÔ™º­]5JÛˆâ?Ò`¢gcˆÞ6K#ŠDw‰òˆ¶Ïx“ŽjHGãFQbš wú^Ñß(z´-ÓèÅq5ÁZF]â¶2äKö�ˆ®eÈU–°¯ dIøræ<';Ÿ‰d9iˆ±P,(sÀi\æü$Æ+_°4��Šel �€bÀîݻɀ|â{ XX�;΄.ýé¦i X´ �蕘b”(ä*vX�HŠ�� Dçc‰ÐüE·›g—猟 cïE»-Þ]—­õý*üž��ÅQ,—% _ðŒ]Ì\Ùî7ˆ»Ø%q`#�d€-„Õî“’(–÷¼v¯¥ ŠB"3_ß �Ð1V«DT®D,ãXúé ¾R§ëûaׇ �@Xôe•+ÆjK/güPŸ¢¸ÝeWеªPä0«5À*ØôÅÄ×c±™t&Þ€h7ŽE¹��ŠE (Û¹Ê ßñH�(B˜U\Úcy'Gˆà^¦“íýYЇe ¡\#|´;�€îc,åû†Mjï箫‚nUl—?<ÒiÆ«�@§�ûFíô5ymçø…_ñó"…SI|ÞÅJ,d  ˜²Ú%X€YìÒ� Ɇm Ûnùg!‰Y±Œ�€„ˆy® Z�Qô&l[X…ž+ÈùX‰Óh4È��Ë�8†�³P,ؽ{7™Âøø8™��(–œ9s†L�ˆ [XqLÌíÊ- £œ F9È'¹]¹…b�@c´¿çc�@ž±‹ÿŠmb¬ }o}×]±|8·°Ç @9B-ÿS²ˆ±À0¹rû �”+ß¿Ëc¹¶T×£¨·Ýû³¶—���$cuá¶ãé�$M±³ºœ+H„��¹S,u`£K«º ’­��’ °Š>]0jŒåRš Ñ)‚3�€ÌuË*óz¬¶g wQéGÈ��ĦXAæFèúVW8ý‚­4!çJZž¨½‚^3çU£¶a¶2[Ñ€b£N)jÇ û �ä-Zs¨ƒi[¶d_A��HNŸœÖ-kJj•m×É � wråüÝÔtk¶.I+3ô &N£Ñ � mt¥÷ZÖ„óç¤eMÙv]ûÅ‚ÄàÜB�ðӪDŽxRˆ¦.TòðßÖ#€›¶=æ^c¹=kÅ*»wï&B'ü¥€JˆeM ±Ý¶RŠ\a–’%-«Ù¶È³\¥£¦(V–œ9s†¢€Jfíj °êzÈeÛ{-k»)¢•NÂP,Ú|fñMNÔ‚Êy=ÒÒiŠ–©íº\5KÞˆbA¡P»®°\L”+5‚%DM\™yQs)YÉu‹ÙíP¹âè50Û³í1Û®KRR$E˲&¤\Ùv]ˆmBÜcYSŽŒ•=̪F±®OÔù#®“G|íoôìÕó*|À¶ç¿„g{HñÅò¬ 70Lç¡1æÛ«âª!¾ ™˜®P©?§T˜%Ç®ô¨Ëé ¬9ŸOêÑU§¹§9ƒ±Ú»!ðm94†è†Ïµ­pÛ!ä*ïÅá¶,‰geâÈT¥)W1æÈU1ÖÌË„¶y’6‹}Bxf)¹²¬ G”ÈMˆ\Ms×'ƒØB$¼;T5ÆÖ›­sŽOí/м6E=·£G{ H7ym»Ñ|Ÿî¾D1©)hI’ üïôEº+µ<çRù‚­1×,v-äÓþnØö Bl·m!ÄXëúâäå*yùI[±‚ª~ÁÆÀÕkæê½\‰‘ÉK(…A·ÍíÓO½‰=ØŠòš½äÊ¥™j•üÿ)×ÞêZ`Ͳ&l[þrÜù>‹]š,!líïðŸY))\5ÞÚïêyH­£&…N§”»žÚ:Î{¥\%Ò]â}ÅÀkÇóPÜYEx½äøU½ëᥩª€%e’‚LiS%¶-T Ã”ˆ|ü•%4¥‰1ÞrîîÓ!i¥U¢×~oS³ÌŠc´Sù”«$2MUïÎ.dþ@·º5å;ýϲ¦„³,oPU·,©vcòÿDŒÿéšä|âÓ!i·dyP¬¶~\,­R°¿zaÅ%WñÞ?W±µ~6i’S¼üÞhº4LßÞBˆ1!ŽtMh’v%JKÛOº²¦K«.R`ˆƒìýß”Ó :Ÿúá;_£íºxVG÷O´ŒòVsBò?|$¸Ó Lè¶§ ØÞOÆZc,ù‡œ¸KßrÏÑH>ìDØDJ}ƒñìy¡‹Vrãÿ:ÚÞÁ€¸FºÈ.ß«ÊùÛF_~”f%‘ogx\ùßöª„n ™à9xÊw’ºë�bökïL±"ÎoÖ;OŠ—MúKÅû‚á3˜;JC×vú¬¶9PàµÃ±çw?ˆ±†@¦6åû¡+ðʵhY‡e=À.M��ÙãlÝtyà ¹†m×›3¡X��ùŒ·äùÎÎLœ;Ü{·�äK´­P¬Ôá [ JK CP¥ššb%ÇâQ@@Ødô#P¬²°{÷n2!„ññq ˆ@±ðß óë) œPiaŠE›ÏF#'jAå¼€Ê rå ³Û�àr`‡b�`Ö ìb }¯ wkÑXÎáíâ¹:?Pd´÷kø¡Ï¾…%"ìèûƒèæœ7¯( Ì:¤céçcŲ=vïg7”=ç}v9­áµ¡AÅçûƒèBPyóŠH6ÆêÔ£ôuÿƒœÍ3Ï®¢k7÷tüw×iá&)(I%ñòS@ùï0�(`ŒÒDÛºrá~Ÿ¡®¢~$9¦B*?5 mÅÒO :XÄWr‚”)HÔiCùoái°Òщ\¾&Òu�n¬4#¨€|½.ßvÄùÝ�m©vÔþÓ´ùo½úñç‰ÄXB©ú3”«.¼D †«S³(‚ ŒÒ&£dy«Ôú-]v-‡õÈKŒ—q8âeDt¥÷ê$»t4K;z2¾’heoô™÷@²1–žŸÔ+èû­· §µ÷À7|aH„Ýe;Œ4žý¢Ý4ë:åv”±ñb>Ë¢‹Ú›Ú{ÌÕ2P ßâ– pÓŽ±†��‚$ä*UÅ¢/��"æ™h�€¡ä¿O’ó±§Ñh @þéH®2‘7+q8(¹¼¡Xf°{÷n2!„ññq ˆ‚N)í”B ÿ=K2?±žÊyA~â‹6_^FNÔ‚Êy(*d�� X���±Ñ¾WEÁQò$å\Š~jsÛ£œc¼Dc¿9n{jsÛ#Qb¼P@åĶÇÈ„ÅXzãÑ qýÝÖõs¿`´?è:^$eÿ=úƒJëhç¼€€Š;æ7Æ’&@YŽ\?ßSÃÍõóp¬C/ ñ�� �IDATÄc&8{"«H‹lÈR±Úñ¶‡�Ì‘ÏðÕ\Ö0Ä (gOQæ.…o¶»Ž*v%�‰y=VG ÏôVª‘ž²AÄy¨yË(ïQ¥¾=ê�¸b S2êr½lš¢…\@9Io®`†™Ø%âÒŒÜö¹å-ÝP™d;9'ÿócÇrÞ?¼¿$\èÅ,ºòÐõ϶ùý*Ь»†Ðc®R@&ùŸ÷XØü\m £¿}Ñ-*ȲdõôNó9¨ÈºøÐ¸’Êð¹Páfº'c‰÷ Ò¿�(KŽ%®XtV��@,¤qÚ*�PlÒéå|¬Äi4dPlz‘«èj‡b%ÇâQ@�‹Ú¡Xɲ{÷n2!„ññq ˆ@±ðß óë) œä‡<LßG±hóÙÐh4r¢PÎ rB¦ïs¢#��˜1�@+¶MdFhŸG{ÅòîX‘æúªx×ûî¾aúr±ð, 9:ʇù|©Ô*LÒ/’Û†\A°,òÀOÇSÇ ­Ã•È7¹BjM:öíN·bzj›Eá§B·ý0sk^Ôý½Úæ¶¡Å“¨VÏ~«ÚK{sý¡{yr³vý¬U×¹«m}ä[`Ði^!É‹òRiR`#åz5o• ÿœà ŽP3w;%v?óÂkM¼VFÿ0W¾¡W®"&/ü¥ Æ�ËûOýð¯\uÇ�€qD±|ƒ CýVöä5:ðòýA@±ÂŒ…þI×öC‰V *@wäó¸¯f· õâ5`•Y¨\ÎP/ªCAtG>ûÊÅ âÔN},‰\•íͶ/kJ†pü)@â1–EЇÁ£´:×/Ó_ãž’ “#Ñ_ÍÄ÷UiöÇÊóµM[± ΈªE&˜ªXá#XÞO¢¥ZÄ[uB†î;}ñüÌ@é´8:ú0WïÒKe3Â&š[pƒ#ÓŠcdC’lŒbĦÐ!ñ2>>Î^þ(@R¢E&� Xô‰S@�€b™}â� Xy‡>q �b„3ˆ�ÀÌkxx˜L��k÷îÝd ��ä„;v*Öøø8��y`xxxzz:P±Dvƒr <Ý’ùI‰‰É Jp&“È¥–ó¼2¢@ieHsÞ’äUø»¤i4*¼ËvúV~Rbbòœr?<<¬²(·yeDÒ(Êæ¼%IO‚¹‚��`(�� X���(��”îwiò=ÉWä`;mý4d•ž4Ó–«s› :ŒÃ7ß8«ÕÒ¸’¥v—±ç[µÀå—Uò0 …ÌL(3ÔCƒc,å¶ŒŒ…Vz{aûÞÜ› W°¥œ„ÄvzRƒ"¿ØÕ%¨˜¼Ù¢§AÿÜõw %ëÍØ dÇûho‡Ax5ë4ÓR¨ùSVÍ3zz*î(­ m­K-µ!ÍÁ÷ïl›jøãÊ¢nƱÔžªÒäÍÍóH¿¹oý‹žà¤Cœ$ò¡»bÒeÌ7mÒþê¶Ø7Ÿ“{#åUøÞ<üÛ^òJ½T”jÖQ¦¥Só£S†Í³Óô$ÔdÂ[A¸1 Om&-½‹<O¢©FybïYT´™ij’oiutU&Ýw§5Œ+ÁDÓlD'ªË.xK6èÛLв÷d$ô.QnÛésÊóŽ,F¸ã•¹±í=Õ¤›–‰7/pR}ã­g~ž=ž®-Wem[FFb¢PìúÜQm1ÈÜU mü9±,²ë ¼NäÓu‚›nÖ ï©ÞªAÙ(…ËT‚2dE”ÚbVfVR0ÉÙïÍsëZêIu x:£/¡’ͤ€Lé Og%’ró4«>ç'ñÑ-†z‹ô£«(Eß{–VÍß$²Ì÷æz‰¶-ò$^Ö÷¶YæfcôH+…7ÊPÂGÚV³LR=Iá…›aóô}b†¹Ú…1Éa£ÎI]òÄÞ[wµ—Ĺþöý0µÀÓ› ߆‘Bz¢äC:yþ”î¾M!µé×®ðþašÕ]:ÃÓœU"3IaÄÅÕX2iË–( ë1UìÒ�оG ò�Š�àòÙ™U²��À+ZÃ,%Æ��3@±��À ü{F†iÊöéùL‰‰Éó2<<L^‘Hò0ÿiÎm6Z=ôÐ#<²´´tüøñ§Ÿ~z||�€œ¸¹ÓÓÓ£££ÓÓÓ{öì¡W��Ì ê«i±ÜúÌ™3"Ž „nWÂLì”u³ÔÜÊ@Êy^'®×i£X¾¿ë”F£¡:{¿[Ò·7afõ¬«œÌU–š[H9¯ÃëÄû: z�À P,��@±���P,��(…ÝW°‹],]6ë Ų)–ï­ºNgÛK M¹÷$'ƒò<Æœ'Ï»®ç澎oÊ ö:=6b,wö)Œ~CKÐKA˜s’}ˆßCž§\Ï~oÊ ö:½7“bÆX*;BÎ` ù½Êkï}ÿºð°ÂuM-r7åiÆÜq¥Ü[ÌJ¹‰yÞ¶žÇû¦™T~Ó[„ï%½4“\ÄX±Ç®ƒkÛú)m-ŽW®BœŽŽ<¬ô Pj)÷ÕÈó”'t”¹yžíë¥Sä+Ït]´‰Öà\¥<öWK'åñâ©¥\ÿJšËXÞ"Ûz®¬j\%’Úëø„¡-· z¬`ÕîêˆuH??žä!à6±$!WУEŽQ€i±DïÅQéôññNLÐoeú|‡¬ªB‘RžóÆžç#^oŒÚR”Çò:F·ˆ$šIñç ÆU×3¿w´/åÆLÊCRîuæbï„ ÏM4#Ñ_'Í)¾Y•NïÍ$Š•Dt¥òQ0ìÂaÑïWÂÂ'>éß¶Myš9µ”hçI§<¡™Yå¹¹¯r•‰-"¡‚(òÌ =ÚæWÈc¼ zVÄé­“—Ä8mÒ)OnæB:yã[¤™òx³=óznîë¬E$ÑLXA ��f€b��Š��€b��Š��Güç 6ŸïÝ’¾mï Zr›¥¤œ”ó:e~…õÐC=òÈ#KKKÇúé§ÇÇÇ‘q��ÈI�0===:::==½gÏžjaâ��(6nÅÚ½{7™��9aÇŽŠõàƒÆò ˲Èh�€èØö˜eMâEìï6==­þ®¯ÈS» � FŠ!W‰R¡ÈÕUè��Š…ƒŌβ� �…²@\Å F«ðC�F4Ì( X†ù2I¨ † $Á‡¹®Ixþ^8g8ñ(Ñzªµ0èVe6FkEQ]“èï…s†‰C±ð;R­…A·Šë¸á@ø(~Y @݆(àá�Š€‡ ø€b€á‚Ÿ(¦�Á�@±0%��(���Š��(Vi``‰�Ë ÌX*§åíý­J@±0ëh-o �(ˆ/r7­8’.¯ •LqD(_"lÈÖÊâ¹yÒåU¡rå‹+¸DK†-‘Ùí€Éˆÿþ/ÇÇÂyBbQ,Àdd|ÿÂKÑ!íÅ�, �Š��(V ‹� ÿfÅ¢Ã.ŽØË©´z‰£m“ÿšÙD±ŠSN¥`,$Û&ÿÁ8P,�� P�p¼�Å¢á5 Ç ÊV-Q, øfTK‹JŒ‡AaA²mÿÅÂ[ ¨6(�€ ±  X��Ä.€b�A@n‹ª @ÐF3+Û-û��Ðx‹R� ž+“bTQѨÕDf(AÀ¬Z'W^Å€<[L¬3žŠ�fXL¬3 X���(º§(}� Ì€î)J�Å ª�@±0�DØ@±ªg˜ �4)e›àJ�YFÅB{ðIŒ°®`»Ê¨X€¯��(N=P|�´A §¾|šâȶ%Ôé,‚?’t’^^ ï<%ˆbÁ|£(T0^ ÊP‚(�!˜Š€KÀ(���Š>ôƒdÛ(P,l"D-úÁ�\¤Ü(P¬R?P4¸P`Z� Ó€bѺ��pÍQ,��_ �€P,� D ÷P,ÀmCrŒò pÛÁŒ³¬)D !/ˆbQl�H&yf(Å�€ßo†b�@\~‘Ô Å�(rPU¤^+  ì %SªŠE#‡RÔR†‡sk7¢ÿ>?…˜UJ*T)9 µÔô¡ÍS¬”£ª(PoÅBBp$¨·PhÅ‚LIüM" � Ìp$ñ7‰$B@±� €æP,\9ØRdcDsO5�0L±ÊéÊáÀ’T�ó ���Å�(ÅèmF±��Šcúƒ’ÒÛl˜¡X��óÆ.’gÐÐ)ŠLN3²8(5(¡¹@±€ÉiF¥%4(Û€ X@l�(��¤Háû-P, !µ¥ ¾ß¢BµP[ ìŠEµÃoŠÀ ÅüV h�P,��@±rI:Ý&tÎ@±k8�Š•ét›Ð9Å®á�(N.�� X8¹�8j�(�ਊ…× ��(Vòbƒ× xcä� X‰ƒØ�Ð@È �ˆ$�P,�$¤‘: (€D—›uzä�Å(T¼U�³N,(�¡/XÇP,��tÅ��‚3 ��ÎP,��@±���P,P0݈Ò@±À ˜nTf© ô©x(� @ÅC±ràYà¤��˜k P¬= œ��sÍcÚŠE”�°y3e%1­i+Vš2žB"Àd”3È[DR’¤ õ»Cœ“Z’gU '�P, 1ª�€Sˆb�@ÖN!2‰b`>ŠœE*&úNP,�ÌG‘³‚bB±�ˆx_� ÀXßÜh£O,(�"„¡€b�à‘ X��@H‡bQ¨��„t…´–•’*��ˆb B|� �§�P, jáŠR+µð‚�FTã Å���F@¯ Ñ��ŠE487�€bàÜ� X8È��€bå^p�P¬ìA��P¬‚X@q��ŠE€� X��€b€/ôjRd€bÑÀ èÕ¤È�Å¢1���Š�…N �Kf@'ŠÅƒüë–(}ñÆK :u}Ÿ*O•ÂÃ-Ê‹ŠAuêý>)Tb,mÞ �Ì�ÅÂÑæ½��Å"è��‹à���ň%ú¬˜�ŠéHÎX/—XÖDз*0õ>1Ú XÐ1]txúJ‘Zøå½¡÷÷ò“’4à<¿f®ÒVøú W{Ô Å‚D,ˆ÷Õ·^)Rº¥¯\–{_’ÑÁ<¿f®ÒVªúÀÐ8н:¶^ARòãü]sI—Ò­ÖôOäµò¿ CüM�ÐaÏ hïØêBâõ-kʶ¯|¢ÿÀ¶Bì¢&Ä”M!„mOYÖ˜m×-k"Dð7 1V¸ãŒ[ÃËWÆl{LMTq’eMÙv]~eÛc–5.ÄN©UÎ=BÑ´í1!v ±Ó{[¡uR�¥byçÖ9f¸ÕùÒ-o÷ &Tú,öÖν¦5Û®;1–þ¹üc§“ò[GŸêzg#™�.rÑ+˜óTBâXÈ™ëÎd´T“Úö˜¦Iª/ñJ&ƒ0!„“Î%BˆšM!šåœ‚QNOˆÂ3b¬b˜ïò¼¸Þã'ÿ–’ãš[!?Ô$g¯ö³šúÖ¶–5!DS-Ør.©©¡¯ÖÙƒõÂô &ú"ñÞ<é<G®�Å‚ V]*GÀìó õ¡05…h:ê²S!Ä“š&MXÖ„#Eãž3uöJ ³í1Ûn1©f:×NùPã”,dét (€bq€mYÖ„e·ÎúÓìº63P©×NÙ­'5IMÔlß.=œÒ‚§'¥Î©nF!„ü§mïuÒjE²ª±¤Q J­U骇üÌ3Kb—w‚»wÕ°¦IM'D“ã^ãB!nâ ËšâÛâV»R^�(–ÙFzÎϺO—gXìôN‚Ðg^¨¾Á —__ÂåR;9_ò¦„xL\^¼õ€ûdà¥R"¸V•j¦\7�dŽÙ+ˆé‰73õ…ÀŽ Lz{]R$<ûÞêÓÜC7T> Íƒßåt*Öm».Ä6g¼ÔÅ–ù¾+šsåQQEsëìR4ÄXj¦æ€šaáYºÛT ájá®êWé?öìŽQº•ZÅåÌ-”Þ%C=¡-ÿ B<* hP,ên)œMgeÕ”¦:µˆŠ²5{ë‡r –wÝqSMD”sßÕrcma]ÎH¤Ô�P,(WX)çV¸–CéÛýéqLÝòF]Âo‡Ze쫚21BÛ*× ³¶ÉL¦°óÝ>@± J»•½sZd#œ µÖnº.#Q-V›Ò6Õ9ªVÓäMÍh—]‚ã2“Ÿ„ôIbR> [PœRdÛ{u“ª ;åÄ•…YS±ä°~zˆ¶[î˜Ò3Ù (× ±MÆaN|¶Ë‘±ÎývùZ¢b#L*@å:m[кÉú¾šä̘ïïôK}‚»Û¹tÔ™p!' nBÈÉŠrgB5qQ݇ Ðçjhó¡W°Œ5Õµ™…m9ò f"éÀ%hCB!„³1®¤©Åg-ÁŸ:ÖD´.ö‚Âô…P¦øîF*7¹šªf78bPOhOUßyré•5Ûnˆ+k“'„xLˆ]Bì’gh9G?¦E }>!t!k)eŠ95R±¨¸=VÇà‰ 5ç’®è* ëãÝ]I‹v9;áÊô< f9_5„h: eR'}wéÅÅŒ~Í)½‚¥ˆ÷µ.¸1u*£¶_mͲÆÕL÷¶ºëS¤õÎFm©²Ú«©¦M©¨9³0&Õ9Å2¢Ò' º–'‹äÖB Å‚ôC×>L¾;-…Ûåðæt¤ÓåX÷“¡fa4µÓŠ'´1ªq!„m«9{C'mJ0U�(ŽpJŽ¡ nœáŸZ«f¸e¬ÇÌWÝ€N�×tõ::Ú©Ïtw¶ß•Ç—LØvCˆ]–5æt>©´MŸ4O¡ XÄìÅ“ðš¶8w[«À4ºÈ=×–K­—7õ¥Êj_AÛn8 ‡÷Úö˜3ýòæñBL !„¸AˆR®´•Å“JóÔsÕd÷"­#€²(V>õ ©~T•³qß”<}±Ufvu‘lËš‹‘]r¥-½ªk›¬Kéw¦­?é÷ ÿ= Ĥ78úÚÔÂÁË£\®-q ³ˆ�P¬ŒÃµ ©mO9€jf]CFTúñ¾¾óî\S6ôh*¸]„í@Øt¾Ú«(ìlr¡dæ góÀÚµˆËcl5!s^¤)<Ó僎 �ˤà,Ë%65!vÉ�Këd Rc`zÐæ=kX´9 äÉÖBת,µyà¤5G·v:«›¿$_DmÆ¡¦ËkgwµlãKÌŠe^pCs­3ËåÌ]~„Ö¥æê[s|å=Á ¡Ô4zMÃ&œ¹‚5G.O´í½BÜkÛcBüXˆ¦M!&…¸G®#¶í† ñ€K‡”øy7Æ¥‡0SÅ#û ´çUΓªGB®ñyÜp”ÕK® ‚ŽîyóuýHg¶…âGTDõ¸5ËÚîh᎞ÉÐê !öil;]ƒmú´ Ñr8$�c%SdnRKj5MYwŠ–Þ¿†«¯/äYÞ3®ÔiÂÞ˜L¡Æ®¤ðØvݲÆI€BÎ_W«˜ä¿$Ä=rR»£vo ±Ï¹Jʘþw‹Ó@P€bS›-ÎøÐ”ŠiËþ˜â¸'\ì §\+ŽÕ"RQ´ÀN†DÛœ¨ë!vZÖ¸œï'DͶO:·¹Wˆ«@ê !&µÁ¶)!¶ ñ˜:ÔQx†ÍDk&ãX�(V¾À$EÌg†B]\Ùû|»oðäkî]{½kÿ[o•ÆŽ\©+jŽþ]‰,k\îèœi"»åF‚÷ ±KˆI!b›³ K΃ŸÔæ /Š+{>Õõ0‹«ðµº ˵buZ<™›¤<×'mfDÙ¡ ¢¢ÇZ;åÜù©ïC(.O…óª—ë!„Ø¥`9AXSîÌäôò©Yé»Ô¶ëÎ/Sç kGŸl“ºåüf§“í {i‹½šLp§³¡0ï•ô™(V«cÎìˆÖ¤!Éa§íŽÞÔ‚özoÕ§q½çP?˜ÊQ‹Zë®MMù&j¶NÜëèMݶ÷ÊøIˆ'„¸Aˆ]BlbRˆ ±Kˆ{¤dʾDÕÓè̹¸2ÙÝÕW €6£X`X½wúè¤Ý«øëlšî ªkË~umhz·Q×þ©¯élÐ^âI¥mÚä#B¼-DMˆ„ø’÷ !œÍ/|ÂG×AJ!!/½+� J¥=.9ÑÈ·õ8¼c[@çÖ*—ì9Ÿ?&Ärn½oÕ„hÚö”ÛöN'Ò’_ÝëÌÑú\|ý¹Îú°¦ïÓñXP¬‚ØñRu,´ž|XwÂ£Ëæ>(7Z®É³©Ôl@MçjÎÝBµ^ÊÖÔdüÔ*W÷±MˆÇµír^bÓ²¦l{—¶û»œ"8¥^AÅm®u`ÚWÔ7�«(v¼ð–EîØvݶ…\~+ÏïPç"ú¾²ÖsØ*åšdáL¯˜P={Ú| ÷Žži5ퟗã6¿ea çYã­Ý’A…åšH’óú�bð8Vì#ų,žÓw9Ýh»t£¯|åB×.uD½¦IMýGž]sâÕ>¶rÂEÓQWiÊi“BLª3PœC“]QTM±Ó‚œØ%ªb‰b,\×èa–¸2¼Öºò·®m¬>¦aå^¢ëí`ôœ¹5åLçsŸyv¬;³*ôñ³+;3Ùö¤3Õb›»”Â9×6ƒŽNvÅaÔˆ«ù$d—¨Š%бJè‘u~óº¦Fu5Ñ\ETz°¢5ž¦'ÒšÒÖ ×\¿×v^wéÓcZ\%ÿg OXÖ˜s°äNí’¦Ü÷V{ƒ]žT5µ‘³ Ükâºn1І5 'Tªk±È¤’"§¯Þº²Ê-<NìåZƒ|EõOœw !,k»<éQ.–HºH߄ɑ¢'„hª]¹¤¯Á ­Nw»(’¼!Õ€béÝúY½ºi³¬q© BµšXÍtM ÐUP´ì4¨¼WOwžÿ¤³kûÛú¢cíxâ1gjÒ¶ëBl“k°l{L_y‡Õ}§­wg©‹·­�1ÛCb=V‹?UˆÄ_j ªp­h }aë*ãšvŒˆœªÞž›Z´ËéÇkªåSÚ­äÝþŸeUDËظv“š7Èž5d%ö ˜~ "Æ*²ÓªÀè}£Öù Þ)—W>é«€õsî]gÞ«¨ÈÙ¾Öu(ðåñ'×Á’ZöÞbÛ '®jè»ZhS§zñéÐ'�Ó[ ŠUø 7¡ÿ¡ÏDw~¨w¸©îA}'o'€úÐù|—;…ø’Š·”t9W4µkÚ®†r¯Ûqço}VCx&w�@9A±ÊÚ»V\韸Vøz¶VrM‘×÷G¯yrܲƄ{žáXëïkÎ/åvì5§·PȵYÎoäI%»Ô%¾ªé}SŠ;E&�ŠE3‹]¨ê®I€z¼ï=;ØuΈð[€åwºã”µW…¾ÊXßçB¢M‘×îUË-kBˆ{œÉô5õÄ ­.rÛ‰QÔúO>Š•8ekfj¨ÉÕ}°;{Í•Q¾û£·Š_Óï¡ãúaľ"§-ºštöyR·Ró2Þvæ1ªc´¦¢e…”å 7©ÿÐüg[yJérq)Uh]à&MêêÞC‡…{¾†kn¡Üfi›šû®N_Ô⤚vÕcB< ï®kYãr9—;[§ÎOE1ÄÑ·½0ÚŽÓ²•ÿl+O ]J* DÌ%µs’#EM—‰×B±ºë¬a×Ò]×,v¯¿)O_”ƒUN÷àå¡Ô FËšâ ¹†OjG ±Í¶ëÎZrãÁzÀÔy#½cš�@°«Zå x6 ¬kóñ¦¼»óiñÙ•%×áŠrëBGä&ZRFK²?PMµ¸×Ù c¢UEv wçä„wJˆ¹Þ1�”.ÆÊ¦¸ê“ׯ,Øòè“ §êžyn%k=¼q‹Ú+®ÌÅx̲&Ôð•s“¦YÖ¸»\O‘sÕäx׬‚ÅIB[‹+@«PqL¹~аÚúOÙrmåîjÞu}I–kF†ß»ë«?àüf—emwzÿDëœø')m ñ„–¥rËö¦>r¦«”ß°œyn¤ÖÖ|·G¡ž XÃv>¡m}4áেYúšßÖÓÝãaÞÖ® é2Úr«)×ÞêNwßN!ö ±Sîïî’@Ýָ¬ 9#”;¦»›¨ƱŠï–j½M×IWBëåSýywo б‚´Ä{ÞGÐ~€š|Nê³ m{¯em—wl÷•(Wª�Up9OæJBžŸmÚP¬òˆÖ„~`cÀ¶°S^¹Rq˜ïqõºl¨]n[£´Ë{àz§,zeOÑí·ã¢u‚>n2;x¢J‡@¯`‰âq]®‚o[óý6tkv}AqÍé']©­¡´ÈoLí«Ï³P³6òÓ�($è|ùMozã×$r?Û늄Z{ ëÏ‘{Lîè¸(®¬úªk1–ÚNð1zÿ�€^Ár)œ«£¯õ¼ËúáÝ¢ÉRjéÌËd��GIDATÊÓÖ#«ðh¶Ý7ií÷ÛîLÙPeí´¬qÕ©)ÛvCˆIug9í0\›Ñ3�b,ÈEgT,»<xLü„¯Èé»únåîºs(IàVžÃMôÙ퓭¦>w¦o4[çßQ7xM@± ƒH%ý–Ë.Zhå—Ôô»lt½¯÷œ-ý+u(‰ëÀûÖŸM¨©‰âÊç¦ðÛĶíYÃAjšór)@(³B—AÈóöŽ(V¹Z²ZÕ<"42廸É;eC;vKíäTkÝf©¦ETúʰ¦Öëx9…¾«»�rÒ®Ë äœA ×?×Ü?ï²*áwGÈNê†ÞƒH,kJˆmÚÖ·SÚ™È28Û麳vhdSëbo‹P}�ó@±Ê+Z!¥©å鬷®¬ªëC_®EWÂYP¥«NkØ4)|:-kŽàMˆ‹±"JS3�P,0W´v¶†;WäJlܧV"k·r]‰€íþ\#^jÊFk§_Mˆmò¶cW¾RD €b•…’Ù»]úR*ס!A1YÈ<r¿M4„ðl°ëº‰ÓO¸Óé3ÜåÚùÐÛERLR�(V‰‚’½iSøí0«ºãô-*Z%Í}$qëá®g¹ÇÌœŽÁš¦@»T˜¥¯ñriG[á;Še4ú¹Vêx*×Üwß"}RŸ®dÞÎ@×ÁZ¶ÝÐeLmì’7}æ…3Næ–F ßP,(9PÚãùÃû›¹uM–B×—k'{'€¨™M=U"ð\.�@± 4!—¶”*PÞäµÞñ*ïZ.—nµ®úªë› úîdèÚä©Ó‡ Â�P,èXL ¹´>ÀZHXæ%|åõIð®ÁÝwM}Ë oJDËá-DÌÞüah*�Š•/0PeÕè‘OXã9žX¸´Ä{ü£~J–ïÞ†rÈʵw†nӃ減Þ1HÇ&@q 4“Ü–{ý¹ºé<zuáåÒ{ùôé…J®ÔI"Þ] õ1*}…–¥5\ñU ´äô´‘^<Pžè-·›.1ЗUùn÷Þzµ ï¡\®KÔ–íΖ¸5!¦Z;¯±”5u€Ë<µƒÖi5ßÃN"Vq˜+sÍ¿ð½Êù™¾v¸¦÷OfUgˆá�P,È5ª+Ïï«ËÛd¸vÑuQ‰ NEW\¥÷j‘L‰Ö3·2÷?Ší�¡Ç`œA -öK›I¡ÔèÊ)V®ž=Ï6-vÐ;#@&tm߇·�ÙK‡�1¾glöË3=¯©&¾ûM kÝ;CiU­í"*×:°ÖEZÜ y …R"(Æ%˜Àé¦sm?¥ÇX­ãUM}â»Ö—xew Ïò¯y´PJ$zÔLB.q¥ËεmîTkw¢OÝ•Ug£w (!„Þ y±Jù­¼5-}*¾6eŸs§Ò³í˜~„£GÆÆ´žÀºoØ$c¬V¹’Ùëú¹'Åp¢S®á…´ìÈ…’Å¢.æß2êáNë~íuy¤6òTWsÓe— .H­Û„ðÌ—Ó½ g´÷C (ŽbA–QÛo©îhÌxëD¾¦ëÇ®}žôc±Z{\{2M  �€bA,Ò5¡&¸·îs1Õ*lr9×”«P´îÉ$Z{${óšÓ™(fæ<3Ñ'<½|j÷Цw«'‚¤œ„æ]ÈOæ%…d¢X@[êÌ`éÙ½ç€ýRª0=ù)MÒ (í¿¤ÞºßiÂdWÑ2¼ @± Pjm¨ a‹£q¼ Å0Þ"dk‹1£%)h@±°,…²eÞ×0&€b™aYJ^}½ãa…4%)ÀMA±¨¾¼>¯ €b%¾É³®{‘‡€byæ œQ±y(`ðG�Å�cý�ü@±���P,È+ô/8ó‹Q¸TQ à2ô/eh.“Îüb.UÅ�Ì%  XøÝ�H2�ŠE#À¢8P,�šîP(Ðü�¤”™F–¢X˜ ŒðHÌÈ4²´Šåk,ŠdA¨Ç”@©<°"+–¯±À‚��êÑ+�E𾡠 XÉ�a çÞ7 X€Â�Š�ÈP,Ú€9ÍP¬²´1� ™Š…�€bWlŒðÑU�@±èàM�P¬ÒC`�€b™!FT0�@±  ‚Ί�Ø&Cò¤Ì9STç ÅÀ63OÈ plÊ€bȱÅ$Q�Š…I ” � >±Áo €Ð!q@±°)€5§™�ùb™iS¨²˜§R5*¼Yf*‡åE¯ U(k2Ì(/ �À r¤XYœY ½-`†bÛÈÒ€öB¶@q‹†¹“„k(äN®•q-¨TMÅÂ~Ѻ� ÖòØ–çFŠbÍ�Ìh¤i(n5™ @S"ÍP,Üj2;4¥’´—D3^A�ì€íÅÃb—CÄg�(Vél1¾Xï7̤PˆÏ�P,âb P��Å€RR殑¼;Š4f çÝ}š?çca%iÌø¤¶¼v ϯémþm Bú¯Sɼü°’P£fVmO3µ%±{Íô_§Bù͈ÀÇLà.�Š˜0� 2eiÒE±�+8@d©E±�+�f€b�„A_Š�ØG3H­/Á¶ëä6Š€}#Š~‚L@±ðÓ‰�€}!¯u1+?]>Ý |G±ÀŒºH¿� X�`pèoÄÅ*]s*XæQTæ¼EÛÄñ(VéHºÒmèõÌÁ:ä_«(#@±�7¨f�(��€qŠÅ0 ä­žä¿NÒjÈO+rÒ­A•Í9)‰›óú`Vg`n3S%ŒÎU ƒÛÇêCyœ¤.2³÷̉rZ=Š€ó“Ô«öôž9¨ŠP̈ ’+”P,� "E�(��ô£X@ã â òÞ8‘7ÀÙ ð=¨(�Þ+� X€÷ ª>ŽYjÜ+£X�%U} ²Ô¸WF±�ç€a(˜ÚB¨Ÿ‘NM@± ›‚¥£�5Åê7 Ä©ÅÅ‚œ¶ØØ›1Ñ�¦ï ÅH¤ÅÒŒ1�(–yžlמoì.3>8� Xx²‰x¾±»ÌøàO¯P,��3¼:@±��Ú�Å� h ��P,�€òB×"ŠEU�l˜]‹(VRU¡#‹€ù€œTxª"€Š•­â:^<�Š@t @ëC±€ð  L­ÅÀ*˜á¡XÔ*��3¼" ��Ì�Å€öÐKb�ŸP,€²÷Lă(ž à­gZ  X„ö3‘­†j(VéÛ]4È@  Yžihjq+WeKb¼í‡ú @™UW²8Š•«²L(1ÔW�š A±���P¬@è¦�@±Ì€>�� �âP,�‚x� w(z�@±pW¢¼²®Š�€—Sæ¬C±��À P¬²Äæt’��ŠfÄæt’�€AN6ŠE�`†“b‚�� Š��(�€zàÅÊu»¢‰(èÇf¢X¹nW4Q�0ݯõ¦Ðõ 3/��p‘sšÂôÓŒb�”.`2” E@ ‡²L(E)�(„b�A�Š@І¸Š�P q  ¼^ ŠPjãhPxA$( :G�@± ÓÕ(U“G±�ñ��š<Š��(¶�v Å"lÚù Ø1 h{@~BqA±���Å�Hº.Q,j!�˜]—(µü< �@±ŠfÙ‹êÆâI�-P¬¢YvHߨé¿ÇPÒ" ŽŠ1vúï1”€Ò±@±� ŒJŽ–à<¡XEó}èÂH_ ÐË$[T_ÓO3-�²W,m1ú�X‰2*~P =M²�P,ü 3r˜lÇÍ"çÅ¢ @I�H9çi¹¹5e(Öºll^EË%CP,@Ìhl^ebYƒÑ X€Ç ”5ªŒb�N{ðÀP,��"B@±ÀXg–/FâéF pf 0ßF¿x\‰'” ˆ9]*”«,P,ÀyK¡,òŸÉ(�®1¾˜‘É(�&À P,(©ÏTW@±�Ÿ€ê åP¬’;MøŒ��Æ(VÉ&|F��c‹0…� ,ŠE˜BÙ�Š��€bt]ˆ�(€BE"àÓ X@kÉ5PUP, µ Ø�€b‚xP“Q,�Ä„*FÜP H(uÅ0Ș X&�À˜˜A5±À¦���1�� X���(��@׸DZ,Ë"S�� ¸¦Dͼ°„¨8ÿ«ÿ×Å'é\Òö&VÖ ˆýQKê?KØú?»û$«›¨”æh71­•´ýÄ2­•D¹IÇ0âÍ Sçè��A±���Å��@±���Å��@±���P,��@±���P,��� ��P,��� ���Å�� ���Å��@±���Å��@±���Å��È'Õ€Ïm!Éœ³$Ĺ@!A¯Hs‡ÅËeÙØv˜b¹¾��_,ËÊÖ`Æ•€îîñª¶?ëèéô �€ X��ÝyT\ èî>¯jû³ŽžŽb��1���Š��(���Š��Ð-U²��  2\eY–ü£÷t}«( ­ôúþ8äéò«6+ˆ� ¢•Ï\){TÍ®o1¢¯ö>Ý÷Zz�:öí cÅøèîn•Dpñ†ÄX��¦†zqíÒ$’Y¥Ë±£§£X��å•+¥qíè6]¥>x[z�Ê+WÙ>·Ó»¡X��%•«.¦Xm/Ob~ ½‚��ÐqH”Bœç}Š�`^˜å«"](PŒK»:½yOG±��z 8Ì}n×w‹raGx¿e ��Ì�Å�� ���Å�� �� \™+8::ºcÇŽééi2��rÂèè¨b¹¾���ÈcŒEh��9Dzmûá‡&#�� Ï<úè£ÿ6J ¬ó½����IEND®B`‚����������������������������������������������./saods9/doc/user/binning/jupiter.mpg���������������������������������������������������������������0000644�0001750�0001750�00000517744�11222161077�016462� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������³�àÿÿà¤��¸��@��������z¿óý)HоR”ˆ«ìî¦Øõ­›79]ÖÊRªéHоR”ˆ«å)HоVg7î¾ve:æÍãªéWÊR‘|¥)WÊR‘|¬|û>¿Øß³?aOœM6açþ¿ùýÍ'c¶V«”Uò•›3¯÷┬¬Ø=oßÕÎ*ùJR"¯”¥"*ùJR"¯”¬Ù‡Ÿúÿç÷4ŽÙZ®"¯³ý›³öÂû~Øz·â5])WÊR‘|¬ùÙ7µuwÁênú®‘|¬ß%{î¿”µîßuqutˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоÆ_ïÎÊScÖs¬Õ²•WY³ýû/ìÛñYûW(«å)IÅ_)JDUò³íÛý»w»|ør¿Â=]"*ù^IÊÿ,suuàœwfsw}Í“q»|ëν÷ݾ×W(«å)IÅ_)JDUò”¤E_)JDUò”¤E_)JDUò”¤E_)JDUò•›¸óþ^øîÆ“¹ß/UÄUò”¤E_+?fWïÅ)]}ørŸ¿«¤E_)JDU÷§'î3íÌéÝ8+%…êŠRQWÊ[ŠKãR^w)MÒxÎÍ™±é8jÞíp—‹B13|ž‡,¤%9 ÀpŸ’ìý™A~~ÖL,:¿ËÒ÷À;’‰n“±|–YHòr�Â8Ò¿÷Inÿ`-®±@–” ²Vt–Vņ”épÌ3¸`ÉIJNÙ{º3=Ì3°ç_òÿÙ•ûñJW_~§ïéó²þn)jêïƒÔÝõîˆ@ †C%òwîoù d!ß·~ZRügÛõ\ˆ{%‰JŸ±É)Õ¾I¨éd£¿Å#/fW´èWà3Š¿ÏÒ”ºé«å)HоR”ˆ«å)HоR³»vûvWùöâóçú®"¯³¹Ÿeãó©Ön0îgWJDUò”¤E_+3›÷_;2FóæñÕu‹~¼Í›2Ýn·Ù•(«ë¥)8«å)HоR•™Öÿ¥3fǯºÝjTE_>v=]ÏøÏ–ÇžwS®®”ˆ«å)HоR”ˆ«å)HоR”ˆ«åè@v¾BÔ—Ø­•¿|®–ù t­LŽºð¤ ’Hï°ßÕ·ÌÐé͹ÝbÙ,7d}5%\’ùx0±…rY ЀܞÊÉɓԄÿ‰e:6Bf¼´aç‚€k]_È(7p*MJIX bRRŒmòI©B] 7-nåâ@jyÊ>ÂBHÄ•ÐÿŠÌ€ÏÐQa˜nø°äaˆÈîžÈ‘®„\Ð�Ëÿ!!›”³r¾b¹Å¶ÎZ@ÿ–XÂ×x$÷Ø,Þ`€9:¿ìø”4šBFãJÜ7dr÷J‹/’PI+nå ÛºèkW„’”#àÐÜ43±hßâaD¯º|5ÖVJ>OÞù ˆØ55ú~néNdþ„¿wÃîoíÑ“‹Ž”•ÆŒ|VFß û÷Ë~¬ô;üz˜áÂE¼êÿ³†”YDÎ’f(¬ZwÙcp Õ‹%ü ÔàÝ“ò~Œ‚ÏÖ€TÅüLGè/”3†Rðݹy%bÙl3§”^éKmxpÔ–‚`aeðÇ`†'’ݹ@U!£C2Æ~VQ};³ç×Ô¹4 ÎJäÁ€H7£“„삱|a- Y(Oû'ä§þϯç[þ<z‰õÕÿŸ‰€!A4„LNû¤7â‚Ó3ÿ’‡Émðó›».òÈNIÝóo¾;îìÉ;œg>û° ‰A…ôîZ %`1Æ—ÑŠÙ%”É)‚ ¥£#¨¾¼PO]òd–M G+±1¿YIt§t¡(ý,JÆvè~¶V÷¾”3¹ø^ ÖU›¥)z´Uò”¤E_+?Ù·û?l/·í‡«~#UÒ"¯½»’Tï÷Æ36fe­û›„TR³»vûvWùöâóçúQW×X·ËÌÝó-ÔËq/™utœUölÆþ¾{ÎVÇcêéHоV2ÿ~vR›³f­”ªºDUò”¤E_+­{cû)Ì;¾4êºDUò•Ÿ³¾Ç~gëcŽ?©ÕMÆíó¯:÷Ü?vøG\¢¯®”¤â¯³ü…ÿ²öZ—ûlÕ…ÕÖ2÷~wR›œ³F-–º¹E_gí¿ÛöÇf~+?Ø/íWJN*ùJV2ÿ~vR›³f­”¨Š¾ºÍ²¶ËýJ_ïø_Ww@wÙ<¢Ó‘ƸbËÝ Û!—’´%¹Ýjÿê4êÿª�ì58¢€,O!boჴb’‚ûâ``b1oÒ“ÒPДe?Úæ€é+§€Ä%ÒRxo͹DÎ4´Æ & % FØf-;2-d4”!¤7 ÄÒþ !F#t n(ÈÒ„’>A[¹{n2ð [l_ |’Ò‚jx o†€§;ä·ü±¨ËÛü×ÏììÌÛ­ÌüyÖ¯ãbnÁˆH-’ò÷ft# ~î¤6ní?&”‡úzPKFéÉÙ+8Í×ò9ïBð(• 7'ôtr’bP”0o -®²2qÙyõ¬7†I(O ß²K) å¥(‚ÀÁY<±»�NJø´þsûÑÛç îa£øu½øÖíŠìƤ´ô ±›žSä7ý)_C#?½44oÆ–1%'mƒ1n_&?ÁŽ„§„:_â™ùC~ãuéÊÅ€í$†#r^(¤†$´`Á˜ †ü_Ål43wý#™;ëÑ€fY5PXfJËù ºyi NCЄód÷ßç÷•‘²Å›ÎXqö•07É,°ÎXa-9Ée€ÀÎî€(W[ↂÙvÿßD%àΔpÌÃ{¡ 9QÈémöÜ’JÅt¯9Íy°ßɤ²‚ú0AC eäq™h ÈvW%á®VI]¾½îg[õs»wesºœüi×”9l£óá?¬ãë«þlVOÊ(­“ˆA¡ €/ÊI4¤pŸóƒ7- ößß(†é (Ÿb°%쌟™‹+% èÜ¢“ÐKÉFû2ïµ@(Á£JNéÝL²Rv/€å?òÐ3ät–œÍ¯‘”ZK ÈlM~7ý²S±mŠå†!*èKrÐÎÁ½ýßÎýùÜp fj*ÿÊùŠèb¸ÆC2>ÍŽaÆY-ÈÀc2y[o²6Ã6ݲ´ýùŠg3Xo«áö|¬ùÇŸº¿Çw0ŸŽù^®•Å_)JDUò”¤E_)JDUò”¤E_)JDUò”¤E_)JDUò”¬îfÝxþÊu™Ì;ÇDUõÒ”ˆ«å)HоV~Æ~¼sÏ_ÇÍcªéWÊR‘|» 1Èåa¸j¹Ç%Ηû²1A=?c¿¸WtiŠÉã]òÑÝJUÊ(´»o™‚sãZÅ«þ¢€Âj\´äöÈÅb î”Pk¥Å”Y'ºCxÝ‚ë’�u‚Š Ù( t'øb¿ & ¢^î°,ƒTû{¨3 ¾M! &”‘¹,©,k”Ý?¤`FHoÈÎ3ýy„�Þ‚¶& É/†ý±3§d>ÈÅâÛbZr¿·e_<ãMì;,ðáZÕýÒA|›É©q 6$²ÀH4–„ 32·ÈÅ~ù6´“ +9eÐLN¹!Ÿ±hBÔ¸ò8ÄdfBCì7^x1)áƒK|ûâÿ~L/,'dÃ1A¿%%†¥Q¸ï½¬²Eé@‘³þX ŠÉAI(7Ë)(Á#r;m.Œ²å»öØwØZÕ¢%'¤¢DÔ“RÐK)–Ø 8ÍòJB7-â¿B[¤·íu’‚`o± 0b@È`ia£Œÿ-¸j>Ì‚˜!)Á˜—óý:1/€ìšÃ@¨PÒ‹+î‚_èü3ä£å÷}·ßòê „ ¡¥£ŽXjMC¶ßfè-ÙB7epfç9Œ£ ¾iõÕþ¯€ë!òñY(È(3Ù½=€-åïÐËÉFÈý»6óLM/!$ÌR�ÆãxÝ‹/Ð’^ à =³Ž³“vÑaŸ¡ÉX˜–t —ÒSô”X`IJ:6GÃpÝÿKõÃô”‹%%%.XnOInž7+¤oãò _ääJîß·[Šý…ÂNTêÿž�h’ù3 ß ä´îRSò9e OÉa‰fÛó†€pŸï3“Y\hßÀª6±iééN@oéï¿m“¶ß ÔW€h^A|¡¡[::wý•’R[[! YŒFÈ푞ñ._›!“›õCoûo˜Ôg7:ï¥,<p¬ v:¯¬­²²fÌ…(å”r»Vt’Ÿ§åð·u!þÛ?OWêÎÆ*­±hù(W}ò[¾8ÍòÄu×ðÜéF_FvÝù»nß:ÛåÞ«º*ü4¥-%WÊφﻯ2¿Ü;æøN]]"*ùJR"¯”¥gì<ý•¿?±„þvËñ|uüµmÎì·4îrñøÓêéYÝM±ë[6nr»­”¥J*úéJN*ùJÎæ}—ΧY¸Ã¹œ}\E_)JDUò”¤E_)JDUò”¤E_)JDUò³öcרïÌýlqÇõ:ªë­{cû)Ì;¾4éE_]Ò!å1Eâ“þÔ¿—ö|œ½ºÆv=»\ÚKE_õärÒ_(š‚øÖ @b:Pž”¥ èåb»¡8¬Èé¼ù ´€è¬” 0h᜔KÈÉJJGïÒPÌ‘›³PòX`OÉø¬S>7|ı¯Ó‹bWXãrwTèÈNFû|… 18²YIÁ‰Ä®7„•É@]-™’§Uá£oÄóøxsñÆÚÕùKBI‰XnÏÆ6ÃRœ”õrÒZF·)*GèGÿÞœ¬þHa03“ù#J’òK I+ bPVl^-?¿û}®10™Š)bnü5!¡© @kà‘›$””—°Ñ¿ #¾G^ÖN€ ö-tô'!ùe†ò’å ÈãKãvÝûá¸f‡=øVÝ–v5°“â¯öèBI¤2Ê GäÒ±hùŠN ±et¤–W,`Ä)¶ɵ€Ä$³¤²fàX1±5)J7F(¤”Y5() $£ þÚæ‚ɉŠ%у> )¼½²6JHEÿ€±L„ᥧñý„°'Ê oÙ% A[º† 0¼à7JBrºS·ê}“pä›ÍYçœý{y„JªÿpM à7ü…±E†ŽJÄ®„`Ä’ËF+ô·ù;b¹y9Ïr¿±@Ž‚ÐMÁŠœœ‚÷%òÐÅŽû%_2F%v¾B,…‹,Iü§&9] K¶@Ýû§ÐÑöOHÐΪ�¢�øÎ‚ò�t„á©)ÏÉA0´|¥!(ù’”cû¡ZäéÆåó\Yø®ª¿åÀ&Àd¢Zî€Æ/žZPR[d~3åìMNî”~f¼€b:ßþß³ñ½Ÿ³ÿ·êcßüûq0`fA\aIÈB1X¾¶1†íûíÖ1ûsÚ£+òÒ“ñHìéÝŽf[nŸŸ¡ÿÕ}RzÅ/œÄ ¿ͶÿöÇö~/¶Ø+mWkbñ/¾K÷Fál3ý¿_ß»œåY.ºjùJR¨«å+­{cû)Ì;¾4긊¾R”ˆ«å)HоR”ˆ«å)HоR³a›lêÌ¿ÿýÿ×WWØ·ËÌÝó-ÔËq/™ut¤E_+>v=]ÏøÏ–ÇžwS®®‘|¬[õflÝÖëu0†îººDU÷ämÝfž”òO~¯Ø@ì¬ÚM›mÿíìü_m°VÚ®’Š¾Ìæí—Îî§Q˜Ãñœ}])8«å)XëÙ¹Ýjlru˜¦Râ*úéXùö|ÿ±¿f~Ÿ8š¸Š¾ô£™9òÔg}÷ßós»ëè ;Ý% ¤¤3pº7 Fè -hGäÒŠQÎó'öF÷ÌëÒŽœ¤ô¼0wÀ|£Äá×.æš@ª¯ú¿�8�Ï$´b÷È%–v€2ý¤—³±A)Ùûã•yŽRI¥%$¤ô§ïÓ¿&'6è� n%£©òÈrøOßÝÂi $$þPo +•ÓÉ¥í¹nY]$Є–’”ÿ›wVºÉ Å�ܲӉ…”Wá%ÿúP0 Jq]÷û –³2J$Þ&ÿ6WWÂ‰Æ ´«ø]8¦GÛ–œ€ÞŒ‚ö/äâДì†, ·ù“Æ8J‘­i&àÜ”dZ@uŠÈNZy ¥ô1‹IIè@O)ÿ~ûí^L!¤°ÞQD<Ká¥t”~‘‰@ÒöÊWÈÜ $¤t¯|p¹c�Ç, Ier_ùɆ2P“_Ùúð×èÙªk¶XãŽsÈ-¤¸ Âåဓ’0¢a_âÑ‹OpÒXk2~ýf/ÿþûÚ1\šMGŒ~H ‹œéų ½±a»ä•ÉcЖõx˜r’SJ!ð0„dô^|¿Á ?·l”äe!›ëˆ�Á<47`Ò’ü1¶% ˜Ádì’“òs€qŸ¹ö#vݳ3Žw`©Õü`(ЖåœÎCFïÂSÉ’Ýúwï·í’§¼Þî<ÿ—¾;±¤îwËÕu›îû}Û·Ûvã•÷ï¤ä|*Ư™Û?ß²þÍ¿Ÿ°‡õt¥¬ªû7ÉÛï¾ù÷Ëßsw«¥fÙ Ûeþ¥/÷ü?¯‹”UõÒ•Ž½–½ùÝ”ÆV?˜tâ¯ÌÛ¯ÙN³9‡cxêºÍ™×ûñJVVl·ïêå|¥)8«å+7s>_=Œç«óÏÆ±õq|¥c/õ¯le9‡c×ÏæWWÊR‘|¥)WÙöJ¾Ý{­kÝ÷ëÂêéY»íþùñÝŸ íþ ÿJ*úéYœßºùÙ”ê7˜7Ž«œUò”¤E_)JDUò•ŸöÏöß›övÎ)û «ˆ«å)HоR”ˆ«åê� ÅR @ÀmŸl ®Û׸ùW—¬ÎÙþý—ömø¬ý„?²yÕþ½ &GFÉFnVJ¶~RX'”V%¡¾Ã9Y`<~¹¨0f(grß#'§!=9ôá» gûöÝÝ×p·ÉÛï¾ù÷Ëßsw«²Ü,s«÷„'ºvÿ}ßf$ѺûŒwΡ¡;od|ÿ>}·øÝ»·amØE]z¬­¶Ùm³9ÍœQì¬ÖïM_E)J⯔¥"*û7;-MÏQî£TËU]yhÅ¡(N|÷Ã÷ÍÎ]D¢¯”¥'|¬ý˜õö;ó?[qýNª}»·nøWoŸWøGŽÛ©»Ìkå/™ÌË2˜«è¥+?Èßÿ¶ÙÿêÛcª*úéJDU÷¡¿ý}ÙÌÆ³­nÎÙMª+3­ö=KwÍVeº–ª‘¿ÿm³ÿÕ¶ÆÿLU÷ì—vËíÂ{da­öf~§8Omd¥'|¥)8«ågÎoËÇ1œåîyÜÖ:®‘|¥+6c_=ç+cŽÆ±ñ|ýŒýxæ7ž¿Ž?šÇUÖo’½÷_ÊZ÷oƒº¸º¹E_+{¿;©MÎYΣË]]'|¥)WÙ»¹êìwÆn§<óòUt¤E_)JDUò•ã;0Þ{¸C³»ÌÁ;먔Uò³»vÛöVý·âûvÞ®“оR”ˆ«å)HоR”ˆ«å)HоV~ÃÏÙ[óûOçl¿WHŠ¾Í²6Ûm¶m²¶ØÍªéHоR”ˆ«å)HоV-úó6lËuºÜCfU]"*ù_ÔéÛþÇn{:¶ÿ#~ç©ÔýUíÆ¹›6 æõºSfëëçLUôR”ª*ùJR"¯”¥gìgëÇ1¼õüqüÖ:"¯®”¤E_+{¿;©MÎYΣË]6ÈÛm¶Ù¶ÊÛc6§ìÊýø¥+¯¿S÷òоºR“Š¾Ï·oöíß íóáÊÿõt¬|ÿ>}·øÝ»·amØD¢¯®”¤â¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJVwnßnÊÿ>Ü^|âDUõÖglÿ~Ëû6üV~ÂÕÒ"¯³ý›³öÂû~Øz·â5]fîgË籜õ~yøÖ>®QWÊÏÛ·íŽÌüV°_Ú®“оR”ˆ«å+3­ö=KwÍVeº–ª2ÿ~vR›³f­”©E_])IÅ_)Y³9ëîæl§8ã²tÝöÿ|øîÏ…vÿ¥}t¥'|¯݆vPHC-ÔØÃp¶¨¤¢¯”¥'}Ÿ8ó÷Wøîæñß+ÕÒ‘|¥)WÙû?eoÏìa?²ý])WٜߺùÙ”ê7˜7Ž«¥gìÊýø¥+¯¿S÷òоºR“оVw3n¼e:Ìæãªë6açþ¿ùýÍ'c¶V”UõÒ”œUò•êý÷~‡ßns·^vvoŸ>ÝGÉó›òñÌg9{žw5Ž”UõÒ”œUöo’½÷_ÊZ÷oƒº¸ººR"¯”¬ùØõw?ã>[yÝNº¸Š¾R±×òÕ·;²ÜÓ¹ËÇãO«ˆ«åcgݳíöæíÙó‹lâ*éWÙóï·ùñùŸ Ͼ ßUÒ‘|¬Ùý|ö7œ­Ž;ÇÕÖ~ÌzûùŸ­Ž8þ§T¢¯®”¤â¯”¥"*ùJÍÜyÿ/|wcIÜï—ªâ*ùY¶B¶Ù©KýÿëâêéWÊÏÆoû«:·ü;güF]ùY›¿uº™L%ûª®QWÊVnŠZ²ópå·}W8«å)HоR³ç~êÿÜÂ~;åz6Û?Û~oÙÛ8§ì&QW×JRqWÊÿ¿èûœûž½Å>Îû/îÙö>Ž•+Ý|å·Á ýO”Ï×ÙuÅ_)^3~5–¥å;;nÇìý·}¿sê'|¥)8«å)HоR”ˆ«å)HоR”ˆ«ågã7ýÕ[þ³þ#.®‘|¥+?mþß¶;3ñYþÁhоºVg7l¾wu:ŒÆŒãêâ*ùJR"¯³l…m²ÿR—ûþ×ÅÕÒ‘|¥b߯3fÌ·[­Ä6eUÄUölÆþ¾{ÎVÇcêéHоR³9¿uó³)Ôo0þoWWÊR‘|¥)WÊR‘|¥)WÊR‘|¬ÿ!ì½–¥þÛõauuŸ³¾Ç~gëcŽ?©Õ(«ë¥gÎËù¸¥««¾SwÔûvÿnÝð®ß>¯ðW×JÍòW¾ëùK^íðwWW8«ìÛgûlýø¾Û?­°Lë}RÝócÕ™n¥ªŸ¶ÿoÛ™ø¬ÿ`¿µ\¢¯³fÛûcû?Ûl¶«¥'}éF/t'>áÇ/}ò÷Ý{åî½QJJ*ùJRqWÊÍ›mÿíìü_m°VÚ®‘|¬lû¶}¾ÜÝ»>qmœE3›÷_;2FóæñÕrоR”œUò•™Öÿ¥3fǯºÝjU\E_+ýY›7uºÝL!»®®³wËߨÒw;åéE^éÝ,¶Ï¿=û/m÷̶w}óï—QJDUö|ûíþ|~gÂóï‚÷Õt¤â¯•Ÿ;/æâ–®®ø=MßUÒ"¯•ùwe­} ïöýû;(åaÒ}“¾û}ó}×¾æ}W(€����H����z¿óýgìǯ±ß™úØãê2®‘|¥)WÊR‘|¥fû¾ßvíÅvݸå}Ãêâ*û;©¾=jwÍÎ^e²×WX·êÌÙ»­Öêa ÝurоÏÙ•ûñJW_~§ë«¥'}›¹Ÿ/žÆsÕùçãGÕÒ‘|¥)WÊÍ™×ûñJVVl·ë£¯fçu©±Ê=Öb™K«”Uò”¤â¯”¥"*ùJV2ÿZöÇöS˜v=|þiÑ|uìÜîµ69GºÌS)uu›¸óþ^øîÆ“¹ÜýOœß—Žc9ËÜó¹£¥}t¥'}›Ûç^uï¸~íðŽº~3ÝYÕ¿áÛ?â2éþÍ¿Ùûa}¿l=[ðê¹E_)JN*û;·m¿eoÛ~/·a-êéHоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«åc/÷çe)±ë9ÖjÙJ«¤E_)Y³:ÿ~)JÊ̓Öýuq}ŸìÛýŸ¶ÛöÃÕ¿«¥"*ùJR"¯±—ºÕ¾?²ØÃ¹Êçã§ù ÿeìµ/öØ?«UÖlÎzûŸù›)Î8ì£e}t¥gìgëÇ1¼õüqüÑÓŠ¾2ÿ~vR›³f­”ªºR"¯”¥"*ùJR"¯”¥"*û7É^û¯å-{·ÁÝ^®”ˆ«åfîêù¸¥«/7[uUÖ³oö~Ø_oÛVü:QW×JÆÏ»gÛíÍÛ³çÙÄUÎ*ùJR"¯”¥"*ù^”ä3óþØßÿ²ÅñÛÕª)(«å)IÅ_)JDUò”¤E_)JDUò”¬îfÝxþÊu™Ì;*"¯®•Ÿ>ûŸ™ð¼ûà½õ\E_)Jüò>ï’wËÝNïŸ3Õ(«Óý›³öÂû~Øz·áÕvàÒj3¤í’žrŒý,ïöVVýþ· 7`Ô†‹Ëÿ|œRöOrÖÿéZ—¾ë>ÉŸ<êþ/H|Løj>BpÔ%ÐŒÛ8N/•Êî¼ÏѿߵÍÄÜ’ÆlžßïÙ[ã÷¾1”“º?Ð0\Uøvg_ïÅ)YY°zß®›dm¶ÛlÛem±›W 5»:¶ý÷Ìùöï³v_G^ß>]’ÒU|¥)TUò”¤E_)JDUò”¬îݶý•¿mø¾Ý„·ˆ«ë¥c/u«|e±‡s•ÏÆFÏ»gÛíÍÛ³çÙÄJ*úë7·Î¼ëßpýÛáutœUò½±{ @îÉnß/þ}Ç~³ª)(«å)XËÝùÝJnrÎu¶Zç}uŒ¿ß”¦Ç¬çY«e*®³üÿûmŸþ­¶7ùE_])IÅ_)kØ ÆÙ°ÞËëOÈ7õ§ŒÇ÷í¬’Š¾R”œUò”¬ÝÝ_7µeæáËn¨Š¾ºVlοߊR²³`õ¿]\E_+7s>_=Œç«óÏÆ«¤E_)KՀĆXÙ*nZ6Û'¥/»”Ù tör»£?Û«.Ëg_„4 †9§ñ›t£giV~Ù;–¾ÈnË]틤"J&nžü¤§ò²2#†ò¹e}ÑòÓöèn”æÖ‚È`P<²i|Rq5<¡¸ ÒSô !§+§f9YßÝPÒ44 SMIi)¬û²w-8–_J7ùOÉNdg¼_áN-Äavµ45 çO/òÃ0nÎ+$¤nC K ˜²’7ñ¡ ] j „01%�Ü¢Ó¾/–YhÅ¡;†ï¹/¥ œKé lY+?}Úò᜚y(a(4²_΄âŠdá»nŽOÙ;ºsô¾|þÐKAx²Wü™ƒ²Y¥$%GB;!²Zz­Ù3Så,áa縀9*¿w&K (7†Ø á¼7'n~H)-)JF6ûõfÞ¼˜‡û“He†}Æ”4i\ b¿NÀe)J‹ý%䤽ñH|1¬™ÀÏø À£ ÈäÒah/ñ›¶B Éãy,”^_ýv°3Ë!§£•ÐÒt�XZFàÆ«#–ÄœŒ4£Q»Ëü3fsÔsr*›iÕøY)(‡¸bq%!‰N!$–ÃtýÐÛ?ù¾JÜ'Þ$0¼”ÿ:Q’¦Z³ý²S™xïòòý…'¿Ô!4°ßÔž40¾Jn’‘ñ_ý²>NKÿ“k!Qi%¡�a(ÉÉÁ¥§”’²~Ieð—HacPZFta™·ÚÝ"Œc0öfaæ*¿æ |¬ÍߺÝL¦ýÕOÙ•ûñJW_~§ëº%$´§î˜fïñ)Æøga©_ÛÈ׽ʽ…YÕò•™Öû¥»æÇ«2ÝK«´•_)JDUò•›lÿmŸ¿ÛgãÕ¶«ˆ«å)HоR”ˆ«ìý˜õö;ó?[qýFUÒ‘}Ÿ°óöVüþÆùØÿWJDUò³:ßcÔ·|Øõf[©utˆ«å+6c_=ç+cŽÆ«ˆ«å)HоR”ˆ«å+>ÉWÛ¯u­{¾áÝz®"¯”¥"*ùJÏŸ}¿ÏÌø^}ð^ú®"¯ÖËÅ~VÝ;>ܰwÌçnv=½önÁ¡¤ÞVÄÔ³ ´ š„þùÃ?Ì•>GbSq¿kç`!!¤˜L/”ý%#­’ØnRP7vNwøí¿w××€ a-?§%8¯€Â0ÌRQò‹Z é+îZ>Ù·NϯžC)ûa,¶=ZÖ¯òdÒ°J¤1X  ¤äŒ, Äò‰@Y å`’RPZrKÛ>¸Å”¸k”1(bYKÃ3äddº:8ÆFž´“îÊI©JKá¡i[‰¨@kåt’Ûº •òRZJuz´%(B3bˆa¨ßÃ� Ñ¿äÂTR{ÿÈéÏ›²,²|·ÏŸ°ñäùÕèM,03“SðaŒá€6 ̲€Ãº¡¶ìÛ–‘µÖ(øšZ�lPÔâbq041Ò„ Bgßì²¶û|ÿBzôâbR…pþè+† ¢ÆäHÔ—Y@7OܤR9¸fJmÅ ¢Z Oã )þÉÅ &°j bfù!R’“Æ'£›®Eæùlµïñœå‹6ª¿/,4šJä¡…bú [õf/6à:JvÈ);”7¸Î4bZÖQEmƒ6O+úË dä–POåòjJß”éFÈýýÑ@ÂdÆÅð(WéNAi˜´ï–‚Zò^N):0[ÊJZQ·Å–”æÄÄòòJ&n“‹å¤ äìÉhZxÞI÷1ùÖ±x~=M˜×<têÿ BÞ &$¾J°Ô$5a¨ÈéGHnI/''ÙƒvêýæGHb@,+gIN17?fÅº Gز††dg쫵‰DÔ† 1›Ð‚Ê!#RQÛ‰ã6_ý?£¶¿öâih @hÙJÁ¡¤ÒË@DrЂg,·Àe;–ϺŸ[³}ûàìgW3åÒ«þ`©%ñ¿!±„´î‚Ë%íÃye¡ %}²@¶ëßÿï Qd±§$a®­ßf~ù¾ë¾‚Q4¼Bä2‘°ÒÿãW)ñ‰v!•‹ù%?&þr_6v¼%å¶~3ð.Ÿ·9;:¶Ï›a¼ý¾‡ã· #ÙUøk>íŸo·7nÏœ[gWKÒ¢¯”¥"*ùY¶ÏöÙûñ}¶~=[`êºDUò”¤E_+ûÿ¶|hÜ0Ï•ÝøH¬s¯v¨¤¢¯³9»eó»©Ôf0ü`º~Ûý¿lvgâ³ý‚þÕtˆ«å)IÅ_)JDUò”¤E_)Jφﻯ2¿Ü;æøN\E_])HоR³l…m²ÿR—ûþ×êâ*ùJR"¯•›d+m—ú”¿ßðþ¿WHŠ¿×€„´r7'äbRvý=û”ŸÑÙл¨k¾¿g½ÑHÈ&“ (…¿JKÜ¢ùi`߯’ùa«+’‘‹~‹ûæÝÕx lWÀ_³üÒ„6å£ìXÔbß¾Vv÷¾ÑeàU!¥€Ô„ ±„?û§ÑÿZÔP×,fIl×Îâ3ÊÔ<ãĵµ_ˆ ‹A}= ¶OK% A[òWJ />á½@g³nýî‘447†�T‡ FB9eÿÑÉ[â_/–™þ-®”$üþí „”p0±_C”–00a[¡%¡¹c: „¿ÖÎÛ=ƒöÀW$¬·BPJtòY\¤”¸aH(¦t''nPÅïûÜØü¾áKw}™úì©Õý`Ò`qÈHf£RC[óìKú¾È&gÛg}Ha4˜YElŒ1aŒ‚ÒYi û>(0¼QüŸºQŠJün‰xšgÄ$bZ ù?á»#}¸‰K 3l”°Ð1Â:RÛë³Ö^Hj ãÑÐJf&bWIHÜ'lV-±…vJ2q/××¾eÿÏâDúªü 0 å $Ì_O!âbIA¨Ç ·Èd7- Oÿ·tgº¿9+òÒQ\­Ò“™ YÐ7¡±h)#P”-)îë¶þ„pÒ`ÝÊ/$®¬Œ¢º²Jé/£žQ/Œ}÷N_пËåíƒ;àÂK A ¼ù7%ý’ûn—×#ÿ¹¼q£ßqMU_æ@nY 0­’Y4¿² 7•‹€rnJRSØ ~žœÛwÿ5ä÷!䆠´Ÿ’QC #ô!ÐZI 6bYx”Œÿ'§îòÜN’ŽR~ÙòY=‰\445ÊN’†GJS·>ù˜f,”^,k|K/:_m¿Ü™þ)ÑÓ²yy;;Ôûgù–[Û¬ê*øB&XÀÜÙ(ÃVW7âXi@gõôß?û%Ú⣥oðÍ’¿ò:×’”n[·ß¿ø#Œ_ô ÄÑœ¿·g ÌýþvGÉÛdu/%ñ®»Xn&¾ãP„ ÿ£¥Ÿ«“‘¾ÉëJ“Ü#>¾ƒü²pvcWðöm·ÿ¶?³ñ}¶Á[jº÷Û·KþÿnÊÙ·enÎ{ºøŠ‹ºš¾V|æü¼sÎ^çÍWIÅ_)JDUò”¤E_)JÏÙ_c¿3õ±ÇÔdE_])XëÙkßÙLiØõcù‡DUõÒ•›¹Ÿ/žÆsÕùçãGÄUõÒ•Ž¿›–¦ç¨÷Qªeª"¯®³ý›³öÂû~Øz·áÕtˆ«å)HоV}»·nøWoŸWø>®‘}Œ½Ö­ñý–ÆÎW?}])WÙ³?õÿÏîi;ŽÔû%_n½Öµîû‡uêºüº•–­³ûÿÔîîjß½/}Œ¿Ö½±ý”æ_?šu]*Š¿²7°Ü„a¹»ä¡ßŒ“‘Ï%}‘Æìv{ìÉ ÞOàP¢° K-)Ɇo‹éI5ЂQ}ó²?Áƒ?ì×Ë+—ÐÛ}þdwo¾?+ï²Ç9­õôÒh’ɹɨN“Šÿ„ ­úrKÜ'î•£íðÑ·…¾9}°±Â‡ µ«÷ñ šœÉ&ìŒ3'8gäÖ,1aEtoп O_èo6´“�¡|˜ŽX´•’Vè!JBKN+£ŒF@iÙÙEb[iña¤Î€C á½%¥%†’Ê@n’”t±-?þ‡íÊNÏ™­ÀÉ4n,¬MbŠ@iÅY) ~†7ë&~„–ø!¯%™vXýð_?cØ~®¯bÉ›$ Œ!6&¤aHAE—_BØ´r² Ä¿† ükkÓp-ÒŽ”$ – Hj7N #Kt ¤ ¾ŒœR‚öA{¡ÈepφâÃI©ý/Ó¶(ÏÝ9ÌÅ¡Òå|Ý t>²†'†ÀB -ОèÈBq-%bÓ¶ÝhOÜ1éÇ£b®wÌc[£ùÜÚªþñNZHlPa+ò€ÇBR£>IIÉéJ2vø'¯öÊßëAD΂ƒC3^ÑÃQŠ%­} BQß~Ên×;K�³ ˜XÒoB a‰(jS÷)˜ %¶A]ÙѾÙÞç‚hجÙxgÉåa»„9(37Gé FÁ˜ ÷sýÌaîr„…N¯ò€pÀ2YD¢Òœ¿å§îŸú{—º¸iJt'òBRV}Þù±XŒ‚oåôô¥òr¸k ¥t:~èeu=í‰E–€ÂaEŽVåpСƒ‚¿�ŸrI%Ø´|—ùÑï˜!%'§¡9-ÆvKíÐc;nµšsßP•-G=ÇØÕ÷íŠNÌYÍ¿JSŽ5ÓÙ²2Ó¶~®ÿÙ»6ýu33¯»v|Ùßs—kB†Æ a›¾ÿ„n•Œ(ÿ¿ûfû;c´ü–”†$¥#¬±½;ŒÆlWÊã~ÿ„u7{Ô3€¾Î¯Âƒ²ÿe:sò¿fÙb³sòª)KyUò”¤â¯”¥"*ùJÏò7ÿí¶ú¶Øßêâ*ùJžVfïÝn¦S ~꫈«å)HоR”ˆ«å)Y¾Nß}÷Ͼ^û›¼E_])YoñêS6lzû­Ö¨Š¾-úó6lËuºÜCfU])WÊR‘|¥)WÊR‘|¬|ÿ>}·øÝ»·amØE]"*û?fWïÅ)]}ørŸ®è¤˜ééG72VZ×–Z6HÍöK Ê[f¹U›3ž¾çþfÊsŽ;(Û7_÷ò ¾À]$"pÔ%.—%†þß§§%!…£0Ôòþ^ù²­ÃC13$3–ú~ ýˆKålŸ¸ÂÂ7 È‹É ø´ãýñ’i1 B@°èúSËBF•·GG(¯Îÿ€£0×Û?÷¬I0¤PKG(´€Ç%ðÄà05 )NÛ¾G d%‘³ïö×Ëdñ*s>=Íeж«ý^& dÏð+ ˜KÐMÛüÊåô–ŒJJyy%öNÁoêpל5 ˆ’ÊùüÃK d–Ý$ÞY3•úYÆÿµæ€©0¼rbJ,¬SìÅ“ l‚¿J x¢Rdñãv¹£�l‡A\45âihéýÔäwB9Iwåô© „t¶_Þ7ÙÂØÃ0…¼UþزgA7 š´†£;a‰Å%!©J:‰‰~‘©-‘‚R1(ã·¶% 0„´�ߢÐXGÚJ“ÖãJ%þŠûô#žæ\°Ä�Ä”ƒ%–_,–V|€þR#8Gå ®¶w¬&Ná›~åýþA1ß±_’ÒÒ¸k0Ä£âðÔî_¹—±ÌpîÊuPýU_Æ�ȆMî„’‘ÒpiLå3’·GÉ”ôdF%ð„|×€† LéHݾHJÜ%i/~¼¯þ@¬…kºÅ ¤òº”£Ø »¡'tÉB!¨-ø`‡¼†+²V1%¯ŒÆq›+ôa¬ÊéÜ)W¼“ÄÕ˜{*¿­‰¥røå•ÓË%w%A`eÈ|­ó2½çþv=]ÏøÏ–ÇžwQ¶âÃÿOF-òß#¨'~¶ç'¾~§l¾÷6ô\:оR”·•_)JDUò±×òÕ·;²ÜÓ¹ËÇãO«¤E_+6ÈÛm¶Ù¶ÊÛc6«¤E_)XËÝjßÙlaÜåsñ‡ÕÄUò”¤E_)JDUöm‘¶Ûm³m•¶ÆmWJDUò”¤E_c/u«|e±‡s•ÏÆWYó?uŽîa?ÎõrоR”œUò”¤E_)JDUò”¤E_)Yû?eoÏìa?ôùÍùxæ3œ½Ï;š:QWÏWsþ3å±çÔlé)æJ2rÕöçï¹ã÷øG“»vÛöVý·âûvÞ™Öû¥»æÇ«2ÝK”Uþ¬š�Ô£’ƒ{³ ,jC·ßdîž•äd'¿ßtñŽŸ_ÐXJ3d£Ɔ @@jBBPZ3§ZY¿È+?ç^Cõí¾ß­ºßo†¶}Íg3ý'ÎÇ«¹ÿòØóÎê6äß•U_ôÀ4GrWËOM%¡(ÏÑÑÒ”õ¥ÆüŽœì2æ¤%¬QAˆÉAc”ÅéãyIBÆ èÛüŽsí¯#°Í¶uf_ÿ‡þÿ‰ë(¾~hí÷ÇqÁÝ÷;ï©%ýÝÜ;�ú*ýÄ"„ gÉFÌÕþ+ìÈnVnnÙß®ÃÝ=úÙ_¾ßΧÇ)Ùÿ¨¥×üªùJV~Æ~¼sÏ_ÇÍi*¾ºÏömþÏÛ íûaê߇UÖnæ|¾{ÏWçŸ(«ë¥)8«ìÙ¿¥efÁë~ººR"¯±³îÙöûsvìùŶqt¤E_)JDUö‘¿ÿm³ÿÕ¶ÆÿWJDUö-òó7|Ëu2ÜKæ]{-{ó»);¬0êºJ*ùJRqWÊV-ú³6nëuº˜Cw\ù-ߺÖíÛ)JnÊ=Í”UôR•ÌÛ¯ÙN³9‡cEN*úéJÍÜÏ—Ïc9êüóñ£â*úéYþÍ¿Ùûa}¿l=[ðê6Û?Û~oÙÛ8§ì&QW×JRqWÊV~̯ߊRºûðå?]7Ýöû·n+¶íÇ+î(«ë¥)8«å)HоV|ûíþ|~gÂóï‚÷Ôû'}öûæû¯}Ìú®QWØËÝjßÙlaÜåsñ‡ÕÖg[ìz–Ëu.›¾ßïŸÙð®ßà¯ôE_])IÅ_)JÏÙ_c¿3õ±ÇÔdE_])HоR”ˆ«å)HоR•›ä¯}×ò–½Ûàî¯W×JR"¯³;gÛv^Ýöâ»gÚ®”ˆ«å)HоR”ˆ«ìÿ#þÛgÿ«mþ®”ˆ«å)HоR³}ßo»vâ»nÜr¾áôý™_¿¥u÷áÊ~¹E_])IÅ_)JDUò”¤E_)JDUò”¤E_)JÇ_ÍÎËSsÔ{¨Õ2ÕW×Y³?õÿÏîi;ŽÕtˆ«åfÌ篹ÿ™²œãŽÊ6®‘}›3ž¾çþfÊsŽ;(ÚºR"¯”¥"*û{¿;©MÎYΣË]]gÙ*ûuwÜ;¯UÊ*û3›¶_;ºFcÆ £¯å«nwe¹§s—ÆŸWHоR”œUöwSlzÖÍ›œ®ëe*®”ˆ«å)HоVw3n¼e:ÌæWHоVm‘¶Ûm³m•¶ÆmWXùö|ÿ±¿f~Ÿ8™E_]+7s>_=Œç«óÏÆ«œUò”¤E_+;·m¿eoÛ~/·a-êéWÊR‘}ŸgÏ÷ûögì)󉫥"*ùJR"¯”¥"*û¿;)MYγVÊU])WÊÇ_ÍÎËSsÔ{¨Õ2ÕWY¶ÏöÙûñ}¶~=[`éE_]+6ÈVÛ/õ)¿áý~®qWÞ„d++m¶FÛ#0æÎ(öVi?íŸí¿7ìíœSöWIE_)JN*ùJR"¯”¥b߯3fÌ·[­Ä6eDUõÒ³á»îë̯÷ù¾—WWÊR‘|¬û%_n½Öµîû‡uêºDUò”¯ß©Ð¿Ÿ·}º”ý¿ØÅ´¢¯¢”¤â¯”¥"*û3¶¿eý›~+?aêë{­[ãû-Œ;œ®~0ú¹E_)JN*ùJVw3n¼e:ÌæW×JR"¯”¥cgý³ý·æý³Š~Âb*úéJDUò”¤E_+ùy›¾eº™n%ó.®‘}›¸óþ^øîÆ“¹ÜýWJDUò”¤E_)JDUò”¤E_)JDUò”¬[åænù–êe¸—Ì¸Š¾o“·ß}óï—¾æïOœß—Žc9ËÜ󹣪é(«ìÝÝ_7µeæáËnªºRqWÊR‘|¥)WÊVnŠZ²ópå·U;™·^?²fsÆŠ”UõÒ”œUö}»·nøWoŸWø>®±o×™³f[­Öâ2ªå|¬Ùœõ÷?ó6SœqÙFÓf7õóØÞr¶8ìhú¸Š¾Îæm×ì§YœÃ±¢©öíþÝ»á]¾|9_àúºDUò•Ÿ±Ÿ¯Æó×ñÇóGQ—»óº”Üåœê1lµÄUó»vÛöVý·âûvÞŒ¿Ö½±ý”æ_?šu]"*ùJV2÷Z·Çö[w9\üaóнנŸ²†ö~Æý›9­ƒª)IE_gÎÇ«¹ÿòØóÎê6®•‹|¼Íß2ÝL·ù—W×JRqWÊR‘|¬|ÿ>}·øÝ»·amØE7}¿ß>;³á]¿Á_ê¹E_)JN*û3›÷_;2Fó披¥"*ùJR"¯•™Û>Û²öï·Û8–Õtˆ«å)HоR³;gûö_Ù·â³öþ®"¯±o•™»÷[©”Â_ºªéY»¹êìwÆn§<óòŒ”UõÒ³ñ›þêέÿÙÿ—W8«åc¯fçu©±Ê=Öb™K«¬Û![l¿Ô¥þÿ‡õùE_])Y³9ëîæl§8㲜UómŸí³÷âûlüz¶ÁÕt¤E_)Y³?õÿÏîi;ŽÕq����ˆ����z¿óýc/wçu)¹Ë9ÔbÙk«¤E_)JDUò”¤E_)JDUö‘¿ÿm³ÿÕ¶ÆÿWXËýùÙJlzÎuš¶R¨ùö|ÿ±¿f~Ÿ8™E_])IÅ_)JDUò”¤E_)JDUò”¤E_+Æ;oŸ}˜æoÿ“Ÿu2‡TRQWÊR“оR”ˆ«åfvÏ÷쿳oÅgì!ý]"*ùJWà†Fßæ?÷9•ÿããÖw(«è¥)8«åfîêù¸¥«/7[wÕtˆ«å)HоÏWsþ3å±çÔë§û6ÿgí…öý°õoÄjºJ*ùJVlÛoÿlgâûm‚¶Óо2ÿ~vR›³f­”ªºR"¯³|¾ûïŸ|½÷7z:öZ÷çvSv=XþaÕu‹|¼Íß2ÝL·ù—(«ë¬ÿ#þÛgÿ«mþ®“оR”ˆ«å)HоR³»vÛöVý·âûvÞŸ±Ÿ¯Æó×ñÇóXéE_])IÅ_)X·êÌÙ»­Öêa ÝtuìµïÎì¦4ìz±üÃ¥}t¥'|¥+7É^û¯å-{·ÁÝ\\E_])HоVw3ì¼~u:ÍÆÌãéóï·ùñùŸ Ͼ ßUÊ*ùJÏÙ•ûñJW_~§ïêç|¥)WÊR‘|¥)WÊÆÏûgûoÍû;gý„ÕÒ"¯”¥"*ùJR"¯”¥"*ùJR"¯³»vûvWùöâóçúŸ;®çügËcÏ;©×WIE_cçÙóýþÆý™û |âiû1ëìwæ~¶8ãúUtˆ«åfͶÿöÇö~/¶Ø+mNêoZós—™lµª®"¯”¥'|¥+?Ù·û?l/·í‡«~#DUófuþüR••›e·ïêî–&­8bY¿ÃßÈOKô2vwƪ³“z8I]n)ô/þήÙ3üŸÔÎÏfÓ«ù5Ÿ³+÷â”®¾ü9OßÏ’ŽËZsíÕÙNÛ©ó¾S®¢¹Uò”¤â¯³}ßo»vâ»nÜr¾â=])WÊR‘|¥fu¾Ç©nù±êÌ·RÕWWØ·êÌÙ»­Öêa Ýut¤E_c/u«|e±‡s•ÏÆNíÛíÙ_çÛ‹ÏœCêºJ*ùJRqWÊR‘|¥)WÊR‘|¥)WÊÍÜyÿ/|wcIÜï—ªéWÊR±óüùößãvîÝ…·a}t¥gÎËù¸¥««¾SwÑ}t¥"*ùJV¿ö^ËRÿmƒú°¸Š¾»¤~3#ÿ¿éã]•ŠFG%þ;}Ç=Ý!’Ë(†” É@ax¡›¿à_6ü3%ÿÈHBzöe/ßI¥ò ±I/—°o)RR”'ôä•Ã>ÛðÒ‘‹q/ƽæ#0³ˆ•Õþ`1G w ÎŽ8iY0¢÷Àc–_J Å1¿rG·àÐ RrfB1iB |RS²rÉcJ@H`hÔ>ìÏò®‘,¤† 32ƒ°ã?cö&#¡ƒR”rÊý(O„ääúÂQ –KB/tàÞ„¾é哊ݦ-!¿Æ²Jý-»Ü;|®áÍÍY㙞ª¿ÀCÉœ¤y+¥¤¼¥ðÂöAç(±¬„ﲊ+>tª­�;!†¹45¾ÉJ ßæ ~…ðÔ²3ää~R÷Cóg&†7’ÑLåþž‚oÈÉN�£8Ä aClà]‚ ºe“ HjJ’è&d+§ •ŠdrÐÈÁ'ÿÓ€ó€ßZ s±áÄQú*þ* ))(1$-º�ÇÃyH Ø¢ùHKl„�䑊OGGç>G¼xae|¿YY;~7ôÿ'å?ÉçïúõõRÒ‚`( 5$Ä#†|Žž3}‹Å„%dö-%q‰ß§¥ŸU†�ì†Q/ÊIIJ8a ¼Wø7ÐèI[6GI)¤cÕò¿n,([ùUÿ [õælÙ–ëu¸†ÌªlÎzûŸù›)Î8ì§]ï@¢z: ë@è `ߺ6JQ’VB> _úÅïÙ^ñ¡…òÑݲwù;Ûá}ëÍÎÏ»ç˽.J*ü‹|¬ÍߺÝL¦ýÕG^ÍÎëSc”{¬Å2—WtJ¯”¥fÙ Ûeþ¥/÷ü?¯‹œUõÒ”ˆ«å+>¾î¼Êÿpï›á9uq|¥)WÊÌëR™³c×Ýnµ*®³wÛýóã»>Ûüþ”UõÒ•ì7ì{±ù]Ñײո®wˆ«è¬îݾݕþ}¸¼ùÄ>«¤â¯”¥"*ùJV‘¿ÿm³ÿÕ¶ÆÿW×JVnû¾|wg»‚¿Ñ}t¬eþµíì§0ìzùüÓªâ*û;©¶=kfÍÎWu²”ªºR"¯½±Hd!HÊB•³ý°ì½ª)IE_fu¿Ç©LÙ±ëî·Z•>l”庿q¬µ+õ½„üº‹è@!N@fè+ì„àÄL)—·t'/`ñCO¡‡{ :¿¤MÅñxjÀapü‘›€Ý((—Ò’¸bPÜhÔ†!yžöÙ0�¡%£ÿñ,”ÛbRPB,R2rFòhщKm¾ìõ}�:Ü–Œ”à ä´·,j>`Ô ÙP„q‹/ý€bg&¥)(HÑ„ÒbPìÙI( ÄྠA)] 2ù¬7«·ÂE­—Àµ_ÆC€Ã÷ %l„ŸðÌìÒ¾ü!=8g%õ2:zKEë°hhHhéÈ+•ЂÉe <aHWJ~^Ì„†Œ„7:bbPœ‚iA„݃0`ÒúCÅü” ¤·& -Cz’•5ÁÉ @ÒBùº &PÄ#$§I(´’²7# ø¢¸û%ò­>P¾înÑWôÃHhå 7Y7|XÂPÂÑ‹r“›a„4€¾èGå•í—aJ@¡e†äËüg B,­Ò”%%¬bSÿF)çâŠù’¿uÉ¡©@j900­¾Ü0Á… &ô„öB1i+·åà27l3ŒÉÏtÃH{–Xg+t£¤iiHhBXjXßÜ®ÄκI¥#å=;6=Ôa¬ óâ¯Ä’”‚²’”`°¤²gr“ò>Éß%§B7GGlwˆ]=Èb¿Øae¥ üš59ã:~û7ó§Ýpt²wAÝŒéOrƒP0¶Å:6Ndô2μÁ1%J Å ¤î Á¬œVBqJäÒÆËÁ‰NÝÒ1»Ü_gZÉÀ,vU_çʽ W¤5Ã? /¤˜’Q0±ˆÈ~”æAa£Pz3«'_3¡¡¥!‹ /ÿÝ*/mŠÙ`cddòþü¡½_ŒOÇ_I+¹YÀÜ^(3dòDÄä ¢Ÿ š÷I!(a„„§„ì× Âg% ¡ŸÃPŒ’Xb~HÄÈn“—ÊÈn—½4«w9mœ_#¢¯ù;¯e¯~we1§cÕæWo@néèìùÎNæŽR_nŽ—Í†æþÁ}XÕö2÷~wR›œ³F-–ººR¨«ìû%_n½Öµîû‡uáut¤E_)JDUò”¤E_)JDUö|æü¼sÎ^çÍcªéYþBÿÙ{-Ký¶êÂå}u޽–½ùÝ”ÆV?˜u]'|¥)WÊR‘|¥)WÊR‘|¥)WٰͶuf_ÿ‡þÿ‰ë«¥gÙ*ûuwÜ;¯ ”Uño•™»÷[©”Â_º¯¨\€ÐÒДîW@nÙ)Èý;bXÄôt`²QÓÅ“Œÿw¾W}œºK HiX ÂjPŒá¸4–’Ý?¨'–R LÅíß^r9j ×Wï(šKbi|²¹eþQ3å¥ý‹%~ÿŒ&8foº;÷º¤Òi4®‚^ %lÛ’É¥d~—d�࿃ g(1fÙ FúÈžX‰‰(¤ŒÈß$˜Ÿ¸nŽ’j3`0RQÒJ%„ôôö¶¤š+§†¥),0”^n43†t£‡Ã mù##à³ÿx;!Àˆ[ò>֯р©DÀÒ¸ae”’‘°ÂËã7Å 7rb8GFÝ?²VÊtŠ&“2Ä”LJ B9cPjJ²wí€oëß•’éù?f]Ê, (PidÄ! /ÑŠB_éÒ” ±‰ãP„ŒA}F†ŒÊ÷¡/¤ ”€-Ãxhi\¾^Føg”%°k§ä§£|¾íì›§9œÖ#xéÕ䆲o@@jz3ðÏÆ!$®ZÿÈé/—éBRzòì` &£õ†�-à[ôbà /²ûuÙÊØ²Gm·½RIy éÅô§ýËÜ!.œÎ[¥ïÊ-›eçÙµäÉ¥·%¤´0i3–QX¡¨Ï™² ÿ²?:~Ù=‘%Y¸ ꊿx<±˜3’ƒ3–Œ5%nŒ”î„“R€„£§!? Ndã5ÆIE%;”Ya‰<5$°.PÂVÁ‰ 匀ބ÷ÈÌý¶UX Z0a/tƒ2pa7§ô() &á¿üJÊÅ¡ Gûµòd€Áщ�³äÜXhÄô'¥²†ï†vÝ‹GßtçìývïðîùJÌ"š¿Ô€é™Æ`Ôo°ÒÒPÇ)ò ©-9ЮQ(­Ô‘¨Þàð$šJ ,7îÅÑË%–3!-ä£â_PÔ#€”$ µ@nI–€2±c>mËO&pŒ¢’ŽÄî”±+þΤêpÎ1Ê äÄäbœ0¤bòrIy7•ƒ:I,”î5“ðÏïAÄš Œ~¦¯Èd ÒÑ·/äIhI,°ÐYÌ9 •™‘xÍòvûï¾}ò÷ÜÝîè >ÁˆÅmÊ”1$½ŠGû~žžû²¶$>C)îî<ÿ—¾;±¤îwËרœn¢¯®”¥ÕM_)XËýùÙJlzÎuš¶Rªâ*ùJR"¯•‹~¬Í›ºÝn¦Ý×WHоR”ˆ«å)HоR±×²×¿;²˜Ó±êÇ󫈫å+?Ù·û?l/·í‡«~#O÷Ù= ýmÓÙÙ¶4fQ˜[<¢¯F^ëVøþËcç+ŸŒ>›dm¶ÛlÛem±›UÒ"¯”¥'}Ÿä/ý—²Ô¿Û`þ¬.®”ˆ«å)HоÆ_ïÎÊScÖs¬Õ²•WJDUòúH,JØš‚)d’’¶Î^F/©Ð1;²_ä—Ñ•|ëçeüÜRÕÕß©»ë²B0ߨ­¸ß G+oûî“™÷ºèwÛë‘�Šªÿ³—ÈH&ƒJ@ÎJá KoËBJ!®á‰+ ´vGå§ ’»Z@ a4¾Q0™°gIx¬’jPË+a¨)¤”ã3’Ž?çÛ^}–¬„tðÂÉ¡ d5ˆd4rðfÈB6%¥É] Q[vÛöÏr\†Ü´�Ä5> È�±= ñ)“·ýöNèÙkçÇœê1C–¡jkZ¿Ö£Z?,aDÌèÅ!Ù%iH䲘šÆ gC(ý“ªƒ ,š…%)&†•Ê)a©�¥._ÅüVè(°,º]}9:pÒŠr ‰¨pÍðؾŒ°K€Ô¸hÙ†$“²É_Ýnà_†lVÅ’’o&—Ãÿ/†íºP”~ŒéGŽïgœw9Àâ‰ó«ý‰`(-$£Á ÜÅí“‹-€çá­Û²1ž=�c†'² ù<˜XNN û%?»t¡?lPÝÑyPÔà+òVúCCS“‹èø5®Åâb8Æn§êí«MH‰Å—úPPj2„ Ae¥#rCCC(~3'¥-ðÝÛ\ÙLrǨ㕸ùÕþ0¤BÃJ HÒnI{Ê)1=¶(›‰E# φ›£bþ^¹¸5ƒC@--BQƤ±©èAx­ŠFIX ÌŽ”bÉ{¥*JQ·×°ÐÄÁ®ƒ2ÑúKC8ÌÙ ¸–…’ŠIH%d¥kËp & È,5)Á¹# `7ù߆4 rZ7PÜŒÉÍõê$ŒÂñôUüRHHÄ®‡(b: hFÈpÌŒvû²KÉNKýþAÖOƒFÿÓöÝÆ#ô¤¤`Þ—û'òñ7#í¶r°FGÏwY<š['n†ãJ%pžŸÒB傃F`1Ë))Éý)[kŒI„À×(´ôZ Fn”€å<bz·}†²lŽ–î½ØÎ@¦¯ó[:~åqŸtü”}°CöÊÉCÿíϹµŸ8ó÷Wøîæñß+ÕÞ½_)Y»íþùñÝŸ íþ ÿUÕ|¬ÎÙþý—ömø¬ý„?£/÷çe)±ë9ÖjÙJ¿JÎÍ÷Éëëß}›3ÿ¬ÌÚ˜«Ó;gûö_Ù·â³öþÛ·Û²¿Ï·Ÿ8‡Ôß%{î¿”µîßuqusоR”œUò”¤E_c¯å«nwe¹§s—ÆŸWYó›òñÌg9{žw5Ž£çÙóýþÆý™û |âe}t¥'|¥)WÊR‘|¥)WÊR‘}ŸgÏ÷ûögì)󉫥"*ùYûúñÌo=5Ž«¤E_)JDUÿg؉„Òjz &ôò^­ºrSÂJAINÛgà]!(èýhM¸3ÃIh, léÿ€Çe§“IdÏøbzR^(`A,%|dšŒXahûü”'|†~ûå:œsªúâ@tRv%à Bv Nᘙ² týè,´ü‘Û/¨´kÀvf<Ź9íjþ¨,5!…|KN)Ð1ÒœL( ¡Ž– OŠVJ Yöéý?ÛÒ¿åä2s»”[ šœŽV ±-²óïÊrýç€LÈH@ßÿJÐ’RY<”JA3à,WXÒŠI_n„ïöGö Ô´n1Ð_Á¿–”z´d§Œ è,§`2Y7 ¬Ý»½ÃöÜ)Cƒ»÷ª¯è€Ç#$®É€Œ%ŒÅp3’’ºC6ÑÃ8C~‚Z‘BgA´‰œÄò‘Ɔ”Z2 è~K)ºKrºKlŸt¥ò†“JBwFÅý0¡¨ &dà…|ÒÀl0 âËJ‘—ZXaIü†¸jR_AyzF§r‰H¹)’…¤ ÌYh;}ÂMòâ¯ÈL H‹ IIƒ:IJ҄“>G|…¥™úÌÔ”°MÀÉù%þ_(3¤®©B@ª ¸°0ÈÈ(¿Â ènK%ìIZZ߈] PšLK%—ÒQLX@Ä#†1 éJ~ÿ£JN÷4›€QѶÜ͆m÷üjqD¤lS§düK@haûööîù¾_=Aç¹áMÌ•_€N[2IM÷JÉýB†ÒÑŸ#fCïøÔž›É£ nCmÃ3â¶Í²B¿Fn16ê–©ÃKIC?FüoÙ¾éîÛl3d¹NŸ’—Û ×5(Bz?ËG|+·AûÙæ‹?“ÖgWÄ„²²¶VvÊ3?lcÔR—e5|¬lÿ¶¶üß³¶qOØM]zvøg@Ü—ÜûõîrœñÑ}‰ÌRF vOÍ÷K÷ê%¨ó·Çd¥"*û>}öÿ>?3áy÷Á{êºRqWÊV-ò³7~ëu2˜K÷U>}öÿ>?3áy÷Á{éE_])XëùjÛÙniÜåãñ§Î*úéJDUò•›3ž¾çþfÊsŽ;)×OWsþ3å±çÔë”UõÒ”œUò”¤E_)_ÕßoÿlÛ˜ç·û)ß²þƪLíŸïÙfßŠÏØCùE_])Y³ýû/ìÛñYû8«ë¥)WÊR‘|¥+>ÏŸïö7ìÏØSçW×_ÐÝ–§ù_Œï·ù»;¨åñõ´Ëÿþé5,ÉKÓÎVÜÃ*—Š¿ÐÀ@PoR6OrÀ²¥÷Å»-8'2UÆÿß+Þ´ ŽLÜ3ÒÉ5oöBJ/•Ë}øÒПöØgV¾MK”i8êªÿ³”mŠùÆ€ã‚÷èÛpD@j ÿbÓ‘ßþÆû…€`YE@ÜÃI™†�¡¥1oHj†$¡ ÛéÁ9¯JÈCl… æB³n¸ÌqÊßVJÜhÜ„ßpƒÐý‘ÝÝ·ÿêÏb4ñf­Dý:¿é 0œ¤¡|„€Ì’Jt—Æ ká‹ÿòcò€º6ûþß^\ FA+”ÑËìØ¤'·éVrÖZ[(™yvÏûgûoÍû;gý„Ñ×ós²ÔÜõê5LµZþø{‰•_6¶Î¬Ëÿðÿßñ=tÝöÿ|øîÏ…vÿªévSWÊR“оWü7·Ûå|ë^îs6fßw<sTRQWÊR³ç~êÿÜÂ~;åyÅ_>v=]ÏøÏ–ÇžwS®®•Ÿ>ûŸ™ð¼ûà½ô¢¯®”¤â¯”¥fÛ?ÛgïÅöÙøõm„hоºÌëR™³c×Ýnµ*®‘|¬Ýöÿ|øîÏ…vÿªë;·m¿eoÛ~/·a-å}t¥'|¥)WÊÆ_ë^ØþÊsǯŸÍ:®‘}™Û>Û²öï·Û8–Ô|ÿ>}·øÝ»·amØE]%|¥+7}¿ß>;³á]¿Á_éÅ_]gì<ý•¿?±„þvËõtˆ«å)HоR”ˆ«ìÜnß:ó¯}Ã÷o„uÕÚÃCM+”—èNo·ùðçßq#õ’“¢¯”¥*оVg[ìz–Ëu-Utˆ«ågví·ì­ûoÅöì%½]"*ùYœßºùÙ”ê7˜7Ž«¤E_+3¶}·eíßn+¶q-ªéWÊÍ›mÿíìü_m°VÚ®‘|¥)WÙ³úùìo9[v5«¥"*û3­þ=JfÍ_uºÔ©óöëB–Ž0þdz¯®ËçÔRQWÊR“оVnû¾|wg»‚¿Õtˆ«å)HоR”ˆ«å)HоR”ˆ«ìÜnß:ó¯}Ã÷o„uÕÒ‘}‹|¼Íß2ÝL·ù—WJDUò”¬û%_n½Öµîû‡uáq}t¬eþµíì§0ìzùüÓªâ*ùJR"¯”¬lÿ¶¶üß³¶qOØM7qçü½ñÝ's¾^”UõÒ”œUò½ ½_»?­_Ÿ–b±ÆI³9ëîæl§8ã²urоR”œUò”¤E_cçÙóýþÆý™û |âjéHоR•Œ½Ö­ñý–ÆÎW?|E_>ÉWÛ¯u­{¾áÝx]])WÊR³ü…ÿ²öZ—ûlÕ…ÄUõÒ”ˆ«åfsvËçwS¨ÌaøÎ>®‘|¥)WÊÏÙ_c¿3õ±ÇÔꫤE_)J͆m³«2ÿü?÷üO\E_]+ßônŒ{p—B¹êù÷ØÏ²ÕÚ¢QWÊR“оVglûnËÛ¾ÜWlâ[UÒ"¯”¬eîüî¥79g:Œ[-uq}™Öû¥»æÇ«2ÝKTéHÄ~¦Ëý=¶Æ÷nv~EÕ”Uò•޽›Ö¦Ç(÷YŠe.®qWÊR‘|¥+>¾î¼Êÿpï›á9q}t¥"*ùJR"¯”¥"*ùJR"¯³ö3õã˜Þzþ8þkNæm×ì§YœÃ±¼u]%|¥)8«å)HоR³}ßo»vâ»nÜr¾â=\E_)JDUò”¤E_+7;-MÏQî£TËU>}öÿ>?3áy÷Á{ê¹E_)JN*ùJR"¯³;gÛv^Ýöâ»gÚ®”ˆ«å)HоR•Œ½Ö­ñý–ÆÎW?|E_]+{-{ó»);¬0긊¾R”ˆ«ågví·ì­ûoÅöì%½]"*ùJR"¯•›»ž®Ç|fêsÏ?)ÕWHоR±³îÙöûsvìùŶqq|¬ùØõw?ã>[yÝNººDUò”¤E_z4ϳo¿Ì{©¸Nø×ØúŠRQWÙ³:ÿ~)JÊ̓Öýý]fîêù¸¥«/7[wÕq|¥)8«å)HоR”ˆ«å)HоR³íÛý»w»|ør¿Â=\E_)JDUò”¤E_+;©¾=jwÍÎ^e²ÖªºDUög7l¾wu:ŒÆŒãêë?açì­ùýŒ'ó¶_«”Uò”¤â¯”¬ýŒýxæ7ž¿Ž?šÇUÄUò•›ä¯}×ò–½Ûàî®.®"¯”¬ÝÌù|ö3ž¯Ï?ÇÕÄUò”¤E_gìǯ±ß™úØãêuUÒ‘|¬ýŒýxæ7ž¿Ž?šÇUÒ"¯”¥cgý³ý·æý³Š~Âb*úéJDUò”¤E_)JDUò”¤E_)JDUò”¤E_fÌëýø¥++6[÷õuŸ³¾Ç~gëcŽ?©ÕE¾VfïÝn¦S ~ê”UõÒ”œUò”¤D����È����z¿óýcgݳíöæíÙó‹lâ*ë7Ýöû·n+¶íÇ+î#Ê*úéJN*ùYœßºùÙ”ê7˜7ަï·ûçÇv|+·ø+ýW(«å)IÅ_)JDUò³öcרïÌýlqÇõ:ªë>ÏŸïö7ìÏØSç(«ë¥)8«å)Y¾Nß}÷Ͼ^û›¼E_])Xùö|ÿ±¿f~Ÿ8˜Š¾ºV>}Ÿ?ßìoÙŸ°§Î&®"¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJVw3ì¼~u:ÍÆÌãâ*÷J·ïó,#?l¿™¿îr³Ž]E)(«ågs6ëÇöS¬ÎaØÞ:®“оR”ˆ«åc¯fçu©±Ê=Öb™K«¤E_)JDUò”¤E_)JÏÆoû«:·ü;güF\E_]+?açì­ùýŒ'ó¶_«ˆ«å)HоR”ˆ«å)HоVlÛoÿlgâûm‚¶Õtˆ«å)HоR•ÌÛ¯ÙN³9‡cx芾6}Û>ßnnÝŸ8¶Î"®•™Û>Û²öï·Û8–ÒŠ¾ºÏ²wßo¾oº÷ÜϪé8«å)HоV:þnvZ›ž£ÝF©–ªºÇ^ÍÎëSc”{¬Å2—(«ë¬îfÝxþÊu™Ì;ÇUÒqWÙûúñÌo=5ަîgË籜õ~yøÖ>®’оR³w3åóØÎz¿<ükF^ëVøþËcç+ŸŒ>"¯®”¤â¯•™Û>Û²öï·Û8–Õtˆ«å+׸ýúß°ÌÆ6Zñ¼Þ³*%}ŸäoÿÛlÿõm±¿ÕÖwSlzÖÍ›œ®ëe)Uq|¥)8«å)HоR³fs×ÜÿÌÙNqÇe:êâ*ùJ͆m³«2ÿü?÷üO]\E_+>v_ÍÅ-]]ðz›¾«¤E_)kýˆý¶Û¿fÛ?t§¿ÙOÒžyæÝ¢h¤ (ž€ßÊm¾ý dÈìóçÙÙÅv²ÛùÕþj—[PÄtd§n”òÿü{7çpŽì£uÉ©¥WÊR³çßoóãó>Ÿ|¾®*úéJϲUöëÝk^ï¸w^W×JR"¯•Ÿ³+÷â”®¾ü9OßÕÒ"¯”¬Û![l¿Ô¥þÿ‡õñuq}ÌÛ¯ÙN³9‡cxêºR"¯³»vûvWùöâóçú®³öcרïÌýlqÇõ:ªå|¥+>¾î¼Êÿpï›á9sоºR‘|¥)WÊV-ò³7~ëu2˜K÷U\E_+>v=]ÏøÏ–ÇžwS®Ÿ³+÷â”®¾ü9OßÕÊ*ùJV>}Ÿ?ßìoÙŸ°§Î&qW×YÝMñëS¾nró-–µUÒ"¯”¥"*ùJR"¯”µþ–edÿòÓ±íÒà Ë^Î­î‘ jrrú Ùtq¼% %æøbŽéÍÔíg§WñŸ?ÏŸmþ7níØ[vwP’ã7ÿnå'ãää6Aß }ËÉ%ogúõ¼†ŽJ ,0éF-(J bWø”RFäänߣ!ó¾½Yn” G&ÁŸd£íɉÝÜ1Š%ò@c–7—ú8¼½›¯«£×WüøÔ$4¼Ÿò>ÉpÂÙ)ÝÊÛ}Ðøj`--öÈÙ웆U0i_²å¤18gÊBYñë}“}W§¤–3¡;üŒJ(4¾{ƒy43âÒR~& oÝúrûX å§lY@ðܲ_§ç Gd¡ %œŽ–Bz0bNè^¹›£FÛ¿ø\êÿX%£òYd´îذݲU€ña©+'t’ ¢Ý(íq€¡+!ƒ658b>`ÎéO}òß9@{¶ÙŸÞ£††“Hi(3Wì”ÈãI‰@ħ¤¢n/¿Û •·Ã7çTåɼ†„aœ3–²Vètô ½Ñò—òCxK”Ÿ’¶ÞÛ¶Ëhe$éUÿ:ÿçÿ+gSÿÏ|3gÌÿŽ“l¶Ûm›l­¶3kÙ’VèÉã\®4­Æ d![ô¶èÈFéìJ þæ“�ª‚ÐQh(fû’7gdd ¤'}öý]Y»7»þî/€ÏÓWùö^ëVøþËcç+ŸŒ>®”»)«ìÜnß:ó¯}Ã÷o„uÕÒ±—ºÕ¾?²ØÃ¹Êçã”UõÒ•›îû}Û·Ûvã•÷ç}t¥gùÿöÛ?ý[loñ}t¥"*ùYþÍ¿Ùûa}¿l=[ñ®³¹›uãû)Ög0ìo(«ë¥)8«å)HоR”ˆ«å)Yo±ê[¾lz³-ÔµDUño•™»÷[©”Â_ºªéHоÍÜyÿ/|wcIÜï—ªéHоÌëR™³c×Ýnµ*®”ˆ«å)HоÍòW¾ëùK^íðwWWJDU÷òÑÓ°Ì7¿ÊË_•Ö+ßPHÐxo)<3% ¯º ø1#JöF%ô6Oã1&á'£}ɼ`j0Î^f/¥“à å|ûv Gd÷ÉÙ?=ép ÀÀbS±¸À2Mü¤q¨l^$¢‹Ù‘œ‚YÛþßÞ Î“™ge…‹sZÒ¯ÖXáˆÜšžÍºK/âЗ-¢†ìRœý=%dä&ñ®¿çI4H Ý4–’Q}%†“T¼IH K&!,JÏÐù¾{š@-)Ò1;â‹ù78Ð0Ã8gÜ– 1.‘wU),a[b‰e’ÊI\44½º@oД %‰Eq„µ¶|לÁ'¦V9cÎÃøêêþ ᄼM è)ðjP„ð‡AX¦ÛàÒWà9ÝÆ—þlŒÝ®ÉH�<ÀoÑ‹ àe#Y(应—r‘ÒPFnÿ(†ñX˜LÙ®MºYäÌ”tr†™%'î®÷©Д–Mý<®Ž¼”·-•Æÿ?N%§Æ’wúãGug7ñÎpçZ½Uš-8 aJHgèAIéÜf))ÅÍ›ÆÿÓ¾%¥�YýŒ„¾Y ÞZqe¡)ŒHfÏú ÿ¿à[b·Ý ‹K·÷©%¡( I,¤2 a]xbqy ã7 ,bqO&ëÎð€XPGÄÌý¤¤mÉ›—Ê%ñ©ý Y¾JBT†éŒsñû/­d‡ŽŠ¿”L( †P`K””•ÃS’ZººP0”ÅìVãÑ¿ÛÞ ÞQ| 3’JNÉß?ÿt~ŸÑ‘ÿ,àœœ€,Œ½}%; 7‚ÐKÄÒRCO@b1�c!;”ÉK–ù(ôüŽ¿îenRK唀*œ’‘ð5,¹Y%¬…>l—Oß"ô¾ß;3ì°š*ÿ•¡#víÐ)9¾ù_ϹûýQz§†£:>ÐÒ1#F;⻄„g%6ÉýÙW fÛûcû?Ûl¶¾¬ªúéJZʯ•Ÿ°óöVüþÆùÛ/ÕÒ"¯”¥fÌ篹ÿ™²œãŽÊuÄUõÖ6Û?Û~oÙÛ8§ì&®‘|¥)WÊR‘|¥)WÊR‘|¥+;™ö^?:fãæqñ}t¥"*ùJR"¯”¥fu¿Ç©LÙ±ëî·Z•W×JR"¯³¹Ÿeãó©Ön0îgOÆoû«:·ü;güF]]¸›úèß÷B Ï—¾^ØzP~£E_ô’ahIdÒùLXÒ¸hÞ^èØ°-‰I bÓöÀ`aY-Ûü•û  ²`ÈÅðÀ0ÌKÜjzðÆ-((7 ÉB] öC7jòØ–…ÓѺwBrP—Áű,hÂPo+bòP‡è/÷õeBV†»¶pÄþ†àÔ‰ˆJ‘Ø þR:#ïõà~ Ÿž¢u­_Ý(g ÄΞ” ´“HE¡8jJéd§¤7fü!$´wÈBä !C%9 Y¢Y@Y1A¥2SÐXí›%÷è3½ƒƒD¢÷Ùb¸ A1#Žý$Ô­)Bv)$·ÌŸ»ÿ¤B|²’ƒ Š-())%ƒ�m¾ t2BrœìÛØ¿nk¾_YÜS�Öª¿ÝðÒÀbŒZF±Ѐ0ŸÆôbÀHƒQ;äíŸo8ƒ7@b ÈR¤°Ô%§¡%·Ý&£ÿ ^¹8 †–Ëø4¢b6J~É I1 ³ô'nÅ ²öá»;':/RM&† JI™X`ÂR¾J8ÅÂk£žùIda¯ÓýçgØ<+‘*«üÐiHÈ(f A(Å%%äÀlÉéB>å0-Ðå–Zvï­äÒ pa,†©)†pÀÔ¬ á£FýöJRètŒÇ#ÔbieÐMåD ·Hn&d–ŒÅÁ¤Ô|ZwéNHN$:9×”˜®£ô£–),¾— #üPÎZÒñlÉéù­ÌlüîvÆ7À4•_éK,˜”LÛ9múŒÛ”WbRSº‹ùú6@Î[¼C IDÎL+ÒQ÷(¤dôñC3¤¶Å ¾’Ûç-‘¾ÙïžrùIN-¥%)JId²ñA‘É©@Ä”Ÿúvû¡#9WÒI¡œ?tto“ƒ3bRÓ²: ¿•~” ®œ4µ~©fîû³ î@¯ž�È¢Y|—Ë,'”’òK+#¥e2K)ûýÉY?ìÕõòððc††ü–žŸ™B;7ä Íº1''nî¥*ú10„ϰ-8o–J¢aH-†§ŒÝö,hbQöÙ‚o—�¹HJ?B>Ä­„bVÿ¡°K Cnüã²=ëyÁÂM=ˆôj¿•³úùìo9[v5«¥/zʯ”¥zP5]º>û£çwalÌï›»Ê*ú)XÙÿlÿmù¿gl⟰š¹Å_)JDUò•ŸnßíÛ¾ÛçÕþêâ*ùJV2÷Z·Çö[w9\üañ}t¥"*ùJR"¯”¬Ù¶ßþØþÏÅöÛmªâ*ùJR"¯”¥"*ùYœÝ²ùÝÔê3~3«¤E_)JDUò”¤E_õ (€0„ÊèåtJéÈû’ùKø1 Þ’R�Á,'ÿþNW¸Å“RÈ &  Ô¸ìƒJGè(aN–IcP¹ùö¨F,04²jQÿÈøb�Á,†Ý�)Èßv(Œ”¥#9œùËbRRMrÒY\# ¤ ¼ÃKJSúw+5“Ø k^ º³ž¿—‡™‡ü¡6µiÔ!$2aD´ô†–”QiNû—ñmÛì¡©B\`Í»Ô ¢b mÊ&„ 0¾”!<) ß$¿Ò[§—†¶Òù[¥¯<LÿPÄ“ ã ™)&1Ûä3! Ý•²6ÊRþ½ð ¾ å£ G&,¡©I £§$®Q3Ÿº7Ý NFß“ò5Ÿ^[ìÝ[«8,ÙÕýo·!–Žœ˜MA_ NOãv~‚¶n^+d¤±Ž¢’eÖN¥�¤´LH͆ÄÀ„¶ Fßñ…#–ût ¦ÿ>¼`P3¹3ðÂZCwdòQOZƒÐØ#b‘ؤ$¯†çé½ @)BPL@c † (7Ò1; ¢Ð“˜¤;²VóçkËÝ™ûå‹ÂOø1ë«ò†äà×@Ä¡ ´€ì½ÊÝY(-Jyt“2K^AhÇ#m¯-ñD>‚ÐÀÄ ²Ž’gFéFؤ ìºII[wŸ_Y,3rþ ,¿ò”ðÒ“Ãz[íðnßù(j>Ücûæ$ÌP„ÀÄ“QÆ ¤•É©,i@`–žZ6å|Sg)?£ŒëêȺ²±üÂPõSWóQ5 M/í“‘ cd¥‹/ätdâŠb[ОÏû»Út¤šM) da ° C�nK%’¹_%*ï¸ß†nó²*¹ErËO &¡(n,`ae’’„·(›€ÊPPÂ’ÊÉÿ¿OþÈIœü7w I_3£ Èÿ tô¤”V K£ºSÿ}vt¾mˆçlôªòeôî–Ø5º@ÂíÓÊè²~(›òYa˜¦Ø¾É{À¡](ÅtmÝÂ=+ÿ7sÏ}Ÿ½X&%d’þûô°am‘ò Fè rnÁ)d£;ÿþ]åɃFq¹¸ÒÍýD¾3¯óÐÝŒ;lué'âpð±G*Š¿ )Y»íþùñÝŸ íþ ÿ^…}t¥"*ùJÍòvûï¾}ò÷ÜÝêâ*ùYöNûí÷Í÷^û™õ]"*ùYÝMñëS¾nró-–µUÒ"¯”¥gvíöì¯óíÅçÎ!ôE_])HоÌíŸïÙfßŠÏØCúºR"¯”¥"*ùXËýùÙJlzÎuš¶RªëñhìÉÜn›åå/ËË¥z~3ÝYÕ¿áÛ?â2êéIÅ_)JDUò”¤E_)J͆m³«2ÿü?÷üO\E_Ý9@d0”éÃR„vÉûï×’3Ç­wNzñ¡¨!¤èG&mÒPj€·Û¾ù‚'öwXNF¼½ê�©3¾-éoÓÜš†b’€Œ‚‹û²xwcî40ˆ¿UWú¤¢i  ßò¼œ€‚‘иÔ%’ý¡8¾·Ä®Éú¼3âhèådÿÒ”œnù-#J&‚ƒwOý(JCr:g Ð0Pj/Ɉé(˜‚øiCPØ !?'l”ô³£¶+~ö°ÂK/ B ¥²>ùú‰h%à†) &|„ íÿB5ä­yÛŸÇŽê#šm¥_‘1˜!Ê)¸´§¤––èåüσ¹NŸÊ,5,ÑËï{pÂbQÒQ_q©Ahã ANÒQdÂkâ²èû£€23ȼ@ R‚A¨É¤¡(F(¦ FF䲃rCxÇJ±}Ô1ïB@Èi01#CL/àÒR9Ed'nZ K ¾’ÿÈY{*çÛ:Ï^ç©S«í&²$4–€ÂYEòËHÔä‚Ie”äà3ŠPÝÊJpï¬�0!PÐ2’± C~ééVü !( è%¹{¡/ÊK¾GOMì�b‚òpnA4¿²IhH ÛÜiiû„t Fd#rRqÈ]�,Äßú7ÄÔ!%ðÞžLHÒfÓÉ}HJ[’þÅòЗ»ëò²ÌfØŒiÜ:¿Ê$´”’R¼CÉ,5 Ä¢ðb Ã’_BúPPÌŽXÄÿ¯ Òž0˜R C†öý› ,­Êt”á›¶JÍ÷ýzë Ä!Ã6Û’À±krÉBq(j?è%¡‘ÐV=yšñ9 Wß%ÓÂv-=º[q‰OGÛ†3c³Þ¡å凑WE_Z7ÉNR™éÿôõvnøöî5̰סÛ;¿[$cç[)G)Î?Ô^ϲ«å)J⯕Ÿdï¾ß|ßu﹟UÒ"¯³q»|ëν÷ݾ×WJDUò•ŸvÏ·Û›·gÎ-³ˆ«ˆ«å)Y»º¾n)jËÍÖÝôE_])HоV-ú³6nëuº˜Cw]]"*û>qçî¯ñÝÌ'ã¾W«¥"*ùJV2÷Z·Çö[w9\üañ}t¬uüÜìµ7=GºS-Uq|¥)WÊR‘|¥)WÊVnîz»ñ›©Ï<ü§U\E_)Y»?åïŽìi;òõ\E_Ú &pÒÊücòsá®—ÛfØ!8'~f}ïtY4H c’Š-£ AY»âÆ•ÐW@C!ÒZ¶Ý†ß+¯IHOGùú;á]º+ýqçc{æUU×É¥r’`)˜5¿ÉJP¿ 7 B WÈ,—†7t£¥ ÿZÃI…ðÂÊß'd'”Œ‚ÀÎBQ‘ÐPÜ„`ÒV+¬¬”|”ûã80¬¡ˆVFÊÇ#º0ºðã-ÀÁކB2‚Ð3o³Ï›|»/twíÕpä›ÿ<(áëU_ô Â¥#?&±Iù t≩B0iEŽB6ߣ•ÝLèÚñh1_nR:6~œ„„ñ¨C¥—÷CüÌÜ!wÄ B7JÔ„ü¯¾û¾ÙÝ|1³3XvÙþÛ?~/¶ÏÇ«l#]=?9¢Ï<|ªþ©jt’ R0ÂùiHGä¢þ~²þÏ·w¹]Ìû/N³q‡s8úºÍÜÏ—Ïc9êüóñ¬}ÛM_>íŸo·7nÏœ[gWJZJ¯•Ÿç϶ÿ·vì-»«¤E_)JDUö~Ûý¿lvgâ³ý‚þÕuŸ¶ÿoÛ™ø¬ÿ`¿µ\¢¯•Œ¿ß”¦Ç¬çY«e*®³öcרïÌýlqÇõ:¢*úë7É^û¯å-{·ÁÝ\]]fãvù×{î»|#®"¯®³|¾ûïŸ|½÷7zlÛoÿlgâûm‚¶Õq}Û¶ß²·í¿Û°–õt¤â¯³;gÛv^Ýöâ»gÚ®”ˆ«å)HоR”ˆ«ìùØõw?ã>[yÝNººÍÜÏ—Ïc9êüóñ¬}\¢¯³á»îë̯÷ù¾—WJN*ùJR"¯”¥"*ùJR"¯•Û·Û²¿Ï·Ÿ8‡Ôû'}öûæû¯}Ìú®QWÊÿ’êù”~üÐ?ÊúÖtÌû/N³q‡s8ú¸Š¾R³¹›uãû)Ög0ìoW8«å)HоR”ˆ«ìeþüì¥6=g:Í[)Ut¤E_)JDUö>}Ÿ?ßìoÙŸ°§Î&®•™Û>Û²öï·Û8–ÒŠ¾ºR“оR”ˆ«åc¯æçe©¹ê=Ôj™j¦ãvù×{î»|#®®QWÊR³fëÿŸÜÒv;eiÅ_])HоÆÏ»gÛíÍÛ³çÙÄQ³îÙöûsvìùŶqt”Uò”¬Ünß:ó¯}Ã÷o„uÎ*úéJ͘yÿ¯þsIØí•¢*úéJDUò”¤E_)JÍÝÏWc¾3u9矔ꈫã¯å«nwe¹§s—ÆŸWYÜϲñùÔë7w3«”Uò³ç7åã˜Îr÷<îkWY»º¾n)jËÍÖÝôE_]gví·ì­ûoÅöì%½]fÙm¶Û6Ù[lfÑ}t¥'|¥)WÊR‘|¥)WÊR‘|¥cgý³ý·æý³Š~ÂiöJ¾Ý{­kÝ÷ëÂå}t¥'}›0óÿ_üþ擱Û+UÒ‘|¥+{­[ãû-Œ;œ®~0øŠ¾w3n¼e:ÌæãªéHоR”ˆ«åfu¿Ç©LÙ±ëî·Z•WHоR±—ºÕ¾?²ØÃ¹Êç㫈«å)HоR”ˆ«å)XËÝùÝJnrÎu¶Zâ*ù¾ï·Ý»q]·n9_q®”ˆ«å+3­þ=JfÍ_uºÔªglÿ~Ëû6üV~ÂÊ*øëùjÛÙniÜåãñ§ÕÒ“Š¾V~ÌzûùŸ­Ž8þ§U]~Ct÷ýÙ_«lfÇÿŸÇ¶Òн>Éß}¾ù¾ëßs>«¥'|¥)WÊÌëR™³c×Ýnµ*›3ž¾çþfÊsŽ;)×W(«åcgݳíöæíÙó‹lâ*é8«ïBÎÿÿfs3¯¿ÈÛ9¬eE)(«ìîfÝxþÊu™Ì;ÇUס oý¶ÿóÙÖÙ‘¿u¶ÎQWÊR“оR”ˆ«å)XëÙkßÙLiØõcù‡DUõÒ”ˆ«ìÙœõ÷?ó6SœqÙNº|7}Ýy•þáß7Ârêé(«å+?ÏŸmþ7níØ[vW8«å+?íŸí¿7ìíœSöF_ë^ØþÊsǯŸÍ:QW×Y¶FÛm¶Í¶VÛµ]'|¥)WÊR³ç~êÿÜÂ~;åxоºR‘|¥)WÊR‘|¥fÌëýø¥++6[÷õq|¥+7wWÍÅ-Yy¸rÛ¾ˆ«ë¥)WÊÌëR™³c×Ýnµ*›îû}Û·Ûvã•÷êå}Ôßµ;æç/2ÙkU])8«å)YoñêS6lzû­Ö¥DUõÒ”ˆ«ågìÊýø¥+¯¿S÷õtˆ«å)HоR½,#¹Õ¸¼n=J~ÜÚ‰E_)JN*ùJR"¯”¥"*û7É^û¯å-{·ÁÝ\]])WÊR‘}Œ¿Ö½±ý”æ_?šu])WÊR‘|¥c¯fçu©±Ê=Öb™K«ˆ«å)HŠ¾ÍÆíó¯:÷Ü?vøG]])WÊR‘|¬îfÝxþÊu™Ì;ÇUÒ"¯”¥fsvËçwS¨ÌaøÎ>"¯®•ŸnßíÛ¾ÛçÕþêâ*ùJR"¯±—ºÕ¾?²ØÃ¹Êçã«¥gí¿ÛöÇf~+?Ø/í(«ë¥)8«å+>íŸo·7nÏœ[gWWÊR‘|¥)WÙó›òñÌg9{žw5Ž«¥gã7ýÕ[þ³þ#.QW×JRqWÊR‘|¥c¯fçu©±Ê=Öb™K«ˆ€�������z¿óý)HоV~ÃÏÙ[óûOçl¿WHоV:þnvZ›ž£ÝF©–ªºDUö:þZ¶çv[šw9xüiõt¤E_)JDUò±³þÙþÛó~ÎÙÅ?a5tˆ«åÿwç+m‘ÿÙû:—ŒÌßþÕ”Uò”¤â¯”¥gÃwÝ×™_îó|'."¯®”¤E_fÛ?ÛgïÅöÙøõm„jºR"¯”¥"*ùY¶FÛm¶Í¶VÛµ]"*ùJR"¯”¥bß«3fî·[©„7uÄUõÒ”ˆ«å)HоR”ˆ«å)HоR”ˆ«å)X·êÌÙ»­Öêa Ýq|eîµoì¶0îr¹øÃêéHоR•™Öû¥»æÇ«2ÝKTE_])Yû2¿~)JëïÔýüE_]+ÑùÝmÿÈûwsñ‡?ùOQ(«å+?íŸí¿7ìíœSöW8«å)HоÍÜÏ—Ïc9êüóñ¬}])WÊR³¹›uãû)Ög0ìoW×JR"¯³öe~üR•×߇)ûúºR"¯”¥"*û>}öÿ>?3áy÷Á{êºR"¯”¥fu¾Ç©nù±êÌ·RÕW×JÇÏóçÛÛ»vÝ„UÄUò”¤E_fï·ûçÇv|+·ø+ýWJDUò”¬Ù¶ßþØþÏÅöÛm¢*úéJDUò”¤E_)JDUò³fÛûcû?Ûl¶«¤E_)JDUò•›dm¶ÛlÛem±›UÄU÷ìßí¶Ç¨ßÿé|Ì-Ýù6ÈÛm¶Ù¶ÊÛc6«¤¢¯”¥'|¥+ÆíÆ:Ô¬¶woØíÛ·í¿Ì|¢¯¢”¤â¯”¥"*û{-{ó»);¬0êºWädó¬zSÍý[ÿ±æØí¥}›d+m—ú”¿ßðþ¾.›îû}Û·Ûvã•÷é³í»/nûq]³‰mW×JRqWÊR‘|¥gùÿöÛ?ý[loõq}Ôßµ;æç/2ÙkU]gÃwÝ×™_îó|'.®QWÊR“оR”ˆ«å)HоR”ˆ«å+>ÉWÛ¯u­{¾áÝx]\E_)JDUò”¬[õflÝÖëu0†î¸Š¾ºR‘|¥cgý³ý·æý³Š~Âjâ*ùY»¹êìwÆn§<óòUtˆ«ågí¿ÛöÇf~+?Ø/ízBhÄÁ­¹'ºÐ‹ûìž”9[³#·XÎë¬/âÉœ˜Jä,‘Œ›!*ã9]%n1ò7ä‘›åç¹¶YõUü Q¾éNÙ)Ý–^é|7–ÊÊû«¯µèpo!¹eô`(1›%ûG(7±Y!i$#}ÔÏt€,(@Çû% ý%%)B±{lѳ~ž‡/Œ%§m^P@b !!VK†þVHbŠûR‘’ߥ!(rSopwãÿ0À6mU~@ )( OBR”`À”'ñ dnÝ/ñ+¡/øÌVÛ\’° ¾ÈHjR_û”_/#ä$±ƒF¤g FQ/ôgn¿v‰„.Q0bqe!J1D´o‹HhÔr·ÝV‚R@n‘œ ÷ðüa›r¥-ò9Y Ùÿ GÉá™+/$$nÛfɳíÜã;Š9aâ'Wüøk0Ößÿ¶sÏùŸeŒÏñ‹>¢úD2i{`)ŸpÄ$¤ò°™¿+£ J9F%ºKNCá›æ¼ çùóí¿ÆíÝ» nÂ/Q‡Û:¾ºô;gwÊtŒ~Êp…,õ1çjŠ[ʯ³ý›³öÂû~Øz·â5])8«å+7w=]ŽøÍÔçž~Sª®"¯”¥"*ùJ͘yÿ¯þsIØí•©þÍ¿Ùûa}¿l=[ñQW×Jô a¿æÛoÜç[ðŸù¯ùÒ}’¯·^ëZ÷}ú𸊾ºV-ú³6nëuº˜Cw]3­ö=KwÍVeº–¨Š½÷û#%©ò;;?æŒÊ7Šw¨¥"*ùYÝM±ë[6nr»­”¥Qo•™»÷[©”Â_ºªâ*ùY¸Ý¾uç^û‡îß뫤⯔¥fù;}÷ß>ù{înñ}t¥"*û;©¶=kfÍÎWu²”ª2÷~wR›œ³F-–ººJ*ûÓ“ðGÛ¬ýùŽJ n!Bê)HоWïݾoß©þmÔý¶ßï”%ª)WËÔ�Ć„^ßô£gÈO}Ëd#tœ_éåeoñ% ÷4¾R3}¿ûa®3þgø4íù¿+õ^¬˜B nRFä `!ýö,¼XÒÒ”pÂÆ'¤nüj~9Gë“/¬ŒeUInMår“ËÒZPR@ÀnÛ†!-Æ—Æì_ß$·Äº²‹à;Fä2Y ;7èJ@(è)Ƭ®‚ºJ î5*ͰNU°šBJJ 冠¼‚¶ È/ºs% ‚úPß‘¿Ù?°BrRÓ“I˜05%¿ -âŠlÑòÆ¡Šé#0f%†à¹ÒZµäîÊÇ-Ìî9gZUü’’a4hj´±\½Ò”÷G(¢“É}#2 XjrM$Þm!„°.Ý#'–Û)º K¡£ìœå›³½ôTâÆ¤j@ÂSÃKJFô�ÙÊO(¢a@[÷ü¢jpÖdôð–¬Ý( @`ÐÇü¤Qaˆá…ºK ~W�°iéùÐ’VÀ}uS‰ýdùUü\L@h†%ñ†t”S'rÃ#ŒCbº†!;¹0¤åý¯ô•ˆ[“C8ÐÔþ1(J6nM%§$fJÆZq(fl³Þ´˜òI€c•ŠÎVÁ-=?eþ†.VN὚¶Ftëqm±A˜”^N%$4±…!¸cXÑ£: nÍÛ%})Nׯÿ¸§qâDõUþ/ž^å`Òòô—Šèø¼WrÊ&%*J~& ‚¹i^O×Hhia‰ÙO`ÜrxbI\•ñx•Ó¿ÿüRñ“õôÒ+”Q+�Tá|˜LA0´•ÕòCCrR”ugI%“Û=Å!8Ha ¤`0CAe†–Xai,1ú9oº_¸Ä§?Q%µÑÑ–üÜËZÄ+)¥Wü¼0²_ÿ% +ìJJÉÃq}Ûà$Ž]ͽÐh¹x—†²:R’Šåõ² ©Ã à Ÿ£â÷èÛ'|ùïÿ¡Ñ—óì—AŠÝóáj|:÷C€6u}¥.šjùJR"¯”¥"*ùJR"¯•›3¯÷┬¬Ø=oßÕÖn7oy×¾áû·Â:å}t¥'}Ÿ;/æâ–®®ø=MßUÒ‘}޽›Ö¦Ç(÷YŠe.Ÿ°óöVüþÆùÛ/ÕÖo»í÷nÜWmÛŽWÜG”UõÒ”œUò³ñ›þêέÿÙÿ—WHоR±×ós²ÔÜõê5LµUÄUò”¤E_+ùy›¾eº™n%ó.®‘|¥)Wô‰©NB~ÉGNm’7²B>Oû·mÐý¶çÞíM+ ”ŒKÿ`vIe)E„öÈëä²6ç}y0£ò¾t¤oÈ”‚^Xݺqýû'p…|»ßÃCJÃI|7qŸ!¤¥<¤w+¤nAå%¾@Í‹,fNÍy·"ó�diWÔ¢Ë& 4—ñCÊe£nQ3$îé+|Œ—ä²5¸ÅÝBÀb¼K(0´ƒÀÈG Oì°Ä:PS (5=?·ï»{¤[”Žý á¨Ahè OI5)- Nøj9cqíÓÑ÷½Úphì5(H`Û”’ŠFB#„0ß² å¡*_Ïšðú70óÇ/‰"*Ò¯ðø²€Lù!1îVåä%Ë OpÄ¡$ÂöÅ!) vÝÛ']€ŸJI0¼Ä~JFÁ¸&>ßb†òWßïËa«J{�¿àe;†’z\—ÐÝ”–7òWNá¹Iϱ½®*@b’hÔõ!Ã{£--ÑÆùcðÞ”K%²ö±Ù–ìì8ƒ–"u}›“@¢öAerÊÿ`3À·FÝ $NB)ù¡()Ûú¾ZƤ”^ã§'ò»òXnI|–’R±E$bpÜÁ9ýPa1$Ý‘ƒCOÁœ¤nØf n”—Ø7£0ÆAy/}Ù[ÜÌM@ NÛtþž0go1(ľ‚@j>-\¤:Wémù¬"?_‡Ð59‹Å§àÒY ¡?†”Ÿ‰yÑÆ¤´|['6NJ5Œ² „´104¢@tq›†ò’M Ûp—A- JOÈΟXB‡BC21 E|^FO).¯†äð.œ^,ôqòï.Pb €;Rw+$ '¤4$ –_/”Û§îJÿt³ Ì”ÿvô¾^~±cŒ¢¯á�€²Z„·I3€ÇB2vå7FÀ$HÍѲ;$Uæƒ15ؾ‚þíÓ˜’1¾ÝÕó³-̽`c†lQ+튷(0´g/2\§ p”%)ÝÐ[oÒÿæ¼öN/ QifÁ¡¶çÿ’”ž†øæ×¸–×f…,‹gWñ»™ö^?:fãæqõu‹|¼Íß2ÝL·ù—Wz4Uò”¤â¯”¥"*ùJR"¯”¥"*ùJR"¯”¥gã7ýÕ[þ³þ#."¯®•›Ûç^uï¸~íðŽº¸Š¾R”ˆ«å)HоR”ˆ«åfî竱ߺœóÏÊuUÒ"¯”¥gví·ì­ûoÅöì%¼E_])HŠ¿¬CùŤ²ÊÁœoèÎù¾ù;!?¡oÔ¦wÍ}\ §ËNå§NƒI¥l‚óî’R8ÒËB�Ë£rSbŸ mÿ¾-óï·ùñùŸ Ͼ ß_H¸ âRxo)»d¥)Àö C_éKŒÉ]ä 9lÛœxìh}¥_ô´RÀ¨ÐÒÊ t#‰¨A``%;îú2“öÍ÷ΓöÛ{Ö’Ÿ¡ gŤb6%”Œž”4¾´ï“•™)+² …÷éä¯öèÙ.‚ú8å ˜Ž”p3’5Y±XçÕ¥“R’€XÒM/ô6,7þž¾/%˜k`-·çïõóyÎw,mµ^ˆ%LùN´‡A1ÃSÓÐ[o÷Ådõ§#fFýsú ©& åâf,¤>éGÿ$jY)FGñ#6gtü»¡Ò€ÇäÂÓ›!-þ?îsŒ 3|Ô’÷F²bú0ÌŒÐ0œKß––ߣçÄÔ”3nÜb³6fLgëŽÑWùò‰Ÿ†6û—No²@¦NÃyhãS‰…ìŒK¢³òOÞ¬¤”‚nÚIHÈèt` /éd¡%„§dò’Mæ²;aº°šBÛàѼš”þ¹}ÿ(3—’V/âà NFÝ?á™°Á»ÕdZ2 (˜œW!òöéF+!<²’ëd߀rpJ6Ì7(vîrˆ‘WùBa ¥ ¢XhF @h ,¤ ®[ä 5 Ad¦’—ÒÞÌZ9+  1”Ò„þQî^lŸÊ /ñ»wØÂŠÿ—÷Ö_ú_ïúÊÄ´)$ 0K+§·,›ŠOB\jJlŸ†¿OÓ€œ˜Ð2R¥Ë+“@Rý²RWèéºï¿éÙ³^ŽS–ffqe8¢¯ÀB &€,ÉJC;ÀÇ ‡t#!×V㌔€§¶|÷¨-( BVV%Œ¶[œŒê+©ÊÅt''ªô$Ò` ˆytìŽ^(…² È))e °Ï·ÄÒцÿFë®*J,jP‚ÃP‘ˆår~BÿåîMÅô¿IO‹†•÷t>ºÿÍûaÎÆ… sôÕþóÐÙ·_^ë}ö|¥/~ë“ç7åã˜Îr÷<îk:2@ÿÝXíòÖýiêêl`ÿ&ù+ßuü¥¯vø;«‹½Ë*¾~Ûý¿lvgâ³ý‚þÕt¥qWÙûúñÌo=5Ž«¬ÿ#þÛgÿ«mþ®QWÊÍ™×ûñJVVl·ïêé8«ìÙ¿¥efÁë~þ®”ˆ«å+6m·ÿ¶?³ñ}¶Á[j¸Š¾R”ˆ«ågìÊýø¥+¯¿S÷õtˆ«ågùÿöÛ?ý[loõtˆ«å~ûÿò_Ù›t¹ÙÝÕß©ª+3­þ=JfÍ_uºÔ©E_]fîgË籜õ~yøÖ>™Öÿ¥3fǯºÝjU\E_)JN*ùJR"¯”¥"*ýiF ÉAhBQùÜ'|®½óbÎÞÜM&PhfNßþ0#¼¿›äwK%óþêUƯIH/t%;Ÿ“·Ü;ªË¾cçWþ˜ÙDÔrŠÈèÈ éÙ)&¡Ë% `ÔâÒVB Å%ý· רA1< 䆕¾ _´|’Q+äaƒF©²¬øð†¿>�fL%“8JR[î„ôô ùéN/”#lÅ…mö½07Ñ)Š(›Ée§ Å%!½oñiR7J1(ãøÎ»äŠNüþvÝ_SoWý¤"±hå~Ù“‹ÉIdÔ`0Y1iá ïÒ3ï³vÖ°Å¡· G/n”!#JJ?ù(ÀnÃÌŽ“²Ðúò(È+ƒxo@j~·O!©ËGJ7JÓЀˆèNI]ª €M( %“r0iE#V)(GH@kᨠï²:qHCô+ë•"Ì;ŠÂHÕUú1CC0¥äÙ!“‰„¾Pz@l‚’7¡+d- ücûËŠ�°j6YA¨)a7»#—Ó¿ûþËìV+‡Ã�¾k–MHÿŒ„²zM@ ±cyh+”X rú6îŽR%m× 8¢gJ7ù8´òAxb%†„'l”$¡¼µ£ìHÚõùÀ­œKgWû<oÈA¨`ÂoÈ Ã†%ß•’Ÿ¿By@ ¸W³€À˜Ä’Ò0„ÐÐҜġ¿Éa›˜§÷éî1¯'ñe„§’J(–M¤¤éFGÛ}·Ä²À±%òmo B /td”C~Éÿ9]?c¶I ??ûð3ÊF­ã—ò„~Ê|UólPèè O)Ÿ„îR$‡ÃP•º ÉÝy’½¯&‡ÅúYr]£¥.ý mÕ›!Û¯^MÀøîÇFÈW(oØ$–RR_%òI_oÛ>Ù>ùÞãvù×{î»|#®ï$p7¸Œ`ê*úéYÝ»mû+~Ûñ}» oWztUò”¤E_)JDUò”¤E_)JDUò”¤E_)JÌíŸïÙfßŠÏØCøŠ¾ºR‘|¥fÃ6ÙÕ™þûþ'®®"¯”¥"*ûýy›6eºÝn!³*®”ˆ«ìùØõw?ã>[yÝNººV>}Ÿ?ßìoÙŸ°§Î&QW×JRqWÊR‘|¥)WÙûoöý±ÙŸŠÏöX¿µè …LÉd’ÓÒXkn„%)Û!/‘ÐWû«©vu®óë|¼Íß2ÝL·ù—:P5—ó}ÕÉÜϾRÄæíì\€ùÕÿMJ !‚VÐ ÒÊ#T™?¡¹M5)K·ÈA-ßê²Êá¥$²ˆîrÀ¾BIE%q<”3åàÂú0ÂòzÑy�Ð(Ž†å¤­Óºº6qhût qª9Òá/ÚÔ�lÒr1Eï¾oÒPB: ü¥`÷Û7Üïyx¾ç;aóë«û@0,¤RLFééÉ?2�¯JxÍ“þdòBsdû ʲaE‹/þJÁ›¥801#¶K’ÉHK¶ãJA,hÏŸÜЂ¶}ƒ@É_òƒR‘½<¤a®é=¶û£åp†>€‚Y-‹åï“ÀºðÁ™e–^ûtíМ¤³M%þØÃ˜qñWï@IE bä´`ÏñCJ)trßüÊïÒêÿ éjðñ3‹ŽÞœZTžå’öG(7¥ß ¶û§Œm—x‚`f& ­úr6Û¥±Çm•”u—fuþüR••›­ûû§¥ÿ8€¾U~àÀŠZÑú6oݶÿäöÓöÙ[++k›J]ÞŠ¾R”ª*ùJR"¯”¥"*ùJ͆m³«2ÿü?÷üO]\E_+?fWïÅ)]}ørŸ¿«¤E_)JDUò³»vûvWùöâóçú®‘|¥)WÊR‘|¥+ýY›7uºÝL!»®"¯®±óüùößãvîÝ…·atˆ«ìüfÿº³«öÄeÕÒ‘|¥)WÊV~̯ߊRºûðå?WWÊVnãÏù{ã»Nç|½F^ëVøþËcç+ŸŒ>QWÏØyû+~c üí—êë>Éß}¾ù¾ëßs>«ˆ«ìeþüì¥6=g:Í[)T[åænù–êe¸—̺ºDUò•ŸöÏöß›övÎ)û «œUò”¤E_)YûúñÌo=5Ž«ˆ«åfù+ßuü¥¯vø;«‹«¤E_+;·m¿eoÛ~/·a-êëýY›7uºÝL!»®QW×JÎêoZós—™lµª®qWÊÌæý×Î̧Q¼Ãù¼u]"*ùJR"¯³ý›³öÂû~Øz·â5])WÙ³9ëîæl§8ã²ut¤E_)JDUò”¬ÎÙþý—ömø¬ý„?ˆ«ë¥zQ“›¹§%(?|z>æ‡uŸª%|¯éÈùÕ¹¿íŸý¶_wÿ©µE"*ùJV~ÌzûùŸ­Ž8þ§T⯮”¤E_)JϜߗŽc9ËÜó¹¬tE_])HоR•Ÿ;/æâ–®®ø=MßDUõÒ”ˆ«ågìgëÇ1¼õüqüÖ:®‘|¥)WÊR‘|¥)WÙþÍ¿Ùûa}¿l=[ñ®”ˆ«ìî¦Øõ­›79]ÖÊRªéHоR”ˆ«å)HоVw3n¼e:ÌæãªéWÊR‘|¥)WÊR‘|¥)WÊR‘|¬Û![l¿Ô¥þÿ‡õñutˆ«å)HоR”ˆ«å)HоR”ˆ«å+7;-MÏQî£TËU\E_)JDUò³9»eó»©Ôf0ügWHоV}»·nøWoŸWøG«¤E_+-[s»-Í;œ¼~4úºDUò”¤E_)JDUò•Ž¿›–¦ç¨÷Qªeª®"¯”¥"*ùJR"¯³wsÕØïŒÝNyçå:ªéY³?õÿÏîi;²´¢¯®”¬Ù¿¥efÁë~þqW×YöíþÝ»á]¾|9_᮳ñ›þêέÿÙÿ—(«çví·ì­ûoÅöì%½6ÈVÛ/õ)¿áý|]]fï·ûçÇv|+·ø+ýW×JV~ÌzûùŸ­Ž8þ§Tâ¯Ìû/N³q‡s8úg[ìz–Ëu-Ut”Uò”¤â¯”¥"*ùY³m¿ý±ýŸ‹í¶ ÛUÒ"¯³}ßo»vâ»nÜr¾â=6¶Î¬Ëÿðÿßñ=ut”Uö6Û?Û~oÙÛ8§ì&®”œUö2ÿZöÇöS˜v=|þiÕt¤E_)JDUò”¤E_)JDUò”¤E_c¯å«nwe¹§s—ÆŸWJÆÏûgûoÍû;gý„Ê*úéJN*ùYþBÿÙ{-Ký¶êÂêë7qçü½ñÝ's¾^”UõÒ”œUò”¤E_)JDUò”¬ý·û~ØìÏÅgûý¢*úéJžVfïÝn¦S ~ꈫë¬ýŒýxæ7ž¿Ž?šÇUÒ"¯”¥"*û>¾î¼Êÿpï›á9ut¤E_)Yû?eoÏìa?²ý\E_)JDUò”¬|û>¿Øß³?aOœLE_]fù;}÷ß>ù{înõtˆ«å)HоR”ˆ«å)Hо[²S¸ÎJÿÍþä¬hÆëßäu±¯¬5ïݶû¾Ws»7ï—Ÿ6î9芾ŠR•Å_)JDUò•Ÿ9¿/Æs—¹çsX긊¾R”ˆ«å)Xùþ|ûoñ»wnÂÛ°ˆŠ¾|ìz»ŸñŸ-<î§]])WØÙ÷lû}¹»v|âÛ8ŠºR"¯”¥"*ùJR"���H����z¿óý+6ÙþÛ?~/¶ÏÇ«l#UÄUò”¬Ùý|ö7œ­Ž;ÇÄUõÒ½ß>ÿ»nß?XÏ„žÚ¢QWÙøÍÿugVÿ‡lÿˆË«¥'|¥fvÏ÷쿳oÅgì!ý\E_)JDUöw3ì¼~u:ÍÆÌãé»?åïŽìi;òõ]gví·ì­ûoÅöì%¼¢¯®•›lÿmŸ¿ÛgãÕ¶ªç|¥)WÊR±×²×¿;²˜Ó±êÇóˆ«ë¥)WÊR‘|¥)WÊR³çßoóãó>Ÿ|¾ˆ«ævÏ÷쿳oÅgì!ý])WÊÆÏ»gÛíÍÛ³çÙÄUÖ~ÃÏÙ[óûOçl¿(«ë¥)8«å)HоR”ˆ«å)HоÇ^ÍÎëSc”{¬Å2—Lë}RÝócÕ™n¥ª®±o×™³f[­Öâ2¥}t¥'|¥c/wçu)¹Ë9ÔbÙk«ˆ«ìý˜õö;ó?[qýNªºVlÆþ¾{ÎVÇcå}t¥'}™Öÿ¥3fǯºÝjU7}¿ß>;³á]¿Á_êºÏ·oöíß íóáÊÿòоºVm­¶_êRÿÃúø¹ÿ|œŸ({v|û}ÍÝŸ*"¯¢”¤â¯•޽–½ùÝ”ÆV?˜u]"*ùYœÝ²ùÝÔê3~3§Î<ýÕþ;¹„üwÊõrоR•Ž¿›–¦ç¨÷QªeªqW×JR"¯”¥"*ùYóï·ùñùŸ Ͼ ßUÒ"¯”¥"*ùJR"¯±óüùößãvîÝ…·at¤E_)JDUò”¤E_+6m·ÿ¶?³ñ}¶Á[jºDUò•ŸäoÿÛlÿõm±¿ÕÄUò”¤E_xÍ™‚3ÿöÙ»»ºýÔÝê)IE_)JÍÜyÿ/|wcIÜï—§}t¥gÛ·ûvï…vùðå„xоºÏömþÏÛ íûaê߈Õtˆ«å)YûúñÌo=5Žˆ«ë¬uüÜìµ7=GºS-Utˆ«å+7É^û¯å-{·ÁÝ\]\E_c/÷çe)±ë9ÖjÙJ«¬ÿ!ì½–¥þÛõaurоR”œUò•Ÿ¶ÿoÛ™ø¬ÿ`¿µ\E_)JÌæý×Î̧Q¼Ãù¼tE_])HоR”ˆ«ìùÇŸº¿Çw0ŸŽù^®”ˆ«å+7É^û¯å-{·ÁÝ\]\E_)JDUò”¤E_)Y¾J÷Ý)kݾêâéöNûí÷Í÷^û™ô¢¯®•Ÿdï¾ß|ßu﹟SöcרïÌýlqÇõ:¢*úéJN*ùJR"¯³9»eó»©Ôf0ügWJDUò”¤E_)Yûoöý±ÙŸŠÏö û^€š’Ý–Q3º¿÷OK!ÉHHÔdC¾ÿ|g³Ó«üÝÖ?’ÝŠÅ|éý6_vNÆ/9Û£ÚìâÀÊû$®^䲺:BÛ•ÒèÉJ;7ß|ý“ŸTX4½‘·èý Hħ”ü1!%r¿$}ÓÙ 5{}s³YƒÏ Ó«ý! ° ¾PVFÜ¢ÈA¹£?OFŒ´¯ä»åÞ\²Èy %`ħ'!CRÃSØj3u#•ÓÝ[ô³m½­„‚þåôž’WßîJ^êü7¾ZKr·ö²b@vŒ57ô%*t|ý‹É,f-ŽF|ÿ£ FÿÜlŽ£…¾'�oU_ÅØ4¼ŒMÛ¾ü˜MgWud3·_êV߸ÈN/oƒóîß+îßçÝ]¿^¾•€O^-$Ò†%?!;?RC2P€ÒùH%dð÷).5w’/¤jI‰+’щE¶ì[?P3åÝ)Su[¶Ên£9�{J¯óuŸöÏöß›övÎ)û «¥èÑWÊ͆m³«2ÿü?÷üO]]gs>ËÇçS¬ÜaÜÎ>QW×YøÍÿugVÿ‡lÿˆË«¤â¯¿'vZÓŸn®ÊpŽÝOòu¬ÎoÝ|ìÊuÌ?›ÇJ*úéYöíþÝ»á]¾|9_á®qWÊR‘|¥)WÊR‘|¥)WÊR‘|¥~ßuu/ýß÷ýÕÿVËSfÚ¢QWÊR“оR•›¾ßïŸÙð®ßà¯ôE_]+7·Î¼ëßpýÛáuq}›»ž®Ç|fêsÏ?)ÕO²wßo¾oº÷ÜϪé(«ågû6ÿgí…öý°õoÄj»rK(–„t²OF†«îÇd¶_ËeŽ”UúÈd0 Œÿ7ü’¦øÿ‘Ð…?rÒŒøö®šRXk£$®\Á™?”®WGἬ—q‰/7ùòZ¹cRû%?%$ͺyIJCMìÅn„£fFOAËKÝî”#†‚“ÉC Àe¶ÝÓ÷&q…ï²ìû¡A7—‘±8Ї¶ö•˜‘¼´üP ‹å-Ée·-»âÒ†6O/!†d7ÌÖ¾„Éhá¡»¡%’ÿBJ/ ­¾l„ÿÊH!‚Œû’3puÈiJC (a7Ѷf)$Ä„|޶+•›îYiFÛª]éËÜ Ô¡%“>÷ßò’‡JKåòÓÿé%|58²YYÀl­®bó²³�¼pšªÿ™’bKMÈGHjSô‹B³ò³#„0JéÉFtl÷¡Id²g@ÒÐ’ÒQX¾[–5wÁ‰É ãPÅ>+»ÑÚ€†“«“·JJ ž’‘²~d!ÒžYe·î7‘Ð×t°§’˜”„€ìb†:õœ@ÁxiE¸Ïºq)Íýc Û9œáß2U| Ž7È-8'0o Hhi}(ÿrM-!î3­§¾íýÍO, `Ü‚Ñùe¥;þPa/”žŽWû% %¡~ÏzÀ¡0²ae?Ût•W(1=•úqy#„í‹Oãr?ü±µÒ Ød"g B /$´¥‘Ë/ŒÝ7oɉû»¿éë[½Æ…õîaýYÄšª¿åÀP5¿Ð”–¢°kâZ_âñ#ýò†â†t ÈGkÆìÆþ¾{ÎVÇcïѲiH-”‚€ÉEbÉ¥ÉXÛñ Yèß'rú~íÑ|ÐÄ2’Cíƒ6wåþK/†þZFŒFBÿØ%?¿÷¦œ¬D˜}‚lû¶}¾ÜÝ»>qmœE6ÈVÛ/õ)¿áý|]yO‘·ß6Ø’5ÕŽO ëS§oþv²^dz«å)J¢¯”¥"*ùJR"¯¿#nû1êÊÁ=ÿû+ÿÖÿ:øúŠV>Ÿ>ÛünÝÛ°¶ì"QW×JRqWÊR³ñ›þêέÿÙÿ—W×JR"¯³fs×ÜÿÌÙNqÇe:é³ýû/ìÛñYûWIE_+?Èßÿ¶ÙÿêÛc«¤â¯”¬û'}öûæû¯}Ìú®"¯”¥"*ùJR"¯”¥"*ùu’ûÐWå¨#ŒéÛŒŒåäee²Yó®æí³ý¶~ü_mŸVØFºDÔféoßdt!ü¼êGº—òþÛ'þÇë,9çWý !¤Ä“q¹)IjB »’ºpÜKHbSò¿Ò„!|Jëºh¢Éœ¾5Ü3†£”Ž’™=-Ò”öÅ|Ì„ Ù;5A ¤#„’J Û%€ÂJà `W OË’ŠOÿnÛê¾ÒMû†rQ¸ J2S¿Ø7¥º A|²À¹Y™Ò[¾¾k!nqÙj'e»j¿¦œ‚`bC‚€é½âÆ%)ÅþŠèt)¬3–œŽÝíi/ò¹+áÃrI¨( ü’à /e~‘»$›’7}þJ½ˆEVFAE¤3€Ü–vìåo‘±A¨Ý¹,„çўƺ0@g”¬ŒZQØ´’òyd”gøn΄}Ææ×ýû?üÆý”Кªû²ÃŽ‚“ò EŽ5?àÏœ1 NÝ#Cž—d£òònroI7§Üš€ÔRw o‘òvN_Øbä Imy€ÂhìPn(0jR0™ÊÁÈý=‹)!…l”ºFrÒÝ 2à“CC�§`2QhAEn‚jKJ>ÎPgÄÂÿ©%Š@Ü”~”÷†GãŘ%|è«þ„…¥Ò”$ 15$·ù( A0™Š,gìÛ)þ3mPB&† Ä"ÀÀg@oéÁ¨°Í¿K6Jsä0 îrWa‰I(å”P À¯F(n%nZJèFNá¥b[td!ا{Ñ`0¢%»Œ É÷ßRRŒÛrV/% ^KgʰËCŠë 8>u5Ê) ( )nPÞ¡¼ î†f&¥,’ú™Æ Úó‰àá¨/t#¡ÀÊw% j_FÅä¥%â÷K+ðÝ»§÷»aˆïLI1”ZJÝ%'ô§##á© O“úwß¡)ïµÅ&ôJ+r,†”äryüžR7‘Æn3 ‘Æ!()òõ®8Wó‘žUÇ�tŽB&3÷) †b¿Ù·I)öÛ;ö|Ç:®+bÐÉB“–„·?/vÿqÝ_H€i76ÊãwÁ™‰ä­ÂI1<¾J-@YCQ–›æÕ§/‘Öy¯¼omÆwìùÏu²oÎSÔR¿äº¾e¿4$ãò°îµuÓWÑJÆÏûgûoÍû;gý„ÕÕ|¥)WÊR³çßoóãó>Ÿ|¾ˆ«çϾßçÇæ|/>ø/}WJφﻯ2¿Ü;æøN\¢¯®”¤â¯³ì÷Ûï›î½÷3êºVw3n¼e:Ìæã¥}t¯~„:Wö~1m–ÈÃxŒ¿QWÙû2¿~)JëïÔýý]fÛ?ÛgïÅöÙøõm„j¸Š¾R”œUò”¤E_)JDUò³l…m²ÿR—ûþ×ÅÕÒ"¯—Hš¡Ÿ8Ü„ ÈÅþ™.~Ûôö~ûvk›k,¬Z»³rß|—$î•÷ÍÖ{Q§Wý@4š3’nÅ ”žå”œºRVFå}ÑÒ²Ù*÷¨Åß×· @åÕƒFÿÓ˜¿“ù{bY/lž„æ¼aaˆ 0¢÷ Å’M%”Ž®‚Ae€ hÐ?²ÿ$"ß±4_JQÊA+’Ãpa0¼VrY3’˜¤¥Ûlù²þ×Ì«¾Sçs—ŒYN<ûj¾†�ì7å å'‹F-?%ÞŸÿ·)?$!9 ¹EcõíNÒa5< ` ²wG‹ Á¨ Å#ä|œß#ýÂF{ɉ¤ÌMNß'røi) ép3Ëá©(7“sö²r^”šbOèp*Á )ãR‚ñ(4=#vGà +tä¡xiÏcûfß)Å0çWPtêýê,¾Mß–•§p0ŒŽÉø•ÀÇÜ4 ¥()9!ˆ/ääöÊ÷0¢˜3¹E$•ÒĺPnQnZ>C\„:KÝ)ê%+'µ`Ü1Ѱa1ÒIJ>q»‡èø Ò€ÉIÈÃ2?}v²K, ÒH]$¤ä222HÅ¿bÛâ¾JSÒ77ü!w åöû>¥qÌ£§WùDB€`ž2P„ò¸bpaEñŸ jYwFNtïù,´«f½v/ÃwYAˆ pÂÉ»ôüRZRW á)Q/ ìŸ*�lö(5„'Œü´á› –—t#$²€Ï åí‘Ñ‘ý¨˜Xa/YdÌŽŽ‚ÊÅt#ÿ†·Èd·à%FI(½™2%òq«ëw�ë_扥“CS¾/$¾ŸXbƒ::Ix­²RŒž‰Y€ÏѾjÃq4’¹]<˜ŠÙ+/6+>!á¨(bPÏ‹Ù#z¬%`‹ü´V O,404j{§ ›ö nÝÝ=#fèÞç– HFBI½<¢òw!æø²gÉÙ*HJ7 AjSÿ®†ûf[® R„‘©«ù &HnÄÂPf/oòCp@ÂòÆm‰L¤„¡9–]ò‹ÛBÿ-ÐRw,§/þÆ1,%‘Ƨr¶ÃP3l­x‹éi‚„ ±«ì[åfnýÖêe0—R羚”¬ØfÛ:³/ÿÃÿÄõÕÄUò³íÛý»w»|ør¿Â=]"*û7}¿ß>;³á]¿Á_êºÏÆoû«:·ü;güF]\¢¯”¥'}™Öÿ¥3fǯºÝjU])WÊR‘|¬eþüì¥6=g:Í[)Utˆ«åfÌoëç±¼ålqØÖ>®‘|¥)WÊÍ™×ûñJVVl·ïéÝ»mû+~Ûñ}» oW(«å)IÅ_)Y³9ëîæl§8ã²uq}޽–½ùÝ”ÆV?˜tä¤6@ÌÙ›6l0æÇfläîݾݕþ}¸¼ùÄ>«¦*ÿfJí€*R3dmØ®ÁŽQiI(–œùã û£,ÝzÀ€§òÊØ´a©È Ïÿ„‹ &âHJº ãR•¶¾dMC¡+ûý¶íËÈK„$”¼Ÿ»±‹í¯^MJ !£—ºIXi}‹`„/¡ tb¤üWá;?‘“y(9dñ+Çã-*ÿ|^äÒ“ˆ|š_ጀ΄d%Im‘Ò”ìÿ é)% gJ_[z93bË(1e$²W(ÐÐ :Ÿ';„§%?âЛþï;‹á£vJNG·-c„äLAl„†,”‚‰yºRœÛû/I#äýɃöÙ0Ô' ¢°OåfBR’Kä¬5µã°ÇPõ÷cñÿ“ÄZUþÀÁ„Î’f¶/#ðì90¡©Ø°·@Ü[”3þWBQ·×l0¾Xa})-‰£ ‡€Ü445 ÆŒJP7dq˜á%3§=äPL Åä”jpF $š[r_-º7ýÀ,Ù `ONßÞ§ Á¨%ôA¥ŒI{—‹J {$™Æ 0o+ ZW×—³\ÿõí¶ên%s«ð†bW@×!bèJ?èA+nœÿ¡%tòY-.ý>¬¤€²‹é+J+`Ҡģt”† +%; ß~ïþè÷£& šY+§ƒ2B“º’YYƒyICù_ôfù‘þ°—ÃP݃’ƒ›”WGrËÈNý?�Ýü£w Ñæ»ç_u¯:¿Æ·B J J0h JRR~&”Pؤ¤oéÜ´£†%?†àŒÖ (Xi4H(3æJRÔþV/—€ðÒû¥%§”0¼ŒÓèdåmðÞ„!ƒz0hc¤a4‡Ì”7GIH%r¿>ñ 0!�ì™úI…’q)†8FK jQÀ¸fù]tÝ¥öüQ‚ˆuÓWð@ gÄÐÔà“†2-?ï²xÍ‘Ÿ '—þï)Y¶B¶Ù©Kýÿëâêï©ýV}›¸óþ^øîÆ“¹ß/UÒ–²«å)HоR•Ž¿›–¦ç¨÷Qªeª"¯Ÿ;®çügËcÏ;©×WJÇ_ËVÜîËsNç/>QW×JÍÝÏWc¾3u9矔ꫜUò”¬[åfnýÖêe0—¾ºV³oö~Ø_oÛVüF«ˆ«å)HоR•ÔÛµ³fç+ºÙJTE_]gϾßçÇæ|/>ø/}WHоW¿Ýk~Ù‘Ô§_^3­Xì}E%}› ÛgVeÿøïøžººRqWÊVnæ|¾{ÏWçŸcêâ*ùJÍßo÷ÏŽìøWoðWú®"¯—H¼R8Ô§¡L²Ò„œ7 íÿìã7ÝW6”Å_ôĀ貰aH@o Û|»rYAŸâXj A(jYÆd –Œ—Ý7°I0–V(4²±i, Î’BÏþÈá…¡?’3ž{9_m|)(ÉÍÜÓ’”¾=sCºÏ×w€À®ÉE ÜgÅ>Kä%%~0%›îŽA—‹_áæœâí*ÿ­P�˜˜Ñ„þMèNÿ%8IIÉáœkPIhg%^÷O†@ª&ò¹a;'˜h3|JÉK–¬ZÊI[$cûåÈ7 Bw-)b‹åŒMÅ ù)ä²ËÎ퓸Ô|‘¶kZ@¡E•² ˜„:I8¤ºQñ,±€7GÈB í—Ôž¥ÞhÕÿ¿ 3®¯÷�:&”Y7—À-Ü45ÃK)t”XÐý<¤|VØgßr ׂ‹A <ÂW Oå”Rq]Ü(FA}áŸ'á»à³\$�€Ô%?†çJw(¤þ‘»–èA}?#„¡¸À.¿y|drÒ’hÀ×ÈÙÑÕ³þ…¥.ŽŸÓ‘Îì{fº9m”ÙÀhr¿e¼ªþ „ÐÅ%÷f-*á%%ß~Œ5¨K«w~KÿÞ3##ÿ³9˜ãÿýŽÿÿ³óh13”Û»ü£Ý.üK¹µ»ûƒ •_)YoñêS6lzû­Ö¥UÛʯ±—ú×¶?²œÃ±ëçóN«¯Fû,zy'¤ÿùýaÇc²µD¢¯”¥'|¥)WÊR‘}Œ¿ß”¦Ç¬çY«e*ŸvÏ·Û›·gÎ-³ˆ«¬|û>¿Øß³?aOœL¢¯®”¤â¯³á»îë̯÷ù¾—OömþÏÛ íûaê߈Õt”Uò½úÙ}—Û|§ùŸ©jû?×QY¶FÛm¶Í¶VÛ´E_>v=]ÏøÏ–ÇžwS®›ä¯}×ò–½Ûàî®.®‘}Ÿ8ó÷Wøîæñß+ÕÒ“Š¾R”ˆ«ågÎÇ«¹ÿòØóÎêuÕÒ"¯”¥"*û{­[ãû-Œ;œ®~0úºV}’¯·^ëZ÷}úð¹E_?mþß¶;3ñYþÁjºVm‘¶Ûm³m•¶ÆmW×JRqWٸݾuç^û‡îßë§ÎËù¸¥««¾SwÕu™Íû¯™N£y‡óxéE_])IÅ_)JDUò”¤E_)JDUö|ûíþ|~gÂóï‚÷Õt¤E_)JDUò•Ÿ;/æâ–®®ø=MßSº›cÖ¶lÜåw[)J”UõÒ”œUò”¤E_fsvËçwS¨ÌaøÎ>®³fëÿŸÜÒv;ejo»í÷nÜWmÛŽWÜG”UõÖnŠZ²ópå·}WIÅ_)JDUö-ú³6nëuº˜Cw]])WÊϲUöëÝk^ï¸w^WHоR”ˆ«åc¯fçu©±Ê=Öb™K«¤E_)JDUò½(Ëù¾êäîgß)bsvò:öZ÷çvSv=XþaÕrоR”œUöo’½÷_ÊZ÷oƒº¸ººR"¯•›1¿¯žÆó•±ÇcXúºDUò”¤E_)JDUö2ÿZöÇöS˜v=|þiÕt¤E_)Yû1ëìwæ~¶8ãúUq|¥cgݳíöæíÙó‹lâ*â*ùJR"¯”¥"*ùJR"¯±óìùþÿc~Ìý…>q4Ù‡Ÿúÿç÷4ŽÙZ®’оR³fuþüR••›­ûú¹Å_)JDUò”¤E_)YþÍ¿Ùûa}¿l=[ñ®"¯±—ºÕ¾?²ØÃ¹Êçã«¥C÷ß›»7}œïöv5ZQW§víöì¯óíÅçÎ!õ])8«åfÌëýø¥++6[÷ôuìµïÎì¦4ìz±üêå|¥)8«å)HоR”ˆ«ìuìµïÎì¦4ìz±üé¶B¶Ù©Kýÿëâé»íþùñÝŸ íþ ÿUÊ*ùY¶ÏöÙûñ}¶~=[a®“оR”ˆ«å)HоR³f7õóØÞr¶8ìkWWÊVm‘¶Ûm³m•¶ÆmWWÊR‘|¥)WÊV|ûíþ|~gÂóï‚÷Õq|¬ÎoÝ|ìÊuÌ?›ÇSöcרïÌýlqÇõ:ªå|¥)8«å)HŠ¾Ìæý×Î̧Q¼Ãù¼u7qçü½ñÝ's¾^«¤¢¯³öe~üR•×߇)ûúºÏòþËÙj_í°VWWÊÎíÛíÙ_çÛ‹ÏœCêºN*ùYó›òñÌg9{žw5Ž«¤E_c/u«|e±‡s•ÏÆM²6Ûm¶m²¶ØÍªë7·Î¼ëßpýÛárоglûnËÛ¾ÜWlâ[UÒ³üÿûmŸþ­¶7øŠ¾ºR“оR”ˆ«ì|ÿ>}·øÝ»·amØE])WÊV}’¯·^ëZ÷}ú𺸊¾ÍÆíó¯:÷Ü?vøG]])WÊR±×òÕ·;²ÜÓ¹ËÇãOˆ«ë¥)WÊR‘}á¾R[çÊíó'8ï•ðw¨¥%|¬ÝÇŸò÷Çv4Îùz®“оR”ˆ«å)HоR•Ôßµ;æç/2ÙkTE_])HоR”ˆ«å)HоR”ˆ«å+Æå­ÛíÙ~Ìû?Çî³²úª%|¥)8«åc¯æçe©¹ê=Ôj™j«¤E_+?mþß¶;3ñYþÁjºDUò³wËߨÒw;åêºDUò”¬ÿ!ì½–¥þÛõaq|ÝÇŸò÷Çv4Îùz®±óìùþÿc~Ìý…>q5rоR”œUög7l¾wu:ŒÆŒãêëýy›6eºÝn!³*®QWÊR“оR”ˆ«å)HоÌíŸmÙ{wÛŠíœKjºV>}Ÿ?ßìoÙŸ°§Î&QW×JRqWÊR‘|¬uìµïÎì¦4ìz±üèÙ÷lû}¹»v|âÛ8йE_)JÏŸ}¿ÏÌø^}ð^úq����ˆ����z¿óý+3›¶_;ºFcÆqõq|¥fsvËçwS¨ÌaøÎ>®"¯”¥"*ùJR"¯³¹Ÿeãó©Ön0îgWJͶ¶Ïß‹í³ñêÛÒŠ¾ºÇ^ÍÎëSc”{¬Å2—WIÅ_)JDUò”¬ùÙ7µuwÁênú"¯®”¤E_)JÅ¿VfÍÝn·Sn눫ë¥)WØëÙ¹Ýjlru˜¦RêéHŠ¾Ìæí—Îî§Q˜Ãñœ}])WÊR³ñ›þêέÿÙÿ—W×Y³:ÿ~)JÊ̓Öýý]"*ùJž^fï™n¦[‰|˦Ìëýø¥++6[÷òоºR“оR”ˆ«å)HоR•ŸnßíÛ¾ÛçÕþâ*ùÝMñëS¾nró-–µUÒ‘}›3ž¾çþfÊsŽ;)×WJDUò•Ÿ ßw^e¸wÍðœº¸Š¾R”ˆ«å)HоR”ˆ«å)HоR”ˆ«ìønûºó+ýþo„åÕÒ‘|¥c¯e¯~we1§cÕæWWÊV}“¾û}ó}×¾æ}WWÊR‘|¥)WÊÍ÷}¾íÛŠí»qÊûˆôηØõ-ß6=Y–êZªå|¥)8«å)HоR”ˆ«ågÃwÝ×™_îó|'.®‘|¥)WÊR‘|¥)WÊV}’¯·^ëZ÷}ú𺸊¾R”ˆ«å)HоR”ˆ«å)HоV~Æ~¼sÏ_ÇÍc©û1ëìwæ~¶8ãúUrоR³wu|ÜRÕ—›‡-»êl3mY—ÿáÿ¿âzâ*øËýkÛÙNaØõóù§UÖm­¶_êRÿÃúøº¸Š¾ÎêmZÙ³s•Ýl¥*Ÿ8ó÷Wøîæñß+ÕÒ"¯”¥'|¥)WÙ»?åïŽìi;òõ])WÊR‘|¥+6g_ïÅ)YY°zß¿ˆ«ë¥)WÙÝM±ë[6nr»­”¥UÒ‘|¬eþüì¥6=g:Í[)Utˆ«å)HоR”ˆ«å)HŠ¾Í²6Ûm¶m²¶ØÍªéHоR”ˆ«å)HоR”ˆ«ìlÿ¶¶üß³¶qOØM]+7wWÍÅ-Yy¸rÛ¾”Uõ× ¤Œ„##c²6ÛeT[É¥ðÀÄ—7£~΄¥?m±ÿó´ñW×ËÈÿ|• jŸ˜WÛïÀy‚E^¤šÊèØ™÷J—÷-óð0øj28× JNnÇÙÀn‚ÓÑÒQ- Œ•!»çNNO åŒ+£rNèÿТb ˜´èù.Žò�ÏÜfPÎSàœPͱíóÜLë0H¸šªù€3 J?ÅÿÙú0acw^óèN|èÝ•qHDÜC+'6톡ߔ–ß”‘ß÷ÛŠ½Ù ,K OÉÙ¡<±¨%Œåt„W,d¾- q©1®J�bLèCî„þèéØ¿Ðà%éJ>‘ž„u˜û‘€Y7«üE-x½ûgùØn^|5ò™–íŸìïd½**ùJRqWÊR‘|¥+3­ö=KwÍVeº–¨Š¾ºR³mŸí³÷âûlüz¶Â4E_])HоR•Ÿ°óöVüþÆùÛ/ÄUóüÿûmŸþ­¶7úºR"¯”¥"*ùY¶ÏöÙûñ}¶~=[a®‘|¬ÝÌù|ö3ž¯Ï?ÇÕÒ"¯”¥cgݳíöæíÙó‹lâ"*úéJÇ^ÍÎëSc”{¬Å2—W×JÍÜÏ—Ïc9êüóñ¬}6¶Î¬Ëÿðÿßñ=rоºÍ˜ß×ÏcyÊØã±¬}]'|¥fù+ßuü¥¯vø;«‹§ã7ýÕ[þ³þ#.QW×_ÿß)GŸ÷ÿl­º—ß¾fDŒÍÒÊù¿e~™ÍîÂÝ®°Ð@á¬~Ü´~“‹G%£º{m“·n²Ž£)Õôóp.–å¶÷é[g@ÍŸb^nƺýÝØ›“öî‘©ü¢ËJ ¹,1,Yx¬w)hÝ=öÏB&•°(”„`Ü7R!t'r°ÔæßäŒ@ïûP²ö !#:úr0nJ_8Ä÷ÿýùIOBYËS¥•îÝÜQÂÇÕWûŽRĉ¥ÃSÀrÜ¢ú9e`Ð.†è%'ýöLJû{ZKü± d ônédnQ ú1i&ÈH|Róî’—Óú6öà† ±H Ø ¤®PnA[|[  B@fd£þœ­²’Õz.d7¶%þ’PBXc‘Ù)èÿ°Ü”†æÿoÙµàì¾;µ™øò%­_áùEC#>Å‹I{ƒy|¿’ÉB�-éBzS¸×-==²jI¥rÃ�Ê@ÊwÙ%äþ„ O@a3RWåîØh߯^‰ `ÒÐ6HJ­‹(°ÆF ÝËÅb_ NÙ)éáŸÛÿï*‹@Ä€ÂÊáŸ% åd—º_”P3ô~_%‹B1µ¸žÌzœžµ W•^‰ ,˜BBK&¤5 ÏŠïÓƒ9IÝ%ŒFOøhgÈß#þð€P7Ððj:Á¬‚ú¾”#³u³íŸ>Ç_I¹yÊ, ô ˜’û,¢Cñ„Þ”ìWrRÑÜ®ÉïöÕ!¸´“Iœ7„~JRèÈ(a-9$Њü –ŽQH/œc¾×[e³b …,Êjÿ‘îæ|¾{ÏWçŸcêïQ€vL,71a‡ŒGûq£p ÉfJ[lÏùIÍÙW—½¦³«å)KIUö|ì¿›ŠZº»àõ7}WJDUönãÏù{ã»Nç|½WJDUö|7}Ýy•þáß7ÂrêéHоÇ_ËVÜîËsNç/>®”ˆ«å)YöNûí÷Í÷^û™ôE_])Y»íþùñÝŸ íþ ÿDUõÖ-ò³7~ëu2˜K÷U]fÙm¶Û6Ù[lfÒŠ¾ºR“оR±×³sºÔØåë1L¥ÕÄUò”¤E_fÌ<ÿ×ÿ?¹¤ìvÊÕt¤E_fÙm¶Û6Ù[lfÕuÔßµ;æç/2ÙkU\¢¯”¬Ùý|ö7œ­Ž;ÇÓ;gûö_Ù·â³öþ"¯×ß#цì¶~Û·NGÈÎVÛ ûtºKÿ¡H•’žŽ²”RVmß'§ä—ѳãóTRZ�JVÿ„§°Áˆvnø½Ù=++ä¼÷¨9X7•€, !“TVé˜%%ý÷pÄq‡'’zúî$ ìj«ÁH( “2>û££drÊà ¤Çt#•œ®ÈY) î¿÷4ÜQ,¬éØ1¸²±YñºK÷-ûo¹Ê½)E”Zv OÛ'¹ ÈE“C@l’¾FÈ,´ó’ýô'³fÞÐ*M(”LH Ñÿ ( ±y=(ÿŒØ½É‰I} ”ö BàfZRÙ»k'WWÖM@hÂÉ|²^AeºKC#·)®‚bqE–ä¬ÉIë{¼’bH&–Š!”’Q7nãzFþ”„£q¼7b[+ªæ'd�x598¢b tؾR2rP„ `féÛ%9?ìŽÍÿòJ(\´C–”–Y1?;F@iI)…a™c@³£³äýa»·0rŽ5ß÷ç°ùÕþ‘!™$À”L`’RKB¶~ܬ„u¿KddCJû§£?Föòh À¡HRVLmÉhGHi7äœxjú i'à„ŸlB’ƒPÁ„Þ5),0˜Œ™=8 Œm¾|Lã>Ép†ÈMÖ¨Ie#1YüW!EòËN¾Ÿ²pNÙÊó{Ë5øsñ(Kºêÿ˜âø q7£’ÆbRB ½;d—· C'£à„²ÓÛ'íÆÞ….}ÃvÜ7b‘Æ  I-’”¥šò~J{#¤­ÔÉ}X„¿Ä  ƒJ^%¥ :Oéè%à„nŸ²�¸Ìjò=æ¸ e‚Xn (”€1“ùI<ä!ÐQm¿Ü•øa,b7šíq†u­°àõ“é«ôQdÄä±iå2 HBC è G)(ÙbZqiOC£Óûï||0š‚nýÛ±œÍ÷ß¾èù;îwZï«€Ä £§ri[bÊä°ÞW&|å O( rÃ]%쎅çkÊçlV9!œ½ƒ / –Vû'ö/bú~åeüg½QãÈæ…E_á)J^Ý_)JDUönæ|¾{ÏWçŸcêéHоR”ˆ«å)HоR³ì•}º÷Z×»î×…ÕÄUò”¤E_)JDUò”¤E_)JDUò”¬ý™_¿¥u÷áÊ~þ"¯®³íÛý»w»|ør¿Â=]"*ùJR"¯”¥"*þ±î„£$¬œ3 k0Ñ Xnû©)Ì¥%Þ¼¾€t´TrŠû“yjI(aYɽ} ÝØjz[;{À§§`¿Yÿ ÎËÈI­„,Uö2Ê É€SŠå§~”dr¹iÁˆÝ‹GAvFJC¡kËÍÏuŽX‘ÆWWñ’WäÂÓÊ!%ƒC?rù4¤  _IcILLÿ’SüκD4WC§ B GÉE0bPi(3~…%JC13¡/›à›¶RI‰,”Žö 冩!œ¼Ëḿ†•ÐWHjr“‹%o·]Å,8%†pÀ1ÀÀné%ô…—tì3à/·%~èß¶Û^{0£Î<Ó‰ÊuWWôyXa¤À߈\´àÇ&t ä€R5Å$´oÀr5 ÿ—daµ¡¤Ô“S�ܘ0ŽƒK%„á‰ACJA5±[ì0!ÊÇ{? %º~J€“ ¤2PÎZJAx¢‹,˜Rº|åq›0Á‹½à KA4 ÂV+-$Ì÷b‰nVI|7lÝËJÙšäFmòØVâ¬uU;ñ`Wpi7æBF¡)Üš1(ᘽŠFfØ ¤·ÿŒR5Ú å%84˜ZCS’Öé/p²zFwÙ?ç””_ø'˜6È0�û–”£ü4·N dÈIPGaˆvÃJîÄÕÞâ�À _-ƒq0­’ÒËÄÌŧ f~ÄüPܤågò^Ã…f0QWò Ÿ(4b:J à6é)ÀÆÅr’Xj2“’“Æ¡(È-3?×n 0YiŽ’¾ПÊOtQ($hÞŸˆ¿ÿ¥ïK‹I@6&Q÷HΤ† ”‚ZV„† ߌ,¼Ý«½Â¸bq\40®ÿn_á¨ý5Ô `h8Þ”™²Ý¾º›÷adu©gŽU5 0²],XKpÏ€©H~°2‚øbR€’[3lW)ú>kšB Ìœ„`ΟðÌŸÿéF,›“Êù9ËÜ®0gFßýŸkÚ'‘ :t 0˜Z~,4˜Kå¿Ù Ò5† '6(1¿ëmyÐbj:ðÎŒŒÝ|Å>Ø´í³JI_†Ž÷{¡;x~<;áË*¿æÔ¯B-Ÿ·OÙŸ¶ÎÏù†þ¥=EîÙUò±—ºÕ¾?²ØÃ¹Êçã«¤â¯•Ž¿–­¹Ý–æÎ^?}]"*û3¶¿eý›~+?aêë3¶}·eíßn+¶q-§@Üîµöî¶ë[m³Vß÷¦*ú)JU|¥)WØëù¹Ùjnzu¦ZªéHоV-ò³7~ëu2˜K÷U?Ù·û?l/·í‡«~#UÊ*ùJRqWÙ¾ï·Ý»q]·n9_q®”ˆ«å)HŠ¾Îæm×ì§YœÃ±¼u]+­{cû)Ì;¾4éE_>v=]ÏøÏ–ÇžwS®®”œUög7î¾ve:æÍãªéHŠ¿)‰D¬R)hv)N„7@Çl?(ëÙ€‡r†lZJnè(®_p„`0Û ¡ˆwBv(½ú¿kç·¡á‰ä¤g+†9Em¸ÌÅ£'–3l4¦oÂG.äÜ÷#‘ÇÕWý'boA43@Ñœ®ìWù.‡Ü¤Ñ· JŠ Å’²Ê|úúA7â±H-¤’4`Õ0C�Û†£¾J’’ØjJÇ·é¾nB@a1ú8Ð(’þ (¤>èJFt HÌž7äô!fÁ(®Y0”„ÊNN9á´–È(¤8ÂÜ´ŒÅb¾t–÷ÍöOqd^Ú¯í�Õ’0˜²ÆüJ årÐS Nü°ÎRyä™°B{ö©!ƒ140„”oˆim†oÊéF ü1=,Ý%†ì¿ùú½æz BSÒ’M)(BQ²1etbË/üJ’Ž„Hb1éFvô`Òå Ÿô$´¥%d|BACŒ JþBRvéJ21HÏhÿ­úÎ,R«ý¡H ,„”$¬ŽRII,²RPðJ‚–”œZ9î]Z@§H`Ô€¡Æ¡9†áˆ A)#[âVq¤ß›~Vu^i%2xiD²gII &–Æ£ýùA$¼C@ÎŽžœ€<Á5… û¤¬LéA}ùn–ÿ(˜MØ3tô~SíÊûì‹'[Nû`NØ\êþ„ÐÄ�Ù$¢i$0¤#aŸl3tvB”YeòÿpÝñˆÿÞl–Kû”CÒrP„nL%>O,™¸ :F @“ŠJ6Ý}Ól Ž (¢Èe$41$>’bŠÁ‰Û'!©éÝt²Ý§ÏýH�¨Þ’±X3çOA†Á£P”‚FG,k³Œ7jÇ·µáäæ4ÙUü¢ ©á¯÷Ia»âÐLJ2€Äb¿ø–^nHJ€ž”òEäÀ`Y]Ò58oY\0¶ü Õ±Ûî”ÑùÎÝïa€t„÷(„B+dÀp‘Ÿ–Ê,š”þžÌ¹Y3Я|©¡Fm¶ý?þ{»¬rÿÿ­ïUð°`#E^›ä¯}×ò–½Ûàî®.®”½k:¾R”ˆ«å)HоW€á Ý-•ÿls§¯ñÿ‰õ”Uò”¤â¯•Ÿä/ý—²Ô¿Û`þ¬.Ÿ¶ÿoÛ™ø¬ÿ`¿µ\¢¯•ÔÛµ³fç+ºÙJU{¿;©MÎYΣË]\E_)JN*ùYó²þn)jêïƒÔÝõ]"*ùY³í»/nûq]³‰mWHоR”ˆ«å+?È_û/e©¶ÁýX]\E_)Y¾J÷Ý)kݾêâêâ*ùJÍòW¾ëùK^íðwWWWÙ³ýû/ìÛñYûWJDUþ `0àW|Kû»|ùJ›£í÷NOß'a­šõä4'„ãÀï’‚ÐKø$¾Y5,_ÅbZ xj¯|³ì•}º÷Z×»î×…ÞÌä!¼¦ éFÅäâ†äòYe:6A43¿Jz_fy…%œ�y]_ëIŒ‘È[‚XØ ¡0²»$ `Ò`è)'†«¥)A·!$.Y 4–„•‹B6@ÄŒ”‘ƒ>ÿpÔ–œ^FFOà]Mk�«”PZzQ’ò�É-¼¾KÅùEä%‹+mÊêXÞß\"ŠäÅdºQÐXa0´Q/7ØbƒRWÿ/)~w¹:XÐþ9ƒ÷jªÿBya d¤ƒv HÆ% n OII BC9y(YE§%Øþná¼µ i4™¹1=A{n’Ë,é%“2·+XıÉßÞL²Y0šÄÿŸmö! ,7¥(-?dlŸ¿FÈJRPÃWN‚i\¬øahdà‘½ î²û)ݤ¯,¼©fS¶ýñ¹±Œ<×:*þ‘¢ JS‰Hœ !#ä%ܬŽ@ßÀ¾NJs>û=“v!‚ÈI/òÃpnADÎ^HP”£`'’†ÖÙ¿öaA¸›Ëèèý$„l„’ýËOIy= qC7¤$mçŠ!b’5Â{ ¶Gaªe¶éJK?¥úÓò®Ÿ÷eŽnýÇIUö` ´„#|’ÓûÜ4“÷uö_pŒ3*äí‘¶Ûm³m•¶ÆmWKÓ{:¾ÏÙ•ûñJW_~§ïêéJ⯔¬û'}öûæû¯}Ìú®"¯”¥gìgëÇ1¼õüqüÖ:"¯®”¤E_)JDUò”¤E_+?mþß¶;3ñYþÁjnãÏù{ã»Nç|½W(«å)IÅ_gÎÇ«¹ÿòØóÎêuѳþÙþÛó~ÎÙÅ?a4ÎoÝ|ìÊuÌ?›ÇUÊ*ùJRqWÊR‘|¥)WÙøÍÿugVÿ‡lÿˆË£gý³ý·æý³Š~Âjé(«å+7ÉÛï¾ù÷Ëßsw¦svËçwS¨ÌaøÎ>"¯~3|žÛ’7ìþVâû(ÞÕ¬ØfÛ:³/ÿÃÿÄõÄUõÒ”œUö}»·nøWoŸWøGµ¤˜[(¤¹îÜãß,€¬:ÁJ_Å_½›#¡,œ—†l…à–BÔžÿ¿ýÿ]œbÙ»¿e?a‹cÔ=Îê)}Ÿ±Ÿ¯Æó×ñÇóXêºVnŠZ²ópå·}8«ë¬[åænù–êe¸—̺ºN*ùJR"¯³ì•}º÷Z×»î×…Ów3åóØÎz¿<ükWIE_)JN*ùJV~Ûý¿lvgâ³ý‚þÑ}t¥fï·ûçÇv|+·ø+ýW×JR"¯•›ä¯}×ò–½Ûàî®.®‘|¥+?mþß¶;3ñYþÁhоºR‘}›Ûç^uï¸~íðŽººR"¯•Ÿ°óöVüþÆùÛ/ÕÒ"¯”¥"*ùJR"¯½?£>δcMû:·ê<æö]EfÙm¶Û6Ù[lfÕrоR³9»eó»©Ôf0ügW8«å)HоR³l…m²ÿR—ûþ×ÅÓ»vÛöVý·âûvÞQW×JRqWÊR‘|¥gÙ*ûuwÜ;¯ §ì<ý•¿?±„þvËòоºR×Àº>“¿òwÛçd«îêvS${wˆ«òR”œUò”¤E_+ІéïøÞíûì­›Êq?ÔRQWÊR“оR³l…m²ÿR—ûþ×ÅÕÄUò”¤E_)JÏØyû+~c üí—â*úë;·o·eŸn/>qªë7}¿ß>;³á]¿Á_éE_])IÅ_cçùóí¿ÆíÝ» nÂ*éHоR”ˆ«åcgݳíöæíÙó‹lâ*éWÙ³ýû/ìÛñYûWJDUò”¬Ùœõ÷?ó6SœqÙN¸Š¾ºR³mŸí³÷âûlüz¶Â4E_])HоV¿ö^ËRÿmƒú°ºm‘¶Ûm³m•¶ÆmW(«ìî¦Øõ­›79]ÖÊRªéYöNûí÷Í÷^û™ôE_])IÅ_)JDUò”¤E_)YðÝ÷uæWû‡|ß Ë«ˆ«åc¯e¯~we1§cÕæOWsþ3å±çÔë«”Uò½™/¶~Ù<îÙþ3»~wcÿ¨¤E_gs>ËÇçS¬ÜaÜÎ>®”œUò³fs×ÜÿÌÙNqÇe:êë;·o·eŸn/>q¥}t¥'}›Ûç^uï¸~íðŽººVlοߊR²³`õ¿(«ë¥)8«å)HоV-úó6lËuºÜCfU]gÎÇ«¹ÿòØóÎêuÊ*ù³?õÿÏîi;²µ])8«å+ÉHK†°Á­ÙÏg[TJ*ùJÏ·oöíß íóáÊÿõsоV6Û?Û~oÙÛ8§ì&®³»vûvWùöâóçúQW×JRqWÊR‘|¬Ù¶ßþØþÏÅöÛmªéWÊR‘|¥+òþÿþ?˜ÿí¶l§ggûgþQWÑ_†¿vc>|oWË;2Ý}Õ¤uìÜîµ69GºÌS)uq}Ÿ±Ÿ¯Æó×ñÇóXêºRqWÙû2¿~)JëïÔýý]gÎ<ýÕþ;¹„üwÊõrоR”œUö:öZ÷çvSv=XþaÕuŽ¿›–¦ç¨÷Qªeª®QWÊR“оR•›ä¯}×ò–½Ûàî®."¯®”¤E_)JDUò”¬eþµíì§0ìzùüÓ¢*úéJDUò•›3ž¾çþfÊsŽ;)×WWÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÙÝMñëS¾nró-–µUÒ‘|¥)WÊR³üÿûmŸþ­¶7øŠ¾ºR‘|¥)WÊV~ÌzûùŸ­Ž8þ§U\E_)JÏÙ_c¿3õ±ÇÔꈫë¥)WÊR¿!’ž¦íÕ›þwÿºÕ¶ÊS(«è¥gù ÿeìµ/öØ?« «œ@���È����z¿óý)HоR”ˆ«ìÿfßìý°¾ß¶­øWJDUò”¤E_)XëÙkßÙLiØõcù‡UÄUò³l…m²ÿR—ûþ×ÅÕÒ"¯”¥"*ùJR"¯”¥"*û7;-MÏQî£TËUz‹Ý GÛœïßt'wew[}Õd¬eîµoì¶0îr¹øÃ銾ºR•E_)JDUö:öZ÷çvSv=XþaÕt¬Ùœõ÷?ó6SœqÙN¹E_]fͶÿöÇö~/¶Ø+mWIÅ_+7qçü½ñÝ's¾^§í¿ÛöÇf~+?Ø/íW(«å)IÅ_)Y»º¾n)jËÍÖÝõ\E_)JDUö:öZ÷çvSv=XþaÔÛgûlýø¾Û?­°OÙ•ûñJW_~§ïêå|¥)8«å)Y»íþùñÝŸ íþ ÿDUóüÿûmŸþ­¶7úºÏ—óqKWW|¦ïªå|¥)8«å)HоR”ˆ«å)YÝM±ë[6nr»­”¥DUõÒ”ˆ«ìûvÿnÝð®ß>¯ðWJÍ™Ï_sÿ3e9Ç”ë”UõÒ±o•™»÷[©”Â_ºªç}›1¿¯žÆó•±ÇcXúºR"¯•Ÿ>ûŸ™ð¼ûà½õ]"*ùJR"¯±×³sºÔØåë1L¥ÕÒ‘|¥-ÈIiûô ߼÷çJ>øwSê¦*ü4¥*оR”ˆ«å)XëùjÛÙniÜåãñ§ÄUõÒ”ˆ«å+6c_=ç+cŽÆ±ôû'}öûæû¯}ÌúQW×JRqWØëÙ¹Ýjlru˜¦RêéHоR”ˆ«ìeîüî¥79g:Œ[-ut¤E_)JDUò±o×™³f[­Öâ2ªë>íŸo·7nÏœ[g(«æÃ6ÙÕ™þûþ'®®”œUò•ÌÛ¯ÙN³9‡cx긊¾V~ÃÏÙ[óûOçl¿WHŠ¾ÏØÏ׎cyëøãù¬u])WÙÝ»}»+üûqyóˆ}WJDUò”¤E_)JDUö-ò³7~ëu2˜K÷U])WÊR³:ßcÔ·|Øõf[©jˆ«ë¥)WÙ¶B¶Ù©KýÿëâêéHоR”ˆ«å)HоV~3ÝYÕ¿áÛ?â2êéWÙû?eoÏìa?²ý]+3­þ=JfÍ_uºÔ©E_])IÅ_)JDUò”¤E_)JÎæm×ì§YœÃ±¼tE_;·m¿eoÛ~/·a-êë{­[ãû-Œ;œ®~0ú¹E_gu6Ç­lÙ¹Êî¶R•WJÇ^ÍÎëSc”{¬Å2—WÆÏûgûoÍû;gý„Ó9¿uó³)Ôo0þoWkå£%¿Çgï”ý‘¾w ï¦ÿ}(«òRî¤7âƒRžцô!¿œž‚w@Û©Ÿ{y4 †!(+oÀnÊO+/ü†ýòP…9h0gݽŽÄÕþkÛ'~µo€÷d…uqÞ™;²ÖœûuvS„vê|ï”뾓P?ÍÝ%%úwÎWÉÀ6èA]$Àž²N{Ïw%r¾Ak-I5ºC{¶%r–ŸI\c;lƒ¬ìp ÌyÕþB¼¦†vlÃF»1£B\{¬}`݆ºy'`œÛ¶Ù³¿ãøOų̀uüµmÎì·4îrñøÓîÊjúéJW|¥)WÊR‘|¥zݶÍÿw=OÿOù—ùî“ç~êÿÜÂ~;åyE^ãwfîÿå/>w•™¾Yª>¢”ˆ«å+>Éß}¾ù¾ëßs>«œUò”¤E_c¯fçu©±Ê=Öb™K«¥gÎËù¸¥««¾SwÒŠ¾ºVo’½÷_ÊZ÷oƒº¸º¹Å_)JDUò”¬ý·û~ØìÏÅgûý¢*úéJDUò”¤E_)k侌Ù?-ävç+t­”úÉ(«ìî¦øõ©ß79y–ËZªéIÅ_)Y¾ï·Ý»q]·n9_qŸìÛýŸ¶ÛöÃÕ¿¥~âÝd!%¹yÀ»6é~ŸÿvÀK;à†kÔ'rÀb’Æ ÁŒSÿ’€ËdÿÜ$gÃq[vdŸ½É&†ý¿Am÷ÁNrwrù-(IEr·qªGg¾…À¨Àd²ÐBNø¿¹| �Û§£d)vìžÈO +¡{ŒÞòvͱÄJ¿˜Y4½Ã~鉽 +„nQlÿ +§ö)Ã8AyöÃ_ µäa©èÁœ”Y$´¥ %âˆI a£•ÊBМ²»õØE¤šM@j@ gO Aa…íÊOà`3$j{¹@)l{duµÛ¹5$ÒQ,¤§äpt÷ /¥r“’’WAA‰OmŠéÿ.óÛmÛ‡·Îk¨]U~É¡»ðÂÿ (¤ ¤Oῆ%�e=yè~Lù#1¿þ¶n”’÷…âðie HÒÛ§î—J:ɘ”’„dåýwCRQa„ Ò‹JCS“É_%;“J/†?G%üYy*&/nÈËÞæ€Vу3rþ& O.Üÿ£phI-ÒŠFÃR5¨ÊëßìvlsÕù±II “SÃI¡¸›³– +  ™’ŒèÈßîÝuâH@†$¢·I,´£|˜4°„/”¬ÿ}œ`À—í}È Ã:yHA]ÒÁ¨É‹ðaY!©ü¢“ðÔô°ÒBpÍîºPXJ+d†(æ+ ½þÜo%—Ò5ò ^B>Nùö±ø(áçWþYÄ×IYE ~„%E§gvCï˜!&öÿtoro¼€˜ðÔ 0¬„–r1I)nPÄfŒŽ5›%?Œ2øŠÿå%¿™wÈøoî3î;ž§×ÐôÛ‰>ƯÉJR羚”¥"*ùJV>Ÿ>ÛünÝÛ°¶ì""¯®³ý›³öÂû~Øz·â5]"*û7s>_=Œç«óÏÆ±õu‹|¬ÍߺÝL¦ýÕW(«åfÌoëç±¼ålqØÖ>®“оR”ˆ«å+ýy›6eºÝn!³*®"¯”¥"*ùJR"¯”¬ß'o¾ûçß/}ÍÞ®"¯”¥"*ùJR"¯³fÛûcû?Ûl¶«¥"*û;©¶=kfÍÎWu²”«rF’ÔVìRY=¶ð@×éÇ?ßu-MdK+üíó)þü!óoñëæguWýƒ2S‘ûoÆ!nΞ1Ãü_çÙe›:¿Ôp(„9hÈB2zR7ò†’¶ù%¤cö @Ñ©ûÅ·èõ€U†ÿÑËvFÈ% %è-_%t Éø²É_ô3y VƤ“Ò´§¯æ7œ9×µÙ Jqa»—¾Á¸ g-(ÉÊ^HÝ¿ù!(Ã0Ý‚ÜNpƒÀ•Uþ…�0IE–‚ƒP_)=²byeì5Ü´rÓݶ$nŒeëK+†rÐ^Ù/¡�Y°ÜYE¡(@iIûäòˆ@cí™;£2¯•'âÒRVnÊ/oÂJ-о1öÍÆrû~ûeÞ̰�Ü®J )9!¨OJ ,ay<”XÞQc:~Á<¬S¸ÌŸqdœ#šrñÆ…ÕWýš[†è BC>A[†b‰`íþ/tr·È%~œû~«½_-YÊ å†¡œ¿Ÿ~5ËãvK§“’”ò3d^($Ì„¡)JC2 |¬„r4¢’LðÝöCþœß~Ž”Þ¸l58¼’^AhB +ìR>a€d†á»—ðÁÏx¸Ì;­g¬ykJ¿Õ’’Yl„gJò÷ËÏ‘—ß²¶~—Q÷ŸãJ-!›röÁ‰ÈFéùXb:\¶ýgÁ»„ÿ¾ñ&Àt‹Ad¤t’€Îûý±kã /ä¶C¥(o‡ï`FC%$¢ßñY ,–WOÅb»£¯d)<nø­¹_QÙœPy:¾þ’n&²C(¼’ñ7 ã:Cvÿp2žŸøÄçùÿ]ñÐ ƒz¾}ÉÐM` ²’”! %Šèt:xÝøËëÄÐ(Xiié H`jS“²ZRz€’øÆ~‘©IùßÞ|A‰ d¾é(·Á¥—’¡›†§§~JÉãZ B8Ôvþß³ÁεJ¯üÓK¤B&âY9—³··lû')-ÔùO¾°îãÏù{ã»Nç|½}ŸÍsUõÒ”ª*ùY¶ÏöÙûñ}¶~=[a›0óÿ_üþ擱Û+SüÿûmŸþ­¶7ùE_]+{-{ó»);¬0ê~ÌzûùŸ­Ž8þ§TE_])IÅ_)JDUò³á»îë̯÷ù¾—WHоÎêoZós—™lµªÌû/N³q‡s8ùÆ©þùlÌüöÜ!ÕÏjŠb¯”¥*оR”ˆ«åfÃ6ÙÕ™þûþ'®®‘|¥gù ÿeìµ/öØ?« «ˆ«å)HоÇϳçûýû3öùÄÕÒ³º›ãÖ§|Üåæ[-j”Uó}ßo»vâ»nÜr¾â=z_«n®ŽãFnµçêÙþù’ìçÔwS|zÔ¼Ëe­V¤Ý:wû}²–ÿ£žÎIVR ¢uz:ÝHÿq»vÿ3 [gC;ã« gCòÄ#%œjþŒù¹·ß¾û*¯ñŸ§ýŠÈÿÛ!8ïÿKfÍ·'ü”%?¡?%ò^ÎÛãBC¥hÝŒ8X â¯Þ%§1A„´¥„%ɧf_C ·ùkF{éÀ†ô(0%„b^A1ÒKGOéå£|¹iI)D·;ß8 ü ”Lܶb‰íöø¼¾”¡=öÿýËK#ý–÷¬�ö)$Áˆå|ž7¤­±5%ï³l†NÉwé@éJr[ÞAXÖ5—Œ¥§«ýÚR²À°`Ä¥)-$Æ^Ý I-;Êéá,’ÿß?Ùó]âˆX o·û†£äŒ &! %ðDüQhл̀œ´äžVFJy`X7ì€+»bö)¸ ·ì3ô}¾þÝÀ4,¤rË H G/d7Ý;Ò}úSÐ…ñˆOG~Ì»ÃÌüs2ÇZUýâˆIO@Ò¹I/âÃJÝ érQIGb²”vÙ÷Bõ¬bHEä£t†bñ`X¿÷ÈNgJ6èNÉÙþBP7+=ãÀc‹FØ4°ÌzR—&èPfß§²I¸3§£írPŒLF&d•Ëù•€-K$•‹A)’œ¯¹7 GÉèÅ¥½*îÎ¥jØ{N¯ÜCA ”€£~’’7†òÃL@) PßÉiß0Öq¸c§ç¹,BÁ»P3‹å““Ëåaˆ(b9cCC?ûdò^Ûäüûʬ(4 €ïáˆ!î”!;œ‚‚8b I, ¡$ßÑ›,i_Œ=z¸¤'†#Yoƒ0ħò¸g8'ò׸BF0²`Ô£dt©¹Ì³áÙTÕÿ‚J/ò“’€2“›íû~Éßä¿ü·u e3^~÷À�* ¶ÿº9i5)FKaŽìJÜ#…ûÀßR[¾{¾R”º©«åfu¿Ç©LÙ±ëî·Z•WXëÙkßÙLiØõcù‡J*ù»?åïŽìi;òõ])8«ìlû¶}¾ÜÝ»>qmœE])WÊR‘|¥)WÙ³ýû/ìÛñYûWJDUò”¤E_gÎËù¸¥««¾SwÕt¤E_)JDUöw3n¼e:Ìæãªëÿû¿9[lûþÏÙÔ¼ffÿö¨”Uò”¤â¯”¥"*ùk _ÛŸ°Äý¶Ù=Ӿ߯/oÌÙK²ZÃyhC”ŒZ_6é—öÿöçeú¨TUFÑ÷ß2œð…æKíß/ìµv÷Ö�©7á¨è)&%4!27(²Ë&¥ódp058$½Û {À€Ä0¾É)()·%—ÓÐÛn1*Á$¯ÿ”â¾}òß^ë10¼­“ѱA¹‰ÿ’Êb^IyÅñ¹;¤°Ž„vo‘xèZÖ,å.Ò¯ô\$?Ëá¥%$Ò€t’‚úyY83#'b÷Ý8¼ÉùæJ5ÙÄÄ“@t5) ß#!Oûbðgt#—“°Ò·ìÑ7ö¾\„‚1eä èoÐt¡—¾I_”dqˆ@fã o¸Ü«®¢\1Åÿùd¡¨éFB Méâ·ÄŒ„6÷šç²—ø 9ʼn®¯ôˆî€q¨ß”0±¨Yh-9$¢¹jÈ)†~„úRÑÈNOÉ+æN(ayLFéHae—ÐJ²W ãFí‘qI€…òYEî07ò’_ܼ3íÆà3ÃP„ÿ‚˜ ”ày9¬h%”K@ %¤­’JΜدË<iC�±H (! Œ¯G9È›»<Þó«õ¤0°—‹%d„§”‚¹kééû`Ô$0¤ Yd±›ŒÓÒ×”Xa0`&`Ô–ð@i7!c$¾²ÒŽ”#ô$·èlcjô%! ´båydßÉ}ƒJNOá å¡\oÉÉv¸ W't!ƒSËûbV/„”Á¿7 /ôä?Oà ù‘‚nÌØîݘR÷|oQÂi«þŠZvAC2pjw !_ߨ'â’PÜL%t$#' fþáòŠ l„ýÆÒ’“8!}g&Œ(”Ýð`Ö_ÍÆ{‚Pa4†XBK+âÝ!‰ å`»tbÆŸŽÇäüí¢LbAero(¾— J§ôQA%!;†± `Ô§m¬Ÿl¶RŽ‹}·~*u‹€Q$m-Ò3ÿÿB?Q[§ÿ¶Ù·nÎ×+öcרïÌýlqÇõ:©°Í¶uf_ÿ‡þÿ‰ë«¾—÷±«åfù;}÷ß>ù{înôý‡Ÿ²·çö0ŸÎÙ~®¹Uò•Ÿ³+÷â”®¾ü9OßÓa›lêÌ¿ÿýÿ×W×JRqWÊôŸöý1ël­¾Û³ç9}ÞLë}RÝócÕ™n¥ª®QWÊR“оR³º›cÖ¶lÜåw[)J«ˆ«å)Yû1ëìwæ~¶8ãúQ}uÛ·Û²¿Ï·Ÿ8‡ÕuŸäoÿÛlÿõm±¿Ê*úéJN*ùJR"¯”¥"*ùJVlÃÏýóûšNÇl­W×JR"¯”¥"*þ±5%'rŠ&åüRTì‡Ùcwý8þÛn)w³&€Ã–ËÁ„¾^È bÒB%üå$kN)›¡);ÿ{æÖ²V ?òÙKfù’ìÙÝ[fk%™lÁõUþé�c†þ”5!©(a]<´$¯™;†%‚ ø®Rv&ìíê6JRÔt —ÐY]K&îWFéß1%”z>Ý=ëÀb2RXFù‘‘ËÒžŸ‹)öø¾†+>Ü5)䟽¸™ÉI,²i](J ÈøidµW)(J;% c2 -Ý$¥¥Úó_¶ËQçî±Úº¾ÌZ +††ƒ�£tbÑ’RKåïÝ‚Slœ‚ŸP¢n+KÜ¢jwÝ) éÎB\—É_éé-úBv«H¡„"ɘj{}¿(¯‹ÃF%#!©~‘¥þ÷Fmÿä¿XŠ!PßÓÐЀѨÝ%ÉX†­·%~ãF#î†B®†§~ø<ïóìp¢*§Wó@MɤџŒÄ”Ÿ²ºKHÑ£37tn’¿B]?ü…=A 0 Ñ¹3„¤'YI@hÐÍ· A/>ëÈN?².h úY%røÒ€n`…nPÌ’ÀÏFHщAa›''ýÖõ�\7¡;rb0al¾F@jFaˆûp„%½ò–Å£¥Õt>A9jY‹Tªþ‘e”XjQ€v‘‰) Áˆû¸b:])¿£%=¡eï¿úùÑ0­ƒRö)‘–þ+¶ÿ²:Û~¦âõY0™‰ŽÎ¾=?ÙIJWÜ'å¥/ýͽÿ[‹â ÔUò”¥ÝM_)YoñêS6lzû­Ö¥UÄUò”¤E_)JDUò±—ú×¶?²œÃ±ëçóN«¤E_fÌoëç±¼ålqØÖ>®”ˆ«å)HоR”ˆ«å+7ÉÛï¾ù÷Ëßsw«ˆ«å)HоVm‘¶Ûm³m•¶ÆmWY³úùìo9[v5”UõÒ•›6ÛÿÛÙø¾Û`­´â¯®”¬lÿ¶¶üß³¶qOØLE_])HоR×Ê%£ ¶Ný{>ß;í×ÝJI‰Z›µFÃ6ÙÕ™þûþ'®˜«ë¯-†%Ý›¸Á®Ì`À—ËQYû?eoÏìa?²ü⯮é�XPÄìø–Ÿþ5Û3ü‘»öWéßý¶î×6’x«û¼÷Á ºwNãF’þHwÿ ßïÿwõ€ˆÅ¤5 “ÿK÷K§£çK¥{o†d è^Ý“õç©d7€'Wôd  Á…!™¿77ïûÿû‰°í‘¶Ûm³m•¶ÆmWKGsåWÊR•Å_zTý¶ï¶w9m·Où•±îw“çßoóãó>Ÿ|¾§víöì¯óíÅçÎ!õ3¶}·eíßn+¶q-©Š¾ºR•E_)JDUò•Ÿ9¿/Æs—¹çsX긊¾R”ˆ«å)HоR•é@Ö_Í÷Wgc9¬ëS;7SéE^Ž¿›–¦ç¨÷Qªeª®³çßoóãó>Ÿ|¾«ˆ«å+6ÈÛm¶Ù¶ÊÛc6«œUöwS|zÔ¼Ëe­Ut¯Jz2‘Òz°Áßÿ²ÎÇJ*ú)JN*ùJR"¯”¥"*û6¶Î¬Ëÿðÿßñ=tý™_¿¥u÷áÊ~þ®’оÆÏ»gÛíÍÛ³çÙÄUÒ“Š¾R³wÛýóã»>Ûüþ«ˆ«å+3¶}·eíßn+¶q-¨ùþ|ûoñ»wnÂÛ°‰E_]+{-{ó»);¬0ê¹Å_)JÏWsþ3å±çÔ눫ë¬Ünß:ó¯}Ã÷o„uÕÒ"¯”¥gÛ·ûvï…vùðå„xоºÍ÷}¾íÛŠí»qÊûˆôÙý|ö7œ­Ž;ÇÕÊ*ùJRqWÊÏömþÏÛ íûaê߈Õtˆ«å)HоVwnÛ~Êß¶ü_nÂ[ÕÒ"¯”¥"*û6ÈVÛ/õ)¿áý|]>v=]ÏøÏ–ÇžwS®®’Š¾Ï²UöëÝk^ï¸w^WJÆÏ»gÛíÍÛ³çÙÄDUõÒ”œUò”¤E_)JDUò”¤E_)JDUò”¤E_fù;}÷ß>ù{înôîݾݕþ}¸¼ùÄ>«¬Ù¿¥efÁë~þQW×JVnîz»ñ›©Ï<ü§T⯮”¤E_)YÝ»mû+~Ûñ}» oWWÊR³ö3õã˜Þzþ8þkW×JR"¯”¥"*ùJV:þnvZ›ž£ÝF©–¨Š¾ºR‘|¥+?ÏŸmþ7níØ[vW×JR"¯½|¤ZV¡ýJÛ=K\™Öû¥»æÇ«2ÝKU]%|¥)8«å)HŠ¾Ïœyû«üws øï•êéHоV}’¯·^ëZ÷}úðººDUò³ç7åã˜Îr÷<îkWHоR”ˆ«å)HоR¿ŒOÛüÉnÝ–ØNWª%|¥+7}¿ß>;³á]¿Á_éÅ_ýy›6eºÝn!³*®”ˆ«ågí¿ÛöÇf~+?Ø/íWHоÏòþËÙj_í°VM²6Ûm¶m²¶ØÍªé(«å)IÅ_+ùY›¿uº™L%ûª®‘|¥)WØ·ËÌÝó-ÔËq/™ut¬ÿ!ì½–¥þÛõarоnû¾|wg»‚¿Õt¤â¯”¥gÎoËÇ1œåîyÜÖ:"¯®•Ÿ;®çügËcÏ;©×WWÊžVfïÝn¦S ~ꫤE_+ùy›¾eº™n%ó.®‘|¥)WÊR‘|¥)WÙÝMñëS¾nró-–µUÒ‘}›dm¶ÛlÛem±›UÒ‘|¥)WÊR‘|¥+Ò½ó~êíÛ«÷}ó®ã—(«è¬lû¶}¾ÜÝ»>qmœE3­þ=JfÍ_uºÔª¸Š¾R¼–†q¹œc¾gqŒ$j˜zª"*ùJRqWÊR‘|¥)WÊÍ÷}¾íÛŠí»qÊûˆõtˆ«ìuìÜîµ69GºÌS)ut¤E_gs6ëÇöS¬ÎaØÞ:®”ˆ«åfãvù×{î»|#®®±×³sºÔØåë1L¥Ê*ùöNûí÷Í÷^û™õ])8«å)HоR³;gûö_Ù·â³öþ®"¯”¥" �������z¿óýz1?ìj{ö39ýŽ~ÿ›ÿ¨¤¢¯•›¾ßïŸÙð®ßà¯õ]'|¥)WÊR‘|¥)WÊR¿oûõ|ùIÿ7êÿ+;lb—·”UôR”œUò”¤E_)X·ËÌÝó-ÔËq/™uq|¥)WÊR‘|¬Î·øõ)›6=}ÖëRªëÆ„Œns»+­yÌùG³º»J*ú+;©¶=kfÍÎWu²”ªºN*ùJR"¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJÆ_ïÎÊScÖs¬Õ²•WWß’¶í¿¶îûvs·78ïÙê)IE_gÎoËÇ1œåîyÜÖ:®•™Öÿ¥3fǯºÝjTE_]c¯æçe©¹ê=Ôj™j«¤â¯³w3åóØÎz¿<ükWJDUò”¬ÿfßìý°¾ß¶­øW×JR"¯”¥c/u«|e±‡s•ÏÆWÍ™Ï_sÿ3e9Ç”뫬îfÝxþÊu™Ì;ÇUÊ*ûýY›7uºÝL!»®|ò:rMß|Ìûž½Å9ã¤ÎnÙ|îêuŒ?ÇÑ—ºÕ¾?²ØÃ¹Êçã”Uóö~ÊߟØÂ;eú|ì¿›ŠZº»àõ7}WY¸Ý¾uç^û‡îßëœUõÒ”œUò”¬ß%{î¿”µîßuqq}t¥"*û6g=}ÏüÍ”çvS®®•›6ÛÿÛÙø¾Û`­´¢¯®”¤â¯±³îÙöûsvìùŶqt¤E_)JDUög7î¾ve:æÍãªë>ݿ۷|+·Ï‡+ü#ÕÊ*û?c?^9ç¯ãæ±Õt¤â¯”¥cçÙóýþÆý™û |âb*úéJDUò”¤E_+7Ýöû·n+¶íÇ+î#ÕÒ"¯³w3åóØÎz¿<ükWY°Í¶uf_ÿ‡þÿ‰ë«”Uönæ|¾{ÏWçŸcêéIÅ_)JDUò”¤E_+7wWÍÅ-Yy¸rÛ¾«¤E_)JÍÜÏ—Ïc9êüóñ¬|E_]gÎÇ«¹ÿòØóÎêuÕÒ"¯”¬ØfÛ:³/ÿÃÿÄõÕÄUò”¤E_)JÏÆoû«:·ü;güF\E_]gùÿöÛ?ý[loõtˆ«å+;©¾=jwÍÎ^e²Öª¸Š¾R•Ÿ>ûŸ™ð¼ûà½ôE_])HŠ¾Í˜yÿ¯þsIØí•ªéHоR”ˆ«ågs6ëÇöS¬ÎaØÞ:®‘|¥gù ÿeìµ/öØ?« «ˆ«å)HоR”ˆ«ìÙ‡Ÿúÿç÷4ŽÙZ®”ˆ«å+3­ö=KwÍVeº–ª¸Š¾R”ˆ«å)HоV>Ÿ>ÛünÝÛ°¶ì"‹|¬ÍߺÝL¦ýÕ:XgýÛ, k©g!|ã±ç51WÑKºR@©0 ¼R_$ Ôvn¤ãœjÌoòõí105„�Z– IHè%”ìQ(ic27FJúB3æÝ½ÎíÈáUUÿ2ý·û~ØìÏÅgûý©öNûí÷Í÷^û™õëÀ-Å˹!Ò”}¸Ü3¥8¤rñhî‚öÅþ3äï›f¸©¥dä>ëÛ÷}<­‚7Y-³$f=¿æÀØ*¿JW„°óÿææ|̦ë~ùZè•_E)IÅ_+ÆçežÄ„³³žÌÌiΧy3›÷_;2FóæñÕrоR³:ßãÔ¦lØõ÷[­J«œUò³mŸí³÷âûlüz¶Â5?açì­ùýŒ'ó¶_«”Uò”¤â¯³ößíûc³?Ÿìö«¥"*ùJVnãÏù{ã»Nç|½W×JR"¯•™Íû¯™N£y‡óxêºDUò³ç~êÿÜÂ~;åz}»·nøWoŸWøG«”Uò”¤â¯”¥"*ùJÍßo÷ÏŽìøWoðWú®"¯”¥"*ùJR"¯³çcÕÜÿŒùlyçu:êíe”5ŽWÇ¿Äɳ¨#žŽ½d¦*ûúvëVRÿÍú{m–îìbß5¿ôd#ä¶Ga¿¥; ß$—Æ™·Î_l–ýý³»î0b_î‘ "ÈÎs¯wÝšúhx4šVàP ñ‰ÉJ:CwOß—JÊ>$¯”®Œ‡ãäAëbpª¯¯€ì¼1yïú?%’ßœ»}Ê[wd# ½ùy­(š6AdÒi, Ô 7ÓÐR@ÎÈ~Žì‹$üù(B½ Ô†€ì™BFÁ¸¯’’ƒJéètôàÜ45ûî’ó·Ût¥ýË& ‡€LMB7+—ؽЄ É„§q‰îÛ’öû¾GÙï!ß²ŒÀËZ¿Ï–MÜšÄ>MÀdbvƒJå£o‘ÔK_C±] îÿf²€wŠ`Ĥ ‹ü´—XhÆ,è B–„ü–ù?%z_Úà DÐ|ñdİfH`h (´„~å+fN èù¾ÚäI…�Ü0šL|Šß¶ ņfß·t—öèßä ¾„«§æº–i¦P¢ 5$0ð(ù{tdÏè+§ìĶ%|ý·Ý¾Y×¾ MA{b ›ÂÀ° ‹,–RzRPè(®½Óߥ)}œïy4'òn+'–` úR„wNtVØxÄ-ÂS•w±<àâ}5›¥fù+ßuü¥¯vø;«‹«½*ùJVglûnËÛ¾ÜWlâ[DUõÒ”ˆ«ìuüµmÎì·4îrñøÓêéY¾J÷Ý)kݾêâå}t¥-Ý; Ã{ý›-|vWX¯WÑJVwnÛ~Êß¶ü_nÂ[Î*úéJDUöm­¶_êRÿÃúøººÍßo÷ÏŽìøWoðWú®QWÊR±óìùþÿc~Ìý…>q3оºR‘|¥)WÊR‘|¯ø'vÊß 7?ÊÊ;²×ŽÊõ”Uò³fuþüR••›­ûùþèNÝ2Öîï¾ù™˜ÞïÕQWÊÍ™×ûñJVVl·ïéÝ»}»+üûqyóˆ}F_ïÎÊScÖs¬Õ²•W×Y¾Nß}÷Ͼ^û›¸ê|ìz»ŸñŸ-<î§]¬”œ·Èï¿èB¸K¥_ö³ÎçÊ*øÁ¥ üoo9÷ýt fNî´+½X C14²W(·I)‹+%ÑŠ/|3ñ(¤ hom¿Nûý¯öNûí÷Í÷^û™õé ÌVAErÑÑÒJù(émÓñe¥9‰ièß'Ý#wߵʎËvuUÙH`T•¹EF)yY '“1(4h`ÞŸŠÜ¼Ÿ×ÿnž€ Ê% ä>„”” ¢³üÒŠd,¢ÖÃpj{7¼(7²4®ïƒ7J3•Ÿ!¥))´>Ø„Z9[·ÉÛýzÇ,’è(²g(§pŒŸñEä—ò„üj\”‚Z:Ÿß>Û³ñ.5cÏokWù¢a C-½<ä´öN(`ntäd$`cô#üÉúÈPVÅLF B 冥yo³(½ò7é I# ßä=MÄ-»”‚VJ7FA0˜”äô”€¯äÜßò–WPÖ{^d”Z>@aI(19%†d“:JG, ¤by)ºß£tž—û[ô?sûœÛó„æ›*¾–0Q[—øjr3r–Pj>+²940È-#;”3#„tvºß¸n,hha @ ËK 1,¬„ û}úRS —ØoèÞóD ÂQ`'Á»†òËØ$aì„%(,°Â¶mØ!œ³?¹% (´ÿÑ¿é%§~Wî’÷,²gFlÙ•‹Ü#3h[c²”ÂÇs^*ÿ6B,nù¶äÖèGÈì_ߊïÛ»~œŸŸ.âßT�Èe ´•öB ,`` C:0Šu#àÍÓÒìÿ¥?|§¾dRPZ”wÉÛî?|øõÞÒQÈ6u}›»«æâ–¬¼Ü9mßUÒ릯•éÉìÉfûõ>øÝÍ÷ÍØü©;©¶=kfÍÎWu²”ª¹E_+6g_ïÅ)YY°zß¿§ìǯ±ß™úØãêuUÄUò”¤â¯”¥"*û;™ö^?:fãæqõt¤E_)JDUò±×³sºÔØåë1L¥ÕÒ"¯”¥gÃwÝ×™_îó|'."¯Ž¿›–¦ç¨÷Qªeª®³ö~ÊߟØÂ;eú¹E_gÙ*ûuwÜ;¯ §ìgëÇ1¼õüqüÖ:®‘|¥)8«å)HоV:þZ¶çv[šw9xüiõu™Öû¥»æÇ«2ÝKT¢¯¼±¿2?ßòKo³,'Ÿvo²Ö¦?Vt”§æÅìJåìŽZlÿqû·Q­j åâQH/d¥)ïóñ›~­¶Í¸ÄØ#°Ñ¿{B$´–1.VAyJs!%ºx¿Ÿ£ìŒ—?/msâpTêü¥ôr™©~’@ÆR?Ù#~g3æÃ[žÐéå–ZF¥ ø¯!ô~3d}ߌ[:®ª@©\™Æ ådºCRÅŒn‘¼$!?¥ J í³ïrnCHbŸa¨ ßä'¥;ýønFèÿ(¬k·Ö['ùÕÿY&†”Ä“8fØg ä²Ò„%; ˜Q|0¾JÿIe憺9.”1D.RF#ß%¥9#r>èøÖÉ@dÿî9 šÄÔ¹|°ÒŠ- åô$1zQûŽŒ3Ÿ¡¹}§µèX7t šW ã>%ïÉ¡¼´ì„~ú3d;ŒèC IéÞù½¿[ñæf",p}µ_ó@(K&äbøgI#—› ¿Ó²PWìÁœ–_&ÿÃzF|ŸÑõ¼šC-8 Ä†nZþ唜L/ ý‹äÔâÑ€±m‹Á))¾×¡) \ âb† !»’’Ã7ÿþÆ^@Ätôd(¬»„L,0˜’À-Á¥$®‚S§ìŒWá0–ŸÉ…§›7BRÉïu¤WÙn<qÔÕøÃRj1 Å!$4¥%œ›ò Ie£Š Axný Ý»¾ýÞä–M)ƒCRJKvA 7–PnCî5…ò¿œèþn„!¶÷¿&€”QX7”7¡²VBC ®WË(¼5’ CfÁˆû1_ÞL KŹe¤hÄdq‹å–3àÝö�™)Gå ¾JJRØ#Uóöq?¬à³â¯À‚Ó‚0…·HÏùY oÑŠÉ ,7§îŒŒ1$je^1Æ!¾J²wýò†Ò4 ôô¯çeªûv Á©Ü”M Ý$4ºpjqJý;§ýúr ÈÎ’“Šå2])¾²Š;„c“ËÇž´àõóîÿ—÷í–!³)«òVlÛoÿlgâûm‚¶Õu™Íû¯™N£y‡óxëÕ³«ë¥)8«ìùÍùxæ3œ½Ï;šÇUÒ‘|¥gùÿöÛ?ý[loõq|¥)WÊR‘|¥)WÊR‘|¥gû6ÿgí…öý°õoÄj¸Š¾Vnæ|¾{ÏWçŸcéû?eoÏìa?²ý\¢¯”¬ÝÝ_7µeæáËnú›Ûç^uï¸~íðŽ¸Š¾ºR“оR”ˆ«å)HŠ¿¤C%’¸ÀÔ6ÿ–” ÈÍÖIFÌ{÷Ãõê1D$Hber”0¬’Ÿöèí•ߌ/da½)C%ýæËÉÃ:Q-þļ¿»§”ކøì¶Jÿ{Р4„²’L BCzKêÝ;ìÿøÄt’”žü­Ù^~î~uWWú Р…“ÐÁ¸¬á!©Nè(èý Iy& ²Rwr““«!4%¥Æm’ä¦A7€ä Ô#¾%28Þ1ÂrQË@ÇkÔ€œ„ÃzÓÿÆ¡+ð–CZ?_Ix¤#“vÛÙ�vWÝ ;äÜMddò@À[†ø5 g·J7Fß åsÞòÑŽß0p®8QõÕýbhf)8´}’Z�vÃ?Oü²ŠIhÎL ìKOß§m™¿½‡F&‰œ–YD²²PŒ’`i{–û$3÷J²y_/ C§+LÌZQŠN/¡½É¸®[•‰A¥ð•î„Ü7~ß¿öt!ñ5¡‹IHGå9d¾^8²ÃRÀ¶J~=*SëÍ9ÌÄíÍXŠêÿ,7 ¬‚ÒZ Ål„ ”^ÈÖÉGAhÀ7éìý’·}½»¡$®„trËàX¯‹n3”1)I,â_ì”–ÊÍ·îÁ@:%„£ ´'u—‹É/ Å‚f+ ±¼j8JFt%Ù{Øøj »p'�£âù_'§1\nN%W á¨GýÂY=í…?ŠÒ«ó’Må£÷%ZBI+KÈåáŠ)·Z´oÑ“Õa,j ©á¡©I â°jP„ô—¶Ax¤†ºRžé`(íû¥ ;V�ë�PŒbœ¶Å¥¸n%pÎø²Ø4'vÜfÉ t.¨ÒÃ9@`¢É›’_žLJÆ•ñ) É`ÌM@@ÇùÒæ¹¸Çm¸[â¯á“C ¥ ´””!ɨٹi,j_†ä†!¡ÿì9HlŸÑŸ_¾ p˜3ðÞ‚ÊÃR“ðÉ|v÷ÛºWÕнòûèÿÄïeWÊR³9¿uó³)Ôo0þoz4UõÖ-ú³6nëuº˜Cw]]"*ùJV2ÿZöÇöS˜v=|þiÑ}t¥"*ùJR"¯”¬uìµïÎì¦4ìz±üêâ*ùJR"¯”¥"*ùJWá‰dîù•÷WÝ»«·9\(ùE_E)IÅ_)JDUò³çcÕÜÿŒùlyçu:êë>ÉWÛ¯u­{¾áÝx\¢¯®³wÛýóã»>Ûüþ«¤â¯³üÿûmŸþ­¶7úºR"¯³fëÿŸÜÒv;ekXj Nd$`ÿ™ÏËßä¡YÕÑÝKÖ Ï·oöíß íóáÊÿôÅ_ꑹ+-841/Ó”þ•£o‰[’Ñ’VÙ¯|Q $ÞK@’W&² J ¥a¿ìÜ4 ÔìÎä²ÀÈЖÙï—q…†|Ý ‘‘¹EîR‘·„¡¾$'e3Ÿ{@*ù ¤ †ät~XÅ6BB;§ðIJ]É.Ž”a¿ýy#XÀ8EË´«þ†_,†^à&ß–”7&£raièà]8””‘þßàÐ.åãöáœhoäºC\–PÏ‚8Ô' +©@NNÈËÙµò2ÈE†$–’:R„dP„Ï‹å¥$ÂÑ·ÉÉÃR‘¹ É·÷¿á‰))+{¡—ÃxÂ` îƒWɬÀXï¯|ÙÕ±‡þ¡aJU¥_a %¥(å§§)‰á€Qa8­Û¤¡87|û6É^Íy’aed¥¹GHn@ÔŽA(oÛ“„Éý'º OtmXB ,hi “ %%¤â±_bË-÷ébù(®„”Kü5%7;«\id0Äà+ð`a% Üa\§+ jxßÃq,¤¤1]·vi«ÿ4ô÷Çwf{E_ë13b²SÃxÂþå'Š|V (‘©åbXj6HÆæ®ò„ÀbnÁ¸ e”MéÙ<°ÒÿãP’^B¹(¾’¶Ã;)^â�›'’Ñ‘Š&ì4®KJrS¾&âËÿ÷È·ù*S¤máFrVïÿÝä¦Á¥îŸÆ'á¨ËéÝÿÜgÏwô³ž§¹?SWó°—íömó1ëo²wî½ÎcµE+-[s»-Í;œ¼~4ûèljúéJÎíÛoÙ[öß‹íØKyÅ_])HоR³9»eó»©Ôf0ügWWÊR‘|¯Cm™ÿ;)û§þÙ³­|þ/ɜݲùÝÔê3~3«”Uò”¤â¯³íÛý»w»|ør¿Â=])WÊö‘³fÛ¶9M¹ØìªŠJ*û7·Î¼ëßpýÛáut¤â¯”¥"*ùJR"¯³wÛýóã»>Ûüþ«¥"*ùJÍÝÕóqKV^n¶ïªâ*ûùy›¾eº™n%ó.®³ì÷Ûï›î½÷3ê>Ÿ>ÛünÝÛ°¶ì"QW×Y¶FÛm¶Í¶VÛµ]z‚Ñ’ŽûÇ‹Ã÷3òò¢*ôønûºó+ýþo„å×ôl^HÏÿÃÉ|Þ§ûnÙÿgVU’’Š¿ÖÈE¹i&;$¤„:\¯ÐK—KÝ<Ãú« �¸„„bуyY]9óô!F¸ÌÃFŒ;6Úñô°Ç´êÿI€LŒ—é-;t¶JRœ0²²RFôGøksl%�蘞”‘ÔqÙ†°Ìr )q›;÷>äÒ±¾*ûЄ™²”fm¶Û³c³jŠRÖU|¥)8«å)HоR”ˆ«ågϾßçÇæ|/>ø/}WHŠ¾Îæm×ì§YœÃ±¼u])WÊÇϳçûýû3öùÄÕÒ"¯•‹|¼Íß2ÝL·ù—WYó›òñÌg9{žw5Ž”UófëÿŸÜÒv;ejºý÷ÿä¾9³6èÿs³»«¿S ¨ˆ«å+6ÈVÛ/õ)¿áý|]7·Î¼ëßpýÛáq}uŸ±Ÿ¯Æó×ñÇóXê|ìz»ŸñŸ-<î§]\E_)JN*ùJV-ò³7~ëu2˜K÷TE_])HоV2÷Z·Çö[w9\üaôîݶý•¿mø¾Ý„·«”Uò”¤â¯³9¿uó³)Ôo0þoFÏ»gÛíÍÛ³çÙÄUÒQWÊR“оR”ˆ«ìÝÌù|ö3ž¯Ï?ÇÕÒ‘}Ÿ°óöVüþÆùÛ/Óq»|ëν÷ݾ×WIE_{¤kd)Oÿv_ÿ}Û7W2¢”ˆ«ìuìÜîµ69GºÌS)tûvÿnÝð®ß>¯ðWHоR”œUò”¤E_)JDUò”¬eîüî¥79g:Œ[-q|üfÿº³«öÄeÕÒ‘}›ä¯}×ò–½Ûàî®.®”ˆ«å)HоR”ˆ«å+>¾î¼Êÿpï›á9tß'o¾ûçß/}ÍÞQW×JWäîÛ„œgùÔÎwùO·oôE^‹~¼Í›2Ýn·Ù•WJN*ùJR"¯•ýiBºŸ¾íœæù÷îý•òœö¨¤¢¯³l¶Ûm›l­¶3jºRqWÊžVfïÝn¦S ~ꫤE_)JDUò”¤E_gvíöì¯óíÅçÎ!ôÿý“þV^gOù‡lîî¬îN¨¯éFìëS쿆ößìýÖr¸êb¯¢”¥QWÊV:önwZ›£Ýf)”º¸Š¾Vo’½÷_ÊZ÷oƒº¸ººDUò•Ž¿›–¦ç¨÷Qªeª®"¯³çeüÜRÕÕß©»ê~3ÝYÕ¿áÛ?â2êé(«å)IÅ_+;·m¿eoÛ~/·a-êéWÊÆÏ»gÛíÍÛ³çÙÄUÒ"¯”¥"*ùY¶B¶Ù©KýÿëâêéWÊR³çßoóãó>Ÿ|¾ˆ«ë¥)WÊR‘|¥)WÊVlοߊR²³`õ¿OŸ}¿ÏÌø^}ð^úQWÍòW¾ëùK^íðwWWJN*û6c_=ç+cŽÆ±õt¤E_)YoñêS6lzû­Ö¥UÄUò”¤E_+ýy›6eºÝn!³*™Û?ß²þÍ¿Ÿ°‡õrоR•‹|¬ÍߺÝL¦ýÕ8«ß:22ÒgH@ãùÙ`<Ç󚢔”Uò”¤â¯”¥"*ûöîÿ¿Ï”û7ê|ÿ¶ËÌíQJJ*ùJRqWÊR‘|¥)WÊR‘|¥)WÊR³ñ›þêέÿÙÿ—WÌë}RÝócÕ™n¥ª®”ˆ«å)HоR”ˆ«å)HоVm‘¶Ûm³m•¶ÆmWHоV}»·nøWoŸWøG«¤E_)JDUò±×²×¿;²˜Ó±êÇóÿKl¬ûþùjùŸ7Í×÷WÌ=ª%|¥)8«ìîgÙxüêu›Œ;™ÇÎŒÙþÛöée­¶=·ç3ý•ª)(«å)IÅ_)JDUò•ŸäoÿÛlÿõm±¿ÕÄUò•Ÿ¶ÿoÛ™ø¬ÿ`¿µ\E_)JDUò”¤E_)JDUö~ÃÏÙ[óûOçl¿WJD@���H����z¿óýgÎËù¸¥««¾SwÕtˆ«å)HоR”ˆ«å)HоR”ˆ«å)Y³:ÿ~)JÊ̓ÖýüE_])HоR”ˆ«ìÙ¿¥efÁë~þ®”ˆ«å+?È_û/e©¶ÁýX]\E_gìǯ±ß™úØãêuUÖnŠZ²ópå·}W(«åc/u«|e±‡s•ÏÆWIÅ_+>v_ÍÅ-]]ðz›¾«¬ÝÝ_7µeæáËnúQW×JÎæ}—ΧY¸üw3­usоR”ˆ«å)HоR”ˆ«å+>ÏŸïö7ìÏØSçWWÊVnæ|¾{ÏWçŸcêâ*û>¾î¼Êÿpï›á9ut¬|ÿ>}·øÝ»·amØD¢¯®”¤â¯•øgJ~ËVý™Ùy/g1öÿšõ›»ž®Ç|fêsÏ?)Õ(«æîgË籜õ~yøÖ>®³fs×ÜÿÌÙNqÇe:èÙ÷lû}¹»v|âÛ8ˆŠ¾ºR“оR•Ÿä/ý—²Ô¿Û`þ¬."¯®”¬ÝÝ_7µeæáËnú"¯|œŸÙ{¾ù÷ûåwt|·ÄZŠRQWÊR“оR³|¾ûïŸ|½÷7z¸Š¾R”ˆ«å)HоR”ˆ«å)HоR”ˆ«å+?ÏŸmþ7níØ[vWWÊR‘|¥)WÊÏ—óqKWW|¦ïªéWÊR‘|¥)WÊWäl”¤ÿØÌ­ŽÏ¶ìïÖëþ#ý›gÿ#9ëêÙÿýjÏü¢¯¢”¤â¯”¥"*ùJR"¯±³þÙþÛó~ÎÙÅ?a5t¤E_)JÍ™×ûñJVVl·ïâ*úë6ÈVÛ/õ)¿áý|]]"*ùJV2÷Z·Çö[w9\üañ}u›dm¶ÛlÛem±›Swu|ÜRÕ—›‡-»ê¹E_)JN*û>ݿ۷|+·Ï‡+ü#ÕÒ³ñ›þêέÿÙÿ—(«ë¥cgý³ý·æý³Š~Âjç|¥+Ë1$¦Ü`×ì§e³žÒоŠÍÝÏWc¾3u9矔ꫤ⯳9»eó»©Ôf?Œê]]+7Ýöû·n+¶íÇ+î#Ê*úéJN*ùJVwS|zÔ¼Ëe­Jˆ«ë¬uüµmÎì·4îrñøÓêéWÊ͘ß×ÏcyÊØã±¬}]"*ùJR"¯”¥"*ùYoñêS6lzû­Ö¥*®‘|¥)WÊR³ç7åã˜Îr÷<îkW×JR"¯”¬ÎoÝ|ìÊuÎÇózÕ;t£ WWù ç峄œV|~”U𠬾ÙÍæ§œÿ›ûl#jŠVm‘¶Ûm³m•¶ÆmW×JÏÛ·íŽÌüV²Åý©þÍ¿Ùûa}¿l=[ñ"¯®³ì÷Ûï›î½÷3ê»Ô†¤1%’þŠÉAåa¨å¥¿ÎžèÙò©ômöôiÕþ^±×òÕ·;²ÜÓ¹ËÇãO»¼(ÉÈìRR‡)¿”5;ýÐã:bGOû¾Ìߨ�Ë#”rÜhß¿BöÎJ†gý#YóZL"*þm)KYUölÛoÿlgâûm–+mOÆoû«:·ü;güF]]%}ø`Þ¥¶~Çç톳vZN.¢•™Û>Û²öï·Û8–Ñ}uŸ9¿/Æs—¹çsXêºN*ùJVm‘¶Ûm³m•¶ÆmW×JR"¯”¥"*û?fWïÅ)]}ørŸ¿«¥"*ùJR"¯”¥"*ùYó?uŽîa?ò½]"*ùJV¿ö^ËRÿmƒú°¸Š¾ºV:öZ÷çvSv=XþaÓ£¿J÷nÍB·n¾µ¹ŠùRн-[s»-Í;œ¼~4úºRqWÊV>Ÿ>ÛünÝÛ°¶ì"Ÿ±Ÿ¯Æó×ñÇóXéE_])IÅ_)YøÍÿugVÿ‡lÿˆËŸÝÏÊÛl¼µÿÿÙ™»3«žt¢¯OÆoû«:·ü;güF\í÷}ÏïÝùŒÙlƒ9ÌzŸ¼Ÿ>ûŸ™ð¼ûå ßWôeü„t¸ÜêtŒÿ·ùJvý¥~°*JÅ%%ÿ¶ÆðÃrœj6ÿí·ÿÎßÞì0 BjR’Ûüÿ‰©ß'†¥%“ÿ–ÉOFåfËçÝàâÃÒžÉäÌ‚ÿè-(ù$Ä¥Ëù%tqƒ ?ì¿Ã]7\5"Ëä-ÑËB ÄÂ’V!d–•Ó€lŒK3bFt#îÚñ3™”àÚkWù ÒƒWÊp`¡œ7¯0´'bŠ-·Ù‹îº†F·“�b— Ii/�Ü47„Œ-!™(ä¢É„´!'##„çØ'ŒºÉN& QÃ�-NJLÀT´'7?$ ÄþÃPWßþï÷õaœ˜P¾øòÃxÂax ž‚QLC û>û'vNBvêûØ0æVÂ;yÕÿ4ÀT ÂhÏÉå }‰\²ÓÉIÈGÈ^Fü´ —Îyâ` !íÐÆîŸ è݆¶ÿ³^;·UôôY4¦ÄÀÒ¶GFA12F:I¥d‹J¾ÅlÛì0hËÒ�˜†M! À7 å#då$¬øÝ’ÜBü—¿èÙ!?gø§º¾æï¹M_ùÚ—X185%³÷íД9)8'^ÉÍÛ­Ûü¾}ɽ‹:¾Íßo÷ÏŽìøWoò…©¸Ý¾uç^û‡îßë£/õ¯le9‡c×ÏæW8«å+3¶}·eíßn+¶q-ªç|¬|ÿ>}·øÝ»·amØE]"*ùY°Í¶uf_ÿ‡þÿ‰ë«¤E_)JDUò³ñ›þêέÿÙÿ—WHŠ¾Ï·oöíß íóáÊÿõt¤E_)JDUò”¤E_)JDUölÆþ¾{ÎVÇcéðÝ÷uæWû‡|ß Ë«¤¢¯”¬ùÙ7µuwÁênú™Û>Û²öï·Û8–Ñ}t¬Ùœõ÷?ó6SœqÙNº¹Å_)JDUò³çßoóãó>Ÿ|¡{êºÆ_ïÎÊScÖs¬Õ²•(«ã/wçu)¹Ë9ÔbÙkµ¡v- uääþ7wùn€ŸÑ»£:µ“öe~üR•×߇)ûùÒ‡7îßo¹ÎËnèÿ2Ÿv¦*ÿª€b€Â“²P„†7à! ~0˜Ÿ“ÒVÏÑ‘•þB;|ºú£J 0\^ ICJÍË/dìR]<¢ùnW&‡o¶Í|He @/ÐV%âÊd|‘²zY¿åý …öþûÏ@Ï‹Få§%¨,¯¾ã É,°2^úF'Œ,¦Éß#©;ß>…œj–/€{mWñ I5 Ñ¡©Ø¢†áƒ 8¿ÃJ&£tá¹!¥¸ÒðÏÒ»�©HJqDÐÒÓÿ&“†bŠ&§%)Èÿä¥<oùBKÁ ž÷§ÐŸ¿ÉÄÐÔ°ÂS%Ã{÷ÉÛ^àc²¶ÉÝUEg/džpâË)¤¬117}†—Ý%„÷Cÿs7û»6<yÄIÕüh¤2fÃx PÀR”¹3!.XnßrÐéŇdä¤Ôë p*€ÂËÜ5M%t䄞LnMt6û•‘ÊÉF ý†êÀ(LåpÜXÝÓËBðaa¤2V%§ c~K%ÿ %úvûÜÀÄ“RÅnZ3€Ý¶I(#>Û†„âþ FADµ#|Û[¾Æ(KcÏ*¿ÑÀ*,™Ê†-JRMÀ6 ý»à$4–…t§”ä|ÙÚø!DÔ’×t%3)9;tuï·oòò¯¸R~ A@1ž•‡IE¥¼’^šҗ(¦ãP‘£v¼ÈÀ!á¨BCé/%Ût¡úR0¬K‚±HcþêCgº~QŒ ðó¥Wü«9¿uó³)Ôo;ÍëU]){–U}Ÿä/ý—²Ô¿Û`þ¬.®³:ßãÔ¦lØõ÷[­JU?È_û/e©¶ÁýX\¢¯ŸgÏ÷ûögì)󉫥'|¥+6¶Î¬Ëÿðÿßñ=q}t¥"*û?açì­ùýŒ'ó¶_«¬Ûgûlýø¾Û?­°W(«å)IÅ_)JDUò”¤E_)JDUö~ÌzûùŸ­Ž8þ§U]+?Èßÿ¶ÙÿêÛc”UõÒ”œUö:þZ¶çv[šw9xüiôÎÙöÝ—·}¸®ÙĶ«¤¢¯”¬|û>¿Øß³?aOœM\⯕Ÿ°óöVüþÆùÛ/Óöe~üR•×߇)ûù÷ß}ò÷e¯v=Û3}ó9¥znŠZ²ópå·}^ùIK¡}ûnéÛ+vïØc­l§ú¯ðŸ/~0öùyggZ¹ùzërAƒR”»oÿÏŠlŸ²¥ cüg ßóÛY´êþÑ °ÄQ‡,´ä¡‰a;'ôâ¿ï¾Éèßä¤q­}\d0)ùx¤–Ct'mÿ--Ã9y=)+§”Wû‰x•Ê%ýýåI T0 ÂÉ€0w*z€l4§ÛnPfèý)+£ %ÿ]õÂ‹å“ GN+?Jq/ò‹-*GröÎÃ@P„ý³íøÛÀÛþ²!qáokWùž‚hÓ‹K @bC_&“K+tg%7~”$îÃPë÷ ˜J! )% 059‰¸nFå͉¡¥”_ JQº@Â…oóv×¶/Ë+¡|˜VHI[Ÿ‰i(j�ÀgBKe-›œÛDÂЂÒXN É J Hfá=<3îžJÊBÒ–éÿæ°|îÒÉó«üS€Ç 4,0näÌѲ7-?A4¿ú]ºR¹kß&òÉBC~!€d§þ€6È ù(q…òËål3d$°žÉèÙï~BbˆiI[#±Iá¸g%2ËJ Ćt£m¿&xN{眈C6 Å£Yä,^ÜÜ‘¯úøÄ³doѽÔì¤ðáfE¦¯ô T°–‚ÑŠ¼„—JÑÀoñmÀÆÙ‰Å£ôº1\îó€dWÎQeîѰhfܬXb@±D·åbJP‰e§äÿß{Éò ñ ”„!$>ŸÒPÔü„VéÅ¡ÿd(´d‹fo} Bh¤1©N&>HjK,´’ö%ì”±0 +vFVN$¨NØ[as«ÿ;R³fs×ÜÿÌÙNqÇe:ê櫓«ìÜnß:ó¯}Ã÷o„uÕÒ‘|¥bß/3wÌ·S-ľeÕÄUò•Ÿ9¿/Æs—¹çsX긊¾Ç^ÍÎëSc”{¬Å2—Næm×ì§Yœìv7©Ut”Uò”¤â¯”¬eþµíì§0ìzùüÓªâ*ùJR"¯”¥"*ùY»™òùìg=_ž~5¦svËçwS¨Ì~?Ôº¹E_)JÌë}RÝócÕ™n¥©sоºR±o×™³f[­Öâ2¢*úéJÌë}RÝócÕ™n¥©q}t¥c/÷çe)±ë9ÖjÙJˆ«æÌëýø¥++6[÷÷d´bÑñ3Œÿ BQÓŠérZ‚ ÜîÙ7ì÷Ûï›î½÷3ëY7 Jºa-ºU¿B÷ÙÖêcÕe•çWûBn¡ˆè!Jt†íÿÛ¤js¶FB˜°ÞÝòK/lÛ{ºC&†àÍÒ‚€Û’  Tî[¡% ÝËJ HΖ?\P¤7•ÒÒäÂbR4´$®GÎS¾Ã~e "ú@ É…’j‚À+(cÆ$¤ûVéû}‹BÿØ35ã!Ÿr0•}…’ÃQÊ�©„'åä(¯ƒ B0gOå£u±|jy,´3á®ßO !—ÊÀ1Gn”åÀ€7 –Ÿ’”ý†l71xËÈ“@2-ˆHg,™Ð¥–7|coœ¡¿oЂÊC—”å eÜ‚Šá©ä4r  Û~€ÔVOB~ù¾)¤§:6FHÔ¿ù+¹_cÂE‘™B‡N¯÷�6 &ìJÅ„ 0bF”_�™²:6A\orZ;oÂKHÜ6â@)ÐI˜4§,44¢òKÉ(7`Ì”Pg)Ò„´ËãI=ûëž‚a ˜ZÉ]|­ÒZºq,41%”‰II}!„£ô–ÝìÒD$pÒñx°ÔÉ Ü˜MÍ0®fG-ÒS»áˆû~¼ô¿aB›â(ŒN_é @ øß ù4crŠ&àÔn¢ cþžÒ’’Xk«¿¼ø²@®!âRJ! 7î‚’_ ObYIéÈO–ü²Æ%ô>ßµÉÄ-Ãwî1%„†§ºHhJÐÊG+”Ÿ±X3ô# ôt¥ dÙÔJðgÉÄÐÔ‚3'Œ/ä?á¹ Ye±{çìã=ÓšÊpªjý`;N&’úC ¥†”¹7–Èåî’4®QEä'÷á‹ß>Û]0‰ Û””ðÑŸ¶N%ü4¼‚òPŸºúFÿ÷ï³!\7“Qƒ „ÝË&dr¾ÝƒÉ›|ÉB΄òËéÈŸŠ×Í�u±€ßòñ PWlã7O北û†+îßýûÚpæØ«üí¿ÛöÇf~+?ÙbþÕt¬ÎnÙ|îêuÇã:—{–U|îgÙxüêu›Çs:×WJN*ùJV~ÌzûùŸ­Ž8þ§TE_])_÷NNêÝY“÷o|ÝÜî-å}¥'|¥fÃ6ÙÕ™þûþ'®®"¯±×³sºÔØåë1L¥ÕÒ‘}›0óÿ_üþ擱Û+UÒ±—»óº”Üåœê1lµÊ*úë7}¿ß>;³á]¿Êþ«¤â¯”¥"*ùJR"¯”¥"*ù_ÆÃ›º|Ëwg¨¬ûvÿnÝð®ß>¯ð(«ë¬|ÿ>}·øÝ»·amØE]bß«3fî·[©„7uÄUó:ßãÔ¦lØõ÷[­JTä¤3lÙÝJ[1ç[ÔR"¯ö„ÒË&”§–1„a©ã?+w- ý`Öêæ}+X„Òû†bGNN& 4¯±E|Œ3p,žœúSK羜RY goòÙ9Mú>o›%Ÿ/=ö ¨rŠ Ý#†¤bK&¿Bz „ ÒÒœ„¶Ø¢úË-²¿×–a.Ò¯ói€` ‰‰b²2KÈŽZR„%(Ù%!=?’3sÑ’ßìŠÿñ7ÃZúz JJH`bF† Oû(”„Éý¿l÷H­Š&2 ¹e±i-)Á€îZ»Ô„¤f á)Gýÿy¢ˆhKn‚ƒ:7HfÿtLèù Y<¯‚Ü¡›Œuá°·X?åÅ_éxfÌ”ŒQ¢’Y†·I#dð0W& #dâÕÕ¶Ë{Š’`i0¼V !þ”†tFdü„1I -;'u~” )É_Oïu¾ÄÀ‰„ÒÒ‹,#¿&†¥$²%×%tç`ÍÆ§%›\àÂj‚ƒHa¨ J>-”WBRŽPoÝ(èÁ3¥;î~J6éË¡ÝÛaj _~7ü–K!$¤ºCs€á ù]!¹—¹‰, ”Å>mÆ^àäÒa]—H ùlzpg/ d%9%•Ðvíò8ãSõáð ú ĉEœ’JÙ;âÉ{¤¬Xg~7¯:3æNBýÖ!�è5!¤ÂÀn°ÎYHéB Kwt†d•ñ_–LG%¡—ò2¬ÿÇøç p:ñWë0`I0a ¤ 3l0187~ZÃYHo+(´§ší|\1¤fB V|ƒŸm•Û>Ûm»em@Ä Clœß’SÓÏë~”þççîì—«úÇÑWÊR—]5|¥)WÊVw3n¼e:Ìçc±½J«ˆ«ågùÿöÛ?ý[loô[åænù–êe¸—̺¹E_gù ÿeìµ/öØ?« ¦Ìëýø¥++6[÷ôeîüî¥79g:Œ[-uq|¥c¯æçe©¹ê=Ôj™j«œUò”¤E_)X·êÌÙ»­Öêa Ýuq|¥)WÊR‘|¬Ù¿¥efÁë~þÛ¶ß²·í¿Û°–õrоÍòW¾ëùK^íðwWWJN*ùJR"¯”¥"*ùJR"¯³l¶Ûm›l­¶3kY4˜‚j$;©÷f|ûã¿ß}÷ßï¾öOòþËÙj_í°VWLUþà4½ÑÊC$¦I(„'•Ã:†¥‚>GÀ8CìµÞ‡�™ @`!äw ,¶Åq{1)_&¤7~¼Ý·CgÞùVî竱ߺœóÏÊuUÜ®Æâ8ª¯÷‰2K&”QiÅ‘·ÅpÄvèÈC6+ÒïÎOÈFú­�0Kd“KI/t1e~_ß’†ôbМS¤nø¬‚¹\')W‡¥£éUþ¤„`ÂE ”„²]öì†ýð,´æÿ³~ŸÛ?¼ÖsvËçwS¨Ì~?ÔººZ|¥)i*¾R”ˆ«å)HоÆ_ïÎÊScÖs¬Õ²•WJÏØÏ׎cyëøãù¬t¢¯®”¤â¯³wsÕØïŒÝNyçå:ªë;©¶=kfÍÎWu²”¥ÕÊ*ùJRqWÊR³a›lêÌ¿ÿýÿ×W×JR"¯”¬ÿfßìý°¾ß¶­øWWÊφﻯ2¿Ü;æøN]]"*ùJR"¯”¥Ù.އß-Û£»ï™ÜKæ\¢¯FÏûgûoÍû;gý„ÕÒ“Š¾R”ˆ«ìuüµmÎì·4îrñøÓêéY»?åïŽìi;òô¢¯®”¤â¯”¥"*ùJÇ^ÍÎëSc”{¬Å2—WWÊR‘|¥)WÊÏ·oöíß íóáÊÿõtˆ«ì[õflÝÖëu0†îººVlÆþ¾{ÎVÇcå|Ù‡Ÿúÿç÷4ŽÙZ®”œUò³9¿uó³)Ôo;ÍëU>¾î¼Êÿpï›á9urоR±o×™³f[­Öâ2ªç|¥)WÊÆÏûgûoÍû;gý„ÕÒ"¯•›3ž¾çþfÊsŽ;)×WHоR”ˆ«å)HоR”ˆ«å+3›¶_;ºFcñøÎ¥ÕÄUò¼®žÒœÜîÍÜü­Øýºª)(«å)IÅ_)JDUò”¤E_)JDUò³fuþüR••›­ûùÓ¿Ìg}Âz>Í×¾[»˜÷¨”Uöm‘¶Ûm³m•¶ÆmWJÎêmZÙ³s•Ýl¥)q|ønûºó+ýþo„åÕÖg[üz”Í›¾ëu©J«ˆ«ågs>ËÇçS¬Ü~;™Öºm­¶_êRÿÃúøºg7î¾ve:çcù½jˆ«ë¬Ýöÿ|øîÏ…vÿ(Wú›äí÷ß|ûåï¹»ÕÄUöw3ì¼~u:ÍÇã¹k«¥'|¥)WÊR‘|¥)WÊͲ¶ËýJ_ïø_WHоR”ˆ«ågìÊýø¥+¯¿S÷õtˆ«ìÎoÝ|ìÊuÎÇózÕWJDUò”¤E_)JDUò³a›lêÌ¿ÿýÿ×WHоÎêoZós—™lµ©Uu™ÍÛ/ÝN£1øügRêå}›0óÿ_üþ擱Û+UÒ“Š¾Ïœß—Žc9ËÜó¹¬u])WÊW„ Ä!VB6Á[mQ(«å)IÅ_)JDUò”¤E_gÎÇ«¹ÿòØóÎêuÕÒ‘|¯,‘×ó©ÑŸïÕ»7Ê›ÕQIE_)JÏŸ}¿ÏÌø^}ò…ï§}t¥"*ùJR"¯³çcÕÜÿŒùlyçu:êéXùþ|ûoñ»wnÂÛ°‰E_])IÅ_)_ÐCdüÃ~s¾ÿoúŸê%|¥+>v=]ÏøÏ–ÇžwS®qW×JVlÆþ¾{ÎVÇcâ*úéJÍÆíó¯:÷Ü?vøG\E_>íŸo·7nÏœ[gWJDUò”¤E_)JDUò”¤E_)JDUò•›1¿¯žÆó•±ÇcXùÐR Ì„de+mŽÛc‡m°(«çB’ßî“]Û³>É}„3:Ú¢”ˆ«ìû'}öûæû¯}Ìú®³º›cÖ¶lÜåw[)J]\E_)JN*ùJR"¯”¥"*ùJVn7oy×¾áû·Â:â*úéYœÝ²ùÝÔê3Æu.®"¯³çeüÜRÕÕß©»êºR"¯•èH×WÍþ^'ã>ùjÛ¾¨¤¢¯•Ÿ°óöVüþÆùÛ/ÕÖnŠZ²ópå·}WÍ™Ï_sÿ3e9ǔ뫥'���ˆ����z¿óýgÛ·ûvï…vùðå„z-ú³6nëuº˜Cw]\¢¯”¬Ù¶ßþØþÏÅöÛmªç|¥)WÊR‘|¥)WÙû1ëìwæ~¶8ãúUt¬lû¶}¾ÜÝ»>qmœD¢¯®”¤â¯”¥"*ùYû?eoÏìa?²ý]"*ùJR"¯”¥gí¿ÛöÇf~+?Ø/íW×Y¶B¶Ù©Kýÿëâé»íþùñÝŸ íþ ÿUÊ*ùJRqWÊR‘|¬Ünß:ó¯}Ã÷o„uÕÒ"¯”¬uìÜîµ69GºÌS)uq|¥+7qçü½ñÝ's¾^ˆ«çÙ;ï·ß7Ý{îgÕt¤E_+3›÷_;2FóæñÔÎÙþý—ömø¬ý„?£¯æçe©¹ê=Ôj™j”Uóf7õóØÞr¶8ìkWJÇ^ÍÎëSc”{¬Å2—WÆÏ»gÛíÍÛ³çÙÄSwËߨÒw;åêºDUò•›¾ßïŸÙð®ßà¯õ\⯔¥"*û3›÷_;2FóæñÕt¤E_)JDUö-úó6lËuºÜCfU3­ö=KwÍVeº–ªºÌë}RÝócÕ™n¥ªQW×JRqWÊR‘}™ÍÛ/ÝN£1‡ã8úºVw3ì¼~u:ÍÆÌãå}u‹|¼Íß2ÝL·ù—WIÅ_)JDUò”¤E_)Yó?uŽîa?ò½\E_)JDUò”¯~5™Lÿ¬Þ­”Üîë|¥.QWÑJRqWÊÇÏóçÛÛ»vÝ„UÒ"¯”¥"*ùJR"¯•ý;dõ„‘άÎ:Ô}E%|¥)8«å)HоR•Ÿ°óöVüþÆùÛ/ÄUõÒ³9¿uó³)Ôo0þoWWÊÎêmZÙ³s•Ýl¥*®±o—™»æ[©–â_2å}t¥'|¬ÝÝ_7µeæáËnú›¾ßïŸÙð®ßà¯õ\¢¯”¥fu¾Ç©nù±êÌ·RÕ8«ë¥)WÊR‘|¥)WÊVg7l¾wu:ŒÆŒãèÙÿlÿmù¿gl⟰™E_]bß«3fî·[©„7uÕÒqWÙû1ëìwæ~¶8ãúUt¤E_)JDUò”¤E_fÌëýø¥++6[÷õt¤E_)JDUò”¤E_+{-{ó»);¬0êºÍ™×ûñJVVl·ïå}u›äí÷ß|ûåï¹»ÕÒqWÊR‘|¥)WÊR‘|¥)WÊÍßo÷ÏŽìøWoðWú®³öe~üR•×߇)ûùE_]{¤k S8×5Îøñ9®ÊzŠDUò”¤â¯”¥¬4hÀÿ|Û}xÿ÷lþß³²å~JW»¾GϾÜÖ;ýöù¿GPçݽÚ,$Å#¡Óöt}þ%à‚Ÿÿº2UÐé^Þ†:¿ÏR¿q¬”}Ñó©nìß}Ù™ÌîùrlÎzûŸù›)Î8ì§]r«ë¥)8«åyCF –Ã[ ã–ζsž¢’оR”œUò”¤E_)JDUò”¤E_+>¾î¼Êÿpï›á9utˆ«å)HоR”ˆ«ågÃwÝ×™_îó|'.®‘}Ÿ³+÷â”®¾ü9OßÕÒ‘|¥)WÊR‘|¥)WÊR‘}›1¿¯žÆó•±ÇcXúºW§üÜÇÛ„û«3¿¿ÿ}³¸ùE^›6ÛÿÛÙø¾Û`­µ]zwNmÙhæ™÷e}Öqì?|ªÎ–I­¶p„õ§¶o”¥ÍÛ7í¥}Œß÷VuoøvÏøŒ»ÐK¶dŒ7¤–eŒnžzvrR7ßü7]Í!† šPÄîœùJç©þHGãY;çÏ·í}šM+ô`ш&ôý²Kå`Ä£ðÂË,–3ää:ù`eßÜúêÿ4°Ð(ZP’hgKôb¾àg£“JËáÊùA¬Ñ;œŽ€pÄ“šJÅü€¿ì’‹& ¤¥%t#=[ ù?kŒB I\7† ™†ý‰c7- 0´$´ä†¤¤”'“úþ¹$´ðÀÌC!rÉ„­¿B:RKêw”’ihNÉÛ}‹Bq{¦ðÐhò„ñV•�W90š^& É¿J2‘ñN†ÉA3Û 5 –36MàC ¹8­Üjv|JNÆdü[ ÅvùIHﮃÉ;M%¡B¤’†§ð21%rѲI•»î„¶Fʶ%$4�Á I@c¡†lžé!eü” FFû 1öAiOG”÷wËì¼ HM_ð‚ZÆáŒ4kæfws™–õØ�t™H ÝŠBPZ:7ä-ÐÅâó”’ž^цÛî×ËŠJKn3£t#ìœß~ï¸Oï”ù³æ^§@[‡ÑWà¥)uÓWÊÌë}RÝócÕ™n¥ª®‘|¥)WÊR‘|¥)WÊR‘|¥)WÊR‘}ŸäoÿÛlÿõm±¿ÕÖ2ÿZöÇöS˜v=|þiÔønûºó+ýþo„åÊ*úéJN*ùXËÝjßÙlaÜåsñ‡Óq»|ëν÷ݾ×W(«å)IÅ_gs>ËÇçS¬ÜaÜÎ>®”ˆ«å)Hоô¥gçý±¿þ;e‹ã¶ÿ«P¡ƒ36lÙ†6eaŸo˜sf¨¬[åænù–êe¸—̺b¯Ž½–½ùÝ”ÆV?˜tøonHÌ´|½û2÷ùKvw3ÑY,·Kð?ò›v1Juö>¢"¯ì“I£fÈßwKÝ'mЯ™=äî»ô}ÌhÃ\aDÇøšMIeärÆô'†b¹/©°jC‚ú?lûá·ÁK è^ã?ÜgùÛý¶ßrûoÆ!m–ϯÐÀ')˜7“íˆA¡›-(Bò }±hø–¿ý‘¶Jú/ `*Ö¯Þt€ì´  “q5?ä &ï’Z é@ßÉAŒ¶(”œÉCä.Ìd9X´!‹ût$¯ñ4¿Š(¬hÏö éA/1[¡’‹¤B!trË-ˆÅ|’ÊJ pÆt ¦/|Ų‚BvKGJïMÄ¢nb`Å“3%¸ ãC~)9#•Òý·JJ¼Ÿö#¯oSðºêúÃR’úKé&¤1ÝÓ‹@ϲR‚i]¿-,íѲJg³€ì˜Xn)#(´äpÞQ4 ¥9°ÏÃ:rPŸ¸gÿä¾ýv€†a˜°*04¼È)%ù{t“I©Oßp”•÷B7e”1ÑyRbCM@o� ›Ó¿A ²ÑðÝ`Ôp£Á/ŽûÝײÙB³,ì¾&š¿è¤2jr9 )ÈéÉÁ¹|¬RÙ t •ÿ%}‰h•·¾D§)ˆA/1Ê ðÜnGå–ë+¾ß)1½¼0˜Z!ˆ+ç+rPÕ† ¬²zC�ÉÈ) ONZWè×Ðɤ/ˆdÒÀn4¤îÅ£'ýÊ BC2S€¿Èݹ\±¤¡©ÊÿWþæ ʱ�v*ÿÏT»$Ä?”'wÝ,öfC%Ѳ;\kè}_)JÏÙ_c¿3õ±ÇÔê®*ø·ëÌÙ³-Öëq ™TÙ‡Ÿúÿç÷4ŽÙZ®’оR•Ÿ±Ÿ¯Æó×ñÇóXéÅ_])Y¶B¶Ù©Kýÿëââ*úéJDUò”¤E_)JDUò”¤E_)JDUò”¤E_)JDUò¼! ¶güì§îŸûfεóø¿QIE_)Y³í»/nûq]³‰mW8«å½ ÿûq½{üÛœ¤s»lÝö>ÁJb¯¿%Ù÷ßçoŽ9_çC¬zÖÏw€vM…ý‘òP¢Ðã:B”v(öå„í]îN,0¢‘Éxc)=.û!Üoëß»õgº©&ñ¥£~5¯ñY²1kSd䤣÷[�ã'ïsìäñ@5ª¯é†€Ÿrƒ @jQe’ŸYiï¿@m‚Lû¡;%÷›ßt I3�RP öÌü¯ñ|˜– /ô’ßòÓ˜%K¾hPM (7òJý)Y0±©ÌJ/ !ŽÃ0cü…ñ™WÑC@R„4¤”YhÈl7rƒz„}Ë(®‡OìWuûÁo¿ß0xQÿð÷µ«àŠ/†}3† ¶I[l^é<†Æ”Xcî„mº;q¿#y”T“ NAðg Hi+b‰›7¤”‡åí†mƒ‘’ŸÐ»žPae–ŽRKAiG%†bè(¤2@Ào)Ü3¤”VJ†tï‘õG ADÄ”’’ÆyNXfìÜi( –œž7?(¾ŒºÇå‰79ܬàS€ï•¸N&·O)?ò²q\–ƒF€”¼_d#£d”û{ãa™$ÎR:†¡ÊFd1â™Ã~Øhω#w+lÿ_U(”MÀWrÆn‰¨d 3p”ˆO‚rI¡f”É{•ƒ xoÜ´þJ½ÒŸÊ/Ie  |Å#H3íkûeqx:U@W) H ?ÅníŸd£~^/$”–èNGèm–Ýï`M |Xk?Ť†ŽPÔ€Û!9§Ò7)’^ß'ü37Í|ÙSÝÙ èWßï» ¼œùºß73å.õ€!+†ä“8i] A/ ¾Œ3#¥;¥º?„§?Ùÿúô·c8•)gŠ¢¯¼ñcIˆ%8aKÌ4jþÑøovq…ñÓÙC>×Ïo±€`’bQE§ýùa¿n¿@ÄüÒR $ C’‘ûëã–…è«å+;™·^?²fsÆñÕw¡E_fï·ûçÇv|+·ø+ýWXùö|ÿ±¿f~Ÿ8š¹E_)J÷t¶ùótãûwØÜÏñýÎú"¯¢¿%³­mº¿Ûý»vvYËÃê)WÊR“оÏWsþ3å±çÔë¦Ùm¶Û6Ù[lfÕt”Uö}’¯·^ëZ÷}úðººRqWÊR‘|¥)WÊR‘|¥)WØ·ÊÌÝû­ÔÊa/ÝUt¤E_cçÙóýþÆý™û |âjéHоV:þZ¶çv[šw9xüiõuéHÄ~Ý"‘ŸÿÕ°àþÛþÒŠ¿Ò“@®ø´6Ì‹@Ôä'¥ºPØ´tfû¥hèÿ¡—z€Â¾(0˜L@jI¥ŒZ@¿Gû£'³ èûlÆ7ï¿kûF# ”Ù� ¼MÁ›ô¥Æ!(ûmÐÅâ‰M“õÁIL€ ‚k~.„ä}Ÿq¹;¿û¤„§!?çÞH¿Ö1Ò¯ö i ®z@Èah/àÂQaŽR cwFIxÇߣ†±Hù“®˜ J(„„tPj îC!n7¥9¡®Vø7b^)Ò–F_C\Á¡ :!rƒCCKNàYÊ %ò^FÈÉ@jZs–€Ôó“¸C[À¢8ᤱ„ÃÿÅ–Ûð9E!(äˆK–œZ¶ÚãëýBâ¿`ªªþ±0 , r‹á¨-9S|Q)JÈA•ÿÈühhÄ¥òw¹$0Þ„§òÃI�Tnó–G(²·Ü”˜µ%eö4€0‚ÊØ±˜n ÉäÔòÃxFéKAh%¡=·ÉK'åP†MIhGÝ)ÄÔ%8„XfIi†äy1²7'ä¥öÜoÃ5–RLQ¹B–8€:uy$ÞS†$a5º”‹,¶Û|ŒQHB ÿôí“úvå!w2t’º –€/ËØ–Pç¹ImŽNt?@Í™îéy8·€`¤ŠÁ)rŸ†çá…àžPb”t3þáQ &“ pl[ò“ÊJ@SÓ’Ñú°Õbû·OiÔ¯ø±b=ÉÆÊ¯óÙ8„Á?#¥?ÿ‰OöÙ.7b–ú NÎ×{ð€–À`®—AIƒÒ[º1DÞVùÂKå¥.ÉCl6ùªRJ&%(å29iO@FÙ)ùH ~øajuÿ–«èÀT` I¤Ô£|Y0˜3—’Ê)8—ÕË’“‹CbÙÙû!òn¬8y†€³ÓWð€@LNÈ ÌãR5�ô¶-=;¥;—ƒY ܤvΔ¥ßÞ�j Ýó>è |ΦÜÆw½ A„Ô2 ¸3ýÑ’VÙÊ%#d÷NJ~AIÎß9êÚð—jYÀ m5}ê)­³ð>ž?¶_â¶µE)vSWÊR“оR”ˆ«ìÿfßìý°¾ß¶­øNêmZÙ³s•Ýl¥*®’оR•›0óÿ_üþ擱Û+N*úéJDUò”¬ÎÙöÝ—·}¸®ÙĶˆ«ë¬Û#m¶ÛfÛ+mŒÚ®‘|¥)WÊÅ¿^fÍ™n·[ˆlÊ«¤E_+6ÙþÛ?~/¶ÏÇ«l#Q×ós²ÔÜõê5LµUÊ*ùJRqWÊϲwßo¾oº÷ÜϪéWÊÏ·oöíß íóáÊÿó¡°FulxÞ¥âO?©küyõŠ¿Ò'4Ô†”Ÿäd”Ò—JKÅ|r7ßäÖßµÞà!(“É`0žŒŒL(4¢·ûöß>ç#'©‡Uጜ;çnÛô¾|ûço̽€Á¥ -<„Z~,4j>Ý;äј33£þù,÷×άë0xq>º¿¤R Ø4féÄ ÝÀÂ�,-?•¶Ý`,ü—þFA¯|uÓ (ÄÄ€ßô0„ñ¹±a¹(ü7é-¼ûü’ÓÖeƒ–Z@©hû¡ÊA]‹G, òÜ¥Qd¤#¥9E'•¿MB�¨�°4´¶å -(û“F d!%æÈ ߌ(oOìî× Ô/©ßfZª¿¦¿€bYA˜g,5‚òK(¶ü†Û”0¼è+”¶~¨’aA¡„1¥þÔ¯’÷Å«ÀÎRv$än‘… fëþÎÿ•˜ tþLJ1lÊ!~ S†d9+ºz�Ã¥þfmhå e’ü˜€Ìé&†¤1ö, '¸fhÌ¿ŸfçÐ1±=Lx½â¯ÈZv-’Ê+t­#y@gź ’ÄÔ§ü3üRy#iÐQ5 Ie 5¤¤¼ðˆ|šZÆô?RÊ~èÌ‚ß"߀2Ýñ4¤§üYEòKáŽ_ò~/rËéœQ{¿H¶Ê!æ&nSb’3†rù3„òVIhßäC!Ƥfã|ÁcŽY‡ _攕ƒ›†–’SRKBx@Ü„tÿÀ²T_ܱ¨ý—zÀ`+Ãwù<²Z á©Ä×ÈFœåôü„¡¾BP‡,5ó ×A…“C�ÂK- 6JI˜ rŠb¿%î‚ÑÒœ’‘ |sgé¾kŠFFCnÝײÒî7í¶~—Û-wJXñN¡b€eM_ GC¸Ïÿßô cñ›?_s”µfÆTg7l¾wu:ŒÆŒãêézöu|¥)TUò³ö~ÊߟØÂ;eúºDUöo“·ß}óï—¾æïWJDUò”¤E_)JDUò³ý›³öÂû~Øz·â5]"*ûÂ{²›åüûå~ÍÜ~[7[}QJJ*ùY»™òùìg=_ž~5«¬ÎÙöÝ—·}¸®ÙĶˆ«ë¬ønûºó+ýþo„åÕÒqWÊR‘|¥)WØËÝùÝJnrÎu¶ZêéHоR”ˆ«ìîgÙxüêu›Œ;™ÇÕÒ‘|¯èÌ–é?íÙ{ïöØýΨ¤¢¯ô(јQy.”}¹|šž^ã1%$¿Ñ•³ý¶V{ Òa5%»d šœÊ(™˜``Â[!?b[£§PÞÃ7]òêÎæm×ì§YœÃ±¼uÊîÕUþì´äÑŽZ”`‚Qx`iE†# ±½Òá£wéùHäzòèf(‡Ðxný�Xhn ÈlK (”KOßrQjHÅ|–¾8Öåæÿ»lÛo»æ[37ÿŸêùy›¾eº™n%ó.Éò°uØÀ 0ä²€-/’þd#$!(tòXº[•‚[£ü1þ×–�8& BC6Ù%†tt%)FB? VÙ„¥ðÇ%œÚñˆ+#!Ht fù ¶Säe¶VS™¬’%ðbÿh«ìÛ![l¿Ô¥þÿ‡õñuu™Íû¯™N£y‡óxê»Ð¢¯”¥'|¥gvíöì¯óíÅçÎ!õ\E_gÎÇ«¹ÿòØóÎêuÓçcÕÜÿŒùlyçu:êë;©¾=jwÍÎ^e²Ö©E_{-{ó»);¬0êºRqWÊR‘|¥)WÊR‘|¥)WÊR‘}Ÿ8ó÷Wøîæñß+Ñ—»óº”Üåœê1lµÕÒQWÊR“оR×÷Od¡ùoß û·Cæ©·5VIE_+7É^û¯å-{·ÁÝ\]]'|¥)WÊR³:ßcÔ·|Øõf[©jˆ«ë¥+>ÉWÛ¯u­{¾áÝx\E_]gs6ëÇöS¬ÎaØÞ:®‘|¥gu7Ç­Nù¹Ë̶ZÕWWÊZÉo·FåîŽÑÐÜæÛôâK«œ?ë$¢¯”¥fÙm¶Û6Ù[lfÓŠ¾ºÎêoZós—™lµª®‘|¬eîµoì¶0îr¹øÃêéWÊR‘|¬eîüî¥79g:Œ[-tÛgûlýø¾Û?­°W(«å)IÅ_gÙ;ï·ß7Ý{îgÕt¤E_)YþFÿý¶ÏÿVÛý\E_)JDUò•›Ûç^uï¸~íðŽº¸Š¾V}“¾û}ó}×¾æ}WHоR”ˆ«ìÝÝ_7µeæáËnút;?|íÆq ÊQ?¬Ö¨¤¢¯”¥'}Ÿ³¾Ç~gëcŽ?©ÕOÛ·íŽÌüV°_Ú®³ö3õã˜Þzþ8þk(«ë¥)8«å)YÝM±ë[6nr»­”¥DUõÒ”ˆ«åc¯e¯~we1§cÕæWHоR”ˆ«å)HоV2ÿZöÇöS˜v=|þiÕuÔßµ;æç/2ÙkT¢¯®³ößíûc³?Ÿìö«¤â¯³wÛýóã»>Ûüþ«¬Û#m¶ÛfÛ+mŒÚŸdï¾ß|ßu﹟J*úë7w=]ŽøÍÔçž~Sª®“оVlÎzûŸù›)Î8ì§]]fù+ßuü¥¯vø;«‹”Uóì÷Ûï›î½÷3êºÍ¶¶Ïß‹í³ñêÛÕq|¥)8«å)HоR”ˆ«å)YÝMñëS¾nró-–µDUõÒ”ˆ«å)HоVwnÛ~Êß¶ü_nÂ[ÕÒ"¯³¹Ÿeãó©Ön0îg:SÃÿÛgÛñìÿ;gý–ÛµE%|¥)8«å)HоR¼fù’·^Ãß¶S¬lŸ;/æâ–®®ø=MßJ*úë6¶Î¬Ëÿðÿßñ=t[õælÙ–ëu¸†Ìª¸Š¾V-òó7|Ëu2ÜKæ]]'}›îû}Û·Ûvã•÷êë;™·^?²fsÆñÔηØõ-ß6=Y–êZ¥}u›¸óþ^øîÆ“¹ß/UÒqWÊR‘}ù'd¶OÎ3w9Ÿoöÿ-±ú¢•™Öû¥»æÇ«2ÝKT¢¯®”¬ÎÙöÝ—·}¸®ÙĶœUõÖ:þnvZ›ž£ÝF©–ªºDUò”¤E_)JDUò”¤E_gÃwÝ×™_îó|'.®”ˆ«å)HоR”ˆ«å)HоR”ˆ«å+>ÏŸïö7ìÏØSçWWÊVm‘¶Ûm³m•¶ÆmO—óqKWW|¦ï¥}t¥'|¥)WÊR‘|¥fî竱ߺœóÏÊuUÄUög[üz”Í›¾ëu©Sñˆãgl¾£Û6ýŸþÊ_VQIE_+?f=}ŽüÏÖÇSªŽ¿–­¹Ý–æÎ^?}\E_fv϶콻íÅvÎ%µ])8«å)^¢‘úÛ?éãûeþ+aJ*ú)JN*ùJR"¯”¥"*ùJR"¯”¥" ���È����z¿óý)HоR•޽›Ö¦Ç(÷YŠe."¯®•Ÿ³+÷â”®¾ü9OßÕÄUò”¤E_+ÐŽŒ´ôœ¾0vÀ{l³ÄñÒo»í÷nÜWmÛŽWÜG«”Uò•éÝ9·e£šgÝ•÷Yǰýòª"*ùJRqWÊÏÙ•ûñJW_~§ïêéWÊÇ^ÍÎëSc”{¬Å2—WHоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоR±³þÙþÛó~ÎÙÅ?a5q|¥)WÊR‘|¥)WÊR‘|¥)WÊR‘|¥zP„³ã¾øÏ¾òÅqûýÕê%}›Ûç^uï¸~íðŽººRqWÊR‘|¥gù ÿeìµ/öØ?« «ˆ«å)HоR•ÔÛµ³fç+ºÙJTE_])HоR”ˆ«å)HоR”ˆ«å)Y³?õÿÏîi;²´E_]+{­[ãû-Œ;œ®~0ú¸Š¾Í›mÿíìü_m°VÚ®”ˆ«å)XËýkÛÙNaØõóù§DUõÒ”ˆ«å)HоR”ˆ«ìÜnß:ó¯}Ã÷o„uÕÒ‘|¥)WÊR³fÛûcû?Ûl¶ˆ«ë¥c¯æçe©¹ê=Ôj™j«ˆ«å)HоR”ˆ«ìuüµmÎì·4îrñøÓêéHоR”ˆ«å)HоR”ˆ«å+>ÉWÛ¯u­{¾áÝx]\E_+7}¿ß>;³á]¿Á_êºDUö|ì¿›ŠZº»àõ7}WJDUö}“¾û}ó}×¾æ}WY³úùìo9[v5«”Uö-òó7|Ëu2ÜKæ]]fù;}÷ß>ù{înõq|¥)8«åfãvù×{î»|#®›¹Ÿ/žÆsÕùçãXú¹E_)JN*ùJR"¯”¥"*ùYœÝ²ùÝÔê3~3«¤E_c¯e¯~we1§cÕæWJDUò•ŸgÏ÷ûögì)󉫈«å)HоR”ˆ«ìuìÜîµ69GºÌS)tÛ#m¶ÛfÛ+mŒÚ®’оV}“¾û}ó}×¾æ}WIÅ_gu6Ç­lÙ¹Êî¶R•WJDUönãÏù{ã»Nç|½MÜyÿ/|wcIÜï—ªé(«å)kÉï‘Ñ÷ÿå£qÙ?g4ìv[>ˆ«èÙ¶ßþØþÏÅöÛmªë>¾î¼Êÿpï›á9uè,où“—Ûô}¸ÆßŠÏÛ;~ßçË”Uù)JU|¥)WÊÍ÷}¾íÛŠí»qÊûˆõuå$–„%ºnÉÍóã¾3ãe}›¸óþ^øîÆ“¹ß/Sç7åã˜Îr÷<îkWWÊV~ÌzûùŸ­Ž8þ§U\⯔¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJV-úó6lËuºÜCfTE^è9Ûî–ÿ~íÛf?ì%:ê)IE_)YöNûí÷Í÷^û™õ\⯔¥"*ùJR"¯¼'¸^o»ÿ³~ï›:òKßzŠRQWÊÌæý×Î̧Q¼Ãù¼u]'|¬uüµmÎì·4îrñøÓêëÓŸ>Ûüý¥·Ç·øö}º¼¢¯‹íÖ†ýA ËË=\“›îs›­€XVå—¾Ü$°Þ„6îÇ# öÌ¥ °þÛý¿lvgâ³ý‚þ׺Ø Còa43ÉEôŒgOÃ>N-³gO݃vù;6þçØq➪¿Í”¯22QÐèýÆ¡K¾ÄµÆ'2;­Úô¤ P‘4¾_J g=ƒ:Ii)8–ŒŒŽ”2A!Zít†¡;¤¤î„ŽžRË%14¢hì„îYhÎŒÛd«"…d0c#ÈO!}€§ H`ÇHNB\´?èÅ)#P5Â~¼þ‡sÌsÉÀ?ª¯ 7,5)N,Ï‹Nûa¨å!A¼²øa/a¼ Ù%)FOt\@�„�ä­Û#díÒéÙòP1 ùe¬#^B²]Úõ(�Р†7„¹lŒ„ìKÁˆJ0ÝV Û¡~œÏŸæ³“ BI¥ãŠå”Ýà +ò “‹HGÿr²6=‡S:€ˆiÕÿ'Éß#¬$à„Žuæt�–£ê/µ‰¥1Yþؤ¤¢…#vÝ$ÎCIIuòùa¨J1Cví’÷ÈX×WÊß>N}ñ®ŒÝÝп³;=ê|�6"QWä¥)vSWÊÎêmZÙ³s•Ýl¥*›0óÿ_üþ擱Û+UÊ*ùY¶ÏöÙûñ}¶~=[a®³ößíûc³?Ÿìöˆ«ë¥)8«å)_““û/cwß>ÿ|®ï¾[â,¢¯¢½].s©f6™nof“öcרïÌýlqÇõ:ªâ*ùJRqWÊÌíŸïÙfßŠÏØCú:þZ¶çv[šw9xüiõrоV|7}Ýy•þáß7Ârêë?íŸí¿7ìíœSöW×JRqWØËÝjßÙlaÜåsñ‡ÕÒ±o•™»÷[©”Â_º¥}t¬eîüî¥79g:Œ[-usоR”ˆ«å+Æ„ŒÌ¬ýkÏÔ¦;·[㨔Uò”¬[åfnýÖêe0—î©Å_]+?ÏŸmþ7níØ[v_–ÉC''eì1¿Ý{¿âŸ­LUý"hhì‚’ƒ‚ÒØ'¶ÜbI.†ß—ízPT”4„Ãz[ &ô ®PÌKûò›ý²R„•îÅ^!·ÿçGtoÙ¿Ø%Ÿååü£Ÿ·Þû 1“qDÑ™%ätâÓ“º² ]„ŒÅòV(á…öøeæã8çêuÕøPP‰…†ð2’MBƒ¥)B Å”oö~PÌŸóçW²d�ëÐV(›¶FHa1 J‘… •ÊÉ å'¶Z_$ïýô"a†!N ²y§~Ýt‚W,§ûd’I쑈û^xš€Â¿ÊGÅ•‘û‚÷ -Ë!}ºCxÂÒã>Ý>òÉ<æZ–,A:º¿‚Qd.Lq¡„Ì‘£F±E|åâR3öéãQƒJÙ.€"~R2@tW%'¤¼Œ€ÒÀ®Ø¤tþÁ¹Ó¸gÜjOÉÖÂRy1?ÂðO,!%îZP3ô’÷IaŒ‚Èã.ËûnÜiA©ÊîL+ߤ4jBPJ ûì”%#2­¾î{¾ߘÏÈò«ëÄÔqa¹h ) †!âËü””äîKNnÿ¥ìé{¤J!†’hhFNÃJ%•†¹/ Ha!\7ä¥)CcÕ` N&†7:J@/$4iE$›Ð’ÀÈÔ££ ´d#”Z~3>jÎŽþ_û BYx à/‹Í‰»rRy/¥ /dfIjþ1ìs“ò•–NV_ó$7§7Ã;u£¬r“þìÉ[):É}|âjMWJ@(èù%0ÞÛ#,¾°,1ÆmžJúù&ù;}÷ß>ù{în÷°œp�þί®•û§ÿº^ïºûîÛ~¦ÎÛú‹¦š¾Æ_ïÎÊScÖs¬Õ²•Læý×Î̧Q¼Ãù¼u6ÈVÛ/õ)¿áý|]\E_gs6ëÇöS¬ÎaØÞ:›6ÛÿÛÙø¾Û`­µ]"*ùJÆ_ë^ØþÊsǯŸÍ:®qWÊR‘|¬[õælÙ–ëu¸†ÌªºDUò”¤E_)JÍ÷}¾íÛŠí»qÊûˆñ}t¥"*ùJR"¯”¬Î·øõ)›6=}ÖëRªâ*ùYó²þn)jêïƒÔÝõ{7;­MŽQî³Ê]\¢¯”¥'|¥+;™·^?²fsÆñÑ|ÝÇŸò÷Çv4Îùz®Ö0géFΞ‡_Û²œï…?m¿mY‹ã9eâVgù# ïÒœ”¡™¸£}§Wî €Rƒó£—“†#g߆âYY(+»ïÿÝÙ½õ¤ 2PÄ4¡.Èß0&13!ƒq-?ì‘¥n–Êèµò?Æt!{m›ûîo/¡=öG?¯ý’~÷Û�vƒ …rjYHß”’ƒ_£°JzF—’P$q‰ßëÈCšqâÈÊ#WWñy5 �­,CãK@Ü4¢ÐWíÒ_&§r²2~ã b†öût× Erƒ &ðÔ šQ0 „â’¤â‰(N^é+!$Þê$¯µí¾É%$¤nL/—÷J ؤä”ḗaHNÿÒK) ¾ª !¤ ÄñŽ’M bj2zŽØ5(Èݶ%t¯~²‘y‹sØå¡]_Á)Ô|t†:::I]JFÄÍ”å#òºKpϲÛkÍ šÜ4†Xj1þÁˆ-ßt HÂøgBKbÔ3 —ößÞˆ0†Z &'0&''ïÊã6/’ñD°ÔS ñX§)bÓÚ¼�Q!¡¨èYHÝùLñ4”éG Ü•’–Ù o“º#Ô‘Œ¥“û?±ÑWðC ¡¤Ü¹h ៗ²2Rœ–N+¡8¢aEt%¾7rþ»ê€Òü†®ÀSp¹h,h!‚ä’ÑËb‰§ ÿ½á� c#¡%wü¢Óú ›$¶ß§b¿^Nø;üÕ�Wí²xg/ÉmŠ%÷ÊÙß%ûä·Ûnÿzg¥³÷Py¦ÑWý\0´•œ¿÷ÖAH,fJ ûŒÂPR:Qòp-eîèÅv¾f ÝЩ+%.å#da£KÿäËt²\opŽèÝõé GÛ“ åRÒ²xÒ`b¿è,¼_ÈèOåw))JrzÕyp‚‰ˆÍöê~‡Û #¤%(PGOá Ýš”žs`ñ 4Š¿ÏR•Ÿ ßw^e¸wÍðœ»Ú³«ë¥)WÊR‘|¥)WÊR³9»eó»©Ôf0ügW×Yo±ê[¾lz³-ÔµUÒ"¯”¥"*ùJR"¯”¥cçÙóýþÆý™û |âb*ù³úùìo9[v5«¬eîµoì¶0îr¹øÃêå|¬uüµmÎì·4îrñøÓèëÙ¹Ýjlru˜¦Rêâ*ùJRqWÊϲUöëÝk^ï¸w^WY³í»/nûq]³‰m(«ë¬ùÇŸº¿Çw0ŸŽù^®±óìùþÿc~Ìý…>q1{„ô,#ü±Û±Ÿæìcàëyð0­›pä% Ìý\´fùðJP³Õ`C¯wWíøÅîµ1™Æ/n£O½¸ÒJ%”Û ¿’Ù;䓹,7ô²?ÍÒ3bƒöXË›3êªø°Ô•ÍЄ”LØ·éÛ`ÎQetdtm™ Ü'/{êÀW•ËÝ))’YLŒ_!îÉÙ)A 7ò‰c6Q{J輫a,¢`7GG%þù¹}“„çNPÖß²>AI)!<ûÑBXhÄ%%â`oèRr2RQH`¾üÆt¤ÍÓ|æ_Qìïó0W0‰íjþG&$†Z !lJãX0 ô•Ï/d¥+âXÆØ¾pÌ7æÐ©¸š5ÿ•‚³á¨é,4¿º_’€'NJZ_ôYÀ œcÁ…§$gBzKèé+: ~”r°k|ù;÷lÞñ¨‚zJInYiGßC3§§# CRŽRrÒœ”bÂi±ÿaºƒÅžæf_È&bÃR_BCC2¥–1d0ý²F³ÿ¾OS5áÃ11�[¯‰HGùáˆl³¥Ó¿ ì¯w@tWÅ”Yeq©&úF|œ–K ´°ß™¶Åô°Ì4'ïï„b‘‘ŽÇ+fÆm¶Ù¶V¯¢OýÈ.·öU}ŸnßíÛ¾ÛçÕþêëËHÄ%*Vü'ŒÊÆöí‡öízUþüeô¤1þÅl”§–’ÐŒ—ìRRŽLÃ>múF ¶ùþdÞhHZC9- XfB7FFÈ$m“ÉHöc2¶¾•òY/He0Ġ׾’4 Ð3ñ5%~Ÿ¯©)ßß*&0aD­†l”§dvg/§ed(‡2—¯/ˆYÆk«ù4¥gÎÇ«¹ÿòØóÎêuÞ­}t¬ù÷ÛüøüÏ…çßïªâ*ùJR"¯”¥"*ùJR"¯”¥"*ùJÏÙ_c¿3õ±ÇÔ꫈«åc/u«|e±‡s•ÏÆWXÙ÷lû}¹»v|âÛ8‰E_]gu6Ç­lÙ¹Êî¶R•WIÅ_+?f=}ŽüÏÖÇSª®‘|¥fï·ûçÇv|+·ø+ýWWÙû1ëìwæ~¶8ãúUt¤E_)JDUò±o×™³f[­Öâ2¨·ËÌÝó-ÔËq/™urŠ¿Y fÛñ©îý=ŸtŽæ«oöÙXÍ}(P?BMÛléA“KÛ–†J_Ó¶I_ôu2:ZùUÖ !dô¥”Ñ‘ƒvÉûoþÌ—ÌýxÑç\»ÄMU_ö¼1a¨àP¾M+É\ Þ” Ù³'•‰\™P CY(1jÜ0šBAdÁŸvAa¤Þţ؅ƒ0hk!þGn[e—¾ÿ\Òh&üBÈÈ+¥ 7@ÐÀ.’H+æGè) £7lݳ"Ô¬4¯É¤Òc§'Ž’_OOÅ'$¿ò]¤3 ¡¬Ÿö¼ªëP¡FþO}kWðJ�?!¡ö,­ƒFîWÅrТøae—Ó‹ýbbM,uÌ(0¢¶Ý‚„ºJHGH`HféüjF¯’[ý¾]``nHgFå£ •²8Ö! %  #¥ÐÍð ’1˜”×5‹ ,¾„ran4®¤r²:yhr‹K·5(ø¤fß®ÎØX{ŸÇi»®š¿Ï …4jK ÉÛ|_ßêm‚_¹‡lÛms~v=]ÏøÏ–ÇžwS®ì”Cò‹ JwÉÏŠ—†•’QãÒùß5‡†£|¾ýÛ3ÿ²r!óî³·~ÍïX(Û:¿:R„Û7ÿó¶Ìæñã¯v䣉¥‹Á�gòú~A)!™?oЖ䯿C/uP†‰ ' ù%£îŽ5BJÿú å ¤ãðÁ¼ ¡þSÞ°˜B!–„Œ&LNSþVHfÈ€À245 OÁ<¼Ì„ NÛ{ƒa$p¼:êþJ�u‰¥”K+“1Mƒ‘МY}й1%¤”4½Ý ÌÃß+ØfÛ:³/ÿÃÿÄõÛŠ&b‹--Ý?/–”¾Ïò’¤múYS\Û¯õ¦¯”¥.ºjùJV2ÿ~vR›³f­”¨Š¾ºR‘|¥)WÊR³;gûö_Ù·â³öþ"¯®±óüùößãvîÝ…·atˆ«åfsvËçwS¨ÌaøÎ>›dm¶ÛlÛem±›UÊ*ùJVo’½÷_ÊZ÷oƒº¸¹Å_])HоV-òó7|Ëu2ÜKæ]]"*ùJR"¯•Œ½Ö­ñý–ÆÎW?}]"*ùJV~̯ߊRºûðå?W×JR"¯”¥"*þiCJNãR¤« ~ûáØ®®Û¾;ñ÷ÒR Òhjvî5¹%‘wÈá¥w% ߣôt¸Ü‹åÌû/N³q‡s8ú»“vjªÿ»�؇ƒyh(a@: à`”bJ)Â8jKÅü—ä¾ÿ#»£÷ÚéË,0šü5%†—Æ!Ð’oèJ](ᡟ£d†lIgBo„ò>-¥( ß%?å»·ýóîÍ»fVÕ…ŒZlRT1_|Ë}ó€ðcôd#lÇ^xÓ¹ª ÕWý±ÐD†dä N@ÌÿKð̓Žœ‚Vd'úxb[¥W™@ii/† JS÷ù¤¯Û£§LJI=8¾ù R¬üg¾\€ÂŠî°B¥aˆvÛ™ùÕyÉJvn–ql§c”çý¶3[uáCåWý˜�ù#RpÞ”~^ÅnÃQÛd—Єp3óâÓ–Ûö}ïž¡+6ߟûmŸþ¿ÛlÿþªŠ]½4Õöm­¶_êRÿÃúøººVlÛoÿlgâûm‚¶Öò«ë¥)8«ågu6Ç­lÙ¹Êî¶R•WHоR•޽–½ùÝ”ÆV?˜tE_?È_û/e©¶ÁýX]]bß/3wÌ·S-ľeÕÊ*ùJRqWÊÏŸ}¿ÏÌø^}ð^ú®‘|¥)WÊR‘|¥)WÊR‘|¥)WÊW÷fàIó8sÙ”{™Q(«å)IÅ_)JDUò”¤E_gìÊýø¥+¯¿S÷õt¤E_fãvù×{î»|#®®³wÛýóã»>Ûüþ«”Uò”¤â¯³ö~ÊߟØÂ;eúºR"¯”¥"*ùJV}»·nøWoŸWøGˆ«çϾßçÇæ|/>ø/}WJDUúЄç»ìí¹%›üéKn¦F;¿~öJRQW߯‘ÛòNÝ€÷ËØWe™Ú¢”ˆ«å)Y³í»/nûq]³‰m8«ë¥)WÊR‘|¥)WÊR‘|¥+6ÈÛm¶Ù¶ÊÛc6ˆ«ë¥)WÊÏÙ_c¿3õ±ÇÔꫤE_)JDUò”¤E_)JDUò±—û󲔨õœë5l¥UÒ"¯”¬Ù‡Ÿúÿç÷4ŽÙZ›Ûç^uï¸~íð޹E_7É^û¯å-{·ÁÝ\]])8«å)HŠ¾Í˜yÿ¯þsIØí•ªéHоR”ˆ«ìÙ¶ßþØþÏÅöÛmªéHоR”ˆ«åc¯e¯~we1§cÕæWHоR”ˆ«å+7ÉÛï¾ù÷Ëßsw«ˆ«å)HоÍÝÏWc¾3u9矔ꫥgví·ì­ûoÅöì%¼¢¯®”¤â¯”¬ÿfßìý°¾ß¶­øWWÊR‘}‹~¬Í›ºÝn¦Ý×WJDUò”¤E_+>¾î¼Êÿpï›á9utˆ«å)HоR³w3åóØÎz¿<ükWWÊR‘|¥)WÊR‘|¥)WÊR³çcÕÜÿŒùlyçu:â*úéJDUò³wu|ÜRÕ—›‡-»êºÍÆíó¯:÷Ü?vøG\¢¯®”¤â¯³ö3õã˜Þzþ8þkWJÌíŸmÙ{wÛŠíœKiE_6ÙþÛ?~/¶ÏÇ«l#S|¾ûïŸ|½÷7zºÏÙ_c¿3õ±ÇÔꈫë¥)8«å)HоR•™Û?ß²þÍ¿Ÿ°‡ñ}t¥"*ùJR"¯”¥"*ùYøÍÿugVÿ‡lÿˆË«¤E_gs6ëÇöS¬ÎaØÞ:®”ˆ«å)YÝM±ë[6nr»­”¥DUõÖo“·ß}óï—¾æïMÝÕóqKV^n¶ïªå|¥)8«ï†5›+)oÛ³­N¶V¨¥%|¥)8«å+>ݿ۷|+·Ï‡+ü#ÕÄUò”¤E_)JDUò”¤E_xÄ-Lÿ~Êÿægù¿;eŸ•ÕQJJ*ùJRqWÊR‘|¯ ùaÌî­ÅãqêSöæÔV|æü¼sÎ^çÍc¥�������z¿óý+?Èßÿ¶ÙÿêÛc«ˆ«ìÿ#þÛgÿ«mþ®”ˆ«å)HŠ¾Ìæý×Î̧Q¼ì7­Ut¬ùÙ7µuwÁênúQW×JRqWØËÝùÝJnrÎu¶Zêë¿;)MYγVÊU\¢¯•‹|¬ÍߺÝL¦ýÕWIÅ_)JDUò”¤E_)Yóï·ùñùŸ ϾP½õ\E_)Y¾J÷Ý)kݾêâêâ*ùJR"¯”¬û'}öûæû¯}Ìú®"¯”¬û%_n½Öµîû‡uáuq|¥)WÊR‘|¥)WÊR‘}޽–½ùÝ”ÆV?˜u]gã7ýÕ[þ³þ#.™Û>Û²öï·Û8–ÒŠ¾ºR“оW¡³˜zR“¶Ç§þ`YþOŸ}¿ÏÌø^}ò…ïªå}™ÍÛ/ÝN£1øügRêéIÅ_)Y»?åïŽìi;òôî‘™YÔùûaíÆ?e²³Š”UôR³wu|ÜRÕ—›‡-»ê¹Å_)JDUö³oö~Ø_oÛVüF«¥"*ùYû1ëìwæ~¶8ãúTüfÿº³«öÄe×ìwÛ otï³ð†oÑÙò³„æÍLUù)JU}Ÿd«í׺ֽßpî¼.›¹Ÿ/žÆsÕùçãXúºJ*ùJRqWÊR‘|¥)WÊR‘|¥c¯æçe©¹ê=Ôj™j«ˆ«å)HоR”ˆ«å)HоR¼¶—vnãf0`KŽeލ”Uö2÷Z·Çö[w9\üaõt¤â¯”¥"*ùJR"¯•Ž¿–­¹Ý–æÎ^?}]"*û6açþ¿ùýÍ'c¶V«¬ÎnÙ|îêuÇã:—NêmZÙ³s•Ýl¥)rо‘¿ÿm³ÿÕ¶ÆÿLíŸïÙfßŠÏØCúnŠZ²ópå·}WWÊR“оVg7l¾wu:ŒÇãñK¦Ìëýø¥++6[÷õrоR”œUò”¬û'}öûæû¯}Ìú"¯®¼c3—ÿ[»º»¿gï™™¶9Uã]†7Ï÷îs>ìÛ¿ÉÍò™c¥}¬îݾݕþ}¸¼ùÄ>§ÎËù¸¥««¾SwÑ}t¥'|¥)WÊV~̯ߊRºûðå?WWÊW£ôçfݾ?vû¾ÝÝ@j¢QWÊR“оVwnßnÊÿ>Ü^|âUÖ‘¿ÿm³ÿÕ¶Æÿ(«ë¥)8«å)HоR”ˆ«å)HоR”ˆ«ìßwÛîݸ®Û·¯¸WYöíþÝ»á]¾|9_á®QWÊV}“¾û}ó}×¾æ}OÙ_c¿3õ±ÇÔꈫçã7ýÕ[þ³þ#.®•Ÿ8ó÷Wøîæñß+ÄUõÒ•›3ž¾çþfÊsŽ;)×8«ë¥)WÊVg7î¾ve:çcù½j«ˆ«å)HоR”ˆ«å)HоR¼nÉn§fÿàž¾Ùnûgê8>¢QWÊR“оR”ˆ«ïÙ.ý#Õ³nýNïße+íßö9ª)IE_éd¶Î—Ö£Bµ)Ô±U›»ž®Ç|fêsÏ?)ÕWWÊR“оR”ˆ«å+ùy›¾eº™n%ó.®"¯”¥"*û?Èßÿ¶ÙÿêÛc«¥"*ùJR"¯³çßoóãó>Ÿ|¡{êwnÛ~Êß¶ü_nÂ[ÕÒQWÊV2ÿ~vR›³f­”©Ö”sÊëÎøÍñ' ΢*ú)Y³9ëîæl§8ã²usоR”ˆ«å+?fWïÅ)]}ørŸ¿«ˆ«ìý·û~ØìÏÅgû,_Ú®•›0óÿ_üþ擱Û+J*úéJN*ùkt7ý‘˜jSÛn¦ÿ÷umŸõ3.É^œî¼Ùy²úߟò³« ¦*û8Ô£·åwWûs¹¹×¸çݹž°¼Èãý? n3·dtÍÝXõ6·úCZPžéfAýYÒ7Ü ò·‚CçøûêÄÐ*L@/'ä•ÒJå$é/ô'íÓ²JÁ‰ÿroÜg ^íóû‹€ʪÿš€ 1»tâ†éÝÉ„½ÊKt†¿Üô¤]z�C‰¡¤ ÌŸ·ZqD²˜nÙ9(-™!(Ìÿ}úvÈ÷ß:R” ¢ðfn^À\¤#¹Jøš„¤¯ÐŠÄ½O‰/r@,FÁ¥†“„Ò_Ý7éßrfOYHûd†d†dá»o¿ßÞ{ øv]_ùü “ ùJùÊùÍ}þÛå'o󷹿±Ÿ¯Æó×ñÇóXëôJ@våîBå¿!îã dö„rQÉiÛ ûüùZùhê @ wÀe·!$–¸ÌŒMù’ZÛvCÜnÞìØ8Â)«ü%+7É^û¯å-{·ÁÝ\]]éÑWÊV|æü¼sÎ^çÍcªâ*ùJR"¯”¥"*ùJR"¯•޽›Ö¦Ç(÷YŠe.®‘|¥)WÙÝ»}»+üûqyóˆ}WJDUò”¬ß'o¾ûçß/}ÍÞ"¯Ž¿›–¦ç¨÷Qªeª®•Œ½Ö­ñý–ÆÎW?|¢¯®³f7õóØÞr¶8ìkWIÅ_)JDUò”¤E_)JDUò”¤E_fvÏ÷쿳oÅgì!ý;™·^?²fs±ØÞ¥Sößíûc³?Ÿì±iÙ=ÂY{æËlÏ»¾îµí•ÔµÓz-úó6lËuºÜCfUye c•ñïñ'rCìê磯Q;§' BwB²z“û¾NÛµŸÕD þ†Élµgß#ñ‰WŽÿoÙrÞuÓ€5Ä2xͰթÌ’Ò²rR4¢Ñ°ÃJμ5.»ìÙa¤Ô¤¾RúBPárºn’ܾJÊOX͹}†'Éx„_Nønà$šŒ^è&ïÐZ8΄•·Oº³ûéÀ*Ltri59<â‹ÉKoù7á„>JûºP_Ü–ÏÙï|æo›±<u­_ÂA0‡3^Éåba`òº È€ßɃÜb3f-?t7íxÁŒ ‹|7àÀÎWÝ<¼‹WÈQ]�7(½¶ù Ý “!pÄ#ðߊMø”7#£¤5ÔüFdd¥¬K$eU•ÃYi`°܄'¾û¿n„äðÂgä¼Û|Ÿ•ŠT`7‡ã–~B„ÒËOÈBSŠVMèÍÀ)øa=BþHÝÊ}z`Òb‰ 1BL%‘°aX ¡.’‹È Øfb¶ÍðJ]>ù Ñ@: /ä: aƒ@² J6@ϼϒ´BR¶{!dŠ éÁ c`!( Ì”!: +¡S‚X#µÒÿ¶<õ.U\„�ü²Ëá‰!ƒ[rVÙ‘’Ž”éfICX§Bû¯œn7oy×¾áû·Â:ﷀĢø ß¾ål¸b2 (…Ã3ºq+¤f„z6KëÅ€˜‡ÿ ZK)²JÁ¼¾„’Ò5 IfFF›#,û§£(žºjÿJVo“·ß}óï—¾æïz”UõÒ”ˆ«å)HоR•åm‘¶@Í•²•²³7ù˜áC¥}Û¶ß²·í¿Û°–õtœUò•›lÿmŸ¿ÛgãÕ¶ªâ*ùJR"¯•îÝöF;œìzú¿S(ÅIÜϲñùÔë7Žæu®®QWÊR“Š¾Ìæí—Îî§Q˜ü~3©ut¬uìµïÎì¦4ìz±üÃ¥}t¥'|¥)WÊR³ç~êÿÜÂ~;åxоnû¾|wg»”+ýWJDUö:öZ÷çvSv=XþaÓä¿ù¾ø~1þß|ùlìï·Ï´›îû}Û·Ûvã•÷çà ÈK Ï›çÌwÏ»Œëjb¯¢õ€U8•ÑPIC AIŸ¶um‰{÷ÊÉÁ ÷º`“8ÜYIäÂÝ'|å§üŒ’a_²0Ü^ãPÛzͲ9|•‹—œ# ¥† ½ƒP5¤¡9 ,®°B6¼íÉà+«ô`Òih&×þ-›äôbfáƒZ>&—ƒCR1(蟻»l×®äÂ`)$¢’„!+ ºC &§#aœ7~5)èA(b;,—Û^%%`*9HHRz …€Ù�cñ„²^ OÃÐìß¡úQ¶½X ÐCA)(B -)%pÞ3teð*Ø3²Ò®—}ýå;>æÑÊö•,„X$Âð͉c>@ E³¤ 0jÓÒR6Ù,„$fBv׎„"° J/¾å‹ý‹ÅpÇHiINå’ÑËB)vS{ë.J& 4²Ò”#”ž”PXF GO-�9Û–œ^G@×WÎé׉(ø €nŸ‹(¾†/Wåὑ‰aŒ%t!Ó»d'ùþû¨œ%Wü_!‹ýg4õöp‚Fm³|oç?zömþÏÛ íûaê߈Õᜤ•¸gGC27Ce6e(åTo“·ß}óï—¾æï}%_é@BLBJId¼LNGÈ-ò6OÝý?~¡©ØpßòÛÞÑ<å¹{z: ðIã_#–Èt'¸ÜWC–Žž»æ‰Á¿o¾B\1òº6Éܶãº?uöTM ÄÐÎ^,1<´–Œ^@Äm’ŽÂ“Æl1¬„qœ¦Ø'kËÌ9Çœ:Ò¯øE.a¬ÞÉ/|óþ—WJ7ù#î1‡ÜÛÕ³«ìî¦Øõ­›79]ÖÊR—WJU|¥+6açþ¿ùýÍ'c¶Vˆ«ë¥fîêù¸¥«/7[wÕq|¥)WÊR‘|¬[õælÙ–ëu¸†ÌªºDUò¿tþHl·~µvͳæùùûå(uE%|¬îgÙxüêu›Çs:×WIÅ_)JDUò”¬ý™_¿¥u÷áÊ~þ"¯®”¯ èì×°Üâ·m×¹ìû°ï(«è¬ÎÙöÝ—·}¸®ÙĶ«¤â¯”¥"*ýi B>Ýóý»:]°ÖeüÇŸö7U¿J8ÅuíÒŽ~S°GùÅçÇzúþÎËçœkm¿ýŽÛ/ªõ 'Ù¦)%·‚“ÐÃC�Ê Ù#د³÷_ØÅØmçWï é¥ÈX¼pÏÛ¡·ü®Ù(I1%$hÌ„ô§6ÈÙ+½!03�Á—BJ0nA4¬œVɺKÁŽžŒ°wî7"° À‹Û#ìJ!' 44´¿A05 åŒGGÈB‘ÊrþîS{“ÊbCp£ ™)%q¡‰éËJ9lŒ“É|²ÒJIhÛ{ÇsÖZU÷“I¬^ΜžK(—ÐW/¤®3I,f+ 3¾Á©-.5ÞÈšB,43}€Á3†þérÉX¬59’Mä$u†: NÇŒGÍxä±¢ËéäĆÁˆÅôäl1<¦@iHJ FÉä´%þÏo߀塜”ŽPÀX®ü #(•Ê!d#§ô0ü ù¨|ãù¤p·'E_× ¥ð3’€ÄÊ+%E ²RPW%#€lŒ”¶J_ä7OØeórJÈIeæÛ%%„q%%ùiÄ­‰hPN”÷Ü­ÐÚú–A0„Ù¬R�-ý$0_/¡9ÅñŽŒý€±ß:s¤f¾Sn†?tºF²6%fK·ÏÄ·I%vÝúÇ •_ÍÎÙöÝ—·}¸®ÙĶ«¯BF¹ß?Ûîç+º•ò_2Ψ½»:¿¤COAOŠI}ódv^^»íþÛõæá!},of&oƒ ™!…îYIé%' ²k’Š%11€¾øg¾p•f/•Мœ—¶ÊÛïÒèp/|+ëèA©ßËIA»”ZI¨äÄ¥ÃzCzF§ mŽJ:sâOkÍÎk,ó‰ÁuÕÿ2%0Þ†Éû„÷I¿ç^ÿoûgÛef²Vn7oy×¾áû·Â:èùþ|ûoñ»wnÂÛ°‹Ñ¢¯®³ç~êÿÜÂ~;åzºU}›3¯÷┬¬Ø=oßÕÒ‘|¯)¤dgû4¥<-?þê)(«ìû'}öûæû¯}Ìú®”œUò•‹|¬ÍߺÝL¦ýÕWWÙþBÿÙ{-Ký¶êÂéœÝ²ùÝÔê3Æu.®’оR•›»«æâ–¬¼Ü9mßN*úéJÇ_ËVÜîËsNç/>"¯®³ö3õã˜Þzþ8þkWHоÍÜÏ—Ïc9êüóñ¬}]fÙ Ûeþ¥/÷ü?¯‹¢ß«3fî·[©„7uÊ*úéJN*û?ÏŸmþ7níØ[vWJDUò”¬ßwÛîݸ®Û·¯¸W×zâË!æà\¡˜¦ t« nýßa­ÐŽß^z½% ¶Œ‘Ÿ'>ݾ;ç;áôeN¯úÊ8A0¢‰»äþ1x„RJÅŒB +šWÝ99[2=ç€v4˜†t–7YÌYA»ÿËÉįò¸Â¿å—ý{x J!¤¼R @jKB7);%�§òÒLüfFI+!<jpÆ êö�Ч†^È|÷FI4§#6@iHHQ“”WønÝ»=ä!ŸñË_¨xŠêþÑ4ܽ†f)ö&ŸÀÉH&VÎNJ‚_GÈFÿí×{�ÒÒ +ŠA 5Œ+—ËG&â¸Ý!¬é`Ñ™›bÑ‘øØëÅ“;ò’WålL@ÂðÒi(–3bÐÀtd£ü”8·û:^ö¤ À2‚É…¡%£¥†”#¾HC‰)íø v ÉFËßë‘ÕÔzÉà4U_æ€uÿ& ½ÃRщn¤—‘ú_ #”€¡‹NRŒ5JäÄ$%Œ-ƒSÉNœÀX#3'ÙmŠvÿ=ì� ×á…|Q§€À"††Ð0”®‚Ÿ„}òYÓÚð¤´'!úC?+’ðÏÒŒ¯þC2wÉÝ›œeèüo9J=·è«ù5Ÿ°óöVüþÆùÛ/Δâ³ó–ýöÈÛ~ýþRŒsÇ^…%òIHÈ Ý5Ø1Òé) dþœÛöëÉÁ •]íM_ê@b²‹(†‚`ÞŒKd�Ù(å¡%á¹+ÉdÀ¡9T�ÀE¿Bù3Mb&Ÿ“¾a¨)=ד¶èNÁ;+]¢ƒ9}�W’WB:Ò„á `¢Ð”€ì%Û6fAhlއ]òd„³¶A£6oÖrœö¼×ãÏáäà!]_’”¥ëÙÕöwnÛ~Êß¶ü_nÂ[ÕÒ‘|¥fu¾Ç©nù±êÌ·RÔº}“¾û}ó}×¾æ}(«ë¥)8«å)HоR³|•ïºþR×»|ÕÅÕÄUönæ|¾{ÏWçŸcêéHоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«å+>Éß}¾ù¾ëßs>«ˆ«å)YöNûí÷Í÷^û™ôE_]fù+ßuü¥¯vø;«‹«¤E_¼°Ä’“ÿÜ®øggçù}·øïö{Ô†D”M)$̀̄da…o¾Ia(NÙÙÆ' c‹t¡Þðô±ÞuÙ &€Á€0tþœ”t¡Ø®^`Ä'¿mÆâ²R„þ‡éB+ „Ð †q¨I+£!<Ù‰Håa½( $1ü3'lŽí½òÜBÀ7.µål´6ý#RÛá»ÑŸ¯~»Ð Bb Ĥ}É›ät¡ C¥{möOÅ6û£¡ºzzo;ÿ÷Åñë]_êCx†!?¡¡¬Ä!·-‹ Û•ºKJ:3t÷Oíì¡ ò²x&$bž3’Ð5/ƒ2P“ßó‘ß²¼Î058· é(4oáˆFĽ‚rwåíÿ’º7² B JIEg}²‘†%t'!±{ýøNìêšøð²~Š¿êE“xo)“ †’ÓÒ0®S‰X˜œQiJwK‘¾Co¿¼èƒC&¥%¡?$„ Á®Pnßþž1M‹KŒÛ§m»†xB+¥Ò‚’—é)!-l¡˜gWÿlýW5³îÙöûsvìùŶqŸ¶W4Ã¥Wº B ÙY Û+;eŸ¶1ê+?açì­ùýŒ'ó¶_«½*ùJVn7oy×¾áû·Â:ç|ý˜õö;ó?[qýNªºR"¯•›îû}Û·Ûvã•÷êéWÊR‘|¥)WÊVg[üz”Í›¾ëu©J«ˆ«åx̳×÷$¤üÇ-YKÙ]o—ê)(«ìùÍùxæ3œ½Ï;šÇUÒ“Š¾R”ˆ«å)HоÍßo÷ÏŽìøWoò…ªéHоR”ˆ«å+{-{ó»);¬0긊¾Vm³ý¶~ü_mŸVØF¦Ì<ÿ×ÿ?¹¤ìvÊÕrоžVfïÝn¦S ~ê’§Ißõfß-·wêR÷ÏðåTR"¯”¥'|¥)WÊR‘|¥+3›¶_;ºFcñøÎ¥ÄUõÒ±—ºÕ¾?²ØÃ¹Êçã¦v϶콻íÅvÎ%´¢¯®³ö3õã˜Þzþ8þkLæý×Î̧Q¼ì7­Uq|¬Ù¶ßþØþÏÅöÛ,VÚ®“оR”ˆ«å)HŠ¾Ïœyû«üws øï•éöNûí÷Í÷^û™õ7w=]ŽøÍÔçž~Sª®QWÊVm³ý¶~ü_mŸVØF«œUò”¤E_)Y³í»/nûq]³‰mWWÊR‘|¬|û>¿Øß³?aOœM]"*û6g_ïÅ)YY°zß¿£¯e¯~we1§cÕæWIE_)JN*ùJVwnÛ~Êß¶ü_nÂ[ÄUõÒ³;gÛv^Ýöâ»gÚŸ9¿/Æs—¹çsXéE_>qçî¯ñÝÌ'ã¾W«¥'|¥)WÊͲ6Ûm¶m²¶ØÍªéWÊR‘}ŸäoÿÛlÿõm±¿ÕÒ±óüùößãvîÝ…·aоºR“оR”ˆ«å)HоR±óìùþÿc~Ìý…>q5q}îœá½³u·gýÛfZ·êÊZ¤Î·Øõ-ß6=Y–êZ—WIE_)XëÙ¹Ýjlru˜¦Rêç|¬eþüì¥6=g:Í[)Utˆ«å+¿;)MYγVÊU\E_)JDUò”¤E_)JDUò”¬ønûºó+ýþo„åÄUõÒ”ˆ«å)HоR”ˆ«å)YoñêS6lzû­Ö¥*"¯Ÿ°óöVüþÆùÛ/Ñ—»óº”Üåœê1lµÓwËߨÒw;åê¹E_)JN*ùJV2÷Z·Çö[w9\üañ}u޽›Ö¦Ç(÷YŠe.‹|¼Íß2ÝL·ù—W(«å)IÅ_)JDUò”¬Î·Øõ-ß6=Y–êZ—W×JR"¯”¥"*ùJVg7î¾ve:çcù½jˆ«ë¥fÌ篹ÿ™²œãŽÊuÕÄUò”¤E_+-[s»-Í;œ¼~4úºDUò”¤E_)JDUò”¤E_)JDUöl3mY—ÿáÿ¿âzéœßºùÙ”ê7æõª®±×²×¿;²˜Ó±êÇó”UõÒ³öcרïÌýlqÇõ:ªç|¥)WٜߺùÙ”ê7æõª®”ˆ«å)Y¶B¶Ù©Kýÿëââ*úé^žŸ iï¹ÜçWÿ¶_ÙnõоR”œUò”¤E_)Jôüè gêÊ WRó‹Su”UôVlοߊR²³`õ¿WIÅ_fu¾Ç©nù±êÌ·RÔººR"¯”¥"*ùJR"¯”¥"*ùJR"���H����z¿óý)HоVwS|zÔ¼Ëe­J«¤E_fÌoëç±¼ålqØÖ>› ÛgVeÿøïøžº2ÿ~vR›³f­”ª¹E_)JÏ—óqKWW|¦ï§}t¥"*ùJVg[ìz–Ëu-Kˆ«çví·ì­ûoÅöì%½]gÎÇ«¹ÿòØóÎêuÕÊ*ùYœßºùÙ”ê7æõª®“оVnŠZ²ópå·}WHоR”ˆ«å)HоVg[ìz–Ëu-K«¤E_)JDUò”¤E_)JDUò”¤E_)JDUö‘¿ÿm³ÿÕ¶ÆÿWJDUò”¤E_gìÊýø¥+¯¿S÷ôîݶý•¿mø¾Ý„·«¤¢¯”¥'|¥+3­þ=JfÍ_uºÔ¥DUñ³þÙþÛó~ÎÙÅ?a5t¤E_)JDUò”¤E_)JDUò”¤E_+­{cû)Ì;¾4êºDUò•ÿ§}²_í²óîßü¦ìßê‰E_)JN*ùJϲUöëÝk^ï¸w^OömþÏÛ íûaê߈Ҋ¾ºR“оWíòR;·q¿¬ï›«fØî¿ú‡Éó?uŽîa?ò½\¢¯³ç~êÿÜÂ~;åzºRqWÊÏWsþ3å±çÔ뫤E_)JDUò”¤E_)JDUò•ŸìÛýŸ¶ÛöÃÕ¿ªâ*ùY¶FÛm¶Í¶VÛµ]"*ùJR"¯”¥"*ùJVnŠZ²ópå·}W×JR"¯”¥"*ùY»?åïŽìi;òôéHÌíúÑ›gëû8ŒïÇmäηØõ-ß6=Y–êZ—(«ë¥+¿;)MYγVÊT⯮”¬Ù‡Ÿúÿç÷4ŽÙZ"¯™Û>Û²öï·Û8–Õu™Öû¥»æÇ«2ÝKRêå|¥xÌ4iÝ›«-oŸ³©l¶_¨ˆ«åfsvËçwS¨Ì~?ÔººN*û{­[ãû-Œ;œ®~0ùöû¶9þŸûþíÔ¾nfÛf¨¯Êÿ?ü÷øÏûmöÛ±ÃÙœúb¯¢³wËߨÒw;åêºU|¥)WÙó²þn)jêïƒÔÝõ])WÙ³?õÿÏîi;²µ]+ËÃPœÙ/¾’GQÝ]\ÕqоŠR“оV2ÿZöÇöS˜v=|þiÕtˆ«ìîgÙxüêu›Çs:×WJDUò³q»|ëν÷ݾ×WHоÍÝÏWc¾3u9矔ꫬùÙ7µuwÁênú®QWÊR“Š¾Í²6Ûm¶m²¶ØÍªéHоVwS|zÔ¼Ëe­J«¬Î·Øõ-ß6=Y–êZ—(«ë¥gùÿöÛ?ý[loôýŒýxæ7ž¿Ž?šÇDUñ³þÙþÛó~ÎÙÅ?a4ÝÇŸò÷Çv4Îùz®¼±ƒ>K7ù,Üj™jîìÆÄUôV}“¾û}ó}×¾æ}MÝÏWc¾3u9矔꫈«å)IÅ_fͶÿöÇö~/¶Ùb¶Õt¤E_)JDUò³q»|ëν÷ݾ×F^ëVøþËcç+ŸŒ>®QWÙ¾Nß}÷Ͼ^û›½]{⑆¤vt¶ÕŽÛ?ã¶_UDE_gû6ÿgí…öý°õoÄjºRqWÙöJ¾Ý{­kÝ÷ëÂêéHоR”ˆ«å)Y»íþùñÝŸ íþP¯ôE_]+?¿î¬êßðíŸñuq}ŸnßíÛ¾ÛçÕþêéHоR³9»eó»©Ôf?Œê\ån„mû²±çÿÿÿcÿëë”UôR³öe~üR•×ßå§ïêç|¥fîêù¸¥«/7[wÕq|¥gÎ<ýÕþ;¹„üwÊõq|¥)WØÙÿlÿmù¿gl⟰šm‘¶Ûm³m•¶ÆmNíÛoÙ[öß‹íØKz¹E_)JN*ùJÆ_ë^ØþÊsǯŸÍ:®"¯½òô«üÎÛgm¶V?~þ¢””Uò”¤â¯•å§Žžÿ`$„§…#õ?ù(Ì®ùÖ®~;|Ìëÿ-²Þ°ko””¡ü†ßžvéSýÙû ¥¢¯É^Òδ7mØ÷ÙöëÝlê|?ZËØšRJÍòPZ?=’>윓Ý[ãº÷½Àå 3fJÒW&¡%»lXÞo>ïóÜaºÇfX_È&ÀRŒ‚Ä!.ž‚ºŒØ•Òž†ÉKíöOùðϬ) 8¹eñ¸ ïÊNA|jPŒ–ÏÑ’qºúQ3€‡”Fäbg,–”âÊŠ(”ŸÜo/¶ÉG,3ü^Ní¶Þrb‚,„40¾”' '§’Ê+¤1Ä1oœ–œ’³!b×y¾)`5®¯ùQ@1(š’Š_+üYêÙñû|ãs OGûtçÌ÷%|7$nK|wÌØï²÷=nxëêÎM1a½±c N)ðÞ„’ŠÛòº7+ÿðÂ^Cfºa€þ”! S–”: iI/`ѽ0„” JKÝ‚ iùwGB–§|ªÿ‡ÒÞQy;-|oÛ¡%%·bBBTû~iæØ/JоVo“·ß}óï—¾æïLíŸïÙfßŠÏØCú¸Š¾Vg7î¾ve:çcù½j«¤â¯”¥"*ùJR"¯³íÛý»w»|ør¿Â=ýy›6eºÝn!³*Ÿ³¾Ç~gëcŽ?©ÕW(«å)IÅ_fÌoëç±¼ålqØÖ>®”ˆ«å)HоR•›dm¶ÛlÛem±›DUõÖm³ý¶~ü_mŸVØF«¤E_+6ÈÛm¶Ù¶ÊÛc6«¤E_gs>ËÇçS¬Ü~;™ÖººR"¯”¯J[£('²ûs¿Veõ¥?2¢QWٸݾuç^û‡îßë¦ù+ßuü¥¯vø;«‹«¤E_+?mþß¶;3ñYþËö§ÎoËÇ1œåîyÜÖ:®"¯•™ÍÛ/ÝN£1øügRíd­ÃI/m·‘o†Çs_³à:pܾ”ñ›þ´möÙlŒÎzº°ÔÒ*uÓ€3,…Ã0fä¬05(IL’Є0Ò‰IZ2BQІd7doµé€¦ (šã A7ìRPAevG@bC á¼j%`,ãÛÞt!½ô¿Kd©-Æ`žÌQò%9IÉÝ<–7^Ç€Å!b`gAD´”MG’_Ç’ÓÒ‚WIh@LJ+æ%³ý|Ú7<r»‘YÇšxëZ¿Ê£@ô’†ô†ä¥( ñdµ”%$„!b9}µ¥W%8°(²�¡  Ÿ‘‘ù5‘Ð1“ƒa‰ÈßËÅfÙ'mxð3Ã8I%á¬WFåd“wK’²Ücå¹çßJÒ^ü41 M¨(¯²pca…ô¥Ó‹èNØ”’WÈù+®¥¹†gãÇ>U1 &GûäíÈ_“€ÀÇIA††ò÷K'ô'3§£ŸvÀ¨É,߰߀Ïér’‘¸ahûQIXÔ££«fëd^¤„#'üJéC—ƒ7Δo“‹GÅ ò¸ÆHÔbVÛ\T€è *‚òSù/—¿ O+Jo‘Ù?d7%[«eT5¾â…®UÕÀ`X Ä.’hAO†òQ3£%%dò‹d#•²ÓûqˆÃ_ß3�@Én„¡cJܤ¡Ã>Ã?î”wï·Ý{>Ô8,e$¯ó}†p0RvéOÝ,Z]ÐRŸ ?üý¶½I-�KÄ¢‚]$¢Ñ·Né ’Ð[$·Cá…möéKúþP €qWüš•å'Œœûp&„£…'oƒõEëÙÕò³çßoóãó>Ÿ|¡{êºN*ùJR"¯”¬û%_n½Öµîû‡uáuq|¥)WÊR‘|¥+?ÏŸmþ7níØ[vW×JR"¯”¥"*ùJÏ·oöíß íóáÊÿõq|¥)WÊR‘|¥)WÊÇÏóçÛÛ»vÝ„UÖ6Û?Û~oÙÛ8§ì&QW×Jþ4j>9{ç'ÿûægÙ¿ã­rÿß·GÏ‚„å«}Üu»}ñËm(«ë@G‘„!>f7tdc†m…,U¬†_ÛŽÅ–ù³fÏ×ß;¤óF}½‘%ä}¾JþÊ)?-Ù{}Ž_êÊv}} %†ðÂÊ+'$7#”C ÄÒðÎZv唄§2Yó–­‘sloÊU_ꀪ Ý‹!¤i3§`Äd Hÿr€±lW H‰-{ë� Jq¤ÝÓƒQ±\hicÿƒ:qEnJÝù]òþMÖ !Ri ¤®Já„Ò‰} -)&¥™ KÈ,3ôôm²òFëa¶rgI+ ¢ÊO!dù<¼RvVÛ8nèOrfGò5ärspÚUøÊPfI°Ô•Ê&7J (‘ˆI-)î7§ ”Lýò fö%†”žûŒC‰…’19(èåŒ&Ý ¬übÜÅ”‚a ¢G Å!,ZöB”‚fB[Œ%²r JRvE版ü1à ®KObn&àÞ4ä•‘»dwܬ5#ÓRMv?ˆ`åWø|ŽW)ÐÉ~”Ÿ¤iº¶}™Üí¬? ßw^e¸wÍðœºýŠVÙ�(í¶`-ưá^É{¶U}Ÿ>ûŸ™ð¼ûå ß_B�¿£éÿ i)=¸`ÒR’Jn:–Ý?£o•õó›¬CPR6NÜ—É[%†~öÜþß«¶K;üÛÙ ùÕþˆÝ¾íú4·ãSЀÄ$¢Ò‚¸Nß}Ñ“úT¯žð÷Ù�B&’œ˜”ƒKå†gAmÊÙû!±_ó?3å_²JÈùÕöwnßnÊÿ>Ü^|âUÒ±o×™³f[­Öâ2®ÊjúéYû?eoÏìa?²ý\⯳ì•}º÷Z×»î×…ÕÒ‘|¬û'}öûæû¯}Ìú®‘|¥)WÊR‘}›lÿmŸ¿ÛgãÕ¶ªë7;-MÏQî£TËU\¢¯”¥'}Ÿ9¿/Æs—¹çsXêºÌæý×Î̧Q¼ì7­Tî¦Øõ­›79]ÖÊR—(«ë¥)8«å)HоVnæ|¾{ÏWçŸcêë6ÈÛm¶Ù¶ÊÛc6”UõÒ”œUò½8íºvû:e;·û:¹ÇTW£ ͶFÍ‘°í±¶c›:¥h°Ð:P“ú]ròBP´„rÓþßþÜ’æÞÓWA %ɈÅtÆþJùK~ZRŽÝ´Ûýþ½h/†÷Ie† & ÉÅ•ŠÛ¥=8´rb2…¸ãvÝ{^”°Àt’ÐRF!% ¤b“Ï);1Aˆù)/l‚ÃÐ_A{|÷–­¸#ŒkJ¿¼Y aðaE¤3¡$у0f ÉÌ‚óWF ÿ3§#çã7O÷))&òË!¥ ²Jù/øc$´§äÎPÒÊ+ôd|”½ !“�lÉ…% É&¡;p rÉOé) Å 5)~…í‹èÿj²ƒ°iE¤5%%!½�cbhk€ÆÅ å”ý †¶éß ÉïµÄ£±Â–G㪫ñ–MG/ˆElV( %®€Ô–‘ˆCrPÐ3·HÄ•Æ BwèUó€ÀÀÎ7£ ´Ã^ù)+žŽù‘ò7Ù°BôØ 7�· 36,%Ÿlä>_FÀe(}¹|ñ¸o¾k³m¿ý±ýŸ‹í¶X­µé¹Ž… }t¥/RоZËÝ¿FA/!9'oÌÿ-¿ÙØu’õ€¥!†pÔþ” `Ü^䤤!%n^3#³+­VZu´!`Bh`ÄŸÓÐB@nù¼1x¾^Od•±{¯ïÚøýöP2@b¼ËI3 gInYhÜf J‡Ý8‘Û•|—!#6åÿ÷$í·ûss|¼¤ý±¿5ÇݺƒÅUWä¥+ùY›¿uº™L%ûªôh«ë¥+;·m¿eoÛ~/·a-â*úéXëÙ¹Ýjlru˜¦Rêâ*ùJÆ^ïÎêSs–s¨Å²×WWÊžVfïÝn¦S ~ꫤE_)JDUöglûnËÛ¾ÜWlâ[UÒ‘|¥fvÏ÷쿳oÅgì!ý\E_)JDUö:þnvZ›ž£ÝF©–ªºR"¯”¥cçùóí¿ÆíÝ» nÂ"*øëÙkßÙLiØõcù‡UÒ‘}Û·Û²¿Ï·Ÿ8‡ÕuŸ¶ÿoÛ™ø¬ÿe‹ûUÊ*ùkÈã>Æü´ã;lèÉéÛ)ö^sÞÉHŠ¿ë ;)¹3¸Ü²8À2XÜ_G B11 d i|¿ºSÉ6j¾Xa4 æAx¤(²·-©Éq¸aDÂÒ_Nè+?Ééo¿ÞðàT˜n3ðÔ ¤åÉvNB~ݲû5ô°*K+¤hgéÍÊ @` ú\¼[·åd¡!¤´“»æÞñ¡#ÌpÖ•}å|LÙ!¤ÐÝÓLKä•·Éiû¾ä¾5¿á¼3ô¤“Úá�ÁËæ�á%$ Ñˆ==)Û•‰}KÜ´–Z]» kûÒ†“H{ðĤ¢f�¨„žŒ‡ÜaIKò”YKGßã·¾ZLBQúIhN å}ò:r[,´ô6Ý%l…gFNÁ-/°áýÈ*ÿ=¶FÛm¶Í¶VÛµ]fî<ÿ—¾;±¤îwËÕwµgWÊR±óüùößãvîÝ…·aо»é@'&ü’j:v+'ôïݤgG(· %€Ý ‚Û¯k!4ä¢aiBrKÅ't위'!=Á‰å|yh?#~[mµÓ !Q7l5 ¥†äòakJ]2q4¤gCO( ì•ÞvÎÂ[O®¯ó :!#€ÖCbŠ%'2Ý ÿ,˜„¡•d}›mŒúñöðÌ™9»í²rFFqŸ§¯«ºÝ¯Ÿ`ºÿ0�M_fÌëýø¥++6[÷ôÎnÙ|îêuÇã:—WKYUò”¤â¯±×²×¿;²˜Ó±êÇó«¥"*ùJR"¯”¥z“‡|ÏŸ~öíÛüíñ²Š¾ŠR“оR”ˆ«å)Y»¹êìwÆn§<óòQ}t¥bß+3wî·S)„¿uDUõÒ”ˆ«å)HоRÖ””Q{ NèWëGËs›Ÿ•ú–öIE_gùÿöÛ?ý[loõuŸd«í׺ֽßpî¼.®"¯³;gûö_Ù·â³öþ®•›dm¶ÛlÛem±›DUóá»îë̯÷ù¾—{€“Yhårót'ìŽ1)þû»'ô 7#¿Ì¤Þ–zuÚ�B ¤ÂPhgû£t  —‚öåo¾ _/6Of éʺäÀ*R”¥jzI©GåbúzôS‘… Ahßß–œÛ¦ø± 1!¨û|Êû7Üjî5{Œë)9]÷{ÔÀ§¥#ü—gGON-ܵý&o›7É͵å¡8î WWà(0ÀÒÓŠN FAL3q¼´¿Û¾^b@Ä’þkÏ 5¡8¼ÿ F㛿ݲ¿ÝŸs޾•€. åþ4¯ÐYIŧ~žœ^JÉhIc1LM`…÷ý¬ø �ì¢bI¸4´§nÅ|ú0jS›„†Ĥ’Æ?BwßÛvVf�úU4òaE ÏÒÁ¿ó%ƒ:wÿ·ùŽ}ŸüÛµÖI4�Ü´òØ–… VOF- IWÈI{umž°° 8i¥ƒ p΄gØn-9<1²fÃ;+ý•ï4PˆÁ.ŸÃ�Âzöè䜸B9ˆÜb�öÏÞYAgŽŠ¿Ð€d‚úX–°Òºi,—þ OI[ð,žÆ÷Æoþ×€ (˜…#!ÿ¶;?ÿ°åóŽÖJ]¿¸šjùJV|ûíþ|~gÂóï”/}o*¾ºÍ™×ûñJVVl·ïêéWÊR‘|¥)WÙûúñÌo=5Ž«¥fÌëýø¥++6[÷òоºÅ¾^fï™n¦[‰|Ë«¤â¯”¥"*ùJR"¯”¥"*û?f=}ŽüÏÖÇSª®”ˆ«ìØfÛ:³/ÿÃÿÄõÕұ׳sºÔØåë1L¥Ê*ù³?õÿÏîi;²µ]fͶÿöÇö~/¶Ùb¶ÔÎÙöÝ—·}¸®ÙĶˆ«ë¥)8«å)HоÍÝÕóqKV^n¶ïªëýY›7uºÝL!»®®QWÊR³a›lêÌ¿ÿýÿ×8«çs>ËÇçS¬Ü~;™Öºo’½÷_ÊZ÷oƒº¸ººÍ²6Ûm¶m²¶ØÍ¥}t¥'}‹|¬ÍߺÝL¦ýÕWJDUò³º›ãÖ§|Üåæ[-jU]"*ùJR"¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJÍÜÏ—Ïc9êüóñ¬}\E_b߯3fÌ·[­Ä6eUÒ‘}ŸnßíÛ¾ÛçÕþêéY¸Ý¾uç^û‡îßë”UõÒ”œUò”¤E_-ÖýþËK-‚3õ·fËeTV}’¯·^ëZ÷}úð¹ÒŒœÜz9Û’>æïŒŒoLUôR”ª*ùJR"¯”¬ý™_¿¥u÷áÊ~þ®"¯³ì•}º÷Z×»î×…ÕÒ‘|¥)WÊÇÏóçÛÛ»vÝ„UÒ"¯”¥"*û3¶}·eíßn+¶q-©Üͺñý”ë3ŽÆõ*®’оR³¹›uãû)Ög;êU\⯔¥fÌ<ÿ×ÿ?¹¤ìvÊÑ|eþµíì§0ìzùüÓªéHоR”ˆ«å)HоR”ˆ«å)HŠ¾Ìæí—Îî§Q˜ü~3©uuŽ¿–­¹Ý–æÎ^?}\¢¯³»vûvWùöâóçú®”œUò”¤E_)JDUöm­¶_êRÿÃúøººÏòþËÙj_í°VW(«ìîgÙxüêu›Çs:×WYoñêS6lzû­Ö¥*›¹Ÿ/žÆsÕùçãXøŠ¾ºÎêoZós—™lµ©Tû'}öûæû¯}Ìú®"¯”¥'|¥)WÊV>Ÿ>ÛünÝÛ°¶ì"®"¯”¥"*ùJR"¯”¥c¯e¯~we1§cÕæW×JR"¯”¬ÎoÝ|ìÊuÎÇózÕWWÊV-úó6lËuºÜCfU\E_)JDUò•Ÿ³¾Ç~gëcŽ?©ÕWWÊ͘yÿ¯þsIØí•ªéWÊR‘|¥)WÊVlÛoÿlgâûm–+mG^ÍÎëSc”{¬Å2—(«ë¯AhI!;«%_uwn£;væµE"*ùJVlÃÏýóûšNÇl­8«ë¥)WÊR‘}Ž¿›–¦ç¨÷Qªeª®”ˆ«å)Y³úùìo9[v5ˆ«ë¥)WÊͶ¶Ïß‹í³ñêÛÕtˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«ì[åænù–êe¸—̺6Û?Û~oÙÛ8§ì&®’оÍÜyÿ/|wcIÜï—ªéIÄ���ˆ����z¿óýgu7Ç­Nù¹Ë̶ZÕW_“ºz Ûsñ¿ãÌ70ãe}¥'|¥)WÙoñêS6lzû­Ö¥UÖ|ì¿›ŠZº»àõ7}W(«ïnŒµºÓÍï×ß©mŽ;+IöNûí÷Í÷^û™õ]"*ùJRqWÊR‘|¥)WÊW¥,Ç?ûmû9½•ßäoØÖ2¢QWÊR“оR•Ÿ³+÷â”®¾ü9OßÄUõÖ|ãÏÝ_㻘OÇ|¯WY³?õÿÏîi;²´¢¯®•Ôßµ;æç/2ÙkU\⯳w3åóØÎz¿<ükWJDUò”¤E_)JDUò•›¸óþ^øîÆ“¹ß/UÄUò”¤E_+;™ö^?:fãæqõuýݽó“Îÿýó3ìßñÒŠ½6g=}ÏüÍ”çvS®®±o•™»÷[©”Â_ºªâ*ùJVm­¶_êRÿÃúø¹Å_;©¶=kfÍÎWu²”ªºR"¯”¥gìgëÇ1¼õüqüÖ:"¯Ÿ±Ÿ¯Æó×ñÇóXêlÆþ¾{ÎVÇcéÝ»}»+üûqyóˆ}W(«å)YðÝ÷uæWû‡|ß ËœUõÖ~3ÝYÕ¿áÛ?â2éøÍÿugVÿ‡lÿˆË«”Uò³l¶Ûm›l­¶3j|ûíþ|~gÂóï‚÷ÔÝÌù|ö3ž¯Ï?ÇÄUõÒ”œUölÃÏýóûšNÇl­WXëÙ¹Ýjlru˜¦Rêå|¯K«g_ÏðÅlµ¹†+~³¨¤E_fãvù×{î»|#®›6ÛÿÛÙø¾Û`­µ-[s»-Í;œ¼~4ú¸Š¾V~ÃÏÙ[óûOçl¿WIÅ_)Yóï·ùñùŸ Ͼ ßUÄUò”¤E_+>¾î¼Êÿpï›á9tÛgûlýø¾Û?­°W(«å)IÅ_)JDUò¿nïÒ=[6_S»÷ÙJûwý‡TVwnßnÊÿ>Ü^|âJ*úéJN*ùJR"¯•›d+m—ú”¿ßðþ¾.®³fs×ÜÿÌÙNqÇe:å}t¥'|¬Û#m¶ÛfÛ+mŒÚ®‘|¥)WÊR‘|¥+;©¶=kfÍÎWu²”¨Š¾ºR‘|¥NÝjV_Ã{oö~Îë9\uD¢¯³a›lêÌ¿ÿýÿ×WJN*ùJR"¯”¥"*ùJõ~δ7mǾϷ^ëgSáú¢QWØËÝjßÙlaÜåsñ‡Ó}ßo»vâ»nÜr¾â=]"*û?Ù·û?l/·í‡«~#Sl¶Ûm›l­¶3j-ò³7~ëu2˜K÷U{¿;©MÎYΣË\¢¯®•‹~¼Í›2Ýn·Ù•WTUò”¯¿óüÌëf|û»¿Ëù^QWÑYœÝ²ùÝÔê3~3«¤â¯”¥"*ùJR"¯”¥"*ùJVg7l¾wu:ŒÆŒãâ*úéJDUò•ÿ„ìù{ñ†öùyggZ¹ùzM÷}¾íÛŠí»qÊûˆòнöûÿÒâ¶m—Øvûu·gÛTR‘|¥)8«å)HоR•Ÿ;/æâ–®®ø=MßDUño•™»÷[©”Â_ºªëßîß+¶ß?Zÿu6Í•ÿ_ì9ê%|¬û'}öûæû¯}Ìú®“оR”ˆ«ì[õflÝÖëu0†îººR"¯”¥"*û6ÈVÛ/õ)¿áý|]>v_ÍÅ-]]ðz›¾«¤¢¯±³îÙöûsvìùŶqû'}öûæû¯}Ìú®³}ßo»vâ»nÜr¾â<E_])IÅ_)JDUò”¤E_)Y»íþùñÝŸ íþ ÿUÄUò•Ÿ³+÷â”®¾ü9OßÕÄUò”¤E_gìgëÇ1¼õüqüÖ:®•Û¶ß²·í¿Û°–òоlÃÏýóûšNÇl­WJN*û6m·ÿ¶?³ñ}¶Á[j-òó7|Ëu2ÜKæ]]cgݳíöæíÙó‹lâ%|ÿfßìý°¾ß¶­øWJN*û?¿î¬êßðíŸñuuå0Ä3³f5ÙãÝcê%}ïû2þïÖÙÛæ}ÝJÿ+­j¨¥"*ùJW¤´ºRœéûlÕW§ù ÿeìµ/öØ?« «¥c¯fçu©±Ê=Öb™Kˆ«ë¥)8«åc¯å«nwe¹§s—ÆŸ^Y-¹+¡Æ%²wa yþçÌþì¤4²ËV|Ö²z6ìKß b² wcµ“c@:_Âén¶Ù[Ïÿ³30æZÿfµònÜθÒݲÏý]º>KwGgÍÞú‚CK&—Ë(†’Rr?Ø5%p€ß²”PÔ'ôð&”’6¬àT´Œ, q© CKFÁ©ËÉbþJ05#R‡)Å);ÞfFfû‘ÅâqÊ®¯ù>&•þÛåätq¨ 7æ[õ#ó›ã½—|¾ûïŸ|½÷7{ëa¡¡©&ndñ¬“²¼1·S„!Ý „7%ÚË�v€ÐÜ[ GÀ6ê/|Sôäò¹\%†~–èÊ+ÿ«%38ñcÀr«þ+KÙ€è2€cÛ‘݆pÔþn—ÈÎêùÕÆîH]ä7·Î¼ëßpýÛáwCSW×YoñêS6lzû­Ö¥Sößíûc³?Ÿìö«µ•_)JN*ùJR"¯”¥"*ùJR"¯³q»|ëν÷ݾ×WJDUò”¤E_c/õ¯le9‡c×ÏæWJDUò¼¯Ò„›ý¿ËSã—‘Âöâ¤ùÇŸº¿Çw0ŸŽù^›0óÿ_üþ擱Û+S}t¥*оR•Ìû/N³q‡s8øŠ¾ºR‘|¥~Köûî³ñ›³¾}œý¿v1^¢QWÊV~̯ߊRºûðå?W8«ìeþµíì§0ìzùüÓªéYøÍÿugVÿ‡lÿˆË”Uó»vûvWùöâóçúŸä/ý—²Ô¿Û`þ¬.¿ü„ãܾ0õ+%'~%ÆoùªÊ¯!%~‡·ù¿Æ|b vßýº¿eQ§WúðÐ+‹-@T1 B’‘©é,3î’ù÷fQe$ôeÝb K»pÀßòSöÙ(JC’ƒ>Û—É5vcpÍï>‚ÿ &–”t$¤ Éé‚·ÈéÉÀX¬3 -!?ýþB{6½Ña€T1©�PßRLA\´ñ€e%–ž–K¥ŠJ6²ïlØ×=ð‚¹–µ}` &–>À„~JÃF 7§ ü¤eºŠßät„üþò{d 7'( )ߎ÷Åü™ÓúqhJ’_3g¬ä¼”vè+2K㔂V-81)夒7ô|’¿뻤ÒC1+£#$šMá›bih)° ÿÐKN øgߟz{vûó·ç YæËÑWù°ÎL/ýË&$”œ\än¼ž€Î—F‹ÿ£¤²^{Ô–�Â)eJ@¯Ÿì”vãv OByhOÉ Cžóóo+È\5rò[|7£† ´ 3'†9Cyx'þIIoùÿkŒ`b:23u6à ã o±lÌéÏÑÛ»÷ºFüNÁcŒM_õ\„•’ŒY0 Ñ‘‰¨îŽL%~’ønGÿ#†»oŠB72ñà0¤ Â%–ÃPMJ@ÏÈ/'`‘¸´ #%+å#œ¹¯=À¢@ÀnÉø´¡œ’öƒdóOu§–•n7¶kÝpb`c„ýöýRBPX º@ÊrP‰X®á‰q™/ߨ¿v4YÍ€UÇi{°ðÞŽ‚ÑÊÁ‘ÑÊ-D®‡(„¬²™ ”Û^÷=•_)J[J¯”¥"*ùJͲ6Ûm¶m²¶ØÍ©»º¾n)jËÍÖÝô¢¯®”¤â¯³ü…ÿ²öZ—ûlÕ…ÕÖo“·ß}óï—¾æïOÙ_c¿3õ±ÇÔê”UõÒ”œUò”¤E_)JDUò•›0óÿ_üþ擱Û+Q³îÙöûsvìùŶqнÐ1‚'3;ñ§5Ü[½E)WÊÏØÏ׎cyëøãù¬u]'|¬ù÷ÛüøüÏ…çßïªéWÊÅ¿^fÍ™n·[ˆlÊ«¤E_+ÉhÜ`Üý”ùÖì£Ìá\uEbß/3wÌ·S-ľeÊ*ø·êÌÙ»­Öêa Ýv¬„î–çýÝ?óVŒŒÛl²>ç¯ïϲìοߊR²³`õ¿zpÿÃ9]'ñ…ä!òƒF¡d—›þÛ$á¹þö9§WûrÃR€ÐÀ1a˜7$²i\3âZRÜ”Œ”¤3·Û;ò¶Y&éÌLI 0¼Z9{¤j / ra//£a¿í»ô ÈN>ôäÜ€–VHi,¼Ô$ß–Zœ¤öÛe¡axàõÄ!B‹(¿ÒX`jKÜ41(,5»~„r`ÜXoOü58½²>îÝï•qûÛ;l,Ý–.Þ¯rD0Ô!ÅS 5)ù%tàÔ«ýƒSÉA©ÎJ+dÀ8Ýžùñ1¥° Àl ý¿I,¼°B†ù+|„3+ÝÄÊ&�è *€Ò±m¸ÂnC²01)‡ró'l—~…P„ �?éܧá¨éOB:IhŤ²Ÿ”`×åt’†fÜfÃ=ÐæwÆ(ìrÈçʯù¹3¥!)%£ì1%t# iãs ëZv;¯{“kAD¦Èlº—ÿÿ»üOîÿþïd¾—ØÕòÜMÙ!‰ÉûfýÒry*èøg[ï¾gßXiV•_öÜ€ ˆ}E á¨9 -!4nÈûää0fë÷È Á®3vǾÜwGdï³uìûïžô §10®kÜÙû KÃ’å|¼ý»[€$5$À”Èý Ê{%®Á„¯†#•¾u)µä|!X{€Ô×´«þ}JV|ãÏÝ_㻘OÇ|¯{6u}t¬îgÙxüêu›Œ;™ÇÕÄUò³a›lêÌ¿ÿýÿ×WYþÍ¿Ùûa}¿l=[ñQW×JRqWÊR‘|¥cçùóí¿ÆíÝ» nÂ*â*ùJφﻯ2¿Ü;æøN]\E_+6g=}ÏüÍ”çvS®®‘|¥)WÊR‘}ŸäoÿÛlÿõm±¿ÕÒ‘|¥gs>ËÇçS¬ÜaÜÎ>Œ½ßÔ¦ç,çQ‹e®QW×JRqWÊÏÙ_c¿3õ±ÇÔꫤE_/fŽQy Ø¿ÐLo°JSМ†ì7ä'²:I\o%©ï.³¥{¶~ŒéùÆ3Íͳ¯²ï¨�j’Kù¢Ã_á£�oƒ7@Ì„  þá»l1gëËdÜ|DZãƒÀYU_êPV ×)�©<5%2I™;ð, @a4¡Ÿ»mÐÿÕ³XÐat:PRRLnVè(5 c$ A1ÖàX¤t§#öÃ_T–‚À,(N&2„¡Ø _pÄäíË A]ËéNGøoͼņ åŒ@nOIx²ÃSòRYE¡,LJyLЄñ¬ÅvߦùãWñƒ€:Ú¯D”ï¹_r™)ŧö ,i $´¥²y7d!8²³¥ïb &€øÄþ”n_ÊOßý·ONÎ3t£cvMÙã2 ,²gÉGÛd ) b?åâÆæmÉ ëa·Ë/U?9†à £‡YÕò”¥íÙÕò”¤E_ë�Bý•²K+îÍÒÛ¿Gø­Ãr hGÝú©þ¯…€Ü´¤˜Ã Ù;ô†§¹/îè-(%nÉÈÈGÊÕµ¬< €ßdpÒ€Â{|RJ%ðÓ†pÖÈO|Wü³¶>æ�è18Ð KOá©ÃF–0­¾m÷å0Çm†¾èUåfÛ:¸1×WùJR³|¾ûïŸ|½÷7{Õ¢¯™Íû¯™N£y‡óxêºR"¯”¥"*ùJR"¯”¥"*ùJVn7oy×¾áû·Â:â*úéJDUò”¤E_)JDUò•Ÿ9¿/Æs—¹çsX긊¾R”ˆ«å)HоR±³þÙþÛó~ÎÙÅ?a4ÿ!ì½–¥þÛõarоºR“Š¾Ïœß—Žc9ËÜó¹¬uõ²j�N„ðÂHJRM& @A_t䤧OOoÙ+é/ïò¯’|ì¿›ŠZº»àõ7}} Q$ÒÒXÐÔ @F%ä?ÿäS£†nZrKéIhù ʼäq†9YæWWû¤—€§+€ÉEþÀÂC2ŽWœZ@nÿ³¸ÜߣwkƈH /¤1)+ºŒQ3$¤ô?ü­ÀÈbFnØk}ÿ?^ˆ„¯&P…“CzrFä'6Á…¾Fù‰Œž•ŒI+¦ùá1 Gã ÛýÊéêNéNt3–‡OpÜ—-=ÛyiÊnüåž'¢%u¢¾ãRÃ~d±Écºß¡³üÛtóúîm)}_)JU|¯Jr0ÿݳíÓöý³ý·6¢ú€ @B`i3ð3ö–Á/‚Ihø¯ƒ8 ¶nÿýþK«½Í³¸�檾òi40 €Ü´g)”P^OëJ6I+|ƒ6Igcû2z~¼)…‰,ŽìÃR‘¥†³­"Ÿ·1¶ÚöÀ0…$0 ‚Ƥ5=‹Æró!9IIÉá„¢ú6@ÍòÛå—ýNÌÁs«å)KÕ¢¯³mŸí³÷âûlüz¶Â5])WÊR³üÿûmŸþ­¶7øŠ¾ºR‘}™Û?ß²þÍ¿Ÿ°‡õt¬û%_n½Öµîû‡uárоºR±×ós²ÔÜõê5LµN*úéYûoöý±ÙŸŠÏö ûUÄUò”¤E_fî<ÿ—¾;±¤îwËÕt¤E_)JÏÙ_c¿3õ±ÇÔꈫë¥)WÊV}“¾û}ó}×¾æ}WWÊR³:ßcÔ·|Øõf[©jˆ«ë¯ÝÿûïŽQŸ’ýØS2¾òg[üz”Í›¾ëu©Urо[Ó°iJdäŒ7t%ç?'}Ðæ,~>ÁIE_õ@ @`Y4²’’±d¿V,4—ú~ÿ¥ƒ HÇÃ2 ^w}޽(�cƒ�, N è騖1l—%£dô’Êòz—·ýï…|7}Ýy•þáß7ÂrïN@4A)<®òQÒ7'ô}Ünßa™_vÛ ù¯#%œ5¥_A@Uɤ®ûýÒJø%̇ý[lœœÛ—ûäî2ãpÒ³wÍÒ1ÏÃ_æÿ+/2Àú¾Æ°P’ƒP_ᥠÝ% —ÐXÅäŒ@J”ܾžJïþÞÖ‚ÐÐŽ‹Á™6Ĥ,aeɉÛÃB]jF%¥¿¡Lv`§œTêÿƒZË @ft¾ÎḘ̂߬Ï;ÿl¿¯­€X²‰…‚ËŠá¿þFÜ ¤¸À3Ð3“~ý ÉÁ¼ —é(šLF@ÎVÀQ)-(Cdü0°/’œãÊ*ÙÜrÄH’«üa 4¤ 0›ú@RV ID¿ùEò‹nWûḬî{/ëºBœ%pÒY1#zwB9c>K%Ÿ4®5%¯ºFýщ—(F,”K OI}Æ’ßëà]’3t¯“¸Ä²ï'ŠFÈÙH͂ʮÊ2­…Æ8¥‘¢¯ˆ)fB22•¶Çm±Ã¶ØF¨¬uìµïÎì¦4ìz±üêïVί³wsÕØïŒÝNyçå:©þBÿÙ{-Ký¶êÂêéWÊV|7}Ýy•þáß7Ârêç|¬îݶý•¿mø¾Ý„·«¬lÿ¶¶üß³¶qOØL¢¯®•Ÿç϶ÿ·vì-»«œUò”¤E_)k%9ý=IÇü¤ð1ÇnIØÓì’Š¾R”œUò”¤E_)JDUò”¬uìÜîµ69GºÌS)q}t¥c¯æçe©¹ê=Ôj™jˆ«ë¥)WÊR‘|¥+6ÈÛm¶Ù¶ÊÛc6ˆ«ë¥)WÊR‘}Ÿd«í׺ֽßpî¼.®”ˆ«ågu7Ç­Nù¹Ë̶ZÕWHоR³wu|ÜRÕ—›‡-»ê¸Š¾R”ˆ«å+6¶Î¬Ëÿðÿßñ=uq|¥)WÊR‘|¬ý™_¿¥u÷áÊ~þ®‘|¬û'}öûæû¯}Ìú®‘|¥)WÊR±³þÙþÛó~ÎÙÅ?a1}t¥"*ùJR"¯”¥c¯fçu©±Ê=Öb™Kˆ«ë¥)WÊÍ›mÿíìü_m°VÚ®‘|¬ÎoÝ|ìÊuÌ?›ÇUÒ"¯”¥"*ûÒŽöOGhø<œª)IE_)JN*ùJR"¯”¥"*ùJñ»vêvoþ ëí–ï¶~£ƒê%|¬eþüì¥6=g:Í[)UtœUò”¬uìµïÎì¦4ìz±üâ*øùö|ÿ±¿f~Ÿ8šg[üz”Í›¾ëu©TÛ![l¿Ô¥þÿ‡õñurоR³|¾ûïŸ|½÷7z|ûíþ|~gÂóï‚÷Ñ}t¥fv϶콻íÅvÎ%´â¯®”¤E_+6ÙþÛ?~/¶ÏÇ«l#UÒ"¯”¥"*ùY»íþùñÝŸ íþ ÿUÒ"¯”¥"*û7}¿ß>;³á]¿Á_êºÏÙ_c¿3õ±ÇÔê«”Uò”¤â¯”¯NéßnήyÆ·ß}Øïººê%|¥)8«ìý˜õö;ó?[qýNªºR"¯”¥"*ùJR"¯•‹~¬Í›ºÝn¦Ý×WHоR”ˆ«ìýŒýxæ7ž¿Ž?šÇUÒ‘|¥)WÊR‘}ÔÛµ³fç+ºÙJU])WÊR‘|¥fîgË籜õ~yøÖ>®"¯”¥"*ùJR"¯”¥fÌ篹ÿ™²œãŽÊuÄUõÖm³ý¶~ü_mŸVØF«¤E_)JDUò”¤E_)JDUönæ|¾{ÏWçŸcé¾J÷Ý)kݾêâéûoöý±ÙŸŠÏö ûUÊ*ùJRqWÊR‘}Ÿ°óöVüþÆùÛ/ÓfëÿŸÜÒv;ejºJ*ùJRqWÊR‘|¬îݶý•¿mø¾Ý„·§Ï¾ßçÇæ|/>ø/}W(«å)IÅ_)JDUò”¤E_)JDUò”¤E_)JÏØyû+~c üí—â*úéJDUò”¬ÎÙþý—ömø¬ý„?ˆ€���È����z¿óý)XÙÿlÿmù¿gl⟰˜Š¾ºR³l¶Ûm›l­¶3hоºÍ†m³«2ÿü?÷üO]]"*ùXÙÿlÿmù¿gl⟰šºDUönãÏù{ã»Nç|½WJÇ_ËVÜîËsNç/>QW×JRqWÊR‘|¥+Ücôý³íŒ=¶ßþ¿ÒqÇìÒŠ¾ŠR“оR±—»óº”Üåœê1lµÓç~êÿÜÂ~;åyE_]fî<ÿ—¾;±¤îwËÕtœUò”¤E_)JDUò¼¡£¾ëÝÆ»­]ú–£69U”Uò”¤â¯•›lÿmŸ¿ÛgãÕ¶¨ËÝjßÙlaÜåsñ‡ÕÊ*ùJVm‘¶Ûm³m•¶Æm8«ë¥)WÊR‘|¥gs>ËÇçS¬Ü~;™Öº¸Š¾Í™Ï_sÿ3e9ǔ뫥cgݳíöæíÙó‹lâ%|Ýöÿ|øîÏ…vÿ(Wú®”œUö~3ÝYÕ¿áÛ?â2êë7;-MÏQî£TËU\¢¯•›¾ßïŸÙð®ßå ÿUÒqWÊR‘|¥)WÙ¾J÷Ý)kݾêâêéHоR”ˆ«å)HоR”ˆ«ìý·û~ØìÏÅgû,_Ú®³ì•}º÷Z×»î×…ÕÊ*ùJRqWÊR‘}ŸöÏöß›övÎ)û «¬ý˜õö;ó?[qýNª¹E_)JN*ùJR"¯”¥"*ùJR"¯”¥"*ùJR"¯½!„l¬…m•²ŒÏÛònŠZ²ópå·}WIE_gÙ;ï·ß7Ý{îgÕt¤â¯”¥"*ùJR"¯•™ÍÛ/ÝN£1øügRêéWٜݲùÝÔê3Æu.®”ˆ«å)HоR•Ÿ³+÷â”®¾ü9OßÄUõÒ±×òÕ·;²ÜÓ¹ËÇãO«ˆ«å)X·ëÌÙ³-Öëq ™Q}uŸŒß÷VuoøvÏøŒººDUöm³ý¶~ü_mŸVØF«¥"*ùYûúñÌo=5Ž£¯fçu©±Ê=Öb™K«”Uò³»vÛöVý·âûvÞ®“Š¾ÍÆíó¯:÷Ü?vøG]])WÊR‘|¥)WÊR³wËߨÒw;å芾ºR³º›ãÖ§|Üåæ[-jTE_])HŠ¾ÍÆíó¯:÷Ü?vøG]])WÊR‘|¥)WÊR‘|¥fÌëýø¥++6[÷õq}›¸óþ^øîÆ“¹ß/U×—þB~WÛüÒ`Ëâ2ü™ÍÛ/ÝN£1øügRå}t¥fͶÿöÇö~/¶Ùb¶Óо}“¾û}ó}×¾æ}WJÆ^ëVøþËcç+ŸŒ>QW×Y¶ÏöÙûñ}¶~=[a®³mŸí³÷âûlüz¶Â4E_])IÅ_gÃwÝ×™_îó|'.®”ˆ«å)HоR±³þÙþÛó~ÎÙÅ?a5q|¥fÌ篹ÿ™²œãŽÊuÓl¶Ûm›l­¶3iE_?f=}ŽüÏÖÇSª®”œUò³9¿uó³)Ôo;ÍëU]"*û>s~^9Œç/sÎæ±Õt¬ß'o¾ûçß/}ÍÞQW×JRqWÊR‘|¥)WÊR‘|¥gÙ*ûuwÜ;¯ «ˆ«å-}ÐÃ7K¥a+Ûþÿ =¿9ó ã¶²J*ùJRqWÊR‘|¥)WÊô XÖ?¶Î¬cþç™Ùlþ¢³á»îë̯÷ù¾—(«ë¯ìÛõýÔÌξíÙófw}Î]E"*ùJRqWÊR³ößíûc³?Ÿì±hоºü“²['络ÎÏ·û–Øýz"úP†–S¿G™ô6B¸?²_t°Oë½ Ø`gÃC¿&bW&—€Æè%$ ä¥ÙÉy?“¸Ü”©®F•‰õUÿ8�¬¬’ÑÓ·)¿gã7Gî_fAÜþs-zæï’½÷_ÊZ÷oƒº¸»í©H ÈEü‚X¢-¤²Zö%?B:øÂZ˜÷lš�9ÃS‰¡ a,Ø0¿^éÿ ýò3d˜—Ҟɷ×0Û:¿áô¾œ�Nb±E£!8²h@Ôt¥ééO%ÿBÆÿÒ”  u¯_8(´„%òvûß>=wo˦¯¢•ã{°Î{8C3;žìá;˜Ë§) wÏ“›î´|°=Ô·Z–m´ªú)JN*û3›÷_;2Fó±üÞµUÒ‘|¥cçÙóýþÆý™û |âiœßºùÙ”ê7æõªQW×JRqWÊR‘|¥)WÊR³wÛýóã»>Ûü¡_芾ºVlÆþ¾{ÎVÇcêâ*ùJR"¯•›d+m—ú”¿ßðþ¾.®‘}ŸŒß÷VuoøvÏøŒººV-ò³7~ëu2˜K÷T¢¯®”¤â¯•›d+m—ú”¿ßðþ¾.޽–½ùÝ”ÆV?˜u\¢¯”¥c/u«|e±‡s•ÏÆ8«ë¥+ú(ïÔêÝ·ýOÍì¶Ç-Ùö”Uô^À%€Ûå“ ½Zpad… 04ngNC¾|îçkÉîæ|¾{ÏWçŸcï¹€Ä5$ÎB-²XÎŒPgGGù<0¢ú:ÓÜ3¤˜3ì3ý¶íî-ÀÙ:ª¿®B/£`1‰h,3þOä´¸FIEŒNJRL@Ô%¸Fõ`P¢’Xoù8°Òøb ¡¡›%ÞJé8›RwéIXfã“þk¦W@Ç/’‹&ÿGA]�8ü01!½ƒ[¬3“:KOÈû³*ð\˜„”ÄÄ„£#pÀœXÐÏò¿JR3“pb”È@cÛ*ñ;‡8ríjþh+$°À*S|_) X¡¥ò†6  ßô†~Ž‚Ñ†£%º>˳ aŒŒŸºC†£†ñˆß>äÄ»¡]øÅäqyb²9HFä²’ܬ͊û£ä!¥åäåwCemp¯iþwP{lªÿ¸P ’‚‹A@©Ä¤gI5 d_RÃ~Fr‘û2yÉÍ@% &%ô–_B Û•Ö0 £†¡ÐžPÖÙÙÛ£§¢ø}é@¨€nPÆ)²zr�ºt|ÒQ{ºzRéo›­ÍÄ`çWà…¡(ûwᜠ$ДlëéOZºÓþvë{“~Š!âhä#�VŸØ3ŒBFnHQa®•mÒ’º fK{ád ÜYEÖþ†§nÃU¶î¯ú0Å„›ÚüüéUüšR—u5|¬lû¶}¾ÜÝ»>qmœE]"*ùJR"¯”¬ÿ!ì½–¥þÛõauq|¥+3­þ=JfÍ_uºÔ¥DUõÒ”ˆ«ïCpœá;7)|‘ÎëZ·tŒ½ßÔ¦ç,çQ‹e®®³:ßcÔ·|Øõf[©j\¢¯®”¤â¯³ö~ÊߟØÂ;eúºR"¯±oÕ™³w[­ÔºêéHоV~3ÝYÕ¿áÛ?â2é»íþùñÝŸ íþP¯ôå È@Õöη[-{#p¬#J*ù†îÝg÷Ù¶Z·ßþíÏÊíÎV¨¥"*ùJRqWÊR‘|¬uìÜîµ69GºÌS)sä¶@Öß©ÖÏöÿoÎæegk_ ÈÉKäí“ó+lSdîŸÉN5Ïè'CE_a„t('rJ hퟠ•’„§ô;lç{í½!¥$˜Yî¹y?³îœŸÓƆQD=‘†Ÿo¶OýãËùÒá¥Ë/'’¾èå’‹AiJ�‰j,`Ä2ÿzPÐÔr·87£ôòQ3üÅâ€Ï�· ²ÉNWR‹ÆÂ±Ê 9˜Ö#ÚÕý2i1Š,·ä°ÎY\¿Ê&§¤1r•pÔRS‹VB2PÈï|àÉ/†’à[“( )9)˜ 'ôvû%xb3}‰^úPlŽ” GÖØj ¸²Y[ò‘ðCæfÉØc–²‰Eûæ & å!dü¿Àe$ÄŽJÈd¥nû7Kÿ‘ѾC5ŸgÌ;ƒüUþ—ºÕ¾?²ØÃ¹Êçã«¥/ ²«å)HŠ¿ÒÀu‹@(1òFŒÌÌŽ„3¡ºqêßæù?]` ‚Òt_B:Vm‘¶ß!}˜¬Ÿ–í¸FEâËÑòskº—›©k3cÕ}H4 “�O‹B†–¶ùrö ÿ! Ð6ÃR”„gÉMÀù²ùäCê«þMKxgãù°ÄÓû²÷%£%JZBzßkÝM_c/÷çe)±ë9ÖjÙJ«¥cgݳíöæíÙó‹lâ"*úéJN*ùJR"¯”¥"*ùJR"¯±—»óº”Üåœê1lµÕÒ³çcÕÜÿŒùlyçu:å}u›äí÷ß|ûåï¹»ÓöcרïÌýlqÇõ:ªâ*ûË1$¦Ü`×ì§e³žÕŸ ßw^e¸wÍðœº¸Š¾R”œUò•ÿ„£>Ý}¹ÿev^;üýc¨”Uò½³ý·íÒË[l{oÎgû+I³:ÿ~)JÊ̓Öýý>v_ÍÅ-]]ðz›¾ˆ«ë¥)8«åfs~ëçfS¨Þv?›ÖªwnßnÊÿ>Ü^|âSmŸí³÷âûlüz¶Â4¢¯®îÆ¡(,¢€É{'3üèìû'±[ôâ¸JÆnÛÜm˜yÿ¯þsIØí•¯fCId$xbädäÓ†’Ò3 ¡¥„~JûÿËßXeƒ êû6(7íËC„þZBP[dñ4oÿ¤0Ù»ýúPÛëéIHÑ’OA\ Œ )?Z\  {òRRYHÅdl~ÞùÈK%%‚Ào’–Jy(7ñ™%nYa.‚’Jàc1™³½Ý¸8¤€ÌŽ^佃3tì”ñ¨M+âÐÈÝÒ•%9†^HA¦0qç´«ý H!¹A…ŒOÉd.œVV,„œŸþû„¸bwß'ÿßß- ,´ ¯ËèÛ²q|3ÆŒINÈÛ%¾+”Èá=¿mýô@òÉ©+ðÒ²z ICwFGý%–œ [ÉAIëHÂ^ì‡÷ÎÀM¹HAHF+e§15¶ø b¸jý›—À›º/«ê89\ÐùUþN”¥íÙÕò”¤E_/¨€ÄaÆ–B(¶éBFúùCQúƒ^+º m³=ó/Ù•ûñJW_~§ï切ï’Èa¸—‘ˆA P±©/lQ/ JƒQÃmº2þOÿ%øË‡c[‡…UWüô ”L)t|ŒèÿvæçÛfÝXfÈÙ[ms.èAh(3d#›bÝò>û ûí‚k¤ýóÜ“¿t¾1òòÿ?6fm”ê_÷Ogò«è¥)k*¾R•éFNn=íÉswÆ Æ7”UôR”œUò”¤E_)YÝ»mû+~Ûñ}» oWWÊR‘|¥)WÊR‘|¥)WÙû?eoÏìa?²ý]+{¿;©MÎYΣË\¢¯®”¤â¯”¥"*û?f=}ŽüÏÖÇSª®”ˆ«ìîݶý•¿mø¾Ý„·½`Årj øgÛ Ì–JR7lÜb0×/lŽw}½ãïJ²ƒhJ‹K1NWZ8kn­ÕкÀ8O?®|ø>uu Á¼ (Ä¡=О3|Ÿ€Á_$–HÝ 3æl”kÚ—ÔXie“Ò”ìPÅ`ÜR‰¼¢^/}‚V%â¾ùßë8hg&t†òÝ’’j8n(˜øÀÎKÉ |‡É+d~|ýµÂ,²e–0¢Ê&–‹%§ ''t#â_úùA¨Ý²Êý*¼ŒíŽêQ¨w´«ýye ™Æ'!(à6Ä¡ˆ,´ ¢’±+¿ %bÊãKBNNÛ½ñ²a ŸâS7éB÷+?NĤfÅ|ŽÈÎëéïï«�¡1!€[r@ÇtºŽPj_Q÷+·ý(Ì7ð·ÅÃŒ–û§dýúUÛ+díð†B×óÛÿÜx ¥Wä¥){u|¥+?È_û/e©¶ÁýX\E_¬²ò7Ûíöû1Y»%;¥cæW"û럆¡.Ãq( *‘©BxH È/ô>èÁ»¸Ýö)?–ÿÔ€„äß¹EŤ5( +–ßñŸ#”Q[ñ™.ŸNB^Îp€Ðá©F塆¨5Åd ï²·XAn¦ÈW¼^sQ,*Ò¯ùVvÏ÷쿳oÅgí…?«¥/jί•Ÿ³+÷â”®¾ü9OßÕÒ"¯³ì÷Ûï›î½÷3êºR"¯”¬ÿ!ì½–¥þÛõatû%_n½Öµîû‡uárоºÍ™×ûñJVVl·ïêé8«å+>s~^9Œç/sÎæ±Õq|¥)WÊR‘|¥)WÊR‘|¥+{7;­MŽQî³Ê\E_]+>Éß}¾ù¾ëßs>WWÊR³¹Ÿeãó©Ön?Ìë\E_])HоR•Ÿ ßw^e¸wÍ𜸊¿º°)ˆcs’‡tí”/|€Ò¿ßä>[œØý}d%Bð ÉpÒÃCp` Mß0—ܯ¾ÍöÈn_Oþ×Â~¾î¼Êÿpï›á9w¥ P ÜèÁ%-8¡¡(ûîZ7K6[ç kÏG k×Wû´ðÒajÉ À;B9hö!†ñ®‚ƒyE•°ÒøB~ßçÃwׇ((/°g);†Œß–[÷”üå|ØbqL’Wo·Ì×§&Bi03î”�Ù/JÍÒî„òJ2 (3O?¥÷kÕ°É/öB é�·Æ£ä#p/²6O Á8”^ù ûÜjârÎ (MUÀi}ƒ“RW -Í÷üidÄôwèÉB%b¹Hû,7÷ÉؤíîÖ�Ä7 ¤†0 ŠÄÄbbv”þÛ#ñ¼4g+Œè‘­þíî¦é«þ.j2R„üWB:xÔ”Hßá­“þÊwûfø××Õ€bMJI¸ (CÙ”ü´ŒI[bɉè@Ø´§ð2ÿgégÚ@�è´†ô’‰½!¿ž´¡õ ¢ÆtíÊ ÈømóÜ�(�ø Äb’ZCI_à”6ÃzñNøbv^ Ýþß/Xþ£ˆ¤ ÕûÈ@S“QÀ-Hoÿ ”Ø ¡(&~0²ñ7ýÿèHå%TÎ×Ë™¿;)MYγVÊU6ÈÛm¶Ù¶ÊÛc6«½è«å+>ÏŸïö7ìÏØSçWtJ¯”¥"*û{7;­MŽQî³Ê]6ÈVÛ/õ)¿áý|]]%|¥+úää²wS1Ÿ7ÝÿÝÖ9JhоŠVw3ì¼~u:ÍÇã¹k¢ß¯3fÌ·[­Ä6eDUõÒ”œUò•›3¯÷┬¬Ø=oßÕÄUò•›3ž¾çþfÊsŽ;)×Lë}RÝócÕ™n¥©rо|ìz»ŸñŸ-<î§]])8«åfî<ÿ—¾;±¤îwËÕtˆ«ågví·ì­ûoÅöì%½]"*ùJVo»í÷nÜWmÛŽWÜGˆ«Ü¢FWζO¿_Îÿ(WlvUEfu¾Ç©nù±êÌ·RÔº¹E_)JN*ûýY›7uºÝL!»®®•›ä¯}×ò–½Ûàî®.QW×JRqWËX)jÝþï×Ôžœ¾ü#÷F95’’Š¿ÒàܘP`gXN ܽÓ×ÑùÊéÛ}ö|¦Íî )‚2¿NVWîÿ ïßšþNíÛíÙ_çÛ‹ÏœCêº{ί•›îû}Û·Ûvã•÷êéi*¾R”ˆ«å)HŠ¾Ï²UöëÝk^ï¸w^WJDUò”¤E_)JÍòvûï¾}ò÷ÜÝâ*úéYó²þn)jêïƒÔÝõ\E_)JDUö2ÿ~vR›³f­”ªºÏò7ÿí¶ú¶Øßêå|¬eþµíì§0ìzùüÓªé8«å)HоR³wsÕØïŒÝNyçå:©ÝM±ë[6nr»­”¥.QW×JRqWÙþFÿý¶ÏÿVÛý]+;·m¿eoÛ~/·a-å}t¥'|¥+6açþ¿ùýÍ'c¶Vˆ«çìgëÇ1¼õüqüÖ:›äí÷ß|ûåï¹»ÕÒQWÊVwS|zÔ¼Ëe­J¦u¾Ç©nù±êÌ·RÔ¸Š¾wnßnÊÿ>Ü^|âUÒ±³þÙþÛó~ÎÙÅ?a1}t¬Ù¿¥efÁë~þ®qWØùþ|ûoñ»wnÂÛ°ŠlÎzûŸù›)Î8ì§]]%|¥)8«ìî¦øõ©ß79y–ËZ•WJDUò•›»ž®Ç|fêsÏ?)ÕWWÊR³ñ›þêέÿÙÿ—W͘ß×ÏcyÊØã±¬|éÛ¶èŸlËß¿3ìÌýÚ¢’оR”œUò³üÿûmŸþ­¶7úºDUò”¤E_)JDUò•Œ½ßÔ¦ç,çQ‹e®®"¯”¥gù ÿeìµ/öØ?« ˆ«ë¥)WÊR‘|¥)WÊR‘|¥)WÊR‘}Ôßµ;æç/2ÙkRªéHоR³l…m²ÿR—ûþ×ÅÕÄUò•‹~¬Í›ºÝn¦Ý×WWÊÌíŸïÙfßŠÏØCúºDUò•›»ž®Ç|fêsÏ?)ÕLëR™³c×Ýnµ)RоºR“оR”ˆ«å)HоR”ˆ«åfu¾Ç©nù±êÌ·RÔººÅ¾VfïÝn¦S ~ê”UõÒ•ŸnßíÛ¾ÛçÕþç}uéí›}¿|‡ZÛóŸ~s¶ùZ¢’оR”œUò”¤E_)JDUò”¤E_)JDUò”¬lÿ¶¶üß³¶qOØLE_])HоR•Ÿdï¾ß|ßu﹟DUõÖ}“¾û}ó}×¾æ}WHоR”ˆ«ågû6ÿgí…öý°õoÄjo’½÷_ÊZ÷oƒº¸º¹E_+>ÉWÛ¯u­{¾áÝx];™·^?²fs±ØÞ¥UÄUö-úó6lËuºÜCfTé9Ÿî—ÛìíÛ÷;ì5:ª)WÊV|ìz»ŸñŸ-<î§]\⯔¥"*û7·Î¼ëßpýÛátÝöÿ|øîÏ…vÿ(Wú®’оÍòW¾ëùK^íðwWWJN*û?Ù·û?l/·í‡«~#UÒ‘�������z¿óý+3›÷_;2Fó±üÞµUÄUöm­¶_êRÿÃúøººÍòW¾ëùK^íðwWW(«ågìǯ±ß™úØãêuUÖ:þZ¶çv[šw9xüiñ}t¥gì<ý•¿?±„þvË󊾺R‘|¬lÿ¶¶üß³¶qOØM]"*û3›¶_;ºFcñøÎ¥ÕÒ‘|¥)WÊR³öcרïÌýlqÇõ:¢*úéYóï·ùñùŸ ϾP½õ\E_)JDUò•™ÍÛ/ÝN£1øügRêâ*ýiéÝ Ýû3q.7>Í·?7íŸY)IE_)JN*ùJÎêoZós—™lµ©Uq|¥+?mþß¶;3ñYþËöˆ«ë¬uìÜîµ69GºÌS)utˆ«å)HоR•‹~¬Í›ºÝn¦Ý×W×JR"¯•ŸvÏ·Û›·gÎ-³ˆ«¤E_)JDUò”¬Ùœõ÷?ó6SœqÙN¸Š¾ºR‘|¥+ùy›¾eº™n%ó."¯®”¤E_+6g_ïÅ)YY°zß¿«¬ÎoÝ|ìÊuÎÇózÕ(«çí¿ÛöÇf~+?ÙbþÕt¬ÝÇŸò÷Çv4Îùz"¯®”¬îݾݕþ}¸¼ùÄ>œUõÒ”ˆ«å)HоR”ˆ«ìÙ¿¥efÁë~þ®±×òÕ·;²ÜÓ¹ËÇãO«”Uò”¤â¯”¥"*ùJVo’½÷_ÊZ÷oƒº¸¸Š¾ºÌëR™³c×Ýnµ)Tÿ#þÛgÿ«mþ®QWÊõ'šÀ{³°vNn/8½Q^WéB?Íþßå©ñËÈá{qQ}¥'}Ÿ±Ÿ¯Æó×ñÇóXêºR"¯”¥"*û>ÉWÛ¯u­{¾áÝx]]+6ÈVÛ/õ)¿áý|\¢¯®”¤â¯³a›lêÌ¿ÿýÿ×WY³?õÿÏîi;²µ\¢¯”¥'|¥)WÊR‘}Ÿ³+÷â”®¾ü9OßÓ»vûvWùöâóçú®’оR”œUò”¤E_fï·ûçÇv|+·ùB¿Õt¬ÎnÙ|îêuÇã:—(«æî<ÿ—¾;±¤îwËÕu›»ž®Ç|fêsÏ?)ÕWWÊVglÿ~Ëû6üV~ÂÕÎ*û?c?^9ç¯ãæ±ÕuŸ±Ÿ¯Æó×ñÇóXê¹E_)JN*ùJÍÝÏWc¾3u9矔꫈«å)HоR³ì÷Ûï›î½÷3긊¾Ïœyû«üws øï•é»íþùñÝŸ íþP¯õ]%|¥)8«ågì<ý•¿?±„þvËõtˆ«ìîݶý•¿mø¾Ý„·«¥cçÙóýþÆý™û |âe}t¥'|¥)WÞýt¯ìüb:Û-‘†ñ~¢””Uò”¤â¯”¥"*ùJR"¯”¥"*ùJR"¯”¥"*ùJR"¯•›1¿¯žÆó•±ÇcXú~Æ~¼sÏ_ÇÍcªå|¥c¯fçu©±Ê=Öb™K«œU÷–œR:{ý€’žÿÕŒ¿Ö½±ý”æ_?šu\¢¯”¥'|¬Ù¿¥efÁë~þ®‘}Ÿ±Ÿ¯Æó×ñÇóXêºV|æü¼sÎ^çÍc¥}t¥'}޽–½ùÝ”ÆV?˜u]+>¾î¼Êÿpï›á9rоºR“оR•™Íû¯™N£yØþoZ¢*úéXËýkÛÙNaØõóù§Q׳sºÔØåë1L¥Ê*úéJN*ùY°Í¶uf_ÿ‡þÿ‰ë«¬ÿfßìý°¾ß¶­ø(«ë¥)8«ìù÷ÛüøüÏ…çß(^ú®•™Öû¥»æÇ«2ÝKRå|î¦Øõ­›79]ÖÊR—FÏ»gÛíÍÛ³çÙÄUÖglûnËÛ¾ÜWlâ[DUõÖm³ý¶~ü_mŸVØF«¤â¯”¬ÎÙþý—ömø¬ý„?«ˆ«ågùÿöÛ?ý[lo÷w€œ0 Î[•²F|ž‡}×·ÉèKgÿ#þ¯˜nk¬M >FÙ8–¼íöXÒ¿¹@`½²{§¶–®lŽà©Õþ3ü…ÿ²öZ—ûlÕ…Ñ׳sºÔØåë1L¥ßN 1îQ)Ó€Ây@UiI`Ü•±Im‰}¤’ßeX�qIIh%$ †ÎIý`‚gwÉ)Ÿ•çìò Üà#:¿ç”¾†�¤šBŧôï÷ܯßt£ä€ 3ÿñIà jû2õâÊ&”ðÎ7|ù(ß•ó°vîc¸«o¥Wà¬ùÇŸº¿Çw0ŸŽù^®–ò«å)HоV|ìz»ŸñŸ-<î§]7qçü½ñÝ's¾^«”U÷’_oó|ý„vÏ›ï•þ½ê)HоR”œUò”¤E_)Y»º¾n)jËÍÖÝõ6ÈVÛ/õ)¿áý|\¢¯‹|¼Íß2ÝL·ù—WYó?uŽîa?ò½?ÏŸmþ7níØ[vW×Jž^fï™n¦[‰|Ë«œUò”¤E_)JͲ6Ûm¶m²¶ØÍ¢*úéJDUò•Ÿ;®çügËcÏ;©×WWÊR‘|¥gÃwÝ×™_îó|'.›äí÷ß|ûåï¹»Ê*úéJN*û?ÏŸmþ7níØ[vz*ÐŽ¬5?tt%%’€Ää$cô­nIã3ç÷ñ[#?ùä;¥9 jzúöÿóúýîÃ@v„g@ › ²øÅ±A©)‰Å¾ýäíðÇç5ɰ“ÖEÏU_ïÊÚ@©+baA½˜†)<0±»~¾É&#l”æÌ^nX@Å^<™’CAEg&rúK,¾ I5GèÊÝ–ÿ¡Òù­‹¶µ–Bø´ùhÙ;!zS’ä²nB0Ò„”0­¿o¶› Ho,šJ/bÒŽŒŽœû²Œ‘…6Xie­(AjlÉ÷ެAû0³�Ý¥_ 0 30a0²ß°fØ ¤„ ‡“²Füåt/o’Ùõ× !$ ä”�é±|1¢YX æ@Ì4ÎPÈK’ÕñB®! !‰AI)†#ñ(7~4¼ŒVC2F–Ž_ïÃSÐ19c=ãƒÒ„·ü5;þJÎѰ×Á›!<¬èXϾ·ý¹ pðSWý†�0˜0…ønÃrºÿJy )(5D¤' ËCnŒý½êA è1…$4´$˜ü¤†#d³#bÒX ’Ž0´¯€¶2üêYX7 NBQøJ»ãS»wûXV Û|ù׆§)º¾ÊNçt$#ãí·[â<Uþì�”Y} è~7¥85132F ù8¯¶- 5Æ¥j÷Î_?ÏŸmþ7níØ[v}ܰC9e“YH&|baaœšÅôw%t$5¶q¹$Ž[nuã€`¼YCPŽÛî1 |4´²�Éa¨BSÆþœÀ9<%ºcå 4å«þkJVnŠZ²ópå·}zÖu}t¥"*ùJR"¯±×òÕ·;²ÜÓ¹ËÇãO«¥"*ùY³9ëîæl§8ã²tÙœõ÷?ó6SœqÙNº¹E_fÌëýø¥++6[÷õt¬[õælÙ–ëu¸†Ì¨Š¾ºÍÜÏ—Ïc9êüóñ¬}]gã7ýÕ[þ³þ#."¯®”¤â¯”¥gÎÇ«¹ÿòØóÎêuÄUó;gûö_Ù·â³öþ®”ˆ«åfÙ Ûeþ¥/÷ü?¯‹«¤E_)^—gÏÙøÌ0%]A*'åšÒ³oö~Ø_oÛVüF”UõÖ>}Ÿ?ßìoÙŸ°§Î&®“оVo’½÷_ÊZ÷oƒº¸ººDUò”¤E_ÒOé) (éÎJOC'ýÀ·_¿$-_ßCŽ|”8gå–Zpi`6A1 ËƒwèIx1òZY¿Û^,<¼„ Á9’ÿÏ“ò23‚ÛÿŽ ×¼€ad/‘˜!–RPJd“9iø3rQ459òÿØ5}ö{ËÌ?à·qçêêþ`a(„á¥èHNø¾^%’ñOËtô€ßtrRþå) MìɪÜ03†%†§öÉ…#~’c 3 Nè@`GÛü’ú.Po+“:J)¡…nK, üM@fA[�Û~·J iÛÿ‘ýÞ�Ð5(/†£ºPZp˜(å¤kpÏÒ?C ã6Â.ýoÌ>º¿çè ø´ ¡ˆ,3[†}’°ÀÁ¿ 1;bÆô> ÌþñBr)|0•˜#3fûì ŽÆ/3¶¯ )(ÿþÙ/ÉC†Ý]­|–ý#R¼ÙW&ö¿"À_)J]4Õú )¨JŸ't|¼ûæç.û8JàP “0bwbP&lrØ´X(3ºS›edíÚø…é@v ¿·ügQhº7›e ¶uqŸ­ÚâGQª¾�h’Y0—Ð3¥)ü ”ïÌ,¥}°Fuí˜ËÍ_wq0 “rC~/†–”äbZR0´££â²Ï|ÅnĿљ ×Ã?açì­ùýŒ'ó¶_ŸÀ2оºÇ_ÍÎËSsÔ{¨Õ2ÕWK²š¾R”ˆ«ågví·ì­ûoÅöì%½?c?^9ç¯ãæ±ÕrоR³öcרïÌýlqÇõ:ªç|¥)WÊV~ÃÏÙ[óûOçl¿WWÊR‘|¥)WÊR‘}›»ž®Ç|fêsÏ?)ÕWJÍßo÷ÏŽìøWoò…¥}t¬ùÇŸº¿Çw0ŸŽù^›dm¶ÛlÛem±›DUõÒ•™Öÿ¥3fǯºÝjR§}t¬ùÍùxæ3œ½Ï;šÇUÄUò¼ ¦Ê@ßÛ+?îžÃÿ_áþ¢Ö€–Oß}¾ùÒÎëWÈuå'㗕銿݀kùc>rö&älJpÍÆtt'âÑÒ7§¡Ü >Å%—4®Å%þ^nRKã;ÜXi5 ðiÝ\¡½ÑïJ!!ºJᨠüjCvïЂ‘øjR—Ãxa…t§#²„®î%)&'�ZžRRÊHnÿ’· ÎΞœž7†ô”ÉOÑïX<IÊ;žÖ¯õƒqh é,4²L+>0¼KPÀÒÒLNèΞ”„ @Ã/’€\”ò;¤ËÁ'ÿÊè G/'|Œ¿¸ÔòßÞä˜B,4¢-% ¬ÒJéB2?Ì” 0¢Êì04'Z6ýõó@'Ïå|È/älß’ÃWöHiX' r’4n çi¥]G¿ o‹¥)}•_)JDUòÞM)¡‰BPKßwB–+?ÛqÝóslH†MÄ Ä—ÛŒB~ÎÃzÒØ[nF>*ÿ¢Q(?””¶& ²hGJ:2J%á£R’û3 Ãr;»ß0Û캲»ºÌ?÷we÷r}ïܼ”€ß ¦Øho%WJ:WOHÁ™f±]) é+f{À ÒÈÙÿî­±¿ý™Kã‡Ü‡â6 UW¦u¾Ç©nù±êÌ·RÔººÌíŸmÙ{wÛŠíœKj»¶š¾Å¿VfÍÝn·Snë«¥'|¬îݶý•¿mø¾Ý„·«¤E_cgݳíöæíÙó‹lâ)û?eoÏìa?²ý6ÈVÛ/õ)¿áý|]7É^û¯å-{·ÁÝ\\¢¯®”¤â¯³ì÷Ûï›î½÷3ê»Y#ôôeô#}¿ÿíŸ7ü~Ùo—d”Uò”¬û%_n½Öµîû‡uásоºR‘|¥fv϶콻íÅvÎ%µ\E_gϾßçÇæ|/>ùB÷Õt¬Û![l¿Ô¥þÿ‡õñrоºÌæí—Îî§Q˜ü~3©utœUò”¬î¦Øõ­›79]ÖÊR—WÏÛ·íŽÌüV²Åý©ó?uŽîa?ò½]fÙ Ûeþ¥/÷ü?¯‹”UõÒ”œUÿa�Ĥ$šÜ—†ò±i(1%—ƒŒŽ5() ä¼–Ù)í‰IÏýÞÄ. t %`”bfÄ4¡?•Ø’Hax®ëȱ[÷ßß8Ž-Å”\gØ3—ÝÓ÷K! G,¼Q,fÁ¬˜f6õ  ˜LJ'âŠÄ¢ùðÒ²RKÈJ’0¦FÝÇ^în4õÚÕüL‚ºSƒCr>GØè¿€),¤“JFêß1X m†ô7kç»dm¶ÛlÛem±›^£!?'ð2~O€Ê1(4—ñHûÝú HÇdoŒ{ÉÞˆ�ݨ«å)K®š¾R”ˆ«åì�1å€TXÀÄ—Æ”3û«£ïÙ“™9yÙo×–/üñ‹á*Çí²ÿøæu™Î½ÂI©&òÊ�§%Ùˆ_o²†ç!ŒÊI{’Ñ·JWß·k—2ˆµUú�`¤bÑÃI„‹ØnA(¡»þå1]99öÿKÈ×ÏÝ+V?2úòŸð…|¶ËvËΫX`g(òÒ[m7­†#q¬¤ÿ÷Hßk ß/3wÌ·S-ľeÕüªúéJ]«å)HоR”ˆ«ì[åfnýÖêe0—î©Æ¶t²Ç©}¿²ú”?¶y?Èßÿ¶ÙÿêÛc«”Uò³üÿûmŸþ­¶7ú~̯ߊRºûðå?WWÊR“оV‘¿ÿm³ÿÕ¶ÆÿW^Io¿ÍûæggÍß;:÷Ìí–ÒŠ½6ÈÛm¶Ù¶ÊÛc6«¥'|¥)WÊR‘|¥+6g=}ÏüÍ”çvS®"¯®³fuþüR••›­ûùÆçl¶íÛà…:Öã‡õã*%|¥fîêù¸¥«/7[wÕsŠ¾Í˜ß×ÏcyÊØã±¬}])WÞ” Çôu·Üï÷ÎËÝœäïm}h†’WÃ1dņ”î7�Ù!?`ÀÀĺY+t¡.ËvÚøõy{¥nήyÆ·ß}Øïººî}ÃÎ_õÐy3¡úS‰»„(01¥ôd¤­Â8ÒÒäÄòZ¶lϯ•M $'sÍZ™l{/}Îûï•õí�v hiH%pÁ»† GÝÄ”ËèA+ ìéÏ¿nÆ_CB@vL!ôSùa¹úKGb’J,b’¿á?—‘‰Ÿs™n‹Îì9±<Âuç×ÏóçÛÛ»vÝ„UßY(Ït¡((hJP45 •ñI(%(FãrxÅdæÙ8ÿs@¨ÜBÄ´lYOŸ²PI É(­þoÒã9Íóü÷a*š¿çŸä/ý—²Ô¿Û`þ¬.Ÿ³+÷â”®¾ü9OßÞа¥€7Èã8a/`0ZFoß%)ß#„3†e¹éÈtÞÓK&òˆx5ÿC‰Ÿ¤43$°Ô’÷èº�lÝ¿Ùü1†Å_ÄHoå °€Ô�Ý%œ”rË%“{ŽZ>b¸Ï·mùNù]”  1i!¤´€oñ/>èã?û¡ ñœhný<k”è`Pg^N- –„`¨J6ë Åu~ùZðen„mû²±çÿÿÿcÿëë²éX _¬„LA¬R„t¶ß¥]?ž•¬ÿŒê¹´¥èuÑWÊR•E_)JDUò±×ós²ÔÜõê5LµUÒ"¯”¥"*ùY³:ÿ~)JÊ̓Öýý]"*ùJR"¯”¥"*ùJR"¯”¬ýŒýxæ7ž¿Ž?šÇUÄUò”¤E_z7FoÝiæ›ÿeÿÔqì;l©7Ýöû·n+¶íÇ+î#ÕÖwnßnÊÿ>Ü^|âJ*úéJÏömþÏÛ íûaê߈ӊ¾ºR½].s©F6Ýnfo”UôR”œUöglÿ~Ëû6üV~ÂÕÖ|ãÏÝ_㻘OÇ|¯W(«åÝ�<(jS¿GK¯ ß?GWì7 è~„ô¤nïp©KÅ_êI 0 Fؘ€ÇO ÉB�ÇéG?møÇïò»ç°�T„dvå–€²KOýÉC•°ÜIlζ{‹J\ž|êþ±„‚°FlÈÛ#}Ÿ ô²~Ý)ÿŸýÉ¥+yUò”¥QWٜݲùÝÔê3Æu.›¾ßïŸÙð®ßå ÿUÒQWÊR“оR•›¾ßïŸÙð®ßå ÿDUñ—ú×¶?²œÃ±ëçóN«¥gvíöì¯óíÅçÎ!ô¢¯®”¤â¯”¥cçÙóýþÆý™û |âb*úéJDUò”¤E_+3¶¿eý›~+?aêéWÊR‘|¬eîµoì¶0îr¹øÃêéWÊR³»vÛöVý·âûvÞ"¯®”¤E_+>v_ÍÅ-]]ðz›¾¦Ìoëç±¼ålqØÖ>®QWÊR“оR”ˆ«å+>v_ÍÅ-]]ðz›¾«ˆ«å)HоR”ˆ«å)HоR³»vÛöVý·âûvÞ®"¯¿£|œœ“>ß37Ç/qnxêŠRQWÊV2ÿ~vR›³f­”ª¹Å_)YÝ»mû+~Ûñ}» oWWÊÏ—óqKWW|¦ïªéWÊR‘|¥)WÊϜߗŽc9ËÜó¹¬u]"*û?Ù·û?l/·í‡«~#UÒ‘|¥)WÊR‘|¥gÎoËÇ1œåîyÜÖ:®"¯³wÛýóã»>Ûü¡_êºR"¯”¥"*ùJV|ìz»ŸñŸ-<î§\E_])Y°Í¶uf_ÿ‡þÿ‰ëˆ«ë¥+3›¶_;ºFcñøÎ¥ÄUõÒ”ˆ«å+ß÷lÿ}»¾Æ÷ní¹Šu>¨”Uò±—û󲔨õœë5l¥UÒqWÊR‘|¥fu¿Ç©LÙ±ëî·Z”ª¸Š¾R”ˆ«ågu6Ç­lÙ¹Êî¶R”ºw3ì¼~u:ÍÇã¹k«”Uög7l¾wu:ŒÇãñK«¥'|¥)WÊR‘|¥)WÙû?eoÏìa?²ý6m·ÿ¶?³ñ}¶Ë¶«¬ÎnÙ|îêuÇã:—(«ë¥)8«å)HоR³fuþüR••›­ûú¸Š¾R”ˆ«å)HоR”ˆ«å)HоR³l¶Ûm›l­¶3j}“¾û}ó}×¾æ}(«æÌëýø¥++6[÷õt¤â¯•‹~¼Í›2Ýn·Ù•WHоV|7}Ýy•þáß7ÂrêéWÊR‘|¥fî竱ߺœóÏÊuUÄUò”¤E_)Jž^fï™n¦[‰|ˈ«ë¬ØfÛ:³/ÿÃÿÄõÕÒ"¯”¥" ���H����z¿óý)Yó±êîÆ|¶<óºq}t¬ÎÙöÝ—·}¸®ÙĶ«ˆ«å)Yû?eoÏìa?²üE_]+ùY›¿uº™L%ûª®"¯”¥"*ùJR"¯”¥"*ù^”ŒGês°ÞÛþ­»?lwQIE_)JÎæ}—ΧY¸Ã¹œ|⯮³ý›³öÂû~Øz·â5]"*ùJÅ¿^fÍ™n·[ˆlÊ«ˆ«å)HоR”ˆ«å+;©¶=kfÍÎWu²”ª¸Š¾Vm³ý¶~ü_mŸVØF«¤E_+>s~^9Œç/sÎæ±Õtˆ«å)HоR”ˆ«ìÙý|ö7œ­Ž;ÇÕÒ‘|¥)WÊVnû¾|wg»‚¿Õq|¥)WÊV-úó6lËuºÜCfU\E_fû¾ßvíÅvݸå}Äz-úó6lËuºÜCfU]%|¥+?ÏŸmþ7níØ[v8«ë¥)WÙó?uŽîa?ò½]c¯å«nwe¹§s—ÆŸW(«å)IÅ_)JDUò”¤E_-i-løoÜbd¥³üþr66ÉYðÝ÷uæWû‡|ß Ë¦*úéJU|¬Ùœõ÷?ó6SœqÙNººDUò”¤E_)Yûoöý±ÙŸŠÏö ûUÄUò”¤E_b߯3fÌ·[­Ä6eUÒ‘|¥gÙ;ï·ß7Ý{îgÔîݶý•¿mø¾Ý„·”UõÒ•›¾ßïŸÙð®ßà¯ô⯮³¹›uãû)Ög0ìoWY¶FÛm¶Í¶VÛ´¢¯®”¬|û>¿Øß³?aOœL⯮”¤E_)JDUò³fs×ÜÿÌÙNqÇe:êë6m·ÿ¶?³ñ}¶Á[iE_])Y³ýû/ìÛñYû8«ë¥zÝûsÔ¯Ý[ãanª‰E_c¯fçu©±Ê=Öb™K«¥'|¬û%_n½Öµîû‡uáutˆ«å+?açì­ùýŒ'ó¶_¯ßöùþOpŽŒ0Ì1Ï?%yúÔÔÅ_’•‹|¼Íß2ÝL·ù—WTUò”¤E_)JDUö6}Û>ßnnÝŸ8¶Î"®”ˆ«å)HоR³9»eó»©Ôf0ügWWÊVlÆþ¾{ÎVÇcêâ*ùJR"¯”¥"*û>v_ÍÅ-]]ðz›¾§Ï¾ßçÇæ|/>ø/}WIE_)YÜͺñý”ë3˜v7Ž«œUò”¤E_)JDUò”¤E_+>v=]ÏøÏ–ÇžwS®®‘|¬î¦øõ©ß79y–ËZ¨·ËÌÝó-ÔËq/™urоR”œUò”¤E_)Xùö|ÿ±¿f~Ÿ8š>}Ÿ?ßìoÙŸ°§Î&QWÏØÏ׎cyëøãù¬u7·Î¼ëßpýÛáutˆ«ågs>ËÇçS¬ÜaÜÎ>®“Š¾Í˜yÿ¯þsIØí•¨ËýkÛÙNaØõóù§Qײ׿;²˜Ó±êÇó«”Uò”¤â¯³l…m²ÿR—ûþ×ÅÕÖ~Ûý¿lvgâ³ý‚þÕrоWÿòQ¶=ÿ=[ oþWùóüuE"*û6açþ¿ùýÍ'c¶V§s6ëÇöS¬ÎaØÞ:®‘|¥)8«å)HоR”ˆ«ågu6Ç­lÙ¹Êî¶R•W^ÿ¡Ñ—óì—AŠÝóáj|:QWÑJRqWÊR‘|¥)WÊÌíŸïÙfßŠÏØCúºDUò”¤E_zÒƒJÿ�ñÑþá5¤¢¯”¥'|¥)WÊV~ÃÏÙ[óûOçl¿MÜyÿ/|wcIÜï—¥}t¬ÎoÝ|ìÊuÌ?›ÇUÎ*ùYoñêS6lzû­Ö¥UÒ"¯”¥¬²ÐÃ~Ûþ¿öÙ‘ÓÿŒÜçæœòоŽêoZós—™lµª®ô aŒî,Å£Pߨ¾€æÿ èK·{ЖxfÃw(–ÑÃXÀŸÊl¾ãÛðÅ/'”ß\Ã8±-U_óÚ^À  I… 07Ã’†ICQØ´á»% {ì„å³ñwž &†\”œ–eîùfîwÊùòŸ|~öñ’«ðR³|•ïºþR×»|ÕÅÕÛJ¯”¥"*ùJR"¯³q»|ëν÷ݾ×WJDUò”¤E_)YþFÿý¶ÏÿVÛý\E_)JDUò”¤E_)JDUò”¤E_+6m·ÿ¶?³ñ}¶Á[jºDUò”¬ÿ#þÛgÿ«mþ"¯› ÛgVeÿøïøžººR"¯”¥"*û3­þ=JfÍ_uºÔ©÷ãS¸¯‚>mÌs¿}Îfß>7ÔRQWÊͶ¶Ïß‹í³ñêÛÕtœUö:önwZ›£Ýf)”º¿ö^ËRÿmƒú°ºlÆþ¾{ÎVÇcî°iep3º1HéÉ|ÿd2RPÏËÃ7oÛuªÎu}e“qX¿þù êHB6GHß²B[Ù·ù³}«–”ÃH@a?d‘Ü¢¸×�£$oGÄÞŒòJ+å Ö@€Ä°2cy-°f’ТÑà HÌ’ŠOÈÿoòÚÂQ7w䢒咑‰I IY#xBù4–S—‹~ù!¬žw¾!'ãÄ«b ­_Ý!†d/—ÀnQà ^+Æ$ 3Ò5(ä¤2JOO,%’çÔ�ÙÜ”J Oû9›ö% rRKݧ—Ý%–ãxÝ/ïBA|‡¸Ix˜ŽŸ’‰H&· °b3m†?Ù<nt8Ïûß=(0 Äd²6Ûm³óú¶ÏÖÚÓð#—Ïþ•_ö�A&$05!ˆø½ùdÇN )(å±\nGmú[%Òêµ€I¡œ¦A3î’¸Bv&ÂKýP”NJ7îΜz/„×ô>Nÿ²E³ffÝ ð÷w~}ÖK;p©«þªL8 ’MÉI}ú„í‹ÁŽ”ô’ƒ]*ýñA™øk½òì^éß%¿nnÝŸ3îg=öùö{ÝP‰¥ü€Ìœ7—ŠmÆ¡¨¤þØ7ä§oöÛ¦ö¼a€Q‰¥¡©J22qcKFå/º@mß²_b½ŠÓ±­€çWüDaÏÿoþ[êìÛí»gs·=uH„MA ¬Z>ûì¼ìí¿oòŽv=÷o¾¹·±ÕgWÊR•Å_+ùY›¿uº™L%ûª®‘|¥+7ÉÛï¾ù÷Ëßswˆ«ë¥)WٰͶuf_ÿ‡þÿ‰ë«¥"*ùYþÍ¿Ùûa}¿l=[ñ®‘|¬eîµoì¶0îr¹øÃêéWÊR‘|¥)WÊVnîz»ñ›©Ï<ü§U7;-MÏQî£TËT¢¯®”¤â¯”¥"*ùJÍÜÏ—Ïc9êüóñ¬}\E_+?f=}ŽüÏÖÇSª®‘}ÿý÷0ï²?ïþÛ¨í–êûkë�UÐ r9l€ÒQ@e9$¾„ã€ÂR Aid§3%;¿¾N_Ù ý$¬ÝÒ …½ò^kêÀ;GA47¤ay)‹,`ÀÄ$˜Ê,¼„$3d¥’éBB?½æ¡¾"õÕý‚94¶ Ť4††“öùÊû,°Ç[¡8 ot|ÞâàÄà†ô>?þ‚ß%)G@a5”‰y’¾/§§¥÷¼¹4²¹x°•ò7,®‡)_:R3t# 4hÜ7eìÃ}ô´¤ âða| ×Ý ,…ÓÑ‹,¤dð0ž”ì’’¯Ñ“ù'¶¼Üß6øÅ]_ò roF%”÷H@Ô%ÓÜ$3£Œë é ¼õ¼˜ŽQHCm¶FÈÏÆl˜oZ[ºÛ(Ëïö²«å)KYUòô T˜K/'nù ol”>Gûb’Z?@ÜZ:Ýl«ÍRÏN¯û0 †€À°1Ê è ã ]? ß2W,~¢ö+tbÔ”¾í|>úHðÌœ‚ÒÜ rZ6FJxc�Sº r•™9=NÈmϼ€ K&#í†3׆••“ÑÊ(cŽÙ˜î× Žºªþ-+ò_«vZþfû³7n³>Íöw:LëR™³c×Ýnµ*ôh«ë¥)8«å)HоR”ˆ«åb߯3fÌ·[­Ä6eUÒ"¯”¥"*ùJR"¯”¥"*ùJR"¯³;gûö_Ù·â³öþŸ>ûŸ™ð¼ûà½õ]%|¥)8«å)HоR”ˆ«å)HŠ¿xjP„'¥ò ؾÇ?äŽ5L¼Í÷e®úß &’à œ0„Ž€ K , !ºSûl“†b‰yݳ_:A+dì^|”†·/#ål3ãzÛöíïB¢€3ƒFXÄp݉]!)$—ýú?&¥)û%(ûyYß2ÌÊXàêêýÄÀÀÒV§¹nÌZ: ã - ~—èì4¬Zø×䋚 -(ÈèáƒP’·+# ¤d'ý‹/$”†³’Æ+}gt†”0›ÃSþßòŠ-¤ô[£r·ã3dwO%ä:2d&Óñ`còRIY))%¥)/á%$ä O/%÷éw{$ý¸⇠ÕþL¢‰HÈ”¶ÙÒß«l¿¶wgÿ­ÿ²R—³gWÊR“оR”ˆ«ý`(å@Ô!eŒOFÙ OÇ$fÿäô—²TýW¥�»–i4 –ÓƒF'?åvGÈÌvÿ'¶ÄŒIy  Y(¾¡‰ËVøylQû|5; Èëûoz ³å 03%%t'ºòú>&`‘ÈC„ï²Qïqì`å¬M¥_ó*V2ÿ~vR›³f­”ª»Ø³«å)HоR”ˆ«å+>v=]ÏøÏ–ÇžwS®Ž¿›–¦ç¨÷QªeªQW×Y¾ï·Ý»q]·n9_q®“оVg[ìz–Ëu-UuÌû/N³q‡s8ùE_])IÅ_)JÍ÷}¾íÛŠí»qÊûˆñ}t¥"*ùJR"¯•Ÿ°óöVüþÆùÛ/ÕÒ"¯•Û¶ß²·í¿Û°–õuŸ°óöVüþÆùÛ/Ê*úéJñŒÃgÿæ=ßöo›ô÷ýn±ñ}¥'Ñ@¥ºSò A» ‘…—Æ|„ŽŒßdà”ãݺí„Âú „ÂÒø  ­Š(´ä¤¡…#ô ³:K�£!;dþ𥟆'£òvèùבÊNH×o“Û6û=ô§$ÔþK!,aA‘°Ý› ²PÄdâº?%FwtÞ*Û`þÄ~»J¿KÁ„ÒSøÀ1Ý)AY;>,´öGK`Á¼oéHÎ3ï4VBIh.^ÙƒzX”WÛ/äôvý9ä§§Y×¥¡¼²‚òJı¥%(䤥(Nû¿ANW @Äýû–¾{›¥=n­Ük)jÝF¯áªÝ”Ê�iUôR”½:*ùJR"¯”¥Ò&Ê!0ß³ó~Ê}ºÿm³çÿŸöËûRϬ�~@éÈ/!ÿBxFG߆§wûïú É-M¶w°€™Rz?&¥ÒXÖ BK%¯¥ Á¥=»+ômïnXxÔ“ ª,g ÉÅ ˜œYE Iy-ºMI+ágøËäᄉˆÈ+ Ûm¶ý¶Îc³÷ïÏæûËgäóxµ¥_‚•›Ûç^uï¸~íðŽº»Ö³«ìÛ![l¿Ô¥þÿ‡õñut¤E_+?Èßÿ¶ÙÿêÛc«¬î¦øõ©ß79y–ËZ¥}v¿ÑÊÿþ„t?ýÊû1ÿ«¡°¬•›îû}Û·Ûvã•÷å}t¥*оR”ˆ«å)HоR•™Û?ß²þÍ¿Ÿ°‡ñ{ô²Q›÷uì­±¿œ;lÛÔR’оR”œUò”¤E_c/õ¯le9‡c×ÏæWJDUò³l¶Ûm›l­¶3jºDUò”¬lÿ¶¶üß³¶qOØLE_]í�¨H B1H IIG(´· È VÊK¥ÕÙ.Ï—y.‡ëý”­Ù¾îÝû}™¢pÜßdîù;Žû˜ßw9»*ÇyÕÿ¢@ ©Èü™ù ¡9¾(´ô'ôdp„ý¶A+!™##·¾.† é/d b@ÂrRÿéIJËu,jÆ«?ö€€˜0²’–HÝÉy(t–øòVý†üŽc!‰¯}ƒ &r‹¤ Àž[•ö/%)Ø¥<éÁ›ìòî[¥µãº·"18åÚUÿ¥õäÔâ·&dþÊÁ¬_Üg͹HBRJN-#‘²Ò1ZòÈ _§È ý Éý Cß nì7`äýþ]éôQWùz^ �ü™†‚ºpÌ€2ŽS°ß÷Êï†}ÒgÊÝ-îñ èb^Gù;£ FéÅ ¿ö o·J6döÝ¥~ï1œqDUþ °Ô77OB9cŸ¶'?9üíØï}$`”Äbi) á¥|²j>ÌÅ«—~‚Ðß8cýߢé�Üš‰i+ä€ßl’P@`À,žV¿-’Ð…wÝ9¶¼™„0„„”‚Pœ’Ïn’Æ•úRJFJwVß’Ÿm޼öZ»¨ð6êU^€0‡&Ù\1+I5³#ÉIûdòú~Ì”Ÿ x´!#!¶=ÿ×ÿëÿ¯õúÀ°aH+;ŒŒç¶ÌºŽêmZÙ³s•Ýl¥*ôú_þ@¢¯®”¬ÝÜõv;ã7SžyùN«¢U{äï‘Ð’nûægÜõî)Ï&Ìoëç±¼ålqØÖ>®’оR”œUò•Œ¿Ö½±ý”æ_?šu>ÉWÛ¯u­{¾áÝx\¢¯™Öÿ¥3fǯºÝjU])8«å)HоVo»í÷nÜWmÛŽWÜG«¤E_)JÍ›mÿíìü_m°VÚ"¯®”¤E_fîgË籜õ~yøÖ>®•Ÿ±Ÿ¯Æó×ñÇóXéE_])Y°Í¶uf_ÿ‡þÿ‰ëœUõװܱîÇåwG^ËVâ¹Þ¢’оR±³îÙöûsvìùŶqÜnß:ó¯}Ã÷o„uÄUówsÕØïŒÝNyçå:ªéIÅ_)JDUöwS|zÔ¼Ëe­Vä“2YÒ–ÉÉïŸ'§/ᤖìí†m”ûÜÚRñWú Š!¸ÖϲöÎãQût'rQYº:³îò@0(j fà ã>Åb†íÓÐJWOê æî‹Â}“¾û}ó}×¾æ}Wc“ðð¹ÕÿB�6 FèÉĬ�ÁHO 3¬aiľ’ú~ä¶Ût÷íd �¸¤7-<²Ûa­³mó`ÍÆðÌx>nžÌÈkÄR Âó«÷ ˜„`ÂNfã[súTߥ}#ÿö R馯•Ôßµ;æç/2ÙkU]*оVo“·ß}óï—¾æï:Y_º¾fRö?,Õc̨”Uò”¤â¯”¥c/wçu)¹Ë9ÔbÙkˆ«çÙ;ï·ß7Ý{îgÕu‹|¬ÍߺÝL¦ýÕW(«å)IÅ_)JDUò”¬ØfÛ:³/ÿÃÿÄõÄUõÒ”ˆ«ågÎ<ýÕþ;¹„üwÊõtˆ«å)HоVm³ý¶~ü_mŸVØF«¬îݶý•¿mø¾Ý„·”UõÒ•Ÿ ßw^e¸wÍðœ¹Å_])HоR•Ôßµ;æç/2ÙkTE_ùY›¿uº™L%ûª®”ˆ«å+?íŸí¿7ìíœSöWWÊÏ—óqKWW|¦ïªéWÊR‘|¥)WÊR‘}޽–½ùÝ”ÆV?˜u]c/wçu)¹Ë9ÔbÙk«”Uò•›îû}Û·Ûvã•÷êç|¥)WÙóï·ùñùŸ Ͼ ßNÿvøþÙŸ˜ïÔÈ7Ç-ûTRQWÊR“оR”ˆ«å)HоR•Û¶ß²·í¿Û°–ñ}t¥"*ùY³:ÿ~)JÊ̓Öýý;·o·eŸn/>qªå|¥)8«å)HоR•ÌÛ¯ÙN³9‡cx芾ºR‘|¥+3›¶_;ºFcÆqñ}t¥"*ùJV}“¾û}ó}×¾æ}W×^’Ðûîîß›ïß»Žù]ê)(«å+;™ö^?:fãæqõsоR”ˆ«å)HоR³:ßãÔ¦lØõ÷[­J«ˆ«å)HоR”ˆ«å)HоR•›d+m—ú”¿ßðþ¾."¯~5öÂ_çÙ¾|Ï»üí׳,w¨¥%|¥)8«ìeîüî¥79g:Œ[-tîݶý•¿mø¾Ý„·«¤¢¯•ŸŒß÷VuoøvÏøŒººÍ²¶ËýJ_ïø_W×JVglûnËÛ¾ÜWlâ[N*úéJDUò”¤E_)JDUöm³ý¶~ü_mŸVØF«¬ønûºó+ýþo„åÓq»|ëν÷ݾ×(«ë¥)8«å)HоV-úó6lËuºÜCfU]"*ùJR"¯¿§²B?c°@JKaA,±U¤¢¯”¥'}޽›Ö¦Ç(÷YŠe.®”ˆ«å+6ÈÛm¶Ù¶ÊÛc6«ˆ«å)HоR”ˆ€���ˆ����z¿àŒß÷Vuoú‡lÿˆË«¥"*ùJÇ_ÍÎËSwuê5LµUÄUò³º›cÖ¶lÜåw[)J]]"*ùJV}“¾û}ó}×¾æ}W×JR"¯³fÛûcû?Ûl±[jºR"¯•Ÿ9¿/Æs—¹çsXê~ÃÏÙ[óûáüí—黹êìwÆn§<óòRоºVlÛoÿlgâûm–+mW8«å+Æm™ ul=ùûà•¹«æÔJ*ùJRqWØ·ÊÌÝû­ÔÊa/ÝUt¤E_)JDUò”¤E_)XÙ÷lû}¹»v|âÛ8ЏоR”ˆ«å)HоR³wu|ÜRÕ—›ñ nú®"¯•›¹Ÿ/žÆsÕùçãXúºDUò”¤E_)Jž^fï™n¦[‰|ˈ«ë¥+>ݿ۷|+·Ï‡+ü#ÄUõÒ•ãvFévR~WêÙ_ç~ÊýùÒŠ¾ŠR³º›ãÖ§|Üåæ[-jT⯮•éKteö_nwá—Ôr”üʉE_)JN*ùJR"¯•ŸvÏ·Û›·gÎ-³ˆ«¤E_+7wWÍÅ-Yy¿¶ïªéWÊR‘|¬eþüì¥6gYγVÊU]"*ùJR"¯”¬uüÜìµ7wQî£TËU\E_)JDUö:þnvZ›»¨÷Qªeª®”ˆ«ìî¦øõ©ß79y–ËZ•G_ËVÜîËsNç/>®’оR”œUò”¤E_)JDUò”¤E_)Y¶FÛm¶Í¶VÛµ\E_)Y³úùìo9[v5«ˆ«ågì<ý•¿?±ŽÎÙ~®‘|¥+7ÉÛï¾ù÷Ëßswˆ«ë¥)WÙ»º¾n)jËÍø…·}WJDUò³üÿûmŸþ­¶7úºDUò³wsÕØïŒÝNyçå:ªéWÊÍßo÷ÏŽìøWoò…ªë6ÈÛm¶Ù¶ÊÛc6”UõÒ”œUò”¤E_)JDUò•Œ½ßÔ¦îË9ÔbÙk«ˆ«å)HоR”ˆ«å)HоR”ˆ«å)Hоž^fï™n¦[‰|Ë«¥fù;}÷ß>ù{înòо|ì¿›ŠZº»î%MßS;gÛv^Ýöâ»gÚ®‘|¥+7Ýöû·n+¶íÇ+î#Î*úéJDUönŠZ²ó~!mßUÒ‘}™Öÿ¥3fǯºÝjRªéHоVo’½÷_ÊZ÷oƒº¸ººDUò³;gÛv^Ýöâ»gÚ®‘|¬ý·û~ØìÏÅgû,_Ú®³»vÛöVý·âûvÞQW×JVo“·ß}óï—¾æï8«ë¬ùÙ7µuwÜJ›¾«¤E_)Yó²þn)jê︕7}WWÊR‘|¥)WÊR‘|¬ý™_¿¥u÷øBŸ¿«¤E_fÙm¶Û6Ù[lfÕuŒ¿Ö½±ý”æ_?šu\¢¯”¥'}Ÿ¶ÿoÛ™ø¬ÿe‹ûUÒ‘|¬ý™_¿¥u÷øBŸ¿«¤E_fÌ篹ÿ™²œãŽÊuÕÖwnÛ~Êß¶ü_nÂ[ÕÊ*ùJRqWÊÇ_ËVÜîËsNç/>®‘|¥+;·m¿eoÛ~/·a-â*ùó›òñÌg9{žw5Ž«¥"*ùJR"¯³çßoóãó>Ÿ|¡{êºW”œZ7Áù÷o•÷oóî®ß¯J*ú)JN*ùJÎæ}—ΧY¸üw3­t[åænù–êe¸—̹E_])IÅ_)JDUò”¤E_c/u«|e±‡s•ÏÆWY³ýû/ìÛñYûW(«ïù?æKc[/¯sûægÝNµ|Õ¤E_)tÃKmÑ“ÊJs#Œé K·Ù™?7ÿ³öÕi FéFNBvG ÊĿЃsºs6ï銿/Rƒ1+AEô§ŠB– JI Û²vvcî)þß~ŽŒ—Ð4çÙþsß©–tšu~JR–’«å)HоV|ûíþ|~gÂóï”/}WHоR•ŸäoÿÛlÿõm±¿ÄUõÒ³fs×ÜÿÌÙNqÇe:éo±ê[¾lz³-Ôµ.QW×JÌæý×Î̧Q¼ì7­UsоVo“·ß}óï—¾æïWHоÍÝÏWc¾3u9矔ꫥ"*ùJÎæm×ì§Yœìv7©Uq|¥)WØ·êÌÙ»­Öêa Ýtÿ!ì½–¥þÛõaut”Uò”¤â¯³}ßo»vâ»nÜr¾â=]fî竱ߺœóÏÊuUÊ*û?È_û/e©¶ÁýX]])8«åz“‡|ÏŸ~öíÛüíñµ”Uò³fs×ÜÿÌÙNqÇe:êé8«å)Hо]`Ò>5›¤ˆý†õ6Û¯¿Á?8Ëx I£JàeŠÉO+4µ ^-?‚@"põ=örfÙä#b’Ô¹C9A…ã:z ,c–€Œ&²f úãËX *«üÊR©i-(ø0;� ®–G )<–„•’’òt·RP§FºÅ€dCÿô†’ˆÉÝò•ÐŽ”Ò‘œ™¸Â¶/ŒÇëçà’ :R8èBR„üŒ[í² í¶JøOÿ·ûd=ãVÈ+|€-³2o³eŒWûgVíaþ1j_ö¤€dYa˜i7rb]ùY†qˆAYJ9a¥9HFbÜ5Ñö|þ°4¬‚Q@7éÜ1 B IøÐ/†!‘Ý( Hc|IùH×Á«6ÙþÛ?~/¶ÏÇ«l#Zï*¿ô `²ÈA™<3w+a¨ÉÛüRq[ä£#5C†IEü®×̉€ 4•÷r†q½,K|J0§GO%”ÈC¿OÊèopƒ@LL NJw|žZ“öé%œõ}¶ó}óî}íC@4!C‰…ò€PKÉåÙ%$ ,´fHoéø#;Ø·�æuË)}ˆÄ4“9I/ö!•‹o¹47÷,½ƒ”âQM–‹á"ïüì¿›ŠZº»î%Mß]ÔÕõÒ”¶•_)JDUöm­¶_êRÿÃúøººR"¯¼¤ FÊsøÌÛþ¿Ùû?~QJJ*ùJRqWÊR‘|¯t¹Ùœ÷îÌ{ <j™Î[™&v϶콻íÅvÎ%µ\¢¯³¹Ÿeãó©Ön?Ìë]]+7ÉÛï¾ù÷Ëßswˆ«ë¥+>íŸo·7nÏœ[g8«ë¥)WÊVw3ì¼~u:ÍÇã¹k«ˆ«å)HоR”ˆ«å)HоWþ“É&í³sŽ~–ÿ÷Z²Ãê/JM!–RSZR3ì„!%•ƒre#ò]†’^‰Õþ˜‡ÿ/p†“QùDÜW@b{”®žIÅ'`ŽpÎ1INkÑbI`À3ÓÐQ4²Ð2Y0´¶&àÀÇéƒù#_¾j²E�Ä ¤''‚H/% á)Î÷Ü0¶I}þš°N‚Æ“QË,´ä‚›ôô€ßrÒKA(¼Èå:‰h«Æý°ì¦s‚««þ`LBJÙº‘úvî·-,”ô»¸Ã÷Þä×£6¶ýºYkmmùÌÿej‹Úöu|¥)TUò”¤E_ö €aÈHàT˜P`ÄÑ¥}ÂJ,–ëG(„«m¾ÊÛ^D�;!–’èß#%+JKù=ŠÉÁ=ÒÈOãvK½ãƒJ(è·ßu#¾ûæù(N5Î?-J¾ÄMH`¥$nÜ®‚`fÀd¢’»¸küá‰îM|Æ#+¾¼Ì쮯ø•c¯æçe©»ºu¦Z­x¾XϳnãI¾W)òTœ“Ønøu“f7õóØÞr¶8ìkz4UõÒ±³þÙþÛó~ÎÙÅ?a5uE_)Y³í»/nûq]³‰mWWÊR‘|¥bß+3wî·S)„¿uUÄUò”¤E_)JDUò•™Íû¯™N£yØþoZªâ*û>¾î¼ÊÿuŽù¾—WYó²þn)jê︕7}W(«åbß«3fî·[©„7uÕÒqWÊÏ·oöíß íóáÊÿõtˆ«åc/÷çe)³:Îuš¶RªéWÊR‘|¥)WÙû?eoÏìc‡ó¶_¾ª¨,3¡(,458¢’¼VG&Ëü –‚‘Ætó°Ô}ò6ï|µ=; oîkl¯óõöu+~³¯bXkâ·ø5(Ix¤£q˜ÝØcŒNRzC NN=‚ª«ýX˜°ÄâÊè% tðÄ1IÅfäÞRRq1Û#³oñelîg,3–rÛ`‚YDÒÑÃQŠHÔrøÒØ7¤”Œœwù®Ö‰I(`ü´$›ˆy.XД„wFÙúЂŠOC¡ýï�ÌLÊü›ÃRý?% Ž’û%£ô7á¨ÇÜ|8C€sU_ãöÈVÛ/õ)¿áý|]]){u|¥)WÊR‘|¾žY«tn”£â±IWÙÉxn‹|„†%8š•>NɾiþFÿý¶ÏÿVÛýï�ªM-%ô> ’ÈBKßd#¤b\1;ìMOGSa¿oµËŒª¯ä�dM(šLܯ‰Hã ÌÝÛ2ËìçìÍýå¯Jwü›Ã? AMþ ýáéÙíÔ—BÞóV‰•_)Y³?õÿÏîk‡c¶V«¶•_c/wçu)»²Îu¶ZêéYó›òñÌg9{žw5Ž”UõÒ”œUò³w3åóØÎz¿<ükMòW¾ëùK^íðwWW(«ìùÇŸº¿Çw1ƒñß+Ó¹›uãû)Ög;êU]"*û7·Î¼ëßuݾ×WJN*ùJV‘¿ÿm³ÿÕ¶ÆÿW×JR"¯”¬îfÝxþÊu™ÎÇcz•WWÊV-òó7|Ëu2ÜKæ]\E_)JDUò”¤E_+­{cû)Ì;¾4êºDU÷—¿GØÕpž…sþù{ì¼Ì³q÷± % š†Ýa¹[ñ¥“=,”€ 4·èA)ó5ä’¿‘ÊéÏ»„6ùþíû«ìaÿ1­{À*¸i <bPÃ_-ËGAå’øÍ‰|¡£Jé|…ô².L誯¤"o!ü5)Ü®‡-”Ñ¿+'›dn”äâòœÛ#õÜt¥Â?œŒÒ—BrzÒ»ºPœýcv;ßGÝ�;àUñe¤½ÃQ™%d“:RVû$¤»J-Ñ‚z dt£½ó@ΞŽMؤ÷ÈlVNo¿Gü²Ü ä Œ·Ý/·¹Õ°�öuš¥)ztUò”¤E_)JDUòúð$¢û¤¬žœÌ’`n/†’Ã1`¡(È-þeö¾vM!’™Ð’†¾êByûžœè(fîZŒ÷ÐÃ�~´âi01b¹y=ri)¹@e$¼2xbUû÷¸1ǃ u‹1L‡éIm²Sòs'dþQ -óÿÛ¥ B2¯-u€¡Y#ŒÙ)ΖÉËOé䆥?nsrn¯M_fu¿Ç©LÙ±ëî·Z”ªºRÖU|¥gví·ì­ûoÅöì%½\E_)JDUò•Û·Û²¿Ï·Ÿ8‡Ôû%_n½Öµîû‡uárоºVwSlzÖÍ›œ®ëe)K«œUò¼’ß›÷ÌÎÏ›Îνó;eµE%|¥)8«å)HоR”ˆ«å+>Éß}¾ù¾ëßs>«ˆ«å)Hоô¥Œÿ·ûl{2Ÿ²7î­þpé3­ö=KwÍVeº–¥ÕÒQWÊR³»vÛöVý·âûvÞqW×o,˜‚þéýGmØgd£ýÐÉ“ñêWÍì”Uÿs‰0°% RRãrXfB ˜5(ÈÈ!b, fÝ#z9ÈÙw(@ä¹i,1à ù)d é |‚Ò“ؤ¤½ËéBZù€h`GÎßï—†£îÏ’Ž¤îÍÍoÛç¾Ä€ äÒЀ0K`ω‰AE|Ž05¯ö%”îë).ßîy.vb…›iWüUñù+N|r¿Ì^;‹ÝZ¢ûP �5&ÿ‰„4à2òQÒ4­Ævå¸BF ”0”„+ð.íï— a…¾ß€ãìßô•ò’„gOZ™†¹‹×wÔUüZZÒœPJSöcpBÓû)GôöVeÕäî‘‹u䲘Öcq£Ç{yUôZ HÄ~Ý"‘ŸÿÕ¶0?ý±ÿíwC@BÛüHONÅ}ÑÒ„òóä!-Ñ¿Ïþí¾×½à;àWàÂßäýÈdÄ”’Ë GÉã1H!Ä€ý còýÎÕUõ€Å ¤§·É,¤$¤|žŒ@ÉAD°ÞÁ¡!¹³7ÍÛ}y’žXϑҀΌÙý’€ÉlVûrFm¾$k®b|'·)? B{r‹ K Ãƒ2_`ÂÆr™xý|ý §Œ¿§¶Ùÿ?ö?ó}á`5 ^›dm¶ÛlÛem±›UÒ—¡E_)JDUölÆþ¾{ÎVÇcêéHоVnŠZ²ó~!mßUÖ~Æ~¼sÏ_ÇÍc¥||û>¿Øß³?aOœM])8«å+6c_=ç+cŽÆ±õq|¥)WÊͶ¶Ïß‹í³ñêÛÕtˆ«ìùÇŸº¿Çw1ƒñß+ÕÒ‘|¬ÿ#þÛgÿ«mþ®‘}á?»‹Ngú¸ö¨¥%}ã†6ÏÿÌ{¿ìß7éïúÝcê+ùY›¿uº™L%ûª®"¯”¬|û>¿Øß³?aOœM\⯕øbX¼ÝA ÍÕÛ«Ží¸¶Õ”Uò³ößíûc³?Ÿì±jºN*ùk,1ªKüÍóý¾}ÛíÛœiŽþÉIE_ôt€\QiŽM&pÄ(´œ¢ÿå ¤`,„2”É|¼Çݼ�ûä Nà_­)?t£’Ëã1+Ë@f-·÷í|v³¹Ÿeãó©Ön?Ìë]Ê4}UÚP`¤±¼¬Å%%¥§§—ÒRƒ1|%,…žœÙ†qâL�ȇÒÀÒöä¼»¤°ÄíÆðÎQ|¢Ë@Ôäÿùhßüù?½ñRø�Ñ�ø¤'' ¬4`$|”d,¬PÅ7-$nFýlʸ„ `Ìý±iGÅâºr3°þ’¶Ûl3£6ÊVkÍ:þZ¶çv[šw9xüiô|ÿ>}·øÝ»·amØE¨Ð9*½ÙŸ£gÿ~c¿ÿnÿ#({lú¢”·•_fÌoëç±¼ålqØÖ>wHÖl1~5ÜიѡÕühÓ>PýñïÍÝÕ™L¾üéE_E+>s~^9Œç/sÎæ±ÕuE_gù ÿeìµ/öØ?« «¥gÎ<ýÕþ;¹ŒŽù^QW×JRqWÙû2¿~)Jëïð…?WJDUö|ûíþ|~gÂóï”/}WYðÝ÷uæWû¬wÍ𜺹E_)JÍ™×ûñJVVm„­ûùÅ_?açì­ùýŒpþvËõt¤E_+öù)Û¸ßÖwÍÕ³lw_ýCê)(«å)IÅ_)^¬Î¥çZ³öç-ÔýFÓôçäœÊFÁ?çuôìµlìÆùE_E+;·o·eŸn/>qªç|¥)WÊV2ÿ~vR›3¬çY«e*®"¯”¥"*û>¾î¼ÊÿuŽù¾—WYoñêS6lzû­Ö¥*®QWÊR“оR”ˆ«å)Y°Í¶uf_ÿ¨ïøž¸Š¾ºR‘|¥)WÊVwSlzÖÍ›œ®ëe)K«ˆ«å)Yó?uŽîcã¾Wˆ«ë¬ÎnÙ|îêuÇã:—WHŠ¾Í›mÿíìü_m²ÅmªéHоR”ˆ«å)Yû1ëìwæ~¶8ãúQ{¡8¼ùÌ= Aûs“·4;¨ýQJJ*ùJRqWØ·ÊÌÝû­ÔÊa/ÝUt¤E_)Yû?eoÏìc‡ó¶_«ˆ«ìÙ¿¥efØJß¿«¥"*ùJR"¯³wsÕØïŒÝNyçå:ªéHоR”ˆ«å)HоVo’½÷_ÊZ÷oƒº¸ººDUöm³ý¶~ü_mŸVØF«¥fîêù¸¥«/7âÝô¢¯®³ñ›þêέÿPíŸñutœUò”¤E_+>s~^9Œç/sÎæ±Õtˆ«å)HоVl3mY—ÿêûþ'®®‘|¥Ì—Û?lžwlÿÝ¿;üõоR”œUò”¤E_)JDUò³q»|ëν÷XýÛáutˆ«å)HоR”ˆ«å)HоR±oÕ™³w[­Ôºêâ*ùJR"¯”¥"*ùX·êÌÙ»­Öêa Ýutˆ«å)Yó±êîÆ|¶<óºq|î¦øõ©ß79y–ËZ•WJñ›f@BÝ[~~ø%njù²Š¾ŠR“оR³wËߨÖç|½F_ë^ØþÊsǯŸÍ:QW×Yû2¿~)Jëïð…?G_ËVÜîËsNç/>®"¯”¬ß'o¾ûçß/}ÍÞ®qWÊR‘}ÌÛ¯ÙN³9ØìoRªë>}öÿ>?3áy÷Ï…ïªâ*ù^žœr·ùû!ó6ý8üŽw¨¤¢¯”¥'���È����z¿óý)HоÇ^ÍÎëSc”{¬Å2—M™×ûñJVVl·ïêé(«å)IÅ_fÙ Ûeþ¥/÷ü?¯‹«¥"*ùJϲUöëÝk^ï¸w^E¾VfïÝn¦S ~ê”UõÒ”œUò”¤E_)JDUò”¬eîüî¥79g:Œ[-q}t¥"*ùJR"¯”¥"*ûÿߌÉo›ögg7}Ô–ø-—NÈÉJÇòJNÆeóF_1ýE%|¥)8«å)HоR”ˆ«å)HоR”ˆ«å+Ò¬¿›î®Næ}ò–'7oQ(«ï Èÿ„üÿdfqÙ}”ÿíúÕQJÌëR™³c×Ýnµ)Q|[åænù–êe¸—̺ºRqWÊR‘|¥fï·ûçÇv|+·ùB¿Õq|¬[õælÙ–ëu¸†ÌªºÏò7ÿí¶ú¶Øßå}t¬îݶý•¿mø¾Ý„·«œUò”¤E_)YûúñÌo=5Ž«ˆ«å)HоÌë}RÝócÕ™n¥©ut¤E_+7·Î¼ëßpýÛáuuŸd«í׺ֽßpî¼.QW×JRqWÊR‘|¥)WÊÆ_ë^ØþÊsǯŸÍ:®‘}޽–½ùÝ”ÆV?˜u])WÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÙ¾J÷Ý)kݾêâêéHоR”ˆ«ìÿfßìý°¾ß¶­øWJÏŸ}¿ÏÌø^}ò…ï¥}uÔÛµ³fç+ºÙJRêé8«åc/wçu)¹Ë9ÔbÙk«¤E_)^JC»?wζì1Nr‡1ü}D¢¯”¥'|¬ùÙ7µuwÁênú®‘|¥)WÊR‘}ŸäoÿÛlÿõm±¿Ñײ׿;²˜Ó±êÇó¢ß+3wî·S)„¿uUÊ*ùJRqWÊR‘|¥)WÊR‘|¥cgݳíöæíÙó‹lâ*â*ùJR"¯”¥gìgëÇ1¼õüqüÖ:"¯®”¤E_)JÎíÛoÙ[öß‹íØKxоºR‘|¥gùÿöÛ?ý[loõq|¬Û#m¶ÛfÛ+mŒÚ®‘}ŸvÏ·Û›·gÎ-³ˆ«¥cgý³ý·æý³Š~Âe}t¥fÃ6ÙÕ™þûþ'®qW×JR"¯³|¾ûïŸ|½÷7zºR"¯”¥"*ùJR"¯”¥gvíöì¯óíÅçÎ!ôE_])_Æ Ë[vÎ~|üc·e-”âåz}»·nøWoŸWøG¦îgË籜õ~yøÖ>®‘|¬ßwÛîݸ®Û·¯¸WIÅ_)Y³:ÿ~)JÊ̓Öýý\E_fÃ6ÙÕ™þûþ'®‹|¼Íß2ÝL·ù—WIE_bß«3fî·[©„7uÕÖ‘¿ÿm³ÿÕ¶ÆÿWWÙ»?åïŽìi;òõ]-nåŒ Ã6K¶—†?s™û79kˆ«òR³¹Ÿeãó©Ön?Ìë\ûìÈé~ưÞÍ¿m¶7;f\E_E)IÅ_)Xùö|ÿ±¿f~Ÿ8š¸Š¾V‘¿ÿm³ÿÕ¶ÆÿWXëùjÛÙniÜåãñ§Ê*úéJN*ù_¸Þûï—»-{±îÙ›ï˜ñÍQIE_)JN*ùJR"¯³ç7åã˜Îr÷<îkWJÇ_ËVÜîËsNç/>QW×JþIFêÊû)¿o±ûåïØsÔDUò•Ÿ³¾Ç~gëcŽ?©Õ?-w푟þ¤l°?Ô¦ZÔlE_E+{-{ó»);¬0ê¹Å_)JDUò•ŸvÏ·Û›·gÎ-³ˆ«ˆ«å)HоV:þnvZ›ž£ÝF©–ªºDUò”¤E_c¯æçe©¹ê=Ôj™j«¥"*ùJV2÷Z·Çö[w9\üañ}t¯Ã ÈNdâJ:¹øýÅî~3ÔJ*û>ÏŸïö7ìÏØSçOömþÏÛ íûaê߈Õtˆ«å+ÓÙ³íÿÛ9¦ý³åŒÜAíê"*û7w=]ŽøÍÔçž~Sª®•Œ½Ö­ñý–ÆÎW?|E_])IÅ_)JDUò”¤E_)JDUöo“·ß}óï—¾æïWJÌæí—Îî§Q˜ü~3©rоºÏò7ÿí¶ú¶ØßéþFÿý¶ÏÿVÛýëÀ-,´’Q/æÁ¼„œ19ÎÂ[§d>í¸ÜŸ†w²`9:¿Š Ù~_‚Ø4ÿºvNfFßä§»×x 1dàp’¿)ò ø°ßѱ–”á‹èI{gûvû£Þ šL É)!Ÿ2@oÊJSˆd½ðÂÒBØgHÄ}™’’øÌŸ›Öº�©\5-�7á¥é+£biD¿“º;2PKOJjy;|yÊøSÈ–•~€ÀÐâ ,¾ð‡ÈÃ6Øš\›°f%|–GÈ–„¶G×H¤T¤a5Ó’Y(þ~I/íˆD¾†rú7¾dþ÷È€ű01 /'òÐ.7²\—Ã1o÷XÁˆû® BwBv,®±‰ÃVÿ÷þøæÌ¦Pªß:Œø€v*¿éÉ 8ŠÂ‰…†¥,0ZJÁ#sòñhdá¿Oéf†Ø� Ð(–m÷è(£_NÏÐü°2^ÏÛò—÷oÿÚðÍÂ?dq¤¾ûoótöuçJÝ›¬ëè`T rk–Pij@Ñ»üŽüfN %íÒ„g )ÿ=?Z00�ʯùÂJ-ò>ÿmúJçÃQÖñŸoQÝ»mû+~Ûñ}» o}|°Ò/�U“‹OéK'ç%öJ9A¥†£oЊۤo/£æ¼ �v�~BA£§¥(䬑›ïØõ¡Ñ· cðû³€ ¼ªÿ/JVg[üz”Í›¾ëu©J»©«ë¬[õælÙ–ëu¸†ÌªºDUò”¤E_)JDUò”¤E_)JDUò³º›ãÖ§|Üåæ[-jU]"*ùJR"¯”¥"*ùJVo»í÷nÜWmÛŽWÜGˆ«ë¬ù÷ÛüøüÏ…çß(^ú®‘|¬eîüî¥79g:Œ[-uuŸ>ûŸ™ð¼ûå ßJ*úéY»íþùñÝŸ íþP¯õ\⯔¥"*ùJR"¯ô TšRI‰ÿ$šŸ’ŒoúP+²1ý?3¯vC);¿ ¨À6Á e F)°Î„–yN7—¿JF§ä|¯ypä? JIX™·Å§9Hù(OÜ ŽXІû¥“”19wH5)è�°˜Wù í²@¿Å–„’ù]�(ü'ïúS99w’…-J<àâyƒ­*ÿJ’-MF(5%bS¿J ˆéNF&ùE÷Û ®ŒJvõó(B¶8¤fÁa‹û é1 ÿìÜ”†ÊeßSÁœ%–’ˆiAY9=)Î_ACÉ]ÂÒ„„#мúM¾,ŒØì…§¶9÷;/ŸÅþ¿?ÃÀ?Y>U}¥/VоV|7}Ýy•þáß7ÂrêéWú†M!'V/>S–îϰ`ìçf|¯ö]ôð(n Ù%†úIa©äÌS%#1IÉHÂ`j>G“±M¾Î­ï‡Þà$ ÀÐÂù7r¶ãRYXhÔ±˜ol„'¾¾Gãr/?v8BÚº¿É!9.ÉéßdîÁ ò†'fç9ÿ¬sY/|¢I®ZI¼3¾+rÝ(I,‘Š%R:7Ìœ°J]5W…Ýöÿ|øîÏ…vÿ(Wúéúš¾ºVlÆþ¾{ÎVÇcêíåWÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÊR³wsÕØïŒÝNyçå:¢*úë>v=]ÏøÏ–ÇžwS®®‘|¯ Ìë׳m—ó¿qÙNým´ŸnßíÛ¾ÛçÕþêå|¥)8«ìÙ¿¥efÁë~þ›äí÷ß|ûåï¹»ÕÒQWÊR“о[ùiÈÊç!‘–XÞ¾Á”±¬ÿlö Xi@e?Jå¡=_v|¼ìÝ–ÔÅ_õRo %â` Ë-)ÄÍÈa¥ ¤á› cr˜–ŽŸ¡²3¡®š?-<°ÂJÉH‰Œ„“?CùN^ JIL”mʲUþúæ¤å—Ë, �¤¡Ÿ ¤a¹S“{¥%üåâÿ÷Ä„­­Á€—ÒQ(hÏÃ9½º6È/%(9þN ûù%dkçÛlÎÊ<-DZ¿É€`€Ô6 áŽPc ÈmË,±®0¤mÝ:ŸõµóˤL+”Œÿ», –—û9þÎÝ*ýŽÙ¶¹·¶›:¾R”·•_)JDUòÞMÉHbP÷NèÝ j†Ÿ‰纔»%ÝËI0Ð x C6IIJ[¥<§) %í·É&¥{3”7&øfù+ßuü¥¯vø;«‹¾ÈM ,˜ŽBÅôð#¤˜‚’žœÁ¬QhÀdĶGÉ9‰yÚùI0®Ve3`Œ¼Ž‘Õ†lÙ!?ï1ÜÃEË]_ͬÝÜõv;ã7SžyùNªº^¥|¬uìÜîµ69GºÌS)utˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоR”ˆ«åcçÙóýþÆý™û |âi³í»/nûq]³‰mW(«ìùÇŸº¿Çw0ŸŽù^®”œUò”¤E_)Y»º¾n)jËÍÖÝõ>qçî¯ñÝÌ'ã¾W”UõÒ•‹|¬ÍߺÝL¦ýÕ8«ëºA¤Ä­íó¥;„'l×öÕ¾ëùÛû›ký))Êùí÷J?a(r¹Æ>ûÓÐÈ_ìƒKB1|504´d”„'ÿÛ¡(Oå$jzFmú~J®H@¥%(!€g†’ÓЄå–ŒÝ)À6ÊÊMöß_G,„œ’¹  7’Êvå€X3„”’Š)\¢Òÿî†ž‚‰ewJ Ø¿€ºQ²’œÿü´'üù5¹#ûÈI‡±ûJ¿Å”ŒRŒr6Ù[˜äm°vÚ¢”½‹:¾R”œUò”¤E_+?Èßÿ¶ÙÿêÛc«ºÀT¼øiA%,¿¶ønéÏÍèÝ©ÑWý²ƒCCKWÅ'0a47¥043rS †Žž4¿‘ú3}Íÿß2&# ­»¾}ßÿúÏ~’ûsöéÿf×Ñ€@_#Kå–M/r·%¡Ü0š„~P ¹mÙúvÃ~Pܯ|ųý·íÒË[l{oÎgû+\ˆ4à9]^Ÿ¶ÿoÛ™ø¬ÿe‹ûUÒ—£E_)JDUò±—ºÕ¾?²ØÃ¹Êçã«¬î¦øõ©ß79y–ËZ•(«çϾßçÇæ|/>ùB÷Õt¤â¯”¥"*ùJR"¯”¥bß«3fî·[©„7uÄUõÒ±—ºÕ¾?²ØÃ¹Êç㫈«å)HоV2÷~wR›œ³F-–ººDUò”¬Î·øõ)›6=}ÖëR•W×JR"¯±o—™»æ[©–â_2êë6açþ¿ùýÍ'c¶VŸä²[çÊêQ¡+ZÔÊP¹E_EzF$ %¸ÝÂ;wÊÝ\ü½¸™>s~^9Œç/sÎæ±Õq´?(›‰D¶RBvBY;ŒÌŽŽK[†$¤wã:U{²x�®@gÝÉèùD°˜–Œ3/äb›†a“|];|´ Z¡ùkû=J]îÀb’Ã7( Þ”WGÌPÔ¥ éÛ¥Šÿbÿèü5o²[Þf5««üAE’ó·ËeôuãðBS•Ý^æY/´�À44X4²ÐY_%<²†_èBÁ®Œ0jF'røÄÿOüc^�ï·JwÛb’3$²øhÞRò ͆£íÆlžs2dªÿ-K^/0OFûì’û'³!ûùŸoß)uäí÷ß|ûåï¹»ÝtÕõÒ¿§gØ'ìã7ÃVìÙmöµ×, ¡ -#>Cç /ç}ŸubÖ”l„q®£ý-1!¥“Óö% jMù [e™Ø{_JJK & ²ÊîWÁ¸1? ¤ XÐ,‚ò~ÉÍËįѾ°` K -93b²%‚hg%»04nù„oÓû6}ì!€&AoÒÿ£¿@jzRRya¹ %•ºæÝº35ç°ãTq; ®¯â�Á Áƒ@ÏGù%²BS•ÿééÿån¿·Ì¦mp«7·Î¼ëßpýÛáuw¡è«å)J⯳l¶Ûm›l­¶3jºR"¯•Û¶ß²·í¿Û°–õtˆ«ìÝÜõv;ã7SžyùNªºVwnÛ~Êß¶ü_nÂ[Ê*ù»?åïŽìi;òõ])8«åfs~ëçfS¨Þv?›ÖªºDUöo»í÷nÜWmÛŽWÜG£/wçu)¹Ë9ÔbÙk«¤¢¯”¥'|¥gìgëÇ1¼õüqüÖ:®"¯”¬ùÍùxæ3œ½Ï;šÇO¿ÿï›å©þoû/í²ö8+Ê*ôÝÇŸò÷Çv4Îùz®”œUò”¤E_)JDUò”¤E_+>Éß}¾ù¾ëßs>«¬ùÇŸº¿Çw0ŸŽù^QWúÂÀ4&Z~FA/~”¡wïŸ'“¾OÈùŠWGî»èÄÒa5(!$#2 Á¥“Ò5“ŠmÐ7lZY’XOéo|>— Õj«þ­¸( Â`a ¼LýAY%'² Ø5#ž„–ƒÍwÙwY €ì0„ƒ¤¤¥%† ÈÄ®—é NNÈ»±hÛn1ïr‘Ò„üýÂNÇ;)ÏÛüo´�دßá­òpßÒß÷Ù?íóöù”Øí¬”± 2_ö‚‹¤Ôâƒ@©Iéã +§d ’€ÝðÇÓ†bPhÄÿr@tnM™ò=%†~€Àt B@ÀÄî1%§r¿‚_nH÷È›>íŸo·7nÏœ[gW±‚O#Å_êI€ Ay¸Ä}‚›þIج„oðBxÇûlùoyjRîzjùY³úùìo9[v5«¥r«å)HоR”ˆ«å)HŠ¾ÏØyû+~c üí—êéHоR”ˆ«ågí¿ÛöÇf~+?ÙbþÕtˆ«å+?È_û/e©¶ÁýX]\E_gã7ýÕ[þ³þ#.®”ˆ«å)HоR•Ÿ9¿/Æs—¹çsX芾ºVg7l¾wu:ŒÇãñK§Û·ûvï…vùðå„yE_6c_=ç+cŽÆ±õt¤â¯”¥"*ùJR"¯”¥"*ùJR"¯¿ü‡OKm–í‘™ÿîÎ%û*MÜyÿ/|wcIÜï—©¾ï·Ý»q]·n9_q®QWÊVnîz»ñ›©Ï<ü§U\⯕Ÿä/ý—²Ô¿Û`þ¬.®‘|¥fï·ûçÇv|+·ùB¿Õq|¥)WÊR‘|¥)WÊR‘|¥fãvù×{î»|#®®"¯”¥gs>ËÇçS¬Ü~;™Ö¸Š¾ºR‘|¥fsvËçwS¨Ì~?Ôº¸Š¾R”ˆ«å)HоÌë}RÝócÕ™n¥©ut¤E_)JDUò”¬Ù¶ßþØþÏÅöÛ,VÚ"¯›»«æâ–¬¼Ü9mßUÒ‘|¥)WÊR³»vÛöVý·âûvÞ"¯®”¤E_)JDUönû¾|wg»”+ýWJDUò”¤E_)JDUò³fÛûcû?Ûl±[jºDUò”¤E_)JDUò”¤E_c¯fçu©±Ê=Öb™K«¬û%_n½Öµîû‡uáurоV2ÿ~vR›³f­”ª2÷Z·Çö[w9\üaõq|¬Û#m¶ÛfÛ+mŒÚ®“оV³oö~Ø_oÛVüF«¤E_+;·o·eŸn/>q©oñêS6lzû­Ö¥*®QWÊR³wu|ÜRÕ—›‡-»éÅ_7s>_=Œç«óÏÆ±õt¤E_+;©¶=kfÍÎWu²”¥ÕÖnŠZ²ó~£Ýô¢¯®³ì÷Ûï›î½÷3êºN*ùJR"¯”¥"*ùJR"¯”¥"*ùJVg[üz”Í›¾ëu©Jˆ«çu7Ç­Nù¹Ë̶ZÔªºV}“¾û}ó}×¾æ}(«ë¥fù;}÷ß>ù{înõsоV>Ÿ>ÛünÝÛ°¶ì"Ÿç϶ÿ·vì-»«”Uò”¤â¯•Œ½ßÔ¦ç,çQ‹e®®‘�������z¿óý)HŠ¾Ï—óqKWW}Ä©»ê-úó6lËuºÜCfU]cçùóí¿ÆíÝ» nÂ%|Ùœõ÷?ó6SœqÙNººRqWÊR‘|¬ønûºó+ýÖ;æøN]{­[ãû-Œ;œ®~0ú¹E_)JN*ùJR"¯”¬ý˜õö;ó?[qýNª¸Š¾R”ˆ«ïAhIÝm’ÝIÛ»:;|íÏÆzŠÏömþÏÛ íûaê߈ÕrоVg7l¾wu:ŒÇãñK«¬Û#m¶ÛfÛ+mŒÚ"¯®•›d+m—ú”¿ßðþ¾.®qWÊR³9¿uó³)Ôo;ÍëTE_]c/u«|e±‡s•ÏÆWHоR”ˆ«å)HоV2ÿZöÇöS˜v=|þiÕu›¾ßïŸÙð®ßå ÿJ*úéYû2¿~)Jëïð…?W8«ìÙ‡Ÿúÿç÷5ñÛ+UÒ‘|¥)WÊR‘|¥c/õ¯le9‡c×ÏæWWÊÆ_ïÎÊSfuœë5l¥UÒ"¯”¥fù;}÷ß>ù{înñ}t¥"*ùJVo»í÷nÜWmÛŽWÜGˆ«ë¥)WÊV~Ûý¿lvgâ³ý–/íWWÊR‘|¥)WÙðÝ÷uæWû¬wÍ𜺺R"¯”¥"*ùJVg[ìz–Ëu-Kˆ«ë¥+3¶}·eíßn+¶q-¢*úéYþBÿÙ{-Ký¶êÂêâ*û?fWïÅ)]}þ§ïêéHоÏò7ÿí¶ú¶Øßêë7ÉÛï¾ù÷Ëßsw«”Uò”¯èßoÝ”ÍÛ›ò[æ?î±OWÑJRqWÊR‘|¥)WÊR‘|¯NéS«ï»>JÙ¾NûæYË9¾jŠJ*û7;-MÝÔ{¨Õ2ÕWJN*û7}¿ß>;³á]¿Êþ«¥"*ùY»™òùìg=_ž~5«¤E_gÃwÝ×™_î±ß7ÂrêéHоR•›1¿¯žÆó•±ÇcXøŠ¾|æü¼sÎ^çÍcªéHоR”ˆ«ìùÙ7µuwÜJ›¾«¥gÎÇ«¹ÿòØóÎêuÊ*úéJN*ùJV~Æ~¼sÏ_ÇÍc¢*úéJDUò•›¾ßïŸÙð®ßå ÿSmŸí³÷âûlüz¶Â4¢¯®•Û·Û²¿Ï·Ÿ8‡Ô[õflÝÖëu0†î¸Š¾-úó6lËuºÜCfU>¾î¼ÊÿuŽù¾—WHоR”œUö¿ö^ËRÿmƒú°ººV:þZ¶çv[šw9xüiòоºR“оÎíÛoÙ[öß‹íØKzºR"¯”¥"*ùJR"¯”¥"*ùk5ò>WÏÛü¤ýóﳫî·G?Y)(«ìý‡Ÿ²·çö1ÃùÛ/ÕÒ“Š¾R•Ÿ9¿/Æs—¹çsX芾ºR‘|¥)WØËÝjßÙlaÜåsñ‡ÕÖo’½÷_ÊZ÷oƒº¸ºlÎzûŸù›)Î8ì§\¢¯®”¤â¯”¥"*ùJR"¯³q»|ëν÷XýÛáut¤E_)JDUò”¤E_)JDUò³íÛý»w»|ør¿Â=]"*ùJR"¯•›6ÛÿÛÙø¾ÛeŠÛUÒ"¯”¬ýŒýxæ7ž¿Ž?šÇUÄUò”¤E_)JDUò”¤E_+?ÏŸmþ7níØ[vWHоR”ˆ«å)HоR•ùÑ‘–“:ByÙ`<ÇóšQW§víöì¯óíÅçÎ!õ])8«å)HоR”ˆ«å)HоR”ˆ«ìÎoÝ|ìÊuÎÇózÕW^É—OÛ·Økç[/°º‰E_)JN*ùJR"¯”¬ß'o¾ûçß/}ÍÞ®"¯•޽–½ùÝ”ÆV?˜u]"*ùY»íþùñÝŸ íþP¯õ]yE 5J;äìÇE_E+?f=}ŽüÏÖÇSª®qWÊR³;gÛv^Ýöâ»gÚ"¯Ž½›Ö¦ÌÊ=Öb™K«¥"*ùY³:ÿ~)JÊͰ•¿WHоR³çeüÜRÕÕßq*nú®"¯”¥"*ùXËýkÛÙNaØõóù§UÒ"¯”¥gu7Ç­Nù¹Ë̶ZÔ¨Š¾ºÍ†m³«2ÿýCÿÄõÕÒ"¯”¥"*ùX·ëÌÙ³-Öëq ™UuŸ9¿/Æs—¹çsXéE_])^ZqHÿ‡gÙÿVÙþÏú³ü¿W¦î<ÿ—¾;±¬Îùzô¼ùéÛöA]ÈX—ÓÿNìøÍ†ÒÇç}zÐ @ªY?t$¤d'¡ËÅtrˆt§#bÐXã§ soL€ ± „ÞR_¡ Gî„?Ù<1uç~RR[%ܵûÎÊ�òº¿`ÀvLHo@bs¡J N+—öH Cpk…îJÏøì»ÓKØ0^ŽZCHA¼¢YY%~R4¾òPŸ†þV}Лµð¢` ÄÅþ†dNÄ„#„ fã7eíÖ}€Èa™H5 èø`Á÷Ù ÊC/ ô±äh«þÜB�z`ГzxÝúñ}.‚¿èà\3#}óböù)û#í¯ª28 !~1 IY Ñ»5)FC9MÔ7yœ�Ì[¡­²±L†ÿ'%™•þùÒ„äñ›+eÝ01[2Ѷ(±®”#t€£vÉÅgÅâþã:vÚ¯Þ*þh` Ê,3þù-Ê„§ü—d22\´7ÉB:Y†öݯ;¸Ý¾uç^û¬~íðŽ»î„Ðb_Á»ìž á‰FOíò0B¿Óº9IË B‚. �¾ pÀÜœL/¤®Ÿ’Èw3 ün³öÌ3Ìc¸«þKJÍÆíó¯:÷Ýc÷o¸®º»Ñ¢¯”¥"*ùY»º¾n)jËÍø…·}E¿^fÍ™n·[ˆlÊ«”Uò³¹›uãû)Ög;êU3­þ=JfÍ_uºÔ¥UÄUò”¤â¯”¥"*ùYÝ»mû+~Ûñ}» oWkHB ãvWưÅf~ýÏ\¢¯ÉJRqWÊR‘|¥)WÊR‘|¬ÝÝ_7µeæüBÛ¾«¤E_)JDUò”¤E_)Yóï·ùñùŸ ϾP½õ\E_zF+~Ïó-¿ø%³}ùÏñ¹ÝWµ‰a¹=8š ˆC'¤®Û¹{ðݰÎ5Ø#使I½™Ð_ÈÉ, ròC2 ’ïÂ•Žæ_D Êåò‰{ðai@Ͳqié/l„#~…§ ;†t:}ň�/ª¯÷?rƒID"’KH` ÌåäbÀnRB3ŽRPé (j¶J;ß!bŸ¡²: ÈÝ ÉÈBoËOê32þëþú��§ -=’c6Hná®^J ²0fF%¶Î„|ùË ÉÈÙ)ÍìÁXÍŽËýÿ®Å=Âù 5_E)KÓ¢¯”¥"*ûÒR ÌœùÐô|œpï·¾ÄÐZ�¯!’oBK FNII|„pÍӋΆ/'äÆm|ZÖ’²V´wCô+ü„Èüqûáß¹·_ô€�œ7^{$1Ð1)$¡ /~PÒËà¹[ ' ûå—Ù€vHX ònܳr %|_ÅËB å£á»Œ nÙH¾^L úè}Ò4®íÛ~1¾ÿï¾¶JŒÏeöiÕüšòZ ý³ ý! ™Ö5¾c]šLæý×Î̧Q¼ì7­T[åænù–êe¸—Ì»¶š¾ºR“оÏÙ•ûñJW_„)ûú>Ÿ>ÛünÝÛ°¶ì"®’оR”œUò³ì÷Ûï›î½÷3êºDUò•޽›Ö¦ÌÊ=Öb™K«ˆ«å)HоR”ˆ«å+6ÙþÛ?~/¶ÏÇ«l#Q׳sºÔÙ™GºÌS)rоºR±³îÙöûsvìùŶqо}’¯·^ëZ÷}úðººR"¯•‹|¬ÍߺÝL¦ýÕWHоR”ˆ«å)HŠ¿Þ�f0¶Bym°hB6é/ôd|Q_ /’‹K%b9%Ú÷€WP+ŠN!††å“ Á­„ä–A[±)Xa,µkÃð}„Ò¸AyÊü Ü”%ÆaªJŸ$®ZC7ßüµéŠ &† tÂKnã’„äò_ý?¥%—ŠÃ¾/î÷›8((™iWð@@¢’’ˆ}(JP‡)/2pφ¡‘ÐèHÄ!)§#{ç©‚ á…Ò÷ÀÉ}² ü¤lØíÙ;¯m‘ÆëË^‡üQWÊR—DªùJR"¯”¥"*ÿD°`*û±#’’à ÝòJm’2ýì@@MB - AD"ÐÃCøHt’ˆHÈï¾Ü–0¾œù ù¯–„—þíÊìéï¾}ц3çÝøæ]ö ‰¼7}Ê)‰¥ÿÊ&9_Ž36Jú OàY(Åu§^wâx ë«þJRôh«å)HоR”ˆ«ìuìµïÎì¦4ìz±üé³m¿ý±ýŸ‹í¶X­µ]fͶÿöÇö~/¶Ùb¶ÒоºR“оR³fëÿŸÜ×Çl­WWÊ͆m³«2ÿýCÿÄõÕÖ|ûíþ|~gÂóï”/}(«ë¥)8«å)HоVn7oy×¾ë»|#®ŸnßíÛ¾ÛçÕþé³m¿ý±ýŸ‹í¶X­´¢¯®±×³sºÔÙ™GºÌS)utœUò³»vÛöVý·âûvÞ®‘|¥+7É^û¯å-{·ÁÝ\\E_6g=}ÏüÍ”çvS®Û·Û²¿Ï·Ÿ8‡Õu›3ž¾çþfÊsŽ;)×(«þ–xé&†ðÝŠø7~‰A¹1 Ëû¡!¨ì??õˆA0 ≥îC Ù –´Ý=< Á£QønB¸Õ„ ]È8‰‰ B iØ4­¿ï“’žZlÌŸ’„ŒA)ÙW¥&XaC? ‘£~ð Æ$7—òzSËÈn’Wü3 È|yK8á•Í „À0Œ€%ÿß$¾7§:zFÿÖž•t¤ÎïrnÐ ?I1ÿÔ¯Ïøžw}¸ÒÝq½ÞâÞ—>оR”´•_)JDUò”¤E_­=ÂðÝÑþ|ã:D$ý¾ÊYÛãï§€XQ4*@Ð1¶û¹1 ÿlèI¡£€£”Vãïó^t6ûƒR‚ÿØ ½Ò0­¹},‡éOXÌœû>ô…rk¿Ü¯²Jä¤nYEþ7%ÊÁ­’¸ßûñ‘® ­U_âöm·ÿ¶?³ñ}¶Ë¶«¬ß'o¾ûçß/}Íޮ”¥'|¥{d·èo¿goñùó~ÏŽ5ºê%|¥+?c?^9ç¯ãæ±ÓоºÍÜyÿ/|wcX;òõ]"*ùJR"¯”¥c/õ¯le9‡c×ÏæW×JR"¯”¥"*ùKXi@d®‡J„ô' ß¡öIE_)JN*û6ÈVÛ/õ)¿áý|]])WÊR‘|¥)Wï Á¨ÙO¾ûôdŒø£udìíÖÜÎuöÒiH)¡Ÿ ›¿ÃX´œ°Ü 0 ÞY5% %#tïÆï|õ 1�cŠÉHj¹k(•¾ÉÝ÷ý1‚økŸqn˪¯Öñ 3¤ž [–Ù=vìΔ¬fHJ{x½˜ß×ÏcyÊØã±¬}ö’ÊàZÓƒ ,„ŸÜnA\¿†­#QÉ@aƒF ®5÷²�`�ü4¼0šØ`ÒòVN-._(i[fF^)Ÿ¹#Ù%šuÇiY¾ï·Ý»q]·n9_q®ô¨«å)Hо]0ÒiHtÑ‹èý$§¶ëÅo’“º²ûYøiHÿ†ä –‘˜ÜŒéëR±ê¾”C! ¾Z7ïùII !…gÁ¥#l—(¿ÒWÙ.3¯ 1¿û\ÛsÌ:¿Ñ–L&“PZJ,˜[ŒJRB ~ZqX gO(š„nÄ1h^î÷ȈEVÛl„äoÊݲ³l”¡ôvgÎíûûÚ�dL ”£”RJÈNÁ©à)ÉI-¿JKRzW’¿ì4“|ÆçáuUò”¥èÑWÊR³l…m²ÿR—ûþ×ÅÄUõÒ”ˆ«å)HоR•›¸óþ^øîưw;å芾ºR‘|¥)WÙþFÿý¶ÏÿVÛý])WÊVg[ìz–Ëu-K«ˆ«å)HоR”ˆ«å)HоR”ˆ«å)YœÝ²ùÝÔê3Æu."¯®”¤E_Þ €a5e씬'””·vÁ%|ÈwÊ3;­ï @ nbÆôÐSËNRQÝ(ῤ3“\–ߤäb¶ÿß!¬ùÙ7µuwÜJ›¾¹÷_÷NM,@` 3ƒI} )èIiJR”†º ¹(&q¨HÞ7%‘þk&�~M(·ø4²`Äu€Ù%±h%䥌ɂÍÛ!“óåßå#¤oÏó3­™óìvíþÿ/å{¶X …¤oÝx¼^P¾ ÿt„oò>û£²•råî _õUþÐ €?àSŠ(7–œQ)¹Ó†”û |ZwøgãSòF¹Ûz°Ð yE–‚·t FÜ`k–—I/ 7†ŒGø­Ê}“þnÛ^K�é¹iG’ðÎé,µmѾãPœ”ìW/î±›;®„ @P4°ÒÉKã6Èì‘¶cÙÇøgË E_ìv 8Ä„§ÐŸÆ‰¤´#°ÂºYT‡ß!Ðóv÷ž„Î^IJPo‘¨JF2Ic: ý#{rÎŒŸúµåJ AGls³#~1 Ø!ÈÃ…Ù.*¾R•Œ¿Ö½±ý”æ_?šuÕM_])Y»íþùñÝŸ íþP¯ôE_])Yó±êîÆ|¶<óºq|Ù¶ßþØþÏÅöÛ,VÚ®”ˆ«å)YÝ»mû+~Ûñ}» oW×X·ÊÌÝû­ÔÊa/ÝUtˆ«åfîêù¸¥«/7âÝõ]"*ùJR"¯•‹|¼Íß2ÝL·ù—W^”d³º¾ù’”/óáû¾ã¥}¥'|¥)WÊR‘|¥)WÊR‘|¥)WÊR‘|¥)WÊV:þnvZ›»¨÷Qªeª›d+m—ú”¿ßðþ¾.QW×JÇÏóçÛÛ»vÝ„UÎ*ùJR"¯³;gûö_Ù·â³öþ®”ˆ«ìeþµíì§0ìzùüÓªéXëù¹Ùjnî£ÝF©–©E_])XÙ÷lû}¹»v|âÛ8‰Å_])HŠ¾ÏŸ}¿ÏÌø^}ò…ï©ó±êîÆ|¶<óºuuÛ·Û²¿Ï·Ÿ8‡ÒоºR“оR”ˆ«åbß«3fî·[©„7uÓ:ßcÔ·|Øõf[©j]\¢¯•›3¯÷┬¬Û [÷õtœUò”¤E_+6ÈVÛ/õ)¿áý|]]"*ùJV2÷Z·Çö[w9\üañ}t¥é‡7uù–5Çî'(«è¥)8«åzÐŒy}Y™ÓÉ_`íQYöJ¾Ý{­kÝ÷ëÂå}t¬Û#m¶ÛfÛ+mŒÚ®qWÊR‘|¬Û#m¶ÛfÛ+mŒÚ®‘}›¹Ÿ/žÆsÕùçãXúºÏœyû«üws?ò½\¢¯”¥{?^ÁÑÏç3œ®¿”ê5q}¥'|¬Ù‡Ÿúÿç÷5ñÛ+Sì÷Ûï›î½÷3ê¹E_+>ݿ۷|+·Ï‡+ü#ÕÒqWÊR³¹Ÿeãó©Ön?Ìë\E_])Y»™òùìg=_ž~5ˆ«ë¥gìÊýø¥+¯¿Âýý\E_gìgëÇ1¼õüqüÖ:®³ößíûc³?Ÿì±j¹E_)Y¶FÛm¶Í¶VÛµ\⯔¥"*ùXËýùÙJlγf­”ªºDUò”¤E_yDŒ¿ÙNœßü¯Ù¶Xý›Ÿ•QJJ*û?íŸí¿7ìíœSöWJÏÙ_c¿3õ±ÇÔꈫë¥y-ß³|…«?foÛw}³£ê"*ûÆ„ŒÌ¬ýa9ú”ÇvJßmEc/÷çe)³:Îuš¶Rªâ*ùJRqWÊÍ™Ï_sÿ3e9Ç”ë†#ŒÙ×ö;Ö¿·gçöãê%|¬[õælÙ–ëu¸†ÌªºN*ùJR"¯±—ºÕ¾?²ØÃ¹Êçã£/õ¯le9‡c×ÏæWIE_gùÿöÛ?ý[loõuÔÛµ³fç+ºÙJRêâ*ùJôïú;³wç­_2¾Æº÷Âu|¬îݶý•¿mø¾Ý„·¦î竱ߺœóÏÊuUÄUò”¤â¯”¥" ���H����z¿óý)HоV¿ö^ËRÿmƒú°ººÌë}RÝócÕ™n¥©rоºR“оW„ÔÙ;«înøÁßzŠJ*ùJVglÿ~Ëû6üV~ÂÎ*ù»íþùñÝŸ íþP¯õ]gÎÇ«¹ÿòØóÎêuÕÊ*ùJRqWÊR³a›lêÌ¿ÿýÿ×W×XëÙ¹Ýjlru˜¦RêéWÊR‘|¥)WÊR‘}Ÿä/ý—²Ô¿Û`þ¬.›Ûç^uï¸~íðŽººJ*ùY»™òùìg=_ž~5«¤â¯”¥fï·ûçÇv|+·ùB¿Ñ}t¥"*û;·m¿eoÛ~/·a-êéHоR•ŸäoÿÛlÿõm±¿ÄUó»vÛöVý·âûvÞ®”ˆ«ï%£8NWÈëÊý›q}óc_Ióï·ùñùŸ ϾP½õ]%|¬üfÿº³«öÄeÕÒqWÊR‘|¥gÎoËÇ1œåîyÜÖ:®"¯”¥"*ùJR"¯³á»îë̯÷ù¾—WYÝ»}»+üûqyóˆ}W(«å)IÅ_)JDUò”¬uìµïÎì¦4ìz±üâ*úë>v_ÍÅ-]]ðz›¾¦vÏ÷쿳oÅgì!ý\¢¯”¬ß%{î¿”µîßuqusŠ¾ÏŸ}¿ÏÌø^}ò…ï©¶B¶Ù©Kýÿëâêë?açì­ùýŒ'ó¶_”Uó:ßcÔ·|Øõf[©j]]gÎoËÇ1œåîyÜÖ:®"¯”¬lÿ¶¶üß³¶qOØM\⯔¥"*ùYöíþÝ»á]¾|9_ᮑ|¥)WÊÆ_ïÎÊScÖs¬Õ²•WYoñêS6lzû­Ö¥*QW×JRqWÊR‘|¬ÎÙþý—ömø¬ý„?«¤E_+?È_û/e©¶ÁýX]]"*ùJV-ò³7~ëu2˜K÷TE_])YöJ¾Ý{­kÝ÷ëÂâ*úé^ß÷üîùŸÍÖÉ7œÇ)óÔJ*ùJRqWÊV2÷~wR›œ³F-–º¸Š¾R•Ÿ ßw^e¸wÍ𜸊¾ºR‘|¥)WÊR‘}ønÈvüõãØ$Ó?8Ù>ÉWÛ¯u­{¾áÝx]]%|¥)8«å)HŠ¾Í¶¶Ïß‹í³ñêÛÕt¤E_+{¿;©MÎYΣË]]"*ùJÇ_ËVÜîËsNç/>®"¯”¥"*ùJÍ›mÿíìü_m²Åmªâ*ùJR"¯”¥"*ùJV~̯ߊRºûðå?W×JR"¯”¬Ýöÿ|øîÏ…vÿ(Wú®"¯³íÛý»w»|ør¿Â=>Éß}¾ù¾ëßs>«¤¢¯”¥'|¥)WÊR‘|¥)WÊÏWsþ3å±çÔë§víöì¯óíÅçÎ!õ\¢¯¿o»c—ÿéÿ¿îÙÝKææm¶jl—~‘êÙ·~§wﲕöïûÕˆ«ì[õælÙ–ëu¸†ÌªºRqWØÙ÷lû}¹»v|âÛ8Šm‘¶Ûm³m•¶ÆmWXùö|ÿ±¿f~Ÿ8™E_])IÅ_+3¶¿eý›~+?aéó±êîÆ|¶<óºurоR”œUò±—û󲔨õœë5l¥UÒ"¯”¥"*ùY»íþùñÝŸ íþP¯õ?íŸí¿7ìíœSöW(«å+6açþ¿ùýÍ'c¶V«œUò”¤E_y\j7|׺û¯ÝL³O¨¯)ÆgwÊtŒ~Êp…,õ1çj‰E_+6c_=ç+cŽÆ±ôÛ#m¶ÛfÛ+mŒÚ®"¯”¥'|¯Û䧺»vZ¹Üÿó3+l·ëz¨ùN~Ÿo—»>víÏÂj%|¥)8«ì[åænù–êe¸—̺ºR"¯³:ßãÔ¦lØõ÷[­JU])WÊR½ÈÍœÃÒ”¶=?óúÏòоŠVl3mY—ÿáÿ¿âzêç}Ÿ¶ÿoÛ™ø¬ÿe‹ûQ—ºÕ¾?²ØÃ¹Êç㫤¢¯”¥'|¥)WÙóï·ùñùŸ ϾP½õ>}öÿ>?3áy÷ʾ«¤¢¯•‹~¼Í›2Ýn·Ù•WIÅ_fÌ篹ÿ™²œãŽÊuÕÒ‘|¥)WÙÜͺñý”ë3ŽÆõ*®”ˆ«å)HоR”ˆ«ìÛ![l¿Ô¥þÿ‡õñut¤E_fu¿Ç©LÙ±ëî·Z”ªºR"¯”¬Ùœõ÷?ó6SœqÙNº¸Š¾R”ˆ«ìeþüì¥6=g:Í[)Ut¤E_+7Ýöû·n+¶íÇ+î#ΟжVßö~•3l¿î³–snõŠ¾Ï²wßo¾oº÷ÜϪéIÅ_+ÆnîŸ}¾Í™™”gηïQIE_)JÆ^ëVøþËcç+ŸŒ>qW×JR"¯”¥"*û?f=}ŽüÏÖÇSªÛ·Û²¿Ï·Ÿ8‡ÖâyA(ßýómп§l‡-['«šÝKkè�1 ¾ B +ïº8Ô” Á¡œbQÐP Æò¹/öådðÕ*çÚuš,2`gN/íóœ”7ãFda½Çö%#ïºUïnxÔá„ÜPG-±|„¬“¸… nǹa,…öÖÌp*ŒœL)Œíú:�±IF(3!9É…¯q¿¡ƒB3:}À(älVeà$´á¿ìãJá¨l¶C‚7)—ydóÖAÆzêôàʆ:6Ä®Y(j~ÿîp¾åt3ÿ³$ ¶°�3߀¥Ð’Q3$0gÉAiÙÕúQ÷AY<¿·uP €]ˆôŠü¾_KÒãÀo–W~…6VÙîj@4(´t§–ò~dÒI잊t Hݙƿÿ½Ñ”�7•_€˜ÂnÜiYÎÃpÖq‹Ç�åѺ:QÔß½Á¾ÂP�6 á¤ÌCÜšR„ån´­%Œû•Û’IIÎÝzíRù€VQ3ä“ %nYa›gҸ‰(Gtt»l†Óábâ¯ø%gù ÿeìµ/öØ?« ºÄÂÐMwHbRR\fa¡¾–,°/—¿ßn¶×1(Ég;}Ù·ÝŽwÜîß3wÚô(«è¬ùÙ7µuwÁênú®³ñ›þêέÿÙÿ—TUõÒ”œUò³çßoóãó>Ÿ|¡{êºDUò•ãBY¿9û+në~ۜ͟çÏš¢QWÊV~̯ߊRºûðå?W8«å+6c_=ç+cŽÆ±õq|¥)WÊV:þZ¶çv[šw9xüiõq|¥)WÊϲUöëÝk^ï¸w^E¾^fï™n¦[‰|Ë«”UönŠZ²ópå·}WJN*ùJþœ…/~xJ¾;2ò×ÝJQ(«åfÌ<ÿ×ÿ?¹¤ìvÊÕuŸ¶ÿoÛ™ø¬ÿe‹ûDUõÖ:þnvZ›ž£ÝF©–ªºN*ùk åâ‹åmËÈã7;¥•ºòœ^«,´Ž”§#cú~Ûõ^´š’À¹X5ðÍ’^á™$ÇGåâXgÝþ,n}öû#ìv:u¸94šMH`Ä%(Éî[#€é(û#§¥±ˆÉBF£þ’RSºví`Ñ _°…Rxn䲟Ÿ‘Êè„Ëé+)/£²1(JC AE¨Á¬”rò Y´“QÀËPþ•k¼è O+þ_q„¬Á¼7ãI})ü¤ôï‹GùfkÊá¸ü@u¥){vu|¥)WÞYH- FNçäí÷ê½(ÀLZº6ý%àÀ‚^Kòz å¥öZ3 ìæ}y:Yoôêÿ»$²h ºðc#l“Ó‹Ý0hhÏ—“÷bДdädï|aä–œÿr•÷fãvù8Ö=«>N[] ƒ ! J?(®„ŒA) AŽ_ÙcþJ;+{èdÎ(œ1A¨ÉÅ8fGÉå§u¤†œŒ„`ÍúJÁ(éttïy¹k?„UÕÿ¥¼˜_-_,Ìá nŽíÿÉsÐŽùõ‚õ¬êùJRqWÊò÷J·o÷Û­OWG û‹¨¬ùÙ7µuwÁênúQW×JRqWÊR‘|¥)WØëÙkßÙLiØõcù‡UÒ‘|¥)WÊR‘|¥)WٜݲùÝÔê3Æu.®”ˆ«å)HоR”ˆ«ìîfÝxþÊu™ÎÇcz•WYó±êîÆ|¶<óºurоòËAHéOmã…ñÛÎÙ}WÓˆlCý#¤šœ‚hÌ€Ävlù{6By_„º Í’Þù©dwß|“ùߨ”¼¬¯–í²Úû@Ë &ô ¼W%t±e%²rÉI݈ É\3%ÊFÄ´çN÷œ‡$jêþ»•ÓƒCR’Ò4Á€Æ/a?!“ÐÉBS—Óò?${åÙÍû¯™N£yØþoZ¯`l€Ò‰¡œa[t ÿŒå )ù=ð-“›gt;5âí’{1>U|¥)vSWÊR‘|¥)WÙöNûí÷Í÷^û™õîÀbÀÂɈ +¤1Ù˜¤SaˆÉè;ä—¶Ù;6W~3Þõ€”“ƒ {í¿å8Öý‚ ~ΖÅîùï»\¨ª¯ …Ê&# ,²hÀÌ”)�8fFÉÈAKe?~{µæ¯¡€À´_Ž€Â¹-�(OBqh@bF+’‚å%«m÷¼î<ÿ—¾;±¤îwËÓãœ⯟³¾Ç~gëcŽ?©Õ9E ¤d!‘¶Ø;*¢—E5|¬Ù‡Ÿúÿç÷4ŽÙZ®“оÍÜÏ—Ïc9êüóñ¬}])WÊÏòþËÙj_í°VWHоR”ˆ«ìeîµoì¶0îr¹øÃêéYó?uŽîa?ò¼¢¯®³¹Ÿeãó©Ön?Ìë]]'|¥)WÊÍòvûï¾}ò÷ÜÝêéWÊR‘|¯å!.ùòs}Ö–º–ëRͨ¬î¦Øõ­›79]ÖÊR—(«ë¬Ùý|ö7œ­Ž;ÇÕÒqWÊÅ¿VfÍÝn·Snë§Î<ýÕþ;¹„üwÊõrŠ¿xo%#¤hÍ·?:7ìÉK7d½¶Çëì‰+@>à:FFå—€ÎÉGNJJ ,5ïþ߆ ÅæOÎíï‰ñ¯¶ÿ>Íóæ}ßçn½™c½öP†ýÝ@bC1|5$Òñ/„·-8¼ÈßdrÊå�¥&ªó2ÅŽ8 WWø rÒŒŸ¸jzKJÒWA_íÐüi}Žƒ!·sýâ/§�<!†|’’ù7§ô¡#Jã{¥9%?'§$brñ¾ùМ _ò«å)K²š¾R”ˆ«å)Hо^À<¬WÃ8Â÷C'dâotî„ HKü–ΔïÂ9Þñ÷¿-Òa1­‹Ktw„•÷Gá $îÊügÈNK5ÌŒ$UWö@4I-$À„¤p‚VI šÝÊ_ø ý‘ÊlÈÂuòì0¬„fF$#+ŽØVÇc5íÀ4ÉAEÿ!#£îZ‡á’¶dt,%9²7Cg¼ ’H§…E_)J]ÔÕò”¤E_)JDUò”¤E_)JDUö|ûíþ|~gÂóï”/}WJDUò”¤E_gÙ;ï·ß7Ý{îgÕt¬ýŒýxæ7ž¿Ž?šÇJ*ùoñêS6lzû­Ö¥*®³á»îë̯÷ù¾—WWÙó±êîÆ|¶<óºtÙ¶ßþØþÏÅöÛ,VÚ®‘|¥)8«å)HоR”ˆ«åíÀB 2é+â‹Èåïƒ:\²’WBÛ¿Ût#7ìžÛ¯^"³çßoóãó>Ÿ|¡{ë-çWýt05 0J3† åä§`ÒÿJ‰¤¬‚‹í†Â:ø¾hIe/äô6OG¿èÉÜh·t}Ô–«è`;ÐhieI[Ù<„€t¥³trþ I)™¬¼Ã.í�À † ´'“†† 1? èBŠ+#³`ÎÜ®ŽK(aÝ‘y]›çPõ‘Ÿ“ë«þJñ¹l÷ÛíóçcßæmÜ{Q{6u|¥)8«å)tƒHh&td¶ßÓÒVÈÙ³ñ©Ý¿û+uüíKE_Aeâ–—Ègé3/e›wfÛþ½ø¨¡£8g%âVNHbwB éì[bi_’¾Ì‘’–Nµ½�;H%âÃ¥E£rJ9I/žZ KQEéØi+{Å ™ËK–œ‘™%%º> ßÿ±5£ò:¯–”¶Û®óØf#XêêüàS§ä'ìŒZâßþ3¶ß¤nßç_¸T¯ÉÝ=í¹øßñÎæ˜q·¦¯¢”¥r«å)HŠ¾Å¿VfÍÝn·Snë«¥"*û;©¶=kfÍÎWu²”¥Ño—™»æ[©–â_2êé(«å)IÅ_)Y¶FÛm¶Í¶VÛµ\E_+{7;­MŽQî³Ê]]"*ùJV~ÌzûùŸ­Ž8þ§TE_])HоR”ˆ«åfÙm¶Û6Ù[lfÕu› ÛgVeÿøïøž¹E_])IÅ_)JÏWsþ3å±çÔ눫ë¥)WËÞ�ìâƒ~,1 4 J{·ÝEä£�ç'+¡ÐïÖ¾÷ƒ¥›Î¯û¸adÐ'£ËAE£bö’²V°Ä éF(½²X–ë¸ ƒÙ†¥�[<oC$§GbºRŽߣ!Ûõ¾$_--´%Ð7|èìœøýÌøËÖ–�ø ¥)Nü—ÿ/; ¾ï¿Ûfè3¡“ßýýç' mU}e�fLIc?ÍóäîWB¡½ IA¥·Ìžÿ#}»;=A@'BJßä ¾Är¸hgËwÝ û©ú2ºvV»X!†à2ᤲӸNJ±IÌÉYÏ u¥!)ô�’[õä'§îVZFäà.Ë/}þ,jS¿ý™›Zw' #�ú*üd0ŒGINŸÐ‚Ã6ÈÙ e’‘ñiÉHJ?b™'mºï]É`1ù�e$ €äd†¤šŠ)!Ÿ¾Éù}’‡BY O¼0Ø ÂPÐÝú6|[t1D¬Ý+±ÉJ¶s³\VÊÏ‘²6FØg|í[çfÌÇÌ×lx«ý)0ÛðÔ»ÿ¾GÅ$tòò0 ðÜ7¥Ýnʼžu¿Ç©LÙ±ëî·Z”©Æl‘«uô²ØÇc1ƒÇú‹­é«å)KYUò•‹|¼Íß2ÝL·ù—WWÊR‘|¥gvíöì¯óíÅçÎ!õ6¶Î¬Ëÿðÿßñ=rоºR“оÎêmZÙ³s•Ýl¥)ut¤E_)JDUò³¹›uãû)Ög;êU]"*ùJR"¯³çcÕÜÿŒùlyçu:êéHоR”ˆ«ìÿ#þÛgÿ«mþ®”ˆ«å)HоR”ˆ«å)HоV|ì¿›ŠZº»àõ7}WYöíþÝ»á]¾|9_áQW×JV2ÿZöÇöS˜v=|þiÓŠ¾wnßnÊÿ>Ü^|âUÖ}»·nøWoŸWøG§ùÿöÛ?ý[loòоºR½º_ugß2{ön¶fZ™þøóÚ"¯¢”¤â¯”¥"*ùJR"¯”¥"*ùJR"¯”¬î¦øõ©ß79y–ËZ•8ܧÿý·ùû9Íùû8ö>QWÑYó±êîÆ|¶<óºutœUö2÷~wR›œ³F-–ººWïÒßó·GÉ[1íó-÷Î!¥}¬ùÇŸº¿Çw0ŸŽù^®qWÊR‘}é-gOlµ™›ÿçlØþÚ¢””Uò”¤â¯”¥"*ùJÇ^ÍÎëSc”{¬Å2—WWÊR‘|¥zsã²VŽÜå}Üî¼~²õD¢¯”¬ù÷ÛüøüÏ…çß(^ú®qWÊòÑÒ²y\  càòp^“9»eó»©Ôf?Œê]\¢¯”¥c¯æçe©¹ê=Ôj™jœUóößíûc³?Ÿì±jo“·ß}óï—¾æïW^É×mÛ¶øköS¯8©E_E)IÅ_)^ÿ¡ÑŸüû%Ðb·|øZŸ¨”Uò³fs×ÜÿÌÙNqÇe:êé8«å)HоR•ý;>Á?g¾·cþËo³ý¥}Ÿ ßw^e¸wÍ𜺺N*ûÒ‡^l–û'çga{³ìùó´›äí÷ß|ûåï¹»Ñ׳sºÔØåë1L¥ÓüÿûmŸþ­¶7úb¯®”¥QWÊV>Ÿ>ÛünÝÛ°¶ì"®"¯³º›ãÖ§|Üåæ[-jU?c?^9ç¯ãæ±Õt”Uò”¤â¯”¬ÝÜõv;ã7SžyùNª¸Š¾R•™Öû¥»æÇ«2ÝKRâ*úéYÝ»}»+üûqyóˆ}OØyû+~c üí—å|ßwÛîݸ®Û·¯¸WJ͘yÿ¯þsIØí•¢*úë>}öÿ>?3áy÷ʾ«¤â¯³9¿uó³)Ôo;ÍëU])WÊÍ›mÿíìü_m²ÅmªéWÊV2ÿZöÇöS˜v=|þiÕq|¬ûvÿnÝð®ß>¯ðOòþËÙj_í°VW(«å)IÅ_)JDUò”¤E_~ß%#»wúÎùº¶mŽëÿ¨}Ebß«3fî·[©„7uÕÊ*ùJVlÎzûŸù›)Î8ì§\â���ˆ����z¿óý)HоV~̯ߊRºûðå?WHоR”ˆ«å)Hоñ›#ä;­+õþ½ó¿uîüúŠÌíŸïÙfßŠÏØCú¹E_)JÆ_ë^ØþÊsǯŸÍ:qW¿5¿ûßû»|ÛáÕ¤¢¯”¥'|¬uìÜîµ69GºÌS)utˆ«å+6ÈÛm¶Ù¶ÊÛc6«ˆ«å)HоR”ˆ«å)HоR±—û󲔨õœë5l¥UÄUò•™Û?ß²þÍ¿Ÿ°‡õq|¥)WÊR³ý›³öÂû~Øz·â4E_])HоR”ˆ«åfï·ûçÇv|+·ø+ýWHŠ¾ÍÆíó¯:÷Ü?vøG]])WÊR‘|¥)WٜߺùÙ”ê7˜7ަù+ßuü¥¯vø;«‹«¤¢¯”¥'|¥+?fWïÅ)]}ørŸ¿ˆ«ë¥)WÊÌíŸïÙfßŠÏØCúºDUò³ößíûc³?Ÿìö§víöì¯óíÅçÎ!õ\¢¯”¥'|¥)WÊR³wu|ÜRÕ—›‡-»èоºVg7l¾wu:ŒÆŒãéûúñÌo=5Ž”UõÒ±×ós²ÔÜõê5LµUÎ*ùJöd¾Ùûdó»gøÎíùÝþ¢QWÊR“оR”ˆ«å)XëÙkßÙLiØõcù‡DUõÒ”ˆ«å)HоR”ˆ«ïJP†~Ïößœüìçg?¶?Ñò0JM?¶$õemÛÔ¨¥'Å_)JÎêoZós—™lµª¨«ë¥)WÊR‘|¥)WÊR‘|¥~)¾FÝkÛþé ëãýD¢¯³9»eó»©Ôf0üg8ÝÑúYÔ—ò¾_Ùß2þn}E"*ùJRqWÊVlÆþ¾{ÎVÇc黺¾n)jËÍÖÝô¢¯®•™Íû¯™N£y‡óxê¹Å_gÎËù¸¥««¾SwÕt¤E_)JDUò”¤E_)JDUûÿB[6J5çÊèûo™IÝþo˜ÿ`¥)оR”ª*ùJR"¯³öcרïÌýlqÇõ:¨ëÙ¹Ýjlru˜¦Rêë3¶}·eíßn+¶q-¥}t¥c¯æçe©¹ê=Ôj™jœUõÖlÛoÿlgâûm‚¶Ôønûºó+ýþo„åÕÊ*ùJÏò7ÿí¶ú¶Øßêç}›6ÛÿÛÙø¾Û`­µ])WÊR‘|¥)WÊR‘}›d+m—ú”¿ßðþ¾.®³»vûvWùöâóçú޽›Ö¦Ç(÷YŠe.QW×JRqWÊÆÏûgûoÍû;gý„ÕÒ"¯”¥"*ùJVlοߊR²³`õ¿W×JVlÃÏýóûšNÇl­W×JR"¯”¥fv϶콻íÅvÎ%´E_])HоR”ˆ«ìÙ¶ßþØþÏÅöÛmªéHоÆ_ë^ØþÊsǯŸÍ:®”ˆ«ågu7Ç­Nù¹Ë̶ZÕWY¸Ý¾uç^û‡îßë”UõÒ”œUò³ö~ÊߟØÂ;eúºDUò”¯@ÆÍ&2ß¿o±ýûš|¢¯Læí—Îî§Q˜Ãñœ}])8«ågùÿöÛ?ý[loõtˆ«å)HоR³:ßãÔ¦lØõ÷[­J«ˆ«ågû6ÿgí…öý°õoÄj|ìz»ŸñŸ-<î§]\¢¯”¥'|¥+?È_û/e©¶ÁýX\E_>v=]ÏøÏ–ÇžwS®®”ˆ«å)HоR”ˆ«ìØfÛ:³/ÿÃÿÄõÕÒ‘|¥gû6ÿgí…öý°õoÄj¸Š¾R”ˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоV|ì¿›ŠZº»àõ7}:zqÈ›õuÿ™¶Ý²Ö¿ó*¢QWÙóï·ùñùŸ Ͼ ßUÒ“Š¾V-úó6lËuºÜCfUùy›¾eº™n%ó.™Û?ß²þÍ¿Ÿ°‡òоºR³wÛýóã»>ÛüþœUõÒ”ˆ«å)HŠ¾Í™Ï_sÿ3e9ǔ뫥gÎoËÇ1œåîyÜÖ:QWͶ¶Ïß‹í³ñêÛÔýŒýxæ7ž¿Ž?šÇSl¶Ûm›l­¶3j¸Š¾R”œUò³çcÕÜÿŒùlyçu:êéWÊÇ_ËVÜîËsNç/>®Þ’j ,¢¿YcF¾Œÿ3¹Ëvaýþ¥¢¯Áu€+ tïþèèÝМ²Ò1 û>éVùð»ê¡ ä“yh„�Ùø –è-<¤üŸÓ²Jü¬‹ÃöÛØ10d2ŠI4®CB? À²K/:‚Ê/#¶û²?@B7^s0çs]_Á,gBJéNé%bRPKOr»bb~äŽûÑ›½€° ÊAÅ–ÉI_#9cP–Û Ýò ã]±+ãÕzÐÐ ‹¡œ¼”ä 4´°ƒxj7@ÔcÙ(GÃRýÂxBä�^H [ðÂ^ß‘±EÊNPÖ^Ù²3\øöê8ó„þÓ«þbQcF„%0%‚U¸Ô7ﻉwßV šRSÑ»¥ù»¡»-JsÐ䜼úûx°h` ˆhá;—˜§ü ÌKA-)%ú”‚Ü™­H&†“{S‹áˆ(´¡;tô£wNÈ`”!Ñ’žž–A`8Z'Ì,|Uÿé}$@”YKÀ…ò´pÆø¾3§ì–BÙôŒB»ì‡û_:ß'o¾ûçß/}ÍÞôº¨«â߯3fÌ·[­Ä6eS»vûvWùöâóçú®³ö~ÊߟØÂ;eûyUõÒ”œUò”¤E_)YøÍÿugVÿ‡lÿˆË«ˆ«å)HоR”ˆ«ìÎnÙ|îêuŒ?ÇÓfuþüR••›­ûúºÅ¿VfÍÝn·Snë”Uóa›lêÌ¿ÿýÿ×WJN*ùJR"¯”¬îݶý•¿mø¾Ý„·«ˆ«å)HоR”ˆ«åxÇ@ÂÙ/™*WRÕÿWÿ¨¤¢¯³ñ›þêέÿÙÿ—WJN*ùY³9ëîæl§8ã²s¥†ݲº–rÎ;sZKJž‚¹möÝoî§ýLÿÔýTh«÷–‚ahý4k§§l²º{elžŒÏ”¯åßN!€ji!7£!£!9hÞ0²Ü3–wGB:^Û!;ïy`û%!¸¤äò¹,´tlVK¥ŒÉröboBfNÝ®Ððby4˜_,ie)9ÐŒ.†&ñ¥¡cz@óïfË'°5í*þ „ÎMù%„Êtð.Sa¨,!;|Œò¾mÚð6´!|gÿtþŸ¿uOüïñç*Éz.�<¢¯”¥-åWÙðÝ÷uæWû‡|ß Ë»¡  &³£m¶Ã6FGÙ!¾e€L„�©Wž¥›ùÕÿX,I|’(„z_lYiBqLM ázPÄfNJ~«A0ãC@mÃ1I %dt¤šÒ”Œ-†ì²þßïú¯‘üûíþ|~gÂóï‚÷×Ö !pž¯‹é)!¤®žXÔÉx7}‹FI,à!þÍÆÞIç÷°ì"º¿åIéÌÈwûu¶ØßͶïØì¹7w=]ŽøÍÔçž~Sªõ` %a¯À¿-)Û­Ÿ¥ %äl„¾=§ >òŽ¿›–¦ç¨÷Qªeªõ81€ÑW×JRÚU|¥+ùY›¿uº™L%ûª"¯®•éÙ\`ß¾cŸ:¿ÏñÛ÷e³µD¢¯³ö~ÊߟØÂ;eúºRqWÊV6}Û>ßnnÝŸ8¶Î"®"¯³mŸí³÷âûlüz¶Â5]+-[s»-Í;œ¼~4ùE_])YÜͺñý”ë3˜v7ŽœUõÖ|ì¿›ŠZº»àõ7}WHŠ¾Ï†ï»¯2¿Ü;æøN]]gu6Ç­lÙ¹Êî¶R•W(«å)IÅ_)JDUò”¤E_~Nÿã¾?ŸíÕú’݈2m‘¶Ûm³m•¶Æm9- cpÆ5ó3;¹ÌËzŠb¯–òúr?n¯¾%§¡N¯„¾Ïþ$-V ¬CB Ã:û'älWJB:;b÷À|V^ß·ôéÕÿY&†£#üB}±x´9Y8±ˆ _ —ÑÐPj8ný%§'n­ï˜€À0°ÄŒÏ•²£?ã?ógFQY[¤ûë�&!$‡ƒw @jF#d£”Ť¯ÒYE¡_ÆôþXG|ù|+q»|ëν÷ݾ×y_‰<Y:º¾ºR—³gWÊR‘|¥)WÊþ‡J;üέÕ÷3ã‡}ÏÃÛúŠJ*ÿ¬rƒ´ 1r^èßÒž”#§þ—( òП–Î_‹{æÁƒX ÷J†¶ùŒÏŠ}¿C­û¯üêkè¤ÔQi“‹/†WÅ!%¡?†¡&üXÄt!$²ÉE t|¯6oIC€ÂŽJ X܆¶ÃvH6N듯+œA•¥_ãé^Ž4'}ÑöùƒÖîß|Ì ÿQz¶u}‹|¬ÍߺÝL¦ýÕWJÆÏ»gÛíÍÛ³çÙÄDUõÒ•ŸŒß÷VuoøvÏøŒ¹Å_]fî竱ߺœóÏÊuSwu|ÜRÕ—›‡-»ê¹E_)X·ëÌÙ³-Öëq ™UsоÆÏ»gÛíÍÛ³çÙÄS}ßo»vâ»nÜr¾â=]%|¥)8«å)Y°Í¶uf_ÿ‡þÿ‰ëˆ«æî<ÿ—¾;±¤îwËÔûvÿnÝð®ß>¯ðWIE_z7ÈÛ˜¬Ò¬wÿ¯ÿwY¼úŠR"¯”¬eþüì¥6=g:Í[)TÝÝ_7µeæáËnú"¯®³fuþüR••›­ûúnîz»ñ›©Ï<ü§U\E_+;·o·eŸn/>qªé8«åé@c‰½€ÆÝIùÜ´1e¶t}ÿJÕݯ=öíþÝ»á]¾|9_á95+tòú¾Ï»ûí÷?s¬xPTêÿ|acHa˜¬öJv,™ƒQ»ZWßwÉü•ÐŽH5õòM²6Ûm¶m²¶ØÍ¯³L9a©ü Âöý…`Äb€¹hIA¨I1)è+ HÄtŒíó|gwËߨÒw;åë…<ãD÷ç“ê«ë¥)z´Uò”¤E_)JDUò”¤E_ôP“ Ù5•úRÀºùhݹCR”#e—¾vHNûô6¹ +}‰ qœ¬R ùJÅm‹+ ÍÙ.4—¿» U)B9£“xfü!À,&†â²_~[a›ößíÐKN^{Í€À®€Ä!’ƒ>BQ¹KÃô ø²_täì¬o÷ŒæüÓÍXV•—Ýöÿ|øîÏ…vÿªéKÙ³«å)HоR³;gûö_Ù·â³öþ®"¯”¥fs~ëçfS¨ÞaüÞ:"¯®”¤E_gÎÇ«¹ÿòØóÎêuÕÒ‘|¥)WÊR‘}Ÿç϶ÿ·vì-»«¥"*ùJV~Æ~¼sÏ_ÇÍc¢*úéJDUò±oÕ™³w[­ÔºêéWÊW¥OGùhï…vè#Q(«ågÙ*ûuwÜ;¯ £çÙóýþÆý™û |âjâ*ÿ²p(_!¡„Á¨Ý�a8߯“ ] %Òȃ7|†GÎ÷•�Èš5Ë·Ý.3ô„l[—‹és°jFaˆ_ï>²aD2˜±£7ò7mÂ>oøüÁ/·ÝõôbÎ ûÿéJñi NèA0”„€Û”…~ŒÉÞñ¿æìæ A´«þ9KºB&¡%’Y,hĨ'oÍÅŒ–= ¾n{q¿Ù·û?l/·í‡«~#^¿ÔUõÒ”®U|¥)WˤCã—Û! é$åds’€”}¿c³Ôþ„>èÍ÷ý*Ùá½ÀTìcŸ{°ÃR΀Ää2Vå> ~R1- NBIcÑÐZrsosm§Wö@ ×Fã €eœ íú7Ûe`Òº>ä¦BÜ´#„_+FèÈÛ þ5‚3÷ÿì³Ògæþþô Q»  §$#%­;¶ÉèR FÃFr_-?|ÿw{ÉØ¥—:¾R”»é«å)HоV|ìz»ŸñŸ-<î§]]"*ùJV}“¾û}ó}×¾æ}W×JR"¯”¥"*ùJR"¯”¬ý·û~ØìÏÅgûý©³í»/nûq]³‰m(«ë¥)8«å)Yû2¿~)JëïÔýüE_]gu6Ç­lÙ¹Êî¶R•WHоR”ˆ«å)HоR³q»|ëν÷ݾ×WWˬHH¥’ŒßÙÐèøj Σ™ÞäÒ˜«ÿ@ˆE€«‰¸!% ²Rslú�l„ìXÝ“œ¤öåýŸûÉ€BXg& 5­’ÄÔ¸ ·Aeº~GéùÙû¬îßtûÂ$EŒá»ÝÂv~Ÿl7²)ú9¯zЀd­„ 1+¥ƒPãP•¥(%öèèãwÝ sÿ׆ù”hXµ«ñàårùD¢Æ£„ïº: éû'díÿà[’¶ðÇù¯„âÑ“Žç/wÆ}÷ù¾^ï§@0/!Ô 3nWA[†† 0 #þÈNÛ~—á¿ã‘µÓ!€\Cø™ñ}!¨ÛpÔîZN/§—Ù]erпÌŽÖûžÈ ¥Wü§ÊùÆ•ÃPÈOýŸí³ü£ûzÒÀ/ Gèý8bSËù )ÒSçÉÉß¶ã ÕÛ^Ø�ðšL,¤±i)ÿAEÊ|JÎ_I[$3:KàaŸ'ôŽ7ûË€0è¥zpnÈ<4 .ßô¡/ÓÒP‡è@B²õ™ûãŒ?8Å_Þ!�?I Ô|¿ÃvJrCþü—Ò”?I,fA-·A[^<�:CâË&`ÂöÜ”ŒÈ+»~ŽW%q£7ùiÛŒOèû^\1 R7—¿ééK'§%úºl¿™³ ͵AAˆ ̇ÙÝõ›×ùçñÿÿ×ýÐ9*¾ÌÈèO%£æãsÿûgÝÉmŽÊV°R—£E_+6g=}ÏüÍ”çvS®®•E_gs6ëÇöS¬ÎaØÞ:®”ˆ«åfù;}÷ß>ù{înõtˆ«å)HоVwnÛ~Êß¶ü_nÂ[ÕÒ"¯•‹~¼Í›2Ýn·Ù•WHоVnæ|¾{ÏWçŸcêéWÙöNûí÷Í÷^û™õ])WÊR‘|¥)WÊÏØyû+~c üí—êéWÊÏœyû«üws øï•êéWÊR‘}ŸnßíÛ¾ÛçÕþêéXëÙ¹Ýjlru˜¦Rå|lû¶}¾ÜÝ»>qmœE])8«ìÙ‡Ÿúÿç÷4ŽÙZ®”ˆ«å~FGì­ÌÛlÿÿú³º[ò-E%|¥)8«å)HоR”ˆ«å)HоV2÷Z·Çö[w9\üaõtˆ«å)HоR”ˆ«å+øÂ²RÂûgý³³þÛczš¢QWÊR“оR”ˆ«å)HоR”ˆ«ìÝöÿ|øîÏ…vÿªéHоÆÏ»gÛíÍÛ³çÙÄUÒ‘|¥)WÊVnîz»ñ›©Ï<ü§U\E_)JDUò”¤E_)Xùö|ÿ±¿f~Ÿ8š¸Š¾R”ˆ«å)HоR”ˆ«å)HоR”ˆ«å)HоR•›dm¶ÛlÛem±›DUõÒ”ˆ«å)HŠ¾Ï²UöëÝk^ï¸w^WY¾Nß}÷Ͼ^û›½\¢¯³ö~ÊߟØÂ;eúºÌæý×Î̧Q¼Ãù¼u\E_)Y»™òùìg=_ž~5«œUò”¤E_)JDUò”¤E_)XËÝjßÙlaÜåsñ‡ÕÄUò”¤E_)JDUò•Û¶ß²·í¿Û°–õq|¥)WÊR‘}›¾ßïŸÙð®ßà¯õ]gÛ·ûvï…vùðå„z}»·nøWoŸWøG”UõÒ”œU÷¿ï²¾ûwGc?cJ}þÜCTR’Š¾ÏØyû+~c üí—êéXëùjÛÙniÜåãñ§ÄUófs×ÜÿÌÙNqÇe:êë?c?^9ç¯ãæ±ÔîfÝxþÊu™Ì;ÇDUõÒ”œ@���È����z¿óýc/wçu)¹Ë9ÔbÙk«¤E_c¯fçu©±Ê=Öb™K«¥"*û;·m¿eoÛ~/·a-êéHоV~3ÝYÕ¿áÛ?â2êéWÊR‘|¥)WÊͶ¶Ïß‹í³ñêÛÕtˆ«å)Y¶ÏöÙûñ}¶~=[a"¯®±³þÙþÛó~ÎÙÅ?a4û'}öûæû¯}Ìú®QWØëùjÛÙniÜåãñ§ÕÒ“Š¾Îæ}—ΧY¸üw3­tî¦øõ©ß79y–ËZ•WIE_fÙm¶Û6Ù[lfÕt¤â¯•Ÿ ßw^e¸wÍ𜺺DUò³çeüÜRÕÕß©»êºDUò”¤E_)JžVfïÝn¦S ~ꈫë¥)WÊR‘}ÌÛ¯ÙN³9ØìoRªéHоR×¹D¾vK1ÍþCu9'a§çÛö>É(«ìÙ¿¥efÁë~þ®³wÛýóã»>Ûü¡_긊¾R”œUò•Ôßµ;æç/2ÙkR©³ýû/ìÛñYû(«çvíöì¯óíÅçÎ!õ])8«å)HоÆ^ïÎêSs–s¨Å²×WJDUò”¤E_zvW7ï˜çίóüvýÙlí#/÷çe)±ë9ÖjÙJ«¯n5ÿ³>mØüíûåvÍ»zb¯¢¼'£îûíÑ݇uæv[}öê]E'|¥gìgëÇ1¼õüqüÖ:®qWÊR‘|¬[åænù–êe¸—̺ºÇ_ÍÎËSsÔ{¨Õ2Õ(«ë¥fÌëýø¥++6[÷ôý™_¿¥u÷áÊ~þ"¯›»ž®Ç|fêsÏ?)ÕWJN*ùYþÍ¿Ùûa}¿l=[ñ®‘|¥+3­ö=KwÍVeº–¥ÄUõÒ”ˆ«å)Hоñ¹Û©ûgø%N¥¸ñÝ\ÊŠRQWÊR“оÍÜÏ—Ïc9êüóñ¬}])WÊR¼‘•¿X÷ëëá<ìîÆlÛ(«è¥)8«åfï·ûçÇv|+·ùB¿Óÿûì®Ï¿Gè[°íÎ^ÝÄ=D¢¯”¥'|¬ÿ!ì½–¥þÛõautˆ«å)HоR”ˆ«ìÙ¿¥efÁë~þ®”ˆ«å)HоR”ˆ«ågìÊýø¥+¯¿S÷õtˆ«ì[õælÙ–ëu¸†ÌªºR"¯”¥"*ùJÍ™×ûñJVVl·ïé»íþùñÝŸ íþP¯ô¢¯®”¤â¯”¥"*ùJR"¯”¥"*ùJR"¯”¬ønûºó+ýþo„åÑ×ós²ÔÜõê5LµJ*úéJN*û3›÷_;2Fó±üÞµUÒ‘|¥gÎoËÇ1œåîyÜÖ:›Ûç^uï¸~íð޹E_]cçùóí¿ÆíÝ» nÂ*é8«å+6açþ¿ùýÍ'c¶V«ˆ«å)HоR”ˆ«å)HŠ¾Ï—óqKWW|¦ï©öNûí÷Í÷^û™õ]%|¥fîgË籜õ~yøÖ>®qWÊR‘|¥)WÞ^éBvíþûu©ñêèá_qr‘¿ÿm³ÿÕ¶ÆÿWIE_)JN*ûЖmº~Ã{;;mýY—Ú¢””Uò¼nÈ-™øß‚ýþÿ(Õ´ÔÛµ³fç+ºÙJRêâ*ùJRqWÊR‘|¥)WÊR‘|¥)WÙo±ê[¾lz³-Ôµ.®”ˆ«å+{­[ãû-Œ;œ®~0ú‘¿ÿm³ÿÕ¶Æÿ(«ãgý³ý·æý³Š~ÂjéYo±ê[¾lz³-Ôµ."¯®³;gÛv^Ýöâ»gÚ®“оR”ˆ«ìîݶý•¿mø¾Ý„·«¬ÎÙþý—ömø¬ý„?«”Uò•éHÆWïöVvsy¬êS³¿Sù6ÙþÛ?~/¶ÏÇ«l#DU÷âGNFÉN»gKlÉè;oó«)ì•ÔÛµ³fç+ºÙJRêâ*ùJÎêmZÙ³s•Ýl¥)tß%{î¿”µîßuqq}uŸç϶ÿ·vì-»«¤â¯³l…m²ÿR—ûþ×ÅÕÒ±³þÙþÛó~ÎÙÅ?a2оºR“оR”ˆ«ìîݶý•¿mø¾Ý„·«¥ïÿû¶m»³«:Ýn­³©rоŠR“оR•Ÿ9¿/Æs—¹çsX芾ºR‘|¥)WÊR³:ßcÔ·|Øõf[©j\E_])Y»íþùñÝŸ íþP¯ôE_])HоR•Ž¿–­¹Ý–æÎ^?|E_]+7}¿ß>;³á]¿Êþ«ˆ«å+;·o·eŸn/>qªâ*û?f=}ŽüÏÖÇSª®”ˆ«å)HоVnŠZ²ópå·}OÙ_c¿3õ±ÇÔê«”Uöm³ý¶~ü_mŸVØF«¥'|¥+?f=}ŽüÏÖÇSª"¯®•™Íû¯™N£yØþoZªâ*ùKÔ€œ%�›a­ÿùA*woú–Ï_Ù??Í{rÀvVp�Ÿ$7m‰eV%¿ý•ÑÐY7ìà`#öÿ+ÜyŽª¯øý½¸²Fÿ>ÃT3Ýh[>uоüVÙ4†Xn,5ÊŽœ’VHoå#¶,˜R™“ ÒØ'ÜÎ�¤441)O(hÂ[“[ 7)×øj ÎÈÈJ]?¡îNÛea�úªÿˆ`Ôvgãvûíú>ûýÆì0ì<pýD”[t'''’…£·n˜îxëîx„J,7nYeñ¥tXo,¤ôIˆbYéØ i! KYJHI€7&%8­¹3€ß§!2JÉ/?ãpoÿ„¥¿’¡¯«Qìq’«þ·ËÌÝó-ÔËq/™uwÙ�t�õ4·áˆG(¤þZvO&§!~„§|Ø' ¤ è×ÈZ ϸçÇ|ûvû¯vû·Û®ëøêjú)Y³í»/nûq]³‰mWtʯ³öcרïÌýlqÇõ:ªë7}¿ß>;³á]¿Êþ£gݳíöæíÙó‹lâ%}t¥fÌoëç±¼ålqØÖ>qW×JÍ™Ï_sÿ3e9Ç”ë§ìǯ±ß™úØãêuJ*úé_™XìIIØÞ¾aéëæ¿¨ˆ«å)IÅ_)JDUò”¤E_fÙm¶Û6Ù[lfÔî¦Øõ­›79]ÖÊR—WIE_)XËýkÛÙNaØõóù§Sf7õóØÞr¶8ìkWÎæm×ì§Yœìv7©TÙ¿¥efÁë~þ®¿tºöÙgÍØü¾;©gÄUôR•ŸäoÿÛlÿõm±¿Î*úéJDUò³w3åóØÎz¿<ükWHоR±×²×¿;²˜Ó±êÇ󫈫åë�5¸A‰NÀ]9°Á„¿ÿöO^Cõ²F8ÞžóE§Žžv={67ÿþͲø­}„ÿ@gå¤0È&•‘‹@ÒHÔÁ…£6è|Z3> BÞâFuUWõÀNM&Røb{d•ƒ?ß1lLø1”#§—·,¢ðÈég{çà&Ðf /t—ËèéÀToééÙùYçéûnÅÿ¿6¼�‚PÐÀ˜™[2xjKü–‚ÓÏB‘Ù•ûd³ï|÷l¶Ûm›l­¶3kŸðèùÕïÊGïÑ¿RþÀ{ººðïQJ^¥}›3ž¾çþfÊsŽ;)×_ƒ B26Í»·ZÝßþÿ÷[õºÏ²R"¯÷i�À¢Û$44hJF•¾Z5<¢¶å©g³ìùïRLà„¢NÈHhÍÒû–€ß˜´ñ™%‹OßJZøÝë@© “CwÀY;bQd¤£¤'ºQóîÎRÛt²ßïyÃLúêøC I5NÛ¥±„·dmöäÄù'äŒ$öý›^Jûxa •‹ ÉHfJà‡öKè)$Ô¥‹BBR¸ù¶Çß1&òPãP[î”l’†÷åüSn0# fù?~û5_a Š¿…¶FÛm¶Í¶VÛµ])zUò³º›cÖ¶lÜåw[)J]]"*ùJR"¯”¥gÎËù¸¥««¾SwÑ|ηØõ-ß6=Y–êZ—OÙ_c¿3õ±ÇÔꫬ|ÿ>}·øÝ»·amØD¢¯®”¬î¦øõ©ß79y–ËZ•8«ë¥)WÊV|ûíþ|~gÂóï”/}OÆoû«:·ü;güF\¢¯‹~¼Í›2Ýn·Ù•9%÷ß7ÍÝ›¾nìêû³·SHËýùÙJlzÎuš¶Rªâ*û;©¶=kfÍÎWu²”¥ÕÒ“Š¾R•Œ¿ß”¦Ç¬çY«e*"¯®³öe~üR•×߇)ûúm­¶_êRÿÃúøº¹E_)JÌíŸïÙfßŠÏØCùÅ_]gÎÇ«¹ÿòØóÎêuÕÖ~ÃÏÙ[óûOçl¿(«ý( SñX…ºydÔt!=èéÛ(·@Åçÿ Z2[;kè` ãRžMIE ™ƒ8¥†£¤’”¡ñ,†ã]BPŽ®»Î€fJ%”CïÐL_û!( Gù!¨AEî])Ûvíh�ЄŒü„ƒ Ÿà.„•º‰I(bxGãy}8ïß^9ÔS½¥_óB1)Ïã3oúÿgìýùüME){u|¥)8«å)HоR”ˆ«ý€CY`Sâ’Š,—öû7Ìß䆕¸¡ÝnϽî�2$Œé%úPKÛ$–—G%¥©B9Hd}ñK/:7ùï¨ùMÕòsïÌøüø‰ï°–œ�{ÐQ0IE! +¡€Û¶JJl±EæÈ@Çd©:ò]]k8>Ò¯øÞÌëýø¥++6[÷ô[åænù–êe¸—Ì»¬Q-†$i_¡³r[ PÒ_G_ýCÿmÛw×ôè«ìÎÙþý—ömø¬ý„?«¥+•_)Jò˜fùÛ¬$k­g%xó¹Ç4¢¯¢”¤â¯”¥"*ùJV|ûíþ|~gÂóï”/}W×JR"¯³ü…ÿ²öZ—ûlÕ…ÕÒ‘|¥)WÊR‘|¥)WÊR‘|¥)WÙûúñÌo=5Ž«¥"*ÿpªHdÀÄS+£“S‰jA\h@fIÉêHIÝ“Ùzî€`Lå`3‰™ 0¤¾Å¥ÆbÒÿ?”‡%oƾXÛ�J!}•²zRJbŠA`6ãKÅòòÈßÿò–mýA0bO& °ß÷/'d—Ý(H`bq`gd|¿OëmÛkÉwð[9´«ü)KÖ³«å)HоR”ˆ«å)HŠ¿Xh:þlù²zòò‘òR³Ñ¸NU÷ *X!£–PÙ)&²ìÃtò‘Ý<jRЇ£ëà¼ný·î…oöFøn—=¾Ûßk(†�~XnÛ$ ¾¤1ªÎñiÃIlœ¬¶-Êýï#eZUÿ >IIÛ£ñ®JèWý/ÓÿÊë^]ͺÀSƒÃvÁ¿n[2ÒÛ?ûlí±ÊÇoõɽ>}|¥+>¾î¼Êÿpï›á9v’«ë¥)WÊÌë}RÝócÕ™n¥©t[åfnýÖêe0—E_fîgË籜õ~yøÖ>®•Û¶ß²·í¿Û°–ñ}t¥'|¥gs>ËÇçS¬Ü~;™Öº¸Š¾R”ˆ«ìÿ#þÛgÿ«mþ®”ˆ«å)HоR•Ÿ>ûŸ™ð¼ûå ßDUóößíûc³?Ÿì±jºR"¯³}ßo»vâ»nÜr¾â=]+¿;)MYγVÊT¢¯®”¤â¯Þ†£/åì¢Y¡s¿YÈá&_MÐa™Ðåb^Èø²`n%–[ fÅ¥?}¾ßþZ>éØmò;èÀŽn+òòry`[±Hçþ­+GÿæwÈ×ÿ¨‹U_â8B÷NénKìíþtíòú·Û±Û5‚úp€v‚‹@gÈà_”WA1 É”ì„_WÈÉBqIFû—x0ÀÒ“ËB¿)?$''ïÖÿË}·ffÙ­¾•_Í¥)tʯ”¥"*ùJ] ÒÆ6`Ó÷ýt¶Û¥jîã:>ΗøçÔÅ_bP’oFw(n?lpbx@×䜶Róç]î�M‹ Kä$˜R8f‚ÊíÊ û 7 Oÿ¸Ä¾A{ ¥×Hš`hj +ñ© &'%<Ô—¸b6ß%%/†²_#q ù¯¢&KJq4#|†þľ52úrVét÷J^ó9Á`WWøúR³;gûö_Ù·â³öþõh«ë¥)WÊR‘|¥)WÊR‘|¥gí¿ÛöÇf~+?ÙbþÔý˜õö;ó?[qýN©E_7·Î¼ëßpýÛáut¬|ÿ>}·øÝ»·amØDE_])IÅ_)JDUò”¬î¦øõ©ß79y–ËZ•W×JR"¯”¥"*ùJR"¯³ö~ÊߟØÂ;eúºR"¯•éßçËùþÃz7íóvu,ÝØö}QIE_ïÀb�–Ý GFÈAiH ²I})ÿ£òÐXÇÈHÌ‚»^”„Ÿ(eðÐ1Ê HÄ$1%ô’JÉå9-’WKövw÷Çþ}öÿ>?3áy÷ʾ½)`0%“ å§’þßïŠý¶GC÷ü¾À_ÿ•›kÏÊn8åWWç&�ìha,5™¶ßþZ9KêbÕ“¾nùKg}î(Ü4bÝœ‘ŒìIaŽ)ÜUôü� ŠÝ$Ñ›LíɉFtd•ÒIä°Œò) ½Hˆd>4k”¿rŠèvèÿ  ÀÆGîÀº0ÜK Ô|Í QWüwu|ÜRÕ—›‡-»êþVíËFîÌùÜ!L4�G‡ßY!¤ ¤ `ž5%ô ¤ ÁˆÁ»g+¨fù=+$?Í^Phix²407~€Î‚ÐÎCä§ûò’”¥²wÏß!ì¤é³æ,\Uÿ9,èGNܤýþÈÉOý²öÈ)?§%IFß¡<uïÀn‚Èß§†£á¡¥ògG g (¤æûâ÷ÌÖÃ?Åoa@ dÜžZzSÿÒRLÅ–†1em‘²¹%ô×Îà CðFĬŸÊCÂaìvͶÛ5!ÄãØß©(GÅ�¤½™ŒBR°JwG/[¤–œ”%™ϼFù;}÷ß>ù{înõt»Þš¾Ç_ËVÜîËsNç/>®³íÛý»w»|ør¿Â=]¬ªùJRqWÊVlÛoÿlgâûm–+mWWÊR‘|¥)WÙ¾J÷Ý)kݾêâêéHоR”ˆ«å)Y»™òùìg=_ž~5ˆ«ë¥)WÊR‘|¬ÎnÙ|îêuÇã:—WHоV}“¾û}ó}×¾æ}WHŠ¾Îæ}—ΧY¸üw3­ut¤E_)JDUò”¬eþµíì§0ìzùüÓ¢*úëýy›6eºÝn!³*®‘|¬ÿfßìý°¾ß¶­øWXëÙ¹Ýjlru˜¦RåX°‰©Xb îîœ4Æeºs­w”“ø«ågÎÇ«¹ÿòØóÎêuÕÒ¨«å)Y³ýû/ìÛñYûW×JVg7î¾ve:çcù½jˆ«ë¥fîgË籜õ~yøÖ>®"¯±³îÙöûsvìùŶquÿ%’ß8WR ZÖ¦R…ÔJ*ùJRqWÊR‘}Ÿ9¿/Æs—¹çsXêºR"¯”¥"*ùJR"¯•ŸvÏ·Û›·gÎ-³ˆ£/u«|e±‡s•ÏÆW(«å)IÅ_)Xùö|ÿ±¿f~Ÿ8š¸Š¾R”ˆ«å)HоR”ˆ«å)X·êÌÙ»­Öêa Ýq}t¬[åfnýÖêe0—îªn7oy×¾áû·Â:å}t¥'}ÌÛ¯ÙN³9ØìoRªéHŠ¾Í™Ï_sÿ3e9Ç”뫬ßwÛîݸ®Û·¯¸W(«å)IÅ_)JDUò”¤E_)Yû2¿~)JëïÔýüÿdä¡(QËo“¾ZŸ©l¶8t¢¯G_ÍÎËSsÔ{¨Õ2ÕWJN*û6m·ÿ¶?³ñ}¶Ë¶«¥gí¿ÛöÇf~+?ÙbþÒŠ¾wnßnÊÿ>Ü^|âSfuþüR••›­ûúºDUò³mŸí³÷âûlüz¶Â5]zr@÷Ù\ýúÔÝIÊË|hýWÑYó²þn)jêïƒÔÝõ{-{ó»);¬0긊¾R”œUö-ú³6nëuº˜Cw]])WÊR‘|¬Ù¶ßþØþÏÅöÛ,VÚ®‘|¥)WÊR‘|¥)WÙ³úùìo9[v5«¬|ÿ>}·øÝ»·amØE\¢¯³9»eó»©Ôf?Œê]])8«å)HŠ¾Îæm×ì§Yœìv7©Ut¬eþüì¥6=g:Í[)RоºÎêoZós—™lµ©Tÿfßìý°¾ß¶­øWWÊÆ^ïÎêSs–s¨Å²×WYöJ¾Ý{­kÝ÷ëÂâ*úéJN*ùJR"�������z¿à{1¿¯žÆó•±ÇcXùБ®¯›ü¼OÆ}ò÷Â;}õEbß+3wî·S)„¿uJ*ùû1ëìwæ~¶8ãúUuÌÛ¯ÙN³9ØìoRªâ*ùJRqWÊÌæý×Î̧Q¼ì7­UuŒ½Ö­ñý–ÆÎW?|¢¯®”¬ÿ#þÛgÿ«mþqWÏØÏ׎cyëøãù¬u3›¶_;ºFcñøÎ¥ÕÒQWÊR“оR”ˆ«å)HоR”ˆ«ìûvÿnÝð®ß>¯ðWJDUò”¤E_)JDUò”¤E_)JDUò³¹›uãû)Ög;êU]"*ùYÝ»}»+üûqyóˆ}WYøÍÿugVÿ¨vÏøŒ¹E_]c¯fçu©³2u˜¦Rêé8«å)Hо÷ùœßgù“³gâ”üt›d+m—ú”¿ßðþ¾.®’оR”œUö>}Ÿ?ßìoÙŸ°§Î&®”ˆ«ìηøõ)›6=}ÖëR•WY»?åïŽìks¾^£çùóí¿ÆíÝ» nÂ%}t¥'|¥)WÙøÍÿugVÿ¨vÏøŒº2ÿ~vR›3¬çY«e*®³l…m²ÿR—ûþ×ÅÊ*úéYó±êîÆ|¶<óºusоR•ŸnßíÛ¾ÛçÕþâ*úéYóï·ùñùŸ ϾP½õ6g=}ÏüÍ”çvS®QW×Xëù¹Ùjnî£ÝF©–ªºN*ùJR"¯”¥"*ùJͲ6Ûm¶m²¶ØÍªâ*ùJR"¯”¬ønûºó+ýÖ;æøN]\E_)JDUö-òó7|Ëu2ÜKæ]])WÊϲUöëÝk^ï¸w^NíÛíÙ_çÛ‹ÏœCê¹E_)XËýùÙJlγf­”ª¹Å_fÃ6ÙÕ™þ¡ÿ¿âzêéHŠ¾ÏØÏ׎cyëøãù¬u7·Î¼ëßuݾ×WY»?åïŽìks¾^”UõÒ”œUölÆþ¾{ÎVÇcêéHоR”ˆ«åc¯å«nwe¹§s—ÆŸ>üoÆ6äŽoà|îqÙxÓõD¢¯”¥'|¥)WÊR‘|¬ý™_¿¥u÷øBŸ¿¦ï·ûçÇv|+·ùB¿ÕrоR”œUön7oy×¾ë»|#®®”ˆ«å)HŠ¾Ïœß—Žc9ËÜó¹¬u])WÊÍÆíó¯:÷Ýc÷o„uÕ×ÿþHÌÿ)»£~Ï–ÝK?nÂt¢¯¢”¬uìÜîµ6fQî³Ê\⯮”¤E_)JDUò”¤E_)_ºFñÍ™F¿uqÀ{ æTJ*ùJRqWÊR‘|¥+>ÏŸïö7ìÏØSçW×JR"¯”¥gu6Ç­lÙ¹Êî¶R”¸Š¾:þnvZ›»¨÷Qªeª®•ŸöÏöß›övÎ)û ”UõÒ”œUò³}ßo»vâ»nÜr¾â=]"*ùJÿ’5ò÷m÷ìÌëÁÿí¾ý™x]D¢¯”¥'|¥)WØËýkÛÙNaØõóù§Sw3åóØÎz¿<ükWYÜͺñý”ë3ŽÆõ*QW×JRqWÊR‘|¬ùØõw?ã>[yÝNººDUò”¬ÎoÝ|ìÊuÎÇózÕWÌæý×Î̧Q¼ì7­Ut¬eþµíì§0ìzùüÓ¥}u‹~¼Í›2Ýn·Ù•Mòvûï¾}ò÷ÜÝêâ*ùJRqWØ·êÌÙ»­Öêa Ýut¤E_)JDUò”¤E_+;·o·eŸn/>qªéWÊR‘|¥+6¶Î¬Ëÿõýÿ×WÆÏûgûoÍû;gý„ÕÒ‘|¯t°ãÿæq¯™–è[æêõ”Uò”¤â¯”¥fu¾Ç©nù±êÌ·RÔ¸Š¾ºô$köÿo»œ®êWÉ}òΨ¤¢¯³çcÕÜÿŒùlyçu:êë?Ù·û?l/·í‡«~#UÄUö~ÃÏÙ[óûáüí—é¸Ý¾uç^û¬~íðŽºwSlzÖÍ›œ®ëe)K«ˆ«ågìgëÇ1¼õüqüÖ:®“оR”ˆ«å)HоR”ˆ«å)HоR”ˆ«å+7}¿ß>;³á]¿Êþ¦û¾ßvíÅvݸå}ÄyE_>ÉWÛ¯u­{¾áÝx]])8«å)HоR”ˆ«å)YûúñÌo=5Žˆ«ë¥)WÊV³oö~Ø_oÛVüF«ˆ«å+ßô:3ÿŸdº VïŸ SáÕоR”œUö~Ûý¿lvgâ³ý–/íWJDUò”¬ùØõw?ã>[yÝN¸Š¾g7î¾ve:çcù½j«¥gϾßçÇæ|/>ùB÷ÒŠ¾ºR“оÇ^ÍÎëSfeë1L¥ÕÒ‘|¥)WÙÜͺñý”ë3ŽÆõ*®³:ßãÔ¦lØõ÷[­JUÚ&ÀÇým·Ì0¶éü¬ŒŸß¥z»v¢*þ ¬´”P-9f~–Bþ=þdz~±ÇÞð PÜIÉÅt²zñ3d'–5$Ä |ŽJèNÛî½Ô!€œ  š ÂZ’¹(oü '›|R]nÉNètîRµÏ¶ª¯ùYE 5(NNçt}÷Ê“f7õóØÞr¶8ìk}© ;90I8˜Wå à ä´wJwGı¿¤få'¤¤Œ}c&�í($,LÄÄg %pÄŒ%Œ�´²œ…Æt’¾åtöͨgø£b¯ùÛ?ÛgïÅöÙøõm„j»édÀ ÒX²’PÞ‘»§$gC•±_5%|‚‘ºRžžÛl÷ÀW�ï °.´>|‘‹á8nb¸Î‡Ø°×»Û}*¿ÉR³wÛýóã»>Ûü¡_껢U|¥fu¿Ç©LÙ±ëî·Z”ª¸Š¾R•›ä¯}×ò–½Ûàî®."¯®”¤E_)JDUò”¤E_+7qçü½ñÝ`îwËÕtˆ«å)HоR•›d+m—ú”¿ßðþ¾."¯®±o•™»÷[©”Â_ºªéWÙ»íþùñÝŸ íþP¯õ])WÊV³oö~Ø_oÛVüF«ˆ«å)HоR”ˆ«ìuüÜìµ7wQî£TËU])WÊÏòþËÙj_í°VWv€vX¸FNûÃe§wûoÊ3¥Šu'ç§E_ÞØ Ò‚‹AC &ì–ñ)%²z{“÷GÈÿýËCæ]ôD†††”LbɈ@ÒØ„^OKâÖBH`ÞQhC flܤ>k˜C Ü °Üœ–Ô¾ J ZCr6ÉJSƒF#’2ÙwÌ@¡ ŠB ÝoÉI_GìÛ}Æm³îÎ7¯ÿßûÌÂAº¿º�(M(–Ô†€Ôâò0`Î7d0o݆–t¡”•ï¯$€ÄÓÐøoŸ³ÈvÏûöÙúýFÌoëç±¼ålqØÖ>®ô?¦¯ÐJ@ÂPÌ1† l1™™ŽfSWâfBŠ)‘Æ£ ÌŽ{ìͺÏÖ Vò«þ€pÒ¹H„'« ˜„°Â¾ÛnÛ”KéFFÈF=ïhi3/`09/0jF¡ö,½ñ( ý-“Š%¥#v¾k,¬›»:ñŸÐßt}þûáymîLšªÿr`*”àÎ’o-!¼½Šä¬ÈÝI@ ÿ’ºÜgå~œƒ/ ŒéÅý›§6t¡Ií•—»ã:¯¢PQ\0™ñ,´$­¿Ý-Ê èÛü;²Kê ß#ïûÎb,´MbÊí‰_#”âYcC2Ôß~’Ý=œ6Žj”üêÿ–Ò”½ *ùY»¹êìwÆn§<óòUtˆ«å)HоR•ÔÛµ³fç+ºÙJRâ*úéJDUò”¤E_fÃ6ÙÕ™þ¡ÿ¿âzêéHоÇ_ÍÎËSwuê5LµS9»eó»©Ôf?Œê]]%|¥+?mþß¶;3ñYþËöœUõÖ|ìz»ŸñŸ-<î§]]"*ùJR"¯”¥"*ùJR"¯”¥"*ù}Hᥤ5=¨Ãql€Í’RCP”|ÅâÑ›òЭ|á?’XÏþBÆgJräaçöÃý÷`+ú@cІä$ò†d%žÒ–Å!(OJdFÉ(þÚáÕUÿ:1D £–J Nl͒Ĥÿó -@Þå!쌎ÿ6׃½€’‚öBHH!%ô ¤ï›²JÈ9(ÀeòÐ4ö¼}·|o•_)J]«å)HоR”ˆ«ìûvÿnÝð®ß>¯ð},2€v€½{'äˆdô%$5±E3§Æõá»_0»ÀT¤ô~QIOÃ8×û”Ãbùù=?^ßÜù§WëBB6ã¾£zI‰û ¤tîJG-/öß ¥ü…}ykè„"ja©%~œÀa�9Q[°Üÿ¹}ñ¨|‘…n”$ûçpÑWÙ³úùìo9[v5«¬ýŒýxæ7ž¿Ž?šÇUÛʯ”¥'}Û·Û²¿Ï·Ÿ8‡Õt¤E_)YöíþÝ»á]¾|9_á®"¯•™Öû¥»æÇ«2ÝKRêéWÙ³ýû/ìÛñYûW^ÛlÌÙæÛwÌö^j‰E_)JN*ùJR"¯”¬Û#m¶ÛfÛ+mŒÚ®"¯”¥"*ùJÆÏûgûoÍû;gý„ÕÄUò”¤E_)JDUúÃA_££%™T½HÝ–¾ÙK}”a4¤†X¬S¥%ô$4#t$ ålÉÜ5¼jþIiî›á÷ÖÈdÀ @béÅ ÷Ii`ÜVܲƒP0´l‹û:°†é_Úâ ª¯ùÐà Å7ج„a¤–Å öÙgÒ…eÉ»À0&”M)Ê4'âWCÿNÜü5»öë|“¾¸7O>U|¥)i*¾R”ˆ«å)Hо]bf&äŸÆ'ü²BpÄ„t¡º3·ýÖà ¹7\†‡B{d©Y(Œ¯“ò6éOèÿ Ü$ìÏý´êÿ¡Œ ;&'”ŒRpf á…biIBä vÈ;”žãF7×Î „½™==[îœVë=•ÛôsvÙ¾g_½À›wÝðÖàT–ŒKéIKG AHÅÉ,“Ý\n÷Î3¶¿eý›~+?l)ýËÀÒÕ:¾ºR—m5|¥)WÊR‘}Ž¿›–¦îê=Ôj™j«¥"*ùJR"¯”¥gÛ·ûvï…vùðå„xоºVnû¾|wg»”+ýMÜyÿ/|wcX;òô¢¯®”¤â¯”¥"*ûùY›¿uº™L%ûªŸdï¾ß|ßu﹟UÖglÿ~Ëû6üV~ÂÊ*úéJN*ùJÇϳçûýû3öùÄÕÄUò±o—™»æ[©–â_2êë?Ù·û?l/·í‡«~#J*úï«€„1;¡*% ²’4Î_ /9}ˆÄŒ¸NÙ ,#ß,ùØõw?ã>[yÝN¹ÒR Ì”då«íÏßsÇïðe§WûP �¯¤¿¶(c`Ò¾ù8›É?a¿ ®fgéúϼQIÅ¡ Ç'o—¹ùÏGû‡¯¼§P ©È(b , g,¢†ô†7%d†ï¿GÀ`®y]/¶kóý‡iÕò”¥ÛM_)JDUò”¤E_/J²ÃIÊG,–0¬1±ÿ~‚YH÷û¥ÐÝñÒR& ût¤¤oÐéÈÈOî”ü„åb“Ý¿Seõß@pÀ*Ê/†§` 2>eòN,i_Ÿ¶è% èAeüŒ›eÕWñ@:øðf|ŒÈá¿d¥,è A[М„ò:¿èN¾xÙÿlÿmù¿gl⟰›Ñ�±IFä„·@Á˜3ô#ò¶Êùûïº_rO>ó6ŸÊ¯”¥gu7Ç­Nù¹Ë̶ZÔ«¢U}t¥"*ùJW§ÑÝ›¿=jù•ö5×¾ë”UôR”œUò”¤E_gÎËù¸¥««¾âTÝõ])WÊR‘|¥)WÊR‘|¥)WÙoñêS6lzû­Ö¥*®”ˆ«å)HŠ¾Í¶¶Ïß‹í³ñêÛÕt¤E_)JDUþ˜ 0A~·}›’ñC~GB~GZÃB°×Ù¯«ÐBH!”¡©®B/~ŸŸ¿Ihù1D´ä Á!>øÓ,¤¥™9±y?%;í‰ï–ÉÉòE*ãÞª¿¼P!‰Kqˆd9–†Cÿ·ÎÃJìù*ì’»ªò¨HÜê=9]ò¿Ç¶Z—Œï¯ ÀLž4´ M! 4˜œ7ätÝÆ:Kß q™Ðûœ÷´!@0JH]º /¹JÿâÞÄÏþOd픫>ÿ¦Ïçcøp_ð:^×€òÑÃP8g(-»§~0¼Z2@ˆ_³äë´p @,,1äŒü —žR8?ã w)?~ÏËݽ¾ÔÕÿ0ºa¤ÔËOÈ)ét6Ï•™ûöÛ»çUô„�Ä4¾3p ¾G!Éeì–)6@gNKlÿ”‚^%íÑcH»“ˆÿ—ŠF(1r_-rjZJbœd`ù-þ -fίÎM,²j@Ài1,‚ÑœûöJrXpŒÉ£] B7{8 I×+�¥hèÈOà÷á¼¢XfJ2ßtà…)®)0 #àÂÓ‹ýRKé%•ƒrЗOŽYÙ±ùîßý÷o”·ù¿Î­övÍ¿8/KóÎO}™C#}·ûnù›õmÌL¦fSY+>}öÿ>?3áy÷ʾ«»)«å)Xëù¹Ùjnî£ÝF©–©Å_])HоR”ˆ«å)HоR”ˆ«ìØfÛ:³/ÿÔ?÷üO]])WÊÍÆíó¯:÷Ýc÷o„uÕÒ"¯”¥"*ùJR"¯”¥"*ùJR"¯•›3¯÷┬¬Û [÷õu›¾ßïŸÙð®ßå ÿJ*úéJN*û6açþ¿ùýÍpìvÊÕt¤E_)Xùö|ÿ±¿f~Ÿ8š¸Š¾Ï²wßo¾oº÷ÜÏ­à 3~ÿ¿~¿ÑÝfî„0¶ms)KÅ_î0ÁŒßfGI[þŽœœ‘ÈG+÷tr†-Ñ‘ÝîaE ½Šå¾ }ÊA+^û¡¹Yþ)jòзg¼Õ,žu¡H -† 3¾Ã@¶û§'¥öONÏÒ[«§$ªää9C ø·ß%öÛ¹ù–£6ïØÿê>ÉWÛ¯u­{¾áÝx]]n:*ùJRÒU}›3¯÷┬¬Û [÷õt¤E_)JDUò±×òÕ·;²ÜÓ¹ËÇãO«¤E_)JDUò”¤E_)JDUò”¤E_+3¶¿eý›~+?aêéWÊV}“¾û}ó}×¾æ}WWÊR‘}Ÿ>ûŸ™ð¼ûå ßUÒ³9»eó»©Ôf?Œê\¢¯®”¤â¯”¥fÌ<ÿ×ÿ?¹®ŽÙZ"¯q»ç@JÙ_nØ!nj¹µÔÛµ³fç+ºÙJRêå|¥)8«å)HоÇϳçûýû3öùÄÑo—™»æ[©–â_2éöíþÝ»á]¾|9_á®QWÊÏWsþ3å±çÔ뫤⯳ý›³öÂû~Øz·â5]+;·o·eŸn/>q¥}t¥'|¥)WÊR‘|¥)WÊR‘|¥)WÊV:þZ¶çv[šw9xüiõq|¬ÝÇŸò÷Çv5ƒ¹ß/UÖl3mY—ÿêûþ'®QW¾ù¥ÿVý·OÙÌÛ;oÕª)^Ÿ÷Fg~Üõ+÷VøÆ_Ø[ª"¯¢”¤â¯•›3¯÷┬¬Û [÷õtˆ«å)HоV~3ÝYÕ¿ê³þ#.Û¶ß²·í¿Û°–õrоR”œUò”¤E_)oè/§„¶ù;3>ücuäïðOue·G>Á(«ìηØõ-ß6=Y–êZ—O—óqKWW}Ä©»êºDUò”¬ßwÛîݸ®Û·¯¸8«ë¥)WÊR‘|¥)WÊR³:ßcÔ·|Øõf[©j\E_])HоR³q»|ëν÷XýÛáuq��·����������������������������./saods9/doc/install.html���������������������������������������������������������������������������0000644�0001750�0001750�00000004544�11425634103�014212� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> <title>DS9 Installation Instructions</title> </head> <body> <h3> <img alt="" src="sun.gif" height="98" width="100" align="middle"> SAOImage DS9 Installation Instructions <a href="#windows"></a><br> </h3> <blockquote> <blockquote> <p><b>Solaris / Linux Installation</b></p> DS9 for Solaris and Linux is a self contained application and does not require any installation procedures or support files.<br> <ol> <li>Download DS9. This is a gzip'ed tar file.<br> </li> <li>Use the following command line to extract DS9: <br> </li> <tt>$ gzcat ds9.&lt;port&gt;.&lt;version&gt;.tar.gz | tar -xvf -</tt> <li>Move the DS9 executable into a directory in your path.</li> </ol> <p><b>MacOSX</b></p> There are versions of DS9 for 10.4 (Tiger) and 10.5 (Leopard)<br> </blockquote> <blockquote> <ol> <li> Download DS9 for MacOSX. This is an universal application that contains binaries for both PPC and Intel Macs. Drag to your Applications folder.<br> </li> </ol> <p><b>Darwin</b></p> There are versions of DS9 for 10.4 (Tiger) and 10.5 (Leopard). Darwin is only recommended for experienced users of unix and linux. For other users, we recommend DS9 for MacOSX.<br> <br> DS9 Darwin requires X11.&nbsp; DS9 for Darwin is a unix executable and must be run from the command line of a Terminal window.<br> <ol> <li>Download DS9 for Darwin. This is a gzip'ed tar file.</li> <li>Open a Terminal window.</li> <li>Use the following command line to extract DS9: <br> </li> <tt>$ gzcat ds9.darwin&lt;arch&gt;.&lt;version&gt;.tar.gz | tar -xvf -</tt> <li>(Optional) Move the DS9 executable into a directory in your path.<br> </li> </ol> <p><b>Windows 7/Vista/XP</b><br> </p> </blockquote> <blockquote> <ol> <li>Download DS9 for Windows NT/2000/XP. This is a WinZip.exe install file.</li> <li>Execute the install file. DS9 will be installed by default in <tt>C:\Program Files\ds9</tt>. It will contain two files, the DS9 application and cygwin.dll.</li> <li>To run, go to <tt>C:\Program Files\ds9</tt> and double click on the DS9 icon.</li> </ol> </blockquote> </blockquote> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/tutorial.html��������������������������������������������������������������������������0000644�0001750�0001750�00000001603�11231165151�014375� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; SunOS 5.8 sun4u) [Netscape]"> <title>SAOImage: Tutorials</title> </head> <body style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);" alink="#ff0000" link="#0000ee" vlink="#551a8b"> <h2> <img src="sun.gif" alt="" align="middle" height="98" width="100"> SAOImage DS9: Tutorials<br> </h2> <blockquote>Below is a list of instructional tutorials which are currently available. This list is updated regularly as new material becomes available.<br> <br> <a href="http://www.cfa.harvard.edu/dvlwrap/special/ds9/May52009.ram"><b>Exploring Advanced Features of SAOImage DS9</b></a><br> <i>CFA Head Lunch Talk: May 5, 2009</i><br> <br> </blockquote> <br> </body> </html> �����������������������������������������������������������������������������������������������������������������������������./saods9/doc/faq.html�������������������������������������������������������������������������������0000644�0001750�0001750�00000117532�12022164762�013320� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 FAQ</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="sun.gif" height="98" align="middle" width="100"> SAOImage DS9 FAQ</h3> <blockquote> <p>This FAQ is a new, on going project, and it is far from being complete. But as common questions on DS9 are received, the FAQ will be updated. </p> <p><b>Contents</b></p> <blockquote><a href="#Copyright">Copyright</a><br> <a href="#General">General</a><br> <a href="#Fonts">Fonts</a><br> <a href="faq.html#Linux">Linux</a> <br> <a href="faq.html#Windows">Windows</a> <br> <a href="#MacOSX">MacOSX</a><br> <a href="faq.html#X11">X11</a> <br> <a href="#IRAF">IRAF</a> <br> <a href="#Coordinates">Coordinates</a> <br> <a href="#Regions">Regions</a> <br> <a href="#Printing">Printing</a> <br> <a href="#XPA">XPA</a><br> <a href="#VO">VO</a><br> </blockquote> </blockquote> <blockquote> <p> <b><a name="Copyright"></a>Copyright</b></p> <blockquote> <p>SAOImage DS9 is composed of approximately 20 open source packages, all of which are distributed under their own open source license agreements, usually GPL, LGPL, or BSD. In addition, several open source packages have been developed here at the Smithsonian Astrophysical Observatory, Cambridge, MA, USA and are distributed under the terms of the GNU General Public License as published by the Free Software Foundation. As long as you continue to adhere to the provisions of the licenses, you are free to distribute SAOImage DS9 along with your software.</p> <p>The <a href="http://www.gnu.org/copyleft/gpl.html">GNU site</a> contains an excellent FAQ on the the dos and donts of GPL.</p> </blockquote> <p><b><a name="General"></a>General</b></p> <blockquote> <p><b>The web browser, catalog tool, image server, and other Analysis functions don't appear to work. Whats going on?<br> </b></p> <p>For a number of the Analysis functions, DS9 requires temporary disk space to download and store data. By default, this directory is defined by the TMP or TEMP environment variable. This is usually defined as <tt>/tmp</tt> for Linux and MacOSX users. For Windows users, this will vary, depending on which version of Windows you have. In any case, if the temp directory is not writable, or you have specified an invalid directory in the preferences, these functions will fail with a variety of error messages.<br> </p> <p><b>My system admin stripped the DS9 binary and now DS9 fails to start with the following error message:</b></p> <p><tt>Application initialization failed: Can't find a usable tk.tcl in the following directories...</tt></p> <p>DS9 is based on tcl/tk which is a scripting language which requires many support files. To create a stand alone application, we <i>fool</i> tcl/tk into thinking that it has a valid installation. To do this, DS9 is really an application, along with an zip archive attached. The first thing DS9 does is to create a virtual file system in memory and unpack that archive into memory. The application DS9 is already stripped of debugging symbols when built. </p> <p>It appears that the <tt>strip</tt> command is <i>stripping</i> part of the archive, hence DS9 is unable to un-compress it. In summary, don't <tt>strip</tt> the DS9 binary and everything works fine. </p> <p><b>When I open my FITS image, all I see is 'white'. Yet everything, including the color bar seems to work?</b></p> <p>New with version 2.1, is support for the DATASEC keyword. This keyword specifies what portion of the image is valid data, for calculating min / max and for displaying. This is very important for images created from CCDs with over scan and bias strips. By default, this support is enabled. However, a number of fits images with this keyword, have invalid values. Therefor, when DS9 opens the image, it finds no valid data to display. To correct this problem, either disable DATASEC support, via the Scale menu, or correct the the value of DATASEC in the fits header. You can also change the default behavior by disabling DATASEC from the preferences menu.<br> </p> </blockquote> <p> <b><a name="Fonts"></a>Fonts</b></p> <blockquote> <p><b>Where is the Symbol Font? How do I enter special characters into an entry dialog?</b> </p> <p>The concept of a separate <tt>SYMBOL</tt> font is no longer implemented with the latest OS font and scripting support, especially with scalable anti-alias fonts such as Xft for Linux. Most newer fonts (if not all) now have greek characters as part of the font. The greek chars start at unicode \u0391 for 'A' and \u03b1 for 'a'. Each OS has a tool used to build and copy a string of characters. Then use the Edit:Paste menu of DS9 to insert the character string.</p> <p>Linux- Gnome: <b>gucharmap<br> </b>Linux- KDE: <b>kcharselect<br> </b>MacOSX: <b>Character Viewer</b> (Select <tt>Edit:Special Characters</tt>) Now click and drag the characters to a terminal window. Then select the string and select <tt>Edit:Copy</tt>.<br> Windows: <b>Character Map</b> (from <tt>Start</tt> button, select <tt>All Programs</tt>, <tt>Accessories</tt>, <tt>System Tools</tt> and then <tt>Character Map</tt>)<br> </p> </blockquote> <p> <b><a name="Linux"></a>Linux</b></p> <blockquote> <p><b>My /tmp directory is mounted -noexec and bin table filtering does not work.</b></p> <p>Set the environment variable FILTER_TMPDIR to a directory that is both writable and can execute.<br> </p> <p><b>I have Red Hat 7, and I'm running KDE. The magnifier keeps going blank after a few seconds, what's going on?</b> </p> <p>The problem was in KDE. If the user has decided to hide the panel taskbar and&nbsp; sets a delay time for when it appears if the mouse is moved to the panel&nbsp; location, then it appears that KDE creates mouse events that fool DS9 into&nbsp; thinking the mouse is outside and it blanks the magnifier. By turning off the&nbsp; hide panel, the effect goes away. The alternative is to update to KDE2.1Beta&nbsp; where this method of dealing with the hidden panel is not used and all is&nbsp; well, as it was for KDE </p> <p><b>I have FreeBSD. When I run ds9, I get the following error:</b> <tt>&nbsp; <b>ELF binary type "0" not known</b> </tt><b>Whats going on?</b></p> <p>The solution was to use the <b><tt>brandelf</tt></b> utility on the file to ensure that the machine understood that it &nbsp;was a Linux program.</p> <p><tt>% brandelf -t Linux (file name)<br> </tt></p> <blockquote> </blockquote> </blockquote> <p> <b><a name="Windows"></a>Windows</b></p> <blockquote> <p><b>When I do Save Image, I get the same result (and this is true for either .gif, .jpeg, .tiff, .png and .ppm) : it saves only a stripe at the top of my image.<br> </b></p> <p>This problem seems to be caused by running DS9 in Windows XP compatibility mode. Please un-check the compatibility option in the properties dialog.<br> </p> <p><b>How can I open a FITS file with an extension name?</b></p> <p><b> </b>By default, the windows port of DS9 uses the Windows standard dialog box to open and save files. This can be a problem in that the native Windows dialog will not allow extensions to the file name, such as <tt>foo.fits[2]</tt>. You must use the Unix like standard dialogs to be able to specify an extension. Select <tt>Edit-&gt;Preferences-&gt;General:Dialogbox</tt> to change the default standard dialog.</p> <p><b>Every time I create an auxiliary window in ds9, such as a Pixel Table, or Analysis Plot, it will retreat behind the main ds9 window. Then, when I bring the auxiliary window to the front and move the mouse out of it, it automatically goes behind the main ds9 window again. What can I do to fix things so that the auxiliary window stays on top of the ds9 window?</b> </p> <p>To fix things so that the auxiliary window stays on top of the ds9 window, do the following: </p> <blockquote> <p><tt>Go to the icon task bar at the bottom of the screen.</tt><tt> Bring the auxiliary window to the front by clicking on its icon in the icon task bar.</tt><tt> While the mouse still is on the aux window icon, press the mouse button, and keeping it pressed, move the mouse off the task bar.</tt><tt> Release the mouse while off the task bar.</tt><tt> The auxiliary window will now stay on top of the main ds9 window.</tt></p> <blockquote> </blockquote> </blockquote> </blockquote> <p><b><a name="MacOSX"></a>MacOSX</b><br> </p> <blockquote> <p><b>I can't invoke the 'Save Image' function from the MacOSX X11 version. I get an error message "An error has occurred while creating the image. Please make sure entire image is visible on screen."<br> </b></p> Up until MacOSX 10.8 (Mountain Lion), Apple provided their own version of a X11 server. At first, it was based on XFree86 (X11R6.6) and available with versions up to MacOSX 10.4. Later with MacOSX versions 10.5 to 10.7, the Apple's X11 server was based upon X.org (X11R7.2). <br> <br> The Apple version of X11 server for MacOSX 10.5 to 10.7 contains a bug which fails if you invoke certain X11 calls on a window if its location is not at 0,0 on the screen. Hence, within DS9, if you 'Save Image' and your window is not exactly in the upper left corner, it will fail.<br> <br> Again, this only affects users of MacOSX 10.5 to 10.7.<br> <br> Starting with MacOSX 10.8, Apple no longer provides a X11 window server. The user must go to the XQuartz site and download/install directly. The current version is 2.7.3.<br> <p><b>When I invoke DS9 MacOSX Aqua from the command line, I get weird errors such as<tt>:</tt></b></p> <blockquote> <p><tt>The document "foo.fits" could not be opened. SAOImage DS9 cannot open files in the "Flexible Image Transport System" format.</tt></p> </blockquote> <p><b><tt> </tt></b>When opening MacOSX Aqua from the command line, it is better to use the <tt>OPEN</tt> application as opposed to specifying the binary directly. The <tt>OPEN</tt> application sets up the environment just as it is when a user double clicks.</p> <tt> # good</tt><br> <tt>% open /Applications/SAOImage\ DS9.app foo.fits<br> <br> # bad<br> % /Applications/SAOImage\ DS9.app/Contents/MacOS/ds9 bar.fits</tt><br> <p><b>How can I open a FITS file with an extension name?</b></p> <p><b> </b>By default, DS9 MacOSX Aqua uses the MacOSX standard dialog box to open and save files. This can be a problem in that the native MacOSX dialog will not allow extensions to the file name, such as <tt>foo.fits[2]</tt>. You must use the Unix like standard dialogs to be able to specify an extension. Select <tt>Edit-&gt;Preferences-&gt;General</tt> to change the default standard dialog.</p> <p><b>How do I set my PATH environment variable under MacOSX for use with external analysis programs, such as funtools?<br> </b></p> <p>When you double click on a MacOSX application, it does not parse any shell startup files, such as ~/.profile. Instead, the environment is defined using a special environment file, <tt>.MacOSX/environment.plist</tt>. This file can be created with the MacOSX utility <tt>/Developer/Applications/PropertyListEditor.app. </tt>For further information, please click <a href="http://developer.apple.com/qa/qa2001/qa1067.html">here</a>.<br> </p> <blockquote> </blockquote> </blockquote> <p> <b><a name="X11"></a>X11</b><br> </p> <blockquote> <p><b>Is it possible to work in batch mode without a physical display?<br> </b></p> <p>DS9 is written as an interactive, window client program, and as a result, does require a window server to be available for rendering (X11, Windows, or MacOSX).<br> <br> Therefore, using DS9 as a batch process can be cumbersome. We recommend using <tt>xvfb</tt> under X11. Just set up a virtual display buffer, reset your DISPLAY variable, then invoke DS9 with a number of command line options or use xpa from a shell script as a batch processor.</p> <p><b>When I start DS9, I get the following error message:</b></p> <tt>_X11TransSocketINETConnect: Can't get address for foo.bar.edu </tt><br> <tt>couldn't connect to display "foo.bar.edu:0.0"</tt> &nbsp; <br> <p>DS9 is unable to determine a valid X11 Display server, because of a number of reasons. Most often this is seen when you have a laptop configured for a network, but is not physically connected. You need to set the DISPLAY environment variable to :0.0 </p> <blockquote><tt>$ xhost + </tt><br> <tt>$ set DISPLAY=:0.0 </tt><br> <tt>$ export DISPLAY </tt><br> </blockquote> <p><b>Under Solaris, when I start DS9, my twm window manager crashes!</b></p> <p>TWM distributed with X11R5 had a major bug, that was corrected around 1996. DS9 will trigger this bug, and will cause TWM to crash. If you are running Solaris, and have X11R5 installed, be sure that /usr/openwin/bin is in your path before X11R5/bin. This will insure that you are running the correct version of TWM . </p> <p><b>When I run ds9 with the tvtwm window manager, sometimes the open file dialog box does not appear?</b> </p> <p>If you are running tvtwm, and you are currently viewing a virtual screen other than the first, when you open a file, the dialog box will appear in the first virtual screen, not your current. This is a bug with tvtwm and not ds9.</p> </blockquote> <blockquote> <p> </p> </blockquote> </blockquote> <blockquote> <p><b><a name="IRAF"></a>IRAF</b></p> </blockquote> <blockquote> <blockquote> <blockquote> <blockquote> </blockquote> </blockquote> <p><b>I can't use more than 9 frames with the IMEXAMINE task?</b><br> </p> <p>The task <tt>IMEXAMINE</tt> can not be used with frame numbers greater than 9.</p> <p><b>Can I display from IRAF to DS9 running under Windows or MacOSX?</b> </p> <p>Yes, DS9 for Windows and MacOSX is also a fully functional IRAF display server. To direct image output from IRAF to DS9 running under Windows or MacOSX, use the IMTDEV environment variable. For example, if the machine is named 'foo.bar.edu', define IMTDEV to the follow value before entering IRAF. </p> <blockquote><tt>$ setenv IMTDEV inet:5137:foo.bar.edu </tt><br> <tt>$ cl </tt><br> <tt>cl&gt; display dev$pix</tt><br> </blockquote> <blockquote> <blockquote> </blockquote> </blockquote> <p><b>I'm having problems with </b><b>mscred task </b><b>msczero?</b></p> DS9 now supports IRAF's new IIS image display protocol. However, there is one minor problem with the <b>mscred</b> task <b>msczero.</b> Before using <b>msczero</b>, issue the following command in the cl:<br> <br> <tt>cl&gt; set disable_wcs_maps=""<br> cl&gt; flpr</tt><br> <p><b>I find that there is a frustrating delay in performing operations on images displayed from IRAF - there's a wait of a second or two before an image is (re)displayed, whereas <i>saoimage</i> reacts virtually instantly for the same type of operation. This makes running imexamine on a batch of images a pain, and using the mouse to change color gamma/bias to desired values basically impossible.</b> </p> <p>DS9 and <i>saoimage</i> are similar in speed when working with IRAF. In fact, DS9 uses&nbsp; the same code to interface with IRAF as saoimage and ximtool. The only&nbsp; difference is that DS9 is double buffered, whereas, <i>saoimage</i> and <i>ximtool</i> only&nbsp; use a single buffer. So with <i>saoimage</i> and <i>ximtool</i>, you see incremental progress,&nbsp; where DS9 will render the image all at one time. However, the overall time to&nbsp; finish rendering should almost be the same. </p> <p>DS9 runs in both 8 bit and 24 bit environments, but <i>saoimage</i> is restricted to 8 bit. If you are running DS9 and <i>saoimage</i> at the same time, then you must be in 8 bit mode. You should not see any&nbsp; delay in changing the color bias/contrast between the two. </p> <p>However, if you are running DS9 in 24 bit mode, then you will see slower&nbsp; performance in changing the bias/contrast, as compared to 8 bit mode. Instead of&nbsp; changing a color look up table, as in 8 bit mode, DS9 has to update every pixel&nbsp; on the screen. If your cpu speed is slow, you can select the&nbsp; Edit:Preferences:True Colorbar to tell DS9 not to update the entire screen,&nbsp; only a part of the screen. This should only be needed if your machine is slower&nbsp; than 200 MHz. Again <i>saoimage</i> does not even run in 24 bit mode, so there are no&nbsp; comparisons. </p> <p><b>I try to display an image from IRAF and I get the following error message:</b></p> <p><tt>Cannot open device (node!imtool,,512,512)</tt></p> <p> </p> <p>DS9 works the same way as <tt>ximtool,</tt> <tt>saoimage,</tt> and <tt>saotng.</tt> No special scripts&nbsp; should be needed. If you have one of the above currently working, DS9 should&nbsp; work <i>out of the box</i>. </p> <p>IRAF can use one of three methods to communicate with DS9: fifo, socket, and unix&nbsp; domain name. The DS9 defaults are:</p> <blockquote><tt>fifo /dev/imt1</tt> <br> <tt>port 5137</tt> <br> <tt>unix /tmp/.IMT%d</tt> </blockquote> <p>If your IRAF configuration is set up different (i.e., a different port number, or&nbsp; via a fifo), you need to tell DS9 how to communicate with iraf. DS9 uses the same&nbsp; command line options as XIMTOOL: </p> <blockquote><tt>-fifo </tt> <br> <tt> -fifo_only </tt><br> <tt> -inet_only </tt> <br> <tt> -port </tt> <br> <tt> -port_only </tt> <br> <tt> -unix </tt> <br> <tt> -unix_only </tt> </blockquote> </blockquote> </blockquote> <blockquote> </blockquote> <blockquote> <blockquote> <p><b>I try to display an image, I see something, but it's corrupted and I get multiple error messages from DS9...</b></p> <p><b> </b>An IRAF image server (<i>ximtool</i>, <i>saoimage</i>, DS9, etc...) uses a configuration file&nbsp; to specify the number of available buffers and their sizes. What actually passes&nbsp; from IRAF is not the buffer size, but an index number into this file. </p> <p>So when an image server starts (DS9), it will attempt to locate this file as&nbsp; $HOME/.imtoolrc and /usr/local/lib/imtoolrc. If not found, it will look for shell&nbsp; environment variables IMTOOLRC and imtoolrc, that contains the name of the configuration file. </p> <p>If no configuration file is found, DS9 will assume the following default configuration: </p> <blockquote><tt>&nbsp;1&nbsp; 2&nbsp; 512&nbsp; 512&nbsp; # imt1|imt512 </tt><br> <tt>&nbsp;2&nbsp; 2&nbsp; 800&nbsp; 800&nbsp; # imt2|imt800 </tt><br> <tt>&nbsp;3&nbsp; 2 1024 1024&nbsp; # imt3|imt1024 </tt><br> <tt>&nbsp;4&nbsp; 1 1600 1600&nbsp; # imt4|imt1600 </tt><br> <tt>&nbsp;5&nbsp; 1 2048 2048&nbsp; # imt5|imt2048 </tt><br> <tt>&nbsp;6&nbsp; 1 4096 4096&nbsp; # imt6|imt4096 </tt><br> <tt>&nbsp;7&nbsp; 1 8192 8192&nbsp; # imt7|imt8192 </tt><br> <tt>&nbsp;8&nbsp; 1 1024 4096&nbsp; # imt8|imt1x4 </tt><br> <tt>&nbsp;9&nbsp; 2 1144&nbsp; 880&nbsp; # imt9|imtfs full screen (1152x900 minus frame) </tt><br> <tt>10&nbsp; 2 1144&nbsp; 764&nbsp; # imt10|imtfs35 full screen at 35mm film aspect ratio </tt><br> <tt>11&nbsp; 2&nbsp; 128&nbsp; 128&nbsp; # imt11|imt128 </tt><br> <tt>12&nbsp; 2&nbsp; 256&nbsp; 256&nbsp; # imt12|imt256 </tt><br> <tt>13&nbsp; 2&nbsp; 128 1056&nbsp; # imt13|imttall128 tall &amp; narrow for spectro. </tt><br> <tt>14&nbsp; 2&nbsp; 256 1056&nbsp; # imt14|imttall256 tall &amp; wider for spectro. </tt><br> <tt>15&nbsp; 2 1056&nbsp; 128&nbsp; # imt15|imtwide128 wide &amp; thin for spectro. </tt><br> <tt>16&nbsp; 2 1056&nbsp; 256&nbsp; # imt16|imtwide256 wide &amp; fatter for spectro. </tt><br> <tt>17&nbsp; 2 1008&nbsp; 648&nbsp; # imt17|imtssy Solitaire fmt w/ imtool border </tt><br> <tt>18&nbsp; 2 1024&nbsp; 680&nbsp; # imt18|imtssn Solitaire fmt w/out imtool border </tt><br> <tt>19&nbsp; 1 4096 1024&nbsp; # imt19|imt4x1</tt><br> </blockquote> <p>If on the other hand, IRAF assumes a different buffer size, the image will appear corrupted and DS9 may issue a number of error messages. </p> <p>Another problem is that this file must be in sync with dev$graphcap. If your&nbsp; system administrator has made changes to graphcap, they must also be implemented in imtoolrc. </p> <p>Here is a note from NOAO: </p> <blockquote> <p><tt>The messages means that there is no /usr/local/lib/imtoolrc file </tt><tt>on the machine. This is created as a symlink to dev$imtoolrc by the </tt><tt>iraf install script but only if the /usr/local/lib dir already exists on the </tt><tt>machine. The fix is the create the dir and rerun the install script or </tt><tt>else make the link by hand.&nbsp; Users can also just copy dev$imtoolrc </tt><tt>to $HOME/.imtoolrc and restart the server to also workaround it. Note </tt><tt>that an existing .imtoolrc might define old frame buffer configs which </tt><tt>might confuse things, so if the system file exists check for a private </tt><tt>copy screwing things up. </tt></p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <p><b>Where do I find this .imtoolrc file?</b> </p> <p>Again, here a note from NOAO concerning this issue: </p> <blockquote> <p><tt>In a smooth installation the imtoolrc file is installed as a </tt><tt>/usr/local/lib/imtoolrc symlink pointing to the dev$imtoolrc file in the </tt><tt>iraf system.&nbsp; This is normally what's used but XImtool (and DS9?) also </tt><tt>allow a $HOME/.imtoolrc and IMTOOLRC environment variable defining the </tt><tt>path as fallbacks.&nbsp; There are several practical problems with&nbsp; this:&nbsp; for </tt><tt>some reason (I'm trying to fix) the imtoolrc link won't be created if </tt><tt>the /usr/local/lib directory doesn't exist when the install script is </tt><tt>run on the machine, even though it's run as root and the file can be </tt><tt>directory easily.&nbsp; On PC-IRAF systems there is also a typo in the install </tt><tt>script (extra logical or at line 515) which causes it to exit before </tt><tt>the display setup is run (i.e. no /dev fifos or imtoolrc). If users don't </tt><tt>catch this or see it in the README file they'll think everything went </tt><tt>fine. Lastly, the local iraf admin might not have run the install script </tt><tt>on the local iraf NFS client machine at all.</tt></p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <p><b>When I display an image from IRAF, the SCALE menu option is not active, Why?</b> </p> <p>When you display an image from IRAF into DS9, IRAF actually does the color scale&nbsp; distribution. In Display, use the ztrans and z1,z2 parameters to set the upper/lower bounds and distribution. You can also use the zscale parameter to auto determine z1,z2.Here are the DISPLAY parameters in question: </p> <blockquote><tt>ztrans=[linear|log|none|user] </tt><br> <tt>z1=min </tt><br> <tt>z2=max </tt><br> <tt>zscale=[yes|no]</tt></blockquote> <p>What actually is sent from IRAF to DS9 is one byte per pixel, values 0-200,&nbsp; which already has applied both the upper and lower clipping bounds and the distribution. So this is why, the SCALE menu is disabled in DS9 when it receives a image from IRAF.</p> </blockquote> </blockquote> <blockquote> <p> <b><a name="Coordinates"></a>Coordinates</b></p> </blockquote> <blockquote> <blockquote> <p><b>Why don't I see PHYSICAL/WCS/WCSA...WCSZ coordinates displayed when I load my image?</b></p> <p>DS9 supports the following coordinate systems: </p> <blockquote><tt>WCS Sky coords (fk4,fk5,icrs,galactic,ecliptic) <br> </tt><tt>WCS Linear coords <br> </tt><tt>Image (also known as Logical) <br> </tt><tt>Physical (also known as CCD)<br> Detector<br> Amplifier &nbsp; </tt><br> </blockquote> <p>DS9 uses the following FITS keywords in the header to define a coordinate system: &nbsp;</p> </blockquote> <center> <table nosave="" border="1" cellpadding="4" width="75%"> <tbody> <tr> <td><b>Coordinate System</b></td> <td><b>Keyword Values</b></td> </tr> <tr nosave=""> <td nosave=""><tt>WCS / WCSA...WCSZ</tt></td> <td><tt>CRVAL,CRPIX,CRDELT,CD... (for images) <br> TCRVL,TCRPX,TCDLT,... (for tables)</tt></td> </tr> <tr> <td><tt>Image</tt></td> <td><tt>none required</tt></td> </tr> <tr> <td><tt>Physical</tt></td> <td><tt>WCSNAMEP='PHYSICAL' or LTMx_x/LTVx</tt></td> </tr> <tr> <td valign="top"><tt>Detector</tt><br> </td> <td valign="top"><tt>DTMx_x/DTVx</tt><br> </td> </tr> <tr> <td valign="top"><tt>Amplifier</tt><br> </td> <td valign="top"><tt>ATMx_x/ATVx</tt><br> </td> </tr> </tbody> </table> </center> <blockquote> <p>If the required keywords are not present, values for those coordinates are not displayed. </p> <p>Note: For PHYSICAL, DS9 will first look for an alternative WCS with WCSNAMEx='PHYSICAL'. If not found, DS9 will then look for the LTMx_x LTVx keywords.</p> </blockquote> </blockquote> <blockquote> <p> <b><a name="Regions"></a>Regions</b></p> <blockquote> <p><b>How do I indicate distance on my printed images?</b>&nbsp; </p> <p>You have two choices, the RULER region and the LINE region. The ruler region is mainly used for interactive measurements. For printed output, use the LINE region to create a distance indicator. In the line region dialog, there is a read-only entry that indicates the length in pixels, degrees, arcmin, or arcsec. Edit to the desired distance and enter the desired label, including ' or ", in the region text labile entry. You have the option of arrows at each end of the line. </p> </blockquote> </blockquote> <blockquote> <p> <b><a name="Printing"></a>Printing</b></p> <blockquote> <p><b>I can make some wonderful color images in DS9 and save them as postscript files that look great, but often when I print them they appear washed out or very different than they do on the screen. My question then is what, if anything, can I do about this?</b> </p> <p>The problem is that you create an image on a display, which is the product of&nbsp; RGB colors (red, green, and blue) and print the image on a printer, which is the&nbsp; product of CMYK colors (cyan, yellow, magenta, and black). Furthermore, every&nbsp; monitor is different in how it will display a certain color, and every printing&nbsp; technology is different in how well it will reproduce that color. And finally,&nbsp; the translation between RGB and CMYK is not symmetric, i.e. its not possible to&nbsp; translate some colors back and forth. </p> <p>It's possible to calibrate your monitor and your printer, to create a&nbsp; translation matrix, to correct for problems outlined above (in the Macintosh&nbsp; world, this is what ColorSync does). The idea is to <i>apply</i> a gamma correction to the output of DS9, so&nbsp; that it will print much more in line with what you expect. To do this you'd need&nbsp; special software and hardware, and its only valid for your monitor and your&nbsp; printer. </p> <p>In summary, its not worth it. Especially in the case of publication, such as ApJ,&nbsp; where you have no idea on what printing technology will be used to reproduce&nbsp; your image. So the only control you have is to calibrate your monitor and to&nbsp; hope for the best. </p> <p>However, there are some <i>rules of thumb </i>that might help. First, printers have a very hard time with <i>blues</i> and <i>purples</i>, as they tend to be washed out. Either avoid these colors, or over compensate these colors.&nbsp;</p> <p>ApJ has a good idea in that you send in both an electronic version and a hard copy of your color image. That way, they can manually adjust the printers to&nbsp; try to match your output.</p> <p><i>NOTE: Even though ApJ requests images in CMYK, we recommend RGB. From personal experience, if you send RGB, the printed results will be closer to the original.</i></p> <p><b>We used DS9 to generate 300 dpi CMYK eps figures, as per the ApJ specifications, but the color scheme on&nbsp; our proofs is wrong.&nbsp; In the proofs, the violet is washed out and looks similar to the black, and the blue is not nearly as intense.</b></p> <p><b> </b>There are two issues here: first,&nbsp; color printers are notorious for failure to reproduce blues and purples correctly. Second,&nbsp; not all colors in RGB space can be reproduced correctly in CMYK space, blues being the prime example. Below is an excerpt from an industry pamphlet:</p> <blockquote> <p><tt>Be aware that it is possible to see colors in RGB that you can't make with CMYK. They are said to be "out of the CMYK color gamut". What happens is that the RGB-to-CMYK translator just gets as close as possible to the appearance of the original and that's as good as it can be. It's something that everyone in the industry puts up with. So it's best to select any colors you use for fonts or other design elements in your layout using CMYK definitions instead of RGB. That way, you will have a better idea of how they will appear in your printed piece. Here's a common example: many programs translate the 100% Blue in RGB into a somewhat purple-looking color in CMYK. We recommend a CMYK value of 100-65-0-0 to get a nice clean blue.<font size="-1"><br> </font></tt></p> </blockquote> <p>For this reason, you may wish to use the RGB color space or colormaps without deep blues and purples, such as <tt>BB</tt> or <tt>Heat.</tt></p> </blockquote> </blockquote> <blockquote> <p> <b><a name="XPA"></a>XPA</b></p> <blockquote> <p><b>How can I use XPA to display from a client machine to DS9 on a server machine?<br> </b></p> <p>Assuming you have direct IP reachability between the machines (i.e. one host can successfully connect() to the other), XPA does allow you to have an XPA-enabled server like DS9 on one machine and a client on another. To make this work, you need to do two things (let's assume DS9 is running on a machine called "server_host" and you want to send xpa commands from "client_host"):<br> </p> <ol> <li>The XPA server program (i.e. DS9) must allow the client host to send XPA commands. Access can be permitted in one of two ways:<br> <ol style="list-style-type: lower-alpha;"> <li>Send the XPA server an acl request by running xpaset on the same host on which the server is running (i.e. on the server_host):<br> <br> <span style="font-family: monospace;">% xpaset -p ds9 -acl client_host +<br> <br> </span></li> <li>For more permanent access, add permissions in ~acls.xpa:<br> <br> <span style="font-family: monospace;">% cat &gt; ~/acls.xpa</span><br style="font-family: monospace;"> <span style="font-family: monospace;">DS9:ds9 client_host +<br> </span><br> You can check the acls for an XPA server using xpaget: <br> <br> <span style="font-family: monospace;">% xpaget ds9 -acl<br> </span><br> </li> </ol> </li> <li>On the client side, the client needs to communicate with the xpansname server program on the server machine to find the XPA server communication info. This also can be done in two ways:<br> <ol style="list-style-type: lower-alpha;"> <li>use the -i [host] switch to override <span style="font-family: monospace;">XPA_NSINET</span> for this execution (The default port is 14285):<br> <span style="font-family: monospace;"><br> % xpaget -i 'server_host:14285<span style="font-family: monospace;">' ds9</span></span><br> <br> </li> <li>Set the <span style="font-family: monospace;">XPA_NSINET</span> variable for more permanent selection of xpans on the server host:<br> <br> <span style="font-family: monospace;">% setenv XPA_NSINET 'server_host:14285'</span><br> </li> </ol> </li> </ol> <p>Once these two setup steps are performed, you should be able to send commands to DS9 and receive data from DS9. You can look at the <a href="http://hea-www.harvard.edu/saord/xpa/acl.html">xpaacl man page</a> for more information.</p> <p><b>I have a laptop, that most of the time, is connected to a network. DS9 runs fine. However, when I'm not connected to a network and I start DS9, it hangs. What's going on?</b></p> <p>&nbsp;DS9 uses XPA for interprocess communication. When DS9 starts, XPA initializes itself. XPA uses either IP sockets or UNIX sockets, based if your machine is configured to connect to the internet. In the case where your machine is configured for the internet, but you are not currently connected, XPA gets very confused. So, you can define a shell variable, XPA_METHOD, that tells XPA which method to use. </p> <p>The following is from the XPA documentation: </p> <blockquote> <p><tt>Determines the socket connection method used by this session of XPA. The choices are: inet (to use INET or Internet-based sockets) and local (unix) (to use UNIX sockets). The default is INET. Using the inet method will allow access from other machines (subject to access controls) but using local will not. Local is most useful for private access and when the machine in question is not connected to the Internet</tt></p> </blockquote> <p>More information is available on XPA shell variables at: <a href="http://hea-www.harvard.edu/RD/xpa/env.html">The XPA Environment</a><br> </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> </p> </blockquote> </blockquote> <blockquote> <p><b><a name="VO"></a>VO</b></p> <blockquote> <p><b>I can't connect to any of the virtual observatories. What do I do now?</b></p> <p>The DS9 help facility now contains a tutorial on how to configure DS9 to by pass network firewalls. See <a href="ref/vo.html">Virtual Observatory Reference</a> for more information.</p> </blockquote> </blockquote> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�013256� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r1.7.html����������������������������������������������������������������������0000644�0001750�0001750�00000007610�10415010755�014647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 1.7 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 1.7 Release Notes</h3> <ul> <h4> <b>Version 1.7.2</b></h4> <ol> <li> <tt>Fixes a rather nasty bug with coordinates.</tt></li> <li> <tt>XPA version 2.b32</tt></li> <br> <tt>example:</tt> <br> <tt>$ ds9&amp;</tt> <br> <tt>$ xpaget DS9 # will list all public access points</tt> <br> <tt>$ xpaset -p DS9 colormap BB # change colormap</tt> <br> <tt>$ xpaset -p DS9 file snr.fits # load a fits file</tt> <br> <tt>$ cat snr.fits | xpaset DS9 fits # load via XPA</tt> <br> <tt>$ cat snr.fits | xpaset DS9 fits foo[key=RAWX,RAWY] # load via XPA</tt> <br> <tt>Note: xpa class and name for ds9</tt> <br> <tt>-- xpa class : 'DS9'</tt> <br> <tt>-- xpa name&nbsp; : 'DS9'</tt> <br> <tt>both class and name are case sensitive</tt> <br> <tt>To specify a different xpa name for this application use the</tt> <br> <tt>-title command line option:</tt> <br> <tt>$ ds9&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # default name of 'DS9'</tt> <br> <tt>$ ds9 -title foo&amp; # name of 'foo'</tt> <br> <tt>$ xpaset -p foo colormap BB # change colormap for 'foo'</tt> <br> <tt>$ xpaset -p :foo colormap A # change colormap for 'foo'</tt> <br> <tt>$ xpaset -p DS9:foo colormap BB # change colormap for 'foo'</tt> <br> <tt>$ xpaset -p DS9: colormap I8 # change colormap for 'DS9 &amp; foo'</tt> <li><tt>fixed bug with zscale and minmax preferences</tt></li> <li> <tt>geometry command line option: $ ds9 -geometry 600x500</tt></li> <br> <tt>Note: this does not include space needed for menus.</tt> <li><tt>default wcs is 'fk5'</tt></li> </ol> <h4> <b>Version 1.7</b></h4> <ol> <li> <tt>new version of Fits I/O library</tt></li> <li> <tt>.Z, .z, and .gz files are supported</tt></li> <br> <tt>example:</tt> <br> <tt>$ ds9 snr.fits.Z</tt> <br> <tt>$ ds9 snr.fits.z</tt> <li><tt>url's are now supported</tt></li> <br> <tt>example:</tt> <br> <tt>$ ds9 ftp://legacy.gsfc.nasa.gov/rosat/data/hri/images/fits/rh100193_img.fits</tt> <br> <tt>$ ds9 http://legacy.gsfc.nasa.gov/FTP/rosat/data/cdrom/vol1/IMAGES/00h/p000s26b.img.Z</tt> <li><tt>fixed some minor problems with Mosaic Images</tt></li> <li> <tt>Support for FITS bin tables</tt></li> <br> <tt>example:</tt> <br> <tt>$ ds9 snr.fits[2] # assume 'X' or 'x' and 'Y' or 'y' column</tt> <br> <tt>$ ds9 snr.fits[EVENTS]</tt> <br> <tt>$ ds9 snr.fits # assumes EVENTS or STDEVT extension</tt> <br> <tt>$ ds9 snr.fits[key=RAWX,RAWY] # bin on RAWX/RAWY column</tt> <li><tt>Backward compatible with Einstein .xpa data for bining</tt></li> <li> <tt>Contours are now supported</tt></li> <br> <tt>You can generate contours for each frame and cut/paste them into other frames. When you paste a contour, you choose which coordinate system to translate the contour into. Obvisously, to paste via WCS, each image must have a valid WCS. Printing of image/contours also is supported.</tt> <br> <tt>The contour algorithm currently implemented is a general purpose algorithm, good for most images. However, there are some issues that make it less than optimal for sparse high energy data. Therefor, next on the list is implemention of the 'Pros Imcontour' algorithm.</tt> <li><tt>Now supports ICRS WCS</tt></li> <li> <tt>Now Uses Tcl/Tk 8.0.4 and BLT 2.4g</tt></li> <li> <tt>Now uses Doug Minks's wcssubs 2.6.</tt></li> </ol> </ul> </body> </html> ������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r7.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000070741�12132042644�014653� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 7 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 7 Release Notes</h3> <ol> <ol> <li><tt>10.18.2010 SCALE: fixed a problem preserve Scale at load.</tt></li> <li><tt>10.18.2010 REGION: add group new, group update, and select invert commands.</tt></li> <li><tt>10.20.2010 TCL/TK: update to version 8.5.9.</tt></li> <li><tt>12.01.2010 FOV: Add HEASARC/Suzaku templates for HXD, XIS, and XRS</tt></li> <li><tt>12.03.2010 CATALOG: fixed a problem when dec is specified as -00:xx:xx for CXC, SIMBAD, SKYBOT, and SKYVIEW</tt></li> <li><tt>12.07.2010 BINNING: update WCS keywords for FITS bintables</tt></li> <li><tt>12.10.2010 GUI: fixed a problem with displaying greek letters under linux.</tt></li> <li><tt>12.24.2010 MOSAIC: fixed a problem introduced with verison 6.1 with wcs mosaics when first segment is flipped.</tt></li> <li><tt>12.24.2010 MOSAIC: removed the FLT_EPSILON fudge factors in calculating mosaic segment matrices.</tt></li> <li><tt>01.04.2011 SOLARIS: fixed a major bug with color allocation.</tt></li> <li><tt>02.03.2011 POSTSCRIPT: all ports now generate identical postscript output (with a minor exception with ast grid numerics).</tt></li> <li><tt>02.03.2011 TEXT: selecting a TEXT region now handles rotated text correctly.</tt></li> <li><tt>02.18.2011 GROUPS: fixed a problem with selecting multiple regions.</tt></li> <li><tt>02.21.2011 PIXELTABLE: fixed two problems with xpa and copy commands.</tt></li> <li><tt>02.28.2011 GUI: add theme options.</tt></li> <li><tt>03.01.2011 TKTABLE: updated to version 2.10.</tt></li> <li><tt>03.03.2011 POSTSCRIPT: add new scale factor.</tt></li> <li><tt>03.02.2011 GUI: all dialogs now use the new ttk widgets (with a few exceptions).</tt></li> <li><tt>03.04.2011 PREFS: add -bg and -nan xpa/command line options.</tt></li> <li><tt>03.14.2011 MOSAIC: added patch from Frank Valdes for default DETSIZE values.</tt></li> <li><tt>03.14.2011 CMAP: add load/save xpa/command line options.</tt></li> <li><tt>03.14.2011 BACKUP: fixed a problem with saved cmaps. Pathname is now relative.</tt></li> <li><tt>03.17.2011 TKIMG: updated to version 1.4.</tt></li> <li><tt>03.17.2011 ZLIB: updated to version 1.2.5</tt></li> <li><tt>03.18.2011 WCSSUBS: updated to version 3.8.2</tt></li> <li><tt>04.05.2011 AST: updated to version 5.6-0</tt></li> <li><tt>04.05.2011 WCS: fixed/improved support for TNX, ZPN, ZPX, CAR.</tt></li> <li><tt>04.25.2011 WCS: use AST for most WCS functions.</tt></li> <li><tt>04.25.2011 SCALE: fix Scale Dialog formating issues.</tt></li> <li><tt>04.26.2011 HELP: All user manual images are now local.</tt></li> <li><tt>04.26.2011 CONTOUR: fixed problem with generating contours with BITPIX=-64.</tt></li> <li><tt>04.26.2011 SMOOTH: now generates BITPIX=-64 image.</tt></li> <li><tt>04.27.2011 SCALE: fixed a problem with setting scale user limits and then loading an image.</tt></li> <li><tt>04.28.2011 EXTERNAL FILE: fixed a problem with macro substitution $filename.</tt></li> <li><tt>04.28.2011 FUNTOOLS: updated to version 1.4.5.</tt></li> <li><tt>04.28.2011 XPA: reinstalled version 2.1.13.</tt></li> <li><tt>05.02.2011 WCS: use AST for all FITS WCS projections and DSS. Use WCSSUBS for TNX, ZPX, SIP, SCAMP, WCSDEP.</tt></li> <li><tt>05.06.2011 WCS: Added additional reverse transformation (thanks Ed Los) for calculation of Panner WCS compass.</tt></li> <li><tt>05.09.2011 GRID: add support for non-standard WCSDEP keyword.</tt></li> <li><tt>05.12.2011 IMGSVR: for all image servers (2mass,dss,first,nvss,skyview) if invoked with no argument, yet dialog has a name or coords, automatically retreive the image.</tt></li> <li><tt>05.12.2011 FITS: External File support- fixed a problem where the channel was not closed after the open pipe cmd was invoked and ds9 would run out of resources.</tt></li> <li><tt>05.13.2011 GUI: enhanced/implemented Match/Lock Crosshairs.</tt></li> <li><tt>05.13.2011 GUI: enhanced/implemented Match/Lock Frames.</tt></li> <li><tt>05.13.2011 GUI: Moved Match Scale/Bin/Colorbar to respective menus.</tt></li> <li><tt>05.16.2011 CONTOUR: fixed a problem with NAN in data.</tt></li> <li><tt>05.17.2011 CATALOG: NED fixed a problem with getURL and added support for in/out sys/sky formats.</tt></li> <li><tt>05.19.2011 CATALOG: SIMBAD added support for in/out sys/sky formats.</tt></li> <li><tt>05.19.2011 CATALOG: CDS added support for in/out sys/sky formats.</tt></li> <li><tt>05.20.2011 COMPOSITE: speed up create/delete composite region with +1000 regions.</tt></li> <li><tt>05.20.2011 WCS: implemented preferred WCS for each frame. All WCS functions use the preferred WCS (i.e. copy/paste/load/save regions, contours, align, match, lock, rgb, cube).</tt></li> <li><tt>05.25.2011 WCSSUBS: updated to version 3.8.3.</tt></li> <li><tt>05.25.2011 AST: updated to version 5.7-0.</tt></li> <li><tt>05.26.2011 WCS: use AST for TNX,ZPX,SCAMP.</tt></li> <li><tt>05.27.2011 REGIONS: if unable to copy/cut/paste in WCS, fall back upon PHYSICAL.</tt></li> <li><tt>05.27.2011 REGIONS: if unable to map coordinates correctly, do not a region.</tt></li> <li><tt>06.03.2011 WCS: added support for xLON/xLAT and xyLN xyLT WCS.</tt></li> <li><tt>06.03.2011 REGIONS: added regions properites commands to xpa,samp, and command line.</tt></li> <li><tt>06.10.2011 HEALPIX: added support for generating an image from a healpix table (both binary and ascii).</tt></li> <li><tt>06.13.2011 WCS: use AST for all WCS including TAN-SIP and WCSDEP.</tt></li> <li><tt>06.16.2011 SAMP: added code to clean up better when DS9 is unable to parse a SAMP hub file.</tt></li> <li><tt>06.16.2011 REGIONS: be sure to return template id when created.</tt></li> <li><tt>06.16.2011 ANALYSIS: added autoload support for analysis files. DS9 will search a list of known dirs for *.ds9, at which DS9 will load the analysis file, and add the path to env(PATH).</tt></li> <li><tt>06.20.2011 RGB: fixed a problem where the calculated wcs rotation between two frames was reset.</tt></li> <li><tt>06.27.2011 REGIONS: fixed a problem the ds9, ciao, and pros regions parser. The parsers will now accept arcmin and arcsec syntax which includes sciencetific notation.</tt></li> <li><tt>07.07.2011 POSTSCRIPT: generate postscipt now uses generic font names reguardless of platform and window manager.</tt></li> <li><tt>07.08.2011 BIN: split mousewheel preferences between zoom and binning. By default, a bin file is zoom'd in/out with the mouse wheel, unless the binning mouse wheel is enabled via the preferences.</tt></li> <li><tt>07.08.2011 GUI: add preference for standard dialog box for order of file types.</tt></li> <li><tt>07.21.2011 GUI: all non-modal dialogs have Edit menu.</tt></li> <li><tt>07.21.2011 DATACUBE: add match/lock slice commands.</tt></li> <li><tt>07.22.2011 AST: updated to version 5.7-2</tt></li> <li><tt>07.22.2011 WCS: speedup generating sexagesimal output</tt></li> <li><tt>07.25.2011 BIN: fixed a problem with the update filter function.</tt></li> <li><tt>07.29.2011 DIALOGS: fixed a problem with the motif dialogbox and selection of the initial directory. Set the code to the same as tkfmbox.tcl.</tt></li> <li><tt>08.22.2011 WCS: if CTYPE is not of known type, assume LINEAR.</tt></li> <li><tt>08.26.2011 PANNER: simplified compass prefs.</tt></li> <li><tt>09.19.2011 WCS: only use A_ and B_ keywords if CTYPE is TAN-SIP. Ignore otherwise.</tt></li> <li><tt>09.26.2011 REGIONS: use ::math::fuzzy for comparisons in basepanda, composite, and convert.</tt></li> <li><tt>09.27.2011 WCSSUBS: updated to version 3.8.4.</tt></li> <li><tt>09.30.2011 REGIONS: implemented M_PI_2, M_TWOMPI constants.</tt></li> <li><tt>09.30.2011 REGIONS: use fuzzy math for degToRad() and radToDeg()</tt></li> <li><tt>10.04.2011 WCS: pass any PV and QV keywords if present, regardless of projection.</tt></li> <li><tt>10.05.2011 AST: updated to version 5.7-3</tt></li> <li><tt>10.24.2011 REGIONS: fixed a problem with angs and PANDA, EPANDA, and BPANDA and copy/paste in FK5. This is related to the fuzzy math changes made earlier.</tt></li> <li><tt>10.25.2011 FITSY++: fixed a problem finding cols by name in bin tables. Previous 'R' would be matched by 'RA'.</tt></li> <li><tt>10.28.2011 HV: remove NED,SIMBAD,ADS,TDC,SKYVIEW,W3BROWSE from ANALYSIS:ARCHIVES menu due to lack of support from sites.</tt></li> <li><tt>10.28.2011 COLORMAP: add colormap server to colormap dialog</tt></li> <li><tt>11.01.2011 PRINT COORDINATES: now uses default skyframe and skyformat (as defined by WCS menu).</tt></li> <li><tt>11.04.2011 SCALE: add asinh() and sinh() scales.</tt></li> <li><tt>11.10.2011 CROP: add new crop commands.</tt></li> <li><tt>12.09.2011 AST: updated to version 6.0-1</tt></li> <li><tt>12.09.2011 CROSSHAIR: fixed an issue with coordinates of crosshair were .5 pixel off in Y.</tt></li> <li><tt>12.09.2011 GUI: fixed an issue with centerimage() was .5 pixel off in Y.</tt></li> <li><tt>12.15.2011 GRID: fixed an issue with text upside down.</tt></li> <li><tt>01.03.2012 BIN: fixed a problem with depth of a 3d bin'd table.</tt></li> <li><tt>01.03.2012 GRID: DSS and Linear projections use AST.</tt></li> <li><tt>01.17.2012 3D: 3D Frame is now available.</tt></li> <li><tt>01.19.2012 ANALYSIS: added $z macro.</tt></li> <li><tt>01.19.2012 CROP: add [xmin:xmax,ymin:ymax,zmin:zmax] syntax</tt></li> <li><tt>01.19.2012 CROP: check for valid crop with [] syntax.</tt></li> <li><tt>01.23.2012 3D: add current slice highlite.</tt></li> <li><tt>01.23.2012 SAVEIMAGE: fixed a problem with frame highlite during saveimage process.</tt></li> <li><tt>01.23.2012 ANALYSIS: expand $image macro to accept new params: rgb and 3d.</tt></li> <li><tt>01.27.2012 ANALYSIS: expand $filename(full) to return full filename (without cropping or filters parameters).</tt></li> <li><tt>01.27.2012 ANALYSIS: add macro $value.</tt></li> <li><tt>01.27.2012 CROP: fixed a problem when using an image subsection spec for a datacube.</tt></li> <li><tt>01.28.2012 REGIONS: clean up rendering code for X,ps,win32,macosx to reduce un-needed calls to set the graphics context.</tt></li> <li><tt>01.28.2012 CROP: all data cubes can be cropped in 3D.</tt></li> <li><tt>01.28.2012 CROP: cropping in 3D will reset currentSlice if needed.</tt></li> <li><tt>01.28.2012 REGIONS: fixed a problem if the region color was an X11 valid color, some names would get mapped to the incorrect color when printing.</tt></li> <li><tt>02.02.2012 COLORMAP: fixed a problem with SAO format colormaps that have very long lines.</tt></li> <li><tt>02.03.2012 PRINT COORDINATES: added filename to options.</tt></li> <li><tt>02.03.2012 WCS: if wcs parameters are changed or reset, all open catalogs regions are updated. Normal regions are not changed.</tt></li> <li><tt>02.07.2012 COLORMAP: remove support for old RTD and ITT colormaps</tt></li> <li><tt>02.08.2012 GUI: consolidate MATCH and LOCK items into submenus.</tt></li> <li><tt>02.08.2012 GUI: move match bin, match scale, and match colorbar to frame match menu.</tt></li> <li><tt>02.16.2012 CUBE: fixed a proble with calculating the wcs to image for axis 3.</tt></li> <li><tt>02.16.2012 FITSY++: changes required for gcc 4.7.</tt></li> <li><tt>02.16.2012 BLT: patched graph.tcl to use legendRelief instead of labelRelief.</tt></li> <li><tt>02.16.2012 RGB: added lock wcs.</tt></li> <li><tt>02.16.2012 FUNTOOLS: updated to version 1.4.5-2.</tt></li> <li><tt>02.21.2012 3D: fixed a problem with scale clip scope. Should alway be in GLOBAL.</tt></li> <li><tt>02.29.2012 HEADER: add save header command.</tt></li> <li><tt>03.01.2012 XPA: updated to version 2.1.14.</tt></li> <li><tt>03.01.2012 MINMAX: AUTOSCAN set to SAMPLE if width*height*depth &gt; 1e8.</tt></li> <li><tt>03.12.2012 IMGSVR: fixed a problem with clearing params if no image was loaded previously.</tt></li> <li><tt>03.22.2012 REGION: add ellipse3d, box3d, polygon3d, point3d regions.</tt></li> <li><tt>03.23.2012 IMGSVR: fixed a problem new frame option and rgb.</tt></li> <li><tt>03.23.2012 BIN: check for valid col names for -bin col command.</tt></li> <li><tt>03.28.2012 REGIONS: add Analysis support per region.</tt></li> <li><tt>03.28.2012 REGIONS: add Analysis Plot3d support for Circle,Ellipse,Box,Polygon,Point.</tt></li> <li><tt>03.28.2012 REGIONS: add Analysis Plot2d support for Projection,Line,Vector.</tt></li> <li><tt>03.28.2012 REGIONS: Circle3d now converted to Circle.</tt></li> <li><tt>03.28.2012 REGIONS: Plot3d saves native coordinate values.</tt></li> <li><tt>03.28.2012 SCALE: simplified scale dialog controls to allow user values.</tt></li> <li><tt>03.29.2012 WCS: fixed a problem with numaxes &gt; 3 images and editing WCS params.</tt></li> <li><tt>04.09.2012 WCS: second attempt to handle non-equatorial wcs. try to build a legal header from the wcssubs struct to feed to ast.</tt></li> <li><tt>04.10.2012 SCALE: fixed an issue with autocut, ll != hh.</tt></li> <li><tt>04.10.2012 SKYVIEW: add WISE/COBE/WMAP to skyview survey menu.</tt></li> <li><tt>04.10.2012 WCS: if CD matrix is all zero, use cdelt/pc matrix.</tt></li> <li><tt>04.11.2012 SMOOTH: fixed a problem with images with BSCALE/BZERO.</tt></li> <li><tt>04.11.2012 CATALOG: fixed a problem with d:m:s formated DEC which started with a '+'</tt></li> <li><tt>04.12.2012 CATALOG: fixed a problem with d:m:s to degree conversion. Try to maintain higher precision.</tt></li> <li><tt>04.12.2012 CATALOG: add IAU location code to dialog.</tt></li> <li><tt>04.13.2012 COLORMAP: add user contributed cmaps.</tt></li> <li><tt>04.18.2012 GUI: fixed a problem with long WCSNAME values.</tt></li> <li><tt>04.20.2012 FITSY: added support for GZIP compresss parameter ZQUANTIZ.</tt></li> <li><tt>04.23.2012 PS: fixed a bug with definiton of 32 bit integers on 64 bit OS.</tt></li> <li><tt>04.23.2012 PREFS: add Text Dialog Font preferences menu.</tt></li> <li><tt>04.23.2012 LOCK: fixed a problem with lock frame and mouse wheel events.</tt></li> <li><tt>04.24.2012 SKYBOT: Look for EXPTIME and add 1/2 to DATE-OBS to get middle of observation.</tt></li> <li><tt>04.24.2012 LINUX64: add --hash-style=both to support old and new GNU API for hash libs.</tt></li> <li><tt>04.26.2012 PHOTO: add support for other image formats.</tt></li> <li><tt>04.26.2012 EXPORT: add support for exporting to other image formats.</tt></li> <li><tt>04.30.2012 WCS: fixed a problem with TAN-SIP and wcs append/replace.</tt></li> <li><tt>05.01.2012 TCL: check to see if packages msgcat and http have already been found before sourcing during startup.</tt></li> <li><tt>05.03.2012 MPEG: fixed a problem with the bottom of an image cut off.</tt></li> <li><tt>05.07.2012 COLORTAG: add color tags.</tt></li> <li><tt>05.10.2012 CROP: fixed a problem with backup and lock crop.</tt></li> <li><tt>05.10.2012 SCALE: fixed a problem lock scale and crop.</tt></li> <li><tt>05.10.2012 BACKUP: fixed a problem with back and -slice, -mosaic load options.</tt></li> <li><tt>05.11.2012 REGIONS: add auto plot2d and plot3d prefs.</tt></li> <li><tt>05.14.2012 GUI: add fits save.</tt></li> <li><tt>05.17.2012 MPEG: updated to ezMPEG v0.1</tt></li> <li><tt>05.17.2012 AST: updated to 7.0.3</tt></li> <li><tt>05.23.2012 WCS: is always displayed</tt></li> <li><tt>05.23.2012 CATALOG: fixed a problem with the sign of d:m:s conversion introduced on 04.12.2012.</tt></li> <li><tt>05.28.2012 MOVIE: minor tweaks on incr slice during movie.</tt></li> <li><tt>05.28.2012 WIN32: fixed a problem with 3d fillImageJoin. Statck overflow.</tt></li> <li><tt>05.29.2012 BACKUP: fixed active frames issue.</tt></li> <li><tt>05.30.2012 GUI: add threads command.</tt></li> <li><tt>05.30.2012 GUI: fixed a problem with PASTE for entries. Will now process unicode.</tt></li> <li><tt>05.31.2012 GRID: fixed a problem with parsing 6.1 and 6.2 backup save sets. New grid options parser implemented.</tt></li> <li><tt>05.31.2012 PLOT: fixed a problem in generating postscript. Now just set plot size.</tt></li> <li><tt>05.31.2012 PLOT: fixed a postscript font issue with helvetica.</tt></li> <li><tt>05.31.2012 PLOT: add axes format.</tt></li> <li><tt><b>06.06.2012 RELEASE version 7.0</b></tt></li> <li><tt>06.12.2012 BACKUP: fixed a problem with processing version 6.1 and 6.2 backup save sets.</tt></li> <li><tt><b>06.15.2012 RELEASE version 7.0.1</b></tt></li> <li><tt>06.13.2012 3D: add border graphics.</tt></li> <li><tt>06.15.2012 TCLLIB: updated to version 1.14. This fixes a problem with math::fuzzy::tlt.</tt></li> <li><tt>06.21.2012 REGION: fixed a problem with rotated images and postscript printing of circle region.</tt></li> <li><tt>06.21.2012 IMGSRV: fixed a problem loading images from dss/2mass/etc from the command line. Use the first frame if not already loaded.</tt></li> <li><tt>06.21.2012 SLA: removed from build tree. not needed since AST now has own version.</tt></li> <li><tt>06.21.2012 HELP: rm link to home page. hv can't handle the new web site.</tt></li> <li><tt>06.22.2012 SKYBOT: added -filter=0.</tt></li> <li><tt>06.22.2012 POSTSCRIPT: fixed a problem with rotated text regions affecting other regions.</tt></li> <li><tt>06.22.2012 REGIONS: fixed a problem selecting text regions at high zoom.</tt></li> <li><tt>06.22.2012 WCS: add support for SAO Polynomial Plate.</tt></li> <li><tt>06.25.2012 GUI: improved error handling. Will now properly handle a FATAL error msg from internal widgets.</tt></li> <li><tt>06.25.2012 GUI: non FATAL msgs can be supressed via preferences.</tt></li> <li><tt>06.25.2012 FRAME: trap SIGBUS while scanning for min/max.</tt></li> <li><tt>06.25.2012 WCS: use new version of AST:fitschan.c which supports SAO polynomial plate solution and checks for the case of all PV keywords=0.</tt></li> <li><tt>06.25.2012 GUI: enable hidden directory button for linux standard dialog box (windows only).</tt></li> <li><tt>06.25.2012 GUI: move About menu item to Help menu.</tt></li> <li><tt>06.27.2012 LOCK: fixed a problem with LOCK FRAME and the current skyframe.</tt></li> <li><tt>06.27.2012 PANNER: fixed a problem where the wcs compass was incorrectly set.</tt></li> <li><tt>06.29.2012 AST: updated to 7.0.5</tt></li> <li><tt>07.02.2012 HTTP: set default timeout to 1 minute.</tt></li> <li><tt><b>07.03.2012 RELEASE version 7.0.2</b></tt></li> <li><tt>07.05.2012 RGB: fixed a problem with -rgbimage and extnames.</tt></li> <li><tt>07.05.2012 GCC: fixed a problem gcc 4.5 and Pixmap typedef.</tt></li> <li><tt>07.06.2012 SCALE: fixed a problem with scale dialog and very small numbers.</tt></li> <li><tt>07.10.2012 BIN: fixed a problem with very large FITS Bin Tables.</tt></li> <li><tt>07.11.2012 FITSY++: fixed a number of problems with very large (2Gb&gt;) FITS Image and Bin Tables.</tt></li> <li><tt>07.13.2012 WINDOWS: fixed a problem with dashs on the display. Tk does not give us much flexibilty, so pick something closer to the desired length.</tt></li> <li><tt>07.17.2012 CATALOG: add sdss r7 and sdss r8 to default menu.</tt></li> <li><tt>07.17.2012 GRIDS: fixed a problem where each frame grid remembers its own configuration.</tt></li> <li><tt>07.17.2012 FITSY++: fixed a number of problems with save very large (2Gb&gt;) FITS Image and Bin Tables.</tt></li> <li><tt>07.23.2012 REGIONS: fixed a problem with PLOT3D and BOX, ELLIPSE, POLYGON. At certain angles, incorrect counts were calculated.</tt></li> <li><tt>07.27.2012 REGIONS: fixed a problem with rendering ELLIPSE PANDA X11 at angle=0.</tt></li> <li><tt>07.30.2012 PRINT: fixed a problem with printing simple text and catalog dialogs.</tt></li> <li><tt>07.30.2012 REGIONS: add default length format to preferences.</tt></li> <li><tt>07.30.2012 GUI: update infobox when moving between frames.</tt></li> <li><tt>07.30.2012 BACKUP: don't save compressed image files if not requested.</tt></li> <li><tt>08.02.2012 WCS: fixed a number of issues with the WCS parameters dialog.</tt></li> <li><tt>08.02.2012 WCS: added support for SIP and SCAMP keywords to WCS parameters dialog.</tt></li> <li><tt>08.06.2012 MAGNIFIER: be sure to update magnifier when changing slice.</tt></li> <li><tt>08.09.2012 PLOT: fixed a problem reading muliple datasets from one source.</tt></li> <li><tt>08.10.2012 AST: updated to version 7.0.6</tt></li> <li><tt>08.13.2012 3D: add z axis scaling.</tt></li> <li><tt>08.13.2012 FITSY++: accept double quoted (invalid) strings.</tt></li> <li><tt>08.21.2012 REGIONS: fixed a problem with -regions centroid command.</tt></li> <li><tt>09.05.2012 SMOOTH: add lock/match smooth.</tt></li> <li><tt>09.14.2012 PLOT: enhanced gui.</tt></li> <li><tt>09.14.2012 PLOT: add bar chart option.</tt></li> <li><tt>09.14.2012 PLOT: add scatter chart option.</tt></li> <li><tt>09.14.2012 REGIONS: add Analysis Statistics.</tt></li> <li><tt>09.14.2012 REGIONS: add Analysis Radial Profile.</tt></li> <li><tt>10.3.2012 CATALOG: add match option.</tt></li> <li><tt><b>10.15.2012 RELEASE version 7.1</b></tt></li> <li><tt>10.18.2012 GUI: update File menu.</tt></li> <li><tt>11.02.2012 GUI: add support for NRRD file format. Includes encodings: raw and gzip.</tt></li> <li><tt>11.05.2012 GUI: fixed a problem with cut/paste for contours and catalogs.</tt></li> <li><tt>11.27.2012 PLOT: fixed typo in range dialog.</tt></li> <li><tt>11.27.2012 GUI: fixed a problem with clear analysis menu item and the analysis menu.</tt></li> <li><tt>12.06.2012 SAMP: fixed a typo which disabled SAMP_HUB functionality.</tt></li> <li><tt>12.06.2012 DS9: fixed a problem on how to align an image with an odd size frame. In versions &lt;7.0, the floating point number was rounded down. This has been re-implemented.</tt></li> <li><tt>12.11.2012 GPL: upgrade license to GPL v3.</tt></li> <li><tt>12.18.2012 COLORBAR: add support for SAO format GAMMA param.</tt></li> <li><tt>12.18.2012 SAVEIMAGE: add support for EPS.</tt></li> <li><tt>12.20.2012 REGIONS: fixed a problem with updating analysis plot x/y axis titles.</tt></li> <li><tt>12.21.2012 REGIONS: fixed a problem with analysis radial profile and negative xaxis values.</tt></li> <li><tt>12.21.2012 REGIONS: fixed a problem with writing composited regions.</tt></li> <li><tt>12.21.2012 REGIONS: fixed a problem with list/save data radial annulus.</tt></li> <li><tt>12.28.2012 RGB: add photo export.</tt></li> <li><tt>01.19.2013 FITSY++: fixed a problem parsing filters</tt></li> <li><tt>01.19.2013 FITSY++: fixed a problem with incomplete variable array TFORM descriptions, used in fits compression. If no length is specified, set default to 8.<br> </tt></li> <li><tt>01.29.2013 SAVE: save fits will now save an entire cube if loaded.</tt></li> <li><tt>01.30.2013 SAVE: add support for save mecube.</tt></li> <li><tt>01.31.2013 CONTOUR: fixed a problem with loading a set of contours with a specified color.</tt></li> <li><tt>02.13.2013 FITSY++: support new fits compression float/double gzip method.</tt></li> <li><tt>02.13.2013 FITSY++: ds9 now distinguishes between BLANK/NAN/INF values.</tt></li> <li><tt>02.15.2013 REGIONS: no longer output filename in header.</tt></li> <li><tt>02.26.2013 FITSY++: use magic bytes to check for gz compressed files before load.</tt></li> <li><tt>02.28.2013 RGB: loading rgbimage, rgbcube, rgbarray into non-rgb frame will create new rgb frame for all command line, xpa, and samp commands.</tt></li> <li><tt>03.01.2013 FRAME: trap SIGBUS and SIGSEGV while scanning data.</tt></li> <li><tt>03.01.2013 FRAME: will only return error messages at levels info, warning, and error.</tt></li> <li><tt>03.10.2013 PREFS: fixed a problem with prefs zoom align.</tt></li> <li><tt>03.12.2013 BACKUP: check for sym links.</tt></li> <li><tt>03.14.2013 GUI: non-modal dialogs are now created at the center of the main ds9 window.</tt></li> <li><tt>03.25.2013 VO: default vo method is mime.</tt></li> <li><tt>03.25.2013 VO: if xpa method fails, default to mime.</tt></li> <li><tt>03.26.2013 XPA: add samp cmd to xpa.</tt></li> <li><tt>03.26.2013 SAMP: add xpa cmd to samp.</tt></li> <li><tt>04.01.2013 AST: updated to version 7.1.1</tt></li> <li><tt>04.11.2013 CATALOG: fixed cut and paste.</tt></li> <li><tt>04.11.2013 WCS: SAO_PLT is now handled directly by AST.</tt></li> <li><tt>04.12.2013 PREFS: add dialog center option.</tt></li> <li><tt>04.12.2013 PLOT: all plots (user, analysis and catalogs) are now available to the plot command.</tt></li> <li><tt><b>04.15.2013 RELEASE version 7.2</b></tt></li> </ol> </ol> </body> </html> �������������������������������./saods9/doc/release/r1.6.html����������������������������������������������������������������������0000644�0001750�0001750�00000001472�10415010755�014646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 1.6 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 1.6 Release Notes</h3> <ul> <h4> <b>Version 1.6.1</b></h4> <ol> <li> <tt>fix some minor problems with odd chars in filenames</tt></li> <li> <tt>fix problems with fits image extensions</tt></li> <li> <tt>removed minimal geometry restrictions</tt></li> <li> <tt>fits file support is more robust</tt></li> </ol> </ul> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r5.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000073646�11300355440�014655� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 5 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 5 Release Notes</h3> <ol> <ol> <li><tt>07.16.2007 FITSY++: fix a problem with rice compressed images and multiple tiles.</tt></li> <li><tt>07.17.2007 MOSAIC: fix a problem with bin table extensions at the end of a mosaic image wcs.</tt></li> <li><tt>07.20.2007 COLORMAP: fixed a problem with loading external colormaps.</tt></li> <li><tt>07.20.2007 COLORMAP: fixed a problem colormap menus.</tt></li> <li><tt>07.23.2007 ARCHIVES: new url for skyview.</tt></li> <li><tt>07.23.2007 I18N: add language support for Japanese. (many thanks to Masahiro Tsujimoto!).</tt></li> <li><tt>07.23.2007 PIXEL TABLE: xpaget will now return the pixel table values.</tt></li> <li><tt>07.31.2007 SOLARISx86: now supporting solarisx86.</tt></li> <li><tt>08.15.2007 PIXELTABLE: fixed a minor problem with xpaget pixeltable.</tt></li> <li><tt>08.15.2007 FUNTOOLS: update to version 1.4.0</tt></li> <li><tt>08.15.2007 IIS: fixed a problem with frame number greater than 10.</tt></li> <li><tt>08.15.2007 EXAMINE: changed frame name to 'Frame'.</tt></li> <li><tt>09.02.2007 CATALOGS: updated urls and menu titles.</tt></li> <li><tt>09.20.2007 PREFS: new prefs dialog box.</tt></li> <li><tt>09.24.2007 CATALOGS: fixed a problem with the CDS query.</tt></li> <li><tt>09.24.2007 CATALOGS: add SDSS DR6.</tt></li> <li><tt>09.24.2007 SKYVIEW: fixed default image size and updated url.</tt></li> <li><tt>09.24.2007 PROJECTION: install callbacks only after Button Release.</tt></li> <li><tt>09.25.2007 REGIONS: add xpa/command SHOW and SHOWTEXT support.</tt></li> <li><tt>09.25.2007 CONTOURS: fixed a problem with load contours from the command line.</tt></li> <li><tt>10.03.2007 MACOSX: MacOSX Aqua support is now fully implemented!</tt></li> <li><tt>10.03.2007 COLORMAP: pass colormap names thru translation tables</tt></li> <li><tt>10.03.2007 XPA: update to version 2.1.8</tt></li> <li><tt>10.05.2007 COMPOSITE: add global properties switch.</tt></li> <li><tt>10.05.2007 LINE: fixed a problem with initial displayed arrow checkboxes in dialog.</tt></li> <li><tt>10.05.2007 FOV: moved FOV menu to more visible level</tt></li> <li><tt>10.10.2007 I18N: add language support for French.</tt></li> <li><tt>10.11.2007 CATALOGS: fixed a problem with the symbol editor dialog.</tt></li> <li><tt><b>10.15.2007 RELEASE version 5.0</b></tt></li> <li><tt>10.16.2007 PROJECTION: fixed a problem with the coordinates of the projection plot.</tt></li> <li><tt>10.17.2007 RICE: fixed a problem with float and double RICE compression.</tt></li> <li><tt>10.24.2007 RICE: fixed several problems with mosaics, cubes and RICE compression.</tt></li> <li><tt>10.24.2007 GUI: added support for ds9 beta versions.</tt></li> <li><tt>10.24.2007 PREFS: added OK and Cancel buttons to all tabs.</tt></li> <li><tt>10.29.2007 CATALOGS: implemented support for new CDS catalogs search format.</tt></li> <li><tt>10.30.2007 SAOTK: implemented reentrant parsers.</tt></li> <li><tt>11.01.2007 SAOTK: now support any color for markers, contours, etc.</tt></li> <li><tt>11.02.2007 MACOSX/WINDOWS: fixed a problem with native open file dialog. If bad file name had been used, (or an extention), an error would occur.</tt></li> <li><tt>11.07.2007 TCL/TK: update to version 8.4.16.</tt></li> <li><tt>11.08.2007 PLOT: fixed a problem with xpa/command line linear/line tokens to match documentation.</tt></li> <li><tt>11.09.2007 PREFERENCES: fixed a problem with slower ppcs. use 'update idletasks' instead of 'update' to avoid possible race condition.</tt></li> <li><tt>11.21.2007 XPA: update to version 2.1.9</tt></li> <li><tt>11.21.2007 FUNTOOLS: update to version 1.4.1</tt></li> <li><tt>11.21.2007 WCSSUBS: update to version 3.7.0</tt></li> <li><tt>11.21.2007 TCLLIBS: update to version 1.10</tt></li> <li><tt>11.28.2007 TCL/TK: update to version 8.4.17 beta.</tt></li> <li><tt>11.28.2007 ANALYSIS: fix a problem with spaces in tmp file names.</tt></li> <li><tt>12.05.2007 FLEXLEXER.Y: updated version.</tt></li> <li><tt>12.06.2007 GUI: change key binding 'c' to 'r'. It conflicts with 'copy' on MacOSX and Windows platforms.</tt></li> <li><tt>12.06.2007 REGIONS: fixed a problem with pasteing regions into an empty frame.</tt></li> <li><tt>12.18.2007 ZIP: fixed a problem with the unix Makefile.</tt></li> <li><tt>12.18.2007 FUNTOOLS: update to version 1.4.2.</tt></li> <li><tt>12.18.2007 2MASS: limit size to 1024 arcsec.</tt></li> <li><tt>12.21.2007 FITSY++: add support for HCOMPRESS compressed FITS.</tt></li> <li><tt>12.28.2007 FITSY++: add support for GZIP compressed FITS.</tt></li> <li><tt>01.03.2008 FITSY++: add support for PLIO compressed FITS.</tt></li> <li><tt>01.04.2008 GUI: fixed a problem with X11 servers that return truecolor 32 bit when in fact the visual is truecolor 24bit.</tt></li> <li><tt><b>01.15.2008 RELEASE version 5.1</b></tt></li> <li><tt>01.17.2008 ANALYSIS: add the directory of any loaded analysis file to the PATH.</tt></li> <li><tt>01.22.2008 REGIONS: fixed a problem introduced with reentrant parsers. Sexagesimal values between -00 and +00 were incorrectly parsed as +00.</tt></li> <li><tt>01.23.2008 REGIONS: fixed a problem with parsing HMS/DMS coordinates.</tt></li> <li><tt>01.24.2008 GUI: fixed a problem shift rotate mode.</tt></li> <li><tt>01.24.2008 GUI: info panel 'Frame' width set to +4.</tt></li> <li><tt>01.24.2008 GUI: add new goto frame menu.</tt></li> <li><tt>01.24.2008 GUI: add support for move frames.</tt></li> <li><tt>01.24.2008 ANALYSIS: for MacOSX tiger, wrap cmds with shell and PATH.</tt></li> <li><tt>01.25.2008 CATALOGS: make sure xpa and command line retrieves are syncronous.</tt></li> <li><tt>01.28.2008 CONTOUR: fixed a problem with loading contour levels into multiple frames.</tt></li> <li><tt>01.31.2008 WINDOWS: changed how windows come into focus.</tt></li> <li><tt>01.31.2008 TCL/TK: update to version 8.4.17.</tt></li> <li><tt>02.07.2008 GUI: change default directory for standard dialog to $HOME.</tt></li> <li><tt>02.07.2008 ANALYSIS: add /sw/bin to default path for MacOSX.</tt></li> <li><tt>02.20.2008 CATALOGS: add support for editing a catalog table and regions.</tt></li> <li><tt>02.20.2008 TEXT: add enable rotation switch for text regions.</tt></li> <li><tt>02.20.2008 GUI: ds9 will now start in the users home directory for MacOSX Aqua users when invoked from a double click and the default dialog box is Motif or Windows.</tt></li> <li><tt>02.20.2008 TCL/TK: update to version 8.4.18.</tt></li> <li><tt>02.26.2008 IIS: disable most keystroke and mouse events for iis frames.</tt></li> <li><tt>02.28.2008 FITSY++: fixed a problem with save fits and smoothed images.</tt></li> <li><tt>02.29.2008 WCS: fixed a problem with calculating the size and center of complex fits images in WCS.</tt></li> <li><tt>03.05.2008 GUI: backed out change key binding 'c' to 'r'. It causes untold grief with IRAF.</tt></li> <li><tt>03.10.2008 MACOSX: fixed a problem with printing non standard colors.</tt></li> <li><tt>03.10.2008 CATALOGS: catalog dialogs are now tied to the frame. This allows multiple copies of the same catalog, one per frame.</tt></li> <li><tt>03.12.2008 GRID: added support for PC001001 formated WCS keywords.</tt></li> <li><tt>03.13.2008 IIS: make sure socket is closed on exec.</tt></li> <li><tt>03.13.2008 WINDOWS: add support for native printing.</tt></li> <li><tt>03.18.2008 CROSSHAIR: fix a problem with the line width for postscript.</tt></li> <li><tt>03.18.2008 MACOSX: restore postscript printing.</tt></li> <li><tt>03.18.2008 WINDOWS: restore postscript printing.</tt></li> <li><tt>03.19.2008 GUI: enhancements with Find/FindNext in text dialog windows.</tt></li> <li><tt>03.19.2008 GUI: add console support.</tt></li> <li><tt>03.24.2008 REGIONS: apply WCS to fits regions if present.</tt></li> <li><tt>03.25.2008 PREFS: fixed a problem with Zoom menu preferences.</tt></li> <li><tt>03.31.2008 GUI: add support for user configured button bar.</tt></li> <li><tt>04.03.2008 CATALOGS: add support for simbad.</tt></li> <li><tt>04.04.2008 MASKS: fixed a problem with mask color preference.</tt></li> <li><tt>04.07.2008 IMEXAMINE: added support for key stroke events.</tt></li> <li><tt><b>04.15.2008 RELEASE version 5.2</b></tt></li> <li><tt>04.18.2008 REGIONS: added support for centroid.</tt></li> <li><tt>04.21.2008 GUI: fixed a problem with 'c' and control-c.</tt></li> <li><tt>04.21.2008 IIS: fixed a problem key events. Now all key events are active until IIS is in cursor mode. At this point all key events are passed to IRAF except for 'TAB'.</tt></li> <li><tt>04.23.2008 MACOSX: split the binary and archive into two files, and codesign the binary, so that it will play well with leopard's new firewall.</tt></li> <li><tt>04.25.2008 FITSY++: fixed a proble with mapincr. If seek_ is at end of file, mmap will not return an error.</tt></li> <li><tt>04.28.2008 GUI: delete all frames resets the frame counter (broken in 5.2).</tt></li> <li><tt>06.02.2008 GCC: remove all references to <iostream.h> and use <iostream> instead.</iostream></iostream.h></tt></li> <li><tt>06.02.2008 GCC: support for gcc 4.2.</tt></li> <li><tt>06.02.2008 GUI: fix typo in bin.tcl menus.</tt></li> <li><tt>06.03.2008 FITSY++: changes to processing the header where ds9 will now work with illegal fits files that contains NULLs instead of SPACEs.</tt></li> <li><tt>06.03.2008 RICE: implemented compatibility with cfitsio 3.08.</tt></li> <li><tt>06.04.2008 GZIP: implemented compatibility with cfitsio 3.08.</tt></li> <li><tt>06.04.2008 HCOMPRESS: implemented compatibility with cfitsio 3.08.</tt></li> <li><tt>06.05.2008 IIS: disable scale menu with iis frame (fixed from version 5.2).</tt></li> <li><tt>06.05.2008 REGIONS: fixed FITS regions polygon support. Now determine how many points based on the repeat value of the column, but check for .</tt></li> <li><tt>06.06.2008 FITS: for saveimage fits, if non-linear WCS, don't attempt to save WCS.</tt></li> <li><tt>06.06.2008 BLINK: add xpa/command line option -blink interval.</tt></li> <li><tt>06.06.2008 REGIONS: add for DASH property.</tt></li> <li><tt>07.11.2008 REGIONS: fixed a problem with the 'delete all' button.</tt></li> <li><tt>07.16.2008 XPA: if CHECKDNS fails, set XPA_METHOD to local and initialize.</tt></li> <li><tt>07.21.2008 PROJECTION: minor change to ensure that we step over the grid in 1 pixel values.</tt></li> <li><tt>07.24.2008 IIS: add support for all 16 IIS colors.</tt></li> <li><tt>07.25.2008 BINNING: fixed a problem with smooth and 3d binning.</tt></li> <li><tt>08.04.2008 FITSY++: fixed a problem with BSCALE/BZERO and float/double data types.</tt></li> <li><tt>08.11.2008 CATALOGS: fixed a problem with catalogs retrieved via a cds search. The id returned would fail during evaluation in creating a valid header.</tt></li> <li><tt>08.11.2008 CATALOGS: add CMC to catalog menu.</tt></li> <li><tt>08.11.2008 GUI: fixed a problem with the initial directory for the standard dialog when loading from the command line.</tt></li> <li><tt>08.14.2008 VECTOR: vast improvements in optimization.</tt></li> <li><tt>08.19.2008 GUI: catch a failure to initialize window system (a problem with X11) and exit nice.</tt></li> <li><tt>08.19.2008 MACOSX: fixed the window tab problem for Aqua port.</tt></li> <li><tt>08.19.2008 MACOSX: fixed canvas background issues.</tt></li> <li><tt>08.20.2008 GUI: Add buttons to vertical layout.</tt></li> <li><tt>09.10.2008 XPA: fixed a problem with blink interval &lt; 1.</tt></li> <li><tt>09.12.2008 PREFS: add 'Preserve During Load' for scale, pan, and regions.</tt></li> <li><tt>09.12.2008 CONTOUR: add dash line option.</tt></li> <li><tt>09.17.2008 PANNER: check to see if we are at pole.</tt></li> <li><tt>09.17.2008 CATALOGS: add copy from row(s).</tt></li> <li><tt>09.17.2008 REGIONS: look for new FITS POLYGON termination conditions</tt></li> <li><tt>09.22.2008 COLORBAR: removed truecolor colorbar options. Always paint the entire image.</tt></li> <li><tt>09.25.2008 BINNING: automatically look for x,y then ra,dec, before settling for columns 1 and 2.</tt></li> <li><tt>09.25.2008 IMEXAM: added 'any' event (returns with a mouse event or key event).</tt></li> <li><tt>10.02.2008 CATALOGS: fixed a problem with size format for SIMBAD and NED. Degrees and ArcSecs were incorrectly calculated.</tt></li> <li><tt>10.03.2008 CATALOGS: Add support for CXC catalog.</tt></li> <li><tt>10.08.2008 MACOSX: add MacOSX X11 10.5 firewall port.</tt></li> <li><tt>10.10.2008 FOV: add sao/binospec.</tt></li> <li><tt><b>10.15.2008 RELEASE version 5.3</b></tt></li> <li><tt>10.17.2008 CATALOGS: removed support for Chandra Source Catalog at request of Ian Evans of CXC.</tt></li> <li><tt>10.22.2008 MASKS: add support for mask transparency.</tt></li> <li><tt>10.24.2008 MASKS: add new mask properties.</tt></li> <li><tt>10.28.2008 GRID: add grid title support.</tt></li> <li><tt><b>10.31.2008 RELEASE version 5.4</b></tt></li> <li><tt>10.31.2008 GRID: full grid support for command line and xpa.</tt></li> <li><tt>11.04.2008 FITSY: fixed a problem with header keywords that start with 'END'.</tt></li> <li><tt>11.13.2008 FITSY: fixed a problem when there was a failure to correctly parse iraf or wcs keywords.</tt></li> <li><tt>12.02.2008 FITS: for saveimage fits, fixed a problem with LTMV,DTMV, and WCS coordinates. They were off by 1 pixel in x.</tt></li> <li><tt>12.02.2008 GUI: fixed a problem with panning via click and drag.</tt></li> <li><tt>12.04.2008 MPEG: changed makefiles to compile tkmpeg code without optiminzation. -O created invalid code for MacOSX (and possible others)</tt></li> <li><tt>12.04.2008 REGIONS: fixed a problem when creating a default panda region via a mouse click.</tt></li> <li><tt>12.05.2008 POSTSCRIPT: fixed a problem with printing frames that have no image loaded.</tt></li> <li><tt>12.05.2008 CATALOGS: fixed a problem with using the arrow keys in catalog dialogs.</tt></li> <li><tt>12.10.2008 REGIONS: fixed a problem elongated rotated ellipses.</tt></li> <li><tt>12.10.2008 MACOSX: fixed several problems with processing AppleEvents OpenDocument and PrintDocument. DS9 now supports opendoc and printdoc while currently running.</tt></li> <li><tt>12.12.2008 IIS: re-enabled mouse events while in cursor mode.</tt></li> <li><tt>12.12.2008 IIS: trap arrow keys while in cursor mode, do not pass to IRAF, instead warp cursor.</tt></li> <li><tt>12.15.2008 SMOOTH: ignore NAN in smoothing convolution.</tt></li> <li><tt>12.16.2008 GUI: fixed a problem with 'get fits size' to make it behave in the regions of poles.</tt></li> <li><tt>12.29.2008 IIS: try to decode OBJECT from iisMessageCmd.</tt></li> <li><tt>12.29.2008 IIS: if frame is in cursor mode (via the imexam task), RESET FRAME, will attempt to clean up.</tt></li> <li><tt>01.05.2009 FUNTOOLS: update to version 1.4.2.2</tt></li> <li><tt>01.05.2009 WCSSUBS: update to version 3.7.6</tt></li> <li><tt>01.05.2009 GUI: add support for loading FITS multiple extension as multiple frames.</tt></li> <li><tt>01.05.2009 EXAMINE: fixed many problems. Will work not work with data loaded via stdin or xpa fits.</tt></li> <li><tt>01.15.2009 SMOOOTH: fixed a problem with BZERO and BSCALE. These keywords are reset to default values if present in the smoothed image, since the scaling has already been applied.</tt></li> <li><tt>01.15.2009 FILTER: fixed an issue when unable to build a valid filter. Previously, it would exit() the program. Now, it will issue an error message and continue.</tt></li> <li><tt>01.16.2009 MACOSX: if using the X11 port of MacOSX, increase the size of the window to make room for the size tab, similar for Aqua.</tt></li> <li><tt>01.16.2009 SAVEAS: PNG now saves without GAMMA.</tt></li> <li><tt>01.20.2009 GUI: Rearrange Frame menu and Region menu. They had grown too long and some window managers were having difficulties.</tt></li> <li><tt>01.21.2009 REGIONS: fixed a problem rendering Bezier curves.</tt></li> <li><tt><b>01.23.2009 RELEASE version 5.5</b></tt></li> <li><tt><b>01.28.2009 RELEASE version 5.5.1</b></tt></li> <li><tt>01.28.2009 GUI: fixed a problem in that the last file name loaded is incorrectly set if there are command line options that follow the file name.</tt></li> <li><tt>02.02.2009 CATALOGS: updated urls for cds mirrors.</tt></li> <li><tt>02.03.2009 CATALOGS: cleaned up tsv code. Will read comma and tab separted values, and will write tab separated values. Assumes first row is cols header unless first and second cols are numbers, then assumes ra, dec, in fk5 degrees.</tt></li> <li><tt>02.04.2009 PSEUDOCOLOR: fixed a problem with the frame not remembering its current colormap bias and contrast setting when toggling between frames.</tt></li> <li><tt>02.10.2009 BLT: fixed a problem zoombox under Aqua. XOR draws are now disabled.</tt></li> <li><tt>02.11.2009 CIAO: The ciao regions parser will now accept compound region descriptions.</tt></li> <li><tt>02.12.2009 CONTOURS: fixed a problem with command line/xpa dashed line parameter. Processing the -contour command is now a lot more robust in determining missing parameters.</tt></li> <li><tt>02.16.2009 HISTOGRAM EQU: fixed a problem with clipping low = clipping high (usually as a result of ZSCALE).</tt></li> <li><tt>02.19.2009 FITSY++: fixed a problem specifying an extension number of 0 with a multiple extension file with no primary image. It now properly fails to load.</tt></li> <li><tt>02.19.2009 GUI: FITS multiple extension multiple frame will now load a primary image if present.</tt></li> <li><tt>02.19.2009 GUI: compressed FITS multiple extension multiple frame will now load properly.</tt></li> <li><tt>02.19.2009 GUI: FITS multiple extension multiple frame will ignore any bin table extensions.</tt></li> <li><tt>02.19.2009 BLT: add support for MacOSX native printing.</tt></li> <li><tt>02.19.2009 PLOT: native printing now fully supported for MacOSX and Windows.</tt></li> <li><tt>02.24.2009 SAMP: add support for VO Simple Application Messaging Protocol (SAMP). Will process image.load.fits and table.load.votable events.</tt></li> <li><tt>02.25.2009 FITSY++: fixed a problem with saving a slice of a cube. The header had invalid keywords.</tt></li> <li><tt>02.27.2009 CATALOGS: support VOTable format.</tt></li> <li><tt>03.02.2009 MacOSX: support for the MacOSX X11 Leopard 10.5 non-firewall version has been discontinued.</tt></li> <li><tt>03.02.2009 MacOSX: fixed a problem with plot y axis titles offset.</tt></li> <li><tt>03.02.2009 MacOSX: fixed a problem fork/exec and version 10.5 New version of tclMacNotify.c now used.</tt></li> <li><tt>03.09.2009 FUNTOOLS: updated to version 1.4.3.</tt></li> <li><tt>03.10.2009 REGIONS: fixed a problem with listing irregular panda, ellipse panda, and box panda in ds9/funtools format. The conjunction has been removed.</tt></li> <li><tt>03.12.2009 GUI: If in tile mode, with only one frame, and tile mode is set to manual, tile anyway (don't drop into single mode).</tt></li> <li><tt>03.12.2009 CATALOGS: speed up rendering of catalogs for simple symbol filters.</tt></li> <li><tt>03.12.2009 REGIONS: support wildcards in filename.</tt></li> <li><tt>03.12.2009 REGIONS: add support for load into all frames.</tt></li> <li><tt>03.17.2009 GUI: Name server support now utilizies CDS Sesame.</tt></li> <li><tt>03.17.2009 SKYVIEW: fixed a problem processing the survey query.</tt></li> <li><tt>03.18.2009 HV: add support for cookies.</tt></li> <li><tt>03.18.2009 ARCHIVES: add support for NVO Montage.</tt></li> <li><tt>03.18.2009 REGIONS: fixed a problem calculating the WCS angle of a flipped WCS.</tt></li> <li><tt>03.18.2009 HV: add support for mime-type text/xml for votable.</tt></li> <li><tt>03.19.2009 CATALOGS: CDS now uses VOTABLE.</tt></li> <li><tt>03.24.2009 CATALOGS: SIMBAD now uses VOTABLE.</tt></li> <li><tt>03.24.2009 CATALOGS: NED now uses VOTABLE.</tt></li> <li><tt>03.24.2009 CATALOGS: add preferences to download in VOTABLE if available.</tt></li> <li><tt>04.01.2009 GUI: when you delete a frame, the current frame is reset to the previous frame, not the first frame.</tt></li> <li><tt>04.06.2009 RULER: use preferences default distance system.</tt></li> <li><tt>04.06.2009 GUI: fixed a problem with open other url.</tt></li> <li><tt>04.09.2009 PROJECTION: properly calculate width when rebinning.</tt></li> <li><tt><b>04.15.2009 RELEASE version 5.6</b></tt></li> <li><tt>04.16.2009 REGIONS: fixed a rather nasty bug which caused a segv when switching between modes after copy a region from a frame.</tt></li> <li><tt><b>04.16.2009 RELEASE version 5.6.1</b></tt></li> <li><tt>04.17.2009 SAMP: use xmlrpc url method in POST header.</tt></li> <li><tt>04.17.2009 CATALOGS: fixed a typo in the default SDSSR5 query.</tt></li> <li><tt>04.20.2009 HV: fixed a problem with parsing query linked to a button.</tt></li> <li><tt><b>04.20.2009 RELEASE version 5.6.2</b></tt></li> <li><tt>04.22.2009 PREFS: updated the default name server menu.</tt></li> <li><tt>04.24.2009 FIRST: removed a debug statement which was left in.</tt></li> <li><tt>04.27.2009 REGIONS: fixed a problem loading a fits file with specified extension.</tt></li> <li><tt>04.28.2009 HV: fixed again a problem with parsing url within a link with a query which contains a '?'.</tt></li> <li><tt><b>04.30.2009 RELEASE version 5.6.3</b></tt></li> <li><tt>05.01.2009 REGIONS: fixed a problem creating a text region with arcsec or arcmin char.</tt></li> <li><tt>05.01.2009 NAMESRVR: fixed a problem with simbad cfa sexagesimal.</tt></li> <li><tt>05.01.2009 CATALOGS: fixed a problem with quoting a VOTABLE FIELD DESCRIPTION string.</tt></li> <li><tt>05.01.2009 CATALOGS: add column parameters in header output.</tt></li> <li><tt>05.04.2009 SAMP: fixed a problem with select row list.</tt></li> <li><tt>05.04.2009 REGIONS: add list to xpa and command line regions option.</tt></li> <li><tt>05.21.2009 NVSS: add NVSS Image server back.</tt></li> <li><tt>05.26.2009 NAMESRVR: set default name server to cds.</tt></li> <li><tt>05.26.2009 CATALOGS: set default catalog erver to cds.</tt></li> <li><tt>05.26.2009 SAMP: fixed a proble with quoting filenames and urls for xml.</tt></li> <li><tt>05.26.2009 CATALOGS: will now try to determine the RA and DEC cols via the UCD if available.</tt></li> <li><tt>05.26.2009 GUI: fixed a problem with standard dialog boxes and MacOSX Aqua and Windows. The dialogbox would sometimes fail to rise to top.</tt></li> <li><tt>05.27.2009 GUI: WCS menu correctly updates print coordinate parameters.</tt></li> <li><tt>05.27.2009 REGIONS: autocentroid now works for move, edit, and rotate.</tt></li> <li><tt>05.27.2009 CATALOGS: CDS Search now retrieves search options from cds.</tt></li> <li><tt>05.27.2009 CATALOGS: fixed a problem with FILTER and VOTable. The votable cols params were not being properly transfered to the new filtered table.</tt></li> <li><tt>06.10.2009 REGIONS: DS9 regions syntax now supported in VOTable format.</tt></li> <li><tt>06.11.2009 CATALOGS: "No Items Found" is now displayed on status line and not as a model dialog.</tt></li> <li><tt>06.11.2009 REGIONS: fixed problem with dashed lines with rotated ellipses.</tt></li> <li><tt>06.11.2009 GUI: fixed problem with standard file dialog boxes. Now, command line options and xpa command DOES NOT CHANGE the current directory. Only the use of the dialog box will reset the current directory.</tt></li> <li><tt>06.11.2009 SAMP: don't send empty catalogs.</tt></li> <li><tt>06.11.2009 CATALOGS: don't write empty catalogs.</tt></li> <li><tt>06.11.2009 FILTER: fixed a problem with parsing filters on the command line that contain quotes.</tt></li> <li><tt>06.16.2009 SAMP: the samp port number is now automatically determined at connection time.</tt></li> <li><tt>06.17.2009 CATALOGS: for VOTables, change id to ID.</tt></li> <li><tt>06.17.2009 CATALOGS: Add ID param to CXC catalog.</tt></li> <li><tt>06.17.2009 SAMP: send unique catalog table-id for each catalog so tha multiple copies of ds9 with the same catalog loaded don't walk all over each other when connected to a hub.</tt></li> <li><tt>06.18.2009 REGIONS: Update info box, graphs, and pixel table when draging in pointer and catalog mode.</tt></li> <li><tt>06.18.2009 GUI: clean up code which enables/disables WCS menus based on current frame.</tt></li> <li><tt>06.19.2009 HV: add support for arrow keys and mouse wheel.</tt></li> <li><tt>06.19.2009 HV: add support for copy key shortcut.</tt></li> <li><tt>06.19.2009 HV: add support for Return key shortcut for Submit.</tt></li> <li><tt>06.25.2009 GUI: update crosshair, infobox, pixeltable when changing current slice in crosshair mode.</tt></li> <li><tt>06.25.2009 REGIONS: fixed a problem with create/load/save regions with mosaic. The WCS of the first mosaic segment loaded is used for all regions.</tt></li> <li><tt>06.30.2009 REGIONS: removed listwcs option for ds9 format.</tt></li> <li><tt>06.30.2009 IIS: disabled annoying 'port/addr already in use' error message.</tt></li> <li><tt>07.06.2009 BINNING: add update button to bin dialog.</tt></li> <li><tt>07.06.2009 HV: add enhancements to allow complete control over a web browser window.</tt></li> <li><tt>07.06.2009 VO: add enhancements to allow complete control over the vo dialog.</tt></li> <li><tt>07.09.2009 XPA: 'page setup' has been renamed pagesetup.</tt></li> <li><tt>07.15.2009 HV: support for sync http added.</tt></li> <li><tt>07.15.2009 VO: support for sync http added.</tt></li> <li><tt>07.15.2009 ANALYSIS: support for sync http added.</tt></li> <li><tt>07.15.2009 ANALYSIS: analysis tasks invoked via xpa or command line are now run in blocking (sync) mode.</tt></li> <li><tt>07.16.2009 XPA: added optional param to xpaget array to specify the endianness.</tt></li> <li><tt>08.05.2009 XPA: add sleep command.</tt></li> <li><tt>08.05.2009 GUI: add sleep command line option.</tt></li> <li><tt>08.10.2009 GUI: fixed command line option commands.</tt></li> <li><tt>08.10.2009 CATALOGS: for CDS catalogs, ignore the UCD at first and look for _RAJ2000 and _DEJ2000, then the UCD, then a list of common names.</tt></li> <li><tt>08.11.2009 GUI: update Magnifier in Pan mode and key arrows.</tt></li> <li><tt>08.12.2009 WINDOWS: Add support for wildcard filename expansion if invoked from DOS shell.</tt></li> <li><tt>08.12.2009 REGIONS: Add support for load template at ra dec skyframe.</tt></li> <li><tt>08.20.2009 MOSAIC: default for loading mosaics is now WCS not IRAF.</tt></li> <li><tt>08.25.2009 SAMP: implemented full XPA capabilities via SAMP.</tt></li> <li><tt>08.25.2009 I18N: make changes to fitsy++ lexer to allow non-single byte chars in filenames and paths.</tt></li> <li><tt>08.26.2009 SAMP: fixed a problem with parsing the hub.xmlrup.url.</tt></li> <li><tt>08.26.2009 XPA: update to version 2.1.10.</tt></li> <li><tt>08.27.2009 FUNTOOLS: update to version 1.4.4.</tt></li> <li><tt>09.01.2009 SAMP: fixed a problem with extra key value pairs in message.</tt></li> <li><tt>09.01.2009 CATALOGS: add default samp command.</tt></li> <li><tt>09.01.2009 CATALOGS: removed modal dialog info box calls. Messages are now updated in the status windows.</tt></li> <li><tt>09.01.2009 GUI: added new level of menu updates that are only executed when a frame is create or deleted and not everytime there is a change of state.</tt></li> <li><tt>09.03.2009 WINDOWS: disable menu updates during blinking because windows redraws the menu window each time the configuration is changed.</tt></li> <li><tt>09.03.2009 SOLARIS: removed support for Solaris<9.0. DS9 now requires libxml2 be supported by the OS.</tt></li> <li><tt>09.03.2009 GUI: added signal handling for non-windows. We now trap SIGINT and clean up before exiting.</tt></li> <li><tt>09.08.2009 I18N: fixed a problem with spaces in filename.</tt></li> <li><tt>09.08.2009 SAMP: fixed a problem using a hub that uses the Apache xmlrpc library.</tt></li> <li><tt>09.10.2009 SAMP: fixed a problem with invalid ds9.get commands.</tt></li> <li><tt>09.10.2009 GUI: cmap xpa, samp, and command line option is now much more tolerant to capitalization and spellings.</tt></li> <li><tt>09.10.2009 WINDOWS: tcc is now used for the bin filter compiler. cygwin is no longer required.</tt></li> <li><tt>09.21.2009 MACOSX: ports to Tiger (10.4), Leopard (10.5), and Snow Leopard (10.6) are now built under 10.6</tt></li> <li><tt>09.22.2009 MACOSX: fixed a problem with snowleopard. For 32bit visuals, the alpha channel is set to 0xff, not 0.</tt></li> <li><tt>09.28.2009 XPA: add XPA connect/disconnect menu options.</tt></li> <li><tt>09.29.2009 RGB: fixed a problem with displaying images with NAN.</tt></li> <li><tt>10.02.2009 MACOSX: pcc is now used for the bin filter compiler of i386 platforms if XCode is not installed./tt></li> <li><tt>10.09.2009 ANALYSIS: fixed a problem with analysis plot command to maintain backward compatibility./tt></li> <li><tt>10.12.2009 SMOOTH: fixed a problem that smooth is reset when no image is loaded. /tt></li> <li><tt><b>10.15.2009 RELEASE version 5.7</b></tt></li> </ol> </ol> </body> </html> ������������������������������������������������������������������������������������������./saods9/doc/release/r2.3.html����������������������������������������������������������������������0000644�0001750�0001750�00000005727�10415010756�014654� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 2.3 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <div align="right"> <div align="left"> </div> <h3 align="left"> <font size="-1"></font><img alt="" src="../sun.gif" align="middle" height="98" width="100"> Version 2.3 Release Notes</h3> </div> <ol> <ol> </ol> <h4> <b>Version 2.3b1</b></h4> <ol> <li> <tt>11.04.2002 add multi-language support structure.</tt></li> <li> <tt>12.02.2002 configure http user agent to 'ds9'. This fixes a problem with www.google.com</tt></li> <li> <tt>12.02.2002 add Help DS9 Home Page menu Item.</tt></li> <li> <tt>12.03.2002 Web Display: implemented 'Content-Encoding' and modified 'Mime-Type' to use new proposed FITS Mime-Type RFC.</tt></li> <li> <tt>12.03.2002 Web Display: when the mime-type is set to 'application/octet-stream', try to parse the url, looking for a valid fits or fits.gz image. If so, load as a fits. If not, save to disk.</tt></li> <li> <tt>12.03.2002 Web Display: reduced the size of fonts by -2 to more closely match netscape and internet explorer.</tt></li> <li> <tt>12.03.2002 Web Display: updated Archive menus to use new IRAS web interface.</tt></li> <li> <tt>12.03.2002 Web Display: add font size argument to HV. Now, web sites can have different default font sizes, based on what looks the best.</tt></li> <li> <tt>12.10.2002 Fixed a problem with calculating LTMV keywords from alt WCS keywords in the case of WCSNAME='PHYSICAL'</tt></li> <li> <tt>12.10.2002 Add support for TDMIN and TDMAX FITS bin table keywords.</tt></li> <li> <tt>12.10.2002 Add 'Delete All Frames' support.</tt></li> <li> <tt>12.10.2002 only use fits keyword inheritence if INHERIT keyword is present in the header.</tt></li> <li> <tt>12.11.2002 Fixed a problem with WCS headers and INHERIT, which resulted in duplicate keywords. This made wcssubs very confused.</tt></li> <li> <tt>12.11.2002 Add 'Delete Selected Regions' to Regions menu.</tt></li> <li> <tt>12.11.2002 Add confirmation dialog to 'Delete All Regions'.</tt></li> <li> <tt>12.12.2002 Display Header List dialog is now 40 chars wide.</tt></li> <li> <tt>12.12.2002 Web Display: add initial coordinates to ADS archive sites</tt></li> <li> <tt>12.16.2002 Add *.fit and *.fts to fits dialog box templates.</tt></li> <li> <tt>12.16.2002 Add support for GUI Groups, based on region tags.</tt></li> <li> <tt>12.17.2002 Add HSV colormap.</tt></li> <li> <tt>12.18.2002 Fixed a problem with the PANDA Region at zooms other than 1.</tt></li> <li> <tt>12.19.2002 DS9 version 2.3b1 released to the public.</tt></li> </ol> </ol> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> </body> </html> �����������������������������������������./saods9/doc/release/r1.8.html����������������������������������������������������������������������0000644�0001750�0001750�00000037634�10415010755�014661� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 1.8 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 1.8 Release Notes</h3> <ol> <h4> <b>Version 1.8.7.8</b></h4> <ol> <li> <tt>Dialog windows now use the same colormap as the parent window.</tt></li> <li> <tt>Fixed a problem with the tile xpa point.</tt></li> </ol> <h4> <b>Version 1.8.7.7</b></h4> <ol> <li> <tt>Fixed a problem with updating the Contour dialog box.</tt></li> <li> <tt>Fixed another problem with .gz, .Z, and .z</tt></li> <li> <tt>Coordinate Grids now support WCS of projection TNX.</tt></li> <li> <tt>Improved the appearance of Grids while in Internal Mode.</tt></li> </ol> <h4> <b>Version 1.8.7.6</b></h4> <ol> <li> <tt>Fixed a problem with running under linux and displaying on Solaris.</tt></li> <li> <tt>Fixed a problem with Truecolor 8 support.</tt></li> <li> <tt>Added Coordinate Grids!</tt></li> <li> <tt>Mouse coordinates may be printed by pressing the 'C' key. Which coordinates are printed may be specified via the 'Edit:Preferences:Print Coordinates' menu.</tt></li> <li> <tt>Default Region Parameters now can be specified via the Preferences menu.</tt></li> <li> <tt>Contour Dialog has been redesigned and Contour scales and limits added.</tt></li> <li> <tt>Fixed a problem with Contour scales log, squared, and sqrt.</tt></li> <li> <tt>The user can save and load contours via the Contour Parameter Dialog Box. The contours may be any supported coordinate system.</tt></li> <li> <tt>The user can save and load contour levels via the Contour Parameter Dialog Box.</tt></li> <li> <tt>Fixed a problem with file names that contain .z, .Z, .gz</tt></li> </ol> <h4> <b>Version 1.8.7.5</b></h4> <ol> <li> <tt>Fixed a problem with Truecolor 24 bit visuals under Solaris 7</tt></li> <li> <tt>Fixed a problem with selecting Ruler Regions that are horizontal or vertical.</tt></li> </ol> <h4> <b>Version 1.8.7.4</b></h4> <ol> <li> <tt>Fixed a major bug with mosaics with an amplifier that reads out in reverse and the data has been flipped before writing.</tt></li> </ol> <h4> <b>Version 1.8.7.3</b></h4> <ol> <li> <tt>New wcssubs: Fixed a problem with wcs of RA--NCP and DEC--NCP</tt></li> <li> <tt>Fixed a problem with 'Scale:User Limits'</tt></li> <li> <tt>Removed a warning message if xpa is not available</tt></li> <li> <tt>The coordinate info box is updated while editing regions</tt></li> <li> <tt>Fixed a problem with the window manager closing region dialog boxes, regions list dialog box, and analysis result dialog box</tt></li> <li> <tt>List Regions, Display Header, and the Analysis Dialog box now have options for printing, saving, and searching the contents.</tt></li> <li> <tt>Display Header now supports multiple dialogs, one for each frame.</tt></li> <li> <tt>Fixed a problem with parsing region files and the LINE region.</tt></li> <li> <tt>Fixed a problem with polygon regions and PROS region file formats.</tt></li> <li> <tt>All regions are deleted when 'Clear Frame' or 'Open' action taken.</tt></li> <li> <tt>When creating Text regions, the 'Cancel' button now works.</tt></li> <li> <tt>'Clear Frame' has been moved from 'File menu to 'Frame' menu.</tt></li> <li> <tt>shell variable DS9_ARRAY may be used to define default array parameters. Example: $export DS9_ARRAY='[dim=512,bitpix=-32]'</tt></li> <li> <tt>shell variable DS9_BINKEY may be used to define default FITS bin table cols. Example: $export DS9_BINKEY='[bin=rawx,rawy]'</tt></li> <li> <tt>new 'Open Array...' menu item has been added to the 'File' menu.</tt></li> <li> <tt>Changes to following ommand line options:</tt></li> <br> <tt>-array, -mosaicimage, -mosaicimages, -mosaicsegment, -shared</tt> </ol> <h4> <b>Version 1.8.7.2</b></h4> <ol> <li> <tt>Add the -iconify command line option.</tt></li> <li> <tt>FITS Region Binary Table Region file format is supported for input.</tt></li> </ol> <h4> <b>Version 1.8.7.1</b></h4> <ol> <li> <tt>Now using BLT 2.4l</tt></li> <li> <tt>Now using X11R6</tt></li> <li> <tt>Fixed a problem with selecting blink frames multiple times.</tt></li> <li> <tt>Fixed a problem with Line Regions always printing with arrows.</tt></li> <li> <tt>Fixed a problem when a printing error occurs.</tt></li> <li> <tt>External File support is now available.</tt></li> <li> <tt>External Analysis support is now available.</tt></li> <li> <tt>Added Frame refresh menu item.</tt></li> <li> <tt>Fixed a problem with shared memory size.</tt></li> <li> <tt>XPA frame has changed. The argument is now only a number, not a name. This clears up some problems with syntax. If the frame does not exists, the frame is created. The option 'frameno' is provided for backward compatiblity.</tt></li> <br> <tt>Example: xpaset -p ds9 frame 2 # goto frame name 'frame2'</tt> <br> <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xpaset -p ds9 frame frameno 4 # goto frame name 'frame4'</tt> </ol> <h4> <b>Version 1.8.7</b></h4> <ol> <li> <tt>Scale type 'Ln' has been removed.</tt></li> <li> <tt>Contour scales Log, Sqrt, and Squared have been fixed.</tt></li> <li> <tt>Contour Dialog box is now non-modal.</tt></li> <li> <tt>Fixed a problem with the FITS Header Dialog box.</tt></li> <li> <tt>Support for &gt; 256 colors in truecolor mode.</tt></li> <li> <tt>New PS level 2 drivers that support more than 256 colors.</tt></li> <li> <tt>Crosshairs will now appear in the magnifier if graphics enabled.</tt></li> <li> <tt>Improved on the gui in terms of tile and blink. Now ds9 is in one of 3 display modes: single frame, tile frames, and blink frames.</tt></li> <li> <tt>You can now Show or Hide frames, via the Frame:Show/Hide menu. When a frame is 'Hidden', it does not appear in Single, Tile, or Blink mode, and can not be selected via the Frames menu.</tt></li> <li> <tt>Added a new mode: Examine. While in examine mode, if you click, a new frame is created, loaded with the same data, and scaled about the point you clicked. If the base frame is a FITS image, it is zoomed, if the base frame is a FITS binary table, it is blocked. The file is not loaded again, but shared between frames, requiring little additional memory. When you clear or delete a base frame, all examine frames are deleted. Options as to how many frames are created and the scale factor may be specified via the preferences menu.</tt></li> </ol> <h4> <b>Version 1.8.6.9</b></h4> <ol> <li> <tt>Support for FITS Bin Table Type 'U' (unsigned short) and Type 'V' (unsigned long). Note these are not supported by the FITS standard.</tt></li> <li> <tt>Added new default colormap 'Cool'</tt></li> <li> <tt>SAOtng and PROS Regions file support: if wcs coords are used, yet no wcs system has been specified, the native wcs of the file is used.</tt></li> <li> <tt>Regions now are available in the magnifier (user prerference)</tt></li> <li> <tt>Fixed a problem with working with line regions at high zoom factors</tt></li> <li> <tt>Fixed a problem with working with polygon regions at high zoom factors</tt></li> </ol> <h4> <b>Version 1.8.6.8</b></h4> <ol> <li> <tt>Fixed again problems with FITS Tables, Binning, Physical Coords, and WCS</tt></li> </ol> <h4> <b>Version 1.8.6.7</b></h4> <ol> <li> <tt>Binning on a third column is now supported</tt></li> <li> <tt>Fixed a problem with FITS Tables and bit fields</tt></li> </ol> <h4> <b>Version 1.8.6.6</b></h4> <ol> <li> <tt>Added new 'Zoom to Fit Window' function</tt></li> <li> <tt>Added new 'Block to Fit Window' function</tt></li> <li> <tt>Added 'Block to...' function</tt></li> <li> <tt>'Mode' menu has been moved to under 'Edit' menu.</tt></li> <li> <tt>Show/Hide Panner and Magnifier via the prefs, command line, and xpa</tt></li> <li> <tt>Tear-Off menus now have window titles</tt></li> <li> <tt>minor changes to xpa options syntax (no more -options), see <a href="xpa.html">XPA</a> for more info.</tt></li> <li> <tt>xpa colormap is no longer case sensitive</tt></li> <li> <tt>fixed a problem with tables and physical coordinates</tt></li> <li> <tt>fixed a problem with interactive pan/zoom/rotate and coordinates</tt></li> </ol> <h4> <b>Version 1.8.6.5</b></h4> <ol> <li> <tt>Fixed a problem with reading IRAF Pros regions files</tt></li> </ol> <h4> <b>Version 1.8.6.4</b></h4> <ol> <li> <tt>Fixed a problem with Little Endian Machines and doubles in FITS bin tables</tt></li> </ol> <h4> <b>Version 1.8.6.3</b></h4> <ol> <li> <tt>Now supports SAOtng regions files in physical coordinates.</tt></li> </ol> <h4> <b>Version 1.8.6.2</b></h4> <ol> <li> <tt>Improved Region clipping</tt></li> <li> <tt>Fixed a problem with finding the Preferences File</tt></li> </ol> <h4> <b>Version 1.8.6.1</b></h4> <ol> <li> <tt>Fixed a rather nasty bug with rendering Circle Regions. This bug would sometimes cause the X Server to hang.</tt></li> <li> <tt>Now does a better job of creating the default size regions.</tt></li> <li> <tt>Frame buttons Prev and Next now will cycle thru all frames.</tt></li> </ol> <h4> <b>Version 1.8.6</b></h4> <ol> <li> <tt>Automatic Tile Mode with multiple files on command line</tt></li> <li> <tt>Fixed problems with HTTP and FTP access</tt></li> <li> <tt>Fixed another problem with FITS Bin tables and regions</tt></li> <li> <tt>There are now 2 modes for interactive panning-- default click to center</tt></li> <ul> <li> <tt>Click to Center (SAOimage method)</tt></li> <li> <tt>Drag to Center (Native DS9 method)</tt></li> </ul> <li> <tt>New frames use the current user scale limits and colorscale.</tt></li> <li> <tt>Added frameno option to FRAME xpa point</tt></li> <li> <tt>REGION SAVE FORMAT menu now reflects coords available</tt></li> </ol> <h4> <b>Version 1.8.5</b></h4> <ol> <li> <tt>New GUI Buttons Bar</tt></li> <li> <tt>Rearranged Menus, smaller desktop footprint</tt></li> <li> <tt>New Tiling algorithms</tt></li> <li> <tt>Truecolor 8bit support</tt></li> <br> <tt>$ds9 -visual truecolor8</tt> <li><tt>Truecolor 16bit support</tt></li> <br> <tt>$ds9 -visual truecolor16</tt> <li><tt>Truecolor 24bit enhancements</tt></li> <br> <tt>$ds9 -visual truecolor24</tt> <li><tt>Pseudocolor 8bit enhancements</tt></li> <br> <tt>$ds9 -visual pseudocolor8</tt> <li><tt>Regions Modes now intergrated into Pointer Mode</tt></li> <li> <tt>New colormaps have been added</tt></li> <li> <tt>Fixed a problem with FITS ext names</tt></li> <li> <tt>Editing RECTANGLE regions resizes about the opposite node, not the center</tt></li> <li> <tt>Polished the GUI for creating regions</tt></li> <li> <tt>list/save regions in saoimage format now outputs points</tt></li> <li> <tt>Fixed a problem with existing regions and blocking</tt></li> </ol> <h4> <b>Version 1.8.4.1</b></h4> <ol> <li> <tt>Fixed problem with rotate mode and updating menus</tt></li> </ol> <h4> <b>Version 1.8.4</b></h4> <ol> <li> <tt>24 bit color support</tt></li> <li> <tt>New Postscript drivers</tt></li> <ul> <li> <tt>CMYK support</tt></li> <li> <tt>Variable resolution</tt></li> </ul> <li> <tt>Online Documentation!</tt></li> <li> <tt>Fixed a problem with Physical Coordinates and FITS Bin Tables</tt></li> <li> <tt>Sticky file names have been implemented</tt></li> <li> <tt>Fixed a problem with standard dialogs and double/triple clicks</tt></li> <li> <tt>If Header window is open, load will display the new header</tt></li> <li> <tt>Delete Frame now asks for confirmation</tt></li> <li> <tt>Fixed a problem with arrays and xpa</tt></li> <li> <tt>Fixed a problem with FITS keyword inheritance</tt></li> <li> <tt>for FITS bin tables, the keywords BIN, BINKEY, and KEY are equivalent</tt></li> <li> <tt>Fixed a problem with regions and tiled frames</tt></li> <li> <tt>Keystroke shortcuts have been added to the GUI</tt></li> <li> <tt>Added WCS menu items to preferences saved</tt></li> <li> <tt>Added 'Clear Preferences' to preferences menu</tt></li> <li> <tt>Mouse button 2 is now bound to 'Pan' function</tt></li> <li> <tt>Minor changes to layout of Small and Large Infomation Panel</tt></li> <li> <tt>Fixed problem with pseudocolor 8 and private colormaps</tt></li> </ol> <h4> <b>Version 1.8.3</b></h4> <ol> <li> <tt>Fixed a problem with arrays and xpa</tt></li> <li> <tt>xpaget regions: you now can specify coord/coordformat/format</tt></li> <li> <tt>$ xpaget ds9 regions -format pros -coord fk4 -coordformat hms</tt></li> <li> <tt>Interactive rotation is now works!</tt></li> <li> <tt>PanZoom Dialog and Rotate Dialog now have 'Apply' buttons</tt></li> <li> <tt>Preferences have been implemented. 'Save Preferences' will save the current values of the 'Preferences' and 'View' menus in $HOME/.ds9.prefs. On startup, this values will be used.</tt></li> <li> <tt>Source user tcl file has been implemented. If $HOME/.ds9 exists, it will be sourced on start up.</tt></li> <li> <tt>New Standard Dialog box has been implemented. User now has a choice of motif, windows, or 'blue plate special' dialog boxes.</tt></li> <li> <tt>'$ xpaget ds9 file' now returns full file name</tt></li> <li> <tt>More tolerant of non-existent or bad files.</tt></li> <li> <tt>More robust checking of mosaic files</tt></li> <li> <tt>FITS keyword inheritance is now supported.</tt></li> <li> <tt>Mosaic Multiple Extension Fits files are now supported.</tt></li> <li> <tt>Coordinate name 'CCD' has been changed to 'Physical'</tt></li> </ol> <h4> <b>Version 1.8.2</b></h4> <ol> <li> <tt>Support for raw data arrays</tt></li> <br> <tt>$ ds9 "foo.arr[xdim=512,ydim=512,bitpix=-32]"</tt> <br> <tt>$ ds9 "foo.arr[xdim=512,ydim=512,bitpix=16,skip=100]"</tt> <br> <tt>$ ds9 "foo.arr[dim=1024,bitpix=8,bigendian]"</tt> <br> <tt>$ ds9 "foo.arr[dim=1024,bitpix=8,arch=littleendian]"</tt> <li><tt>xpa support for raw data arrays</tt></li> <br> <tt>$ cat foo.arr | xpaset ds9 array "[dim=512,bitpix=16]"</tt> </ol> <h4> <b>Version 1.8.1.2</b></h4> <ol> <li> <tt>fixed problem with printing</tt></li> </ol> <h4> <b>Version 1.8.1.1</b></h4> <ol> <li> <tt>fix problem with change of xpa api</tt></li> </ol> <h4> <b>Version 1.8.1</b></h4> <ol> <li> <tt>fix blockfactor,blockbuffersize, and blockfunction command line options.</tt></li> <li> <tt>fixed problem with Marker type Line Dialog box.</tt></li> <li> <tt>Added new marker type: Ruler.</tt></li> <li> <tt>fixed major problem with regions files and loading via xpa.</tt></li> <li> <tt>Added arrows to line marker.</tt></li> <li> <tt>more robust error handling.</tt></li> <li> <tt>bin table extension names and column names are no longer case sensitive.</tt></li> <li> <tt>fixed problem with printing to different page sizes</tt></li> </ol> <h4> <b>Version 1.8</b></h4> <ol> <li> <tt>Fixed a major memory leak</tt></li> <li> <tt>Fixed a XPA printing problem</tt></li> <li> <tt>Fixed problem with LOG scale</tt></li> <li> <tt>the xpa application name is now "ds9".</tt></li> <li> <tt>the xpa class name is now "DS9"</tt></li> <br> <tt>example:</tt> <br> <tt>$ xpaget ds9 version # get version number from just ds9</tt> <br> <tt>$ xpaget DS9:ds9 version # get version number from just ds9</tt> <li><tt>$ xpaget DS9: version # get version number for all DS9 apps</tt></li> <li> <tt>Markers!</tt></li> </ol> </ol> </body> </html> ����������������������������������������������������������������������������������������������������./saods9/doc/release/r1.5.html����������������������������������������������������������������������0000644�0001750�0001750�00000005560�10415010755�014647� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 1.5 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 1.5 Release Notes</h3> <ul> <h4> <b>Version 1.5</b></h4> <ol> <li> <tt>Fixed problem with Windows style Open file dialog box</tt></li> <li> <tt>Now supports following coords systems:</tt></li> <ul> <li> <tt>Image (was Logical)</tt></li> <li> <tt>CCD (was Physical)</tt></li> <li> <tt>Detector (was Mosaic Physical)</tt></li> <li> <tt>Amplifier</tt></li> <li> <tt>WCS</tt></li> </ul> <li> <tt>New version of Doug Mink's WCS libs</tt></li> <li> <tt>Fixed minor problems with interactive Pan Mode</tt></li> <li> <tt>Added "Source TCL" file support</tt></li> <li> <tt>Open Mosaic Image command</tt></li> <br> <tt>Will open multiple fits files as a mosaic.</tt> <br> <tt>Supports following patterns:</tt> <br> <tt>*#.fits</tt> <br> <tt>*_#.fits</tt> <br> <tt>*.IM*.fits</tt> <li><tt>Open Mosaic Segment command</tt></li> <li> <tt>Fixed minor problem with zscale and high energy data</tt></li> <li> <tt>The Magnifier now Works!</tt></li> <br> <tt>There are two algorithms available (under Preferences)</tt> <br> <tt>Magnification can be selected via preferences</tt> <ol> <li> <tt>Fast (and less Accurate)</tt></li> <li> <tt>More Accurate (and slower)</tt></li> </ol> <li> <tt>Improvements to Dialogs</tt></li> <li> <tt>Now supports (unoffical)FITS data size -16 (unsigned short)</tt></li> <li> <tt>Support for byte swapped processors</tt></li> <li> <tt>Support large images &gt; 8k x 8k</tt></li> <li> <tt>Loading images are now 10x faster</tt></li> <li> <tt>Supports BLANK Fits keyword</tt></li> <li> <tt>&nbsp;Menu Short Cuts have been added (use Alt key, such as Alt-f for Frame menu)</tt></li> <li> <tt>Horizontal and Verticle Graphs now work in all modes (not just Crosshair)</tt></li> <li> <tt>ds9 will accept fits files via STDIN (ie. $ cat foo.fits | ds9 -file -&nbsp; )</tt></li> <li> <tt>command line argument support (ie. $ds9 -? for list)</tt></li> <li> <tt>crosshair position is more accurate</tt></li> <li> <tt>added new scales: 'ln' and 'log'.</tt></li> <ol> <li> <tt>ln --&nbsp; SAOimage natural log based algorithm</tt></li> <li> <tt>log--&nbsp; IRAF log base 10 algorithm</tt></li> </ol> <li> <tt>Support for Postscript printing (Level 1 and Level 2)</tt></li> <li> <tt>Blinking is now supported</tt></li> </ol> </ul> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r1.9.html����������������������������������������������������������������������0000644�0001750�0001750�00000030127�10415010755�014650� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 1.9 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 1.9 Release Notes</h3> <ol> <h4> <b>Version 1.9.8</b></h4> <ol> <li> <tt>fixed a problem with listing regions that are very long. the size limit has been increased from 1024 to 8192</tt></li> <li> <tt>completed MS Windows port</tt></li> <li> <tt>fixed a problem with large polygons in FITS Regions bin table format</tt></li> <li> <tt>ds9 will now correctly load a FITS Extension image without a primary header</tt></li> <li> <tt>xpa wcs [reset|replace|append] function added</tt></li> <li> <tt>the default nameserver is now 'simbad-sao'</tt></li> </ol> <h4> <b>Version 1.9.7.2</b></h4> <ol> <li> <tt>fixed a problem with reading arrays via xpa and extra data an the end of the image</tt></li> <li> <tt>fixed a problem with region callbacks and actions on regions within the callback</tt></li> <li> <tt>fixed a memory leak with deleteing polygon vertices</tt></li> <li> <tt>double click on region with select=0 no longers opens a dialog</tt></li> <li> <tt>added select property to ds9 region properties list</tt></li> <li> <tt>for default annulus, ellipse annulus, box annulus, the number of annuli is now used when the user click and drags</tt></li> <li> <tt>fixed a problem with ellipse annulus and box annulus and zero inner radius</tt></li> <li> <tt>fixed a problem with box and boxannuls and updating the region dialog coords</tt></li> <li> <tt>fixed a problem with turning off/on active frames</tt></li> <li> <tt>fixed a problem with saving fits images created from a fits image extension</tt></li> <li> <tt>added new 'new' option to xpa points 'FITS' and 'ARRAY' to create a new frame before loading the new image</tt></li> <li> <tt>completed port HP-UX</tt></li> </ol> <h4> <b>Version 1.9.7.1</b></h4> <ol> <li> <tt>fixed a problem with prefs and sourcing external tcl files</tt></li> </ol> <h4> <b>Version 1.9.7</b></h4> <ol> <li> <tt>mktclapp is now used to build the application from tcl</tt></li> <li> <tt>fixed a problem with HMS and hour=0</tt></li> <li> <tt>fixed a problem with parseing old ds9 region files and 'global'</tt></li> <li> <tt>support for SAOtng Regions file format has been restored</tt></li> <li> <tt>upgraded to tcl/tk 8.3.2</tt></li> <li> <tt>upgraded to blt2.4u</tt></li> <li> <tt>minor changes made to ciao regions file format</tt></li> <li> <tt>fixed a problem with Ciao FITS regions files</tt></li> </ol> <h4> <b>Version 1.9.6</b></h4> <ol> <li> <tt>Added Truecolor Colorbar preference</tt></li> <li> <tt>Fitsy++ now supports fixed and free format keyword strings correctly</tt></li> <li> <tt>While in 'Pan' mode, the arrow keys may be used to pan the image</tt></li> <li> <tt>Custom Page Setup in mm is now supported</tt></li> <li> <tt>Region Text string can now contain both a ' and "</tt></li> <li> <tt>Region File format for text now supports the following text strings:</tt></li> <ol> <tt>text="This is a test"</tt> <br> <tt>text="This is a test of '"</tt> <br> <tt>text='This is a test of "'</tt> <br> <tt>text={This is a test of ' and "}</tt> </ol> <li> <tt>DS9 will now correctly parse a regions spec with a delim of ';'</tt></li> <li> <tt>XPA tcl command now runs in the same context frame as source and ds9</tt></li> <li> <tt>Fixed a problem with the Colorbar contrat/bias dialog and truecolor</tt></li> <li> <tt>Fixed a problem with BOX list/save format</tt></li> <li> <tt>Fixed a problem with contours in that one extra level was generated when using the low/high and number of contours controls</tt></li> <li> <tt>Updated to Doug Mink's wcssub version 2.8.1, which fixes a problem with keywords without an '='</tt></li> <li> <tt>Fixed a problem with printing Region Text with '(', ')', or '\' in it.</tt></li> <li> <tt>Region file format is now valid for both reading and writing Region files</tt></li> <li> <tt>Implemented new Regions file format, version 3</tt></li> <li> <tt>Fixed a problem with IRAF and the 'f' and 'c' keys</tt></li> <li> <tt>Images with odd length will center on pixel boundaries</tt></li> <li> <tt>The number of bins if determined from TLMIN/TLMAX will now vary, based on column type (integer or real). The bin space for integer is TLMIN-.5 to TLMAX +.5 and for real TLMIN to TLMAX.</tt></li> <li> <tt>Binning Dialog box is now non-modal</tt></li> <li> <tt>Made improvements in the resolution of coordinates</tt></li> <li> <tt>Added the -version command line option</tt></li> <li> <tt>Fixed a problem with bad name resolution and NED-SAO</tt></li> <li> <tt>Fixed a problem with -grid and -contour command line options</tt></li> <li> <tt>Add -format, -coord, -coordformat, and -delim to xpaget regions</tt></li> <li> <tt>Added FITS bin table filtering</tt></li> <li> <tt>Changed XPA BLOCK to BIN</tt></li> <li> <tt>bin factors of less than 1 but greater that 0 are now allowed</tt></li> <li> <tt>fixed a problem with ecliptic coords and FITS BIN TABLES with wcs</tt></li> <li> <tt>Fixed a problem with contours and high resolution values</tt></li> <li> <tt>Added algorithm method to contours</tt></li> <li> <tt>Fixed a problem with contours and re-binning a FITS bin table</tt></li> <li> <tt>Changes to BIN commandline options to mirror BIN xpa options</tt></li> <li> <tt>Added raise/lower command line options</tt></li> <li> <tt>Added raise/lower xpa options</tt></li> <li> <tt>Cut/Paste to/from the primary selection is now provided</tt></li> <li> <tt>Added new type of grid, Exterior Axis with interior numerics</tt></li> <li> <tt>Fixed problems with grid numerics and rotation of non-zero</tt></li> <li> <tt>Fixed a problem with graphs and no FITS loaded</tt></li> <li> <tt>Added Regions Delimiter menu</tt></li> <li> <tt>Added ANNULUS, ELLIPSE ANNULUS, and BOX ANNULUS regions</tt></li> </ol> <h4> <b>Version 1.9.5</b></h4> <ol> <li> <tt>Fixed a problem with Saving FITS images on byte swaped platforms</tt></li> <li> <tt>FITS Bin table support now uses TLMIN/TLMAX to determine binning buffersize up to the user specified limit</tt></li> <li> <tt>Fixed the XPA Regions format,coord, and coordformat calls</tt></li> <li> <tt>Changed the behavior of $xpaget ds9 regions [format|coord|coordformat]</tt></li> </ol> <h4> <b>Version 1.9.4</b></h4> <ol> <li> <tt>Added ability to save a FITS bin table as a FITS image</tt></li> <li> <tt>Added xpa point to support the above</tt></li> <li> <tt>Fixed a problem with loading arrays</tt></li> <li> <tt>Added support for the Rosat All Sky Survey</tt></li> <li> <tt>Added command line support for DSS and RASS</tt></li> <li> <tt>Fixed a problem with displaying LINEAR WCS</tt></li> <li> <tt>DS9 is now much more tolarent of FITS files in which the data segment is short in size, ie, is not a multiple of FITBLOCK (2880 bytes)</tt></li> <li> <tt>Fixed a problem with FITS files with headers with 100's or 1000's of comments or history keywords</tt></li> <li> <tt>Enhanced Preferences support</tt></li> <li> <tt>The information panel is now updated during blinking</tt></li> <li> <tt>Fixed a problem with long frame names</tt></li> <li> <tt>Added new fuctionality to the 'Frame' xpa point</tt></li> <li> <tt>Fixed a memory problem that caused problems with the Alpha port</tt></li> <li> <tt>Fixed a problem with regions in sexagesimal format and NATIVE WCS</tt></li> <li> <tt>DS9 is now much mor tolerant of sexagesimal format regions that do not map directly on top of a image</tt></li> <li> <tt>Implemented the new default region format</tt></li> <li> <tt>Fixed a problem with Polygon regions and creating/moving vertices</tt></li> <li> <tt>Added Colormap Contrast and Bias Dialog</tt></li> <li> <tt>Fixed a problem with Box regions and negative width and height</tt></li> <li> <tt>Angle has been added to the Ruler Region dialog box</tt></li> <li> <tt>Length has been added to the Line Region dialog box</tt></li> <li> <tt>Fixed a problem with Region Text and the '"' character</tt></li> <li> <tt>Added XPA point for DSS</tt></li> <li> <tt>Added XPA point for RASS</tt></li> <li> <tt>Added XPA point for Name Servers</tt></li> <li> <tt>Fixed a problem with rotated Regions and IRAF images</tt></li> <li> <tt>Added XPA point xpaget fits</tt></li> <li> <tt>Added XPA point xpaset file save &lt;filename&gt;</tt></li> <li> <tt>xpa regions may now be delimited by nl or semicolon</tt></li> </ol> <h4> <b>Version 1.9.3</b></h4> <ol> <li> <tt>Fixed a problem with preferences. The prefs file was not parsed.</tt></li> <li> <tt>Fixed a problem with xpaset ds9 fits and multiple ext fits files</tt></li> <li> <tt>Fixed some minor problems with xpa and blink,frame</tt></li> <li> <tt>Added xpaset ds9 frame [first|next|prev|last]</tt></li> <li> <tt>Added printing of pixel tables</tt></li> <li> <tt>Added Copy/Paste support for pixel tables</tt></li> <li> <tt>Fixed a problem with changing the size of pixel tables</tt></li> <li> <tt>'F' toggles Info Pannel 'freeze' mode.</tt></li> <li> <tt>Full shared memory support has been added</tt></li> <br> <tt>$xpaget ds9 shm</tt> <br> <tt>$xpaset -p ds9 shm 102 8640</tt> <br> <tt>$xpaset -p ds9 shm shmid 102 8640 foo[2]</tt> <br> <tt>$xpaset -p ds9 shm mosaicimage key 100 10240 foo</tt> <br> <tt>$xpaset -p ds9 shm mosaic key 100 10240 foo[3]</tt> <br> <tt>$xpaset -p ds9 shm array shmid 102 8640 [dim=32,bitpix=16]</tt> <p><tt>$xpaset -p ds9 update 1 100 100 200 200 # update HDU1 in image coords</tt> <br> <tt>$xpaset -p ds9 update 3 400 400 500 500 # update HDU3 in image coords</tt></p> </ol> <h4> <b>Version 1.9.2</b></h4> <ol> <li> <tt>Fixed yet another problem with contours</tt></li> <li> <tt>Fixed a problem with loading arrays with bitpix of -64</tt></li> </ol> <h4> <b>Version 1.9.1</b></h4> <ol> <li> <tt>Fixed the 'Analysis' menu item 'DSS'</tt></li> <li> <tt>provided for more backward compatibility with old preference files</tt></li> <li> <tt>Fixed a problem with IRAF support and changing buffer sizes</tt></li> <li> <tt>Fixed a problem with contours and reading incorrectly levels</tt></li> <li> <tt>Fixed a problem with printing and pan/rotation/zoom</tt></li> <li> <tt>Fixed a problem with Grid Rotated numbers and MSB/LSB cross-platform</tt></li> </ol> <h4> <b>Version 1.9</b></h4> <ol> <li> <tt>DS9 now supports IRAF!</tt></li> </ol> <ol> <li> <tt>point regions now have the include/exclude property</tt></li> <li> <tt>crosshairs will now print</tt></li> <li> <tt>fixed a problem with contours and the contour dialog is visible</tt></li> <li> <tt>fixed a problem with the wcs of FITS files with very long headers</tt></li> <li> <tt>added Pixel Table feature</tt></li> <li> <tt>contours now appear in the magnifier with graphics enabled</tt></li> <li> <tt>John Roll's Tcl Ast package has been added</tt></li> <li> <tt>DS9 is now more tolerant of 'SIMPLE = F' type FITS files</tt></li> <li> <tt>fixed a problem with render speed in single frame mode and multiple frames loaded</tt></li> <li> <tt>The Pan Zoom Rotate Dialog Box is now Non-Modal</tt></li> <li> <tt>Name Resolution support has been added</tt></li> <li> <tt>DSS support has been added</tt></li> <li> <tt>A problem with contours has been corrected. if contours levels = n, then n+1 contours are actually rendered</tt></li> <li> <tt>DEC Alphas are now supported</tt></li> <li> <tt>SGI is now supported</tt></li> <li> <tt>LINEAR WCS is now fully supported</tt></li> </ol> </ol> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r2.1.html����������������������������������������������������������������������0000644�0001750�0001750�00000053351�10415010756�014646� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 2.1 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 2.1 Release Notes</h3> <ol> <h4> <b>Version 2.1</b></h4> <ol> <li> <tt>04.05.2002 fixed a problem with xpa contour load.</tt></li> <li> <tt>04.22.2002 ds9 version 2.1 released to the public.</tt></li> </ol> <h4> <b>Version 2.1b7</b></h4> <ol> <li> <tt>04.02.2002 upgrade to XPA 2.1.0e2. This fixes a problem with xpa and linux/linuxppc.</tt></li> <li> <tt>04.03.2002 fixed a problem with AST. plot.c, line 19463, change parameter 'force' from 1 to 0 in call to 'CheckLabels'. Sometimes we were seeing adj labels that where the same. This change makes sure that the labels are 'reduced' if we have this condition.</tt></li> <li> <tt>04.03.2002 ds9 will now automatically open as a bin table fits extension named EVENTS, STDEVT, and RAYEVENT.</tt></li> <li> <tt>04.03.2002 when trying to find an image to open in relax mode (ie the use did not specify an extension), ds9 will not find a valid image if the length of either axis is 0.</tt></li> <li> <tt>04.03.2002 now check for Ghostscript version 6.50 or higher when invoking Save As.</tt></li> <li> <tt>04.03.2002 add help application preference. Users can now choose between Netscape and Mozilla as the prefered help application.</tt></li> <li> <tt>04.04.2002 ds9 version 2.1b7 released to the public.</tt></li> </ol> <h4> <b>Version 2.1b6</b></h4> <ol> <li> <tt>02.04.2002 upgraded to ast version 1.8.6. Modified ast to use sscanf() for all platforms except Darwin. Darwin uses astSscanf(), which works around a problem with sscanf() on MacOSX, with format strings of the following format: sscanf(str, " %s %n", foo, &amp;nc).</tt></li> <li> <tt>02.04.2002 changed fity++ primary_/head_ header relationship. primary_ is only set if there is a primary header is available and different from head_.</tt></li> <li> <tt>02.04.2002 wsc's are init'd with both the head_ and the primary_ (if available) to handle the case where wcs keywords are spread between hdu nd primary headers in mulitiple extension files.</tt></li> <li> <tt>02.06.2002 all xpa commands are now 'catch{}' to invoke a procedure that will unwind the watch cursor stack. Hopefully, no more stuck watch cursors.</tt></li> <li> <tt>02.07.2002 add <i>color</i> and <i>width</i> parameters to contours paste command. defaults are <i>green</i> and <i>1</i></tt></li> <li> <tt>02.08.2002 fixed a problem with the FRAME menu. It was cutting off the last separator.</tt></li> <li> <tt>02.12.2002 AST grid still does not support ICRS properly. When a user sets the coordinate system to ICRS, the actually parameters sent to the AST grid code is FK5</tt></li> <li> <tt>02.13.2002 for XPA points array, fits, regions, and wcs (fillbuf=false), manually flush the buffer at the end to make sure no data is left</tt></li> <li> <tt>02.13.2002 ecliptic coords from wcssubs corrected by new version of wcs/wcscon.c</tt></li> <li> <tt>02.13.2002 AST grids, corrected the MDJ-OBS keyword generated to generate the correct EPOCH.</tt></li> <li> <tt>02.13.2002 adjusted the EQUINOX value for ECLIPTIC coords for ast grids to agree with wcssubs. Seems for ecliptic coords, wcssubs and ast use two slightly different interpretations of the EQUINOX value.</tt></li> <li> <tt>02.13.2002 fixed a problem with histogram equalization introduced in version 2.1b5.</tt></li> <li> <tt>02.14.2002 fixed a problem with titles in plot(stdin). We now take the first line, and starting from the end, pick off the dimension, x and y axis titles, and the remainder is taken as the plot title. It can contain spaces and special characters such as '[]'</tt></li> <li> <tt>02.14.2002 add 'Always create new plot' option to prefs</tt></li> <li> <tt>02.14.2002 add multiple analysis plots, unless prefs are unset</tt></li> <li> <tt>02.14.2002 change default annulus and panda to 1 annuli</tt></li> <li> <tt>02.14.2002 enable multiple array loads via blueplate dialog</tt></li> <li> <tt>02.14.2002 reset,append, and replace wcs now processes OBJECT keyword</tt></li> <li> <tt>02.15.2002 fixed a problem with grid format of degrees. Sometimes, the incorrect format would be used. This was corrected by up'ng the number of digits displayed to d.3</tt></li> <li> <tt>02.21.2002 upgraded to AST 1.8.7</tt></li> <li> <tt>02.21.2002 upgraded to WCS 3.0.7</tt></li> <li> <tt>02.22.2002 fixed a problem with Ascii Tables in fitsy++. The column offset is now calculated from TBCOLn if present.</tt></li> <li> <tt>02.22.2002 simplied columns in fitsy++. Now all columns have a value(char* ptr, int i) and str(char* ptr, int i) procedure.</tt></li> <li> <tt>02.22.2002 add support for HST WFPC2 mosaics</tt></li> <li> <tt>02.25.2002 fixed a problem with 'marker command'. The command STRING must be quoted by '\{' '\}' before being pasted to the Frame parser.</tt></li> <li> <tt>02.26.2002 add $ERROR/ERROR: support for analysis $plot(stdin) macro.</tt></li> <li> <tt>02.26.2002 analysis menus now support multiple levels of hierarchical menus</tt></li> <li> <tt>02.26.2002 multiple hierarchical menus may have the same label</tt></li> <li> <tt>02.26.2002 hierarchical menu label may have an imbedded spaces</tt></li> <li> <tt>02.26.2002 add endhmenu endparam to analysis file parser</tt></li> <li> <tt>02.26.2002 analysis file text maybe indented</tt></li> <li> <tt>02.26.2002 add help support to analysis file</tt></li> <li> <tt>02.27.2002 add $BEGINTEXT/$ENDTEXT to $plot(stdin) macro</tt></li> <li> <tt>02.27.2002 add xpa get fits [type|image|table] command</tt></li> <li> <tt>02.27.2002 minor tweak with the File:Save as menu</tt></li> <li> <tt>02.27.2002 clean up some minor memory leaks with FitsImage::initwcs()</tt></li> <li> <tt>02.27.2002 fixed a problem in dialog.tcl DialogWait and reseting errorInfo</tt></li> <li> <tt>03.01.2002 dss non-save file now uses internal gz</tt></li> <li> <tt>03.04.2002 plot windows can now support a second set of y and error values.</tt></li> <li> <tt>03.05.2002 add debug iis option</tt></li> <li> <tt>03.05.2002 filenames now always reflect fits extension name/number and filter.</tt></li> <li> <tt>03.05.2002 the last step in analysis commands now replaces all '][' with ',', building up readable filters.</tt></li> <li> <tt>03.06.2002 updated nan.C and nan.h to reflect erics new treatment of alpha</tt></li> <li> <tt>03.08.2002 add support for save fits gz</tt></li> <li> <tt>03.12.2002 keywords BSCALE/BZERO/BLANK are now ignored for FITS IEEE floating point data</tt></li> <li> <tt>03.12.2002 IEEE nan and inf are supported as valid FITS IEEE floating point data</tt></li> <li> <tt>03.13.2002 add fits.sh test suite which tests for bitpix = 8,16,32,-32,-64 and BLANK,BSCALE,BZERO keywords, and IEEE floating point data NaN and INF.</tt></li> <li> <tt>03.15.2002 add save resample support</tt></li> <li> <tt>03.18.2002 add support for Mosaic Fast Render. Only valid for IRAF mosaics. Basically, you track the current fitsimage til you have miss.</tt></li> <li> <tt>03.19.2002 upgrade XPA 2.1.0e</tt></li> <li> <tt>03.19.2002 upgrade FILTER 1.1.0e</tt></li> <li> <tt>03.19.2002 upgrade FITSY 1.1.0e</tt></li> <li> <tt>03.19.2002 fixed a problem when a user CUT a region that had a dialog box open. A CUT operation now calls the delete callback to remove any pending dialog boxes.</tt></li> <li> <tt>03.19.2002 fixed a problem with -print command line option for truecolor visuals. We need to make sure that the window is realized so that the colormap has been created.</tt></li> <li> <tt>03.20.2002 ds9 version 2.1b6 released to the public</tt></li> </ol> <h4> <b>Version 2.1b5</b></h4> <ol> <li> <tt>fixed a problem with bogus wcs data and replace wcs xpa command</tt></li> <li> <tt>add view tickmarks to grid dialog box</tt></li> <li> <tt>fixed a problem with loading a custom colormap and then printing</tt></li> <li> <tt>add command line/xpa option load colormap file</tt></li> <li> <tt>fixed problems with grid dialog box and switching between frames</tt></li> <li> <tt>add command line option pan</tt></li> <li> <tt>add command line option about</tt></li> <li> <tt>add command line option view</tt></li> <li> <tt>gzip compression is now built-in</tt></li> <li> <tt>add xpa fits [mosaic|mosaicimage]</tt></li> <li> <tt>fixed a problem with loading arrays via stdin</tt></li> <li> <tt>fixed a problem with the panda region and rotation</tt></li> <li> <tt>improved performance in plotting of large data sets</tt></li> <li> <tt>fixed a problem with xpa analysis plot stdin and ';' in the title</tt></li> <li> <tt>increased the histequ internal buffer size to 16k</tt></li> <li> <tt>enhance xpa analysis load command</tt></li> <li> <tt>add multiple preload analysis files</tt></li> <li> <tt>add hiearch analysis menus</tt></li> <li> <tt>fixed cancel support for Namesvr</tt></li> <li> <tt>fixed cancel support for DSS</tt></li> <li> <tt>add virtual observatory support</tt></li> <li> <tt>add jpeg,tiff,pgn,ppm support, via ghostscript</tt></li> <li> <tt>fix a problem with min/max and DATASEC</tt></li> <li> <tt>added 'load incr' commands</tt></li> <li> <tt>added 'load xxxxx incr' command</tt></li> <li> <tt>fixed minor memory leaks</tt></li> <li> <tt>added analysis command log</tt></li> <li> <tt>add xpa grid load/save</tt></li> <li> <tt>add command line option grid</tt></li> <li> <tt>fixed a problem with loading fits from a stream where the primary hdu contains an image</tt></li> <li> <tt>enhance xpa/command support for dss</tt></li> <li> <tt>add nameserver command line option</tt></li> <li> <tt>fix a problem with panner and magnifer preferences</tt></li> <li> <tt>fixed a issue when gz files are a few bytes short</tt></li> <li> <tt>add support for wcs mosaics</tt></li> <li> <tt>added support for wcs grids for all types of mosaics</tt></li> <li> <tt>speed up printing by factor of 5</tt></li> <li> <tt>add new grid type</tt></li> <li> <tt>updated to wcssubs 3.0.5</tt></li> <li> <tt>updated to ast 1.8.3</tt></li> <li> <tt>updated to filter 1.0b9</tt></li> <li> <tt>updated to fitsy 1.0b9</tt></li> <li> <tt>command line options -file, -mosaic, -mosaicimage, -array, -url are now modal</tt></li> <li> <tt>add -debug [options] support</tt></li> <li> <tt>fixed a problem with contours and NAN data</tt></li> <li> <tt>fixed a problem with contours and DATASEC</tt></li> <li> <tt>split the pros, saoimage, and saotng parsers</tt></li> <li> <tt>fixed a problem with text with the saotng parser</tt></li> <li> <tt>fixed a problem with saotng,saoimage, and pros regions parsers and \n terminators</tt></li> <li> <tt>add thin width contours</tt></li> <li> <tt>add thin width grids</tt></li> <li> <tt>fixed a problem with iraf mosaics</tt></li> <li> <tt>10.31.2001 Physical, Amplifier, and Detector coordinates are only displayed if keywords are present</tt></li> <li> <tt>11.1.2001 Diplay header will display primary header if requested</tt></li> <li> <tt>11.1.2001 add xpa cmap value command</tt></li> <li> <tt>11.2.2001 removed support for analysis with files with spaces cause it created a problem with filename with extensions</tt></li> <li> <tt>11.2.2001 fixed a problem with analysis regions files and special characters that was causing a problem with ellipse annlus</tt></li> <li> <tt>11.2.2001 add analysis $file[$region] macro</tt></li> <li> <tt>11.8.2001 fixed a problem with saving pixel table data</tt></li> <li> <tt>11.8.2001 add John Rolls new blueplate special stand dialog box</tt></li> <li> <tt>11.8.2001 removed 'Open Mosaic Images', since you can now do the same from the dialog box</tt></li> <li> <tt>11.8.2001 fixed a problem with printing/saving text from SimpleTextDialog</tt></li> <li> <tt>11.9.2001 load muliple files is now much faster</tt></li> <li> <tt>11.13.2001 fixed a problem with Simple List Box and windows</tt></li> <li> <tt>11.13.2001 default standard dialog box for windows is now the windows default</tt></li> <li> <tt>12.3.2001 expand update to update [now]</tt></li> <li> <tt>12.4.2001 fitsy++ now promotes all keyword finds to uppercase</tt></li> <li> <tt>12.4.2001 add 'get fits header # keyword &lt;str&gt;' command</tt></li> <li> <tt>12.4.2001 fix a problem with selecting projection region at high zoom factors</tt></li> <li> <tt>12.5.2001 fixed problems with length and orientation of projection region</tt></li> <li> <tt>12.6.2001 change 'get data values' syntax to include fits #</tt></li> <li> <tt>12.14.2001 fixed a problem with mosaics with linear wcs that caused a core</tt></li> <li> <tt>12.31.2001 supported added for regions and mosaics</tt></li> <li> <tt>1.2.2002 projection regions now support mosaics</tt></li> <li> <tt>1.3.2002 updated xparemote with proxy support</tt></li> <li> <tt>1.3.2002 add vo prefs</tt></li> <li> <tt>1.4.2002 add ciao pie region support</tt></li> <li> <tt>1.7.2002 fixed panda and wcs with rotation problem</tt></li> <li> <tt>1.9.2002 uprade ast to version 1.8.4</tt></li> <li> <tt>1.15.2002 enable Blt_ZoomStack for data plots</tt></li> <li> <tt>1.17.2002 fixed a problem with iraf mosaics with flipped segments and a round off problem</tt></li> <li> <tt>1.18.2002 add support for multiple aux contours</tt></li> <li> <tt>1.23.2002 fixed a problem with fits headers and the END keyword is not 8 chars</tt></li> <li> <tt>1.23.2002 fixed many problems with no fits loaded and user gui actions</tt></li> <li> <tt>1.24.2002 fixed a problem with looking for fits region extensions and a filter specified</tt></li> <li> <tt>1.24.2002 add regions file format and coord system to prefs menu</tt></li> <li> <tt>1.25.2002 get data values now spans mosaics and is in native coords</tt></li> <li> <tt>1.31.2002 ds9 version 2.1b5 released to the public</tt></li> </ol> <h4> <b>Version 2.1b4</b></h4> <ol> <li> <tt>fixed a problem very, very large images and int overflow</tt></li> <li> <tt>add Page Setup preferences</tt></li> <li> <tt>plot data is filtered to remove all non numeric data</tt></li> <li> <tt>fixed a problem with plotting x,y data on alpha</tt></li> <li> <tt>add manual grid layout</tt></li> <li> <tt>text regions can now be rotated</tt></li> <li> <tt>regions text now appears in the magnifier</tt></li> <li> <tt>added the PANDA region</tt></li> <li> <tt>added analysis file macro $entry</tt></li> <li> <tt>fixed a problem with multiple menu entries for analysis files with multiple file templates</tt></li> <li> <tt>default values of Analysis file parameters are now updated</tt></li> <li> <tt>fixed a problem with clear analysis commands</tt></li> <li> <tt>analysis tasks are now non-blocking</tt></li> <li> <tt>add xy regions file format</tt></li> <li> <tt>fixed problem with ps level 2 psuedocolor8 printing and inverse colormaps</tt></li> <li> <tt>in regions files, the comment char '#' comments out til a new-line char</tt></li> <li> <tt>extended $regions macro to include multiple properties and regions format</tt></li> <li> <tt>fixed a problem with loading array data on a little endian machine and the arch is not specified</tt></li> <li> <tt>fixed a problem with histogram equalization</tt></li> <li> <tt>fixed a major problem with all negative float or double data and min/max issues</tt></li> <li> <tt>fixed a problem with $regions and no wcs</tt></li> <li> <tt>fixed a problem with printing ps level 2 and fits with NAN</tt></li> <li> <tt>fixed a problem with running on a msb machine, and displaying on a lsb 24bit machine</tt></li> <li> <tt>unrolled all mosaic algorithms to cycle thru all segments for each pixel</tt></li> <li> <tt>add DATASEC for rendering and printing</tt></li> <li> <tt>upgraded to tcl/tk 8.3.3</tt></li> <li> <tt>add http and ftp macro expand to analysis</tt></li> <li> <tt>fixed a problem with contour log scale</tt></li> <li> <tt>add button 2 bindinds for panner</tt></li> <li> <tt>iraf -fifo default is now /dev/imt1</tt></li> <li> <tt>commented out error messages for bad iraf -fifo, -port, -unix</tt></li> <li> <tt>add default imtoolrc values to fb_config if no imtoolrc file is found at startup</tt></li> <li> <tt>add iis support for windows port</tt></li> <li> <tt>add command: get data coordsys x y dx dy var</tt></li> <li> <tt>add plot limits to plot tool</tt></li> <li> <tt>add PROJECTION region</tt></li> <li> <tt>add GETURL analysis macro</tt></li> <li> <tt>Fits bin table keywords TUNITx are now process if available</tt></li> <li> <tt>add $filename(root) macro</tt></li> <li> <tt>update filename on load</tt></li> <li> <tt>fixed a problem with Colormaps with a name with a single character</tt></li> <li> <tt>added iraf 'non-display' imexamine support</tt></li> </ol> <h4> <b>Version 2.1b3</b></h4> <ol> <li> <tt>fixed a problem with angles of regions specified in WCS</tt></li> <li> <tt>add xpa point 'regions save'</tt></li> <li> <tt>add xpa point 'regions load'</tt></li> <li> <tt>regions file format <i>SAOIMAGE</i> now supports annulus, ellipse annulus, and box annulus</tt></li> <li> <tt>the obsolete <i>Ftools</i> regions file format support has been removed</tt></li> <li> <tt>fixed many problems with <i>IRAF</i> regions file format</tt></li> <li> <tt>fixed many problems with <i>CIAO</i> regions file format</tt></li> <li> <tt>removed all support for Rosat All Sky Survey</tt></li> <li> <tt>all comments and global settings have been removed from regions output if delimiter is set to semicolon</tt></li> <li> <tt>fixed a problem with regions defined in WCS degrees and do not lie on an image</tt></li> <li> <tt>fixed a problem with ellipse annulus and box annulus regions in regions files that contain only one region</tt></li> <li> <tt>check for radius of length 0 for circle, annulus, ellipse, and ellipse annulus</tt></li> <li> <tt>Added Histogram Equalization colormap scale distribution</tt></li> <li> <tt>removed <i>default</i> as font option</tt></li> <li> <tt>default font is now <i>helvetica</i></tt></li> <li> <tt>changed command line option -regionfile to -region</tt></li> <li> <tt>fixed a problem with command line option -region and incorrect coordinates</tt></li> <li> <tt>Change the 'Scale:User Limits...' dialog into non-modal 'Scale Parameters...'</tt></li> <li> <tt>Added 'ZMax' Scale Limits algorithm</tt></li> <li> <tt>fixed a problem with loading regions files with full pathnames with 'fits' in them</tt></li> <li> <tt>Updated Prefs, command line options, and xpa points to reflect the new way minmax and scale options are handled</tt></li> <li> <tt>Removed 'Scan On Load' prefs</tt></li> <li> <tt>Added 'Source/Background' region property</tt></li> <li> <tt>Add support for 'Source/Background' region property to SAOtng region parser</tt></li> <li> <tt>Fixed a color problem with pseudocolor 8 frames and black/white. This showed up in new Sun hardware and Solaris 8 sofware</tt></li> <li> <tt>Fixed a problem with Postscript printing in pseudocolor 8 colormode</tt></li> <li> <tt>The magnifier now updates during blinking</tt></li> <li> <tt>Added pixel table commands to command line options and xpa</tt></li> <li> <tt>Add -single command line option</tt></li> <li> <tt>Add default region shape to preferences</tt></li> <li> <tt>New Analysis File format supported, with new macros $message, $text, $plot</tt></li> <li> <tt>Add -analysis command line option</tt></li> <li> <tt>Add subcommands to xpa <i>analysis:</i> load,clear,message,text,plot</tt></li> <li> <tt>Add Analysis File macros $data and $image</tt></li> <li> <tt>Add autoload FITS regions option</tt></li> <li> <tt>Add load FITS Region file to command line options and xpa regions</tt></li> <li> <tt>DSS servers now have limits as to size of image downloaded</tt></li> <li> <tt>Open Array now presents a dialog box if no specs are given</tt></li> <li> <tt>Now supports compression with .ftz extension</tt></li> <li> <tt>All non-modal windows raise to top when re-invoked</tt></li> <li> <tt>Added Line Width to all regions</tt></li> <li> <tt>Comments are now retained for regions files</tt></li> <li> <tt>Add Line Width to contours</tt></li> <li> <tt>Changed xpa delim to strip yes/no</tt></li> <li> <tt>Contour methods are 'Faster' and 'Better'</tt></li> <li> <tt>Add Convert Contours to polygons</tt></li> <li> <tt>Add $xpa analysis macro</tt></li> <li> <tt>Add $param analysis macros</tt></li> <li> <tt>Fixed a problem with crosshair and rebinning</tt></li> <li> <tt>Fixed a problem with pan click and drag and fits binary tables</tt></li> <li> <tt>Add undo regions</tt></li> <li> <tt>Add cut/copy/paste regions</tt></li> <li> <tt>Changed the preferences file and startup file to be consistent across platforms</tt></li> <li> <tt>Add 'Pan then Zoom' to button 2 options</tt></li> <li> <tt>Add support for FITS 3D data cubes</tt></li> <li> <tt>Add Edit button row</tt></li> <li> <tt>Add default mode to prefs</tt></li> <li> <tt>Fixed a problem with file names starting with 'file'</tt></li> <li> <tt>Add xpa regions shape/color/width</tt></li> </ol> </ol> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r6.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000042540�11556610245�014655� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 6 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 6 Release Notes</h3> <ol> <ol> <li><tt>10.20.2009 XPA: moved processing xpa command line options to first pass, and init xpa earlier in startup, so that vo and web click can be processed along with regular command line options. </tt></li> <li><tt>10.24.2009 UPDATE: fixed a problem with trying to provide support for backward compatibility.</tt></li> <li><tt>10.24.2009 IMGSVR: fixed a problem with trying to provide support for backward compatibility</tt></li> <li><tt>10.24.2009 GUI: sleep command arg is now optional</tt></li> <li><tt>10.24.2009 MOSAIC: IRAF mosaics are now layed out based on the first segment load, like WCS mosaics</tt></li> <li><tt>10.27.2009 GUI: fixed a problem if you delete all frames, some of the load commands (such as -rgbcube) are not executed until there is a new frame. Now, if there are no frames, the load command will create a new frame if needed</tt></li> <li><tt>10.28.2009 REGION: Corrected a problem with creating templates from a VAR. Uncommented old syntax which has been superceeded</tt></li> <li><tt>11.02.2009 GRID: fixed a problem with 'grid numlab gap2'</tt></li> <li><tt>11.02.2009 AST: updated to version 5.3-1 <li><tt>11.05.2009 TILE: corrected documentation for '-tile grid layout', should be column #, row #</tt></li> <li><tt>11.05.2009 DATACUBE: fixed a problem with '-wcs replace|reset|append'. The result WCS is now applied to all slices</tt></li> <li><tt>11.05.2009 XPA: fixed a problem with 'xpaset wcs replace foo.wcs'</tt></li> <li><tt>11.13.2009 RICE: updated to cfitsio 3210/tt></li> <li><tt>11.16.2009 COMPRESS: fixed a problem with compression that extends over a page boundry of 1Gb</tt></li> <li><tt>11.30.2009 GRID: fixed a problem with exterior numerics and zoomed images</tt></li> <li><tt>11.30.2009 HELP: combine FAQ and ISSUES pages</tt></li> <li><tt>12.04.2009 RGB: aux contour overlays are now displayed on a per channel basis</tt></li> <li><tt>12.07.2009 RGB: rgb images with data cubes can now set the current slice on a per channel basis</tt></li> <li><tt>12.07.2009 VO: fixed a problem with xpa keep-alive</tt></li> <li><tt>12.10.2009 TK: fixed a problem MacOSX X11 standard file dialog boxes. Borrowed code from tk8.5 to correct the problem when events are added to X11</tt></li> <li><tt>12.10.2009 GUI: fixed a problem with modal dialogs when the user closed the window via the window manager and not the OK/CANCEL button</tt></li> <li><tt>12.10.2009 XPA: update to version 2.1.11</tt></li> <li><tt>12.14.2009 RGB: fixed a problem with a incorrect WCS compass in the panner image</tt></li> <li><tt>12.15.2009 WCS: Documented the old ALIGN command and updated for XPA and SAMP</tt></li> <li><tt>12.15.2009 GUI: Values accepted for SKYFORMAT expanded to 'deg', 'degree', and 'degrees' for command line options, XPA, and SAMP</tt></li> <li><tt>12.17.2009 WCS: added code to test for bad WCS alignment issues (mainly from CAR projection, or pole problems)</tt></li> <li><tt>12.17.2009 WCS: added code for WCS alignment for CAR. If CAR, getWCScrpix() is taken from center of image, and not from CRPIX keywords</tt></li> <li><tt>12.18.2009 CATALOG: added USNO UCAC3 to the Optical list</tt></li> <li><tt>12.24.2009 DATACUBE: DS9 now supports FITS images up to 10 dimensions. Happy Holidays!</tt></li> <li><tt>12.28.2009 ANALYSIS: fixed problems with $data and $url and spaces in the tmp directory path name</tt></li> <li><tt>12.28.2009 COMM: fixed problems with spaces in file names received as argumetns via SAMP and http</tt></li> <li><tt>12.29.2009 REGION: fixed problems with XPA/SAMP and -format/-system/-sky options</tt></li> <li><tt>12.29.2009 GUI: fixed a problem with hiding the current frame</tt></li> <li><tt>12.30.2009 HV: at EXIT, close all opened HV windows so that tmp files may be deleted</tt></li> <li><tt>12.30.2009 HV: fixed a problem for MIME type 'multipart/mixed', a tmp file was not deleted</tt></li> <li><tt>12.30.2009 HV: fixed a problem for MIME type 'text/plain', a tmp file was not deleted</tt></li> <li><tt>12.30.2009 ANALYSIS: add $filedialog(open) and $filedialog(save) macros</tt></li> <li><tt>12.30.2009 GUI: allow filenames starting with a '-'</tt></li> <li><tt>01.07.2009 I18N: for X11 port, look for LC_MESSAGES, LC_ALL, LANG env vars to set langage in that order</tt></li> <li><tt>01.07.2009 I18N: update Japanese language translation</tt></li> <li><tt>01.07.2009 CONTOUR: fix muliple problems with command line contour options. Each frame will now remember contour params between frames</tt></li> <li><tt>01.08.2009 ANALYSIS: minor changes in output of get analysis commands. Now include parameters for web and bind commands</tt></li> <li><tt>01.11.2009 COLORBAR: fixed a problem with the orientation of the numerics for vertical colorbar. This problem was introduced with AST-5.3</tt></li> <li><tt>01.11.2009 RGB: fixed a memory leak for RGB frames</tt></li> <li><tt>01.11.2009 I18N: update Japanese language translation</tt></li> <li><tt>01.11.2009 MACOSX: fixed a problem with non-native standard file dialog boxes and error messages</tt></li> <li><tt>01.12.2009 AST: fixed a memory leak with colorbar grid.</tt></li> <li><tt>01.13.2009 PLOT: fixed a rare problem when the user closes a plot while in the middle of a zoom.</tt></li> <li><tt>01.13.2009 IRAF: fixed a problem for mosaic iraf images are loaded and the bounding box is incorrectly calculated.</tt></li> <li><tt><b>01.15.2010 RELEASE version 6.0</b></tt></li> <li><tt>01.27.2010 XPA: fixed a problem with reporting errors during an XPA operation. The correct error message is now passed to XPA.</tt></li> <li><tt>01.27.2010 SAMP: fixed a problem with reporting errors during an SAMP operation. The correct error message is now passed to SAMP.</tt></li> <li><tt>01.27.2010 REGION: fixed a problem with catch and XPA/SAMP. Errors are now reset when needed so as not to invoke an XPA/SAMP ERROR message.</tt></li> <li><tt>01.27.2010 XPA: update to version 2.1.12</tt></li> <li><tt>02.02.2010 CONTOURS: fixed a problem with manually entered contours values.</tt></li> <li><tt>02.12.2010 COLORBAR: add numerics equal distance option.</tt></li> <li><tt>02.12.2010 COLORBAR: add colorbar size option.</tt></li> <li><tt>02.12.2010 COLORBAR: move colorbar parameters from view menu to colorbar menu.</tt></li> <li><tt>02.18.2010 MACOSX: fixed a problem where pcc was always being installed. Now, first look for FILTER_CC (valid for X11 users only). Next, see if /usr/bin/gcc exists. Finally, install pcc if needed, and set to use it.</tt></li> <li><tt>02.25.2010 SCALE: fixed numerous problems with LOG and POW scales. Previously, the exp value of the log ratio was based on the dynamic range of the data. It is now specified by the user. This solves a number of issues with data which contains negative values. (see new documenation on scale equations).</tt></li> <li><tt>02.25.2010 CATALOG: CSC is now loaded as a VOTABLE by default.</tt></li> <li><tt>03.02.2010 CATALOG: add support for SkyBot catalog server.</tt></li> <li><tt>03.03.2010 MACOSX: printing, reduce image by 5% so colorbar end tick numerics are not cutoff.</tt></li> <li><tt>03.03.2010 WINDOWS: printing, reduce image by 5% so colorbar end tick numerics are not cutoff.</tt></li> <li><tt>03.03.2010 HV: fixed a problem with MouseWheel scrolling under X11.</tt></li> <li><tt>03.04.2010 ZOOM: added support for mouse wheel zoom.</tt></li> <li><tt>03.04.2010 HV: added support for Find and FindNext.</tt></li> <li><tt>03.10.2010 POSTSCRIPT: if colorbar and colorbar numerics are visible, reduce image by 5% so colorbar end tick numerics are not cutoff.</tt></li> <li><tt>03.10.2010 PRINT: add psprint xpa/command/samp command for postscript printing on MacOSX and Windows.</tt></li> <li><tt>03.10.2010 GRID: add support for custom numeric formats.</tt></li> <li><tt>03.17.2010 BIN: add support for Match Bin.</tt></li> <li><tt>03.23.2010 FITS: add a check tor binary tables with no rows or cols.</tt></li> <li><tt>03.24.2010 WINDOWS: fixed a problem with native printing and bitmaps that were not aligned upon a word boundary.</tt></li> <li><tt>03.24.2010 WINDOWS: fixed a problem with rendering circle point and box circle point.</tt></li> <li><tt>03.26.2010 HV: fixed a rather nasty bug. If a HV window is open when prefs are saved, the next time ds9 is started, upon exist it tried to close an non-existent window, and went into a loop.</tt></li> <li><tt>03.29.2010 SAMP: add support for table.load.fits events.</tt></li> <li><tt>04.13.2010 BACKUP: add support for backup and restore.</tt></li> <li><tt>04.14.2010 GUI: ensure all temp files in /tmp have unique names which will not conflict with other programs.</tt></li> <li><tt>04.14.2010 RGB: corrected inconsistant behavior. The creation of a RGB frame will not alter the single/tile setting.</tt></li> <li><tt>04.16.2010 TK: fixed a problem with some tk lib scripts not sourced at startup and if -cd is executed, ds9 is unable to locate the scripts.</tt></li> <li><tt>04.16.2010 CIAO: removed any conjuction operators (which are not supported).</tt></li> <li><tt>04.16.2010 COLORBAR: fixed a rather nasty memory bug which was invoked when the colorbar was re-configured.</tt></li> <li><tt>04.23.2010 BACKUP: backup save sets can be saved into on a repeat basis.</tt></li> <li><tt>04.26.2010 SCALE: fixed a problem with segv and Scale Dialog box.</tt></li> <li><tt>04.26.2010 GUI: fixed a problem matching frames while in single mode.</tt></li> <li><tt>04.29.2010 GUI: add cycle windows key shortcut.</tt></li> <li><tt>05.04.2010 WINDOWS: new windows installation procedure.</tt></li> <li><tt>05.06.2010 CATALOG: add IAU location code in preferences (for Skybot).</tt></li> <li><tt>05.10.2010 REGION: fixed a problem with projection region when one or both end points are off the image. All gaps (mosaic) or off image (non-mosaic) have a value of 0 and NaNs are ignored.</tt></li> <li><tt>05.12.2010 VOTable: add support for FIEDref and PARAMref elements.</tt></li> <li><tt><b>05.15.2010 RELEASE version 6.1</b></tt></li> <li><tt>05.18.2010 WINDOWS: change windows installation procedure back to allow user to specify destination directory.</tt></li> <li><tt>05.18.2010 SAMP: fixed an issue with DS9 being confused as to if it is currently connected and the need to shutdown SAMP at exit.</tt></li> <li><tt><b>05.18.2010 RELEASE version 6.1.1</b></tt></li> <li><tt>05.19.2010 BACKUP: fixed several major problems.</tt></li> <li><tt>05.19.2010 PSEUDOCOLOR: fixed a typo.</tt></li> <li><tt><b>05.19.2010 RELEASE version 6.1.2</b></tt></li> <li><tt>05.20.2010 MACOSX: always install pcc if gcc not available. We don't want old versions of pcc around after upgrades of the OS.</tt></li> <li><tt>05.28.2010 PLOT: added statistics window for plots.</tt></li> <li><tt>05.28.2010 PLOT: fixed some problems with menus and clear data.</tt></li> <li><tt>05.28.2010 NAMESERVER: add get option to return coords directly to calling proc.</tt></li> <li><tt>06.17.2010 CHECKDNS: update chechdns to add support for actually connect.</tt></li> <li><tt>06.17.2010 VO: use checkdns to look for active server. If none found, used hard coded list.</tt></li> <li><tt>06.21.2010 ZOOM TO FIT: center image exactly, do not round to nearest whole pixel.</tt></li> <li><tt>06.21.2010 BACKUP: don't save prefs(version) var. We want the current preference file version, not the save set version.</tt></li> <li><tt>06.21.2010 GUI: ds9 will now look for its auxiliary file using the current name of the executable.</tt></li> <li><tt>06.30.2010 WCS: add WCS Edit dialog.</tt></li> <li><tt>07.01.2010 XPA: add frame has command.</tt></li> <li><tt>07.01.2010 SAMP: add frame has command.</tt></li> <li><tt>07.09.2010 SAMP: fixed a problem with updating the connect meun item after a manual disconnect.</tt></li> <li><tt>07.09.2010 SAMP: added support for SAMP_HUB env var.</tt></li> <li><tt>07.13.2010 COLORBAR: fixed a problem with a bad default -size param. This problem only showed up with a pseudocolor8 visual.</tt></li> <li><tt>07.15.2010 GUI: implemented support for internal error message facility. Any fatal internal error event will trigger an GUI error message, hopefully leaving the user the option to save data and to exit gracefully.</tt></li> <li><tt>07.15.2010 GUI: implemented support for trapping the SIGBUS signal and routing it to the internal error message facilty. This usually occurs when a data file has been overwritten or a shared memory segment is no longer available.</tt></li> <li><tt>07.27.2010 PLOT: save font info when save configuration.</tt></li> <li><tt>08.04.2010 REGION: fixed a problem with the close button on EPANDA and BPANDA dialog boxes.</tt></li> <li><tt>08.05.2010 COLORBAR: fixed a problem when the image is all one value.</tt></li> <li><tt>08.10.2010 GUI: add Frame Match Image, Physical, Detector, Amplifier buttons.</tt></li> <li><tt>08.12.2010 MAGNIFIER: add magnifier prefs for XPA, SAMP, and the command line.</tt></li> <li><tt>08.12.2010 MAGNIFIER: add magnifier color option.</tt></li> <li><tt>08.17.2010 GRID: fixed a problem with init colors.</tt></li> <li><tt>08.17.2010 GRID: now supports colors in form #ffffff.</tt></li> <li><tt>08.18.2010 CONTOURS: fixed an issue when loading aux contours which do not end with a linefeed.</tt></li> <li><tt>08.23.2010 COLORBAR: fixed an issue when printing colorbar from the command line. The numerics are now updated before printing.</tt></li> <li><tt>08.23.2010 COLORBAR: fixed an issue when rendering numerics. Numerics are now properly positioned, regardless of colorbar orientation or font.</tt></li> <li><tt>08.25.2010 GRID: fixed a number of issues when rendering grid numerics. Numerics are now properly positioned, regardless of orientation or font.</tt></li> <li><tt>08.27.2010 POSTSCRIPT: fixed a rather nastsy prolblem with the level 2 postscript driver (Ascii85 filter) in which, sometimes, the last line of the image would not be written.</tt></li> <li><tt>08.30.2010 POSTSCRIPT: add new postscript level 3 driver, which uses Flate and Ascii85 filters.</tt></li> <li><tt>08.31.2010 COLORBAR: add support for user specified number of tickmarks to be displayed.</tt></li> <li><tt>08.31.2010 CATALOG: The user can now invoke a blank catalog tool via the command line, xpa, or samp.</tt></li> <li><tt>09.01.2010 TCL/TK: upate to version 8.5.8.</tt></li> <li><tt>09.01.2010 CATALOG: add font properties to display symbol database.</tt></li> <li><tt>09.07.2010 CATALOG: now supports image/physical coordinate systems.</tt></li> <li><tt>09.21.2010 CONTOUR: copy/paste contours no longer requires equatorial sky param.</tt></li> <li><tt>09.21.2010 REGION: copy/paste contours no longer requires equatorial sky param.</tt></li> <li><tt>09.21.2010 SAVEAS: add optional params for jpeg, mpeg and tiff command line options.</tt></li> <li><tt>09.22.2010 FOV: update Chandra Templates.</tt></li> <li><tt>09.22.2010 GUI: add open and close support for XPA, SAMP, and command line, for all dialogs.</tt></li> <li><tt>09.28.2010 COLORBAR: fixed a problem with generating colorbar values when no frame is available.</tt></li> <li><tt>09.30.2010 HV: fixed a problem with multiple cookies, which created a bad header.</tt></li> <li><tt>09.30.2010 VO: fixed a problem with 'xpaget ds9 vo connect'. Now returns only the current connections, not all possible connections.</tt></li> <li><tt>09.30.2010 REGION: added check for no frame and no image loaded for xpaset regions via stdin.</tt></li> <li><tt>09.30.2010 ANALYSIS: add 'task #|name' command.</tt></li> <li><tt>10.01.2010 ANALYSIS: fixed a problem when an analysis file was loaded after an image had been loaded. Them menu was not properly updated to reflect the template for each menu item.</tt></li> <li><tt>10.05.2010 CUBE: fixed a problem in which sometimes changing the current slice whould hang.</tt></li> <li><tt>10.05.2010 CUBE: add support for WCS in cube dialog.</tt></li> <li><tt>10.07.2010 CENTROID: add support centroid params xpa/command line.</tt></li> <li><tt>10.07.2010 CENTROID: fix some problems with an offset of .5 pixels.</tt></li> <li><tt>10.07.2010 SMOOTH: new frames inherit current smooth params.</tt></li> <li><tt>10.07.2010 RGB: fixed a problem when the first image load has a flipped wcs.</tt></li> <li><tt>10.08.2010 REGION: add CIRCLE3D region.</tt></li> <li><tt>10.11.2010 BACKUP: fixed a problem with smoothed images and contours.</tt></li> <li><tt>10.14.2010 HELP: fixed a problem with finding the help files if the CD command has changed the default directory.</tt></li> <li><tt>10.14.2010 XPA: update to version 2.1.13</tt></li> <li><tt><b>10.15.2010 RELEASE version 6.2</b></tt></li> </ol> </ol> </body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r4.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000063507�10643265705�014664� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 4 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 4.0 Release Notes</h3> <ol> <h4> <b>Version 4</b></h4> <ol> <li><tt>09.13.2004 AST: update to version 3.4-4</tt></li> <li><tt>09.13.2004 TCL/TK: update to version 8.4.7</tt></li> <li><tt>09.14.2004 WCSSUBS: update to version 3.5.6</tt></li> <li><tt>09.14.2004 TCLLIB: update to version 1.6.1</tt></li> <li><tt>09.15.2004 TKTABLE: installed 2.9</tt></li> <li><tt>09.20.2004 SAOTK: fixed a problem with calculating a regions rotational angle with a galactic or ecliptic wcs.</tt></li> <li><tt>09.21.2004 SAVEFITS: fixed a problem with the savefits xpa and command line options.</tt></li> <li><tt>09.21.2004 REGIONS: fixed a problem with updating region dialog boxes after a change in event file bin factor.</tt></li> <li><tt>09.23.2004 DSS: if user selects dss2red or dss2blue survey, force server to eso.</tt></li> <li><tt>09.23.2004 2MASS: add image server.</tt></li> <li><tt>10.01.2004 DSS: fixed a problem with 'Update from current Frame'.</tt></li> <li><tt>10.12.2004 MAKEFILE: add export-dynamic for linux so that external shared libs can be loaded.</tt></li> <li><tt>10.21.2004 GUI: fixed a problem if while blinking the user changes the colorbar via mouse.</tt></li> <li><tt>11.17.2004 IMAGESERVER: fixed incompatibilities between DSS and 2MASS.</tt></li> <li><tt>11.19.2004 AST: update to version 3.5</tt></li> <li><tt>11.29.2004 FUNTOOLS: update to version 1.2.4</tt></li> <li><tt>11.30.2004 SAOTK: use NaN.h from Funtools. This corrects problems with new architectures.</tt></li> <li><tt>12.03.2004 MAKEFILE: now support gcc 3.4.x</tt></li> <li><tt>12.15.2004 XPA: fixed a problem with preserve regions command.</tt></li> <li><tt>12.15.2004 HTML: fixed several problems with color matching within htmlwidget.</tt></li> <li><tt>12.16.2004 GUI: fixed a problem with saving text from SimpleTextDialog.</tt></li> <li><tt>12.16.2004 WCS: main wcs menu item now sets default marker coordinate system and skyframe.</tt></li> <li><tt>12.16.2004 COMPASS: create compass now uses current marker dialog system and skyframe.</tt></li> <li><tt>12.20.2004 POLYGON: fixed a problem with the exclude strip and rotation.</tt></li> <li><tt>12.20.2004 COMPOSITE: add support for composite region.</tt></li> <li><tt>12.22.2004 TEXT REGION: fixed a problem in which the text angle did not reflect the native coordinate system.</tt></li> <li><tt>12.29.2004 IMAGESERVER: xpa and command line options are now synchronous. The GUI is still asynchronous.</tt></li> <li><tt>12.30.2004 NAMESERVER: fixed a problem with sexigesmal from SIMBAD near the equator.</tt></li> <li><tt>12.30.2004 NAMESERVER: xpa and command line options are now synchronous. The GUI is still asynchronous.</tt></li> <li><tt>01.31.2005 VECTOR: add support for new VECTOR region.</tt></li> <li><tt>02.08.2005 REGIONS: fix varies errors with definition of angles. Position angles are now defined as from first positive coordinate axis to second positive coordinate axis except in the case of equatorial wcs, in this case it is defined as from second positive coordinate axis to first positive coordinate axis.</tt></li> <li><tt>02.16.2005 SCALE: added User menu options to clarify current scaling mode.</tt></li> <li><tt>02.17.2005 LINUX64: fixed a problem with generating postscript.</tt></li> <li><tt>02.28.2005 MOSAIC: add support for mosaic data cubes.</tt></li> <li><tt>03.01.2005 STD Dialog: fixed several problems with ds9 not remembering the current working directory.</tt></li> <li><tt>03.02.2005 WINDOWS: fixed a problem with a memory leak when rendering regions on the windows platform. We no longer try to clip against a clip region.</tt></li> <li><tt>03.02.2005 WINDOWS: fixed a problem with command line options that require the ds9 window to be visible. We have to process all events with 'update' before the windows version of ds9 is visible.</tt></li> <li><tt>03.03.2005 REGIONS: add support to all regions parsers for ms windows line terminators</tt></li> <li><tt>03.03.2005 ANALYSIS: removed extra ';' at the end of all regions substitutions.</tt></li> <li><tt>03.16.2005 FITS: increased fits file name size to 1024 chars.</tt></li> <li><tt>03.17.2005 CATALOGS: are finally implemented!</tt></li> <li><tt>03.24.2005 WINDOWS: implemented non-windows native standard dialogs. This allows uses to specify a file extension.</tt></li> <li><tt>03.29.2005 FITY++: fixed a problem with filtering large bin tables while in mmapincr mode. We now insure that enough data is mmap'd for filter to build its good array.</tt></li> <li><tt>03.29.2005 PRESERVE: fixed syntax errors with preserve regions and pan.</tt></li> <li><tt>03.30.2005 REGIONS: fixed regions parsers to accept a regions file without terminator as the last character.</tt></li> <li><tt>03.30.2005 ZOOM: all zooms are now specified in terms of x and y internally</tt></li> <li><tt>04.01.2005 GRID: fixed a problem with grid options</tt></li> <li><tt>04.28.2005 REGIONS: reimplemented basemarker,baseellipse,basebox classes.</tt></li> <li><tt>04.28.2005 ZOOM: implemented support for different x and y zoom.</tt></li> <li><tt>04.29.2005 XPA: update to version 2.1.6</tt></li> <li><tt>04.29.2005 FUNTOOLS: update to version 1.3.0b3</tt></li> <li><tt>04.29.2005 TCL/TK: update to version 8.4.9</tt></li> <li><tt>05.25.2005 REGIONS: update all regions code</tt></li> <li><tt>05.25.2005 REGIONS: add EPANDA</tt></li> <li><tt>06.07.2005 FUNTOOLS: update to version 1.3.0b6</tt></li> <li><tt>06.13.2005 SCALE: new LOG algorithm log10(i/s*1000+1)/log10(1001) where 0&lt;i&lt;s</tt></li> <li><tt>06.13.2005 MAKEFILE: add support for FreeBSD</tt></li> <li><tt>06.19.2005 FTP: all ftp opens now are in passive mode</tt></li> <li><tt>06.28.2005 BIN: fixed a problem with -bin factor</tt></li> <li><tt>06.28.2005 PAGESETUP: pagesetup command line options are no longer case sensitive</tt></li> <li><tt>07.12.2005 FUNTOOLS: update to version 1.3.0.b7</tt></li> <li><tt>07.13.2005 REGIONS: new DS9 regions 4.0 format</tt></li> <li><tt>07.13.2005 REGIONS: add copy,cut,paste,undo xpa and command line options.</tt></li> <li><tt>08.01.2005 GCC: add support for gcc 4.0. Remove backward support for gcc 2.96 or earlier.</tt></li> <li><tt>08.03.2005 REGIONS: panda,epanda,bpanda, only render start/stop angles in red/blue when selected.</tt></li> <li><tt>08.04.2005 SMOOTH: add smoothing algorithms boxcar,tophat,gaussian</tt></li> <li><tt>08.15.2005 COLORBAR: add support for printing the colorbar</tt></li> <li><tt>08.15.2005 FUNTOOLS: update to version 1.3.0b9</tt></li> <li><tt>08.15.2005 ZLIB: update to version 1.2.3</tt></li> <li><tt>08.17.2005 GUI: add View menu and prefs.</tt></li> <li><tt>08.24.2005 REGIONS: fixed a problem with ciao pie regions.</tt></li> <li><tt>08.24.2005 REGIONS: add invert selection.</tt></li> <li><tt>08.25.2005 GUI: add display image window size.</tt></li> <li><tt><b>08.30.2005 RELEASE version 4.0b6</b></tt></li> <li><tt>09.12.2005 IIS: fixed a problem with iis and cursors.</tt></li> <li><tt><b>09.12.2005 RELEASE version 4.0b7</b></tt></li> <li><tt>09.15.2005 ARRAY: fixed a problem with loading array cubes from a file and determining the correct endian.</tt></li> <li><tt>10.24.2005 BIN: if unable to find suitable cols to bin, chose the first and second column. This way, if you have table, it will always load, even if you don't know the column names.</tt></li> <li><tt>10.25.2005 BIN: binning dialog box. if number of columns is too large to display, wrap the menu.</tt></li> <li><tt>10.27.2005 CONTOUR: complete support for command line/xpa control of contour features.</tt></li> <li><tt>10.27.2005 CONTOUR: fixed a problem with convert and contours of zero length.</tt></li> <li><tt>11.01.2005 FITS: fixed a problem loading very small arrays mmapincr</tt></li> <li><tt>11.01.2005 VECTOR: small change to correct issue with gcc 4.0.1</tt></li> <li><tt>11.01.2005 WCS: fixed a problem with wcs append/replace.</tt></li> <li><tt>11.02.2005 GRID: fixed a problem with alternative linear wcs.</tt></li> <li><tt>11.02.2005 WCS: fixed a problem with alternative wcs names. All wcs names are now lower case.</tt></li> <li><tt>11.03.2005 CONTOUR: fixed a problem with contour convert after a catalog command.</tt></li> <li><tt>11.03.2005 HELP: altered tk to pass -help to us. For -help, we now display a brief message and exit and for --help, we display the reference manual command line options.</tt></li> <li><tt>11.09.2005 CATALOG: fixed a problem with starbase to trim column names of white spaces.</tt></li> <li><tt>11.09.2005 CATALOG: add user specified RA/DEC column option.</tt></li> <li><tt>11.10.2005 CATALOG: speed up catreg for large dbs</tt></li> <li><tt>11.14.2005 GUI: the meus Cut,Copy,Paste,Clear now works for all dialog boxes on all platforms.</tt></li> <li><tt>11.16.2005 REGIONS: fixed a problem with rendering arrows for line,vector,ruler, and compass with width&gt;1.</tt></li> <li><tt>11.16.2005 GUI: Modified standard dialog boxes to remember file types.</tt></li> <li><tt>11.17.2005 GUI: remove 'Use Cursors' Misc Option.</tt></li> <li><tt>11.17.2005 GUI: Modified standard dialog boxes to remember filters.</tt></li> <li><tt>11.18.2005 COMPOSITE: fixed a problem with loading composite regions with properties.</tt></li> <li><tt>12.05.2005 RGB: Fixed a problem with wcs matching rgb frames .</tt></li> <li><tt>12.08.2005 REGIONS: Fixed a problem general comment such as ## and #.</tt></li> <li><tt>12.08.2005 HELP: reset previous behavior for -help. fv uses ds9 -help to probe for ds9. Until fv is changed, we need to support the prior behavior.</tt></li> <li><tt>12.15.2005 X11: Insure that all X11 rendering is calculated in double precision until the very last, at which, the results are rounded to the nearest integer. This includes markers, contours, grids.</tt></li> <li><tt>12.17.2005 PS: set default resolution to 150, from 72.</tt></li> <li><tt>12.19.2005 GUI: add .ftz and .FTZ to default fits name filter.</tt></li> <li><tt>12.19.2005 FREEBSD: added support for freebsd.</tt></li> <li><tt>01.03.2006 FITSY++: fixed an overflow problem with mmap very large array files.</tt></li> <li><tt>01.04.2006 GUI: reinstated DETECTOR and AMPLIFIER coordinate system menu items in menus and removed the preferences.</tt></li> <li><tt>01.04.2006 GUI: reinstated ZMAX menu items in menus.</tt></li> <li><tt>01.05.2006 CATALOGS: fixed a problem with rotated or flipped images and determining image size in ra and dec</tt></li> <li><tt>01.05.2006 PROJECTION: fixed a problem move and moveto.</tt></li> <li><tt>01.12.2006 COLORBAR: added numerics to colorbar.</tt></li> <li><tt>01.18.2006 GUI: separte controls for min/max and low/high.</tt></li> <li><tt>01.24.2006 HISTOGRAM EQU: is now based on low/high, not min/max.</tt></li> <li><tt>01.27.2006 GUI: fixed a problem with updating the current colormap.</tt></li> <li><tt>01.30.2006 PANNER: under truecolor visuals, the panner is now updated with the colorbar.</tt></li> <li><tt>02.01.2006 TEMPLATE: tweak xmm templates for correct boresite.</tt></li> <li><tt>02.03.2006 GUI: fixed Shift-Tab under linux.</tt></li> <li><tt>02.03.2006 GUI: fixed a problem with loading multiple files, with -single command line option, followed by Match Frame. The frames where not realized so the coordinate systems where not valid.</tt></li> <li><tt>02.03.2006 MARKERS: added the ability to toggle marker text.</tt></li> <li><tt><b>02.08.2006 RELEASE version 4.0b8</b></tt></li> <li><tt>02.07.2006 TCL/TK: update to version 8.4.12</tt></li> <li><tt>02.08.2006 CROSSHAIR: fix a typo that caused the crosshair command-line option to fail.</tt></li> <li><tt>02.27.2006 CATALOG: fixed a problem with finding which columns contain RA and DEC.</tt></li> <li><tt>02.27.2006 XPA: fixed a problem with xpaget ds9 width.</tt></li> <li><tt>03.20.2006 DSS: add new survey options for STSCI.</tt></li> <li><tt>03.24.2006 i18n: finished implemenation of internationalization and localization code.</tt></li> <li><tt>03.29.2006 SCALE: fixed a problem with RGB frames and log/pow scales. Incorrect low/high values were being used to calculate the scale.</tt></li> <li><tt>03.29.2006 PREFS: the default prefs file is now ds9.prf. The following directories are now searched in order: ./ ~ /usr/local/lib /opt/local/lib </tt></li> <li><tt>03.29.2006 INITALIZATION: the default initalization file is now ds9.ini. The following directories are now searched in order: ./ ~ /usr/local/lib /opt/local/lib </tt></li> <li><tt>03.31.2006 GUI: fixed a problem with several dialog boxes with the Paste menu option. If the clipboard was empty, an error was generated.</tt></li> <li><tt>04.3.2006 FITS HEADER: fixed a problem displaying datacube headers.</tt></li> <li><tt>04.3.2006 PROJECTION REGION: Projection region plots can now be accessed via XPA PLOT</tt></li> <li><tt>04.5.2006 MACOSX: fix a problem with the macosx startup scripts to allow path names with a space.</tt></li> <li><tt>04.7.2006 WCS: fix a problem WCS menu and images without a wcs.</tt></li> <li><tt>04.10.2006 GRID: fixed a problem with GLACTIC wcs, AST, WCSSUBS, and defined LATPOLE/LONPOLE keywords.</tt></li> <li><tt><b>04.15.2006 RELEASE version 4.0b9</b></tt></li> <li><tt>04.18.2006 CATALOGS: fixed a problem with filter editor menu.</tt></li> <li><tt>04.18.2006 CATALOGS: fixed a problem with searching for other catalogs</tt></li> <li><tt>04.24.2006 TEMP: DS9 will now look for environment vars TEMP and TMP first for location of temp directory.</tt></li> <li><tt>04.28.2006 PREFS: Fixed a problem with writing invalid preferences.</tt></li> <li><tt>04.28.2006 PS: Fixed a problem with printing Grayscale and pure white values. They were being rounded off to 254, not 255.</tt></li> <li><tt>04.28.2006 PREFS: prefs are now written to a users home directory if available (including windows) and hidden.</tt></li> <li><tt>05.02.2006 GCC: now compiles properly under gcc 4.1</tt></li> <li><tt>05.08.2006 SCALE: more checks for illegal low/high values for log/pow scales</tt></li> <li><tt>05.10.2006 BIN: fix an issue with calculated width/height. No matter the bin factor, or the dimensions of the data, always have at least an 1x1 image.</tt></li> <li><tt>05.11.2006 DARWIN: compile under 10.4.x with no OSSPINLOCKLOCK, which is not available under 10.3.x</tt></li> <li><tt>05.16.2006 CROSSHAIR: fixed a problem with xpa/cmd option crosshair.</tt></li> <li><tt>05.16.2006 ANALYSIS: fixed a problem with loading analysis files with bindings at startup with one frame.</tt></li> <li><tt>05.22.2006 WCSSUBS: Update to version 3.6.4</tt></li> <li><tt>05.25.2006 ANALYSIS: add $xcen and $ycen macros.</tt></li> <li><tt>05.25.2006 ANALYSIS: add $vo_method macro.</tt></li> <li><tt>06.05.2006 FITSY++: fixed a problem with incorrectly detecting the beginning sequence of gz stream.</tt></li> <li><tt>06.12.2006 HV/XPA: Implemented 'xpaset' mime support.</tt></li> <li><tt>06.14.2006 FITS: Fixed a problem with displaying the header of a file in which there was an extention name in the primary header.</tt></li> <li><tt>06.21.2006 GUI: Fixed a problem -single and -blink command line optons.</tt></li> <li><tt>06.21.2006 REGIONS: Check for valid image loaded before processing load regions commands.</tt></li> <li><tt>06.21.2006 MOSAIC: fixed a problem with mosaicimage wfpc2 and display header.</tt></li> <li><tt>06.23.2006 HV: Implemented file caching.</tt></li> <li><tt>06.23.2006 HV: Implemented image caching.</tt></li> <li><tt>06.26.2006 HV: Implemented multiple mime processing.</tt></li> <li><tt>06.29.2006 TCLLIB: update to version 1.8</tt></li> <li><tt>07.11.2006 WCSSUBS: update to version 3.6.5</tt></li> <li><tt>07.11.2006 WCSSUBS: fix a problem with naxis&gt;2</tt></li> <li><tt>07.12.2006 NAME SERVER: support for HTTP redirection</tt></li> <li><tt>07.12.2006 IMAGE SERVER: support for HTTP redirection</tt></li> <li><tt>07.13.2006 CATALOGS: support for HTTP redirection</tt></li> <li><tt>07.13.2006 REGIONS: fixed a problem with cut/copy/paste regions dialog.</tt></li> <li><tt>07.25.2006 PREFS: preferences are automatically saved.</tt></li> <li><tt>07.25.2006 FITSY++: fixed a problem with large RGB arrays and streams.</tt></li> <li><tt>07.31.2006 RGB: add support for invert RGB colormap.</tt></li> <li><tt>07.31.2006 FIRST: add support for VLA FIRST image server.</tt></li> <li><tt>08.01.2006 HTTP: add timeout options to all geturl calls.</tt></li> <li><tt>08.02.2006 CATALOGS: add suppport for SDSS.</tt></li> <li><tt>08.07.2006 ANALYSIS: fixed a problem with cancel geturl tasks.</tt></li> <li><tt>08.14.2006 TKTABLE: fixed configure files for darwin intel.</tt></li> <li><tt>08.14.2006 TKIMG: fixed configure files for darwin intel.</tt></li> <li><tt>08.14.2006 AST: apply patch to plot.c at line 23207</tt></li> <li><tt>08.17.2006 BIN: fixed a problem with binning 3D and integer cols.</tt></li> <li><tt>08.17.2006 BIN: fixed a problem with binning 3D and updating the bin dialog box.</tt></li> <li><tt>08.17.2006 SCALE: changed AUTO to sample only for mosaics. </tt></li> <li><tt>08.30.2006 CATALOG: fixed a problem with filtering and column names to leading or trailing spaces. </tt></li> <li><tt>08.31.2006 CATALOG: add support for CSV catalog files with/wo header. </tt></li> <li><tt>09.06.2006 EPANDA: Fixed problems with rendering start and stop angles.</tt></li> <li><tt>09.08.2006 BPANDA: Fixed problems with rendering start and stop angles.</tt></li> <li><tt>09.11.2006 TEMPLATES: When creating templates, they were placed in the upper right corner of the frame. This has been changed to the center of the frame.</tt></li> <li><tt>09.11.2006 TEMPLATES: When templates where created via the gui, the screen was not refreshed properly. This has been corrected.</tt></li> <li><tt>09.12.2006 FITSY++: Fixed a problem with hist() and column values of 0, which was used as the default value.</tt></li> <li><tt>09.13.2006 COMPOSITE: Add complement angle.</tt></li> <li><tt>09.15.2006 CPANDA,EPANDA,BPANDA: fixed a conflict with funtools. Stop/start angles will alway increase in value.</tt></li> <li><tt>09.18.2006 MOSAIC IMAGE NEXT: removed support.</tt></li> <li><tt><b>10.01.2006 RELEASE version 4.0b10</b></tt></li> <li><tt>10.01.2006 I18N: Add Portuguese support.</tt></li> <li><tt><b>10.01.2006 RELEASE version 4.0b10.1</b></tt></li> <li><tt>10.01.2006 FITS: external support for bzip2.</tt></li> <li><tt>10.01.2006 REGIONS: fixed a problem with clipping regions in tile mode.</tt></li> <li><tt>10.03.2006 HV: add support for HTTP-EQUIV HTML Meta keyword.</tt></li> <li><tt>10.03.2006 PANDA: fixed a problem with zero length radius and printing.</tt></li> <li><tt>10.10.2006 WCSSUBS: update to version 3.6.6</tt></li> <li><tt>10.13.2006 TCL/TK: update to version 8.4.13</tt></li> <li><tt>10.13.2006 FUNTOOLS: update to version 1.3.0b22</tt></li> <li><tt>10.13.2006 TCLLIB: update to version 1.9</tt></li> <li><tt>10.23.2006 LANGUAGE: add support for following languages fr,es,de,it,pt,ru,da.</tt></li> <li><tt>10.23.2006 HTTP: increase timeout to 3 minutes.</tt></li> <li><tt>10.24.2006 GUI: add view colorbar numerics support.<br></tt></li> <li><tt>10.31.2006 CATALOGS: add full symbol support via xpa/command line.<br></tt></li> <li><tt>10.31.2006 CATALOGS: fixed a problem with the optional catalog name as a parameter.<br></tt></li> <li><tt>10.31.2006 GUI: multi column frame and active frame menu.<br></tt></li> <li><tt>10.31.2006 GUI: multi column catalog col name menus.<br></tt></li> <li><tt>11.02.2006 XPA: add xpaget ds9 fits bitpix.<br></tt></li> <li><tt>11.06.2006 GUI: add confirmation option preference.<br></tt></li> <li><tt>11.28.2006 REGIONS: add xpa/command line option get info.<br></tt></li> <li><tt>11.28.2006 REGIONS: fits regions file: first look for extension [REGIONS], then attempt to load the first extension.<br></tt></li> <li><tt>11.29.2006 FITS: fixed a overflow problem with very very large fits images > 8Gb in size.<br></tt></li> <li><tt>12.06.2006 RGB: fixed a problem with aligning very large images.<br></tt></li> <li><tt>12.07.2006 MOSAIC: fixed a problem with wcs mosaicsa and very large images.<br></tt></li> <li><tt>12.09.2006 FITS: removed a kludge for defining the wcs tangent point that only affected AIR and AZP projections.<br></tt></li> <li><tt>12.12.2006 GUI: fixed a problem with default vertical layout. The default size is now consistent with other options.<br></tt></li> <li><tt>12.13.2006 SAVEAS: fixed a problem with PHYSICAL and WCS coordinates. They were 1 pixel off.<br></tt></li> <li><tt>12.13.2006 CPANDA/EPANDA: fixed a problem with render and printing with an image flipped.<br></tt></li> <li><tt>12.20.2006 RGB: NaN are now ignored when building an RGB image.<br></tt></li> <li><tt>12.22.2006 GUI: Increased default X size so that buttons do not cause automatic resizing.<br></tt></li> <li><tt>01.08.2007 PREFS: fixed a problem with frame parser and LoadPrefs so that a preferences file from version b9 will correctly parse.<br></tt></li> <li><tt>01.23.2007 FITS: Added additional checks for valid format and values for DATASEC, DETSEC, and DETSIZE keywords.<br></tt></li> <li><tt>01.24.2007 CATALOGS: fixed a problem with redirect.<br></tt></li> <li><tt>01.24.2007 REGIONS: fixed a problem measuring WCS lengths across wcs mosacis and RGB images.<br></tt></li> <li><tt>01.25.2007 REGIONS: fixed a problem with rotated text regions.<br></tt></li> <li><tt>01.30.2007 DSS: Split DSS server into three servers.<br></tt></li> <li><tt>01.31.2007 GUI: add binning buffersize 8192 and binfactor 256.<br></tt></li> <li><tt><b>02.01.2007 RELEASE version 4.0b11</b></tt></li> <li><tt>02.02.2007 CATALOGS: add cols.<br></tt></li> <li><tt>02.02.2007 VO: default url is now http://cxc.harvard.edu/chandraed/list.txt.<br></tt></li> <li><tt>02.07.2007 PREFERENCES: if ds9 detects a newer prefs file, it will not be processed.<br></tt></li> <li><tt>02.09.2007 SKYVIEW: added support for HEASARC's skyview image cutout service.<br></tt></li> <li><tt>02.09.2007 GUI: dropped the 'b' for beta, afterall, ds9 is always beta!<br></tt></li> <li><tt>02.13.2007 CATALOGS: new non-modal search catalogs support.<br></tt></li> <li><tt>02.13.2007 CATALOGS: add show/hide support.<br></tt></li> <li><tt>02.15.2007 FIRST: fixed a problem with xpa first.<br></tt></li> <li><tt>02.15.2007 2MASS: fixed a problem with xpa 2mass.<br></tt></li> <li><tt>03.06.2007 MASK: add support for fits masks.<br></tt></li> <li><tt>03.06.2007 MOSAIC: remove support for 'fast mosaic' mode.<br></tt></li> <li><tt>03.06.2007 SCALE: added support for zscale parameter prefs.<br></tt></li> <li><tt>03.20.2007 FITSY++: add support for compressed FITS.</tt></li> <li><tt>03.27.2007 WCS: fixed support for alt wcs for bin tables.<br></tt></li> <li><tt>03.29.2007 REGIONS: add support for user specified point sizes<br></tt></li> <li><tt>04.02.2007 GRID: fixed a problem with TNX projection.<br></tt></li> <li><tt>04.03.2007 FITSY++: split code supporting FITS ASCII tables and FITS Binary Tables.<br></tt></li> <li><tt>04.03.2007 FITSY++: removed code supporting FITS Binary Tables substring arrays.<br></tt></li> <li><tt>04.03.2007 WCSSUBS: update to version 3.6.8</tt></li> <li><tt>04.03.2007 FUNTOOLS: update to version 1.3.0b30</tt></li> <li><tt>04.03.2007 XPA: update to version 2.1.7b2</tt></li> <li><tt>04.06.2007 FITSY++: add support for RICE compressed FITS.</tt></li> <li><tt>04.06.2007 SMOOTH: now implemented on a per channel basis for RGB.</tt></li> <li><tt>04.10.2007 WCSSUBS: backed out of wcscon.c to version 3.6.6 due to a bug in prec.</tt></li> <li><tt>04.12.2007 WINDOWS: fixed a problem with iis and iraf.</tt></li> <li><tt><b>04.15.2007 RELEASE version 4.12</b></tt></li> <li><tt>04.16.2007 FITSIMAGE: fixed an bug with setting file names after a reset.</tt></li> <li><tt>04.26.2007 ESO-DSS: support new survey names.</tt></li> <li><tt>05.10.2007 NSVR: fixed a problem with xpa/command line name lookup.</tt></li> <li><tt>05.10.2007 NSVR: fixed a problem redirection.</tt></li> <li><tt>05.11.2007 TCL: realize ds9 before executing any external tcl source.</tt></li> <li><tt>05.11.2007 CATALOGS: for csv files, ignore any comment lines.</tt></li> <li><tt>05.21.2007 MOSAICS: fixed several problems with constructing mosaics from both IRAF and WCS keywords.</tt></li> <li><tt>05.21.2007 IRAF MOSAICS: the image size is now defined by the actual data (just as with WCS) and not the DETSIZE keyword.</tt></li> <li><tt>05.30.2007 GRID: fixed a problem with plain font style that resulted in always using system and not the selected font.</tt></li> <li><tt>05.31.2007 ELLIPSE PANDA: fixed a problem incorrect postscript code.</tt></li> <li><tt>06.08.2007 GUI: fixed a problem with the Display Fits Header button.</tt></li> <li><tt>06.13.2007 FITS: add fits header command and xpa point.</tt></li> <li><tt>06.30.2007 RULER: fixed a problem with displaying the length text.</tt></li> <li><tt><b>07.15.2007 RELEASE version 4.13</b></tt></li> </ol> </ol> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r3.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000103440�10415010756�014641� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 3.0 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 3.0 Release Notes</h3> <ol> <h4> <b>Version 3.0</b></h4> <ol> <li> <tt>12.24.2002 TCL/TK: update to 8.4.1</tt></li> <li> <tt>12.24.2002 BLT: update to 2.4z</tt></li> <li> <tt>12.24.2002 TKIMG: update to 1.3rc</tt></li> <li> <tt>01.03.2003 XPA: fixed a problem with 'xpaget ds9 regions selected'</tt></li> <li><tt>01.28.2003 SAVEAS: now saves all slices of a data cube, if the display mode is single.</tt></li> <li><tt>01.28.2003 GUI: Add 'wm protocol . WM_DELETE_WINDOW QuitDS9' for main window so that tcl/tk 8.4 does not segv when a user double clicks on a close window icon.</tt></li> <li><tt>01.29.2003 GCC: add support for gcc 3.0/3.2</tt></li> <li><tt>01.29.2002 GCC: updated saotk/FlexLexer.h from flex 2.5.27, available at http://lex.sourceforge.net/<br> </tt></li> <li><tt>02.04.2003 WINDOWS: modify configuration files for tkimg1.3 and tkhtml to support windows.<br> </tt></li> <li><tt>02.05.2003 WCS: upgrade to 3.3.0</tt></li> <li><tt>02.06.2003 ARCHIVE: the default ADS max search size is now a radius of .1 arcmin.</tt></li> <li><tt>02.06.2003 XPA: add '-xpa tcl' command line option. By default, disable xpa tcl access since it is a major security risk.</tt></li> <li><tt>02.07.03 FITS: fixed a problem with loading fits files via the url menu or command line.<br> </tt></li> <li><tt>02.07.03 HTTP: loading images via url http processes the image based on the http header mime type and encoding, not the file name. images loaded via url ftp are still processed based on file name.</tt></li> <li><tt>02.07.03 PLOT: fixed a problem with global vars and the plot widget.</tt></li> <li><tt>02.11.03 BINNING: fixed a bug with the bin table smoothing support. If the bin factor is large enough to bin the entire image in the bin buffer, ds9 would segv by trying to read out of bounds.</tt></li> <li><tt>02.25.03 XPA: fixed a bug with loading an image from xpa stdin without a filename.</tt></li> <li><tt>02.25.03 XPA: add 'fillbuf=false' to all xpa receive commands that do not use $buf. This will speed up processing because the data socket is not opened.</tt></li> <li><tt>02.25.03 XPA: fixed a problem with appending an wcs via xpa. The appended wcs is now positioned at the end, not the beginning. also, a problem occurred when the 'END' card was not the last card of the header. This has been fixed.</tt></li> <li><tt>02.25.03 XPA: changes to xpa regions syntax. 'moveback'/'movefront' are now 'move back'/'move front', 'selectall'/'selectnone' are now 'select all'/'select none', and 'deleteall' is 'delete all'. Backward compatibility has bee maintained</tt></li> <li><tt>02.25.03 XPA: add 'select group &lt;groupname&gt;' and 'delete select' to xpa regions access point.</tt></li> <li><tt>02.26.03 HV: add support for gif,png,ppm,xbm,xpm file formats</tt></li> <li><tt>02.27.03 </tt><tt>HV: </tt><tt>fixed some problems with tkhtml uri resolver. This cleans up a lot of tcl code.</tt></li> <li><tt>03.04.03 HV: images are now scaled if the width/height args are provided in the html src.</tt></li> <li><tt>03.04.03 ARCHIVE: add chandra archive web chaser.</tt></li> <li><tt>03.12.03 COLORMAP: Fixed a problem with InitColorbar and a colormap of A or B.</tt></li> <li><tt>03.12.03 ANALYSIS: all comments after # are ignored.</tt></li> <li><tt>03.12.03 ANALYSIS: non macros can be escaped by using $$.</tt></li> <li><tt>03.31.03 COMMAND: Add -frame command line option.</tt></li> <li><tt>04.08.03 GUI: Remove Magnifier Mode option, along with Magnifier Replicate code.</tt></li> <li><tt>04.23.03 HST WFPC: Mosaic images must be loaded directly. this fixes a problem in that it was not possible to autodect a WFPC2 image in an incoming data stream, such as stdin.</tt></li> <li><tt>05.12.03 API: *** CHANGE *** Frame load syntax has changed to make it consistent across all modes and file formats. In particular, the general syntax is: &lt;frame&gt; load fits|array &lt;filename&gt; mmap|alloc|alloc gz|channel|shared|socket|var &lt;options&gt;</tt></li> <li><tt>05.12.03 API: *** CHANGE *** shared memory loads no longer require the size of the memory segment.</tt></li> <li><tt>05.20.03 WCS: update to 3.3.4</tt></li> <li><tt>05.20.03 AST: update to 2.0</tt></li> <li><tt>05.22.03 GRID: fix a problem with grid.C interface to AST. The text bounding box code was returning the coordinates in a clockwise manner. It needs to be returned in an anti-clockwise manner.</tt></li> <li><tt>05.22.03 GRID: Add support for user specified Grid Axes Numerics gap.</tt></li> <li><tt>05.27.03 GRID: Fixed a problem with the bounding box of a publication grid. it was .5 pixels off.</tt></li> <li><tt>05.28.03 GUI: Fixed a problem with 'get cursor'. Sometimes, as with loading dss images, the matrices were not updated in time, and 'get cursor' returned bogus values. Now all calls to 'get cursor' force an update.</tt></li> <li><tt>06.02.03 GUI: fixed several problems with examine mode</tt></li> <li><tt>06.02.03 ARCHIVE: add NOAO 4MASS and SIRTF and NOAO NSA to archive menu</tt></li> <li><tt>06.09.03 RGB: support is FINISHED! now, lets see how its works!</tt></li> <li><tt>06.11.03 RGB: Add Lock Channels to lock most Scale and Bin parameters between channels.</tt></li> <li><tt>06.16.03 GRID: Add numerics spacing to save/load grid configuration</tt></li> <li><tt>06.16.03 FITS: Add 3D array data cube</tt></li> <li><tt>06.17.03 FITS: Fixed a problem with an incorrect data cube dialog and wfpc2 mosaics and rgb data cubes. Basically, these two cases are not really data cubes.</tt></li> <li><tt>06.17.03 RGB: Replace RGB menu with RGB dialog.</tt></li> <li><tt>06.17.03 XPA: Fixed a problem with xpaget ds9 regions [include|exclude|source|background].</tt></li> <li><tt>06.18.03 REGION: fix a problem with non-linear physical coordinates and save/load regions.</tt></li> <li><tt>06.18.03 WCS: fix a problem with determining the rotation of a wcs coordinate system. previously, CRPIX was used as the start point. This does not work in cases where the tangent point is very far off the image. Instead, (1,1) is used.</tt></li> <li><tt>06.18.03 WCS: Remove preference Panner WCS origin. This is stupid and breaks with the previous change. Just remove it instead of trying to fix it.</tt></li> <li><tt>06.26.03 FITS: Add support 3D array data cubes.</tt></li> <li><tt>06.30.03 RGB: Add support for RGB array data cube.</tt></li> <li><tt>07.01.03 DSS: Fixed namesrv.tcl and dss.tcl to promote more robust error handling. In particular, http error codes are now checked, and the results are verified before proceeding</tt></li> <li><tt>07.01.03 XPA: fixed a problem with $ds9 -xpa tcl. The next argument was being ignored.</tt></li> <li><tt>07.02.03 DSS: fixed another problem with namesrv.tcl. SAONED and SAOSIMBAD were returning incorrect values for southern hemisphere.</tt></li> <li><tt>07.02.03 HTTP: remove http log from preferences and added http log and ftp log to debug menu</tt></li> <li><tt>07.03.03 GUI: fixed a problem with open file dialog box. if the user clicked 'cancel', an error message would result. this has been corrected.</tt></li> <li><tt>07.09.03 FITS: add Large File Support for Linux. Linux is still restricted to ~2.5Gb.</tt></li> <li><tt>07.10.03 FITS: add FLUSH parameter for fitsy++ array.</tt></li> <li><tt>07.10.03 FITS: Major change in behavior of fitsy++ streams and FLUSH. Only socket and socketgz will flush, all others will not flush the buffer after an error, or after successfull loading a fits image.</tt></li> <li><tt>07.11.03 XPA: add DATACUBE support.</tt></li> <li><tt>07.14.03 WCS: Fixed a problem with WCS XLON-TAN (NPOLE) and AST. NPOLE is a special wcs equ coord system, and has to be handed by wcs2ast().</tt></li> <li><tt>07.15.03 XPA: add xpa iis access port for control of some iis functionality.</tt></li> <li> <p><b><tt>07.17.03 RELEASE version 3.0b4</tt></b></p> </li> <li><tt>07.25.03 FITS: add MMAPINCR memory access mode. This only mmaps the data needed, not the entire file. This allows a user to view many small segements of a very large file.</tt></li> <li><tt>07.28.03 TCL/TK: upgrade to 8.4.4</tt></li> <li><tt>07.30.03 XPA: add regions fg/bg support.</tt></li> <li><tt>08.05.03 PLOT: reimplement analaysis plot widget to support unlimited number of data sets.</tt></li> <li><tt>08.07.03 ARCHIVE: add Rosat All-Sky survey</tt></li> <li><tt>08.08.03 XPA: add PLOT, which allows full control over all plot widgets via xpa.</tt></li> <li><tt>08.13.03 COLORMAP: fixed a problem with loading lut colormaps under linux. ifstream behaves differently between solaris and linux.</tt></li> <li><tt>08.14.03 XPA: changed xpaget array. Now returns the array data in the current frame.</tt></li> <li> <p><tt><b>08.15.03 RELEASE version 3.0b5</b></tt></p> </li> <li><tt>08.18.03 FITS: add Large file support for darwin and linuxppc</tt></li> <li><tt>08.18.03 LINUXPPC: fixed a problem with linking linuxppc. The copy of libX11.a that comes with Yellow Dog 3.0 is bad. So we can't links static.</tt></li> <li><tt>08.19.03 XPA: add options to xpa update so that 'update idletasks' is not run at the end of file loads. This allows the user to do several incremental loads without updating the screen.</tt></li> <li><tt>08.19.03 API: only update idletasks for horz/vert graph if graphs are on</tt></li> <li><tt>08.19.03 API: add debug idletasks support.</tt></li> <li><tt>08.29.03 GCC: gcc 3.3 is now supported. For all code, if GNUC &gt;=3, new &lt;sstream&gt; are used. For all code, GNUC &lt;3, &lt;strstream&gt; is used.</tt></li> <li><tt>08.29.03 PLOT: fixed a problem with saving plot data in x,y,ye format</tt></li> <li><tt>08.29.03 FITS: add LFS for solaris.</tt></li> <li><tt>08.29.03 COMMAND: add -analysismenu command line option at the request of CXC.</tt></li> <li><tt>08.29.03 COMMAND: fixed a problem with -pan and -pan to and other comman line options that follow.</tt></li> <li><tt>09.02.03 FITS: add LFS for alpha.</tt></li> <li><tt>09.04.03 SOLARIS: add new solaris64 port. Requires gcc 3.3 or greater.</tt></li> <li><tt>09.04.03 XPA: upgrade to 2.1.4</tt></li> <li><tt>09.04.03 FILTER: upgrade to 1.2.3b1</tt></li> <li><tt>09.04.03 FITSY: upgrade to 1.2.3b1<br> </tt></li> <li><tt>09.06.03 SOLARIS: fixed a problem with 64bit machines and truecolor displays.</tt></li> <li><tt>09.06.03 FITS: add support for multiple extension fits data cubes.</tt></li> <li><tt>09.08.03 REGION: fixed a problem with projection regions and an undefined variable.</tt></li> <li><tt>09.08.03 BINNING: fixed a problem with fits bin tables without TLMIN/TLMAX or TDMIN/TDMAX. the center was incorrectly being calculated.</tt></li> <li><tt>09.08.03 ARCHIVE: fixed a problem with the NOAO archive web display with no images loaded. The variables 'ra' and 'dec' were not defined.</tt></li> <li><tt>09.08.03 PLOT: ixed a problem with the plot widget and the preferences unique plot parameter.</tt></li> <li><tt>09.09.03 PLOT: project plot xaxis are now in coordinate system specified via the marker dialog box.</tt></li> <li><tt>09.11.03 PLOT: fixed a problem with the line, ruler, and projection regions and properly displaying wcs linear coordinates</tt></li> <li><tt>09.11.03 WCS: cleaned up a lot of code for setting/adjusting coordinate menus</tt></li> <li><tt>09.11.03 RGB: loading a new channel in a rgb image will no longer delete regions, grids, or aux contours.</tt></li> <li><tt>09.15.03 FITS: removed BITPIX32 define. using &lt;int&gt; instead since it is defined as a consistent 4 bytes across all platforms.</tt></li> <li><tt>09.18.03 RGB: split lock rgb into lock scale and lock bin.</tt></li> <li><tt>09.21.03 BINNING: frames now have 'memory' of certain bin paramenters. It is now possiable to set bin parameters before loading a bin table.</tt></li> <li><tt>09.22.03 RGB: InfoBox now displays all values for RGB images, not just the current channel value.</tt></li> <li><tt>09.22.03 API: change names of various tcl marker variables</tt></li> <li><tt>09.22.03 REGION: add prefs for regions color, width, properties, font</tt></li> <li><tt>09.22.03 GUI: add HJKL key bindings as substitute for arrow keys</tt></li> <li> <p><tt><b>09.24.03 RELEASE version 3.0b6</b></tt></p> </li> <li><tt>09.29.03 WCS: changes to getWCSRotation, getWCSOrientation to better reflect the actual rotation</tt></li> <li><tt>09.30.03 XPA: add xpa/command line options for configuration of info panel</tt></li> <li><tt>09.30.03 API: change variable 'mosaic(fast)' to 'ds9(mosaic,fast)'</tt></li> <li><tt>09.30.03 FITS: add new support for blank/Inf/NaN background color</tt></li> <li><tt>10.01.03 FITS: add support for image background color.</tt></li> <li><tt>10.01.03 RGB: add support for RGB lock colorbar</tt></li> <li><tt>10.23.03 HV: add support for VO DIS</tt></li> <li><tt>10.23.03 HV: fixed a problem with forms and encrypting field names, allow with the returned value</tt></li> <li><tt>10.23.03 GUI: Change mode 'Default' to 'None'. We can't use the term 'default' because with problems with tcl switchs and the default keyword</tt></li> <li><tt>10.24.03 WCS: add support for WCS AIPS projections via the preferences menu.</tt></li> <li><tt>10.24.03 API: add acknowledgment</tt></li> <li><tt>11.03.03 COMMAND: fixed a problem with command line options -mosaicimage, -mosaicimagewfpc2, -medatacube</tt></li> <li><tt>11.03.03 FITS: fixed a problem with multiple extension data cube with all memory models except MMAPINCR.</tt></li> <li><tt>11.03.03 COMMAND: fixed a problem with command line options -mosaicimagewcs, -mosaicimageiraf, -mosaicimagewfpc2, -medatacube and RGB frames</tt></li> <li><tt>11.05.03 WCS: remove internal wcsZoom matrix. All wcsZoom actions are now applied to the current &nbsp;zoom matrix. This fixes a number of problems with 'Match Frames to WCS'</tt></li> <li><tt>11.05.03 WCS: fixed a problem with rotated images and examine mode.</tt></li> <li><tt>11.07.03 </tt><tt>REGION: f</tt><tt>fixed a problem with regular panda regions. The code incorrectly determined a regulier panda was irregulier and output it as such.</tt></li> <li><tt>11.07.03 REGION: fixed a problem with region angles in general, where there there was a rotation in the wcs.</tt></li> <li><tt>11.07.03 HV: add Server Apache Refresh support.</tt></li> <li><tt>11.07.03 XPA: add xpaget ds9 fits size &lt;coordsys&gt; &lt;skyformat&gt;</tt></li> <li><tt>11.11.03 XPA: add regions group support.</tt></li> <li><tt>12.01.03 WCS: update to 3.5.0</tt></li> <li><tt>12.01.03 XPA: add get contour &lt;coordinate system&gt; &lt;skyframe&gt; support.</tt></li> <li><tt>12.05.03 WCS: update to 3.5.1</tt></li> <li><tt>12.05.03 XPA: upgrade to 2.1.5</tt></li> <li><tt>12.05.03 FILTER: upgrade to 1.2.3</tt></li> <li><tt>12.05.03 FITSY: upgrade to 1.2.3</tt></li> <li><tt>12.05.03 AST: upgrade to 3.0</tt></li> <li><tt>12.05.03 IIS: upgrade to 1.0</tt></li> <li><tt>12.10.03 REGION: casted all XPoint to short. There is a problem with rendering line segments at very high zoom. X11 overflows and the lines become random. We should check that screen coordinates never exceed SHRT_MAX</tt></li> <li><tt>12.10.03 ANALYSIS: geturl() macro is formated before execution.</tt></li> <li><tt>12.11.03 FITs: add mosaic image next wcs support.</tt></li> <li><tt>12.15.03 RGB: fixed a problem with wcs matching when one of the wcs is flipped in XX</tt></li> <li><tt>12.15.03 WCS: </tt><tt>fixed a problem with wcs matching when one of the wcs is flipped in XX</tt></li> <li><tt>12.15.03 REGION: load fits regions now utilitize the current region color, width, and font</tt></li> <li><tt>12.24.03 WCS: back out change #50. We have to use the projection tan point to correctly build mosaics and RGB images.</tt></li> <li><tt>01.09.04 AST: upgrade to 3.1.1</tt></li> <li><tt>01.09.04 GRID: pass PV,PROJP,PS keywords to AST<br> </tt></li> <li><tt>01.12.04 TCLLIB: add tcllib 1.4. This package contains a number of useful tcl packages<br> </tt></li> <li><tt>01.12.04 FTP: upgrade to 2.4</tt></li> <li><tt>01.13.04 TCL: upgrade to 8.4.5</tt></li> <li><tt>01.13.04 TK: upgrade to 8.4.5</tt></li> <li><tt>01.13.04 HTTP: add support for proxy authentication.</tt></li> <li><tt>01.14.04 COMMAND: fixed a problem with printing from the command line. The canvas widget was not fully realized before printing, resulting in no image.</tt></li> <li><tt>01.15.04 MKTCLAPP: made two changes to the default init script of mktclapp. The first sees that the the virtual file system is init'd before the first call to Tcl. This allows Tcl to 'see' encoding files. The second, for windows only, makes sure that the Tcl windows file system is init'd before the first call to Tcl.</tt></li> <li><tt>01.15.04 MKTCLAPP: add default encoding files to ds9.mta, now that we can use them.</tt></li> <li><tt>01.22.04 GUI: Add preference for default temporary file directory.</tt></li> <li><tt>01.23.04 XPA: add xpa imexam.</tt></li> <li><tt>01.25.04 XPA: add xpa fits header.</tt></li> <li><tt>01.25.04 XPA: add xpa fits depth.</tt></li> <li><tt>01.25.04 XPA: modified xpa fits size.</tt></li> <li><tt>01.25.04 GUI: add language support for info and error messages.</tt></li> <li><tt>02.01.04 WCS: more on #50 and #141. If wcs projection is Zenithal, use CRPIX as reference point to determine wcs rotation and oriention. Otherwise, use image center point.</tt></li> <li><tt>02.04.04 CONTOUR: modified smooth algorithm. We now SMOOTH the entire image with a gaussian kernal. Previously, we would block by 2 before smoothing with a boxcar kernal. Finally, the default method is BLOCK.</tt></li> <li><tt>02.04.04 CONTOUR:&nbsp;</tt><tt>A .5 error has been removed from the BLOCK algorithm.</tt></li> <li><tt>02.04.04 CONTOUR: </tt><tt>the number of contour levels has been inconsistant in the pass. this has been fixed. </tt><tt>If the number of levels is 1, the high cut value is used.</tt></li> <li><tt>02.04.04 CONTOUR: fixed log scale bug. it was incorrectly calculating the levels.</tt></li> <li><tt>02.05.04 SAVEAS: jpeg,tiff,png,ppm support is now internal and available to all ports. gs is no longer needed.</tt></li> <li><tt>02.10.04 REGION: add show/hide support for fg and bg regions.</tt></li> <li><tt>02.10.04 COLORMAP: fixed a problem with the -cmap value x y command. On truecolor visuals, we need to be realized before we start to manipulate the colormap.</tt></li> <li><tt>02.10.04 FITS: cleaned up smooth convolve code. same speed, easier to understand.</tt></li> <li><tt>02.11.04 GUI: Add Colorbar Parameter dialog.</tt></li> <li><tt>02.11.04 COLORBAR: add support for load/save contrast/bias.</tt></li> <li><tt>02.12.04 EXPORT: split EXPORT from SAVEAS. Currently only FITS is supported.</tt></li> <li><tt>02.17.04 CONTOUR: when update data cube slice, automatically regenerate contours.</tt></li> <li><tt>02.18.04 REGION: the marker menu is now enabled if no frame or an empty frame is available.</tt></li> <li><tt>02.20.04 SCALE: add Auto MinMax. by default, use SCAN for single and SAMPLE for Mosaic and DataCube files</tt></li> <li><tt>02.20.04 SCALE: fixed a problem with scobe being reset to LOCAL.</tt></li> <li><tt>02.23.04 CONTOUR: fixed a problem with incorrect contours for mosaics and rgb images at startup.</tt></li> <li><tt>02.23.04 XPA: add cd (current directory) command</tt></li> <li><tt>02.24.04 AST: upgrade 3.2.4</tt></li> <li><tt>02.24.04 DOC: added support for generating postscript and pdf versions of the reference manual.</tt></li> <li><tt>02.25.04 CONTOUR: convert contours to polygons will now also convert any aux contours.</tt></li> <li><tt>02.27.04 PANDA: fixed probems with GUI add angle.</tt></li> <li><tt>02.27.04 CIRCLE: new GUI edit algorithm.</tt></li> <li><tt>02.27.04 ANNULUS: new GUI edit and add annulus algorithms.</tt></li> <li><tt>02.27.04 ELLIPSE: new GU edit algorithm.</tt></li> <li><tt>02.27.04 ELLIPSE ANNULUS: new GUI edit and add annulus algorithm. This fixed a problem with 0 radius annuli. Also fixed a problem with GUI rotate after close dialog box.</tt></li> <li><tt>3.1.04 BOXANNULUS: new GUI edit and add size algorithms. This fixed a problem with 0 size annuli.</tt></li> <li><tt>03.01.04 PANDA: new GUI edit and add annulus algorithms.</tt></li> <li><tt>03.01.04 PANDA: fixed a problem with a full PANDA from 0 to 360 degrees. Previously, it was displayed as 0 to 0 degrees.</tt></li> <li><tt>03.02.04 PANDA: fixed a problem with postscript and radial lines. The zoom was incorrectly being calculated..</tt></li> <li><tt>03.02.04 PANDA: fixed a problem with render in magnifier. The wrong zoom factor was being used.</tt></li> <li><tt>03.09.04 GUI: add Tab/Shift-Tab bindings to panner.</tt></li> <li><tt>03.10.04 GRID: fixed a problem with single publication bounding box. It now takes into account DATASEC.</tt></li> <li><tt>03.10.04 AST: upgrade to 3.2.6</tt></li> <li><tt>03.12.04 GRAPH: graphs are now active for single,tile,and blink modes.</tt></li> <li><tt>03.16.04 WCS LINEAR: fixed many problems with alignment of WCS LINEAR MOSAICS</tt></li> <li><tt>03.16.04 RGB: fixed many problems with alignment of RGB WCS images</tt></li> <li><tt>03.18.04 FITS: fixed a problem with random numbers beening displayed for BLANK/NaN</tt></li> <li> <p><tt><b>03.18.04 </b><b>RELEASE version 3.0b7</b></tt></p> </li> <li><tt>03.22.04 PIXELTABLE: fixed a problem with 'unset pixelValues'.</tt></li> <li><tt>03.22.04 SAVEAS: fixed a problem with 'processSaveAs'.</tt></li> <li><tt>03.22.04 RGB: fixed a problem with turning off all loaded channels within a frame.</tt></li> <li><tt>03.31.04 IIS: fixed a problem with a old variable in DisplayCoordDialog.</tt></li> <li><tt>03.31.04 BINNING: fixed a problem with dimensions of DBL_MIN,DBL_MAX.</tt></li> <li><tt>03.31.04 IIS: turn off blinking cursor while changing colormap so we do not see a color flash due to the updating of the frame when the cursor form is changed.</tt></li> <li><tt>04.01.04 WEB DISPLAY: add options on how to load downloaded fits.</tt></li> <li><tt>04.01.04 WEB DISPLAY: fixed a problem when the image width/height contains garbage.</tt></li> <li><tt>04.02.04 TCL/TK: update to 8.4.6</tt></li> <li><tt>04.05.04 PAN: fixed yet another problem with -pan. Hopefully this time, I've got it right.</tt></li> <li><tt>04.06.04 GRID: fixed a problem with psLine and gcc 2.96.</tt></li> <li><tt>04.06.04 MAKEFILE: fixed a typo with ./configure.</tt></li> <li> <p><tt><b>04.06.04 </b><b>RELEASE version 3.0b8</b></tt></p> </li> <li><tt>04.12.04 SAVEAS: add SaveAs MPEG-1 support using tkmpeg and exmpeg.</tt></li> <li><tt>04.14.04 BINNING: 60% improvement in speed for little endian arch.</tt></li> <li><tt>04.23.04 ZLIB: upgrade to version 1.2.1<br> </tt></li> <li><tt>04.26.04 ALPHA: minor changes to make.alpha and ds9/Makefile for alpha support.</tt></li> <li><tt>04.26.04 FITS: fixed problems with trying to open regions extensions in cases where the mode was not mmap.<br> </tt></li> <li><tt>04.27.04 EXTERNAL FITS: fixed major problems with pattern matching.</tt></li> <li><tt>04.27.04 FITSY++: skip over unknow binary column types. We used to force an exit.</tt></li> <li><tt>04.28.04 FITSY++: fixed a problem with SocketGZ where if too little data had arrived, ds9 would incorrectly see this as an error.</tt></li> <li><tt>04.29.04 GUI: fixed a race condition in which ds9 'thinks' the windows have been realized, and XPA has been init'd and the user starts to delete windows that don't exists. Now XPA is not realized until the canvas window has been realized.</tt></li> <li><tt>04.29.04 LINUX: return to a full static link. Seems like the best option to support current and future versions of linux.</tt></li> <li><tt>04.29.04 PRINT: add print prefs.</tt></li> <li> <p><tt><b>05.03.04 </b><b>RELEASE version 3.0b9</b></tt></p> </li> <li><tt>05.04.04 BINNING: fixed a problem with column size double and buffer overflow on little endian machines.<br> </tt></li> <li><tt>05.04.04 PANDA: fixed a problem with postscript and gcc 2.95 compilers. This problem had already been fixed for gcc 3.x compilers.</tt></li> <li><tt>05.06.04 BINNING: add support for variable binning in x and y.</tt></li> <li><tt>05.07.04 IIS: fixed a problem with buffer overflow and determining imtool.rc file location.</tt></li> <li><tt>05.07.04 FRAMEBASE: fixed some minor memory leaks.</tt></li> <li><tt>05.10.04 BINNING: for FITS REGIONS files, when loading against a binned image, compare X and Y bin columns to regions X and Y bin columns for a match. Do not load unless they match.</tt></li> <li><tt>05.10.04 GUI: add 'option' command to control GUI appearance. Removed many -bd 2 options to clean up the interface.</tt></li> <li><tt>05.12.04 BINNING: fixed a major problem with 3D binning. Once it was turned on and then turned off, important internal parameters where not being update, resulting in segvs.</tt></li> <li><tt>05.15.04 RGB: fixed memory leak in loading RGB images.</tt></li> <li><tt>05.17.04 LINUX: ok, back to two versions: one dynamic, one static. The static version is buggy under Fedora, but is required for old versions of RH. So the default version will be dynamic linked, with an static version available for older machines.</tt></li> <li><tt>05.21.04 XPA: fixed a problem with WCS REPLACE FILE and WCS APPEND FILE.</tt></li> <li><tt>05.25.04 PANDA: fixed CIAO output so that the start angle is always less than the end angle.</tt></li> <li><tt>05.26.04 FITSY++: clean up code for strm.C, map.C, mapincr.C</tt></li> <li><tt>05.31.04 FITSY++: introduce new 'internal paging' mapince.C for binning files larger than 1Gb. Only 1Gb segments are mmap at one time, to allow binning &gt;2Gb/&gt;4Gb bin tables under a 32bit OS.</tt></li> <li><tt>05.31.04 FITSDATA: optimized swap(), getValueFloat(), getValueDouble(), and scan() in hopes of speeding up display times, especially for linux.</tt></li> <li><tt>06.13.04 WCS: upgrade to version 3.5.3</tt></li> <li><tt>06.16.04 WEB DISPLAY: increased default font by one size.</tt></li> <li><tt>06.16.04 GUI: fixed a problem with display header. Under Fedora Core 2, the default font size was too small.</tt></li> <li><tt>06.17.04 XPA: add fits header keyword support.</tt></li> <li><tt>06.17.04 PLOT: add option plot names to xpa, plot name in window title, plot data command</tt></li> <li><tt>06.17.04 PLOT: fixed a problem with closing xpa plots via xpa.</tt></li> <li><tt>06.18.04 PLOT: remove prefs 'Unique Plot'. This never worked correctly and is now obsolete.</tt></li> <li><tt>06.21.04 PANDA: radii now extend from inner annuli to outer annuli and not from the center.</tt></li> <li><tt>06.21.04 RGB: fixed a problem with 'fit to zoom' for rgb frames.</tt></li> <li><tt>06.22.04 AST: update to version 3.3-1.</tt></li> <li><tt>06.23.04 GRIDS: fixed justification (yet again!)</tt></li> <li><tt>06.24.04 REGIONS: the default GUI size is now constant, reguardless of current zoom.</tt></li> <li><tt>06.24.04 REGIONS: add support for cut/copy/paste regions across frames.</tt></li> <li><tt>06.25.04 REGIONS: add unselect, begin rotate, end rotate, begin move, end move, begin edit, end edit callback support.</tt></li> <li><tt>06.25.04 GUI: add support for multiple FITS headers for multiple extension FITS files.</tt></li> <li><tt>06.28.04 REGIONS: add support for listing WCS keywords and values as comments in region files.</tt></li> <li><tt>06.28.04 REGIONS: fixed a problem with the TEXT region handles with zooms not equal to 1.</tt></li> <li><tt>06.28.04 XPA: fixed a problem with xpaset regions color and xpaset regions width.</tt></li> <li><tt>06.29.04 FITS: add support for reload option. if reload option is set, markers and aux contours are preserved across loads.</tt></li> <li><tt>07.01.04 FITSY++: fixed a problem with binning if the image header contained more than 36 cards.</tt></li> <li><tt>07.01.04 FITSY++: added TV and TS keyword support for FITS bin tables.</tt></li> <li><tt>07.01.04 FITSY++: add TP keyword support for FITS bin tables.</tt></li> <li><tt>07.02.04 GRID: fixed a problem with a wcs with PC keywords.</tt></li> <li><tt>07.05.04 WCS: removed WCS projection option. Its no longer needed.</tt></li> <li><tt>07.05.04 GRID: fixed several problems with converting from wcs to AST. AST is very very picky as to which keywords to use and in what order. These include CDELT's, CD's, PC's, CROTA's.</tt></li> <li><tt>07.08.04 SAVEAS: reorganize save as menus.</tt></li> <li><tt>07.08.04 SAVEAS: add support for saving multiple frames as MPEG movie.</tt></li> <li><tt>07.13.04 MOSAIC: fixed a problem with mosaic image wcs with orientations of xx.</tt></li> <li><tt>07.14.04 WCS: upgrade to version 3.5.5.</tt></li> <li><tt>07.14.04 FITSY++: add support for real number format 'D'.</tt></li> <li><tt>07.14.04 FITSY: add changes to support real number format 'D'.</tt></li> <li><tt>07.15.04 ANALYSIS: stderr can now be redirected to stdout for $text with the |&amp; macro.</tt></li> <li><tt>07.15.04 ANALYSIS: shell environment vars will be expanded within the command with the env() macro.</tt></li> <li><tt>07.15.04 ANALYSIS: add support for the WEB menu item.</tt></li> <li> <p><tt><b>07.26.04 </b><b>RELEASE version 3.0<br> </b></tt></p> </li> <li><tt>07.28.04 IIS: fixed a problem with iraf iis support that would sometimes result in a blank screen.</tt></li> <li> <p><tt><b>07.28.04 </b><b>RELEASE version 3.0.1<br> </b></tt></p> </li> <li> <tt>08.02.2004 VECTOR: fixed a problem with matrix inversion with numbers smaller than DBL_EPSILON.</tt></li> <li><tt>08.02.2004 FRAME: check for negative zoom.</tt></li> <li><tt>08.06.2004 FITSIMAGE: fixed a problem with determining the length of a vector in the case of a non-wcs rotated coordinate system.</tt></li> <li><tt>08.09.2004 GRID: fixed a problem with a rotation in physical and wcs linear grids.</tt></li> <li><tt>08.10.2004 MAKEFILE: add support for emacs tags in saods9/saotk</tt></li> <li><tt>08.12.2004 PROJECTION: fixed a problem with paste projection and setup callback procs.</tt></li> <li><tt>08.12.2004 REGIONS: fixed a problem where regions properties where lost if cut/paste across frames.</tt></li> <li><tt>08.13.2004 DIALOGS: fixed an issues with some windows managers who needed a hint to bring all dialogs to the front.</tt></li> <li><tt>08.13.2004 POLYGON: change default create method to be simular to box.</tt></li> <li><tt>08.13.2004 POLYGON: add prefs default polygon size.</tt></li> <li><tt>08.13.2004 POLYGON: fixed a problem with the control handles at high zoom.</tt></li> <li><tt>08.16.2004 REGIONS: fixed a problem with updating coordinates/angles/distances when rebinning a FITS bin table.</tt></li> <li><tt>08.16.2004 REGIONS: add default system, sky, skyformat, dist system, and dist format for regions dialog to preferences.</tt></li> <li><tt>08.16.2004 FITSY++: fixed a problem with &lt;unsigned char&gt; columns. They where incorrectly cased as a &lt;char&gt;.</tt></li> <li><tt>08.18.2004 SCALE: nolonger reset scale mode from USERCLIP on load FITS.</tt></li> <li><tt>08.18.2004 AST: upgrade to version 3.4</tt></li> <li><tt>08.18.2004 GRID: minor tweaks with the default axes numerics gaps.</tt></li> <li><tt>08.18.2004 REGIONS: for RGB frames, always use the keyFits channel in mapping regions to/from reference coordinate system.</tt></li> <li><tt>08.19.2004 LINUX64: add support for Linux 64.</tt></li> <li><tt>08.24.2004 XPA: add get data support.</tt></li> <li><tt>08.25.2004 AST: fixed a bug with using free'd memory in plot.c</tt></li> <li><tt>08.25.2004 GUI: fixed two problems with the getDataValues routine. With non-symetric binning or equatorial sky coordinates, an incorrect number of values where returned.</tt></li> <li> <p><tt><b>08.27.2004 </b><b>RELEASE version 3.0.2<br> </b></tt></p> </li> <li><tt>09.01.2004 FTTYS++: add a check for mmapincr and mmap to ensure that there is at least 2880 bytes before trying to parse a header.</tt></li> <li><tt>09.02.2004 FITSY++: add new memory mode, SMMAP which allows for split fits mmap files.</tt></li> <li><tt>09.02.2004 XPA: add new support for split mmap and shared FITS files.</tt></li> <li><tt>09.03.2004 FITSY++: add new memory mode, SSHARE which allows for split fits shared memory files.</tt></li> <li><tt>09.06.2004 COMMAND: add support for split mmap and shared FITS files.</tt></li> <li><tt>09.07.2004 XPA: update to 2.1.6</tt></li> <li> <p><tt><b>09.10.2004 </b><b>RELEASE version 3.0.3<br> </b></tt></p> </li> </ol> </ol> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r2.2.html����������������������������������������������������������������������0000644�0001750�0001750�00000044006�10415010756�014644� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 2.2 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 2.2 Release Notes</h3> <ol> <h4> <b>Version 2.2.1</b></h4> <ol> <li> <tt>11.04.2002 fixed bin smooth buttons.</tt></li> <li> <tt>11.07.2002 remove debug statements in dss.tcl</tt></li> <li> <tt>11.07.2002 fixed a problem with pure virtual method called when frame was deleted and histequ was the active scale.</tt></li> <li> <tt>11.07.2002 fixed a problem with pasting filters that contains '\n' on the end of the string.</tt></li> <li> <tt>11.14.2002 add W3Browse to archive menu</tt></li> <li> <tt>11.14.2002 Web Display: for redirection, first use 'location' meta data parameter, then look for first 'href' in html to find the redirection url.</tt></li> <li> <tt>11.14.2002 move 'IISInit' after 'ProcessCommandLine' so that iis command line options take affect.</tt></li> <li> <tt>11.14.2002 remove menu short cut options. Too many conflicts and unable to support multiple languages.</tt></li> <li> <tt>11.18.2002 change prefs(scalemode) to prefs(scale,mode), prefs(scalescope) to prefs(scale,scope) and added prefs(scale,scope) to prefs written.</tt></li> <li> <tt>11.18.2002 change prefs(minmaxmode) to prefs(minmax,mode), prefs(minmaxsample) to prefs(minmax,sample)</tt></li> <li> <tt>11.18.2002 changes to Archive Servers preferences take effect immediately.</tt></li> <li> <tt>11.19.2002 Web Display: improved support for fits mime-types.</tt></li> <li> <tt>11.20.2002 Web Display: improved HVVerifyURL repairing urls.</tt></li> <li> <tt>11.20.2002 Archive: add IRAS MSX support.</tt></li> <li> <tt>11.22.2002 add 'update now' when a new display is received. This will allow 'movies' from iraf to display properly.</tt></li> <li> <tt>11.22.2002 ds9 version 2.2.1 released to the public.</tt></li> </ol> <h4> <b>Version 2.2</b></h4> <ol> <li> <tt>09.03.2002 add Archive Server user prefs.</tt></li> <li> <tt>09.03.2002 when HV window is unable to parse input, place a html header around it and display it as text.</tt></li> <li> <tt>09.04.2002 update FITS Bin Table WCS keywords to conform to 25 June 2002 WCS FITS Documentation.</tt></li> <li> <tt>09.04.2002 add support for FITS Bin Table Alt WCS keywords.</tt></li> <li> <tt>09.04.2002 corrected minor errors in xpa documentation.</tt></li> <li> <tt>09.04.2002 fixed a minor memory leak when frame is deleted and an image is still loaded.</tt></li> <li> <tt>09.05.2002 added IPAC NED to archive menu.</tt></li> <li> <tt>09.05.2002 add 'marker # move to canvas x y' command for CXC.</tt></li> <li> <tt>09.05.2002 add 'marker # angle' command for CXC.</tt></li> <li> <tt>09.09.2002 change ds9 regions syntax for ellipse annulus and box annulus from old saoimage to funtools syntax.</tt></li> <li> <tt>09.10.2002 undid grid WIDGETBB fix. The results where not acceptable.</tt></li> <li> <tt>09.12.2002 fixed a nasty bug with binning FITS bin tables and high bin factor values.</tt></li> <li> <tt>09.13.2002 add Match Scales to Frame menu. This matches all scale parameters across all frames.</tt></li> <li> <tt>09.16.2002 add Grid debug option.</tt></li> <li> <tt>09.17.2002 upgrade to ast 1.8.9. This corrected two problems. First, incorrect grids were generated for dss images in the southern hemisphere. Second, a problem with galactic grids that crossed 0 degrees.</tt></li> <li> <tt>09.17.2002 modify grid code to not to set attributes unless really needed. ast 1.8.9 tends to set attributes much more often than previous versions.</tt></li> <li> <tt>09.17.2002 fixed a problem with reconizing non-standard wcs in the header.</tt></li> <li> <tt>09.17.2002 add more xpa grid support for coordinate systems, grid type, and view options.</tt></li> <li> <tt>09.18.2002 fixed grid axes label and title spacing problems in publication mode.</tt></li> <li> <tt>09.18.2002 add optional grid axes label and title spacing parameters that override internal calculated values.</tt></li> <li> <tt>09.18.2002 the grid x-axis is now plotted on the bottom of publication grid.</tt></li> <li> <tt>09.18.2002 zoom to fit now makes room for labels for publication grid.</tt></li> <li> <tt>09.19.2002 fixed a problem with Clear Analysis File that deleted too much of the Analysis Menu.</tt></li> <li> <tt>09.19.2002 support new vo list syntax of a tab delimited newline terminated list of three parameters, xpa, title, and url.</tt></li> <li> <tt>09.20.2002 PHYSICAL Coordinate System: first look for WCSNAMEx='PHYSICAL', then look for LTM/LTV keywords.</tt></li> <li> <tt>09.24.2002 fixed yet another bug with binning, and TLMIN/TLMAX keywords whose values were not powers of 2.</tt></li> <li> <tt>09.24.2002 fixed a problem with cores and bad wcs grids. ds9 now checks to make sure ast generated a vaild grid.</tt></li> <li> <tt>09.24.2002 WebDisplay: plain text is now displayed using &lt;pre&gt;.</tt></li> <li> <tt>09.24.2002 WebDisplay: default method for forms is now GET.</tt></li> <li> <tt>09.24.2002 WebDisplay: default width for TEXT form elements is 20</tt></li> <li> <tt>09.24.2002 XPA nameserver: http has a error, so just clear errorInfo.</tt></li> <li> <tt>09.25.2002 fixed a bug in wcsinit.c, line 328 and line 409.</tt></li> <li> <tt>09.25.2002 add Debug Bin option.</tt></li> <li> <tt>09.26.2002 upgrade to xpa 2.1.3</tt></li> <li> <tt>09.26.2002 upgrade to wcssubs 3.1.3</tt></li> <li> <tt>09.26.2002 upgrade to filter 1.2b1</tt></li> <li> <tt>09.26.2002 upgrade to fitsy 1.2b1</tt></li> <li> <tt>10.01.2002 Web Display: more robust URL parseing</tt></li> <li> <tt>10.01.2002 Web Display: add 'Save to Fits File' option</tt></li> <li> <tt>10.01.2002 fixed 'xpaget ds9 bin cols' to return only 2 cols if bin depth is 1.</tt></li> <li> <tt>10.07.2002 Web Display: add support for new window with button click.</tt></li> <li> <tt>10.08.2002 Change in saotk Makefiles to correct a problem with Bison and Flex.</tt></li> <li> <tt>10.08.2002 Analysis Text now updates as text arrives.</tt></li> <li> <tt>10.08.2002 add xpa/command line support for MatchFrames.</tt></li> <li> <tt>10.08.2002 don't write WCS for Save Fits Resample and DSS fits.</tt></li> <li> <tt>10.10.2002 Web Display: hidden fields are not totally encoded if url is present.</tt></li> <li> <tt>10.17.2002 Fixed a problem with default fonts. Add the option of 'Default', which will not set any font options, if selected. This allows the native system to choose the best font/size combo.</tt></li> <li> <tt>10.18.2002 Add ProcessFrameCmd.</tt></li> <li> <tt>10.18.2002 Add system wide preference file support.</tt></li> <li> <tt>10.18.2002 Add Default mode. It just updates the infobox and graphs, with no regions.</tt></li> <li> <tt>10.21.2002 Fixed a problem with old prefs files and marker(system).</tt></li> <li> <tt>10.22.2002 Fixed a problem with MINMAX Sample. Sample intervals are now equal in row and columns.</tt></li> <li> <tt>10.25.2002 Fixed a problem with vo and errors that occur when connecting to the vo server.</tt></li> <li> <tt>10.25.2002 Add Match Colorbars and Match Scales xpa/command line options.</tt></li> <li> <tt>10.25.2002 Changed Analysis plot error reporting to include first line of received data.</tt></li> <li> <tt>10.25.2002 Fixed a problem with DSS and editing the dialog with another image loaded.</tt></li> <li> <tt>10.27.2002 Add filename to ds9/funtools regions file header.</tt></li> <li> <tt>10.29.2002 Add Lock Crosshairs xpa/command line options.</tt></li> <li> <tt>10.31.2002 ds9 version 2.2 released to public.</tt></li> <h4> <b>Version 2.2b2</b></h4> </ol> <ol> <li> <tt>07.31.2002 fixed a problem with hv and urls of the form foo.com/foo/bar.html#foo. Now, the html is not reloaded before the goto is executed.</tt></li> <li> <tt>08.01.2002 add adjust text size support to web browser</tt></li> <li> <tt>08.01.2002 add boxcar and tophat smooth support for binning.</tt></li> <li> <tt>08.05.2002 add -vo commandline and xpa support</tt></li> <li> <tt>08.05.2002 fixed a problem for the windows port where windows has been configured to open a fits file with ds9. In this case, the file path name passed to ds9 is actually in 'dos' format. So we used a cygwin function to convert to a posix format. This only occurs in a command line file name option.</tt></li> <li> <tt>08.06.2002 fixed a problem with smooth and depth&gt;1.</tt></li> <li> <tt>08.06.2002 fixed a problem with save fits resample.</tt></li> <li> <tt>08.07.2002 the user can now display the horz and vert graphs, even in tile or blink mode</tt></li> <li> <tt>08.07.2002 ds9 will operate in single mode, even if in tile or blink mode, if there is just one frame.</tt></li> <li> <tt>08.08.2002 add Gaussian smooth support for binning.</tt></li> <li> <tt>08.08.2002 fixed a problem with the plot tool and displaying discrete x y e1 y2 data. The correct colors are now used.</tt></li> <li> <tt>08.08.2002 the plot tool will now always update the plot title, x axis label, and y axis label when receiving new data.</tt></li> <li> <tt>08.08.2002 add xpaset -p ds9 analysis plot close support.</tt></li> <li> <tt>08.08.2002 add Know Issues Documentation</tt></li> <li> <tt>08.12.2002 add http proxy support.</tt></li> <li> <tt>08.12.2002 fixed a problem with the close box for the bin dialog box.</tt></li> <li> <tt>08.20.2002 add support for default fonts to preferences.</tt></li> <li> <tt>08.23.2002 remove timeouts for all http requests with optional cancel support.</tt></li> <li> <tt>08.23.2002 fixed a number of items with web display.</tt></li> <li> <tt>08.26.2002 reformat all documentation to remove references to Helvetica</tt></li> <li> <tt>08.26.2002 bring grid WIDGETBB in by one so that the border can be seen and printed.</tt></li> <li> <tt>08.26.2002 fixed a problem with web gifs under windows. The output channel needed an -translation binary flag.</tt></li> <li> <tt>08.26.2002 adjust font sizes for web display to more closely follow those of Netscape and IE.</tt></li> <li> <tt>08.27.2002 add 'Save as Fits', 'Save as Image', and 'Page Setup' buttons.</tt></li> <li> <tt>08.27.2002 add 'First' and 'NVSS' archive server menu items.</tt></li> <li> <tt>08.28.2002 add auto coordinate feed to HV for archive servers.</tt></li> <li> <tt>08.30.2002 ds9 version 2.2b2 released to public.</tt></li> </ol> <h4> <b>Version 2.2b1</b></h4> <ol> <li> <tt>04.05.2002 fixed a problem with xpa contour load.</tt></li> <li> <tt>04.05.2002 improved parsing of analysis menu file. In particular, keywords like 'help', 'param', and 'end' can be used more freely.</tt></li> <li> <tt>04.10.2002 add tag suppport for regions.</tt></li> <li> <tt>04.11.2002 add background marker stack. The default stack is in the foreground.</tt></li> <li> <tt>04.11.2002 fixed checks for can Edit, can Move, can Rotate, and can Delete properties thru out marker code.</tt></li> <li> <tt>04.11.2002 add HIGHLITE marker property.</tt></li> <li> <tt>04.12.2002 add $null macro to analysis support.</tt></li> <li> <tt>04.17.2002 fitsy++ now builds an keyword index to search for keywords. Previously, it would search sequentially.</tt></li> <li> <tt>04.18.2002 add a fix to ps level 2 driver to prevent a '\n%' in the image data. Seems the perl script 'assemble' does a global search/replace that results in corrupted image data. This fix includes a redesign of a previous fix that worked around an issue with old versions of dvips that will incorrectly process'\n%%'.</tt></li> <li> <tt>04.18.2002 upgrade to WCS 3.1.0</tt></li> <li> <tt>04.24.2002 start to add support for multiple wcs's.</tt></li> <li> <tt>04.25.2002 add support for multiple wcs's in infobox.</tt></li> <li> <tt>04.26.2002 improve tag support for regions. All functionality of selected regions are now available for tagged regions.</tt></li> <li> <tt>04.30.2002 add marker command var command to support regions files in tcl vars.</tt></li> <li> <tt>05.08.2002 recalc polygon center when adding or deleteing vertex.</tt></li> <li> <tt>05.13.2002 complete implementation of multiple wcs support. ds9 now supports a total of 31 coordinate systems. Furthermore, of the 27 WCS coordinate systems, both sky coordinates and linear coordinates are fully supported.</tt></li> <li> <tt>05.13.2002 complete re-implemenation of map() functions. Now all map functions are in the fits case, and only map between REF and IMAGE/PHYSICAL/AMPLIFIER/DETECTOR/WCS/WCSA... coordinate systems. This cleans up alot of code and confusion.</tt></li> <li> <tt>05.14.2002 add support for TCROT and CDn_1 WCS keywords in FITS bin tables.</tt></li> <li> <tt>05.16.2002 dramatically speed up parsing wcs keywords by substituting the fitsy++ index based keyword search routine for Doug Mink's 'ksearch' routine. With multiple wcs's in a large mosaic this can save up to a minute at load time.</tt></li> <li> <tt>05.16.2002 fixed a minor problem with xpa dss. http has a error, that carries over and is caught by xpa.</tt></li> <li> <tt>05.16.2002 analysis $text windows will not appear if there is no output, or just an &lt;cr&gt;.</tt></li> <li> <tt>05.16.2002 fixed display header to correctly display 80 chars, not 79.</tt></li> <li> <tt>05.16.2002 fixed a problem with iis and very long file names. names up to 256 chars are now allowed.</tt></li> <li> <tt>005.20.2002 AMPLIFER and DETECTOR coordinate menu entries are now an option, to be enabled via the Preferences:Misc menu option. Changes will take affect at startup.</tt></li> <li> <tt>05.23.2002 add support for 3D binning of fits bin tables.</tt></li> <li> <tt>05.24.2002 made changes to grid.C to handle the special LONG/NPOL skyframe coordinate system used by Chandra.</tt></li> <li> <tt>05.24.2002 add -xpa and xpa prefs to allow a user to enable or disable initialization of XPA at startup</tt></li> <li> <tt>05.28.2002 add -xpa [inet|local|unix|localhost] xpa point.</tt></li> <li> <tt>05.29.2002 correct 3D binning to properly reflect filter params in the filename.</tt></li> <li> <tt>06.03.2002 fixed a problem with Fits Bin Tables, odd length rows and referencing shorts.</tt></li> <li> <tt>06.04.2002 add support for multiple wcs with skyframe panner compass, along with prefs.</tt></li> <li> <tt>06.04.2002 add -xpa noxpans support.</tt></li> <li> <tt>06.04.2002 match frames wcs now uses the wcs system and wcs skyframe specified in align to wcs.</tt></li> <li> <tt>06.05.2002 upgrade to xpa 2.1.1</tt></li> <li> <tt>06.06.2002 add wcs master menu and buttons</tt></li> <li> <tt>06.06.2002 sync xpa wcs and command line wcs command.</tt></li> <li> <tt>06.10.2002 xpa wcs and commanline -wcs now uses same code to process</tt></li> <li> <tt>06.10.2002 xpa nameserver format now skyformat</tt></li> <li> <tt>06.10.2002 added support for variable args for xpa contour and -contour.</tt></li> <li> <tt>06.11.2002 add match frames physical, amplifier, detector. this does not handle rotation, nor orientation.</tt></li> <li> <tt>06.11.2002 the master wcs menu now modifies the Region:File Coordinate System menu also</tt></li> <li> <tt>06.11.2002 fixed a problem with list projection and linear wcs. the thickness parameter was not written correctly.</tt></li> <li> <tt>06.12.2002 fixed a problem with -tile and -region commandline options. The ds9 window must be realized before processing region files.</tt></li> <li> <tt>06.13.2002 fixed a problem with -pagesetup commandline option.</tt></li> <li> <tt>06.13.2002 fixed a problem with ds9parser.Y, prosparser.Y, and tngparser.Y when processing coordinates when no coordinate system has been specified.</tt></li> <li> <tt>06.13.2002 fixed a problem with -pan to command line option. The ds9 window needs to be realized (and the matrices defined) before processing.</tt></li> <li> <tt>06.13.2002 binning on a third column now invokes the data cube dialog box.</tt></li> <li> <tt>06.14.2002 add smaller buffer sizes to binning menus. We want to do this for those building large 3D binning movies.</tt></li> <li> <tt>06.19.2002 implemented new grid support. Grids now handle rotated images much better. Numerics are better positioned.</tt></li> <li> <tt>06.27.2002 updated to WCSSUBS 3.1.1. This corrects a number of TNX problems.</tt></li> <li> <tt>06.27.2002 add File:XPA info menu item.</tt></li> <li> <tt>06.27.2002 add XPA regions selected feature.</tt></li> <li> <tt>06.28.2002 Analysis $geturl macro calls are now logged.</tt></li> <li> <tt>07.01.2002 add support for limited web browser</tt></li> <li> <tt>07.01.2002 help reference manual now uses built-in brower, and is static.</tt></li> <li> <tt>07.02.2002 fixed a problem with cross-platform displays and 16 bit truecolor.</tt></li> <li> <tt>07.08.2002 fixed a problem with regions and changes in the bin factor of fits bin tables.</tt></li> <li> <tt>07.08.2002 add $xpa_method analysis macro.</tt></li> <li> <tt>07.08.2002 add @@xpa_method@@ support in hv.html</tt></li> <li> <tt>07.22.2002 fix numerous problems with internal web browser.</tt></li> <li> <tt>07.23.2002 add async support for internal web browser.</tt></li> <li> <tt>07.24.2002 changed Makefiles so that parser.C, parser.C.h, and lex.C are now archived. Therefor, builds no longer need bison and flex, unless changes have been made to the parser.Y. This gets around problems with different versions of bison.</tt></li> <li> <tt>07.25.2002 add support for the Compass region.</tt></li> <li> <tt>07.25.2002 add vo proxy and internal hv support.</tt></li> </ol> </ol> </body> </html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/release/r2.0.html����������������������������������������������������������������������0000644�0001750�0001750�00000001766�10415010756�014650� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]"> <title>DS9 Version 2.0 Release Notes</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="../sun.gif" align="middle" height="98" width="100">Version 2.0 Release Notes</h3> <ol> <h4> <b>Version 2.0</b></h4> <ol> <li> <tt>changed xpa tcl received to remove eval statement</tt></li> </ol> <ol> <li> <tt>fixed a problem clearing the magnifier in the windows version</tt></li> <li> <tt>implemented a work around for a bug in dvips version 5.55 and level 2 postscript driver</tt></li> <li> <tt>filename with a space in them will now load correctly</tt></li> <li> <tt>fixed a problem with FITS Regions Files and optional columns</tt></li> </ol> </ol> </body> </html> ����������./saods9/doc/sun.gif��������������������������������������������������������������������������������0000644�0001750�0001750�00000007042�10414777120�013152� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89ad�b�÷��� Ï�¡Ç�¡Ì�¡Þ�¢È�£Ê�£Õ�¤É�¥Ï�¦Ê�¦Ì¦Ê¦Ë¥Ê§È§Ê¦Í¥Â¦É§É¨Ë ¨Å ©Ï©À«Í«·®Ð#±Ñ(®ª3·Ó;³œJÀÙP·‰h¼voÍâÁc“ÆSœÝì£ÉF´Í8ÄëôÇÑ(ÔÔá×áõùêÙ ïÚðúýòÚõÛöÛöÛöÜ÷Û�÷Û÷ýþøÛ�øÜúÜ�ûþþþÿÿÿÞ�ÿß�ÿÿÿ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!ù��?�,����d�b��þ�H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ#Â,P (A²d ‘,nx\9q‹":h p€@€�8@€@ >ˆ(Á‚Ë£_ ±áÁMHM   S¥ÖäI¡ƒ*‘®ä±TƒÍ¨Y³"à ¢Ö´SmfÊBìÆ%:D�À€¸Y €èÁá-à.¤¡à »wä ‘b…Š!*8œÀÀ 6sî‡ :<†E‡�<pᣇDÃEpÂÇ݇ xÐá#„žŽY7dñ¡§TØö¨Ñ#GèÝVø8aøðZ=Vþ\À@‚ˆÊ–À�®-tP‡‘;í{áÇ®ÿu©l°Zz½ðlÁ0uÜÙBýq�œ{ Öàp4 ‚Q¢°A{œñ‡C ýÕ7•$L׃qœ%¶‚Š&L˜@� § ø4š‹òYÈâT¤ " 2J…€&,Ø‘€Xd%H€ÖŽÙõØÃo@fu)tw")Žèc‘ €Á€G•�À”T®`%“ÏyÐÈ:¬Aw ¼—‚b–HfX€¦G%D�ÂÉA VÆxâƒ5Ô€ƒ&v6ÁàEév^–‚²TÂP&á_!¦i)0€*’þ R÷£ìÙc¤áØ‘àÀ™¡@Sg'被.ÜIB®ê(¨À§¦Ô¹Pi`pa™<© f©¥)œºë ±Êºµ[âšbô†-‰=ü§–`Ö¦ Á[4†…Ñö`0Œ Á„ < B»=œ°™psjªC  PÚ½ÂÉmŠ=аm�"h$ˆS)À„èæf˜<Œ­3HèY»8ôàÁ/Þ[§³@ ¦qX¦E@ ¡Ð�`ïmYÝšI¥€ÑbÛCŒ°Þ[>püí‰$©b tZ€âNtC:ºW·¹ÜY’>Sj€ÌV›¢þÏ¿e@©C“˜Ã¶YÑhÑÉœ©Ìîª:pÁßßË*.Ü©*à-ífyfÀn¬_FÀ ±€›îQ~+q*€0@•sŒy ãC bFšsh B ËëÖht 0DˆFÚµ«.yi×÷Nʱî¹_ÞltìZî§ò3"݈ý->ª)¯ìóm!¨`ùôì¯Jv.¯©VÀ6>$‚�´‚0ÂÿÐ ù:£:Ž!LÕk_û0×›õQ§-‚‹.�ï9„èð|ÀÁð„�Ý)ôê¦ÀZL~³÷:Ó+ãé¯ZµÉ]Î臬”A`q&Ì¡;–¨ ±+þ\ÈÚl…i ÛÉ€nÞîð‰¸RÁãÄ'>/O7‹Á\RÊ„À�A± ¶ÞýÅ3#„¢ñãèø$2°€ñq@lâ±@Ú"‚ ‹Š èYóNàü US#—Ä€§6¶é Rp˜ 3˜ÓÕ € ~dV´y¹°j…, "wX'ÐÀˆØš”)g)6ç AêNä¬o†u:›V¹C4щìC"“€ü!$yLû ûŠˆLb&3 $Î Ê&•Ñ-¤9-º€æ¬IÎÑ”>˜Á¸  ’%äØe`zYÍrZ³ˆ6þXA (9uÅ— AÁ¸W*SÚó ÔñA L\`Gê\ g¤mÛhSO„šÓ+{ÊÑ<`)Ê”÷žbÕ¦£õ™:AÎxó™+eé{B LlÆtzkã�z7@åu2!àL\D à€ x &æOÍ9I†z †ü[IC²„°m7âc€SG`€Ç”0*¾fÙ‚Xu<U„KWòÕ¥Vå©—Œ-}ªVÊ’­) ÁáJÔÔ ;Ø€�&øT¤`ƒhåk_WÙZ®à$�Ü"€Ãäc 8É´N¶œø!mxLàÏ$±pþ*TS ×ÈžÖ£…P[{UÄ(ÀRÅŠW³ÎB’½m2‹X›¶¾u©ðíA¾Z>ñ9€þ; bIX*Wv蔤 ¬ŠÕ¸ÎI*`T&¾ `w„ ¾Ë1çÊ1¨bQÏËÇœ*µŠ!`}u'ƒÅHh�[5ª' Íæ ¿3mLsfÊ€�„+,é¢RÿM °Õ€j<n… ذ@t¹+*" ÁÃP8âè¡ hœ¡¨E ò‚Óe%O L Ì"&·Æ›ÚfM»Ù…P1~$ъ䆮IèÅ©‘&`‚S¹ýá«Dö§£-:B@þ—KÌ÷´u•%G¶€(-HIŵåVØÌ™N¯¾²j¬)ÈÖG?‰¦%5 )˜(܂̭@Ý oëövÚœ…`¨k!xdx5ÍXñHˆ@–Õ�ø2bs¬€.€]œ`Ÿ'@¥`¼;YfI¨3ïIÒ­r¦‚d ð€ @ b=[`0WBõÔ@¨Õ©‰/¤¼mÄJ ¹L5Ï*ÐN \«p-FKžÚsº<`$þ(NÚ‘ají´à€zÀº"è`|Jc5JOvøŽž2½èd ¢ùÀ–¬q¶ër·)´¿a�<n{€€€lnk ��«Îeþ2Œ¢4â*ý”8'eIƒÆ²8 ÓêR™™çof48ƒÑ^Ë §òõß3³Ag±üÚ¨!oˆÒ”—ÍåLˆBcí ƒØIո³ß¬P´æ i°{¼e±–I4HÇœÊ{Ð:_ú,6 ä¢u·¢D•"ä’' û#)„ †:®F‚õEl�d—‹ Ð-üàªo¢ëÀ,ÒáÝT@fÚôgg8}DÑ [¾y]¶©'^YK>¦)Ò&Ðì‡Ì>ÞÊ™ >(pU®J7‹e¾þ&ͼ ¼$È&õ5•¹^„È(LyͯûáîÀ¾-ƒÂÀËr›L ¯öþ–CI“’‘*°§ÐÞm4æoÅv œñó¸ªß‰.5ƒÔÇ%\Áès¼e%îW8Vw{w¢� 9Ùת²*ï¦}±'×qg­G'#4¡Aï‘mÄ‘Jô|«R4ßÑ#Û"0+PPoq2 E& �-Ó8'ö½—3&òbx“ G€‚Á'³d»&&H„Ž'Ã,8†vò’ƒ'bfb!vÁiHdQ£}°#¬â*@‚CÓCZq‚¬!P±+Us5&A.HŽr"Ÿ·mÜC�àƒ+Qps -l7<ÁA7u½ÇvÐuÅ' òþ’Sh·;‰RP4H"*@#`'/@†m£,ã}î!'è%h4"_Ø)rXàwˆ+ö!Ïm*à~;¢%¬Ò)P/sw%ƒ*•¨ª˜"`í-·Q„${"[2Ì@•¨¨Ø‹ Á"@­<G"Þ²€û℆+pÐÈÒhlŒâ×È4ŒÇà—8Ž!�P�ûáâÁp6�P;& ±KÑð¨C-&°_[A�ðñ( Á/P&7qà;‘‘°�àD!‘¡$!"ð*©’(y($ “29“4Y“�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/doc/new.html�������������������������������������������������������������������������������0000644�0001750�0001750�00000033015�12036064766�013343� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; SunOS 5.8 sun4u) [Netscape]"> <title>DS9 New Features</title> </head> <body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b"> <h3> <img alt="" src="sun.gif" align="middle" height="98" width="100"> SAOImage DS9 Version 7 New Features</h3> <blockquote> <p><b>Version 7.1<br> </b></p> <blockquote> <p><b>Catalog Matching</b><br> </p> <p> DS9 now supports catalog matching. From the Catalog menu option, the user selects two currently loaded catalogs, an error radius, and matching function. The user may request all sources that are present in both catalogs, or in one catalog and not in the other. Each catalog need not to be specified in the same world coordinate system.<br> </p> <p><b>Enhanced Plot Tool</b><br> </p> <p> In addition to a Line Plot Tool, DS9 now supports additional Bar and Scatter Plots Tools. The GUI for the Plot Tools have been enhanced and new features have been added including statistics and data lists. Each Plot Tool supports multiple data sets and custom plotting options.</p> <p><b>Catalog Scatter Plots</b><br> </p> <p>The user may now plot the results of two columns of a loaded catalog as a scatter plot. A selected region on the image will highlight the corresponding row and plot point. Likewise, a selected row or plot point will highlight the corresponding image region.<br> </p> <p><b>Interactive Region Analysis</b><br> </p> <p> DS9 regions now support interactive region analysis. The analysis tasks are enabled by selecting the Analysis Menu in a region's dialog box. Interactive analysis tasks includes statistics, data cuts in 2D and 3D, and radial profiles.<br> </p> <p><b>Other Enhancements</b><br> </p> <p>3D scaling along the z axis of data cubes<br> Lock/Match Smoothing option<br> WCS dialog support for non-linear projections such as TAN-SIP and SCAMP<br> Support for FITS files larger than 2Gb has been improved<br> </p> </blockquote> <p><b>Version 7.0<br> </b></p> <blockquote> <p><b>3-D Data Visualization</b><br> </p> <p> Previous versions of SAOImage DS9 would allow users to load 3-D data into traditional 2-D frames, and would allow users to step through successive z-dimension pixel slices of the data cube. To visualize 3-D data in DS9 v. 7.0, a new module, encompassed by the new <tt>Frame 3D</tt> option, allows users to load and view data cubes in multiple dimensions.</p> <p>The new module implements a simple ray-trace algorithm. For each pixel on the screen, a ray is projected back into the view volume, based on the current viewing parameters, returning a data value if the ray intersects the FITS data cube. To determine the value returned, there are 2 methods available, Maximum Intensity Projection (MIP) and Average Intensity Projection (AIP). MIP returns the maximum value encountered, AIP returns an average of all values encountered. At this point, normal DS9 operations are applied, such as scaling, clipping and applying a color map.<br> </p> <p>Rendering time is independent of the actual data cube size. Instead, the time it takes to render is based on how many rays are needed to project the data cube upon the screen in the view volume and the current zoom factor. The new module requires no special hardware or graphical processor unit (GPU) and the rendering time is adequate for interactive GUI manipulation on most computers. The rendering engine is developed using the POSIX thread library, allowing multiple light weight processes to be spawned to complete an image in parallel. The number of threads actually generated is a user specified parameter. Since all modern hardware contain multiple CPU cores, the default value is 8 threads. For larger work stations, this number can be increase. For every doubling in the number of CPU cores available, rendering times decrease approximately 75%.<br> </p> <p>The new module is support on all hardware platforms currently supported by DS9, including 32-bit and 64-bit versions of Linux and MacOSX, and 32-bit versions of Windows and Solaris.<br> </p> <p>All 2-D graphics, regions, cross hairs, contours, and coordinate grids, are applied to the current slice, which is selected by the user. When the user wishes to match or lock a 2-D image and to a 3-D data cube, the current slice is used to determine the rendering solution. The user can crop the data cube for all 3 axes via the command line or the GUI. The new module also supports FITS event files binned into a data cube.<br> </p> <p>All printing support has been extended to the new 3-D module. The user may generate 3-D images in Postscript, JPEG, TIFF, and other formats, just as in the 2-D case. Furthermore, native printing is supported for the Windows version.<br> </p> <p>DS9 analysis macros have been enhanced to fully support the new 3-D module, allowing the user to invoke external analysis tasks based on the current view parameters and to return results back into DS9 in the form of text, plot, 2-D image, or 3-D image.<br> </p> <p>Funding for 3-D data visualization was provided by the JWST Mission office at Space Telescope Science Institute (NAS-03127) </p> <p><b>Color Tags</b><br> </p> The purpose of color tags are to highlight (or hide) certain values of data, regardless of the color map selected. The user creates, edits, and deletes color tags via the GUI. To create a color tag, enter the Colorbar Mode, and click once on the colorbar. This creates a default color tag. Click and drag to change the values. Click and drag on one side to increase or decrease the value. Double click to manually edit the values and color. Place the cursor over the color tag and press the delete key to delete it. From the color parameters dialog, the user can load, save, and delete all color tags for that frame.<br> <p><b>Regions<br> </b></p> Regions now support analysis tasks unique to each region type. In the menu of the region dialog, the <tt>Analysis</tt> menu will contain any type specific analysis tasks. The <tt>Circle</tt>, <tt>Ellipse</tt>, <tt>Box</tt>, <tt>Polygon</tt>, and <tt>Point</tt> regions now support interactive 1-D cuts along the 3rd axis of 3-D data cubes. The <tt>Line</tt>, <tt>Vector</tt>, and <tt>Projection</tt> regions support 2-D cuts through the current slice of 2-D and 3-D data. The <tt>Auto Plot</tt> option under the regions preferences can be used to specify if a plot is automatically generated when the region is created.<br> <p><b>Analysis<br> </b></p> DS9 analysis macros have been enhanced to fully support the new 3-D module, allowing the user to invoke external analysis tasks on the current slice of 3-D data cube. The macro <tt>$z</tt> is now supported for 3-D data. In support of <tt>Funtools</tt>, the <tt>PLANE</tt> keyword is supported.<br> <p><b>Slice</b><br> </p> DS9 now allows the user to load a 3-D data cube one slice at a time via the GUI or from the command line. Use the option <tt>-slice </tt>to specify that all following 2-D files are to be interpreted as a slice of a 3-D data cube.<br> <p><b>Photo</b><br> </p> DS9 can now load images in TIFF, JPEG, and PNG file format directly. When loaded into a <tt>Frame</tt>, the average of the luminosity is used. When loaded into a <tt>Frame RGB</tt>, each channel is loaded directly. Use the <tt>-photo</tt> command line option to specify that all following files are to be interpreted as a photo image.<br> <p><b>Export</b><br> </p> DS9 will export the current image in TIFF, JPEG, or PNG file format with the current colorbar parameters applied. The entire image is exported (not just the visible portion) at the native resolution.<br> <p><b>Lock/Match</b><br> </p> The support for the Lock/Match functionality of DS9 has been greatly enhanced. The user may choose to lock/match frames, the cross hair, cropping, the current slice, binning parameters, scale parameters, or color map parameters.<br> <p><b>Crop<br> </b></p> DS9 now supports cropping the current image, via the GUI, command line, or XPA/SAMP in both 2-D and 3-D. The user may specify a rectangular region of the image data as a center and width/height in any coordinate system via the Crop Dialog, or can interactively select the region of the image to display by clicking and dragging while in Crop Mode. For 3-D frames, the <i>shift-click</i> to change the front clip plane, and <i>control-click</i> to change the back clip plane. From the command line, cropping parameters can be specified in IRAF format.<br> <p><b>ASINH Scale<br> </b></p> A new scale function has been added, <tt>ashinh</tt>, based on the arc sinh function. This new function has similar properties as the <tt>log</tt> function, with <tt>a=10</tt>.<br> <p><b>All new GUI<br> </b></p> <p>DS9 now supports basic GUI elements (buttons, menus, etc) via the native window manager API. Each port of DS9 will have a native look and feel of each hardware platform. DS9 will take advantage of the current user selected <i>Theme </i>if supported by the native windowing system.<br> </p> <p><b>Postscript</b><b><br> </b></p> DS9 now generates identical postscript code for a particular image, regardless of which hardware platform was used to generate the image.<br> <p><b>Catalogs</b><b><br> </b></p> The user may now specify coordinates in any equatorial system (not just FK5) for a catalog search and receive results in any equatorial system, to be plotted or saved. Local catalogs in any equatorial system are now supported.<br> <p><b>New WCS support</b><br> </p> <p>New WCS support for non-FITS WCS projections have been added to DS9: TNX, ZPX, SCAMP, SIP and HEALPIX.&nbsp; The keyword WCSDEP is now supported.<br> </p> <p>Enhancements and improvements have been made in the support for the following FITS WCS projections: COD, COO, COE, COP, ZEA, and CAR.<br> </p> <p>DS9 now supports non-equatorial long/lat coordinate systems in the form of xLON/xLAT and xyLN/xyLT. This includes solar WCS HPLN/HPLT, HGLN/HGLT, and HRLN/HRLT systems.<br> </p> <p>DS9 now fully supports multiple alternative celestial WCS, if specified. All cut/paste/copy operations, catalog, image server, contour, regions, and coordinate grids will now use the default WCS as selected by the user, via the WCS menu item.<br> </p> <p><b>HEALPIX</b><br> </p> <p>DS9 now supports native HEALPIX maps, in both FITS binary table and ascii table form. Any table with keyword PIXTYPE=HEALPIX or NSIDE=x will be processed as an HEALPIX image. The user may specify HEALPIX parameters within the file specification to indicate RING (default) or NESTED order, Coordinate System (default is Unknown),&nbsp; Quadrant (default is first), and Equator (default), North, or South layout. The appropriate WCS is generated for the image.<br> </p> <p><b>External Analysis</b><b> Files<br> </b></p> DS9 will now look for external analysis files in the following locations at start up: the current directory, <tt>$HOME/bin, /usr/local/bin</tt>, <tt>/opt/local/bin,</tt> and <tt>/soft/saord/bin</tt> in the form of <tt>*.ds9</tt>. If found, they will be automatically loaded. Users may disable this feature via the presences analysis panel. DS9 will continue to load <tt>ds9.ans</tt> and <tt>ds9.analysis</tt> if found, and users specified analysis files as before. DS9 will verify that the same analysis file is not loaded twice to avoid duplication of analysis menus. </blockquote> <p><b> For more detailed information, Please see <a href="release/r7.0.html">Release Notes</a></b></p> </blockquote> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/��������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201303�012672� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/gpl.txt�������������������������������������������������������������������������0000644�0001750�0001750�00000043131�11131474217�014234� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/xmlrpc.tcl����������������������������������������������������������������������0000644�0001750�0001750�00000051737�11251552127�014735� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# xmlrpc0.3 # Written by Eric Yeh # # Server API: # xmlrpc::serve # Note: all callable functions should be defined in the global scope # # Client API: # xmlrpc::call url methodName params # url is of the form "http://hostname:port" # methodName is the name of the method to call # and params is a list of arguments to the method # where each argument is a "typed tcl" value defined below # xmlrpc::buildRequest # return an XML-RPC client request # xmlrpc::marshall # return a marshalled "typed tcl" value # xmlrpc::unmarshall # return an unmarshalled "typed tcl" value # xmlrpc::assoc # return a cons of a list if the key matches # # Typed Tcl values: # Because Tcl has no types for variables, all values will be represented # as a 2 element tuple of the form: # {type, value} where value is the original value # and type is a string describing its type. # Valid types (case sensitive, must be lowercase): # int # boolean # string # double # dateTime.iso8601 # base64 # struct # array # Note: # When marshalling dictionaries(tcl arrays), tcl has no # way of creating unnamed dictionaries. Therefore, # the way to use a dictionary is to create it as normal, # and refer to its name in the "tcl type". # For example: # set dict(first) {string eric} # xmlrpc::marshall {struct dict} # # the marshall procedure will attempt to "find" dict # using upvar(yuck!) and checking the global scope. # # Unmarshalling of a dictionary results in a 2 element # list of the form (remaining, alist) # where remaining is unused marshalled data (should be empty) # and alist is an A-list. # An A-list has the form: # {key, datum} where key is the key and datum is its value. # The method "assoc" is provided to access information from # this data structure. It behaves like the LISP assoc, in that # it will return the (key, datum) pair if a match is found. # TODO: # -currently server functions can't return dictionaries # -add more error handling # -Check for [{}] in unmarshalling # -Empty dictionaries package provide xmlrpc 0.3 namespace eval xmlrpc { namespace export call buildRequest marshall unmarshall assoc namespace export serve variable READSIZE 4096; # read size variable WS "\[ |\n|\t\|\r]"; # WhiteSpace variable W "\[^ |\n|\t\]"; # a word with no spaces variable DIGIT "\[0-9\]"; # Digit variable response ""; # response to return variable acceptfd ""; # socket to listen on variable DEBUG 0; # debug } # Given a port, create a new socket # and start listening on it # proc xmlrpc::serve {port} { variable acceptfd set acceptfd [socket -server xmlrpc::serveOnce $port] return $acceptfd } # Accept a new connection # proc xmlrpc::serveOnce {sock addr port} { variable READSIZE debug "in serveOnce: addr: $addr" debug "in serveOnce: port: $port" fconfigure $sock -translation {lf lf} -buffersize $READSIZE fconfigure $sock -blocking off fileevent $sock readable [list xmlrpc::doRequest $sock] } # Given a socket, # Handle an XML-RPC request # proc xmlrpc::doRequest {sock} { variable WS set res [readHeader $sock] set headerStatus [lindex $res 0]; # Header + Status set body [lindex $res 1]; # Body, if any set RE "\[^\n\]+\n(.*)" if {![regexp $RE $headerStatus {} header]} { return [errReturn "Malformed Request"] } set body [getBody $sock $header $body] set RE "<\?xml.version=."; # xml version append RE "\[^\?\]+.\?>$WS*"; # version number append RE "<methodCall>$WS*"; # methodCall tag append RE "<methodName>"; # methodName tag append RE "(\[a-zA-Z0-9_:\/\\.\]+)"; # method Name append RE "</methodName>$WS*"; # end methodName tag append RE "(.*)"; # parameters, if any append RE "</methodCall>.*"; # end methodCall tag if {![regexp $RE $body {} mname params]} { return [errReturn "Malformed methodCall"] } set args {} set param [string range $params 8 end] set param [string trim $param] while {[string range $param 0 6] == "<param>"} { set param [string range $param 7 end] set param [string trim $param] set res [unmarshall $param] set param [lindex $res 0] set el [lindex $res 1] lappend args $el if {[string range $param 0 7] != "</param>"} { return [errReturn "Invalid End Param"] } set param [string range $param 8 end] set param [string trim $param] } if {$param != "</params>"} { return [errReturn "Invalid End Params"] } if {[catch {set result [eval ::$mname $args]}]} { set response [buildFault 100 "eval() failed"] } else { set response [buildResponse $result] } debug "in doRequest: response:\n$response" puts -nonewline $sock $response flush $sock catch {close $sock} } # Given a "typed tcl" value, # build an XML-RPC response # proc buildResponse {result} { # build the body set body "<?xml version=\"1.0\"?>\n" append body "<methodResponse>\n" append body "\t<params>\n" append body "\t\t<param>\n" append body [xmlrpc::marshall $result 3 2] append body "\n\t\t</param>\n" append body "\t</params>\n" append body "</methodResponse>\n" set lenbod [string length $body] # build the header set header "HTTP/1.1 200 OK\n" append header "Content-Type: text/xml\n" append header "Content-length: $lenbod\n" set response "$header\n$body" return $response #return [string trim $response] } # Given an error code (integer) # and an errmsg (string) # build an XML-RPC fault # proc buildFault {errcode errmsg} { set err(faultCode) [list int $errcode] set err(faultString) [list string $errmsg] # build the body set body "<?xml version=\"1.0\"?>\n" append body "<methodResponse>\n" append body "\t<fault>\n" append body [xmlrpc::marshall {struct err} 2] append body "\t</fault>\n" append body "</methodResponse>\n" set lenbod [string length $body] # build the header set header "HTTP/1.1 200 OK\n" append header "Content-Type: text/xml\n" append header "Content-length: $lenbod\n" set response "$header\n$body" return [string trim $response] } # send an XML-RPC request # proc xmlrpc::call {url method methodName params {ntabs 4} {distance 3}} { variable READSIZE variable response global readdone global xmlcall set readdone 0 set xmlcall 1 set RE {http://([^:]+):([0-9]+)} if {![regexp $RE $url {} host port]} { return [errReturn "Malformed URL"] } set sock [socket $host $port] fconfigure $sock -translation {lf lf} -buffersize $READSIZE fconfigure $sock -blocking off if {[catch {set request [buildRequest $method $methodName $params $ntabs $distance]}]} { return } puts -nonewline $sock $request flush $sock fileevent $sock readable [list xmlrpc::getResponse $sock] vwait readdone catch {close $sock} if {$readdone > 0} { return $response } else { return [errReturn "xmlrpc::call failed"] } } # Given a socket to read on, # get and parse the response from the server # proc xmlrpc::getResponse {sock} { variable response global readdone set res [readHeader $sock] set headerStatus [lindex $res 0]; # Header + Status set body [lindex $res 1]; # Body, if any set header [parseHTTPCode $headerStatus] set body [getBody $sock $header $body] set response [parseResponse $body] set readdone 1 } # Given a socket to read on, # a string of header information # and a string, body, # return a string representing the entire body # proc xmlrpc::getBody {sock header body} { set res [parseHTTPHeaders $header] set headersl [lindex $res 1]; # A-list of headers set expLenl [assoc "Content-Length" $headersl] if {$expLenl == {}} { set expLenl [assoc "Content-length" $headersl] if {$expLenl == {}} { return [errReturn "No Content-length found"] } } set expLen [lindex $expLenl 1] set body [readBody $body $expLen $sock] return $body } # Given a socket to read on, # Return a 2 element list of the form: # {header, body} where both are strings # Note: header will include the first line which is the status # proc xmlrpc::readHeader {sock} { set buffer "" while {1} { if {[catch {set buff [nbRead $sock]}]} { return [errReturn "Premature eof"] } append buffer $buff set nindex [string first "\n\n" $buffer] if {$nindex > 0} { break } set bindex [string first "\r\n\r\n" $buffer] if {$bindex > 0} { break } } if {$nindex > 0} { set header [string range $buffer 0 [expr $nindex - 1]] set body [string range $buffer [expr $nindex + 2] end] } elseif {$bindex > 0} { set header [string range $buffer 0 [expr $bindex - 1]] set body [string range $buffer [expr $bindex + 4] end] } return [list $header $body] } # Given the body buffer, # the number of bytes expected in the body (Content-Length) # and a socket to read on, # return the entire body buffer # proc xmlrpc::readBody {body expLen sock} { set newbody $body while {1} { if {[catch {set buff [nbRead $sock]}]} { return [errReturn "Premature eof"] } append newbody $buff set bodLen [string length $newbody] if {$bodLen == $expLen} { break } elseif {$bodLen > $expLen} { return [errReturn "Content-length:$expLen does not match Body Length:$bodLen"] } } return $newbody } # Given a string, str, # check the HTTP status # and return the unused portion of str # proc xmlrpc::parseHTTPCode {str} { variable DIGIT set RE "HTTP/"; # HTTP message append RE "($DIGIT+\\.*$DIGIT*)."; # version append RE "($DIGIT+)."; # status code append RE "(\[^\n\]+)\n(.*)"; # status message if {![regexp $RE $str {} vern status code rest]} { return [errReturn "Unrecognized HTTP code:\n$str"] } if {$status != "200"} { return [errReturn "Bad HTTP status: $status"] } return $rest } # Given a string, str, # return a 2 element list of the form: # {remaining, alist} # where remaining is the unused portion of str # and alist is an A-list of header information # proc xmlrpc::parseHTTPHeaders {str} { set headers {} set remain {} set remainp 0 set RE {([^:]+):(.*)} set parts [split $str "\n"] foreach {part} $parts { if {$part == "" && !$remainp} { set remainp 1 continue } if {$remainp} { lappend remain $part continue } if {![regexp $RE $part {} key value]} { return [errReturn "Unrecognized HTTP Header format: $part"] } set value [string trim $value] lappend headers [list $key $value] } set rest [join $remain "\n"] return [list $rest $headers] } # Given a string, str # parse the response from the server # returning the unmarshalled data # proc xmlrpc::parseResponse {str} { variable WS set RE "<\?xml.version=."; # xml version append RE "(\[^\?\]+).\?>$WS*"; # version number append RE "<methodResponse>$WS*"; # method response tag append RE "<params>$WS*"; # params tag append RE "<param>$WS*"; # param tag append RE "(<value>.*)"; # value append RE "</param>$WS*"; # end param tag append RE "</params>$WS*"; # end params tag append RE "</methodResponse>"; # end method response tag if {![regexp $RE $str {} vern value]} { set RE "<\?xml.version=."; # xml version append RE "(\[^\?\]+).\?>$WS*"; # version number append RE "<methodResponse>$WS*"; # method response tag append RE "<fault>$WS*"; # fault tag append RE "(.*)$WS*"; # fault values append RE "</fault>$WS*"; # end fault tag append RE "</methodResponse>"; # end method response tag if {![regexp $RE $str {} vern value]} { return [errReturn "Unrecognized response from server"] } } set result [unmarshall $value] return $result } # Given a non-blocking file descriptor, fd # do a read # proc xmlrpc::nbRead {fd} { variable READSIZE fileevent $fd readable "" set buffer "" while {1} { if {[eof $fd]} { catch {close $fd} break } set temp [read $fd $READSIZE] if {$temp == ""} { break } append buffer $temp } return $buffer } # Given a methodName, # and a list of parameters, # return an XML-RPC request # proc xmlrpc::buildRequest {method methodName params {ntabs 4} {distance 2}} { # build the body set body "<?xml version=\"1.0\"?>\n" append body "<methodCall>\n" append body "\t<methodName>$methodName</methodName>\n" if {$params != {}} { append body "\t\t<params>\n" foreach {param} $params { append body "\t\t\t<param>\n" append body [xmlrpc::marshall $param $ntabs $distance] append body "\n\t\t\t</param>\n" } append body "\t\t</params>\n" } append body "</methodCall>\n" set body [regsub -all "\n" $body "\r\n"] set lenbod [string length $body] # build the header set header "POST /$method HTTP/1.0\n" append header "Content-Type: text/xml\n" append header "Content-length: $lenbod\n" set header [regsub -all "\n" $header "\r\n"] set request "$header\r\n$body" return $request } # Given a "typed tcl" value # return the marshalled representation # proc xmlrpc::marshall {param {ntabs 0} {distance 1}} { if {![validParam $param]} { return [errReturn "Malformed Parameter: $param"] } set strtabs "" for {set x 0} {$x < $ntabs} {incr x} { append strtabs "\t" } set type [lindex $param 0] set val [lindex $param 1] if {$type == "int"} { return "$strtabs<value><int>$val</int></value>" } elseif {$type == "i4"} { return "$strtabs<value><i4>$val</i4></value>" } elseif {$type == "boolean"} { return "$strtabs<value><boolean>$val</boolean></value>" } elseif {$type == "string"} { return "$strtabs<value><string>$val</string></value>" } elseif {$type == "double"} { return "$strtabs<value><double>$val</double></value>" } elseif {$type == "dateTime.iso8601"} { return "$strtabs<value><dateTime.iso8601>$val</dateTime.iso8601></value>" } elseif {$type == "base64"} { return "$strtabs<value><base64>$val</base64></value>" } elseif {$type == "struct"} { # get the original caller's scope upvar $distance $val dict # try the global scope if {![array exists dict]} { upvar #0 $val dict } set str "$strtabs<value>\n" append str "$strtabs\t<struct>\n" foreach {k v} [array get dict] { append str "$strtabs\t\t<member>\n" append str "$strtabs\t\t\t<name>$k</name>\n" append str [marshall $v [expr $ntabs + 3] [expr $distance + 1]] append str "\n$strtabs\t\t</member>\n" } append str "$strtabs\t</struct>\n" append str "$strtabs</value>\n" return $str } elseif {$type == "array"} { set str "$strtabs<value>\n" append str "$strtabs\t<array>\n" append str "$strtabs\t\t<data>\n" foreach el $val { append str [marshall $el [expr $ntabs + 3] [expr $distance + 1]] append str "\n" } append str "$strtabs\t\t</data>\n" append str "$strtabs\t</array>\n" append str "$strtabs</value>\n" return $str } else { return [errReturn "Unknown type: $type"] } } # Given a value param, # return 1 if it a valid parameter # return 0 if not # A valid parameter is a 2 element tuple # proc xmlrpc::validParam {param} { if {[llength $param] != 2} { return 0 } return 1 } # Given a marshalled value, # unmarshall it and return it # proc xmlrpc::unmarshall {str} { set str [string trim $str] if {[string range $str 0 6] != "<value>"} { return [errReturn "Bad value tag"] } set str [string range $str 7 end] set str [string trimleft $str] set RE {<([^>]+)>} if {![regexp $RE $str {} btag]} { return [errReturn "No beginning tag found: $str"] } if {$btag == "int" || $btag == "i4"} { set res [umInt $str] } elseif {$btag== "boolean"} { set res [umBool $str] } elseif {$btag == "string"} { set res [umString $str] } elseif {$btag == "double"} { set res [umDouble $str] } elseif {$btag == "dateTime.iso8601"} { set res [umDateTime $str] } elseif {$btag == "base64"} { set res [umBase64 $str] } elseif {$btag == "array"} { set res [umArray $str] } elseif {$btag == "struct"} { set res [umStruct $str] } else { # return [errReturn "Unknown type: $str"] # assume string set id [string first "<" $str ] if {$id != -1} { set vv [string range $str 0 [expr $id-1]] set rr [string range $str $id end] set str "<string>${vv}</string>${rr}" set res [umString $str] } else { return [errReturn "Unknown type: $str"] } } set rest [lindex $res 0] set val [lindex $res 1] if {[string range $rest 0 7] != "</value>"} { return [errReturn "Invalid close of value tag"] } set rest [string range $rest 8 end] set rest [string trim $rest] return [list $rest $val] } proc xmlrpc::umInt {str} { variable WS variable DIGIT set RE "<(int|i4)>$WS*"; # int tag append RE "(-*)($DIGIT+)$WS*"; # int value append RE "</(int|i4)>$WS*"; # end int tag append RE "(.*)"; # leftover if {![regexp $RE $str {} tag negp digits engtag rest]} { return [errReturn "Invalid Integer"] } if {$negp != ""} { set digits [expr -1 * $digits] } else { set digits [expr 1 * $digits] } set rest [string trim $rest] return [list $rest $digits] } proc xmlrpc::umBool {str} { variable WS set RE "<boolean>$WS*"; # boolean tag append RE "(0|1)$WS*"; # boolean value append RE "</boolean>$WS*"; # end boolean tag append RE "(.*)"; # leftover if {![regexp $RE $str {} bool rest]} { return [errReturn "Invalid Boolean"] } set rest [string trim $rest] return [list $rest $bool] } proc xmlrpc::umString {str} { variable WS set RE "<string>"; # string tag append RE "(\[^<\]*)"; # string value append RE "</string>$WS*"; # end string tag append RE "(.*)"; # leftover if {![regexp $RE $str {} s rest]} { return [errReturn "Invalid String"] } set rest [string trim $rest] return [list $rest $s] } proc xmlrpc::umDouble {str} { variable WS variable DIGIT set RE "<double>$WS*"; # double tag append RE "(-*)($DIGIT*\.?$DIGIT*)$WS*"; # double value append RE "</double>$WS*"; # end double tag append RE "(.*)"; # leftover if {![regexp $RE $str {} negp d rest]} { return [errReturn "Invalid Double"] } if {$negp != ""} { set d [expr -1 * $d] } else { set d [expr 1 * $d] } set rest [string trim $rest] return [list $rest $d] } proc xmlrpc::umDateTime {str} { variable WS variable DIGIT set RE "<dateTime\\.iso8601>$WS*"; # dateTime tag append RE "($DIGIT+T$DIGIT+:$DIGIT+:$DIGIT+)$WS*"; # dateTime value append RE "</dateTime\\.iso8601>$WS*"; # end string tag append RE "(.*)"; # leftover if {![regexp $RE $str {} dateTime rest]} { return [errReturn "Invalid DateTime"] } set rest [string trim $rest] return [list $rest $dateTime] } proc xmlrpc::umBase64 {str} { variable WS set RE "<base64>"; # string tag append RE "(\[^<\]*)"; # string value append RE "</base64>$WS*"; # end string tag append RE "(.*)"; # leftover if {![regexp $RE $str {} s rest]} { return [errReturn "Invalid Base64"] } set rest [string trim $rest] return [list $rest $s] } proc xmlrpc::umArray {str} { variable WS set RE "<array>$WS*"; # array tag append RE "<data>$WS*"; # data tag append RE "(.*)"; # leftover if {![regexp $RE $str {} rest]} { return [errReturn "Invalid Array"] } set l {} while {[string range $rest 0 6] == "<value>"} { set res [unmarshall $rest] set rest [lindex $res 0] set el [lindex $res 1] lappend l $el } set REAREND "</data>$WS*"; # end data tag append REAREND "</array>$WS*"; # end array tag append REAREND "(.*)"; # leftover if {![regexp $REAREND $rest {} leftover]} { return [errReturn "Invalid End Array"] } return [list $leftover $l] } proc xmlrpc::umStruct {str} { variable WS variable W if {[string range $str 0 7] != "<struct>"} { return [errReturn "Invalid Struct"] } set RE "<name>$WS*"; # name tag append RE "($W+?)$WS*"; # key append RE "</name>$WS*"; # end name tag append RE "(<value>.*)"; # value tag set l {} set str [string range $str 8 end] set str [string trim $str] while {[string range $str 0 7] == "<member>"} { set str [string range $str 8 end] set str [string trim $str] if {![regexp $RE $str {} key val]} { return [errReturn "Invalid Struct Member"] } set res [unmarshall $val] set str [lindex $res 0] set el [lindex $res 1] lappend l [list $key $el] if {[string range $str 0 8] != "</member>"} { return [errReturn "Invalid End Struct Member"] } set str [string range $str 9 end] set str [string trim $str] } if {[string range $str 0 8] != "</struct>"} { return [errReturn "Invalid End Struct"] } set str [string range $str 9 end] set str [string trim $str] return [list $str $l] } # Given a key, and a list of elements where each element is of the form: # {key, datum}, return {key, datum} if the requested key matches # a key in the list. # Returns the first match found in the list. # Return {} on failure # proc xmlrpc::assoc {key list} { foreach {cons} $list { set tkey [lindex $cons 0] if {$key == $tkey} { return $cons } } return {} } proc xmlrpc::warn {msg} { puts stderr $msg } proc xmlrpc::debug {msg} { variable DEBUG if {$DEBUG} { puts "$msg" } } proc xmlrpc::errReturn {msg} { warn $msg return -code error } proc xmlrpc::test {} { set person(first) {string "eric m"} set person(last) {string yeh} set employed(programmer) {struct person} #set xml [marshall {struct employed}] #set w [list {int 1}] #set q [list "array \{$w\}" {int 2} {string eric}] #puts [marshall "array \{$q\}"] #set xml [marshall {array {{int 1} {string {hello everybody}}}}] set xml [marshall {struct person}] debug "xml:\n$xml" set data [unmarshall $xml] debug "data: $data" set data [lindex $data 1] debug "data: $data" puts [assoc "first" $data] } proc bgerror {error} { global xmlcall if {$xmlcall} { global readdone set readdone -1 set xmlcall 0 } } #xmlrpc::test ���������������������������������./saods9/xmlrpc-0.3/INSTALL�������������������������������������������������������������������������0000644�0001750�0001750�00000001412�11131474217�013736� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Tcl searches for packages from the auto_path variable. To see what this is currently set to, start tclsh and enter: puts $auto_path On my system, it prints: /usr/lib/tcl8.0 /usr/lib In any of the directories in $auto_path, type: tar -zxf xmlrpctcl.gz Note: You may need to be root to do this. This will create a directory called xmlrpc0.3 Then start tclsh again, and type: pkg_mkIndex directory where directory is the full path to the xmlrpc0.3 directory just created. Inside xmlrpc0.3, you should now see a "pkgIndex.tcl" file. If all is well, in a tclsh you should now be able to type: package require xmlrpc Documentation: Documentation can be found in the source(xmlrpc.tcl). Samples: To try the samples provided, just start testserver.tcl and then run testclient.tcl. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/CHANGES�������������������������������������������������������������������������0000644�0001750�0001750�00000000607�11131474217�013705� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������4-20-2001: -can handle lines ending with \r\n (windows) -xmlrpc::call can be in a catch statement and it will catch errors (had a problem with catching fileevent errors that get raised in the background) -fixed the test example to call the right function 3-15-2001: -fixed the case where the non-blocking read call reached EOF prematurely -added "catches" around the close of socket calls �������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/testserver.tcl������������������������������������������������������������������0000755�0001750�0001750�00000000177�11131474217�015631� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env tclsh package require xmlrpc xmlrpc::serve 5555 proc test {a b} { return [list string $a$b] } vwait forever �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/xmlrpc-0.3/testclient.tcl������������������������������������������������������������������0000755�0001750�0001750�00000000302�11131474217�015567� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env tclsh package require xmlrpc if {[catch {set res [xmlrpc::call "http://localhost:5555" "test" {{int 1} {string b}}]}]} { puts "xmlrpc call failed" } else { puts "res: $res." } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwin64x86lion�����������������������������������������������������������������������0000644�0001750�0001750�00000001253�12077031450�014630� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# make sure installed: PKG_CONFIG for Xft, see notes OS = unix ARCH = darwin64x86lion X11INCLUDE=/usr/X11/include X11LIB = /usr/X11/lib EXTTCLFLAGS=--disable-corefoundation XX = -O2 YY = -gstabs+ -fno-inline ZZ = -m64 -arch x86_64 -mmacosx-version-min=10.7 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz ASTFLAGS = star_cv_cnf_trail_type=long JOBS = 4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinx86tiger������������������������������������������������������������������������0000644�0001750�0001750�00000001245�11773331763�014644� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinx86tiger X11INCLUDE=/usr/X11R6/include X11LIB = /usr/X11R6/lib EXTTCLFLAGS=--disable-corefoundation export MACOSX_DEPLOYMENT_TARGET := 10.4 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++-4.0 CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc-4.0 CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = echo ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-tiger.tar.gz ASTFLAGS = ac_cv_header_execinfo_h=no JOBS = 4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinsnowleopard���������������������������������������������������������������������0000644�0001750�0001750�00000000204�11260736452�015506� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinsnowleopard ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinlion����������������������������������������������������������������������������0000644�0001750�0001750�00000000176�11621260423�014111� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinlion ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/cmaps/�������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�012174� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/cmaps/cubehelix1.sao�����������������������������������������������������������������������0000644�0001750�0001750�00000010316�11742074507�014753� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#----------------------------------------- # cubehelix colour scheme for saoimage/DS9 # # start....: 0.5 # rotations: -1.5 # hue......: 2.0 # gamma....: 1.0 # # see: Green (2011), BASI, 39, 289. #----------------------------------------- # Dave Green: dag@mrao.cam.ac.uk #----------------------------------------- PSEUDOCOLOR RED: (0.00,0.00) (0.01,0.02) (0.02,0.04) (0.03,0.06) (0.04,0.08) (0.05,0.09) (0.06,0.10) (0.07,0.10) (0.08,0.11) (0.09,0.11) (0.10,0.10) (0.11,0.10) (0.12,0.09) (0.13,0.08) (0.14,0.07) (0.15,0.05) (0.16,0.04) (0.17,0.02) (0.18,0.00) (0.19,0.00) (0.20,0.00) (0.21,0.00) (0.22,0.00) (0.23,0.00) (0.24,0.00) (0.25,0.00) (0.26,0.00) (0.27,0.00) (0.28,0.00) (0.29,0.00) (0.30,0.00) (0.31,0.00) (0.32,0.00) (0.33,0.00) (0.34,0.03) (0.35,0.06) (0.36,0.09) (0.37,0.13) (0.38,0.17) (0.39,0.21) (0.40,0.26) (0.41,0.31) (0.42,0.36) (0.43,0.41) (0.44,0.46) (0.45,0.51) (0.46,0.56) (0.47,0.61) (0.48,0.66) (0.49,0.71) (0.50,0.76) (0.51,0.80) (0.52,0.84) (0.53,0.88) (0.54,0.91) (0.55,0.94) (0.56,0.97) (0.57,0.99) (0.58,1.00) (0.59,1.00) (0.60,1.00) (0.61,1.00) (0.62,1.00) (0.63,1.00) (0.64,1.00) (0.65,1.00) (0.66,1.00) (0.67,0.99) (0.68,0.97) (0.69,0.95) (0.70,0.93) (0.71,0.90) (0.72,0.88) (0.73,0.86) (0.74,0.83) (0.75,0.81) (0.76,0.79) (0.77,0.77) (0.78,0.75) (0.79,0.73) (0.80,0.72) (0.81,0.71) (0.82,0.70) (0.83,0.69) (0.84,0.69) (0.85,0.69) (0.86,0.70) (0.87,0.71) (0.88,0.72) (0.89,0.73) (0.90,0.75) (0.91,0.77) (0.92,0.79) (0.93,0.81) (0.94,0.84) (0.95,0.87) (0.96,0.89) (0.97,0.92) (0.98,0.95) (0.99,0.97) (1.00,1.00) GREEN: (0.00,0.00) (0.01,0.00) (0.02,0.00) (0.03,0.01) (0.04,0.01) (0.05,0.01) (0.06,0.02) (0.07,0.03) (0.08,0.04) (0.09,0.05) (0.10,0.07) (0.11,0.08) (0.12,0.10) (0.13,0.12) (0.14,0.14) (0.15,0.16) (0.16,0.18) (0.17,0.20) (0.18,0.23) (0.19,0.25) (0.20,0.28) (0.21,0.30) (0.22,0.33) (0.23,0.35) (0.24,0.38) (0.25,0.40) (0.26,0.42) (0.27,0.44) (0.28,0.46) (0.29,0.48) (0.30,0.50) (0.31,0.51) (0.32,0.53) (0.33,0.54) (0.34,0.55) (0.35,0.55) (0.36,0.56) (0.37,0.56) (0.38,0.56) (0.39,0.56) (0.40,0.55) (0.41,0.55) (0.42,0.54) (0.43,0.53) (0.44,0.52) (0.45,0.51) (0.46,0.50) (0.47,0.49) (0.48,0.47) (0.49,0.46) (0.50,0.45) (0.51,0.44) (0.52,0.43) (0.53,0.42) (0.54,0.41) (0.55,0.40) (0.56,0.40) (0.57,0.39) (0.58,0.39) (0.59,0.39) (0.60,0.39) (0.61,0.40) (0.62,0.40) (0.63,0.41) (0.64,0.42) (0.65,0.43) (0.66,0.45) (0.67,0.47) (0.68,0.48) (0.69,0.50) (0.70,0.53) (0.71,0.55) (0.72,0.57) (0.73,0.60) (0.74,0.63) (0.75,0.65) (0.76,0.68) (0.77,0.71) (0.78,0.73) (0.79,0.76) (0.80,0.78) (0.81,0.81) (0.82,0.83) (0.83,0.85) (0.84,0.87) (0.85,0.89) (0.86,0.91) (0.87,0.93) (0.88,0.94) (0.89,0.95) (0.90,0.96) (0.91,0.97) (0.92,0.98) (0.93,0.99) (0.94,0.99) (0.95,0.99) (0.96,1.00) (0.97,1.00) (0.98,1.00) (0.99,1.00) (1.00,1.00) BLUE: (0.00,0.00) (0.01,0.02) (0.02,0.05) (0.03,0.07) (0.04,0.10) (0.05,0.13) (0.06,0.16) (0.07,0.19) (0.08,0.22) (0.09,0.25) (0.10,0.28) (0.11,0.30) (0.12,0.33) (0.13,0.35) (0.14,0.37) (0.15,0.38) (0.16,0.40) (0.17,0.41) (0.18,0.41) (0.19,0.41) (0.20,0.41) (0.21,0.41) (0.22,0.40) (0.23,0.38) (0.24,0.37) (0.25,0.35) (0.26,0.32) (0.27,0.30) (0.28,0.27) (0.29,0.24) (0.30,0.21) (0.31,0.18) (0.32,0.15) (0.33,0.12) (0.34,0.09) (0.35,0.07) (0.36,0.04) (0.37,0.02) (0.38,0.00) (0.39,0.00) (0.40,0.00) (0.41,0.00) (0.42,0.00) (0.43,0.00) (0.44,0.00) (0.45,0.00) (0.46,0.00) (0.47,0.00) (0.48,0.01) (0.49,0.04) (0.50,0.07) (0.51,0.11) (0.52,0.15) (0.53,0.19) (0.54,0.24) (0.55,0.28) (0.56,0.33) (0.57,0.39) (0.58,0.44) (0.59,0.50) (0.60,0.55) (0.61,0.61) (0.62,0.66) (0.63,0.71) (0.64,0.76) (0.65,0.81) (0.66,0.86) (0.67,0.90) (0.68,0.94) (0.69,0.98) (0.70,1.00) (0.71,1.00) (0.72,1.00) (0.73,1.00) (0.74,1.00) (0.75,1.00) (0.76,1.00) (0.77,1.00) (0.78,1.00) (0.79,1.00) (0.80,1.00) (0.81,1.00) (0.82,1.00) (0.83,1.00) (0.84,1.00) (0.85,1.00) (0.86,1.00) (0.87,1.00) (0.88,1.00) (0.89,0.98) (0.90,0.97) (0.91,0.96) (0.92,0.95) (0.93,0.95) (0.94,0.94) (0.95,0.95) (0.96,0.95) (0.97,0.96) (0.98,0.97) (0.99,0.98) (1.00,1.00) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/cmaps/cubehelix0.sao�����������������������������������������������������������������������0000644�0001750�0001750�00000010265�11742074507�014755� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#----------------------------------------- #cubehelixcolourschemeforsaoimage/DS9 # #start....:0.5 #rotations:-1.5 #hue......:1.0 #gamma....:1.0 # #see:Green(2011),BASI,39,289. #----------------------------------------- #DaveGreen:dag@mrao.cam.ac.uk #----------------------------------------- PSEUDOCOLOR RED: (0.00,0.00) (0.01,0.02) (0.02,0.03) (0.03,0.05) (0.04,0.06) (0.05,0.07) (0.06,0.08) (0.07,0.09) (0.08,0.09) (0.09,0.10) (0.10,0.10) (0.11,0.10) (0.12,0.10) (0.13,0.10) (0.14,0.10) (0.15,0.10) (0.16,0.10) (0.17,0.09) (0.18,0.09) (0.19,0.09) (0.20,0.09) (0.21,0.08) (0.22,0.08) (0.23,0.08) (0.24,0.08) (0.25,0.08) (0.26,0.09) (0.27,0.09) (0.28,0.10) (0.29,0.11) (0.30,0.12) (0.31,0.13) (0.32,0.15) (0.33,0.16) (0.34,0.18) (0.35,0.20) (0.36,0.23) (0.37,0.25) (0.38,0.27) (0.39,0.30) (0.40,0.33) (0.41,0.36) (0.42,0.39) (0.43,0.42) (0.44,0.45) (0.45,0.48) (0.46,0.51) (0.47,0.54) (0.48,0.57) (0.49,0.60) (0.50,0.63) (0.51,0.65) (0.52,0.68) (0.53,0.70) (0.54,0.72) (0.55,0.75) (0.56,0.76) (0.57,0.78) (0.58,0.79) (0.59,0.80) (0.60,0.81) (0.61,0.82) (0.62,0.83) (0.63,0.83) (0.64,0.83) (0.65,0.83) (0.66,0.83) (0.67,0.83) (0.68,0.82) (0.69,0.82) (0.70,0.81) (0.71,0.81) (0.72,0.80) (0.73,0.79) (0.74,0.79) (0.75,0.78) (0.76,0.77) (0.77,0.77) (0.78,0.76) (0.79,0.76) (0.80,0.76) (0.81,0.76) (0.82,0.76) (0.83,0.76) (0.84,0.77) (0.85,0.77) (0.86,0.78) (0.87,0.79) (0.88,0.80) (0.89,0.81) (0.90,0.82) (0.91,0.84) (0.92,0.85) (0.93,0.87) (0.94,0.89) (0.95,0.91) (0.96,0.93) (0.97,0.95) (0.98,0.96) (0.99,0.98) (1.00,1.00) GREEN: (0.00,0.00) (0.01,0.01) (0.02,0.01) (0.03,0.02) (0.04,0.02) (0.05,0.03) (0.06,0.04) (0.07,0.05) (0.08,0.06) (0.09,0.07) (0.10,0.08) (0.11,0.10) (0.12,0.11) (0.13,0.12) (0.14,0.14) (0.15,0.15) (0.16,0.17) (0.17,0.19) (0.18,0.20) (0.19,0.22) (0.20,0.24) (0.21,0.26) (0.22,0.27) (0.23,0.29) (0.24,0.31) (0.25,0.32) (0.26,0.34) (0.27,0.36) (0.28,0.37) (0.29,0.39) (0.30,0.40) (0.31,0.41) (0.32,0.42) (0.33,0.43) (0.34,0.44) (0.35,0.45) (0.36,0.46) (0.37,0.46) (0.38,0.47) (0.39,0.47) (0.40,0.48) (0.41,0.48) (0.42,0.48) (0.43,0.48) (0.44,0.48) (0.45,0.48) (0.46,0.48) (0.47,0.48) (0.48,0.48) (0.49,0.48) (0.50,0.47) (0.51,0.47) (0.52,0.47) (0.53,0.47) (0.54,0.47) (0.55,0.48) (0.56,0.48) (0.57,0.48) (0.58,0.48) (0.59,0.49) (0.60,0.50) (0.61,0.50) (0.62,0.51) (0.63,0.52) (0.64,0.53) (0.65,0.54) (0.66,0.55) (0.67,0.57) (0.68,0.58) (0.69,0.60) (0.70,0.61) (0.71,0.63) (0.72,0.65) (0.73,0.67) (0.74,0.68) (0.75,0.70) (0.76,0.72) (0.77,0.74) (0.78,0.76) (0.79,0.77) (0.80,0.79) (0.81,0.81) (0.82,0.83) (0.83,0.84) (0.84,0.86) (0.85,0.87) (0.86,0.89) (0.87,0.90) (0.88,0.91) (0.89,0.92) (0.90,0.93) (0.91,0.94) (0.92,0.95) (0.93,0.96) (0.94,0.97) (0.95,0.97) (0.96,0.98) (0.97,0.98) (0.98,0.99) (0.99,0.99) (1.00,1.00) BLUE: (0.00,0.00) (0.01,0.02) (0.02,0.03) (0.03,0.05) (0.04,0.07) (0.05,0.09) (0.06,0.11) (0.07,0.13) (0.08,0.15) (0.09,0.17) (0.10,0.19) (0.11,0.21) (0.12,0.22) (0.13,0.24) (0.14,0.25) (0.15,0.27) (0.16,0.28) (0.17,0.29) (0.18,0.30) (0.19,0.30) (0.20,0.31) (0.21,0.31) (0.22,0.31) (0.23,0.31) (0.24,0.30) (0.25,0.30) (0.26,0.29) (0.27,0.28) (0.28,0.28) (0.29,0.27) (0.30,0.26) (0.31,0.25) (0.32,0.24) (0.33,0.23) (0.34,0.22) (0.35,0.21) (0.36,0.20) (0.37,0.19) (0.38,0.19) (0.39,0.19) (0.40,0.18) (0.41,0.18) (0.42,0.19) (0.43,0.19) (0.44,0.20) (0.45,0.21) (0.46,0.22) (0.47,0.23) (0.48,0.25) (0.49,0.27) (0.50,0.29) (0.51,0.31) (0.52,0.33) (0.53,0.36) (0.54,0.39) (0.55,0.42) (0.56,0.45) (0.57,0.48) (0.58,0.51) (0.59,0.54) (0.60,0.58) (0.61,0.61) (0.62,0.64) (0.63,0.67) (0.64,0.70) (0.65,0.73) (0.66,0.76) (0.67,0.78) (0.68,0.81) (0.69,0.83) (0.70,0.85) (0.71,0.87) (0.72,0.89) (0.73,0.91) (0.74,0.92) (0.75,0.93) (0.76,0.94) (0.77,0.94) (0.78,0.95) (0.79,0.95) (0.80,0.95) (0.81,0.95) (0.82,0.95) (0.83,0.95) (0.84,0.95) (0.85,0.95) (0.86,0.94) (0.87,0.94) (0.88,0.94) (0.89,0.94) (0.90,0.94) (0.91,0.94) (0.92,0.94) (0.93,0.94) (0.94,0.94) (0.95,0.95) (0.96,0.95) (0.97,0.96) (0.98,0.97) (0.99,0.99) (1.00,1.00) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/unix/��������������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201303�012052� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/unix/Makefile������������������������������������������������������������������������������0000644�0001750�0001750�00000001074�11516404165�013533� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include include ../make.pkgs CXXFLAGS = $(CXXOPT) -I../include -I../saotk/vector -I../saotk/widget -I$(X11INCLUDE) SRC = rotstr.C OBJS = $(SRC:%.C=%.o) INCLS = rotstr.h LIB = libxxlib.a all : $(LIB) install : all cp $(INCLS) ../include/. cp $(LIB) ../lib/. $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.so *.a FORCE : ifdef DEPENDS %.d: %.C set -e; $(CXX) -MM $(CXXFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.C=.d) endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/unix/rotstr.C������������������������������������������������������������������������������0000644�0001750�0001750�00000013214�11700667477�013547� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "rotstr.h" #include "vector.h" #include "widget.h" #include <tk.h> #include <X11/Xutil.h> void XDrawRotString(Display* display, Drawable drawable, GC gc, Vector& v, double angle, const char* text, Tk_Font font, Widget* parent) { if (angle>-.01 && angle<+.01) { Tk_DrawChars(display, drawable, gc, font, text, strlen(text), v[0], v[1]); return; } // this is a very crude "green screen" method. // since the text is rendered with an anti-alias method, the text color // will vary from the initial color to the mask color. // so to avoid a 'dark' ring around the text, we calculate a mask value, // from the middle of the background image. int width = parent->getWidth(); int height = parent->getHeight(); int depth = parent->getDepth(); Tk_FontMetrics metrics; Tk_GetFontMetrics(font, &metrics); int srcw = Tk_TextWidth(font, text, strlen(text))+4; int srch = metrics.linespace+2; BBox dstbb; { // calculate bounding box Vector corner = (Vector(srcw,srch)-Vector(1,1))/2; int ww = Tk_TextWidth(font, text, strlen(text)); int hh = metrics.ascent-metrics.descent; Matrix mx = Translate(ww/2.,-hh/2.) * Rotate(angle) * Translate(v); dstbb = BBox(v,v); dstbb.bound(-corner * mx); dstbb.bound( corner * mx); dstbb.bound(Vector( corner[0],-corner[1]) * mx); dstbb.bound(Vector(-corner[0], corner[1]) * mx); } // clip bounding box against window BBox dsttbb = intersect(dstbb,BBox(0,0,width,height)); int dstx = dsttbb.ll[0]; int dsty = dsttbb.ll[1]; int dstw = dsttbb.size()[0]; int dsth = dsttbb.size()[1]; if (dstw<=0 || dsth<=0) return; // get background image into dstxmap Pixmap dstpmap = XCreatePixmap(display, drawable, dstw, dsth, depth); XCopyArea(display, drawable, dstpmap, gc, dstx, dsty, dstw, dsth, 0, 0); XImage* dstxmap = XGetImage(display, dstpmap, 0, 0, dstw, dsth, AllPlanes, ZPixmap); unsigned char* dst = (unsigned char*)dstxmap->data; int dstl = dstxmap->bytes_per_line; int dstb = dstxmap->bits_per_pixel/8; // calc mask unsigned char mask[4]; { switch (dstb) { case 1: case 2: // We don't want to decode, so just take the first value in the bg memcpy(mask,dst,dstb); case 3: case 4: // average the background values over the extent { int cnt =0; unsigned char* dst = (unsigned char*)dstxmap->data; unsigned long mk[4]; for (int kk=0; kk<3; kk++) mk[kk] =0; for (int jj=0; jj<dsth; jj++) { // the line may be padded at the end unsigned char* dptr = dst + jj*dstl; for (int ii=0; ii<dstw; ii++, dptr+=dstb) { // the edges can be unprediciable, don't use if (dstx+ii > 0 && dstx+ii < width && dsty+jj > 0 && dsty+jj < height) { for (int kk=0; kk<dstb; kk++) mk[kk] += *(dptr+kk); cnt++; } } } for (int kk=0; kk<dstb; kk++) { if (mk[kk] && cnt) mk[kk] /= cnt; mask[kk] = mk[kk]; } } break; } } // create srcpmap Pixmap srcpmap = XCreatePixmap(display, drawable, srcw, srch, depth); { XImage* srcxmap = XGetImage(display, srcpmap, 0, 0, srcw, srch, AllPlanes, ZPixmap); unsigned char* src = (unsigned char*)srcxmap->data; int srcl = srcxmap->bytes_per_line; int srcb = srcxmap->bits_per_pixel/8; // fill srcpmap with mask value(s) for (int jj=0; jj<srch; jj++) { // the line may be padded at the end unsigned char* sptr = src + jj*srcl; for (int ii=0; ii<srcw; ii++, sptr+=srcb) memcpy(sptr,mask,srcb); } XPutImage(display, srcpmap, gc, srcxmap, 0, 0, 0, 0, srcw, srch); // render text into srcpmap XSetBackground(display,gc,parent->getColor("black")); Tk_DrawChars(display, srcpmap, gc, font, text, strlen(text), 2, metrics.ascent); XDestroyImage(srcxmap); } // get rendered text into srcxmap { XImage* srcxmap = XGetImage(display, srcpmap, 0, 0, srcw, srch, AllPlanes, ZPixmap); unsigned char* src = (unsigned char*)srcxmap->data; int srcl = srcxmap->bytes_per_line; int srcb = srcxmap->bits_per_pixel/8; // rotate text from srcxmap to dstxmap Matrix m = Translate(-Vector(srcw,srch)/2) * Rotate(angle) * Translate(Vector(dstw,dsth)/2) * Translate((dstbb.center()-dsttbb.center())); double* mm = (m.invert()).mm(); for (int jj=0; jj<dsth; jj++) { // the line may be padded at the end unsigned char* dptr = dst + jj*dstl; for (int ii=0; ii<dstw; ii++, dptr+=dstb) { double xx = ii*mm[0] + jj*mm[3] + mm[6]; double yy = ii*mm[1] + jj*mm[4] + mm[7]; if (xx >= 0 && xx < srcw && yy >= 0 && yy < srch) { unsigned char* sptr = src + ((int)yy)*srcl + ((int)xx)*srcb; switch (dstb) { case 1: if (*sptr != mask[0]) memcpy(dptr,sptr,dstb); break; case 2: if (*(sptr+0) != mask[0] || *(sptr+1) != mask[1]) memcpy(dptr,sptr,dstb); break; case 3: if (*(sptr+0) != mask[0] || *(sptr+1) != mask[1] || *(sptr+2) != mask[2]) memcpy(dptr,sptr,dstb); case 4: if (*(sptr+0) != mask[0] || *(sptr+1) != mask[1] || *(sptr+2) != mask[2]) memcpy(dptr,sptr,dstb); break; } } } } XDestroyImage(srcxmap); } // put rotated text into dstpmap and copy into drawable XPutImage(display, dstpmap, gc, dstxmap, 0, 0, 0, 0, dstw, dsth); XCopyArea(display, dstpmap, drawable, gc, 0, 0, dstw, dsth, dstx, dsty); // clean up XFreePixmap(display, srcpmap); XFreePixmap(display, dstpmap); XDestroyImage(dstxmap); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/unix/rotstr.h������������������������������������������������������������������������������0000644�0001750�0001750�00000000643�11700667477�013616� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 1999-2012 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #ifndef __rotstr_h__ #define __rotstr_h__ #include <tk.h> class Widget; class Vector; extern void XDrawRotString(Display* display, Drawable drawable, GC gc, Vector&, double angle, const char* text, Tk_Font font, Widget* parent); #endif ���������������������������������������������������������������������������������������������./saods9/make.macosxx86leopard����������������������������������������������������������������������0000644�0001750�0001750�00000001124�11773331763�015162� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxx86leopard X11INCLUDE =../include/X11 export MACOSX_DEPLOYMENT_TARGET := 10.5 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 AA = -fPIC -D_MACOSX -DMAC_OSX_TK -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-leopard.tar.gz JOBS = 4 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.linux���������������������������������������������������������������������������������0000644�0001750�0001750�00000001071�11773331763�013113� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = linux X11INCLUDE=/usr/X11R6/include X11LIB = /usr/X11R6/lib XX = -O2 YY = -gstabs+ -fno-inline ZZ = # note: bug with gcc 4.1 and 4.2 # can't use -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 # AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} #CXX = g++ CXX = g++44 CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} #CC = gcc CC = gcc44 CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = zcat JOBS = 4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/checkdns/����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201305�012653� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/checkdns/Makefile��������������������������������������������������������������������������0000644�0001750�0001750�00000000732�11115554507�014333� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include CFLAGS = $(CCOPT) -I../include SRC = checkdns.c OBJS = $(SRC:%.c=%.o) LIB = libcheckdns.a all : $(LIB) install : all cp -f $(LIB) ../lib/. $(LIB) : $(OBJS) $(COBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) $(COBJS) clean : FORCE rm -f core *~ *# distclean : clean rm -f *.a *.so *.o FORCE : ifdef DEPENDS %.d: %.c set -e; $(CC) -MM $(CFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ include $(SRC:.c=.d) endif ��������������������������������������./saods9/checkdns/checkdns.c������������������������������������������������������������������������0000644�0001750�0001750�00000013256�11700667477�014641� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* Copyright (C) 1999-2012 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA * For conditions of distribution and use, see copyright notice in "copyright" */ /* linux: gcc -Wall -o checkdns -g checkdns.c */ #define HAVE_TCL 1 #include <string.h> #include <unistd.h> #include <errno.h> #include <signal.h> #include <netdb.h> #if HAVE_TCL #include <tcl.h> #else #include <stdio.h> #include <stdlib.h> extern char *optarg; extern int optind; #endif #ifndef SZ_LINE #define SZ_LINE 2048 #endif static int debug=0; /* shared between main routine and signal handler */ static int dns_alarm_flag=0; /* alarm signal handler */ static void dns_alarm(int signo) { dns_alarm_flag = 1; } /* check whether we can get info in an ip in a finite amount of time */ static int checkdns(char *name, int delay, int cflag) { int fd; int got; int flag=0; unsigned int ip; unsigned int port=80; char *s=NULL; char host[SZ_LINE]; char tbuf[SZ_LINE]; struct hostent *h; struct sockaddr_in sock_in; struct sigaction act1, oact1; /* get temp name, look for port */ if( name && *name ){ strncpy(tbuf, name, SZ_LINE-1); if( (s=strchr(tbuf, ':')) ){ *s = '\0'; port = atoi(s+1); } } else { *tbuf = '\0'; } /* start the alarm, if necessary */ if( delay > 0 ){ /* set up alarm signal handler */ act1.sa_handler = dns_alarm; sigemptyset(&act1.sa_mask); act1.sa_flags = 0; #ifdef SA_INTERRUPT act1.sa_flags |= SA_INTERRUPT; #endif if( sigaction(SIGALRM, &act1, &oact1) < 0 ){ flag = 1; goto done; } /* start the alarm */ alarm(delay); } /* get name of host we are interested in */ if( *tbuf ) strncpy(host, tbuf, SZ_LINE-1); else{ /* use current host */ if( gethostname(host, SZ_LINE) < 0 ){ if( errno != EINTR ){ if( debug ) perror("gethostname"); flag = 2; goto done; } } else if( debug ){ fprintf(stderr, "gethostname: %s\n", host); } } /* if the alarm went off, we are done */ if( delay && dns_alarm_flag ){ if( debug ) fprintf(stderr, "alarm after gethostname()\n"); goto done; } /* try to get info on this host */ if( !(h=gethostbyname(host)) ){ if( errno != EINTR ){ if( debug ) perror("gethostbyname"); flag = 3; goto done; } } else if( debug ){ fprintf(stderr, "gethostbyname: %s (%d)\n", h->h_name, port); } /* if the alarm went off, we are done */ if( delay && dns_alarm_flag ){ if( debug ) fprintf(stderr, "alarm after gethostbyname()\n"); flag = 4; goto done; } /* connect, if necessary */ if( cflag ){ memcpy(&ip, h->h_addr_list[0], (size_t)h->h_length); ip = ntohl(ip); if( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ if( errno != EINTR ){ if( debug ) perror("socket"); flag = 5; goto done; } } memset((char *)&sock_in, 0, sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_addr.s_addr = htonl(ip); sock_in.sin_port = htons(port); got = connect(fd, (struct sockaddr *)&sock_in, sizeof(sock_in)); close(fd); if( got < 0 ){ if( errno != EINTR ){ perror("connect"); flag = 6; goto done; } } else if( debug ){ fprintf(stderr, "connect succeeded\n"); } } /* if the alarm went off, we are done */ if( delay && dns_alarm_flag ){ if( debug ) fprintf(stderr, "alarm after connect()\n"); flag = 100; goto done; } /* stop the alarm, if necessary */ if( delay ){ /* turn off the alarm */ alarm(0); /* reset up alarm signal handler */ act1.sa_handler = oact1.sa_handler; sigemptyset(&act1.sa_mask); act1.sa_flags = 0; #ifdef SA_INTERRUPT act1.sa_flags |= SA_INTERRUPT; #endif sigaction(SIGALRM, &act1, &oact1); } done: /* if alarm went off, set return status flag */ if( dns_alarm_flag ){ if( !flag ) flag = dns_alarm_flag; } /* return status flag */ return(flag); } #if HAVE_TCL static int CheckDNS_Tcl(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int got; int delay=5; int cflag=0; char *s, *t; char *host=NULL; char tbuf[SZ_LINE]; /* make sure argument count is correct */ if( objc < 3 ){ Tcl_WrongNumArgs(interp, 1, objv, "host delay [connect]"); return(TCL_ERROR); } /* get host */ s = Tcl_GetStringFromObj(objv[1], NULL); if( s && (*s != '\0') ){ host = s; } /* get delay */ t = Tcl_GetStringFromObj(objv[2], NULL); if( t && (*t != '\0') ){ delay = atoi(t); } if( objc >= 4 ){ /* get connect flag */ t = Tcl_GetStringFromObj(objv[3], NULL); if( t && (*t != '\0') ){ cflag = atoi(t); } } /* reset error/result condition */ Tcl_ResetResult(interp); /* check the DNS */ got = checkdns(host, delay, cflag); /* set return value */ sprintf(tbuf, "%d", got); Tcl_SetResult(interp, tbuf, TCL_VOLATILE); /* tcl command complete */ return TCL_OK; } int Checkdns_Init (void *vinterp) { Tcl_Interp *interp = (Tcl_Interp *)vinterp; /* add xpa commands to this interpreter */ Tcl_CreateObjCommand(interp, "checkdns", CheckDNS_Tcl, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_PkgProvide(interp, "checkdns", "1.1"); return(TCL_OK); } #else int main(int argc, char **argv) { int c; int cflag=0; int delay=5; int got; char *name; /* process switch arguments */ while ((c = getopt(argc, argv, "cd:v")) != -1){ switch(c){ case 'c': cflag = 1; break; case 'd': delay = atoi(optarg); break; case 'v': debug = 1; break; } } /* sanity check */ if( (argc - optind) < 1 ){ fprintf(stderr, "usage: %s -c -d delay host\n", argv[0]); return 1; } /* get arguments */ name = argv[optind+0]; /* make the call */ got = checkdns(name, delay, cflag); /* output results */ fprintf(stderr, "return code: %d\n", got); return got; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.linux64�������������������������������������������������������������������������������0000644�0001750�0001750�00000000661�12047253303�013255� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = linux64 X11INCLUDE=/usr/include/X11 X11LIB = /usr/lib64 XX = -O2 YY = -g -fno-inline ZZ = -m64 -Wl,--hash-style=both AA = -fPIC -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D__M64 #OPTS = ${XX} ${ZZ} OPTS = ${YY} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = zcat JOBS = 4 �������������������������������������������������������������������������������./saods9/make.darwinmountainlion��������������������������������������������������������������������0000644�0001750�0001750�00000000206�12031114557�015660� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinmountainlion ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-snowleopard.tar.gz ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.darwinleopard�������������������������������������������������������������������������0000644�0001750�0001750�00000000174�11260736452�014605� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = unix ARCH = darwinleopard ZCAT = gzcat CODESIGN = codesign ZIPFILE = ds9.zip FILTERCOMPILER = pcc-i386-leopard.tar.gz����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/copyright����������������������������������������������������������������������������������0000644�0001750�0001750�00000001624�12061451606�013042� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (C) 1999-2012 Smithsonian Astrophysical Observatory, Cambridge, MA, USA 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 3 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, see <http://www.gnu.org/licenses/>. Correspondence concerning SAOImage DS9 should be addressed as follows: William Joye Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA wjoye@cfa.harvard.edu http://hea-www.harvard.edu/RD/ds9/ ������������������������������������������������������������������������������������������������������������./saods9/hcompress/���������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12133201304�013073� 5����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/hcompress/Makefile�������������������������������������������������������������������������0000644�0001750�0001750�00000000426�11021613047�014543� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../make.include CFLAGS = $(CCOPT) -I. SRC = hdecompress.c OBJS = $(SRC:%.c=%.o) LIB = libhcomp.a $(LIB) : $(OBJS) $(RM) $@ $(AR) -cr $@ $(OBJS) install : $(LIB) cp $(LIB) ../lib/. clean : FORCE rm -f core *~ *# distclean : clean rm -f *.o *.a *.so FORCE : ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/hcompress/hdecompress.c��������������������������������������������������������������������0000644�0001750�0001750�00000173412�11021613047�015571� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* ######################################################################### These routines to apply the H-compress decompression algorithm to a 2-D Fits image were written by R. White at the STScI and were obtained from the STScI at http://www.stsci.edu/software/hcompress.html This source file is a concatination of the following sources files in the original distribution hinv.c hsmooth.c undigitize.c decode.c dodecode.c qtree_decode.c qread.c bit_input.c The following modifications have been made to the original code: - commented out redundant "include" statements - added the nextchar global variable - changed all the 'extern' declarations to 'static', since all the routines are in the same source file - changed the first parameter in decode (and in lower level routines from a file stream to a char array - modified the myread routine, and lower level byte reading routines, to copy the input bytes to a char array, instead of reading them from a file stream - changed the function declarations to the more modern ANSI C style - changed calls to printf and perror to call the CFITSIO ffpmsg routine - replace "exit" statements with "return" statements ############################################################################ */ #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> /*#include "fitsio2.h"*/ #define LONGLONG long long #define DATA_DECOMPRESSION_ERR 0 /* WDP added test to see if min and max are already defined */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif static long nextchar; static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale); static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale); static int hinv(int a[], int nx, int ny, int smooth ,int scale); static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale); static void undigitize(int a[], int nx, int ny, int scale); static void undigitize64(LONGLONG a[], int nx, int ny, int scale); static void unshuffle(int a[], int n, int n2, int tmp[]); static void unshuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void hsmooth(int a[], int nxtop, int nytop, int ny, int scale); static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale); static void qread(unsigned char *infile,char *a, int n); static int readint(unsigned char *infile); static LONGLONG readlonglong(unsigned char *infile); static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int dodecode64(unsigned char *infile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int qtree_decode(unsigned char *infile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_inputing_bits(); static int input_bit(unsigned char *infile); static int input_nbits(unsigned char *infile, int n); /* make input_nybble a separate routine, for added effiency */ /* #define input_nybble(infile) input_nbits(infile,4) */ static int input_nybble(unsigned char *infile); static int input_nnybble(unsigned char *infile, int n, unsigned char *array); static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]); static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit); static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit); static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n); static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static int input_huffman(unsigned char *infile); /* ---------------------------------------------------------------------- */ int fits_hdecompress(unsigned char *input, int smooth, int *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* decode the input array */ stat = decode(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv(a, *nx, *ny, smooth, *scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat, *iarray, ii, nval; if (*status > 0) return(*status); /* decode the input array */ stat = decode64(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize64(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv64(a, *nx, *ny, smooth, *scale); *status = stat; /* pack the I*8 values back into an I*4 array */ iarray = (int *) a; nval = (*nx) * (*ny); for (ii = 0; ii < nval; ii++) iarray[ii] = (int) a[ii]; return(*status); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hinv.c Inverse H-transform of NX x NY integer image * * Programmer: R. White Date: 23 July 1993 */ /* ############################################################################ */ static int hinv(int a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift, bit0, bit1, bit2, mask0, mask1, mask2, prnd0, prnd1, prnd2, nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; int h0, hx, hy, hc; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<<log2n) ) { log2n += 1; } /* * get temporary storage for shuffling elements */ tmp = (int *) malloc(((nmax+1)/2)*sizeof(int)); if (tmp == (int *) NULL) { ffpmsg("hinv: insufficient memory"); return(DATA_DECOMPRESSION_ERR); } /* * set up masks, rounding parameters */ shift = 1; bit0 = 1 << (log2n - 1); bit1 = bit0 << 1; bit2 = bit0 << 2; mask0 = -bit0; mask1 = mask0 << 1; mask2 = mask0 << 2; prnd0 = bit0 >> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<<log2n; for (k = log2n-1; k>=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i<nxtop; i++) { unshuffle(&a[ny*i],nytop,1,tmp); } for (j = 0; j<nytop; j++) { unshuffle(&a[j],nxtop,ny,tmp); } /* * smooth by interpolating coefficients if SMOOTH != 0 */ if (smooth) hsmooth(a,nxtop,nytop,ny,scale); oddx = nxtop % 2; oddy = nytop % 2; for (i = 0; i<nxtop-oddx; i += 2) { s00 = ny*i; /* s00 is index of a[i,j] */ s10 = s00+ny; /* s10 is index of a[i+1,j] */ for (j = 0; j<nytop-oddy; j += 2) { h0 = a[s00 ]; hx = a[s10 ]; hy = a[s00+1]; hc = a[s10+1]; /* * round hx and hy to multiple of bit1, hc to multiple of bit0 * h0 is already a multiple of bit2 */ hx = (hx + ((hx >= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j<nytop-oddy; j += 2) { h0 = a[s00 ]; hy = a[s00+1]; hy = ((hy >= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift; LONGLONG mask0, mask1, mask2, prnd0, prnd1, prnd2, bit0, bit1, bit2; LONGLONG nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; LONGLONG h0, hx, hy, hc; int s10, s00; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<<log2n) ) { log2n += 1; } /* * get temporary storage for shuffling elements */ tmp = (LONGLONG *) malloc(((nmax+1)/2)*sizeof(LONGLONG)); if (tmp == (LONGLONG *) NULL) { ffpmsg("hinv64: insufficient memory"); return(DATA_DECOMPRESSION_ERR); } /* * set up masks, rounding parameters */ shift = 1; bit0 = ((LONGLONG) 1) << (log2n - 1); bit1 = bit0 << 1; bit2 = bit0 << 2; mask0 = -bit0; mask1 = mask0 << 1; mask2 = mask0 << 2; prnd0 = bit0 >> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<<log2n; for (k = log2n-1; k>=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i<nxtop; i++) { unshuffle64(&a[ny*i],nytop,1,tmp); } for (j = 0; j<nytop; j++) { unshuffle64(&a[j],nxtop,ny,tmp); } /* * smooth by interpolating coefficients if SMOOTH != 0 */ if (smooth) hsmooth64(a,nxtop,nytop,ny,scale); oddx = nxtop % 2; oddy = nytop % 2; for (i = 0; i<nxtop-oddx; i += 2) { s00 = ny*i; /* s00 is index of a[i,j] */ s10 = s00+ny; /* s10 is index of a[i+1,j] */ for (j = 0; j<nytop-oddy; j += 2) { h0 = a[s00 ]; hx = a[s10 ]; hy = a[s00+1]; hc = a[s10+1]; /* * round hx and hy to multiple of bit1, hc to multiple of bit0 * h0 is already a multiple of bit2 */ hx = (hx + ((hx >= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j<nytop-oddy; j += 2) { h0 = a[s00 ]; hy = a[s00+1]; hy = ((hy >= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static void unshuffle(int a[], int n, int n2, int tmp[]) /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ { int i; int nhalf; int *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i<n; i++) { *pt = *p1; p1 += n2; pt += 1; } /* * distribute 1st half of array to even elements */ p2 = &a[ n2*(nhalf-1) ]; /* pointer to a[i] */ p1 = &a[(n2*(nhalf-1))<<1]; /* pointer to a[2*i] */ for (i=nhalf-1; i >= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i<n; i += 2) { *p1 = *pt; p1 += (n2+n2); pt += 1; } } /* ############################################################################ */ static void unshuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]) /* LONGLONG a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension LONGLONG tmp[]; scratch storage */ { int i; int nhalf; LONGLONG *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i<n; i++) { *pt = *p1; p1 += n2; pt += 1; } /* * distribute 1st half of array to even elements */ p2 = &a[ n2*(nhalf-1) ]; /* pointer to a[i] */ p1 = &a[(n2*(nhalf-1))<<1]; /* pointer to a[2*i] */ for (i=nhalf-1; i >= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i<n; i += 2) { *p1 = *pt; p1 += (n2+n2); pt += 1; } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hsmooth.c Smooth H-transform image by adjusting coefficients toward * interpolated values * * Programmer: R. White Date: 13 April 1992 */ /* ############################################################################ */ static void hsmooth(int a[], int nxtop, int nytop, int ny, int scale) /* int a[]; array of H-transform coefficients int nxtop,nytop; size of coefficient block to use int ny; actual 1st dimension of array int scale; truncation scale factor that was used */ { int i, j; int ny2, s10, s00, diff, dmax, dmin, s, smax; int hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2; int m1,m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i<nxtop-2; i += 2) { s00 = ny*i; /* s00 is index of a[i,j] */ s10 = s00+ny; /* s10 is index of a[i+1,j] */ for (j = 0; j<nytop; j += 2) { /* * hp is h0 (mean value) in next x zone, hm is h0 in previous x zone */ hm = a[s00-ny2]; h0 = a[s00]; hp = a[s00+ny2]; /* * diff = 8 * hx slope that would match h0 in neighboring zones */ diff = hp-hm; /* * monotonicity constraints on diff */ dmax = max( min( (hp-h0), (h0-hm) ), 0 ) << 2; dmin = min( max( (hp-h0), (h0-hm) ), 0 ) << 2; /* * if monotonicity would set slope = 0 then don't change hx. * note dmax>=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i<nxtop; i += 2) { s00 = ny*i+2; s10 = s00+ny; for (j = 2; j<nytop-2; j += 2) { hm = a[s00-2]; h0 = a[s00]; hp = a[s00+2]; diff = hp-hm; dmax = max( min( (hp-h0), (h0-hm) ), 0 ) << 2; dmin = min( max( (hp-h0), (h0-hm) ), 0 ) << 2; if (dmin < dmax) { diff = max( min(diff, dmax), dmin); s = diff-(a[s00+1]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i<nxtop-2; i += 2) { s00 = ny*i+2; s10 = s00+ny; for (j = 2; j<nytop-2; j += 2) { /* * ------------------ y * | hmp | | hpp | | * ------------------ | * | | h0 | | | * ------------------ -------x * | hmm | | hpm | * ------------------ */ hmm = a[s00-ny2-2]; hpm = a[s00+ny2-2]; hmp = a[s00-ny2+2]; hpp = a[s00+ny2+2]; h0 = a[s00]; /* * diff = 64 * hc value that would match h0 in neighboring zones */ diff = hpp + hmm - hmp - hpm; /* * 2 times x,y slopes in this zone */ hx2 = a[s10 ]<<1; hy2 = a[s00+1]<<1; /* * monotonicity constraints on diff */ m1 = min(max(hpp-h0,0)-hx2-hy2, max(h0-hpm,0)+hx2-hy2); m2 = min(max(h0-hmp,0)-hx2+hy2, max(hmm-h0,0)+hx2+hy2); dmax = min(m1,m2) << 4; m1 = max(min(hpp-h0,0)-hx2-hy2, min(h0-hpm,0)+hx2-hy2); m2 = max(min(h0-hmp,0)-hx2+hy2, min(hmm-h0,0)+hx2+hy2); dmin = max(m1,m2) << 4; /* * if monotonicity would set slope = 0 then don't change hc. * note dmax>=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale) /* LONGLONG a[]; array of H-transform coefficients int nxtop,nytop; size of coefficient block to use int ny; actual 1st dimension of array int scale; truncation scale factor that was used */ { int i, j; int ny2, s10, s00; LONGLONG hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2, diff, dmax, dmin, s, smax, m1, m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i<nxtop-2; i += 2) { s00 = ny*i; /* s00 is index of a[i,j] */ s10 = s00+ny; /* s10 is index of a[i+1,j] */ for (j = 0; j<nytop; j += 2) { /* * hp is h0 (mean value) in next x zone, hm is h0 in previous x zone */ hm = a[s00-ny2]; h0 = a[s00]; hp = a[s00+ny2]; /* * diff = 8 * hx slope that would match h0 in neighboring zones */ diff = hp-hm; /* * monotonicity constraints on diff */ dmax = max( min( (hp-h0), (h0-hm) ), 0 ) << 2; dmin = min( max( (hp-h0), (h0-hm) ), 0 ) << 2; /* * if monotonicity would set slope = 0 then don't change hx. * note dmax>=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i<nxtop; i += 2) { s00 = ny*i+2; s10 = s00+ny; for (j = 2; j<nytop-2; j += 2) { hm = a[s00-2]; h0 = a[s00]; hp = a[s00+2]; diff = hp-hm; dmax = max( min( (hp-h0), (h0-hm) ), 0 ) << 2; dmin = min( max( (hp-h0), (h0-hm) ), 0 ) << 2; if (dmin < dmax) { diff = max( min(diff, dmax), dmin); s = diff-(a[s00+1]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i<nxtop-2; i += 2) { s00 = ny*i+2; s10 = s00+ny; for (j = 2; j<nytop-2; j += 2) { /* * ------------------ y * | hmp | | hpp | | * ------------------ | * | | h0 | | | * ------------------ -------x * | hmm | | hpm | * ------------------ */ hmm = a[s00-ny2-2]; hpm = a[s00+ny2-2]; hmp = a[s00-ny2+2]; hpp = a[s00+ny2+2]; h0 = a[s00]; /* * diff = 64 * hc value that would match h0 in neighboring zones */ diff = hpp + hmm - hmp - hpm; /* * 2 times x,y slopes in this zone */ hx2 = a[s10 ]<<1; hy2 = a[s00+1]<<1; /* * monotonicity constraints on diff */ m1 = min(max(hpp-h0,0)-hx2-hy2, max(h0-hpm,0)+hx2-hy2); m2 = min(max(h0-hmp,0)-hx2+hy2, max(hmm-h0,0)+hx2+hy2); dmax = min(m1,m2) << 4; m1 = max(min(hpp-h0,0)-hx2-hy2, min(h0-hpm,0)+hx2-hy2); m2 = max(min(h0-hmp,0)-hx2+hy2, min(hmm-h0,0)+hx2+hy2); dmin = max(m1,m2) << 4; /* * if monotonicity would set slope = 0 then don't change hc. * note dmax>=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* undigitize.c undigitize H-transform * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static void undigitize(int a[], int nx, int ny, int scale) { int *p; /* * multiply by scale */ if (scale <= 1) return; for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale; } /* ############################################################################ */ static void undigitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG *p, scale64; /* * multiply by scale */ if (scale <= 1) return; scale64 = (LONGLONG) scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale64; } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* decode.c read codes from infile and construct array * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ############################################################################ */ static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale) /* char *infile; input file int *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { LONGLONG sumall; int nel, stat; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = (int) sumall; return(stat); } /* ############################################################################ */ static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale) /* char *infile; input file LONGLONG *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { int nel, stat; LONGLONG sumall; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode64(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = sumall; return(stat); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* dodecode.c Decode stream of characters on infile and return array * * This version encodes the different quadrants separately * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]) /* int a[]; int nx,ny; Array dimensions are [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ { int i, nel, nx2, ny2, stat; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for (i=0; i<nel; i++) a[i] = 0; /* * Initialize bit input */ start_inputing_bits(); /* * read bit planes for each quadrant */ stat = qtree_decode(infile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (stat) return(stat); stat = qtree_decode(infile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (stat) return(stat); stat = qtree_decode(infile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (stat) return(stat); stat = qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); if (stat) return(stat); /* * make sure there is an EOF symbol (nybble=0) at end */ if (input_nybble(infile) != 0) { ffpmsg("dodecode: bad bit plane values"); return(DATA_DECOMPRESSION_ERR); } /* * now get the sign bits * Re-initialize bit input */ start_inputing_bits(); for (i=0; i<nel; i++) { if (a[i]) { /* tried putting the input_bit code in-line here, instead of */ /* calling the function, but it made no difference in the speed */ if (input_bit(infile)) a[i] = -a[i]; } } return(0); } /* ############################################################################ */ static int dodecode64(unsigned char *infile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]) /* LONGLONG a[]; int nx,ny; Array dimensions are [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ { int i, nel, nx2, ny2, stat; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for (i=0; i<nel; i++) a[i] = 0; /* * Initialize bit input */ start_inputing_bits(); /* * read bit planes for each quadrant */ stat = qtree_decode64(infile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (stat) return(stat); stat = qtree_decode64(infile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (stat) return(stat); stat = qtree_decode64(infile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (stat) return(stat); stat = qtree_decode64(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); if (stat) return(stat); /* * make sure there is an EOF symbol (nybble=0) at end */ if (input_nybble(infile) != 0) { ffpmsg("dodecode64: bad bit plane values"); return(DATA_DECOMPRESSION_ERR); } /* * now get the sign bits * Re-initialize bit input */ start_inputing_bits(); for (i=0; i<nel; i++) { if (a[i]) { if (input_bit(infile) != 0) a[i] = -a[i]; } } return(0); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* qtree_decode.c Read stream of codes from infile and construct bit planes * in quadrant of 2-D array using binary quadtree coding * * Programmer: R. White Date: 7 May 1991 */ /* ############################################################################ */ static int qtree_decode(unsigned char *infile, int a[], int n, int nqx, int nqy, int nbitplanes) /* char *infile; int a[]; a is 2-D array with dimensions (n,n) int n; length of full row in a int nqx; partial length of row to decode int nqy; partial length of column (<=n) int nbitplanes; number of bitplanes to decode */ { int log2n, k, bit, b, nqmax; int nx,ny,nfx,nfy,c; int nqx2, nqy2; unsigned char *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<<log2n)) { log2n += 1; } /* * allocate scratch array for working space */ nqx2=(nqx+1)/2; nqy2=(nqy+1)/2; scratch = (unsigned char *) malloc(nqx2*nqy2); if (scratch == (unsigned char *) NULL) { ffpmsg("qtree_decode: insufficient memory"); return(DATA_DECOMPRESSION_ERR); } /* * now decode each bit plane, starting at the top * A is assumed to be initialized to zero */ for (bit = nbitplanes-1; bit >= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<<log2n; for (k = 1; k<log2n; k++) { /* * this somewhat cryptic code generates the sequence * n[k-1] = (n[k]+1)/2 where n[log2n]=nqx or nqy */ c = c>>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) /* char *infile; LONGLONG a[]; a is 2-D array with dimensions (n,n) int n; length of full row in a int nqx; partial length of row to decode int nqy; partial length of column (<=n) int nbitplanes; number of bitplanes to decode */ { int log2n, k, bit, b, nqmax; int nx,ny,nfx,nfy,c; int nqx2, nqy2; unsigned char *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<<log2n)) { log2n += 1; } /* * allocate scratch array for working space */ nqx2=(nqx+1)/2; nqy2=(nqy+1)/2; scratch = (unsigned char *) malloc(nqx2*nqy2); if (scratch == (unsigned char *) NULL) { ffpmsg("qtree_decode64: insufficient memory"); return(DATA_DECOMPRESSION_ERR); } /* * now decode each bit plane, starting at the top * A is assumed to be initialized to zero */ for (bit = nbitplanes-1; bit >= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect64(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode64: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<<log2n; for (k = 1; k<log2n; k++) { /* * this somewhat cryptic code generates the sequence * n[k-1] = (n[k]+1)/2 where n[log2n]=nqx or nqy */ c = c>>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ /* * do one quadtree expansion step on array a[(nqx+1)/2,(nqy+1)/2] * results put into b[nqx,nqy] (which may be the same as a) */ static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]) { int i; /* * first copy a to b, expanding each 4-bit value */ qtree_copy(a,nx,ny,b,ny); /* * now read new 4-bit values into b for each non-zero element */ for (i = nx*ny-1; i >= 0; i--) { if (b[i]) b[i] = input_huffman(infile); } } /* ############################################################################ */ /* * copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels * a,b may be same array */ static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n) /* int n; declared y dimension of b */ { int i, j, k, nx2, ny2; int s00, s10; /* * first copy 4-bit values to b * start at end in case a,b are same array */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; k = ny2*(nx2-1)+ny2-1; /* k is index of a[i,j] */ for (i = nx2-1; i >= 0; i--) { s00 = 2*(n*i+ny2-1); /* s00 is index of b[2*i,2*j] */ for (j = ny2-1; j >= 0; j--) { b[s00] = a[k]; k -= 1; s00 -= 2; } } /* * now expand each 2x2 block */ for (i = 0; i<nx-1; i += 2) { /* Note: Unlike the case in qtree_bitins, this code runs faster on a 32-bit linux machine using the s10 intermediate variable, rather that using s00+n. Go figure! */ s00 = n*i; /* s00 is index of b[i,j] */ s10 = s00+n; /* s10 is index of b[i+1,j] */ for (j = 0; j<ny-1; j += 2) { switch (b[s00]) { case(0): b[s10+1] = 0; b[s10 ] = 0; b[s00+1] = 0; b[s00 ] = 0; break; case(1): b[s10+1] = 1; b[s10 ] = 0; b[s00+1] = 0; b[s00 ] = 0; break; case(2): b[s10+1] = 0; b[s10 ] = 1; b[s00+1] = 0; b[s00 ] = 0; break; case(3): b[s10+1] = 1; b[s10 ] = 1; b[s00+1] = 0; b[s00 ] = 0; break; case(4): b[s10+1] = 0; b[s10 ] = 0; b[s00+1] = 1; b[s00 ] = 0; break; case(5): b[s10+1] = 1; b[s10 ] = 0; b[s00+1] = 1; b[s00 ] = 0; break; case(6): b[s10+1] = 0; b[s10 ] = 1; b[s00+1] = 1; b[s00 ] = 0; break; case(7): b[s10+1] = 1; b[s10 ] = 1; b[s00+1] = 1; b[s00 ] = 0; break; case(8): b[s10+1] = 0; b[s10 ] = 0; b[s00+1] = 0; b[s00 ] = 1; break; case(9): b[s10+1] = 1; b[s10 ] = 0; b[s00+1] = 0; b[s00 ] = 1; break; case(10): b[s10+1] = 0; b[s10 ] = 1; b[s00+1] = 0; b[s00 ] = 1; break; case(11): b[s10+1] = 1; b[s10 ] = 1; b[s00+1] = 0; b[s00 ] = 1; break; case(12): b[s10+1] = 0; b[s10 ] = 0; b[s00+1] = 1; b[s00 ] = 1; break; case(13): b[s10+1] = 1; b[s10 ] = 0; b[s00+1] = 1; b[s00 ] = 1; break; case(14): b[s10+1] = 0; b[s10 ] = 1; b[s00+1] = 1; b[s00 ] = 1; break; case(15): b[s10+1] = 1; b[s10 ] = 1; b[s00+1] = 1; b[s00 ] = 1; break; } /* b[s10+1] = b[s00] & 1; b[s10 ] = (b[s00]>>1) & 1; b[s00+1] = (b[s00]>>2) & 1; b[s00 ] = (b[s00]>>3) & 1; */ s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ /* not worth converting this to use 16 case statements */ b[s10 ] = (b[s00]>>1) & 1; b[s00 ] = (b[s00]>>3) & 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j<ny-1; j += 2) { /* not worth converting this to use 16 case statements */ b[s00+1] = (b[s00]>>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ /* not worth converting this to use 16 case statements */ b[s00 ] = (b[s00]>>3) & 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00; int plane_val; plane_val = 1 << bit; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i<nx-1; i += 2) { s00 = n*i; /* s00 is index of b[i,j] */ /* Note: this code appears to run very slightly faster on a 32-bit linux machine using s00+n rather than the s10 intermediate variable */ /* s10 = s00+n; */ /* s10 is index of b[i+1,j] */ for (j = 0; j<ny-1; j += 2) { switch (a[k]) { case(0): break; case(1): b[s00+n+1] |= plane_val; break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; break; case(4): b[s00+1] |= plane_val; break; case(5): b[s00+n+1] |= plane_val; b[s00+1] |= plane_val; break; case(6): b[s00+n ] |= plane_val; b[s00+1] |= plane_val; break; case(7): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00+1] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00+n+1] |= plane_val; b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(13): b[s00+n+1] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10+1] |= ( a[k] & 1) << bit; b[s10 ] |= ((a[k]>>1) & 1) << bit; b[s00+1] |= ((a[k]>>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ s00 += 2; /* s10 += 2; */ k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n ] |= plane_val; break; case(4): break; case(5): break; case(6): b[s00+n ] |= plane_val; break; case(7): b[s00+n ] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10 ] |= ((a[k]>>1) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j<ny-1; j += 2) { switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): b[s00+1] |= plane_val; break; case(5): b[s00+1] |= plane_val; break; case(6): b[s00+1] |= plane_val; break; case(7): b[s00+1] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(13): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(14): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s00+1] |= ((a[k]>>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; */ s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): break; case(5): break; case(6): break; case(7): break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00 ] |= plane_val; break; case(15): b[s00 ] |= plane_val; break; } /* b[s00 ] |= ((a[k]>>3) & 1) << bit; */ k += 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00; int plane_val; plane_val = 1 << bit; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i<nx-1; i += 2) { s00 = n*i; /* s00 is index of b[i,j] */ /* Note: this code appears to run very slightly faster on a 32-bit linux machine using s00+n rather than the s10 intermediate variable */ /* s10 = s00+n; */ /* s10 is index of b[i+1,j] */ for (j = 0; j<ny-1; j += 2) { switch (a[k]) { case(0): break; case(1): b[s00+n+1] |= plane_val; break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; break; case(4): b[s00+1] |= plane_val; break; case(5): b[s00+n+1] |= plane_val; b[s00+1] |= plane_val; break; case(6): b[s00+n ] |= plane_val; b[s00+1] |= plane_val; break; case(7): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00+1] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00+n+1] |= plane_val; b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(13): b[s00+n+1] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n+1] |= plane_val; b[s00+n ] |= plane_val; b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10+1] |= ((LONGLONG) ( a[k] & 1)) << bit; b[s10 ] |= ((((LONGLONG)a[k])>>1) & 1) << bit; b[s00+1] |= ((((LONGLONG)a[k])>>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ s00 += 2; /* s10 += 2; */ k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): b[s00+n ] |= plane_val; break; case(3): b[s00+n ] |= plane_val; break; case(4): break; case(5): break; case(6): b[s00+n ] |= plane_val; break; case(7): b[s00+n ] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(11): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+n ] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s10 ] |= ((((LONGLONG)a[k])>>1) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j<ny-1; j += 2) { switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): b[s00+1] |= plane_val; break; case(5): b[s00+1] |= plane_val; break; case(6): b[s00+1] |= plane_val; break; case(7): b[s00+1] |= plane_val; break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(13): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(14): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; case(15): b[s00+1] |= plane_val; b[s00 ] |= plane_val; break; } /* b[s00+1] |= ((((LONGLONG)a[k])>>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ switch (a[k]) { case(0): break; case(1): break; case(2): break; case(3): break; case(4): break; case(5): break; case(6): break; case(7): break; case(8): b[s00 ] |= plane_val; break; case(9): b[s00 ] |= plane_val; break; case(10): b[s00 ] |= plane_val; break; case(11): b[s00 ] |= plane_val; break; case(12): b[s00 ] |= plane_val; break; case(13): b[s00 ] |= plane_val; break; case(14): b[s00 ] |= plane_val; break; case(15): b[s00 ] |= plane_val; break; } /* b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; */ k += 1; } } } /* ############################################################################ */ static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ /* for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } */ input_nnybble(infile, ((nqx+1)/2) * ((nqy+1)/2), scratch); /* * insert in bitplane BIT of image A */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ /* for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } */ input_nnybble(infile, ((nqx+1)/2) * ((nqy+1)/2), scratch); /* * insert in bitplane BIT of image A */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ /* * Huffman decoding for fixed codes * * Coded values range from 0-15 * * Huffman code values (hex): * * 3e, 00, 01, 08, 02, 09, 1a, 1b, * 03, 1c, 0a, 1d, 0b, 1e, 3f, 0c * * and number of bits in each code: * * 6, 3, 3, 4, 3, 4, 5, 5, * 3, 5, 4, 5, 4, 5, 6, 4 */ static int input_huffman(unsigned char *infile) { int c; /* * get first 3 bits to start */ c = input_nbits(infile,3); if (c < 4) { /* * this is all we need * return 1,2,4,8 for c=0,1,2,3 */ return(1<<c); } /* * get the next bit */ c = input_bit(infile) | (c<<1); if (c < 13) { /* * OK, 4 bits is enough */ switch (c) { case 8 : return(3); case 9 : return(5); case 10 : return(10); case 11 : return(12); case 12 : return(15); } } /* * get yet another bit */ c = input_bit(infile) | (c<<1); if (c < 31) { /* * OK, 5 bits is enough */ switch (c) { case 26 : return(6); case 27 : return(7); case 28 : return(9); case 29 : return(11); case 30 : return(13); } } /* * need the 6th bit */ c = input_bit(infile) | (c<<1); if (c == 62) { return(0); } else { return(14); } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* qread.c Read binary data * * Programmer: R. White Date: 11 March 1991 */ static int readint(unsigned char *infile) { int a,i; unsigned char b[4]; /* Read integer A one byte at a time from infile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. * * This routine is only called to read the first 3 values * in the compressed file, so it doesn't have to be * super-efficient */ for (i=0; i<4; i++) qread(infile,(char *) &b[i],1); a = b[0]; for (i=1; i<4; i++) a = (a<<8) + b[i]; return(a); } /* ############################################################################ */ static LONGLONG readlonglong(unsigned char *infile) { int i; LONGLONG a; unsigned char b[8]; /* Read integer A one byte at a time from infile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. * * This routine is only called to read the first 3 values * in the compressed file, so it doesn't have to be * super-efficient */ for (i=0; i<8; i++) qread(infile,(char *) &b[i],1); a = b[0]; for (i=1; i<8; i++) a = (a<<8) + b[i]; return(a); } /* ############################################################################ */ static void qread(unsigned char *file, char buffer[], int n) { /* * read n bytes from file into buffer * */ memcpy(buffer, &file[nextchar], n); nextchar += n; } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT INPUT ROUTINES */ /* THE BIT BUFFER */ static int buffer2; /* Bits waiting to be input */ static int bits_to_go; /* Number of bits still in buffer */ /* INITIALIZE BIT INPUT */ /* ############################################################################ */ static void start_inputing_bits() { /* * Buffer starts out with no bits in it */ bits_to_go = 0; } /* ############################################################################ */ /* INPUT A BIT */ static int input_bit(unsigned char *infile) { if (bits_to_go == 0) { /* Read the next byte if no */ buffer2 = infile[nextchar]; nextchar++; bits_to_go = 8; } /* * Return the next bit */ bits_to_go -= 1; return((buffer2>>bits_to_go) & 1); } /* ############################################################################ */ /* INPUT N BITS (N must be <= 8) */ static int input_nbits(unsigned char *infile, int n) { /* AND mask for retreiving the right-most n bits */ static int mask[9] = {0, 1, 3, 7, 15, 31, 63, 127, 255}; if (bits_to_go < n) { /* * need another byte's worth of bits */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; bits_to_go += 8; } /* * now pick off the first n bits */ bits_to_go -= n; /* there was a slight gain in speed by replacing the following line */ /* return( (buffer2>>bits_to_go) & ((1<<n)-1) ); */ return( (buffer2>>bits_to_go) & (*(mask+n)) ); } /* ############################################################################ */ /* INPUT 4 BITS */ static int input_nybble(unsigned char *infile) { if (bits_to_go < 4) { /* * need another byte's worth of bits */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; bits_to_go += 8; } /* * now pick off the first 4 bits */ bits_to_go -= 4; return( (buffer2>>bits_to_go) & 15 ); } /* ############################################################################ */ /* INPUT array of 4 BITS */ static int input_nnybble(unsigned char *infile, int n, unsigned char array[]) { /* copy n 4-bit nybbles from infile to the lower 4 bits of array */ int ii, kk, shift1, shift2; /* forcing byte alignment doesn;t help, and even makes it go slightly slower if (bits_to_go != 8) input_nbits(infile, bits_to_go); */ if (n == 1) { array[0] = input_nybble(infile); return(0); } if (bits_to_go == 8) { /* already have 2 full nybbles in buffer2, so backspace the infile array to reuse last char */ nextchar--; bits_to_go = 0; } /* bits_to_go now has a value in the range 0 - 7. After adding */ /* another byte, bits_to_go effectively will be in range 8 - 15 */ shift1 = bits_to_go + 4; /* shift1 will be in range 4 - 11 */ shift2 = bits_to_go; /* shift2 will be in range 0 - 7 */ kk = 0; /* special case */ if (bits_to_go == 0) { for (ii = 0; ii < n/2; ii++) { /* * refill the buffer with next byte */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; array[kk] = (int) ((buffer2>>4) & 15); array[kk + 1] = (int) ((buffer2) & 15); /* no shift required */ kk += 2; } } else { for (ii = 0; ii < n/2; ii++) { /* * refill the buffer with next byte */ buffer2 = (buffer2<<8) | (int) infile[nextchar]; nextchar++; array[kk] = (int) ((buffer2>>shift1) & 15); array[kk + 1] = (int) ((buffer2>>shift2) & 15); kk += 2; } } if (ii * 2 != n) { /* have to read last odd byte */ array[n-1] = input_nybble(infile); } return( (buffer2>>bits_to_go) & 15 ); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./saods9/make.macosxx86tiger������������������������������������������������������������������������0000644�0001750�0001750�00000001142�12127331353�014633� 0����������������������������������������������������������������������������������������������������ustar �oles����������������������������oles�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OS = macosx ARCH = macosxx86tiger X11INCLUDE =../include/X11 export MACOSX_DEPLOYMENT_TARGET := 10.4 XX = -O2 YY = -gstabs+ -fno-inline ZZ = -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 AA = -fPIC -D_MACOSX -DMAC_OSX_TK -DHAVE_SYS_UN_H -DHAVE_SYS_SHM_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 OPTS = ${XX} ${ZZ} NOPTS = ${YY} ${ZZ} CXX = g++ CXXOPT = ${OPTS} ${AA} CXXNOPT = ${NOPTS} ${AA} CC = gcc CCOPT = ${OPTS} ${AA} CCNOPT = ${NOPTS} ${AA} ZCAT = gzcat CODESIGN = echo FILTERCOMPILER = pcc-i386-tiger.tar.gz ASTFLAGS = ac_cv_header_execinfo_h=no JOBS = 4 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������